You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
703 lines
11 KiB
703 lines
11 KiB
/*++
|
|
|
|
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++) != 0) {
|
|
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))
|
|
: ' ');
|
|
}
|
|
|
|
|
|
|