XPutBackEvent copies an XEvent internally, so the pointer passed in must
[freeglut] / src / x11 / fg_window_x11.c
index 71814ac..cea4ba2 100644 (file)
@@ -28,8 +28,9 @@
 
 #define FREEGLUT_BUILDING_LIB
 #include <GL/freeglut.h>
-#include <limits.h>  /* LONG_MAX */
-#include <unistd.h>  /* usleep */
+#include <limits.h>     /* LONG_MAX */
+#include <unistd.h>     /* usleep, gethostname, getpid */
+#include <sys/types.h>  /* pid_t */
 #include "../fg_internal.h"
 
 #ifdef EGL_VERSION_1_0
@@ -136,7 +137,7 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
     XEvent eventReturnBuffer; /* return buffer required for a call */
     unsigned long mask;
     unsigned int current_DisplayMode = fgState.DisplayMode ;
-    XConfigureEvent fakeEvent = {0};
+    XEvent fakeEvent = {0};
 
     /* Save the display mode if we are creating a menu window */
     if( window->IsMenu && ( ! fgStructure.MenuContext ) )
@@ -246,14 +247,14 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
     /* Fake configure event to force viewport setup
      * even with no window manager.
      */
-    fakeEvent.type = ConfigureNotify;
-    fakeEvent.display = fgDisplay.pDisplay.Display;
-    fakeEvent.window = window->Window.Handle;
-    fakeEvent.x = x;
-    fakeEvent.y = y;
-    fakeEvent.width = w;
-    fakeEvent.height = h;
-    XPutBackEvent(fgDisplay.pDisplay.Display, (XEvent*)&fakeEvent);
+    fakeEvent.xconfigure.type = ConfigureNotify;
+    fakeEvent.xconfigure.display = fgDisplay.pDisplay.Display;
+    fakeEvent.xconfigure.window = window->Window.Handle;
+    fakeEvent.xconfigure.x = x;
+    fakeEvent.xconfigure.y = y;
+    fakeEvent.xconfigure.width = w;
+    fakeEvent.xconfigure.height = h;
+    XPutBackEvent(fgDisplay.pDisplay.Display, &fakeEvent);
 
     /*
      * The GLX context creation, possibly trying the direct context rendering
@@ -300,12 +301,6 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
     }
 #endif
 
-    /*
-     * XXX Assume the new window is visible by default
-     * XXX Is this a  safe assumption?
-     */
-    window->State.Visible = GL_TRUE;
-
     sizeHints.flags = 0;
     if ( positionUse )
         sizeHints.flags |= USPosition;
@@ -346,6 +341,41 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
     XSetWMProtocols( fgDisplay.pDisplay.Display, window->Window.Handle,
                      &fgDisplay.pDisplay.DeleteWindow, 1 );
 
+    if (fgDisplay.pDisplay.NetWMSupported
+        && fgDisplay.pDisplay.NetWMPid != None
+        && fgDisplay.pDisplay.ClientMachine != None)
+    {
+      char hostname[HOST_NAME_MAX];
+      pid_t pid = getpid();
+
+      if (pid > 0 && gethostname(hostname, sizeof(hostname)) > -1)
+      {
+        hostname[sizeof(hostname) - 1] = '\0';
+
+        XChangeProperty(
+            fgDisplay.pDisplay.Display,
+            window->Window.Handle,
+            fgDisplay.pDisplay.NetWMPid,
+            XA_CARDINAL,
+            32,
+            PropModeReplace,
+            (unsigned char *) &pid,
+            1
+        );
+
+        XChangeProperty(
+            fgDisplay.pDisplay.Display,
+            window->Window.Handle,
+            fgDisplay.pDisplay.ClientMachine,
+            XA_STRING,
+            8,
+            PropModeReplace,
+            (unsigned char *) hostname,
+            strlen(hostname)
+        );
+      }
+    }
+
 #ifdef EGL_VERSION_1_0
     fghPlatformOpenWindowEGL(window);
 #else
@@ -362,11 +392,16 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
        fgRegisterDevices( fgDisplay.pDisplay.Display, &(window->Window.Handle) );
     #endif
 
-    XMapWindow( fgDisplay.pDisplay.Display, window->Window.Handle );
+    if (!window->IsMenu)    /* Don't show window after creation if its a menu */
+    {
+        XMapWindow( fgDisplay.pDisplay.Display, window->Window.Handle );
+        window->State.Visible = GL_TRUE;
+    }
 
     XFree(visualInfo);
 
-    if( !isSubWindow)
+    /* wait till window visible */
+    if( !isSubWindow && !window->IsMenu)
         XPeekIfEvent( fgDisplay.pDisplay.Display, &eventReturnBuffer, &fghWindowIsVisible, (XPointer)(window->Window.Handle) );
 #undef WINDOW_CONFIG
 }