summaryrefslogtreecommitdiff
path: root/platform/x11/os_x11.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/x11/os_x11.cpp')
-rw-r--r--platform/x11/os_x11.cpp137
1 files changed, 131 insertions, 6 deletions
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index c6fdc24768..ef92d190c9 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -37,7 +37,16 @@
#include "X11/Xutil.h"
#ifdef EXPERIMENTAL_WM_API
+#include "X11/Xatom.h"
#include "X11/extensions/Xinerama.h"
+// ICCCM
+#define WM_NormalState 1L // window normal state
+#define WM_IconicState 3L // window minimized
+
+// EWMH
+#define _NET_WM_STATE_REMOVE 0L // remove/unset property
+#define _NET_WM_STATE_ADD 1L // add/set property
+#define _NET_WM_STATE_TOGGLE 2L // toggle property
#endif
#include "main/main.h"
@@ -214,6 +223,8 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev);
#else
+ minimized = false;
+ minimized = false;
window_data.position.x = 0;
window_data.position.y = 0;
window_data.size.width = 800;
@@ -549,7 +560,7 @@ void OS_X11::set_wm_border(bool p_enabled) {
}
void OS_X11::set_wm_fullscreen(bool p_enabled) {
- // code for netwm-compliants
+ // Using EWMH -- Extened Window Manager Hints
XEvent xev;
Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False);
Atom wm_fullscreen = XInternAtom(x11_display, "_NET_WM_STATE_FULLSCREEN", False);
@@ -559,7 +570,7 @@ void OS_X11::set_wm_fullscreen(bool p_enabled) {
xev.xclient.window = x11_window;
xev.xclient.message_type = wm_state;
xev.xclient.format = 32;
- xev.xclient.data.l[0] = p_enabled ? 1L : 0L;
+ xev.xclient.data.l[0] = p_enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
xev.xclient.data.l[1] = wm_fullscreen;
xev.xclient.data.l[2] = 0;
@@ -567,6 +578,7 @@ void OS_X11::set_wm_fullscreen(bool p_enabled) {
}
int OS_X11::get_screen_count() const {
+ // Using Xinerama Extension
int event_base, error_base;
const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base);
if( !ext_okay ) return 0;
@@ -611,6 +623,7 @@ void OS_X11::set_screen(int p_screen) {
}
Point2 OS_X11::get_screen_position(int p_screen) const {
+ // Using Xinerama Extension
int event_base, error_base;
const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base);
if( !ext_okay ) return Point2i(0,0);
@@ -625,6 +638,7 @@ Point2 OS_X11::get_screen_position(int p_screen) const {
}
Size2 OS_X11::get_screen_size(int p_screen) const {
+ // Using Xinerama Extension
int event_base, error_base;
const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base);
if( !ext_okay ) return Size2i(0,0);
@@ -651,14 +665,14 @@ void OS_X11::set_window_position(const Point2& p_position) {
if( current_videomode.fullscreen )
return;
- // _NET_FRAME_EXTENTS
+ // Using EWMH -- Extended Window Manager Hints
+ // to get the size of the decoration
Atom property = XInternAtom(x11_display,"_NET_FRAME_EXTENTS", True);
Atom type;
int format;
unsigned long len;
unsigned long remaining;
unsigned char *data = NULL;
- //long *extends;
int result;
result = XGetWindowProperty(
@@ -759,7 +773,6 @@ void OS_X11::set_resizable(bool p_enabled) {
xsh->max_width = xwa.width;
xsh->min_height = xwa.height;
xsh->max_height = xwa.height;
- printf("%d %d\n", xwa.width, xwa.height);
}
XSetWMNormalHints(x11_display, x11_window, xsh);
XFree(xsh);
@@ -770,6 +783,119 @@ void OS_X11::set_resizable(bool p_enabled) {
bool OS_X11::is_resizable() const {
return current_videomode.resizable;
}
+
+void OS_X11::set_minimized(bool p_enabled) {
+ // Using ICCCM -- Inter-Client Communication Conventions Manual
+ XEvent xev;
+ Atom wm_change = XInternAtom(x11_display, "WM_CHANGE_STATE", False);
+
+ memset(&xev, 0, sizeof(xev));
+ xev.type = ClientMessage;
+ xev.xclient.window = x11_window;
+ xev.xclient.message_type = wm_change;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = p_enabled ? WM_IconicState : WM_NormalState;
+
+ XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev);
+}
+
+bool OS_X11::is_minimized() const {
+ // Using ICCCM -- Inter-Client Communication Conventions Manual
+ Atom property = XInternAtom(x11_display,"WM_STATE", True);
+ Atom type;
+ int format;
+ unsigned long len;
+ unsigned long remaining;
+ unsigned char *data = NULL;
+
+ int result = XGetWindowProperty(
+ x11_display,
+ x11_window,
+ property,
+ 0,
+ 32,
+ False,
+ AnyPropertyType,
+ &type,
+ &format,
+ &len,
+ &remaining,
+ &data
+ );
+
+ if( result == Success ) {
+ long *state = (long *) data;
+ if( state[0] == 3L )
+ return true;
+ }
+ return false;
+}
+
+void OS_X11::set_maximized(bool p_enabled) {
+ // Using EWMH -- Extended Window Manager Hints
+ XEvent xev;
+ Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False);
+ Atom wm_max_horz = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
+ Atom wm_max_vert = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_VERT", False);
+
+ memset(&xev, 0, sizeof(xev));
+ xev.type = ClientMessage;
+ xev.xclient.window = x11_window;
+ xev.xclient.message_type = wm_state;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = p_enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
+ xev.xclient.data.l[1] = wm_max_horz;
+ xev.xclient.data.l[2] = wm_max_vert;
+
+ XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev);
+
+ maximized = p_enabled;
+}
+
+bool OS_X11::is_maximized() const {
+ // Using EWMH -- Extended Window Manager Hints
+ Atom property = XInternAtom(x11_display,"_NET_WM_STATE",False );
+ Atom type;
+ int format;
+ unsigned long len;
+ unsigned long remaining;
+ unsigned char *data = NULL;
+
+ int result = XGetWindowProperty(
+ x11_display,
+ x11_window,
+ property,
+ 0,
+ 1024,
+ False,
+ XA_ATOM,
+ &type,
+ &format,
+ &len,
+ &remaining,
+ &data
+ );
+
+ if(result == Success) {
+ Atom *atoms = (Atom*) data;
+ Atom wm_max_horz = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
+ Atom wm_max_vert = XInternAtom(x11_display, "_NET_WM_STATE_MAXIMIZED_VERT", False);
+ bool found_wm_max_horz = false;
+ bool found_wm_max_vert = false;
+
+ for( unsigned int i=0; i < len; i++ ) {
+ if( atoms[i] == wm_max_horz )
+ found_wm_max_horz = true;
+ if( atoms[i] == wm_max_vert )
+ found_wm_max_vert = true;
+
+ if( found_wm_max_horz && found_wm_max_vert )
+ return true;
+ }
+ }
+
+ return false;
+}
#endif
InputModifierState OS_X11::get_key_modifier_state(unsigned int p_x11_state) {
@@ -1719,4 +1845,3 @@ OS_X11::OS_X11() {
xim_style=0L;
mouse_mode=MOUSE_MODE_VISIBLE;
};
-