|
|
/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
Con
Abstract:
Takes care of request involving the console ( CON: )
Author:
Ramon Juan San Andres (ramonsa) 26-Jun-1991
Notes:
This module issues direct calls to USER, because having ULIB doing so causes programs to crash.
Revision History:
--*/
#include "mode.hxx"
#include "cons.hxx"
#include "keyboard.hxx"
#include "path.hxx"
#include "screen.hxx"
#include "stream.hxx"
#include "system.hxx"
//
// Local prototypes
//
BOOLEAN ConStatus( IN PREQUEST_HEADER Request, IN BOOLEAN JustCodePage );
BOOLEAN ConCodePage( IN PREQUEST_HEADER Request );
BOOLEAN ConSetRowCol( IN PREQUEST_HEADER Request );
BOOLEAN ConSetTypematic( IN PREQUEST_HEADER Request );
BOOLEAN ConHandler( IN PREQUEST_HEADER Request )
/*++
Routine Description:
Handles console requests
Arguments:
Request - Supplies pointer to request
Return Value:
None.
Notes:
--*/
{
BOOLEAN Served = TRUE; // TRUE if request served OK.
DebugPtrAssert( Request ); DebugAssert( Request->DeviceType == DEVICE_TYPE_CON );
//
// So the device is valid. Now serve the request
//
switch( Request->RequestType ) {
case REQUEST_TYPE_STATUS:
//
// Display state of CON device
//
Served = ConStatus( Request, FALSE ); break;
case REQUEST_TYPE_CODEPAGE_PREPARE: case REQUEST_TYPE_CODEPAGE_SELECT: case REQUEST_TYPE_CODEPAGE_REFRESH:
//
// Handle Codepage requests
//
Served = ConCodePage( Request ); break;
case REQUEST_TYPE_CODEPAGE_STATUS:
//
// Display codepage status
//
Served = ConStatus( Request, TRUE ); break;
case REQUEST_TYPE_CON_SET_ROWCOL:
//
// Set rows & columns
//
Served = ConSetRowCol( Request ); break;
case REQUEST_TYPE_CON_SET_TYPEMATIC:
//
// Set typematic rate
//
Served = ConSetTypematic( Request ); break;
default:
DisplayMessageAndExit( MODE_ERROR_INVALID_PARAMETER, NULL, (ULONG)EXIT_ERROR );
}
return Served;
}
BOOLEAN ConStatus( IN PREQUEST_HEADER Request, IN BOOLEAN JustCodePage )
/*++
Routine Description:
Displays status of a console
Arguments:
Request - Supplies pointer to request JustCodePage- Supplies a flag which if TRUE means that only the codepage status should be displayed.
Return Value:
BOOLEAN - TRUE if status displayed successfully, FALSE otherwise
Notes:
--*/
{
SCREEN Screen;
PATH ConPath;
USHORT Rows; USHORT Cols;
ULONG Delay = 0; ULONG Speed = 0;
DSTRING CodepageName;
ULONG Language; ULONG Country; ULONG Codepage;
DSTRING CodepageString; PSTR S1, S2;
if ( !ConPath.Initialize( (LPWSTR)L"CON" ) ) { DisplayMessageAndExit( MODE_ERROR_NO_MEMORY, NULL, (ULONG)EXIT_ERROR ); }
//
// Write the Header
//
WriteStatusHeader( &ConPath );
if ( !Screen.Initialize() ) { DisplayMessageAndExit( MODE_ERROR_NO_MEMORY, NULL, (ULONG)EXIT_ERROR ); }
if ( !JustCodePage ) {
//
// Display non-codepage information
//
Screen.QueryScreenSize( &Rows, &Cols );
Message->Set( MODE_MESSAGE_STATUS_LINES ); Message->Display( "%d", Rows );
Message->Set( MODE_MESSAGE_STATUS_COLS ); Message->Display( "%d", Cols );
if (!SystemParametersInfo( SPI_GETKEYBOARDSPEED, 0, (PVOID)&Speed, 0 )) { ExitWithError( GetLastError() ); } Message->Set( MODE_MESSAGE_STATUS_RATE ); Message->Display( "%d", Speed );
if (!SystemParametersInfo( SPI_GETKEYBOARDDELAY, 0, (PVOID)&Delay, 0 )) { ExitWithError( GetLastError() ); }
Message->Set( MODE_MESSAGE_STATUS_DELAY ); Message->Display( "%d", Delay );
}
Message->Set( MODE_MESSAGE_STATUS_CODEPAGE ); Message->Display( "%d", Screen.QueryCodePage( ) );
Get_Standard_Output_Stream()->WriteChar( '\r' ); Get_Standard_Output_Stream()->WriteChar( '\n' );
return TRUE; }
BOOLEAN ConCodePage( IN PREQUEST_HEADER Request )
/*++
Routine Description:
Handles Codepage requests for the console
Arguments:
Request - Supplies pointer to request
Return Value:
BOOLEAN - TRUE if request handled successfully, FALSE otherwise
Notes:
--*/
{ SCREEN Screen; PREQUEST_DATA_CON_CODEPAGE_SELECT Data;
//
// We only process Codepage Select requests, all other requests
// are No-Ops. Note that the Codepage Status request is not
// processed here.
//
if ( Request->RequestType == REQUEST_TYPE_CODEPAGE_SELECT ) {
Data = (PREQUEST_DATA_CON_CODEPAGE_SELECT)&(((PCON_REQUEST)Request)-> Data.CpSelect);
if ( !Screen.Initialize() ) { DisplayMessageAndExit( MODE_ERROR_NO_MEMORY, NULL, (ULONG)EXIT_ERROR ); }
if ( !Screen.SetCodePage( Data->Codepage ) || !Screen.SetOutputCodePage( Data->Codepage) ) { DisplayMessageAndExit( MODE_ERROR_INVALID_CODEPAGE, NULL, (ULONG)EXIT_ERROR ); }
#ifdef FE_SB
LANGID LangId;
switch (GetConsoleOutputCP()) { case 932: LangId = MAKELANGID( LANG_JAPANESE, SUBLANG_DEFAULT ); break; case 949: LangId = MAKELANGID( LANG_KOREAN, SUBLANG_KOREAN ); break; case 936: LangId = MAKELANGID( LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED ); break; case 950: LangId = MAKELANGID( LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL ); break; default: LangId = PRIMARYLANGID(LANGIDFROMLCID( GetUserDefaultLCID() )); if (LangId == LANG_JAPANESE || LangId == LANG_KOREAN || LangId == LANG_CHINESE ) { LangId = MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ); } else { LangId = MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ); } break; }
SetThreadLocale( MAKELCID(LangId, SORT_DEFAULT) ); #endif
ConStatus( Request, FALSE );
} else {
DisplayMessageAndExit( MODE_MESSAGE_NOT_NEEDED, NULL, EXIT_SUCCESS ); }
return TRUE; }
BOOLEAN ConSetRowCol( IN PREQUEST_HEADER Request )
/*++
Routine Description:
Sets number of rows and columns in the console window.
Arguments:
Request - Supplies pointer to request
Return Value:
BOOLEAN - TRUE if Number of Rows & Columns set successfully, FALSE otherwise
Notes:
--*/
{
PREQUEST_DATA_CON_ROWCOL Data;
SCREEN Screen;
USHORT Rows; USHORT Cols; BOOLEAN IsFullScreen;
DebugPtrAssert( Request);
Data = (PREQUEST_DATA_CON_ROWCOL)&(((PCON_REQUEST)Request)->Data.RowCol);
if ( !Screen.Initialize() ) { DisplayMessageAndExit( MODE_ERROR_NO_MEMORY, NULL, (ULONG)EXIT_ERROR ); }
if ( !Data->SetCol || !Data->SetLines ) {
//
// Since we don't have both values, take the current ones.
//
Screen.QueryScreenSize( &Rows, &Cols ); }
//
// Set the number of rows and columns
//
if ( Data->SetCol ) {
Cols = (USHORT)Data->Col;
}
if ( Data->SetLines ) {
Rows = (USHORT)Data->Lines;
}
if ( !Screen.ChangeScreenSize( Rows, Cols, &IsFullScreen ) ) {
//
// Cannot change the screen size
//
if ( IsFullScreen ) { DisplayMessageAndExit( MODE_ERROR_FULL_SCREEN, NULL, (ULONG)EXIT_ERROR ); } else { DisplayMessageAndExit( MODE_ERROR_INVALID_SCREEN_SIZE, NULL, (ULONG)EXIT_ERROR ); } }
return TRUE; }
BOOLEAN ConSetTypematic( IN PREQUEST_HEADER Request )
/*++
Routine Description:
Sets thje typematic rate
Arguments:
DevicePath - Supplies pointer to path of device Request - Supplies pointer to request
Return Value:
BOOLEAN - TRUE if typematic rate set successfully, FALSE otherwise
Notes:
--*/
{ PREQUEST_DATA_CON_TYPEMATIC Data;
DebugPtrAssert( Request);
Data = (PREQUEST_DATA_CON_TYPEMATIC)&(((PCON_REQUEST)Request)->Data.Typematic);
if ( Data->SetRate ) { if (!SystemParametersInfo( SPI_SETKEYBOARDSPEED, (UINT)Data->Rate, NULL, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE )) { DisplayMessageAndExit( MODE_ERROR_INVALID_RATE, NULL, (ULONG)EXIT_ERROR); } } if ( Data->SetDelay ) { if (!SystemParametersInfo( SPI_SETKEYBOARDDELAY, (UINT)Data->Delay, NULL, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE )) { DisplayMessageAndExit( MODE_ERROR_INVALID_DELAY, NULL, (ULONG)EXIT_ERROR); } }
return TRUE; }
|