From dc163f625ef006c8550791122bda28fb3eb67e3d Mon Sep 17 00:00:00 2001
From: marha <marha@users.sourceforge.net>
Date: Thu, 17 Jan 2013 08:32:19 +0100
Subject: xlaunch: Use dialog for prompting for password input instead of
 console

---
 xorg-server/hw/xwin/xlaunch/main.cc               | 131 ++++++++++++++--------
 xorg-server/hw/xwin/xlaunch/resources/dialog.rc   |  15 +++
 xorg-server/hw/xwin/xlaunch/resources/resources.h |   4 +
 3 files changed, 103 insertions(+), 47 deletions(-)

diff --git a/xorg-server/hw/xwin/xlaunch/main.cc b/xorg-server/hw/xwin/xlaunch/main.cc
index 9211fb503..8e13b4436 100644
--- a/xorg-server/hw/xwin/xlaunch/main.cc
+++ b/xorg-server/hw/xwin/xlaunch/main.cc
@@ -54,56 +54,104 @@ static bool ContainPrintableChars(const char *Buf, unsigned Nbr)
   return false;
 }
 
-static bool CheckOutput(HANDLE hChildStdoutRd, int hStdOut, HANDLE hConsoleOutput, HWND hConsoleWnd)
+/*
+ * Process messages for the prompt dialog.
+ */
+
+static INT_PTR CALLBACK DisplayPromptDlgProc (HWND hwndDialog, UINT message, WPARAM wParam, LPARAM lParam)
 {
-  DWORD NbrAvail=0;
-	PeekNamedPipe(hChildStdoutRd, NULL, NULL, NULL, &NbrAvail, NULL);
-  if (NbrAvail)
+  static LPARAM Param;
+  static UINT PasswordChar;
+  switch (message)
   {
-    char Buf[128];
-    size_t Nbr = _read(hStdOut, Buf, sizeof(Buf));
-  	DWORD NbrWritten;
-		WriteConsole(hConsoleOutput, Buf, Nbr, &NbrWritten, NULL);
-    if (hConsoleWnd && ContainPrintableChars(Buf,NbrWritten))
+    case WM_INITDIALOG:
     {
-      // Only show console again when there are new characters printed
-      ShowWindow(hConsoleWnd, SW_SHOW );  // make it visible again
-      return true;
+      HWND hwndDesk=GetForegroundWindow();
+      RECT rc, rcDlg, rcDesk;
+
+      PasswordChar=SendDlgItemMessage(hwndDialog, IDC_INPUT, EM_GETPASSWORDCHAR, 0, 0);
+
+      GetWindowRect (hwndDesk, &rcDesk);
+      GetWindowRect (hwndDialog, &rcDlg);
+      CopyRect (&rc, &rcDesk);
+
+      OffsetRect (&rcDlg, -rcDlg.left, -rcDlg.top);
+      OffsetRect (&rc, -rc.left, -rc.top);
+      OffsetRect (&rc, -rcDlg.right, -rcDlg.bottom);
+
+      SetWindowPos (hwndDialog,
+      HWND_TOPMOST,
+      rcDesk.left + (rc.right / 2),
+      rcDesk.top + (rc.bottom / 2),
+      0, 0,
+      SWP_NOSIZE | SWP_FRAMECHANGED);
+
+      Param=lParam;
+      SendDlgItemMessage(hwndDialog, IDC_PROMPT_DESC, WM_SETTEXT, 0, lParam);
+      return TRUE;
     }
+    break;
+
+    case WM_COMMAND:
+      switch (LOWORD (wParam))
+      {
+        case IDOK:
+          SendDlgItemMessage(hwndDialog, IDC_INPUT, WM_GETTEXT, 128, Param);
+          EndDialog(hwndDialog, Param);
+          return TRUE;
+        case IDCANCEL:
+          EndDialog(hwndDialog, NULL);
+          return TRUE;
+        case IDC_PASSWORD:
+        {
+          HWND hDlg=GetDlgItem(hwndDialog, IDC_INPUT);
+          if (HIWORD(wParam)==BN_CLICKED)
+          {
+            if (BST_CHECKED==SendDlgItemMessage(hwndDialog, IDC_PASSWORD, BM_GETCHECK, 0, 0))
+              SendMessage(hDlg, EM_SETPASSWORDCHAR, 0, 0);
+            else
+              SendMessage(hDlg, EM_SETPASSWORDCHAR, (WPARAM)PasswordChar, 0);
+          }
+          InvalidateRect(hDlg, NULL, TRUE);
+        }
+        return TRUE;
+      }
+      break;
+
+    case WM_CLOSE:
+      EndDialog (hwndDialog, NULL);
+      return TRUE;
   }
-  return false;
-}
 
-#define NRINPUTS 50
+  return FALSE;
+}
 
-static int CheckInput(HANDLE hConsoleInput, char *Buf, HWND hConsoleWnd)
+static bool CheckOutput(HANDLE hChildStdoutRd, int hStdOut, int hStdIn)
 {
-  INPUT_RECORD Input[NRINPUTS];
   DWORD NbrAvail=0;
-  GetNumberOfConsoleInputEvents(hConsoleInput, &NbrAvail);
-  int w=0;
+  PeekNamedPipe(hChildStdoutRd, NULL, NULL, NULL, &NbrAvail, NULL);
   if (NbrAvail)
   {
-    DWORD NbrRead=0;
-    ReadConsoleInput(hConsoleInput, Input, NRINPUTS, &NbrRead);
-    for (int i=0; i<NbrRead; i++)
+    char Buf[128];
+    size_t Nbr = _read(hStdOut, Buf, sizeof(Buf)-1);
+    if (ContainPrintableChars(Buf,Nbr))
     {
-      if (Input[i].EventType==KEY_EVENT && Input[i].Event.KeyEvent.bKeyDown)
+      Buf[Nbr]=0;
+      INT_PTR Ret = DialogBoxParam (GetModuleHandle(NULL), "IDD_PROMPT", NULL, DisplayPromptDlgProc, (LPARAM)Buf);
+
+      if (Ret)
       {
-        char Char=Input[i].Event.KeyEvent.uChar.AsciiChar;
-        if (Char)
-        {
-          Buf[w++]=Char;
-          if (Char==0xd)
-          {
-            Buf[w++]=0xa; // Convert cariage return to cariage return + line feed
-            if (hConsoleWnd) ShowWindow(hConsoleWnd, SW_HIDE );  // make it invisible again
-          }
-        }
+        char *Data=(char*)Ret;
+        // Write it to the client
+        _write(hStdIn, Data, strlen(Data));
+        _write(hStdIn, "\x0d\x0a", 2);
       }
+
+      return true;
     }
+
   }
-  return w;
+  return false;
 }
 
 
@@ -822,17 +870,12 @@ class CMyWizard : public CWizard
                 SetConsoleMode(hConsoleInput, 0);  // Needed to disable local echo, and return only upon carriage return of read function
                 while (1)
                 {
-                  char Buf[NRINPUTS];
                   if (!WaitForSingleObject(pic.hProcess, 20 ))
                   {
                       // Child does not exist anymore, but it could be that there is still error output in the pipes
                       // So wait some time, that then check the output again
                     Sleep(500);
-                    if (CheckOutput(hChildStdoutRd, hStdOut, hConsoleOutput, hConsoleWnd) || IsWindowVisible(hConsoleWnd))
-                    {
-                      // Wait some input to close the window
-                      while (!CheckInput(hConsoleInput, Buf, hConsoleWnd)) Sleep(10);
-                    }
+                    CheckOutput(hChildStdoutRd, hStdOut, hStdIn);
                     break;
                   }
                   if (!WaitForSingleObject(pi.hProcess, 0))
@@ -840,13 +883,7 @@ class CMyWizard : public CWizard
                     TerminateProcess(pic.hProcess, (DWORD)-1);
                     break;
                   }
-                  CheckOutput(hChildStdoutRd, hStdOut, hConsoleOutput, hConsoleWnd);
-
-                  int w=CheckInput(hConsoleInput, Buf, hConsoleWnd);
-                  if (w)
-                  {  // Write it to the client
-                    _write(hStdIn, Buf, w);
-                  }
+                  CheckOutput(hChildStdoutRd, hStdOut, hStdIn);
                 }
                 #else
                 // Hide a console window
diff --git a/xorg-server/hw/xwin/xlaunch/resources/dialog.rc b/xorg-server/hw/xwin/xlaunch/resources/dialog.rc
index fd7dae522..3435329b2 100644
--- a/xorg-server/hw/xwin/xlaunch/resources/dialog.rc
+++ b/xorg-server/hw/xwin/xlaunch/resources/dialog.rc
@@ -136,3 +136,18 @@ BEGIN
     LTEXT           STR_FINISH_SAVE_DESC,IDC_FINISH_SAVE_DESC,7,56,300,12
     PUSHBUTTON      STR_FINISH_SAVE,IDC_FINISH_SAVE,7,68,75,14 
 END
+
+/* Prompting dialog  */
+IDD_PROMPT DIALOGEX 32, 32, 260, 115
+STYLE DS_SETFONT | DS_CENTERMOUSE | WS_POPUP | WS_VISIBLE | WS_CAPTION
+EXSTYLE WS_EX_NOPARENTNOTIFY
+CAPTION "Input requested?"
+FONT 8, "MS Shell Dlg 2", 0, 0, 0x1
+BEGIN
+    LTEXT           "",IDC_PROMPT_DESC,7,7,245,50, WS_BORDER
+    EDITTEXT        IDC_INPUT,7,67,245,12, WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL | ES_PASSWORD
+    AUTOCHECKBOX    "Show Characters", IDC_PASSWORD, 7,77,245,12, WS_TABSTOP
+    DEFPUSHBUTTON   "OK",IDOK,61,95,50,15, WS_TABSTOP
+    PUSHBUTTON      "Cancel",IDCANCEL,147,95,50,14, WS_TABSTOP
+END
+
diff --git a/xorg-server/hw/xwin/xlaunch/resources/resources.h b/xorg-server/hw/xwin/xlaunch/resources/resources.h
index bccfb1702..256ebb9fa 100644
--- a/xorg-server/hw/xwin/xlaunch/resources/resources.h
+++ b/xorg-server/hw/xwin/xlaunch/resources/resources.h
@@ -94,6 +94,10 @@
 #define IDC_DISABLEAC_DESC            269
 #define IDC_XDMCP_TERMINATE           270
 
+#define IDC_PROMPT_DESC               280
+#define IDC_INPUT                     281
+#define IDC_PASSWORD                  282
+
 #define IDS_DISPLAY_TITLE             300
 #define IDS_DISPLAY_SUBTITLE          301
 #define IDS_CLIENTS_TITLE             302
-- 
cgit v1.2.3