⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vbemp.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 3 页
字号:
            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 + -