1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
#ifndef HEADLESS
#include "myX11.h"
#include <string.h>
#include <string>
#include <map>
#include <SDL.h>
#if !defined(HEADLESS)
#include <SDL_syswm.h>
#endif
void MyX11GetFrameBorderOffset(Display* display, Window& window, int* out_left, int* out_top)
{
// XGetWindowProperty stuff
Atom actual_type;
int actual_format;
unsigned long nitems;
unsigned long bytes_remaining;
int* data;
int status;
Atom net_frame_extents = XInternAtom(display, "_NET_FRAME_EXTENTS", True);
status = XGetWindowProperty(
display,
window,
net_frame_extents,
0, // long_offset
4, // long_length - we expect 4 32-bit values for _NET_FRAME_EXTENTS
false, // delete
AnyPropertyType,
&actual_type,
&actual_format,
&nitems,
&bytes_remaining,
(unsigned char**)&data);
*out_left = *out_top = 0;
if (status == Success) {
if ((nitems == 4) && (bytes_remaining == 0)) {
*out_left = data[0];
*out_top = data[2];
}
XFree(data);
}
}
static const int windowStates = 8;
static const std::string windowStatesStr[windowStates] = {
"_NET_WM_STATE_STICKY",
"_NET_WM_STATE_MAXIMIZED_VERT",
"_NET_WM_STATE_MAXIMIZED_HORZ",
"_NET_WM_STATE_SHADED",
"_NET_WM_STATE_HIDDEN",
"_NET_WM_STATE_FULLSCREEN",
"_NET_WM_STATE_ABOVE",
"_NET_WM_STATE_BELOW"
};
int MyX11GetWindowState(Display* display, Window& window)
{
// XGetWindowProperty stuff
Atom actual_type;
int actual_format;
unsigned long nitems;
unsigned long bytes_remaining;
Atom* data;
int status;
Atom atom = XInternAtom(display, "_NET_WM_STATE", true);
Atom windowStatesAtoms[windowStates];
std::map<Atom,int> windowStatesInt;
for (int i=0; i<windowStates; i++) {
windowStatesAtoms[i] = XInternAtom(display, windowStatesStr[i].c_str(), false);
windowStatesInt[windowStatesAtoms[i]] = 1<<i;
}
status = XGetWindowProperty(
display,
window,
atom,
0,
20,
false,
AnyPropertyType,
&actual_type,
&actual_format,
&nitems,
&bytes_remaining,
(unsigned char**)&data);
if (status == Success) {
int windowState = 0;
for (int i=0; i<nitems; i++) {
Atom& a = data[i];
std::map<Atom,int>::iterator it = windowStatesInt.find(a);
if (it != windowStatesInt.end()) {
windowState += it->second;
}
}
XFree(data);
return windowState;
}
return 0;
}
void MyX11SetWindowState(Display* display, Window& window, int windowState)
{
if (windowState <= 0)
return;
Atom windowStatesAtoms[windowStates];
for (int i=0; i<windowStates; i++) {
windowStatesAtoms[i] = XInternAtom(display, windowStatesStr[i].c_str(), false);
}
Atom wm_state = XInternAtom(display, "_NET_WM_STATE", False);
XEvent xev;
memset(&xev, 0, sizeof(xev));
xev.type = ClientMessage;
xev.xclient.window = window;
xev.xclient.message_type = wm_state;
xev.xclient.format = 32;
xev.xclient.data.l[2] = 0;
xev.xclient.data.l[3] = 0;
Window root = XDefaultRootWindow(display);
static const int _NET_WM_STATE_REMOVE = 0;
static const int _NET_WM_STATE_ADD = 1;
for (int i=0; i<windowStates; i++) {
if (1<<i & windowState) {
xev.xclient.data.l[0] = _NET_WM_STATE_ADD;
xev.xclient.data.l[1] = windowStatesAtoms[i];
XSendEvent(display, root, false, SubstructureNotifyMask, &xev);
} else {
xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
xev.xclient.data.l[1] = windowStatesAtoms[i];
XSendEvent(display, root, false, SubstructureNotifyMask, &xev);
}
}
}
#endif // #ifndef HEADLESS
|