- Bootvid rewrite by Filip Navara (with some fixes by myself)

- HAL DMA enhancements by Filip Navara.
- CSRSS Console enhancements by Filip Navara.
- Win32k Primitive Queue/Input/Painting/Focus enhancements by Filip Navara.
- Other misc win32k/CSR bug fixes by Filip Navara.
- The new bootvid code has some bugs, but try out a GUI Boot!

svn path=/trunk/; revision=24464
This commit is contained in:
Alex Ionescu 2006-10-09 04:00:34 +00:00
parent 3012ee8072
commit 6951a4887c
42 changed files with 1886 additions and 1963 deletions

View file

@ -140,21 +140,21 @@ CreateCommonFreeLoaderSections(PINICACHE IniCache)
NULL,
INSERT_LAST,
L"MenuTextColor",
L"White");
L"Gray");
/* MenuColor=Blue */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"MenuColor",
L"Blue");
L"Black");
/* TextColor=Yellow */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"TextColor",
L"Yellow");
L"Gray");
/* SelectedTextColor=Black */
IniCacheInsertKey(IniSection,
@ -169,6 +169,41 @@ CreateCommonFreeLoaderSections(PINICACHE IniCache)
INSERT_LAST,
L"SelectedColor",
L"Gray");
/* SelectedColor=Gray */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"ShowTime",
L"No");
/* SelectedColor=Gray */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"MenuBox",
L"No");
/* SelectedColor=Gray */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"CenterMenu",
L"No");
/* SelectedColor=Gray */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"MinimalUI",
L"Yes");
/* SelectedColor=Gray */
IniCacheInsertKey(IniSection,
NULL,
INSERT_LAST,
L"TimeText",
L"Seconds until highlighted choice will be started automatically: ");
}

View file

@ -16,6 +16,7 @@ Signature = "$ReactOS$"
atapi.sys = 3
buslogic.sys = 3
blue.sys = 3
bootvid.sys = 3
c_437.nls = 2
c_1252.nls = 2
cdfs.sys = 3

View file

@ -18,6 +18,7 @@ typedef struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES;
#include <wincon.h>
#include <blue/ntddblue.h>
#include <ndk/inbvfuncs.h>
#define NDEBUG
#include <debug.h>
@ -52,6 +53,18 @@ HalQueryDisplayOwnership(
#define TAB_WIDTH 8
#define MISC (PUCHAR)0x3c2
#define SEQ (PUCHAR)0x3c4
#define SEQDATA (PUCHAR)0x3c5
#define CRTC (PUCHAR)0x3d4
#define CRTCDATA (PUCHAR)0x3d5
#define GRAPHICS (PUCHAR)0x3ce
#define GRAPHICSDATA (PUCHAR)0x3cf
#define ATTRIB (PUCHAR)0x3c0
#define STATUS (PUCHAR)0x3da
#define PELMASK (PUCHAR)0x3c6
#define PELINDEX (PUCHAR)0x3c8
#define PELDATA (PUCHAR)0x3c9
/* NOTES ******************************************************************/
/*
@ -73,26 +86,130 @@ typedef struct _DEVICE_EXTENSION
USHORT Columns; /* Number of columns */
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
typedef struct _VGA_REGISTERS
{
UCHAR CRT[24];
UCHAR Attribute[21];
UCHAR Graphics[9];
UCHAR Sequencer[5];
UCHAR Misc;
} VGA_REGISTERS, *PVGA_REGISTERS;
static const VGA_REGISTERS VidpMode3Regs =
{
/* CRT Controller Registers */
{0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F, 0x00, 0x47, 0x1E, 0x00,
0x00, 0x00, 0x05, 0xF0, 0x9C, 0x8E, 0x8F, 0x28, 0x1F, 0x96, 0xB9, 0xA3},
/* Attribute Controller Registers */
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B,
0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x00, 0x0F, 0x08, 0x00},
/* Graphics Controller Registers */
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x00, 0xFF},
/* Sequencer Registers */
{0x03, 0x00, 0x03, 0x00, 0x02},
/* Misc Output Register */
0xE3
};
static const UCHAR DefaultPalette[] =
{
0, 0, 0,
0, 0, 0xC0,
0, 0xC0, 0,
0, 0xC0, 0xC0,
0xC0, 0, 0,
0xC0, 0, 0xC0,
0xC0, 0xC0, 0,
0xC0, 0xC0, 0xC0,
0x80, 0x80, 0x80,
0, 0, 0xFF,
0, 0xFF, 0,
0, 0xFF, 0xFF,
0xFF, 0, 0,
0xFF, 0, 0xFF,
0xFF, 0xFF, 0,
0xFF, 0xFF, 0xFF
};
/* FUNCTIONS **************************************************************/
NTSTATUS STDCALL
DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
static NTSTATUS STDCALL
ScrCreate(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
static VOID FASTCALL
ScrSetRegisters(const VGA_REGISTERS *Registers)
{
UINT i;
/* Update misc output register */
WRITE_PORT_UCHAR(MISC, Registers->Misc);
/* Synchronous reset on */
WRITE_PORT_UCHAR(SEQ, 0x00);
WRITE_PORT_UCHAR(SEQDATA, 0x01);
/* Write sequencer registers */
for (i = 1; i < sizeof(Registers->Sequencer); i++)
{
WRITE_PORT_UCHAR(SEQ, i);
WRITE_PORT_UCHAR(SEQDATA, Registers->Sequencer[i]);
}
/* Synchronous reset off */
WRITE_PORT_UCHAR(SEQ, 0x00);
WRITE_PORT_UCHAR(SEQDATA, 0x03);
/* Deprotect CRT registers 0-7 */
WRITE_PORT_UCHAR(CRTC, 0x11);
WRITE_PORT_UCHAR(CRTCDATA, Registers->CRT[0x11] & 0x7f);
/* Write CRT registers */
for (i = 0; i < sizeof(Registers->CRT); i++)
{
WRITE_PORT_UCHAR(CRTC, i);
WRITE_PORT_UCHAR(CRTCDATA, Registers->CRT[i]);
}
/* Write graphics controller registers */
for (i = 0; i < sizeof(Registers->Graphics); i++)
{
WRITE_PORT_UCHAR(GRAPHICS, i);
WRITE_PORT_UCHAR(GRAPHICSDATA, Registers->Graphics[i]);
}
/* Write attribute controller registers */
for (i = 0; i < sizeof(Registers->Attribute); i++)
{
READ_PORT_UCHAR(STATUS);
WRITE_PORT_UCHAR(ATTRIB, i);
WRITE_PORT_UCHAR(ATTRIB, Registers->Attribute[i]);
}
/* Set the PEL mask. */
WRITE_PORT_UCHAR(PELMASK, 0xff);
}
static VOID FASTCALL
ScrAcquireOwnership(PDEVICE_EXTENSION DeviceExtension)
{
PDEVICE_EXTENSION DeviceExtension;
PHYSICAL_ADDRESS BaseAddress;
NTSTATUS Status;
unsigned int offset;
UCHAR data, value;
ULONG Index;
DeviceExtension = DeviceObject->DeviceExtension;
ScrSetRegisters(&VidpMode3Regs);
/* disable interrupts */
_disable();
/* Disable screen and enable palette access. */
READ_PORT_UCHAR(STATUS);
WRITE_PORT_UCHAR(ATTRIB, 0x00);
for (Index = 0; Index < sizeof(DefaultPalette) / 3; Index++)
{
WRITE_PORT_UCHAR(PELINDEX, Index);
WRITE_PORT_UCHAR(PELDATA, DefaultPalette[Index * 3] >> 2);
WRITE_PORT_UCHAR(PELDATA, DefaultPalette[Index * 3 + 1] >> 2);
WRITE_PORT_UCHAR(PELDATA, DefaultPalette[Index * 3 + 2] >> 2);
}
/* Enable screen and disable palette access. */
READ_PORT_UCHAR(STATUS);
WRITE_PORT_UCHAR(ATTRIB, 0x20);
/* get current output position */
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORPOSLO);
@ -122,8 +239,13 @@ ScrCreate(PDEVICE_OBJECT DeviceObject,
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_SCANLINES);
DeviceExtension->ScanLines = (READ_PORT_UCHAR (CRTC_DATA) & 0x1F) + 1;
/* enable interrupts */
_enable();
/* show blinking cursor */
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORSTART);
WRITE_PORT_UCHAR (CRTC_DATA, (DeviceExtension->ScanLines - 1) & 0x1F);
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSOREND);
data = READ_PORT_UCHAR (CRTC_DATA) & 0xE0;
WRITE_PORT_UCHAR (CRTC_DATA,
data | ((DeviceExtension->ScanLines - 1) & 0x1F));
/* calculate number of text rows */
DeviceExtension->Rows =
@ -132,10 +254,26 @@ ScrCreate(PDEVICE_OBJECT DeviceObject,
DeviceExtension->Rows = 30;
#endif
DPRINT ("%d Columns %d Rows %d Scanlines\n",
DPRINT1 ("%d Columns %d Rows %d Scanlines\n",
DeviceExtension->Columns,
DeviceExtension->Rows,
DeviceExtension->ScanLines);
}
NTSTATUS STDCALL
DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
static NTSTATUS STDCALL
ScrCreate(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PDEVICE_EXTENSION DeviceExtension;
PHYSICAL_ADDRESS BaseAddress;
NTSTATUS Status;
DeviceExtension = DeviceObject->DeviceExtension;
ScrAcquireOwnership(DeviceExtension);
/* get pointer to video memory */
BaseAddress.QuadPart = VIDMEM_BASE;
@ -150,16 +288,6 @@ ScrCreate(PDEVICE_OBJECT DeviceObject,
DeviceExtension->Mode = ENABLE_PROCESSED_OUTPUT |
ENABLE_WRAP_AT_EOL_OUTPUT;
/* show blinking cursor */
_disable();
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSORSTART);
WRITE_PORT_UCHAR (CRTC_DATA, (DeviceExtension->ScanLines - 1) & 0x1F);
WRITE_PORT_UCHAR (CRTC_COMMAND, CRTC_CURSOREND);
data = READ_PORT_UCHAR (CRTC_DATA) & 0xE0;
WRITE_PORT_UCHAR (CRTC_DATA,
data | ((DeviceExtension->ScanLines - 1) & 0x1F));
_enable();
Status = STATUS_SUCCESS;
Irp->IoStatus.Status = Status;
@ -184,7 +312,7 @@ ScrWrite(PDEVICE_OBJECT DeviceObject,
int rows, columns;
int processed = DeviceExtension->Mode & ENABLE_PROCESSED_OUTPUT;
if (HalQueryDisplayOwnership())
if (0 && InbvCheckDisplayOwnership())
{
/* Display is in graphics mode, we're not allowed to touch it */
Status = STATUS_SUCCESS;

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Before After
Before After

View file

@ -2,7 +2,7 @@
* ReactOS Boot video driver
*
* Copyright (C) 2003 Casper S. Hornstroup
* Copyright (C) 2004 Filip Navara
* Copyright (C) 2004, 2005 Filip Navara
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -23,77 +23,150 @@
/* INCLUDES ******************************************************************/
#include <ntddk.h>
#include <windef.h>
#include <ndk/ldrfuncs.h>
#include "bootvid.h"
#include "ntbootvid.h"
#include "resource.h"
#define NDEBUG
#include <debug.h>
//#define USE_PROGRESS_BAR
/* GLOBALS *******************************************************************/
/*
* NOTE:
* This is based on SvgaLib 640x480x16 mode definition with the
* following changes:
* - Graphics: Data Rotate (Index 3)
* Set to zero to indicate that the data written to video memory by
* CPU should be processed unmodified.
* - Graphics: Mode Register (Index 5)
* Set to Write Mode 2 and Read Mode 0.
*/
static const VGA_REGISTERS Mode12Regs =
{
/* CRT Controller Registers */
{0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xEA, 0x8C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xE3},
/* Attribute Controller Registers */
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
0x0C, 0x0D, 0x0E, 0x0F, 0x81, 0x00, 0x0F, 0x00, 0x00},
/* Graphics Controller Registers */
{0x00, 0x0F, 0x00, 0x00, 0x00, 0x02, 0x05, 0x0F, 0xFF},
/* Sequencer Registers */
{0x03, 0x01, 0x0F, 0x00, 0x06},
/* Misc Output Register */
0xE3
};
PUCHAR VideoMemory;
/* Must be 4 bytes per entry */
long maskbit[640];
static CLIENT_ID BitmapThreadId;
static PUCHAR BootimageBitmap;
static LONG ShutdownNotify;
static KEVENT ShutdownCompleteEvent;
/* DATA **********************************************************************/
static PDRIVER_OBJECT BootVidDriverObject = NULL;
static RGBQUAD _MainPalette[16];
static UCHAR _Square1[9 * 4];
static UCHAR _Square2[9 * 4];
static UCHAR _Square3[9 * 4];
/* FUNCTIONS *****************************************************************/
static BOOLEAN FASTCALL
InbvFindBootimage()
static VOID NTAPI
BootVidAnimationThread(PVOID Ignored)
{
UCHAR PaletteBitmapBuffer[sizeof(BITMAPINFOHEADER) + sizeof(_MainPalette)];
PBITMAPINFOHEADER PaletteBitmap = (PBITMAPINFOHEADER)PaletteBitmapBuffer;
LPRGBQUAD Palette = (LPRGBQUAD)(PaletteBitmapBuffer + sizeof(BITMAPINFOHEADER));
ULONG Iteration, Index, ClrUsed;
UINT AnimBarPos;
LARGE_INTEGER Interval;
/*
* Build a bitmap containing the fade in palette. The palette entries
* are then processed in a loop and set using VidBitBlt function.
*/
ClrUsed = sizeof(_MainPalette) / sizeof(_MainPalette[0]);
RtlZeroMemory(PaletteBitmap, sizeof(BITMAPINFOHEADER));
PaletteBitmap->biSize = sizeof(BITMAPINFOHEADER);
PaletteBitmap->biBitCount = 4;
PaletteBitmap->biClrUsed = ClrUsed;
/*
* Main animation loop.
*/
for (Iteration = 0, AnimBarPos = 0; !ShutdownNotify; Iteration++)
{
if (Iteration <= PALETTE_FADE_STEPS)
{
for (Index = 0; Index < ClrUsed; Index++)
{
Palette[Index].rgbRed =
_MainPalette[Index].rgbRed * Iteration / PALETTE_FADE_STEPS;
Palette[Index].rgbGreen =
_MainPalette[Index].rgbGreen * Iteration / PALETTE_FADE_STEPS;
Palette[Index].rgbBlue =
_MainPalette[Index].rgbBlue * Iteration / PALETTE_FADE_STEPS;
}
VidBitBlt(PaletteBitmapBuffer, 0, 0);
}
#ifdef USE_PROGRESS_BAR
else
{
break;
}
Interval.QuadPart = -PALETTE_FADE_TIME;
#else
if (AnimBarPos == 0)
{
VidSolidColorFill(0x173, 354, 0x178, 354 + 9, 0);
}
else if (AnimBarPos > 3)
{
VidSolidColorFill(0xe3 + AnimBarPos * 8, 354,
0xe8 + AnimBarPos * 8, 354 + 9,
0);
}
if (AnimBarPos >= 3)
VidBufferToScreenBlt(_Square1, 0xeb + AnimBarPos * 8, 354, 6, 9, 4);
if (AnimBarPos >= 2 && AnimBarPos <= 16)
VidBufferToScreenBlt(_Square2, 0xf3 + AnimBarPos * 8, 354, 6, 9, 4);
if (AnimBarPos >= 1 && AnimBarPos <= 15)
VidBufferToScreenBlt(_Square3, 0xfb + AnimBarPos * 8, 354, 6, 9, 4);
if (Iteration <= PALETTE_FADE_STEPS)
{
Interval.QuadPart = -PALETTE_FADE_TIME;
if ((Iteration % 5) == 0)
AnimBarPos++;
}
else
{
Interval.QuadPart = -PALETTE_FADE_TIME * 5;
AnimBarPos++;
}
AnimBarPos = Iteration % 18;
#endif
/* Wait for a bit. */
KeDelayExecutionThread(KernelMode, FALSE, &Interval);
}
DPRINT("Finishing bootvid thread.\n");
KeSetEvent(&ShutdownCompleteEvent, 0, FALSE);
PsTerminateSystemThread(0);
}
NTSTATUS NTAPI
BootVidDisplayBootLogo(PVOID ImageBase)
{
PBITMAPINFOHEADER BitmapInfoHeader;
LPRGBQUAD Palette;
static const ULONG BitmapIds[2] = {IDB_BOOTIMAGE, IDB_BAR};
PUCHAR BitmapData[2];
ULONG Index;
HANDLE BitmapThreadHandle;
CLIENT_ID BitmapThreadId;
NTSTATUS Status;
KeInitializeEvent(&ShutdownCompleteEvent, NotificationEvent, FALSE);
/*
* Get the bitmaps from the executable.
*/
for (Index = 0; Index < sizeof(BitmapIds) / sizeof(BitmapIds[0]); Index++)
{
PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry;
LDR_RESOURCE_INFO ResourceInfo;
NTSTATUS Status;
PVOID BaseAddress = BootVidDriverObject->DriverStart;
ULONG Size;
ResourceInfo.Type = RT_BITMAP;
ResourceInfo.Name = IDB_BOOTIMAGE;
ResourceInfo.Type = /* RT_BITMAP */ 2;
ResourceInfo.Name = BitmapIds[Index];
ResourceInfo.Language = 0x09;
Status = LdrFindResource_U(
BaseAddress,
ImageBase,
&ResourceInfo,
RESOURCE_DATA_LEVEL,
&ResourceDataEntry);
@ -101,472 +174,60 @@ InbvFindBootimage()
if (!NT_SUCCESS(Status))
{
DPRINT("LdrFindResource_U() failed with status 0x%.08x\n", Status);
return FALSE;
return Status;
}
Status = LdrAccessResource(
BaseAddress,
ImageBase,
ResourceDataEntry,
(PVOID*)&BootimageBitmap,
(PVOID*)&BitmapData[Index],
&Size);
if (!NT_SUCCESS(Status))
{
DPRINT("LdrAccessResource() failed with status 0x%.08x\n", Status);
return FALSE;
}
return TRUE;
}
static BOOLEAN FASTCALL
InbvMapVideoMemory(VOID)
{
PHYSICAL_ADDRESS PhysicalAddress;
PhysicalAddress.QuadPart = 0xA0000;
VideoMemory = MmMapIoSpace(PhysicalAddress, 0x10000, MmNonCached);
return VideoMemory != NULL;
}
static BOOLEAN FASTCALL
InbvUnmapVideoMemory(VOID)
{
MmUnmapIoSpace(VideoMemory, 0x10000);
return TRUE;
}
static VOID FASTCALL
vgaPreCalc()
{
ULONG j;
for (j = 0; j < 80; j++)
{
maskbit[j * 8 + 0] = 128;
maskbit[j * 8 + 1] = 64;
maskbit[j * 8 + 2] = 32;
maskbit[j * 8 + 3] = 16;
maskbit[j * 8 + 4] = 8;
maskbit[j * 8 + 5] = 4;
maskbit[j * 8 + 6] = 2;
maskbit[j * 8 + 7] = 1;
return Status;
}
}
static VOID FASTCALL
vgaSetRegisters(const VGA_REGISTERS *Registers)
{
UINT i;
/* Update misc output register */
WRITE_PORT_UCHAR(MISC, Registers->Misc);
/* Synchronous reset on */
WRITE_PORT_UCHAR(SEQ, 0x00);
WRITE_PORT_UCHAR(SEQDATA, 0x01);
/* Write sequencer registers */
for (i = 1; i < sizeof(Registers->Sequencer); i++)
{
WRITE_PORT_UCHAR(SEQ, i);
WRITE_PORT_UCHAR(SEQDATA, Registers->Sequencer[i]);
}
/* Synchronous reset off */
WRITE_PORT_UCHAR(SEQ, 0x00);
WRITE_PORT_UCHAR(SEQDATA, 0x03);
/* Deprotect CRT registers 0-7 */
WRITE_PORT_UCHAR(CRTC, 0x11);
WRITE_PORT_UCHAR(CRTCDATA, Registers->CRT[0x11] & 0x7f);
/* Write CRT registers */
for (i = 0; i < sizeof(Registers->CRT); i++)
{
WRITE_PORT_UCHAR(CRTC, i);
WRITE_PORT_UCHAR(CRTCDATA, Registers->CRT[i]);
}
/* Write graphics controller registers */
for (i = 0; i < sizeof(Registers->Graphics); i++)
{
WRITE_PORT_UCHAR(GRAPHICS, i);
WRITE_PORT_UCHAR(GRAPHICSDATA, Registers->Graphics[i]);
}
/* Write attribute controller registers */
for (i = 0; i < sizeof(Registers->Attribute); i++)
{
READ_PORT_UCHAR(STATUS);
WRITE_PORT_UCHAR(ATTRIB, i);
WRITE_PORT_UCHAR(ATTRIB, Registers->Attribute[i]);
}
}
static VOID
InbvInitVGAMode(VOID)
{
/* Zero out video memory (clear a possibly trashed screen) */
RtlZeroMemory(VideoMemory, 0x10000);
vgaSetRegisters(&Mode12Regs);
/* Set the PEL mask. */
WRITE_PORT_UCHAR(PELMASK, 0xff);
vgaPreCalc();
}
static BOOLEAN STDCALL
VidResetDisplay(VOID)
{
/*
* We are only using standard VGA facilities so we can rely on the
* HAL 'int10mode3' reset to cleanup the hardware state.
*/
return FALSE;
}
static VOID STDCALL
VidCleanUp(VOID)
{
InbvUnmapVideoMemory();
InterlockedIncrement(&ShutdownNotify);
KeWaitForSingleObject(&ShutdownCompleteEvent, Executive, KernelMode,
FALSE, NULL);
}
static VOID FASTCALL
InbvSetColor(INT Index, UCHAR Red, UCHAR Green, UCHAR Blue)
{
WRITE_PORT_UCHAR(PELINDEX, Index);
WRITE_PORT_UCHAR(PELDATA, Red >> 2);
WRITE_PORT_UCHAR(PELDATA, Green >> 2);
WRITE_PORT_UCHAR(PELDATA, Blue >> 2);
}
static VOID FASTCALL
InbvSetBlackPalette()
{
register ULONG r = 0;
/* Disable screen and enable palette access. */
READ_PORT_UCHAR(STATUS);
WRITE_PORT_UCHAR(ATTRIB, 0x00);
for (r = 0; r < 16; r++)
{
InbvSetColor(r, 0, 0, 0);
}
/* Enable screen and enable palette access. */
READ_PORT_UCHAR(STATUS);
WRITE_PORT_UCHAR(ATTRIB, 0x20);
}
static VOID FASTCALL
InbvDisplayBitmap(ULONG Width, ULONG Height, PCHAR ImageData)
{
ULONG j, k, y;
register ULONG i;
register ULONG x;
register ULONG c;
k = 0;
for (y = 0; y < Height; y++)
{
for (j = 0; j < 8; j++)
{
x = j;
/*
* Loop through the line and process every 8th pixel.
* This way we can get a way with using the same bit mask
* for several pixels and thus not need to do as much I/O
* communication.
* Initialize the graphics output.
*/
while (x < 640)
if (!VidInitialize(TRUE))
{
c = 0;
if (x < Width)
{
c = ImageData[k + x];
for (i = 1; i < 4; i++)
{
if (x + i * 8 < Width)
{
c |= (ImageData[k + x + i * 8] << i * 8);
return STATUS_UNSUCCESSFUL;
}
}
}
InbvPutPixels(x, 479 - y, c);
x += 8 * 4;
}
}
k += Width;
}
}
static VOID FASTCALL
InbvDisplayCompressedBitmap()
{
PBITMAPV5HEADER bminfo;
ULONG i,j,k;
ULONG x,y;
ULONG curx,cury;
ULONG bfOffBits;
ULONG clen;
PCHAR ImageData;
UCHAR ClrUsed;
bminfo = (PBITMAPV5HEADER) &BootimageBitmap[0];
DPRINT("bV5Size = %d\n", bminfo->bV5Size);
DPRINT("bV5Width = %d\n", bminfo->bV5Width);
DPRINT("bV5Height = %d\n", bminfo->bV5Height);
DPRINT("bV5Planes = %d\n", bminfo->bV5Planes);
DPRINT("bV5BitCount = %d\n", bminfo->bV5BitCount);
DPRINT("bV5Compression = %d\n", bminfo->bV5Compression);
DPRINT("bV5SizeImage = %d\n", bminfo->bV5SizeImage);
DPRINT("bV5XPelsPerMeter = %d\n", bminfo->bV5XPelsPerMeter);
DPRINT("bV5YPelsPerMeter = %d\n", bminfo->bV5YPelsPerMeter);
DPRINT("bV5ClrUsed = %d\n", bminfo->bV5ClrUsed);
DPRINT("bV5ClrImportant = %d\n", bminfo->bV5ClrImportant);
if (bminfo->bV5ClrUsed)
ClrUsed = bminfo->bV5ClrUsed;
else
ClrUsed = 1 << bminfo->bV5BitCount;
bfOffBits = bminfo->bV5Size + ClrUsed * sizeof(RGBQUAD);
DPRINT("bfOffBits = %d\n", bfOffBits);
DPRINT("size of color indices = %d\n", ClrUsed * sizeof(RGBQUAD));
DPRINT("first byte of data = %d\n", BootimageBitmap[bfOffBits]);
InbvSetBlackPalette();
ImageData = ExAllocatePool(NonPagedPool, bminfo->bV5Width * bminfo->bV5Height);
RtlZeroMemory(ImageData, bminfo->bV5Width * bminfo->bV5Height);
/*
* ImageData has 1 pixel per byte.
* bootimage has 2 pixels per byte.
* Load the bar bitmap and get the square data from it.
*/
if (bminfo->bV5Compression == 2)
{
k = 0;
j = 0;
while ((j < bminfo->bV5SizeImage) && (k < (ULONG) (bminfo->bV5Width * bminfo->bV5Height)))
{
unsigned char b;
VidBitBlt(BitmapData[1], 0, 0);
VidScreenToBufferBlt(_Square1, 0, 0, 6, 9, 4);
VidScreenToBufferBlt(_Square2, 8, 0, 6, 9, 4);
VidScreenToBufferBlt(_Square3, 16, 0, 6, 9, 4);
clen = BootimageBitmap[bfOffBits + j];
j++;
/*
* Save the main image palette and replace it with black palette, so
* we can do fade in effect later.
*/
if (clen > 0)
{
/* Encoded mode */
BitmapInfoHeader = (PBITMAPINFOHEADER)BitmapData[0];
Palette = (LPRGBQUAD)(BitmapData[0] + BitmapInfoHeader->biSize);
RtlCopyMemory(_MainPalette, Palette, sizeof(_MainPalette));
RtlZeroMemory(Palette, sizeof(_MainPalette));
b = BootimageBitmap[bfOffBits + j];
j++;
/*
* Display the main image.
*/
for (i = 0; i < (clen / 2); i++)
{
ImageData[k] = (b & 0xf0) >> 4;
k++;
ImageData[k] = b & 0xf;
k++;
}
if ((clen & 1) > 0)
{
ImageData[k] = (b & 0xf0) >> 4;
k++;
}
}
else
{
/* Absolute mode */
b = BootimageBitmap[bfOffBits + j];
j++;
VidBitBlt(BitmapData[0], 0, 0);
if (b == 0)
{
/* End of line */
if (k % bminfo->bV5Width)
{
cury = k / bminfo->bV5Width;
k = (cury + 1) * bminfo->bV5Width;
}
}
else if (b == 1)
{
/* End of image */
break;
}
else if (b == 2)
{
x = BootimageBitmap[bfOffBits + j];
j++;
y = BootimageBitmap[bfOffBits + j];
j++;
curx = k % bminfo->bV5Width;
cury = k / bminfo->bV5Width;
k = (cury + y) * bminfo->bV5Width + (curx + x);
}
else
{
if ((j & 1) > 0)
{
DPRINT("Unaligned copy!\n");
}
clen = b;
for (i = 0; i < (clen / 2); i++)
{
b = BootimageBitmap[bfOffBits + j];
j++;
ImageData[k] = (b & 0xf0) >> 4;
k++;
ImageData[k] = b & 0xf;
k++;
}
if ((clen & 1) > 0)
{
b = BootimageBitmap[bfOffBits + j];
j++;
ImageData[k] = (b & 0xf0) >> 4;
k++;
}
/* Word align */
j += (j & 1);
}
}
}
InbvDisplayBitmap(bminfo->bV5Width, bminfo->bV5Height, ImageData);
}
else
{
DbgPrint("Warning boot image need to be compressed using RLE4\n");
}
ExFreePool(ImageData);
}
static VOID FASTCALL
InbvFadeUpPalette()
{
PBITMAPV5HEADER bminfo;
PRGBQUAD Palette;
ULONG i;
unsigned char r, g, b;
register ULONG c;
LARGE_INTEGER Interval;
FADER_PALETTE_ENTRY FaderPalette[16];
FADER_PALETTE_ENTRY FaderPaletteDelta[16];
UCHAR ClrUsed;
RtlZeroMemory(&FaderPalette, sizeof(FaderPalette));
RtlZeroMemory(&FaderPaletteDelta, sizeof(FaderPaletteDelta));
bminfo = (PBITMAPV5HEADER)&BootimageBitmap[0];
Palette = (PRGBQUAD)&BootimageBitmap[bminfo->bV5Size];
if (bminfo->bV5ClrUsed)
ClrUsed = bminfo->bV5ClrUsed;
else
ClrUsed = 1 << bminfo->bV5BitCount;
for (i = 0; i < 16 && i < ClrUsed; i++)
{
FaderPaletteDelta[i].r = ((Palette[i].rgbRed << 8) / PALETTE_FADE_STEPS);
FaderPaletteDelta[i].g = ((Palette[i].rgbGreen << 8) / PALETTE_FADE_STEPS);
FaderPaletteDelta[i].b = ((Palette[i].rgbBlue << 8) / PALETTE_FADE_STEPS);
}
for (i = 0; i < PALETTE_FADE_STEPS && !ShutdownNotify; i++)
{
/* Disable screen and enable palette access. */
READ_PORT_UCHAR(STATUS);
WRITE_PORT_UCHAR(ATTRIB, 0x00);
for (c = 0; c < ClrUsed; c++)
{
/* Add the delta */
FaderPalette[c].r += FaderPaletteDelta[c].r;
FaderPalette[c].g += FaderPaletteDelta[c].g;
FaderPalette[c].b += FaderPaletteDelta[c].b;
/* Get the integer values */
r = FaderPalette[c].r >> 8;
g = FaderPalette[c].g >> 8;
b = FaderPalette[c].b >> 8;
/* Don't go too far */
if (r > Palette[c].rgbRed)
r = Palette[c].rgbRed;
if (g > Palette[c].rgbGreen)
g = Palette[c].rgbGreen;
if (b > Palette[c].rgbBlue)
b = Palette[c].rgbBlue;
/* Update the hardware */
InbvSetColor(c, r, g, b);
}
/* Enable screen and disable palette access. */
READ_PORT_UCHAR(STATUS);
WRITE_PORT_UCHAR(ATTRIB, 0x20);
/* Wait for a bit. */
Interval.QuadPart = -PALETTE_FADE_TIME;
KeDelayExecutionThread(KernelMode, FALSE, &Interval);
}
}
static VOID STDCALL
InbvBitmapThreadMain(PVOID Ignored)
{
if (InbvFindBootimage())
{
InbvDisplayCompressedBitmap();
InbvFadeUpPalette();
}
else
{
DbgPrint("Warning: Cannot find boot image\n");
}
KeSetEvent(&ShutdownCompleteEvent, 0, FALSE);
}
static BOOLEAN STDCALL
VidInitialize(VOID)
{
NTSTATUS Status;
HANDLE BitmapThreadHandle;
InbvMapVideoMemory();
InbvInitVGAMode();
/*
* Start a thread that handles the fade in and bar animation effects.
*/
Status = PsCreateSystemThread(
&BitmapThreadHandle,
@ -574,99 +235,47 @@ VidInitialize(VOID)
NULL,
NULL,
&BitmapThreadId,
InbvBitmapThreadMain,
BootVidAnimationThread,
NULL);
if (!NT_SUCCESS(Status))
{
return FALSE;
VidCleanUp();
return Status;
}
ZwClose(BitmapThreadHandle);
return TRUE;
return STATUS_SUCCESS;
}
static NTSTATUS STDCALL
VidDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
VOID NTAPI
BootVidUpdateProgress(ULONG Progress)
{
PIO_STACK_LOCATION IrpSp;
NTSTATUS Status;
NTBOOTVID_FUNCTION_TABLE* FunctionTable;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
Status = STATUS_SUCCESS;
switch(IrpSp->MajorFunction)
#ifdef USE_PROGRESS_BAR
if (ShutdownNotify == 0)
{
/* Opening and closing handles to the device */
case IRP_MJ_CREATE:
case IRP_MJ_CLOSE:
break;
case IRP_MJ_DEVICE_CONTROL:
switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_BOOTVID_INITIALIZE:
VidInitialize();
FunctionTable = (NTBOOTVID_FUNCTION_TABLE *)
Irp->AssociatedIrp.SystemBuffer;
FunctionTable->ResetDisplay = VidResetDisplay;
Irp->IoStatus.Information = sizeof(NTBOOTVID_FUNCTION_TABLE);
break;
case IOCTL_BOOTVID_CLEANUP:
VidCleanUp();
break;
default:
Status = STATUS_NOT_IMPLEMENTED;
break;
VidSolidColorFill(0x103, 354, 0x103 + (Progress * 120 / 100), 354 + 9, 1);
}
break;
/* Unsupported operations */
default:
Status = STATUS_NOT_IMPLEMENTED;
#endif
}
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
VOID NTAPI
BootVidFinalizeBootLogo(VOID)
{
InterlockedIncrement(&ShutdownNotify);
DPRINT1("Waiting for bootvid thread to finish.\n");
KeWaitForSingleObject(&ShutdownCompleteEvent, Executive, KernelMode,
FALSE, NULL);
DPRINT1("Bootvid thread to finish.\n");
VidResetDisplay();
}
NTSTATUS STDCALL
DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
PDEVICE_OBJECT BootVidDevice;
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\BootVid");
NTSTATUS Status;
BootVidDriverObject = DriverObject;
ShutdownNotify = 0;
KeInitializeEvent(&ShutdownCompleteEvent, NotificationEvent, FALSE);
/* Register driver routines */
DriverObject->MajorFunction[IRP_MJ_CLOSE] = VidDispatch;
DriverObject->MajorFunction[IRP_MJ_CREATE] = VidDispatch;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VidDispatch;
DriverObject->DriverUnload = NULL;
DriverObject->Flags |= DO_BUFFERED_IO;
/* Create device */
Status = IoCreateDevice(
DriverObject,
0,
&DeviceName,
FILE_DEVICE_BOOTVID,
0,
FALSE,
&BootVidDevice);
return Status;
return STATUS_SUCCESS;
}

View file

@ -0,0 +1,14 @@
LIBRARY bootvid.sys
EXPORTS
VidInitialize@4
VidCleanUp@0
VidResetDisplay@0
VidBufferToScreenBlt@24
VidScreenToBufferBlt@24
VidBitBlt@12
VidSolidColorFill@20
VidDisplayString@4
BootVidDisplayBootLogo@4
BootVidUpdateProgress@4
BootVidFinalizeBootLogo@0

View file

@ -2,7 +2,7 @@
* ReactOS Boot video driver
*
* Copyright (C) 2003 Casper S. Hornstroup
* Copyright (C) 2004 Filip Navara
* Copyright (C) 2004, 2005 Filip Navara
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -24,104 +24,42 @@
#ifndef _BOOTVID_H
#define _BOOTVID_H
#define PALETTE_FADE_STEPS 20
#include <ntddk.h>
#include <windef.h>
#include <wingdi.h>
#include <ndk/ldrfuncs.h>
#define PALETTE_FADE_STEPS 15
#define PALETTE_FADE_TIME 20 * 10000 /* 20ms */
/*
* Windows Bitmap structures
*/
BOOLEAN NTAPI VidInitialize(BOOLEAN);
VOID NTAPI VidCleanUp(VOID);
VOID NTAPI VidResetDisplay(VOID);
VOID NTAPI VidBufferToScreenBlt(PUCHAR, ULONG, ULONG, ULONG, ULONG, ULONG);
VOID NTAPI VidScreenToBufferBlt(PUCHAR, ULONG, ULONG, ULONG, ULONG, ULONG);
VOID NTAPI VidBitBlt(PUCHAR, ULONG, ULONG);
VOID NTAPI VidSolidColorFill(ULONG, ULONG, ULONG, ULONG, ULONG);
VOID NTAPI VidDisplayString(PUCHAR);
#define RT_BITMAP 2
typedef BOOLEAN (NTAPI *PVID_INITIALIZE)(BOOLEAN);
typedef VOID (NTAPI *PVID_CLEAN_UP)(VOID);
typedef VOID (NTAPI *PVID_RESET_DISPLAY)(VOID);
typedef VOID (NTAPI *PVID_BUFFER_TO_SCREEN_BLT)(PUCHAR, ULONG, ULONG, ULONG, ULONG, ULONG);
typedef VOID (NTAPI *PVID_SCREEN_TO_BUFFER_BLT)(PUCHAR, ULONG, ULONG, ULONG, ULONG, ULONG);
typedef VOID (NTAPI *PVID_BITBLT)(PUCHAR, ULONG, ULONG);
typedef VOID (NTAPI *PVID_SOLID_COLOR_FILL)(ULONG, ULONG, ULONG, ULONG, ULONG);
typedef VOID (NTAPI *PVID_DISPLAY_STRING)(PUCHAR);
typedef struct tagRGBQUAD
typedef struct _VID_FUNCTION_TABLE
{
unsigned char rgbBlue;
unsigned char rgbGreen;
unsigned char rgbRed;
unsigned char rgbReserved;
} RGBQUAD, *PRGBQUAD;
typedef long FXPT2DOT30;
typedef struct tagCIEXYZ
{
FXPT2DOT30 ciexyzX;
FXPT2DOT30 ciexyzY;
FXPT2DOT30 ciexyzZ;
} CIEXYZ, *LPCIEXYZ;
typedef struct tagCIEXYZTRIPLE
{
CIEXYZ ciexyzRed;
CIEXYZ ciexyzGreen;
CIEXYZ ciexyzBlue;
} CIEXYZTRIPLE, *LPCIEXYZTRIPLE;
typedef struct {
DWORD bV5Size;
LONG bV5Width;
LONG bV5Height;
WORD bV5Planes;
WORD bV5BitCount;
DWORD bV5Compression;
DWORD bV5SizeImage;
LONG bV5XPelsPerMeter;
LONG bV5YPelsPerMeter;
DWORD bV5ClrUsed;
DWORD bV5ClrImportant;
DWORD bV5RedMask;
DWORD bV5GreenMask;
DWORD bV5BlueMask;
DWORD bV5AlphaMask;
DWORD bV5CSType;
CIEXYZTRIPLE bV5Endpoints;
DWORD bV5GammaRed;
DWORD bV5GammaGreen;
DWORD bV5GammaBlue;
DWORD bV5Intent;
DWORD bV5ProfileData;
DWORD bV5ProfileSize;
DWORD bV5Reserved;
} BITMAPV5HEADER, *PBITMAPV5HEADER;
/*
* Private driver structures
*/
typedef struct {
ULONG r;
ULONG g;
ULONG b;
} FADER_PALETTE_ENTRY;
typedef struct _VGA_REGISTERS
{
UCHAR CRT[24];
UCHAR Attribute[21];
UCHAR Graphics[9];
UCHAR Sequencer[5];
UCHAR Misc;
} VGA_REGISTERS, *PVGA_REGISTERS;
/* VGA registers */
#define MISC (PUCHAR)0x3c2
#define SEQ (PUCHAR)0x3c4
#define SEQDATA (PUCHAR)0x3c5
#define CRTC (PUCHAR)0x3d4
#define CRTCDATA (PUCHAR)0x3d5
#define GRAPHICS (PUCHAR)0x3ce
#define GRAPHICSDATA (PUCHAR)0x3cf
#define ATTRIB (PUCHAR)0x3c0
#define STATUS (PUCHAR)0x3da
#define PELMASK (PUCHAR)0x3c6
#define PELINDEX (PUCHAR)0x3c8
#define PELDATA (PUCHAR)0x3c9
/* In pixelsups.S */
extern VOID
InbvPutPixels(int x, int y, unsigned long c);
NTSTATUS STDCALL
DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
PVID_INITIALIZE Initialize;
PVID_CLEAN_UP CleanUp;
PVID_RESET_DISPLAY ResetDisplay;
PVID_BUFFER_TO_SCREEN_BLT BufferToScreenBlt;
PVID_SCREEN_TO_BUFFER_BLT ScreenToBufferBlt;
PVID_BITBLT BitBlt;
PVID_SOLID_COLOR_FILL SolidColorFill;
PVID_DISPLAY_STRING DisplayString;
} VID_FUNCTION_TABLE, *PVID_FUNCTION_TABLE;
#endif /* _BOOTVID_H */

View file

@ -1,9 +1,14 @@
<module name="bootvid" type="kernelmodedriver" installbase="system32/drivers" installname="bootvid.sys">
<module name="bootvid" type="kernelmodedll" entrypoint="DriverEntry@8" installbase="system32/drivers" installname="bootvid.sys">
<importlibrary definition="bootvid.def"></importlibrary>
<bootstrap base="reactos" nameoncd="bootvid.sys" />
<include base="bootvid">.</include>
<define name="__USE_W32API" />
<library>ntoskrnl</library>
<library>hal</library>
<file>bootvid.c</file>
<file>pixelsup_i386.S</file>
<file>vid.c</file>
<file>vid_vga.c</file>
<file>vid_vgatext.c</file>
<file>vid_xbox.c</file>
<file>bootvid.rc</file>
</module>

View file

@ -9,4 +9,6 @@
#include <reactos/version.rc>
IDB_BOOTIMAGE BITMAP DISCARDABLE "bootimage.bmp"
IDB_BAR BITMAP DISCARDABLE "bar.bmp"

View file

@ -1,13 +0,0 @@
/* FIXME: Bootvid will eventually become a DLL and this will be deprecated */
#define FILE_DEVICE_BOOTVID 53335
#define IOCTL_BOOTVID_INITIALIZE \
CTL_CODE(FILE_DEVICE_BOOTVID, 1, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_BOOTVID_CLEANUP \
CTL_CODE(FILE_DEVICE_BOOTVID, 2, METHOD_BUFFERED, FILE_ANY_ACCESS)
typedef struct
{
BOOLEAN (NTAPI *ResetDisplay)(VOID);
} NTBOOTVID_FUNCTION_TABLE;

View file

@ -1,108 +0,0 @@
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/inbv/i386/pixelsup.S
* PURPOSE: Boot video support
* PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
*/
/*
* VOID
* InbvPutPixels(int x, int y, unsigned long c);
*
* Will put 4 pixels on the screen at
* (x+0*8,y), (x+1*8,y), (x+2*8,y), and (x+3*8,y)
* c will contain:
* bits 0- 3: Palette index for pixel at (x+0*8,y)
* bits 8-11: Palette index for pixel at (x+1*8,y)
* bits 16-19: Palette index for pixel at (x+2*8,y)
* bits 24-27: Palette index for pixel at (x+3*8,y)
*
* Parameters:
* [EBP+08h] - x X-coordinate of first pixel
* [ESP+0Ch] - y Y-coordinate of first pixel
* [ESP+10h] - c 4*4-bit color indices
*/
.globl _InbvPutPixels
_InbvPutPixels:
pushl %ebp
movl %esp, %ebp
pushl %esi
pushl %ebx
/* Compute mask and put it in EBX
mask = maskbit[x] */
movl 0x8(%ebp), %esi
movl _maskbit(,%esi, 4), %ebx
/* Don't set bit mask if it is already set */
cmpl (inbv_last_mask),%ebx
je .nomask
/* Set Mask Bit Register
WRITE_PORT_UCHAR((PUCHAR)0x3ce,0x08);
WRITE_PORT_UCHAR((PUCHAR)0x3cf,mask); */
movl %ebx,(inbv_last_mask)
movw $0x3ce,%dx
movb $0x08,%al
outb %al,%dx
movw $0x3cf,%dx
movb %bl,%al
outb %al,%dx
.nomask:
/* Compute offset in video memory and put it in EBX
offset = (x >> 3) + (y << 4) + (y << 6); */
movl 0xC(%ebp), %esi /* y */
movl %esi, %ebx
shll $0x6, %ebx
shll $0x4, %esi
addl %esi, %ebx
movl 0x8(%ebp), %eax /* x */
shrl $0x3, %eax
addl %eax, %ebx
/* Latch first byte
(UCHAR) READ_REGISTER_UCHAR(VideoMemory + offset+0); */
movl (_VideoMemory), %esi
addl %ebx, %esi
movb 0x0(%esi), %bl
/* Write color index for first pixel
*((PUCHAR)(VideoMemory + offset+0)) = (c >> 0*8) & 0xff; */
movl 0x10(%ebp), %eax
movb %al, 0x0(%esi)
/* Latch second byte
(UCHAR) READ_REGISTER_UCHAR(VideoMemory + offset+1); */
movb 0x1(%esi), %bl
/* Write color index for second pixel
*((PUCHAR)(VideoMemory + offset+1)) = (c >> 1*8) & 0xff; */
shrl $0x8, %eax
movb %al, 0x1(%esi)
/* Latch third byte
(UCHAR) READ_REGISTER_UCHAR(VideoMemory + offset+2); */
movb 0x2(%esi), %bl
/* Write color index for third pixel
*((PUCHAR)(VideoMemory + offset+2)) = (c >> 2*8) & 0xff; */
shrl $0x8, %eax
movb %al, 0x2(%esi)
/* Latch fourth byte
(UCHAR) READ_REGISTER_UCHAR(VideoMemory + offset+3); */
movb 0x3(%esi), %bl
/* Write color index for fourth pixel
*((PUCHAR)(VideoMemory + offset+3)) = (c >> 3*8) & 0xff; */
shrl $0x8, %eax
movb %al, 0x3(%esi)
popl %ebx
popl %esi
popl %ebp
ret
.bss
inbv_last_mask:
.short 0

View file

@ -1,4 +1,6 @@
/* $Id$ */
/* Bitmaps */
#define IDB_BOOTIMAGE 100
#define IDB_BOOTIMAGE 1
#define IDB_BAR 8

View file

@ -0,0 +1,119 @@
/*
* ReactOS Boot video driver
*
* Copyright (C) 2005 Filip Navara
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* INCLUDES ******************************************************************/
#include "bootvid.h"
#define NDEBUG
#include <debug.h>
/* GLOBALS *******************************************************************/
static PVID_FUNCTION_TABLE VidTable;
extern VID_FUNCTION_TABLE VidVgaTable;
extern VID_FUNCTION_TABLE VidVgaTextTable;
extern VID_FUNCTION_TABLE VidXboxTable;
/* FUNCTIONS *****************************************************************/
BOOLEAN NTAPI
VidInitialize(
IN BOOLEAN SetMode)
{
ULONG PciId;
/*
* Check for Xbox by identifying device at PCI 0:0:0, if it's
* 0x10de/0x02a5 then we're running on an Xbox.
*/
CHECKPOINT1;
WRITE_PORT_ULONG((PULONG)0xcf8, 0x80000000);
PciId = READ_PORT_ULONG((PULONG)0xcfc);
if (0x02a510de == PciId)
VidTable = &VidXboxTable;
else if (SetMode)
VidTable = &VidVgaTable;
else
VidTable = &VidVgaTextTable;
return VidTable->Initialize(SetMode);
}
VOID STDCALL
VidResetDisplay(VOID)
{
VidTable->ResetDisplay();
}
VOID NTAPI
VidCleanUp(VOID)
{
VidTable->CleanUp();
}
VOID NTAPI
VidBufferToScreenBlt(
IN PUCHAR Buffer,
IN ULONG Left,
IN ULONG Top,
IN ULONG Width,
IN ULONG Height,
IN ULONG Delta)
{
VidTable->BufferToScreenBlt(Buffer, Left, Top, Width, Height, Delta);
}
VOID NTAPI
VidScreenToBufferBlt(
OUT PUCHAR Buffer,
IN ULONG Left,
IN ULONG Top,
IN ULONG Width,
IN ULONG Height,
IN ULONG Delta)
{
VidTable->ScreenToBufferBlt(Buffer, Left, Top, Width, Height, Delta);
}
VOID NTAPI
VidBitBlt(
IN PUCHAR Buffer,
IN ULONG Left,
IN ULONG Top)
{
VidTable->BitBlt(Buffer, Left, Top);
}
VOID NTAPI
VidSolidColorFill(
IN ULONG Left,
IN ULONG Top,
IN ULONG Right,
IN ULONG Bottom,
IN ULONG Color)
{
VidTable->SolidColorFill(Left, Top, Right, Bottom, Color);
}
VOID NTAPI
VidDisplayString(
IN PUCHAR String)
{
VidTable->DisplayString(String);
}

View file

@ -0,0 +1,512 @@
/*
* ReactOS Boot video driver
*
* Copyright (C) 2005 Filip Navara
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* INCLUDES ******************************************************************/
#include "bootvid.h"
#define NDEBUG
#include <debug.h>
/* TYPES AND DEFINITIONS *****************************************************/
typedef struct _VGA_REGISTERS
{
UCHAR CRT[24];
UCHAR Attribute[21];
UCHAR Graphics[9];
UCHAR Sequencer[5];
UCHAR Misc;
} VGA_REGISTERS, *PVGA_REGISTERS;
/* VGA registers */
#define MISC (PUCHAR)0x3c2
#define SEQ (PUCHAR)0x3c4
#define SEQDATA (PUCHAR)0x3c5
#define CRTC (PUCHAR)0x3d4
#define CRTCDATA (PUCHAR)0x3d5
#define GRAPHICS (PUCHAR)0x3ce
#define GRAPHICSDATA (PUCHAR)0x3cf
#define ATTRIB (PUCHAR)0x3c0
#define STATUS (PUCHAR)0x3da
#define PELMASK (PUCHAR)0x3c6
#define PELINDEX (PUCHAR)0x3c8
#define PELDATA (PUCHAR)0x3c9
/* GLOBALS *******************************************************************/
/*
* NOTE:
* This is based on SvgaLib 640x480x16 mode definition with the
* following changes:
* - Graphics: Data Rotate (Index 3)
* Set to zero to indicate that the data written to video memory by
* CPU should be processed unmodified.
* - Graphics: Mode Register (Index 5)
* Set to Write Mode 2 and Read Mode 0.
*/
static const VGA_REGISTERS VidpMode12Regs =
{
/* CRT Controller Registers */
{0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xEA, 0x8C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xE3},
/* Attribute Controller Registers */
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
0x0C, 0x0D, 0x0E, 0x0F, 0x81, 0x00, 0x0F, 0x00, 0x00},
/* Graphics Controller Registers */
{0x00, 0x0F, 0x00, 0x00, 0x00, 0x02, 0x05, 0x0F, 0xFF},
/* Sequencer Registers */
{0x03, 0x01, 0x0F, 0x00, 0x06},
/* Misc Output Register */
0xE3
};
static const RGBQUAD DefaultPalette[] =
{
{0, 0, 0},
{0, 0, 0x80},
{0, 0x80, 0},
{0, 0x80, 0x80},
{0x80, 0, 0},
{0x80, 0, 0x80},
{0x80, 0x80, 0},
{0x80, 0x80, 0x80},
{0xC0, 0xC0, 0xC0},
{0, 0, 0xFF},
{0, 0xFF, 0},
{0, 0xFF, 0xFF},
{0xFF, 0, 0},
{0xFF, 0, 0xFF},
{0xFF, 0xFF, 0},
{0xFF, 0xFF, 0xFF}
};
static BOOLEAN VidpInitialized = FALSE;
static PUCHAR VidpMemory;
static CHAR VidpMaskBit[640];
static ULONG VidpCurrentX;
static ULONG VidpCurrentY;
/* FUNCTIONS *****************************************************************/
static VOID FASTCALL
VidpSetRegisters(const VGA_REGISTERS *Registers)
{
UINT i;
/* Update misc output register */
WRITE_PORT_UCHAR(MISC, Registers->Misc);
/* Synchronous reset on */
WRITE_PORT_UCHAR(SEQ, 0x00);
WRITE_PORT_UCHAR(SEQDATA, 0x01);
/* Write sequencer registers */
for (i = 1; i < sizeof(Registers->Sequencer); i++)
{
WRITE_PORT_UCHAR(SEQ, i);
WRITE_PORT_UCHAR(SEQDATA, Registers->Sequencer[i]);
}
/* Synchronous reset off */
WRITE_PORT_UCHAR(SEQ, 0x00);
WRITE_PORT_UCHAR(SEQDATA, 0x03);
/* Deprotect CRT registers 0-7 */
WRITE_PORT_UCHAR(CRTC, 0x11);
WRITE_PORT_UCHAR(CRTCDATA, Registers->CRT[0x11] & 0x7f);
/* Write CRT registers */
for (i = 0; i < sizeof(Registers->CRT); i++)
{
WRITE_PORT_UCHAR(CRTC, i);
WRITE_PORT_UCHAR(CRTCDATA, Registers->CRT[i]);
}
/* Write graphics controller registers */
for (i = 0; i < sizeof(Registers->Graphics); i++)
{
WRITE_PORT_UCHAR(GRAPHICS, i);
WRITE_PORT_UCHAR(GRAPHICSDATA, Registers->Graphics[i]);
}
/* Write attribute controller registers */
for (i = 0; i < sizeof(Registers->Attribute); i++)
{
READ_PORT_UCHAR(STATUS);
WRITE_PORT_UCHAR(ATTRIB, i);
WRITE_PORT_UCHAR(ATTRIB, Registers->Attribute[i]);
}
/* Set the PEL mask. */
WRITE_PORT_UCHAR(PELMASK, 0xff);
}
static BOOLEAN NTAPI
VidVgaInitialize(
IN BOOLEAN SetMode)
{
ULONG Index;
PHYSICAL_ADDRESS PhysicalAddress;
if (!VidpInitialized)
{
PhysicalAddress.QuadPart = 0xA0000;
VidpMemory = MmMapIoSpace(PhysicalAddress, 0x10000, MmNonCached);
if (VidpMemory == NULL)
return FALSE;
for (Index = 0; Index < 80; Index++)
{
VidpMaskBit[Index * 8 + 0] = 128;
VidpMaskBit[Index * 8 + 1] = 64;
VidpMaskBit[Index * 8 + 2] = 32;
VidpMaskBit[Index * 8 + 3] = 16;
VidpMaskBit[Index * 8 + 4] = 8;
VidpMaskBit[Index * 8 + 5] = 4;
VidpMaskBit[Index * 8 + 6] = 2;
VidpMaskBit[Index * 8 + 7] = 1;
}
VidpInitialized = TRUE;
}
if (SetMode)
{
VidpSetRegisters(&VidpMode12Regs);
VidpCurrentX = VidpCurrentY = 0;
/* Disable screen and enable palette access. */
READ_PORT_UCHAR(STATUS);
WRITE_PORT_UCHAR(ATTRIB, 0x00);
for (Index = 0; Index < sizeof(DefaultPalette) / sizeof(RGBQUAD); Index++)
{
WRITE_PORT_UCHAR(PELINDEX, Index);
WRITE_PORT_UCHAR(PELDATA, DefaultPalette[Index].rgbRed >> 2);
WRITE_PORT_UCHAR(PELDATA, DefaultPalette[Index].rgbGreen >> 2);
WRITE_PORT_UCHAR(PELDATA, DefaultPalette[Index].rgbBlue >> 2);
}
/* Enable screen and disable palette access. */
READ_PORT_UCHAR(STATUS);
WRITE_PORT_UCHAR(ATTRIB, 0x20);
}
return TRUE;
}
static VOID STDCALL
VidVgaResetDisplay(VOID)
{
VidVgaInitialize(TRUE);
}
static VOID NTAPI
VidVgaCleanUp(VOID)
{
if (VidpInitialized)
{
MmUnmapIoSpace(VidpMemory, 0x10000);
VidpInitialized = FALSE;
}
}
static VOID NTAPI
VidVgaBufferToScreenBlt(
IN PUCHAR Buffer,
IN ULONG Left,
IN ULONG Top,
IN ULONG Width,
IN ULONG Height,
IN ULONG Delta)
{
ULONG x, y;
PUCHAR BufferPtr;
ULONG VidOffset;
for (x = Left; x < Left + Width; x++)
{
WRITE_PORT_UCHAR(GRAPHICS, 0x08);
WRITE_PORT_UCHAR(GRAPHICSDATA, VidpMaskBit[x]);
BufferPtr = Buffer;
VidOffset = (x >> 3) + (Top * 80);
if (((x - Left) % 2) == 0)
{
for (y = Top; y < Top + Height; y++)
{
READ_REGISTER_UCHAR(VidpMemory + VidOffset);
WRITE_REGISTER_UCHAR(VidpMemory + VidOffset, *BufferPtr >> 4);
VidOffset += 80;
BufferPtr += Delta;
}
}
else
{
for (y = Top; y < Top + Height; y++)
{
READ_REGISTER_UCHAR(VidpMemory + VidOffset);
WRITE_REGISTER_UCHAR(VidpMemory + VidOffset, *BufferPtr & 0xf);
VidOffset += 80;
BufferPtr += Delta;
}
Buffer++;
}
}
}
static VOID NTAPI
VidVgaScreenToBufferBlt(
OUT PUCHAR Buffer,
IN ULONG Left,
IN ULONG Top,
IN ULONG Width,
IN ULONG Height,
IN ULONG Delta)
{
UCHAR Plane;
UCHAR b;
ULONG x, y;
/* Reset the destination. */
RtlZeroMemory(Buffer, (Delta > 0 ? Delta : -Delta) * Height);
for (Plane = 0; Plane < 4; Plane++)
{
WRITE_PORT_UCHAR(GRAPHICS, 0x04);
WRITE_PORT_UCHAR(GRAPHICSDATA, Plane);
for (y = Top; y < Top + Height; y++)
{
for (x = Left; x < Left + Width; x++)
{
b = READ_REGISTER_UCHAR(VidpMemory + (y * 80 + (x >> 3)));
b >>= 7 - (x & 7);
b &= 1;
b <<= Plane + ((~(x - Left) & 1) << 2);
Buffer[(y - Top) * Delta + ((x - Left) >> 1)] |= b;
}
}
}
}
static VOID NTAPI
VidVgaBitBlt(
IN PUCHAR Buffer,
IN ULONG Left,
IN ULONG Top)
{
PBITMAPINFOHEADER BitmapInfoHeader;
LPRGBQUAD Palette;
ULONG bfOffBits;
UCHAR ClrUsed;
ULONG Index;
ULONG Delta;
BitmapInfoHeader = (PBITMAPINFOHEADER)Buffer;
Palette = (LPRGBQUAD)(Buffer + BitmapInfoHeader->biSize);
if (BitmapInfoHeader->biClrUsed)
ClrUsed = BitmapInfoHeader->biClrUsed;
else
ClrUsed = 1 << BitmapInfoHeader->biBitCount;
bfOffBits = BitmapInfoHeader->biSize + ClrUsed * sizeof(RGBQUAD);
/* Disable screen and enable palette access. */
READ_PORT_UCHAR(STATUS);
WRITE_PORT_UCHAR(ATTRIB, 0x00);
for (Index = 0; Index < ClrUsed; Index++)
{
WRITE_PORT_UCHAR(PELINDEX, Index);
WRITE_PORT_UCHAR(PELDATA, Palette[Index].rgbRed >> 2);
WRITE_PORT_UCHAR(PELDATA, Palette[Index].rgbGreen >> 2);
WRITE_PORT_UCHAR(PELDATA, Palette[Index].rgbBlue >> 2);
}
/* Enable screen and disable palette access. */
READ_PORT_UCHAR(STATUS);
WRITE_PORT_UCHAR(ATTRIB, 0x20);
if (BitmapInfoHeader->biCompression == 2)
{
PUCHAR OutputBuffer;
ULONG InputPos, OutputPos;
ULONG x, y;
UCHAR b;
ULONG Length;
Delta = (BitmapInfoHeader->biWidth + 1) >> 1;
OutputBuffer = ExAllocatePool(NonPagedPool, Delta * BitmapInfoHeader->biHeight);
RtlZeroMemory(OutputBuffer, Delta * BitmapInfoHeader->biHeight);
OutputPos = InputPos = 0;
Buffer += bfOffBits;
while (InputPos < BitmapInfoHeader->biSizeImage &&
OutputPos < Delta * BitmapInfoHeader->biHeight * 2)
{
Length = Buffer[InputPos++];
if (Length > 0)
{
/* Encoded mode */
b = Buffer[InputPos++];
if (OutputPos % 2)
{
OutputBuffer[OutputPos >> 1] |= b & 0xf;
b = (b >> 4) | (b << 4);
Length--;
OutputPos++;
}
memset(OutputBuffer + (OutputPos >> 1), b, Length / 2);
OutputPos += Length;
if (Length & 1)
{
OutputBuffer[OutputPos >> 1] |= b & 0xf;
OutputPos++;
}
}
else
{
/* Absolute mode */
b = Buffer[InputPos++];
if (b == 0)
{
/* End of line */
if (OutputPos % Delta)
OutputPos = ((OutputPos / Delta) + 1) * Delta;
}
else if (b == 1)
{
/* End of image */
break;
}
else if (b == 2)
{
x = Buffer[InputPos++];
y = Buffer[InputPos++];
OutputPos = ((OutputPos / Delta) + y) * Delta +
((OutputPos % Delta) + x);
}
else
{
Length = b;
if (Length)
{
if (OutputPos % 2)
{
ASSERT(FALSE);
}
for (Index = 0; Index < (Length / 2); Index++)
{
b = Buffer[InputPos++];
OutputBuffer[OutputPos >> 1] = b;
OutputPos += 2;
}
if (Length & 1)
{
b = Buffer[InputPos++];
OutputBuffer[OutputPos >> 1] |= b >> 4;
OutputPos++;
}
}
/* Word align */
InputPos += (InputPos & 1);
}
}
}
VidBufferToScreenBlt(OutputBuffer +
(Delta * (BitmapInfoHeader->biHeight - 1)),
0, 0, BitmapInfoHeader->biWidth,
BitmapInfoHeader->biHeight, -Delta);
ExFreePool(OutputBuffer);
}
else
{
Delta = ((BitmapInfoHeader->biWidth + 31) & ~31) >> 1;
if (BitmapInfoHeader->biHeight < 0)
{
VidBufferToScreenBlt(Buffer + bfOffBits,
0, 0, BitmapInfoHeader->biWidth,
-BitmapInfoHeader->biHeight, Delta);
}
else
{
VidBufferToScreenBlt(Buffer + bfOffBits +
(Delta * (BitmapInfoHeader->biHeight - 1)),
0, 0, BitmapInfoHeader->biWidth,
BitmapInfoHeader->biHeight, -Delta);
}
}
}
static VOID NTAPI
VidVgaSolidColorFill(
IN ULONG Left,
IN ULONG Top,
IN ULONG Right,
IN ULONG Bottom,
IN ULONG Color)
{
ULONG x, y;
ULONG VidOffset;
for (x = Left; x <= Right; x++)
{
WRITE_PORT_UCHAR(GRAPHICS, 0x08);
WRITE_PORT_UCHAR(GRAPHICSDATA, VidpMaskBit[x]);
VidOffset = (x >> 3) + (Top * 80);
for (y = Top; y <= Bottom; y++)
{
READ_REGISTER_UCHAR(VidpMemory + VidOffset);
WRITE_REGISTER_UCHAR(VidpMemory + VidOffset, Color & 0xF);
VidOffset += 80;
}
}
}
static VOID NTAPI
VidVgaDisplayString(
IN PUCHAR String)
{
}
VID_FUNCTION_TABLE VidVgaTable =
{
VidVgaInitialize,
VidVgaCleanUp,
VidVgaResetDisplay,
VidVgaBufferToScreenBlt,
VidVgaScreenToBufferBlt,
VidVgaBitBlt,
VidVgaSolidColorFill,
VidVgaDisplayString
};

View file

@ -0,0 +1,251 @@
/*
* ReactOS Boot video driver
*
* Copyright (C) 2005 Filip Navara
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* INCLUDES ******************************************************************/
#include "bootvid.h"
#define NDEBUG
#include <debug.h>
/* TYPES AND DEFINITIONS *****************************************************/
/* VGA registers */
#define MISC (PUCHAR)0x3c2
#define SEQ (PUCHAR)0x3c4
#define SEQDATA (PUCHAR)0x3c5
#define CRTC (PUCHAR)0x3d4
#define CRTCDATA (PUCHAR)0x3d5
#define GRAPHICS (PUCHAR)0x3ce
#define GRAPHICSDATA (PUCHAR)0x3cf
#define ATTRIB (PUCHAR)0x3c0
#define STATUS (PUCHAR)0x3da
#define PELMASK (PUCHAR)0x3c6
#define PELINDEX (PUCHAR)0x3c8
#define PELDATA (PUCHAR)0x3c9
#define CRTC_COLUMNS 0x01
#define CRTC_OVERFLOW 0x07
#define CRTC_ROWS 0x12
#define CRTC_SCANLINES 0x09
#define CRTC_CURHI 0x0e
#define CRTC_CURLO 0x0f
#define CHAR_ATTRIBUTE_BLACK 0x00 /* black on black */
#define CHAR_ATTRIBUTE 0x1F /* grey on blue */
/* GLOBALS *******************************************************************/
static BOOLEAN VidpInitialized = FALSE;
static PUCHAR VidpMemory;
static ULONG SizeX, SizeY;
/* FUNCTIONS *****************************************************************/
static VOID NTAPI
VidpVgaTextClearDisplay(VOID)
{
WORD *ptr = (WORD*)VidpMemory;
ULONG i;
for (i = 0; i < SizeX * SizeY; i++, ptr++)
*ptr = (0x1700 + ' ');
}
static BOOLEAN NTAPI
VidVgaTextInitialize(
IN BOOLEAN SetMode)
{
ULONG ScanLines;
PHYSICAL_ADDRESS PhysicalAddress;
UCHAR Data;
if (!VidpInitialized)
{
PhysicalAddress.QuadPart = 0xB8000;
VidpMemory = MmMapIoSpace(PhysicalAddress, 0x2000, MmNonCached);
if (VidpMemory == NULL)
return FALSE;
VidpInitialized = TRUE;
WRITE_PORT_UCHAR(CRTC, CRTC_COLUMNS);
SizeX = READ_PORT_UCHAR(CRTCDATA) + 1;
WRITE_PORT_UCHAR(CRTC, CRTC_ROWS);
SizeY = READ_PORT_UCHAR(CRTCDATA);
WRITE_PORT_UCHAR(CRTC, CRTC_OVERFLOW);
Data = READ_PORT_UCHAR(CRTCDATA);
SizeY |= (((Data & 0x02) << 7) | ((Data & 0x40) << 3));
SizeY++;
WRITE_PORT_UCHAR(CRTC, CRTC_SCANLINES);
ScanLines = (READ_PORT_UCHAR(CRTCDATA) & 0x1F) + 1;
SizeY = SizeY / ScanLines;
VidpVgaTextClearDisplay();
WRITE_PORT_UCHAR(CRTC, CRTC_CURLO);
WRITE_PORT_UCHAR(CRTCDATA, 0);
WRITE_PORT_UCHAR(CRTC, CRTC_CURHI);
WRITE_PORT_UCHAR(CRTCDATA, 0);
}
return TRUE;
}
static VOID NTAPI
VidVgaTextResetDisplay(VOID)
{
VidVgaTextInitialize(TRUE);
}
static VOID NTAPI
VidVgaTextCleanUp(VOID)
{
if (VidpInitialized)
{
MmUnmapIoSpace(VidpMemory, 0x10000);
VidpInitialized = FALSE;
}
}
static VOID NTAPI
VidVgaTextBufferToScreenBlt(
IN PUCHAR Buffer,
IN ULONG Left,
IN ULONG Top,
IN ULONG Width,
IN ULONG Height,
IN ULONG Delta)
{
}
static VOID NTAPI
VidVgaTextScreenToBufferBlt(
OUT PUCHAR Buffer,
IN ULONG Left,
IN ULONG Top,
IN ULONG Width,
IN ULONG Height,
IN ULONG Delta)
{
}
static VOID NTAPI
VidVgaTextBitBlt(
IN PUCHAR Buffer,
IN ULONG Left,
IN ULONG Top)
{
}
static VOID NTAPI
VidVgaTextSolidColorFill(
IN ULONG Left,
IN ULONG Top,
IN ULONG Right,
IN ULONG Bottom,
IN ULONG Color)
{
}
static VOID NTAPI
VidpVgaTextScrollDisplay(VOID)
{
PUSHORT ptr;
int i;
ptr = (PUSHORT)VidpMemory + SizeX;
RtlMoveMemory(VidpMemory, ptr, SizeX * (SizeY - 1) * 2);
ptr = (PUSHORT)VidpMemory + (SizeX * (SizeY - 1));
for (i = 0; i < (int)SizeX; i++, ptr++)
*ptr = (CHAR_ATTRIBUTE << 8) + ' ';
}
static VOID NTAPI
VidVgaTextDisplayString(
IN PUCHAR String)
{
PCH pch;
int offset;
ULONG CursorX;
ULONG CursorY;
pch = String;
WRITE_PORT_UCHAR(CRTC, CRTC_CURHI);
offset = READ_PORT_UCHAR(CRTCDATA) << 8;
WRITE_PORT_UCHAR(CRTC, CRTC_CURLO);
offset += READ_PORT_UCHAR(CRTCDATA);
CursorY = offset / SizeX;
CursorX = offset % SizeX;
while (*pch != 0)
{
if (*pch == '\n')
{
CursorY++;
CursorX = 0;
}
else if (*pch == '\b')
{
if (CursorX > 0)
CursorX--;
}
else if (*pch != '\r')
{
PUSHORT ptr;
ptr = (PUSHORT)VidpMemory + ((CursorY * SizeX) + CursorX);
*ptr = (CHAR_ATTRIBUTE << 8) + *pch;
CursorX++;
if (CursorX >= SizeX)
{
CursorY++;
CursorX = 0;
}
}
if (CursorY >= SizeY)
{
VidpVgaTextScrollDisplay();
CursorY = SizeY - 1;
}
pch++;
}
offset = (CursorY * SizeX) + CursorX;
WRITE_PORT_UCHAR(CRTC, CRTC_CURLO);
WRITE_PORT_UCHAR(CRTCDATA, (UCHAR)(offset & 0xff));
WRITE_PORT_UCHAR(CRTC, CRTC_CURHI);
WRITE_PORT_UCHAR(CRTCDATA, (UCHAR)((offset >> 8) & 0xff));
}
VID_FUNCTION_TABLE VidVgaTextTable = {
VidVgaTextInitialize,
VidVgaTextCleanUp,
VidVgaTextResetDisplay,
VidVgaTextBufferToScreenBlt,
VidVgaTextScreenToBufferBlt,
VidVgaTextBitBlt,
VidVgaTextSolidColorFill,
VidVgaTextDisplayString
};

View file

@ -0,0 +1,101 @@
/*
* ReactOS Boot video driver
*
* Copyright (C) 2005 Filip Navara
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* INCLUDES ******************************************************************/
#include "bootvid.h"
#define NDEBUG
#include <debug.h>
/* FUNCTIONS *****************************************************************/
static BOOLEAN NTAPI
VidXboxInitialize(
IN BOOLEAN SetMode)
{
return TRUE;
}
static VOID NTAPI
VidXboxResetDisplay(VOID)
{
}
static VOID NTAPI
VidXboxCleanUp(VOID)
{
}
static VOID NTAPI
VidXboxBufferToScreenBlt(
IN PUCHAR Buffer,
IN ULONG Left,
IN ULONG Top,
IN ULONG Width,
IN ULONG Height,
IN ULONG Delta)
{
}
static VOID NTAPI
VidXboxScreenToBufferBlt(
OUT PUCHAR Buffer,
IN ULONG Left,
IN ULONG Top,
IN ULONG Width,
IN ULONG Height,
IN ULONG Delta)
{
}
static VOID NTAPI
VidXboxBitBlt(
IN PUCHAR Buffer,
IN ULONG Left,
IN ULONG Top)
{
}
static VOID NTAPI
VidXboxSolidColorFill(
IN ULONG Left,
IN ULONG Top,
IN ULONG Right,
IN ULONG Bottom,
IN ULONG Color)
{
}
static VOID NTAPI
VidXboxDisplayString(
IN PUCHAR String)
{
}
VID_FUNCTION_TABLE VidXboxTable = {
VidXboxInitialize,
VidXboxCleanUp,
VidXboxResetDisplay,
VidXboxBufferToScreenBlt,
VidXboxScreenToBufferBlt,
VidXboxBitBlt,
VidXboxSolidColorFill,
VidXboxDisplayString
};

View file

@ -22,8 +22,6 @@
#include "videoprt.h"
/* EXTERNAL FUNCTIONS *********************************************************/
/* GLOBAL VARIABLES ***********************************************************/
PVIDEO_PORT_DEVICE_EXTENSION ResetDisplayParametersDeviceExtension = NULL;
@ -174,8 +172,10 @@ IntVideoPortDispatchClose(
if (DeviceExtension->DeviceOpened >= 1 &&
InterlockedDecrement((PLONG)&DeviceExtension->DeviceOpened) == 0)
{
ResetDisplayParametersDeviceExtension = NULL;
InbvNotifyDisplayOwnershipLost(NULL);
ResetDisplayParametersDeviceExtension = DeviceExtension;
HalReleaseDisplayOwnership();
IntVideoPortResetDisplayParameters(80, 50);
}
Irp->IoStatus.Status = STATUS_SUCCESS;
@ -290,15 +290,18 @@ IntVideoPortDispatchWrite(
/*
* Storing the device extension pointer in a static variable is an
* ugly hack. Unfortunately, we need it in VideoPortResetDisplayParameters
* and HalAcquireDisplayOwnership doesn't allow us to pass a userdata
* ugly hack. Unfortunately, we need it in IntVideoPortResetDisplayParameters
* and InbvNotifyDisplayOwnershipLost doesn't allow us to pass a userdata
* parameter. On the bright side, the DISPLAY device is opened
* exclusively, so there can be only one device extension active at
* any point in time.
*
* FIXME: We should process all opened display devices in
* IntVideoPortResetDisplayParameters.
*/
ResetDisplayParametersDeviceExtension = DeviceExtension;
HalAcquireDisplayOwnership(IntVideoPortResetDisplayParameters);
InbvNotifyDisplayOwnershipLost(IntVideoPortResetDisplayParameters);
nErrCode = STATUS_SUCCESS;
Irp->IoStatus.Information = piosStack->Parameters.Write.Length;

View file

@ -101,6 +101,3 @@ WRITE_PORT_BUFFER_USHORT@12
WRITE_PORT_UCHAR@8
WRITE_PORT_ULONG@8
WRITE_PORT_USHORT@8
HalReleaseDisplayOwnership@0
HalQueryDisplayOwnership@0

View file

@ -16,646 +16,14 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/hal/x86/display.c
* PURPOSE: Blue screen display
* PROGRAMMER: Eric Kohl (ekohl@rz-online.de)
* UPDATE HISTORY:
* Created 08/10/99
*/
/*
* Portions of this code are from the XFree86 Project and available from the
* following license:
*
* Copyright (C) 1994-2003 The XFree86 Project, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
* NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of the XFree86 Project shall
* not be used in advertising or otherwise to promote the sale, use or other
* dealings in this Software without prior written authorization from the
* XFree86 Project.
*/
/* DISPLAY OWNERSHIP
*
* So, who owns the physical display and is allowed to write to it?
*
* In MS NT, upon boot HAL owns the display. Somewhere in the boot
* sequence (haven't figured out exactly where or by who), some
* component calls HalAcquireDisplayOwnership. From that moment on,
* the display is owned by that component and is switched to graphics
* mode. The display is not supposed to return to text mode, except
* in case of a bug check. The bug check will call HalDisplayString
* to output a string to the text screen. HAL will notice that it
* currently doesn't own the display and will re-take ownership, by
* calling the callback function passed to HalAcquireDisplayOwnership.
* After the bugcheck, execution is halted. So, under NT, the only
* possible sequence of display modes is text mode -> graphics mode ->
* text mode (the latter hopefully happening very infrequently).
*
* Things are a little bit different in the current state of ReactOS.
* We want to have a functional interactive text mode. We should be
* able to switch from text mode to graphics mode when a GUI app is
* started and switch back to text mode when it's finished. Then, when
* another GUI app is started, another switch to and from graphics mode
* is possible. Also, when the system bugchecks in graphics mode we want
* to switch back to text mode to show the registers and stack trace.
* Last but not least, HalDisplayString is used a lot more in ReactOS,
* e.g. to print debug messages when the /DEBUGPORT=SCREEN boot option
* is present.
* 3 Components are involved in Reactos: HAL, BLUE.SYS and VIDEOPRT.SYS.
* As in NT, on boot HAL owns the display. When entering the text mode
* command interpreter, BLUE.SYS kicks in. It will write directly to the
* screen, more or less behind HALs back.
* When a GUI app is started, WIN32K.SYS will open the DISPLAY device.
* This open call will end up in VIDEOPRT.SYS. That component will then
* take ownership of the display by calling HalAcquireDisplayOwnership.
* When the GUI app terminates (WIN32K.SYS will close the DISPLAY device),
* we want to give ownership of the display back to HAL. Using the
* standard exported HAL functions, that's a bit of a problem, because
* there is no function defined to do that. In NT, this is handled by
* HalDisplayString, but that solution isn't satisfactory in ReactOS,
* because HalDisplayString is (in some cases) also used to output debug
* messages. If we do it the NT way, the first debug message output while
* in graphics mode would switch the display back to text mode.
* So, instead, if HalDisplayString detects that HAL doesn't have ownership
* of the display, it doesn't do anything.
* To return ownership to HAL, a new function is exported,
* HalReleaseDisplayOwnership. This function is called by the DISPLAY
* device Close routine in VIDEOPRT.SYS. It is also called at the beginning
* of a bug check, so HalDisplayString is activated again.
* Now, while the display is in graphics mode (not owned by HAL), BLUE.SYS
* should also refrain from writing to the screen buffer. The text mode
* screen buffer might overlap the graphics mode screen buffer, so changing
* something in the text mode buffer might mess up the graphics screen. To
* allow BLUE.SYS to detect if HAL owns the display, another new function is
* exported, HalQueryDisplayOwnership. BLUE.SYS will call this function to
* check if it's allowed to touch the text mode buffer.
*
* In an ideal world, when HAL takes ownership of the display, it should set
* up the CRT using real-mode (actually V86 mode, but who cares) INT 0x10
* calls. Unfortunately, this will require HAL to setup a real-mode interrupt
* table etc. So, we chickened out of that by having the loader set up the
* display before switching to protected mode. If HAL is given back ownership
* after a GUI app terminates, the INT 0x10 calls are made by VIDEOPRT.SYS,
* since there is already support for them via the VideoPortInt10 routine.
*/
#include <hal.h>
#define NDEBUG
#include <debug.h>
#define SCREEN_SYNCHRONIZATION
#define VGA_GRAPH_MEM 0xa0000
#define VGA_CHAR_MEM 0xb8000
#define VGA_END_MEM 0xbffff
#define VGA_AC_INDEX 0x3c0
#define VGA_AC_READ 0x3c1
#define VGA_AC_WRITE 0x3c0
#define VGA_MISC_WRITE 0x3c2
#define VGA_SEQ_INDEX 0x3c4
#define VGA_SEQ_DATA 0x3c5
#define VGA_DAC_MASK 0x3c6
#define VGA_DAC_READ_INDEX 0x3c7
#define VGA_DAC_WRITE_INDEX 0x3c8
#define VGA_DAC_DATA 0x3c9
#define VGA_FEATURE_READ 0x3ca
#define VGA_MISC_READ 0x3cc
#define VGA_GC_INDEX 0x3ce
#define VGA_GC_DATA 0x3cf
#define VGA_CRTC_INDEX 0x3d4
#define VGA_CRTC_DATA 0x3d5
#define VGA_INSTAT_READ 0x3da
#define VGA_SEQ_NUM_REGISTERS 5
#define VGA_CRTC_NUM_REGISTERS 25
#define VGA_GC_NUM_REGISTERS 9
#define VGA_AC_NUM_REGISTERS 21
#define CRTC_COLUMNS 0x01
#define CRTC_OVERFLOW 0x07
#define CRTC_ROWS 0x12
#define CRTC_SCANLINES 0x09
#define CRTC_CURHI 0x0e
#define CRTC_CURLO 0x0f
#define CHAR_ATTRIBUTE_BLACK 0x00 /* black on black */
#define CHAR_ATTRIBUTE 0x17 /* grey on blue */
#define FONT_AMOUNT (8*8192)
/* VARIABLES ****************************************************************/
static ULONG CursorX = 0; /* Cursor Position */
static ULONG CursorY = 0;
static ULONG SizeX = 80; /* Display size */
static ULONG SizeY = 25;
static BOOLEAN DisplayInitialized = FALSE;
static BOOLEAN HalOwnsDisplay = TRUE;
static PUSHORT VideoBuffer = NULL;
static PUCHAR GraphVideoBuffer = NULL;
static PHAL_RESET_DISPLAY_PARAMETERS HalResetDisplayParameters = NULL;
static UCHAR SavedTextPalette[768];
static UCHAR SavedTextMiscOutReg;
static UCHAR SavedTextCrtcReg[VGA_CRTC_NUM_REGISTERS];
static UCHAR SavedTextAcReg[VGA_AC_NUM_REGISTERS];
static UCHAR SavedTextGcReg[VGA_GC_NUM_REGISTERS];
static UCHAR SavedTextSeqReg[VGA_SEQ_NUM_REGISTERS];
static UCHAR SavedTextFont[2][FONT_AMOUNT];
static BOOLEAN TextPaletteEnabled = FALSE;
/* PRIVATE FUNCTIONS *********************************************************/
VOID FASTCALL
HalClearDisplay (UCHAR CharAttribute)
{
WORD *ptr = (WORD*)VideoBuffer;
ULONG i;
for (i = 0; i < SizeX * SizeY; i++, ptr++)
*ptr = ((CharAttribute << 8) + ' ');
CursorX = 0;
CursorY = 0;
}
/* STATIC FUNCTIONS *********************************************************/
VOID STATIC
HalScrollDisplay (VOID)
{
PUSHORT ptr;
int i;
ptr = VideoBuffer + SizeX;
RtlMoveMemory(VideoBuffer,
ptr,
SizeX * (SizeY - 1) * 2);
ptr = VideoBuffer + (SizeX * (SizeY - 1));
for (i = 0; i < (int)SizeX; i++, ptr++)
{
*ptr = (CHAR_ATTRIBUTE << 8) + ' ';
}
}
VOID STATIC FASTCALL
HalPutCharacter (CHAR Character)
{
PUSHORT ptr;
ptr = VideoBuffer + ((CursorY * SizeX) + CursorX);
*ptr = (CHAR_ATTRIBUTE << 8) + Character;
}
VOID STATIC
HalDisablePalette(VOID)
{
(VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, 0x20);
TextPaletteEnabled = FALSE;
}
VOID STATIC
HalEnablePalette(VOID)
{
(VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, 0x00);
TextPaletteEnabled = TRUE;
}
UCHAR STATIC FASTCALL
HalReadGc(ULONG Index)
{
WRITE_PORT_UCHAR((PUCHAR)VGA_GC_INDEX, (UCHAR)Index);
return(READ_PORT_UCHAR((PUCHAR)VGA_GC_DATA));
}
VOID STATIC FASTCALL
HalWriteGc(ULONG Index, UCHAR Value)
{
WRITE_PORT_UCHAR((PUCHAR)VGA_GC_INDEX, (UCHAR)Index);
WRITE_PORT_UCHAR((PUCHAR)VGA_GC_DATA, Value);
}
UCHAR STATIC FASTCALL
HalReadSeq(ULONG Index)
{
WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_INDEX, (UCHAR)Index);
return(READ_PORT_UCHAR((PUCHAR)VGA_SEQ_DATA));
}
VOID STATIC FASTCALL
HalWriteSeq(ULONG Index, UCHAR Value)
{
WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_INDEX, (UCHAR)Index);
WRITE_PORT_UCHAR((PUCHAR)VGA_SEQ_DATA, Value);
}
VOID STATIC FASTCALL
HalWriteAc(ULONG Index, UCHAR Value)
{
if (TextPaletteEnabled)
{
Index &= ~0x20;
}
else
{
Index |= 0x20;
}
(VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, (UCHAR)Index);
WRITE_PORT_UCHAR((PUCHAR)VGA_AC_WRITE, Value);
}
UCHAR STATIC FASTCALL
HalReadAc(ULONG Index)
{
if (TextPaletteEnabled)
{
Index &= ~0x20;
}
else
{
Index |= 0x20;
}
(VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
WRITE_PORT_UCHAR((PUCHAR)VGA_AC_INDEX, (UCHAR)Index);
return(READ_PORT_UCHAR((PUCHAR)VGA_AC_READ));
}
VOID STATIC FASTCALL
HalWriteCrtc(ULONG Index, UCHAR Value)
{
WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, (UCHAR)Index);
WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, Value);
}
UCHAR STATIC FASTCALL
HalReadCrtc(ULONG Index)
{
WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, (UCHAR)Index);
return(READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA));
}
VOID STATIC FASTCALL
HalResetSeq(BOOLEAN Start)
{
if (Start)
{
HalWriteSeq(0x00, 0x01);
}
else
{
HalWriteSeq(0x00, 0x03);
}
}
VOID STATIC FASTCALL
HalBlankScreen(BOOLEAN On)
{
UCHAR Scrn;
Scrn = HalReadSeq(0x01);
if (On)
{
Scrn &= ~0x20;
}
else
{
Scrn |= 0x20;
}
HalResetSeq(TRUE);
HalWriteSeq(0x01, Scrn);
HalResetSeq(FALSE);
}
VOID STATIC
HalSaveFont(VOID)
{
UCHAR Attr10;
UCHAR MiscOut, Gc4, Gc5, Gc6, Seq2, Seq4;
ULONG i;
/* Check if we are already in graphics mode. */
Attr10 = HalReadAc(0x10);
if (Attr10 & 0x01)
{
return;
}
/* Save registers. */
MiscOut = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ);
Gc4 = HalReadGc(0x04);
Gc5 = HalReadGc(0x05);
Gc6 = HalReadGc(0x06);
Seq2 = HalReadSeq(0x02);
Seq4 = HalReadSeq(0x04);
/* Force colour mode. */
WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, (UCHAR)(MiscOut | 0x01));
HalBlankScreen(FALSE);
for (i = 0; i < 2; i++)
{
/* Save font 1 */
HalWriteSeq(0x02, (UCHAR)(0x04 << i)); /* Write to plane 2 or 3 */
HalWriteSeq(0x04, 0x06); /* Enable plane graphics. */
HalWriteGc(0x04, (UCHAR)(0x02 + i)); /* Read plane 2 or 3 */
HalWriteGc(0x05, 0x00); /* Write mode 0; read mode 0 */
HalWriteGc(0x06, 0x05); /* Set graphics. */
memcpy(SavedTextFont[i], GraphVideoBuffer, FONT_AMOUNT);
}
/* Restore registers. */
HalWriteAc(0x10, Attr10);
HalWriteSeq(0x02, Seq2);
HalWriteSeq(0x04, Seq4);
HalWriteGc(0x04, Gc4);
HalWriteGc(0x05, Gc5);
HalWriteGc(0x06, Gc6);
WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, MiscOut);
HalBlankScreen(TRUE);
}
VOID STATIC
HalSaveMode(VOID)
{
ULONG i;
SavedTextMiscOutReg = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ);
for (i = 0; i < VGA_CRTC_NUM_REGISTERS; i++)
{
SavedTextCrtcReg[i] = HalReadCrtc(i);
}
HalEnablePalette();
for (i = 0; i < VGA_AC_NUM_REGISTERS; i++)
{
SavedTextAcReg[i] = HalReadAc(i);
}
HalDisablePalette();
for (i = 0; i < VGA_GC_NUM_REGISTERS; i++)
{
SavedTextGcReg[i] = HalReadGc(i);
}
for (i = 0; i < VGA_SEQ_NUM_REGISTERS; i++)
{
SavedTextSeqReg[i] = HalReadSeq(i);
}
}
VOID STATIC
HalDacDelay(VOID)
{
(VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
(VOID)READ_PORT_UCHAR((PUCHAR)VGA_INSTAT_READ);
}
VOID STATIC
HalSavePalette(VOID)
{
ULONG i;
WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_MASK, 0xFF);
WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_READ_INDEX, 0x00);
for (i = 0; i < 768; i++)
{
SavedTextPalette[i] = READ_PORT_UCHAR((PUCHAR)VGA_DAC_DATA);
HalDacDelay();
}
}
VOID STATIC
HalRestoreFont(VOID)
{
UCHAR MiscOut, Attr10, Gc1, Gc3, Gc4, Gc5, Gc6, Gc8;
UCHAR Seq2, Seq4;
ULONG i;
/* Save registers. */
MiscOut = READ_PORT_UCHAR((PUCHAR)VGA_MISC_READ);
Attr10 = HalReadAc(0x10);
Gc1 = HalReadGc(0x01);
Gc3 = HalReadGc(0x03);
Gc4 = HalReadGc(0x04);
Gc5 = HalReadGc(0x05);
Gc6 = HalReadGc(0x06);
Gc8 = HalReadGc(0x08);
Seq2 = HalReadSeq(0x02);
Seq4 = HalReadSeq(0x04);
/* Force into colour mode. */
WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, (UCHAR)(MiscOut | 0x10));
HalBlankScreen(FALSE);
HalWriteGc(0x03, 0x00); /* Don't rotate; write unmodified. */
HalWriteGc(0x08, 0xFF); /* Write all bits. */
HalWriteGc(0x01, 0x00); /* All planes from CPU. */
for (i = 0; i < 2; i++)
{
HalWriteSeq(0x02, (UCHAR)(0x04 << i)); /* Write to plane 2 or 3 */
HalWriteSeq(0x04, 0x06); /* Enable plane graphics. */
HalWriteGc(0x04, (UCHAR)(0x02 + i)); /* Read plane 2 or 3 */
HalWriteGc(0x05, 0x00); /* Write mode 0; read mode 0. */
HalWriteGc(0x06, 0x05); /* Set graphics. */
memcpy(GraphVideoBuffer, SavedTextFont[i], FONT_AMOUNT);
}
HalBlankScreen(TRUE);
/* Restore registers. */
WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, MiscOut);
HalWriteAc(0x10, Attr10);
HalWriteGc(0x01, Gc1);
HalWriteGc(0x03, Gc3);
HalWriteGc(0x04, Gc4);
HalWriteGc(0x05, Gc5);
HalWriteGc(0x06, Gc6);
HalWriteGc(0x08, Gc8);
HalWriteSeq(0x02, Seq2);
HalWriteSeq(0x04, Seq4);
}
VOID STATIC
HalRestoreMode(VOID)
{
ULONG i;
WRITE_PORT_UCHAR((PUCHAR)VGA_MISC_WRITE, SavedTextMiscOutReg);
for (i = 1; i < VGA_SEQ_NUM_REGISTERS; i++)
{
HalWriteSeq(i, SavedTextSeqReg[i]);
}
/* Unlock CRTC registers 0-7 */
HalWriteCrtc(17, (UCHAR)(SavedTextCrtcReg[17] & ~0x80));
for (i = 0; i < VGA_CRTC_NUM_REGISTERS; i++)
{
HalWriteCrtc(i, SavedTextCrtcReg[i]);
}
for (i = 0; i < VGA_GC_NUM_REGISTERS; i++)
{
HalWriteGc(i, SavedTextGcReg[i]);
}
HalEnablePalette();
for (i = 0; i < VGA_AC_NUM_REGISTERS; i++)
{
HalWriteAc(i, SavedTextAcReg[i]);
}
HalDisablePalette();
}
VOID STATIC
HalRestorePalette(VOID)
{
ULONG i;
WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_MASK, 0xFF);
WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_WRITE_INDEX, 0x00);
for (i = 0; i < 768; i++)
{
WRITE_PORT_UCHAR((PUCHAR)VGA_DAC_DATA, SavedTextPalette[i]);
HalDacDelay();
}
HalDisablePalette();
}
/* PRIVATE FUNCTIONS ********************************************************/
VOID FASTCALL
HalInitializeDisplay (PLOADER_PARAMETER_BLOCK LoaderBlock)
/*
* FUNCTION: Initalize the display
* ARGUMENTS:
* InitParameters = Parameters setup by the boot loader
*/
{
PHYSICAL_ADDRESS PhysBuffer;
if (! DisplayInitialized)
{
ULONG ScanLines;
ULONG Data;
PhysBuffer.u.HighPart = 0;
PhysBuffer.u.LowPart = VGA_GRAPH_MEM;
GraphVideoBuffer = MmMapIoSpace(PhysBuffer, VGA_END_MEM - VGA_GRAPH_MEM + 1, MmNonCached);
if (NULL == GraphVideoBuffer)
{
return;
}
VideoBuffer = (PUSHORT) (GraphVideoBuffer + (VGA_CHAR_MEM - VGA_GRAPH_MEM));
/* Set cursor position */
// CursorX = LoaderBlock->cursorx;
// CursorY = LoaderBlock->cursory;
CursorX = 0;
CursorY = 0;
/* read screen size from the crtc */
/* FIXME: screen size should be read from the boot parameters */
WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_COLUMNS);
SizeX = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA) + 1;
WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_ROWS);
SizeY = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA);
WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_OVERFLOW);
Data = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA);
SizeY |= (((Data & 0x02) << 7) | ((Data & 0x40) << 3));
SizeY++;
WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_SCANLINES);
ScanLines = (READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA) & 0x1F) + 1;
SizeY = SizeY / ScanLines;
#ifdef BOCHS_30ROWS
SizeY=30;
#endif
HalClearDisplay(CHAR_ATTRIBUTE_BLACK);
DisplayInitialized = TRUE;
/*
Save the VGA state at this point so we can restore it on a bugcheck.
*/
HalSavePalette();
HalSaveMode();
HalSaveFont();
}
}
#include <ndk/inbvfuncs.h>
/* PUBLIC FUNCTIONS *********************************************************/
VOID STDCALL
HalReleaseDisplayOwnership(VOID)
/*
* FUNCTION: Release ownership of display back to HAL
*/
{
if (HalResetDisplayParameters == NULL)
return;
if (HalOwnsDisplay == TRUE)
return;
if (!HalResetDisplayParameters(SizeX, SizeY))
{
HalRestoreMode();
HalRestoreFont();
HalRestorePalette();
}
HalOwnsDisplay = TRUE;
HalClearDisplay(CHAR_ATTRIBUTE);
}
VOID STDCALL
HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters)
/*
@ -665,12 +33,11 @@ HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParamete
* reset routine.
*/
{
HalOwnsDisplay = FALSE;
HalResetDisplayParameters = ResetDisplayParameters;
}
VOID STDCALL
HalDisplayString(IN PCH String)
HalDisplayString(
IN PCH String)
/*
* FUNCTION: Switches the screen to HAL console mode (BSOD) if not there
* already and displays a string
@ -680,85 +47,7 @@ HalDisplayString(IN PCH String)
* mode
*/
{
PCH pch;
#ifdef SCREEN_SYNCHRONIZATION
int offset;
#endif
static KSPIN_LOCK Lock;
KIRQL OldIrql;
ULONG Flags;
/* See comment at top of file */
if (! HalOwnsDisplay || ! DisplayInitialized)
{
return;
}
pch = String;
OldIrql = KfRaiseIrql(HIGH_LEVEL);
KiAcquireSpinLock(&Lock);
Ki386SaveFlags(Flags);
Ki386DisableInterrupts();
#ifdef SCREEN_SYNCHRONIZATION
WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURHI);
offset = READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA)<<8;
WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURLO);
offset += READ_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA);
CursorY = offset / SizeX;
CursorX = offset % SizeX;
#endif
while (*pch != 0)
{
if (*pch == '\n')
{
CursorY++;
CursorX = 0;
}
else if (*pch == '\b')
{
if (CursorX > 0)
{
CursorX--;
}
}
else if (*pch != '\r')
{
HalPutCharacter (*pch);
CursorX++;
if (CursorX >= SizeX)
{
CursorY++;
CursorX = 0;
}
}
if (CursorY >= SizeY)
{
HalScrollDisplay ();
CursorY = SizeY - 1;
}
pch++;
}
#ifdef SCREEN_SYNCHRONIZATION
offset = (CursorY * SizeX) + CursorX;
WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURLO);
WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, (UCHAR)(offset & 0xff));
WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_INDEX, CRTC_CURHI);
WRITE_PORT_UCHAR((PUCHAR)VGA_CRTC_DATA, (UCHAR)((offset >> 8) & 0xff));
#endif
Ki386RestoreFlags(Flags);
KiReleaseSpinLock(&Lock);
KfLowerIrql(OldIrql);
InbvDisplayString(String);
}
VOID STDCALL
@ -767,14 +56,6 @@ HalQueryDisplayParameters(OUT PULONG DispSizeX,
OUT PULONG CursorPosX,
OUT PULONG CursorPosY)
{
if (DispSizeX)
*DispSizeX = SizeX;
if (DispSizeY)
*DispSizeY = SizeY;
if (CursorPosX)
*CursorPosX = CursorX;
if (CursorPosY)
*CursorPosY = CursorY;
}
@ -782,15 +63,6 @@ VOID STDCALL
HalSetDisplayParameters(IN ULONG CursorPosX,
IN ULONG CursorPosY)
{
CursorX = (CursorPosX < SizeX) ? CursorPosX : SizeX - 1;
CursorY = (CursorPosY < SizeY) ? CursorPosY : SizeY - 1;
}
BOOLEAN STDCALL
HalQueryDisplayOwnership(VOID)
{
return !HalOwnsDisplay;
}
/* EOF */

View file

@ -1565,6 +1565,9 @@ IoFlushAdapterBuffers(
{
BOOLEAN SlaveDma = FALSE;
PROS_MAP_REGISTER_ENTRY RealMapRegisterBase;
PHYSICAL_ADDRESS HighestAcceptableAddress;
PHYSICAL_ADDRESS PhysicalAddress;
PPFN_NUMBER MdlPagesPtr;
ASSERT_IRQL(DISPATCH_LEVEL);
@ -1601,14 +1604,23 @@ IoFlushAdapterBuffers(
{
if (SlaveDma && !AdapterObject->IgnoreCount)
Length -= HalReadDmaCounter(AdapterObject);
}
HalpCopyBufferMap(Mdl, RealMapRegisterBase, CurrentVa, Length, FALSE);
}
}
else
{
/* FIXME: Unimplemented case */
ASSERT(FALSE);
MdlPagesPtr = MmGetMdlPfnArray(Mdl);
MdlPagesPtr += ((ULONG_PTR)CurrentVa - (ULONG_PTR)Mdl->StartVa) >> PAGE_SHIFT;
PhysicalAddress.QuadPart = *MdlPagesPtr << PAGE_SHIFT;
PhysicalAddress.QuadPart += BYTE_OFFSET(CurrentVa);
HighestAcceptableAddress = HalpGetAdapterMaximumPhysicalAddress(AdapterObject);
if (PhysicalAddress.QuadPart + Length >
HighestAcceptableAddress.QuadPart)
{
HalpCopyBufferMap(Mdl, RealMapRegisterBase, CurrentVa, Length, FALSE);
}
}
}
@ -1793,11 +1805,12 @@ IoMapTransfer(
HighestAcceptableAddress.QuadPart)
{
UseMapRegisters = TRUE;
PhysicalAddress = RealMapRegisterBase->PhysicalAddress;
PhysicalAddress = RealMapRegisterBase[Counter].PhysicalAddress;
PhysicalAddress.QuadPart += ByteOffset;
if ((ULONG_PTR)MapRegisterBase & MAP_BASE_SW_SG)
{
RealMapRegisterBase->Counter = ~0;
Counter = 0;
}
}
}

View file

@ -46,7 +46,6 @@ HalInitSystem (ULONG BootPhase,
//HalpInitPhase1();
/* Initialize display and make the screen black */
HalInitializeDisplay (LoaderBlock);
HalpInitBusHandlers();
HalpInitDma();
@ -55,12 +54,7 @@ HalInitSystem (ULONG BootPhase,
}
else if (BootPhase == 2)
{
PHYSICAL_ADDRESS Null = {{0}};
/* Go to blue screen */
HalClearDisplay (0x17); /* grey on blue */
HalpZeroPageMapping = MmMapIoSpace(Null, PAGE_SIZE, MmNonCached);
HalpZeroPageMapping = MmMapIoSpace((LARGE_INTEGER)0LL, PAGE_SIZE, MmNonCached);
}
return TRUE;

View file

@ -17,11 +17,6 @@ typedef struct _KD_PORT_INFORMATION
ULONG BaudRate;
ULONG BaseAddress;
} KD_PORT_INFORMATION, *PKD_PORT_INFORMATION;
/* display.c */
VOID FASTCALL HalInitializeDisplay (struct _LOADER_PARAMETER_BLOCK *LoaderBlock);
VOID FASTCALL HalClearDisplay (UCHAR CharAttribute);
/* adapter.c */
PADAPTER_OBJECT STDCALL HalpAllocateAdapterEx(ULONG NumberOfMapRegisters,BOOLEAN IsMaster, BOOLEAN Dma32BitAddresses);

View file

@ -786,6 +786,9 @@ ExpInitializeExecutive(IN ULONG Cpu,
/* Set up Region Maps, Sections and the Paging File */
MmInit2();
/* Initialize the boot video. */
InbvDisplayInitialize();
/* Initialize the Process Manager */
if (!PsInitSystem()) KEBUGCHECK(PROCESS_INITIALIZATION_FAILED);
@ -832,6 +835,10 @@ ExPhase2Init(PVOID Context)
/* Check if GUI Boot is enabled */
if (strstr(KeLoaderBlock->LoadOptions, "NOGUIBOOT")) NoGuiBoot = TRUE;
/* Display the boot screen image if not disabled */
if (!ExpInTextModeSetup) InbvDisplayInitialize2(NoGuiBoot);
if (!NoGuiBoot) InbvDisplayBootLogo();
/* Clear the screen to blue and display the boot notice and debug status */
HalInitSystem(2, KeLoaderBlock);
if (NoGuiBoot) ExpDisplayNotice();
@ -923,9 +930,6 @@ ExPhase2Init(PVOID Context)
/* Initialize the I/O Subsystem */
if (!IoInitSystem(KeLoaderBlock)) KeBugCheck(IO1_INITIALIZATION_FAILED);
/* Display the boot screen image if not disabled */
if (!NoGuiBoot) InbvEnableBootDriver(TRUE);
/* Unmap Low memory, and initialize the MPW and Balancer Thread */
MmInit3();
@ -955,12 +959,6 @@ ExPhase2Init(PVOID Context)
ZwClose(ThreadHandle);
ZwClose(ProcessHandle);
/*
* FIXME: FILIP!
* Disable the Boot Logo
*/
if (!NoGuiBoot) InbvEnableBootDriver(FALSE);
/* FIXME: We should free the initial process' memory!*/
/* Increase init phase */

View file

@ -142,7 +142,16 @@ ShutdownThreadMain(PVOID Context)
/* Run the thread on the boot processor */
KeSetSystemAffinityThread(1);
HalReleaseDisplayOwnership();
if (InbvIsBootDriverInstalled())
{
InbvAcquireDisplayOwnership();
InbvResetDisplay();
InbvSolidColorFill(0, 0, 639, 479, 4);
InbvSetTextColor(15);
InbvInstallDisplayStringFilter(NULL);
InbvEnableDisplayString(TRUE);
InbvSetScrollRegion(0, 0, 639, 479);
}
if (Action == ShutdownNoReboot)
{

View file

@ -11,209 +11,250 @@
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
#include "../../drivers/base/bootvid/ntbootvid.h"
#define NDEBUG
#include <internal/debug.h>
#if defined (ALLOC_PRAGMA)
#pragma alloc_text(INIT, InbvEnableBootDriver)
#pragma alloc_text(INIT, InbvDisplayInitialize)
#endif
/* ROS Internal. Please deprecate */
NTHALAPI
VOID
NTAPI
HalReleaseDisplayOwnership(VOID);
/* GLOBALS *******************************************************************/
/* DATA **********************************************************************/
static HANDLE BootVidDevice = NULL;
static BOOLEAN BootVidDriverInstalled = FALSE;
static NTBOOTVID_FUNCTION_TABLE BootVidFunctionTable;
static BOOLEAN (NTAPI *VidInitialize)(BOOLEAN);
static VOID (NTAPI *VidCleanUp)(VOID);
static VOID (NTAPI *VidResetDisplay)(VOID);
static VOID (NTAPI *VidBufferToScreenBlt)(PUCHAR, ULONG, ULONG, ULONG, ULONG, ULONG);
static VOID (NTAPI *VidScreenToBufferBlt)(PUCHAR, ULONG, ULONG, ULONG, ULONG, ULONG);
static VOID (NTAPI *VidBitBlt)(PUCHAR, ULONG, ULONG);
static VOID (NTAPI *VidSolidColorFill)(ULONG, ULONG, ULONG, ULONG, ULONG);
static VOID (NTAPI *VidDisplayString)(PUCHAR);
static NTSTATUS (NTAPI *BootVidDisplayBootLogo)(PVOID);
static VOID (NTAPI *BootVidUpdateProgress)(ULONG Progress);
static VOID (NTAPI *BootVidFinalizeBootLogo)(VOID);
static KSPIN_LOCK InbvLock;
static KIRQL InbvOldIrql;
static ULONG InbvDisplayState = 0;
static PHAL_RESET_DISPLAY_PARAMETERS InbvResetDisplayParameters = NULL;
static PVOID BootVidBase;
/* FUNCTIONS *****************************************************************/
NTSTATUS
static
InbvCheckBootVid(VOID)
{
IO_STATUS_BLOCK Iosb;
if (BootVidDevice == NULL)
VOID NTAPI INIT_FUNCTION
InbvDisplayInitialize(VOID)
{
struct {
ANSI_STRING Name;
PVOID *Ptr;
} Exports[] = {
{ RTL_CONSTANT_STRING("VidInitialize"), (PVOID*)&VidInitialize },
{ RTL_CONSTANT_STRING("VidCleanUp"), (PVOID*)&VidCleanUp },
{ RTL_CONSTANT_STRING("VidResetDisplay"), (PVOID*)&VidResetDisplay },
{ RTL_CONSTANT_STRING("VidBufferToScreenBlt"), (PVOID*)&VidBufferToScreenBlt },
{ RTL_CONSTANT_STRING("VidScreenToBufferBlt"), (PVOID*)&VidScreenToBufferBlt },
{ RTL_CONSTANT_STRING("VidBitBlt"), (PVOID*)&VidBitBlt },
{ RTL_CONSTANT_STRING("VidSolidColorFill"), (PVOID*)&VidSolidColorFill },
{ RTL_CONSTANT_STRING("VidDisplayString"), (PVOID*)&VidDisplayString },
{ RTL_CONSTANT_STRING("BootVidDisplayBootLogo"), (PVOID*)&BootVidDisplayBootLogo },
{ RTL_CONSTANT_STRING("BootVidUpdateProgress"), (PVOID*)&BootVidUpdateProgress },
{ RTL_CONSTANT_STRING("BootVidFinalizeBootLogo"), (PVOID*)&BootVidFinalizeBootLogo }
};
UNICODE_STRING BootVidPath = RTL_CONSTANT_STRING(L"bootvid.sys");
PLDR_DATA_TABLE_ENTRY ModuleObject = NULL, LdrEntry;
ULONG Index;
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING BootVidName = RTL_CONSTANT_STRING(L"\\Device\\BootVid");
InitializeObjectAttributes(&ObjectAttributes,
&BootVidName,
0,
NULL,
NULL);
Status = ZwOpenFile(&BootVidDevice,
FILE_ALL_ACCESS,
&ObjectAttributes,
&Iosb,
0,
0);
/* FIXME: Hack, try to search for boot driver. */
#if 0
ModuleObject = LdrGetModuleObject(&BootVidPath);
#else
{
NTSTATUS LdrProcessModule(PVOID, PUNICODE_STRING, PLDR_DATA_TABLE_ENTRY*);
PLIST_ENTRY ListHead, NextEntry;
ListHead = &KeLoaderBlock->LoadOrderListHead;
NextEntry = ListHead->Flink;
while (ListHead != NextEntry)
{
/* Get the entry */
LdrEntry = CONTAINING_RECORD(NextEntry,
LDR_DATA_TABLE_ENTRY,
InLoadOrderLinks);
/* Compare names */
if (RtlEqualUnicodeString(&LdrEntry->BaseDllName, &BootVidPath, TRUE))
{
/* Tell, that the module is already loaded */
LdrEntry->Flags |= LDRP_ENTRY_INSERTED;
Status = LdrProcessModule(LdrEntry->DllBase,
&BootVidPath,
&ModuleObject);
if (!NT_SUCCESS(Status))
{
return(Status);
DPRINT1("%x\n", Status);
return;
}
}
return(STATUS_SUCCESS);
break;
}
/* Go to the next driver */
NextEntry= NextEntry->Flink;
}
}
#endif
VOID
STDCALL
if (ModuleObject != NULL)
{
for (Index = 0; Index < sizeof(Exports) / sizeof(Exports[0]); Index++)
{
Status = LdrGetProcedureAddress(ModuleObject->DllBase,
&Exports[Index].Name, 0,
Exports[Index].Ptr);
if (!NT_SUCCESS(Status))
return;
}
DPRINT1("Done!\n");
KeInitializeSpinLock(&InbvLock);
BootVidBase = ModuleObject->DllBase;
BootVidDriverInstalled = TRUE;
}
}
static VOID NTAPI
InbvAcquireLock(VOID)
{
if ((InbvOldIrql = KeGetCurrentIrql()) < DISPATCH_LEVEL)
InbvOldIrql = KfRaiseIrql(DISPATCH_LEVEL);
KiAcquireSpinLock(&InbvLock);
}
static VOID NTAPI
InbvReleaseLock(VOID)
{
KiReleaseSpinLock(&InbvLock);
if (InbvOldIrql < DISPATCH_LEVEL)
KfLowerIrql(InbvOldIrql);
}
VOID STDCALL
InbvEnableBootDriver(IN BOOLEAN Enable)
{
if (BootVidDriverInstalled)
{
if (InbvDisplayState >= 2)
return;
InbvAcquireLock();
if (InbvDisplayState == 0)
VidCleanUp();
InbvDisplayState = !Enable;
InbvReleaseLock();
}
else
{
InbvDisplayState = !Enable;
}
}
VOID NTAPI
InbvAcquireDisplayOwnership(VOID)
{
if (InbvResetDisplayParameters && InbvDisplayState == 2)
{
if (InbvResetDisplayParameters != NULL)
InbvResetDisplayParameters(80, 50);
}
InbvDisplayState = 0;
}
BOOLEAN
STDCALL
BOOLEAN STDCALL
InbvCheckDisplayOwnership(VOID)
{
return FALSE;
return InbvDisplayState != 2;
}
BOOLEAN
STDCALL
BOOLEAN STDCALL
InbvDisplayString(IN PCHAR String)
{
/* Call Bootvid (we don't support bootvid for now)
* vidDisplayString(String);
* so instead, we'll fall-back to HAL
*/
HalDisplayString(String);
if (BootVidDriverInstalled && InbvDisplayState == 0)
{
InbvAcquireLock();
VidDisplayString(String);
InbvReleaseLock();
/* Call Headless (We don't support headless for now)
HeadlessDispatch(DISPLAY_STRING);
*/
/* Return success */
return TRUE;
}
BOOLEAN
STDCALL
InbvResetDisplayParameters(ULONG SizeX,
ULONG SizeY)
{
return(InbvResetDisplay());
return FALSE;
}
VOID
STDCALL
INIT_FUNCTION
InbvEnableBootDriver(IN BOOLEAN Enable)
{
NTSTATUS Status;
IO_STATUS_BLOCK Iosb;
Status = InbvCheckBootVid();
if (!NT_SUCCESS(Status))
{
return;
}
if (Enable)
{
/* Notify the hal we will acquire the display. */
HalAcquireDisplayOwnership(InbvResetDisplayParameters);
Status = ZwDeviceIoControlFile(BootVidDevice,
NULL,
NULL,
NULL,
&Iosb,
IOCTL_BOOTVID_INITIALIZE,
NULL,
0,
&BootVidFunctionTable,
sizeof(BootVidFunctionTable));
if (!NT_SUCCESS(Status))
{
KEBUGCHECK(0);
}
BootVidDriverInstalled = TRUE;
CHECKPOINT;
}
else
{
Status = ZwDeviceIoControlFile(BootVidDevice,
NULL,
NULL,
NULL,
&Iosb,
IOCTL_BOOTVID_CLEANUP,
NULL,
0,
NULL,
0);
if (!NT_SUCCESS(Status))
{
KEBUGCHECK(0);
}
BootVidDriverInstalled = FALSE;
/* Notify the hal we have released the display. */
HalReleaseDisplayOwnership();
}
ZwClose(BootVidDevice);
BootVidDevice = NULL;
}
BOOLEAN
STDCALL
BOOLEAN STDCALL
InbvEnableDisplayString(IN BOOLEAN Enable)
{
return FALSE;
}
VOID
STDCALL
VOID STDCALL
InbvInstallDisplayStringFilter(IN PVOID Unknown)
{
}
BOOLEAN
STDCALL
BOOLEAN STDCALL
InbvIsBootDriverInstalled(VOID)
{
return(BootVidDriverInstalled);
return BootVidDriverInstalled;
}
VOID
STDCALL
InbvNotifyDisplayOwnershipLost(IN PVOID Callback)
VOID STDCALL
InbvNotifyDisplayOwnershipLost(
IN PVOID Callback)
{
if (BootVidDriverInstalled)
{
InbvAcquireLock();
if (InbvDisplayState != 2)
VidCleanUp();
else if (InbvResetDisplayParameters != NULL)
InbvResetDisplayParameters(80, 50);
InbvResetDisplayParameters = Callback;
InbvDisplayState = 2;
InbvReleaseLock();
}
else
{
InbvResetDisplayParameters = Callback;
InbvDisplayState = 2;
}
}
BOOLEAN
STDCALL
BOOLEAN STDCALL
InbvResetDisplay(VOID)
{
if (!BootVidDriverInstalled)
if (BootVidDriverInstalled && InbvDisplayState == 0)
{
return(FALSE);
VidResetDisplay();
return TRUE;
}
return(BootVidFunctionTable.ResetDisplay());
return FALSE;
}
VOID
STDCALL
InbvSetScrollRegion(IN ULONG Left,
VOID STDCALL
InbvSetScrollRegion(
IN ULONG Left,
IN ULONG Top,
IN ULONG Width,
IN ULONG Height)
@ -221,31 +262,88 @@ InbvSetScrollRegion(IN ULONG Left,
}
VOID
STDCALL
InbvSetTextColor(IN ULONG Color)
VOID STDCALL
InbvSetTextColor(
IN ULONG Color)
{
}
VOID
STDCALL
InbvSolidColorFill(IN ULONG Left,
VOID STDCALL
InbvSolidColorFill(
IN ULONG Left,
IN ULONG Top,
IN ULONG Width,
IN ULONG Height,
IN ULONG Color)
{
if (BootVidDriverInstalled && InbvDisplayState == 0)
{
VidSolidColorFill(Left, Top, Width, Height, Color);
}
}
NTSTATUS
STDCALL
NtDisplayString(IN PUNICODE_STRING DisplayString)
BOOLEAN NTAPI
BootVidResetDisplayParameters(ULONG SizeX, ULONG SizeY)
{
BootVidFinalizeBootLogo();
return TRUE;
}
VOID NTAPI
InbvDisplayInitialize2(BOOLEAN NoGuiBoot)
{
VidInitialize(!NoGuiBoot);
}
VOID NTAPI
InbvDisplayBootLogo(VOID)
{
InbvEnableBootDriver(TRUE);
if (BootVidDriverInstalled)
{
InbvResetDisplayParameters = BootVidResetDisplayParameters;
BootVidDisplayBootLogo(BootVidBase);
}
}
VOID NTAPI
InbvUpdateProgressBar(
IN ULONG Progress)
{
if (BootVidDriverInstalled)
{
BootVidUpdateProgress(Progress);
}
}
VOID NTAPI
InbvFinalizeBootLogo(VOID)
{
if (BootVidDriverInstalled)
{
/* Notify the hal we have released the display. */
/* InbvReleaseDisplayOwnership(); */
BootVidFinalizeBootLogo();
InbvEnableBootDriver(FALSE);
}
}
NTSTATUS STDCALL
NtDisplayString(
IN PUNICODE_STRING DisplayString)
{
OEM_STRING OemString;
RtlUnicodeStringToOemString(&OemString, DisplayString, TRUE);
HalDisplayString(OemString.Buffer);
InbvDisplayString(OemString.Buffer);
RtlFreeOemString(&OemString);
return STATUS_SUCCESS;

View file

@ -7,9 +7,21 @@
/* FUNCTIONS *****************************************************************/
BOOLEAN
NTAPI
InbvDisplayString(IN PCHAR String);
VOID NTAPI INIT_FUNCTION
InbvDisplayInitialize(VOID);
VOID NTAPI
InbvDisplayInitialize2(BOOLEAN NoGuiBoot);
VOID NTAPI
InbvDisplayBootLogo(VOID);
VOID NTAPI
InbvUpdateProgressBar(ULONG Progress);
VOID NTAPI
InbvFinalizeBootLogo(VOID);
#endif /* NTOSKRNL_INBV_H */

View file

@ -1140,7 +1140,7 @@ KdbpInternalEnter()
KbdDisableMouse();
if (KdpDebugMode.Screen)
{
HalReleaseDisplayOwnership();
InbvAcquireDisplayOwnership();
}
/* Call the interface's main loop on a different stack */

View file

@ -16,14 +16,6 @@
#pragma alloc_text(INIT, KiInitializeBugCheck)
#endif
/* ROS Internal. Please deprecate */
NTHALAPI
VOID
NTAPI
HalReleaseDisplayOwnership(
VOID
);
/* GLOBALS *******************************************************************/
LIST_ENTRY BugcheckCallbackListHead;
@ -435,8 +427,6 @@ KiDisplayBlueScreen(IN ULONG MessageId,
{
CHAR AnsiName[75];
/* FIXMEs: Use inbv to clear, fill and write to screen. */
/* Check if this is a hard error */
if (IsHardError)
{
@ -847,8 +837,18 @@ KeBugCheckWithTf(IN ULONG BugCheckCode,
}
}
/* Switching back to the blue screen so we print messages on it */
HalReleaseDisplayOwnership();
/* Use the boot video driver to clear, fill and write to screen. */
if (InbvIsBootDriverInstalled())
{
/* FIXME: This should happen in KiDisplayBlueScreen!!! */
InbvAcquireDisplayOwnership();
InbvResetDisplay();
InbvSolidColorFill(0, 0, 639, 479, 4);
InbvSetTextColor(15);
InbvInstallDisplayStringFilter(NULL);
InbvEnableDisplayString(TRUE);
InbvSetScrollRegion(0, 0, 639, 479);
}
/* Raise IRQL to HIGH_LEVEL */
Ke386DisableInterrupts();

View file

@ -16,10 +16,6 @@
/* FIXME: Is there a way to create real aliasses with gcc? [CSH] */
#define ALIAS(Name, Target) typeof(Target) Name = Target
/* Private user32 routines for CSRSS, not defined in any header file */
extern VOID STDCALL PrivateCsrssRegisterPrimitive(VOID);
extern VOID STDCALL PrivateCsrssAcquireOrReleaseInputOwnership(BOOL Release);
/* GLOBALS *******************************************************************/
#define ConioInitRect(Rect, Top, Left, Bottom, Right) \
@ -1422,37 +1418,6 @@ ConioProcessKey(MSG *msg, PCSRSS_CONSOLE Console, BOOL TextMode)
}
}
DWORD STDCALL
Console_Api (PVOID unused)
{
/* keep reading events from the keyboard and stuffing them into the current
console's input queue */
MSG msg;
/* This call establishes our message queue */
PeekMessageW(&msg, 0, 0, 0, PM_NOREMOVE);
/* This call registers our message queue */
PrivateCsrssRegisterPrimitive();
/* This call turns on the input system in win32k */
PrivateCsrssAcquireOrReleaseInputOwnership(FALSE);
while (TRUE)
{
GetMessageW(&msg, 0, 0, 0);
TranslateMessage(&msg);
if (msg.message == WM_CHAR || msg.message == WM_SYSCHAR ||
msg.message == WM_KEYDOWN || msg.message == WM_KEYUP ||
msg.message == WM_SYSKEYDOWN || msg.message == WM_SYSKEYUP)
{
ConioProcessKey(&msg, TuiGetFocusConsole(), TRUE);
}
}
PrivateCsrssAcquireOrReleaseInputOwnership(TRUE);
return 0;
}
CSR_API(CsrGetScreenBufferInfo)
{
NTSTATUS Status;

View file

@ -170,20 +170,11 @@ Win32CsrInitialization(PCSRSS_API_DEFINITION *ApiDefinitions,
PCSRSS_EXPORTED_FUNCS Exports,
HANDLE CsrssApiHeap)
{
HANDLE ThreadHandle;
CsrExports = *Exports;
Win32CsrApiHeap = CsrssApiHeap;
PrivateCsrssManualGuiCheck(0);
CsrInitConsoleSupport();
ThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) Console_Api, NULL, 0, NULL);
if (NULL == ThreadHandle)
{
DPRINT1("CSR: Unable to create console thread\n");
return FALSE;
}
CloseHandle(ThreadHandle);
*ApiDefinitions = Win32CsrApiDefinitions;
*ObjectDefinitions = Win32CsrObjectDefinitions;

View file

@ -18,11 +18,28 @@ static PCSRSS_CONSOLE ActiveConsole;
static BOOL ConsInitialized = FALSE;
static LRESULT CALLBACK
TuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (msg == WM_ACTIVATE)
{
CHECKPOINT1;
if (LOWORD(wParam) != WA_INACTIVE)
{
CHECKPOINT1;
SetFocus(hWnd);
ConioDrawConsole(ActiveConsole);
}
}
return DefWindowProcW(hWnd, msg, wParam, lParam);
}
static BOOL FASTCALL
TuiInit(VOID)
{
CONSOLE_SCREEN_BUFFER_INFO ScrInfo;
DWORD BytesReturned;
WNDCLASSEXW wc;
ConsoleDeviceHandle = CreateFileW(L"\\\\.\\BlueScreen", FILE_ALL_ACCESS, 0, NULL,
OPEN_EXISTING, 0, NULL);
@ -42,6 +59,17 @@ TuiInit(VOID)
}
PhysicalConsoleSize = ScrInfo.dwSize;
RtlZeroMemory(&wc, sizeof(WNDCLASSEXW));
wc.cbSize = sizeof(WNDCLASSEXW);
wc.lpszClassName = L"TuiConsoleWindowClass";
wc.lpfnWndProc = TuiConsoleWndProc;
wc.hInstance = (HINSTANCE) GetModuleHandleW(NULL);
if (RegisterClassExW(&wc) == 0)
{
DPRINT1("Failed to register console wndproc\n");
return FALSE;
}
return TRUE;
}
@ -194,6 +222,8 @@ TuiChangeTitle(PCSRSS_CONSOLE Console)
static VOID STDCALL
TuiCleanupConsole(PCSRSS_CONSOLE Console)
{
DestroyWindow(Console->hWindow);
EnterCriticalSection(&ActiveConsoleLock);
/* Switch to next console */
@ -215,6 +245,47 @@ TuiCleanupConsole(PCSRSS_CONSOLE Console)
}
}
DWORD STDCALL
TuiConsoleThread (PVOID Data)
{
PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Data;
HWND NewWindow;
MSG msg;
NewWindow = CreateWindowW(L"TuiConsoleWindowClass",
Console->Title.Buffer,
0,
-32000, -32000, 0, 0,
NULL, NULL,
(HINSTANCE) GetModuleHandleW(NULL),
(PVOID) Console);
Console->hWindow = NewWindow;
if (NULL == NewWindow)
{
DPRINT1("CSR: Unable to create console window\n");
return 1;
}
SetForegroundWindow(Console->hWindow);
while (TRUE)
{
GetMessageW(&msg, 0, 0, 0);
DispatchMessage(&msg);
TranslateMessage(&msg);
if (msg.message == WM_CHAR || msg.message == WM_SYSCHAR ||
msg.message == WM_KEYDOWN || msg.message == WM_KEYUP ||
msg.message == WM_SYSKEYDOWN || msg.message == WM_SYSKEYUP)
{
CHECKPOINT1;
ConioProcessKey(&msg, Console, TRUE);
}
}
return 0;
}
static CSRSS_CONSOLE_VTBL TuiVtbl =
{
TuiInitScreenBuffer,
@ -229,6 +300,8 @@ static CSRSS_CONSOLE_VTBL TuiVtbl =
NTSTATUS FASTCALL
TuiInitConsole(PCSRSS_CONSOLE Console)
{
HANDLE ThreadHandle;
if (! ConsInitialized)
{
ConsInitialized = TRUE;
@ -240,11 +313,20 @@ TuiInitConsole(PCSRSS_CONSOLE Console)
}
Console->Vtbl = &TuiVtbl;
Console->hWindow = (HWND) NULL;
Console->hWindow = NULL;
Console->Size = PhysicalConsoleSize;
Console->ActiveBuffer->MaxX = PhysicalConsoleSize.X;
Console->ActiveBuffer->MaxY = PhysicalConsoleSize.Y;
ThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) TuiConsoleThread,
Console, 0, NULL);
if (NULL == ThreadHandle)
{
DPRINT1("CSR: Unable to create console thread\n");
return STATUS_UNSUCCESSFUL;
}
CloseHandle(ThreadHandle);
EnterCriticalSection(&ActiveConsoleLock);
if (NULL != ActiveConsole)
{

View file

@ -5,10 +5,10 @@
#include <include/msgqueue.h>
#include <include/window.h>
VOID FASTCALL
IntValidateParent(PWINDOW_OBJECT Child, HRGN ValidRegion);
BOOL FASTCALL
co_UserRedrawWindow(PWINDOW_OBJECT Wnd, const RECT* UpdateRect, HRGN UpdateRgn, ULONG Flags);
VOID FASTCALL
IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags);
BOOL FASTCALL
IntGetPaintMessage(HWND hWnd, UINT MsgFilterMin, UINT MsgFilterMax, PW32THREAD Thread,
MSG *Message, BOOL Remove);

View file

@ -88,11 +88,6 @@ PVOID UserGetNextHandle(PUSER_HANDLE_TABLE ht, HANDLE* handle, USER_OBJECT_TYPE
HWINSTA FASTCALL UserGetProcessWindowStation(VOID);
/*************** INPUT.C ***************/
NTSTATUS FASTCALL
UserAcquireOrReleaseInputOwnership(BOOLEAN Release);
/*************** WINPOS.C ***************/
BOOL FASTCALL

View file

@ -89,6 +89,7 @@ co_IntSendActivateMessages(HWND hWndPrev, HWND hWnd, BOOL MouseActivate)
/* FIXME: IntIsWindow */
CHECKPOINT1;
co_IntPostOrSendMessage(hWnd, WM_NCACTIVATE, (WPARAM)(hWnd == UserGetForegroundWindow()), 0);
/* FIXME: WA_CLICKACTIVE */
co_IntPostOrSendMessage(hWnd, WM_ACTIVATE,
@ -158,7 +159,8 @@ co_IntSetForegroundAndFocusWindow(PWINDOW_OBJECT Window, PWINDOW_OBJECT FocusWin
return FALSE;
}
if (0 == (Window->Style & WS_VISIBLE))
if (0 == (Window->Style & WS_VISIBLE) &&
Window->OwnerThread->ThreadsProcess != CsrProcess)
{
DPRINT("Failed - Invisible\n");
return FALSE;
@ -172,7 +174,7 @@ co_IntSetForegroundAndFocusWindow(PWINDOW_OBJECT Window, PWINDOW_OBJECT FocusWin
if (hWndPrev == hWnd)
{
DPRINT("Failed - Same\n");
DPRINT1("Failed - Same\n");
return TRUE;
}
@ -200,6 +202,7 @@ co_IntSetForegroundAndFocusWindow(PWINDOW_OBJECT Window, PWINDOW_OBJECT FocusWin
/* FIXME: Send WM_ACTIVATEAPP to all thread windows. */
}
CHECKPOINT1;
co_IntSendSetFocusMessages(hWndFocusPrev, hWndFocus);
co_IntSendActivateMessages(hWndPrev, hWnd, MouseActivate);
@ -272,7 +275,8 @@ co_IntSetActiveWindow(PWINDOW_OBJECT Window OPTIONAL)
if (Window != 0)
{
if (!(Window->Style & WS_VISIBLE) ||
if ((!(Window->Style & WS_VISIBLE) &&
Window->OwnerThread->ThreadsProcess != CsrProcess) ||
(Window->Style & (WS_POPUP | WS_CHILD)) == WS_CHILD)
{
return ThreadQueue ? 0 : ThreadQueue->ActiveWindow;

View file

@ -48,7 +48,6 @@ static CLIENT_ID KeyboardThreadId;
static HANDLE KeyboardDeviceHandle;
static KEVENT InputThreadsStart;
static BOOLEAN InputThreadsRunning = FALSE;
PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue = 0;
/* FUNCTIONS *****************************************************************/
ULONG FASTCALL
@ -733,9 +732,6 @@ KeyboardThreadMain(PVOID StartContext)
}
/* Find the target thread whose locale is in effect */
if (!IntGetScreenDC())
FocusQueue = W32kGetPrimitiveMessageQueue();
else
FocusQueue = IntGetFocusMessageQueue();
/* This might cause us to lose hot keys, which are important
@ -793,42 +789,10 @@ KeyboardEscape:
}
NTSTATUS FASTCALL
UserAcquireOrReleaseInputOwnership(BOOLEAN Release)
{
if (Release && InputThreadsRunning && !pmPrimitiveMessageQueue)
{
DPRINT( "Releasing input: PM = %08x\n", pmPrimitiveMessageQueue );
KeClearEvent(&InputThreadsStart);
InputThreadsRunning = FALSE;
NtAlertThread(KeyboardThreadHandle);
NtAlertThread(MouseThreadHandle);
}
else if (!Release && !InputThreadsRunning)
{
InputThreadsRunning = TRUE;
KeSetEvent(&InputThreadsStart, IO_NO_INCREMENT, FALSE);
}
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL
NtUserAcquireOrReleaseInputOwnership(BOOLEAN Release)
{
DECLARE_RETURN(NTSTATUS);
DPRINT("Enter NtUserAcquireOrReleaseInputOwnership\n");
UserEnterExclusive();
RETURN(UserAcquireOrReleaseInputOwnership(Release));
CLEANUP:
DPRINT("Leave NtUserAcquireOrReleaseInputOwnership, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
return STATUS_SUCCESS;
}
@ -867,6 +831,8 @@ InitInputImpl(VOID)
DPRINT1("Win32K: Failed to create mouse thread.\n");
}
InputThreadsRunning = TRUE;
KeSetEvent(&InputThreadsStart, IO_NO_INCREMENT, FALSE);
return STATUS_SUCCESS;
}

View file

@ -17,39 +17,6 @@
/* registered Logon process */
PW32PROCESS LogonProcess = NULL;
VOID W32kRegisterPrimitiveMessageQueue(VOID)
{
extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue;
if( !pmPrimitiveMessageQueue )
{
PW32THREAD pThread;
pThread = PsGetCurrentThreadWin32Thread();
if( pThread && pThread->MessageQueue )
{
pmPrimitiveMessageQueue = pThread->MessageQueue;
IntReferenceMessageQueue(pmPrimitiveMessageQueue);
DPRINT( "Installed primitive input queue.\n" );
}
}
else
{
DPRINT1( "Alert! Someone is trying to steal the primitive queue.\n" );
}
}
VOID W32kUnregisterPrimitiveMessageQueue(VOID)
{
extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue;
IntDereferenceMessageQueue(pmPrimitiveMessageQueue);
pmPrimitiveMessageQueue = NULL;
}
PUSER_MESSAGE_QUEUE W32kGetPrimitiveMessageQueue()
{
extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue;
return pmPrimitiveMessageQueue;
}
BOOL FASTCALL
co_IntRegisterLogonProcess(HANDLE ProcessId, BOOL Register)
{
@ -119,11 +86,6 @@ NtUserCallNoParam(DWORD Routine)
switch(Routine)
{
case NOPARAM_ROUTINE_REGISTER_PRIMITIVE:
W32kRegisterPrimitiveMessageQueue();
Result = (DWORD)TRUE;
break;
case NOPARAM_ROUTINE_DESTROY_CARET:
Result = (DWORD)co_IntDestroyCaret(PsGetCurrentThread()->Tcb.Win32Thread);
break;

View file

@ -479,12 +479,6 @@ co_MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd,
DECLARE_RETURN(BOOL);
USER_REFERENCE_ENTRY Ref;
if( !IntGetScreenDC() ||
PsGetCurrentThreadWin32Thread()->MessageQueue == W32kGetPrimitiveMessageQueue() )
{
RETURN(FALSE);
}
WaitObjects[1] = MessageQueue->NewMessages;
WaitObjects[0] = &HardwareMessageQueueLock;
do
@ -719,16 +713,6 @@ co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
}
FocusMessageQueue = IntGetFocusMessageQueue();
if( !IntGetScreenDC() )
{
/* FIXME: What to do about Msg.pt here? */
if( W32kGetPrimitiveMessageQueue() )
{
MsqPostMessage(W32kGetPrimitiveMessageQueue(), &Msg, FALSE, QS_KEY);
}
}
else
{
if (FocusMessageQueue == NULL)
{
DPRINT("No focus message queue\n");
@ -748,7 +732,6 @@ co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
DPRINT("Invalid focus window handle\n");
}
}
}
VOID FASTCALL
MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam)
@ -1511,10 +1494,6 @@ MsqDestroyMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
IntDereferenceMessageQueue(MessageQueue);
}
/* if this is the primitive message queue, deregister it */
if (MessageQueue == W32kGetPrimitiveMessageQueue())
W32kUnregisterPrimitiveMessageQueue();
/* clean it up */
MsqCleanupMessageQueue(MessageQueue);

View file

@ -81,11 +81,14 @@ IntIntersectWithParents(PWINDOW_OBJECT Child, PRECT WindowRect)
return TRUE;
}
VOID FASTCALL
IntValidateParent(PWINDOW_OBJECT Child, HRGN ValidRegion)
BOOL FASTCALL
IntValidateParent(PWINDOW_OBJECT Child, BOOL Recurse)
{
PWINDOW_OBJECT ParentWindow = Child->Parent;
while (ParentWindow && ParentWindow->Style & WS_CHILD)
ParentWindow = ParentWindow->Parent;
while (ParentWindow)
{
if (ParentWindow->Style & WS_CLIPCHILDREN)
@ -93,13 +96,17 @@ IntValidateParent(PWINDOW_OBJECT Child, HRGN ValidRegion)
if (ParentWindow->UpdateRegion != 0)
{
NtGdiCombineRgn(ParentWindow->UpdateRegion, ParentWindow->UpdateRegion,
ValidRegion, RGN_DIFF);
/* FIXME: If the resulting region is empty, remove fake posted paint message */
if (Recurse)
return FALSE;
IntInvalidateWindows(ParentWindow, Child->UpdateRegion,
RDW_VALIDATE | RDW_NOCHILDREN);
}
ParentWindow = ParentWindow->Parent;
}
return TRUE;
}
/**
@ -219,7 +226,7 @@ IntGetNCUpdateRgn(PWINDOW_OBJECT Window, BOOL Validate)
*/
static VOID FASTCALL
co_IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags)
co_IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags, BOOL Recurse)
{
HDC hDC;
HWND hWnd = Window->hSelf;
@ -229,7 +236,8 @@ co_IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags)
{
if (Window->UpdateRegion)
{
IntValidateParent(Window, Window->UpdateRegion);
if (!IntValidateParent(Window, Recurse))
return;
}
if (Flags & RDW_UPDATENOW)
@ -290,6 +298,7 @@ co_IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags)
if ((List = IntWinListChildren(Window)))
{
/* FIXME: Handle WS_EX_TRANSPARENT */
for (phWnd = List; *phWnd; ++phWnd)
{
Window = UserGetWindowObject(*phWnd);
@ -297,7 +306,7 @@ co_IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags)
{
USER_REFERENCE_ENTRY Ref;
UserRefObjectCo(Window, &Ref);
co_IntPaintWindows(Window, Flags);
co_IntPaintWindows(Window, Flags, TRUE);
UserDerefObjectCo(Window);
}
}
@ -578,7 +587,7 @@ co_UserRedrawWindow(PWINDOW_OBJECT Window, const RECT* UpdateRect, HRGN UpdateRg
if (Flags & (RDW_ERASENOW | RDW_UPDATENOW))
{
co_IntPaintWindows(Window, Flags);
co_IntPaintWindows(Window, Flags, FALSE);
}
/*

View file

@ -133,7 +133,8 @@ BOOL FASTCALL can_activate_window( PWINDOW_OBJECT Wnd OPTIONAL)
if (!Wnd) return FALSE;
style = Wnd->Style;
if (!(style & WS_VISIBLE)) return FALSE;
if (!(style & WS_VISIBLE) &&
Wnd->OwnerThread->ThreadsProcess != CsrProcess) return FALSE;
if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
return !(style & WS_DISABLED);
}
@ -1194,7 +1195,6 @@ co_WinPosSetWindowPos(
CopyRect.left + (OldWindowRect.left - NewWindowRect.left),
CopyRect.top + (OldWindowRect.top - NewWindowRect.top), SRCCOPY, 0, 0);
UserReleaseDC(Window, Dc, FALSE);
IntValidateParent(Window, CopyRgn);
NtGdiOffsetRgn(CopyRgn, -NewWindowRect.left, -NewWindowRect.top);
}
else if(VisRgn)

View file

@ -294,8 +294,6 @@ co_IntInitializeDesktopGraphics(VOID)
}
DC_SetOwnership(ScreenDeviceContext, NULL);
UserAcquireOrReleaseInputOwnership(FALSE);
/* Setup the cursor */
co_IntLoadDefaultCursors();
@ -305,7 +303,6 @@ co_IntInitializeDesktopGraphics(VOID)
VOID FASTCALL
IntEndDesktopGraphics(VOID)
{
UserAcquireOrReleaseInputOwnership(TRUE);
if (NULL != ScreenDeviceContext)
{
DC_SetOwnership(ScreenDeviceContext, PsGetCurrentProcess());

View file

@ -2528,7 +2528,6 @@ IntEnumDisplaySettings(
{
if (iModeNum == 0 || CachedDevModes == NULL) /* query modes from drivers */
{
BOOL PrimarySurfaceCreated = FALSE;
UNICODE_STRING DriverFileNames;
LPWSTR CurrentName;
DRVENABLEDATA DrvEnableData;
@ -2541,11 +2540,7 @@ IntEnumDisplaySettings(
return FALSE;
}
if (!HalQueryDisplayOwnership())
{
IntCreatePrimarySurface();
PrimarySurfaceCreated = TRUE;
}
IntPrepareDriverIfNeeded();
/*
* DriverFileNames may be a list of drivers in REG_SZ_MULTI format,
@ -2611,10 +2606,6 @@ IntEnumDisplaySettings(
SizeOfCachedDevModes = 0;
CachedDevModes = NULL;
CachedDevModesEnd = NULL;
if (PrimarySurfaceCreated)
{
IntDestroyPrimarySurface();
}
SetLastWin32Error(STATUS_NO_MEMORY);
return FALSE;
}
@ -2643,11 +2634,6 @@ IntEnumDisplaySettings(
}
}
if (PrimarySurfaceCreated)
{
IntDestroyPrimarySurface();
}
RtlFreeUnicodeString(&DriverFileNames);
}