+++ /dev/null
-/*
- * ReactOS VBE miniport video driver
- * Copyright (C) 2004 Filip Navara
- *
- * Power Management and VBE 1.2 support
- * Copyright (C) 2004 Magnus Olsen
- *
- * 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * TODO:
- * - Check input parameters everywhere.
- * - Call VideoPortVerifyAccessRanges to reserve the memory we're about
- * to map.
- */
-
-/* INCLUDES *******************************************************************/
-
-#include "vbemp.h"
-
-#undef LOWORD
-#undef HIWORD
-#define LOWORD(l) ((USHORT)((ULONG_PTR)(l)))
-#define HIWORD(l) ((USHORT)(((ULONG_PTR)(l)>>16)&0xFFFF))
-
-/* PUBLIC AND PRIVATE FUNCTIONS ***********************************************/
-
-ULONG NTAPI
-DriverEntry(IN PVOID Context1, IN PVOID Context2)
-{
- VIDEO_HW_INITIALIZATION_DATA InitData;
-
- VideoPortZeroMemory(&InitData, sizeof(InitData));
- InitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
- InitData.HwFindAdapter = VBEFindAdapter;
- InitData.HwInitialize = VBEInitialize;
- InitData.HwStartIO = VBEStartIO;
- InitData.HwResetHw = VBEResetHw;
- InitData.HwGetPowerState = VBEGetPowerState;
- InitData.HwSetPowerState = VBESetPowerState;
- InitData.HwGetVideoChildDescriptor = VBEGetVideoChildDescriptor;
- InitData.HwDeviceExtensionSize = sizeof(VBE_DEVICE_EXTENSION);
-
- return VideoPortInitialize(Context1, Context2, &InitData, NULL);
-}
-
-/*
- * VBEFindAdapter
- *
- * Should detect a VBE compatible display adapter, but it's not possible
- * to use video port Int 10 services at this time during initialization,
- * so we always return NO_ERROR and do the real work in VBEInitialize.
- */
-
-VP_STATUS NTAPI
-VBEFindAdapter(
- IN PVOID HwDeviceExtension,
- IN PVOID HwContext,
- IN PWSTR ArgumentString,
- IN OUT PVIDEO_PORT_CONFIG_INFO ConfigInfo,
- OUT PUCHAR Again)
-{
- if (VideoPortIsNoVesa())
- return ERROR_DEV_NOT_EXIST;
-
- return NO_ERROR;
-}
-
-/*
- * VBESortModesCallback
- *
- * Helper function for sorting video mode list.
- */
-
-static int
-VBESortModesCallback(PVBE_MODEINFO VbeModeInfoA, PVBE_MODEINFO VbeModeInfoB)
-{
- VideoPortDebugPrint(Info, "VBESortModesCallback: %dx%dx%d / %dx%dx%d\n",
- VbeModeInfoA->XResolution, VbeModeInfoA->YResolution,
- VbeModeInfoA->BitsPerPixel,
- VbeModeInfoB->XResolution, VbeModeInfoB->YResolution,
- VbeModeInfoB->BitsPerPixel);
-
- /*
- * FIXME: Until some reasonable method for changing video modes will
- * be available we favor more bits per pixel. It should be changed
- * later.
- */
- if (VbeModeInfoA->BitsPerPixel < VbeModeInfoB->BitsPerPixel) return -1;
- if (VbeModeInfoA->BitsPerPixel > VbeModeInfoB->BitsPerPixel) return 1;
- if (VbeModeInfoA->XResolution < VbeModeInfoB->XResolution) return -1;
- if (VbeModeInfoA->XResolution > VbeModeInfoB->XResolution) return 1;
- if (VbeModeInfoA->YResolution < VbeModeInfoB->YResolution) return -1;
- if (VbeModeInfoA->YResolution > VbeModeInfoB->YResolution) return 1;
- return 0;
-}
-
-/*
- * VBESortModes
- *
- * Simple function for sorting the video mode list. Uses bubble sort.
- */
-
-VOID FASTCALL
-VBESortModes(PVBE_DEVICE_EXTENSION DeviceExtension)
-{
- BOOLEAN Finished = FALSE;
- ULONG Pos;
- int Result;
- VBE_MODEINFO TempModeInfo;
- USHORT TempModeNumber;
-
- while (!Finished)
- {
- Finished = TRUE;
- for (Pos = 0; Pos < DeviceExtension->ModeCount - 1; Pos++)
- {
- Result = VBESortModesCallback(
- DeviceExtension->ModeInfo + Pos,
- DeviceExtension->ModeInfo + Pos + 1);
- if (Result > 0)
- {
- Finished = FALSE;
-
- VideoPortMoveMemory(
- &TempModeInfo,
- DeviceExtension->ModeInfo + Pos,
- sizeof(VBE_MODEINFO));
- TempModeNumber = DeviceExtension->ModeNumbers[Pos];
-
- VideoPortMoveMemory(
- DeviceExtension->ModeInfo + Pos,
- DeviceExtension->ModeInfo + Pos + 1,
- sizeof(VBE_MODEINFO));
- DeviceExtension->ModeNumbers[Pos] =
- DeviceExtension->ModeNumbers[Pos + 1];
-
- VideoPortMoveMemory(
- DeviceExtension->ModeInfo + Pos + 1,
- &TempModeInfo,
- sizeof(VBE_MODEINFO));
- DeviceExtension->ModeNumbers[Pos + 1] = TempModeNumber;
- }
- }
- }
-}
-
-/*
- * VBEInitialize
- *
- * Performs the first initialization of the adapter, after the HAL has given
- * up control of the video hardware to the video port driver.
- *
- * This function performs these steps:
- * - Gets global VBE information and finds if VBE BIOS is present.
- * - Builds the internal mode list using the list of modes provided by
- * the VBE.
- */
-
-BOOLEAN NTAPI
-VBEInitialize(PVOID HwDeviceExtension)
-{
- INT10_BIOS_ARGUMENTS BiosRegisters;
- VP_STATUS Status;
- PVBE_DEVICE_EXTENSION VBEDeviceExtension =
- (PVBE_DEVICE_EXTENSION)HwDeviceExtension;
- ULONG Length;
- ULONG ModeCount;
- ULONG SuitableModeCount;
- USHORT ModeTemp;
- ULONG CurrentMode;
- PVBE_MODEINFO VbeModeInfo;
-
- /*
- * Get the Int 10 interface that we will use for allocating real
- * mode memory and calling the video BIOS.
- */
-
- VBEDeviceExtension->Int10Interface.Version = VIDEO_PORT_INT10_INTERFACE_VERSION_1;
- VBEDeviceExtension->Int10Interface.Size = sizeof(VIDEO_PORT_INT10_INTERFACE);
- Status = VideoPortQueryServices(
- HwDeviceExtension,
- VideoPortServicesInt10,
- (PINTERFACE)&VBEDeviceExtension->Int10Interface);
-
- if (Status != NO_ERROR)
- {
- VideoPortDebugPrint(Error, "Failed to get Int 10 service functions (Status %x)\n", Status);
- return FALSE;
- }
-
- /*
- * Allocate a bit of memory that will be later used for VBE transport
- * buffer. This memory must be accessible from V86 mode so it must fit
- * in the first megabyte of physical memory.
- */
-
- Length = 0x400;
- Status = VBEDeviceExtension->Int10Interface.Int10AllocateBuffer(
- VBEDeviceExtension->Int10Interface.Context,
- &VBEDeviceExtension->TrampolineMemorySegment,
- &VBEDeviceExtension->TrampolineMemoryOffset,
- &Length);
-
- if (Status != NO_ERROR)
- {
- VideoPortDebugPrint(Error, "Failed to allocate virtual memory (Status %x)\n", Status);
- return FALSE;
- }
-
- /*
- * Get the VBE general information.
- */
-
- VBEDeviceExtension->Int10Interface.Int10WriteMemory(
- VBEDeviceExtension->Int10Interface.Context,
- VBEDeviceExtension->TrampolineMemorySegment,
- VBEDeviceExtension->TrampolineMemoryOffset,
- "VBE2",
- 4);
-
- VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
- BiosRegisters.Eax = VBE_GET_CONTROLLER_INFORMATION;
- BiosRegisters.Edi = VBEDeviceExtension->TrampolineMemoryOffset;
- BiosRegisters.SegEs = VBEDeviceExtension->TrampolineMemorySegment;
- VBEDeviceExtension->Int10Interface.Int10CallBios(
- VBEDeviceExtension->Int10Interface.Context,
- &BiosRegisters);
-
- if (VBE_GETRETURNCODE(BiosRegisters.Eax) == VBE_SUCCESS)
- {
- VBEDeviceExtension->Int10Interface.Int10ReadMemory(
- VBEDeviceExtension->Int10Interface.Context,
- VBEDeviceExtension->TrampolineMemorySegment,
- VBEDeviceExtension->TrampolineMemoryOffset,
- &VBEDeviceExtension->VbeInfo,
- sizeof(VBEDeviceExtension->VbeInfo));
-
- /* Verify the VBE signature. */
- if (VideoPortCompareMemory(VBEDeviceExtension->VbeInfo.Signature, "VESA", 4) != 4)
- {
- VideoPortDebugPrint(Error, "No VBE BIOS present\n");
- return FALSE;
- }
-
- VideoPortDebugPrint(Trace, "VBE BIOS Present (%d.%d, %8ld Kb)\n",
- VBEDeviceExtension->VbeInfo.Version / 0x100,
- VBEDeviceExtension->VbeInfo.Version & 0xFF,
- VBEDeviceExtension->VbeInfo.TotalMemory * 64);
-
-#ifdef VBE12_SUPPORT
- if (VBEDeviceExtension->VbeInfo.Version < 0x102)
-#else
- if (VBEDeviceExtension->VbeInfo.Version < 0x200)
-#endif
- {
- VideoPortDebugPrint(Error, "VBE BIOS present, but incompatible version %d.%d\n",
- VBEDeviceExtension->VbeInfo.Version / 0x100,
- VBEDeviceExtension->VbeInfo.Version & 0xFF);
- return FALSE;
- }
- }
- else
- {
- VideoPortDebugPrint(Error, "No VBE BIOS found.\n");
- return FALSE;
- }
-
- /*
- * Build a mode list here that can be later used by
- * IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES and IOCTL_VIDEO_QUERY_AVAIL_MODES
- * calls.
- */
-
- /*
- * Get the number of supported video modes.
- *
- * No need to be map the memory. It's either in the video BIOS memory or
- * in our trampoline memory. In either case the memory is already mapped.
- */
-
- for (ModeCount = 0; ; ModeCount++)
- {
- /* Read the VBE mode number. */
- VBEDeviceExtension->Int10Interface.Int10ReadMemory(
- VBEDeviceExtension->Int10Interface.Context,
- HIWORD(VBEDeviceExtension->VbeInfo.VideoModePtr),
- LOWORD(VBEDeviceExtension->VbeInfo.VideoModePtr) + (ModeCount << 1),
- &ModeTemp,
- sizeof(ModeTemp));
-
- /* End of list? */
- if (ModeTemp == 0xFFFF || ModeTemp == 0)
- break;
- }
-
- /*
- * Allocate space for video modes information.
- */
-
- VBEDeviceExtension->ModeInfo =
- VideoPortAllocatePool(HwDeviceExtension, VpPagedPool, ModeCount * sizeof(VBE_MODEINFO), TAG_VBE);
- VBEDeviceExtension->ModeNumbers =
- VideoPortAllocatePool(HwDeviceExtension, VpPagedPool, ModeCount * sizeof(USHORT), TAG_VBE);
-
- /*
- * Get the actual mode infos.
- */
-
- for (CurrentMode = 0, SuitableModeCount = 0;
- CurrentMode < ModeCount;
- CurrentMode++)
- {
- /* Read the VBE mode number. */
- VBEDeviceExtension->Int10Interface.Int10ReadMemory(
- VBEDeviceExtension->Int10Interface.Context,
- HIWORD(VBEDeviceExtension->VbeInfo.VideoModePtr),
- LOWORD(VBEDeviceExtension->VbeInfo.VideoModePtr) + (CurrentMode << 1),
- &ModeTemp,
- sizeof(ModeTemp));
-
- /* Call VBE BIOS to read the mode info. */
- VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
- BiosRegisters.Eax = VBE_GET_MODE_INFORMATION;
- BiosRegisters.Ecx = ModeTemp;
- BiosRegisters.Edi = VBEDeviceExtension->TrampolineMemoryOffset + 0x200;
- BiosRegisters.SegEs = VBEDeviceExtension->TrampolineMemorySegment;
- VBEDeviceExtension->Int10Interface.Int10CallBios(
- VBEDeviceExtension->Int10Interface.Context,
- &BiosRegisters);
-
- /* Read the VBE mode info. */
- VBEDeviceExtension->Int10Interface.Int10ReadMemory(
- VBEDeviceExtension->Int10Interface.Context,
- VBEDeviceExtension->TrampolineMemorySegment,
- VBEDeviceExtension->TrampolineMemoryOffset + 0x200,
- VBEDeviceExtension->ModeInfo + SuitableModeCount,
- sizeof(VBE_MODEINFO));
-
- VbeModeInfo = VBEDeviceExtension->ModeInfo + SuitableModeCount;
-
- /* Is this mode acceptable? */
- if (VBE_GETRETURNCODE(BiosRegisters.Eax) == VBE_SUCCESS &&
- VbeModeInfo->XResolution >= 640 &&
- VbeModeInfo->YResolution >= 480 &&
- (VbeModeInfo->MemoryModel == VBE_MEMORYMODEL_PACKEDPIXEL ||
- VbeModeInfo->MemoryModel == VBE_MEMORYMODEL_DIRECTCOLOR) &&
- VbeModeInfo->PhysBasePtr != 0)
- {
- if (VbeModeInfo->ModeAttributes & VBE_MODEATTR_LINEAR)
- {
- /* Bit 15 14 13 12 | 11 10 9 8 | 7 6 5 4 | 3 2 1 0 */
- // if (ModeTemp & 0x4000)
- //{
- VBEDeviceExtension->ModeNumbers[SuitableModeCount] = ModeTemp | 0x4000;
- SuitableModeCount++;
- //}
- }
-#ifdef VBE12_SUPPORT
- else
- {
- 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 NTAPI
-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 NTAPI
-VBEResetHw(
- PVOID DeviceExtension,
- ULONG Columns,
- ULONG Rows)
-{
- /* Return FALSE to let HAL reset the display with INT10 */
- return FALSE;
-}
-
-/*
- * VBEGetPowerState
- *
- * Queries whether the device can support the requested power state.
- */
-
-VP_STATUS NTAPI
-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 ( VBE_GETRETURNCODE(BiosRegisters.Eax) == VBE_NOT_SUPPORTED)
- return ERROR_DEV_NOT_EXIST;
- if (VBE_GETRETURNCODE(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 (VBE_GETRETURNCODE(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 NTAPI
-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 (VBE_GETRETURNCODE(BiosRegisters.Eax) == VBE_NOT_SUPPORTED)
- return ERROR_DEV_NOT_EXIST;
- if (VBE_GETRETURNCODE(BiosRegisters.Eax) != VBE_SUCCESS)
- return ERROR_INVALID_FUNCTION;
-
- return VBE_SUCCESS;
-}
-
-/*
- * VBESetCurrentMode
- *
- * Sets the adapter to the specified operating mode.
- */
-
-BOOLEAN FASTCALL
-VBESetCurrentMode(
- PVBE_DEVICE_EXTENSION DeviceExtension,
- PVIDEO_MODE RequestedMode,
- PSTATUS_BLOCK StatusBlock)
-{
- INT10_BIOS_ARGUMENTS BiosRegisters;
-
- if (RequestedMode->RequestedMode >= DeviceExtension->ModeCount)
- {
- return ERROR_INVALID_PARAMETER;
- }
-
- VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
- BiosRegisters.Eax = VBE_SET_VBE_MODE;
- BiosRegisters.Ebx = DeviceExtension->ModeNumbers[RequestedMode->RequestedMode];
- DeviceExtension->Int10Interface.Int10CallBios(
- DeviceExtension->Int10Interface.Context,
- &BiosRegisters);
-
- if (VBE_GETRETURNCODE(BiosRegisters.Eax) == VBE_SUCCESS)
- {
- DeviceExtension->CurrentMode = RequestedMode->RequestedMode;
- }
- else
- {
- VideoPortDebugPrint(Error, "VBEMP: VBESetCurrentMode failed (%x)\n", BiosRegisters.Eax);
- DeviceExtension->CurrentMode = -1;
- }
-
- return VBE_GETRETURNCODE(BiosRegisters.Eax) == VBE_SUCCESS;
-}
-
-/*
- * VBEResetDevice
- *
- * Resets the video hardware to the default mode, to which it was initialized
- * at system boot.
- */
-
-BOOLEAN FASTCALL
-VBEResetDevice(
- PVBE_DEVICE_EXTENSION DeviceExtension,
- PSTATUS_BLOCK StatusBlock)
-{
- INT10_BIOS_ARGUMENTS BiosRegisters;
-
- VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
- BiosRegisters.Eax = VBE_SET_VBE_MODE;
- BiosRegisters.Ebx = 0x3;
- DeviceExtension->Int10Interface.Int10CallBios(
- DeviceExtension->Int10Interface.Context,
- &BiosRegisters);
-
- return VBE_GETRETURNCODE(BiosRegisters.Eax) == VBE_SUCCESS;
-}
-
-/*
- * VBEMapVideoMemory
- *
- * Maps the video hardware frame buffer and video RAM into the virtual address
- * space of the requestor.
- */
-
-BOOLEAN FASTCALL
-VBEMapVideoMemory(
- PVBE_DEVICE_EXTENSION DeviceExtension,
- PVIDEO_MEMORY RequestedAddress,
- PVIDEO_MEMORY_INFORMATION MapInformation,
- PSTATUS_BLOCK StatusBlock)
-{
- PHYSICAL_ADDRESS FrameBuffer;
- ULONG inIoSpace = VIDEO_MEMORY_SPACE_MEMORY;
-
- StatusBlock->Information = sizeof(VIDEO_MEMORY_INFORMATION);
-
- if (DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].ModeAttributes &
- VBE_MODEATTR_LINEAR)
- {
- FrameBuffer.QuadPart =
- DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].PhysBasePtr;
- MapInformation->VideoRamBase = RequestedAddress->RequestedVirtualAddress;
- if (DeviceExtension->VbeInfo.Version < 0x300)
- {
- MapInformation->VideoRamLength =
- DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].BytesPerScanLine *
- DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].YResolution;
- }
- else
- {
- MapInformation->VideoRamLength =
- DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].LinBytesPerScanLine *
- DeviceExtension->ModeInfo[DeviceExtension->CurrentMode].YResolution;
- }
- }
-#ifdef VBE12_SUPPORT
- else
- {
- FrameBuffer.QuadPart = 0xA0000;
- MapInformation->VideoRamBase = RequestedAddress->RequestedVirtualAddress;
- MapInformation->VideoRamLength = 0x10000;
- }
-#endif
-
- VideoPortMapMemory(DeviceExtension, FrameBuffer,
- &MapInformation->VideoRamLength, &inIoSpace,
- &MapInformation->VideoRamBase);
-
- MapInformation->FrameBufferBase = MapInformation->VideoRamBase;
- MapInformation->FrameBufferLength = MapInformation->VideoRamLength;
-
- return TRUE;
-}
-
-/*
- * VBEUnmapVideoMemory
- *
- * Releases a mapping between the virtual address space and the adapter's
- * frame buffer and video RAM.
- */
-
-BOOLEAN FASTCALL
-VBEUnmapVideoMemory(
- PVBE_DEVICE_EXTENSION DeviceExtension,
- PVIDEO_MEMORY VideoMemory,
- PSTATUS_BLOCK StatusBlock)
-{
- VideoPortUnmapMemory(DeviceExtension, VideoMemory->RequestedVirtualAddress,
- NULL);
- return TRUE;
-}
-
-/*
- * VBEQueryNumAvailModes
- *
- * Returns the number of video modes supported by the adapter and the size
- * in bytes of the video mode information, which can be used to allocate a
- * buffer for an IOCTL_VIDEO_QUERY_AVAIL_MODES request.
- */
-
-BOOLEAN FASTCALL
-VBEQueryNumAvailModes(
- PVBE_DEVICE_EXTENSION DeviceExtension,
- PVIDEO_NUM_MODES Modes,
- PSTATUS_BLOCK StatusBlock)
-{
- Modes->NumModes = DeviceExtension->ModeCount;
- Modes->ModeInformationLength = sizeof(VIDEO_MODE_INFORMATION);
- StatusBlock->Information = sizeof(VIDEO_NUM_MODES);
- return TRUE;
-}
-
-/*
- * VBEQueryMode
- *
- * Returns information about one particular video mode.
- */
-
-VOID FASTCALL
-VBEQueryMode(
- PVBE_DEVICE_EXTENSION DeviceExtension,
- PVIDEO_MODE_INFORMATION VideoMode,
- ULONG VideoModeId)
-{
- PVBE_MODEINFO VBEMode = &DeviceExtension->ModeInfo[VideoModeId];
- ULONG dpi;
-
- VideoMode->Length = sizeof(VIDEO_MODE_INFORMATION);
- VideoMode->ModeIndex = VideoModeId;
- VideoMode->VisScreenWidth = VBEMode->XResolution;
- VideoMode->VisScreenHeight = VBEMode->YResolution;
- if (DeviceExtension->VbeInfo.Version < 0x300)
- VideoMode->ScreenStride = VBEMode->BytesPerScanLine;
- else
- VideoMode->ScreenStride = VBEMode->LinBytesPerScanLine;
- VideoMode->NumberOfPlanes = VBEMode->NumberOfPlanes;
- VideoMode->BitsPerPlane = VBEMode->BitsPerPixel / VBEMode->NumberOfPlanes;
- VideoMode->Frequency = 1;
-
- /* Assume 96DPI and 25.4 millimeters per inch, round to nearest */
- dpi = 96;
- VideoMode->XMillimeter = ((ULONGLONG)VBEMode->XResolution * 254 + (dpi * 5)) / (dpi * 10);
- VideoMode->YMillimeter = ((ULONGLONG)VBEMode->YResolution * 254 + (dpi * 5)) / (dpi * 10);
-
- if (VBEMode->BitsPerPixel > 8)
- {
- /*
- * Always report 16bpp modes and not 15bpp mode...
- */
- if (VBEMode->BitsPerPixel == 15 && VBEMode->NumberOfPlanes == 1)
- {
- VideoMode->BitsPerPlane = 16;
- }
-
- if (DeviceExtension->VbeInfo.Version < 0x300)
- {
- VideoMode->NumberRedBits = VBEMode->RedMaskSize;
- VideoMode->NumberGreenBits = VBEMode->GreenMaskSize;
- VideoMode->NumberBlueBits = VBEMode->BlueMaskSize;
- VideoMode->RedMask = ((1 << VBEMode->RedMaskSize) - 1) << VBEMode->RedFieldPosition;
- VideoMode->GreenMask = ((1 << VBEMode->GreenMaskSize) - 1) << VBEMode->GreenFieldPosition;
- VideoMode->BlueMask = ((1 << VBEMode->BlueMaskSize) - 1) << VBEMode->BlueFieldPosition;
- }
- else
- {
- VideoMode->NumberRedBits = VBEMode->LinRedMaskSize;
- VideoMode->NumberGreenBits = VBEMode->LinGreenMaskSize;
- VideoMode->NumberBlueBits = VBEMode->LinBlueMaskSize;
- VideoMode->RedMask = ((1 << VBEMode->LinRedMaskSize) - 1) << VBEMode->LinRedFieldPosition;
- VideoMode->GreenMask = ((1 << VBEMode->LinGreenMaskSize) - 1) << VBEMode->LinGreenFieldPosition;
- VideoMode->BlueMask = ((1 << VBEMode->LinBlueMaskSize) - 1) << VBEMode->LinBlueFieldPosition;
- }
- }
- else
- {
- VideoMode->NumberRedBits =
- VideoMode->NumberGreenBits =
- VideoMode->NumberBlueBits = 6;
- VideoMode->RedMask =
- VideoMode->GreenMask =
- VideoMode->BlueMask = 0;
- }
- VideoMode->VideoMemoryBitmapWidth = VBEMode->XResolution;
- VideoMode->VideoMemoryBitmapHeight = VBEMode->YResolution;
- VideoMode->AttributeFlags = VIDEO_MODE_GRAPHICS | VIDEO_MODE_COLOR |
- VIDEO_MODE_NO_OFF_SCREEN;
- if (VideoMode->BitsPerPlane <= 8)
- VideoMode->AttributeFlags |= VIDEO_MODE_PALETTE_DRIVEN;
- VideoMode->DriverSpecificAttributeFlags = 0;
-}
-
-/*
- * VBEQueryAvailModes
- *
- * Returns information about each video mode supported by the adapter.
- */
-
-BOOLEAN FASTCALL
-VBEQueryAvailModes(
- PVBE_DEVICE_EXTENSION DeviceExtension,
- PVIDEO_MODE_INFORMATION ReturnedModes,
- PSTATUS_BLOCK StatusBlock)
-{
- ULONG CurrentModeId;
- PVIDEO_MODE_INFORMATION CurrentMode;
- PVBE_MODEINFO CurrentVBEMode;
-
- for (CurrentModeId = 0, CurrentMode = ReturnedModes,
- CurrentVBEMode = DeviceExtension->ModeInfo;
- CurrentModeId < DeviceExtension->ModeCount;
- CurrentModeId++, CurrentMode++, CurrentVBEMode++)
- {
- VBEQueryMode(DeviceExtension, CurrentMode, CurrentModeId);
- }
-
- StatusBlock->Information =
- sizeof(VIDEO_MODE_INFORMATION) * DeviceExtension->ModeCount;
-
- return TRUE;
-}
-
-/*
- * VBEQueryCurrentMode
- *
- * Returns information about current video mode.
- */
-
-BOOLEAN FASTCALL
-VBEQueryCurrentMode(
- PVBE_DEVICE_EXTENSION DeviceExtension,
- PVIDEO_MODE_INFORMATION VideoModeInfo,
- PSTATUS_BLOCK StatusBlock)
-{
- StatusBlock->Information = sizeof(VIDEO_MODE_INFORMATION);
-
- VBEQueryMode(
- DeviceExtension,
- VideoModeInfo,
- DeviceExtension->CurrentMode);
-
- return TRUE;
-}
-
-/*
- * VBESetColorRegisters
- *
- * Sets the adapter's color registers to the specified RGB values. There
- * are code paths in this function, one generic and one for VGA compatible
- * controllers. The latter is needed for Bochs, where the generic one isn't
- * yet implemented.
- */
-
-BOOLEAN FASTCALL
-VBESetColorRegisters(
- PVBE_DEVICE_EXTENSION DeviceExtension,
- PVIDEO_CLUT ColorLookUpTable,
- PSTATUS_BLOCK StatusBlock)
-{
- INT10_BIOS_ARGUMENTS BiosRegisters;
- ULONG Entry;
- PULONG OutputEntry;
- ULONG OutputBuffer[256];
-
- if (ColorLookUpTable->NumEntries + ColorLookUpTable->FirstEntry > 256)
- return FALSE;
-
- /*
- * For VGA compatible adapters program the color registers directly.
- */
-
- if (!(DeviceExtension->VbeInfo.Capabilities & 2))
- {
- for (Entry = ColorLookUpTable->FirstEntry;
- Entry < ColorLookUpTable->NumEntries + ColorLookUpTable->FirstEntry;
- Entry++)
- {
- VideoPortWritePortUchar((PUCHAR)0x03c8, Entry);
- VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[Entry].RgbArray.Red);
- VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[Entry].RgbArray.Green);
- VideoPortWritePortUchar((PUCHAR)0x03c9, ColorLookUpTable->LookupTable[Entry].RgbArray.Blue);
- }
-
- return TRUE;
- }
- else
- {
- /*
- * We can't just copy the values, because we need to swap the Red
- * and Blue values.
- */
-
- for (Entry = ColorLookUpTable->FirstEntry,
- OutputEntry = OutputBuffer;
- Entry < ColorLookUpTable->NumEntries + ColorLookUpTable->FirstEntry;
- Entry++, OutputEntry++)
- {
- *OutputEntry =
- (ColorLookUpTable->LookupTable[Entry].RgbArray.Red << 16) |
- (ColorLookUpTable->LookupTable[Entry].RgbArray.Green << 8) |
- (ColorLookUpTable->LookupTable[Entry].RgbArray.Blue);
- }
-
- DeviceExtension->Int10Interface.Int10WriteMemory(
- DeviceExtension->Int10Interface.Context,
- DeviceExtension->TrampolineMemorySegment,
- DeviceExtension->TrampolineMemoryOffset,
- OutputBuffer,
- (OutputEntry - OutputBuffer) * sizeof(ULONG));
-
- VideoPortZeroMemory(&BiosRegisters, sizeof(BiosRegisters));
- BiosRegisters.Eax = VBE_SET_GET_PALETTE_DATA;
- BiosRegisters.Ebx = 0;
- BiosRegisters.Ecx = ColorLookUpTable->NumEntries;
- BiosRegisters.Edx = ColorLookUpTable->FirstEntry;
- BiosRegisters.Edi = DeviceExtension->TrampolineMemoryOffset;
- BiosRegisters.SegEs = DeviceExtension->TrampolineMemorySegment;
- DeviceExtension->Int10Interface.Int10CallBios(
- DeviceExtension->Int10Interface.Context,
- &BiosRegisters);
-
- return VBE_GETRETURNCODE(BiosRegisters.Eax) == VBE_SUCCESS;
- }
-}