mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-07-22 08:51:13 +00:00
Merge branch 'main' into no-ie
This commit is contained in:
@@ -574,9 +574,7 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc)
|
||||
if (src) {
|
||||
SDL_RWseek(src, fp_offset, RW_SEEK_SET);
|
||||
}
|
||||
if (surface) {
|
||||
SDL_FreeSurface(surface);
|
||||
}
|
||||
SDL_FreeSurface(surface);
|
||||
surface = NULL;
|
||||
}
|
||||
if (freesrc && src) {
|
||||
|
||||
@@ -244,37 +244,28 @@ SDL_bool SDL_EGL_HasExtension(_THIS, SDL_EGL_ExtensionType type, const char *ext
|
||||
void *
|
||||
SDL_EGL_GetProcAddress(_THIS, const char *proc)
|
||||
{
|
||||
const Uint32 eglver = (((Uint32) _this->egl_data->egl_version_major) << 16) | ((Uint32) _this->egl_data->egl_version_minor);
|
||||
const SDL_bool is_egl_15_or_later = eglver >= ((((Uint32) 1) << 16) | 5);
|
||||
void *retval = NULL;
|
||||
if (_this->egl_data != NULL) {
|
||||
const Uint32 eglver = (((Uint32) _this->egl_data->egl_version_major) << 16) | ((Uint32) _this->egl_data->egl_version_minor);
|
||||
const SDL_bool is_egl_15_or_later = eglver >= ((((Uint32) 1) << 16) | 5);
|
||||
|
||||
/* EGL 1.5 can use eglGetProcAddress() for any symbol. 1.4 and earlier can't use it for core entry points. */
|
||||
if (!retval && is_egl_15_or_later && _this->egl_data->eglGetProcAddress) {
|
||||
retval = _this->egl_data->eglGetProcAddress(proc);
|
||||
}
|
||||
/* EGL 1.5 can use eglGetProcAddress() for any symbol. 1.4 and earlier can't use it for core entry points. */
|
||||
if (!retval && is_egl_15_or_later && _this->egl_data->eglGetProcAddress) {
|
||||
retval = _this->egl_data->eglGetProcAddress(proc);
|
||||
}
|
||||
|
||||
#if !defined(__EMSCRIPTEN__) && !defined(SDL_VIDEO_DRIVER_VITA) /* LoadFunction isn't needed on Emscripten and will call dlsym(), causing other problems. */
|
||||
/* Try SDL_LoadFunction() first for EGL <= 1.4, or as a fallback for >= 1.5. */
|
||||
if (!retval) {
|
||||
static char procname[64];
|
||||
retval = SDL_LoadFunction(_this->egl_data->opengl_dll_handle, proc);
|
||||
/* just in case you need an underscore prepended... */
|
||||
if (!retval && (SDL_strlen(proc) < (sizeof (procname) - 1))) {
|
||||
procname[0] = '_';
|
||||
SDL_strlcpy(procname + 1, proc, sizeof (procname) - 1);
|
||||
retval = SDL_LoadFunction(_this->egl_data->opengl_dll_handle, procname);
|
||||
#if !defined(__EMSCRIPTEN__) && !defined(SDL_VIDEO_DRIVER_VITA) /* LoadFunction isn't needed on Emscripten and will call dlsym(), causing other problems. */
|
||||
/* Try SDL_LoadFunction() first for EGL <= 1.4, or as a fallback for >= 1.5. */
|
||||
if (!retval) {
|
||||
retval = SDL_LoadFunction(_this->egl_data->opengl_dll_handle, proc);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Try eglGetProcAddress if we're on <= 1.4 and still searching... */
|
||||
if (!retval && !is_egl_15_or_later && _this->egl_data->eglGetProcAddress) {
|
||||
retval = _this->egl_data->eglGetProcAddress(proc);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Try eglGetProcAddress if we're on <= 1.4 and still searching... */
|
||||
if (!retval && !is_egl_15_or_later && _this->egl_data->eglGetProcAddress) {
|
||||
retval = _this->egl_data->eglGetProcAddress(proc);
|
||||
if (retval) {
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -301,8 +292,8 @@ SDL_EGL_UnloadLibrary(_THIS)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
SDL_EGL_LoadLibraryOnly(_THIS, const char *egl_path)
|
||||
static int
|
||||
SDL_EGL_LoadLibraryInternal(_THIS, const char *egl_path)
|
||||
{
|
||||
void *egl_dll_handle = NULL, *opengl_dll_handle = NULL;
|
||||
const char *path = NULL;
|
||||
@@ -313,15 +304,6 @@ SDL_EGL_LoadLibraryOnly(_THIS, const char *egl_path)
|
||||
SDL_bool vc4 = (0 == access("/sys/module/vc4/", F_OK));
|
||||
#endif
|
||||
|
||||
if (_this->egl_data) {
|
||||
return SDL_SetError("EGL context already created");
|
||||
}
|
||||
|
||||
_this->egl_data = (struct SDL_EGL_VideoData *) SDL_calloc(1, sizeof(SDL_EGL_VideoData));
|
||||
if (!_this->egl_data) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT
|
||||
d3dcompiler = SDL_GetHint(SDL_HINT_VIDEO_WIN_D3DCOMPILER);
|
||||
if (d3dcompiler) {
|
||||
@@ -482,6 +464,26 @@ SDL_EGL_LoadLibraryOnly(_THIS, const char *egl_path)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_EGL_LoadLibraryOnly(_THIS, const char *egl_path)
|
||||
{
|
||||
if (_this->egl_data) {
|
||||
return SDL_SetError("EGL context already created");
|
||||
}
|
||||
|
||||
_this->egl_data = (struct SDL_EGL_VideoData *) SDL_calloc(1, sizeof(SDL_EGL_VideoData));
|
||||
if (!_this->egl_data) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
if (SDL_EGL_LoadLibraryInternal(_this, egl_path) < 0) {
|
||||
SDL_free(_this->egl_data);
|
||||
_this->egl_data = NULL;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_EGL_GetVersion(_THIS) {
|
||||
if (_this->egl_data->eglQueryString) {
|
||||
|
||||
@@ -436,6 +436,7 @@ SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask,
|
||||
return SDL_PIXELFORMAT_RGB24;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
if (Rmask == 0) {
|
||||
return SDL_PIXELFORMAT_RGB888;
|
||||
|
||||
@@ -400,9 +400,11 @@ SDL_INTERSECTRECTANDLINE(const RECTTYPE * rect, SCALARTYPE *X1, SCALARTYPE *Y1,
|
||||
outcode1 = COMPUTEOUTCODE(rect, x, y);
|
||||
} else {
|
||||
if (outcode2 & CODE_TOP) {
|
||||
SDL_assert(y2 != y1); /* if equal: division by zero. */
|
||||
y = recty1;
|
||||
x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
|
||||
} else if (outcode2 & CODE_BOTTOM) {
|
||||
SDL_assert(y2 != y1); /* if equal: division by zero. */
|
||||
y = recty2;
|
||||
x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
|
||||
} else if (outcode2 & CODE_LEFT) {
|
||||
|
||||
@@ -77,8 +77,12 @@ SDL_CalculateShapeBitmap(SDL_WindowShapeMode mode,SDL_Surface *shape,Uint8* bitm
|
||||
int bytes_per_scanline = (shape->w + (ppb - 1)) / ppb;
|
||||
Uint8 *bitmap_scanline;
|
||||
SDL_Color key;
|
||||
|
||||
if(SDL_MUSTLOCK(shape))
|
||||
SDL_LockSurface(shape);
|
||||
|
||||
SDL_memset(bitmap, 0, shape->h * bytes_per_scanline);
|
||||
|
||||
for(y = 0;y<shape->h;y++) {
|
||||
bitmap_scanline = bitmap + y * bytes_per_scanline;
|
||||
for(x=0;x<shape->w;x++) {
|
||||
@@ -118,6 +122,7 @@ SDL_CalculateShapeBitmap(SDL_WindowShapeMode mode,SDL_Surface *shape,Uint8* bitm
|
||||
bitmap_scanline[x / ppb] |= mask_value << (x % ppb);
|
||||
}
|
||||
}
|
||||
|
||||
if(SDL_MUSTLOCK(shape))
|
||||
SDL_UnlockSurface(shape);
|
||||
}
|
||||
@@ -257,20 +262,53 @@ SDL_FreeShapeTree(SDL_ShapeTree** shape_tree)
|
||||
int
|
||||
SDL_SetWindowShape(SDL_Window *window,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode)
|
||||
{
|
||||
SDL_VideoDevice *_this = SDL_GetVideoDevice();
|
||||
int result;
|
||||
if(window == NULL || !SDL_IsShapedWindow(window))
|
||||
|
||||
if (window == NULL || !SDL_IsShapedWindow(window)) {
|
||||
/* The window given was not a shapeable window. */
|
||||
return SDL_NONSHAPEABLE_WINDOW;
|
||||
if(shape == NULL)
|
||||
}
|
||||
if (shape == NULL) {
|
||||
/* Invalid shape argument. */
|
||||
return SDL_INVALID_SHAPE_ARGUMENT;
|
||||
}
|
||||
|
||||
if(shape_mode != NULL)
|
||||
if (shape_mode != NULL) {
|
||||
window->shaper->mode = *shape_mode;
|
||||
result = SDL_GetVideoDevice()->shape_driver.SetWindowShape(window->shaper,shape,shape_mode);
|
||||
}
|
||||
result = _this->shape_driver.SetWindowShape(window->shaper, shape, shape_mode);
|
||||
window->shaper->hasshape = SDL_TRUE;
|
||||
if(window->shaper->userx != 0 && window->shaper->usery != 0) {
|
||||
SDL_SetWindowPosition(window,window->shaper->userx,window->shaper->usery);
|
||||
if (window->shaper->userx != 0 && window->shaper->usery != 0) {
|
||||
int x = window->shaper->userx;
|
||||
int y = window->shaper->usery;
|
||||
|
||||
if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISUNDEFINED(y) ||
|
||||
SDL_WINDOWPOS_ISCENTERED(x) || SDL_WINDOWPOS_ISCENTERED(y)) {
|
||||
int displayIndex;
|
||||
SDL_Rect bounds;
|
||||
|
||||
if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISCENTERED(x)) {
|
||||
displayIndex = (x & 0xFFFF);
|
||||
if (displayIndex >= _this->num_displays) {
|
||||
displayIndex = 0;
|
||||
}
|
||||
} else {
|
||||
displayIndex = (y & 0xFFFF);
|
||||
if (displayIndex >= _this->num_displays) {
|
||||
displayIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_GetDisplayBounds(displayIndex, &bounds);
|
||||
if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISCENTERED(x)) {
|
||||
window->x = bounds.x + (bounds.w - window->w) / 2;
|
||||
}
|
||||
if (SDL_WINDOWPOS_ISUNDEFINED(y) || SDL_WINDOWPOS_ISCENTERED(y)) {
|
||||
window->y = bounds.y + (bounds.h - window->h) / 2;
|
||||
}
|
||||
}
|
||||
SDL_SetWindowPosition(window, x, y);
|
||||
window->shaper->userx = 0;
|
||||
window->shaper->usery = 0;
|
||||
}
|
||||
|
||||
@@ -230,7 +230,7 @@ SDL_CreateRGBSurfaceFrom(void *pixels,
|
||||
|
||||
minimalPitch = SDL_CalculatePitch(format, width, SDL_TRUE);
|
||||
|
||||
if (pitch < 0 || ((size_t) pitch) < minimalPitch) {
|
||||
if (pitch < 0 || (pitch > 0 && ((size_t) pitch) < minimalPitch)) {
|
||||
SDL_InvalidParamError("pitch");
|
||||
return NULL;
|
||||
}
|
||||
@@ -272,7 +272,7 @@ SDL_CreateRGBSurfaceWithFormatFrom(void *pixels,
|
||||
|
||||
minimalPitch = SDL_CalculatePitch(format, width, SDL_TRUE);
|
||||
|
||||
if (pitch < 0 || ((size_t) pitch) < minimalPitch) {
|
||||
if (pitch < 0 || (pitch > 0 && ((size_t) pitch) < minimalPitch)) {
|
||||
SDL_InvalidParamError("pitch");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -450,7 +450,6 @@ typedef struct VideoBootStrap
|
||||
/* Not all of these are available in a given build. Use #ifdefs, etc. */
|
||||
extern VideoBootStrap COCOA_bootstrap;
|
||||
extern VideoBootStrap X11_bootstrap;
|
||||
extern VideoBootStrap DirectFB_bootstrap;
|
||||
extern VideoBootStrap WINDOWS_bootstrap;
|
||||
extern VideoBootStrap WINRT_bootstrap;
|
||||
extern VideoBootStrap HAIKU_bootstrap;
|
||||
@@ -461,20 +460,17 @@ extern VideoBootStrap PS2_bootstrap;
|
||||
extern VideoBootStrap PSP_bootstrap;
|
||||
extern VideoBootStrap VITA_bootstrap;
|
||||
extern VideoBootStrap RISCOS_bootstrap;
|
||||
extern VideoBootStrap N3DS_bootstrap;
|
||||
extern VideoBootStrap RPI_bootstrap;
|
||||
extern VideoBootStrap KMSDRM_bootstrap;
|
||||
extern VideoBootStrap KMSDRM_LEGACY_bootstrap;
|
||||
extern VideoBootStrap DUMMY_bootstrap;
|
||||
extern VideoBootStrap DUMMY_evdev_bootstrap;
|
||||
extern VideoBootStrap Wayland_bootstrap;
|
||||
extern VideoBootStrap NACL_bootstrap;
|
||||
extern VideoBootStrap VIVANTE_bootstrap;
|
||||
extern VideoBootStrap Emscripten_bootstrap;
|
||||
extern VideoBootStrap QNX_bootstrap;
|
||||
extern VideoBootStrap OFFSCREEN_bootstrap;
|
||||
extern VideoBootStrap NGAGE_bootstrap;
|
||||
extern VideoBootStrap OS2DIVE_bootstrap;
|
||||
extern VideoBootStrap OS2VMAN_bootstrap;
|
||||
|
||||
/* Use SDL_OnVideoThread() sparingly, to avoid regressions in use cases that currently happen to work */
|
||||
extern SDL_bool SDL_OnVideoThread(void);
|
||||
|
||||
@@ -56,6 +56,13 @@
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
#ifdef __LINUX__
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* Available video drivers */
|
||||
static VideoBootStrap *bootstrap[] = {
|
||||
#if SDL_VIDEO_DRIVER_COCOA
|
||||
@@ -70,9 +77,6 @@ static VideoBootStrap *bootstrap[] = {
|
||||
#if SDL_VIDEO_DRIVER_VIVANTE
|
||||
&VIVANTE_bootstrap,
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_DIRECTFB
|
||||
&DirectFB_bootstrap,
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_WINDOWS
|
||||
&WINDOWS_bootstrap,
|
||||
#endif
|
||||
@@ -82,9 +86,6 @@ static VideoBootStrap *bootstrap[] = {
|
||||
#if SDL_VIDEO_DRIVER_HAIKU
|
||||
&HAIKU_bootstrap,
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_PANDORA
|
||||
&PND_bootstrap,
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_UIKIT
|
||||
&UIKIT_bootstrap,
|
||||
#endif
|
||||
@@ -100,6 +101,9 @@ static VideoBootStrap *bootstrap[] = {
|
||||
#if SDL_VIDEO_DRIVER_VITA
|
||||
&VITA_bootstrap,
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_N3DS
|
||||
&N3DS_bootstrap,
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_KMSDRM
|
||||
&KMSDRM_bootstrap,
|
||||
#endif
|
||||
@@ -109,25 +113,15 @@ static VideoBootStrap *bootstrap[] = {
|
||||
#if SDL_VIDEO_DRIVER_RPI
|
||||
&RPI_bootstrap,
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_NACL
|
||||
&NACL_bootstrap,
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_EMSCRIPTEN
|
||||
&Emscripten_bootstrap,
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_QNX
|
||||
&QNX_bootstrap,
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_OFFSCREEN
|
||||
&OFFSCREEN_bootstrap,
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_NGAGE
|
||||
&NGAGE_bootstrap,
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_OS2
|
||||
&OS2DIVE_bootstrap,
|
||||
&OS2VMAN_bootstrap,
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_DUMMY
|
||||
&DUMMY_bootstrap,
|
||||
#if SDL_INPUT_LINUXEV
|
||||
@@ -192,6 +186,22 @@ typedef struct {
|
||||
} SDL_WindowTextureData;
|
||||
|
||||
|
||||
static Uint32
|
||||
SDL_DefaultGraphicsBackends(SDL_VideoDevice *_this)
|
||||
{
|
||||
#if (SDL_VIDEO_OPENGL && __MACOSX__) || (__IPHONEOS__ && !TARGET_OS_MACCATALYST) || __ANDROID__
|
||||
if (_this->GL_CreateContext != NULL) {
|
||||
return SDL_WINDOW_OPENGL;
|
||||
}
|
||||
#endif
|
||||
#if SDL_VIDEO_METAL && (TARGET_OS_MACCATALYST || __MACOSX__ || __IPHONEOS__)
|
||||
if (_this->Metal_CreateView != NULL) {
|
||||
return SDL_WINDOW_METAL;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
SDL_CreateWindowTexture(SDL_VideoDevice *_this, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch)
|
||||
{
|
||||
@@ -413,7 +423,7 @@ SDL_VideoInit(const char *driver_name)
|
||||
SDL_bool init_keyboard = SDL_FALSE;
|
||||
SDL_bool init_mouse = SDL_FALSE;
|
||||
SDL_bool init_touch = SDL_FALSE;
|
||||
int i;
|
||||
int i = 0;
|
||||
|
||||
/* Check to make sure we don't overwrite '_this' */
|
||||
if (_this != NULL) {
|
||||
@@ -684,29 +694,33 @@ SDL_GetDisplayName(int displayIndex)
|
||||
int
|
||||
SDL_GetDisplayBounds(int displayIndex, SDL_Rect * rect)
|
||||
{
|
||||
SDL_VideoDisplay *display;
|
||||
|
||||
CHECK_DISPLAY_INDEX(displayIndex, -1);
|
||||
|
||||
if (rect) {
|
||||
SDL_VideoDisplay *display = &_this->displays[displayIndex];
|
||||
|
||||
if (_this->GetDisplayBounds) {
|
||||
if (_this->GetDisplayBounds(_this, display, rect) == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Assume that the displays are left to right */
|
||||
if (displayIndex == 0) {
|
||||
rect->x = 0;
|
||||
rect->y = 0;
|
||||
} else {
|
||||
SDL_GetDisplayBounds(displayIndex-1, rect);
|
||||
rect->x += rect->w;
|
||||
}
|
||||
rect->w = display->current_mode.w;
|
||||
rect->h = display->current_mode.h;
|
||||
if (!rect) {
|
||||
return SDL_InvalidParamError("rect");
|
||||
}
|
||||
return 0; /* !!! FIXME: should this be an error if (rect==NULL) ? */
|
||||
|
||||
display = &_this->displays[displayIndex];
|
||||
|
||||
if (_this->GetDisplayBounds) {
|
||||
if (_this->GetDisplayBounds(_this, display, rect) == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Assume that the displays are left to right */
|
||||
if (displayIndex == 0) {
|
||||
rect->x = 0;
|
||||
rect->y = 0;
|
||||
} else {
|
||||
SDL_GetDisplayBounds(displayIndex-1, rect);
|
||||
rect->x += rect->w;
|
||||
}
|
||||
rect->w = display->current_mode.w;
|
||||
rect->h = display->current_mode.h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -719,25 +733,28 @@ ParseDisplayUsableBoundsHint(SDL_Rect *rect)
|
||||
int
|
||||
SDL_GetDisplayUsableBounds(int displayIndex, SDL_Rect * rect)
|
||||
{
|
||||
SDL_VideoDisplay *display;
|
||||
|
||||
CHECK_DISPLAY_INDEX(displayIndex, -1);
|
||||
|
||||
if (rect) {
|
||||
SDL_VideoDisplay *display = &_this->displays[displayIndex];
|
||||
if (!rect) {
|
||||
return SDL_InvalidParamError("rect");
|
||||
}
|
||||
|
||||
if ((displayIndex == 0) && ParseDisplayUsableBoundsHint(rect)) {
|
||||
display = &_this->displays[displayIndex];
|
||||
|
||||
if ((displayIndex == 0) && ParseDisplayUsableBoundsHint(rect)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_this->GetDisplayUsableBounds) {
|
||||
if (_this->GetDisplayUsableBounds(_this, display, rect) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
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) ? */
|
||||
|
||||
/* Oh well, just give the entire display bounds. */
|
||||
return SDL_GetDisplayBounds(displayIndex, rect);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -1239,7 +1256,7 @@ SDL_SetWindowDisplayMode(SDL_Window * window, const SDL_DisplayMode * mode)
|
||||
SDL_DisplayMode fullscreen_mode;
|
||||
if (SDL_GetWindowDisplayMode(window, &fullscreen_mode) == 0) {
|
||||
if (SDL_SetDisplayModeForDisplay(SDL_GetDisplayForWindow(window), &fullscreen_mode) == 0) {
|
||||
#ifndef ANDROID
|
||||
#ifndef __ANDROID__
|
||||
/* Android may not resize the window to exactly what our fullscreen mode is, especially on
|
||||
* windowed Android environments like the Chromebook or Samsung DeX. Given this, we shouldn't
|
||||
* use fullscreen_mode.w and fullscreen_mode.h, but rather get our current native size. As such,
|
||||
@@ -1285,9 +1302,8 @@ SDL_GetWindowDisplayMode(SDL_Window * window, SDL_DisplayMode * mode)
|
||||
return SDL_SetError("Couldn't find display mode match");
|
||||
}
|
||||
|
||||
if (mode) {
|
||||
*mode = fullscreen_mode;
|
||||
}
|
||||
*mode = fullscreen_mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1453,7 +1469,7 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen)
|
||||
|
||||
/* Generate a mode change event here */
|
||||
if (resized) {
|
||||
#if !defined(ANDROID) && !defined(WIN32)
|
||||
#if !defined(__ANDROID__) && !defined(__WIN32__)
|
||||
/* Android may not resize the window to exactly what our fullscreen mode is, especially on
|
||||
* windowed Android environments like the Chromebook or Samsung DeX. Given this, we shouldn't
|
||||
* use fullscreen_mode.w and fullscreen_mode.h, but rather get our current native size. As such,
|
||||
@@ -1562,11 +1578,25 @@ SDL_FinishWindowCreation(SDL_Window *window, Uint32 flags)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
SDL_ContextNotSupported(const char *name)
|
||||
{
|
||||
return SDL_SetError("%s support is either not configured in SDL "
|
||||
"or not available in current SDL video driver "
|
||||
"(%s) or platform", name, _this->name);
|
||||
}
|
||||
|
||||
static int
|
||||
SDL_DllNotSupported(const char *name)
|
||||
{
|
||||
return SDL_SetError("No dynamic %s support in current SDL video driver (%s)", name, _this->name);
|
||||
}
|
||||
|
||||
SDL_Window *
|
||||
SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
|
||||
{
|
||||
SDL_Window *window;
|
||||
Uint32 graphics_flags = flags & (SDL_WINDOW_OPENGL | SDL_WINDOW_METAL | SDL_WINDOW_VULKAN);
|
||||
Uint32 type_flags, graphics_flags;
|
||||
|
||||
if (!_this) {
|
||||
/* Initialize the video system if needed */
|
||||
@@ -1575,7 +1605,9 @@ 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) {
|
||||
/* ensure no more than one of these flags is set */
|
||||
type_flags = flags & (SDL_WINDOW_UTILITY | SDL_WINDOW_TOOLTIP | SDL_WINDOW_POPUP_MENU);
|
||||
if ((type_flags & (type_flags - 1)) != 0) {
|
||||
SDL_SetError("Conflicting window flags specified");
|
||||
return NULL;
|
||||
}
|
||||
@@ -1594,25 +1626,21 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ensure no more than one of these flags is set */
|
||||
graphics_flags = flags & (SDL_WINDOW_OPENGL | SDL_WINDOW_METAL | SDL_WINDOW_VULKAN);
|
||||
if ((graphics_flags & (graphics_flags - 1)) != 0) {
|
||||
SDL_SetError("Conflicting window flags specified");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Some platforms have certain graphics backends enabled by default */
|
||||
if (!graphics_flags && !SDL_IsVideoContextExternal()) {
|
||||
#if (SDL_VIDEO_OPENGL && __MACOSX__) || (__IPHONEOS__ && !TARGET_OS_MACCATALYST) || __ANDROID__ || __NACL__
|
||||
if (_this->GL_CreateContext != NULL) {
|
||||
flags |= SDL_WINDOW_OPENGL;
|
||||
}
|
||||
#endif
|
||||
#if SDL_VIDEO_METAL && (TARGET_OS_MACCATALYST || __MACOSX__ || __IPHONEOS__)
|
||||
if (_this->Metal_CreateView != NULL) {
|
||||
flags |= SDL_WINDOW_METAL;
|
||||
}
|
||||
#endif
|
||||
flags |= SDL_DefaultGraphicsBackends(_this);
|
||||
}
|
||||
|
||||
if (flags & SDL_WINDOW_OPENGL) {
|
||||
if (!_this->GL_CreateContext) {
|
||||
SDL_SetError("OpenGL support is either not configured in SDL "
|
||||
"or not available in current SDL video driver "
|
||||
"(%s) or platform", _this->name);
|
||||
SDL_ContextNotSupported("OpenGL");
|
||||
return NULL;
|
||||
}
|
||||
if (SDL_GL_LoadLibrary(NULL) < 0) {
|
||||
@@ -1622,13 +1650,7 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
|
||||
|
||||
if (flags & SDL_WINDOW_VULKAN) {
|
||||
if (!_this->Vulkan_CreateSurface) {
|
||||
SDL_SetError("Vulkan support is either not configured in SDL "
|
||||
"or not available in current SDL video driver "
|
||||
"(%s) or platform", _this->name);
|
||||
return NULL;
|
||||
}
|
||||
if (graphics_flags & SDL_WINDOW_OPENGL) {
|
||||
SDL_SetError("Vulkan and OpenGL not supported on same window");
|
||||
SDL_ContextNotSupported("Vulkan");
|
||||
return NULL;
|
||||
}
|
||||
if (SDL_Vulkan_LoadLibrary(NULL) < 0) {
|
||||
@@ -1638,19 +1660,7 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
|
||||
|
||||
if (flags & SDL_WINDOW_METAL) {
|
||||
if (!_this->Metal_CreateView) {
|
||||
SDL_SetError("Metal support is either not configured in SDL "
|
||||
"or not available in current SDL video driver "
|
||||
"(%s) or platform", _this->name);
|
||||
return NULL;
|
||||
}
|
||||
/* 'flags' may have default flags appended, don't check against that. */
|
||||
if (graphics_flags & SDL_WINDOW_OPENGL) {
|
||||
SDL_SetError("Metal and OpenGL not supported on same window");
|
||||
return NULL;
|
||||
}
|
||||
if (graphics_flags & SDL_WINDOW_VULKAN) {
|
||||
SDL_SetError("Metal and Vulkan not supported on same window. "
|
||||
"To use MoltenVK, set SDL_WINDOW_VULKAN only.");
|
||||
SDL_ContextNotSupported("Metal");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -1792,9 +1802,7 @@ SDL_CreateWindowFrom(const void *data)
|
||||
|
||||
if (SDL_GetHintBoolean(SDL_HINT_VIDEO_FOREIGN_WINDOW_OPENGL, SDL_FALSE)) {
|
||||
if (!_this->GL_CreateContext) {
|
||||
SDL_SetError("OpenGL support is either not configured in SDL "
|
||||
"or not available in current SDL video driver "
|
||||
"(%s) or platform", _this->name);
|
||||
SDL_ContextNotSupported("OpenGL");
|
||||
return NULL;
|
||||
}
|
||||
if (SDL_GL_LoadLibrary(NULL) < 0) {
|
||||
@@ -1805,9 +1813,7 @@ SDL_CreateWindowFrom(const void *data)
|
||||
|
||||
if (SDL_GetHintBoolean(SDL_HINT_VIDEO_FOREIGN_WINDOW_VULKAN, SDL_FALSE)) {
|
||||
if (!_this->Vulkan_CreateSurface) {
|
||||
SDL_SetError("Vulkan support is either not configured in SDL "
|
||||
"or not available in current SDL video driver "
|
||||
"(%s) or platform", _this->name);
|
||||
SDL_ContextNotSupported("Vulkan");
|
||||
return NULL;
|
||||
}
|
||||
if (flags & SDL_WINDOW_OPENGL) {
|
||||
@@ -1858,11 +1864,22 @@ SDL_RecreateWindow(SDL_Window * window, Uint32 flags)
|
||||
SDL_bool loaded_vulkan = SDL_FALSE;
|
||||
SDL_bool need_vulkan_unload = SDL_FALSE;
|
||||
SDL_bool need_vulkan_load = SDL_FALSE;
|
||||
Uint32 graphics_flags;
|
||||
|
||||
/* ensure no more than one of these flags is set */
|
||||
graphics_flags = flags & (SDL_WINDOW_OPENGL | SDL_WINDOW_METAL | SDL_WINDOW_VULKAN);
|
||||
if ((graphics_flags & (graphics_flags - 1)) != 0) {
|
||||
return SDL_SetError("Conflicting window flags specified");
|
||||
}
|
||||
|
||||
if ((flags & SDL_WINDOW_OPENGL) && !_this->GL_CreateContext) {
|
||||
return SDL_SetError("OpenGL support is either not configured in SDL "
|
||||
"or not available in current SDL video driver "
|
||||
"(%s) or platform", _this->name);
|
||||
return SDL_ContextNotSupported("OpenGL");
|
||||
}
|
||||
if ((flags & SDL_WINDOW_VULKAN) && !_this->Vulkan_CreateSurface) {
|
||||
return SDL_ContextNotSupported("Vulkan");
|
||||
}
|
||||
if ((flags & SDL_WINDOW_METAL) && !_this->Metal_CreateView) {
|
||||
return SDL_ContextNotSupported("Metal");
|
||||
}
|
||||
|
||||
if (window->flags & SDL_WINDOW_FOREIGN) {
|
||||
@@ -1917,18 +1934,6 @@ SDL_RecreateWindow(SDL_Window * window, Uint32 flags)
|
||||
need_vulkan_load = SDL_TRUE;
|
||||
}
|
||||
|
||||
if ((flags & SDL_WINDOW_VULKAN) && (flags & SDL_WINDOW_OPENGL)) {
|
||||
return SDL_SetError("Vulkan and OpenGL not supported on same window");
|
||||
}
|
||||
|
||||
if ((flags & SDL_WINDOW_METAL) && (flags & SDL_WINDOW_OPENGL)) {
|
||||
return SDL_SetError("Metal and OpenGL not supported on same window");
|
||||
}
|
||||
|
||||
if ((flags & SDL_WINDOW_METAL) && (flags & SDL_WINDOW_VULKAN)) {
|
||||
return SDL_SetError("Metal and Vulkan not supported on same window");
|
||||
}
|
||||
|
||||
if (need_gl_unload) {
|
||||
SDL_GL_UnloadLibrary();
|
||||
}
|
||||
@@ -2637,16 +2642,25 @@ SDL_CreateWindowFramebuffer(SDL_Window * window)
|
||||
attempt_texture_framebuffer = SDL_FALSE;
|
||||
}
|
||||
|
||||
#if defined(__WIN32__) || defined(__WINGDK__) /* GDI BitBlt() is way faster than Direct3D dynamic textures right now. (!!! FIXME: is this still true?) */
|
||||
#if defined(__LINUX__)
|
||||
/* On WSL, direct X11 is faster than using OpenGL for window framebuffers, so try to detect WSL and avoid texture framebuffer. */
|
||||
else if ((_this->CreateWindowFramebuffer != NULL) && (SDL_strcmp(_this->name, "x11") == 0)) {
|
||||
struct stat sb;
|
||||
if ((stat("/proc/sys/fs/binfmt_misc/WSLInterop", &sb) == 0) || (stat("/run/WSL", &sb) == 0)) { /* if either of these exist, we're on WSL. */
|
||||
attempt_texture_framebuffer = SDL_FALSE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(__WIN32__) || defined(__WINGDK__) /* GDI BitBlt() is way faster than Direct3D dynamic textures right now. (!!! FIXME: is this still true?) */
|
||||
else if ((_this->CreateWindowFramebuffer != NULL) && (SDL_strcmp(_this->name, "windows") == 0)) {
|
||||
attempt_texture_framebuffer = SDL_FALSE;
|
||||
}
|
||||
#endif
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
#endif
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
else {
|
||||
attempt_texture_framebuffer = SDL_FALSE;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (attempt_texture_framebuffer) {
|
||||
if (SDL_CreateWindowTexture(_this, window, &format, &pixels, &pitch) == -1) {
|
||||
@@ -3416,7 +3430,7 @@ SDL_GL_LoadLibrary(const char *path)
|
||||
retval = 0;
|
||||
} else {
|
||||
if (!_this->GL_LoadLibrary) {
|
||||
return SDL_SetError("No dynamic GL support in current SDL video driver (%s)", _this->name);
|
||||
return SDL_DllNotSupported("OpenGL");
|
||||
}
|
||||
retval = _this->GL_LoadLibrary(_this, path);
|
||||
}
|
||||
@@ -3724,7 +3738,7 @@ SDL_GL_SetAttribute(SDL_GLattr attr, int value)
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
||||
} else {
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0);
|
||||
};
|
||||
}
|
||||
break;
|
||||
case SDL_GL_CONTEXT_FLAGS:
|
||||
if (value & ~(SDL_GL_CONTEXT_DEBUG_FLAG |
|
||||
@@ -4033,6 +4047,8 @@ SDL_GL_GetAttribute(SDL_GLattr attr, int *value)
|
||||
#endif /* SDL_VIDEO_OPENGL */
|
||||
}
|
||||
|
||||
#define NOT_AN_OPENGL_WINDOW "The specified window isn't an OpenGL window"
|
||||
|
||||
SDL_GLContext
|
||||
SDL_GL_CreateContext(SDL_Window * window)
|
||||
{
|
||||
@@ -4040,7 +4056,7 @@ SDL_GL_CreateContext(SDL_Window * window)
|
||||
CHECK_WINDOW_MAGIC(window, NULL);
|
||||
|
||||
if (!(window->flags & SDL_WINDOW_OPENGL)) {
|
||||
SDL_SetError("The specified window isn't an OpenGL window");
|
||||
SDL_SetError(NOT_AN_OPENGL_WINDOW);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -4077,7 +4093,7 @@ SDL_GL_MakeCurrent(SDL_Window * window, SDL_GLContext ctx)
|
||||
CHECK_WINDOW_MAGIC(window, -1);
|
||||
|
||||
if (!(window->flags & SDL_WINDOW_OPENGL)) {
|
||||
return SDL_SetError("The specified window isn't an OpenGL window");
|
||||
return SDL_SetError(NOT_AN_OPENGL_WINDOW);
|
||||
}
|
||||
} else if (!_this->gl_allow_no_surface) {
|
||||
return SDL_SetError("Use of OpenGL without a window is not supported on this platform");
|
||||
@@ -4158,7 +4174,7 @@ SDL_GL_SwapWindowWithResult(SDL_Window * window)
|
||||
CHECK_WINDOW_MAGIC(window, -1);
|
||||
|
||||
if (!(window->flags & SDL_WINDOW_OPENGL)) {
|
||||
return SDL_SetError("The specified window isn't an OpenGL window");
|
||||
return SDL_SetError(NOT_AN_OPENGL_WINDOW);
|
||||
}
|
||||
|
||||
if (SDL_GL_GetCurrentWindow() != window) {
|
||||
@@ -4311,8 +4327,8 @@ SDL_StartTextInput(void)
|
||||
SDL_Window *window;
|
||||
|
||||
/* First, enable text events */
|
||||
SDL_EventState(SDL_TEXTINPUT, SDL_ENABLE);
|
||||
SDL_EventState(SDL_TEXTEDITING, SDL_ENABLE);
|
||||
(void)SDL_EventState(SDL_TEXTINPUT, SDL_ENABLE);
|
||||
(void)SDL_EventState(SDL_TEXTEDITING, SDL_ENABLE);
|
||||
|
||||
/* Then show the on-screen keyboard, if any */
|
||||
window = SDL_GetFocusWindow();
|
||||
@@ -4367,8 +4383,8 @@ SDL_StopTextInput(void)
|
||||
}
|
||||
|
||||
/* Finally disable text events */
|
||||
SDL_EventState(SDL_TEXTINPUT, SDL_DISABLE);
|
||||
SDL_EventState(SDL_TEXTEDITING, SDL_DISABLE);
|
||||
(void)SDL_EventState(SDL_TEXTINPUT, SDL_DISABLE);
|
||||
(void)SDL_EventState(SDL_TEXTEDITING, SDL_DISABLE);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -4427,9 +4443,6 @@ SDL_GetMessageBoxCount(void)
|
||||
#if SDL_VIDEO_DRIVER_HAIKU
|
||||
#include "haiku/SDL_bmessagebox.h"
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_OS2
|
||||
#include "os2/SDL_os2messagebox.h"
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_RISCOS
|
||||
#include "riscos/SDL_riscosmessagebox.h"
|
||||
#endif
|
||||
@@ -4437,7 +4450,7 @@ SDL_GetMessageBoxCount(void)
|
||||
#include "vita/SDL_vitamessagebox.h"
|
||||
#endif
|
||||
|
||||
#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT || SDL_VIDEO_DRIVER_COCOA || SDL_VIDEO_DRIVER_UIKIT || SDL_VIDEO_DRIVER_X11 || SDL_VIDEO_DRIVER_WAYLAND || SDL_VIDEO_DRIVER_HAIKU || SDL_VIDEO_DRIVER_OS2 || SDL_VIDEO_DRIVER_RISCOS
|
||||
#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT || SDL_VIDEO_DRIVER_COCOA || SDL_VIDEO_DRIVER_UIKIT || SDL_VIDEO_DRIVER_X11 || SDL_VIDEO_DRIVER_WAYLAND || SDL_VIDEO_DRIVER_HAIKU || SDL_VIDEO_DRIVER_RISCOS
|
||||
static SDL_bool SDL_MessageboxValidForDriver(const SDL_MessageBoxData *messageboxdata, SDL_SYSWM_TYPE drivertype)
|
||||
{
|
||||
SDL_SysWMinfo info;
|
||||
@@ -4552,13 +4565,6 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
|
||||
retval = 0;
|
||||
}
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_OS2
|
||||
if (retval == -1 &&
|
||||
SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_OS2) &&
|
||||
OS2_ShowMessageBox(messageboxdata, buttonid) == 0) {
|
||||
retval = 0;
|
||||
}
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_RISCOS
|
||||
if (retval == -1 &&
|
||||
SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_RISCOS) &&
|
||||
@@ -4727,9 +4733,7 @@ int SDL_Vulkan_LoadLibrary(const char *path)
|
||||
retval = 0;
|
||||
} else {
|
||||
if (!_this->Vulkan_LoadLibrary) {
|
||||
return SDL_SetError("Vulkan support is either not configured in SDL "
|
||||
"or not available in current SDL video driver "
|
||||
"(%s) or platform", _this->name);
|
||||
return SDL_DllNotSupported("Vulkan");
|
||||
}
|
||||
retval = _this->Vulkan_LoadLibrary(_this, path);
|
||||
}
|
||||
@@ -4829,16 +4833,19 @@ SDL_Metal_CreateView(SDL_Window * window)
|
||||
CHECK_WINDOW_MAGIC(window, NULL);
|
||||
|
||||
if (!(window->flags & SDL_WINDOW_METAL)) {
|
||||
SDL_SetError("The specified window isn't a Metal window");
|
||||
return NULL;
|
||||
/* No problem, we can convert to Metal */
|
||||
if (window->flags & SDL_WINDOW_OPENGL) {
|
||||
window->flags &= ~SDL_WINDOW_OPENGL;
|
||||
SDL_GL_UnloadLibrary();
|
||||
}
|
||||
if (window->flags & SDL_WINDOW_VULKAN) {
|
||||
window->flags &= ~SDL_WINDOW_VULKAN;
|
||||
SDL_Vulkan_UnloadLibrary();
|
||||
}
|
||||
window->flags |= SDL_WINDOW_METAL;
|
||||
}
|
||||
|
||||
if (_this->Metal_CreateView) {
|
||||
return _this->Metal_CreateView(_this, window);
|
||||
} else {
|
||||
SDL_SetError("Metal is not supported.");
|
||||
return NULL;
|
||||
}
|
||||
return _this->Metal_CreateView(_this, window);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -37,9 +37,6 @@
|
||||
#define VK_USE_PLATFORM_METAL_EXT
|
||||
#define VK_USE_PLATFORM_MACOS_MVK
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_DIRECTFB
|
||||
#define VK_USE_PLATFORM_DIRECTFB_EXT
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_UIKIT
|
||||
#define VK_USE_PLATFORM_METAL_EXT
|
||||
#define VK_USE_PLATFORM_IOS_MVK
|
||||
|
||||
@@ -601,9 +601,12 @@ SDL_ConvertPixels_ARGB8888_to_YUV(int width, int height, const void *src, int sr
|
||||
Uint8 *plane_interleaved_uv;
|
||||
Uint32 y_stride, uv_stride, y_skip, uv_skip;
|
||||
|
||||
GetYUVPlanes(width, height, dst_format, dst, dst_pitch,
|
||||
(const Uint8 **)&plane_y, (const Uint8 **)&plane_u, (const Uint8 **)&plane_v,
|
||||
&y_stride, &uv_stride);
|
||||
if (GetYUVPlanes(width, height, dst_format, dst, dst_pitch,
|
||||
(const Uint8 **)&plane_y, (const Uint8 **)&plane_u, (const Uint8 **)&plane_v,
|
||||
&y_stride, &uv_stride) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
plane_interleaved_uv = (plane_y + height * y_stride);
|
||||
y_skip = (y_stride - width);
|
||||
|
||||
|
||||
@@ -66,6 +66,11 @@
|
||||
str = [aString UTF8String];
|
||||
}
|
||||
|
||||
/* We're likely sending the composed text, so we reset the IME status. */
|
||||
if ([self hasMarkedText]) {
|
||||
[self unmarkText];
|
||||
}
|
||||
|
||||
SDL_SendKeyboardText(str);
|
||||
}
|
||||
|
||||
@@ -114,7 +119,7 @@
|
||||
(int) selectedRange.location, (int) selectedRange.length);
|
||||
|
||||
DEBUG_IME(@"setMarkedText: %@, (%d, %d)", _markedText,
|
||||
selRange.location, selRange.length);
|
||||
selectedRange.location, selectedRange.length);
|
||||
}
|
||||
|
||||
- (void)unmarkText
|
||||
@@ -177,209 +182,49 @@
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/* This is a helper function for HandleModifierSide. This
|
||||
* function reverts back to behavior before the distinction between
|
||||
* sides was made.
|
||||
*/
|
||||
static void
|
||||
HandleNonDeviceModifier(unsigned int device_independent_mask,
|
||||
unsigned int oldMods,
|
||||
unsigned int newMods,
|
||||
SDL_Scancode scancode)
|
||||
{
|
||||
unsigned int oldMask, newMask;
|
||||
|
||||
/* Isolate just the bits we care about in the depedent bits so we can
|
||||
* figure out what changed
|
||||
*/
|
||||
oldMask = oldMods & device_independent_mask;
|
||||
newMask = newMods & device_independent_mask;
|
||||
|
||||
if (oldMask && oldMask != newMask) {
|
||||
SDL_SendKeyboardKey(SDL_RELEASED, scancode);
|
||||
} else if (newMask && oldMask != newMask) {
|
||||
SDL_SendKeyboardKey(SDL_PRESSED, scancode);
|
||||
}
|
||||
}
|
||||
|
||||
/* This is a helper function for HandleModifierSide.
|
||||
* This function sets the actual SDL_PrivateKeyboard event.
|
||||
*/
|
||||
static void
|
||||
HandleModifierOneSide(unsigned int oldMods, unsigned int newMods,
|
||||
SDL_Scancode scancode,
|
||||
unsigned int sided_device_dependent_mask)
|
||||
{
|
||||
unsigned int old_dep_mask, new_dep_mask;
|
||||
|
||||
/* Isolate just the bits we care about in the depedent bits so we can
|
||||
* figure out what changed
|
||||
*/
|
||||
old_dep_mask = oldMods & sided_device_dependent_mask;
|
||||
new_dep_mask = newMods & sided_device_dependent_mask;
|
||||
|
||||
/* We now know that this side bit flipped. But we don't know if
|
||||
* it went pressed to released or released to pressed, so we must
|
||||
* find out which it is.
|
||||
*/
|
||||
if (new_dep_mask && old_dep_mask != new_dep_mask) {
|
||||
SDL_SendKeyboardKey(SDL_PRESSED, scancode);
|
||||
} else {
|
||||
SDL_SendKeyboardKey(SDL_RELEASED, scancode);
|
||||
}
|
||||
}
|
||||
|
||||
/* This is a helper function for DoSidedModifiers.
|
||||
* This function will figure out if the modifier key is the left or right side,
|
||||
* e.g. left-shift vs right-shift.
|
||||
*/
|
||||
static void
|
||||
HandleModifierSide(int device_independent_mask,
|
||||
unsigned int oldMods, unsigned int newMods,
|
||||
SDL_Scancode left_scancode,
|
||||
SDL_Scancode right_scancode,
|
||||
unsigned int left_device_dependent_mask,
|
||||
unsigned int right_device_dependent_mask)
|
||||
{
|
||||
unsigned int device_dependent_mask = (left_device_dependent_mask |
|
||||
right_device_dependent_mask);
|
||||
unsigned int diff_mod;
|
||||
|
||||
/* On the basis that the device independent mask is set, but there are
|
||||
* no device dependent flags set, we'll assume that we can't detect this
|
||||
* keyboard and revert to the unsided behavior.
|
||||
*/
|
||||
if ((device_dependent_mask & newMods) == 0) {
|
||||
/* Revert to the old behavior */
|
||||
HandleNonDeviceModifier(device_independent_mask, oldMods, newMods, left_scancode);
|
||||
return;
|
||||
}
|
||||
|
||||
/* XOR the previous state against the new state to see if there's a change */
|
||||
diff_mod = (device_dependent_mask & oldMods) ^
|
||||
(device_dependent_mask & newMods);
|
||||
if (diff_mod) {
|
||||
/* A change in state was found. Isolate the left and right bits
|
||||
* to handle them separately just in case the values can simulataneously
|
||||
* change or if the bits don't both exist.
|
||||
*/
|
||||
if (left_device_dependent_mask & diff_mod) {
|
||||
HandleModifierOneSide(oldMods, newMods, left_scancode, left_device_dependent_mask);
|
||||
}
|
||||
if (right_device_dependent_mask & diff_mod) {
|
||||
HandleModifierOneSide(oldMods, newMods, right_scancode, right_device_dependent_mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This is a helper function for DoSidedModifiers.
|
||||
* This function will release a key press in the case that
|
||||
* it is clear that the modifier has been released (i.e. one side
|
||||
* can't still be down).
|
||||
*/
|
||||
static void
|
||||
ReleaseModifierSide(unsigned int device_independent_mask,
|
||||
unsigned int oldMods, unsigned int newMods,
|
||||
SDL_Scancode left_scancode,
|
||||
SDL_Scancode right_scancode,
|
||||
unsigned int left_device_dependent_mask,
|
||||
unsigned int right_device_dependent_mask)
|
||||
{
|
||||
unsigned int device_dependent_mask = (left_device_dependent_mask |
|
||||
right_device_dependent_mask);
|
||||
|
||||
/* On the basis that the device independent mask is set, but there are
|
||||
* no device dependent flags set, we'll assume that we can't detect this
|
||||
* keyboard and revert to the unsided behavior.
|
||||
*/
|
||||
if ((device_dependent_mask & oldMods) == 0) {
|
||||
/* In this case, we can't detect the keyboard, so use the left side
|
||||
* to represent both, and release it.
|
||||
*/
|
||||
SDL_SendKeyboardKey(SDL_RELEASED, left_scancode);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* This could have been done in an if-else case because at this point,
|
||||
* we know that all keys have been released when calling this function.
|
||||
* But I'm being paranoid so I want to handle each separately,
|
||||
* so I hope this doesn't cause other problems.
|
||||
*/
|
||||
if ( left_device_dependent_mask & oldMods ) {
|
||||
SDL_SendKeyboardKey(SDL_RELEASED, left_scancode);
|
||||
}
|
||||
if ( right_device_dependent_mask & oldMods ) {
|
||||
SDL_SendKeyboardKey(SDL_RELEASED, right_scancode);
|
||||
}
|
||||
}
|
||||
|
||||
/* This function will handle the modifier keys and also determine the
|
||||
* correct side of the key.
|
||||
*/
|
||||
static void
|
||||
DoSidedModifiers(unsigned short scancode,
|
||||
unsigned int oldMods, unsigned int newMods)
|
||||
{
|
||||
/* Set up arrays for the key syms for the left and right side. */
|
||||
const SDL_Scancode left_mapping[] = {
|
||||
SDL_SCANCODE_LSHIFT,
|
||||
SDL_SCANCODE_LCTRL,
|
||||
SDL_SCANCODE_LALT,
|
||||
SDL_SCANCODE_LGUI
|
||||
};
|
||||
const SDL_Scancode right_mapping[] = {
|
||||
SDL_SCANCODE_RSHIFT,
|
||||
SDL_SCANCODE_RCTRL,
|
||||
SDL_SCANCODE_RALT,
|
||||
SDL_SCANCODE_RGUI
|
||||
};
|
||||
/* Set up arrays for the device dependent masks with indices that
|
||||
* correspond to the _mapping arrays
|
||||
*/
|
||||
const unsigned int left_device_mapping[] = { NX_DEVICELSHIFTKEYMASK, NX_DEVICELCTLKEYMASK, NX_DEVICELALTKEYMASK, NX_DEVICELCMDKEYMASK };
|
||||
const unsigned int right_device_mapping[] = { NX_DEVICERSHIFTKEYMASK, NX_DEVICERCTLKEYMASK, NX_DEVICERALTKEYMASK, NX_DEVICERCMDKEYMASK };
|
||||
|
||||
unsigned int i, bit;
|
||||
|
||||
/* Iterate through the bits, testing each against the old modifiers */
|
||||
for (i = 0, bit = NSEventModifierFlagShift; bit <= NSEventModifierFlagCommand; bit <<= 1, ++i) {
|
||||
unsigned int oldMask, newMask;
|
||||
|
||||
oldMask = oldMods & bit;
|
||||
newMask = newMods & bit;
|
||||
|
||||
/* If the bit is set, we must always examine it because the left
|
||||
* and right side keys may alternate or both may be pressed.
|
||||
*/
|
||||
if (newMask) {
|
||||
HandleModifierSide(bit, oldMods, newMods,
|
||||
left_mapping[i], right_mapping[i],
|
||||
left_device_mapping[i], right_device_mapping[i]);
|
||||
}
|
||||
/* If the state changed from pressed to unpressed, we must examine
|
||||
* the device dependent bits to release the correct keys.
|
||||
*/
|
||||
else if (oldMask && oldMask != newMask) {
|
||||
ReleaseModifierSide(bit, oldMods, newMods,
|
||||
left_mapping[i], right_mapping[i],
|
||||
left_device_mapping[i], right_device_mapping[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
HandleModifiers(_THIS, unsigned short scancode, unsigned int modifierFlags)
|
||||
{
|
||||
SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata;
|
||||
SDL_Scancode code = darwin_scancode_table[scancode];
|
||||
|
||||
if (modifierFlags == data.modifierFlags) {
|
||||
return;
|
||||
const SDL_Scancode codes[] = {
|
||||
SDL_SCANCODE_LSHIFT,
|
||||
SDL_SCANCODE_LCTRL,
|
||||
SDL_SCANCODE_LALT,
|
||||
SDL_SCANCODE_LGUI,
|
||||
SDL_SCANCODE_RSHIFT,
|
||||
SDL_SCANCODE_RCTRL,
|
||||
SDL_SCANCODE_RALT,
|
||||
SDL_SCANCODE_RGUI,
|
||||
SDL_SCANCODE_LSHIFT,
|
||||
SDL_SCANCODE_LCTRL,
|
||||
SDL_SCANCODE_LALT,
|
||||
SDL_SCANCODE_LGUI, };
|
||||
|
||||
const unsigned int modifiers[] = {
|
||||
NX_DEVICELSHIFTKEYMASK,
|
||||
NX_DEVICELCTLKEYMASK,
|
||||
NX_DEVICELALTKEYMASK,
|
||||
NX_DEVICELCMDKEYMASK,
|
||||
NX_DEVICERSHIFTKEYMASK,
|
||||
NX_DEVICERCTLKEYMASK,
|
||||
NX_DEVICERALTKEYMASK,
|
||||
NX_DEVICERCMDKEYMASK,
|
||||
NX_SHIFTMASK,
|
||||
NX_CONTROLMASK,
|
||||
NX_ALTERNATEMASK,
|
||||
NX_COMMANDMASK };
|
||||
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
if (code == codes[i])
|
||||
{
|
||||
if (modifierFlags & modifiers[i])
|
||||
SDL_SendKeyboardKey(SDL_PRESSED, code);
|
||||
else
|
||||
SDL_SendKeyboardKey(SDL_RELEASED, code);
|
||||
}
|
||||
}
|
||||
|
||||
DoSidedModifiers(scancode, data.modifierFlags, modifierFlags);
|
||||
data.modifierFlags = modifierFlags;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -558,9 +403,9 @@ Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
|
||||
}
|
||||
|
||||
SDL_SendKeyboardKey(SDL_PRESSED, code);
|
||||
#if 1
|
||||
#ifdef DEBUG_SCANCODES
|
||||
if (code == SDL_SCANCODE_UNKNOWN) {
|
||||
fprintf(stderr, "The key you just pressed is not recognized by SDL. To help get this fixed, report this to the SDL forums/mailing list <https://discourse.libsdl.org/> or to Christian Walther <cwalther@gmx.ch>. Mac virtual key code is %d.\n", scancode);
|
||||
SDL_Log("The key you just pressed is not recognized by SDL. To help get this fixed, report this to the SDL forums/mailing list <https://discourse.libsdl.org/> or to Christian Walther <cwalther@gmx.ch>. Mac virtual key code is %d.\n", scancode);
|
||||
}
|
||||
#endif
|
||||
if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
|
||||
@@ -579,8 +424,7 @@ Cocoa_HandleKeyEvent(_THIS, NSEvent *event)
|
||||
SDL_SendKeyboardKey(SDL_RELEASED, code);
|
||||
break;
|
||||
case NSEventTypeFlagsChanged:
|
||||
/* FIXME CW 2007-08-14: check if this whole mess that takes up half of this file is really necessary */
|
||||
HandleModifiers(_this, scancode, (unsigned int)[event modifierFlags]);
|
||||
HandleModifiers(_this, scancode, (unsigned int)[event modifierFlags]);
|
||||
break;
|
||||
default: /* just to avoid compiler warnings */
|
||||
break;
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
/*
|
||||
* @author Mark Callow, www.edgewise-consulting.com.
|
||||
*
|
||||
* Thanks to Alex Szpakowski, @slime73 on GitHub, for his gist showing
|
||||
* how to add a CAMetalLayer backed view.
|
||||
* Thanks to @slime73 on GitHub for their gist showing how to add a CAMetalLayer
|
||||
* backed view.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
/*
|
||||
* @author Mark Callow, www.edgewise-consulting.com.
|
||||
*
|
||||
* Thanks to Alex Szpakowski, @slime73 on GitHub, for his gist showing
|
||||
* how to add a CAMetalLayer backed view.
|
||||
* Thanks to @slime73 on GitHub for their gist showing how to add a CAMetalLayer
|
||||
* backed view.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ extern void Cocoa_HandleMouseWarp(CGFloat x, CGFloat y);
|
||||
extern void Cocoa_QuitMouse(_THIS);
|
||||
|
||||
typedef struct {
|
||||
/* Wether we've seen a cursor warp since the last move event. */
|
||||
/* Whether we've seen a cursor warp since the last move event. */
|
||||
SDL_bool seenWarp;
|
||||
/* What location our last cursor warp was to. */
|
||||
CGFloat lastWarpX;
|
||||
|
||||
@@ -42,16 +42,22 @@ struct SDL_GLDriverData
|
||||
@interface SDLOpenGLContext : NSOpenGLContext {
|
||||
SDL_atomic_t dirty;
|
||||
SDL_Window *window;
|
||||
CVDisplayLinkRef displayLink;
|
||||
@public SDL_mutex *swapIntervalMutex;
|
||||
@public SDL_cond *swapIntervalCond;
|
||||
@public SDL_atomic_t swapIntervalSetting;
|
||||
@public SDL_atomic_t swapIntervalsPassed;
|
||||
}
|
||||
|
||||
- (id)initWithFormat:(NSOpenGLPixelFormat *)format
|
||||
shareContext:(NSOpenGLContext *)share;
|
||||
- (void)scheduleUpdate;
|
||||
- (void)updateIfNeeded;
|
||||
- (void)movedToNewScreen;
|
||||
- (void)setWindow:(SDL_Window *)window;
|
||||
- (SDL_Window*)window;
|
||||
- (void)explicitUpdate;
|
||||
|
||||
- (void)dealloc;
|
||||
@end
|
||||
|
||||
/* OpenGL functions */
|
||||
|
||||
@@ -52,6 +52,23 @@ SDL_OpenGLAsyncDispatchChanged(void *userdata, const char *name, const char *old
|
||||
SDL_opengl_async_dispatch = SDL_GetStringBoolean(hint, SDL_FALSE);
|
||||
}
|
||||
|
||||
static CVReturn
|
||||
DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext)
|
||||
{
|
||||
SDLOpenGLContext *nscontext = (__bridge SDLOpenGLContext *) displayLinkContext;
|
||||
|
||||
/*printf("DISPLAY LINK! %u\n", (unsigned int) SDL_GetTicks()); */
|
||||
const int setting = SDL_AtomicGet(&nscontext->swapIntervalSetting);
|
||||
if (setting != 0) { /* nothing to do if vsync is disabled, don't even lock */
|
||||
SDL_LockMutex(nscontext->swapIntervalMutex);
|
||||
SDL_AtomicAdd(&nscontext->swapIntervalsPassed, 1);
|
||||
SDL_CondSignal(nscontext->swapIntervalCond);
|
||||
SDL_UnlockMutex(nscontext->swapIntervalMutex);
|
||||
}
|
||||
|
||||
return kCVReturnSuccess;
|
||||
}
|
||||
|
||||
@implementation SDLOpenGLContext : NSOpenGLContext
|
||||
|
||||
- (id)initWithFormat:(NSOpenGLPixelFormat *)format
|
||||
@@ -61,12 +78,32 @@ SDL_OpenGLAsyncDispatchChanged(void *userdata, const char *name, const char *old
|
||||
if (self) {
|
||||
SDL_AtomicSet(&self->dirty, 0);
|
||||
self->window = NULL;
|
||||
SDL_AtomicSet(&self->swapIntervalSetting, 0);
|
||||
SDL_AtomicSet(&self->swapIntervalsPassed, 0);
|
||||
self->swapIntervalCond = SDL_CreateCond();
|
||||
self->swapIntervalMutex = SDL_CreateMutex();
|
||||
if (!self->swapIntervalCond || !self->swapIntervalMutex) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
/* !!! FIXME: check return values. */
|
||||
CVDisplayLinkCreateWithActiveCGDisplays(&self->displayLink);
|
||||
CVDisplayLinkSetOutputCallback(self->displayLink, &DisplayLinkCallback, (__bridge void * _Nullable) self);
|
||||
CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(self->displayLink, [self CGLContextObj], [format CGLPixelFormatObj]);
|
||||
CVDisplayLinkStart(displayLink);
|
||||
}
|
||||
|
||||
SDL_AddHintCallback(SDL_HINT_MAC_OPENGL_ASYNC_DISPATCH, SDL_OpenGLAsyncDispatchChanged, NULL);
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)movedToNewScreen
|
||||
{
|
||||
if (self->displayLink) {
|
||||
CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(self->displayLink, [self CGLContextObj], [[self pixelFormat] CGLPixelFormatObj]);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)scheduleUpdate
|
||||
{
|
||||
SDL_AtomicAdd(&self->dirty, 1);
|
||||
@@ -158,6 +195,15 @@ SDL_OpenGLAsyncDispatchChanged(void *userdata, const char *name, const char *old
|
||||
- (void)dealloc
|
||||
{
|
||||
SDL_DelHintCallback(SDL_HINT_MAC_OPENGL_ASYNC_DISPATCH, SDL_OpenGLAsyncDispatchChanged, NULL);
|
||||
if (self->displayLink) {
|
||||
CVDisplayLinkRelease(self->displayLink);
|
||||
}
|
||||
if (self->swapIntervalCond) {
|
||||
SDL_DestroyCond(self->swapIntervalCond);
|
||||
}
|
||||
if (self->swapIntervalMutex) {
|
||||
SDL_DestroyMutex(self->swapIntervalMutex);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -211,6 +257,7 @@ Cocoa_GL_CreateContext(_THIS, SDL_Window * window)
|
||||
int glversion_major;
|
||||
int glversion_minor;
|
||||
NSOpenGLPixelFormatAttribute profile;
|
||||
int interval;
|
||||
|
||||
if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
@@ -318,6 +365,10 @@ Cocoa_GL_CreateContext(_THIS, SDL_Window * window)
|
||||
|
||||
sdlcontext = (SDL_GLContext)CFBridgingRetain(context);
|
||||
|
||||
/* vsync is handled separately by synchronizing with a display link. */
|
||||
interval = 0;
|
||||
[context setValues:&interval forParameter:NSOpenGLCPSwapInterval];
|
||||
|
||||
if ( Cocoa_GL_MakeCurrent(_this, window, (__bridge SDL_GLContext)context) < 0 ) {
|
||||
Cocoa_GL_DeleteContext(_this, (__bridge SDL_GLContext)context);
|
||||
SDL_SetError("Failed making OpenGL context current");
|
||||
@@ -389,21 +440,17 @@ int
|
||||
Cocoa_GL_SetSwapInterval(_THIS, int interval)
|
||||
{ @autoreleasepool
|
||||
{
|
||||
NSOpenGLContext *nscontext;
|
||||
GLint value;
|
||||
SDLOpenGLContext *nscontext = (__bridge SDLOpenGLContext *) SDL_GL_GetCurrentContext();
|
||||
int status;
|
||||
|
||||
if (interval < 0) { /* no extension for this on Mac OS X at the moment. */
|
||||
return SDL_SetError("Late swap tearing currently unsupported");
|
||||
}
|
||||
|
||||
nscontext = (__bridge NSOpenGLContext*)SDL_GL_GetCurrentContext();
|
||||
if (nscontext != nil) {
|
||||
value = interval;
|
||||
[nscontext setValues:&value forParameter:NSOpenGLCPSwapInterval];
|
||||
status = 0;
|
||||
} else {
|
||||
if (nscontext == nil) {
|
||||
status = SDL_SetError("No current OpenGL context");
|
||||
} else {
|
||||
SDL_LockMutex(nscontext->swapIntervalMutex);
|
||||
SDL_AtomicSet(&nscontext->swapIntervalsPassed, 0);
|
||||
SDL_AtomicSet(&nscontext->swapIntervalSetting, interval);
|
||||
SDL_UnlockMutex(nscontext->swapIntervalMutex);
|
||||
status = 0;
|
||||
}
|
||||
|
||||
return status;
|
||||
@@ -413,17 +460,8 @@ int
|
||||
Cocoa_GL_GetSwapInterval(_THIS)
|
||||
{ @autoreleasepool
|
||||
{
|
||||
NSOpenGLContext *nscontext;
|
||||
GLint value;
|
||||
int status = 0;
|
||||
|
||||
nscontext = (__bridge NSOpenGLContext*)SDL_GL_GetCurrentContext();
|
||||
if (nscontext != nil) {
|
||||
[nscontext getValues:&value forParameter:NSOpenGLCPSwapInterval];
|
||||
status = (int)value;
|
||||
}
|
||||
|
||||
return status;
|
||||
SDLOpenGLContext* nscontext = (__bridge SDLOpenGLContext*)SDL_GL_GetCurrentContext();
|
||||
return nscontext ? SDL_AtomicGet(&nscontext->swapIntervalSetting) : 0;
|
||||
}}
|
||||
|
||||
int
|
||||
@@ -432,6 +470,27 @@ Cocoa_GL_SwapWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDLOpenGLContext* nscontext = (__bridge SDLOpenGLContext*)SDL_GL_GetCurrentContext();
|
||||
SDL_VideoData *videodata = (__bridge SDL_VideoData *) _this->driverdata;
|
||||
const int setting = SDL_AtomicGet(&nscontext->swapIntervalSetting);
|
||||
|
||||
if (setting == 0) {
|
||||
/* nothing to do if vsync is disabled, don't even lock */
|
||||
} else if (setting < 0) { /* late swap tearing */
|
||||
SDL_LockMutex(nscontext->swapIntervalMutex);
|
||||
while (SDL_AtomicGet(&nscontext->swapIntervalsPassed) == 0) {
|
||||
SDL_CondWait(nscontext->swapIntervalCond, nscontext->swapIntervalMutex);
|
||||
}
|
||||
SDL_AtomicSet(&nscontext->swapIntervalsPassed, 0);
|
||||
SDL_UnlockMutex(nscontext->swapIntervalMutex);
|
||||
} else {
|
||||
SDL_LockMutex(nscontext->swapIntervalMutex);
|
||||
do { /* always wait here so we know we just hit a swap interval. */
|
||||
SDL_CondWait(nscontext->swapIntervalCond, nscontext->swapIntervalMutex);
|
||||
} while ((SDL_AtomicGet(&nscontext->swapIntervalsPassed) % setting) != 0);
|
||||
SDL_AtomicSet(&nscontext->swapIntervalsPassed, 0);
|
||||
SDL_UnlockMutex(nscontext->swapIntervalMutex);
|
||||
}
|
||||
|
||||
/*{ static Uint64 prev = 0; const Uint64 now = SDL_GetTicks64(); const unsigned int diff = (unsigned int) (now - prev); prev = now; printf("GLSWAPBUFFERS TICKS %u\n", diff); }*/
|
||||
|
||||
/* on 10.14 ("Mojave") and later, this deadlocks if two contexts in two
|
||||
threads try to swap at the same time, so put a mutex around it. */
|
||||
|
||||
@@ -47,11 +47,17 @@ Cocoa_CreateShaper(SDL_Window* window)
|
||||
SDL_ShapeData* data;
|
||||
int resized_properly;
|
||||
SDL_WindowData* windata = (__bridge SDL_WindowData*)window->driverdata;
|
||||
|
||||
result = (SDL_WindowShaper *)SDL_malloc(sizeof(SDL_WindowShaper));
|
||||
if (!result) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
[windata.nswindow setOpaque:NO];
|
||||
|
||||
[windata.nswindow setStyleMask:NSWindowStyleMaskBorderless];
|
||||
|
||||
result = (SDL_WindowShaper *)SDL_malloc(sizeof(SDL_WindowShaper));
|
||||
result->window = window;
|
||||
result->mode.mode = ShapeModeDefault;
|
||||
result->mode.parameters.binarizationCutoff = 1;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "SDL_cocoashape.h"
|
||||
#include "SDL_cocoavulkan.h"
|
||||
#include "SDL_cocoametalview.h"
|
||||
#include "SDL_cocoaopengles.h"
|
||||
|
||||
@implementation SDL_VideoData
|
||||
|
||||
|
||||
@@ -85,6 +85,7 @@ typedef enum
|
||||
-(void) windowDidResignKey:(NSNotification *) aNotification;
|
||||
-(void) windowDidChangeBackingProperties:(NSNotification *) aNotification;
|
||||
-(void) windowDidChangeScreenProfile:(NSNotification *) aNotification;
|
||||
-(void) windowDidChangeScreen:(NSNotification *) aNotification;
|
||||
-(void) windowWillEnterFullScreen:(NSNotification *) aNotification;
|
||||
-(void) windowDidEnterFullScreen:(NSNotification *) aNotification;
|
||||
-(void) windowWillExitFullScreen:(NSNotification *) aNotification;
|
||||
|
||||
@@ -260,18 +260,20 @@ static void ConvertNSRect(NSScreen *screen, BOOL fullscreen, NSRect *r)
|
||||
static void
|
||||
ScheduleContextUpdates(SDL_WindowData *data)
|
||||
{
|
||||
/* We still support OpenGL as long as Apple offers it, deprecated or not, so disable deprecation warnings about it. */
|
||||
#if SDL_VIDEO_OPENGL
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
NSOpenGLContext *currentContext;
|
||||
NSMutableArray *contexts;
|
||||
if (!data || !data.nscontexts) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* We still support OpenGL as long as Apple offers it, deprecated or not, so disable deprecation warnings about it. */
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
currentContext = [NSOpenGLContext currentContext];
|
||||
contexts = data.nscontexts;
|
||||
@synchronized (contexts) {
|
||||
@@ -287,6 +289,8 @@ ScheduleContextUpdates(SDL_WindowData *data)
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif /* SDL_VIDEO_OPENGL */
|
||||
}
|
||||
|
||||
/* !!! FIXME: this should use a hint callback. */
|
||||
@@ -496,6 +500,7 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
|
||||
[center addObserver:self selector:@selector(windowDidResignKey:) name:NSWindowDidResignKeyNotification object:window];
|
||||
[center addObserver:self selector:@selector(windowDidChangeBackingProperties:) name:NSWindowDidChangeBackingPropertiesNotification object:window];
|
||||
[center addObserver:self selector:@selector(windowDidChangeScreenProfile:) name:NSWindowDidChangeScreenProfileNotification object:window];
|
||||
[center addObserver:self selector:@selector(windowDidChangeScreen:) name:NSWindowDidChangeScreenNotification object:window];
|
||||
[center addObserver:self selector:@selector(windowWillEnterFullScreen:) name:NSWindowWillEnterFullScreenNotification object:window];
|
||||
[center addObserver:self selector:@selector(windowDidEnterFullScreen:) name:NSWindowDidEnterFullScreenNotification object:window];
|
||||
[center addObserver:self selector:@selector(windowWillExitFullScreen:) name:NSWindowWillExitFullScreenNotification object:window];
|
||||
@@ -628,6 +633,7 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
|
||||
[center removeObserver:self name:NSWindowDidResignKeyNotification object:window];
|
||||
[center removeObserver:self name:NSWindowDidChangeBackingPropertiesNotification object:window];
|
||||
[center removeObserver:self name:NSWindowDidChangeScreenProfileNotification object:window];
|
||||
[center removeObserver:self name:NSWindowDidChangeScreenNotification object:window];
|
||||
[center removeObserver:self name:NSWindowWillEnterFullScreenNotification object:window];
|
||||
[center removeObserver:self name:NSWindowDidEnterFullScreenNotification object:window];
|
||||
[center removeObserver:self name:NSWindowWillExitFullScreenNotification object:window];
|
||||
@@ -786,6 +792,11 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
|
||||
return;
|
||||
}
|
||||
|
||||
if (focusClickPending) {
|
||||
focusClickPending = 0;
|
||||
[self onMovingOrFocusClickPendingStateCleared];
|
||||
}
|
||||
|
||||
window = _data.window;
|
||||
nswindow = _data.nswindow;
|
||||
rect = [nswindow contentRectForFrameRect:[nswindow frame]];
|
||||
@@ -911,6 +922,16 @@ Cocoa_UpdateClipCursor(SDL_Window * window)
|
||||
SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_ICCPROF_CHANGED, 0, 0);
|
||||
}
|
||||
|
||||
- (void)windowDidChangeScreen:(NSNotification *)aNotification
|
||||
{
|
||||
/*printf("WINDOWDIDCHANGESCREEN\n");*/
|
||||
if (_data && _data.nscontexts) {
|
||||
for (SDLOpenGLContext *context in _data.nscontexts) {
|
||||
[context movedToNewScreen];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)windowWillEnterFullScreen:(NSNotification *)aNotification
|
||||
{
|
||||
SDL_Window *window = _data.window;
|
||||
@@ -1734,6 +1755,8 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window)
|
||||
return SDL_SetError("%s", [[e reason] UTF8String]);
|
||||
}
|
||||
|
||||
[nswindow setColorSpace:[NSColorSpace sRGBColorSpace]];
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200 /* Added in the 10.12.0 SDK. */
|
||||
/* By default, don't allow users to make our window tabbed in 10.12 or later */
|
||||
if ([nswindow respondsToSelector:@selector(setTabbingMode:)]) {
|
||||
@@ -2251,7 +2274,9 @@ Cocoa_GetWindowDisplayIndex(_THIS, SDL_Window * window)
|
||||
|
||||
/* Not recognized via CHECK_WINDOW_MAGIC */
|
||||
if (data == nil) {
|
||||
return SDL_SetError("Window data not set");
|
||||
/* Don't set the error here, it hides other errors and is ignored anyway */
|
||||
/*return SDL_SetError("Window data not set");*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* NSWindow.screen may be nil when the window is off-screen. */
|
||||
@@ -2350,11 +2375,21 @@ Cocoa_DestroyWindow(_THIS, SDL_Window * window)
|
||||
[data.nswindow close];
|
||||
}
|
||||
|
||||
#if SDL_VIDEO_OPENGL
|
||||
|
||||
contexts = [data.nscontexts copy];
|
||||
for (SDLOpenGLContext *context in contexts) {
|
||||
/* Calling setWindow:NULL causes the context to remove itself from the context list. */
|
||||
[context setWindow:NULL];
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_OPENGL */
|
||||
|
||||
if (window->shaper) {
|
||||
CFBridgingRelease(window->shaper->driverdata);
|
||||
SDL_free(window->shaper);
|
||||
window->shaper = NULL;
|
||||
}
|
||||
}
|
||||
window->driverdata = NULL;
|
||||
}}
|
||||
|
||||
@@ -1,412 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_DIRECTFB
|
||||
|
||||
#include "SDL_DirectFB_video.h"
|
||||
#include "SDL_DirectFB_window.h"
|
||||
|
||||
#include "../../events/SDL_windowevents_c.h"
|
||||
|
||||
#define COLOR_EXPAND(col) col.r, col.g, col.b, col.a
|
||||
|
||||
static DFB_Theme theme_std = {
|
||||
4, 4, 8, 8,
|
||||
{255, 200, 200, 200},
|
||||
24,
|
||||
{255, 0, 0, 255},
|
||||
16,
|
||||
{255, 255, 255, 255},
|
||||
"/usr/share/fonts/truetype/freefont/FreeSans.ttf",
|
||||
{255, 255, 0, 0},
|
||||
{255, 255, 255, 0},
|
||||
};
|
||||
|
||||
static DFB_Theme theme_none = {
|
||||
0, 0, 0, 0,
|
||||
{0, 0, 0, 0},
|
||||
0,
|
||||
{0, 0, 0, 0},
|
||||
0,
|
||||
{0, 0, 0, 0},
|
||||
NULL
|
||||
};
|
||||
|
||||
static void
|
||||
DrawTriangle(IDirectFBSurface * s, int down, int x, int y, int w)
|
||||
{
|
||||
int x1, x2, x3;
|
||||
int y1, y2, y3;
|
||||
|
||||
if (down) {
|
||||
x1 = x + w / 2;
|
||||
x2 = x;
|
||||
x3 = x + w;
|
||||
y1 = y + w;
|
||||
y2 = y;
|
||||
y3 = y;
|
||||
} else {
|
||||
x1 = x + w / 2;
|
||||
x2 = x;
|
||||
x3 = x + w;
|
||||
y1 = y;
|
||||
y2 = y + w;
|
||||
y3 = y + w;
|
||||
}
|
||||
s->FillTriangle(s, x1, y1, x2, y2, x3, y3);
|
||||
}
|
||||
|
||||
static void
|
||||
LoadFont(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_DFB_DEVICEDATA(_this);
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
|
||||
if (windata->font != NULL) {
|
||||
SDL_DFB_RELEASE(windata->font);
|
||||
windata->font = NULL;
|
||||
SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, windata->font));
|
||||
}
|
||||
|
||||
if (windata->theme.font != NULL)
|
||||
{
|
||||
DFBFontDescription fdesc;
|
||||
|
||||
SDL_zero(fdesc);
|
||||
fdesc.flags = DFDESC_HEIGHT;
|
||||
fdesc.height = windata->theme.font_size;
|
||||
SDL_DFB_CHECK(devdata->
|
||||
dfb->CreateFont(devdata->dfb, windata->theme.font,
|
||||
&fdesc, &windata->font));
|
||||
SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, windata->font));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
DrawCraption(_THIS, IDirectFBSurface * s, int x, int y, char *text)
|
||||
{
|
||||
DFBSurfaceTextFlags flags;
|
||||
|
||||
flags = DSTF_CENTER | DSTF_TOP;
|
||||
|
||||
s->DrawString(s, text, -1, x, y, flags);
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_WM_RedrawLayout(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
IDirectFBSurface *s = windata->window_surface;
|
||||
DFB_Theme *t = &windata->theme;
|
||||
int i;
|
||||
int d = (t->caption_size - t->font_size) / 2;
|
||||
int x, y, w;
|
||||
|
||||
|
||||
if (!windata->is_managed || (window->flags & SDL_WINDOW_FULLSCREEN))
|
||||
return;
|
||||
|
||||
SDL_DFB_CHECK(s->SetSrcBlendFunction(s, DSBF_ONE));
|
||||
SDL_DFB_CHECK(s->SetDstBlendFunction(s, DSBF_ZERO));
|
||||
SDL_DFB_CHECK(s->SetDrawingFlags(s, DSDRAW_NOFX));
|
||||
SDL_DFB_CHECK(s->SetBlittingFlags(s, DSBLIT_NOFX));
|
||||
|
||||
LoadFont(_this, window);
|
||||
/* s->SetDrawingFlags(s, DSDRAW_BLEND); */
|
||||
s->SetColor(s, COLOR_EXPAND(t->frame_color));
|
||||
/* top */
|
||||
for (i = 0; i < t->top_size; i++)
|
||||
s->DrawLine(s, 0, i, windata->size.w, i);
|
||||
/* bottom */
|
||||
for (i = windata->size.h - t->bottom_size; i < windata->size.h; i++)
|
||||
s->DrawLine(s, 0, i, windata->size.w, i);
|
||||
/* left */
|
||||
for (i = 0; i < t->left_size; i++)
|
||||
s->DrawLine(s, i, 0, i, windata->size.h);
|
||||
/* right */
|
||||
for (i = windata->size.w - t->right_size; i < windata->size.w; i++)
|
||||
s->DrawLine(s, i, 0, i, windata->size.h);
|
||||
/* Caption */
|
||||
s->SetColor(s, COLOR_EXPAND(t->caption_color));
|
||||
s->FillRectangle(s, t->left_size, t->top_size, windata->client.w,
|
||||
t->caption_size);
|
||||
/* Close Button */
|
||||
w = t->caption_size;
|
||||
x = windata->size.w - t->right_size - w + d;
|
||||
y = t->top_size + d;
|
||||
s->SetColor(s, COLOR_EXPAND(t->close_color));
|
||||
DrawTriangle(s, 1, x, y, w - 2 * d);
|
||||
/* Max Button */
|
||||
s->SetColor(s, COLOR_EXPAND(t->max_color));
|
||||
DrawTriangle(s, window->flags & SDL_WINDOW_MAXIMIZED ? 1 : 0, x - w,
|
||||
y, w - 2 * d);
|
||||
|
||||
/* Caption */
|
||||
if (*window->title) {
|
||||
s->SetColor(s, COLOR_EXPAND(t->font_color));
|
||||
DrawCraption(_this, s, (x - w) / 2, t->top_size + d, window->title);
|
||||
}
|
||||
/* Icon */
|
||||
if (windata->icon) {
|
||||
DFBRectangle dr;
|
||||
|
||||
dr.x = t->left_size + d;
|
||||
dr.y = t->top_size + d;
|
||||
dr.w = w - 2 * d;
|
||||
dr.h = w - 2 * d;
|
||||
s->SetBlittingFlags(s, DSBLIT_BLEND_ALPHACHANNEL);
|
||||
|
||||
s->StretchBlit(s, windata->icon, NULL, &dr);
|
||||
}
|
||||
windata->wm_needs_redraw = 0;
|
||||
}
|
||||
|
||||
DFBResult
|
||||
DirectFB_WM_GetClientSize(_THIS, SDL_Window * window, int *cw, int *ch)
|
||||
{
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
IDirectFBWindow *dfbwin = windata->dfbwin;
|
||||
|
||||
SDL_DFB_CHECK(dfbwin->GetSize(dfbwin, cw, ch));
|
||||
dfbwin->GetSize(dfbwin, cw, ch);
|
||||
*cw -= windata->theme.left_size + windata->theme.right_size;
|
||||
*ch -=
|
||||
windata->theme.top_size + windata->theme.caption_size +
|
||||
windata->theme.bottom_size;
|
||||
return DFB_OK;
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_WM_AdjustWindowLayout(SDL_Window * window, int flags, int w, int h)
|
||||
{
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
|
||||
if (!windata->is_managed)
|
||||
windata->theme = theme_none;
|
||||
else if (flags & SDL_WINDOW_BORDERLESS)
|
||||
/* desc.caps |= DWCAPS_NODECORATION;) */
|
||||
windata->theme = theme_none;
|
||||
else if (flags & SDL_WINDOW_FULLSCREEN) {
|
||||
windata->theme = theme_none;
|
||||
} else if (flags & SDL_WINDOW_MAXIMIZED) {
|
||||
windata->theme = theme_std;
|
||||
windata->theme.left_size = 0;
|
||||
windata->theme.right_size = 0;
|
||||
windata->theme.top_size = 0;
|
||||
windata->theme.bottom_size = 0;
|
||||
} else {
|
||||
windata->theme = theme_std;
|
||||
}
|
||||
|
||||
windata->client.x = windata->theme.left_size;
|
||||
windata->client.y = windata->theme.top_size + windata->theme.caption_size;
|
||||
windata->client.w = w;
|
||||
windata->client.h = h;
|
||||
windata->size.w =
|
||||
w + windata->theme.left_size + windata->theme.right_size;
|
||||
windata->size.h =
|
||||
h + windata->theme.top_size +
|
||||
windata->theme.caption_size + windata->theme.bottom_size;
|
||||
}
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
WM_POS_NONE = 0x00,
|
||||
WM_POS_CAPTION = 0x01,
|
||||
WM_POS_CLOSE = 0x02,
|
||||
WM_POS_MAX = 0x04,
|
||||
WM_POS_LEFT = 0x08,
|
||||
WM_POS_RIGHT = 0x10,
|
||||
WM_POS_TOP = 0x20,
|
||||
WM_POS_BOTTOM = 0x40,
|
||||
};
|
||||
|
||||
static int
|
||||
WMIsClient(DFB_WindowData * p, int x, int y)
|
||||
{
|
||||
x -= p->client.x;
|
||||
y -= p->client.y;
|
||||
if (x < 0 || y < 0)
|
||||
return 0;
|
||||
if (x >= p->client.w || y >= p->client.h)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
WMPos(DFB_WindowData * p, int x, int y)
|
||||
{
|
||||
int pos = WM_POS_NONE;
|
||||
|
||||
if (!WMIsClient(p, x, y)) {
|
||||
if (y < p->theme.top_size) {
|
||||
pos |= WM_POS_TOP;
|
||||
} else if (y < p->client.y) {
|
||||
if (x <
|
||||
p->size.w - p->theme.right_size - 2 * p->theme.caption_size) {
|
||||
pos |= WM_POS_CAPTION;
|
||||
} else if (x <
|
||||
p->size.w - p->theme.right_size -
|
||||
p->theme.caption_size) {
|
||||
pos |= WM_POS_MAX;
|
||||
} else {
|
||||
pos |= WM_POS_CLOSE;
|
||||
}
|
||||
} else if (y >= p->size.h - p->theme.bottom_size) {
|
||||
pos |= WM_POS_BOTTOM;
|
||||
}
|
||||
if (x < p->theme.left_size) {
|
||||
pos |= WM_POS_LEFT;
|
||||
} else if (x >= p->size.w - p->theme.right_size) {
|
||||
pos |= WM_POS_RIGHT;
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
int
|
||||
DirectFB_WM_ProcessEvent(_THIS, SDL_Window * window, DFBWindowEvent * evt)
|
||||
{
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
SDL_Window *grabbed_window = SDL_GetGrabbedWindow();
|
||||
IDirectFBWindow *dfbwin = windata->dfbwin;
|
||||
DFBWindowOptions wopts;
|
||||
|
||||
if (!windata->is_managed)
|
||||
return 0;
|
||||
|
||||
SDL_DFB_CHECK(dfbwin->GetOptions(dfbwin, &wopts));
|
||||
|
||||
switch (evt->type) {
|
||||
case DWET_BUTTONDOWN:
|
||||
if (evt->buttons & DIBM_LEFT) {
|
||||
int pos = WMPos(windata, evt->x, evt->y);
|
||||
switch (pos) {
|
||||
case WM_POS_NONE:
|
||||
return 0;
|
||||
case WM_POS_CLOSE:
|
||||
windata->wm_grab = WM_POS_NONE;
|
||||
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_CLOSE, 0,
|
||||
0);
|
||||
return 1;
|
||||
case WM_POS_MAX:
|
||||
windata->wm_grab = WM_POS_NONE;
|
||||
if (window->flags & SDL_WINDOW_MAXIMIZED) {
|
||||
SDL_RestoreWindow(window);
|
||||
} else {
|
||||
SDL_MaximizeWindow(window);
|
||||
}
|
||||
return 1;
|
||||
case WM_POS_CAPTION:
|
||||
if (!(wopts & DWOP_KEEP_STACKING)) {
|
||||
DirectFB_RaiseWindow(_this, window);
|
||||
}
|
||||
if (window->flags & SDL_WINDOW_MAXIMIZED)
|
||||
return 1;
|
||||
SDL_FALLTHROUGH;
|
||||
default:
|
||||
windata->wm_grab = pos;
|
||||
if (grabbed_window != NULL)
|
||||
DirectFB_SetWindowMouseGrab(_this, grabbed_window, SDL_FALSE);
|
||||
DirectFB_SetWindowMouseGrab(_this, window, SDL_TRUE);
|
||||
windata->wm_lastx = evt->cx;
|
||||
windata->wm_lasty = evt->cy;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
case DWET_BUTTONUP:
|
||||
if (!windata->wm_grab)
|
||||
return 0;
|
||||
if (!(evt->buttons & DIBM_LEFT)) {
|
||||
if (windata->wm_grab & (WM_POS_RIGHT | WM_POS_BOTTOM)) {
|
||||
int dx = evt->cx - windata->wm_lastx;
|
||||
int dy = evt->cy - windata->wm_lasty;
|
||||
|
||||
if (!(wopts & DWOP_KEEP_SIZE)) {
|
||||
int cw, ch;
|
||||
if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_BOTTOM)
|
||||
dx = 0;
|
||||
else if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_RIGHT)
|
||||
dy = 0;
|
||||
SDL_DFB_CHECK(dfbwin->GetSize(dfbwin, &cw, &ch));
|
||||
|
||||
/* necessary to trigger an event - ugly */
|
||||
SDL_DFB_CHECK(dfbwin->DisableEvents(dfbwin, DWET_ALL));
|
||||
SDL_DFB_CHECK(dfbwin->Resize(dfbwin, cw + dx + 1, ch + dy));
|
||||
SDL_DFB_CHECK(dfbwin->EnableEvents(dfbwin, DWET_ALL));
|
||||
|
||||
SDL_DFB_CHECK(dfbwin->Resize(dfbwin, cw + dx, ch + dy));
|
||||
}
|
||||
}
|
||||
DirectFB_SetWindowMouseGrab(_this, window, SDL_FALSE);
|
||||
if (grabbed_window != NULL)
|
||||
DirectFB_SetWindowMouseGrab(_this, grabbed_window, SDL_TRUE);
|
||||
windata->wm_grab = WM_POS_NONE;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case DWET_MOTION:
|
||||
if (!windata->wm_grab)
|
||||
return 0;
|
||||
if (evt->buttons & DIBM_LEFT) {
|
||||
int dx = evt->cx - windata->wm_lastx;
|
||||
int dy = evt->cy - windata->wm_lasty;
|
||||
|
||||
if (windata->wm_grab & WM_POS_CAPTION) {
|
||||
if (!(wopts & DWOP_KEEP_POSITION))
|
||||
SDL_DFB_CHECK(dfbwin->Move(dfbwin, dx, dy));
|
||||
}
|
||||
if (windata->wm_grab & (WM_POS_RIGHT | WM_POS_BOTTOM)) {
|
||||
if (!(wopts & DWOP_KEEP_SIZE)) {
|
||||
int cw, ch;
|
||||
|
||||
/* Make sure all events are disabled for this operation ! */
|
||||
SDL_DFB_CHECK(dfbwin->DisableEvents(dfbwin, DWET_ALL));
|
||||
|
||||
if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_BOTTOM)
|
||||
dx = 0;
|
||||
else if ((windata->wm_grab & (WM_POS_BOTTOM | WM_POS_RIGHT)) == WM_POS_RIGHT)
|
||||
dy = 0;
|
||||
|
||||
SDL_DFB_CHECK(dfbwin->GetSize(dfbwin, &cw, &ch));
|
||||
SDL_DFB_CHECK(dfbwin->Resize(dfbwin, cw + dx, ch + dy));
|
||||
|
||||
SDL_DFB_CHECK(dfbwin->EnableEvents(dfbwin, DWET_ALL));
|
||||
}
|
||||
}
|
||||
windata->wm_lastx = evt->cx;
|
||||
windata->wm_lasty = evt->cy;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case DWET_KEYDOWN:
|
||||
break;
|
||||
case DWET_KEYUP:
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_directfb_wm_h_
|
||||
#define SDL_directfb_wm_h_
|
||||
|
||||
#include "SDL_DirectFB_video.h"
|
||||
|
||||
typedef struct _DFB_Theme DFB_Theme;
|
||||
struct _DFB_Theme
|
||||
{
|
||||
int left_size;
|
||||
int right_size;
|
||||
int top_size;
|
||||
int bottom_size;
|
||||
DFBColor frame_color;
|
||||
int caption_size;
|
||||
DFBColor caption_color;
|
||||
int font_size;
|
||||
DFBColor font_color;
|
||||
char *font;
|
||||
DFBColor close_color;
|
||||
DFBColor max_color;
|
||||
};
|
||||
|
||||
extern void DirectFB_WM_AdjustWindowLayout(SDL_Window * window, int flags, int w, int h);
|
||||
extern void DirectFB_WM_RedrawLayout(_THIS, SDL_Window * window);
|
||||
|
||||
extern int DirectFB_WM_ProcessEvent(_THIS, SDL_Window * window,
|
||||
DFBWindowEvent * evt);
|
||||
|
||||
extern DFBResult DirectFB_WM_GetClientSize(_THIS, SDL_Window * window,
|
||||
int *cw, int *ch);
|
||||
|
||||
|
||||
#endif /* SDL_directfb_wm_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_DIRECTFB
|
||||
|
||||
#include "SDL_DirectFB_video.h"
|
||||
#include "SDL_DirectFB_dyn.h"
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC
|
||||
#include "SDL_name.h"
|
||||
#include "SDL_loadso.h"
|
||||
|
||||
#define DFB_SYM(ret, name, args, al, func) ret (*name) args;
|
||||
static struct _SDL_DirectFB_Symbols
|
||||
{
|
||||
DFB_SYMS
|
||||
const unsigned int *directfb_major_version;
|
||||
const unsigned int *directfb_minor_version;
|
||||
const unsigned int *directfb_micro_version;
|
||||
} SDL_DirectFB_Symbols;
|
||||
#undef DFB_SYM
|
||||
|
||||
#define DFB_SYM(ret, name, args, al, func) ret name args { func SDL_DirectFB_Symbols.name al ; }
|
||||
DFB_SYMS
|
||||
#undef DFB_SYM
|
||||
|
||||
static void *handle = NULL;
|
||||
|
||||
int
|
||||
SDL_DirectFB_LoadLibrary(void)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
if (handle == NULL) {
|
||||
handle = SDL_LoadObject(SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC);
|
||||
if (handle != NULL) {
|
||||
retval = 1;
|
||||
#define DFB_SYM(ret, name, args, al, func) if (!(SDL_DirectFB_Symbols.name = SDL_LoadFunction(handle, # name))) retval = 0;
|
||||
DFB_SYMS
|
||||
#undef DFB_SYM
|
||||
if (!
|
||||
(SDL_DirectFB_Symbols.directfb_major_version =
|
||||
SDL_LoadFunction(handle, "directfb_major_version")))
|
||||
retval = 0;
|
||||
if (!
|
||||
(SDL_DirectFB_Symbols.directfb_minor_version =
|
||||
SDL_LoadFunction(handle, "directfb_minor_version")))
|
||||
retval = 0;
|
||||
if (!
|
||||
(SDL_DirectFB_Symbols.directfb_micro_version =
|
||||
SDL_LoadFunction(handle, "directfb_micro_version")))
|
||||
retval = 0;
|
||||
}
|
||||
}
|
||||
if (retval) {
|
||||
const char *stemp = DirectFBCheckVersion(DIRECTFB_MAJOR_VERSION,
|
||||
DIRECTFB_MINOR_VERSION,
|
||||
DIRECTFB_MICRO_VERSION);
|
||||
/* Version Check */
|
||||
if (stemp != NULL) {
|
||||
fprintf(stderr,
|
||||
"DirectFB Lib: Version mismatch. Compiled: %d.%d.%d Library %d.%d.%d\n",
|
||||
DIRECTFB_MAJOR_VERSION, DIRECTFB_MINOR_VERSION,
|
||||
DIRECTFB_MICRO_VERSION,
|
||||
*SDL_DirectFB_Symbols.directfb_major_version,
|
||||
*SDL_DirectFB_Symbols.directfb_minor_version,
|
||||
*SDL_DirectFB_Symbols.directfb_micro_version);
|
||||
retval = 0;
|
||||
}
|
||||
}
|
||||
if (!retval)
|
||||
SDL_DirectFB_UnLoadLibrary();
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_DirectFB_UnLoadLibrary(void)
|
||||
{
|
||||
if (handle != NULL) {
|
||||
SDL_UnloadObject(handle);
|
||||
handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
int
|
||||
SDL_DirectFB_LoadLibrary(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_DirectFB_UnLoadLibrary(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_DirectFB_dyn_h_
|
||||
#define SDL_DirectFB_dyn_h_
|
||||
|
||||
#define DFB_SYMS \
|
||||
DFB_SYM(DFBResult, DirectFBError, (const char *msg, DFBResult result), (msg, result), return) \
|
||||
DFB_SYM(DFBResult, DirectFBErrorFatal, (const char *msg, DFBResult result), (msg, result), return) \
|
||||
DFB_SYM(const char *, DirectFBErrorString, (DFBResult result), (result), return) \
|
||||
DFB_SYM(const char *, DirectFBUsageString, ( void ), (), return) \
|
||||
DFB_SYM(DFBResult, DirectFBInit, (int *argc, char *(*argv[]) ), (argc, argv), return) \
|
||||
DFB_SYM(DFBResult, DirectFBSetOption, (const char *name, const char *value), (name, value), return) \
|
||||
DFB_SYM(DFBResult, DirectFBCreate, (IDirectFB **interface), (interface), return) \
|
||||
DFB_SYM(const char *, DirectFBCheckVersion, (unsigned int required_major, unsigned int required_minor, unsigned int required_micro), \
|
||||
(required_major, required_minor, required_micro), return)
|
||||
|
||||
int SDL_DirectFB_LoadLibrary(void);
|
||||
void SDL_DirectFB_UnLoadLibrary(void);
|
||||
|
||||
#endif /* SDL_DirectFB_dyn_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,742 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_DIRECTFB
|
||||
|
||||
/* Handle the event stream, converting DirectFB input events into SDL events */
|
||||
|
||||
#include "SDL_DirectFB_video.h"
|
||||
#include "SDL_DirectFB_window.h"
|
||||
#include "SDL_DirectFB_modes.h"
|
||||
|
||||
#include "SDL_syswm.h"
|
||||
|
||||
#include "../../events/SDL_mouse_c.h"
|
||||
#include "../../events/SDL_keyboard_c.h"
|
||||
#include "../../events/SDL_windowevents_c.h"
|
||||
#include "../../events/SDL_events_c.h"
|
||||
#include "../../events/scancodes_linux.h"
|
||||
#include "../../events/scancodes_xfree86.h"
|
||||
|
||||
#include "SDL_DirectFB_events.h"
|
||||
|
||||
#if USE_MULTI_API
|
||||
#define SDL_SendMouseMotion_ex(w, id, relative, x, y, p) SDL_SendMouseMotion(w, id, relative, x, y, p)
|
||||
#define SDL_SendMouseButton_ex(w, id, state, button) SDL_SendMouseButton(w, id, state, button)
|
||||
#define SDL_SendKeyboardKey_ex(id, state, scancode) SDL_SendKeyboardKey(id, state, scancode)
|
||||
#define SDL_SendKeyboardText_ex(id, text) SDL_SendKeyboardText(id, text)
|
||||
#else
|
||||
#define SDL_SendMouseMotion_ex(w, id, relative, x, y, p) SDL_SendMouseMotion(w, id, relative, x, y)
|
||||
#define SDL_SendMouseButton_ex(w, id, state, button) SDL_SendMouseButton(w, id, state, button)
|
||||
#define SDL_SendKeyboardKey_ex(id, state, scancode) SDL_SendKeyboardKey(state, scancode)
|
||||
#define SDL_SendKeyboardText_ex(id, text) SDL_SendKeyboardText(text)
|
||||
#endif
|
||||
|
||||
typedef struct _cb_data cb_data;
|
||||
struct _cb_data
|
||||
{
|
||||
DFB_DeviceData *devdata;
|
||||
int sys_ids;
|
||||
int sys_kbd;
|
||||
};
|
||||
|
||||
/* The translation tables from a DirectFB keycode to a SDL keysym */
|
||||
static SDL_Scancode oskeymap[256];
|
||||
|
||||
|
||||
static SDL_Keysym *DirectFB_TranslateKey(_THIS, DFBWindowEvent * evt,
|
||||
SDL_Keysym * keysym, Uint32 *unicode);
|
||||
static SDL_Keysym *DirectFB_TranslateKeyInputEvent(_THIS, DFBInputEvent * evt,
|
||||
SDL_Keysym * keysym, Uint32 *unicode);
|
||||
|
||||
static void DirectFB_InitOSKeymap(_THIS, SDL_Scancode * keypmap, int numkeys);
|
||||
static int DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button);
|
||||
|
||||
static void UnicodeToUtf8( Uint16 w , char *utf8buf)
|
||||
{
|
||||
unsigned char *utf8s = (unsigned char *) utf8buf;
|
||||
|
||||
if ( w < 0x0080 ) {
|
||||
utf8s[0] = ( unsigned char ) w;
|
||||
utf8s[1] = 0;
|
||||
}
|
||||
else if ( w < 0x0800 ) {
|
||||
utf8s[0] = 0xc0 | (( w ) >> 6 );
|
||||
utf8s[1] = 0x80 | (( w ) & 0x3f );
|
||||
utf8s[2] = 0;
|
||||
}
|
||||
else {
|
||||
utf8s[0] = 0xe0 | (( w ) >> 12 );
|
||||
utf8s[1] = 0x80 | (( ( w ) >> 6 ) & 0x3f );
|
||||
utf8s[2] = 0x80 | (( w ) & 0x3f );
|
||||
utf8s[3] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
FocusAllMice(_THIS, SDL_Window *window)
|
||||
{
|
||||
#if USE_MULTI_API
|
||||
SDL_DFB_DEVICEDATA(_this);
|
||||
int index;
|
||||
|
||||
for (index = 0; index < devdata->num_mice; index++)
|
||||
SDL_SetMouseFocus(devdata->mouse_id[index], id);
|
||||
#else
|
||||
SDL_SetMouseFocus(window);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
FocusAllKeyboards(_THIS, SDL_Window *window)
|
||||
{
|
||||
#if USE_MULTI_API
|
||||
SDL_DFB_DEVICEDATA(_this);
|
||||
int index;
|
||||
|
||||
for (index = 0; index < devdata->num_keyboard; index++)
|
||||
SDL_SetKeyboardFocus(index, id);
|
||||
#else
|
||||
SDL_SetKeyboardFocus(window);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
MotionAllMice(_THIS, int x, int y)
|
||||
{
|
||||
#if USE_MULTI_API
|
||||
SDL_DFB_DEVICEDATA(_this);
|
||||
int index;
|
||||
|
||||
for (index = 0; index < devdata->num_mice; index++) {
|
||||
SDL_Mouse *mouse = SDL_GetMouse(index);
|
||||
mouse->x = mouse->last_x = x;
|
||||
mouse->y = mouse->last_y = y;
|
||||
/* SDL_SendMouseMotion(devdata->mouse_id[index], 0, x, y, 0); */
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
KbdIndex(_THIS, int id)
|
||||
{
|
||||
SDL_DFB_DEVICEDATA(_this);
|
||||
int index;
|
||||
|
||||
for (index = 0; index < devdata->num_keyboard; index++) {
|
||||
if (devdata->keyboard[index].id == id)
|
||||
return index;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
ClientXY(DFB_WindowData * p, int *x, int *y)
|
||||
{
|
||||
int cx, cy;
|
||||
|
||||
cx = *x;
|
||||
cy = *y;
|
||||
|
||||
cx -= p->client.x;
|
||||
cy -= p->client.y;
|
||||
|
||||
if (cx < 0 || cy < 0)
|
||||
return 0;
|
||||
if (cx >= p->client.w || cy >= p->client.h)
|
||||
return 0;
|
||||
*x = cx;
|
||||
*y = cy;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
ProcessWindowEvent(_THIS, SDL_Window *sdlwin, DFBWindowEvent * evt)
|
||||
{
|
||||
SDL_DFB_DEVICEDATA(_this);
|
||||
SDL_DFB_WINDOWDATA(sdlwin);
|
||||
SDL_Keysym keysym;
|
||||
Uint32 unicode;
|
||||
char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
|
||||
|
||||
if (evt->clazz == DFEC_WINDOW) {
|
||||
switch (evt->type) {
|
||||
case DWET_BUTTONDOWN:
|
||||
if (ClientXY(windata, &evt->x, &evt->y)) {
|
||||
if (!devdata->use_linux_input) {
|
||||
SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0, evt->x,
|
||||
evt->y, 0);
|
||||
SDL_SendMouseButton_ex(sdlwin, devdata->mouse_id[0],
|
||||
SDL_PRESSED,
|
||||
DirectFB_TranslateButton
|
||||
(evt->button));
|
||||
} else {
|
||||
MotionAllMice(_this, evt->x, evt->y);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DWET_BUTTONUP:
|
||||
if (ClientXY(windata, &evt->x, &evt->y)) {
|
||||
if (!devdata->use_linux_input) {
|
||||
SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0, evt->x,
|
||||
evt->y, 0);
|
||||
SDL_SendMouseButton_ex(sdlwin, devdata->mouse_id[0],
|
||||
SDL_RELEASED,
|
||||
DirectFB_TranslateButton
|
||||
(evt->button));
|
||||
} else {
|
||||
MotionAllMice(_this, evt->x, evt->y);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DWET_MOTION:
|
||||
if (ClientXY(windata, &evt->x, &evt->y)) {
|
||||
if (!devdata->use_linux_input) {
|
||||
if (!(sdlwin->flags & SDL_WINDOW_MOUSE_GRABBED))
|
||||
SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0,
|
||||
evt->x, evt->y, 0);
|
||||
} else {
|
||||
/* relative movements are not exact!
|
||||
* This code should limit the number of events sent.
|
||||
* However it kills MAME axis recognition ... */
|
||||
static int cnt = 0;
|
||||
if (1 && ++cnt > 20) {
|
||||
MotionAllMice(_this, evt->x, evt->y);
|
||||
cnt = 0;
|
||||
}
|
||||
}
|
||||
if (!(sdlwin->flags & SDL_WINDOW_MOUSE_FOCUS))
|
||||
SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_ENTER, 0,
|
||||
0);
|
||||
}
|
||||
break;
|
||||
case DWET_KEYDOWN:
|
||||
if (!devdata->use_linux_input) {
|
||||
DirectFB_TranslateKey(_this, evt, &keysym, &unicode);
|
||||
/* printf("Scancode %d %d %d\n", keysym.scancode, evt->key_code, evt->key_id); */
|
||||
SDL_SendKeyboardKey_ex(0, SDL_PRESSED, keysym.scancode);
|
||||
if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
|
||||
SDL_zeroa(text);
|
||||
UnicodeToUtf8(unicode, text);
|
||||
if (*text) {
|
||||
SDL_SendKeyboardText_ex(0, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DWET_KEYUP:
|
||||
if (!devdata->use_linux_input) {
|
||||
DirectFB_TranslateKey(_this, evt, &keysym, &unicode);
|
||||
SDL_SendKeyboardKey_ex(0, SDL_RELEASED, keysym.scancode);
|
||||
}
|
||||
break;
|
||||
case DWET_POSITION:
|
||||
if (ClientXY(windata, &evt->x, &evt->y)) {
|
||||
SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_MOVED,
|
||||
evt->x, evt->y);
|
||||
}
|
||||
break;
|
||||
case DWET_POSITION_SIZE:
|
||||
if (ClientXY(windata, &evt->x, &evt->y)) {
|
||||
SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_MOVED,
|
||||
evt->x, evt->y);
|
||||
}
|
||||
SDL_FALLTHROUGH;
|
||||
case DWET_SIZE:
|
||||
/* FIXME: what about < 0 */
|
||||
evt->w -= (windata->theme.right_size + windata->theme.left_size);
|
||||
evt->h -=
|
||||
(windata->theme.top_size + windata->theme.bottom_size +
|
||||
windata->theme.caption_size);
|
||||
SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_RESIZED,
|
||||
evt->w, evt->h);
|
||||
break;
|
||||
case DWET_CLOSE:
|
||||
SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_CLOSE, 0, 0);
|
||||
break;
|
||||
case DWET_GOTFOCUS:
|
||||
DirectFB_SetContext(_this, sdlwin);
|
||||
FocusAllKeyboards(_this, sdlwin);
|
||||
SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_FOCUS_GAINED,
|
||||
0, 0);
|
||||
break;
|
||||
case DWET_LOSTFOCUS:
|
||||
SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
|
||||
FocusAllKeyboards(_this, 0);
|
||||
break;
|
||||
case DWET_ENTER:
|
||||
/* SDL_DirectFB_ReshowCursor(_this, 0); */
|
||||
FocusAllMice(_this, sdlwin);
|
||||
/* FIXME: when do we really enter ? */
|
||||
if (ClientXY(windata, &evt->x, &evt->y))
|
||||
MotionAllMice(_this, evt->x, evt->y);
|
||||
SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_ENTER, 0, 0);
|
||||
break;
|
||||
case DWET_LEAVE:
|
||||
SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_LEAVE, 0, 0);
|
||||
FocusAllMice(_this, 0);
|
||||
/* SDL_DirectFB_ReshowCursor(_this, 1); */
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
} else
|
||||
printf("Event Clazz %d\n", evt->clazz);
|
||||
}
|
||||
|
||||
static void
|
||||
ProcessInputEvent(_THIS, DFBInputEvent * ievt)
|
||||
{
|
||||
SDL_DFB_DEVICEDATA(_this);
|
||||
SDL_Keysym keysym;
|
||||
int kbd_idx;
|
||||
Uint32 unicode;
|
||||
char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
|
||||
SDL_Window* grabbed_window = SDL_GetGrabbedWindow();
|
||||
|
||||
if (!devdata->use_linux_input) {
|
||||
if (ievt->type == DIET_AXISMOTION) {
|
||||
if ((grabbed_window != NULL) && (ievt->flags & DIEF_AXISREL)) {
|
||||
if (ievt->axis == DIAI_X)
|
||||
SDL_SendMouseMotion_ex(grabbed_window, ievt->device_id, 1,
|
||||
ievt->axisrel, 0, 0);
|
||||
else if (ievt->axis == DIAI_Y)
|
||||
SDL_SendMouseMotion_ex(grabbed_window, ievt->device_id, 1, 0,
|
||||
ievt->axisrel, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
static int last_x, last_y;
|
||||
|
||||
switch (ievt->type) {
|
||||
case DIET_AXISMOTION:
|
||||
if (ievt->flags & DIEF_AXISABS) {
|
||||
if (ievt->axis == DIAI_X)
|
||||
last_x = ievt->axisabs;
|
||||
else if (ievt->axis == DIAI_Y)
|
||||
last_y = ievt->axisabs;
|
||||
if (!(ievt->flags & DIEF_FOLLOW)) {
|
||||
#if USE_MULTI_API
|
||||
SDL_Mouse *mouse = SDL_GetMouse(ievt->device_id);
|
||||
SDL_Window *window = SDL_GetWindowFromID(mouse->focus);
|
||||
#else
|
||||
SDL_Window *window = grabbed_window;
|
||||
#endif
|
||||
if (window) {
|
||||
DFB_WindowData *windata =
|
||||
(DFB_WindowData *) window->driverdata;
|
||||
int x, y;
|
||||
|
||||
windata->dfbwin->GetPosition(windata->dfbwin, &x, &y);
|
||||
SDL_SendMouseMotion_ex(window, ievt->device_id, 0,
|
||||
last_x - (x +
|
||||
windata->client.x),
|
||||
last_y - (y +
|
||||
windata->client.y), 0);
|
||||
} else {
|
||||
SDL_SendMouseMotion_ex(window, ievt->device_id, 0, last_x,
|
||||
last_y, 0);
|
||||
}
|
||||
}
|
||||
} else if (ievt->flags & DIEF_AXISREL) {
|
||||
if (ievt->axis == DIAI_X)
|
||||
SDL_SendMouseMotion_ex(grabbed_window, ievt->device_id, 1,
|
||||
ievt->axisrel, 0, 0);
|
||||
else if (ievt->axis == DIAI_Y)
|
||||
SDL_SendMouseMotion_ex(grabbed_window, ievt->device_id, 1, 0,
|
||||
ievt->axisrel, 0);
|
||||
}
|
||||
break;
|
||||
case DIET_KEYPRESS:
|
||||
kbd_idx = KbdIndex(_this, ievt->device_id);
|
||||
DirectFB_TranslateKeyInputEvent(_this, ievt, &keysym, &unicode);
|
||||
/* printf("Scancode %d %d %d\n", keysym.scancode, evt->key_code, evt->key_id); */
|
||||
SDL_SendKeyboardKey_ex(kbd_idx, SDL_PRESSED, keysym.scancode);
|
||||
if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) {
|
||||
SDL_zeroa(text);
|
||||
UnicodeToUtf8(unicode, text);
|
||||
if (*text) {
|
||||
SDL_SendKeyboardText_ex(kbd_idx, text);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DIET_KEYRELEASE:
|
||||
kbd_idx = KbdIndex(_this, ievt->device_id);
|
||||
DirectFB_TranslateKeyInputEvent(_this, ievt, &keysym, &unicode);
|
||||
SDL_SendKeyboardKey_ex(kbd_idx, SDL_RELEASED, keysym.scancode);
|
||||
break;
|
||||
case DIET_BUTTONPRESS:
|
||||
if (ievt->buttons & DIBM_LEFT)
|
||||
SDL_SendMouseButton_ex(grabbed_window, ievt->device_id, SDL_PRESSED, 1);
|
||||
if (ievt->buttons & DIBM_MIDDLE)
|
||||
SDL_SendMouseButton_ex(grabbed_window, ievt->device_id, SDL_PRESSED, 2);
|
||||
if (ievt->buttons & DIBM_RIGHT)
|
||||
SDL_SendMouseButton_ex(grabbed_window, ievt->device_id, SDL_PRESSED, 3);
|
||||
break;
|
||||
case DIET_BUTTONRELEASE:
|
||||
if (!(ievt->buttons & DIBM_LEFT))
|
||||
SDL_SendMouseButton_ex(grabbed_window, ievt->device_id, SDL_RELEASED, 1);
|
||||
if (!(ievt->buttons & DIBM_MIDDLE))
|
||||
SDL_SendMouseButton_ex(grabbed_window, ievt->device_id, SDL_RELEASED, 2);
|
||||
if (!(ievt->buttons & DIBM_RIGHT))
|
||||
SDL_SendMouseButton_ex(grabbed_window, ievt->device_id, SDL_RELEASED, 3);
|
||||
break;
|
||||
default:
|
||||
break; /* please gcc */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_PumpEventsWindow(_THIS)
|
||||
{
|
||||
SDL_DFB_DEVICEDATA(_this);
|
||||
DFBInputEvent ievt;
|
||||
SDL_Window *w;
|
||||
|
||||
for (w = devdata->firstwin; w != NULL; w = w->next) {
|
||||
SDL_DFB_WINDOWDATA(w);
|
||||
DFBWindowEvent evt;
|
||||
|
||||
while (windata->eventbuffer->GetEvent(windata->eventbuffer,
|
||||
DFB_EVENT(&evt)) == DFB_OK) {
|
||||
if (!DirectFB_WM_ProcessEvent(_this, w, &evt)) {
|
||||
/* Send a SDL_SYSWMEVENT if the application wants them */
|
||||
if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
|
||||
SDL_SysWMmsg wmmsg;
|
||||
SDL_VERSION(&wmmsg.version);
|
||||
wmmsg.subsystem = SDL_SYSWM_DIRECTFB;
|
||||
wmmsg.msg.dfb.event.window = evt;
|
||||
SDL_SendSysWMEvent(&wmmsg);
|
||||
}
|
||||
ProcessWindowEvent(_this, w, &evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Now get relative events in case we need them */
|
||||
while (devdata->events->GetEvent(devdata->events,
|
||||
DFB_EVENT(&ievt)) == DFB_OK) {
|
||||
|
||||
if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
|
||||
SDL_SysWMmsg wmmsg;
|
||||
SDL_VERSION(&wmmsg.version);
|
||||
wmmsg.subsystem = SDL_SYSWM_DIRECTFB;
|
||||
wmmsg.msg.dfb.event.input = ievt;
|
||||
SDL_SendSysWMEvent(&wmmsg);
|
||||
}
|
||||
ProcessInputEvent(_this, &ievt);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_InitOSKeymap(_THIS, SDL_Scancode * keymap, int numkeys)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Initialize the DirectFB key translation table */
|
||||
for (i = 0; i < numkeys; ++i)
|
||||
keymap[i] = SDL_SCANCODE_UNKNOWN;
|
||||
|
||||
keymap[DIKI_A - DIKI_UNKNOWN] = SDL_SCANCODE_A;
|
||||
keymap[DIKI_B - DIKI_UNKNOWN] = SDL_SCANCODE_B;
|
||||
keymap[DIKI_C - DIKI_UNKNOWN] = SDL_SCANCODE_C;
|
||||
keymap[DIKI_D - DIKI_UNKNOWN] = SDL_SCANCODE_D;
|
||||
keymap[DIKI_E - DIKI_UNKNOWN] = SDL_SCANCODE_E;
|
||||
keymap[DIKI_F - DIKI_UNKNOWN] = SDL_SCANCODE_F;
|
||||
keymap[DIKI_G - DIKI_UNKNOWN] = SDL_SCANCODE_G;
|
||||
keymap[DIKI_H - DIKI_UNKNOWN] = SDL_SCANCODE_H;
|
||||
keymap[DIKI_I - DIKI_UNKNOWN] = SDL_SCANCODE_I;
|
||||
keymap[DIKI_J - DIKI_UNKNOWN] = SDL_SCANCODE_J;
|
||||
keymap[DIKI_K - DIKI_UNKNOWN] = SDL_SCANCODE_K;
|
||||
keymap[DIKI_L - DIKI_UNKNOWN] = SDL_SCANCODE_L;
|
||||
keymap[DIKI_M - DIKI_UNKNOWN] = SDL_SCANCODE_M;
|
||||
keymap[DIKI_N - DIKI_UNKNOWN] = SDL_SCANCODE_N;
|
||||
keymap[DIKI_O - DIKI_UNKNOWN] = SDL_SCANCODE_O;
|
||||
keymap[DIKI_P - DIKI_UNKNOWN] = SDL_SCANCODE_P;
|
||||
keymap[DIKI_Q - DIKI_UNKNOWN] = SDL_SCANCODE_Q;
|
||||
keymap[DIKI_R - DIKI_UNKNOWN] = SDL_SCANCODE_R;
|
||||
keymap[DIKI_S - DIKI_UNKNOWN] = SDL_SCANCODE_S;
|
||||
keymap[DIKI_T - DIKI_UNKNOWN] = SDL_SCANCODE_T;
|
||||
keymap[DIKI_U - DIKI_UNKNOWN] = SDL_SCANCODE_U;
|
||||
keymap[DIKI_V - DIKI_UNKNOWN] = SDL_SCANCODE_V;
|
||||
keymap[DIKI_W - DIKI_UNKNOWN] = SDL_SCANCODE_W;
|
||||
keymap[DIKI_X - DIKI_UNKNOWN] = SDL_SCANCODE_X;
|
||||
keymap[DIKI_Y - DIKI_UNKNOWN] = SDL_SCANCODE_Y;
|
||||
keymap[DIKI_Z - DIKI_UNKNOWN] = SDL_SCANCODE_Z;
|
||||
|
||||
keymap[DIKI_0 - DIKI_UNKNOWN] = SDL_SCANCODE_0;
|
||||
keymap[DIKI_1 - DIKI_UNKNOWN] = SDL_SCANCODE_1;
|
||||
keymap[DIKI_2 - DIKI_UNKNOWN] = SDL_SCANCODE_2;
|
||||
keymap[DIKI_3 - DIKI_UNKNOWN] = SDL_SCANCODE_3;
|
||||
keymap[DIKI_4 - DIKI_UNKNOWN] = SDL_SCANCODE_4;
|
||||
keymap[DIKI_5 - DIKI_UNKNOWN] = SDL_SCANCODE_5;
|
||||
keymap[DIKI_6 - DIKI_UNKNOWN] = SDL_SCANCODE_6;
|
||||
keymap[DIKI_7 - DIKI_UNKNOWN] = SDL_SCANCODE_7;
|
||||
keymap[DIKI_8 - DIKI_UNKNOWN] = SDL_SCANCODE_8;
|
||||
keymap[DIKI_9 - DIKI_UNKNOWN] = SDL_SCANCODE_9;
|
||||
|
||||
keymap[DIKI_F1 - DIKI_UNKNOWN] = SDL_SCANCODE_F1;
|
||||
keymap[DIKI_F2 - DIKI_UNKNOWN] = SDL_SCANCODE_F2;
|
||||
keymap[DIKI_F3 - DIKI_UNKNOWN] = SDL_SCANCODE_F3;
|
||||
keymap[DIKI_F4 - DIKI_UNKNOWN] = SDL_SCANCODE_F4;
|
||||
keymap[DIKI_F5 - DIKI_UNKNOWN] = SDL_SCANCODE_F5;
|
||||
keymap[DIKI_F6 - DIKI_UNKNOWN] = SDL_SCANCODE_F6;
|
||||
keymap[DIKI_F7 - DIKI_UNKNOWN] = SDL_SCANCODE_F7;
|
||||
keymap[DIKI_F8 - DIKI_UNKNOWN] = SDL_SCANCODE_F8;
|
||||
keymap[DIKI_F9 - DIKI_UNKNOWN] = SDL_SCANCODE_F9;
|
||||
keymap[DIKI_F10 - DIKI_UNKNOWN] = SDL_SCANCODE_F10;
|
||||
keymap[DIKI_F11 - DIKI_UNKNOWN] = SDL_SCANCODE_F11;
|
||||
keymap[DIKI_F12 - DIKI_UNKNOWN] = SDL_SCANCODE_F12;
|
||||
|
||||
keymap[DIKI_ESCAPE - DIKI_UNKNOWN] = SDL_SCANCODE_ESCAPE;
|
||||
keymap[DIKI_LEFT - DIKI_UNKNOWN] = SDL_SCANCODE_LEFT;
|
||||
keymap[DIKI_RIGHT - DIKI_UNKNOWN] = SDL_SCANCODE_RIGHT;
|
||||
keymap[DIKI_UP - DIKI_UNKNOWN] = SDL_SCANCODE_UP;
|
||||
keymap[DIKI_DOWN - DIKI_UNKNOWN] = SDL_SCANCODE_DOWN;
|
||||
keymap[DIKI_CONTROL_L - DIKI_UNKNOWN] = SDL_SCANCODE_LCTRL;
|
||||
keymap[DIKI_CONTROL_R - DIKI_UNKNOWN] = SDL_SCANCODE_RCTRL;
|
||||
keymap[DIKI_SHIFT_L - DIKI_UNKNOWN] = SDL_SCANCODE_LSHIFT;
|
||||
keymap[DIKI_SHIFT_R - DIKI_UNKNOWN] = SDL_SCANCODE_RSHIFT;
|
||||
keymap[DIKI_ALT_L - DIKI_UNKNOWN] = SDL_SCANCODE_LALT;
|
||||
keymap[DIKI_ALT_R - DIKI_UNKNOWN] = SDL_SCANCODE_RALT;
|
||||
keymap[DIKI_META_L - DIKI_UNKNOWN] = SDL_SCANCODE_LGUI;
|
||||
keymap[DIKI_META_R - DIKI_UNKNOWN] = SDL_SCANCODE_RGUI;
|
||||
keymap[DIKI_SUPER_L - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
|
||||
keymap[DIKI_SUPER_R - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
|
||||
/* FIXME:Do we read hyper keys ?
|
||||
* keymap[DIKI_HYPER_L - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
|
||||
* keymap[DIKI_HYPER_R - DIKI_UNKNOWN] = SDL_SCANCODE_APPLICATION;
|
||||
*/
|
||||
keymap[DIKI_TAB - DIKI_UNKNOWN] = SDL_SCANCODE_TAB;
|
||||
keymap[DIKI_ENTER - DIKI_UNKNOWN] = SDL_SCANCODE_RETURN;
|
||||
keymap[DIKI_SPACE - DIKI_UNKNOWN] = SDL_SCANCODE_SPACE;
|
||||
keymap[DIKI_BACKSPACE - DIKI_UNKNOWN] = SDL_SCANCODE_BACKSPACE;
|
||||
keymap[DIKI_INSERT - DIKI_UNKNOWN] = SDL_SCANCODE_INSERT;
|
||||
keymap[DIKI_DELETE - DIKI_UNKNOWN] = SDL_SCANCODE_DELETE;
|
||||
keymap[DIKI_HOME - DIKI_UNKNOWN] = SDL_SCANCODE_HOME;
|
||||
keymap[DIKI_END - DIKI_UNKNOWN] = SDL_SCANCODE_END;
|
||||
keymap[DIKI_PAGE_UP - DIKI_UNKNOWN] = SDL_SCANCODE_PAGEUP;
|
||||
keymap[DIKI_PAGE_DOWN - DIKI_UNKNOWN] = SDL_SCANCODE_PAGEDOWN;
|
||||
keymap[DIKI_CAPS_LOCK - DIKI_UNKNOWN] = SDL_SCANCODE_CAPSLOCK;
|
||||
keymap[DIKI_NUM_LOCK - DIKI_UNKNOWN] = SDL_SCANCODE_NUMLOCKCLEAR;
|
||||
keymap[DIKI_SCROLL_LOCK - DIKI_UNKNOWN] = SDL_SCANCODE_SCROLLLOCK;
|
||||
keymap[DIKI_PRINT - DIKI_UNKNOWN] = SDL_SCANCODE_PRINTSCREEN;
|
||||
keymap[DIKI_PAUSE - DIKI_UNKNOWN] = SDL_SCANCODE_PAUSE;
|
||||
|
||||
keymap[DIKI_KP_EQUAL - DIKI_UNKNOWN] = SDL_SCANCODE_KP_EQUALS;
|
||||
keymap[DIKI_KP_DECIMAL - DIKI_UNKNOWN] = SDL_SCANCODE_KP_PERIOD;
|
||||
keymap[DIKI_KP_0 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_0;
|
||||
keymap[DIKI_KP_1 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_1;
|
||||
keymap[DIKI_KP_2 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_2;
|
||||
keymap[DIKI_KP_3 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_3;
|
||||
keymap[DIKI_KP_4 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_4;
|
||||
keymap[DIKI_KP_5 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_5;
|
||||
keymap[DIKI_KP_6 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_6;
|
||||
keymap[DIKI_KP_7 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_7;
|
||||
keymap[DIKI_KP_8 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_8;
|
||||
keymap[DIKI_KP_9 - DIKI_UNKNOWN] = SDL_SCANCODE_KP_9;
|
||||
keymap[DIKI_KP_DIV - DIKI_UNKNOWN] = SDL_SCANCODE_KP_DIVIDE;
|
||||
keymap[DIKI_KP_MULT - DIKI_UNKNOWN] = SDL_SCANCODE_KP_MULTIPLY;
|
||||
keymap[DIKI_KP_MINUS - DIKI_UNKNOWN] = SDL_SCANCODE_KP_MINUS;
|
||||
keymap[DIKI_KP_PLUS - DIKI_UNKNOWN] = SDL_SCANCODE_KP_PLUS;
|
||||
keymap[DIKI_KP_ENTER - DIKI_UNKNOWN] = SDL_SCANCODE_KP_ENTER;
|
||||
|
||||
keymap[DIKI_QUOTE_LEFT - DIKI_UNKNOWN] = SDL_SCANCODE_GRAVE; /* TLDE */
|
||||
keymap[DIKI_MINUS_SIGN - DIKI_UNKNOWN] = SDL_SCANCODE_MINUS; /* AE11 */
|
||||
keymap[DIKI_EQUALS_SIGN - DIKI_UNKNOWN] = SDL_SCANCODE_EQUALS; /* AE12 */
|
||||
keymap[DIKI_BRACKET_LEFT - DIKI_UNKNOWN] = SDL_SCANCODE_RIGHTBRACKET; /* AD11 */
|
||||
keymap[DIKI_BRACKET_RIGHT - DIKI_UNKNOWN] = SDL_SCANCODE_LEFTBRACKET; /* AD12 */
|
||||
keymap[DIKI_BACKSLASH - DIKI_UNKNOWN] = SDL_SCANCODE_BACKSLASH; /* BKSL */
|
||||
keymap[DIKI_SEMICOLON - DIKI_UNKNOWN] = SDL_SCANCODE_SEMICOLON; /* AC10 */
|
||||
keymap[DIKI_QUOTE_RIGHT - DIKI_UNKNOWN] = SDL_SCANCODE_APOSTROPHE; /* AC11 */
|
||||
keymap[DIKI_COMMA - DIKI_UNKNOWN] = SDL_SCANCODE_COMMA; /* AB08 */
|
||||
keymap[DIKI_PERIOD - DIKI_UNKNOWN] = SDL_SCANCODE_PERIOD; /* AB09 */
|
||||
keymap[DIKI_SLASH - DIKI_UNKNOWN] = SDL_SCANCODE_SLASH; /* AB10 */
|
||||
keymap[DIKI_LESS_SIGN - DIKI_UNKNOWN] = SDL_SCANCODE_NONUSBACKSLASH; /* 103rd */
|
||||
|
||||
}
|
||||
|
||||
static SDL_Keysym *
|
||||
DirectFB_TranslateKey(_THIS, DFBWindowEvent * evt, SDL_Keysym * keysym, Uint32 *unicode)
|
||||
{
|
||||
SDL_DFB_DEVICEDATA(_this);
|
||||
int kbd_idx = 0; /* Window events lag the device source KbdIndex(_this, evt->device_id); */
|
||||
DFB_KeyboardData *kbd = &devdata->keyboard[kbd_idx];
|
||||
|
||||
keysym->scancode = SDL_SCANCODE_UNKNOWN;
|
||||
|
||||
if (kbd->map && evt->key_code >= kbd->map_adjust &&
|
||||
evt->key_code < kbd->map_size + kbd->map_adjust)
|
||||
keysym->scancode = kbd->map[evt->key_code - kbd->map_adjust];
|
||||
|
||||
if (keysym->scancode == SDL_SCANCODE_UNKNOWN ||
|
||||
devdata->keyboard[kbd_idx].is_generic) {
|
||||
if (evt->key_id - DIKI_UNKNOWN < SDL_arraysize(oskeymap))
|
||||
keysym->scancode = oskeymap[evt->key_id - DIKI_UNKNOWN];
|
||||
else
|
||||
keysym->scancode = SDL_SCANCODE_UNKNOWN;
|
||||
}
|
||||
|
||||
*unicode =
|
||||
(DFB_KEY_TYPE(evt->key_symbol) == DIKT_UNICODE) ? evt->key_symbol : 0;
|
||||
if (*unicode == 0 &&
|
||||
(evt->key_symbol > 0 && evt->key_symbol < 255))
|
||||
*unicode = evt->key_symbol;
|
||||
|
||||
return keysym;
|
||||
}
|
||||
|
||||
static SDL_Keysym *
|
||||
DirectFB_TranslateKeyInputEvent(_THIS, DFBInputEvent * evt,
|
||||
SDL_Keysym * keysym, Uint32 *unicode)
|
||||
{
|
||||
SDL_DFB_DEVICEDATA(_this);
|
||||
int kbd_idx = KbdIndex(_this, evt->device_id);
|
||||
DFB_KeyboardData *kbd = &devdata->keyboard[kbd_idx];
|
||||
|
||||
keysym->scancode = SDL_SCANCODE_UNKNOWN;
|
||||
|
||||
if (kbd->map && evt->key_code >= kbd->map_adjust &&
|
||||
evt->key_code < kbd->map_size + kbd->map_adjust)
|
||||
keysym->scancode = kbd->map[evt->key_code - kbd->map_adjust];
|
||||
|
||||
if (keysym->scancode == SDL_SCANCODE_UNKNOWN || devdata->keyboard[kbd_idx].is_generic) {
|
||||
if (evt->key_id - DIKI_UNKNOWN < SDL_arraysize(oskeymap))
|
||||
keysym->scancode = oskeymap[evt->key_id - DIKI_UNKNOWN];
|
||||
else
|
||||
keysym->scancode = SDL_SCANCODE_UNKNOWN;
|
||||
}
|
||||
|
||||
*unicode =
|
||||
(DFB_KEY_TYPE(evt->key_symbol) == DIKT_UNICODE) ? evt->key_symbol : 0;
|
||||
if (*unicode == 0 &&
|
||||
(evt->key_symbol > 0 && evt->key_symbol < 255))
|
||||
*unicode = evt->key_symbol;
|
||||
|
||||
return keysym;
|
||||
}
|
||||
|
||||
static int
|
||||
DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button)
|
||||
{
|
||||
switch (button) {
|
||||
case DIBI_LEFT:
|
||||
return 1;
|
||||
case DIBI_MIDDLE:
|
||||
return 2;
|
||||
case DIBI_RIGHT:
|
||||
return 3;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static DFBEnumerationResult
|
||||
EnumKeyboards(DFBInputDeviceID device_id,
|
||||
DFBInputDeviceDescription desc, void *callbackdata)
|
||||
{
|
||||
cb_data *cb = callbackdata;
|
||||
DFB_DeviceData *devdata = cb->devdata;
|
||||
#if USE_MULTI_API
|
||||
SDL_Keyboard keyboard;
|
||||
#endif
|
||||
|
||||
if (!cb->sys_kbd) {
|
||||
if (cb->sys_ids) {
|
||||
if (device_id >= 0x10)
|
||||
return DFENUM_OK;
|
||||
} else {
|
||||
if (device_id < 0x10)
|
||||
return DFENUM_OK;
|
||||
}
|
||||
} else {
|
||||
if (device_id != DIDID_KEYBOARD)
|
||||
return DFENUM_OK;
|
||||
}
|
||||
|
||||
if ((desc.caps & DIDTF_KEYBOARD)) {
|
||||
#if USE_MULTI_API
|
||||
SDL_zero(keyboard);
|
||||
SDL_AddKeyboard(&keyboard, devdata->num_keyboard);
|
||||
#endif
|
||||
devdata->keyboard[devdata->num_keyboard].id = device_id;
|
||||
devdata->keyboard[devdata->num_keyboard].is_generic = 0;
|
||||
if (!SDL_strncmp("X11", desc.name, 3))
|
||||
{
|
||||
devdata->keyboard[devdata->num_keyboard].map = xfree86_scancode_table2;
|
||||
devdata->keyboard[devdata->num_keyboard].map_size = SDL_arraysize(xfree86_scancode_table2);
|
||||
devdata->keyboard[devdata->num_keyboard].map_adjust = 8;
|
||||
} else {
|
||||
devdata->keyboard[devdata->num_keyboard].map = linux_scancode_table;
|
||||
devdata->keyboard[devdata->num_keyboard].map_size = SDL_arraysize(linux_scancode_table);
|
||||
devdata->keyboard[devdata->num_keyboard].map_adjust = 0;
|
||||
}
|
||||
|
||||
SDL_DFB_LOG("Keyboard %d - %s\n", device_id, desc.name);
|
||||
|
||||
devdata->num_keyboard++;
|
||||
|
||||
if (cb->sys_kbd)
|
||||
return DFENUM_CANCEL;
|
||||
}
|
||||
return DFENUM_OK;
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_InitKeyboard(_THIS)
|
||||
{
|
||||
SDL_DFB_DEVICEDATA(_this);
|
||||
cb_data cb;
|
||||
|
||||
DirectFB_InitOSKeymap(_this, &oskeymap[0], SDL_arraysize(oskeymap));
|
||||
|
||||
devdata->num_keyboard = 0;
|
||||
cb.devdata = devdata;
|
||||
|
||||
if (devdata->use_linux_input) {
|
||||
cb.sys_kbd = 0;
|
||||
cb.sys_ids = 0;
|
||||
SDL_DFB_CHECK(devdata->dfb->
|
||||
EnumInputDevices(devdata->dfb, EnumKeyboards, &cb));
|
||||
if (devdata->num_keyboard == 0) {
|
||||
cb.sys_ids = 1;
|
||||
SDL_DFB_CHECK(devdata->dfb->EnumInputDevices(devdata->dfb,
|
||||
EnumKeyboards,
|
||||
&cb));
|
||||
}
|
||||
} else {
|
||||
cb.sys_kbd = 1;
|
||||
SDL_DFB_CHECK(devdata->dfb->EnumInputDevices(devdata->dfb,
|
||||
EnumKeyboards,
|
||||
&cb));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_QuitKeyboard(_THIS)
|
||||
{
|
||||
/* SDL_DFB_DEVICEDATA(_this); */
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_DirectFB_events_h_
|
||||
#define SDL_DirectFB_events_h_
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
|
||||
/* Functions to be exported */
|
||||
extern void DirectFB_InitKeyboard(_THIS);
|
||||
extern void DirectFB_QuitKeyboard(_THIS);
|
||||
extern void DirectFB_PumpEventsWindow(_THIS);
|
||||
|
||||
#endif /* SDL_DirectFB_events_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,414 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_DIRECTFB
|
||||
|
||||
#include "SDL_DirectFB_video.h"
|
||||
#include "SDL_DirectFB_modes.h"
|
||||
|
||||
#define DFB_MAX_MODES 200
|
||||
|
||||
struct screen_callback_t
|
||||
{
|
||||
int numscreens;
|
||||
DFBScreenID screenid[DFB_MAX_SCREENS];
|
||||
DFBDisplayLayerID gralayer[DFB_MAX_SCREENS];
|
||||
DFBDisplayLayerID vidlayer[DFB_MAX_SCREENS];
|
||||
int aux; /* auxiliary integer for callbacks */
|
||||
};
|
||||
|
||||
struct modes_callback_t
|
||||
{
|
||||
int nummodes;
|
||||
SDL_DisplayMode *modelist;
|
||||
};
|
||||
|
||||
static DFBEnumerationResult
|
||||
EnumModesCallback(int width, int height, int bpp, void *data)
|
||||
{
|
||||
struct modes_callback_t *modedata = (struct modes_callback_t *) data;
|
||||
SDL_DisplayMode mode;
|
||||
|
||||
mode.w = width;
|
||||
mode.h = height;
|
||||
mode.refresh_rate = 0;
|
||||
mode.driverdata = NULL;
|
||||
mode.format = SDL_PIXELFORMAT_UNKNOWN;
|
||||
|
||||
if (modedata->nummodes < DFB_MAX_MODES) {
|
||||
modedata->modelist[modedata->nummodes++] = mode;
|
||||
}
|
||||
|
||||
return DFENUM_OK;
|
||||
}
|
||||
|
||||
static DFBEnumerationResult
|
||||
EnumScreensCallback(DFBScreenID screen_id, DFBScreenDescription desc,
|
||||
void *callbackdata)
|
||||
{
|
||||
struct screen_callback_t *devdata = (struct screen_callback_t *) callbackdata;
|
||||
|
||||
devdata->screenid[devdata->numscreens++] = screen_id;
|
||||
return DFENUM_OK;
|
||||
}
|
||||
|
||||
static DFBEnumerationResult
|
||||
EnumLayersCallback(DFBDisplayLayerID layer_id, DFBDisplayLayerDescription desc,
|
||||
void *callbackdata)
|
||||
{
|
||||
struct screen_callback_t *devdata = (struct screen_callback_t *) callbackdata;
|
||||
|
||||
if (desc.caps & DLCAPS_SURFACE) {
|
||||
if ((desc.type & DLTF_GRAPHICS) && (desc.type & DLTF_VIDEO)) {
|
||||
if (devdata->vidlayer[devdata->aux] == -1)
|
||||
devdata->vidlayer[devdata->aux] = layer_id;
|
||||
} else if (desc.type & DLTF_GRAPHICS) {
|
||||
if (devdata->gralayer[devdata->aux] == -1)
|
||||
devdata->gralayer[devdata->aux] = layer_id;
|
||||
}
|
||||
}
|
||||
return DFENUM_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
CheckSetDisplayMode(_THIS, SDL_VideoDisplay * display, DFB_DisplayData * data, SDL_DisplayMode * mode)
|
||||
{
|
||||
SDL_DFB_DEVICEDATA(_this);
|
||||
DFBDisplayLayerConfig config;
|
||||
DFBDisplayLayerConfigFlags failed;
|
||||
|
||||
SDL_DFB_CHECKERR(data->layer->SetCooperativeLevel(data->layer,
|
||||
DLSCL_ADMINISTRATIVE));
|
||||
config.width = mode->w;
|
||||
config.height = mode->h;
|
||||
config.pixelformat = DirectFB_SDLToDFBPixelFormat(mode->format);
|
||||
config.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT;
|
||||
if (devdata->use_yuv_underlays) {
|
||||
config.flags |= DLCONF_OPTIONS;
|
||||
config.options = DLOP_ALPHACHANNEL;
|
||||
}
|
||||
failed = 0;
|
||||
data->layer->TestConfiguration(data->layer, &config, &failed);
|
||||
SDL_DFB_CHECKERR(data->layer->SetCooperativeLevel(data->layer,
|
||||
DLSCL_SHARED));
|
||||
if (failed == 0)
|
||||
{
|
||||
SDL_AddDisplayMode(display, mode);
|
||||
SDL_DFB_LOG("Mode %d x %d Added\n", mode->w, mode->h);
|
||||
}
|
||||
else
|
||||
SDL_DFB_ERR("Mode %d x %d not available: %x\n", mode->w,
|
||||
mode->h, failed);
|
||||
|
||||
return;
|
||||
error:
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DirectFB_SetContext(_THIS, SDL_Window *window)
|
||||
{
|
||||
#if (DFB_VERSION_ATLEAST(1,0,0))
|
||||
/* FIXME: does not work on 1.0/1.2 with radeon driver
|
||||
* the approach did work with the matrox driver
|
||||
* This has simply no effect.
|
||||
*/
|
||||
|
||||
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
|
||||
DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
|
||||
|
||||
/* FIXME: should we handle the error */
|
||||
if (dispdata->vidIDinuse)
|
||||
SDL_DFB_CHECK(dispdata->vidlayer->SwitchContext(dispdata->vidlayer,
|
||||
DFB_TRUE));
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_InitModes(_THIS)
|
||||
{
|
||||
SDL_DFB_DEVICEDATA(_this);
|
||||
IDirectFBDisplayLayer *layer = NULL;
|
||||
SDL_VideoDisplay display;
|
||||
DFB_DisplayData *dispdata = NULL;
|
||||
SDL_DisplayMode mode;
|
||||
DFBGraphicsDeviceDescription caps;
|
||||
DFBDisplayLayerConfig dlc;
|
||||
struct screen_callback_t *screencbdata;
|
||||
|
||||
int tcw[DFB_MAX_SCREENS];
|
||||
int tch[DFB_MAX_SCREENS];
|
||||
int i;
|
||||
DFBResult ret;
|
||||
|
||||
SDL_DFB_ALLOC_CLEAR(screencbdata, sizeof(*screencbdata));
|
||||
|
||||
screencbdata->numscreens = 0;
|
||||
|
||||
for (i = 0; i < DFB_MAX_SCREENS; i++) {
|
||||
screencbdata->gralayer[i] = -1;
|
||||
screencbdata->vidlayer[i] = -1;
|
||||
}
|
||||
|
||||
SDL_DFB_CHECKERR(devdata->dfb->EnumScreens(devdata->dfb, &EnumScreensCallback,
|
||||
screencbdata));
|
||||
|
||||
for (i = 0; i < screencbdata->numscreens; i++) {
|
||||
IDirectFBScreen *screen;
|
||||
|
||||
SDL_DFB_CHECKERR(devdata->dfb->GetScreen(devdata->dfb,
|
||||
screencbdata->screenid
|
||||
[i], &screen));
|
||||
|
||||
screencbdata->aux = i;
|
||||
SDL_DFB_CHECKERR(screen->EnumDisplayLayers(screen, &EnumLayersCallback,
|
||||
screencbdata));
|
||||
screen->GetSize(screen, &tcw[i], &tch[i]);
|
||||
|
||||
screen->Release(screen);
|
||||
}
|
||||
|
||||
/* Query card capabilities */
|
||||
|
||||
devdata->dfb->GetDeviceDescription(devdata->dfb, &caps);
|
||||
|
||||
for (i = 0; i < screencbdata->numscreens; i++) {
|
||||
SDL_DFB_CHECKERR(devdata->dfb->GetDisplayLayer(devdata->dfb,
|
||||
screencbdata->gralayer
|
||||
[i], &layer));
|
||||
|
||||
SDL_DFB_CHECKERR(layer->SetCooperativeLevel(layer,
|
||||
DLSCL_ADMINISTRATIVE));
|
||||
layer->EnableCursor(layer, 1);
|
||||
SDL_DFB_CHECKERR(layer->SetCursorOpacity(layer, 0xC0));
|
||||
|
||||
if (devdata->use_yuv_underlays) {
|
||||
dlc.flags = DLCONF_PIXELFORMAT | DLCONF_OPTIONS;
|
||||
dlc.pixelformat = DSPF_ARGB;
|
||||
dlc.options = DLOP_ALPHACHANNEL;
|
||||
|
||||
ret = layer->SetConfiguration(layer, &dlc);
|
||||
if (ret != DFB_OK) {
|
||||
/* try AiRGB if the previous failed */
|
||||
dlc.pixelformat = DSPF_AiRGB;
|
||||
SDL_DFB_CHECKERR(layer->SetConfiguration(layer, &dlc));
|
||||
}
|
||||
}
|
||||
|
||||
/* Query layer configuration to determine the current mode and pixelformat */
|
||||
dlc.flags = DLCONF_ALL;
|
||||
SDL_DFB_CHECKERR(layer->GetConfiguration(layer, &dlc));
|
||||
|
||||
mode.format = DirectFB_DFBToSDLPixelFormat(dlc.pixelformat);
|
||||
|
||||
if (mode.format == SDL_PIXELFORMAT_UNKNOWN) {
|
||||
SDL_DFB_ERR("Unknown dfb pixelformat %x !\n", dlc.pixelformat);
|
||||
goto error;
|
||||
}
|
||||
|
||||
mode.w = dlc.width;
|
||||
mode.h = dlc.height;
|
||||
mode.refresh_rate = 0;
|
||||
mode.driverdata = NULL;
|
||||
|
||||
SDL_DFB_ALLOC_CLEAR(dispdata, sizeof(*dispdata));
|
||||
|
||||
dispdata->layer = layer;
|
||||
dispdata->pixelformat = dlc.pixelformat;
|
||||
dispdata->cw = tcw[i];
|
||||
dispdata->ch = tch[i];
|
||||
|
||||
/* YUV - Video layer */
|
||||
|
||||
dispdata->vidID = screencbdata->vidlayer[i];
|
||||
dispdata->vidIDinuse = 0;
|
||||
|
||||
SDL_zero(display);
|
||||
|
||||
display.desktop_mode = mode;
|
||||
display.current_mode = mode;
|
||||
display.driverdata = dispdata;
|
||||
|
||||
#if (DFB_VERSION_ATLEAST(1,2,0))
|
||||
dlc.flags =
|
||||
DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT |
|
||||
DLCONF_OPTIONS;
|
||||
ret = layer->SetConfiguration(layer, &dlc);
|
||||
#endif
|
||||
|
||||
SDL_DFB_CHECKERR(layer->SetCooperativeLevel(layer, DLSCL_SHARED));
|
||||
|
||||
SDL_AddVideoDisplay(&display, SDL_FALSE);
|
||||
}
|
||||
SDL_DFB_FREE(screencbdata);
|
||||
return;
|
||||
error:
|
||||
/* FIXME: Cleanup not complete, Free existing displays */
|
||||
SDL_DFB_FREE(dispdata);
|
||||
SDL_DFB_RELEASE(layer);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
|
||||
{
|
||||
SDL_DFB_DEVICEDATA(_this);
|
||||
DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
|
||||
SDL_DisplayMode mode;
|
||||
struct modes_callback_t data;
|
||||
int i;
|
||||
|
||||
data.nummodes = 0;
|
||||
/* Enumerate the available fullscreen modes */
|
||||
SDL_DFB_CALLOC(data.modelist, DFB_MAX_MODES, sizeof(SDL_DisplayMode));
|
||||
SDL_DFB_CHECKERR(devdata->dfb->EnumVideoModes(devdata->dfb,
|
||||
EnumModesCallback, &data));
|
||||
|
||||
for (i = 0; i < data.nummodes; ++i) {
|
||||
mode = data.modelist[i];
|
||||
|
||||
mode.format = SDL_PIXELFORMAT_ARGB8888;
|
||||
CheckSetDisplayMode(_this, display, dispdata, &mode);
|
||||
mode.format = SDL_PIXELFORMAT_RGB888;
|
||||
CheckSetDisplayMode(_this, display, dispdata, &mode);
|
||||
mode.format = SDL_PIXELFORMAT_RGB24;
|
||||
CheckSetDisplayMode(_this, display, dispdata, &mode);
|
||||
mode.format = SDL_PIXELFORMAT_RGB565;
|
||||
CheckSetDisplayMode(_this, display, dispdata, &mode);
|
||||
mode.format = SDL_PIXELFORMAT_INDEX8;
|
||||
CheckSetDisplayMode(_this, display, dispdata, &mode);
|
||||
}
|
||||
|
||||
SDL_DFB_FREE(data.modelist);
|
||||
error:
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
DirectFB_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
|
||||
{
|
||||
/*
|
||||
* FIXME: video mode switch is currently broken for 1.2.0
|
||||
*
|
||||
*/
|
||||
|
||||
SDL_DFB_DEVICEDATA(_this);
|
||||
DFB_DisplayData *data = (DFB_DisplayData *) display->driverdata;
|
||||
DFBDisplayLayerConfig config, rconfig;
|
||||
DFBDisplayLayerConfigFlags fail = 0;
|
||||
|
||||
SDL_DFB_CHECKERR(data->layer->SetCooperativeLevel(data->layer,
|
||||
DLSCL_ADMINISTRATIVE));
|
||||
|
||||
SDL_DFB_CHECKERR(data->layer->GetConfiguration(data->layer, &config));
|
||||
config.flags = DLCONF_WIDTH | DLCONF_HEIGHT;
|
||||
if (mode->format != SDL_PIXELFORMAT_UNKNOWN) {
|
||||
config.flags |= DLCONF_PIXELFORMAT;
|
||||
config.pixelformat = DirectFB_SDLToDFBPixelFormat(mode->format);
|
||||
data->pixelformat = config.pixelformat;
|
||||
}
|
||||
config.width = mode->w;
|
||||
config.height = mode->h;
|
||||
|
||||
if (devdata->use_yuv_underlays) {
|
||||
config.flags |= DLCONF_OPTIONS;
|
||||
config.options = DLOP_ALPHACHANNEL;
|
||||
}
|
||||
|
||||
data->layer->TestConfiguration(data->layer, &config, &fail);
|
||||
|
||||
if (fail &
|
||||
(DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT |
|
||||
DLCONF_OPTIONS)) {
|
||||
SDL_DFB_ERR("Error setting mode %dx%d-%x\n", mode->w, mode->h,
|
||||
mode->format);
|
||||
return -1;
|
||||
}
|
||||
|
||||
config.flags &= ~fail;
|
||||
SDL_DFB_CHECKERR(data->layer->SetConfiguration(data->layer, &config));
|
||||
#if (DFB_VERSION_ATLEAST(1,2,0))
|
||||
/* Need to call this twice ! */
|
||||
SDL_DFB_CHECKERR(data->layer->SetConfiguration(data->layer, &config));
|
||||
#endif
|
||||
|
||||
/* Double check */
|
||||
SDL_DFB_CHECKERR(data->layer->GetConfiguration(data->layer, &rconfig));
|
||||
SDL_DFB_CHECKERR(data->
|
||||
layer->SetCooperativeLevel(data->layer, DLSCL_SHARED));
|
||||
|
||||
if ((config.width != rconfig.width) || (config.height != rconfig.height)
|
||||
|| ((mode->format != SDL_PIXELFORMAT_UNKNOWN)
|
||||
&& (config.pixelformat != rconfig.pixelformat))) {
|
||||
SDL_DFB_ERR("Error setting mode %dx%d-%x\n", mode->w, mode->h,
|
||||
mode->format);
|
||||
return -1;
|
||||
}
|
||||
|
||||
data->pixelformat = rconfig.pixelformat;
|
||||
data->cw = config.width;
|
||||
data->ch = config.height;
|
||||
display->current_mode = *mode;
|
||||
|
||||
return 0;
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_QuitModes(_THIS)
|
||||
{
|
||||
SDL_DisplayMode tmode;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < _this->num_displays; ++i) {
|
||||
SDL_VideoDisplay *display = &_this->displays[i];
|
||||
DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
|
||||
|
||||
SDL_GetDesktopDisplayMode(i, &tmode);
|
||||
tmode.format = SDL_PIXELFORMAT_UNKNOWN;
|
||||
DirectFB_SetDisplayMode(_this, display, &tmode);
|
||||
|
||||
SDL_GetDesktopDisplayMode(i, &tmode);
|
||||
DirectFB_SetDisplayMode(_this, display, &tmode);
|
||||
|
||||
if (dispdata->layer) {
|
||||
SDL_DFB_CHECK(dispdata->
|
||||
layer->SetCooperativeLevel(dispdata->layer,
|
||||
DLSCL_ADMINISTRATIVE));
|
||||
SDL_DFB_CHECK(dispdata->
|
||||
layer->SetCursorOpacity(dispdata->layer, 0x00));
|
||||
SDL_DFB_CHECK(dispdata->
|
||||
layer->SetCooperativeLevel(dispdata->layer,
|
||||
DLSCL_SHARED));
|
||||
}
|
||||
|
||||
SDL_DFB_RELEASE(dispdata->layer);
|
||||
SDL_DFB_RELEASE(dispdata->vidlayer);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_directfb_modes_h_
|
||||
#define SDL_directfb_modes_h_
|
||||
|
||||
#include <directfb.h>
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
|
||||
#define SDL_DFB_DISPLAYDATA(win) DFB_DisplayData *dispdata = ((win) ? (DFB_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata : NULL)
|
||||
|
||||
typedef struct _DFB_DisplayData DFB_DisplayData;
|
||||
struct _DFB_DisplayData
|
||||
{
|
||||
IDirectFBDisplayLayer *layer;
|
||||
DFBSurfacePixelFormat pixelformat;
|
||||
/* FIXME: support for multiple video layer.
|
||||
* However, I do not know any card supporting
|
||||
* more than one
|
||||
*/
|
||||
DFBDisplayLayerID vidID;
|
||||
IDirectFBDisplayLayer *vidlayer;
|
||||
|
||||
int vidIDinuse;
|
||||
|
||||
int cw;
|
||||
int ch;
|
||||
};
|
||||
|
||||
|
||||
extern void DirectFB_InitModes(_THIS);
|
||||
extern void DirectFB_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
|
||||
extern int DirectFB_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
|
||||
extern void DirectFB_QuitModes(_THIS);
|
||||
|
||||
extern void DirectFB_SetContext(_THIS, SDL_Window *window);
|
||||
|
||||
#endif /* SDL_directfb_modes_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,388 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_DIRECTFB
|
||||
|
||||
|
||||
#include "SDL_DirectFB_video.h"
|
||||
#include "SDL_DirectFB_mouse.h"
|
||||
#include "SDL_DirectFB_modes.h"
|
||||
#include "SDL_DirectFB_window.h"
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "../../events/SDL_mouse_c.h"
|
||||
|
||||
static SDL_Cursor *DirectFB_CreateDefaultCursor(void);
|
||||
static SDL_Cursor *DirectFB_CreateCursor(SDL_Surface * surface,
|
||||
int hot_x, int hot_y);
|
||||
static int DirectFB_ShowCursor(SDL_Cursor * cursor);
|
||||
static void DirectFB_FreeCursor(SDL_Cursor * cursor);
|
||||
static void DirectFB_WarpMouse(SDL_Window * window, int x, int y);
|
||||
|
||||
static const char *arrow[] = {
|
||||
/* pixels */
|
||||
"X ",
|
||||
"XX ",
|
||||
"X.X ",
|
||||
"X..X ",
|
||||
"X...X ",
|
||||
"X....X ",
|
||||
"X.....X ",
|
||||
"X......X ",
|
||||
"X.......X ",
|
||||
"X........X ",
|
||||
"X.....XXXXX ",
|
||||
"X..X..X ",
|
||||
"X.X X..X ",
|
||||
"XX X..X ",
|
||||
"X X..X ",
|
||||
" X..X ",
|
||||
" X..X ",
|
||||
" X..X ",
|
||||
" XX ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
};
|
||||
|
||||
static SDL_Cursor *
|
||||
DirectFB_CreateDefaultCursor(void)
|
||||
{
|
||||
SDL_VideoDevice *dev = SDL_GetVideoDevice();
|
||||
|
||||
SDL_DFB_DEVICEDATA(dev);
|
||||
DFB_CursorData *curdata;
|
||||
DFBSurfaceDescription dsc;
|
||||
SDL_Cursor *cursor;
|
||||
Uint32 *dest;
|
||||
int pitch, i, j;
|
||||
|
||||
SDL_DFB_ALLOC_CLEAR( cursor, sizeof(*cursor));
|
||||
SDL_DFB_ALLOC_CLEAR(curdata, sizeof(*curdata));
|
||||
|
||||
dsc.flags =
|
||||
DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
|
||||
dsc.caps = DSCAPS_VIDEOONLY;
|
||||
dsc.width = 32;
|
||||
dsc.height = 32;
|
||||
dsc.pixelformat = DSPF_ARGB;
|
||||
|
||||
SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
|
||||
&curdata->surf));
|
||||
curdata->hotx = 0;
|
||||
curdata->hoty = 0;
|
||||
cursor->driverdata = curdata;
|
||||
|
||||
SDL_DFB_CHECKERR(curdata->surf->Lock(curdata->surf, DSLF_WRITE,
|
||||
(void *) &dest, &pitch));
|
||||
|
||||
/* Relies on the fact that this is only called with ARGB surface. */
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
for (j = 0; j < 32; j++)
|
||||
{
|
||||
switch (arrow[i][j])
|
||||
{
|
||||
case ' ': dest[j] = 0x00000000; break;
|
||||
case '.': dest[j] = 0xffffffff; break;
|
||||
case 'X': dest[j] = 0xff000000; break;
|
||||
}
|
||||
}
|
||||
dest += (pitch >> 2);
|
||||
}
|
||||
|
||||
curdata->surf->Unlock(curdata->surf);
|
||||
return cursor;
|
||||
error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create a cursor from a surface */
|
||||
static SDL_Cursor *
|
||||
DirectFB_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
|
||||
{
|
||||
SDL_VideoDevice *dev = SDL_GetVideoDevice();
|
||||
|
||||
SDL_DFB_DEVICEDATA(dev);
|
||||
DFB_CursorData *curdata;
|
||||
DFBSurfaceDescription dsc;
|
||||
SDL_Cursor *cursor;
|
||||
Uint32 *dest;
|
||||
Uint32 *p;
|
||||
int pitch, i;
|
||||
|
||||
SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
|
||||
SDL_assert(surface->pitch == surface->w * 4);
|
||||
|
||||
SDL_DFB_ALLOC_CLEAR( cursor, sizeof(*cursor));
|
||||
SDL_DFB_ALLOC_CLEAR(curdata, sizeof(*curdata));
|
||||
|
||||
dsc.flags =
|
||||
DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
|
||||
dsc.caps = DSCAPS_VIDEOONLY;
|
||||
dsc.width = surface->w;
|
||||
dsc.height = surface->h;
|
||||
dsc.pixelformat = DSPF_ARGB;
|
||||
|
||||
SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
|
||||
&curdata->surf));
|
||||
curdata->hotx = hot_x;
|
||||
curdata->hoty = hot_y;
|
||||
cursor->driverdata = curdata;
|
||||
|
||||
SDL_DFB_CHECKERR(curdata->surf->Lock(curdata->surf, DSLF_WRITE,
|
||||
(void *) &dest, &pitch));
|
||||
|
||||
p = surface->pixels;
|
||||
for (i = 0; i < surface->h; i++)
|
||||
SDL_memcpy((char *) dest + i * pitch,
|
||||
(char *) p + i * surface->pitch, 4 * surface->w);
|
||||
|
||||
curdata->surf->Unlock(curdata->surf);
|
||||
return cursor;
|
||||
error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Show the specified cursor, or hide if cursor is NULL */
|
||||
static int
|
||||
DirectFB_ShowCursor(SDL_Cursor * cursor)
|
||||
{
|
||||
SDL_DFB_CURSORDATA(cursor);
|
||||
SDL_Window *window;
|
||||
|
||||
window = SDL_GetFocusWindow();
|
||||
if (!window)
|
||||
return -1;
|
||||
else {
|
||||
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
|
||||
|
||||
if (display) {
|
||||
DFB_DisplayData *dispdata =
|
||||
(DFB_DisplayData *) display->driverdata;
|
||||
DFB_WindowData *windata = (DFB_WindowData *) window->driverdata;
|
||||
|
||||
if (cursor)
|
||||
SDL_DFB_CHECKERR(windata->dfbwin->
|
||||
SetCursorShape(windata->dfbwin,
|
||||
curdata->surf, curdata->hotx,
|
||||
curdata->hoty));
|
||||
|
||||
SDL_DFB_CHECKERR(dispdata->layer->
|
||||
SetCooperativeLevel(dispdata->layer,
|
||||
DLSCL_ADMINISTRATIVE));
|
||||
SDL_DFB_CHECKERR(dispdata->layer->
|
||||
SetCursorOpacity(dispdata->layer,
|
||||
cursor ? 0xC0 : 0x00));
|
||||
SDL_DFB_CHECKERR(dispdata->layer->
|
||||
SetCooperativeLevel(dispdata->layer,
|
||||
DLSCL_SHARED));
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Free a window manager cursor */
|
||||
static void
|
||||
DirectFB_FreeCursor(SDL_Cursor * cursor)
|
||||
{
|
||||
SDL_DFB_CURSORDATA(cursor);
|
||||
|
||||
SDL_DFB_RELEASE(curdata->surf);
|
||||
SDL_DFB_FREE(cursor->driverdata);
|
||||
SDL_DFB_FREE(cursor);
|
||||
}
|
||||
|
||||
/* Warp the mouse to (x,y) */
|
||||
static void
|
||||
DirectFB_WarpMouse(SDL_Window * window, int x, int y)
|
||||
{
|
||||
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
|
||||
DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
|
||||
DFB_WindowData *windata = (DFB_WindowData *) window->driverdata;
|
||||
int cx, cy;
|
||||
|
||||
SDL_DFB_CHECKERR(windata->dfbwin->GetPosition(windata->dfbwin, &cx, &cy));
|
||||
SDL_DFB_CHECKERR(dispdata->layer->WarpCursor(dispdata->layer,
|
||||
cx + x + windata->client.x,
|
||||
cy + y + windata->client.y));
|
||||
|
||||
error:
|
||||
return;
|
||||
}
|
||||
|
||||
#if USE_MULTI_API
|
||||
|
||||
static void DirectFB_MoveCursor(SDL_Cursor * cursor);
|
||||
static void DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_Window * window,
|
||||
int x, int y);
|
||||
static void DirectFB_FreeMouse(SDL_Mouse * mouse);
|
||||
|
||||
static int id_mask;
|
||||
|
||||
static DFBEnumerationResult
|
||||
EnumMice(DFBInputDeviceID device_id, DFBInputDeviceDescription desc,
|
||||
void *callbackdata)
|
||||
{
|
||||
DFB_DeviceData *devdata = callbackdata;
|
||||
|
||||
if ((desc.type & DIDTF_MOUSE) && (device_id & id_mask)) {
|
||||
SDL_Mouse mouse;
|
||||
|
||||
SDL_zero(mouse);
|
||||
mouse.id = device_id;
|
||||
mouse.CreateCursor = DirectFB_CreateCursor;
|
||||
mouse.ShowCursor = DirectFB_ShowCursor;
|
||||
mouse.MoveCursor = DirectFB_MoveCursor;
|
||||
mouse.FreeCursor = DirectFB_FreeCursor;
|
||||
mouse.WarpMouse = DirectFB_WarpMouse;
|
||||
mouse.FreeMouse = DirectFB_FreeMouse;
|
||||
mouse.cursor_shown = 1;
|
||||
|
||||
SDL_AddMouse(&mouse, desc.name, 0, 0, 1);
|
||||
devdata->mouse_id[devdata->num_mice++] = device_id;
|
||||
}
|
||||
return DFENUM_OK;
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_InitMouse(_THIS)
|
||||
{
|
||||
SDL_DFB_DEVICEDATA(_this);
|
||||
|
||||
devdata->num_mice = 0;
|
||||
if (devdata->use_linux_input) {
|
||||
/* try non-core devices first */
|
||||
id_mask = 0xF0;
|
||||
devdata->dfb->EnumInputDevices(devdata->dfb, EnumMice, devdata);
|
||||
if (devdata->num_mice == 0) {
|
||||
/* try core devices */
|
||||
id_mask = 0x0F;
|
||||
devdata->dfb->EnumInputDevices(devdata->dfb, EnumMice, devdata);
|
||||
}
|
||||
}
|
||||
if (devdata->num_mice == 0) {
|
||||
SDL_Mouse mouse;
|
||||
|
||||
SDL_zero(mouse);
|
||||
mouse.CreateCursor = DirectFB_CreateCursor;
|
||||
mouse.ShowCursor = DirectFB_ShowCursor;
|
||||
mouse.MoveCursor = DirectFB_MoveCursor;
|
||||
mouse.FreeCursor = DirectFB_FreeCursor;
|
||||
mouse.WarpMouse = DirectFB_WarpMouse;
|
||||
mouse.FreeMouse = DirectFB_FreeMouse;
|
||||
mouse.cursor_shown = 1;
|
||||
|
||||
SDL_AddMouse(&mouse, "Mouse", 0, 0, 1);
|
||||
devdata->num_mice = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_QuitMouse(_THIS)
|
||||
{
|
||||
SDL_DFB_DEVICEDATA(_this);
|
||||
|
||||
if (devdata->use_linux_input) {
|
||||
SDL_MouseQuit();
|
||||
} else {
|
||||
SDL_DelMouse(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* This is called when a mouse motion event occurs */
|
||||
static void
|
||||
DirectFB_MoveCursor(SDL_Cursor * cursor)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* Warp the mouse to (x,y) */
|
||||
static void
|
||||
DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_Window * window, int x, int y)
|
||||
{
|
||||
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
|
||||
DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
|
||||
DFB_WindowData *windata = (DFB_WindowData *) window->driverdata;
|
||||
DFBResult ret;
|
||||
int cx, cy;
|
||||
|
||||
SDL_DFB_CHECKERR(windata->dfbwin->GetPosition(windata->dfbwin, &cx, &cy));
|
||||
SDL_DFB_CHECKERR(dispdata->layer->WarpCursor(dispdata->layer,
|
||||
cx + x + windata->client.x,
|
||||
cy + y + windata->client.y));
|
||||
|
||||
error:
|
||||
return;
|
||||
}
|
||||
|
||||
/* Free the mouse when it's time */
|
||||
static void
|
||||
DirectFB_FreeMouse(SDL_Mouse * mouse)
|
||||
{
|
||||
/* nothing yet */
|
||||
}
|
||||
|
||||
#else /* USE_MULTI_API */
|
||||
|
||||
void
|
||||
DirectFB_InitMouse(_THIS)
|
||||
{
|
||||
SDL_DFB_DEVICEDATA(_this);
|
||||
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
|
||||
mouse->CreateCursor = DirectFB_CreateCursor;
|
||||
mouse->ShowCursor = DirectFB_ShowCursor;
|
||||
mouse->WarpMouse = DirectFB_WarpMouse;
|
||||
mouse->FreeCursor = DirectFB_FreeCursor;
|
||||
|
||||
SDL_SetDefaultCursor(DirectFB_CreateDefaultCursor());
|
||||
|
||||
devdata->num_mice = 1;
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_QuitMouse(_THIS)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_DirectFB_mouse_h_
|
||||
#define SDL_DirectFB_mouse_h_
|
||||
|
||||
#include <directfb.h>
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
|
||||
typedef struct _DFB_CursorData DFB_CursorData;
|
||||
struct _DFB_CursorData
|
||||
{
|
||||
IDirectFBSurface *surf;
|
||||
int hotx;
|
||||
int hoty;
|
||||
};
|
||||
|
||||
#define SDL_DFB_CURSORDATA(curs) DFB_CursorData *curdata = (DFB_CursorData *) ((curs) ? (curs)->driverdata : NULL)
|
||||
|
||||
extern void DirectFB_InitMouse(_THIS);
|
||||
extern void DirectFB_QuitMouse(_THIS);
|
||||
|
||||
#endif /* SDL_DirectFB_mouse_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,332 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_DIRECTFB
|
||||
|
||||
#include "SDL_DirectFB_video.h"
|
||||
|
||||
#if SDL_DIRECTFB_OPENGL
|
||||
|
||||
#include "SDL_DirectFB_opengl.h"
|
||||
#include "SDL_DirectFB_window.h"
|
||||
|
||||
#include <directfbgl.h>
|
||||
#include "SDL_loadso.h"
|
||||
#endif
|
||||
|
||||
#if SDL_DIRECTFB_OPENGL
|
||||
|
||||
struct SDL_GLDriverData
|
||||
{
|
||||
int gl_active; /* to stop switching drivers while we have a valid context */
|
||||
int initialized;
|
||||
DirectFB_GLContext *firstgl; /* linked list */
|
||||
|
||||
/* OpenGL */
|
||||
void (*glFinish) (void);
|
||||
void (*glFlush) (void);
|
||||
};
|
||||
|
||||
#define OPENGL_REQUIRS_DLOPEN
|
||||
#if defined(OPENGL_REQUIRS_DLOPEN) && defined(HAVE_DLOPEN)
|
||||
#include <dlfcn.h>
|
||||
#define GL_LoadObject(X) dlopen(X, (RTLD_NOW|RTLD_GLOBAL))
|
||||
#define GL_LoadFunction dlsym
|
||||
#define GL_UnloadObject dlclose
|
||||
#else
|
||||
#define GL_LoadObject SDL_LoadObject
|
||||
#define GL_LoadFunction SDL_LoadFunction
|
||||
#define GL_UnloadObject SDL_UnloadObject
|
||||
#endif
|
||||
|
||||
static void DirectFB_GL_UnloadLibrary(_THIS);
|
||||
|
||||
int
|
||||
DirectFB_GL_Initialize(_THIS)
|
||||
{
|
||||
if (_this->gl_data) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
_this->gl_data =
|
||||
(struct SDL_GLDriverData *) SDL_calloc(1,
|
||||
sizeof(struct
|
||||
SDL_GLDriverData));
|
||||
if (!_this->gl_data) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
_this->gl_data->initialized = 0;
|
||||
|
||||
++_this->gl_data->initialized;
|
||||
_this->gl_data->firstgl = NULL;
|
||||
|
||||
if (DirectFB_GL_LoadLibrary(_this, NULL) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Initialize extensions */
|
||||
/* FIXME needed?
|
||||
* X11_GL_InitExtensions(_this);
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_GL_Shutdown(_THIS)
|
||||
{
|
||||
if (!_this->gl_data || (--_this->gl_data->initialized > 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
DirectFB_GL_UnloadLibrary(_this);
|
||||
|
||||
SDL_free(_this->gl_data);
|
||||
_this->gl_data = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
DirectFB_GL_LoadLibrary(_THIS, const char *path)
|
||||
{
|
||||
void *handle = NULL;
|
||||
|
||||
SDL_DFB_DEBUG("Loadlibrary : %s\n", path);
|
||||
|
||||
if (_this->gl_data->gl_active) {
|
||||
return SDL_SetError("OpenGL context already created");
|
||||
}
|
||||
|
||||
|
||||
if (path == NULL) {
|
||||
path = SDL_getenv("SDL_OPENGL_LIBRARY");
|
||||
if (path == NULL) {
|
||||
path = "libGL.so.1";
|
||||
}
|
||||
}
|
||||
|
||||
handle = GL_LoadObject(path);
|
||||
if (handle == NULL) {
|
||||
SDL_DFB_ERR("Library not found: %s\n", path);
|
||||
/* SDL_LoadObject() will call SDL_SetError() for us. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_DFB_DEBUG("Loaded library: %s\n", path);
|
||||
|
||||
_this->gl_config.dll_handle = handle;
|
||||
if (path) {
|
||||
SDL_strlcpy(_this->gl_config.driver_path, path,
|
||||
SDL_arraysize(_this->gl_config.driver_path));
|
||||
} else {
|
||||
*_this->gl_config.driver_path = '\0';
|
||||
}
|
||||
|
||||
_this->gl_data->glFinish = DirectFB_GL_GetProcAddress(_this, "glFinish");
|
||||
_this->gl_data->glFlush = DirectFB_GL_GetProcAddress(_this, "glFlush");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
DirectFB_GL_UnloadLibrary(_THIS)
|
||||
{
|
||||
#if 0
|
||||
int ret = GL_UnloadObject(_this->gl_config.dll_handle);
|
||||
if (ret)
|
||||
SDL_DFB_ERR("Error #%d trying to unload library.\n", ret);
|
||||
_this->gl_config.dll_handle = NULL;
|
||||
#endif
|
||||
/* Free OpenGL memory */
|
||||
SDL_free(_this->gl_data);
|
||||
_this->gl_data = NULL;
|
||||
}
|
||||
|
||||
void *
|
||||
DirectFB_GL_GetProcAddress(_THIS, const char *proc)
|
||||
{
|
||||
void *handle;
|
||||
|
||||
handle = _this->gl_config.dll_handle;
|
||||
return GL_LoadFunction(handle, proc);
|
||||
}
|
||||
|
||||
SDL_GLContext
|
||||
DirectFB_GL_CreateContext(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
DirectFB_GLContext *context;
|
||||
|
||||
SDL_DFB_ALLOC_CLEAR(context, sizeof(DirectFB_GLContext));
|
||||
|
||||
SDL_DFB_CHECKERR(windata->surface->GetGL(windata->surface,
|
||||
&context->context));
|
||||
|
||||
if (!context->context)
|
||||
return NULL;
|
||||
|
||||
context->is_locked = 0;
|
||||
context->sdl_window = window;
|
||||
|
||||
context->next = _this->gl_data->firstgl;
|
||||
_this->gl_data->firstgl = context;
|
||||
|
||||
SDL_DFB_CHECK(context->context->Unlock(context->context));
|
||||
|
||||
if (DirectFB_GL_MakeCurrent(_this, window, context) < 0) {
|
||||
DirectFB_GL_DeleteContext(_this, context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return context;
|
||||
|
||||
error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
|
||||
{
|
||||
DirectFB_GLContext *ctx = (DirectFB_GLContext *) context;
|
||||
DirectFB_GLContext *p;
|
||||
|
||||
for (p = _this->gl_data->firstgl; p; p = p->next)
|
||||
{
|
||||
if (p->is_locked) {
|
||||
SDL_DFB_CHECKERR(p->context->Unlock(p->context));
|
||||
p->is_locked = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (ctx != NULL) {
|
||||
SDL_DFB_CHECKERR(ctx->context->Lock(ctx->context));
|
||||
ctx->is_locked = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DirectFB_GL_SetSwapInterval(_THIS, int interval)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
int
|
||||
DirectFB_GL_GetSwapInterval(_THIS)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
DirectFB_GL_SwapWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
DirectFB_GLContext *p;
|
||||
|
||||
#if 0
|
||||
if (devdata->glFinish)
|
||||
devdata->glFinish();
|
||||
else if (devdata->glFlush)
|
||||
devdata->glFlush();
|
||||
#endif
|
||||
|
||||
for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
|
||||
if (p->sdl_window == window && p->is_locked)
|
||||
{
|
||||
SDL_DFB_CHECKERR(p->context->Unlock(p->context));
|
||||
p->is_locked = 0;
|
||||
}
|
||||
|
||||
SDL_DFB_CHECKERR(windata->window_surface->Flip(windata->window_surface,NULL, DSFLIP_PIPELINE |DSFLIP_BLIT | DSFLIP_ONSYNC ));
|
||||
return 0;
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context)
|
||||
{
|
||||
DirectFB_GLContext *ctx = (DirectFB_GLContext *) context;
|
||||
DirectFB_GLContext *p;
|
||||
|
||||
if (ctx->is_locked)
|
||||
SDL_DFB_CHECK(ctx->context->Unlock(ctx->context));
|
||||
SDL_DFB_RELEASE(ctx->context);
|
||||
|
||||
for (p = _this->gl_data->firstgl; p && p->next != ctx; p = p->next)
|
||||
;
|
||||
if (p)
|
||||
p->next = ctx->next;
|
||||
else
|
||||
_this->gl_data->firstgl = ctx->next;
|
||||
|
||||
SDL_DFB_FREE(ctx);
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_GL_FreeWindowContexts(_THIS, SDL_Window * window)
|
||||
{
|
||||
DirectFB_GLContext *p;
|
||||
|
||||
for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
|
||||
if (p->sdl_window == window)
|
||||
{
|
||||
if (p->is_locked)
|
||||
SDL_DFB_CHECK(p->context->Unlock(p->context));
|
||||
SDL_DFB_RELEASE(p->context);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_GL_ReAllocWindowContexts(_THIS, SDL_Window * window)
|
||||
{
|
||||
DirectFB_GLContext *p;
|
||||
|
||||
for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
|
||||
if (p->sdl_window == window)
|
||||
{
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
SDL_DFB_CHECK(windata->surface->GetGL(windata->surface,
|
||||
&p->context));
|
||||
if (p->is_locked)
|
||||
SDL_DFB_CHECK(p->context->Lock(p->context));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_GL_DestroyWindowContexts(_THIS, SDL_Window * window)
|
||||
{
|
||||
DirectFB_GLContext *p;
|
||||
|
||||
for (p = _this->gl_data->firstgl; p != NULL; p = p->next)
|
||||
if (p->sdl_window == window)
|
||||
DirectFB_GL_DeleteContext(_this, p);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SDL_directfb_opengl_h_
|
||||
#define SDL_directfb_opengl_h_
|
||||
|
||||
#include "SDL_DirectFB_video.h"
|
||||
|
||||
#if SDL_DIRECTFB_OPENGL
|
||||
|
||||
#include "SDL_opengl.h"
|
||||
|
||||
typedef struct _DirectFB_GLContext DirectFB_GLContext;
|
||||
struct _DirectFB_GLContext
|
||||
{
|
||||
IDirectFBGL *context;
|
||||
DirectFB_GLContext *next;
|
||||
|
||||
SDL_Window *sdl_window;
|
||||
int is_locked;
|
||||
};
|
||||
|
||||
/* OpenGL functions */
|
||||
extern int DirectFB_GL_Initialize(_THIS);
|
||||
extern void DirectFB_GL_Shutdown(_THIS);
|
||||
|
||||
extern int DirectFB_GL_LoadLibrary(_THIS, const char *path);
|
||||
extern void *DirectFB_GL_GetProcAddress(_THIS, const char *proc);
|
||||
extern SDL_GLContext DirectFB_GL_CreateContext(_THIS, SDL_Window * window);
|
||||
extern int DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window,
|
||||
SDL_GLContext context);
|
||||
extern int DirectFB_GL_SetSwapInterval(_THIS, int interval);
|
||||
extern int DirectFB_GL_GetSwapInterval(_THIS);
|
||||
extern int DirectFB_GL_SwapWindow(_THIS, SDL_Window * window);
|
||||
extern void DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context);
|
||||
|
||||
extern void DirectFB_GL_FreeWindowContexts(_THIS, SDL_Window * window);
|
||||
extern void DirectFB_GL_ReAllocWindowContexts(_THIS, SDL_Window * window);
|
||||
extern void DirectFB_GL_DestroyWindowContexts(_THIS, SDL_Window * window);
|
||||
|
||||
#endif /* SDL_DIRECTFB_OPENGL */
|
||||
|
||||
#endif /* SDL_directfb_opengl_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,130 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_DIRECTFB
|
||||
|
||||
#include "SDL_DirectFB_video.h"
|
||||
#include "SDL_DirectFB_shape.h"
|
||||
#include "SDL_DirectFB_window.h"
|
||||
|
||||
#include "../SDL_shape_internals.h"
|
||||
|
||||
SDL_WindowShaper*
|
||||
DirectFB_CreateShaper(SDL_Window* window) {
|
||||
SDL_WindowShaper* result = NULL;
|
||||
SDL_ShapeData* data;
|
||||
int resized_properly;
|
||||
|
||||
result = SDL_malloc(sizeof(SDL_WindowShaper));
|
||||
result->window = window;
|
||||
result->mode.mode = ShapeModeDefault;
|
||||
result->mode.parameters.binarizationCutoff = 1;
|
||||
result->userx = result->usery = 0;
|
||||
data = SDL_malloc(sizeof(SDL_ShapeData));
|
||||
result->driverdata = data;
|
||||
data->surface = NULL;
|
||||
window->shaper = result;
|
||||
resized_properly = DirectFB_ResizeWindowShape(window);
|
||||
SDL_assert(resized_properly == 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
DirectFB_ResizeWindowShape(SDL_Window* window) {
|
||||
SDL_ShapeData* data = window->shaper->driverdata;
|
||||
SDL_assert(data != NULL);
|
||||
|
||||
if (window->x != -1000)
|
||||
{
|
||||
window->shaper->userx = window->x;
|
||||
window->shaper->usery = window->y;
|
||||
}
|
||||
SDL_SetWindowPosition(window,-1000,-1000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
DirectFB_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode) {
|
||||
|
||||
if(shaper == NULL || shape == NULL || shaper->driverdata == NULL)
|
||||
return -1;
|
||||
if(shape->format->Amask == 0 && SDL_SHAPEMODEALPHA(shape_mode->mode))
|
||||
return -2;
|
||||
if(shape->w != shaper->window->w || shape->h != shaper->window->h)
|
||||
return -3;
|
||||
|
||||
{
|
||||
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(shaper->window);
|
||||
SDL_DFB_DEVICEDATA(display->device);
|
||||
Uint32 *pixels;
|
||||
Sint32 pitch;
|
||||
Uint32 h,w;
|
||||
Uint8 *src, *bitmap;
|
||||
DFBSurfaceDescription dsc;
|
||||
|
||||
SDL_ShapeData *data = shaper->driverdata;
|
||||
|
||||
SDL_DFB_RELEASE(data->surface);
|
||||
|
||||
dsc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
|
||||
dsc.width = shape->w;
|
||||
dsc.height = shape->h;
|
||||
dsc.caps = DSCAPS_PREMULTIPLIED;
|
||||
dsc.pixelformat = DSPF_ARGB;
|
||||
|
||||
SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc, &data->surface));
|
||||
|
||||
/* Assume that shaper->alphacutoff already has a value, because SDL_SetWindowShape() should have given it one. */
|
||||
SDL_DFB_ALLOC_CLEAR(bitmap, shape->w * shape->h);
|
||||
SDL_CalculateShapeBitmap(shaper->mode,shape,bitmap,1);
|
||||
|
||||
src = bitmap;
|
||||
|
||||
SDL_DFB_CHECK(data->surface->Lock(data->surface, DSLF_WRITE | DSLF_READ, (void **) &pixels, &pitch));
|
||||
|
||||
h = shaper->window->h;
|
||||
while (h--) {
|
||||
for (w = 0; w < shaper->window->w; w++) {
|
||||
if (*src)
|
||||
pixels[w] = 0xFFFFFFFF;
|
||||
else
|
||||
pixels[w] = 0;
|
||||
src++;
|
||||
|
||||
}
|
||||
pixels += (pitch >> 2);
|
||||
}
|
||||
SDL_DFB_CHECK(data->surface->Unlock(data->surface));
|
||||
SDL_DFB_FREE(bitmap);
|
||||
|
||||
/* FIXME: Need to call this here - Big ?? */
|
||||
DirectFB_WM_RedrawLayout(SDL_GetDisplayForWindow(shaper->window)->device, shaper->window);
|
||||
}
|
||||
|
||||
return 0;
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_DirectFB_shape_h_
|
||||
#define SDL_DirectFB_shape_h_
|
||||
|
||||
#include <directfb.h>
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "SDL_shape.h"
|
||||
|
||||
typedef struct {
|
||||
IDirectFBSurface *surface;
|
||||
} SDL_ShapeData;
|
||||
|
||||
extern SDL_WindowShaper* DirectFB_CreateShaper(SDL_Window* window);
|
||||
extern int DirectFB_ResizeWindowShape(SDL_Window* window);
|
||||
extern int DirectFB_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shapeMode);
|
||||
|
||||
#endif /* SDL_DirectFB_shape_h_ */
|
||||
@@ -1,418 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_DIRECTFB
|
||||
|
||||
/*
|
||||
* #include "SDL_DirectFB_keyboard.h"
|
||||
*/
|
||||
#include "SDL_DirectFB_modes.h"
|
||||
#include "SDL_DirectFB_opengl.h"
|
||||
#include "SDL_DirectFB_vulkan.h"
|
||||
#include "SDL_DirectFB_window.h"
|
||||
#include "SDL_DirectFB_WM.h"
|
||||
|
||||
|
||||
/* DirectFB video driver implementation.
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <directfb.h>
|
||||
#include <directfb_version.h>
|
||||
#include <directfb_strings.h>
|
||||
|
||||
#include "SDL_video.h"
|
||||
#include "SDL_mouse.h"
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "../SDL_pixels_c.h"
|
||||
#include "../../events/SDL_events_c.h"
|
||||
#include "SDL_DirectFB_video.h"
|
||||
#include "SDL_DirectFB_events.h"
|
||||
#include "SDL_DirectFB_render.h"
|
||||
#include "SDL_DirectFB_mouse.h"
|
||||
#include "SDL_DirectFB_shape.h"
|
||||
|
||||
|
||||
#include "SDL_DirectFB_dyn.h"
|
||||
|
||||
/* Initialization/Query functions */
|
||||
static int DirectFB_VideoInit(_THIS);
|
||||
static void DirectFB_VideoQuit(_THIS);
|
||||
|
||||
static SDL_VideoDevice *DirectFB_CreateDevice(void);
|
||||
|
||||
VideoBootStrap DirectFB_bootstrap = {
|
||||
"directfb", "DirectFB",
|
||||
DirectFB_CreateDevice
|
||||
};
|
||||
|
||||
static const DirectFBSurfaceDrawingFlagsNames(drawing_flags);
|
||||
static const DirectFBSurfaceBlittingFlagsNames(blitting_flags);
|
||||
static const DirectFBAccelerationMaskNames(acceleration_mask);
|
||||
|
||||
/* DirectFB driver bootstrap functions */
|
||||
|
||||
static void
|
||||
DirectFB_DeleteDevice(SDL_VideoDevice * device)
|
||||
{
|
||||
SDL_DirectFB_UnLoadLibrary();
|
||||
SDL_DFB_FREE(device->driverdata);
|
||||
SDL_DFB_FREE(device);
|
||||
}
|
||||
|
||||
static SDL_VideoDevice *
|
||||
DirectFB_CreateDevice(void)
|
||||
{
|
||||
SDL_VideoDevice *device;
|
||||
|
||||
if (!SDL_DirectFB_LoadLibrary()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
SDL_DFB_ALLOC_CLEAR(device, sizeof(SDL_VideoDevice));
|
||||
|
||||
/* Set the function pointers */
|
||||
device->VideoInit = DirectFB_VideoInit;
|
||||
device->VideoQuit = DirectFB_VideoQuit;
|
||||
device->GetDisplayModes = DirectFB_GetDisplayModes;
|
||||
device->SetDisplayMode = DirectFB_SetDisplayMode;
|
||||
device->PumpEvents = DirectFB_PumpEventsWindow;
|
||||
device->CreateSDLWindow = DirectFB_CreateWindow;
|
||||
device->CreateSDLWindowFrom = DirectFB_CreateWindowFrom;
|
||||
device->SetWindowTitle = DirectFB_SetWindowTitle;
|
||||
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;
|
||||
device->MaximizeWindow = DirectFB_MaximizeWindow;
|
||||
device->MinimizeWindow = DirectFB_MinimizeWindow;
|
||||
device->RestoreWindow = DirectFB_RestoreWindow;
|
||||
device->SetWindowMouseGrab = DirectFB_SetWindowMouseGrab;
|
||||
device->SetWindowKeyboardGrab = DirectFB_SetWindowKeyboardGrab;
|
||||
device->DestroyWindow = DirectFB_DestroyWindow;
|
||||
device->GetWindowWMInfo = DirectFB_GetWindowWMInfo;
|
||||
|
||||
/* !!! FIXME: implement SetWindowBordered */
|
||||
|
||||
#if SDL_DIRECTFB_OPENGL
|
||||
device->GL_LoadLibrary = DirectFB_GL_LoadLibrary;
|
||||
device->GL_GetProcAddress = DirectFB_GL_GetProcAddress;
|
||||
device->GL_MakeCurrent = DirectFB_GL_MakeCurrent;
|
||||
|
||||
device->GL_CreateContext = DirectFB_GL_CreateContext;
|
||||
device->GL_SetSwapInterval = DirectFB_GL_SetSwapInterval;
|
||||
device->GL_GetSwapInterval = DirectFB_GL_GetSwapInterval;
|
||||
device->GL_SwapWindow = DirectFB_GL_SwapWindow;
|
||||
device->GL_DeleteContext = DirectFB_GL_DeleteContext;
|
||||
|
||||
#endif
|
||||
|
||||
/* Shaped window support */
|
||||
device->shape_driver.CreateShaper = DirectFB_CreateShaper;
|
||||
device->shape_driver.SetWindowShape = DirectFB_SetWindowShape;
|
||||
device->shape_driver.ResizeWindowShape = DirectFB_ResizeWindowShape;
|
||||
|
||||
#if SDL_VIDEO_VULKAN
|
||||
device->Vulkan_LoadLibrary = DirectFB_Vulkan_LoadLibrary;
|
||||
device->Vulkan_UnloadLibrary = DirectFB_Vulkan_UnloadLibrary;
|
||||
device->Vulkan_GetInstanceExtensions = DirectFB_Vulkan_GetInstanceExtensions;
|
||||
device->Vulkan_CreateSurface = DirectFB_Vulkan_CreateSurface;
|
||||
#endif
|
||||
|
||||
device->free = DirectFB_DeleteDevice;
|
||||
|
||||
return device;
|
||||
error:
|
||||
if (device)
|
||||
SDL_free(device);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
DirectFB_DeviceInformation(IDirectFB * dfb)
|
||||
{
|
||||
DFBGraphicsDeviceDescription desc;
|
||||
int n;
|
||||
|
||||
dfb->GetDeviceDescription(dfb, &desc);
|
||||
|
||||
SDL_DFB_LOG( "DirectFB Device Information");
|
||||
SDL_DFB_LOG( "===========================");
|
||||
SDL_DFB_LOG( "Name: %s", desc.name);
|
||||
SDL_DFB_LOG( "Vendor: %s", desc.vendor);
|
||||
SDL_DFB_LOG( "Driver Name: %s", desc.driver.name);
|
||||
SDL_DFB_LOG( "Driver Vendor: %s", desc.driver.vendor);
|
||||
SDL_DFB_LOG( "Driver Version: %d.%d", desc.driver.major,
|
||||
desc.driver.minor);
|
||||
|
||||
SDL_DFB_LOG( "Video memory: %d", desc.video_memory);
|
||||
|
||||
SDL_DFB_LOG( "Blitting flags:");
|
||||
for (n = 0; blitting_flags[n].flag; n++) {
|
||||
if (desc.blitting_flags & blitting_flags[n].flag)
|
||||
SDL_DFB_LOG( " %s", blitting_flags[n].name);
|
||||
}
|
||||
|
||||
SDL_DFB_LOG( "Drawing flags:");
|
||||
for (n = 0; drawing_flags[n].flag; n++) {
|
||||
if (desc.drawing_flags & drawing_flags[n].flag)
|
||||
SDL_DFB_LOG( " %s", drawing_flags[n].name);
|
||||
}
|
||||
|
||||
|
||||
SDL_DFB_LOG( "Acceleration flags:");
|
||||
for (n = 0; acceleration_mask[n].mask; n++) {
|
||||
if (desc.acceleration_mask & acceleration_mask[n].mask)
|
||||
SDL_DFB_LOG( " %s", acceleration_mask[n].name);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
static int readBoolEnv(const char *env_name, int def_val)
|
||||
{
|
||||
char *stemp;
|
||||
|
||||
stemp = SDL_getenv(env_name);
|
||||
if (stemp)
|
||||
return SDL_atoi(stemp);
|
||||
else
|
||||
return def_val;
|
||||
}
|
||||
|
||||
static int
|
||||
DirectFB_VideoInit(_THIS)
|
||||
{
|
||||
IDirectFB *dfb = NULL;
|
||||
DFB_DeviceData *devdata = NULL;
|
||||
DFBResult ret;
|
||||
|
||||
SDL_DFB_ALLOC_CLEAR(devdata, sizeof(*devdata));
|
||||
|
||||
SDL_DFB_CHECKERR(DirectFBInit(NULL, NULL));
|
||||
|
||||
/* avoid switching to the framebuffer when we
|
||||
* are running X11 */
|
||||
ret = readBoolEnv(DFBENV_USE_X11_CHECK , 1);
|
||||
if (ret) {
|
||||
if (SDL_getenv("DISPLAY"))
|
||||
DirectFBSetOption("system", "x11");
|
||||
else
|
||||
DirectFBSetOption("disable-module", "x11input");
|
||||
}
|
||||
|
||||
devdata->use_linux_input = readBoolEnv(DFBENV_USE_LINUX_INPUT, 1); /* default: on */
|
||||
|
||||
if (!devdata->use_linux_input)
|
||||
{
|
||||
SDL_DFB_LOG("Disabling linux input\n");
|
||||
DirectFBSetOption("disable-module", "linux_input");
|
||||
}
|
||||
|
||||
SDL_DFB_CHECKERR(DirectFBCreate(&dfb));
|
||||
|
||||
DirectFB_DeviceInformation(dfb);
|
||||
|
||||
devdata->use_yuv_underlays = readBoolEnv(DFBENV_USE_YUV_UNDERLAY, 0); /* default: off */
|
||||
devdata->use_yuv_direct = readBoolEnv(DFBENV_USE_YUV_DIRECT, 0); /* default is off! */
|
||||
|
||||
/* Create global Eventbuffer for axis events */
|
||||
if (devdata->use_linux_input) {
|
||||
SDL_DFB_CHECKERR(dfb->CreateInputEventBuffer(dfb, DICAPS_ALL,
|
||||
DFB_TRUE,
|
||||
&devdata->events));
|
||||
} else {
|
||||
SDL_DFB_CHECKERR(dfb->CreateInputEventBuffer(dfb, DICAPS_AXES
|
||||
/* DICAPS_ALL */ ,
|
||||
DFB_TRUE,
|
||||
&devdata->events));
|
||||
}
|
||||
|
||||
/* simple window manager support */
|
||||
devdata->has_own_wm = readBoolEnv(DFBENV_USE_WM, 0);
|
||||
|
||||
devdata->initialized = 1;
|
||||
|
||||
devdata->dfb = dfb;
|
||||
devdata->firstwin = NULL;
|
||||
|
||||
_this->driverdata = devdata;
|
||||
|
||||
DirectFB_InitModes(_this);
|
||||
|
||||
#if SDL_DIRECTFB_OPENGL
|
||||
DirectFB_GL_Initialize(_this);
|
||||
#endif
|
||||
|
||||
DirectFB_InitMouse(_this);
|
||||
DirectFB_InitKeyboard(_this);
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
error:
|
||||
SDL_DFB_FREE(devdata);
|
||||
SDL_DFB_RELEASE(dfb);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
DirectFB_VideoQuit(_THIS)
|
||||
{
|
||||
DFB_DeviceData *devdata = (DFB_DeviceData *) _this->driverdata;
|
||||
|
||||
DirectFB_QuitModes(_this);
|
||||
DirectFB_QuitKeyboard(_this);
|
||||
DirectFB_QuitMouse(_this);
|
||||
|
||||
devdata->events->Reset(devdata->events);
|
||||
SDL_DFB_RELEASE(devdata->events);
|
||||
SDL_DFB_RELEASE(devdata->dfb);
|
||||
|
||||
#if SDL_DIRECTFB_OPENGL
|
||||
DirectFB_GL_Shutdown(_this);
|
||||
#endif
|
||||
|
||||
devdata->initialized = 0;
|
||||
}
|
||||
|
||||
/* DirectFB driver general support functions */
|
||||
|
||||
static const struct {
|
||||
DFBSurfacePixelFormat dfb;
|
||||
Uint32 sdl;
|
||||
} pixelformat_tab[] =
|
||||
{
|
||||
{ DSPF_RGB32, SDL_PIXELFORMAT_RGB888 }, /* 24 bit RGB (4 byte, nothing@24, red 8@16, green 8@8, blue 8@0) */
|
||||
{ DSPF_ARGB, SDL_PIXELFORMAT_ARGB8888 }, /* 32 bit ARGB (4 byte, alpha 8@24, red 8@16, green 8@8, blue 8@0) */
|
||||
{ DSPF_RGB16, SDL_PIXELFORMAT_RGB565 }, /* 16 bit RGB (2 byte, red 5@11, green 6@5, blue 5@0) */
|
||||
{ DSPF_RGB332, SDL_PIXELFORMAT_RGB332 }, /* 8 bit RGB (1 byte, red 3@5, green 3@2, blue 2@0) */
|
||||
{ DSPF_ARGB4444, SDL_PIXELFORMAT_ARGB4444 }, /* 16 bit ARGB (2 byte, alpha 4@12, red 4@8, green 4@4, blue 4@0) */
|
||||
{ DSPF_ARGB1555, SDL_PIXELFORMAT_ARGB1555 }, /* 16 bit ARGB (2 byte, alpha 1@15, red 5@10, green 5@5, blue 5@0) */
|
||||
{ DSPF_RGB24, SDL_PIXELFORMAT_RGB24 }, /* 24 bit RGB (3 byte, red 8@16, green 8@8, blue 8@0) */
|
||||
{ DSPF_RGB444, SDL_PIXELFORMAT_RGB444 }, /* 16 bit RGB (2 byte, nothing @12, red 4@8, green 4@4, blue 4@0) */
|
||||
{ DSPF_YV12, SDL_PIXELFORMAT_YV12 }, /* 12 bit YUV (8 bit Y plane followed by 8 bit quarter size V/U planes) */
|
||||
{ DSPF_I420,SDL_PIXELFORMAT_IYUV }, /* 12 bit YUV (8 bit Y plane followed by 8 bit quarter size U/V planes) */
|
||||
{ DSPF_YUY2, SDL_PIXELFORMAT_YUY2 }, /* 16 bit YUV (4 byte/ 2 pixel, macropixel contains CbYCrY [31:0]) */
|
||||
{ DSPF_UYVY, SDL_PIXELFORMAT_UYVY }, /* 16 bit YUV (4 byte/ 2 pixel, macropixel contains YCbYCr [31:0]) */
|
||||
{ DSPF_RGB555, SDL_PIXELFORMAT_RGB555 }, /* 16 bit RGB (2 byte, nothing @15, red 5@10, green 5@5, blue 5@0) */
|
||||
#if (DFB_VERSION_ATLEAST(1,5,0))
|
||||
{ DSPF_ABGR, SDL_PIXELFORMAT_ABGR8888 }, /* 32 bit ABGR (4 byte, alpha 8@24, blue 8@16, green 8@8, red 8@0) */
|
||||
#endif
|
||||
#if (ENABLE_LUT8)
|
||||
{ DSPF_LUT8, SDL_PIXELFORMAT_INDEX8 }, /* 8 bit LUT (8 bit color and alpha lookup from palette) */
|
||||
#endif
|
||||
|
||||
#if (DFB_VERSION_ATLEAST(1,2,0))
|
||||
{ DSPF_BGR555, SDL_PIXELFORMAT_BGR555 }, /* 16 bit BGR (2 byte, nothing @15, blue 5@10, green 5@5, red 5@0) */
|
||||
#else
|
||||
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR555 },
|
||||
#endif
|
||||
|
||||
/* Pfff ... nonmatching formats follow */
|
||||
|
||||
{ DSPF_ALUT44, SDL_PIXELFORMAT_UNKNOWN }, /* 8 bit ALUT (1 byte, alpha 4@4, color lookup 4@0) */
|
||||
{ DSPF_A8, SDL_PIXELFORMAT_UNKNOWN }, /* 8 bit alpha (1 byte, alpha 8@0), e.g. anti-aliased glyphs */
|
||||
{ DSPF_AiRGB, SDL_PIXELFORMAT_UNKNOWN }, /* 32 bit ARGB (4 byte, inv. alpha 8@24, red 8@16, green 8@8, blue 8@0) */
|
||||
{ DSPF_A1, SDL_PIXELFORMAT_UNKNOWN }, /* 1 bit alpha (1 byte/ 8 pixel, most significant bit used first) */
|
||||
{ DSPF_NV12, SDL_PIXELFORMAT_UNKNOWN }, /* 12 bit YUV (8 bit Y plane followed by one 16 bit quarter size CbCr [15:0] plane) */
|
||||
{ DSPF_NV16, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit YUV (8 bit Y plane followed by one 16 bit half width CbCr [15:0] plane) */
|
||||
{ DSPF_ARGB2554, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit ARGB (2 byte, alpha 2@14, red 5@9, green 5@4, blue 4@0) */
|
||||
{ DSPF_NV21, SDL_PIXELFORMAT_UNKNOWN }, /* 12 bit YUV (8 bit Y plane followed by one 16 bit quarter size CrCb [15:0] plane) */
|
||||
{ DSPF_AYUV, SDL_PIXELFORMAT_UNKNOWN }, /* 32 bit AYUV (4 byte, alpha 8@24, Y 8@16, Cb 8@8, Cr 8@0) */
|
||||
{ DSPF_A4, SDL_PIXELFORMAT_UNKNOWN }, /* 4 bit alpha (1 byte/ 2 pixel, more significant nibble used first) */
|
||||
{ DSPF_ARGB1666, SDL_PIXELFORMAT_UNKNOWN }, /* 1 bit alpha (3 byte/ alpha 1@18, red 6@16, green 6@6, blue 6@0) */
|
||||
{ DSPF_ARGB6666, SDL_PIXELFORMAT_UNKNOWN }, /* 6 bit alpha (3 byte/ alpha 6@18, red 6@16, green 6@6, blue 6@0) */
|
||||
{ DSPF_RGB18, SDL_PIXELFORMAT_UNKNOWN }, /* 6 bit RGB (3 byte/ red 6@16, green 6@6, blue 6@0) */
|
||||
{ DSPF_LUT2, SDL_PIXELFORMAT_UNKNOWN }, /* 2 bit LUT (1 byte/ 4 pixel, 2 bit color and alpha lookup from palette) */
|
||||
|
||||
#if (DFB_VERSION_ATLEAST(1,3,0))
|
||||
{ DSPF_RGBA4444, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit RGBA (2 byte, red 4@12, green 4@8, blue 4@4, alpha 4@0) */
|
||||
#endif
|
||||
|
||||
#if (DFB_VERSION_ATLEAST(1,4,3))
|
||||
{ DSPF_RGBA5551, SDL_PIXELFORMAT_UNKNOWN }, /* 16 bit RGBA (2 byte, red 5@11, green 5@6, blue 5@1, alpha 1@0) */
|
||||
{ DSPF_YUV444P, SDL_PIXELFORMAT_UNKNOWN }, /* 24 bit full YUV planar (8 bit Y plane followed by an 8 bit Cb and an 8 bit Cr plane) */
|
||||
{ DSPF_ARGB8565, SDL_PIXELFORMAT_UNKNOWN }, /* 24 bit ARGB (3 byte, alpha 8@16, red 5@11, green 6@5, blue 5@0) */
|
||||
{ DSPF_AVYU, SDL_PIXELFORMAT_UNKNOWN }, /* 32 bit AVYU 4:4:4 (4 byte, alpha 8@24, Cr 8@16, Y 8@8, Cb 8@0) */
|
||||
{ DSPF_VYU, SDL_PIXELFORMAT_UNKNOWN }, /* 24 bit VYU 4:4:4 (3 byte, Cr 8@16, Y 8@8, Cb 8@0) */
|
||||
#endif
|
||||
|
||||
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX1LSB },
|
||||
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX1MSB },
|
||||
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX4LSB },
|
||||
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_INDEX4MSB },
|
||||
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR24 },
|
||||
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR888 },
|
||||
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_RGBA8888 },
|
||||
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_BGRA8888 },
|
||||
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_ARGB2101010 },
|
||||
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_ABGR4444 },
|
||||
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_ABGR1555 },
|
||||
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_BGR565 },
|
||||
{ DSPF_UNKNOWN, SDL_PIXELFORMAT_YVYU }, /**< Packed mode: Y0+V0+Y1+U0 (1 pla */
|
||||
};
|
||||
|
||||
Uint32
|
||||
DirectFB_DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++)
|
||||
if (pixelformat_tab[i].dfb == pixelformat)
|
||||
{
|
||||
return pixelformat_tab[i].sdl;
|
||||
}
|
||||
return SDL_PIXELFORMAT_UNKNOWN;
|
||||
}
|
||||
|
||||
DFBSurfacePixelFormat
|
||||
DirectFB_SDLToDFBPixelFormat(Uint32 format)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++)
|
||||
if (pixelformat_tab[i].sdl == format)
|
||||
{
|
||||
return pixelformat_tab[i].dfb;
|
||||
}
|
||||
return DSPF_UNKNOWN;
|
||||
}
|
||||
|
||||
void DirectFB_SetSupportedPixelFormats(SDL_RendererInfo* ri)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i=0, j=0; pixelformat_tab[i].dfb != DSPF_UNKNOWN; i++)
|
||||
if (pixelformat_tab[i].sdl != SDL_PIXELFORMAT_UNKNOWN)
|
||||
ri->texture_formats[j++] = pixelformat_tab[i].sdl;
|
||||
ri->num_texture_formats = j;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
|
||||
@@ -1,165 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifndef SDL_DirectFB_video_h_
|
||||
#define SDL_DirectFB_video_h_
|
||||
|
||||
#include <directfb.h>
|
||||
#include <directfb_version.h>
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "SDL_scancode.h"
|
||||
#include "SDL_render.h"
|
||||
|
||||
|
||||
#define DFB_VERSIONNUM(X, Y, Z) \
|
||||
((X)*1000 + (Y)*100 + (Z))
|
||||
|
||||
#define DFB_COMPILEDVERSION \
|
||||
DFB_VERSIONNUM(DIRECTFB_MAJOR_VERSION, DIRECTFB_MINOR_VERSION, DIRECTFB_MICRO_VERSION)
|
||||
|
||||
#define DFB_VERSION_ATLEAST(X, Y, Z) \
|
||||
(DFB_COMPILEDVERSION >= DFB_VERSIONNUM(X, Y, Z))
|
||||
|
||||
#if (DFB_VERSION_ATLEAST(1,0,0))
|
||||
#ifdef SDL_VIDEO_OPENGL
|
||||
#define SDL_DIRECTFB_OPENGL 1
|
||||
#endif
|
||||
#else
|
||||
#error "SDL_DIRECTFB: Please compile against libdirectfb version >= 1.0.0"
|
||||
#endif
|
||||
|
||||
/* Set below to 1 to compile with (old) multi mice/keyboard api. Code left in
|
||||
* in case we see this again ...
|
||||
*/
|
||||
|
||||
#define USE_MULTI_API (0)
|
||||
|
||||
/* Support for LUT8/INDEX8 pixel format.
|
||||
* This is broken in DirectFB 1.4.3. It works in 1.4.0 and 1.4.5
|
||||
* occurred.
|
||||
*/
|
||||
|
||||
#if (DFB_COMPILEDVERSION == DFB_VERSIONNUM(1, 4, 3))
|
||||
#define ENABLE_LUT8 (0)
|
||||
#else
|
||||
#define ENABLE_LUT8 (1)
|
||||
#endif
|
||||
|
||||
#define DIRECTFB_DEBUG 1
|
||||
|
||||
#define DFBENV_USE_YUV_UNDERLAY "SDL_DIRECTFB_YUV_UNDERLAY" /* Default: off */
|
||||
#define DFBENV_USE_YUV_DIRECT "SDL_DIRECTFB_YUV_DIRECT" /* Default: off */
|
||||
#define DFBENV_USE_X11_CHECK "SDL_DIRECTFB_X11_CHECK" /* Default: on */
|
||||
#define DFBENV_USE_LINUX_INPUT "SDL_DIRECTFB_LINUX_INPUT" /* Default: on */
|
||||
#define DFBENV_USE_WM "SDL_DIRECTFB_WM" /* Default: off */
|
||||
|
||||
#define SDL_DFB_RELEASE(x) do { if ( (x) != NULL ) { SDL_DFB_CHECK(x->Release(x)); x = NULL; } } while (0)
|
||||
#define SDL_DFB_FREE(x) do { SDL_free((x)); (x) = NULL; } while (0)
|
||||
#define SDL_DFB_UNLOCK(x) do { if ( (x) != NULL ) { x->Unlock(x); } } while (0)
|
||||
|
||||
#define SDL_DFB_CONTEXT "SDL_DirectFB"
|
||||
|
||||
#define SDL_DFB_ERR(x...) SDL_LogError(SDL_LOG_CATEGORY_ERROR, x)
|
||||
|
||||
#if (DIRECTFB_DEBUG)
|
||||
#define SDL_DFB_LOG(x...) SDL_LogInfo(SDL_LOG_CATEGORY_VIDEO, x)
|
||||
|
||||
#define SDL_DFB_DEBUG(x...) SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, x)
|
||||
|
||||
static SDL_INLINE DFBResult sdl_dfb_check(DFBResult ret, const char *src_file, int src_line) {
|
||||
if (ret != DFB_OK) {
|
||||
SDL_DFB_LOG("%s (%d):%s", src_file, src_line, DirectFBErrorString (ret) );
|
||||
SDL_SetError("%s:%s", SDL_DFB_CONTEXT, DirectFBErrorString (ret) );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define SDL_DFB_CHECK(x...) do { sdl_dfb_check( x, __FILE__, __LINE__); } while (0)
|
||||
#define SDL_DFB_CHECKERR(x...) do { if ( sdl_dfb_check( x, __FILE__, __LINE__) != DFB_OK ) goto error; } while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define SDL_DFB_CHECK(x...) x
|
||||
#define SDL_DFB_CHECKERR(x...) do { if (x != DFB_OK ) goto error; } while (0)
|
||||
#define SDL_DFB_LOG(x...) do {} while (0)
|
||||
#define SDL_DFB_DEBUG(x...) do {} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define SDL_DFB_CALLOC(r, n, s) \
|
||||
do { \
|
||||
r = SDL_calloc (n, s); \
|
||||
if (!(r)) { \
|
||||
SDL_DFB_ERR("Out of memory"); \
|
||||
SDL_OutOfMemory(); \
|
||||
goto error; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SDL_DFB_ALLOC_CLEAR(r, s) SDL_DFB_CALLOC(r, 1, s)
|
||||
|
||||
/* Private display data */
|
||||
|
||||
#define SDL_DFB_DEVICEDATA(dev) DFB_DeviceData *devdata = (dev ? (DFB_DeviceData *) ((dev)->driverdata) : NULL)
|
||||
|
||||
#define DFB_MAX_SCREENS 10
|
||||
|
||||
typedef struct _DFB_KeyboardData DFB_KeyboardData;
|
||||
struct _DFB_KeyboardData
|
||||
{
|
||||
const SDL_Scancode *map; /* keyboard scancode map */
|
||||
int map_size; /* size of map */
|
||||
int map_adjust; /* index adjust */
|
||||
int is_generic; /* generic keyboard */
|
||||
int id;
|
||||
};
|
||||
|
||||
typedef struct _DFB_DeviceData DFB_DeviceData;
|
||||
struct _DFB_DeviceData
|
||||
{
|
||||
int initialized;
|
||||
|
||||
IDirectFB *dfb;
|
||||
int num_mice;
|
||||
int mouse_id[0x100];
|
||||
int num_keyboard;
|
||||
DFB_KeyboardData keyboard[10];
|
||||
SDL_Window *firstwin;
|
||||
|
||||
int use_yuv_underlays;
|
||||
int use_yuv_direct;
|
||||
int use_linux_input;
|
||||
int has_own_wm;
|
||||
|
||||
/* global events */
|
||||
IDirectFBEventBuffer *events;
|
||||
};
|
||||
|
||||
Uint32 DirectFB_DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat);
|
||||
DFBSurfacePixelFormat DirectFB_SDLToDFBPixelFormat(Uint32 format);
|
||||
void DirectFB_SetSupportedPixelFormats(SDL_RendererInfo *ri);
|
||||
|
||||
|
||||
#endif /* SDL_DirectFB_video_h_ */
|
||||
@@ -1,169 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_DIRECTFB
|
||||
|
||||
#include "SDL_DirectFB_window.h"
|
||||
|
||||
#include "SDL_loadso.h"
|
||||
#include "SDL_DirectFB_vulkan.h"
|
||||
|
||||
int DirectFB_Vulkan_LoadLibrary(_THIS, const char *path)
|
||||
{
|
||||
VkExtensionProperties *extensions = NULL;
|
||||
Uint32 i, extensionCount = 0;
|
||||
SDL_bool hasSurfaceExtension = SDL_FALSE;
|
||||
SDL_bool hasDirectFBSurfaceExtension = SDL_FALSE;
|
||||
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
|
||||
if(_this->vulkan_config.loader_handle)
|
||||
return SDL_SetError("Vulkan already loaded");
|
||||
|
||||
/* Load the Vulkan loader library */
|
||||
if(!path)
|
||||
path = SDL_getenv("SDL_VULKAN_LIBRARY");
|
||||
if(!path)
|
||||
path = "libvulkan.so.1";
|
||||
_this->vulkan_config.loader_handle = SDL_LoadObject(path);
|
||||
if(!_this->vulkan_config.loader_handle)
|
||||
return -1;
|
||||
SDL_strlcpy(_this->vulkan_config.loader_path, path,
|
||||
SDL_arraysize(_this->vulkan_config.loader_path));
|
||||
vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
|
||||
_this->vulkan_config.loader_handle, "vkGetInstanceProcAddr");
|
||||
if(!vkGetInstanceProcAddr)
|
||||
goto fail;
|
||||
_this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr;
|
||||
_this->vulkan_config.vkEnumerateInstanceExtensionProperties =
|
||||
(void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)(
|
||||
VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
|
||||
if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties)
|
||||
goto fail;
|
||||
extensions = SDL_Vulkan_CreateInstanceExtensionsList(
|
||||
(PFN_vkEnumerateInstanceExtensionProperties)
|
||||
_this->vulkan_config.vkEnumerateInstanceExtensionProperties,
|
||||
&extensionCount);
|
||||
if(!extensions)
|
||||
goto fail;
|
||||
for(i = 0; i < extensionCount; i++)
|
||||
{
|
||||
if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
|
||||
hasSurfaceExtension = SDL_TRUE;
|
||||
else if(SDL_strcmp(VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0)
|
||||
hasDirectFBSurfaceExtension = SDL_TRUE;
|
||||
}
|
||||
SDL_free(extensions);
|
||||
if(!hasSurfaceExtension)
|
||||
{
|
||||
SDL_SetError("Installed Vulkan doesn't implement the "
|
||||
VK_KHR_SURFACE_EXTENSION_NAME " extension");
|
||||
goto fail;
|
||||
}
|
||||
else if(!hasDirectFBSurfaceExtension)
|
||||
{
|
||||
SDL_SetError("Installed Vulkan doesn't implement the "
|
||||
VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME "extension");
|
||||
goto fail;
|
||||
}
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
SDL_UnloadObject(_this->vulkan_config.loader_handle);
|
||||
_this->vulkan_config.loader_handle = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void DirectFB_Vulkan_UnloadLibrary(_THIS)
|
||||
{
|
||||
if(_this->vulkan_config.loader_handle)
|
||||
{
|
||||
SDL_UnloadObject(_this->vulkan_config.loader_handle);
|
||||
_this->vulkan_config.loader_handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_bool DirectFB_Vulkan_GetInstanceExtensions(_THIS,
|
||||
SDL_Window *window,
|
||||
unsigned *count,
|
||||
const char **names)
|
||||
{
|
||||
static const char *const extensionsForDirectFB[] = {
|
||||
VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME
|
||||
};
|
||||
if(!_this->vulkan_config.loader_handle)
|
||||
{
|
||||
SDL_SetError("Vulkan is not loaded");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
return SDL_Vulkan_GetInstanceExtensions_Helper(
|
||||
count, names, SDL_arraysize(extensionsForDirectFB),
|
||||
extensionsForDirectFB);
|
||||
}
|
||||
|
||||
SDL_bool DirectFB_Vulkan_CreateSurface(_THIS,
|
||||
SDL_Window *window,
|
||||
VkInstance instance,
|
||||
VkSurfaceKHR *surface)
|
||||
{
|
||||
SDL_DFB_DEVICEDATA(_this);
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
|
||||
(PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
|
||||
PFN_vkCreateDirectFBSurfaceEXT vkCreateDirectFBSurfaceEXT =
|
||||
(PFN_vkCreateDirectFBSurfaceEXT)vkGetInstanceProcAddr(
|
||||
instance,
|
||||
"vkCreateDirectFBSurfaceEXT");
|
||||
VkDirectFBSurfaceCreateInfoEXT createInfo;
|
||||
VkResult result;
|
||||
|
||||
if(!_this->vulkan_config.loader_handle)
|
||||
{
|
||||
SDL_SetError("Vulkan is not loaded");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if(!vkCreateDirectFBSurfaceEXT)
|
||||
{
|
||||
SDL_SetError(VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME
|
||||
" extension is not enabled in the Vulkan instance.");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
SDL_zero(createInfo);
|
||||
createInfo.sType = VK_STRUCTURE_TYPE_DIRECTFB_SURFACE_CREATE_INFO_EXT;
|
||||
createInfo.pNext = NULL;
|
||||
createInfo.flags = 0;
|
||||
createInfo.dfb = devdata->dfb;
|
||||
createInfo.surface = windata->surface;
|
||||
result = vkCreateDirectFBSurfaceEXT(instance, &createInfo,
|
||||
NULL, surface);
|
||||
if(result != VK_SUCCESS)
|
||||
{
|
||||
SDL_SetError("vkCreateDirectFBSurfaceEXT failed: %s",
|
||||
SDL_Vulkan_GetResultString(result));
|
||||
return SDL_FALSE;
|
||||
}
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* vim: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifndef SDL_DirectFB_vulkan_h_
|
||||
#define SDL_DirectFB_vulkan_h_
|
||||
|
||||
#include "../SDL_vulkan_internal.h"
|
||||
#include "../SDL_sysvideo.h"
|
||||
|
||||
#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_DIRECTFB
|
||||
|
||||
int DirectFB_Vulkan_LoadLibrary(_THIS, const char *path);
|
||||
void DirectFB_Vulkan_UnloadLibrary(_THIS);
|
||||
SDL_bool DirectFB_Vulkan_GetInstanceExtensions(_THIS,
|
||||
SDL_Window *window,
|
||||
unsigned *count,
|
||||
const char **names);
|
||||
SDL_bool DirectFB_Vulkan_CreateSurface(_THIS,
|
||||
SDL_Window *window,
|
||||
VkInstance instance,
|
||||
VkSurfaceKHR *surface);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SDL_DirectFB_vulkan_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,565 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_DIRECTFB
|
||||
|
||||
#include "SDL_DirectFB_video.h"
|
||||
#include "SDL_DirectFB_modes.h"
|
||||
#include "SDL_DirectFB_window.h"
|
||||
#include "SDL_DirectFB_shape.h"
|
||||
|
||||
#if SDL_DIRECTFB_OPENGL
|
||||
#include "SDL_DirectFB_opengl.h"
|
||||
#endif
|
||||
|
||||
#include "SDL_syswm.h"
|
||||
|
||||
#include "../SDL_pixels_c.h"
|
||||
|
||||
int
|
||||
DirectFB_CreateWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_DFB_DEVICEDATA(_this);
|
||||
SDL_DFB_DISPLAYDATA(window);
|
||||
DFB_WindowData *windata = NULL;
|
||||
DFBWindowOptions wopts;
|
||||
DFBWindowDescription desc;
|
||||
int x, y;
|
||||
int bshaped = 0;
|
||||
|
||||
SDL_DFB_ALLOC_CLEAR(window->driverdata, sizeof(DFB_WindowData));
|
||||
SDL_memset(&desc, 0, sizeof(DFBWindowDescription));
|
||||
windata = (DFB_WindowData *) window->driverdata;
|
||||
|
||||
windata->is_managed = devdata->has_own_wm;
|
||||
#if 1
|
||||
SDL_DFB_CHECKERR(devdata->dfb->SetCooperativeLevel(devdata->dfb,
|
||||
DFSCL_NORMAL));
|
||||
SDL_DFB_CHECKERR(dispdata->layer->SetCooperativeLevel(dispdata->layer,
|
||||
DLSCL_ADMINISTRATIVE));
|
||||
#endif
|
||||
/* FIXME ... ughh, ugly */
|
||||
if (window->x == -1000 && window->y == -1000)
|
||||
bshaped = 1;
|
||||
|
||||
/* Fill the window description. */
|
||||
x = window->x;
|
||||
y = window->y;
|
||||
|
||||
DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
|
||||
|
||||
/* Create Window */
|
||||
desc.caps = 0;
|
||||
desc.flags =
|
||||
DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_POSX | DWDESC_POSY | DWDESC_SURFACE_CAPS;
|
||||
|
||||
if (bshaped) {
|
||||
desc.flags |= DWDESC_CAPS;
|
||||
desc.caps |= DWCAPS_ALPHACHANNEL;
|
||||
}
|
||||
else
|
||||
{
|
||||
desc.flags |= DWDESC_PIXELFORMAT;
|
||||
}
|
||||
|
||||
if (!(window->flags & SDL_WINDOW_BORDERLESS))
|
||||
desc.caps |= DWCAPS_NODECORATION;
|
||||
|
||||
desc.posx = x;
|
||||
desc.posy = y;
|
||||
desc.width = windata->size.w;
|
||||
desc.height = windata->size.h;
|
||||
desc.pixelformat = dispdata->pixelformat;
|
||||
desc.surface_caps = DSCAPS_PREMULTIPLIED;
|
||||
#if DIRECTFB_MAJOR_VERSION == 1 && DIRECTFB_MINOR_VERSION >= 6
|
||||
if (window->flags & SDL_WINDOW_OPENGL) {
|
||||
desc.surface_caps |= DSCAPS_GL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Create the window. */
|
||||
SDL_DFB_CHECKERR(dispdata->layer->CreateWindow(dispdata->layer, &desc,
|
||||
&windata->dfbwin));
|
||||
|
||||
/* Set Options */
|
||||
SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
|
||||
|
||||
/* explicit rescaling of surface */
|
||||
wopts |= DWOP_SCALE;
|
||||
if (window->flags & SDL_WINDOW_RESIZABLE) {
|
||||
wopts &= ~DWOP_KEEP_SIZE;
|
||||
}
|
||||
else {
|
||||
wopts |= DWOP_KEEP_SIZE;
|
||||
}
|
||||
|
||||
if (window->flags & SDL_WINDOW_FULLSCREEN) {
|
||||
wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_STACKING | DWOP_KEEP_SIZE;
|
||||
SDL_DFB_CHECK(windata->dfbwin->SetStackingClass(windata->dfbwin, DWSC_UPPER));
|
||||
}
|
||||
|
||||
if (bshaped) {
|
||||
wopts |= DWOP_SHAPED | DWOP_ALPHACHANNEL;
|
||||
wopts &= ~DWOP_OPAQUE_REGION;
|
||||
}
|
||||
|
||||
SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
|
||||
|
||||
/* See what we got */
|
||||
SDL_DFB_CHECK(DirectFB_WM_GetClientSize
|
||||
(_this, window, &window->w, &window->h));
|
||||
|
||||
/* Get the window's surface. */
|
||||
SDL_DFB_CHECKERR(windata->dfbwin->GetSurface(windata->dfbwin,
|
||||
&windata->window_surface));
|
||||
|
||||
/* And get a subsurface for rendering */
|
||||
SDL_DFB_CHECKERR(windata->window_surface->
|
||||
GetSubSurface(windata->window_surface, &windata->client,
|
||||
&windata->surface));
|
||||
|
||||
SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0xFF));
|
||||
|
||||
/* Create Eventbuffer */
|
||||
|
||||
SDL_DFB_CHECKERR(windata->dfbwin->CreateEventBuffer(windata->dfbwin,
|
||||
&windata->
|
||||
eventbuffer));
|
||||
SDL_DFB_CHECKERR(windata->dfbwin->
|
||||
EnableEvents(windata->dfbwin, DWET_ALL));
|
||||
|
||||
/* Create a font */
|
||||
/* FIXME: once during Video_Init */
|
||||
windata->font = NULL;
|
||||
|
||||
/* Make it the top most window. */
|
||||
SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin));
|
||||
|
||||
/* remember parent */
|
||||
/* windata->sdlwin = window; */
|
||||
|
||||
/* Add to list ... */
|
||||
|
||||
windata->next = devdata->firstwin;
|
||||
windata->opacity = 0xFF;
|
||||
devdata->firstwin = window;
|
||||
|
||||
/* Draw Frame */
|
||||
DirectFB_WM_RedrawLayout(_this, window);
|
||||
|
||||
return 0;
|
||||
error:
|
||||
SDL_DFB_RELEASE(windata->surface);
|
||||
SDL_DFB_RELEASE(windata->dfbwin);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DirectFB_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_SetWindowTitle(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
|
||||
if (windata->is_managed) {
|
||||
windata->wm_needs_redraw = 1;
|
||||
DirectFB_WM_RedrawLayout(_this, window);
|
||||
} else {
|
||||
SDL_Unsupported();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
|
||||
{
|
||||
SDL_DFB_DEVICEDATA(_this);
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
SDL_Surface *surface = NULL;
|
||||
|
||||
if (icon) {
|
||||
SDL_PixelFormat format;
|
||||
DFBSurfaceDescription dsc;
|
||||
Uint32 *dest;
|
||||
Uint32 *p;
|
||||
int pitch, i;
|
||||
|
||||
/* Convert the icon to ARGB for modern window managers */
|
||||
SDL_InitFormat(&format, SDL_PIXELFORMAT_ARGB8888);
|
||||
surface = SDL_ConvertSurface(icon, &format, 0);
|
||||
if (!surface) {
|
||||
return;
|
||||
}
|
||||
dsc.flags =
|
||||
DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
|
||||
dsc.caps = DSCAPS_VIDEOONLY;
|
||||
dsc.width = surface->w;
|
||||
dsc.height = surface->h;
|
||||
dsc.pixelformat = DSPF_ARGB;
|
||||
|
||||
SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
|
||||
&windata->icon));
|
||||
|
||||
SDL_DFB_CHECKERR(windata->icon->Lock(windata->icon, DSLF_WRITE,
|
||||
(void *) &dest, &pitch));
|
||||
|
||||
p = surface->pixels;
|
||||
for (i = 0; i < surface->h; i++)
|
||||
SDL_memcpy((char *) dest + i * pitch,
|
||||
(char *) p + i * surface->pitch, 4 * surface->w);
|
||||
|
||||
SDL_DFB_CHECK(windata->icon->Unlock(windata->icon));
|
||||
SDL_FreeSurface(surface);
|
||||
} else {
|
||||
SDL_DFB_RELEASE(windata->icon);
|
||||
}
|
||||
return;
|
||||
error:
|
||||
SDL_FreeSurface(surface);
|
||||
SDL_DFB_RELEASE(windata->icon);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_SetWindowPosition(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
int x, y;
|
||||
|
||||
x = window->x;
|
||||
y = window->y;
|
||||
|
||||
DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
|
||||
SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, x, y));
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_SetWindowSize(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
|
||||
if(SDL_IsShapedWindow(window))
|
||||
DirectFB_ResizeWindowShape(window);
|
||||
|
||||
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
|
||||
int cw;
|
||||
int ch;
|
||||
|
||||
/* Make sure all events are disabled for this operation ! */
|
||||
SDL_DFB_CHECKERR(windata->dfbwin->DisableEvents(windata->dfbwin,
|
||||
DWET_ALL));
|
||||
SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize(_this, window, &cw, &ch));
|
||||
|
||||
if (cw != window->w || ch != window->h) {
|
||||
|
||||
DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
|
||||
SDL_DFB_CHECKERR(windata->dfbwin->Resize(windata->dfbwin,
|
||||
windata->size.w,
|
||||
windata->size.h));
|
||||
}
|
||||
|
||||
SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize
|
||||
(_this, window, &window->w, &window->h));
|
||||
DirectFB_AdjustWindowSurface(window);
|
||||
|
||||
SDL_DFB_CHECKERR(windata->dfbwin->EnableEvents(windata->dfbwin,
|
||||
DWET_ALL));
|
||||
|
||||
}
|
||||
return;
|
||||
error:
|
||||
SDL_DFB_CHECK(windata->dfbwin->EnableEvents(windata->dfbwin, DWET_ALL));
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_ShowWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
|
||||
SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, windata->opacity));
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_HideWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
|
||||
SDL_DFB_CHECK(windata->dfbwin->GetOpacity(windata->dfbwin, &windata->opacity));
|
||||
SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0));
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_RaiseWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
|
||||
SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin));
|
||||
SDL_DFB_CHECK(windata->dfbwin->RequestFocus(windata->dfbwin));
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_MaximizeWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
|
||||
DFBWindowOptions wopts;
|
||||
|
||||
SDL_DFB_CHECK(windata->dfbwin->GetPosition(windata->dfbwin,
|
||||
&windata->restore.x, &windata->restore.y));
|
||||
SDL_DFB_CHECK(windata->dfbwin->GetSize(windata->dfbwin, &windata->restore.w,
|
||||
&windata->restore.h));
|
||||
|
||||
DirectFB_WM_AdjustWindowLayout(window, window->flags | SDL_WINDOW_MAXIMIZED, display->current_mode.w, display->current_mode.h) ;
|
||||
|
||||
SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, 0, 0));
|
||||
SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin,
|
||||
display->current_mode.w, display->current_mode.h));
|
||||
|
||||
/* Set Options */
|
||||
SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
|
||||
wopts |= DWOP_KEEP_SIZE | DWOP_KEEP_POSITION;
|
||||
SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_MinimizeWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
/* FIXME: Size to 32x32 ? */
|
||||
|
||||
SDL_Unsupported();
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_RestoreWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
DFBWindowOptions wopts;
|
||||
|
||||
/* Set Options */
|
||||
SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
|
||||
wopts &= ~(DWOP_KEEP_SIZE | DWOP_KEEP_POSITION);
|
||||
SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
|
||||
|
||||
/* Window layout */
|
||||
DirectFB_WM_AdjustWindowLayout(window, window->flags & ~(SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED),
|
||||
windata->restore.w, windata->restore.h);
|
||||
SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin, windata->restore.w,
|
||||
windata->restore.h));
|
||||
SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, windata->restore.x,
|
||||
windata->restore.y));
|
||||
|
||||
if (!(window->flags & SDL_WINDOW_RESIZABLE))
|
||||
wopts |= DWOP_KEEP_SIZE;
|
||||
|
||||
if (window->flags & SDL_WINDOW_FULLSCREEN)
|
||||
wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_SIZE;
|
||||
SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
|
||||
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
|
||||
{
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
|
||||
if (grabbed) {
|
||||
SDL_DFB_CHECK(windata->dfbwin->GrabPointer(windata->dfbwin));
|
||||
} else {
|
||||
SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
|
||||
{
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
|
||||
if (grabbed) {
|
||||
SDL_DFB_CHECK(windata->dfbwin->GrabKeyboard(windata->dfbwin));
|
||||
} else {
|
||||
SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_DestroyWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_DFB_DEVICEDATA(_this);
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
DFB_WindowData *p;
|
||||
|
||||
/* Some cleanups */
|
||||
SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin));
|
||||
SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin));
|
||||
|
||||
#if SDL_DIRECTFB_OPENGL
|
||||
DirectFB_GL_DestroyWindowContexts(_this, window);
|
||||
#endif
|
||||
|
||||
if (window->shaper)
|
||||
{
|
||||
SDL_ShapeData *data = window->shaper->driverdata;
|
||||
SDL_DFB_CHECK(data->surface->ReleaseSource(data->surface));
|
||||
SDL_DFB_RELEASE(data->surface);
|
||||
SDL_DFB_FREE(data);
|
||||
SDL_DFB_FREE(window->shaper);
|
||||
}
|
||||
|
||||
SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, NULL));
|
||||
SDL_DFB_CHECK(windata->surface->ReleaseSource(windata->surface));
|
||||
SDL_DFB_CHECK(windata->window_surface->ReleaseSource(windata->window_surface));
|
||||
SDL_DFB_RELEASE(windata->icon);
|
||||
SDL_DFB_RELEASE(windata->font);
|
||||
SDL_DFB_RELEASE(windata->eventbuffer);
|
||||
SDL_DFB_RELEASE(windata->surface);
|
||||
SDL_DFB_RELEASE(windata->window_surface);
|
||||
|
||||
SDL_DFB_RELEASE(windata->dfbwin);
|
||||
|
||||
/* Remove from list ... */
|
||||
|
||||
p = devdata->firstwin->driverdata;
|
||||
|
||||
while (p && p->next != window)
|
||||
p = (p->next ? p->next->driverdata : NULL);
|
||||
if (p)
|
||||
p->next = windata->next;
|
||||
else
|
||||
devdata->firstwin = windata->next;
|
||||
SDL_free(windata);
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window,
|
||||
struct SDL_SysWMinfo * info)
|
||||
{
|
||||
const Uint32 version = ((((Uint32) info->version.major) * 1000000) +
|
||||
(((Uint32) info->version.minor) * 10000) +
|
||||
(((Uint32) info->version.patch)));
|
||||
|
||||
SDL_DFB_DEVICEDATA(_this);
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
|
||||
/* Before 2.0.6, it was possible to build an SDL with DirectFB support
|
||||
(SDL_SysWMinfo will be large enough to hold DirectFB info), but build
|
||||
your app against SDL headers that didn't have DirectFB support
|
||||
(SDL_SysWMinfo could be smaller than DirectFB needs. This would lead
|
||||
to an app properly using SDL_GetWindowWMInfo() but we'd accidentally
|
||||
overflow memory on the stack or heap. To protect against this, we've
|
||||
padded out the struct unconditionally in the headers and DirectFB will
|
||||
just return an error for older apps using this function. Those apps
|
||||
will need to be recompiled against newer headers or not use DirectFB,
|
||||
maybe by forcing SDL_VIDEODRIVER=x11. */
|
||||
if (version < 2000006) {
|
||||
info->subsystem = SDL_SYSWM_UNKNOWN;
|
||||
SDL_SetError("Version must be 2.0.6 or newer");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (info->version.major == SDL_MAJOR_VERSION) {
|
||||
info->subsystem = SDL_SYSWM_DIRECTFB;
|
||||
info->info.dfb.dfb = devdata->dfb;
|
||||
info->info.dfb.window = windata->dfbwin;
|
||||
info->info.dfb.surface = windata->surface;
|
||||
return SDL_TRUE;
|
||||
} else {
|
||||
SDL_SetError("Application not compiled with SDL %d",
|
||||
SDL_MAJOR_VERSION);
|
||||
return SDL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DirectFB_AdjustWindowSurface(SDL_Window * window)
|
||||
{
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
int adjust = windata->wm_needs_redraw;
|
||||
int cw, ch;
|
||||
|
||||
DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
|
||||
|
||||
SDL_DFB_CHECKERR(windata->
|
||||
window_surface->GetSize(windata->window_surface, &cw,
|
||||
&ch));
|
||||
if (cw != windata->size.w || ch != windata->size.h) {
|
||||
adjust = 1;
|
||||
}
|
||||
|
||||
if (adjust) {
|
||||
#if SDL_DIRECTFB_OPENGL
|
||||
DirectFB_GL_FreeWindowContexts(SDL_GetVideoDevice(), window);
|
||||
#endif
|
||||
|
||||
#if (DFB_VERSION_ATLEAST(1,2,1))
|
||||
SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin,
|
||||
windata->size.w,
|
||||
windata->size.h));
|
||||
SDL_DFB_CHECKERR(windata->surface->MakeSubSurface(windata->surface,
|
||||
windata->
|
||||
window_surface,
|
||||
&windata->client));
|
||||
#else
|
||||
DFBWindowOptions opts;
|
||||
|
||||
SDL_DFB_CHECKERR(windata->dfbwin->GetOptions(windata->dfbwin, &opts));
|
||||
/* recreate subsurface */
|
||||
SDL_DFB_RELEASE(windata->surface);
|
||||
|
||||
if (opts & DWOP_SCALE)
|
||||
SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin,
|
||||
windata->size.w,
|
||||
windata->size.h));
|
||||
SDL_DFB_CHECKERR(windata->window_surface->
|
||||
GetSubSurface(windata->window_surface,
|
||||
&windata->client, &windata->surface));
|
||||
#endif
|
||||
DirectFB_WM_RedrawLayout(SDL_GetVideoDevice(), window);
|
||||
|
||||
#if SDL_DIRECTFB_OPENGL
|
||||
DirectFB_GL_ReAllocWindowContexts(SDL_GetVideoDevice(), window);
|
||||
#endif
|
||||
}
|
||||
error:
|
||||
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 */
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_directfb_window_h_
|
||||
#define SDL_directfb_window_h_
|
||||
|
||||
#include "SDL_DirectFB_video.h"
|
||||
#include "SDL_DirectFB_WM.h"
|
||||
|
||||
#define SDL_DFB_WINDOWDATA(win) DFB_WindowData *windata = ((win) ? (DFB_WindowData *) ((win)->driverdata) : NULL)
|
||||
|
||||
typedef struct _DFB_WindowData DFB_WindowData;
|
||||
struct _DFB_WindowData
|
||||
{
|
||||
IDirectFBSurface *window_surface; /* window surface */
|
||||
IDirectFBSurface *surface; /* client drawing surface */
|
||||
IDirectFBWindow *dfbwin;
|
||||
IDirectFBEventBuffer *eventbuffer;
|
||||
/* SDL_Window *sdlwin; */
|
||||
SDL_Window *next;
|
||||
Uint8 opacity;
|
||||
DFBRectangle client;
|
||||
DFBDimension size;
|
||||
DFBRectangle restore;
|
||||
|
||||
/* WM extras */
|
||||
int is_managed;
|
||||
int wm_needs_redraw;
|
||||
IDirectFBSurface *icon;
|
||||
IDirectFBFont *font;
|
||||
DFB_Theme theme;
|
||||
|
||||
/* WM moving and sizing */
|
||||
int wm_grab;
|
||||
int wm_lastx;
|
||||
int wm_lasty;
|
||||
};
|
||||
|
||||
extern int DirectFB_CreateWindow(_THIS, SDL_Window * window);
|
||||
extern int DirectFB_CreateWindowFrom(_THIS, SDL_Window * window,
|
||||
const void *data);
|
||||
extern void DirectFB_SetWindowTitle(_THIS, SDL_Window * window);
|
||||
extern void DirectFB_SetWindowIcon(_THIS, SDL_Window * window,
|
||||
SDL_Surface * icon);
|
||||
|
||||
extern void DirectFB_SetWindowPosition(_THIS, SDL_Window * window);
|
||||
extern void DirectFB_SetWindowSize(_THIS, SDL_Window * window);
|
||||
extern void DirectFB_ShowWindow(_THIS, SDL_Window * window);
|
||||
extern void DirectFB_HideWindow(_THIS, SDL_Window * window);
|
||||
extern void DirectFB_RaiseWindow(_THIS, SDL_Window * window);
|
||||
extern void DirectFB_MaximizeWindow(_THIS, SDL_Window * window);
|
||||
extern void DirectFB_MinimizeWindow(_THIS, SDL_Window * window);
|
||||
extern void DirectFB_RestoreWindow(_THIS, SDL_Window * window);
|
||||
extern void DirectFB_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
|
||||
extern void DirectFB_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
|
||||
extern void DirectFB_DestroyWindow(_THIS, SDL_Window * window);
|
||||
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_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -25,6 +25,7 @@
|
||||
#if SDL_VIDEO_DRIVER_EMSCRIPTEN
|
||||
|
||||
#include <emscripten/html5.h>
|
||||
#include <emscripten/dom_pk_codes.h>
|
||||
|
||||
#include "../../events/SDL_events_c.h"
|
||||
#include "../../events/SDL_keyboard_c.h"
|
||||
@@ -38,237 +39,547 @@
|
||||
#define FULLSCREEN_MASK ( SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN )
|
||||
|
||||
/*
|
||||
.keyCode to scancode
|
||||
.keyCode to SDL keycode
|
||||
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent
|
||||
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
|
||||
*/
|
||||
static const SDL_Scancode emscripten_scancode_table[] = {
|
||||
/* 0 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 1 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 2 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 3 */ SDL_SCANCODE_CANCEL,
|
||||
/* 4 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 5 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 6 */ SDL_SCANCODE_HELP,
|
||||
/* 7 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 8 */ SDL_SCANCODE_BACKSPACE,
|
||||
/* 9 */ SDL_SCANCODE_TAB,
|
||||
/* 10 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 11 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 12 */ SDL_SCANCODE_KP_5,
|
||||
/* 13 */ SDL_SCANCODE_RETURN,
|
||||
/* 14 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 15 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 16 */ SDL_SCANCODE_LSHIFT,
|
||||
/* 17 */ SDL_SCANCODE_LCTRL,
|
||||
/* 18 */ SDL_SCANCODE_LALT,
|
||||
/* 19 */ SDL_SCANCODE_PAUSE,
|
||||
/* 20 */ SDL_SCANCODE_CAPSLOCK,
|
||||
/* 21 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 22 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 23 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 24 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 25 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 26 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 27 */ SDL_SCANCODE_ESCAPE,
|
||||
/* 28 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 29 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 30 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 31 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 32 */ SDL_SCANCODE_SPACE,
|
||||
/* 33 */ SDL_SCANCODE_PAGEUP,
|
||||
/* 34 */ SDL_SCANCODE_PAGEDOWN,
|
||||
/* 35 */ SDL_SCANCODE_END,
|
||||
/* 36 */ SDL_SCANCODE_HOME,
|
||||
/* 37 */ SDL_SCANCODE_LEFT,
|
||||
/* 38 */ SDL_SCANCODE_UP,
|
||||
/* 39 */ SDL_SCANCODE_RIGHT,
|
||||
/* 40 */ SDL_SCANCODE_DOWN,
|
||||
/* 41 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 42 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 43 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 44 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 45 */ SDL_SCANCODE_INSERT,
|
||||
/* 46 */ SDL_SCANCODE_DELETE,
|
||||
/* 47 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 48 */ SDL_SCANCODE_0,
|
||||
/* 49 */ SDL_SCANCODE_1,
|
||||
/* 50 */ SDL_SCANCODE_2,
|
||||
/* 51 */ SDL_SCANCODE_3,
|
||||
/* 52 */ SDL_SCANCODE_4,
|
||||
/* 53 */ SDL_SCANCODE_5,
|
||||
/* 54 */ SDL_SCANCODE_6,
|
||||
/* 55 */ SDL_SCANCODE_7,
|
||||
/* 56 */ SDL_SCANCODE_8,
|
||||
/* 57 */ SDL_SCANCODE_9,
|
||||
/* 58 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 59 */ SDL_SCANCODE_SEMICOLON,
|
||||
/* 60 */ SDL_SCANCODE_NONUSBACKSLASH,
|
||||
/* 61 */ SDL_SCANCODE_EQUALS,
|
||||
/* 62 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 63 */ SDL_SCANCODE_MINUS,
|
||||
/* 64 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 65 */ SDL_SCANCODE_A,
|
||||
/* 66 */ SDL_SCANCODE_B,
|
||||
/* 67 */ SDL_SCANCODE_C,
|
||||
/* 68 */ SDL_SCANCODE_D,
|
||||
/* 69 */ SDL_SCANCODE_E,
|
||||
/* 70 */ SDL_SCANCODE_F,
|
||||
/* 71 */ SDL_SCANCODE_G,
|
||||
/* 72 */ SDL_SCANCODE_H,
|
||||
/* 73 */ SDL_SCANCODE_I,
|
||||
/* 74 */ SDL_SCANCODE_J,
|
||||
/* 75 */ SDL_SCANCODE_K,
|
||||
/* 76 */ SDL_SCANCODE_L,
|
||||
/* 77 */ SDL_SCANCODE_M,
|
||||
/* 78 */ SDL_SCANCODE_N,
|
||||
/* 79 */ SDL_SCANCODE_O,
|
||||
/* 80 */ SDL_SCANCODE_P,
|
||||
/* 81 */ SDL_SCANCODE_Q,
|
||||
/* 82 */ SDL_SCANCODE_R,
|
||||
/* 83 */ SDL_SCANCODE_S,
|
||||
/* 84 */ SDL_SCANCODE_T,
|
||||
/* 85 */ SDL_SCANCODE_U,
|
||||
/* 86 */ SDL_SCANCODE_V,
|
||||
/* 87 */ SDL_SCANCODE_W,
|
||||
/* 88 */ SDL_SCANCODE_X,
|
||||
/* 89 */ SDL_SCANCODE_Y,
|
||||
/* 90 */ SDL_SCANCODE_Z,
|
||||
/* 91 */ SDL_SCANCODE_LGUI,
|
||||
/* 92 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 93 */ SDL_SCANCODE_APPLICATION,
|
||||
/* 94 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 95 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 96 */ SDL_SCANCODE_KP_0,
|
||||
/* 97 */ SDL_SCANCODE_KP_1,
|
||||
/* 98 */ SDL_SCANCODE_KP_2,
|
||||
/* 99 */ SDL_SCANCODE_KP_3,
|
||||
/* 100 */ SDL_SCANCODE_KP_4,
|
||||
/* 101 */ SDL_SCANCODE_KP_5,
|
||||
/* 102 */ SDL_SCANCODE_KP_6,
|
||||
/* 103 */ SDL_SCANCODE_KP_7,
|
||||
/* 104 */ SDL_SCANCODE_KP_8,
|
||||
/* 105 */ SDL_SCANCODE_KP_9,
|
||||
/* 106 */ SDL_SCANCODE_KP_MULTIPLY,
|
||||
/* 107 */ SDL_SCANCODE_KP_PLUS,
|
||||
/* 108 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 109 */ SDL_SCANCODE_KP_MINUS,
|
||||
/* 110 */ SDL_SCANCODE_KP_PERIOD,
|
||||
/* 111 */ SDL_SCANCODE_KP_DIVIDE,
|
||||
/* 112 */ SDL_SCANCODE_F1,
|
||||
/* 113 */ SDL_SCANCODE_F2,
|
||||
/* 114 */ SDL_SCANCODE_F3,
|
||||
/* 115 */ SDL_SCANCODE_F4,
|
||||
/* 116 */ SDL_SCANCODE_F5,
|
||||
/* 117 */ SDL_SCANCODE_F6,
|
||||
/* 118 */ SDL_SCANCODE_F7,
|
||||
/* 119 */ SDL_SCANCODE_F8,
|
||||
/* 120 */ SDL_SCANCODE_F9,
|
||||
/* 121 */ SDL_SCANCODE_F10,
|
||||
/* 122 */ SDL_SCANCODE_F11,
|
||||
/* 123 */ SDL_SCANCODE_F12,
|
||||
/* 124 */ SDL_SCANCODE_F13,
|
||||
/* 125 */ SDL_SCANCODE_F14,
|
||||
/* 126 */ SDL_SCANCODE_F15,
|
||||
/* 127 */ SDL_SCANCODE_F16,
|
||||
/* 128 */ SDL_SCANCODE_F17,
|
||||
/* 129 */ SDL_SCANCODE_F18,
|
||||
/* 130 */ SDL_SCANCODE_F19,
|
||||
/* 131 */ SDL_SCANCODE_F20,
|
||||
/* 132 */ SDL_SCANCODE_F21,
|
||||
/* 133 */ SDL_SCANCODE_F22,
|
||||
/* 134 */ SDL_SCANCODE_F23,
|
||||
/* 135 */ SDL_SCANCODE_F24,
|
||||
/* 136 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 137 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 138 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 139 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 140 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 141 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 142 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 143 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 144 */ SDL_SCANCODE_NUMLOCKCLEAR,
|
||||
/* 145 */ SDL_SCANCODE_SCROLLLOCK,
|
||||
/* 146 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 147 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 148 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 149 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 150 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 151 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 152 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 153 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 154 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 155 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 156 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 157 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 158 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 159 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 160 */ SDL_SCANCODE_GRAVE,
|
||||
/* 161 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 162 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 163 */ SDL_SCANCODE_KP_HASH, /*KaiOS phone keypad*/
|
||||
/* 164 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 165 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 166 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 167 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 168 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 169 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 170 */ SDL_SCANCODE_KP_MULTIPLY, /*KaiOS phone keypad*/
|
||||
/* 171 */ SDL_SCANCODE_RIGHTBRACKET,
|
||||
/* 172 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 173 */ SDL_SCANCODE_MINUS, /*FX*/
|
||||
/* 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_AUDIOPLAY, /*IE, Chrome*/
|
||||
/* 180 */ 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*/
|
||||
/* 187 */ SDL_SCANCODE_EQUALS, /*IE, Chrome, D3E legacy*/
|
||||
/* 188 */ SDL_SCANCODE_COMMA,
|
||||
/* 189 */ SDL_SCANCODE_MINUS, /*IE, Chrome, D3E legacy*/
|
||||
/* 190 */ SDL_SCANCODE_PERIOD,
|
||||
/* 191 */ SDL_SCANCODE_SLASH,
|
||||
/* 192 */ SDL_SCANCODE_GRAVE, /*FX, D3E legacy (SDL_SCANCODE_APOSTROPHE in IE/Chrome)*/
|
||||
/* 193 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 194 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 195 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 196 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 197 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 198 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 199 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 200 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 201 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 202 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 203 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 204 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 205 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 206 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 207 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 208 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 209 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 210 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 211 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 212 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 213 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 214 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 215 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 216 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 217 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 218 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 219 */ SDL_SCANCODE_LEFTBRACKET,
|
||||
/* 220 */ SDL_SCANCODE_BACKSLASH,
|
||||
/* 221 */ SDL_SCANCODE_RIGHTBRACKET,
|
||||
/* 222 */ SDL_SCANCODE_APOSTROPHE, /*FX, D3E legacy*/
|
||||
static const SDL_Keycode emscripten_keycode_table[] = {
|
||||
/* 0 */ SDLK_UNKNOWN,
|
||||
/* 1 */ SDLK_UNKNOWN,
|
||||
/* 2 */ SDLK_UNKNOWN,
|
||||
/* 3 */ SDLK_CANCEL,
|
||||
/* 4 */ SDLK_UNKNOWN,
|
||||
/* 5 */ SDLK_UNKNOWN,
|
||||
/* 6 */ SDLK_HELP,
|
||||
/* 7 */ SDLK_UNKNOWN,
|
||||
/* 8 */ SDLK_BACKSPACE,
|
||||
/* 9 */ SDLK_TAB,
|
||||
/* 10 */ SDLK_UNKNOWN,
|
||||
/* 11 */ SDLK_UNKNOWN,
|
||||
/* 12 */ SDLK_KP_5,
|
||||
/* 13 */ SDLK_RETURN,
|
||||
/* 14 */ SDLK_UNKNOWN,
|
||||
/* 15 */ SDLK_UNKNOWN,
|
||||
/* 16 */ SDLK_LSHIFT,
|
||||
/* 17 */ SDLK_LCTRL,
|
||||
/* 18 */ SDLK_LALT,
|
||||
/* 19 */ SDLK_PAUSE,
|
||||
/* 20 */ SDLK_CAPSLOCK,
|
||||
/* 21 */ SDLK_UNKNOWN,
|
||||
/* 22 */ SDLK_UNKNOWN,
|
||||
/* 23 */ SDLK_UNKNOWN,
|
||||
/* 24 */ SDLK_UNKNOWN,
|
||||
/* 25 */ SDLK_UNKNOWN,
|
||||
/* 26 */ SDLK_UNKNOWN,
|
||||
/* 27 */ SDLK_ESCAPE,
|
||||
/* 28 */ SDLK_UNKNOWN,
|
||||
/* 29 */ SDLK_UNKNOWN,
|
||||
/* 30 */ SDLK_UNKNOWN,
|
||||
/* 31 */ SDLK_UNKNOWN,
|
||||
/* 32 */ SDLK_SPACE,
|
||||
/* 33 */ SDLK_PAGEUP,
|
||||
/* 34 */ SDLK_PAGEDOWN,
|
||||
/* 35 */ SDLK_END,
|
||||
/* 36 */ SDLK_HOME,
|
||||
/* 37 */ SDLK_LEFT,
|
||||
/* 38 */ SDLK_UP,
|
||||
/* 39 */ SDLK_RIGHT,
|
||||
/* 40 */ SDLK_DOWN,
|
||||
/* 41 */ SDLK_UNKNOWN,
|
||||
/* 42 */ SDLK_UNKNOWN,
|
||||
/* 43 */ SDLK_UNKNOWN,
|
||||
/* 44 */ SDLK_UNKNOWN,
|
||||
/* 45 */ SDLK_INSERT,
|
||||
/* 46 */ SDLK_DELETE,
|
||||
/* 47 */ SDLK_UNKNOWN,
|
||||
/* 48 */ SDLK_0,
|
||||
/* 49 */ SDLK_1,
|
||||
/* 50 */ SDLK_2,
|
||||
/* 51 */ SDLK_3,
|
||||
/* 52 */ SDLK_4,
|
||||
/* 53 */ SDLK_5,
|
||||
/* 54 */ SDLK_6,
|
||||
/* 55 */ SDLK_7,
|
||||
/* 56 */ SDLK_8,
|
||||
/* 57 */ SDLK_9,
|
||||
/* 58 */ SDLK_UNKNOWN,
|
||||
/* 59 */ SDLK_SEMICOLON,
|
||||
/* 60 */ SDLK_BACKSLASH /*SDL_SCANCODE_NONUSBACKSLASH*/,
|
||||
/* 61 */ SDLK_EQUALS,
|
||||
/* 62 */ SDLK_UNKNOWN,
|
||||
/* 63 */ SDLK_MINUS,
|
||||
/* 64 */ SDLK_UNKNOWN,
|
||||
/* 65 */ SDLK_a,
|
||||
/* 66 */ SDLK_b,
|
||||
/* 67 */ SDLK_c,
|
||||
/* 68 */ SDLK_d,
|
||||
/* 69 */ SDLK_e,
|
||||
/* 70 */ SDLK_f,
|
||||
/* 71 */ SDLK_g,
|
||||
/* 72 */ SDLK_h,
|
||||
/* 73 */ SDLK_i,
|
||||
/* 74 */ SDLK_j,
|
||||
/* 75 */ SDLK_k,
|
||||
/* 76 */ SDLK_l,
|
||||
/* 77 */ SDLK_m,
|
||||
/* 78 */ SDLK_n,
|
||||
/* 79 */ SDLK_o,
|
||||
/* 80 */ SDLK_p,
|
||||
/* 81 */ SDLK_q,
|
||||
/* 82 */ SDLK_r,
|
||||
/* 83 */ SDLK_s,
|
||||
/* 84 */ SDLK_t,
|
||||
/* 85 */ SDLK_u,
|
||||
/* 86 */ SDLK_v,
|
||||
/* 87 */ SDLK_w,
|
||||
/* 88 */ SDLK_x,
|
||||
/* 89 */ SDLK_y,
|
||||
/* 90 */ SDLK_z,
|
||||
/* 91 */ SDLK_LGUI,
|
||||
/* 92 */ SDLK_UNKNOWN,
|
||||
/* 93 */ SDLK_APPLICATION,
|
||||
/* 94 */ SDLK_UNKNOWN,
|
||||
/* 95 */ SDLK_UNKNOWN,
|
||||
/* 96 */ SDLK_KP_0,
|
||||
/* 97 */ SDLK_KP_1,
|
||||
/* 98 */ SDLK_KP_2,
|
||||
/* 99 */ SDLK_KP_3,
|
||||
/* 100 */ SDLK_KP_4,
|
||||
/* 101 */ SDLK_KP_5,
|
||||
/* 102 */ SDLK_KP_6,
|
||||
/* 103 */ SDLK_KP_7,
|
||||
/* 104 */ SDLK_KP_8,
|
||||
/* 105 */ SDLK_KP_9,
|
||||
/* 106 */ SDLK_KP_MULTIPLY,
|
||||
/* 107 */ SDLK_KP_PLUS,
|
||||
/* 108 */ SDLK_UNKNOWN,
|
||||
/* 109 */ SDLK_KP_MINUS,
|
||||
/* 110 */ SDLK_KP_PERIOD,
|
||||
/* 111 */ SDLK_KP_DIVIDE,
|
||||
/* 112 */ SDLK_F1,
|
||||
/* 113 */ SDLK_F2,
|
||||
/* 114 */ SDLK_F3,
|
||||
/* 115 */ SDLK_F4,
|
||||
/* 116 */ SDLK_F5,
|
||||
/* 117 */ SDLK_F6,
|
||||
/* 118 */ SDLK_F7,
|
||||
/* 119 */ SDLK_F8,
|
||||
/* 120 */ SDLK_F9,
|
||||
/* 121 */ SDLK_F10,
|
||||
/* 122 */ SDLK_F11,
|
||||
/* 123 */ SDLK_F12,
|
||||
/* 124 */ SDLK_F13,
|
||||
/* 125 */ SDLK_F14,
|
||||
/* 126 */ SDLK_F15,
|
||||
/* 127 */ SDLK_F16,
|
||||
/* 128 */ SDLK_F17,
|
||||
/* 129 */ SDLK_F18,
|
||||
/* 130 */ SDLK_F19,
|
||||
/* 131 */ SDLK_F20,
|
||||
/* 132 */ SDLK_F21,
|
||||
/* 133 */ SDLK_F22,
|
||||
/* 134 */ SDLK_F23,
|
||||
/* 135 */ SDLK_F24,
|
||||
/* 136 */ SDLK_UNKNOWN,
|
||||
/* 137 */ SDLK_UNKNOWN,
|
||||
/* 138 */ SDLK_UNKNOWN,
|
||||
/* 139 */ SDLK_UNKNOWN,
|
||||
/* 140 */ SDLK_UNKNOWN,
|
||||
/* 141 */ SDLK_UNKNOWN,
|
||||
/* 142 */ SDLK_UNKNOWN,
|
||||
/* 143 */ SDLK_UNKNOWN,
|
||||
/* 144 */ SDLK_NUMLOCKCLEAR,
|
||||
/* 145 */ SDLK_SCROLLLOCK,
|
||||
/* 146 */ SDLK_UNKNOWN,
|
||||
/* 147 */ SDLK_UNKNOWN,
|
||||
/* 148 */ SDLK_UNKNOWN,
|
||||
/* 149 */ SDLK_UNKNOWN,
|
||||
/* 150 */ SDLK_UNKNOWN,
|
||||
/* 151 */ SDLK_UNKNOWN,
|
||||
/* 152 */ SDLK_UNKNOWN,
|
||||
/* 153 */ SDLK_UNKNOWN,
|
||||
/* 154 */ SDLK_UNKNOWN,
|
||||
/* 155 */ SDLK_UNKNOWN,
|
||||
/* 156 */ SDLK_UNKNOWN,
|
||||
/* 157 */ SDLK_UNKNOWN,
|
||||
/* 158 */ SDLK_UNKNOWN,
|
||||
/* 159 */ SDLK_UNKNOWN,
|
||||
/* 160 */ SDLK_BACKQUOTE,
|
||||
/* 161 */ SDLK_UNKNOWN,
|
||||
/* 162 */ SDLK_UNKNOWN,
|
||||
/* 163 */ SDLK_KP_HASH, /*KaiOS phone keypad*/
|
||||
/* 164 */ SDLK_UNKNOWN,
|
||||
/* 165 */ SDLK_UNKNOWN,
|
||||
/* 166 */ SDLK_UNKNOWN,
|
||||
/* 167 */ SDLK_UNKNOWN,
|
||||
/* 168 */ SDLK_UNKNOWN,
|
||||
/* 169 */ SDLK_UNKNOWN,
|
||||
/* 170 */ SDLK_KP_MULTIPLY, /*KaiOS phone keypad*/
|
||||
/* 171 */ SDLK_RIGHTBRACKET,
|
||||
/* 172 */ SDLK_UNKNOWN,
|
||||
/* 173 */ SDLK_MINUS, /*FX*/
|
||||
/* 174 */ SDLK_VOLUMEDOWN, /*IE, Chrome*/
|
||||
/* 175 */ SDLK_VOLUMEUP, /*IE, Chrome*/
|
||||
/* 176 */ SDLK_AUDIONEXT, /*IE, Chrome*/
|
||||
/* 177 */ SDLK_AUDIOPREV, /*IE, Chrome*/
|
||||
/* 178 */ SDLK_UNKNOWN,
|
||||
/* 179 */ SDLK_AUDIOPLAY, /*IE, Chrome*/
|
||||
/* 180 */ SDLK_UNKNOWN,
|
||||
/* 181 */ SDLK_AUDIOMUTE, /*FX*/
|
||||
/* 182 */ SDLK_VOLUMEDOWN, /*FX*/
|
||||
/* 183 */ SDLK_VOLUMEUP, /*FX*/
|
||||
/* 184 */ SDLK_UNKNOWN,
|
||||
/* 185 */ SDLK_UNKNOWN,
|
||||
/* 186 */ SDLK_SEMICOLON, /*IE, Chrome, D3E legacy*/
|
||||
/* 187 */ SDLK_EQUALS, /*IE, Chrome, D3E legacy*/
|
||||
/* 188 */ SDLK_COMMA,
|
||||
/* 189 */ SDLK_MINUS, /*IE, Chrome, D3E legacy*/
|
||||
/* 190 */ SDLK_PERIOD,
|
||||
/* 191 */ SDLK_SLASH,
|
||||
/* 192 */ SDLK_BACKQUOTE, /*FX, D3E legacy (SDLK_APOSTROPHE in IE/Chrome)*/
|
||||
/* 193 */ SDLK_UNKNOWN,
|
||||
/* 194 */ SDLK_UNKNOWN,
|
||||
/* 195 */ SDLK_UNKNOWN,
|
||||
/* 196 */ SDLK_UNKNOWN,
|
||||
/* 197 */ SDLK_UNKNOWN,
|
||||
/* 198 */ SDLK_UNKNOWN,
|
||||
/* 199 */ SDLK_UNKNOWN,
|
||||
/* 200 */ SDLK_UNKNOWN,
|
||||
/* 201 */ SDLK_UNKNOWN,
|
||||
/* 202 */ SDLK_UNKNOWN,
|
||||
/* 203 */ SDLK_UNKNOWN,
|
||||
/* 204 */ SDLK_UNKNOWN,
|
||||
/* 205 */ SDLK_UNKNOWN,
|
||||
/* 206 */ SDLK_UNKNOWN,
|
||||
/* 207 */ SDLK_UNKNOWN,
|
||||
/* 208 */ SDLK_UNKNOWN,
|
||||
/* 209 */ SDLK_UNKNOWN,
|
||||
/* 210 */ SDLK_UNKNOWN,
|
||||
/* 211 */ SDLK_UNKNOWN,
|
||||
/* 212 */ SDLK_UNKNOWN,
|
||||
/* 213 */ SDLK_UNKNOWN,
|
||||
/* 214 */ SDLK_UNKNOWN,
|
||||
/* 215 */ SDLK_UNKNOWN,
|
||||
/* 216 */ SDLK_UNKNOWN,
|
||||
/* 217 */ SDLK_UNKNOWN,
|
||||
/* 218 */ SDLK_UNKNOWN,
|
||||
/* 219 */ SDLK_LEFTBRACKET,
|
||||
/* 220 */ SDLK_BACKSLASH,
|
||||
/* 221 */ SDLK_RIGHTBRACKET,
|
||||
/* 222 */ SDLK_QUOTE, /*FX, D3E legacy*/
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Emscripten PK code to scancode
|
||||
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent
|
||||
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code
|
||||
*/
|
||||
static const SDL_Scancode emscripten_scancode_table[] = {
|
||||
/* 0x00 "Unidentified" */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 0x01 "Escape" */ SDL_SCANCODE_ESCAPE,
|
||||
/* 0x02 "Digit0" */ SDL_SCANCODE_0,
|
||||
/* 0x03 "Digit1" */ SDL_SCANCODE_1,
|
||||
/* 0x04 "Digit2" */ SDL_SCANCODE_2,
|
||||
/* 0x05 "Digit3" */ SDL_SCANCODE_3,
|
||||
/* 0x06 "Digit4" */ SDL_SCANCODE_4,
|
||||
/* 0x07 "Digit5" */ SDL_SCANCODE_5,
|
||||
/* 0x08 "Digit6" */ SDL_SCANCODE_6,
|
||||
/* 0x09 "Digit7" */ SDL_SCANCODE_7,
|
||||
/* 0x0A "Digit8" */ SDL_SCANCODE_8,
|
||||
/* 0x0B "Digit9" */ SDL_SCANCODE_9,
|
||||
/* 0x0C "Minus" */ SDL_SCANCODE_MINUS,
|
||||
/* 0x0D "Equal" */ SDL_SCANCODE_EQUALS,
|
||||
/* 0x0E "Backspace" */ SDL_SCANCODE_BACKSPACE,
|
||||
/* 0x0F "Tab" */ SDL_SCANCODE_TAB,
|
||||
/* 0x10 "KeyQ" */ SDL_SCANCODE_Q,
|
||||
/* 0x11 "KeyW" */ SDL_SCANCODE_W,
|
||||
/* 0x12 "KeyE" */ SDL_SCANCODE_E,
|
||||
/* 0x13 "KeyR" */ SDL_SCANCODE_R,
|
||||
/* 0x14 "KeyT" */ SDL_SCANCODE_T,
|
||||
/* 0x15 "KeyY" */ SDL_SCANCODE_Y,
|
||||
/* 0x16 "KeyU" */ SDL_SCANCODE_U,
|
||||
/* 0x17 "KeyI" */ SDL_SCANCODE_I,
|
||||
/* 0x18 "KeyO" */ SDL_SCANCODE_O,
|
||||
/* 0x19 "KeyP" */ SDL_SCANCODE_P,
|
||||
/* 0x1A "BracketLeft" */ SDL_SCANCODE_LEFTBRACKET,
|
||||
/* 0x1B "BracketRight" */ SDL_SCANCODE_RIGHTBRACKET,
|
||||
/* 0x1C "Enter" */ SDL_SCANCODE_RETURN,
|
||||
/* 0x1D "ControlLeft" */ SDL_SCANCODE_LCTRL,
|
||||
/* 0x1E "KeyA" */ SDL_SCANCODE_A,
|
||||
/* 0x1F "KeyS" */ SDL_SCANCODE_S,
|
||||
/* 0x20 "KeyD" */ SDL_SCANCODE_D,
|
||||
/* 0x21 "KeyF" */ SDL_SCANCODE_F,
|
||||
/* 0x22 "KeyG" */ SDL_SCANCODE_G,
|
||||
/* 0x23 "KeyH" */ SDL_SCANCODE_H,
|
||||
/* 0x24 "KeyJ" */ SDL_SCANCODE_J,
|
||||
/* 0x25 "KeyK" */ SDL_SCANCODE_K,
|
||||
/* 0x26 "KeyL" */ SDL_SCANCODE_L,
|
||||
/* 0x27 "Semicolon" */ SDL_SCANCODE_SEMICOLON,
|
||||
/* 0x28 "Quote" */ SDL_SCANCODE_APOSTROPHE,
|
||||
/* 0x29 "Backquote" */ SDL_SCANCODE_GRAVE,
|
||||
/* 0x2A "ShiftLeft" */ SDL_SCANCODE_LSHIFT,
|
||||
/* 0x2B "Backslash" */ SDL_SCANCODE_BACKSLASH,
|
||||
/* 0x2C "KeyZ" */ SDL_SCANCODE_Z,
|
||||
/* 0x2D "KeyX" */ SDL_SCANCODE_X,
|
||||
/* 0x2E "KeyC" */ SDL_SCANCODE_C,
|
||||
/* 0x2F "KeyV" */ SDL_SCANCODE_V,
|
||||
/* 0x30 "KeyB" */ SDL_SCANCODE_B,
|
||||
/* 0x31 "KeyN" */ SDL_SCANCODE_N,
|
||||
/* 0x32 "KeyM" */ SDL_SCANCODE_M,
|
||||
/* 0x33 "Comma" */ SDL_SCANCODE_COMMA,
|
||||
/* 0x34 "Period" */ SDL_SCANCODE_PERIOD,
|
||||
/* 0x35 "Slash" */ SDL_SCANCODE_SLASH,
|
||||
/* 0x36 "ShiftRight" */ SDL_SCANCODE_RSHIFT,
|
||||
/* 0x37 "NumpadMultiply" */ SDL_SCANCODE_KP_MULTIPLY,
|
||||
/* 0x38 "AltLeft" */ SDL_SCANCODE_LALT,
|
||||
/* 0x39 "Space" */ SDL_SCANCODE_SPACE,
|
||||
/* 0x3A "CapsLock" */ SDL_SCANCODE_CAPSLOCK,
|
||||
/* 0x3B "F1" */ SDL_SCANCODE_F1,
|
||||
/* 0x3C "F2" */ SDL_SCANCODE_F2,
|
||||
/* 0x3D "F3" */ SDL_SCANCODE_F3,
|
||||
/* 0x3E "F4" */ SDL_SCANCODE_F4,
|
||||
/* 0x3F "F5" */ SDL_SCANCODE_F5,
|
||||
/* 0x40 "F6" */ SDL_SCANCODE_F6,
|
||||
/* 0x41 "F7" */ SDL_SCANCODE_F7,
|
||||
/* 0x42 "F8" */ SDL_SCANCODE_F8,
|
||||
/* 0x43 "F9" */ SDL_SCANCODE_F9,
|
||||
/* 0x44 "F10" */ SDL_SCANCODE_F10,
|
||||
/* 0x45 "Pause" */ SDL_SCANCODE_PAUSE,
|
||||
/* 0x46 "ScrollLock" */ SDL_SCANCODE_SCROLLLOCK,
|
||||
/* 0x47 "Numpad7" */ SDL_SCANCODE_KP_7,
|
||||
/* 0x48 "Numpad8" */ SDL_SCANCODE_KP_8,
|
||||
/* 0x49 "Numpad9" */ SDL_SCANCODE_KP_9,
|
||||
/* 0x4A "NumpadSubtract" */ SDL_SCANCODE_KP_MINUS,
|
||||
/* 0x4B "Numpad4" */ SDL_SCANCODE_KP_4,
|
||||
/* 0x4C "Numpad5" */ SDL_SCANCODE_KP_5,
|
||||
/* 0x4D "Numpad6" */ SDL_SCANCODE_KP_6,
|
||||
/* 0x4E "NumpadAdd" */ SDL_SCANCODE_KP_PLUS,
|
||||
/* 0x4F "Numpad1" */ SDL_SCANCODE_KP_1,
|
||||
/* 0x50 "Numpad2" */ SDL_SCANCODE_KP_2,
|
||||
/* 0x51 "Numpad3" */ SDL_SCANCODE_KP_3,
|
||||
/* 0x52 "Numpad0" */ SDL_SCANCODE_KP_0,
|
||||
/* 0x53 "NumpadDecimal" */ SDL_SCANCODE_KP_PERIOD,
|
||||
/* 0x54 "PrintScreen" */ SDL_SCANCODE_PRINTSCREEN,
|
||||
/* 0x55 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 0x56 "IntlBackslash" */ SDL_SCANCODE_NONUSBACKSLASH,
|
||||
/* 0x57 "F11" */ SDL_SCANCODE_F11,
|
||||
/* 0x58 "F12" */ SDL_SCANCODE_F12,
|
||||
/* 0x59 "NumpadEqual" */ SDL_SCANCODE_KP_EQUALS,
|
||||
/* 0x5A */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 0x5B */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 0x5C */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 0x5D */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 0x5E */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 0x5F */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 0x60 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 0x61 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 0x62 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 0x63 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 0x64 "F13" */ SDL_SCANCODE_F13,
|
||||
/* 0x65 "F14" */ SDL_SCANCODE_F14,
|
||||
/* 0x66 "F15" */ SDL_SCANCODE_F15,
|
||||
/* 0x67 "F16" */ SDL_SCANCODE_F16,
|
||||
/* 0x68 "F17" */ SDL_SCANCODE_F17,
|
||||
/* 0x69 "F18" */ SDL_SCANCODE_F18,
|
||||
/* 0x6A "F19" */ SDL_SCANCODE_F19,
|
||||
/* 0x6B "F20" */ SDL_SCANCODE_F20,
|
||||
/* 0x6C "F21" */ SDL_SCANCODE_F21,
|
||||
/* 0x6D "F22" */ SDL_SCANCODE_F22,
|
||||
/* 0x6E "F23" */ SDL_SCANCODE_F23,
|
||||
/* 0x6F */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 0x70 "KanaMode" */ SDL_SCANCODE_INTERNATIONAL2,
|
||||
/* 0x71 "Lang2" */ SDL_SCANCODE_LANG2,
|
||||
/* 0x72 "Lang1" */ SDL_SCANCODE_LANG1,
|
||||
/* 0x73 "IntlRo" */ SDL_SCANCODE_INTERNATIONAL1,
|
||||
/* 0x74 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 0x75 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 0x76 "F24" */ SDL_SCANCODE_F24,
|
||||
/* 0x77 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 0x78 */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 0x79 "Convert" */ SDL_SCANCODE_INTERNATIONAL4,
|
||||
/* 0x7A */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 0x7B "NonConvert" */ SDL_SCANCODE_INTERNATIONAL5,
|
||||
/* 0x7C */ SDL_SCANCODE_UNKNOWN,
|
||||
/* 0x7D "IntlYen" */ SDL_SCANCODE_INTERNATIONAL3,
|
||||
/* 0x7E "NumpadComma" */ SDL_SCANCODE_KP_COMMA
|
||||
};
|
||||
|
||||
static SDL_Scancode
|
||||
Emscripten_MapScanCode(const char *code)
|
||||
{
|
||||
const DOM_PK_CODE_TYPE pk_code = emscripten_compute_dom_pk_code(code);
|
||||
if (pk_code < SDL_arraysize(emscripten_scancode_table)) {
|
||||
return emscripten_scancode_table[pk_code];
|
||||
}
|
||||
|
||||
switch (pk_code) {
|
||||
case DOM_PK_PASTE:
|
||||
return SDL_SCANCODE_PASTE;
|
||||
case DOM_PK_MEDIA_TRACK_PREVIOUS:
|
||||
return SDL_SCANCODE_AUDIOPREV;
|
||||
case DOM_PK_CUT:
|
||||
return SDL_SCANCODE_CUT;
|
||||
case DOM_PK_COPY:
|
||||
return SDL_SCANCODE_COPY;
|
||||
case DOM_PK_MEDIA_TRACK_NEXT:
|
||||
return SDL_SCANCODE_AUDIONEXT;
|
||||
case DOM_PK_NUMPAD_ENTER:
|
||||
return SDL_SCANCODE_KP_ENTER;
|
||||
case DOM_PK_CONTROL_RIGHT:
|
||||
return SDL_SCANCODE_RCTRL;
|
||||
case DOM_PK_AUDIO_VOLUME_MUTE:
|
||||
return SDL_SCANCODE_AUDIOMUTE;
|
||||
case DOM_PK_LAUNCH_APP_2:
|
||||
return SDL_SCANCODE_CALCULATOR;
|
||||
case DOM_PK_MEDIA_PLAY_PAUSE:
|
||||
return SDL_SCANCODE_AUDIOPLAY;
|
||||
case DOM_PK_MEDIA_STOP:
|
||||
return SDL_SCANCODE_AUDIOSTOP;
|
||||
case DOM_PK_EJECT:
|
||||
return SDL_SCANCODE_EJECT;
|
||||
case DOM_PK_AUDIO_VOLUME_DOWN:
|
||||
return SDL_SCANCODE_VOLUMEDOWN;
|
||||
case DOM_PK_AUDIO_VOLUME_UP:
|
||||
return SDL_SCANCODE_VOLUMEUP;
|
||||
case DOM_PK_BROWSER_HOME:
|
||||
return SDL_SCANCODE_AC_HOME;
|
||||
case DOM_PK_NUMPAD_DIVIDE:
|
||||
return SDL_SCANCODE_KP_DIVIDE;
|
||||
case DOM_PK_ALT_RIGHT:
|
||||
return SDL_SCANCODE_RALT;
|
||||
case DOM_PK_HELP:
|
||||
return SDL_SCANCODE_HELP;
|
||||
case DOM_PK_NUM_LOCK:
|
||||
return SDL_SCANCODE_NUMLOCKCLEAR;
|
||||
case DOM_PK_HOME:
|
||||
return SDL_SCANCODE_HOME;
|
||||
case DOM_PK_ARROW_UP:
|
||||
return SDL_SCANCODE_UP;
|
||||
case DOM_PK_PAGE_UP:
|
||||
return SDL_SCANCODE_PAGEUP;
|
||||
case DOM_PK_ARROW_LEFT:
|
||||
return SDL_SCANCODE_LEFT;
|
||||
case DOM_PK_ARROW_RIGHT:
|
||||
return SDL_SCANCODE_RIGHT;
|
||||
case DOM_PK_END:
|
||||
return SDL_SCANCODE_END;
|
||||
case DOM_PK_ARROW_DOWN:
|
||||
return SDL_SCANCODE_DOWN;
|
||||
case DOM_PK_PAGE_DOWN:
|
||||
return SDL_SCANCODE_PAGEDOWN;
|
||||
case DOM_PK_INSERT:
|
||||
return SDL_SCANCODE_INSERT;
|
||||
case DOM_PK_DELETE:
|
||||
return SDL_SCANCODE_DELETE;
|
||||
case DOM_PK_META_LEFT:
|
||||
return SDL_SCANCODE_LGUI;
|
||||
case DOM_PK_META_RIGHT:
|
||||
return SDL_SCANCODE_RGUI;
|
||||
case DOM_PK_CONTEXT_MENU:
|
||||
return SDL_SCANCODE_APPLICATION;
|
||||
case DOM_PK_POWER:
|
||||
return SDL_SCANCODE_POWER;
|
||||
case DOM_PK_BROWSER_SEARCH:
|
||||
return SDL_SCANCODE_AC_SEARCH;
|
||||
case DOM_PK_BROWSER_FAVORITES:
|
||||
return SDL_SCANCODE_AC_BOOKMARKS;
|
||||
case DOM_PK_BROWSER_REFRESH:
|
||||
return SDL_SCANCODE_AC_REFRESH;
|
||||
case DOM_PK_BROWSER_STOP:
|
||||
return SDL_SCANCODE_AC_STOP;
|
||||
case DOM_PK_BROWSER_FORWARD:
|
||||
return SDL_SCANCODE_AC_FORWARD;
|
||||
case DOM_PK_BROWSER_BACK:
|
||||
return SDL_SCANCODE_AC_BACK;
|
||||
case DOM_PK_LAUNCH_APP_1:
|
||||
return SDL_SCANCODE_COMPUTER;
|
||||
case DOM_PK_LAUNCH_MAIL:
|
||||
return SDL_SCANCODE_MAIL;
|
||||
case DOM_PK_MEDIA_SELECT:
|
||||
return SDL_SCANCODE_MEDIASELECT;
|
||||
}
|
||||
|
||||
return SDL_SCANCODE_UNKNOWN;
|
||||
}
|
||||
|
||||
static SDL_Keycode
|
||||
Emscripten_MapKeyCode(const EmscriptenKeyboardEvent *keyEvent)
|
||||
{
|
||||
SDL_Keycode keycode = SDLK_UNKNOWN;
|
||||
if (keyEvent->keyCode < SDL_arraysize(emscripten_keycode_table)) {
|
||||
keycode = emscripten_keycode_table[keyEvent->keyCode];
|
||||
if (keycode != SDLK_UNKNOWN) {
|
||||
if (keyEvent->location == DOM_KEY_LOCATION_RIGHT) {
|
||||
switch (keycode) {
|
||||
case SDLK_LSHIFT:
|
||||
keycode = SDLK_RSHIFT;
|
||||
break;
|
||||
case SDLK_LCTRL:
|
||||
keycode = SDLK_RCTRL;
|
||||
break;
|
||||
case SDLK_LALT:
|
||||
keycode = SDLK_RALT;
|
||||
break;
|
||||
case SDLK_LGUI:
|
||||
keycode = SDLK_RGUI;
|
||||
break;
|
||||
}
|
||||
} else if (keyEvent->location == DOM_KEY_LOCATION_NUMPAD) {
|
||||
switch (keycode) {
|
||||
case SDLK_0:
|
||||
case SDLK_INSERT:
|
||||
keycode = SDLK_KP_0;
|
||||
break;
|
||||
case SDLK_1:
|
||||
case SDLK_END:
|
||||
keycode = SDLK_KP_1;
|
||||
break;
|
||||
case SDLK_2:
|
||||
case SDLK_DOWN:
|
||||
keycode = SDLK_KP_2;
|
||||
break;
|
||||
case SDLK_3:
|
||||
case SDLK_PAGEDOWN:
|
||||
keycode = SDLK_KP_3;
|
||||
break;
|
||||
case SDLK_4:
|
||||
case SDLK_LEFT:
|
||||
keycode = SDLK_KP_4;
|
||||
break;
|
||||
case SDLK_5:
|
||||
keycode = SDLK_KP_5;
|
||||
break;
|
||||
case SDLK_6:
|
||||
case SDLK_RIGHT:
|
||||
keycode = SDLK_KP_6;
|
||||
break;
|
||||
case SDLK_7:
|
||||
case SDLK_HOME:
|
||||
keycode = SDLK_KP_7;
|
||||
break;
|
||||
case SDLK_8:
|
||||
case SDLK_UP:
|
||||
keycode = SDLK_KP_8;
|
||||
break;
|
||||
case SDLK_9:
|
||||
case SDLK_PAGEUP:
|
||||
keycode = SDLK_KP_9;
|
||||
break;
|
||||
case SDLK_RETURN:
|
||||
keycode = SDLK_KP_ENTER;
|
||||
break;
|
||||
case SDLK_DELETE:
|
||||
keycode = SDLK_KP_PERIOD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return keycode;
|
||||
}
|
||||
|
||||
/* "borrowed" from SDL_windowsevents.c */
|
||||
static int
|
||||
Emscripten_ConvertUTF32toUTF8(Uint32 codepoint, char * text)
|
||||
@@ -492,109 +803,41 @@ Emscripten_HandleTouch(int eventType, const EmscriptenTouchEvent *touchEvent, vo
|
||||
static EM_BOOL
|
||||
Emscripten_HandleKey(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData)
|
||||
{
|
||||
Uint32 scancode;
|
||||
SDL_bool prevent_default = SDL_FALSE;
|
||||
SDL_bool is_nav_key;
|
||||
const SDL_Keycode keycode = Emscripten_MapKeyCode(keyEvent);
|
||||
SDL_Scancode scancode = Emscripten_MapScanCode(keyEvent->code);
|
||||
SDL_bool prevent_default = SDL_TRUE;
|
||||
SDL_bool is_nav_key = SDL_FALSE;
|
||||
|
||||
/* .keyCode is deprecated, but still the most reliable way to get keys */
|
||||
if (keyEvent->keyCode < SDL_arraysize(emscripten_scancode_table)) {
|
||||
scancode = emscripten_scancode_table[keyEvent->keyCode];
|
||||
|
||||
if (keyEvent->keyCode == 0) {
|
||||
/* KaiOS Left Soft Key and Right Soft Key, they act as OK/Next/Menu and Cancel/Back/Clear */
|
||||
if (SDL_strncmp(keyEvent->key, "SoftLeft", 9) == 0) {
|
||||
scancode = SDL_SCANCODE_AC_FORWARD;
|
||||
}
|
||||
if (SDL_strncmp(keyEvent->key, "SoftRight", 10) == 0) {
|
||||
scancode = SDL_SCANCODE_AC_BACK;
|
||||
}
|
||||
if (scancode == SDL_SCANCODE_UNKNOWN) {
|
||||
/* KaiOS Left Soft Key and Right Soft Key, they act as OK/Next/Menu and Cancel/Back/Clear */
|
||||
if (SDL_strncmp(keyEvent->key, "SoftLeft", 9) == 0) {
|
||||
scancode = SDL_SCANCODE_AC_FORWARD;
|
||||
} else if (SDL_strncmp(keyEvent->key, "SoftRight", 10) == 0) {
|
||||
scancode = SDL_SCANCODE_AC_BACK;
|
||||
}
|
||||
}
|
||||
|
||||
if (scancode != SDL_SCANCODE_UNKNOWN) {
|
||||
|
||||
if (keyEvent->location == DOM_KEY_LOCATION_RIGHT) {
|
||||
switch (scancode) {
|
||||
case SDL_SCANCODE_LSHIFT:
|
||||
scancode = SDL_SCANCODE_RSHIFT;
|
||||
break;
|
||||
case SDL_SCANCODE_LCTRL:
|
||||
scancode = SDL_SCANCODE_RCTRL;
|
||||
break;
|
||||
case SDL_SCANCODE_LALT:
|
||||
scancode = SDL_SCANCODE_RALT;
|
||||
break;
|
||||
case SDL_SCANCODE_LGUI:
|
||||
scancode = SDL_SCANCODE_RGUI;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (keyEvent->location == DOM_KEY_LOCATION_NUMPAD) {
|
||||
switch (scancode) {
|
||||
case SDL_SCANCODE_0:
|
||||
case SDL_SCANCODE_INSERT:
|
||||
scancode = SDL_SCANCODE_KP_0;
|
||||
break;
|
||||
case SDL_SCANCODE_1:
|
||||
case SDL_SCANCODE_END:
|
||||
scancode = SDL_SCANCODE_KP_1;
|
||||
break;
|
||||
case SDL_SCANCODE_2:
|
||||
case SDL_SCANCODE_DOWN:
|
||||
scancode = SDL_SCANCODE_KP_2;
|
||||
break;
|
||||
case SDL_SCANCODE_3:
|
||||
case SDL_SCANCODE_PAGEDOWN:
|
||||
scancode = SDL_SCANCODE_KP_3;
|
||||
break;
|
||||
case SDL_SCANCODE_4:
|
||||
case SDL_SCANCODE_LEFT:
|
||||
scancode = SDL_SCANCODE_KP_4;
|
||||
break;
|
||||
case SDL_SCANCODE_5:
|
||||
scancode = SDL_SCANCODE_KP_5;
|
||||
break;
|
||||
case SDL_SCANCODE_6:
|
||||
case SDL_SCANCODE_RIGHT:
|
||||
scancode = SDL_SCANCODE_KP_6;
|
||||
break;
|
||||
case SDL_SCANCODE_7:
|
||||
case SDL_SCANCODE_HOME:
|
||||
scancode = SDL_SCANCODE_KP_7;
|
||||
break;
|
||||
case SDL_SCANCODE_8:
|
||||
case SDL_SCANCODE_UP:
|
||||
scancode = SDL_SCANCODE_KP_8;
|
||||
break;
|
||||
case SDL_SCANCODE_9:
|
||||
case SDL_SCANCODE_PAGEUP:
|
||||
scancode = SDL_SCANCODE_KP_9;
|
||||
break;
|
||||
case SDL_SCANCODE_RETURN:
|
||||
scancode = SDL_SCANCODE_KP_ENTER;
|
||||
break;
|
||||
case SDL_SCANCODE_DELETE:
|
||||
scancode = SDL_SCANCODE_KP_PERIOD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
prevent_default = SDL_SendKeyboardKey(eventType == EMSCRIPTEN_EVENT_KEYDOWN ? SDL_PRESSED : SDL_RELEASED, scancode);
|
||||
}
|
||||
if (scancode != SDL_SCANCODE_UNKNOWN) {
|
||||
SDL_SendKeyboardKeyAndKeycode(eventType == EMSCRIPTEN_EVENT_KEYDOWN ? SDL_PRESSED : SDL_RELEASED, scancode, keycode);
|
||||
}
|
||||
|
||||
/* 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
|
||||
*/
|
||||
is_nav_key = keyEvent->keyCode == 8 /* backspace */ ||
|
||||
keyEvent->keyCode == 9 /* tab */ ||
|
||||
keyEvent->keyCode == 37 /* left */ ||
|
||||
keyEvent->keyCode == 38 /* up */ ||
|
||||
keyEvent->keyCode == 39 /* right */ ||
|
||||
keyEvent->keyCode == 40 /* down */ ||
|
||||
(keyEvent->keyCode >= 112 && keyEvent->keyCode <= 135) /* F keys*/ ||
|
||||
keyEvent->ctrlKey;
|
||||
if ( (scancode == SDL_SCANCODE_BACKSPACE) ||
|
||||
(scancode == SDL_SCANCODE_TAB) ||
|
||||
(scancode == SDL_SCANCODE_LEFT) ||
|
||||
(scancode == SDL_SCANCODE_UP) ||
|
||||
(scancode == SDL_SCANCODE_RIGHT) ||
|
||||
(scancode == SDL_SCANCODE_DOWN) ||
|
||||
((scancode >= SDL_SCANCODE_F1) && (scancode <= SDL_SCANCODE_F15)) ||
|
||||
keyEvent->ctrlKey ) {
|
||||
is_nav_key = SDL_TRUE;
|
||||
}
|
||||
|
||||
if (eventType == EMSCRIPTEN_EVENT_KEYDOWN && SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE && !is_nav_key)
|
||||
if ((eventType == EMSCRIPTEN_EVENT_KEYDOWN) && (SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE) && !is_nav_key) {
|
||||
prevent_default = SDL_FALSE;
|
||||
}
|
||||
|
||||
return prevent_default;
|
||||
}
|
||||
|
||||
@@ -75,28 +75,31 @@ int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rec
|
||||
var w = $0;
|
||||
var h = $1;
|
||||
var pixels = $2;
|
||||
var canvasId = UTF8ToString($3);
|
||||
var canvas = document.querySelector(canvasId);
|
||||
|
||||
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'];
|
||||
//TODO: this should store a context per canvas
|
||||
if (!Module['SDL3']) Module['SDL3'] = {};
|
||||
var SDL3 = Module['SDL3'];
|
||||
if (SDL3.ctxCanvas !== canvas) {
|
||||
SDL3.ctx = Module['createContext'](canvas, false, true);
|
||||
SDL3.ctxCanvas = 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;
|
||||
if (SDL3.w !== w || SDL3.h !== h || SDL3.imageCtx !== SDL3.ctx) {
|
||||
SDL3.image = SDL3.ctx.createImageData(w, h);
|
||||
SDL3.w = w;
|
||||
SDL3.h = h;
|
||||
SDL3.imageCtx = SDL3.ctx;
|
||||
}
|
||||
var data = SDL2.image.data;
|
||||
var data = SDL3.image.data;
|
||||
var src = pixels >> 2;
|
||||
var dst = 0;
|
||||
var num;
|
||||
|
||||
if (SDL2.data32Data !== data) {
|
||||
SDL2.data32 = new Int32Array(data.buffer);
|
||||
SDL2.data8 = new Uint8Array(data.buffer);
|
||||
SDL2.data32Data = data;
|
||||
if (SDL3.data32Data !== data) {
|
||||
SDL3.data32 = new Int32Array(data.buffer);
|
||||
SDL3.data8 = new Uint8Array(data.buffer);
|
||||
SDL3.data32Data = data;
|
||||
}
|
||||
var data32 = SDL2.data32;
|
||||
num = data32.length;
|
||||
@@ -109,7 +112,7 @@ int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rec
|
||||
// native SDL_memcpy efficiencies, and the remaining loop
|
||||
// just stores, not load + store, so it is faster
|
||||
data32.set(HEAP32.subarray(src, src + num));
|
||||
var data8 = SDL2.data8;
|
||||
var data8 = SDL3.data8;
|
||||
var i = 3;
|
||||
var j = i + 4*num;
|
||||
if (num % 8 == 0) {
|
||||
@@ -139,8 +142,8 @@ int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rec
|
||||
}
|
||||
}
|
||||
|
||||
SDL2.ctx.putImageData(SDL2.image, 0, 0);
|
||||
}, surface->w, surface->h, surface->pixels);
|
||||
SDL3.ctx.putImageData(SDL3.image, 0, 0);
|
||||
}, surface->w, surface->h, surface->pixels, data->canvas_id);
|
||||
|
||||
if (emscripten_has_asyncify() && SDL_GetHintBoolean(SDL_HINT_EMSCRIPTEN_ASYNCIFY, SDL_TRUE)) {
|
||||
/* give back control to browser for screen refresh */
|
||||
|
||||
@@ -20,83 +20,151 @@
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_EMSCRIPTEN && SDL_VIDEO_OPENGL_EGL
|
||||
#if SDL_VIDEO_DRIVER_EMSCRIPTEN
|
||||
|
||||
#include <emscripten/emscripten.h>
|
||||
#include <emscripten/html5_webgl.h>
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
#include "SDL_emscriptenvideo.h"
|
||||
#include "SDL_emscriptenopengles.h"
|
||||
#include "SDL_hints.h"
|
||||
|
||||
#define LOAD_FUNC(NAME) _this->egl_data->NAME = NAME;
|
||||
|
||||
/* EGL implementation of SDL OpenGL support */
|
||||
|
||||
int
|
||||
Emscripten_GLES_LoadLibrary(_THIS, const char *path) {
|
||||
/*we can't load EGL dynamically*/
|
||||
_this->egl_data = (struct SDL_EGL_VideoData *) SDL_calloc(1, sizeof(SDL_EGL_VideoData));
|
||||
if (!_this->egl_data) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
/* Emscripten forces you to manually cast eglGetProcAddress to the real
|
||||
function type; grep for "__eglMustCastToProperFunctionPointerType" in
|
||||
Emscripten's egl.h for details. */
|
||||
_this->egl_data->eglGetProcAddress = (void *(EGLAPIENTRY *)(const char *)) eglGetProcAddress;
|
||||
|
||||
LOAD_FUNC(eglGetDisplay);
|
||||
LOAD_FUNC(eglInitialize);
|
||||
LOAD_FUNC(eglTerminate);
|
||||
LOAD_FUNC(eglChooseConfig);
|
||||
LOAD_FUNC(eglGetConfigAttrib);
|
||||
LOAD_FUNC(eglCreateContext);
|
||||
LOAD_FUNC(eglDestroyContext);
|
||||
LOAD_FUNC(eglCreateWindowSurface);
|
||||
LOAD_FUNC(eglDestroySurface);
|
||||
LOAD_FUNC(eglMakeCurrent);
|
||||
LOAD_FUNC(eglSwapBuffers);
|
||||
LOAD_FUNC(eglSwapInterval);
|
||||
LOAD_FUNC(eglWaitNative);
|
||||
LOAD_FUNC(eglWaitGL);
|
||||
LOAD_FUNC(eglBindAPI);
|
||||
LOAD_FUNC(eglQueryString);
|
||||
LOAD_FUNC(eglGetError);
|
||||
|
||||
_this->egl_data->egl_display = _this->egl_data->eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
if (!_this->egl_data->egl_display) {
|
||||
return SDL_SetError("Could not get EGL display");
|
||||
}
|
||||
|
||||
if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) {
|
||||
return SDL_SetError("Could not initialize EGL");
|
||||
}
|
||||
|
||||
if (path) {
|
||||
SDL_strlcpy(_this->gl_config.driver_path, path, sizeof(_this->gl_config.driver_path) - 1);
|
||||
} else {
|
||||
*_this->gl_config.driver_path = '\0';
|
||||
}
|
||||
|
||||
Emscripten_GLES_LoadLibrary(_THIS, const char *path)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_EGL_CreateContext_impl(Emscripten)
|
||||
SDL_EGL_MakeCurrent_impl(Emscripten)
|
||||
void
|
||||
Emscripten_GLES_UnloadLibrary(_THIS)
|
||||
{
|
||||
}
|
||||
|
||||
void *
|
||||
Emscripten_GLES_GetProcAddress(_THIS, const char *proc)
|
||||
{
|
||||
return emscripten_webgl_get_proc_address(proc);
|
||||
}
|
||||
|
||||
int
|
||||
Emscripten_GLES_SetSwapInterval(_THIS, int interval)
|
||||
{
|
||||
if (interval < 0) {
|
||||
return SDL_SetError("Late swap tearing currently unsupported");
|
||||
} else if(interval == 0) {
|
||||
emscripten_set_main_loop_timing(EM_TIMING_SETTIMEOUT, 0);
|
||||
} else {
|
||||
emscripten_set_main_loop_timing(EM_TIMING_RAF, interval);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Emscripten_GLES_GetSwapInterval(_THIS)
|
||||
{
|
||||
int mode, value;
|
||||
|
||||
emscripten_get_main_loop_timing(&mode, &value);
|
||||
|
||||
if(mode == EM_TIMING_RAF)
|
||||
return value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_GLContext
|
||||
Emscripten_GLES_CreateContext(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_WindowData *window_data;
|
||||
|
||||
EmscriptenWebGLContextAttributes attribs;
|
||||
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context;
|
||||
|
||||
emscripten_webgl_init_context_attributes(&attribs);
|
||||
|
||||
attribs.alpha = _this->gl_config.alpha_size > 0;
|
||||
attribs.depth = _this->gl_config.depth_size > 0;
|
||||
attribs.stencil = _this->gl_config.stencil_size > 0;
|
||||
attribs.antialias = _this->gl_config.multisamplebuffers == 1;
|
||||
|
||||
if(_this->gl_config.major_version == 3)
|
||||
attribs.majorVersion = 2; /* WebGL 2.0 ~= GLES 3.0 */
|
||||
|
||||
window_data = (SDL_WindowData *) window->driverdata;
|
||||
|
||||
if (window_data->gl_context) {
|
||||
SDL_SetError("Cannot create multiple webgl contexts per window");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
context = emscripten_webgl_create_context(window_data->canvas_id, &attribs);
|
||||
|
||||
if (context < 0) {
|
||||
SDL_SetError("Could not create webgl context");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (emscripten_webgl_make_context_current(context) != EMSCRIPTEN_RESULT_SUCCESS) {
|
||||
emscripten_webgl_destroy_context(context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
window_data->gl_context = (SDL_GLContext)context;
|
||||
|
||||
return (SDL_GLContext)context;
|
||||
}
|
||||
|
||||
void
|
||||
Emscripten_GLES_DeleteContext(_THIS, SDL_GLContext context)
|
||||
{
|
||||
SDL_Window *window;
|
||||
|
||||
/* remove the context from its window */
|
||||
for (window = _this->windows; window != NULL; window = window->next) {
|
||||
SDL_WindowData *window_data;
|
||||
window_data = (SDL_WindowData *) window->driverdata;
|
||||
|
||||
if (window_data->gl_context == context) {
|
||||
window_data->gl_context = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
emscripten_webgl_destroy_context((EMSCRIPTEN_WEBGL_CONTEXT_HANDLE)context);
|
||||
}
|
||||
|
||||
int
|
||||
Emscripten_GLES_SwapWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
EGLBoolean ret = SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
|
||||
if (emscripten_has_asyncify() && SDL_GetHintBoolean(SDL_HINT_EMSCRIPTEN_ASYNCIFY, SDL_TRUE)) {
|
||||
/* give back control to browser for screen refresh */
|
||||
emscripten_sleep(0);
|
||||
}
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN && SDL_VIDEO_OPENGL_EGL */
|
||||
int
|
||||
Emscripten_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
|
||||
{
|
||||
/* it isn't possible to reuse contexts across canvases */
|
||||
if (window && context) {
|
||||
SDL_WindowData *window_data;
|
||||
window_data = (SDL_WindowData *) window->driverdata;
|
||||
|
||||
if (context != window_data->gl_context) {
|
||||
return SDL_SetError("Cannot make context current to another window");
|
||||
}
|
||||
}
|
||||
|
||||
if (emscripten_webgl_make_context_current((EMSCRIPTEN_WEBGL_CONTEXT_HANDLE)context) != EMSCRIPTEN_RESULT_SUCCESS) {
|
||||
return SDL_SetError("Unable to make context current");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
|
||||
@@ -23,25 +23,23 @@
|
||||
#ifndef SDL_emscriptenopengles_h_
|
||||
#define SDL_emscriptenopengles_h_
|
||||
|
||||
#if SDL_VIDEO_DRIVER_EMSCRIPTEN && SDL_VIDEO_OPENGL_EGL
|
||||
#if SDL_VIDEO_DRIVER_EMSCRIPTEN
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "../SDL_egl_c.h"
|
||||
|
||||
/* OpenGLES functions */
|
||||
#define Emscripten_GLES_GetAttribute SDL_EGL_GetAttribute
|
||||
#define Emscripten_GLES_GetProcAddress SDL_EGL_GetProcAddress
|
||||
#define Emscripten_GLES_UnloadLibrary SDL_EGL_UnloadLibrary
|
||||
#define Emscripten_GLES_SetSwapInterval SDL_EGL_SetSwapInterval
|
||||
#define Emscripten_GLES_GetSwapInterval SDL_EGL_GetSwapInterval
|
||||
#define Emscripten_GLES_DeleteContext SDL_EGL_DeleteContext
|
||||
|
||||
extern int Emscripten_GLES_LoadLibrary(_THIS, const char *path);
|
||||
extern void Emscripten_GLES_UnloadLibrary(_THIS);
|
||||
extern void * Emscripten_GLES_GetProcAddress(_THIS, const char *proc);
|
||||
extern int Emscripten_GLES_SetSwapInterval(_THIS, int interval);
|
||||
extern int Emscripten_GLES_GetSwapInterval(_THIS);
|
||||
extern SDL_GLContext Emscripten_GLES_CreateContext(_THIS, SDL_Window * window);
|
||||
extern void Emscripten_GLES_DeleteContext(_THIS, SDL_GLContext context);
|
||||
extern int Emscripten_GLES_SwapWindow(_THIS, SDL_Window * window);
|
||||
extern int Emscripten_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN && SDL_VIDEO_OPENGL_EGL */
|
||||
#endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN */
|
||||
|
||||
#endif /* SDL_emscriptenopengles_h_ */
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include "SDL_hints.h"
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "../SDL_pixels_c.h"
|
||||
#include "../SDL_egl_c.h"
|
||||
#include "../../events/SDL_events_c.h"
|
||||
|
||||
#include "SDL_emscriptenvideo.h"
|
||||
@@ -110,7 +109,6 @@ Emscripten_CreateDevice(void)
|
||||
device->UpdateWindowFramebuffer = Emscripten_UpdateWindowFramebuffer;
|
||||
device->DestroyWindowFramebuffer = Emscripten_DestroyWindowFramebuffer;
|
||||
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
device->GL_LoadLibrary = Emscripten_GLES_LoadLibrary;
|
||||
device->GL_GetProcAddress = Emscripten_GLES_GetProcAddress;
|
||||
device->GL_UnloadLibrary = Emscripten_GLES_UnloadLibrary;
|
||||
@@ -120,7 +118,6 @@ Emscripten_CreateDevice(void)
|
||||
device->GL_GetSwapInterval = Emscripten_GLES_GetSwapInterval;
|
||||
device->GL_SwapWindow = Emscripten_GLES_SwapWindow;
|
||||
device->GL_DeleteContext = Emscripten_GLES_DeleteContext;
|
||||
#endif
|
||||
|
||||
device->free = Emscripten_DeleteDevice;
|
||||
|
||||
@@ -218,6 +215,7 @@ Emscripten_CreateWindow(_THIS, SDL_Window * window)
|
||||
SDL_WindowData *wdata;
|
||||
double scaled_w, scaled_h;
|
||||
double css_w, css_h;
|
||||
const char *selector;
|
||||
|
||||
/* Allocate window internal data */
|
||||
wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
|
||||
@@ -225,7 +223,12 @@ Emscripten_CreateWindow(_THIS, SDL_Window * window)
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
wdata->canvas_id = SDL_strdup("#canvas");
|
||||
selector = SDL_GetHint(SDL_HINT_EMSCRIPTEN_CANVAS_SELECTOR);
|
||||
if (!selector) {
|
||||
selector = "#canvas";
|
||||
}
|
||||
|
||||
wdata->canvas_id = SDL_strdup(selector);
|
||||
|
||||
if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
|
||||
wdata->pixel_ratio = emscripten_get_device_pixel_ratio();
|
||||
@@ -259,21 +262,6 @@ Emscripten_CreateWindow(_THIS, SDL_Window * window)
|
||||
}
|
||||
}
|
||||
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
if (window->flags & SDL_WINDOW_OPENGL) {
|
||||
if (!_this->egl_data) {
|
||||
if (SDL_GL_LoadLibrary(NULL) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
wdata->egl_surface = SDL_EGL_CreateSurface(_this, 0);
|
||||
|
||||
if (wdata->egl_surface == EGL_NO_SURFACE) {
|
||||
return SDL_SetError("Could not create GLES window surface");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
wdata->window = window;
|
||||
|
||||
/* Setup driver data for this window */
|
||||
@@ -329,12 +317,6 @@ Emscripten_DestroyWindow(_THIS, SDL_Window * window)
|
||||
data = (SDL_WindowData *) window->driverdata;
|
||||
|
||||
Emscripten_UnregisterEventHandlers(data);
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
if (data->egl_surface != EGL_NO_SURFACE) {
|
||||
SDL_EGL_DestroySurface(_this, data->egl_surface);
|
||||
data->egl_surface = EGL_NO_SURFACE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* We can't destroy the canvas, so resize it to zero instead */
|
||||
emscripten_set_canvas_element_size(data->canvas_id, 0, 0);
|
||||
|
||||
@@ -28,18 +28,13 @@
|
||||
#include <emscripten/emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
#include <EGL/egl.h>
|
||||
#endif
|
||||
|
||||
typedef struct SDL_WindowData
|
||||
{
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
EGLSurface egl_surface;
|
||||
#endif
|
||||
SDL_Window *window;
|
||||
SDL_Surface *surface;
|
||||
|
||||
SDL_GLContext gl_context;
|
||||
|
||||
char *canvas_id;
|
||||
|
||||
float pixel_ratio;
|
||||
|
||||
@@ -309,7 +309,7 @@ public:
|
||||
fComputedMessageBoxWidth(0.0f),
|
||||
fCloseButton(G_CLOSE_BUTTON_ID), fDefaultButton(G_DEFAULT_BUTTON_ID),
|
||||
fCustomColorScheme(false), fThereIsLongLine(false),
|
||||
HAIKU_SDL_DefTitle("SDL2 MessageBox"),
|
||||
HAIKU_SDL_DefTitle("SDL MessageBox"),
|
||||
HAIKU_SDL_DefMessage("Some information has been lost."),
|
||||
HAIKU_SDL_DefButton("OK")
|
||||
{
|
||||
|
||||
@@ -94,8 +94,7 @@ int HAIKU_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) {
|
||||
// printf("HAIKU_GL_MakeCurrent(%llx), win = %llx, thread = %d\n", (uint64)context, (uint64)window, find_thread(NULL));
|
||||
if (glView != NULL) {
|
||||
if ((glView->Window() == NULL) || (window == NULL) || (_ToBeWin(window)->GetGLView() != glView)) {
|
||||
SDL_SetError("MakeCurrent failed");
|
||||
return -1;
|
||||
return SDL_SetError("MakeCurrent failed");
|
||||
}
|
||||
}
|
||||
_GetBeApp()->SetCurrentContext(glView);
|
||||
|
||||
@@ -180,13 +180,13 @@ KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window) {
|
||||
}
|
||||
|
||||
/* Wait immediately for vsync (as if we only had two buffers).
|
||||
Even if we are already doing a WaitPageflip at the begining of this
|
||||
Even if we are already doing a WaitPageflip at the beginning of this
|
||||
function, this is NOT redundant because here we wait immediately
|
||||
after submitting the image to the screen, reducing lag, and if
|
||||
we have waited here, there won't be a pending pageflip so the
|
||||
WaitPageflip at the beggining of this function will be a no-op.
|
||||
WaitPageflip at the beginning of this function will be a no-op.
|
||||
Just leave it here and don't worry.
|
||||
Run your SDL2 program with "SDL_KMSDRM_DOUBLE_BUFFER=1 <program_name>"
|
||||
Run your SDL program with "SDL_KMSDRM_DOUBLE_BUFFER=1 <program_name>"
|
||||
to enable this. */
|
||||
if (windata->double_buffer) {
|
||||
if (!KMSDRM_WaitPageflip(_this, windata)) {
|
||||
|
||||
@@ -308,8 +308,8 @@ KMSDRM_CreateDevice(void)
|
||||
return device;
|
||||
|
||||
cleanup:
|
||||
if (device)
|
||||
SDL_free(device);
|
||||
SDL_free(device);
|
||||
|
||||
if (viddata)
|
||||
SDL_free(viddata);
|
||||
return NULL;
|
||||
@@ -666,8 +666,8 @@ KMSDRM_CrtcGetVrr(uint32_t drm_fd, uint32_t crtc_id)
|
||||
/* Gets a DRM connector, builds an SDL_Display with it, and adds it to the
|
||||
list of SDL Displays in _this->displays[] */
|
||||
static void
|
||||
KMSDRM_AddDisplay (_THIS, drmModeConnector *connector, drmModeRes *resources) {
|
||||
|
||||
KMSDRM_AddDisplay (_THIS, drmModeConnector *connector, drmModeRes *resources)
|
||||
{
|
||||
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
|
||||
SDL_DisplayData *dispdata = NULL;
|
||||
SDL_VideoDisplay display = {0};
|
||||
@@ -770,14 +770,37 @@ KMSDRM_AddDisplay (_THIS, drmModeConnector *connector, drmModeRes *resources) {
|
||||
drmModeModeInfo *mode = &connector->modes[i];
|
||||
|
||||
if (!SDL_memcmp(mode, &crtc->mode, sizeof(crtc->mode))) {
|
||||
mode_index = i;
|
||||
break;
|
||||
mode_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mode_index == -1) {
|
||||
ret = SDL_SetError("Failed to find index of mode attached to the CRTC.");
|
||||
goto cleanup;
|
||||
int current_area, largest_area = 0;
|
||||
|
||||
/* Find the preferred mode or the highest resolution mode */
|
||||
for (i = 0; i < connector->count_modes; i++) {
|
||||
drmModeModeInfo *mode = &connector->modes[i];
|
||||
|
||||
if (mode->type & DRM_MODE_TYPE_PREFERRED) {
|
||||
mode_index = i;
|
||||
break;
|
||||
}
|
||||
|
||||
current_area = mode->hdisplay * mode->vdisplay;
|
||||
if (current_area > largest_area) {
|
||||
mode_index = i;
|
||||
largest_area = current_area;
|
||||
}
|
||||
}
|
||||
if (mode_index != -1) {
|
||||
crtc->mode = connector->modes[mode_index];
|
||||
}
|
||||
}
|
||||
|
||||
if (mode_index == -1) {
|
||||
ret = SDL_SetError("Failed to find index of mode attached to the CRTC.");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
@@ -1412,7 +1435,7 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window)
|
||||
|
||||
if (!(viddata->gbm_init)) {
|
||||
|
||||
/* After SDL_CreateWindow, most SDL2 programs will do SDL_CreateRenderer(),
|
||||
/* After SDL_CreateWindow, most SDL programs will do SDL_CreateRenderer(),
|
||||
which will in turn call GL_CreateRenderer() or GLES2_CreateRenderer().
|
||||
In order for the GL_CreateRenderer() or GLES2_CreateRenderer() call to
|
||||
succeed without an unnecessary window re-creation, we must:
|
||||
@@ -1433,28 +1456,34 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window)
|
||||
}
|
||||
}
|
||||
|
||||
/* Manually load the GL library. KMSDRM_EGL_LoadLibrary() has already
|
||||
been called by SDL_CreateWindow() but we don't do anything there,
|
||||
out KMSDRM_EGL_LoadLibrary() is a dummy precisely to be able to load it here.
|
||||
If we let SDL_CreateWindow() load the lib, it would be loaded
|
||||
before we call KMSDRM_GBMInit(), causing all GLES programs to fail. */
|
||||
if (!_this->egl_data) {
|
||||
egl_display = (NativeDisplayType)((SDL_VideoData *)_this->driverdata)->gbm_dev;
|
||||
if (SDL_EGL_LoadLibrary(_this, NULL, egl_display, EGL_PLATFORM_GBM_MESA)) {
|
||||
return (SDL_SetError("Can't load EGL/GL library on window creation."));
|
||||
}
|
||||
/* Manually load the GL library. KMSDRM_EGL_LoadLibrary() has already
|
||||
been called by SDL_CreateWindow() but we don't do anything there,
|
||||
our KMSDRM_EGL_LoadLibrary() is a dummy precisely to be able to load it here.
|
||||
If we let SDL_CreateWindow() load the lib, it would be loaded
|
||||
before we call KMSDRM_GBMInit(), causing all GLES programs to fail. */
|
||||
if (!_this->egl_data) {
|
||||
egl_display = (NativeDisplayType)((SDL_VideoData *)_this->driverdata)->gbm_dev;
|
||||
if (SDL_EGL_LoadLibrary(_this, NULL, egl_display, EGL_PLATFORM_GBM_MESA) < 0) {
|
||||
/* Try again with OpenGL ES 2.0 */
|
||||
_this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES;
|
||||
_this->gl_config.major_version = 2;
|
||||
_this->gl_config.minor_version = 0;
|
||||
if (SDL_EGL_LoadLibrary(_this, NULL, egl_display, EGL_PLATFORM_GBM_MESA) < 0) {
|
||||
return (SDL_SetError("Can't load EGL/GL library on window creation."));
|
||||
}
|
||||
}
|
||||
|
||||
_this->gl_config.driver_loaded = 1;
|
||||
_this->gl_config.driver_loaded = 1;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Create the cursor BO for the display of this window,
|
||||
now that we know this is not a VK window. */
|
||||
KMSDRM_CreateCursorBO(display);
|
||||
/* Create the cursor BO for the display of this window,
|
||||
now that we know this is not a VK window. */
|
||||
KMSDRM_CreateCursorBO(display);
|
||||
|
||||
/* Create and set the default cursor for the display
|
||||
/* Create and set the default cursor for the display
|
||||
of this window, now that we know this is not a VK window. */
|
||||
KMSDRM_InitMouse(_this, display);
|
||||
KMSDRM_InitMouse(_this, display);
|
||||
|
||||
/* The FULLSCREEN flags are cut out from window->flags at this point,
|
||||
so we can't know if a window is fullscreen or not, hence all windows
|
||||
|
||||
@@ -20,13 +20,28 @@
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifndef SDL_naclwindow_h_
|
||||
#define SDL_naclwindow_h_
|
||||
#ifdef SDL_VIDEO_DRIVER_N3DS
|
||||
|
||||
extern int NACL_CreateWindow(_THIS, SDL_Window * window);
|
||||
extern void NACL_SetWindowTitle(_THIS, SDL_Window * window);
|
||||
extern void NACL_DestroyWindow(_THIS, SDL_Window * window);
|
||||
#include <3ds.h>
|
||||
|
||||
#endif /* SDL_naclwindow_h_ */
|
||||
#include "../../events/SDL_events_c.h"
|
||||
#include "SDL_n3dsevents_c.h"
|
||||
#include "SDL_n3dstouch.h"
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
void
|
||||
N3DS_PumpEvents(_THIS)
|
||||
{
|
||||
hidScanInput();
|
||||
N3DS_PollTouch();
|
||||
|
||||
if (!aptMainLoop()) {
|
||||
SDL_Event ev;
|
||||
ev.type = SDL_QUIT;
|
||||
SDL_PushEvent(&ev);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_N3DS */
|
||||
|
||||
/* vi: set sts=4 ts=4 sw=4 expandtab: */
|
||||
@@ -18,13 +18,14 @@
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_n3dsevents_c_h_
|
||||
#define SDL_n3dsevents_c_h_
|
||||
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifndef SDL_naclevents_c_h_
|
||||
#define SDL_naclevents_c_h_
|
||||
extern void N3DS_PumpEvents(_THIS);
|
||||
|
||||
#include "SDL_naclvideo.h"
|
||||
#endif /* SDL_n3dsevents_c_h_ */
|
||||
|
||||
extern void NACL_PumpEvents(_THIS);
|
||||
|
||||
#endif /* SDL_naclevents_c_h_ */
|
||||
/* vi: set sts=4 ts=4 sw=4 expandtab: */
|
||||
148
src/video/n3ds/SDL_n3dsframebuffer.c
Normal file
148
src/video/n3ds/SDL_n3dsframebuffer.c
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_N3DS
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "SDL_n3dsframebuffer_c.h"
|
||||
#include "SDL_n3dsvideo.h"
|
||||
|
||||
#define N3DS_SURFACE "_SDL_N3DSSurface"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int width, height;
|
||||
} Dimensions;
|
||||
|
||||
SDL_FORCE_INLINE void FreePreviousWindowFramebuffer(SDL_Window *window);
|
||||
SDL_FORCE_INLINE SDL_Surface *CreateNewWindowFramebuffer(SDL_Window *window);
|
||||
SDL_FORCE_INLINE void CopyFramebuffertoN3DS(u32 *dest, const Dimensions dest_dim, const u32 *source, const Dimensions source_dim);
|
||||
SDL_FORCE_INLINE int GetDestOffset(int x, int y, int dest_width);
|
||||
SDL_FORCE_INLINE int GetSourceOffset(int x, int y, int source_width);
|
||||
SDL_FORCE_INLINE void FlushN3DSBuffer(const void *buffer, u32 bufsize, gfxScreen_t screen);
|
||||
|
||||
int
|
||||
SDL_N3DS_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch)
|
||||
{
|
||||
SDL_Surface *framebuffer;
|
||||
|
||||
FreePreviousWindowFramebuffer(window);
|
||||
framebuffer = CreateNewWindowFramebuffer(window);
|
||||
|
||||
if (!framebuffer) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
SDL_SetWindowData(window, N3DS_SURFACE, framebuffer);
|
||||
*format = FRAMEBUFFER_FORMAT;
|
||||
*pixels = framebuffer->pixels;
|
||||
*pitch = framebuffer->pitch;
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_FORCE_INLINE void
|
||||
FreePreviousWindowFramebuffer(SDL_Window *window)
|
||||
{
|
||||
SDL_Surface *surface = (SDL_Surface *) SDL_GetWindowData(window, N3DS_SURFACE);
|
||||
SDL_FreeSurface(surface);
|
||||
}
|
||||
|
||||
SDL_FORCE_INLINE SDL_Surface *
|
||||
CreateNewWindowFramebuffer(SDL_Window *window)
|
||||
{
|
||||
int w, h, bpp;
|
||||
Uint32 Rmask, Gmask, Bmask, Amask;
|
||||
SDL_PixelFormatEnumToMasks(FRAMEBUFFER_FORMAT, &bpp, &Rmask, &Gmask, &Bmask, &Amask);
|
||||
SDL_GetWindowSize(window, &w, &h);
|
||||
return SDL_CreateRGBSurface(0, w, h, bpp, Rmask, Gmask, Bmask, Amask);
|
||||
}
|
||||
|
||||
int
|
||||
SDL_N3DS_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects)
|
||||
{
|
||||
SDL_WindowData *drv_data = (SDL_WindowData *) window->driverdata;
|
||||
SDL_Surface *surface;
|
||||
u16 width, height;
|
||||
u32 *framebuffer;
|
||||
u32 bufsize;
|
||||
|
||||
surface = (SDL_Surface *) SDL_GetWindowData(window, N3DS_SURFACE);
|
||||
if (!surface) {
|
||||
return SDL_SetError("%s: Unable to get the window surface.", __func__);
|
||||
}
|
||||
|
||||
/* Get the N3DS internal framebuffer and its size */
|
||||
framebuffer = (u32 *) gfxGetFramebuffer(drv_data->screen, GFX_LEFT, &width, &height);
|
||||
bufsize = width * height * 4;
|
||||
|
||||
CopyFramebuffertoN3DS(framebuffer, (Dimensions){ width, height },
|
||||
surface->pixels, (Dimensions){ surface->w, surface->h });
|
||||
FlushN3DSBuffer(framebuffer, bufsize, drv_data->screen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_FORCE_INLINE void
|
||||
CopyFramebuffertoN3DS(u32 *dest, const Dimensions dest_dim, const u32 *source, const Dimensions source_dim)
|
||||
{
|
||||
int rows = SDL_min(dest_dim.width, source_dim.height);
|
||||
int cols = SDL_min(dest_dim.height, source_dim.width);
|
||||
for (int y = 0; y < rows; ++y) {
|
||||
for (int x = 0; x < cols; ++x) {
|
||||
SDL_memcpy(
|
||||
dest + GetDestOffset(x, y, dest_dim.width),
|
||||
source + GetSourceOffset(x, y, source_dim.width),
|
||||
4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SDL_FORCE_INLINE int
|
||||
GetDestOffset(int x, int y, int dest_width)
|
||||
{
|
||||
return dest_width - y - 1 + dest_width * x;
|
||||
}
|
||||
|
||||
SDL_FORCE_INLINE int
|
||||
GetSourceOffset(int x, int y, int source_width)
|
||||
{
|
||||
return x + y * source_width;
|
||||
}
|
||||
|
||||
SDL_FORCE_INLINE void
|
||||
FlushN3DSBuffer(const void *buffer, u32 bufsize, gfxScreen_t screen)
|
||||
{
|
||||
GSPGPU_FlushDataCache(buffer, bufsize);
|
||||
gfxScreenSwapBuffers(screen, false);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_N3DS_DestroyWindowFramebuffer(_THIS, SDL_Window *window)
|
||||
{
|
||||
SDL_Surface *surface;
|
||||
surface = (SDL_Surface *) SDL_SetWindowData(window, N3DS_SURFACE, NULL);
|
||||
SDL_FreeSurface(surface);
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_N3DS */
|
||||
|
||||
/* vi: set sts=4 ts=4 sw=4 expandtab: */
|
||||
33
src/video/n3ds/SDL_n3dsframebuffer_c.h
Normal file
33
src/video/n3ds/SDL_n3dsframebuffer_c.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_n3dsframebuffer_c_h_
|
||||
#define SDL_n3dsframebuffer_c_h_
|
||||
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
int SDL_N3DS_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch);
|
||||
int SDL_N3DS_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects);
|
||||
void SDL_N3DS_DestroyWindowFramebuffer(_THIS, SDL_Window *window);
|
||||
|
||||
#endif /* SDL_n3dsframebuffer_c_h_ */
|
||||
|
||||
/* vi: set sts=4 ts=4 sw=4 expandtab: */
|
||||
@@ -18,21 +18,59 @@
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifndef SDL_naclopengles_h_
|
||||
#define SDL_naclopengles_h_
|
||||
#ifdef SDL_VIDEO_DRIVER_N3DS
|
||||
|
||||
extern int NACL_GLES_LoadLibrary(_THIS, const char *path);
|
||||
extern void *NACL_GLES_GetProcAddress(_THIS, const char *proc);
|
||||
extern void NACL_GLES_UnloadLibrary(_THIS);
|
||||
extern SDL_GLContext NACL_GLES_CreateContext(_THIS, SDL_Window * window);
|
||||
extern int NACL_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
|
||||
extern int NACL_GLES_SetSwapInterval(_THIS, int interval);
|
||||
extern int NACL_GLES_GetSwapInterval(_THIS);
|
||||
extern int NACL_GLES_SwapWindow(_THIS, SDL_Window * window);
|
||||
extern void NACL_GLES_DeleteContext(_THIS, SDL_GLContext context);
|
||||
#include <3ds.h>
|
||||
|
||||
#endif /* SDL_naclopengles_h_ */
|
||||
#include "SDL_n3dsswkb.h"
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
static SwkbdState sw_keyboard;
|
||||
const static size_t BUFFER_SIZE = 256;
|
||||
|
||||
void
|
||||
N3DS_SwkbInit()
|
||||
{
|
||||
swkbdInit(&sw_keyboard, SWKBD_TYPE_NORMAL, 2, -1);
|
||||
}
|
||||
|
||||
void
|
||||
N3DS_SwkbPoll()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
N3DS_SwkbQuit()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
N3DS_HasScreenKeyboardSupport(_THIS)
|
||||
{
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
N3DS_StartTextInput(_THIS)
|
||||
{
|
||||
char buffer[BUFFER_SIZE];
|
||||
SwkbdButton button_pressed;
|
||||
button_pressed = swkbdInputText(&sw_keyboard, buffer, BUFFER_SIZE);
|
||||
if (button_pressed == SWKBD_BUTTON_CONFIRM) {
|
||||
SDL_SendKeyboardText(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
N3DS_StopTextInput(_THIS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_N3DS */
|
||||
|
||||
/* vi: set sts=4 ts=4 sw=4 expandtab: */
|
||||
@@ -18,21 +18,21 @@
|
||||
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_PANDORA
|
||||
|
||||
/* Being a null driver, there's no event stream. We just define stubs for
|
||||
most of the API. */
|
||||
#ifndef SDL_n3dskeyboard_h_
|
||||
#define SDL_n3dskeyboard_h_
|
||||
|
||||
#include "../../events/SDL_events_c.h"
|
||||
|
||||
void
|
||||
PND_PumpEvents(_THIS)
|
||||
{
|
||||
/* Not implemented. */
|
||||
}
|
||||
void N3DS_SwkbInit();
|
||||
void N3DS_SwkbPoll();
|
||||
void N3DS_SwkbQuit();
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_PANDORA */
|
||||
SDL_bool N3DS_HasScreenKeyboardSupport(_THIS);
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
void N3DS_StartTextInput(_THIS);
|
||||
void N3DS_StopTextInput(_THIS);
|
||||
|
||||
#endif /* SDL_n3dskeyboard_h_ */
|
||||
|
||||
/* vi: set sts=4 ts=4 sw=4 expandtab: */
|
||||
84
src/video/n3ds/SDL_n3dstouch.c
Normal file
84
src/video/n3ds/SDL_n3dstouch.c
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_N3DS
|
||||
|
||||
#include <3ds.h>
|
||||
|
||||
#include "../../events/SDL_touch_c.h"
|
||||
#include "SDL_n3dstouch.h"
|
||||
|
||||
#define N3DS_TOUCH_ID 0
|
||||
|
||||
/*
|
||||
Factors used to convert touchscreen coordinates to
|
||||
SDL's 0-1 values. Note that the N3DS's screen is
|
||||
internally in a portrait disposition so the
|
||||
GSP_SCREEN constants are flipped.
|
||||
*/
|
||||
#define TOUCHSCREEN_SCALE_X 1.0f / GSP_SCREEN_HEIGHT_BOTTOM
|
||||
#define TOUCHSCREEN_SCALE_Y 1.0f / GSP_SCREEN_WIDTH
|
||||
|
||||
void
|
||||
N3DS_InitTouch(void)
|
||||
{
|
||||
SDL_AddTouch(N3DS_TOUCH_ID, SDL_TOUCH_DEVICE_DIRECT, "Touchscreen");
|
||||
}
|
||||
|
||||
void
|
||||
N3DS_QuitTouch(void)
|
||||
{
|
||||
SDL_DelTouch(N3DS_TOUCH_ID);
|
||||
}
|
||||
|
||||
void
|
||||
N3DS_PollTouch(void)
|
||||
{
|
||||
touchPosition touch;
|
||||
static SDL_bool was_pressed = SDL_FALSE;
|
||||
SDL_bool pressed;
|
||||
hidTouchRead(&touch);
|
||||
pressed = (touch.px != 0 || touch.py != 0);
|
||||
|
||||
if (pressed != was_pressed) {
|
||||
was_pressed = pressed;
|
||||
SDL_SendTouch(N3DS_TOUCH_ID,
|
||||
0,
|
||||
NULL,
|
||||
pressed,
|
||||
touch.px * TOUCHSCREEN_SCALE_X,
|
||||
touch.py * TOUCHSCREEN_SCALE_Y,
|
||||
pressed ? 1.0f : 0.0f);
|
||||
} else if (pressed) {
|
||||
SDL_SendTouchMotion(N3DS_TOUCH_ID,
|
||||
0,
|
||||
NULL,
|
||||
touch.px * TOUCHSCREEN_SCALE_X,
|
||||
touch.py * TOUCHSCREEN_SCALE_Y,
|
||||
1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_N3DS */
|
||||
|
||||
/* vi: set sts=4 ts=4 sw=4 expandtab: */
|
||||
@@ -19,7 +19,13 @@
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_n3dstouch_h_
|
||||
#define SDL_n3dstouch_h_
|
||||
|
||||
/* SDL surface based renderer implementation */
|
||||
void N3DS_InitTouch(void);
|
||||
void N3DS_QuitTouch(void);
|
||||
void N3DS_PollTouch(void);
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
#endif /* SDL_n3dstouch_h_ */
|
||||
|
||||
/* vi: set sts=4 ts=4 sw=4 expandtab: */
|
||||
196
src/video/n3ds/SDL_n3dsvideo.c
Normal file
196
src/video/n3ds/SDL_n3dsvideo.c
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_N3DS
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "SDL_n3dsevents_c.h"
|
||||
#include "SDL_n3dsframebuffer_c.h"
|
||||
#include "SDL_n3dsswkb.h"
|
||||
#include "SDL_n3dstouch.h"
|
||||
#include "SDL_n3dsvideo.h"
|
||||
|
||||
#define N3DSVID_DRIVER_NAME "n3ds"
|
||||
|
||||
SDL_FORCE_INLINE void AddN3DSDisplay(gfxScreen_t screen);
|
||||
|
||||
static int N3DS_VideoInit(_THIS);
|
||||
static void N3DS_VideoQuit(_THIS);
|
||||
static void N3DS_GetDisplayModes(_THIS, SDL_VideoDisplay *display);
|
||||
static int N3DS_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect);
|
||||
static int N3DS_CreateWindow(_THIS, SDL_Window *window);
|
||||
static void N3DS_DestroyWindow(_THIS, SDL_Window *window);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gfxScreen_t screen;
|
||||
} DisplayDriverData;
|
||||
|
||||
/* N3DS driver bootstrap functions */
|
||||
|
||||
static void
|
||||
N3DS_DeleteDevice(SDL_VideoDevice *device)
|
||||
{
|
||||
SDL_free(device->displays);
|
||||
SDL_free(device->driverdata);
|
||||
SDL_free(device);
|
||||
}
|
||||
|
||||
static SDL_VideoDevice *
|
||||
N3DS_CreateDevice(void)
|
||||
{
|
||||
SDL_VideoDevice *device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
|
||||
if (!device) {
|
||||
SDL_OutOfMemory();
|
||||
return (0);
|
||||
}
|
||||
|
||||
device->VideoInit = N3DS_VideoInit;
|
||||
device->VideoQuit = N3DS_VideoQuit;
|
||||
|
||||
device->GetDisplayModes = N3DS_GetDisplayModes;
|
||||
device->GetDisplayBounds = N3DS_GetDisplayBounds;
|
||||
|
||||
device->CreateSDLWindow = N3DS_CreateWindow;
|
||||
device->DestroyWindow = N3DS_DestroyWindow;
|
||||
|
||||
device->HasScreenKeyboardSupport = N3DS_HasScreenKeyboardSupport;
|
||||
device->StartTextInput = N3DS_StartTextInput;
|
||||
device->StopTextInput = N3DS_StopTextInput;
|
||||
|
||||
device->PumpEvents = N3DS_PumpEvents;
|
||||
|
||||
device->CreateWindowFramebuffer = SDL_N3DS_CreateWindowFramebuffer;
|
||||
device->UpdateWindowFramebuffer = SDL_N3DS_UpdateWindowFramebuffer;
|
||||
device->DestroyWindowFramebuffer = SDL_N3DS_DestroyWindowFramebuffer;
|
||||
|
||||
device->free = N3DS_DeleteDevice;
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
VideoBootStrap N3DS_bootstrap = { N3DSVID_DRIVER_NAME, "N3DS Video Driver", N3DS_CreateDevice };
|
||||
|
||||
static int
|
||||
N3DS_VideoInit(_THIS)
|
||||
{
|
||||
gfxInit(GSP_RGBA8_OES, GSP_RGBA8_OES, false);
|
||||
hidInit();
|
||||
|
||||
AddN3DSDisplay(GFX_TOP);
|
||||
AddN3DSDisplay(GFX_BOTTOM);
|
||||
|
||||
N3DS_InitTouch();
|
||||
N3DS_SwkbInit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_FORCE_INLINE void
|
||||
AddN3DSDisplay(gfxScreen_t screen)
|
||||
{
|
||||
SDL_DisplayMode mode;
|
||||
SDL_VideoDisplay display;
|
||||
DisplayDriverData *display_driver_data = SDL_calloc(1, sizeof(DisplayDriverData));
|
||||
if (display_driver_data == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_zero(mode);
|
||||
SDL_zero(display);
|
||||
|
||||
display_driver_data->screen = screen;
|
||||
|
||||
mode.w = (screen == GFX_TOP) ? GSP_SCREEN_HEIGHT_TOP : GSP_SCREEN_HEIGHT_BOTTOM;
|
||||
mode.h = GSP_SCREEN_WIDTH;
|
||||
mode.refresh_rate = 60;
|
||||
mode.format = FRAMEBUFFER_FORMAT;
|
||||
mode.driverdata = NULL;
|
||||
|
||||
display.name = (screen == GFX_TOP) ? "N3DS top screen" : "N3DS bottom screen";
|
||||
display.desktop_mode = mode;
|
||||
display.current_mode = mode;
|
||||
display.driverdata = display_driver_data;
|
||||
|
||||
SDL_AddVideoDisplay(&display, SDL_FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
N3DS_VideoQuit(_THIS)
|
||||
{
|
||||
N3DS_SwkbQuit();
|
||||
N3DS_QuitTouch();
|
||||
|
||||
hidExit();
|
||||
gfxExit();
|
||||
}
|
||||
|
||||
static void
|
||||
N3DS_GetDisplayModes(_THIS, SDL_VideoDisplay *display)
|
||||
{
|
||||
/* Each display only has a single mode */
|
||||
SDL_AddDisplayMode(display, &display->current_mode);
|
||||
}
|
||||
|
||||
static int
|
||||
N3DS_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect)
|
||||
{
|
||||
DisplayDriverData *driver_data = (DisplayDriverData *) display->driverdata;
|
||||
if (driver_data == NULL) {
|
||||
return -1;
|
||||
}
|
||||
rect->x = 0;
|
||||
rect->y = (driver_data->screen == GFX_TOP) ? 0 : GSP_SCREEN_WIDTH;
|
||||
rect->w = display->current_mode.w;
|
||||
rect->h = display->current_mode.h;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
N3DS_CreateWindow(_THIS, SDL_Window *window)
|
||||
{
|
||||
DisplayDriverData *display_data;
|
||||
SDL_WindowData *window_data = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
|
||||
if (window_data == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
display_data = (DisplayDriverData *) SDL_GetDisplayDriverData(window->display_index);
|
||||
window_data->screen = display_data->screen;
|
||||
window->driverdata = window_data;
|
||||
SDL_SetKeyboardFocus(window);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
N3DS_DestroyWindow(_THIS, SDL_Window *window)
|
||||
{
|
||||
if (window == NULL) {
|
||||
return;
|
||||
}
|
||||
SDL_free(window->driverdata);
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_N3DS */
|
||||
|
||||
/* vi: set sts=4 ts=4 sw=4 expandtab: */
|
||||
@@ -20,14 +20,19 @@
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifndef SDL_os2mouse_h_
|
||||
#define SDL_os2mouse_h_
|
||||
#ifndef SDL_n3dsvideo_h_
|
||||
#define SDL_n3dsvideo_h_
|
||||
|
||||
extern HPOINTER hptrCursor;
|
||||
#include <3ds.h>
|
||||
|
||||
extern void OS2_InitMouse(_THIS, ULONG hab);
|
||||
extern void OS2_QuitMouse(_THIS);
|
||||
#include "../SDL_sysvideo.h"
|
||||
typedef struct SDL_WindowData
|
||||
{
|
||||
gfxScreen_t screen; /**< Keeps track of which N3DS screen is targetted */
|
||||
} SDL_WindowData;
|
||||
|
||||
#endif /* SDL_os2mouse_h_ */
|
||||
#define FRAMEBUFFER_FORMAT SDL_PIXELFORMAT_RGBA8888
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
#endif /* SDL_n3dsvideo_h_ */
|
||||
|
||||
/* vi: set sts=4 ts=4 sw=4 expandtab: */
|
||||
@@ -1,438 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_NACL
|
||||
|
||||
#include "SDL.h"
|
||||
#include "../../events/SDL_events_c.h"
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "SDL_naclevents_c.h"
|
||||
#include "SDL_naclvideo.h"
|
||||
#include "ppapi_simple/ps_event.h"
|
||||
|
||||
/* Ref: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent */
|
||||
|
||||
static SDL_Scancode NACL_Keycodes[] = {
|
||||
SDL_SCANCODE_UNKNOWN, /* 0 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 1 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 2 */
|
||||
SDL_SCANCODE_CANCEL, /* DOM_VK_CANCEL 3 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 4 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 5 */
|
||||
SDL_SCANCODE_HELP, /* DOM_VK_HELP 6 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 7 */
|
||||
SDL_SCANCODE_BACKSPACE, /* DOM_VK_BACK_SPACE 8 */
|
||||
SDL_SCANCODE_TAB, /* DOM_VK_TAB 9 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 10 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 11 */
|
||||
SDL_SCANCODE_CLEAR, /* DOM_VK_CLEAR 12 */
|
||||
SDL_SCANCODE_RETURN, /* DOM_VK_RETURN 13 */
|
||||
SDL_SCANCODE_RETURN, /* DOM_VK_ENTER 14 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 15 */
|
||||
SDL_SCANCODE_LSHIFT, /* DOM_VK_SHIFT 16 */
|
||||
SDL_SCANCODE_LCTRL, /* DOM_VK_CONTROL 17 */
|
||||
SDL_SCANCODE_LALT, /* DOM_VK_ALT 18 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_PAUSE 19 */
|
||||
SDL_SCANCODE_CAPSLOCK, /* DOM_VK_CAPS_LOCK 20 */
|
||||
SDL_SCANCODE_LANG1, /* DOM_VK_KANA DOM_VK_HANGUL 21 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_EISU 22 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_JUNJA 23 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_FINAL 24 */
|
||||
SDL_SCANCODE_LANG2, /* DOM_VK_HANJA DOM_VK_KANJI 25 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 26 */
|
||||
SDL_SCANCODE_ESCAPE, /* DOM_VK_ESCAPE 27 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_CONVERT 28 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_NONCONVERT 29 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_ACCEPT 30 */
|
||||
SDL_SCANCODE_MODE, /* DOM_VK_MODECHANGE 31 */
|
||||
SDL_SCANCODE_SPACE, /* DOM_VK_SPACE 32 */
|
||||
SDL_SCANCODE_PAGEUP, /* DOM_VK_PAGE_UP 33 */
|
||||
SDL_SCANCODE_PAGEDOWN, /* DOM_VK_PAGE_DOWN 34 */
|
||||
SDL_SCANCODE_END, /* DOM_VK_END 35 */
|
||||
SDL_SCANCODE_HOME, /* DOM_VK_HOME 36 */
|
||||
SDL_SCANCODE_LEFT, /* DOM_VK_LEFT 37 */
|
||||
SDL_SCANCODE_UP, /* DOM_VK_UP 38 */
|
||||
SDL_SCANCODE_RIGHT, /* DOM_VK_RIGHT 39 */
|
||||
SDL_SCANCODE_DOWN, /* DOM_VK_DOWN 40 */
|
||||
SDL_SCANCODE_SELECT, /* DOM_VK_SELECT 41 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_PRINT 42 */
|
||||
SDL_SCANCODE_EXECUTE, /* DOM_VK_EXECUTE 43 */
|
||||
SDL_SCANCODE_PRINTSCREEN, /* DOM_VK_PRINTSCREEN 44 */
|
||||
SDL_SCANCODE_INSERT, /* DOM_VK_INSERT 45 */
|
||||
SDL_SCANCODE_DELETE, /* DOM_VK_DELETE 46 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 47 */
|
||||
SDL_SCANCODE_0, /* DOM_VK_0 48 */
|
||||
SDL_SCANCODE_1, /* DOM_VK_1 49 */
|
||||
SDL_SCANCODE_2, /* DOM_VK_2 50 */
|
||||
SDL_SCANCODE_3, /* DOM_VK_3 51 */
|
||||
SDL_SCANCODE_4, /* DOM_VK_4 52 */
|
||||
SDL_SCANCODE_5, /* DOM_VK_5 53 */
|
||||
SDL_SCANCODE_6, /* DOM_VK_6 54 */
|
||||
SDL_SCANCODE_7, /* DOM_VK_7 55 */
|
||||
SDL_SCANCODE_8, /* DOM_VK_8 56 */
|
||||
SDL_SCANCODE_9, /* DOM_VK_9 57 */
|
||||
SDL_SCANCODE_KP_COLON, /* DOM_VK_COLON 58 */
|
||||
SDL_SCANCODE_SEMICOLON, /* DOM_VK_SEMICOLON 59 */
|
||||
SDL_SCANCODE_KP_LESS, /* DOM_VK_LESS_THAN 60 */
|
||||
SDL_SCANCODE_EQUALS, /* DOM_VK_EQUALS 61 */
|
||||
SDL_SCANCODE_KP_GREATER, /* DOM_VK_GREATER_THAN 62 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_QUESTION_MARK 63 */
|
||||
SDL_SCANCODE_KP_AT, /* DOM_VK_AT 64 */
|
||||
SDL_SCANCODE_A, /* DOM_VK_A 65 */
|
||||
SDL_SCANCODE_B, /* DOM_VK_B 66 */
|
||||
SDL_SCANCODE_C, /* DOM_VK_C 67 */
|
||||
SDL_SCANCODE_D, /* DOM_VK_D 68 */
|
||||
SDL_SCANCODE_E, /* DOM_VK_E 69 */
|
||||
SDL_SCANCODE_F, /* DOM_VK_F 70 */
|
||||
SDL_SCANCODE_G, /* DOM_VK_G 71 */
|
||||
SDL_SCANCODE_H, /* DOM_VK_H 72 */
|
||||
SDL_SCANCODE_I, /* DOM_VK_I 73 */
|
||||
SDL_SCANCODE_J, /* DOM_VK_J 74 */
|
||||
SDL_SCANCODE_K, /* DOM_VK_K 75 */
|
||||
SDL_SCANCODE_L, /* DOM_VK_L 76 */
|
||||
SDL_SCANCODE_M, /* DOM_VK_M 77 */
|
||||
SDL_SCANCODE_N, /* DOM_VK_N 78 */
|
||||
SDL_SCANCODE_O, /* DOM_VK_O 79 */
|
||||
SDL_SCANCODE_P, /* DOM_VK_P 80 */
|
||||
SDL_SCANCODE_Q, /* DOM_VK_Q 81 */
|
||||
SDL_SCANCODE_R, /* DOM_VK_R 82 */
|
||||
SDL_SCANCODE_S, /* DOM_VK_S 83 */
|
||||
SDL_SCANCODE_T, /* DOM_VK_T 84 */
|
||||
SDL_SCANCODE_U, /* DOM_VK_U 85 */
|
||||
SDL_SCANCODE_V, /* DOM_VK_V 86 */
|
||||
SDL_SCANCODE_W, /* DOM_VK_W 87 */
|
||||
SDL_SCANCODE_X, /* DOM_VK_X 88 */
|
||||
SDL_SCANCODE_Y, /* DOM_VK_Y 89 */
|
||||
SDL_SCANCODE_Z, /* DOM_VK_Z 90 */
|
||||
SDL_SCANCODE_LGUI, /* DOM_VK_WIN 91 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 92 */
|
||||
SDL_SCANCODE_APPLICATION, /* DOM_VK_CONTEXT_MENU 93 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 94 */
|
||||
SDL_SCANCODE_SLEEP, /* DOM_VK_SLEEP 95 */
|
||||
SDL_SCANCODE_KP_0, /* DOM_VK_NUMPAD0 96 */
|
||||
SDL_SCANCODE_KP_1, /* DOM_VK_NUMPAD1 97 */
|
||||
SDL_SCANCODE_KP_2, /* DOM_VK_NUMPAD2 98 */
|
||||
SDL_SCANCODE_KP_3, /* DOM_VK_NUMPAD3 99 */
|
||||
SDL_SCANCODE_KP_4, /* DOM_VK_NUMPAD4 100 */
|
||||
SDL_SCANCODE_KP_5, /* DOM_VK_NUMPAD5 101 */
|
||||
SDL_SCANCODE_KP_6, /* DOM_VK_NUMPAD6 102 */
|
||||
SDL_SCANCODE_KP_7, /* DOM_VK_NUMPAD7 103 */
|
||||
SDL_SCANCODE_KP_8, /* DOM_VK_NUMPAD8 104 */
|
||||
SDL_SCANCODE_KP_9, /* DOM_VK_NUMPAD9 105 */
|
||||
SDL_SCANCODE_KP_MULTIPLY, /* DOM_VK_MULTIPLY 106 */
|
||||
SDL_SCANCODE_KP_PLUS, /* DOM_VK_ADD 107 */
|
||||
SDL_SCANCODE_KP_COMMA, /* DOM_VK_SEPARATOR 108 */
|
||||
SDL_SCANCODE_KP_MINUS, /* DOM_VK_SUBTRACT 109 */
|
||||
SDL_SCANCODE_KP_PERIOD, /* DOM_VK_DECIMAL 110 */
|
||||
SDL_SCANCODE_KP_DIVIDE, /* DOM_VK_DIVIDE 111 */
|
||||
SDL_SCANCODE_F1, /* DOM_VK_F1 112 */
|
||||
SDL_SCANCODE_F2, /* DOM_VK_F2 113 */
|
||||
SDL_SCANCODE_F3, /* DOM_VK_F3 114 */
|
||||
SDL_SCANCODE_F4, /* DOM_VK_F4 115 */
|
||||
SDL_SCANCODE_F5, /* DOM_VK_F5 116 */
|
||||
SDL_SCANCODE_F6, /* DOM_VK_F6 117 */
|
||||
SDL_SCANCODE_F7, /* DOM_VK_F7 118 */
|
||||
SDL_SCANCODE_F8, /* DOM_VK_F8 119 */
|
||||
SDL_SCANCODE_F9, /* DOM_VK_F9 120 */
|
||||
SDL_SCANCODE_F10, /* DOM_VK_F10 121 */
|
||||
SDL_SCANCODE_F11, /* DOM_VK_F11 122 */
|
||||
SDL_SCANCODE_F12, /* DOM_VK_F12 123 */
|
||||
SDL_SCANCODE_F13, /* DOM_VK_F13 124 */
|
||||
SDL_SCANCODE_F14, /* DOM_VK_F14 125 */
|
||||
SDL_SCANCODE_F15, /* DOM_VK_F15 126 */
|
||||
SDL_SCANCODE_F16, /* DOM_VK_F16 127 */
|
||||
SDL_SCANCODE_F17, /* DOM_VK_F17 128 */
|
||||
SDL_SCANCODE_F18, /* DOM_VK_F18 129 */
|
||||
SDL_SCANCODE_F19, /* DOM_VK_F19 130 */
|
||||
SDL_SCANCODE_F20, /* DOM_VK_F20 131 */
|
||||
SDL_SCANCODE_F21, /* DOM_VK_F21 132 */
|
||||
SDL_SCANCODE_F22, /* DOM_VK_F22 133 */
|
||||
SDL_SCANCODE_F23, /* DOM_VK_F23 134 */
|
||||
SDL_SCANCODE_F24, /* DOM_VK_F24 135 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 136 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 137 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 138 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 139 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 140 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 141 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 142 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 143 */
|
||||
SDL_SCANCODE_NUMLOCKCLEAR, /* DOM_VK_NUM_LOCK 144 */
|
||||
SDL_SCANCODE_SCROLLLOCK, /* DOM_VK_SCROLL_LOCK 145 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_FJ_JISHO 146 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_FJ_MASSHOU 147 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_FJ_TOUROKU 148 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_FJ_LOYA 149 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_FJ_ROYA 150 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 151 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 152 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 153 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 154 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 155 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 156 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 157 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 158 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 159 */
|
||||
SDL_SCANCODE_GRAVE, /* DOM_VK_CIRCUMFLEX 160 */
|
||||
SDL_SCANCODE_KP_EXCLAM, /* DOM_VK_EXCLAMATION 161 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_DOUBLE_QUOTE 162 */
|
||||
SDL_SCANCODE_KP_HASH, /* DOM_VK_HASH 163 */
|
||||
SDL_SCANCODE_CURRENCYUNIT, /* DOM_VK_DOLLAR 164 */
|
||||
SDL_SCANCODE_KP_PERCENT, /* DOM_VK_PERCENT 165 */
|
||||
SDL_SCANCODE_KP_AMPERSAND, /* DOM_VK_AMPERSAND 166 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_UNDERSCORE 167 */
|
||||
SDL_SCANCODE_KP_LEFTPAREN, /* DOM_VK_OPEN_PAREN 168 */
|
||||
SDL_SCANCODE_KP_RIGHTPAREN, /* DOM_VK_CLOSE_PAREN 169 */
|
||||
SDL_SCANCODE_KP_MULTIPLY, /* DOM_VK_ASTERISK 170 */
|
||||
SDL_SCANCODE_KP_PLUS, /* DOM_VK_PLUS 171 */
|
||||
SDL_SCANCODE_KP_PLUS, /* DOM_VK_PIPE 172 */
|
||||
SDL_SCANCODE_MINUS, /* DOM_VK_HYPHEN_MINUS 173 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_OPEN_CURLY_BRACKET 174 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_CLOSE_CURLY_BRACKET 175 */
|
||||
SDL_SCANCODE_NONUSBACKSLASH, /* DOM_VK_TILDE 176 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 177 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 178 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 179 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 180 */
|
||||
SDL_SCANCODE_MUTE, /* DOM_VK_VOLUME_MUTE 181 */
|
||||
SDL_SCANCODE_VOLUMEDOWN, /* DOM_VK_VOLUME_DOWN 182 */
|
||||
SDL_SCANCODE_VOLUMEUP, /* DOM_VK_VOLUME_UP 183 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 184 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 185 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 186 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 187 */
|
||||
SDL_SCANCODE_COMMA, /* DOM_VK_COMMA 188 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 189 */
|
||||
SDL_SCANCODE_PERIOD, /* DOM_VK_PERIOD 190 */
|
||||
SDL_SCANCODE_SLASH, /* DOM_VK_SLASH 191 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_BACK_QUOTE 192 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 193 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 194 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 195 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 196 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 197 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 198 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 199 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 200 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 201 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 202 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 203 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 204 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 205 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 206 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 207 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 208 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 209 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 210 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 211 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 212 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 213 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 214 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 215 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 216 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 217 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 218 */
|
||||
SDL_SCANCODE_LEFTBRACKET, /* DOM_VK_OPEN_BRACKET 219 */
|
||||
SDL_SCANCODE_BACKSLASH, /* DOM_VK_BACK_SLASH 220 */
|
||||
SDL_SCANCODE_RIGHTBRACKET, /* DOM_VK_CLOSE_BRACKET 221 */
|
||||
SDL_SCANCODE_APOSTROPHE, /* DOM_VK_QUOTE 222 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 223 */
|
||||
SDL_SCANCODE_RGUI, /* DOM_VK_META 224 */
|
||||
SDL_SCANCODE_RALT, /* DOM_VK_ALTGR 225 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 226 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_ICO_HELP 227 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_ICO_00 228 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 229 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_ICO_CLEAR 230 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 231 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 232 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_RESET 233 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_JUMP 234 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_PA1 235 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_PA2 236 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_PA3 237 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_WSCTRL 238 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_CUSEL 239 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_ATTN 240 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_FINISH 241 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_COPY 242 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_AUTO 243 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_ENLW 244 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_BACKTAB 245 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_ATTN 246 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_CRSEL 247 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_EXSEL 248 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_EREOF 249 */
|
||||
SDL_SCANCODE_AUDIOPLAY, /* DOM_VK_PLAY 250 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_ZOOM 251 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 252 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_PA1 253 */
|
||||
SDL_SCANCODE_UNKNOWN, /* DOM_VK_WIN_OEM_CLEAR 254 */
|
||||
SDL_SCANCODE_UNKNOWN, /* 255 */
|
||||
};
|
||||
|
||||
static Uint8 SDL_NACL_translate_mouse_button(int32_t button) {
|
||||
switch (button) {
|
||||
case PP_INPUTEVENT_MOUSEBUTTON_LEFT:
|
||||
return SDL_BUTTON_LEFT;
|
||||
case PP_INPUTEVENT_MOUSEBUTTON_MIDDLE:
|
||||
return SDL_BUTTON_MIDDLE;
|
||||
case PP_INPUTEVENT_MOUSEBUTTON_RIGHT:
|
||||
return SDL_BUTTON_RIGHT;
|
||||
|
||||
case PP_INPUTEVENT_MOUSEBUTTON_NONE:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_Scancode
|
||||
SDL_NACL_translate_keycode(int keycode)
|
||||
{
|
||||
SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN;
|
||||
|
||||
if (keycode < SDL_arraysize(NACL_Keycodes)) {
|
||||
scancode = NACL_Keycodes[keycode];
|
||||
}
|
||||
if (scancode == SDL_SCANCODE_UNKNOWN) {
|
||||
SDL_Log("The key you just pressed is not recognized by SDL. To help get this fixed, please report this to the SDL forums/mailing list <https://discourse.libsdl.org/> NACL KeyCode %d", keycode);
|
||||
}
|
||||
return scancode;
|
||||
}
|
||||
|
||||
void NACL_PumpEvents(_THIS) {
|
||||
PSEvent* ps_event;
|
||||
PP_Resource event;
|
||||
PP_InputEvent_Type type;
|
||||
PP_InputEvent_Modifier modifiers;
|
||||
struct PP_Rect rect;
|
||||
struct PP_FloatPoint fp;
|
||||
struct PP_Point location;
|
||||
struct PP_Var var;
|
||||
const char *str;
|
||||
char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
|
||||
Uint32 str_len;
|
||||
SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata;
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
|
||||
if (driverdata->window) {
|
||||
while ((ps_event = PSEventTryAcquire()) != NULL) {
|
||||
event = ps_event->as_resource;
|
||||
switch(ps_event->type) {
|
||||
/* From DidChangeView, contains a view resource */
|
||||
case PSE_INSTANCE_DIDCHANGEVIEW:
|
||||
driverdata->ppb_view->GetRect(event, &rect);
|
||||
NACL_SetScreenResolution(rect.size.width, rect.size.height, SDL_PIXELFORMAT_UNKNOWN);
|
||||
// FIXME: Rebuild context? See life.c UpdateContext
|
||||
break;
|
||||
|
||||
/* From HandleInputEvent, contains an input resource. */
|
||||
case PSE_INSTANCE_HANDLEINPUT:
|
||||
type = driverdata->ppb_input_event->GetType(event);
|
||||
modifiers = driverdata->ppb_input_event->GetModifiers(event);
|
||||
switch(type) {
|
||||
case PP_INPUTEVENT_TYPE_MOUSEDOWN:
|
||||
SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_PRESSED, SDL_NACL_translate_mouse_button(driverdata->ppb_mouse_input_event->GetButton(event)));
|
||||
break;
|
||||
case PP_INPUTEVENT_TYPE_MOUSEUP:
|
||||
SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_RELEASED, SDL_NACL_translate_mouse_button(driverdata->ppb_mouse_input_event->GetButton(event)));
|
||||
break;
|
||||
case PP_INPUTEVENT_TYPE_WHEEL:
|
||||
/* FIXME: GetTicks provides high resolution scroll events */
|
||||
fp = driverdata->ppb_wheel_input_event->GetDelta(event);
|
||||
SDL_SendMouseWheel(mouse->focus, mouse->mouseID, fp.x, fp.y, SDL_MOUSEWHEEL_NORMAL);
|
||||
break;
|
||||
|
||||
case PP_INPUTEVENT_TYPE_MOUSEENTER:
|
||||
case PP_INPUTEVENT_TYPE_MOUSELEAVE:
|
||||
/* FIXME: Mouse Focus */
|
||||
break;
|
||||
|
||||
|
||||
case PP_INPUTEVENT_TYPE_MOUSEMOVE:
|
||||
location = driverdata->ppb_mouse_input_event->GetPosition(event);
|
||||
SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_FALSE, location.x, location.y);
|
||||
break;
|
||||
|
||||
case PP_INPUTEVENT_TYPE_TOUCHSTART:
|
||||
case PP_INPUTEVENT_TYPE_TOUCHMOVE:
|
||||
case PP_INPUTEVENT_TYPE_TOUCHEND:
|
||||
case PP_INPUTEVENT_TYPE_TOUCHCANCEL:
|
||||
/* FIXME: Touch events */
|
||||
break;
|
||||
|
||||
case PP_INPUTEVENT_TYPE_KEYDOWN:
|
||||
SDL_SendKeyboardKey(SDL_PRESSED, SDL_NACL_translate_keycode(driverdata->ppb_keyboard_input_event->GetKeyCode(event)));
|
||||
break;
|
||||
|
||||
case PP_INPUTEVENT_TYPE_KEYUP:
|
||||
SDL_SendKeyboardKey(SDL_RELEASED, SDL_NACL_translate_keycode(driverdata->ppb_keyboard_input_event->GetKeyCode(event)));
|
||||
break;
|
||||
|
||||
case PP_INPUTEVENT_TYPE_CHAR:
|
||||
var = driverdata->ppb_keyboard_input_event->GetCharacterText(event);
|
||||
str = driverdata->ppb_var->VarToUtf8(var, &str_len);
|
||||
/* str is not null terminated! */
|
||||
if ( str_len >= SDL_arraysize(text) ) {
|
||||
str_len = SDL_arraysize(text) - 1;
|
||||
}
|
||||
SDL_strlcpy(text, str, str_len );
|
||||
text[str_len] = '\0';
|
||||
|
||||
SDL_SendKeyboardText(text);
|
||||
/* FIXME: Do we have to handle ref counting? driverdata->ppb_var->Release(var);*/
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
/* From HandleMessage, contains a PP_Var. */
|
||||
case PSE_INSTANCE_HANDLEMESSAGE:
|
||||
break;
|
||||
|
||||
/* From DidChangeFocus, contains a PP_Bool with the current focus state. */
|
||||
case PSE_INSTANCE_DIDCHANGEFOCUS:
|
||||
break;
|
||||
|
||||
/* When the 3D context is lost, no resource. */
|
||||
case PSE_GRAPHICS3D_GRAPHICS3DCONTEXTLOST:
|
||||
break;
|
||||
|
||||
/* When the mouse lock is lost. */
|
||||
case PSE_MOUSELOCK_MOUSELOCKLOST:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
PSEventRelease(ps_event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_NACL */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_NACL
|
||||
#endif /* SDL_VIDEO_DRIVER_NACL */
|
||||
@@ -1,174 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_NACL
|
||||
|
||||
/* NaCl SDL video GLES 2 driver implementation */
|
||||
|
||||
#include "SDL_video.h"
|
||||
#include "SDL_naclvideo.h"
|
||||
|
||||
#ifdef HAVE_DLOPEN
|
||||
#include "dlfcn.h"
|
||||
#endif
|
||||
|
||||
#include "ppapi/gles2/gl2ext_ppapi.h"
|
||||
#include "ppapi_simple/ps.h"
|
||||
|
||||
/* GL functions */
|
||||
int
|
||||
NACL_GLES_LoadLibrary(_THIS, const char *path)
|
||||
{
|
||||
/* FIXME: Support dynamic linking when PNACL supports it */
|
||||
return glInitializePPAPI(PSGetInterface) == 0;
|
||||
}
|
||||
|
||||
void *
|
||||
NACL_GLES_GetProcAddress(_THIS, const char *proc)
|
||||
{
|
||||
#ifdef HAVE_DLOPEN
|
||||
return dlsym( 0 /* RTLD_DEFAULT */, proc);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
NACL_GLES_UnloadLibrary(_THIS)
|
||||
{
|
||||
/* FIXME: Support dynamic linking when PNACL supports it */
|
||||
glTerminatePPAPI();
|
||||
}
|
||||
|
||||
int
|
||||
NACL_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext sdl_context)
|
||||
{
|
||||
SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata;
|
||||
/* FIXME: Check threading issues...otherwise use a hardcoded _this->context across all threads */
|
||||
driverdata->ppb_instance->BindGraphics(driverdata->instance, (PP_Resource) sdl_context);
|
||||
glSetCurrentContextPPAPI((PP_Resource) sdl_context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_GLContext
|
||||
NACL_GLES_CreateContext(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata;
|
||||
PP_Resource context, share_context = 0;
|
||||
/* 64 seems nice. */
|
||||
Sint32 attribs[64];
|
||||
int i = 0;
|
||||
|
||||
if (_this->gl_config.share_with_current_context) {
|
||||
share_context = (PP_Resource) SDL_GL_GetCurrentContext();
|
||||
}
|
||||
|
||||
/* FIXME: Some ATTRIBS from PP_Graphics3DAttrib are not set here */
|
||||
|
||||
attribs[i++] = PP_GRAPHICS3DATTRIB_WIDTH;
|
||||
attribs[i++] = window->w;
|
||||
attribs[i++] = PP_GRAPHICS3DATTRIB_HEIGHT;
|
||||
attribs[i++] = window->h;
|
||||
attribs[i++] = PP_GRAPHICS3DATTRIB_RED_SIZE;
|
||||
attribs[i++] = _this->gl_config.red_size;
|
||||
attribs[i++] = PP_GRAPHICS3DATTRIB_GREEN_SIZE;
|
||||
attribs[i++] = _this->gl_config.green_size;
|
||||
attribs[i++] = PP_GRAPHICS3DATTRIB_BLUE_SIZE;
|
||||
attribs[i++] = _this->gl_config.blue_size;
|
||||
|
||||
if (_this->gl_config.alpha_size) {
|
||||
attribs[i++] = PP_GRAPHICS3DATTRIB_ALPHA_SIZE;
|
||||
attribs[i++] = _this->gl_config.alpha_size;
|
||||
}
|
||||
|
||||
/*if (_this->gl_config.buffer_size) {
|
||||
attribs[i++] = EGL_BUFFER_SIZE;
|
||||
attribs[i++] = _this->gl_config.buffer_size;
|
||||
}*/
|
||||
|
||||
attribs[i++] = PP_GRAPHICS3DATTRIB_DEPTH_SIZE;
|
||||
attribs[i++] = _this->gl_config.depth_size;
|
||||
|
||||
if (_this->gl_config.stencil_size) {
|
||||
attribs[i++] = PP_GRAPHICS3DATTRIB_STENCIL_SIZE;
|
||||
attribs[i++] = _this->gl_config.stencil_size;
|
||||
}
|
||||
|
||||
if (_this->gl_config.multisamplebuffers) {
|
||||
attribs[i++] = PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS;
|
||||
attribs[i++] = _this->gl_config.multisamplebuffers;
|
||||
}
|
||||
|
||||
if (_this->gl_config.multisamplesamples) {
|
||||
attribs[i++] = PP_GRAPHICS3DATTRIB_SAMPLES;
|
||||
attribs[i++] = _this->gl_config.multisamplesamples;
|
||||
}
|
||||
|
||||
attribs[i++] = PP_GRAPHICS3DATTRIB_NONE;
|
||||
|
||||
context = driverdata->ppb_graphics->Create(driverdata->instance, share_context, attribs);
|
||||
|
||||
if (context) {
|
||||
/* We need to make the context current, otherwise nothing works */
|
||||
SDL_GL_MakeCurrent(window, (SDL_GLContext) context);
|
||||
}
|
||||
|
||||
return (SDL_GLContext) context;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
NACL_GLES_SetSwapInterval(_THIS, int interval)
|
||||
{
|
||||
/* STUB */
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
int
|
||||
NACL_GLES_GetSwapInterval(_THIS)
|
||||
{
|
||||
/* STUB */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
NACL_GLES_SwapWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata;
|
||||
struct PP_CompletionCallback callback = { NULL, 0, PP_COMPLETIONCALLBACK_FLAG_NONE };
|
||||
if (driverdata->ppb_graphics->SwapBuffers((PP_Resource) SDL_GL_GetCurrentContext(), callback ) != 0) {
|
||||
return SDL_SetError("SwapBuffers failed");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
NACL_GLES_DeleteContext(_THIS, SDL_GLContext context)
|
||||
{
|
||||
SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata;
|
||||
driverdata->ppb_core->ReleaseResource((PP_Resource) context);
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_NACL */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,187 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_NACL
|
||||
|
||||
#include "ppapi/c/pp_errors.h"
|
||||
#include "ppapi/c/pp_instance.h"
|
||||
#include "ppapi_simple/ps.h"
|
||||
#include "ppapi_simple/ps_interface.h"
|
||||
#include "ppapi_simple/ps_event.h"
|
||||
#include "nacl_io/nacl_io.h"
|
||||
|
||||
#include "SDL_naclvideo.h"
|
||||
#include "SDL_naclwindow.h"
|
||||
#include "SDL_naclevents_c.h"
|
||||
#include "SDL_naclopengles.h"
|
||||
#include "SDL_video.h"
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "../../events/SDL_events_c.h"
|
||||
|
||||
#define NACLVID_DRIVER_NAME "nacl"
|
||||
|
||||
/* Static init required because NACL_SetScreenResolution
|
||||
* may appear even before SDL starts and we want to remember
|
||||
* the window width and height
|
||||
*/
|
||||
static SDL_VideoData nacl = {0};
|
||||
|
||||
void
|
||||
NACL_SetScreenResolution(int width, int height, Uint32 format)
|
||||
{
|
||||
PP_Resource context;
|
||||
|
||||
nacl.w = width;
|
||||
nacl.h = height;
|
||||
nacl.format = format;
|
||||
|
||||
if (nacl.window) {
|
||||
nacl.window->w = width;
|
||||
nacl.window->h = height;
|
||||
SDL_SendWindowEvent(nacl.window, SDL_WINDOWEVENT_RESIZED, width, height);
|
||||
}
|
||||
|
||||
/* FIXME: Check threading issues...otherwise use a hardcoded _this->context across all threads */
|
||||
context = (PP_Resource) SDL_GL_GetCurrentContext();
|
||||
if (context) {
|
||||
PSInterfaceGraphics3D()->ResizeBuffers(context, width, height);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Initialization/Query functions */
|
||||
static int NACL_VideoInit(_THIS);
|
||||
static void NACL_VideoQuit(_THIS);
|
||||
|
||||
static int NACL_Available(void) {
|
||||
return PSGetInstanceId() != 0;
|
||||
}
|
||||
|
||||
static void NACL_DeleteDevice(SDL_VideoDevice *device) {
|
||||
SDL_VideoData *driverdata = (SDL_VideoData*) device->driverdata;
|
||||
driverdata->ppb_core->ReleaseResource((PP_Resource) driverdata->ppb_message_loop);
|
||||
/* device->driverdata is not freed because it points to static memory */
|
||||
SDL_free(device);
|
||||
}
|
||||
|
||||
static int
|
||||
NACL_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SDL_VideoDevice *NACL_CreateDevice(void) {
|
||||
SDL_VideoDevice *device;
|
||||
|
||||
if (!NACL_Available()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
|
||||
if (!device) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
device->driverdata = &nacl;
|
||||
|
||||
/* Set the function pointers */
|
||||
device->VideoInit = NACL_VideoInit;
|
||||
device->VideoQuit = NACL_VideoQuit;
|
||||
device->PumpEvents = NACL_PumpEvents;
|
||||
|
||||
device->CreateSDLWindow = NACL_CreateWindow;
|
||||
device->SetWindowTitle = NACL_SetWindowTitle;
|
||||
device->DestroyWindow = NACL_DestroyWindow;
|
||||
|
||||
device->SetDisplayMode = NACL_SetDisplayMode;
|
||||
|
||||
device->free = NACL_DeleteDevice;
|
||||
|
||||
/* GL pointers */
|
||||
device->GL_LoadLibrary = NACL_GLES_LoadLibrary;
|
||||
device->GL_GetProcAddress = NACL_GLES_GetProcAddress;
|
||||
device->GL_UnloadLibrary = NACL_GLES_UnloadLibrary;
|
||||
device->GL_CreateContext = NACL_GLES_CreateContext;
|
||||
device->GL_MakeCurrent = NACL_GLES_MakeCurrent;
|
||||
device->GL_SetSwapInterval = NACL_GLES_SetSwapInterval;
|
||||
device->GL_GetSwapInterval = NACL_GLES_GetSwapInterval;
|
||||
device->GL_SwapWindow = NACL_GLES_SwapWindow;
|
||||
device->GL_DeleteContext = NACL_GLES_DeleteContext;
|
||||
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
VideoBootStrap NACL_bootstrap = {
|
||||
NACLVID_DRIVER_NAME, "SDL Native Client Video Driver",
|
||||
NACL_CreateDevice
|
||||
};
|
||||
|
||||
int NACL_VideoInit(_THIS) {
|
||||
SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata;
|
||||
SDL_DisplayMode mode;
|
||||
|
||||
SDL_zero(mode);
|
||||
mode.format = driverdata->format;
|
||||
mode.w = driverdata->w;
|
||||
mode.h = driverdata->h;
|
||||
mode.refresh_rate = 0;
|
||||
mode.driverdata = NULL;
|
||||
if (SDL_AddBasicVideoDisplay(&mode) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_AddDisplayMode(&_this->displays[0], &mode);
|
||||
|
||||
PSInterfaceInit();
|
||||
driverdata->instance = PSGetInstanceId();
|
||||
driverdata->ppb_graphics = PSInterfaceGraphics3D();
|
||||
driverdata->ppb_message_loop = PSInterfaceMessageLoop();
|
||||
driverdata->ppb_core = PSInterfaceCore();
|
||||
driverdata->ppb_fullscreen = PSInterfaceFullscreen();
|
||||
driverdata->ppb_instance = PSInterfaceInstance();
|
||||
driverdata->ppb_image_data = PSInterfaceImageData();
|
||||
driverdata->ppb_view = PSInterfaceView();
|
||||
driverdata->ppb_var = PSInterfaceVar();
|
||||
driverdata->ppb_input_event = (PPB_InputEvent*) PSGetInterface(PPB_INPUT_EVENT_INTERFACE);
|
||||
driverdata->ppb_keyboard_input_event = (PPB_KeyboardInputEvent*) PSGetInterface(PPB_KEYBOARD_INPUT_EVENT_INTERFACE);
|
||||
driverdata->ppb_mouse_input_event = (PPB_MouseInputEvent*) PSGetInterface(PPB_MOUSE_INPUT_EVENT_INTERFACE);
|
||||
driverdata->ppb_wheel_input_event = (PPB_WheelInputEvent*) PSGetInterface(PPB_WHEEL_INPUT_EVENT_INTERFACE);
|
||||
driverdata->ppb_touch_input_event = (PPB_TouchInputEvent*) PSGetInterface(PPB_TOUCH_INPUT_EVENT_INTERFACE);
|
||||
|
||||
|
||||
driverdata->message_loop = driverdata->ppb_message_loop->Create(driverdata->instance);
|
||||
|
||||
PSEventSetFilter(PSE_ALL);
|
||||
|
||||
/* We're done! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NACL_VideoQuit(_THIS) {
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_NACL */
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifndef SDL_naclvideo_h_
|
||||
#define SDL_naclvideo_h_
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "ppapi_simple/ps_interface.h"
|
||||
#include "ppapi/c/pp_input_event.h"
|
||||
|
||||
|
||||
/* Hidden "this" pointer for the video functions */
|
||||
#define _THIS SDL_VideoDevice *_this
|
||||
|
||||
|
||||
/* Private display data */
|
||||
|
||||
typedef struct SDL_VideoData {
|
||||
Uint32 format;
|
||||
int w, h;
|
||||
SDL_Window *window;
|
||||
|
||||
const PPB_Graphics3D *ppb_graphics;
|
||||
const PPB_MessageLoop *ppb_message_loop;
|
||||
const PPB_Core *ppb_core;
|
||||
const PPB_Fullscreen *ppb_fullscreen;
|
||||
const PPB_Instance *ppb_instance;
|
||||
const PPB_ImageData *ppb_image_data;
|
||||
const PPB_View *ppb_view;
|
||||
const PPB_Var *ppb_var;
|
||||
const PPB_InputEvent *ppb_input_event;
|
||||
const PPB_KeyboardInputEvent *ppb_keyboard_input_event;
|
||||
const PPB_MouseInputEvent *ppb_mouse_input_event;
|
||||
const PPB_WheelInputEvent *ppb_wheel_input_event;
|
||||
const PPB_TouchInputEvent *ppb_touch_input_event;
|
||||
|
||||
PP_Resource message_loop;
|
||||
PP_Instance instance;
|
||||
|
||||
/* FIXME: Check threading issues...otherwise use a hardcoded _this->context across all threads */
|
||||
/* PP_Resource context; */
|
||||
|
||||
} SDL_VideoData;
|
||||
|
||||
extern void NACL_SetScreenResolution(int width, int height, Uint32 format);
|
||||
|
||||
|
||||
#endif /* SDL_naclvideo_h_ */
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_NACL
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
|
||||
#include "../../events/SDL_mouse_c.h"
|
||||
#include "../../events/SDL_keyboard_c.h"
|
||||
#include "SDL_naclvideo.h"
|
||||
#include "SDL_naclwindow.h"
|
||||
|
||||
int
|
||||
NACL_CreateWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata;
|
||||
|
||||
if (driverdata->window) {
|
||||
return SDL_SetError("NaCl only supports one window");
|
||||
}
|
||||
driverdata->window = window;
|
||||
|
||||
/* Adjust the window data to match the screen */
|
||||
window->x = 0;
|
||||
window->y = 0;
|
||||
window->w = driverdata->w;
|
||||
window->h = driverdata->h;
|
||||
|
||||
window->flags &= ~SDL_WINDOW_RESIZABLE; /* window is NEVER resizeable */
|
||||
window->flags |= SDL_WINDOW_FULLSCREEN; /* window is always fullscreen */
|
||||
window->flags &= ~SDL_WINDOW_HIDDEN;
|
||||
window->flags |= SDL_WINDOW_SHOWN; /* only one window on NaCl */
|
||||
window->flags |= SDL_WINDOW_INPUT_FOCUS; /* always has input focus */
|
||||
window->flags |= SDL_WINDOW_OPENGL;
|
||||
|
||||
SDL_SetMouseFocus(window);
|
||||
SDL_SetKeyboardFocus(window);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
NACL_SetWindowTitle(_THIS, SDL_Window * window)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void
|
||||
NACL_DestroyWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata;
|
||||
if (window == driverdata->window) {
|
||||
driverdata->window = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_NACL */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -220,10 +220,9 @@ void DirectDraw(_THIS, int numrects, SDL_Rect *rects, TUint16* screenBuffer)
|
||||
|
||||
TInt i;
|
||||
|
||||
//const TInt sourceNumBytesPerPixel = ((screen->format->BitsPerPixel-1) >> 3) + 1;
|
||||
TDisplayMode displayMode = phdata->NGAGE_DisplayMode;
|
||||
const TInt sourceNumBytesPerPixel = ((GetBpp(displayMode)-1) / 8) + 1;
|
||||
//
|
||||
|
||||
const TPoint fixedOffset = phdata->NGAGE_ScreenOffset;
|
||||
const TInt screenW = screen->w;
|
||||
const TInt screenH = screen->h;
|
||||
@@ -383,7 +382,6 @@ void DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
|
||||
DirectDraw(_this, numrects, rects, screenBuffer);
|
||||
}
|
||||
|
||||
//TRect rect2 = TRect(phdata->NGAGE_WsWindow.Size());
|
||||
for (int i = 0; i < numrects; ++i)
|
||||
{
|
||||
TInt aAx = rects[i].x;
|
||||
|
||||
@@ -30,7 +30,16 @@
|
||||
#include <e32svr.h>
|
||||
#include <bitdev.h>
|
||||
#include <w32std.h>
|
||||
#include <bitdraw.h> // CFbsDrawDevice
|
||||
|
||||
class CFbsDrawDevice : public CBase
|
||||
{
|
||||
public:
|
||||
public:
|
||||
IMPORT_C static CFbsDrawDevice* NewScreenDeviceL(TScreenInfoV01 aInfo,TDisplayMode aDispMode);
|
||||
public:
|
||||
virtual void Update() {}
|
||||
virtual void UpdateRegion(const TRect&) {}
|
||||
};
|
||||
|
||||
#define _THIS SDL_VideoDevice *_this
|
||||
|
||||
@@ -46,10 +55,7 @@ typedef struct SDL_VideoData
|
||||
TRequestStatus NGAGE_WsEventStatus;
|
||||
TRequestStatus NGAGE_RedrawEventStatus;
|
||||
TWsEvent NGAGE_WsEvent;
|
||||
//TWsRedrawEvent NGAGE_RedrawEvent;
|
||||
|
||||
CFbsDrawDevice* NGAGE_DrawDevice;
|
||||
|
||||
TBool NGAGE_IsWindowFocused; /* Not used yet */
|
||||
|
||||
/* Screen hardware frame buffer info */
|
||||
@@ -64,10 +70,6 @@ typedef struct SDL_VideoData
|
||||
|
||||
CFbsBitGc::TGraphicsOrientation NGAGE_ScreenOrientation;
|
||||
|
||||
/* Simulate double screen height */
|
||||
//TInt NGAGE_ScreenXScaleValue;
|
||||
//TInt NGAGE_ScreenYScaleValue;
|
||||
|
||||
} SDL_VideoData;
|
||||
|
||||
#endif /* _SDL_ngagevideo_h */
|
||||
|
||||
@@ -66,7 +66,7 @@ int SDL_OFFSCREEN_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_
|
||||
if (SDL_getenv("SDL_VIDEO_OFFSCREEN_SAVE_FRAMES")) {
|
||||
char file[128];
|
||||
SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp",
|
||||
SDL_GetWindowID(window), ++frame_number);
|
||||
(int)SDL_GetWindowID(window), ++frame_number);
|
||||
SDL_SaveBMP(surface, file);
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -1,171 +0,0 @@
|
||||
/*
|
||||
gradd.h structures and constants -- only the ones used by SDL_os2vman.c.
|
||||
|
||||
Based on public knowledge from around the internet including pages from
|
||||
http://www.osfree.org and http://www.edm2.com
|
||||
*/
|
||||
|
||||
#ifndef SDL_gradd_h_
|
||||
#define SDL_gradd_h_
|
||||
|
||||
typedef struct _INITPROCOUT {
|
||||
ULONG ulLength; /* Length of the INITPROCOUT data structure, in bytes. */
|
||||
ULONG ulVRAMVirt; /* 32-bit virtual address of VRAM. */
|
||||
} INITPROCOUT;
|
||||
typedef INITPROCOUT *PINITPROCOUT;
|
||||
|
||||
#define RC_SUCCESS 0
|
||||
|
||||
typedef ULONG GID;
|
||||
typedef ULONG (_System FNVMIENTRY) (
|
||||
GID gid, ULONG ulFunction,
|
||||
PVOID pIn,
|
||||
PVOID pOut /* PINITPROCOUT */
|
||||
);
|
||||
|
||||
#define VMI_CMD_INITPROC 1
|
||||
#define VMI_CMD_TERMPROC 3
|
||||
#define VMI_CMD_QUERYMODES 5
|
||||
#define VMI_CMD_SETMODE 6
|
||||
#define VMI_CMD_PALETTE 7
|
||||
#define VMI_CMD_BITBLT 8
|
||||
#define VMI_CMD_LINE 9
|
||||
#define VMI_CMD_REQUESTHW 14
|
||||
#define VMI_CMD_QUERYCURRENTMODE 0x1001
|
||||
|
||||
#define QUERYMODE_NUM_MODES 0x01
|
||||
#define QUERYMODE_MODE_DATA 0x02
|
||||
|
||||
typedef struct _HWPALETTEINFO {
|
||||
ULONG ulLength; /* Size of the HWPALETTEINFO data structure, in bytes. */
|
||||
ULONG fFlags; /* Palette flag. */
|
||||
ULONG ulStartIndex; /* Starting palette index. */
|
||||
ULONG ulNumEntries; /* Number of palette slots to query or set. */
|
||||
PRGB2 pRGBs; /* Pointer to the array of RGB values. */
|
||||
} HWPALETTEINFO;
|
||||
typedef HWPALETTEINFO *PHWPALETTEINFO;
|
||||
|
||||
#define PALETTE_GET 0x01
|
||||
#define PALETTE_SET 0x02
|
||||
|
||||
typedef struct _BMAPINFO {
|
||||
ULONG ulLength; /* Length of the BMAPINFO data structure, in bytes. */
|
||||
ULONG ulType; /* Description of the Blt. */
|
||||
ULONG ulWidth; /* Width in pels of the bit map. */
|
||||
ULONG ulHeight; /* Height in pels of the bit map. */
|
||||
ULONG ulBpp; /* Number of bits per pel/color depth. */
|
||||
ULONG ulBytesPerLine; /* Number of aligned bytes per line. */
|
||||
PBYTE pBits; /* Pointer to bit-map bits. */
|
||||
} BMAPINFO;
|
||||
typedef BMAPINFO *PBMAPINFO;
|
||||
|
||||
#define BMAP_VRAM 0
|
||||
#define BMAP_MEMORY 1
|
||||
|
||||
typedef struct _LINEPACK {
|
||||
ULONG ulStyleStep; /* Value to be added to ulStyleValue. */
|
||||
ULONG ulStyleValue; /* Style value at the current pel. */
|
||||
ULONG ulFlags; /* Flags used for the LINEPACK data structure. */
|
||||
struct _LINEPACK *plpkNext; /* Pointer to next LINEPACK data structure. */
|
||||
ULONG ulAbsDeltaX; /* Clipped Bresenham Delta X, absolute. */
|
||||
ULONG ulAbsDeltaY; /* Clipped Bresenham Delta Y, absolute. */
|
||||
POINTL ptlClipStart; /* Pointer to location for device to perform Bresenham algorithm. */
|
||||
POINTL ptlClipEnd; /* Ending location for Bresenham algorithm (see ptlClipStart). */
|
||||
POINTL ptlStart; /* Pointer to starting location for line. */
|
||||
POINTL ptlEnd; /* Ending location for line. */
|
||||
LONG lClipStartError;/* Standard Bresenham error at the clipped start point. */
|
||||
} LINEPACK;
|
||||
typedef LINEPACK *PLINEPACK;
|
||||
|
||||
typedef struct _LINEINFO {
|
||||
ULONG ulLength; /* Length of LINEINFO data structure. */
|
||||
ULONG ulType; /* Defines line type. */
|
||||
ULONG ulStyleMask; /* A 32-bit style mask. */
|
||||
ULONG cLines; /* Count of lines to be drawn. */
|
||||
ULONG ulFGColor; /* Line Foreground color. */
|
||||
ULONG ulBGColor; /* Line Background color. */
|
||||
USHORT usForeROP; /* Line Foreground mix. */
|
||||
USHORT usBackROP; /* Line Background mix. */
|
||||
PBMAPINFO pDstBmapInfo; /* Pointer to destination surface bit map. */
|
||||
PLINEPACK alpkLinePack; /* Pointer to LINEPACK data structure. */
|
||||
PRECTL prclBounds; /* Pointer to bounding rect of a clipped line. */
|
||||
} LINEINFO;
|
||||
typedef LINEINFO *PLINEINFO;
|
||||
|
||||
#define LINE_DO_FIRST_PEL 0x02
|
||||
#define LINE_DIR_Y_POSITIVE 0x04
|
||||
#define LINE_HORIZONTAL 0x08
|
||||
#define LINE_DIR_X_POSITIVE 0x20
|
||||
#define LINE_VERTICAL 0x1000
|
||||
#define LINE_DO_LAST_PEL 0x4000
|
||||
#define LINE_SOLID 0x01
|
||||
|
||||
typedef struct _BLTRECT {
|
||||
ULONG ulXOrg; /* X origin of the destination Blt. */
|
||||
ULONG ulYOrg; /* Y origin of the destination Blt. */
|
||||
ULONG ulXExt; /* X extent of the BitBlt. */
|
||||
ULONG ulYExt; /* Y extent of the BitBlt. */
|
||||
} BLTRECT;
|
||||
typedef BLTRECT *PBLTRECT;
|
||||
|
||||
typedef struct _BITBLTINFO {
|
||||
ULONG ulLength; /* Length of the BITBLTINFO data structure, in bytes. */
|
||||
ULONG ulBltFlags; /* Flags for rendering of rasterized data. */
|
||||
ULONG cBlits; /* Count of Blts to be performed. */
|
||||
ULONG ulROP; /* Raster operation. */
|
||||
ULONG ulMonoBackROP; /* Background mix if B_APPLY_BACK_ROP is set. */
|
||||
ULONG ulSrcFGColor; /* Monochrome source Foreground color. */
|
||||
ULONG ulSrcBGColor; /* Monochrome source Background color and transparent color. */
|
||||
ULONG ulPatFGColor; /* Monochrome pattern Foreground color. */
|
||||
ULONG ulPatBGColor; /* Monochrome pattern Background color. */
|
||||
PBYTE abColors; /* Pointer to color translation table. */
|
||||
PBMAPINFO pSrcBmapInfo; /* Pointer to source bit map (BMAPINFO) */
|
||||
PBMAPINFO pDstBmapInfo; /* Pointer to destination bit map (BMAPINFO). */
|
||||
PBMAPINFO pPatBmapInfo; /* Pointer to pattern bit map (BMAPINFO). */
|
||||
PPOINTL aptlSrcOrg; /* Pointer to array of source origin POINTLs. */
|
||||
PPOINTL aptlPatOrg; /* Pointer to array of pattern origin POINTLs. */
|
||||
PBLTRECT abrDst; /* Pointer to array of Blt rects. */
|
||||
PRECTL prclSrcBounds; /* Pointer to source bounding rect of source Blts. */
|
||||
PRECTL prclDstBounds; /* Pointer to destination bounding rect of destination Blts. */
|
||||
} BITBLTINFO;
|
||||
typedef BITBLTINFO *PBITBLTINFO;
|
||||
|
||||
#define BF_DEFAULT_STATE 0x0
|
||||
#define BF_ROP_INCL_SRC (0x01 << 2)
|
||||
#define BF_PAT_HOLLOW (0x01 << 8)
|
||||
|
||||
typedef struct _GDDMODEINFO {
|
||||
ULONG ulLength; /* Size of the GDDMODEINFO data structure, in bytes. */
|
||||
ULONG ulModeId; /* ID used to make SETMODE request. */
|
||||
ULONG ulBpp; /* Number of colors (bpp). */
|
||||
ULONG ulHorizResolution;/* Number of horizontal pels. */
|
||||
ULONG ulVertResolution; /* Number of vertical scan lines. */
|
||||
ULONG ulRefreshRate; /* Refresh rate in Hz. */
|
||||
PBYTE pbVRAMPhys; /* Physical address of VRAM. */
|
||||
ULONG ulApertureSize; /* Size of VRAM, in bytes. */
|
||||
ULONG ulScanLineSize; /* Size of one scan line, in bytes. */
|
||||
|
||||
ULONG fccColorEncoding, ulTotalVRAMSize, cColors;
|
||||
} GDDMODEINFO;
|
||||
typedef GDDMODEINFO *PGDDMODEINFO;
|
||||
|
||||
typedef struct _HWREQIN {
|
||||
ULONG ulLength; /* Size of the HWREQIN data structure, in bytes. */
|
||||
ULONG ulFlags; /* Request option flags. */
|
||||
ULONG cScrChangeRects; /* Count of screen rectangles affected by HWREQIN. */
|
||||
PRECTL arectlScreen; /* Array of screen rectangles affected by HWREQIN. */
|
||||
} HWREQIN;
|
||||
typedef HWREQIN *PHWREQIN;
|
||||
|
||||
#define REQUEST_HW 0x01
|
||||
|
||||
/*
|
||||
BOOL GreDeath(HDC hdc, PVOID pInstance, LONG lFunction);
|
||||
LONG GreResurrection(HDC hdc, LONG cbVmem, PULONG pReserved, PVOID pInstance, LONG lFunction);
|
||||
*/
|
||||
#define GreDeath(h) (BOOL)Gre32Entry3((ULONG)(h), 0, 0x40B7L)
|
||||
#define GreResurrection(h,n,r) (LONG)Gre32Entry5((ULONG)(h), (ULONG)(n), (ULONG)(r), 0, 0x40B8L)
|
||||
ULONG _System Gre32Entry3(ULONG, ULONG, ULONG);
|
||||
ULONG _System Gre32Entry5(ULONG, ULONG, ULONG, ULONG, ULONG);
|
||||
|
||||
#endif /* SDL_gradd_h_ */
|
||||
@@ -1,331 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
#include "../SDL_sysvideo.h"
|
||||
#define INCL_WIN
|
||||
#define INCL_GPI
|
||||
#include <os2.h>
|
||||
#define _MEERROR_H_
|
||||
#include <mmioos2.h>
|
||||
#include <os2me.h>
|
||||
#define INCL_MM_OS2
|
||||
#include <dive.h>
|
||||
#include <fourcc.h>
|
||||
#include "SDL_os2output.h"
|
||||
|
||||
typedef struct _VODATA {
|
||||
HDIVE hDive;
|
||||
PVOID pBuffer;
|
||||
ULONG ulDIVEBufNum;
|
||||
FOURCC fccColorEncoding;
|
||||
ULONG ulWidth;
|
||||
ULONG ulHeight;
|
||||
BOOL fBlitterReady;
|
||||
} VODATA;
|
||||
|
||||
static BOOL voQueryInfo(VIDEOOUTPUTINFO *pInfo);
|
||||
static PVODATA voOpen(void);
|
||||
static VOID voClose(PVODATA pVOData);
|
||||
static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd,
|
||||
SDL_DisplayMode *pSDLDisplayMode,
|
||||
HRGN hrgnShape, BOOL fVisible);
|
||||
static PVOID voVideoBufAlloc(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight,
|
||||
ULONG ulBPP, ULONG fccColorEncoding,
|
||||
PULONG pulScanLineSize);
|
||||
static VOID voVideoBufFree(PVODATA pVOData);
|
||||
static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects,
|
||||
ULONG cSDLRects);
|
||||
|
||||
OS2VIDEOOUTPUT voDive = {
|
||||
voQueryInfo,
|
||||
voOpen,
|
||||
voClose,
|
||||
voSetVisibleRegion,
|
||||
voVideoBufAlloc,
|
||||
voVideoBufFree,
|
||||
voUpdate
|
||||
};
|
||||
|
||||
|
||||
static BOOL voQueryInfo(VIDEOOUTPUTINFO *pInfo)
|
||||
{
|
||||
DIVE_CAPS sDiveCaps;
|
||||
FOURCC fccFormats[100];
|
||||
|
||||
/* Query information about display hardware from DIVE. */
|
||||
SDL_zeroa(fccFormats);
|
||||
SDL_zero(sDiveCaps);
|
||||
sDiveCaps.pFormatData = fccFormats;
|
||||
sDiveCaps.ulFormatLength = 100;
|
||||
sDiveCaps.ulStructLen = sizeof(DIVE_CAPS);
|
||||
|
||||
if (DiveQueryCaps(&sDiveCaps, DIVE_BUFFER_SCREEN)) {
|
||||
debug_os2("DiveQueryCaps() failed.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (sDiveCaps.ulDepth < 8) {
|
||||
debug_os2("Not enough screen colors to run DIVE. "
|
||||
"Must be at least 256 colors.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pInfo->ulBPP = sDiveCaps.ulDepth;
|
||||
pInfo->fccColorEncoding = sDiveCaps.fccColorEncoding;
|
||||
pInfo->ulScanLineSize = sDiveCaps.ulScanLineBytes;
|
||||
pInfo->ulHorizResolution = sDiveCaps.ulHorizontalResolution;
|
||||
pInfo->ulVertResolution = sDiveCaps.ulVerticalResolution;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PVODATA voOpen(void)
|
||||
{
|
||||
PVODATA pVOData = SDL_calloc(1, sizeof(VODATA));
|
||||
|
||||
if (pVOData == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (DiveOpen(&pVOData->hDive, FALSE, NULL) != DIVE_SUCCESS) {
|
||||
SDL_free(pVOData);
|
||||
SDL_SetError("DIVE: A display engine instance open failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pVOData;
|
||||
}
|
||||
|
||||
static VOID voClose(PVODATA pVOData)
|
||||
{
|
||||
voVideoBufFree(pVOData);
|
||||
DiveClose(pVOData->hDive);
|
||||
SDL_free(pVOData);
|
||||
}
|
||||
|
||||
static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd,
|
||||
SDL_DisplayMode *pSDLDisplayMode,
|
||||
HRGN hrgnShape, BOOL fVisible)
|
||||
{
|
||||
HPS hps;
|
||||
HRGN hrgn;
|
||||
RGNRECT rgnCtl;
|
||||
PRECTL prectl = NULL;
|
||||
ULONG ulRC;
|
||||
|
||||
if (!fVisible) {
|
||||
if (pVOData->fBlitterReady) {
|
||||
pVOData->fBlitterReady = FALSE;
|
||||
DiveSetupBlitter(pVOData->hDive, 0);
|
||||
debug_os2("DIVE blitter is tuned off");
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Query visible rectangles */
|
||||
hps = WinGetPS(hwnd);
|
||||
hrgn = GpiCreateRegion(hps, 0, NULL);
|
||||
if (hrgn == NULLHANDLE) {
|
||||
WinReleasePS(hps);
|
||||
SDL_SetError("GpiCreateRegion() failed");
|
||||
} else {
|
||||
WinQueryVisibleRegion(hwnd, hrgn);
|
||||
if (hrgnShape != NULLHANDLE)
|
||||
GpiCombineRegion(hps, hrgn, hrgn, hrgnShape, CRGN_AND);
|
||||
|
||||
rgnCtl.ircStart = 1;
|
||||
rgnCtl.crc = 0;
|
||||
rgnCtl.ulDirection = 1;
|
||||
GpiQueryRegionRects(hps, hrgn, NULL, &rgnCtl, NULL);
|
||||
if (rgnCtl.crcReturned != 0) {
|
||||
prectl = SDL_malloc(rgnCtl.crcReturned * sizeof(RECTL));
|
||||
if (prectl != NULL) {
|
||||
rgnCtl.ircStart = 1;
|
||||
rgnCtl.crc = rgnCtl.crcReturned;
|
||||
rgnCtl.ulDirection = 1;
|
||||
GpiQueryRegionRects(hps, hrgn, NULL, &rgnCtl, prectl);
|
||||
} else {
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
}
|
||||
GpiDestroyRegion(hps, hrgn);
|
||||
WinReleasePS(hps);
|
||||
|
||||
if (prectl != NULL) {
|
||||
/* Setup DIVE blitter. */
|
||||
SETUP_BLITTER sSetupBlitter;
|
||||
SWP swp;
|
||||
POINTL pointl = { 0,0 };
|
||||
|
||||
WinQueryWindowPos(hwnd, &swp);
|
||||
WinMapWindowPoints(hwnd, HWND_DESKTOP, &pointl, 1);
|
||||
|
||||
sSetupBlitter.ulStructLen = sizeof(SETUP_BLITTER);
|
||||
sSetupBlitter.fccSrcColorFormat = pVOData->fccColorEncoding;
|
||||
sSetupBlitter.fInvert = FALSE;
|
||||
sSetupBlitter.ulSrcWidth = pVOData->ulWidth;
|
||||
sSetupBlitter.ulSrcHeight = pVOData->ulHeight;
|
||||
sSetupBlitter.ulSrcPosX = 0;
|
||||
sSetupBlitter.ulSrcPosY = 0;
|
||||
sSetupBlitter.ulDitherType = 0;
|
||||
sSetupBlitter.fccDstColorFormat = FOURCC_SCRN;
|
||||
sSetupBlitter.ulDstWidth = swp.cx;
|
||||
sSetupBlitter.ulDstHeight = swp.cy;
|
||||
sSetupBlitter.lDstPosX = 0;
|
||||
sSetupBlitter.lDstPosY = 0;
|
||||
sSetupBlitter.lScreenPosX = pointl.x;
|
||||
sSetupBlitter.lScreenPosY = pointl.y;
|
||||
|
||||
sSetupBlitter.ulNumDstRects = rgnCtl.crcReturned;
|
||||
sSetupBlitter.pVisDstRects = prectl;
|
||||
|
||||
ulRC = DiveSetupBlitter(pVOData->hDive, &sSetupBlitter);
|
||||
SDL_free(prectl);
|
||||
|
||||
if (ulRC == DIVE_SUCCESS) {
|
||||
pVOData->fBlitterReady = TRUE;
|
||||
WinInvalidateRect(hwnd, NULL, TRUE);
|
||||
debug_os2("DIVE blitter is ready now.");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
SDL_SetError("DiveSetupBlitter(), rc = 0x%X", ulRC);
|
||||
} /* if (prectl != NULL) */
|
||||
} /* if (hrgn == NULLHANDLE) else */
|
||||
|
||||
pVOData->fBlitterReady = FALSE;
|
||||
DiveSetupBlitter(pVOData->hDive, 0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static PVOID voVideoBufAlloc(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight,
|
||||
ULONG ulBPP, FOURCC fccColorEncoding,
|
||||
PULONG pulScanLineSize)
|
||||
{
|
||||
ULONG ulRC;
|
||||
ULONG ulScanLineSize = ulWidth * (ulBPP >> 3);
|
||||
|
||||
/* Destroy previous buffer. */
|
||||
voVideoBufFree(pVOData);
|
||||
|
||||
if (ulWidth == 0 || ulHeight == 0 || ulBPP == 0)
|
||||
return NULL;
|
||||
|
||||
/* Bytes per line. */
|
||||
ulScanLineSize = (ulScanLineSize + 3) & ~3; /* 4-byte aligning */
|
||||
*pulScanLineSize = ulScanLineSize;
|
||||
|
||||
ulRC = DosAllocMem(&pVOData->pBuffer,
|
||||
(ulHeight * ulScanLineSize) + sizeof(ULONG),
|
||||
PAG_COMMIT | PAG_EXECUTE | PAG_READ | PAG_WRITE);
|
||||
if (ulRC != NO_ERROR) {
|
||||
debug_os2("DosAllocMem(), rc = %u", ulRC);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ulRC = DiveAllocImageBuffer(pVOData->hDive, &pVOData->ulDIVEBufNum,
|
||||
fccColorEncoding, ulWidth, ulHeight,
|
||||
ulScanLineSize, pVOData->pBuffer);
|
||||
if (ulRC != DIVE_SUCCESS) {
|
||||
debug_os2("DiveAllocImageBuffer(), rc = 0x%X", ulRC);
|
||||
DosFreeMem(pVOData->pBuffer);
|
||||
pVOData->pBuffer = NULL;
|
||||
pVOData->ulDIVEBufNum = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pVOData->fccColorEncoding = fccColorEncoding;
|
||||
pVOData->ulWidth = ulWidth;
|
||||
pVOData->ulHeight = ulHeight;
|
||||
|
||||
debug_os2("buffer: 0x%P, DIVE buffer number: %u",
|
||||
pVOData->pBuffer, pVOData->ulDIVEBufNum);
|
||||
|
||||
return pVOData->pBuffer;
|
||||
}
|
||||
|
||||
static VOID voVideoBufFree(PVODATA pVOData)
|
||||
{
|
||||
ULONG ulRC;
|
||||
|
||||
if (pVOData->ulDIVEBufNum != 0) {
|
||||
ulRC = DiveFreeImageBuffer(pVOData->hDive, pVOData->ulDIVEBufNum);
|
||||
if (ulRC != DIVE_SUCCESS) {
|
||||
debug_os2("DiveFreeImageBuffer(,%u), rc = %u", pVOData->ulDIVEBufNum, ulRC);
|
||||
} else {
|
||||
debug_os2("DIVE buffer %u destroyed", pVOData->ulDIVEBufNum);
|
||||
}
|
||||
pVOData->ulDIVEBufNum = 0;
|
||||
}
|
||||
|
||||
if (pVOData->pBuffer != NULL) {
|
||||
ulRC = DosFreeMem(pVOData->pBuffer);
|
||||
if (ulRC != NO_ERROR) {
|
||||
debug_os2("DosFreeMem(), rc = %u", ulRC);
|
||||
}
|
||||
pVOData->pBuffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects,
|
||||
ULONG cSDLRects)
|
||||
{
|
||||
ULONG ulRC;
|
||||
|
||||
if (!pVOData->fBlitterReady || (pVOData->ulDIVEBufNum == 0)) {
|
||||
debug_os2("DIVE blitter is not ready");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (pSDLRects != 0) {
|
||||
PBYTE pbLineMask;
|
||||
|
||||
pbLineMask = SDL_stack_alloc(BYTE, pVOData->ulHeight);
|
||||
if (pbLineMask == NULL) {
|
||||
debug_os2("Not enough stack size");
|
||||
return FALSE;
|
||||
}
|
||||
SDL_memset(pbLineMask, 0, pVOData->ulHeight);
|
||||
|
||||
for ( ; ((LONG)cSDLRects) > 0; cSDLRects--, pSDLRects++) {
|
||||
SDL_memset(&pbLineMask[pSDLRects->y], 1, pSDLRects->h);
|
||||
}
|
||||
|
||||
ulRC = DiveBlitImageLines(pVOData->hDive, pVOData->ulDIVEBufNum,
|
||||
DIVE_BUFFER_SCREEN, pbLineMask);
|
||||
SDL_stack_free(pbLineMask);
|
||||
|
||||
if (ulRC != DIVE_SUCCESS) {
|
||||
debug_os2("DiveBlitImageLines(), rc = 0x%X", ulRC);
|
||||
}
|
||||
} else {
|
||||
ulRC = DiveBlitImage(pVOData->hDive, pVOData->ulDIVEBufNum,
|
||||
DIVE_BUFFER_SCREEN);
|
||||
if (ulRC != DIVE_SUCCESS) {
|
||||
debug_os2("DiveBlitImage(), rc = 0x%X", ulRC);
|
||||
}
|
||||
}
|
||||
|
||||
return ulRC == DIVE_SUCCESS;
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,561 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_OS2
|
||||
|
||||
/* Display a OS/2 message box */
|
||||
|
||||
#include "SDL.h"
|
||||
#include "../../core/os2/SDL_os2.h"
|
||||
#include "SDL_os2video.h"
|
||||
#define INCL_WIN
|
||||
#include <os2.h>
|
||||
|
||||
#define IDD_TEXT_MESSAGE 1001
|
||||
#define IDD_BITMAP 1002
|
||||
#define IDD_PB_FIRST 1003
|
||||
|
||||
typedef struct _MSGBOXDLGDATA {
|
||||
USHORT cb;
|
||||
HWND hwndUnder;
|
||||
} MSGBOXDLGDATA;
|
||||
|
||||
static VOID _wmInitDlg(HWND hwnd, MSGBOXDLGDATA *pDlgData)
|
||||
{
|
||||
HPS hps = WinGetPS(hwnd);
|
||||
POINTL aptText[TXTBOX_COUNT];
|
||||
HENUM hEnum;
|
||||
HWND hWndNext;
|
||||
CHAR acBuf[256];
|
||||
ULONG cbBuf;
|
||||
ULONG cButtons = 0;
|
||||
ULONG ulButtonsCY = 0;
|
||||
ULONG ulButtonsCX = 0;
|
||||
RECTL rectl;
|
||||
ULONG ulX;
|
||||
ULONG ulIdx;
|
||||
struct _BUTTON {
|
||||
HWND hwnd; /* Button window handle. */
|
||||
ULONG ulCX; /* Button width in dialog coordinates. */
|
||||
} aButtons[32];
|
||||
RECTL rectlItem;
|
||||
HAB hab = WinQueryAnchorBlock(hwnd);
|
||||
|
||||
/* --- Align the buttons to the right/bottom. --- */
|
||||
|
||||
/* Collect window handles of all buttons in dialog. */
|
||||
hEnum = WinBeginEnumWindows(hwnd);
|
||||
|
||||
while ((hWndNext = WinGetNextWindow(hEnum)) != NULLHANDLE) {
|
||||
if (WinQueryClassName(hWndNext, sizeof(acBuf), acBuf) == 0) {
|
||||
continue;
|
||||
}
|
||||
if (SDL_strcmp(acBuf, "#3") == 0) { /* Class name of button. */
|
||||
if (cButtons < sizeof(aButtons) / sizeof(struct _BUTTON)) {
|
||||
aButtons[cButtons].hwnd = hWndNext;
|
||||
cButtons++;
|
||||
}
|
||||
}
|
||||
}
|
||||
WinEndEnumWindows(hEnum);
|
||||
|
||||
/* Query size of text for each button, get width of each button, total
|
||||
* buttons width (ulButtonsCX) and max. height (ulButtonsCX) in _dialog
|
||||
* coordinates_. */
|
||||
hps = WinGetPS(hwnd);
|
||||
|
||||
for(ulIdx = 0; ulIdx < cButtons; ulIdx++) {
|
||||
/* Query size of text in window coordinates. */
|
||||
cbBuf = WinQueryWindowText(aButtons[ulIdx].hwnd, sizeof(acBuf), acBuf);
|
||||
GpiQueryTextBox(hps, cbBuf, acBuf, TXTBOX_COUNT, aptText);
|
||||
aptText[TXTBOX_TOPRIGHT].x -= aptText[TXTBOX_BOTTOMLEFT].x;
|
||||
aptText[TXTBOX_TOPRIGHT].y -= aptText[TXTBOX_BOTTOMLEFT].y;
|
||||
/* Convert text size to dialog coordinates. */
|
||||
WinMapDlgPoints(hwnd, &aptText[TXTBOX_TOPRIGHT], 1, FALSE);
|
||||
/* Add vertical and horizontal space for button's frame (dialog coord.). */
|
||||
if (aptText[TXTBOX_TOPRIGHT].x < 30) { /* Minimal button width. */
|
||||
aptText[TXTBOX_TOPRIGHT].x = 30;
|
||||
} else {
|
||||
aptText[TXTBOX_TOPRIGHT].x += 4;
|
||||
}
|
||||
aptText[TXTBOX_TOPRIGHT].y += 3;
|
||||
|
||||
aButtons[ulIdx].ulCX = aptText[TXTBOX_TOPRIGHT].x; /* Store button width */
|
||||
ulButtonsCX += aptText[TXTBOX_TOPRIGHT].x + 2; /* Add total btn. width */
|
||||
/* Get max. height for buttons. */
|
||||
if (ulButtonsCY < aptText[TXTBOX_TOPRIGHT].y)
|
||||
ulButtonsCY = aptText[TXTBOX_TOPRIGHT].y + 1;
|
||||
}
|
||||
|
||||
WinReleasePS(hps);
|
||||
|
||||
/* Expand horizontal size of the window to fit all buttons and move window
|
||||
* to the center of parent window. */
|
||||
|
||||
/* Convert total width of buttons to window coordinates. */
|
||||
aptText[0].x = ulButtonsCX + 4;
|
||||
WinMapDlgPoints(hwnd, &aptText[0], 1, TRUE);
|
||||
/* Check width of the window and expand as needed. */
|
||||
WinQueryWindowRect(hwnd, &rectlItem);
|
||||
if (rectlItem.xRight <= aptText[0].x)
|
||||
rectlItem.xRight = aptText[0].x;
|
||||
|
||||
/* Move window rectangle to the center of owner window. */
|
||||
WinQueryWindowRect(pDlgData->hwndUnder, &rectl);
|
||||
/* Left-bottom point of centered dialog on owner window. */
|
||||
rectl.xLeft = (rectl.xRight - rectlItem.xRight) / 2;
|
||||
rectl.yBottom = (rectl.yTop - rectlItem.yTop) / 2;
|
||||
/* Map left-bottom point to desktop. */
|
||||
WinMapWindowPoints(pDlgData->hwndUnder, HWND_DESKTOP, (PPOINTL)&rectl, 1);
|
||||
WinOffsetRect(hab, &rectlItem, rectl.xLeft, rectl.yBottom);
|
||||
|
||||
/* Set new rectangle for the window. */
|
||||
WinSetWindowPos(hwnd, HWND_TOP, rectlItem.xLeft, rectlItem.yBottom,
|
||||
rectlItem.xRight - rectlItem.xLeft,
|
||||
rectlItem.yTop - rectlItem.yBottom,
|
||||
SWP_SIZE | SWP_MOVE);
|
||||
|
||||
/* Set buttons positions. */
|
||||
|
||||
/* Get horizontal position for the first button. */
|
||||
WinMapDlgPoints(hwnd, (PPOINTL)&rectlItem, 2, FALSE); /* Win size to dlg coord. */
|
||||
ulX = rectlItem.xRight - rectlItem.xLeft - ulButtonsCX - 2; /* First button position. */
|
||||
|
||||
/* Set positions and sizes for all buttons. */
|
||||
for (ulIdx = 0; ulIdx < cButtons; ulIdx++) {
|
||||
/* Get poisition and size for the button in dialog coordinates. */
|
||||
aptText[0].x = ulX;
|
||||
aptText[0].y = 2;
|
||||
aptText[1].x = aButtons[ulIdx].ulCX;
|
||||
aptText[1].y = ulButtonsCY;
|
||||
/* Convert to window coordinates. */
|
||||
WinMapDlgPoints(hwnd, aptText, 2, TRUE);
|
||||
|
||||
WinSetWindowPos(aButtons[ulIdx].hwnd, HWND_TOP,
|
||||
aptText[0].x, aptText[0].y, aptText[1].x, aptText[1].y,
|
||||
SWP_MOVE | SWP_SIZE);
|
||||
|
||||
/* Offset horizontal position for the next button. */
|
||||
ulX += aButtons[ulIdx].ulCX + 2;
|
||||
}
|
||||
|
||||
/* Set right bound of the text to right bound of the last button and
|
||||
* bottom bound of the text just above the buttons. */
|
||||
|
||||
aptText[2].x = 25; /* Left bound of text in dlg coordinates. */
|
||||
aptText[2].y = ulButtonsCY + 3; /* Bottom bound of the text in dlg coords. */
|
||||
WinMapDlgPoints(hwnd, &aptText[2], 1, TRUE); /* Convert ^^^ to win. coords */
|
||||
hWndNext = WinWindowFromID(hwnd, IDD_TEXT_MESSAGE);
|
||||
WinQueryWindowRect(hWndNext, &rectlItem);
|
||||
rectlItem.xLeft = aptText[2].x;
|
||||
rectlItem.yBottom = aptText[2].y;
|
||||
/* Right bound of the text equals right bound of the last button. */
|
||||
rectlItem.xRight = aptText[0].x + aptText[1].x;
|
||||
WinSetWindowPos(hWndNext, HWND_TOP, rectlItem.xLeft, rectlItem.yBottom,
|
||||
rectlItem.xRight - rectlItem.xLeft,
|
||||
rectlItem.yTop - rectlItem.yBottom,
|
||||
SWP_MOVE | SWP_SIZE);
|
||||
}
|
||||
|
||||
static MRESULT EXPENTRY DynDlgProc(HWND hwnd, USHORT message, MPARAM mp1, MPARAM mp2)
|
||||
{
|
||||
switch (message) {
|
||||
case WM_INITDLG:
|
||||
_wmInitDlg(hwnd, (MSGBOXDLGDATA*)mp2);
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (SHORT1FROMMP(mp1)) {
|
||||
case DID_OK:
|
||||
WinDismissDlg(hwnd, FALSE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return(WinDefDlgProc(hwnd, message, mp1, mp2));
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static HWND _makeDlg(const SDL_MessageBoxData *messageboxdata)
|
||||
{
|
||||
SDL_MessageBoxButtonData*
|
||||
pSDLBtnData = (SDL_MessageBoxButtonData *)messageboxdata->buttons;
|
||||
ULONG cSDLBtnData = messageboxdata->numbuttons;
|
||||
|
||||
PSZ pszTitle = OS2_UTF8ToSys(messageboxdata->title);
|
||||
ULONG cbTitle = (pszTitle == NULL)? 1 : (SDL_strlen(pszTitle) + 1);
|
||||
PSZ pszText = OS2_UTF8ToSys(messageboxdata->message);
|
||||
ULONG cbText = (pszText == NULL)? 1 : (SDL_strlen(pszText) + 1);
|
||||
|
||||
PDLGTEMPLATE pTemplate;
|
||||
ULONG cbTemplate;
|
||||
ULONG ulIdx;
|
||||
PCHAR pcDlgData;
|
||||
PDLGTITEM pDlgItem;
|
||||
PSZ pszBtnText;
|
||||
ULONG cbBtnText;
|
||||
HWND hwnd;
|
||||
|
||||
const SDL_MessageBoxColor* pSDLColors = (messageboxdata->colorScheme == NULL)?
|
||||
NULL : messageboxdata->colorScheme->colors;
|
||||
const SDL_MessageBoxColor* pSDLColor;
|
||||
|
||||
MSGBOXDLGDATA stDlgData;
|
||||
|
||||
/* Build a dialog tamplate in memory */
|
||||
|
||||
/* Size of template */
|
||||
cbTemplate = sizeof(DLGTEMPLATE) + ((2 + cSDLBtnData) * sizeof(DLGTITEM)) +
|
||||
sizeof(ULONG) + /* First item data - frame control data. */
|
||||
cbTitle + /* First item data - frame title + ZERO. */
|
||||
cbText + /* Second item data - ststic text + ZERO.*/
|
||||
3; /* Third item data - system icon Id. */
|
||||
|
||||
/* Button items datas - text for buttons. */
|
||||
for (ulIdx = 0; ulIdx < cSDLBtnData; ulIdx++) {
|
||||
pszBtnText = (PSZ)pSDLBtnData[ulIdx].text;
|
||||
cbTemplate += (pszBtnText == NULL)? 1 : (SDL_strlen(pszBtnText) + 1);
|
||||
}
|
||||
|
||||
/* Presentation parameter space. */
|
||||
if (pSDLColors != NULL) {
|
||||
cbTemplate += 26 /* PP for frame. */ +
|
||||
26 /* PP for static text. */ +
|
||||
(48 * cSDLBtnData); /* PP for buttons. */
|
||||
}
|
||||
|
||||
/* Allocate memory for the dialog template. */
|
||||
pTemplate = (PDLGTEMPLATE) SDL_malloc(cbTemplate);
|
||||
/* Pointer on data for dialog items in allocated memory. */
|
||||
pcDlgData = &((PCHAR)pTemplate)[sizeof(DLGTEMPLATE) +
|
||||
((2 + cSDLBtnData) * sizeof(DLGTITEM))];
|
||||
|
||||
/* Header info */
|
||||
pTemplate->cbTemplate = cbTemplate; /* size of dialog template to pass to WinCreateDlg() */
|
||||
pTemplate->type = 0; /* Currently always 0. */
|
||||
pTemplate->codepage = 0;
|
||||
pTemplate->offadlgti = 14; /* Offset to array of DLGTITEMs. */
|
||||
pTemplate->fsTemplateStatus = 0; /* Reserved field? */
|
||||
|
||||
/* Index in array of dlg items of item to get focus, */
|
||||
/* if 0 then focus goes to first control that can have focus. */
|
||||
pTemplate->iItemFocus = 0;
|
||||
pTemplate->coffPresParams = 0;
|
||||
|
||||
/* First item info - frame */
|
||||
pDlgItem = pTemplate->adlgti;
|
||||
pDlgItem->fsItemStatus = 0; /* Reserved? */
|
||||
/* Number of dialog item child windows owned by this item. */
|
||||
pDlgItem->cChildren = 2 + cSDLBtnData; /* Ststic text + buttons. */
|
||||
/* Length of class name, if 0 then offClassname contains a WC_ value. */
|
||||
pDlgItem->cchClassName = 0;
|
||||
pDlgItem->offClassName = (USHORT)WC_FRAME;
|
||||
/* Length of text. */
|
||||
pDlgItem->cchText = cbTitle;
|
||||
pDlgItem->offText = pcDlgData - (PCHAR)pTemplate; /* Offset to title text. */
|
||||
/* Copy text for the title into the dialog template. */
|
||||
if (pszTitle != NULL) {
|
||||
SDL_memcpy(pcDlgData, pszTitle, cbTitle);
|
||||
} else {
|
||||
*pcDlgData = '\0';
|
||||
}
|
||||
pcDlgData += pDlgItem->cchText;
|
||||
|
||||
pDlgItem->flStyle = WS_GROUP | WS_VISIBLE | WS_CLIPSIBLINGS |
|
||||
FS_DLGBORDER | WS_SAVEBITS;
|
||||
pDlgItem->x = 100;
|
||||
pDlgItem->y = 100;
|
||||
pDlgItem->cx = 175;
|
||||
pDlgItem->cy = 65;
|
||||
pDlgItem->id = DID_OK; /* An ID value? */
|
||||
if (pSDLColors == NULL)
|
||||
pDlgItem->offPresParams = 0;
|
||||
else {
|
||||
/* Presentation parameter for the frame - dialog colors. */
|
||||
pDlgItem->offPresParams = pcDlgData - (PCHAR)pTemplate;
|
||||
((PPRESPARAMS)pcDlgData)->cb = 22;
|
||||
pcDlgData += 4;
|
||||
((PPARAM)pcDlgData)->id = PP_FOREGROUNDCOLOR;
|
||||
((PPARAM)pcDlgData)->cb = 3;
|
||||
((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].b;
|
||||
((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].g;
|
||||
((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].r;
|
||||
pcDlgData += 11;
|
||||
((PPARAM)pcDlgData)->id = PP_BACKGROUNDCOLOR;
|
||||
((PPARAM)pcDlgData)->cb = 3;
|
||||
((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].b;
|
||||
((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].g;
|
||||
((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].r;
|
||||
pcDlgData += 11;
|
||||
}
|
||||
|
||||
/* Offset to ctl data. */
|
||||
pDlgItem->offCtlData = pcDlgData - (PCHAR)pTemplate;
|
||||
/* Put CtlData for the dialog in here */
|
||||
*((PULONG)pcDlgData) = FCF_TITLEBAR | FCF_SYSMENU;
|
||||
pcDlgData += sizeof(ULONG);
|
||||
|
||||
/* Second item info - static text (message). */
|
||||
pDlgItem++;
|
||||
pDlgItem->fsItemStatus = 0;
|
||||
/* No children since its a control, it could have child control */
|
||||
/* (ex. a group box). */
|
||||
pDlgItem->cChildren = 0;
|
||||
/* Length of class name, 0 - offClassname contains a WC_ constant. */
|
||||
pDlgItem->cchClassName = 0;
|
||||
pDlgItem->offClassName = (USHORT)WC_STATIC;
|
||||
|
||||
pDlgItem->cchText = cbText;
|
||||
pDlgItem->offText = pcDlgData - (PCHAR)pTemplate; /* Offset to the text. */
|
||||
/* Copy message text into the dialog template. */
|
||||
if (pszText != NULL) {
|
||||
SDL_memcpy(pcDlgData, pszText, cbText);
|
||||
} else {
|
||||
*pcDlgData = '\0';
|
||||
}
|
||||
pcDlgData += pDlgItem->cchText;
|
||||
|
||||
pDlgItem->flStyle = SS_TEXT | DT_TOP | DT_LEFT | DT_WORDBREAK | WS_VISIBLE;
|
||||
/* It will be really set in _wmInitDlg(). */
|
||||
pDlgItem->x = 25;
|
||||
pDlgItem->y = 13;
|
||||
pDlgItem->cx = 147;
|
||||
pDlgItem->cy = 62; /* It will be used. */
|
||||
|
||||
pDlgItem->id = IDD_TEXT_MESSAGE; /* an ID value */
|
||||
if (pSDLColors == NULL)
|
||||
pDlgItem->offPresParams = 0;
|
||||
else {
|
||||
/* Presentation parameter for the static text - dialog colors. */
|
||||
pDlgItem->offPresParams = pcDlgData - (PCHAR)pTemplate;
|
||||
((PPRESPARAMS)pcDlgData)->cb = 22;
|
||||
pcDlgData += 4;
|
||||
((PPARAM)pcDlgData)->id = PP_FOREGROUNDCOLOR;
|
||||
((PPARAM)pcDlgData)->cb = 3;
|
||||
((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].b;
|
||||
((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].g;
|
||||
((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].r;
|
||||
pcDlgData += 11;
|
||||
((PPARAM)pcDlgData)->id = PP_BACKGROUNDCOLOR;
|
||||
((PPARAM)pcDlgData)->cb = 3;
|
||||
((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].b;
|
||||
((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].g;
|
||||
((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].r;
|
||||
pcDlgData += 11;
|
||||
}
|
||||
pDlgItem->offCtlData = 0;
|
||||
|
||||
/* Third item info - static bitmap. */
|
||||
pDlgItem++;
|
||||
pDlgItem->fsItemStatus = 0;
|
||||
pDlgItem->cChildren = 0;
|
||||
pDlgItem->cchClassName = 0;
|
||||
pDlgItem->offClassName = (USHORT)WC_STATIC;
|
||||
|
||||
pDlgItem->cchText = 3; /* 0xFF, low byte of the icon Id, high byte of icon Id. */
|
||||
pDlgItem->offText = pcDlgData - (PCHAR)pTemplate; /* Offset to the Id. */
|
||||
/* Write system icon ID into dialog template. */
|
||||
*((PBYTE)pcDlgData) = 0xFF; /* First byte is 0xFF, next 2 are system pointer Id. */
|
||||
pcDlgData++;
|
||||
*((PUSHORT)pcDlgData) = ((messageboxdata->flags & SDL_MESSAGEBOX_ERROR) != 0)?
|
||||
SPTR_ICONERROR :
|
||||
((messageboxdata->flags & SDL_MESSAGEBOX_WARNING) != 0)?
|
||||
SPTR_ICONWARNING : SPTR_ICONINFORMATION;
|
||||
pcDlgData += 2;
|
||||
|
||||
pDlgItem->flStyle = SS_SYSICON | WS_VISIBLE;
|
||||
|
||||
pDlgItem->x = 4;
|
||||
pDlgItem->y = 45; /* It will be really set in _wmInitDlg(). */
|
||||
pDlgItem->cx = 0;
|
||||
pDlgItem->cy = 0;
|
||||
|
||||
pDlgItem->id = IDD_BITMAP;
|
||||
pDlgItem->offPresParams = 0;
|
||||
pDlgItem->offCtlData = 0;
|
||||
|
||||
/* Next items - buttons. */
|
||||
for (ulIdx = 0; ulIdx < cSDLBtnData; ulIdx++) {
|
||||
pDlgItem++;
|
||||
|
||||
pDlgItem->fsItemStatus = 0;
|
||||
pDlgItem->cChildren = 0; /* No children. */
|
||||
pDlgItem->cchClassName = 0; /* 0 - offClassname is WC_ constant. */
|
||||
pDlgItem->offClassName = (USHORT)WC_BUTTON;
|
||||
|
||||
pszBtnText = OS2_UTF8ToSys(pSDLBtnData[ulIdx].text);
|
||||
cbBtnText = (pszBtnText == NULL)? 1 : (SDL_strlen(pszBtnText) + 1);
|
||||
pDlgItem->cchText = cbBtnText;
|
||||
pDlgItem->offText = pcDlgData - (PCHAR)pTemplate; /* Offset to the text. */
|
||||
/* Copy text for the button into the dialog template. */
|
||||
if (pszBtnText != NULL) {
|
||||
SDL_memcpy(pcDlgData, pszBtnText, cbBtnText);
|
||||
} else {
|
||||
*pcDlgData = '\0';
|
||||
}
|
||||
pcDlgData += pDlgItem->cchText;
|
||||
SDL_free(pszBtnText);
|
||||
|
||||
pDlgItem->flStyle = BS_PUSHBUTTON | WS_TABSTOP | WS_VISIBLE;
|
||||
if (pSDLBtnData[ulIdx].flags == SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) {
|
||||
pDlgItem->flStyle |= BS_DEFAULT;
|
||||
pTemplate->iItemFocus = ulIdx + 3; /* +3 - frame, static text and icon. */
|
||||
pSDLColor = &pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED];
|
||||
} else {
|
||||
pSDLColor = &pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT];
|
||||
}
|
||||
|
||||
/* It will be really set in _wmInitDlg() */
|
||||
pDlgItem->x = 10;
|
||||
pDlgItem->y = 10;
|
||||
pDlgItem->cx = 70;
|
||||
pDlgItem->cy = 15;
|
||||
|
||||
pDlgItem->id = IDD_PB_FIRST + ulIdx; /* an ID value */
|
||||
if (pSDLColors == NULL)
|
||||
pDlgItem->offPresParams = 0;
|
||||
else {
|
||||
/* Presentation parameter for the button - dialog colors. */
|
||||
pDlgItem->offPresParams = pcDlgData - (PCHAR)pTemplate;
|
||||
((PPRESPARAMS)pcDlgData)->cb = 44;
|
||||
pcDlgData += 4;
|
||||
((PPARAM)pcDlgData)->id = PP_FOREGROUNDCOLOR;
|
||||
((PPARAM)pcDlgData)->cb = 3;
|
||||
((PPARAM)pcDlgData)->ab[0] = pSDLColor->b;
|
||||
((PPARAM)pcDlgData)->ab[1] = pSDLColor->g;
|
||||
((PPARAM)pcDlgData)->ab[2] = pSDLColor->r;
|
||||
pcDlgData += 11;
|
||||
((PPARAM)pcDlgData)->id = PP_BACKGROUNDCOLOR;
|
||||
((PPARAM)pcDlgData)->cb = 3;
|
||||
((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND].b;
|
||||
((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND].g;
|
||||
((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND].r;
|
||||
pcDlgData += 11;
|
||||
((PPARAM)pcDlgData)->id = PP_BORDERLIGHTCOLOR;
|
||||
((PPARAM)pcDlgData)->cb = 3;
|
||||
((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].b;
|
||||
((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].g;
|
||||
((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].r;
|
||||
pcDlgData += 11;
|
||||
((PPARAM)pcDlgData)->id = PP_BORDERDARKCOLOR;
|
||||
((PPARAM)pcDlgData)->cb = 3;
|
||||
((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].b;
|
||||
((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].g;
|
||||
((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].r;
|
||||
pcDlgData += 11;
|
||||
}
|
||||
pDlgItem->offCtlData = 0;
|
||||
}
|
||||
/* Check, end of templ. data: &((PCHAR)pTemplate)[cbTemplate] == pcDlgData */
|
||||
|
||||
/* Create the dialog from template. */
|
||||
stDlgData.cb = sizeof(MSGBOXDLGDATA);
|
||||
stDlgData.hwndUnder = (messageboxdata->window != NULL && messageboxdata->window->driverdata != NULL)?
|
||||
((WINDATA *)messageboxdata->window->driverdata)->hwnd : HWND_DESKTOP;
|
||||
|
||||
hwnd = WinCreateDlg(HWND_DESKTOP, /* Parent is desktop. */
|
||||
stDlgData.hwndUnder,
|
||||
(PFNWP)DynDlgProc, pTemplate, &stDlgData);
|
||||
SDL_free(pTemplate);
|
||||
SDL_free(pszTitle);
|
||||
SDL_free(pszText);
|
||||
|
||||
return hwnd;
|
||||
}
|
||||
|
||||
|
||||
int OS2_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
|
||||
{
|
||||
HWND hwnd;
|
||||
ULONG ulRC;
|
||||
SDL_MessageBoxButtonData
|
||||
*pSDLBtnData = (SDL_MessageBoxButtonData *)messageboxdata->buttons;
|
||||
ULONG cSDLBtnData = messageboxdata->numbuttons;
|
||||
BOOL fVideoInitialized = SDL_WasInit(SDL_INIT_VIDEO);
|
||||
HAB hab;
|
||||
HMQ hmq;
|
||||
BOOL fSuccess = FALSE;
|
||||
|
||||
if (!fVideoInitialized) {
|
||||
PTIB tib;
|
||||
PPIB pib;
|
||||
|
||||
DosGetInfoBlocks(&tib, &pib);
|
||||
if (pib->pib_ultype == 2 || pib->pib_ultype == 0) {
|
||||
/* VIO windowable or fullscreen protect-mode session */
|
||||
pib->pib_ultype = 3; /* Presentation Manager protect-mode session */
|
||||
}
|
||||
|
||||
hab = WinInitialize(0);
|
||||
if (hab == NULLHANDLE) {
|
||||
debug_os2("WinInitialize() failed");
|
||||
return -1;
|
||||
}
|
||||
hmq = WinCreateMsgQueue(hab, 0);
|
||||
if (hmq == NULLHANDLE) {
|
||||
debug_os2("WinCreateMsgQueue() failed");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create dynamic dialog. */
|
||||
hwnd = _makeDlg(messageboxdata);
|
||||
/* Show dialog and obtain button Id. */
|
||||
ulRC = WinProcessDlg(hwnd);
|
||||
/* Destroy dialog, */
|
||||
WinDestroyWindow(hwnd);
|
||||
|
||||
if (ulRC == DID_CANCEL) {
|
||||
/* Window closed by ESC, Alt+F4 or system menu. */
|
||||
ULONG ulIdx;
|
||||
|
||||
for (ulIdx = 0; ulIdx < cSDLBtnData; ulIdx++, pSDLBtnData++) {
|
||||
if (pSDLBtnData->flags == SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) {
|
||||
*buttonid = pSDLBtnData->buttonid;
|
||||
fSuccess = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Button pressed. */
|
||||
ulRC -= IDD_PB_FIRST;
|
||||
if (ulRC < cSDLBtnData) {
|
||||
*buttonid = pSDLBtnData[ulRC].buttonid;
|
||||
fSuccess = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fVideoInitialized) {
|
||||
WinDestroyMsgQueue(hmq);
|
||||
WinTerminate(hab);
|
||||
}
|
||||
|
||||
return (fSuccess)? 0 : -1;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_OS2 */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_OS2
|
||||
|
||||
extern int OS2_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid);
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_OS2 */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,194 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_OS2
|
||||
|
||||
#include "SDL_os2video.h"
|
||||
#include "../../events/SDL_mouse_c.h"
|
||||
#include "SDL_os2util.h"
|
||||
|
||||
HPOINTER hptrCursor = NULLHANDLE;
|
||||
|
||||
static SDL_Cursor* OS2_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
|
||||
{
|
||||
ULONG ulMaxW = WinQuerySysValue(HWND_DESKTOP, SV_CXPOINTER);
|
||||
ULONG ulMaxH = WinQuerySysValue(HWND_DESKTOP, SV_CYPOINTER);
|
||||
HPOINTER hptr;
|
||||
SDL_Cursor* pSDLCursor;
|
||||
|
||||
if (surface->w > ulMaxW || surface->h > ulMaxH) {
|
||||
debug_os2("Given image size is %u x %u, maximum allowed size is %u x %u",
|
||||
surface->w, surface->h, ulMaxW, ulMaxH);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hptr = utilCreatePointer(surface, hot_x, ulMaxH - hot_y - 1);
|
||||
if (hptr == NULLHANDLE)
|
||||
return NULL;
|
||||
|
||||
pSDLCursor = SDL_calloc(1, sizeof(SDL_Cursor));
|
||||
if (pSDLCursor == NULL) {
|
||||
WinDestroyPointer(hptr);
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pSDLCursor->driverdata = (void *)hptr;
|
||||
return pSDLCursor;
|
||||
}
|
||||
|
||||
static SDL_Cursor* OS2_CreateSystemCursor(SDL_SystemCursor id)
|
||||
{
|
||||
SDL_Cursor* pSDLCursor;
|
||||
LONG lSysId;
|
||||
HPOINTER hptr;
|
||||
|
||||
switch (id) {
|
||||
case SDL_SYSTEM_CURSOR_ARROW: lSysId = SPTR_ARROW; break;
|
||||
case SDL_SYSTEM_CURSOR_IBEAM: lSysId = SPTR_TEXT; break;
|
||||
case SDL_SYSTEM_CURSOR_WAIT: lSysId = SPTR_WAIT; break;
|
||||
case SDL_SYSTEM_CURSOR_CROSSHAIR: lSysId = SPTR_MOVE; break;
|
||||
case SDL_SYSTEM_CURSOR_WAITARROW: lSysId = SPTR_WAIT; break;
|
||||
case SDL_SYSTEM_CURSOR_SIZENWSE: lSysId = SPTR_SIZENWSE; break;
|
||||
case SDL_SYSTEM_CURSOR_SIZENESW: lSysId = SPTR_SIZENESW; break;
|
||||
case SDL_SYSTEM_CURSOR_SIZEWE: lSysId = SPTR_SIZEWE; break;
|
||||
case SDL_SYSTEM_CURSOR_SIZENS: lSysId = SPTR_SIZENS; break;
|
||||
case SDL_SYSTEM_CURSOR_SIZEALL: lSysId = SPTR_MOVE; break;
|
||||
case SDL_SYSTEM_CURSOR_NO: lSysId = SPTR_ILLEGAL; break;
|
||||
case SDL_SYSTEM_CURSOR_HAND: lSysId = SPTR_ARROW; break;
|
||||
default:
|
||||
debug_os2("Unknown cursor id: %u", id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* On eCS SPTR_WAIT for last paramether fCopy=TRUE/FALSE gives different
|
||||
* "wait" icons. -=8( ) */
|
||||
hptr = WinQuerySysPointer(HWND_DESKTOP, lSysId,
|
||||
id == SDL_SYSTEM_CURSOR_WAIT);
|
||||
if (hptr == NULLHANDLE) {
|
||||
debug_os2("Cannot load OS/2 system pointer %u for SDL cursor id %u",
|
||||
lSysId, id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pSDLCursor = SDL_calloc(1, sizeof(SDL_Cursor));
|
||||
if (pSDLCursor == NULL) {
|
||||
WinDestroyPointer(hptr);
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pSDLCursor->driverdata = (void *)hptr;
|
||||
return pSDLCursor;
|
||||
}
|
||||
|
||||
static void OS2_FreeCursor(SDL_Cursor *cursor)
|
||||
{
|
||||
HPOINTER hptr = (HPOINTER)cursor->driverdata;
|
||||
|
||||
WinDestroyPointer(hptr);
|
||||
SDL_free(cursor);
|
||||
}
|
||||
|
||||
static int OS2_ShowCursor(SDL_Cursor *cursor)
|
||||
{
|
||||
hptrCursor = (cursor != NULL)? (HPOINTER)cursor->driverdata : NULLHANDLE;
|
||||
return ((SDL_GetMouseFocus() == NULL) ||
|
||||
WinSetPointer(HWND_DESKTOP, hptrCursor))? 0 : -1;
|
||||
}
|
||||
|
||||
static void OS2_WarpMouse(SDL_Window * window, int x, int y)
|
||||
{
|
||||
WINDATA *pWinData = (WINDATA *)window->driverdata;
|
||||
POINTL pointl;
|
||||
|
||||
pointl.x = x;
|
||||
pointl.y = window->h - y;
|
||||
WinMapWindowPoints(pWinData->hwnd, HWND_DESKTOP, &pointl, 1);
|
||||
/* pWinData->lSkipWMMouseMove++; ???*/
|
||||
WinSetPointerPos(HWND_DESKTOP, pointl.x, pointl.y);
|
||||
}
|
||||
|
||||
static int OS2_WarpMouseGlobal(int x, int y)
|
||||
{
|
||||
WinSetPointerPos(HWND_DESKTOP, x,
|
||||
WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN) - y);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int OS2_CaptureMouse(SDL_Window *window)
|
||||
{
|
||||
return WinSetCapture(HWND_DESKTOP, (window == NULL)? NULLHANDLE :
|
||||
((WINDATA *)window->driverdata)->hwnd)? 0 : -1;
|
||||
}
|
||||
|
||||
static Uint32 OS2_GetGlobalMouseState(int *x, int *y)
|
||||
{
|
||||
POINTL pointl;
|
||||
ULONG ulRes;
|
||||
|
||||
WinQueryPointerPos(HWND_DESKTOP, &pointl);
|
||||
*x = pointl.x;
|
||||
*y = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN) - pointl.y - 1;
|
||||
|
||||
ulRes = (WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) & 0x8000)? SDL_BUTTON_LMASK : 0;
|
||||
if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) & 0x8000)
|
||||
ulRes |= SDL_BUTTON_RMASK;
|
||||
if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) & 0x8000)
|
||||
ulRes |= SDL_BUTTON_MMASK;
|
||||
|
||||
return ulRes;
|
||||
}
|
||||
|
||||
|
||||
void OS2_InitMouse(_THIS, ULONG hab)
|
||||
{
|
||||
SDL_Mouse *pSDLMouse = SDL_GetMouse();
|
||||
|
||||
pSDLMouse->CreateCursor = OS2_CreateCursor;
|
||||
pSDLMouse->CreateSystemCursor = OS2_CreateSystemCursor;
|
||||
pSDLMouse->ShowCursor = OS2_ShowCursor;
|
||||
pSDLMouse->FreeCursor = OS2_FreeCursor;
|
||||
pSDLMouse->WarpMouse = OS2_WarpMouse;
|
||||
pSDLMouse->WarpMouseGlobal = OS2_WarpMouseGlobal;
|
||||
pSDLMouse->CaptureMouse = OS2_CaptureMouse;
|
||||
pSDLMouse->GetGlobalMouseState = OS2_GetGlobalMouseState;
|
||||
|
||||
SDL_SetDefaultCursor(OS2_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW));
|
||||
if (hptrCursor == NULLHANDLE)
|
||||
hptrCursor = WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, TRUE);
|
||||
}
|
||||
|
||||
void OS2_QuitMouse(_THIS)
|
||||
{
|
||||
SDL_Mouse *pSDLMouse = SDL_GetMouse();
|
||||
|
||||
if (pSDLMouse->def_cursor != NULL) {
|
||||
SDL_free(pSDLMouse->def_cursor);
|
||||
pSDLMouse->def_cursor = NULL;
|
||||
pSDLMouse->cur_cursor = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_OS2 */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#ifndef SDL_os2output_
|
||||
#define SDL_os2output_
|
||||
|
||||
#include "../../core/os2/SDL_os2.h"
|
||||
|
||||
typedef struct _VODATA *PVODATA;
|
||||
|
||||
typedef struct _VIDEOOUTPUTINFO {
|
||||
ULONG ulBPP;
|
||||
ULONG fccColorEncoding;
|
||||
ULONG ulScanLineSize;
|
||||
ULONG ulHorizResolution;
|
||||
ULONG ulVertResolution;
|
||||
} VIDEOOUTPUTINFO;
|
||||
|
||||
typedef struct _OS2VIDEOOUTPUT {
|
||||
BOOL (*QueryInfo)(VIDEOOUTPUTINFO *pInfo);
|
||||
PVODATA (*Open)();
|
||||
VOID (*Close)(PVODATA pVOData);
|
||||
|
||||
BOOL (*SetVisibleRegion)(PVODATA pVOData, HWND hwnd,
|
||||
SDL_DisplayMode *pSDLDisplayMode, HRGN hrgnShape,
|
||||
BOOL fVisible);
|
||||
|
||||
PVOID (*VideoBufAlloc)(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight,
|
||||
ULONG ulBPP, ULONG fccColorEncoding,
|
||||
PULONG pulScanLineSize);
|
||||
|
||||
VOID (*VideoBufFree)(PVODATA pVOData);
|
||||
BOOL (*Update)(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects,
|
||||
ULONG cSDLRects);
|
||||
} OS2VIDEOOUTPUT;
|
||||
|
||||
extern OS2VIDEOOUTPUT voDive;
|
||||
extern OS2VIDEOOUTPUT voVMan;
|
||||
|
||||
#endif /* SDL_os2output_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_OS2
|
||||
|
||||
#include "SDL_os2util.h"
|
||||
|
||||
HPOINTER utilCreatePointer(SDL_Surface *surface, ULONG ulHotX, ULONG ulHotY)
|
||||
{
|
||||
HBITMAP hbm;
|
||||
BITMAPINFOHEADER2 bmih;
|
||||
BITMAPINFO bmi;
|
||||
HPS hps;
|
||||
PULONG pulBitmap;
|
||||
PULONG pulDst, pulSrc, pulDstMask;
|
||||
ULONG ulY, ulX;
|
||||
HPOINTER hptr = NULLHANDLE;
|
||||
|
||||
if (surface->format->format != SDL_PIXELFORMAT_ARGB8888) {
|
||||
debug_os2("Image format should be SDL_PIXELFORMAT_ARGB8888");
|
||||
return NULLHANDLE;
|
||||
}
|
||||
|
||||
pulBitmap = (PULONG) SDL_malloc(surface->h * surface->w * 2 * sizeof(ULONG));
|
||||
if (pulBitmap == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
return NULLHANDLE;
|
||||
}
|
||||
|
||||
/* pulDst - last line of surface (image) part of the result bitmap */
|
||||
pulDst = &pulBitmap[ (surface->h - 1) * surface->w ];
|
||||
/* pulDstMask - last line of mask part of the result bitmap */
|
||||
pulDstMask = &pulBitmap[ (2 * surface->h - 1) * surface->w ];
|
||||
/* pulSrc - first line of source image */
|
||||
pulSrc = (PULONG)surface->pixels;
|
||||
|
||||
for (ulY = 0; ulY < surface->h; ulY++) {
|
||||
for (ulX = 0; ulX < surface->w; ulX++) {
|
||||
if ((pulSrc[ulX] & 0xFF000000) == 0) {
|
||||
pulDst[ulX] = 0;
|
||||
pulDstMask[ulX] = 0xFFFFFFFF;
|
||||
} else {
|
||||
pulDst[ulX] = pulSrc[ulX] & 0xFFFFFF;
|
||||
pulDstMask[ulX] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set image and mask pointers on one line up */
|
||||
pulDst -= surface->w;
|
||||
pulDstMask -= surface->w;
|
||||
/* Set source image pointer to the next line */
|
||||
pulSrc = (PULONG) (((PCHAR)pulSrc) + surface->pitch);
|
||||
}
|
||||
|
||||
/* Create system bitmap object. */
|
||||
SDL_zero(bmih);
|
||||
SDL_zero(bmi);
|
||||
|
||||
bmih.cbFix = sizeof(BITMAPINFOHEADER2);
|
||||
bmih.cx = surface->w;
|
||||
bmih.cy = 2 * surface->h;
|
||||
bmih.cPlanes = 1;
|
||||
bmih.cBitCount = 32;
|
||||
bmih.ulCompression = BCA_UNCOMP;
|
||||
bmih.cbImage = bmih.cx * bmih.cy * 4;
|
||||
|
||||
bmi.cbFix = sizeof(BITMAPINFOHEADER);
|
||||
bmi.cx = bmih.cx;
|
||||
bmi.cy = bmih.cy;
|
||||
bmi.cPlanes = 1;
|
||||
bmi.cBitCount = 32;
|
||||
|
||||
hps = WinGetPS(HWND_DESKTOP);
|
||||
hbm = GpiCreateBitmap(hps, (PBITMAPINFOHEADER2)&bmih, CBM_INIT,
|
||||
(PBYTE)pulBitmap, (PBITMAPINFO2)&bmi);
|
||||
if (hbm == GPI_ERROR) {
|
||||
debug_os2("GpiCreateBitmap() failed");
|
||||
} else {
|
||||
/* Create a system pointer object. */
|
||||
hptr = WinCreatePointer(HWND_DESKTOP, hbm, TRUE, ulHotX, ulHotY);
|
||||
if (hptr == NULLHANDLE) {
|
||||
debug_os2("WinCreatePointer() failed");
|
||||
}
|
||||
}
|
||||
GpiDeleteBitmap(hbm);
|
||||
|
||||
WinReleasePS(hps);
|
||||
SDL_free(pulBitmap);
|
||||
|
||||
return hptr;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_OS2 */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_os2util_h_
|
||||
#define SDL_os2util_h_
|
||||
|
||||
#include "SDL_log.h"
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "../../core/os2/SDL_os2.h"
|
||||
|
||||
#define INCL_WIN
|
||||
#define INCL_GPI
|
||||
#include <os2.h>
|
||||
|
||||
HPOINTER utilCreatePointer(SDL_Surface *surface, ULONG ulHotX, ULONG ulHotY);
|
||||
|
||||
#endif /* SDL_os2util_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifndef SDL_os2video_h_
|
||||
#define SDL_os2video_h_
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "../../core/os2/SDL_os2.h"
|
||||
|
||||
#define INCL_DOS
|
||||
#define INCL_DOSERRORS
|
||||
#define INCL_DOSPROCESS
|
||||
#define INCL_WIN
|
||||
#define INCL_GPI
|
||||
#define INCL_OS2MM
|
||||
#define INCL_DOSMEMMGR
|
||||
#include <os2.h>
|
||||
|
||||
#include "SDL_os2mouse.h"
|
||||
#include "SDL_os2output.h"
|
||||
|
||||
typedef struct SDL_VideoData {
|
||||
HAB hab;
|
||||
HMQ hmq;
|
||||
OS2VIDEOOUTPUT *pOutput; /* Video output routines */
|
||||
} SDL_VideoData;
|
||||
|
||||
typedef struct _WINDATA {
|
||||
SDL_Window *window;
|
||||
OS2VIDEOOUTPUT *pOutput; /* Video output routines */
|
||||
HWND hwndFrame;
|
||||
HWND hwnd;
|
||||
PFNWP fnUserWndProc;
|
||||
PFNWP fnWndFrameProc;
|
||||
|
||||
PVODATA pVOData; /* Video output data */
|
||||
|
||||
HRGN hrgnShape;
|
||||
HPOINTER hptrIcon;
|
||||
RECTL rectlBeforeFS;
|
||||
|
||||
LONG lSkipWMSize;
|
||||
LONG lSkipWMMove;
|
||||
LONG lSkipWMMouseMove;
|
||||
LONG lSkipWMVRNEnabled;
|
||||
LONG lSkipWMAdjustFramePos;
|
||||
} WINDATA;
|
||||
|
||||
typedef struct _DISPLAYDATA {
|
||||
ULONG ulDPIHor;
|
||||
ULONG ulDPIVer;
|
||||
ULONG ulDPIDiag;
|
||||
} DISPLAYDATA;
|
||||
|
||||
typedef struct _MODEDATA {
|
||||
ULONG ulDepth;
|
||||
ULONG fccColorEncoding;
|
||||
ULONG ulScanLineBytes;
|
||||
} MODEDATA;
|
||||
|
||||
#endif /* SDL_os2video_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,483 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
#include "../SDL_sysvideo.h"
|
||||
|
||||
#define INCL_DOSERRORS
|
||||
#define INCL_DOSPROCESS
|
||||
#define INCL_DOSMODULEMGR
|
||||
#define INCL_WIN
|
||||
#define INCL_GPI
|
||||
#define INCL_GPIBITMAPS /* GPI bit map functions */
|
||||
#include <os2.h>
|
||||
#include "SDL_os2output.h"
|
||||
#include "SDL_os2video.h"
|
||||
|
||||
#include "SDL_gradd.h"
|
||||
|
||||
typedef struct _VODATA {
|
||||
PVOID pBuffer;
|
||||
HRGN hrgnVisible;
|
||||
ULONG ulBPP;
|
||||
ULONG ulScanLineSize;
|
||||
ULONG ulWidth;
|
||||
ULONG ulHeight;
|
||||
ULONG ulScreenHeight;
|
||||
ULONG ulScreenBytesPerLine;
|
||||
RECTL rectlWin;
|
||||
|
||||
PRECTL pRectl;
|
||||
ULONG cRectl;
|
||||
PBLTRECT pBltRect;
|
||||
ULONG cBltRect;
|
||||
} VODATA;
|
||||
|
||||
static BOOL voQueryInfo(VIDEOOUTPUTINFO *pInfo);
|
||||
static PVODATA voOpen();
|
||||
static VOID voClose(PVODATA pVOData);
|
||||
static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd,
|
||||
SDL_DisplayMode *pSDLDisplayMode,
|
||||
HRGN hrgnShape, BOOL fVisible);
|
||||
static PVOID voVideoBufAlloc(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight,
|
||||
ULONG ulBPP, ULONG fccColorEncoding,
|
||||
PULONG pulScanLineSize);
|
||||
static VOID voVideoBufFree(PVODATA pVOData);
|
||||
static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects,
|
||||
ULONG cSDLRects);
|
||||
|
||||
OS2VIDEOOUTPUT voVMan = {
|
||||
voQueryInfo,
|
||||
voOpen,
|
||||
voClose,
|
||||
voSetVisibleRegion,
|
||||
voVideoBufAlloc,
|
||||
voVideoBufFree,
|
||||
voUpdate
|
||||
};
|
||||
|
||||
|
||||
static HMODULE hmodVMan = NULLHANDLE;
|
||||
static FNVMIENTRY *pfnVMIEntry = NULL;
|
||||
static ULONG ulVRAMAddress = 0;
|
||||
|
||||
static VOID APIENTRY ExitVMan(VOID)
|
||||
{
|
||||
if (ulVRAMAddress != 0 && hmodVMan != NULLHANDLE) {
|
||||
pfnVMIEntry(0, VMI_CMD_TERMPROC, NULL, NULL);
|
||||
DosFreeModule(hmodVMan);
|
||||
}
|
||||
|
||||
DosExitList(EXLST_EXIT, (PFNEXITLIST)NULL);
|
||||
}
|
||||
|
||||
static BOOL _vmanInit(void)
|
||||
{
|
||||
ULONG ulRC;
|
||||
CHAR acBuf[256];
|
||||
INITPROCOUT stInitProcOut;
|
||||
|
||||
if (hmodVMan != NULLHANDLE) /* already initialized */
|
||||
return TRUE;
|
||||
|
||||
/* Load vman.dll */
|
||||
ulRC = DosLoadModule(acBuf, sizeof(acBuf), "VMAN", &hmodVMan);
|
||||
if (ulRC != NO_ERROR) {
|
||||
debug_os2("Could not load VMAN.DLL, rc = %u : %s", ulRC, acBuf);
|
||||
hmodVMan = NULLHANDLE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Get VMIEntry */
|
||||
ulRC = DosQueryProcAddr(hmodVMan, 0L, "VMIEntry", (PFN *)&pfnVMIEntry);
|
||||
if (ulRC != NO_ERROR) {
|
||||
debug_os2("Could not query address of VMIEntry from VMAN.DLL (Err: %lu)", ulRC);
|
||||
DosFreeModule(hmodVMan);
|
||||
hmodVMan = NULLHANDLE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* VMAN initialization */
|
||||
stInitProcOut.ulLength = sizeof(stInitProcOut);
|
||||
ulRC = pfnVMIEntry(0, VMI_CMD_INITPROC, NULL, &stInitProcOut);
|
||||
if (ulRC != RC_SUCCESS) {
|
||||
debug_os2("Could not initialize VMAN for this process");
|
||||
pfnVMIEntry = NULL;
|
||||
DosFreeModule(hmodVMan);
|
||||
hmodVMan = NULLHANDLE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Store video memory virtual address */
|
||||
ulVRAMAddress = stInitProcOut.ulVRAMVirt;
|
||||
/* We use exit list for VMI_CMD_TERMPROC */
|
||||
if (DosExitList(EXLST_ADD | 0x00001000, (PFNEXITLIST)ExitVMan) != NO_ERROR) {
|
||||
debug_os2("DosExitList() failed");
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static PRECTL _getRectlArray(PVODATA pVOData, ULONG cRects)
|
||||
{
|
||||
PRECTL pRectl;
|
||||
|
||||
if (pVOData->cRectl >= cRects)
|
||||
return pVOData->pRectl;
|
||||
|
||||
pRectl = SDL_realloc(pVOData->pRectl, cRects * sizeof(RECTL));
|
||||
if (pRectl == NULL)
|
||||
return NULL;
|
||||
|
||||
pVOData->pRectl = pRectl;
|
||||
pVOData->cRectl = cRects;
|
||||
return pRectl;
|
||||
}
|
||||
|
||||
static PBLTRECT _getBltRectArray(PVODATA pVOData, ULONG cRects)
|
||||
{
|
||||
PBLTRECT pBltRect;
|
||||
|
||||
if (pVOData->cBltRect >= cRects)
|
||||
return pVOData->pBltRect;
|
||||
|
||||
pBltRect = SDL_realloc(pVOData->pBltRect, cRects * sizeof(BLTRECT));
|
||||
if (pBltRect == NULL)
|
||||
return NULL;
|
||||
|
||||
pVOData->pBltRect = pBltRect;
|
||||
pVOData->cBltRect = cRects;
|
||||
return pBltRect;
|
||||
}
|
||||
|
||||
|
||||
static BOOL voQueryInfo(VIDEOOUTPUTINFO *pInfo)
|
||||
{
|
||||
ULONG ulRC;
|
||||
GDDMODEINFO sCurModeInfo;
|
||||
|
||||
if (!_vmanInit())
|
||||
return FALSE;
|
||||
|
||||
/* Query current (desktop) mode */
|
||||
ulRC = pfnVMIEntry(0, VMI_CMD_QUERYCURRENTMODE, NULL, &sCurModeInfo);
|
||||
if (ulRC != RC_SUCCESS) {
|
||||
debug_os2("Could not query desktop video mode.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pInfo->ulBPP = sCurModeInfo.ulBpp;
|
||||
pInfo->ulHorizResolution = sCurModeInfo.ulHorizResolution;
|
||||
pInfo->ulVertResolution = sCurModeInfo.ulVertResolution;
|
||||
pInfo->ulScanLineSize = sCurModeInfo.ulScanLineSize;
|
||||
pInfo->fccColorEncoding = sCurModeInfo.fccColorEncoding;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static PVODATA voOpen(void)
|
||||
{
|
||||
PVODATA pVOData;
|
||||
|
||||
if (!_vmanInit())
|
||||
return NULL;
|
||||
|
||||
pVOData = SDL_calloc(1, sizeof(VODATA));
|
||||
if (pVOData == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pVOData;
|
||||
}
|
||||
|
||||
static VOID voClose(PVODATA pVOData)
|
||||
{
|
||||
if (pVOData->pRectl != NULL)
|
||||
SDL_free(pVOData->pRectl);
|
||||
|
||||
if (pVOData->pBltRect != NULL)
|
||||
SDL_free(pVOData->pBltRect);
|
||||
|
||||
voVideoBufFree(pVOData);
|
||||
}
|
||||
|
||||
static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd,
|
||||
SDL_DisplayMode *pSDLDisplayMode,
|
||||
HRGN hrgnShape, BOOL fVisible)
|
||||
{
|
||||
HPS hps;
|
||||
BOOL fSuccess = FALSE;
|
||||
|
||||
hps = WinGetPS(hwnd);
|
||||
|
||||
if (pVOData->hrgnVisible != NULLHANDLE) {
|
||||
GpiDestroyRegion(hps, pVOData->hrgnVisible);
|
||||
pVOData->hrgnVisible = NULLHANDLE;
|
||||
}
|
||||
|
||||
if (fVisible) {
|
||||
/* Query visible rectangles */
|
||||
pVOData->hrgnVisible = GpiCreateRegion(hps, 0, NULL);
|
||||
if (pVOData->hrgnVisible == NULLHANDLE) {
|
||||
SDL_SetError("GpiCreateRegion() failed");
|
||||
} else {
|
||||
if (WinQueryVisibleRegion(hwnd, pVOData->hrgnVisible) == RGN_ERROR) {
|
||||
GpiDestroyRegion(hps, pVOData->hrgnVisible);
|
||||
pVOData->hrgnVisible = NULLHANDLE;
|
||||
} else {
|
||||
if (hrgnShape != NULLHANDLE)
|
||||
GpiCombineRegion(hps, pVOData->hrgnVisible, pVOData->hrgnVisible,
|
||||
hrgnShape, CRGN_AND);
|
||||
fSuccess = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
WinQueryWindowRect(hwnd, &pVOData->rectlWin);
|
||||
WinMapWindowPoints(hwnd, HWND_DESKTOP, (PPOINTL)&pVOData->rectlWin, 2);
|
||||
|
||||
if (pSDLDisplayMode != NULL) {
|
||||
pVOData->ulScreenHeight = pSDLDisplayMode->h;
|
||||
pVOData->ulScreenBytesPerLine =
|
||||
((MODEDATA *)pSDLDisplayMode->driverdata)->ulScanLineBytes;
|
||||
}
|
||||
}
|
||||
|
||||
WinReleasePS(hps);
|
||||
|
||||
return fSuccess;
|
||||
}
|
||||
|
||||
static PVOID voVideoBufAlloc(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight,
|
||||
ULONG ulBPP, ULONG fccColorEncoding,
|
||||
PULONG pulScanLineSize)
|
||||
{
|
||||
ULONG ulRC;
|
||||
ULONG ulScanLineSize = ulWidth * (ulBPP >> 3);
|
||||
|
||||
/* Destroy previous buffer */
|
||||
voVideoBufFree(pVOData);
|
||||
|
||||
if (ulWidth == 0 || ulHeight == 0 || ulBPP == 0)
|
||||
return NULL;
|
||||
|
||||
/* Bytes per line */
|
||||
ulScanLineSize = (ulScanLineSize + 3) & ~3; /* 4-byte aligning */
|
||||
*pulScanLineSize = ulScanLineSize;
|
||||
|
||||
ulRC = DosAllocMem(&pVOData->pBuffer,
|
||||
(ulHeight * ulScanLineSize) + sizeof(ULONG),
|
||||
PAG_COMMIT | PAG_EXECUTE | PAG_READ | PAG_WRITE);
|
||||
if (ulRC != NO_ERROR) {
|
||||
debug_os2("DosAllocMem(), rc = %u", ulRC);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pVOData->ulBPP = ulBPP;
|
||||
pVOData->ulScanLineSize = ulScanLineSize;
|
||||
pVOData->ulWidth = ulWidth;
|
||||
pVOData->ulHeight = ulHeight;
|
||||
|
||||
return pVOData->pBuffer;
|
||||
}
|
||||
|
||||
static VOID voVideoBufFree(PVODATA pVOData)
|
||||
{
|
||||
ULONG ulRC;
|
||||
|
||||
if (pVOData->pBuffer == NULL)
|
||||
return;
|
||||
|
||||
ulRC = DosFreeMem(pVOData->pBuffer);
|
||||
if (ulRC != NO_ERROR) {
|
||||
debug_os2("DosFreeMem(), rc = %u", ulRC);
|
||||
} else {
|
||||
pVOData->pBuffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects,
|
||||
ULONG cSDLRects)
|
||||
{
|
||||
PRECTL prectlDst, prectlScan;
|
||||
HPS hps;
|
||||
HRGN hrgnUpdate;
|
||||
RGNRECT rgnCtl;
|
||||
SDL_Rect stSDLRectDef;
|
||||
BMAPINFO bmiSrc;
|
||||
BMAPINFO bmiDst;
|
||||
PPOINTL pptlSrcOrg;
|
||||
PBLTRECT pbrDst;
|
||||
HWREQIN sHWReqIn;
|
||||
BITBLTINFO sBitbltInfo;
|
||||
ULONG ulIdx;
|
||||
|
||||
if (pVOData->pBuffer == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (pVOData->hrgnVisible == NULLHANDLE)
|
||||
return TRUE;
|
||||
|
||||
bmiSrc.ulLength = sizeof(BMAPINFO);
|
||||
bmiSrc.ulType = BMAP_MEMORY;
|
||||
bmiSrc.ulWidth = pVOData->ulWidth;
|
||||
bmiSrc.ulHeight = pVOData->ulHeight;
|
||||
bmiSrc.ulBpp = pVOData->ulBPP;
|
||||
bmiSrc.ulBytesPerLine = pVOData->ulScanLineSize;
|
||||
bmiSrc.pBits = (PBYTE)pVOData->pBuffer;
|
||||
|
||||
bmiDst.ulLength = sizeof(BMAPINFO);
|
||||
bmiDst.ulType = BMAP_VRAM;
|
||||
bmiDst.pBits = (PBYTE)ulVRAMAddress;
|
||||
bmiDst.ulWidth = bmiSrc.ulWidth;
|
||||
bmiDst.ulHeight = bmiSrc.ulHeight;
|
||||
bmiDst.ulBpp = bmiSrc.ulBpp;
|
||||
bmiDst.ulBytesPerLine = pVOData->ulScreenBytesPerLine;
|
||||
|
||||
/* List of update rectangles. This is the intersection of requested
|
||||
* rectangles and visible rectangles. */
|
||||
if (cSDLRects == 0) {
|
||||
/* Full update requested */
|
||||
stSDLRectDef.x = 0;
|
||||
stSDLRectDef.y = 0;
|
||||
stSDLRectDef.w = bmiSrc.ulWidth;
|
||||
stSDLRectDef.h = bmiSrc.ulHeight;
|
||||
pSDLRects = &stSDLRectDef;
|
||||
cSDLRects = 1;
|
||||
}
|
||||
|
||||
/* Make list of destination rectangles (prectlDst) list from the source
|
||||
* list (prectl). */
|
||||
prectlDst = _getRectlArray(pVOData, cSDLRects);
|
||||
if (prectlDst == NULL) {
|
||||
debug_os2("Not enough memory");
|
||||
return FALSE;
|
||||
}
|
||||
prectlScan = prectlDst;
|
||||
for (ulIdx = 0; ulIdx < cSDLRects; ulIdx++, pSDLRects++, prectlScan++) {
|
||||
prectlScan->xLeft = pSDLRects->x;
|
||||
prectlScan->yTop = pVOData->ulHeight - pSDLRects->y;
|
||||
prectlScan->xRight = prectlScan->xLeft + pSDLRects->w;
|
||||
prectlScan->yBottom = prectlScan->yTop - pSDLRects->h;
|
||||
}
|
||||
|
||||
hps = WinGetPS(hwnd);
|
||||
if (hps == NULLHANDLE)
|
||||
return FALSE;
|
||||
|
||||
/* Make destination region to update */
|
||||
hrgnUpdate = GpiCreateRegion(hps, cSDLRects, prectlDst);
|
||||
/* "AND" on visible and destination regions, result is region to update */
|
||||
GpiCombineRegion(hps, hrgnUpdate, hrgnUpdate, pVOData->hrgnVisible, CRGN_AND);
|
||||
|
||||
/* Get rectangles of the region to update */
|
||||
rgnCtl.ircStart = 1;
|
||||
rgnCtl.crc = 0;
|
||||
rgnCtl.ulDirection = 1;
|
||||
rgnCtl.crcReturned = 0;
|
||||
GpiQueryRegionRects(hps, hrgnUpdate, NULL, &rgnCtl, NULL);
|
||||
if (rgnCtl.crcReturned == 0) {
|
||||
GpiDestroyRegion(hps, hrgnUpdate);
|
||||
WinReleasePS(hps);
|
||||
return TRUE;
|
||||
}
|
||||
/* We don't need prectlDst, use it again to store update regions */
|
||||
prectlDst = _getRectlArray(pVOData, rgnCtl.crcReturned);
|
||||
if (prectlDst == NULL) {
|
||||
debug_os2("Not enough memory");
|
||||
GpiDestroyRegion(hps, hrgnUpdate);
|
||||
WinReleasePS(hps);
|
||||
return FALSE;
|
||||
}
|
||||
rgnCtl.ircStart = 1;
|
||||
rgnCtl.crc = rgnCtl.crcReturned;
|
||||
rgnCtl.ulDirection = 1;
|
||||
GpiQueryRegionRects(hps, hrgnUpdate, NULL, &rgnCtl, prectlDst);
|
||||
GpiDestroyRegion(hps, hrgnUpdate);
|
||||
WinReleasePS(hps);
|
||||
cSDLRects = rgnCtl.crcReturned;
|
||||
|
||||
/* Now cRect/prectlDst is a list of regions in window (update && visible) */
|
||||
|
||||
/* Make lists for blitting from update regions */
|
||||
pbrDst = _getBltRectArray(pVOData, cSDLRects);
|
||||
if (pbrDst == NULL) {
|
||||
debug_os2("Not enough memory");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
prectlScan = prectlDst;
|
||||
pptlSrcOrg = (PPOINTL)prectlDst; /* Yes, this memory block will be used again */
|
||||
for (ulIdx = 0; ulIdx < cSDLRects; ulIdx++, prectlScan++, pptlSrcOrg++) {
|
||||
pbrDst[ulIdx].ulXOrg = pVOData->rectlWin.xLeft + prectlScan->xLeft;
|
||||
pbrDst[ulIdx].ulYOrg = pVOData->ulScreenHeight -
|
||||
(pVOData->rectlWin.yBottom + prectlScan->yTop);
|
||||
pbrDst[ulIdx].ulXExt = prectlScan->xRight - prectlScan->xLeft;
|
||||
pbrDst[ulIdx].ulYExt = prectlScan->yTop - prectlScan->yBottom;
|
||||
pptlSrcOrg->x = prectlScan->xLeft;
|
||||
pptlSrcOrg->y = bmiSrc.ulHeight - prectlScan->yTop;
|
||||
}
|
||||
pptlSrcOrg = (PPOINTL)prectlDst;
|
||||
|
||||
/* Request HW */
|
||||
sHWReqIn.ulLength = sizeof(HWREQIN);
|
||||
sHWReqIn.ulFlags = REQUEST_HW;
|
||||
sHWReqIn.cScrChangeRects = 1;
|
||||
sHWReqIn.arectlScreen = &pVOData->rectlWin;
|
||||
if (pfnVMIEntry(0, VMI_CMD_REQUESTHW, &sHWReqIn, NULL) != RC_SUCCESS) {
|
||||
debug_os2("pfnVMIEntry(,VMI_CMD_REQUESTHW,,) failed");
|
||||
sHWReqIn.cScrChangeRects = 0; /* for fail signal only */
|
||||
} else {
|
||||
RECTL rclSrcBounds;
|
||||
|
||||
rclSrcBounds.xLeft = 0;
|
||||
rclSrcBounds.yBottom = 0;
|
||||
rclSrcBounds.xRight = bmiSrc.ulWidth;
|
||||
rclSrcBounds.yTop = bmiSrc.ulHeight;
|
||||
|
||||
SDL_zero(sBitbltInfo);
|
||||
sBitbltInfo.ulLength = sizeof(BITBLTINFO);
|
||||
sBitbltInfo.ulBltFlags = BF_DEFAULT_STATE | BF_ROP_INCL_SRC | BF_PAT_HOLLOW;
|
||||
sBitbltInfo.cBlits = cSDLRects;
|
||||
sBitbltInfo.ulROP = ROP_SRCCOPY;
|
||||
sBitbltInfo.pSrcBmapInfo = &bmiSrc;
|
||||
sBitbltInfo.pDstBmapInfo = &bmiDst;
|
||||
sBitbltInfo.prclSrcBounds = &rclSrcBounds;
|
||||
sBitbltInfo.prclDstBounds = &pVOData->rectlWin;
|
||||
sBitbltInfo.aptlSrcOrg = pptlSrcOrg;
|
||||
sBitbltInfo.abrDst = pbrDst;
|
||||
|
||||
/* Screen update */
|
||||
if (pfnVMIEntry(0, VMI_CMD_BITBLT, &sBitbltInfo, NULL) != RC_SUCCESS) {
|
||||
debug_os2("pfnVMIEntry(,VMI_CMD_BITBLT,,) failed");
|
||||
sHWReqIn.cScrChangeRects = 0; /* for fail signal only */
|
||||
}
|
||||
|
||||
/* Release HW */
|
||||
sHWReqIn.ulFlags = 0;
|
||||
if (pfnVMIEntry(0, VMI_CMD_REQUESTHW, &sHWReqIn, NULL) != RC_SUCCESS) {
|
||||
debug_os2("pfnVMIEntry(,VMI_CMD_REQUESTHW,,) failed");
|
||||
}
|
||||
}
|
||||
|
||||
return sHWReqIn.cScrChangeRects != 0;
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,833 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_PANDORA
|
||||
|
||||
/* SDL internals */
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "SDL_version.h"
|
||||
#include "SDL_syswm.h"
|
||||
#include "SDL_loadso.h"
|
||||
#include "SDL_events.h"
|
||||
#include "../../events/SDL_mouse_c.h"
|
||||
#include "../../events/SDL_keyboard_c.h"
|
||||
|
||||
/* PND declarations */
|
||||
#include "SDL_pandora.h"
|
||||
#include "SDL_pandora_events.h"
|
||||
|
||||
/* WIZ declarations */
|
||||
#include "GLES/gl.h"
|
||||
#ifdef WIZ_GLES_LITE
|
||||
static NativeWindowType hNativeWnd = 0; /* A handle to the window we will create. */
|
||||
#endif
|
||||
|
||||
static int
|
||||
PND_available(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
PND_destroy(SDL_VideoDevice * device)
|
||||
{
|
||||
if (device->driverdata != NULL) {
|
||||
SDL_free(device->driverdata);
|
||||
device->driverdata = NULL;
|
||||
}
|
||||
SDL_free(device);
|
||||
}
|
||||
|
||||
static SDL_VideoDevice *
|
||||
PND_create()
|
||||
{
|
||||
SDL_VideoDevice *device;
|
||||
SDL_VideoData *phdata;
|
||||
int status;
|
||||
|
||||
/* Check if pandora could be initialized */
|
||||
status = PND_available();
|
||||
if (status == 0) {
|
||||
/* PND could not be used */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize SDL_VideoDevice structure */
|
||||
device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
|
||||
if (device == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize internal Pandora specific data */
|
||||
phdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
|
||||
if (phdata == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
SDL_free(device);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
device->driverdata = phdata;
|
||||
|
||||
phdata->egl_initialized = SDL_TRUE;
|
||||
|
||||
|
||||
/* Setup amount of available displays */
|
||||
device->num_displays = 0;
|
||||
|
||||
/* Set device free function */
|
||||
device->free = PND_destroy;
|
||||
|
||||
/* Setup all functions which we can handle */
|
||||
device->VideoInit = PND_videoinit;
|
||||
device->VideoQuit = PND_videoquit;
|
||||
device->GetDisplayModes = PND_getdisplaymodes;
|
||||
device->SetDisplayMode = PND_setdisplaymode;
|
||||
device->CreateSDLWindow = PND_createwindow;
|
||||
device->CreateSDLWindowFrom = PND_createwindowfrom;
|
||||
device->SetWindowTitle = PND_setwindowtitle;
|
||||
device->SetWindowIcon = PND_setwindowicon;
|
||||
device->SetWindowPosition = PND_setwindowposition;
|
||||
device->SetWindowSize = PND_setwindowsize;
|
||||
device->ShowWindow = PND_showwindow;
|
||||
device->HideWindow = PND_hidewindow;
|
||||
device->RaiseWindow = PND_raisewindow;
|
||||
device->MaximizeWindow = PND_maximizewindow;
|
||||
device->MinimizeWindow = PND_minimizewindow;
|
||||
device->RestoreWindow = PND_restorewindow;
|
||||
device->DestroyWindow = PND_destroywindow;
|
||||
#if 0
|
||||
device->GetWindowWMInfo = PND_getwindowwminfo;
|
||||
#endif
|
||||
device->GL_LoadLibrary = PND_gl_loadlibrary;
|
||||
device->GL_GetProcAddress = PND_gl_getprocaddres;
|
||||
device->GL_UnloadLibrary = PND_gl_unloadlibrary;
|
||||
device->GL_CreateContext = PND_gl_createcontext;
|
||||
device->GL_MakeCurrent = PND_gl_makecurrent;
|
||||
device->GL_SetSwapInterval = PND_gl_setswapinterval;
|
||||
device->GL_GetSwapInterval = PND_gl_getswapinterval;
|
||||
device->GL_SwapWindow = PND_gl_swapwindow;
|
||||
device->GL_DeleteContext = PND_gl_deletecontext;
|
||||
device->PumpEvents = PND_PumpEvents;
|
||||
|
||||
/* !!! FIXME: implement SetWindowBordered */
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
VideoBootStrap PND_bootstrap = {
|
||||
#ifdef WIZ_GLES_LITE
|
||||
"wiz",
|
||||
"SDL Wiz Video Driver",
|
||||
#else
|
||||
"pandora",
|
||||
"SDL Pandora Video Driver",
|
||||
#endif
|
||||
PND_available,
|
||||
PND_create
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
/* SDL Video and Display initialization/handling functions */
|
||||
/*****************************************************************************/
|
||||
int
|
||||
PND_videoinit(_THIS)
|
||||
{
|
||||
SDL_VideoDisplay display;
|
||||
SDL_DisplayMode current_mode;
|
||||
|
||||
SDL_zero(current_mode);
|
||||
#ifdef WIZ_GLES_LITE
|
||||
current_mode.w = 320;
|
||||
current_mode.h = 240;
|
||||
#else
|
||||
current_mode.w = 800;
|
||||
current_mode.h = 480;
|
||||
#endif
|
||||
current_mode.refresh_rate = 60;
|
||||
current_mode.format = SDL_PIXELFORMAT_RGB565;
|
||||
current_mode.driverdata = NULL;
|
||||
|
||||
SDL_zero(display);
|
||||
display.desktop_mode = current_mode;
|
||||
display.current_mode = current_mode;
|
||||
display.driverdata = NULL;
|
||||
|
||||
SDL_AddVideoDisplay(&display, SDL_FALSE);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
PND_videoquit(_THIS)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
PND_getdisplaymodes(_THIS, SDL_VideoDisplay * display)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
PND_setdisplaymode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
PND_createwindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
|
||||
|
||||
SDL_WindowData *wdata;
|
||||
|
||||
/* Allocate window internal data */
|
||||
wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
|
||||
if (wdata == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
/* Setup driver data for this window */
|
||||
window->driverdata = wdata;
|
||||
|
||||
/* Check if window must support OpenGL ES rendering */
|
||||
if ((window->flags & SDL_WINDOW_OPENGL) == SDL_WINDOW_OPENGL) {
|
||||
|
||||
EGLBoolean initstatus;
|
||||
|
||||
/* Mark this window as OpenGL ES compatible */
|
||||
wdata->uses_gles = SDL_TRUE;
|
||||
|
||||
/* Create connection to OpenGL ES */
|
||||
if (phdata->egl_display == EGL_NO_DISPLAY) {
|
||||
phdata->egl_display = eglGetDisplay((NativeDisplayType) 0);
|
||||
if (phdata->egl_display == EGL_NO_DISPLAY) {
|
||||
return SDL_SetError("PND: Can't get connection to OpenGL ES");
|
||||
}
|
||||
|
||||
initstatus = eglInitialize(phdata->egl_display, NULL, NULL);
|
||||
if (initstatus != EGL_TRUE) {
|
||||
return SDL_SetError("PND: Can't init OpenGL ES library");
|
||||
}
|
||||
}
|
||||
|
||||
phdata->egl_refcount++;
|
||||
}
|
||||
|
||||
/* Window has been successfully created */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
PND_createwindowfrom(_THIS, SDL_Window * window, const void *data)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
PND_setwindowtitle(_THIS, SDL_Window * window)
|
||||
{
|
||||
}
|
||||
void
|
||||
PND_setwindowicon(_THIS, SDL_Window * window, SDL_Surface * icon)
|
||||
{
|
||||
}
|
||||
void
|
||||
PND_setwindowposition(_THIS, SDL_Window * window)
|
||||
{
|
||||
}
|
||||
void
|
||||
PND_setwindowsize(_THIS, SDL_Window * window)
|
||||
{
|
||||
}
|
||||
void
|
||||
PND_showwindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
}
|
||||
void
|
||||
PND_hidewindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
}
|
||||
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_destroywindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
|
||||
eglTerminate(phdata->egl_display);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* SDL Window Manager function */
|
||||
/*****************************************************************************/
|
||||
#if 0
|
||||
SDL_bool
|
||||
PND_getwindowwminfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
|
||||
{
|
||||
if (info->version.major <= SDL_MAJOR_VERSION) {
|
||||
return SDL_TRUE;
|
||||
} else {
|
||||
SDL_SetError("application not compiled with SDL %d",
|
||||
SDL_MAJOR_VERSION);
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Failed to get window manager information */
|
||||
return SDL_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/* SDL OpenGL/OpenGL ES functions */
|
||||
/*****************************************************************************/
|
||||
int
|
||||
PND_gl_loadlibrary(_THIS, const char *path)
|
||||
{
|
||||
/* Check if OpenGL ES library is specified for GF driver */
|
||||
if (path == NULL) {
|
||||
path = SDL_getenv("SDL_OPENGL_LIBRARY");
|
||||
if (path == NULL) {
|
||||
path = SDL_getenv("SDL_OPENGLES_LIBRARY");
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if default library loading requested */
|
||||
if (path == NULL) {
|
||||
/* Already linked with GF library which provides egl* subset of */
|
||||
/* functions, use Common profile of OpenGL ES library by default */
|
||||
#ifdef WIZ_GLES_LITE
|
||||
path = "/lib/libopengles_lite.so";
|
||||
#else
|
||||
path = "/usr/lib/libGLES_CM.so";
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Load dynamic library */
|
||||
_this->gl_config.dll_handle = SDL_LoadObject(path);
|
||||
if (!_this->gl_config.dll_handle) {
|
||||
/* Failed to load new GL ES library */
|
||||
return SDL_SetError("PND: Failed to locate OpenGL ES library");
|
||||
}
|
||||
|
||||
/* Store OpenGL ES library path and name */
|
||||
SDL_strlcpy(_this->gl_config.driver_path, path,
|
||||
SDL_arraysize(_this->gl_config.driver_path));
|
||||
|
||||
/* New OpenGL ES library is loaded */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *
|
||||
PND_gl_getprocaddres(_THIS, const char *proc)
|
||||
{
|
||||
void *function_address;
|
||||
|
||||
/* Try to get function address through the egl interface */
|
||||
function_address = eglGetProcAddress(proc);
|
||||
if (function_address != NULL) {
|
||||
return function_address;
|
||||
}
|
||||
|
||||
/* Then try to get function in the OpenGL ES library */
|
||||
if (_this->gl_config.dll_handle) {
|
||||
function_address =
|
||||
SDL_LoadFunction(_this->gl_config.dll_handle, proc);
|
||||
if (function_address != NULL) {
|
||||
return function_address;
|
||||
}
|
||||
}
|
||||
|
||||
/* Failed to get GL ES function address pointer */
|
||||
SDL_SetError("PND: Cannot locate OpenGL ES function name");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
PND_gl_unloadlibrary(_THIS)
|
||||
{
|
||||
SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
|
||||
|
||||
if (phdata->egl_initialized == SDL_TRUE) {
|
||||
/* Unload OpenGL ES library */
|
||||
if (_this->gl_config.dll_handle) {
|
||||
SDL_UnloadObject(_this->gl_config.dll_handle);
|
||||
_this->gl_config.dll_handle = NULL;
|
||||
}
|
||||
} else {
|
||||
SDL_SetError("PND: GF initialization failed, no OpenGL ES support");
|
||||
}
|
||||
}
|
||||
|
||||
SDL_GLContext
|
||||
PND_gl_createcontext(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
|
||||
SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
|
||||
EGLBoolean status;
|
||||
EGLint configs;
|
||||
uint32_t attr_pos;
|
||||
EGLint attr_value;
|
||||
EGLint cit;
|
||||
|
||||
/* Check if EGL was initialized */
|
||||
if (phdata->egl_initialized != SDL_TRUE) {
|
||||
SDL_SetError("PND: EGL initialization failed, no OpenGL ES support");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Prepare attributes list to pass them to OpenGL ES */
|
||||
attr_pos = 0;
|
||||
wdata->gles_attributes[attr_pos++] = EGL_SURFACE_TYPE;
|
||||
wdata->gles_attributes[attr_pos++] = EGL_WINDOW_BIT;
|
||||
wdata->gles_attributes[attr_pos++] = EGL_RED_SIZE;
|
||||
wdata->gles_attributes[attr_pos++] = _this->gl_config.red_size;
|
||||
wdata->gles_attributes[attr_pos++] = EGL_GREEN_SIZE;
|
||||
wdata->gles_attributes[attr_pos++] = _this->gl_config.green_size;
|
||||
wdata->gles_attributes[attr_pos++] = EGL_BLUE_SIZE;
|
||||
wdata->gles_attributes[attr_pos++] = _this->gl_config.blue_size;
|
||||
wdata->gles_attributes[attr_pos++] = EGL_ALPHA_SIZE;
|
||||
|
||||
/* Setup alpha size in bits */
|
||||
if (_this->gl_config.alpha_size) {
|
||||
wdata->gles_attributes[attr_pos++] = _this->gl_config.alpha_size;
|
||||
} else {
|
||||
wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
|
||||
}
|
||||
|
||||
/* Setup color buffer size */
|
||||
if (_this->gl_config.buffer_size) {
|
||||
wdata->gles_attributes[attr_pos++] = EGL_BUFFER_SIZE;
|
||||
wdata->gles_attributes[attr_pos++] = _this->gl_config.buffer_size;
|
||||
} else {
|
||||
wdata->gles_attributes[attr_pos++] = EGL_BUFFER_SIZE;
|
||||
wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
|
||||
}
|
||||
|
||||
/* Setup depth buffer bits */
|
||||
wdata->gles_attributes[attr_pos++] = EGL_DEPTH_SIZE;
|
||||
wdata->gles_attributes[attr_pos++] = _this->gl_config.depth_size;
|
||||
|
||||
/* Setup stencil bits */
|
||||
if (_this->gl_config.stencil_size) {
|
||||
wdata->gles_attributes[attr_pos++] = EGL_STENCIL_SIZE;
|
||||
wdata->gles_attributes[attr_pos++] = _this->gl_config.buffer_size;
|
||||
} else {
|
||||
wdata->gles_attributes[attr_pos++] = EGL_STENCIL_SIZE;
|
||||
wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
|
||||
}
|
||||
|
||||
/* Set number of samples in multisampling */
|
||||
if (_this->gl_config.multisamplesamples) {
|
||||
wdata->gles_attributes[attr_pos++] = EGL_SAMPLES;
|
||||
wdata->gles_attributes[attr_pos++] =
|
||||
_this->gl_config.multisamplesamples;
|
||||
}
|
||||
|
||||
/* Multisample buffers, OpenGL ES 1.0 spec defines 0 or 1 buffer */
|
||||
if (_this->gl_config.multisamplebuffers) {
|
||||
wdata->gles_attributes[attr_pos++] = EGL_SAMPLE_BUFFERS;
|
||||
wdata->gles_attributes[attr_pos++] =
|
||||
_this->gl_config.multisamplebuffers;
|
||||
}
|
||||
|
||||
/* Finish attributes list */
|
||||
wdata->gles_attributes[attr_pos] = EGL_NONE;
|
||||
|
||||
/* Request first suitable framebuffer configuration */
|
||||
status = eglChooseConfig(phdata->egl_display, wdata->gles_attributes,
|
||||
wdata->gles_configs, 1, &configs);
|
||||
if (status != EGL_TRUE) {
|
||||
SDL_SetError("PND: Can't find closest configuration for OpenGL ES");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check if nothing has been found, try "don't care" settings */
|
||||
if (configs == 0) {
|
||||
int32_t it;
|
||||
int32_t jt;
|
||||
GLint depthbits[4] = { 32, 24, 16, EGL_DONT_CARE };
|
||||
|
||||
for (it = 0; it < 4; it++) {
|
||||
for (jt = 16; jt >= 0; jt--) {
|
||||
/* Don't care about color buffer bits, use what exist */
|
||||
/* Replace previous set data with EGL_DONT_CARE */
|
||||
attr_pos = 0;
|
||||
wdata->gles_attributes[attr_pos++] = EGL_SURFACE_TYPE;
|
||||
wdata->gles_attributes[attr_pos++] = EGL_WINDOW_BIT;
|
||||
wdata->gles_attributes[attr_pos++] = EGL_RED_SIZE;
|
||||
wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
|
||||
wdata->gles_attributes[attr_pos++] = EGL_GREEN_SIZE;
|
||||
wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
|
||||
wdata->gles_attributes[attr_pos++] = EGL_BLUE_SIZE;
|
||||
wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
|
||||
wdata->gles_attributes[attr_pos++] = EGL_ALPHA_SIZE;
|
||||
wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
|
||||
wdata->gles_attributes[attr_pos++] = EGL_BUFFER_SIZE;
|
||||
wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
|
||||
|
||||
/* Try to find requested or smallest depth */
|
||||
if (_this->gl_config.depth_size) {
|
||||
wdata->gles_attributes[attr_pos++] = EGL_DEPTH_SIZE;
|
||||
wdata->gles_attributes[attr_pos++] = depthbits[it];
|
||||
} else {
|
||||
wdata->gles_attributes[attr_pos++] = EGL_DEPTH_SIZE;
|
||||
wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
|
||||
}
|
||||
|
||||
if (_this->gl_config.stencil_size) {
|
||||
wdata->gles_attributes[attr_pos++] = EGL_STENCIL_SIZE;
|
||||
wdata->gles_attributes[attr_pos++] = jt;
|
||||
} else {
|
||||
wdata->gles_attributes[attr_pos++] = EGL_STENCIL_SIZE;
|
||||
wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
|
||||
}
|
||||
|
||||
wdata->gles_attributes[attr_pos++] = EGL_SAMPLES;
|
||||
wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
|
||||
wdata->gles_attributes[attr_pos++] = EGL_SAMPLE_BUFFERS;
|
||||
wdata->gles_attributes[attr_pos++] = EGL_DONT_CARE;
|
||||
wdata->gles_attributes[attr_pos] = EGL_NONE;
|
||||
|
||||
/* Request first suitable framebuffer configuration */
|
||||
status =
|
||||
eglChooseConfig(phdata->egl_display,
|
||||
wdata->gles_attributes,
|
||||
wdata->gles_configs, 1, &configs);
|
||||
|
||||
if (status != EGL_TRUE) {
|
||||
SDL_SetError
|
||||
("PND: Can't find closest configuration for OpenGL ES");
|
||||
return NULL;
|
||||
}
|
||||
if (configs != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (configs != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* No available configs */
|
||||
if (configs == 0) {
|
||||
SDL_SetError("PND: Can't find any configuration for OpenGL ES");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize config index */
|
||||
wdata->gles_config = 0;
|
||||
|
||||
/* Now check each configuration to find out the best */
|
||||
for (cit = 0; cit < configs; cit++) {
|
||||
uint32_t stencil_found;
|
||||
uint32_t depth_found;
|
||||
|
||||
stencil_found = 0;
|
||||
depth_found = 0;
|
||||
|
||||
if (_this->gl_config.stencil_size) {
|
||||
status =
|
||||
eglGetConfigAttrib(phdata->egl_display,
|
||||
wdata->gles_configs[cit], EGL_STENCIL_SIZE,
|
||||
&attr_value);
|
||||
if (status == EGL_TRUE) {
|
||||
if (attr_value != 0) {
|
||||
stencil_found = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
stencil_found = 1;
|
||||
}
|
||||
|
||||
if (_this->gl_config.depth_size) {
|
||||
status =
|
||||
eglGetConfigAttrib(phdata->egl_display,
|
||||
wdata->gles_configs[cit], EGL_DEPTH_SIZE,
|
||||
&attr_value);
|
||||
if (status == EGL_TRUE) {
|
||||
if (attr_value != 0) {
|
||||
depth_found = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
depth_found = 1;
|
||||
}
|
||||
|
||||
/* Exit from loop if found appropriate configuration */
|
||||
if ((depth_found != 0) && (stencil_found != 0)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If best could not be found, use first */
|
||||
if (cit == configs) {
|
||||
cit = 0;
|
||||
}
|
||||
wdata->gles_config = cit;
|
||||
|
||||
/* Create OpenGL ES context */
|
||||
wdata->gles_context =
|
||||
eglCreateContext(phdata->egl_display,
|
||||
wdata->gles_configs[wdata->gles_config], NULL, NULL);
|
||||
if (wdata->gles_context == EGL_NO_CONTEXT) {
|
||||
SDL_SetError("PND: OpenGL ES context creation has been failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef WIZ_GLES_LITE
|
||||
if( !hNativeWnd ) {
|
||||
hNativeWnd = (NativeWindowType)SDL_malloc(16*1024);
|
||||
|
||||
if(!hNativeWnd)
|
||||
printf( "Error: Wiz framebuffer allocatation failed\n" );
|
||||
else
|
||||
printf( "SDL: Wiz framebuffer allocated: %X\n", hNativeWnd );
|
||||
}
|
||||
else {
|
||||
printf( "SDL: Wiz framebuffer already allocated: %X\n", hNativeWnd );
|
||||
}
|
||||
|
||||
wdata->gles_surface =
|
||||
eglCreateWindowSurface(phdata->egl_display,
|
||||
wdata->gles_configs[wdata->gles_config],
|
||||
hNativeWnd, NULL );
|
||||
#else
|
||||
wdata->gles_surface =
|
||||
eglCreateWindowSurface(phdata->egl_display,
|
||||
wdata->gles_configs[wdata->gles_config],
|
||||
(NativeWindowType) 0, NULL);
|
||||
#endif
|
||||
|
||||
|
||||
if (wdata->gles_surface == 0) {
|
||||
SDL_SetError("Error : eglCreateWindowSurface failed;");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Make just created context current */
|
||||
status =
|
||||
eglMakeCurrent(phdata->egl_display, wdata->gles_surface,
|
||||
wdata->gles_surface, wdata->gles_context);
|
||||
if (status != EGL_TRUE) {
|
||||
/* Destroy OpenGL ES surface */
|
||||
eglDestroySurface(phdata->egl_display, wdata->gles_surface);
|
||||
eglDestroyContext(phdata->egl_display, wdata->gles_context);
|
||||
wdata->gles_context = EGL_NO_CONTEXT;
|
||||
SDL_SetError("PND: Can't set OpenGL ES context on creation");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_this->gl_config.accelerated = 1;
|
||||
|
||||
/* Always clear stereo enable, since OpenGL ES do not supports stereo */
|
||||
_this->gl_config.stereo = 0;
|
||||
|
||||
/* Get back samples and samplebuffers configurations. Rest framebuffer */
|
||||
/* parameters could be obtained through the OpenGL ES API */
|
||||
status =
|
||||
eglGetConfigAttrib(phdata->egl_display,
|
||||
wdata->gles_configs[wdata->gles_config],
|
||||
EGL_SAMPLES, &attr_value);
|
||||
if (status == EGL_TRUE) {
|
||||
_this->gl_config.multisamplesamples = attr_value;
|
||||
}
|
||||
status =
|
||||
eglGetConfigAttrib(phdata->egl_display,
|
||||
wdata->gles_configs[wdata->gles_config],
|
||||
EGL_SAMPLE_BUFFERS, &attr_value);
|
||||
if (status == EGL_TRUE) {
|
||||
_this->gl_config.multisamplebuffers = attr_value;
|
||||
}
|
||||
|
||||
/* Get back stencil and depth buffer sizes */
|
||||
status =
|
||||
eglGetConfigAttrib(phdata->egl_display,
|
||||
wdata->gles_configs[wdata->gles_config],
|
||||
EGL_DEPTH_SIZE, &attr_value);
|
||||
if (status == EGL_TRUE) {
|
||||
_this->gl_config.depth_size = attr_value;
|
||||
}
|
||||
status =
|
||||
eglGetConfigAttrib(phdata->egl_display,
|
||||
wdata->gles_configs[wdata->gles_config],
|
||||
EGL_STENCIL_SIZE, &attr_value);
|
||||
if (status == EGL_TRUE) {
|
||||
_this->gl_config.stencil_size = attr_value;
|
||||
}
|
||||
|
||||
/* Under PND OpenGL ES output can't be double buffered */
|
||||
_this->gl_config.double_buffer = 0;
|
||||
|
||||
/* GL ES context was successfully created */
|
||||
return wdata->gles_context;
|
||||
}
|
||||
|
||||
int
|
||||
PND_gl_makecurrent(_THIS, SDL_Window * window, SDL_GLContext context)
|
||||
{
|
||||
SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
|
||||
SDL_WindowData *wdata;
|
||||
EGLBoolean status;
|
||||
|
||||
if (phdata->egl_initialized != SDL_TRUE) {
|
||||
return SDL_SetError("PND: GF initialization failed, no OpenGL ES support");
|
||||
}
|
||||
|
||||
if ((window == NULL) && (context == NULL)) {
|
||||
status =
|
||||
eglMakeCurrent(phdata->egl_display, EGL_NO_SURFACE,
|
||||
EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
if (status != EGL_TRUE) {
|
||||
/* Failed to set current GL ES context */
|
||||
return SDL_SetError("PND: Can't set OpenGL ES context");
|
||||
}
|
||||
} else {
|
||||
wdata = (SDL_WindowData *) window->driverdata;
|
||||
if (wdata->gles_surface == EGL_NO_SURFACE) {
|
||||
return SDL_SetError
|
||||
("PND: OpenGL ES surface is not initialized for this window");
|
||||
}
|
||||
if (wdata->gles_context == EGL_NO_CONTEXT) {
|
||||
return SDL_SetError
|
||||
("PND: OpenGL ES context is not initialized for this window");
|
||||
}
|
||||
if (wdata->gles_context != context) {
|
||||
return SDL_SetError
|
||||
("PND: OpenGL ES context is not belong to this window");
|
||||
}
|
||||
status =
|
||||
eglMakeCurrent(phdata->egl_display, wdata->gles_surface,
|
||||
wdata->gles_surface, wdata->gles_context);
|
||||
if (status != EGL_TRUE) {
|
||||
/* Failed to set current GL ES context */
|
||||
return SDL_SetError("PND: Can't set OpenGL ES context");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
PND_gl_setswapinterval(_THIS, int interval)
|
||||
{
|
||||
SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
|
||||
EGLBoolean status;
|
||||
|
||||
if (phdata->egl_initialized != SDL_TRUE) {
|
||||
return SDL_SetError("PND: EGL initialization failed, no OpenGL ES support");
|
||||
}
|
||||
|
||||
/* Check if OpenGL ES connection has been initialized */
|
||||
if (phdata->egl_display != EGL_NO_DISPLAY) {
|
||||
/* Set swap OpenGL ES interval */
|
||||
status = eglSwapInterval(phdata->egl_display, interval);
|
||||
if (status == EGL_TRUE) {
|
||||
/* Return success to upper level */
|
||||
phdata->swapinterval = interval;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Failed to set swap interval */
|
||||
return SDL_SetError("PND: Cannot set swap interval");
|
||||
}
|
||||
|
||||
int
|
||||
PND_gl_getswapinterval(_THIS)
|
||||
{
|
||||
return ((SDL_VideoData *) _this->driverdata)->swapinterval;
|
||||
}
|
||||
|
||||
int
|
||||
PND_gl_swapwindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
|
||||
SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
|
||||
|
||||
if (phdata->egl_initialized != SDL_TRUE) {
|
||||
return SDL_SetError("PND: GLES initialization failed, no OpenGL ES support");
|
||||
}
|
||||
|
||||
/* Many applications do not uses glFinish(), so we call it for them */
|
||||
glFinish();
|
||||
|
||||
/* Wait until OpenGL ES rendering is completed */
|
||||
eglWaitGL();
|
||||
|
||||
eglSwapBuffers(phdata->egl_display, wdata->gles_surface);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
PND_gl_deletecontext(_THIS, SDL_GLContext context)
|
||||
{
|
||||
SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
|
||||
EGLBoolean status;
|
||||
|
||||
if (phdata->egl_initialized != SDL_TRUE) {
|
||||
SDL_SetError("PND: GLES initialization failed, no OpenGL ES support");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if OpenGL ES connection has been initialized */
|
||||
if (phdata->egl_display != EGL_NO_DISPLAY) {
|
||||
if (context != EGL_NO_CONTEXT) {
|
||||
status = eglDestroyContext(phdata->egl_display, context);
|
||||
if (status != EGL_TRUE) {
|
||||
/* Error during OpenGL ES context destroying */
|
||||
SDL_SetError("PND: OpenGL ES context destroy error");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WIZ_GLES_LITE
|
||||
if( hNativeWnd != 0 )
|
||||
{
|
||||
SDL_free(hNativeWnd);
|
||||
hNativeWnd = 0;
|
||||
printf( "SDL: Wiz framebuffer released\n" );
|
||||
}
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_PANDORA */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef __SDL_PANDORA_H__
|
||||
#define __SDL_PANDORA_H__
|
||||
|
||||
#include <GLES/egl.h>
|
||||
|
||||
#include "../../SDL_internal.h"
|
||||
#include "../SDL_sysvideo.h"
|
||||
|
||||
typedef struct SDL_VideoData
|
||||
{
|
||||
SDL_bool egl_initialized; /* OpenGL ES device initialization status */
|
||||
EGLDisplay egl_display; /* OpenGL ES display connection */
|
||||
uint32_t egl_refcount; /* OpenGL ES reference count */
|
||||
uint32_t swapinterval; /* OpenGL ES default swap interval */
|
||||
|
||||
} SDL_VideoData;
|
||||
|
||||
|
||||
typedef struct SDL_DisplayData
|
||||
{
|
||||
|
||||
} SDL_DisplayData;
|
||||
|
||||
|
||||
typedef struct SDL_WindowData
|
||||
{
|
||||
SDL_bool uses_gles; /* if true window must support OpenGL ES */
|
||||
|
||||
EGLConfig gles_configs[32];
|
||||
EGLint gles_config; /* OpenGL ES configuration index */
|
||||
EGLContext gles_context; /* OpenGL ES context */
|
||||
EGLint gles_attributes[256]; /* OpenGL ES attributes for context */
|
||||
EGLSurface gles_surface; /* OpenGL ES target rendering surface */
|
||||
|
||||
} SDL_WindowData;
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* SDL_VideoDevice functions declaration */
|
||||
/****************************************************************************/
|
||||
|
||||
/* Display and window functions */
|
||||
int PND_videoinit(_THIS);
|
||||
void PND_videoquit(_THIS);
|
||||
void PND_getdisplaymodes(_THIS, SDL_VideoDisplay * display);
|
||||
int PND_setdisplaymode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
|
||||
int PND_createwindow(_THIS, SDL_Window * window);
|
||||
int PND_createwindowfrom(_THIS, SDL_Window * window, const void *data);
|
||||
void PND_setwindowtitle(_THIS, SDL_Window * window);
|
||||
void PND_setwindowicon(_THIS, SDL_Window * window, SDL_Surface * icon);
|
||||
void PND_setwindowposition(_THIS, SDL_Window * window);
|
||||
void PND_setwindowsize(_THIS, SDL_Window * window);
|
||||
void PND_showwindow(_THIS, SDL_Window * window);
|
||||
void PND_hidewindow(_THIS, SDL_Window * window);
|
||||
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_destroywindow(_THIS, SDL_Window * window);
|
||||
|
||||
/* Window manager function */
|
||||
SDL_bool PND_getwindowwminfo(_THIS, SDL_Window * window,
|
||||
struct SDL_SysWMinfo *info);
|
||||
|
||||
/* OpenGL/OpenGL ES functions */
|
||||
int PND_gl_loadlibrary(_THIS, const char *path);
|
||||
void *PND_gl_getprocaddres(_THIS, const char *proc);
|
||||
void PND_gl_unloadlibrary(_THIS);
|
||||
SDL_GLContext PND_gl_createcontext(_THIS, SDL_Window * window);
|
||||
int PND_gl_makecurrent(_THIS, SDL_Window * window, SDL_GLContext context);
|
||||
int PND_gl_setswapinterval(_THIS, int interval);
|
||||
int PND_gl_getswapinterval(_THIS);
|
||||
int PND_gl_swapwindow(_THIS, SDL_Window * window);
|
||||
void PND_gl_deletecontext(_THIS, SDL_GLContext context);
|
||||
|
||||
|
||||
#endif /* __SDL_PANDORA_H__ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
extern void PND_PumpEvents(_THIS);
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
@@ -31,7 +31,11 @@
|
||||
#include <dmaKit.h>
|
||||
|
||||
#include <gsToolkit.h>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeclaration-after-statement"
|
||||
#include <gsInline.h>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
#endif /* SDL_ps2video_h_ */
|
||||
|
||||
|
||||
@@ -62,16 +62,17 @@ static struct {
|
||||
{ PSP_HPRM_HOLD, SDLK_F15 }
|
||||
};
|
||||
|
||||
int EventUpdate(void *data)
|
||||
int
|
||||
EventUpdate(void *data)
|
||||
{
|
||||
while (running) {
|
||||
SDL_SemWait(event_sem);
|
||||
sceHprmPeekCurrentKey(&hprm);
|
||||
SDL_SemPost(event_sem);
|
||||
/* Delay 1/60th of a second */
|
||||
sceKernelDelayThread(1000000 / 60);
|
||||
}
|
||||
return 0;
|
||||
SDL_SemWait(event_sem);
|
||||
sceHprmPeekCurrentKey((u32 *) &hprm);
|
||||
SDL_SemPost(event_sem);
|
||||
/* Delay 1/60th of a second */
|
||||
sceKernelDelayThread(1000000 / 60);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PSP_PumpEvents(_THIS)
|
||||
@@ -80,7 +81,6 @@ void PSP_PumpEvents(_THIS)
|
||||
enum PspHprmKeys keys;
|
||||
enum PspHprmKeys changed;
|
||||
static enum PspHprmKeys old_keys = 0;
|
||||
SDL_Keysym sym;
|
||||
|
||||
SDL_SemWait(event_sem);
|
||||
keys = hprm;
|
||||
@@ -92,14 +92,6 @@ void PSP_PumpEvents(_THIS)
|
||||
if(changed) {
|
||||
for(i=0; i<sizeof(keymap_psp)/sizeof(keymap_psp[0]); i++) {
|
||||
if(changed & keymap_psp[i].id) {
|
||||
sym.scancode = keymap_psp[i].id;
|
||||
sym.sym = keymap_psp[i].sym;
|
||||
|
||||
/* out of date
|
||||
SDL_PrivateKeyboard((keys & keymap_psp[i].id) ?
|
||||
SDL_PRESSED : SDL_RELEASED,
|
||||
&sym);
|
||||
*/
|
||||
SDL_SendKeyboardKey((keys & keymap_psp[i].id) ?
|
||||
SDL_PRESSED : SDL_RELEASED, SDL_GetScancodeFromKey(keymap_psp[i].sym));
|
||||
}
|
||||
|
||||
@@ -1,285 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 2017 BlackBerry Limited
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "../../SDL_internal.h"
|
||||
#include "sdl_qnx.h"
|
||||
|
||||
static EGLDisplay egl_disp;
|
||||
|
||||
/**
|
||||
* Detertmines the pixel format to use based on the current display and EGL
|
||||
* configuration.
|
||||
* @param egl_conf EGL configuration to use
|
||||
* @return A SCREEN_FORMAT* constant for the pixel format to use
|
||||
*/
|
||||
static int
|
||||
chooseFormat(EGLConfig egl_conf)
|
||||
{
|
||||
EGLint buffer_bit_depth;
|
||||
EGLint alpha_bit_depth;
|
||||
|
||||
eglGetConfigAttrib(egl_disp, egl_conf, EGL_BUFFER_SIZE, &buffer_bit_depth);
|
||||
eglGetConfigAttrib(egl_disp, egl_conf, EGL_ALPHA_SIZE, &alpha_bit_depth);
|
||||
|
||||
switch (buffer_bit_depth) {
|
||||
case 32:
|
||||
return SCREEN_FORMAT_RGBX8888;
|
||||
case 24:
|
||||
return SCREEN_FORMAT_RGB888;
|
||||
case 16:
|
||||
switch (alpha_bit_depth) {
|
||||
case 4:
|
||||
return SCREEN_FORMAT_RGBX4444;
|
||||
case 1:
|
||||
return SCREEN_FORMAT_RGBA5551;
|
||||
default:
|
||||
return SCREEN_FORMAT_RGB565;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumerates the supported EGL configurations and chooses a suitable one.
|
||||
* @param[out] pconf The chosen configuration
|
||||
* @param[out] pformat The chosen pixel format
|
||||
* @return 0 if successful, -1 on error
|
||||
*/
|
||||
int
|
||||
glGetConfig(EGLConfig *pconf, int *pformat)
|
||||
{
|
||||
EGLConfig egl_conf = (EGLConfig)0;
|
||||
EGLConfig *egl_configs;
|
||||
EGLint egl_num_configs;
|
||||
EGLint val;
|
||||
EGLBoolean rc;
|
||||
EGLint i;
|
||||
|
||||
// Determine the numbfer of configurations.
|
||||
rc = eglGetConfigs(egl_disp, NULL, 0, &egl_num_configs);
|
||||
if (rc != EGL_TRUE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (egl_num_configs == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Allocate enough memory for all configurations.
|
||||
egl_configs = SDL_malloc(egl_num_configs * sizeof(*egl_configs));
|
||||
if (egl_configs == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get the list of configurations.
|
||||
rc = eglGetConfigs(egl_disp, egl_configs, egl_num_configs,
|
||||
&egl_num_configs);
|
||||
if (rc != EGL_TRUE) {
|
||||
SDL_free(egl_configs);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Find a good configuration.
|
||||
for (i = 0; i < egl_num_configs; i++) {
|
||||
eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_SURFACE_TYPE, &val);
|
||||
if (!(val & EGL_WINDOW_BIT)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_RENDERABLE_TYPE, &val);
|
||||
if (!(val & EGL_OPENGL_ES2_BIT)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_DEPTH_SIZE, &val);
|
||||
if (val == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
egl_conf = egl_configs[i];
|
||||
break;
|
||||
}
|
||||
|
||||
SDL_free(egl_configs);
|
||||
*pconf = egl_conf;
|
||||
*pformat = chooseFormat(egl_conf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the EGL library.
|
||||
* @param _THIS
|
||||
* @param name unused
|
||||
* @return 0 if successful, -1 on error
|
||||
*/
|
||||
int
|
||||
glLoadLibrary(_THIS, const char *name)
|
||||
{
|
||||
EGLNativeDisplayType disp_id = EGL_DEFAULT_DISPLAY;
|
||||
|
||||
egl_disp = eglGetDisplay(disp_id);
|
||||
if (egl_disp == EGL_NO_DISPLAY) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (eglInitialize(egl_disp, NULL, NULL) == EGL_FALSE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the address of an EGL extension function.
|
||||
* @param proc Function name
|
||||
* @return Function address
|
||||
*/
|
||||
void *
|
||||
glGetProcAddress(_THIS, const char *proc)
|
||||
{
|
||||
return eglGetProcAddress(proc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates the given window with the necessary EGL structures for drawing and
|
||||
* displaying content.
|
||||
* @param _THIS
|
||||
* @param window The SDL window to create the context for
|
||||
* @return A pointer to the created context, if successful, NULL on error
|
||||
*/
|
||||
SDL_GLContext
|
||||
glCreateContext(_THIS, SDL_Window *window)
|
||||
{
|
||||
window_impl_t *impl = (window_impl_t *)window->driverdata;
|
||||
EGLContext context;
|
||||
EGLSurface surface;
|
||||
|
||||
struct {
|
||||
EGLint client_version[2];
|
||||
EGLint none;
|
||||
} egl_ctx_attr = {
|
||||
.client_version = { EGL_CONTEXT_CLIENT_VERSION, 2 },
|
||||
.none = EGL_NONE
|
||||
};
|
||||
|
||||
struct {
|
||||
EGLint render_buffer[2];
|
||||
EGLint none;
|
||||
} egl_surf_attr = {
|
||||
.render_buffer = { EGL_RENDER_BUFFER, EGL_BACK_BUFFER },
|
||||
.none = EGL_NONE
|
||||
};
|
||||
|
||||
context = eglCreateContext(egl_disp, impl->conf, EGL_NO_CONTEXT,
|
||||
(EGLint *)&egl_ctx_attr);
|
||||
if (context == EGL_NO_CONTEXT) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
surface = eglCreateWindowSurface(egl_disp, impl->conf, impl->window,
|
||||
(EGLint *)&egl_surf_attr);
|
||||
if (surface == EGL_NO_SURFACE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
eglMakeCurrent(egl_disp, surface, surface, context);
|
||||
|
||||
impl->surface = surface;
|
||||
return context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new value for the number of frames to display before swapping buffers.
|
||||
* @param _THIS
|
||||
* @param interval New interval value
|
||||
* @return 0 if successful, -1 on error
|
||||
*/
|
||||
int
|
||||
glSetSwapInterval(_THIS, int interval)
|
||||
{
|
||||
if (eglSwapInterval(egl_disp, interval) != EGL_TRUE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Swaps the EGL buffers associated with the given window
|
||||
* @param _THIS
|
||||
* @param window Window to swap buffers for
|
||||
* @return 0 if successful, -1 on error
|
||||
*/
|
||||
int
|
||||
glSwapWindow(_THIS, SDL_Window *window)
|
||||
{
|
||||
/* !!! FIXME: should we migrate this all over to use SDL_egl.c? */
|
||||
window_impl_t *impl = (window_impl_t *)window->driverdata;
|
||||
return eglSwapBuffers(egl_disp, impl->surface) == EGL_TRUE ? 0 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the given context the current one for drawing operations.
|
||||
* @param _THIS
|
||||
* @param window SDL window associated with the context (maybe NULL)
|
||||
* @param context The context to activate
|
||||
* @return 0 if successful, -1 on error
|
||||
*/
|
||||
int
|
||||
glMakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context)
|
||||
{
|
||||
window_impl_t *impl;
|
||||
EGLSurface surface = NULL;
|
||||
|
||||
if (window) {
|
||||
impl = (window_impl_t *)window->driverdata;
|
||||
surface = impl->surface;
|
||||
}
|
||||
|
||||
if (eglMakeCurrent(egl_disp, surface, surface, context) != EGL_TRUE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a context.
|
||||
* @param _THIS
|
||||
* @param context The context to destroy
|
||||
*/
|
||||
void
|
||||
glDeleteContext(_THIS, SDL_GLContext context)
|
||||
{
|
||||
eglDestroyContext(egl_disp, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminates access to the EGL library.
|
||||
* @param _THIS
|
||||
*/
|
||||
void
|
||||
glUnloadLibrary(_THIS)
|
||||
{
|
||||
eglTerminate(egl_disp);
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 2017 BlackBerry Limited
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "../../SDL_internal.h"
|
||||
#include "../../events/SDL_keyboard_c.h"
|
||||
#include "SDL_scancode.h"
|
||||
#include "SDL_events.h"
|
||||
#include "sdl_qnx.h"
|
||||
#include <sys/keycodes.h>
|
||||
|
||||
/**
|
||||
* A map thta translates Screen key names to SDL scan codes.
|
||||
* This map is incomplete, but should include most major keys.
|
||||
*/
|
||||
static int key_to_sdl[] = {
|
||||
[KEYCODE_SPACE] = SDL_SCANCODE_SPACE,
|
||||
[KEYCODE_APOSTROPHE] = SDL_SCANCODE_APOSTROPHE,
|
||||
[KEYCODE_COMMA] = SDL_SCANCODE_COMMA,
|
||||
[KEYCODE_MINUS] = SDL_SCANCODE_MINUS,
|
||||
[KEYCODE_PERIOD] = SDL_SCANCODE_PERIOD,
|
||||
[KEYCODE_SLASH] = SDL_SCANCODE_SLASH,
|
||||
[KEYCODE_ZERO] = SDL_SCANCODE_0,
|
||||
[KEYCODE_ONE] = SDL_SCANCODE_1,
|
||||
[KEYCODE_TWO] = SDL_SCANCODE_2,
|
||||
[KEYCODE_THREE] = SDL_SCANCODE_3,
|
||||
[KEYCODE_FOUR] = SDL_SCANCODE_4,
|
||||
[KEYCODE_FIVE] = SDL_SCANCODE_5,
|
||||
[KEYCODE_SIX] = SDL_SCANCODE_6,
|
||||
[KEYCODE_SEVEN] = SDL_SCANCODE_7,
|
||||
[KEYCODE_EIGHT] = SDL_SCANCODE_8,
|
||||
[KEYCODE_NINE] = SDL_SCANCODE_9,
|
||||
[KEYCODE_SEMICOLON] = SDL_SCANCODE_SEMICOLON,
|
||||
[KEYCODE_EQUAL] = SDL_SCANCODE_EQUALS,
|
||||
[KEYCODE_LEFT_BRACKET] = SDL_SCANCODE_LEFTBRACKET,
|
||||
[KEYCODE_BACK_SLASH] = SDL_SCANCODE_BACKSLASH,
|
||||
[KEYCODE_RIGHT_BRACKET] = SDL_SCANCODE_RIGHTBRACKET,
|
||||
[KEYCODE_GRAVE] = SDL_SCANCODE_GRAVE,
|
||||
[KEYCODE_A] = SDL_SCANCODE_A,
|
||||
[KEYCODE_B] = SDL_SCANCODE_B,
|
||||
[KEYCODE_C] = SDL_SCANCODE_C,
|
||||
[KEYCODE_D] = SDL_SCANCODE_D,
|
||||
[KEYCODE_E] = SDL_SCANCODE_E,
|
||||
[KEYCODE_F] = SDL_SCANCODE_F,
|
||||
[KEYCODE_G] = SDL_SCANCODE_G,
|
||||
[KEYCODE_H] = SDL_SCANCODE_H,
|
||||
[KEYCODE_I] = SDL_SCANCODE_I,
|
||||
[KEYCODE_J] = SDL_SCANCODE_J,
|
||||
[KEYCODE_K] = SDL_SCANCODE_K,
|
||||
[KEYCODE_L] = SDL_SCANCODE_L,
|
||||
[KEYCODE_M] = SDL_SCANCODE_M,
|
||||
[KEYCODE_N] = SDL_SCANCODE_N,
|
||||
[KEYCODE_O] = SDL_SCANCODE_O,
|
||||
[KEYCODE_P] = SDL_SCANCODE_P,
|
||||
[KEYCODE_Q] = SDL_SCANCODE_Q,
|
||||
[KEYCODE_R] = SDL_SCANCODE_R,
|
||||
[KEYCODE_S] = SDL_SCANCODE_S,
|
||||
[KEYCODE_T] = SDL_SCANCODE_T,
|
||||
[KEYCODE_U] = SDL_SCANCODE_U,
|
||||
[KEYCODE_V] = SDL_SCANCODE_V,
|
||||
[KEYCODE_W] = SDL_SCANCODE_W,
|
||||
[KEYCODE_X] = SDL_SCANCODE_X,
|
||||
[KEYCODE_Y] = SDL_SCANCODE_Y,
|
||||
[KEYCODE_Z] = SDL_SCANCODE_Z,
|
||||
[KEYCODE_UP] = SDL_SCANCODE_UP,
|
||||
[KEYCODE_DOWN] = SDL_SCANCODE_DOWN,
|
||||
[KEYCODE_LEFT] = SDL_SCANCODE_LEFT,
|
||||
[KEYCODE_PG_UP] = SDL_SCANCODE_PAGEUP,
|
||||
[KEYCODE_PG_DOWN] = SDL_SCANCODE_PAGEDOWN,
|
||||
[KEYCODE_RIGHT] = SDL_SCANCODE_RIGHT,
|
||||
[KEYCODE_RETURN] = SDL_SCANCODE_RETURN,
|
||||
[KEYCODE_TAB] = SDL_SCANCODE_TAB,
|
||||
[KEYCODE_ESCAPE] = SDL_SCANCODE_ESCAPE,
|
||||
};
|
||||
|
||||
/**
|
||||
* Called from the event dispatcher when a keyboard event is encountered.
|
||||
* Translates the event such that it can be handled by SDL.
|
||||
* @param event Screen keyboard event
|
||||
*/
|
||||
void
|
||||
handleKeyboardEvent(screen_event_t event)
|
||||
{
|
||||
int val;
|
||||
SDL_Scancode scancode;
|
||||
|
||||
// Get the key value.
|
||||
if (screen_get_event_property_iv(event, SCREEN_PROPERTY_SYM, &val) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip unrecognized keys.
|
||||
if ((val < 0) || (val >= SDL_TABLESIZE(key_to_sdl))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Translate to an SDL scan code.
|
||||
scancode = key_to_sdl[val];
|
||||
if (scancode == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get event flags (key state).
|
||||
if (screen_get_event_property_iv(event, SCREEN_PROPERTY_FLAGS, &val) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Propagate the event to SDL.
|
||||
// FIXME:
|
||||
// Need to handle more key states (such as key combinations).
|
||||
if (val & KEY_DOWN) {
|
||||
SDL_SendKeyboardKey(SDL_PRESSED, scancode);
|
||||
} else {
|
||||
SDL_SendKeyboardKey(SDL_RELEASED, scancode);
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 2017 BlackBerry Limited
|
||||
|
||||
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_QNX_H__
|
||||
#define __SDL_QNX_H__
|
||||
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include <screen/screen.h>
|
||||
#include <EGL/egl.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
screen_window_t window;
|
||||
EGLSurface surface;
|
||||
EGLConfig conf;
|
||||
} window_impl_t;
|
||||
|
||||
extern void handleKeyboardEvent(screen_event_t event);
|
||||
|
||||
extern int glGetConfig(EGLConfig *pconf, int *pformat);
|
||||
extern int glLoadLibrary(_THIS, const char *name);
|
||||
void *glGetProcAddress(_THIS, const char *proc);
|
||||
extern SDL_GLContext glCreateContext(_THIS, SDL_Window *window);
|
||||
extern int glSetSwapInterval(_THIS, int interval);
|
||||
extern int glSwapWindow(_THIS, SDL_Window *window);
|
||||
extern int glMakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
|
||||
extern void glDeleteContext(_THIS, SDL_GLContext context);
|
||||
extern void glUnloadLibrary(_THIS);
|
||||
|
||||
#endif
|
||||
@@ -1,358 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 2017 BlackBerry Limited
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "sdl_qnx.h"
|
||||
|
||||
static screen_context_t context;
|
||||
static screen_event_t event;
|
||||
|
||||
/**
|
||||
* Initializes the QNX video plugin.
|
||||
* Creates the Screen context and event handles used for all window operations
|
||||
* by the plugin.
|
||||
* @param _THIS
|
||||
* @return 0 if successful, -1 on error
|
||||
*/
|
||||
static int
|
||||
videoInit(_THIS)
|
||||
{
|
||||
SDL_VideoDisplay display;
|
||||
|
||||
if (screen_create_context(&context, 0) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (screen_create_event(&event) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_zero(display);
|
||||
|
||||
if (SDL_AddVideoDisplay(&display, SDL_FALSE) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
_this->num_displays = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
videoQuit(_THIS)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new native Screen window and associates it with the given SDL
|
||||
* window.
|
||||
* @param _THIS
|
||||
* @param window SDL window to initialize
|
||||
* @return 0 if successful, -1 on error
|
||||
*/
|
||||
static int
|
||||
createWindow(_THIS, SDL_Window *window)
|
||||
{
|
||||
window_impl_t *impl;
|
||||
int size[2];
|
||||
int numbufs;
|
||||
int format;
|
||||
int usage;
|
||||
|
||||
impl = SDL_calloc(1, sizeof(*impl));
|
||||
if (impl == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create a native window.
|
||||
if (screen_create_window(&impl->window, context) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// Set the native window's size to match the SDL window.
|
||||
size[0] = window->w;
|
||||
size[1] = window->h;
|
||||
|
||||
if (screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_SIZE,
|
||||
size) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_SOURCE_SIZE,
|
||||
size) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// Create window buffer(s).
|
||||
if (window->flags & SDL_WINDOW_OPENGL) {
|
||||
if (glGetConfig(&impl->conf, &format) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
numbufs = 2;
|
||||
|
||||
usage = SCREEN_USAGE_OPENGL_ES2;
|
||||
if (screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_USAGE,
|
||||
&usage) < 0) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
format = SCREEN_FORMAT_RGBX8888;
|
||||
numbufs = 1;
|
||||
}
|
||||
|
||||
// Set pixel format.
|
||||
if (screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_FORMAT,
|
||||
&format) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// Create buffer(s).
|
||||
if (screen_create_window_buffers(impl->window, numbufs) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
window->driverdata = impl;
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if (impl->window) {
|
||||
screen_destroy_window(impl->window);
|
||||
}
|
||||
|
||||
SDL_free(impl);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a pointer to the Screen buffer associated with the given window. Note
|
||||
* that the buffer is actually created in createWindow().
|
||||
* @param _THIS
|
||||
* @param window SDL window to get the buffer for
|
||||
* @param[out] pixles Holds a pointer to the window's buffer
|
||||
* @param[out] format Holds the pixel format for the buffer
|
||||
* @param[out] pitch Holds the number of bytes per line
|
||||
* @return 0 if successful, -1 on error
|
||||
*/
|
||||
static int
|
||||
createWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format,
|
||||
void ** pixels, int *pitch)
|
||||
{
|
||||
window_impl_t *impl = (window_impl_t *)window->driverdata;
|
||||
screen_buffer_t buffer;
|
||||
|
||||
// Get a pointer to the buffer's memory.
|
||||
if (screen_get_window_property_pv(impl->window, SCREEN_PROPERTY_BUFFERS,
|
||||
(void **)&buffer) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (screen_get_buffer_property_pv(buffer, SCREEN_PROPERTY_POINTER,
|
||||
pixels) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set format and pitch.
|
||||
if (screen_get_buffer_property_iv(buffer, SCREEN_PROPERTY_STRIDE,
|
||||
pitch) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*format = SDL_PIXELFORMAT_RGB888;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Informs the window manager that the window needs to be updated.
|
||||
* @param _THIS
|
||||
* @param window The window to update
|
||||
* @param rects An array of reectangular areas to update
|
||||
* @param numrects Rect array length
|
||||
* @return 0 if successful, -1 on error
|
||||
*/
|
||||
static int
|
||||
updateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects,
|
||||
int numrects)
|
||||
{
|
||||
window_impl_t *impl = (window_impl_t *)window->driverdata;
|
||||
screen_buffer_t buffer;
|
||||
|
||||
if (screen_get_window_property_pv(impl->window, SCREEN_PROPERTY_BUFFERS,
|
||||
(void **)&buffer) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
screen_post_window(impl->window, buffer, numrects, (int *)rects, 0);
|
||||
screen_flush_context(context, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the main event loop.
|
||||
* @param _THIS
|
||||
*/
|
||||
static void
|
||||
pumpEvents(_THIS)
|
||||
{
|
||||
int type;
|
||||
|
||||
for (;;) {
|
||||
if (screen_get_event(context, event, 0) < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &type)
|
||||
< 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (type == SCREEN_EVENT_NONE) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case SCREEN_EVENT_KEYBOARD:
|
||||
handleKeyboardEvent(event);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the size of the native window using the geometry of the SDL window.
|
||||
* @param _THIS
|
||||
* @param window SDL window to update
|
||||
*/
|
||||
static void
|
||||
setWindowSize(_THIS, SDL_Window *window)
|
||||
{
|
||||
window_impl_t *impl = (window_impl_t *)window->driverdata;
|
||||
int size[2];
|
||||
|
||||
size[0] = window->w;
|
||||
size[1] = window->h;
|
||||
|
||||
screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_SIZE, size);
|
||||
screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_SOURCE_SIZE,
|
||||
size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the native window associated with the given SDL window visible.
|
||||
* @param _THIS
|
||||
* @param window SDL window to update
|
||||
*/
|
||||
static void
|
||||
showWindow(_THIS, SDL_Window *window)
|
||||
{
|
||||
window_impl_t *impl = (window_impl_t *)window->driverdata;
|
||||
const int visible = 1;
|
||||
|
||||
screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_VISIBLE,
|
||||
&visible);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the native window associated with the given SDL window invisible.
|
||||
* @param _THIS
|
||||
* @param window SDL window to update
|
||||
*/
|
||||
static void
|
||||
hideWindow(_THIS, SDL_Window *window)
|
||||
{
|
||||
window_impl_t *impl = (window_impl_t *)window->driverdata;
|
||||
const int visible = 0;
|
||||
|
||||
screen_set_window_property_iv(impl->window, SCREEN_PROPERTY_VISIBLE,
|
||||
&visible);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the native window associated with the given SDL window.
|
||||
* @param _THIS
|
||||
* @param window SDL window that is being destroyed
|
||||
*/
|
||||
static void
|
||||
destroyWindow(_THIS, SDL_Window *window)
|
||||
{
|
||||
window_impl_t *impl = (window_impl_t *)window->driverdata;
|
||||
|
||||
if (impl) {
|
||||
screen_destroy_window(impl->window);
|
||||
window->driverdata = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees the plugin object created by createDevice().
|
||||
* @param device Plugin object to free
|
||||
*/
|
||||
static void
|
||||
deleteDevice(SDL_VideoDevice *device)
|
||||
{
|
||||
SDL_free(device);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the QNX video plugin used by SDL.
|
||||
* @param devindex Unused
|
||||
* @return Initialized device if successful, NULL otherwise
|
||||
*/
|
||||
static SDL_VideoDevice *
|
||||
createDevice(int devindex)
|
||||
{
|
||||
SDL_VideoDevice *device;
|
||||
|
||||
device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice));
|
||||
if (device == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
device->driverdata = NULL;
|
||||
device->VideoInit = videoInit;
|
||||
device->VideoQuit = videoQuit;
|
||||
device->CreateSDLWindow = createWindow;
|
||||
device->CreateWindowFramebuffer = createWindowFramebuffer;
|
||||
device->UpdateWindowFramebuffer = updateWindowFramebuffer;
|
||||
device->SetWindowSize = setWindowSize;
|
||||
device->ShowWindow = showWindow;
|
||||
device->HideWindow = hideWindow;
|
||||
device->PumpEvents = pumpEvents;
|
||||
device->DestroyWindow = destroyWindow;
|
||||
|
||||
device->GL_LoadLibrary = glLoadLibrary;
|
||||
device->GL_GetProcAddress = glGetProcAddress;
|
||||
device->GL_CreateContext = glCreateContext;
|
||||
device->GL_SetSwapInterval = glSetSwapInterval;
|
||||
device->GL_SwapWindow = glSwapWindow;
|
||||
device->GL_MakeCurrent = glMakeCurrent;
|
||||
device->GL_DeleteContext = glDeleteContext;
|
||||
device->GL_UnloadLibrary = glUnloadLibrary;
|
||||
|
||||
device->free = deleteDevice;
|
||||
return device;
|
||||
}
|
||||
|
||||
VideoBootStrap QNX_bootstrap = {
|
||||
"qnx", "QNX Screen",
|
||||
createDevice
|
||||
};
|
||||
@@ -52,7 +52,7 @@ RPI_GLES_SwapWindow(_THIS, SDL_Window * window) {
|
||||
}
|
||||
|
||||
/* Wait immediately for vsync (as if we only had two buffers), for low input-lag scenarios.
|
||||
* Run your SDL2 program with "SDL_RPI_DOUBLE_BUFFER=1 <program_name>" to enable this. */
|
||||
* Run your SDL program with "SDL_RPI_DOUBLE_BUFFER=1 <program_name>" to enable this. */
|
||||
if (wdata->double_buffer) {
|
||||
SDL_LockMutex(wdata->vsync_cond_mutex);
|
||||
SDL_CondWait(wdata->vsync_cond, wdata->vsync_cond_mutex);
|
||||
|
||||
@@ -40,9 +40,11 @@ SDL_RISCOS_translate_keycode(int keycode)
|
||||
if (keycode < SDL_arraysize(riscos_scancode_table)) {
|
||||
scancode = riscos_scancode_table[keycode];
|
||||
|
||||
#ifdef DEBUG_SCANCODES
|
||||
if (scancode == SDL_SCANCODE_UNKNOWN) {
|
||||
SDL_Log("The key you just pressed is not recognized by SDL: %d", keycode);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return scancode;
|
||||
|
||||
@@ -33,6 +33,14 @@
|
||||
|
||||
#include "../../events/SDL_events_c.h"
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
#include <AvailabilityVersions.h>
|
||||
|
||||
# ifndef __IPHONE_13_0
|
||||
# define __IPHONE_13_0 130000
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef main
|
||||
#undef main
|
||||
#endif
|
||||
@@ -116,6 +124,53 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
@interface SDLLaunchStoryboardViewController : UIViewController
|
||||
@property (nonatomic, strong) UIViewController *storyboardViewController;
|
||||
- (instancetype)initWithStoryboardViewController:(UIViewController *)storyboardViewController;
|
||||
@end
|
||||
|
||||
@implementation SDLLaunchStoryboardViewController
|
||||
|
||||
- (instancetype)initWithStoryboardViewController:(UIViewController *)storyboardViewController {
|
||||
self = [super init];
|
||||
self.storyboardViewController = storyboardViewController;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
[self addChildViewController:self.storyboardViewController];
|
||||
[self.view addSubview:self.storyboardViewController.view];
|
||||
self.storyboardViewController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
self.storyboardViewController.view.frame = self.view.bounds;
|
||||
[self.storyboardViewController didMoveToParentViewController:self];
|
||||
|
||||
UIApplication.sharedApplication.statusBarHidden = self.prefersStatusBarHidden;
|
||||
UIApplication.sharedApplication.statusBarStyle = self.preferredStatusBarStyle;
|
||||
}
|
||||
|
||||
- (BOOL)prefersStatusBarHidden {
|
||||
return [[NSBundle.mainBundle objectForInfoDictionaryKey:@"UIStatusBarHidden"] boolValue];
|
||||
}
|
||||
|
||||
- (UIStatusBarStyle)preferredStatusBarStyle {
|
||||
NSString *statusBarStyle = [NSBundle.mainBundle objectForInfoDictionaryKey:@"UIStatusBarStyle"];
|
||||
if ([statusBarStyle isEqualToString:@"UIStatusBarStyleLightContent"]) {
|
||||
return UIStatusBarStyleLightContent;
|
||||
}
|
||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
|
||||
if (@available(iOS 13.0, *)) {
|
||||
if ([statusBarStyle isEqualToString:@"UIStatusBarStyleDarkContent"]) {
|
||||
return UIStatusBarStyleDarkContent;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return UIStatusBarStyleDefault;
|
||||
}
|
||||
|
||||
@end
|
||||
#endif /* !TARGET_OS_TV */
|
||||
|
||||
@interface SDLLaunchScreenController ()
|
||||
@@ -141,10 +196,9 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
||||
|
||||
NSString *screenname = nibNameOrNil;
|
||||
NSBundle *bundle = nibBundleOrNil;
|
||||
BOOL atleastiOS8 = UIKit_IsSystemVersionAtLeast(8.0);
|
||||
|
||||
/* Launch screens were added in iOS 8. Otherwise we use launch images. */
|
||||
if (screenname && atleastiOS8) {
|
||||
/* A launch screen may not exist. Fall back to launch images in that case. */
|
||||
if (screenname) {
|
||||
@try {
|
||||
self.view = [bundle loadNibNamed:screenname owner:self options:nil][0];
|
||||
}
|
||||
@@ -241,9 +295,9 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
||||
UIImageOrientation imageorient = UIImageOrientationUp;
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
/* Bugs observed / workaround tested in iOS 8.3, 7.1, and 6.1. */
|
||||
/* Bugs observed / workaround tested in iOS 8.3. */
|
||||
if (UIInterfaceOrientationIsLandscape(curorient)) {
|
||||
if (atleastiOS8 && image.size.width < image.size.height) {
|
||||
if (image.size.width < image.size.height) {
|
||||
/* On iOS 8, portrait launch images displayed in forced-
|
||||
* landscape mode (e.g. a standard Default.png on an iPhone
|
||||
* when Info.plist only supports landscape orientations) need
|
||||
@@ -253,15 +307,6 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
||||
} else if (curorient == UIInterfaceOrientationLandscapeRight) {
|
||||
imageorient = UIImageOrientationLeft;
|
||||
}
|
||||
} else if (!atleastiOS8 && image.size.width > image.size.height) {
|
||||
/* On iOS 7 and below, landscape launch images displayed in
|
||||
* landscape mode (e.g. landscape iPad launch images) need
|
||||
* to be rotated to display in the expected orientation. */
|
||||
if (curorient == UIInterfaceOrientationLandscapeLeft) {
|
||||
imageorient = UIImageOrientationLeft;
|
||||
} else if (curorient == UIInterfaceOrientationLandscapeRight) {
|
||||
imageorient = UIImageOrientationRight;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -378,13 +423,14 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
||||
#if !TARGET_OS_TV
|
||||
screenname = [bundle objectForInfoDictionaryKey:@"UILaunchStoryboardName"];
|
||||
|
||||
if (screenname && UIKit_IsSystemVersionAtLeast(8.0)) {
|
||||
if (screenname) {
|
||||
@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];
|
||||
__auto_type storyboardVc = [storyboard instantiateInitialViewController];
|
||||
vc = [[SDLLaunchStoryboardViewController alloc] initWithStoryboardViewController:storyboardVc];
|
||||
}
|
||||
@catch (NSException *exception) {
|
||||
/* Do nothing (there's more code to execute below). */
|
||||
@@ -444,43 +490,6 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
||||
/* Do nothing. */
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
- (void)application:(UIApplication *)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation
|
||||
{
|
||||
SDL_OnApplicationDidChangeStatusBarOrientation();
|
||||
}
|
||||
#endif
|
||||
|
||||
- (void)applicationWillTerminate:(UIApplication *)application
|
||||
{
|
||||
SDL_OnApplicationWillTerminate();
|
||||
}
|
||||
|
||||
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
|
||||
{
|
||||
SDL_OnApplicationDidReceiveMemoryWarning();
|
||||
}
|
||||
|
||||
- (void)applicationWillResignActive:(UIApplication*)application
|
||||
{
|
||||
SDL_OnApplicationWillResignActive();
|
||||
}
|
||||
|
||||
- (void)applicationDidEnterBackground:(UIApplication*)application
|
||||
{
|
||||
SDL_OnApplicationDidEnterBackground();
|
||||
}
|
||||
|
||||
- (void)applicationWillEnterForeground:(UIApplication*)application
|
||||
{
|
||||
SDL_OnApplicationWillEnterForeground();
|
||||
}
|
||||
|
||||
- (void)applicationDidBecomeActive:(UIApplication*)application
|
||||
{
|
||||
SDL_OnApplicationDidBecomeActive();
|
||||
}
|
||||
|
||||
- (void)sendDropFileForURL:(NSURL *)url
|
||||
{
|
||||
NSURL *fileURL = url.filePathURL;
|
||||
|
||||
@@ -41,10 +41,84 @@
|
||||
|
||||
static BOOL UIKit_EventPumpEnabled = YES;
|
||||
|
||||
|
||||
@interface SDL_LifecycleObserver : NSObject
|
||||
@property (nonatomic, assign) BOOL isObservingNotifications;
|
||||
@end
|
||||
|
||||
@implementation SDL_LifecycleObserver
|
||||
|
||||
- (void)eventPumpChanged
|
||||
{
|
||||
NSNotificationCenter *notificationCenter = NSNotificationCenter.defaultCenter;
|
||||
if (UIKit_EventPumpEnabled && !self.isObservingNotifications) {
|
||||
self.isObservingNotifications = YES;
|
||||
[notificationCenter addObserver:self selector:@selector(applicationDidBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil];
|
||||
[notificationCenter addObserver:self selector:@selector(applicationWillResignActive) name:UIApplicationWillResignActiveNotification object:nil];
|
||||
[notificationCenter addObserver:self selector:@selector(applicationDidEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil];
|
||||
[notificationCenter addObserver:self selector:@selector(applicationWillEnterForeground) name:UIApplicationWillEnterForegroundNotification object:nil];
|
||||
[notificationCenter addObserver:self selector:@selector(applicationWillTerminate) name:UIApplicationWillTerminateNotification object:nil];
|
||||
[notificationCenter addObserver:self selector:@selector(applicationDidReceiveMemoryWarning) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
|
||||
#if !TARGET_OS_TV
|
||||
[notificationCenter addObserver:self selector:@selector(applicationDidChangeStatusBarOrientation) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
|
||||
#endif
|
||||
} else if (!UIKit_EventPumpEnabled && self.isObservingNotifications) {
|
||||
self.isObservingNotifications = NO;
|
||||
[notificationCenter removeObserver:self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)applicationDidBecomeActive
|
||||
{
|
||||
SDL_OnApplicationDidBecomeActive();
|
||||
}
|
||||
|
||||
- (void)applicationWillResignActive
|
||||
{
|
||||
SDL_OnApplicationWillResignActive();
|
||||
}
|
||||
|
||||
- (void)applicationDidEnterBackground
|
||||
{
|
||||
SDL_OnApplicationDidEnterBackground();
|
||||
}
|
||||
|
||||
- (void)applicationWillEnterForeground
|
||||
{
|
||||
SDL_OnApplicationWillEnterForeground();
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate
|
||||
{
|
||||
SDL_OnApplicationWillTerminate();
|
||||
}
|
||||
|
||||
- (void)applicationDidReceiveMemoryWarning
|
||||
{
|
||||
SDL_OnApplicationDidReceiveMemoryWarning();
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
- (void)applicationDidChangeStatusBarOrientation
|
||||
{
|
||||
SDL_OnApplicationDidChangeStatusBarOrientation();
|
||||
}
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
|
||||
void
|
||||
SDL_iPhoneSetEventPump(SDL_bool enabled)
|
||||
{
|
||||
UIKit_EventPumpEnabled = enabled;
|
||||
|
||||
static SDL_LifecycleObserver *lifecycleObserver;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
lifecycleObserver = [SDL_LifecycleObserver new];
|
||||
});
|
||||
[lifecycleObserver eventPumpChanged];
|
||||
}
|
||||
|
||||
void
|
||||
@@ -241,6 +315,11 @@ static void OnGCMouseConnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14
|
||||
}
|
||||
};
|
||||
|
||||
mouse.mouseInput.scroll.valueChangedHandler = ^(GCControllerDirectionPad *dpad, float xValue, float yValue)
|
||||
{
|
||||
SDL_SendMouseWheel(SDL_GetMouseFocus(), 0, xValue, yValue, SDL_MOUSEWHEEL_NORMAL);
|
||||
};
|
||||
|
||||
dispatch_queue_t queue = dispatch_queue_create( "org.libsdl.input.mouse", DISPATCH_QUEUE_SERIAL );
|
||||
dispatch_set_target_queue( queue, dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 ) );
|
||||
mouse.handlerQueue = queue;
|
||||
|
||||
@@ -124,86 +124,16 @@ UIKit_ShowMessageBoxAlertController(const SDL_MessageBoxData *messageboxdata, in
|
||||
return YES;
|
||||
}
|
||||
|
||||
/* UIAlertView is deprecated in iOS 8+ in favor of UIAlertController. */
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000
|
||||
@interface SDLAlertViewDelegate : NSObject <UIAlertViewDelegate>
|
||||
|
||||
@property (nonatomic, assign) int *clickedIndex;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SDLAlertViewDelegate
|
||||
|
||||
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
|
||||
{
|
||||
if (_clickedIndex != NULL) {
|
||||
*_clickedIndex = (int) buttonIndex;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
#endif /* __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 */
|
||||
|
||||
static BOOL
|
||||
UIKit_ShowMessageBoxAlertView(const SDL_MessageBoxData *messageboxdata, int *buttonid)
|
||||
{
|
||||
/* UIAlertView is deprecated in iOS 8+ in favor of UIAlertController. */
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000
|
||||
int i;
|
||||
int clickedindex = messageboxdata->numbuttons;
|
||||
UIAlertView *alert = [[UIAlertView alloc] init];
|
||||
SDLAlertViewDelegate *delegate = [[SDLAlertViewDelegate alloc] init];
|
||||
|
||||
alert.delegate = delegate;
|
||||
alert.title = @(messageboxdata->title);
|
||||
alert.message = @(messageboxdata->message);
|
||||
|
||||
for (i = 0; i < messageboxdata->numbuttons; i++) {
|
||||
const SDL_MessageBoxButtonData *sdlButton;
|
||||
if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) {
|
||||
sdlButton = &messageboxdata->buttons[messageboxdata->numbuttons - 1 - i];
|
||||
} else {
|
||||
sdlButton = &messageboxdata->buttons[i];
|
||||
}
|
||||
[alert addButtonWithTitle:@(sdlButton->text)];
|
||||
}
|
||||
|
||||
delegate.clickedIndex = &clickedindex;
|
||||
|
||||
[alert show];
|
||||
|
||||
UIKit_WaitUntilMessageBoxClosed(messageboxdata, &clickedindex);
|
||||
|
||||
alert.delegate = nil;
|
||||
|
||||
if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) {
|
||||
clickedindex = messageboxdata->numbuttons - 1 - clickedindex;
|
||||
}
|
||||
*buttonid = messageboxdata->buttons[clickedindex].buttonid;
|
||||
return YES;
|
||||
#else
|
||||
return NO;
|
||||
#endif /* __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 */
|
||||
}
|
||||
|
||||
static void
|
||||
UIKit_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int *buttonid, int *returnValue)
|
||||
{ @autoreleasepool
|
||||
{
|
||||
BOOL success = NO;
|
||||
|
||||
@autoreleasepool {
|
||||
success = UIKit_ShowMessageBoxAlertController(messageboxdata, buttonid);
|
||||
if (!success) {
|
||||
success = UIKit_ShowMessageBoxAlertView(messageboxdata, buttonid);
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
*returnValue = SDL_SetError("Could not show message box.");
|
||||
} else {
|
||||
if (UIKit_ShowMessageBoxAlertController(messageboxdata, buttonid)) {
|
||||
*returnValue = 0;
|
||||
} else {
|
||||
*returnValue = SDL_SetError("Could not show message box.");
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
||||
int
|
||||
UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
/*
|
||||
* @author Mark Callow, www.edgewise-consulting.com.
|
||||
*
|
||||
* Thanks to Alex Szpakowski, @slime73 on GitHub, for his gist showing
|
||||
* how to add a CAMetalLayer backed view.
|
||||
* Thanks to @slime73 on GitHub for their gist showing how to add a CAMetalLayer
|
||||
* backed view.
|
||||
*/
|
||||
|
||||
#ifndef SDL_uikitmetalview_h_
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
/*
|
||||
* @author Mark Callow, www.edgewise-consulting.com.
|
||||
*
|
||||
* Thanks to Alex Szpakowski, @slime73 on GitHub, for his gist showing
|
||||
* how to add a CAMetalLayer backed view.
|
||||
* Thanks to @slime73 on GitHub for their gist showing how to add a CAMetalLayer
|
||||
* backed view.
|
||||
*/
|
||||
|
||||
#include "../../SDL_internal.h"
|
||||
@@ -87,11 +87,7 @@ UIKit_Metal_CreateView(_THIS, SDL_Window * window)
|
||||
* dimensions of the screen rather than the dimensions in points
|
||||
* yielding high resolution on retine displays.
|
||||
*/
|
||||
if ([data.uiwindow.screen respondsToSelector:@selector(nativeScale)]) {
|
||||
scale = data.uiwindow.screen.nativeScale;
|
||||
} else {
|
||||
scale = data.uiwindow.screen.scale;
|
||||
}
|
||||
scale = data.uiwindow.screen.nativeScale;
|
||||
}
|
||||
|
||||
metalview = [[SDL_uikitmetalview alloc] initWithFrame:data.uiwindow.bounds
|
||||
|
||||
@@ -150,11 +150,7 @@
|
||||
* Estimate the DPI based on the screen scale multiplied by the base DPI for the device
|
||||
* type (e.g. based on iPhone 1 and iPad 1)
|
||||
*/
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000
|
||||
float scale = (float)screen.nativeScale;
|
||||
#else
|
||||
float scale = (float)screen.scale;
|
||||
#endif
|
||||
float defaultDPI;
|
||||
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
|
||||
defaultDPI = 132.0f;
|
||||
@@ -503,12 +499,6 @@ UIKit_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0
|
||||
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;
|
||||
|
||||
@@ -150,9 +150,8 @@ UIKit_GL_CreateContext(_THIS, SDL_Window * window)
|
||||
* versions. */
|
||||
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)))) {
|
||||
/* iOS currently doesn't support GLES >3.0. */
|
||||
if (major > 3 || (major == 3 && minor > 0)) {
|
||||
SDL_SetError("OpenGL ES %d.%d context could not be created", major, minor);
|
||||
return NULL;
|
||||
}
|
||||
@@ -170,11 +169,7 @@ UIKit_GL_CreateContext(_THIS, SDL_Window * window)
|
||||
/* Set the scale to the natural scale factor of the screen - the
|
||||
* backing dimensions of the OpenGL view will match the pixel
|
||||
* dimensions of the screen rather than the dimensions in points. */
|
||||
if ([data.uiwindow.screen respondsToSelector:@selector(nativeScale)]) {
|
||||
scale = data.uiwindow.screen.nativeScale;
|
||||
} else {
|
||||
scale = data.uiwindow.screen.scale;
|
||||
}
|
||||
scale = data.uiwindow.screen.nativeScale;
|
||||
}
|
||||
|
||||
context = [[SDLEAGLContext alloc] initWithAPI:api sharegroup:sharegroup];
|
||||
|
||||
@@ -93,14 +93,8 @@
|
||||
}
|
||||
|
||||
if (sRGB) {
|
||||
/* sRGB EAGL drawable support was added in iOS 7. */
|
||||
if (UIKit_IsSystemVersionAtLeast(7.0)) {
|
||||
colorFormat = kEAGLColorFormatSRGBA8;
|
||||
colorBufferFormat = GL_SRGB8_ALPHA8;
|
||||
} else {
|
||||
SDL_SetError("sRGB drawables are not supported.");
|
||||
return nil;
|
||||
}
|
||||
colorFormat = kEAGLColorFormatSRGBA8;
|
||||
colorBufferFormat = GL_SRGB8_ALPHA8;
|
||||
} else if (rBits >= 8 || gBits >= 8 || bBits >= 8 || aBits > 0) {
|
||||
/* if user specifically requests rbg888 or some color format higher than 16bpp */
|
||||
colorFormat = kEAGLColorFormatRGBA8;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user