diff options
Diffstat (limited to 'src/client/renderingengine.cpp')
-rw-r--r-- | src/client/renderingengine.cpp | 111 |
1 files changed, 104 insertions, 7 deletions
diff --git a/src/client/renderingengine.cpp b/src/client/renderingengine.cpp index 72c1ccfbd..82d1411d6 100644 --- a/src/client/renderingengine.cpp +++ b/src/client/renderingengine.cpp @@ -43,6 +43,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #ifdef XORG_USED #include <X11/Xlib.h> #include <X11/Xutil.h> +#include <X11/Xatom.h> #endif #ifdef __ANDROID__ @@ -186,23 +187,119 @@ bool RenderingEngine::print_video_modes() return videomode_list != NULL; } -void RenderingEngine::setXorgClassHint( - const video::SExposedVideoData &video_data, const std::string &name) +bool RenderingEngine::setupTopLevelWindow(const std::string &name) +{ + // FIXME: It would make more sense for there to be a switch of some + // sort here that would call the correct toplevel setup methods for + // the environment Minetest is running in but for now not deviating + // from the original pattern. + + /* Setting Xorg properties for the top level window */ + setupTopLevelXorgWindow(name); + /* Done with Xorg properties */ + + /* Setting general properties for the top level window */ + verbosestream << "Client: Configuring general top level" + << " window properties" + << std::endl; + + bool result = setWindowIcon(); + + verbosestream << "Client: Finished configuring general top level" + << " window properties" + << std::endl; + /* Done with general properties */ + + // FIXME: setWindowIcon returns a bool result but it is unused. + // For now continue to return this result. + return result; +} + +void RenderingEngine::setupTopLevelXorgWindow(const std::string &name) { #ifdef XORG_USED - if (video_data.OpenGLLinux.X11Display == NULL) + const video::SExposedVideoData exposedData = driver->getExposedVideoData(); + + Display *x11_dpl = reinterpret_cast<Display *>(exposedData.OpenGLLinux.X11Display); + if (x11_dpl == NULL) { + warningstream << "Client: Could not find X11 Display in ExposedVideoData" + << std::endl; return; + } + + verbosestream << "Client: Configuring Xorg specific top level" + << " window properties" + << std::endl; + + Window x11_win = reinterpret_cast<Window>(exposedData.OpenGLLinux.X11Window); + + // Set application name and class hints. For now name and class are the same. XClassHint *classhint = XAllocClassHint(); - classhint->res_name = (char *)name.c_str(); - classhint->res_class = (char *)name.c_str(); + classhint->res_name = const_cast<char *>(name.c_str()); + classhint->res_class = const_cast<char *>(name.c_str()); - XSetClassHint((Display *)video_data.OpenGLLinux.X11Display, - video_data.OpenGLLinux.X11Window, classhint); + XSetClassHint(x11_dpl, x11_win, classhint); XFree(classhint); + + // FIXME: In the future WMNormalHints should be set ... e.g see the + // gtk/gdk code (gdk/x11/gdksurface-x11.c) for the setup_top_level + // method. But for now (as it would require some significant changes) + // leave the code as is. + + // The following is borrowed from the above gdk source for setting top + // level windows. The source indicates and the Xlib docs suggest that + // this will set the WM_CLIENT_MACHINE and WM_LOCAL_NAME. This will not + // set the WM_CLIENT_MACHINE to a Fully Qualified Domain Name (FQDN) which is + // required by the Extended Window Manager Hints (EWMH) spec when setting + // the _NET_WM_PID (see further down) but running Minetest in an env + // where the window manager is on another machine from Minetest (therefore + // making the PID useless) is not expected to be a problem. Further + // more, using gtk/gdk as the model it would seem that not using a FQDN is + // not an issue for modern Xorg window managers. + + verbosestream << "Client: Setting Xorg window manager Properties" + << std::endl; + + XSetWMProperties (x11_dpl, x11_win, NULL, NULL, NULL, 0, NULL, NULL, NULL); + + // Set the _NET_WM_PID window property according to the EWMH spec. _NET_WM_PID + // (in conjunction with WM_CLIENT_MACHINE) can be used by window managers to + // force a shutdown of an application if it doesn't respond to the destroy + // window message. + + verbosestream << "Client: Setting Xorg _NET_WM_PID extened window manager property" + << std::endl; + + Atom NET_WM_PID = XInternAtom(x11_dpl, "_NET_WM_PID", false); + + pid_t pid = getpid(); + infostream << "Client: PID is '" << static_cast<long>(pid) << "'" + << std::endl; + + XChangeProperty(x11_dpl, x11_win, NET_WM_PID, + XA_CARDINAL, 32, PropModeReplace, + reinterpret_cast<unsigned char *>(&pid),1); + + // Set the WM_CLIENT_LEADER window property here. Minetest has only one + // window and that window will always be the leader. + + verbosestream << "Client: Setting Xorg WM_CLIENT_LEADER property" + << std::endl; + + Atom WM_CLIENT_LEADER = XInternAtom(x11_dpl, "WM_CLIENT_LEADER", false); + + XChangeProperty (x11_dpl, x11_win, WM_CLIENT_LEADER, + XA_WINDOW, 32, PropModeReplace, + reinterpret_cast<unsigned char *>(&x11_win), 1); + + verbosestream << "Client: Finished configuring Xorg specific top level" + << " window properties" + << std::endl; #endif } + bool RenderingEngine::setWindowIcon() { #if defined(XORG_USED) |