703 lines
10 KiB
C
703 lines
10 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)
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This file contains an interface to the screen that is independent
|
|||
|
of the screen type actually being written to. It is layered on top
|
|||
|
of modules pecific to vga text mode and vga graphics mode.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
|
|||
|
#include "bootx86.h"
|
|||
|
#include "displayp.h"
|
|||
|
|
|||
|
|
|||
|
#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
|
|||
|
pTextCharOut(
|
|||
|
IN UCHAR c
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
putwS(
|
|||
|
PUNICODE_STRING String
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
BlPrint(
|
|||
|
PCHAR 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
|
|||
|
|
|||
|
Does not do:
|
|||
|
|
|||
|
- field width specification
|
|||
|
- floating point.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
cp - pointer to the format string, text string.
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
Nothing
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
USHORT b,c,w,len;
|
|||
|
PUCHAR ap;
|
|||
|
ULONG l;
|
|||
|
ULONG Count;
|
|||
|
CHAR ch;
|
|||
|
ULONG DeviceId;
|
|||
|
|
|||
|
|
|||
|
if (BlConsoleOutDeviceId == 0) {
|
|||
|
DeviceId = 1;
|
|||
|
} else {
|
|||
|
DeviceId = BlConsoleOutDeviceId;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Cast a pointer to the first word on the stack
|
|||
|
//
|
|||
|
ap = (PUCHAR)&cp + sizeof(PCHAR);
|
|||
|
|
|||
|
//
|
|||
|
// Process the arguments using the descriptor string
|
|||
|
//
|
|||
|
while(b = *cp++) {
|
|||
|
if(b == '%') {
|
|||
|
|
|||
|
c = *cp++;
|
|||
|
|
|||
|
switch (c) {
|
|||
|
|
|||
|
case 'd':
|
|||
|
puti((long)*((int *)ap));
|
|||
|
ap += sizeof(int);
|
|||
|
break;
|
|||
|
|
|||
|
case 's':
|
|||
|
ArcWrite(DeviceId, *((PCHAR *)ap), strlen(*((PCHAR *)ap)), &Count);
|
|||
|
ap += sizeof(char *);
|
|||
|
break;
|
|||
|
|
|||
|
case 'c':
|
|||
|
//
|
|||
|
// Does not handle dbcs chars
|
|||
|
//
|
|||
|
ArcWrite(DeviceId, ((char *)ap), 1, &Count);
|
|||
|
ap += sizeof(int);
|
|||
|
break;
|
|||
|
|
|||
|
case 'x':
|
|||
|
w = *((USHORT *)ap);
|
|||
|
len = (USHORT)ZLEN_SHORT(w);
|
|||
|
ch = '0';
|
|||
|
while (len--) {
|
|||
|
ArcWrite(DeviceId, &ch, 1, &Count);
|
|||
|
}
|
|||
|
putx((ULONG)*((USHORT *)ap));
|
|||
|
ap += sizeof(int);
|
|||
|
break;
|
|||
|
|
|||
|
case 'u':
|
|||
|
putu((ULONG)*((USHORT *)ap));
|
|||
|
ap += sizeof(int);
|
|||
|
break;
|
|||
|
|
|||
|
case 'w':
|
|||
|
c = *cp++;
|
|||
|
switch (c) {
|
|||
|
case 'S':
|
|||
|
case 'Z':
|
|||
|
putwS(*((PUNICODE_STRING *)ap));
|
|||
|
ap += sizeof(PUNICODE_STRING);
|
|||
|
break;
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case 'l':
|
|||
|
c = *cp++;
|
|||
|
|
|||
|
switch(c) {
|
|||
|
|
|||
|
case '0':
|
|||
|
break;
|
|||
|
|
|||
|
case 'u':
|
|||
|
putu(*((ULONG *)ap));
|
|||
|
ap += sizeof(long);
|
|||
|
break;
|
|||
|
|
|||
|
case 'x':
|
|||
|
l = *((ULONG *)ap);
|
|||
|
len = (USHORT)ZLEN_LONG(l);
|
|||
|
ch = '0';
|
|||
|
while (len--) {
|
|||
|
ArcWrite(DeviceId, &ch, 1, &Count);
|
|||
|
}
|
|||
|
putx(*((ULONG *)ap));
|
|||
|
ap += sizeof(long);
|
|||
|
break;
|
|||
|
|
|||
|
case 'd':
|
|||
|
puti(*((ULONG *)ap));
|
|||
|
ap += sizeof(long);
|
|||
|
break;
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
default :
|
|||
|
ch = (char)b;
|
|||
|
ArcWrite(DeviceId, &ch, 1, &Count);
|
|||
|
ch = (char)c;
|
|||
|
ArcWrite(DeviceId, &ch, 1, &Count);
|
|||
|
}
|
|||
|
} else {
|
|||
|
|
|||
|
if (DbcsLangId && GrIsDBCSLeadByte(*(cp - 1))) {
|
|||
|
//
|
|||
|
// A double-byte char.
|
|||
|
//
|
|||
|
ArcWrite(DeviceId, cp - 1, 2, &Count);
|
|||
|
cp++;
|
|||
|
} else {
|
|||
|
ArcWrite(DeviceId, cp - 1, 1, &Count);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
putwS(
|
|||
|
PUNICODE_STRING String
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Writes unicode string to the display at the current cursor position.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
String - pointer to unicode string to display
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
Nothing
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
ULONG i;
|
|||
|
ULONG Count;
|
|||
|
UCHAR ch;
|
|||
|
|
|||
|
for(i=0; i < String->Length/sizeof(WCHAR); i++) {
|
|||
|
ch = (UCHAR)String->Buffer[i];
|
|||
|
ArcWrite(BlConsoleOutDeviceId, &ch, 1, &Count);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
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;
|
|||
|
UCHAR ch;
|
|||
|
|
|||
|
if(x/16) {
|
|||
|
putx(x/16);
|
|||
|
}
|
|||
|
|
|||
|
if((j=x%16) > 9) {
|
|||
|
ch = (UCHAR)(j+'A'-10);
|
|||
|
ArcWrite(BlConsoleOutDeviceId, &ch, 1, &Count);
|
|||
|
} else {
|
|||
|
ch = (UCHAR)(j+'0');
|
|||
|
ArcWrite(BlConsoleOutDeviceId, &ch, 1, &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;
|
|||
|
UCHAR ch;
|
|||
|
|
|||
|
if(i<0) {
|
|||
|
i = -i;
|
|||
|
ch = '-';
|
|||
|
ArcWrite(BlConsoleOutDeviceId, &ch, 1, &Count);
|
|||
|
}
|
|||
|
|
|||
|
if(i/10) {
|
|||
|
puti(i/10);
|
|||
|
}
|
|||
|
|
|||
|
ch = (UCHAR)((i%10)+'0');
|
|||
|
ArcWrite(BlConsoleOutDeviceId, &ch, 1, &Count);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
putu(
|
|||
|
ULONG u
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Write an unsigned long to display
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
u - unsigned
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
Nothing
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
ULONG Count;
|
|||
|
UCHAR ch;
|
|||
|
|
|||
|
if(u/10) {
|
|||
|
putu(u/10);
|
|||
|
}
|
|||
|
|
|||
|
ch = (UCHAR)((u%10)+'0');
|
|||
|
ArcWrite(BlConsoleOutDeviceId, &ch, 1, &Count);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
pTextCharOut(
|
|||
|
IN UCHAR c
|
|||
|
)
|
|||
|
{
|
|||
|
if(DbcsLangId) {
|
|||
|
//
|
|||
|
// Single-byte only
|
|||
|
//
|
|||
|
TextGrCharOut(&c);
|
|||
|
} else {
|
|||
|
TextTmCharOut(&c);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
PUCHAR
|
|||
|
TextCharOut(
|
|||
|
IN PUCHAR pc
|
|||
|
)
|
|||
|
{
|
|||
|
if(DbcsLangId) {
|
|||
|
return(TextGrCharOut(pc));
|
|||
|
} else {
|
|||
|
return(TextTmCharOut(pc));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
TextStringOut(
|
|||
|
IN PUCHAR String
|
|||
|
)
|
|||
|
{
|
|||
|
if(DbcsLangId) {
|
|||
|
TextGrStringOut(String);
|
|||
|
} else {
|
|||
|
TextTmStringOut(String);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
TextClearToEndOfLine(
|
|||
|
VOID
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Clears from the current cursor position to the end of the line
|
|||
|
by writing blanks with the current video attribute.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
Nothing
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
if(DbcsLangId) {
|
|||
|
TextGrClearToEndOfLine();
|
|||
|
} else {
|
|||
|
TextTmClearToEndOfLine();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
TextClearFromStartOfLine(
|
|||
|
VOID
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Clears from the start of the line to the current cursor position
|
|||
|
by writing blanks with the current video attribute.
|
|||
|
The cursor position is not changed.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
Nothing
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
if(DbcsLangId) {
|
|||
|
TextGrClearFromStartOfLine();
|
|||
|
} else {
|
|||
|
TextTmClearFromStartOfLine();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
TextClearToEndOfDisplay(
|
|||
|
VOID
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Clears from the current cursor position to the end of the video
|
|||
|
display by writing blanks with the current video attribute.
|
|||
|
The cursor position is not changed.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
Nothing
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
if(DbcsLangId) {
|
|||
|
TextGrClearToEndOfDisplay();
|
|||
|
} else {
|
|||
|
TextTmClearToEndOfDisplay();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
TextClearDisplay(
|
|||
|
VOID
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Clears the video display and positions the cursor
|
|||
|
at the upper left corner of the screen (0,0).
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
Nothing
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
if(DbcsLangId) {
|
|||
|
TextGrClearDisplay();
|
|||
|
} else {
|
|||
|
TextTmClearDisplay();
|
|||
|
}
|
|||
|
TextSetCursorPosition(0,0);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
TextSetCursorPosition(
|
|||
|
IN ULONG X,
|
|||
|
IN ULONG Y
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Moves the location of the software cursor to the specified X,Y position
|
|||
|
on screen.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
X - Supplies the X-position of the cursor
|
|||
|
|
|||
|
Y - Supplies the Y-position of the cursor
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
TextColumn = (USHORT)X;
|
|||
|
TextRow = (USHORT)Y;
|
|||
|
|
|||
|
if(DbcsLangId) {
|
|||
|
TextGrPositionCursor((USHORT)Y,(USHORT)X);
|
|||
|
} else {
|
|||
|
TextTmPositionCursor((USHORT)Y,(USHORT)X);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
TextGetCursorPosition(
|
|||
|
OUT PULONG X,
|
|||
|
OUT PULONG Y
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Gets the position of the soft cursor.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
X - Receives column coordinate of where character would be written.
|
|||
|
|
|||
|
Y - Receives row coordinate of where next character would be written.
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
Nothing.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
*X = (ULONG)TextColumn;
|
|||
|
*Y = (ULONG)TextRow;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
TextSetCurrentAttribute(
|
|||
|
IN UCHAR Attribute
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Sets the character attribute to be used for subsequent text display.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
Nothing.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
TextCurrentAttribute = Attribute;
|
|||
|
|
|||
|
if(DbcsLangId) {
|
|||
|
TextGrSetCurrentAttribute(Attribute);
|
|||
|
} else {
|
|||
|
TextTmSetCurrentAttribute(Attribute);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
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.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
if(DbcsLangId) {
|
|||
|
TextGrFillAttribute(Attribute,Length);
|
|||
|
} else {
|
|||
|
TextTmFillAttribute(Attribute,Length);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
UCHAR
|
|||
|
TextGetGraphicsCharacter(
|
|||
|
IN GraphicsChar WhichOne
|
|||
|
)
|
|||
|
{
|
|||
|
return((WhichOne < GraphicsCharMax)
|
|||
|
? (DbcsLangId ? TextGrGetGraphicsChar(WhichOne) : TextTmGetGraphicsChar(WhichOne))
|
|||
|
: ' ');
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|