[CONSOLE.CPL-KERNEL32]

Fix some compilation warnings with MSVC.

[KERNEL32-CONSRV]
- Implement console graphics screen buffers, as described in http://blog.airesoft.co.uk/2012/10/things-ms-can-do-that-they-dont-tell-you-about-console-graphics/ .
  The idea is that the console server creates a memory shared section to be shared with the client console application (it increases performance). A mutex is used to "say" to the console server that he can repaint the screen. The function InvalidateConsoleDIBits is implemented too. The definition of the structure CONSOLE_GRAPHICS_BUFFER_INFO comes directly from the site.
- CreateConsoleScreenBuffer was modified to be able to create such buffers.
This is needed for a working NTVDM-like application.

[CONSRV]
- Rework the console buffer structures so that text-mode buffers and graphics-mode buffers can "inherit" from an "abstract" structure, CONSOLE_SCREEN_BUFFER. Add few helper functions for manipulating them.
- Reorganize the output code in "graphics.c" and "text.c" files to separate text-mode only code from graphics-mode only code, both in the console server and in the GUI front-end.

Other fixes:
- Fix mouse handling (left and right clicks when one goes away from the "Selection" mode); do not handle mouse signal when we reactivate the GUI front-end window by a click.
- Fix GetLargestConsoleWindowSize API in console server side. Now pressing Alt+F9 in Far Manager to "change" the "video" mode works correctly.

Finally:
- Start to implement a (fake, i.e. not using directly a VGA driver) console fullscreen mode. Currently Alt-Enter key presses call a stub which just alternates DPRINTing between "switch to fullscreen mode" and "switch to windowed mode".

Images here:
- Example of an application (a 16-bit emulator by Mysoft) which uses the console graphics screen-buffer functionality: http://img577.imageshack.us/img577/1693/mysoftemulatorargon.png
- A potpourri of console applications which use graphics screen-buffers: http://img571.imageshack.us/img571/6526/consoledelirium.png

Enjoy :)

svn path=/trunk/; revision=59099
This commit is contained in:
Hermès Bélusca-Maïto
2013-05-29 00:29:07 +00:00
parent 7791dc4bd9
commit 7c2b066810
30 changed files with 3392 additions and 2105 deletions
+2 -1
View File
@@ -93,7 +93,6 @@ InitConsoleDefaults(PCONSOLE_PROPS pConInfo)
pConInfo->ci.HistoryBufferSize = 50;
pConInfo->ci.NumberOfHistoryBuffers = 4;
pConInfo->ci.HistoryNoDup = FALSE;
pConInfo->ci.FullScreen = FALSE;
pConInfo->ci.QuickEdit = FALSE;
pConInfo->ci.InsertMode = TRUE;
// pConInfo->ci.InputBufferSize;
@@ -119,6 +118,8 @@ InitConsoleDefaults(PCONSOLE_PROPS pConInfo)
GuiInfo->FontWeight = FW_DONTCARE;
GuiInfo->UseRasterFonts = TRUE;
GuiInfo->FullScreen = FALSE;
GuiInfo->ShowWindow = SW_SHOWNORMAL;
GuiInfo->AutoPosition = TRUE;
GuiInfo->WindowOrigin.x = 0;
GuiInfo->WindowOrigin.y = 0;
+16 -16
View File
@@ -273,8 +273,8 @@ LayoutProc(HWND hwndDlg,
sheight = wheight;
}
}
swidth = max(swidth, 1);
sheight = max(sheight, 1);
swidth = min(max(swidth , 1), 0xFFFF);
sheight = min(max(sheight, 1), 0xFFFF);
if (lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_WIDTH || lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_HEIGHT)
{
@@ -292,10 +292,10 @@ LayoutProc(HWND hwndDlg,
}
}
pConInfo->ci.ScreenBufferSize.X = swidth;
pConInfo->ci.ScreenBufferSize.Y = sheight;
pConInfo->ci.ConsoleSize.X = wwidth;
pConInfo->ci.ConsoleSize.Y = wheight;
pConInfo->ci.ScreenBufferSize.X = (SHORT)swidth;
pConInfo->ci.ScreenBufferSize.Y = (SHORT)sheight;
pConInfo->ci.ConsoleSize.X = (SHORT)wwidth;
pConInfo->ci.ConsoleSize.Y = (SHORT)wheight;
GuiInfo->WindowOrigin.x = left;
GuiInfo->WindowOrigin.y = top;
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
@@ -319,15 +319,15 @@ LayoutProc(HWND hwndDlg,
DWORD sheight, swidth;
DWORD left, top;
wwidth = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, NULL, FALSE);
wwidth = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, NULL, FALSE);
wheight = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, NULL, FALSE);
swidth = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, NULL, FALSE);
swidth = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, NULL, FALSE);
sheight = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, NULL, FALSE);
left = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, FALSE);
top = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP, NULL, FALSE);
left = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, FALSE);
top = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP, NULL, FALSE);
swidth = max(swidth, 1);
sheight = max(sheight, 1);
swidth = min(max(swidth , 1), 0xFFFF);
sheight = min(max(sheight, 1), 0xFFFF);
/* Automatically adjust window size when screen buffer decreases */
if (wwidth > swidth)
@@ -342,10 +342,10 @@ LayoutProc(HWND hwndDlg,
wheight = sheight;
}
pConInfo->ci.ScreenBufferSize.X = swidth;
pConInfo->ci.ScreenBufferSize.Y = sheight;
pConInfo->ci.ConsoleSize.X = wwidth;
pConInfo->ci.ConsoleSize.Y = wheight;
pConInfo->ci.ScreenBufferSize.X = (SHORT)swidth;
pConInfo->ci.ScreenBufferSize.Y = (SHORT)sheight;
pConInfo->ci.ConsoleSize.X = (SHORT)wwidth;
pConInfo->ci.ConsoleSize.Y = (SHORT)wheight;
GuiInfo->WindowOrigin.x = left;
GuiInfo->WindowOrigin.y = top;
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+6 -3
View File
@@ -23,6 +23,7 @@ OptionsProc(HWND hwndDlg,
LPARAM lParam)
{
PCONSOLE_PROPS pConInfo;
PGUI_CONSOLE_INFO GuiInfo;
LRESULT lResult;
HWND hDlgCtrl;
LPPSHNOTIFY lppsn;
@@ -70,6 +71,7 @@ OptionsProc(HWND hwndDlg,
case WM_COMMAND:
{
if (!pConInfo) break;
GuiInfo = pConInfo->TerminalInfo.TermInfo;
switch (LOWORD(wParam))
{
@@ -93,13 +95,13 @@ OptionsProc(HWND hwndDlg,
}
case IDC_RADIO_DISPLAY_WINDOW:
{
pConInfo->ci.FullScreen = FALSE;
GuiInfo->FullScreen = FALSE;
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
break;
}
case IDC_RADIO_DISPLAY_FULL:
{
pConInfo->ci.FullScreen = TRUE;
GuiInfo->FullScreen = TRUE;
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
break;
}
@@ -167,6 +169,7 @@ static
void
UpdateDialogElements(HWND hwndDlg, PCONSOLE_PROPS pConInfo)
{
PGUI_CONSOLE_INFO GuiInfo = pConInfo->TerminalInfo.TermInfo;
HWND hDlgCtrl;
TCHAR szBuffer[MAX_PATH];
@@ -225,7 +228,7 @@ UpdateDialogElements(HWND hwndDlg, PCONSOLE_PROPS pConInfo)
SendMessage(hDlgCtrl, BM_SETCHECK, (LPARAM)BST_UNCHECKED, 0);
/* Update full/window screen */
if (pConInfo->ci.FullScreen)
if (GuiInfo->FullScreen)
{
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_DISPLAY_FULL);
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
@@ -438,16 +438,38 @@ GetNumberOfConsoleFonts(VOID)
/*
* @unimplemented (Undocumented)
* @implemented (Undocumented)
* @note See http://blog.airesoft.co.uk/2012/10/things-ms-can-do-that-they-dont-tell-you-about-console-graphics/
*/
DWORD
BOOL
WINAPI
InvalidateConsoleDIBits(DWORD Unknown0,
DWORD Unknown1)
InvalidateConsoleDIBits(IN HANDLE hConsoleOutput,
IN PSMALL_RECT lpRect)
{
DPRINT1("InvalidateConsoleDIBits(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
NTSTATUS Status;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_INVALIDATEDIBITS InvalidateDIBitsRequest = &ApiMessage.Data.InvalidateDIBitsRequest;
if (lpRect == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
InvalidateDIBitsRequest->OutputHandle = hConsoleOutput;
InvalidateDIBitsRequest->Region = *lpRect;
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
NULL,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepInvalidateBitMapRect),
sizeof(CONSOLE_INVALIDATEDIBITS));
if (!NT_SUCCESS(Status))
{
BaseSetLastNTError(Status);
return FALSE;
}
return TRUE;
}
@@ -1445,8 +1467,8 @@ SetConsoleWindowInfo(HANDLE hConsoleOutput,
}
SetWindowInfoRequest->OutputHandle = hConsoleOutput;
SetWindowInfoRequest->Absolute = bAbsolute;
SetWindowInfoRequest->WindowRect = *lpConsoleWindow;
SetWindowInfoRequest->Absolute = bAbsolute;
SetWindowInfoRequest->WindowRect = *lpConsoleWindow;
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
NULL,
@@ -1803,31 +1825,68 @@ CreateConsoleScreenBuffer(DWORD dwDesiredAccess,
{
NTSTATUS Status;
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_CREATESCREENBUFFER CreateScreenBufferRequest = &ApiMessage.Data.CreateScreenBufferRequest;
PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
PCONSOLE_GRAPHICS_BUFFER_INFO GraphicsBufferInfo = /*(PCONSOLE_GRAPHICS_BUFFER_INFO)*/lpScreenBufferData;
if ( (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)) ||
(dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) ||
(dwFlags != CONSOLE_TEXTMODE_BUFFER) )
(dwFlags != CONSOLE_TEXTMODE_BUFFER && dwFlags != CONSOLE_GRAPHICS_BUFFER) )
{
SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
ApiMessage.Data.CreateScreenBufferRequest.Access = dwDesiredAccess;
ApiMessage.Data.CreateScreenBufferRequest.ShareMode = dwShareMode;
ApiMessage.Data.CreateScreenBufferRequest.Inheritable =
CreateScreenBufferRequest->ScreenBufferType = dwFlags;
CreateScreenBufferRequest->Access = dwDesiredAccess;
CreateScreenBufferRequest->ShareMode = dwShareMode;
CreateScreenBufferRequest->Inheritable =
(lpSecurityAttributes ? lpSecurityAttributes->bInheritHandle : FALSE);
if (dwFlags == CONSOLE_GRAPHICS_BUFFER)
{
if (CreateScreenBufferRequest->Inheritable || GraphicsBufferInfo == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
CreateScreenBufferRequest->GraphicsBufferInfo = *GraphicsBufferInfo;
CaptureBuffer = CsrAllocateCaptureBuffer(1, GraphicsBufferInfo->dwBitMapInfoLength);
if (CaptureBuffer == NULL)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
CsrCaptureMessageBuffer(CaptureBuffer,
(PVOID)GraphicsBufferInfo->lpBitMapInfo,
GraphicsBufferInfo->dwBitMapInfoLength,
(PVOID*)&CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMapInfo);
}
Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
NULL,
CaptureBuffer,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepCreateScreenBuffer),
sizeof(CONSOLE_CREATESCREENBUFFER));
if (CaptureBuffer)
CsrFreeCaptureBuffer(CaptureBuffer);
if (!NT_SUCCESS(Status))
{
BaseSetLastNTError(Status);
return INVALID_HANDLE_VALUE;
}
return ApiMessage.Data.CreateScreenBufferRequest.OutputHandle;
if (dwFlags == CONSOLE_GRAPHICS_BUFFER && GraphicsBufferInfo)
{
GraphicsBufferInfo->hMutex = CreateScreenBufferRequest->GraphicsBufferInfo.hMutex ;
GraphicsBufferInfo->lpBitMap = CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMap;
}
return CreateScreenBufferRequest->OutputHandle;
}
@@ -2296,7 +2355,7 @@ GetConsoleInputExeNameA(DWORD nBufferLength, LPSTR lpBuffer)
/* Initialize strings for conversion */
RtlInitUnicodeString(&BufferU, Buffer);
BufferA.Length = 0;
BufferA.MaximumLength = nBufferLength;
BufferA.MaximumLength = (USHORT)nBufferLength;
BufferA.Buffer = lpBuffer;
/* Convert unicode name to ansi, copying as much chars as fit */
@@ -46,7 +46,7 @@ IntCaptureMessageString(PCSR_CAPTURE_BUFFER CaptureBuffer,
Size = MultiByteToWideChar(CP_ACP, 0, String, Size, RequestString->Buffer, Size * sizeof(WCHAR))
* sizeof(WCHAR);
}
RequestString->Length = RequestString->MaximumLength = Size;
RequestString->Length = RequestString->MaximumLength = (USHORT)Size;
}
-1
View File
@@ -194,7 +194,6 @@ extern "C" {
#define PROFILE_USER 0x10000000
#define PROFILE_KERNEL 0x20000000
#define PROFILE_SERVER 0x40000000
#define CONSOLE_TEXTMODE_BUFFER 1
#define CREATE_NEW 1
#define CREATE_ALWAYS 2
#define OPEN_EXISTING 3
+39 -4
View File
@@ -24,12 +24,15 @@ extern "C" {
/*
* Console display modes
*/
// These codes are answered by GetConsoleDisplayMode
#define CONSOLE_WINDOWED 0
#define CONSOLE_FULLSCREEN 1
#define CONSOLE_FULLSCREEN_HARDWARE 2
#if (_WIN32_WINNT >= 0x0600)
#define CONSOLE_OVERSTRIKE 1
#endif
#define CONSOLE_FULLSCREEN_HARDWARE 2
// These codes should be given to SetConsoleDisplayMode
#define CONSOLE_FULLSCREEN_MODE 1
#define CONSOLE_WINDOWED_MODE 2
@@ -53,6 +56,12 @@ extern "C" {
#define COMMON_LVB_REVERSE_VIDEO 0x4000
#define COMMON_LVB_UNDERSCORE 0x8000
/*
* Screen buffer types
*/
#define CONSOLE_TEXTMODE_BUFFER 1
#define CONSOLE_GRAPHICS_BUFFER 2 /* Undocumented, see http://blog.airesoft.co.uk/2012/10/things-ms-can-do-that-they-dont-tell-you-about-console-graphics/ */
/*
* Control handler codes
*/
@@ -154,29 +163,35 @@ typedef struct _CHAR_INFO {
} Char;
WORD Attributes;
} CHAR_INFO,*PCHAR_INFO;
typedef struct _SMALL_RECT {
SHORT Left;
SHORT Top;
SHORT Right;
SHORT Bottom;
} SMALL_RECT,*PSMALL_RECT;
typedef struct _CONSOLE_CURSOR_INFO {
DWORD dwSize;
BOOL bVisible;
} CONSOLE_CURSOR_INFO,*PCONSOLE_CURSOR_INFO;
typedef struct _COORD {
SHORT X;
SHORT Y;
} COORD, *PCOORD;
typedef struct _CONSOLE_SELECTION_INFO {
DWORD dwFlags;
COORD dwSelectionAnchor;
SMALL_RECT srSelection;
} CONSOLE_SELECTION_INFO, *PCONSOLE_SELECTION_INFO;
typedef struct _CONSOLE_FONT_INFO {
DWORD nFont;
COORD dwFontSize;
} CONSOLE_FONT_INFO, *PCONSOLE_FONT_INFO;
typedef struct _CONSOLE_SCREEN_BUFFER_INFO {
COORD dwSize;
COORD dwCursorPosition;
@@ -184,7 +199,20 @@ typedef struct _CONSOLE_SCREEN_BUFFER_INFO {
SMALL_RECT srWindow;
COORD dwMaximumWindowSize;
} CONSOLE_SCREEN_BUFFER_INFO,*PCONSOLE_SCREEN_BUFFER_INFO;
/* Undocumented, see http://blog.airesoft.co.uk/2012/10/things-ms-can-do-that-they-dont-tell-you-about-console-graphics/ */
#if defined(_WINGDI_) && !defined(NOGDI)
typedef struct _CONSOLE_GRAPHICS_BUFFER_INFO {
DWORD dwBitMapInfoLength;
LPBITMAPINFO lpBitMapInfo;
DWORD dwUsage; // DIB_PAL_COLORS or DIB_RGB_COLORS
HANDLE hMutex;
PVOID lpBitMap;
} CONSOLE_GRAPHICS_BUFFER_INFO, *PCONSOLE_GRAPHICS_BUFFER_INFO;
#endif
typedef BOOL(CALLBACK *PHANDLER_ROUTINE)(_In_ DWORD);
typedef struct _KEY_EVENT_RECORD {
BOOL bKeyDown;
WORD wRepeatCount;
@@ -198,18 +226,21 @@ typedef struct _KEY_EVENT_RECORD {
}
#ifdef __GNUC__
/* gcc's alignment is not what win32 expects */
PACKED
PACKED
#endif
KEY_EVENT_RECORD;
typedef struct _MOUSE_EVENT_RECORD {
COORD dwMousePosition;
DWORD dwButtonState;
DWORD dwControlKeyState;
DWORD dwEventFlags;
} MOUSE_EVENT_RECORD;
typedef struct _WINDOW_BUFFER_SIZE_RECORD { COORD dwSize; } WINDOW_BUFFER_SIZE_RECORD;
typedef struct _MENU_EVENT_RECORD { UINT dwCommandId; } MENU_EVENT_RECORD,*PMENU_EVENT_RECORD;
typedef struct _WINDOW_BUFFER_SIZE_RECORD { COORD dwSize; } WINDOW_BUFFER_SIZE_RECORD;
typedef struct _MENU_EVENT_RECORD { UINT dwCommandId; } MENU_EVENT_RECORD,*PMENU_EVENT_RECORD;
typedef struct _FOCUS_EVENT_RECORD { BOOL bSetFocus; } FOCUS_EVENT_RECORD;
typedef struct _INPUT_RECORD {
WORD EventType;
union {
@@ -322,6 +353,9 @@ BOOL WINAPI GetConsoleMode(HANDLE,PDWORD);
UINT WINAPI GetConsoleOutputCP(VOID);
BOOL WINAPI GetConsoleScreenBufferInfo(_In_ HANDLE, _Out_ PCONSOLE_SCREEN_BUFFER_INFO);
/* Undocumented, see http://blog.airesoft.co.uk/2012/10/things-ms-can-do-that-they-dont-tell-you-about-console-graphics/ */
BOOL WINAPI InvalidateConsoleDIBits(_In_ HANDLE, _In_ PSMALL_RECT);
DWORD
WINAPI
GetConsoleTitleA(
@@ -342,6 +376,7 @@ BOOL APIENTRY SetConsoleDisplayMode(_In_ HANDLE hConsoleOutput, _In_ DWORD dwFla
COORD WINAPI GetLargestConsoleWindowSize(_In_ HANDLE);
BOOL WINAPI GetNumberOfConsoleInputEvents(HANDLE,PDWORD);
BOOL WINAPI GetNumberOfConsoleMouseButtons(_Out_ PDWORD);
BOOL WINAPI PeekConsoleInputA(HANDLE,PINPUT_RECORD,DWORD,PDWORD);
BOOL
+16 -5
View File
@@ -60,7 +60,7 @@ typedef enum _CONSRV_API_NUMBER
ConsolepGetTitle,
ConsolepSetTitle,
ConsolepCreateScreenBuffer,
// ConsolepInvalidateBitMapRect,
ConsolepInvalidateBitMapRect,
// ConsolepVDMOperation,
// ConsolepSetCursor,
// ConsolepShowCursor,
@@ -236,8 +236,6 @@ typedef struct
DWORD ConsoleMode;
} CONSOLE_GETSETCONSOLEMODE, *PCONSOLE_GETSETCONSOLEMODE;
#define CONSOLE_WINDOWED 0 /* Internal console hardware state */
typedef struct
{
// HANDLE OutputHandle;
@@ -266,11 +264,17 @@ typedef struct
typedef struct
{
HANDLE OutputHandle; /* Handle to newly created screen buffer */
HANDLE OutputHandle; /* Handle to newly created screen buffer */
DWORD ScreenBufferType; /* Type of the screen buffer: CONSOLE_TEXTMODE_BUFFER or CONSOLE_GRAPHICS_BUFFER */
/*
* If we are creating a graphics screen buffer,
* this structure holds the initialization information.
*/
CONSOLE_GRAPHICS_BUFFER_INFO GraphicsBufferInfo;
DWORD Access;
DWORD ShareMode;
BOOL Inheritable;
BOOL Inheritable;
} CONSOLE_CREATESCREENBUFFER, *PCONSOLE_CREATESCREENBUFFER;
typedef struct
@@ -278,6 +282,12 @@ typedef struct
HANDLE OutputHandle; /* Handle to screen buffer to switch to */
} CONSOLE_SETACTIVESCREENBUFFER, *PCONSOLE_SETACTIVESCREENBUFFER;
typedef struct
{
HANDLE OutputHandle;
SMALL_RECT Region;
} CONSOLE_INVALIDATEDIBITS, *PCONSOLE_INVALIDATEDIBITS;
typedef struct
{
DWORD Length;
@@ -624,6 +634,7 @@ typedef struct _CONSOLE_API_MESSAGE
CONSOLE_GETSETHWSTATE HardwareStateRequest;
/* Console window */
CONSOLE_INVALIDATEDIBITS InvalidateDIBitsRequest;
CONSOLE_GETSETCONSOLETITLE TitleRequest;
CONSOLE_GETLARGESTWINDOWSIZE GetLargestWindowSizeRequest;
CONSOLE_SETWINDOWINFO SetWindowInfoRequest;
+20 -2
View File
@@ -12,18 +12,36 @@ list(APPEND SOURCE
alias.c
coninput.c
conoutput.c
graphics.c
text.c
console.c
handle.c
init.c
lineinput.c
settings.c
consrv.rc
frontends/gui/guiterm.c
frontends/gui/guisettings.c
frontends/gui/graphics.c
frontends/gui/text.c
frontends/tui/tuiterm.c
${CMAKE_CURRENT_BINARY_DIR}/consrv.def)
add_library(consrv SHARED ${SOURCE})
add_library(consrv SHARED
${SOURCE}
consrv.rc)
#
# Explicitely enable MS extensions to be able to use unnamed (anonymous) nested structs.
#
# FIXME: http://www.cmake.org/Bug/view.php?id=12998
if(MSVC)
## NOTE: No need to specify it as we use MSVC :)
#add_target_compile_flags(consrv "/Ze")
##set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "/Ze")
else()
add_target_compile_flags(consrv "-fms-extensions")
#set_source_files_properties(${SOURCE} PROPERTIES COMPILE_FLAGS "-fms-extensions")
endif()
target_link_libraries(consrv win32ksys ${PSEH_LIB} uuid) # win32ksys because of NtUser...()
+1
View File
@@ -24,6 +24,7 @@ CSR_API(SrvFlushConsoleInputBuffer);
CSR_API(SrvGetConsoleNumberOfInputEvents);
/* conoutput.c */
CSR_API(SrvInvalidateBitMapRect);
CSR_API(SrvReadConsoleOutput);
CSR_API(SrvWriteConsole);
CSR_API(SrvWriteConsoleOutput);
+8 -10
View File
@@ -82,7 +82,7 @@ ConioProcessInputEvent(PCONSOLE Console,
if (Console->InputBuffer.Mode & ENABLE_LINE_INPUT &&
(vk == VK_PAUSE || (vk == 'S' &&
(cks & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) &&
!(cks & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)))))
!(cks & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)))))
{
ConioPause(Console, PAUSED_FROM_KEYBOARD);
return STATUS_SUCCESS;
@@ -101,8 +101,8 @@ ConioProcessInputEvent(PCONSOLE Console,
/* add event to the queue */
ConInRec = ConsoleAllocHeap(0, sizeof(ConsoleInput));
if (ConInRec == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
if (ConInRec == NULL) return STATUS_INSUFFICIENT_RESOURCES;
ConInRec->InputEvent = *InputEvent;
InsertTailList(&Console->InputBuffer.InputEvents, &ConInRec->ListEntry);
@@ -178,7 +178,6 @@ ConioProcessKey(PCONSOLE Console, MSG* msg)
* or translated keys may be involved. */
static UINT LastVirtualKey = 0;
DWORD ShiftState;
UINT RepeatCount;
WCHAR UnicodeChar;
UINT VirtualKeyCode;
UINT VirtualScanCode;
@@ -193,8 +192,7 @@ ConioProcessKey(PCONSOLE Console, MSG* msg)
return;
}
RepeatCount = 1;
VirtualScanCode = (msg->lParam >> 16) & 0xff;
VirtualScanCode = HIWORD(msg->lParam) & 0xFF;
Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR ||
msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR;
@@ -218,17 +216,17 @@ ConioProcessKey(PCONSOLE Console, MSG* msg)
Chars,
2,
0,
0);
NULL);
UnicodeChar = (1 == RetChars ? Chars[0] : 0);
}
er.EventType = KEY_EVENT;
er.Event.KeyEvent.bKeyDown = Down;
er.Event.KeyEvent.wRepeatCount = RepeatCount;
er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar;
er.Event.KeyEvent.dwControlKeyState = ShiftState;
er.Event.KeyEvent.wRepeatCount = 1;
er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode;
er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode;
er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar;
er.Event.KeyEvent.dwControlKeyState = ShiftState;
if (ConioProcessKeyCallback(Console,
msg,
+15 -15
View File
@@ -10,6 +10,8 @@
/* Macros used to call functions in the FRONTEND_VTBL virtual table */
#define ConioCleanupConsole(Console) \
(Console)->TermIFace.Vtbl->CleanupConsole(Console)
#define ConioDrawRegion(Console, Region) \
(Console)->TermIFace.Vtbl->DrawRegion((Console), (Region))
#define ConioWriteStream(Console, Block, CurStartX, CurStartY, ScrolledLines, Buffer, Length) \
@@ -19,26 +21,24 @@
(Console)->TermIFace.Vtbl->SetCursorInfo((Console), (Buff))
#define ConioSetScreenInfo(Console, Buff, OldCursorX, OldCursorY) \
(Console)->TermIFace.Vtbl->SetScreenInfo((Console), (Buff), (OldCursorX), (OldCursorY))
#define ConioUpdateScreenInfo(Console, Buff) \
(Console)->TermIFace.Vtbl->UpdateScreenInfo((Console), (Buff))
#define ConioIsBufferResizeSupported(Console) \
(Console)->TermIFace.Vtbl->IsBufferResizeSupported(Console)
#define ConioChangeTitle(Console) \
(Console)->TermIFace.Vtbl->ChangeTitle(Console)
#define ConioCleanupConsole(Console) \
(Console)->TermIFace.Vtbl->CleanupConsole(Console)
#define ConioChangeIcon(Console, hWindowIcon) \
(Console)->TermIFace.Vtbl->ChangeIcon((Console), (hWindowIcon))
// #define ConioResizeBuffer(Console, Buff, Size) (Console)->TermIFace.Vtbl->ResizeBuffer((Console), (Buff), (Size))
#define ConioResizeTerminal(Console) \
(Console)->TermIFace.Vtbl->ResizeTerminal(Console)
#define ConioProcessKeyCallback(Console, Msg, KeyStateMenu, ShiftState, VirtualKeyCode, Down) \
(Console)->TermIFace.Vtbl->ProcessKeyCallback((Console), (Msg), (KeyStateMenu), (ShiftState), (VirtualKeyCode), (Down))
#define ConioGetLargestConsoleWindowSize(Console, pSize) \
(Console)->TermIFace.Vtbl->GetLargestConsoleWindowSize((Console), (pSize))
#define ConioGetConsoleWindowHandle(Console) \
(Console)->TermIFace.Vtbl->GetConsoleWindowHandle(Console)
#define ConioRefreshInternalInfo(Console) \
(Console)->TermIFace.Vtbl->RefreshInternalInfo(Console)
#define ConioChangeTitle(Console) \
(Console)->TermIFace.Vtbl->ChangeTitle(Console)
#define ConioChangeIcon(Console, hWindowIcon) \
(Console)->TermIFace.Vtbl->ChangeIcon((Console), (hWindowIcon))
#define ConioGetConsoleWindowHandle(Console) \
(Console)->TermIFace.Vtbl->GetConsoleWindowHandle(Console)
#define ConioGetLargestConsoleWindowSize(Console, pSize) \
(Console)->TermIFace.Vtbl->GetLargestConsoleWindowSize((Console), (pSize))
#define ConioGetDisplayMode(Console) \
(Console)->TermIFace.Vtbl->GetDisplayMode(Console)
#define ConioSetDisplayMode(Console, NewMode) \
(Console)->TermIFace.Vtbl->SetDisplayMode((Console), (NewMode))
/* EOF */
File diff suppressed because it is too large Load Diff
+20 -8
View File
@@ -9,23 +9,35 @@
#pragma once
#define ConSrvGetTextModeBuffer(ProcessData, Handle, Ptr, Access, LockConsole) \
ConSrvGetObject((ProcessData), (Handle), (PCONSOLE_IO_OBJECT*)(Ptr), NULL, \
(Access), (LockConsole), TEXTMODE_BUFFER)
#define ConSrvGetTextModeBufferAndHandleEntry(ProcessData, Handle, Ptr, Entry, Access, LockConsole) \
ConSrvGetObject((ProcessData), (Handle), (PCONSOLE_IO_OBJECT*)(Ptr), (Entry), \
(Access), (LockConsole), TEXTMODE_BUFFER)
#define ConSrvGetGraphicsBuffer(ProcessData, Handle, Ptr, Access, LockConsole) \
ConSrvGetObject((ProcessData), (Handle), (PCONSOLE_IO_OBJECT*)(Ptr), NULL, \
(Access), (LockConsole), GRAPHICS_BUFFER)
#define ConSrvGetGraphicsBufferAndHandleEntry(ProcessData, Handle, Ptr, Entry, Access, LockConsole) \
ConSrvGetObject((ProcessData), (Handle), (PCONSOLE_IO_OBJECT*)(Ptr), (Entry), \
(Access), (LockConsole), GRAPHICS_BUFFER)
#define ConSrvGetScreenBuffer(ProcessData, Handle, Ptr, Access, LockConsole) \
ConSrvGetObject((ProcessData), (Handle), (PCONSOLE_IO_OBJECT*)(Ptr), NULL, \
(Access), (LockConsole), SCREEN_BUFFER)
#define ConSrvGetScreenBufferAndHandleEntry(ProcessData, Handle, Ptr, Entry, Access, LockConsole) \
ConSrvGetObject((ProcessData), (Handle), (PCONSOLE_IO_OBJECT*)(Ptr), (Entry), \
(Access), (LockConsole), SCREEN_BUFFER)
#define ConSrvReleaseScreenBuffer(Buff, IsConsoleLocked) \
ConSrvReleaseObject(&(Buff)->Header, (IsConsoleLocked))
NTSTATUS FASTCALL ConSrvCreateScreenBuffer(IN OUT PCONSOLE Console,
OUT PCONSOLE_SCREEN_BUFFER* Buffer,
IN COORD ScreenBufferSize,
IN USHORT ScreenAttrib,
IN USHORT PopupAttrib,
IN ULONG DisplayMode,
IN BOOLEAN IsCursorVisible,
IN ULONG CursorSize);
NTSTATUS FASTCALL ConSrvCreateScreenBuffer(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
IN OUT PCONSOLE Console,
IN ULONG BufferType,
IN PVOID ScreenBufferInfo);
VOID WINAPI ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer);
VOID FASTCALL ConioSetActiveScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer);
/* EOF */
+71 -73
View File
@@ -479,9 +479,10 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole,
{
NTSTATUS Status;
SECURITY_ATTRIBUTES SecurityAttributes;
CONSOLE_INFO ConsoleInfo;
SIZE_T Length = 0;
DWORD ProcessId = HandleToUlong(ConsoleLeaderProcess->ClientId.UniqueProcess);
CONSOLE_INFO ConsoleInfo;
TEXTMODE_BUFFER_INFO ScreenBufferInfo;
PCONSOLE Console;
PCONSOLE_SCREEN_BUFFER NewBuffer;
BOOL GuiMode;
@@ -564,14 +565,17 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole,
ConsoleInfo.ConsoleSize.X = (SHORT)ConsoleStartInfo->ConsoleWindowSize.cx;
ConsoleInfo.ConsoleSize.Y = (SHORT)ConsoleStartInfo->ConsoleWindowSize.cy;
}
/*
if (ConsoleStartInfo->dwStartupFlags & STARTF_RUNFULLSCREEN)
{
ConsoleInfo.FullScreen = TRUE;
}
*/
}
/*
* Fix the screen buffer size if needed. The rule is:
* ScreenBufferSize >= ConsoleSize
*/
if (ConsoleInfo.ScreenBufferSize.X < ConsoleInfo.ConsoleSize.X)
ConsoleInfo.ScreenBufferSize.X = ConsoleInfo.ConsoleSize.X;
if (ConsoleInfo.ScreenBufferSize.Y < ConsoleInfo.ConsoleSize.Y)
ConsoleInfo.ScreenBufferSize.Y = ConsoleInfo.ConsoleSize.Y;
/*
* Initialize the console
*/
@@ -583,6 +587,7 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole,
memcpy(Console->Colors, ConsoleInfo.Colors, sizeof(ConsoleInfo.Colors));
Console->ConsoleSize = ConsoleInfo.ConsoleSize;
Console->FixedSize = FALSE; // Value by default; is reseted by the front-ends if needed.
/*
* Initialize the input buffer
@@ -618,17 +623,18 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole,
Console->CodePage = GetOEMCP();
Console->OutputCodePage = GetOEMCP();
/* Initialize a new screen buffer with default settings */
/* Initialize a new text-mode screen buffer with default settings */
ScreenBufferInfo.ScreenBufferSize = ConsoleInfo.ScreenBufferSize;
ScreenBufferInfo.ScreenAttrib = ConsoleInfo.ScreenAttrib;
ScreenBufferInfo.PopupAttrib = ConsoleInfo.PopupAttrib;
ScreenBufferInfo.IsCursorVisible = TRUE;
ScreenBufferInfo.CursorSize = ConsoleInfo.CursorSize;
InitializeListHead(&Console->BufferList);
Status = ConSrvCreateScreenBuffer(Console,
&NewBuffer,
ConsoleInfo.ScreenBufferSize,
ConsoleInfo.ScreenAttrib,
ConsoleInfo.PopupAttrib,
(ConsoleInfo.FullScreen ? CONSOLE_FULLSCREEN_MODE
: CONSOLE_WINDOWED_MODE),
TRUE,
ConsoleInfo.CursorSize);
Status = ConSrvCreateScreenBuffer(&NewBuffer,
Console,
CONSOLE_TEXTMODE_BUFFER,
&ScreenBufferInfo);
if (!NT_SUCCESS(Status))
{
DPRINT1("ConSrvCreateScreenBuffer: failed, Status = 0x%08lx\n", Status);
@@ -642,7 +648,6 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole,
InitializeListHead(&Console->WriteWaitQueue);
Console->PauseFlags = 0;
Console->UnpauseEvent = NULL;
// HardwareState
/*
* Initialize the alias and history buffers
@@ -1043,7 +1048,7 @@ CSR_API(SrvGetConsoleMode)
ConsoleModeRequest->ConsoleMode = ConsoleMode;
}
else if (SCREEN_BUFFER == Object->Type)
else if (TEXTMODE_BUFFER == Object->Type || GRAPHICS_BUFFER == Object->Type)
{
PCONSOLE_SCREEN_BUFFER Buffer = (PCONSOLE_SCREEN_BUFFER)Object;
ConsoleModeRequest->ConsoleMode = Buffer->Mode;
@@ -1115,7 +1120,7 @@ CSR_API(SrvSetConsoleMode)
}
InputBuffer->Mode = (ConsoleMode & CONSOLE_VALID_INPUT_MODES);
}
else if (SCREEN_BUFFER == Object->Type)
else if (TEXTMODE_BUFFER == Object->Type || GRAPHICS_BUFFER == Object->Type)
{
PCONSOLE_SCREEN_BUFFER Buffer = (PCONSOLE_SCREEN_BUFFER)Object;
@@ -1242,6 +1247,7 @@ CSR_API(SrvSetConsoleTitle)
* ConsoleHwState has the correct size to be compatible
* with NT's, but values are not.
*/
#if 0
static NTSTATUS FASTCALL
SetConsoleHardwareState(PCONSOLE Console, ULONG ConsoleHwState)
{
@@ -1262,15 +1268,17 @@ SetConsoleHardwareState(PCONSOLE Console, ULONG ConsoleHwState)
return STATUS_INVALID_PARAMETER_3; /* Client: (handle, set_get, [mode]) */
}
#endif
CSR_API(SrvGetConsoleHardwareState)
{
#if 0
NTSTATUS Status;
PCONSOLE_GETSETHWSTATE HardwareStateRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HardwareStateRequest;
PCONSOLE_SCREEN_BUFFER Buff;
PCONSOLE Console;
Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
HardwareStateRequest->OutputHandle,
&Buff,
GENERIC_READ,
@@ -1286,16 +1294,21 @@ CSR_API(SrvGetConsoleHardwareState)
ConSrvReleaseScreenBuffer(Buff, TRUE);
return Status;
#else
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
#endif
}
CSR_API(SrvSetConsoleHardwareState)
{
#if 0
NTSTATUS Status;
PCONSOLE_GETSETHWSTATE HardwareStateRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.HardwareStateRequest;
PCONSOLE_SCREEN_BUFFER Buff;
PCONSOLE Console;
Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
HardwareStateRequest->OutputHandle,
&Buff,
GENERIC_WRITE,
@@ -1312,6 +1325,10 @@ CSR_API(SrvSetConsoleHardwareState)
ConSrvReleaseScreenBuffer(Buff, TRUE);
return Status;
#else
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
#endif
}
CSR_API(SrvGetConsoleDisplayMode)
@@ -1319,7 +1336,6 @@ CSR_API(SrvGetConsoleDisplayMode)
NTSTATUS Status;
PCONSOLE_GETDISPLAYMODE GetDisplayModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetDisplayModeRequest;
PCONSOLE Console;
ULONG DisplayMode = 0;
Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
&Console, TRUE);
@@ -1329,22 +1345,17 @@ CSR_API(SrvGetConsoleDisplayMode)
return Status;
}
if (Console->ActiveBuffer->DisplayMode & CONSOLE_FULLSCREEN_MODE)
DisplayMode |= CONSOLE_FULLSCREEN_HARDWARE; // CONSOLE_FULLSCREEN
else if (Console->ActiveBuffer->DisplayMode & CONSOLE_WINDOWED_MODE)
DisplayMode |= CONSOLE_WINDOWED;
GetDisplayModeRequest->DisplayMode = DisplayMode;
Status = STATUS_SUCCESS;
GetDisplayModeRequest->DisplayMode = ConioGetDisplayMode(Console);
ConSrvReleaseConsole(Console, TRUE);
return Status;
return STATUS_SUCCESS;
}
CSR_API(SrvSetConsoleDisplayMode)
{
NTSTATUS Status;
PCONSOLE_SETDISPLAYMODE SetDisplayModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetDisplayModeRequest;
PCONSOLE Console;
PCONSOLE_SCREEN_BUFFER Buff;
Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
@@ -1358,17 +1369,16 @@ CSR_API(SrvSetConsoleDisplayMode)
return Status;
}
if (SetDisplayModeRequest->DisplayMode & ~(CONSOLE_FULLSCREEN_MODE | CONSOLE_WINDOWED_MODE))
Console = Buff->Header.Console;
if (ConioSetDisplayMode(Console, SetDisplayModeRequest->DisplayMode))
{
Status = STATUS_INVALID_PARAMETER;
SetDisplayModeRequest->NewSBDim = Buff->ScreenBufferSize;
Status = STATUS_SUCCESS;
}
else
{
Buff->DisplayMode = SetDisplayModeRequest->DisplayMode;
// TODO: Change the display mode
SetDisplayModeRequest->NewSBDim = Buff->ScreenBufferSize;
Status = STATUS_SUCCESS;
Status = STATUS_INVALID_PARAMETER;
}
ConSrvReleaseScreenBuffer(Buff, TRUE);
@@ -1382,7 +1392,7 @@ CSR_API(SrvGetLargestConsoleWindowSize)
PCONSOLE_SCREEN_BUFFER Buff;
PCONSOLE Console;
Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
GetLargestWindowSizeRequest->OutputHandle,
&Buff,
GENERIC_READ,
@@ -1398,62 +1408,50 @@ CSR_API(SrvGetLargestConsoleWindowSize)
CSR_API(SrvSetConsoleWindowInfo)
{
#if 0
NTSTATUS Status;
#endif
PCONSOLE_SETWINDOWINFO SetWindowInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetWindowInfoRequest;
#if 0
PCONSOLE_SCREEN_BUFFER Buff;
PCONSOLE Console;
#endif
SMALL_RECT WindowRect = SetWindowInfoRequest->WindowRect;
#if 0
Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
SetWindowInfoRequest->OutputHandle,
&Buff,
GENERIC_READ,
TRUE);
if (!NT_SUCCESS(Status)) return Status;
DPRINT("SrvSetConsoleWindowInfo(0x%08x, %d, {L%d, T%d, R%d, B%d}) called\n",
SetWindowInfoRequest->OutputHandle, SetWindowInfoRequest->Absolute,
WindowRect.Left, WindowRect.Top, WindowRect.Right, WindowRect.Bottom);
Console = Buff->Header.Console;
Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
SetWindowInfoRequest->OutputHandle,
&Buff,
GENERIC_READ,
TRUE);
if (!NT_SUCCESS(Status)) return Status;
if (SetWindowInfoRequest->Absolute == FALSE)
{
/* Relative positions given. Transform them to absolute ones */
WindowRect.Left += Buff->ShowX;
WindowRect.Top += Buff->ShowY;
WindowRect.Right += Buff->ShowX + Console->ConsoleSize.X - 1;
WindowRect.Bottom += Buff->ShowY + Console->ConsoleSize.Y - 1;
WindowRect.Left += Buff->ViewOrigin.X;
WindowRect.Top += Buff->ViewOrigin.Y;
WindowRect.Right += Buff->ViewOrigin.X + Buff->ViewSize.X - 1;
WindowRect.Bottom += Buff->ViewOrigin.Y + Buff->ViewSize.Y - 1;
}
if ( (WindowRect.Left < 0) || (WindowRect.Top < 0) ||
(WindowRect.Right > ScreenBufferSize.X) ||
(WindowRect.Bottom > ScreenBufferSize.Y) ||
(WindowRect.Right <= WindowRect.Left) ||
/* See MSDN documentation on SetConsoleWindowInfo about the performed checks */
if ( (WindowRect.Left < 0) || (WindowRect.Top < 0) ||
(WindowRect.Right >= Buff->ScreenBufferSize.X) ||
(WindowRect.Bottom >= Buff->ScreenBufferSize.Y) ||
(WindowRect.Right <= WindowRect.Left) ||
(WindowRect.Bottom <= WindowRect.Top) )
{
ConSrvReleaseScreenBuffer(Buff, TRUE);
return STATUS_INVALID_PARAMETER;
}
Buff->ShowX = WindowRect.Left;
Buff->ShowY = WindowRect.Top;
Buff->ViewOrigin.X = WindowRect.Left;
Buff->ViewOrigin.Y = WindowRect.Top;
// These two lines are frontend-specific.
Console->ConsoleSize.X = WindowRect.Right - WindowRect.Left + 1;
Console->ConsoleSize.Y = WindowRect.Bottom - WindowRect.Top + 1;
// ConioGetLargestConsoleWindowSize(Console, &GetLargestWindowSizeRequest->Size);
Buff->ViewSize.X = WindowRect.Right - WindowRect.Left + 1;
Buff->ViewSize.Y = WindowRect.Bottom - WindowRect.Top + 1;
ConSrvReleaseScreenBuffer(Buff, TRUE);
return STATUS_SUCCESS;
#else
DPRINT1("SrvSetConsoleWindowInfo(0x%08x, %d, {L%d, T%d, R%d, B%d}) UNIMPLEMENTED\n",
SetWindowInfoRequest->OutputHandle, SetWindowInfoRequest->Absolute,
WindowRect.Left, WindowRect.Top, WindowRect.Right, WindowRect.Bottom);
return STATUS_NOT_IMPLEMENTED;
#endif
}
CSR_API(SrvGetConsoleWindow)
+1
View File
@@ -24,6 +24,7 @@
#include <wincon.h>
#include <winuser.h>
#define NTOS_MODE_USER
#include <ndk/exfuncs.h>
#include <ndk/iofuncs.h>
#include <ndk/mmfuncs.h>
#include <ndk/obfuncs.h>
@@ -0,0 +1,81 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Console Server DLL
* FILE: win32ss/user/consrv/frontends/gui/graphics.c
* PURPOSE: GUI Terminal Front-End - Support for graphics-mode screen-buffers
* PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
*/
/* INCLUDES *******************************************************************/
#include "consrv.h"
#include "include/conio.h"
#include "include/settings.h"
#include "guisettings.h"
#define NDEBUG
#include <debug.h>
/* FUNCTIONS ******************************************************************/
VOID
GuiCopyFromGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer)
{
/*
* This function supposes that the system clipboard was opened.
*/
// PCONSOLE Console = Buffer->Header.Console;
UNIMPLEMENTED;
}
VOID
GuiPasteToGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer)
{
/*
* This function supposes that the system clipboard was opened.
*/
// PCONSOLE Console = Buffer->Header.Console;
UNIMPLEMENTED;
}
VOID
GuiPaintGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer,
PGUI_CONSOLE_DATA GuiData,
HDC hDC,
PRECT rc)
{
if (Buffer->BitMap == NULL) return;
/* Grab the mutex */
NtWaitForSingleObject(Buffer->Mutex, FALSE, NULL);
/*
* The seventh parameter (YSrc) of SetDIBitsToDevice always designates
* the Y-coordinate of the "lower-left corner" of the image, be the DIB
* in bottom-up or top-down mode.
*/
SetDIBitsToDevice(hDC,
/* Coordinates / size of the repainted rectangle, in the view's frame */
rc->left,
rc->top,
rc->right - rc->left,
rc->bottom - rc->top,
/* Coordinates / size of the corresponding image portion, in the graphics screen-buffer's frame */
Buffer->ViewOrigin.X + rc->left,
Buffer->ViewOrigin.Y + rc->top,
0,
Buffer->ScreenBufferSize.Y, // == Buffer->BitMapInfo->bmiHeader.biHeight
Buffer->BitMap,
Buffer->BitMapInfo,
Buffer->BitMapUsage);
/* Release the mutex */
NtReleaseMutant(Buffer->Mutex, NULL);
}
/* EOF */
@@ -106,6 +106,11 @@ GuiConsoleReadUserSettings(IN OUT PGUI_CONSOLE_INFO TermInfo,
TermInfo->FontWeight = Value;
RetVal = TRUE;
}
else if (!wcscmp(szValueName, L"FullScreen"))
{
TermInfo->FullScreen = Value;
RetVal = TRUE;
}
else if (!wcscmp(szValueName, L"WindowPosition"))
{
TermInfo->AutoPosition = FALSE;
@@ -157,6 +162,9 @@ do {
SetConsoleSetting(L"FontSize", REG_DWORD, sizeof(DWORD), &TermInfo->FontSize, 0);
SetConsoleSetting(L"FontWeight", REG_DWORD, sizeof(DWORD), &TermInfo->FontWeight, FW_DONTCARE);
Storage = TermInfo->FullScreen;
SetConsoleSetting(L"FullScreen", REG_DWORD, sizeof(DWORD), &Storage, FALSE);
if (TermInfo->AutoPosition == FALSE)
{
Storage = MAKELONG(TermInfo->WindowOrigin.x, TermInfo->WindowOrigin.y);
@@ -192,10 +200,11 @@ GuiConsoleGetDefaultSettings(IN OUT PGUI_CONSOLE_INFO TermInfo,
wcsncpy(TermInfo->FaceName, L"Fixedsys", LF_FACESIZE); // HACK: !!
// TermInfo->FaceName[0] = L'\0';
TermInfo->FontFamily = FF_DONTCARE;
TermInfo->FontSize = 0;
TermInfo->FontSize = 0;
TermInfo->FontWeight = FW_DONTCARE;
TermInfo->UseRasterFonts = TRUE;
TermInfo->FullScreen = FALSE;
TermInfo->ShowWindow = SW_SHOWNORMAL;
TermInfo->AutoPosition = TRUE;
TermInfo->WindowOrigin.x = 0;
@@ -218,6 +227,7 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
{
NTSTATUS Status;
PCONSOLE Console = GuiData->Console;
PCONSOLE_SCREEN_BUFFER ActiveBuffer = Console->ActiveBuffer;
PCONSOLE_PROCESS_DATA ProcessData;
HANDLE hSection = NULL, hClientSection = NULL;
LARGE_INTEGER SectionSize;
@@ -282,17 +292,30 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
pSharedInfo->ci.HistoryBufferSize = Console->HistoryBufferSize;
pSharedInfo->ci.NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers;
pSharedInfo->ci.HistoryNoDup = Console->HistoryNoDup;
pSharedInfo->ci.FullScreen = !!(Console->ActiveBuffer->DisplayMode & CONSOLE_FULLSCREEN_MODE);
pSharedInfo->ci.QuickEdit = Console->QuickEdit;
pSharedInfo->ci.InsertMode = Console->InsertMode;
pSharedInfo->ci.InputBufferSize = 0;
pSharedInfo->ci.ScreenBufferSize = Console->ActiveBuffer->ScreenBufferSize;
pSharedInfo->ci.ConsoleSize = Console->ConsoleSize;
pSharedInfo->ci.ScreenBufferSize = ActiveBuffer->ScreenBufferSize;
pSharedInfo->ci.ConsoleSize = ActiveBuffer->ViewSize;
pSharedInfo->ci.CursorBlinkOn;
pSharedInfo->ci.ForceCursorOff;
pSharedInfo->ci.CursorSize = Console->ActiveBuffer->CursorInfo.dwSize;
pSharedInfo->ci.ScreenAttrib = Console->ActiveBuffer->ScreenDefaultAttrib;
pSharedInfo->ci.PopupAttrib = Console->ActiveBuffer->PopupDefaultAttrib;
pSharedInfo->ci.CursorSize = ActiveBuffer->CursorInfo.dwSize;
if (GetType(ActiveBuffer) == TEXTMODE_BUFFER)
{
PTEXTMODE_SCREEN_BUFFER Buffer = (PTEXTMODE_SCREEN_BUFFER)ActiveBuffer;
pSharedInfo->ci.ScreenAttrib = Buffer->ScreenDefaultAttrib;
pSharedInfo->ci.PopupAttrib = Buffer->PopupDefaultAttrib;
}
else // if (GetType(ActiveBuffer) == GRAPHICS_BUFFER)
{
// PGRAPHICS_SCREEN_BUFFER Buffer = (PGRAPHICS_SCREEN_BUFFER)ActiveBuffer;
DPRINT1("GuiConsoleShowConsoleProperties - Graphics buffer\n");
// FIXME: Gather defaults from the registry ?
pSharedInfo->ci.ScreenAttrib = DEFAULT_SCREEN_ATTRIB;
pSharedInfo->ci.PopupAttrib = DEFAULT_POPUP_ATTRIB ;
}
pSharedInfo->ci.CodePage;
/* GUI Information */
@@ -302,9 +325,10 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
wcsncpy(GuiInfo->FaceName, GuiData->GuiInfo.FaceName, LF_FACESIZE);
GuiInfo->FaceName[Length] = L'\0';
GuiInfo->FontFamily = GuiData->GuiInfo.FontFamily;
GuiInfo->FontSize = GuiData->GuiInfo.FontSize;
GuiInfo->FontSize = GuiData->GuiInfo.FontSize;
GuiInfo->FontWeight = GuiData->GuiInfo.FontWeight;
GuiInfo->UseRasterFonts = GuiData->GuiInfo.UseRasterFonts;
GuiInfo->FullScreen = GuiData->GuiInfo.FullScreen;
/// GuiInfo->WindowPosition = GuiData->GuiInfo.WindowPosition;
GuiInfo->AutoPosition = GuiData->GuiInfo.AutoPosition;
GuiInfo->WindowOrigin = GuiData->GuiInfo.WindowOrigin;
@@ -322,6 +346,7 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
else
{
Length = 0;
// FIXME: Load the default parameters from the registry.
}
/* Null-terminate the title */
@@ -478,6 +503,12 @@ GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
GuiConsoleMoveWindow(GuiData);
InvalidateRect(GuiData->hWindow, NULL, TRUE);
/*
* Apply full-screen mode.
*/
GuiData->GuiInfo.FullScreen = GuiInfo->FullScreen;
// TODO: Apply it really
}
/*
@@ -27,6 +27,9 @@ typedef struct _GUI_CONSOLE_INFO
DWORD FontWeight;
BOOL UseRasterFonts;
BOOL FullScreen; /* Whether the console is displayed in full-screen or windowed mode */
// ULONG HardwareState; /* _GDI_MANAGED, _DIRECT */
WORD ShowWindow;
BOOL AutoPosition;
POINT WindowOrigin;
@@ -44,9 +47,10 @@ typedef struct _GUI_CONSOLE_DATA
HWND hWindow; /* Handle to the console's window */
HICON hIcon; /* Handle to the console's icon (big) */
HICON hIconSm; /* Handle to the console's icon (small) */
// COLORREF Colors[16];
BOOL IgnoreNextMouseSignal; /* Used in cases where we don't want to treat a mouse signal */
// COLORREF Colors[16];
// PVOID ScreenBuffer; /* Hardware screen buffer */
// PVOID ScreenBuffer; /* Hardware screen buffer */
HFONT Font;
UINT CharWidth;
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,281 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Console Server DLL
* FILE: win32ss/user/consrv/frontends/gui/text.c
* PURPOSE: GUI Terminal Front-End - Support for text-mode screen-buffers
* PROGRAMMERS: van Geldorp
* Johannes Anderwald
* Jeffrey Morlan
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
*/
/* INCLUDES *******************************************************************/
#include "consrv.h"
#include "include/conio.h"
#include "include/settings.h"
#include "guisettings.h"
#define NDEBUG
#include <debug.h>
/* GLOBALS ********************************************************************/
/* Copied from consrv/text.c */
#define ConsoleAnsiCharToUnicodeChar(Console, dWChar, sChar) \
MultiByteToWideChar((Console)->OutputCodePage, 0, (sChar), 1, (dWChar), 1)
/* FUNCTIONS ******************************************************************/
VOID
GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer)
{
/*
* This function supposes that the system clipboard was opened.
*/
PCONSOLE Console = Buffer->Header.Console;
HANDLE hData;
PBYTE ptr;
LPWSTR data, dstPos;
ULONG selWidth, selHeight;
ULONG xPos, yPos, size;
selWidth = Console->Selection.srSelection.Right - Console->Selection.srSelection.Left + 1;
selHeight = Console->Selection.srSelection.Bottom - Console->Selection.srSelection.Top + 1;
DPRINT("Selection is (%d|%d) to (%d|%d)\n",
Console->Selection.srSelection.Left,
Console->Selection.srSelection.Top,
Console->Selection.srSelection.Right,
Console->Selection.srSelection.Bottom);
/* Basic size for one line and termination */
size = selWidth + 1;
if (selHeight > 0)
{
/* Multiple line selections have to get \r\n appended */
size += ((selWidth + 2) * (selHeight - 1));
}
size *= sizeof(WCHAR);
/* Allocate memory, it will be passed to the system and may not be freed here */
hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, size);
if (hData == NULL) return;
data = GlobalLock(hData);
if (data == NULL) return;
DPRINT("Copying %dx%d selection\n", selWidth, selHeight);
dstPos = data;
for (yPos = 0; yPos < selHeight; yPos++)
{
ptr = ConioCoordToPointer(Buffer,
Console->Selection.srSelection.Left,
yPos + Console->Selection.srSelection.Top);
/* Copy only the characters, leave attributes alone */
for (xPos = 0; xPos < selWidth; xPos++)
{
ConsoleAnsiCharToUnicodeChar(Console, &dstPos[xPos], (LPCSTR)&ptr[xPos * 2]);
}
dstPos += selWidth;
if (yPos != (selHeight - 1))
{
wcscat(data, L"\r\n");
dstPos += 2;
}
}
DPRINT("Setting data <%S> to clipboard\n", data);
GlobalUnlock(hData);
EmptyClipboard();
SetClipboardData(CF_UNICODETEXT, hData);
}
VOID
GuiPasteToTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer)
{
/*
* This function supposes that the system clipboard was opened.
*/
PCONSOLE Console = Buffer->Header.Console;
HANDLE hData;
LPWSTR str;
WCHAR CurChar = 0;
SHORT VkKey; // MAKEWORD(low = vkey_code, high = shift_state);
INPUT_RECORD er;
hData = GetClipboardData(CF_UNICODETEXT);
if (hData == NULL) return;
str = GlobalLock(hData);
if (str == NULL) return;
DPRINT("Got data <%S> from clipboard\n", str);
er.EventType = KEY_EVENT;
er.Event.KeyEvent.wRepeatCount = 1;
while (*str)
{
/* \r or \n characters. Go to the line only if we get "\r\n" sequence. */
if (CurChar == L'\r' && *str == L'\n')
{
str++;
continue;
}
CurChar = *str++;
/* Get the key code (+ shift state) corresponding to the character */
VkKey = VkKeyScanW(CurChar);
if (VkKey == 0xFFFF)
{
DPRINT1("VkKeyScanW failed - Should simulate the key...\n");
continue;
}
/* Pressing some control keys */
/* Pressing the character key, with the control keys maintained pressed */
er.Event.KeyEvent.bKeyDown = TRUE;
er.Event.KeyEvent.wVirtualKeyCode = LOBYTE(VkKey);
er.Event.KeyEvent.wVirtualScanCode = MapVirtualKeyW(LOBYTE(VkKey), MAPVK_VK_TO_CHAR);
er.Event.KeyEvent.uChar.UnicodeChar = CurChar;
er.Event.KeyEvent.dwControlKeyState = 0;
if (HIBYTE(VkKey) & 1)
er.Event.KeyEvent.dwControlKeyState |= SHIFT_PRESSED;
if (HIBYTE(VkKey) & 2)
er.Event.KeyEvent.dwControlKeyState |= LEFT_CTRL_PRESSED; // RIGHT_CTRL_PRESSED;
if (HIBYTE(VkKey) & 4)
er.Event.KeyEvent.dwControlKeyState |= LEFT_ALT_PRESSED; // RIGHT_ALT_PRESSED;
ConioProcessInputEvent(Console, &er);
/* Up all the character and control keys */
er.Event.KeyEvent.bKeyDown = FALSE;
ConioProcessInputEvent(Console, &er);
}
GlobalUnlock(hData);
}
VOID
GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
PGUI_CONSOLE_DATA GuiData,
HDC hDC,
PRECT rc)
{
PCONSOLE Console = Buffer->Header.Console;
// ASSERT(Console == GuiData->Console);
ULONG TopLine, BottomLine, LeftChar, RightChar;
ULONG Line, Char, Start;
PBYTE From;
PWCHAR To;
BYTE LastAttribute, Attribute;
ULONG CursorX, CursorY, CursorHeight;
HBRUSH CursorBrush, OldBrush;
HFONT OldFont;
if (Buffer->Buffer == NULL) return;
TopLine = rc->top / GuiData->CharHeight + Buffer->ViewOrigin.Y;
BottomLine = (rc->bottom + (GuiData->CharHeight - 1)) / GuiData->CharHeight - 1 + Buffer->ViewOrigin.Y;
LeftChar = rc->left / GuiData->CharWidth + Buffer->ViewOrigin.X;
RightChar = (rc->right + (GuiData->CharWidth - 1)) / GuiData->CharWidth - 1 + Buffer->ViewOrigin.X;
LastAttribute = ConioCoordToPointer(Buffer, LeftChar, TopLine)[1];
SetTextColor(hDC, RGBFromAttrib(Console, TextAttribFromAttrib(LastAttribute)));
SetBkColor(hDC, RGBFromAttrib(Console, BkgdAttribFromAttrib(LastAttribute)));
if (BottomLine >= Buffer->ScreenBufferSize.Y) BottomLine = Buffer->ScreenBufferSize.Y - 1;
if (RightChar >= Buffer->ScreenBufferSize.X) RightChar = Buffer->ScreenBufferSize.X - 1;
OldFont = SelectObject(hDC, GuiData->Font);
for (Line = TopLine; Line <= BottomLine; Line++)
{
WCHAR LineBuffer[80];
From = ConioCoordToPointer(Buffer, LeftChar, Line);
Start = LeftChar;
To = LineBuffer;
for (Char = LeftChar; Char <= RightChar; Char++)
{
if (*(From + 1) != LastAttribute || (Char - Start == sizeof(LineBuffer) / sizeof(WCHAR)))
{
TextOutW(hDC,
(Start - Buffer->ViewOrigin.X) * GuiData->CharWidth,
(Line - Buffer->ViewOrigin.Y) * GuiData->CharHeight,
LineBuffer,
Char - Start);
Start = Char;
To = LineBuffer;
Attribute = *(From + 1);
if (Attribute != LastAttribute)
{
SetTextColor(hDC, RGBFromAttrib(Console, TextAttribFromAttrib(Attribute)));
SetBkColor(hDC, RGBFromAttrib(Console, BkgdAttribFromAttrib(Attribute)));
LastAttribute = Attribute;
}
}
MultiByteToWideChar(Console->OutputCodePage,
0, (PCHAR)From, 1, To, 1);
To++;
From += 2;
}
TextOutW(hDC,
(Start - Buffer->ViewOrigin.X) * GuiData->CharWidth,
(Line - Buffer->ViewOrigin.Y) * GuiData->CharHeight,
LineBuffer,
RightChar - Start + 1);
}
/*
* Draw the caret
*/
if (Buffer->CursorInfo.bVisible &&
Buffer->CursorBlinkOn &&
!Buffer->ForceCursorOff)
{
CursorX = Buffer->CursorPosition.X;
CursorY = Buffer->CursorPosition.Y;
if (LeftChar <= CursorX && CursorX <= RightChar &&
TopLine <= CursorY && CursorY <= BottomLine)
{
CursorHeight = ConioEffectiveCursorSize(Console, GuiData->CharHeight);
From = ConioCoordToPointer(Buffer, Buffer->CursorPosition.X, Buffer->CursorPosition.Y) + 1;
if (*From != DEFAULT_SCREEN_ATTRIB)
{
CursorBrush = CreateSolidBrush(RGBFromAttrib(Console, *From));
}
else
{
CursorBrush = CreateSolidBrush(RGBFromAttrib(Console, Buffer->ScreenDefaultAttrib));
}
OldBrush = SelectObject(hDC, CursorBrush);
PatBlt(hDC,
(CursorX - Buffer->ViewOrigin.X) * GuiData->CharWidth,
(CursorY - Buffer->ViewOrigin.Y) * GuiData->CharHeight + (GuiData->CharHeight - CursorHeight),
GuiData->CharWidth,
CursorHeight,
PATCOPY);
SelectObject(hDC, OldBrush);
DeleteObject(CursorBrush);
}
}
SelectObject(hDC, OldFont);
}
/* EOF */
@@ -230,7 +230,7 @@ TuiSwapConsole(INT Next)
}
static VOID FASTCALL
TuiCopyRect(char *Dest, PCONSOLE_SCREEN_BUFFER Buff, SMALL_RECT* Region)
TuiCopyRect(char *Dest, PTEXTMODE_SCREEN_BUFFER Buff, SMALL_RECT* Region)
{
UINT SrcDelta, DestDelta;
LONG i;
@@ -476,21 +476,6 @@ TuiCleanupConsole(PCONSOLE Console)
ConsoleFreeHeap(TuiData);
}
static VOID WINAPI
TuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, SHORT CursorStartX, SHORT CursorStartY,
UINT ScrolledLines, CHAR *Buffer, UINT Length)
{
DWORD BytesWritten;
PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer;
if (ActiveConsole->Console->ActiveBuffer != Buff) return;
if (!WriteFile(ConsoleDeviceHandle, Buffer, Length, &BytesWritten, NULL))
{
DPRINT1("Error writing to BlueScreen\n");
}
}
static VOID WINAPI
TuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region)
{
@@ -499,7 +484,7 @@ TuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region)
PCONSOLE_DRAW ConsoleDraw;
UINT ConsoleDrawSize;
if (ActiveConsole->Console != Console) return;
if (ActiveConsole->Console != Console || GetType(Buff) != TEXTMODE_BUFFER) return;
ConsoleDrawSize = sizeof(CONSOLE_DRAW) +
(ConioRectWidth(Region) * ConioRectHeight(Region)) * 2;
@@ -516,7 +501,7 @@ TuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region)
ConsoleDraw->CursorX = Buff->CursorPosition.X;
ConsoleDraw->CursorY = Buff->CursorPosition.Y;
TuiCopyRect((char *) (ConsoleDraw + 1), Buff, Region);
TuiCopyRect((char*)(ConsoleDraw + 1), (PTEXTMODE_SCREEN_BUFFER)Buff, Region);
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_DRAW,
NULL, 0, ConsoleDraw, ConsoleDrawSize, &BytesReturned, NULL))
@@ -529,6 +514,21 @@ TuiDrawRegion(PCONSOLE Console, SMALL_RECT* Region)
ConsoleFreeHeap(ConsoleDraw);
}
static VOID WINAPI
TuiWriteStream(PCONSOLE Console, SMALL_RECT* Region, SHORT CursorStartX, SHORT CursorStartY,
UINT ScrolledLines, CHAR *Buffer, UINT Length)
{
DWORD BytesWritten;
PCONSOLE_SCREEN_BUFFER Buff = Console->ActiveBuffer;
if (ActiveConsole->Console->ActiveBuffer != Buff) return;
if (!WriteFile(ConsoleDeviceHandle, Buffer, Length, &BytesWritten, NULL))
{
DPRINT1("Error writing to BlueScreen\n");
}
}
static BOOL WINAPI
TuiSetCursorInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff)
{
@@ -557,9 +557,10 @@ TuiSetScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff, SHORT OldCursorX
DWORD BytesReturned;
if (ActiveConsole->Console->ActiveBuffer != Buff) return TRUE;
if (GetType(Buff) != TEXTMODE_BUFFER) return FALSE;
Info.dwCursorPosition = Buff->CursorPosition;
Info.wAttributes = Buff->ScreenDefaultAttrib;
Info.wAttributes = ((PTEXTMODE_SCREEN_BUFFER)Buff)->ScreenDefaultAttrib;
if (!DeviceIoControl(ConsoleDeviceHandle, IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO,
&Info, sizeof(CONSOLE_SCREEN_BUFFER_INFO), NULL, 0,
@@ -572,18 +573,6 @@ TuiSetScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff, SHORT OldCursorX
return TRUE;
}
static BOOL WINAPI
TuiUpdateScreenInfo(PCONSOLE Console, PCONSOLE_SCREEN_BUFFER Buff)
{
return TRUE;
}
static BOOL WINAPI
TuiIsBufferResizeSupported(PCONSOLE Console)
{
return (Console && Console->State == CONSOLE_INITIALIZING ? TRUE : FALSE);
}
static VOID WINAPI
TuiResizeTerminal(PCONSOLE Console)
{
@@ -640,22 +629,36 @@ TuiGetLargestConsoleWindowSize(PCONSOLE Console, PCOORD pSize)
*pSize = PhysicalConsoleSize;
}
static ULONG WINAPI
TuiGetDisplayMode(PCONSOLE Console)
{
return CONSOLE_FULLSCREEN_HARDWARE; // CONSOLE_FULLSCREEN;
}
static BOOL WINAPI
TuiSetDisplayMode(PCONSOLE Console, ULONG NewMode)
{
// if (NewMode & ~(CONSOLE_FULLSCREEN_MODE | CONSOLE_WINDOWED_MODE))
// return FALSE;
return TRUE;
}
static FRONTEND_VTBL TuiVtbl =
{
TuiCleanupConsole,
TuiWriteStream,
TuiDrawRegion,
TuiWriteStream,
TuiSetCursorInfo,
TuiSetScreenInfo,
TuiUpdateScreenInfo,
TuiIsBufferResizeSupported,
TuiResizeTerminal,
TuiProcessKeyCallback,
TuiRefreshInternalInfo,
TuiChangeTitle,
TuiChangeIcon,
TuiGetConsoleWindowHandle,
TuiGetLargestConsoleWindowSize
TuiGetLargestConsoleWindowSize,
TuiGetDisplayMode,
TuiSetDisplayMode,
};
NTSTATUS FASTCALL
@@ -670,6 +673,9 @@ TuiInitConsole(PCONSOLE Console,
if (Console == NULL || ConsoleInfo == NULL)
return STATUS_INVALID_PARAMETER;
if (GetType(Console->ActiveBuffer) != TEXTMODE_BUFFER)
return STATUS_INVALID_PARAMETER;
/* Initialize the TUI terminal emulator */
if (!TuiInit(Console->CodePage)) return STATUS_UNSUCCESSFUL;
@@ -693,8 +699,10 @@ TuiInitConsole(PCONSOLE Console,
* the console size when we display it with the hardware.
*/
Console->ConsoleSize = PhysicalConsoleSize;
ConioResizeBuffer(Console, Console->ActiveBuffer, PhysicalConsoleSize);
Console->ActiveBuffer->DisplayMode |= CONSOLE_FULLSCREEN_MODE;
ConioResizeBuffer(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), PhysicalConsoleSize);
/* The console cannot be resized anymore */
Console->FixedSize = TRUE; // MUST be placed AFTER the call to ConioResizeBuffer !!
// ConioResizeTerminal(Console);
/*
+274
View File
@@ -0,0 +1,274 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Console Server DLL
* FILE: win32ss/user/consrv/graphics.c
* PURPOSE: Console Output Functions for graphics-mode screen-buffers
* PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
*
* NOTE: See http://blog.airesoft.co.uk/2012/10/things-ms-can-do-that-they-dont-tell-you-about-console-graphics/
* for more information.
*/
/* INCLUDES *******************************************************************/
#include "consrv.h"
#include "include/conio.h"
#include "conio.h"
#include "conoutput.h"
#include "handle.h"
#define NDEBUG
#include <debug.h>
/* PRIVATE FUNCTIONS **********************************************************/
CONSOLE_IO_OBJECT_TYPE
GRAPHICS_BUFFER_GetType(PCONSOLE_SCREEN_BUFFER This)
{
// return This->Header.Type;
return GRAPHICS_BUFFER;
}
static CONSOLE_SCREEN_BUFFER_VTBL GraphicsVtbl =
{
GRAPHICS_BUFFER_GetType,
};
NTSTATUS
CONSOLE_SCREEN_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
IN OUT PCONSOLE Console,
IN SIZE_T Size);
VOID
CONSOLE_SCREEN_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer);
NTSTATUS
GRAPHICS_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
IN OUT PCONSOLE Console,
IN PGRAPHICS_BUFFER_INFO GraphicsInfo)
{
NTSTATUS Status = STATUS_SUCCESS;
PGRAPHICS_SCREEN_BUFFER NewBuffer = NULL;
LARGE_INTEGER SectionSize;
ULONG ViewSize = 0;
HANDLE ProcessHandle;
if (Buffer == NULL || Console == NULL || GraphicsInfo == NULL)
return STATUS_INVALID_PARAMETER;
*Buffer = NULL;
Status = CONSOLE_SCREEN_BUFFER_Initialize((PCONSOLE_SCREEN_BUFFER*)&NewBuffer,
Console,
sizeof(GRAPHICS_SCREEN_BUFFER));
if (!NT_SUCCESS(Status)) return Status;
NewBuffer->Header.Type = GRAPHICS_BUFFER;
NewBuffer->Vtbl = &GraphicsVtbl;
/*
* 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;
NewBuffer->ClientProcess = ProcessHandle;
/* Get infos from the graphics buffer information structure */
NewBuffer->BitMapInfoLength = GraphicsInfo->Info.dwBitMapInfoLength;
NewBuffer->BitMapInfo = ConsoleAllocHeap(HEAP_ZERO_MEMORY, NewBuffer->BitMapInfoLength);
if (NewBuffer->BitMapInfo == NULL)
{
CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Adjust the bitmap height if needed (bottom-top vs. top-bottom). Use always bottom-up. */
if (GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight > 0)
GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight = -GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight;
/* We do not use anything else than uncompressed bitmaps */
if (GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression != BI_RGB)
{
DPRINT1("biCompression == %d != BI_RGB, correct that!\n", GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression);
GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression = BI_RGB;
}
RtlCopyMemory(NewBuffer->BitMapInfo,
GraphicsInfo->Info.lpBitMapInfo,
GraphicsInfo->Info.dwBitMapInfoLength);
NewBuffer->BitMapUsage = GraphicsInfo->Info.dwUsage;
/* Set the screen buffer size. Fight against overflows. */
if ( GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biWidth <= 0xFFFF &&
-GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight <= 0xFFFF )
{
/* Be careful about the sign of biHeight */
NewBuffer->ScreenBufferSize.X = (SHORT)GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biWidth ;
NewBuffer->ScreenBufferSize.Y = (SHORT)-GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biHeight;
NewBuffer->OldViewSize = NewBuffer->ViewSize =
NewBuffer->OldScreenBufferSize = NewBuffer->ScreenBufferSize;
}
else
{
Status = STATUS_INSUFFICIENT_RESOURCES;
ConsoleFreeHeap(NewBuffer->BitMapInfo);
CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
goto Quit;
}
/*
* Create a mutex to synchronize bitmap memory access
* between ourselves and the client.
*/
Status = NtCreateMutant(&NewBuffer->Mutex, MUTANT_ALL_ACCESS, NULL, FALSE);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtCreateMutant() failed: %lu\n", Status);
ConsoleFreeHeap(NewBuffer->BitMapInfo);
CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
goto Quit;
}
/*
* Duplicate the Mutex for the client. We must keep a trace of it
* so that we can close it when the client releases the screen buffer.
*/
Status = NtDuplicateObject(NtCurrentProcess(),
NewBuffer->Mutex,
ProcessHandle,
&NewBuffer->ClientMutex,
0, 0, DUPLICATE_SAME_ACCESS);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
NtClose(NewBuffer->Mutex);
ConsoleFreeHeap(NewBuffer->BitMapInfo);
CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
goto Quit;
}
/*
* Create a memory section for the bitmap area, to share with the client.
*/
SectionSize.QuadPart = NewBuffer->BitMapInfo->bmiHeader.biSizeImage;
Status = NtCreateSection(&NewBuffer->hSection,
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);
NtClose(NewBuffer->ClientMutex);
NtClose(NewBuffer->Mutex);
ConsoleFreeHeap(NewBuffer->BitMapInfo);
CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
goto Quit;
}
/*
* Create a view for our needs.
*/
ViewSize = 0;
NewBuffer->BitMap = NULL;
Status = NtMapViewOfSection(NewBuffer->hSection,
NtCurrentProcess(),
(PVOID*)&NewBuffer->BitMap,
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(NewBuffer->hSection);
NtClose(NewBuffer->ClientMutex);
NtClose(NewBuffer->Mutex);
ConsoleFreeHeap(NewBuffer->BitMapInfo);
CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
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 screen buffer.
*/
ViewSize = 0;
NewBuffer->ClientBitMap = NULL;
Status = NtMapViewOfSection(NewBuffer->hSection,
ProcessHandle,
(PVOID*)&NewBuffer->ClientBitMap,
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(), NewBuffer->BitMap);
NtClose(NewBuffer->hSection);
NtClose(NewBuffer->ClientMutex);
NtClose(NewBuffer->Mutex);
ConsoleFreeHeap(NewBuffer->BitMapInfo);
CONSOLE_SCREEN_BUFFER_Destroy((PCONSOLE_SCREEN_BUFFER)NewBuffer);
goto Quit;
}
NewBuffer->ViewOrigin.X = NewBuffer->ViewOrigin.Y = 0;
NewBuffer->VirtualY = 0;
NewBuffer->CursorBlinkOn = FALSE;
NewBuffer->ForceCursorOff = TRUE;
NewBuffer->CursorInfo.bVisible = FALSE;
NewBuffer->CursorInfo.dwSize = 0;
NewBuffer->CursorPosition.X = NewBuffer->CursorPosition.Y = 0;
NewBuffer->Mode = 0;
*Buffer = (PCONSOLE_SCREEN_BUFFER)NewBuffer;
Status = STATUS_SUCCESS;
Quit:
return Status;
}
VOID
GRAPHICS_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer)
{
PGRAPHICS_SCREEN_BUFFER Buff = (PGRAPHICS_SCREEN_BUFFER)Buffer;
/*
* IMPORTANT !! Reinitialize the type so that we don't enter a recursive
* infinite loop when calling CONSOLE_SCREEN_BUFFER_Destroy.
*/
Buffer->Header.Type = SCREEN_BUFFER;
/*
* Uninitialize the graphics screen buffer
* in the reverse way we initialized it.
*/
NtUnmapViewOfSection(Buff->ClientProcess, Buff->ClientBitMap);
NtUnmapViewOfSection(NtCurrentProcess(), Buff->BitMap);
NtClose(Buff->hSection);
NtClose(Buff->ClientMutex);
NtClose(Buff->Mutex);
ConsoleFreeHeap(Buff->BitMapInfo);
CONSOLE_SCREEN_BUFFER_Destroy(Buffer);
}
/* EOF */
+8 -3
View File
@@ -101,7 +101,7 @@ ConSrvCloseHandleEntry(PCONSOLE_IO_HANDLE Entry)
/* If the last handle to a screen buffer is closed, delete it... */
if (AdjustHandleCounts(Entry, -1) == 0)
{
if (Object->Type == SCREEN_BUFFER)
if (Object->Type == TEXTMODE_BUFFER || Object->Type == GRAPHICS_BUFFER)
{
PCONSOLE_SCREEN_BUFFER Buffer = (PCONSOLE_SCREEN_BUFFER)Object;
/* ...unless it's the only buffer left. Windows allows deletion
@@ -114,6 +114,10 @@ ConSrvCloseHandleEntry(PCONSOLE_IO_HANDLE Entry)
{
DPRINT("Closing the input buffer\n");
}
else
{
DPRINT1("Invalid object type %d\n", Object->Type);
}
}
/// LOCK /// LeaveCriticalSection(&Console->Lock);
@@ -429,9 +433,10 @@ ConSrvGetObject(PCONSOLE_PROCESS_DATA ProcessData,
if ( HandleEntry == NULL ||
ObjectEntry == NULL ||
(HandleEntry->Access & Access) == 0 ||
(Type != 0 && ObjectEntry->Type != Type) )
/*(Type != 0 && ObjectEntry->Type != Type)*/
(Type != 0 && (ObjectEntry->Type & Type) == 0) )
{
DPRINT1("ConSrvGetObject returning invalid handle (%x) of type %lu with access %lu\n", Handle, Type, Access);
DPRINT1("ConSrvGetObject returning invalid handle (%x) of type %lu with access %lu ; wanted type %lu with access %lu\n", Handle, ObjectEntry->Type, HandleEntry->Access, Type, Access);
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_INVALID_HANDLE;
}
+156 -46
View File
@@ -20,8 +20,11 @@
/* Object type magic numbers */
typedef enum _CONSOLE_IO_OBJECT_TYPE
{
INPUT_BUFFER = 0x01, // --> Input-type handles
SCREEN_BUFFER = 0x02 // --> Output-type handles
// 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
SCREEN_BUFFER = 0x03, // --> Any SB type
INPUT_BUFFER = 0x04 // --> Input-type handles
} CONSOLE_IO_OBJECT_TYPE;
typedef struct _CONSOLE_IO_OBJECT
@@ -33,6 +36,69 @@ typedef struct _CONSOLE_IO_OBJECT
LONG HandleCount;
} CONSOLE_IO_OBJECT, *PCONSOLE_IO_OBJECT;
/******************************************************************************\
|* *|
|* Abstract "class" for screen-buffers, be they text-mode or graphics *|
|* *|
\******************************************************************************/
/*
* See conoutput.c for the implementation
*/
typedef struct _CONSOLE_SCREEN_BUFFER CONSOLE_SCREEN_BUFFER,
*PCONSOLE_SCREEN_BUFFER;
typedef struct _CONSOLE_SCREEN_BUFFER_VTBL
{
CONSOLE_IO_OBJECT_TYPE (*GetType)(PCONSOLE_SCREEN_BUFFER This);
} CONSOLE_SCREEN_BUFFER_VTBL, *PCONSOLE_SCREEN_BUFFER_VTBL;
#define GetType(This) (This)->Vtbl->GetType(This)
struct _CONSOLE_SCREEN_BUFFER
{
CONSOLE_IO_OBJECT Header; /* Object header - MUST BE IN FIRST PLACE */
PCONSOLE_SCREEN_BUFFER_VTBL Vtbl; /* Virtual table */
LIST_ENTRY ListEntry; /* Entry in console's list of buffers */
COORD ScreenBufferSize; /* Size of this screen buffer. (Rows, Columns) for text-mode and (Width, Height) for graphics */
COORD ViewSize; /* Associated "view" (i.e. console) size */
COORD OldScreenBufferSize; /* Old size of this screen buffer */
COORD OldViewSize; /* Old associated view size */
COORD ViewOrigin; /* Beginning offset for the actual display area */
/***** Put that VV in TEXTMODE_SCREEN_BUFFER ?? *****/
USHORT VirtualY; /* Top row of buffer being displayed, reported to callers */
COORD CursorPosition; /* Current cursor position */
BOOLEAN CursorBlinkOn;
BOOLEAN ForceCursorOff;
// ULONG CursorSize;
CONSOLE_CURSOR_INFO CursorInfo; // FIXME: Keep this member or not ??
/*********************************************/
// WORD ScreenDefaultAttrib; /* Default screen char attribute */
// WORD PopupDefaultAttrib; /* Default popup char attribute */
USHORT Mode; /* Output buffer modes */
};
/******************************************************************************\
|* *|
|* Text-mode and graphics-mode screen-buffer "classes" *|
|* *|
\******************************************************************************/
/*
* See text.c for the implementation
*/
/************************************************************************
* Screen buffer structure represents the win32 screen buffer object. *
* Internally, the portion of the buffer being shown CAN loop past the *
@@ -49,40 +115,62 @@ typedef struct _CONSOLE_IO_OBJECT
* internally, I just wrap back to the top of the buffer. *
************************************************************************/
typedef struct _CONSOLE_SCREEN_BUFFER
typedef struct _TEXTMODE_BUFFER_INFO
{
CONSOLE_IO_OBJECT Header; /* Object header */
LIST_ENTRY ListEntry; /* Entry in console's list of buffers */
COORD ScreenBufferSize;
USHORT ScreenAttrib;
USHORT PopupAttrib;
BOOLEAN IsCursorVisible;
ULONG CursorSize;
} TEXTMODE_BUFFER_INFO, *PTEXTMODE_BUFFER_INFO;
typedef struct _TEXTMODE_SCREEN_BUFFER
{
CONSOLE_SCREEN_BUFFER; /* Screen buffer base class - MUST BE IN FIRST PLACE */
BYTE *Buffer; /* CHAR_INFO */ /* Pointer to screen buffer */
COORD ScreenBufferSize; /* Size of this screen buffer */
COORD CursorPosition; /* Current cursor position */
USHORT ShowX, ShowY; /* Beginning offset for the actual display area */
USHORT VirtualY; /* Top row of buffer being displayed, reported to callers */
BOOLEAN CursorBlinkOn;
BOOLEAN ForceCursorOff;
// ULONG CursorSize;
CONSOLE_CURSOR_INFO CursorInfo; // FIXME: Keep this member or not ??
WORD ScreenDefaultAttrib; /* Default screen char attribute */
WORD PopupDefaultAttrib; /* Default popup char attribute */
USHORT Mode;
ULONG DisplayMode;
} CONSOLE_SCREEN_BUFFER, *PCONSOLE_SCREEN_BUFFER;
} TEXTMODE_SCREEN_BUFFER, *PTEXTMODE_SCREEN_BUFFER;
/*
* See graphics.c for the implementation
*/
typedef struct _GRAPHICS_BUFFER_INFO
{
CONSOLE_GRAPHICS_BUFFER_INFO Info;
} GRAPHICS_BUFFER_INFO, *PGRAPHICS_BUFFER_INFO;
typedef struct _GRAPHICS_SCREEN_BUFFER
{
CONSOLE_SCREEN_BUFFER; /* Screen buffer base class - MUST BE IN FIRST PLACE */
ULONG BitMapInfoLength; /* Real size of the structure pointed by BitMapInfo */
LPBITMAPINFO BitMapInfo; /* Information on the bitmap buffer */
ULONG BitMapUsage; /* See the uUsage parameter of GetDIBits */
HANDLE hSection; /* Handle to the memory shared section for the bitmap buffer */
PVOID BitMap; /* Our bitmap buffer */
PVOID ClientBitMap; /* A copy of the client view of our bitmap buffer */
HANDLE Mutex; /* Our mutex, used to synchronize read / writes to the bitmap buffer */
HANDLE ClientMutex; /* A copy of the client handle to our mutex */
HANDLE ClientProcess; /* Handle to the client process who opened the buffer, to unmap the view */
} GRAPHICS_SCREEN_BUFFER, *PGRAPHICS_SCREEN_BUFFER;
typedef struct _CONSOLE_INPUT_BUFFER
{
CONSOLE_IO_OBJECT Header; /* Object header */
CONSOLE_IO_OBJECT Header; /* Object header - MUST BE IN FIRST PLACE */
ULONG InputBufferSize; /* Size of this input buffer */
LIST_ENTRY InputEvents; /* List head for input event queue */
HANDLE ActiveEvent; /* Event set when an input event is added in its queue */
LIST_ENTRY ReadWaitQueue; /* List head for the queue of read wait blocks */
ULONG InputBufferSize; /* Size of this input buffer */
LIST_ENTRY InputEvents; /* List head for input event queue */
HANDLE ActiveEvent; /* Event set when an input event is added in its queue */
LIST_ENTRY ReadWaitQueue; /* List head for the queue of read wait blocks */
USHORT Mode; /* Console Input Buffer mode flags */
USHORT Mode; /* Input buffer modes */
} CONSOLE_INPUT_BUFFER, *PCONSOLE_INPUT_BUFFER;
typedef struct _FRONTEND_VTBL
@@ -90,7 +178,12 @@ typedef struct _FRONTEND_VTBL
/*
* Internal interface (functions called by the console server only)
*/
// BOOL (WINAPI *Init)();
VOID (WINAPI *CleanupConsole)(struct _CONSOLE* Console);
/* Interface used for both text-mode and graphics screen buffers */
VOID (WINAPI *DrawRegion)(struct _CONSOLE* Console,
SMALL_RECT* Region);
/* Interface used only for text-mode screen buffers */
VOID (WINAPI *WriteStream)(struct _CONSOLE* Console,
SMALL_RECT* Block,
SHORT CursorStartX,
@@ -98,17 +191,12 @@ typedef struct _FRONTEND_VTBL
UINT ScrolledLines,
CHAR *Buffer,
UINT Length);
VOID (WINAPI *DrawRegion)(struct _CONSOLE* Console,
SMALL_RECT* Region);
BOOL (WINAPI *SetCursorInfo)(struct _CONSOLE* Console,
PCONSOLE_SCREEN_BUFFER ScreenBuffer);
BOOL (WINAPI *SetScreenInfo)(struct _CONSOLE* Console,
PCONSOLE_SCREEN_BUFFER ScreenBuffer,
SHORT OldCursorX,
SHORT OldCursorY);
BOOL (WINAPI *UpdateScreenInfo)(struct _CONSOLE* Console,
PCONSOLE_SCREEN_BUFFER ScreenBuffer);
BOOL (WINAPI *IsBufferResizeSupported)(struct _CONSOLE* Console);
VOID (WINAPI *ResizeTerminal)(struct _CONSOLE* Console);
BOOL (WINAPI *ProcessKeyCallback)(struct _CONSOLE* Console,
MSG* msg,
@@ -127,7 +215,20 @@ typedef struct _FRONTEND_VTBL
HWND (WINAPI *GetConsoleWindowHandle)(struct _CONSOLE* Console);
VOID (WINAPI *GetLargestConsoleWindowSize)(struct _CONSOLE* Console,
PCOORD pSize);
ULONG (WINAPI *GetDisplayMode)(struct _CONSOLE* Console);
BOOL (WINAPI *SetDisplayMode)(struct _CONSOLE* Console,
ULONG NewMode);
#if 0 // Possible future front-end interface
BOOL (WINAPI *GetFrontEndProperty)(struct _CONSOLE* Console,
ULONG Flag,
PVOID Info,
ULONG Size);
BOOL (WINAPI *SetFrontEndProperty)(struct _CONSOLE* Console,
ULONG Flag,
PVOID Info /*,
ULONG Size */);
#endif
} FRONTEND_VTBL, *PFRONTEND_VTBL;
typedef struct _FRONTEND_IFACE
@@ -160,8 +261,9 @@ typedef struct _CONSOLE
FRONTEND_IFACE TermIFace; /* Frontend-specific interface */
/**************************** Input buffer and data ***************************/
CONSOLE_INPUT_BUFFER InputBuffer; /* Input buffer of the console */
CONSOLE_INPUT_BUFFER InputBuffer; /* Input buffer of the console */
/** Put those things in TEXTMODE_SCREEN_BUFFER ?? **/
PWCHAR LineBuffer; /* Current line being input, in line buffered mode */
WORD LineMaxSize; /* Maximum size of line in characters (including CR+LF) */
WORD LineSize; /* Current size of line */
@@ -170,6 +272,7 @@ typedef struct _CONSOLE
BOOLEAN LineUpPressed;
BOOLEAN LineInsertToggle; /* Replace character over cursor instead of inserting */
ULONG LineWakeupMask; /* Bitmap of which control characters will end line input */
/***************************************************/
BOOLEAN QuickEdit;
BOOLEAN InsertMode;
@@ -186,8 +289,6 @@ typedef struct _CONSOLE
HANDLE UnpauseEvent;
LIST_ENTRY WriteWaitQueue; /* List head for the queue of write wait blocks */
ULONG HardwareState; /* _GDI_MANAGED, _DIRECT */
/**************************** Aliases and Histories ***************************/
struct _ALIAS_HEADER *Aliases;
LIST_ENTRY HistoryBuffers;
@@ -196,10 +297,12 @@ typedef struct _CONSOLE
BOOLEAN HistoryNoDup; /* Remove old duplicate history entries */
/****************************** Other properties ******************************/
UNICODE_STRING OriginalTitle; /* Original title of console, the one when the console leader is launched. Always NULL-terminated */
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 */
/* SIZE */ COORD ConsoleSize; /* The size of the console */
COORD ConsoleSize; /* The current size of the console, for text-mode only */
BOOLEAN FixedSize; /* TRUE if the console is of fixed size */
COLORREF Colors[16]; /* Colour palette */
} CONSOLE, *PCONSOLE;
@@ -222,23 +325,30 @@ NTSTATUS FASTCALL ConioProcessInputEvent(PCONSOLE Console,
PINPUT_RECORD InputEvent);
/* conoutput.c */
#define ConioInitRect(Rect, top, left, bottom, right) \
do { \
((Rect)->Top) = top; \
((Rect)->Left) = left; \
((Rect)->Bottom) = bottom; \
((Rect)->Right) = right; \
} while (0)
#define ConioIsRectEmpty(Rect) \
(((Rect)->Left > (Rect)->Right) || ((Rect)->Top > (Rect)->Bottom))
#define ConioRectHeight(Rect) \
(((Rect)->Top) > ((Rect)->Bottom) ? 0 : ((Rect)->Bottom) - ((Rect)->Top) + 1)
#define ConioRectWidth(Rect) \
(((Rect)->Left) > ((Rect)->Right) ? 0 : ((Rect)->Right) - ((Rect)->Left) + 1)
PBYTE FASTCALL ConioCoordToPointer(PCONSOLE_SCREEN_BUFFER Buf,
ULONG X,
ULONG Y);
PBYTE ConioCoordToPointer(PTEXTMODE_SCREEN_BUFFER Buff, ULONG X, ULONG Y);
VOID FASTCALL ConioDrawConsole(PCONSOLE Console);
NTSTATUS FASTCALL ConioResizeBuffer(PCONSOLE Console,
PCONSOLE_SCREEN_BUFFER ScreenBuffer,
COORD Size);
NTSTATUS FASTCALL ConioWriteConsole(PCONSOLE Console,
PCONSOLE_SCREEN_BUFFER Buff,
CHAR *Buffer,
DWORD Length,
BOOL Attrib);
NTSTATUS ConioResizeBuffer(PCONSOLE Console,
PTEXTMODE_SCREEN_BUFFER ScreenBuffer,
COORD Size);
NTSTATUS ConioWriteConsole(PCONSOLE Console,
PTEXTMODE_SCREEN_BUFFER Buff,
CHAR *Buffer,
DWORD Length,
BOOL Attrib);
DWORD FASTCALL ConioEffectiveCursorSize(PCONSOLE Console,
DWORD Scale);
@@ -29,12 +29,11 @@ typedef struct _CONSOLE_INFO
ULONG NumberOfHistoryBuffers;
BOOLEAN HistoryNoDup;
/* BOOLEAN */ ULONG FullScreen; /* Give the type of console: GUI (windowed) or TUI (fullscreen) */
BOOLEAN QuickEdit;
BOOLEAN InsertMode;
ULONG InputBufferSize;
COORD ScreenBufferSize;
/* SIZE */ COORD ConsoleSize; /* The size of the console */
ULONG InputBufferSize;
COORD ScreenBufferSize;
COORD ConsoleSize; /* The size of the console */
BOOLEAN CursorBlinkOn;
BOOLEAN ForceCursorOff;
@@ -66,7 +65,7 @@ typedef struct _CONSOLE_PROPS
BOOLEAN AppliedConfig;
DWORD ActiveStaticControl;
CONSOLE_INFO ci; /* Console-specific informations */
CONSOLE_INFO ci; /* Console-specific informations */
TERMINAL_INFO TerminalInfo; /* Frontend-specific parameters */
} CONSOLE_PROPS, *PCONSOLE_PROPS;
+3 -3
View File
@@ -70,7 +70,7 @@ PCSR_API_ROUTINE ConsoleServerApiDispatchTable[ConsolepMaxApiNumber - CONSRV_FIR
SrvGetConsoleTitle,
SrvSetConsoleTitle,
SrvCreateConsoleScreenBuffer,
// SrvInvalidateBitMapRect,
SrvInvalidateBitMapRect,
// SrvVDMConsoleOperation,
// SrvSetConsoleCursor,
// SrvShowConsoleCursor,
@@ -161,7 +161,7 @@ BOOLEAN ConsoleServerApiServerValidTable[ConsolepMaxApiNumber - CONSRV_FIRST_API
FALSE, // SrvGetConsoleTitle,
FALSE, // SrvSetConsoleTitle,
FALSE, // SrvCreateConsoleScreenBuffer,
// FALSE, // SrvInvalidateBitMapRect,
FALSE, // SrvInvalidateBitMapRect,
// FALSE, // SrvVDMConsoleOperation,
// FALSE, // SrvSetConsoleCursor,
// FALSE, // SrvShowConsoleCursor,
@@ -252,7 +252,7 @@ PCHAR ConsoleServerApiNameTable[ConsolepMaxApiNumber - CONSRV_FIRST_API_NUMBER]
"GetConsoleTitle",
"SetConsoleTitle",
"CreateConsoleScreenBuffer",
// "InvalidateBitMapRect",
"InvalidateBitMapRect",
// "VDMConsoleOperation",
// "SetConsoleCursor",
// "ShowConsoleCursor",
+19 -6
View File
@@ -46,8 +46,7 @@ HistoryCurrentBuffer(PCONSOLE Console)
/* Couldn't find the buffer, create a new one */
Hist = ConsoleAllocHeap(0, sizeof(HISTORY_BUFFER) + ExeName.Length);
if (!Hist)
return NULL;
if (!Hist) return NULL;
Hist->MaxEntries = Console->HistoryBufferSize;
Hist->NumEntries = 0;
Hist->Entries = ConsoleAllocHeap(0, Hist->MaxEntries * sizeof(UNICODE_STRING));
@@ -194,10 +193,14 @@ LineInputSetPos(PCONSOLE Console, UINT Pos)
static VOID
LineInputEdit(PCONSOLE Console, UINT NumToDelete, UINT NumToInsert, WCHAR *Insertion)
{
PTEXTMODE_SCREEN_BUFFER ActiveBuffer;
UINT Pos = Console->LinePos;
UINT NewSize = Console->LineSize - NumToDelete + NumToInsert;
UINT i;
if (GetType(Console->ActiveBuffer) != TEXTMODE_BUFFER) return;
ActiveBuffer = (PTEXTMODE_SCREEN_BUFFER)Console->ActiveBuffer;
/* Make sure there's always enough room for ending \r\n */
if (NewSize + 2 > Console->LineMaxSize)
return;
@@ -215,11 +218,11 @@ LineInputEdit(PCONSOLE Console, UINT NumToDelete, UINT NumToInsert, WCHAR *Inser
WideCharToMultiByte(Console->OutputCodePage, 0,
&Console->LineBuffer[i], 1,
&AsciiChar, 1, NULL, NULL);
ConioWriteConsole(Console, Console->ActiveBuffer, &AsciiChar, 1, TRUE);
ConioWriteConsole(Console, ActiveBuffer, &AsciiChar, 1, TRUE);
}
for (; i < Console->LineSize; i++)
{
ConioWriteConsole(Console, Console->ActiveBuffer, " ", 1, TRUE);
ConioWriteConsole(Console, ActiveBuffer, " ", 1, TRUE);
}
Console->LinePos = i;
}
@@ -407,7 +410,12 @@ LineInputKeyDown(PCONSOLE Console, KEY_EVENT_RECORD *KeyEvent)
LineInputSetPos(Console, Console->LineSize);
Console->LineBuffer[Console->LineSize++] = L'\r';
if (Console->InputBuffer.Mode & ENABLE_ECHO_INPUT)
ConioWriteConsole(Console, Console->ActiveBuffer, "\r", 1, TRUE);
{
if (GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER)
{
ConioWriteConsole(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), "\r", 1, TRUE);
}
}
/* Add \n if processed input. There should usually be room for it,
* but an exception to the rule exists: the buffer could have been
@@ -417,7 +425,12 @@ LineInputKeyDown(PCONSOLE Console, KEY_EVENT_RECORD *KeyEvent)
{
Console->LineBuffer[Console->LineSize++] = L'\n';
if (Console->InputBuffer.Mode & ENABLE_ECHO_INPUT)
ConioWriteConsole(Console, Console->ActiveBuffer, "\n", 1, TRUE);
{
if (GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER)
{
ConioWriteConsole(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), "\n", 1, TRUE);
}
}
}
Console->LineComplete = TRUE;
Console->LinePos = 0;
+104 -37
View File
@@ -274,11 +274,6 @@ ConSrvReadUserSettings(IN OUT PCONSOLE_INFO ConsoleInfo,
ConsoleInfo->HistoryNoDup = (BOOLEAN)Value;
RetVal = TRUE;
}
else if (!wcscmp(szValueName, L"FullScreen"))
{
ConsoleInfo->FullScreen = Value;
RetVal = TRUE;
}
else if (!wcscmp(szValueName, L"QuickEdit"))
{
ConsoleInfo->QuickEdit = (BOOLEAN)Value;
@@ -370,9 +365,6 @@ do {
Storage = ConsoleInfo->HistoryNoDup;
SetConsoleSetting(L"HistoryNoDup", REG_DWORD, sizeof(DWORD), &Storage, FALSE);
Storage = ConsoleInfo->FullScreen;
SetConsoleSetting(L"FullScreen", REG_DWORD, sizeof(DWORD), &Storage, FALSE);
Storage = ConsoleInfo->QuickEdit;
SetConsoleSetting(L"QuickEdit", REG_DWORD, sizeof(DWORD), &Storage, FALSE);
@@ -414,10 +406,11 @@ ConSrvGetDefaultSettings(IN OUT PCONSOLE_INFO ConsoleInfo,
ConsoleInfo->NumberOfHistoryBuffers = 4;
ConsoleInfo->HistoryNoDup = FALSE;
ConsoleInfo->FullScreen = FALSE;
ConsoleInfo->QuickEdit = FALSE;
ConsoleInfo->InsertMode = TRUE;
// ConsoleInfo->InputBufferSize;
// Rule: ScreenBufferSize >= ConsoleSize
ConsoleInfo->ScreenBufferSize.X = 80;
ConsoleInfo->ScreenBufferSize.Y = 300;
ConsoleInfo->ConsoleSize.X = 80;
@@ -452,17 +445,6 @@ ConSrvApplyUserSettings(IN PCONSOLE Console,
IN PCONSOLE_INFO ConsoleInfo)
{
PCONSOLE_SCREEN_BUFFER ActiveBuffer = Console->ActiveBuffer;
COORD BufSize;
BOOL SizeChanged = FALSE;
/*
* Apply full-screen mode.
*/
if (ConsoleInfo->FullScreen)
Console->ActiveBuffer->DisplayMode |= CONSOLE_FULLSCREEN_MODE;
else
Console->ActiveBuffer->DisplayMode &= ~CONSOLE_FULLSCREEN_MODE;
// TODO: Apply it really
/*
* Apply terminal-edition settings:
@@ -476,9 +458,19 @@ ConSrvApplyUserSettings(IN PCONSOLE Console,
* Apply foreground and background colors for both screen and popup
* and copy the new palette.
*/
ActiveBuffer->ScreenDefaultAttrib = ConsoleInfo->ScreenAttrib;
ActiveBuffer->PopupDefaultAttrib = ConsoleInfo->PopupAttrib;
memcpy(Console->Colors, ConsoleInfo->Colors, sizeof(s_Colors)); // FIXME: Possible buffer overflow if s_colors is bigger than pConInfo->Colors.
if (GetType(ActiveBuffer) == TEXTMODE_BUFFER)
{
PTEXTMODE_SCREEN_BUFFER Buffer = (PTEXTMODE_SCREEN_BUFFER)ActiveBuffer;
Buffer->ScreenDefaultAttrib = ConsoleInfo->ScreenAttrib;
Buffer->PopupDefaultAttrib = ConsoleInfo->PopupAttrib;
}
else // if (Console->ActiveBuffer->Header.Type == GRAPHICS_BUFFER)
{
}
// FIXME: Possible buffer overflow if s_colors is bigger than pConInfo->Colors.
memcpy(Console->Colors, ConsoleInfo->Colors, sizeof(s_Colors));
// TODO: Really update the screen attributes as FillConsoleOutputAttribute does.
@@ -486,24 +478,99 @@ ConSrvApplyUserSettings(IN PCONSOLE Console,
ActiveBuffer->CursorInfo.bVisible = (ConsoleInfo->CursorSize != 0);
ActiveBuffer->CursorInfo.dwSize = min(max(ConsoleInfo->CursorSize, 0), 100);
/* Resize the console */
if (ConsoleInfo->ConsoleSize.X != Console->ConsoleSize.X ||
ConsoleInfo->ConsoleSize.Y != Console->ConsoleSize.Y)
if (GetType(ActiveBuffer) == TEXTMODE_BUFFER)
{
Console->ConsoleSize = ConsoleInfo->ConsoleSize;
SizeChanged = TRUE;
}
PTEXTMODE_SCREEN_BUFFER Buffer = (PTEXTMODE_SCREEN_BUFFER)ActiveBuffer;
COORD BufSize;
/* Resize its active screen-buffer */
BufSize = ConsoleInfo->ScreenBufferSize;
if (BufSize.X != ActiveBuffer->ScreenBufferSize.X ||
BufSize.Y != ActiveBuffer->ScreenBufferSize.Y)
/* Resize its active screen-buffer */
BufSize = ConsoleInfo->ScreenBufferSize;
if (Console->FixedSize)
{
/*
* The console is in fixed-size mode, so we cannot resize anything
* at the moment. However, keep those settings somewhere so that
* we can try to set them up when we will be allowed to do so.
*/
if (ConsoleInfo->ConsoleSize.X != Buffer->OldViewSize.X ||
ConsoleInfo->ConsoleSize.Y != Buffer->OldViewSize.Y)
{
Buffer->OldViewSize = ConsoleInfo->ConsoleSize;
}
/* Buffer size is not allowed to be smaller than the view size */
if (BufSize.X >= Buffer->OldViewSize.X && BufSize.Y >= Buffer->OldViewSize.Y)
{
if (BufSize.X != Buffer->OldScreenBufferSize.X ||
BufSize.Y != Buffer->OldScreenBufferSize.Y)
{
/*
* The console is in fixed-size mode, so we cannot resize anything
* at the moment. However, keep those settings somewhere so that
* we can try to set them up when we will be allowed to do so.
*/
Buffer->OldScreenBufferSize = BufSize;
}
}
}
else
{
BOOL SizeChanged = FALSE;
/* Resize the console */
if (ConsoleInfo->ConsoleSize.X != Buffer->ViewSize.X ||
ConsoleInfo->ConsoleSize.Y != Buffer->ViewSize.Y)
{
Buffer->ViewSize = ConsoleInfo->ConsoleSize;
SizeChanged = TRUE;
}
/* Resize the screen-buffer */
if (BufSize.X != Buffer->ScreenBufferSize.X ||
BufSize.Y != Buffer->ScreenBufferSize.Y)
{
if (NT_SUCCESS(ConioResizeBuffer(Console, Buffer, BufSize)))
SizeChanged = TRUE;
}
if (SizeChanged) ConioResizeTerminal(Console);
}
}
else // if (GetType(ActiveBuffer) == GRAPHICS_BUFFER)
{
if (NT_SUCCESS(ConioResizeBuffer(Console, ActiveBuffer, BufSize)))
SizeChanged = TRUE;
}
PGRAPHICS_SCREEN_BUFFER Buffer = (PGRAPHICS_SCREEN_BUFFER)ActiveBuffer;
if (SizeChanged) ConioResizeTerminal(Console);
/*
* In any case we do NOT modify the size of the graphics screen-buffer.
* We just allow resizing the view only if the new size is smaller
* than the older one.
*/
if (Console->FixedSize)
{
/*
* The console is in fixed-size mode, so we cannot resize anything
* at the moment. However, keep those settings somewhere so that
* we can try to set them up when we will be allowed to do so.
*/
if (ConsoleInfo->ConsoleSize.X <= Buffer->ViewSize.X ||
ConsoleInfo->ConsoleSize.Y <= Buffer->ViewSize.Y)
{
Buffer->OldViewSize = ConsoleInfo->ConsoleSize;
}
}
else
{
/* Resize the view if its size is bigger than the specified size */
if (ConsoleInfo->ConsoleSize.X <= Buffer->ViewSize.X ||
ConsoleInfo->ConsoleSize.Y <= Buffer->ViewSize.Y)
{
Buffer->ViewSize = ConsoleInfo->ConsoleSize;
// SizeChanged = TRUE;
}
}
}
}
/* EOF */
File diff suppressed because it is too large Load Diff