windows-nt/Source/XPSP1/NT/base/boot/efi/display.c
2020-09-26 16:20:57 +08:00

658 lines
11 KiB
C

/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
display.c
Author:
Thomas Parslow [TomP] Feb-13-1991
Reworked substantially in Tokyo 7-July-95 (tedm)
Port from ARC-BIOS to EFI 22-Nov-2000 (andrewr)
Abstract:
This file contains an interface to the screen that is independent
of the screen type actually being written to. The module serves
as a layer between OS loader applications and the EFI services
that do the actual legwork of writing to the default console
handlers.
--*/
#include "bldr.h"
#include "bootefi.h"
#include "efi.h"
#include "efip.h"
#include "flop.h"
//
// Externals
//
extern EFI_HANDLE EfiImageHandle;
extern EFI_SYSTEM_TABLE *EfiST;
extern EFI_BOOT_SERVICES *EfiBS;
extern EFI_RUNTIME_SERVICES *EfiRS;
extern EFI_GUID EfiDevicePathProtocol;
extern EFI_GUID EfiBlockIoProtocol;
extern BOOLEAN GoneVirtual;
#define ZLEN_SHORT(x) ((x < 0x10) + (x < 0x100) + (x < 0x1000))
#define ZLEN_LONG(x) ((x < 0x10) + (x < 0x100) + (x < 0x1000) + \
(x < 0x10000) + (x < 0x100000)+(x < 0x1000000)+(x < 0x10000000))
//
// Current screen position.
//
USHORT TextColumn = 0;
USHORT TextRow = 0;
//
// Current text attribute
//
UCHAR TextCurrentAttribute = 0x07; // start with white on black.
//
// Internal routines
//
VOID
puti(
LONG
);
VOID
putx(
ULONG
);
VOID
putu(
ULONG
);
VOID
putwS(
PUNICODE_STRING String
);
VOID
putS(
PCWSTR String
);
VOID
puts(
PCSTR String
);
VOID
BlPrint(
PTCHAR cp,
...
)
/*++
Routine Description:
Standard printf function with a subset of formating features supported.
Currently handles
%d, %ld - signed short, signed long
%u, %lu - unsigned short, unsigned long
%c, %s - character, string
%x, %lx - unsigned print in hex, unsigned long print in hex
%C, %S - ansi character, string
%wS - counted UNICODE_STRING
Does not do:
- field width specification
- floating point.
Arguments:
cp - pointer to the format string, text string.
Returns:
Nothing
--*/
{
ULONG l;
ULONG Count;
TCHAR ch;
ULONG DeviceId;
TCHAR b,c;
PTSTR FormatString;
va_list args;
FormatString = cp;
DeviceId = BlConsoleOutDeviceId;
va_start(args, cp);
//
// Process the arguments using the descriptor string
//
while(*FormatString != TEXT('\0')) {
b = *FormatString;
FormatString += 1;
if(b == TEXT('%')) {
c = *FormatString;
FormatString += 1;
switch (c) {
case TEXT('d'):
puti((LONG)va_arg(args, LONG));
break;
case TEXT('s'):
putS((PCWSTR)va_arg(args, PWSTR));
break;
case TEXT('S'):
puts((PCSTR)va_arg(args, PSTR));
break;
case TEXT('c'):
ch = (WCHAR)va_arg( args, WCHAR );
ArcWrite(DeviceId, &ch, 1*sizeof(WCHAR), &Count);
break;
case TEXT('C'):
ch = (CHAR)va_arg( args, CHAR );
ArcWrite(DeviceId, &ch, 1*sizeof(CHAR), &Count);
break;
case TEXT('x'):
//note that this doesn't currently support zero padding.
putx((ULONG)va_arg( args, ULONG));
break;
case TEXT('u'):
putu( (ULONG)va_arg( args, ULONG ));
break;
case TEXT('w'):
c = *FormatString;
FormatString += 1;
switch (c) {
case TEXT('S'):
case TEXT('Z'):
putwS((PUNICODE_STRING)va_arg( args, PUNICODE_STRING));
break;
}
break;
case TEXT('l'):
c = *FormatString;
FormatString += 1;
switch(c) {
case TEXT('0'):
break;
case TEXT('u'):
putu(va_arg( args, ULONG));
break;
case TEXT('x'):
//note that this doesn't currently support zero padding
putx(va_arg( args, ULONG));
break;
case TEXT('d'):
puti(va_arg( args, ULONG));
break;
}
break;
default :
ch = (TCHAR)b;
ArcWrite(DeviceId, &ch, 1*sizeof(TCHAR), &Count);
ch = (TCHAR)c;
ArcWrite(DeviceId, &ch, 1*sizeof(TCHAR), &Count);
}
} else {
ArcWrite(DeviceId, FormatString - 1, 1*sizeof(TCHAR), &Count);
}
}
va_end(args);
#if 0
//
// This code pauses the system after each BlPrint. You must enter
// a character to continue. This is used for debugging
//
ArcRead(BlConsoleInDeviceId, &l, 1, &Count);
#endif
}
VOID
putwS(
PUNICODE_STRING String
)
/*++
Routine Description:
Writes counted unicode string to the display at the current
cursor position.
Arguments:
String - pointer to unicode string to display
Returns:
Nothing
--*/
{
ULONG i;
ULONG Count;
for(i=0; i < String->Length; i++) {
ArcWrite(BlConsoleOutDeviceId, &String->Buffer[i], 1*sizeof(WCHAR), &Count);
}
}
VOID
puts(
PCSTR AnsiString
)
/*++
Routine Description:
Writes an ANSI string to the display at the current cursor position.
Arguments:
String - pointer to ANSI string to display
Returns:
Nothing
--*/
{
ULONG i;
ULONG Count;
WCHAR Char;
PCSTR p;
p = AnsiString;
while (*p != '\0') {
Char = (WCHAR)*p;
ArcWrite(BlConsoleOutDeviceId, &Char, sizeof(WCHAR), &Count);
p += 1;
}
}
VOID
putS(
PCWSTR UnicodeString
)
/*++
Routine Description:
Writes an ANSI string to the display at the current cursor position.
Arguments:
String - pointer to ANSI string to display
Returns:
Nothing
--*/
{
ULONG i;
ULONG Count;
WCHAR Char;
PCWSTR p;
p = UnicodeString;
while (*p != L'\0') {
Char = *p;
ArcWrite(BlConsoleOutDeviceId, &Char, sizeof(WCHAR), &Count);
p += 1;
}
}
VOID
putx(
ULONG x
)
/*++
Routine Description:
Writes hex long to the display at the current cursor position.
Arguments:
x - ulong to write
Returns:
Nothing
--*/
{
ULONG j;
ULONG Count;
_TUCHAR ch;
if(x/16) {
putx(x/16);
}
if((j=x%16) > 9) {
ch = (_TUCHAR)(j+TEXT('A')-10);
ArcWrite(BlConsoleOutDeviceId, &ch, 1*sizeof(_TUCHAR), &Count);
} else {
ch = (_TUCHAR)(j+TEXT('0'));
ArcWrite(BlConsoleOutDeviceId, &ch, 1*sizeof(_TUCHAR), &Count);
}
}
VOID
puti(
LONG i
)
/*++
Routine Description:
Writes a long integer on the display at the current cursor position.
Arguments:
i - the integer to write to the display.
Returns:
Nothing
--*/
{
ULONG Count;
_TUCHAR ch;
if(i<0) {
i = -i;
ch = TEXT('-');
ArcWrite(BlConsoleOutDeviceId, &ch, 1*sizeof(_TUCHAR), &Count);
}
if(i/10) {
puti(i/10);
}
ch = (_TUCHAR)((i%10)+TEXT('0'));
ArcWrite(BlConsoleOutDeviceId, &ch, 1*sizeof(_TUCHAR), &Count);
}
VOID
putu(
ULONG u
)
/*++
Routine Description:
Write an unsigned long to display
Arguments:
u - unsigned
Returns:
Nothing
--*/
{
ULONG Count;
_TUCHAR ch;
if(u/10) {
putu(u/10);
}
ch = (_TUCHAR)((u%10)+TEXT('0'));
ArcWrite(BlConsoleOutDeviceId, &ch, 1*sizeof(_TUCHAR), &Count);
}
#if 0
VOID
pTextCharOut(
IN UCHAR c
)
{
if(DbcsLangId) {
//
// Single-byte only
//
TextGrCharOut(&c);
} else {
TextTmCharOut(&c);
}
}
#endif
VOID
TextCharOut(
IN PWCHAR pc
)
{
WCHAR Text[2];
Text[0] = *pc;
Text[1] = L'\0';
if (GoneVirtual) {
FlipToPhysical();
}
EfiST->ConOut->OutputString(EfiST->ConOut,Text);
if (GoneVirtual) {
FlipToVirtual();
}
#if 0
if(DbcsLangId) {
return(TextGrCharOut(pc));
} else {
return(TextTmCharOut(pc));
}
#endif
}
VOID
TextStringOut(
IN PWCHAR String
)
{
PWCHAR p = String;
while (*p) {
TextCharOut(p);
p += 1;
}
#if 0
if(DbcsLangId) {
TextGrStringOut(String);
} else {
TextTmStringOut(String);
}
#endif
}
VOID
TextSetCurrentAttribute(
IN UCHAR Attribute
)
/*++
Routine Description:
Sets the character attribute to be used for subsequent text display.
Arguments:
Returns:
Nothing.
--*/
{
TextCurrentAttribute = Attribute;
#ifdef EFI
BlEfiSetAttribute( Attribute );
#else
if(DbcsLangId) {
TextGrSetCurrentAttribute(Attribute);
} else {
TextTmSetCurrentAttribute(Attribute);
}
#endif
}
UCHAR
TextGetCurrentAttribute(
VOID
)
{
return(TextCurrentAttribute);
}
VOID
TextFillAttribute(
IN UCHAR Attribute,
IN ULONG Length
)
/*++
Routine Description:
Changes the screen attribute starting at the current cursor position.
The cursor is not moved.
Arguments:
Attribute - Supplies the new attribute
Length - Supplies the length of the area to change (in bytes)
Return Value:
None.
--*/
{
#ifdef EFI
ULONG x,y, OrigX, OrigY;
BOOLEAN FirstTime = TRUE;
BlEfiGetCursorPosition( &OrigX, &OrigY );
x = OrigX;
y = OrigY;
for (y = OrigY; y < BlEfiGetLinesPerRow() ; y++) {
x = FirstTime
? OrigX
: 0 ;
FirstTime = FALSE;
for (; x <= BlEfiGetColumnsPerLine(); x++) {
BlEfiPositionCursor( y, x );
BlEfiSetAttribute( Attribute );
}
}
BlEfiPositionCursor( OrigY, OrigX );
#else
if(DbcsLangId) {
TextGrFillAttribute(Attribute,Length);
} else {
TextTmFillAttribute(Attribute,Length);
}
#endif
}
_TUCHAR
TextGetGraphicsCharacter(
IN GraphicsChar WhichOne
)
{
#ifdef EFI
return(BlEfiGetGraphicsChar( WhichOne ));
#else
return((WhichOne < GraphicsCharMax)
? (DbcsLangId
? TextGrGetGraphicsChar(WhichOne)
: TextTmGetGraphicsChar(WhichOne))
: TEXT(' '));
#endif
}