884 lines
22 KiB
C
884 lines
22 KiB
C
/*++
|
|
|
|
Copyright (c) 1993 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
fefb.c (was textmode\kernel\spvidgfb.c)
|
|
|
|
Abstract:
|
|
|
|
Text setup display support for Frame Buffer displays.
|
|
|
|
Author:
|
|
|
|
Hideyuki Nagase (hideyukn) 01-July-1994
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include <precomp.h>
|
|
#pragma hdrstop
|
|
|
|
//
|
|
// Vector for frame buffer functions.
|
|
//
|
|
|
|
VIDEO_FUNCTION_VECTOR FrameBufferKanjiVideoVector =
|
|
|
|
{
|
|
FrameBufferKanjiDisplayString,
|
|
FrameBufferKanjiClearRegion,
|
|
FrameBufferKanjiSpecificInit,
|
|
FrameBufferKanjiSpecificReInit,
|
|
FrameBufferKanjiSpecificTerminate,
|
|
FrameBufferKanjiSpecificInitPalette,
|
|
FrameBufferKanjiSpecificScrollUp
|
|
};
|
|
|
|
|
|
BOOLEAN FrameBufferKanjiInitialized = FALSE;
|
|
|
|
//
|
|
// Number of bytes that make up a row of characters.
|
|
// Equal to the screen stride (number of bytes on a scan line)
|
|
// multiplies by the height of a char in bytes; double that
|
|
// if DoubleCharHeight is TRUE.
|
|
//
|
|
ULONG KanjiCharRowDelta;
|
|
ULONG KanjiBytesPerPixel;
|
|
ULONG KanjiCharWidth;
|
|
|
|
//
|
|
// Physical font information
|
|
//
|
|
extern BOOTFONTBIN_HEADER BootFontHeader;
|
|
|
|
VOID
|
|
FrameBufferKanjiSpecificInit(
|
|
IN PVIDEO_MODE_INFORMATION VideoModes,
|
|
IN ULONG NumberOfModes,
|
|
IN ULONG ModeSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Perform frame buffer specific initialization. This includes
|
|
|
|
- setting the desired video mode.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status;
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
VIDEO_MODE VideoMode;
|
|
PVIDEO_MODE_INFORMATION mode;
|
|
|
|
if(FrameBufferKanjiInitialized) {
|
|
return;
|
|
}
|
|
|
|
mode = pFrameBufferDetermineModeToUse(VideoModes,NumberOfModes,ModeSize);
|
|
|
|
if(mode == 0) {
|
|
SpDisplayRawMessage(SP_SCRN_VIDEO_ERROR_RAW, 2, VIDEOBUG_BADMODE, 0);
|
|
while(TRUE); // loop forever
|
|
}
|
|
|
|
//
|
|
// Save away the mode info in a global.
|
|
//
|
|
VideoVariables->VideoModeInfo = *mode;
|
|
|
|
//
|
|
// Set the desired mode.
|
|
//
|
|
VideoMode.RequestedMode = VideoVariables->VideoModeInfo.ModeIndex;
|
|
|
|
Status = ZwDeviceIoControlFile(
|
|
VideoVariables->hDisplay,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&IoStatusBlock,
|
|
IOCTL_VIDEO_SET_CURRENT_MODE,
|
|
&VideoMode,
|
|
sizeof(VideoMode),
|
|
NULL,
|
|
0
|
|
);
|
|
|
|
if(!NT_SUCCESS(Status)) {
|
|
KdPrint(("SETUP: Unable to set mode %u (status = %lx)\n",VideoMode.RequestedMode,Status));
|
|
SpDisplayRawMessage(SP_SCRN_VIDEO_ERROR_RAW, 2, VIDEOBUG_SETMODE, Status);
|
|
while(TRUE); // loop forever
|
|
}
|
|
|
|
//
|
|
// Map the frame buffer.
|
|
//
|
|
pSpvidMapVideoMemory(TRUE);
|
|
|
|
FrameBufferKanjiInitialized = TRUE;
|
|
|
|
//
|
|
// Logical FontGlyph information
|
|
//
|
|
FEFontCharacterHeight = BootFontHeader.CharacterImageHeight +
|
|
BootFontHeader.CharacterTopPad +
|
|
BootFontHeader.CharacterBottomPad;
|
|
FEFontCharacterWidth = BootFontHeader.CharacterImageSbcsWidth;
|
|
|
|
//
|
|
// Determine the width of the screen. If it's double the size
|
|
// of the minimum number of characters per row (or larger)
|
|
// then we'll double the width of each character as we draw it.
|
|
//
|
|
VideoVariables->ScreenWidth = VideoVariables->VideoModeInfo.VisScreenWidth / FEFontCharacterWidth;
|
|
|
|
//
|
|
// Determine the height of the screen. If it's double the size
|
|
// of the minimum number of characters per column (or larger)
|
|
// then we'll double the height of each character as we draw it.
|
|
//
|
|
VideoVariables->ScreenHeight = VideoVariables->VideoModeInfo.VisScreenHeight / FEFontCharacterHeight;
|
|
|
|
KanjiCharRowDelta = VideoVariables->VideoModeInfo.ScreenStride * FEFontCharacterHeight;
|
|
|
|
KanjiBytesPerPixel = VideoVariables->VideoModeInfo.BitsPerPlane / 8;
|
|
|
|
if(KanjiBytesPerPixel == 3) {
|
|
KanjiBytesPerPixel = 4;
|
|
}
|
|
|
|
KdPrint(("SETUPDD:KanjiBytesPerPixel = %d\n",KanjiBytesPerPixel));
|
|
|
|
KanjiCharWidth = FEFontCharacterWidth * KanjiBytesPerPixel;
|
|
|
|
//
|
|
// Allocate the background buffer, if needed
|
|
//
|
|
VideoVariables->ActiveVideoBuffer = VideoVariables->VideoMemoryInfo.FrameBufferBase;
|
|
|
|
if (SP_IS_UPGRADE_GRAPHICS_MODE()) {
|
|
VideoVariables->VideoBufferSize = VideoVariables->VideoMemoryInfo.FrameBufferLength;
|
|
|
|
VideoVariables->VideoBuffer = SpMemAlloc(VideoVariables->VideoBufferSize);
|
|
|
|
if (VideoVariables->VideoBuffer) {
|
|
VideoVariables->ActiveVideoBuffer = VideoVariables->VideoBuffer;
|
|
} else {
|
|
VideoVariables->VideoBufferSize = 0;
|
|
SP_SET_UPGRADE_GRAPHICS_MODE(FALSE);
|
|
}
|
|
}
|
|
}
|
|
|
|
VOID
|
|
FrameBufferKanjiSpecificReInit(
|
|
VOID
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
VIDEO_MODE VideoMode;
|
|
|
|
if(!FrameBufferKanjiInitialized) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Set the desired mode.
|
|
//
|
|
VideoMode.RequestedMode = VideoVariables->VideoModeInfo.ModeIndex;
|
|
|
|
Status = ZwDeviceIoControlFile(
|
|
VideoVariables->hDisplay,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&IoStatusBlock,
|
|
IOCTL_VIDEO_SET_CURRENT_MODE,
|
|
&VideoMode,
|
|
sizeof(VideoMode),
|
|
NULL,
|
|
0
|
|
);
|
|
|
|
if(!NT_SUCCESS(Status)) {
|
|
KdPrint(("SETUP: Unable to set mode %u (status = %lx)\n",VideoMode.RequestedMode,Status));
|
|
SpDisplayRawMessage(SP_SCRN_VIDEO_ERROR_RAW, 2, VIDEOBUG_SETMODE, Status);
|
|
while(TRUE); // loop forever
|
|
}
|
|
|
|
FrameBufferKanjiSpecificInitPalette();
|
|
|
|
//
|
|
// Blast the background video information to the
|
|
// foreground
|
|
//
|
|
if (SP_IS_UPGRADE_GRAPHICS_MODE() && VideoVariables->VideoBuffer &&
|
|
VideoVariables->VideoBufferSize) {
|
|
PUCHAR Source = VideoVariables->VideoBuffer;
|
|
PUCHAR Destination = VideoVariables->VideoMemoryInfo.FrameBufferBase;
|
|
ULONG Index;
|
|
|
|
for (Index=0; Index < VideoVariables->VideoBufferSize; Index++) {
|
|
WRITE_REGISTER_UCHAR(Destination + Index, *(Source + Index));
|
|
}
|
|
|
|
SP_SET_UPGRADE_GRAPHICS_MODE(FALSE);
|
|
}
|
|
|
|
VideoVariables->ActiveVideoBuffer = VideoVariables->VideoMemoryInfo.FrameBufferBase;
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
FrameBufferKanjiSpecificInitPalette(
|
|
VOID
|
|
)
|
|
{
|
|
BOOLEAN rc;
|
|
ULONG NumEntries;
|
|
ULONG BufferSize;
|
|
PVIDEO_CLUT clut;
|
|
// NTSTATUS Status;
|
|
// IO_STATUS_BLOCK IoStatusBlock;
|
|
UCHAR i;
|
|
|
|
rc = TRUE;
|
|
|
|
//
|
|
// For non-palette-driven displays, we construct a simple palette
|
|
// for use w/ gamma correcting adapters.
|
|
//
|
|
|
|
if(!(VideoVariables->VideoModeInfo.AttributeFlags & VIDEO_MODE_PALETTE_DRIVEN)) {
|
|
|
|
switch(KanjiBytesPerPixel) {
|
|
case 1:
|
|
NumEntries = 3;
|
|
break;
|
|
case 2:
|
|
NumEntries = 32;
|
|
break;
|
|
default:
|
|
NumEntries = 255;
|
|
break;
|
|
}
|
|
|
|
BufferSize = sizeof(VIDEO_CLUT)+(sizeof(VIDEO_CLUTDATA)*NumEntries); // size is close enough
|
|
clut = SpMemAlloc(BufferSize);
|
|
|
|
clut->NumEntries = (USHORT)NumEntries;
|
|
clut->FirstEntry = 0;
|
|
|
|
for(i=0; i<NumEntries; i++) {
|
|
clut->LookupTable[i].RgbArray.Red = i;
|
|
clut->LookupTable[i].RgbArray.Green = i;
|
|
clut->LookupTable[i].RgbArray.Blue = i;
|
|
clut->LookupTable[i].RgbArray.Unused = 0;
|
|
}
|
|
|
|
// Status = ZwDeviceIoControlFile(
|
|
// hDisplay,
|
|
// NULL,
|
|
// NULL,
|
|
// NULL,
|
|
// &IoStatusBlock,
|
|
// IOCTL_VIDEO_SET_COLOR_REGISTERS,
|
|
// clut,
|
|
// BufferSize,
|
|
// NULL,
|
|
// 0
|
|
// );
|
|
|
|
SpMemFree(clut);
|
|
|
|
// if(!NT_SUCCESS(Status)) {
|
|
// KdPrint(("SETUP: Unable to set palette (status = %lx)\n",Status));
|
|
// rc = FALSE;
|
|
// }
|
|
}
|
|
|
|
return(rc);
|
|
}
|
|
|
|
|
|
VOID
|
|
FrameBufferKanjiSpecificTerminate(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Perform frame buffer specific termination. This includes
|
|
|
|
- unmapping the frame buffer from memory
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
if(FrameBufferKanjiInitialized) {
|
|
|
|
//
|
|
// Clear screen for next video mode.
|
|
//
|
|
FrameBufferKanjiClearRegion(
|
|
0,
|
|
0,
|
|
VideoVariables->ScreenWidth,
|
|
VideoVariables->ScreenHeight,
|
|
ATT_FG_BLACK|ATT_BG_BLACK
|
|
);
|
|
|
|
//
|
|
// Unmap video memory
|
|
//
|
|
pSpvidMapVideoMemory(FALSE);
|
|
|
|
if (VideoVariables->VideoBuffer && VideoVariables->VideoBufferSize) {
|
|
SpMemFree(VideoVariables->VideoBuffer);
|
|
VideoVariables->VideoBuffer = 0;
|
|
VideoVariables->VideoBufferSize = 0;
|
|
}
|
|
|
|
FrameBufferKanjiInitialized = FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
FrameBufferKanjiDisplayString(
|
|
IN PSTR String,
|
|
IN UCHAR Attribute,
|
|
IN ULONG X, // 0-based coordinates (character units)
|
|
IN ULONG Y
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Write a string of characters to the display.
|
|
|
|
Arguments:
|
|
|
|
String - supplies a 0-terminated character string in the OEM charset
|
|
to be displayed at the given position.
|
|
|
|
Attribute - supplies the attributes for characters in the string.
|
|
|
|
X,Y - specify the character-based (0-based) position of the output.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONG BgColorValue;
|
|
ULONG FgColorValue;
|
|
PUCHAR Destination;
|
|
PUCHAR CharOrigin,LineOrigin,pGlyphRow;
|
|
ULONG Length;
|
|
PUCHAR pch;
|
|
ULONG I,J,K;
|
|
ULONG CurrentColumn;
|
|
|
|
//
|
|
// Eliminate invalid coord.
|
|
//
|
|
if( X >= VideoVariables->ScreenWidth ) X = 0;
|
|
if( Y >= VideoVariables->ScreenHeight ) Y = 3;
|
|
|
|
ASSERT(FEFontCharacterWidth == 8);
|
|
|
|
//
|
|
// Calculate the bit patterns that yield the foreground and background
|
|
// attributes when poked into the frame buffer.
|
|
//
|
|
|
|
FgColorValue = VideoVariables->AttributeToColorValue[Attribute & 0x0f];
|
|
BgColorValue = VideoVariables->AttributeToColorValue[(Attribute >> 4) & 0x0f];
|
|
|
|
//
|
|
// Calculate the address of the upper left pixel of the first character
|
|
// to be displayed.
|
|
//
|
|
|
|
CharOrigin = (PUCHAR)VideoVariables->ActiveVideoBuffer
|
|
+ (Y * KanjiCharRowDelta)
|
|
+ (X * KanjiCharWidth);
|
|
|
|
//
|
|
// Set current column.
|
|
//
|
|
CurrentColumn = X;
|
|
|
|
//
|
|
// Output each character in the string.
|
|
//
|
|
|
|
for(pch=String; *pch; pch++) {
|
|
|
|
//
|
|
// Initialize line Origin
|
|
//
|
|
|
|
LineOrigin = CharOrigin;
|
|
|
|
if(DbcsFontIsDBCSLeadByte(*pch)) {
|
|
|
|
//
|
|
// This is Full Width Character ( 16 + 1 + 2 * 8 )
|
|
// | | | Height
|
|
// | | Post Leading
|
|
// | Pre Leading
|
|
// Real font image body
|
|
|
|
USHORT Word;
|
|
|
|
if((CurrentColumn+1) >= VideoVariables->ScreenWidth) {
|
|
break;
|
|
}
|
|
|
|
Word = ((*pch) << 8) | (*(pch+1));
|
|
|
|
pGlyphRow = DbcsFontGetDbcsFontChar(Word);
|
|
|
|
//
|
|
// If we can not get image, replace it with full width space.
|
|
//
|
|
|
|
if(pGlyphRow == NULL) {
|
|
pGlyphRow = DbcsFontGetDbcsFontChar(FEFontDefaultChar);
|
|
}
|
|
|
|
//
|
|
// Draw pre leading lines
|
|
//
|
|
|
|
for (I = 0; I < BootFontHeader.CharacterTopPad; I += 1 ) {
|
|
|
|
Destination = LineOrigin;
|
|
|
|
for( J = 0; J < BootFontHeader.CharacterImageDbcsWidth; J += 1 ) {
|
|
|
|
switch(KanjiBytesPerPixel) {
|
|
|
|
case 1:
|
|
*Destination++ = (UCHAR)BgColorValue;
|
|
break;
|
|
|
|
case 2:
|
|
*(PUSHORT)Destination = (USHORT)BgColorValue;
|
|
Destination += 2;
|
|
break;
|
|
|
|
case 4:
|
|
*(PULONG)Destination = (ULONG)BgColorValue;
|
|
Destination += 4;
|
|
break;
|
|
}
|
|
}
|
|
|
|
LineOrigin += VideoVariables->VideoModeInfo.ScreenStride;
|
|
}
|
|
|
|
//
|
|
// Draw font glyph body
|
|
//
|
|
|
|
for (I = 0; I < BootFontHeader.CharacterImageHeight; I += 1 ) {
|
|
|
|
Destination = LineOrigin;
|
|
|
|
for( J = 0; J < 2; J += 1 ) {
|
|
|
|
BYTE ShiftMask = 0x80;
|
|
|
|
for( K = 0; K < 8 ; K += 1 ) {
|
|
|
|
ULONG DrawValue;
|
|
|
|
if (pGlyphRow && (*pGlyphRow & ShiftMask))
|
|
DrawValue = FgColorValue;
|
|
else
|
|
DrawValue = BgColorValue;
|
|
|
|
switch(KanjiBytesPerPixel) {
|
|
|
|
case 1:
|
|
*Destination++ = (UCHAR)DrawValue;
|
|
break;
|
|
|
|
case 2:
|
|
*(PUSHORT)Destination = (USHORT)DrawValue;
|
|
Destination += 2;
|
|
break;
|
|
|
|
case 4:
|
|
*(PULONG)Destination = (ULONG)DrawValue;
|
|
Destination += 4;
|
|
break;
|
|
}
|
|
|
|
ShiftMask = ShiftMask >> 1;
|
|
}
|
|
|
|
pGlyphRow ++;
|
|
}
|
|
|
|
LineOrigin += VideoVariables->VideoModeInfo.ScreenStride;
|
|
}
|
|
|
|
//
|
|
// Draw post leading lines
|
|
//
|
|
|
|
for (I = 0; I < BootFontHeader.CharacterBottomPad; I += 1) {
|
|
|
|
Destination = LineOrigin;
|
|
|
|
for( J = 0; J < BootFontHeader.CharacterImageDbcsWidth; J += 1 ) {
|
|
|
|
switch(KanjiBytesPerPixel) {
|
|
|
|
case 1:
|
|
*Destination++ = (UCHAR)BgColorValue;
|
|
break;
|
|
|
|
case 2:
|
|
*(PUSHORT)Destination = (USHORT)BgColorValue;
|
|
Destination += 2;
|
|
break;
|
|
|
|
case 4:
|
|
*(PULONG)Destination = (ULONG)BgColorValue;
|
|
Destination += 4;
|
|
break;
|
|
}
|
|
}
|
|
|
|
LineOrigin += VideoVariables->VideoModeInfo.ScreenStride;
|
|
}
|
|
|
|
CharOrigin += (BootFontHeader.CharacterImageDbcsWidth * KanjiBytesPerPixel);
|
|
CurrentColumn += 2;
|
|
|
|
//
|
|
// Move to Next character ( skip Dbcs Trailing byte )
|
|
//
|
|
|
|
pch++;
|
|
|
|
} else if(DbcsFontIsGraphicsChar(*pch)) {
|
|
|
|
BYTE ShiftMask = 0x80;
|
|
ULONG DrawValue;
|
|
|
|
if(CurrentColumn >= VideoVariables->ScreenWidth) {
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Graphics Character special
|
|
//
|
|
|
|
pGlyphRow = DbcsFontGetGraphicsChar(*pch);
|
|
|
|
if(pGlyphRow == NULL) {
|
|
pGlyphRow = DbcsFontGetGraphicsChar(0x0);
|
|
}
|
|
|
|
for (I = 0; I < FEFontCharacterHeight; I += 1 ) {
|
|
|
|
ShiftMask = 0x80;
|
|
Destination = LineOrigin;
|
|
|
|
for( K = 0; K < 8 ; K += 1 ) {
|
|
|
|
if( *pGlyphRow & ShiftMask )
|
|
DrawValue = BgColorValue;
|
|
else
|
|
DrawValue = FgColorValue;
|
|
|
|
switch(KanjiBytesPerPixel) {
|
|
|
|
case 1:
|
|
*Destination++ = (UCHAR)DrawValue;
|
|
break;
|
|
|
|
case 2:
|
|
*(PUSHORT)Destination = (USHORT)DrawValue;
|
|
Destination += 2;
|
|
break;
|
|
|
|
case 4:
|
|
*(PULONG)Destination = (ULONG)DrawValue;
|
|
Destination += 4;
|
|
break;
|
|
}
|
|
|
|
ShiftMask = ShiftMask >> 1;
|
|
}
|
|
|
|
pGlyphRow ++;
|
|
LineOrigin += VideoVariables->VideoModeInfo.ScreenStride;
|
|
}
|
|
|
|
CharOrigin += (BootFontHeader.CharacterImageSbcsWidth * KanjiBytesPerPixel);
|
|
CurrentColumn += 1;
|
|
|
|
} else {
|
|
|
|
if(CurrentColumn >= VideoVariables->ScreenWidth) {
|
|
break;
|
|
}
|
|
|
|
pGlyphRow = DbcsFontGetSbcsFontChar(*pch);
|
|
|
|
//
|
|
// If we can not get image, replace it with half width space.
|
|
//
|
|
|
|
if(pGlyphRow == NULL) {
|
|
pGlyphRow = DbcsFontGetSbcsFontChar(0x20);
|
|
}
|
|
|
|
for (I = 0; I < BootFontHeader.CharacterTopPad; I += 1 ) {
|
|
|
|
Destination = LineOrigin;
|
|
|
|
for( J = 0; J < BootFontHeader.CharacterImageSbcsWidth; J += 1 ) {
|
|
|
|
switch(KanjiBytesPerPixel) {
|
|
|
|
case 1:
|
|
*Destination++ = (UCHAR)BgColorValue;
|
|
break;
|
|
|
|
case 2:
|
|
*(PUSHORT)Destination = (USHORT)BgColorValue;
|
|
Destination += 2;
|
|
break;
|
|
|
|
case 4:
|
|
*(PULONG)Destination = (ULONG)BgColorValue;
|
|
Destination += 4;
|
|
break;
|
|
}
|
|
}
|
|
|
|
LineOrigin += VideoVariables->VideoModeInfo.ScreenStride;
|
|
}
|
|
|
|
for (I = 0; I < BootFontHeader.CharacterImageHeight; I += 1 ) {
|
|
|
|
BYTE ShiftMask = 0x80;
|
|
|
|
Destination = LineOrigin;
|
|
|
|
for( K = 0; K < 8 ; K += 1 ) {
|
|
|
|
ULONG DrawValue;
|
|
|
|
if( *pGlyphRow & ShiftMask )
|
|
DrawValue = FgColorValue;
|
|
else
|
|
DrawValue = BgColorValue;
|
|
|
|
switch(KanjiBytesPerPixel) {
|
|
|
|
case 1:
|
|
*Destination++ = (UCHAR)DrawValue;
|
|
break;
|
|
|
|
case 2:
|
|
*(PUSHORT)Destination = (USHORT)DrawValue;
|
|
Destination += 2;
|
|
break;
|
|
|
|
case 4:
|
|
*(PULONG)Destination = (ULONG)DrawValue;
|
|
Destination += 4;
|
|
break;
|
|
}
|
|
|
|
ShiftMask = ShiftMask >> 1;
|
|
}
|
|
|
|
pGlyphRow ++;
|
|
LineOrigin += VideoVariables->VideoModeInfo.ScreenStride;
|
|
}
|
|
|
|
for (I = 0; I < BootFontHeader.CharacterBottomPad; I += 1) {
|
|
|
|
Destination = LineOrigin;
|
|
|
|
for( J = 0; J < BootFontHeader.CharacterImageSbcsWidth; J += 1 ) {
|
|
|
|
switch(KanjiBytesPerPixel) {
|
|
|
|
case 1:
|
|
*Destination++ = (UCHAR)BgColorValue;
|
|
break;
|
|
|
|
case 2:
|
|
*(PUSHORT)Destination = (USHORT)BgColorValue;
|
|
Destination += 2;
|
|
break;
|
|
|
|
case 4:
|
|
*(PULONG)Destination = (ULONG)BgColorValue;
|
|
Destination += 4;
|
|
break;
|
|
}
|
|
}
|
|
|
|
LineOrigin += VideoVariables->VideoModeInfo.ScreenStride;
|
|
}
|
|
|
|
CharOrigin += (BootFontHeader.CharacterImageSbcsWidth * KanjiBytesPerPixel);
|
|
CurrentColumn += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
FrameBufferKanjiClearRegion(
|
|
IN ULONG X,
|
|
IN ULONG Y,
|
|
IN ULONG W,
|
|
IN ULONG H,
|
|
IN UCHAR Attribute
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Clear out a screen region to a specific attribute.
|
|
|
|
Arguments:
|
|
|
|
X,Y,W,H - specify rectangle in 0-based character coordinates.
|
|
|
|
Attribute - Low nibble specifies attribute to be filled in the rectangle
|
|
(ie, the background color to be cleared to).
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
PUCHAR Destination;
|
|
ULONG Fill;
|
|
ULONG i;
|
|
ULONG FillLength;
|
|
ULONG x;
|
|
|
|
ASSERT(X+W <= VideoVariables->ScreenWidth);
|
|
ASSERT(Y+H <= VideoVariables->ScreenHeight);
|
|
|
|
if(X+W > VideoVariables->ScreenWidth) {
|
|
W = VideoVariables->ScreenWidth-X;
|
|
}
|
|
|
|
if(Y+H > VideoVariables->ScreenHeight) {
|
|
H = VideoVariables->ScreenHeight-Y;
|
|
}
|
|
|
|
Fill = VideoVariables->AttributeToColorValue[Attribute & 0x0f];
|
|
|
|
Destination = (PUCHAR)VideoVariables->ActiveVideoBuffer
|
|
+ (Y * KanjiCharRowDelta)
|
|
+ (X * KanjiCharWidth);
|
|
|
|
FillLength = W * KanjiCharWidth;
|
|
|
|
for(i=0; i<H*FEFontCharacterHeight; i++) {
|
|
|
|
switch(KanjiBytesPerPixel) {
|
|
|
|
case 1:
|
|
for(x=0; x<FillLength ; x++) {
|
|
*(PUCHAR)(Destination+(x)) = (UCHAR)Fill;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
for(x=0; x<FillLength/2; x++) {
|
|
*(PUSHORT)(Destination+(x*2)) = (USHORT)Fill;
|
|
}
|
|
break;
|
|
|
|
case 4:
|
|
for(x=0; x<FillLength/4; x++) {
|
|
*(PULONG)(Destination+(x*4)) = (ULONG)Fill;
|
|
}
|
|
break;
|
|
}
|
|
|
|
Destination += VideoVariables->VideoModeInfo.ScreenStride;
|
|
}
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
FrameBufferKanjiSpecificScrollUp(
|
|
IN ULONG TopLine,
|
|
IN ULONG BottomLine,
|
|
IN ULONG LineCount,
|
|
IN UCHAR FillAttribute
|
|
)
|
|
{
|
|
PUCHAR Source,Target;
|
|
ULONG Count;
|
|
|
|
Target = (PUCHAR)VideoVariables->ActiveVideoBuffer
|
|
+ (TopLine * KanjiCharRowDelta);
|
|
|
|
Source = Target + (LineCount * KanjiCharRowDelta);
|
|
|
|
Count = (((BottomLine - TopLine) + 1) - LineCount) * KanjiCharRowDelta;
|
|
|
|
RtlMoveMemory(Target,Source,Count);
|
|
|
|
FrameBufferKanjiClearRegion(
|
|
0,
|
|
(BottomLine - LineCount) + 1,
|
|
VideoVariables->ScreenWidth,
|
|
LineCount,
|
|
FillAttribute
|
|
);
|
|
|
|
return(TRUE);
|
|
}
|