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.... ???
1.1 --- a/src/video/x11/SDL_x11events.c Tue Jul 13 23:05:14 2010 -0700
1.2 +++ b/src/video/x11/SDL_x11events.c Tue Jul 13 23:11:10 2010 -0700
1.3 @@ -34,18 +34,19 @@
1.4 #include "SDL_timer.h"
1.5 #include "SDL_syswm.h"
1.6
1.7 -/*#define DEBUG_XEVENTS*/
1.8 +#define DEBUG_XEVENTS
1.9
1.10 static void
1.11 X11_DispatchEvent(_THIS)
1.12 {
1.13 SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
1.14 + Display *display = videodata->display;
1.15 SDL_WindowData *data;
1.16 XEvent xevent;
1.17 int i;
1.18
1.19 SDL_zero(xevent); /* valgrind fix. --ryan. */
1.20 - XNextEvent(videodata->display, &xevent);
1.21 + XNextEvent(display, &xevent);
1.22
1.23 /* filter events catchs XIM events and sends them to the correct
1.24 handler */
1.25 @@ -80,6 +81,7 @@
1.26 if (!data) {
1.27 return;
1.28 }
1.29 +
1.30 #if 0
1.31 printf("type = %d display = %d window = %d\n",
1.32 xevent.type, xevent.xany.display, xevent.xany.window);
1.33 @@ -182,9 +184,8 @@
1.34 #if 0
1.35 if (videodata->key_layout[keycode] == SDLK_UNKNOWN) {
1.36 int min_keycode, max_keycode;
1.37 - XDisplayKeycodes(videodata->display, &min_keycode,
1.38 - &max_keycode);
1.39 - keysym = XKeycodeToKeysym(videodata->display, keycode, 0);
1.40 + XDisplayKeycodes(display, &min_keycode, &max_keycode);
1.41 + keysym = XKeycodeToKeysym(display, keycode, 0);
1.42 fprintf(stderr,
1.43 "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",
1.44 keycode, keycode - min_keycode, keysym,
1.45 @@ -289,9 +290,58 @@
1.46 }
1.47 break;
1.48
1.49 + case PropertyNotify:{
1.50 +#ifdef DEBUG_XEVENTS
1.51 + char *name = XGetAtomName(display, xevent.xproperty.atom);
1.52 + printf("PropertyNotify (atom = %s)\n", name ? name : "NULL");
1.53 + if (name) {
1.54 + XFree(name);
1.55 + }
1.56 +#endif
1.57 + if (xevent.xproperty.atom == videodata->_NET_WM_STATE) {
1.58 + unsigned char *propdata;
1.59 + int status, real_format;
1.60 + Atom real_type;
1.61 + unsigned long items_read, items_left, i;
1.62 +
1.63 +#ifdef DEBUG_XEVENTS
1.64 + printf("_NET_WM_STATE: {");
1.65 +#endif
1.66 + status = XGetWindowProperty(display, data->xwindow, videodata->_NET_WM_STATE, 0L, 8192L, False, XA_ATOM, &real_type, &real_format, &items_read, &items_left, &propdata);
1.67 + if (status == Success) {
1.68 + Atom *atoms = (Atom *)propdata;
1.69 + for (i = 0; i < items_read; i++) {
1.70 + if (atoms[i] == videodata->_NET_WM_STATE_HIDDEN) {
1.71 +#ifdef DEBUG_XEVENTS
1.72 + printf(" _NET_WM_STATE_HIDDEN");
1.73 +#endif
1.74 + }
1.75 + if (atoms[i] == videodata->_NET_WM_STATE_MAXIMIZED_HORZ) {
1.76 +#ifdef DEBUG_XEVENTS
1.77 + printf(" _NET_WM_STATE_MAXIMIZED_HORZ");
1.78 +#endif
1.79 + }
1.80 + if (atoms[i] == videodata->_NET_WM_STATE_MAXIMIZED_VERT) {
1.81 +#ifdef DEBUG_XEVENTS
1.82 + printf(" _NET_WM_STATE_MAXIMIZED_VERT");
1.83 +#endif
1.84 + }
1.85 + if (atoms[i] == videodata->_NET_WM_STATE_FULLSCREEN) {
1.86 +#ifdef DEBUG_XEVENTS
1.87 + printf(" _NET_WM_STATE_FULLSCREEN");
1.88 +#endif
1.89 + }
1.90 + }
1.91 + }
1.92 +#ifdef DEBUG_XEVENTS
1.93 + printf(" }\n");
1.94 +#endif
1.95 + }
1.96 + }
1.97 + break;
1.98 +
1.99 /* Copy the selection from XA_CUT_BUFFER0 to the requested property */
1.100 case SelectionRequest: {
1.101 - Display *display = videodata->display;
1.102 XSelectionRequestEvent *req;
1.103 XEvent sevent;
1.104 int seln_format;
2.1 --- a/src/video/x11/SDL_x11modes.c Tue Jul 13 23:05:14 2010 -0700
2.2 +++ b/src/video/x11/SDL_x11modes.c Tue Jul 13 23:11:10 2010 -0700
2.3 @@ -23,7 +23,7 @@
2.4
2.5 #include "SDL_x11video.h"
2.6
2.7 -//#define X11MODES_DEBUG
2.8 +#define X11MODES_DEBUG
2.9 #undef SDL_VIDEO_DRIVER_X11_XINERAMA
2.10 #undef SDL_VIDEO_DRIVER_X11_XRANDR
2.11 #undef SDL_VIDEO_DRIVER_X11_VIDMODE
2.12 @@ -253,6 +253,7 @@
2.13 return SDL_TRUE;
2.14 }
2.15
2.16 +static
2.17 Bool SDL_NAME(XF86VidModeGetModeInfo) (Display * dpy, int scr,
2.18 SDL_NAME(XF86VidModeModeInfo) * info)
2.19 {
2.20 @@ -296,6 +297,7 @@
2.21 &data->saved_view.y);
2.22 }
2.23
2.24 +/*
2.25 static void
2.26 restore_mode(Display * display, SDL_DisplayData * data)
2.27 {
2.28 @@ -313,6 +315,7 @@
2.29 data->saved_view.y);
2.30 }
2.31 }
2.32 +*/
2.33 #endif /* SDL_VIDEO_DRIVER_X11_VIDMODE */
2.34
2.35 void
3.1 --- a/src/video/x11/SDL_x11sym.h Tue Jul 13 23:05:14 2010 -0700
3.2 +++ b/src/video/x11/SDL_x11sym.h Tue Jul 13 23:11:10 2010 -0700
3.3 @@ -67,12 +67,14 @@
3.4 SDL_X11_SYM(int,XFreeGC,(Display* a,GC b),(a,b),return)
3.5 SDL_X11_SYM(int,XFreeModifiermap,(XModifierKeymap* a),(a),return)
3.6 SDL_X11_SYM(int,XFreePixmap,(Display* a,Pixmap b),(a,b),return)
3.7 +SDL_X11_SYM(char*,XGetAtomName,(Display *a,Atom b),(a,b),return)
3.8 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)
3.9 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)
3.10 SDL_X11_SYM(XModifierKeymap*,XGetModifierMapping,(Display* a),(a),return)
3.11 SDL_X11_SYM(int,XGetPointerControl,(Display* a,int* b,int* c,int* d),(a,b,c,d),return)
3.12 SDL_X11_SYM(int,XGetRGBColormaps,(Display* a,Window b,XStandardColormap **c,int *d,Atom e),(a,b,c,d,e),return)
3.13 SDL_X11_SYM(Window,XGetSelectionOwner,(Display* a,Atom b),(a,b),return)
3.14 +SDL_X11_SYM(Status,XGetTextProperty,(Display *a,Window b,XTextProperty *c,Atom d),(a,b,c,d),return)
3.15 SDL_X11_SYM(XVisualInfo*,XGetVisualInfo,(Display* a,long b,XVisualInfo* c,int* d),(a,b,c,d),return)
3.16 SDL_X11_SYM(Status,XGetWindowAttributes,(Display* a,Window b,XWindowAttributes* c),(a,b,c),return)
3.17 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)
4.1 --- a/src/video/x11/SDL_x11video.c Tue Jul 13 23:05:14 2010 -0700
4.2 +++ b/src/video/x11/SDL_x11video.c Tue Jul 13 23:11:10 2010 -0700
4.3 @@ -242,6 +242,43 @@
4.4 };
4.5
4.6
4.7 +static void
4.8 +X11_CheckWindowManager(_THIS)
4.9 +{
4.10 + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
4.11 + Display *display = data->display;
4.12 + Atom _NET_SUPPORTING_WM_CHECK;
4.13 + int status, real_format;
4.14 + Atom real_type;
4.15 + unsigned long items_read, items_left;
4.16 + unsigned char *propdata;
4.17 + Window wm_window = 0;
4.18 +#ifdef DEBUG_WINDOW_MANAGER
4.19 + char *wm_name;
4.20 +#endif
4.21 +
4.22 + _NET_SUPPORTING_WM_CHECK = XInternAtom(display, "_NET_SUPPORTING_WM_CHECK", False);
4.23 + status = XGetWindowProperty(display, DefaultRootWindow(display), _NET_SUPPORTING_WM_CHECK, 0L, 1L, False, XA_WINDOW, &real_type, &real_format, &items_read, &items_left, &propdata);
4.24 + if (status == Success && items_read) {
4.25 + wm_window = ((Window*)propdata)[0];
4.26 + }
4.27 + XFree(propdata);
4.28 +
4.29 + if (!wm_window) {
4.30 +#ifdef DEBUG_WINDOW_MANAGER
4.31 + printf("Couldn't get _NET_SUPPORTING_WM_CHECK property\n");
4.32 +#endif
4.33 + return;
4.34 + }
4.35 + data->net_wm = SDL_TRUE;
4.36 +
4.37 +#ifdef DEBUG_WINDOW_MANAGER
4.38 + wm_name = X11_GetWindowTitle(_this, wm_window);
4.39 + printf("Window manager: %s\n", wm_name);
4.40 + SDL_free(wm_name);
4.41 +#endif
4.42 +}
4.43 +
4.44 int
4.45 X11_VideoInit(_THIS)
4.46 {
4.47 @@ -259,8 +296,20 @@
4.48 #endif
4.49
4.50 /* Look up some useful Atoms */
4.51 - data->WM_DELETE_WINDOW =
4.52 - XInternAtom(data->display, "WM_DELETE_WINDOW", False);
4.53 +#define GET_ATOM(X) data->X = XInternAtom(data->display, #X, False)
4.54 + GET_ATOM(WM_DELETE_WINDOW);
4.55 + GET_ATOM(_NET_WM_STATE);
4.56 + GET_ATOM(_NET_WM_STATE_HIDDEN);
4.57 + GET_ATOM(_NET_WM_STATE_MAXIMIZED_VERT);
4.58 + GET_ATOM(_NET_WM_STATE_MAXIMIZED_HORZ);
4.59 + GET_ATOM(_NET_WM_STATE_FULLSCREEN);
4.60 + GET_ATOM(_NET_WM_NAME);
4.61 + GET_ATOM(_NET_WM_ICON_NAME);
4.62 + GET_ATOM(_NET_WM_ICON);
4.63 + GET_ATOM(UTF8_STRING);
4.64 +
4.65 + /* Detect the window manager */
4.66 + X11_CheckWindowManager(_this);
4.67
4.68 if (X11_InitModes(_this) < 0) {
4.69 return -1;
5.1 --- a/src/video/x11/SDL_x11video.h Tue Jul 13 23:05:14 2010 -0700
5.2 +++ b/src/video/x11/SDL_x11video.h Tue Jul 13 23:11:10 2010 -0700
5.3 @@ -68,7 +68,22 @@
5.4 int numwindows;
5.5 SDL_WindowData **windowlist;
5.6 int windowlistlength;
5.7 +
5.8 + /* This is true for ICCCM2.0-compliant window managers */
5.9 + SDL_bool net_wm;
5.10 +
5.11 + /* Useful atoms */
5.12 Atom WM_DELETE_WINDOW;
5.13 + Atom _NET_WM_STATE;
5.14 + Atom _NET_WM_STATE_HIDDEN;
5.15 + Atom _NET_WM_STATE_MAXIMIZED_VERT;
5.16 + Atom _NET_WM_STATE_MAXIMIZED_HORZ;
5.17 + Atom _NET_WM_STATE_FULLSCREEN;
5.18 + Atom _NET_WM_NAME;
5.19 + Atom _NET_WM_ICON_NAME;
5.20 + Atom _NET_WM_ICON;
5.21 + Atom UTF8_STRING;
5.22 +
5.23 SDL_scancode key_layout[256];
5.24 SDL_bool selection_waiting;
5.25 } SDL_VideoData;
6.1 --- a/src/video/x11/SDL_x11window.c Tue Jul 13 23:05:14 2010 -0700
6.2 +++ b/src/video/x11/SDL_x11window.c Tue Jul 13 23:11:10 2010 -0700
6.3 @@ -42,6 +42,20 @@
6.4 #define _NET_WM_STATE_ADD 1l
6.5 #define _NET_WM_STATE_TOGGLE 2l
6.6
6.7 +static SDL_bool
6.8 +X11_WindowIsOldstyleFullscreen(SDL_Window * window)
6.9 +{
6.10 + SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
6.11 + SDL_VideoData *videodata = (SDL_VideoData *) data->videodata;
6.12 +
6.13 + /* ICCCM2.0-compliant window managers can handle fullscreen windows */
6.14 + if ((window->flags & SDL_WINDOW_FULLSCREEN) && !videodata->net_wm) {
6.15 + return SDL_TRUE;
6.16 + } else {
6.17 + return SDL_FALSE;
6.18 + }
6.19 +}
6.20 +
6.21 static void
6.22 X11_GetDisplaySize(_THIS, SDL_Window * window, int *w, int *h)
6.23 {
6.24 @@ -128,14 +142,10 @@
6.25 }
6.26
6.27 {
6.28 - Atom _NET_WM_STATE =
6.29 - XInternAtom(data->videodata->display, "_NET_WM_STATE", False);
6.30 - Atom _NET_WM_STATE_MAXIMIZED_VERT =
6.31 - XInternAtom(data->videodata->display,
6.32 - "_NET_WM_STATE_MAXIMIZED_VERT", False);
6.33 - Atom _NET_WM_STATE_MAXIMIZED_HORZ =
6.34 - XInternAtom(data->videodata->display,
6.35 - "_NET_WM_STATE_MAXIMIZED_HORZ", False);
6.36 + Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE;
6.37 + Atom _NET_WM_STATE_MAXIMIZED_VERT = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT;
6.38 + Atom _NET_WM_STATE_MAXIMIZED_HORZ = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
6.39 + Atom _NET_WM_STATE_FULLSCREEN = data->videodata->_NET_WM_STATE_FULLSCREEN;
6.40 Atom actualType;
6.41 int actualFormat;
6.42 unsigned long i, numItems, bytesAfter;
6.43 @@ -148,19 +158,21 @@
6.44 &propertyValue) == Success) {
6.45 Atom *atoms = (Atom *) propertyValue;
6.46 int maximized = 0;
6.47 + int fullscreen = 0;
6.48
6.49 for (i = 0; i < numItems; ++i) {
6.50 if (atoms[i] == _NET_WM_STATE_MAXIMIZED_VERT) {
6.51 maximized |= 1;
6.52 } else if (atoms[i] == _NET_WM_STATE_MAXIMIZED_HORZ) {
6.53 maximized |= 2;
6.54 + } else if ( atoms[i] == _NET_WM_STATE_FULLSCREEN) {
6.55 + fullscreen = 1;
6.56 }
6.57 - /* Might also want to check the following properties:
6.58 - _NET_WM_STATE_ABOVE, _NET_WM_STATE_FULLSCREEN
6.59 - */
6.60 }
6.61 if (maximized == 3) {
6.62 window->flags |= SDL_WINDOW_MAXIMIZED;
6.63 + } else if (fullscreen == 1) {
6.64 + window->flags |= SDL_WINDOW_FULLSCREEN;
6.65 }
6.66 XFree(propertyValue);
6.67 }
6.68 @@ -180,11 +192,6 @@
6.69 } else {
6.70 window->flags &= ~SDL_WINDOW_RESIZABLE;
6.71 }
6.72 - if (style & WS_MAXIMIZE) {
6.73 - window->flags |= SDL_WINDOW_MAXIMIZED;
6.74 - } else {
6.75 - window->flags &= ~SDL_WINDOW_MAXIMIZED;
6.76 - }
6.77 if (style & WS_MINIMIZE) {
6.78 window->flags |= SDL_WINDOW_MINIMIZED;
6.79 } else {
6.80 @@ -225,6 +232,14 @@
6.81 XSizeHints *sizehints;
6.82 XWMHints *wmhints;
6.83 XClassHint *classhints;
6.84 + SDL_bool oldstyle_fullscreen;
6.85 +
6.86 + /* ICCCM2.0-compliant window managers can handle fullscreen windows */
6.87 + if ((window->flags & SDL_WINDOW_FULLSCREEN) && !data->net_wm) {
6.88 + oldstyle_fullscreen = SDL_TRUE;
6.89 + } else {
6.90 + oldstyle_fullscreen = SDL_FALSE;
6.91 + }
6.92
6.93 #if SDL_VIDEO_DRIVER_X11_XINERAMA
6.94 /* FIXME
6.95 @@ -265,7 +280,7 @@
6.96 depth = displaydata->depth;
6.97 }
6.98
6.99 - if (window->flags & SDL_WINDOW_FULLSCREEN) {
6.100 + if (oldstyle_fullscreen) {
6.101 xattr.override_redirect = True;
6.102 } else {
6.103 xattr.override_redirect = False;
6.104 @@ -417,7 +432,6 @@
6.105 }
6.106
6.107 /* OK, we got a colormap, now fill it in as best as we can */
6.108 -
6.109 colorcells = SDL_malloc(visual->map_entries * sizeof(XColor));
6.110 if (NULL == colorcells) {
6.111 SDL_SetError("out of memory in X11_CreateWindow");
6.112 @@ -494,7 +508,7 @@
6.113 visual, AllocNone);
6.114 }
6.115
6.116 - if ((window->flags & SDL_WINDOW_FULLSCREEN)
6.117 + if (oldstyle_fullscreen
6.118 || window->x == SDL_WINDOWPOS_CENTERED) {
6.119 X11_GetDisplaySize(_this, window, &x, NULL);
6.120 x = (x - window->w) / 2;
6.121 @@ -503,7 +517,7 @@
6.122 } else {
6.123 x = window->x;
6.124 }
6.125 - if ((window->flags & SDL_WINDOW_FULLSCREEN)
6.126 + if (oldstyle_fullscreen
6.127 || window->y == SDL_WINDOWPOS_CENTERED) {
6.128 X11_GetDisplaySize(_this, window, NULL, &y);
6.129 y = (y - window->h) / 2;
6.130 @@ -539,12 +553,12 @@
6.131 sizehints = XAllocSizeHints();
6.132 if (sizehints) {
6.133 if (!(window->flags & SDL_WINDOW_RESIZABLE)
6.134 - || (window->flags & SDL_WINDOW_FULLSCREEN)) {
6.135 + || oldstyle_fullscreen) {
6.136 sizehints->min_width = sizehints->max_width = window->w;
6.137 sizehints->min_height = sizehints->max_height = window->h;
6.138 sizehints->flags = PMaxSize | PMinSize;
6.139 }
6.140 - if (!(window->flags & SDL_WINDOW_FULLSCREEN)
6.141 + if (!oldstyle_fullscreen
6.142 && window->x != SDL_WINDOWPOS_UNDEFINED
6.143 && window->y != SDL_WINDOWPOS_UNDEFINED) {
6.144 sizehints->x = x;
6.145 @@ -555,7 +569,7 @@
6.146 XFree(sizehints);
6.147 }
6.148
6.149 - if (window->flags & (SDL_WINDOW_BORDERLESS | SDL_WINDOW_FULLSCREEN)) {
6.150 + if ((window->flags & SDL_WINDOW_BORDERLESS) || oldstyle_fullscreen) {
6.151 SDL_bool set;
6.152 Atom WM_HINTS;
6.153
6.154 @@ -643,23 +657,6 @@
6.155 }
6.156 }
6.157
6.158 - /* Tell KDE to keep fullscreen windows on top */
6.159 - if (window->flags & SDL_WINDOW_FULLSCREEN) {
6.160 - XEvent ev;
6.161 -
6.162 - SDL_zero(ev);
6.163 - ev.xclient.type = ClientMessage;
6.164 - ev.xclient.window = RootWindow(data->display, displaydata->screen);
6.165 - ev.xclient.message_type =
6.166 - XInternAtom(data->display, "KWM_KEEP_ON_TOP", False);
6.167 - ev.xclient.format = 32;
6.168 - ev.xclient.data.l[0] = w;
6.169 - ev.xclient.data.l[1] = CurrentTime;
6.170 - XSendEvent(data->display,
6.171 - RootWindow(data->display, displaydata->screen), False,
6.172 - SubstructureRedirectMask, &ev);
6.173 - }
6.174 -
6.175 /* Set the input hints so we get keyboard input */
6.176 wmhints = XAllocWMHints();
6.177 if (wmhints) {
6.178 @@ -678,6 +675,26 @@
6.179 XFree(classhints);
6.180 }
6.181
6.182 + /* FIXME: Why doesn't this work? */
6.183 + if (window->flags & SDL_WINDOW_FULLSCREEN) {
6.184 + Atom _NET_WM_STATE = data->_NET_WM_STATE;
6.185 + Atom _NET_WM_STATE_FULLSCREEN = data->_NET_WM_STATE_FULLSCREEN;
6.186 + XEvent e;
6.187 +
6.188 + e.xany.type = ClientMessage;
6.189 + e.xclient.display = data->display;
6.190 + e.xclient.window = w;
6.191 + e.xclient.message_type = _NET_WM_STATE;
6.192 + e.xclient.format = 32;
6.193 + e.xclient.data.l[0] = _NET_WM_STATE_ADD;
6.194 + e.xclient.data.l[1] = _NET_WM_STATE_FULLSCREEN;
6.195 + e.xclient.data.l[2] = 0l;
6.196 +
6.197 + XSendEvent(data->display,
6.198 + RootWindow(data->display, displaydata->screen), 0,
6.199 + SubstructureNotifyMask | SubstructureRedirectMask, &e);
6.200 + }
6.201 +
6.202 /* Allow the window to be deleted by the window manager */
6.203 XSetWMProtocols(data->display, w, &data->WM_DELETE_WINDOW, 1);
6.204
6.205 @@ -716,7 +733,7 @@
6.206 {
6.207 Window w = (Window) data;
6.208
6.209 - /* FIXME: Query the title from the existing window */
6.210 + window->title = X11_GetWindowTitle(_this, w);
6.211
6.212 if (SetupWindowData(_this, window, w, SDL_FALSE) < 0) {
6.213 return -1;
6.214 @@ -724,6 +741,36 @@
6.215 return 0;
6.216 }
6.217
6.218 +char *
6.219 +X11_GetWindowTitle(_THIS, Window xwindow)
6.220 +{
6.221 + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
6.222 + Display *display = data->display;
6.223 + int status, real_format;
6.224 + Atom real_type;
6.225 + unsigned long items_read, items_left;
6.226 + unsigned char *propdata;
6.227 + char *title = NULL;
6.228 +
6.229 + status = XGetWindowProperty(display, xwindow, data->_NET_WM_NAME,
6.230 + 0L, 8192L, False, data->UTF8_STRING, &real_type, &real_format,
6.231 + &items_read, &items_left, &propdata);
6.232 + if (status == Success) {
6.233 + title = SDL_strdup(SDL_static_cast(char*, propdata));
6.234 + XFree(propdata);
6.235 + } else {
6.236 + status = XGetWindowProperty(display, xwindow, XA_WM_NAME,
6.237 + 0L, 8192L, False, XA_STRING, &real_type, &real_format,
6.238 + &items_read, &items_left, &propdata);
6.239 + if (status == Success) {
6.240 + title = SDL_iconv_string("UTF-8", "", SDL_static_cast(char*, propdata), items_read+1);
6.241 + } else {
6.242 + title = SDL_strdup("");
6.243 + }
6.244 + }
6.245 + return title;
6.246 +}
6.247 +
6.248 void
6.249 X11_SetWindowTitle(_THIS, SDL_Window * window)
6.250 {
6.251 @@ -735,14 +782,8 @@
6.252 const char *icon = NULL;
6.253
6.254 #ifdef X_HAVE_UTF8_STRING
6.255 - Atom _NET_WM_NAME = 0;
6.256 - Atom _NET_WM_ICON_NAME = 0;
6.257 -
6.258 - /* Look up some useful Atoms */
6.259 - if (SDL_X11_HAVE_UTF8) {
6.260 - _NET_WM_NAME = XInternAtom(display, "_NET_WM_NAME", False);
6.261 - _NET_WM_ICON_NAME = XInternAtom(display, "_NET_WM_ICON_NAME", False);
6.262 - }
6.263 + Atom _NET_WM_NAME = data->videodata->_NET_WM_NAME;
6.264 + Atom _NET_WM_ICON_NAME = data->videodata->_NET_WM_ICON_NAME;
6.265 #endif
6.266
6.267 if (title != NULL) {
6.268 @@ -803,7 +844,7 @@
6.269 {
6.270 SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
6.271 Display *display = data->videodata->display;
6.272 - Atom _NET_WM_ICON = XInternAtom(display, "_NET_WM_ICON", False);
6.273 + Atom _NET_WM_ICON = data->videodata->_NET_WM_ICON;
6.274
6.275 if (icon) {
6.276 SDL_PixelFormat format;
6.277 @@ -842,16 +883,20 @@
6.278 {
6.279 SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
6.280 Display *display = data->videodata->display;
6.281 + SDL_bool oldstyle_fullscreen;
6.282 int x, y;
6.283
6.284 - if ((window->flags & SDL_WINDOW_FULLSCREEN)
6.285 + /* ICCCM2.0-compliant window managers can handle fullscreen windows */
6.286 + oldstyle_fullscreen = X11_WindowIsOldstyleFullscreen(window);
6.287 +
6.288 + if (oldstyle_fullscreen
6.289 || window->x == SDL_WINDOWPOS_CENTERED) {
6.290 X11_GetDisplaySize(_this, window, &x, NULL);
6.291 x = (x - window->w) / 2;
6.292 } else {
6.293 x = window->x;
6.294 }
6.295 - if ((window->flags & SDL_WINDOW_FULLSCREEN)
6.296 + if (oldstyle_fullscreen
6.297 || window->y == SDL_WINDOWPOS_CENTERED) {
6.298 X11_GetDisplaySize(_this, window, NULL, &y);
6.299 y = (y - window->h) / 2;
6.300 @@ -904,15 +949,14 @@
6.301 SDL_DisplayData *displaydata =
6.302 (SDL_DisplayData *) window->display->driverdata;
6.303 Display *display = data->videodata->display;
6.304 - Atom _NET_WM_STATE = XInternAtom(display, "_NET_WM_STATE", False);
6.305 - Atom _NET_WM_STATE_MAXIMIZED_VERT =
6.306 - XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_VERT", False);
6.307 - Atom _NET_WM_STATE_MAXIMIZED_HORZ =
6.308 - XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
6.309 + Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE;
6.310 + Atom _NET_WM_STATE_MAXIMIZED_VERT = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT;
6.311 + Atom _NET_WM_STATE_MAXIMIZED_HORZ = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
6.312 XEvent e;
6.313
6.314 e.xany.type = ClientMessage;
6.315 - e.xany.window = data->xwindow;
6.316 + e.xclient.display = display;
6.317 + e.xclient.window = data->xwindow;
6.318 e.xclient.message_type = _NET_WM_STATE;
6.319 e.xclient.format = 32;
6.320 e.xclient.data.l[0] =
6.321 @@ -920,7 +964,6 @@
6.322 e.xclient.data.l[1] = _NET_WM_STATE_MAXIMIZED_VERT;
6.323 e.xclient.data.l[2] = _NET_WM_STATE_MAXIMIZED_HORZ;
6.324 e.xclient.data.l[3] = 0l;
6.325 - e.xclient.data.l[4] = 0l;
6.326
6.327 XSendEvent(display, RootWindow(display, displaydata->screen), 0,
6.328 SubstructureNotifyMask | SubstructureRedirectMask, &e);
6.329 @@ -935,7 +978,12 @@
6.330 void
6.331 X11_MinimizeWindow(_THIS, SDL_Window * window)
6.332 {
6.333 - X11_HideWindow(_this, window);
6.334 + SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
6.335 + SDL_DisplayData *displaydata =
6.336 + (SDL_DisplayData *) window->display->driverdata;
6.337 + Display *display = data->videodata->display;
6.338 +
6.339 + XIconifyWindow(display, data->xwindow, displaydata->screen);
6.340 }
6.341
6.342 void
6.343 @@ -950,8 +998,12 @@
6.344 {
6.345 SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
6.346 Display *display = data->videodata->display;
6.347 + SDL_bool oldstyle_fullscreen;
6.348
6.349 - if ((window->flags & (SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_FULLSCREEN))
6.350 + /* ICCCM2.0-compliant window managers can handle fullscreen windows */
6.351 + oldstyle_fullscreen = X11_WindowIsOldstyleFullscreen(window);
6.352 +
6.353 + if (((window->flags & SDL_WINDOW_INPUT_GRABBED) || oldstyle_fullscreen)
6.354 && (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
6.355 /* Try to grab the mouse */
6.356 for (;;) {
7.1 --- a/src/video/x11/SDL_x11window.h Tue Jul 13 23:05:14 2010 -0700
7.2 +++ b/src/video/x11/SDL_x11window.h Tue Jul 13 23:11:10 2010 -0700
7.3 @@ -35,6 +35,7 @@
7.4
7.5 extern int X11_CreateWindow(_THIS, SDL_Window * window);
7.6 extern int X11_CreateWindowFrom(_THIS, SDL_Window * window, const void *data);
7.7 +extern char *X11_GetWindowTitle(_THIS, Window xwindow);
7.8 extern void X11_SetWindowTitle(_THIS, SDL_Window * window);
7.9 extern void X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon);
7.10 extern void X11_SetWindowPosition(_THIS, SDL_Window * window);