Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

724 lines
23 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: screen.c
  3. *
  4. * Initializes the GDIINFO and DEVINFO structures for DrvEnablePDEV.
  5. *
  6. * Copyright (c) 1992 Microsoft Corporation
  7. \**************************************************************************/
  8. #include "driver.h"
  9. #define SYSTM_LOGFONT {16,7,0,0,700,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS, \
  10. CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,VARIABLE_PITCH | \
  11. FF_DONTCARE,L"System"}
  12. #define HELVE_LOGFONT {12,9,0,0,400,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS, \
  13. CLIP_STROKE_PRECIS,PROOF_QUALITY,VARIABLE_PITCH | \
  14. FF_DONTCARE,L"MS Sans Serif"}
  15. #define COURI_LOGFONT {12,9,0,0,400,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS, \
  16. CLIP_STROKE_PRECIS,PROOF_QUALITY,FIXED_PITCH | \
  17. FF_DONTCARE, L"Courier"}
  18. // This is the basic devinfo for a default driver. This is used as a base and customized based
  19. // on information passed back from the miniport driver.
  20. const DEVINFO gDevInfoFrameBuffer = {
  21. (GCAPS_OPAQUERECT | // Graphics capabilities
  22. GCAPS_PALMANAGED |
  23. GCAPS_ALTERNATEFILL |
  24. GCAPS_WINDINGFILL |
  25. GCAPS_MONO_DITHER |
  26. GCAPS_COLOR_DITHER ),
  27. // Should also implement GCAPS_HORIZSTRIKE so that the underlines
  28. // aren't drawn using DrvBitBlt
  29. SYSTM_LOGFONT, // Default font description
  30. HELVE_LOGFONT, // ANSI variable font description
  31. COURI_LOGFONT, // ANSI fixed font description
  32. 0, // Count of device fonts
  33. BMF_8BPP, // Preferred DIB format
  34. 8, // Width of color dither
  35. 8, // Height of color dither
  36. 0 // Default palette to use for this device
  37. };
  38. /******************************Public*Routine******************************\
  39. * bInitSURF
  40. *
  41. * Enables the surface. Maps the frame buffer into memory.
  42. *
  43. \**************************************************************************/
  44. BOOL bInitSURF(PPDEV ppdev, BOOL bFirst)
  45. {
  46. VIDEO_MEMORY VideoMemory;
  47. VIDEO_MEMORY_INFORMATION VideoMemoryInfo;
  48. DWORD ReturnedDataLength;
  49. // Set the mode.
  50. if (EngDeviceIoControl(ppdev->hDriver,
  51. IOCTL_VIDEO_SET_CURRENT_MODE,
  52. (LPVOID) &ppdev->ulMode, // input buffer
  53. sizeof(DWORD),
  54. NULL,
  55. 0,
  56. &ReturnedDataLength))
  57. {
  58. DISPDBG((0, "Failed SET_CURRENT_MODE\n"));
  59. return(FALSE);
  60. }
  61. if (bFirst)
  62. {
  63. // Get the linear memory address range.
  64. VideoMemory.RequestedVirtualAddress = NULL;
  65. if (EngDeviceIoControl(ppdev->hDriver,
  66. IOCTL_VIDEO_MAP_VIDEO_MEMORY,
  67. (PVOID) &VideoMemory, // input buffer
  68. sizeof (VIDEO_MEMORY),
  69. (PVOID) &VideoMemoryInfo, // output buffer
  70. sizeof (VideoMemoryInfo),
  71. &ReturnedDataLength))
  72. {
  73. DISPDBG((0, "Failed MAP_VIDEO_MEMORY\n"));
  74. return(FALSE);
  75. }
  76. }
  77. // Record the Frame Buffer Linear Address.
  78. if (bFirst)
  79. {
  80. ppdev->pjScreen = (PBYTE) VideoMemoryInfo.FrameBufferBase;
  81. }
  82. // Set the various write mode values, so we don't have to read before write
  83. // later on
  84. vSetWriteModes(&ppdev->ulrm0_wmX);
  85. // Initialize the VGA registers to their default states, so that we
  86. // can be sure of drawing properly even when the miniport didn't
  87. // happen to set them the way we like them:
  88. vInitRegs(ppdev);
  89. // Since we just did a mode-set, we'll be in non-planar mode. And make
  90. // sure we reset the bank manager (otherwise, after a switch from full-
  91. // screen, we may think we've got one bank mapped in, when in fact there's
  92. // a different one mapped in, and bad things would happen...).
  93. ppdev->flBank &= ~BANK_PLANAR;
  94. ppdev->rcl1WindowClip.bottom = -1;
  95. ppdev->rcl2WindowClip[0].bottom = -1;
  96. ppdev->rcl2WindowClip[1].bottom = -1;
  97. ppdev->rcl1PlanarClip.bottom = -1;
  98. ppdev->rcl2PlanarClip[0].bottom = -1;
  99. ppdev->rcl2PlanarClip[1].bottom = -1;
  100. return(TRUE);
  101. }
  102. /******************************Public*Routine******************************\
  103. * vDisableSURF
  104. *
  105. * Disable the surface. Un-Maps the frame in memory.
  106. *
  107. \**************************************************************************/
  108. VOID vDisableSURF(PPDEV ppdev)
  109. {
  110. DWORD returnedDataLength;
  111. VIDEO_MEMORY videoMemory;
  112. videoMemory.RequestedVirtualAddress = (PVOID) ppdev->pjScreen;
  113. if (EngDeviceIoControl(ppdev->hDriver,
  114. IOCTL_VIDEO_UNMAP_VIDEO_MEMORY,
  115. (LPVOID) &videoMemory,
  116. sizeof(VIDEO_MEMORY),
  117. NULL,
  118. 0,
  119. &returnedDataLength))
  120. {
  121. RIP("Failed UNMAP_VIDEO_MEMORY");
  122. }
  123. }
  124. /******************************Public*Routine******************************\
  125. * bInitPDEV
  126. *
  127. * Determine the mode we should be in based on the DEVMODE passed in.
  128. * Query mini-port to get information needed to fill in the DevInfo and the
  129. * GdiInfo .
  130. *
  131. \**************************************************************************/
  132. BOOL bInitPDEV(
  133. PPDEV ppdev,
  134. DEVMODEW *pDevMode,
  135. GDIINFO *pGdiInfo,
  136. DEVINFO *pDevInfo)
  137. {
  138. ULONG cModes;
  139. PVIDEO_MODE_INFORMATION pVideoBuffer, pVideoModeSelected, pVideoTemp;
  140. VIDEO_COLOR_CAPABILITIES colorCapabilities;
  141. ULONG ulTemp;
  142. BOOL bSelectDefault;
  143. ULONG cbModeSize;
  144. BANK_POSITION BankPosition;
  145. ULONG ulReturn;
  146. //
  147. // calls the miniport to get mode information.
  148. //
  149. cModes = getAvailableModes(ppdev->hDriver, &pVideoBuffer, &cbModeSize);
  150. if (cModes == 0)
  151. {
  152. DISPDBG((0, "vga256.dll: no available modes\n"));
  153. return(FALSE);
  154. }
  155. //
  156. // Determine if we are looking for a default mode.
  157. //
  158. if ( ((pDevMode->dmPelsWidth) ||
  159. (pDevMode->dmPelsHeight) ||
  160. (pDevMode->dmBitsPerPel) ||
  161. (pDevMode->dmDisplayFlags) ||
  162. (pDevMode->dmDisplayFrequency)) == 0)
  163. {
  164. bSelectDefault = TRUE;
  165. }
  166. else
  167. {
  168. bSelectDefault = FALSE;
  169. }
  170. //
  171. // Now see if the requested mode has a match in that table.
  172. //
  173. pVideoModeSelected = NULL;
  174. pVideoTemp = pVideoBuffer;
  175. while (cModes--)
  176. {
  177. if (pVideoTemp->Length != 0)
  178. {
  179. if (bSelectDefault ||
  180. ((pVideoTemp->VisScreenWidth == pDevMode->dmPelsWidth) &&
  181. (pVideoTemp->VisScreenHeight == pDevMode->dmPelsHeight) &&
  182. (pVideoTemp->BitsPerPlane *
  183. pVideoTemp->NumberOfPlanes == pDevMode->dmBitsPerPel) &&
  184. (pVideoTemp->Frequency == pDevMode->dmDisplayFrequency)))
  185. {
  186. pVideoModeSelected = pVideoTemp;
  187. DISPDBG((2, "vga256: Found a match\n")) ;
  188. break;
  189. }
  190. }
  191. pVideoTemp = (PVIDEO_MODE_INFORMATION)
  192. (((PUCHAR)pVideoTemp) + cbModeSize);
  193. }
  194. //
  195. // If no mode has been found, return an error
  196. //
  197. if (pVideoModeSelected == NULL)
  198. {
  199. DISPDBG((0, "vga256.dll: no valid modes\n"));
  200. EngFreeMem(pVideoBuffer);
  201. return(FALSE);
  202. }
  203. //
  204. // Fill in the GDIINFO data structure with the information returned from
  205. // the kernel driver.
  206. //
  207. ppdev->ulMode = pVideoModeSelected->ModeIndex;
  208. ppdev->cxScreen = pVideoModeSelected->VisScreenWidth;
  209. ppdev->cyScreen = pVideoModeSelected->VisScreenHeight;
  210. ppdev->ulBitCount = pVideoModeSelected->BitsPerPlane *
  211. pVideoModeSelected->NumberOfPlanes;
  212. ppdev->lDeltaScreen = pVideoModeSelected->ScreenStride;
  213. ppdev->flRed = pVideoModeSelected->RedMask;
  214. ppdev->flGreen = pVideoModeSelected->GreenMask;
  215. ppdev->flBlue = pVideoModeSelected->BlueMask;
  216. if (!(pVideoModeSelected->AttributeFlags & VIDEO_MODE_NO_OFF_SCREEN))
  217. {
  218. ppdev->fl |= DRIVER_OFFSCREEN_REFRESHED;
  219. }
  220. pGdiInfo->ulVersion = GDI_DRIVER_VERSION;
  221. pGdiInfo->ulTechnology = DT_RASDISPLAY;
  222. pGdiInfo->ulHorzSize = pVideoModeSelected->XMillimeter;
  223. pGdiInfo->ulVertSize = pVideoModeSelected->YMillimeter;
  224. pGdiInfo->ulHorzRes = ppdev->cxScreen;
  225. pGdiInfo->ulVertRes = ppdev->cyScreen;
  226. pGdiInfo->ulPanningHorzRes = ppdev->cxScreen;
  227. pGdiInfo->ulPanningVertRes = ppdev->cyScreen;
  228. pGdiInfo->cBitsPixel = pVideoModeSelected->BitsPerPlane;
  229. pGdiInfo->cPlanes = pVideoModeSelected->NumberOfPlanes;
  230. pGdiInfo->ulVRefresh = pVideoModeSelected->Frequency;
  231. pGdiInfo->ulBltAlignment = 8; // Prefer 8-pel alignment of windows
  232. // for fast text routines
  233. pGdiInfo->ulLogPixelsX = pDevMode->dmLogPixels;
  234. pGdiInfo->ulLogPixelsY = pDevMode->dmLogPixels;
  235. pGdiInfo->flTextCaps = TC_RA_ABLE | TC_SCROLLBLT;
  236. pGdiInfo->flRaster = 0; // DDI reservers flRaster
  237. pGdiInfo->ulDACRed = pVideoModeSelected->NumberRedBits;
  238. pGdiInfo->ulDACGreen = pVideoModeSelected->NumberGreenBits;
  239. pGdiInfo->ulDACBlue = pVideoModeSelected->NumberBlueBits;
  240. // Assuming palette is orthogonal - all colors are same size.
  241. ppdev->cPaletteShift = 8 - pGdiInfo->ulDACRed;
  242. pGdiInfo->ulAspectX = 0x24; // One-to-one aspect ratio
  243. pGdiInfo->ulAspectY = 0x24;
  244. pGdiInfo->ulAspectXY = 0x33;
  245. pGdiInfo->xStyleStep = 1; // A style unit is 3 pels
  246. pGdiInfo->yStyleStep = 1;
  247. pGdiInfo->denStyleStep = 3;
  248. pGdiInfo->ptlPhysOffset.x = 0;
  249. pGdiInfo->ptlPhysOffset.y = 0;
  250. pGdiInfo->szlPhysSize.cx = 0;
  251. pGdiInfo->szlPhysSize.cy = 0;
  252. // RGB and CMY color info.
  253. // try to get it from the miniport.
  254. // if the miniport doesn ot support this feature, use defaults.
  255. if (EngDeviceIoControl(ppdev->hDriver,
  256. IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES,
  257. NULL,
  258. 0,
  259. &colorCapabilities,
  260. sizeof(VIDEO_COLOR_CAPABILITIES),
  261. &ulTemp))
  262. {
  263. DISPDBG((1, "vga256 DISP getcolorCapabilities failed \n"));
  264. pGdiInfo->ciDevice.Red.x = 6700;
  265. pGdiInfo->ciDevice.Red.y = 3300;
  266. pGdiInfo->ciDevice.Red.Y = 0;
  267. pGdiInfo->ciDevice.Green.x = 2100;
  268. pGdiInfo->ciDevice.Green.y = 7100;
  269. pGdiInfo->ciDevice.Green.Y = 0;
  270. pGdiInfo->ciDevice.Blue.x = 1400;
  271. pGdiInfo->ciDevice.Blue.y = 800;
  272. pGdiInfo->ciDevice.Blue.Y = 0;
  273. pGdiInfo->ciDevice.AlignmentWhite.x = 3127;
  274. pGdiInfo->ciDevice.AlignmentWhite.y = 3290;
  275. pGdiInfo->ciDevice.AlignmentWhite.Y = 0;
  276. pGdiInfo->ciDevice.RedGamma = 20000;
  277. pGdiInfo->ciDevice.GreenGamma = 20000;
  278. pGdiInfo->ciDevice.BlueGamma = 20000;
  279. }
  280. else
  281. {
  282. pGdiInfo->ciDevice.Red.x = colorCapabilities.RedChromaticity_x;
  283. pGdiInfo->ciDevice.Red.y = colorCapabilities.RedChromaticity_y;
  284. pGdiInfo->ciDevice.Red.Y = 0;
  285. pGdiInfo->ciDevice.Green.x = colorCapabilities.GreenChromaticity_x;
  286. pGdiInfo->ciDevice.Green.y = colorCapabilities.GreenChromaticity_y;
  287. pGdiInfo->ciDevice.Green.Y = 0;
  288. pGdiInfo->ciDevice.Blue.x = colorCapabilities.BlueChromaticity_x;
  289. pGdiInfo->ciDevice.Blue.y = colorCapabilities.BlueChromaticity_y;
  290. pGdiInfo->ciDevice.Blue.Y = 0;
  291. pGdiInfo->ciDevice.AlignmentWhite.x = colorCapabilities.WhiteChromaticity_x;
  292. pGdiInfo->ciDevice.AlignmentWhite.y = colorCapabilities.WhiteChromaticity_y;
  293. pGdiInfo->ciDevice.AlignmentWhite.Y = colorCapabilities.WhiteChromaticity_Y;
  294. // if we have a color device store the three color gamma values,
  295. // otherwise store the unique gamma value in all three.
  296. if (colorCapabilities.AttributeFlags & VIDEO_DEVICE_COLOR)
  297. {
  298. pGdiInfo->ciDevice.RedGamma = colorCapabilities.RedGamma;
  299. pGdiInfo->ciDevice.GreenGamma = colorCapabilities.GreenGamma;
  300. pGdiInfo->ciDevice.BlueGamma = colorCapabilities.BlueGamma;
  301. }
  302. else
  303. {
  304. pGdiInfo->ciDevice.RedGamma = colorCapabilities.WhiteGamma;
  305. pGdiInfo->ciDevice.GreenGamma = colorCapabilities.WhiteGamma;
  306. pGdiInfo->ciDevice.BlueGamma = colorCapabilities.WhiteGamma;
  307. }
  308. };
  309. pGdiInfo->ciDevice.Cyan.x = 0;
  310. pGdiInfo->ciDevice.Cyan.y = 0;
  311. pGdiInfo->ciDevice.Cyan.Y = 0;
  312. pGdiInfo->ciDevice.Magenta.x = 0;
  313. pGdiInfo->ciDevice.Magenta.y = 0;
  314. pGdiInfo->ciDevice.Magenta.Y = 0;
  315. pGdiInfo->ciDevice.Yellow.x = 0;
  316. pGdiInfo->ciDevice.Yellow.y = 0;
  317. pGdiInfo->ciDevice.Yellow.Y = 0;
  318. // No dye correction for raster displays.
  319. pGdiInfo->ciDevice.MagentaInCyanDye = 0;
  320. pGdiInfo->ciDevice.YellowInCyanDye = 0;
  321. pGdiInfo->ciDevice.CyanInMagentaDye = 0;
  322. pGdiInfo->ciDevice.YellowInMagentaDye = 0;
  323. pGdiInfo->ciDevice.CyanInYellowDye = 0;
  324. pGdiInfo->ciDevice.MagentaInYellowDye = 0;
  325. // Fill in the rest of the devinfo and GdiInfo structures.
  326. pGdiInfo->ulNumColors = 20;
  327. pGdiInfo->ulNumPalReg = 1 << ppdev->ulBitCount;
  328. pGdiInfo->ulDevicePelsDPI = 0; // For printers only
  329. pGdiInfo->ulPrimaryOrder = PRIMARY_ORDER_CBA;
  330. pGdiInfo->ulHTPatternSize = HT_PATSIZE_4x4_M;
  331. pGdiInfo->ulHTOutputFormat = HT_FORMAT_8BPP;
  332. pGdiInfo->flHTFlags = HT_FLAG_ADDITIVE_PRIMS;
  333. // Fill in the basic devinfo structure
  334. *pDevInfo = gDevInfoFrameBuffer;
  335. EngFreeMem(pVideoBuffer);
  336. //
  337. // Try to determine if the miniport supports
  338. // IOCTL_VIDEO_SET_BANK_POSITION.
  339. //
  340. BankPosition.ReadBankPosition = 0;
  341. BankPosition.WriteBankPosition = 0;
  342. if (EngDeviceIoControl(ppdev->hDriver,
  343. IOCTL_VIDEO_SET_BANK_POSITION,
  344. &BankPosition,
  345. sizeof(BANK_POSITION),
  346. NULL,
  347. 0,
  348. &ulReturn) == NO_ERROR)
  349. {
  350. ppdev->BankIoctlSupported = TRUE;
  351. } else {
  352. ppdev->BankIoctlSupported = FALSE;
  353. }
  354. return(TRUE);
  355. }
  356. /******************************Public*Routine******************************\
  357. * VOID vInitSavedBits(ppdev)
  358. *
  359. * Initializes saved bits structures. Must be done after bank
  360. * initialization and vInitBrushCache.
  361. *
  362. \**************************************************************************/
  363. VOID vInitSavedBits(PPDEV ppdev)
  364. {
  365. if (!((ppdev->fl & DRIVER_OFFSCREEN_REFRESHED) &&
  366. (ppdev->fl & DRIVER_HAS_OFFSCREEN)))
  367. {
  368. return;
  369. }
  370. //
  371. // set up rect to right of visible screen
  372. //
  373. ppdev->rclSavedBitsRight.left = ppdev->cxScreen;
  374. ppdev->rclSavedBitsRight.top = 0;
  375. ppdev->rclSavedBitsRight.right = max((ppdev->lNextScan-PELS_PER_DWORD),
  376. ppdev->rclSavedBitsRight.left);
  377. ppdev->rclSavedBitsRight.bottom = ppdev->cyScreen;
  378. //
  379. // set up rect below visible screen
  380. //
  381. ppdev->rclSavedBitsBottom.left = 0;
  382. ppdev->rclSavedBitsBottom.top = ppdev->cyScreen;
  383. ppdev->rclSavedBitsBottom.right = ppdev->rclSavedBitsRight.right;
  384. ppdev->rclSavedBitsBottom.bottom = ppdev->cTotalScans - BRUSH_MAX_CACHE_SCANS;
  385. //
  386. // NOTE: we have subtracted one DWORD from the right edge. This is because
  387. // later it is assumed that we can align by right shifting by up to
  388. // one DWORD (unless of course, the width of the buffer is 0).
  389. //
  390. ppdev->bBitsSaved = FALSE;
  391. DISPDBG((1,"ppdev->rclSavedBitsRight = (%04x,%04x,%04x,%04x) %lux%lu\n",
  392. ppdev->rclSavedBitsRight.left,
  393. ppdev->rclSavedBitsRight.top,
  394. ppdev->rclSavedBitsRight.right,
  395. ppdev->rclSavedBitsRight.bottom,
  396. ppdev->rclSavedBitsRight.right - ppdev->rclSavedBitsRight.left,
  397. ppdev->rclSavedBitsRight.bottom - ppdev->rclSavedBitsRight.top
  398. ));
  399. DISPDBG((1,"ppdev->rclSavedBitsBottom = (%04x,%04x,%04x,%04x) %lux%lu\n",
  400. ppdev->rclSavedBitsBottom.left,
  401. ppdev->rclSavedBitsBottom.top,
  402. ppdev->rclSavedBitsBottom.right,
  403. ppdev->rclSavedBitsBottom.bottom,
  404. ppdev->rclSavedBitsBottom.right - ppdev->rclSavedBitsBottom.left,
  405. ppdev->rclSavedBitsBottom.bottom - ppdev->rclSavedBitsBottom.top
  406. ));
  407. return;
  408. }
  409. /******************************Public*Routine******************************\
  410. * VOID vInitBrushCache(ppdev)
  411. *
  412. * Initializes various brush cache structures. Must be done after bank
  413. * initialization.
  414. *
  415. \**************************************************************************/
  416. VOID vInitBrushCache(PPDEV ppdev)
  417. {
  418. LONG cCacheBrushesPerScan = ppdev->lNextScan / BRUSH_SIZE;
  419. LONG cCacheScans;
  420. LONG cCacheEntries;
  421. LONG i;
  422. LONG j;
  423. BRUSHCACHEENTRY* pbce;
  424. if (ppdev->cyScreen + BRUSH_MAX_CACHE_SCANS > (ULONG) ppdev->cTotalScans)
  425. {
  426. goto InitFailed;
  427. }
  428. cCacheScans = BRUSH_MAX_CACHE_SCANS;
  429. cCacheEntries = cCacheScans * cCacheBrushesPerScan;
  430. ppdev->pbceCache = (BRUSHCACHEENTRY*) EngAllocMem(FL_ZERO_MEMORY,
  431. cCacheEntries * sizeof(BRUSHCACHEENTRY), ALLOC_TAG);
  432. if (ppdev->pbceCache == NULL)
  433. {
  434. goto InitFailed;
  435. }
  436. // We successfully managed to allocate all our data structures for looking
  437. // after off-screen memory, so set the flag saying that we can use it
  438. // (note that if ppdev->fl's DRIVER_OFFSCREEN_REFRESHED hasn't been set, the
  439. // memory cannot be used for long-term storage):
  440. ppdev->fl |= DRIVER_HAS_OFFSCREEN;
  441. ppdev->iCache = 0; // 0 is a reserved index
  442. ppdev->iCacheLast = cCacheEntries - 1;
  443. // Initialize our cache entry array:
  444. pbce = &ppdev->pbceCache[0];
  445. for (i = (ppdev->cTotalScans-BRUSH_MAX_CACHE_SCANS); i < ppdev->cTotalScans; i++)
  446. {
  447. for (j = 0; j < cCacheBrushesPerScan; j++)
  448. {
  449. // Bitmap offset is in planar format, where every byte is one
  450. // quadpixel:
  451. pbce->yCache = i;
  452. pbce->ulCache = (i * ppdev->lNextScan + j * BRUSH_SIZE) / 4;
  453. // This verification pointer doesn't actually have to be
  454. // initialized, but we do so for debugging purposes:
  455. pbce->prbVerifyRealization = NULL;
  456. pbce++;
  457. }
  458. }
  459. return;
  460. InitFailed:
  461. ppdev->fl &= ~(DRIVER_OFFSCREEN_REFRESHED | DRIVER_HAS_OFFSCREEN);
  462. return;
  463. }
  464. /******************************Public*Routine******************************\
  465. * VOID vResetBrushCache(ppdev)
  466. *
  467. * Blows away the brush cache entries -- this is useful when switching
  468. * out of full-screen mode, where anyone could have written over the video
  469. * memory where we cache our brushes.
  470. *
  471. \**************************************************************************/
  472. VOID vResetBrushCache(PPDEV ppdev)
  473. {
  474. BRUSHCACHEENTRY* pbce;
  475. LONG i;
  476. // Make sure we actually have a brush cache before we try to reset it:
  477. if (ppdev->fl & DRIVER_HAS_OFFSCREEN)
  478. {
  479. pbce = &ppdev->pbceCache[0];
  480. for (i = ppdev->iCacheLast; i >= 0; i--)
  481. {
  482. pbce->prbVerifyRealization = NULL;
  483. pbce++;
  484. }
  485. }
  486. }
  487. /******************************Public*Routine******************************\
  488. * VOID vDisableBrushCache(ppdev)
  489. *
  490. * Frees various brush cache structures.
  491. *
  492. \**************************************************************************/
  493. VOID vDisableBrushCache(PPDEV ppdev)
  494. {
  495. if (ppdev->pbceCache != NULL)
  496. {
  497. EngFreeMem(ppdev->pbceCache);
  498. }
  499. }
  500. /******************************Public*Routine******************************\
  501. * getAvailableModes
  502. *
  503. * Calls the miniport to get the list of modes supported by the kernel driver,
  504. * and returns the list of modes supported by the diplay driver among those
  505. *
  506. * returns the number of entries in the videomode buffer.
  507. * 0 means no modes are supported by the miniport or that an error occured.
  508. *
  509. * NOTE: the buffer must be freed up by the caller.
  510. *
  511. \**************************************************************************/
  512. DWORD getAvailableModes(
  513. HANDLE hDriver,
  514. PVIDEO_MODE_INFORMATION *modeInformation,
  515. DWORD *cbModeSize)
  516. {
  517. ULONG ulTemp;
  518. VIDEO_NUM_MODES modes;
  519. PVIDEO_MODE_INFORMATION pVideoTemp;
  520. //
  521. // Get the number of modes supported by the mini-port
  522. //
  523. if (EngDeviceIoControl(hDriver,
  524. IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES,
  525. NULL,
  526. 0,
  527. &modes,
  528. sizeof(VIDEO_NUM_MODES),
  529. &ulTemp))
  530. {
  531. DISPDBG((0, "vga256 getAvailableModes failed VIDEO_QUERY_NUM_AVAIL_MODES\n"));
  532. return(0);
  533. }
  534. *cbModeSize = modes.ModeInformationLength;
  535. //
  536. // Allocate the buffer for the mini-port to write the modes in.
  537. //
  538. *modeInformation = (PVIDEO_MODE_INFORMATION)
  539. EngAllocMem(FL_ZERO_MEMORY,
  540. modes.NumModes *
  541. modes.ModeInformationLength, ALLOC_TAG);
  542. if (*modeInformation == (PVIDEO_MODE_INFORMATION) NULL)
  543. {
  544. DISPDBG((0, "vga256 getAvailableModes failed EngAllocMem\n"));
  545. return 0;
  546. }
  547. //
  548. // Ask the mini-port to fill in the available modes.
  549. //
  550. if (EngDeviceIoControl(hDriver,
  551. IOCTL_VIDEO_QUERY_AVAIL_MODES,
  552. NULL,
  553. 0,
  554. *modeInformation,
  555. modes.NumModes * modes.ModeInformationLength,
  556. &ulTemp))
  557. {
  558. DISPDBG((0, "vga256 getAvailableModes failed VIDEO_QUERY_AVAIL_MODES\n"));
  559. EngFreeMem(*modeInformation);
  560. *modeInformation = (PVIDEO_MODE_INFORMATION) NULL;
  561. return(0);
  562. }
  563. //
  564. // Now see which of these modes are supported by the display driver.
  565. // As an internal mechanism, set the length to 0 for the modes we
  566. // DO NOT support.
  567. //
  568. ulTemp = modes.NumModes;
  569. pVideoTemp = *modeInformation;
  570. //
  571. // Mode is rejected if it is not one plane, or not graphics, or is not
  572. // one of 8 bits per pel (that is all the vga 256 currently supports)
  573. //
  574. while (ulTemp--)
  575. {
  576. if ((pVideoTemp->NumberOfPlanes != 1 ) ||
  577. !(pVideoTemp->AttributeFlags & VIDEO_MODE_GRAPHICS) ||
  578. (pVideoTemp->AttributeFlags & VIDEO_MODE_LINEAR) ||
  579. (pVideoTemp->BitsPerPlane != 8) ||
  580. (BROKEN_RASTERS(pVideoTemp->ScreenStride,
  581. pVideoTemp->VisScreenHeight)))
  582. {
  583. pVideoTemp->Length = 0;
  584. }
  585. pVideoTemp = (PVIDEO_MODE_INFORMATION)
  586. (((PUCHAR)pVideoTemp) + modes.ModeInformationLength);
  587. }
  588. return modes.NumModes;
  589. }