Lots of prep for the "real" way to support fullscreen mode on modern window managers.
Unfortunately, this doesn't work. I also noticed that maximizing doesn't work as well. Also xprop hangs when trying to list properties of SDL windows.... ???
This commit is contained in:
parent
51b5767091
commit
983b11625f
7 changed files with 242 additions and 70 deletions
|
@ -34,18 +34,19 @@
|
||||||
#include "SDL_timer.h"
|
#include "SDL_timer.h"
|
||||||
#include "SDL_syswm.h"
|
#include "SDL_syswm.h"
|
||||||
|
|
||||||
/*#define DEBUG_XEVENTS*/
|
#define DEBUG_XEVENTS
|
||||||
|
|
||||||
static void
|
static void
|
||||||
X11_DispatchEvent(_THIS)
|
X11_DispatchEvent(_THIS)
|
||||||
{
|
{
|
||||||
SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
|
SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
|
||||||
|
Display *display = videodata->display;
|
||||||
SDL_WindowData *data;
|
SDL_WindowData *data;
|
||||||
XEvent xevent;
|
XEvent xevent;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
SDL_zero(xevent); /* valgrind fix. --ryan. */
|
SDL_zero(xevent); /* valgrind fix. --ryan. */
|
||||||
XNextEvent(videodata->display, &xevent);
|
XNextEvent(display, &xevent);
|
||||||
|
|
||||||
/* filter events catchs XIM events and sends them to the correct
|
/* filter events catchs XIM events and sends them to the correct
|
||||||
handler */
|
handler */
|
||||||
|
@ -80,6 +81,7 @@ X11_DispatchEvent(_THIS)
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
printf("type = %d display = %d window = %d\n",
|
printf("type = %d display = %d window = %d\n",
|
||||||
xevent.type, xevent.xany.display, xevent.xany.window);
|
xevent.type, xevent.xany.display, xevent.xany.window);
|
||||||
|
@ -182,9 +184,8 @@ X11_DispatchEvent(_THIS)
|
||||||
#if 0
|
#if 0
|
||||||
if (videodata->key_layout[keycode] == SDLK_UNKNOWN) {
|
if (videodata->key_layout[keycode] == SDLK_UNKNOWN) {
|
||||||
int min_keycode, max_keycode;
|
int min_keycode, max_keycode;
|
||||||
XDisplayKeycodes(videodata->display, &min_keycode,
|
XDisplayKeycodes(display, &min_keycode, &max_keycode);
|
||||||
&max_keycode);
|
keysym = XKeycodeToKeysym(display, keycode, 0);
|
||||||
keysym = XKeycodeToKeysym(videodata->display, keycode, 0);
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"The key you just pressed is not recognized by SDL. To help get this fixed, please report this to the SDL mailing list <sdl@libsdl.org> X11 KeyCode %d (%d), X11 KeySym 0x%X (%s).\n",
|
"The key you just pressed is not recognized by SDL. To help get this fixed, please report this to the SDL mailing list <sdl@libsdl.org> X11 KeyCode %d (%d), X11 KeySym 0x%X (%s).\n",
|
||||||
keycode, keycode - min_keycode, keysym,
|
keycode, keycode - min_keycode, keysym,
|
||||||
|
@ -289,9 +290,58 @@ X11_DispatchEvent(_THIS)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PropertyNotify:{
|
||||||
|
#ifdef DEBUG_XEVENTS
|
||||||
|
char *name = XGetAtomName(display, xevent.xproperty.atom);
|
||||||
|
printf("PropertyNotify (atom = %s)\n", name ? name : "NULL");
|
||||||
|
if (name) {
|
||||||
|
XFree(name);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (xevent.xproperty.atom == videodata->_NET_WM_STATE) {
|
||||||
|
unsigned char *propdata;
|
||||||
|
int status, real_format;
|
||||||
|
Atom real_type;
|
||||||
|
unsigned long items_read, items_left, i;
|
||||||
|
|
||||||
|
#ifdef DEBUG_XEVENTS
|
||||||
|
printf("_NET_WM_STATE: {");
|
||||||
|
#endif
|
||||||
|
status = XGetWindowProperty(display, data->xwindow, videodata->_NET_WM_STATE, 0L, 8192L, False, XA_ATOM, &real_type, &real_format, &items_read, &items_left, &propdata);
|
||||||
|
if (status == Success) {
|
||||||
|
Atom *atoms = (Atom *)propdata;
|
||||||
|
for (i = 0; i < items_read; i++) {
|
||||||
|
if (atoms[i] == videodata->_NET_WM_STATE_HIDDEN) {
|
||||||
|
#ifdef DEBUG_XEVENTS
|
||||||
|
printf(" _NET_WM_STATE_HIDDEN");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (atoms[i] == videodata->_NET_WM_STATE_MAXIMIZED_HORZ) {
|
||||||
|
#ifdef DEBUG_XEVENTS
|
||||||
|
printf(" _NET_WM_STATE_MAXIMIZED_HORZ");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (atoms[i] == videodata->_NET_WM_STATE_MAXIMIZED_VERT) {
|
||||||
|
#ifdef DEBUG_XEVENTS
|
||||||
|
printf(" _NET_WM_STATE_MAXIMIZED_VERT");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (atoms[i] == videodata->_NET_WM_STATE_FULLSCREEN) {
|
||||||
|
#ifdef DEBUG_XEVENTS
|
||||||
|
printf(" _NET_WM_STATE_FULLSCREEN");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef DEBUG_XEVENTS
|
||||||
|
printf(" }\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
/* Copy the selection from XA_CUT_BUFFER0 to the requested property */
|
/* Copy the selection from XA_CUT_BUFFER0 to the requested property */
|
||||||
case SelectionRequest: {
|
case SelectionRequest: {
|
||||||
Display *display = videodata->display;
|
|
||||||
XSelectionRequestEvent *req;
|
XSelectionRequestEvent *req;
|
||||||
XEvent sevent;
|
XEvent sevent;
|
||||||
int seln_format;
|
int seln_format;
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
#include "SDL_x11video.h"
|
#include "SDL_x11video.h"
|
||||||
|
|
||||||
//#define X11MODES_DEBUG
|
#define X11MODES_DEBUG
|
||||||
#undef SDL_VIDEO_DRIVER_X11_XINERAMA
|
#undef SDL_VIDEO_DRIVER_X11_XINERAMA
|
||||||
#undef SDL_VIDEO_DRIVER_X11_XRANDR
|
#undef SDL_VIDEO_DRIVER_X11_XRANDR
|
||||||
#undef SDL_VIDEO_DRIVER_X11_VIDMODE
|
#undef SDL_VIDEO_DRIVER_X11_VIDMODE
|
||||||
|
@ -253,6 +253,7 @@ CheckVidMode(Display * display, int *major, int *minor)
|
||||||
return SDL_TRUE;
|
return SDL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
Bool SDL_NAME(XF86VidModeGetModeInfo) (Display * dpy, int scr,
|
Bool SDL_NAME(XF86VidModeGetModeInfo) (Display * dpy, int scr,
|
||||||
SDL_NAME(XF86VidModeModeInfo) * info)
|
SDL_NAME(XF86VidModeModeInfo) * info)
|
||||||
{
|
{
|
||||||
|
@ -296,6 +297,7 @@ save_mode(Display * display, SDL_DisplayData * data)
|
||||||
&data->saved_view.y);
|
&data->saved_view.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
static void
|
static void
|
||||||
restore_mode(Display * display, SDL_DisplayData * data)
|
restore_mode(Display * display, SDL_DisplayData * data)
|
||||||
{
|
{
|
||||||
|
@ -313,6 +315,7 @@ restore_mode(Display * display, SDL_DisplayData * data)
|
||||||
data->saved_view.y);
|
data->saved_view.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
#endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
|
#endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -67,12 +67,14 @@ SDL_X11_SYM(int,XFreeCursor,(Display* a,Cursor b),(a,b),return)
|
||||||
SDL_X11_SYM(int,XFreeGC,(Display* a,GC b),(a,b),return)
|
SDL_X11_SYM(int,XFreeGC,(Display* a,GC b),(a,b),return)
|
||||||
SDL_X11_SYM(int,XFreeModifiermap,(XModifierKeymap* a),(a),return)
|
SDL_X11_SYM(int,XFreeModifiermap,(XModifierKeymap* a),(a),return)
|
||||||
SDL_X11_SYM(int,XFreePixmap,(Display* a,Pixmap b),(a,b),return)
|
SDL_X11_SYM(int,XFreePixmap,(Display* a,Pixmap b),(a,b),return)
|
||||||
|
SDL_X11_SYM(char*,XGetAtomName,(Display *a,Atom b),(a,b),return)
|
||||||
SDL_X11_SYM(int,XGetErrorDatabaseText,(Display* a,_Xconst char* b,_Xconst char* c,_Xconst char* d,char* e,int f),(a,b,c,d,e,f),return)
|
SDL_X11_SYM(int,XGetErrorDatabaseText,(Display* a,_Xconst char* b,_Xconst char* c,_Xconst char* d,char* e,int f),(a,b,c,d,e,f),return)
|
||||||
SDL_X11_SYM(XImage*,XGetImage,(Display* a,Drawable b,int c,int d,unsigned int e,unsigned int f,unsigned long g, int h),(a,b,c,d,e,f,g,h),return)
|
SDL_X11_SYM(XImage*,XGetImage,(Display* a,Drawable b,int c,int d,unsigned int e,unsigned int f,unsigned long g, int h),(a,b,c,d,e,f,g,h),return)
|
||||||
SDL_X11_SYM(XModifierKeymap*,XGetModifierMapping,(Display* a),(a),return)
|
SDL_X11_SYM(XModifierKeymap*,XGetModifierMapping,(Display* a),(a),return)
|
||||||
SDL_X11_SYM(int,XGetPointerControl,(Display* a,int* b,int* c,int* d),(a,b,c,d),return)
|
SDL_X11_SYM(int,XGetPointerControl,(Display* a,int* b,int* c,int* d),(a,b,c,d),return)
|
||||||
SDL_X11_SYM(int,XGetRGBColormaps,(Display* a,Window b,XStandardColormap **c,int *d,Atom e),(a,b,c,d,e),return)
|
SDL_X11_SYM(int,XGetRGBColormaps,(Display* a,Window b,XStandardColormap **c,int *d,Atom e),(a,b,c,d,e),return)
|
||||||
SDL_X11_SYM(Window,XGetSelectionOwner,(Display* a,Atom b),(a,b),return)
|
SDL_X11_SYM(Window,XGetSelectionOwner,(Display* a,Atom b),(a,b),return)
|
||||||
|
SDL_X11_SYM(Status,XGetTextProperty,(Display *a,Window b,XTextProperty *c,Atom d),(a,b,c,d),return)
|
||||||
SDL_X11_SYM(XVisualInfo*,XGetVisualInfo,(Display* a,long b,XVisualInfo* c,int* d),(a,b,c,d),return)
|
SDL_X11_SYM(XVisualInfo*,XGetVisualInfo,(Display* a,long b,XVisualInfo* c,int* d),(a,b,c,d),return)
|
||||||
SDL_X11_SYM(Status,XGetWindowAttributes,(Display* a,Window b,XWindowAttributes* c),(a,b,c),return)
|
SDL_X11_SYM(Status,XGetWindowAttributes,(Display* a,Window b,XWindowAttributes* c),(a,b,c),return)
|
||||||
SDL_X11_SYM(int,XGetWindowProperty,(Display* a,Window b,Atom c,long d,long e,Bool f,Atom g,Atom* h,int* i,unsigned long* j,unsigned long *k,unsigned char **l),(a,b,c,d,e,f,g,h,i,j,k,l),return)
|
SDL_X11_SYM(int,XGetWindowProperty,(Display* a,Window b,Atom c,long d,long e,Bool f,Atom g,Atom* h,int* i,unsigned long* j,unsigned long *k,unsigned char **l),(a,b,c,d,e,f,g,h,i,j,k,l),return)
|
||||||
|
|
|
@ -242,6 +242,43 @@ VideoBootStrap X11_bootstrap = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
X11_CheckWindowManager(_THIS)
|
||||||
|
{
|
||||||
|
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
|
||||||
|
Display *display = data->display;
|
||||||
|
Atom _NET_SUPPORTING_WM_CHECK;
|
||||||
|
int status, real_format;
|
||||||
|
Atom real_type;
|
||||||
|
unsigned long items_read, items_left;
|
||||||
|
unsigned char *propdata;
|
||||||
|
Window wm_window = 0;
|
||||||
|
#ifdef DEBUG_WINDOW_MANAGER
|
||||||
|
char *wm_name;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_NET_SUPPORTING_WM_CHECK = XInternAtom(display, "_NET_SUPPORTING_WM_CHECK", False);
|
||||||
|
status = XGetWindowProperty(display, DefaultRootWindow(display), _NET_SUPPORTING_WM_CHECK, 0L, 1L, False, XA_WINDOW, &real_type, &real_format, &items_read, &items_left, &propdata);
|
||||||
|
if (status == Success && items_read) {
|
||||||
|
wm_window = ((Window*)propdata)[0];
|
||||||
|
}
|
||||||
|
XFree(propdata);
|
||||||
|
|
||||||
|
if (!wm_window) {
|
||||||
|
#ifdef DEBUG_WINDOW_MANAGER
|
||||||
|
printf("Couldn't get _NET_SUPPORTING_WM_CHECK property\n");
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
data->net_wm = SDL_TRUE;
|
||||||
|
|
||||||
|
#ifdef DEBUG_WINDOW_MANAGER
|
||||||
|
wm_name = X11_GetWindowTitle(_this, wm_window);
|
||||||
|
printf("Window manager: %s\n", wm_name);
|
||||||
|
SDL_free(wm_name);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
X11_VideoInit(_THIS)
|
X11_VideoInit(_THIS)
|
||||||
{
|
{
|
||||||
|
@ -259,8 +296,20 @@ X11_VideoInit(_THIS)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Look up some useful Atoms */
|
/* Look up some useful Atoms */
|
||||||
data->WM_DELETE_WINDOW =
|
#define GET_ATOM(X) data->X = XInternAtom(data->display, #X, False)
|
||||||
XInternAtom(data->display, "WM_DELETE_WINDOW", False);
|
GET_ATOM(WM_DELETE_WINDOW);
|
||||||
|
GET_ATOM(_NET_WM_STATE);
|
||||||
|
GET_ATOM(_NET_WM_STATE_HIDDEN);
|
||||||
|
GET_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
|
||||||
|
GET_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
|
||||||
|
GET_ATOM(_NET_WM_STATE_FULLSCREEN);
|
||||||
|
GET_ATOM(_NET_WM_NAME);
|
||||||
|
GET_ATOM(_NET_WM_ICON_NAME);
|
||||||
|
GET_ATOM(_NET_WM_ICON);
|
||||||
|
GET_ATOM(UTF8_STRING);
|
||||||
|
|
||||||
|
/* Detect the window manager */
|
||||||
|
X11_CheckWindowManager(_this);
|
||||||
|
|
||||||
if (X11_InitModes(_this) < 0) {
|
if (X11_InitModes(_this) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -68,7 +68,22 @@ typedef struct SDL_VideoData
|
||||||
int numwindows;
|
int numwindows;
|
||||||
SDL_WindowData **windowlist;
|
SDL_WindowData **windowlist;
|
||||||
int windowlistlength;
|
int windowlistlength;
|
||||||
|
|
||||||
|
/* This is true for ICCCM2.0-compliant window managers */
|
||||||
|
SDL_bool net_wm;
|
||||||
|
|
||||||
|
/* Useful atoms */
|
||||||
Atom WM_DELETE_WINDOW;
|
Atom WM_DELETE_WINDOW;
|
||||||
|
Atom _NET_WM_STATE;
|
||||||
|
Atom _NET_WM_STATE_HIDDEN;
|
||||||
|
Atom _NET_WM_STATE_MAXIMIZED_VERT;
|
||||||
|
Atom _NET_WM_STATE_MAXIMIZED_HORZ;
|
||||||
|
Atom _NET_WM_STATE_FULLSCREEN;
|
||||||
|
Atom _NET_WM_NAME;
|
||||||
|
Atom _NET_WM_ICON_NAME;
|
||||||
|
Atom _NET_WM_ICON;
|
||||||
|
Atom UTF8_STRING;
|
||||||
|
|
||||||
SDL_scancode key_layout[256];
|
SDL_scancode key_layout[256];
|
||||||
SDL_bool selection_waiting;
|
SDL_bool selection_waiting;
|
||||||
} SDL_VideoData;
|
} SDL_VideoData;
|
||||||
|
|
|
@ -42,6 +42,20 @@
|
||||||
#define _NET_WM_STATE_ADD 1l
|
#define _NET_WM_STATE_ADD 1l
|
||||||
#define _NET_WM_STATE_TOGGLE 2l
|
#define _NET_WM_STATE_TOGGLE 2l
|
||||||
|
|
||||||
|
static SDL_bool
|
||||||
|
X11_WindowIsOldstyleFullscreen(SDL_Window * window)
|
||||||
|
{
|
||||||
|
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||||
|
SDL_VideoData *videodata = (SDL_VideoData *) data->videodata;
|
||||||
|
|
||||||
|
/* ICCCM2.0-compliant window managers can handle fullscreen windows */
|
||||||
|
if ((window->flags & SDL_WINDOW_FULLSCREEN) && !videodata->net_wm) {
|
||||||
|
return SDL_TRUE;
|
||||||
|
} else {
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
X11_GetDisplaySize(_THIS, SDL_Window * window, int *w, int *h)
|
X11_GetDisplaySize(_THIS, SDL_Window * window, int *w, int *h)
|
||||||
{
|
{
|
||||||
|
@ -128,14 +142,10 @@ SetupWindowData(_THIS, SDL_Window * window, Window w, BOOL created)
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
Atom _NET_WM_STATE =
|
Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE;
|
||||||
XInternAtom(data->videodata->display, "_NET_WM_STATE", False);
|
Atom _NET_WM_STATE_MAXIMIZED_VERT = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT;
|
||||||
Atom _NET_WM_STATE_MAXIMIZED_VERT =
|
Atom _NET_WM_STATE_MAXIMIZED_HORZ = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
|
||||||
XInternAtom(data->videodata->display,
|
Atom _NET_WM_STATE_FULLSCREEN = data->videodata->_NET_WM_STATE_FULLSCREEN;
|
||||||
"_NET_WM_STATE_MAXIMIZED_VERT", False);
|
|
||||||
Atom _NET_WM_STATE_MAXIMIZED_HORZ =
|
|
||||||
XInternAtom(data->videodata->display,
|
|
||||||
"_NET_WM_STATE_MAXIMIZED_HORZ", False);
|
|
||||||
Atom actualType;
|
Atom actualType;
|
||||||
int actualFormat;
|
int actualFormat;
|
||||||
unsigned long i, numItems, bytesAfter;
|
unsigned long i, numItems, bytesAfter;
|
||||||
|
@ -148,19 +158,21 @@ SetupWindowData(_THIS, SDL_Window * window, Window w, BOOL created)
|
||||||
&propertyValue) == Success) {
|
&propertyValue) == Success) {
|
||||||
Atom *atoms = (Atom *) propertyValue;
|
Atom *atoms = (Atom *) propertyValue;
|
||||||
int maximized = 0;
|
int maximized = 0;
|
||||||
|
int fullscreen = 0;
|
||||||
|
|
||||||
for (i = 0; i < numItems; ++i) {
|
for (i = 0; i < numItems; ++i) {
|
||||||
if (atoms[i] == _NET_WM_STATE_MAXIMIZED_VERT) {
|
if (atoms[i] == _NET_WM_STATE_MAXIMIZED_VERT) {
|
||||||
maximized |= 1;
|
maximized |= 1;
|
||||||
} else if (atoms[i] == _NET_WM_STATE_MAXIMIZED_HORZ) {
|
} else if (atoms[i] == _NET_WM_STATE_MAXIMIZED_HORZ) {
|
||||||
maximized |= 2;
|
maximized |= 2;
|
||||||
|
} else if ( atoms[i] == _NET_WM_STATE_FULLSCREEN) {
|
||||||
|
fullscreen = 1;
|
||||||
}
|
}
|
||||||
/* Might also want to check the following properties:
|
|
||||||
_NET_WM_STATE_ABOVE, _NET_WM_STATE_FULLSCREEN
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
if (maximized == 3) {
|
if (maximized == 3) {
|
||||||
window->flags |= SDL_WINDOW_MAXIMIZED;
|
window->flags |= SDL_WINDOW_MAXIMIZED;
|
||||||
|
} else if (fullscreen == 1) {
|
||||||
|
window->flags |= SDL_WINDOW_FULLSCREEN;
|
||||||
}
|
}
|
||||||
XFree(propertyValue);
|
XFree(propertyValue);
|
||||||
}
|
}
|
||||||
|
@ -180,11 +192,6 @@ SetupWindowData(_THIS, SDL_Window * window, Window w, BOOL created)
|
||||||
} else {
|
} else {
|
||||||
window->flags &= ~SDL_WINDOW_RESIZABLE;
|
window->flags &= ~SDL_WINDOW_RESIZABLE;
|
||||||
}
|
}
|
||||||
if (style & WS_MAXIMIZE) {
|
|
||||||
window->flags |= SDL_WINDOW_MAXIMIZED;
|
|
||||||
} else {
|
|
||||||
window->flags &= ~SDL_WINDOW_MAXIMIZED;
|
|
||||||
}
|
|
||||||
if (style & WS_MINIMIZE) {
|
if (style & WS_MINIMIZE) {
|
||||||
window->flags |= SDL_WINDOW_MINIMIZED;
|
window->flags |= SDL_WINDOW_MINIMIZED;
|
||||||
} else {
|
} else {
|
||||||
|
@ -225,6 +232,14 @@ X11_CreateWindow(_THIS, SDL_Window * window)
|
||||||
XSizeHints *sizehints;
|
XSizeHints *sizehints;
|
||||||
XWMHints *wmhints;
|
XWMHints *wmhints;
|
||||||
XClassHint *classhints;
|
XClassHint *classhints;
|
||||||
|
SDL_bool oldstyle_fullscreen;
|
||||||
|
|
||||||
|
/* ICCCM2.0-compliant window managers can handle fullscreen windows */
|
||||||
|
if ((window->flags & SDL_WINDOW_FULLSCREEN) && !data->net_wm) {
|
||||||
|
oldstyle_fullscreen = SDL_TRUE;
|
||||||
|
} else {
|
||||||
|
oldstyle_fullscreen = SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
#if SDL_VIDEO_DRIVER_X11_XINERAMA
|
#if SDL_VIDEO_DRIVER_X11_XINERAMA
|
||||||
/* FIXME
|
/* FIXME
|
||||||
|
@ -265,7 +280,7 @@ X11_CreateWindow(_THIS, SDL_Window * window)
|
||||||
depth = displaydata->depth;
|
depth = displaydata->depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window->flags & SDL_WINDOW_FULLSCREEN) {
|
if (oldstyle_fullscreen) {
|
||||||
xattr.override_redirect = True;
|
xattr.override_redirect = True;
|
||||||
} else {
|
} else {
|
||||||
xattr.override_redirect = False;
|
xattr.override_redirect = False;
|
||||||
|
@ -417,7 +432,6 @@ X11_CreateWindow(_THIS, SDL_Window * window)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OK, we got a colormap, now fill it in as best as we can */
|
/* OK, we got a colormap, now fill it in as best as we can */
|
||||||
|
|
||||||
colorcells = SDL_malloc(visual->map_entries * sizeof(XColor));
|
colorcells = SDL_malloc(visual->map_entries * sizeof(XColor));
|
||||||
if (NULL == colorcells) {
|
if (NULL == colorcells) {
|
||||||
SDL_SetError("out of memory in X11_CreateWindow");
|
SDL_SetError("out of memory in X11_CreateWindow");
|
||||||
|
@ -494,7 +508,7 @@ X11_CreateWindow(_THIS, SDL_Window * window)
|
||||||
visual, AllocNone);
|
visual, AllocNone);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((window->flags & SDL_WINDOW_FULLSCREEN)
|
if (oldstyle_fullscreen
|
||||||
|| window->x == SDL_WINDOWPOS_CENTERED) {
|
|| window->x == SDL_WINDOWPOS_CENTERED) {
|
||||||
X11_GetDisplaySize(_this, window, &x, NULL);
|
X11_GetDisplaySize(_this, window, &x, NULL);
|
||||||
x = (x - window->w) / 2;
|
x = (x - window->w) / 2;
|
||||||
|
@ -503,7 +517,7 @@ X11_CreateWindow(_THIS, SDL_Window * window)
|
||||||
} else {
|
} else {
|
||||||
x = window->x;
|
x = window->x;
|
||||||
}
|
}
|
||||||
if ((window->flags & SDL_WINDOW_FULLSCREEN)
|
if (oldstyle_fullscreen
|
||||||
|| window->y == SDL_WINDOWPOS_CENTERED) {
|
|| window->y == SDL_WINDOWPOS_CENTERED) {
|
||||||
X11_GetDisplaySize(_this, window, NULL, &y);
|
X11_GetDisplaySize(_this, window, NULL, &y);
|
||||||
y = (y - window->h) / 2;
|
y = (y - window->h) / 2;
|
||||||
|
@ -539,12 +553,12 @@ X11_CreateWindow(_THIS, SDL_Window * window)
|
||||||
sizehints = XAllocSizeHints();
|
sizehints = XAllocSizeHints();
|
||||||
if (sizehints) {
|
if (sizehints) {
|
||||||
if (!(window->flags & SDL_WINDOW_RESIZABLE)
|
if (!(window->flags & SDL_WINDOW_RESIZABLE)
|
||||||
|| (window->flags & SDL_WINDOW_FULLSCREEN)) {
|
|| oldstyle_fullscreen) {
|
||||||
sizehints->min_width = sizehints->max_width = window->w;
|
sizehints->min_width = sizehints->max_width = window->w;
|
||||||
sizehints->min_height = sizehints->max_height = window->h;
|
sizehints->min_height = sizehints->max_height = window->h;
|
||||||
sizehints->flags = PMaxSize | PMinSize;
|
sizehints->flags = PMaxSize | PMinSize;
|
||||||
}
|
}
|
||||||
if (!(window->flags & SDL_WINDOW_FULLSCREEN)
|
if (!oldstyle_fullscreen
|
||||||
&& window->x != SDL_WINDOWPOS_UNDEFINED
|
&& window->x != SDL_WINDOWPOS_UNDEFINED
|
||||||
&& window->y != SDL_WINDOWPOS_UNDEFINED) {
|
&& window->y != SDL_WINDOWPOS_UNDEFINED) {
|
||||||
sizehints->x = x;
|
sizehints->x = x;
|
||||||
|
@ -555,7 +569,7 @@ X11_CreateWindow(_THIS, SDL_Window * window)
|
||||||
XFree(sizehints);
|
XFree(sizehints);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window->flags & (SDL_WINDOW_BORDERLESS | SDL_WINDOW_FULLSCREEN)) {
|
if ((window->flags & SDL_WINDOW_BORDERLESS) || oldstyle_fullscreen) {
|
||||||
SDL_bool set;
|
SDL_bool set;
|
||||||
Atom WM_HINTS;
|
Atom WM_HINTS;
|
||||||
|
|
||||||
|
@ -643,23 +657,6 @@ X11_CreateWindow(_THIS, SDL_Window * window)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tell KDE to keep fullscreen windows on top */
|
|
||||||
if (window->flags & SDL_WINDOW_FULLSCREEN) {
|
|
||||||
XEvent ev;
|
|
||||||
|
|
||||||
SDL_zero(ev);
|
|
||||||
ev.xclient.type = ClientMessage;
|
|
||||||
ev.xclient.window = RootWindow(data->display, displaydata->screen);
|
|
||||||
ev.xclient.message_type =
|
|
||||||
XInternAtom(data->display, "KWM_KEEP_ON_TOP", False);
|
|
||||||
ev.xclient.format = 32;
|
|
||||||
ev.xclient.data.l[0] = w;
|
|
||||||
ev.xclient.data.l[1] = CurrentTime;
|
|
||||||
XSendEvent(data->display,
|
|
||||||
RootWindow(data->display, displaydata->screen), False,
|
|
||||||
SubstructureRedirectMask, &ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the input hints so we get keyboard input */
|
/* Set the input hints so we get keyboard input */
|
||||||
wmhints = XAllocWMHints();
|
wmhints = XAllocWMHints();
|
||||||
if (wmhints) {
|
if (wmhints) {
|
||||||
|
@ -678,6 +675,26 @@ X11_CreateWindow(_THIS, SDL_Window * window)
|
||||||
XFree(classhints);
|
XFree(classhints);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: Why doesn't this work? */
|
||||||
|
if (window->flags & SDL_WINDOW_FULLSCREEN) {
|
||||||
|
Atom _NET_WM_STATE = data->_NET_WM_STATE;
|
||||||
|
Atom _NET_WM_STATE_FULLSCREEN = data->_NET_WM_STATE_FULLSCREEN;
|
||||||
|
XEvent e;
|
||||||
|
|
||||||
|
e.xany.type = ClientMessage;
|
||||||
|
e.xclient.display = data->display;
|
||||||
|
e.xclient.window = w;
|
||||||
|
e.xclient.message_type = _NET_WM_STATE;
|
||||||
|
e.xclient.format = 32;
|
||||||
|
e.xclient.data.l[0] = _NET_WM_STATE_ADD;
|
||||||
|
e.xclient.data.l[1] = _NET_WM_STATE_FULLSCREEN;
|
||||||
|
e.xclient.data.l[2] = 0l;
|
||||||
|
|
||||||
|
XSendEvent(data->display,
|
||||||
|
RootWindow(data->display, displaydata->screen), 0,
|
||||||
|
SubstructureNotifyMask | SubstructureRedirectMask, &e);
|
||||||
|
}
|
||||||
|
|
||||||
/* Allow the window to be deleted by the window manager */
|
/* Allow the window to be deleted by the window manager */
|
||||||
XSetWMProtocols(data->display, w, &data->WM_DELETE_WINDOW, 1);
|
XSetWMProtocols(data->display, w, &data->WM_DELETE_WINDOW, 1);
|
||||||
|
|
||||||
|
@ -716,7 +733,7 @@ X11_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
|
||||||
{
|
{
|
||||||
Window w = (Window) data;
|
Window w = (Window) data;
|
||||||
|
|
||||||
/* FIXME: Query the title from the existing window */
|
window->title = X11_GetWindowTitle(_this, w);
|
||||||
|
|
||||||
if (SetupWindowData(_this, window, w, SDL_FALSE) < 0) {
|
if (SetupWindowData(_this, window, w, SDL_FALSE) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -724,6 +741,36 @@ X11_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
X11_GetWindowTitle(_THIS, Window xwindow)
|
||||||
|
{
|
||||||
|
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
|
||||||
|
Display *display = data->display;
|
||||||
|
int status, real_format;
|
||||||
|
Atom real_type;
|
||||||
|
unsigned long items_read, items_left;
|
||||||
|
unsigned char *propdata;
|
||||||
|
char *title = NULL;
|
||||||
|
|
||||||
|
status = XGetWindowProperty(display, xwindow, data->_NET_WM_NAME,
|
||||||
|
0L, 8192L, False, data->UTF8_STRING, &real_type, &real_format,
|
||||||
|
&items_read, &items_left, &propdata);
|
||||||
|
if (status == Success) {
|
||||||
|
title = SDL_strdup(SDL_static_cast(char*, propdata));
|
||||||
|
XFree(propdata);
|
||||||
|
} else {
|
||||||
|
status = XGetWindowProperty(display, xwindow, XA_WM_NAME,
|
||||||
|
0L, 8192L, False, XA_STRING, &real_type, &real_format,
|
||||||
|
&items_read, &items_left, &propdata);
|
||||||
|
if (status == Success) {
|
||||||
|
title = SDL_iconv_string("UTF-8", "", SDL_static_cast(char*, propdata), items_read+1);
|
||||||
|
} else {
|
||||||
|
title = SDL_strdup("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
X11_SetWindowTitle(_THIS, SDL_Window * window)
|
X11_SetWindowTitle(_THIS, SDL_Window * window)
|
||||||
{
|
{
|
||||||
|
@ -735,14 +782,8 @@ X11_SetWindowTitle(_THIS, SDL_Window * window)
|
||||||
const char *icon = NULL;
|
const char *icon = NULL;
|
||||||
|
|
||||||
#ifdef X_HAVE_UTF8_STRING
|
#ifdef X_HAVE_UTF8_STRING
|
||||||
Atom _NET_WM_NAME = 0;
|
Atom _NET_WM_NAME = data->videodata->_NET_WM_NAME;
|
||||||
Atom _NET_WM_ICON_NAME = 0;
|
Atom _NET_WM_ICON_NAME = data->videodata->_NET_WM_ICON_NAME;
|
||||||
|
|
||||||
/* Look up some useful Atoms */
|
|
||||||
if (SDL_X11_HAVE_UTF8) {
|
|
||||||
_NET_WM_NAME = XInternAtom(display, "_NET_WM_NAME", False);
|
|
||||||
_NET_WM_ICON_NAME = XInternAtom(display, "_NET_WM_ICON_NAME", False);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (title != NULL) {
|
if (title != NULL) {
|
||||||
|
@ -803,7 +844,7 @@ X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
|
||||||
{
|
{
|
||||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||||
Display *display = data->videodata->display;
|
Display *display = data->videodata->display;
|
||||||
Atom _NET_WM_ICON = XInternAtom(display, "_NET_WM_ICON", False);
|
Atom _NET_WM_ICON = data->videodata->_NET_WM_ICON;
|
||||||
|
|
||||||
if (icon) {
|
if (icon) {
|
||||||
SDL_PixelFormat format;
|
SDL_PixelFormat format;
|
||||||
|
@ -842,16 +883,20 @@ X11_SetWindowPosition(_THIS, SDL_Window * window)
|
||||||
{
|
{
|
||||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||||
Display *display = data->videodata->display;
|
Display *display = data->videodata->display;
|
||||||
|
SDL_bool oldstyle_fullscreen;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
if ((window->flags & SDL_WINDOW_FULLSCREEN)
|
/* ICCCM2.0-compliant window managers can handle fullscreen windows */
|
||||||
|
oldstyle_fullscreen = X11_WindowIsOldstyleFullscreen(window);
|
||||||
|
|
||||||
|
if (oldstyle_fullscreen
|
||||||
|| window->x == SDL_WINDOWPOS_CENTERED) {
|
|| window->x == SDL_WINDOWPOS_CENTERED) {
|
||||||
X11_GetDisplaySize(_this, window, &x, NULL);
|
X11_GetDisplaySize(_this, window, &x, NULL);
|
||||||
x = (x - window->w) / 2;
|
x = (x - window->w) / 2;
|
||||||
} else {
|
} else {
|
||||||
x = window->x;
|
x = window->x;
|
||||||
}
|
}
|
||||||
if ((window->flags & SDL_WINDOW_FULLSCREEN)
|
if (oldstyle_fullscreen
|
||||||
|| window->y == SDL_WINDOWPOS_CENTERED) {
|
|| window->y == SDL_WINDOWPOS_CENTERED) {
|
||||||
X11_GetDisplaySize(_this, window, NULL, &y);
|
X11_GetDisplaySize(_this, window, NULL, &y);
|
||||||
y = (y - window->h) / 2;
|
y = (y - window->h) / 2;
|
||||||
|
@ -904,15 +949,14 @@ X11_SetWindowMaximized(_THIS, SDL_Window * window, SDL_bool maximized)
|
||||||
SDL_DisplayData *displaydata =
|
SDL_DisplayData *displaydata =
|
||||||
(SDL_DisplayData *) window->display->driverdata;
|
(SDL_DisplayData *) window->display->driverdata;
|
||||||
Display *display = data->videodata->display;
|
Display *display = data->videodata->display;
|
||||||
Atom _NET_WM_STATE = XInternAtom(display, "_NET_WM_STATE", False);
|
Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE;
|
||||||
Atom _NET_WM_STATE_MAXIMIZED_VERT =
|
Atom _NET_WM_STATE_MAXIMIZED_VERT = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT;
|
||||||
XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_VERT", False);
|
Atom _NET_WM_STATE_MAXIMIZED_HORZ = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
|
||||||
Atom _NET_WM_STATE_MAXIMIZED_HORZ =
|
|
||||||
XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
|
|
||||||
XEvent e;
|
XEvent e;
|
||||||
|
|
||||||
e.xany.type = ClientMessage;
|
e.xany.type = ClientMessage;
|
||||||
e.xany.window = data->xwindow;
|
e.xclient.display = display;
|
||||||
|
e.xclient.window = data->xwindow;
|
||||||
e.xclient.message_type = _NET_WM_STATE;
|
e.xclient.message_type = _NET_WM_STATE;
|
||||||
e.xclient.format = 32;
|
e.xclient.format = 32;
|
||||||
e.xclient.data.l[0] =
|
e.xclient.data.l[0] =
|
||||||
|
@ -920,7 +964,6 @@ X11_SetWindowMaximized(_THIS, SDL_Window * window, SDL_bool maximized)
|
||||||
e.xclient.data.l[1] = _NET_WM_STATE_MAXIMIZED_VERT;
|
e.xclient.data.l[1] = _NET_WM_STATE_MAXIMIZED_VERT;
|
||||||
e.xclient.data.l[2] = _NET_WM_STATE_MAXIMIZED_HORZ;
|
e.xclient.data.l[2] = _NET_WM_STATE_MAXIMIZED_HORZ;
|
||||||
e.xclient.data.l[3] = 0l;
|
e.xclient.data.l[3] = 0l;
|
||||||
e.xclient.data.l[4] = 0l;
|
|
||||||
|
|
||||||
XSendEvent(display, RootWindow(display, displaydata->screen), 0,
|
XSendEvent(display, RootWindow(display, displaydata->screen), 0,
|
||||||
SubstructureNotifyMask | SubstructureRedirectMask, &e);
|
SubstructureNotifyMask | SubstructureRedirectMask, &e);
|
||||||
|
@ -935,7 +978,12 @@ X11_MaximizeWindow(_THIS, SDL_Window * window)
|
||||||
void
|
void
|
||||||
X11_MinimizeWindow(_THIS, SDL_Window * window)
|
X11_MinimizeWindow(_THIS, SDL_Window * window)
|
||||||
{
|
{
|
||||||
X11_HideWindow(_this, window);
|
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||||
|
SDL_DisplayData *displaydata =
|
||||||
|
(SDL_DisplayData *) window->display->driverdata;
|
||||||
|
Display *display = data->videodata->display;
|
||||||
|
|
||||||
|
XIconifyWindow(display, data->xwindow, displaydata->screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -950,8 +998,12 @@ X11_SetWindowGrab(_THIS, SDL_Window * window)
|
||||||
{
|
{
|
||||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||||
Display *display = data->videodata->display;
|
Display *display = data->videodata->display;
|
||||||
|
SDL_bool oldstyle_fullscreen;
|
||||||
|
|
||||||
if ((window->flags & (SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_FULLSCREEN))
|
/* ICCCM2.0-compliant window managers can handle fullscreen windows */
|
||||||
|
oldstyle_fullscreen = X11_WindowIsOldstyleFullscreen(window);
|
||||||
|
|
||||||
|
if (((window->flags & SDL_WINDOW_INPUT_GRABBED) || oldstyle_fullscreen)
|
||||||
&& (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
|
&& (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
|
||||||
/* Try to grab the mouse */
|
/* Try to grab the mouse */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
|
@ -35,6 +35,7 @@ typedef struct
|
||||||
|
|
||||||
extern int X11_CreateWindow(_THIS, SDL_Window * window);
|
extern int X11_CreateWindow(_THIS, SDL_Window * window);
|
||||||
extern int X11_CreateWindowFrom(_THIS, SDL_Window * window, const void *data);
|
extern int X11_CreateWindowFrom(_THIS, SDL_Window * window, const void *data);
|
||||||
|
extern char *X11_GetWindowTitle(_THIS, Window xwindow);
|
||||||
extern void X11_SetWindowTitle(_THIS, SDL_Window * window);
|
extern void X11_SetWindowTitle(_THIS, SDL_Window * window);
|
||||||
extern void X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon);
|
extern void X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon);
|
||||||
extern void X11_SetWindowPosition(_THIS, SDL_Window * window);
|
extern void X11_SetWindowPosition(_THIS, SDL_Window * window);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue