mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-14 16:14:38 +00:00
Updates SDL to 2.0.5
This commit is contained in:
parent
00a4a21e3f
commit
1e671bfc7a
274 changed files with 11502 additions and 4656 deletions
|
|
@ -109,10 +109,20 @@ SDL_BlitCopy(SDL_BlitInfo * info)
|
|||
overlap = (src < (dst + h*dstskip));
|
||||
}
|
||||
if (overlap) {
|
||||
while (h--) {
|
||||
SDL_memmove(dst, src, w);
|
||||
src += srcskip;
|
||||
dst += dstskip;
|
||||
if ( dst < src ) {
|
||||
while ( h-- ) {
|
||||
SDL_memmove(dst, src, w);
|
||||
src += srcskip;
|
||||
dst += dstskip;
|
||||
}
|
||||
} else {
|
||||
src += ((h-1) * srcskip);
|
||||
dst += ((h-1) * dstskip);
|
||||
while ( h-- ) {
|
||||
SDL_memmove(dst, src, w);
|
||||
src -= srcskip;
|
||||
dst -= dstskip;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ SDL_Blit_Slow(SDL_BlitInfo * info)
|
|||
SDL_PixelFormat *dst_fmt = info->dst_fmt;
|
||||
int srcbpp = src_fmt->BytesPerPixel;
|
||||
int dstbpp = dst_fmt->BytesPerPixel;
|
||||
Uint32 rgbmask = ~src_fmt->Amask;
|
||||
Uint32 ckey = info->colorkey & rgbmask;
|
||||
|
||||
srcy = 0;
|
||||
posy = 0;
|
||||
|
|
@ -85,7 +87,7 @@ SDL_Blit_Slow(SDL_BlitInfo * info)
|
|||
srcpixel = (srcR << src_fmt->Rshift) |
|
||||
(srcG << src_fmt->Gshift) | (srcB << src_fmt->Bshift);
|
||||
}
|
||||
if (srcpixel == info->colorkey) {
|
||||
if ((srcpixel & rgbmask) == ckey) {
|
||||
posx += incx;
|
||||
dst += dstbpp;
|
||||
continue;
|
||||
|
|
@ -127,6 +129,7 @@ SDL_Blit_Slow(SDL_BlitInfo * info)
|
|||
dstR = srcR + ((255 - srcA) * dstR) / 255;
|
||||
dstG = srcG + ((255 - srcA) * dstG) / 255;
|
||||
dstB = srcB + ((255 - srcA) * dstB) / 255;
|
||||
dstA = srcA + ((255 - srcA) * dstA) / 255;
|
||||
break;
|
||||
case SDL_COPY_ADD:
|
||||
dstR = srcR + dstR;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
This code currently supports Win32 DIBs in uncompressed 8 and 24 bpp.
|
||||
*/
|
||||
|
||||
#include "SDL_hints.h"
|
||||
#include "SDL_video.h"
|
||||
#include "SDL_assert.h"
|
||||
#include "SDL_endian.h"
|
||||
|
|
@ -47,6 +48,11 @@
|
|||
#define BI_BITFIELDS 3
|
||||
#endif
|
||||
|
||||
/* Logical color space values for BMP files */
|
||||
#ifndef LCS_WINDOWS_COLOR_SPACE
|
||||
/* 0x57696E20 == "Win " */
|
||||
#define LCS_WINDOWS_COLOR_SPACE 0x57696E20
|
||||
#endif
|
||||
|
||||
static void CorrectAlphaChannel(SDL_Surface *surface)
|
||||
{
|
||||
|
|
@ -457,6 +463,8 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst)
|
|||
int i, pad;
|
||||
SDL_Surface *surface;
|
||||
Uint8 *bits;
|
||||
SDL_bool save32bit = SDL_FALSE;
|
||||
SDL_bool saveLegacyBMP = SDL_FALSE;
|
||||
|
||||
/* The Win32 BMP file header (14 bytes) */
|
||||
char magic[2] = { 'B', 'M' };
|
||||
|
|
@ -478,14 +486,24 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst)
|
|||
Uint32 biClrUsed;
|
||||
Uint32 biClrImportant;
|
||||
|
||||
/* The additional header members from the Win32 BITMAPV4HEADER struct (108 bytes in total) */
|
||||
Uint32 bV4RedMask = 0;
|
||||
Uint32 bV4GreenMask = 0;
|
||||
Uint32 bV4BlueMask = 0;
|
||||
Uint32 bV4AlphaMask = 0;
|
||||
Uint32 bV4CSType = 0;
|
||||
Sint32 bV4Endpoints[3 * 3] = {0};
|
||||
Uint32 bV4GammaRed = 0;
|
||||
Uint32 bV4GammaGreen = 0;
|
||||
Uint32 bV4GammaBlue = 0;
|
||||
|
||||
/* Make sure we have somewhere to save */
|
||||
surface = NULL;
|
||||
if (dst) {
|
||||
SDL_bool save32bit = SDL_FALSE;
|
||||
#ifdef SAVE_32BIT_BMP
|
||||
/* We can save alpha information in a 32-bit BMP */
|
||||
if (saveme->map->info.flags & SDL_COPY_COLORKEY ||
|
||||
saveme->format->Amask) {
|
||||
if (saveme->format->BitsPerPixel >= 8 && (saveme->format->Amask ||
|
||||
saveme->map->info.flags & SDL_COPY_COLORKEY)) {
|
||||
save32bit = SDL_TRUE;
|
||||
}
|
||||
#endif /* SAVE_32BIT_BMP */
|
||||
|
|
@ -497,7 +515,7 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst)
|
|||
SDL_SetError("%d bpp BMP files not supported",
|
||||
saveme->format->BitsPerPixel);
|
||||
}
|
||||
} else if ((saveme->format->BitsPerPixel == 24) &&
|
||||
} else if ((saveme->format->BitsPerPixel == 24) && !save32bit &&
|
||||
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
|
||||
(saveme->format->Rmask == 0x00FF0000) &&
|
||||
(saveme->format->Gmask == 0x0000FF00) &&
|
||||
|
|
@ -515,13 +533,7 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst)
|
|||
/* 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,
|
||||
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
|
||||
SDL_PIXELFORMAT_ARGB8888
|
||||
#else
|
||||
SDL_PIXELFORMAT_BGRA8888
|
||||
#endif
|
||||
);
|
||||
SDL_InitFormat(&format, SDL_PIXELFORMAT_BGRA32);
|
||||
} else {
|
||||
SDL_InitFormat(&format, SDL_PIXELFORMAT_BGR24);
|
||||
}
|
||||
|
|
@ -537,6 +549,10 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (save32bit) {
|
||||
saveLegacyBMP = SDL_GetHintBoolean(SDL_HINT_BMP_SAVE_LEGACY_FORMAT, SDL_FALSE);
|
||||
}
|
||||
|
||||
if (surface && (SDL_LockSurface(surface) == 0)) {
|
||||
const int bw = surface->w * surface->format->BytesPerPixel;
|
||||
|
||||
|
|
@ -572,6 +588,21 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst)
|
|||
}
|
||||
biClrImportant = 0;
|
||||
|
||||
/* Set the BMP info values for the version 4 header */
|
||||
if (save32bit && !saveLegacyBMP) {
|
||||
biSize = 108;
|
||||
biCompression = BI_BITFIELDS;
|
||||
/* The BMP format is always little endian, these masks stay the same */
|
||||
bV4RedMask = 0x00ff0000;
|
||||
bV4GreenMask = 0x0000ff00;
|
||||
bV4BlueMask = 0x000000ff;
|
||||
bV4AlphaMask = 0xff000000;
|
||||
bV4CSType = LCS_WINDOWS_COLOR_SPACE;
|
||||
bV4GammaRed = 0;
|
||||
bV4GammaGreen = 0;
|
||||
bV4GammaBlue = 0;
|
||||
}
|
||||
|
||||
/* Write the BMP info values */
|
||||
SDL_WriteLE32(dst, biSize);
|
||||
SDL_WriteLE32(dst, biWidth);
|
||||
|
|
@ -585,6 +616,21 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst)
|
|||
SDL_WriteLE32(dst, biClrUsed);
|
||||
SDL_WriteLE32(dst, biClrImportant);
|
||||
|
||||
/* 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]);
|
||||
}
|
||||
SDL_WriteLE32(dst, bV4GammaRed);
|
||||
SDL_WriteLE32(dst, bV4GammaGreen);
|
||||
SDL_WriteLE32(dst, bV4GammaBlue);
|
||||
}
|
||||
|
||||
/* Write the palette (in BGR color order) */
|
||||
if (surface->format->palette) {
|
||||
SDL_Color *colors;
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ int
|
|||
SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_display)
|
||||
{
|
||||
void *dll_handle = NULL, *egl_dll_handle = NULL; /* The naming is counter intuitive, but hey, I just work here -- Gabriel */
|
||||
char *path = NULL;
|
||||
const char *path = NULL;
|
||||
#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT
|
||||
const char *d3dcompiler;
|
||||
#endif
|
||||
|
|
@ -558,7 +558,8 @@ int
|
|||
SDL_EGL_GetSwapInterval(_THIS)
|
||||
{
|
||||
if (!_this->egl_data) {
|
||||
return SDL_SetError("EGL not initialized");
|
||||
SDL_SetError("EGL not initialized");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _this->egl_data->egl_swapinterval;
|
||||
|
|
|
|||
|
|
@ -27,27 +27,20 @@
|
|||
#include "SDL_pixels_c.h"
|
||||
|
||||
/* Public routines */
|
||||
|
||||
/*
|
||||
* Create an empty RGB surface of the appropriate depth
|
||||
* Create an empty RGB surface of the appropriate depth using the given
|
||||
* enum SDL_PIXELFORMAT_* format
|
||||
*/
|
||||
SDL_Surface *
|
||||
SDL_CreateRGBSurface(Uint32 flags,
|
||||
int width, int height, int depth,
|
||||
Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
|
||||
SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth,
|
||||
Uint32 format)
|
||||
{
|
||||
SDL_Surface *surface;
|
||||
Uint32 format;
|
||||
|
||||
/* The flags are no longer used, make the compiler happy */
|
||||
(void)flags;
|
||||
|
||||
/* Get the pixel format */
|
||||
format = SDL_MasksToPixelFormatEnum(depth, Rmask, Gmask, Bmask, Amask);
|
||||
if (format == SDL_PIXELFORMAT_UNKNOWN) {
|
||||
SDL_SetError("Unknown pixel format");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate the surface */
|
||||
surface = (SDL_Surface *) SDL_calloc(1, sizeof(*surface));
|
||||
if (surface == NULL) {
|
||||
|
|
@ -105,7 +98,7 @@ SDL_CreateRGBSurface(Uint32 flags,
|
|||
}
|
||||
|
||||
/* By default surface with an alpha mask are set up for blending */
|
||||
if (Amask) {
|
||||
if (surface->format->Amask) {
|
||||
SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND);
|
||||
}
|
||||
|
||||
|
|
@ -114,6 +107,26 @@ SDL_CreateRGBSurface(Uint32 flags,
|
|||
return surface;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create an empty RGB surface of the appropriate depth
|
||||
*/
|
||||
SDL_Surface *
|
||||
SDL_CreateRGBSurface(Uint32 flags,
|
||||
int width, int height, int depth,
|
||||
Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
|
||||
{
|
||||
Uint32 format;
|
||||
|
||||
/* Get the pixel format */
|
||||
format = SDL_MasksToPixelFormatEnum(depth, Rmask, Gmask, Bmask, Amask);
|
||||
if (format == SDL_PIXELFORMAT_UNKNOWN) {
|
||||
SDL_SetError("Unknown pixel format");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return SDL_CreateRGBSurfaceWithFormat(flags, width, height, depth, format);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create an RGB surface from an existing memory buffer
|
||||
*/
|
||||
|
|
@ -125,8 +138,30 @@ SDL_CreateRGBSurfaceFrom(void *pixels,
|
|||
{
|
||||
SDL_Surface *surface;
|
||||
|
||||
surface =
|
||||
SDL_CreateRGBSurface(0, 0, 0, depth, Rmask, Gmask, Bmask, Amask);
|
||||
surface = SDL_CreateRGBSurface(0, 0, 0, depth, Rmask, Gmask, Bmask, Amask);
|
||||
if (surface != NULL) {
|
||||
surface->flags |= SDL_PREALLOC;
|
||||
surface->pixels = pixels;
|
||||
surface->w = width;
|
||||
surface->h = height;
|
||||
surface->pitch = pitch;
|
||||
SDL_SetClipRect(surface, NULL);
|
||||
}
|
||||
return surface;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create an RGB surface from an existing memory buffer using the given given
|
||||
* enum SDL_PIXELFORMAT_* format
|
||||
*/
|
||||
SDL_Surface *
|
||||
SDL_CreateRGBSurfaceWithFormatFrom(void *pixels,
|
||||
int width, int height, int depth, int pitch,
|
||||
Uint32 format)
|
||||
{
|
||||
SDL_Surface *surface;
|
||||
|
||||
surface = SDL_CreateRGBSurfaceWithFormat(0, 0, 0, depth, format);
|
||||
if (surface != NULL) {
|
||||
surface->flags |= SDL_PREALLOC;
|
||||
surface->pixels = pixels;
|
||||
|
|
|
|||
|
|
@ -86,6 +86,8 @@ struct SDL_Window
|
|||
|
||||
SDL_DisplayMode fullscreen_mode;
|
||||
|
||||
float opacity;
|
||||
|
||||
float brightness;
|
||||
Uint16 *gamma;
|
||||
Uint16 *saved_gamma; /* (just offset into gamma) */
|
||||
|
|
@ -95,6 +97,7 @@ struct SDL_Window
|
|||
|
||||
SDL_bool is_hiding;
|
||||
SDL_bool is_destroying;
|
||||
SDL_bool is_dropping; /* drag/drop in progress, expecting SDL_SendDropComplete(). */
|
||||
|
||||
SDL_WindowShaper *shaper;
|
||||
|
||||
|
|
@ -175,6 +178,11 @@ struct SDL_VideoDevice
|
|||
*/
|
||||
int (*GetDisplayDPI) (_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi);
|
||||
|
||||
/*
|
||||
* Get the usable bounds of a display (bounds minus menubar or whatever)
|
||||
*/
|
||||
int (*GetDisplayUsableBounds) (_THIS, SDL_VideoDisplay * display, SDL_Rect * rect);
|
||||
|
||||
/*
|
||||
* Get a list of the available display modes for a display.
|
||||
*/
|
||||
|
|
@ -200,6 +208,10 @@ struct SDL_VideoDevice
|
|||
void (*SetWindowSize) (_THIS, SDL_Window * window);
|
||||
void (*SetWindowMinimumSize) (_THIS, SDL_Window * window);
|
||||
void (*SetWindowMaximumSize) (_THIS, SDL_Window * window);
|
||||
int (*GetWindowBordersSize) (_THIS, SDL_Window * window, int *top, int *left, int *bottom, int *right);
|
||||
int (*SetWindowOpacity) (_THIS, SDL_Window * window, float opacity);
|
||||
int (*SetWindowModalFor) (_THIS, SDL_Window * modal_window, SDL_Window * parent_window);
|
||||
int (*SetWindowInputFocus) (_THIS, SDL_Window * window);
|
||||
void (*ShowWindow) (_THIS, SDL_Window * window);
|
||||
void (*HideWindow) (_THIS, SDL_Window * window);
|
||||
void (*RaiseWindow) (_THIS, SDL_Window * window);
|
||||
|
|
@ -207,6 +219,7 @@ struct SDL_VideoDevice
|
|||
void (*MinimizeWindow) (_THIS, SDL_Window * window);
|
||||
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 (*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);
|
||||
|
|
|
|||
|
|
@ -55,6 +55,10 @@
|
|||
#undef CreateWindow
|
||||
#endif
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
/* Available video drivers */
|
||||
static VideoBootStrap *bootstrap[] = {
|
||||
#if SDL_VIDEO_DRIVER_COCOA
|
||||
|
|
@ -177,7 +181,7 @@ ShouldUseTextureFramebuffer()
|
|||
/* See if the user or application wants a specific behavior */
|
||||
hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION);
|
||||
if (hint) {
|
||||
if (*hint == '0') {
|
||||
if (*hint == '0' || SDL_strcasecmp(hint, "false") == 0) {
|
||||
return SDL_FALSE;
|
||||
} else {
|
||||
return SDL_TRUE;
|
||||
|
|
@ -254,6 +258,8 @@ SDL_CreateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, Uint32 * f
|
|||
|
||||
/* Check to see if there's a specific driver requested */
|
||||
if (hint && *hint != '0' && *hint != '1' &&
|
||||
SDL_strcasecmp(hint, "true") != 0 &&
|
||||
SDL_strcasecmp(hint, "false") != 0 &&
|
||||
SDL_strcasecmp(hint, "software") != 0) {
|
||||
for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) {
|
||||
SDL_RendererInfo info;
|
||||
|
|
@ -443,10 +449,8 @@ int
|
|||
SDL_VideoInit(const char *driver_name)
|
||||
{
|
||||
SDL_VideoDevice *video;
|
||||
const char *hint;
|
||||
int index;
|
||||
int i;
|
||||
SDL_bool allow_screensaver;
|
||||
|
||||
/* Check to make sure we don't overwrite '_this' */
|
||||
if (_this != NULL) {
|
||||
|
|
@ -534,13 +538,7 @@ SDL_VideoInit(const char *driver_name)
|
|||
joystick, or passively watching a movie. Things that use SDL but
|
||||
function more like a normal desktop app should explicitly reenable the
|
||||
screensaver. */
|
||||
hint = SDL_GetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER);
|
||||
if (hint) {
|
||||
allow_screensaver = SDL_atoi(hint) ? SDL_TRUE : SDL_FALSE;
|
||||
} else {
|
||||
allow_screensaver = SDL_FALSE;
|
||||
}
|
||||
if (!allow_screensaver) {
|
||||
if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_ALLOW_SCREENSAVER, SDL_FALSE)) {
|
||||
SDL_DisableScreenSaver();
|
||||
}
|
||||
|
||||
|
|
@ -684,7 +682,26 @@ SDL_GetDisplayBounds(int displayIndex, SDL_Rect * rect)
|
|||
rect->w = display->current_mode.w;
|
||||
rect->h = display->current_mode.h;
|
||||
}
|
||||
return 0;
|
||||
return 0; /* !!! FIXME: should this be an error if (rect==NULL) ? */
|
||||
}
|
||||
|
||||
int SDL_GetDisplayUsableBounds(int displayIndex, SDL_Rect * rect)
|
||||
{
|
||||
CHECK_DISPLAY_INDEX(displayIndex, -1);
|
||||
|
||||
if (rect) {
|
||||
SDL_VideoDisplay *display = &_this->displays[displayIndex];
|
||||
|
||||
if (_this->GetDisplayUsableBounds) {
|
||||
if (_this->GetDisplayUsableBounds(_this, display, rect) == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Oh well, just give the entire display bounds. */
|
||||
return SDL_GetDisplayBounds(displayIndex, rect);
|
||||
}
|
||||
return 0; /* !!! FIXME: should this be an error if (rect==NULL) ? */
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -700,7 +717,9 @@ SDL_GetDisplayDPI(int displayIndex, float * ddpi, float * hdpi, float * vdpi)
|
|||
if (_this->GetDisplayDPI(_this, display, ddpi, hdpi, vdpi) == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1285,16 +1304,11 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen)
|
|||
}
|
||||
|
||||
#define CREATE_FLAGS \
|
||||
(SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI)
|
||||
(SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_SKIP_TASKBAR | SDL_WINDOW_POPUP_MENU | SDL_WINDOW_UTILITY | SDL_WINDOW_TOOLTIP)
|
||||
|
||||
static void
|
||||
SDL_FinishWindowCreation(SDL_Window *window, Uint32 flags)
|
||||
{
|
||||
window->windowed.x = window->x;
|
||||
window->windowed.y = window->y;
|
||||
window->windowed.w = window->w;
|
||||
window->windowed.h = window->h;
|
||||
|
||||
if (flags & SDL_WINDOW_MAXIMIZED) {
|
||||
SDL_MaximizeWindow(window);
|
||||
}
|
||||
|
|
@ -1316,7 +1330,6 @@ SDL_Window *
|
|||
SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
|
||||
{
|
||||
SDL_Window *window;
|
||||
const char *hint;
|
||||
|
||||
if (!_this) {
|
||||
/* Initialize the video system if needed */
|
||||
|
|
@ -1325,6 +1338,11 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
|
|||
}
|
||||
}
|
||||
|
||||
if ( (((flags & SDL_WINDOW_UTILITY) != 0) + ((flags & SDL_WINDOW_TOOLTIP) != 0) + ((flags & SDL_WINDOW_POPUP_MENU) != 0)) > 1 ) {
|
||||
SDL_SetError("Conflicting window flags specified");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Some platforms can't create zero-sized windows */
|
||||
if (w < 1) {
|
||||
w = 1;
|
||||
|
|
@ -1341,7 +1359,9 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
|
|||
|
||||
/* Some platforms have OpenGL enabled by default */
|
||||
#if (SDL_VIDEO_OPENGL && __MACOSX__) || __IPHONEOS__ || __ANDROID__ || __NACL__
|
||||
flags |= SDL_WINDOW_OPENGL;
|
||||
if (SDL_strcmp(_this->name, "dummy") != 0) {
|
||||
flags |= SDL_WINDOW_OPENGL;
|
||||
}
|
||||
#endif
|
||||
if (flags & SDL_WINDOW_OPENGL) {
|
||||
if (!_this->GL_CreateContext) {
|
||||
|
|
@ -1357,8 +1377,7 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
|
|||
* SDL_WINDOW_ALLOW_HIGHDPI flag.
|
||||
*/
|
||||
if (flags & SDL_WINDOW_ALLOW_HIGHDPI) {
|
||||
hint = SDL_GetHint(SDL_HINT_VIDEO_HIGHDPI_DISABLED);
|
||||
if (hint && SDL_atoi(hint) > 0) {
|
||||
if (SDL_GetHintBoolean(SDL_HINT_VIDEO_HIGHDPI_DISABLED, SDL_FALSE)) {
|
||||
flags &= ~SDL_WINDOW_ALLOW_HIGHDPI;
|
||||
}
|
||||
}
|
||||
|
|
@ -1389,8 +1408,28 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
|
|||
window->y = bounds.y + (bounds.h - h) / 2;
|
||||
}
|
||||
}
|
||||
window->windowed.x = window->x;
|
||||
window->windowed.y = window->y;
|
||||
window->windowed.w = window->w;
|
||||
window->windowed.h = window->h;
|
||||
|
||||
if (flags & SDL_WINDOW_FULLSCREEN) {
|
||||
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
|
||||
int displayIndex;
|
||||
SDL_Rect bounds;
|
||||
|
||||
displayIndex = SDL_GetIndexOfDisplay(display);
|
||||
SDL_GetDisplayBounds(displayIndex, &bounds);
|
||||
|
||||
window->x = bounds.x;
|
||||
window->y = bounds.y;
|
||||
window->w = bounds.w;
|
||||
window->h = bounds.h;
|
||||
}
|
||||
|
||||
window->flags = ((flags & CREATE_FLAGS) | SDL_WINDOW_HIDDEN);
|
||||
window->last_fullscreen_flags = window->flags;
|
||||
window->opacity = 1.0f;
|
||||
window->brightness = 1.0f;
|
||||
window->next = _this->windows;
|
||||
window->is_destroying = SDL_FALSE;
|
||||
|
|
@ -1451,6 +1490,7 @@ SDL_CreateWindowFrom(const void *data)
|
|||
window->flags = SDL_WINDOW_FOREIGN;
|
||||
window->last_fullscreen_flags = window->flags;
|
||||
window->is_destroying = SDL_FALSE;
|
||||
window->opacity = 1.0f;
|
||||
window->brightness = 1.0f;
|
||||
window->next = _this->windows;
|
||||
if (_this->windows) {
|
||||
|
|
@ -1795,6 +1835,24 @@ SDL_SetWindowBordered(SDL_Window * window, SDL_bool bordered)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
SDL_SetWindowResizable(SDL_Window * window, SDL_bool resizable)
|
||||
{
|
||||
CHECK_WINDOW_MAGIC(window,);
|
||||
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
|
||||
const int want = (resizable != SDL_FALSE); /* normalize the flag. */
|
||||
const int have = ((window->flags & SDL_WINDOW_RESIZABLE) != 0);
|
||||
if ((want != have) && (_this->SetWindowResizable)) {
|
||||
if (want) {
|
||||
window->flags |= SDL_WINDOW_RESIZABLE;
|
||||
} else {
|
||||
window->flags &= ~SDL_WINDOW_RESIZABLE;
|
||||
}
|
||||
_this->SetWindowResizable(_this, window, (SDL_bool) want);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SDL_SetWindowSize(SDL_Window * window, int w, int h)
|
||||
{
|
||||
|
|
@ -1883,6 +1941,28 @@ SDL_SetWindowMinimumSize(SDL_Window * window, int min_w, int min_h)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
SDL_GetWindowBordersSize(SDL_Window * window, int *top, int *left, int *bottom, int *right)
|
||||
{
|
||||
int dummy = 0;
|
||||
|
||||
if (!top) { top = &dummy; }
|
||||
if (!left) { left = &dummy; }
|
||||
if (!right) { right = &dummy; }
|
||||
if (!bottom) { bottom = &dummy; }
|
||||
|
||||
/* Always initialize, so applications don't have to care */
|
||||
*top = *left = *bottom = *right = 0;
|
||||
|
||||
CHECK_WINDOW_MAGIC(window, -1);
|
||||
|
||||
if (!_this->GetWindowBordersSize) {
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
return _this->GetWindowBordersSize(_this, window, top, left, bottom, right);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_GetWindowMinimumSize(SDL_Window * window, int *min_w, int *min_h)
|
||||
{
|
||||
|
|
@ -2144,6 +2224,68 @@ SDL_GetWindowBrightness(SDL_Window * window)
|
|||
return window->brightness;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SetWindowOpacity(SDL_Window * window, float opacity)
|
||||
{
|
||||
int retval;
|
||||
CHECK_WINDOW_MAGIC(window, -1);
|
||||
|
||||
if (!_this->SetWindowOpacity) {
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
if (opacity < 0.0f) {
|
||||
opacity = 0.0f;
|
||||
} else if (opacity > 1.0f) {
|
||||
opacity = 1.0f;
|
||||
}
|
||||
|
||||
retval = _this->SetWindowOpacity(_this, window, opacity);
|
||||
if (retval == 0) {
|
||||
window->opacity = opacity;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_GetWindowOpacity(SDL_Window * window, float * out_opacity)
|
||||
{
|
||||
CHECK_WINDOW_MAGIC(window, -1);
|
||||
|
||||
if (out_opacity) {
|
||||
*out_opacity = window->opacity;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SetWindowModalFor(SDL_Window * modal_window, SDL_Window * parent_window)
|
||||
{
|
||||
CHECK_WINDOW_MAGIC(modal_window, -1);
|
||||
CHECK_WINDOW_MAGIC(parent_window, -1);
|
||||
|
||||
if (!_this->SetWindowModalFor) {
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
return _this->SetWindowModalFor(_this, modal_window, parent_window);
|
||||
}
|
||||
|
||||
int
|
||||
SDL_SetWindowInputFocus(SDL_Window * window)
|
||||
{
|
||||
CHECK_WINDOW_MAGIC(window, -1);
|
||||
|
||||
if (!_this->SetWindowInputFocus) {
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
return _this->SetWindowInputFocus(_this, window);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
SDL_SetWindowGammaRamp(SDL_Window * window, const Uint16 * red,
|
||||
const Uint16 * green,
|
||||
|
|
@ -2359,8 +2501,6 @@ SDL_OnWindowFocusGained(SDL_Window * window)
|
|||
static SDL_bool
|
||||
ShouldMinimizeOnFocusLoss(SDL_Window * window)
|
||||
{
|
||||
const char *hint;
|
||||
|
||||
if (!(window->flags & SDL_WINDOW_FULLSCREEN) || window->is_destroying) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
|
@ -2371,16 +2511,7 @@ ShouldMinimizeOnFocusLoss(SDL_Window * window)
|
|||
}
|
||||
#endif
|
||||
|
||||
hint = SDL_GetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS);
|
||||
if (hint) {
|
||||
if (*hint == '0') {
|
||||
return SDL_FALSE;
|
||||
} else {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return SDL_TRUE;
|
||||
return SDL_GetHintBoolean(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, SDL_TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -3596,6 +3727,16 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
|
|||
int
|
||||
SDL_ShowSimpleMessageBox(Uint32 flags, const char *title, const char *message, SDL_Window *window)
|
||||
{
|
||||
#ifdef __EMSCRIPTEN__
|
||||
/* !!! FIXME: propose a browser API for this, get this #ifdef out of here? */
|
||||
/* Web browsers don't (currently) have an API for a custom message box
|
||||
that can block, but for the most common case (SDL_ShowSimpleMessageBox),
|
||||
we can use the standard Javascript alert() function. */
|
||||
EM_ASM_({
|
||||
alert(UTF8ToString($0) + "\n\n" + UTF8ToString($1));
|
||||
}, title, message);
|
||||
return 0;
|
||||
#else
|
||||
SDL_MessageBoxData data;
|
||||
SDL_MessageBoxButtonData button;
|
||||
|
||||
|
|
@ -3613,20 +3754,13 @@ SDL_ShowSimpleMessageBox(Uint32 flags, const char *title, const char *message, S
|
|||
button.text = "OK";
|
||||
|
||||
return SDL_ShowMessageBox(&data, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
SDL_ShouldAllowTopmost(void)
|
||||
{
|
||||
const char *hint = SDL_GetHint(SDL_HINT_ALLOW_TOPMOST);
|
||||
if (hint) {
|
||||
if (*hint == '0') {
|
||||
return SDL_FALSE;
|
||||
} else {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
return SDL_TRUE;
|
||||
return SDL_GetHintBoolean(SDL_HINT_ALLOW_TOPMOST, SDL_TRUE);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
|||
|
|
@ -34,11 +34,11 @@ void android_egl_context_backup();
|
|||
void android_egl_context_restore();
|
||||
|
||||
#if SDL_AUDIO_DRIVER_ANDROID
|
||||
void AndroidAUD_ResumeDevices(void);
|
||||
void AndroidAUD_PauseDevices(void);
|
||||
void ANDROIDAUDIO_ResumeDevices(void);
|
||||
void ANDROIDAUDIO_PauseDevices(void);
|
||||
#else
|
||||
static void AndroidAUD_ResumeDevices(void) {}
|
||||
static void AndroidAUD_PauseDevices(void) {}
|
||||
static void ANDROIDAUDIO_ResumeDevices(void) {}
|
||||
static void ANDROIDAUDIO_PauseDevices(void) {}
|
||||
#endif
|
||||
|
||||
void
|
||||
|
|
@ -83,14 +83,14 @@ Android_PumpEvents(_THIS)
|
|||
if (isPaused && !isPausing) {
|
||||
/* Make sure this is the last thing we do before pausing */
|
||||
android_egl_context_backup();
|
||||
AndroidAUD_PauseDevices();
|
||||
ANDROIDAUDIO_PauseDevices();
|
||||
if(SDL_SemWait(Android_ResumeSem) == 0) {
|
||||
#else
|
||||
if (isPaused) {
|
||||
if(SDL_SemTryWait(Android_ResumeSem) == 0) {
|
||||
#endif
|
||||
isPaused = 0;
|
||||
AndroidAUD_ResumeDevices();
|
||||
ANDROIDAUDIO_ResumeDevices();
|
||||
/* Restore the GL Context from here, as this operation is thread dependent */
|
||||
if (!SDL_HasEvent(SDL_QUIT)) {
|
||||
android_egl_context_restore();
|
||||
|
|
@ -113,7 +113,7 @@ Android_PumpEvents(_THIS)
|
|||
#else
|
||||
if(SDL_SemTryWait(Android_PauseSem) == 0) {
|
||||
android_egl_context_backup();
|
||||
AndroidAUD_PauseDevices();
|
||||
ANDROIDAUDIO_PauseDevices();
|
||||
isPaused = 1;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -304,18 +304,22 @@ static SDL_Scancode Android_Keycodes[] = {
|
|||
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NAVIGATE_NEXT */
|
||||
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NAVIGATE_IN */
|
||||
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NAVIGATE_OUT */
|
||||
SDL_SCANCODE_UNKNOWN,
|
||||
SDL_SCANCODE_UNKNOWN,
|
||||
SDL_SCANCODE_UNKNOWN,
|
||||
SDL_SCANCODE_UNKNOWN,
|
||||
SDL_SCANCODE_UNKNOWN,
|
||||
SDL_SCANCODE_UNKNOWN,
|
||||
SDL_SCANCODE_UNKNOWN,
|
||||
SDL_SCANCODE_UNKNOWN,
|
||||
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STEM_PRIMARY */
|
||||
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STEM_1 */
|
||||
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STEM_2 */
|
||||
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STEM_3 */
|
||||
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_DPAD_UP_LEFT */
|
||||
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_DPAD_DOWN_LEFT */
|
||||
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_DPAD_UP_RIGHT */
|
||||
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_DPAD_DOWN_RIGHT */
|
||||
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_SKIP_FORWARD */
|
||||
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_SKIP_BACKWARD */
|
||||
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_STEP_FORWARD */
|
||||
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_STEP_BACKWARD */
|
||||
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SOFT_SLEEP */
|
||||
SDL_SCANCODE_CUT, /* AKEYCODE_CUT */
|
||||
SDL_SCANCODE_COPY, /* AKEYCODE_COPY */
|
||||
SDL_SCANCODE_PASTE, /* AKEYCODE_PASTE */
|
||||
};
|
||||
|
||||
static SDL_Scancode
|
||||
|
|
|
|||
|
|
@ -32,15 +32,24 @@
|
|||
|
||||
#define ACTION_DOWN 0
|
||||
#define ACTION_UP 1
|
||||
#define ACTION_MOVE 2
|
||||
#define ACTION_HOVER_MOVE 7
|
||||
#define ACTION_SCROLL 8
|
||||
#define BUTTON_PRIMARY 1
|
||||
#define BUTTON_SECONDARY 2
|
||||
#define BUTTON_TERTIARY 4
|
||||
#define BUTTON_BACK 8
|
||||
#define BUTTON_FORWARD 16
|
||||
|
||||
static Uint8 SDLButton;
|
||||
|
||||
void
|
||||
Android_InitMouse(void)
|
||||
{
|
||||
SDLButton = 0;
|
||||
}
|
||||
|
||||
void Android_OnMouse( int androidButton, int action, float x, float y) {
|
||||
static Uint8 SDLButton;
|
||||
|
||||
if (!Android_Window) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -53,6 +62,10 @@ void Android_OnMouse( int androidButton, int action, float x, float y) {
|
|||
SDLButton = SDL_BUTTON_RIGHT;
|
||||
} else if (androidButton == BUTTON_TERTIARY) {
|
||||
SDLButton = SDL_BUTTON_MIDDLE;
|
||||
} else if (androidButton == BUTTON_FORWARD) {
|
||||
SDLButton = SDL_BUTTON_X1;
|
||||
} else if (androidButton == BUTTON_BACK) {
|
||||
SDLButton = SDL_BUTTON_X2;
|
||||
}
|
||||
SDL_SendMouseMotion(Android_Window, 0, 0, x, y);
|
||||
SDL_SendMouseButton(Android_Window, 0, SDL_PRESSED, SDLButton);
|
||||
|
|
@ -65,6 +78,7 @@ void Android_OnMouse( int androidButton, int action, float x, float y) {
|
|||
SDL_SendMouseButton(Android_Window, 0, SDL_RELEASED, SDLButton);
|
||||
break;
|
||||
|
||||
case ACTION_MOVE:
|
||||
case ACTION_HOVER_MOVE:
|
||||
SDL_SendMouseMotion(Android_Window, 0, 0, x, y);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "SDL_androidvideo.h"
|
||||
|
||||
extern void Android_InitMouse(void);
|
||||
extern void Android_OnMouse( int button, int action, float x, float y);
|
||||
|
||||
#endif /* _SDL_androidmouse_h */
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ static void Android_GetWindowCoordinates(float x, float y,
|
|||
*window_y = (int)(y * window_h);
|
||||
}
|
||||
|
||||
static volatile SDL_bool separate_mouse_and_touch = SDL_FALSE;
|
||||
static SDL_bool separate_mouse_and_touch = SDL_FALSE;
|
||||
|
||||
static void
|
||||
SeparateEventsHintWatcher(void *userdata, const char *name,
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "SDL_androidclipboard.h"
|
||||
#include "SDL_androidevents.h"
|
||||
#include "SDL_androidkeyboard.h"
|
||||
#include "SDL_androidmouse.h"
|
||||
#include "SDL_androidtouch.h"
|
||||
#include "SDL_androidwindow.h"
|
||||
|
||||
|
|
@ -181,6 +182,8 @@ Android_VideoInit(_THIS)
|
|||
|
||||
Android_InitTouch();
|
||||
|
||||
Android_InitMouse();
|
||||
|
||||
/* We're done! */
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -191,7 +194,6 @@ Android_VideoQuit(_THIS)
|
|||
Android_QuitTouch();
|
||||
}
|
||||
|
||||
/* This function gets called before VideoInit() */
|
||||
void
|
||||
Android_SetScreenResolution(int width, int height, Uint32 format, float rate)
|
||||
{
|
||||
|
|
@ -200,8 +202,33 @@ Android_SetScreenResolution(int width, int height, Uint32 format, float rate)
|
|||
Android_ScreenFormat = format;
|
||||
Android_ScreenRate = rate;
|
||||
|
||||
/*
|
||||
Update the resolution of the desktop mode, so that the window
|
||||
can be properly resized. The screen resolution change can for
|
||||
example happen when the Activity enters or exists immersive mode,
|
||||
which can happen after VideoInit().
|
||||
*/
|
||||
SDL_VideoDevice* device = SDL_GetVideoDevice();
|
||||
if (device && device->num_displays > 0)
|
||||
{
|
||||
SDL_VideoDisplay* display = &device->displays[0];
|
||||
display->desktop_mode.format = Android_ScreenFormat;
|
||||
display->desktop_mode.w = Android_ScreenWidth;
|
||||
display->desktop_mode.h = Android_ScreenHeight;
|
||||
display->desktop_mode.refresh_rate = Android_ScreenRate;
|
||||
}
|
||||
|
||||
if (Android_Window) {
|
||||
SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_RESIZED, width, height);
|
||||
|
||||
/* Force the current mode to match the resize otherwise the SDL_WINDOWEVENT_RESTORED event
|
||||
* will fall back to the old mode */
|
||||
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(Android_Window);
|
||||
|
||||
display->current_mode.format = format;
|
||||
display->current_mode.w = width;
|
||||
display->current_mode.h = height;
|
||||
display->current_mode.refresh_rate = rate;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,23 +25,13 @@
|
|||
#include "SDL_cocoavideo.h"
|
||||
#include "../../events/SDL_clipboardevents_c.h"
|
||||
|
||||
static NSString *
|
||||
GetTextFormat(_THIS)
|
||||
{
|
||||
if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5) {
|
||||
return NSPasteboardTypeString;
|
||||
} else {
|
||||
return NSStringPboardType;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
Cocoa_SetClipboardText(_THIS, const char *text)
|
||||
{ @autoreleasepool
|
||||
{
|
||||
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
|
||||
NSPasteboard *pasteboard;
|
||||
NSString *format = GetTextFormat(_this);
|
||||
NSString *format = NSPasteboardTypeString;
|
||||
|
||||
pasteboard = [NSPasteboard generalPasteboard];
|
||||
data->clipboard_count = [pasteboard declareTypes:[NSArray arrayWithObject:format] owner:nil];
|
||||
|
|
@ -55,12 +45,12 @@ Cocoa_GetClipboardText(_THIS)
|
|||
{ @autoreleasepool
|
||||
{
|
||||
NSPasteboard *pasteboard;
|
||||
NSString *format = GetTextFormat(_this);
|
||||
NSString *format = NSPasteboardTypeString;
|
||||
NSString *available;
|
||||
char *text;
|
||||
|
||||
pasteboard = [NSPasteboard generalPasteboard];
|
||||
available = [pasteboard availableTypeFromArray: [NSArray arrayWithObject:format]];
|
||||
available = [pasteboard availableTypeFromArray:[NSArray arrayWithObject:format]];
|
||||
if ([available isEqualToString:format]) {
|
||||
NSString* string;
|
||||
const char *utf8;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
@interface SDLApplication : NSApplication
|
||||
|
||||
- (void)terminate:(id)sender;
|
||||
- (void)sendEvent:(NSEvent *)theEvent;
|
||||
|
||||
@end
|
||||
|
||||
|
|
@ -47,6 +48,48 @@
|
|||
SDL_SendQuit();
|
||||
}
|
||||
|
||||
static SDL_bool s_bShouldHandleEventsInSDLApplication = SDL_FALSE;
|
||||
|
||||
static void Cocoa_DispatchEvent(NSEvent *theEvent)
|
||||
{
|
||||
SDL_VideoDevice *_this = SDL_GetVideoDevice();
|
||||
|
||||
switch ([theEvent type]) {
|
||||
case NSLeftMouseDown:
|
||||
case NSOtherMouseDown:
|
||||
case NSRightMouseDown:
|
||||
case NSLeftMouseUp:
|
||||
case NSOtherMouseUp:
|
||||
case NSRightMouseUp:
|
||||
case NSLeftMouseDragged:
|
||||
case NSRightMouseDragged:
|
||||
case NSOtherMouseDragged: /* usually middle mouse dragged */
|
||||
case NSMouseMoved:
|
||||
case NSScrollWheel:
|
||||
Cocoa_HandleMouseEvent(_this, theEvent);
|
||||
break;
|
||||
case NSKeyDown:
|
||||
case NSKeyUp:
|
||||
case NSFlagsChanged:
|
||||
Cocoa_HandleKeyEvent(_this, theEvent);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Dispatch events here so that we can handle events caught by
|
||||
// nextEventMatchingMask in SDL, as well as events caught by other
|
||||
// processes (such as CEF) that are passed down to NSApp.
|
||||
- (void)sendEvent:(NSEvent *)theEvent
|
||||
{
|
||||
if (s_bShouldHandleEventsInSDLApplication) {
|
||||
Cocoa_DispatchEvent(theEvent);
|
||||
}
|
||||
|
||||
[super sendEvent:theEvent];
|
||||
}
|
||||
|
||||
@end // SDLApplication
|
||||
|
||||
/* setAppleMenu disappeared from the headers in 10.4 */
|
||||
|
|
@ -114,28 +157,23 @@
|
|||
*/
|
||||
for (NSWindow *window in [NSApp orderedWindows]) {
|
||||
if (window != win && [window canBecomeKeyWindow]) {
|
||||
if ([window respondsToSelector:@selector(isOnActiveSpace)]) {
|
||||
if (![window isOnActiveSpace]) {
|
||||
continue;
|
||||
}
|
||||
if (![window isOnActiveSpace]) {
|
||||
continue;
|
||||
}
|
||||
[window makeKeyAndOrderFront:self];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If a window wasn't found above, iterate through all visible windows
|
||||
* (including the 'About' window, if it's shown) and make the first one key.
|
||||
* Note that +[NSWindow windowNumbersWithOptions:] was added in 10.6.
|
||||
/* If a window wasn't found above, iterate through all visible windows in
|
||||
* the active Space in z-order (including the 'About' window, if it's shown)
|
||||
* and make the first one key.
|
||||
*/
|
||||
if ([NSWindow respondsToSelector:@selector(windowNumbersWithOptions:)]) {
|
||||
/* Get all visible windows in the active Space, in z-order. */
|
||||
for (NSNumber *num in [NSWindow windowNumbersWithOptions:0]) {
|
||||
NSWindow *window = [NSApp windowWithWindowNumber:[num integerValue]];
|
||||
if (window && window != win && [window canBecomeKeyWindow]) {
|
||||
[window makeKeyAndOrderFront:self];
|
||||
return;
|
||||
}
|
||||
for (NSNumber *num in [NSWindow windowNumbersWithOptions:0]) {
|
||||
NSWindow *window = [NSApp windowWithWindowNumber:[num integerValue]];
|
||||
if (window && window != win && [window canBecomeKeyWindow]) {
|
||||
[window makeKeyAndOrderFront:self];
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -176,7 +214,7 @@
|
|||
|
||||
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
|
||||
{
|
||||
return (BOOL)SDL_SendDropFile([filename UTF8String]);
|
||||
return (BOOL)SDL_SendDropFile(NULL, [filename UTF8String]) && SDL_SendDropComplete(NULL);
|
||||
}
|
||||
@end
|
||||
|
||||
|
|
@ -291,7 +329,7 @@ CreateApplicationMenus(void)
|
|||
|
||||
|
||||
/* Add the fullscreen view toggle menu option, if supported */
|
||||
if ([NSApp respondsToSelector:@selector(setPresentationOptions:)]) {
|
||||
if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) {
|
||||
/* Create the view menu */
|
||||
viewMenu = [[NSMenu alloc] initWithTitle:@"View"];
|
||||
|
||||
|
|
@ -319,18 +357,10 @@ Cocoa_RegisterApp(void)
|
|||
[SDLApplication sharedApplication];
|
||||
SDL_assert(NSApp != nil);
|
||||
|
||||
const char *hint = SDL_GetHint(SDL_HINT_MAC_BACKGROUND_APP);
|
||||
if (!hint || *hint == '0') {
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
|
||||
if ([NSApp respondsToSelector:@selector(setActivationPolicy:)]) {
|
||||
#endif
|
||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
|
||||
} else {
|
||||
ProcessSerialNumber psn = {0, kCurrentProcess};
|
||||
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
|
||||
}
|
||||
#endif
|
||||
s_bShouldHandleEventsInSDLApplication = SDL_TRUE;
|
||||
|
||||
if (!SDL_GetHintBoolean(SDL_HINT_MAC_BACKGROUND_APP, SDL_FALSE)) {
|
||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
}
|
||||
|
||||
|
|
@ -381,29 +411,11 @@ Cocoa_PumpEvents(_THIS)
|
|||
break;
|
||||
}
|
||||
|
||||
switch ([event type]) {
|
||||
case NSLeftMouseDown:
|
||||
case NSOtherMouseDown:
|
||||
case NSRightMouseDown:
|
||||
case NSLeftMouseUp:
|
||||
case NSOtherMouseUp:
|
||||
case NSRightMouseUp:
|
||||
case NSLeftMouseDragged:
|
||||
case NSRightMouseDragged:
|
||||
case NSOtherMouseDragged: /* usually middle mouse dragged */
|
||||
case NSMouseMoved:
|
||||
case NSScrollWheel:
|
||||
Cocoa_HandleMouseEvent(_this, event);
|
||||
break;
|
||||
case NSKeyDown:
|
||||
case NSKeyUp:
|
||||
case NSFlagsChanged:
|
||||
Cocoa_HandleKeyEvent(_this, event);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (!s_bShouldHandleEventsInSDLApplication) {
|
||||
Cocoa_DispatchEvent(event);
|
||||
}
|
||||
/* Pass through to NSApp to make sure everything stays in sync */
|
||||
|
||||
// Pass events down to SDLApplication to be handled in sendEvent:
|
||||
[NSApp sendEvent:event];
|
||||
}
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "../../events/scancodes_darwin.h"
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <IOKit/hid/IOHIDLib.h>
|
||||
|
||||
/*#define DEBUG_IME NSLog */
|
||||
#define DEBUG_IME(...)
|
||||
|
|
@ -69,14 +70,6 @@
|
|||
SDL_SendKeyboardText(str);
|
||||
}
|
||||
|
||||
- (void)insertText:(id)insertString
|
||||
{
|
||||
/* This method is part of NSTextInput and not NSTextInputClient, but
|
||||
* apparently it still might be called in OS X 10.5 and can cause beeps if
|
||||
* the implementation is missing: http://crbug.com/47890 */
|
||||
[self insertText:insertString replacementRange:NSMakeRange(0, 0)];
|
||||
}
|
||||
|
||||
- (void)doCommandBySelector:(SEL)myselector
|
||||
{
|
||||
/* No need to do anything since we are not using Cocoa
|
||||
|
|
@ -102,7 +95,7 @@
|
|||
|
||||
- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange;
|
||||
{
|
||||
if ([aString isKindOfClass: [NSAttributedString class]]) {
|
||||
if ([aString isKindOfClass:[NSAttributedString class]]) {
|
||||
aString = [aString string];
|
||||
}
|
||||
|
||||
|
|
@ -120,7 +113,7 @@
|
|||
_markedRange = NSMakeRange(0, [aString length]);
|
||||
|
||||
SDL_SendEditingText([aString UTF8String],
|
||||
selectedRange.location, selectedRange.length);
|
||||
(int) selectedRange.location, (int) selectedRange.length);
|
||||
|
||||
DEBUG_IME(@"setMarkedText: %@, (%d, %d)", _markedText,
|
||||
selRange.location, selRange.length);
|
||||
|
|
@ -150,10 +143,10 @@
|
|||
aRange.location, aRange.length, windowHeight,
|
||||
NSStringFromRect(rect));
|
||||
|
||||
if ([[self window] respondsToSelector:@selector(convertRectToScreen:)]) {
|
||||
rect = [[self window] convertRectToScreen:rect];
|
||||
if ([window respondsToSelector:@selector(convertRectToScreen:)]) {
|
||||
rect = [window convertRectToScreen:rect];
|
||||
} else {
|
||||
rect.origin = [[self window] convertBaseToScreen:rect.origin];
|
||||
rect.origin = [window convertBaseToScreen:rect.origin];
|
||||
}
|
||||
|
||||
return rect;
|
||||
|
|
@ -191,6 +184,116 @@
|
|||
|
||||
@end
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
Set up a HID callback to properly detect Caps Lock up/down events.
|
||||
Derived from:
|
||||
http://stackoverflow.com/questions/7190852/using-iohidmanager-to-get-modifier-key-events
|
||||
*/
|
||||
|
||||
static IOHIDManagerRef s_hidManager = NULL;
|
||||
|
||||
static void
|
||||
HIDCallback(void *context, IOReturn result, void *sender, IOHIDValueRef value)
|
||||
{
|
||||
if (context != s_hidManager) {
|
||||
/* An old callback, ignore it (related to bug 2157 below) */
|
||||
return;
|
||||
}
|
||||
|
||||
IOHIDElementRef elem = IOHIDValueGetElement(value);
|
||||
if (IOHIDElementGetUsagePage(elem) != kHIDPage_KeyboardOrKeypad
|
||||
|| IOHIDElementGetUsage(elem) != kHIDUsage_KeyboardCapsLock) {
|
||||
return;
|
||||
}
|
||||
CFIndex pressed = IOHIDValueGetIntegerValue(value);
|
||||
SDL_SendKeyboardKey(pressed ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
|
||||
}
|
||||
|
||||
static CFDictionaryRef
|
||||
CreateHIDDeviceMatchingDictionary(UInt32 usagePage, UInt32 usage)
|
||||
{
|
||||
CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault,
|
||||
0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
|
||||
if (dict) {
|
||||
CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usagePage);
|
||||
if (number) {
|
||||
CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsagePageKey), number);
|
||||
CFRelease(number);
|
||||
number = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage);
|
||||
if (number) {
|
||||
CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsageKey), number);
|
||||
CFRelease(number);
|
||||
return dict;
|
||||
}
|
||||
}
|
||||
CFRelease(dict);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
QuitHIDCallback()
|
||||
{
|
||||
if (!s_hidManager) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0 /* Releasing here causes a crash on Mac OS X 10.10 and earlier,
|
||||
* so just leak it for now. See bug 2157 for details.
|
||||
*/
|
||||
IOHIDManagerUnscheduleFromRunLoop(s_hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
||||
IOHIDManagerRegisterInputValueCallback(s_hidManager, NULL, NULL);
|
||||
IOHIDManagerClose(s_hidManager, 0);
|
||||
|
||||
CFRelease(s_hidManager);
|
||||
#endif
|
||||
s_hidManager = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
InitHIDCallback()
|
||||
{
|
||||
s_hidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
|
||||
if (!s_hidManager) {
|
||||
return;
|
||||
}
|
||||
CFDictionaryRef keyboard = NULL, keypad = NULL;
|
||||
CFArrayRef matches = NULL;
|
||||
keyboard = CreateHIDDeviceMatchingDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard);
|
||||
if (!keyboard) {
|
||||
goto fail;
|
||||
}
|
||||
keypad = CreateHIDDeviceMatchingDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Keypad);
|
||||
if (!keypad) {
|
||||
goto fail;
|
||||
}
|
||||
CFDictionaryRef matchesList[] = { keyboard, keypad };
|
||||
matches = CFArrayCreate(kCFAllocatorDefault, (const void **)matchesList, 2, NULL);
|
||||
if (!matches) {
|
||||
goto fail;
|
||||
}
|
||||
IOHIDManagerSetDeviceMatchingMultiple(s_hidManager, matches);
|
||||
IOHIDManagerRegisterInputValueCallback(s_hidManager, HIDCallback, s_hidManager);
|
||||
IOHIDManagerScheduleWithRunLoop(s_hidManager, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
|
||||
if (IOHIDManagerOpen(s_hidManager, kIOHIDOptionsTypeNone) == kIOReturnSuccess) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
fail:
|
||||
QuitHIDCallback();
|
||||
|
||||
cleanup:
|
||||
if (matches) {
|
||||
CFRelease(matches);
|
||||
}
|
||||
if (keypad) {
|
||||
CFRelease(keypad);
|
||||
}
|
||||
if (keyboard) {
|
||||
CFRelease(keyboard);
|
||||
}
|
||||
}
|
||||
|
||||
/* This is a helper function for HandleModifierSide. This
|
||||
* function reverts back to behavior before the distinction between
|
||||
* sides was made.
|
||||
|
|
@ -328,24 +431,6 @@ ReleaseModifierSide(unsigned int device_independent_mask,
|
|||
}
|
||||
}
|
||||
|
||||
/* This is a helper function for DoSidedModifiers.
|
||||
* This function handles the CapsLock case.
|
||||
*/
|
||||
static void
|
||||
HandleCapsLock(unsigned short scancode,
|
||||
unsigned int oldMods, unsigned int newMods)
|
||||
{
|
||||
unsigned int oldMask, newMask;
|
||||
|
||||
oldMask = oldMods & NSAlphaShiftKeyMask;
|
||||
newMask = newMods & NSAlphaShiftKeyMask;
|
||||
|
||||
if (oldMask != newMask) {
|
||||
SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
|
||||
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
|
||||
}
|
||||
}
|
||||
|
||||
/* This function will handle the modifier keys and also determine the
|
||||
* correct side of the key.
|
||||
*/
|
||||
|
|
@ -374,9 +459,6 @@ DoSidedModifiers(unsigned short scancode,
|
|||
|
||||
unsigned int i, bit;
|
||||
|
||||
/* Handle CAPSLOCK separately because it doesn't have a left/right side */
|
||||
HandleCapsLock(scancode, oldMods, newMods);
|
||||
|
||||
/* Iterate through the bits, testing each against the old modifiers */
|
||||
for (i = 0, bit = NSShiftKeyMask; bit <= NSCommandKeyMask; bit <<= 1, ++i) {
|
||||
unsigned int oldMask, newMask;
|
||||
|
|
@ -498,11 +580,10 @@ Cocoa_InitKeyboard(_THIS)
|
|||
SDL_SetScancodeName(SDL_SCANCODE_RALT, "Right Option");
|
||||
SDL_SetScancodeName(SDL_SCANCODE_RGUI, "Right Command");
|
||||
|
||||
/* On pre-10.6, you might have the initial capslock key state wrong. */
|
||||
if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_6) {
|
||||
data->modifierFlags = [NSEvent modifierFlags];
|
||||
SDL_ToggleModState(KMOD_CAPS, (data->modifierFlags & NSAlphaShiftKeyMask) != 0);
|
||||
}
|
||||
data->modifierFlags = [NSEvent modifierFlags];
|
||||
SDL_ToggleModState(KMOD_CAPS, (data->modifierFlags & NSAlphaShiftKeyMask) != 0);
|
||||
|
||||
InitHIDCallback();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -628,6 +709,7 @@ Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
|
|||
void
|
||||
Cocoa_QuitKeyboard(_THIS)
|
||||
{
|
||||
QuitHIDCallback();
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_COCOA */
|
||||
|
|
|
|||
|
|
@ -30,12 +30,14 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
const void *moderef;
|
||||
CGDisplayModeRef moderef;
|
||||
} SDL_DisplayModeData;
|
||||
|
||||
extern void Cocoa_InitModes(_THIS);
|
||||
extern int Cocoa_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect);
|
||||
extern int Cocoa_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect);
|
||||
extern void Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
|
||||
extern int Cocoa_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hpdi, float * vdpi);
|
||||
extern int Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
|
||||
extern void Cocoa_QuitModes(_THIS);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
#include "SDL_assert.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_COCOA
|
||||
|
||||
|
|
@ -55,25 +56,6 @@ Cocoa_ToggleMenuBar(const BOOL show)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* !!! FIXME: clean out the pre-10.6 code when it makes sense to do so. */
|
||||
#define FORCE_OLD_API 0
|
||||
|
||||
#if FORCE_OLD_API
|
||||
#undef MAC_OS_X_VERSION_MIN_REQUIRED
|
||||
#define MAC_OS_X_VERSION_MIN_REQUIRED 1050
|
||||
#endif
|
||||
|
||||
static BOOL
|
||||
IS_SNOW_LEOPARD_OR_LATER()
|
||||
{
|
||||
#if FORCE_OLD_API
|
||||
return NO;
|
||||
#else
|
||||
return floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
CG_SetError(const char *prefix, CGDisplayErr result)
|
||||
{
|
||||
|
|
@ -118,65 +100,46 @@ CG_SetError(const char *prefix, CGDisplayErr result)
|
|||
}
|
||||
|
||||
static SDL_bool
|
||||
GetDisplayMode(_THIS, const void *moderef, CVDisplayLinkRef link, SDL_DisplayMode *mode)
|
||||
GetDisplayMode(_THIS, CGDisplayModeRef vidmode, CVDisplayLinkRef link, SDL_DisplayMode *mode)
|
||||
{
|
||||
SDL_DisplayModeData *data;
|
||||
long width = 0;
|
||||
long height = 0;
|
||||
long bpp = 0;
|
||||
long refreshRate = 0;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
int bpp = 0;
|
||||
int refreshRate = 0;
|
||||
CFStringRef fmt;
|
||||
|
||||
data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data));
|
||||
if (!data) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
data->moderef = moderef;
|
||||
data->moderef = vidmode;
|
||||
|
||||
if (IS_SNOW_LEOPARD_OR_LATER()) {
|
||||
CGDisplayModeRef vidmode = (CGDisplayModeRef) moderef;
|
||||
CFStringRef fmt = CGDisplayModeCopyPixelEncoding(vidmode);
|
||||
width = (long) CGDisplayModeGetWidth(vidmode);
|
||||
height = (long) CGDisplayModeGetHeight(vidmode);
|
||||
refreshRate = (long) (CGDisplayModeGetRefreshRate(vidmode) + 0.5);
|
||||
fmt = CGDisplayModeCopyPixelEncoding(vidmode);
|
||||
width = (int) CGDisplayModeGetWidth(vidmode);
|
||||
height = (int) CGDisplayModeGetHeight(vidmode);
|
||||
refreshRate = (int) (CGDisplayModeGetRefreshRate(vidmode) + 0.5);
|
||||
|
||||
if (CFStringCompare(fmt, CFSTR(IO32BitDirectPixels),
|
||||
kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
|
||||
bpp = 32;
|
||||
} else if (CFStringCompare(fmt, CFSTR(IO16BitDirectPixels),
|
||||
kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
|
||||
bpp = 16;
|
||||
} else if (CFStringCompare(fmt, CFSTR(kIO30BitDirectPixels),
|
||||
kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
|
||||
bpp = 30;
|
||||
} else {
|
||||
bpp = 0; /* ignore 8-bit and such for now. */
|
||||
}
|
||||
|
||||
CFRelease(fmt);
|
||||
if (CFStringCompare(fmt, CFSTR(IO32BitDirectPixels),
|
||||
kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
|
||||
bpp = 32;
|
||||
} else if (CFStringCompare(fmt, CFSTR(IO16BitDirectPixels),
|
||||
kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
|
||||
bpp = 16;
|
||||
} else if (CFStringCompare(fmt, CFSTR(kIO30BitDirectPixels),
|
||||
kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
|
||||
bpp = 30;
|
||||
} else {
|
||||
bpp = 0; /* ignore 8-bit and such for now. */
|
||||
}
|
||||
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
|
||||
if (!IS_SNOW_LEOPARD_OR_LATER()) {
|
||||
CFNumberRef number;
|
||||
double refresh;
|
||||
CFDictionaryRef vidmode = (CFDictionaryRef) moderef;
|
||||
number = CFDictionaryGetValue(vidmode, kCGDisplayWidth);
|
||||
CFNumberGetValue(number, kCFNumberLongType, &width);
|
||||
number = CFDictionaryGetValue(vidmode, kCGDisplayHeight);
|
||||
CFNumberGetValue(number, kCFNumberLongType, &height);
|
||||
number = CFDictionaryGetValue(vidmode, kCGDisplayBitsPerPixel);
|
||||
CFNumberGetValue(number, kCFNumberLongType, &bpp);
|
||||
number = CFDictionaryGetValue(vidmode, kCGDisplayRefreshRate);
|
||||
CFNumberGetValue(number, kCFNumberDoubleType, &refresh);
|
||||
refreshRate = (long) (refresh + 0.5);
|
||||
}
|
||||
#endif
|
||||
CFRelease(fmt);
|
||||
|
||||
/* CGDisplayModeGetRefreshRate returns 0 for many non-CRT displays. */
|
||||
if (refreshRate == 0 && link != NULL) {
|
||||
CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(link);
|
||||
if ((time.flags & kCVTimeIsIndefinite) == 0 && time.timeValue != 0) {
|
||||
refreshRate = (long) ((time.timeScale / (double) time.timeValue) + 0.5);
|
||||
refreshRate = (int) ((time.timeScale / (double) time.timeValue) + 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -203,22 +166,6 @@ GetDisplayMode(_THIS, const void *moderef, CVDisplayLinkRef link, SDL_DisplayMod
|
|||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
Cocoa_ReleaseDisplayMode(_THIS, const void *moderef)
|
||||
{
|
||||
if (IS_SNOW_LEOPARD_OR_LATER()) {
|
||||
CGDisplayModeRelease((CGDisplayModeRef) moderef); /* NULL is ok */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
Cocoa_ReleaseDisplayModeList(_THIS, CFArrayRef modelist)
|
||||
{
|
||||
if (IS_SNOW_LEOPARD_OR_LATER()) {
|
||||
CFRelease(modelist); /* NULL is ok */
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
Cocoa_GetDisplayName(CGDirectDisplayID displayID)
|
||||
{
|
||||
|
|
@ -261,7 +208,7 @@ Cocoa_InitModes(_THIS)
|
|||
SDL_VideoDisplay display;
|
||||
SDL_DisplayData *displaydata;
|
||||
SDL_DisplayMode mode;
|
||||
const void *moderef = NULL;
|
||||
CGDisplayModeRef moderef = NULL;
|
||||
CVDisplayLinkRef link = NULL;
|
||||
|
||||
if (pass == 0) {
|
||||
|
|
@ -278,15 +225,7 @@ Cocoa_InitModes(_THIS)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (IS_SNOW_LEOPARD_OR_LATER()) {
|
||||
moderef = CGDisplayCopyDisplayMode(displays[i]);
|
||||
}
|
||||
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
|
||||
if (!IS_SNOW_LEOPARD_OR_LATER()) {
|
||||
moderef = CGDisplayCurrentMode(displays[i]);
|
||||
}
|
||||
#endif
|
||||
moderef = CGDisplayCopyDisplayMode(displays[i]);
|
||||
|
||||
if (!moderef) {
|
||||
continue;
|
||||
|
|
@ -294,7 +233,7 @@ Cocoa_InitModes(_THIS)
|
|||
|
||||
displaydata = (SDL_DisplayData *) SDL_malloc(sizeof(*displaydata));
|
||||
if (!displaydata) {
|
||||
Cocoa_ReleaseDisplayMode(_this, moderef);
|
||||
CGDisplayModeRelease(moderef);
|
||||
continue;
|
||||
}
|
||||
displaydata->display = displays[i];
|
||||
|
|
@ -306,7 +245,7 @@ Cocoa_InitModes(_THIS)
|
|||
display.name = (char *)Cocoa_GetDisplayName(displays[i]);
|
||||
if (!GetDisplayMode(_this, moderef, link, &mode)) {
|
||||
CVDisplayLinkRelease(link);
|
||||
Cocoa_ReleaseDisplayMode(_this, moderef);
|
||||
CGDisplayModeRelease(moderef);
|
||||
SDL_free(display.name);
|
||||
SDL_free(displaydata);
|
||||
continue;
|
||||
|
|
@ -338,21 +277,70 @@ Cocoa_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Cocoa_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect)
|
||||
{
|
||||
SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
|
||||
const CGDirectDisplayID cgdisplay = displaydata->display;
|
||||
NSArray *screens = [NSScreen screens];
|
||||
NSScreen *screen = nil;
|
||||
|
||||
/* !!! FIXME: maybe track the NSScreen in SDL_DisplayData? */
|
||||
for (NSScreen *i in screens) {
|
||||
const CGDirectDisplayID thisDisplay = (CGDirectDisplayID) [[[i deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue];
|
||||
if (thisDisplay == cgdisplay) {
|
||||
screen = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_assert(screen != nil); /* didn't find it?! */
|
||||
if (screen == nil) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const CGRect cgrect = CGDisplayBounds(cgdisplay);
|
||||
const NSRect frame = [screen visibleFrame];
|
||||
|
||||
// !!! FIXME: I assume -[NSScreen visibleFrame] is relative to the origin of the screen in question and not the whole desktop.
|
||||
// !!! FIXME: The math vs CGDisplayBounds might be incorrect if that's not the case, though. Check this.
|
||||
rect->x = (int)(cgrect.origin.x + frame.origin.x);
|
||||
rect->y = (int)(cgrect.origin.y + frame.origin.y);
|
||||
rect->w = (int)frame.size.width;
|
||||
rect->h = (int)frame.size.height;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Cocoa_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi)
|
||||
{
|
||||
const float MM_IN_INCH = 25.4f;
|
||||
|
||||
SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
|
||||
|
||||
CGSize displaySize = CGDisplayScreenSize(data->display);
|
||||
int pixelWidth = (int) CGDisplayPixelsWide(data->display);
|
||||
int pixelHeight = (int) CGDisplayPixelsHigh(data->display);
|
||||
|
||||
if (ddpi) {
|
||||
*ddpi = SDL_ComputeDiagonalDPI(pixelWidth, pixelHeight, displaySize.width / MM_IN_INCH, displaySize.height / MM_IN_INCH);
|
||||
}
|
||||
if (hdpi) {
|
||||
*hdpi = pixelWidth * MM_IN_INCH / displaySize.width;
|
||||
}
|
||||
if (vdpi) {
|
||||
*vdpi = pixelHeight * MM_IN_INCH / displaySize.height;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
|
||||
{
|
||||
SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
|
||||
CFArrayRef modes = NULL;
|
||||
|
||||
if (IS_SNOW_LEOPARD_OR_LATER()) {
|
||||
modes = CGDisplayCopyAllDisplayModes(data->display, NULL);
|
||||
}
|
||||
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
|
||||
if (!IS_SNOW_LEOPARD_OR_LATER()) {
|
||||
modes = CGDisplayAvailableModes(data->display);
|
||||
}
|
||||
#endif
|
||||
CFArrayRef modes = CGDisplayCopyAllDisplayModes(data->display, NULL);
|
||||
|
||||
if (modes) {
|
||||
CVDisplayLinkRef link = NULL;
|
||||
|
|
@ -362,37 +350,19 @@ Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
|
|||
CVDisplayLinkCreateWithCGDisplay(data->display, &link);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
const void *moderef = CFArrayGetValueAtIndex(modes, i);
|
||||
CGDisplayModeRef moderef = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
|
||||
SDL_DisplayMode mode;
|
||||
if (GetDisplayMode(_this, moderef, link, &mode)) {
|
||||
if (IS_SNOW_LEOPARD_OR_LATER()) {
|
||||
CGDisplayModeRetain((CGDisplayModeRef) moderef);
|
||||
}
|
||||
CGDisplayModeRetain(moderef);
|
||||
SDL_AddDisplayMode(display, &mode);
|
||||
}
|
||||
}
|
||||
|
||||
CVDisplayLinkRelease(link);
|
||||
Cocoa_ReleaseDisplayModeList(_this, modes);
|
||||
CFRelease(modes);
|
||||
}
|
||||
}
|
||||
|
||||
static CGError
|
||||
Cocoa_SwitchMode(_THIS, CGDirectDisplayID display, const void *mode)
|
||||
{
|
||||
if (IS_SNOW_LEOPARD_OR_LATER()) {
|
||||
return CGDisplaySetDisplayMode(display, (CGDisplayModeRef) mode, NULL);
|
||||
}
|
||||
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
|
||||
if (!IS_SNOW_LEOPARD_OR_LATER()) {
|
||||
return CGDisplaySwitchToMode(display, (CFDictionaryRef) mode);
|
||||
}
|
||||
#endif
|
||||
|
||||
return kCGErrorFailure;
|
||||
}
|
||||
|
||||
int
|
||||
Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
|
||||
{
|
||||
|
|
@ -408,7 +378,7 @@ Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
|
|||
|
||||
if (data == display->desktop_mode.driverdata) {
|
||||
/* Restoring desktop mode */
|
||||
Cocoa_SwitchMode(_this, displaydata->display, data->moderef);
|
||||
CGDisplaySetDisplayMode(displaydata->display, data->moderef, NULL);
|
||||
|
||||
if (CGDisplayIsMain(displaydata->display)) {
|
||||
CGReleaseAllDisplays();
|
||||
|
|
@ -433,7 +403,7 @@ Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
|
|||
}
|
||||
|
||||
/* Do the physical switch */
|
||||
result = Cocoa_SwitchMode(_this, displaydata->display, data->moderef);
|
||||
result = CGDisplaySetDisplayMode(displaydata->display, data->moderef, NULL);
|
||||
if (result != kCGErrorSuccess) {
|
||||
CG_SetError("CGDisplaySwitchToMode()", result);
|
||||
goto ERR_NO_SWITCH;
|
||||
|
|
@ -478,11 +448,11 @@ Cocoa_QuitModes(_THIS)
|
|||
}
|
||||
|
||||
mode = (SDL_DisplayModeData *) display->desktop_mode.driverdata;
|
||||
Cocoa_ReleaseDisplayMode(_this, mode->moderef);
|
||||
CGDisplayModeRelease(mode->moderef);
|
||||
|
||||
for (j = 0; j < display->num_display_modes; j++) {
|
||||
mode = (SDL_DisplayModeData*) display->display_modes[j].driverdata;
|
||||
Cocoa_ReleaseDisplayMode(_this, mode->moderef);
|
||||
CGDisplayModeRelease(mode->moderef);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -226,13 +226,15 @@ Cocoa_WarpMouseGlobal(int x, int y)
|
|||
|
||||
Cocoa_HandleMouseWarp(point.x, point.y);
|
||||
|
||||
/* According to the docs, this was deprecated in 10.6, but it's still
|
||||
* around. The substitute requires a CGEventSource, but I'm not entirely
|
||||
* sure how we'd procure the right one for this event.
|
||||
*/
|
||||
CGSetLocalEventsSuppressionInterval(0.0);
|
||||
CGWarpMouseCursorPosition(point);
|
||||
CGSetLocalEventsSuppressionInterval(0.25);
|
||||
|
||||
/* CGWarpMouse causes a short delay by default, which is preventable by
|
||||
* Calling this directly after. CGSetLocalEventsSuppressionInterval can also
|
||||
* prevent it, but it's deprecated as of OS X 10.6.
|
||||
*/
|
||||
if (!mouse->relative_mode) {
|
||||
CGAssociateMouseAndMouseCursorPosition(YES);
|
||||
}
|
||||
|
||||
/* CGWarpMouseCursorPosition doesn't generate a window event, unlike our
|
||||
* other implementations' APIs. Send what's appropriate.
|
||||
|
|
@ -314,7 +316,7 @@ Cocoa_GetGlobalMouseState(int *x, int *y)
|
|||
|
||||
for (NSScreen *screen in [NSScreen screens]) {
|
||||
NSRect frame = [screen frame];
|
||||
if (NSPointInRect(cocoaLocation, frame)) {
|
||||
if (NSMouseInRect(cocoaLocation, frame, NO)) {
|
||||
*x = (int) cocoaLocation.x;
|
||||
*y = (int) ((frame.origin.y + frame.size.height) - cocoaLocation.y);
|
||||
break;
|
||||
|
|
@ -396,7 +398,7 @@ Cocoa_HandleMouseEvent(_THIS, NSEvent *event)
|
|||
/* Ignore events that aren't inside the client area (i.e. title bar.) */
|
||||
if ([event window]) {
|
||||
NSRect windowRect = [[[event window] contentView] frame];
|
||||
if (!NSPointInRect([event locationInWindow], windowRect)) {
|
||||
if (!NSMouseInRect([event locationInWindow], windowRect, NO)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -419,8 +421,8 @@ Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event)
|
|||
{
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
|
||||
float x = -[event deltaX];
|
||||
float y = [event deltaY];
|
||||
CGFloat x = -[event deltaX];
|
||||
CGFloat y = [event deltaY];
|
||||
SDL_MouseWheelDirection direction = SDL_MOUSEWHEEL_NORMAL;
|
||||
|
||||
if ([event respondsToSelector:@selector(isDirectionInvertedFromDevice)]) {
|
||||
|
|
@ -430,14 +432,14 @@ Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event)
|
|||
}
|
||||
|
||||
if (x > 0) {
|
||||
x += 0.9f;
|
||||
x = SDL_ceil(x);
|
||||
} else if (x < 0) {
|
||||
x -= 0.9f;
|
||||
x = SDL_floor(x);
|
||||
}
|
||||
if (y > 0) {
|
||||
y += 0.9f;
|
||||
y = SDL_ceil(y);
|
||||
} else if (y < 0) {
|
||||
y -= 0.9f;
|
||||
y = SDL_floor(y);
|
||||
}
|
||||
SDL_SendMouseWheel(window, mouse->mouseID, (int)x, (int)y, direction);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@
|
|||
#if SDL_MAC_NO_SANDBOX
|
||||
|
||||
#include "SDL_keyboard.h"
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_cocoavideo.h"
|
||||
#include "../../thread/SDL_systhread.h"
|
||||
|
||||
#include "../../events/SDL_mouse_c.h"
|
||||
|
||||
|
|
@ -96,7 +96,7 @@ Cocoa_MouseTapCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event
|
|||
eventLocation = CGEventGetUnflippedLocation(event);
|
||||
windowRect = [nswindow contentRectForFrameRect:[nswindow frame]];
|
||||
|
||||
if (!NSPointInRect(NSPointFromCGPoint(eventLocation), windowRect)) {
|
||||
if (!NSMouseInRect(NSPointFromCGPoint(eventLocation), windowRect, NO)) {
|
||||
|
||||
/* This is in CGs global screenspace coordinate system, which has a
|
||||
* flipped Y.
|
||||
|
|
@ -109,15 +109,14 @@ Cocoa_MouseTapCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event
|
|||
newLocation.x = NSMaxX(windowRect) - 1.0;
|
||||
}
|
||||
|
||||
if (eventLocation.y < NSMinY(windowRect)) {
|
||||
if (eventLocation.y <= NSMinY(windowRect)) {
|
||||
newLocation.y -= (NSMinY(windowRect) - eventLocation.y + 1);
|
||||
} else if (eventLocation.y >= NSMaxY(windowRect)) {
|
||||
newLocation.y += (eventLocation.y - NSMaxY(windowRect) + 1);
|
||||
} else if (eventLocation.y > NSMaxY(windowRect)) {
|
||||
newLocation.y += (eventLocation.y - NSMaxY(windowRect));
|
||||
}
|
||||
|
||||
CGSetLocalEventsSuppressionInterval(0);
|
||||
CGWarpMouseCursorPosition(newLocation);
|
||||
CGSetLocalEventsSuppressionInterval(0.25);
|
||||
CGAssociateMouseAndMouseCursorPosition(YES);
|
||||
|
||||
if ((CGEventMaskBit(type) & movementEventsMask) == 0) {
|
||||
/* For click events, we just constrain the event to the window, so
|
||||
|
|
@ -203,7 +202,7 @@ Cocoa_InitMouseEventTap(SDL_MouseData* driverdata)
|
|||
|
||||
tapdata->runloopStartedSemaphore = SDL_CreateSemaphore(0);
|
||||
if (tapdata->runloopStartedSemaphore) {
|
||||
tapdata->thread = SDL_CreateThread(&Cocoa_MouseTapThread, "Event Tap Loop", tapdata);
|
||||
tapdata->thread = SDL_CreateThreadInternal(&Cocoa_MouseTapThread, "Event Tap Loop", 512 * 1024, tapdata);
|
||||
if (!tapdata->thread) {
|
||||
SDL_DestroySemaphore(tapdata->runloopStartedSemaphore);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -173,6 +173,8 @@ Cocoa_GL_CreateContext(_THIS, SDL_Window * window)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
attr[i++] = NSOpenGLPFAAllowOfflineRenderers;
|
||||
|
||||
/* specify a profile if we're on Lion (10.7) or later. */
|
||||
if (lion_or_later) {
|
||||
NSOpenGLPixelFormatAttribute profile = NSOpenGLProfileVersionLegacy;
|
||||
|
|
|
|||
|
|
@ -35,9 +35,7 @@ Cocoa_CreateShaper(SDL_Window* window)
|
|||
SDL_WindowData* windata = (SDL_WindowData*)window->driverdata;
|
||||
[windata->nswindow setOpaque:NO];
|
||||
|
||||
if ([windata->nswindow respondsToSelector:@selector(setStyleMask:)]) {
|
||||
[windata->nswindow setStyleMask:NSBorderlessWindowMask];
|
||||
}
|
||||
[windata->nswindow setStyleMask:NSBorderlessWindowMask];
|
||||
|
||||
SDL_WindowShaper* result = result = malloc(sizeof(SDL_WindowShaper));
|
||||
result->window = window;
|
||||
|
|
|
|||
|
|
@ -73,6 +73,8 @@ Cocoa_CreateDevice(int devindex)
|
|||
device->VideoInit = Cocoa_VideoInit;
|
||||
device->VideoQuit = Cocoa_VideoQuit;
|
||||
device->GetDisplayBounds = Cocoa_GetDisplayBounds;
|
||||
device->GetDisplayUsableBounds = Cocoa_GetDisplayUsableBounds;
|
||||
device->GetDisplayDPI = Cocoa_GetDisplayDPI;
|
||||
device->GetDisplayModes = Cocoa_GetDisplayModes;
|
||||
device->SetDisplayMode = Cocoa_SetDisplayMode;
|
||||
device->PumpEvents = Cocoa_PumpEvents;
|
||||
|
|
@ -86,6 +88,7 @@ Cocoa_CreateDevice(int devindex)
|
|||
device->SetWindowSize = Cocoa_SetWindowSize;
|
||||
device->SetWindowMinimumSize = Cocoa_SetWindowMinimumSize;
|
||||
device->SetWindowMaximumSize = Cocoa_SetWindowMaximumSize;
|
||||
device->SetWindowOpacity = Cocoa_SetWindowOpacity;
|
||||
device->ShowWindow = Cocoa_ShowWindow;
|
||||
device->HideWindow = Cocoa_HideWindow;
|
||||
device->RaiseWindow = Cocoa_RaiseWindow;
|
||||
|
|
@ -93,6 +96,7 @@ Cocoa_CreateDevice(int devindex)
|
|||
device->MinimizeWindow = Cocoa_MinimizeWindow;
|
||||
device->RestoreWindow = Cocoa_RestoreWindow;
|
||||
device->SetWindowBordered = Cocoa_SetWindowBordered;
|
||||
device->SetWindowResizable = Cocoa_SetWindowResizable;
|
||||
device->SetWindowFullscreen = Cocoa_SetWindowFullscreen;
|
||||
device->SetWindowGammaRamp = Cocoa_SetWindowGammaRamp;
|
||||
device->GetWindowGammaRamp = Cocoa_GetWindowGammaRamp;
|
||||
|
|
@ -146,8 +150,7 @@ Cocoa_VideoInit(_THIS)
|
|||
Cocoa_InitKeyboard(_this);
|
||||
Cocoa_InitMouse(_this);
|
||||
|
||||
const char *hint = SDL_GetHint(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES);
|
||||
data->allow_spaces = ( (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) && (!hint || (*hint != '0')) );
|
||||
data->allow_spaces = ((floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) && SDL_GetHintBoolean(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, SDL_TRUE));
|
||||
|
||||
/* The IOPM assertion API can disable the screensaver as of 10.7. */
|
||||
data->screensaver_use_iopm = floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6;
|
||||
|
|
@ -173,13 +176,7 @@ Cocoa_CreateImage(SDL_Surface * surface)
|
|||
int i;
|
||||
NSImage *img;
|
||||
|
||||
converted = SDL_ConvertSurfaceFormat(surface,
|
||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||
SDL_PIXELFORMAT_RGBA8888,
|
||||
#else
|
||||
SDL_PIXELFORMAT_ABGR8888,
|
||||
#endif
|
||||
0);
|
||||
converted = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_RGBA32, 0);
|
||||
if (!converted) {
|
||||
return nil;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@ extern void Cocoa_SetWindowPosition(_THIS, SDL_Window * window);
|
|||
extern void Cocoa_SetWindowSize(_THIS, SDL_Window * window);
|
||||
extern void Cocoa_SetWindowMinimumSize(_THIS, SDL_Window * window);
|
||||
extern void Cocoa_SetWindowMaximumSize(_THIS, SDL_Window * window);
|
||||
extern int Cocoa_SetWindowOpacity(_THIS, SDL_Window * window, float opacity);
|
||||
extern void Cocoa_ShowWindow(_THIS, SDL_Window * window);
|
||||
extern void Cocoa_HideWindow(_THIS, SDL_Window * window);
|
||||
extern void Cocoa_RaiseWindow(_THIS, SDL_Window * window);
|
||||
|
|
@ -132,6 +133,7 @@ extern void Cocoa_MaximizeWindow(_THIS, SDL_Window * window);
|
|||
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_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
|
||||
extern int Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp);
|
||||
extern int Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp);
|
||||
|
|
|
|||
|
|
@ -80,20 +80,20 @@
|
|||
|
||||
- (void)sendEvent:(NSEvent *)event
|
||||
{
|
||||
[super sendEvent:event];
|
||||
[super sendEvent:event];
|
||||
|
||||
if ([event type] != NSLeftMouseUp) {
|
||||
return;
|
||||
}
|
||||
if ([event type] != NSLeftMouseUp) {
|
||||
return;
|
||||
}
|
||||
|
||||
id delegate = [self delegate];
|
||||
if (![delegate isKindOfClass:[Cocoa_WindowListener class]]) {
|
||||
return;
|
||||
}
|
||||
id delegate = [self delegate];
|
||||
if (![delegate isKindOfClass:[Cocoa_WindowListener class]]) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ([delegate isMoving]) {
|
||||
[delegate windowDidFinishMoving];
|
||||
}
|
||||
if ([delegate isMoving]) {
|
||||
[delegate windowDidFinishMoving];
|
||||
}
|
||||
}
|
||||
|
||||
/* We'll respond to selectors by doing nothing so we don't beep.
|
||||
|
|
@ -116,9 +116,12 @@
|
|||
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
|
||||
{ @autoreleasepool
|
||||
{
|
||||
SDL_VideoDevice *_this = SDL_GetVideoDevice();
|
||||
NSPasteboard *pasteboard = [sender draggingPasteboard];
|
||||
NSArray *types = [NSArray arrayWithObject:NSFilenamesPboardType];
|
||||
NSString *desiredType = [pasteboard availableTypeFromArray:types];
|
||||
SDL_Window *sdlwindow = nil;
|
||||
|
||||
if (desiredType == nil) {
|
||||
return NO; /* can't accept anything that's being dropped here. */
|
||||
}
|
||||
|
|
@ -132,13 +135,10 @@
|
|||
NSArray *array = [pasteboard propertyListForType:@"NSFilenamesPboardType"];
|
||||
|
||||
for (NSString *path in array) {
|
||||
NSURL *fileURL = [[NSURL fileURLWithPath:path] autorelease];
|
||||
NSURL *fileURL = [NSURL fileURLWithPath:path];
|
||||
NSNumber *isAlias = nil;
|
||||
|
||||
/* Functionality for resolving URL aliases was added with OS X 10.6. */
|
||||
if ([fileURL respondsToSelector:@selector(getResourceValue:forKey:error:)]) {
|
||||
[fileURL getResourceValue:&isAlias forKey:NSURLIsAliasFileKey error:nil];
|
||||
}
|
||||
[fileURL getResourceValue:&isAlias forKey:NSURLIsAliasFileKey error:nil];
|
||||
|
||||
/* If the URL is an alias, resolve it. */
|
||||
if ([isAlias boolValue]) {
|
||||
|
|
@ -157,11 +157,22 @@
|
|||
}
|
||||
}
|
||||
|
||||
if (!SDL_SendDropFile([[fileURL path] UTF8String])) {
|
||||
/* !!! FIXME: is there a better way to do this? */
|
||||
if (_this) {
|
||||
for (sdlwindow = _this->windows; sdlwindow; sdlwindow = sdlwindow->next) {
|
||||
NSWindow *nswindow = ((SDL_WindowData *) sdlwindow->driverdata)->nswindow;
|
||||
if (nswindow == self) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!SDL_SendDropFile(sdlwindow, [[fileURL path] UTF8String])) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_SendDropComplete(sdlwindow);
|
||||
return YES;
|
||||
}}
|
||||
|
||||
|
|
@ -196,17 +207,17 @@ ScheduleContextUpdates(SDL_WindowData *data)
|
|||
}
|
||||
}
|
||||
|
||||
/* !!! FIXME: this should use a hint callback. */
|
||||
static int
|
||||
GetHintCtrlClickEmulateRightClick()
|
||||
{
|
||||
const char *hint = SDL_GetHint( SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK );
|
||||
return hint != NULL && *hint != '0';
|
||||
return SDL_GetHintBoolean(SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK, SDL_FALSE);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
static NSUInteger
|
||||
GetWindowStyle(SDL_Window * window)
|
||||
{
|
||||
unsigned int style;
|
||||
NSUInteger style = 0;
|
||||
|
||||
if (window->flags & SDL_WINDOW_FULLSCREEN) {
|
||||
style = NSBorderlessWindowMask;
|
||||
|
|
@ -224,21 +235,17 @@ GetWindowStyle(SDL_Window * window)
|
|||
}
|
||||
|
||||
static SDL_bool
|
||||
SetWindowStyle(SDL_Window * window, unsigned int style)
|
||||
SetWindowStyle(SDL_Window * window, NSUInteger style)
|
||||
{
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
NSWindow *nswindow = data->nswindow;
|
||||
|
||||
if (![nswindow respondsToSelector: @selector(setStyleMask:)]) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* The view responder chain gets messed with during setStyleMask */
|
||||
if ([[nswindow contentView] nextResponder] == data->listener) {
|
||||
[[nswindow contentView] setNextResponder:nil];
|
||||
}
|
||||
|
||||
[nswindow performSelector: @selector(setStyleMask:) withObject: (id)(uintptr_t)style];
|
||||
[nswindow setStyleMask:style];
|
||||
|
||||
/* The view responder chain gets messed with during setStyleMask */
|
||||
if ([[nswindow contentView] nextResponder] != data->listener) {
|
||||
|
|
@ -302,9 +309,7 @@ SetWindowStyle(SDL_Window * window, unsigned int style)
|
|||
|
||||
[view setNextResponder:self];
|
||||
|
||||
if ([view respondsToSelector:@selector(setAcceptsTouchEvents:)]) {
|
||||
[view setAcceptsTouchEvents:YES];
|
||||
}
|
||||
[view setAcceptsTouchEvents:YES];
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||
|
|
@ -589,12 +594,9 @@ SetWindowStyle(SDL_Window * window, unsigned int style)
|
|||
[NSMenu setMenuBarVisible:NO];
|
||||
}
|
||||
|
||||
/* On pre-10.6, you might have the capslock key state wrong now because we can't check here. */
|
||||
if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_6) {
|
||||
const unsigned int newflags = [NSEvent modifierFlags] & NSAlphaShiftKeyMask;
|
||||
_data->videodata->modifierFlags = (_data->videodata->modifierFlags & ~NSAlphaShiftKeyMask) | newflags;
|
||||
SDL_ToggleModState(KMOD_CAPS, newflags != 0);
|
||||
}
|
||||
const unsigned int newflags = [NSEvent modifierFlags] & NSAlphaShiftKeyMask;
|
||||
_data->videodata->modifierFlags = (_data->videodata->modifierFlags & ~NSAlphaShiftKeyMask) | newflags;
|
||||
SDL_ToggleModState(KMOD_CAPS, newflags != 0);
|
||||
}
|
||||
|
||||
- (void)windowDidResignKey:(NSNotification *)aNotification
|
||||
|
|
@ -820,23 +822,18 @@ SetWindowStyle(SDL_Window * window, unsigned int style)
|
|||
- (void)mouseDown:(NSEvent *)theEvent
|
||||
{
|
||||
int button;
|
||||
int clicks;
|
||||
|
||||
/* Ignore events that aren't inside the client area (i.e. title bar.) */
|
||||
if ([theEvent window]) {
|
||||
NSRect windowRect = [[[theEvent window] contentView] frame];
|
||||
|
||||
/* add one to size, since NSPointInRect is exclusive of the bottom
|
||||
edges, which mean it misses the top of the window by one pixel
|
||||
(as the origin is the bottom left). */
|
||||
windowRect.size.width += 1;
|
||||
windowRect.size.height += 1;
|
||||
|
||||
if (!NSPointInRect([theEvent locationInWindow], windowRect)) {
|
||||
if (!NSMouseInRect([theEvent locationInWindow], windowRect, NO)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ([self processHitTest:theEvent]) {
|
||||
SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0);
|
||||
return; /* dragging, drop event. */
|
||||
}
|
||||
|
||||
|
|
@ -858,10 +855,12 @@ SetWindowStyle(SDL_Window * window, unsigned int style)
|
|||
button = SDL_BUTTON_MIDDLE;
|
||||
break;
|
||||
default:
|
||||
button = [theEvent buttonNumber] + 1;
|
||||
button = (int) [theEvent buttonNumber] + 1;
|
||||
break;
|
||||
}
|
||||
SDL_SendMouseButton(_data->window, 0, SDL_PRESSED, button);
|
||||
|
||||
clicks = (int) [theEvent clickCount];
|
||||
SDL_SendMouseButtonClicks(_data->window, 0, SDL_PRESSED, button, clicks);
|
||||
}
|
||||
|
||||
- (void)rightMouseDown:(NSEvent *)theEvent
|
||||
|
|
@ -877,8 +876,10 @@ SetWindowStyle(SDL_Window * window, unsigned int style)
|
|||
- (void)mouseUp:(NSEvent *)theEvent
|
||||
{
|
||||
int button;
|
||||
int clicks;
|
||||
|
||||
if ([self processHitTest:theEvent]) {
|
||||
SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0);
|
||||
return; /* stopped dragging, drop event. */
|
||||
}
|
||||
|
||||
|
|
@ -898,10 +899,12 @@ SetWindowStyle(SDL_Window * window, unsigned int style)
|
|||
button = SDL_BUTTON_MIDDLE;
|
||||
break;
|
||||
default:
|
||||
button = [theEvent buttonNumber] + 1;
|
||||
button = (int) [theEvent buttonNumber] + 1;
|
||||
break;
|
||||
}
|
||||
SDL_SendMouseButton(_data->window, 0, SDL_RELEASED, button);
|
||||
|
||||
clicks = (int) [theEvent clickCount];
|
||||
SDL_SendMouseButtonClicks(_data->window, 0, SDL_RELEASED, button, clicks);
|
||||
}
|
||||
|
||||
- (void)rightMouseUp:(NSEvent *)theEvent
|
||||
|
|
@ -922,6 +925,7 @@ SetWindowStyle(SDL_Window * window, unsigned int style)
|
|||
int x, y;
|
||||
|
||||
if ([self processHitTest:theEvent]) {
|
||||
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_HIT_TEST, 0, 0);
|
||||
return; /* dragging, drop event. */
|
||||
}
|
||||
|
||||
|
|
@ -956,13 +960,8 @@ SetWindowStyle(SDL_Window * window, unsigned int style)
|
|||
cgpoint.x = window->x + x;
|
||||
cgpoint.y = window->y + y;
|
||||
|
||||
/* According to the docs, this was deprecated in 10.6, but it's still
|
||||
* around. The substitute requires a CGEventSource, but I'm not entirely
|
||||
* sure how we'd procure the right one for this event.
|
||||
*/
|
||||
CGSetLocalEventsSuppressionInterval(0.0);
|
||||
CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint);
|
||||
CGSetLocalEventsSuppressionInterval(0.25);
|
||||
CGAssociateMouseAndMouseCursorPosition(YES);
|
||||
|
||||
Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y);
|
||||
#endif
|
||||
|
|
@ -1075,6 +1074,7 @@ SetWindowStyle(SDL_Window * window, unsigned int style)
|
|||
- (void)rightMouseDown:(NSEvent *)theEvent;
|
||||
- (BOOL)mouseDownCanMoveWindow;
|
||||
- (void)drawRect:(NSRect)dirtyRect;
|
||||
- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent;
|
||||
@end
|
||||
|
||||
@implementation SDLView
|
||||
|
|
@ -1114,6 +1114,15 @@ SetWindowStyle(SDL_Window * window, unsigned int style)
|
|||
cursor:[NSCursor invisibleCursor]];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
|
||||
{
|
||||
if (SDL_GetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH)) {
|
||||
return SDL_GetHintBoolean(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, SDL_FALSE);
|
||||
} else {
|
||||
return SDL_GetHintBoolean("SDL_MAC_MOUSE_FOCUS_CLICKTHROUGH", SDL_FALSE);
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
||||
static int
|
||||
|
|
@ -1157,7 +1166,7 @@ SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, SDL_bool created
|
|||
}
|
||||
|
||||
{
|
||||
unsigned int style = [nswindow styleMask];
|
||||
unsigned long style = [nswindow styleMask];
|
||||
|
||||
if (style == NSBorderlessWindowMask) {
|
||||
window->flags |= SDL_WINDOW_BORDERLESS;
|
||||
|
|
@ -1208,7 +1217,7 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window)
|
|||
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
|
||||
NSRect rect;
|
||||
SDL_Rect bounds;
|
||||
unsigned int style;
|
||||
NSUInteger style;
|
||||
NSArray *screens = [NSScreen screens];
|
||||
|
||||
Cocoa_GetDisplayBounds(_this, display, &bounds);
|
||||
|
|
@ -1263,7 +1272,7 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window)
|
|||
}
|
||||
}
|
||||
|
||||
[nswindow setContentView: contentView];
|
||||
[nswindow setContentView:contentView];
|
||||
[contentView release];
|
||||
|
||||
/* Allow files and folders to be dragged onto the window by users */
|
||||
|
|
@ -1470,27 +1479,6 @@ Cocoa_RestoreWindow(_THIS, SDL_Window * window)
|
|||
}
|
||||
}}
|
||||
|
||||
static NSWindow *
|
||||
Cocoa_RebuildWindow(SDL_WindowData * data, NSWindow * nswindow, unsigned style)
|
||||
{
|
||||
if (!data->created) {
|
||||
/* Don't mess with other people's windows... */
|
||||
return nswindow;
|
||||
}
|
||||
|
||||
[data->listener close];
|
||||
data->nswindow = [[SDLWindow alloc] initWithContentRect:[[nswindow contentView] frame] styleMask:style backing:NSBackingStoreBuffered defer:NO screen:[nswindow screen]];
|
||||
[data->nswindow setContentView:[nswindow contentView]];
|
||||
[data->nswindow registerForDraggedTypes:[NSArray arrayWithObject:(NSString *)kUTTypeFileURL]];
|
||||
/* See comment in SetupWindowData. */
|
||||
[data->nswindow setOneShot:NO];
|
||||
[data->listener listen:data];
|
||||
|
||||
[nswindow close];
|
||||
|
||||
return data->nswindow;
|
||||
}
|
||||
|
||||
void
|
||||
Cocoa_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
|
||||
{ @autoreleasepool
|
||||
|
|
@ -1502,6 +1490,20 @@ Cocoa_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
|
|||
}
|
||||
}}
|
||||
|
||||
void
|
||||
Cocoa_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable)
|
||||
{ @autoreleasepool
|
||||
{
|
||||
/* Don't set this if we're in a space!
|
||||
* The window will get permanently stuck if resizable is false.
|
||||
* -flibit
|
||||
*/
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
Cocoa_WindowListener *listener = data->listener;
|
||||
if (![listener isInFullscreenSpace]) {
|
||||
SetWindowStyle(window, GetWindowStyle(window));
|
||||
}
|
||||
}}
|
||||
|
||||
void
|
||||
Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
|
||||
|
|
@ -1532,11 +1534,7 @@ Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display
|
|||
rect.origin.y += (screenRect.size.height - rect.size.height);
|
||||
}
|
||||
|
||||
if ([nswindow respondsToSelector: @selector(setStyleMask:)]) {
|
||||
[nswindow performSelector: @selector(setStyleMask:) withObject: (id)NSBorderlessWindowMask];
|
||||
} else {
|
||||
nswindow = Cocoa_RebuildWindow(data, nswindow, NSBorderlessWindowMask);
|
||||
}
|
||||
[nswindow setStyleMask:NSBorderlessWindowMask];
|
||||
} else {
|
||||
rect.origin.x = window->windowed.x;
|
||||
rect.origin.y = window->windowed.y;
|
||||
|
|
@ -1544,16 +1542,12 @@ Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display
|
|||
rect.size.height = window->windowed.h;
|
||||
ConvertNSRect([nswindow screen], fullscreen, &rect);
|
||||
|
||||
if ([nswindow respondsToSelector: @selector(setStyleMask:)]) {
|
||||
[nswindow performSelector: @selector(setStyleMask:) withObject: (id)(uintptr_t)GetWindowStyle(window)];
|
||||
[nswindow setStyleMask:GetWindowStyle(window)];
|
||||
|
||||
/* Hack to restore window decorations on Mac OS X 10.10 */
|
||||
NSRect frameRect = [nswindow frame];
|
||||
[nswindow setFrame:NSMakeRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width + 1, frameRect.size.height) display:NO];
|
||||
[nswindow setFrame:frameRect display:NO];
|
||||
} else {
|
||||
nswindow = Cocoa_RebuildWindow(data, nswindow, GetWindowStyle(window));
|
||||
}
|
||||
/* Hack to restore window decorations on Mac OS X 10.10 */
|
||||
NSRect frameRect = [nswindow frame];
|
||||
[nswindow setFrame:NSMakeRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width + 1, frameRect.size.height) display:NO];
|
||||
[nswindow setFrame:frameRect display:NO];
|
||||
}
|
||||
|
||||
/* The view responder chain gets messed with during setStyleMask */
|
||||
|
|
@ -1767,6 +1761,14 @@ Cocoa_SetWindowHitTest(SDL_Window * window, SDL_bool enabled)
|
|||
return 0; /* just succeed, the real work is done elsewhere. */
|
||||
}
|
||||
|
||||
int
|
||||
Cocoa_SetWindowOpacity(_THIS, SDL_Window * window, float opacity)
|
||||
{
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
[data->nswindow setAlphaValue:opacity];
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_COCOA */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ DirectFB_CreateDevice(int devindex)
|
|||
device->SetWindowIcon = DirectFB_SetWindowIcon;
|
||||
device->SetWindowPosition = DirectFB_SetWindowPosition;
|
||||
device->SetWindowSize = DirectFB_SetWindowSize;
|
||||
device->SetWindowOpacity = DirectFB_SetWindowOpacity;
|
||||
device->ShowWindow = DirectFB_ShowWindow;
|
||||
device->HideWindow = DirectFB_HideWindow;
|
||||
device->RaiseWindow = DirectFB_RaiseWindow;
|
||||
|
|
|
|||
|
|
@ -529,4 +529,17 @@ DirectFB_AdjustWindowSurface(SDL_Window * window)
|
|||
return;
|
||||
}
|
||||
|
||||
int
|
||||
DirectFB_SetWindowOpacity(_THIS, SDL_Window * window, float opacity)
|
||||
{
|
||||
const Uint8 alpha = (Uint8) ((unsigned int) (opacity * 255.0f));
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
SDL_DFB_CHECKERR(windata->dfbwin->SetOpacity(windata->dfbwin, alpha));
|
||||
windata->opacity = alpha;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ extern SDL_bool DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window,
|
|||
struct SDL_SysWMinfo *info);
|
||||
|
||||
extern void DirectFB_AdjustWindowSurface(SDL_Window * window);
|
||||
extern int DirectFB_SetWindowOpacity(_THIS, SDL_Window * window, float opacity);
|
||||
|
||||
#endif /* _SDL_directfb_window_h */
|
||||
|
||||
|
|
|
|||
|
|
@ -217,16 +217,16 @@ static const SDL_Scancode emscripten_scancode_table[] = {
|
|||
/* 171 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 172 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 173 */ SDL_SCANCODE_MINUS, /*FX*/
|
||||
/* 174 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 175 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 176 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 177 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 174 */ SDL_SCANCODE_VOLUMEDOWN, /*IE, Chrome*/
|
||||
/* 175 */ SDL_SCANCODE_VOLUMEUP, /*IE, Chrome*/
|
||||
/* 176 */ SDL_SCANCODE_AUDIONEXT, /*IE, Chrome*/
|
||||
/* 177 */ SDL_SCANCODE_AUDIOPREV, /*IE, Chrome*/
|
||||
/* 178 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 179 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 179 */ SDL_SCANCODE_AUDIOPLAY, /*IE, Chrome*/
|
||||
/* 180 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 181 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 182 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 183 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 181 */ SDL_SCANCODE_AUDIOMUTE, /*FX*/
|
||||
/* 182 */ SDL_SCANCODE_VOLUMEDOWN, /*FX*/
|
||||
/* 183 */ SDL_SCANCODE_VOLUMEUP, /*FX*/
|
||||
/* 184 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 185 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 186 */ SDL_SCANCODE_SEMICOLON, /*IE, Chrome, D3E legacy*/
|
||||
|
|
@ -301,25 +301,34 @@ EM_BOOL
|
|||
Emscripten_HandleMouseMove(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData)
|
||||
{
|
||||
SDL_WindowData *window_data = userData;
|
||||
int mx = mouseEvent->canvasX, my = mouseEvent->canvasY;
|
||||
int mx, my;
|
||||
static double residualx = 0, residualy = 0;
|
||||
EmscriptenPointerlockChangeEvent pointerlock_status;
|
||||
|
||||
/* check for pointer lock */
|
||||
emscripten_get_pointerlock_status(&pointerlock_status);
|
||||
/* rescale (in case canvas is being scaled)*/
|
||||
double client_w, client_h, xscale, yscale;
|
||||
emscripten_get_element_css_size(NULL, &client_w, &client_h);
|
||||
xscale = window_data->window->w / client_w;
|
||||
yscale = window_data->window->h / client_h;
|
||||
|
||||
if (pointerlock_status.isActive) {
|
||||
mx = mouseEvent->movementX;
|
||||
my = mouseEvent->movementY;
|
||||
/* check for pointer lock */
|
||||
int isPointerLockSupported = emscripten_get_pointerlock_status(&pointerlock_status);
|
||||
int isPointerLocked = isPointerLockSupported == EMSCRIPTEN_RESULT_SUCCESS ? pointerlock_status.isActive : SDL_FALSE;
|
||||
|
||||
if (isPointerLocked) {
|
||||
residualx += mouseEvent->movementX * xscale;
|
||||
residualy += mouseEvent->movementY * yscale;
|
||||
/* Let slow sub-pixel motion accumulate. Don't lose it. */
|
||||
mx = residualx;
|
||||
residualx -= mx;
|
||||
my = residualy;
|
||||
residualy -= my;
|
||||
} else {
|
||||
mx = mouseEvent->canvasX * xscale;
|
||||
my = mouseEvent->canvasY * yscale;
|
||||
}
|
||||
|
||||
/* rescale (in case canvas is being scaled)*/
|
||||
double client_w, client_h;
|
||||
emscripten_get_element_css_size(NULL, &client_w, &client_h);
|
||||
|
||||
mx = mx * (window_data->window->w / (client_w * window_data->pixel_ratio));
|
||||
my = my * (window_data->window->h / (client_h * window_data->pixel_ratio));
|
||||
|
||||
SDL_SendMouseMotion(window_data->window, 0, pointerlock_status.isActive, mx, my);
|
||||
SDL_SendMouseMotion(window_data->window, 0, isPointerLocked, mx, my);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -341,16 +350,36 @@ Emscripten_HandleMouseButton(int eventType, const EmscriptenMouseEvent *mouseEve
|
|||
default:
|
||||
return 0;
|
||||
}
|
||||
SDL_SendMouseButton(window_data->window, 0, eventType == EMSCRIPTEN_EVENT_MOUSEDOWN ? SDL_PRESSED : SDL_RELEASED, sdl_button);
|
||||
return 1;
|
||||
|
||||
SDL_EventType sdl_event_type = (eventType == EMSCRIPTEN_EVENT_MOUSEDOWN ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_SendMouseButton(window_data->window, 0, sdl_event_type, sdl_button);
|
||||
return SDL_GetEventState(sdl_event_type) == SDL_ENABLE;
|
||||
}
|
||||
|
||||
EM_BOOL
|
||||
Emscripten_HandleMouseFocus(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData)
|
||||
{
|
||||
SDL_WindowData *window_data = userData;
|
||||
SDL_SendWindowEvent(window_data->window, eventType == EMSCRIPTEN_EVENT_MOUSEENTER ? SDL_WINDOWEVENT_ENTER : SDL_WINDOWEVENT_LEAVE, 0, 0);
|
||||
return 1;
|
||||
|
||||
int mx = mouseEvent->canvasX, my = mouseEvent->canvasY;
|
||||
EmscriptenPointerlockChangeEvent pointerlock_status;
|
||||
|
||||
/* check for pointer lock */
|
||||
int isPointerLockSupported = emscripten_get_pointerlock_status(&pointerlock_status);
|
||||
int isPointerLocked = isPointerLockSupported == EMSCRIPTEN_RESULT_SUCCESS ? pointerlock_status.isActive : SDL_FALSE;
|
||||
|
||||
if (!isPointerLocked) {
|
||||
/* rescale (in case canvas is being scaled)*/
|
||||
double client_w, client_h;
|
||||
emscripten_get_element_css_size(NULL, &client_w, &client_h);
|
||||
|
||||
mx = mx * (window_data->window->w / client_w);
|
||||
my = my * (window_data->window->h / client_h);
|
||||
SDL_SendMouseMotion(window_data->window, 0, isPointerLocked, mx, my);
|
||||
}
|
||||
|
||||
SDL_SetMouseFocus(eventType == EMSCRIPTEN_EVENT_MOUSEENTER ? window_data->window : NULL);
|
||||
return SDL_GetEventState(SDL_WINDOWEVENT) == SDL_ENABLE;
|
||||
}
|
||||
|
||||
EM_BOOL
|
||||
|
|
@ -358,15 +387,22 @@ Emscripten_HandleWheel(int eventType, const EmscriptenWheelEvent *wheelEvent, vo
|
|||
{
|
||||
SDL_WindowData *window_data = userData;
|
||||
SDL_SendMouseWheel(window_data->window, 0, wheelEvent->deltaX, -wheelEvent->deltaY, SDL_MOUSEWHEEL_NORMAL);
|
||||
return 1;
|
||||
return SDL_GetEventState(SDL_MOUSEWHEEL) == SDL_ENABLE;
|
||||
}
|
||||
|
||||
EM_BOOL
|
||||
Emscripten_HandleFocus(int eventType, const EmscriptenFocusEvent *wheelEvent, void *userData)
|
||||
{
|
||||
SDL_WindowData *window_data = userData;
|
||||
/* If the user switches away while keys are pressed (such as
|
||||
* via Alt+Tab), key release events won't be received. */
|
||||
if (eventType == EMSCRIPTEN_EVENT_BLUR) {
|
||||
SDL_ResetKeyboard();
|
||||
}
|
||||
|
||||
|
||||
SDL_SendWindowEvent(window_data->window, eventType == EMSCRIPTEN_EVENT_FOCUS ? SDL_WINDOWEVENT_FOCUS_GAINED : SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
|
||||
return 1;
|
||||
return SDL_GetEventState(SDL_WINDOWEVENT) == SDL_ENABLE;
|
||||
}
|
||||
|
||||
EM_BOOL
|
||||
|
|
@ -374,12 +410,16 @@ Emscripten_HandleTouch(int eventType, const EmscriptenTouchEvent *touchEvent, vo
|
|||
{
|
||||
SDL_WindowData *window_data = userData;
|
||||
int i;
|
||||
double client_w, client_h;
|
||||
int preventDefault = 0;
|
||||
|
||||
SDL_TouchID deviceId = 1;
|
||||
if (SDL_AddTouch(deviceId, "") < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
emscripten_get_element_css_size(NULL, &client_w, &client_h);
|
||||
|
||||
for (i = 0; i < touchEvent->numTouches; i++) {
|
||||
SDL_FingerID id;
|
||||
float x, y;
|
||||
|
|
@ -388,20 +428,44 @@ Emscripten_HandleTouch(int eventType, const EmscriptenTouchEvent *touchEvent, vo
|
|||
continue;
|
||||
|
||||
id = touchEvent->touches[i].identifier;
|
||||
x = touchEvent->touches[i].canvasX / (float)window_data->windowed_width;
|
||||
y = touchEvent->touches[i].canvasY / (float)window_data->windowed_height;
|
||||
x = touchEvent->touches[i].canvasX / client_w;
|
||||
y = touchEvent->touches[i].canvasY / client_h;
|
||||
|
||||
if (eventType == EMSCRIPTEN_EVENT_TOUCHMOVE) {
|
||||
SDL_SendTouchMotion(deviceId, id, x, y, 1.0f);
|
||||
} else if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART) {
|
||||
if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART) {
|
||||
if (!window_data->finger_touching) {
|
||||
window_data->finger_touching = SDL_TRUE;
|
||||
window_data->first_finger = id;
|
||||
SDL_SendMouseMotion(window_data->window, SDL_TOUCH_MOUSEID, 0, x, y);
|
||||
SDL_SendMouseButton(window_data->window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
|
||||
}
|
||||
SDL_SendTouch(deviceId, id, SDL_TRUE, x, y, 1.0f);
|
||||
|
||||
if (!preventDefault && SDL_GetEventState(SDL_FINGERDOWN) == SDL_ENABLE) {
|
||||
preventDefault = 1;
|
||||
}
|
||||
} else if (eventType == EMSCRIPTEN_EVENT_TOUCHMOVE) {
|
||||
if ((window_data->finger_touching) && (window_data->first_finger == id)) {
|
||||
SDL_SendMouseMotion(window_data->window, SDL_TOUCH_MOUSEID, 0, x, y);
|
||||
}
|
||||
SDL_SendTouchMotion(deviceId, id, x, y, 1.0f);
|
||||
|
||||
if (!preventDefault && SDL_GetEventState(SDL_FINGERMOTION) == SDL_ENABLE) {
|
||||
preventDefault = 1;
|
||||
}
|
||||
} else {
|
||||
if ((window_data->finger_touching) && (window_data->first_finger == id)) {
|
||||
SDL_SendMouseButton(window_data->window, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
|
||||
window_data->finger_touching = SDL_FALSE;
|
||||
}
|
||||
SDL_SendTouch(deviceId, id, SDL_FALSE, x, y, 1.0f);
|
||||
|
||||
if (!preventDefault && SDL_GetEventState(SDL_FINGERUP) == SDL_ENABLE) {
|
||||
preventDefault = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 1;
|
||||
return preventDefault;
|
||||
}
|
||||
|
||||
EM_BOOL
|
||||
|
|
@ -431,16 +495,19 @@ Emscripten_HandleKey(int eventType, const EmscriptenKeyboardEvent *keyEvent, voi
|
|||
break;
|
||||
}
|
||||
}
|
||||
SDL_SendKeyboardKey(eventType == EMSCRIPTEN_EVENT_KEYDOWN ?
|
||||
SDL_PRESSED : SDL_RELEASED, scancode);
|
||||
SDL_SendKeyboardKey(eventType == EMSCRIPTEN_EVENT_KEYDOWN ? SDL_PRESSED : SDL_RELEASED, scancode);
|
||||
}
|
||||
}
|
||||
|
||||
/* if we prevent keydown, we won't get keypress
|
||||
* also we need to ALWAYS prevent backspace and tab otherwise chrome takes action and does bad navigation UX
|
||||
SDL_bool prevent_default = SDL_GetEventState(eventType == EMSCRIPTEN_EVENT_KEYDOWN ? SDL_KEYDOWN : SDL_KEYUP) == SDL_ENABLE;
|
||||
|
||||
/* if TEXTINPUT events are enabled we can't prevent keydown or we won't get keypress
|
||||
* we need to ALWAYS prevent backspace and tab otherwise chrome takes action and does bad navigation UX
|
||||
*/
|
||||
return SDL_GetEventState(SDL_TEXTINPUT) != SDL_ENABLE || eventType != EMSCRIPTEN_EVENT_KEYDOWN
|
||||
|| keyEvent->keyCode == 8 /* backspace */ || keyEvent->keyCode == 9 /* tab */;
|
||||
if (eventType == EMSCRIPTEN_EVENT_KEYDOWN && SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE && keyEvent->keyCode != 8 /* backspace */ && keyEvent->keyCode != 9 /* tab */)
|
||||
prevent_default = SDL_FALSE;
|
||||
|
||||
return prevent_default;
|
||||
}
|
||||
|
||||
EM_BOOL
|
||||
|
|
@ -450,65 +517,24 @@ Emscripten_HandleKeyPress(int eventType, const EmscriptenKeyboardEvent *keyEvent
|
|||
if (Emscripten_ConvertUTF32toUTF8(keyEvent->charCode, text)) {
|
||||
SDL_SendKeyboardText(text);
|
||||
}
|
||||
return 1;
|
||||
return SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE;
|
||||
}
|
||||
|
||||
EM_BOOL
|
||||
Emscripten_HandleFullscreenChange(int eventType, const EmscriptenFullscreenChangeEvent *fullscreenChangeEvent, void *userData)
|
||||
{
|
||||
/*make sure this is actually our element going fullscreen*/
|
||||
if(SDL_strcmp(fullscreenChangeEvent->id, "SDLFullscreenElement") != 0)
|
||||
return 0;
|
||||
|
||||
SDL_WindowData *window_data = userData;
|
||||
if(fullscreenChangeEvent->isFullscreen)
|
||||
{
|
||||
SDL_bool is_desktop_fullscreen;
|
||||
window_data->window->flags |= window_data->requested_fullscreen_mode;
|
||||
|
||||
if(!window_data->requested_fullscreen_mode)
|
||||
window_data->window->flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; /*we didn't reqest fullscreen*/
|
||||
|
||||
window_data->requested_fullscreen_mode = 0;
|
||||
|
||||
is_desktop_fullscreen = (window_data->window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
|
||||
/*update size*/
|
||||
if(window_data->window->flags & SDL_WINDOW_RESIZABLE || is_desktop_fullscreen)
|
||||
{
|
||||
emscripten_set_canvas_size(fullscreenChangeEvent->screenWidth, fullscreenChangeEvent->screenHeight);
|
||||
SDL_SendWindowEvent(window_data->window, SDL_WINDOWEVENT_RESIZED, fullscreenChangeEvent->screenWidth, fullscreenChangeEvent->screenHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*preserve ratio*/
|
||||
double w = window_data->window->w;
|
||||
double h = window_data->window->h;
|
||||
double factor = SDL_min(fullscreenChangeEvent->screenWidth / w, fullscreenChangeEvent->screenHeight / h);
|
||||
emscripten_set_element_css_size(NULL, w * factor, h * factor);
|
||||
}
|
||||
if(!window_data->requested_fullscreen_mode)
|
||||
window_data->window->flags |= SDL_WINDOW_FULLSCREEN; /*we didn't reqest fullscreen*/
|
||||
}
|
||||
else
|
||||
{
|
||||
EM_ASM({
|
||||
//un-reparent canvas (similar to Module.requestFullscreen)
|
||||
var canvas = Module['canvas'];
|
||||
if(canvas.parentNode.id == "SDLFullscreenElement") {
|
||||
var canvasContainer = canvas.parentNode;
|
||||
canvasContainer.parentNode.insertBefore(canvas, canvasContainer);
|
||||
canvasContainer.parentNode.removeChild(canvasContainer);
|
||||
}
|
||||
});
|
||||
double unscaled_w = window_data->windowed_width / window_data->pixel_ratio;
|
||||
double unscaled_h = window_data->windowed_height / window_data->pixel_ratio;
|
||||
emscripten_set_canvas_size(window_data->windowed_width, window_data->windowed_height);
|
||||
|
||||
if (!window_data->external_size && window_data->pixel_ratio != 1.0f) {
|
||||
emscripten_set_element_css_size(NULL, unscaled_w, unscaled_h);
|
||||
}
|
||||
|
||||
SDL_SendWindowEvent(window_data->window, SDL_WINDOWEVENT_RESIZED, unscaled_w, unscaled_h);
|
||||
|
||||
window_data->window->flags &= ~FULLSCREEN_MASK;
|
||||
}
|
||||
|
||||
|
|
@ -519,17 +545,11 @@ EM_BOOL
|
|||
Emscripten_HandleResize(int eventType, const EmscriptenUiEvent *uiEvent, void *userData)
|
||||
{
|
||||
SDL_WindowData *window_data = userData;
|
||||
if(window_data->window->flags & FULLSCREEN_MASK)
|
||||
{
|
||||
SDL_bool is_desktop_fullscreen = (window_data->window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
|
||||
if(window_data->window->flags & SDL_WINDOW_RESIZABLE || is_desktop_fullscreen)
|
||||
{
|
||||
emscripten_set_canvas_size(uiEvent->windowInnerWidth * window_data->pixel_ratio, uiEvent->windowInnerHeight * window_data->pixel_ratio);
|
||||
SDL_SendWindowEvent(window_data->window, SDL_WINDOWEVENT_RESIZED, uiEvent->windowInnerWidth, uiEvent->windowInnerHeight);
|
||||
}
|
||||
}
|
||||
else
|
||||
/* update pixel ratio */
|
||||
window_data->pixel_ratio = emscripten_get_device_pixel_ratio();
|
||||
|
||||
if(!(window_data->window->flags & FULLSCREEN_MASK))
|
||||
{
|
||||
/* this will only work if the canvas size is set through css */
|
||||
if(window_data->window->flags & SDL_WINDOW_RESIZABLE)
|
||||
|
|
@ -555,6 +575,22 @@ Emscripten_HandleResize(int eventType, const EmscriptenUiEvent *uiEvent, void *u
|
|||
return 0;
|
||||
}
|
||||
|
||||
EM_BOOL
|
||||
Emscripten_HandleCanvasResize(int eventType, const void *reserved, void *userData)
|
||||
{
|
||||
/*this is used during fullscreen changes*/
|
||||
SDL_WindowData *window_data = userData;
|
||||
|
||||
if(window_data->fullscreen_resize)
|
||||
{
|
||||
double css_w, css_h;
|
||||
emscripten_get_element_css_size(NULL, &css_w, &css_h);
|
||||
SDL_SendWindowEvent(window_data->window, SDL_WINDOWEVENT_RESIZED, css_w, css_h);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EM_BOOL
|
||||
Emscripten_HandleVisibilityChange(int eventType, const EmscriptenVisibilityChangeEvent *visEvent, void *userData)
|
||||
{
|
||||
|
|
@ -570,15 +606,15 @@ Emscripten_RegisterEventHandlers(SDL_WindowData *data)
|
|||
emscripten_set_mousemove_callback("#canvas", data, 0, Emscripten_HandleMouseMove);
|
||||
|
||||
emscripten_set_mousedown_callback("#canvas", data, 0, Emscripten_HandleMouseButton);
|
||||
emscripten_set_mouseup_callback("#canvas", data, 0, Emscripten_HandleMouseButton);
|
||||
emscripten_set_mouseup_callback("#document", data, 0, Emscripten_HandleMouseButton);
|
||||
|
||||
emscripten_set_mouseenter_callback("#canvas", data, 0, Emscripten_HandleMouseFocus);
|
||||
emscripten_set_mouseleave_callback("#canvas", data, 0, Emscripten_HandleMouseFocus);
|
||||
|
||||
emscripten_set_wheel_callback("#canvas", data, 0, Emscripten_HandleWheel);
|
||||
|
||||
emscripten_set_focus_callback("#canvas", data, 0, Emscripten_HandleFocus);
|
||||
emscripten_set_blur_callback("#canvas", data, 0, Emscripten_HandleFocus);
|
||||
emscripten_set_focus_callback("#window", data, 0, Emscripten_HandleFocus);
|
||||
emscripten_set_blur_callback("#window", data, 0, Emscripten_HandleFocus);
|
||||
|
||||
emscripten_set_touchstart_callback("#canvas", data, 0, Emscripten_HandleTouch);
|
||||
emscripten_set_touchend_callback("#canvas", data, 0, Emscripten_HandleTouch);
|
||||
|
|
@ -607,15 +643,15 @@ Emscripten_UnregisterEventHandlers(SDL_WindowData *data)
|
|||
emscripten_set_mousemove_callback("#canvas", NULL, 0, NULL);
|
||||
|
||||
emscripten_set_mousedown_callback("#canvas", NULL, 0, NULL);
|
||||
emscripten_set_mouseup_callback("#canvas", NULL, 0, NULL);
|
||||
emscripten_set_mouseup_callback("#document", NULL, 0, NULL);
|
||||
|
||||
emscripten_set_mouseenter_callback("#canvas", NULL, 0, NULL);
|
||||
emscripten_set_mouseleave_callback("#canvas", NULL, 0, NULL);
|
||||
|
||||
emscripten_set_wheel_callback("#canvas", NULL, 0, NULL);
|
||||
|
||||
emscripten_set_focus_callback("#canvas", NULL, 0, NULL);
|
||||
emscripten_set_blur_callback("#canvas", NULL, 0, NULL);
|
||||
emscripten_set_focus_callback("#window", NULL, 0, NULL);
|
||||
emscripten_set_blur_callback("#window", NULL, 0, NULL);
|
||||
|
||||
emscripten_set_touchstart_callback("#canvas", NULL, 0, NULL);
|
||||
emscripten_set_touchend_callback("#canvas", NULL, 0, NULL);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,9 @@ Emscripten_RegisterEventHandlers(SDL_WindowData *data);
|
|||
|
||||
extern void
|
||||
Emscripten_UnregisterEventHandlers(SDL_WindowData *data);
|
||||
|
||||
extern int
|
||||
Emscripten_HandleCanvasResize(int eventType, const void *reserved, void *userData);
|
||||
#endif /* _SDL_emscriptenevents_h */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
|||
|
|
@ -69,15 +69,25 @@ int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rec
|
|||
/* Send the data to the display */
|
||||
|
||||
EM_ASM_INT({
|
||||
//TODO: don't create context every update
|
||||
var ctx = Module['canvas'].getContext('2d');
|
||||
var w = $0;
|
||||
var h = $1;
|
||||
var pixels = $2;
|
||||
|
||||
//library_sdl.js SDL_UnlockSurface
|
||||
var image = ctx.createImageData($0, $1);
|
||||
var data = image.data;
|
||||
var src = $2 >> 2;
|
||||
if (!Module['SDL2']) Module['SDL2'] = {};
|
||||
var SDL2 = Module['SDL2'];
|
||||
if (SDL2.ctxCanvas !== Module['canvas']) {
|
||||
SDL2.ctx = Module['createContext'](Module['canvas'], false, true);
|
||||
SDL2.ctxCanvas = Module['canvas'];
|
||||
}
|
||||
if (SDL2.w !== w || SDL2.h !== h || SDL2.imageCtx !== SDL2.ctx) {
|
||||
SDL2.image = SDL2.ctx.createImageData(w, h);
|
||||
SDL2.w = w;
|
||||
SDL2.h = h;
|
||||
SDL2.imageCtx = SDL2.ctx;
|
||||
}
|
||||
var data = SDL2.image.data;
|
||||
var src = pixels >> 2;
|
||||
var dst = 0;
|
||||
var isScreen = true;
|
||||
var num;
|
||||
if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) {
|
||||
// IE10/IE11: ImageData objects are backed by the deprecated CanvasPixelArray,
|
||||
|
|
@ -90,26 +100,58 @@ int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rec
|
|||
data[dst ] = val & 0xff;
|
||||
data[dst+1] = (val >> 8) & 0xff;
|
||||
data[dst+2] = (val >> 16) & 0xff;
|
||||
data[dst+3] = isScreen ? 0xff : ((val >> 24) & 0xff);
|
||||
data[dst+3] = 0xff;
|
||||
src++;
|
||||
dst += 4;
|
||||
}
|
||||
} else {
|
||||
var data32 = new Uint32Array(data.buffer);
|
||||
if (SDL2.data32Data !== data) {
|
||||
SDL2.data32 = new Int32Array(data.buffer);
|
||||
SDL2.data8 = new Uint8Array(data.buffer);
|
||||
}
|
||||
var data32 = SDL2.data32;
|
||||
num = data32.length;
|
||||
if (isScreen) {
|
||||
while (dst < num) {
|
||||
// HEAP32[src++] is an optimization. Instead, we could do {{{ makeGetValue('buffer', 'dst', 'i32') }}};
|
||||
data32[dst++] = HEAP32[src++] | 0xff000000;
|
||||
// logically we need to do
|
||||
// while (dst < num) {
|
||||
// data32[dst++] = HEAP32[src++] | 0xff000000
|
||||
// }
|
||||
// the following code is faster though, because
|
||||
// .set() is almost free - easily 10x faster due to
|
||||
// native memcpy efficiencies, and the remaining loop
|
||||
// just stores, not load + store, so it is faster
|
||||
data32.set(HEAP32.subarray(src, src + num));
|
||||
var data8 = SDL2.data8;
|
||||
var i = 3;
|
||||
var j = i + 4*num;
|
||||
if (num % 8 == 0) {
|
||||
// unrolling gives big speedups
|
||||
while (i < j) {
|
||||
data8[i] = 0xff;
|
||||
i = i + 4 | 0;
|
||||
data8[i] = 0xff;
|
||||
i = i + 4 | 0;
|
||||
data8[i] = 0xff;
|
||||
i = i + 4 | 0;
|
||||
data8[i] = 0xff;
|
||||
i = i + 4 | 0;
|
||||
data8[i] = 0xff;
|
||||
i = i + 4 | 0;
|
||||
data8[i] = 0xff;
|
||||
i = i + 4 | 0;
|
||||
data8[i] = 0xff;
|
||||
i = i + 4 | 0;
|
||||
data8[i] = 0xff;
|
||||
i = i + 4 | 0;
|
||||
}
|
||||
} else {
|
||||
while (dst < num) {
|
||||
data32[dst++] = HEAP32[src++];
|
||||
} else {
|
||||
while (i < j) {
|
||||
data8[i] = 0xff;
|
||||
i = i + 4 | 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx.putImageData(image, 0, 0);
|
||||
SDL2.ctx.putImageData(SDL2.image, 0, 0);
|
||||
return 0;
|
||||
}, surface->w, surface->h, surface->pixels);
|
||||
|
||||
|
|
|
|||
|
|
@ -58,11 +58,13 @@ Emscripten_CreateDefaultCursor()
|
|||
return cursor;
|
||||
}
|
||||
|
||||
/*
|
||||
static SDL_Cursor*
|
||||
Emscripten_CreateCursor(SDL_Surface* sruface, int hot_x, int hot_y)
|
||||
{
|
||||
return Emscripten_CreateDefaultCursor();
|
||||
}
|
||||
*/
|
||||
|
||||
static SDL_Cursor*
|
||||
Emscripten_CreateSystemCursor(SDL_SystemCursor id)
|
||||
|
|
@ -200,7 +202,9 @@ Emscripten_InitMouse()
|
|||
{
|
||||
SDL_Mouse* mouse = SDL_GetMouse();
|
||||
|
||||
/*
|
||||
mouse->CreateCursor = Emscripten_CreateCursor;
|
||||
*/
|
||||
mouse->ShowCursor = Emscripten_ShowCursor;
|
||||
mouse->FreeCursor = Emscripten_FreeCursor;
|
||||
mouse->WarpMouse = Emscripten_WarpMouse;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "SDL_video.h"
|
||||
#include "SDL_mouse.h"
|
||||
#include "SDL_hints.h"
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "../SDL_pixels_c.h"
|
||||
#include "../SDL_egl_c.h"
|
||||
|
|
@ -47,6 +48,7 @@ static void Emscripten_SetWindowSize(_THIS, SDL_Window * window);
|
|||
static void Emscripten_DestroyWindow(_THIS, SDL_Window * window);
|
||||
static void Emscripten_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
|
||||
static void Emscripten_PumpEvents(_THIS);
|
||||
static void Emscripten_SetWindowTitle(_THIS, SDL_Window * window);
|
||||
|
||||
|
||||
/* Emscripten driver bootstrap functions */
|
||||
|
|
@ -75,6 +77,12 @@ Emscripten_CreateDevice(int devindex)
|
|||
return (0);
|
||||
}
|
||||
|
||||
/* Firefox sends blur event which would otherwise prevent full screen
|
||||
* when the user clicks to allow full screen.
|
||||
* See https://bugzilla.mozilla.org/show_bug.cgi?id=1144964
|
||||
*/
|
||||
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
|
||||
|
||||
/* Set the function pointers */
|
||||
device->VideoInit = Emscripten_VideoInit;
|
||||
device->VideoQuit = Emscripten_VideoQuit;
|
||||
|
|
@ -84,9 +92,9 @@ Emscripten_CreateDevice(int devindex)
|
|||
device->PumpEvents = Emscripten_PumpEvents;
|
||||
|
||||
device->CreateWindow = Emscripten_CreateWindow;
|
||||
/*device->CreateWindowFrom = Emscripten_CreateWindowFrom;
|
||||
/*device->CreateWindowFrom = Emscripten_CreateWindowFrom;*/
|
||||
device->SetWindowTitle = Emscripten_SetWindowTitle;
|
||||
device->SetWindowIcon = Emscripten_SetWindowIcon;
|
||||
/*device->SetWindowIcon = Emscripten_SetWindowIcon;
|
||||
device->SetWindowPosition = Emscripten_SetWindowPosition;*/
|
||||
device->SetWindowSize = Emscripten_SetWindowSize;
|
||||
/*device->ShowWindow = Emscripten_ShowWindow;
|
||||
|
|
@ -129,15 +137,17 @@ int
|
|||
Emscripten_VideoInit(_THIS)
|
||||
{
|
||||
SDL_DisplayMode mode;
|
||||
double css_w, css_h;
|
||||
|
||||
/* Use a fake 32-bpp desktop mode */
|
||||
mode.format = SDL_PIXELFORMAT_RGB888;
|
||||
|
||||
emscripten_get_element_css_size(NULL, &css_w, &css_h);
|
||||
mode.w = EM_ASM_INT_V({
|
||||
return screen.width;
|
||||
});
|
||||
|
||||
mode.w = css_w;
|
||||
mode.h = css_h;
|
||||
mode.h = EM_ASM_INT_V({
|
||||
return screen.height;
|
||||
});
|
||||
|
||||
mode.refresh_rate = 0;
|
||||
mode.driverdata = NULL;
|
||||
|
|
@ -199,7 +209,7 @@ Emscripten_CreateWindow(_THIS, SDL_Window * window)
|
|||
|
||||
emscripten_get_element_css_size(NULL, &css_w, &css_h);
|
||||
|
||||
wdata->external_size = css_w != scaled_w || css_h != scaled_h;
|
||||
wdata->external_size = SDL_floor(css_w) != scaled_w || SDL_floor(css_h) != scaled_h;
|
||||
|
||||
if ((window->flags & SDL_WINDOW_RESIZABLE) && wdata->external_size) {
|
||||
/* external css has resized us */
|
||||
|
|
@ -218,9 +228,6 @@ Emscripten_CreateWindow(_THIS, SDL_Window * window)
|
|||
}
|
||||
}
|
||||
|
||||
wdata->windowed_width = scaled_w;
|
||||
wdata->windowed_height = scaled_h;
|
||||
|
||||
if (window->flags & SDL_WINDOW_OPENGL) {
|
||||
if (!_this->egl_data) {
|
||||
if (SDL_GL_LoadLibrary(NULL) < 0) {
|
||||
|
|
@ -255,6 +262,8 @@ static void Emscripten_SetWindowSize(_THIS, SDL_Window * window)
|
|||
|
||||
if (window->driverdata) {
|
||||
data = (SDL_WindowData *) window->driverdata;
|
||||
/* update pixel ratio */
|
||||
data->pixel_ratio = emscripten_get_device_pixel_ratio();
|
||||
emscripten_set_canvas_size(window->w * data->pixel_ratio, window->h * data->pixel_ratio);
|
||||
|
||||
/*scale canvas down*/
|
||||
|
|
@ -290,30 +299,49 @@ Emscripten_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * di
|
|||
data = (SDL_WindowData *) window->driverdata;
|
||||
|
||||
if(fullscreen) {
|
||||
EmscriptenFullscreenStrategy strategy;
|
||||
SDL_bool is_desktop_fullscreen = (window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
int res;
|
||||
|
||||
strategy.scaleMode = is_desktop_fullscreen ? EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH : EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT;
|
||||
|
||||
if(!is_desktop_fullscreen) {
|
||||
strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE;
|
||||
} else if(window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
|
||||
strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF;
|
||||
} else {
|
||||
strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF;
|
||||
}
|
||||
|
||||
strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT;
|
||||
|
||||
strategy.canvasResizedCallback = Emscripten_HandleCanvasResize;
|
||||
strategy.canvasResizedCallbackUserData = data;
|
||||
|
||||
data->requested_fullscreen_mode = window->flags & (SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN);
|
||||
/*unset the fullscreen flags as we're not actually fullscreen yet*/
|
||||
window->flags &= ~(SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN);
|
||||
data->fullscreen_resize = is_desktop_fullscreen;
|
||||
|
||||
EM_ASM({
|
||||
//reparent canvas (similar to Module.requestFullscreen)
|
||||
var canvas = Module['canvas'];
|
||||
if(canvas.parentNode.id != "SDLFullscreenElement") {
|
||||
var canvasContainer = document.createElement("div");
|
||||
canvasContainer.id = "SDLFullscreenElement";
|
||||
canvas.parentNode.insertBefore(canvasContainer, canvas);
|
||||
canvasContainer.appendChild(canvas);
|
||||
}
|
||||
});
|
||||
|
||||
int is_fullscreen;
|
||||
emscripten_get_canvas_size(&data->windowed_width, &data->windowed_height, &is_fullscreen);
|
||||
emscripten_request_fullscreen("SDLFullscreenElement", 1);
|
||||
res = emscripten_request_fullscreen_strategy(NULL, 1, &strategy);
|
||||
if(res != EMSCRIPTEN_RESULT_SUCCESS && res != EMSCRIPTEN_RESULT_DEFERRED) {
|
||||
/* unset flags, fullscreen failed */
|
||||
window->flags &= ~(SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN);
|
||||
}
|
||||
}
|
||||
else
|
||||
emscripten_exit_fullscreen();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
Emscripten_SetWindowTitle(_THIS, SDL_Window * window) {
|
||||
EM_ASM_INT({
|
||||
if (typeof Module['setWindowTitle'] !== 'undefined') {
|
||||
Module['setWindowTitle'](Module['Pointer_stringify']($0));
|
||||
}
|
||||
return 0;
|
||||
}, window->title);
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#define _SDL_emscriptenvideo_h
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "../../events/SDL_touch_c.h"
|
||||
#include <emscripten/emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
|
||||
|
|
@ -37,14 +38,15 @@ typedef struct SDL_WindowData
|
|||
SDL_Window *window;
|
||||
SDL_Surface *surface;
|
||||
|
||||
int windowed_width;
|
||||
int windowed_height;
|
||||
|
||||
float pixel_ratio;
|
||||
|
||||
SDL_bool external_size;
|
||||
|
||||
int requested_fullscreen_mode;
|
||||
SDL_bool fullscreen_resize;
|
||||
|
||||
SDL_bool finger_touching; /* for mapping touch events to mice */
|
||||
SDL_FingerID first_finger;
|
||||
} SDL_WindowData;
|
||||
|
||||
#endif /* _SDL_emscriptenvideo_h */
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ enum WinCommands {
|
|||
BWIN_RESTORE_WINDOW,
|
||||
BWIN_SET_TITLE,
|
||||
BWIN_SET_BORDERED,
|
||||
BWIN_SET_RESIZABLE,
|
||||
BWIN_FULLSCREEN
|
||||
};
|
||||
|
||||
|
|
@ -336,16 +337,30 @@ class SDL_BWin:public BDirectWindow
|
|||
break;
|
||||
|
||||
case B_KEY_DOWN:
|
||||
{
|
||||
int32 i = 0;
|
||||
int8 byte;
|
||||
int8 bytes[4] = { 0, 0, 0, 0 };
|
||||
while (i < 4 && msg->FindInt8("byte", i, &byte) == B_OK) {
|
||||
bytes[i] = byte;
|
||||
i++;
|
||||
}
|
||||
if (msg->FindInt32("key", &key) == B_OK) {
|
||||
_KeyEvent((SDL_Scancode)key, &bytes[0], i, SDL_PRESSED);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case B_UNMAPPED_KEY_DOWN: /* modifier keys are unmapped */
|
||||
if (msg->FindInt32("key", &key) == B_OK) {
|
||||
_KeyEvent((SDL_Scancode)key, SDL_PRESSED);
|
||||
_KeyEvent((SDL_Scancode)key, NULL, 0, SDL_PRESSED);
|
||||
}
|
||||
break;
|
||||
|
||||
case B_KEY_UP:
|
||||
case B_UNMAPPED_KEY_UP: /* modifier keys are unmapped */
|
||||
if (msg->FindInt32("key", &key) == B_OK) {
|
||||
_KeyEvent(key, SDL_RELEASED);
|
||||
_KeyEvent(key, NULL, 0, SDL_RELEASED);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -378,6 +393,9 @@ class SDL_BWin:public BDirectWindow
|
|||
case BWIN_SET_BORDERED:
|
||||
_SetBordered(message);
|
||||
break;
|
||||
case BWIN_SET_RESIZABLE:
|
||||
_SetResizable(message);
|
||||
break;
|
||||
case BWIN_SHOW_WINDOW:
|
||||
Show();
|
||||
break;
|
||||
|
|
@ -508,13 +526,15 @@ private:
|
|||
_PostWindowEvent(msg);
|
||||
}
|
||||
|
||||
void _KeyEvent(int32 keyCode, int32 keyState) {
|
||||
void _KeyEvent(int32 keyCode, const int8 *keyUtf8, const ssize_t & len, int32 keyState) {
|
||||
/* Create a message to pass along to the BeApp thread */
|
||||
BMessage msg(BAPP_KEY);
|
||||
msg.AddInt32("key-state", keyState);
|
||||
msg.AddInt32("key-scancode", keyCode);
|
||||
if (keyUtf8 != NULL) {
|
||||
msg.AddData("key-utf8", B_INT8_TYPE, (const void*)keyUtf8, len);
|
||||
}
|
||||
be_app->PostMessage(&msg);
|
||||
/* Apparently SDL only uses the scancode */
|
||||
}
|
||||
|
||||
void _RepaintEvent() {
|
||||
|
|
@ -568,6 +588,18 @@ private:
|
|||
SetLook(bEnabled ? B_BORDERED_WINDOW_LOOK : B_NO_BORDER_WINDOW_LOOK);
|
||||
}
|
||||
|
||||
void _SetResizable(BMessage *msg) {
|
||||
bool bEnabled;
|
||||
if(msg->FindBool("window-resizable", &bEnabled) != B_OK) {
|
||||
return;
|
||||
}
|
||||
if (bEnabled) {
|
||||
SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_ZOOMABLE));
|
||||
} else {
|
||||
SetFlags(Flags() | (B_NOT_RESIZABLE | B_NOT_ZOOMABLE));
|
||||
}
|
||||
}
|
||||
|
||||
void _Restore() {
|
||||
if(IsMinimized()) {
|
||||
Minimize(false);
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ BE_CreateDevice(int devindex)
|
|||
device->MinimizeWindow = BE_MinimizeWindow;
|
||||
device->RestoreWindow = BE_RestoreWindow;
|
||||
device->SetWindowBordered = BE_SetWindowBordered;
|
||||
device->SetWindowResizable = BE_SetWindowResizable;
|
||||
device->SetWindowFullscreen = BE_SetWindowFullscreen;
|
||||
device->SetWindowGammaRamp = BE_SetWindowGammaRamp;
|
||||
device->GetWindowGammaRamp = BE_GetWindowGammaRamp;
|
||||
|
|
|
|||
|
|
@ -145,6 +145,12 @@ void BE_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) {
|
|||
_ToBeWin(window)->PostMessage(&msg);
|
||||
}
|
||||
|
||||
void BE_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable) {
|
||||
BMessage msg(BWIN_SET_RESIZABLE);
|
||||
msg.AddBool("window-resizable", resizable != SDL_FALSE);
|
||||
_ToBeWin(window)->PostMessage(&msg);
|
||||
}
|
||||
|
||||
void BE_ShowWindow(_THIS, SDL_Window * window) {
|
||||
BMessage msg(BWIN_SHOW_WINDOW);
|
||||
_ToBeWin(window)->PostMessage(&msg);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ extern void BE_MaximizeWindow(_THIS, SDL_Window * window);
|
|||
extern void BE_MinimizeWindow(_THIS, SDL_Window * window);
|
||||
extern void BE_RestoreWindow(_THIS, SDL_Window * window);
|
||||
extern void BE_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered);
|
||||
extern void BE_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable);
|
||||
extern void BE_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
|
||||
extern int BE_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp);
|
||||
extern int BE_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp);
|
||||
|
|
|
|||
|
|
@ -84,9 +84,8 @@ MIR_GetSym(const char *fnname, int *pHasModule)
|
|||
/* Define all the function pointers and wrappers... */
|
||||
#define SDL_MIR_MODULE(modname) int SDL_MIR_HAVE_##modname = 0;
|
||||
#define SDL_MIR_SYM(rc,fn,params) SDL_DYNMIRFN_##fn MIR_##fn = NULL;
|
||||
#define SDL_MIR_SYM_CONST(type,name) SDL_DYMMIRCONST_##name MIR_##name = NULL;
|
||||
#include "SDL_mirsym.h"
|
||||
#undef SDL_MIR_MODULE
|
||||
#undef SDL_MIR_SYM
|
||||
|
||||
static int mir_load_refcount = 0;
|
||||
|
||||
|
|
@ -103,9 +102,8 @@ SDL_MIR_UnloadSymbols(void)
|
|||
/* set all the function pointers to NULL. */
|
||||
#define SDL_MIR_MODULE(modname) SDL_MIR_HAVE_##modname = 0;
|
||||
#define SDL_MIR_SYM(rc,fn,params) MIR_##fn = NULL;
|
||||
#define SDL_MIR_SYM_CONST(type,name) MIR_##name = NULL;
|
||||
#include "SDL_mirsym.h"
|
||||
#undef SDL_MIR_MODULE
|
||||
#undef SDL_MIR_SYM
|
||||
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_MIR_DYNAMIC
|
||||
|
|
@ -138,16 +136,12 @@ SDL_MIR_LoadSymbols(void)
|
|||
}
|
||||
|
||||
#define SDL_MIR_MODULE(modname) SDL_MIR_HAVE_##modname = 1; /* default yes */
|
||||
#define SDL_MIR_SYM(rc,fn,params)
|
||||
#include "SDL_mirsym.h"
|
||||
#undef SDL_MIR_MODULE
|
||||
#undef SDL_MIR_SYM
|
||||
|
||||
#define SDL_MIR_MODULE(modname) thismod = &SDL_MIR_HAVE_##modname;
|
||||
#define SDL_MIR_SYM(rc,fn,params) MIR_##fn = (SDL_DYNMIRFN_##fn) MIR_GetSym(#fn,thismod);
|
||||
#define SDL_MIR_SYM_CONST(type,name) MIR_##name = *(SDL_DYMMIRCONST_##name*) MIR_GetSym(#name,thismod);
|
||||
#include "SDL_mirsym.h"
|
||||
#undef SDL_MIR_MODULE
|
||||
#undef SDL_MIR_SYM
|
||||
|
||||
if ((SDL_MIR_HAVE_MIR_CLIENT) && (SDL_MIR_HAVE_XKBCOMMON)) {
|
||||
/* all required symbols loaded. */
|
||||
|
|
@ -162,9 +156,8 @@ SDL_MIR_LoadSymbols(void)
|
|||
|
||||
#define SDL_MIR_MODULE(modname) SDL_MIR_HAVE_##modname = 1; /* default yes */
|
||||
#define SDL_MIR_SYM(rc,fn,params) MIR_##fn = fn;
|
||||
#define SDL_MIR_SYM_CONST(type,name) MIR_##name = name;
|
||||
#include "SDL_mirsym.h"
|
||||
#undef SDL_MIR_MODULE
|
||||
#undef SDL_MIR_SYM
|
||||
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,13 +36,13 @@ int SDL_MIR_LoadSymbols(void);
|
|||
void SDL_MIR_UnloadSymbols(void);
|
||||
|
||||
/* Declare all the function pointers and wrappers... */
|
||||
#define SDL_MIR_MODULE(modname)
|
||||
#define SDL_MIR_SYM(rc,fn,params) \
|
||||
typedef rc (*SDL_DYNMIRFN_##fn) params; \
|
||||
extern SDL_DYNMIRFN_##fn MIR_##fn;
|
||||
#define SDL_MIR_SYM_CONST(type, name) \
|
||||
typedef type SDL_DYMMIRCONST_##name; \
|
||||
extern SDL_DYMMIRCONST_##name MIR_##name;
|
||||
#include "SDL_mirsym.h"
|
||||
#undef SDL_MIR_MODULE
|
||||
#undef SDL_MIR_SYM
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,73 +53,79 @@ HandleKeyText(int32_t key_code)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
CheckKeyboardFocus(SDL_Window* sdl_window)
|
||||
{
|
||||
SDL_Window* keyboard_window = SDL_GetKeyboardFocus();
|
||||
|
||||
if (keyboard_window != sdl_window)
|
||||
SDL_SetKeyboardFocus(sdl_window);
|
||||
}
|
||||
|
||||
|
||||
/* FIXME
|
||||
Mir still needs to implement its IM API, for now we assume
|
||||
a single key press produces a character.
|
||||
*/
|
||||
static void
|
||||
HandleKeyEvent(MirKeyEvent const ev, SDL_Window* window)
|
||||
HandleKeyEvent(MirKeyboardEvent const* key_event, SDL_Window* window)
|
||||
{
|
||||
uint32_t scancode = SDL_SCANCODE_UNKNOWN;
|
||||
Uint8 key_state = ev.action == mir_key_action_up ? SDL_RELEASED : SDL_PRESSED;
|
||||
xkb_keysym_t key_code;
|
||||
Uint8 key_state;
|
||||
int event_scancode;
|
||||
uint32_t sdl_scancode = SDL_SCANCODE_UNKNOWN;
|
||||
|
||||
CheckKeyboardFocus(window);
|
||||
MirKeyboardAction action = MIR_mir_keyboard_event_action(key_event);
|
||||
|
||||
if (ev.scan_code < SDL_arraysize(xfree86_scancode_table2))
|
||||
scancode = xfree86_scancode_table2[ev.scan_code];
|
||||
key_state = SDL_PRESSED;
|
||||
key_code = MIR_mir_keyboard_event_key_code(key_event);
|
||||
event_scancode = MIR_mir_keyboard_event_scan_code(key_event);
|
||||
|
||||
if (scancode != SDL_SCANCODE_UNKNOWN)
|
||||
SDL_SendKeyboardKey(key_state, scancode);
|
||||
if (action == mir_keyboard_action_up)
|
||||
key_state = SDL_RELEASED;
|
||||
|
||||
if (event_scancode < SDL_arraysize(xfree86_scancode_table2))
|
||||
sdl_scancode = xfree86_scancode_table2[event_scancode];
|
||||
|
||||
if (sdl_scancode != SDL_SCANCODE_UNKNOWN)
|
||||
SDL_SendKeyboardKey(key_state, sdl_scancode);
|
||||
|
||||
if (key_state == SDL_PRESSED)
|
||||
HandleKeyText(ev.key_code);
|
||||
HandleKeyText(key_code);
|
||||
}
|
||||
|
||||
static void
|
||||
HandleMouseButton(SDL_Window* sdl_window, Uint8 state, MirMotionButton button_state)
|
||||
HandleMouseButton(SDL_Window* sdl_window, Uint8 state, MirPointerEvent const* pointer)
|
||||
{
|
||||
static uint32_t last_sdl_button;
|
||||
uint32_t sdl_button;
|
||||
uint32_t sdl_button = SDL_BUTTON_LEFT;
|
||||
MirPointerButton button_state = mir_pointer_button_primary;
|
||||
|
||||
static uint32_t old_button_states = 0;
|
||||
uint32_t new_button_states = MIR_mir_pointer_event_buttons(pointer);
|
||||
|
||||
// XOR on our old button states vs our new states to get the newley pressed/released button
|
||||
button_state = new_button_states ^ old_button_states;
|
||||
|
||||
switch (button_state) {
|
||||
case mir_motion_button_primary:
|
||||
case mir_pointer_button_primary:
|
||||
sdl_button = SDL_BUTTON_LEFT;
|
||||
break;
|
||||
case mir_motion_button_secondary:
|
||||
case mir_pointer_button_secondary:
|
||||
sdl_button = SDL_BUTTON_RIGHT;
|
||||
break;
|
||||
case mir_motion_button_tertiary:
|
||||
case mir_pointer_button_tertiary:
|
||||
sdl_button = SDL_BUTTON_MIDDLE;
|
||||
break;
|
||||
case mir_motion_button_forward:
|
||||
case mir_pointer_button_forward:
|
||||
sdl_button = SDL_BUTTON_X1;
|
||||
break;
|
||||
case mir_motion_button_back:
|
||||
case mir_pointer_button_back:
|
||||
sdl_button = SDL_BUTTON_X2;
|
||||
break;
|
||||
default:
|
||||
sdl_button = last_sdl_button;
|
||||
break;
|
||||
}
|
||||
|
||||
last_sdl_button = sdl_button;
|
||||
old_button_states = new_button_states;
|
||||
|
||||
SDL_SendMouseButton(sdl_window, 0, state, sdl_button);
|
||||
}
|
||||
|
||||
static void
|
||||
HandleMouseMotion(SDL_Window* sdl_window, int x, int y)
|
||||
{
|
||||
SDL_SendMouseMotion(sdl_window, 0, 0, x, y);
|
||||
SDL_Mouse* mouse = SDL_GetMouse();
|
||||
SDL_SendMouseMotion(sdl_window, 0, mouse->relative_mode, x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -148,71 +154,102 @@ AddTouchDevice(int device_id)
|
|||
}
|
||||
|
||||
static void
|
||||
HandleTouchEvent(MirMotionEvent const motion, int cord_index, SDL_Window* sdl_window)
|
||||
HandleTouchEvent(MirTouchEvent const* touch, int device_id, SDL_Window* sdl_window)
|
||||
{
|
||||
int device_id = motion.device_id;
|
||||
int id = motion.pointer_coordinates[cord_index].id;
|
||||
int i, point_count;
|
||||
point_count = MIR_mir_touch_event_point_count(touch);
|
||||
|
||||
int width = sdl_window->w;
|
||||
int height = sdl_window->h;
|
||||
float x = motion.pointer_coordinates[cord_index].x;
|
||||
float y = motion.pointer_coordinates[cord_index].y;
|
||||
AddTouchDevice(device_id);
|
||||
|
||||
float n_x = x / width;
|
||||
float n_y = y / height;
|
||||
float pressure = motion.pointer_coordinates[cord_index].pressure;
|
||||
for (i = 0; i < point_count; i++) {
|
||||
int id = MIR_mir_touch_event_id(touch, i);
|
||||
|
||||
AddTouchDevice(motion.device_id);
|
||||
int width = sdl_window->w;
|
||||
int height = sdl_window->h;
|
||||
|
||||
switch (motion.action) {
|
||||
case mir_motion_action_down:
|
||||
case mir_motion_action_pointer_down:
|
||||
HandleTouchPress(device_id, id, SDL_TRUE, n_x, n_y, pressure);
|
||||
break;
|
||||
case mir_motion_action_up:
|
||||
case mir_motion_action_pointer_up:
|
||||
HandleTouchPress(device_id, id, SDL_FALSE, n_x, n_y, pressure);
|
||||
break;
|
||||
case mir_motion_action_hover_move:
|
||||
case mir_motion_action_move:
|
||||
HandleTouchMotion(device_id, id, n_x, n_y, pressure);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
float x = MIR_mir_touch_event_axis_value(touch, i, mir_touch_axis_x);
|
||||
float y = MIR_mir_touch_event_axis_value(touch, i, mir_touch_axis_y);
|
||||
|
||||
float n_x = x / width;
|
||||
float n_y = y / height;
|
||||
|
||||
float pressure = MIR_mir_touch_event_axis_value(touch, i, mir_touch_axis_pressure);
|
||||
|
||||
switch (MIR_mir_touch_event_action(touch, i)) {
|
||||
case mir_touch_action_up:
|
||||
HandleTouchPress(device_id, id, SDL_FALSE, n_x, n_y, pressure);
|
||||
break;
|
||||
case mir_touch_action_down:
|
||||
HandleTouchPress(device_id, id, SDL_TRUE, n_x, n_y, pressure);
|
||||
break;
|
||||
case mir_touch_action_change:
|
||||
HandleTouchMotion(device_id, id, n_x, n_y, pressure);
|
||||
break;
|
||||
case mir_touch_actions:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
HandleMouseEvent(MirMotionEvent const motion, int cord_index, SDL_Window* sdl_window)
|
||||
HandleMouseEvent(MirPointerEvent const* pointer, SDL_Window* sdl_window)
|
||||
{
|
||||
SDL_SetMouseFocus(sdl_window);
|
||||
|
||||
switch (motion.action) {
|
||||
case mir_motion_action_down:
|
||||
case mir_motion_action_pointer_down:
|
||||
HandleMouseButton(sdl_window, SDL_PRESSED, motion.button_state);
|
||||
switch (MIR_mir_pointer_event_action(pointer)) {
|
||||
case mir_pointer_action_button_down:
|
||||
HandleMouseButton(sdl_window, SDL_PRESSED, pointer);
|
||||
break;
|
||||
case mir_motion_action_up:
|
||||
case mir_motion_action_pointer_up:
|
||||
HandleMouseButton(sdl_window, SDL_RELEASED, motion.button_state);
|
||||
case mir_pointer_action_button_up:
|
||||
HandleMouseButton(sdl_window, SDL_RELEASED, pointer);
|
||||
break;
|
||||
case mir_motion_action_hover_move:
|
||||
case mir_motion_action_move:
|
||||
HandleMouseMotion(sdl_window,
|
||||
motion.pointer_coordinates[cord_index].x,
|
||||
motion.pointer_coordinates[cord_index].y);
|
||||
case mir_pointer_action_motion: {
|
||||
int x, y;
|
||||
int hscroll, vscroll;
|
||||
SDL_Mouse* mouse = SDL_GetMouse();
|
||||
x = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_x);
|
||||
y = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_y);
|
||||
|
||||
if (mouse) {
|
||||
if (mouse->relative_mode) {
|
||||
int relative_x = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_relative_x);
|
||||
int relative_y = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_relative_y);
|
||||
HandleMouseMotion(sdl_window, relative_x, relative_y);
|
||||
}
|
||||
else if (mouse->x != x || mouse->y != y) {
|
||||
HandleMouseMotion(sdl_window, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
hscroll = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_hscroll);
|
||||
vscroll = MIR_mir_pointer_event_axis_value(pointer, mir_pointer_axis_vscroll);
|
||||
if (vscroll != 0 || hscroll != 0)
|
||||
HandleMouseScroll(sdl_window, hscroll, vscroll);
|
||||
}
|
||||
break;
|
||||
case mir_motion_action_outside:
|
||||
case mir_pointer_action_leave:
|
||||
SDL_SetMouseFocus(NULL);
|
||||
break;
|
||||
case mir_motion_action_scroll:
|
||||
HandleMouseScroll(sdl_window,
|
||||
motion.pointer_coordinates[cord_index].hscroll,
|
||||
motion.pointer_coordinates[cord_index].vscroll);
|
||||
case mir_pointer_action_enter:
|
||||
default:
|
||||
break;
|
||||
case mir_motion_action_cancel:
|
||||
case mir_motion_action_hover_enter:
|
||||
case mir_motion_action_hover_exit:
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
MIR_HandleInput(MirInputEvent const* input_event, SDL_Window* window)
|
||||
{
|
||||
switch (MIR_mir_input_event_get_type(input_event)) {
|
||||
case (mir_input_event_type_key):
|
||||
HandleKeyEvent(MIR_mir_input_event_get_keyboard_event(input_event), window);
|
||||
break;
|
||||
case (mir_input_event_type_pointer):
|
||||
HandleMouseEvent(MIR_mir_input_event_get_pointer_event(input_event), window);
|
||||
break;
|
||||
case (mir_input_event_type_touch):
|
||||
HandleTouchEvent(MIR_mir_input_event_get_touch_event(input_event),
|
||||
MIR_mir_input_event_get_device_id(input_event),
|
||||
window);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -220,32 +257,54 @@ HandleMouseEvent(MirMotionEvent const motion, int cord_index, SDL_Window* sdl_wi
|
|||
}
|
||||
|
||||
static void
|
||||
HandleMotionEvent(MirMotionEvent const motion, SDL_Window* sdl_window)
|
||||
MIR_HandleResize(MirResizeEvent const* resize_event, SDL_Window* window)
|
||||
{
|
||||
int cord_index;
|
||||
for (cord_index = 0; cord_index < motion.pointer_count; cord_index++) {
|
||||
if (motion.pointer_coordinates[cord_index].tool_type == mir_motion_tool_type_finger) {
|
||||
HandleTouchEvent(motion, cord_index, sdl_window);
|
||||
int new_w = MIR_mir_resize_event_get_width (resize_event);
|
||||
int new_h = MIR_mir_resize_event_get_height(resize_event);
|
||||
|
||||
int old_w = window->w;
|
||||
int old_h = window->h;
|
||||
|
||||
if (new_w != old_w || new_h != old_h)
|
||||
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, new_w, new_h);
|
||||
}
|
||||
|
||||
static void
|
||||
MIR_HandleSurface(MirSurfaceEvent const* surface_event, SDL_Window* window)
|
||||
{
|
||||
MirSurfaceAttrib attrib = MIR_mir_surface_event_get_attribute(surface_event);
|
||||
int value = MIR_mir_surface_event_get_attribute_value(surface_event);
|
||||
|
||||
if (attrib == mir_surface_attrib_focus) {
|
||||
if (value == mir_surface_focused) {
|
||||
SDL_SetKeyboardFocus(window);
|
||||
}
|
||||
else {
|
||||
HandleMouseEvent(motion, cord_index, sdl_window);
|
||||
else if (value == mir_surface_unfocused) {
|
||||
SDL_SetKeyboardFocus(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MIR_HandleInput(MirSurface* surface, MirEvent const* ev, void* context)
|
||||
MIR_HandleEvent(MirSurface* surface, MirEvent const* ev, void* context)
|
||||
{
|
||||
SDL_Window* window = (SDL_Window*)context;
|
||||
switch (ev->type) {
|
||||
case (mir_event_type_key):
|
||||
HandleKeyEvent(ev->key, window);
|
||||
break;
|
||||
case (mir_event_type_motion):
|
||||
HandleMotionEvent(ev->motion, window);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
MirEventType event_type = MIR_mir_event_get_type(ev);
|
||||
SDL_Window* window = (SDL_Window*)context;
|
||||
|
||||
if (window) {
|
||||
switch (event_type) {
|
||||
case (mir_event_type_input):
|
||||
MIR_HandleInput(MIR_mir_event_get_input_event(ev), window);
|
||||
break;
|
||||
case (mir_event_type_resize):
|
||||
MIR_HandleResize(MIR_mir_event_get_resize_event(ev), window);
|
||||
break;
|
||||
case (mir_event_type_surface):
|
||||
MIR_HandleSurface(MIR_mir_event_get_surface_event(ev), window);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
#include <mir_toolkit/mir_client_library.h>
|
||||
|
||||
extern void
|
||||
MIR_HandleInput(MirSurface* surface, MirEvent const* ev, void* context);
|
||||
MIR_HandleEvent(MirSurface* surface, MirEvent const* ev, void* context);
|
||||
|
||||
#endif /* _SDL_mirevents_h */
|
||||
|
||||
|
|
|
|||
|
|
@ -33,39 +33,18 @@
|
|||
|
||||
#include "SDL_mirdyn.h"
|
||||
|
||||
static const Uint32 mir_pixel_format_to_sdl_format[] = {
|
||||
SDL_PIXELFORMAT_UNKNOWN, /* mir_pixel_format_invalid */
|
||||
SDL_PIXELFORMAT_ABGR8888, /* mir_pixel_format_abgr_8888 */
|
||||
SDL_PIXELFORMAT_BGR888, /* mir_pixel_format_xbgr_8888 */
|
||||
SDL_PIXELFORMAT_ARGB8888, /* mir_pixel_format_argb_8888 */
|
||||
SDL_PIXELFORMAT_RGB888, /* mir_pixel_format_xrgb_8888 */
|
||||
SDL_PIXELFORMAT_BGR24 /* mir_pixel_format_bgr_888 */
|
||||
};
|
||||
|
||||
Uint32
|
||||
MIR_GetSDLPixelFormat(MirPixelFormat format)
|
||||
{
|
||||
return mir_pixel_format_to_sdl_format[format];
|
||||
}
|
||||
|
||||
int
|
||||
MIR_CreateWindowFramebuffer(_THIS, SDL_Window* window, Uint32* format,
|
||||
void** pixels, int* pitch)
|
||||
{
|
||||
MIR_Data* mir_data = _this->driverdata;
|
||||
MIR_Window* mir_window;
|
||||
MirSurfaceParameters surfaceparm;
|
||||
|
||||
mir_data->software = SDL_TRUE;
|
||||
|
||||
if (MIR_CreateWindow(_this, window) < 0)
|
||||
return SDL_SetError("Failed to created a mir window.");
|
||||
|
||||
mir_window = window->driverdata;
|
||||
|
||||
MIR_mir_surface_get_parameters(mir_window->surface, &surfaceparm);
|
||||
|
||||
*format = MIR_GetSDLPixelFormat(surfaceparm.pixel_format);
|
||||
*format = MIR_GetSDLPixelFormat(mir_data->pixel_format);
|
||||
if (*format == SDL_PIXELFORMAT_UNKNOWN)
|
||||
return SDL_SetError("Unknown pixel format");
|
||||
|
||||
|
|
@ -75,12 +54,6 @@ MIR_CreateWindowFramebuffer(_THIS, SDL_Window* window, Uint32* format,
|
|||
if (*pixels == NULL)
|
||||
return SDL_OutOfMemory();
|
||||
|
||||
mir_window->surface = MIR_mir_connection_create_surface_sync(mir_data->connection, &surfaceparm);
|
||||
if (!MIR_mir_surface_is_valid(mir_window->surface)) {
|
||||
const char* error = MIR_mir_surface_get_error_message(mir_window->surface);
|
||||
return SDL_SetError("Failed to created a mir surface: %s", error);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -91,12 +64,14 @@ MIR_UpdateWindowFramebuffer(_THIS, SDL_Window* window,
|
|||
MIR_Window* mir_window = window->driverdata;
|
||||
|
||||
MirGraphicsRegion region;
|
||||
MirBufferStream* bs;
|
||||
int i, j, x, y, w, h, start;
|
||||
int bytes_per_pixel, bytes_per_row, s_stride, d_stride;
|
||||
char* s_dest;
|
||||
char* pixels;
|
||||
|
||||
MIR_mir_surface_get_graphics_region(mir_window->surface, ®ion);
|
||||
bs = MIR_mir_surface_get_buffer_stream(mir_window->surface);
|
||||
MIR_mir_buffer_stream_get_graphics_region(bs, ®ion);
|
||||
|
||||
s_dest = region.vaddr;
|
||||
pixels = (char*)window->surface->pixels;
|
||||
|
|
@ -138,13 +113,13 @@ MIR_UpdateWindowFramebuffer(_THIS, SDL_Window* window,
|
|||
|
||||
bytes_per_row = bytes_per_pixel * w;
|
||||
for (j = 0; j < h; j++) {
|
||||
memcpy(s_dest, pixels, bytes_per_row);
|
||||
SDL_memcpy(s_dest, pixels, bytes_per_row);
|
||||
pixels += s_stride;
|
||||
s_dest += d_stride;
|
||||
}
|
||||
}
|
||||
|
||||
MIR_mir_surface_swap_buffers_sync(mir_window->surface);
|
||||
MIR_mir_buffer_stream_swap_buffers_sync(bs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,13 +27,22 @@
|
|||
|
||||
#if SDL_VIDEO_DRIVER_MIR
|
||||
|
||||
#include "SDL_mirmouse.h"
|
||||
|
||||
#include "../../events/SDL_mouse_c.h"
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "SDL_assert.h"
|
||||
|
||||
#include "SDL_mirdyn.h"
|
||||
|
||||
#include "SDL_mirvideo.h"
|
||||
#include "SDL_mirmouse.h"
|
||||
#include "SDL_mirwindow.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MirCursorConfiguration* conf;
|
||||
MirBufferStream* stream;
|
||||
} MIR_Cursor;
|
||||
|
||||
static SDL_Cursor*
|
||||
MIR_CreateDefaultCursor()
|
||||
{
|
||||
|
|
@ -41,6 +50,18 @@ MIR_CreateDefaultCursor()
|
|||
|
||||
cursor = SDL_calloc(1, sizeof(SDL_Cursor));
|
||||
if (cursor) {
|
||||
|
||||
MIR_Cursor* mir_cursor = SDL_calloc(1, sizeof(MIR_Cursor));
|
||||
if (mir_cursor) {
|
||||
mir_cursor->conf = NULL;
|
||||
mir_cursor->stream = NULL;
|
||||
cursor->driverdata = mir_cursor;
|
||||
}
|
||||
else {
|
||||
SDL_OutOfMemory();
|
||||
SDL_free(cursor);
|
||||
cursor = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
SDL_OutOfMemory();
|
||||
|
|
@ -49,58 +70,168 @@ MIR_CreateDefaultCursor()
|
|||
return cursor;
|
||||
}
|
||||
|
||||
static SDL_Cursor*
|
||||
MIR_CreateCursor(SDL_Surface* sruface, int hot_x, int hot_y)
|
||||
static void
|
||||
CopySurfacePixelsToMirStream(SDL_Surface* surface, MirBufferStream* stream)
|
||||
{
|
||||
return MIR_CreateDefaultCursor();
|
||||
char* dest, *pixels;
|
||||
int i, s_w, s_h, r_stride, p_stride, bytes_per_pixel, bytes_per_row;
|
||||
|
||||
MirGraphicsRegion region;
|
||||
MIR_mir_buffer_stream_get_graphics_region(stream, ®ion);
|
||||
|
||||
s_w = surface->w;
|
||||
s_h = surface->h;
|
||||
|
||||
bytes_per_pixel = surface->format->BytesPerPixel;
|
||||
bytes_per_row = bytes_per_pixel * s_w;
|
||||
|
||||
dest = region.vaddr;
|
||||
pixels = (char*)surface->pixels;
|
||||
|
||||
r_stride = region.stride;
|
||||
p_stride = surface->pitch;
|
||||
|
||||
for (i = 0; i < s_h; i++)
|
||||
{
|
||||
SDL_memcpy(dest, pixels, bytes_per_row);
|
||||
dest += r_stride;
|
||||
pixels += p_stride;
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_Cursor*
|
||||
MIR_CreateCursor(SDL_Surface* surface, int hot_x, int hot_y)
|
||||
{
|
||||
MirCursorConfiguration* conf;
|
||||
MirBufferStream* stream;
|
||||
|
||||
int s_w = surface->w;
|
||||
int s_h = surface->h;
|
||||
|
||||
MIR_Data* mir_data = (MIR_Data*)SDL_GetVideoDevice()->driverdata;
|
||||
SDL_Cursor* cursor = MIR_CreateDefaultCursor();
|
||||
MIR_Cursor* mir_cursor;
|
||||
|
||||
if (!cursor) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mir_cursor = (MIR_Cursor*)cursor->driverdata;
|
||||
|
||||
stream = MIR_mir_connection_create_buffer_stream_sync(mir_data->connection,
|
||||
s_w, s_h, mir_data->pixel_format,
|
||||
mir_buffer_usage_software);
|
||||
|
||||
conf = MIR_mir_cursor_configuration_from_buffer_stream(stream, hot_x, hot_y);
|
||||
|
||||
CopySurfacePixelsToMirStream(surface, stream);
|
||||
MIR_mir_buffer_stream_swap_buffers_sync(stream);
|
||||
|
||||
mir_cursor->conf = conf;
|
||||
mir_cursor->stream = stream;
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
static SDL_Cursor*
|
||||
MIR_CreateSystemCursor(SDL_SystemCursor id)
|
||||
{
|
||||
char const* cursor_name = NULL;
|
||||
SDL_Cursor* cursor = MIR_CreateDefaultCursor();
|
||||
MIR_Cursor* mir_cursor = (MIR_Cursor*)cursor->driverdata;
|
||||
|
||||
if (!cursor) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch(id) {
|
||||
case SDL_SYSTEM_CURSOR_ARROW:
|
||||
cursor_name = MIR_mir_arrow_cursor_name;
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_IBEAM:
|
||||
cursor_name = MIR_mir_caret_cursor_name;
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_WAIT:
|
||||
cursor_name = MIR_mir_busy_cursor_name;
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_CROSSHAIR:
|
||||
/* Unsupported */
|
||||
cursor_name = MIR_mir_arrow_cursor_name;
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_WAITARROW:
|
||||
cursor_name = MIR_mir_busy_cursor_name;
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_SIZENWSE:
|
||||
cursor_name = MIR_mir_omnidirectional_resize_cursor_name;
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_SIZENESW:
|
||||
cursor_name = MIR_mir_omnidirectional_resize_cursor_name;
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_SIZEWE:
|
||||
cursor_name = MIR_mir_horizontal_resize_cursor_name;
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_SIZENS:
|
||||
cursor_name = MIR_mir_vertical_resize_cursor_name;
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_SIZEALL:
|
||||
cursor_name = MIR_mir_omnidirectional_resize_cursor_name;
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_NO:
|
||||
/* Unsupported */
|
||||
cursor_name = MIR_mir_closed_hand_cursor_name;
|
||||
break;
|
||||
case SDL_SYSTEM_CURSOR_HAND:
|
||||
cursor_name = MIR_mir_open_hand_cursor_name;
|
||||
break;
|
||||
default:
|
||||
SDL_assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return MIR_CreateDefaultCursor();
|
||||
mir_cursor->conf = MIR_mir_cursor_configuration_from_name(cursor_name);
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
static void
|
||||
MIR_FreeCursor(SDL_Cursor* cursor)
|
||||
{
|
||||
if (cursor)
|
||||
SDL_free(cursor);
|
||||
if (cursor) {
|
||||
|
||||
if (cursor->driverdata) {
|
||||
MIR_Cursor* mir_cursor = (MIR_Cursor*)cursor->driverdata;
|
||||
|
||||
if (mir_cursor->conf)
|
||||
MIR_mir_cursor_configuration_destroy(mir_cursor->conf);
|
||||
if (mir_cursor->stream)
|
||||
MIR_mir_buffer_stream_release_sync(mir_cursor->stream);
|
||||
|
||||
SDL_free(mir_cursor);
|
||||
}
|
||||
|
||||
SDL_free(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
MIR_ShowCursor(SDL_Cursor* cursor)
|
||||
{
|
||||
MIR_Data* mir_data = (MIR_Data*)SDL_GetVideoDevice()->driverdata;
|
||||
MIR_Window* mir_window = mir_data->current_window;
|
||||
|
||||
if (cursor && cursor->driverdata) {
|
||||
if (mir_window && MIR_mir_surface_is_valid(mir_window->surface)) {
|
||||
MIR_Cursor* mir_cursor = (MIR_Cursor*)cursor->driverdata;
|
||||
|
||||
if (mir_cursor->conf) {
|
||||
MIR_mir_surface_configure_cursor(mir_window->surface, mir_cursor->conf);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(mir_window && MIR_mir_surface_is_valid(mir_window->surface)) {
|
||||
MIR_mir_surface_configure_cursor(mir_window->surface, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -119,7 +250,7 @@ MIR_WarpMouseGlobal(int x, int y)
|
|||
static int
|
||||
MIR_SetRelativeMouseMode(SDL_bool enabled)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TODO Actually implement the cursor, need to wait for mir support */
|
||||
|
|
|
|||
|
|
@ -21,29 +21,122 @@
|
|||
|
||||
/* *INDENT-OFF* */
|
||||
|
||||
#ifndef SDL_MIR_MODULE
|
||||
#define SDL_MIR_MODULE(modname)
|
||||
#endif
|
||||
|
||||
#ifndef SDL_MIR_SYM
|
||||
#define SDL_MIR_SYM(rc,fn,params)
|
||||
#endif
|
||||
|
||||
#ifndef SDL_MIR_SYM_CONST
|
||||
#define SDL_MIR_SYM_CONST(type, name)
|
||||
#endif
|
||||
|
||||
SDL_MIR_MODULE(MIR_CLIENT)
|
||||
SDL_MIR_SYM(MirDisplayConfiguration*,mir_connection_create_display_config,(MirConnection *connection))
|
||||
SDL_MIR_SYM(MirSurface *,mir_connection_create_surface_sync,(MirConnection *connection, MirSurfaceParameters const *params))
|
||||
SDL_MIR_SYM(MirSurface *,mir_surface_create_sync,(MirSurfaceSpec* spec))
|
||||
SDL_MIR_SYM(MirEGLNativeWindowType,mir_buffer_stream_get_egl_native_window,(MirBufferStream *surface))
|
||||
SDL_MIR_SYM(void,mir_buffer_stream_get_graphics_region,(MirBufferStream *stream, MirGraphicsRegion *graphics_region))
|
||||
SDL_MIR_SYM(void,mir_buffer_stream_swap_buffers_sync,(MirBufferStream *stream))
|
||||
SDL_MIR_SYM(void,mir_surface_set_event_handler,(MirSurface *surface, mir_surface_event_callback callback, void* context))
|
||||
SDL_MIR_SYM(MirSurfaceSpec*,mir_connection_create_spec_for_normal_surface,(MirConnection *connection, int width, int height, MirPixelFormat format))
|
||||
SDL_MIR_SYM(MirSurfaceSpec*,mir_connection_create_spec_for_changes,(MirConnection *connection))
|
||||
SDL_MIR_SYM(void,mir_surface_spec_set_buffer_usage,(MirSurfaceSpec *spec, MirBufferUsage usage))
|
||||
SDL_MIR_SYM(void,mir_surface_spec_set_name,(MirSurfaceSpec *spec, char const *name))
|
||||
SDL_MIR_SYM(void,mir_surface_spec_release,(MirSurfaceSpec *spec))
|
||||
SDL_MIR_SYM(void,mir_surface_spec_set_width,(MirSurfaceSpec *spec, unsigned width))
|
||||
SDL_MIR_SYM(void,mir_surface_spec_set_height,(MirSurfaceSpec *spec, unsigned height))
|
||||
SDL_MIR_SYM(void,mir_surface_spec_set_min_width,(MirSurfaceSpec *spec, unsigned min_width))
|
||||
SDL_MIR_SYM(void,mir_surface_spec_set_min_height,(MirSurfaceSpec *spec, unsigned min_height))
|
||||
SDL_MIR_SYM(void,mir_surface_spec_set_max_width,(MirSurfaceSpec *spec, unsigned max_width))
|
||||
SDL_MIR_SYM(void,mir_surface_spec_set_max_height,(MirSurfaceSpec *spec, unsigned max_height))
|
||||
SDL_MIR_SYM(void,mir_surface_spec_set_type,(MirSurfaceSpec *spec, MirSurfaceType type))
|
||||
SDL_MIR_SYM(void,mir_surface_spec_set_state,(MirSurfaceSpec *spec, MirSurfaceState state))
|
||||
SDL_MIR_SYM(void,mir_surface_spec_set_pointer_confinement,(MirSurfaceSpec *spec, MirPointerConfinementState state))
|
||||
SDL_MIR_SYM(void,mir_surface_apply_spec,(MirSurface *surface, MirSurfaceSpec *spec))
|
||||
SDL_MIR_SYM(void,mir_surface_get_parameters,(MirSurface *surface, MirSurfaceParameters *params))
|
||||
SDL_MIR_SYM(MirBufferStream*,mir_surface_get_buffer_stream,(MirSurface *surface))
|
||||
SDL_MIR_SYM(MirCursorConfiguration*,mir_cursor_configuration_from_buffer_stream,(MirBufferStream const* stream, int hot_x, int hot_y))
|
||||
SDL_MIR_SYM(MirBufferStream*,mir_connection_create_buffer_stream_sync,(MirConnection *connection, int w, int h, MirPixelFormat format, MirBufferUsage usage))
|
||||
SDL_MIR_SYM(MirKeyboardAction,mir_keyboard_event_action,(MirKeyboardEvent const *event))
|
||||
SDL_MIR_SYM(xkb_keysym_t,mir_keyboard_event_key_code,(MirKeyboardEvent const *event))
|
||||
SDL_MIR_SYM(int,mir_keyboard_event_scan_code,(MirKeyboardEvent const *event))
|
||||
SDL_MIR_SYM(bool,mir_pointer_event_button_state,(MirPointerEvent const *event, MirPointerButton button))
|
||||
SDL_MIR_SYM(MirPointerButtons,mir_pointer_event_buttons,(MirPointerEvent const *event))
|
||||
SDL_MIR_SYM(MirInputDeviceId,mir_input_event_get_device_id,(MirInputEvent const* ev))
|
||||
SDL_MIR_SYM(MirTouchId,mir_touch_event_id,(MirTouchEvent const *event, size_t touch_index))
|
||||
SDL_MIR_SYM(float,mir_touch_event_axis_value,(MirTouchEvent const *event, size_t touch_index, MirTouchAxis axis))
|
||||
SDL_MIR_SYM(MirTouchAction,mir_touch_event_action,(MirTouchEvent const *event, size_t touch_index))
|
||||
SDL_MIR_SYM(MirPointerAction,mir_pointer_event_action,(MirPointerEvent const *event))
|
||||
SDL_MIR_SYM(float,mir_pointer_event_axis_value,(MirPointerEvent const *event, MirPointerAxis))
|
||||
SDL_MIR_SYM(MirEventType,mir_event_get_type,(MirEvent const *event))
|
||||
SDL_MIR_SYM(MirInputEventType,mir_input_event_get_type,(MirInputEvent const *event))
|
||||
SDL_MIR_SYM(MirInputEvent const*,mir_event_get_input_event,(MirEvent const *event))
|
||||
SDL_MIR_SYM(MirResizeEvent const*,mir_event_get_resize_event,(MirEvent const *event))
|
||||
SDL_MIR_SYM(MirKeyboardEvent const*,mir_input_event_get_keyboard_event,(MirInputEvent const *event))
|
||||
SDL_MIR_SYM(MirPointerEvent const*,mir_input_event_get_pointer_event,(MirInputEvent const *event))
|
||||
SDL_MIR_SYM(MirTouchEvent const*,mir_input_event_get_touch_event,(MirInputEvent const *event))
|
||||
SDL_MIR_SYM(MirSurfaceEvent const*,mir_event_get_surface_event,(MirEvent const *event))
|
||||
SDL_MIR_SYM(unsigned int,mir_touch_event_point_count,(MirTouchEvent const *event))
|
||||
SDL_MIR_SYM(void,mir_connection_get_available_surface_formats,(MirConnection* connection, MirPixelFormat* formats, unsigned const int format_size, unsigned int *num_valid_formats))
|
||||
SDL_MIR_SYM(MirEGLNativeDisplayType,mir_connection_get_egl_native_display,(MirConnection *connection))
|
||||
SDL_MIR_SYM(MirBool,mir_connection_is_valid,(MirConnection *connection))
|
||||
SDL_MIR_SYM(bool,mir_connection_is_valid,(MirConnection *connection))
|
||||
SDL_MIR_SYM(void,mir_connection_release,(MirConnection *connection))
|
||||
SDL_MIR_SYM(MirPixelFormat,mir_connection_get_egl_pixel_format,(MirConnection* connection, void* egldisplay, void* eglconfig))
|
||||
SDL_MIR_SYM(MirConnection *,mir_connect_sync,(char const *server, char const *app_name))
|
||||
SDL_MIR_SYM(void,mir_display_config_destroy,(MirDisplayConfiguration* display_configuration))
|
||||
SDL_MIR_SYM(MirEGLNativeWindowType,mir_surface_get_egl_native_window,(MirSurface *surface))
|
||||
SDL_MIR_SYM(char const *,mir_surface_get_error_message,(MirSurface *surface))
|
||||
SDL_MIR_SYM(void,mir_surface_get_graphics_region,(MirSurface *surface, MirGraphicsRegion *graphics_region))
|
||||
SDL_MIR_SYM(void,mir_surface_get_parameters,(MirSurface *surface, MirSurfaceParameters *parameters))
|
||||
SDL_MIR_SYM(MirBool,mir_surface_is_valid,(MirSurface *surface))
|
||||
SDL_MIR_SYM(bool,mir_surface_is_valid,(MirSurface *surface))
|
||||
SDL_MIR_SYM(void,mir_surface_release_sync,(MirSurface *surface))
|
||||
SDL_MIR_SYM(void,mir_surface_set_event_handler,(MirSurface *surface, MirEventDelegate const *event_handler))
|
||||
SDL_MIR_SYM(MirWaitHandle*,mir_surface_set_type,(MirSurface *surface, MirSurfaceType type))
|
||||
SDL_MIR_SYM(MirWaitHandle*,mir_surface_set_state,(MirSurface *surface, MirSurfaceState state))
|
||||
SDL_MIR_SYM(void,mir_surface_swap_buffers_sync,(MirSurface *surface))
|
||||
SDL_MIR_SYM(void,mir_buffer_stream_release_sync,(MirBufferStream *stream))
|
||||
SDL_MIR_SYM(MirCursorConfiguration*,mir_cursor_configuration_from_name,(char const* cursor_name))
|
||||
SDL_MIR_SYM(MirWaitHandle*,mir_surface_configure_cursor,(MirSurface* surface, MirCursorConfiguration const* conf))
|
||||
SDL_MIR_SYM(void,mir_cursor_configuration_destroy,(MirCursorConfiguration* conf))
|
||||
SDL_MIR_SYM(int,mir_resize_event_get_width,(MirResizeEvent const* resize_event))
|
||||
SDL_MIR_SYM(int,mir_resize_event_get_height,(MirResizeEvent const* resize_event))
|
||||
SDL_MIR_SYM(char const*,mir_connection_get_error_message,(MirConnection* connection))
|
||||
SDL_MIR_SYM(MirSurfaceAttrib,mir_surface_event_get_attribute,(MirSurfaceEvent const* surface_event))
|
||||
SDL_MIR_SYM(int,mir_surface_event_get_attribute_value,(MirSurfaceEvent const* surface_event))
|
||||
SDL_MIR_SYM(void,mir_wait_for,(MirWaitHandle* handle))
|
||||
SDL_MIR_SYM(MirDisplayConfig*,mir_connection_create_display_configuration,(MirConnection* connection))
|
||||
SDL_MIR_SYM(void,mir_display_config_release,(MirDisplayConfig* config))
|
||||
SDL_MIR_SYM(int,mir_display_config_get_num_outputs,(MirDisplayConfig const* config))
|
||||
SDL_MIR_SYM(MirOutput*,mir_display_config_get_mutable_output,(MirDisplayConfig* config, size_t index))
|
||||
SDL_MIR_SYM(int,mir_output_get_num_modes,(MirOutput const* output))
|
||||
SDL_MIR_SYM(MirPixelFormat,mir_output_get_current_pixel_format,(MirOutput const* output))
|
||||
SDL_MIR_SYM(int,mir_output_get_position_x,(MirOutput const* output))
|
||||
SDL_MIR_SYM(int,mir_output_get_position_y,(MirOutput const* output))
|
||||
SDL_MIR_SYM(bool,mir_output_is_enabled,(MirOutput const* output))
|
||||
SDL_MIR_SYM(MirOutputConnectionState,mir_output_get_connection_state,(MirOutput const* output))
|
||||
SDL_MIR_SYM(size_t,mir_output_get_preferred_mode_index,(MirOutput const* output))
|
||||
SDL_MIR_SYM(MirOutputType,mir_output_get_type,(MirOutput const* output))
|
||||
SDL_MIR_SYM(char const*,mir_output_type_name,(MirOutputType type))
|
||||
SDL_MIR_SYM(void,mir_output_set_current_mode,(MirOutput* output, MirOutputMode const* mode))
|
||||
SDL_MIR_SYM(MirOutputMode const*,mir_output_get_mode,(MirOutput const* output, size_t index))
|
||||
SDL_MIR_SYM(int,mir_output_mode_get_width,(MirOutputMode const* mode))
|
||||
SDL_MIR_SYM(int,mir_output_mode_get_height,(MirOutputMode const* mode))
|
||||
SDL_MIR_SYM(double,mir_output_mode_get_refresh_rate,(MirOutputMode const* mode))
|
||||
SDL_MIR_SYM(MirOutputGammaSupported,mir_output_is_gamma_supported,(MirOutput const* output))
|
||||
SDL_MIR_SYM(uint32_t,mir_output_get_gamma_size,(MirOutput const* output))
|
||||
SDL_MIR_SYM(void,mir_output_get_gamma,(MirOutput const* output, uint16_t* red, uint16_t* green, uint16_t* blue, uint32_t size))
|
||||
SDL_MIR_SYM(void,mir_output_set_gamma,(MirOutput* output, uint16_t const* red, uint16_t const* green, uint16_t const* blue, uint32_t size))
|
||||
|
||||
SDL_MIR_SYM_CONST(char const*,mir_omnidirectional_resize_cursor_name)
|
||||
SDL_MIR_SYM_CONST(char const*,mir_busy_cursor_name)
|
||||
SDL_MIR_SYM_CONST(char const*,mir_arrow_cursor_name)
|
||||
SDL_MIR_SYM_CONST(char const*,mir_caret_cursor_name)
|
||||
SDL_MIR_SYM_CONST(char const*,mir_vertical_resize_cursor_name)
|
||||
SDL_MIR_SYM_CONST(char const*,mir_horizontal_resize_cursor_name)
|
||||
SDL_MIR_SYM_CONST(char const*,mir_open_hand_cursor_name)
|
||||
SDL_MIR_SYM_CONST(char const*,mir_closed_hand_cursor_name)
|
||||
SDL_MIR_SYM_CONST(char const*,mir_disabled_cursor_name)
|
||||
|
||||
SDL_MIR_MODULE(XKBCOMMON)
|
||||
SDL_MIR_SYM(int,xkb_keysym_to_utf8,(xkb_keysym_t keysym, char *buffer, size_t size))
|
||||
|
||||
#undef SDL_MIR_MODULE
|
||||
#undef SDL_MIR_SYM
|
||||
#undef SDL_MIR_SYM_CONST
|
||||
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
|||
|
|
@ -27,18 +27,37 @@
|
|||
|
||||
#if SDL_VIDEO_DRIVER_MIR
|
||||
|
||||
#include "SDL_mirwindow.h"
|
||||
#include "SDL_video.h"
|
||||
|
||||
#include "SDL_mirframebuffer.h"
|
||||
#include "SDL_mirmouse.h"
|
||||
#include "SDL_miropengl.h"
|
||||
#include "SDL_mirvideo.h"
|
||||
#include "SDL_mirwindow.h"
|
||||
|
||||
#include "SDL_mirdyn.h"
|
||||
|
||||
#define MIR_DRIVER_NAME "mir"
|
||||
|
||||
static const Uint32 mir_pixel_format_to_sdl_format[] = {
|
||||
SDL_PIXELFORMAT_UNKNOWN, /* mir_pixel_format_invalid */
|
||||
SDL_PIXELFORMAT_ABGR8888, /* mir_pixel_format_abgr_8888 */
|
||||
SDL_PIXELFORMAT_BGR888, /* mir_pixel_format_xbgr_8888 */
|
||||
SDL_PIXELFORMAT_ARGB8888, /* mir_pixel_format_argb_8888 */
|
||||
SDL_PIXELFORMAT_RGB888, /* mir_pixel_format_xrgb_8888 */
|
||||
SDL_PIXELFORMAT_BGR24, /* mir_pixel_format_bgr_888 */
|
||||
SDL_PIXELFORMAT_RGB24, /* mir_pixel_format_rgb_888 */
|
||||
SDL_PIXELFORMAT_RGB565, /* mir_pixel_format_rgb_565 */
|
||||
SDL_PIXELFORMAT_RGBA5551, /* mir_pixel_format_rgba_5551 */
|
||||
SDL_PIXELFORMAT_RGBA4444 /* mir_pixel_format_rgba_4444 */
|
||||
};
|
||||
|
||||
Uint32
|
||||
MIR_GetSDLPixelFormat(MirPixelFormat format)
|
||||
{
|
||||
return mir_pixel_format_to_sdl_format[format];
|
||||
}
|
||||
|
||||
static int
|
||||
MIR_VideoInit(_THIS);
|
||||
|
||||
|
|
@ -94,7 +113,7 @@ MIR_DeleteDevice(SDL_VideoDevice* device)
|
|||
SDL_MIR_UnloadSymbols();
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
MIR_PumpEvents(_THIS)
|
||||
{
|
||||
}
|
||||
|
|
@ -146,29 +165,30 @@ MIR_CreateDevice(int device_index)
|
|||
device->GL_GetProcAddress = MIR_GL_GetProcAddress;
|
||||
|
||||
/* mirwindow */
|
||||
device->CreateWindow = MIR_CreateWindow;
|
||||
device->DestroyWindow = MIR_DestroyWindow;
|
||||
device->GetWindowWMInfo = MIR_GetWindowWMInfo;
|
||||
device->SetWindowFullscreen = MIR_SetWindowFullscreen;
|
||||
device->MaximizeWindow = MIR_MaximizeWindow;
|
||||
device->MinimizeWindow = MIR_MinimizeWindow;
|
||||
device->RestoreWindow = MIR_RestoreWindow;
|
||||
device->CreateWindow = MIR_CreateWindow;
|
||||
device->DestroyWindow = MIR_DestroyWindow;
|
||||
device->GetWindowWMInfo = MIR_GetWindowWMInfo;
|
||||
device->SetWindowFullscreen = MIR_SetWindowFullscreen;
|
||||
device->MaximizeWindow = MIR_MaximizeWindow;
|
||||
device->MinimizeWindow = MIR_MinimizeWindow;
|
||||
device->RestoreWindow = MIR_RestoreWindow;
|
||||
device->ShowWindow = MIR_RestoreWindow;
|
||||
device->HideWindow = MIR_HideWindow;
|
||||
device->SetWindowSize = MIR_SetWindowSize;
|
||||
device->SetWindowMinimumSize = MIR_SetWindowMinimumSize;
|
||||
device->SetWindowMaximumSize = MIR_SetWindowMaximumSize;
|
||||
device->SetWindowTitle = MIR_SetWindowTitle;
|
||||
device->SetWindowGrab = MIR_SetWindowGrab;
|
||||
device->SetWindowGammaRamp = MIR_SetWindowGammaRamp;
|
||||
device->GetWindowGammaRamp = MIR_GetWindowGammaRamp;
|
||||
|
||||
device->CreateWindowFrom = NULL;
|
||||
device->SetWindowTitle = NULL;
|
||||
device->SetWindowIcon = NULL;
|
||||
device->SetWindowPosition = NULL;
|
||||
device->SetWindowSize = NULL;
|
||||
device->SetWindowMinimumSize = NULL;
|
||||
device->SetWindowMaximumSize = NULL;
|
||||
device->ShowWindow = NULL;
|
||||
device->HideWindow = NULL;
|
||||
device->RaiseWindow = NULL;
|
||||
device->SetWindowBordered = NULL;
|
||||
device->SetWindowGammaRamp = NULL;
|
||||
device->GetWindowGammaRamp = NULL;
|
||||
device->SetWindowGrab = NULL;
|
||||
device->SetWindowResizable = NULL;
|
||||
device->OnWindowEnter = NULL;
|
||||
device->SetWindowPosition = NULL;
|
||||
|
||||
/* mirframebuffer */
|
||||
device->CreateWindowFramebuffer = MIR_CreateWindowFramebuffer;
|
||||
|
|
@ -206,77 +226,88 @@ VideoBootStrap MIR_bootstrap = {
|
|||
MIR_Available, MIR_CreateDevice
|
||||
};
|
||||
|
||||
static void
|
||||
MIR_SetCurrentDisplayMode(MirDisplayOutput const* out, SDL_VideoDisplay* display)
|
||||
static SDL_DisplayMode
|
||||
MIR_ConvertModeToSDLMode(MirOutputMode const* mode, MirPixelFormat format)
|
||||
{
|
||||
SDL_DisplayMode mode = {
|
||||
.format = SDL_PIXELFORMAT_RGB888,
|
||||
.w = out->modes[out->current_mode].horizontal_resolution,
|
||||
.h = out->modes[out->current_mode].vertical_resolution,
|
||||
.refresh_rate = out->modes[out->current_mode].refresh_rate,
|
||||
.driverdata = NULL
|
||||
SDL_DisplayMode sdl_mode = {
|
||||
.format = MIR_GetSDLPixelFormat(format),
|
||||
.w = MIR_mir_output_mode_get_width(mode),
|
||||
.h = MIR_mir_output_mode_get_height(mode),
|
||||
.refresh_rate = MIR_mir_output_mode_get_refresh_rate(mode),
|
||||
.driverdata = NULL
|
||||
};
|
||||
|
||||
display->desktop_mode = mode;
|
||||
display->current_mode = mode;
|
||||
return sdl_mode;
|
||||
}
|
||||
|
||||
static void
|
||||
MIR_AddAllModesFromDisplay(MirDisplayOutput const* out, SDL_VideoDisplay* display)
|
||||
MIR_AddModeToDisplay(SDL_VideoDisplay* display, MirOutputMode const* mode, MirPixelFormat format)
|
||||
{
|
||||
int n_mode;
|
||||
for (n_mode = 0; n_mode < out->num_modes; ++n_mode) {
|
||||
SDL_DisplayMode mode = {
|
||||
.format = SDL_PIXELFORMAT_RGB888,
|
||||
.w = out->modes[n_mode].horizontal_resolution,
|
||||
.h = out->modes[n_mode].vertical_resolution,
|
||||
.refresh_rate = out->modes[n_mode].refresh_rate,
|
||||
.driverdata = NULL
|
||||
};
|
||||
SDL_DisplayMode sdl_mode = MIR_ConvertModeToSDLMode(mode, format);
|
||||
SDL_AddDisplayMode(display, &sdl_mode);
|
||||
}
|
||||
|
||||
SDL_AddDisplayMode(display, &mode);
|
||||
static void
|
||||
MIR_InitDisplayFromOutput(_THIS, MirOutput* output)
|
||||
{
|
||||
SDL_VideoDisplay display;
|
||||
int m;
|
||||
|
||||
MirPixelFormat format = MIR_mir_output_get_current_pixel_format(output);
|
||||
int num_modes = MIR_mir_output_get_num_modes(output);
|
||||
SDL_DisplayMode current_mode = MIR_ConvertModeToSDLMode(mir_output_get_current_mode(output), format);
|
||||
|
||||
SDL_zero(display);
|
||||
|
||||
// Unfortunate cast, but SDL_AddVideoDisplay will strdup this pointer so its read-only in this case.
|
||||
display.name = (char*)MIR_mir_output_type_name(MIR_mir_output_get_type(output));
|
||||
|
||||
for (m = 0; m < num_modes; m++) {
|
||||
MirOutputMode const* mode = MIR_mir_output_get_mode(output, m);
|
||||
MIR_AddModeToDisplay(&display, mode, format);
|
||||
}
|
||||
|
||||
display.desktop_mode = current_mode;
|
||||
display.current_mode = current_mode;
|
||||
|
||||
display.driverdata = output;
|
||||
SDL_AddVideoDisplay(&display);
|
||||
}
|
||||
|
||||
static void
|
||||
MIR_InitDisplays(_THIS)
|
||||
{
|
||||
MIR_Data* mir_data = _this->driverdata;
|
||||
int num_outputs = MIR_mir_display_config_get_num_outputs(mir_data->display_config);
|
||||
int d;
|
||||
|
||||
MirDisplayConfiguration* display_config = MIR_mir_connection_create_display_config(mir_data->connection);
|
||||
for (d = 0; d < num_outputs; d++) {
|
||||
MirOutput* output = MIR_mir_display_config_get_mutable_output(mir_data->display_config, d);
|
||||
SDL_bool enabled = MIR_mir_output_is_enabled(output);
|
||||
MirOutputConnectionState state = MIR_mir_output_get_connection_state(output);
|
||||
|
||||
for (d = 0; d < display_config->num_outputs; d++) {
|
||||
MirDisplayOutput const* out = display_config->outputs + d;
|
||||
|
||||
SDL_VideoDisplay display;
|
||||
SDL_zero(display);
|
||||
|
||||
if (out->used &&
|
||||
out->connected &&
|
||||
out->num_modes &&
|
||||
out->current_mode < out->num_modes) {
|
||||
|
||||
MIR_SetCurrentDisplayMode(out, &display);
|
||||
MIR_AddAllModesFromDisplay(out, &display);
|
||||
|
||||
SDL_AddVideoDisplay(&display);
|
||||
if (enabled && state == mir_output_connection_state_connected) {
|
||||
MIR_InitDisplayFromOutput(_this, output);
|
||||
}
|
||||
}
|
||||
|
||||
MIR_mir_display_config_destroy(display_config);
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
MIR_VideoInit(_THIS)
|
||||
{
|
||||
MIR_Data* mir_data = _this->driverdata;
|
||||
|
||||
mir_data->connection = MIR_mir_connect_sync(NULL, __PRETTY_FUNCTION__);
|
||||
mir_data->software = SDL_FALSE;
|
||||
mir_data->connection = MIR_mir_connect_sync(NULL, __PRETTY_FUNCTION__);
|
||||
mir_data->current_window = NULL;
|
||||
mir_data->software = SDL_FALSE;
|
||||
mir_data->pixel_format = mir_pixel_format_invalid;
|
||||
|
||||
if (!MIR_mir_connection_is_valid(mir_data->connection))
|
||||
return SDL_SetError("Failed to connect to the Mir Server");
|
||||
if (!MIR_mir_connection_is_valid(mir_data->connection)) {
|
||||
return SDL_SetError("Failed to connect to the mir server: %s",
|
||||
MIR_mir_connection_get_error_message(mir_data->connection));
|
||||
}
|
||||
|
||||
mir_data->display_config = MIR_mir_connection_create_display_configuration(mir_data->connection);
|
||||
|
||||
MIR_InitDisplays(_this);
|
||||
MIR_InitMouse();
|
||||
|
|
@ -284,11 +315,27 @@ MIR_VideoInit(_THIS)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
MIR_CleanUpDisplayConfig(_THIS)
|
||||
{
|
||||
MIR_Data* mir_data = _this->driverdata;
|
||||
int i;
|
||||
|
||||
// SDL_VideoQuit frees the display driverdata, we own it not them
|
||||
for (i = 0; i < _this->num_displays; ++i) {
|
||||
_this->displays[i].driverdata = NULL;
|
||||
}
|
||||
|
||||
MIR_mir_display_config_release(mir_data->display_config);
|
||||
}
|
||||
|
||||
static void
|
||||
MIR_VideoQuit(_THIS)
|
||||
{
|
||||
MIR_Data* mir_data = _this->driverdata;
|
||||
|
||||
MIR_CleanUpDisplayConfig(_this);
|
||||
|
||||
MIR_FiniMouse();
|
||||
|
||||
MIR_GL_DeleteContext(_this, NULL);
|
||||
|
|
@ -303,40 +350,48 @@ MIR_VideoQuit(_THIS)
|
|||
static int
|
||||
MIR_GetDisplayBounds(_THIS, SDL_VideoDisplay* display, SDL_Rect* rect)
|
||||
{
|
||||
MIR_Data* mir_data = _this->driverdata;
|
||||
int d;
|
||||
MirOutput const* output = display->driverdata;
|
||||
|
||||
MirDisplayConfiguration* display_config = MIR_mir_connection_create_display_config(mir_data->connection);
|
||||
|
||||
for (d = 0; d < display_config->num_outputs; d++) {
|
||||
MirDisplayOutput const* out = display_config->outputs + d;
|
||||
|
||||
if (out->used &&
|
||||
out->connected &&
|
||||
out->num_modes &&
|
||||
out->current_mode < out->num_modes) {
|
||||
|
||||
rect->x = out->position_x;
|
||||
rect->y = out->position_y;
|
||||
rect->w = out->modes->horizontal_resolution;
|
||||
rect->h = out->modes->vertical_resolution;
|
||||
}
|
||||
}
|
||||
|
||||
MIR_mir_display_config_destroy(display_config);
|
||||
rect->x = MIR_mir_output_get_position_x(output);
|
||||
rect->y = MIR_mir_output_get_position_y(output);
|
||||
rect->w = display->current_mode.w;
|
||||
rect->h = display->current_mode.h;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
MIR_GetDisplayModes(_THIS, SDL_VideoDisplay* sdl_display)
|
||||
MIR_GetDisplayModes(_THIS, SDL_VideoDisplay* display)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
MIR_SetDisplayMode(_THIS, SDL_VideoDisplay* sdl_display, SDL_DisplayMode* mode)
|
||||
MIR_SetDisplayMode(_THIS, SDL_VideoDisplay* display, SDL_DisplayMode* mode)
|
||||
{
|
||||
return 0;
|
||||
int m;
|
||||
MirOutput* output = display->driverdata;
|
||||
int num_modes = MIR_mir_output_get_num_modes(output);
|
||||
Uint32 sdl_format = MIR_GetSDLPixelFormat(
|
||||
MIR_mir_output_get_current_pixel_format(output));
|
||||
|
||||
for (m = 0; m < num_modes; m++) {
|
||||
MirOutputMode const* mir_mode = MIR_mir_output_get_mode(output, m);
|
||||
int width = MIR_mir_output_mode_get_width(mir_mode);
|
||||
int height = MIR_mir_output_mode_get_height(mir_mode);
|
||||
double refresh_rate = MIR_mir_output_mode_get_refresh_rate(mir_mode);
|
||||
|
||||
if (mode->format == sdl_format &&
|
||||
mode->w == width &&
|
||||
mode->h == height &&
|
||||
mode->refresh_rate == refresh_rate) {
|
||||
|
||||
// FIXME Currently wont actually *set* anything. Need to wait for applying display changes
|
||||
MIR_mir_output_set_current_mode(output, mir_mode);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_MIR */
|
||||
|
|
|
|||
|
|
@ -29,13 +29,20 @@
|
|||
#include <EGL/egl.h>
|
||||
#include <mir_toolkit/mir_client_library.h>
|
||||
|
||||
typedef struct MIR_Window MIR_Window;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MirConnection* connection;
|
||||
SDL_bool software;
|
||||
|
||||
MirConnection* connection;
|
||||
MirDisplayConfig* display_config;
|
||||
MIR_Window* current_window;
|
||||
SDL_bool software;
|
||||
MirPixelFormat pixel_format;
|
||||
} MIR_Data;
|
||||
|
||||
extern Uint32
|
||||
MIR_GetSDLPixelFormat(MirPixelFormat format);
|
||||
|
||||
#endif /* _SDL_mirvideo_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "../SDL_egl_c.h"
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "../../events/SDL_keyboard_c.h"
|
||||
|
||||
#include "SDL_mirevents.h"
|
||||
#include "SDL_mirwindow.h"
|
||||
|
|
@ -55,7 +56,7 @@ FindValidPixelFormat(MIR_Data* mir_data)
|
|||
|
||||
MirPixelFormat formats[pf_size];
|
||||
MIR_mir_connection_get_available_surface_formats(mir_data->connection, formats,
|
||||
pf_size, &valid_formats);
|
||||
pf_size, &valid_formats);
|
||||
|
||||
for (f = 0; f < valid_formats; f++) {
|
||||
MirPixelFormat cur_pf = formats[f];
|
||||
|
|
@ -77,21 +78,10 @@ MIR_CreateWindow(_THIS, SDL_Window* window)
|
|||
{
|
||||
MIR_Window* mir_window;
|
||||
MIR_Data* mir_data;
|
||||
MirPixelFormat pixel_format;
|
||||
MirBufferUsage buffer_usage;
|
||||
|
||||
MirSurfaceParameters surfaceparm =
|
||||
{
|
||||
.name = "MirSurface",
|
||||
.width = window->w,
|
||||
.height = window->h,
|
||||
.pixel_format = mir_pixel_format_invalid,
|
||||
.buffer_usage = mir_buffer_usage_hardware,
|
||||
.output_id = mir_display_output_id_invalid
|
||||
};
|
||||
|
||||
MirEventDelegate delegate = {
|
||||
MIR_HandleInput,
|
||||
window
|
||||
};
|
||||
MirSurfaceSpec* spec;
|
||||
|
||||
mir_window = SDL_calloc(1, sizeof(MIR_Window));
|
||||
if (!mir_window)
|
||||
|
|
@ -100,9 +90,6 @@ MIR_CreateWindow(_THIS, SDL_Window* window)
|
|||
mir_data = _this->driverdata;
|
||||
window->driverdata = mir_window;
|
||||
|
||||
if (mir_data->software)
|
||||
surfaceparm.buffer_usage = mir_buffer_usage_software;
|
||||
|
||||
if (window->x == SDL_WINDOWPOS_UNDEFINED)
|
||||
window->x = 0;
|
||||
|
||||
|
|
@ -112,20 +99,49 @@ MIR_CreateWindow(_THIS, SDL_Window* window)
|
|||
mir_window->mir_data = mir_data;
|
||||
mir_window->sdl_window = window;
|
||||
|
||||
surfaceparm.pixel_format = FindValidPixelFormat(mir_data);
|
||||
if (surfaceparm.pixel_format == mir_pixel_format_invalid) {
|
||||
if (window->flags & SDL_WINDOW_OPENGL) {
|
||||
pixel_format = MIR_mir_connection_get_egl_pixel_format(mir_data->connection,
|
||||
_this->egl_data->egl_display,
|
||||
_this->egl_data->egl_config);
|
||||
}
|
||||
else {
|
||||
pixel_format = FindValidPixelFormat(mir_data);
|
||||
}
|
||||
|
||||
mir_data->pixel_format = pixel_format;
|
||||
if (pixel_format == mir_pixel_format_invalid) {
|
||||
return SDL_SetError("Failed to find a valid pixel format.");
|
||||
}
|
||||
|
||||
mir_window->surface = MIR_mir_connection_create_surface_sync(mir_data->connection, &surfaceparm);
|
||||
buffer_usage = mir_buffer_usage_hardware;
|
||||
if (mir_data->software)
|
||||
buffer_usage = mir_buffer_usage_software;
|
||||
|
||||
spec = MIR_mir_connection_create_spec_for_normal_surface(mir_data->connection,
|
||||
window->w,
|
||||
window->h,
|
||||
pixel_format);
|
||||
|
||||
MIR_mir_surface_spec_set_buffer_usage(spec, buffer_usage);
|
||||
MIR_mir_surface_spec_set_name(spec, "Mir surface");
|
||||
|
||||
if (window->flags & SDL_WINDOW_INPUT_FOCUS)
|
||||
SDL_SetKeyboardFocus(window);
|
||||
|
||||
mir_window->surface = MIR_mir_surface_create_sync(spec);
|
||||
MIR_mir_surface_set_event_handler(mir_window->surface, MIR_HandleEvent, window);
|
||||
|
||||
MIR_mir_surface_spec_release(spec);
|
||||
|
||||
if (!MIR_mir_surface_is_valid(mir_window->surface)) {
|
||||
const char* error = MIR_mir_surface_get_error_message(mir_window->surface);
|
||||
return SDL_SetError("Failed to created a mir surface: %s", error);
|
||||
return SDL_SetError("Failed to created a mir surface: %s",
|
||||
MIR_mir_surface_get_error_message(mir_window->surface));
|
||||
}
|
||||
|
||||
if (window->flags & SDL_WINDOW_OPENGL) {
|
||||
EGLNativeWindowType egl_native_window =
|
||||
(EGLNativeWindowType)MIR_mir_surface_get_egl_native_window(mir_window->surface);
|
||||
(EGLNativeWindowType)MIR_mir_buffer_stream_get_egl_native_window(
|
||||
MIR_mir_surface_get_buffer_stream(mir_window->surface));
|
||||
|
||||
mir_window->egl_surface = SDL_EGL_CreateSurface(_this, egl_native_window);
|
||||
|
||||
|
|
@ -138,7 +154,7 @@ MIR_CreateWindow(_THIS, SDL_Window* window)
|
|||
mir_window->egl_surface = EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
MIR_mir_surface_set_event_handler(mir_window->surface, &delegate);
|
||||
mir_data->current_window = mir_window;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -146,13 +162,15 @@ MIR_CreateWindow(_THIS, SDL_Window* window)
|
|||
void
|
||||
MIR_DestroyWindow(_THIS, SDL_Window* window)
|
||||
{
|
||||
MIR_Data* mir_data = _this->driverdata;
|
||||
MIR_Data* mir_data = _this->driverdata;
|
||||
MIR_Window* mir_window = window->driverdata;
|
||||
|
||||
if (mir_data) {
|
||||
SDL_EGL_DestroySurface(_this, mir_window->egl_surface);
|
||||
MIR_mir_surface_release_sync(mir_window->surface);
|
||||
|
||||
mir_data->current_window = NULL;
|
||||
|
||||
SDL_free(mir_window);
|
||||
}
|
||||
window->driverdata = NULL;
|
||||
|
|
@ -180,49 +198,223 @@ MIR_SetWindowFullscreen(_THIS, SDL_Window* window,
|
|||
SDL_VideoDisplay* display,
|
||||
SDL_bool fullscreen)
|
||||
{
|
||||
MIR_Data* mir_data = _this->driverdata;
|
||||
MIR_Window* mir_window = window->driverdata;
|
||||
MirSurfaceSpec* spec;
|
||||
MirSurfaceState state;
|
||||
|
||||
if (IsSurfaceValid(mir_window) < 0)
|
||||
return;
|
||||
|
||||
if (fullscreen) {
|
||||
MIR_mir_surface_set_state(mir_window->surface, mir_surface_state_fullscreen);
|
||||
state = mir_surface_state_fullscreen;
|
||||
} else {
|
||||
MIR_mir_surface_set_state(mir_window->surface, mir_surface_state_restored);
|
||||
state = mir_surface_state_restored;
|
||||
}
|
||||
|
||||
spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
|
||||
MIR_mir_surface_spec_set_state(spec, state);
|
||||
|
||||
MIR_mir_surface_apply_spec(mir_window->surface, spec);
|
||||
MIR_mir_surface_spec_release(spec);
|
||||
}
|
||||
|
||||
void
|
||||
MIR_MaximizeWindow(_THIS, SDL_Window* window)
|
||||
{
|
||||
MIR_Data* mir_data = _this->driverdata;
|
||||
MIR_Window* mir_window = window->driverdata;
|
||||
MirSurfaceSpec* spec;
|
||||
|
||||
if (IsSurfaceValid(mir_window) < 0)
|
||||
return;
|
||||
|
||||
MIR_mir_surface_set_state(mir_window->surface, mir_surface_state_maximized);
|
||||
spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
|
||||
MIR_mir_surface_spec_set_state(spec, mir_surface_state_maximized);
|
||||
|
||||
MIR_mir_surface_apply_spec(mir_window->surface, spec);
|
||||
MIR_mir_surface_spec_release(spec);
|
||||
}
|
||||
|
||||
void
|
||||
MIR_MinimizeWindow(_THIS, SDL_Window* window)
|
||||
{
|
||||
MIR_Data* mir_data = _this->driverdata;
|
||||
MIR_Window* mir_window = window->driverdata;
|
||||
MirSurfaceSpec* spec;
|
||||
|
||||
if (IsSurfaceValid(mir_window) < 0)
|
||||
return;
|
||||
|
||||
MIR_mir_surface_set_state(mir_window->surface, mir_surface_state_minimized);
|
||||
spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
|
||||
MIR_mir_surface_spec_set_state(spec, mir_surface_state_minimized);
|
||||
|
||||
MIR_mir_surface_apply_spec(mir_window->surface, spec);
|
||||
MIR_mir_surface_spec_release(spec);
|
||||
}
|
||||
|
||||
void
|
||||
MIR_RestoreWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
MIR_Data* mir_data = _this->driverdata;
|
||||
MIR_Window* mir_window = window->driverdata;
|
||||
MirSurfaceSpec* spec;
|
||||
|
||||
if (IsSurfaceValid(mir_window) < 0)
|
||||
return;
|
||||
|
||||
MIR_mir_surface_set_state(mir_window->surface, mir_surface_state_restored);
|
||||
spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
|
||||
MIR_mir_surface_spec_set_state(spec, mir_surface_state_restored);
|
||||
|
||||
MIR_mir_surface_apply_spec(mir_window->surface, spec);
|
||||
MIR_mir_surface_spec_release(spec);
|
||||
}
|
||||
|
||||
void
|
||||
MIR_HideWindow(_THIS, SDL_Window* window)
|
||||
{
|
||||
MIR_Data* mir_data = _this->driverdata;
|
||||
MIR_Window* mir_window = window->driverdata;
|
||||
MirSurfaceSpec* spec;
|
||||
|
||||
if (IsSurfaceValid(mir_window) < 0)
|
||||
return;
|
||||
|
||||
spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
|
||||
MIR_mir_surface_spec_set_state(spec, mir_surface_state_hidden);
|
||||
|
||||
MIR_mir_surface_apply_spec(mir_window->surface, spec);
|
||||
MIR_mir_surface_spec_release(spec);
|
||||
}
|
||||
|
||||
void
|
||||
MIR_SetWindowSize(_THIS, SDL_Window* window)
|
||||
{
|
||||
MIR_Data* mir_data = _this->driverdata;
|
||||
MIR_Window* mir_window = window->driverdata;
|
||||
MirSurfaceSpec* spec;
|
||||
|
||||
if (IsSurfaceValid(mir_window) < 0)
|
||||
return;
|
||||
|
||||
/* You cannot set the x/y of a mir window! So only update w/h */
|
||||
spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
|
||||
MIR_mir_surface_spec_set_width (spec, window->w);
|
||||
MIR_mir_surface_spec_set_height(spec, window->h);
|
||||
|
||||
MIR_mir_surface_apply_spec(mir_window->surface, spec);
|
||||
MIR_mir_surface_spec_release(spec);
|
||||
}
|
||||
|
||||
void
|
||||
MIR_SetWindowMinimumSize(_THIS, SDL_Window* window)
|
||||
{
|
||||
MIR_Data* mir_data = _this->driverdata;
|
||||
MIR_Window* mir_window = window->driverdata;
|
||||
MirSurfaceSpec* spec;
|
||||
|
||||
if (IsSurfaceValid(mir_window) < 0)
|
||||
return;
|
||||
|
||||
spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
|
||||
MIR_mir_surface_spec_set_min_width (spec, window->min_w);
|
||||
MIR_mir_surface_spec_set_min_height(spec, window->min_h);
|
||||
|
||||
MIR_mir_surface_apply_spec(mir_window->surface, spec);
|
||||
MIR_mir_surface_spec_release(spec);
|
||||
}
|
||||
|
||||
void
|
||||
MIR_SetWindowMaximumSize(_THIS, SDL_Window* window)
|
||||
{
|
||||
MIR_Data* mir_data = _this->driverdata;
|
||||
MIR_Window* mir_window = window->driverdata;
|
||||
MirSurfaceSpec* spec;
|
||||
|
||||
if (IsSurfaceValid(mir_window) < 0)
|
||||
return;
|
||||
|
||||
spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
|
||||
MIR_mir_surface_spec_set_max_width (spec, window->max_w);
|
||||
MIR_mir_surface_spec_set_max_height(spec, window->max_h);
|
||||
|
||||
MIR_mir_surface_apply_spec(mir_window->surface, spec);
|
||||
MIR_mir_surface_spec_release(spec);
|
||||
}
|
||||
|
||||
void
|
||||
MIR_SetWindowTitle(_THIS, SDL_Window* window)
|
||||
{
|
||||
MIR_Data* mir_data = _this->driverdata;
|
||||
MIR_Window* mir_window = window->driverdata;
|
||||
char const* title = window->title ? window->title : "";
|
||||
MirSurfaceSpec* spec;
|
||||
|
||||
if (IsSurfaceValid(mir_window) < 0)
|
||||
return;
|
||||
|
||||
spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
|
||||
MIR_mir_surface_spec_set_name(spec, title);
|
||||
|
||||
MIR_mir_surface_apply_spec(mir_window->surface, spec);
|
||||
MIR_mir_surface_spec_release(spec);
|
||||
}
|
||||
|
||||
void
|
||||
MIR_SetWindowGrab(_THIS, SDL_Window* window, SDL_bool grabbed)
|
||||
{
|
||||
MIR_Data* mir_data = _this->driverdata;
|
||||
MIR_Window* mir_window = window->driverdata;
|
||||
MirPointerConfinementState confined = mir_pointer_unconfined;
|
||||
MirSurfaceSpec* spec;
|
||||
|
||||
if (grabbed)
|
||||
confined = mir_pointer_confined_to_surface;
|
||||
|
||||
spec = MIR_mir_connection_create_spec_for_changes(mir_data->connection);
|
||||
MIR_mir_surface_spec_set_pointer_confinement(spec, confined);
|
||||
|
||||
MIR_mir_surface_apply_spec(mir_window->surface, spec);
|
||||
MIR_mir_surface_spec_release(spec);
|
||||
}
|
||||
|
||||
int
|
||||
MIR_SetWindowGammaRamp(_THIS, SDL_Window* window, Uint16 const* ramp)
|
||||
{
|
||||
MirOutput* output = SDL_GetDisplayForWindow(window)->driverdata;
|
||||
Uint32 ramp_size = 256;
|
||||
|
||||
// FIXME Need to apply the changes to the output, once that public API function is around
|
||||
if (MIR_mir_output_is_gamma_supported(output) == mir_output_gamma_supported) {
|
||||
MIR_mir_output_set_gamma(output,
|
||||
ramp + ramp_size * 0,
|
||||
ramp + ramp_size * 1,
|
||||
ramp + ramp_size * 2,
|
||||
ramp_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
MIR_GetWindowGammaRamp(_THIS, SDL_Window* window, Uint16* ramp)
|
||||
{
|
||||
MirOutput* output = SDL_GetDisplayForWindow(window)->driverdata;
|
||||
Uint32 ramp_size = 256;
|
||||
|
||||
if (MIR_mir_output_is_gamma_supported(output) == mir_output_gamma_supported) {
|
||||
if (MIR_mir_output_get_gamma_size(output) == ramp_size) {
|
||||
MIR_mir_output_get_gamma(output,
|
||||
ramp + ramp_size * 0,
|
||||
ramp + ramp_size * 1,
|
||||
ramp + ramp_size * 2,
|
||||
ramp_size);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_MIR */
|
||||
|
|
|
|||
|
|
@ -31,13 +31,13 @@
|
|||
|
||||
#include "SDL_mirvideo.h"
|
||||
|
||||
typedef struct {
|
||||
struct MIR_Window {
|
||||
SDL_Window* sdl_window;
|
||||
MIR_Data* mir_data;
|
||||
MIR_Data* mir_data;
|
||||
|
||||
MirSurface* surface;
|
||||
EGLSurface egl_surface;
|
||||
} MIR_Window;
|
||||
EGLSurface egl_surface;
|
||||
};
|
||||
|
||||
|
||||
extern int
|
||||
|
|
@ -60,9 +60,33 @@ MIR_MinimizeWindow(_THIS, SDL_Window* window);
|
|||
extern void
|
||||
MIR_RestoreWindow(_THIS, SDL_Window* window);
|
||||
|
||||
extern void
|
||||
MIR_HideWindow(_THIS, SDL_Window* window);
|
||||
|
||||
extern SDL_bool
|
||||
MIR_GetWindowWMInfo(_THIS, SDL_Window* window, SDL_SysWMinfo* info);
|
||||
|
||||
extern void
|
||||
MIR_SetWindowSize(_THIS, SDL_Window* window);
|
||||
|
||||
extern void
|
||||
MIR_SetWindowMinimumSize(_THIS, SDL_Window* window);
|
||||
|
||||
extern void
|
||||
MIR_SetWindowMaximumSize(_THIS, SDL_Window* window);
|
||||
|
||||
extern void
|
||||
MIR_SetWindowTitle(_THIS, SDL_Window* window);
|
||||
|
||||
extern void
|
||||
MIR_SetWindowGrab(_THIS, SDL_Window* window, SDL_bool grabbed);
|
||||
|
||||
extern int
|
||||
MIR_SetWindowGammaRamp(_THIS, SDL_Window* window, Uint16 const* ramp);
|
||||
|
||||
extern int
|
||||
MIR_GetWindowGammaRamp(_THIS, SDL_Window* window, Uint16* ramp);
|
||||
|
||||
#endif /* _SDL_mirwindow_h */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
|||
|
|
@ -41,8 +41,6 @@
|
|||
static NativeWindowType hNativeWnd = 0; /* A handle to the window we will create. */
|
||||
#endif
|
||||
|
||||
static SDL_bool PND_initialized = SDL_FALSE;
|
||||
|
||||
static int
|
||||
PND_available(void)
|
||||
{
|
||||
|
|
@ -52,11 +50,11 @@ PND_available(void)
|
|||
static void
|
||||
PND_destroy(SDL_VideoDevice * device)
|
||||
{
|
||||
SDL_VideoData *phdata = (SDL_VideoData *) device->driverdata;
|
||||
|
||||
if (device->driverdata != NULL) {
|
||||
SDL_free(device->driverdata);
|
||||
device->driverdata = NULL;
|
||||
}
|
||||
SDL_free(device);
|
||||
}
|
||||
|
||||
static SDL_VideoDevice *
|
||||
|
|
@ -93,9 +91,8 @@ PND_create()
|
|||
phdata->egl_initialized = SDL_TRUE;
|
||||
|
||||
|
||||
/* Setup amount of available displays and current display */
|
||||
/* Setup amount of available displays */
|
||||
device->num_displays = 0;
|
||||
device->current_display = 0;
|
||||
|
||||
/* Set device free function */
|
||||
device->free = PND_destroy;
|
||||
|
|
@ -204,10 +201,6 @@ PND_createwindow(_THIS, SDL_Window * window)
|
|||
|
||||
SDL_WindowData *wdata;
|
||||
|
||||
uint32_t winargc = 0;
|
||||
int32_t status;
|
||||
|
||||
|
||||
/* Allocate window internal data */
|
||||
wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
|
||||
if (wdata == NULL) {
|
||||
|
|
@ -292,7 +285,7 @@ PND_restorewindow(_THIS, SDL_Window * window)
|
|||
{
|
||||
}
|
||||
void
|
||||
PND_setwindowgrab(_THIS, SDL_Window * window)
|
||||
PND_setwindowgrab(_THIS, SDL_Window * window, SDL_bool grabbed)
|
||||
{
|
||||
}
|
||||
void
|
||||
|
|
@ -326,8 +319,6 @@ PND_getwindowwminfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
|
|||
int
|
||||
PND_gl_loadlibrary(_THIS, const char *path)
|
||||
{
|
||||
SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
|
||||
|
||||
/* Check if OpenGL ES library is specified for GF driver */
|
||||
if (path == NULL) {
|
||||
path = SDL_getenv("SDL_OPENGL_LIBRARY");
|
||||
|
|
@ -365,7 +356,6 @@ PND_gl_loadlibrary(_THIS, const char *path)
|
|||
void *
|
||||
PND_gl_getprocaddres(_THIS, const char *proc)
|
||||
{
|
||||
SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
|
||||
void *function_address;
|
||||
|
||||
/* Try to get function address through the egl interface */
|
||||
|
|
@ -409,10 +399,7 @@ PND_gl_createcontext(_THIS, SDL_Window * window)
|
|||
{
|
||||
SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
|
||||
SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
|
||||
SDL_DisplayData *didata =
|
||||
(SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
|
||||
EGLBoolean status;
|
||||
int32_t gfstatus;
|
||||
EGLint configs;
|
||||
uint32_t attr_pos;
|
||||
EGLint attr_value;
|
||||
|
|
@ -629,12 +616,12 @@ PND_gl_createcontext(_THIS, SDL_Window * window)
|
|||
hNativeWnd = (NativeWindowType)malloc(16*1024);
|
||||
|
||||
if(!hNativeWnd)
|
||||
printf( "Error : Wiz framebuffer allocatation failed\n" );
|
||||
printf( "Error: Wiz framebuffer allocatation failed\n" );
|
||||
else
|
||||
printf( "SDL13: Wiz framebuffer allocated: %X\n", hNativeWnd );
|
||||
printf( "SDL: Wiz framebuffer allocated: %X\n", hNativeWnd );
|
||||
}
|
||||
else {
|
||||
printf( "SDL13: Wiz framebuffer already allocated: %X\n", hNativeWnd );
|
||||
printf( "SDL: Wiz framebuffer already allocated: %X\n", hNativeWnd );
|
||||
}
|
||||
|
||||
wdata->gles_surface =
|
||||
|
|
@ -792,9 +779,6 @@ PND_gl_swapwindow(_THIS, SDL_Window * window)
|
|||
{
|
||||
SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
|
||||
SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
|
||||
SDL_DisplayData *didata =
|
||||
(SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
|
||||
|
||||
|
||||
if (phdata->egl_initialized != SDL_TRUE) {
|
||||
SDL_SetError("PND: GLES initialization failed, no OpenGL ES support");
|
||||
|
|
@ -838,7 +822,7 @@ PND_gl_deletecontext(_THIS, SDL_GLContext context)
|
|||
{
|
||||
free(hNativeWnd);
|
||||
hNativeWnd = 0;
|
||||
printf( "SDL13: Wiz framebuffer released\n" );
|
||||
printf( "SDL: Wiz framebuffer released\n" );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ void PND_raisewindow(_THIS, SDL_Window * window);
|
|||
void PND_maximizewindow(_THIS, SDL_Window * window);
|
||||
void PND_minimizewindow(_THIS, SDL_Window * window);
|
||||
void PND_restorewindow(_THIS, SDL_Window * window);
|
||||
void PND_setwindowgrab(_THIS, SDL_Window * window);
|
||||
void PND_setwindowgrab(_THIS, SDL_Window * window, SDL_bool grabbed);
|
||||
void PND_destroywindow(_THIS, SDL_Window * window);
|
||||
|
||||
/* Window manager function */
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@
|
|||
#include "../../events/SDL_keyboard_c.h"
|
||||
#include "SDL_pspvideo.h"
|
||||
#include "SDL_pspevents_c.h"
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_keyboard.h"
|
||||
#include "../../thread/SDL_systhread.h"
|
||||
#include <psphprm.h>
|
||||
|
||||
#ifdef PSPIRKEYB
|
||||
|
|
@ -264,7 +264,7 @@ void PSP_EventInit(_THIS)
|
|||
return;
|
||||
}
|
||||
running = 1;
|
||||
if((thread = SDL_CreateThread(EventUpdate, "PSPInputThread",NULL)) == NULL) {
|
||||
if((thread = SDL_CreateThreadInternal(EventUpdate, "PSPInputThread", 4096, NULL)) == NULL) {
|
||||
SDL_SetError("Can't create input thread\n");
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ PSP_Create()
|
|||
if (gldata == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
SDL_free(device);
|
||||
SDL_free(phdata);
|
||||
return NULL;
|
||||
}
|
||||
device->gl_data = gldata;
|
||||
|
|
@ -101,7 +102,7 @@ PSP_Create()
|
|||
phdata->egl_initialized = SDL_TRUE;
|
||||
|
||||
|
||||
/* Setup amount of available displays and current display */
|
||||
/* Setup amount of available displays */
|
||||
device->num_displays = 0;
|
||||
|
||||
/* Set device free function */
|
||||
|
|
@ -234,7 +235,7 @@ PSP_CreateWindow(_THIS, SDL_Window * window)
|
|||
int
|
||||
PSP_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
|
||||
{
|
||||
return -1;
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "SDL_assert.h"
|
||||
#include "SDL_surface.h"
|
||||
#include "SDL_hints.h"
|
||||
|
||||
#include "SDL_rpivideo.h"
|
||||
#include "SDL_rpimouse.h"
|
||||
|
|
@ -70,7 +71,16 @@ RPI_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
|
|||
SDL_assert(surface->pitch == surface->w * 4);
|
||||
|
||||
cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor));
|
||||
if (cursor == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
curdata = (RPI_CursorData *) SDL_calloc(1, sizeof(*curdata));
|
||||
if (curdata == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
SDL_free(cursor);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
curdata->hot_x = hot_x;
|
||||
curdata->hot_y = hot_y;
|
||||
|
|
@ -78,17 +88,17 @@ RPI_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
|
|||
curdata->h = surface->h;
|
||||
|
||||
/* This usage is inspired by Wayland/Weston RPI code, how they figured this out is anyone's guess */
|
||||
curdata->resource = vc_dispmanx_resource_create( VC_IMAGE_ARGB8888, surface->w | (surface->pitch << 16), surface->h | (surface->h << 16), &dummy );
|
||||
curdata->resource = vc_dispmanx_resource_create(VC_IMAGE_ARGB8888, surface->w | (surface->pitch << 16), surface->h | (surface->h << 16), &dummy);
|
||||
SDL_assert(curdata->resource);
|
||||
vc_dispmanx_rect_set( &dst_rect, 0, 0, curdata->w, curdata->h);
|
||||
vc_dispmanx_rect_set(&dst_rect, 0, 0, curdata->w, curdata->h);
|
||||
/* A note from Weston:
|
||||
* vc_dispmanx_resource_write_data() ignores ifmt,
|
||||
* rect.x, rect.width, and uses stride only for computing
|
||||
* the size of the transfer as rect.height * stride.
|
||||
* Therefore we can only write rows starting at x=0.
|
||||
*/
|
||||
ret = vc_dispmanx_resource_write_data( curdata->resource, VC_IMAGE_ARGB8888, surface->pitch, surface->pixels, &dst_rect );
|
||||
SDL_assert ( ret == DISPMANX_SUCCESS );
|
||||
ret = vc_dispmanx_resource_write_data(curdata->resource, VC_IMAGE_ARGB8888, surface->pitch, surface->pixels, &dst_rect);
|
||||
SDL_assert (ret == DISPMANX_SUCCESS);
|
||||
|
||||
cursor->driverdata = curdata;
|
||||
|
||||
|
|
@ -108,7 +118,9 @@ RPI_ShowCursor(SDL_Cursor * cursor)
|
|||
SDL_VideoDisplay *display;
|
||||
SDL_DisplayData *data;
|
||||
VC_DISPMANX_ALPHA_T alpha = { DISPMANX_FLAGS_ALPHA_FROM_SOURCE /* flags */ , 255 /*opacity 0->255*/, 0 /* mask */ };
|
||||
|
||||
uint32_t layer = SDL_RPI_MOUSELAYER;
|
||||
const char *env;
|
||||
|
||||
mouse = SDL_GetMouse();
|
||||
if (mouse == NULL) {
|
||||
return -1;
|
||||
|
|
@ -117,15 +129,15 @@ RPI_ShowCursor(SDL_Cursor * cursor)
|
|||
if (cursor == NULL) {
|
||||
/* FIXME: We hide the current mouse's cursor, what we actually need is *_HideCursor */
|
||||
|
||||
if ( mouse->cur_cursor != NULL && mouse->cur_cursor->driverdata != NULL) {
|
||||
if (mouse->cur_cursor != NULL && mouse->cur_cursor->driverdata != NULL) {
|
||||
curdata = (RPI_CursorData *) mouse->cur_cursor->driverdata;
|
||||
if (curdata->element > DISPMANX_NO_HANDLE) {
|
||||
update = vc_dispmanx_update_start( 10 );
|
||||
SDL_assert( update );
|
||||
ret = vc_dispmanx_element_remove( update, curdata->element );
|
||||
SDL_assert( ret == DISPMANX_SUCCESS );
|
||||
ret = vc_dispmanx_update_submit_sync( update );
|
||||
SDL_assert( ret == DISPMANX_SUCCESS );
|
||||
update = vc_dispmanx_update_start(10);
|
||||
SDL_assert(update);
|
||||
ret = vc_dispmanx_element_remove(update, curdata->element);
|
||||
SDL_assert(ret == DISPMANX_SUCCESS);
|
||||
ret = vc_dispmanx_update_submit_sync(update);
|
||||
SDL_assert(ret == DISPMANX_SUCCESS);
|
||||
curdata->element = DISPMANX_NO_HANDLE;
|
||||
}
|
||||
}
|
||||
|
|
@ -152,25 +164,30 @@ RPI_ShowCursor(SDL_Cursor * cursor)
|
|||
}
|
||||
|
||||
if (curdata->element == DISPMANX_NO_HANDLE) {
|
||||
vc_dispmanx_rect_set( &src_rect, 0, 0, curdata->w << 16, curdata->h << 16 );
|
||||
vc_dispmanx_rect_set( &dst_rect, 0, 0, curdata->w, curdata->h);
|
||||
vc_dispmanx_rect_set(&src_rect, 0, 0, curdata->w << 16, curdata->h << 16);
|
||||
vc_dispmanx_rect_set(&dst_rect, 0, 0, curdata->w, curdata->h);
|
||||
|
||||
update = vc_dispmanx_update_start( 10 );
|
||||
SDL_assert( update );
|
||||
update = vc_dispmanx_update_start(10);
|
||||
SDL_assert(update);
|
||||
|
||||
curdata->element = vc_dispmanx_element_add( update,
|
||||
env = SDL_GetHint(SDL_HINT_RPI_VIDEO_LAYER);
|
||||
if (env) {
|
||||
layer = SDL_atoi(env) + 1;
|
||||
}
|
||||
|
||||
curdata->element = vc_dispmanx_element_add(update,
|
||||
data->dispman_display,
|
||||
SDL_RPI_MOUSELAYER, // layer
|
||||
layer,
|
||||
&dst_rect,
|
||||
curdata->resource,
|
||||
&src_rect,
|
||||
DISPMANX_PROTECTION_NONE,
|
||||
&alpha,
|
||||
DISPMANX_NO_HANDLE, // clamp
|
||||
VC_IMAGE_ROT0 );
|
||||
SDL_assert( curdata->element > DISPMANX_NO_HANDLE);
|
||||
ret = vc_dispmanx_update_submit_sync( update );
|
||||
SDL_assert( ret == DISPMANX_SUCCESS );
|
||||
VC_IMAGE_ROT0);
|
||||
SDL_assert(curdata->element > DISPMANX_NO_HANDLE);
|
||||
ret = vc_dispmanx_update_submit_sync(update);
|
||||
SDL_assert(ret == DISPMANX_SUCCESS);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -189,17 +206,17 @@ RPI_FreeCursor(SDL_Cursor * cursor)
|
|||
|
||||
if (curdata != NULL) {
|
||||
if (curdata->element != DISPMANX_NO_HANDLE) {
|
||||
update = vc_dispmanx_update_start( 10 );
|
||||
SDL_assert( update );
|
||||
ret = vc_dispmanx_element_remove( update, curdata->element );
|
||||
SDL_assert( ret == DISPMANX_SUCCESS );
|
||||
ret = vc_dispmanx_update_submit_sync( update );
|
||||
SDL_assert( ret == DISPMANX_SUCCESS );
|
||||
update = vc_dispmanx_update_start(10);
|
||||
SDL_assert(update);
|
||||
ret = vc_dispmanx_element_remove(update, curdata->element);
|
||||
SDL_assert(ret == DISPMANX_SUCCESS);
|
||||
ret = vc_dispmanx_update_submit_sync(update);
|
||||
SDL_assert(ret == DISPMANX_SUCCESS);
|
||||
}
|
||||
|
||||
if (curdata->resource != DISPMANX_NO_HANDLE) {
|
||||
ret = vc_dispmanx_resource_delete( curdata->resource );
|
||||
SDL_assert( ret == DISPMANX_SUCCESS );
|
||||
ret = vc_dispmanx_resource_delete(curdata->resource);
|
||||
SDL_assert(ret == DISPMANX_SUCCESS);
|
||||
}
|
||||
|
||||
SDL_free(cursor->driverdata);
|
||||
|
|
@ -221,35 +238,54 @@ RPI_WarpMouseGlobal(int x, int y)
|
|||
{
|
||||
RPI_CursorData *curdata;
|
||||
DISPMANX_UPDATE_HANDLE_T update;
|
||||
int ret;
|
||||
VC_RECT_T dst_rect;
|
||||
VC_RECT_T src_rect;
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
|
||||
if (mouse != NULL && mouse->cur_cursor != NULL && mouse->cur_cursor->driverdata != NULL) {
|
||||
curdata = (RPI_CursorData *) mouse->cur_cursor->driverdata;
|
||||
if (curdata->element != DISPMANX_NO_HANDLE) {
|
||||
int ret;
|
||||
update = vc_dispmanx_update_start( 10 );
|
||||
SDL_assert( update );
|
||||
vc_dispmanx_rect_set( &dst_rect, x, y, curdata->w, curdata->h);
|
||||
ret = vc_dispmanx_element_change_attributes(
|
||||
update,
|
||||
curdata->element,
|
||||
ELEMENT_CHANGE_DEST_RECT,
|
||||
0,
|
||||
0,
|
||||
&dst_rect,
|
||||
NULL,
|
||||
DISPMANX_NO_HANDLE,
|
||||
DISPMANX_NO_ROTATE);
|
||||
SDL_assert( ret == DISPMANX_SUCCESS );
|
||||
/* Submit asynchronously, otherwise the peformance suffers a lot */
|
||||
ret = vc_dispmanx_update_submit( update, 0, NULL );
|
||||
SDL_assert( ret == DISPMANX_SUCCESS );
|
||||
return (ret == DISPMANX_SUCCESS) ? 0 : -1;
|
||||
}
|
||||
}
|
||||
if (mouse == NULL || mouse->cur_cursor == NULL || mouse->cur_cursor->driverdata == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1; /* !!! FIXME: this should SDL_SetError() somewhere. */
|
||||
curdata = (RPI_CursorData *) mouse->cur_cursor->driverdata;
|
||||
if (curdata->element == DISPMANX_NO_HANDLE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
update = vc_dispmanx_update_start(10);
|
||||
if (!update) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
src_rect.x = 0;
|
||||
src_rect.y = 0;
|
||||
src_rect.width = curdata->w << 16;
|
||||
src_rect.height = curdata->h << 16;
|
||||
dst_rect.x = x;
|
||||
dst_rect.y = y;
|
||||
dst_rect.width = curdata->w;
|
||||
dst_rect.height = curdata->h;
|
||||
|
||||
ret = vc_dispmanx_element_change_attributes(
|
||||
update,
|
||||
curdata->element,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&dst_rect,
|
||||
&src_rect,
|
||||
DISPMANX_NO_HANDLE,
|
||||
DISPMANX_NO_ROTATE);
|
||||
if (ret != DISPMANX_SUCCESS) {
|
||||
return SDL_SetError("vc_dispmanx_element_change_attributes() failed");
|
||||
}
|
||||
|
||||
/* Submit asynchronously, otherwise the peformance suffers a lot */
|
||||
ret = vc_dispmanx_update_submit(update, 0, NULL);
|
||||
if (ret != DISPMANX_SUCCESS) {
|
||||
return SDL_SetError("vc_dispmanx_update_submit() failed");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#include "SDL_events.h"
|
||||
#include "../../events/SDL_mouse_c.h"
|
||||
#include "../../events/SDL_keyboard_c.h"
|
||||
#include "SDL_hints.h"
|
||||
|
||||
#ifdef SDL_INPUT_LINUXEV
|
||||
#include "../../core/linux/SDL_evdev.h"
|
||||
|
|
@ -88,7 +89,7 @@ RPI_Create()
|
|||
|
||||
device->driverdata = phdata;
|
||||
|
||||
/* Setup amount of available displays and current display */
|
||||
/* Setup amount of available displays */
|
||||
device->num_displays = 0;
|
||||
|
||||
/* Set device free function */
|
||||
|
|
@ -221,6 +222,8 @@ RPI_CreateWindow(_THIS, SDL_Window * window)
|
|||
VC_RECT_T src_rect;
|
||||
VC_DISPMANX_ALPHA_T dispman_alpha;
|
||||
DISPMANX_UPDATE_HANDLE_T dispman_update;
|
||||
uint32_t layer = SDL_RPI_VIDEOLAYER;
|
||||
const char *env;
|
||||
|
||||
/* Disable alpha, otherwise the app looks composed with whatever dispman is showing (X11, console,etc) */
|
||||
dispman_alpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
|
||||
|
|
@ -253,11 +256,25 @@ RPI_CreateWindow(_THIS, SDL_Window * window)
|
|||
src_rect.width = window->w << 16;
|
||||
src_rect.height = window->h << 16;
|
||||
|
||||
env = SDL_GetHint(SDL_HINT_RPI_VIDEO_LAYER);
|
||||
if (env) {
|
||||
layer = SDL_atoi(env);
|
||||
}
|
||||
|
||||
dispman_update = vc_dispmanx_update_start( 0 );
|
||||
wdata->dispman_window.element = vc_dispmanx_element_add ( dispman_update, displaydata->dispman_display, SDL_RPI_VIDEOLAYER /* layer */, &dst_rect, 0/*src*/, &src_rect, DISPMANX_PROTECTION_NONE, &dispman_alpha /*alpha*/, 0/*clamp*/, 0/*transform*/);
|
||||
wdata->dispman_window.element = vc_dispmanx_element_add (dispman_update,
|
||||
displaydata->dispman_display,
|
||||
layer /* layer */,
|
||||
&dst_rect,
|
||||
0 /*src*/,
|
||||
&src_rect,
|
||||
DISPMANX_PROTECTION_NONE,
|
||||
&dispman_alpha /*alpha*/,
|
||||
0 /*clamp*/,
|
||||
0 /*transform*/);
|
||||
wdata->dispman_window.width = window->w;
|
||||
wdata->dispman_window.height = window->h;
|
||||
vc_dispmanx_update_submit_sync( dispman_update );
|
||||
vc_dispmanx_update_submit_sync(dispman_update);
|
||||
|
||||
if (!_this->egl_data) {
|
||||
if (SDL_GL_LoadLibrary(NULL) < 0) {
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@
|
|||
@interface SDLLaunchScreenController : UIViewController
|
||||
|
||||
- (instancetype)init;
|
||||
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil;
|
||||
- (void)loadView;
|
||||
- (NSUInteger)supportedInterfaceOrientations;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa
|
|||
[UIApplication sharedApplication].idleTimerDisabled = disable;
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
/* Load a launch image using the old UILaunchImageFile-era naming rules. */
|
||||
static UIImage *
|
||||
SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
||||
|
|
@ -114,17 +115,31 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
|||
|
||||
return image;
|
||||
}
|
||||
#endif /* !TARGET_OS_TV */
|
||||
|
||||
@interface SDLLaunchScreenController ()
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
- (NSUInteger)supportedInterfaceOrientations;
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
@implementation SDLLaunchScreenController
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
return [self initWithNibName:nil bundle:[NSBundle mainBundle]];
|
||||
}
|
||||
|
||||
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
|
||||
{
|
||||
if (!(self = [super initWithNibName:nil bundle:nil])) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
NSString *screenname = [bundle objectForInfoDictionaryKey:@"UILaunchStoryboardName"];
|
||||
NSString *screenname = nibNameOrNil;
|
||||
NSBundle *bundle = nibBundleOrNil;
|
||||
BOOL atleastiOS8 = UIKit_IsSystemVersionAtLeast(8.0);
|
||||
|
||||
/* Launch screens were added in iOS 8. Otherwise we use launch images. */
|
||||
|
|
@ -141,27 +156,28 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
|||
|
||||
if (!self.view) {
|
||||
NSArray *launchimages = [bundle objectForInfoDictionaryKey:@"UILaunchImages"];
|
||||
UIInterfaceOrientation curorient = [UIApplication sharedApplication].statusBarOrientation;
|
||||
NSString *imagename = nil;
|
||||
UIImage *image = nil;
|
||||
|
||||
int screenw = (int)([UIScreen mainScreen].bounds.size.width + 0.5);
|
||||
int screenh = (int)([UIScreen mainScreen].bounds.size.height + 0.5);
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
UIInterfaceOrientation curorient = [UIApplication sharedApplication].statusBarOrientation;
|
||||
|
||||
/* We always want portrait-oriented size, to match UILaunchImageSize. */
|
||||
if (screenw > screenh) {
|
||||
int width = screenw;
|
||||
screenw = screenh;
|
||||
screenh = width;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Xcode 5 introduced a dictionary of launch images in Info.plist. */
|
||||
if (launchimages) {
|
||||
for (NSDictionary *dict in launchimages) {
|
||||
UIInterfaceOrientationMask orientmask = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
|
||||
NSString *minversion = dict[@"UILaunchImageMinimumOSVersion"];
|
||||
NSString *sizestring = dict[@"UILaunchImageSize"];
|
||||
NSString *orientstring = dict[@"UILaunchImageOrientation"];
|
||||
NSString *minversion = dict[@"UILaunchImageMinimumOSVersion"];
|
||||
NSString *sizestring = dict[@"UILaunchImageSize"];
|
||||
|
||||
/* Ignore this image if the current version is too low. */
|
||||
if (minversion && !UIKit_IsSystemVersionAtLeast(minversion.doubleValue)) {
|
||||
|
|
@ -176,6 +192,10 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
|||
}
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
UIInterfaceOrientationMask orientmask = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
|
||||
NSString *orientstring = dict[@"UILaunchImageOrientation"];
|
||||
|
||||
if (orientstring) {
|
||||
if ([orientstring isEqualToString:@"PortraitUpsideDown"]) {
|
||||
orientmask = UIInterfaceOrientationMaskPortraitUpsideDown;
|
||||
|
|
@ -192,6 +212,7 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
|||
if ((orientmask & (1 << curorient)) == 0) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
imagename = dict[@"UILaunchImageName"];
|
||||
}
|
||||
|
|
@ -199,7 +220,9 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
|||
if (imagename) {
|
||||
image = [UIImage imageNamed:imagename];
|
||||
}
|
||||
} else {
|
||||
}
|
||||
#if !TARGET_OS_TV
|
||||
else {
|
||||
imagename = [bundle objectForInfoDictionaryKey:@"UILaunchImageFile"];
|
||||
|
||||
if (imagename) {
|
||||
|
|
@ -210,11 +233,13 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
|||
image = SDL_LoadLaunchImageNamed(@"Default", screenh);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (image) {
|
||||
UIImageView *view = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
UIImageOrientation imageorient = UIImageOrientationUp;
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
/* Bugs observed / workaround tested in iOS 8.3, 7.1, and 6.1. */
|
||||
if (UIInterfaceOrientationIsLandscape(curorient)) {
|
||||
if (atleastiOS8 && image.size.width < image.size.height) {
|
||||
|
|
@ -238,6 +263,7 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Create the properly oriented image. */
|
||||
view.image = [[UIImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:imageorient];
|
||||
|
|
@ -254,6 +280,7 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
|||
/* Do nothing. */
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
- (BOOL)shouldAutorotate
|
||||
{
|
||||
/* If YES, the launch image will be incorrectly rotated in some cases. */
|
||||
|
|
@ -267,6 +294,7 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
|||
* the ones set here (it will cause an exception in that case.) */
|
||||
return UIInterfaceOrientationMaskAll;
|
||||
}
|
||||
#endif /* !TARGET_OS_TV */
|
||||
|
||||
@end
|
||||
|
||||
|
|
@ -333,7 +361,6 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
|||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||
|
||||
#if SDL_IPHONE_LAUNCHSCREEN
|
||||
/* The normal launch screen is displayed until didFinishLaunching returns,
|
||||
|
|
@ -342,9 +369,32 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
|||
* displayed (e.g. if resources are loaded before SDL_GL_SwapWindow is
|
||||
* called), so we show the launch screen programmatically until the first
|
||||
* time events are pumped. */
|
||||
UIViewController *viewcontroller = [[SDLLaunchScreenController alloc] init];
|
||||
UIViewController *vc = nil;
|
||||
NSString *screenname = nil;
|
||||
|
||||
if (viewcontroller.view) {
|
||||
/* tvOS only uses a plain launch image. */
|
||||
#if !TARGET_OS_TV
|
||||
screenname = [bundle objectForInfoDictionaryKey:@"UILaunchStoryboardName"];
|
||||
|
||||
if (screenname && UIKit_IsSystemVersionAtLeast(8.0)) {
|
||||
@try {
|
||||
/* The launch storyboard is actually a nib in some older versions of
|
||||
* Xcode. We'll try to load it as a storyboard first, as it's more
|
||||
* modern. */
|
||||
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:screenname bundle:bundle];
|
||||
vc = [storyboard instantiateInitialViewController];
|
||||
}
|
||||
@catch (NSException *exception) {
|
||||
/* Do nothing (there's more code to execute below). */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (vc == nil) {
|
||||
vc = [[SDLLaunchScreenController alloc] initWithNibName:screenname bundle:bundle];
|
||||
}
|
||||
|
||||
if (vc.view) {
|
||||
launchWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
|
||||
/* We don't want the launch window immediately hidden when a real SDL
|
||||
|
|
@ -355,7 +405,7 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
|||
* other windows when possible. */
|
||||
launchWindow.hidden = NO;
|
||||
|
||||
launchWindow.rootViewController = viewcontroller;
|
||||
launchWindow.rootViewController = vc;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -382,6 +432,7 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
|||
SDL_SendAppEvent(SDL_APP_LOWMEMORY);
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
- (void)application:(UIApplication *)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation
|
||||
{
|
||||
BOOL isLandscape = UIInterfaceOrientationIsLandscape(application.statusBarOrientation);
|
||||
|
|
@ -409,6 +460,7 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)applicationWillResignActive:(UIApplication*)application
|
||||
{
|
||||
|
|
@ -447,16 +499,34 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
|||
}
|
||||
}
|
||||
|
||||
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
|
||||
- (void)sendDropFileForURL:(NSURL *)url
|
||||
{
|
||||
NSURL *fileURL = url.filePathURL;
|
||||
if (fileURL != nil) {
|
||||
SDL_SendDropFile([fileURL.path UTF8String]);
|
||||
SDL_SendDropFile(NULL, fileURL.path.UTF8String);
|
||||
} else {
|
||||
SDL_SendDropFile([url.absoluteString UTF8String]);
|
||||
SDL_SendDropFile(NULL, url.absoluteString.UTF8String);
|
||||
}
|
||||
SDL_SendDropComplete(NULL);
|
||||
}
|
||||
|
||||
#if TARGET_OS_TV
|
||||
/* TODO: Use this on iOS 9+ as well? */
|
||||
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
|
||||
{
|
||||
/* TODO: Handle options */
|
||||
[self sendDropFileForURL:url];
|
||||
return YES;
|
||||
}
|
||||
#endif /* TARGET_OS_TV */
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
|
||||
{
|
||||
[self sendDropFileForURL:url];
|
||||
return YES;
|
||||
}
|
||||
#endif /* !TARGET_OS_TV */
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
|||
35
Engine/lib/sdl/src/video/uikit/SDL_uikitclipboard.h
Normal file
35
Engine/lib/sdl/src/video/uikit/SDL_uikitclipboard.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#ifndef _SDL_uikitclipboard_h
|
||||
#define _SDL_uikitclipboard_h
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
|
||||
extern int UIKit_SetClipboardText(_THIS, const char *text);
|
||||
extern char *UIKit_GetClipboardText(_THIS);
|
||||
extern SDL_bool UIKit_HasClipboardText(_THIS);
|
||||
|
||||
extern void UIKit_InitClipboard(_THIS);
|
||||
extern void UIKit_QuitClipboard(_THIS);
|
||||
|
||||
#endif /* _SDL_uikitclipboard_h */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
111
Engine/lib/sdl/src/video/uikit/SDL_uikitclipboard.m
Normal file
111
Engine/lib/sdl/src/video/uikit/SDL_uikitclipboard.m
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2016 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_UIKIT
|
||||
|
||||
#include "SDL_uikitvideo.h"
|
||||
#include "../../events/SDL_clipboardevents_c.h"
|
||||
|
||||
#import <UIKit/UIPasteboard.h>
|
||||
|
||||
int
|
||||
UIKit_SetClipboardText(_THIS, const char *text)
|
||||
{
|
||||
#if TARGET_OS_TV
|
||||
return SDL_SetError("The clipboard is not available on tvOS");
|
||||
#else
|
||||
@autoreleasepool {
|
||||
[UIPasteboard generalPasteboard].string = @(text);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
char *
|
||||
UIKit_GetClipboardText(_THIS)
|
||||
{
|
||||
#if TARGET_OS_TV
|
||||
return SDL_strdup(""); // Unsupported.
|
||||
#else
|
||||
@autoreleasepool {
|
||||
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
|
||||
NSString *string = pasteboard.string;
|
||||
|
||||
if (string != nil) {
|
||||
return SDL_strdup(string.UTF8String);
|
||||
} else {
|
||||
return SDL_strdup("");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
UIKit_HasClipboardText(_THIS)
|
||||
{
|
||||
@autoreleasepool {
|
||||
#if !TARGET_OS_TV
|
||||
if ([UIPasteboard generalPasteboard].string != nil) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
#endif
|
||||
return SDL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UIKit_InitClipboard(_THIS)
|
||||
{
|
||||
#if !TARGET_OS_TV
|
||||
@autoreleasepool {
|
||||
SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata;
|
||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||
|
||||
id observer = [center addObserverForName:UIPasteboardChangedNotification
|
||||
object:nil
|
||||
queue:nil
|
||||
usingBlock:^(NSNotification *note) {
|
||||
SDL_SendClipboardUpdate();
|
||||
}];
|
||||
|
||||
data.pasteboardObserver = observer;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
UIKit_QuitClipboard(_THIS)
|
||||
{
|
||||
@autoreleasepool {
|
||||
SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata;
|
||||
|
||||
if (data.pasteboardObserver != nil) {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:data.pasteboardObserver];
|
||||
}
|
||||
|
||||
data.pasteboardObserver = nil;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_UIKIT */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include "SDL_uikitvideo.h"
|
||||
#include "SDL_uikitevents.h"
|
||||
#include "SDL_uikitopengles.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
|
|
@ -62,6 +63,9 @@ UIKit_PumpEvents(_THIS)
|
|||
do {
|
||||
result = CFRunLoopRunInMode((CFStringRef)UITrackingRunLoopMode, seconds, TRUE);
|
||||
} while(result == kCFRunLoopRunHandledSource);
|
||||
|
||||
/* See the comment in the function definition. */
|
||||
UIKit_GL_RestoreCurrentContext();
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_UIKIT */
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ extern int UIKit_InitModes(_THIS);
|
|||
extern void UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
|
||||
extern int UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
|
||||
extern void UIKit_QuitModes(_THIS);
|
||||
extern int UIKit_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect);
|
||||
|
||||
#endif /* _SDL_uikitmodes_h */
|
||||
|
||||
|
|
|
|||
|
|
@ -156,9 +156,12 @@ UIKit_AddDisplay(UIScreen *uiscreen)
|
|||
SDL_bool
|
||||
UIKit_IsDisplayLandscape(UIScreen *uiscreen)
|
||||
{
|
||||
#if !TARGET_OS_TV
|
||||
if (uiscreen == [UIScreen mainScreen]) {
|
||||
return UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation);
|
||||
} else {
|
||||
} else
|
||||
#endif /* !TARGET_OS_TV */
|
||||
{
|
||||
CGSize size = uiscreen.bounds.size;
|
||||
return (size.width > size.height);
|
||||
}
|
||||
|
|
@ -187,6 +190,14 @@ UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
|
|||
SDL_bool isLandscape = UIKit_IsDisplayLandscape(data.uiscreen);
|
||||
SDL_bool addRotation = (data.uiscreen == [UIScreen mainScreen]);
|
||||
CGFloat scale = data.uiscreen.scale;
|
||||
NSArray *availableModes = nil;
|
||||
|
||||
#if TARGET_OS_TV
|
||||
addRotation = SDL_FALSE;
|
||||
availableModes = @[data.uiscreen.currentMode];
|
||||
#else
|
||||
availableModes = data.uiscreen.availableModes;
|
||||
#endif
|
||||
|
||||
#ifdef __IPHONE_8_0
|
||||
/* The UIScreenMode of an iPhone 6 Plus should be 1080x1920 rather than
|
||||
|
|
@ -196,7 +207,7 @@ UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
|
|||
}
|
||||
#endif
|
||||
|
||||
for (UIScreenMode *uimode in data.uiscreen.availableModes) {
|
||||
for (UIScreenMode *uimode in availableModes) {
|
||||
/* The size of a UIScreenMode is in pixels, but we deal exclusively
|
||||
* in points (except in SDL_GL_GetDrawableSize.) */
|
||||
int w = (int)(uimode.size.width / scale);
|
||||
|
|
@ -219,9 +230,11 @@ UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
|
|||
{
|
||||
@autoreleasepool {
|
||||
SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
|
||||
SDL_DisplayModeData *modedata = (__bridge SDL_DisplayModeData *)mode->driverdata;
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
SDL_DisplayModeData *modedata = (__bridge SDL_DisplayModeData *)mode->driverdata;
|
||||
[data.uiscreen setCurrentMode:modedata.uiscreenmode];
|
||||
#endif
|
||||
|
||||
if (data.uiscreen == [UIScreen mainScreen]) {
|
||||
/* [UIApplication setStatusBarOrientation:] no longer works reliably
|
||||
|
|
@ -242,6 +255,36 @@ UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
UIKit_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect)
|
||||
{
|
||||
@autoreleasepool {
|
||||
int displayIndex = (int) (display - _this->displays);
|
||||
SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
|
||||
|
||||
/* the default function iterates displays to make a fake offset,
|
||||
as if all the displays were side-by-side, which is fine for iOS. */
|
||||
if (SDL_GetDisplayBounds(displayIndex, rect) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
CGRect frame = data.uiscreen.bounds;
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
if (!UIKit_IsSystemVersionAtLeast(7.0)) {
|
||||
frame = [data.uiscreen applicationFrame];
|
||||
}
|
||||
#endif
|
||||
|
||||
rect->x += frame.origin.x;
|
||||
rect->y += frame.origin.y;
|
||||
rect->w = frame.size.width;
|
||||
rect->h = frame.size.height;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
UIKit_QuitModes(_THIS)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ extern void UIKit_GL_DeleteContext(_THIS, SDL_GLContext context);
|
|||
extern void *UIKit_GL_GetProcAddress(_THIS, const char *proc);
|
||||
extern int UIKit_GL_LoadLibrary(_THIS, const char *path);
|
||||
|
||||
extern void UIKit_GL_RestoreCurrentContext();
|
||||
|
||||
#endif
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
|||
|
|
@ -140,10 +140,19 @@ UIKit_GL_CreateContext(_THIS, SDL_Window * window)
|
|||
EAGLSharegroup *sharegroup = nil;
|
||||
CGFloat scale = 1.0;
|
||||
int samples = 0;
|
||||
int major = _this->gl_config.major_version;
|
||||
int minor = _this->gl_config.minor_version;
|
||||
|
||||
/* The EAGLRenderingAPI enum values currently map 1:1 to major GLES
|
||||
* versions. */
|
||||
EAGLRenderingAPI api = _this->gl_config.major_version;
|
||||
EAGLRenderingAPI api = major;
|
||||
|
||||
/* iOS currently doesn't support GLES >3.0. iOS 6 also only supports up
|
||||
* to GLES 2.0. */
|
||||
if (major > 3 || (major == 3 && (minor > 0 || !UIKit_IsSystemVersionAtLeast(7.0)))) {
|
||||
SDL_SetError("OpenGL ES %d.%d context could not be created", major, minor);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (_this->gl_config.multisamplebuffers > 0) {
|
||||
samples = _this->gl_config.multisamplesamples;
|
||||
|
|
@ -217,6 +226,24 @@ UIKit_GL_DeleteContext(_THIS, SDL_GLContext context)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
UIKit_GL_RestoreCurrentContext()
|
||||
{
|
||||
@autoreleasepool {
|
||||
/* Some iOS system functionality (such as Dictation on the on-screen
|
||||
keyboard) uses its own OpenGL ES context but doesn't restore the
|
||||
previous one when it's done. This is a workaround to make sure the
|
||||
expected SDL-created OpenGL ES context is active after the OS is
|
||||
finished running its own code for the frame. If this isn't done, the
|
||||
app may crash or have other nasty symptoms when Dictation is used.
|
||||
*/
|
||||
EAGLContext *context = (__bridge EAGLContext *) SDL_GL_GetCurrentContext();
|
||||
if (context != NULL && [EAGLContext currentContext] != context) {
|
||||
[EAGLContext setCurrentContext:context];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_UIKIT */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@
|
|||
|
||||
if (msaaRenderbuffer != 0) {
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, msaaRenderbuffer);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_RGBA8, backingWidth, backingHeight);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, colorBufferFormat, backingWidth, backingHeight);
|
||||
}
|
||||
|
||||
if (depthRenderbuffer != 0) {
|
||||
|
|
|
|||
|
|
@ -21,14 +21,25 @@
|
|||
#ifndef _SDL_uikitvideo_h
|
||||
#define _SDL_uikitvideo_h
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
|
||||
#ifdef __OBJC__
|
||||
|
||||
#include <UIKit/UIKit.h>
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
@interface SDL_VideoData : NSObject
|
||||
|
||||
@property (nonatomic) id pasteboardObserver;
|
||||
|
||||
@end
|
||||
|
||||
CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen);
|
||||
|
||||
#endif /* __OBJC__ */
|
||||
|
||||
void UIKit_SuspendScreenSaver(_THIS);
|
||||
|
||||
BOOL UIKit_IsSystemVersionAtLeast(double version);
|
||||
CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen);
|
||||
SDL_bool UIKit_IsSystemVersionAtLeast(double version);
|
||||
|
||||
#endif /* _SDL_uikitvideo_h */
|
||||
|
||||
|
|
|
|||
|
|
@ -36,9 +36,14 @@
|
|||
#include "SDL_uikitmodes.h"
|
||||
#include "SDL_uikitwindow.h"
|
||||
#include "SDL_uikitopengles.h"
|
||||
#include "SDL_uikitclipboard.h"
|
||||
|
||||
#define UIKITVID_DRIVER_NAME "uikit"
|
||||
|
||||
@implementation SDL_VideoData
|
||||
|
||||
@end
|
||||
|
||||
/* Initialization/Query functions */
|
||||
static int UIKit_VideoInit(_THIS);
|
||||
static void UIKit_VideoQuit(_THIS);
|
||||
|
|
@ -53,60 +58,75 @@ UIKit_Available(void)
|
|||
|
||||
static void UIKit_DeleteDevice(SDL_VideoDevice * device)
|
||||
{
|
||||
SDL_free(device);
|
||||
@autoreleasepool {
|
||||
CFRelease(device->driverdata);
|
||||
SDL_free(device);
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_VideoDevice *
|
||||
UIKit_CreateDevice(int devindex)
|
||||
{
|
||||
SDL_VideoDevice *device;
|
||||
@autoreleasepool {
|
||||
SDL_VideoDevice *device;
|
||||
SDL_VideoData *data;
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
|
||||
if (!device) {
|
||||
SDL_free(device);
|
||||
SDL_OutOfMemory();
|
||||
return (0);
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
|
||||
if (device) {
|
||||
data = [SDL_VideoData new];
|
||||
} else {
|
||||
SDL_free(device);
|
||||
SDL_OutOfMemory();
|
||||
return (0);
|
||||
}
|
||||
|
||||
device->driverdata = (void *) CFBridgingRetain(data);
|
||||
|
||||
/* Set the function pointers */
|
||||
device->VideoInit = UIKit_VideoInit;
|
||||
device->VideoQuit = UIKit_VideoQuit;
|
||||
device->GetDisplayModes = UIKit_GetDisplayModes;
|
||||
device->SetDisplayMode = UIKit_SetDisplayMode;
|
||||
device->PumpEvents = UIKit_PumpEvents;
|
||||
device->SuspendScreenSaver = UIKit_SuspendScreenSaver;
|
||||
device->CreateWindow = UIKit_CreateWindow;
|
||||
device->SetWindowTitle = UIKit_SetWindowTitle;
|
||||
device->ShowWindow = UIKit_ShowWindow;
|
||||
device->HideWindow = UIKit_HideWindow;
|
||||
device->RaiseWindow = UIKit_RaiseWindow;
|
||||
device->SetWindowBordered = UIKit_SetWindowBordered;
|
||||
device->SetWindowFullscreen = UIKit_SetWindowFullscreen;
|
||||
device->DestroyWindow = UIKit_DestroyWindow;
|
||||
device->GetWindowWMInfo = UIKit_GetWindowWMInfo;
|
||||
device->GetDisplayUsableBounds = UIKit_GetDisplayUsableBounds;
|
||||
|
||||
#if SDL_IPHONE_KEYBOARD
|
||||
device->HasScreenKeyboardSupport = UIKit_HasScreenKeyboardSupport;
|
||||
device->ShowScreenKeyboard = UIKit_ShowScreenKeyboard;
|
||||
device->HideScreenKeyboard = UIKit_HideScreenKeyboard;
|
||||
device->IsScreenKeyboardShown = UIKit_IsScreenKeyboardShown;
|
||||
device->SetTextInputRect = UIKit_SetTextInputRect;
|
||||
#endif
|
||||
|
||||
device->SetClipboardText = UIKit_SetClipboardText;
|
||||
device->GetClipboardText = UIKit_GetClipboardText;
|
||||
device->HasClipboardText = UIKit_HasClipboardText;
|
||||
|
||||
/* OpenGL (ES) functions */
|
||||
device->GL_MakeCurrent = UIKit_GL_MakeCurrent;
|
||||
device->GL_GetDrawableSize = UIKit_GL_GetDrawableSize;
|
||||
device->GL_SwapWindow = UIKit_GL_SwapWindow;
|
||||
device->GL_CreateContext = UIKit_GL_CreateContext;
|
||||
device->GL_DeleteContext = UIKit_GL_DeleteContext;
|
||||
device->GL_GetProcAddress = UIKit_GL_GetProcAddress;
|
||||
device->GL_LoadLibrary = UIKit_GL_LoadLibrary;
|
||||
device->free = UIKit_DeleteDevice;
|
||||
|
||||
device->gl_config.accelerated = 1;
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
/* Set the function pointers */
|
||||
device->VideoInit = UIKit_VideoInit;
|
||||
device->VideoQuit = UIKit_VideoQuit;
|
||||
device->GetDisplayModes = UIKit_GetDisplayModes;
|
||||
device->SetDisplayMode = UIKit_SetDisplayMode;
|
||||
device->PumpEvents = UIKit_PumpEvents;
|
||||
device->SuspendScreenSaver = UIKit_SuspendScreenSaver;
|
||||
device->CreateWindow = UIKit_CreateWindow;
|
||||
device->SetWindowTitle = UIKit_SetWindowTitle;
|
||||
device->ShowWindow = UIKit_ShowWindow;
|
||||
device->HideWindow = UIKit_HideWindow;
|
||||
device->RaiseWindow = UIKit_RaiseWindow;
|
||||
device->SetWindowBordered = UIKit_SetWindowBordered;
|
||||
device->SetWindowFullscreen = UIKit_SetWindowFullscreen;
|
||||
device->DestroyWindow = UIKit_DestroyWindow;
|
||||
device->GetWindowWMInfo = UIKit_GetWindowWMInfo;
|
||||
|
||||
#if SDL_IPHONE_KEYBOARD
|
||||
device->HasScreenKeyboardSupport = UIKit_HasScreenKeyboardSupport;
|
||||
device->ShowScreenKeyboard = UIKit_ShowScreenKeyboard;
|
||||
device->HideScreenKeyboard = UIKit_HideScreenKeyboard;
|
||||
device->IsScreenKeyboardShown = UIKit_IsScreenKeyboardShown;
|
||||
device->SetTextInputRect = UIKit_SetTextInputRect;
|
||||
#endif
|
||||
|
||||
/* OpenGL (ES) functions */
|
||||
device->GL_MakeCurrent = UIKit_GL_MakeCurrent;
|
||||
device->GL_GetDrawableSize = UIKit_GL_GetDrawableSize;
|
||||
device->GL_SwapWindow = UIKit_GL_SwapWindow;
|
||||
device->GL_CreateContext = UIKit_GL_CreateContext;
|
||||
device->GL_DeleteContext = UIKit_GL_DeleteContext;
|
||||
device->GL_GetProcAddress = UIKit_GL_GetProcAddress;
|
||||
device->GL_LoadLibrary = UIKit_GL_LoadLibrary;
|
||||
device->free = UIKit_DeleteDevice;
|
||||
|
||||
device->gl_config.accelerated = 1;
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
VideoBootStrap UIKIT_bootstrap = {
|
||||
|
|
@ -138,7 +158,7 @@ UIKit_SuspendScreenSaver(_THIS)
|
|||
@autoreleasepool {
|
||||
/* Ignore ScreenSaver API calls if the idle timer hint has been set. */
|
||||
/* FIXME: The idle timer hint should be deprecated for SDL 2.1. */
|
||||
if (SDL_GetHint(SDL_HINT_IDLE_TIMER_DISABLED) == NULL) {
|
||||
if (!SDL_GetHintBoolean(SDL_HINT_IDLE_TIMER_DISABLED, SDL_FALSE)) {
|
||||
UIApplication *app = [UIApplication sharedApplication];
|
||||
|
||||
/* Prevent the display from dimming and going to sleep. */
|
||||
|
|
@ -147,7 +167,7 @@ UIKit_SuspendScreenSaver(_THIS)
|
|||
}
|
||||
}
|
||||
|
||||
BOOL
|
||||
SDL_bool
|
||||
UIKit_IsSystemVersionAtLeast(double version)
|
||||
{
|
||||
return [[UIDevice currentDevice].systemVersion doubleValue] >= version;
|
||||
|
|
@ -156,6 +176,7 @@ UIKit_IsSystemVersionAtLeast(double version)
|
|||
CGRect
|
||||
UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen)
|
||||
{
|
||||
#if !TARGET_OS_TV && (__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0)
|
||||
BOOL hasiOS7 = UIKit_IsSystemVersionAtLeast(7.0);
|
||||
|
||||
if (hasiOS7 || (window->flags & (SDL_WINDOW_BORDERLESS|SDL_WINDOW_FULLSCREEN))) {
|
||||
|
|
@ -164,6 +185,9 @@ UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen)
|
|||
} else {
|
||||
return screen.applicationFrame;
|
||||
}
|
||||
#else
|
||||
return screen.bounds;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -45,7 +45,9 @@
|
|||
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
self.autoresizesSubviews = YES;
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
self.multipleTouchEnabled = YES;
|
||||
#endif
|
||||
|
||||
touchId = 1;
|
||||
SDL_AddTouch(touchId, "");
|
||||
|
|
@ -141,12 +143,13 @@
|
|||
|
||||
if (!firstFingerDown) {
|
||||
CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
|
||||
int clicks = (int) touch.tapCount;
|
||||
|
||||
/* send mouse moved event */
|
||||
SDL_SendMouseMotion(sdlwindow, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
|
||||
|
||||
/* send mouse down event */
|
||||
SDL_SendMouseButton(sdlwindow, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
|
||||
SDL_SendMouseButtonClicks(sdlwindow, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT, clicks);
|
||||
|
||||
firstFingerDown = touch;
|
||||
}
|
||||
|
|
@ -164,7 +167,8 @@
|
|||
|
||||
if (touch == firstFingerDown) {
|
||||
/* send mouse up */
|
||||
SDL_SendMouseButton(sdlwindow, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
|
||||
int clicks = (int) touch.tapCount;
|
||||
SDL_SendMouseButtonClicks(sdlwindow, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT, clicks);
|
||||
firstFingerDown = nil;
|
||||
}
|
||||
|
||||
|
|
@ -197,6 +201,69 @@
|
|||
}
|
||||
}
|
||||
|
||||
#if TARGET_OS_TV || defined(__IPHONE_9_1)
|
||||
- (SDL_Scancode)scancodeFromPressType:(UIPressType)presstype
|
||||
{
|
||||
switch (presstype) {
|
||||
case UIPressTypeUpArrow:
|
||||
return SDL_SCANCODE_UP;
|
||||
case UIPressTypeDownArrow:
|
||||
return SDL_SCANCODE_DOWN;
|
||||
case UIPressTypeLeftArrow:
|
||||
return SDL_SCANCODE_LEFT;
|
||||
case UIPressTypeRightArrow:
|
||||
return SDL_SCANCODE_RIGHT;
|
||||
case UIPressTypeSelect:
|
||||
/* HIG says: "primary button behavior" */
|
||||
return SDL_SCANCODE_SELECT;
|
||||
case UIPressTypeMenu:
|
||||
/* HIG says: "returns to previous screen" */
|
||||
return SDL_SCANCODE_MENU;
|
||||
case UIPressTypePlayPause:
|
||||
/* HIG says: "secondary button behavior" */
|
||||
return SDL_SCANCODE_PAUSE;
|
||||
default:
|
||||
return SDL_SCANCODE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
|
||||
{
|
||||
for (UIPress *press in presses) {
|
||||
SDL_Scancode scancode = [self scancodeFromPressType:press.type];
|
||||
SDL_SendKeyboardKey(SDL_PRESSED, scancode);
|
||||
}
|
||||
|
||||
[super pressesBegan:presses withEvent:event];
|
||||
}
|
||||
|
||||
- (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
|
||||
{
|
||||
for (UIPress *press in presses) {
|
||||
SDL_Scancode scancode = [self scancodeFromPressType:press.type];
|
||||
SDL_SendKeyboardKey(SDL_RELEASED, scancode);
|
||||
}
|
||||
|
||||
[super pressesEnded:presses withEvent:event];
|
||||
}
|
||||
|
||||
- (void)pressesCancelled:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
|
||||
{
|
||||
for (UIPress *press in presses) {
|
||||
SDL_Scancode scancode = [self scancodeFromPressType:press.type];
|
||||
SDL_SendKeyboardKey(SDL_RELEASED, scancode);
|
||||
}
|
||||
|
||||
[super pressesCancelled:presses withEvent:event];
|
||||
}
|
||||
|
||||
- (void)pressesChanged:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
|
||||
{
|
||||
/* This is only called when the force of a press changes. */
|
||||
[super pressesChanged:presses withEvent:event];
|
||||
}
|
||||
#endif /* TARGET_OS_TV || defined(__IPHONE_9_1) */
|
||||
|
||||
@end
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_UIKIT */
|
||||
|
|
|
|||
|
|
@ -1,23 +1,24 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2016 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.
|
||||
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:
|
||||
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.
|
||||
*/
|
||||
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"
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
|
@ -25,10 +26,17 @@
|
|||
|
||||
#include "SDL_touch.h"
|
||||
|
||||
#if SDL_IPHONE_KEYBOARD
|
||||
@interface SDL_uikitviewcontroller : UIViewController <UITextFieldDelegate>
|
||||
#if TARGET_OS_TV
|
||||
#import <GameController/GameController.h>
|
||||
#define SDLRootViewController GCEventViewController
|
||||
#else
|
||||
@interface SDL_uikitviewcontroller : UIViewController
|
||||
#define SDLRootViewController UIViewController
|
||||
#endif
|
||||
|
||||
#if SDL_IPHONE_KEYBOARD
|
||||
@interface SDL_uikitviewcontroller : SDLRootViewController <UITextFieldDelegate>
|
||||
#else
|
||||
@interface SDL_uikitviewcontroller : SDLRootViewController
|
||||
#endif
|
||||
|
||||
@property (nonatomic, assign) SDL_Window *window;
|
||||
|
|
@ -46,8 +54,11 @@
|
|||
|
||||
- (void)loadView;
|
||||
- (void)viewDidLayoutSubviews;
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
- (NSUInteger)supportedInterfaceOrientations;
|
||||
- (BOOL)prefersStatusBarHidden;
|
||||
#endif
|
||||
|
||||
#if SDL_IPHONE_KEYBOARD
|
||||
- (void)showKeyboard;
|
||||
|
|
|
|||
|
|
@ -33,11 +33,23 @@
|
|||
#include "SDL_uikitvideo.h"
|
||||
#include "SDL_uikitmodes.h"
|
||||
#include "SDL_uikitwindow.h"
|
||||
#include "SDL_uikitopengles.h"
|
||||
|
||||
#if SDL_IPHONE_KEYBOARD
|
||||
#include "keyinfotable.h"
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_TV
|
||||
static void
|
||||
SDL_AppleTVControllerUIHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
|
||||
{
|
||||
@autoreleasepool {
|
||||
SDL_uikitviewcontroller *viewcontroller = (__bridge SDL_uikitviewcontroller *) userdata;
|
||||
viewcontroller.controllerUserInteractionEnabled = hint && (*hint != '0');
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@implementation SDL_uikitviewcontroller {
|
||||
CADisplayLink *displayLink;
|
||||
int animationInterval;
|
||||
|
|
@ -59,6 +71,12 @@
|
|||
#if SDL_IPHONE_KEYBOARD
|
||||
[self initKeyboard];
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_TV
|
||||
SDL_AddHintCallback(SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS,
|
||||
SDL_AppleTVControllerUIHintChanged,
|
||||
(__bridge void *) self);
|
||||
#endif
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
|
@ -68,6 +86,12 @@
|
|||
#if SDL_IPHONE_KEYBOARD
|
||||
[self deinitKeyboard];
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_TV
|
||||
SDL_DelHintCallback(SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS,
|
||||
SDL_AppleTVControllerUIHintChanged,
|
||||
(__bridge void *) self);
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)setAnimationCallback:(int)interval
|
||||
|
|
@ -102,6 +126,9 @@
|
|||
{
|
||||
/* Don't run the game loop while a messagebox is up */
|
||||
if (!UIKit_ShowingMessageBox()) {
|
||||
/* See the comment in the function definition. */
|
||||
UIKit_GL_RestoreCurrentContext();
|
||||
|
||||
animationCallback(animationCallbackParam);
|
||||
}
|
||||
}
|
||||
|
|
@ -120,6 +147,7 @@
|
|||
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, w, h);
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
- (NSUInteger)supportedInterfaceOrientations
|
||||
{
|
||||
return UIKit_GetSupportedOrientations(window);
|
||||
|
|
@ -134,6 +162,7 @@
|
|||
{
|
||||
return (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) != 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
---- Keyboard related functionality below this line ----
|
||||
|
|
@ -164,9 +193,11 @@
|
|||
textField.hidden = YES;
|
||||
keyboardVisible = NO;
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||
[center addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
|
||||
[center addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)setView:(UIView *)view
|
||||
|
|
@ -182,9 +213,11 @@
|
|||
|
||||
- (void)deinitKeyboard
|
||||
{
|
||||
#if !TARGET_OS_TV
|
||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||
[center removeObserver:self name:UIKeyboardWillShowNotification object:nil];
|
||||
[center removeObserver:self name:UIKeyboardWillHideNotification object:nil];
|
||||
#endif
|
||||
}
|
||||
|
||||
/* reveal onscreen virtual keyboard */
|
||||
|
|
@ -205,6 +238,7 @@
|
|||
|
||||
- (void)keyboardWillShow:(NSNotification *)notification
|
||||
{
|
||||
#if !TARGET_OS_TV
|
||||
CGRect kbrect = [[notification userInfo][UIKeyboardFrameBeginUserInfoKey] CGRectValue];
|
||||
|
||||
/* The keyboard rect is in the coordinate space of the screen/window, but we
|
||||
|
|
@ -212,10 +246,12 @@
|
|||
kbrect = [self.view convertRect:kbrect fromView:nil];
|
||||
|
||||
[self setKeyboardHeight:(int)kbrect.size.height];
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)keyboardWillHide:(NSNotification *)notification
|
||||
{
|
||||
SDL_StopTextInput();
|
||||
[self setKeyboardHeight:0];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -99,14 +99,13 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo
|
|||
/* only one window on iOS, always shown */
|
||||
window->flags &= ~SDL_WINDOW_HIDDEN;
|
||||
|
||||
if (displaydata.uiscreen == [UIScreen mainScreen]) {
|
||||
window->flags |= SDL_WINDOW_INPUT_FOCUS; /* always has input focus */
|
||||
} else {
|
||||
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. */
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
if (displaydata.uiscreen == [UIScreen mainScreen]) {
|
||||
NSUInteger orients = UIKit_GetSupportedOrientations(window);
|
||||
BOOL supportsLandscape = (orients & UIInterfaceOrientationMaskLandscape) != 0;
|
||||
|
|
@ -119,6 +118,7 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo
|
|||
height = temp;
|
||||
}
|
||||
}
|
||||
#endif /* !TARGET_OS_TV */
|
||||
|
||||
window->x = 0;
|
||||
window->y = 0;
|
||||
|
|
@ -152,7 +152,6 @@ UIKit_CreateWindow(_THIS, SDL_Window *window)
|
|||
@autoreleasepool {
|
||||
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
|
||||
SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
|
||||
const CGSize origsize = data.uiscreen.currentMode.size;
|
||||
|
||||
/* SDL currently puts this window at the start of display's linked list. We rely on this. */
|
||||
SDL_assert(_this->windows == window);
|
||||
|
|
@ -165,6 +164,8 @@ UIKit_CreateWindow(_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
|
||||
const CGSize origsize = data.uiscreen.currentMode.size;
|
||||
if ((origsize.width == 0.0f) && (origsize.height == 0.0f)) {
|
||||
if (display->num_display_modes == 0) {
|
||||
_this->GetDisplayModes(_this, display);
|
||||
|
|
@ -197,6 +198,7 @@ UIKit_CreateWindow(_THIS, SDL_Window *window)
|
|||
[UIApplication sharedApplication].statusBarHidden = NO;
|
||||
}
|
||||
}
|
||||
#endif /* !TARGET_OS_TV */
|
||||
|
||||
/* ignore the size user requested, and make a fullscreen window */
|
||||
/* !!! FIXME: can we have a smaller view? */
|
||||
|
|
@ -258,6 +260,7 @@ UIKit_UpdateWindowBorder(_THIS, SDL_Window * window)
|
|||
SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
|
||||
SDL_uikitviewcontroller *viewcontroller = data.viewcontroller;
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
if (data.uiwindow.screen == [UIScreen mainScreen]) {
|
||||
if (window->flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS)) {
|
||||
[UIApplication sharedApplication].statusBarHidden = YES;
|
||||
|
|
@ -273,6 +276,7 @@ UIKit_UpdateWindowBorder(_THIS, SDL_Window * window)
|
|||
|
||||
/* Update the view's frame to account for the status bar change. */
|
||||
viewcontroller.view.frame = UIKit_ComputeViewFrame(window, data.uiwindow.screen);
|
||||
#endif /* !TARGET_OS_TV */
|
||||
|
||||
#ifdef SDL_IPHONE_KEYBOARD
|
||||
/* Make sure the view is offset correctly when the keyboard is visible. */
|
||||
|
|
@ -363,6 +367,7 @@ UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
|
|||
}
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
NSUInteger
|
||||
UIKit_GetSupportedOrientations(SDL_Window * window)
|
||||
{
|
||||
|
|
@ -428,6 +433,7 @@ UIKit_GetSupportedOrientations(SDL_Window * window)
|
|||
|
||||
return orientationMask;
|
||||
}
|
||||
#endif /* !TARGET_OS_TV */
|
||||
|
||||
int
|
||||
SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam)
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ VIVANTE_Create()
|
|||
|
||||
device->driverdata = data;
|
||||
|
||||
/* Setup amount of available displays and current display */
|
||||
/* Setup amount of available displays */
|
||||
device->num_displays = 0;
|
||||
|
||||
/* Set device free function */
|
||||
|
|
@ -366,12 +366,13 @@ VIVANTE_HideWindow(_THIS, SDL_Window * window)
|
|||
SDL_bool
|
||||
VIVANTE_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
|
||||
{
|
||||
/*
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
SDL_DisplayData *displaydata = SDL_GetDisplayDriverData(0);
|
||||
|
||||
if (info->version.major == SDL_MAJOR_VERSION &&
|
||||
info->version.minor == SDL_MINOR_VERSION) {
|
||||
info->subsystem = SDL_SYSWM_VIVANTE;
|
||||
info->info.vivante.display = displaydata->native_display;
|
||||
info->info.vivante.window = data->native_window;
|
||||
return SDL_TRUE;
|
||||
} else {
|
||||
|
|
@ -379,9 +380,6 @@ VIVANTE_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
|
|||
SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
|
||||
return SDL_FALSE;
|
||||
}
|
||||
*/
|
||||
SDL_Unsupported();
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -94,9 +94,6 @@ WAYLAND_GetSym(const char *fnname, int *pHasModule)
|
|||
#define SDL_WAYLAND_SYM(rc,fn,params) SDL_DYNWAYLANDFN_##fn WAYLAND_##fn = NULL;
|
||||
#define SDL_WAYLAND_INTERFACE(iface) const struct wl_interface *WAYLAND_##iface = NULL;
|
||||
#include "SDL_waylandsym.h"
|
||||
#undef SDL_WAYLAND_MODULE
|
||||
#undef SDL_WAYLAND_SYM
|
||||
#undef SDL_WAYLAND_INTERFACE
|
||||
|
||||
static int wayland_load_refcount = 0;
|
||||
|
||||
|
|
@ -115,9 +112,6 @@ SDL_WAYLAND_UnloadSymbols(void)
|
|||
#define SDL_WAYLAND_SYM(rc,fn,params) WAYLAND_##fn = NULL;
|
||||
#define SDL_WAYLAND_INTERFACE(iface) WAYLAND_##iface = NULL;
|
||||
#include "SDL_waylandsym.h"
|
||||
#undef SDL_WAYLAND_MODULE
|
||||
#undef SDL_WAYLAND_SYM
|
||||
#undef SDL_WAYLAND_INTERFACE
|
||||
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC
|
||||
|
|
@ -150,20 +144,12 @@ SDL_WAYLAND_LoadSymbols(void)
|
|||
}
|
||||
|
||||
#define SDL_WAYLAND_MODULE(modname) SDL_WAYLAND_HAVE_##modname = 1; /* default yes */
|
||||
#define SDL_WAYLAND_SYM(rc,fn,params)
|
||||
#define SDL_WAYLAND_INTERFACE(iface)
|
||||
#include "SDL_waylandsym.h"
|
||||
#undef SDL_WAYLAND_MODULE
|
||||
#undef SDL_WAYLAND_SYM
|
||||
#undef SDL_WAYLAND_INTERFACE
|
||||
|
||||
#define SDL_WAYLAND_MODULE(modname) thismod = &SDL_WAYLAND_HAVE_##modname;
|
||||
#define SDL_WAYLAND_SYM(rc,fn,params) WAYLAND_##fn = (SDL_DYNWAYLANDFN_##fn) WAYLAND_GetSym(#fn,thismod);
|
||||
#define SDL_WAYLAND_INTERFACE(iface) WAYLAND_##iface = (struct wl_interface *) WAYLAND_GetSym(#iface,thismod);
|
||||
#include "SDL_waylandsym.h"
|
||||
#undef SDL_WAYLAND_MODULE
|
||||
#undef SDL_WAYLAND_SYM
|
||||
#undef SDL_WAYLAND_INTERFACE
|
||||
|
||||
if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT) {
|
||||
/* all required symbols loaded. */
|
||||
|
|
@ -180,9 +166,6 @@ SDL_WAYLAND_LoadSymbols(void)
|
|||
#define SDL_WAYLAND_SYM(rc,fn,params) WAYLAND_##fn = fn;
|
||||
#define SDL_WAYLAND_INTERFACE(iface) WAYLAND_##iface = &iface;
|
||||
#include "SDL_waylandsym.h"
|
||||
#undef SDL_WAYLAND_MODULE
|
||||
#undef SDL_WAYLAND_SYM
|
||||
#undef SDL_WAYLAND_INTERFACE
|
||||
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,10 +53,7 @@ void SDL_WAYLAND_UnloadSymbols(void);
|
|||
extern SDL_DYNWAYLANDFN_##fn WAYLAND_##fn;
|
||||
#define SDL_WAYLAND_INTERFACE(iface) extern const struct wl_interface *WAYLAND_##iface;
|
||||
#include "SDL_waylandsym.h"
|
||||
#undef SDL_WAYLAND_MODULE
|
||||
#undef SDL_WAYLAND_SYM
|
||||
#undef SDL_WAYLAND_INTERFACE
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
@ -79,6 +76,7 @@ void SDL_WAYLAND_UnloadSymbols(void);
|
|||
#define wl_proxy_get_user_data (*WAYLAND_wl_proxy_get_user_data)
|
||||
#define wl_proxy_add_listener (*WAYLAND_wl_proxy_add_listener)
|
||||
#define wl_proxy_marshal_constructor (*WAYLAND_wl_proxy_marshal_constructor)
|
||||
#define wl_proxy_marshal_constructor_versioned (*WAYLAND_wl_proxy_marshal_constructor_versioned)
|
||||
|
||||
#define wl_seat_interface (*WAYLAND_wl_seat_interface)
|
||||
#define wl_surface_interface (*WAYLAND_wl_surface_interface)
|
||||
|
|
@ -96,7 +94,8 @@ void SDL_WAYLAND_UnloadSymbols(void);
|
|||
|
||||
#endif /* SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC */
|
||||
|
||||
#include "wayland-client.h"
|
||||
#include "wayland-client-core.h"
|
||||
#include "wayland-client-protocol.h"
|
||||
#include "wayland-egl.h"
|
||||
|
||||
#endif /* !defined _SDL_waylanddyn_h */
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "SDL_stdinc.h"
|
||||
#include "SDL_assert.h"
|
||||
#include "SDL_log.h"
|
||||
|
||||
#include "../../events/SDL_sysevents.h"
|
||||
#include "../../events/SDL_events_c.h"
|
||||
|
|
@ -36,11 +37,13 @@
|
|||
|
||||
#include "SDL_waylanddyn.h"
|
||||
|
||||
#include "pointer-constraints-unstable-v1-client-protocol.h"
|
||||
#include "relative-pointer-unstable-v1-client-protocol.h"
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/mman.h>
|
||||
#include <poll.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
|
|
@ -49,13 +52,17 @@ struct SDL_WaylandInput {
|
|||
struct wl_seat *seat;
|
||||
struct wl_pointer *pointer;
|
||||
struct wl_keyboard *keyboard;
|
||||
struct zwp_relative_pointer_v1 *relative_pointer;
|
||||
SDL_WindowData *pointer_focus;
|
||||
SDL_WindowData *keyboard_focus;
|
||||
|
||||
/* Last motion location */
|
||||
wl_fixed_t sx_w;
|
||||
wl_fixed_t sy_w;
|
||||
|
||||
|
||||
double dx_frac;
|
||||
double dy_frac;
|
||||
|
||||
struct {
|
||||
struct xkb_keymap *keymap;
|
||||
struct xkb_state *state;
|
||||
|
|
@ -171,10 +178,9 @@ ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial)
|
|||
}
|
||||
|
||||
static void
|
||||
pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
|
||||
uint32_t time, uint32_t button, uint32_t state_w)
|
||||
pointer_handle_button_common(struct SDL_WaylandInput *input, uint32_t serial,
|
||||
uint32_t time, uint32_t button, uint32_t state_w)
|
||||
{
|
||||
struct SDL_WaylandInput *input = data;
|
||||
SDL_WindowData *window = input->pointer_focus;
|
||||
enum wl_pointer_button_state state = state_w;
|
||||
uint32_t sdl_button;
|
||||
|
|
@ -183,7 +189,7 @@ pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
|
|||
switch (button) {
|
||||
case BTN_LEFT:
|
||||
sdl_button = SDL_BUTTON_LEFT;
|
||||
if (ProcessHitTest(data, serial)) {
|
||||
if (ProcessHitTest(input, serial)) {
|
||||
return; /* don't pass this event on to app. */
|
||||
}
|
||||
break;
|
||||
|
|
@ -209,10 +215,18 @@ pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
|
|||
}
|
||||
|
||||
static void
|
||||
pointer_handle_axis(void *data, struct wl_pointer *pointer,
|
||||
uint32_t time, uint32_t axis, wl_fixed_t value)
|
||||
pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
|
||||
uint32_t time, uint32_t button, uint32_t state_w)
|
||||
{
|
||||
struct SDL_WaylandInput *input = data;
|
||||
|
||||
pointer_handle_button_common(input, serial, time, button, state_w);
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_handle_axis_common(struct SDL_WaylandInput *input,
|
||||
uint32_t time, uint32_t axis, wl_fixed_t value)
|
||||
{
|
||||
SDL_WindowData *window = input->pointer_focus;
|
||||
enum wl_pointer_axis a = axis;
|
||||
int x, y;
|
||||
|
|
@ -235,6 +249,15 @@ pointer_handle_axis(void *data, struct wl_pointer *pointer,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_handle_axis(void *data, struct wl_pointer *pointer,
|
||||
uint32_t time, uint32_t axis, wl_fixed_t value)
|
||||
{
|
||||
struct SDL_WaylandInput *input = data;
|
||||
|
||||
pointer_handle_axis_common(input, time, axis, value);
|
||||
}
|
||||
|
||||
static const struct wl_pointer_listener pointer_listener = {
|
||||
pointer_handle_enter,
|
||||
pointer_handle_leave,
|
||||
|
|
@ -302,9 +325,9 @@ keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
|
|||
|
||||
window = wl_surface_get_user_data(surface);
|
||||
|
||||
input->keyboard_focus = window;
|
||||
window->keyboard_device = input;
|
||||
if (window) {
|
||||
input->keyboard_focus = window;
|
||||
window->keyboard_device = input;
|
||||
SDL_SetKeyboardFocus(window->sdlwindow);
|
||||
}
|
||||
}
|
||||
|
|
@ -454,6 +477,164 @@ void Wayland_display_destroy_input(SDL_VideoData *d)
|
|||
d->input = NULL;
|
||||
}
|
||||
|
||||
void Wayland_display_add_relative_pointer_manager(SDL_VideoData *d, uint32_t id)
|
||||
{
|
||||
d->relative_pointer_manager =
|
||||
wl_registry_bind(d->registry, id,
|
||||
&zwp_relative_pointer_manager_v1_interface, 1);
|
||||
}
|
||||
|
||||
void Wayland_display_destroy_relative_pointer_manager(SDL_VideoData *d)
|
||||
{
|
||||
if (d->relative_pointer_manager)
|
||||
zwp_relative_pointer_manager_v1_destroy(d->relative_pointer_manager);
|
||||
}
|
||||
|
||||
void Wayland_display_add_pointer_constraints(SDL_VideoData *d, uint32_t id)
|
||||
{
|
||||
d->pointer_constraints =
|
||||
wl_registry_bind(d->registry, id,
|
||||
&zwp_pointer_constraints_v1_interface, 1);
|
||||
}
|
||||
|
||||
void Wayland_display_destroy_pointer_constraints(SDL_VideoData *d)
|
||||
{
|
||||
if (d->pointer_constraints)
|
||||
zwp_pointer_constraints_v1_destroy(d->pointer_constraints);
|
||||
}
|
||||
|
||||
static void
|
||||
relative_pointer_handle_relative_motion(void *data,
|
||||
struct zwp_relative_pointer_v1 *pointer,
|
||||
uint32_t time_hi,
|
||||
uint32_t time_lo,
|
||||
wl_fixed_t dx_w,
|
||||
wl_fixed_t dy_w,
|
||||
wl_fixed_t dx_unaccel_w,
|
||||
wl_fixed_t dy_unaccel_w)
|
||||
{
|
||||
struct SDL_WaylandInput *input = data;
|
||||
SDL_VideoData *d = input->display;
|
||||
SDL_WindowData *window = input->pointer_focus;
|
||||
double dx_unaccel;
|
||||
double dy_unaccel;
|
||||
double dx;
|
||||
double dy;
|
||||
|
||||
dx_unaccel = wl_fixed_to_double(dx_unaccel_w);
|
||||
dy_unaccel = wl_fixed_to_double(dy_unaccel_w);
|
||||
|
||||
/* Add left over fraction from last event. */
|
||||
dx_unaccel += input->dx_frac;
|
||||
dy_unaccel += input->dy_frac;
|
||||
|
||||
input->dx_frac = modf(dx_unaccel, &dx);
|
||||
input->dy_frac = modf(dy_unaccel, &dy);
|
||||
|
||||
if (input->pointer_focus && d->relative_mouse_mode) {
|
||||
SDL_SendMouseMotion(window->sdlwindow, 0, 1, (int)dx, (int)dy);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct zwp_relative_pointer_v1_listener relative_pointer_listener = {
|
||||
relative_pointer_handle_relative_motion,
|
||||
};
|
||||
|
||||
static void
|
||||
locked_pointer_locked(void *data,
|
||||
struct zwp_locked_pointer_v1 *locked_pointer)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
locked_pointer_unlocked(void *data,
|
||||
struct zwp_locked_pointer_v1 *locked_pointer)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct zwp_locked_pointer_v1_listener locked_pointer_listener = {
|
||||
locked_pointer_locked,
|
||||
locked_pointer_unlocked,
|
||||
};
|
||||
|
||||
static void
|
||||
lock_pointer_to_window(SDL_Window *window,
|
||||
struct SDL_WaylandInput *input)
|
||||
{
|
||||
SDL_WindowData *w = window->driverdata;
|
||||
SDL_VideoData *d = input->display;
|
||||
struct zwp_locked_pointer_v1 *locked_pointer;
|
||||
|
||||
if (w->locked_pointer)
|
||||
return;
|
||||
|
||||
locked_pointer =
|
||||
zwp_pointer_constraints_v1_lock_pointer(d->pointer_constraints,
|
||||
w->surface,
|
||||
input->pointer,
|
||||
NULL,
|
||||
ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
|
||||
zwp_locked_pointer_v1_add_listener(locked_pointer,
|
||||
&locked_pointer_listener,
|
||||
window);
|
||||
|
||||
w->locked_pointer = locked_pointer;
|
||||
}
|
||||
|
||||
int Wayland_input_lock_pointer(struct SDL_WaylandInput *input)
|
||||
{
|
||||
SDL_VideoDevice *vd = SDL_GetVideoDevice();
|
||||
SDL_VideoData *d = input->display;
|
||||
SDL_Window *window;
|
||||
struct zwp_relative_pointer_v1 *relative_pointer;
|
||||
|
||||
if (!d->relative_pointer_manager)
|
||||
return -1;
|
||||
|
||||
if (!d->pointer_constraints)
|
||||
return -1;
|
||||
|
||||
if (!input->relative_pointer) {
|
||||
relative_pointer =
|
||||
zwp_relative_pointer_manager_v1_get_relative_pointer(
|
||||
d->relative_pointer_manager,
|
||||
input->pointer);
|
||||
zwp_relative_pointer_v1_add_listener(relative_pointer,
|
||||
&relative_pointer_listener,
|
||||
input);
|
||||
input->relative_pointer = relative_pointer;
|
||||
}
|
||||
|
||||
for (window = vd->windows; window; window = window->next)
|
||||
lock_pointer_to_window(window, input);
|
||||
|
||||
d->relative_mouse_mode = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input)
|
||||
{
|
||||
SDL_VideoDevice *vd = SDL_GetVideoDevice();
|
||||
SDL_VideoData *d = input->display;
|
||||
SDL_Window *window;
|
||||
SDL_WindowData *w;
|
||||
|
||||
for (window = vd->windows; window; window = window->next) {
|
||||
w = window->driverdata;
|
||||
if (w->locked_pointer)
|
||||
zwp_locked_pointer_v1_destroy(w->locked_pointer);
|
||||
w->locked_pointer = NULL;
|
||||
}
|
||||
|
||||
zwp_relative_pointer_v1_destroy(input->relative_pointer);
|
||||
input->relative_pointer = NULL;
|
||||
|
||||
d->relative_mouse_mode = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_WAYLAND */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
|||
|
|
@ -32,6 +32,15 @@ extern void Wayland_PumpEvents(_THIS);
|
|||
extern void Wayland_display_add_input(SDL_VideoData *d, uint32_t id);
|
||||
extern void Wayland_display_destroy_input(SDL_VideoData *d);
|
||||
|
||||
extern void Wayland_display_add_pointer_constraints(SDL_VideoData *d, uint32_t id);
|
||||
extern void Wayland_display_destroy_pointer_constraints(SDL_VideoData *d);
|
||||
|
||||
extern int Wayland_input_lock_pointer(struct SDL_WaylandInput *input);
|
||||
extern int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input);
|
||||
|
||||
extern void Wayland_display_add_relative_pointer_manager(SDL_VideoData *d, uint32_t id);
|
||||
extern void Wayland_display_destroy_relative_pointer_manager(SDL_VideoData *d);
|
||||
|
||||
#endif /* _SDL_waylandevents_h */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
|
|
@ -70,7 +69,6 @@ wayland_create_tmp_file(off_t size)
|
|||
|
||||
xdg_path = SDL_getenv("XDG_RUNTIME_DIR");
|
||||
if (!xdg_path) {
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -116,8 +114,7 @@ create_buffer_from_shm(Wayland_CursorData *d,
|
|||
shm_fd = wayland_create_tmp_file(size);
|
||||
if (shm_fd < 0)
|
||||
{
|
||||
fprintf(stderr, "creating mouse cursor buffer failed!\n");
|
||||
return -1;
|
||||
return SDL_SetError("Creating mouse cursor buffer failed.");
|
||||
}
|
||||
|
||||
d->shm_data = mmap(NULL,
|
||||
|
|
@ -128,8 +125,8 @@ create_buffer_from_shm(Wayland_CursorData *d,
|
|||
0);
|
||||
if (d->shm_data == MAP_FAILED) {
|
||||
d->shm_data = NULL;
|
||||
fprintf (stderr, "mmap () failed\n");
|
||||
close (shm_fd);
|
||||
return SDL_SetError("mmap() failed.");
|
||||
}
|
||||
|
||||
shm_pool = wl_shm_create_pool(data->shm, shm_fd, size);
|
||||
|
|
@ -159,6 +156,11 @@ Wayland_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
|
|||
SDL_VideoDevice *vd = SDL_GetVideoDevice ();
|
||||
SDL_VideoData *wd = (SDL_VideoData *) vd->driverdata;
|
||||
Wayland_CursorData *data = calloc (1, sizeof (Wayland_CursorData));
|
||||
if (!data) {
|
||||
SDL_OutOfMemory();
|
||||
free(cursor);
|
||||
return NULL;
|
||||
}
|
||||
cursor->driverdata = (void *) data;
|
||||
|
||||
/* Assume ARGB8888 */
|
||||
|
|
@ -169,7 +171,7 @@ Wayland_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
|
|||
if (create_buffer_from_shm (data,
|
||||
surface->w,
|
||||
surface->h,
|
||||
WL_SHM_FORMAT_XRGB8888) < 0)
|
||||
WL_SHM_FORMAT_ARGB8888) < 0)
|
||||
{
|
||||
free (cursor->driverdata);
|
||||
free (cursor);
|
||||
|
|
@ -187,6 +189,8 @@ Wayland_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
|
|||
data->hot_y = hot_y;
|
||||
data->w = surface->w;
|
||||
data->h = surface->h;
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
return cursor;
|
||||
|
|
@ -200,6 +204,11 @@ CreateCursorFromWlCursor(SDL_VideoData *d, struct wl_cursor *wlcursor)
|
|||
cursor = calloc(1, sizeof (*cursor));
|
||||
if (cursor) {
|
||||
Wayland_CursorData *data = calloc (1, sizeof (Wayland_CursorData));
|
||||
if (!data) {
|
||||
SDL_OutOfMemory();
|
||||
free(cursor);
|
||||
return NULL;
|
||||
}
|
||||
cursor->driverdata = (void *) data;
|
||||
|
||||
data->buffer = WAYLAND_wl_cursor_image_get_buffer(wlcursor->images[0]);
|
||||
|
|
@ -322,13 +331,13 @@ Wayland_ShowCursor(SDL_Cursor *cursor)
|
|||
{
|
||||
Wayland_CursorData *data = cursor->driverdata;
|
||||
|
||||
wl_surface_attach(data->surface, data->buffer, 0, 0);
|
||||
wl_surface_damage(data->surface, 0, 0, data->w, data->h);
|
||||
wl_surface_commit(data->surface);
|
||||
wl_pointer_set_cursor (pointer, 0,
|
||||
data->surface,
|
||||
data->hot_x,
|
||||
data->hot_y);
|
||||
wl_surface_attach(data->surface, data->buffer, 0, 0);
|
||||
wl_surface_damage(data->surface, 0, 0, data->w, data->h);
|
||||
wl_surface_commit(data->surface);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -356,7 +365,13 @@ Wayland_WarpMouseGlobal(int x, int y)
|
|||
static int
|
||||
Wayland_SetRelativeMouseMode(SDL_bool enabled)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
SDL_VideoDevice *vd = SDL_GetVideoDevice();
|
||||
SDL_VideoData *data = (SDL_VideoData *) vd->driverdata;
|
||||
|
||||
if (enabled)
|
||||
return Wayland_input_lock_pointer(data->input);
|
||||
else
|
||||
return Wayland_input_unlock_pointer(data->input);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -21,6 +21,18 @@
|
|||
|
||||
/* *INDENT-OFF* */
|
||||
|
||||
#ifndef SDL_WAYLAND_MODULE
|
||||
#define SDL_WAYLAND_MODULE(modname)
|
||||
#endif
|
||||
|
||||
#ifndef SDL_WAYLAND_SYM
|
||||
#define SDL_WAYLAND_SYM(rc,fn,params)
|
||||
#endif
|
||||
|
||||
#ifndef SDL_WAYLAND_INTERFACE
|
||||
#define SDL_WAYLAND_INTERFACE(iface)
|
||||
#endif
|
||||
|
||||
SDL_WAYLAND_MODULE(WAYLAND_CLIENT)
|
||||
SDL_WAYLAND_SYM(void, wl_proxy_marshal, (struct wl_proxy *, uint32_t, ...))
|
||||
SDL_WAYLAND_SYM(struct wl_proxy *, wl_proxy_create, (struct wl_proxy *, const struct wl_interface *))
|
||||
|
|
@ -55,6 +67,9 @@ SDL_WAYLAND_SYM(void, wl_list_insert_list, (struct wl_list *, struct wl_list *))
|
|||
SDL_WAYLAND_MODULE(WAYLAND_CLIENT_1_4)
|
||||
SDL_WAYLAND_SYM(struct wl_proxy *, wl_proxy_marshal_constructor, (struct wl_proxy *, uint32_t opcode, const struct wl_interface *interface, ...))
|
||||
|
||||
SDL_WAYLAND_MODULE(WAYLAND_CLIENT_1_10)
|
||||
SDL_WAYLAND_SYM(struct wl_proxy *, wl_proxy_marshal_constructor_versioned, (struct wl_proxy *proxy, uint32_t opcode, const struct wl_interface *interface, uint32_t version, ...))
|
||||
|
||||
SDL_WAYLAND_INTERFACE(wl_seat_interface)
|
||||
SDL_WAYLAND_INTERFACE(wl_surface_interface)
|
||||
SDL_WAYLAND_INTERFACE(wl_shm_pool_interface)
|
||||
|
|
@ -99,8 +114,10 @@ SDL_WAYLAND_SYM(enum xkb_state_component, xkb_state_update_mask, (struct xkb_sta
|
|||
xkb_layout_index_t latched_layout,\
|
||||
xkb_layout_index_t locked_layout) )
|
||||
|
||||
#undef SDL_WAYLAND_MODULE
|
||||
#undef SDL_WAYLAND_SYM
|
||||
#undef SDL_WAYLAND_INTERFACE
|
||||
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
//SDL_WAYLAND_SYM(ret, fn, params)
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@
|
|||
#include "SDL_waylandmouse.h"
|
||||
#include "SDL_waylandtouch.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
|
|
@ -55,6 +57,56 @@ Wayland_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode);
|
|||
static void
|
||||
Wayland_VideoQuit(_THIS);
|
||||
|
||||
/* Find out what class name we should use
|
||||
* Based on src/video/x11/SDL_x11video.c */
|
||||
static char *
|
||||
get_classname()
|
||||
{
|
||||
char *spot;
|
||||
#if defined(__LINUX__) || defined(__FREEBSD__)
|
||||
char procfile[1024];
|
||||
char linkfile[1024];
|
||||
int linksize;
|
||||
#endif
|
||||
|
||||
/* First allow environment variable override */
|
||||
spot = SDL_getenv("SDL_VIDEO_WAYLAND_WMCLASS");
|
||||
if (spot) {
|
||||
return SDL_strdup(spot);
|
||||
} else {
|
||||
/* Fallback to the "old" envvar */
|
||||
spot = SDL_getenv("SDL_VIDEO_X11_WMCLASS");
|
||||
if (spot) {
|
||||
return SDL_strdup(spot);
|
||||
}
|
||||
}
|
||||
|
||||
/* Next look at the application's executable name */
|
||||
#if defined(__LINUX__) || defined(__FREEBSD__)
|
||||
#if defined(__LINUX__)
|
||||
SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/exe", getpid());
|
||||
#elif defined(__FREEBSD__)
|
||||
SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/file",
|
||||
getpid());
|
||||
#else
|
||||
#error Where can we find the executable name?
|
||||
#endif
|
||||
linksize = readlink(procfile, linkfile, sizeof(linkfile) - 1);
|
||||
if (linksize > 0) {
|
||||
linkfile[linksize] = '\0';
|
||||
spot = SDL_strrchr(linkfile, '/');
|
||||
if (spot) {
|
||||
return SDL_strdup(spot + 1);
|
||||
} else {
|
||||
return SDL_strdup(linkfile);
|
||||
}
|
||||
}
|
||||
#endif /* __LINUX__ || __FREEBSD__ */
|
||||
|
||||
/* Finally use the default we've used forever */
|
||||
return SDL_strdup("SDL_App");
|
||||
}
|
||||
|
||||
/* Wayland driver bootstrap functions */
|
||||
static int
|
||||
Wayland_Available(void)
|
||||
|
|
@ -117,7 +169,10 @@ Wayland_CreateDevice(int devindex)
|
|||
device->CreateWindow = Wayland_CreateWindow;
|
||||
device->ShowWindow = Wayland_ShowWindow;
|
||||
device->SetWindowFullscreen = Wayland_SetWindowFullscreen;
|
||||
device->MaximizeWindow = Wayland_MaximizeWindow;
|
||||
device->RestoreWindow = Wayland_RestoreWindow;
|
||||
device->SetWindowSize = Wayland_SetWindowSize;
|
||||
device->SetWindowTitle = Wayland_SetWindowTitle;
|
||||
device->DestroyWindow = Wayland_DestroyWindow;
|
||||
device->SetWindowHitTest = Wayland_SetWindowHitTest;
|
||||
|
||||
|
|
@ -145,7 +200,7 @@ display_handle_geometry(void *data,
|
|||
{
|
||||
SDL_VideoDisplay *display = data;
|
||||
|
||||
display->name = strdup(model);
|
||||
display->name = SDL_strdup(model);
|
||||
display->driverdata = output;
|
||||
}
|
||||
|
||||
|
|
@ -253,8 +308,10 @@ display_handle_global(void *data, struct wl_registry *registry, uint32_t id,
|
|||
} else if (strcmp(interface, "wl_shm") == 0) {
|
||||
d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
|
||||
d->cursor_theme = WAYLAND_wl_cursor_theme_load(NULL, 32, d->shm);
|
||||
d->default_cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "left_ptr");
|
||||
|
||||
} else if (strcmp(interface, "zwp_relative_pointer_manager_v1") == 0) {
|
||||
Wayland_display_add_relative_pointer_manager(d, id);
|
||||
} else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0) {
|
||||
Wayland_display_add_pointer_constraints(d, id);
|
||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
|
||||
} else if (strcmp(interface, "qt_touch_extension") == 0) {
|
||||
Wayland_touch_create(d, id);
|
||||
|
|
@ -283,6 +340,11 @@ Wayland_VideoInit(_THIS)
|
|||
|
||||
_this->driverdata = data;
|
||||
|
||||
data->xkb_context = WAYLAND_xkb_context_new(0);
|
||||
if (!data->xkb_context) {
|
||||
return SDL_SetError("Failed to create XKB context");
|
||||
}
|
||||
|
||||
data->display = WAYLAND_wl_display_connect(NULL);
|
||||
if (data->display == NULL) {
|
||||
return SDL_SetError("Failed to connect to a Wayland display");
|
||||
|
|
@ -301,13 +363,11 @@ Wayland_VideoInit(_THIS)
|
|||
// Second roundtrip to receive all output events.
|
||||
WAYLAND_wl_display_roundtrip(data->display);
|
||||
|
||||
data->xkb_context = WAYLAND_xkb_context_new(0);
|
||||
if (!data->xkb_context) {
|
||||
return SDL_SetError("Failed to create XKB context");
|
||||
}
|
||||
|
||||
Wayland_InitMouse();
|
||||
|
||||
/* Get the surface class name, usually the name of the application */
|
||||
data->classname = get_classname();
|
||||
|
||||
WAYLAND_wl_display_flush(data->display);
|
||||
|
||||
return 0;
|
||||
|
|
@ -341,6 +401,8 @@ Wayland_VideoQuit(_THIS)
|
|||
}
|
||||
|
||||
Wayland_display_destroy_input(data);
|
||||
Wayland_display_destroy_pointer_constraints(data);
|
||||
Wayland_display_destroy_relative_pointer_manager(data);
|
||||
|
||||
if (data->xkb_context) {
|
||||
WAYLAND_xkb_context_unref(data->xkb_context);
|
||||
|
|
@ -376,6 +438,7 @@ Wayland_VideoQuit(_THIS)
|
|||
WAYLAND_wl_display_disconnect(data->display);
|
||||
}
|
||||
|
||||
SDL_free(data->classname);
|
||||
free(data);
|
||||
_this->driverdata = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,9 +42,10 @@ typedef struct {
|
|||
struct wl_compositor *compositor;
|
||||
struct wl_shm *shm;
|
||||
struct wl_cursor_theme *cursor_theme;
|
||||
struct wl_cursor *default_cursor;
|
||||
struct wl_pointer *pointer;
|
||||
struct wl_shell *shell;
|
||||
struct zwp_relative_pointer_manager_v1 *relative_pointer_manager;
|
||||
struct zwp_pointer_constraints_v1 *pointer_constraints;
|
||||
|
||||
EGLDisplay edpy;
|
||||
EGLContext context;
|
||||
|
|
@ -58,6 +59,10 @@ typedef struct {
|
|||
struct qt_surface_extension *surface_extension;
|
||||
struct qt_windowmanager *windowmanager;
|
||||
#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
|
||||
|
||||
char *classname;
|
||||
|
||||
int relative_mouse_mode;
|
||||
} SDL_VideoData;
|
||||
|
||||
#endif /* _SDL_waylandvideo_h */
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "../SDL_sysvideo.h"
|
||||
#include "../../events/SDL_windowevents_c.h"
|
||||
#include "../SDL_egl_c.h"
|
||||
#include "SDL_waylandevents_c.h"
|
||||
#include "SDL_waylandwindow.h"
|
||||
#include "SDL_waylandvideo.h"
|
||||
#include "SDL_waylandtouch.h"
|
||||
|
|
@ -46,6 +47,33 @@ handle_configure(void *data, struct wl_shell_surface *shell_surface,
|
|||
SDL_Window *window = wind->sdlwindow;
|
||||
struct wl_region *region;
|
||||
|
||||
/* wl_shell_surface spec states that this is a suggestion.
|
||||
Ignore if less than or greater than max/min size. */
|
||||
|
||||
if (width == 0 || height == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
|
||||
if ((window->flags & SDL_WINDOW_RESIZABLE)) {
|
||||
if (window->max_w > 0) {
|
||||
width = SDL_min(width, window->max_w);
|
||||
}
|
||||
width = SDL_max(width, window->min_w);
|
||||
|
||||
if (window->max_h > 0) {
|
||||
height = SDL_min(height, window->max_h);
|
||||
}
|
||||
height = SDL_max(height, window->min_h);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (width == window->w && height == window->h) {
|
||||
return;
|
||||
}
|
||||
|
||||
window->w = width;
|
||||
window->h = height;
|
||||
WAYLAND_wl_egl_window_resize(wind->egl_window, window->w, window->h, 0, 0);
|
||||
|
|
@ -145,6 +173,26 @@ Wayland_SetWindowFullscreen(_THIS, SDL_Window * window,
|
|||
WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
|
||||
}
|
||||
|
||||
void
|
||||
Wayland_RestoreWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_WindowData *wind = window->driverdata;
|
||||
|
||||
wl_shell_surface_set_toplevel(wind->shell_surface);
|
||||
|
||||
WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
|
||||
}
|
||||
|
||||
void
|
||||
Wayland_MaximizeWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_WindowData *wind = window->driverdata;
|
||||
|
||||
wl_shell_surface_set_maximized(wind->shell_surface, NULL);
|
||||
|
||||
WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
|
||||
}
|
||||
|
||||
int Wayland_CreateWindow(_THIS, SDL_Window *window)
|
||||
{
|
||||
SDL_WindowData *data;
|
||||
|
|
@ -178,6 +226,7 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window)
|
|||
wl_surface_set_user_data(data->surface, data);
|
||||
data->shell_surface = wl_shell_get_shell_surface(c->shell,
|
||||
data->surface);
|
||||
wl_shell_surface_set_class (data->shell_surface, c->classname);
|
||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
|
||||
if (c->surface_extension) {
|
||||
data->extended_surface = qt_surface_extension_get_extended_surface(
|
||||
|
|
@ -214,6 +263,10 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window)
|
|||
wl_surface_set_opaque_region(data->surface, region);
|
||||
wl_region_destroy(region);
|
||||
|
||||
if (c->relative_mouse_mode) {
|
||||
Wayland_input_lock_pointer(c->input);
|
||||
}
|
||||
|
||||
WAYLAND_wl_display_flush(c->display);
|
||||
|
||||
return 0;
|
||||
|
|
@ -233,6 +286,17 @@ void Wayland_SetWindowSize(_THIS, SDL_Window * window)
|
|||
wl_region_destroy(region);
|
||||
}
|
||||
|
||||
void Wayland_SetWindowTitle(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_WindowData *wind = window->driverdata;
|
||||
|
||||
if (window->title != NULL) {
|
||||
wl_shell_surface_set_title(wind->shell_surface, window->title);
|
||||
}
|
||||
|
||||
WAYLAND_wl_display_flush( ((SDL_VideoData*)_this->driverdata)->display );
|
||||
}
|
||||
|
||||
void Wayland_DestroyWindow(_THIS, SDL_Window *window)
|
||||
{
|
||||
SDL_VideoData *data = _this->driverdata;
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ typedef struct {
|
|||
struct wl_egl_window *egl_window;
|
||||
struct SDL_WaylandInput *keyboard_device;
|
||||
EGLSurface egl_surface;
|
||||
struct zwp_locked_pointer_v1 *locked_pointer;
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
|
||||
struct qt_extended_surface *extended_surface;
|
||||
|
|
@ -49,8 +50,11 @@ extern void Wayland_ShowWindow(_THIS, SDL_Window *window);
|
|||
extern void Wayland_SetWindowFullscreen(_THIS, SDL_Window * window,
|
||||
SDL_VideoDisplay * _display,
|
||||
SDL_bool fullscreen);
|
||||
extern void Wayland_MaximizeWindow(_THIS, SDL_Window * window);
|
||||
extern void Wayland_RestoreWindow(_THIS, SDL_Window * window);
|
||||
extern int Wayland_CreateWindow(_THIS, SDL_Window *window);
|
||||
extern void Wayland_SetWindowSize(_THIS, SDL_Window * window);
|
||||
extern void Wayland_SetWindowTitle(_THIS, SDL_Window * window);
|
||||
extern void Wayland_DestroyWindow(_THIS, SDL_Window *window);
|
||||
|
||||
extern SDL_bool
|
||||
|
|
|
|||
|
|
@ -198,13 +198,26 @@ WindowsScanCodeToSDLScanCode(LPARAM lParam, WPARAM wParam)
|
|||
return code;
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
WIN_ShouldIgnoreFocusClick()
|
||||
{
|
||||
return !SDL_GetHintBoolean(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, SDL_FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
WIN_CheckWParamMouseButton(SDL_bool bwParamMousePressed, SDL_bool bSDLMousePressed, SDL_WindowData *data, Uint8 button, SDL_MouseID mouseID)
|
||||
{
|
||||
if (data->focus_click_pending && button == SDL_BUTTON_LEFT && !bwParamMousePressed) {
|
||||
data->focus_click_pending = SDL_FALSE;
|
||||
WIN_UpdateClipCursor(data->window);
|
||||
if (data->focus_click_pending & SDL_BUTTON(button)) {
|
||||
/* Ignore the button click for activation */
|
||||
if (!bwParamMousePressed) {
|
||||
data->focus_click_pending &= ~SDL_BUTTON(button);
|
||||
if (!data->focus_click_pending) {
|
||||
WIN_UpdateClipCursor(data->window);
|
||||
}
|
||||
}
|
||||
if (WIN_ShouldIgnoreFocusClick()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (bwParamMousePressed && !bSDLMousePressed) {
|
||||
|
|
@ -326,17 +339,7 @@ WIN_ConvertUTF32toUTF8(UINT32 codepoint, char * text)
|
|||
static SDL_bool
|
||||
ShouldGenerateWindowCloseOnAltF4(void)
|
||||
{
|
||||
const char *hint;
|
||||
|
||||
hint = SDL_GetHint(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4);
|
||||
if (hint) {
|
||||
if (*hint == '0') {
|
||||
return SDL_TRUE;
|
||||
} else {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
}
|
||||
return SDL_TRUE;
|
||||
return !SDL_GetHintBoolean(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, SDL_FALSE);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK
|
||||
|
|
@ -398,8 +401,24 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
minimized = HIWORD(wParam);
|
||||
if (!minimized && (LOWORD(wParam) != WA_INACTIVE)) {
|
||||
data->focus_click_pending = (GetAsyncKeyState(VK_LBUTTON) != 0);
|
||||
|
||||
if (LOWORD(wParam) == WA_CLICKACTIVE) {
|
||||
if (GetAsyncKeyState(VK_LBUTTON)) {
|
||||
data->focus_click_pending |= SDL_BUTTON_LMASK;
|
||||
}
|
||||
if (GetAsyncKeyState(VK_RBUTTON)) {
|
||||
data->focus_click_pending |= SDL_BUTTON_RMASK;
|
||||
}
|
||||
if (GetAsyncKeyState(VK_MBUTTON)) {
|
||||
data->focus_click_pending |= SDL_BUTTON_MMASK;
|
||||
}
|
||||
if (GetAsyncKeyState(VK_XBUTTON1)) {
|
||||
data->focus_click_pending |= SDL_BUTTON_X1MASK;
|
||||
}
|
||||
if (GetAsyncKeyState(VK_XBUTTON2)) {
|
||||
data->focus_click_pending |= SDL_BUTTON_X2MASK;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0);
|
||||
if (SDL_GetKeyboardFocus() != data->window) {
|
||||
SDL_SetKeyboardFocus(data->window);
|
||||
|
|
@ -423,6 +442,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
if (SDL_GetKeyboardFocus() == data->window) {
|
||||
SDL_SetKeyboardFocus(NULL);
|
||||
WIN_ResetDeadKeys();
|
||||
}
|
||||
|
||||
ClipCursor(NULL);
|
||||
|
|
@ -737,6 +757,13 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
break;
|
||||
#endif /* WM_GETMINMAXINFO */
|
||||
|
||||
case WM_WINDOWPOSCHANGING:
|
||||
|
||||
if (data->expected_resize) {
|
||||
returnCode = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
{
|
||||
RECT rect;
|
||||
|
|
@ -763,6 +790,9 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
h = rect.bottom - rect.top;
|
||||
SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESIZED, w,
|
||||
h);
|
||||
|
||||
/* Forces a WM_PAINT event */
|
||||
InvalidateRect(hwnd, NULL, FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -907,12 +937,13 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
if (buffer) {
|
||||
if (DragQueryFile(drop, i, buffer, size)) {
|
||||
char *file = WIN_StringToUTF8(buffer);
|
||||
SDL_SendDropFile(file);
|
||||
SDL_SendDropFile(data->window, file);
|
||||
SDL_free(file);
|
||||
}
|
||||
SDL_stack_free(buffer);
|
||||
}
|
||||
}
|
||||
SDL_SendDropComplete(data->window);
|
||||
DragFinish(drop);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -927,15 +958,17 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
const SDL_Point point = { (int) winpoint.x, (int) winpoint.y };
|
||||
const SDL_HitTestResult rc = window->hit_test(window, &point, window->hit_test_data);
|
||||
switch (rc) {
|
||||
case SDL_HITTEST_DRAGGABLE: return HTCAPTION;
|
||||
case SDL_HITTEST_RESIZE_TOPLEFT: return HTTOPLEFT;
|
||||
case SDL_HITTEST_RESIZE_TOP: return HTTOP;
|
||||
case SDL_HITTEST_RESIZE_TOPRIGHT: return HTTOPRIGHT;
|
||||
case SDL_HITTEST_RESIZE_RIGHT: return HTRIGHT;
|
||||
case SDL_HITTEST_RESIZE_BOTTOMRIGHT: return HTBOTTOMRIGHT;
|
||||
case SDL_HITTEST_RESIZE_BOTTOM: return HTBOTTOM;
|
||||
case SDL_HITTEST_RESIZE_BOTTOMLEFT: return HTBOTTOMLEFT;
|
||||
case SDL_HITTEST_RESIZE_LEFT: return HTLEFT;
|
||||
#define POST_HIT_TEST(ret) { SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0); return ret; }
|
||||
case SDL_HITTEST_DRAGGABLE: POST_HIT_TEST(HTCAPTION);
|
||||
case SDL_HITTEST_RESIZE_TOPLEFT: POST_HIT_TEST(HTTOPLEFT);
|
||||
case SDL_HITTEST_RESIZE_TOP: POST_HIT_TEST(HTTOP);
|
||||
case SDL_HITTEST_RESIZE_TOPRIGHT: POST_HIT_TEST(HTTOPRIGHT);
|
||||
case SDL_HITTEST_RESIZE_RIGHT: POST_HIT_TEST(HTRIGHT);
|
||||
case SDL_HITTEST_RESIZE_BOTTOMRIGHT: POST_HIT_TEST(HTBOTTOMRIGHT);
|
||||
case SDL_HITTEST_RESIZE_BOTTOM: POST_HIT_TEST(HTBOTTOM);
|
||||
case SDL_HITTEST_RESIZE_BOTTOMLEFT: POST_HIT_TEST(HTBOTTOMLEFT);
|
||||
case SDL_HITTEST_RESIZE_LEFT: POST_HIT_TEST(HTLEFT);
|
||||
#undef POST_HIT_TEST
|
||||
case SDL_HITTEST_NORMAL: return HTCLIENT;
|
||||
}
|
||||
}
|
||||
|
|
@ -1012,7 +1045,8 @@ HINSTANCE SDL_Instance = NULL;
|
|||
int
|
||||
SDL_RegisterApp(char *name, Uint32 style, void *hInst)
|
||||
{
|
||||
WNDCLASS class;
|
||||
WNDCLASSEX wcex;
|
||||
TCHAR path[MAX_PATH];
|
||||
|
||||
/* Only do this once... */
|
||||
if (app_registered) {
|
||||
|
|
@ -1034,19 +1068,24 @@ SDL_RegisterApp(char *name, Uint32 style, void *hInst)
|
|||
}
|
||||
|
||||
/* Register the application class */
|
||||
class.hCursor = NULL;
|
||||
class.hIcon =
|
||||
LoadImage(SDL_Instance, SDL_Appname, IMAGE_ICON, 0, 0,
|
||||
LR_DEFAULTCOLOR);
|
||||
class.lpszMenuName = NULL;
|
||||
class.lpszClassName = SDL_Appname;
|
||||
class.hbrBackground = NULL;
|
||||
class.hInstance = SDL_Instance;
|
||||
class.style = SDL_Appstyle;
|
||||
class.lpfnWndProc = WIN_WindowProc;
|
||||
class.cbWndExtra = 0;
|
||||
class.cbClsExtra = 0;
|
||||
if (!RegisterClass(&class)) {
|
||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
wcex.hCursor = NULL;
|
||||
wcex.hIcon = NULL;
|
||||
wcex.hIconSm = NULL;
|
||||
wcex.lpszMenuName = NULL;
|
||||
wcex.lpszClassName = SDL_Appname;
|
||||
wcex.style = SDL_Appstyle;
|
||||
wcex.hbrBackground = NULL;
|
||||
wcex.lpfnWndProc = WIN_WindowProc;
|
||||
wcex.hInstance = SDL_Instance;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
|
||||
/* Use the first icon as a default icon, like in the Explorer */
|
||||
GetModuleFileName(SDL_Instance, path, MAX_PATH);
|
||||
ExtractIconEx(path, 0, &wcex.hIcon, &wcex.hIconSm, 1);
|
||||
|
||||
if (!RegisterClassEx(&wcex)) {
|
||||
return SDL_SetError("Couldn't register application class");
|
||||
}
|
||||
|
||||
|
|
@ -1058,7 +1097,7 @@ SDL_RegisterApp(char *name, Uint32 style, void *hInst)
|
|||
void
|
||||
SDL_UnregisterApp()
|
||||
{
|
||||
WNDCLASS class;
|
||||
WNDCLASSEX wcex;
|
||||
|
||||
/* SDL_RegisterApp might not have been called before */
|
||||
if (!app_registered) {
|
||||
|
|
@ -1067,8 +1106,10 @@ SDL_UnregisterApp()
|
|||
--app_registered;
|
||||
if (app_registered == 0) {
|
||||
/* Check for any registered window classes. */
|
||||
if (GetClassInfo(SDL_Instance, SDL_Appname, &class)) {
|
||||
if (GetClassInfoEx(SDL_Instance, SDL_Appname, &wcex)) {
|
||||
UnregisterClass(SDL_Appname, SDL_Instance);
|
||||
if (wcex.hIcon) DestroyIcon(wcex.hIcon);
|
||||
if (wcex.hIconSm) DestroyIcon(wcex.hIconSm);
|
||||
}
|
||||
SDL_free(SDL_Appname);
|
||||
SDL_Appname = NULL;
|
||||
|
|
|
|||
|
|
@ -157,11 +157,47 @@ WIN_QuitKeyboard(_THIS)
|
|||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
WIN_ResetDeadKeys()
|
||||
{
|
||||
/*
|
||||
if a deadkey has been typed, but not the next character (which the deadkey might modify),
|
||||
this tries to undo the effect pressing the deadkey.
|
||||
see: http://archives.miloush.net/michkap/archive/2006/09/10/748775.html
|
||||
*/
|
||||
BYTE keyboardState[256];
|
||||
WCHAR buffer[16];
|
||||
int keycode, scancode, result, i;
|
||||
|
||||
GetKeyboardState(keyboardState);
|
||||
|
||||
keycode = VK_SPACE;
|
||||
scancode = MapVirtualKey(keycode, MAPVK_VK_TO_VSC);
|
||||
if (scancode == 0) {
|
||||
/* the keyboard doesn't have this key */
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
result = ToUnicode(keycode, scancode, keyboardState, (LPWSTR)buffer, 16, 0);
|
||||
if (result > 0) {
|
||||
/* success */
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WIN_StartTextInput(_THIS)
|
||||
{
|
||||
#ifndef SDL_DISABLE_WINDOWS_IME
|
||||
SDL_Window *window = SDL_GetKeyboardFocus();
|
||||
SDL_Window *window;
|
||||
#endif
|
||||
|
||||
WIN_ResetDeadKeys();
|
||||
|
||||
#ifndef SDL_DISABLE_WINDOWS_IME
|
||||
window = SDL_GetKeyboardFocus();
|
||||
if (window) {
|
||||
HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
|
||||
SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
|
||||
|
|
@ -176,7 +212,13 @@ void
|
|||
WIN_StopTextInput(_THIS)
|
||||
{
|
||||
#ifndef SDL_DISABLE_WINDOWS_IME
|
||||
SDL_Window *window = SDL_GetKeyboardFocus();
|
||||
SDL_Window *window;
|
||||
#endif
|
||||
|
||||
WIN_ResetDeadKeys();
|
||||
|
||||
#ifndef SDL_DISABLE_WINDOWS_IME
|
||||
window = SDL_GetKeyboardFocus();
|
||||
if (window) {
|
||||
HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
|
||||
SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ extern void WIN_InitKeyboard(_THIS);
|
|||
extern void WIN_UpdateKeymap(void);
|
||||
extern void WIN_QuitKeyboard(_THIS);
|
||||
|
||||
extern void WIN_ResetDeadKeys(void);
|
||||
|
||||
extern void WIN_StartTextInput(_THIS);
|
||||
extern void WIN_StopTextInput(_THIS);
|
||||
extern void WIN_SetTextInputRect(_THIS, SDL_Rect *rect);
|
||||
|
|
|
|||
|
|
@ -452,9 +452,9 @@ WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
|
|||
}
|
||||
|
||||
/* Align the buttons to the right/bottom. */
|
||||
x = Size.cx - ButtonWidth - ButtonMargin;
|
||||
x = Size.cx - (ButtonWidth + ButtonMargin) * messageboxdata->numbuttons;
|
||||
y = Size.cy - ButtonHeight - ButtonMargin;
|
||||
for (i = 0; i < messageboxdata->numbuttons; ++i) {
|
||||
for (i = messageboxdata->numbuttons - 1; i >= 0; --i) {
|
||||
SDL_bool isDefault;
|
||||
|
||||
if (buttons[i].flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) {
|
||||
|
|
@ -466,7 +466,7 @@ WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
|
|||
FreeDialogData(dialog);
|
||||
return -1;
|
||||
}
|
||||
x -= ButtonWidth + ButtonMargin;
|
||||
x += ButtonWidth + ButtonMargin;
|
||||
}
|
||||
|
||||
/* FIXME: If we have a parent window, get the Instance and HWND for them */
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#if SDL_VIDEO_DRIVER_WINDOWS
|
||||
|
||||
#include "SDL_windowsvideo.h"
|
||||
#include "../../../include/SDL_assert.h"
|
||||
|
||||
/* Windows CE compatibility */
|
||||
#ifndef CDS_FULLSCREEN
|
||||
|
|
@ -69,40 +70,16 @@ WIN_GetMonitorDPI(HMONITOR hMonitor,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
WIN_GetDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode)
|
||||
static void
|
||||
WIN_UpdateDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode)
|
||||
{
|
||||
SDL_VideoData *vid_data = (SDL_VideoData *) _this->driverdata;
|
||||
SDL_DisplayModeData *data;
|
||||
DEVMODE devmode;
|
||||
SDL_DisplayModeData *data = (SDL_DisplayModeData *) mode->driverdata;
|
||||
HDC hdc;
|
||||
|
||||
devmode.dmSize = sizeof(devmode);
|
||||
devmode.dmDriverExtra = 0;
|
||||
if (!EnumDisplaySettings(deviceName, index, &devmode)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data));
|
||||
if (!data) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
data->DeviceMode = devmode;
|
||||
data->DeviceMode.dmFields =
|
||||
(DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY |
|
||||
DM_DISPLAYFLAGS);
|
||||
data->ScaleX = 1.0f;
|
||||
data->ScaleY = 1.0f;
|
||||
data->DiagDPI = 0.0f;
|
||||
data->HorzDPI = 0.0f;
|
||||
data->VertDPI = 0.0f;
|
||||
|
||||
/* Fill in the mode information */
|
||||
mode->format = SDL_PIXELFORMAT_UNKNOWN;
|
||||
mode->w = devmode.dmPelsWidth;
|
||||
mode->h = devmode.dmPelsHeight;
|
||||
mode->refresh_rate = devmode.dmDisplayFrequency;
|
||||
mode->driverdata = data;
|
||||
|
||||
if (index == ENUM_CURRENT_SETTINGS
|
||||
&& (hdc = CreateDC(deviceName, NULL, NULL, NULL)) != NULL) {
|
||||
|
|
@ -112,8 +89,8 @@ WIN_GetDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mod
|
|||
int logical_width = GetDeviceCaps( hdc, HORZRES );
|
||||
int logical_height = GetDeviceCaps( hdc, VERTRES );
|
||||
|
||||
data->ScaleX = (float)logical_width / devmode.dmPelsWidth;
|
||||
data->ScaleY = (float)logical_height / devmode.dmPelsHeight;
|
||||
data->ScaleX = (float)logical_width / data->DeviceMode.dmPelsWidth;
|
||||
data->ScaleY = (float)logical_height / data->DeviceMode.dmPelsHeight;
|
||||
mode->w = logical_width;
|
||||
mode->h = logical_height;
|
||||
|
||||
|
|
@ -126,8 +103,8 @@ WIN_GetDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mod
|
|||
dpi_data.vid_data = vid_data;
|
||||
dpi_data.mode = mode;
|
||||
dpi_data.mode_data = data;
|
||||
monitor_rect.left = devmode.dmPosition.x;
|
||||
monitor_rect.top = devmode.dmPosition.y;
|
||||
monitor_rect.left = data->DeviceMode.dmPosition.x;
|
||||
monitor_rect.top = data->DeviceMode.dmPosition.y;
|
||||
monitor_rect.right = monitor_rect.left + 1;
|
||||
monitor_rect.bottom = monitor_rect.top + 1;
|
||||
EnumDisplayMonitors(NULL, &monitor_rect, WIN_GetMonitorDPI, (LPARAM)&dpi_data);
|
||||
|
|
@ -175,10 +152,10 @@ WIN_GetDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mod
|
|||
} else if (bmi->bmiHeader.biBitCount == 4) {
|
||||
mode->format = SDL_PIXELFORMAT_INDEX4LSB;
|
||||
}
|
||||
} else {
|
||||
} else if (mode->format == SDL_PIXELFORMAT_UNKNOWN) {
|
||||
/* FIXME: Can we tell what this will be? */
|
||||
if ((devmode.dmFields & DM_BITSPERPEL) == DM_BITSPERPEL) {
|
||||
switch (devmode.dmBitsPerPel) {
|
||||
if ((data->DeviceMode.dmFields & DM_BITSPERPEL) == DM_BITSPERPEL) {
|
||||
switch (data->DeviceMode.dmBitsPerPel) {
|
||||
case 32:
|
||||
mode->format = SDL_PIXELFORMAT_RGB888;
|
||||
break;
|
||||
|
|
@ -200,6 +177,42 @@ WIN_GetDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mod
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
WIN_GetDisplayMode(_THIS, LPCTSTR deviceName, DWORD index, SDL_DisplayMode * mode)
|
||||
{
|
||||
SDL_DisplayModeData *data;
|
||||
DEVMODE devmode;
|
||||
|
||||
devmode.dmSize = sizeof(devmode);
|
||||
devmode.dmDriverExtra = 0;
|
||||
if (!EnumDisplaySettings(deviceName, index, &devmode)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data));
|
||||
if (!data) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
mode->driverdata = data;
|
||||
data->DeviceMode = devmode;
|
||||
|
||||
/* Default basic information */
|
||||
data->ScaleX = 1.0f;
|
||||
data->ScaleY = 1.0f;
|
||||
data->DiagDPI = 0.0f;
|
||||
data->HorzDPI = 0.0f;
|
||||
data->VertDPI = 0.0f;
|
||||
|
||||
mode->format = SDL_PIXELFORMAT_UNKNOWN;
|
||||
mode->w = data->DeviceMode.dmPelsWidth;
|
||||
mode->h = data->DeviceMode.dmPelsHeight;
|
||||
mode->refresh_rate = data->DeviceMode.dmDisplayFrequency;
|
||||
|
||||
/* Fill in the mode information */
|
||||
WIN_UpdateDisplayMode(_this, deviceName, index, mode);
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -329,7 +342,44 @@ WIN_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi,
|
|||
*vdpi = data->VertDPI;
|
||||
}
|
||||
|
||||
return data->DiagDPI != 0.0f ? 0 : -1;
|
||||
return data->DiagDPI != 0.0f ? 0 : SDL_SetError("Couldn't get DPI");
|
||||
}
|
||||
|
||||
int
|
||||
WIN_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect)
|
||||
{
|
||||
const SDL_DisplayModeData *data = (const SDL_DisplayModeData *) display->current_mode.driverdata;
|
||||
const DEVMODE *pDevMode = &data->DeviceMode;
|
||||
POINT pt = {
|
||||
/* !!! FIXME: no scale, right? */
|
||||
(LONG) (pDevMode->dmPosition.x + (pDevMode->dmPelsWidth / 2)),
|
||||
(LONG) (pDevMode->dmPosition.y + (pDevMode->dmPelsHeight / 2))
|
||||
};
|
||||
HMONITOR hmon = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL);
|
||||
MONITORINFO minfo;
|
||||
const RECT *work;
|
||||
BOOL rc = FALSE;
|
||||
|
||||
SDL_assert(hmon != NULL);
|
||||
|
||||
if (hmon != NULL) {
|
||||
SDL_zero(minfo);
|
||||
minfo.cbSize = sizeof (MONITORINFO);
|
||||
rc = GetMonitorInfo(hmon, &minfo);
|
||||
SDL_assert(rc);
|
||||
}
|
||||
|
||||
if (!rc) {
|
||||
return SDL_SetError("Couldn't find monitor data");
|
||||
}
|
||||
|
||||
work = &minfo.rcWork;
|
||||
rect->x = (int)SDL_ceil(work->left * data->ScaleX);
|
||||
rect->y = (int)SDL_ceil(work->top * data->ScaleY);
|
||||
rect->w = (int)SDL_ceil((work->right - work->left) * data->ScaleX);
|
||||
rect->h = (int)SDL_ceil((work->bottom - work->top) * data->ScaleY);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -366,7 +416,7 @@ WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
|
|||
LONG status;
|
||||
|
||||
if (mode->driverdata == display->desktop_mode.driverdata) {
|
||||
status = ChangeDisplaySettingsEx(displaydata->DeviceName, NULL, NULL, 0, NULL);
|
||||
status = ChangeDisplaySettingsEx(displaydata->DeviceName, NULL, NULL, CDS_FULLSCREEN, NULL);
|
||||
} else {
|
||||
status = ChangeDisplaySettingsEx(displaydata->DeviceName, &data->DeviceMode, NULL, CDS_FULLSCREEN, NULL);
|
||||
}
|
||||
|
|
@ -389,6 +439,7 @@ WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
|
|||
return SDL_SetError("ChangeDisplaySettingsEx() failed: %s", reason);
|
||||
}
|
||||
EnumDisplaySettings(displaydata->DeviceName, ENUM_CURRENT_SETTINGS, &data->DeviceMode);
|
||||
WIN_UpdateDisplayMode(_this, displaydata->DeviceName, ENUM_CURRENT_SETTINGS, mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ typedef struct
|
|||
|
||||
extern int WIN_InitModes(_THIS);
|
||||
extern int WIN_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect);
|
||||
extern int WIN_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect);
|
||||
extern int WIN_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi);
|
||||
extern void WIN_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
|
||||
extern int WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ WIN_CreateDevice(int devindex)
|
|||
device->VideoInit = WIN_VideoInit;
|
||||
device->VideoQuit = WIN_VideoQuit;
|
||||
device->GetDisplayBounds = WIN_GetDisplayBounds;
|
||||
device->GetDisplayUsableBounds = WIN_GetDisplayUsableBounds;
|
||||
device->GetDisplayDPI = WIN_GetDisplayDPI;
|
||||
device->GetDisplayModes = WIN_GetDisplayModes;
|
||||
device->SetDisplayMode = WIN_SetDisplayMode;
|
||||
|
|
@ -136,6 +137,7 @@ WIN_CreateDevice(int devindex)
|
|||
device->SetWindowIcon = WIN_SetWindowIcon;
|
||||
device->SetWindowPosition = WIN_SetWindowPosition;
|
||||
device->SetWindowSize = WIN_SetWindowSize;
|
||||
device->SetWindowOpacity = WIN_SetWindowOpacity;
|
||||
device->ShowWindow = WIN_ShowWindow;
|
||||
device->HideWindow = WIN_HideWindow;
|
||||
device->RaiseWindow = WIN_RaiseWindow;
|
||||
|
|
@ -143,6 +145,7 @@ WIN_CreateDevice(int devindex)
|
|||
device->MinimizeWindow = WIN_MinimizeWindow;
|
||||
device->RestoreWindow = WIN_RestoreWindow;
|
||||
device->SetWindowBordered = WIN_SetWindowBordered;
|
||||
device->SetWindowResizable = WIN_SetWindowResizable;
|
||||
device->SetWindowFullscreen = WIN_SetWindowFullscreen;
|
||||
device->SetWindowGammaRamp = WIN_SetWindowGammaRamp;
|
||||
device->GetWindowGammaRamp = WIN_GetWindowGammaRamp;
|
||||
|
|
|
|||
|
|
@ -478,7 +478,8 @@ WIN_HideWindow(_THIS, SDL_Window * window)
|
|||
void
|
||||
WIN_RaiseWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOSIZE);
|
||||
HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
|
||||
SetForegroundWindow(hwnd);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -519,6 +520,22 @@ WIN_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
|
|||
data->in_border_change = SDL_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
WIN_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable)
|
||||
{
|
||||
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
|
||||
HWND hwnd = data->hwnd;
|
||||
DWORD style = GetWindowLong(hwnd, GWL_STYLE);
|
||||
|
||||
if (resizable) {
|
||||
style |= STYLE_RESIZABLE;
|
||||
} else {
|
||||
style &= ~STYLE_RESIZABLE;
|
||||
}
|
||||
|
||||
SetWindowLong(hwnd, GWL_STYLE, style);
|
||||
}
|
||||
|
||||
void
|
||||
WIN_RestoreWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
|
|
@ -826,6 +843,39 @@ WIN_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
|
|||
return 0; /* just succeed, the real work is done elsewhere. */
|
||||
}
|
||||
|
||||
int
|
||||
WIN_SetWindowOpacity(_THIS, SDL_Window * window, float opacity)
|
||||
{
|
||||
const SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
const HWND hwnd = data->hwnd;
|
||||
const LONG style = GetWindowLong(hwnd, GWL_EXSTYLE);
|
||||
|
||||
SDL_assert(style != 0);
|
||||
|
||||
if (opacity == 1.0f) {
|
||||
/* want it fully opaque, just mark it unlayered if necessary. */
|
||||
if (style & WS_EX_LAYERED) {
|
||||
if (SetWindowLong(hwnd, GWL_EXSTYLE, style & ~WS_EX_LAYERED) == 0) {
|
||||
return WIN_SetError("SetWindowLong()");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const BYTE alpha = (BYTE) ((int) (opacity * 255.0f));
|
||||
/* want it transparent, mark it layered if necessary. */
|
||||
if ((style & WS_EX_LAYERED) == 0) {
|
||||
if (SetWindowLong(hwnd, GWL_EXSTYLE, style | WS_EX_LAYERED) == 0) {
|
||||
return WIN_SetError("SetWindowLong()");
|
||||
}
|
||||
}
|
||||
|
||||
if (SetLayeredWindowAttributes(hwnd, 0, alpha, LWA_ALPHA) == 0) {
|
||||
return WIN_SetError("SetLayeredWindowAttributes()");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ typedef struct
|
|||
SDL_bool expected_resize;
|
||||
SDL_bool in_border_change;
|
||||
SDL_bool in_title_click;
|
||||
SDL_bool focus_click_pending;
|
||||
Uint8 focus_click_pending;
|
||||
SDL_bool windowed_mode_was_maximized;
|
||||
SDL_bool in_window_deactivation;
|
||||
struct SDL_VideoData *videodata;
|
||||
|
|
@ -56,6 +56,7 @@ extern void WIN_SetWindowTitle(_THIS, SDL_Window * window);
|
|||
extern void WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon);
|
||||
extern void WIN_SetWindowPosition(_THIS, SDL_Window * window);
|
||||
extern void WIN_SetWindowSize(_THIS, SDL_Window * window);
|
||||
extern int WIN_SetWindowOpacity(_THIS, SDL_Window * window, float opacity);
|
||||
extern void WIN_ShowWindow(_THIS, SDL_Window * window);
|
||||
extern void WIN_HideWindow(_THIS, SDL_Window * window);
|
||||
extern void WIN_RaiseWindow(_THIS, SDL_Window * window);
|
||||
|
|
@ -63,6 +64,7 @@ extern void WIN_MaximizeWindow(_THIS, SDL_Window * window);
|
|||
extern void WIN_MinimizeWindow(_THIS, SDL_Window * window);
|
||||
extern void WIN_RestoreWindow(_THIS, SDL_Window * window);
|
||||
extern void WIN_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered);
|
||||
extern void WIN_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable);
|
||||
extern void WIN_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
|
||||
extern int WIN_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp);
|
||||
extern int WIN_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp);
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ using Windows::UI::Core::CoreCursor;
|
|||
#include "SDL_system.h"
|
||||
|
||||
extern "C" {
|
||||
#include "../../thread/SDL_systhread.h"
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "../../events/SDL_events_c.h"
|
||||
}
|
||||
|
|
@ -113,7 +114,7 @@ WINRT_CycleXAMLThread()
|
|||
|
||||
_mutex = SDL_CreateMutex();
|
||||
_threadState = ThreadState_Running;
|
||||
_XAMLThread = SDL_CreateThread(WINRT_XAMLThreadMain, "SDL/XAML App Thread", nullptr);
|
||||
_XAMLThread = SDL_CreateThreadInternal(WINRT_XAMLThreadMain, "SDL/XAML App Thread", 0, nullptr);
|
||||
|
||||
SDL_LockMutex(_mutex);
|
||||
while (_threadState != ThreadState_Yielding) {
|
||||
|
|
|
|||
|
|
@ -67,6 +67,13 @@ extern void WINRT_ProcessKeyDownEvent(Windows::UI::Core::KeyEventArgs ^args);
|
|||
extern void WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^args);
|
||||
extern void WINRT_ProcessCharacterReceivedEvent(Windows::UI::Core::CharacterReceivedEventArgs ^args);
|
||||
|
||||
#if NTDDI_VERSION >= NTDDI_WIN10
|
||||
extern SDL_bool WINRT_HasScreenKeyboardSupport(_THIS);
|
||||
extern void WINRT_ShowScreenKeyboard(_THIS, SDL_Window *window);
|
||||
extern void WINRT_HideScreenKeyboard(_THIS, SDL_Window *window);
|
||||
extern SDL_bool WINRT_IsScreenKeyboardShown(_THIS, SDL_Window *window);
|
||||
#endif // NTDDI_VERSION >= ...
|
||||
|
||||
/* XAML Thread Management */
|
||||
extern void WINRT_CycleXAMLThread();
|
||||
|
||||
|
|
|
|||
196
Engine/lib/sdl/src/video/winrt/SDL_winrtgamebar.cpp
Normal file
196
Engine/lib/sdl/src/video/winrt/SDL_winrtgamebar.cpp
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2016 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_WINRT
|
||||
|
||||
/* Windows includes */
|
||||
#include <roapi.h>
|
||||
#include <windows.foundation.h>
|
||||
#include <EventToken.h>
|
||||
|
||||
|
||||
/* SDL includes */
|
||||
extern "C" {
|
||||
#include "SDL_mouse.h"
|
||||
#include "../SDL_sysvideo.h"
|
||||
}
|
||||
#include "SDL_winrtvideo_cpp.h"
|
||||
|
||||
|
||||
/* Game Bar events can come in off the main thread. Use the following
|
||||
WinRT CoreDispatcher to deal with them on SDL's thread.
|
||||
*/
|
||||
static Platform::WeakReference WINRT_MainThreadDispatcher;
|
||||
|
||||
|
||||
/* Win10's initial SDK (the 10.0.10240.0 release) does not include references
|
||||
to Game Bar APIs, as the Game Bar was released via Win10 10.0.10586.0.
|
||||
|
||||
Declare its WinRT/COM interface here, to allow compilation with earlier
|
||||
Windows SDKs.
|
||||
*/
|
||||
MIDL_INTERFACE("1DB9A292-CC78-4173-BE45-B61E67283EA7")
|
||||
IGameBarStatics_ : public IInspectable
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE add_VisibilityChanged(
|
||||
__FIEventHandler_1_IInspectable *handler,
|
||||
Windows::Foundation::EventRegistrationToken *token) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE remove_VisibilityChanged(
|
||||
Windows::Foundation::EventRegistrationToken token) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE add_IsInputRedirectedChanged(
|
||||
__FIEventHandler_1_IInspectable *handler,
|
||||
Windows::Foundation::EventRegistrationToken *token) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE remove_IsInputRedirectedChanged(
|
||||
Windows::Foundation::EventRegistrationToken token) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE get_Visible(
|
||||
boolean *value) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE get_IsInputRedirected(
|
||||
boolean *value) = 0;
|
||||
};
|
||||
|
||||
/* Declare the game bar's COM GUID */
|
||||
static GUID IID_IGameBarStatics_ = { MAKELONG(0xA292, 0x1DB9), 0xCC78, 0x4173, { 0xBE, 0x45, 0xB6, 0x1E, 0x67, 0x28, 0x3E, 0xA7 } };
|
||||
|
||||
/* Retrieves a pointer to the game bar, or NULL if it is not available.
|
||||
If a pointer is returned, it's ->Release() method must be called
|
||||
after the caller has finished using it.
|
||||
*/
|
||||
static IGameBarStatics_ *
|
||||
WINRT_GetGameBar()
|
||||
{
|
||||
wchar_t *wClassName = L"Windows.Gaming.UI.GameBar";
|
||||
HSTRING hClassName;
|
||||
IActivationFactory *pActivationFactory = NULL;
|
||||
IGameBarStatics_ *pGameBar = NULL;
|
||||
HRESULT hr;
|
||||
|
||||
hr = ::WindowsCreateString(wClassName, (UINT32)wcslen(wClassName), &hClassName);
|
||||
if (FAILED(hr)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
hr = Windows::Foundation::GetActivationFactory(hClassName, &pActivationFactory);
|
||||
if (FAILED(hr)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
pActivationFactory->QueryInterface(IID_IGameBarStatics_, (void **) &pGameBar);
|
||||
|
||||
done:
|
||||
if (pActivationFactory) {
|
||||
pActivationFactory->Release();
|
||||
}
|
||||
if (hClassName) {
|
||||
::WindowsDeleteString(hClassName);
|
||||
}
|
||||
return pGameBar;
|
||||
}
|
||||
|
||||
static void
|
||||
WINRT_HandleGameBarIsInputRedirected_MainThread()
|
||||
{
|
||||
IGameBarStatics_ *gameBar;
|
||||
boolean isInputRedirected = 0;
|
||||
if (!WINRT_MainThreadDispatcher) {
|
||||
/* The game bar event handler has been deregistered! */
|
||||
return;
|
||||
}
|
||||
gameBar = WINRT_GetGameBar();
|
||||
if (!gameBar) {
|
||||
/* Shouldn't happen, but just in case... */
|
||||
return;
|
||||
}
|
||||
if (SUCCEEDED(gameBar->get_IsInputRedirected(&isInputRedirected))) {
|
||||
if ( ! isInputRedirected) {
|
||||
/* Input-control is now back to the SDL app. Restore the cursor,
|
||||
in case Windows does not (it does not in either Win10
|
||||
10.0.10240.0 or 10.0.10586.0, maybe later version(s) too.
|
||||
*/
|
||||
SDL_Cursor *cursor = SDL_GetCursor();
|
||||
SDL_SetCursor(cursor);
|
||||
}
|
||||
}
|
||||
gameBar->Release();
|
||||
}
|
||||
|
||||
static void
|
||||
WINRT_HandleGameBarIsInputRedirected_NonMainThread(Platform::Object ^ o1, Platform::Object ^o2)
|
||||
{
|
||||
Windows::UI::Core::CoreDispatcher ^dispatcher = WINRT_MainThreadDispatcher.Resolve<Windows::UI::Core::CoreDispatcher>();
|
||||
if (dispatcher) {
|
||||
dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler(&WINRT_HandleGameBarIsInputRedirected_MainThread));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WINRT_InitGameBar(_THIS)
|
||||
{
|
||||
SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata;
|
||||
IGameBarStatics_ *gameBar = WINRT_GetGameBar();
|
||||
if (gameBar) {
|
||||
/* GameBar.IsInputRedirected events can come in via something other than
|
||||
the main/SDL thread.
|
||||
|
||||
Get a WinRT 'CoreDispatcher' that can be used to call back into the
|
||||
SDL thread.
|
||||
*/
|
||||
WINRT_MainThreadDispatcher = Windows::UI::Core::CoreWindow::GetForCurrentThread()->Dispatcher;
|
||||
Windows::Foundation::EventHandler<Platform::Object ^> ^handler = \
|
||||
ref new Windows::Foundation::EventHandler<Platform::Object ^>(&WINRT_HandleGameBarIsInputRedirected_NonMainThread);
|
||||
__FIEventHandler_1_IInspectable * pHandler = reinterpret_cast<__FIEventHandler_1_IInspectable *>(handler);
|
||||
gameBar->add_IsInputRedirectedChanged(pHandler, &driverdata->gameBarIsInputRedirectedToken);
|
||||
gameBar->Release();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WINRT_QuitGameBar(_THIS)
|
||||
{
|
||||
SDL_VideoData *driverdata;
|
||||
IGameBarStatics_ *gameBar;
|
||||
if (!_this || !_this->driverdata) {
|
||||
return;
|
||||
}
|
||||
gameBar = WINRT_GetGameBar();
|
||||
if (!gameBar) {
|
||||
return;
|
||||
}
|
||||
driverdata = (SDL_VideoData *)_this->driverdata;
|
||||
if (driverdata->gameBarIsInputRedirectedToken.Value) {
|
||||
gameBar->remove_IsInputRedirectedChanged(driverdata->gameBarIsInputRedirectedToken);
|
||||
driverdata->gameBarIsInputRedirectedToken.Value = 0;
|
||||
}
|
||||
WINRT_MainThreadDispatcher = nullptr;
|
||||
gameBar->Release();
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_WINRT */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
35
Engine/lib/sdl/src/video/winrt/SDL_winrtgamebar_cpp.h
Normal file
35
Engine/lib/sdl/src/video/winrt/SDL_winrtgamebar_cpp.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2016 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_config.h"
|
||||
|
||||
#ifndef _SDL_winrtgamebar_h
|
||||
#define _SDL_winrtgamebar_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* These are exported as C++ functions, rather than C, to fix a compilation
|
||||
bug with MSVC 2013, for Windows 8.x builds. */
|
||||
extern void WINRT_InitGameBar(_THIS);
|
||||
extern void WINRT_QuitGameBar(_THIS);
|
||||
#endif
|
||||
|
||||
#endif /* _SDL_winrtmouse_h */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
@ -383,4 +383,48 @@ WINRT_ProcessCharacterReceivedEvent(Windows::UI::Core::CharacterReceivedEventArg
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#if NTDDI_VERSION >= NTDDI_WIN10
|
||||
|
||||
SDL_bool WINRT_HasScreenKeyboardSupport(_THIS)
|
||||
{
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
void WINRT_ShowScreenKeyboard(_THIS, SDL_Window *window)
|
||||
{
|
||||
using namespace Windows::UI::ViewManagement;
|
||||
InputPane ^ inputPane = InputPane::GetForCurrentView();
|
||||
if (inputPane) {
|
||||
inputPane->TryShow();
|
||||
}
|
||||
}
|
||||
|
||||
void WINRT_HideScreenKeyboard(_THIS, SDL_Window *window)
|
||||
{
|
||||
using namespace Windows::UI::ViewManagement;
|
||||
InputPane ^ inputPane = InputPane::GetForCurrentView();
|
||||
if (inputPane) {
|
||||
inputPane->TryHide();
|
||||
}
|
||||
}
|
||||
|
||||
SDL_bool WINRT_IsScreenKeyboardShown(_THIS, SDL_Window *window)
|
||||
{
|
||||
using namespace Windows::UI::ViewManagement;
|
||||
InputPane ^ inputPane = InputPane::GetForCurrentView();
|
||||
if (inputPane) {
|
||||
// dludwig@pobox.com: checking inputPane->Visible doesn't seem to detect visibility,
|
||||
// at least not on the Windows Phone 10.0.10240.0 emulator. Checking
|
||||
// the size of inputPane->OccludedRect, however, does seem to work.
|
||||
Windows::Foundation::Rect rect = inputPane->OccludedRect;
|
||||
if (rect.Width > 0 && rect.Height > 0) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
#endif // NTDDI_VERSION >= ...
|
||||
|
||||
#endif // SDL_VIDEO_DRIVER_WINRT
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
* Windows includes:
|
||||
*/
|
||||
#include <Windows.h>
|
||||
#include <windows.ui.core.h>
|
||||
using namespace Windows::UI::Core;
|
||||
using Windows::UI::Core::CoreCursor;
|
||||
|
||||
|
|
@ -116,11 +117,69 @@ WINRT_ShowCursor(SDL_Cursor * cursor)
|
|||
return 0;
|
||||
}
|
||||
|
||||
CoreWindow ^ coreWindow = CoreWindow::GetForCurrentThread();
|
||||
if (cursor) {
|
||||
CoreCursor ^* theCursor = (CoreCursor ^*) cursor->driverdata;
|
||||
CoreWindow::GetForCurrentThread()->PointerCursor = *theCursor;
|
||||
coreWindow->PointerCursor = *theCursor;
|
||||
} else {
|
||||
CoreWindow::GetForCurrentThread()->PointerCursor = nullptr;
|
||||
// HACK ALERT: TL;DR - Hiding the cursor in WinRT/UWP apps is weird, and
|
||||
// a Win32-style cursor resource file must be directly included in apps,
|
||||
// otherwise hiding the cursor will cause mouse-motion data to never be
|
||||
// received.
|
||||
//
|
||||
// Here's the lengthy explanation:
|
||||
//
|
||||
// There are two ways to hide a cursor in WinRT/UWP apps.
|
||||
// Both involve setting the WinRT CoreWindow's (which is somewhat analogous
|
||||
// to a Win32 HWND) 'PointerCursor' property.
|
||||
//
|
||||
// The first way to hide a cursor sets PointerCursor to nullptr. This
|
||||
// is, arguably, the easiest to implement for an app. It does have an
|
||||
// unfortunate side-effect: it'll prevent mouse-motion events from being
|
||||
// sent to the app (via CoreWindow).
|
||||
//
|
||||
// The second way to hide a cursor sets PointerCursor to a transparent
|
||||
// cursor. This allows mouse-motion events to be sent to the app, but is
|
||||
// more difficult to set up, as:
|
||||
// 1. WinRT/UWP, while providing a few stock cursors, does not provide
|
||||
// a completely transparent cursor.
|
||||
// 2. WinRT/UWP allows apps to provide custom-built cursors, but *ONLY*
|
||||
// if they are linked directly inside the app, via Win32-style
|
||||
// cursor resource files. APIs to create cursors at runtime are
|
||||
// not provided to apps, and attempting to link-to or use Win32
|
||||
// cursor-creation APIs could cause an app to fail Windows Store
|
||||
// certification.
|
||||
//
|
||||
// SDL can use either means of hiding the cursor. It provides a Win32-style
|
||||
// set of cursor resource files in its source distribution, inside
|
||||
// src/main/winrt/. If those files are linked to an SDL-for-WinRT/UWP app
|
||||
// (by including them in a MSVC project, for example), SDL will attempt to
|
||||
// use those, if and when the cursor is hidden via SDL APIs. If those
|
||||
// files are not linked in, SDL will attempt to hide the cursor via the
|
||||
// 'set PointerCursor to nullptr' means (which, if you recall, causes
|
||||
// mouse-motion data to NOT be sent to the app!).
|
||||
//
|
||||
// Tech notes:
|
||||
// - SDL's blank cursor resource uses a resource ID of 5000.
|
||||
// - SDL's cursor resources consist of the following two files:
|
||||
// - src/main/winrt/SDL2-WinRTResource_BlankCursor.cur -- cursor pixel data
|
||||
// - src/main/winrt/SDL2-WinRTResources.rc -- declares the cursor resource, and its ID (of 5000)
|
||||
//
|
||||
|
||||
const unsigned int win32CursorResourceID = 5000;
|
||||
CoreCursor ^ blankCursor = ref new CoreCursor(CoreCursorType::Custom, win32CursorResourceID);
|
||||
|
||||
// Set 'PointerCursor' to 'blankCursor' in a way that shouldn't throw
|
||||
// an exception if the app hasn't loaded that resource.
|
||||
ABI::Windows::UI::Core::ICoreCursor * iblankCursor = reinterpret_cast<ABI::Windows::UI::Core::ICoreCursor *>(blankCursor);
|
||||
ABI::Windows::UI::Core::ICoreWindow * icoreWindow = reinterpret_cast<ABI::Windows::UI::Core::ICoreWindow *>(coreWindow);
|
||||
HRESULT hr = icoreWindow->put_PointerCursor(iblankCursor);
|
||||
if (FAILED(hr)) {
|
||||
// The app doesn't contain the cursor resource, or some other error
|
||||
// occurred. Just use the other, but mouse-motion-preventing, means of
|
||||
// hiding the cursor.
|
||||
coreWindow->PointerCursor = nullptr;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
/* Windows includes */
|
||||
#include <agile.h>
|
||||
#include <windows.graphics.display.h>
|
||||
#include <windows.system.display.h>
|
||||
#include <dxgi.h>
|
||||
#include <dxgi1_2.h>
|
||||
using namespace Windows::ApplicationModel::Core;
|
||||
|
|
@ -41,7 +42,8 @@ using namespace Windows::UI::ViewManagement;
|
|||
|
||||
|
||||
/* [re]declare Windows GUIDs locally, to limit the amount of external lib(s) SDL has to link to */
|
||||
static const GUID IID_IDXGIFactory2 = { 0x50c83a1c, 0xe072, 0x4c48,{ 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0 } };
|
||||
static const GUID IID_IDisplayRequest = { 0xe5732044, 0xf49f, 0x4b60, { 0x8d, 0xd4, 0x5e, 0x7e, 0x3a, 0x63, 0x2a, 0xc0 } };
|
||||
static const GUID IID_IDXGIFactory2 = { 0x50c83a1c, 0xe072, 0x4c48, { 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0 } };
|
||||
|
||||
|
||||
/* SDL includes */
|
||||
|
|
@ -61,6 +63,7 @@ extern "C" {
|
|||
#include "../../core/winrt/SDL_winrtapp_xaml.h"
|
||||
#include "SDL_winrtvideo_cpp.h"
|
||||
#include "SDL_winrtevents_c.h"
|
||||
#include "SDL_winrtgamebar_cpp.h"
|
||||
#include "SDL_winrtmouse_c.h"
|
||||
#include "SDL_main.h"
|
||||
#include "SDL_system.h"
|
||||
|
|
@ -82,6 +85,11 @@ static void WINRT_DestroyWindow(_THIS, SDL_Window * window);
|
|||
static SDL_bool WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info);
|
||||
|
||||
|
||||
/* Misc functions */
|
||||
static ABI::Windows::System::Display::IDisplayRequest * WINRT_CreateDisplayRequest(_THIS);
|
||||
extern void WINRT_SuspendScreenSaver(_THIS);
|
||||
|
||||
|
||||
/* SDL-internal globals: */
|
||||
SDL_Window * WINRT_GlobalSDLWindow = NULL;
|
||||
|
||||
|
|
@ -118,18 +126,15 @@ WINRT_CreateDevice(int devindex)
|
|||
device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
|
||||
if (!device) {
|
||||
SDL_OutOfMemory();
|
||||
if (device) {
|
||||
SDL_free(device);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
data = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
|
||||
if (!data) {
|
||||
SDL_OutOfMemory();
|
||||
SDL_free(device);
|
||||
return (0);
|
||||
}
|
||||
SDL_zerop(data);
|
||||
device->driverdata = data;
|
||||
|
||||
/* Set the function pointers */
|
||||
|
|
@ -142,6 +147,15 @@ WINRT_CreateDevice(int devindex)
|
|||
device->SetDisplayMode = WINRT_SetDisplayMode;
|
||||
device->PumpEvents = WINRT_PumpEvents;
|
||||
device->GetWindowWMInfo = WINRT_GetWindowWMInfo;
|
||||
device->SuspendScreenSaver = WINRT_SuspendScreenSaver;
|
||||
|
||||
#if NTDDI_VERSION >= NTDDI_WIN10
|
||||
device->HasScreenKeyboardSupport = WINRT_HasScreenKeyboardSupport;
|
||||
device->ShowScreenKeyboard = WINRT_ShowScreenKeyboard;
|
||||
device->HideScreenKeyboard = WINRT_HideScreenKeyboard;
|
||||
device->IsScreenKeyboardShown = WINRT_IsScreenKeyboardShown;
|
||||
#endif
|
||||
|
||||
#ifdef SDL_VIDEO_OPENGL_EGL
|
||||
device->GL_LoadLibrary = WINRT_GLES_LoadLibrary;
|
||||
device->GL_GetProcAddress = WINRT_GLES_GetProcAddress;
|
||||
|
|
@ -167,12 +181,17 @@ VideoBootStrap WINRT_bootstrap = {
|
|||
int
|
||||
WINRT_VideoInit(_THIS)
|
||||
{
|
||||
SDL_VideoData * driverdata = (SDL_VideoData *) _this->driverdata;
|
||||
if (WINRT_InitModes(_this) < 0) {
|
||||
return -1;
|
||||
}
|
||||
WINRT_InitMouse(_this);
|
||||
WINRT_InitTouch(_this);
|
||||
|
||||
WINRT_InitGameBar(_this);
|
||||
if (driverdata) {
|
||||
/* Initialize screensaver-disabling support */
|
||||
driverdata->displayRequest = WINRT_CreateDisplayRequest(_this);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -414,6 +433,12 @@ WINRT_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
|
|||
void
|
||||
WINRT_VideoQuit(_THIS)
|
||||
{
|
||||
SDL_VideoData * driverdata = (SDL_VideoData *) _this->driverdata;
|
||||
if (driverdata && driverdata->displayRequest) {
|
||||
driverdata->displayRequest->Release();
|
||||
driverdata->displayRequest = NULL;
|
||||
}
|
||||
WINRT_QuitGameBar(_this);
|
||||
WINRT_QuitMouse(_this);
|
||||
}
|
||||
|
||||
|
|
@ -483,7 +508,7 @@ WINRT_DetectWindowFlags(SDL_Window * window)
|
|||
// data->coreWindow->PointerPosition is not supported on WinPhone 8.0
|
||||
latestFlags |= SDL_WINDOW_MOUSE_FOCUS;
|
||||
#else
|
||||
if (data->coreWindow->Bounds.Contains(data->coreWindow->PointerPosition)) {
|
||||
if (data->coreWindow->Visible && data->coreWindow->Bounds.Contains(data->coreWindow->PointerPosition)) {
|
||||
latestFlags |= SDL_WINDOW_MOUSE_FOCUS;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -753,6 +778,65 @@ WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
|
|||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static ABI::Windows::System::Display::IDisplayRequest *
|
||||
WINRT_CreateDisplayRequest(_THIS)
|
||||
{
|
||||
/* Setup a WinRT DisplayRequest object, usable for enabling/disabling screensaver requests */
|
||||
wchar_t *wClassName = L"Windows.System.Display.DisplayRequest";
|
||||
HSTRING hClassName;
|
||||
IActivationFactory *pActivationFactory = NULL;
|
||||
IInspectable * pDisplayRequestRaw = nullptr;
|
||||
ABI::Windows::System::Display::IDisplayRequest * pDisplayRequest = nullptr;
|
||||
HRESULT hr;
|
||||
|
||||
hr = ::WindowsCreateString(wClassName, (UINT32)wcslen(wClassName), &hClassName);
|
||||
if (FAILED(hr)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
hr = Windows::Foundation::GetActivationFactory(hClassName, &pActivationFactory);
|
||||
if (FAILED(hr)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
hr = pActivationFactory->ActivateInstance(&pDisplayRequestRaw);
|
||||
if (FAILED(hr)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
hr = pDisplayRequestRaw->QueryInterface(IID_IDisplayRequest, (void **) &pDisplayRequest);
|
||||
if (FAILED(hr)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
if (pDisplayRequestRaw) {
|
||||
pDisplayRequestRaw->Release();
|
||||
}
|
||||
if (pActivationFactory) {
|
||||
pActivationFactory->Release();
|
||||
}
|
||||
if (hClassName) {
|
||||
::WindowsDeleteString(hClassName);
|
||||
}
|
||||
|
||||
return pDisplayRequest;
|
||||
}
|
||||
|
||||
void
|
||||
WINRT_SuspendScreenSaver(_THIS)
|
||||
{
|
||||
SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata;
|
||||
if (driverdata && driverdata->displayRequest) {
|
||||
ABI::Windows::System::Display::IDisplayRequest * displayRequest = (ABI::Windows::System::Display::IDisplayRequest *) driverdata->displayRequest;
|
||||
if (_this->suspend_screensaver) {
|
||||
displayRequest->RequestActive();
|
||||
} else {
|
||||
displayRequest->RequestRelease();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_WINRT */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
|||
|
|
@ -46,6 +46,17 @@ typedef struct SDL_VideoData {
|
|||
* passed to eglGetDisplay and eglCreateWindowSurface:
|
||||
*/
|
||||
IUnknown *winrtEglWindow;
|
||||
|
||||
/* Event token(s), for unregistering WinRT event handler(s).
|
||||
These are just a struct with a 64-bit integer inside them
|
||||
*/
|
||||
Windows::Foundation::EventRegistrationToken gameBarIsInputRedirectedToken;
|
||||
|
||||
/* A WinRT DisplayRequest, used for implementing SDL_*ScreenSaver() functions.
|
||||
* This is really a pointer to a 'ABI::Windows::System::Display::IDisplayRequest *',
|
||||
* It's casted to 'IUnknown *', to help with building SDL.
|
||||
*/
|
||||
IUnknown *displayRequest;
|
||||
} SDL_VideoData;
|
||||
|
||||
/* The global, WinRT, SDL Window.
|
||||
|
|
|
|||
|
|
@ -106,11 +106,8 @@ X11_GetSym(const char *fnname, int *pHasModule)
|
|||
#endif /* SDL_VIDEO_DRIVER_X11_DYNAMIC */
|
||||
|
||||
/* Define all the function pointers and wrappers... */
|
||||
#define SDL_X11_MODULE(modname)
|
||||
#define SDL_X11_SYM(rc,fn,params,args,ret) SDL_DYNX11FN_##fn X11_##fn = NULL;
|
||||
#include "SDL_x11sym.h"
|
||||
#undef SDL_X11_MODULE
|
||||
#undef SDL_X11_SYM
|
||||
|
||||
/* Annoying varargs entry point... */
|
||||
#ifdef X_HAVE_UTF8_STRING
|
||||
|
|
@ -120,10 +117,7 @@ SDL_DYNX11FN_XGetICValues X11_XGetICValues = NULL;
|
|||
|
||||
/* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */
|
||||
#define SDL_X11_MODULE(modname) int SDL_X11_HAVE_##modname = 0;
|
||||
#define SDL_X11_SYM(rc,fn,params,args,ret)
|
||||
#include "SDL_x11sym.h"
|
||||
#undef SDL_X11_MODULE
|
||||
#undef SDL_X11_SYM
|
||||
|
||||
static int x11_load_refcount = 0;
|
||||
|
||||
|
|
@ -139,8 +133,6 @@ SDL_X11_UnloadSymbols(void)
|
|||
#define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 0;
|
||||
#define SDL_X11_SYM(rc,fn,params,args,ret) X11_##fn = NULL;
|
||||
#include "SDL_x11sym.h"
|
||||
#undef SDL_X11_MODULE
|
||||
#undef SDL_X11_SYM
|
||||
|
||||
#ifdef X_HAVE_UTF8_STRING
|
||||
X11_XCreateIC = NULL;
|
||||
|
|
@ -177,16 +169,11 @@ SDL_X11_LoadSymbols(void)
|
|||
}
|
||||
|
||||
#define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 1; /* default yes */
|
||||
#define SDL_X11_SYM(a,fn,x,y,z)
|
||||
#include "SDL_x11sym.h"
|
||||
#undef SDL_X11_MODULE
|
||||
#undef SDL_X11_SYM
|
||||
|
||||
#define SDL_X11_MODULE(modname) thismod = &SDL_X11_HAVE_##modname;
|
||||
#define SDL_X11_SYM(a,fn,x,y,z) X11_##fn = (SDL_DYNX11FN_##fn) X11_GetSym(#fn,thismod);
|
||||
#include "SDL_x11sym.h"
|
||||
#undef SDL_X11_MODULE
|
||||
#undef SDL_X11_SYM
|
||||
|
||||
#ifdef X_HAVE_UTF8_STRING
|
||||
X11_XCreateIC = (SDL_DYNX11FN_XCreateIC)
|
||||
|
|
@ -209,8 +196,6 @@ SDL_X11_LoadSymbols(void)
|
|||
#define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 1; /* default yes */
|
||||
#define SDL_X11_SYM(a,fn,x,y,z) X11_##fn = (SDL_DYNX11FN_##fn) fn;
|
||||
#include "SDL_x11sym.h"
|
||||
#undef SDL_X11_MODULE
|
||||
#undef SDL_X11_SYM
|
||||
|
||||
#ifdef X_HAVE_UTF8_STRING
|
||||
X11_XCreateIC = XCreateIC;
|
||||
|
|
|
|||
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