Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1547001
  • 博文数量: 596
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 173
  • 用 户 组: 普通用户
  • 注册时间: 2016-07-06 15:50
个人简介

在线笔记

文章分类

全部博文(596)

文章存档

2016年(1)

2015年(104)

2014年(228)

2013年(226)

2012年(26)

2011年(11)

分类: 虚拟化

2015-04-08 16:01:55


  1. //
  2. // VBoxDispDrvEnablePDEV 主要做了两件事
  3. // @1. 分配内存给PVBOXDISPDEV
  4. // @2. 填充gdiInfo, devInfo, 并赋值给pdevcaps, pdi
  5. // @2.1 显示模式
  6. // @2.2 鼠标支持模式
  7. // @2.3 画刷
  8. //
  9. //
  10. /* First function which is called after entry point, provides info about device to GDI.
  11.  * Returns pointer to our driver private info structure which would be passed by GDI to our other callbacks.
  12.  */
  13. DHPDEV APIENTRY
  14. VBoxDispDrvEnablePDEV(DEVMODEW *pdm, LPWSTR pwszLogAddress, ULONG cPat, HSURF *phsurfPatterns,
  15.                       ULONG cjCaps, ULONG *pdevcaps,
  16.                       ULONG cjDevInfo, DEVINFO *pdi,
  17.                       HDEV hdev, PWSTR pwszDeviceName, HANDLE hDriver)
  18. {
  19.     PVBOXDISPDEV pDev = NULL;
  20.     GDIINFO gdiInfo;
  21.     DEVINFO devInfo;
  22.     int rc;

  23.     /* Next 3 are only used for printer drivers */
  24.     NOREF(pwszLogAddress);
  25.     NOREF(cPat);
  26.     NOREF(phsurfPatterns);
  27.     NOREF(pwszDeviceName);

  28.     LOGF_ENTER();

  29.     //@1
  30.     pDev = (PVBOXDISPDEV) EngAllocMem(FL_ZERO_MEMORY, sizeof(VBOXDISPDEV), MEM_ALLOC_TAG);
  31.     if (!pDev)
  32.     {
  33.         WARN(("EngAllocMem failed!\n"));
  34.         return NULL;
  35.     }
  36.     pDev->hDriver = hDriver;

  37.     //@2
  38.     //通过miniport从注册表获取配置
  39.     ULONG ulRegistryFlags = 0;
  40.     rc = VBoxDispMPQueryRegistryFlags(hDriver, &ulRegistryFlags);
  41.     if (RT_SUCCESS(rc))
  42.     {
  43.         pDev->bBitmapCacheDisabled = (ulRegistryFlags & VBOXVIDEO_REGISTRY_FLAGS_DISABLE_BITMAP_CACHE) != 0;
  44.         LOG(("Bitmap cache %s", pDev->bBitmapCacheDisabled? "disabled": "enabled"));
  45.     }

  46.     //@2.1
  47.     /* Initialize device structure and query miniport to fill device and gdi infos */
  48.     rc = VBoxDispInitDevice(pDev, pdm, &gdiInfo, &devInfo);
  49.     if (RT_FAILURE(rc))
  50.     {
  51.         VBOX_WARNRC(rc);
  52.         EngFreeMem(pDev);
  53.         return NULL;
  54.     }

  55.     //@2.2
  56.     /* Initialize mouse pointer caps */
  57.     rc = VBoxDispInitPointerCaps(pDev, &devInfo);
  58.     if (RT_FAILURE(rc))
  59.     {
  60.         VBOX_WARNRC(rc);
  61.     }

  62.     //@2.3
  63.     /* Initialize palette */
  64.     rc = VBoxDispInitPalette(pDev, &devInfo);
  65.     if (RT_FAILURE(rc))
  66.     {
  67.         VBOX_WARNRC(rc);
  68.         EngFreeMem(pDev);
  69.         return NULL;
  70.     }

  71.     if(g_EngineVersionDDI >= DDI_DRIVER_VERSION_NT5)
  72.     {
  73.         devInfo.flGraphicsCaps2 |= GCAPS2_RESERVED1;
  74.     }

  75.     /* Copy gathered info to supplied buffers */
  76.     memcpy(pdevcaps, &gdiInfo, min(sizeof(GDIINFO), cjCaps));
  77.     memcpy(pdi, &devInfo, min(sizeof(DEVINFO), cjDevInfo));

  78.     LOGF_LEAVE();
  79.     return (DHPDEV)pDev;
  80. }


  81. // @2.1 显示模式
  82. //
  83. // VBoxDispInitDevice
  84. // 1. 从miniport获取支持的显示模式,对比用户设置的显示模式
  85. // 2. /* Fill GDIINFO structure */
  86. // 3. /* Fill DEVINFO structure */
  87. //
  88. static int VBoxDispInitDevice(PVBOXDISPDEV pDev, DEVMODEW *pdm, GDIINFO *pGdiInfo, DEVINFO *pDevInfo)
  89. {
  90.     VIDEO_MODE_INFORMATION *pModesTable, selectedMode;
  91.     ULONG cModes, i=0;
  92.     int rc;

  93.     LOGF_ENTER();

  94.     //@1
  95.     /* Get a list of supported modes by both miniport and display driver */
  96.     rc = VBoxDispMPGetVideoModes(pDev->hDriver, &pModesTable, &cModes);
  97.     VBOX_WARNRC_RETRC(rc);

  98.     /* Check if requested mode is available in the list */
  99.     if ((g_EngineVersionDDI < DDI_DRIVER_VERSION_NT5)
  100.         && (pdm->dmBitsPerPel==0)
  101.         && (pdm->dmPelsWidth==0)
  102.         && (pdm->dmPelsHeight==0)
  103.         && (pdm->dmDisplayFrequency==0))
  104.     {
  105.         /* Special case for NT4, just return default(first) mode */
  106.         memcpy(&selectedMode, &pModesTable[0], sizeof(VIDEO_MODE_INFORMATION));
  107.     }
  108.     else
  109.     {
  110.         for (; i<cModes; ++i)
  111.         {
  112.             if ((pdm->dmBitsPerPel == (pModesTable[i].BitsPerPlane * pModesTable[i].NumberOfPlanes))
  113.                 && (pdm->dmPelsWidth == pModesTable[i].VisScreenWidth)
  114.                 && (pdm->dmPelsHeight == pModesTable[i].VisScreenHeight)
  115.                 && (pdm->dmDisplayFrequency == pModesTable[i].Frequency))
  116.             {
  117.                 memcpy(&selectedMode, &pModesTable[i], sizeof(VIDEO_MODE_INFORMATION));
  118.                 break;
  119.             }
  120.         }
  121.     }
  122.     EngFreeMem(pModesTable);

  123.     if (i>=cModes)
  124.     {
  125.         WARN(("can't support requested mode %dx%d@%dbpp(%dHz)!",
  126.               pdm->dmPelsWidth, pdm->dmPelsHeight, pdm->dmBitsPerPel, pdm->dmDisplayFrequency));
  127.         return VERR_NOT_SUPPORTED;
  128.     }

  129.     LOG(("match for requested mode %dx%d@%dbpp(%dHz)",
  130.          selectedMode.VisScreenWidth, selectedMode.VisScreenHeight, selectedMode.BitsPerPlane, selectedMode.Frequency));

  131.     /* Update private device info with mode information */
  132.     pDev->mode.ulIndex = selectedMode.ModeIndex;
  133.     pDev->mode.ulWidth = selectedMode.VisScreenWidth;
  134.     pDev->mode.ulHeight = selectedMode.VisScreenHeight;
  135.     pDev->mode.ulBitsPerPel = selectedMode.BitsPerPlane * selectedMode.NumberOfPlanes;
  136.     pDev->mode.lScanlineStride = selectedMode.ScreenStride;
  137.     pDev->mode.flMaskR = selectedMode.RedMask;
  138.     pDev->mode.flMaskG = selectedMode.GreenMask;
  139.     pDev->mode.flMaskB = selectedMode.BlueMask;
  140.     pDev->mode.ulPaletteShift = (pDev->mode.ulBitsPerPel==8) ? (8-selectedMode.NumberRedBits) : 0;

  141.     //@2
  142.     /* Fill GDIINFO structure */
  143.     memset(pGdiInfo, 0, sizeof(GDIINFO));

  144.     pGdiInfo->ulVersion = (g_EngineVersionDDI<DDI_DRIVER_VERSION_NT5) ? GDI_DRIVER_VERSION:0x5000;
  145.     pGdiInfo->ulVersion |= VBOXDISPDRIVERVERSION;

  146.     pGdiInfo->ulTechnology = DT_RASDISPLAY;

  147.     pGdiInfo->ulHorzSize = selectedMode.XMillimeter;
  148.     pGdiInfo->ulVertSize = selectedMode.YMillimeter;

  149.     pGdiInfo->ulHorzRes = pDev->mode.ulWidth;
  150.     pGdiInfo->ulVertRes = pDev->mode.ulHeight;

  151.     pGdiInfo->cBitsPixel = pDev->mode.ulBitsPerPel;
  152.     pGdiInfo->cPlanes = selectedMode.NumberOfPlanes;

  153.     pGdiInfo->ulNumColors = (pDev->mode.ulBitsPerPel==8) ? 20 : ((ULONG)(-1));

  154.     pGdiInfo->ulLogPixelsX = pdm->dmLogPixels;
  155.     pGdiInfo->ulLogPixelsY = pdm->dmLogPixels;
  156.     if (pdm->dmLogPixels!=96)
  157.     {
  158.         WARN(("requested logical pixel res %d isn't 96", pdm->dmLogPixels));
  159.     }

  160.     pGdiInfo->flTextCaps = TC_RA_ABLE;

  161.     pGdiInfo->ulDACRed = selectedMode.NumberRedBits;
  162.     pGdiInfo->ulDACGreen = selectedMode.NumberGreenBits;
  163.     pGdiInfo->ulDACBlue = selectedMode.NumberBlueBits;

  164.     pGdiInfo->ulAspectX = 0x24;
  165.     pGdiInfo->ulAspectY = 0x24;
  166.     /* note: ulAspectXY should be square root of sum of squares of x and y aspects */
  167.     pGdiInfo->ulAspectXY = 0x33;

  168.     /* search for "styled cosmetic lines" on msdn for more info */
  169.     pGdiInfo->xStyleStep = 1;
  170.     pGdiInfo->yStyleStep = 1;
  171.     pGdiInfo->denStyleStep = 3;

  172.     pGdiInfo->ulNumPalReg = (pDev->mode.ulBitsPerPel==8) ? (1<<pDev->mode.ulBitsPerPel) : 0;

  173.     /* @todo: might want to implement IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES in miniport driver
  174.      * and query host for this info there
  175.      */
  176.     VBOXDISPSETCIEC(pGdiInfo->ciDevice.Red, 6700, 3300, 0);
  177.     VBOXDISPSETCIEC(pGdiInfo->ciDevice.Green, 2100, 7100, 0);
  178.     VBOXDISPSETCIEC(pGdiInfo->ciDevice.Blue, 1400, 800, 0);
  179.     VBOXDISPSETCIEC(pGdiInfo->ciDevice.AlignmentWhite, 3127, 3290, 0);
  180.     VBOXDISPSETCIEC(pGdiInfo->ciDevice.Cyan, 0, 0, 0);
  181.     VBOXDISPSETCIEC(pGdiInfo->ciDevice.Magenta, 0, 0, 0);
  182.     VBOXDISPSETCIEC(pGdiInfo->ciDevice.Yellow, 0, 0, 0);
  183.     pGdiInfo->ciDevice.RedGamma = 20000;
  184.     pGdiInfo->ciDevice.GreenGamma = 20000;
  185.     pGdiInfo->ciDevice.BlueGamma = 20000;

  186.     pGdiInfo->ulPrimaryOrder = PRIMARY_ORDER_CBA;

  187.     pGdiInfo->ulHTPatternSize = HT_PATSIZE_4x4_M;
  188.     switch (pDev->mode.ulBitsPerPel)
  189.     {
  190.         case 8:
  191.         {
  192.             pGdiInfo->ulHTOutputFormat = HT_FORMAT_8BPP;
  193.             break;
  194.         }
  195.         case 16:
  196.         {
  197.             pGdiInfo->ulHTOutputFormat = HT_FORMAT_16BPP;
  198.             break;
  199.         }
  200.         case 24:
  201.         {
  202.             pGdiInfo->ulHTOutputFormat = HT_FORMAT_24BPP;
  203.             break;
  204.         }
  205.         case 32:
  206.         {
  207.             pGdiInfo->ulHTOutputFormat = HT_FORMAT_32BPP;
  208.             break;
  209.         }
  210.     }
  211.     pGdiInfo->flHTFlags = HT_FLAG_ADDITIVE_PRIMS;

  212.     pGdiInfo->ulVRefresh = selectedMode.Frequency;

  213.     /* 0 means BitBlt's are accelerated by driver */
  214.     pGdiInfo->ulBltAlignment = 0;

  215.     pGdiInfo->ulPhysicalPixelCharacteristics = PPC_UNDEFINED;
  216.     pGdiInfo->ulPhysicalPixelGamma = PPG_DEFAULT;

  217.     //@3
  218.     /* Fill DEVINFO structure */
  219.     memset(pDevInfo, 0, sizeof(DEVINFO));

  220.     pDevInfo->flGraphicsCaps = GCAPS_OPAQUERECT;
  221. #ifdef VBOX_WITH_DDRAW
  222.     pDevInfo->flGraphicsCaps |= GCAPS_DIRECTDRAW;
  223. #endif
  224.     VBOXDISPMAKELOGFONTW(pDevInfo->lfDefaultFont,
  225.                          16, 7, FW_BOLD, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, VARIABLE_PITCH, L"System");

  226.     VBOXDISPMAKELOGFONTW(pDevInfo->lfAnsiVarFont,
  227.                          12, 9, FW_NORMAL, CLIP_STROKE_PRECIS, PROOF_QUALITY, VARIABLE_PITCH, L"MS Sans Serif");

  228.     VBOXDISPMAKELOGFONTW(pDevInfo->lfAnsiFixFont,
  229.                          12, 9, FW_NORMAL, CLIP_STROKE_PRECIS, PROOF_QUALITY, FIXED_PITCH, L"Courier");
  230.     pDevInfo->cFonts = 0;
  231.     pDevInfo->cxDither = 8;
  232.     pDevInfo->cyDither = 8;
  233.     pDevInfo->hpalDefault = 0;
  234.     pDevInfo->flGraphicsCaps2 = 0;

  235.     switch (pDev->mode.ulBitsPerPel)
  236.     {
  237.         case 8:
  238.         {
  239.             pDevInfo->flGraphicsCaps |= GCAPS_PALMANAGED|GCAPS_COLOR_DITHER;
  240.             pDevInfo->iDitherFormat = BMF_8BPP;
  241.             break;
  242.         }
  243.         case 16:
  244.         {
  245.             pDevInfo->iDitherFormat = BMF_16BPP;
  246.             break;
  247.         }
  248.         case 24:
  249.         {
  250.             pDevInfo->iDitherFormat = BMF_24BPP;
  251.             break;
  252.         }
  253.         case 32:
  254.         {
  255.             pDevInfo->iDitherFormat = BMF_32BPP;
  256.             break;
  257.         }
  258.     }

  259.     LOGF_LEAVE();
  260.     return rc;
  261. }

  262. //
  263. //Disp.dll 与 miniport通过 EngDeviceIoControl通信
  264. // 1. 查询有几种模式
  265. // 2. 获取所有的模式
  266. // 3. 筛选支持的模式
  267. // 4. copy
  268. //
  269. /* Returns list video modes supported by both miniport and display driver.
  270.  * Note: caller is resposible to free up ppModesTable.
  271.  */
  272. int VBoxDispMPGetVideoModes(HANDLE hDriver, PVIDEO_MODE_INFORMATION *ppModesTable, ULONG *pcModes)
  273. {
  274.     DWORD dwrc;
  275.     VIDEO_NUM_MODES numModes;
  276.     ULONG cbReturned, i, j, cSupportedModes;
  277.     PVIDEO_MODE_INFORMATION pMiniportModes, pMode;

  278.     LOGF_ENTER();

  279.     //@1
  280.     /* Get number of video modes supported by miniport */
  281.     dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES, NULL, 0,
  282.                               &numModes, sizeof(VIDEO_NUM_MODES), &cbReturned);
  283.     VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR);

  284.     if (numModes.ModeInformationLength != sizeof(VIDEO_MODE_INFORMATION))
  285.     {
  286.         WARN(("sizeof(VIDEO_MODE_INFORMATION) differs for miniport and display drivers. "
  287.               "Check that both are compiled with same ddk version!"));
  288.     }

  289.     /* Allocate temp buffer */
  290.     pMiniportModes = (PVIDEO_MODE_INFORMATION)
  291.                      EngAllocMem(0, numModes.NumModes*numModes.ModeInformationLength, MEM_ALLOC_TAG);

  292.     if (!pMiniportModes)
  293.     {
  294.         WARN(("not enough memory!"));
  295.         return VERR_NO_MEMORY;
  296.     }

  297.     //@2
  298.     /* Get video modes supported by miniport */
  299.     dwrc = EngDeviceIoControl(hDriver, IOCTL_VIDEO_QUERY_AVAIL_MODES, NULL, 0,
  300.                               pMiniportModes, numModes.NumModes*numModes.ModeInformationLength, &cbReturned);
  301.     if (dwrc != NO_ERROR)
  302.     {
  303.         EngFreeMem(pMiniportModes);
  304.         VBOX_CHECK_WINERR_RETRC(dwrc, VERR_DEV_IO_ERROR);
  305.     }

  306.     //@3
  307.     /* Check which of miniport modes are supprted by display driver.
  308.      * Note: size of VIDEO_MODE_INFORMATION is returned by miniport driver in numModes.ModeInformationLength,
  309.      * it might be different from the one we have here.
  310.      */
  311.     cSupportedModes = 0;
  312.     pMode = pMiniportModes;
  313.     for (i=0; i<numModes.NumModes; ++i)
  314.     {
  315.         /*sanity check*/
  316.         if (pMode->Length != sizeof(VIDEO_MODE_INFORMATION))
  317.         {
  318.             WARN(("Unexpected mode len %i expected %i!", pMode->Length, sizeof(VIDEO_MODE_INFORMATION)));
  319.         }

  320. #if 0
  321. /* Returns if given video mode is supported by display driver */
  322. static BOOL VBoxDispVideoModeSupported(const PVIDEO_MODE_INFORMATION pMode)
  323. {
  324.     if ((pMode->NumberOfPlanes==1)
  325.         && (pMode->AttributeFlags & VIDEO_MODE_GRAPHICS)
  326.         && !(pMode->AttributeFlags & VIDEO_MODE_BANKED)
  327.         && (pMode->BitsPerPlane==8 || pMode->BitsPerPlane==16 || pMode->BitsPerPlane==24 || pMode->BitsPerPlane==32))
  328.     {
  329.         return TRUE;
  330.     }
  331.     return FALSE;
  332. }
  333. #endif
  334.         if (VBoxDispVideoModeSupported(pMode))
  335.         {
  336.             cSupportedModes++;
  337.         }
  338.         else
  339.         {
  340.             pMode->Length = 0;
  341.         }

  342.         pMode = (PVIDEO_MODE_INFORMATION) (((PUCHAR)pMode)+numModes.ModeInformationLength);
  343.     }
  344.     *pcModes = cSupportedModes;

  345.     if (0==cSupportedModes)
  346.     {
  347.         WARN(("0 video modes supported!"));
  348.         EngFreeMem(pMiniportModes);
  349.         return VERR_NOT_SUPPORTED;
  350.     }

  351.     /* Allocate and zero output buffer */
  352.     *ppModesTable = (PVIDEO_MODE_INFORMATION)
  353.                     EngAllocMem(FL_ZERO_MEMORY, cSupportedModes*sizeof(VIDEO_MODE_INFORMATION), MEM_ALLOC_TAG);

  354.     if (!*ppModesTable)
  355.     {
  356.         WARN(("not enough memory!"));
  357.         EngFreeMem(pMiniportModes);
  358.         return VERR_NO_MEMORY;
  359.     }

  360.     //@4
  361.     /* Copy supported modes to output buffer */
  362.     pMode = pMiniportModes;
  363.     for (j=0, i=0; i<numModes.NumModes; ++i)
  364.     {
  365.         if (pMode->Length != 0)
  366.         {
  367.             memcpy(&(*ppModesTable)[j], pMode, numModes.ModeInformationLength);
  368.             ++j;
  369.         }

  370.         pMode = (PVIDEO_MODE_INFORMATION) (((PUCHAR)pMode)+numModes.ModeInformationLength);
  371.     }
  372.     Assert(j==cSupportedModes);

  373.     /* Free temp buffer */
  374.     EngFreeMem(pMiniportModes);

  375.     LOGF_LEAVE();
  376.     return VINF_SUCCESS;
  377. }



  378. /* Process Video Request Packet. */
  379. static BOOLEAN
  380. VBoxDrvStartIO(PVOID HwDeviceExtension, PVIDEO_REQUEST_PACKET RequestPacket)
  381. {
  382.     
  383.         /* Returns count of supported video modes and structure size in bytes,
  384.          * used to allocate buffer for the following IOCTL_VIDEO_QUERY_AVAIL_MODES call.
  385.          */
  386.         case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
  387.         {
  388.             STARTIO_OUT(VIDEO_NUM_MODES, pNumModes);

  389.             //硬编码生成显示模式列表,并保存在pExt
  390.             bResult = VBoxMPQueryNumAvailModes(pExt, pNumModes, pStatus);
  391.             break;
  392.         }

  393.         /* Returns information about supported video modes. */
  394.         case IOCTL_VIDEO_QUERY_AVAIL_MODES:
  395.         {
  396.             PVIDEO_MODE_INFORMATION pModes = (PVIDEO_MODE_INFORMATION) RequestPacket->OutputBuffer;

  397.             if (RequestPacket->OutputBufferLength < VBoxMPXpdmGetVideoModesCount(pExt)*sizeof(VIDEO_MODE_INFORMATION))
  398.             {
  399.                 pStatus->Status = ERROR_INSUFFICIENT_BUFFER;
  400.                 break;
  401.             }

  402.             //复制IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES保存在pExt的显示模式
  403.             bResult = VBoxMPQueryAvailModes(pExt, pModes, pStatus);
  404.             break;
  405.         }
  406. }


  407. // @2.2 鼠标支持模式
  408. // miniport所提供的画刷的能力caps
  409. //
  410. /* Called for IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES.
  411.  * Query supported hardware pointer feaures.
  412.  * Note: we always return all caps we could ever support,
  413.  * related functions will return errors if host doesn't accept pointer integration
  414.  * and force display driver to enter software fallback codepath.
  415.  */
  416. BOOLEAN VBoxMPQueryPointerCapabilities(PVBOXMP_DEVEXT pExt, PVIDEO_POINTER_CAPABILITIES pCaps, PSTATUS_BLOCK pStatus)
  417. {
  418.     LOGF_ENTER();

  419.     pStatus->Information = sizeof(VIDEO_POINTER_CAPABILITIES);

  420.     pCaps->Flags = VIDEO_MODE_ASYNC_POINTER | VIDEO_MODE_COLOR_POINTER | VIDEO_MODE_MONO_POINTER;
  421.     /* Up to 64x64 shapes */
  422.     pCaps->MaxWidth = 64;
  423.     pCaps->MaxHeight = 64;
  424.     /* Not used by our display driver */
  425.     pCaps->HWPtrBitmapStart = -1;
  426.     pCaps->HWPtrBitmapEnd = -1;

  427.     LOGF_LEAVE();
  428.     return TRUE;
  429. }


  430. // @2.3 画刷
  431. /* Creates default device palette */
  432. int VBoxDispInitPalette(PVBOXDISPDEV pDev, DEVINFO *pDevInfo)
  433. {
  434.     if (pDev->mode.ulBitsPerPel!=8)
  435.     {
  436.         pDev->hDefaultPalette = EngCreatePalette(PAL_BITFIELDS, 0, NULL,
  437.                                                  pDev->mode.flMaskR, pDev->mode.flMaskG, pDev->mode.flMaskB);

  438.         if (!pDev->hDefaultPalette)
  439.         {
  440.             WARN(("EngCreatePalette failed"));
  441.             return VERR_GENERAL_FAILURE;
  442.         }

  443.         pDevInfo->hpalDefault = pDev->hDefaultPalette;
  444.         return VINF_SUCCESS;
  445.     }

  446.     /* Create driver managed palette.
  447.      * First entry should be black (0,0,0), last should be while (255, 255, 255).
  448.      * Note: Other entries should be set in similar way, so that entries with complementing indicies
  449.      * have quite contrast colors stored.
  450.      */

  451.     pDev->pPalette = (PPALETTEENTRY) EngAllocMem(0, sizeof(PALETTEENTRY) * 256, MEM_ALLOC_TAG);
  452.     if (!pDev->pPalette)
  453.     {
  454.         WARN(("not enough memory!"));
  455.         return VERR_NO_MEMORY;
  456.     }

  457.     BYTE r=0, g=0, b=0;
  458.     for (ULONG i=0; i<256; ++i)
  459.     {
  460.         pDev->pPalette[i].peRed = r;
  461.         pDev->pPalette[i].peGreen = g;
  462.         pDev->pPalette[i].peBlue = b;
  463.         pDev->pPalette[i].peFlags = 0;

  464.         r += 32;
  465.         if (!r)
  466.         {
  467.             g += 32;
  468.             if (!g)
  469.             {
  470.                 b += 64;
  471.             }
  472.         }
  473.     }

  474.     /* Now overwrite window decoration colors by common ones */
  475.     for (ULONG i=0; i<RT_ELEMENTS(defPal); ++i)
  476.     {
  477.         pDev->pPalette[i] = defPal[i];
  478.         pDev->pPalette[(~i)&0xFF] = defPalComp[i];
  479.     }

  480.     /* Sanity check in case we'd change palette filling */
  481.     Assert(pDev->pPalette[0].peRed==0 && pDev->pPalette[0].peGreen==0 && pDev->pPalette[0].peBlue==0);
  482.     Assert(pDev->pPalette[255].peRed==255 && pDev->pPalette[255].peGreen==255 && pDev->pPalette[255].peBlue==255);

  483.     pDev->hDefaultPalette = EngCreatePalette(PAL_INDEXED, 256, (PULONG)pDev->pPalette, 0, 0, 0);
  484.     if (!pDev->hDefaultPalette)
  485.     {
  486.         WARN(("EngCreatePalette failed"));
  487.         EngFreeMem(pDev->pPalette);
  488.         pDev->pPalette = NULL;
  489.         return VERR_GENERAL_FAILURE;
  490.     }

  491.     pDevInfo->hpalDefault = pDev->hDefaultPalette;
  492.     return VINF_SUCCESS;
  493. }


阅读(1979) | 评论(0) | 转发(0) |
0

上一篇:vim 多个剪贴板

下一篇:DrvEnableDriver

给主人留下些什么吧!~~