update sdl Merge commit '4d48f9d23713d94b861da7b5d41baf2a41334994'
This commit is contained in:
303
external/sdl/SDL/src/video/SDL_bmp.c
vendored
303
external/sdl/SDL/src/video/SDL_bmp.c
vendored
@ -71,7 +71,7 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8)
|
||||
|
||||
/* !!! FIXME: for all these reads, handle error vs eof? handle -2 if non-blocking? */
|
||||
for (;;) {
|
||||
if (SDL_RWread(src, &ch, 1) <= 0) {
|
||||
if (!SDL_ReadU8(src, &ch)) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
/*
|
||||
@ -80,7 +80,7 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8)
|
||||
*/
|
||||
if (ch) {
|
||||
Uint8 pixel;
|
||||
if (SDL_RWread(src, &pixel, 1) <= 0) {
|
||||
if (!SDL_ReadU8(src, &pixel)) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
if (isRle8) { /* 256-color bitmap, compressed */
|
||||
@ -107,7 +107,7 @@ static SDL_bool 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) <= 0) {
|
||||
if (!SDL_ReadU8(src, &ch)) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
switch (ch) {
|
||||
@ -118,11 +118,11 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8)
|
||||
case 1: /* end of bitmap */
|
||||
return SDL_FALSE; /* success! */
|
||||
case 2: /* delta */
|
||||
if (SDL_RWread(src, &ch, 1) <= 0) {
|
||||
if (!SDL_ReadU8(src, &ch)) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
ofs += ch;
|
||||
if (SDL_RWread(src, &ch, 1) <= 0) {
|
||||
if (!SDL_ReadU8(src, &ch)) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
bits -= (ch * pitch);
|
||||
@ -132,7 +132,7 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8)
|
||||
needsPad = (ch & 1);
|
||||
do {
|
||||
Uint8 pixel;
|
||||
if (SDL_RWread(src, &pixel, 1) <= 0) {
|
||||
if (!SDL_ReadU8(src, &pixel)) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
COPY_PIXEL(pixel);
|
||||
@ -141,7 +141,7 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8)
|
||||
needsPad = (((ch + 1) >> 1) & 1); /* (ch+1)>>1: bytes size */
|
||||
for (;;) {
|
||||
Uint8 pixel;
|
||||
if (SDL_RWread(src, &pixel, 1) <= 0) {
|
||||
if (!SDL_ReadU8(src, &pixel)) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
COPY_PIXEL(pixel >> 4);
|
||||
@ -155,7 +155,7 @@ static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8)
|
||||
}
|
||||
}
|
||||
/* pad at even boundary */
|
||||
if (needsPad && (SDL_RWread(src, &ch, 1) <= 0)) {
|
||||
if (needsPad && !SDL_ReadU8(src, &ch)) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
break;
|
||||
@ -195,7 +195,7 @@ static void CorrectAlphaChannel(SDL_Surface *surface)
|
||||
|
||||
SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
{
|
||||
SDL_bool was_error;
|
||||
SDL_bool was_error = SDL_TRUE;
|
||||
Sint64 fp_offset = 0;
|
||||
int bmpPitch;
|
||||
int i, pad;
|
||||
@ -235,42 +235,45 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
|
||||
/* Make sure we are passed a valid data source */
|
||||
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, 2) != 2) {
|
||||
SDL_Error(SDL_EFREAD);
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
if (SDL_strncmp(magic, "BM", 2) != 0) {
|
||||
SDL_SetError("File is not a Windows BMP file");
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
/* bfSize = */ SDL_ReadLE32(src);
|
||||
/* bfReserved1 = */ SDL_ReadLE16(src);
|
||||
/* bfReserved2 = */ SDL_ReadLE16(src);
|
||||
bfOffBits = SDL_ReadLE32(src);
|
||||
if (!SDL_ReadU32LE(src, NULL /* bfSize */) ||
|
||||
!SDL_ReadU16LE(src, NULL /* bfReserved1 */) ||
|
||||
!SDL_ReadU16LE(src, NULL /* bfReserved2 */) ||
|
||||
!SDL_ReadU32LE(src, &bfOffBits)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Read the Win32 BITMAPINFOHEADER */
|
||||
biSize = SDL_ReadLE32(src);
|
||||
if (!SDL_ReadU32LE(src, &biSize)) {
|
||||
goto done;
|
||||
}
|
||||
if (biSize == 12) { /* really old BITMAPCOREHEADER */
|
||||
biWidth = (Uint32)SDL_ReadLE16(src);
|
||||
biHeight = (Uint32)SDL_ReadLE16(src);
|
||||
/* biPlanes = */ SDL_ReadLE16(src);
|
||||
biBitCount = SDL_ReadLE16(src);
|
||||
Uint16 biWidth16, biHeight16;
|
||||
if (!SDL_ReadU16LE(src, &biWidth16) ||
|
||||
!SDL_ReadU16LE(src, &biHeight16) ||
|
||||
!SDL_ReadU16LE(src, NULL /* biPlanes */) ||
|
||||
!SDL_ReadU16LE(src, &biBitCount)) {
|
||||
goto done;
|
||||
}
|
||||
biWidth = biWidth16;
|
||||
biHeight = biHeight16;
|
||||
biCompression = BI_RGB;
|
||||
/* biSizeImage = 0; */
|
||||
/* biXPelsPerMeter = 0; */
|
||||
@ -279,16 +282,18 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
/* biClrImportant = 0; */
|
||||
} else if (biSize >= 40) { /* some version of BITMAPINFOHEADER */
|
||||
Uint32 headerSize;
|
||||
biWidth = SDL_ReadLE32(src);
|
||||
biHeight = SDL_ReadLE32(src);
|
||||
/* biPlanes = */ SDL_ReadLE16(src);
|
||||
biBitCount = SDL_ReadLE16(src);
|
||||
biCompression = SDL_ReadLE32(src);
|
||||
/* biSizeImage = */ SDL_ReadLE32(src);
|
||||
/* biXPelsPerMeter = */ SDL_ReadLE32(src);
|
||||
/* biYPelsPerMeter = */ SDL_ReadLE32(src);
|
||||
biClrUsed = SDL_ReadLE32(src);
|
||||
/* biClrImportant = */ SDL_ReadLE32(src);
|
||||
if (!SDL_ReadS32LE(src, &biWidth) ||
|
||||
!SDL_ReadS32LE(src, &biHeight) ||
|
||||
!SDL_ReadU16LE(src, NULL /* biPlanes */) ||
|
||||
!SDL_ReadU16LE(src, &biBitCount) ||
|
||||
!SDL_ReadU32LE(src, &biCompression) ||
|
||||
!SDL_ReadU32LE(src, NULL /* biSizeImage */) ||
|
||||
!SDL_ReadU32LE(src, NULL /* biXPelsPerMeter */) ||
|
||||
!SDL_ReadU32LE(src, NULL /* biYPelsPerMeter */) ||
|
||||
!SDL_ReadU32LE(src, &biClrUsed) ||
|
||||
!SDL_ReadU32LE(src, NULL /* biClrImportant */)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* 64 == BITMAPCOREHEADER2, an incompatible OS/2 2.x extension. Skip this stuff for now. */
|
||||
if (biSize != 64) {
|
||||
@ -301,24 +306,32 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
following the legacy v1 info header, just past biSize. */
|
||||
if (biCompression == BI_BITFIELDS) {
|
||||
haveRGBMasks = SDL_TRUE;
|
||||
Rmask = SDL_ReadLE32(src);
|
||||
Gmask = SDL_ReadLE32(src);
|
||||
Bmask = SDL_ReadLE32(src);
|
||||
if (!SDL_ReadU32LE(src, &Rmask) ||
|
||||
!SDL_ReadU32LE(src, &Gmask) ||
|
||||
!SDL_ReadU32LE(src, &Bmask)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* ...v3 adds an alpha mask. */
|
||||
if (biSize >= 56) { /* BITMAPV3INFOHEADER; adds alpha mask */
|
||||
haveAlphaMask = SDL_TRUE;
|
||||
Amask = SDL_ReadLE32(src);
|
||||
if (!SDL_ReadU32LE(src, &Amask)) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* the mask fields are ignored for v2+ headers if not BI_BITFIELD. */
|
||||
if (biSize >= 52) { /* BITMAPV2INFOHEADER; adds RGB masks */
|
||||
/*Rmask = */ SDL_ReadLE32(src);
|
||||
/*Gmask = */ SDL_ReadLE32(src);
|
||||
/*Bmask = */ SDL_ReadLE32(src);
|
||||
if (!SDL_ReadU32LE(src, NULL /* Rmask */) ||
|
||||
!SDL_ReadU32LE(src, NULL /* Gmask */) ||
|
||||
!SDL_ReadU32LE(src, NULL /* Bmask */)) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (biSize >= 56) { /* BITMAPV3INFOHEADER; adds alpha mask */
|
||||
/*Amask = */ SDL_ReadLE32(src);
|
||||
if (!SDL_ReadU32LE(src, NULL /* Amask */)) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -331,12 +344,13 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
/* skip any header bytes we didn't handle... */
|
||||
headerSize = (Uint32)(SDL_RWtell(src) - (fp_offset + 14));
|
||||
if (biSize > headerSize) {
|
||||
SDL_RWseek(src, (biSize - headerSize), SDL_RW_SEEK_CUR);
|
||||
if (SDL_RWseek(src, (biSize - headerSize), SDL_RW_SEEK_CUR) < 0) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (biWidth <= 0 || biHeight == 0) {
|
||||
SDL_SetError("BMP file with bad dimensions (%" SDL_PRIs32 "x%" SDL_PRIs32 ")", biWidth, biHeight);
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
if (biHeight < 0) {
|
||||
@ -348,7 +362,6 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
|
||||
/* Check for read error */
|
||||
if (SDL_strcmp(SDL_GetError(), "") != 0) {
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -366,7 +379,6 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
case 6:
|
||||
case 7:
|
||||
SDL_SetError("%d-bpp BMP images are not supported", biBitCount);
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
default:
|
||||
ExpandBMP = 0;
|
||||
@ -431,7 +443,6 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
surface = SDL_CreateSurface(biWidth, biHeight, format);
|
||||
|
||||
if (surface == NULL) {
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
@ -441,13 +452,11 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
if (palette) {
|
||||
if (SDL_RWseek(src, fp_offset + 14 + biSize, SDL_RW_SEEK_SET) < 0) {
|
||||
SDL_Error(SDL_EFSEEK);
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (biBitCount >= 32) { /* we shift biClrUsed by this value later. */
|
||||
SDL_SetError("Unsupported or incorrect biBitCount field");
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -459,26 +468,27 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
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) {
|
||||
/* !!! FIXME: this should check for i/o errors! */
|
||||
SDL_RWread(src, &palette->colors[i].b, 1);
|
||||
SDL_RWread(src, &palette->colors[i].g, 1);
|
||||
SDL_RWread(src, &palette->colors[i].r, 1);
|
||||
if (!SDL_ReadU8(src, &palette->colors[i].b) ||
|
||||
!SDL_ReadU8(src, &palette->colors[i].g) ||
|
||||
!SDL_ReadU8(src, &palette->colors[i].r)) {
|
||||
goto done;
|
||||
}
|
||||
palette->colors[i].a = SDL_ALPHA_OPAQUE;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < (int)biClrUsed; ++i) {
|
||||
/* !!! FIXME: this should check for i/o errors! */
|
||||
SDL_RWread(src, &palette->colors[i].b, 1);
|
||||
SDL_RWread(src, &palette->colors[i].g, 1);
|
||||
SDL_RWread(src, &palette->colors[i].r, 1);
|
||||
SDL_RWread(src, &palette->colors[i].a, 1);
|
||||
if (!SDL_ReadU8(src, &palette->colors[i].b) ||
|
||||
!SDL_ReadU8(src, &palette->colors[i].g) ||
|
||||
!SDL_ReadU8(src, &palette->colors[i].r) ||
|
||||
!SDL_ReadU8(src, &palette->colors[i].a)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* According to Microsoft documentation, the fourth element
|
||||
is reserved and must be zero, so we shouldn't treat it as
|
||||
@ -493,7 +503,6 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
/* Read the surface pixels. Note that the bmp image is upside down */
|
||||
if (SDL_RWseek(src, fp_offset + bfOffBits, SDL_RW_SEEK_SET) < 0) {
|
||||
SDL_Error(SDL_EFSEEK);
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
if ((biCompression == BI_RLE4) || (biCompression == BI_RLE8)) {
|
||||
@ -537,16 +546,13 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
int shift = (8 - ExpandBMP);
|
||||
for (i = 0; i < surface->w; ++i) {
|
||||
if (i % (8 / ExpandBMP) == 0) {
|
||||
if (SDL_RWread(src, &pixel, 1) != 1) {
|
||||
SDL_Error(SDL_EFREAD);
|
||||
was_error = SDL_TRUE;
|
||||
if (!SDL_ReadU8(src, &pixel)) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
bits[i] = (pixel >> shift);
|
||||
if (bits[i] >= biClrUsed) {
|
||||
SDL_SetError("A BMP image contains a pixel with a color out of the palette");
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
pixel <<= ExpandBMP;
|
||||
@ -555,15 +561,12 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
|
||||
default:
|
||||
if (SDL_RWread(src, bits, surface->pitch) != surface->pitch) {
|
||||
SDL_Error(SDL_EFREAD);
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
if (biBitCount == 8 && palette && biClrUsed < (1u << biBitCount)) {
|
||||
for (i = 0; i < surface->w; ++i) {
|
||||
if (bits[i] >= biClrUsed) {
|
||||
SDL_SetError("A BMP image contains a pixel with a color out of the palette");
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
@ -598,7 +601,9 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
if (pad) {
|
||||
Uint8 padbyte;
|
||||
for (i = 0; i < pad; ++i) {
|
||||
SDL_RWread(src, &padbyte, 1);
|
||||
if (!SDL_ReadU8(src, &padbyte)) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (topDown) {
|
||||
@ -610,6 +615,9 @@ SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, SDL_bool freesrc)
|
||||
if (correctAlpha) {
|
||||
CorrectAlphaChannel(surface);
|
||||
}
|
||||
|
||||
was_error = SDL_FALSE;
|
||||
|
||||
done:
|
||||
if (was_error) {
|
||||
if (src) {
|
||||
@ -629,15 +637,10 @@ SDL_Surface *SDL_LoadBMP(const char *file)
|
||||
return SDL_LoadBMP_RW(SDL_RWFromFile(file, "rb"), 1);
|
||||
}
|
||||
|
||||
int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
|
||||
int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, SDL_bool freedst)
|
||||
{
|
||||
/* !!! FIXME: this calls SDL_ClearError() and then checks if an error happened during this function to
|
||||
!!! FIXME: decide if there was a problem, but there's risk of innocent things setting an error
|
||||
!!! FIXME: string for innocent unrelated reasons, and also, an app supplying its own RWops
|
||||
!!! FIXME: implementation may not set the error string on failure. We should check for i/o
|
||||
!!! FIXME: failures as we go, and return early if one occurs. */
|
||||
|
||||
Sint64 fp_offset;
|
||||
SDL_bool was_error = SDL_TRUE;
|
||||
Sint64 fp_offset, new_offset;
|
||||
int i, pad;
|
||||
SDL_Surface *intermediate_surface;
|
||||
Uint8 *bits;
|
||||
@ -678,6 +681,11 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
|
||||
/* Make sure we have somewhere to save */
|
||||
intermediate_surface = NULL;
|
||||
if (dst) {
|
||||
if (!surface) {
|
||||
SDL_InvalidParamError("surface");
|
||||
goto done;
|
||||
}
|
||||
|
||||
#ifdef SAVE_32BIT_BMP
|
||||
/* We can save alpha information in a 32-bit BMP */
|
||||
if (surface->format->BitsPerPixel >= 8 &&
|
||||
@ -693,6 +701,7 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
|
||||
} else {
|
||||
SDL_SetError("%d bpp BMP files not supported",
|
||||
surface->format->BitsPerPixel);
|
||||
goto done;
|
||||
}
|
||||
} else if ((surface->format->BitsPerPixel == 24) && !save32bit &&
|
||||
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
|
||||
@ -707,32 +716,33 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
|
||||
) {
|
||||
intermediate_surface = surface;
|
||||
} else {
|
||||
SDL_PixelFormat format;
|
||||
Uint32 pixel_format;
|
||||
|
||||
/* If the surface has a colorkey or alpha channel we'll save a
|
||||
32-bit BMP with alpha channel, otherwise save a 24-bit BMP. */
|
||||
if (save32bit) {
|
||||
SDL_InitFormat(&format, SDL_PIXELFORMAT_BGRA32);
|
||||
pixel_format = SDL_PIXELFORMAT_BGRA32;
|
||||
} else {
|
||||
SDL_InitFormat(&format, SDL_PIXELFORMAT_BGR24);
|
||||
pixel_format = SDL_PIXELFORMAT_BGR24;
|
||||
}
|
||||
intermediate_surface = SDL_ConvertSurface(surface, &format);
|
||||
intermediate_surface = SDL_ConvertSurfaceFormat(surface, pixel_format);
|
||||
if (intermediate_surface == NULL) {
|
||||
SDL_SetError("Couldn't convert image to %d bpp",
|
||||
format.BitsPerPixel);
|
||||
(int)SDL_BITSPERPIXEL(pixel_format));
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Set no error here because it may overwrite a more useful message from
|
||||
SDL_RWFromFile() if SDL_SaveBMP_RW() is called from SDL_SaveBMP(). */
|
||||
return -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (save32bit) {
|
||||
saveLegacyBMP = SDL_GetHintBoolean(SDL_HINT_BMP_SAVE_LEGACY_FORMAT, SDL_FALSE);
|
||||
}
|
||||
|
||||
if (intermediate_surface && (SDL_LockSurface(intermediate_surface) == 0)) {
|
||||
if (SDL_LockSurface(intermediate_surface) == 0) {
|
||||
const int bw = intermediate_surface->w * intermediate_surface->format->BytesPerPixel;
|
||||
|
||||
/* Set the BMP file header values */
|
||||
@ -743,12 +753,16 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
|
||||
|
||||
/* Write the BMP file header values */
|
||||
fp_offset = SDL_RWtell(dst);
|
||||
SDL_ClearError();
|
||||
SDL_RWwrite(dst, magic, 2);
|
||||
SDL_WriteLE32(dst, bfSize);
|
||||
SDL_WriteLE16(dst, bfReserved1);
|
||||
SDL_WriteLE16(dst, bfReserved2);
|
||||
SDL_WriteLE32(dst, bfOffBits);
|
||||
if (fp_offset < 0) {
|
||||
goto done;
|
||||
}
|
||||
if (SDL_RWwrite(dst, magic, 2) != 2 ||
|
||||
!SDL_WriteU32LE(dst, bfSize) ||
|
||||
!SDL_WriteU16LE(dst, bfReserved1) ||
|
||||
!SDL_WriteU16LE(dst, bfReserved2) ||
|
||||
!SDL_WriteU32LE(dst, bfOffBits)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Set the BMP info values */
|
||||
biSize = 40;
|
||||
@ -783,31 +797,39 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
|
||||
}
|
||||
|
||||
/* Write the BMP info values */
|
||||
SDL_WriteLE32(dst, biSize);
|
||||
SDL_WriteLE32(dst, biWidth);
|
||||
SDL_WriteLE32(dst, biHeight);
|
||||
SDL_WriteLE16(dst, biPlanes);
|
||||
SDL_WriteLE16(dst, biBitCount);
|
||||
SDL_WriteLE32(dst, biCompression);
|
||||
SDL_WriteLE32(dst, biSizeImage);
|
||||
SDL_WriteLE32(dst, biXPelsPerMeter);
|
||||
SDL_WriteLE32(dst, biYPelsPerMeter);
|
||||
SDL_WriteLE32(dst, biClrUsed);
|
||||
SDL_WriteLE32(dst, biClrImportant);
|
||||
if (!SDL_WriteU32LE(dst, biSize) ||
|
||||
!SDL_WriteS32LE(dst, biWidth) ||
|
||||
!SDL_WriteS32LE(dst, biHeight) ||
|
||||
!SDL_WriteU16LE(dst, biPlanes) ||
|
||||
!SDL_WriteU16LE(dst, biBitCount) ||
|
||||
!SDL_WriteU32LE(dst, biCompression) ||
|
||||
!SDL_WriteU32LE(dst, biSizeImage) ||
|
||||
!SDL_WriteU32LE(dst, biXPelsPerMeter) ||
|
||||
!SDL_WriteU32LE(dst, biYPelsPerMeter) ||
|
||||
!SDL_WriteU32LE(dst, biClrUsed) ||
|
||||
!SDL_WriteU32LE(dst, biClrImportant)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Write the BMP info values for the version 4 header */
|
||||
if (save32bit && !saveLegacyBMP) {
|
||||
SDL_WriteLE32(dst, bV4RedMask);
|
||||
SDL_WriteLE32(dst, bV4GreenMask);
|
||||
SDL_WriteLE32(dst, bV4BlueMask);
|
||||
SDL_WriteLE32(dst, bV4AlphaMask);
|
||||
SDL_WriteLE32(dst, bV4CSType);
|
||||
for (i = 0; i < 3 * 3; i++) {
|
||||
SDL_WriteLE32(dst, bV4Endpoints[i]);
|
||||
if (!SDL_WriteU32LE(dst, bV4RedMask) ||
|
||||
!SDL_WriteU32LE(dst, bV4GreenMask) ||
|
||||
!SDL_WriteU32LE(dst, bV4BlueMask) ||
|
||||
!SDL_WriteU32LE(dst, bV4AlphaMask) ||
|
||||
!SDL_WriteU32LE(dst, bV4CSType)) {
|
||||
goto done;
|
||||
}
|
||||
for (i = 0; i < 3 * 3; i++) {
|
||||
if (!SDL_WriteU32LE(dst, bV4Endpoints[i])) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (!SDL_WriteU32LE(dst, bV4GammaRed) ||
|
||||
!SDL_WriteU32LE(dst, bV4GammaGreen) ||
|
||||
!SDL_WriteU32LE(dst, bV4GammaBlue)) {
|
||||
goto done;
|
||||
}
|
||||
SDL_WriteLE32(dst, bV4GammaRed);
|
||||
SDL_WriteLE32(dst, bV4GammaGreen);
|
||||
SDL_WriteLE32(dst, bV4GammaBlue);
|
||||
}
|
||||
|
||||
/* Write the palette (in BGR color order) */
|
||||
@ -818,21 +840,25 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
|
||||
colors = intermediate_surface->format->palette->colors;
|
||||
ncolors = intermediate_surface->format->palette->ncolors;
|
||||
for (i = 0; i < ncolors; ++i) {
|
||||
SDL_RWwrite(dst, &colors[i].b, 1);
|
||||
SDL_RWwrite(dst, &colors[i].g, 1);
|
||||
SDL_RWwrite(dst, &colors[i].r, 1);
|
||||
SDL_RWwrite(dst, &colors[i].a, 1);
|
||||
if (!SDL_WriteU8(dst, colors[i].b) ||
|
||||
!SDL_WriteU8(dst, colors[i].g) ||
|
||||
!SDL_WriteU8(dst, colors[i].r) ||
|
||||
!SDL_WriteU8(dst, colors[i].a)) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the bitmap offset */
|
||||
bfOffBits = (Uint32)(SDL_RWtell(dst) - fp_offset);
|
||||
if (SDL_RWseek(dst, fp_offset + 10, SDL_RW_SEEK_SET) < 0) {
|
||||
SDL_Error(SDL_EFSEEK);
|
||||
goto done;
|
||||
}
|
||||
if (!SDL_WriteU32LE(dst, bfOffBits)) {
|
||||
goto done;
|
||||
}
|
||||
SDL_WriteLE32(dst, bfOffBits);
|
||||
if (SDL_RWseek(dst, fp_offset + bfOffBits, SDL_RW_SEEK_SET) < 0) {
|
||||
SDL_Error(SDL_EFSEEK);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Write the bitmap image upside down */
|
||||
@ -841,38 +867,53 @@ int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
|
||||
while (bits > (Uint8 *)intermediate_surface->pixels) {
|
||||
bits -= intermediate_surface->pitch;
|
||||
if (SDL_RWwrite(dst, bits, bw) != bw) {
|
||||
SDL_Error(SDL_EFWRITE);
|
||||
break;
|
||||
goto done;
|
||||
}
|
||||
if (pad) {
|
||||
const Uint8 padbyte = 0;
|
||||
for (i = 0; i < pad; ++i) {
|
||||
SDL_RWwrite(dst, &padbyte, 1);
|
||||
if (!SDL_WriteU8(dst, padbyte)) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the BMP file size */
|
||||
bfSize = (Uint32)(SDL_RWtell(dst) - fp_offset);
|
||||
if (SDL_RWseek(dst, fp_offset + 2, SDL_RW_SEEK_SET) < 0) {
|
||||
SDL_Error(SDL_EFSEEK);
|
||||
new_offset = SDL_RWtell(dst);
|
||||
if (new_offset < 0) {
|
||||
goto done;
|
||||
}
|
||||
bfSize = (Uint32)(new_offset - fp_offset);
|
||||
if (SDL_RWseek(dst, fp_offset + 2, SDL_RW_SEEK_SET) < 0) {
|
||||
goto done;
|
||||
}
|
||||
if (!SDL_WriteU32LE(dst, bfSize)) {
|
||||
goto done;
|
||||
}
|
||||
SDL_WriteLE32(dst, bfSize);
|
||||
if (SDL_RWseek(dst, fp_offset + bfSize, SDL_RW_SEEK_SET) < 0) {
|
||||
SDL_Error(SDL_EFSEEK);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Close it up.. */
|
||||
SDL_UnlockSurface(intermediate_surface);
|
||||
if (intermediate_surface != surface) {
|
||||
SDL_DestroySurface(intermediate_surface);
|
||||
}
|
||||
|
||||
was_error = SDL_FALSE;
|
||||
}
|
||||
|
||||
if (freedst && dst) {
|
||||
SDL_RWclose(dst);
|
||||
done:
|
||||
if (intermediate_surface && intermediate_surface != surface) {
|
||||
SDL_DestroySurface(intermediate_surface);
|
||||
}
|
||||
return (SDL_strcmp(SDL_GetError(), "") == 0) ? 0 : -1;
|
||||
if (freedst && dst) {
|
||||
if (SDL_RWclose(dst) < 0) {
|
||||
was_error = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
if (was_error) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDL_SaveBMP(SDL_Surface *surface, const char *file)
|
||||
|
15
external/sdl/SDL/src/video/SDL_pixels.c
vendored
15
external/sdl/SDL/src/video/SDL_pixels.c
vendored
@ -140,6 +140,12 @@ SDL_bool SDL_GetMasksForPixelFormatEnum(Uint32 format, int *bpp, Uint32 *Rmask,
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
/* Partial support for SDL_Surface with FOURCC */
|
||||
if (SDL_ISPIXELFORMAT_FOURCC(format)) {
|
||||
/* Not a format that uses masks */
|
||||
*bpp = 0;
|
||||
*Rmask = *Gmask = *Bmask = *Amask = 0;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
#else
|
||||
if (SDL_ISPIXELFORMAT_FOURCC(format)) {
|
||||
SDL_SetError("SDL not built with YUV support");
|
||||
@ -181,11 +187,6 @@ SDL_bool SDL_GetMasksForPixelFormatEnum(Uint32 format, int *bpp, Uint32 *Rmask,
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
if (SDL_ISPIXELFORMAT_FOURCC(format)) {
|
||||
/* Not a format that uses masks */
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
if (SDL_PIXELTYPE(format) != SDL_PIXELTYPE_PACKED8 &&
|
||||
SDL_PIXELTYPE(format) != SDL_PIXELTYPE_PACKED16 &&
|
||||
SDL_PIXELTYPE(format) != SDL_PIXELTYPE_PACKED32) {
|
||||
@ -314,10 +315,8 @@ Uint32 SDL_GetPixelFormatEnumForMasks(int bpp, Uint32 Rmask, Uint32 Gmask, Uint3
|
||||
Bmask == 0x03 &&
|
||||
Amask == 0x00) {
|
||||
return SDL_PIXELFORMAT_RGB332;
|
||||
} else {
|
||||
return SDL_PIXELFORMAT_INDEX8;
|
||||
}
|
||||
break;
|
||||
return SDL_PIXELFORMAT_INDEX8;
|
||||
case 12:
|
||||
if (Rmask == 0) {
|
||||
return SDL_PIXELFORMAT_RGB444;
|
||||
|
5
external/sdl/SDL/src/video/SDL_sysvideo.h
vendored
5
external/sdl/SDL/src/video/SDL_sysvideo.h
vendored
@ -354,6 +354,9 @@ struct SDL_VideoDevice
|
||||
/* Tell window that app enabled drag'n'drop events */
|
||||
void (*AcceptDragAndDrop)(SDL_Window *window, SDL_bool accept);
|
||||
|
||||
/* Display the system-level window menu */
|
||||
void (*ShowWindowSystemMenu)(SDL_Window *window, int x, int y);
|
||||
|
||||
/* * * */
|
||||
/* Data common to all drivers */
|
||||
SDL_threadID thread;
|
||||
@ -363,7 +366,7 @@ struct SDL_VideoDevice
|
||||
SDL_Window *wakeup_window;
|
||||
SDL_Mutex *wakeup_lock; /* Initialized only if WaitEventTimeout/SendWakeupEvent are supported */
|
||||
int num_displays;
|
||||
SDL_VideoDisplay *displays;
|
||||
SDL_VideoDisplay **displays;
|
||||
SDL_Window *windows;
|
||||
SDL_Window *grabbed_window;
|
||||
Uint8 window_magic;
|
||||
|
143
external/sdl/SDL/src/video/SDL_video.c
vendored
143
external/sdl/SDL/src/video/SDL_video.c
vendored
@ -18,6 +18,7 @@
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "SDL_internal.h"
|
||||
|
||||
/* The high-level video driver subsystem */
|
||||
@ -118,12 +119,12 @@ static VideoBootStrap *bootstrap[] = {
|
||||
#ifdef SDL_VIDEO_DRIVER_QNX
|
||||
&QNX_bootstrap,
|
||||
#endif
|
||||
#ifdef SDL_VIDEO_DRIVER_OFFSCREEN
|
||||
&OFFSCREEN_bootstrap,
|
||||
#endif
|
||||
#ifdef SDL_VIDEO_DRIVER_NGAGE
|
||||
&NGAGE_bootstrap,
|
||||
#endif
|
||||
#ifdef SDL_VIDEO_DRIVER_OFFSCREEN
|
||||
&OFFSCREEN_bootstrap,
|
||||
#endif
|
||||
#ifdef SDL_VIDEO_DRIVER_DUMMY
|
||||
&DUMMY_bootstrap,
|
||||
#ifdef SDL_INPUT_LINUXEV
|
||||
@ -462,7 +463,7 @@ int SDL_VideoInit(const char *driver_name)
|
||||
goto pre_driver_error;
|
||||
}
|
||||
init_keyboard = SDL_TRUE;
|
||||
if (SDL_InitMouse() < 0) {
|
||||
if (SDL_PreInitMouse() < 0) {
|
||||
goto pre_driver_error;
|
||||
}
|
||||
init_mouse = SDL_TRUE;
|
||||
@ -558,6 +559,8 @@ int SDL_VideoInit(const char *driver_name)
|
||||
SDL_StartTextInput();
|
||||
}
|
||||
|
||||
SDL_PostInitMouse();
|
||||
|
||||
/* We're ready to go! */
|
||||
return 0;
|
||||
|
||||
@ -640,57 +643,51 @@ SDL_DisplayID SDL_AddBasicVideoDisplay(const SDL_DisplayMode *desktop_mode)
|
||||
|
||||
SDL_DisplayID SDL_AddVideoDisplay(const SDL_VideoDisplay *display, SDL_bool send_event)
|
||||
{
|
||||
SDL_VideoDisplay *displays, *new_display;
|
||||
SDL_DisplayID id = 0;
|
||||
SDL_VideoDisplay **displays, *new_display;
|
||||
SDL_DisplayID id;
|
||||
int i;
|
||||
|
||||
displays = (SDL_VideoDisplay *)SDL_malloc((_this->num_displays + 1) * sizeof(*displays));
|
||||
if (displays) {
|
||||
int i;
|
||||
|
||||
if (_this->displays) {
|
||||
/* The display list may contain self-referential pointers to the desktop mode. */
|
||||
SDL_memcpy(displays, _this->displays, _this->num_displays * sizeof(*displays));
|
||||
for (i = 0; i < _this->num_displays; ++i) {
|
||||
if (displays[i].current_mode == &_this->displays[i].desktop_mode) {
|
||||
displays[i].current_mode = &displays[i].desktop_mode;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_free(_this->displays);
|
||||
}
|
||||
|
||||
_this->displays = displays;
|
||||
id = _this->next_object_id++;
|
||||
new_display = &displays[_this->num_displays++];
|
||||
|
||||
SDL_memcpy(new_display, display, sizeof(*new_display));
|
||||
new_display->id = id;
|
||||
new_display->device = _this;
|
||||
if (display->name) {
|
||||
new_display->name = SDL_strdup(display->name);
|
||||
} else {
|
||||
char name[32];
|
||||
|
||||
SDL_itoa(id, name, 10);
|
||||
new_display->name = SDL_strdup(name);
|
||||
}
|
||||
if (new_display->content_scale == 0.0f) {
|
||||
new_display->content_scale = 1.0f;
|
||||
}
|
||||
|
||||
new_display->desktop_mode.displayID = id;
|
||||
new_display->current_mode = &new_display->desktop_mode;
|
||||
SDL_FinalizeDisplayMode(&new_display->desktop_mode);
|
||||
|
||||
for (i = 0; i < new_display->num_fullscreen_modes; ++i) {
|
||||
new_display->fullscreen_modes[i].displayID = id;
|
||||
}
|
||||
|
||||
if (send_event) {
|
||||
SDL_SendDisplayEvent(new_display, SDL_EVENT_DISPLAY_CONNECTED, 0);
|
||||
}
|
||||
} else {
|
||||
new_display = (SDL_VideoDisplay *)SDL_malloc(sizeof(*new_display));
|
||||
if (!new_display) {
|
||||
SDL_OutOfMemory();
|
||||
return 0;
|
||||
}
|
||||
|
||||
displays = (SDL_VideoDisplay **)SDL_realloc(_this->displays, (_this->num_displays + 1) * sizeof(*displays));
|
||||
if (!displays) {
|
||||
SDL_OutOfMemory();
|
||||
SDL_free(new_display);
|
||||
return 0;
|
||||
}
|
||||
_this->displays = displays;
|
||||
_this->displays[_this->num_displays++] = new_display;
|
||||
|
||||
id = _this->next_object_id++;
|
||||
SDL_memcpy(new_display, display, sizeof(*new_display));
|
||||
new_display->id = id;
|
||||
new_display->device = _this;
|
||||
if (display->name) {
|
||||
new_display->name = SDL_strdup(display->name);
|
||||
} else {
|
||||
char name[32];
|
||||
|
||||
SDL_itoa(id, name, 10);
|
||||
new_display->name = SDL_strdup(name);
|
||||
}
|
||||
if (new_display->content_scale == 0.0f) {
|
||||
new_display->content_scale = 1.0f;
|
||||
}
|
||||
|
||||
new_display->desktop_mode.displayID = id;
|
||||
new_display->current_mode = &new_display->desktop_mode;
|
||||
SDL_FinalizeDisplayMode(&new_display->desktop_mode);
|
||||
|
||||
for (i = 0; i < new_display->num_fullscreen_modes; ++i) {
|
||||
new_display->fullscreen_modes[i].displayID = id;
|
||||
}
|
||||
|
||||
if (send_event) {
|
||||
SDL_SendDisplayEvent(new_display, SDL_EVENT_DISPLAY_CONNECTED, 0);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
@ -713,7 +710,7 @@ void SDL_DelVideoDisplay(SDL_DisplayID displayID, SDL_bool send_event)
|
||||
return;
|
||||
}
|
||||
|
||||
display = &_this->displays[display_index];
|
||||
display = _this->displays[display_index];
|
||||
|
||||
if (send_event) {
|
||||
SDL_SendDisplayEvent(display, SDL_EVENT_DISPLAY_DISCONNECTED, 0);
|
||||
@ -725,6 +722,7 @@ void SDL_DelVideoDisplay(SDL_DisplayID displayID, SDL_bool send_event)
|
||||
display->desktop_mode.driverdata = NULL;
|
||||
SDL_free(display->driverdata);
|
||||
display->driverdata = NULL;
|
||||
SDL_free(display);
|
||||
|
||||
if (display_index < (_this->num_displays - 1)) {
|
||||
SDL_memmove(&_this->displays[display_index], &_this->displays[display_index + 1], (_this->num_displays - display_index - 1) * sizeof(_this->displays[display_index]));
|
||||
@ -753,7 +751,7 @@ SDL_DisplayID *SDL_GetDisplays(int *count)
|
||||
}
|
||||
|
||||
for (i = 0; i < _this->num_displays; ++i) {
|
||||
displays[i] = _this->displays[i].id;
|
||||
displays[i] = _this->displays[i]->id;
|
||||
}
|
||||
displays[i] = 0;
|
||||
} else {
|
||||
@ -774,7 +772,7 @@ SDL_VideoDisplay *SDL_GetVideoDisplay(SDL_DisplayID displayID)
|
||||
if (display_index < 0) {
|
||||
return NULL;
|
||||
}
|
||||
return &_this->displays[display_index];
|
||||
return _this->displays[display_index];
|
||||
}
|
||||
|
||||
SDL_VideoDisplay *SDL_GetVideoDisplayForWindow(SDL_Window *window)
|
||||
@ -788,7 +786,7 @@ SDL_DisplayID SDL_GetPrimaryDisplay(void)
|
||||
SDL_UninitializedVideo();
|
||||
return 0;
|
||||
}
|
||||
return _this->displays[0].id;
|
||||
return _this->displays[0]->id;
|
||||
}
|
||||
|
||||
int SDL_GetDisplayIndex(SDL_DisplayID displayID)
|
||||
@ -800,7 +798,7 @@ int SDL_GetDisplayIndex(SDL_DisplayID displayID)
|
||||
}
|
||||
|
||||
for (display_index = 0; display_index < _this->num_displays; ++display_index) {
|
||||
if (displayID == _this->displays[display_index].id) {
|
||||
if (displayID == _this->displays[display_index]->id) {
|
||||
return display_index;
|
||||
}
|
||||
}
|
||||
@ -851,7 +849,7 @@ int SDL_GetDisplayBounds(SDL_DisplayID displayID, SDL_Rect *rect)
|
||||
rect->x = 0;
|
||||
rect->y = 0;
|
||||
} else {
|
||||
SDL_GetDisplayBounds(_this->displays[SDL_GetDisplayIndex(displayID) - 1].id, rect);
|
||||
SDL_GetDisplayBounds(_this->displays[SDL_GetDisplayIndex(displayID) - 1]->id, rect);
|
||||
rect->x += rect->w;
|
||||
}
|
||||
rect->w = display->current_mode->w;
|
||||
@ -1254,7 +1252,7 @@ static SDL_DisplayID GetDisplayForRect(int x, int y, int w, int h)
|
||||
|
||||
if (_this) {
|
||||
for (i = 0; i < _this->num_displays; ++i) {
|
||||
SDL_VideoDisplay *display = &_this->displays[i];
|
||||
SDL_VideoDisplay *display = _this->displays[i];
|
||||
SDL_Rect display_rect;
|
||||
SDL_GetDisplayBounds(display->id, &display_rect);
|
||||
|
||||
@ -1388,14 +1386,14 @@ static void SDL_CheckWindowDisplayChanged(SDL_Window *window)
|
||||
/* Sanity check our fullscreen windows */
|
||||
display_index = SDL_GetDisplayIndex(displayID);
|
||||
for (i = 0; i < _this->num_displays; ++i) {
|
||||
SDL_VideoDisplay *display = &_this->displays[i];
|
||||
SDL_VideoDisplay *display = _this->displays[i];
|
||||
|
||||
if (display->fullscreen_window == window) {
|
||||
if (display_index != i) {
|
||||
if (display_index < 0) {
|
||||
display_index = i;
|
||||
} else {
|
||||
SDL_VideoDisplay *new_display = &_this->displays[display_index];
|
||||
SDL_VideoDisplay *new_display = _this->displays[display_index];
|
||||
|
||||
/* The window was moved to a different display */
|
||||
if (new_display->fullscreen_window &&
|
||||
@ -1487,7 +1485,7 @@ static int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen)
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < _this->num_displays; ++i) {
|
||||
display = &_this->displays[i];
|
||||
display = _this->displays[i];
|
||||
if (display->fullscreen_window == window) {
|
||||
break;
|
||||
}
|
||||
@ -1526,7 +1524,7 @@ static int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen)
|
||||
}
|
||||
} else if (fullscreen && window->last_fullscreen_exclusive_display && !window->fullscreen_exclusive) {
|
||||
for (i = 0; i < _this->num_displays; ++i) {
|
||||
SDL_VideoDisplay *last_display = &_this->displays[i];
|
||||
SDL_VideoDisplay *last_display = _this->displays[i];
|
||||
if (last_display->fullscreen_window == window) {
|
||||
SDL_SetDisplayModeForDisplay(last_display, NULL);
|
||||
if (_this->SetWindowFullscreen) {
|
||||
@ -1582,7 +1580,7 @@ static int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen)
|
||||
|
||||
/* Restore the video mode on other displays if needed */
|
||||
for (i = 0; i < _this->num_displays; ++i) {
|
||||
SDL_VideoDisplay *other = &_this->displays[i];
|
||||
SDL_VideoDisplay *other = _this->displays[i];
|
||||
if (other != display && other->fullscreen_window == window) {
|
||||
SDL_SetDisplayModeForDisplay(other, NULL);
|
||||
if (_this->SetWindowFullscreen) {
|
||||
@ -3731,7 +3729,7 @@ void SDL_VideoQuit(void)
|
||||
_this->VideoQuit(_this);
|
||||
|
||||
for (i = _this->num_displays; i--; ) {
|
||||
SDL_VideoDisplay *display = &_this->displays[i];
|
||||
SDL_VideoDisplay *display = _this->displays[i];
|
||||
SDL_DelVideoDisplay(display->id, SDL_FALSE);
|
||||
}
|
||||
if (_this->displays) {
|
||||
@ -5056,6 +5054,19 @@ SDL_bool SDL_ShouldAllowTopmost(void)
|
||||
return SDL_GetHintBoolean(SDL_HINT_ALLOW_TOPMOST, SDL_TRUE);
|
||||
}
|
||||
|
||||
int SDL_ShowWindowSystemMenu(SDL_Window *window, int x, int y)
|
||||
{
|
||||
CHECK_WINDOW_MAGIC(window, -1)
|
||||
CHECK_WINDOW_NOT_POPUP(window, -1)
|
||||
|
||||
if (_this->ShowWindowSystemMenu) {
|
||||
_this->ShowWindowSystemMenu(window, x, y);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
int SDL_SetWindowHitTest(SDL_Window *window, SDL_HitTest callback, void *callback_data)
|
||||
{
|
||||
CHECK_WINDOW_MAGIC(window, -1);
|
||||
|
@ -108,7 +108,7 @@ void Android_PumpEvents_Blocking(SDL_VideoDevice *_this)
|
||||
|
||||
ANDROIDAUDIO_PauseDevices();
|
||||
openslES_PauseDevices();
|
||||
aaudio_PauseDevices();
|
||||
AAUDIO_PauseDevices();
|
||||
|
||||
if (SDL_WaitSemaphore(Android_ResumeSem) == 0) {
|
||||
|
||||
@ -119,7 +119,7 @@ void Android_PumpEvents_Blocking(SDL_VideoDevice *_this)
|
||||
|
||||
ANDROIDAUDIO_ResumeDevices();
|
||||
openslES_ResumeDevices();
|
||||
aaudio_ResumeDevices();
|
||||
AAUDIO_ResumeDevices();
|
||||
|
||||
/* Restore the GL Context from here, as this operation is thread dependent */
|
||||
#ifdef SDL_VIDEO_OPENGL_EGL
|
||||
@ -160,9 +160,9 @@ void Android_PumpEvents_Blocking(SDL_VideoDevice *_this)
|
||||
}
|
||||
}
|
||||
|
||||
if (aaudio_DetectBrokenPlayState()) {
|
||||
aaudio_PauseDevices();
|
||||
aaudio_ResumeDevices();
|
||||
if (AAUDIO_DetectBrokenPlayState()) {
|
||||
AAUDIO_PauseDevices();
|
||||
AAUDIO_ResumeDevices();
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,7 +187,7 @@ void Android_PumpEvents_NonBlocking(SDL_VideoDevice *_this)
|
||||
if (videodata->pauseAudio) {
|
||||
ANDROIDAUDIO_PauseDevices();
|
||||
openslES_PauseDevices();
|
||||
aaudio_PauseDevices();
|
||||
AAUDIO_PauseDevices();
|
||||
}
|
||||
|
||||
backup_context = 0;
|
||||
@ -203,7 +203,7 @@ void Android_PumpEvents_NonBlocking(SDL_VideoDevice *_this)
|
||||
if (videodata->pauseAudio) {
|
||||
ANDROIDAUDIO_ResumeDevices();
|
||||
openslES_ResumeDevices();
|
||||
aaudio_ResumeDevices();
|
||||
AAUDIO_ResumeDevices();
|
||||
}
|
||||
|
||||
#ifdef SDL_VIDEO_OPENGL_EGL
|
||||
@ -246,9 +246,9 @@ void Android_PumpEvents_NonBlocking(SDL_VideoDevice *_this)
|
||||
}
|
||||
}
|
||||
|
||||
if (aaudio_DetectBrokenPlayState()) {
|
||||
aaudio_PauseDevices();
|
||||
aaudio_ResumeDevices();
|
||||
if (AAUDIO_DetectBrokenPlayState()) {
|
||||
AAUDIO_PauseDevices();
|
||||
AAUDIO_ResumeDevices();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -268,7 +268,7 @@ void Android_SendResize(SDL_Window *window)
|
||||
*/
|
||||
SDL_VideoDevice *device = SDL_GetVideoDevice();
|
||||
if (device && device->num_displays > 0) {
|
||||
SDL_VideoDisplay *display = &device->displays[0];
|
||||
SDL_VideoDisplay *display = device->displays[0];
|
||||
SDL_DisplayMode desktop_mode;
|
||||
|
||||
SDL_zero(desktop_mode);
|
||||
|
@ -255,7 +255,7 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
|
||||
SDL_Window *window = device->windows;
|
||||
int i;
|
||||
for (i = 0; i < device->num_displays; ++i) {
|
||||
SDL_Window *fullscreen_window = device->displays[i].fullscreen_window;
|
||||
SDL_Window *fullscreen_window = device->displays[i]->fullscreen_window;
|
||||
if (fullscreen_window) {
|
||||
if (fullscreen_window->flags & SDL_WINDOW_MINIMIZED) {
|
||||
SDL_RestoreWindow(fullscreen_window);
|
||||
|
@ -520,7 +520,7 @@ void Cocoa_QuitModes(SDL_VideoDevice *_this)
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < _this->num_displays; ++i) {
|
||||
SDL_VideoDisplay *display = &_this->displays[i];
|
||||
SDL_VideoDisplay *display = _this->displays[i];
|
||||
SDL_DisplayModeData *mode;
|
||||
|
||||
if (display->current_mode->driverdata != display->desktop_mode.driverdata) {
|
||||
|
@ -2467,9 +2467,9 @@ SDL_DisplayID Cocoa_GetDisplayForWindow(SDL_VideoDevice *_this, SDL_Window *wind
|
||||
displayid = [[screen.deviceDescription objectForKey:@"NSScreenNumber"] unsignedIntValue];
|
||||
|
||||
for (i = 0; i < _this->num_displays; i++) {
|
||||
SDL_DisplayData *displaydata = _this->displays[i].driverdata;
|
||||
SDL_DisplayData *displaydata = _this->displays[i]->driverdata;
|
||||
if (displaydata != NULL && displaydata->display == displayid) {
|
||||
return _this->displays[i].id;
|
||||
return _this->displays[i]->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
14
external/sdl/SDL/src/video/haiku/SDL_BWin.h
vendored
14
external/sdl/SDL/src/video/haiku/SDL_BWin.h
vendored
@ -155,9 +155,12 @@ class SDL_BWin : public BWindow
|
||||
|
||||
void UpdateCurrentView()
|
||||
{
|
||||
#ifdef SDL_VIDEO_OPENGL
|
||||
if (_SDL_GLView != NULL) {
|
||||
SetCurrentView(_SDL_GLView);
|
||||
} else if (_SDL_View != NULL) {
|
||||
} else
|
||||
#endif
|
||||
if (_SDL_View != NULL) {
|
||||
SetCurrentView(_SDL_View);
|
||||
} else {
|
||||
SetCurrentView(NULL);
|
||||
@ -454,10 +457,13 @@ class SDL_BWin : public BWindow
|
||||
delete pendingMessage;
|
||||
}
|
||||
if (_bitmap != NULL) {
|
||||
if (_SDL_View != NULL && _cur_view == _SDL_View)
|
||||
_SDL_View->Draw(Bounds());
|
||||
else if (_SDL_GLView != NULL && _cur_view == _SDL_GLView) {
|
||||
#ifdef SDL_VIDEO_OPENGL
|
||||
if (_SDL_GLView != NULL && _cur_view == _SDL_GLView) {
|
||||
_SDL_GLView->CopyPixelsIn(_bitmap, B_ORIGIN);
|
||||
} else
|
||||
#endif
|
||||
if (_SDL_View != NULL && _cur_view == _SDL_View) {
|
||||
_SDL_View->Draw(Bounds());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -188,7 +188,7 @@ static float CalculateRefreshRate(drmModeModeInfo *mode)
|
||||
den *= mode->vscan;
|
||||
}
|
||||
|
||||
return ((100 * num) / den) / 100.0f;
|
||||
return ((100 * (Sint64)num) / den) / 100.0f;
|
||||
}
|
||||
|
||||
static int KMSDRM_Available(void)
|
||||
|
@ -48,7 +48,6 @@ struct SDL_DisplayData
|
||||
|
||||
static void N3DS_DeleteDevice(SDL_VideoDevice *device)
|
||||
{
|
||||
SDL_free(device->displays);
|
||||
SDL_free(device->driverdata);
|
||||
SDL_free(device);
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ int SDL_RunApp(int argc, char* argv[], SDL_main_func mainFunction, void * reserv
|
||||
return exit_status;
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
#if !TARGET_OS_TV && !TARGET_OS_XR
|
||||
/* Load a launch image using the old UILaunchImageFile-era naming rules. */
|
||||
static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
||||
{
|
||||
@ -142,8 +142,10 @@ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
||||
self.storyboardViewController.view.frame = self.view.bounds;
|
||||
[self.storyboardViewController didMoveToParentViewController:self];
|
||||
|
||||
#if !TARGET_OS_XR
|
||||
UIApplication.sharedApplication.statusBarHidden = self.prefersStatusBarHidden;
|
||||
UIApplication.sharedApplication.statusBarStyle = self.preferredStatusBarStyle;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (BOOL)prefersStatusBarHidden
|
||||
@ -210,11 +212,18 @@ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
||||
NSArray *launchimages = [bundle objectForInfoDictionaryKey:@"UILaunchImages"];
|
||||
NSString *imagename = nil;
|
||||
UIImage *image = nil;
|
||||
|
||||
|
||||
#if TARGET_OS_XR
|
||||
int screenw = SDL_XR_SCREENWIDTH;
|
||||
int screenh = SDL_XR_SCREENHEIGHT;
|
||||
#else
|
||||
int screenw = (int)([UIScreen mainScreen].bounds.size.width + 0.5);
|
||||
int screenh = (int)([UIScreen mainScreen].bounds.size.height + 0.5);
|
||||
#endif
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
|
||||
|
||||
#if !TARGET_OS_TV && !TARGET_OS_XR
|
||||
UIInterfaceOrientation curorient = [UIApplication sharedApplication].statusBarOrientation;
|
||||
|
||||
/* We always want portrait-oriented size, to match UILaunchImageSize. */
|
||||
@ -244,7 +253,7 @@ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
||||
}
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
#if !TARGET_OS_TV && !TARGET_OS_XR
|
||||
UIInterfaceOrientationMask orientmask = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
|
||||
NSString *orientstring = dict[@"UILaunchImageOrientation"];
|
||||
|
||||
@ -273,7 +282,7 @@ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
||||
image = [UIImage imageNamed:imagename];
|
||||
}
|
||||
}
|
||||
#if !TARGET_OS_TV
|
||||
#if !TARGET_OS_TV && !TARGET_OS_XR
|
||||
else {
|
||||
imagename = [bundle objectForInfoDictionaryKey:@"UILaunchImageFile"];
|
||||
|
||||
@ -288,10 +297,15 @@ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
||||
#endif
|
||||
|
||||
if (image) {
|
||||
UIImageView *view = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
#if TARGET_OS_XR
|
||||
CGRect viewFrame = CGRectMake(0, 0, screenw, screenh);
|
||||
#else
|
||||
CGRect viewFrame = [UIScreen mainScreen].bounds;
|
||||
#endif
|
||||
UIImageView *view = [[UIImageView alloc] initWithFrame:viewFrame];
|
||||
UIImageOrientation imageorient = UIImageOrientationUp;
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
#if !TARGET_OS_TV && !TARGET_OS_XR
|
||||
/* Bugs observed / workaround tested in iOS 8.3. */
|
||||
if (UIInterfaceOrientationIsLandscape(curorient)) {
|
||||
if (image.size.width < image.size.height) {
|
||||
@ -420,7 +434,7 @@ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
||||
NSString *screenname = nil;
|
||||
|
||||
/* tvOS only uses a plain launch image. */
|
||||
#if !TARGET_OS_TV
|
||||
#if !TARGET_OS_TV && !TARGET_OS_XR
|
||||
screenname = [bundle objectForInfoDictionaryKey:@"UILaunchStoryboardName"];
|
||||
|
||||
if (screenname) {
|
||||
@ -443,7 +457,12 @@ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
||||
}
|
||||
|
||||
if (vc.view) {
|
||||
launchWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
#if TARGET_OS_XR
|
||||
CGRect viewFrame = CGRectMake(0, 0, SDL_XR_SCREENWIDTH, SDL_XR_SCREENHEIGHT);
|
||||
#else
|
||||
CGRect viewFrame = [UIScreen mainScreen].bounds;
|
||||
#endif
|
||||
launchWindow = [[UIWindow alloc] initWithFrame:viewFrame];
|
||||
|
||||
/* We don't want the launch window immediately hidden when a real SDL
|
||||
* window is shown - we fade it out ourselves when we're ready. */
|
||||
|
@ -57,7 +57,7 @@ static BOOL UIKit_EventPumpEnabled = YES;
|
||||
[notificationCenter addObserver:self selector:@selector(applicationWillEnterForeground) name:UIApplicationWillEnterForegroundNotification object:nil];
|
||||
[notificationCenter addObserver:self selector:@selector(applicationWillTerminate) name:UIApplicationWillTerminateNotification object:nil];
|
||||
[notificationCenter addObserver:self selector:@selector(applicationDidReceiveMemoryWarning) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
|
||||
#if !TARGET_OS_TV
|
||||
#if !TARGET_OS_TV && !TARGET_OS_XR
|
||||
[notificationCenter addObserver:self
|
||||
selector:@selector(applicationDidChangeStatusBarOrientation)
|
||||
name:UIApplicationDidChangeStatusBarOrientationNotification
|
||||
@ -99,7 +99,7 @@ static BOOL UIKit_EventPumpEnabled = YES;
|
||||
SDL_OnApplicationDidReceiveMemoryWarning();
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
#if !TARGET_OS_TV && !TARGET_OS_XR
|
||||
- (void)applicationDidChangeStatusBarOrientation
|
||||
{
|
||||
SDL_OnApplicationDidChangeStatusBarOrientation();
|
||||
|
@ -98,7 +98,11 @@ static BOOL UIKit_ShowMessageBoxAlertController(const SDL_MessageBoxData *messag
|
||||
}
|
||||
|
||||
if (window == nil || window.rootViewController == nil) {
|
||||
#if TARGET_OS_XR
|
||||
alertwindow = [[UIWindow alloc] init];
|
||||
#else
|
||||
alertwindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
#endif
|
||||
alertwindow.rootViewController = [UIViewController new];
|
||||
alertwindow.windowLevel = UIWindowLevelAlert;
|
||||
|
||||
|
@ -81,6 +81,7 @@ SDL_MetalView UIKit_Metal_CreateView(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
CGFloat scale = 1.0;
|
||||
SDL_uikitmetalview *metalview;
|
||||
|
||||
#if !TARGET_OS_XR
|
||||
if (window->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) {
|
||||
/* Set the scale to the natural scale factor of the screen - then
|
||||
* the backing dimensions of the Metal view will match the pixel
|
||||
@ -89,6 +90,7 @@ SDL_MetalView UIKit_Metal_CreateView(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
*/
|
||||
scale = data.uiwindow.screen.nativeScale;
|
||||
}
|
||||
#endif
|
||||
|
||||
metalview = [[SDL_uikitmetalview alloc] initWithFrame:data.uiwindow.bounds
|
||||
scale:scale];
|
||||
|
@ -27,26 +27,39 @@
|
||||
|
||||
@interface SDL_UIKitDisplayData : NSObject
|
||||
|
||||
#if !TARGET_OS_XR
|
||||
- (instancetype)initWithScreen:(UIScreen *)screen;
|
||||
|
||||
@property(nonatomic, strong) UIScreen *uiscreen;
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
@interface SDL_UIKitDisplayModeData : NSObject
|
||||
|
||||
#if !TARGET_OS_XR
|
||||
@property(nonatomic, strong) UIScreenMode *uiscreenmode;
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
#if !TARGET_OS_XR
|
||||
extern SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen);
|
||||
#endif
|
||||
|
||||
extern int UIKit_InitModes(SDL_VideoDevice *_this);
|
||||
#if !TARGET_OS_XR
|
||||
extern int UIKit_AddDisplay(UIScreen *uiscreen, SDL_bool send_event);
|
||||
extern void UIKit_DelDisplay(UIScreen *uiscreen);
|
||||
#endif
|
||||
extern int UIKit_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display);
|
||||
extern int UIKit_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode);
|
||||
extern void UIKit_QuitModes(SDL_VideoDevice *_this);
|
||||
extern int UIKit_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect);
|
||||
|
||||
// because visionOS does not have a screen
|
||||
// we create a fake 1080p display to maintain compatibility.
|
||||
#if TARGET_OS_XR
|
||||
#define SDL_XR_SCREENWIDTH 1920
|
||||
#define SDL_XR_SCREENHEIGHT 1080
|
||||
#endif
|
||||
|
||||
#endif /* SDL_uikitmodes_h_ */
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
@implementation SDL_UIKitDisplayData
|
||||
|
||||
#if !TARGET_OS_XR
|
||||
- (instancetype)initWithScreen:(UIScreen *)screen
|
||||
{
|
||||
if (self = [super init]) {
|
||||
@ -37,20 +38,23 @@
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@synthesize uiscreen;
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
@implementation SDL_UIKitDisplayModeData
|
||||
|
||||
#if !TARGET_OS_XR
|
||||
@synthesize uiscreenmode;
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
@interface SDL_DisplayWatch : NSObject
|
||||
@end
|
||||
|
||||
#if !TARGET_OS_XR
|
||||
@implementation SDL_DisplayWatch
|
||||
|
||||
+ (void)start
|
||||
@ -92,7 +96,9 @@
|
||||
}
|
||||
|
||||
@end
|
||||
#endif
|
||||
|
||||
#if !TARGET_OS_XR
|
||||
static int UIKit_AllocateDisplayModeData(SDL_DisplayMode *mode,
|
||||
UIScreenMode *uiscreenmode)
|
||||
{
|
||||
@ -112,6 +118,7 @@ static int UIKit_AllocateDisplayModeData(SDL_DisplayMode *mode,
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void UIKit_FreeDisplayModeData(SDL_DisplayMode *mode)
|
||||
{
|
||||
@ -121,6 +128,7 @@ static void UIKit_FreeDisplayModeData(SDL_DisplayMode *mode)
|
||||
}
|
||||
}
|
||||
|
||||
#if !TARGET_OS_XR
|
||||
static float UIKit_GetDisplayModeRefreshRate(UIScreen *uiscreen)
|
||||
{
|
||||
#ifdef __IPHONE_10_3
|
||||
@ -235,7 +243,11 @@ int UIKit_AddDisplay(UIScreen *uiscreen, SDL_bool send_event)
|
||||
display.desktop_mode = mode;
|
||||
|
||||
/* Allocate the display data */
|
||||
#if TARGET_OS_XR
|
||||
SDL_UIKitDisplayData *data = [[SDL_UIKitDisplayData alloc] init];
|
||||
#else
|
||||
SDL_UIKitDisplayData *data = [[SDL_UIKitDisplayData alloc] initWithScreen:uiscreen];
|
||||
#endif
|
||||
if (!data) {
|
||||
UIKit_FreeDisplayModeData(&display.desktop_mode);
|
||||
return SDL_OutOfMemory();
|
||||
@ -247,6 +259,41 @@ int UIKit_AddDisplay(UIScreen *uiscreen, SDL_bool send_event)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_XR
|
||||
int UIKit_AddDisplay(SDL_bool send_event){
|
||||
CGSize size = CGSizeMake(SDL_XR_SCREENWIDTH, SDL_XR_SCREENHEIGHT);
|
||||
SDL_VideoDisplay display;
|
||||
SDL_DisplayMode mode;
|
||||
|
||||
SDL_zero(mode);
|
||||
mode.w = (int)size.width;
|
||||
mode.h = (int)size.height;
|
||||
mode.pixel_density = 1;
|
||||
mode.format = SDL_PIXELFORMAT_ABGR8888;
|
||||
mode.refresh_rate = 60;
|
||||
|
||||
display.natural_orientation = SDL_ORIENTATION_LANDSCAPE;
|
||||
|
||||
display.desktop_mode = mode;
|
||||
|
||||
SDL_UIKitDisplayData *data = [[SDL_UIKitDisplayData alloc] init];
|
||||
|
||||
if (!data) {
|
||||
UIKit_FreeDisplayModeData(&display.desktop_mode);
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
display.driverdata = (SDL_DisplayData *)CFBridgingRetain(data);
|
||||
if (SDL_AddVideoDisplay(&display, send_event) == 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !TARGET_OS_XR
|
||||
|
||||
void UIKit_DelDisplay(UIScreen *uiscreen)
|
||||
{
|
||||
@ -281,20 +328,27 @@ SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen)
|
||||
return (size.width > size.height);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
int UIKit_InitModes(SDL_VideoDevice *_this)
|
||||
{
|
||||
@autoreleasepool {
|
||||
#if TARGET_OS_XR
|
||||
UIKit_AddDisplay(SDL_FALSE);
|
||||
#else
|
||||
for (UIScreen *uiscreen in [UIScreen screens]) {
|
||||
if (UIKit_AddDisplay(uiscreen, SDL_FALSE) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#if !TARGET_OS_TV
|
||||
#endif
|
||||
|
||||
#if !TARGET_OS_TV && !TARGET_OS_XR
|
||||
SDL_OnApplicationDidChangeStatusBarOrientation();
|
||||
#endif
|
||||
|
||||
#if !TARGET_OS_XR
|
||||
[SDL_DisplayWatch start];
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -302,6 +356,7 @@ int UIKit_InitModes(SDL_VideoDevice *_this)
|
||||
|
||||
int UIKit_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display)
|
||||
{
|
||||
#if !TARGET_OS_XR
|
||||
@autoreleasepool {
|
||||
SDL_UIKitDisplayData *data = (__bridge SDL_UIKitDisplayData *)display->driverdata;
|
||||
|
||||
@ -331,11 +386,13 @@ int UIKit_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display)
|
||||
UIKit_AddDisplayMode(display, w, h, data.uiscreen, uimode, addRotation);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int UIKit_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
|
||||
{
|
||||
#if !TARGET_OS_XR
|
||||
@autoreleasepool {
|
||||
SDL_UIKitDisplayData *data = (__bridge SDL_UIKitDisplayData *)display->driverdata;
|
||||
|
||||
@ -359,7 +416,7 @@ int UIKit_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -367,7 +424,11 @@ int UIKit_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *displ
|
||||
{
|
||||
@autoreleasepool {
|
||||
SDL_UIKitDisplayData *data = (__bridge SDL_UIKitDisplayData *)display->driverdata;
|
||||
#if TARGET_OS_XR
|
||||
CGRect frame = CGRectMake(0, 0, SDL_XR_SCREENWIDTH, SDL_XR_SCREENHEIGHT);
|
||||
#else
|
||||
CGRect frame = data.uiscreen.bounds;
|
||||
#endif
|
||||
|
||||
/* the default function iterates displays to make a fake offset,
|
||||
as if all the displays were side-by-side, which is fine for iOS. */
|
||||
@ -386,13 +447,15 @@ int UIKit_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *displ
|
||||
|
||||
void UIKit_QuitModes(SDL_VideoDevice *_this)
|
||||
{
|
||||
#if !TARGET_OS_XR
|
||||
[SDL_DisplayWatch stop];
|
||||
#endif
|
||||
|
||||
/* Release Objective-C objects, so higher level doesn't free() them. */
|
||||
int i, j;
|
||||
@autoreleasepool {
|
||||
for (i = 0; i < _this->num_displays; i++) {
|
||||
SDL_VideoDisplay *display = &_this->displays[i];
|
||||
SDL_VideoDisplay *display = _this->displays[i];
|
||||
|
||||
UIKit_FreeDisplayModeData(&display->desktop_mode);
|
||||
for (j = 0; j < display->num_fullscreen_modes; j++) {
|
||||
@ -408,7 +471,7 @@ void UIKit_QuitModes(SDL_VideoDevice *_this)
|
||||
}
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
#if !TARGET_OS_TV && !TARGET_OS_XR
|
||||
void SDL_OnApplicationDidChangeStatusBarOrientation(void)
|
||||
{
|
||||
BOOL isLandscape = UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation);
|
||||
|
@ -33,7 +33,11 @@
|
||||
|
||||
@end
|
||||
|
||||
#if TARGET_OS_XR
|
||||
CGRect UIKit_ComputeViewFrame(SDL_Window *window);
|
||||
#else
|
||||
CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen);
|
||||
#endif
|
||||
|
||||
#endif /* __OBJC__ */
|
||||
|
||||
|
@ -52,7 +52,9 @@ static void UIKit_VideoQuit(SDL_VideoDevice *_this);
|
||||
static void UIKit_DeleteDevice(SDL_VideoDevice *device)
|
||||
{
|
||||
@autoreleasepool {
|
||||
CFRelease(device->driverdata);
|
||||
if (device->driverdata){
|
||||
CFRelease(device->driverdata);
|
||||
}
|
||||
SDL_free(device);
|
||||
}
|
||||
}
|
||||
@ -183,6 +185,7 @@ SDL_bool UIKit_IsSystemVersionAtLeast(double version)
|
||||
|
||||
SDL_SystemTheme UIKit_GetSystemTheme(void)
|
||||
{
|
||||
#if !TARGET_OS_XR
|
||||
if (@available(iOS 12.0, tvOS 10.0, *)) {
|
||||
switch ([UIScreen mainScreen].traitCollection.userInterfaceStyle) {
|
||||
case UIUserInterfaceStyleDark:
|
||||
@ -193,9 +196,15 @@ SDL_SystemTheme UIKit_GetSystemTheme(void)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return SDL_SYSTEM_THEME_UNKNOWN;
|
||||
}
|
||||
|
||||
#if TARGET_OS_XR
|
||||
CGRect UIKit_ComputeViewFrame(SDL_Window *window){
|
||||
return CGRectMake(window->x, window->y, window->w, window->h);
|
||||
}
|
||||
#else
|
||||
CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen)
|
||||
{
|
||||
SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->driverdata;
|
||||
@ -234,6 +243,8 @@ CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen)
|
||||
return frame;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void UIKit_ForceUpdateHomeIndicator(void)
|
||||
{
|
||||
#if !TARGET_OS_TV
|
||||
|
12
external/sdl/SDL/src/video/uikit/SDL_uikitview.m
vendored
12
external/sdl/SDL/src/video/uikit/SDL_uikitview.m
vendored
@ -417,6 +417,9 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
|
||||
SDL_SendKeyboardKey(UIKit_GetEventTimestamp([event timestamp]), SDL_PRESSED, scancode);
|
||||
}
|
||||
}
|
||||
if (SDL_TextInputActive()) {
|
||||
[super pressesBegan:presses withEvent:event];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
|
||||
@ -427,6 +430,9 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
|
||||
SDL_SendKeyboardKey(UIKit_GetEventTimestamp([event timestamp]), SDL_RELEASED, scancode);
|
||||
}
|
||||
}
|
||||
if (SDL_TextInputActive()) {
|
||||
[super pressesEnded:presses withEvent:event];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)pressesCancelled:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
|
||||
@ -437,11 +443,17 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
|
||||
SDL_SendKeyboardKey(UIKit_GetEventTimestamp([event timestamp]), SDL_RELEASED, scancode);
|
||||
}
|
||||
}
|
||||
if (SDL_TextInputActive()) {
|
||||
[super pressesCancelled:presses withEvent:event];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)pressesChanged:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
|
||||
{
|
||||
/* This is only called when the force of a press changes. */
|
||||
if (SDL_TextInputActive()) {
|
||||
[super pressesChanged:presses withEvent:event];
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* TARGET_OS_TV || defined(__IPHONE_9_1) */
|
||||
|
@ -63,11 +63,11 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
|
||||
@implementation SDLUITextField : UITextField
|
||||
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
|
||||
{
|
||||
if (action == @selector(paste:)) {
|
||||
return NO;
|
||||
}
|
||||
if (action == @selector(paste:)) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
return [super canPerformAction:action withSender:sender];
|
||||
return [super canPerformAction:action withSender:sender];
|
||||
}
|
||||
@end
|
||||
|
||||
@ -82,6 +82,7 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
|
||||
SDLUITextField *textField;
|
||||
BOOL hardwareKeyboard;
|
||||
BOOL showingKeyboard;
|
||||
BOOL hidingKeyboard;
|
||||
BOOL rotatingOrientation;
|
||||
NSString *committedText;
|
||||
NSString *obligateForBackspace;
|
||||
@ -99,6 +100,7 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
|
||||
[self initKeyboard];
|
||||
hardwareKeyboard = NO;
|
||||
showingKeyboard = NO;
|
||||
hidingKeyboard = NO;
|
||||
rotatingOrientation = NO;
|
||||
#endif
|
||||
|
||||
@ -160,7 +162,9 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
|
||||
{
|
||||
displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(doLoop:)];
|
||||
|
||||
#ifdef __IPHONE_10_3
|
||||
#if TARGET_OS_XR
|
||||
displayLink.preferredFramesPerSecond = 90 / animationInterval; //TODO: Get frame max frame rate on visionOS
|
||||
#elif defined(__IPHONE_10_3)
|
||||
SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->driverdata;
|
||||
|
||||
if ([displayLink respondsToSelector:@selector(preferredFramesPerSecond)] && data != nil && data.uiwindow != nil && [data.uiwindow.screen respondsToSelector:@selector(maximumFramesPerSecond)]) {
|
||||
@ -292,7 +296,18 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
|
||||
selector:@selector(keyboardWillShow:)
|
||||
name:UIKeyboardWillShowNotification
|
||||
object:nil];
|
||||
[center addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
|
||||
[center addObserver:self
|
||||
selector:@selector(keyboardDidShow:)
|
||||
name:UIKeyboardDidShowNotification
|
||||
object:nil];
|
||||
[center addObserver:self
|
||||
selector:@selector(keyboardWillHide:)
|
||||
name:UIKeyboardWillHideNotification
|
||||
object:nil];
|
||||
[center addObserver:self
|
||||
selector:@selector(keyboardDidHide:)
|
||||
name:UIKeyboardDidHideNotification
|
||||
object:nil];
|
||||
#endif
|
||||
[center addObserver:self
|
||||
selector:@selector(textFieldTextDidChange:)
|
||||
@ -363,7 +378,15 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
|
||||
[center removeObserver:self
|
||||
name:UIKeyboardWillShowNotification
|
||||
object:nil];
|
||||
[center removeObserver:self name:UIKeyboardWillHideNotification object:nil];
|
||||
[center removeObserver:self
|
||||
name:UIKeyboardDidShowNotification
|
||||
object:nil];
|
||||
[center removeObserver:self
|
||||
name:UIKeyboardWillHideNotification
|
||||
object:nil];
|
||||
[center removeObserver:self
|
||||
name:UIKeyboardDidHideNotification
|
||||
object:nil];
|
||||
#endif
|
||||
[center removeObserver:self
|
||||
name:UITextFieldTextDidChangeNotification
|
||||
@ -373,23 +396,40 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
|
||||
/* reveal onscreen virtual keyboard */
|
||||
- (void)showKeyboard
|
||||
{
|
||||
if (keyboardVisible) {
|
||||
return;
|
||||
}
|
||||
|
||||
keyboardVisible = YES;
|
||||
if (textField.window) {
|
||||
showingKeyboard = YES;
|
||||
[textField becomeFirstResponder];
|
||||
showingKeyboard = NO;
|
||||
}
|
||||
}
|
||||
|
||||
/* hide onscreen virtual keyboard */
|
||||
- (void)hideKeyboard
|
||||
{
|
||||
if (!keyboardVisible) {
|
||||
return;
|
||||
}
|
||||
|
||||
keyboardVisible = NO;
|
||||
[textField resignFirstResponder];
|
||||
if (textField.window) {
|
||||
hidingKeyboard = YES;
|
||||
[textField resignFirstResponder];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)keyboardWillShow:(NSNotification *)notification
|
||||
{
|
||||
BOOL shouldStartTextInput = NO;
|
||||
|
||||
if (!SDL_TextInputActive() && !hidingKeyboard && !rotatingOrientation) {
|
||||
shouldStartTextInput = YES;
|
||||
}
|
||||
|
||||
showingKeyboard = YES;
|
||||
#if !TARGET_OS_TV
|
||||
CGRect kbrect = [[notification userInfo][UIKeyboardFrameEndUserInfoKey] CGRectValue];
|
||||
|
||||
@ -399,14 +439,36 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
|
||||
|
||||
[self setKeyboardHeight:(int)kbrect.size.height];
|
||||
#endif
|
||||
|
||||
if (shouldStartTextInput) {
|
||||
SDL_StartTextInput();
|
||||
}
|
||||
}
|
||||
|
||||
- (void)keyboardDidShow:(NSNotification *)notification
|
||||
{
|
||||
showingKeyboard = NO;
|
||||
}
|
||||
|
||||
- (void)keyboardWillHide:(NSNotification *)notification
|
||||
{
|
||||
if (!showingKeyboard && !rotatingOrientation) {
|
||||
BOOL shouldStopTextInput = NO;
|
||||
|
||||
if (SDL_TextInputActive() && !showingKeyboard && !rotatingOrientation) {
|
||||
shouldStopTextInput = YES;
|
||||
}
|
||||
|
||||
hidingKeyboard = YES;
|
||||
[self setKeyboardHeight:0];
|
||||
|
||||
if (shouldStopTextInput) {
|
||||
SDL_StopTextInput();
|
||||
}
|
||||
[self setKeyboardHeight:0];
|
||||
}
|
||||
|
||||
- (void)keyboardDidHide:(NSNotification *)notification
|
||||
{
|
||||
hidingKeyboard = NO;
|
||||
}
|
||||
|
||||
- (void)textFieldTextDidChange:(NSNotification *)notification
|
||||
@ -425,8 +487,8 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
|
||||
size_t deleteLength = SDL_utf8strlen([[committedText substringFromIndex:matchLength] UTF8String]);
|
||||
while (deleteLength > 0) {
|
||||
/* Send distinct down and up events for each backspace action */
|
||||
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_BACKSPACE);
|
||||
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_BACKSPACE);
|
||||
SDL_SendVirtualKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_BACKSPACE);
|
||||
SDL_SendVirtualKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_BACKSPACE);
|
||||
--deleteLength;
|
||||
}
|
||||
}
|
||||
@ -451,7 +513,11 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
|
||||
{
|
||||
CGAffineTransform t = self.view.transform;
|
||||
CGPoint offset = CGPointMake(0.0, 0.0);
|
||||
#if TARGET_OS_XR
|
||||
CGRect frame = UIKit_ComputeViewFrame(window);
|
||||
#else
|
||||
CGRect frame = UIKit_ComputeViewFrame(window, self.view.window.screen);
|
||||
#endif
|
||||
|
||||
if (self.keyboardHeight) {
|
||||
int rectbottom = self.textInputRect.y + self.textInputRect.h;
|
||||
|
@ -65,6 +65,7 @@
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
#if !TARGET_OS_XR
|
||||
/* Workaround to fix window orientation issues in iOS 8. */
|
||||
/* As of July 1 2019, I haven't been able to reproduce any orientation
|
||||
* issues with this disabled on iOS 12. The issue this is meant to fix might
|
||||
@ -74,6 +75,7 @@
|
||||
if (!UIKit_IsSystemVersionAtLeast(9.0)) {
|
||||
self.frame = self.screen.bounds;
|
||||
}
|
||||
#endif
|
||||
[super layoutSubviews];
|
||||
}
|
||||
|
||||
@ -84,8 +86,13 @@ static int SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, UIWindow
|
||||
SDL_VideoDisplay *display = SDL_GetVideoDisplayForWindow(window);
|
||||
SDL_UIKitDisplayData *displaydata = (__bridge SDL_UIKitDisplayData *)display->driverdata;
|
||||
SDL_uikitview *view;
|
||||
|
||||
|
||||
#if TARGET_OS_XR
|
||||
CGRect frame = UIKit_ComputeViewFrame(window);
|
||||
#else
|
||||
CGRect frame = UIKit_ComputeViewFrame(window, displaydata.uiscreen);
|
||||
#endif
|
||||
|
||||
int width = (int)frame.size.width;
|
||||
int height = (int)frame.size.height;
|
||||
|
||||
@ -98,13 +105,15 @@ static int SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, UIWindow
|
||||
|
||||
data.uiwindow = uiwindow;
|
||||
|
||||
#if !TARGET_OS_XR
|
||||
if (displaydata.uiscreen != [UIScreen mainScreen]) {
|
||||
window->flags &= ~SDL_WINDOW_RESIZABLE; /* window is NEVER resizable */
|
||||
window->flags &= ~SDL_WINDOW_INPUT_FOCUS; /* never has input focus */
|
||||
window->flags |= SDL_WINDOW_BORDERLESS; /* never has a status bar. */
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
#if !TARGET_OS_TV && !TARGET_OS_XR
|
||||
if (displaydata.uiscreen == [UIScreen mainScreen]) {
|
||||
/* SDL_CreateWindow sets the window w&h to the display's bounds if the
|
||||
* fullscreen flag is set. But the display bounds orientation might not
|
||||
@ -166,7 +175,7 @@ int UIKit_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
/* If monitor has a resolution of 0x0 (hasn't been explicitly set by the
|
||||
* user, so it's in standby), try to force the display to a resolution
|
||||
* that most closely matches the desired window size. */
|
||||
#if !TARGET_OS_TV
|
||||
#if !TARGET_OS_TV && !TARGET_OS_XR
|
||||
const CGSize origsize = data.uiscreen.currentMode.size;
|
||||
if ((origsize.width == 0.0f) && (origsize.height == 0.0f)) {
|
||||
const SDL_DisplayMode *bestmode;
|
||||
@ -197,12 +206,18 @@ int UIKit_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
|
||||
/* ignore the size user requested, and make a fullscreen window */
|
||||
/* !!! FIXME: can we have a smaller view? */
|
||||
#if TARGET_OS_XR
|
||||
UIWindow *uiwindow = [[SDL_uikitwindow alloc] initWithFrame:CGRectMake(window->x, window->y, window->w, window->h)];
|
||||
#else
|
||||
UIWindow *uiwindow = [[SDL_uikitwindow alloc] initWithFrame:data.uiscreen.bounds];
|
||||
#endif
|
||||
|
||||
/* put the window on an external display if appropriate. */
|
||||
#if !TARGET_OS_XR
|
||||
if (data.uiscreen != [UIScreen mainScreen]) {
|
||||
[uiwindow setScreen:data.uiscreen];
|
||||
}
|
||||
#endif
|
||||
|
||||
if (SetupWindowData(_this, window, uiwindow, SDL_TRUE) < 0) {
|
||||
return -1;
|
||||
@ -229,7 +244,10 @@ void UIKit_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
/* Make this window the current mouse focus for touch input */
|
||||
SDL_VideoDisplay *display = SDL_GetVideoDisplayForWindow(window);
|
||||
SDL_UIKitDisplayData *displaydata = (__bridge SDL_UIKitDisplayData *)display->driverdata;
|
||||
if (displaydata.uiscreen == [UIScreen mainScreen]) {
|
||||
#if !TARGET_OS_XR
|
||||
if (displaydata.uiscreen == [UIScreen mainScreen])
|
||||
#endif
|
||||
{
|
||||
SDL_SetMouseFocus(window);
|
||||
SDL_SetKeyboardFocus(window);
|
||||
}
|
||||
@ -258,7 +276,7 @@ static void UIKit_UpdateWindowBorder(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->driverdata;
|
||||
SDL_uikitviewcontroller *viewcontroller = data.viewcontroller;
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
#if !TARGET_OS_TV && !TARGET_OS_XR
|
||||
if (data.uiwindow.screen == [UIScreen mainScreen]) {
|
||||
if (window->flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS)) {
|
||||
[UIApplication sharedApplication].statusBarHidden = YES;
|
||||
@ -354,9 +372,11 @@ void UIKit_GetWindowSizeInPixels(SDL_VideoDevice *_this, SDL_Window *window, int
|
||||
CGSize size = view.bounds.size;
|
||||
CGFloat scale = 1.0;
|
||||
|
||||
#if !TARGET_OS_XR
|
||||
if (window->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) {
|
||||
scale = windata.uiwindow.screen.nativeScale;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Integer truncation of fractional values matches SDL_uikitmetalview and
|
||||
* SDL_uikitopenglview. */
|
||||
|
@ -158,6 +158,7 @@ void SDL_WAYLAND_UnloadSymbols(void);
|
||||
#define libdecor_frame_is_visible (*WAYLAND_libdecor_frame_is_visible)
|
||||
#define libdecor_frame_is_floating (*WAYLAND_libdecor_frame_is_floating)
|
||||
#define libdecor_frame_set_parent (*WAYLAND_libdecor_frame_set_parent)
|
||||
#define libdecor_frame_show_window_menu (*WAYLAND_libdecor_frame_show_window_menu)
|
||||
#define libdecor_frame_get_xdg_surface (*WAYLAND_libdecor_frame_get_xdg_surface)
|
||||
#define libdecor_frame_get_xdg_toplevel (*WAYLAND_libdecor_frame_get_xdg_toplevel)
|
||||
#define libdecor_frame_translate_coordinate (*WAYLAND_libdecor_frame_translate_coordinate)
|
||||
|
@ -311,12 +311,25 @@ static SDL_bool keyboard_repeat_key_is_set(SDL_WaylandKeyboardRepeat *repeat_inf
|
||||
return repeat_info->is_initialized && repeat_info->is_key_down && key == repeat_info->key;
|
||||
}
|
||||
|
||||
static void sync_done_handler(void *data, struct wl_callback *callback, uint32_t callback_data)
|
||||
{
|
||||
/* Nothing to do, just destroy the callback */
|
||||
wl_callback_destroy(callback);
|
||||
}
|
||||
|
||||
static struct wl_callback_listener sync_listener = {
|
||||
sync_done_handler
|
||||
};
|
||||
|
||||
void Wayland_SendWakeupEvent(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
{
|
||||
SDL_VideoData *d = _this->driverdata;
|
||||
|
||||
/* TODO: Maybe use a pipe to avoid the compositor roundtrip? */
|
||||
wl_display_sync(d->display);
|
||||
/* Queue a sync event to unblock the event queue fd if it's empty and being waited on.
|
||||
* TODO: Maybe use a pipe to avoid the compositor roundtrip?
|
||||
*/
|
||||
struct wl_callback *cb = wl_display_sync(d->display);
|
||||
wl_callback_add_listener(cb, &sync_listener, NULL);
|
||||
WAYLAND_wl_display_flush(d->display);
|
||||
}
|
||||
|
||||
@ -541,6 +554,19 @@ static void pointer_handle_leave(void *data, struct wl_pointer *pointer,
|
||||
}
|
||||
|
||||
if (input->pointer_focus) {
|
||||
SDL_WindowData *wind = (SDL_WindowData *)wl_surface_get_user_data(surface);
|
||||
|
||||
if (wind) {
|
||||
/* Clear the capture flag and raise all buttons */
|
||||
wind->sdlwindow->flags &= ~SDL_WINDOW_MOUSE_CAPTURE;
|
||||
|
||||
SDL_SendMouseButton(Wayland_GetPointerTimestamp(input, 0), wind->sdlwindow, 0, SDL_RELEASED, SDL_BUTTON_LEFT);
|
||||
SDL_SendMouseButton(Wayland_GetPointerTimestamp(input, 0), wind->sdlwindow, 0, SDL_RELEASED, SDL_BUTTON_RIGHT);
|
||||
SDL_SendMouseButton(Wayland_GetPointerTimestamp(input, 0), wind->sdlwindow, 0, SDL_RELEASED, SDL_BUTTON_MIDDLE);
|
||||
SDL_SendMouseButton(Wayland_GetPointerTimestamp(input, 0), wind->sdlwindow, 0, SDL_RELEASED, SDL_BUTTON_X1);
|
||||
SDL_SendMouseButton(Wayland_GetPointerTimestamp(input, 0), wind->sdlwindow, 0, SDL_RELEASED, SDL_BUTTON_X2);
|
||||
}
|
||||
|
||||
SDL_SetMouseFocus(NULL);
|
||||
input->pointer_focus = NULL;
|
||||
}
|
||||
@ -2705,6 +2731,9 @@ void Wayland_display_destroy_input(SDL_VideoData *d)
|
||||
if (input->primary_selection_device->selection_source != NULL) {
|
||||
Wayland_primary_selection_source_destroy(input->primary_selection_device->selection_source);
|
||||
}
|
||||
if (input->primary_selection_device->primary_selection_device != NULL) {
|
||||
zwp_primary_selection_device_v1_destroy(input->primary_selection_device->primary_selection_device);
|
||||
}
|
||||
SDL_free(input->primary_selection_device);
|
||||
}
|
||||
|
||||
|
@ -204,6 +204,7 @@ SDL_WAYLAND_SYM(bool, libdecor_frame_is_visible, (struct libdecor_frame *))
|
||||
SDL_WAYLAND_SYM(bool, libdecor_frame_is_floating, (struct libdecor_frame *))
|
||||
SDL_WAYLAND_SYM(void, libdecor_frame_set_parent, (struct libdecor_frame *,\
|
||||
struct libdecor_frame *))
|
||||
SDL_WAYLAND_SYM(void, libdecor_frame_show_window_menu, (struct libdecor_frame *, struct wl_seat *, uint32_t, int, int))
|
||||
SDL_WAYLAND_SYM(struct xdg_surface *, libdecor_frame_get_xdg_surface, (struct libdecor_frame *))
|
||||
SDL_WAYLAND_SYM(struct xdg_toplevel *, libdecor_frame_get_xdg_toplevel, (struct libdecor_frame *))
|
||||
SDL_WAYLAND_SYM(void, libdecor_frame_translate_coordinate, (struct libdecor_frame *, int, int, int *, int *))
|
||||
|
@ -209,6 +209,7 @@ static SDL_VideoDevice *Wayland_CreateDevice(void)
|
||||
device->SetWindowHitTest = Wayland_SetWindowHitTest;
|
||||
device->FlashWindow = Wayland_FlashWindow;
|
||||
device->HasScreenKeyboardSupport = Wayland_HasScreenKeyboardSupport;
|
||||
device->ShowWindowSystemMenu = Wayland_ShowWindowSystemMenu;
|
||||
|
||||
#ifdef SDL_USE_LIBDBUS
|
||||
if (SDL_SystemTheme_Init())
|
||||
@ -672,6 +673,10 @@ static void Wayland_free_display(SDL_VideoDisplay *display)
|
||||
SDL_DisplayData *display_data = display->driverdata;
|
||||
int i;
|
||||
|
||||
if (display_data->xdg_output) {
|
||||
zxdg_output_v1_destroy(display_data->xdg_output);
|
||||
}
|
||||
|
||||
if (wl_output_get_version(display_data->output) >= WL_OUTPUT_RELEASE_SINCE_VERSION) {
|
||||
wl_output_release(display_data->output);
|
||||
} else {
|
||||
@ -931,7 +936,7 @@ static void Wayland_VideoCleanup(SDL_VideoDevice *_this)
|
||||
Wayland_FiniMouse(data);
|
||||
|
||||
for (i = _this->num_displays - 1; i >= 0; --i) {
|
||||
SDL_VideoDisplay *display = &_this->displays[i];
|
||||
SDL_VideoDisplay *display = _this->displays[i];
|
||||
Wayland_free_display(display);
|
||||
}
|
||||
|
||||
|
@ -2154,7 +2154,7 @@ int Wayland_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
if (window->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) {
|
||||
int i;
|
||||
for (i = 0; i < _this->num_displays; i++) {
|
||||
float scale = _this->displays[i].driverdata->scale_factor;
|
||||
float scale = _this->displays[i]->driverdata->scale_factor;
|
||||
data->windowed_scale_factor = SDL_max(data->windowed_scale_factor, scale);
|
||||
}
|
||||
}
|
||||
@ -2357,6 +2357,23 @@ void Wayland_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
WAYLAND_wl_display_flush(viddata->display);
|
||||
}
|
||||
|
||||
void Wayland_ShowWindowSystemMenu(SDL_Window *window, int x, int y)
|
||||
{
|
||||
SDL_WindowData *wind = window->driverdata;
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) {
|
||||
if (wind->shell_surface.libdecor.frame) {
|
||||
libdecor_frame_show_window_menu(wind->shell_surface.libdecor.frame, wind->waylandData->input->seat, wind->waylandData->input->last_implicit_grab_serial, x, y);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL) {
|
||||
if (wind->shell_surface.xdg.roleobj.toplevel) {
|
||||
xdg_toplevel_show_window_menu(wind->shell_surface.xdg.roleobj.toplevel, wind->waylandData->input->seat, wind->waylandData->input->last_implicit_grab_serial, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Wayland_SuspendScreenSaver(SDL_VideoDevice *_this)
|
||||
{
|
||||
SDL_VideoData *data = _this->driverdata;
|
||||
|
@ -150,6 +150,7 @@ extern void Wayland_SetWindowMaximumSize(SDL_VideoDevice *_this, SDL_Window *win
|
||||
extern void Wayland_GetWindowSizeInPixels(SDL_VideoDevice *_this, SDL_Window *window, int *w, int *h);
|
||||
extern int Wayland_SetWindowModalFor(SDL_VideoDevice *_this, SDL_Window *modal_window, SDL_Window *parent_window);
|
||||
extern void Wayland_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern void Wayland_ShowWindowSystemMenu(SDL_Window *window, int x, int y);
|
||||
extern void Wayland_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window);
|
||||
extern int Wayland_SuspendScreenSaver(SDL_VideoDevice *_this);
|
||||
|
||||
|
@ -352,18 +352,27 @@ static void WIN_AddDisplay(SDL_VideoDevice *_this, HMONITOR hMonitor, const MONI
|
||||
// ready to be added to allow any displays that we can't fully query to be
|
||||
// removed
|
||||
for (i = 0; i < _this->num_displays; ++i) {
|
||||
SDL_DisplayData *driverdata = _this->displays[i].driverdata;
|
||||
SDL_DisplayData *driverdata = _this->displays[i]->driverdata;
|
||||
if (SDL_wcscmp(driverdata->DeviceName, info->szDevice) == 0) {
|
||||
SDL_bool moved = (index != i);
|
||||
SDL_bool changed_bounds = SDL_FALSE;
|
||||
|
||||
if (moved) {
|
||||
SDL_VideoDisplay tmp;
|
||||
if (driverdata->state != DisplayRemoved) {
|
||||
/* We've already enumerated this display, don't move it */
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_assert(index < _this->num_displays);
|
||||
SDL_memcpy(&tmp, &_this->displays[index], sizeof(tmp));
|
||||
SDL_memcpy(&_this->displays[index], &_this->displays[i], sizeof(tmp));
|
||||
SDL_memcpy(&_this->displays[i], &tmp, sizeof(tmp));
|
||||
if (index >= _this->num_displays) {
|
||||
/* This should never happen due to the check above, but just in case... */
|
||||
return;
|
||||
}
|
||||
|
||||
if (moved) {
|
||||
SDL_VideoDisplay *tmp;
|
||||
|
||||
tmp = _this->displays[index];
|
||||
_this->displays[index] = _this->displays[i];
|
||||
_this->displays[i] = tmp;
|
||||
i = index;
|
||||
}
|
||||
|
||||
@ -371,7 +380,7 @@ static void WIN_AddDisplay(SDL_VideoDevice *_this, HMONITOR hMonitor, const MONI
|
||||
driverdata->state = DisplayUnchanged;
|
||||
|
||||
if (!_this->setting_display_mode) {
|
||||
SDL_VideoDisplay *existing_display = &_this->displays[i];
|
||||
SDL_VideoDisplay *existing_display = _this->displays[i];
|
||||
SDL_Rect bounds;
|
||||
|
||||
SDL_ResetFullscreenDisplayModes(existing_display);
|
||||
@ -645,7 +654,7 @@ void WIN_RefreshDisplays(SDL_VideoDevice *_this)
|
||||
// Mark all displays as potentially invalid to detect
|
||||
// entries that have actually been removed
|
||||
for (i = 0; i < _this->num_displays; ++i) {
|
||||
SDL_DisplayData *driverdata = _this->displays[i].driverdata;
|
||||
SDL_DisplayData *driverdata = _this->displays[i]->driverdata;
|
||||
driverdata->state = DisplayRemoved;
|
||||
}
|
||||
|
||||
@ -656,7 +665,7 @@ void WIN_RefreshDisplays(SDL_VideoDevice *_this)
|
||||
// Delete any entries still marked as invalid, iterate
|
||||
// in reverse as each delete takes effect immediately
|
||||
for (i = _this->num_displays - 1; i >= 0; --i) {
|
||||
SDL_VideoDisplay *display = &_this->displays[i];
|
||||
SDL_VideoDisplay *display = _this->displays[i];
|
||||
SDL_DisplayData *driverdata = display->driverdata;
|
||||
if (driverdata->state == DisplayRemoved) {
|
||||
SDL_DelVideoDisplay(display->id, SDL_TRUE);
|
||||
@ -665,7 +674,7 @@ void WIN_RefreshDisplays(SDL_VideoDevice *_this)
|
||||
|
||||
// Send events for any newly added displays
|
||||
for (i = 0; i < _this->num_displays; ++i) {
|
||||
SDL_VideoDisplay *display = &_this->displays[i];
|
||||
SDL_VideoDisplay *display = _this->displays[i];
|
||||
SDL_DisplayData *driverdata = display->driverdata;
|
||||
if (driverdata->state == DisplayAdded) {
|
||||
SDL_SendDisplayEvent(display, SDL_EVENT_DISPLAY_CONNECTED, 0);
|
||||
|
@ -207,6 +207,7 @@ static SDL_VideoDevice *WIN_CreateDevice(void)
|
||||
device->SetWindowHitTest = WIN_SetWindowHitTest;
|
||||
device->AcceptDragAndDrop = WIN_AcceptDragAndDrop;
|
||||
device->FlashWindow = WIN_FlashWindow;
|
||||
device->ShowWindowSystemMenu = WIN_ShowWindowSystemMenu;
|
||||
|
||||
device->shape_driver.CreateShaper = Win32_CreateShaper;
|
||||
device->shape_driver.SetWindowShape = Win32_SetWindowShape;
|
||||
|
@ -51,6 +51,14 @@ typedef HRESULT (WINAPI *DwmSetWindowAttribute_t)(HWND hwnd, DWORD dwAttribute,
|
||||
#define SWP_NOCOPYBITS 0
|
||||
#endif
|
||||
|
||||
/* An undocumented message to create a popup system menu
|
||||
* - wParam is always 0
|
||||
* - lParam = MAKELONG(x, y) where x and y are the screen coordinates where the menu should be displayed
|
||||
*/
|
||||
#ifndef WM_POPUPSYSTEMMENU
|
||||
#define WM_POPUPSYSTEMMENU 0x313
|
||||
#endif
|
||||
|
||||
/* #define HIGHDPI_DEBUG */
|
||||
|
||||
/* Fake window to help with DirectInput events. */
|
||||
@ -845,7 +853,6 @@ void WIN_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
{
|
||||
DWORD style;
|
||||
HWND hwnd;
|
||||
int nCmdShow;
|
||||
|
||||
SDL_bool bActivate = SDL_GetHintBoolean(SDL_HINT_WINDOW_ACTIVATE_WHEN_SHOWN, SDL_TRUE);
|
||||
|
||||
@ -855,13 +862,16 @@ void WIN_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
}
|
||||
|
||||
hwnd = window->driverdata->hwnd;
|
||||
nCmdShow = bActivate ? SW_SHOW : SW_SHOWNA;
|
||||
style = GetWindowLong(hwnd, GWL_EXSTYLE);
|
||||
if (style & WS_EX_NOACTIVATE) {
|
||||
nCmdShow = SW_SHOWNOACTIVATE;
|
||||
bActivate = SDL_FALSE;
|
||||
}
|
||||
ShowWindow(hwnd, nCmdShow);
|
||||
if (bActivate) {
|
||||
ShowWindow(hwnd, SW_SHOW);
|
||||
} else {
|
||||
/* Use SetWindowPos instead of ShowWindow to avoid activating the parent window if this is a child window */
|
||||
SetWindowPos(hwnd, NULL, 0, 0, 0, 0, window->driverdata->copybits_flag | SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER);
|
||||
}
|
||||
|
||||
if (window->flags & SDL_WINDOW_POPUP_MENU && bActivate) {
|
||||
if (window->parent == SDL_GetKeyboardFocus()) {
|
||||
@ -1483,6 +1493,17 @@ int WIN_FlashWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_FlashOperati
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WIN_ShowWindowSystemMenu(SDL_Window *window, int x, int y)
|
||||
{
|
||||
const SDL_WindowData *data = window->driverdata;
|
||||
POINT pt;
|
||||
|
||||
pt.x = x;
|
||||
pt.y = y;
|
||||
ClientToScreen(data->hwnd, &pt);
|
||||
SendMessage(data->hwnd, WM_POPUPSYSTEMMENU, 0, MAKELPARAM(pt.x, pt.y));
|
||||
}
|
||||
#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/
|
||||
|
||||
void WIN_UpdateDarkModeForHWND(HWND hwnd)
|
||||
|
@ -108,6 +108,7 @@ extern void WIN_AcceptDragAndDrop(SDL_Window *window, SDL_bool accept);
|
||||
extern int WIN_FlashWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_FlashOperation operation);
|
||||
extern void WIN_UpdateDarkModeForHWND(HWND hwnd);
|
||||
extern int WIN_SetWindowPositionInternal(SDL_Window *window, UINT flags);
|
||||
extern void WIN_ShowWindowSystemMenu(SDL_Window *window, int x, int y);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
|
@ -467,8 +467,8 @@ static int X11_MessageBoxCreateWindow(SDL_MessageBoxDataX11 *data)
|
||||
X11_XTranslateCoordinates(display, windowdata->xwindow, RootWindow(display, data->screen), x, y, &x, &y, &dummy);
|
||||
} else {
|
||||
const SDL_VideoDevice *dev = SDL_GetVideoDevice();
|
||||
if ((dev) && (dev->displays) && (dev->num_displays > 0)) {
|
||||
const SDL_VideoDisplay *dpy = &dev->displays[0];
|
||||
if (dev && dev->displays && dev->num_displays > 0) {
|
||||
const SDL_VideoDisplay *dpy = dev->displays[0];
|
||||
const SDL_DisplayData *dpydata = dpy->driverdata;
|
||||
x = dpydata->x + ((dpy->current_mode->w - data->dialog_width) / 2);
|
||||
y = dpydata->y + ((dpy->current_mode->h - data->dialog_height) / 3);
|
||||
|
@ -99,7 +99,7 @@ static void UpdateDisplayContentScale(float scale)
|
||||
|
||||
if (viddevice) {
|
||||
for (i = 0; i < viddevice->num_displays; ++i) {
|
||||
SDL_SetDisplayContentScale(&viddevice->displays[i], scale);
|
||||
SDL_SetDisplayContentScale(viddevice->displays[i], scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -821,8 +821,9 @@ int X11_InitModes(SDL_VideoDevice *_this)
|
||||
int xrandr_major, xrandr_minor;
|
||||
/* require at least XRandR v1.3 */
|
||||
if (CheckXRandR(data->display, &xrandr_major, &xrandr_minor) &&
|
||||
(xrandr_major >= 2 || (xrandr_major == 1 && xrandr_minor >= 3))) {
|
||||
return X11_InitModes_XRandR(_this);
|
||||
(xrandr_major >= 2 || (xrandr_major == 1 && xrandr_minor >= 3)) &&
|
||||
X11_InitModes_XRandR(_this) == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
|
||||
|
@ -84,7 +84,7 @@ static int X11_SafetyNetErrHandler(Display *d, XErrorEvent *e)
|
||||
if (device != NULL) {
|
||||
int i;
|
||||
for (i = 0; i < device->num_displays; i++) {
|
||||
SDL_VideoDisplay *display = &device->displays[i];
|
||||
SDL_VideoDisplay *display = device->displays[i];
|
||||
if (SDL_GetCurrentDisplayMode(display->id) != SDL_GetDesktopDisplayMode(display->id)) {
|
||||
X11_SetDisplayMode(device, display, &display->desktop_mode);
|
||||
}
|
||||
@ -213,6 +213,7 @@ static SDL_VideoDevice *X11_CreateDevice(void)
|
||||
device->SetWindowHitTest = X11_SetWindowHitTest;
|
||||
device->AcceptDragAndDrop = X11_AcceptDragAndDrop;
|
||||
device->FlashWindow = X11_FlashWindow;
|
||||
device->ShowWindowSystemMenu = X11_ShowWindowSystemMenu;
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_X11_XFIXES
|
||||
device->SetWindowMouseRect = X11_SetWindowMouseRect;
|
||||
|
27
external/sdl/SDL/src/video/x11/SDL_x11window.c
vendored
27
external/sdl/SDL/src/video/x11/SDL_x11window.c
vendored
@ -423,7 +423,6 @@ int X11_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
SDL_WindowData *windowdata;
|
||||
Display *display = data->display;
|
||||
int screen = displaydata->screen;
|
||||
const int transparent = (window->flags & SDL_WINDOW_TRANSPARENT) ? SDL_TRUE : SDL_FALSE;
|
||||
Visual *visual;
|
||||
int depth;
|
||||
XSetWindowAttributes xattr;
|
||||
@ -443,6 +442,7 @@ int X11_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window)
|
||||
SDL_bool undefined_position = SDL_FALSE;
|
||||
|
||||
#if defined(SDL_VIDEO_OPENGL_GLX) || defined(SDL_VIDEO_OPENGL_EGL)
|
||||
const int transparent = (window->flags & SDL_WINDOW_TRANSPARENT) ? SDL_TRUE : SDL_FALSE;
|
||||
const char *forced_visual_id = SDL_GetHint(SDL_HINT_VIDEO_X11_WINDOW_VISUALID);
|
||||
|
||||
if (forced_visual_id != NULL && forced_visual_id[0] != '\0') {
|
||||
@ -1957,4 +1957,29 @@ int SDL_X11_SetWindowTitle(Display *display, Window xwindow, char *title)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void X11_ShowWindowSystemMenu(SDL_Window *window, int x, int y)
|
||||
{
|
||||
SDL_WindowData *data = window->driverdata;
|
||||
SDL_DisplayData *displaydata = SDL_GetDisplayDriverDataForWindow(window);
|
||||
Display *display = data->videodata->display;
|
||||
Window root = RootWindow(display, displaydata->screen);
|
||||
XClientMessageEvent e;
|
||||
Window childReturn;
|
||||
int wx, wy;
|
||||
|
||||
SDL_zero(e);
|
||||
X11_XTranslateCoordinates(display, data->xwindow, root, x, y, &wx, &wy, &childReturn);
|
||||
|
||||
e.type = ClientMessage;
|
||||
e.window = data->xwindow;
|
||||
e.message_type = X11_XInternAtom(display, "_GTK_SHOW_WINDOW_MENU", 0);
|
||||
e.data.l[0] = 0; /* GTK device ID (unused) */
|
||||
e.data.l[1] = wx; /* X coordinate relative to root */
|
||||
e.data.l[2] = wy; /* Y coordinate relative to root */
|
||||
e.format = 32;
|
||||
|
||||
X11_XSendEvent(display, root, False, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent *)&e);
|
||||
X11_XFlush(display);
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_X11 */
|
||||
|
@ -115,6 +115,7 @@ extern int X11_GetWindowWMInfo(SDL_VideoDevice *_this, SDL_Window *window, struc
|
||||
extern int X11_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
|
||||
extern void X11_AcceptDragAndDrop(SDL_Window *window, SDL_bool accept);
|
||||
extern int X11_FlashWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_FlashOperation operation);
|
||||
extern void X11_ShowWindowSystemMenu(SDL_Window *window, int x, int y);
|
||||
|
||||
int SDL_X11_SetWindowTitle(Display *display, Window xwindow, char *title);
|
||||
void X11_UpdateWindowPosition(SDL_Window *window);
|
||||
|
Reference in New Issue
Block a user