Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenguiconsole.c
Go to the documentation of this file.
00001 /* $Id: guiconsole.c 55620 2012-02-15 22:15:33Z ion $ 00002 * 00003 * COPYRIGHT: See COPYING in the top level directory 00004 * PROJECT: ReactOS system libraries 00005 * FILE: subsys/csrss/win32csr/guiconsole.c 00006 * PURPOSE: Implementation of gui-mode consoles 00007 */ 00008 00009 /* INCLUDES ******************************************************************/ 00010 00011 #define NDEBUG 00012 #include "w32csr.h" 00013 #include <debug.h> 00014 00015 /* Not defined in any header file */ 00016 extern VOID WINAPI PrivateCsrssManualGuiCheck(LONG Check); 00017 00018 /* GLOBALS *******************************************************************/ 00019 00020 typedef struct GUI_CONSOLE_DATA_TAG 00021 { 00022 HFONT Font; 00023 unsigned CharWidth; 00024 unsigned CharHeight; 00025 BOOL CursorBlinkOn; 00026 BOOL ForceCursorOff; 00027 CRITICAL_SECTION Lock; 00028 HMODULE ConsoleLibrary; 00029 HANDLE hGuiInitEvent; 00030 WCHAR FontName[LF_FACESIZE]; 00031 DWORD FontSize; 00032 DWORD FontWeight; 00033 DWORD FullScreen; 00034 DWORD QuickEdit; 00035 DWORD InsertMode; 00036 DWORD WindowPosition; 00037 DWORD UseRasterFonts; 00038 COLORREF ScreenText; 00039 COLORREF ScreenBackground; 00040 COLORREF PopupBackground; 00041 COLORREF PopupText; 00042 COLORREF Colors[16]; 00043 WCHAR szProcessName[MAX_PATH]; 00044 BOOL WindowSizeLock; 00045 POINT OldCursor; 00046 } GUI_CONSOLE_DATA, *PGUI_CONSOLE_DATA; 00047 00048 #ifndef WM_APP 00049 #define WM_APP 0x8000 00050 #endif 00051 #define PM_CREATE_CONSOLE (WM_APP + 1) 00052 #define PM_DESTROY_CONSOLE (WM_APP + 2) 00053 00054 #define CURSOR_BLINK_TIME 500 00055 #define DEFAULT_ATTRIB (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED) 00056 00057 static BOOL ConsInitialized = FALSE; 00058 static HWND NotifyWnd; 00059 00060 typedef struct _GUICONSOLE_MENUITEM 00061 { 00062 UINT uID; 00063 const struct _GUICONSOLE_MENUITEM *SubMenu; 00064 WORD wCmdID; 00065 } GUICONSOLE_MENUITEM, *PGUICONSOLE_MENUITEM; 00066 00067 static const GUICONSOLE_MENUITEM GuiConsoleEditMenuItems[] = 00068 { 00069 { IDS_MARK, NULL, ID_SYSTEM_EDIT_MARK }, 00070 { IDS_COPY, NULL, ID_SYSTEM_EDIT_COPY }, 00071 { IDS_PASTE, NULL, ID_SYSTEM_EDIT_PASTE }, 00072 { IDS_SELECTALL, NULL, ID_SYSTEM_EDIT_SELECTALL }, 00073 { IDS_SCROLL, NULL, ID_SYSTEM_EDIT_SCROLL }, 00074 { IDS_FIND, NULL, ID_SYSTEM_EDIT_FIND }, 00075 00076 { 0, NULL, 0 } /* End of list */ 00077 }; 00078 00079 static const GUICONSOLE_MENUITEM GuiConsoleMainMenuItems[] = 00080 { 00081 { (UINT)-1, NULL, 0 }, /* Separator */ 00082 { IDS_EDIT, GuiConsoleEditMenuItems, 0 }, 00083 { IDS_DEFAULTS, NULL, ID_SYSTEM_DEFAULTS }, 00084 { IDS_PROPERTIES, NULL, ID_SYSTEM_PROPERTIES }, 00085 00086 { 0, NULL, 0 } /* End of list */ 00087 }; 00088 00089 static const COLORREF s_Colors[] = 00090 { 00091 RGB(0, 0, 0), 00092 RGB(0, 0, 128), 00093 RGB(0, 128, 0), 00094 RGB(0, 128, 128), 00095 RGB(128, 0, 0), 00096 RGB(128, 0, 128), 00097 RGB(128, 128, 0), 00098 RGB(192, 192, 192), 00099 RGB(128, 128, 128), 00100 RGB(0, 0, 255), 00101 RGB(0, 255, 0), 00102 RGB(0, 255, 255), 00103 RGB(255, 0, 0), 00104 RGB(255, 0, 255), 00105 RGB(255, 255, 0), 00106 RGB(255, 255, 255) 00107 }; 00108 00109 #define GuiConsoleRGBFromAttribute(GuiData, Attribute) ((GuiData)->Colors[(Attribute) & 0xF]) 00110 00111 /* FUNCTIONS *****************************************************************/ 00112 00113 static VOID 00114 GuiConsoleAppendMenuItems(HMENU hMenu, 00115 const GUICONSOLE_MENUITEM *Items) 00116 { 00117 UINT i = 0; 00118 WCHAR szMenuString[255]; 00119 HMENU hSubMenu; 00120 HINSTANCE hInst = GetModuleHandleW(L"win32csr"); 00121 00122 do 00123 { 00124 if (Items[i].uID != (UINT)-1) 00125 { 00126 if (LoadStringW(hInst, 00127 Items[i].uID, 00128 szMenuString, 00129 sizeof(szMenuString) / sizeof(szMenuString[0])) > 0) 00130 { 00131 if (Items[i].SubMenu != NULL) 00132 { 00133 hSubMenu = CreatePopupMenu(); 00134 if (hSubMenu != NULL) 00135 { 00136 GuiConsoleAppendMenuItems(hSubMenu, 00137 Items[i].SubMenu); 00138 00139 if (!AppendMenuW(hMenu, 00140 MF_STRING | MF_POPUP, 00141 (UINT_PTR)hSubMenu, 00142 szMenuString)) 00143 { 00144 DestroyMenu(hSubMenu); 00145 } 00146 } 00147 } 00148 else 00149 { 00150 AppendMenuW(hMenu, 00151 MF_STRING, 00152 Items[i].wCmdID, 00153 szMenuString); 00154 } 00155 } 00156 } 00157 else 00158 { 00159 AppendMenuW(hMenu, 00160 MF_SEPARATOR, 00161 0, 00162 NULL); 00163 } 00164 i++; 00165 } while(!(Items[i].uID == 0 && Items[i].SubMenu == NULL && Items[i].wCmdID == 0)); 00166 } 00167 00168 static VOID 00169 GuiConsoleCreateSysMenu(PCSRSS_CONSOLE Console) 00170 { 00171 HMENU hMenu; 00172 hMenu = GetSystemMenu(Console->hWindow, 00173 FALSE); 00174 if (hMenu != NULL) 00175 { 00176 GuiConsoleAppendMenuItems(hMenu, 00177 GuiConsoleMainMenuItems); 00178 DrawMenuBar(Console->hWindow); 00179 } 00180 } 00181 00182 static VOID 00183 GuiConsoleGetDataPointers(HWND hWnd, PCSRSS_CONSOLE *Console, PGUI_CONSOLE_DATA *GuiData) 00184 { 00185 *Console = (PCSRSS_CONSOLE) GetWindowLongPtrW(hWnd, GWL_USERDATA); 00186 *GuiData = (NULL == *Console ? NULL : (*Console)->PrivateData); 00187 } 00188 00189 static BOOL 00190 GuiConsoleOpenUserRegistryPathPerProcessId(DWORD ProcessId, PHANDLE hProcHandle, PHKEY hResult, REGSAM samDesired) 00191 { 00192 HANDLE hProcessToken = NULL; 00193 HANDLE hProcess; 00194 00195 BYTE Buffer[256]; 00196 DWORD Length = 0; 00197 UNICODE_STRING SidName; 00198 LONG res; 00199 PTOKEN_USER TokUser; 00200 00201 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | READ_CONTROL, FALSE, ProcessId); 00202 if (!hProcess) 00203 { 00204 DPRINT("Error: OpenProcess failed(0x%x)\n", GetLastError()); 00205 return FALSE; 00206 } 00207 00208 if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken)) 00209 { 00210 DPRINT("Error: OpenProcessToken failed(0x%x)\n", GetLastError()); 00211 CloseHandle(hProcess); 00212 return FALSE; 00213 } 00214 00215 if (!GetTokenInformation(hProcessToken, TokenUser, (PVOID)Buffer, sizeof(Buffer), &Length)) 00216 { 00217 DPRINT("Error: GetTokenInformation failed(0x%x)\n",GetLastError()); 00218 CloseHandle(hProcessToken); 00219 CloseHandle(hProcess); 00220 return FALSE; 00221 } 00222 00223 TokUser = ((PTOKEN_USER)Buffer)->User.Sid; 00224 if (!NT_SUCCESS(RtlConvertSidToUnicodeString(&SidName, TokUser, TRUE))) 00225 { 00226 DPRINT("Error: RtlConvertSidToUnicodeString failed(0x%x)\n", GetLastError()); 00227 CloseHandle(hProcessToken); 00228 CloseHandle(hProcess); 00229 return FALSE; 00230 } 00231 00232 res = RegOpenKeyExW(HKEY_USERS, SidName.Buffer, 0, samDesired, hResult); 00233 RtlFreeUnicodeString(&SidName); 00234 00235 CloseHandle(hProcessToken); 00236 if (res != ERROR_SUCCESS) 00237 { 00238 CloseHandle(hProcess); 00239 return FALSE; 00240 } 00241 00242 if (hProcHandle) 00243 *hProcHandle = hProcess; 00244 else 00245 CloseHandle(hProcess); 00246 00247 return TRUE; 00248 } 00249 00250 static BOOL 00251 GuiConsoleOpenUserSettings(PGUI_CONSOLE_DATA GuiData, DWORD ProcessId, PHKEY hSubKey, REGSAM samDesired, BOOL bCreate) 00252 { 00253 WCHAR szProcessName[MAX_PATH]; 00254 WCHAR szBuffer[MAX_PATH]; 00255 UINT fLength, wLength; 00256 DWORD dwBitmask, dwLength; 00257 WCHAR CurDrive[] = { 'A',':', 0 }; 00258 HANDLE hProcess; 00259 HKEY hKey; 00260 WCHAR * ptr; 00261 00262 /* 00263 * console properties are stored under 00264 * HKCU\Console\* 00265 * 00266 * There are 3 ways to store console properties 00267 * 00268 * 1. use console title as subkey name 00269 * i.e. cmd.exe 00270 * 00271 * 2. use application name as subkey name 00272 * 00273 * 3. use unexpanded path to console application. 00274 * i.e. %SystemRoot%_system32_cmd.exe 00275 */ 00276 00277 DPRINT("GuiConsoleOpenUserSettings entered\n"); 00278 00279 if (!GuiConsoleOpenUserRegistryPathPerProcessId(ProcessId, &hProcess, &hKey, samDesired)) 00280 { 00281 DPRINT("GuiConsoleOpenUserRegistryPathPerProcessId failed\n"); 00282 return FALSE; 00283 } 00284 00285 /* FIXME we do not getting the process name so no menu will be loading, why ?*/ 00286 fLength = GetProcessImageFileNameW(hProcess, szProcessName, sizeof(GuiData->szProcessName) / sizeof(WCHAR)); 00287 CloseHandle(hProcess); 00288 00289 //DPRINT1("szProcessName3 : %S\n",szProcessName); 00290 00291 if (!fLength) 00292 { 00293 DPRINT("GetProcessImageFileNameW failed(0x%x)ProcessId %d\n", GetLastError(), ProcessId); 00294 return FALSE; 00295 } 00296 /* 00297 * try the process name as path 00298 */ 00299 00300 ptr = wcsrchr(szProcessName, L'\\'); 00301 wcscpy(GuiData->szProcessName, ptr); 00302 00303 swprintf(szBuffer, L"Console%s",ptr); 00304 DPRINT("#1 Path : %S\n", szBuffer); 00305 00306 if (bCreate) 00307 { 00308 if (RegCreateKeyW(hKey, szBuffer, hSubKey) == ERROR_SUCCESS) 00309 { 00310 RegCloseKey(hKey); 00311 return TRUE; 00312 } 00313 RegCloseKey(hKey); 00314 return FALSE; 00315 } 00316 00317 if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS) 00318 { 00319 RegCloseKey(hKey); 00320 return TRUE; 00321 } 00322 00323 /* 00324 * try the "Shortcut to processname" as path 00325 * FIXME: detect wheter the process was started as a shortcut 00326 */ 00327 00328 swprintf(szBuffer, L"Console\\Shortcut to %S", ptr); 00329 DPRINT("#2 Path : %S\n", szBuffer); 00330 if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS) 00331 { 00332 swprintf(GuiData->szProcessName, L"Shortcut to %S", ptr); 00333 RegCloseKey(hKey); 00334 return TRUE; 00335 } 00336 00337 /* 00338 * if the path contains \\Device\\HarddiskVolume1\... remove it 00339 */ 00340 00341 if (szProcessName[0] == L'\\') 00342 { 00343 dwBitmask = GetLogicalDrives(); 00344 while(dwBitmask) 00345 { 00346 if (dwBitmask & 0x1) 00347 { 00348 dwLength = QueryDosDeviceW(CurDrive, szBuffer, MAX_PATH); 00349 if (dwLength) 00350 { 00351 if (!memcmp(szBuffer, szProcessName, (dwLength-2)*sizeof(WCHAR))) 00352 { 00353 wcscpy(szProcessName, CurDrive); 00354 RtlMoveMemory(&szProcessName[2], &szProcessName[dwLength-1], fLength - dwLength -1); 00355 break; 00356 } 00357 } 00358 } 00359 dwBitmask = (dwBitmask >> 1); 00360 CurDrive[0]++; 00361 } 00362 } 00363 00364 /* 00365 * last attempt: check whether the file is under %SystemRoot% 00366 * and use path like Console\%SystemRoot%_dir_dir2_file.exe 00367 */ 00368 00369 wLength = GetWindowsDirectoryW(szBuffer, MAX_PATH); 00370 if (wLength) 00371 { 00372 if (!wcsncmp(szProcessName, szBuffer, wLength)) 00373 { 00374 /* replace slashes by underscores */ 00375 while((ptr = wcschr(szProcessName, L'\\'))) 00376 ptr[0] = L'_'; 00377 00378 swprintf(szBuffer, L"Console\\%%SystemRoot%%%S", &szProcessName[wLength]); 00379 DPRINT("#3 Path : %S\n", szBuffer); 00380 if (RegOpenKeyExW(hKey, szBuffer, 0, samDesired, hSubKey) == ERROR_SUCCESS) 00381 { 00382 swprintf(GuiData->szProcessName, L"%%SystemRoot%%%S", &szProcessName[wLength]); 00383 RegCloseKey(hKey); 00384 return TRUE; 00385 } 00386 } 00387 } 00388 RegCloseKey(hKey); 00389 return FALSE; 00390 } 00391 00392 static VOID 00393 GuiConsoleWriteUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData) 00394 { 00395 HKEY hKey; 00396 PCSR_PROCESS ProcessData; 00397 00398 if (Console->ProcessList.Flink == &Console->ProcessList) 00399 { 00400 DPRINT("GuiConsoleWriteUserSettings: No Process!!!\n"); 00401 return; 00402 } 00403 ProcessData = CONTAINING_RECORD(Console->ProcessList.Flink, CSR_PROCESS, ConsoleLink); 00404 if (!GuiConsoleOpenUserSettings(GuiData, PtrToUlong(ProcessData->ClientId.UniqueProcess), &hKey, KEY_READ | KEY_WRITE, TRUE)) 00405 { 00406 return; 00407 } 00408 00409 if (Console->ActiveBuffer->CursorInfo.dwSize <= 1) 00410 { 00411 RegDeleteKeyW(hKey, L"CursorSize"); 00412 } 00413 else 00414 { 00415 RegSetValueExW(hKey, L"CursorSize", 0, REG_DWORD, (const BYTE *)&Console->ActiveBuffer->CursorInfo.dwSize, sizeof(DWORD)); 00416 } 00417 00418 if (Console->NumberOfHistoryBuffers == 5) 00419 { 00420 RegDeleteKeyW(hKey, L"NumberOfHistoryBuffers"); 00421 } 00422 else 00423 { 00424 DWORD Temp = Console->NumberOfHistoryBuffers; 00425 RegSetValueExW(hKey, L"NumberOfHistoryBuffers", 0, REG_DWORD, (const BYTE *)&Temp, sizeof(DWORD)); 00426 } 00427 00428 if (Console->HistoryBufferSize == 50) 00429 { 00430 RegDeleteKeyW(hKey, L"HistoryBufferSize"); 00431 } 00432 else 00433 { 00434 DWORD Temp = Console->HistoryBufferSize; 00435 RegSetValueExW(hKey, L"HistoryBufferSize", 0, REG_DWORD, (const BYTE *)&Temp, sizeof(DWORD)); 00436 } 00437 00438 if (GuiData->FullScreen == FALSE) 00439 { 00440 RegDeleteKeyW(hKey, L"FullScreen"); 00441 } 00442 else 00443 { 00444 RegSetValueExW(hKey, L"FullScreen", 0, REG_DWORD, (const BYTE *)&GuiData->FullScreen, sizeof(DWORD)); 00445 } 00446 00447 if ( GuiData->QuickEdit == FALSE) 00448 { 00449 RegDeleteKeyW(hKey, L"QuickEdit"); 00450 } 00451 else 00452 { 00453 RegSetValueExW(hKey, L"QuickEdit", 0, REG_DWORD, (const BYTE *)&GuiData->QuickEdit, sizeof(DWORD)); 00454 } 00455 00456 if (GuiData->InsertMode == TRUE) 00457 { 00458 RegDeleteKeyW(hKey, L"InsertMode"); 00459 } 00460 else 00461 { 00462 RegSetValueExW(hKey, L"InsertMode", 0, REG_DWORD, (const BYTE *)&GuiData->InsertMode, sizeof(DWORD)); 00463 } 00464 00465 if (Console->HistoryNoDup == FALSE) 00466 { 00467 RegDeleteKeyW(hKey, L"HistoryNoDup"); 00468 } 00469 else 00470 { 00471 DWORD Temp = Console->HistoryNoDup; 00472 RegSetValueExW(hKey, L"HistoryNoDup", 0, REG_DWORD, (const BYTE *)&Temp, sizeof(DWORD)); 00473 } 00474 00475 if (GuiData->ScreenText == RGB(192, 192, 192)) 00476 { 00477 /* 00478 * MS uses console attributes instead of real color 00479 */ 00480 RegDeleteKeyW(hKey, L"ScreenText"); 00481 } 00482 else 00483 { 00484 RegSetValueExW(hKey, L"ScreenText", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenText, sizeof(COLORREF)); 00485 } 00486 00487 if (GuiData->ScreenBackground == RGB(0, 0, 0)) 00488 { 00489 RegDeleteKeyW(hKey, L"ScreenBackground"); 00490 } 00491 else 00492 { 00493 RegSetValueExW(hKey, L"ScreenBackground", 0, REG_DWORD, (const BYTE *)&GuiData->ScreenBackground, sizeof(COLORREF)); 00494 } 00495 00496 RegCloseKey(hKey); 00497 } 00498 00499 static void 00500 GuiConsoleReadUserSettings(HKEY hKey, PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCSRSS_SCREEN_BUFFER Buffer) 00501 { 00502 DWORD dwNumSubKeys = 0; 00503 DWORD dwIndex; 00504 DWORD dwValueName; 00505 DWORD dwValue; 00506 DWORD dwType; 00507 WCHAR szValueName[MAX_PATH]; 00508 WCHAR szValue[LF_FACESIZE] = L"\0"; 00509 DWORD Value; 00510 00511 if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwNumSubKeys, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) 00512 { 00513 DPRINT("GuiConsoleReadUserSettings: RegQueryInfoKey failed\n"); 00514 return; 00515 } 00516 00517 DPRINT("GuiConsoleReadUserSettings entered dwNumSubKeys %d\n", dwNumSubKeys); 00518 00519 for (dwIndex = 0; dwIndex < dwNumSubKeys; dwIndex++) 00520 { 00521 dwValue = sizeof(Value); 00522 dwValueName = MAX_PATH; 00523 00524 if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, &dwType, (BYTE*)&Value, &dwValue) != ERROR_SUCCESS) 00525 { 00526 if (dwType == REG_SZ) 00527 { 00528 /* 00529 * retry in case of string value 00530 */ 00531 dwValue = sizeof(szValue); 00532 dwValueName = LF_FACESIZE; 00533 if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, NULL, (BYTE*)szValue, &dwValue) != ERROR_SUCCESS) 00534 break; 00535 } 00536 else 00537 break; 00538 } 00539 if (!wcscmp(szValueName, L"CursorSize")) 00540 { 00541 if (Value == 0x32) 00542 { 00543 Buffer->CursorInfo.dwSize = Value; 00544 } 00545 else if (Value == 0x64) 00546 { 00547 Buffer->CursorInfo.dwSize = Value; 00548 } 00549 } 00550 else if (!wcscmp(szValueName, L"ScreenText")) 00551 { 00552 GuiData->ScreenText = Value; 00553 } 00554 else if (!wcscmp(szValueName, L"ScreenBackground")) 00555 { 00556 GuiData->ScreenBackground = Value; 00557 } 00558 else if (!wcscmp(szValueName, L"FaceName")) 00559 { 00560 wcscpy(GuiData->FontName, szValue); 00561 } 00562 else if (!wcscmp(szValueName, L"FontSize")) 00563 { 00564 GuiData->FontSize = Value; 00565 } 00566 else if (!wcscmp(szValueName, L"FontWeight")) 00567 { 00568 GuiData->FontWeight = Value; 00569 } 00570 else if (!wcscmp(szValueName, L"HistoryNoDup")) 00571 { 00572 Console->HistoryNoDup = Value; 00573 } 00574 else if (!wcscmp(szValueName, L"WindowSize")) 00575 { 00576 Console->Size.X = LOWORD(Value); 00577 Console->Size.Y = HIWORD(Value); 00578 } 00579 else if (!wcscmp(szValueName, L"ScreenBufferSize")) 00580 { 00581 if(Buffer) 00582 { 00583 Buffer->MaxX = LOWORD(Value); 00584 Buffer->MaxY = HIWORD(Value); 00585 } 00586 } 00587 else if (!wcscmp(szValueName, L"FullScreen")) 00588 { 00589 GuiData->FullScreen = Value; 00590 } 00591 else if (!wcscmp(szValueName, L"QuickEdit")) 00592 { 00593 GuiData->QuickEdit = Value; 00594 } 00595 else if (!wcscmp(szValueName, L"InsertMode")) 00596 { 00597 GuiData->InsertMode = Value; 00598 } 00599 } 00600 } 00601 static VOID 00602 GuiConsoleUseDefaults(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PCSRSS_SCREEN_BUFFER Buffer) 00603 { 00604 /* 00605 * init guidata with default properties 00606 */ 00607 00608 wcscpy(GuiData->FontName, L"DejaVu Sans Mono"); 00609 GuiData->FontSize = 0x0008000C; // font is 8x12 00610 GuiData->FontWeight = FW_NORMAL; 00611 GuiData->FullScreen = FALSE; 00612 GuiData->QuickEdit = FALSE; 00613 GuiData->InsertMode = TRUE; 00614 GuiData->ScreenText = RGB(192, 192, 192); 00615 GuiData->ScreenBackground = RGB(0, 0, 0); 00616 GuiData->PopupText = RGB(128, 0, 128); 00617 GuiData->PopupBackground = RGB(255, 255, 255); 00618 GuiData->WindowPosition = UINT_MAX; 00619 GuiData->UseRasterFonts = TRUE; 00620 memcpy(GuiData->Colors, s_Colors, sizeof(s_Colors)); 00621 00622 Console->HistoryBufferSize = 50; 00623 Console->NumberOfHistoryBuffers = 5; 00624 Console->HistoryNoDup = FALSE; 00625 Console->Size.X = 80; 00626 Console->Size.Y = 25; 00627 00628 if (Buffer) 00629 { 00630 Buffer->MaxX = 80; 00631 Buffer->MaxY = 300; 00632 Buffer->CursorInfo.bVisible = TRUE; 00633 Buffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE; 00634 } 00635 } 00636 00637 VOID 00638 FASTCALL 00639 GuiConsoleInitScrollbar(PCSRSS_CONSOLE Console, HWND hwnd) 00640 { 00641 SCROLLINFO sInfo; 00642 PGUI_CONSOLE_DATA GuiData = Console->PrivateData; 00643 00644 DWORD Width = Console->Size.X * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE)); 00645 DWORD Height = Console->Size.Y * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION); 00646 00647 /* set scrollbar sizes */ 00648 sInfo.cbSize = sizeof(SCROLLINFO); 00649 sInfo.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; 00650 sInfo.nMin = 0; 00651 if (Console->ActiveBuffer->MaxY > Console->Size.Y) 00652 { 00653 sInfo.nMax = Console->ActiveBuffer->MaxY - 1; 00654 sInfo.nPage = Console->Size.Y; 00655 sInfo.nPos = Console->ActiveBuffer->ShowY; 00656 SetScrollInfo(hwnd, SB_VERT, &sInfo, TRUE); 00657 Width += GetSystemMetrics(SM_CXVSCROLL); 00658 ShowScrollBar(hwnd, SB_VERT, TRUE); 00659 } 00660 else 00661 { 00662 ShowScrollBar(hwnd, SB_VERT, FALSE); 00663 } 00664 00665 if (Console->ActiveBuffer->MaxX > Console->Size.X) 00666 { 00667 sInfo.nMax = Console->ActiveBuffer->MaxX - 1; 00668 sInfo.nPage = Console->Size.X; 00669 sInfo.nPos = Console->ActiveBuffer->ShowX; 00670 SetScrollInfo(hwnd, SB_HORZ, &sInfo, TRUE); 00671 Height += GetSystemMetrics(SM_CYHSCROLL); 00672 ShowScrollBar(hwnd, SB_HORZ, TRUE); 00673 00674 } 00675 else 00676 { 00677 ShowScrollBar(hwnd, SB_HORZ, FALSE); 00678 } 00679 00680 SetWindowPos(hwnd, NULL, 0, 0, Width, Height, 00681 SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); 00682 } 00683 00684 static BOOL 00685 GuiConsoleHandleNcCreate(HWND hWnd, CREATESTRUCTW *Create) 00686 { 00687 PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Create->lpCreateParams; 00688 PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA)Console->PrivateData; 00689 HDC Dc; 00690 HFONT OldFont; 00691 TEXTMETRICW Metrics; 00692 SIZE CharSize; 00693 PCSR_PROCESS ProcessData; 00694 HKEY hKey; 00695 00696 Console->hWindow = hWnd; 00697 00698 if (NULL == GuiData) 00699 { 00700 DPRINT1("GuiConsoleNcCreate: HeapAlloc failed\n"); 00701 return FALSE; 00702 } 00703 00704 GuiConsoleUseDefaults(Console, GuiData, Console->ActiveBuffer); 00705 if (Console->ProcessList.Flink != &Console->ProcessList) 00706 { 00707 ProcessData = CONTAINING_RECORD(Console->ProcessList.Flink, CSR_PROCESS, ConsoleLink); 00708 if (GuiConsoleOpenUserSettings(GuiData, PtrToUlong(ProcessData->ClientId.UniqueProcess), &hKey, KEY_READ, FALSE)) 00709 { 00710 GuiConsoleReadUserSettings(hKey, Console, GuiData, Console->ActiveBuffer); 00711 RegCloseKey(hKey); 00712 } 00713 } 00714 00715 InitializeCriticalSection(&GuiData->Lock); 00716 00717 GuiData->Font = CreateFontW(LOWORD(GuiData->FontSize), 00718 0, //HIWORD(GuiData->FontSize), 00719 0, 00720 TA_BASELINE, 00721 GuiData->FontWeight, 00722 FALSE, 00723 FALSE, 00724 FALSE, 00725 OEM_CHARSET, 00726 OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, 00727 NONANTIALIASED_QUALITY, FIXED_PITCH | FF_DONTCARE, 00728 GuiData->FontName); 00729 if (NULL == GuiData->Font) 00730 { 00731 DPRINT1("GuiConsoleNcCreate: CreateFont failed\n"); 00732 DeleteCriticalSection(&GuiData->Lock); 00733 HeapFree(Win32CsrApiHeap, 0, GuiData); 00734 return FALSE; 00735 } 00736 Dc = GetDC(hWnd); 00737 if (NULL == Dc) 00738 { 00739 DPRINT1("GuiConsoleNcCreate: GetDC failed\n"); 00740 DeleteObject(GuiData->Font); 00741 DeleteCriticalSection(&GuiData->Lock); 00742 HeapFree(Win32CsrApiHeap, 0, GuiData); 00743 return FALSE; 00744 } 00745 OldFont = SelectObject(Dc, GuiData->Font); 00746 if (NULL == OldFont) 00747 { 00748 DPRINT1("GuiConsoleNcCreate: SelectObject failed\n"); 00749 ReleaseDC(hWnd, Dc); 00750 DeleteObject(GuiData->Font); 00751 DeleteCriticalSection(&GuiData->Lock); 00752 HeapFree(Win32CsrApiHeap, 0, GuiData); 00753 return FALSE; 00754 } 00755 if (! GetTextMetricsW(Dc, &Metrics)) 00756 { 00757 DPRINT1("GuiConsoleNcCreate: GetTextMetrics failed\n"); 00758 SelectObject(Dc, OldFont); 00759 ReleaseDC(hWnd, Dc); 00760 DeleteObject(GuiData->Font); 00761 DeleteCriticalSection(&GuiData->Lock); 00762 HeapFree(Win32CsrApiHeap, 0, GuiData); 00763 return FALSE; 00764 } 00765 GuiData->CharWidth = Metrics.tmMaxCharWidth; 00766 GuiData->CharHeight = Metrics.tmHeight + Metrics.tmExternalLeading; 00767 00768 /* Measure real char width more precisely if possible. */ 00769 if (GetTextExtentPoint32W(Dc, L"R", 1, &CharSize)) 00770 GuiData->CharWidth = CharSize.cx; 00771 00772 SelectObject(Dc, OldFont); 00773 00774 ReleaseDC(hWnd, Dc); 00775 GuiData->CursorBlinkOn = TRUE; 00776 GuiData->ForceCursorOff = FALSE; 00777 00778 DPRINT("Console %p GuiData %p\n", Console, GuiData); 00779 Console->PrivateData = GuiData; 00780 SetWindowLongPtrW(hWnd, GWL_USERDATA, (DWORD_PTR) Console); 00781 00782 SetTimer(hWnd, CONGUI_UPDATE_TIMER, CONGUI_UPDATE_TIME, NULL); 00783 GuiConsoleCreateSysMenu(Console); 00784 00785 GuiData->WindowSizeLock = TRUE; 00786 GuiConsoleInitScrollbar(Console, hWnd); 00787 GuiData->WindowSizeLock = FALSE; 00788 00789 SetEvent(GuiData->hGuiInitEvent); 00790 00791 return (BOOL) DefWindowProcW(hWnd, WM_NCCREATE, 0, (LPARAM) Create); 00792 } 00793 00794 static VOID 00795 SmallRectToRect(PCSRSS_CONSOLE Console, PRECT Rect, PSMALL_RECT SmallRect) 00796 { 00797 PCSRSS_SCREEN_BUFFER Buffer = Console->ActiveBuffer; 00798 PGUI_CONSOLE_DATA GuiData = Console->PrivateData; 00799 Rect->left = (SmallRect->Left - Buffer->ShowX) * GuiData->CharWidth; 00800 Rect->top = (SmallRect->Top - Buffer->ShowY) * GuiData->CharHeight; 00801 Rect->right = (SmallRect->Right + 1 - Buffer->ShowX) * GuiData->CharWidth; 00802 Rect->bottom = (SmallRect->Bottom + 1 - Buffer->ShowY) * GuiData->CharHeight; 00803 } 00804 00805 static VOID 00806 GuiConsoleUpdateSelection(PCSRSS_CONSOLE Console, PCOORD coord) 00807 { 00808 RECT oldRect, newRect; 00809 HWND hWnd = Console->hWindow; 00810 00811 SmallRectToRect(Console, &oldRect, &Console->Selection.srSelection); 00812 00813 if(coord != NULL) 00814 { 00815 SMALL_RECT rc; 00816 /* exchange left/top with right/bottom if required */ 00817 rc.Left = min(Console->Selection.dwSelectionAnchor.X, coord->X); 00818 rc.Top = min(Console->Selection.dwSelectionAnchor.Y, coord->Y); 00819 rc.Right = max(Console->Selection.dwSelectionAnchor.X, coord->X); 00820 rc.Bottom = max(Console->Selection.dwSelectionAnchor.Y, coord->Y); 00821 00822 SmallRectToRect(Console, &newRect, &rc); 00823 00824 if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) 00825 { 00826 if (memcmp(&rc, &Console->Selection.srSelection, sizeof(SMALL_RECT)) != 0) 00827 { 00828 HRGN rgn1, rgn2; 00829 00830 /* calculate the region that needs to be updated */ 00831 if((rgn1 = CreateRectRgnIndirect(&oldRect))) 00832 { 00833 if((rgn2 = CreateRectRgnIndirect(&newRect))) 00834 { 00835 if(CombineRgn(rgn1, rgn2, rgn1, RGN_XOR) != ERROR) 00836 { 00837 InvalidateRgn(hWnd, rgn1, FALSE); 00838 } 00839 00840 DeleteObject(rgn2); 00841 } 00842 DeleteObject(rgn1); 00843 } 00844 } 00845 } 00846 else 00847 { 00848 InvalidateRect(hWnd, &newRect, FALSE); 00849 } 00850 Console->Selection.dwFlags |= CONSOLE_SELECTION_NOT_EMPTY; 00851 Console->Selection.srSelection = rc; 00852 ConioPause(Console, PAUSED_FROM_SELECTION); 00853 } 00854 else 00855 { 00856 /* clear the selection */ 00857 if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) 00858 { 00859 InvalidateRect(hWnd, &oldRect, FALSE); 00860 } 00861 Console->Selection.dwFlags = CONSOLE_NO_SELECTION; 00862 ConioUnpause(Console, PAUSED_FROM_SELECTION); 00863 } 00864 } 00865 00866 00867 static VOID 00868 GuiConsolePaint(PCSRSS_CONSOLE Console, 00869 PGUI_CONSOLE_DATA GuiData, 00870 HDC hDC, 00871 PRECT rc) 00872 { 00873 PCSRSS_SCREEN_BUFFER Buff; 00874 ULONG TopLine, BottomLine, LeftChar, RightChar; 00875 ULONG Line, Char, Start; 00876 PBYTE From; 00877 PWCHAR To; 00878 BYTE LastAttribute, Attribute; 00879 ULONG CursorX, CursorY, CursorHeight; 00880 HBRUSH CursorBrush, OldBrush; 00881 HFONT OldFont; 00882 00883 Buff = Console->ActiveBuffer; 00884 00885 EnterCriticalSection(&Buff->Header.Console->Lock); 00886 00887 TopLine = rc->top / GuiData->CharHeight + Buff->ShowY; 00888 BottomLine = (rc->bottom + (GuiData->CharHeight - 1)) / GuiData->CharHeight - 1 + Buff->ShowY; 00889 LeftChar = rc->left / GuiData->CharWidth + Buff->ShowX; 00890 RightChar = (rc->right + (GuiData->CharWidth - 1)) / GuiData->CharWidth - 1 + Buff->ShowX; 00891 LastAttribute = ConioCoordToPointer(Buff, LeftChar, TopLine)[1]; 00892 00893 SetTextColor(hDC, GuiConsoleRGBFromAttribute(GuiData, LastAttribute)); 00894 SetBkColor(hDC, GuiConsoleRGBFromAttribute(GuiData, LastAttribute >> 4)); 00895 00896 if (BottomLine >= Buff->MaxY) BottomLine = Buff->MaxY - 1; 00897 if (RightChar >= Buff->MaxX) RightChar = Buff->MaxX - 1; 00898 00899 OldFont = SelectObject(hDC, 00900 GuiData->Font); 00901 00902 for (Line = TopLine; Line <= BottomLine; Line++) 00903 { 00904 WCHAR LineBuffer[80]; 00905 From = ConioCoordToPointer(Buff, LeftChar, Line); 00906 Start = LeftChar; 00907 To = LineBuffer; 00908 00909 for (Char = LeftChar; Char <= RightChar; Char++) 00910 { 00911 if (*(From + 1) != LastAttribute || (Char - Start == sizeof(LineBuffer) / sizeof(WCHAR))) 00912 { 00913 TextOutW(hDC, 00914 (Start - Buff->ShowX) * GuiData->CharWidth, 00915 (Line - Buff->ShowY) * GuiData->CharHeight, 00916 LineBuffer, 00917 Char - Start); 00918 Start = Char; 00919 To = LineBuffer; 00920 Attribute = *(From + 1); 00921 if (Attribute != LastAttribute) 00922 { 00923 SetTextColor(hDC, GuiConsoleRGBFromAttribute(GuiData, Attribute)); 00924 SetBkColor(hDC, GuiConsoleRGBFromAttribute(GuiData, Attribute >> 4)); 00925 LastAttribute = Attribute; 00926 } 00927 } 00928 00929 MultiByteToWideChar(Console->OutputCodePage, 00930 0, 00931 (PCHAR)From, 00932 1, 00933 To, 00934 1); 00935 To++; 00936 From += 2; 00937 } 00938 00939 TextOutW(hDC, 00940 (Start - Buff->ShowX) * GuiData->CharWidth, 00941 (Line - Buff->ShowY) * GuiData->CharHeight, 00942 LineBuffer, 00943 RightChar - Start + 1); 00944 } 00945 00946 if (Buff->CursorInfo.bVisible && GuiData->CursorBlinkOn && 00947 !GuiData->ForceCursorOff) 00948 { 00949 CursorX = Buff->CurrentX; 00950 CursorY = Buff->CurrentY; 00951 if (LeftChar <= CursorX && CursorX <= RightChar && 00952 TopLine <= CursorY && CursorY <= BottomLine) 00953 { 00954 CursorHeight = ConioEffectiveCursorSize(Console, GuiData->CharHeight); 00955 From = ConioCoordToPointer(Buff, Buff->CurrentX, Buff->CurrentY) + 1; 00956 00957 if (*From != DEFAULT_ATTRIB) 00958 { 00959 CursorBrush = CreateSolidBrush(GuiConsoleRGBFromAttribute(GuiData, *From)); 00960 } 00961 else 00962 { 00963 CursorBrush = CreateSolidBrush(GuiData->ScreenText); 00964 } 00965 00966 OldBrush = SelectObject(hDC, 00967 CursorBrush); 00968 PatBlt(hDC, 00969 (CursorX - Buff->ShowX) * GuiData->CharWidth, 00970 (CursorY - Buff->ShowY) * GuiData->CharHeight + (GuiData->CharHeight - CursorHeight), 00971 GuiData->CharWidth, 00972 CursorHeight, 00973 PATCOPY); 00974 SelectObject(hDC, 00975 OldBrush); 00976 DeleteObject(CursorBrush); 00977 } 00978 } 00979 00980 LeaveCriticalSection(&Buff->Header.Console->Lock); 00981 00982 SelectObject(hDC, 00983 OldFont); 00984 } 00985 00986 static VOID 00987 GuiConsoleHandlePaint(HWND hWnd, HDC hDCPaint) 00988 { 00989 HDC hDC; 00990 PAINTSTRUCT ps; 00991 PCSRSS_CONSOLE Console; 00992 PGUI_CONSOLE_DATA GuiData; 00993 00994 hDC = BeginPaint(hWnd, &ps); 00995 if (hDC != NULL && 00996 ps.rcPaint.left < ps.rcPaint.right && 00997 ps.rcPaint.top < ps.rcPaint.bottom) 00998 { 00999 GuiConsoleGetDataPointers(hWnd, 01000 &Console, 01001 &GuiData); 01002 if (Console != NULL && GuiData != NULL && 01003 Console->ActiveBuffer != NULL) 01004 { 01005 if (Console->ActiveBuffer->Buffer != NULL) 01006 { 01007 EnterCriticalSection(&GuiData->Lock); 01008 01009 GuiConsolePaint(Console, 01010 GuiData, 01011 hDC, 01012 &ps.rcPaint); 01013 01014 if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) 01015 { 01016 RECT rc; 01017 SmallRectToRect(Console, &rc, &Console->Selection.srSelection); 01018 01019 /* invert the selection */ 01020 if (IntersectRect(&rc, 01021 &ps.rcPaint, 01022 &rc)) 01023 { 01024 PatBlt(hDC, 01025 rc.left, 01026 rc.top, 01027 rc.right - rc.left, 01028 rc.bottom - rc.top, 01029 DSTINVERT); 01030 } 01031 } 01032 01033 LeaveCriticalSection(&GuiData->Lock); 01034 } 01035 } 01036 01037 } 01038 EndPaint(hWnd, &ps); 01039 } 01040 01041 static VOID 01042 GuiConsoleHandleKey(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 01043 { 01044 PCSRSS_CONSOLE Console; 01045 PGUI_CONSOLE_DATA GuiData; 01046 MSG Message; 01047 01048 GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); 01049 Message.hwnd = hWnd; 01050 Message.message = msg; 01051 Message.wParam = wParam; 01052 Message.lParam = lParam; 01053 01054 if(msg == WM_CHAR || msg == WM_SYSKEYDOWN) 01055 { 01056 /* clear the selection */ 01057 GuiConsoleUpdateSelection(Console, NULL); 01058 } 01059 01060 ConioProcessKey(&Message, Console, FALSE); 01061 } 01062 01063 static VOID WINAPI 01064 GuiDrawRegion(PCSRSS_CONSOLE Console, SMALL_RECT *Region) 01065 { 01066 RECT RegionRect; 01067 SmallRectToRect(Console, &RegionRect, Region); 01068 InvalidateRect(Console->hWindow, &RegionRect, FALSE); 01069 } 01070 01071 static VOID 01072 GuiInvalidateCell(PCSRSS_CONSOLE Console, UINT x, UINT y) 01073 { 01074 SMALL_RECT CellRect = { x, y, x, y }; 01075 GuiDrawRegion(Console, &CellRect); 01076 } 01077 01078 static VOID WINAPI 01079 GuiWriteStream(PCSRSS_CONSOLE Console, SMALL_RECT *Region, LONG CursorStartX, LONG CursorStartY, 01080 UINT ScrolledLines, CHAR *Buffer, UINT Length) 01081 { 01082 PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData; 01083 PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer; 01084 LONG CursorEndX, CursorEndY; 01085 RECT ScrollRect; 01086 01087 if (NULL == Console->hWindow || NULL == GuiData) 01088 { 01089 return; 01090 } 01091 01092 if (0 != ScrolledLines) 01093 { 01094 ScrollRect.left = 0; 01095 ScrollRect.top = 0; 01096 ScrollRect.right = Console->Size.X * GuiData->CharWidth; 01097 ScrollRect.bottom = Region->Top * GuiData->CharHeight; 01098 01099 ScrollWindowEx(Console->hWindow, 01100 0, 01101 -(ScrolledLines * GuiData->CharHeight), 01102 &ScrollRect, 01103 NULL, 01104 NULL, 01105 NULL, 01106 SW_INVALIDATE); 01107 } 01108 01109 GuiDrawRegion(Console, Region); 01110 01111 if (CursorStartX < Region->Left || Region->Right < CursorStartX 01112 || CursorStartY < Region->Top || Region->Bottom < CursorStartY) 01113 { 01114 GuiInvalidateCell(Console, CursorStartX, CursorStartY); 01115 } 01116 01117 CursorEndX = Buff->CurrentX; 01118 CursorEndY = Buff->CurrentY; 01119 if ((CursorEndX < Region->Left || Region->Right < CursorEndX 01120 || CursorEndY < Region->Top || Region->Bottom < CursorEndY) 01121 && (CursorEndX != CursorStartX || CursorEndY != CursorStartY)) 01122 { 01123 GuiInvalidateCell(Console, CursorEndX, CursorEndY); 01124 } 01125 01126 // Set up the update timer (very short interval) - this is a "hack" for getting the OS to 01127 // repaint the window without having it just freeze up and stay on the screen permanently. 01128 GuiData->CursorBlinkOn = TRUE; 01129 SetTimer(Console->hWindow, CONGUI_UPDATE_TIMER, CONGUI_UPDATE_TIME, NULL); 01130 } 01131 01132 static BOOL WINAPI 01133 GuiSetCursorInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff) 01134 { 01135 if (Console->ActiveBuffer == Buff) 01136 { 01137 GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY); 01138 } 01139 01140 return TRUE; 01141 } 01142 01143 static BOOL WINAPI 01144 GuiSetScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff, UINT OldCursorX, UINT OldCursorY) 01145 { 01146 if (Console->ActiveBuffer == Buff) 01147 { 01148 /* Redraw char at old position (removes cursor) */ 01149 GuiInvalidateCell(Console, OldCursorX, OldCursorY); 01150 /* Redraw char at new position (shows cursor) */ 01151 GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY); 01152 } 01153 01154 return TRUE; 01155 } 01156 01157 static BOOL WINAPI 01158 GuiUpdateScreenInfo(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buff) 01159 { 01160 PGUI_CONSOLE_DATA GuiData = (PGUI_CONSOLE_DATA) Console->PrivateData; 01161 01162 if (Console->ActiveBuffer == Buff) 01163 { 01164 GuiData->ScreenText = GuiConsoleRGBFromAttribute(GuiData, Buff->DefaultAttrib); 01165 GuiData->ScreenBackground = GuiConsoleRGBFromAttribute(GuiData, Buff->DefaultAttrib >> 4); 01166 } 01167 01168 return TRUE; 01169 } 01170 01171 static VOID 01172 GuiConsoleHandleTimer(HWND hWnd) 01173 { 01174 PCSRSS_CONSOLE Console; 01175 PGUI_CONSOLE_DATA GuiData; 01176 PCSRSS_SCREEN_BUFFER Buff; 01177 01178 SetTimer(hWnd, CONGUI_UPDATE_TIMER, CURSOR_BLINK_TIME, NULL); 01179 01180 GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); 01181 01182 Buff = Console->ActiveBuffer; 01183 GuiInvalidateCell(Console, Buff->CurrentX, Buff->CurrentY); 01184 GuiData->CursorBlinkOn = ! GuiData->CursorBlinkOn; 01185 01186 if((GuiData->OldCursor.x != Buff->CurrentX) || (GuiData->OldCursor.y != Buff->CurrentY)) 01187 { 01188 SCROLLINFO xScroll; 01189 int OldScrollX = -1, OldScrollY = -1; 01190 int NewScrollX = -1, NewScrollY = -1; 01191 01192 xScroll.cbSize = sizeof(SCROLLINFO); 01193 xScroll.fMask = SIF_POS; 01194 // Capture the original position of the scroll bars and save them. 01195 if(GetScrollInfo(hWnd, SB_HORZ, &xScroll))OldScrollX = xScroll.nPos; 01196 if(GetScrollInfo(hWnd, SB_VERT, &xScroll))OldScrollY = xScroll.nPos; 01197 01198 // If we successfully got the info for the horizontal scrollbar 01199 if(OldScrollX >= 0) 01200 { 01201 if((Buff->CurrentX < Buff->ShowX)||(Buff->CurrentX >= (Buff->ShowX + Console->Size.X))) 01202 { 01203 // Handle the horizontal scroll bar 01204 if(Buff->CurrentX >= Console->Size.X) NewScrollX = Buff->CurrentX - Console->Size.X + 1; 01205 else NewScrollX = 0; 01206 } 01207 else 01208 { 01209 NewScrollX = OldScrollX; 01210 } 01211 } 01212 // If we successfully got the info for the vertical scrollbar 01213 if(OldScrollY >= 0) 01214 { 01215 if((Buff->CurrentY < Buff->ShowY) || (Buff->CurrentY >= (Buff->ShowY + Console->Size.Y))) 01216 { 01217 // Handle the vertical scroll bar 01218 if(Buff->CurrentY >= Console->Size.Y) NewScrollY = Buff->CurrentY - Console->Size.Y + 1; 01219 else NewScrollY = 0; 01220 } 01221 else 01222 { 01223 NewScrollY = OldScrollY; 01224 } 01225 } 01226 01227 // Adjust scroll bars and refresh the window if the cursor has moved outside the visible area 01228 // NOTE: OldScroll# and NewScroll# will both be -1 (initial value) if the info for the respective scrollbar 01229 // was not obtained successfully in the previous steps. This means their difference is 0 (no scrolling) 01230 // and their associated scrollbar is left alone. 01231 if((OldScrollX != NewScrollX) || (OldScrollY != NewScrollY)) 01232 { 01233 Buff->ShowX = NewScrollX; 01234 Buff->ShowY = NewScrollY; 01235 ScrollWindowEx(hWnd, 01236 (OldScrollX - NewScrollX) * GuiData->CharWidth, 01237 (OldScrollY - NewScrollY) * GuiData->CharHeight, 01238 NULL, 01239 NULL, 01240 NULL, 01241 NULL, 01242 SW_INVALIDATE); 01243 if(NewScrollX >= 0) 01244 { 01245 xScroll.nPos = NewScrollX; 01246 SetScrollInfo(hWnd, SB_HORZ, &xScroll, TRUE); 01247 } 01248 if(NewScrollY >= 0) 01249 { 01250 xScroll.nPos = NewScrollY; 01251 SetScrollInfo(hWnd, SB_VERT, &xScroll, TRUE); 01252 } 01253 UpdateWindow(hWnd); 01254 GuiData->OldCursor.x = Buff->CurrentX; 01255 GuiData->OldCursor.y = Buff->CurrentY; 01256 } 01257 } 01258 } 01259 01260 static VOID 01261 GuiConsoleHandleClose(HWND hWnd) 01262 { 01263 PCSRSS_CONSOLE Console; 01264 PGUI_CONSOLE_DATA GuiData; 01265 PLIST_ENTRY current_entry; 01266 PCSR_PROCESS current; 01267 01268 GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); 01269 01270 EnterCriticalSection(&Console->Lock); 01271 01272 current_entry = Console->ProcessList.Flink; 01273 while (current_entry != &Console->ProcessList) 01274 { 01275 current = CONTAINING_RECORD(current_entry, CSR_PROCESS, ConsoleLink); 01276 current_entry = current_entry->Flink; 01277 01278 /* FIXME: Windows will wait up to 5 seconds for the thread to exit. 01279 * We shouldn't wait here, though, since the console lock is entered. 01280 * A copy of the thread list probably needs to be made. */ 01281 ConioConsoleCtrlEvent(CTRL_CLOSE_EVENT, current); 01282 } 01283 01284 LeaveCriticalSection(&Console->Lock); 01285 } 01286 01287 static VOID 01288 GuiConsoleHandleNcDestroy(HWND hWnd) 01289 { 01290 PCSRSS_CONSOLE Console; 01291 PGUI_CONSOLE_DATA GuiData; 01292 01293 01294 GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); 01295 KillTimer(hWnd, 1); 01296 Console->PrivateData = NULL; 01297 DeleteCriticalSection(&GuiData->Lock); 01298 GetSystemMenu(hWnd, TRUE); 01299 if (GuiData->ConsoleLibrary) 01300 FreeLibrary(GuiData->ConsoleLibrary); 01301 01302 HeapFree(Win32CsrApiHeap, 0, GuiData); 01303 } 01304 01305 static COORD 01306 PointToCoord(PCSRSS_CONSOLE Console, LPARAM lParam) 01307 { 01308 PCSRSS_SCREEN_BUFFER Buffer = Console->ActiveBuffer; 01309 PGUI_CONSOLE_DATA GuiData = Console->PrivateData; 01310 COORD Coord; 01311 Coord.X = Buffer->ShowX + ((short)LOWORD(lParam) / (int)GuiData->CharWidth); 01312 Coord.Y = Buffer->ShowY + ((short)HIWORD(lParam) / (int)GuiData->CharHeight); 01313 01314 /* Clip coordinate to ensure it's inside buffer */ 01315 if (Coord.X < 0) Coord.X = 0; 01316 else if (Coord.X >= Buffer->MaxX) Coord.X = Buffer->MaxX - 1; 01317 if (Coord.Y < 0) Coord.Y = 0; 01318 else if (Coord.Y >= Buffer->MaxY) Coord.Y = Buffer->MaxY - 1; 01319 return Coord; 01320 } 01321 01322 static VOID 01323 GuiConsoleLeftMouseDown(HWND hWnd, LPARAM lParam) 01324 { 01325 PCSRSS_CONSOLE Console; 01326 PGUI_CONSOLE_DATA GuiData; 01327 01328 GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); 01329 if (Console == NULL || GuiData == NULL) return; 01330 01331 Console->Selection.dwSelectionAnchor = PointToCoord(Console, lParam); 01332 01333 SetCapture(hWnd); 01334 01335 Console->Selection.dwFlags |= CONSOLE_SELECTION_IN_PROGRESS | CONSOLE_MOUSE_SELECTION | CONSOLE_MOUSE_DOWN; 01336 01337 GuiConsoleUpdateSelection(Console, &Console->Selection.dwSelectionAnchor); 01338 } 01339 01340 static VOID 01341 GuiConsoleLeftMouseUp(HWND hWnd, LPARAM lParam) 01342 { 01343 PCSRSS_CONSOLE Console; 01344 PGUI_CONSOLE_DATA GuiData; 01345 COORD c; 01346 01347 GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); 01348 if (Console == NULL || GuiData == NULL) return; 01349 if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) return; 01350 01351 c = PointToCoord(Console, lParam); 01352 01353 Console->Selection.dwFlags &= ~CONSOLE_MOUSE_DOWN; 01354 01355 GuiConsoleUpdateSelection(Console, &c); 01356 01357 ReleaseCapture(); 01358 } 01359 01360 static VOID 01361 GuiConsoleMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam) 01362 { 01363 PCSRSS_CONSOLE Console; 01364 PGUI_CONSOLE_DATA GuiData; 01365 COORD c; 01366 01367 if (!(wParam & MK_LBUTTON)) return; 01368 01369 GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); 01370 if (Console == NULL || GuiData == NULL) return; 01371 if (!(Console->Selection.dwFlags & CONSOLE_MOUSE_DOWN)) return; 01372 01373 c = PointToCoord(Console, lParam); /* TODO: Scroll buffer to bring c into view */ 01374 01375 GuiConsoleUpdateSelection(Console, &c); 01376 } 01377 01378 static VOID 01379 GuiConsoleCopy(HWND hWnd, PCSRSS_CONSOLE Console) 01380 { 01381 if (OpenClipboard(hWnd) == TRUE) 01382 { 01383 HANDLE hData; 01384 PBYTE ptr; 01385 LPSTR data, dstPos; 01386 ULONG selWidth, selHeight; 01387 ULONG xPos, yPos, size; 01388 01389 selWidth = Console->Selection.srSelection.Right - Console->Selection.srSelection.Left + 1; 01390 selHeight = Console->Selection.srSelection.Bottom - Console->Selection.srSelection.Top + 1; 01391 DPRINT("Selection is (%d|%d) to (%d|%d)\n", 01392 Console->Selection.srSelection.Left, 01393 Console->Selection.srSelection.Top, 01394 Console->Selection.srSelection.Right, 01395 Console->Selection.srSelection.Bottom); 01396 01397 /* Basic size for one line and termination */ 01398 size = selWidth + 1; 01399 if (selHeight > 0) 01400 { 01401 /* Multiple line selections have to get \r\n appended */ 01402 size += ((selWidth + 2) * (selHeight - 1)); 01403 } 01404 01405 /* Allocate memory, it will be passed to the system and may not be freed here */ 01406 hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, size); 01407 if (hData == NULL) 01408 { 01409 CloseClipboard(); 01410 return; 01411 } 01412 data = GlobalLock(hData); 01413 if (data == NULL) 01414 { 01415 CloseClipboard(); 01416 return; 01417 } 01418 01419 DPRINT("Copying %dx%d selection\n", selWidth, selHeight); 01420 dstPos = data; 01421 01422 for (yPos = 0; yPos < selHeight; yPos++) 01423 { 01424 ptr = ConioCoordToPointer(Console->ActiveBuffer, 01425 Console->Selection.srSelection.Left, 01426 yPos + Console->Selection.srSelection.Top); 01427 /* Copy only the characters, leave attributes alone */ 01428 for (xPos = 0; xPos < selWidth; xPos++) 01429 { 01430 dstPos[xPos] = ptr[xPos * 2]; 01431 } 01432 dstPos += selWidth; 01433 if (yPos != (selHeight - 1)) 01434 { 01435 strcat(data, "\r\n"); 01436 dstPos += 2; 01437 } 01438 } 01439 01440 DPRINT("Setting data <%s> to clipboard\n", data); 01441 GlobalUnlock(hData); 01442 01443 EmptyClipboard(); 01444 SetClipboardData(CF_TEXT, hData); 01445 CloseClipboard(); 01446 } 01447 } 01448 01449 static VOID 01450 GuiConsolePaste(HWND hWnd, PCSRSS_CONSOLE Console) 01451 { 01452 if (OpenClipboard(hWnd) == TRUE) 01453 { 01454 HANDLE hData; 01455 LPSTR str; 01456 size_t len; 01457 01458 hData = GetClipboardData(CF_TEXT); 01459 if (hData == NULL) 01460 { 01461 CloseClipboard(); 01462 return; 01463 } 01464 01465 str = GlobalLock(hData); 01466 if (str == NULL) 01467 { 01468 CloseClipboard(); 01469 return; 01470 } 01471 DPRINT("Got data <%s> from clipboard\n", str); 01472 len = strlen(str); 01473 01474 ConioWriteConsole(Console, Console->ActiveBuffer, str, len, TRUE); 01475 01476 GlobalUnlock(hData); 01477 CloseClipboard(); 01478 } 01479 } 01480 01481 static VOID 01482 GuiConsoleRightMouseDown(HWND hWnd) 01483 { 01484 PCSRSS_CONSOLE Console; 01485 PGUI_CONSOLE_DATA GuiData; 01486 01487 GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); 01488 if (Console == NULL || GuiData == NULL) return; 01489 01490 if (!(Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY)) 01491 { 01492 GuiConsolePaste(hWnd, Console); 01493 } 01494 else 01495 { 01496 GuiConsoleCopy(hWnd, Console); 01497 01498 /* Clear the selection */ 01499 GuiConsoleUpdateSelection(Console, NULL); 01500 } 01501 01502 } 01503 01504 01505 static VOID 01506 GuiConsoleShowConsoleProperties(HWND hWnd, BOOL Defaults, PGUI_CONSOLE_DATA GuiData) 01507 { 01508 PCSRSS_CONSOLE Console; 01509 APPLET_PROC CPLFunc; 01510 TCHAR szBuffer[MAX_PATH]; 01511 ConsoleInfo SharedInfo; 01512 01513 DPRINT("GuiConsoleShowConsoleProperties entered\n"); 01514 01515 GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); 01516 01517 if (GuiData == NULL) 01518 { 01519 DPRINT("GuiConsoleGetDataPointers failed\n"); 01520 return; 01521 } 01522 01523 if (GuiData->ConsoleLibrary == NULL) 01524 { 01525 GetWindowsDirectory(szBuffer,MAX_PATH); 01526 _tcscat(szBuffer, _T("\\system32\\console.dll")); 01527 GuiData->ConsoleLibrary = LoadLibrary(szBuffer); 01528 01529 if (GuiData->ConsoleLibrary == NULL) 01530 { 01531 DPRINT1("failed to load console.dll"); 01532 return; 01533 } 01534 } 01535 01536 CPLFunc = (APPLET_PROC) GetProcAddress(GuiData->ConsoleLibrary, _T("CPlApplet")); 01537 if (!CPLFunc) 01538 { 01539 DPRINT("Error: Console.dll misses CPlApplet export\n"); 01540 return; 01541 } 01542 01543 /* setup struct */ 01544 SharedInfo.InsertMode = GuiData->InsertMode; 01545 SharedInfo.HistoryBufferSize = Console->HistoryBufferSize; 01546 SharedInfo.NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers; 01547 SharedInfo.ScreenText = GuiData->ScreenText; 01548 SharedInfo.ScreenBackground = GuiData->ScreenBackground; 01549 SharedInfo.PopupText = GuiData->PopupText; 01550 SharedInfo.PopupBackground = GuiData->PopupBackground; 01551 SharedInfo.WindowSize = (DWORD)MAKELONG(Console->Size.X, Console->Size.Y); 01552 SharedInfo.WindowPosition = GuiData->WindowPosition; 01553 SharedInfo.ScreenBuffer = (DWORD)MAKELONG(Console->ActiveBuffer->MaxX, Console->ActiveBuffer->MaxY); 01554 SharedInfo.UseRasterFonts = GuiData->UseRasterFonts; 01555 SharedInfo.FontSize = (DWORD)GuiData->FontSize; 01556 SharedInfo.FontWeight = GuiData->FontWeight; 01557 SharedInfo.CursorSize = Console->ActiveBuffer->CursorInfo.dwSize; 01558 SharedInfo.HistoryNoDup = Console->HistoryNoDup; 01559 SharedInfo.FullScreen = GuiData->FullScreen; 01560 SharedInfo.QuickEdit = GuiData->QuickEdit; 01561 memcpy(&SharedInfo.Colors[0], GuiData->Colors, sizeof(s_Colors)); 01562 01563 if (!CPLFunc(hWnd, CPL_INIT, 0, 0)) 01564 { 01565 DPRINT("Error: failed to initialize console.dll\n"); 01566 return; 01567 } 01568 01569 if (CPLFunc(hWnd, CPL_GETCOUNT, 0, 0) != 1) 01570 { 01571 DPRINT("Error: console.dll returned unexpected CPL count\n"); 01572 return; 01573 } 01574 01575 CPLFunc(hWnd, CPL_DBLCLK, (LPARAM)&SharedInfo, Defaults); 01576 } 01577 static LRESULT 01578 GuiConsoleHandleSysMenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) 01579 { 01580 LRESULT Ret = TRUE; 01581 PCSRSS_CONSOLE Console; 01582 PGUI_CONSOLE_DATA GuiData; 01583 COORD bottomRight = { 0, 0 }; 01584 01585 GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); 01586 01587 switch(wParam) 01588 { 01589 case ID_SYSTEM_EDIT_MARK: 01590 DPRINT1("Marking not handled yet\n"); 01591 break; 01592 01593 case ID_SYSTEM_EDIT_COPY: 01594 GuiConsoleCopy(hWnd, Console); 01595 break; 01596 01597 case ID_SYSTEM_EDIT_PASTE: 01598 GuiConsolePaste(hWnd, Console); 01599 break; 01600 01601 case ID_SYSTEM_EDIT_SELECTALL: 01602 bottomRight.X = Console->Size.X - 1; 01603 bottomRight.Y = Console->Size.Y - 1; 01604 GuiConsoleUpdateSelection(Console, &bottomRight); 01605 break; 01606 01607 case ID_SYSTEM_EDIT_SCROLL: 01608 DPRINT1("Scrolling is not handled yet\n"); 01609 break; 01610 01611 case ID_SYSTEM_EDIT_FIND: 01612 DPRINT1("Finding is not handled yet\n"); 01613 break; 01614 01615 case ID_SYSTEM_DEFAULTS: 01616 GuiConsoleShowConsoleProperties(hWnd, TRUE, GuiData); 01617 break; 01618 01619 case ID_SYSTEM_PROPERTIES: 01620 GuiConsoleShowConsoleProperties(hWnd, FALSE, GuiData); 01621 break; 01622 01623 default: 01624 Ret = DefWindowProcW(hWnd, WM_SYSCOMMAND, wParam, lParam); 01625 break; 01626 } 01627 return Ret; 01628 } 01629 01630 static VOID 01631 GuiConsoleGetMinMaxInfo(HWND hWnd, PMINMAXINFO minMaxInfo) 01632 { 01633 PCSRSS_CONSOLE Console; 01634 PGUI_CONSOLE_DATA GuiData; 01635 DWORD windx, windy; 01636 01637 GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); 01638 if((Console == NULL)|| (GuiData == NULL)) return; 01639 01640 windx = CONGUI_MIN_WIDTH * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE)); 01641 windy = CONGUI_MIN_HEIGHT * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION); 01642 01643 minMaxInfo->ptMinTrackSize.x = windx; 01644 minMaxInfo->ptMinTrackSize.y = windy; 01645 01646 windx = (Console->ActiveBuffer->MaxX) * GuiData->CharWidth + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE)); 01647 windy = (Console->ActiveBuffer->MaxY) * GuiData->CharHeight + 2 * (GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYEDGE)) + GetSystemMetrics(SM_CYCAPTION); 01648 01649 if(Console->Size.X < Console->ActiveBuffer->MaxX) windy += GetSystemMetrics(SM_CYHSCROLL); // window currently has a horizontal scrollbar 01650 if(Console->Size.Y < Console->ActiveBuffer->MaxY) windx += GetSystemMetrics(SM_CXVSCROLL); // window currently has a vertical scrollbar 01651 01652 minMaxInfo->ptMaxTrackSize.x = windx; 01653 minMaxInfo->ptMaxTrackSize.y = windy; 01654 } 01655 static VOID 01656 GuiConsoleResize(HWND hWnd, WPARAM wParam, LPARAM lParam) 01657 { 01658 PCSRSS_CONSOLE Console; 01659 PGUI_CONSOLE_DATA GuiData; 01660 GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); 01661 if((Console == NULL) || (GuiData == NULL)) return; 01662 01663 if ((GuiData->WindowSizeLock == FALSE) && (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED)) 01664 { 01665 PCSRSS_SCREEN_BUFFER Buff = Console->ActiveBuffer; 01666 DWORD windx, windy, charx, chary; 01667 01668 GuiData->WindowSizeLock = TRUE; 01669 01670 windx = LOWORD(lParam); 01671 windy = HIWORD(lParam); 01672 01673 // Compensate for existing scroll bars (because lParam values do not accommodate scroll bar) 01674 if(Console->Size.X < Buff->MaxX) windy += GetSystemMetrics(SM_CYHSCROLL); // window currently has a horizontal scrollbar 01675 if(Console->Size.Y < Buff->MaxY) windx += GetSystemMetrics(SM_CXVSCROLL); // window currently has a vertical scrollbar 01676 01677 charx = windx / GuiData->CharWidth; 01678 chary = windy / GuiData->CharHeight; 01679 01680 // Character alignment (round size up or down) 01681 if((windx % GuiData->CharWidth) >= (GuiData->CharWidth / 2)) ++charx; 01682 if((windy % GuiData->CharHeight) >= (GuiData->CharHeight / 2)) ++chary; 01683 01684 // Compensate for added scroll bars in new window 01685 if(charx < Buff->MaxX)windy -= GetSystemMetrics(SM_CYHSCROLL); // new window will have a horizontal scroll bar 01686 if(chary < Buff->MaxY)windx -= GetSystemMetrics(SM_CXVSCROLL); // new window will have a vertical scroll bar 01687 01688 charx = windx / GuiData->CharWidth; 01689 chary = windy / GuiData->CharHeight; 01690 01691 // Character alignment (round size up or down) 01692 if((windx % GuiData->CharWidth) >= (GuiData->CharWidth / 2)) ++charx; 01693 if((windy % GuiData->CharHeight) >= (GuiData->CharHeight / 2)) ++chary; 01694 01695 // Resize window 01696 if((charx != Console->Size.X) || (chary != Console->Size.Y)) 01697 { 01698 Console->Size.X = (charx <= Buff->MaxX) ? charx : Buff->MaxX; 01699 Console->Size.Y = (chary <= Buff->MaxY) ? chary : Buff->MaxY; 01700 } 01701 01702 GuiConsoleInitScrollbar(Console, hWnd); 01703 01704 // Adjust the start of the visible area if we are attempting to show nonexistent areas 01705 if((Buff->MaxX - Buff->ShowX) < Console->Size.X) Buff->ShowX = Buff->MaxX - Console->Size.X; 01706 if((Buff->MaxY - Buff->ShowY) < Console->Size.Y) Buff->ShowY = Buff->MaxY - Console->Size.Y; 01707 InvalidateRect(hWnd, NULL, TRUE); 01708 01709 GuiData->WindowSizeLock = FALSE; 01710 } 01711 } 01712 01713 VOID 01714 FASTCALL 01715 GuiConsoleHandleScrollbarMenu() 01716 { 01717 HMENU hMenu; 01718 01719 hMenu = CreatePopupMenu(); 01720 if (hMenu == NULL) 01721 { 01722 DPRINT("CreatePopupMenu failed\n"); 01723 return; 01724 } 01725 //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLHERE); 01726 //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1); 01727 //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLTOP); 01728 //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLBOTTOM); 01729 //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1); 01730 //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_UP); 01731 //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLPAGE_DOWN); 01732 //InsertItem(hMenu, MFT_SEPARATOR, MIIM_FTYPE, 0, NULL, -1); 01733 //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLUP); 01734 //InsertItem(hMenu, MIIM_STRING, MIIM_ID | MIIM_FTYPE | MIIM_STRING, 0, NULL, IDS_SCROLLDOWN); 01735 01736 } 01737 01738 static NTSTATUS WINAPI 01739 GuiResizeBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER ScreenBuffer, COORD Size) 01740 { 01741 BYTE * Buffer; 01742 DWORD Offset = 0; 01743 BYTE * OldPtr; 01744 USHORT CurrentY; 01745 BYTE * OldBuffer; 01746 #if HAVE_WMEMSET 01747 USHORT value = MAKEWORD(' ', ScreenBuffer->DefaultAttrib); 01748 #endif 01749 DWORD diff; 01750 DWORD i; 01751 01752 /* Buffer size is not allowed to be smaller than window size */ 01753 if (Size.X < Console->Size.X || Size.Y < Console->Size.Y) 01754 return STATUS_INVALID_PARAMETER; 01755 01756 if (Size.X == ScreenBuffer->MaxX && Size.Y == ScreenBuffer->MaxY) 01757 return STATUS_SUCCESS; 01758 01759 Buffer = HeapAlloc(Win32CsrApiHeap, 0, Size.X * Size.Y * 2); 01760 if (!Buffer) 01761 return STATUS_NO_MEMORY; 01762 01763 DPRINT1("Resizing (%d,%d) to (%d,%d)\n", ScreenBuffer->MaxX, ScreenBuffer->MaxY, Size.X, Size.Y); 01764 OldBuffer = ScreenBuffer->Buffer; 01765 01766 for (CurrentY = 0; CurrentY < ScreenBuffer->MaxY && CurrentY < Size.Y; CurrentY++) 01767 { 01768 OldPtr = ConioCoordToPointer(ScreenBuffer, 0, CurrentY); 01769 if (Size.X <= ScreenBuffer->MaxX) 01770 { 01771 /* reduce size */ 01772 RtlCopyMemory(&Buffer[Offset], OldPtr, Size.X * 2); 01773 Offset += (Size.X * 2); 01774 } 01775 else 01776 { 01777 /* enlarge size */ 01778 RtlCopyMemory(&Buffer[Offset], OldPtr, ScreenBuffer->MaxX * 2); 01779 Offset += (ScreenBuffer->MaxX * 2); 01780 01781 diff = Size.X - ScreenBuffer->MaxX; 01782 /* zero new part of it */ 01783 #if HAVE_WMEMSET 01784 wmemset((WCHAR*)&Buffer[Offset], value, diff); 01785 #else 01786 for (i = 0; i < diff; i++) 01787 { 01788 Buffer[Offset++] = ' '; 01789 Buffer[Offset++] = ScreenBuffer->DefaultAttrib; 01790 } 01791 #endif 01792 } 01793 } 01794 01795 if (Size.Y > ScreenBuffer->MaxY) 01796 { 01797 diff = Size.X * (Size.Y - ScreenBuffer->MaxY); 01798 #if HAVE_WMEMSET 01799 wmemset((WCHAR*)&Buffer[Offset], value, diff); 01800 #else 01801 for (i = 0; i < diff; i++) 01802 { 01803 Buffer[Offset++] = ' '; 01804 Buffer[Offset++] = ScreenBuffer->DefaultAttrib; 01805 } 01806 #endif 01807 } 01808 01809 (void)InterlockedExchangePointer((PVOID volatile *)&ScreenBuffer->Buffer, Buffer); 01810 HeapFree(Win32CsrApiHeap, 0, OldBuffer); 01811 ScreenBuffer->MaxX = Size.X; 01812 ScreenBuffer->MaxY = Size.Y; 01813 ScreenBuffer->VirtualY = 0; 01814 01815 /* Ensure cursor and window are within buffer */ 01816 if (ScreenBuffer->CurrentX >= Size.X) 01817 ScreenBuffer->CurrentX = Size.X - 1; 01818 if (ScreenBuffer->CurrentY >= Size.Y) 01819 ScreenBuffer->CurrentY = Size.Y - 1; 01820 if (ScreenBuffer->ShowX > Size.X - Console->Size.X) 01821 ScreenBuffer->ShowX = Size.X - Console->Size.X; 01822 if (ScreenBuffer->ShowY > Size.Y - Console->Size.Y) 01823 ScreenBuffer->ShowY = Size.Y - Console->Size.Y; 01824 01825 /* TODO: Should update scrollbar, but can't use anything that 01826 * calls SendMessage or it could cause deadlock */ 01827 01828 return STATUS_SUCCESS; 01829 } 01830 01831 static VOID 01832 GuiApplyUserSettings(PCSRSS_CONSOLE Console, PGUI_CONSOLE_DATA GuiData, PConsoleInfo pConInfo) 01833 { 01834 DWORD windx, windy; 01835 PCSRSS_SCREEN_BUFFER ActiveBuffer = Console->ActiveBuffer; 01836 COORD BufSize; 01837 BOOL SizeChanged = FALSE; 01838 01839 EnterCriticalSection(&Console->Lock); 01840 01841 /* apply text / background color */ 01842 GuiData->ScreenText = pConInfo->ScreenText; 01843 GuiData->ScreenBackground = pConInfo->ScreenBackground; 01844 01845 /* apply cursor size */ 01846 ActiveBuffer->CursorInfo.dwSize = min(max(pConInfo->CursorSize, 1), 100); 01847 01848 windx = LOWORD(pConInfo->WindowSize); 01849 windy = HIWORD(pConInfo->WindowSize); 01850 01851 if (windx != Console->Size.X || windy != Console->Size.Y) 01852 { 01853 /* resize window */ 01854 Console->Size.X = windx; 01855 Console->Size.Y = windy; 01856 SizeChanged = TRUE; 01857 } 01858 01859 BufSize.X = LOWORD(pConInfo->ScreenBuffer); 01860 BufSize.Y = HIWORD(pConInfo->ScreenBuffer); 01861 if (BufSize.X != ActiveBuffer->MaxX || BufSize.Y != ActiveBuffer->MaxY) 01862 { 01863 if (NT_SUCCESS(GuiResizeBuffer(Console, ActiveBuffer, BufSize))) 01864 SizeChanged = TRUE; 01865 } 01866 01867 if (SizeChanged) 01868 { 01869 GuiData->WindowSizeLock = TRUE; 01870 GuiConsoleInitScrollbar(Console, pConInfo->hConsoleWindow); 01871 GuiData->WindowSizeLock = FALSE; 01872 } 01873 01874 LeaveCriticalSection(&Console->Lock); 01875 InvalidateRect(pConInfo->hConsoleWindow, NULL, TRUE); 01876 } 01877 01878 static 01879 LRESULT 01880 GuiConsoleHandleScroll(HWND hwnd, UINT uMsg, WPARAM wParam) 01881 { 01882 PCSRSS_CONSOLE Console; 01883 PCSRSS_SCREEN_BUFFER Buff; 01884 PGUI_CONSOLE_DATA GuiData; 01885 SCROLLINFO sInfo; 01886 int fnBar; 01887 int old_pos, Maximum; 01888 PUSHORT pShowXY; 01889 01890 GuiConsoleGetDataPointers(hwnd, &Console, &GuiData); 01891 if (Console == NULL || GuiData == NULL) 01892 return FALSE; 01893 Buff = Console->ActiveBuffer; 01894 01895 if (uMsg == WM_HSCROLL) 01896 { 01897 fnBar = SB_HORZ; 01898 Maximum = Buff->MaxX - Console->Size.X; 01899 pShowXY = &Buff->ShowX; 01900 } 01901 else 01902 { 01903 fnBar = SB_VERT; 01904 Maximum = Buff->MaxY - Console->Size.Y; 01905 pShowXY = &Buff->ShowY; 01906 } 01907 01908 /* set scrollbar sizes */ 01909 sInfo.cbSize = sizeof(SCROLLINFO); 01910 sInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE | SIF_TRACKPOS; 01911 01912 if (!GetScrollInfo(hwnd, fnBar, &sInfo)) 01913 { 01914 return FALSE; 01915 } 01916 01917 old_pos = sInfo.nPos; 01918 01919 switch(LOWORD(wParam)) 01920 { 01921 case SB_LINELEFT: 01922 sInfo.nPos -= 1; 01923 break; 01924 01925 case SB_LINERIGHT: 01926 sInfo.nPos += 1; 01927 break; 01928 01929 case SB_PAGELEFT: 01930 sInfo.nPos -= sInfo.nPage; 01931 break; 01932 01933 case SB_PAGERIGHT: 01934 sInfo.nPos += sInfo.nPage; 01935 break; 01936 01937 case SB_THUMBTRACK: 01938 sInfo.nPos = sInfo.nTrackPos; 01939 ConioPause(Console, PAUSED_FROM_SCROLLBAR); 01940 break; 01941 01942 case SB_THUMBPOSITION: 01943 ConioUnpause(Console, PAUSED_FROM_SCROLLBAR); 01944 break; 01945 01946 case SB_TOP: 01947 sInfo.nPos = sInfo.nMin; 01948 break; 01949 01950 case SB_BOTTOM: 01951 sInfo.nPos = sInfo.nMax; 01952 break; 01953 01954 default: 01955 break; 01956 } 01957 01958 sInfo.nPos = max(sInfo.nPos, 0); 01959 sInfo.nPos = min(sInfo.nPos, Maximum); 01960 01961 if (old_pos != sInfo.nPos) 01962 { 01963 USHORT OldX = Buff->ShowX; 01964 USHORT OldY = Buff->ShowY; 01965 *pShowXY = sInfo.nPos; 01966 01967 ScrollWindowEx(hwnd, 01968 (OldX - Buff->ShowX) * GuiData->CharWidth, 01969 (OldY - Buff->ShowY) * GuiData->CharHeight, 01970 NULL, 01971 NULL, 01972 NULL, 01973 NULL, 01974 SW_INVALIDATE); 01975 01976 sInfo.fMask = SIF_POS; 01977 SetScrollInfo(hwnd, fnBar, &sInfo, TRUE); 01978 01979 UpdateWindow(hwnd); 01980 } 01981 return 0; 01982 } 01983 01984 static LRESULT CALLBACK 01985 GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 01986 { 01987 LRESULT Result = 0; 01988 PGUI_CONSOLE_DATA GuiData = NULL; 01989 PCSRSS_CONSOLE Console = NULL; 01990 01991 GuiConsoleGetDataPointers(hWnd, &Console, &GuiData); 01992 01993 switch(msg) 01994 { 01995 case WM_NCCREATE: 01996 Result = (LRESULT) GuiConsoleHandleNcCreate(hWnd, (CREATESTRUCTW *) lParam); 01997 break; 01998 case WM_PAINT: 01999 GuiConsoleHandlePaint(hWnd, (HDC)wParam); 02000 break; 02001 case WM_KEYDOWN: 02002 case WM_KEYUP: 02003 case WM_SYSKEYDOWN: 02004 case WM_SYSKEYUP: 02005 case WM_CHAR: 02006 GuiConsoleHandleKey(hWnd, msg, wParam, lParam); 02007 break; 02008 case WM_TIMER: 02009 GuiConsoleHandleTimer(hWnd); 02010 break; 02011 case WM_CLOSE: 02012 GuiConsoleHandleClose(hWnd); 02013 break; 02014 case WM_NCDESTROY: 02015 GuiConsoleHandleNcDestroy(hWnd); 02016 break; 02017 case WM_LBUTTONDOWN: 02018 GuiConsoleLeftMouseDown(hWnd, lParam); 02019 break; 02020 case WM_LBUTTONUP: 02021 GuiConsoleLeftMouseUp(hWnd, lParam); 02022 break; 02023 case WM_RBUTTONDOWN: 02024 GuiConsoleRightMouseDown(hWnd); 02025 break; 02026 case WM_MOUSEMOVE: 02027 GuiConsoleMouseMove(hWnd, wParam, lParam); 02028 break; 02029 case WM_SYSCOMMAND: 02030 Result = GuiConsoleHandleSysMenuCommand(hWnd, wParam, lParam); 02031 break; 02032 case WM_HSCROLL: 02033 case WM_VSCROLL: 02034 Result = GuiConsoleHandleScroll(hWnd, msg, wParam); 02035 break; 02036 case WM_GETMINMAXINFO: 02037 GuiConsoleGetMinMaxInfo(hWnd, (PMINMAXINFO)lParam); 02038 break; 02039 case WM_SIZE: 02040 GuiConsoleResize(hWnd, wParam, lParam); 02041 break; 02042 case PM_APPLY_CONSOLE_INFO: 02043 GuiApplyUserSettings(Console, GuiData, (PConsoleInfo)wParam); 02044 if (lParam) 02045 { 02046 GuiConsoleWriteUserSettings(Console, GuiData); 02047 } 02048 break; 02049 default: 02050 Result = DefWindowProcW(hWnd, msg, wParam, lParam); 02051 break; 02052 } 02053 02054 return Result; 02055 } 02056 02057 static LRESULT CALLBACK 02058 GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 02059 { 02060 HWND NewWindow; 02061 LONG WindowCount; 02062 MSG Msg; 02063 PWCHAR Buffer, Title; 02064 PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) lParam; 02065 02066 02067 02068 switch(msg) 02069 { 02070 case WM_CREATE: 02071 SetWindowLongW(hWnd, GWL_USERDATA, 0); 02072 return 0; 02073 case PM_CREATE_CONSOLE: 02074 Buffer = HeapAlloc(Win32CsrApiHeap, 0, 02075 Console->Title.Length + sizeof(WCHAR)); 02076 if (NULL != Buffer) 02077 { 02078 memcpy(Buffer, Console->Title.Buffer, Console->Title.Length); 02079 Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0'; 02080 Title = Buffer; 02081 } 02082 else 02083 { 02084 Title = L""; 02085 } 02086 NewWindow = CreateWindowExW(WS_EX_CLIENTEDGE, 02087 L"ConsoleWindowClass", 02088 Title, 02089 WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL, 02090 CW_USEDEFAULT, 02091 CW_USEDEFAULT, 02092 CW_USEDEFAULT, 02093 CW_USEDEFAULT, 02094 NULL, 02095 NULL, 02096 (HINSTANCE) GetModuleHandleW(NULL), 02097 (PVOID) Console); 02098 if (NULL != Buffer) 02099 { 02100 HeapFree(Win32CsrApiHeap, 0, Buffer); 02101 } 02102 if (NULL != NewWindow) 02103 { 02104 SetWindowLongW(hWnd, GWL_USERDATA, GetWindowLongW(hWnd, GWL_USERDATA) + 1); 02105 ShowWindow(NewWindow, (int)wParam); 02106 } 02107 return (LRESULT) NewWindow; 02108 case PM_DESTROY_CONSOLE: 02109 /* Window creation is done using a PostMessage(), so it's possible that the 02110 * window that we want to destroy doesn't exist yet. So first empty the message 02111 * queue */ 02112 while(PeekMessageW(&Msg, NULL, 0, 0, PM_REMOVE)) 02113 { 02114 TranslateMessage(&Msg); 02115 DispatchMessageW(&Msg); 02116 } 02117 DestroyWindow(Console->hWindow); 02118 Console->hWindow = NULL; 02119 WindowCount = GetWindowLongW(hWnd, GWL_USERDATA); 02120 WindowCount--; 02121 SetWindowLongW(hWnd, GWL_USERDATA, WindowCount); 02122 if (0 == WindowCount) 02123 { 02124 NotifyWnd = NULL; 02125 DestroyWindow(hWnd); 02126 PrivateCsrssManualGuiCheck(-1); 02127 PostQuitMessage(0); 02128 } 02129 return 0; 02130 default: 02131 return DefWindowProcW(hWnd, msg, wParam, lParam); 02132 } 02133 } 02134 02135 static DWORD WINAPI 02136 GuiConsoleGuiThread(PVOID Data) 02137 { 02138 MSG msg; 02139 PHANDLE GraphicsStartupEvent = (PHANDLE) Data; 02140 02141 NotifyWnd = CreateWindowW(L"Win32CsrCreateNotify", 02142 L"", 02143 WS_OVERLAPPEDWINDOW, 02144 CW_USEDEFAULT, 02145 CW_USEDEFAULT, 02146 CW_USEDEFAULT, 02147 CW_USEDEFAULT, 02148 NULL, 02149 NULL, 02150 (HINSTANCE) GetModuleHandleW(NULL), 02151 NULL); 02152 if (NULL == NotifyWnd) 02153 { 02154 PrivateCsrssManualGuiCheck(-1); 02155 SetEvent(*GraphicsStartupEvent); 02156 return 1; 02157 } 02158 02159 SetEvent(*GraphicsStartupEvent); 02160 02161 while(GetMessageW(&msg, NULL, 0, 0)) 02162 { 02163 TranslateMessage(&msg); 02164 DispatchMessageW(&msg); 02165 } 02166 02167 return 1; 02168 } 02169 02170 static BOOL 02171 GuiInit(VOID) 02172 { 02173 WNDCLASSEXW wc; 02174 02175 if (NULL == NotifyWnd) 02176 { 02177 PrivateCsrssManualGuiCheck(+1); 02178 } 02179 02180 wc.cbSize = sizeof(WNDCLASSEXW); 02181 wc.lpszClassName = L"Win32CsrCreateNotify"; 02182 wc.lpfnWndProc = GuiConsoleNotifyWndProc; 02183 wc.style = 0; 02184 wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL); 02185 wc.hIcon = NULL; 02186 wc.hCursor = NULL; 02187 wc.hbrBackground = NULL; 02188 wc.lpszMenuName = NULL; 02189 wc.cbClsExtra = 0; 02190 wc.cbWndExtra = 0; 02191 wc.hIconSm = NULL; 02192 if (RegisterClassExW(&wc) == 0) 02193 { 02194 DPRINT1("Failed to register notify wndproc\n"); 02195 return FALSE; 02196 } 02197 02198 wc.cbSize = sizeof(WNDCLASSEXW); 02199 wc.lpszClassName = L"ConsoleWindowClass"; 02200 wc.lpfnWndProc = GuiConsoleWndProc; 02201 wc.style = 0; 02202 wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL); 02203 wc.hIcon = LoadIconW(GetModuleHandleW(L"win32csr"), MAKEINTRESOURCEW(1)); 02204 wc.hCursor = LoadCursorW(NULL, (LPCWSTR) IDC_ARROW); 02205 wc.hbrBackground = CreateSolidBrush(RGB(0,0,0)); 02206 wc.lpszMenuName = NULL; 02207 wc.cbClsExtra = 0; 02208 wc.cbWndExtra = 0; 02209 wc.hIconSm = LoadImageW(GetModuleHandleW(L"win32csr"), MAKEINTRESOURCEW(1), IMAGE_ICON, 02210 GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 02211 LR_SHARED); 02212 if (RegisterClassExW(&wc) == 0) 02213 { 02214 DPRINT1("Failed to register console wndproc\n"); 02215 return FALSE; 02216 } 02217 02218 return TRUE; 02219 } 02220 02221 static VOID WINAPI 02222 GuiInitScreenBuffer(PCSRSS_CONSOLE Console, PCSRSS_SCREEN_BUFFER Buffer) 02223 { 02224 Buffer->DefaultAttrib = DEFAULT_ATTRIB; 02225 } 02226 02227 static BOOL WINAPI 02228 GuiChangeTitle(PCSRSS_CONSOLE Console) 02229 { 02230 PWCHAR Buffer, Title; 02231 02232 Buffer = HeapAlloc(Win32CsrApiHeap, 0, 02233 Console->Title.Length + sizeof(WCHAR)); 02234 if (NULL != Buffer) 02235 { 02236 memcpy(Buffer, Console->Title.Buffer, Console->Title.Length); 02237 Buffer[Console->Title.Length / sizeof(WCHAR)] = L'\0'; 02238 Title = Buffer; 02239 } 02240 else 02241 { 02242 Title = L""; 02243 } 02244 02245 SendMessageW(Console->hWindow, WM_SETTEXT, 0, (LPARAM) Title); 02246 02247 if (NULL != Buffer) 02248 { 02249 HeapFree(Win32CsrApiHeap, 0, Buffer); 02250 } 02251 02252 return TRUE; 02253 } 02254 02255 static BOOL WINAPI 02256 GuiChangeIcon(PCSRSS_CONSOLE Console, HICON hWindowIcon) 02257 { 02258 SendMessageW(Console->hWindow, WM_SETICON, ICON_BIG, (LPARAM)hWindowIcon); 02259 SendMessageW(Console->hWindow, WM_SETICON, ICON_SMALL, (LPARAM)hWindowIcon); 02260 02261 return TRUE; 02262 } 02263 02264 static VOID WINAPI 02265 GuiCleanupConsole(PCSRSS_CONSOLE Console) 02266 { 02267 SendMessageW(NotifyWnd, PM_DESTROY_CONSOLE, 0, (LPARAM) Console); 02268 } 02269 02270 static CSRSS_CONSOLE_VTBL GuiVtbl = 02271 { 02272 GuiInitScreenBuffer, 02273 GuiWriteStream, 02274 GuiDrawRegion, 02275 GuiSetCursorInfo, 02276 GuiSetScreenInfo, 02277 GuiUpdateScreenInfo, 02278 GuiChangeTitle, 02279 GuiCleanupConsole, 02280 GuiChangeIcon, 02281 GuiResizeBuffer, 02282 }; 02283 02284 NTSTATUS FASTCALL 02285 GuiInitConsole(PCSRSS_CONSOLE Console, int ShowCmd) 02286 { 02287 HANDLE GraphicsStartupEvent; 02288 HANDLE ThreadHandle; 02289 PGUI_CONSOLE_DATA GuiData; 02290 02291 if (! ConsInitialized) 02292 { 02293 ConsInitialized = TRUE; 02294 if (! GuiInit()) 02295 { 02296 ConsInitialized = FALSE; 02297 return STATUS_UNSUCCESSFUL; 02298 } 02299 } 02300 02301 Console->Vtbl = &GuiVtbl; 02302 if (NULL == NotifyWnd) 02303 { 02304 GraphicsStartupEvent = CreateEventW(NULL, FALSE, FALSE, NULL); 02305 if (NULL == GraphicsStartupEvent) 02306 { 02307 return STATUS_UNSUCCESSFUL; 02308 } 02309 02310 ThreadHandle = CreateThread(NULL, 02311 0, 02312 GuiConsoleGuiThread, 02313 (PVOID) &GraphicsStartupEvent, 02314 0, 02315 NULL); 02316 if (NULL == ThreadHandle) 02317 { 02318 CloseHandle(GraphicsStartupEvent); 02319 DPRINT1("Win32Csr: Failed to create graphics console thread. Expect problems\n"); 02320 return STATUS_UNSUCCESSFUL; 02321 } 02322 SetThreadPriority(ThreadHandle, THREAD_PRIORITY_HIGHEST); 02323 CloseHandle(ThreadHandle); 02324 02325 WaitForSingleObject(GraphicsStartupEvent, INFINITE); 02326 CloseHandle(GraphicsStartupEvent); 02327 02328 if (NULL == NotifyWnd) 02329 { 02330 DPRINT1("Win32Csr: Failed to create notification window.\n"); 02331 return STATUS_UNSUCCESSFUL; 02332 } 02333 } 02334 GuiData = HeapAlloc(Win32CsrApiHeap, HEAP_ZERO_MEMORY, 02335 sizeof(GUI_CONSOLE_DATA)); 02336 if (!GuiData) 02337 { 02338 DPRINT1("Win32Csr: Failed to create GUI_CONSOLE_DATA\n"); 02339 return STATUS_UNSUCCESSFUL; 02340 } 02341 02342 Console->PrivateData = (PVOID) GuiData; 02343 /* 02344 * we need to wait untill the GUI has been fully initialized 02345 * to retrieve custom settings i.e. WindowSize etc.. 02346 * Ideally we could use SendNotifyMessage for this but its not 02347 * yet implemented. 02348 * 02349 */ 02350 GuiData->hGuiInitEvent = CreateEventW(NULL, FALSE, FALSE, NULL); 02351 /* create console */ 02352 PostMessageW(NotifyWnd, PM_CREATE_CONSOLE, ShowCmd, (LPARAM) Console); 02353 02354 /* wait untill initialization has finished */ 02355 WaitForSingleObject(GuiData->hGuiInitEvent, INFINITE); 02356 DPRINT("received event Console %p GuiData %p X %d Y %d\n", Console, Console->PrivateData, Console->Size.X, Console->Size.Y); 02357 CloseHandle(GuiData->hGuiInitEvent); 02358 GuiData->hGuiInitEvent = NULL; 02359 02360 return STATUS_SUCCESS; 02361 } 02362 02363 /* EOF */ Generated on Sat May 26 2012 04:37:33 for ReactOS by
1.7.6.1
|