📄 vbemp.c
字号:
VBEDeviceExtension->ModeNumbers[SuitableModeCount] = ModeTemp;
SuitableModeCount++;
}
#endif
}
}
if (SuitableModeCount == 0)
{
VideoPortDebugPrint(Warn, "VBEMP: No video modes supported\n");
return FALSE;
}
VBEDeviceExtension->ModeCount = SuitableModeCount;
/*
* Sort the video mode list according to resolution and bits per pixel.
*/
VBESortModes(VBEDeviceExtension);
/*
* Print the supported video modes.
*/
for (CurrentMode = 0;
CurrentMode < SuitableModeCount;
CurrentMode++)
{
VideoPortDebugPrint(Trace, "%dx%dx%d\n",
VBEDeviceExtension->ModeInfo[CurrentMode].XResolution,
VBEDeviceExtension->ModeInfo[CurrentMode].YResolution,
VBEDeviceExtension->ModeInfo[CurrentMode].BitsPerPixel);
}
/*
* Enumerate our children.
*/
VideoPortEnumerateChildren(HwDeviceExtension, NULL);
return TRUE;
}
/*
* VBEStartIO
*
* Processes the specified Video Request Packet.
*/
BOOLEAN STDCALL
VBEStartIO(
PVOID HwDeviceExtension,
PVIDEO_REQUEST_PACKET RequestPacket)
{
BOOLEAN Result;
RequestPacket->StatusBlock->Status = ERROR_INVALID_FUNCTION;
switch (RequestPacket->IoControlCode)
{
case IOCTL_VIDEO_SET_CURRENT_MODE:
if (RequestPacket->InputBufferLength < sizeof(VIDEO_MODE))
{
RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
return TRUE;
}
Result = VBESetCurrentMode(
(PVBE_DEVICE_EXTENSION)HwDeviceExtension,
(PVIDEO_MODE)RequestPacket->InputBuffer,
RequestPacket->StatusBlock);
break;
case IOCTL_VIDEO_RESET_DEVICE:
Result = VBEResetDevice(
(PVBE_DEVICE_EXTENSION)HwDeviceExtension,
RequestPacket->StatusBlock);
break;
case IOCTL_VIDEO_MAP_VIDEO_MEMORY:
if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MEMORY_INFORMATION) ||
RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY))
{
RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
return TRUE;
}
Result = VBEMapVideoMemory(
(PVBE_DEVICE_EXTENSION)HwDeviceExtension,
(PVIDEO_MEMORY)RequestPacket->InputBuffer,
(PVIDEO_MEMORY_INFORMATION)RequestPacket->OutputBuffer,
RequestPacket->StatusBlock);
break;
case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:
if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY))
{
RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
return TRUE;
}
Result = VBEUnmapVideoMemory(
(PVBE_DEVICE_EXTENSION)HwDeviceExtension,
(PVIDEO_MEMORY)RequestPacket->InputBuffer,
RequestPacket->StatusBlock);
break;
case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
if (RequestPacket->OutputBufferLength < sizeof(VIDEO_NUM_MODES))
{
RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
return TRUE;
}
Result = VBEQueryNumAvailModes(
(PVBE_DEVICE_EXTENSION)HwDeviceExtension,
(PVIDEO_NUM_MODES)RequestPacket->OutputBuffer,
RequestPacket->StatusBlock);
break;
case IOCTL_VIDEO_QUERY_AVAIL_MODES:
if (RequestPacket->OutputBufferLength <
((PVBE_DEVICE_EXTENSION)HwDeviceExtension)->ModeCount * sizeof(VIDEO_MODE_INFORMATION))
{
RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
return TRUE;
}
Result = VBEQueryAvailModes(
(PVBE_DEVICE_EXTENSION)HwDeviceExtension,
(PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer,
RequestPacket->StatusBlock);
break;
case IOCTL_VIDEO_SET_COLOR_REGISTERS:
if (RequestPacket->InputBufferLength < sizeof(VIDEO_CLUT) ||
RequestPacket->InputBufferLength <
(((PVIDEO_CLUT)RequestPacket->InputBuffer)->NumEntries * sizeof(ULONG)) +
FIELD_OFFSET(VIDEO_CLUT, LookupTable))
{
RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
return TRUE;
}
Result = VBESetColorRegisters(
(PVBE_DEVICE_EXTENSION)HwDeviceExtension,
(PVIDEO_CLUT)RequestPacket->InputBuffer,
RequestPacket->StatusBlock);
break;
case IOCTL_VIDEO_QUERY_CURRENT_MODE:
if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MODE_INFORMATION))
{
RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
return TRUE;
}
Result = VBEQueryCurrentMode(
(PVBE_DEVICE_EXTENSION)HwDeviceExtension,
(PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer,
RequestPacket->StatusBlock);
break;
default:
RequestPacket->StatusBlock->Status = ERROR_INVALID_FUNCTION;
return FALSE;
}
if (Result)
RequestPacket->StatusBlock->Status = NO_ERROR;
return TRUE;
}
/*
* VBEResetHw
*
* This function is called to reset the hardware to a known state.
*/
BOOLEAN STDCALL
VBEResetHw(
PVOID DeviceExtension,
ULONG Columns,
ULONG Rows)
{
INT10_BIOS_ARGUMENTS BiosRegisters;
PVBE_DEVICE_EXTENSION VBEDeviceExtension =
(PVBE_DEVICE_EXTENSION)DeviceExtension;
if (!VBEResetDevice(DeviceExtension, NULL))
return FALSE;
/* Change number of columns/rows */
VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
if (Columns == 80 && Rows == 25)
{
/* Default text size, don't change anything. */
return TRUE;
}
else if (Columns == 80 && Rows == 28)
{
/* Use 9x14 font (80x28) */
BiosRegisters.Eax = 0x1111;
}
else if (Columns == 80 && Rows == 43)
{
/* Use 8x8 font in 350 scans mode (80x43) */
BiosRegisters.Eax = 0x1201;
BiosRegisters.Ebx = 0x30;
VBEDeviceExtension->Int10Interface.Int10CallBios(
VBEDeviceExtension->Int10Interface.Context,
&BiosRegisters);
BiosRegisters.Eax = 0x3;
BiosRegisters.Ebx = 0;
VBEDeviceExtension->Int10Interface.Int10CallBios(
VBEDeviceExtension->Int10Interface.Context,
&BiosRegisters);
BiosRegisters.Eax = 0x1112;
}
else if (Columns == 80 && Rows == 50)
{
/* Use 8x8 font (80x50) */
BiosRegisters.Eax = 0x1112;
}
else
return FALSE;
VBEDeviceExtension->Int10Interface.Int10CallBios(
VBEDeviceExtension->Int10Interface.Context,
&BiosRegisters);
return TRUE;
}
/*
* VBEGetPowerState
*
* Queries whether the device can support the requested power state.
*/
VP_STATUS STDCALL
VBEGetPowerState(
PVOID HwDeviceExtension,
ULONG HwId,
PVIDEO_POWER_MANAGEMENT VideoPowerControl)
{
INT10_BIOS_ARGUMENTS BiosRegisters;
PVBE_DEVICE_EXTENSION VBEDeviceExtension =
(PVBE_DEVICE_EXTENSION)HwDeviceExtension;
if (HwId != DISPLAY_ADAPTER_HW_ID ||
VideoPowerControl->Length < sizeof(VIDEO_POWER_MANAGEMENT))
return ERROR_INVALID_FUNCTION;
/*
* Get general power support information.
*/
VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
BiosRegisters.Eax = VBE_POWER_MANAGEMENT_EXTENSIONS;
BiosRegisters.Ebx = 0;
BiosRegisters.Edi = 0;
BiosRegisters.SegEs = 0;
VBEDeviceExtension->Int10Interface.Int10CallBios(
VBEDeviceExtension->Int10Interface.Context,
&BiosRegisters);
if (BiosRegisters.Eax == VBE_NOT_SUPPORTED)
return ERROR_DEV_NOT_EXIST;
if (BiosRegisters.Eax != VBE_SUCCESS)
return ERROR_INVALID_FUNCTION;
/*
* Get current power state.
*/
VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
BiosRegisters.Eax = VBE_POWER_MANAGEMENT_EXTENSIONS;
BiosRegisters.Ebx = 0x2;
BiosRegisters.Edi = 0;
BiosRegisters.SegEs = 0;
VBEDeviceExtension->Int10Interface.Int10CallBios(
VBEDeviceExtension->Int10Interface.Context,
&BiosRegisters);
if (BiosRegisters.Eax == VBE_SUCCESS)
{
VideoPowerControl->DPMSVersion = BiosRegisters.Ebx & 0xFF;
switch (BiosRegisters.Ebx >> 8)
{
case 0: VideoPowerControl->PowerState = VideoPowerOn; break;
case 1: VideoPowerControl->PowerState = VideoPowerStandBy; break;
case 2: VideoPowerControl->PowerState = VideoPowerSuspend; break;
case 4: VideoPowerControl->PowerState = VideoPowerOff; break;
case 5: VideoPowerControl->PowerState = VideoPowerOn; break;
default: VideoPowerControl->PowerState = VideoPowerUnspecified;
}
return NO_ERROR;
}
return ERROR_DEV_NOT_EXIST;
}
/*
* VBESetPowerState
*
* Sets the power state of the specified device
*/
VP_STATUS STDCALL
VBESetPowerState(
PVOID HwDeviceExtension,
ULONG HwId,
PVIDEO_POWER_MANAGEMENT VideoPowerControl)
{
INT10_BIOS_ARGUMENTS BiosRegisters;
PVBE_DEVICE_EXTENSION VBEDeviceExtension =
(PVBE_DEVICE_EXTENSION)HwDeviceExtension;
if (HwId != DISPLAY_ADAPTER_HW_ID ||
VideoPowerControl->Length < sizeof(VIDEO_POWER_MANAGEMENT) ||
VideoPowerControl->PowerState < VideoPowerOn ||
VideoPowerControl->PowerState > VideoPowerHibernate)
return ERROR_INVALID_FUNCTION;
if (VideoPowerControl->PowerState == VideoPowerHibernate)
return NO_ERROR;
/*
* Set current power state.
*/
VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
BiosRegisters.Eax = VBE_POWER_MANAGEMENT_EXTENSIONS;
BiosRegisters.Ebx = 1;
BiosRegisters.Edi = 0;
BiosRegisters.SegEs = 0;
switch (VideoPowerControl->PowerState)
{
case VideoPowerStandBy: BiosRegisters.Ebx |= 0x100; break;
case VideoPowerSuspend: BiosRegisters.Ebx |= 0x200; break;
case VideoPowerOff: BiosRegisters.Ebx |= 0x400; break;
}
VBEDeviceExtension->Int10Interface.Int10CallBios(
VBEDeviceExtension->Int10Interface.Context,
&BiosRegisters);
if (BiosRegisters.Eax == VBE_NOT_SUPPORTED)
return ERROR_DEV_NOT_EXIST;
if (BiosRegisters.Eax != VBE_SUCCESS)
return ERROR_INVALID_FUNCTION;
return VBE_SUCCESS;
}
/*
* VBESetCurrentMode
*
* Sets the adapter to the specified operating mode.
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -