[CONSRV]: Start implementing popup windows (it's what you see when you press e.g...
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sat, 30 Aug 2014 16:20:32 +0000 (16:20 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sat, 30 Aug 2014 16:20:32 +0000 (16:20 +0000)
svn path=/branches/condrv_restructure/; revision=63992

win32ss/user/winsrv/consrv.cmake
win32ss/user/winsrv/consrv/console.c
win32ss/user/winsrv/consrv/include/conio_winsrv.h
win32ss/user/winsrv/consrv/popup.c [new file with mode: 0644]
win32ss/user/winsrv/consrv/popup.h [new file with mode: 0644]

index 073a4db..a60a546 100644 (file)
@@ -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
index e0a6455..347caf6 100644 (file)
@@ -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));
 
index 73604ba..c510132 100644 (file)
@@ -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 (file)
index 0000000..88cd574
--- /dev/null
@@ -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 <debug.h>
+
+
+/* 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 (file)
index 0000000..c83c6b9
--- /dev/null
@@ -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);