Help porting the XLaunch feature to autoselect the display number

Michael DePaulo <[email protected]> Mon, 23 Feb 2015 22:57:51 -0500
Newsgroups gmane.os.cygwin.xfree
Message-ID <CAMKht8jmDcsEZYrf2518f2oXzc+WO4cWGd4haNVndMkyUzKHrg@mail.gmail.com>
Hi,

i was talking with Jon Turney about this on IRC.

I am trying to port this feature of VcXsrv (and XMing also I think) to
Cygwin XLaunch:
https://sourceforge.net/p/vcxsrv/code/ci/460182676a960385dff96c1563f781213060f6fc/

Attached is my WIP patch. (I know it needs the comments updated for main.cc).

There's a bug in main.cc that is causing this to happen when -1 is specified:
http://imgur.com/Jv4tpip

I am not very familiar with C or C++. I am hoping that someone could
give me some advice. (I am much better at Java and bash.)

Thanks,
-Mike

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://x.cygwin.com/docs/
FAQ:                   http://x.cygwin.com/docs/faq/
0001-Now-the-display-number-can-be-set-to-automatic-by-sp.patch (application/octet-stream, 7.2 KB)
From 460182676a960385dff96c1563f781213060f6fc Mon Sep 17 00:00:00 2001
From: marha <[email protected]>
Date: Thu, 3 May 2012 13:09:19 +0200
Subject: [PATCH] Now the display number can be set to automatic by specifying
 -1

v2: Port to Cygwin XWin (Mike DePaulo)

diff --git a/config.h.orig b/config.h
index 070c175..4ece822 100644
--- a/config.h.orig
+++ b/config.h
@@ -52,11 +52,7 @@ struct CConfig
     CConfig() : window(MultiWindow),
                 client(NoClient),
                 local(true),
-#ifdef _DEBUG
-                display("1"),
-#else
-                display("0"),
-#endif
+                display("-1"),
                 localprogram("xterm"),
                 remoteprogram("xterm"),
                 host(""),
diff --git a/main.cc.orig b/main.cc
index d343536..0a713d4 100644
--- a/main.cc.orig
+++ b/main.cc
@@ -39,6 +39,8 @@
 
 #include <X11/Xlib.h>
 
+#include <sstream>
+
 #ifdef _DEBUG
 static bool debug = true;
 #else
@@ -617,14 +619,19 @@ class CMyWizard : public CWizard
 	    BOOL showconsole = FALSE;
 
             // Construct display strings
+	    int DisplayNbr=atoi(config.display.c_str());
 	    std::string display_id = ":" + config.display;
 	    std::string display = "localhost" + display_id + ".0";
 
             // Build X server commandline
 #if defined (__CYGWIN__)
-	    buffer = "XWin " + display_id + " ";
+	    buffer = "Xwin ";
+	    if (DisplayNbr!=-1)
+	      buffer += display_id + " ";
 #elif defined (__MINGW__)
-	    buffer = "Xming " + display_id + " ";
+	    buffer = "Xming ";
+	    if (DisplayNbr!=-1)
+	      buffer += display_id + " ";
 #else
 #error "Don't know X server name"
 #endif
@@ -675,6 +682,22 @@ class CMyWizard : public CWizard
                 buffer += " ";
             }
 
+            int *pDisplayfd;
+            if (DisplayNbr==-1)
+            {
+              // Pass the handle of some shared memory to vcxsrv to getting back the display nbr
+              SECURITY_ATTRIBUTES sa;
+              sa.nLength=sizeof(sa);
+              sa.lpSecurityDescriptor=NULL;
+              sa.bInheritHandle=TRUE;
+              HANDLE hDisplayFdMem=CreateFileMapping(INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE, 0, sizeof(int), NULL);
+              pDisplayfd=(int*)MapViewOfFile(hDisplayFdMem, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, 0);
+              *pDisplayfd=-1;  // Not yet initialised
+              buffer+="-displayfd ";
+              std::stringstream ss;
+              ss<<(int)hDisplayFdMem;
+              buffer+=ss.str();
+            }
             // Construct client commandline
 	    if (config.client == CConfig::StartProgram)
 	    {
@@ -744,12 +767,26 @@ class CMyWizard : public CWizard
               printf("Server: %s\n", buffer.c_str());
 
 	    if( !CreateProcess( NULL, (CHAR*)buffer.c_str(), NULL, NULL,
-                        FALSE, 0, NULL, NULL, &si, &pi ))
+                        TRUE, 0, NULL, NULL, &si, &pi ))
 		throw win32_error("CreateProcess failed");
 	    handles[hcount++] = pi.hProcess;
-
 	    if (!client.empty())
 	    {
+                if (DisplayNbr==-1)
+                {
+                  // Wait maximum 10 seconds
+                  int Count=1000;
+                  while (-1==*pDisplayfd)
+                  {
+                    if (Count-- < 0)
+                      throw std::runtime_error("Connection to server failed");
+                    Sleep(10);
+                  }
+                  std::stringstream ss;
+                  ss<<*pDisplayfd;
+                  display_id = ":" + ss.str();
+                  display = "DISPLAY=127.0.0.1" + display_id + ".0";
+                }
                 // Set DISPLAY variable
 		SetEnvironmentVariable("DISPLAY",display.c_str());
 
diff --git a/resources/dialog.rc.orig b/resources/dialog.rc
index 3f55a5a..b8859c6 100644
--- a/resources/dialog.rc.orig
+++ b/resources/dialog.rc
@@ -47,7 +47,8 @@ BEGIN
     CONTROL         "IMG_NODECORATION",IDC_NODECORATION_IMG,"Static",SS_BITMAP | SS_NOTIFY,230,60,0,0
 
     LTEXT           STR_DISPLAY_DESC,IDC_DISPLAY_DESC,7,120,64,12
-    EDITTEXT        IDC_DISPLAY,80,118,67,12,ES_NUMBER
+    LTEXT           STR_DISPLAY_EXTRA_DESC,IDC_DISPLAY_EXTRA_DESC,7,132,200,12
+    EDITTEXT        IDC_DISPLAY,80,118,67,12
 END
 
 IDD_CLIENTS DIALOGEX 0, 0, 317, 143
diff --git a/resources/resources.h.orig b/resources/resources.h
index e8bca5a..13e2192 100644
--- a/resources/resources.h.orig
+++ b/resources/resources.h
@@ -46,35 +46,36 @@
 #define IDC_NODECORATION_IMG    207
 #define IDC_DISPLAY             208
 #define IDC_DISPLAY_DESC        209
+#define IDC_DISPLAY_EXTRA_DESC  210
 
-#define IDC_CLIENT_NONE         210
-#define IDC_XDMCP               211
-#define IDC_CLIENT              212
-#define IDC_CLIENT_LOCAL        213
-#define IDC_CLIENT_REMOTE       214
-#define IDC_CLIENT_HOST         215
-#define IDC_CLIENT_USER         216
-#define IDC_CLIENT_PROTOCOL     217
-#define IDC_CLIENT_CONFIGURE    218
-#define IDC_CLIENT_PROGRAM      219
-#define IDC_XDMCP_QUERY         220
-#define IDC_XDMCP_BROADCAST     221
-#define IDC_XDMCP_INDIRECT      222
-#define IDC_XDMCP_HOST          223
-#define IDC_CLIENT_NONE_DESC    224
-#define IDC_XDMCP_DESC          225
-#define IDC_CLIENT_DESC         226
-#define IDC_XDMCP_QUERY_DESC    227
-#define IDC_CLIENT_PROGRAM_DESC 228
-#define IDC_CLIENT_HOST_DESC    229
-#define IDC_CLIENT_USER_DESC    230
-#define IDC_CLIENT_PROTOCOL_DESC 231
-#define IDC_CLIENT_REMOTEPROGRAM      232
-#define IDC_CLIENT_REMOTEPROGRAM_DESC 233
-#define IDC_CLIENT_SSH_KEYCHAIN  234
-#define IDC_CLIENT_SSH_TERMINAL  235
-#define IDC_CLIENT_PROTOCOL_EXTRA_PARAMS_DESC 236
-#define IDC_CLIENT_PROTOCOL_EXTRA_PARAMS 237
+#define IDC_CLIENT_NONE         211
+#define IDC_XDMCP               212
+#define IDC_CLIENT              213
+#define IDC_CLIENT_LOCAL        214
+#define IDC_CLIENT_REMOTE       215
+#define IDC_CLIENT_HOST         216
+#define IDC_CLIENT_USER         217
+#define IDC_CLIENT_PROTOCOL     218
+#define IDC_CLIENT_CONFIGURE    219
+#define IDC_CLIENT_PROGRAM      220
+#define IDC_XDMCP_QUERY         221
+#define IDC_XDMCP_BROADCAST     222
+#define IDC_XDMCP_INDIRECT      223
+#define IDC_XDMCP_HOST          224
+#define IDC_CLIENT_NONE_DESC    225
+#define IDC_XDMCP_DESC          226
+#define IDC_CLIENT_DESC         227
+#define IDC_XDMCP_QUERY_DESC    228
+#define IDC_CLIENT_PROGRAM_DESC 229
+#define IDC_CLIENT_HOST_DESC    230
+#define IDC_CLIENT_USER_DESC    231
+#define IDC_CLIENT_PROTOCOL_DESC 232
+#define IDC_CLIENT_REMOTEPROGRAM      233
+#define IDC_CLIENT_REMOTEPROGRAM_DESC 234
+#define IDC_CLIENT_SSH_KEYCHAIN  235
+#define IDC_CLIENT_SSH_TERMINAL  236
+#define IDC_CLIENT_PROTOCOL_EXTRA_PARAMS_DESC 237
+#define IDC_CLIENT_PROTOCOL_EXTRA_PARAMS 238
 
 #define IDC_FONTPATH_DESC        240
 
diff --git a/resources/strings.rc.orig b/resources/strings.rc
index c42fbe6..1872930 100644
--- a/resources/strings.rc.orig
+++ b/resources/strings.rc
@@ -30,6 +30,7 @@
 #define STR_WINDOWED                "One window"
 #define STR_NODECORATION            "One window without titlebar"
 #define STR_DISPLAY_DESC            "Display number"
+#define STR_DISPLAY_EXTRA_DESC      "(Specify -1 to let XWin automatically choose one)"
 
 #define STR_CAPTION_CLIENTS         "Session type"
 #define STR_CLIENT_NONE             "Start no client"