consplittergraphics.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,563 行 · 第 1/4 页
C
1,563 行
/*++
Copyright (c) 2004 - 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
ConSplitterGraphics.c
Abstract:
Support for ConsoleControl protocol. Support for Graphics output spliter.
Support for DevNull Console Out. This console uses memory buffers
to represnt the console. It allows a console to start very early and
when a new console is added it is synced up with the current console
--*/
#include "ConSplitter.h"
#include EFI_PROTOCOL_DEFINITION (Hii)
static CHAR16 mCrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL };
EFI_STATUS
EFIAPI
ConSpliterConsoleControlGetMode (
IN EFI_CONSOLE_CONTROL_PROTOCOL *This,
OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode,
OUT BOOLEAN *GopExists,
OUT BOOLEAN *StdInLocked
)
/*++
Routine Description:
Return the current video mode information. Also returns info about existence
of Graphics Output devices or UGA Draw devices in system, and if the Std In device is locked. All the
arguments are optional and only returned if a non NULL pointer is passed in.
Arguments:
This - Protocol instance pointer.
Mode - Are we in text of grahics mode.
GopExists - TRUE if GOP Spliter has found a GOP/UGA device
StdInLocked - TRUE if StdIn device is keyboard locked
Returns:
EFI_SUCCESS - Mode information returned.
EFI_INVALID_PARAMETER - Invalid parameters.
--*/
{
TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;
UINTN Index;
Private = CONSOLE_CONTROL_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
if (Mode == NULL) {
return EFI_INVALID_PARAMETER;
}
*Mode = Private->ConsoleOutputMode;
if (GopExists != NULL) {
*GopExists = FALSE;
for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
if ((Private->TextOutList[Index].GraphicsOutput != NULL) || (Private->TextOutList[Index].UgaDraw != NULL)) {
*GopExists = TRUE;
break;
}
}
}
if (StdInLocked != NULL) {
*StdInLocked = ConSpliterConssoleControlStdInLocked ();
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
ConSpliterConsoleControlSetMode (
IN EFI_CONSOLE_CONTROL_PROTOCOL *This,
IN EFI_CONSOLE_CONTROL_SCREEN_MODE Mode
)
/*++
Routine Description:
Set the current mode to either text or graphics. Graphics is
for Quiet Boot.
Arguments:
This - Protocol instance pointer.
Mode - Mode to set the
Returns:
EFI_SUCCESS - Mode information returned.
EFI_INVALID_PARAMETER - Invalid parameter.
EFI_UNSUPPORTED - Operation unsupported.
--*/
{
TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;
UINTN Index;
TEXT_OUT_AND_GOP_DATA *TextAndGop;
BOOLEAN Supported;
Private = CONSOLE_CONTROL_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
if (Mode >= EfiConsoleControlScreenMaxValue) {
return EFI_INVALID_PARAMETER;
}
Supported = FALSE;
TextAndGop = &Private->TextOutList[0];
for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++, TextAndGop++) {
if ((TextAndGop->GraphicsOutput != NULL) || (TextAndGop->UgaDraw != NULL)) {
Supported = TRUE;
break;
}
}
if ((!Supported) && (Mode == EfiConsoleControlScreenGraphics)) {
return EFI_UNSUPPORTED;
}
Private->ConsoleOutputMode = Mode;
TextAndGop = &Private->TextOutList[0];
for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++, TextAndGop++) {
TextAndGop->TextOutEnabled = TRUE;
//
// If we are going into Graphics mode disable ConOut to any GOP/UGA device
//
if ((Mode == EfiConsoleControlScreenGraphics) &&((TextAndGop->GraphicsOutput != NULL) || (TextAndGop->UgaDraw != NULL))) {
TextAndGop->TextOutEnabled = FALSE;
#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
DevNullGopSync (Private, TextAndGop->GraphicsOutput, TextAndGop->UgaDraw);
#else
DevNullUgaSync (Private, TextAndGop->UgaDraw);
#endif
}
}
if (Mode == EfiConsoleControlScreenText) {
DevNullSyncGopStdOut (Private);
}
return EFI_SUCCESS;
}
#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
EFI_STATUS
EFIAPI
ConSpliterGraphicsOutputQueryMode (
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN UINT32 ModeNumber,
OUT UINTN *SizeOfInfo,
OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
)
/*++
Routine Description:
Return the current video mode information.
Arguments:
This - Protocol instance pointer.
ModeNumber - The mode number to return information on.
Info - Caller allocated buffer that returns information about ModeNumber.
SizeOfInfo - A pointer to the size, in bytes, of the Info buffer.
Returns:
EFI_SUCCESS - Mode information returned.
EFI_BUFFER_TOO_SMALL - The Info buffer was too small.
EFI_DEVICE_ERROR - A hardware error occurred trying to retrieve the video mode.
EFI_NOT_STARTED - Video display is not initialized. Call SetMode ()
EFI_INVALID_PARAMETER - One of the input args was NULL.
--*/
{
TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;
EFI_STATUS Status;
TEXT_OUT_GOP_MODE *Mode;
if (This == NULL || Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) {
return EFI_INVALID_PARAMETER;
}
//
// retrieve private data
//
Private = GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
if (Private->HardwareNeedsStarting) {
return EFI_NOT_STARTED;
}
Status = gBS->AllocatePool (
EfiBootServicesData,
sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),
Info
);
if (EFI_ERROR (Status)) {
return Status;
}
*SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
EfiCopyMem (*Info, Private->GraphicsOutput.Mode->Info, *SizeOfInfo);
Mode = &Private->GraphicsOutputModeBuffer[ModeNumber];
(*Info)->HorizontalResolution = Mode->HorizontalResolution;
(*Info)->VerticalResolution = Mode->VerticalResolution;
(*Info)->PixelsPerScanLine = Mode->HorizontalResolution;
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
ConSpliterGraphicsOutputSetMode (
IN EFI_GRAPHICS_OUTPUT_PROTOCOL * This,
IN UINT32 ModeNumber
)
/*++
Routine Description:
Graphics output protocol interface to set video mode
Arguments:
This - Protocol instance pointer.
ModeNumber - The mode number to be set.
Returns:
EFI_SUCCESS - Graphics mode was changed.
EFI_DEVICE_ERROR - The device had an error and could not complete the request.
EFI_UNSUPPORTED - ModeNumber is not supported by this device.
--*/
{
EFI_STATUS Status;
TEXT_OUT_SPLITTER_PRIVATE_DATA *Private;
UINTN Index;
EFI_STATUS ReturnStatus;
TEXT_OUT_GOP_MODE *Mode;
UINTN Size;
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
UINTN NumberIndex;
UINTN SizeOfInfo;
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
EFI_UGA_DRAW_PROTOCOL *UgaDraw;
if (ModeNumber >= This->Mode->MaxMode) {
return EFI_UNSUPPORTED;
}
if (ModeNumber == This->Mode->Mode) {
return EFI_SUCCESS;
}
Private = GRAPHICS_OUTPUT_SPLITTER_PRIVATE_DATA_FROM_THIS (This);
//
// GopDevNullSetMode ()
//
ReturnStatus = EFI_SUCCESS;
//
// Free the old version
//
if (Private->GraphicsOutputBlt != NULL) {
gBS->FreePool (Private->GraphicsOutputBlt);
}
//
// Allocate the virtual Blt buffer
//
Mode = &Private->GraphicsOutputModeBuffer[ModeNumber];
Size = Mode->HorizontalResolution * Mode->VerticalResolution * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
Private->GraphicsOutputBlt = EfiLibAllocateZeroPool (Size);
if (Private->GraphicsOutputBlt == NULL) {
return EFI_OUT_OF_RESOURCES;
}
if (!Private->HardwareNeedsStarting) {
if (Private->ConsoleOutputMode != EfiConsoleControlScreenGraphics) {
return EFI_UNSUPPORTED;
}
}
//
// return the worst status met
//
for (Index = 0; Index < Private->CurrentNumberOfConsoles; Index++) {
GraphicsOutput = Private->TextOutList[Index].GraphicsOutput;
if (GraphicsOutput != NULL) {
//
// Find corresponding ModeNumber of this GraphicsOutput instance
//
for (NumberIndex = 0; NumberIndex < GraphicsOutput->Mode->MaxMode; NumberIndex ++) {
Status = GraphicsOutput->QueryMode (GraphicsOutput, (UINT32) NumberIndex, &SizeOfInfo, &Info);
if (EFI_ERROR (Status)) {
return Status;
}
if ((Info->HorizontalResolution == Mode->HorizontalResolution) && (Info->VerticalResolution == Mode->VerticalResolution)) {
gBS->FreePool (Info);
break;
}
gBS->FreePool (Info);
}
Status = GraphicsOutput->SetMode (GraphicsOutput, (UINT32) NumberIndex);
if (EFI_ERROR (Status)) {
ReturnStatus = Status;
}
}
UgaDraw = Private->TextOutList[Index].UgaDraw;
if (UgaDraw != NULL) {
Status = UgaDraw->SetMode (
UgaDraw,
Mode->HorizontalResolution,
Mode->VerticalResolution,
32,
60
);
if (EFI_ERROR (Status)) {
ReturnStatus = Status;
}
}
}
This->Mode->Mode = ModeNumber;
Info = This->Mode->Info;
Info->HorizontalResolution = Mode->HorizontalResolution;
Info->VerticalResolution = Mode->VerticalResolution;
Info->PixelsPerScanLine = Mode->HorizontalResolution;
//
// Information is not enough here, so the following items remain unchanged:
// GraphicsOutputMode->Info->Version, GraphicsOutputMode->Info->PixelFormat
// GraphicsOutputMode->SizeOfInfo, GraphicsOutputMode->FrameBufferBase, GraphicsOutputMode->FrameBufferSize
// These items will be initialized/updated when a new GOP device is added into ConsoleSplitter.
//
Private->HardwareNeedsStarting = FALSE;
return ReturnStatus;
}
EFI_STATUS
DevNullGraphicsOutputBlt (
IN TEXT_OUT_SPLITTER_PRIVATE_DATA *Private,
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
IN UINTN SourceX,
IN UINTN SourceY,
IN UINTN DestinationX,
IN UINTN DestinationY,
IN UINTN Width,
IN UINTN Height,
IN UINTN Delta OPTIONAL
)
{
UINTN SrcY;
UINTN Index;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltPtr;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ScreenPtr;
UINTN HorizontalResolution;
UINTN VerticalResolution;
if ((BltOperation < EfiBltVideoFill) || (BltOperation >= EfiGraphicsOutputBltOperationMax)) {
return EFI_INVALID_PARAMETER;
}
if (Width == 0 || Height == 0) {
return EFI_INVALID_PARAMETER;
}
if (Delta == 0) {
Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
}
HorizontalResolution = Private->GraphicsOutput.Mode->Info->HorizontalResolution;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?