diff --git a/reactos/include/csrss/csrss.h b/reactos/include/csrss/csrss.h index c1e59c71cef..13d428a58ab 100644 --- a/reactos/include/csrss/csrss.h +++ b/reactos/include/csrss/csrss.h @@ -368,6 +368,26 @@ typedef struct HANDLE Handle; } CSRSS_DUPLICATE_HANDLE_REPLY, *PCSRSS_DUPLICATE_HANDLE_REPLY; +#define CONSOLE_HARDWARE_STATE_GET 0 +#define CONSOLE_HARDWARE_STATE_SET 1 + +#define CONSOLE_HARDWARE_STATE_GDI_MANAGED 0 +#define CONSOLE_HARDWARE_STATE_DIRECT 1 + +typedef struct +{ + HANDLE ConsoleHandle; + DWORD SetGet; // 0=get; 1=set + DWORD State; + +} CSRSS_CONSOLE_HARDWARE_STATE, *PCSRSS_CONSOLE_HARDWARE_STATE; + +typedef struct +{ + HANDLE ConsoleHandle; + HWND WindowHandle; +} CSRSS_CONSOLE_WINDOW, *PCSRSS_CONSOLE_WINDOW; + #define CSRSS_MAX_WRITE_CONSOLE_REQUEST \ (MAX_MESSAGE_DATA - sizeof(ULONG) - sizeof(CSRSS_WRITE_CONSOLE_REQUEST)) @@ -427,6 +447,8 @@ typedef struct #define CSRSS_CLOSE_HANDLE (0x26) #define CSRSS_VERIFY_HANDLE (0x27) #define CSRSS_DUPLICATE_HANDLE (0x28) +#define CSRSS_SETGET_CONSOLE_HW_STATE (0x29) +#define CSRSS_GET_CONSOLE_WINDOW (0x2A) /* Keep in sync with definition below. */ #define CSRSS_REQUEST_HEADER_SIZE (sizeof(LPC_MESSAGE) + sizeof(ULONG)) @@ -473,6 +495,8 @@ typedef struct CSRSS_CLOSE_HANDLE_REQUEST CloseHandleRequest; CSRSS_VERIFY_HANDLE_REQUEST VerifyHandleRequest; CSRSS_DUPLICATE_HANDLE_REQUEST DuplicateHandleRequest; + CSRSS_CONSOLE_HARDWARE_STATE ConsoleHardwareStateRequest; + CSRSS_CONSOLE_WINDOW ConsoleWindowRequest; } Data; } CSRSS_API_REQUEST, *PCSRSS_API_REQUEST; @@ -506,6 +530,8 @@ typedef struct CSRSS_GET_INPUT_HANDLE_REPLY GetInputHandleReply; CSRSS_GET_OUTPUT_HANDLE_REPLY GetOutputHandleReply; CSRSS_DUPLICATE_HANDLE_REPLY DuplicateHandleReply; + CSRSS_CONSOLE_HARDWARE_STATE ConsoleHardwareStateReply; + CSRSS_CONSOLE_WINDOW ConsoleWindowReply; } Data; } CSRSS_API_REPLY, *PCSRSS_API_REPLY; diff --git a/reactos/lib/kernel32/kernel32.def b/reactos/lib/kernel32/kernel32.def index 9187a90dc73..39e5a193982 100644 --- a/reactos/lib/kernel32/kernel32.def +++ b/reactos/lib/kernel32/kernel32.def @@ -238,6 +238,7 @@ GetConsoleScreenBufferInfo@8 GetConsoleSelectionInfo@4 GetConsoleTitleA@8 GetConsoleTitleW@8 +GetConsoleWindow@0 GetCurrencyFormatA@24 GetCurrencyFormatW@24 GetCurrentConsoleFont@12 diff --git a/reactos/lib/kernel32/kernel32.edf b/reactos/lib/kernel32/kernel32.edf index 3b4b1d23eb6..afd19d4a40f 100644 --- a/reactos/lib/kernel32/kernel32.edf +++ b/reactos/lib/kernel32/kernel32.edf @@ -1,4 +1,4 @@ -; $Id: kernel32.edf,v 1.24 2003/05/29 00:36:41 hyperion Exp $ +; $Id: kernel32.edf,v 1.25 2003/06/19 19:38:26 ea Exp $ ; ; kernel32.edf ; @@ -242,6 +242,7 @@ GetConsoleScreenBufferInfo=GetConsoleScreenBufferInfo@8 GetConsoleSelectionInfo=GetConsoleSelectionInfo@4 GetConsoleTitleA=GetConsoleTitleA@8 GetConsoleTitleW=GetConsoleTitleW@8 +GetConsoleWindow=GetConsoleWindow@0 GetCurrencyFormatA=GetCurrencyFormatA@24 GetCurrencyFormatW=GetCurrencyFormatW@24 GetCurrentConsoleFont=GetCurrentConsoleFont@12 diff --git a/reactos/lib/kernel32/misc/console.c b/reactos/lib/kernel32/misc/console.c index 1b0fef76282..a5c6da07cac 100644 --- a/reactos/lib/kernel32/misc/console.c +++ b/reactos/lib/kernel32/misc/console.c @@ -1,4 +1,4 @@ -/* $Id: console.c,v 1.57 2003/05/16 20:33:15 ea Exp $ +/* $Id: console.c,v 1.58 2003/06/19 19:38:26 ea Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -305,15 +305,32 @@ GetConsoleFontSize(HANDLE hConsoleOutput, } DWORD STDCALL -GetConsoleHardwareState (DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2) +GetConsoleHardwareState (HANDLE hConsole, + DWORD Flags, + PDWORD State) /* * Undocumented */ { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + CSRSS_API_REQUEST Request; + CSRSS_API_REPLY Reply; + NTSTATUS Status; + + Request.Type = CSRSS_SETGET_CONSOLE_HW_STATE; + Request.Data.ConsoleHardwareStateRequest.ConsoleHandle = hConsole; + Request.Data.ConsoleHardwareStateRequest.SetGet = CONSOLE_HARDWARE_STATE_GET; + + Status = CsrClientCallServer(& Request, + & Reply, + sizeof(CSRSS_API_REQUEST), + sizeof(CSRSS_API_REPLY)); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + *State = Reply.Data.ConsoleHardwareStateReply.State; + return TRUE; } DWORD STDCALL @@ -457,15 +474,32 @@ SetConsoleFont (DWORD Unknown0, } WINBOOL STDCALL -SetConsoleHardwareState (DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2) +SetConsoleHardwareState (HANDLE hConsole, + DWORD Flags, + DWORD State) /* * Undocumented */ { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + CSRSS_API_REQUEST Request; + CSRSS_API_REPLY Reply; + NTSTATUS Status; + + Request.Type = CSRSS_SETGET_CONSOLE_HW_STATE; + Request.Data.ConsoleHardwareStateRequest.ConsoleHandle = hConsole; + Request.Data.ConsoleHardwareStateRequest.SetGet = CONSOLE_HARDWARE_STATE_SET; + Request.Data.ConsoleHardwareStateRequest.State = State; + + Status = CsrClientCallServer(& Request, + & Reply, + sizeof(CSRSS_API_REQUEST), + sizeof(CSRSS_API_REPLY)); + if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status)) + { + SetLastErrorByStatus(Status); + return FALSE; + } + return TRUE; } WINBOOL STDCALL @@ -2186,7 +2220,7 @@ RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine) { for (i = 0; i < NrCtrlHandlers; i++) { - if (CtrlHandlers[i] == HandlerRoutine) + if ((PHANDLER_ROUTINE) CtrlHandlers[i] == HandlerRoutine) { CtrlHandlers[i] = CtrlHandlers[NrCtrlHandlers - 1]; NrCtrlHandlers--; @@ -2656,4 +2690,31 @@ AttachConsole(DWORD dwProcessId) return FALSE; } +/*-------------------------------------------------------------- + * GetConsoleWindow/0 + */ +HWND STDCALL +GetConsoleWindow (VOID) +{ + CSRSS_API_REQUEST Request; + CSRSS_API_REPLY Reply; + NTSTATUS Status; + + Request.Data.ConsoleWindowRequest.ConsoleHandle = + OpenConsoleW (L"CONOUT$", (GENERIC_READ|GENERIC_WRITE), FALSE, OPEN_EXISTING); + if (INVALID_HANDLE_VALUE == Request.Data.ConsoleWindowRequest.ConsoleHandle) + { + return (HWND) NULL; + } + Request.Type = CSRSS_GET_CONSOLE_WINDOW; + Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) ); + if (!NT_SUCCESS(Status ) || !NT_SUCCESS(Status = Reply.Status)) + { + SetLastErrorByStatus (Status); + return (HWND) NULL; + } + return Reply.Data.ConsoleWindowReply.WindowHandle; +} + + /* EOF */ diff --git a/reactos/subsys/csrss/api.h b/reactos/subsys/csrss/api.h index 53d29bf071f..0d3d4cb9b68 100644 --- a/reactos/subsys/csrss/api.h +++ b/reactos/subsys/csrss/api.h @@ -66,11 +66,13 @@ typedef struct CSRSS_CONSOLE_t WORD Mode; /* Console mode flags */ WORD EchoCount; /* count of chars to echo, in line buffered mode */ UNICODE_STRING Title; /* Title of console */ - struct { /* active code pages */ + struct { /* active code pages */ UINT Input; UINT Output; } CodePageId; - BOOL EarlyReturn; /* wake client and return data, even if we are in line buffered mode, and we don't have a complete line */ + BOOL EarlyReturn; /* wake client and return data, even if we are in line buffered mode, and we don't have a complete line */ + DWORD HardwareState; /* _GDI_MANAGED, _DIRECT */ + HWND hWindow; } CSRSS_CONSOLE, *PCSRSS_CONSOLE; typedef struct _CSRSS_PROCESS_DATA @@ -137,6 +139,8 @@ CSR_API(CsrGetOutputHandle); CSR_API(CsrCloseHandle); CSR_API(CsrVerifyHandle); CSR_API(CsrDuplicateHandle); +CSR_API(CsrHardwareStateProperty); +CSR_API(CsrGetConsoleWindow); /* print.c */ VOID STDCALL DisplayString(LPCWSTR lpwString); diff --git a/reactos/subsys/csrss/api/conio.c b/reactos/subsys/csrss/api/conio.c index 019970e6d05..38abe19b368 100644 --- a/reactos/subsys/csrss/api/conio.c +++ b/reactos/subsys/csrss/api/conio.c @@ -1,4 +1,4 @@ -/* $Id: conio.c,v 1.47 2003/03/26 22:10:43 hbirr Exp $ +/* $Id: conio.c,v 1.48 2003/06/19 19:38:26 ea Exp $ * * reactos/subsys/csrss/api/conio.c * @@ -757,6 +757,9 @@ NTSTATUS STDCALL CsrInitConsole(PCSRSS_CONSOLE Console) RtlFreeHeap( CsrssApiHeap, 0, Console->ActiveBuffer ); return Status; } + /* Create the GDI Window to be used in windowed mode */ + /* FIXME: create window; now write NULL */ + Console->hWindow = (HWND) NULL; /* add a reference count because the buffer is tied to the console */ Console->ActiveBuffer->Header.ReferenceCount++; /* make console active, and insert into console list */ @@ -2443,4 +2446,120 @@ CSR_API(CsrWriteConsoleInput) return Reply->Status; } +/********************************************************************** + * HardwareStateProperty + * + * DESCRIPTION + * Set/Get the value of the HardwareState and switch + * between direct video buffer ouput and GDI windowed + * output. + * ARGUMENTS + * Client hands us a CSRSS_CONSOLE_HARDWARE_STATE + * object. We use the same object to reply. + * NOTE + * ConsoleHwState has the correct size to be compatible + * with NT's, but values are not. + */ +static NTSTATUS FASTCALL SetConsoleHardwareState (PCSRSS_CONSOLE Console, DWORD ConsoleHwState) +{ + if ( (CONSOLE_HARDWARE_STATE_GDI_MANAGED == ConsoleHwState) + ||(CONSOLE_HARDWARE_STATE_DIRECT == ConsoleHwState)) + { + if (Console->HardwareState != ConsoleHwState) + { + /* TODO: implement switching from full screen to windowed mode */ + /* TODO: or back; now simply store the hardware state */ + Console->HardwareState = ConsoleHwState; + } + return STATUS_SUCCESS; + } + return STATUS_INVALID_PARAMETER_3; // Client: (handle, set_get, [mode]) +} + +CSR_API(CsrHardwareStateProperty) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status; + + Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY); + Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE); + + LOCK; + + Status = CsrGetObject ( + ProcessData, + Request->Data.ConsoleHardwareStateRequest.ConsoleHandle, + (Object_t**) & Console + ); + if (!NT_SUCCESS(Status)) + { + Reply->Status = Status; + } + else + { + if(Console->Header.Type != CSRSS_CONSOLE_MAGIC) + { + Reply->Status = STATUS_INVALID_HANDLE; + } + else + { + switch (Request->Data.ConsoleHardwareStateRequest.SetGet) + { + case CONSOLE_HARDWARE_STATE_GET: + Reply->Data.ConsoleHardwareStateReply.State = Console->HardwareState; + break; + + case CONSOLE_HARDWARE_STATE_SET: + Reply->Status = SetConsoleHardwareState (Console, Request->Data.ConsoleHardwareStateRequest.State); + break; + + default: + Reply->Status = STATUS_INVALID_PARAMETER_2; // Client: (handle, [set_get], mode) + break; + } + } + } + + UNLOCK; + + return Reply->Status; +} + +CSR_API(CsrGetConsoleWindow) +{ + PCSRSS_CONSOLE Console; + NTSTATUS Status; + + Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY); + Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE); + + LOCK; + + Status = CsrGetObject ( + ProcessData, + Request->Data.ConsoleWindowRequest.ConsoleHandle, + (Object_t**) & Console + ); + if (!NT_SUCCESS(Status)) + { + Reply->Status = Status; + } + else + { + if(Console->Header.Type != CSRSS_CONSOLE_MAGIC) + { + Reply->Status = STATUS_INVALID_HANDLE; + } + else + { + // Is this GDI handle valid in the client's context? + Reply->Data.ConsoleWindowReply.WindowHandle = Console->hWindow; + } + } + + UNLOCK; + + return Reply->Status; +} + /* EOF */