From 8a45602a5b8006e8d8ae8db8922cde9a42ba22a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Mon, 1 Apr 2013 00:23:34 +0000 Subject: [PATCH] [KERNEL32-CONSRV] Implement (Get/Set)ConsoleDisplayMode. [PSDK] Reorganize wincon.h a little bit and add few new flags from MSDN / Wine's wincon.h (which was up-to-date compared to ours) and from https://sites.google.com/site/marckupper/utilities/setconsolemode (the ENABLE_AUTO_POSITION flag which happens to be set by default for consoles on Windows Vista+). [CONSRV] - Fix the implementation of Srv(Get/Set)ConsoleMode. - Try to fix some mouse handling problems. - Add a TEMPORARY HACK!!!! to circumvent one of the many bugs we have in user32/win32k concerning handling right-mouse clicks on windows titlebars. The comment: /* * HACK: !! Because, when we deal with WM_RBUTTON* and we do not * call after that DefWindowProc, on ReactOS, right-clicks on the * (non-client) application title-bar does not display the system * menu and does not trigger a WM_NCRBUTTONUP message too. * See: http://git.reactos.org/?p=reactos.git;a=blob;f=reactos/win32ss/user/user32/windows/defwnd.c;hb=HEAD#l1103 * and line 1135 too. */ Tested with Far Manager 3 (TM) Happy Easter !! svn path=/branches/ros-csrss/; revision=58632 --- dll/win32/kernel32/client/console/console.c | 78 +++++--- include/psdk/wincon.h | 180 +++++++++++------- include/reactos/subsys/win/conmsg.h | 46 +++-- win32ss/user/consrv/conio.h | 15 +- win32ss/user/consrv/conoutput.c | 8 +- win32ss/user/consrv/console.c | 157 +++++++++++++-- win32ss/user/consrv/consrv.h | 2 + .../user/consrv/frontends/gui/guisettings.c | 2 +- win32ss/user/consrv/frontends/gui/guiterm.c | 95 +++++++-- win32ss/user/consrv/init.c | 12 +- 10 files changed, 431 insertions(+), 164 deletions(-) diff --git a/dll/win32/kernel32/client/console/console.c b/dll/win32/kernel32/client/console/console.c index 54e6e8102d2..bceab26c32c 100644 --- a/dll/win32/kernel32/client/console/console.c +++ b/dll/win32/kernel32/client/console/console.c @@ -296,22 +296,30 @@ DuplicateConsoleHandle(HANDLE hConsole, /* - * @unimplemented + * @implemented */ -INT +BOOL WINAPI -GetConsoleDisplayMode(LPDWORD lpdwMode) - /* - * FUNCTION: Get the console display mode - * ARGUMENTS: - * lpdwMode - Address of variable that receives the current value - * of display mode - * STATUS: Undocumented - */ +GetConsoleDisplayMode(LPDWORD lpModeFlags) { - DPRINT1("GetConsoleDisplayMode(0x%x) UNIMPLEMENTED!\n", lpdwMode); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + NTSTATUS Status; + CONSOLE_API_MESSAGE ApiMessage; + PCONSOLE_GETDISPLAYMODE GetDisplayModeRequest = &ApiMessage.Data.GetDisplayModeRequest; + + // GetDisplayModeRequest->OutputHandle = hConsoleOutput; + + Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, + NULL, + CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetDisplayMode), + sizeof(CONSOLE_GETDISPLAYMODE)); + if (!NT_SUCCESS(Status)) + { + BaseSetLastNTError(Status); + return FALSE; + } + + *lpModeFlags = GetDisplayModeRequest->DisplayMode; + return TRUE; } @@ -359,6 +367,8 @@ GetConsoleHardwareState(HANDLE hConsoleOutput, CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETSETHWSTATE HardwareStateRequest = &ApiMessage.Data.HardwareStateRequest; + DPRINT1("GetConsoleHardwareState(%d, 0x%p) UNIMPLEMENTED!\n", Flags, State); + HardwareStateRequest->OutputHandle = hConsoleOutput; Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, @@ -499,24 +509,34 @@ SetConsoleCursor(DWORD Unknown0, /* - * @unimplemented + * @implemented */ BOOL WINAPI -SetConsoleDisplayMode(HANDLE hOut, - DWORD dwNewMode, - PCOORD lpdwOldMode) - /* - * FUNCTION: Set the console display mode. - * ARGUMENTS: - * hOut - Standard output handle. - * dwNewMode - New mode. - * lpdwOldMode - Address of a variable that receives the old mode. - */ +SetConsoleDisplayMode(HANDLE hConsoleOutput, + DWORD dwFlags, + PCOORD lpNewScreenBufferDimensions) { - DPRINT1("SetConsoleDisplayMode(0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n", hOut, dwNewMode, lpdwOldMode); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + NTSTATUS Status; + CONSOLE_API_MESSAGE ApiMessage; + PCONSOLE_SETDISPLAYMODE SetDisplayModeRequest = &ApiMessage.Data.SetDisplayModeRequest; + + SetDisplayModeRequest->OutputHandle = hConsoleOutput; + SetDisplayModeRequest->DisplayMode = dwFlags; + SetDisplayModeRequest->NewSBDim = (COORD){0,0}; + + Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, + NULL, + CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetDisplayMode), + sizeof(CONSOLE_SETDISPLAYMODE)); + if (!NT_SUCCESS(Status)) + { + BaseSetLastNTError(Status); + return FALSE; + } + + *lpNewScreenBufferDimensions = SetDisplayModeRequest->NewSBDim; + return TRUE; } @@ -547,6 +567,8 @@ SetConsoleHardwareState(HANDLE hConsoleOutput, CONSOLE_API_MESSAGE ApiMessage; PCONSOLE_GETSETHWSTATE HardwareStateRequest = &ApiMessage.Data.HardwareStateRequest; + DPRINT1("SetConsoleHardwareState(%d, %d) UNIMPLEMENTED!\n", Flags, State); + HardwareStateRequest->OutputHandle = hConsoleOutput; HardwareStateRequest->State = State; @@ -1144,7 +1166,7 @@ SetConsoleMode(HANDLE hConsoleHandle, PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &ApiMessage.Data.ConsoleModeRequest; ConsoleModeRequest->ConsoleHandle = hConsoleHandle; - ConsoleModeRequest->ConsoleMode = dwMode; + ConsoleModeRequest->ConsoleMode = dwMode; Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, diff --git a/include/psdk/wincon.h b/include/psdk/wincon.h index cf723b84e77..bbc1bfe6920 100644 --- a/include/psdk/wincon.h +++ b/include/psdk/wincon.h @@ -14,17 +14,44 @@ extern "C" { #pragma warning(disable:4820) #endif +/* + * Special PID for parent process for AttachConsole API + */ +#if (_WIN32_WINNT >= 0x0501) +#define ATTACH_PARENT_PROCESS ((DWORD)-1) +#endif + +/* + * Console display modes + */ +#define CONSOLE_FULLSCREEN 1 +#define CONSOLE_FULLSCREEN_HARDWARE 2 +#if (_WIN32_WINNT >= 0x0600) +#define CONSOLE_OVERSTRIKE 1 +#endif + +#define CONSOLE_FULLSCREEN_MODE 1 +#define CONSOLE_WINDOWED_MODE 2 + /* * Color attributes for text and screen background */ -#define FOREGROUND_BLUE 0x0001 -#define FOREGROUND_GREEN 0x0002 -#define FOREGROUND_RED 0x0004 -#define FOREGROUND_INTENSITY 0x0008 -#define BACKGROUND_BLUE 0x0010 -#define BACKGROUND_GREEN 0x0020 -#define BACKGROUND_RED 0x0040 -#define BACKGROUND_INTENSITY 0x0080 +#define FOREGROUND_BLUE 0x0001 +#define FOREGROUND_GREEN 0x0002 +#define FOREGROUND_RED 0x0004 +#define FOREGROUND_INTENSITY 0x0008 +#define BACKGROUND_BLUE 0x0010 +#define BACKGROUND_GREEN 0x0020 +#define BACKGROUND_RED 0x0040 +#define BACKGROUND_INTENSITY 0x0080 + +#define COMMON_LVB_LEADING_BYTE 0x0100 +#define COMMON_LVB_TRAILING_BYTE 0x0200 +#define COMMON_LVB_GRID_HORIZONTAL 0x0400 +#define COMMON_LVB_GRID_LVERTICAL 0x0800 +#define COMMON_LVB_GRID_RVERTICAL 0x1000 +#define COMMON_LVB_REVERSE_VIDEO 0x4000 +#define COMMON_LVB_UNDERSCORE 0x8000 /* * Control handler codes @@ -38,20 +65,39 @@ extern "C" { /* * Input mode flags */ -#define ENABLE_PROCESSED_INPUT 0x0001 -#define ENABLE_LINE_INPUT 0x0002 -#define ENABLE_ECHO_INPUT 0x0004 -#define ENABLE_WINDOW_INPUT 0x0008 -#define ENABLE_MOUSE_INPUT 0x0010 -#define ENABLE_INSERT_MODE 0x0020 -#define ENABLE_QUICK_EDIT_MODE 0x0040 -#define ENABLE_EXTENDED_FLAGS 0x0080 +#define ENABLE_PROCESSED_INPUT 0x0001 +#define ENABLE_LINE_INPUT 0x0002 +#define ENABLE_ECHO_INPUT 0x0004 +#define ENABLE_WINDOW_INPUT 0x0008 +#define ENABLE_MOUSE_INPUT 0x0010 +#define ENABLE_INSERT_MODE 0x0020 +#define ENABLE_QUICK_EDIT_MODE 0x0040 +#define ENABLE_EXTENDED_FLAGS 0x0080 +#if (_WIN32_WINNT >= 0x0600) +#define ENABLE_AUTO_POSITION 0x0100 +#endif /* * Output mode flags */ -#define ENABLE_PROCESSED_OUTPUT 0x0001 -#define ENABLE_WRAP_AT_EOL_OUTPUT 0x0002 +#define ENABLE_PROCESSED_OUTPUT 0x0001 +#define ENABLE_WRAP_AT_EOL_OUTPUT 0x0002 + +/* + * Console selection flags + */ +#define CONSOLE_NO_SELECTION 0x0000 +#define CONSOLE_SELECTION_IN_PROGRESS 0x0001 +#define CONSOLE_SELECTION_NOT_EMPTY 0x0002 +#define CONSOLE_MOUSE_SELECTION 0x0004 +#define CONSOLE_MOUSE_DOWN 0x0008 + +/* + * History duplicate flags + */ +#if (_WIN32_WINNT >= 0x0600) +#define HISTORY_NO_DUP_FLAG 0x0001 +#endif /* * Event types @@ -102,53 +148,53 @@ typedef struct _CONSOLE_READCONSOLE_CONTROL { } CONSOLE_READCONSOLE_CONTROL, *PCONSOLE_READCONSOLE_CONTROL; typedef struct _CHAR_INFO { - union { - WCHAR UnicodeChar; - CHAR AsciiChar; - } Char; - WORD Attributes; + union { + WCHAR UnicodeChar; + CHAR AsciiChar; + } Char; + WORD Attributes; } CHAR_INFO,*PCHAR_INFO; typedef struct _SMALL_RECT { - SHORT Left; - SHORT Top; - SHORT Right; - SHORT Bottom; + SHORT Left; + SHORT Top; + SHORT Right; + SHORT Bottom; } SMALL_RECT,*PSMALL_RECT; typedef struct _CONSOLE_CURSOR_INFO { - DWORD dwSize; - BOOL bVisible; + DWORD dwSize; + BOOL bVisible; } CONSOLE_CURSOR_INFO,*PCONSOLE_CURSOR_INFO; typedef struct _COORD { - SHORT X; - SHORT Y; + SHORT X; + SHORT Y; } COORD, *PCOORD; typedef struct _CONSOLE_SELECTION_INFO { - DWORD dwFlags; - COORD dwSelectionAnchor; - SMALL_RECT srSelection; + DWORD dwFlags; + COORD dwSelectionAnchor; + SMALL_RECT srSelection; } CONSOLE_SELECTION_INFO, *PCONSOLE_SELECTION_INFO; typedef struct _CONSOLE_FONT_INFO { - DWORD nFont; - COORD dwFontSize; + DWORD nFont; + COORD dwFontSize; } CONSOLE_FONT_INFO, *PCONSOLE_FONT_INFO; typedef struct _CONSOLE_SCREEN_BUFFER_INFO { - COORD dwSize; - COORD dwCursorPosition; - WORD wAttributes; - SMALL_RECT srWindow; - COORD dwMaximumWindowSize; + COORD dwSize; + COORD dwCursorPosition; + WORD wAttributes; + SMALL_RECT srWindow; + COORD dwMaximumWindowSize; } CONSOLE_SCREEN_BUFFER_INFO,*PCONSOLE_SCREEN_BUFFER_INFO; typedef BOOL(CALLBACK *PHANDLER_ROUTINE)(_In_ DWORD); typedef struct _KEY_EVENT_RECORD { - BOOL bKeyDown; - WORD wRepeatCount; - WORD wVirtualKeyCode; - WORD wVirtualScanCode; - union { - WCHAR UnicodeChar; - CHAR AsciiChar; - } uChar; - DWORD dwControlKeyState; + BOOL bKeyDown; + WORD wRepeatCount; + WORD wVirtualKeyCode; + WORD wVirtualScanCode; + union { + WCHAR UnicodeChar; + CHAR AsciiChar; + } uChar; + DWORD dwControlKeyState; } #ifdef __GNUC__ /* gcc's alignment is not what win32 expects */ @@ -156,29 +202,26 @@ typedef struct _KEY_EVENT_RECORD { #endif KEY_EVENT_RECORD; typedef struct _MOUSE_EVENT_RECORD { - COORD dwMousePosition; - DWORD dwButtonState; - DWORD dwControlKeyState; - DWORD dwEventFlags; + 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 _FOCUS_EVENT_RECORD { BOOL bSetFocus; } FOCUS_EVENT_RECORD; typedef struct _INPUT_RECORD { - WORD EventType; - union { - KEY_EVENT_RECORD KeyEvent; - MOUSE_EVENT_RECORD MouseEvent; - WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent; - MENU_EVENT_RECORD MenuEvent; - FOCUS_EVENT_RECORD FocusEvent; - } Event; + WORD EventType; + union { + KEY_EVENT_RECORD KeyEvent; + MOUSE_EVENT_RECORD MouseEvent; + WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent; + MENU_EVENT_RECORD MenuEvent; + FOCUS_EVENT_RECORD FocusEvent; + } Event; } INPUT_RECORD,*PINPUT_RECORD; #if (_WIN32_WINNT >= 0x0600) -#define HISTORY_NO_DUP_FLAG 0x1 -#define CONSOLE_OVERSTRIKE 0x1 - typedef struct _CONSOLE_HISTORY_INFO { UINT cbSize; UINT HistoryBufferSize; @@ -212,7 +255,6 @@ typedef struct _CONSOLE_FONT_INFOEX { BOOL WINAPI AllocConsole(VOID); #if (_WIN32_WINNT >= 0x0501) -#define ATTACH_PARENT_PROCESS (DWORD)-1 BOOL WINAPI AttachConsole(_In_ DWORD); BOOL WINAPI AddConsoleAliasA(_In_ LPCSTR, _In_ LPCSTR, _In_ LPCSTR); @@ -294,7 +336,7 @@ GetConsoleTitleW( #if (_WIN32_WINNT >= 0x0500) HWND WINAPI GetConsoleWindow(VOID); -WINBASEAPI BOOL APIENTRY GetConsoleDisplayMode(_Out_ LPDWORD lpModeFlags); +BOOL APIENTRY GetConsoleDisplayMode(_Out_ LPDWORD lpModeFlags); BOOL APIENTRY SetConsoleDisplayMode(_In_ HANDLE hConsoleOutput, _In_ DWORD dwFlags, _Out_opt_ PCOORD lpNewScreenBufferDimensions); #endif COORD WINAPI GetLargestConsoleWindowSize(_In_ HANDLE); @@ -438,10 +480,6 @@ WriteConsoleOutputCharacterW( _In_ COORD dwWriteCoord, _Out_ LPDWORD lpNumberOfCharsWritten); -#define CONSOLE_FULLSCREEN 1 -#define CONSOLE_FULLSCREEN_HARDWARE 2 -#define CONSOLE_FULLSCREEN_MODE 1 -#define CONSOLE_WINDOWED_MODE 2 #ifdef UNICODE #define AddConsoleAlias AddConsoleAliasW diff --git a/include/reactos/subsys/win/conmsg.h b/include/reactos/subsys/win/conmsg.h index 61a874de3da..4a0ed014ce6 100644 --- a/include/reactos/subsys/win/conmsg.h +++ b/include/reactos/subsys/win/conmsg.h @@ -66,11 +66,11 @@ typedef enum _CONSRV_API_NUMBER // ConsolepShowCursor, // ConsolepMenuControl, // ConsolepSetPalette, - // ConsolepSetDisplayMode, + ConsolepSetDisplayMode, // ConsolepRegisterVDM, ConsolepGetHardwareState, ConsolepSetHardwareState, - // ConsolepGetDisplayMode, + ConsolepGetDisplayMode, ConsolepAddAlias, ConsolepGetAlias, ConsolepGetAliasesLength, @@ -236,6 +236,34 @@ typedef struct DWORD ConsoleMode; } CONSOLE_GETSETCONSOLEMODE, *PCONSOLE_GETSETCONSOLEMODE; + +#define CONSOLE_WINDOWED 0 /* Internal console hardware state */ +typedef struct +{ + // HANDLE OutputHandle; + DWORD DisplayMode; +} CONSOLE_GETDISPLAYMODE, *PCONSOLE_GETDISPLAYMODE; + +typedef struct +{ + HANDLE OutputHandle; + DWORD DisplayMode; + COORD NewSBDim; +} CONSOLE_SETDISPLAYMODE, *PCONSOLE_SETDISPLAYMODE; + +/* + * Console hardware states. + */ +#define CONSOLE_HARDWARE_STATE_GDI_MANAGED 0 +#define CONSOLE_HARDWARE_STATE_DIRECT 1 + +typedef struct +{ + HANDLE OutputHandle; + DWORD State; +} CONSOLE_GETSETHWSTATE, *PCONSOLE_GETSETHWSTATE; + + typedef struct { HANDLE OutputHandle; /* Handle to newly created screen buffer */ @@ -425,18 +453,6 @@ typedef struct } CONSOLE_OPENCONSOLE, *PCONSOLE_OPENCONSOLE; -/* - * Console hardware states. - */ -#define CONSOLE_HARDWARE_STATE_GDI_MANAGED 0 -#define CONSOLE_HARDWARE_STATE_DIRECT 1 - -typedef struct -{ - HANDLE OutputHandle; - DWORD State; -} CONSOLE_GETSETHWSTATE, *PCONSOLE_GETSETHWSTATE; - typedef struct { HWND WindowHandle; @@ -585,6 +601,8 @@ typedef struct _CONSOLE_API_MESSAGE /* Console mode */ CONSOLE_GETSETCONSOLEMODE ConsoleModeRequest; + CONSOLE_GETDISPLAYMODE GetDisplayModeRequest; + CONSOLE_SETDISPLAYMODE SetDisplayModeRequest; CONSOLE_GETSETHWSTATE HardwareStateRequest; /* Console window */ diff --git a/win32ss/user/consrv/conio.h b/win32ss/user/consrv/conio.h index b2789d128fe..a488e13b72f 100644 --- a/win32ss/user/consrv/conio.h +++ b/win32ss/user/consrv/conio.h @@ -54,6 +54,7 @@ typedef struct _CONSOLE_SCREEN_BUFFER WORD ScreenDefaultAttrib; /* Default screen char attribute */ WORD PopupDefaultAttrib; /* Default popup char attribute */ USHORT Mode; + ULONG DisplayMode; } CONSOLE_SCREEN_BUFFER, *PCONSOLE_SCREEN_BUFFER; typedef struct _CONSOLE_INPUT_BUFFER @@ -198,8 +199,7 @@ typedef struct _CONSOLE HANDLE UnpauseEvent; LIST_ENTRY WriteWaitQueue; /* List head for the queue of write wait blocks */ - DWORD HardwareState; /* _GDI_MANAGED, _DIRECT */ -/* BOOLEAN */ ULONG FullScreen; // Give the type of console: GUI (windowed) or TUI (fullscreen) + ULONG HardwareState; /* _GDI_MANAGED, _DIRECT */ /**************************** Aliases and Histories ***************************/ struct _ALIAS_HEADER *Aliases; @@ -217,16 +217,6 @@ typedef struct _CONSOLE } CONSOLE, *PCONSOLE; -/* CONSOLE_SELECTION_INFO dwFlags values */ -#define CONSOLE_NO_SELECTION 0x0 -#define CONSOLE_SELECTION_IN_PROGRESS 0x1 -#define CONSOLE_SELECTION_NOT_EMPTY 0x2 -#define CONSOLE_MOUSE_SELECTION 0x4 -#define CONSOLE_MOUSE_DOWN 0x8 - -/* HistoryFlags values */ -#define HISTORY_NO_DUP_FLAG 0x1 - /* PauseFlags values (internal only) */ #define PAUSED_FROM_KEYBOARD 0x1 #define PAUSED_FROM_SCROLLBAR 0x2 @@ -274,6 +264,7 @@ NTSTATUS FASTCALL ConSrvCreateScreenBuffer(IN OUT PCONSOLE Console, IN COORD ScreenBufferSize, IN USHORT ScreenAttrib, IN USHORT PopupAttrib, + IN ULONG DisplayMode, IN BOOLEAN IsCursorVisible, IN ULONG CursorSize); VOID WINAPI ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer); diff --git a/win32ss/user/consrv/conoutput.c b/win32ss/user/consrv/conoutput.c index 679552bfd77..9fbf203c71f 100644 --- a/win32ss/user/consrv/conoutput.c +++ b/win32ss/user/consrv/conoutput.c @@ -65,6 +65,7 @@ ConSrvCreateScreenBuffer(IN OUT PCONSOLE Console, IN COORD ScreenBufferSize, IN USHORT ScreenAttrib, IN USHORT PopupAttrib, + IN ULONG DisplayMode, IN BOOLEAN IsCursorVisible, IN ULONG CursorSize) { @@ -103,9 +104,11 @@ ConSrvCreateScreenBuffer(IN OUT PCONSOLE Console, { ClearLineBuffer(*Buffer); } - (*Buffer)->Mode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT; (*Buffer)->CursorPosition = (COORD){0, 0}; + (*Buffer)->Mode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT; + (*Buffer)->DisplayMode = DisplayMode; + InsertHeadList(&Console->BufferList, &(*Buffer)->ListEntry); return STATUS_SUCCESS; } @@ -1273,6 +1276,7 @@ CSR_API(SrvCreateConsoleScreenBuffer) COORD ScreenBufferSize = (COORD){80, 25}; USHORT ScreenAttrib = DEFAULT_SCREEN_ATTRIB; USHORT PopupAttrib = DEFAULT_POPUP_ATTRIB; + ULONG DisplayMode = CONSOLE_WINDOWED_MODE; BOOLEAN IsCursorVisible = TRUE; ULONG CursorSize = CSR_DEFAULT_CURSOR_SIZE; @@ -1314,6 +1318,7 @@ CSR_API(SrvCreateConsoleScreenBuffer) { ScreenAttrib = Console->ActiveBuffer->ScreenDefaultAttrib; PopupAttrib = Console->ActiveBuffer->PopupDefaultAttrib; + DisplayMode = Console->ActiveBuffer->DisplayMode; IsCursorVisible = Console->ActiveBuffer->CursorInfo.bVisible; CursorSize = Console->ActiveBuffer->CursorInfo.dwSize; @@ -1325,6 +1330,7 @@ CSR_API(SrvCreateConsoleScreenBuffer) ScreenBufferSize, ScreenAttrib, PopupAttrib, + DisplayMode, IsCursorVisible, CursorSize); if (NT_SUCCESS(Status)) diff --git a/win32ss/user/consrv/console.c b/win32ss/user/consrv/console.c index ebeb7cbebb7..a536854853c 100644 --- a/win32ss/user/consrv/console.c +++ b/win32ss/user/consrv/console.c @@ -391,6 +391,7 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole, /* if (ConsoleStartInfo->dwStartupFlags & STARTF_RUNFULLSCREEN) { + ConsoleInfo.FullScreen = TRUE; } */ } @@ -422,9 +423,8 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole, return STATUS_UNSUCCESSFUL; } - // TODO: Use the values from ConsoleInfo. - Console->InputBuffer.Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | - ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT; + Console->InputBuffer.Mode = ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | + ENABLE_ECHO_INPUT | ENABLE_MOUSE_INPUT; Console->QuickEdit = ConsoleInfo.QuickEdit; Console->InsertMode = ConsoleInfo.InsertMode; InitializeListHead(&Console->InputBuffer.ReadWaitQueue); @@ -440,6 +440,8 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole, ConsoleInfo.ScreenBufferSize, ConsoleInfo.ScreenAttrib, ConsoleInfo.PopupAttrib, + (ConsoleInfo.FullScreen ? CONSOLE_FULLSCREEN_MODE + : CONSOLE_WINDOWED_MODE), TRUE, ConsoleInfo.CursorSize); if (!NT_SUCCESS(Status)) @@ -452,7 +454,6 @@ ConSrvInitConsole(OUT PCONSOLE* NewConsole, } /* Make the new screen buffer active */ Console->ActiveBuffer = NewBuffer; - Console->FullScreen = ConsoleInfo.FullScreen; InitializeListHead(&Console->WriteWaitQueue); /* @@ -1010,19 +1011,20 @@ CSR_API(SrvFreeConsole) CSR_API(SrvSetConsoleMode) { -#define CONSOLE_INPUT_MODE_VALID ( ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | \ - ENABLE_ECHO_INPUT | ENABLE_WINDOW_INPUT | \ - ENABLE_MOUSE_INPUT | \ - ENABLE_INSERT_MODE | ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS ) -#define CONSOLE_OUTPUT_MODE_VALID ( ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT ) +#define CONSOLE_VALID_CONTROL_MODES ( ENABLE_EXTENDED_FLAGS | ENABLE_INSERT_MODE | ENABLE_QUICK_EDIT_MODE ) +#define CONSOLE_VALID_INPUT_MODES ( ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | \ + ENABLE_ECHO_INPUT | ENABLE_WINDOW_INPUT | \ + ENABLE_MOUSE_INPUT ) +#define CONSOLE_VALID_OUTPUT_MODES ( ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT ) NTSTATUS Status; PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleModeRequest; - Object_t* Object = NULL; + DWORD ConsoleMode = ConsoleModeRequest->ConsoleMode; + Object_t* Object = NULL; Status = ConSrvGetObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process), - ConsoleModeRequest->ConsoleHandle, - &Object, NULL, GENERIC_WRITE, TRUE, 0); + ConsoleModeRequest->ConsoleHandle, + &Object, NULL, GENERIC_WRITE, TRUE, 0); if (!NT_SUCCESS(Status)) return Status; Status = STATUS_SUCCESS; @@ -1030,18 +1032,62 @@ CSR_API(SrvSetConsoleMode) if (CONIO_INPUT_BUFFER_MAGIC == Object->Type) { PCONSOLE_INPUT_BUFFER InputBuffer = (PCONSOLE_INPUT_BUFFER)Object; - InputBuffer->Mode = ConsoleModeRequest->ConsoleMode & CONSOLE_INPUT_MODE_VALID; + PCONSOLE Console = InputBuffer->Header.Console; + + DPRINT("SetConsoleMode(Input, %d)\n", ConsoleMode); + + /* + * 1. Only the presence of valid mode flags is allowed. + */ + if (ConsoleMode & ~(CONSOLE_VALID_INPUT_MODES | CONSOLE_VALID_CONTROL_MODES)) + { + Status = STATUS_INVALID_PARAMETER; + goto Quit; + } + + /* + * 2. If we use control mode flags without ENABLE_EXTENDED_FLAGS, + * then consider the flags invalid. + * + if ( (ConsoleMode & CONSOLE_VALID_CONTROL_MODES) && + (ConsoleMode & ENABLE_EXTENDED_FLAGS) == 0 ) + { + Status = STATUS_INVALID_PARAMETER; + goto Quit; + } + */ + + /* + * 3. Now we can continue. + */ + if (ConsoleMode & CONSOLE_VALID_CONTROL_MODES) + { + Console->QuickEdit = !!(ConsoleMode & ENABLE_QUICK_EDIT_MODE); + Console->InsertMode = !!(ConsoleMode & ENABLE_INSERT_MODE); + } + InputBuffer->Mode = (ConsoleMode & CONSOLE_VALID_INPUT_MODES); } else if (CONIO_SCREEN_BUFFER_MAGIC == Object->Type) { PCONSOLE_SCREEN_BUFFER Buffer = (PCONSOLE_SCREEN_BUFFER)Object; - Buffer->Mode = ConsoleModeRequest->ConsoleMode & CONSOLE_OUTPUT_MODE_VALID; + + DPRINT("SetConsoleMode(Output, %d)\n", ConsoleMode); + + if (ConsoleMode & ~CONSOLE_VALID_OUTPUT_MODES) + { + Status = STATUS_INVALID_PARAMETER; + } + else + { + Buffer->Mode = (ConsoleMode & CONSOLE_VALID_OUTPUT_MODES); + } } else { Status = STATUS_INVALID_HANDLE; } +Quit: ConSrvReleaseObject(Object, TRUE); return Status; } @@ -1053,8 +1099,8 @@ CSR_API(SrvGetConsoleMode) Object_t* Object = NULL; Status = ConSrvGetObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process), - ConsoleModeRequest->ConsoleHandle, - &Object, NULL, GENERIC_READ, TRUE, 0); + ConsoleModeRequest->ConsoleHandle, + &Object, NULL, GENERIC_READ, TRUE, 0); if (!NT_SUCCESS(Status)) return Status; Status = STATUS_SUCCESS; @@ -1062,7 +1108,19 @@ CSR_API(SrvGetConsoleMode) if (CONIO_INPUT_BUFFER_MAGIC == Object->Type) { PCONSOLE_INPUT_BUFFER InputBuffer = (PCONSOLE_INPUT_BUFFER)Object; - ConsoleModeRequest->ConsoleMode = InputBuffer->Mode; + PCONSOLE Console = InputBuffer->Header.Console; + DWORD ConsoleMode = InputBuffer->Mode; + + if (Console->QuickEdit || Console->InsertMode) + { + // Windows does this, even if it's not documented on MSDN + ConsoleMode |= ENABLE_EXTENDED_FLAGS; + + if (Console->QuickEdit ) ConsoleMode |= ENABLE_QUICK_EDIT_MODE; + if (Console->InsertMode) ConsoleMode |= ENABLE_INSERT_MODE; + } + + ConsoleModeRequest->ConsoleMode = ConsoleMode; } else if (CONIO_SCREEN_BUFFER_MAGIC == Object->Type) { @@ -1181,7 +1239,7 @@ CSR_API(SrvGetConsoleTitle) * with NT's, but values are not. */ static NTSTATUS FASTCALL -SetConsoleHardwareState(PCONSOLE Console, DWORD ConsoleHwState) +SetConsoleHardwareState(PCONSOLE Console, ULONG ConsoleHwState) { DPRINT1("Console Hardware State: %d\n", ConsoleHwState); @@ -1223,7 +1281,6 @@ CSR_API(SrvGetConsoleHardwareState) HardwareStateRequest->State = Console->HardwareState; ConSrvReleaseScreenBuffer(Buff, TRUE); - return Status; } @@ -1237,7 +1294,7 @@ CSR_API(SrvSetConsoleHardwareState) Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), HardwareStateRequest->OutputHandle, &Buff, - GENERIC_READ, + GENERIC_WRITE, TRUE); if (!NT_SUCCESS(Status)) { @@ -1250,7 +1307,67 @@ CSR_API(SrvSetConsoleHardwareState) Status = SetConsoleHardwareState(Console, HardwareStateRequest->State); ConSrvReleaseScreenBuffer(Buff, TRUE); + return Status; +} +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); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to get console handle in SrvGetConsoleDisplayMode\n"); + 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; + + ConSrvReleaseConsole(Console, TRUE); + return Status; +} + +CSR_API(SrvSetConsoleDisplayMode) +{ + NTSTATUS Status; + PCONSOLE_SETDISPLAYMODE SetDisplayModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetDisplayModeRequest; + PCONSOLE_SCREEN_BUFFER Buff; + + Status = ConSrvGetScreenBuffer(ConsoleGetPerProcessData(CsrGetClientThread()->Process), + SetDisplayModeRequest->OutputHandle, + &Buff, + GENERIC_WRITE, + TRUE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to get console handle in SrvSetConsoleDisplayMode\n"); + return Status; + } + + if (SetDisplayModeRequest->DisplayMode & ~(CONSOLE_FULLSCREEN_MODE | CONSOLE_WINDOWED_MODE)) + { + Status = STATUS_INVALID_PARAMETER; + } + else + { + Buff->DisplayMode = SetDisplayModeRequest->DisplayMode; + // TODO: Change the display mode + SetDisplayModeRequest->NewSBDim = Buff->ScreenBufferSize; + + Status = STATUS_SUCCESS; + } + + ConSrvReleaseScreenBuffer(Buff, TRUE); return Status; } diff --git a/win32ss/user/consrv/consrv.h b/win32ss/user/consrv/consrv.h index 7275515fe3f..9b95b1f3fa0 100644 --- a/win32ss/user/consrv/consrv.h +++ b/win32ss/user/consrv/consrv.h @@ -151,6 +151,8 @@ CSR_API(SrvSetConsoleTitle); CSR_API(SrvGetConsoleTitle); CSR_API(SrvGetConsoleHardwareState); CSR_API(SrvSetConsoleHardwareState); +CSR_API(SrvGetConsoleDisplayMode); +CSR_API(SrvSetConsoleDisplayMode); CSR_API(SrvGetConsoleWindow); CSR_API(SrvSetConsoleIcon); CSR_API(SrvGetConsoleCP); diff --git a/win32ss/user/consrv/frontends/gui/guisettings.c b/win32ss/user/consrv/frontends/gui/guisettings.c index 3fc5418919b..0a276729e1f 100644 --- a/win32ss/user/consrv/frontends/gui/guisettings.c +++ b/win32ss/user/consrv/frontends/gui/guisettings.c @@ -281,7 +281,7 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData, pSharedInfo->ci.HistoryBufferSize = Console->HistoryBufferSize; pSharedInfo->ci.NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers; pSharedInfo->ci.HistoryNoDup = Console->HistoryNoDup; - pSharedInfo->ci.FullScreen = Console->FullScreen; + pSharedInfo->ci.FullScreen = !!(Console->ActiveBuffer->DisplayMode & CONSOLE_FULLSCREEN_MODE); pSharedInfo->ci.QuickEdit = Console->QuickEdit; pSharedInfo->ci.InsertMode = Console->InsertMode; pSharedInfo->ci.InputBufferSize = 0; diff --git a/win32ss/user/consrv/frontends/gui/guiterm.c b/win32ss/user/consrv/frontends/gui/guiterm.c index c8d2a01d409..74e2520df5a 100644 --- a/win32ss/user/consrv/frontends/gui/guiterm.c +++ b/win32ss/user/consrv/frontends/gui/guiterm.c @@ -16,6 +16,8 @@ #include "guisettings.h" #include "resource.h" +#include + #define NDEBUG #include @@ -876,12 +878,12 @@ PointToCoord(PGUI_CONSOLE_DATA GuiData, LPARAM lParam) static LRESULT GuiConsoleHandleMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM lParam) { - LRESULT Ret = TRUE; + BOOL Err = FALSE; PCONSOLE Console = GuiData->Console; if (!ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) { - Ret = FALSE; + Err = TRUE; goto Quit; } @@ -943,7 +945,7 @@ GuiConsoleHandleMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM } default: - Ret = FALSE; + Err = TRUE; break; } } @@ -958,31 +960,37 @@ GuiConsoleHandleMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM switch (msg) { case WM_LBUTTONDOWN: + SetCapture(GuiData->hWindow); dwButtonState = FROM_LEFT_1ST_BUTTON_PRESSED; dwEventFlags = 0; break; case WM_MBUTTONDOWN: + SetCapture(GuiData->hWindow); dwButtonState = FROM_LEFT_2ND_BUTTON_PRESSED; dwEventFlags = 0; break; case WM_RBUTTONDOWN: + SetCapture(GuiData->hWindow); dwButtonState = RIGHTMOST_BUTTON_PRESSED; dwEventFlags = 0; break; case WM_LBUTTONUP: + ReleaseCapture(); dwButtonState = 0; dwEventFlags = 0; break; case WM_MBUTTONUP: + ReleaseCapture(); dwButtonState = 0; dwEventFlags = 0; break; case WM_RBUTTONUP: + ReleaseCapture(); dwButtonState = 0; dwEventFlags = 0; break; @@ -1018,11 +1026,11 @@ GuiConsoleHandleMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM break; default: - Ret = FALSE; + Err = TRUE; break; } - if (Ret) + if (!Err) { if (wKeyState & MK_LBUTTON) dwButtonState |= FROM_LEFT_1ST_BUTTON_PRESSED; @@ -1060,14 +1068,18 @@ GuiConsoleHandleMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM ConioProcessInputEvent(Console, &er); } } + else + { + Err = TRUE; + } LeaveCriticalSection(&Console->Lock); Quit: - if (!Ret) - Ret = DefWindowProcW(GuiData->hWindow, msg, wParam, lParam); - - return Ret; + if (Err) + return DefWindowProcW(GuiData->hWindow, msg, wParam, lParam); + else + return 0; } static VOID @@ -1473,6 +1485,50 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) break; } + case WM_NCRBUTTONDOWN: + { + DPRINT("WM_NCRBUTTONDOWN\n"); + /* + * HACK: !! Because, when we deal with WM_RBUTTON* and we do not + * call after that DefWindowProc, on ReactOS, right-clicks on the + * (non-client) application title-bar does not display the system + * menu and does not trigger a WM_NCRBUTTONUP message too. + * See: http://git.reactos.org/?p=reactos.git;a=blob;f=reactos/win32ss/user/user32/windows/defwnd.c;hb=HEAD#l1103 + * and line 1135 too. + */ + if (DefWindowProcW(hWnd, WM_NCHITTEST, 0, lParam) == HTCAPTION) + return DefWindowProcW(hWnd, WM_CONTEXTMENU, wParam, lParam); + else + goto Default; + } + // case WM_NCRBUTTONUP: + // DPRINT1("WM_NCRBUTTONUP\n"); + // goto Default; + + case WM_CONTEXTMENU: + { + if (DefWindowProcW(hWnd /*GuiData->hWindow*/, WM_NCHITTEST, 0, lParam) == HTCLIENT) + { + HMENU hMenu = CreatePopupMenu(); + if (hMenu != NULL) + { + GuiConsoleAppendMenuItems(hMenu, GuiConsoleEditMenuItems); + TrackPopupMenuEx(hMenu, + TPM_RIGHTBUTTON, + GET_X_LPARAM(lParam), + GET_Y_LPARAM(lParam), + hWnd, + NULL); + DestroyMenu(hMenu); + } + break; + } + else + { + goto Default; + } + } + case WM_SYSCOMMAND: { Result = GuiConsoleHandleSysMenuCommand(GuiData, wParam, lParam); @@ -1486,6 +1542,22 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) break; } + case WM_SETFOCUS: + case WM_KILLFOCUS: + { + Console = GuiData->Console; // Not NULL because checked in GuiGetGuiData. + if (ConSrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) + { + INPUT_RECORD er; + er.EventType = FOCUS_EVENT; + er.Event.FocusEvent.bSetFocus = (msg == WM_SETFOCUS); + ConioProcessInputEvent(Console, &er); + + LeaveCriticalSection(&Console->Lock); + } + break; + } + case WM_GETMINMAXINFO: GuiConsoleGetMinMaxInfo(GuiData, (PMINMAXINFO)lParam); break; @@ -1514,7 +1586,7 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) // SetWindowText(GuiData->hWindow, GuiData->Console->Title.Buffer); // break; - default: + default: Default: Result = DefWindowProcW(hWnd, msg, wParam, lParam); break; } @@ -1725,7 +1797,7 @@ GuiInit(VOID) wc.cbSize = sizeof(WNDCLASSEXW); wc.lpszClassName = GUI_CONSOLE_WINDOW_CLASS; wc.lpfnWndProc = GuiConsoleWndProc; - wc.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; + wc.style = CS_DBLCLKS /* | CS_HREDRAW | CS_VREDRAW */; wc.hInstance = ConSrvDllInstance; wc.hIcon = ghDefaultIcon; wc.hIconSm = ghDefaultIconSm; @@ -2207,6 +2279,7 @@ GuiInitConsole(PCONSOLE Console, /* if (ConsoleStartInfo->dwStartupFlags & STARTF_RUNFULLSCREEN) { + ConsoleInfo.FullScreen = TRUE; } */ } diff --git a/win32ss/user/consrv/init.c b/win32ss/user/consrv/init.c index 3e4dd14bfb6..4e0aacc5260 100644 --- a/win32ss/user/consrv/init.c +++ b/win32ss/user/consrv/init.c @@ -73,11 +73,11 @@ PCSR_API_ROUTINE ConsoleServerApiDispatchTable[ConsolepMaxApiNumber - CONSRV_FIR // SrvShowConsoleCursor, // SrvConsoleMenuControl, // SrvSetConsolePalette, - // SrvSetConsoleDisplayMode, + SrvSetConsoleDisplayMode, // SrvRegisterConsoleVDM, SrvGetConsoleHardwareState, SrvSetConsoleHardwareState, - // SrvGetConsoleDisplayMode, + SrvGetConsoleDisplayMode, SrvAddConsoleAlias, SrvGetConsoleAlias, SrvGetConsoleAliasesLength, @@ -164,11 +164,11 @@ BOOLEAN ConsoleServerApiServerValidTable[ConsolepMaxApiNumber - CONSRV_FIRST_API // FALSE, // SrvShowConsoleCursor, // FALSE, // SrvConsoleMenuControl, // FALSE, // SrvSetConsolePalette, - // FALSE, // SrvSetConsoleDisplayMode, + FALSE, // SrvSetConsoleDisplayMode, // FALSE, // SrvRegisterConsoleVDM, FALSE, // SrvGetConsoleHardwareState, FALSE, // SrvSetConsoleHardwareState, - // TRUE, // SrvGetConsoleDisplayMode, + TRUE, // SrvGetConsoleDisplayMode, FALSE, // SrvAddConsoleAlias, FALSE, // SrvGetConsoleAlias, FALSE, // SrvGetConsoleAliasesLength, @@ -255,11 +255,11 @@ PCHAR ConsoleServerApiNameTable[ConsolepMaxApiNumber - CONSRV_FIRST_API_NUMBER] // "ShowConsoleCursor", // "ConsoleMenuControl", // "SetConsolePalette", - // "SetConsoleDisplayMode", + "SetConsoleDisplayMode", // "RegisterConsoleVDM", "GetConsoleHardwareState", "SetConsoleHardwareState", - // "GetConsoleDisplayMode", + "GetConsoleDisplayMode", "AddConsoleAlias", "GetConsoleAlias", "GetConsoleAliasesLength",