|
@@ -36,6 +36,17 @@
|
|
|
#include "servers/physics/physics_server_sw.h"
|
|
|
|
|
|
#include "X11/Xutil.h"
|
|
|
+#ifdef NEW_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"
|
|
|
|
|
|
|
|
@@ -56,7 +67,7 @@
|
|
|
|
|
|
|
|
|
#include <X11/Xatom.h>
|
|
|
-#include "os/pc_joystick_map.h"
|
|
|
+//#include "os/pc_joystick_map.h"
|
|
|
|
|
|
#undef CursorShape
|
|
|
|
|
@@ -117,10 +128,10 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
|
|
|
|
|
|
if (xim == NULL) {
|
|
|
WARN_PRINT("XOpenIM failed");
|
|
|
- xim_style=NULL;
|
|
|
+ xim_style=0L;
|
|
|
} else {
|
|
|
::XIMStyles *xim_styles=NULL;
|
|
|
- xim_style=0;
|
|
|
+ xim_style=0L;
|
|
|
char *imvalret=NULL;
|
|
|
imvalret = XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL);
|
|
|
if (imvalret != NULL || xim_styles == NULL) {
|
|
@@ -128,7 +139,7 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
|
|
|
}
|
|
|
|
|
|
if (xim_styles) {
|
|
|
- xim_style = 0;
|
|
|
+ xim_style = 0L;
|
|
|
for (int i=0;i<xim_styles->count_styles;i++) {
|
|
|
|
|
|
if (xim_styles->supported_styles[i] ==
|
|
@@ -162,14 +173,11 @@ 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();
|
|
|
|
|
|
- if (true) {
|
|
|
- rasterizer = memnew( RasterizerGLES2 );
|
|
|
- } else {
|
|
|
- //rasterizer = memnew( RasterizerGLES1 );
|
|
|
- };
|
|
|
+ rasterizer = memnew( RasterizerGLES2 );
|
|
|
|
|
|
#endif
|
|
|
visual_server = memnew( VisualServerRaster(rasterizer) );
|
|
@@ -179,9 +187,10 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
|
|
|
visual_server =memnew(VisualServerWrapMT(visual_server,get_render_thread_mode()==RENDER_SEPARATE_THREAD));
|
|
|
}
|
|
|
|
|
|
+#ifndef NEW_WM_API
|
|
|
// borderless fullscreen window mode
|
|
|
if (current_videomode.fullscreen) {
|
|
|
- // needed for lxde/openbox, possibly others
|
|
|
+ // needed for lxde/openbox, possibly others
|
|
|
Hints hints;
|
|
|
Atom property;
|
|
|
hints.flags = 2;
|
|
@@ -210,7 +219,7 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
|
|
|
XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev);
|
|
|
}
|
|
|
|
|
|
- // disable resizeable window
|
|
|
+ // disable resizable window
|
|
|
if (!current_videomode.resizable) {
|
|
|
XSizeHints *xsh;
|
|
|
xsh = XAllocSizeHints();
|
|
@@ -226,7 +235,25 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
|
|
|
xsh->min_height = xwa.height;
|
|
|
xsh->max_height = xwa.height;
|
|
|
XSetWMNormalHints(x11_display, x11_window, xsh);
|
|
|
+ XFree(xsh);
|
|
|
}
|
|
|
+#else
|
|
|
+ capture_idle = 0;
|
|
|
+ minimized = false;
|
|
|
+ maximized = false;
|
|
|
+
|
|
|
+ if (current_videomode.fullscreen) {
|
|
|
+ //set_wm_border(false);
|
|
|
+ set_wm_fullscreen(true);
|
|
|
+ }
|
|
|
+ if (!current_videomode.resizable) {
|
|
|
+ int screen = get_screen();
|
|
|
+ Size2i screen_size = get_screen_size(screen);
|
|
|
+ set_window_size(screen_size);
|
|
|
+ set_resizable(false);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
|
|
|
AudioDriverManagerSW::get_driver(p_audio_driver)->set_singleton();
|
|
|
|
|
@@ -264,19 +291,20 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
|
|
|
|
|
|
XChangeWindowAttributes(x11_display, x11_window,CWEventMask,&new_attr);
|
|
|
|
|
|
- XClassHint* classHint;
|
|
|
+ XClassHint* classHint;
|
|
|
|
|
|
- /* set the titlebar name */
|
|
|
- XStoreName(x11_display, x11_window, "Godot");
|
|
|
+ /* set the titlebar name */
|
|
|
+ XStoreName(x11_display, x11_window, "Godot");
|
|
|
|
|
|
- /* set the name and class hints for the window manager to use */
|
|
|
- classHint = XAllocClassHint();
|
|
|
- if (classHint) {
|
|
|
- classHint->res_name = "Godot";
|
|
|
- classHint->res_class = "Godot";
|
|
|
- }
|
|
|
- XSetClassHint(x11_display, x11_window, classHint);
|
|
|
- XFree(classHint);
|
|
|
+ /* set the name and class hints for the window manager to use */
|
|
|
+ classHint = XAllocClassHint();
|
|
|
+ if (classHint) {
|
|
|
+ char wmclass[] = "Godot";
|
|
|
+ classHint->res_name = wmclass;
|
|
|
+ classHint->res_class = wmclass;
|
|
|
+ }
|
|
|
+ XSetClassHint(x11_display, x11_window, classHint);
|
|
|
+ XFree(classHint);
|
|
|
|
|
|
wm_delete = XInternAtom(x11_display, "WM_DELETE_WINDOW", true);
|
|
|
XSetWMProtocols(x11_display, x11_window, &wm_delete, 1);
|
|
@@ -468,8 +496,9 @@ void OS_X11::set_mouse_mode(MouseMode p_mode) {
|
|
|
center.y = current_videomode.height/2;
|
|
|
XWarpPointer(x11_display, None, x11_window,
|
|
|
0,0,0,0, (int)center.x, (int)center.y);
|
|
|
- }
|
|
|
|
|
|
+ input->set_mouse_pos(center);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void OS_X11::warp_mouse_pos(const Point2& p_to) {
|
|
@@ -497,7 +526,6 @@ OS::MouseMode OS_X11::get_mouse_mode() const {
|
|
|
|
|
|
|
|
|
int OS_X11::get_mouse_button_state() const {
|
|
|
-
|
|
|
return last_button_state;
|
|
|
}
|
|
|
|
|
@@ -524,6 +552,344 @@ void OS_X11::get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen) cons
|
|
|
|
|
|
}
|
|
|
|
|
|
+#ifdef NEW_WM_API
|
|
|
+#if 0
|
|
|
+// Just now not needed. Can be used for a possible OS.set_border(bool) method
|
|
|
+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);
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
+void OS_X11::set_wm_fullscreen(bool p_enabled) {
|
|
|
+ // 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);
|
|
|
+
|
|
|
+ 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_fullscreen;
|
|
|
+ xev.xclient.data.l[2] = 0;
|
|
|
+
|
|
|
+ XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
|
|
|
+}
|
|
|
+
|
|
|
+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;
|
|
|
+
|
|
|
+ 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 {
|
|
|
+ // 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);
|
|
|
+
|
|
|
+ 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 {
|
|
|
+ // 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);
|
|
|
+
|
|
|
+ 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);
|
|
|
+
|
|
|
+ int screen = get_screen();
|
|
|
+ Point2i screen_position = get_screen_position(screen);
|
|
|
+
|
|
|
+ return Point2i(x-screen_position.x, y-screen_position.y);
|
|
|
+}
|
|
|
+
|
|
|
+void OS_X11::set_window_position(const Point2& p_position) {
|
|
|
+ // 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;
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+
|
|
|
+ int screen = get_screen();
|
|
|
+ Point2i screen_position = get_screen_position(screen);
|
|
|
+
|
|
|
+ left -= screen_position.x;
|
|
|
+ top -= screen_position.y;
|
|
|
+
|
|
|
+ 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) {
|
|
|
+ XResizeWindow(x11_display, x11_window, p_size.x, p_size.y);
|
|
|
+}
|
|
|
+
|
|
|
+void OS_X11::set_fullscreen(bool p_enabled) {
|
|
|
+ set_wm_fullscreen(p_enabled);
|
|
|
+ current_videomode.fullscreen = p_enabled;
|
|
|
+
|
|
|
+ visual_server->init();
|
|
|
+}
|
|
|
+
|
|
|
+bool OS_X11::is_fullscreen() const {
|
|
|
+ return current_videomode.fullscreen;
|
|
|
+}
|
|
|
+
|
|
|
+void OS_X11::set_resizable(bool p_enabled) {
|
|
|
+ XSizeHints *xsh;
|
|
|
+ xsh = XAllocSizeHints();
|
|
|
+ xsh->flags = p_enabled ? 0L : PMinSize | PMaxSize;
|
|
|
+ if(!p_enabled) {
|
|
|
+ XWindowAttributes xwa;
|
|
|
+ XGetWindowAttributes(x11_display,x11_window,&xwa);
|
|
|
+ xsh->min_width = xwa.width;
|
|
|
+ xsh->max_width = xwa.width;
|
|
|
+ xsh->min_height = xwa.height;
|
|
|
+ xsh->max_height = xwa.height;
|
|
|
+ }
|
|
|
+ XSetWMNormalHints(x11_display, x11_window, xsh);
|
|
|
+ XFree(xsh);
|
|
|
+ current_videomode.resizable = 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, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
|
|
|
+
|
|
|
+ //XEvent xev;
|
|
|
+ Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False);
|
|
|
+ Atom wm_hidden = XInternAtom(x11_display, "_NET_WM_STATE_HIDDEN", 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] = _NET_WM_STATE_ADD;
|
|
|
+ xev.xclient.data.l[1] = wm_hidden;
|
|
|
+
|
|
|
+ XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | 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] == WM_IconicState )
|
|
|
+ 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, SubstructureRedirectMask | 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;
|
|
|
+ }
|
|
|
+ XFree(atoms);
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|
|
|
+#endif
|
|
|
|
|
|
InputModifierState OS_X11::get_key_modifier_state(unsigned int p_x11_state) {
|
|
|
|
|
@@ -598,11 +964,9 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) {
|
|
|
KeySym keysym_keycode=0; // keysym used to find a keycode
|
|
|
KeySym keysym_unicode=0; // keysym used to find unicode
|
|
|
|
|
|
- int nbytes=0; // bytes the string takes
|
|
|
-
|
|
|
// XLookupString returns keysyms usable as nice scancodes/
|
|
|
char str[256+1];
|
|
|
- nbytes=XLookupString(xkeyevent, str, 256, &keysym_keycode, NULL);
|
|
|
+ XLookupString(xkeyevent, str, 256, &keysym_keycode, NULL);
|
|
|
|
|
|
// Meanwhile, XLookupString returns keysyms useful for unicode.
|
|
|
|
|
@@ -699,7 +1063,7 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) {
|
|
|
::Time tresh=ABS(peek_event.xkey.time-xkeyevent->time);
|
|
|
if (peek_event.type == KeyPress && tresh<5 ) {
|
|
|
KeySym rk;
|
|
|
- nbytes=XLookupString((XKeyEvent*)&peek_event, str, 256, &rk, NULL);
|
|
|
+ XLookupString((XKeyEvent*)&peek_event, str, 256, &rk, NULL);
|
|
|
if (rk==keysym_keycode) {
|
|
|
XEvent event;
|
|
|
XNextEvent(x11_display, &event); //erase next event
|
|
@@ -763,13 +1127,18 @@ void OS_X11::process_xevents() {
|
|
|
break;
|
|
|
|
|
|
case VisibilityNotify: {
|
|
|
-
|
|
|
XVisibilityEvent * visibility = (XVisibilityEvent *)&event;
|
|
|
minimized = (visibility->state == VisibilityFullyObscured);
|
|
|
-
|
|
|
} break;
|
|
|
|
|
|
- case FocusIn:
|
|
|
+ case FocusIn:
|
|
|
+ minimized = false;
|
|
|
+#ifdef NEW_WM_API
|
|
|
+ if(current_videomode.fullscreen) {
|
|
|
+ set_wm_fullscreen(true);
|
|
|
+ visual_server->init();
|
|
|
+ }
|
|
|
+#endif
|
|
|
main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN);
|
|
|
if (mouse_mode==MOUSE_MODE_CAPTURED) {
|
|
|
XGrabPointer(x11_display, x11_window, True,
|
|
@@ -780,6 +1149,13 @@ void OS_X11::process_xevents() {
|
|
|
break;
|
|
|
|
|
|
case FocusOut:
|
|
|
+#ifdef NEW_WM_API
|
|
|
+ if(current_videomode.fullscreen) {
|
|
|
+ set_wm_fullscreen(false);
|
|
|
+ set_minimized(true);
|
|
|
+ visual_server->init();
|
|
|
+ }
|
|
|
+#endif
|
|
|
main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
|
|
|
if (mouse_mode==MOUSE_MODE_CAPTURED) {
|
|
|
//dear X11, I try, I really try, but you never work, you do whathever you want.
|
|
@@ -806,7 +1182,7 @@ void OS_X11::process_xevents() {
|
|
|
event.xbutton.x=last_mouse_pos.x;
|
|
|
event.xbutton.y=last_mouse_pos.y;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
InputEvent mouse_event;
|
|
|
mouse_event.ID=++event_id;
|
|
|
mouse_event.type = InputEvent::MOUSE_BUTTON;
|
|
@@ -841,7 +1217,7 @@ void OS_X11::process_xevents() {
|
|
|
last_click_ms+=diff;
|
|
|
last_click_pos = Point2(event.xbutton.x,event.xbutton.y);
|
|
|
}
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
input->parse_input_event( mouse_event);
|
|
|
|
|
@@ -851,16 +1227,15 @@ void OS_X11::process_xevents() {
|
|
|
|
|
|
|
|
|
last_timestamp=event.xmotion.time;
|
|
|
-
|
|
|
+
|
|
|
// Motion is also simple.
|
|
|
// A little hack is in order
|
|
|
// to be able to send relative motion events.
|
|
|
-
|
|
|
Point2i pos( event.xmotion.x, event.xmotion.y );
|
|
|
|
|
|
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.
|
|
@@ -869,9 +1244,9 @@ void OS_X11::process_xevents() {
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- Point2i ncenter = pos;
|
|
|
- pos = last_mouse_pos + ( pos-center );
|
|
|
- center=ncenter;
|
|
|
+ Point2i new_center = pos;
|
|
|
+ pos = last_mouse_pos + ( pos - center );
|
|
|
+ center=new_center;
|
|
|
do_mouse_warp=true;
|
|
|
#else
|
|
|
//Dear X11, thanks for making my life miserable
|
|
@@ -884,9 +1259,7 @@ void OS_X11::process_xevents() {
|
|
|
XWarpPointer(x11_display, None, x11_window,
|
|
|
0,0,0,0, (int)center.x, (int)center.y);
|
|
|
#endif
|
|
|
-
|
|
|
}
|
|
|
-
|
|
|
|
|
|
if (!last_mouse_pos_valid) {
|
|
|
|
|
@@ -895,7 +1268,14 @@ void OS_X11::process_xevents() {
|
|
|
}
|
|
|
|
|
|
Point2i rel = pos - last_mouse_pos;
|
|
|
-
|
|
|
+
|
|
|
+#ifdef NEW_WM_API
|
|
|
+ if (mouse_mode==MOUSE_MODE_CAPTURED) {
|
|
|
+ pos.x = current_videomode.width / 2;
|
|
|
+ pos.y = current_videomode.height / 2;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
InputEvent motion_event;
|
|
|
motion_event.ID=++event_id;
|
|
|
motion_event.type=InputEvent::MOUSE_MOTION;
|
|
@@ -915,6 +1295,8 @@ void OS_X11::process_xevents() {
|
|
|
motion_event.mouse_motion.relative_y=rel.y;
|
|
|
|
|
|
last_mouse_pos=pos;
|
|
|
+
|
|
|
+ // printf("rel: %d,%d\n", rel.x, rel.y );
|
|
|
|
|
|
input->parse_input_event( motion_event);
|
|
|
|
|
@@ -989,8 +1371,18 @@ void OS_X11::process_xevents() {
|
|
|
if (do_mouse_warp) {
|
|
|
|
|
|
XWarpPointer(x11_display, None, x11_window,
|
|
|
- 0,0,0,0, (int)current_videomode.width/2, (int)current_videomode.height/2);
|
|
|
-
|
|
|
+ 0,0,0,0, (int)current_videomode.width/2, (int)current_videomode.height/2);
|
|
|
+
|
|
|
+ /*
|
|
|
+ Window root, child;
|
|
|
+ int root_x, root_y;
|
|
|
+ int win_x, win_y;
|
|
|
+ unsigned int mask;
|
|
|
+ XQueryPointer( x11_display, x11_window, &root, &child, &root_x, &root_y, &win_x, &win_y, &mask );
|
|
|
+
|
|
|
+ printf("Root: %d,%d\n", root_x, root_y);
|
|
|
+ printf("Win: %d,%d\n", win_x, win_y);
|
|
|
+ */
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1358,6 +1750,7 @@ void OS_X11::process_joysticks() {
|
|
|
#endif
|
|
|
};
|
|
|
|
|
|
+
|
|
|
void OS_X11::set_cursor_shape(CursorShape p_shape) {
|
|
|
|
|
|
ERR_FAIL_INDEX(p_shape,CURSOR_MAX);
|
|
@@ -1470,8 +1863,6 @@ OS_X11::OS_X11() {
|
|
|
#endif
|
|
|
|
|
|
minimized = false;
|
|
|
- xim_style=NULL;
|
|
|
+ xim_style=0L;
|
|
|
mouse_mode=MOUSE_MODE_VISIBLE;
|
|
|
-
|
|
|
-
|
|
|
};
|