[FORMATTING] Standardize win32csr to 4-space indents. Based on a patch by Adam Kachwa...
[reactos.git] / reactos / subsystems / win32 / csrss / win32csr / guiconsole.c
index ff5cbf3..e274872 100644 (file)
@@ -19,35 +19,33 @@ extern VOID WINAPI PrivateCsrssManualGuiCheck(LONG Check);
 
 typedef struct GUI_CONSOLE_DATA_TAG
 {
-  HFONT Font;
-  unsigned CharWidth;
-  unsigned CharHeight;
-  PWCHAR LineBuffer;
-  BOOL CursorBlinkOn;
-  BOOL ForceCursorOff;
-  CRITICAL_SECTION Lock;
-  RECT Selection;
-  POINT SelectionStart;
-  BOOL MouseDown;
-  HMODULE ConsoleLibrary;
-  HANDLE hGuiInitEvent;
-  WCHAR FontName[LF_FACESIZE];
-  DWORD FontSize;
-  DWORD FontWeight;
-  DWORD HistoryNoDup;
-  DWORD FullScreen;
-  DWORD QuickEdit;
-  DWORD InsertMode;
-  DWORD NumberOfHistoryBuffers;
-  DWORD HistoryBufferSize;
-  DWORD WindowPosition;
-  DWORD UseRasterFonts;
-  COLORREF ScreenText;
-  COLORREF ScreenBackground;
-  COLORREF PopupBackground;
-  COLORREF PopupText;
-  COLORREF Colors[16];
-  WCHAR szProcessName[MAX_PATH];
+    HFONT Font;
+    unsigned CharWidth;
+    unsigned CharHeight;
+    BOOL CursorBlinkOn;
+    BOOL ForceCursorOff;
+    CRITICAL_SECTION Lock;
+    HMODULE ConsoleLibrary;
+    HANDLE hGuiInitEvent;
+    WCHAR FontName[LF_FACESIZE];
+    DWORD FontSize;
+    DWORD FontWeight;
+    DWORD HistoryNoDup;
+    DWORD FullScreen;
+    DWORD QuickEdit;
+    DWORD InsertMode;
+    DWORD NumberOfHistoryBuffers;
+    DWORD HistoryBufferSize;
+    DWORD WindowPosition;
+    DWORD UseRasterFonts;
+    COLORREF ScreenText;
+    COLORREF ScreenBackground;
+    COLORREF PopupBackground;
+    COLORREF PopupText;
+    COLORREF Colors[16];
+    WCHAR szProcessName[MAX_PATH];
+    BOOL WindowSizeLock;
+    POINT OldCursor;
 } GUI_CONSOLE_DATA, *PGUI_CONSOLE_DATA;
 
 #ifndef WM_APP
@@ -115,7 +113,7 @@ static const COLORREF s_Colors[] =
 
 /* FUNCTIONS *****************************************************************/
 
-static VOID FASTCALL
+static VOID
 GuiConsoleAppendMenuItems(HMENU hMenu,
                           const GUICONSOLE_MENUITEM *Items)
 {
@@ -166,11 +164,11 @@ GuiConsoleAppendMenuItems(HMENU hMenu,
                         0,
                         NULL);
         }
-    i++;
-    }while(!(Items[i].uID == 0 && Items[i].SubMenu == NULL && Items[i].wCmdID == 0));
+        i++;
+    } while(!(Items[i].uID == 0 && Items[i].SubMenu == NULL && Items[i].wCmdID == 0));
 }
 
-static VOID FASTCALL
+static VOID
 GuiConsoleCreateSysMenu(PCSRSS_CONSOLE Console)
 {
     HMENU hMenu;
@@ -184,209 +182,209 @@ GuiConsoleCreateSysMenu(PCSRSS_CONSOLE Console)
     }
 }
 
-static VOID FASTCALL
+static VOID
 GuiConsoleGetDataPointers(HWND hWnd, PCSRSS_CONSOLE *Console, PGUI_CONSOLE_DATA *GuiData)
 {
-  *Console = (PCSRSS_CONSOLE) GetWindowLongPtrW(hWnd, GWL_USERDATA);
-  *GuiData = (NULL == *Console ? NULL : (*Console)->PrivateData);
+    *Console = (PCSRSS_CONSOLE) GetWindowLongPtrW(hWnd, GWL_USERDATA);
+    *GuiData = (NULL == *Console ? NULL : (*Console)->PrivateData);
 }
 
-static BOOL FASTCALL
+static BOOL
 GuiConsoleOpenUserRegistryPathPerProcessId(DWORD ProcessId, PHANDLE hProcHandle, PHKEY hResult, REGSAM samDesired)
 {
-  HANDLE hProcessToken = NULL;
-  HANDLE hProcess;
+    HANDLE hProcessToken = NULL;
+    HANDLE hProcess;
 
-  BYTE Buffer[256];
-  DWORD Length = 0;
-  UNICODE_STRING SidName;
-  LONG res;
-  PTOKEN_USER TokUser;
+    BYTE Buffer[256];
+    DWORD Length = 0;
+    UNICODE_STRING SidName;
+    LONG res;
+    PTOKEN_USER TokUser;
 
-  hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | READ_CONTROL, FALSE, ProcessId);
-  if (!hProcess)
+    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | READ_CONTROL, FALSE, ProcessId);
+    if (!hProcess)
     {
-      DPRINT("Error: OpenProcess failed(0x%x)\n", GetLastError());
-      return FALSE;
+        DPRINT("Error: OpenProcess failed(0x%x)\n", GetLastError());
+        return FALSE;
     }
 
-  if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken))
+    if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken))
     {
-      DPRINT("Error: OpenProcessToken failed(0x%x)\n", GetLastError());
-      CloseHandle(hProcess);
-      return FALSE;
+        DPRINT("Error: OpenProcessToken failed(0x%x)\n", GetLastError());
+        CloseHandle(hProcess);
+        return FALSE;
     }
 
-  if (!GetTokenInformation(hProcessToken, TokenUser, (PVOID)Buffer, sizeof(Buffer), &Length))
+    if (!GetTokenInformation(hProcessToken, TokenUser, (PVOID)Buffer, sizeof(Buffer), &Length))
     {
-      DPRINT("Error: GetTokenInformation failed(0x%x)\n",GetLastError());
-      CloseHandle(hProcess);
-      CloseHandle(hProcessToken);
-      return FALSE;
+        DPRINT("Error: GetTokenInformation failed(0x%x)\n",GetLastError());
+        CloseHandle(hProcess);
+        CloseHandle(hProcessToken);
+        return FALSE;
     }
 
-  TokUser = ((PTOKEN_USER)Buffer)->User.Sid;
-  if (!NT_SUCCESS(RtlConvertSidToUnicodeString(&SidName, TokUser, TRUE)))
+    TokUser = ((PTOKEN_USER)Buffer)->User.Sid;
+    if (!NT_SUCCESS(RtlConvertSidToUnicodeString(&SidName, TokUser, TRUE)))
     {
-      DPRINT("Error: RtlConvertSidToUnicodeString failed(0x%x)\n", GetLastError());
-      return FALSE;
+        DPRINT("Error: RtlConvertSidToUnicodeString failed(0x%x)\n", GetLastError());
+        return FALSE;
     }
 
-  res = RegOpenKeyExW(HKEY_USERS, SidName.Buffer, 0, samDesired, hResult);
-  RtlFreeUnicodeString(&SidName);
+    res = RegOpenKeyExW(HKEY_USERS, SidName.Buffer, 0, samDesired, hResult);
+    RtlFreeUnicodeString(&SidName);
 
-  CloseHandle(hProcessToken);
-  if (hProcHandle)
-    *hProcHandle = hProcess;
-  else
-    CloseHandle(hProcess);
+    CloseHandle(hProcessToken);
+    if (hProcHandle)
+        *hProcHandle = hProcess;
+    else
+        CloseHandle(hProcess);
 
-  if (res != ERROR_SUCCESS)
-    return FALSE;
-  else
-    return TRUE;
+    if (res != ERROR_SUCCESS)
+        return FALSE;
+    else
+        return TRUE;
 }
 
-static BOOL FASTCALL
+static BOOL
 GuiConsoleOpenUserSettings(PGUI_CONSOLE_DATA GuiData, DWORD ProcessId, PHKEY hSubKey, REGSAM samDesired, BOOL bCreate)
 {
-  WCHAR szProcessName[MAX_PATH];
-  WCHAR szBuffer[MAX_PATH];
-  UINT fLength, wLength;
-  DWORD dwBitmask, dwLength;
-  WCHAR CurDrive[] = { 'A',':', 0 };
-  HANDLE hProcess;
-  HKEY hKey;
-  WCHAR * ptr;
+    WCHAR szProcessName[MAX_PATH];
+    WCHAR szBuffer[MAX_PATH];
+    UINT fLength, wLength;
+    DWORD dwBitmask, dwLength;
+    WCHAR CurDrive[] = { 'A',':', 0 };
+    HANDLE hProcess;
+    HKEY hKey;
+    WCHAR * ptr;
 
-  /*
-   * console properties are stored under
-   * HKCU\Console\*
-   *
-   * There are 3 ways to store console properties
-   *
-   *  1. use console title as subkey name
-   *    i.e. cmd.exe
-   *
-   *  2. use application name as subkey name
-   *
-   *  3. use unexpanded path to console application.
-   *     i.e. %SystemRoot%_system32_cmd.exe
-   */
+    /*
+     * console properties are stored under
+     * HKCU\Console\*
+     *
+     * There are 3 ways to store console properties
+     *
+     *  1. use console title as subkey name
+     *    i.e. cmd.exe
+     *
+     *  2. use application name as subkey name
+     *
+     *  3. use unexpanded path to console application.
+     *     i.e. %SystemRoot%_system32_cmd.exe
+     */
 
-  DPRINT("GuiConsoleOpenUserSettings entered\n");
+    DPRINT("GuiConsoleOpenUserSettings entered\n");
 
-  if (!GuiConsoleOpenUserRegistryPathPerProcessId(ProcessId, &hProcess, &hKey, samDesired))
+    if (!GuiConsoleOpenUserRegistryPathPerProcessId(ProcessId, &hProcess, &hKey, samDesired))
     {
-      DPRINT("GuiConsoleOpenUserRegistryPathPerProcessId failed\n");
-      return FALSE;
+        DPRINT("GuiConsoleOpenUserRegistryPathPerProcessId failed\n");
+        return FALSE;
     }
 
-  /* FIXME we do not getting the process name so no menu will be loading, why ?*/
-  fLength = GetProcessImageFileNameW(hProcess, szProcessName, sizeof(GuiData->szProcessName) / sizeof(WCHAR));
-  CloseHandle(hProcess);
+    /* FIXME we do not getting the process name so no menu will be loading, why ?*/
+    fLength = GetProcessImageFileNameW(hProcess, szProcessName, sizeof(GuiData->szProcessName) / sizeof(WCHAR));
+    CloseHandle(hProcess);
 
-  //DPRINT1("szProcessName3 : %S\n",szProcessName);
+    //DPRINT1("szProcessName3 : %S\n",szProcessName);
 
-  if (!fLength)
+    if (!fLength)
     {
-      DPRINT("GetProcessImageFileNameW failed(0x%x)ProcessId %d\n", GetLastError(),hProcess);
-      return FALSE;
+        DPRINT("GetProcessImageFileNameW failed(0x%x)ProcessId %d\n", GetLastError(),hProcess);
+        return FALSE;
     }
-  /*
-   * try the process name as path
-   */
+    /*
+     * try the process name as path
+     */
 
-  ptr = wcsrchr(szProcessName, L'\\');
-  wcscpy(GuiData->szProcessName, ptr);
+    ptr = wcsrchr(szProcessName, L'\\');
+    wcscpy(GuiData->szProcessName, ptr);
 
-  swprintf(szBuffer, L"Console%s",ptr);
-  DPRINT("#1 Path : %S\n", szBuffer);
+    swprintf(szBuffer, L"Console%s",ptr);
+    DPRINT("#1 Path : %S\n", szBuffer);
 
-  if (bCreate)
+    if (bCreate)
     {
-      if (RegCreateKeyW(hKey, szBuffer, hSubKey) == ERROR_SUCCESS)
+        if (RegCreateKeyW(hKey, szBuffer, hSubKey) == ERROR_SUCCESS)
         {
-          RegCloseKey(hKey);
-          return TRUE;
+            RegCloseKey(hKey);
+            return TRUE;
         }
-      RegCloseKey(hKey);
-      return FALSE;
-  }
+        RegCloseKey(hKey);
+        return FALSE;
+    }
 
-  if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS)
+    if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS)
     {
-      RegCloseKey(hKey);
-      return TRUE;
+        RegCloseKey(hKey);
+        return TRUE;
     }
 
-  /*
-   * try the "Shortcut to processname" as path
-   * FIXME: detect wheter the process was started as a shortcut
-   */
+    /*
+     * try the "Shortcut to processname" as path
+     * FIXME: detect wheter the process was started as a shortcut
+     */
 
-  swprintf(szBuffer, L"Console\\Shortcut to %S", ptr);
-  DPRINT("#2 Path : %S\n", szBuffer);
-  if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS)
+    swprintf(szBuffer, L"Console\\Shortcut to %S", ptr);
+    DPRINT("#2 Path : %S\n", szBuffer);
+    if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS)
     {
-      swprintf(GuiData->szProcessName, L"Shortcut to %S", ptr);
-      RegCloseKey(hKey);
-      return TRUE;
+        swprintf(GuiData->szProcessName, L"Shortcut to %S", ptr);
+        RegCloseKey(hKey);
+        return TRUE;
     }
 
-  /*
-   * if the path contains \\Device\\HarddiskVolume1\... remove it
-   */
+    /*
+     * if the path contains \\Device\\HarddiskVolume1\... remove it
+     */
 
-  if (szProcessName[0] == L'\\')
+    if (szProcessName[0] == L'\\')
     {
-      dwBitmask = GetLogicalDrives();
-      while(dwBitmask)
+        dwBitmask = GetLogicalDrives();
+        while(dwBitmask)
         {
-          if (dwBitmask & 0x1)
+            if (dwBitmask & 0x1)
             {
-              dwLength = QueryDosDeviceW(CurDrive, szBuffer, MAX_PATH);
-              if (dwLength)
+                dwLength = QueryDosDeviceW(CurDrive, szBuffer, MAX_PATH);
+                if (dwLength)
                 {
-                  if (!memcmp(szBuffer, szProcessName, (dwLength-2)*sizeof(WCHAR)))
+                    if (!memcmp(szBuffer, szProcessName, (dwLength-2)*sizeof(WCHAR)))
                     {
-                      wcscpy(szProcessName, CurDrive);
-                      RtlMoveMemory(&szProcessName[2], &szProcessName[dwLength-1], fLength - dwLength -1);
-                      break;
+                        wcscpy(szProcessName, CurDrive);
+                        RtlMoveMemory(&szProcessName[2], &szProcessName[dwLength-1], fLength - dwLength -1);
+                        break;
                     }
                 }
             }
-          dwBitmask = (dwBitmask >> 1);
-          CurDrive[0]++;
+            dwBitmask = (dwBitmask >> 1);
+            CurDrive[0]++;
         }
     }
 
-  /*
-   * last attempt: check whether the file is under %SystemRoot%
-   * and use path like Console\%SystemRoot%_dir_dir2_file.exe
-   */
+    /*
+     * last attempt: check whether the file is under %SystemRoot%
+     * and use path like Console\%SystemRoot%_dir_dir2_file.exe
+     */
 
-  wLength = GetWindowsDirectoryW(szBuffer, MAX_PATH);
-  if (wLength)
+    wLength = GetWindowsDirectoryW(szBuffer, MAX_PATH);
+    if (wLength)
     {
-      if (!wcsncmp(szProcessName, szBuffer, wLength))
+        if (!wcsncmp(szProcessName, szBuffer, wLength))
         {
-          /* replace slashes by underscores */
-          while((ptr = wcschr(szProcessName, L'\\')))
-            ptr[0] = L'_';
+            /* replace slashes by underscores */
+            while((ptr = wcschr(szProcessName, L'\\')))
+                ptr[0] = L'_';
 
-          swprintf(szBuffer, L"Console\\\%SystemRoot\%%S", &szProcessName[wLength]);
-          DPRINT("#3 Path : %S\n", szBuffer);
-          if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS)
+            swprintf(szBuffer, L"Console\\%%SystemRoot%%%S", &szProcessName[wLength]);
+            DPRINT("#3 Path : %S\n", szBuffer);
+            if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS)
             {
-              swprintf(GuiData->szProcessName, L"\%SystemRoot\%%S", &szProcessName[wLength]);
-              RegCloseKey(hKey);
-              return TRUE;
+                swprintf(GuiData->szProcessName, L"%%SystemRoot%%%S", &szProcessName[wLength]);
+                RegCloseKey(hKey);
+                return TRUE;
             }
         }
     }
-  RegCloseKey(hKey);
-  return FALSE;
+    RegCloseKey(hKey);
+    return FALSE;
 }
 
 static VOID
@@ -396,238 +394,238 @@ GuiConsoleWriteUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData)
     PCSRSS_PROCESS_DATA ProcessData;
 
     if (Console->ProcessList.Flink == &Console->ProcessList)
-      {
+    {
         DPRINT("GuiConsoleWriteUserSettings: No Process!!!\n");
         return;
-      }
+    }
     ProcessData = CONTAINING_RECORD(Console->ProcessList.Flink, CSRSS_PROCESS_DATA, ProcessEntry);
     if (!GuiConsoleOpenUserSettings(GuiData, PtrToUlong(ProcessData->ProcessId), &hKey, KEY_READ | KEY_WRITE, TRUE))
-      {
+    {
         return;
-      }
+    }
 
-  if (Console->ActiveBuffer->CursorInfo.dwSize <= 1)
+    if (Console->ActiveBuffer->CursorInfo.dwSize <= 1)
     {
-      RegDeleteKeyW(hKey, L"CursorSize");
+        RegDeleteKeyW(hKey, L"CursorSize");
     }
-  else
+    else
     {
-      RegSetValueExW(hKey, L"CursorSize", 0, REG_DWORD, (const BYTE *)&Console->ActiveBuffer->CursorInfo.dwSize, sizeof(DWORD));
+        RegSetValueExW(hKey, L"CursorSize", 0, REG_DWORD, (const BYTE *)&Console->ActiveBuffer->CursorInfo.dwSize, sizeof(DWORD));
     }
 
-  if (GuiData->NumberOfHistoryBuffers == 5)
+    if (GuiData->NumberOfHistoryBuffers == 5)
     {
-      RegDeleteKeyW(hKey, L"NumberOfHistoryBuffers");
+        RegDeleteKeyW(hKey, L"NumberOfHistoryBuffers");
     }
-  else
+    else
     {
-      RegSetValueExW(hKey, L"NumberOfHistoryBuffers", 0, REG_DWORD, (const BYTE *)&GuiData->NumberOfHistoryBuffers, sizeof(DWORD));
+        RegSetValueExW(hKey, L"NumberOfHistoryBuffers", 0, REG_DWORD, (const BYTE *)&GuiData->NumberOfHistoryBuffers, sizeof(DWORD));
     }
 
-  if (GuiData->HistoryBufferSize == 50)
+    if (GuiData->HistoryBufferSize == 50)
     {
-      RegDeleteKeyW(hKey, L"HistoryBufferSize");
+        RegDeleteKeyW(hKey, L"HistoryBufferSize");
     }
-  else
+    else
     {
-      RegSetValueExW(hKey, L"HistoryBufferSize", 0, REG_DWORD, (const BYTE *)&GuiData->HistoryBufferSize, sizeof(DWORD));
+        RegSetValueExW(hKey, L"HistoryBufferSize", 0, REG_DWORD, (const BYTE *)&GuiData->HistoryBufferSize, sizeof(DWORD));
     }
 
-  if (GuiData->FullScreen == FALSE)
+    if (GuiData->FullScreen == FALSE)
     {
-      RegDeleteKeyW(hKey, L"FullScreen");
+        RegDeleteKeyW(hKey, L"FullScreen");
     }
-  else
+    else
     {
-      RegSetValueExW(hKey, L"FullScreen", 0, REG_DWORD, (const BYTE *)&GuiData->FullScreen, sizeof(DWORD));
+        RegSetValueExW(hKey, L"FullScreen", 0, REG_DWORD, (const BYTE *)&GuiData->FullScreen, sizeof(DWORD));
     }
 
-  if ( GuiData->QuickEdit == FALSE)
+    if ( GuiData->QuickEdit == FALSE)
     {
-      RegDeleteKeyW(hKey, L"QuickEdit");
+        RegDeleteKeyW(hKey, L"QuickEdit");
     }
     else
     {
-      RegSetValueExW(hKey, L"QuickEdit", 0, REG_DWORD, (const BYTE *)&GuiData->QuickEdit, sizeof(DWORD));
+        RegSetValueExW(hKey, L"QuickEdit", 0, REG_DWORD, (const BYTE *)&GuiData->QuickEdit, sizeof(DWORD));
     }
 
-  if (GuiData->InsertMode == TRUE)
+    if (GuiData->InsertMode == TRUE)
     {
-      RegDeleteKeyW(hKey, L"InsertMode");
+        RegDeleteKeyW(hKey, L"InsertMode");
     }
-  else
+    else
     {
-      RegSetValueExW(hKey, L"InsertMode", 0, REG_DWORD, (const BYTE *)&GuiData->InsertMode, sizeof(DWORD));
+        RegSetValueExW(hKey, L"InsertMode", 0, REG_DWORD, (const BYTE *)&GuiData->InsertMode, sizeof(DWORD));
     }
 
-  if (GuiData->HistoryNoDup == FALSE)
+    if (GuiData->HistoryNoDup == FALSE)
     {
-      RegDeleteKeyW(hKey, L"HistoryNoDup");
+        RegDeleteKeyW(hKey, L"HistoryNoDup");
     }
-  else
+    else
     {
-      RegSetValueExW(hKey, L"HistoryNoDup", 0, REG_DWORD, (const BYTE *)&GuiData->HistoryNoDup, sizeof(DWORD));
+        RegSetValueExW(hKey, L"HistoryNoDup", 0, REG_DWORD, (const BYTE *)&GuiData->HistoryNoDup, sizeof(DWORD));
     }
 
-  if (GuiData->ScreenText == RGB(192, 192, 192))
+    if (GuiData->ScreenText == RGB(192, 192, 192))
     {
-      /*
-       * MS uses console attributes instead of real color
-       */
-       RegDeleteKeyW(hKey, L"ScreenText");
+        /*
+         * MS uses console attributes instead of real color
+         */
+        RegDeleteKeyW(hKey, L"ScreenText");
     }
-  else
+    else
     {
-       RegSetValueExW(hKey, L"ScreenText", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenText, sizeof(COLORREF));
+        RegSetValueExW(hKey, L"ScreenText", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenText, sizeof(COLORREF));
     }
 
-  if (GuiData->ScreenBackground == RGB(0, 0, 0))
+    if (GuiData->ScreenBackground == RGB(0, 0, 0))
     {
-       RegDeleteKeyW(hKey, L"ScreenBackground");
+        RegDeleteKeyW(hKey, L"ScreenBackground");
     }
-  else
+    else
     {
-       RegSetValueExW(hKey, L"ScreenBackground", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenBackground, sizeof(COLORREF));
+        RegSetValueExW(hKey, L"ScreenBackground", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenBackground, sizeof(COLORREF));
     }
 
-  RegCloseKey(hKey);
+    RegCloseKey(hKey);
 }
 
-static void FASTCALL
+static void
 GuiConsoleReadUserSettings(HKEY hKey, PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCSRSS_SCREEN_BUFFER Buffer)
 {
-  DWORD dwNumSubKeys = 0;
-  DWORD dwIndex;
-  DWORD dwValueName;
-  DWORD dwValue;
-  DWORD dwType;
-  WCHAR szValueName[MAX_PATH];
-  WCHAR szValue[LF_FACESIZE] = L"\0";
-  DWORD Value;
-
-  if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwNumSubKeys, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
-    {
-       DPRINT("GuiConsoleReadUserSettings: RegQueryInfoKey failed\n");
-       return;
+    DWORD dwNumSubKeys = 0;
+    DWORD dwIndex;
+    DWORD dwValueName;
+    DWORD dwValue;
+    DWORD dwType;
+    WCHAR szValueName[MAX_PATH];
+    WCHAR szValue[LF_FACESIZE] = L"\0";
+    DWORD Value;
+
+    if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwNumSubKeys, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
+    {
+        DPRINT("GuiConsoleReadUserSettings: RegQueryInfoKey failed\n");
+        return;
     }
 
-  DPRINT("GuiConsoleReadUserSettings entered dwNumSubKeys %d\n", dwNumSubKeys);
+    DPRINT("GuiConsoleReadUserSettings entered dwNumSubKeys %d\n", dwNumSubKeys);
 
-  for (dwIndex = 0; dwIndex < dwNumSubKeys; dwIndex++)
+    for (dwIndex = 0; dwIndex < dwNumSubKeys; dwIndex++)
     {
-      dwValue = sizeof(Value);
-      dwValueName = MAX_PATH;
+        dwValue = sizeof(Value);
+        dwValueName = MAX_PATH;
 
-      if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, &dwType, (BYTE*)&Value, &dwValue) != ERROR_SUCCESS)
+        if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, &dwType, (BYTE*)&Value, &dwValue) != ERROR_SUCCESS)
         {
-          if (dwType == REG_SZ)
+            if (dwType == REG_SZ)
             {
-              /*
-               * retry in case of string value
-               */
-              dwValue = sizeof(szValue);
-              dwValueName = LF_FACESIZE;
-              if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, NULL, (BYTE*)szValue, &dwValue) != ERROR_SUCCESS)
-                break;
+                /*
+                 * retry in case of string value
+                 */
+                dwValue = sizeof(szValue);
+                dwValueName = LF_FACESIZE;
+                if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, NULL, (BYTE*)szValue, &dwValue) != ERROR_SUCCESS)
+                    break;
             }
-          else
-            break;
+            else
+                break;
         }
-      if (!wcscmp(szValueName, L"CursorSize"))
+        if (!wcscmp(szValueName, L"CursorSize"))
         {
-          if (Value == 0x32)
+            if (Value == 0x32)
             {
-              Buffer->CursorInfo.dwSize = Value;
+                Buffer->CursorInfo.dwSize = Value;
             }
-          else if (Value == 0x64)
+            else if (Value == 0x64)
             {
-              Buffer->CursorInfo.dwSize = Value;
+                Buffer->CursorInfo.dwSize = Value;
             }
         }
-      else if (!wcscmp(szValueName, L"ScreenText"))
+        else if (!wcscmp(szValueName, L"ScreenText"))
         {
-          GuiData->ScreenText = Value;
+            GuiData->ScreenText = Value;
         }
-      else if (!wcscmp(szValueName, L"ScreenBackground"))
+        else if (!wcscmp(szValueName, L"ScreenBackground"))
         {
-          GuiData->ScreenBackground = Value;
+            GuiData->ScreenBackground = Value;
         }
-      else if (!wcscmp(szValueName, L"FaceName"))
+        else if (!wcscmp(szValueName, L"FaceName"))
         {
-          wcscpy(GuiData->FontName, szValue);
+            wcscpy(GuiData->FontName, szValue);
         }
-      else if (!wcscmp(szValueName, L"FontSize"))
+        else if (!wcscmp(szValueName, L"FontSize"))
         {
-          GuiData->FontSize = Value;
+            GuiData->FontSize = Value;
         }
-      else if (!wcscmp(szValueName, L"FontWeight"))
+        else if (!wcscmp(szValueName, L"FontWeight"))
         {
-          GuiData->FontWeight = Value;
+            GuiData->FontWeight = Value;
         }
-      else if (!wcscmp(szValueName, L"HistoryNoDup"))
+        else if (!wcscmp(szValueName, L"HistoryNoDup"))
         {
-          GuiData->HistoryNoDup = Value;
+            GuiData->HistoryNoDup = Value;
         }
-      else if (!wcscmp(szValueName, L"WindowSize"))
+        else if (!wcscmp(szValueName, L"WindowSize"))
         {
-          Console->Size.X = LOWORD(Value);
-                 Console->Size.Y = HIWORD(Value);
+            Console->Size.X = LOWORD(Value);
+            Console->Size.Y = HIWORD(Value);
         }
-      else if (!wcscmp(szValueName, L"ScreenBufferSize"))
+        else if (!wcscmp(szValueName, L"ScreenBufferSize"))
         {
             if(Buffer)
-              {
+            {
                 Buffer->MaxX = LOWORD(Value);
                 Buffer->MaxY = HIWORD(Value);
-              }
+            }
         }
-      else if (!wcscmp(szValueName, L"FullScreen"))
+        else if (!wcscmp(szValueName, L"FullScreen"))
         {
-          GuiData->FullScreen = Value;
+            GuiData->FullScreen = Value;
         }
-      else if (!wcscmp(szValueName, L"QuickEdit"))
+        else if (!wcscmp(szValueName, L"QuickEdit"))
         {
-          GuiData->QuickEdit = Value;
+            GuiData->QuickEdit = Value;
         }
-      else if (!wcscmp(szValueName, L"InsertMode"))
+        else if (!wcscmp(szValueName, L"InsertMode"))
         {
-          GuiData->InsertMode = Value;
+            GuiData->InsertMode = Value;
         }
-   }
+    }
 }
-static VOID FASTCALL
+static VOID
 GuiConsoleUseDefaults(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCSRSS_SCREEN_BUFFER Buffer)
 {
-  /*
-   * init guidata with default properties
-   */
-
-  wcscpy(GuiData->FontName, L"DejaVu Sans Mono");
-  GuiData->FontSize = 0x0008000C; // font is 8x12
-  GuiData->FontWeight = FW_NORMAL;
-  GuiData->HistoryNoDup = FALSE;
-  GuiData->FullScreen = FALSE;
-  GuiData->QuickEdit = FALSE;
-  GuiData->InsertMode = TRUE;
-  GuiData->HistoryBufferSize = 50;
-  GuiData->NumberOfHistoryBuffers = 5;
-  GuiData->ScreenText = RGB(192, 192, 192);
-  GuiData->ScreenBackground = RGB(0, 0, 0);
-  GuiData->PopupText = RGB(128, 0, 128);
-  GuiData->PopupBackground = RGB(255, 255, 255);
-  GuiData->WindowPosition = UINT_MAX;
-  GuiData->UseRasterFonts = TRUE;
-  memcpy(GuiData->Colors, s_Colors, sizeof(s_Colors));
-
-  Console->Size.X = 80;
-  Console->Size.Y = 25;
-
-  if (Buffer)
-    {
-      Buffer->MaxX = 80;
-      Buffer->MaxY = 25;
-      Buffer->CursorInfo.bVisible = TRUE;
-      Buffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE;
+    /*
+     * init guidata with default properties
+     */
+
+    wcscpy(GuiData->FontName, L"DejaVu Sans Mono");
+    GuiData->FontSize = 0x0008000C; // font is 8x12
+    GuiData->FontWeight = FW_NORMAL;
+    GuiData->HistoryNoDup = FALSE;
+    GuiData->FullScreen = FALSE;
+    GuiData->QuickEdit = FALSE;
+    GuiData->InsertMode = TRUE;
+    GuiData->HistoryBufferSize = 50;
+    GuiData->NumberOfHistoryBuffers = 5;
+    GuiData->ScreenText = RGB(192, 192, 192);
+    GuiData->ScreenBackground = RGB(0, 0, 0);
+    GuiData->PopupText = RGB(128, 0, 128);
+    GuiData->PopupBackground = RGB(255, 255, 255);
+    GuiData->WindowPosition = UINT_MAX;
+    GuiData->UseRasterFonts = TRUE;
+    memcpy(GuiData->Colors, s_Colors, sizeof(s_Colors));
+
+    Console->Size.X = 80;
+    Console->Size.Y = 25;
+
+    if (Buffer)
+    {
+        Buffer->MaxX = 80;
+        Buffer->MaxY = 300;
+        Buffer->CursorInfo.bVisible = TRUE;
+        Buffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE;
     }
 }
 
@@ -635,217 +633,233 @@ VOID
 FASTCALL
 GuiConsoleInitScrollbar(PCSRSS_CONSOLE Console, HWND hwnd)
 {
-  SCROLLINFO sInfo;
-  PGUI_CONSOLE_DATA GuiData = Console->PrivateData;
-
-  DWORD Width = Console->Size.X * GuiData->CharWidth + 2 * GetSystemMetrics(SM_CXFIXEDFRAME);
-  DWORD Height = Console->Size.Y * GuiData->CharHeight + 2 * GetSystemMetrics(SM_CYFIXEDFRAME) + GetSystemMetrics(SM_CYCAPTION);
-
-  /* set scrollbar sizes */
-  sInfo.cbSize = sizeof(SCROLLINFO);
-  sInfo.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
-  sInfo.nMin = 0;
-  if (Console->ActiveBuffer->MaxY > Console->Size.Y)
-  {
-      sInfo.nMax = Console->ActiveBuffer->MaxY - 1;
-      sInfo.nPage = Console->Size.Y;
-      sInfo.nPos = Console->ActiveBuffer->ShowY;
-      SetScrollInfo(hwnd, SB_VERT, &sInfo, TRUE);
-      Width += GetSystemMetrics(SM_CXVSCROLL);
-      ShowScrollBar(hwnd, SB_VERT, TRUE);
-  }
-  else
-  {
-      ShowScrollBar(hwnd, SB_VERT, FALSE);
-  }
-
-  if (Console->ActiveBuffer->MaxX > Console->Size.X)
-  {
-      sInfo.nMax = Console->ActiveBuffer->MaxX - 1;
-      sInfo.nPage = Console->Size.X;
-      sInfo.nPos = Console->ActiveBuffer->ShowX;
-      SetScrollInfo(hwnd, SB_HORZ, &sInfo, TRUE);
-      Height += GetSystemMetrics(SM_CYHSCROLL);
-      ShowScrollBar(hwnd, SB_HORZ, TRUE);
-  }
-  else
-  {
-      ShowScrollBar(hwnd, SB_HORZ, FALSE);
-  }
-
-  SetWindowPos(hwnd, NULL, 0, 0, Width, Height,
-               SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
+    SCROLLINFO sInfo;
+    PGUI_CONSOLE_DATA GuiData = Console->PrivateData;
+
+    DWORD Width = Console->Size.X * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE));
+    DWORD Height = Console->Size.Y * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION);
+
+    /* set scrollbar sizes */
+    sInfo.cbSize = sizeof(SCROLLINFO);
+    sInfo.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
+    sInfo.nMin = 0;
+    if (Console->ActiveBuffer->MaxY > Console->Size.Y)
+    {
+        sInfo.nMax = Console->ActiveBuffer->MaxY - 1;
+        sInfo.nPage = Console->Size.Y;
+        sInfo.nPos = Console->ActiveBuffer->ShowY;
+        SetScrollInfo(hwnd, SB_VERT, &sInfo, TRUE);
+        Width += GetSystemMetrics(SM_CXVSCROLL);
+        ShowScrollBar(hwnd, SB_VERT, TRUE);
+    }
+    else
+    {
+        ShowScrollBar(hwnd, SB_VERT, FALSE);
+    }
+
+    if (Console->ActiveBuffer->MaxX > Console->Size.X)
+    {
+        sInfo.nMax = Console->ActiveBuffer->MaxX - 1;
+        sInfo.nPage = Console->Size.X;
+        sInfo.nPos = Console->ActiveBuffer->ShowX;
+        SetScrollInfo(hwnd, SB_HORZ, &sInfo, TRUE);
+        Height += GetSystemMetrics(SM_CYHSCROLL);
+        ShowScrollBar(hwnd, SB_HORZ, TRUE);
+
+    }
+    else
+    {
+        ShowScrollBar(hwnd, SB_HORZ, FALSE);
+    }
+
+    SetWindowPos(hwnd, NULL, 0, 0, Width, Height,
+                 SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
 }
 
-static BOOL FASTCALL
+static BOOL
 GuiConsoleHandleNcCreate(HWND hWnd, CREATESTRUCTW *Create)
 {
-  PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Create->lpCreateParams;
-  PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)Console->PrivateData;
-  HDC Dc;
-  HFONT OldFont;
-  TEXTMETRICW Metrics;
-  PCSRSS_PROCESS_DATA ProcessData;
-  HKEY hKey;
+    PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Create->lpCreateParams;
+    PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)Console->PrivateData;
+    HDC Dc;
+    HFONT OldFont;
+    TEXTMETRICW Metrics;
+    SIZE CharSize;
+    PCSRSS_PROCESS_DATA ProcessData;
+    HKEY hKey;
 
-  Console->hWindow = hWnd;
+    Console->hWindow = hWnd;
 
-  if (NULL == GuiData)
+    if (NULL == GuiData)
     {
-      DPRINT1("GuiConsoleNcCreate: HeapAlloc failed\n");
-      return FALSE;
+        DPRINT1("GuiConsoleNcCreate: HeapAlloc failed\n");
+        return FALSE;
     }
 
-  GuiConsoleUseDefaults(Console, GuiData, Console->ActiveBuffer);
-  if (Console->ProcessList.Flink != &Console->ProcessList)
+    GuiConsoleUseDefaults(Console, GuiData, Console->ActiveBuffer);
+    if (Console->ProcessList.Flink != &Console->ProcessList)
     {
-      ProcessData = CONTAINING_RECORD(Console->ProcessList.Flink, CSRSS_PROCESS_DATA, ProcessEntry);
-      if (GuiConsoleOpenUserSettings(GuiData, PtrToUlong(ProcessData->ProcessId), &hKey, KEY_READ, FALSE))
+        ProcessData = CONTAINING_RECORD(Console->ProcessList.Flink, CSRSS_PROCESS_DATA, ProcessEntry);
+        if (GuiConsoleOpenUserSettings(GuiData, PtrToUlong(ProcessData->ProcessId), &hKey, KEY_READ, FALSE))
         {
-          GuiConsoleReadUserSettings(hKey, Console, GuiData, Console->ActiveBuffer);
-          RegCloseKey(hKey);
+            GuiConsoleReadUserSettings(hKey, Console, GuiData, Console->ActiveBuffer);
+            RegCloseKey(hKey);
         }
     }
 
-  InitializeCriticalSection(&GuiData->Lock);
-
-  GuiData->LineBuffer = (PWCHAR)HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY,
-                                          Console->Size.X * sizeof(WCHAR));
-
-  GuiData->Font = CreateFontW(LOWORD(GuiData->FontSize),
-                              0, //HIWORD(GuiData->FontSize),
-                              0,
-                              TA_BASELINE,
-                              GuiData->FontWeight,
-                              FALSE,
-                              FALSE,
-                              FALSE,
-                              OEM_CHARSET,
-                              OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
-                              NONANTIALIASED_QUALITY, FIXED_PITCH | FF_DONTCARE,
-                              GuiData->FontName);
-  if (NULL == GuiData->Font)
-    {
-      DPRINT1("GuiConsoleNcCreate: CreateFont failed\n");
-      DeleteCriticalSection(&GuiData->Lock);
-      HeapFree(Win32CsrApiHeap, 0, GuiData);
-      return FALSE;
-    }
-  Dc = GetDC(hWnd);
-  if (NULL == Dc)
-    {
-      DPRINT1("GuiConsoleNcCreate: GetDC failed\n");
-      DeleteObject(GuiData->Font);
-      DeleteCriticalSection(&GuiData->Lock);
-      HeapFree(Win32CsrApiHeap, 0, GuiData);
-      return FALSE;
-    }
-  OldFont = SelectObject(Dc, GuiData->Font);
-  if (NULL == OldFont)
-    {
-      DPRINT1("GuiConsoleNcCreate: SelectObject failed\n");
-      ReleaseDC(hWnd, Dc);
-      DeleteObject(GuiData->Font);
-      DeleteCriticalSection(&GuiData->Lock);
-      HeapFree(Win32CsrApiHeap, 0, GuiData);
-      return FALSE;
-    }
-  if (! GetTextMetricsW(Dc, &Metrics))
-    {
-      DPRINT1("GuiConsoleNcCreate: GetTextMetrics failed\n");
-      SelectObject(Dc, OldFont);
-      ReleaseDC(hWnd, Dc);
-      DeleteObject(GuiData->Font);
-      DeleteCriticalSection(&GuiData->Lock);
-      HeapFree(Win32CsrApiHeap, 0, GuiData);
-      return FALSE;
-    }
-  GuiData->CharWidth = Metrics.tmMaxCharWidth;
-  GuiData->CharHeight = Metrics.tmHeight + Metrics.tmExternalLeading;
-  SelectObject(Dc, OldFont);
-
-  ReleaseDC(hWnd, Dc);
-  GuiData->CursorBlinkOn = TRUE;
-  GuiData->ForceCursorOff = FALSE;
-
-  GuiData->Selection.left = -1;
-  DPRINT("Console %p GuiData %p\n", Console, GuiData);
-  Console->PrivateData = GuiData;
-  SetWindowLongPtrW(hWnd, GWL_USERDATA, (DWORD_PTR) Console);
-
-  SetTimer(hWnd, 1, CURSOR_BLINK_TIME, NULL);
-  GuiConsoleCreateSysMenu(Console);
-  GuiConsoleInitScrollbar(Console, hWnd);
-  SetEvent(GuiData->hGuiInitEvent);
-
-  return (BOOL) DefWindowProcW(hWnd, WM_NCCREATE, 0, (LPARAM) Create);
+    InitializeCriticalSection(&GuiData->Lock);
+
+    GuiData->Font = CreateFontW(LOWORD(GuiData->FontSize),
+                                0, //HIWORD(GuiData->FontSize),
+                                0,
+                                TA_BASELINE,
+                                GuiData->FontWeight,
+                                FALSE,
+                                FALSE,
+                                FALSE,
+                                OEM_CHARSET,
+                                OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
+                                NONANTIALIASED_QUALITY, FIXED_PITCH | FF_DONTCARE,
+                                GuiData->FontName);
+    if (NULL == GuiData->Font)
+    {
+        DPRINT1("GuiConsoleNcCreate: CreateFont failed\n");
+        DeleteCriticalSection(&GuiData->Lock);
+        HeapFree(Win32CsrApiHeap, 0, GuiData);
+        return FALSE;
+    }
+    Dc = GetDC(hWnd);
+    if (NULL == Dc)
+    {
+        DPRINT1("GuiConsoleNcCreate: GetDC failed\n");
+        DeleteObject(GuiData->Font);
+        DeleteCriticalSection(&GuiData->Lock);
+        HeapFree(Win32CsrApiHeap, 0, GuiData);
+        return FALSE;
+    }
+    OldFont = SelectObject(Dc, GuiData->Font);
+    if (NULL == OldFont)
+    {
+        DPRINT1("GuiConsoleNcCreate: SelectObject failed\n");
+        ReleaseDC(hWnd, Dc);
+        DeleteObject(GuiData->Font);
+        DeleteCriticalSection(&GuiData->Lock);
+        HeapFree(Win32CsrApiHeap, 0, GuiData);
+        return FALSE;
+    }
+    if (! GetTextMetricsW(Dc, &Metrics))
+    {
+        DPRINT1("GuiConsoleNcCreate: GetTextMetrics failed\n");
+        SelectObject(Dc, OldFont);
+        ReleaseDC(hWnd, Dc);
+        DeleteObject(GuiData->Font);
+        DeleteCriticalSection(&GuiData->Lock);
+        HeapFree(Win32CsrApiHeap, 0, GuiData);
+        return FALSE;
+    }
+    GuiData->CharWidth = Metrics.tmMaxCharWidth;
+    GuiData->CharHeight = Metrics.tmHeight + Metrics.tmExternalLeading;
+
+    /* Measure real char width more precisely if possible. */
+    if (GetTextExtentPoint32W(Dc, L"R", 1, &CharSize))
+        GuiData->CharWidth = CharSize.cx;
+
+    SelectObject(Dc, OldFont);
+
+    ReleaseDC(hWnd, Dc);
+    GuiData->CursorBlinkOn = TRUE;
+    GuiData->ForceCursorOff = FALSE;
+
+    DPRINT("Console %p GuiData %p\n", Console, GuiData);
+    Console->PrivateData = GuiData;
+    SetWindowLongPtrW(hWnd, GWL_USERDATA, (DWORD_PTR) Console);
+
+    SetTimer(hWnd, CONGUI_UPDATE_TIMER, CONGUI_UPDATE_TIME, NULL);
+    GuiConsoleCreateSysMenu(Console);
+
+    GuiData->WindowSizeLock = TRUE;
+    GuiConsoleInitScrollbar(Console, hWnd);
+    GuiData->WindowSizeLock = FALSE;
+
+    SetEvent(GuiData->hGuiInitEvent);
+
+    return (BOOL) DefWindowProcW(hWnd, WM_NCCREATE, 0, (LPARAM) Create);
 }
 
-static VOID FASTCALL
-GuiConsoleUpdateSelection(HWND hWnd, PRECT rc, PGUI_CONSOLE_DATA GuiData)
+static VOID
+SmallRectToRect(PCSRSS_CONSOLE Console, PRECT Rect, PSMALL_RECT SmallRect)
 {
-  RECT oldRect = GuiData->Selection;
-
-  if(rc != NULL)
-  {
-    RECT changeRect = *rc;
+    PCSRSS_SCREEN_BUFFER Buffer = Console->ActiveBuffer;
+    PGUI_CONSOLE_DATA GuiData = Console->PrivateData;
+    Rect->left   = (SmallRect->Left       - Buffer->ShowX) * GuiData->CharWidth;
+    Rect->top    = (SmallRect->Top        - Buffer->ShowY) * GuiData->CharHeight;
+    Rect->right  = (SmallRect->Right  + 1 - Buffer->ShowX) * GuiData->CharWidth;
+    Rect->bottom = (SmallRect->Bottom + 1 - Buffer->ShowY) * GuiData->CharHeight;
+}
 
-    GuiData->Selection = *rc;
+static VOID
+GuiConsoleUpdateSelection(PCSRSS_CONSOLE Console, PCOORD coord)
+{
+    RECT oldRect, newRect;
+    HWND hWnd = Console->hWindow;
 
-    changeRect.left *= GuiData->CharWidth;
-    changeRect.top *= GuiData->CharHeight;
-    changeRect.right *= GuiData->CharWidth;
-    changeRect.bottom *= GuiData->CharHeight;
+    SmallRectToRect(Console, &oldRect, &Console->Selection.srSelection);
 
-    if(rc->left != oldRect.left ||
-       rc->top != oldRect.top ||
-       rc->right != oldRect.right ||
-       rc->bottom != oldRect.bottom)
+    if(coord != NULL)
     {
-      if(oldRect.left != -1)
-      {
-        HRGN rgn1, rgn2;
+        SMALL_RECT rc;
+        /* exchange left/top with right/bottom if required */
+        rc.Left   = min(Console->Selection.dwSelectionAnchor.X, coord->X);
+        rc.Top    = min(Console->Selection.dwSelectionAnchor.Y, coord->Y);
+        rc.Right  = max(Console->Selection.dwSelectionAnchor.X, coord->X);
+        rc.Bottom = max(Console->Selection.dwSelectionAnchor.Y, coord->Y);
 
-        oldRect.left *= GuiData->CharWidth;
-        oldRect.top *= GuiData->CharHeight;
-        oldRect.right *= GuiData->CharWidth;
-        oldRect.bottom *= GuiData->CharHeight;
+        SmallRectToRect(Console, &newRect, &rc);
 
-        /* calculate the region that needs to be updated */
-        if((rgn1 = CreateRectRgnIndirect(&oldRect)))
+        if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY)
         {
-          if((rgn2 = CreateRectRgnIndirect(&changeRect)))
-          {
-            if(CombineRgn(rgn1, rgn2, rgn1, RGN_XOR) != ERROR)
+            if (memcmp(&rc, &Console->Selection.srSelection, sizeof(SMALL_RECT)) != 0)
             {
-              InvalidateRgn(hWnd, rgn1, FALSE);
-            }
+                HRGN rgn1, rgn2;
+
+                /* calculate the region that needs to be updated */
+                if((rgn1 = CreateRectRgnIndirect(&oldRect)))
+                {
+                    if((rgn2 = CreateRectRgnIndirect(&newRect)))
+                    {
+                        if(CombineRgn(rgn1, rgn2, rgn1, RGN_XOR) != ERROR)
+                        {
+                            InvalidateRgn(hWnd, rgn1, FALSE);
+                        }
 
-            DeleteObject(rgn2);
-          }
-          DeleteObject(rgn1);
+                        DeleteObject(rgn2);
+                    }
+                    DeleteObject(rgn1);
+                }
+            }
+        }
+        else
+        {
+            InvalidateRect(hWnd, &newRect, FALSE);
+        }
+        Console->Selection.dwFlags |= CONSOLE_SELECTION_NOT_EMPTY;
+        Console->Selection.srSelection = rc;
+        ConioPause(Console, PAUSED_FROM_SELECTION);
+    }
+    else
+    {
+        /* clear the selection */
+        if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY)
+        {
+            InvalidateRect(hWnd, &oldRect, FALSE);
         }
-      }
-      else
-      {
-        InvalidateRect(hWnd, &changeRect, FALSE);
-      }
-    }
-  }
-  else if(oldRect.left != -1)
-  {
-    /* clear the selection */
-    GuiData->Selection.left = -1;
-    oldRect.left *= GuiData->CharWidth;
-    oldRect.top *= GuiData->CharHeight;
-    oldRect.right *= GuiData->CharWidth;
-    oldRect.bottom *= GuiData->CharHeight;
-    InvalidateRect(hWnd, &oldRect, FALSE);
-  }
+        Console->Selection.dwFlags = CONSOLE_NO_SELECTION;
+        ConioUnpause(Console, PAUSED_FROM_SELECTION);
+    }
 }
 
 
-static VOID FASTCALL
+static VOID
 GuiConsolePaint(PCSRSS_CONSOLE Console,
                 PGUI_CONSOLE_DATA GuiData,
                 HDC hDC,
@@ -863,7 +877,7 @@ GuiConsolePaint(PCSRSS_CONSOLE Console,
 
     Buff = Console->ActiveBuffer;
 
-    EnterCriticalSection(&Buff->Header.Lock);
+    EnterCriticalSection(&Buff->Header.Console->Lock);
 
     TopLine = rc->top / GuiData->CharHeight + Buff->ShowY;
     BottomLine = (rc->bottom + (GuiData->CharHeight - 1)) / GuiData->CharHeight - 1 + Buff->ShowY;
@@ -882,21 +896,22 @@ GuiConsolePaint(PCSRSS_CONSOLE Console,
 
     for (Line = TopLine; Line <= BottomLine; Line++)
     {
+        WCHAR LineBuffer[80];
         From = ConioCoordToPointer(Buff, LeftChar, Line);
         Start = LeftChar;
-        To = GuiData->LineBuffer;
+        To = LineBuffer;
 
         for (Char = LeftChar; Char <= RightChar; Char++)
         {
-            if (*(From + 1) != LastAttribute)
+            if (*(From + 1) != LastAttribute || (Char - Start == sizeof(LineBuffer) / sizeof(WCHAR)))
             {
                 TextOutW(hDC,
                          (Start - Buff->ShowX) * GuiData->CharWidth,
                          (Line - Buff->ShowY) * GuiData->CharHeight,
-                         GuiData->LineBuffer,
+                         LineBuffer,
                          Char - Start);
                 Start = Char;
-                To = GuiData->LineBuffer;
+                To = LineBuffer;
                 Attribute = *(From + 1);
                 if (Attribute != LastAttribute)
                 {
@@ -919,17 +934,17 @@ GuiConsolePaint(PCSRSS_CONSOLE Console,
         TextOutW(hDC,
                  (Start - Buff->ShowX) * GuiData->CharWidth,
                  (Line - Buff->ShowY) * GuiData->CharHeight,
-                 GuiData->LineBuffer,
+                 LineBuffer,
                  RightChar - Start + 1);
     }
 
     if (Buff->CursorInfo.bVisible && GuiData->CursorBlinkOn &&
-        !GuiData->ForceCursorOff)
+            !GuiData->ForceCursorOff)
     {
         CursorX = Buff->CurrentX;
         CursorY = Buff->CurrentY;
         if (LeftChar <= CursorX && CursorX <= RightChar &&
-            TopLine <= CursorY && CursorY <= BottomLine)
+                TopLine <= CursorY && CursorY <= BottomLine)
         {
             CursorHeight = (GuiData->CharHeight * Buff->CursorInfo.dwSize) / 100;
             if (CursorHeight < 1)
@@ -961,13 +976,13 @@ GuiConsolePaint(PCSRSS_CONSOLE Console,
         }
     }
 
-    LeaveCriticalSection(&Buff->Header.Lock);
+    LeaveCriticalSection(&Buff->Header.Console->Lock);
 
     SelectObject(hDC,
                  OldFont);
 }
 
-static VOID FASTCALL
+static VOID
 GuiConsoleHandlePaint(HWND hWnd, HDC hDCPaint)
 {
     HDC hDC;
@@ -977,14 +992,14 @@ GuiConsoleHandlePaint(HWND hWnd, HDC hDCPaint)
 
     hDC = BeginPaint(hWnd, &ps);
     if (hDC != NULL &&
-        ps.rcPaint.left < ps.rcPaint.right &&
-        ps.rcPaint.top < ps.rcPaint.bottom)
+            ps.rcPaint.left < ps.rcPaint.right &&
+            ps.rcPaint.top < ps.rcPaint.bottom)
     {
         GuiConsoleGetDataPointers(hWnd,
                                   &Console,
                                   &GuiData);
         if (Console != NULL && GuiData != NULL &&
-            Console->ActiveBuffer != NULL)
+                Console->ActiveBuffer != NULL)
         {
             if (Console->ActiveBuffer->Buffer != NULL)
             {
@@ -995,14 +1010,10 @@ GuiConsoleHandlePaint(HWND hWnd, HDC hDCPaint)
                                 hDC,
                                 &ps.rcPaint);
 
-                if (GuiData->Selection.left != -1)
+                if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY)
                 {
-                    RECT rc = GuiData->Selection;
-
-                    rc.left *= GuiData->CharWidth;
-                    rc.top *= GuiData->CharHeight;
-                    rc.right *= GuiData->CharWidth;
-                    rc.bottom *= GuiData->CharHeight;
+                    RECT rc;
+                    SmallRectToRect(Console, &rc, &Console->Selection.srSelection);
 
                     /* invert the selection */
                     if (IntersectRect(&rc,
@@ -1026,172 +1037,120 @@ GuiConsoleHandlePaint(HWND hWnd, HDC hDCPaint)
     EndPaint(hWnd, &ps);
 }
 
-static VOID FASTCALL
+static VOID
 GuiConsoleHandleKey(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
-  PCSRSS_CONSOLE Console;
-  PGUI_CONSOLE_DATA GuiData;
-  MSG Message;
-
-  GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
-  Message.hwnd = hWnd;
-  Message.message = msg;
-  Message.wParam = wParam;
-  Message.lParam = lParam;
-
-  if(msg == WM_CHAR || msg == WM_SYSKEYDOWN)
-  {
-    /* clear the selection */
-    GuiConsoleUpdateSelection(hWnd, NULL, GuiData);
-  }
-
-  ConioProcessKey(&Message, Console, FALSE);
-}
+    PCSRSS_CONSOLE Console;
+    PGUI_CONSOLE_DATA GuiData;
+    MSG Message;
 
-static VOID FASTCALL
-GuiIntDrawRegion(PCSRSS_SCREEN_BUFFER Buff, PGUI_CONSOLE_DATA GuiData, HWND Wnd, RECT *Region)
-{
-  RECT RegionRect;
+    GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
+    Message.hwnd = hWnd;
+    Message.message = msg;
+    Message.wParam = wParam;
+    Message.lParam = lParam;
 
-  RegionRect.left = (Region->left - Buff->ShowX) * GuiData->CharWidth;
-  RegionRect.top = (Region->top - Buff->ShowY) * GuiData->CharHeight;
-  RegionRect.right = (Region->right + 1 - Buff->ShowX) * GuiData->CharWidth;
-  RegionRect.bottom = (Region->bottom + 1 - Buff->ShowY) * GuiData->CharHeight;
+    if(msg == WM_CHAR || msg == WM_SYSKEYDOWN)
+    {
+        /* clear the selection */
+        GuiConsoleUpdateSelection(Console, NULL);
+    }
 
-  InvalidateRect(Wnd, &RegionRect, FALSE);
+    ConioProcessKey(&Message, Console, FALSE);
 }
 
 static VOID WINAPI
-GuiDrawRegion(PCSRSS_CONSOLE Console, RECT *Region)
+GuiDrawRegion(PCSRSS_CONSOLE Console, SMALL_RECT *Region)
 {
-  PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData;
-
-  if (NULL != Console->hWindow && NULL != GuiData)
-    {
-      GuiIntDrawRegion(Console->ActiveBuffer, GuiData, Console->hWindow, Region);
-    }
+    RECT RegionRect;
+    SmallRectToRect(Console, &RegionRect, Region);
+    InvalidateRect(Console->hWindow, &RegionRect, FALSE);
 }
 
-static VOID FASTCALL
-GuiInvalidateCell(PCSRSS_SCREEN_BUFFER Buff, PGUI_CONSOLE_DATA GuiData, HWND Wnd, UINT x, UINT y)
+static VOID
+GuiInvalidateCell(PCSRSS_CONSOLE Console, UINT x, UINT y)
 {
-  RECT CellRect;
-
-  CellRect.left = x;
-  CellRect.top = y;
-  CellRect.right = x;
-  CellRect.bottom = y;
-
-  GuiIntDrawRegion(Buff, GuiData, Wnd, &CellRect);
+    SMALL_RECT CellRect = { x, y, x, y };
+    GuiDrawRegion(Console, &CellRect);
 }
 
 static VOID WINAPI
-GuiWriteStream(PCSRSS_CONSOLE Console, RECT *Region, LONG CursorStartX, LONG CursorStartY,
+GuiWriteStream(PCSRSS_CONSOLE Console, SMALL_RECT *Region, LONG CursorStartX, LONG CursorStartY,
                UINT ScrolledLines, CHAR *Buffer, UINT Length)
 {
-  PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData;
-  PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer;
-  LONG CursorEndX, CursorEndY;
-  RECT ScrollRect;
+    PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData;
+    PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer;
+    LONG CursorEndX, CursorEndY;
+    RECT ScrollRect;
 
-  if (NULL == Console->hWindow || NULL == GuiData)
+    if (NULL == Console->hWindow || NULL == GuiData)
     {
-      return;
+        return;
     }
 
-  if (0 != ScrolledLines)
+    if (0 != ScrolledLines)
     {
-      ScrollRect.left = 0;
-      ScrollRect.top = 0;
-      ScrollRect.right = Console->Size.X * GuiData->CharWidth;
-      ScrollRect.bottom = Region->top * GuiData->CharHeight;
+        ScrollRect.left = 0;
+        ScrollRect.top = 0;
+        ScrollRect.right = Console->Size.X * GuiData->CharWidth;
+        ScrollRect.bottom = Region->Top * GuiData->CharHeight;
 
-      if (GuiData->Selection.left != -1)
-      {
-          /* scroll the selection */
-          if (GuiData->Selection.top > ScrolledLines)
-          {
-              GuiData->Selection.top -= ScrolledLines;
-              GuiData->Selection.bottom -= ScrolledLines;
-          }
-          else if (GuiData->Selection.bottom < ScrolledLines)
-          {
-              GuiData->Selection.left = -1;
-          }
-          else
-          {
-              GuiData->Selection.top = 0;
-              GuiData->Selection.bottom -= ScrolledLines;
-          }
-      }
-
-      ScrollWindowEx(Console->hWindow,
-                     0,
-                     -(ScrolledLines * GuiData->CharHeight),
-                     &ScrollRect,
-                     NULL,
-                     NULL,
-                     NULL,
-                     SW_INVALIDATE);
+        ScrollWindowEx(Console->hWindow,
+                       0,
+                       -(ScrolledLines * GuiData->CharHeight),
+                       &ScrollRect,
+                       NULL,
+                       NULL,
+                       NULL,
+                       SW_INVALIDATE);
     }
 
-  GuiIntDrawRegion(Buff, GuiData, Console->hWindow, Region);
+    GuiDrawRegion(Console, Region);
 
-  if (CursorStartX < Region->left || Region->right < CursorStartX
-      || CursorStartY < Region->top || Region->bottom < CursorStartY)
+    if (CursorStartX < Region->Left || Region->Right < CursorStartX
+            || CursorStartY < Region->Top || Region->Bottom < CursorStartY)
     {
-      GuiInvalidateCell(Buff, GuiData, Console->hWindow, CursorStartX, CursorStartY);
+        GuiInvalidateCell(Console, CursorStartX, CursorStartY);
     }
 
-  CursorEndX = Buff->CurrentX;
-  CursorEndY = Buff->CurrentY;
-  if ((CursorEndX < Region->left || Region->right < CursorEndX
-       || CursorEndY < Region->top || Region->bottom < CursorEndY)
-      && (CursorEndX != CursorStartX || CursorEndY != CursorStartY))
+    CursorEndX = Buff->CurrentX;
+    CursorEndY = Buff->CurrentY;
+    if ((CursorEndX < Region->Left || Region->Right < CursorEndX
+            || CursorEndY < Region->Top || Region->Bottom < CursorEndY)
+            && (CursorEndX != CursorStartX || CursorEndY != CursorStartY))
     {
-      GuiInvalidateCell(Buff, GuiData, Console->hWindow, CursorEndX, CursorEndY);
+        GuiInvalidateCell(Console, CursorEndX, CursorEndY);
     }
+
+    // Set up the update timer (very short interval) - this is a "hack" for getting the OS to
+    // repaint the window without having it just freeze up and stay on the screen permanently.
+    GuiData->CursorBlinkOn = TRUE;
+    SetTimer(Console->hWindow, CONGUI_UPDATE_TIMER, CONGUI_UPDATE_TIME, NULL);
 }
 
 static BOOL WINAPI
 GuiSetCursorInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff)
 {
-  RECT UpdateRect;
-
-  if (Console->ActiveBuffer == Buff)
+    if (Console->ActiveBuffer == Buff)
     {
-      UpdateRect.left = Buff->CurrentX;
-      UpdateRect.top = Buff->CurrentY;
-      UpdateRect.right = UpdateRect.left;
-      UpdateRect.bottom = UpdateRect.top;
-      ConioDrawRegion(Console, &UpdateRect);
+        GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY);
     }
 
-  return TRUE;
+    return TRUE;
 }
 
 static BOOL WINAPI
 GuiSetScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, UINT OldCursorX, UINT OldCursorY)
 {
-  RECT UpdateRect;
-
-  if (Console->ActiveBuffer == Buff)
+    if (Console->ActiveBuffer == Buff)
     {
-      /* Redraw char at old position (removes cursor) */
-      UpdateRect.left = OldCursorX;
-      UpdateRect.top = OldCursorY;
-      UpdateRect.right = OldCursorX;
-      UpdateRect.bottom = OldCursorY;
-      ConioDrawRegion(Console, &UpdateRect);
-      /* Redraw char at new position (shows cursor) */
-      UpdateRect.left = Buff->CurrentX;
-      UpdateRect.top = Buff->CurrentY;
-      UpdateRect.right = UpdateRect.left;
-      UpdateRect.bottom = UpdateRect.top;
-      ConioDrawRegion(Console, &UpdateRect);
+        /* Redraw char at old position (removes cursor) */
+        GuiInvalidateCell(Console, OldCursorX, OldCursorY);
+        /* Redraw char at new position (shows cursor) */
+        GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY);
     }
 
-  return TRUE;
+    return TRUE;
 }
 
 static BOOL WINAPI
@@ -1208,204 +1167,232 @@ GuiUpdateScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff)
     return TRUE;
 }
 
-static VOID FASTCALL
+static VOID
 GuiConsoleHandleTimer(HWND hWnd)
 {
-  PCSRSS_CONSOLE Console;
-  PGUI_CONSOLE_DATA GuiData;
-  RECT CursorRect;
-
-  GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
-  GuiData->CursorBlinkOn = ! GuiData->CursorBlinkOn;
-
-  CursorRect.left = Console->ActiveBuffer->CurrentX;
-  CursorRect.top = Console->ActiveBuffer->CurrentY;
-  CursorRect.right = CursorRect.left;
-  CursorRect.bottom = CursorRect.top;
-  GuiDrawRegion(Console, &CursorRect);
+    PCSRSS_CONSOLE Console;
+    PGUI_CONSOLE_DATA GuiData;
+    PCSRSS_SCREEN_BUFFER Buff;
+
+    SetTimer(hWnd, CONGUI_UPDATE_TIMER, CURSOR_BLINK_TIME, NULL);
+
+    GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
+
+    Buff = Console->ActiveBuffer;
+    GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY);
+    GuiData->CursorBlinkOn = ! GuiData->CursorBlinkOn;
+
+    if((GuiData->OldCursor.x != Buff->CurrentX) || (GuiData->OldCursor.y != Buff->CurrentY))
+    {
+        SCROLLINFO xScroll;
+        int OldScrollX = -1, OldScrollY = -1;
+        int NewScrollX = -1, NewScrollY = -1;
+
+        xScroll.cbSize = sizeof(SCROLLINFO);
+        xScroll.fMask = SIF_POS;
+        // Capture the original position of the scroll bars and save them.
+        if(GetScrollInfo(hWnd, SB_HORZ, &xScroll))OldScrollX = xScroll.nPos;
+        if(GetScrollInfo(hWnd, SB_VERT, &xScroll))OldScrollY = xScroll.nPos;
+
+        // If we successfully got the info for the horizontal scrollbar
+        if(OldScrollX >= 0)
+        {
+            if((Buff->CurrentX < Buff->ShowX)||(Buff->CurrentX >= (Buff->ShowX + Console->Size.X)))
+            {
+                // Handle the horizontal scroll bar
+                if(Buff->CurrentX >= Console->Size.X) NewScrollX = Buff->CurrentX - Console->Size.X + 1;
+                else NewScrollX = 0;
+            }
+            else
+            {
+                NewScrollX = OldScrollX;
+            }
+        }
+        // If we successfully got the info for the vertical scrollbar
+        if(OldScrollY >= 0)
+        {
+            if((Buff->CurrentY < Buff->ShowY) || (Buff->CurrentY >= (Buff->ShowY + Console->Size.Y)))
+            {
+                // Handle the vertical scroll bar
+                if(Buff->CurrentY >= Console->Size.Y) NewScrollY = Buff->CurrentY - Console->Size.Y + 1;
+                else NewScrollY = 0;
+            }
+            else
+            {
+                NewScrollY = OldScrollY;
+            }
+        }
+
+        // Adjust scroll bars and refresh the window if the cursor has moved outside the visible area
+        // NOTE: OldScroll# and NewScroll# will both be -1 (initial value) if the info for the respective scrollbar
+        //       was not obtained successfully in the previous steps. This means their difference is 0 (no scrolling)
+        //       and their associated scrollbar is left alone.
+        if((OldScrollX != NewScrollX) || (OldScrollY != NewScrollY))
+        {
+            Buff->ShowX = NewScrollX;
+            Buff->ShowY = NewScrollY;
+            ScrollWindowEx(hWnd,
+                           (OldScrollX - NewScrollX) * GuiData->CharWidth,
+                           (OldScrollY - NewScrollY) * GuiData->CharHeight,
+                           NULL,
+                           NULL,
+                           NULL,
+                           NULL,
+                           SW_INVALIDATE);
+            if(NewScrollX >= 0)
+            {
+                xScroll.nPos = NewScrollX;
+                SetScrollInfo(hWnd, SB_HORZ, &xScroll, TRUE);
+            }
+            if(NewScrollY >= 0)
+            {
+                xScroll.nPos = NewScrollY;
+                SetScrollInfo(hWnd, SB_VERT, &xScroll, TRUE);
+            }
+            UpdateWindow(hWnd);
+            GuiData->OldCursor.x = Buff->CurrentX;
+            GuiData->OldCursor.y = Buff->CurrentY;
+        }
+    }
 }
 
-static VOID FASTCALL
+static VOID
 GuiConsoleHandleClose(HWND hWnd)
 {
-  PCSRSS_CONSOLE Console;
-  PGUI_CONSOLE_DATA GuiData;
-  PLIST_ENTRY current_entry;
-  PCSRSS_PROCESS_DATA current;
+    PCSRSS_CONSOLE Console;
+    PGUI_CONSOLE_DATA GuiData;
+    PLIST_ENTRY current_entry;
+    PCSRSS_PROCESS_DATA current;
 
-  GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
+    GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
 
-  EnterCriticalSection(&Console->Header.Lock);
+    EnterCriticalSection(&Console->Lock);
 
-  current_entry = Console->ProcessList.Flink;
-  while (current_entry != &Console->ProcessList)
+    current_entry = Console->ProcessList.Flink;
+    while (current_entry != &Console->ProcessList)
     {
-      current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry);
-      current_entry = current_entry->Flink;
+        current = CONTAINING_RECORD(current_entry, CSRSS_PROCESS_DATA, ProcessEntry);
+        current_entry = current_entry->Flink;
 
-      /* FIXME: Windows will wait up to 5 seconds for the thread to exit.
-       * We shouldn't wait here, though, since the console lock is entered.
-       * A copy of the thread list probably needs to be made. */
-      ConioConsoleCtrlEvent(CTRL_CLOSE_EVENT, current);
+        /* FIXME: Windows will wait up to 5 seconds for the thread to exit.
+         * We shouldn't wait here, though, since the console lock is entered.
+         * A copy of the thread list probably needs to be made. */
+        ConioConsoleCtrlEvent(CTRL_CLOSE_EVENT, current);
     }
 
-  LeaveCriticalSection(&Console->Header.Lock);
+    LeaveCriticalSection(&Console->Lock);
 }
 
-static VOID FASTCALL
+static VOID
 GuiConsoleHandleNcDestroy(HWND hWnd)
 {
-  PCSRSS_CONSOLE Console;
-  PGUI_CONSOLE_DATA GuiData;
+    PCSRSS_CONSOLE Console;
+    PGUI_CONSOLE_DATA GuiData;
 
 
-  GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
-  KillTimer(hWnd, 1);
-  Console->PrivateData = NULL;
-  DeleteCriticalSection(&GuiData->Lock);
-  GetSystemMenu(hWnd, TRUE);
-  if (GuiData->ConsoleLibrary)
-    FreeLibrary(GuiData->ConsoleLibrary);
+    GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
+    KillTimer(hWnd, 1);
+    Console->PrivateData = NULL;
+    DeleteCriticalSection(&GuiData->Lock);
+    GetSystemMenu(hWnd, TRUE);
+    if (GuiData->ConsoleLibrary)
+        FreeLibrary(GuiData->ConsoleLibrary);
 
-  HeapFree(Win32CsrApiHeap, 0, GuiData);
+    HeapFree(Win32CsrApiHeap, 0, GuiData);
 }
 
-static VOID FASTCALL
-GuiConsoleLeftMouseDown(HWND hWnd, LPARAM lParam)
+static COORD
+PointToCoord(PCSRSS_CONSOLE Console, LPARAM lParam)
 {
-  PCSRSS_CONSOLE Console;
-  PGUI_CONSOLE_DATA GuiData;
-  POINTS pt;
-  RECT rc;
-
-  GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
-  if (Console == NULL || GuiData == NULL) return;
+    PCSRSS_SCREEN_BUFFER Buffer = Console->ActiveBuffer;
+    PGUI_CONSOLE_DATA GuiData = Console->PrivateData;
+    COORD Coord;
+    Coord.X = Buffer->ShowX + ((short)LOWORD(lParam) / (int)GuiData->CharWidth);
+    Coord.Y = Buffer->ShowY + ((short)HIWORD(lParam) / (int)GuiData->CharHeight);
+
+    /* Clip coordinate to ensure it's inside buffer */
+    if (Coord.X < 0)                  Coord.X = 0;
+    else if (Coord.X >= Buffer->MaxX) Coord.X = Buffer->MaxX - 1;
+    if (Coord.Y < 0)                  Coord.Y = 0;
+    else if (Coord.Y >= Buffer->MaxY) Coord.Y = Buffer->MaxY - 1;
+    return Coord;
+}
 
-  pt = MAKEPOINTS(lParam);
+static VOID
+GuiConsoleLeftMouseDown(HWND hWnd, LPARAM lParam)
+{
+    PCSRSS_CONSOLE Console;
+    PGUI_CONSOLE_DATA GuiData;
 
-  rc.left = pt.x / GuiData->CharWidth;
-  rc.top = pt.y / GuiData->CharHeight;
-  rc.right = rc.left + 1;
-  rc.bottom = rc.top + 1;
+    GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
+    if (Console == NULL || GuiData == NULL) return;
 
-  GuiData->SelectionStart.x = rc.left;
-  GuiData->SelectionStart.y = rc.top;
+    Console->Selection.dwSelectionAnchor = PointToCoord(Console, lParam);
 
-  SetCapture(hWnd);
+    SetCapture(hWnd);
 
-  GuiData->MouseDown = TRUE;
+    Console->Selection.dwFlags |= CONSOLE_SELECTION_IN_PROGRESS | CONSOLE_MOUSE_SELECTION | CONSOLE_MOUSE_DOWN;
 
-  GuiConsoleUpdateSelection(hWnd, &rc, GuiData);
+    GuiConsoleUpdateSelection(Console, &Console->Selection.dwSelectionAnchor);
 }
 
-static VOID FASTCALL
+static VOID
 GuiConsoleLeftMouseUp(HWND hWnd, LPARAM lParam)
 {
-  PCSRSS_CONSOLE Console;
-  PGUI_CONSOLE_DATA GuiData;
-  RECT rc;
-  POINTS pt;
-
-  GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
-  if (Console == NULL || GuiData == NULL) return;
-  if (GuiData->Selection.left == -1 || !GuiData->MouseDown) return;
-
-  pt = MAKEPOINTS(lParam);
-
-  rc.left = GuiData->SelectionStart.x;
-  rc.top = GuiData->SelectionStart.y;
-  rc.right = (pt.x >= 0 ? (pt.x / GuiData->CharWidth) + 1 : 0);
-  rc.bottom = (pt.y >= 0 ? (pt.y / GuiData->CharHeight) + 1 : 0);
-
-  /* exchange left/top with right/bottom if required */
-  if(rc.left >= rc.right)
-  {
-    LONG tmp;
-    tmp = rc.left;
-    rc.left = max(rc.right - 1, 0);
-    rc.right = tmp + 1;
-  }
-  if(rc.top >= rc.bottom)
-  {
-    LONG tmp;
-    tmp = rc.top;
-    rc.top = max(rc.bottom - 1, 0);
-    rc.bottom = tmp + 1;
-  }
-
-  GuiData->MouseDown = FALSE;
-
-  GuiConsoleUpdateSelection(hWnd, &rc, GuiData);
-
-  ReleaseCapture();
+    PCSRSS_CONSOLE Console;
+    PGUI_CONSOLE_DATA GuiData;
+    COORD c;
+
+    GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
+    if (Console == NULL || GuiData == NULL) return;
+    if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) return;
+
+    c = PointToCoord(Console, lParam);
+
+    Console->Selection.dwFlags &= ~CONSOLE_MOUSE_DOWN;
+
+    GuiConsoleUpdateSelection(Console, &c);
+
+    ReleaseCapture();
 }
 
-static VOID FASTCALL
+static VOID
 GuiConsoleMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam)
 {
-  PCSRSS_CONSOLE Console;
-  PGUI_CONSOLE_DATA GuiData;
-  RECT rc;
-  POINTS pt;
-
-  if (!(wParam & MK_LBUTTON)) return;
-
-  GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
-  if (Console == NULL || GuiData == NULL || !GuiData->MouseDown) return;
-
-  pt = MAKEPOINTS(lParam);
-
-  rc.left = GuiData->SelectionStart.x;
-  rc.top = GuiData->SelectionStart.y;
-  rc.right = (pt.x >= 0 ? (pt.x / GuiData->CharWidth) + 1 : 0);
-  if (Console->Size.X < rc.right)
-  {
-    rc.right = Console->Size.X;
-  }
-  rc.bottom = (pt.y >= 0 ? (pt.y / GuiData->CharHeight) + 1 : 0);
-  if (Console->Size.Y < rc.bottom)
-  {
-    rc.bottom = Console->Size.Y;
-  }
-
-  /* exchange left/top with right/bottom if required */
-  if(rc.left >= rc.right)
-  {
-    LONG tmp;
-    tmp = rc.left;
-    rc.left = max(rc.right - 1, 0);
-    rc.right = tmp + 1;
-  }
-  if(rc.top >= rc.bottom)
-  {
-    LONG tmp;
-    tmp = rc.top;
-    rc.top = max(rc.bottom - 1, 0);
-    rc.bottom = tmp + 1;
-  }
-
-  GuiConsoleUpdateSelection(hWnd, &rc, GuiData);
+    PCSRSS_CONSOLE Console;
+    PGUI_CONSOLE_DATA GuiData;
+    COORD c;
+
+    if (!(wParam & MK_LBUTTON)) return;
+
+    GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
+    if (Console == NULL || GuiData == NULL) return;
+    if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) return;
+
+    c = PointToCoord(Console, lParam); /* TODO: Scroll buffer to bring c into view */
+
+    GuiConsoleUpdateSelection(Console, &c);
 }
 
-static VOID FASTCALL
+static VOID
 GuiConsoleRightMouseDown(HWND hWnd)
 {
-  PCSRSS_CONSOLE Console;
-  PGUI_CONSOLE_DATA GuiData;
+    PCSRSS_CONSOLE Console;
+    PGUI_CONSOLE_DATA GuiData;
 
-  GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
-  if (Console == NULL || GuiData == NULL) return;
+    GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
+    if (Console == NULL || GuiData == NULL) return;
 
-  if (GuiData->Selection.left == -1)
-  {
-    /* FIXME - paste text from clipboard */
-  }
-  else
-  {
-    /* FIXME - copy selection to clipboard */
+    if (!(Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY))
+    {
+        /* FIXME - paste text from clipboard */
+    }
+    else
+    {
+        /* FIXME - copy selection to clipboard */
 
-    GuiConsoleUpdateSelection(hWnd, NULL, GuiData);
-  }
+        GuiConsoleUpdateSelection(Console, NULL);
+    }
 
 }
 
@@ -1413,517 +1400,606 @@ GuiConsoleRightMouseDown(HWND hWnd)
 static VOID
 GuiConsoleShowConsoleProperties(HWND hWnd, BOOL Defaults, PGUI_CONSOLE_DATA GuiData)
 {
-  PCSRSS_CONSOLE Console;
-  APPLET_PROC CPLFunc;
-  TCHAR szBuffer[MAX_PATH];
-  ConsoleInfo SharedInfo;
+    PCSRSS_CONSOLE Console;
+    APPLET_PROC CPLFunc;
+    TCHAR szBuffer[MAX_PATH];
+    ConsoleInfo SharedInfo;
 
-  DPRINT("GuiConsoleShowConsoleProperties entered\n");
+    DPRINT("GuiConsoleShowConsoleProperties entered\n");
 
-  GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
+    GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
 
-  if (GuiData == NULL)
+    if (GuiData == NULL)
     {
-      DPRINT("GuiConsoleGetDataPointers failed\n");
-      return;
+        DPRINT("GuiConsoleGetDataPointers failed\n");
+        return;
     }
 
-  if (GuiData->ConsoleLibrary == NULL)
+    if (GuiData->ConsoleLibrary == NULL)
     {
-      GetWindowsDirectory(szBuffer,MAX_PATH);
-      _tcscat(szBuffer, _T("\\system32\\console.dll"));
-      GuiData->ConsoleLibrary = LoadLibrary(szBuffer);
+        GetWindowsDirectory(szBuffer,MAX_PATH);
+        _tcscat(szBuffer, _T("\\system32\\console.dll"));
+        GuiData->ConsoleLibrary = LoadLibrary(szBuffer);
 
-      if (GuiData->ConsoleLibrary == NULL)
+        if (GuiData->ConsoleLibrary == NULL)
         {
-          DPRINT1("failed to load console.dll");
-          return;
+            DPRINT1("failed to load console.dll");
+            return;
         }
     }
 
-  CPLFunc = (APPLET_PROC) GetProcAddress(GuiData->ConsoleLibrary, _T("CPlApplet"));
-  if (!CPLFunc)
+    CPLFunc = (APPLET_PROC) GetProcAddress(GuiData->ConsoleLibrary, _T("CPlApplet"));
+    if (!CPLFunc)
     {
-      DPRINT("Error: Console.dll misses CPlApplet export\n");
-      return;
+        DPRINT("Error: Console.dll misses CPlApplet export\n");
+        return;
     }
 
-  /* setup struct */
-  SharedInfo.InsertMode = GuiData->InsertMode;
-  SharedInfo.HistoryBufferSize = GuiData->HistoryBufferSize;
-  SharedInfo.NumberOfHistoryBuffers = GuiData->NumberOfHistoryBuffers;
-  SharedInfo.ScreenText = GuiData->ScreenText;
-  SharedInfo.ScreenBackground = GuiData->ScreenBackground;
-  SharedInfo.PopupText = GuiData->PopupText;
-  SharedInfo.PopupBackground = GuiData->PopupBackground;
-  SharedInfo.WindowSize = (DWORD)MAKELONG(Console->Size.X, Console->Size.Y);
-  SharedInfo.WindowPosition = GuiData->WindowPosition;
-  SharedInfo.ScreenBuffer = (DWORD)MAKELONG(Console->ActiveBuffer->MaxX, Console->ActiveBuffer->MaxY);
-  SharedInfo.UseRasterFonts = GuiData->UseRasterFonts;
-  SharedInfo.FontSize = (DWORD)GuiData->FontSize;
-  SharedInfo.FontWeight = GuiData->FontWeight;
-  SharedInfo.CursorSize = Console->ActiveBuffer->CursorInfo.dwSize;
-  SharedInfo.HistoryNoDup = GuiData->HistoryNoDup;
-  SharedInfo.FullScreen = GuiData->FullScreen;
-  SharedInfo.QuickEdit = GuiData->QuickEdit;
-  memcpy(&SharedInfo.Colors[0], GuiData->Colors, sizeof(s_Colors));
-
-  if (!CPLFunc(hWnd, CPL_INIT, 0, 0))
-    {
-      DPRINT("Error: failed to initialize console.dll\n");
-      return;
+    /* setup struct */
+    SharedInfo.InsertMode = GuiData->InsertMode;
+    SharedInfo.HistoryBufferSize = GuiData->HistoryBufferSize;
+    SharedInfo.NumberOfHistoryBuffers = GuiData->NumberOfHistoryBuffers;
+    SharedInfo.ScreenText = GuiData->ScreenText;
+    SharedInfo.ScreenBackground = GuiData->ScreenBackground;
+    SharedInfo.PopupText = GuiData->PopupText;
+    SharedInfo.PopupBackground = GuiData->PopupBackground;
+    SharedInfo.WindowSize = (DWORD)MAKELONG(Console->Size.X, Console->Size.Y);
+    SharedInfo.WindowPosition = GuiData->WindowPosition;
+    SharedInfo.ScreenBuffer = (DWORD)MAKELONG(Console->ActiveBuffer->MaxX, Console->ActiveBuffer->MaxY);
+    SharedInfo.UseRasterFonts = GuiData->UseRasterFonts;
+    SharedInfo.FontSize = (DWORD)GuiData->FontSize;
+    SharedInfo.FontWeight = GuiData->FontWeight;
+    SharedInfo.CursorSize = Console->ActiveBuffer->CursorInfo.dwSize;
+    SharedInfo.HistoryNoDup = GuiData->HistoryNoDup;
+    SharedInfo.FullScreen = GuiData->FullScreen;
+    SharedInfo.QuickEdit = GuiData->QuickEdit;
+    memcpy(&SharedInfo.Colors[0], GuiData->Colors, sizeof(s_Colors));
+
+    if (!CPLFunc(hWnd, CPL_INIT, 0, 0))
+    {
+        DPRINT("Error: failed to initialize console.dll\n");
+        return;
     }
 
-  if (CPLFunc(hWnd, CPL_GETCOUNT, 0, 0) != 1)
+    if (CPLFunc(hWnd, CPL_GETCOUNT, 0, 0) != 1)
     {
-      DPRINT("Error: console.dll returned unexpected CPL count\n");
-      return;
+        DPRINT("Error: console.dll returned unexpected CPL count\n");
+        return;
     }
 
-  CPLFunc(hWnd, CPL_DBLCLK, (LPARAM)&SharedInfo, Defaults);
+    CPLFunc(hWnd, CPL_DBLCLK, (LPARAM)&SharedInfo, Defaults);
 }
-static LRESULT FASTCALL
+static LRESULT
 GuiConsoleHandleSysMenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam, PGUI_CONSOLE_DATA GuiData)
 {
     LRESULT Ret = TRUE;
 
     switch(wParam)
     {
-        case ID_SYSTEM_EDIT_MARK:
-        case ID_SYSTEM_EDIT_COPY:
-        case ID_SYSTEM_EDIT_PASTE:
-        case ID_SYSTEM_EDIT_SELECTALL:
-        case ID_SYSTEM_EDIT_SCROLL:
-        case ID_SYSTEM_EDIT_FIND:
-            break;
+    case ID_SYSTEM_EDIT_MARK:
+    case ID_SYSTEM_EDIT_COPY:
+    case ID_SYSTEM_EDIT_PASTE:
+    case ID_SYSTEM_EDIT_SELECTALL:
+    case ID_SYSTEM_EDIT_SCROLL:
+    case ID_SYSTEM_EDIT_FIND:
+        break;
 
-        case ID_SYSTEM_DEFAULTS:
-            GuiConsoleShowConsoleProperties(hWnd, TRUE, GuiData);
-            break;
+    case ID_SYSTEM_DEFAULTS:
+        GuiConsoleShowConsoleProperties(hWnd, TRUE, GuiData);
+        break;
 
-        case ID_SYSTEM_PROPERTIES:
-            GuiConsoleShowConsoleProperties(hWnd, FALSE, GuiData);
-            break;
+    case ID_SYSTEM_PROPERTIES:
+        GuiConsoleShowConsoleProperties(hWnd, FALSE, GuiData);
+        break;
 
-        default:
-            Ret = DefWindowProcW(hWnd, WM_SYSCOMMAND, wParam, lParam);
-            break;
+    default:
+        Ret = DefWindowProcW(hWnd, WM_SYSCOMMAND, wParam, lParam);
+        break;
     }
     return Ret;
 }
 
-static VOID FASTCALL
+static VOID
+GuiConsoleGetMinMaxInfo(HWND hWnd, PMINMAXINFO minMaxInfo)
+{
+    PCSRSS_CONSOLE Console;
+    PGUI_CONSOLE_DATA GuiData;
+    GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
+    if((Console == NULL)|| (GuiData == NULL)) return;
+
+    DWORD windx = CONGUI_MIN_WIDTH * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE));
+    DWORD windy = CONGUI_MIN_HEIGHT * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION);
+
+    minMaxInfo->ptMinTrackSize.x = windx;
+    minMaxInfo->ptMinTrackSize.y = windy;
+
+    windx = (Console->ActiveBuffer->MaxX) * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE));
+    windy = (Console->ActiveBuffer->MaxY) * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION);
+
+    if(Console->Size.X < Console->ActiveBuffer->MaxX) windy += GetSystemMetrics(SM_CYHSCROLL);    // window currently has a horizontal scrollbar
+    if(Console->Size.Y < Console->ActiveBuffer->MaxY) windx += GetSystemMetrics(SM_CXVSCROLL);    // window currently has a vertical scrollbar
+
+    minMaxInfo->ptMaxTrackSize.x = windx;
+    minMaxInfo->ptMaxTrackSize.y = windy;
+}
+static VOID
 GuiConsoleResize(HWND hWnd, WPARAM wParam, LPARAM lParam)
 {
-  PCSRSS_CONSOLE Console;
-  PGUI_CONSOLE_DATA GuiData;
-
-  GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
-  if (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED)
-  {
-      DPRINT1("GuiConsoleResize X %d Y %d\n", LOWORD(lParam), HIWORD(lParam));
-  }
+    PCSRSS_CONSOLE Console;
+    PGUI_CONSOLE_DATA GuiData;
+    GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
+    if((Console == NULL) || (GuiData == NULL)) return;
+
+    if ((GuiData->WindowSizeLock == FALSE) && (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED))
+    {
+        PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer;
+
+        GuiData->WindowSizeLock = TRUE;
+
+        DWORD windx = LOWORD(lParam);
+        DWORD windy = HIWORD(lParam);
+
+        // Compensate for existing scroll bars (because lParam values do not accommodate scroll bar)
+        if(Console->Size.X < Buff->MaxX) windy += GetSystemMetrics(SM_CYHSCROLL);    // window currently has a horizontal scrollbar
+        if(Console->Size.Y < Buff->MaxY) windx += GetSystemMetrics(SM_CXVSCROLL);    // window currently has a vertical scrollbar
+
+        DWORD charx = windx / GuiData->CharWidth;
+        DWORD chary = windy / GuiData->CharHeight;
+
+        // Character alignment (round size up or down)
+        if((windx % GuiData->CharWidth) >= (GuiData->CharWidth / 2)) ++charx;
+        if((windy % GuiData->CharHeight) >= (GuiData->CharHeight / 2)) ++chary;
+
+        // Compensate for added scroll bars in new window
+        if(charx < Buff->MaxX)windy -= GetSystemMetrics(SM_CYHSCROLL);    // new window will have a horizontal scroll bar
+        if(chary < Buff->MaxY)windx -= GetSystemMetrics(SM_CXVSCROLL);    // new window will have a vertical scroll bar
+
+        charx = windx / GuiData->CharWidth;
+        chary = windy / GuiData->CharHeight;
+
+        // Character alignment (round size up or down)
+        if((windx % GuiData->CharWidth) >= (GuiData->CharWidth / 2)) ++charx;
+        if((windy % GuiData->CharHeight) >= (GuiData->CharHeight / 2)) ++chary;
+
+        // Resize window
+        if((charx != Console->Size.X) || (chary != Console->Size.Y))
+        {
+            Console->Size.X = (charx <= Buff->MaxX) ? charx : Buff->MaxX;
+            Console->Size.Y = (chary <= Buff->MaxY) ? chary : Buff->MaxY;
+        }
+
+        GuiConsoleInitScrollbar(Console, hWnd);
+
+        // Adjust the start of the visible area if we are attempting to show nonexistent areas
+        if((Buff->MaxX - Buff->ShowX) < Console->Size.X) Buff->ShowX = Buff->MaxX - Console->Size.X;
+        if((Buff->MaxY - Buff->ShowY) < Console->Size.Y) Buff->ShowY = Buff->MaxY - Console->Size.Y;
+        InvalidateRect(hWnd, NULL, TRUE);
+
+        GuiData->WindowSizeLock = FALSE;
+    }
 }
+
 VOID
 FASTCALL
 GuiConsoleHandleScrollbarMenu()
 {
-  HMENU hMenu;
+    HMENU hMenu;
 
-  hMenu = CreatePopupMenu();
-  if (hMenu == NULL)
+    hMenu = CreatePopupMenu();
+    if (hMenu == NULL)
     {
-      DPRINT("CreatePopupMenu failed\n");
-      return;
+        DPRINT("CreatePopupMenu failed\n");
+        return;
     }
-  //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLHERE);
-  //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1);
-  //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLTOP);
-  //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLBOTTOM);
-  //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1);
-  //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_UP);
-  //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_DOWN);
-  //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1);
-  //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLUP);
-  //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLDOWN);
+    //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLHERE);
+    //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1);
+    //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLTOP);
+    //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLBOTTOM);
+    //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1);
+    //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_UP);
+    //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_DOWN);
+    //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1);
+    //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLUP);
+    //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLDOWN);
 
 }
 
-static VOID FASTCALL
-GuiApplyUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PConsoleInfo pConInfo)
+static NTSTATUS WINAPI
+GuiResizeBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer, COORD Size)
 {
-  DWORD windx, windy;
-  PCSRSS_SCREEN_BUFFER ActiveBuffer = Console->ActiveBuffer;
-  BOOL SizeChanged = FALSE;
-
-  EnterCriticalSection(&ActiveBuffer->Header.Lock);
-
-  /* apply text / background color */
-  GuiData->ScreenText = pConInfo->ScreenText;
-  GuiData->ScreenBackground = pConInfo->ScreenBackground;
-
-  /* apply cursor size */
-  ActiveBuffer->CursorInfo.dwSize = min(max(pConInfo->CursorSize, 1), 100);
-
-  windx = LOWORD(pConInfo->ScreenBuffer);
-  windy = HIWORD(pConInfo->ScreenBuffer);
+    BYTE * Buffer;
+    DWORD Offset = 0;
+    BYTE * OldPtr;
+    USHORT CurrentY;
+    BYTE * OldBuffer;
+#if HAVE_WMEMSET
+    USHORT value = MAKEWORD(' ', ScreenBuffer->DefaultAttrib);
+#endif
+    DWORD diff;
+    DWORD i;
 
-  if (windx != ActiveBuffer->MaxX || windy != ActiveBuffer->MaxY)
-  {
-     BYTE * Buffer = HeapAlloc(Win32CsrApiHeap, 0, windx * windy * 2);
+    /* Buffer size is not allowed to be smaller than window size */
+    if (Size.X < Console->Size.X || Size.Y < Console->Size.Y)
+        return STATUS_INVALID_PARAMETER;
 
-     if (Buffer)
-     {
-        DWORD Offset = 0;
-        BYTE * OldPtr;
-        USHORT CurrentY;
-        BYTE * OldBuffer;
-        USHORT value;
-        DWORD diff;
-        DWORD i;
+    if (Size.X == ScreenBuffer->MaxX && Size.Y == ScreenBuffer->MaxY)
+        return STATUS_SUCCESS;
 
-        value = MAKEWORD(' ', ActiveBuffer->DefaultAttrib);
+    Buffer = HeapAlloc(Win32CsrApiHeap, 0, Size.X * Size.Y * 2);
+    if (!Buffer)
+        return STATUS_NO_MEMORY;
 
-        DPRINT("MaxX %d MaxY %d windx %d windy %d value %04x DefaultAttrib %d\n",ActiveBuffer->MaxX, ActiveBuffer->MaxY, windx, windy, value, ActiveBuffer->DefaultAttrib);
-        OldBuffer = ActiveBuffer->Buffer;
+    DPRINT1("Resizing (%d,%d) to (%d,%d)\n", ScreenBuffer->MaxX, ScreenBuffer->MaxY, Size.X, Size.Y);
+    OldBuffer = ScreenBuffer->Buffer;
 
-        for (CurrentY = 0; CurrentY < min(ActiveBuffer->MaxY, windy); CurrentY++)
+    for (CurrentY = 0; CurrentY < ScreenBuffer->MaxY && CurrentY < Size.Y; CurrentY++)
+    {
+        OldPtr = ConioCoordToPointer(ScreenBuffer, 0, CurrentY);
+        if (Size.X <= ScreenBuffer->MaxX)
         {
-            OldPtr = ConioCoordToPointer(ActiveBuffer, 0, CurrentY);
-            if (windx <= ActiveBuffer->MaxX)
-            {
-                /* reduce size */
-                RtlCopyMemory(&Buffer[Offset], OldPtr, windx * 2);
-                Offset += (windx * 2);
-            }
-            else
-            {
-                /* enlarge size */
-                RtlCopyMemory(&Buffer[Offset], OldPtr, ActiveBuffer->MaxX * 2);
-                Offset += (ActiveBuffer->MaxX * 2);
+            /* reduce size */
+            RtlCopyMemory(&Buffer[Offset], OldPtr, Size.X * 2);
+            Offset += (Size.X * 2);
+        }
+        else
+        {
+            /* enlarge size */
+            RtlCopyMemory(&Buffer[Offset], OldPtr, ScreenBuffer->MaxX * 2);
+            Offset += (ScreenBuffer->MaxX * 2);
 
-                diff = windx - ActiveBuffer->MaxX;
-                /* zero new part of it */
+            diff = Size.X - ScreenBuffer->MaxX;
+            /* zero new part of it */
 #if HAVE_WMEMSET
-                wmemset((WCHAR*)&Buffer[Offset], value, diff);
+            wmemset((WCHAR*)&Buffer[Offset], value, diff);
 #else
-                for (i = 0; i < diff; i++)
-                {
-                    Buffer[Offset++] = ' ';
-                    Buffer[Offset++] = ActiveBuffer->DefaultAttrib;
-                }
-#endif
+            for (i = 0; i < diff; i++)
+            {
+                Buffer[Offset++] = ' ';
+                Buffer[Offset++] = ScreenBuffer->DefaultAttrib;
             }
+#endif
         }
+    }
 
-        if (windy > ActiveBuffer->MaxY)
-        {
-            diff = windy - ActiveBuffer->MaxY;
+    if (Size.Y > ScreenBuffer->MaxY)
+    {
+        diff = Size.X * (Size.Y - ScreenBuffer->MaxY);
 #if HAVE_WMEMSET
-                wmemset((WCHAR*)&Buffer[Offset], value, diff * windx);
+        wmemset((WCHAR*)&Buffer[Offset], value, diff);
 #else
-                for (i = 0; i < diff * windx; i++)
-                {
-                    Buffer[Offset++] = ' ';
-                    Buffer[Offset++] = ActiveBuffer->DefaultAttrib;
-                }
-#endif
+        for (i = 0; i < diff; i++)
+        {
+            Buffer[Offset++] = ' ';
+            Buffer[Offset++] = ScreenBuffer->DefaultAttrib;
         }
+#endif
+    }
+
+    (void)InterlockedExchangePointer((PVOID volatile  *)&ScreenBuffer->Buffer, Buffer);
+    HeapFree(Win32CsrApiHeap, 0, OldBuffer);
+    ScreenBuffer->MaxX = Size.X;
+    ScreenBuffer->MaxY = Size.Y;
+    ScreenBuffer->VirtualY = 0;
+
+    /* Ensure cursor and window are within buffer */
+    if (ScreenBuffer->CurrentX >= Size.X)
+        ScreenBuffer->CurrentX = Size.X - 1;
+    if (ScreenBuffer->CurrentY >= Size.Y)
+        ScreenBuffer->CurrentY = Size.Y - 1;
+    if (ScreenBuffer->ShowX > Size.X - Console->Size.X)
+        ScreenBuffer->ShowX = Size.X - Console->Size.X;
+    if (ScreenBuffer->ShowY > Size.Y - Console->Size.Y)
+        ScreenBuffer->ShowY = Size.Y - Console->Size.Y;
+
+    /* TODO: Should update scrollbar, but can't use anything that
+     * calls SendMessage or it could cause deadlock */
+
+    return STATUS_SUCCESS;
+}
+
+static VOID
+GuiApplyUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PConsoleInfo pConInfo)
+{
+    DWORD windx, windy;
+    PCSRSS_SCREEN_BUFFER ActiveBuffer = Console->ActiveBuffer;
+    COORD BufSize;
+    BOOL SizeChanged = FALSE;
+
+    EnterCriticalSection(&Console->Lock);
+
+    /* apply text / background color */
+    GuiData->ScreenText = pConInfo->ScreenText;
+    GuiData->ScreenBackground = pConInfo->ScreenBackground;
+
+    /* apply cursor size */
+    ActiveBuffer->CursorInfo.dwSize = min(max(pConInfo->CursorSize, 1), 100);
+
+    windx = LOWORD(pConInfo->WindowSize);
+    windy = HIWORD(pConInfo->WindowSize);
 
-        (void)InterlockedExchangePointer((PVOID volatile  *)&ActiveBuffer->Buffer, Buffer);
-        HeapFree(Win32CsrApiHeap, 0, OldBuffer);
-        ActiveBuffer->MaxX = windx;
-        ActiveBuffer->MaxY = windy;
-        ActiveBuffer->VirtualY = 0;
+    if (windx != Console->Size.X || windy != Console->Size.Y)
+    {
+        /* resize window */
+        Console->Size.X = windx;
+        Console->Size.Y = windy;
         SizeChanged = TRUE;
-     }
-     else
-     {
-        LeaveCriticalSection(&ActiveBuffer->Header.Lock);
-        return;
-     }
-  }
-
-  windx = LOWORD(pConInfo->WindowSize);
-  windy = HIWORD(pConInfo->WindowSize);
-
-  if (windx > Console->Size.X)
-  {
-      PWCHAR LineBuffer = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, windx * sizeof(WCHAR));
-      if (LineBuffer)
-      {
-          HeapFree(Win32CsrApiHeap, 0, GuiData->LineBuffer);
-          GuiData->LineBuffer = LineBuffer;
-      }
-      else
-      {
-          LeaveCriticalSection(&ActiveBuffer->Header.Lock);
-          return;
-      }
-  }
-
-
-  if (windx != Console->Size.X || windy != Console->Size.Y)
-  {
-      /* resize window */
-      Console->Size.X = windx;
-      Console->Size.Y = windy;
-      SizeChanged = TRUE;
-  }
-
-  if (SizeChanged)
-  {
-      GuiConsoleInitScrollbar(Console, pConInfo->hConsoleWindow);
-  }
-
-  LeaveCriticalSection(&ActiveBuffer->Header.Lock);
-  InvalidateRect(pConInfo->hConsoleWindow, NULL, TRUE);
+    }
+
+    BufSize.X = LOWORD(pConInfo->ScreenBuffer);
+    BufSize.Y = HIWORD(pConInfo->ScreenBuffer);
+    if (BufSize.X != ActiveBuffer->MaxX || BufSize.Y != ActiveBuffer->MaxY)
+    {
+        if (NT_SUCCESS(GuiResizeBuffer(Console, ActiveBuffer, BufSize)))
+            SizeChanged = TRUE;
+    }
+
+    if (SizeChanged)
+    {
+        GuiData->WindowSizeLock = TRUE;
+        GuiConsoleInitScrollbar(Console, pConInfo->hConsoleWindow);
+        GuiData->WindowSizeLock = FALSE;
+    }
+
+    LeaveCriticalSection(&Console->Lock);
+    InvalidateRect(pConInfo->hConsoleWindow, NULL, TRUE);
 }
 
 static
 LRESULT
 GuiConsoleHandleScroll(HWND hwnd, UINT uMsg, WPARAM wParam)
 {
-  PCSRSS_CONSOLE Console;
-  PCSRSS_SCREEN_BUFFER Buff;
-  PGUI_CONSOLE_DATA GuiData;
-  SCROLLINFO sInfo;
-  int fnBar;
-  int old_pos, Maximum;
-  PUSHORT pShowXY;
-
-  GuiConsoleGetDataPointers(hwnd, &Console, &GuiData);
-  if (Console == NULL || GuiData == NULL)
-      return FALSE;
-  Buff = Console->ActiveBuffer;
-
-  if (uMsg == WM_HSCROLL)
-  {
-    fnBar = SB_HORZ;
-    Maximum = Buff->MaxX - Console->Size.X;
-    pShowXY = &Buff->ShowX;
-  }
-  else
-  {
-    fnBar = SB_VERT;
-    Maximum = Buff->MaxY - Console->Size.Y;
-    pShowXY = &Buff->ShowY;
-  }
-
-  /* set scrollbar sizes */
-  sInfo.cbSize = sizeof(SCROLLINFO);
-  sInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE | SIF_TRACKPOS;
-
-  if (!GetScrollInfo(hwnd, fnBar, &sInfo))
-  {
-    return FALSE;
-  }
-
-  old_pos = sInfo.nPos;
-
-  switch(LOWORD(wParam))
-  {
-  case SB_LINELEFT:
-      sInfo.nPos -= 1;
-      break;
-
-  case SB_LINERIGHT:
-      sInfo.nPos += 1;
-      break;
-
-  case SB_PAGELEFT:
-      sInfo.nPos -= sInfo.nPage;
-      break;
-
-  case SB_PAGERIGHT:
-      sInfo.nPos += sInfo.nPage;
-      break;
-
-  case SB_THUMBTRACK:
-      sInfo.nPos = sInfo.nTrackPos;
-      break;
-
-  case SB_TOP:
-      sInfo.nPos = sInfo.nMin;
-      break;
-
-  case SB_BOTTOM:
-      sInfo.nPos = sInfo.nMax;
-      break;
-
-  default:
-     break;
-  }
-
-  sInfo.nPos = max(sInfo.nPos, 0);
-  sInfo.nPos = min(sInfo.nPos, Maximum);
-
-  if (old_pos != sInfo.nPos)
-  {
-      USHORT OldX = Buff->ShowX;
-      USHORT OldY = Buff->ShowY;
-      *pShowXY = sInfo.nPos;
-
-      ScrollWindowEx(hwnd,
-                     (OldX - Buff->ShowX) * GuiData->CharWidth,
-                     (OldY - Buff->ShowY) * GuiData->CharHeight,
-                     NULL,
-                     NULL,
-                     NULL,
-                     NULL,
-                     SW_INVALIDATE);
-
-      sInfo.fMask = SIF_POS;
-      SetScrollInfo(hwnd, fnBar, &sInfo, TRUE);
-
-      UpdateWindow(hwnd);
-  }
-  return 0;
+    PCSRSS_CONSOLE Console;
+    PCSRSS_SCREEN_BUFFER Buff;
+    PGUI_CONSOLE_DATA GuiData;
+    SCROLLINFO sInfo;
+    int fnBar;
+    int old_pos, Maximum;
+    PUSHORT pShowXY;
+
+    GuiConsoleGetDataPointers(hwnd, &Console, &GuiData);
+    if (Console == NULL || GuiData == NULL)
+        return FALSE;
+    Buff = Console->ActiveBuffer;
+
+    if (uMsg == WM_HSCROLL)
+    {
+        fnBar = SB_HORZ;
+        Maximum = Buff->MaxX - Console->Size.X;
+        pShowXY = &Buff->ShowX;
+    }
+    else
+    {
+        fnBar = SB_VERT;
+        Maximum = Buff->MaxY - Console->Size.Y;
+        pShowXY = &Buff->ShowY;
+    }
+
+    /* set scrollbar sizes */
+    sInfo.cbSize = sizeof(SCROLLINFO);
+    sInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE | SIF_TRACKPOS;
+
+    if (!GetScrollInfo(hwnd, fnBar, &sInfo))
+    {
+        return FALSE;
+    }
+
+    old_pos = sInfo.nPos;
+
+    switch(LOWORD(wParam))
+    {
+    case SB_LINELEFT:
+        sInfo.nPos -= 1;
+        break;
+
+    case SB_LINERIGHT:
+        sInfo.nPos += 1;
+        break;
+
+    case SB_PAGELEFT:
+        sInfo.nPos -= sInfo.nPage;
+        break;
+
+    case SB_PAGERIGHT:
+        sInfo.nPos += sInfo.nPage;
+        break;
+
+    case SB_THUMBTRACK:
+        sInfo.nPos = sInfo.nTrackPos;
+        ConioPause(Console, PAUSED_FROM_SCROLLBAR);
+        break;
+
+    case SB_THUMBPOSITION:
+        ConioUnpause(Console, PAUSED_FROM_SCROLLBAR);
+        break;
+
+    case SB_TOP:
+        sInfo.nPos = sInfo.nMin;
+        break;
+
+    case SB_BOTTOM:
+        sInfo.nPos = sInfo.nMax;
+        break;
+
+    default:
+        break;
+    }
+
+    sInfo.nPos = max(sInfo.nPos, 0);
+    sInfo.nPos = min(sInfo.nPos, Maximum);
+
+    if (old_pos != sInfo.nPos)
+    {
+        USHORT OldX = Buff->ShowX;
+        USHORT OldY = Buff->ShowY;
+        *pShowXY = sInfo.nPos;
+
+        ScrollWindowEx(hwnd,
+                       (OldX - Buff->ShowX) * GuiData->CharWidth,
+                       (OldY - Buff->ShowY) * GuiData->CharHeight,
+                       NULL,
+                       NULL,
+                       NULL,
+                       NULL,
+                       SW_INVALIDATE);
+
+        sInfo.fMask = SIF_POS;
+        SetScrollInfo(hwnd, fnBar, &sInfo, TRUE);
+
+        UpdateWindow(hwnd);
+    }
+    return 0;
 }
 
 static LRESULT CALLBACK
 GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
-  LRESULT Result = 0;
-  PGUI_CONSOLE_DATA GuiData = NULL;
-  PCSRSS_CONSOLE Console = NULL;
+    LRESULT Result = 0;
+    PGUI_CONSOLE_DATA GuiData = NULL;
+    PCSRSS_CONSOLE Console = NULL;
 
-  GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
+    GuiConsoleGetDataPointers(hWnd, &Console, &GuiData);
 
-  switch(msg)
+    switch(msg)
     {
-      case WM_NCCREATE:
+    case WM_NCCREATE:
         Result = (LRESULT) GuiConsoleHandleNcCreate(hWnd, (CREATESTRUCTW *) lParam);
         break;
-      case WM_PAINT:
+    case WM_PAINT:
         GuiConsoleHandlePaint(hWnd, (HDC)wParam);
         break;
-      case WM_KEYDOWN:
-      case WM_KEYUP:
-      case WM_SYSKEYDOWN:
-      case WM_SYSKEYUP:
-      case WM_CHAR:
+    case WM_KEYDOWN:
+    case WM_KEYUP:
+    case WM_SYSKEYDOWN:
+    case WM_SYSKEYUP:
+    case WM_CHAR:
         GuiConsoleHandleKey(hWnd, msg, wParam, lParam);
         break;
-      case WM_TIMER:
+    case WM_TIMER:
         GuiConsoleHandleTimer(hWnd);
         break;
-      case WM_CLOSE:
+    case WM_CLOSE:
         GuiConsoleHandleClose(hWnd);
         break;
-      case WM_NCDESTROY:
+    case WM_NCDESTROY:
         GuiConsoleHandleNcDestroy(hWnd);
         break;
-      case WM_LBUTTONDOWN:
-          GuiConsoleLeftMouseDown(hWnd, lParam);
+    case WM_LBUTTONDOWN:
+        GuiConsoleLeftMouseDown(hWnd, lParam);
         break;
-      case WM_LBUTTONUP:
-          GuiConsoleLeftMouseUp(hWnd, lParam);
+    case WM_LBUTTONUP:
+        GuiConsoleLeftMouseUp(hWnd, lParam);
         break;
-      case WM_RBUTTONDOWN:
-          GuiConsoleRightMouseDown(hWnd);
+    case WM_RBUTTONDOWN:
+        GuiConsoleRightMouseDown(hWnd);
         break;
-      case WM_MOUSEMOVE:
-          GuiConsoleMouseMove(hWnd, wParam, lParam);
+    case WM_MOUSEMOVE:
+        GuiConsoleMouseMove(hWnd, wParam, lParam);
         break;
-      case WM_SYSCOMMAND:
-          Result = GuiConsoleHandleSysMenuCommand(hWnd, wParam, lParam, GuiData);
-          break;
-      case WM_HSCROLL:
-      case WM_VSCROLL:
-          Result = GuiConsoleHandleScroll(hWnd, msg, wParam);
-          break;
-      case WM_SIZE:
-          GuiConsoleResize(hWnd, wParam, lParam);
-          break;
-      case PM_APPLY_CONSOLE_INFO:
-          GuiApplyUserSettings(Console, GuiData, (PConsoleInfo)wParam);
-          if (lParam)
-            {
-              GuiConsoleWriteUserSettings(Console, GuiData);
-            }
-          break;
-      default:
+    case WM_SYSCOMMAND:
+        Result = GuiConsoleHandleSysMenuCommand(hWnd, wParam, lParam, GuiData);
+        break;
+    case WM_HSCROLL:
+    case WM_VSCROLL:
+        Result = GuiConsoleHandleScroll(hWnd, msg, wParam);
+        break;
+    case WM_GETMINMAXINFO:
+        GuiConsoleGetMinMaxInfo(hWnd, (PMINMAXINFO)lParam);
+        break;
+    case WM_SIZE:
+        GuiConsoleResize(hWnd, wParam, lParam);
+        break;
+    case PM_APPLY_CONSOLE_INFO:
+        GuiApplyUserSettings(Console, GuiData, (PConsoleInfo)wParam);
+        if (lParam)
+        {
+            GuiConsoleWriteUserSettings(Console, GuiData);
+        }
+        break;
+    default:
         Result = DefWindowProcW(hWnd, msg, wParam, lParam);
         break;
     }
 
-  return Result;
+    return Result;
 }
 
 static LRESULT CALLBACK
 GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
-  HWND NewWindow;
-  LONG WindowCount;
-  MSG Msg;
-  PWCHAR Buffer, Title;
-  PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) lParam;
+    HWND NewWindow;
+    LONG WindowCount;
+    MSG Msg;
+    PWCHAR Buffer, Title;
+    PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) lParam;
 
 
 
-  switch(msg)
+    switch(msg)
     {
-      case WM_CREATE:
+    case WM_CREATE:
         SetWindowLongW(hWnd, GWL_USERDATA, 0);
         return 0;
-      case PM_CREATE_CONSOLE:
+    case PM_CREATE_CONSOLE:
         Buffer = HeapAlloc(Win32CsrApiHeap, 0,
                            Console->Title.Length + sizeof(WCHAR));
         if (NULL != Buffer)
-          {
+        {
             memcpy(Buffer, Console->Title.Buffer, Console->Title.Length);
             Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0';
             Title = Buffer;
-          }
+        }
         else
-          {
+        {
             Title = L"";
-          }
-        NewWindow = CreateWindowW(L"ConsoleWindowClass",
-                                  Title,
-                                  WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_HSCROLL | WS_VSCROLL, //WS_OVERLAPPEDWINDOW
-                                  CW_USEDEFAULT,
-                                  CW_USEDEFAULT,
-                                  CW_USEDEFAULT,
-                                  CW_USEDEFAULT,
-                                  NULL,
-                                  NULL,
-                                  (HINSTANCE) GetModuleHandleW(NULL),
-                                  (PVOID) Console);
+        }
+        NewWindow = CreateWindowExW(WS_EX_CLIENTEDGE,
+                                    L"ConsoleWindowClass",
+                                    Title,
+                                    WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL,
+                                    CW_USEDEFAULT,
+                                    CW_USEDEFAULT,
+                                    CW_USEDEFAULT,
+                                    CW_USEDEFAULT,
+                                    NULL,
+                                    NULL,
+                                    (HINSTANCE) GetModuleHandleW(NULL),
+                                    (PVOID) Console);
         if (NULL != Buffer)
-          {
+        {
             HeapFree(Win32CsrApiHeap, 0, Buffer);
-          }
+        }
         if (NULL != NewWindow)
-          {
+        {
             SetWindowLongW(hWnd, GWL_USERDATA, GetWindowLongW(hWnd, GWL_USERDATA) + 1);
-            ShowWindow(NewWindow, SW_SHOW);
-          }
+            if (wParam)
+              {
+                ShowWindow(NewWindow, SW_SHOW);
+              }
+        }
         return (LRESULT) NewWindow;
-      case PM_DESTROY_CONSOLE:
+    case PM_DESTROY_CONSOLE:
         /* Window creation is done using a PostMessage(), so it's possible that the
          * window that we want to destroy doesn't exist yet. So first empty the message
          * queue */
         while(PeekMessageW(&Msg, NULL, 0, 0, PM_REMOVE))
-          {
+        {
             TranslateMessage(&Msg);
             DispatchMessageW(&Msg);
-          }
+        }
         DestroyWindow(Console->hWindow);
         Console->hWindow = NULL;
         WindowCount = GetWindowLongW(hWnd, GWL_USERDATA);
         WindowCount--;
         SetWindowLongW(hWnd, GWL_USERDATA, WindowCount);
         if (0 == WindowCount)
-          {
+        {
             NotifyWnd = NULL;
             DestroyWindow(hWnd);
             PrivateCsrssManualGuiCheck(-1);
             PostQuitMessage(0);
-          }
+        }
         return 0;
-      default:
+    default:
         return DefWindowProcW(hWnd, msg, wParam, lParam);
     }
 }
@@ -1931,208 +2007,209 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 static DWORD WINAPI
 GuiConsoleGuiThread(PVOID Data)
 {
-  MSG msg;
-  PHANDLE GraphicsStartupEvent = (PHANDLE) Data;
+    MSG msg;
+    PHANDLE GraphicsStartupEvent = (PHANDLE) Data;
 
-  NotifyWnd = CreateWindowW(L"Win32CsrCreateNotify",
-                            L"",
-                            WS_OVERLAPPEDWINDOW,
-                            CW_USEDEFAULT,
-                            CW_USEDEFAULT,
-                            CW_USEDEFAULT,
-                            CW_USEDEFAULT,
-                            NULL,
-                            NULL,
-                            (HINSTANCE) GetModuleHandleW(NULL),
-                            NULL);
-  if (NULL == NotifyWnd)
+    NotifyWnd = CreateWindowW(L"Win32CsrCreateNotify",
+                              L"",
+                              WS_OVERLAPPEDWINDOW,
+                              CW_USEDEFAULT,
+                              CW_USEDEFAULT,
+                              CW_USEDEFAULT,
+                              CW_USEDEFAULT,
+                              NULL,
+                              NULL,
+                              (HINSTANCE) GetModuleHandleW(NULL),
+                              NULL);
+    if (NULL == NotifyWnd)
     {
-      PrivateCsrssManualGuiCheck(-1);
-      SetEvent(*GraphicsStartupEvent);
-      return 1;
+        PrivateCsrssManualGuiCheck(-1);
+        SetEvent(*GraphicsStartupEvent);
+        return 1;
     }
 
-  SetEvent(*GraphicsStartupEvent);
+    SetEvent(*GraphicsStartupEvent);
 
-  while(GetMessageW(&msg, NULL, 0, 0))
+    while(GetMessageW(&msg, NULL, 0, 0))
     {
-      TranslateMessage(&msg);
-      DispatchMessageW(&msg);
+        TranslateMessage(&msg);
+        DispatchMessageW(&msg);
     }
 
-  return 1;
+    return 1;
 }
 
-static BOOL FASTCALL
+static BOOL
 GuiInit(VOID)
 {
-  WNDCLASSEXW wc;
-
-  if (NULL == NotifyWnd)
-    {
-      PrivateCsrssManualGuiCheck(+1);
-    }
-
-  wc.cbSize = sizeof(WNDCLASSEXW);
-  wc.lpszClassName = L"Win32CsrCreateNotify";
-  wc.lpfnWndProc = GuiConsoleNotifyWndProc;
-  wc.style = 0;
-  wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL);
-  wc.hIcon = NULL;
-  wc.hCursor = NULL;
-  wc.hbrBackground = NULL;
-  wc.lpszMenuName = NULL;
-  wc.cbClsExtra = 0;
-  wc.cbWndExtra = 0;
-  wc.hIconSm = NULL;
-  if (RegisterClassExW(&wc) == 0)
-    {
-      DPRINT1("Failed to register notify wndproc\n");
-      return FALSE;
-    }
-
-  wc.cbSize = sizeof(WNDCLASSEXW);
-  wc.lpszClassName = L"ConsoleWindowClass";
-  wc.lpfnWndProc = GuiConsoleWndProc;
-  wc.style = 0;
-  wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL);
-  wc.hIcon = LoadIconW(GetModuleHandleW(L"win32csr"), MAKEINTRESOURCEW(1));
-  wc.hCursor = LoadCursorW(NULL, (LPCWSTR) IDC_ARROW);
-  wc.hbrBackground = NULL;
-  wc.lpszMenuName = NULL;
-  wc.cbClsExtra = 0;
-  wc.cbWndExtra = 0;
-  wc.hIconSm = LoadImageW(GetModuleHandleW(L"win32csr"), MAKEINTRESOURCEW(1), IMAGE_ICON,
-                          GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
-                          LR_SHARED);
-  if (RegisterClassExW(&wc) == 0)
-    {
-      DPRINT1("Failed to register console wndproc\n");
-      return FALSE;
-    }
-
-  return TRUE;
+    WNDCLASSEXW wc;
+
+    if (NULL == NotifyWnd)
+    {
+        PrivateCsrssManualGuiCheck(+1);
+    }
+
+    wc.cbSize = sizeof(WNDCLASSEXW);
+    wc.lpszClassName = L"Win32CsrCreateNotify";
+    wc.lpfnWndProc = GuiConsoleNotifyWndProc;
+    wc.style = 0;
+    wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL);
+    wc.hIcon = NULL;
+    wc.hCursor = NULL;
+    wc.hbrBackground = NULL;
+    wc.lpszMenuName = NULL;
+    wc.cbClsExtra = 0;
+    wc.cbWndExtra = 0;
+    wc.hIconSm = NULL;
+    if (RegisterClassExW(&wc) == 0)
+    {
+        DPRINT1("Failed to register notify wndproc\n");
+        return FALSE;
+    }
+
+    wc.cbSize = sizeof(WNDCLASSEXW);
+    wc.lpszClassName = L"ConsoleWindowClass";
+    wc.lpfnWndProc = GuiConsoleWndProc;
+    wc.style = 0;
+    wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL);
+    wc.hIcon = LoadIconW(GetModuleHandleW(L"win32csr"), MAKEINTRESOURCEW(1));
+    wc.hCursor = LoadCursorW(NULL, (LPCWSTR) IDC_ARROW);
+    wc.hbrBackground = CreateSolidBrush(RGB(0,0,0));
+    wc.lpszMenuName = NULL;
+    wc.cbClsExtra = 0;
+    wc.cbWndExtra = 0;
+    wc.hIconSm = LoadImageW(GetModuleHandleW(L"win32csr"), MAKEINTRESOURCEW(1), IMAGE_ICON,
+                            GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
+                            LR_SHARED);
+    if (RegisterClassExW(&wc) == 0)
+    {
+        DPRINT1("Failed to register console wndproc\n");
+        return FALSE;
+    }
+
+    return TRUE;
 }
 
 static VOID WINAPI
 GuiInitScreenBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buffer)
 {
-  Buffer->DefaultAttrib = DEFAULT_ATTRIB;
+    Buffer->DefaultAttrib = DEFAULT_ATTRIB;
 }
 
 static BOOL WINAPI
 GuiChangeTitle(PCSRSS_CONSOLE Console)
 {
-  PWCHAR Buffer, Title;
+    PWCHAR Buffer, Title;
 
-  Buffer = HeapAlloc(Win32CsrApiHeap, 0,
-                     Console->Title.Length + sizeof(WCHAR));
-  if (NULL != Buffer)
+    Buffer = HeapAlloc(Win32CsrApiHeap, 0,
+                       Console->Title.Length + sizeof(WCHAR));
+    if (NULL != Buffer)
     {
-      memcpy(Buffer, Console->Title.Buffer, Console->Title.Length);
-      Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0';
-      Title = Buffer;
+        memcpy(Buffer, Console->Title.Buffer, Console->Title.Length);
+        Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0';
+        Title = Buffer;
     }
-  else
+    else
     {
-      Title = L"";
+        Title = L"";
     }
 
-  SendMessageW(Console->hWindow, WM_SETTEXT, 0, (LPARAM) Title);
+    SendMessageW(Console->hWindow, WM_SETTEXT, 0, (LPARAM) Title);
 
-  if (NULL != Buffer)
+    if (NULL != Buffer)
     {
-      HeapFree(Win32CsrApiHeap, 0, Buffer);
+        HeapFree(Win32CsrApiHeap, 0, Buffer);
     }
 
-  return TRUE;
+    return TRUE;
 }
 
 static BOOL WINAPI
 GuiChangeIcon(PCSRSS_CONSOLE Console, HICON hWindowIcon)
 {
-  SendMessageW(Console->hWindow, WM_SETICON, ICON_BIG, (LPARAM)hWindowIcon);
-  SendMessageW(Console->hWindow, WM_SETICON, ICON_SMALL, (LPARAM)hWindowIcon);
+    SendMessageW(Console->hWindow, WM_SETICON, ICON_BIG, (LPARAM)hWindowIcon);
+    SendMessageW(Console->hWindow, WM_SETICON, ICON_SMALL, (LPARAM)hWindowIcon);
 
-  return TRUE;
+    return TRUE;
 }
 
 static VOID WINAPI
 GuiCleanupConsole(PCSRSS_CONSOLE Console)
 {
-  SendMessageW(NotifyWnd, PM_DESTROY_CONSOLE, 0, (LPARAM) Console);
+    SendMessageW(NotifyWnd, PM_DESTROY_CONSOLE, 0, (LPARAM) Console);
 }
 
 static CSRSS_CONSOLE_VTBL GuiVtbl =
 {
-  GuiInitScreenBuffer,
-  GuiWriteStream,
-  GuiDrawRegion,
-  GuiSetCursorInfo,
-  GuiSetScreenInfo,
-  GuiUpdateScreenInfo,
-  GuiChangeTitle,
-  GuiCleanupConsole,
-  GuiChangeIcon
+    GuiInitScreenBuffer,
+    GuiWriteStream,
+    GuiDrawRegion,
+    GuiSetCursorInfo,
+    GuiSetScreenInfo,
+    GuiUpdateScreenInfo,
+    GuiChangeTitle,
+    GuiCleanupConsole,
+    GuiChangeIcon,
+    GuiResizeBuffer,
 };
 
 NTSTATUS FASTCALL
-GuiInitConsole(PCSRSS_CONSOLE Console)
+GuiInitConsole(PCSRSS_CONSOLE Console, BOOL Visible)
 {
-  HANDLE GraphicsStartupEvent;
-  HANDLE ThreadHandle;
-  PGUI_CONSOLE_DATA GuiData;
+    HANDLE GraphicsStartupEvent;
+    HANDLE ThreadHandle;
+    PGUI_CONSOLE_DATA GuiData;
 
-  if (! ConsInitialized)
+    if (! ConsInitialized)
     {
-      ConsInitialized = TRUE;
-      if (! GuiInit())
+        ConsInitialized = TRUE;
+        if (! GuiInit())
         {
-          ConsInitialized = FALSE;
-          return STATUS_UNSUCCESSFUL;
+            ConsInitialized = FALSE;
+            return STATUS_UNSUCCESSFUL;
         }
     }
 
-  Console->Vtbl = &GuiVtbl;
-  if (NULL == NotifyWnd)
+    Console->Vtbl = &GuiVtbl;
+    if (NULL == NotifyWnd)
     {
-      GraphicsStartupEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
-      if (NULL == GraphicsStartupEvent)
+        GraphicsStartupEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
+        if (NULL == GraphicsStartupEvent)
         {
-          return STATUS_UNSUCCESSFUL;
+            return STATUS_UNSUCCESSFUL;
         }
 
-      ThreadHandle = CreateThread(NULL,
-                                  0,
-                                  GuiConsoleGuiThread,
-                                  (PVOID) &GraphicsStartupEvent,
-                                  0,
-                                  NULL);
-      if (NULL == ThreadHandle)
+        ThreadHandle = CreateThread(NULL,
+                                    0,
+                                    GuiConsoleGuiThread,
+                                    (PVOID) &GraphicsStartupEvent,
+                                    0,
+                                    NULL);
+        if (NULL == ThreadHandle)
         {
-          NtClose(GraphicsStartupEvent);
-          DPRINT1("Win32Csr: Failed to create graphics console thread. Expect problems\n");
-          return STATUS_UNSUCCESSFUL;
+            NtClose(GraphicsStartupEvent);
+            DPRINT1("Win32Csr: Failed to create graphics console thread. Expect problems\n");
+            return STATUS_UNSUCCESSFUL;
         }
-      SetThreadPriority(ThreadHandle, THREAD_PRIORITY_HIGHEST);
-      CloseHandle(ThreadHandle);
+        SetThreadPriority(ThreadHandle, THREAD_PRIORITY_HIGHEST);
+        CloseHandle(ThreadHandle);
 
-      WaitForSingleObject(GraphicsStartupEvent, INFINITE);
-      CloseHandle(GraphicsStartupEvent);
+        WaitForSingleObject(GraphicsStartupEvent, INFINITE);
+        CloseHandle(GraphicsStartupEvent);
 
-      if (NULL == NotifyWnd)
+        if (NULL == NotifyWnd)
         {
-          DPRINT1("Win32Csr: Failed to create notification window.\n");
-          return STATUS_UNSUCCESSFUL;
+            DPRINT1("Win32Csr: Failed to create notification window.\n");
+            return STATUS_UNSUCCESSFUL;
         }
     }
     GuiData = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY,
                         sizeof(GUI_CONSOLE_DATA));
     if (!GuiData)
-      {
+    {
         DPRINT1("Win32Csr: Failed to create GUI_CONSOLE_DATA\n");
         return STATUS_UNSUCCESSFUL;
-      }
+    }
 
     Console->PrivateData = (PVOID) GuiData;
     /*
@@ -2144,15 +2221,15 @@ GuiInitConsole(PCSRSS_CONSOLE Console)
      */
     GuiData->hGuiInitEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
     /* create console */
-    PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, 0, (LPARAM) Console);
+    PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, Visible, (LPARAM) Console);
 
     /* wait untill initialization has finished */
     WaitForSingleObject(GuiData->hGuiInitEvent, INFINITE);
-    DPRINT1("received event Console %p GuiData %p X %d Y %d\n", Console, Console->PrivateData, Console->Size.X, Console->Size.Y);
+    DPRINT("received event Console %p GuiData %p X %d Y %d\n", Console, Console->PrivateData, Console->Size.X, Console->Size.Y);
     CloseHandle(GuiData->hGuiInitEvent);
     GuiData->hGuiInitEvent = NULL;
 
-  return STATUS_SUCCESS;
+    return STATUS_SUCCESS;
 }
 
 /* EOF */