summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/x11/detect.py10
-rw-r--r--platform/x11/os_x11.cpp228
-rw-r--r--platform/x11/os_x11.h26
3 files changed, 258 insertions, 6 deletions
diff --git a/platform/x11/detect.py b/platform/x11/detect.py
index 8264196a41..773928c72d 100644
--- a/platform/x11/detect.py
+++ b/platform/x11/detect.py
@@ -38,6 +38,11 @@ def can_build():
if (x11_error):
print("xcursor not found.. x11 disabled.")
return False
+
+ x11_error=os.system("pkg-config xinerama --modversion > /dev/null ")
+ if (x11_error):
+ print("xinerama not found.. x11 disabled.")
+ return False
return True # X11 enabled
@@ -48,6 +53,7 @@ def get_opts():
('use_llvm','Use llvm compiler','no'),
('use_sanitizer','Use llvm compiler sanitize address','no'),
('pulseaudio','Detect & Use pulseaudio','yes'),
+ ('experimental_wm_api', 'Use experimental window management API','no'),
]
def get_flags():
@@ -150,3 +156,7 @@ def configure(env):
env.Append( BUILDERS = { 'GLSL120GLES' : env.Builder(action = methods.build_gles2_headers, suffix = 'glsl.h',src_suffix = '.glsl') } )
#env.Append( BUILDERS = { 'HLSL9' : env.Builder(action = methods.build_hlsl_dx9_headers, suffix = 'hlsl.h',src_suffix = '.hlsl') } )
+ if(env["experimental_wm_api"]=="yes"):
+ env.Append(CPPFLAGS=['-DEXPERIMENTAL_WM_API'])
+ env.ParseConfig('pkg-config xinerama --cflags --libs')
+
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index a40af8d2a9..d395e99210 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -36,6 +36,9 @@
#include "servers/physics/physics_server_sw.h"
#include "X11/Xutil.h"
+#ifdef EXPERIMENTAL_WM_API
+#include "X11/extensions/Xinerama.h"
+#endif
#include "main/main.h"
@@ -162,6 +165,7 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
// maybe contextgl wants to be in charge of creating the window
//print_line("def videomode "+itos(current_videomode.width)+","+itos(current_videomode.height));
#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
+
context_gl = memnew( ContextGL_X11( x11_display, x11_window,current_videomode, false ) );
context_gl->initialize();
@@ -181,7 +185,8 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
// borderless fullscreen window mode
if (current_videomode.fullscreen) {
- // needed for lxde/openbox, possibly others
+#ifndef EXPERIMENTAL_WM_API
+ // needed for lxde/openbox, possibly others
Hints hints;
Atom property;
hints.flags = 2;
@@ -208,6 +213,14 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
xev.xclient.data.l[2] = 0;
XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev);
+#else
+ window_data.position.x = 0;
+ window_data.position.y = 0;
+ window_data.size.width = 800;
+ window_data.size.height = 600;
+ set_wm_border(false);
+ set_wm_fullscreen(true);
+#endif
}
// disable resizeable window
@@ -520,6 +533,213 @@ void OS_X11::get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen) cons
}
+#ifdef EXPERIMENTAL_WM_API
+void OS_X11::set_wm_border(bool p_enabled) {
+ // needed for lxde/openbox, possibly others
+ Hints hints;
+ Atom property;
+ hints.flags = 2;
+ hints.decorations = p_enabled ? 1L : 0L;;
+ property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True);
+ XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5);
+ XMapRaised(x11_display, x11_window);
+ //XMoveResizeWindow(x11_display, x11_window, 0, 0, 800, 800);
+}
+
+void OS_X11::set_wm_fullscreen(bool p_enabled) {
+ // code for netwm-compliants
+ XEvent xev;
+ Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False);
+ Atom wm_fullscreen = XInternAtom(x11_display, "_NET_WM_STATE_FULLSCREEN", 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 ? 1L : 0L;
+ xev.xclient.data.l[1] = wm_fullscreen;
+ xev.xclient.data.l[2] = 0;
+
+ XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev);
+}
+
+int OS_X11::get_screen_count() const {
+ int event_base, error_base;
+ const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base);
+ if( !ext_okay ) return 0;
+
+ int count;
+ XineramaScreenInfo* xsi = XineramaQueryScreens(x11_display, &count);
+ XFree(xsi);
+ return count;
+}
+
+int OS_X11::get_screen() const {
+ int x,y;
+ Window child;
+ XTranslateCoordinates( x11_display, x11_window, DefaultRootWindow(x11_display), 0, 0, &x, &y, &child);
+
+ int count = get_screen_count();
+ for(int i=0; i<count; i++) {
+ Point2i pos = get_screen_position(i);
+ Size2i size = get_screen_size(i);
+ if( (x >= pos.x && x <pos.x + size.width) && (y >= pos.y && y < pos.y + size.height) )
+ return i;
+ }
+ return 0;
+}
+
+void OS_X11::set_screen(int p_screen) {
+ int count = get_screen_count();
+ if(p_screen >= count) return;
+
+ if( current_videomode.fullscreen ) {
+ Point2i position = get_screen_position(p_screen);
+ Size2i size = get_screen_size(p_screen);
+
+ XMoveResizeWindow(x11_display, x11_window, position.x, position.y, size.x, size.y);
+ }
+ else {
+ if( p_screen != get_screen() ) {
+ Point2i position = get_screen_position(p_screen);
+ XMoveWindow(x11_display, x11_window, position.x, position.y);
+ }
+ }
+}
+
+Point2 OS_X11::get_screen_position(int p_screen) const {
+ int event_base, error_base;
+ const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base);
+ if( !ext_okay ) return Point2i(0,0);
+
+ int count;
+ XineramaScreenInfo* xsi = XineramaQueryScreens(x11_display, &count);
+ if( p_screen >= count ) return Point2i(0,0);
+
+ Point2i position = Point2i(xsi[p_screen].x_org, xsi[p_screen].y_org);
+ XFree(xsi);
+ return position;
+}
+
+Size2 OS_X11::get_screen_size(int p_screen) const {
+ int event_base, error_base;
+ const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base);
+ if( !ext_okay ) return Size2i(0,0);
+
+ int count;
+ XineramaScreenInfo* xsi = XineramaQueryScreens(x11_display, &count);
+ if( p_screen >= count ) return Size2i(0,0);
+
+ Size2i size = Point2i(xsi[p_screen].width, xsi[p_screen].height);
+ XFree(xsi);
+ return size;
+}
+
+
+Point2 OS_X11::get_window_position() const {
+ int x,y;
+ Window child;
+ XTranslateCoordinates( x11_display, x11_window, DefaultRootWindow(x11_display), 0, 0, &x, &y, &child);
+ return Point2i(x,y);
+}
+
+void OS_X11::set_window_position(const Point2& p_position) {
+
+ if( current_videomode.fullscreen )
+ return;
+
+ // _NET_FRAME_EXTENTS
+ 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(
+ x11_display,
+ x11_window,
+ property,
+ 0,
+ 32,
+ False,
+ AnyPropertyType,
+ &type,
+ &format,
+ &len,
+ &remaining,
+ &data
+ );
+
+ long left = 0L;
+ long top = 0L;
+
+ if( result == Success ) {
+ long *extends = (long *) data;
+
+ left = extends[0];
+ top = extends[2];
+
+ XFree(data);
+ data = NULL;
+ }
+
+ XMoveWindow(x11_display,x11_window,p_position.x - left,p_position.y - top);
+}
+
+Size2 OS_X11::get_window_size() const {
+ XWindowAttributes xwa;
+ XGetWindowAttributes(x11_display, x11_window, &xwa);
+ return Size2i(xwa.width, xwa.height);
+}
+
+void OS_X11::set_window_size(const Size2 p_size) {
+ if( current_videomode.fullscreen )
+ return;
+
+ XResizeWindow(x11_display, x11_window, p_size.x, p_size.y);
+}
+
+void OS_X11::set_fullscreen(bool p_enabled) {
+
+ if(p_enabled && current_videomode.fullscreen)
+ return;
+
+ if(p_enabled) {
+ window_data.size = get_window_size();
+ window_data.position = get_window_position();
+
+ int screen = get_screen();
+ Size2i size = get_screen_size(screen);
+ Point2i position = get_screen_position(screen);
+
+ set_wm_border(false);
+ set_wm_fullscreen(true);
+ XMoveResizeWindow(x11_display, x11_window, position.x, position.y, size.x, size.y);
+
+ current_videomode.fullscreen = True;
+ } else {
+ set_wm_fullscreen(false);
+ set_wm_border(true);
+ XMoveResizeWindow(x11_display, x11_window,
+ window_data.position.x,
+ window_data.position.y,
+ window_data.size.width,
+ window_data.size.height);
+
+ current_videomode.fullscreen = False;
+ }
+
+ visual_server->init();
+}
+
+bool OS_X11::is_fullscreen() const {
+ return current_videomode.fullscreen;
+}
+#endif
InputModifierState OS_X11::get_key_modifier_state(unsigned int p_x11_state) {
@@ -856,7 +1076,7 @@ void OS_X11::process_xevents() {
if (mouse_mode==MOUSE_MODE_CAPTURED) {
#if 1
- Vector2 c = Point2i(current_videomode.width/2,current_videomode.height/2);
+ //Vector2 c = Point2i(current_videomode.width/2,current_videomode.height/2);
if (pos==Point2i(current_videomode.width/2,current_videomode.height/2)) {
//this sucks, it's a hack, etc and is a little inaccurate, etc.
//but nothing I can do, X11 sucks.
@@ -865,9 +1085,9 @@ void OS_X11::process_xevents() {
break;
}
- Point2i ncenter = pos;
+ Point2i new_center = pos;
pos = last_mouse_pos + ( pos-center );
- center=ncenter;
+ center=new_center;
do_mouse_warp=true;
#else
//Dear X11, thanks for making my life miserable
diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h
index dd2476ec1b..72d212c131 100644
--- a/platform/x11/os_x11.h
+++ b/platform/x11/os_x11.h
@@ -159,6 +159,14 @@ class OS_X11 : public OS_Unix {
int joystick_count;
Joystick joysticks[JOYSTICKS_MAX];
+#ifdef EXPERIMENTAL_WM_API
+ struct {
+ Point2i position;
+ Size2i size;
+ } window_data;
+ void set_wm_border(bool p_enabled);
+ void set_wm_fullscreen(bool p_enabled);
+#endif
protected:
@@ -166,8 +174,8 @@ protected:
virtual const char * get_video_driver_name(int p_driver) const;
virtual VideoMode get_default_video_mode() const;
- virtual int get_audio_driver_count() const;
- virtual const char * get_audio_driver_name(int p_driver) const;
+ virtual int get_audio_driver_count() const;
+ virtual const char * get_audio_driver_name(int p_driver) const;
virtual void initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver);
virtual void finalize();
@@ -178,6 +186,7 @@ protected:
void process_joysticks();
void close_joystick(int p_id = -1);
+
public:
virtual String get_name();
@@ -213,6 +222,19 @@ public:
virtual VideoMode get_video_mode(int p_screen=0) const;
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen=0) const;
+#ifdef EXPERIMENTAL_WM_API
+ virtual int get_screen_count() const;
+ virtual int get_screen() const;
+ virtual void set_screen(int p_screen);
+ virtual Point2 get_screen_position(int p_screen=0) const;
+ virtual Size2 get_screen_size(int p_screen=0) const;
+ virtual Point2 get_window_position() const;
+ virtual void set_window_position(const Point2& p_position);
+ virtual Size2 get_window_size() const;
+ virtual void set_window_size(const Size2 p_size);
+ virtual void set_fullscreen(bool p_enabled);
+ virtual bool is_fullscreen() const;
+#endif
virtual void move_window_to_foreground();
void run();