diff --git a/reactos/dll/cpl/console/console.c b/reactos/dll/cpl/console/console.c index d26c23b21e2..436626b6087 100644 --- a/reactos/dll/cpl/console/console.c +++ b/reactos/dll/cpl/console/console.c @@ -118,7 +118,6 @@ InitConsoleDefaults(PCONSOLE_PROPS pConInfo) GuiInfo->FontSize.X = 0; GuiInfo->FontSize.Y = 0; GuiInfo->FontWeight = FW_DONTCARE; - GuiInfo->UseRasterFonts = TRUE; GuiInfo->FullScreen = FALSE; GuiInfo->ShowWindow = SW_SHOWNORMAL; diff --git a/reactos/dll/cpl/console/font.c b/reactos/dll/cpl/console/font.c index 58d7948975f..d714e63fa13 100644 --- a/reactos/dll/cpl/console/font.c +++ b/reactos/dll/cpl/console/font.c @@ -76,11 +76,25 @@ if (GetTextExtentPoint32W(drawItem->hDC, L"R", 1, &CharSize)) GuiData->CharWidth = CharSize.cx; } + +/* + * See also: Display_SetTypeFace in applications/fontview/display.c + */ #endif -BOOL CALLBACK -EnumFontFamExProc(PLOGFONTW lplf, +/* + * Font pixel heights for TrueType fonts + */ +static SHORT TrueTypePoints[] = +{ + // 8, 9, 10, 11, 12, 14, 16, 18, 20, + // 22, 24, 26, 28, 36, 48, 72 + 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 24, 28, 36, 72 +}; + +static BOOL CALLBACK +EnumFontNamesProc(PLOGFONTW lplf, PNEWTEXTMETRICW lpntm, DWORD FontType, LPARAM lParam) @@ -197,6 +211,161 @@ EnumFontFamExProc(PLOGFONTW lplf, return TRUE; } +static BOOL CALLBACK +EnumFontSizesProc(PLOGFONTW lplf, + PNEWTEXTMETRICW lpntm, + DWORD FontType, + LPARAM lParam) +{ + HWND hwndCombo = (HWND)lParam; + WCHAR FontSize[100]; + + if (FontType != TRUETYPE_FONTTYPE) + { + // int logsize = lpntm->tmHeight - lpntm->tmInternalLeading; + // LONG pointsize = MulDiv(logsize, 72, GetDeviceCaps(hdc, LOGPIXELSY)); + + // swprintf(FontSize, L"%2d (%d x %d)", pointsize, lplf->lfWidth, lplf->lfHeight); + swprintf(FontSize, L"%d x %d", lplf->lfWidth, lplf->lfHeight); + + /* Make sure the size doesn't already exist in the list */ + if (SendMessageW(hwndCombo, LB_FINDSTRINGEXACT, 0, (LPARAM)FontSize) == LB_ERR) + { + /* Add the size */ + INT idx = (INT)SendMessageW(hwndCombo, LB_ADDSTRING, 0, (LPARAM)FontSize); + + /* + * Store this information in the list-item's userdata area. + * Format: + * Width = FontSize.X = LOWORD(FontSize); + * Height = FontSize.Y = HIWORD(FontSize); + */ + SendMessageW(hwndCombo, LB_SETITEMDATA, idx, MAKEWPARAM(lplf->lfWidth, lplf->lfHeight)); + } + + return TRUE; + } + else + { + int i; + for (i = 0; i < sizeof(TrueTypePoints) / sizeof(TrueTypePoints[0]); ++i) + { + swprintf(FontSize, L"%2d", TrueTypePoints[i]); + + /* Make sure the size doesn't already exist in the list */ + if (SendMessageW(hwndCombo, LB_FINDSTRINGEXACT, 0, (LPARAM)FontSize) == LB_ERR) + { + /* Add the size */ + INT idx = (INT)SendMessageW(hwndCombo, LB_ADDSTRING, 0, (LPARAM)FontSize); + + /* + * Store this information in the list-item's userdata area. + * Format: + * Width = FontSize.X = LOWORD(FontSize); + * Height = FontSize.Y = HIWORD(FontSize); + */ + SendMessageW(hwndCombo, LB_SETITEMDATA, idx, MAKEWPARAM(0, TrueTypePoints[i])); + } + } + + return FALSE; + } +} + + + +static VOID +FontSizeChange(HWND hwndDlg, + PGUI_CONSOLE_INFO GuiInfo); + +static VOID +FontTypeChange(HWND hwndDlg, + PGUI_CONSOLE_INFO GuiInfo) +{ + INT Length, nSel; + LPWSTR FaceName; + + HDC hDC; + LOGFONTW lf; + + nSel = (INT)SendDlgItemMessageW(hwndDlg, IDC_LBOX_FONTTYPE, + LB_GETCURSEL, 0, 0); + if (nSel == LB_ERR) return; + + Length = (INT)SendDlgItemMessageW(hwndDlg, IDC_LBOX_FONTTYPE, + LB_GETTEXTLEN, nSel, 0); + if (Length == LB_ERR) return; + + FaceName = HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + (Length + 1) * sizeof(WCHAR)); + if (FaceName == NULL) return; + + Length = (INT)SendDlgItemMessageW(hwndDlg, IDC_LBOX_FONTTYPE, + LB_GETTEXT, nSel, (LPARAM)FaceName); + FaceName[Length] = '\0'; + + Length = min(Length/*wcslen(FaceName) + 1*/, LF_FACESIZE); // wcsnlen + wcsncpy(GuiInfo->FaceName, FaceName, LF_FACESIZE); + GuiInfo->FaceName[Length] = L'\0'; + DPRINT1("GuiInfo->FaceName = '%S'\n", GuiInfo->FaceName); + + /* Enumerate the available sizes for the selected font */ + ZeroMemory(&lf, sizeof(lf)); + lf.lfCharSet = DEFAULT_CHARSET; // OEM_CHARSET; + // lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE; + wcsncpy(lf.lfFaceName, FaceName, LF_FACESIZE); + lf.lfFaceName[Length] = L'\0'; + + hDC = GetDC(NULL); + EnumFontFamiliesExW(hDC, &lf, (FONTENUMPROCW)EnumFontSizesProc, + (LPARAM)GetDlgItem(hwndDlg, IDC_LBOX_FONTSIZE), 0); + ReleaseDC(NULL, hDC); + + HeapFree(GetProcessHeap(), 0, FaceName); + + // TODO: Select a default font size???? + FontSizeChange(hwndDlg, GuiInfo); + + // InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_FONT_WINDOW_PREVIEW), NULL, TRUE); + // InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_SELECT_FONT_PREVIEW), NULL, TRUE); +} + +static VOID +FontSizeChange(HWND hwndDlg, + PGUI_CONSOLE_INFO GuiInfo) +{ + INT nSel; + ULONG FontSize; + WCHAR FontSizeStr[20]; + + nSel = (INT)SendDlgItemMessageW(hwndDlg, IDC_LBOX_FONTSIZE, + LB_GETCURSEL, 0, 0); + if (nSel == LB_ERR) return; + + /* + * Format: + * Width = FontSize.X = LOWORD(FontSize); + * Height = FontSize.Y = HIWORD(FontSize); + */ + FontSize = (ULONG)SendDlgItemMessageW(hwndDlg, IDC_LBOX_FONTSIZE, + LB_GETITEMDATA, nSel, 0); + if (FontSize == LB_ERR) return; + + GuiInfo->FontSize.X = LOWORD(FontSize); + GuiInfo->FontSize.Y = HIWORD(FontSize); + DPRINT1("GuiInfo->FontSize = (%d x %d)\n", GuiInfo->FontSize.X, GuiInfo->FontSize.Y); + + InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_FONT_WINDOW_PREVIEW), NULL, TRUE); + InvalidateRect(GetDlgItem(hwndDlg, IDC_STATIC_SELECT_FONT_PREVIEW), NULL, TRUE); + + swprintf(FontSizeStr, L"%2d", GuiInfo->FontSize.X); + SetWindowText(GetDlgItem(hwndDlg, IDC_FONT_SIZE_X), FontSizeStr); + swprintf(FontSizeStr, L"%2d", GuiInfo->FontSize.Y); + SetWindowText(GetDlgItem(hwndDlg, IDC_FONT_SIZE_Y), FontSizeStr); +} + + INT_PTR CALLBACK FontProc(HWND hwndDlg, @@ -214,7 +383,6 @@ FontProc(HWND hwndDlg, case WM_INITDIALOG: { HDC hDC; - HWND hwndCombo; LOGFONTW lf; INT idx; @@ -225,19 +393,19 @@ FontProc(HWND hwndDlg, ZeroMemory(&lf, sizeof(lf)); lf.lfCharSet = DEFAULT_CHARSET; // OEM_CHARSET; // lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE; - // lf.lfFaceName = L""; hDC = GetDC(NULL); - hwndCombo = GetDlgItem(hwndDlg, IDC_LBOX_FONTTYPE); - EnumFontFamiliesExW(hDC, &lf, (FONTENUMPROCW)EnumFontFamExProc, (LPARAM)hwndCombo, 0); + EnumFontFamiliesExW(hDC, &lf, (FONTENUMPROCW)EnumFontNamesProc, + (LPARAM)GetDlgItem(hwndDlg, IDC_LBOX_FONTTYPE), 0); ReleaseDC(NULL, hDC); DPRINT1("GuiInfo->FaceName = '%S'\n", GuiInfo->FaceName); - idx = (INT)SendMessageW(hwndCombo, LB_FINDSTRINGEXACT, 0, (LPARAM)GuiInfo->FaceName); - if (idx != LB_ERR) - { - SendMessageW(hwndCombo, LB_SETCURSEL, (WPARAM)idx, 0); - } + idx = (INT)SendDlgItemMessageW(hwndDlg, IDC_LBOX_FONTTYPE, + LB_FINDSTRINGEXACT, 0, (LPARAM)GuiInfo->FaceName); + if (idx != LB_ERR) SendDlgItemMessageW(hwndDlg, IDC_LBOX_FONTTYPE, + LB_SETCURSEL, (WPARAM)idx, 0); + + FontTypeChange(hwndDlg, GuiInfo); return TRUE; } @@ -247,16 +415,66 @@ FontProc(HWND hwndDlg, LPDRAWITEMSTRUCT drawItem = (LPDRAWITEMSTRUCT)lParam; if (drawItem->CtlID == IDC_STATIC_FONT_WINDOW_PREVIEW) - { PaintConsole(drawItem, pConInfo); - } else if (drawItem->CtlID == IDC_STATIC_SELECT_FONT_PREVIEW) - { PaintText(drawItem, pConInfo, Screen); - } + return TRUE; } + case WM_NOTIFY: + { + switch (((LPNMHDR)lParam)->code) + { + case PSN_APPLY: + { + if (!pConInfo->AppliedConfig) + { + return ApplyConsoleInfo(hwndDlg, pConInfo); + } + else + { + /* Options have already been applied */ + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); + return TRUE; + } + break; + } + } + + break; + } + + case WM_COMMAND: + { + switch (HIWORD(wParam)) + { + case LBN_SELCHANGE: + { + switch (LOWORD(wParam)) + { + case IDC_LBOX_FONTTYPE: + { + FontTypeChange(hwndDlg, GuiInfo); + PropSheet_Changed(GetParent(hwndDlg), hwndDlg); + break; + } + + case IDC_LBOX_FONTSIZE: + { + FontSizeChange(hwndDlg, GuiInfo); + PropSheet_Changed(GetParent(hwndDlg), hwndDlg); + break; + } + } + + break; + } + } + + break; + } + default: break; } diff --git a/reactos/dll/cpl/console/lang/bg-BG.rc b/reactos/dll/cpl/console/lang/bg-BG.rc index b7f0b9da413..e6f62b7530b 100644 --- a/reactos/dll/cpl/console/lang/bg-BG.rc +++ b/reactos/dll/cpl/console/lang/bg-BG.rc @@ -35,7 +35,7 @@ BEGIN LTEXT "Прозоречен преглед:", -1, 10, 10, 94, 10 LTEXT "Размер:", -1, 180, 10, 36, 10 CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74 - LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_DISABLENOSCROLL | WS_VSCROLL + LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL LTEXT "&Шрифт:", -1, 10, 105, 33, 10 CHECKBOX "&Получери шрифтове", IDC_CHECK_BOLD_FONTS, 38, 105, 85, 10 LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL diff --git a/reactos/dll/cpl/console/lang/cs-CZ.rc b/reactos/dll/cpl/console/lang/cs-CZ.rc index 0cfef2c42f4..afda11d7d58 100644 --- a/reactos/dll/cpl/console/lang/cs-CZ.rc +++ b/reactos/dll/cpl/console/lang/cs-CZ.rc @@ -41,7 +41,7 @@ BEGIN LTEXT "Náhled okna:", -1, 10, 10, 94, 10 LTEXT "Velikost:", -1, 180, 10, 36, 10 CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74 - LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_DISABLENOSCROLL | WS_VSCROLL + LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL LTEXT "&Písmo:", -1, 10, 105, 33, 10 CHECKBOX "&Tučná písma", IDC_CHECK_BOLD_FONTS, 56, 105, 60, 10 LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL diff --git a/reactos/dll/cpl/console/lang/de-DE.rc b/reactos/dll/cpl/console/lang/de-DE.rc index 8a241377d0b..5ea5d53f846 100644 --- a/reactos/dll/cpl/console/lang/de-DE.rc +++ b/reactos/dll/cpl/console/lang/de-DE.rc @@ -37,7 +37,7 @@ BEGIN LTEXT "Fenstervorschau", -1, 10, 7, 65, 10 LTEXT "Größe", -1, 130, 10, 30, 10 CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 115, 70 - LISTBOX IDC_LBOX_FONTSIZE, 130, 20, 55, 80, LBS_SORT | LBS_DISABLENOSCROLL | WS_VSCROLL + LISTBOX IDC_LBOX_FONTSIZE, 130, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL LTEXT "&Schrift", -1, 10, 105, 35, 10 CHECKBOX "&Fette Schriften", IDC_CHECK_BOLD_FONTS, 45, 105, 60, 10 LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 50, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL diff --git a/reactos/dll/cpl/console/lang/en-US.rc b/reactos/dll/cpl/console/lang/en-US.rc index a389a6af357..d4d9e576f2b 100644 --- a/reactos/dll/cpl/console/lang/en-US.rc +++ b/reactos/dll/cpl/console/lang/en-US.rc @@ -35,7 +35,7 @@ BEGIN LTEXT "Window Preview:", -1, 10, 10, 94, 10 LTEXT "Size:", -1, 180, 10, 36, 10 CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74 - LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_DISABLENOSCROLL | WS_VSCROLL + LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL LTEXT "&Font:", -1, 10, 105, 33, 10 CHECKBOX "&Bold fonts", IDC_CHECK_BOLD_FONTS, 56, 105, 60, 10 LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL diff --git a/reactos/dll/cpl/console/lang/es-ES.rc b/reactos/dll/cpl/console/lang/es-ES.rc index 86611a92863..4cb83e117ee 100644 --- a/reactos/dll/cpl/console/lang/es-ES.rc +++ b/reactos/dll/cpl/console/lang/es-ES.rc @@ -37,7 +37,7 @@ BEGIN LTEXT "Ventana de Previsualización", -1, 10, 7, 65, 10 LTEXT "Tamaño", -1, 130, 10, 30, 10 CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 115, 70 - LISTBOX IDC_LBOX_FONTSIZE, 130, 20, 55, 80, LBS_SORT | LBS_DISABLENOSCROLL | WS_VSCROLL + LISTBOX IDC_LBOX_FONTSIZE, 130, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL LTEXT "&Fuente", -1, 10, 105, 35, 10 CHECKBOX "&Negrita", IDC_CHECK_BOLD_FONTS, 45, 105, 60, 10 LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 50, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL diff --git a/reactos/dll/cpl/console/lang/fr-FR.rc b/reactos/dll/cpl/console/lang/fr-FR.rc index fcfc76e36ee..4e57984b2fb 100644 --- a/reactos/dll/cpl/console/lang/fr-FR.rc +++ b/reactos/dll/cpl/console/lang/fr-FR.rc @@ -37,14 +37,14 @@ BEGIN LTEXT "Fenêtre de Prévisualisation :", -1, 10, 10, 94, 10 LTEXT "Taille :", -1, 180, 10, 36, 10 CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74 - LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_DISABLENOSCROLL | WS_VSCROLL + LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL LTEXT "&Police :", -1, 10, 105, 33, 10 CHECKBOX "&Gras", IDC_CHECK_BOLD_FONTS, 56, 105, 60, 10 LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL GROUPBOX "", IDC_GROUPBOX_FONT_NAME, 6, 156, 241, 50 CONTROL "", IDC_STATIC_SELECT_FONT_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 16, 165, 95, 35 - LTEXT "Chaque caractère est :", -1, 124, 166, 75, 10 - LTEXT "largeur du pixel\nhauteur du pixel", -1, 136, 180, 101, 20 + LTEXT "Chaque caractère utilise :", -1, 124, 166, 85, 10 + LTEXT "pixels en largeur\npixels en hauteur", -1, 136, 180, 101, 20 LTEXT "", IDC_FONT_SIZE_X, 120, 180, 10, 10 LTEXT "", IDC_FONT_SIZE_Y, 120, 188, 10, 10 END diff --git a/reactos/dll/cpl/console/lang/he-IL.rc b/reactos/dll/cpl/console/lang/he-IL.rc index 2ee72d74b64..a68475013f4 100644 --- a/reactos/dll/cpl/console/lang/he-IL.rc +++ b/reactos/dll/cpl/console/lang/he-IL.rc @@ -37,7 +37,7 @@ BEGIN LTEXT "תצוגה מקדימה:", -1, 10, 10, 94, 10 LTEXT "גודל:", -1, 180, 10, 36, 10 CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74 - LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_DISABLENOSCROLL | WS_VSCROLL + LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL LTEXT "גופן:", -1, 10, 105, 33, 10 CHECKBOX "גופנים מודגשים", IDC_CHECK_BOLD_FONTS, 41, 105, 33, 10 LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL diff --git a/reactos/dll/cpl/console/lang/id-ID.rc b/reactos/dll/cpl/console/lang/id-ID.rc index 4232a3b112d..e84bcbfe107 100644 --- a/reactos/dll/cpl/console/lang/id-ID.rc +++ b/reactos/dll/cpl/console/lang/id-ID.rc @@ -37,7 +37,7 @@ BEGIN LTEXT "Tinjauan Jendela", -1, 10, 7, 65, 10 LTEXT "Ukuran", -1, 130, 10, 30, 10 CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 115, 70 - LISTBOX IDC_LBOX_FONTSIZE, 130, 20, 55, 80, LBS_SORT | LBS_DISABLENOSCROLL | WS_VSCROLL + LISTBOX IDC_LBOX_FONTSIZE, 130, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL LTEXT "&Font", -1, 10, 105, 35, 10 CHECKBOX "Font &tebal", IDC_CHECK_BOLD_FONTS, 45, 105, 60, 10 LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 50, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL diff --git a/reactos/dll/cpl/console/lang/it-IT.rc b/reactos/dll/cpl/console/lang/it-IT.rc index 395c6c45ed2..cfc0bd31e9b 100644 --- a/reactos/dll/cpl/console/lang/it-IT.rc +++ b/reactos/dll/cpl/console/lang/it-IT.rc @@ -37,7 +37,7 @@ BEGIN LTEXT "Anteprima", -1, 10, 7, 65, 10 LTEXT "Dimansione", -1, 130, 10, 30, 10 CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 115, 70 - LISTBOX IDC_LBOX_FONTSIZE, 130, 20, 55, 80, LBS_SORT | LBS_DISABLENOSCROLL | WS_VSCROLL + LISTBOX IDC_LBOX_FONTSIZE, 130, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL LTEXT "&Font", -1, 10, 105, 35, 10 CHECKBOX "&Grassetto fonts", IDC_CHECK_BOLD_FONTS, 45, 105, 60, 10 LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 50, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL diff --git a/reactos/dll/cpl/console/lang/no-NO.rc b/reactos/dll/cpl/console/lang/no-NO.rc index 8a3eb71fe11..634812113d8 100644 --- a/reactos/dll/cpl/console/lang/no-NO.rc +++ b/reactos/dll/cpl/console/lang/no-NO.rc @@ -35,7 +35,7 @@ BEGIN LTEXT "Vindu forhåndsvisning:", -1, 10, 10, 94, 10 LTEXT "Størrelse:", -1, 180, 10, 36, 10 CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74 - LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_DISABLENOSCROLL | WS_VSCROLL + LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL LTEXT "&Skrift:", -1, 10, 105, 33, 10 CHECKBOX "&Fet skrift", IDC_CHECK_BOLD_FONTS, 56, 105, 60, 10 LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL diff --git a/reactos/dll/cpl/console/lang/pl-PL.rc b/reactos/dll/cpl/console/lang/pl-PL.rc index f7e8d7c3588..bcee44f7b5c 100644 --- a/reactos/dll/cpl/console/lang/pl-PL.rc +++ b/reactos/dll/cpl/console/lang/pl-PL.rc @@ -42,7 +42,7 @@ BEGIN LTEXT "Okno podglądu", -1, 10, 7, 65, 10 LTEXT "Rozmiar", -1, 130, 10, 30, 10 CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 115, 70 - LISTBOX IDC_LBOX_FONTSIZE, 130, 20, 55, 80, LBS_SORT | LBS_DISABLENOSCROLL | WS_VSCROLL + LISTBOX IDC_LBOX_FONTSIZE, 130, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL LTEXT "&Czcionka", -1, 10, 105, 35, 10 CHECKBOX "&Pogrubiona czcionka", IDC_CHECK_BOLD_FONTS, 45, 105, 60, 10 LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 50, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL diff --git a/reactos/dll/cpl/console/lang/ro-RO.rc b/reactos/dll/cpl/console/lang/ro-RO.rc index 6f17ed30790..7c33e3a6fbe 100644 --- a/reactos/dll/cpl/console/lang/ro-RO.rc +++ b/reactos/dll/cpl/console/lang/ro-RO.rc @@ -44,7 +44,7 @@ BEGIN LTEXT "Previzionare:", -1, 10, 10, 94, 10 LTEXT "&Mărime:", -1, 180, 10, 36, 10 CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74 - LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_DISABLENOSCROLL | WS_VSCROLL + LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL LTEXT "F&ont:", -1, 10, 105, 33, 10 CHECKBOX "&Aldin", IDC_CHECK_BOLD_FONTS, 56, 105, 60, 10 LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL diff --git a/reactos/dll/cpl/console/lang/ru-RU.rc b/reactos/dll/cpl/console/lang/ru-RU.rc index 13e60dd0861..7a71960c3c0 100644 --- a/reactos/dll/cpl/console/lang/ru-RU.rc +++ b/reactos/dll/cpl/console/lang/ru-RU.rc @@ -37,7 +37,7 @@ BEGIN LTEXT "Окно предпросмотра:", -1, 10, 10, 94, 10 LTEXT "Размер:", -1, 180, 10, 36, 10 CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74 - LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_DISABLENOSCROLL | WS_VSCROLL + LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL LTEXT "&Шрифт:", -1, 10, 105, 33, 10 CHECKBOX "&Жирный", IDC_CHECK_BOLD_FONTS, 56, 105, 60, 10 LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL diff --git a/reactos/dll/cpl/console/lang/sk-SK.rc b/reactos/dll/cpl/console/lang/sk-SK.rc index 09df76713af..6392d83271b 100644 --- a/reactos/dll/cpl/console/lang/sk-SK.rc +++ b/reactos/dll/cpl/console/lang/sk-SK.rc @@ -39,7 +39,7 @@ BEGIN LTEXT "Ukážka okna:", -1, 10, 10, 94, 10 LTEXT "Veľkosť:", -1, 180, 10, 36, 10 CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74 - LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_DISABLENOSCROLL | WS_VSCROLL + LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL LTEXT "&Písmo:", -1, 10, 105, 33, 10 CHECKBOX "&Tučné písma", IDC_CHECK_BOLD_FONTS, 56, 105, 60, 10 LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL diff --git a/reactos/dll/cpl/console/lang/sq-AL.rc b/reactos/dll/cpl/console/lang/sq-AL.rc index cdf416e99a3..8a2364e66d7 100644 --- a/reactos/dll/cpl/console/lang/sq-AL.rc +++ b/reactos/dll/cpl/console/lang/sq-AL.rc @@ -39,7 +39,7 @@ BEGIN LTEXT "Dritare Preview:", -1, 10, 10, 94, 10 LTEXT "Masë:", -1, 180, 10, 36, 10 CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74 - LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_DISABLENOSCROLL | WS_VSCROLL + LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL LTEXT "&Font:", -1, 10, 105, 33, 10 CHECKBOX "&Bold fonts", IDC_CHECK_BOLD_FONTS, 56, 105, 60, 10 LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL diff --git a/reactos/dll/cpl/console/lang/tr-TR.rc b/reactos/dll/cpl/console/lang/tr-TR.rc index 23445d94baf..7521b5bcce9 100644 --- a/reactos/dll/cpl/console/lang/tr-TR.rc +++ b/reactos/dll/cpl/console/lang/tr-TR.rc @@ -37,7 +37,7 @@ BEGIN LTEXT "Pencere Ön İzlemesi:", -1, 10, 10, 94, 10 LTEXT "&Boyutlar:", -1, 180, 10, 36, 10 CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74 - LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_DISABLENOSCROLL | WS_VSCROLL + LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL LTEXT "&Yazı Tipi:", -1, 10, 105, 33, 10 CHECKBOX "&Kalın Yazı Tipleri", IDC_CHECK_BOLD_FONTS, 56, 105, 60, 10 LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL diff --git a/reactos/dll/cpl/console/lang/uk-UA.rc b/reactos/dll/cpl/console/lang/uk-UA.rc index c98f33c127d..dbe92ecf144 100644 --- a/reactos/dll/cpl/console/lang/uk-UA.rc +++ b/reactos/dll/cpl/console/lang/uk-UA.rc @@ -37,7 +37,7 @@ BEGIN LTEXT "Зразок вікна", -1, 10, 10, 94, 10 LTEXT "Size:", -1, 180, 10, 36, 10 CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74 - LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_DISABLENOSCROLL | WS_VSCROLL + LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL LTEXT "&Шрифт:", -1, 10, 105, 33, 10 CHECKBOX "&Жирні", IDC_CHECK_BOLD_FONTS, 56, 105, 60, 10 LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL diff --git a/reactos/dll/cpl/console/lang/zh-CN.rc b/reactos/dll/cpl/console/lang/zh-CN.rc index 409f531e67f..fa8d9bd0390 100644 --- a/reactos/dll/cpl/console/lang/zh-CN.rc +++ b/reactos/dll/cpl/console/lang/zh-CN.rc @@ -37,7 +37,7 @@ BEGIN LTEXT "窗口预览:", -1, 10, 10, 94, 10 LTEXT "大小:", -1, 180, 10, 36, 10 CONTROL "", IDC_STATIC_FONT_WINDOW_PREVIEW, "Static", SS_OWNERDRAW | SS_SUNKEN, 10, 20, 163, 74 - LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_DISABLENOSCROLL | WS_VSCROLL + LISTBOX IDC_LBOX_FONTSIZE, 181, 20, 55, 80, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL LTEXT "&字体(&F):", -1, 10, 105, 33, 10 CHECKBOX "粗体(&B)", IDC_CHECK_BOLD_FONTS, 56, 105, 60, 10 LISTBOX IDC_LBOX_FONTTYPE, 10, 120, 110, 40, LBS_SORT | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL diff --git a/reactos/dll/cpl/console/layout.c b/reactos/dll/cpl/console/layout.c index 41ebc3146e5..fac40bba815 100644 --- a/reactos/dll/cpl/console/layout.c +++ b/reactos/dll/cpl/console/layout.c @@ -120,8 +120,8 @@ PaintText(LPDRAWITEMSTRUCT drawItem, hBrush = CreateSolidBrush(nbkColor); if (!hBrush) return FALSE; - Font = CreateFontW(GuiInfo->FontSize.X, - 0, // GuiInfo->FontSize.Y, + Font = CreateFontW(GuiInfo->FontSize.Y, + 0, // GuiInfo->FontSize.X, 0, TA_BASELINE, GuiInfo->FontWeight, diff --git a/reactos/dll/win32/kernel32/client/console/readwrite.c b/reactos/dll/win32/kernel32/client/console/readwrite.c index 9db3ab5cab1..f1818a0c8c8 100644 --- a/reactos/dll/win32/kernel32/client/console/readwrite.c +++ b/reactos/dll/win32/kernel32/client/console/readwrite.c @@ -881,6 +881,7 @@ IntWriteConsoleOutput(IN HANDLE hConsoleOutput, { WriteOutputRequest->CharInfo = &WriteOutputRequest->StaticBuffer; // CaptureBuffer = NULL; + WriteOutputRequest->UseVirtualMemory = FALSE; } else { @@ -888,17 +889,36 @@ IntWriteConsoleOutput(IN HANDLE hConsoleOutput, /* Allocate a Capture Buffer */ CaptureBuffer = CsrAllocateCaptureBuffer(1, Size); - if (CaptureBuffer == NULL) + if (CaptureBuffer) { - DPRINT1("CsrAllocateCaptureBuffer failed with size %ld!\n", Size); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; + /* Allocate space in the Buffer */ + CsrAllocateMessagePointer(CaptureBuffer, + Size, + (PVOID*)&WriteOutputRequest->CharInfo); + WriteOutputRequest->UseVirtualMemory = FALSE; } + else + { + /* + * CsrAllocateCaptureBuffer failed because we tried to allocate + * a too large (>= 64 kB, size of the CSR heap) data buffer. + * To circumvent this, Windows uses a trick (that we reproduce for + * compatibility reasons): we allocate a heap buffer in the process' + * memory, and CSR will read it via NtReadVirtualMemory. + */ + DPRINT1("CsrAllocateCaptureBuffer failed with size %ld, let's use local heap buffer...\n", Size); - /* Allocate space in the Buffer */ - CsrAllocateMessagePointer(CaptureBuffer, - Size, - (PVOID*)&WriteOutputRequest->CharInfo); + WriteOutputRequest->CharInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, Size); + WriteOutputRequest->UseVirtualMemory = TRUE; + + /* Bail out if we still cannot allocate memory */ + if (WriteOutputRequest->CharInfo == NULL) + { + DPRINT1("Failed to allocate heap buffer with size %ld!\n", Size); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + } } /* Capture the user buffer contents */ @@ -945,7 +965,16 @@ IntWriteConsoleOutput(IN HANDLE hConsoleOutput, Success = NT_SUCCESS(ApiMessage.Status); /* Release the capture buffer if needed */ - if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer); + if (CaptureBuffer) + { + CsrFreeCaptureBuffer(CaptureBuffer); + } + else + { + /* If we used a heap buffer, free it */ + if (WriteOutputRequest->UseVirtualMemory) + RtlFreeHeap(RtlGetProcessHeap(), 0, WriteOutputRequest->CharInfo); + } /* Retrieve the results */ _SEH2_TRY diff --git a/reactos/dll/win32/kernel32/client/vdm.c b/reactos/dll/win32/kernel32/client/vdm.c index 8b50319491f..3456dab587c 100644 --- a/reactos/dll/win32/kernel32/client/vdm.c +++ b/reactos/dll/win32/kernel32/client/vdm.c @@ -1640,26 +1640,101 @@ GetVDMCurrentDirectories(DWORD cchCurDirs, PCHAR lpszzCurDirs) /* - * @unimplemented + * @implemented (undocumented) */ BOOL WINAPI -RegisterConsoleVDM ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, - DWORD Unknown4, - DWORD Unknown5, - DWORD Unknown6, - DWORD Unknown7, - DWORD Unknown8, - DWORD Unknown9, - DWORD Unknown10 - ) +RegisterConsoleVDM(IN DWORD dwRegisterFlags, + IN HANDLE hStartHardwareEvent, + IN HANDLE hEndHardwareEvent, + IN HANDLE hErrorHardwareEvent, + IN DWORD dwUnusedVar, + OUT LPDWORD lpVideoStateLength, + OUT PVOID* lpVideoState, // PVIDEO_HARDWARE_STATE_HEADER* + IN PVOID lpUnusedBuffer, + IN DWORD dwUnusedBufferLength, + IN COORD dwVDMBufferSize, + OUT PVOID* lpVDMBuffer) { - STUB; - return FALSE; + BOOL Success; + CONSOLE_API_MESSAGE ApiMessage; + PCONSOLE_REGISTERVDM RegisterVDMRequest = &ApiMessage.Data.RegisterVDMRequest; + PCSR_CAPTURE_BUFFER CaptureBuffer = NULL; + + /* Set up the data to send to the Console Server */ + RegisterVDMRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + RegisterVDMRequest->RegisterFlags = dwRegisterFlags; + + if (dwRegisterFlags != 0) + { + RegisterVDMRequest->StartHardwareEvent = hStartHardwareEvent; + RegisterVDMRequest->EndHardwareEvent = hEndHardwareEvent; + RegisterVDMRequest->ErrorHardwareEvent = hErrorHardwareEvent; + + RegisterVDMRequest->VDMBufferSize = dwVDMBufferSize; + +#if 0 + RegisterVDMRequest->UnusedBufferLength = dwUnusedBufferLength; + + /* Allocate a Capture Buffer */ + CaptureBuffer = CsrAllocateCaptureBuffer(1, dwUnusedBufferLength); + if (CaptureBuffer == NULL) + { + DPRINT1("CsrAllocateCaptureBuffer failed!\n"); + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + /* Capture the buffer to write */ + CsrCaptureMessageBuffer(CaptureBuffer, + (PVOID)lpUnusedBuffer, + dwUnusedBufferLength, + (PVOID*)&RegisterVDMRequest->UnusedBuffer); +#endif + } + else + { + // CaptureBuffer = NULL; + } + + /* Call the server */ + CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, + CaptureBuffer, + CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepRegisterVDM), + sizeof(*RegisterVDMRequest)); + + /* Check for success */ + Success = NT_SUCCESS(ApiMessage.Status); + + /* Release the capture buffer if needed */ + if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer); + + /* Retrieve the results */ + if (Success) + { + if (dwRegisterFlags != 0) + { + _SEH2_TRY + { + *lpVideoStateLength = RegisterVDMRequest->VideoStateLength; + *lpVideoState = RegisterVDMRequest->VideoState; + *lpVDMBuffer = RegisterVDMRequest->VDMBuffer; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + SetLastError(ERROR_INVALID_ACCESS); + Success = FALSE; + } + _SEH2_END; + } + } + else + { + BaseSetLastNTError(ApiMessage.Status); + } + + /* Return success status */ + return Success; } @@ -1756,9 +1831,8 @@ VDMOperationStarted(IN ULONG Unknown0) { DPRINT1("VDMOperationStarted(%d)\n", Unknown0); - return - BaseUpdateVDMEntry(VdmEntryUpdateControlCHandler, - NULL, - 0, - Unknown0); + return BaseUpdateVDMEntry(VdmEntryUpdateControlCHandler, + NULL, + 0, + Unknown0); } diff --git a/reactos/include/psdk/wincon.h b/reactos/include/psdk/wincon.h index c44e478dab0..2df5ef345a0 100644 --- a/reactos/include/psdk/wincon.h +++ b/reactos/include/psdk/wincon.h @@ -618,6 +618,12 @@ BOOL WINAPI CloseConsoleHandle(_In_ HANDLE); // BOOL WINAPI SetStdHandle(_In_ DWORD, _In_ HANDLE); /* Undocumented */ BOOL WINAPI VerifyConsoleIoHandle(_In_ HANDLE); +/* Undocumented */ +BOOL +WINAPI +RegisterConsoleVDM(_In_ DWORD, _In_ HANDLE, _In_ HANDLE, _In_ HANDLE, _In_ DWORD, + _Out_ LPDWORD, _Out_ PVOID*, _In_ PVOID, _In_ DWORD, _In_ COORD, + _Out_ PVOID*); BOOL WINAPI diff --git a/reactos/include/reactos/subsys/win/conmsg.h b/reactos/include/reactos/subsys/win/conmsg.h index a11d0bf64b8..1f047226d3d 100644 --- a/reactos/include/reactos/subsys/win/conmsg.h +++ b/reactos/include/reactos/subsys/win/conmsg.h @@ -544,7 +544,12 @@ typedef struct SMALL_RECT WriteRegion; BOOLEAN Unicode; - ULONG Unknown; + /* + * If we are going to write too large (>= 64 kB, size of the CSR heap) + * data buffers, we allocate a heap buffer in the process' memory, and + * CSR will read it via NtReadVirtualMemory. + */ + BOOLEAN UseVirtualMemory; } CONSOLE_WRITEOUTPUT, *PCONSOLE_WRITEOUTPUT; typedef struct @@ -801,6 +806,28 @@ typedef struct BOOL Ansi; } CONSOLE_GETKBDLAYOUTNAME, *PCONSOLE_GETKBDLAYOUTNAME; +typedef struct +{ + HANDLE ConsoleHandle; + ULONG RegisterFlags; + HANDLE StartHardwareEvent; + HANDLE EndHardwareEvent; + HANDLE ErrorHardwareEvent; + + /* Unused member */ + ULONG UnusedVar; + + ULONG VideoStateLength; + PVOID VideoState; // PVIDEO_HARDWARE_STATE_HEADER + + /* Unused members */ + PVOID UnusedBuffer; + ULONG UnusedBufferLength; + + COORD VDMBufferSize; + PVOID VDMBuffer; +} CONSOLE_REGISTERVDM, *PCONSOLE_REGISTERVDM; + typedef struct _CONSOLE_API_MESSAGE { PORT_MESSAGE Header; @@ -898,6 +925,9 @@ typedef struct _CONSOLE_API_MESSAGE CONSOLE_GETINPUTOUTPUTCP GetConsoleCPRequest; CONSOLE_SETINPUTOUTPUTCP SetConsoleCPRequest; CONSOLE_GETKBDLAYOUTNAME GetKbdLayoutNameRequest; + + /* Virtual DOS Machine */ + CONSOLE_REGISTERVDM RegisterVDMRequest; } Data; } CONSOLE_API_MESSAGE, *PCONSOLE_API_MESSAGE; diff --git a/reactos/win32ss/user/winsrv/consrv/condrv/conoutput.c b/reactos/win32ss/user/winsrv/consrv/condrv/conoutput.c index 42d5cbfdb36..4fe657454f4 100644 --- a/reactos/win32ss/user/winsrv/consrv/condrv/conoutput.c +++ b/reactos/win32ss/user/winsrv/consrv/condrv/conoutput.c @@ -188,7 +188,7 @@ ConDrvSetConsoleActiveScreenBuffer(IN PCONSOLE Console, if (Buffer == Console->ActiveBuffer) return STATUS_SUCCESS; /* If old buffer has no handles, it's now unreferenced */ - if (Console->ActiveBuffer->Header.HandleCount == 0) + if (Console->ActiveBuffer->Header.ReferenceCount == 0) { ConioDeleteScreenBuffer(Console->ActiveBuffer); } @@ -207,6 +207,13 @@ ConDrvGetActiveScreenBuffer(IN PCONSOLE Console) /* PUBLIC DRIVER APIS *********************************************************/ +NTSTATUS NTAPI +ConDrvWriteConsoleOutputVDM(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN PCHAR_CELL CharInfo/*Buffer*/, + IN COORD CharInfoSize, + IN OUT PSMALL_RECT WriteRegion, + IN BOOLEAN DrawRegion); NTSTATUS NTAPI ConDrvInvalidateBitMapRect(IN PCONSOLE Console, IN PCONSOLE_SCREEN_BUFFER Buffer, @@ -218,6 +225,19 @@ ConDrvInvalidateBitMapRect(IN PCONSOLE Console, /* Validity check */ ASSERT(Console == Buffer->Header.Console); + /* In text-mode only, draw the VDM buffer if present */ + if (GetType(Buffer) == TEXTMODE_BUFFER) + { + PTEXTMODE_SCREEN_BUFFER TextBuffer = (PTEXTMODE_SCREEN_BUFFER)Buffer; + + /*Status =*/ ConDrvWriteConsoleOutputVDM(Buffer->Header.Console, + TextBuffer, + Console->VDMBuffer, + Console->VDMBufferSize, + Region, + FALSE); + } + /* If the output buffer is the current one, redraw the correct portion of the screen */ if (Buffer == Console->ActiveBuffer) TermDrawRegion(Console, Region); diff --git a/reactos/win32ss/user/winsrv/consrv/condrv/text.c b/reactos/win32ss/user/winsrv/consrv/condrv/text.c index 96e30035931..6b8dbdcbc8a 100644 --- a/reactos/win32ss/user/winsrv/consrv/condrv/text.c +++ b/reactos/win32ss/user/winsrv/consrv/condrv/text.c @@ -722,6 +722,68 @@ ConDrvWriteConsoleOutput(IN PCONSOLE Console, return STATUS_SUCCESS; } +/* + * NOTE: This function is strongly inspired by ConDrvWriteConsoleOutput... + */ +NTSTATUS NTAPI +ConDrvWriteConsoleOutputVDM(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN PCHAR_CELL CharInfo/*Buffer*/, + IN COORD CharInfoSize, + IN OUT PSMALL_RECT WriteRegion, + IN BOOLEAN DrawRegion) +{ + SHORT X, Y; + SMALL_RECT ScreenBuffer; + PCHAR_CELL CurCharInfo; + SMALL_RECT CapturedWriteRegion; + PCHAR_INFO Ptr; + + if (Console == NULL || Buffer == NULL || CharInfo == NULL || WriteRegion == NULL) + { + return STATUS_INVALID_PARAMETER; + } + + /* Validity check */ + ASSERT(Console == Buffer->Header.Console); + + CapturedWriteRegion = *WriteRegion; + + /* Make sure WriteRegion is inside the screen buffer */ + ConioInitRect(&ScreenBuffer, 0, 0, + Buffer->ScreenBufferSize.Y - 1, Buffer->ScreenBufferSize.X - 1); + if (!ConioGetIntersection(&CapturedWriteRegion, &ScreenBuffer, &CapturedWriteRegion)) + { + /* + * It is okay to have a WriteRegion completely outside + * the screen buffer. No data is written then. + */ + return STATUS_SUCCESS; + } + + // CurCharInfo = CharInfo; + + for (Y = CapturedWriteRegion.Top; Y <= CapturedWriteRegion.Bottom; ++Y) + { + /**/CurCharInfo = CharInfo + Y * CharInfoSize.X + CapturedWriteRegion.Left;/**/ + + Ptr = ConioCoordToPointer(Buffer, CapturedWriteRegion.Left, Y); + for (X = CapturedWriteRegion.Left; X <= CapturedWriteRegion.Right; ++X) + { + ConsoleAnsiCharToUnicodeChar(Console, &Ptr->Char.UnicodeChar, &CurCharInfo->Char); + Ptr->Attributes = CurCharInfo->Attributes; + ++Ptr; + ++CurCharInfo; + } + } + + if (DrawRegion) TermDrawRegion(Console, &CapturedWriteRegion); + + *WriteRegion = CapturedWriteRegion; + + return STATUS_SUCCESS; +} + NTSTATUS NTAPI ConDrvWriteConsole(IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER ScreenBuffer, diff --git a/reactos/win32ss/user/winsrv/consrv/conoutput.c b/reactos/win32ss/user/winsrv/consrv/conoutput.c index 833b3cdbb79..12a4d4d8e00 100644 --- a/reactos/win32ss/user/winsrv/consrv/conoutput.c +++ b/reactos/win32ss/user/winsrv/consrv/conoutput.c @@ -463,15 +463,15 @@ CSR_API(SrvReadConsoleOutput) DPRINT("SrvReadConsoleOutput\n"); + NumCells = (ReadOutputRequest->ReadRegion.Right - ReadOutputRequest->ReadRegion.Left + 1) * + (ReadOutputRequest->ReadRegion.Bottom - ReadOutputRequest->ReadRegion.Top + 1); + /* * For optimization purposes, Windows (and hence ReactOS, too, for * compatibility reasons) uses a static buffer if no more than one * cell is read. Otherwise a new buffer is used. * The client-side expects that we know this behaviour. */ - NumCells = (ReadOutputRequest->ReadRegion.Right - ReadOutputRequest->ReadRegion.Left + 1) * - (ReadOutputRequest->ReadRegion.Bottom - ReadOutputRequest->ReadRegion.Top + 1); - if (NumCells <= 1) { /* @@ -520,54 +520,95 @@ CSR_API(SrvWriteConsoleOutput) NTSTATUS Status; PCONSOLE_WRITEOUTPUT WriteOutputRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.WriteOutputRequest; PTEXTMODE_SCREEN_BUFFER Buffer; + PCSR_PROCESS Process = CsrGetClientThread()->Process; ULONG NumCells; PCHAR_INFO CharInfo; DPRINT("SrvWriteConsoleOutput\n"); - /* - * For optimization purposes, Windows (and hence ReactOS, too, for - * compatibility reasons) uses a static buffer if no more than one - * cell is written. Otherwise a new buffer is used. - * The client-side expects that we know this behaviour. - */ NumCells = (WriteOutputRequest->WriteRegion.Right - WriteOutputRequest->WriteRegion.Left + 1) * (WriteOutputRequest->WriteRegion.Bottom - WriteOutputRequest->WriteRegion.Top + 1); - if (NumCells <= 1) - { - /* - * Adjust the internal pointer, because its old value points to - * the static buffer in the original ApiMessage structure. - */ - // WriteOutputRequest->CharInfo = &WriteOutputRequest->StaticBuffer; - CharInfo = &WriteOutputRequest->StaticBuffer; - } - else - { - if (!CsrValidateMessageBuffer(ApiMessage, - (PVOID*)&WriteOutputRequest->CharInfo, - NumCells, - sizeof(CHAR_INFO))) - { - return STATUS_INVALID_PARAMETER; - } - - CharInfo = WriteOutputRequest->CharInfo; - } - - Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(Process), WriteOutputRequest->OutputHandle, &Buffer, GENERIC_WRITE, TRUE); if (!NT_SUCCESS(Status)) return Status; + /* + * Validate the message buffer if we do not use a process' heap buffer + * (CsrAllocateCaptureBuffer succeeded because we haven't allocated + * a too large (>= 64 kB, size of the CSR heap) data buffer). + */ + if (!WriteOutputRequest->UseVirtualMemory) + { + /* + * For optimization purposes, Windows (and hence ReactOS, too, for + * compatibility reasons) uses a static buffer if no more than one + * cell is written. Otherwise a new buffer is used. + * The client-side expects that we know this behaviour. + */ + if (NumCells <= 1) + { + /* + * Adjust the internal pointer, because its old value points to + * the static buffer in the original ApiMessage structure. + */ + // WriteOutputRequest->CharInfo = &WriteOutputRequest->StaticBuffer; + CharInfo = &WriteOutputRequest->StaticBuffer; + } + else + { + if (!CsrValidateMessageBuffer(ApiMessage, + (PVOID*)&WriteOutputRequest->CharInfo, + NumCells, + sizeof(CHAR_INFO))) + { + Status = STATUS_INVALID_PARAMETER; + goto Quit; + } + + CharInfo = WriteOutputRequest->CharInfo; + } + } + else + { + /* + * This was not the case: we use a heap buffer. Retrieve its contents. + */ + ULONG Size = NumCells * sizeof(CHAR_INFO); + + CharInfo = ConsoleAllocHeap(HEAP_ZERO_MEMORY, Size); + if (CharInfo == NULL) + { + Status = STATUS_NO_MEMORY; + goto Quit; + } + + Status = NtReadVirtualMemory(Process->ProcessHandle, + WriteOutputRequest->CharInfo, + CharInfo, + Size, + NULL); + if (!NT_SUCCESS(Status)) + { + ConsoleFreeHeap(CharInfo); + // Status = STATUS_NO_MEMORY; + goto Quit; + } + } + Status = ConDrvWriteConsoleOutput(Buffer->Header.Console, Buffer, WriteOutputRequest->Unicode, CharInfo, &WriteOutputRequest->WriteRegion); + /* Free the temporary buffer if we used the process' heap buffer */ + if (WriteOutputRequest->UseVirtualMemory && CharInfo) + ConsoleFreeHeap(CharInfo); + +Quit: ConSrvReleaseScreenBuffer(Buffer, TRUE); return Status; } diff --git a/reactos/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c b/reactos/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c index fc229215fe4..2a7ff36cc40 100644 --- a/reactos/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c +++ b/reactos/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c @@ -506,8 +506,8 @@ OnNcCreate(HWND hWnd, LPCREATESTRUCTW Create) GuiData->hWindow = hWnd; - GuiData->Font = CreateFontW(GuiData->GuiInfo.FontSize.X, - 0, // GuiData->GuiInfo.FontSize.Y, + GuiData->Font = CreateFontW(GuiData->GuiInfo.FontSize.Y, + 0, // GuiData->GuiInfo.FontSize.X, 0, TA_BASELINE, GuiData->GuiInfo.FontWeight, diff --git a/reactos/win32ss/user/winsrv/consrv/frontends/gui/guisettings.c b/reactos/win32ss/user/winsrv/consrv/frontends/gui/guisettings.c index 3220152419a..a3969fe3a23 100644 --- a/reactos/win32ss/user/winsrv/consrv/frontends/gui/guisettings.c +++ b/reactos/win32ss/user/winsrv/consrv/frontends/gui/guisettings.c @@ -98,8 +98,8 @@ GuiConsoleReadUserSettings(IN OUT PGUI_CONSOLE_INFO TermInfo, } else if (!wcscmp(szValueName, L"FontSize")) { - TermInfo->FontSize.X = LOWORD(Value); - TermInfo->FontSize.Y = HIWORD(Value); + TermInfo->FontSize.X = LOWORD(Value); // Width + TermInfo->FontSize.Y = HIWORD(Value); // Height RetVal = TRUE; } else if (!wcscmp(szValueName, L"FontWeight")) @@ -161,7 +161,7 @@ do { SetConsoleSetting(L"FaceName", REG_SZ, (wcslen(TermInfo->FaceName) + 1) * sizeof(WCHAR), TermInfo->FaceName, L'\0'); // wcsnlen SetConsoleSetting(L"FontFamily", REG_DWORD, sizeof(DWORD), &TermInfo->FontFamily, FF_DONTCARE); - Storage = MAKELONG(TermInfo->FontSize.X, TermInfo->FontSize.Y); + Storage = MAKELONG(TermInfo->FontSize.X, TermInfo->FontSize.Y); // Width, Height SetConsoleSetting(L"FontSize", REG_DWORD, sizeof(DWORD), &Storage, 0); SetConsoleSetting(L"FontWeight", REG_DWORD, sizeof(DWORD), &TermInfo->FontWeight, FW_DONTCARE); @@ -197,7 +197,7 @@ GuiConsoleGetDefaultSettings(IN OUT PGUI_CONSOLE_INFO TermInfo, * 1. Load the default values */ // wcsncpy(TermInfo->FaceName, L"DejaVu Sans Mono", LF_FACESIZE); - // TermInfo->FontSize = MAKELONG(12, 8); // 0x0008000C; // font is 8x12 + // TermInfo->FontSize = MAKELONG(8, 12); // 0x000C0008; // font is 8x12 // TermInfo->FontSize = MAKELONG(16, 16); // font is 16x16 // TermInfo->FontWeight = FW_NORMAL; @@ -207,7 +207,6 @@ GuiConsoleGetDefaultSettings(IN OUT PGUI_CONSOLE_INFO TermInfo, TermInfo->FontSize.X = 0; TermInfo->FontSize.Y = 0; TermInfo->FontWeight = FW_DONTCARE; - TermInfo->UseRasterFonts = TRUE; TermInfo->FullScreen = FALSE; TermInfo->ShowWindow = SW_SHOWNORMAL; @@ -333,7 +332,6 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData, GuiInfo->FontFamily = GuiData->GuiInfo.FontFamily; GuiInfo->FontSize = GuiData->GuiInfo.FontSize; GuiInfo->FontWeight = GuiData->GuiInfo.FontWeight; - GuiInfo->UseRasterFonts = GuiData->GuiInfo.UseRasterFonts; GuiInfo->FullScreen = GuiData->GuiInfo.FullScreen; GuiInfo->AutoPosition = GuiData->GuiInfo.AutoPosition; GuiInfo->WindowOrigin = GuiData->GuiInfo.WindowOrigin; @@ -420,6 +418,92 @@ Quit: return; } + + + +BOOL +ChangeFont(PGUI_CONSOLE_DATA GuiData, + LPWSTR FaceName, // Points to a WCHAR array of LF_FACESIZE elements. + ULONG FontFamily, + COORD FontSize, + ULONG FontWeight) +{ + HDC hDC; + HFONT OldFont, NewFont; + TEXTMETRICW Metrics; + SIZE CharSize; + SIZE_T Length; + + NewFont = CreateFontW(FontSize.Y, + 0, // FontSize.X, + 0, + TA_BASELINE, + FontWeight, + FALSE, + FALSE, + FALSE, + OEM_CHARSET, + OUT_DEFAULT_PRECIS, + CLIP_DEFAULT_PRECIS, + NONANTIALIASED_QUALITY, + FIXED_PITCH | FontFamily /* FF_DONTCARE */, + FaceName); + if (NewFont == NULL) + { + DPRINT1("ChangeFont: CreateFont failed\n"); + return FALSE; + } + + hDC = GetDC(GuiData->hWindow); + if (hDC == NULL) + { + DPRINT1("ChangeFont: GetDC failed\n"); + DeleteObject(NewFont); + return FALSE; + } + + OldFont = SelectObject(hDC, NewFont); + if (OldFont == NULL) + { + DPRINT1("ChangeFont: SelectObject failed\n"); + ReleaseDC(GuiData->hWindow, hDC); + DeleteObject(NewFont); + return FALSE; + } + + if (!GetTextMetricsW(hDC, &Metrics)) + { + DPRINT1("ChangeFont: GetTextMetrics failed\n"); + SelectObject(hDC, OldFont); + ReleaseDC(GuiData->hWindow, hDC); + DeleteObject(NewFont); + return FALSE; + } + GuiData->CharWidth = Metrics.tmMaxCharWidth; + GuiData->CharHeight = Metrics.tmHeight + Metrics.tmExternalLeading; + + /* Measure real char width more precisely if possible. */ + if (GetTextExtentPoint32W(hDC, L"R", 1, &CharSize)) + GuiData->CharWidth = CharSize.cx; + + SelectObject(hDC, OldFont); + ReleaseDC(GuiData->hWindow, hDC); + + if (GuiData->Font != NULL) DeleteObject(GuiData->Font); + GuiData->Font = NewFont; + + Length = min(wcslen(FaceName) + 1, LF_FACESIZE); // wcsnlen + wcsncpy(GuiData->GuiInfo.FaceName, FaceName, LF_FACESIZE); + GuiData->GuiInfo.FaceName[Length] = L'\0'; // NULL-terminate + GuiData->GuiInfo.FontFamily = FontFamily; + GuiData->GuiInfo.FontSize = FontSize; + GuiData->GuiInfo.FontWeight = FontWeight; + + return TRUE; +} + + + VOID GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData, HANDLE hClientSection, @@ -501,6 +585,15 @@ GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData, // memcpy(&GuiData->GuiInfo, GuiInfo, sizeof(GUI_CONSOLE_INFO)); + /* Change the font */ + ChangeFont(GuiData, + GuiInfo->FaceName, + GuiInfo->FontFamily, + GuiInfo->FontSize, + GuiInfo->FontWeight); + // HACK, needed because changing font may change the size of the window + /**/TermResizeTerminal(Console);/**/ + /* Move the window to the user's values */ GuiData->GuiInfo.AutoPosition = GuiInfo->AutoPosition; GuiData->GuiInfo.WindowOrigin = GuiInfo->WindowOrigin; @@ -655,7 +748,6 @@ GuiApplyWindowsConsoleSettings(PGUI_CONSOLE_DATA GuiData, GuiInfo.FullScreen = !!pConInfo->FullScreen; GuiInfo.AutoPosition = !!pConInfo->AutoPosition; GuiInfo.WindowOrigin = pConInfo->WindowPosition; - // BOOL GuiInfo.UseRasterFonts = pConInfo-> // WORD GuiInfo.ShowWindow = pConInfo-> @@ -675,6 +767,15 @@ GuiApplyWindowsConsoleSettings(PGUI_CONSOLE_DATA GuiData, // memcpy(&GuiData->GuiInfo, &GuiInfo, sizeof(GUI_CONSOLE_INFO)); + /* Change the font */ + ChangeFont(GuiData, + GuiInfo.FaceName, + GuiInfo.FontFamily, + GuiInfo.FontSize, + GuiInfo.FontWeight); + // HACK, needed because changing font may change the size of the window + /**/TermResizeTerminal(Console);/**/ + /* Move the window to the user's values */ GuiData->GuiInfo.AutoPosition = GuiInfo.AutoPosition; GuiData->GuiInfo.WindowOrigin = GuiInfo.WindowOrigin; diff --git a/reactos/win32ss/user/winsrv/consrv/frontends/gui/guisettings.h b/reactos/win32ss/user/winsrv/consrv/frontends/gui/guisettings.h index ff8a91265d8..df95bdc28c2 100644 --- a/reactos/win32ss/user/winsrv/consrv/frontends/gui/guisettings.h +++ b/reactos/win32ss/user/winsrv/consrv/frontends/gui/guisettings.h @@ -34,7 +34,6 @@ typedef struct _GUI_CONSOLE_INFO ULONG FontFamily; COORD FontSize; ULONG FontWeight; - BOOL UseRasterFonts; BOOL FullScreen; /* Whether the console is displayed in full-screen or windowed mode */ // ULONG HardwareState; /* _GDI_MANAGED, _DIRECT */ diff --git a/reactos/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c b/reactos/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c index 6fb343a324d..8b6bc26bd67 100644 --- a/reactos/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c +++ b/reactos/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c @@ -486,13 +486,15 @@ GuiInitFrontEnd(IN OUT PFRONTEND This, * Set up GUI data */ + // Font data Length = min(wcslen(TermInfo.FaceName) + 1, LF_FACESIZE); // wcsnlen wcsncpy(GuiData->GuiInfo.FaceName, TermInfo.FaceName, LF_FACESIZE); GuiData->GuiInfo.FaceName[Length] = L'\0'; GuiData->GuiInfo.FontFamily = TermInfo.FontFamily; GuiData->GuiInfo.FontSize = TermInfo.FontSize; GuiData->GuiInfo.FontWeight = TermInfo.FontWeight; - GuiData->GuiInfo.UseRasterFonts = TermInfo.UseRasterFonts; + + // Display GuiData->GuiInfo.FullScreen = TermInfo.FullScreen; GuiData->GuiInfo.ShowWindow = TermInfo.ShowWindow; GuiData->GuiInfo.AutoPosition = TermInfo.AutoPosition; diff --git a/reactos/win32ss/user/winsrv/consrv/frontends/gui/text.c b/reactos/win32ss/user/winsrv/consrv/frontends/gui/text.c index 078cb40fe03..50ebbb6d899 100644 --- a/reactos/win32ss/user/winsrv/consrv/frontends/gui/text.c +++ b/reactos/win32ss/user/winsrv/consrv/frontends/gui/text.c @@ -24,7 +24,8 @@ /* FUNCTIONS ******************************************************************/ -COLORREF PaletteRGBFromAttrib(PCONSOLE Console, WORD Attribute) +static COLORREF +PaletteRGBFromAttrib(PCONSOLE Console, WORD Attribute) { HPALETTE hPalette = Console->ActiveBuffer->PaletteHandle; PALETTEENTRY pe; @@ -35,6 +36,44 @@ COLORREF PaletteRGBFromAttrib(PCONSOLE Console, WORD Attribute) return PALETTERGB(pe.peRed, pe.peGreen, pe.peBlue); } +static HFONT +ChangeFontAttributes(PGUI_CONSOLE_DATA GuiData, + // COORD FontSize, + ULONG FontWeight, + BOOLEAN bItalic, + BOOLEAN bUnderline, + BOOLEAN bStrikeOut) +{ + HFONT NewFont; + LOGFONT lf; + + /* Initialize the LOGFONT structure */ + RtlZeroMemory(&lf, sizeof(lf)); + + /* Retrieve the details of the current font */ + if (GetObject(GuiData->Font, sizeof(lf), &lf) == 0) + return NULL; // GuiData->Font; + + /* Change the font attributes */ + // lf.lfHeight = FontSize.Y; + // lf.lfWidth = FontSize.X; + lf.lfWeight = FontWeight; + lf.lfItalic = bItalic; + lf.lfUnderline = bUnderline; + lf.lfStrikeOut = bStrikeOut; + + /* Build a new font */ + NewFont = CreateFontIndirect(&lf); + if (NewFont == NULL) + return NULL; // GuiData->Font; + + // FIXME: Do we need to update GuiData->CharWidth and GuiData->CharHeight ?? + + /* Select it (return the old font) */ + // return SelectObject(GuiData->hMemDC, NewFont); + return NewFont; +} + static VOID CopyBlock(PTEXTMODE_SCREEN_BUFFER Buffer, PSMALL_RECT Selection) @@ -348,7 +387,8 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, WORD LastAttribute, Attribute; ULONG CursorX, CursorY, CursorHeight; HBRUSH CursorBrush, OldBrush; - HFONT OldFont; + HFONT OldFont, NewFont; + BOOLEAN IsUnderscore; if (Buffer->Buffer == NULL) return; @@ -372,7 +412,18 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, SetTextColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, TextAttribFromAttrib(LastAttribute))); SetBkColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, BkgdAttribFromAttrib(LastAttribute))); - OldFont = SelectObject(GuiData->hMemDC, GuiData->Font); + // OldFont = ChangeFontAttributes(GuiData, /* {0}, */ GuiData->GuiInfo.FontWeight, FALSE, FALSE, FALSE); + IsUnderscore = !!(LastAttribute & COMMON_LVB_UNDERSCORE); + NewFont = ChangeFontAttributes(GuiData, /* {0}, */ GuiData->GuiInfo.FontWeight, + FALSE, + IsUnderscore, + FALSE); + if (NewFont == NULL) + { + DPRINT1("ChangeFontAttributes failed, use the original font\n"); + NewFont = GuiData->Font; + } + OldFont = SelectObject(GuiData->hMemDC, NewFont); for (Line = TopLine; Line <= BottomLine; Line++) { @@ -399,9 +450,31 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, Attribute = From->Attributes; if (Attribute != LastAttribute) { - SetTextColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, TextAttribFromAttrib(Attribute))); - SetBkColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, BkgdAttribFromAttrib(Attribute))); LastAttribute = Attribute; + SetTextColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, TextAttribFromAttrib(LastAttribute))); + SetBkColor(GuiData->hMemDC, PaletteRGBFromAttrib(Console, BkgdAttribFromAttrib(LastAttribute))); + + /* Change underscore state if needed */ + if (!!(LastAttribute & COMMON_LVB_UNDERSCORE) != IsUnderscore) + { + IsUnderscore = !!(LastAttribute & COMMON_LVB_UNDERSCORE); + + /* Delete the font we used up to now */ + // SelectObject(GuiData->hMemDC, OldFont); + if (NewFont != GuiData->Font) DeleteObject(NewFont); + /* Recreate it */ + NewFont = ChangeFontAttributes(GuiData, /* {0}, */ GuiData->GuiInfo.FontWeight, + FALSE, + IsUnderscore, + FALSE); + if (NewFont == NULL) + { + DPRINT1("ChangeFontAttributes failed, use the original font\n"); + NewFont = GuiData->Font; + } + /* Select it */ + /* OldFont = */ SelectObject(GuiData->hMemDC, NewFont); + } } } @@ -441,12 +514,15 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, GuiData->CharWidth, CursorHeight, PATCOPY); + SelectObject(GuiData->hMemDC, OldBrush); DeleteObject(CursorBrush); } } + /* Restore the old font and delete the font we used up to now */ SelectObject(GuiData->hMemDC, OldFont); + if (NewFont != GuiData->Font) DeleteObject(NewFont); LeaveCriticalSection(&Console->Lock); } diff --git a/reactos/win32ss/user/winsrv/consrv/handle.c b/reactos/win32ss/user/winsrv/consrv/handle.c index 721f3375558..a114411fc80 100644 --- a/reactos/win32ss/user/winsrv/consrv/handle.c +++ b/reactos/win32ss/user/winsrv/consrv/handle.c @@ -19,53 +19,45 @@ /* GLOBALS ********************************************************************/ +/* Console handle */ typedef struct _CONSOLE_IO_HANDLE { PCONSOLE_IO_OBJECT Object; /* The object on which the handle points to */ - DWORD Access; - BOOL Inheritable; - DWORD ShareMode; + ULONG Access; + ULONG ShareMode; + BOOLEAN Inheritable; } CONSOLE_IO_HANDLE, *PCONSOLE_IO_HANDLE; /* PRIVATE FUNCTIONS **********************************************************/ -static INT -AdjustHandleCounts(PCONSOLE_IO_HANDLE Entry, INT Change) +static LONG +AdjustHandleCounts(IN PCONSOLE_IO_HANDLE Handle, + IN LONG Change) { - PCONSOLE_IO_OBJECT Object = Entry->Object; + PCONSOLE_IO_OBJECT Object = Handle->Object; - DPRINT("AdjustHandleCounts(0x%p, %d), Object = 0x%p\n", Entry, Change, Object); - DPRINT("\tAdjustHandleCounts(0x%p, %d), Object = 0x%p, Object->HandleCount = %d, Object->Type = %lu\n", Entry, Change, Object, Object->HandleCount, Object->Type); + DPRINT("AdjustHandleCounts(0x%p, %d), Object = 0x%p\n", + Handle, Change, Object); + DPRINT("\tAdjustHandleCounts(0x%p, %d), Object = 0x%p, Object->ReferenceCount = %d, Object->Type = %lu\n", + Handle, Change, Object, Object->ReferenceCount, Object->Type); - if (Entry->Access & GENERIC_READ) Object->AccessRead += Change; - if (Entry->Access & GENERIC_WRITE) Object->AccessWrite += Change; - if (!(Entry->ShareMode & FILE_SHARE_READ)) Object->ExclusiveRead += Change; - if (!(Entry->ShareMode & FILE_SHARE_WRITE)) Object->ExclusiveWrite += Change; + if (Handle->Access & GENERIC_READ) Object->AccessRead += Change; + if (Handle->Access & GENERIC_WRITE) Object->AccessWrite += Change; + if (!(Handle->ShareMode & FILE_SHARE_READ)) Object->ExclusiveRead += Change; + if (!(Handle->ShareMode & FILE_SHARE_WRITE)) Object->ExclusiveWrite += Change; - Object->HandleCount += Change; + Object->ReferenceCount += Change; - return Object->HandleCount; + return Object->ReferenceCount; } static VOID -ConSrvCreateHandleEntry(PCONSOLE_IO_HANDLE Entry) +ConSrvCloseHandle(IN PCONSOLE_IO_HANDLE Handle) { - /// LOCK /// PCONSOLE_IO_OBJECT Object = Entry->Object; - /// LOCK /// EnterCriticalSection(&Object->Console->Lock); - AdjustHandleCounts(Entry, +1); - /// LOCK /// LeaveCriticalSection(&Object->Console->Lock); -} - -static VOID -ConSrvCloseHandleEntry(PCONSOLE_IO_HANDLE Entry) -{ - PCONSOLE_IO_OBJECT Object = Entry->Object; + PCONSOLE_IO_OBJECT Object = Handle->Object; if (Object != NULL) { - /// LOCK /// PCONSOLE Console = Object->Console; - /// LOCK /// EnterCriticalSection(&Console->Lock); - /* * If this is a input handle, notify and dereference * all the waits related to this handle. @@ -87,7 +79,7 @@ ConSrvCloseHandleEntry(PCONSOLE_IO_HANDLE Entry) CsrNotifyWait(&Console->ReadWaitQueue, TRUE, NULL, - (PVOID)Entry); + (PVOID)Handle); if (!IsListEmpty(&Console->ReadWaitQueue)) { CsrDereferenceWait(&Console->ReadWaitQueue); @@ -95,7 +87,7 @@ ConSrvCloseHandleEntry(PCONSOLE_IO_HANDLE Entry) } /* If the last handle to a screen buffer is closed, delete it... */ - if (AdjustHandleCounts(Entry, -1) == 0) + if (AdjustHandleCounts(Handle, -1) == 0) { if (Object->Type == TEXTMODE_BUFFER || Object->Type == GRAPHICS_BUFFER) { @@ -116,16 +108,18 @@ ConSrvCloseHandleEntry(PCONSOLE_IO_HANDLE Entry) } } - /// LOCK /// LeaveCriticalSection(&Console->Lock); - /* Invalidate (zero-out) this handle entry */ - // Entry->Object = NULL; - // RtlZeroMemory(Entry, sizeof(*Entry)); + // Handle->Object = NULL; + // RtlZeroMemory(Handle, sizeof(*Handle)); } - RtlZeroMemory(Entry, sizeof(*Entry)); // Be sure the whole entry is invalidated. + RtlZeroMemory(Handle, sizeof(*Handle)); // Be sure the whole entry is invalidated. } + + + + /* Forward declaration, used in ConSrvInitHandlesTable */ static VOID ConSrvFreeHandlesTable(PCONSOLE_PROCESS_DATA ProcessData); @@ -244,10 +238,10 @@ ConSrvInheritHandlesTable(IN PCONSOLE_PROCESS_DATA SourceProcessData, { /* * Copy the handle data and increment the reference count of the - * pointed object (via the call to ConSrvCreateHandleEntry). + * pointed object (via the call to ConSrvCreateHandleEntry == AdjustHandleCounts). */ TargetProcessData->HandleTable[j] = SourceProcessData->HandleTable[i]; - ConSrvCreateHandleEntry(&TargetProcessData->HandleTable[j]); + AdjustHandleCounts(&TargetProcessData->HandleTable[j], +1); ++j; } } @@ -258,7 +252,7 @@ Quit: } static VOID -ConSrvFreeHandlesTable(PCONSOLE_PROCESS_DATA ProcessData) +ConSrvFreeHandlesTable(IN PCONSOLE_PROCESS_DATA ProcessData) { RtlEnterCriticalSection(&ProcessData->HandleTableLock); @@ -277,7 +271,7 @@ ConSrvFreeHandlesTable(PCONSOLE_PROCESS_DATA ProcessData) /* Close all the console handles */ for (i = 0; i < ProcessData->HandleTableSize; i++) { - ConSrvCloseHandleEntry(&ProcessData->HandleTable[i]); + ConSrvCloseHandle(&ProcessData->HandleTable[i]); } } /* Free the handles table memory */ @@ -290,6 +284,12 @@ ConSrvFreeHandlesTable(PCONSOLE_PROCESS_DATA ProcessData) RtlLeaveCriticalSection(&ProcessData->HandleTableLock); } + + + + + +// ConSrvCreateObject VOID ConSrvInitObject(IN OUT PCONSOLE_IO_OBJECT Object, IN CONSOLE_IO_OBJECT_TYPE Type, @@ -300,18 +300,19 @@ ConSrvInitObject(IN OUT PCONSOLE_IO_OBJECT Object, Object->Type = Type; Object->Console = Console; + Object->ReferenceCount = 0; + Object->AccessRead = Object->AccessWrite = 0; Object->ExclusiveRead = Object->ExclusiveWrite = 0; - Object->HandleCount = 0; } NTSTATUS -ConSrvInsertObject(PCONSOLE_PROCESS_DATA ProcessData, - PHANDLE Handle, - PCONSOLE_IO_OBJECT Object, - DWORD Access, - BOOL Inheritable, - DWORD ShareMode) +ConSrvInsertObject(IN PCONSOLE_PROCESS_DATA ProcessData, + OUT PHANDLE Handle, + IN PCONSOLE_IO_OBJECT Object, + IN ULONG Access, + IN BOOLEAN Inheritable, + IN ULONG ShareMode) { #define IO_HANDLES_INCREMENT 2 * 3 @@ -362,7 +363,7 @@ ConSrvInsertObject(PCONSOLE_PROCESS_DATA ProcessData, ProcessData->HandleTable[i].Access = Access; ProcessData->HandleTable[i].Inheritable = Inheritable; ProcessData->HandleTable[i].ShareMode = ShareMode; - ConSrvCreateHandleEntry(&ProcessData->HandleTable[i]); + AdjustHandleCounts(&ProcessData->HandleTable[i], +1); *Handle = ULongToHandle((i << 2) | 0x3); // RtlLeaveCriticalSection(&ProcessData->HandleTableLock); @@ -371,8 +372,8 @@ ConSrvInsertObject(PCONSOLE_PROCESS_DATA ProcessData, } NTSTATUS -ConSrvRemoveObject(PCONSOLE_PROCESS_DATA ProcessData, - HANDLE Handle) +ConSrvRemoveObject(IN PCONSOLE_PROCESS_DATA ProcessData, + IN HANDLE Handle) { ULONG Index = HandleToULong(Handle) >> 2; @@ -390,20 +391,20 @@ ConSrvRemoveObject(PCONSOLE_PROCESS_DATA ProcessData, } ASSERT(ProcessData->ConsoleHandle); - ConSrvCloseHandleEntry(&ProcessData->HandleTable[Index]); + ConSrvCloseHandle(&ProcessData->HandleTable[Index]); RtlLeaveCriticalSection(&ProcessData->HandleTableLock); return STATUS_SUCCESS; } NTSTATUS -ConSrvGetObject(PCONSOLE_PROCESS_DATA ProcessData, - HANDLE Handle, - PCONSOLE_IO_OBJECT* Object, - PVOID* Entry OPTIONAL, - DWORD Access, - BOOL LockConsole, - CONSOLE_IO_OBJECT_TYPE Type) +ConSrvGetObject(IN PCONSOLE_PROCESS_DATA ProcessData, + IN HANDLE Handle, + OUT PCONSOLE_IO_OBJECT* Object, + OUT PVOID* Entry OPTIONAL, + IN ULONG Access, + IN BOOLEAN LockConsole, + IN CONSOLE_IO_OBJECT_TYPE Type) { // NTSTATUS Status; ULONG Index = HandleToULong(Handle) >> 2; @@ -461,12 +462,17 @@ ConSrvGetObject(PCONSOLE_PROCESS_DATA ProcessData, } VOID -ConSrvReleaseObject(PCONSOLE_IO_OBJECT Object, - BOOL IsConsoleLocked) +ConSrvReleaseObject(IN PCONSOLE_IO_OBJECT Object, + IN BOOLEAN IsConsoleLocked) { ConSrvReleaseConsole(Object->Console, IsConsoleLocked); } + + + + + NTSTATUS ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData, PHANDLE pInputHandle, @@ -548,7 +554,7 @@ ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData, NTSTATUS ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData, HANDLE ConsoleHandle, - BOOL CreateNewHandlesTable, + BOOLEAN CreateNewHandlesTable, PHANDLE pInputHandle, PHANDLE pOutputHandle, PHANDLE pErrorHandle) @@ -826,7 +832,7 @@ CSR_API(SrvDuplicateHandle) (DuplicateHandleRequest->Options & DUPLICATE_CLOSE_SOURCE)) { /* Close the original handle if needed */ - ConSrvCloseHandleEntry(Entry); + ConSrvCloseHandle(Entry); } Quit: diff --git a/reactos/win32ss/user/winsrv/consrv/handle.h b/reactos/win32ss/user/winsrv/consrv/handle.h index 2e75f884a4b..d154c5cc17c 100644 --- a/reactos/win32ss/user/winsrv/consrv/handle.h +++ b/reactos/win32ss/user/winsrv/consrv/handle.h @@ -10,23 +10,28 @@ #pragma once -VOID ConSrvInitObject(IN OUT PCONSOLE_IO_OBJECT Object, - IN CONSOLE_IO_OBJECT_TYPE Type, - IN PCONSOLE Console); -NTSTATUS ConSrvInsertObject(PCONSOLE_PROCESS_DATA ProcessData, - PHANDLE Handle, - PCONSOLE_IO_OBJECT Object, - DWORD Access, - BOOL Inheritable, - DWORD ShareMode); -NTSTATUS ConSrvRemoveObject(PCONSOLE_PROCESS_DATA ProcessData, - HANDLE Handle); -NTSTATUS ConSrvGetObject(PCONSOLE_PROCESS_DATA ProcessData, - HANDLE Handle, - PCONSOLE_IO_OBJECT* Object, - PVOID* Entry OPTIONAL, - DWORD Access, - BOOL LockConsole, - CONSOLE_IO_OBJECT_TYPE Type); -VOID ConSrvReleaseObject(PCONSOLE_IO_OBJECT Object, - BOOL IsConsoleLocked); +VOID +ConSrvInitObject(IN OUT PCONSOLE_IO_OBJECT Object, + IN CONSOLE_IO_OBJECT_TYPE Type, + IN PCONSOLE Console); +NTSTATUS +ConSrvInsertObject(IN PCONSOLE_PROCESS_DATA ProcessData, + OUT PHANDLE Handle, + IN PCONSOLE_IO_OBJECT Object, + IN ULONG Access, + IN BOOLEAN Inheritable, + IN ULONG ShareMode); +NTSTATUS +ConSrvRemoveObject(IN PCONSOLE_PROCESS_DATA ProcessData, + IN HANDLE Handle); +NTSTATUS +ConSrvGetObject(IN PCONSOLE_PROCESS_DATA ProcessData, + IN HANDLE Handle, + OUT PCONSOLE_IO_OBJECT* Object, + OUT PVOID* Entry OPTIONAL, + IN ULONG Access, + IN BOOLEAN LockConsole, + IN CONSOLE_IO_OBJECT_TYPE Type); +VOID +ConSrvReleaseObject(IN PCONSOLE_IO_OBJECT Object, + IN BOOLEAN IsConsoleLocked); diff --git a/reactos/win32ss/user/winsrv/consrv/include/conio.h b/reactos/win32ss/user/winsrv/consrv/include/conio.h index 90defe0ea42..8d3dc9f6a4d 100644 --- a/reactos/win32ss/user/winsrv/consrv/include/conio.h +++ b/reactos/win32ss/user/winsrv/consrv/include/conio.h @@ -19,23 +19,35 @@ #define DEFAULT_POPUP_ATTRIB (FOREGROUND_BLUE | FOREGROUND_RED | \ BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY) +/* VGA character cell */ +typedef struct _CHAR_CELL +{ + CHAR Char; + BYTE Attributes; +} CHAR_CELL, *PCHAR_CELL; +C_ASSERT(sizeof(CHAR_CELL) == 2); + + /* Object type magic numbers */ typedef enum _CONSOLE_IO_OBJECT_TYPE { -// ANY_TYPE_BUFFER = 0x00, // --> Match any types of IO handles - TEXTMODE_BUFFER = 0x01, // --> Output-type handles for text SBs - GRAPHICS_BUFFER = 0x02, // --> Output-type handles for graphics SBs + UNKNOWN = 0x00, // --> Unknown object + TEXTMODE_BUFFER = 0x01, // --> Output-type object for text SBs + GRAPHICS_BUFFER = 0x02, // --> Output-type object for graphics SBs SCREEN_BUFFER = 0x03, // --> Any SB type - INPUT_BUFFER = 0x04 // --> Input-type handles + INPUT_BUFFER = 0x04, // --> Input-type object + ANY_TYPE_BUFFER = 0x07, // --> Any IO object } CONSOLE_IO_OBJECT_TYPE; typedef struct _CONSOLE_IO_OBJECT { CONSOLE_IO_OBJECT_TYPE Type; + struct _CONSOLE* /* PCONSOLE */ Console; + LONG ReferenceCount; /* Is incremented each time a console object gets referenced */ + LONG AccessRead, AccessWrite; LONG ExclusiveRead, ExclusiveWrite; - LONG HandleCount; } CONSOLE_IO_OBJECT, *PCONSOLE_IO_OBJECT; @@ -300,6 +312,17 @@ typedef struct _CONSOLE PCONSOLE_SCREEN_BUFFER ActiveBuffer; /* Pointer to currently active screen buffer */ UINT OutputCodePage; + /**** Per-console Virtual DOS Machine Text-mode Buffer ****/ + COORD VDMBufferSize; /* Real size of the VDM buffer, in units of ??? */ + HANDLE VDMBufferSection; /* Handle to the memory shared section for the VDM buffer */ + PVOID VDMBuffer; /* Our VDM buffer */ + PVOID ClientVDMBuffer; /* A copy of the client view of our VDM buffer */ + HANDLE VDMClientProcess; /* Handle to the client process who opened the buffer, to unmap the view */ + + HANDLE StartHardwareEvent; + HANDLE EndHardwareEvent; + HANDLE ErrorHardwareEvent; + /****************************** Other properties ******************************/ UNICODE_STRING OriginalTitle; /* Original title of console, the one defined when the console leader is launched; it never changes. Always NULL-terminated */ UNICODE_STRING Title; /* Title of console. Always NULL-terminated */ diff --git a/reactos/win32ss/user/winsrv/consrv/include/conio_winsrv.h b/reactos/win32ss/user/winsrv/consrv/include/conio_winsrv.h index aba4715a2b8..4669dae0255 100644 --- a/reactos/win32ss/user/winsrv/consrv/include/conio_winsrv.h +++ b/reactos/win32ss/user/winsrv/consrv/include/conio_winsrv.h @@ -83,6 +83,7 @@ struct _FRONTEND PFRONTEND_VTBL Vtbl; /* Virtual table */ NTSTATUS (NTAPI *UnloadFrontEnd)(IN OUT PFRONTEND This); + // struct _WINSRV_CONSOLE* struct _CONSOLE* Console; /* Console to which the frontend is attached to */ PVOID Data; /* Private data */ PVOID OldData; /* Reserved */ diff --git a/reactos/win32ss/user/winsrv/consrv/include/settings.h b/reactos/win32ss/user/winsrv/consrv/include/settings.h index be00e502073..fcef0f18b58 100644 --- a/reactos/win32ss/user/winsrv/consrv/include/settings.h +++ b/reactos/win32ss/user/winsrv/consrv/include/settings.h @@ -51,10 +51,14 @@ typedef struct _CONSOLE_INFO WCHAR ConsoleTitle[MAX_PATH + 1]; } CONSOLE_INFO, *PCONSOLE_INFO; +/* + * BYTE Foreground = LOBYTE(Attributes) & 0x0F; + * BYTE Background = (LOBYTE(Attributes) & 0xF0) >> 4; + */ #define RGBFromAttrib(Console, Attribute) ((Console)->Colors[(Attribute) & 0xF]) -#define TextAttribFromAttrib(Attribute) ((Attribute) & 0xF) -#define BkgdAttribFromAttrib(Attribute) (((Attribute) >> 4) & 0xF) -#define MakeAttrib(TextAttrib, BkgdAttrib) (DWORD)((((BkgdAttrib) & 0xF) << 4) | ((TextAttrib) & 0xF)) +#define TextAttribFromAttrib(Attribute) ( !((Attribute) & COMMON_LVB_REVERSE_VIDEO) ? (Attribute) & 0xF : ((Attribute) >> 4) & 0xF ) +#define BkgdAttribFromAttrib(Attribute) ( !((Attribute) & COMMON_LVB_REVERSE_VIDEO) ? ((Attribute) >> 4) & 0xF : (Attribute) & 0xF ) +#define MakeAttrib(TextAttrib, BkgdAttrib) (USHORT)((((BkgdAttrib) & 0xF) << 4) | ((TextAttrib) & 0xF)) /* * Structure used to communicate with console.dll diff --git a/reactos/win32ss/user/winsrv/consrv/procinit.h b/reactos/win32ss/user/winsrv/consrv/procinit.h index 9c7186667dd..493415156eb 100644 --- a/reactos/win32ss/user/winsrv/consrv/procinit.h +++ b/reactos/win32ss/user/winsrv/consrv/procinit.h @@ -15,7 +15,7 @@ NTSTATUS ConSrvAllocateConsole(PCONSOLE_PROCESS_DATA ProcessData, PCONSOLE_START_INFO ConsoleStartInfo); NTSTATUS ConSrvInheritConsole(PCONSOLE_PROCESS_DATA ProcessData, HANDLE ConsoleHandle, - BOOL CreateNewHandlesTable, + BOOLEAN CreateNewHandlesTable, PHANDLE pInputHandle, PHANDLE pOutputHandle, PHANDLE pErrorHandle); diff --git a/reactos/win32ss/user/winsrv/consrv/subsysreg.c b/reactos/win32ss/user/winsrv/consrv/subsysreg.c index 0ba10afce3a..40f974040c1 100644 --- a/reactos/win32ss/user/winsrv/consrv/subsysreg.c +++ b/reactos/win32ss/user/winsrv/consrv/subsysreg.c @@ -21,8 +21,132 @@ CSR_API(SrvRegisterConsoleVDM) { - DPRINT1("%s not yet implemented\n", __FUNCTION__); - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + PCONSOLE_REGISTERVDM RegisterVDMRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.RegisterVDMRequest; + PCONSOLE Console; + + DPRINT1("SrvRegisterConsoleVDM(%d)\n", RegisterVDMRequest->RegisterFlags); + + Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + &Console, TRUE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Can't get console\n"); + return Status; + } + + if (RegisterVDMRequest->RegisterFlags != 0) + { + LARGE_INTEGER SectionSize; + ULONG Size, ViewSize = 0; + HANDLE ProcessHandle; + + /* + * Remember the handle to the process so that we can close or unmap + * correctly the allocated resources when the client releases the + * screen buffer. + */ + ProcessHandle = CsrGetClientThread()->Process->ProcessHandle; + Console->VDMClientProcess = ProcessHandle; + + Console->VDMBufferSize = RegisterVDMRequest->VDMBufferSize; + + Size = Console->VDMBufferSize.X * Console->VDMBufferSize.Y + * sizeof(CHAR_CELL); + + /* + * Create a memory section for the VDM buffer, to share with the client. + */ + SectionSize.QuadPart = Size; + Status = NtCreateSection(&Console->VDMBufferSection, + SECTION_ALL_ACCESS, + NULL, + &SectionSize, + PAGE_READWRITE, + SEC_COMMIT, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Error: Impossible to create a shared section ; Status = %lu\n", Status); + goto Quit; + } + + /* + * Create a view for our needs. + */ + ViewSize = 0; + Console->VDMBuffer = NULL; + Status = NtMapViewOfSection(Console->VDMBufferSection, + NtCurrentProcess(), + (PVOID*)&Console->VDMBuffer, + 0, + 0, + NULL, + &ViewSize, + ViewUnmap, + 0, + PAGE_READWRITE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Error: Impossible to map the shared section ; Status = %lu\n", Status); + NtClose(Console->VDMBufferSection); + goto Quit; + } + + /* + * Create a view for the client. We must keep a trace of it so that + * we can unmap it when the client releases the VDM buffer. + */ + ViewSize = 0; + Console->ClientVDMBuffer = NULL; + Status = NtMapViewOfSection(Console->VDMBufferSection, + ProcessHandle, + (PVOID*)&Console->ClientVDMBuffer, + 0, + 0, + NULL, + &ViewSize, + ViewUnmap, + 0, + PAGE_READWRITE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Error: Impossible to map the shared section ; Status = %lu\n", Status); + NtUnmapViewOfSection(NtCurrentProcess(), Console->VDMBuffer); + NtClose(Console->VDMBufferSection); + goto Quit; + } + + // TODO: Duplicate the event handles. + + RegisterVDMRequest->VDMBuffer = Console->ClientVDMBuffer; + + Status = STATUS_SUCCESS; + } + else + { + /* RegisterFlags == 0 means we are unregistering the VDM */ + + // TODO: Close the duplicated handles. + + if (Console->VDMBuffer) + { + /* + * Uninitialize the graphics screen buffer + * in the reverse way we initialized it. + */ + NtUnmapViewOfSection(Console->VDMClientProcess, Console->ClientVDMBuffer); + NtUnmapViewOfSection(NtCurrentProcess(), Console->VDMBuffer); + NtClose(Console->VDMBufferSection); + } + Console->VDMBuffer = Console->ClientVDMBuffer = NULL; + + Console->VDMBufferSize.X = Console->VDMBufferSize.Y = 0; + } + +Quit: + ConSrvReleaseConsole(Console, TRUE); + return Status; } CSR_API(SrvVDMConsoleOperation)