21 #include "../../SDL_internal.h"
23 #if SDL_VIDEO_DRIVER_X11
27 #include "../SDL_sysvideo.h"
28 #include "../SDL_pixels_c.h"
29 #include "../../events/SDL_keyboard_c.h"
30 #include "../../events/SDL_mouse_c.h"
37 #if SDL_VIDEO_OPENGL_EGL
45 #define _NET_WM_STATE_REMOVE 0l
46 #define _NET_WM_STATE_ADD 1l
48 static Bool isMapNotify(Display *
dpy, XEvent *ev, XPointer win)
50 return ev->type == MapNotify && ev->xmap.window == *((Window*)win);
52 static Bool isUnmapNotify(Display *
dpy, XEvent *ev, XPointer win)
54 return ev->type == UnmapNotify && ev->xunmap.window == *((Window*)win);
80 return (
data->fswindow != 0);
88 XWindowAttributes attr;
90 X11_XGetWindowAttributes(videodata->display,
data->xwindow, &attr);
91 if (attr.map_state != IsUnmapped) {
105 Display *display =
data->videodata->display;
107 unsigned long remain;
108 unsigned long len,
i;
112 if (X11_XGetWindowProperty(display,
data->xwindow, _NET_WM_ALLOWED_ACTIONS, 0, 1024, False, XA_ATOM, &
type, &form, &
len, &remain, (
unsigned char **)&list) == Success)
131 Display *display = videodata->
display;
155 atoms[
count++] = _NET_WM_STATE_ABOVE;
158 atoms[
count++] = _NET_WM_STATE_SKIP_TASKBAR;
159 atoms[
count++] = _NET_WM_STATE_SKIP_PAGER;
162 atoms[
count++] = _NET_WM_STATE_FOCUSED;
165 atoms[
count++] = _NET_WM_STATE_MAXIMIZED_VERT;
166 atoms[
count++] = _NET_WM_STATE_MAXIMIZED_HORZ;
169 atoms[
count++] = _NET_WM_STATE_FULLSCREEN;
175 X11_XChangeProperty(display, xwindow, _NET_WM_STATE, XA_ATOM, 32,
176 PropModeReplace, (
unsigned char *)atoms,
count);
178 X11_XDeleteProperty(display, xwindow, _NET_WM_STATE);
186 Display *display = videodata->
display;
195 unsigned long i, numItems, bytesAfter;
196 unsigned char *propertyValue =
NULL;
200 if (X11_XGetWindowProperty(display, xwindow, _NET_WM_STATE,
202 &actualFormat, &numItems, &bytesAfter,
203 &propertyValue) == Success) {
204 Atom *atoms = (Atom *) propertyValue;
208 for (
i = 0;
i < numItems; ++
i) {
209 if (atoms[
i] == _NET_WM_STATE_HIDDEN) {
211 }
else if (atoms[
i] == _NET_WM_STATE_FOCUSED) {
213 }
else if (atoms[
i] == _NET_WM_STATE_MAXIMIZED_VERT) {
215 }
else if (atoms[
i] == _NET_WM_STATE_MAXIMIZED_HORZ) {
217 }
else if ( atoms[
i] == _NET_WM_STATE_FULLSCREEN) {
221 if (maximized == 3) {
225 if (fullscreen == 1) {
234 XWindowAttributes attr;
236 X11_XGetWindowAttributes(videodata->
display, xwindow, &attr);
237 if (attr.map_state == IsUnmapped) {
241 X11_XFree(propertyValue);
266 #ifdef X_HAVE_UTF8_STRING
267 if (SDL_X11_HAVE_UTF8 && videodata->
im) {
269 X11_XCreateIC(videodata->
im, XNClientWindow,
w, XNFocusWindow,
w,
270 XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
274 data->created = created;
275 data->videodata = videodata;
279 if (numwindows < windowlistlength) {
280 windowlist[numwindows] =
data;
286 1) *
sizeof(*windowlist));
291 windowlist[numwindows] =
data;
299 XWindowAttributes attrib;
301 X11_XGetWindowAttributes(
data->videodata->display,
w, &attrib);
305 window->h = attrib.height;
306 if (attrib.map_state != IsUnmapped) {
311 data->visual = attrib.visual;
312 data->colormap = attrib.colormap;
320 X11_XGetInputFocus(
data->videodata->display, &FocalWindow, &RevertTo);
349 Atom WM_HINTS = X11_XInternAtom(display,
"_MOTIF_WM_HINTS", True);
350 if (WM_HINTS != None) {
355 unsigned long functions;
356 unsigned long decorations;
358 unsigned long status;
360 (1L << 1), 0,
border ? 1 : 0, 0, 0
363 X11_XChangeProperty(display,
window, WM_HINTS, WM_HINTS, 32,
364 PropModeReplace, (
unsigned char *) &MWMHints,
365 sizeof(MWMHints) /
sizeof(
long));
367 X11_XSetTransientForHint(display,
window, RootWindow(display,
screen));
378 Display *display =
data->display;
379 int screen = displaydata->screen;
382 XSetWindowAttributes xattr;
384 XSizeHints *sizehints;
386 XClassHint *classhints;
387 Atom _NET_WM_BYPASS_COMPOSITOR;
388 Atom _NET_WM_WINDOW_TYPE;
390 const char *wintype_name =
NULL;
395 #if SDL_VIDEO_OPENGL_GLX || SDL_VIDEO_OPENGL_EGL
398 if (forced_visual_id !=
NULL && forced_visual_id[0] !=
'\0')
400 XVisualInfo *vi,
template;
405 vi = X11_XGetVisualInfo(display, VisualIDMask, &
template, &nvis);
418 XVisualInfo *vinfo =
NULL;
420 #if SDL_VIDEO_OPENGL_EGL
427 vinfo = X11_GLES_GetVisual(
_this, display,
screen);
431 #if SDL_VIDEO_OPENGL_GLX
439 visual = vinfo->visual;
440 depth = vinfo->depth;
445 visual = displaydata->visual;
446 depth = displaydata->depth;
450 xattr.background_pixmap = None;
451 xattr.border_pixel = 0;
453 if (visual->class == DirectColor) {
457 int rmax, gmax, bmax;
458 int rmask, gmask, bmask;
459 int rshift, gshift, bshift;
462 X11_XCreateColormap(display, RootWindow(display,
screen),
466 if (!xattr.colormap) {
467 return SDL_SetError(
"Could not create writable colormap");
471 colorcells =
SDL_malloc(visual->map_entries *
sizeof(XColor));
475 ncolors = visual->map_entries;
481 rmask = visual->red_mask;
482 while (0 == (rmask & 1)) {
488 gmask = visual->green_mask;
489 while (0 == (gmask & 1)) {
495 bmask = visual->blue_mask;
496 while (0 == (bmask & 1)) {
502 for (
i = 0;
i < ncolors;
i++) {
507 Uint32 rbits = (rmask *
i) / (ncolors - 1);
508 Uint32 gbits = (gmask *
i) / (ncolors - 1);
509 Uint32 bbits = (bmask *
i) / (ncolors - 1);
512 (rbits << rshift) | (gbits << gshift) | (bbits << bshift);
514 colorcells[
i].pixel = pix;
516 colorcells[
i].red =
red;
517 colorcells[
i].green =
green;
518 colorcells[
i].blue =
blue;
520 colorcells[
i].flags = DoRed | DoGreen | DoBlue;
523 X11_XStoreColors(display, xattr.colormap, colorcells, ncolors);
528 X11_XCreateColormap(display, RootWindow(display,
screen),
532 w = X11_XCreateWindow(display, RootWindow(display,
screen),
534 0,
depth, InputOutput, visual,
535 (CWOverrideRedirect | CWBackPixmap | CWBorderPixel |
536 CWColormap), &xattr);
541 SetWindowBordered(display,
screen,
w,
544 sizehints = X11_XAllocSizeHints();
546 sizehints->flags = 0;
548 sizehints->min_width = sizehints->max_width =
window->w;
549 sizehints->min_height = sizehints->max_height =
window->h;
550 sizehints->flags |= (PMaxSize | PMinSize);
554 sizehints->flags |= USPosition;
557 wmhints = X11_XAllocWMHints();
558 wmhints->input = True;
559 wmhints->window_group =
data->window_group;
560 wmhints->flags = InputHint | WindowGroupHint;
563 classhints = X11_XAllocClassHint();
564 classhints->res_name =
data->classname;
565 classhints->res_class =
data->classname;
568 X11_XSetWMProperties(display,
w,
NULL,
NULL,
NULL, 0, sizehints, wmhints, classhints);
570 X11_XFree(sizehints);
572 X11_XFree(classhints);
575 long pid = (long)
data->pid;
576 _NET_WM_PID = X11_XInternAtom(display,
"_NET_WM_PID", False);
577 X11_XChangeProperty(display,
w, _NET_WM_PID, XA_CARDINAL, 32, PropModeReplace,
578 (
unsigned char *) &pid, 1);
587 wintype_name =
"_NET_WM_WINDOW_TYPE_UTILITY";
589 wintype_name =
"_NET_WM_WINDOW_TYPE_TOOLTIP";
591 wintype_name =
"_NET_WM_WINDOW_TYPE_POPUP_MENU";
593 wintype_name =
"_NET_WM_WINDOW_TYPE_NORMAL";
598 _NET_WM_WINDOW_TYPE = X11_XInternAtom(display,
"_NET_WM_WINDOW_TYPE", False);
599 wintype = X11_XInternAtom(display, wintype_name, False);
600 X11_XChangeProperty(display,
w, _NET_WM_WINDOW_TYPE, XA_ATOM, 32,
601 PropModeReplace, (
unsigned char *)&wintype, 1);
603 _NET_WM_BYPASS_COMPOSITOR = X11_XInternAtom(display,
"_NET_WM_BYPASS_COMPOSITOR", False);
604 X11_XChangeProperty(display,
w, _NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32,
606 (
unsigned char *)&compositor, 1);
613 protocols[proto_count++] =
data->WM_DELETE_WINDOW;
614 protocols[proto_count++] =
data->WM_TAKE_FOCUS;
618 protocols[proto_count++] =
data->_NET_WM_PING;
621 SDL_assert(proto_count <=
sizeof(protocols) /
sizeof(protocols[0]));
623 X11_XSetWMProtocols(display,
w, protocols, proto_count);
627 X11_XDestroyWindow(display,
w);
640 #if SDL_VIDEO_OPENGL_EGL
641 if (!
_this->egl_data) {
649 return SDL_SetError(
"Could not create GLES window surface");
652 return SDL_SetError(
"Could not create GLES window surface (EGL support not configured)");
658 #ifdef X_HAVE_UTF8_STRING
659 if (SDL_X11_HAVE_UTF8 && windowdata->
ic) {
660 X11_XGetICValues(windowdata->
ic, XNFilterEvents, &fevent,
NULL);
666 X11_XSelectInput(display,
w,
667 (FocusChangeMask | EnterWindowMask | LeaveWindowMask |
668 ExposureMask | ButtonPressMask | ButtonReleaseMask |
669 PointerMotionMask | KeyPressMask | KeyReleaseMask |
670 PropertyChangeMask | StructureNotifyMask |
671 KeymapStateMask | fevent));
681 Window
w = (Window)
data;
695 Display *display =
data->display;
696 int status, real_format;
698 unsigned long items_read, items_left;
699 unsigned char *propdata;
702 status = X11_XGetWindowProperty(display, xwindow,
data->_NET_WM_NAME,
703 0L, 8192L, False,
data->UTF8_STRING, &real_type, &real_format,
704 &items_read, &items_left, &propdata);
705 if (status == Success && propdata) {
709 status = X11_XGetWindowProperty(display, xwindow, XA_WM_NAME,
710 0L, 8192L, False, XA_STRING, &real_type, &real_format,
711 &items_read, &items_left, &propdata);
712 if (status == Success && propdata) {
727 XTextProperty titleprop;
730 char *title_locale =
NULL;
732 #ifdef X_HAVE_UTF8_STRING
733 Atom _NET_WM_NAME =
data->videodata->_NET_WM_NAME;
742 status = X11_XStringListToTextProperty(&title_locale, 1, &titleprop);
745 X11_XSetTextProperty(display,
data->xwindow, &titleprop, XA_WM_NAME);
746 X11_XFree(titleprop.value);
748 #ifdef X_HAVE_UTF8_STRING
749 if (SDL_X11_HAVE_UTF8) {
750 status = X11_Xutf8TextListToTextProperty(display, (
char **) &title, 1,
751 XUTF8StringStyle, &titleprop);
752 if (status == Success) {
753 X11_XSetTextProperty(display,
data->xwindow, &titleprop,
755 X11_XFree(titleprop.value);
768 Atom _NET_WM_ICON =
data->videodata->_NET_WM_ICON;
776 propsize = 2 + (icon->
w * icon->
h);
777 propdata =
SDL_malloc(propsize *
sizeof(
long));
783 propdata[0] = icon->
w;
784 propdata[1] = icon->
h;
786 for (
y = 0;
y < icon->
h; ++
y) {
788 for (
x = 0;
x < icon->
w; ++
x) {
792 X11_XChangeProperty(display,
data->xwindow, _NET_WM_ICON, XA_CARDINAL,
793 32, PropModeReplace, (
unsigned char *) propdata,
798 X11_XDeleteProperty(display,
data->xwindow, _NET_WM_ICON);
808 unsigned int childCount;
809 Window childReturn, root, parent;
811 XWindowAttributes attrs;
815 X11_XSync(display, False);
816 X11_XQueryTree(display,
data->xwindow, &root, &parent, &children, &childCount);
817 X11_XGetWindowAttributes(display,
data->xwindow, &attrs);
818 X11_XTranslateCoordinates(display, parent, DefaultRootWindow(display),
819 attrs.x, attrs.y, &orig_x, &orig_y, &childReturn);
829 X11_XSync(display, False);
830 X11_XGetWindowAttributes(display,
data->xwindow, &attrs);
831 X11_XTranslateCoordinates(display, parent, DefaultRootWindow(display),
832 attrs.x, attrs.y, &
x, &
y, &childReturn);
834 if ((
x != orig_x) || (
y != orig_y)) {
857 XSizeHints *sizehints = X11_XAllocSizeHints();
860 X11_XGetWMNormalHints(display,
data->xwindow, sizehints, &userhints);
862 sizehints->min_width =
window->min_w;
863 sizehints->min_height =
window->min_h;
864 sizehints->flags |= PMinSize;
866 X11_XSetWMNormalHints(display,
data->xwindow, sizehints);
868 X11_XFree(sizehints);
873 X11_XRaiseWindow(display,
data->xwindow);
886 XSizeHints *sizehints = X11_XAllocSizeHints();
889 X11_XGetWMNormalHints(display,
data->xwindow, sizehints, &userhints);
891 sizehints->max_width =
window->max_w;
892 sizehints->max_height =
window->max_h;
893 sizehints->flags |= PMaxSize;
895 X11_XSetWMNormalHints(display,
data->xwindow, sizehints);
897 X11_XFree(sizehints);
902 X11_XRaiseWindow(display,
data->xwindow);
913 XWindowAttributes attrs;
917 X11_XSync(display, False);
918 X11_XGetWindowAttributes(display,
data->xwindow, &attrs);
919 orig_w = attrs.width;
920 orig_h = attrs.height;
928 XSizeHints *sizehints = X11_XAllocSizeHints();
931 X11_XGetWMNormalHints(display,
data->xwindow, sizehints, &userhints);
933 sizehints->min_width = sizehints->max_width =
window->w;
934 sizehints->min_height = sizehints->max_height =
window->h;
935 sizehints->flags |= PMinSize | PMaxSize;
937 X11_XSetWMNormalHints(display,
data->xwindow, sizehints);
939 X11_XFree(sizehints);
959 X11_XRaiseWindow(display,
data->xwindow);
968 X11_XSync(display, False);
969 X11_XGetWindowAttributes(display,
data->xwindow, &attrs);
971 if ((attrs.width != orig_w) || (attrs.height != orig_h)) {
975 }
else if ((attrs.width ==
window->w) && (attrs.height ==
window->h)) {
1005 Atom _NET_WM_WINDOW_OPACITY =
data->videodata->_NET_WM_WINDOW_OPACITY;
1007 if (opacity == 1.0
f) {
1008 X11_XDeleteProperty(display,
data->xwindow, _NET_WM_WINDOW_OPACITY);
1010 const Uint32 FullyOpaque = 0xFFFFFFFF;
1011 const long alpha = (long) ((
double)opacity * (double)FullyOpaque);
1012 X11_XChangeProperty(display,
data->xwindow, _NET_WM_WINDOW_OPACITY, XA_CARDINAL, 32,
1013 PropModeReplace, (
unsigned char *)&
alpha, 1);
1023 Display *display =
data->videodata->display;
1025 X11_XSetTransientForHint(display,
data->xwindow, parent_data->xwindow);
1035 X11_XSetInputFocus(display,
data->xwindow, RevertToNone, CurrentTime);
1036 X11_XFlush(display);
1050 Display *display =
data->videodata->display;
1053 SetWindowBordered(display, displaydata->screen,
data->xwindow, bordered);
1054 X11_XFlush(display);
1057 XWindowAttributes attr;
1059 X11_XSync(display, False);
1060 X11_XGetWindowAttributes(display,
data->xwindow, &attr);
1061 }
while (attr.map_state != IsViewable);
1064 X11_XSetInputFocus(display,
data->xwindow, RevertToParent, CurrentTime);
1069 X11_XSync(display, False);
1070 X11_XCheckIfEvent(display, &
event, &isUnmapNotify, (XPointer)&
data->xwindow);
1071 X11_XCheckIfEvent(display, &
event, &isMapNotify, (XPointer)&
data->xwindow);
1080 XSizeHints *sizehints = X11_XAllocSizeHints();
1083 X11_XGetWMNormalHints(display,
data->xwindow, sizehints, &userhints);
1087 const int maxsize = 0x7FFFFFFF;
1088 sizehints->min_width =
window->min_w;
1089 sizehints->min_height =
window->min_h;
1090 sizehints->max_width = (
window->max_w == 0) ? maxsize :
window->max_w;
1091 sizehints->max_height = (
window->max_h == 0) ? maxsize :
window->max_h;
1093 sizehints->min_width =
window->w;
1094 sizehints->min_height =
window->h;
1095 sizehints->max_width =
window->w;
1096 sizehints->max_height =
window->h;
1098 sizehints->flags |= PMinSize | PMaxSize;
1100 X11_XSetWMNormalHints(display,
data->xwindow, sizehints);
1102 X11_XFree(sizehints);
1107 X11_XRaiseWindow(display,
data->xwindow);
1109 X11_XFlush(display);
1120 X11_XMapRaised(display,
data->xwindow);
1125 X11_XIfEvent(display, &
event, &isMapNotify, (XPointer)&
data->xwindow);
1126 X11_XFlush(display);
1129 if (!
data->videodata->net_wm) {
1131 X11_XSetInputFocus(display,
data->xwindow, RevertToNone, CurrentTime);
1132 X11_XFlush(display);
1141 Display *display =
data->videodata->display;
1145 X11_XWithdrawWindow(display,
data->xwindow, displaydata->screen);
1148 X11_XIfEvent(display, &
event, &isUnmapNotify, (XPointer)&
data->xwindow);
1149 X11_XFlush(display);
1159 Display *display =
data->videodata->display;
1160 Atom _NET_ACTIVE_WINDOW =
data->videodata->_NET_ACTIVE_WINDOW;
1168 e.xany.type = ClientMessage;
1169 e.xclient.message_type = _NET_ACTIVE_WINDOW;
1170 e.xclient.format = 32;
1171 e.xclient.window =
data->xwindow;
1172 e.xclient.data.l[0] = 1;
1173 e.xclient.data.l[1] =
data->user_time;
1174 e.xclient.data.l[2] = 0;
1176 X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0,
1177 SubstructureNotifyMask | SubstructureRedirectMask, &
e);
1179 X11_XFlush(display);
1189 X11_XRaiseWindow(display,
data->xwindow);
1191 X11_XFlush(display);
1200 Display *display =
data->videodata->display;
1201 Atom _NET_WM_STATE =
data->videodata->_NET_WM_STATE;
1202 Atom _NET_WM_STATE_MAXIMIZED_VERT =
data->videodata->_NET_WM_STATE_MAXIMIZED_VERT;
1203 Atom _NET_WM_STATE_MAXIMIZED_HORZ =
data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
1215 e.xany.type = ClientMessage;
1216 e.xclient.message_type = _NET_WM_STATE;
1217 e.xclient.format = 32;
1218 e.xclient.window =
data->xwindow;
1219 e.xclient.data.l[0] =
1220 maximized ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
1221 e.xclient.data.l[1] = _NET_WM_STATE_MAXIMIZED_VERT;
1222 e.xclient.data.l[2] = _NET_WM_STATE_MAXIMIZED_HORZ;
1223 e.xclient.data.l[3] = 0
l;
1225 X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0,
1226 SubstructureNotifyMask | SubstructureRedirectMask, &
e);
1230 X11_XFlush(display);
1245 Display *display =
data->videodata->display;
1247 X11_XIconifyWindow(display,
data->xwindow, displaydata->screen);
1248 X11_XFlush(display);
1265 Display *display =
data->videodata->display;
1266 Atom _NET_WM_STATE =
data->videodata->_NET_WM_STATE;
1267 Atom _NET_WM_STATE_FULLSCREEN =
data->videodata->_NET_WM_STATE_FULLSCREEN;
1275 XSizeHints *sizehints = X11_XAllocSizeHints();
1277 X11_XGetWMNormalHints(display,
data->xwindow, sizehints, &
flags);
1281 sizehints->flags &= ~(PMinSize | PMaxSize);
1284 sizehints->flags |= PMinSize | PMaxSize;
1285 sizehints->min_width = sizehints->max_width =
window->windowed.w;
1286 sizehints->min_height = sizehints->max_height =
window->windowed.h;
1288 X11_XSetWMNormalHints(display,
data->xwindow, sizehints);
1289 X11_XFree(sizehints);
1293 e.xany.type = ClientMessage;
1294 e.xclient.message_type = _NET_WM_STATE;
1295 e.xclient.format = 32;
1296 e.xclient.window =
data->xwindow;
1297 e.xclient.data.l[0] =
1298 fullscreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
1299 e.xclient.data.l[1] = _NET_WM_STATE_FULLSCREEN;
1300 e.xclient.data.l[3] = 0
l;
1302 X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0,
1303 SubstructureNotifyMask | SubstructureRedirectMask, &
e);
1309 e.xany.type = ClientMessage;
1310 e.xclient.message_type = _NET_WM_STATE;
1311 e.xclient.format = 32;
1312 e.xclient.window =
data->xwindow;
1313 e.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
1314 e.xclient.data.l[1] =
data->videodata->_NET_WM_STATE_MAXIMIZED_VERT;
1315 e.xclient.data.l[2] =
data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
1316 e.xclient.data.l[3] = 0
l;
1317 X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0,
1318 SubstructureNotifyMask | SubstructureRedirectMask, &
e);
1332 if (
data->visual->class == DirectColor) {
1334 X11_XInstallColormap(display,
data->colormap);
1336 X11_XUninstallColormap(display,
data->colormap);
1340 X11_XFlush(display);
1349 Visual *visual =
data->visual;
1350 Display *display =
data->videodata->display;
1351 const int screen = displaydata->screen;
1352 Window root = RootWindow(display,
screen);
1353 const int def_vis = (visual == DefaultVisual(display,
screen));
1354 unsigned long xattrmask = 0;
1355 XSetWindowAttributes xattr;
1359 if (
data->fswindow ) {
1366 xattr.override_redirect = True;
1367 xattrmask |= CWOverrideRedirect;
1368 xattr.background_pixel = def_vis ? BlackPixel(display,
screen) : 0;
1369 xattrmask |= CWBackPixel;
1370 xattr.border_pixel = 0;
1371 xattrmask |= CWBorderPixel;
1372 xattr.colormap =
data->colormap;
1373 xattrmask |= CWColormap;
1375 data->fswindow = X11_XCreateWindow(display, root,
1377 displaydata->depth, InputOutput,
1378 visual, xattrmask, &xattr);
1380 X11_XSelectInput(display,
data->fswindow, StructureNotifyMask);
1381 X11_XSetWindowBackground(display,
data->fswindow, 0);
1382 X11_XInstallColormap(display,
data->colormap);
1383 X11_XClearWindow(display,
data->fswindow);
1384 X11_XMapRaised(display,
data->fswindow);
1387 X11_XUngrabPointer(display, CurrentTime);
1388 X11_XWarpPointer(display, None, root, 0, 0, 0, 0,
rect.
x,
rect.
y);
1391 X11_XIfEvent(display, &ev, &isMapNotify, (XPointer)&
data->fswindow);
1392 X11_XCheckIfEvent(display, &ev, &isUnmapNotify, (XPointer)&
data->fswindow);
1394 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
1395 if ( displaydata->use_vidmode ) {
1396 X11_XF86VidModeLockModeSwitch(display,
screen, True);
1400 SetWindowBordered(display, displaydata->screen,
data->xwindow,
SDL_FALSE);
1403 X11_XReparentWindow(display,
data->xwindow,
data->fswindow,
1407 X11_XWarpPointer(display, None, root, 0, 0, 0, 0,
rect.
x,
rect.
y);
1412 X11_XWarpPointer(display, None, root, 0, 0, 0, 0,
rect.
x,
rect.
y);
1415 X11_XIfEvent(display, &ev, &isMapNotify, (XPointer)&
data->xwindow);
1416 X11_XCheckIfEvent(display, &ev, &isUnmapNotify, (XPointer)&
data->xwindow);
1426 Display *display =
data->videodata->display;
1427 const int screen = displaydata->screen;
1428 Window root = RootWindow(display,
screen);
1429 Window fswindow =
data->fswindow;
1432 if (!
data->fswindow) {
1436 data->fswindow = None;
1438 #if SDL_VIDEO_DRIVER_X11_VIDMODE
1439 if ( displaydata->use_vidmode ) {
1440 X11_XF86VidModeLockModeSwitch(display,
screen, False);
1449 X11_XSync(display, False);
1450 X11_XCheckIfEvent(display, &ev, &isMapNotify, (XPointer)&
data->xwindow);
1451 X11_XCheckIfEvent(display, &ev, &isUnmapNotify, (XPointer)&
data->xwindow);
1453 SetWindowBordered(display,
screen,
data->xwindow,
1456 X11_XWithdrawWindow(display, fswindow,
screen);
1459 X11_XIfEvent(display, &ev, &isUnmapNotify, (XPointer)&fswindow);
1460 X11_XDestroyWindow(display, fswindow);
1469 const char *env =
SDL_getenv(
"SDL_VIDEO_X11_LEGACY_FULLSCREEN");
1475 if ( displaydata->use_vidmode ) {
1477 }
else if ( !videodata->
net_wm ) {
1488 X11_BeginWindowFullscreenLegacy(
_this,
window, _display);
1490 X11_EndWindowFullscreenLegacy(
_this,
window, _display);
1493 X11_SetWindowFullscreenViaWM(
_this,
window, _display, fullscreen);
1503 Visual *visual =
data->visual;
1504 Colormap colormap =
data->colormap;
1507 int rmask, gmask, bmask;
1508 int rshift, gshift, bshift;
1511 if (visual->class != DirectColor) {
1512 return SDL_SetError(
"Window doesn't have DirectColor visual");
1515 ncolors = visual->map_entries;
1516 colorcells =
SDL_malloc(ncolors *
sizeof(XColor));
1522 rmask = visual->red_mask;
1523 while (0 == (rmask & 1)) {
1529 gmask = visual->green_mask;
1530 while (0 == (gmask & 1)) {
1536 bmask = visual->blue_mask;
1537 while (0 == (bmask & 1)) {
1543 for (
i = 0;
i < ncolors;
i++) {
1544 Uint32 rbits = (rmask *
i) / (ncolors - 1);
1545 Uint32 gbits = (gmask *
i) / (ncolors - 1);
1546 Uint32 bbits = (bmask *
i) / (ncolors - 1);
1547 Uint32 pix = (rbits << rshift) | (gbits << gshift) | (bbits << bshift);
1549 colorcells[
i].pixel = pix;
1551 colorcells[
i].red = ramp[(0 * 256) +
i];
1552 colorcells[
i].green = ramp[(1 * 256) +
i];
1553 colorcells[
i].blue = ramp[(2 * 256) +
i];
1555 colorcells[
i].flags = DoRed | DoGreen | DoBlue;
1558 X11_XStoreColors(display, colormap, colorcells, ncolors);
1559 X11_XFlush(display);
1577 oldstyle_fullscreen = X11_IsWindowLegacyFullscreen(
_this,
window);
1579 if (oldstyle_fullscreen || grabbed) {
1581 if (!
data->videodata->broken_pointer_grab) {
1582 const unsigned int mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask;
1587 for (attempts = 0; attempts < 100; attempts++) {
1588 result = X11_XGrabPointer(display,
data->xwindow, True,
mask, GrabModeAsync,
1589 GrabModeAsync,
data->xwindow, None, CurrentTime);
1590 if (
result == GrabSuccess) {
1596 if (
result != GrabSuccess) {
1603 X11_XRaiseWindow(display,
data->xwindow);
1612 grab_keyboard = oldstyle_fullscreen;
1614 if (grab_keyboard) {
1615 X11_XGrabKeyboard(display,
data->xwindow, True, GrabModeAsync,
1616 GrabModeAsync, CurrentTime);
1619 X11_XUngrabPointer(display, CurrentTime);
1620 X11_XUngrabKeyboard(display, CurrentTime);
1622 X11_XSync(display, False);
1632 Display *display = videodata->
display;
1638 for (
i = 0;
i < numwindows; ++
i) {
1640 windowlist[
i] = windowlist[numwindows - 1];
1641 windowlist[numwindows - 1] =
NULL;
1647 #ifdef X_HAVE_UTF8_STRING
1649 X11_XDestroyIC(
data->ic);
1652 if (
data->created) {
1653 X11_XDestroyWindow(display,
data->xwindow);
1654 X11_XFlush(display);
1670 info->
info.
x11.display = display;
1674 SDL_SetError(
"Application not compiled with SDL %d.%d",
1691 Atom XdndAware = X11_XInternAtom(display,
"XdndAware", False);
1694 Atom xdnd_version = 5;
1695 X11_XChangeProperty(display,
data->xwindow, XdndAware, XA_ATOM, 32,
1696 PropModeReplace, (
unsigned char*)&xdnd_version, 1);
1698 X11_XDeleteProperty(display,
data->xwindow, XdndAware);