From 04822484893657ddefc69dec2ba89fe79b2af6ba Mon Sep 17 00:00:00 2001 From: =?utf8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sat, 30 Aug 2014 16:20:32 +0000 Subject: [PATCH] [CONSRV]: Start implementing popup windows (it's what you see when you press e.g. the F7 key in your console, when you run cmd.exe). svn path=/branches/condrv_restructure/; revision=63992 --- win32ss/user/winsrv/consrv.cmake | 1 + win32ss/user/winsrv/consrv/console.c | 3 + .../user/winsrv/consrv/include/conio_winsrv.h | 3 +- win32ss/user/winsrv/consrv/popup.c | 248 ++++++++++++++++++ win32ss/user/winsrv/consrv/popup.h | 36 +++ 5 files changed, 290 insertions(+), 1 deletion(-) create mode 100644 win32ss/user/winsrv/consrv/popup.c create mode 100644 win32ss/user/winsrv/consrv/popup.h diff --git a/win32ss/user/winsrv/consrv.cmake b/win32ss/user/winsrv/consrv.cmake index 073a4db6bed..a60a546d356 100644 --- a/win32ss/user/winsrv/consrv.cmake +++ b/win32ss/user/winsrv/consrv.cmake @@ -14,6 +14,7 @@ list(APPEND CONSRV_SOURCE consrv/history.c consrv/init.c consrv/lineinput.c + consrv/popup.c consrv/settings.c consrv/subsysreg.c consrv/condrv/coninput.c diff --git a/win32ss/user/winsrv/consrv/console.c b/win32ss/user/winsrv/consrv/console.c index e0a645517fb..347caf68a5b 100644 --- a/win32ss/user/winsrv/consrv/console.c +++ b/win32ss/user/winsrv/consrv/console.c @@ -437,6 +437,9 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle, Console->InsertMode = ConsoleInfo.InsertMode; Console->QuickEdit = ConsoleInfo.QuickEdit; + /* Popup windows */ + InitializeListHead(&Console->PopupWindows); + /* Colour table */ memcpy(Console->Colors, ConsoleInfo.Colors, sizeof(ConsoleInfo.Colors)); diff --git a/win32ss/user/winsrv/consrv/include/conio_winsrv.h b/win32ss/user/winsrv/consrv/include/conio_winsrv.h index 73604ba38b2..c5101321128 100644 --- a/win32ss/user/winsrv/consrv/include/conio_winsrv.h +++ b/win32ss/user/winsrv/consrv/include/conio_winsrv.h @@ -168,7 +168,8 @@ typedef struct _WINSRV_CONSOLE HANDLE ErrorHardwareEvent; /****************************** Other properties ******************************/ - COLORREF Colors[16]; /* Colour palette */ + LIST_ENTRY PopupWindows; /*List of popup windows */ + COLORREF Colors[16]; /* Colour palette */ } WINSRV_CONSOLE, *PWINSRV_CONSOLE; diff --git a/win32ss/user/winsrv/consrv/popup.c b/win32ss/user/winsrv/consrv/popup.c new file mode 100644 index 00000000000..88cd5749594 --- /dev/null +++ b/win32ss/user/winsrv/consrv/popup.c @@ -0,0 +1,248 @@ +/* + * LICENSE: GPL - See COPYING in the top level directory + * PROJECT: ReactOS Console Server DLL + * FILE: win32ss/user/winsrv/consrv/popup.c + * PURPOSE: Console popup windows + * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) + * + * NOTE: Strongly inspired by the DrawBox function + * from base/setup/usetup/interface/usetup.c, written by: + * Eric Kohl (revision 3753) + * Hervé Poussineau (revision 24718) + * and *UiDisplayMenu from FreeLdr. + */ + +/* INCLUDES *******************************************************************/ + +#include "consrv.h" +#include "popup.h" + +#define NDEBUG +#include + + +/* PRIVATE FUNCTIONS **********************************************************/ + +NTSTATUS NTAPI +ConDrvFillConsoleOutput(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN CODE_TYPE CodeType, + IN CODE_ELEMENT Code, + IN ULONG NumCodesToWrite, + IN PCOORD WriteCoord, + OUT PULONG NumCodesWritten OPTIONAL); +NTSTATUS NTAPI +ConDrvReadConsoleOutput(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN BOOLEAN Unicode, + OUT PCHAR_INFO CharInfo/*Buffer*/, + IN OUT PSMALL_RECT ReadRegion); +NTSTATUS NTAPI +ConDrvWriteConsoleOutput(IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN BOOLEAN Unicode, + IN PCHAR_INFO CharInfo/*Buffer*/, + IN OUT PSMALL_RECT WriteRegion); + + +static VOID +DrawBox(PTEXTMODE_SCREEN_BUFFER Buffer, + IN SHORT xLeft, + IN SHORT yTop, + IN SHORT Width, + IN SHORT Height) +{ + COORD coPos; + DWORD Written; + + /* Set screen attributes */ + coPos.X = xLeft; + for (coPos.Y = yTop; coPos.Y < yTop + Height; coPos.Y++) + { + ConDrvFillConsoleOutput(Buffer->Header.Console, + Buffer, + CODE_ATTRIBUTE, + (CODE_ELEMENT)(WORD)Buffer->PopupDefaultAttrib, + Width, + &coPos, + &Written); + } + + /* draw upper left corner */ + coPos.X = xLeft; + coPos.Y = yTop; + ConDrvFillConsoleOutput(Buffer->Header.Console, + Buffer, + CODE_ASCII, + (CODE_ELEMENT)(CHAR)0xDA, // '+', + 1, + &coPos, + &Written); + + /* draw upper edge */ + coPos.X = xLeft + 1; + coPos.Y = yTop; + ConDrvFillConsoleOutput(Buffer->Header.Console, + Buffer, + CODE_ASCII, + (CODE_ELEMENT)(CHAR)0xC4, // '-', + Width - 2, + &coPos, + &Written); + + /* draw upper right corner */ + coPos.X = xLeft + Width - 1; + coPos.Y = yTop; + ConDrvFillConsoleOutput(Buffer->Header.Console, + Buffer, + CODE_ASCII, + (CODE_ELEMENT)(CHAR)0xBF, // '+', + 1, + &coPos, + &Written); + + /* Draw right edge, inner space and left edge */ + for (coPos.Y = yTop + 1; coPos.Y < yTop + Height - 1; coPos.Y++) + { + coPos.X = xLeft; + ConDrvFillConsoleOutput(Buffer->Header.Console, + Buffer, + CODE_ASCII, + (CODE_ELEMENT)(CHAR)0xB3, // '|', + 1, + &coPos, + &Written); + + coPos.X = xLeft + 1; + ConDrvFillConsoleOutput(Buffer->Header.Console, + Buffer, + CODE_ASCII, + (CODE_ELEMENT)(CHAR)' ', + Width - 2, + &coPos, + &Written); + + coPos.X = xLeft + Width - 1; + ConDrvFillConsoleOutput(Buffer->Header.Console, + Buffer, + CODE_ASCII, + (CODE_ELEMENT)(CHAR)0xB3, // '|', + 1, + &coPos, + &Written); + } + + /* draw lower left corner */ + coPos.X = xLeft; + coPos.Y = yTop + Height - 1; + ConDrvFillConsoleOutput(Buffer->Header.Console, + Buffer, + CODE_ASCII, + (CODE_ELEMENT)(CHAR)0xC0, // '+', + 1, + &coPos, + &Written); + + /* draw lower edge */ + coPos.X = xLeft + 1; + coPos.Y = yTop + Height - 1; + ConDrvFillConsoleOutput(Buffer->Header.Console, + Buffer, + CODE_ASCII, + (CODE_ELEMENT)(CHAR)0xC4, // '-', + Width - 2, + &coPos, + &Written); + + /* draw lower right corner */ + coPos.X = xLeft + Width - 1; + coPos.Y = yTop + Height - 1; + ConDrvFillConsoleOutput(Buffer->Header.Console, + Buffer, + CODE_ASCII, + (CODE_ELEMENT)(CHAR)0xD9, // '+', + 1, + &coPos, + &Written); +} + + +/* PUBLIC FUNCTIONS ***********************************************************/ + +PPOPUP_WINDOW +CreatePopupWindow(PTEXTMODE_SCREEN_BUFFER Buffer, + SHORT xLeft, + SHORT yTop, + SHORT Width, + SHORT Height) +{ + PPOPUP_WINDOW Popup; + SMALL_RECT Region; + + /* Create the popup window */ + Popup = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(*Popup)); + if (Popup == NULL) return NULL; + + Popup->ScreenBuffer = Buffer; + Popup->Origin.X = xLeft; + Popup->Origin.Y = yTop; + Popup->Size.X = Width; + Popup->Size.Y = Height; + + /* Save old contents */ + Popup->OldContents = ConsoleAllocHeap(HEAP_ZERO_MEMORY, + Popup->Size.X * Popup->Size.Y * + sizeof(*Popup->OldContents)); + if (Popup->OldContents == NULL) + { + ConsoleFreeHeap(Popup); + return NULL; + } + Region.Left = Popup->Origin.X; + Region.Top = Popup->Origin.Y; + Region.Right = Popup->Origin.X + Popup->Size.X - 1; + Region.Bottom = Popup->Origin.Y + Popup->Size.Y - 1; + ConDrvReadConsoleOutput(Buffer->Header.Console, + Buffer, + TRUE, + Popup->OldContents, + &Region); + + /* Draw it */ + DrawBox(Buffer, + xLeft, yTop, + Width, Height); + + /* Add it into the list of popups */ + InsertTailList(&Buffer->Header.Console->PopupWindows, &Popup->ListEntry); + + return Popup; +} + +VOID +DestroyPopupWindow(PPOPUP_WINDOW Popup) +{ + SMALL_RECT Region; + + if (Popup == NULL) return; + + /* Remove it from the list of popups */ + RemoveEntryList(&Popup->ListEntry); + + /* Restore the old screen-buffer contents */ + Region.Left = Popup->Origin.X; + Region.Top = Popup->Origin.Y; + Region.Right = Popup->Origin.X + Popup->Size.X - 1; + Region.Bottom = Popup->Origin.Y + Popup->Size.Y - 1; + ConDrvWriteConsoleOutput(Popup->ScreenBuffer->Header.Console, + Popup->ScreenBuffer, + TRUE, + Popup->OldContents, + &Region); + + /* Free memory */ + ConsoleFreeHeap(Popup->OldContents); + ConsoleFreeHeap(Popup); +} + +/* EOF */ diff --git a/win32ss/user/winsrv/consrv/popup.h b/win32ss/user/winsrv/consrv/popup.h new file mode 100644 index 00000000000..c83c6b91ff9 --- /dev/null +++ b/win32ss/user/winsrv/consrv/popup.h @@ -0,0 +1,36 @@ +/* + * LICENSE: GPL - See COPYING in the top level directory + * PROJECT: ReactOS Console Server DLL + * FILE: win32ss/user/winsrv/consrv/popup.h + * PURPOSE: Console popup windows + * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +#pragma once + +typedef +VOID +(NTAPI *PPOPUP_INPUT_ROUTINE)(VOID); + +typedef struct _POPUP_WINDOW +{ + LIST_ENTRY ListEntry; /* Entry in console's list of popups */ + PTEXTMODE_SCREEN_BUFFER ScreenBuffer; /* Associated screen-buffer */ + + // SMALL_RECT Region; /* The region the popup occupies */ + COORD Origin; /* Origin of the popup window */ + COORD Size; /* Size of the popup window */ + + PCHAR_INFO OldContents; /* The data under the popup window */ + PPOPUP_INPUT_ROUTINE PopupInputRoutine; /* Routine called when input is received */ +} POPUP_WINDOW, *PPOPUP_WINDOW; + + +PPOPUP_WINDOW +CreatePopupWindow(PTEXTMODE_SCREEN_BUFFER Buffer, + SHORT xLeft, + SHORT yTop, + SHORT Width, + SHORT Height); +VOID +DestroyPopupWindow(PPOPUP_WINDOW Popup); -- 2.17.1