early-access version 2281

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

View File

@@ -53,6 +53,9 @@ typedef struct
#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2
#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 NULL
#endif
#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES
#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES NULL
#endif
#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR
#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR NULL
#endif
@@ -69,6 +72,7 @@ static x11dynlib x11libs[] = {
{NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR},
{NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA},
{NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2},
{NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES},
{NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR},
{NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS},
{NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE}

View File

@@ -39,7 +39,6 @@
#include <X11/Xproto.h>
#include <X11/extensions/Xext.h>
#include <X11/extensions/extutil.h>
#ifndef NO_SHARED_MEMORY
#include <sys/ipc.h>
@@ -59,6 +58,9 @@
#if SDL_VIDEO_DRIVER_X11_XINPUT2
#include <X11/extensions/XInput2.h>
#endif
#if SDL_VIDEO_DRIVER_X11_XFIXES
#include <X11/extensions/Xfixes.h>
#endif
#if SDL_VIDEO_DRIVER_X11_XRANDR
#include <X11/extensions/Xrandr.h>
#endif

View File

@@ -31,6 +31,7 @@
#include "SDL_x11video.h"
#include "SDL_x11touch.h"
#include "SDL_x11xinput2.h"
#include "SDL_x11xfixes.h"
#include "../../core/unix/SDL_poll.h"
#include "../../events/SDL_events_c.h"
#include "../../events/SDL_mouse_c.h"
@@ -269,19 +270,19 @@ static char* X11_URIToLocal(char* uri) {
char *file = NULL;
SDL_bool local;
if (memcmp(uri,"file:/",6) == 0) uri += 6; /* local file? */
else if (strstr(uri,":/") != NULL) return file; /* wrong scheme */
if (SDL_memcmp(uri,"file:/",6) == 0) uri += 6; /* local file? */
else if (SDL_strstr(uri,":/") != NULL) return file; /* wrong scheme */
local = uri[0] != '/' || (uri[0] != '\0' && uri[1] == '/');
/* got a hostname? */
if (!local && uri[0] == '/' && uri[2] != '/') {
char* hostname_end = strchr(uri+1, '/');
char* hostname_end = SDL_strchr(uri+1, '/');
if (hostname_end != NULL) {
char hostname[ 257 ];
if (gethostname(hostname, 255) == 0) {
hostname[ 256 ] = '\0';
if (memcmp(uri+1, hostname, hostname_end - (uri+1)) == 0) {
if (SDL_memcmp(uri+1, hostname, hostname_end - (uri+1)) == 0) {
uri = hostname_end + 1;
local = SDL_TRUE;
}
@@ -353,6 +354,32 @@ X11_GetNumLockModifierMask(_THIS)
return num_mask;
}
static unsigned
X11_GetScrollLockModifierMask(_THIS)
{
SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata;
Display *display = viddata->display;
unsigned num_mask = 0;
int i, j;
XModifierKeymap *xmods;
unsigned n;
xmods = X11_XGetModifierMapping(display);
n = xmods->max_keypermod;
for(i = 3; i < 8; i++) {
for(j = 0; j < n; j++) {
KeyCode kc = xmods->modifiermap[i * n + j];
if (viddata->key_layout[kc] == SDL_SCANCODE_SCROLLLOCK) {
num_mask = 1 << i;
break;
}
}
}
X11_XFreeModifiermap(xmods);
return num_mask;
}
static void
X11_ReconcileKeyboardState(_THIS)
{
@@ -371,6 +398,7 @@ X11_ReconcileKeyboardState(_THIS)
if (X11_XQueryPointer(display, DefaultRootWindow(display), &junk_window, &junk_window, &x, &y, &x, &y, &mask)) {
SDL_ToggleModState(KMOD_CAPS, (mask & LockMask) != 0);
SDL_ToggleModState(KMOD_NUM, (mask & X11_GetNumLockModifierMask(_this)) != 0);
SDL_ToggleModState(KMOD_SCROLL, (mask & X11_GetScrollLockModifierMask(_this)) != 0);
}
keyboardState = SDL_GetKeyboardState(0);
@@ -780,7 +808,8 @@ X11_DispatchEvent(_THIS, XEvent *xevent)
if (SDL_GetKeyboardFocus() != NULL) {
X11_ReconcileKeyboardState(_this);
}
} else if (xevent->type == MappingNotify || xkbEvent->any.xkb_type == XkbStateNotify) {
} else if (xevent->type == MappingNotify ||
(xevent->type == videodata->xkb_event && xkbEvent->any.xkb_type == XkbStateNotify)) {
/* Has the keyboard layout changed? */
const int request = xevent->xmapping.request;
@@ -793,6 +822,31 @@ X11_DispatchEvent(_THIS, XEvent *xevent)
X11_UpdateKeymap(_this);
SDL_SendKeymapChangedEvent();
} else if (xevent->type == PropertyNotify && videodata && videodata->windowlist) {
char* name_of_atom = X11_XGetAtomName(display, xevent->xproperty.atom);
if (SDL_strncmp(name_of_atom, "_ICC_PROFILE", sizeof("_ICC_PROFILE") - 1) == 0) {
XWindowAttributes attrib;
int screennum;
for (i = 0; i < videodata->numwindows; ++i) {
if (videodata->windowlist[i] != NULL) {
data = videodata->windowlist[i];
X11_XGetWindowAttributes(display, data->xwindow, &attrib);
screennum = X11_XScreenNumberOfScreen(attrib.screen);
if (screennum == 0 && SDL_strcmp(name_of_atom, "_ICC_PROFILE") == 0) {
SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_ICCPROF_CHANGED, 0, 0);
} else if (SDL_strncmp(name_of_atom, "_ICC_PROFILE_", sizeof("_ICC_PROFILE_") - 1) == 0 && SDL_strlen(name_of_atom) > sizeof("_ICC_PROFILE_") - 1) {
int iccscreennum = SDL_atoi(&name_of_atom[sizeof("_ICC_PROFILE_") - 1]);
if (screennum == iccscreennum) {
SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_ICCPROF_CHANGED, 0, 0);
}
}
}
}
}
if (name_of_atom) X11_XFree(name_of_atom);
}
return;
}
@@ -817,6 +871,16 @@ X11_DispatchEvent(_THIS, XEvent *xevent)
mouse->last_x = xevent->xcrossing.x;
mouse->last_y = xevent->xcrossing.y;
#if SDL_VIDEO_DRIVER_X11_XFIXES
{
/* Only create the barriers if we have input focus */
SDL_WindowData* windowdata = (SDL_WindowData *) data->window->driverdata;
if ((data->pointer_barrier_active == SDL_TRUE) && windowdata->window->flags & SDL_WINDOW_INPUT_FOCUS) {
X11_ConfineCursorWithFlags(_this, windowdata->window, &windowdata->barrier_rect, X11_BARRIER_HANDLED_BY_EVENT);
}
}
#endif
if (!mouse->relative_mode) {
SDL_SendMouseMotion(data->window, 0, 0, xevent->xcrossing.x, xevent->xcrossing.y);
}
@@ -922,6 +986,13 @@ X11_DispatchEvent(_THIS, XEvent *xevent)
data->pending_focus = PENDING_FOCUS_OUT;
data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_TIME;
}
#if SDL_VIDEO_DRIVER_X11_XFIXES
/* Disable confinement if it is activated. */
if (data->pointer_barrier_active == SDL_TRUE) {
X11_ConfineCursorWithFlags(_this, data->window, NULL, X11_BARRIER_HANDLED_BY_EVENT);
}
#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */
}
break;
@@ -1007,6 +1078,13 @@ X11_DispatchEvent(_THIS, XEvent *xevent)
} else {
X11_DispatchUnmapNotify(data);
}
#if SDL_VIDEO_DRIVER_X11_XFIXES
/* Disable confinement if the window gets hidden. */
if (data->pointer_barrier_active == SDL_TRUE) {
X11_ConfineCursorWithFlags(_this, data->window, NULL, X11_BARRIER_HANDLED_BY_EVENT);
}
#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */
}
break;
@@ -1016,6 +1094,13 @@ X11_DispatchEvent(_THIS, XEvent *xevent)
printf("window %p: MapNotify!\n", data);
#endif
X11_DispatchMapNotify(data);
#if SDL_VIDEO_DRIVER_X11_XFIXES
/* Enable confinement if it was activated. */
if (data->pointer_barrier_active == SDL_TRUE) {
X11_ConfineCursorWithFlags(_this, data->window, &data->barrier_rect, X11_BARRIER_HANDLED_BY_EVENT);
}
#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */
}
break;
@@ -1101,7 +1186,7 @@ X11_DispatchEvent(_THIS, XEvent *xevent)
/* reply with status */
memset(&m, 0, sizeof(XClientMessageEvent));
SDL_memset(&m, 0, sizeof(XClientMessageEvent));
m.type = ClientMessage;
m.display = xevent->xclient.display;
m.window = xevent->xclient.data.l[0];
@@ -1119,7 +1204,7 @@ X11_DispatchEvent(_THIS, XEvent *xevent)
else if(xevent->xclient.message_type == videodata->XdndDrop) {
if (data->xdnd_req == None) {
/* say again - not interested! */
memset(&m, 0, sizeof(XClientMessageEvent));
SDL_memset(&m, 0, sizeof(XClientMessageEvent));
m.type = ClientMessage;
m.display = xevent->xclient.display;
m.window = xevent->xclient.data.l[0];
@@ -1201,7 +1286,7 @@ X11_DispatchEvent(_THIS, XEvent *xevent)
printf("window %p: ButtonPress (X11 button = %d)\n", data, xevent->xbutton.button);
#endif
if (X11_IsWheelEvent(display,xevent,&xticks, &yticks)) {
SDL_SendMouseWheel(data->window, 0, (float) xticks, (float) yticks, SDL_MOUSEWHEEL_NORMAL);
SDL_SendMouseWheel(data->window, 0, (float) -xticks, (float) yticks, SDL_MOUSEWHEEL_NORMAL);
} else {
SDL_bool ignore_click = SDL_FALSE;
int button = xevent->xbutton.button;
@@ -1473,23 +1558,21 @@ X11_HandleFocusChanges(_THIS)
}
}
}
/* Ack! X11_XPending() actually performs a blocking read if no events available */
static int
X11_Pending(Display * display)
static Bool
isAnyEvent(Display *display, XEvent *ev, XPointer arg)
{
/* Flush the display connection and look to see if events are queued */
X11_XFlush(display);
if (X11_XEventsQueued(display, QueuedAlready)) {
return (1);
return True;
}
static SDL_bool
X11_PollEvent(Display *display, XEvent *event)
{
if (!X11_XCheckIfEvent(display, event, isAnyEvent, NULL)) {
return SDL_FALSE;
}
/* More drastic measures are required -- see if X is ready to talk */
if (SDL_IOReady(ConnectionNumber(display), SDL_FALSE, 0)) {
return (X11_XPending(display));
}
/* Oh well, nothing is ready .. */
return (0);
return SDL_TRUE;
}
void
@@ -1500,7 +1583,7 @@ X11_SendWakeupEvent(_THIS, SDL_Window *window)
Window xwindow = ((SDL_WindowData *) window->driverdata)->xwindow;
XClientMessageEvent event;
memset(&event, 0, sizeof(XClientMessageEvent));
SDL_memset(&event, 0, sizeof(XClientMessageEvent));
event.type = ClientMessage;
event.display = req_display;
event.send_event = True;
@@ -1527,27 +1610,35 @@ X11_WaitEventTimeout(_THIS, int timeout)
SDL_zero(xevent);
if (timeout == 0) {
if (X11_Pending(display)) {
X11_XNextEvent(display, &xevent);
} else {
return 0;
}
} else if (timeout > 0) {
int display_fd = ConnectionNumber(display);
fd_set readset;
struct timeval tv_timeout;
FD_ZERO(&readset);
FD_SET(display_fd, &readset);
tv_timeout.tv_sec = (timeout / 1000);
tv_timeout.tv_usec = (timeout % 1000) * 1000;
if (select(display_fd + 1, &readset, NULL, NULL, &tv_timeout) > 0) {
X11_XNextEvent(display, &xevent);
} else {
return 0;
}
/* Flush and poll to grab any events already read and queued */
X11_XFlush(display);
if (X11_PollEvent(display, &xevent)) {
/* Fall through */
} else if (timeout == 0) {
return 0;
} else {
X11_XNextEvent(display, &xevent);
/* Use SDL_IOR_NO_RETRY to ensure SIGINT will break us out of our wait */
int err = SDL_IOReady(ConnectionNumber(display), SDL_IOR_READ | SDL_IOR_NO_RETRY, timeout);
if (err > 0) {
if (!X11_PollEvent(display, &xevent)) {
/* Someone may have beat us to reading the fd. Return 1 here to
* trigger the normal spurious wakeup logic in the event core. */
return 1;
}
} else if (err == 0) {
/* Timeout */
return 0;
} else {
/* Error returned from poll()/select() */
if (errno == EINTR) {
/* If the wait was interrupted by a signal, we may have generated a
* SDL_QUIT event. Let the caller know to call SDL_PumpEvents(). */
return 1;
} else {
return err;
}
}
}
X11_DispatchEvent(_this, &xevent);
@@ -1591,8 +1682,7 @@ X11_PumpEvents(_THIS)
SDL_zero(xevent);
/* Keep processing pending events */
while (X11_Pending(data->display)) {
X11_XNextEvent(data->display, &xevent);
while (X11_PollEvent(data->display, &xevent)) {
X11_DispatchEvent(_this, &xevent);
}

View File

@@ -31,7 +31,7 @@
#include <X11/keysym.h>
#include <X11/XKBlib.h>
#include "imKStoUCS.h"
#include "../../events/imKStoUCS.h"
#ifdef X_HAVE_UTF8_STRING
#include <locale.h>
@@ -205,7 +205,7 @@ X11_KeyCodeToUcs4(_THIS, KeyCode keycode, unsigned char group)
return 0;
}
return X11_KeySymToUcs4(keysym);
return SDL_KeySymToUcs4(keysym);
}
KeySym
@@ -278,7 +278,7 @@ X11_InitKeyboard(_THIS)
int xkb_major = XkbMajorVersion;
int xkb_minor = XkbMinorVersion;
if (X11_XkbQueryExtension(data->display, NULL, NULL, NULL, &xkb_major, &xkb_minor)) {
if (X11_XkbQueryExtension(data->display, NULL, &data->xkb_event, NULL, &xkb_major, &xkb_minor)) {
data->xkb = X11_XkbGetMap(data->display, XkbAllClientInfoMask, XkbUseCoreKbd);
}

View File

@@ -334,10 +334,10 @@ X11_MessageBoxInitPositions( SDL_MessageBoxDataX11 *data )
/* Location for first button. */
if ( messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT ) {
x = data->dialog_width - ( data->dialog_width - width_of_buttons ) / 2 - ( button_width + button_spacing );
} else {
x = ( data->dialog_width - width_of_buttons ) / 2;
}
x = data->dialog_width - ( data->dialog_width - width_of_buttons ) / 2 - ( button_width + button_spacing );
} else {
x = ( data->dialog_width - width_of_buttons ) / 2;
}
y = ybuttons + ( data->dialog_height - ybuttons - button_height ) / 2;
for ( i = 0; i < data->numbuttons; i++ ) {
@@ -352,11 +352,11 @@ X11_MessageBoxInitPositions( SDL_MessageBoxDataX11 *data )
data->buttonpos[ i ].y = y + ( button_height - button_text_height - 1 ) / 2 + button_text_height;
/* Scoot over for next button. */
if ( messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT ) {
x -= button_width + button_spacing;
} else {
x += button_width + button_spacing;
}
if ( messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT ) {
x -= button_width + button_spacing;
} else {
x += button_width + button_spacing;
}
}
}
@@ -404,11 +404,10 @@ X11_MessageBoxCreateWindow( SDL_MessageBoxDataX11 *data )
int x, y;
XSizeHints *sizehints;
XSetWindowAttributes wnd_attr;
Atom _NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_DIALOG, _NET_WM_NAME;
Atom _NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_DIALOG;
Display *display = data->display;
SDL_WindowData *windowdata = NULL;
const SDL_MessageBoxData *messageboxdata = data->messageboxdata;
char *title_locale = NULL;
if ( messageboxdata->window ) {
SDL_DisplayData *displaydata =
@@ -452,32 +451,7 @@ X11_MessageBoxCreateWindow( SDL_MessageBoxDataX11 *data )
X11_XSetTransientForHint( display, data->window, windowdata->xwindow );
}
X11_XStoreName( display, data->window, messageboxdata->title );
_NET_WM_NAME = X11_XInternAtom(display, "_NET_WM_NAME", False);
title_locale = SDL_iconv_utf8_locale(messageboxdata->title);
if (title_locale) {
XTextProperty titleprop;
Status status = X11_XStringListToTextProperty(&title_locale, 1, &titleprop);
SDL_free(title_locale);
if (status) {
X11_XSetTextProperty(display, data->window, &titleprop, XA_WM_NAME);
X11_XFree(titleprop.value);
}
}
#ifdef X_HAVE_UTF8_STRING
if (SDL_X11_HAVE_UTF8) {
XTextProperty titleprop;
Status status = X11_Xutf8TextListToTextProperty(display, (char **) &messageboxdata->title, 1,
XUTF8StringStyle, &titleprop);
if (status == Success) {
X11_XSetTextProperty(display, data->window, &titleprop,
_NET_WM_NAME);
X11_XFree(titleprop.value);
}
}
#endif
SDL_X11_SetWindowTitle(display, data->window, (char*)messageboxdata->title);
/* Let the window manager know this is a dialog box */
_NET_WM_WINDOW_TYPE = X11_XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);

View File

@@ -322,7 +322,7 @@ SetXRandRDisplayName(Display *dpy, Atom EDID, char *name, const size_t namelen,
dump_monitor_info(info);
#endif
SDL_strlcpy(name, info->dsc_product_name, namelen);
free(info);
SDL_free(info);
}
X11_XFree(prop);
}
@@ -358,7 +358,7 @@ GetXftDPI(Display* dpy)
}
/*
* It's possible for SDL_atoi to call strtol, if it fails due to a
* It's possible for SDL_atoi to call SDL_strtol, if it fails due to a
* overflow or an underflow, it will return LONG_MAX or LONG_MIN and set
* errno to ERANGE. So we need to check for this so we dont get crazy dpi
* values
@@ -849,6 +849,16 @@ X11_InitModes(_THIS)
if (_this->num_displays == 0) {
return SDL_SetError("No available displays");
}
#if SDL_VIDEO_DRIVER_X11_XVIDMODE
if (use_vidmode) { /* we intend to remove support for XVidMode soon. */
SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "SDL is using XVidMode to manage your displays!");
SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "This almost always means either SDL was misbuilt");
SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "or your X server is insufficient. Please check your setup!");
SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Fullscreen and/or multiple displays will not work well.");
}
#endif
return 0;
}
@@ -1040,11 +1050,20 @@ X11_SetDisplayMode(_THIS, SDL_VideoDisplay * sdl_display, SDL_DisplayMode * mode
return SDL_SetError("Couldn't get XRandR crtc info");
}
if (crtc->mode == modedata->xrandr_mode) {
#ifdef X11MODES_DEBUG
printf("already in desired mode 0x%lx (%ux%u), nothing to do\n",
crtc->mode, crtc->width, crtc->height);
#endif
status = Success;
goto freeInfo;
}
X11_XGrabServer(display);
status = X11_XRRSetCrtcConfig(display, res, output_info->crtc, CurrentTime,
0, 0, None, crtc->rotation, NULL, 0);
if (status != Success) {
goto setCrtcError;
goto ungrabServer;
}
mm_width = mode->w * DisplayWidthMM(display, data->screen) / DisplayWidth(display, data->screen);
@@ -1067,8 +1086,9 @@ X11_SetDisplayMode(_THIS, SDL_VideoDisplay * sdl_display, SDL_DisplayMode * mode
crtc->x, crtc->y, modedata->xrandr_mode, crtc->rotation,
&data->xrandr_output, 1);
setCrtcError:
ungrabServer:
X11_XUngrabServer(display);
freeInfo:
X11_XRRFreeCrtcInfo(crtc);
X11_XRRFreeOutputInfo(output_info);
X11_XRRFreeScreenResources(res);

View File

@@ -195,6 +195,8 @@ X11_CreatePixmapCursor(SDL_Surface * surface, int hot_x, int hot_y)
&fg, &bg, hot_x, hot_y);
X11_XFreePixmap(display, data_pixmap);
X11_XFreePixmap(display, mask_pixmap);
SDL_free(data_bits);
SDL_free(mask_bits);
return cursor;
}
@@ -321,7 +323,15 @@ static void
X11_WarpMouse(SDL_Window * window, int x, int y)
{
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
#if SDL_VIDEO_DRIVER_X11_XFIXES
/* If we have no barrier, we need to warp */
if (data->pointer_barrier_active == SDL_FALSE) {
WarpMouseInternal(data->xwindow, x, y);
}
#else
WarpMouseInternal(data->xwindow, x, y);
#endif
}
static int

View File

@@ -142,7 +142,7 @@ typedef GLXContext(*PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display * dpy,
#endif
#define OPENGL_REQUIRES_DLOPEN
#if defined(OPENGL_REQUIRES_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
#if defined(OPENGL_REQUIRES_DLOPEN) && defined(HAVE_DLOPEN)
#include <dlfcn.h>
#define GL_LoadObject(X) dlopen(X, (RTLD_NOW|RTLD_GLOBAL))
#define GL_LoadFunction dlsym
@@ -174,7 +174,7 @@ X11_GL_LoadLibrary(_THIS, const char *path)
}
_this->gl_config.dll_handle = GL_LoadObject(path);
if (!_this->gl_config.dll_handle) {
#if defined(OPENGL_REQUIRES_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
#if defined(OPENGL_REQUIRES_DLOPEN) && defined(HAVE_DLOPEN)
SDL_SetError("Failed loading %s: %s", path, dlerror());
#endif
return -1;

View File

@@ -35,7 +35,7 @@ X11_CreateShaper(SDL_Window* window) {
#if SDL_VIDEO_DRIVER_X11_XSHAPE
if (SDL_X11_HAVE_XSHAPE) { /* Make sure X server supports it. */
result = malloc(sizeof(SDL_WindowShaper));
result = SDL_malloc(sizeof(SDL_WindowShaper));
result->window = window;
result->mode.mode = ShapeModeDefault;
result->mode.parameters.binarizationCutoff = 1;
@@ -65,13 +65,13 @@ X11_ResizeWindowShape(SDL_Window* window) {
if(data->bitmapsize != bitmapsize || data->bitmap == NULL) {
data->bitmapsize = bitmapsize;
if(data->bitmap != NULL)
free(data->bitmap);
data->bitmap = malloc(data->bitmapsize);
SDL_free(data->bitmap);
data->bitmap = SDL_malloc(data->bitmapsize);
if(data->bitmap == NULL) {
return SDL_SetError("Could not allocate memory for shaped-window bitmap.");
}
}
memset(data->bitmap,0,data->bitmapsize);
SDL_memset(data->bitmap,0,data->bitmapsize);
window->shaper->userx = window->x;
window->shaper->usery = window->y;

View File

@@ -97,7 +97,6 @@ SDL_X11_SYM(int,XMapRaised,(Display* a,Window b),(a,b),return)
SDL_X11_SYM(Status,XMatchVisualInfo,(Display* a,int b,int c,int d,XVisualInfo* e),(a,b,c,d,e),return)
SDL_X11_SYM(int,XMissingExtension,(Display* a,_Xconst char* b),(a,b),return)
SDL_X11_SYM(int,XMoveWindow,(Display* a,Window b,int c,int d),(a,b,c,d),return)
SDL_X11_SYM(int,XNextEvent,(Display* a,XEvent* b),(a,b),return)
SDL_X11_SYM(Display*,XOpenDisplay,(_Xconst char* a),(a),return)
SDL_X11_SYM(Status,XInitThreads,(void),(),return)
SDL_X11_SYM(int,XPeekEvent,(Display* a,XEvent* b),(a,b),return)
@@ -109,6 +108,7 @@ SDL_X11_SYM(int,XRaiseWindow,(Display* a,Window b),(a,b),return)
SDL_X11_SYM(int,XReparentWindow,(Display* a,Window b,Window c,int d,int e),(a,b,c,d,e),return)
SDL_X11_SYM(int,XResetScreenSaver,(Display* a),(a),return)
SDL_X11_SYM(int,XResizeWindow,(Display* a,Window b,unsigned int c,unsigned int d),(a,b,c,d),return)
SDL_X11_SYM(int,XScreenNumberOfScreen,(Screen* a),(a),return)
SDL_X11_SYM(int,XSelectInput,(Display* a,Window b,long c),(a,b,c),return)
SDL_X11_SYM(Status,XSendEvent,(Display* a,Window b,Bool c,long d,XEvent* e),(a,b,c,d,e),return)
SDL_X11_SYM(XErrorHandler,XSetErrorHandler,(XErrorHandler a),(a),return)
@@ -139,16 +139,7 @@ SDL_X11_SYM(int,XWarpPointer,(Display* a,Window b,Window c,int d,int e,unsigned
SDL_X11_SYM(int,XWindowEvent,(Display* a,Window b,long c,XEvent* d),(a,b,c,d),return)
SDL_X11_SYM(Status,XWithdrawWindow,(Display* a,Window b,int c),(a,b,c),return)
SDL_X11_SYM(VisualID,XVisualIDFromVisual,(Visual* a),(a),return)
SDL_X11_SYM(char*,XGetDefault,(Display* a,char* b, char* c),(a,b,c),return)
#if SDL_VIDEO_DRIVER_X11_CONST_PARAM_XEXTADDDISPLAY
SDL_X11_SYM(XExtDisplayInfo*,XextAddDisplay,(XExtensionInfo* a,Display* b,_Xconst char* c,XExtensionHooks* d,int e,XPointer f),(a,b,c,d,e,f),return)
#else
SDL_X11_SYM(XExtDisplayInfo*,XextAddDisplay,(XExtensionInfo* a,Display* b,char* c,XExtensionHooks* d,int e,XPointer f),(a,b,c,d,e,f),return)
#endif
SDL_X11_SYM(XExtensionInfo*,XextCreateExtension,(void),(),return)
SDL_X11_SYM(void,XextDestroyExtension,(XExtensionInfo* a),(a),)
SDL_X11_SYM(XExtDisplayInfo*,XextFindDisplay,(XExtensionInfo* a,Display* b),(a,b),return)
SDL_X11_SYM(int,XextRemoveDisplay,(XExtensionInfo* a,Display* b),(a,b),return)
SDL_X11_SYM(char*,XGetDefault,(Display* a,_Xconst char* b, _Xconst char* c),(a,b,c),return)
SDL_X11_SYM(Bool,XQueryExtension,(Display* a,_Xconst char* b,int* c,int* d,int* e),(a,b,c,d,e),return)
SDL_X11_SYM(char *,XDisplayString,(Display* a),(a),return)
SDL_X11_SYM(int,XGetErrorText,(Display* a,int b,char* c,int d),(a,b,c,d),return)
@@ -165,6 +156,16 @@ SDL_X11_SYM(SDL_X11_XESetWireToEventRetType,XESetWireToEvent,(Display* a,int b,S
SDL_X11_SYM(SDL_X11_XESetEventToWireRetType,XESetEventToWire,(Display* a,int b,SDL_X11_XESetEventToWireRetType c),(a,b,c),return)
SDL_X11_SYM(void,XRefreshKeyboardMapping,(XMappingEvent *a),(a),)
SDL_X11_SYM(int,XQueryTree,(Display* a,Window b,Window* c,Window* d,Window** e,unsigned int* f),(a,b,c,d,e,f),return)
SDL_X11_SYM(Bool,XSupportsLocale,(void),(),return)
SDL_X11_SYM(Status,XmbTextListToTextProperty,(Display* a,char** b,int c,XICCEncodingStyle d,XTextProperty* e),(a,b,c,d,e),return)
#if SDL_VIDEO_DRIVER_X11_XFIXES
SDL_X11_MODULE(XFIXES)
SDL_X11_SYM(PointerBarrier, XFixesCreatePointerBarrier, (Display* a, Window b, int c, int d, int e, int f, int g, int h, int *i),(a,b,c,d,e,f,g,h,i),return)
SDL_X11_SYM(void, XFixesDestroyPointerBarrier, (Display* a, PointerBarrier b), (a,b),)
SDL_X11_SYM(int, XIBarrierReleasePointer,(Display* a, int b, PointerBarrier c, BarrierEventID d), (a,b,c,d), return)
SDL_X11_SYM(Status, XFixesQueryVersion,(Display* a, int* b, int* c), (a,b,c), return)
#endif
#if SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS
SDL_X11_SYM(Bool,XGetEventData,(Display* a,XGenericEventCookie* b),(a,b),return)

View File

@@ -36,6 +36,7 @@
#include "SDL_x11shape.h"
#include "SDL_x11touch.h"
#include "SDL_x11xinput2.h"
#include "SDL_x11xfixes.h"
#if SDL_VIDEO_OPENGL_EGL
#include "SDL_x11opengles.h"
@@ -184,10 +185,13 @@ X11_CreateDevice(int devindex)
return NULL;
}
device->driverdata = data;
device->wakeup_lock = SDL_CreateMutex();
data->global_mouse_changed = SDL_TRUE;
#if SDL_VIDEO_DRIVER_X11_XFIXES
data->active_cursor_confined_window = NULL;
#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */
data->display = x11_display;
data->request_display = X11_XOpenDisplay(display);
if (data->request_display == NULL) {
@@ -216,6 +220,7 @@ X11_CreateDevice(int devindex)
device->GetDisplayBounds = X11_GetDisplayBounds;
device->GetDisplayUsableBounds = X11_GetDisplayUsableBounds;
device->GetDisplayDPI = X11_GetDisplayDPI;
device->GetWindowICCProfile = X11_GetWindowICCProfile;
device->SetDisplayMode = X11_SetDisplayMode;
device->SuspendScreenSaver = X11_SuspendScreenSaver;
device->PumpEvents = X11_PumpEvents;
@@ -256,6 +261,10 @@ X11_CreateDevice(int devindex)
device->AcceptDragAndDrop = X11_AcceptDragAndDrop;
device->FlashWindow = X11_FlashWindow;
#if SDL_VIDEO_DRIVER_X11_XFIXES
device->SetWindowMouseRect = X11_SetWindowMouseRect;
#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */
device->shape_driver.CreateShaper = X11_CreateShaper;
device->shape_driver.SetWindowShape = X11_SetWindowShape;
device->shape_driver.ResizeWindowShape = X11_ResizeWindowShape;
@@ -405,6 +414,7 @@ X11_VideoInit(_THIS)
GET_ATOM(WM_PROTOCOLS);
GET_ATOM(WM_DELETE_WINDOW);
GET_ATOM(WM_TAKE_FOCUS);
GET_ATOM(WM_NAME);
GET_ATOM(_NET_WM_STATE);
GET_ATOM(_NET_WM_STATE_HIDDEN);
GET_ATOM(_NET_WM_STATE_FOCUSED);
@@ -446,6 +456,14 @@ X11_VideoInit(_THIS)
X11_InitXinput2(_this);
#ifdef SDL_VIDEO_DRIVER_X11_XFIXES
X11_InitXfixes(_this);
#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */
#ifndef X_HAVE_UTF8_STRING
#warning X server does not support UTF8_STRING, a feature introduced in 2000! This is likely to become a hard error in a future libSDL2.
#endif
if (X11_InitKeyboard(_this) != 0) {
return -1;
}

View File

@@ -85,6 +85,9 @@ typedef struct SDL_VideoData
int windowlistlength;
XID window_group;
Window clipboard_window;
#if SDL_VIDEO_DRIVER_X11_XFIXES
SDL_Window *active_cursor_confined_window;
#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */
/* This is true for ICCCM2.0-compliant window managers */
SDL_bool net_wm;
@@ -93,6 +96,7 @@ typedef struct SDL_VideoData
Atom WM_PROTOCOLS;
Atom WM_DELETE_WINDOW;
Atom WM_TAKE_FOCUS;
Atom WM_NAME;
Atom _NET_WM_STATE;
Atom _NET_WM_STATE_HIDDEN;
Atom _NET_WM_STATE_FOCUSED;
@@ -139,6 +143,7 @@ typedef struct SDL_VideoData
#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM
XkbDescPtr xkb;
#endif
int xkb_event;
KeyCode filter_code;
Time filter_time;

View File

@@ -32,6 +32,7 @@
#include "SDL_x11mouse.h"
#include "SDL_x11shape.h"
#include "SDL_x11xinput2.h"
#include "SDL_x11xfixes.h"
#if SDL_VIDEO_OPENGL_EGL
#include "SDL_x11opengles.h"
@@ -261,6 +262,7 @@ SetupWindowData(_THIS, SDL_Window * window, Window w, BOOL created)
}
data->window = window;
data->xwindow = w;
#ifdef X_HAVE_UTF8_STRING
if (SDL_X11_HAVE_UTF8 && videodata->im) {
data->ic =
@@ -670,6 +672,9 @@ X11_CreateWindow(_THIS, SDL_Window * window)
PropertyChangeMask | StructureNotifyMask |
KeymapStateMask | fevent));
/* For _ICC_PROFILE. */
X11_XSelectInput(display, RootWindow(display, screen), PropertyChangeMask);
X11_XkbSelectEvents(display, XkbUseCoreKbd, XkbStateNotifyMask, XkbStateNotifyMask);
X11_XFlush(display);
@@ -713,8 +718,10 @@ X11_GetWindowTitle(_THIS, Window xwindow)
&items_read, &items_left, &propdata);
if (status == Success && propdata) {
title = SDL_iconv_string("UTF-8", "", SDL_static_cast(char*, propdata), items_read+1);
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Failed to convert WM_NAME title expecting UTF8! Title: %s", title);
X11_XFree(propdata);
} else {
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Could not get any window title response from Xorg, returning empty string!");
title = SDL_strdup("");
}
}
@@ -725,27 +732,11 @@ void
X11_SetWindowTitle(_THIS, SDL_Window * window)
{
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
Window xwindow = data->xwindow;
Display *display = data->videodata->display;
Status status;
const char *title = window->title ? window->title : "";
char *title = window->title ? window->title : "";
Atom UTF8_STRING = data->videodata->UTF8_STRING;
Atom _NET_WM_NAME = data->videodata->_NET_WM_NAME;
status = X11_XChangeProperty(display, data->xwindow, _NET_WM_NAME, UTF8_STRING, 8, 0, (const unsigned char *) title, strlen(title));
if (status != 1) {
char *x11_error = NULL;
char x11_error_locale[256];
if (X11_XGetErrorText(display, status, x11_error_locale, sizeof(x11_error_locale)) == Success)
{
x11_error = SDL_iconv_string("UTF-8", "", x11_error_locale, SDL_strlen(x11_error_locale)+1);
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Error when setting X11 window title to %s: %s\n", title, x11_error);
SDL_free(x11_error);
}
}
X11_XFlush(display);
SDL_X11_SetWindowTitle(display, xwindow, title);
}
void
@@ -1581,6 +1572,86 @@ X11_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp)
return 0;
}
typedef struct {
unsigned char *data;
int format, count;
Atom type;
} SDL_x11Prop;
/* Reads property
Must call X11_XFree on results
*/
static void X11_ReadProperty(SDL_x11Prop *p, Display *disp, Window w, Atom prop)
{
unsigned char *ret=NULL;
Atom type;
int fmt;
unsigned long count;
unsigned long bytes_left;
int bytes_fetch = 0;
do {
if (ret != 0) X11_XFree(ret);
X11_XGetWindowProperty(disp, w, prop, 0, bytes_fetch, False, AnyPropertyType, &type, &fmt, &count, &bytes_left, &ret);
bytes_fetch += bytes_left;
} while (bytes_left != 0);
p->data=ret;
p->format=fmt;
p->count=count;
p->type=type;
}
void*
X11_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size)
{
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
Display *display = data->videodata->display;
XWindowAttributes attributes;
Atom icc_profile_atom;
char icc_atom_string[sizeof("_ICC_PROFILE_") + 12];
void* ret_icc_profile_data = NULL;
CARD8* icc_profile_data;
int real_format;
unsigned long real_nitems;
SDL_x11Prop atomProp;
X11_XGetWindowAttributes(display, X11_IsWindowLegacyFullscreen(_this, window) ? data->fswindow : data->xwindow, &attributes);
if (X11_XScreenNumberOfScreen(attributes.screen) > 0) {
SDL_snprintf(icc_atom_string, sizeof("_ICC_PROFILE_") + 12, "%s%d", "_ICC_PROFILE_", X11_XScreenNumberOfScreen(attributes.screen));
} else {
SDL_strlcpy(icc_atom_string, "_ICC_PROFILE", sizeof("_ICC_PROFILE"));
}
X11_XGetWindowAttributes(display, RootWindowOfScreen(attributes.screen), &attributes);
icc_profile_atom = X11_XInternAtom(display, icc_atom_string, True);
if (icc_profile_atom == None) {
SDL_SetError("Screen is not calibrated.\n");
return NULL;
}
X11_ReadProperty(&atomProp, display, RootWindowOfScreen(attributes.screen), icc_profile_atom);
real_format = atomProp.format;
real_nitems = atomProp.count;
icc_profile_data = atomProp.data;
if (real_format == None) {
SDL_SetError("Screen is not calibrated.\n");
return NULL;
}
ret_icc_profile_data = SDL_malloc(real_nitems);
if (!ret_icc_profile_data) {
SDL_OutOfMemory();
return NULL;
}
SDL_memcpy(ret_icc_profile_data, icc_profile_data, real_nitems);
*size = real_nitems;
X11_XFree(icc_profile_data);
return ret_icc_profile_data;
}
void
X11_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
{
@@ -1606,7 +1677,7 @@ X11_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
if (!data->videodata->broken_pointer_grab) {
const unsigned int mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask;
int attempts;
int result;
int result = 0;
/* Try for up to 5000ms (5s) to grab. If it still fails, stop trying. */
for (attempts = 0; attempts < 100; attempts++) {
@@ -1695,6 +1766,13 @@ X11_DestroyWindow(_THIS, SDL_Window * window)
X11_XFlush(display);
}
SDL_free(data);
#if SDL_VIDEO_DRIVER_X11_XFIXES
/* If the pointer barriers are active for this, deactivate it.*/
if (videodata->active_cursor_confined_window == window) {
X11_DestroyPointerBarrier(_this, window);
}
#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */
}
window->driverdata = NULL;
}
@@ -1794,6 +1872,41 @@ X11_FlashWindow(_THIS, SDL_Window * window, SDL_FlashOperation operation)
return 0;
}
int SDL_X11_SetWindowTitle(Display* display, Window xwindow, char* title) {
Atom _NET_WM_NAME = X11_XInternAtom(display, "_NET_WM_NAME", False);
XTextProperty titleprop;
int conv = X11_XmbTextListToTextProperty(display, (char**) &title, 1, XTextStyle, &titleprop);
Status status;
if (X11_XSupportsLocale() != True) {
return SDL_SetError("Current locale not supported by X server, cannot continue.");
}
if (conv == 0) {
X11_XSetTextProperty(display, xwindow, &titleprop, XA_WM_NAME);
X11_XFree(titleprop.value);
/* we know this can't be a locale error as we checked X locale validity */
} else if (conv < 0) {
return SDL_OutOfMemory();
} else { /* conv > 0 */
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "%d characters were not convertable to the current locale!", conv);
return 0;
}
#ifdef X_HAVE_UTF8_STRING
status = X11_Xutf8TextListToTextProperty(display, (char **) &title, 1, XUTF8StringStyle, &titleprop);
if (status == Success) {
X11_XSetTextProperty(display, xwindow, &titleprop, _NET_WM_NAME);
X11_XFree(titleprop.value);
} else {
return SDL_SetError("Failed to convert title to UTF8! Bad encoding, or bad Xorg encoding? Window title: «%s»", title);
}
#endif
X11_XFlush(display);
return 0;
}
#endif /* SDL_VIDEO_DRIVER_X11 */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -73,6 +73,11 @@ typedef struct
#if SDL_VIDEO_OPENGL_EGL
EGLSurface egl_surface;
#endif
#if SDL_VIDEO_DRIVER_X11_XFIXES
SDL_bool pointer_barrier_active;
PointerBarrier barrier[4];
SDL_Rect barrier_rect;
#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */
} SDL_WindowData;
extern void X11_SetNetWMState(_THIS, Window xwindow, Uint32 flags);
@@ -102,6 +107,7 @@ extern void X11_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizabl
extern void X11_SetWindowAlwaysOnTop(_THIS, SDL_Window * window, SDL_bool on_top);
extern void X11_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
extern int X11_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp);
extern void* X11_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size);
extern void X11_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
extern void X11_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
extern void X11_DestroyWindow(_THIS, SDL_Window * window);
@@ -111,6 +117,8 @@ extern int X11_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
extern void X11_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept);
extern int X11_FlashWindow(_THIS, SDL_Window * window, SDL_FlashOperation operation);
int SDL_X11_SetWindowTitle(Display* display, Window xwindow, char* string);
#endif /* SDL_x11window_h_ */
/* vi: set ts=4 sw=4 expandtab: */

206
externals/SDL/src/video/x11/SDL_x11xfixes.c vendored Executable file
View File

@@ -0,0 +1,206 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2017 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_X11 && SDL_VIDEO_DRIVER_X11_XFIXES
#include "SDL_x11video.h"
#include "SDL_x11xfixes.h"
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_touch_c.h"
static int xfixes_initialized = 0;
static int
query_xfixes_version(Display *display, int major, int minor)
{
/* We don't care if this fails, so long as it sets major/minor on it's way out the door. */
X11_XFixesQueryVersion(display, &major, &minor);
return ((major * 1000) + minor);
}
static SDL_bool
xfixes_version_atleast(const int version, const int wantmajor, const int wantminor)
{
return (version >= ((wantmajor * 1000) + wantminor));
}
void
X11_InitXfixes(_THIS)
{
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
int version = 0;
int event, error;
int fixes_opcode;
if (!SDL_X11_HAVE_XFIXES ||
!X11_XQueryExtension(data->display, "XFIXES", &fixes_opcode, &event, &error)) {
return;
}
/* We need at least 5.0 for barriers. */
version = query_xfixes_version(data->display, 5, 0);
if (!xfixes_version_atleast(version, 5, 0)) {
return; /* X server does not support the version we want at all. */
}
xfixes_initialized = 1;
}
int
X11_XfixesIsInitialized()
{
return xfixes_initialized;
}
void
X11_SetWindowMouseRect(_THIS, SDL_Window * window)
{
if (SDL_RectEmpty(&window->mouse_rect)) {
X11_ConfineCursorWithFlags(_this, window, NULL, 0);
} else {
if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
X11_ConfineCursorWithFlags(_this, window, &window->mouse_rect, 0);
} else {
/* Save the state for when we get focus again */
SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
SDL_memcpy(&wdata->barrier_rect, &window->mouse_rect, sizeof(wdata->barrier_rect));
wdata->pointer_barrier_active = SDL_TRUE;
}
}
}
int
X11_ConfineCursorWithFlags(_THIS, SDL_Window * window, const SDL_Rect * rect, int flags)
{
/* Yaakuro: For some reason Xfixes when confining inside a rect where the
* edges exactly match, a rectangle the cursor 'slips' out of the barrier.
* To prevent that the lines for the barriers will span the whole screen.
*/
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
SDL_WindowData *wdata;
if (!X11_XfixesIsInitialized()) {
return SDL_Unsupported();
}
/* If there is already a set of barriers active, disable them. */
if (data->active_cursor_confined_window) {
X11_DestroyPointerBarrier(_this, data->active_cursor_confined_window);
}
SDL_assert(window != NULL);
wdata = (SDL_WindowData *) window->driverdata;
/* If user did not specify an area to confine, destroy the barrier that was/is assigned to
* this window it was assigned */
if (rect) {
int x1, y1, x2, y2;
SDL_Rect bounds;
SDL_GetWindowPosition(window, &bounds.x, &bounds.y);
SDL_GetWindowSize(window, &bounds.w, &bounds.h);
/** Negative values are not allowed. Clip values relative to the specified window. */
x1 = bounds.x + SDL_max(rect->x, 0);
y1 = bounds.y + SDL_max(rect->y, 0);
x2 = SDL_min(bounds.x + rect->x + rect->w, bounds.x + bounds.w);
y2 = SDL_min(bounds.y + rect->y + rect->h, bounds.y + bounds.h);
if ((wdata->barrier_rect.x != rect->x) ||
(wdata->barrier_rect.y != rect->y) ||
(wdata->barrier_rect.w != rect->w) ||
(wdata->barrier_rect.h != rect->h)) {
wdata->barrier_rect = *rect;
}
/* Use the display bounds to ensure the barriers don't have corner gaps */
SDL_GetDisplayBounds(SDL_GetWindowDisplayIndex(window), &bounds);
/** Create the left barrier */
wdata->barrier[0] = X11_XFixesCreatePointerBarrier(data->display, wdata->xwindow,
x1, bounds.y,
x1, bounds.y + bounds.h,
BarrierPositiveX,
0, NULL);
/** Create the right barrier */
wdata->barrier[1] = X11_XFixesCreatePointerBarrier(data->display, wdata->xwindow,
x2, bounds.y,
x2, bounds.y + bounds.h,
BarrierNegativeX,
0, NULL);
/** Create the top barrier */
wdata->barrier[2] = X11_XFixesCreatePointerBarrier(data->display, wdata->xwindow,
bounds.x, y1,
bounds.x + bounds.w, y1,
BarrierPositiveY,
0, NULL);
/** Create the bottom barrier */
wdata->barrier[3] = X11_XFixesCreatePointerBarrier(data->display, wdata->xwindow,
bounds.x, y2,
bounds.x + bounds.w, y2,
BarrierNegativeY,
0, NULL);
X11_XFlush(data->display);
/* Lets remember current active confined window. */
data->active_cursor_confined_window = window;
/* User activated the confinement for this window. We use this later to reactivate
* the confinement if it got deactivated by FocusOut or UnmapNotify */
wdata->pointer_barrier_active = SDL_TRUE;
} else {
X11_DestroyPointerBarrier(_this, window);
/* Only set barrier inactive when user specified NULL and not handled by focus out. */
if (flags != X11_BARRIER_HANDLED_BY_EVENT) {
wdata->pointer_barrier_active = SDL_FALSE;
}
}
return 0;
}
void
X11_DestroyPointerBarrier(_THIS, SDL_Window * window)
{
int i;
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
if (window) {
SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
for (i = 0; i < 4; i++) {
if (wdata->barrier[i] > 0) {
X11_XFixesDestroyPointerBarrier(data->display, wdata->barrier[i]);
wdata->barrier[i] = 0;
}
}
X11_XFlush(data->display);
}
data->active_cursor_confined_window = NULL;
}
#endif /* SDL_VIDEO_DRIVER_X11 && SDL_VIDEO_DRIVER_X11_XFIXES */
/* vi: set ts=4 sw=4 expandtab: */

41
externals/SDL/src/video/x11/SDL_x11xfixes.h vendored Executable file
View File

@@ -0,0 +1,41 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2017 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_x11xfixes_h_
#define SDL_x11xfixes_h_
#if SDL_VIDEO_DRIVER_X11_XFIXES
#define X11_BARRIER_HANDLED_BY_EVENT 1
extern void X11_InitXfixes(_THIS);
extern int X11_XfixesIsInitialized(void);
extern void X11_SetWindowMouseRect(_THIS, SDL_Window * window);
extern int X11_ConfineCursorWithFlags(_THIS, SDL_Window * window, const SDL_Rect * rect, int flags);
extern void X11_DestroyPointerBarrier(_THIS, SDL_Window * window);
#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */
#endif /* SDL_x11xfixes_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -50,7 +50,7 @@ get_bits (int in, int begin, int end)
static int
decode_header (const uchar *edid)
{
if (memcmp (edid, "\x00\xff\xff\xff\xff\xff\xff\x00", 8) == 0)
if (SDL_memcmp (edid, "\x00\xff\xff\xff\xff\xff\xff\x00", 8) == 0)
return TRUE;
return FALSE;
}
@@ -76,7 +76,7 @@ decode_vendor_and_product_identification (const uchar *edid, MonitorInfo *info)
/* Serial Number */
info->serial_number =
edid[0x0c] | edid[0x0d] << 8 | edid[0x0e] << 16 | edid[0x0f] << 24;
edid[0x0c] | edid[0x0d] << 8 | edid[0x0e] << 16 | (Uint32)edid[0x0f] << 24;
/* Week and Year */
is_model_year = FALSE;
@@ -522,7 +522,7 @@ decode_check_sum (const uchar *edid,
MonitorInfo *
decode_edid (const uchar *edid)
{
MonitorInfo *info = calloc (1, sizeof (MonitorInfo));
MonitorInfo *info = SDL_calloc (1, sizeof (MonitorInfo));
decode_check_sum (edid, info);
@@ -534,8 +534,8 @@ decode_edid (const uchar *edid)
!decode_established_timings (edid, info) ||
!decode_standard_timings (edid, info) ||
!decode_descriptors (edid, info)) {
free(info);
return NULL;
SDL_free(info);
return NULL;
}
return info;