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.

1744 lines
61 KiB

  1. /******************************Module*Header**********************************\
  2. *
  3. * *******************
  4. * * GDI SAMPLE CODE *
  5. * *******************
  6. *
  7. * Module Name: enable.c
  8. *
  9. * Content:
  10. *
  11. * This module contains the functions that enable and disable the
  12. * driver, the pdev, and the surface.
  13. *
  14. * Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
  15. * Copyright (c) 1995-2003 Microsoft Corporation. All rights reserved.
  16. \*****************************************************************************/
  17. #include "precomp.h"
  18. #include "glint.h"
  19. DWORD g_dwTag = (DWORD) 0;
  20. HSEMAPHORE g_cs = (HSEMAPHORE)0;
  21. /******************************Public*Structure****************************\
  22. * GDIINFO ggdiDefault
  23. *
  24. * This contains the default GDIINFO fields that are passed back to GDI
  25. * during DrvEnablePDEV.
  26. *
  27. * NOTE: This structure defaults to values for an 8bpp palette device.
  28. * Some fields are overwritten for different colour depths.
  29. \**************************************************************************/
  30. GDIINFO ggdiDefault = {
  31. GDI_DRIVER_VERSION, // ulVersion
  32. DT_RASDISPLAY, // ulTechnology
  33. 0, // ulHorzSize (filled in later)
  34. 0, // ulVertSize (filled in later)
  35. 0, // ulHorzRes (filled in later)
  36. 0, // ulVertRes (filled in later)
  37. 0, // cBitsPixel (filled in later)
  38. 0, // cPlanes (filled in later)
  39. 20, // ulNumColors (palette managed)
  40. 0, // flRaster (DDI reserved field)
  41. 0, // ulLogPixelsX (filled in later)
  42. 0, // ulLogPixelsY (filled in later)
  43. TC_RA_ABLE, // flTextCaps -- If we had wanted console windows
  44. // to scroll by repainting the entire window,
  45. // instead of doing a screen-to-screen blt, we
  46. // would have set TC_SCROLLBLT (yes, the flag is
  47. // bass-ackwards).
  48. 0, // ulDACRed (filled in later)
  49. 0, // ulDACGreen (filled in later)
  50. 0, // ulDACBlue (filled in later)
  51. 0x0024, // ulAspectX
  52. 0x0024, // ulAspectY
  53. 0x0033, // ulAspectXY (one-to-one aspect ratio)
  54. 1, // xStyleStep
  55. 1, // yStyleSte;
  56. 3, // denStyleStep -- Styles have a one-to-one aspect
  57. // ratio, and every 'dot' is 3 pixels long
  58. { 0, 0 }, // ptlPhysOffset
  59. { 0, 0 }, // szlPhysSize
  60. 256, // ulNumPalReg
  61. // These fields are for halftone initialization. The actual values are
  62. // a bit magic, but seem to work well on our display.
  63. { // ciDevice
  64. { 6700, 3300, 0 }, // Red
  65. { 2100, 7100, 0 }, // Green
  66. { 1400, 800, 0 }, // Blue
  67. { 1750, 3950, 0 }, // Cyan
  68. { 4050, 2050, 0 }, // Magenta
  69. { 4400, 5200, 0 }, // Yellow
  70. { 3127, 3290, 0 }, // AlignmentWhite
  71. 20000, // RedGamma
  72. 20000, // GreenGamma
  73. 20000, // BlueGamma
  74. 0, 0, 0, 0, 0, 0 // No dye correction for raster displays
  75. },
  76. 0, // ulDevicePelsDPI (for printers only)
  77. PRIMARY_ORDER_CBA, // ulPrimaryOrder
  78. HT_PATSIZE_4x4_M, // ulHTPatternSize
  79. HT_FORMAT_8BPP, // ulHTOutputFormat
  80. HT_FLAG_ADDITIVE_PRIMS, // flHTFlags
  81. 0, // ulVRefresh
  82. 0, // ulPanningHorzRes
  83. 0, // ulPanningVertRes
  84. 0, // ulBltAlignment
  85. };
  86. /******************************Public*Structure****************************\
  87. * DEVINFO gdevinfoDefault
  88. *
  89. * This contains the default DEVINFO fields that are passed back to GDI
  90. * during DrvEnablePDEV.
  91. *
  92. * NOTE: This structure defaults to values for an 8bpp palette device.
  93. * Some fields are overwritten for different colour depths.
  94. \**************************************************************************/
  95. #define SYSTM_LOGFONT {16,7,0,0,700,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,\
  96. CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,\
  97. VARIABLE_PITCH | FF_DONTCARE,L"System"}
  98. #define HELVE_LOGFONT {12,9,0,0,400,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,\
  99. CLIP_STROKE_PRECIS,PROOF_QUALITY,\
  100. VARIABLE_PITCH | FF_DONTCARE,L"MS Sans Serif"}
  101. #define COURI_LOGFONT {12,9,0,0,400,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,\
  102. CLIP_STROKE_PRECIS,PROOF_QUALITY,\
  103. FIXED_PITCH | FF_DONTCARE, L"Courier"}
  104. DEVINFO gdevinfoDefault = {
  105. (GCAPS_OPAQUERECT |
  106. GCAPS_DITHERONREALIZE |
  107. GCAPS_PALMANAGED |
  108. GCAPS_ALTERNATEFILL |
  109. GCAPS_WINDINGFILL |
  110. GCAPS_MONO_DITHER |
  111. #if WNT_DDRAW
  112. GCAPS_DIRECTDRAW |
  113. #endif // WNT_DDRAW
  114. GCAPS_COLOR_DITHER |
  115. GCAPS_ASYNCMOVE), // NOTE: Only enable ASYNCMOVE if your code
  116. // and hardware can handle DrvMovePointer
  117. // calls at any time, even while another
  118. // thread is in the middle of a drawing
  119. // call such as DrvBitBlt.
  120. // flGraphicsFlags
  121. SYSTM_LOGFONT, // lfDefaultFont
  122. HELVE_LOGFONT, // lfAnsiVarFont
  123. COURI_LOGFONT, // lfAnsiFixFont
  124. 0, // cFonts
  125. BMF_8BPP, // iDitherFormat
  126. 8, // cxDither
  127. 8, // cyDither
  128. 0, // hpalDefault (filled in later)
  129. #if(_WIN32_WINNT >= 0x500)
  130. GCAPS2_CHANGEGAMMARAMP, // flGraphicsCaps2
  131. #endif // (_WIN32_WINNT >= 0x500)
  132. };
  133. /******************************Public*Structure****************************\
  134. * DFVFN gadrvfn[]
  135. *
  136. * Build the driver function table gadrvfn with function index/address
  137. * pairs. This table tells GDI which DDI calls we support, and their
  138. * location (GDI does an indirect call through this table to call us).
  139. *
  140. * Why haven't we implemented DrvSaveScreenBits? To save code.
  141. *
  142. * When the driver doesn't hook DrvSaveScreenBits, USER simulates on-
  143. * the-fly by creating a temporary device-format-bitmap, and explicitly
  144. * calling DrvCopyBits to save/restore the bits. Since we already hook
  145. * DrvCreateDeviceBitmap, we'll end up using off-screen memory to store
  146. * the bits anyway (which would have been the main reason for implementing
  147. * DrvSaveScreenBits). So we may as well save some working set.
  148. \**************************************************************************/
  149. #if DBG || !SYNCHRONIZEACCESS_WORKS
  150. // gadrvfn [] - these entries must be in ascending index order, bad things
  151. // will happen if they aren't.
  152. // In this debug version we always thunk because we have to explicitly
  153. // lock between 2D and 3D operations. DrvEscape doesn't lock.
  154. DRVFN gadrvfn[] = {
  155. { INDEX_DrvEnablePDEV, (PFN) DbgEnablePDEV }, // 0
  156. { INDEX_DrvCompletePDEV, (PFN) DbgCompletePDEV }, // 1
  157. { INDEX_DrvDisablePDEV, (PFN) DbgDisablePDEV }, // 2
  158. { INDEX_DrvEnableSurface, (PFN) DbgEnableSurface }, // 3
  159. { INDEX_DrvDisableSurface, (PFN) DbgDisableSurface }, // 4
  160. { INDEX_DrvAssertMode, (PFN) DbgAssertMode }, // 5
  161. { INDEX_DrvResetPDEV, (PFN) DbgResetPDEV, }, // 7
  162. { INDEX_DrvDisableDriver, (PFN) DbgDisableDriver, }, // 8
  163. { INDEX_DrvCreateDeviceBitmap, (PFN) DbgCreateDeviceBitmap }, // 10
  164. { INDEX_DrvDeleteDeviceBitmap, (PFN) DbgDeleteDeviceBitmap }, // 11
  165. { INDEX_DrvRealizeBrush, (PFN) DbgRealizeBrush }, // 12
  166. { INDEX_DrvDitherColor, (PFN) DbgDitherColor }, // 13
  167. { INDEX_DrvStrokePath, (PFN) DbgStrokePath }, // 14
  168. { INDEX_DrvFillPath, (PFN) DbgFillPath }, // 15
  169. { INDEX_DrvPaint, (PFN) DbgPaint }, // 17
  170. { INDEX_DrvBitBlt, (PFN) DbgBitBlt }, // 18
  171. { INDEX_DrvCopyBits, (PFN) DbgCopyBits }, // 19
  172. // { INDEX_DrvStretchBlt, (PFN) DbgStretchBlt, }, // 20
  173. { INDEX_DrvSetPalette, (PFN) DbgSetPalette }, // 22 (SetPalette)
  174. { INDEX_DrvTextOut, (PFN) DbgTextOut }, // 23 (TextOut)
  175. { INDEX_DrvEscape, (PFN) DbgEscape }, // 24
  176. { INDEX_DrvSetPointerShape, (PFN) DbgSetPointerShape }, // 29
  177. { INDEX_DrvMovePointer, (PFN) DbgMovePointer }, // 30
  178. { INDEX_DrvLineTo, (PFN) DbgLineTo }, // 31
  179. { INDEX_DrvSynchronize, (PFN) DbgSynchronize }, // 38
  180. { INDEX_DrvGetModes, (PFN) DbgGetModes }, // 41
  181. #if WNT_DDRAW
  182. { INDEX_DrvGetDirectDrawInfo, (PFN) DbgGetDirectDrawInfo }, // 59
  183. { INDEX_DrvEnableDirectDraw, (PFN) DbgEnableDirectDraw }, // 60
  184. { INDEX_DrvDisableDirectDraw, (PFN) DbgDisableDirectDraw }, // 61
  185. #endif // WNT_DDRAW
  186. #if(_WIN32_WINNT >= 0x500)
  187. { INDEX_DrvIcmSetDeviceGammaRamp, (PFN) DbgIcmSetDeviceGammaRamp }, // 67
  188. //@@BEGIN_DDKSPLIT
  189. // Currently we don't actually have any code to accelerate the following 3 new
  190. // NT5 GDI features, and because P3 driver uses the NT4 driver's way to support
  191. // device bitmap, hooking the entries here will cause failure if strectching is
  192. // involved.
  193. //@@END_DDKSPLIT
  194. #if defined(_NT5GDI)
  195. { INDEX_DrvGradientFill, (PFN) DbgGradientFill }, // 68
  196. { INDEX_DrvAlphaBlend, (PFN) DbgAlphaBlend }, // 71
  197. { INDEX_DrvTransparentBlt, (PFN) DbgTransparentBlt }, // 74
  198. #endif
  199. { INDEX_DrvNotify, (PFN) DbgNotify }, // 87
  200. //azn { INDEX_DrvDeriveSurface, (PFN) DrvDeriveSurface },
  201. #endif // (_WIN32_WINNT >= 0x500)
  202. };
  203. #else // DBG || !SYNCHRONIZEACCESS_WORKS
  204. // gadrvfn [] - these entries must be in ascending index order, bad things
  205. // will happen if they aren't.
  206. // On Free builds, directly call the appropriate functions...
  207. //
  208. DRVFN gadrvfn[] = {
  209. { INDEX_DrvEnablePDEV, (PFN) DrvEnablePDEV }, // 0
  210. { INDEX_DrvCompletePDEV, (PFN) DrvCompletePDEV }, // 1
  211. { INDEX_DrvDisablePDEV, (PFN) DrvDisablePDEV }, // 2
  212. { INDEX_DrvEnableSurface, (PFN) DrvEnableSurface }, // 3
  213. { INDEX_DrvDisableSurface, (PFN) DrvDisableSurface }, // 4
  214. { INDEX_DrvAssertMode, (PFN) DrvAssertMode }, // 5
  215. { INDEX_DrvResetPDEV, (PFN) DrvResetPDEV, }, // 7
  216. { INDEX_DrvDisableDriver, (PFN) DrvDisableDriver, }, // 8
  217. { INDEX_DrvCreateDeviceBitmap, (PFN) DrvCreateDeviceBitmap }, // 10
  218. { INDEX_DrvDeleteDeviceBitmap, (PFN) DrvDeleteDeviceBitmap }, // 11
  219. { INDEX_DrvRealizeBrush, (PFN) DrvRealizeBrush }, // 12
  220. { INDEX_DrvDitherColor, (PFN) DrvDitherColor }, // 13
  221. { INDEX_DrvStrokePath, (PFN) DrvStrokePath }, // 14
  222. { INDEX_DrvFillPath, (PFN) DrvFillPath }, // 15
  223. { INDEX_DrvPaint, (PFN) DrvPaint }, // 17
  224. { INDEX_DrvBitBlt, (PFN) DrvBitBlt }, // 18
  225. { INDEX_DrvCopyBits, (PFN) DrvCopyBits }, // 19
  226. // { INDEX_DrvStretchBlt, (PFN) DrvStretchBlt, }, // 20
  227. { INDEX_DrvSetPalette, (PFN) DrvSetPalette }, // 22 (SetPalette)
  228. { INDEX_DrvTextOut, (PFN) DrvTextOut }, // 23 (TextOut)
  229. { INDEX_DrvEscape, (PFN) DrvEscape }, // 24
  230. { INDEX_DrvSetPointerShape, (PFN) DrvSetPointerShape }, // 29
  231. { INDEX_DrvMovePointer, (PFN) DrvMovePointer }, // 30
  232. { INDEX_DrvLineTo, (PFN) DrvLineTo }, // 31
  233. { INDEX_DrvSynchronize, (PFN) DrvSynchronize }, // 38
  234. { INDEX_DrvGetModes, (PFN) DrvGetModes }, // 41
  235. #if WNT_DDRAW
  236. { INDEX_DrvGetDirectDrawInfo, (PFN) DrvGetDirectDrawInfo }, // 59
  237. { INDEX_DrvEnableDirectDraw, (PFN) DrvEnableDirectDraw }, // 60
  238. { INDEX_DrvDisableDirectDraw, (PFN) DrvDisableDirectDraw }, // 61
  239. #endif // WNT_DDRAW
  240. #if(_WIN32_WINNT >= 0x500)
  241. { INDEX_DrvIcmSetDeviceGammaRamp, (PFN) DrvIcmSetDeviceGammaRamp }, // 67
  242. #if defined(_NT5GDI)
  243. { INDEX_DrvGradientFill, (PFN) DrvGradientFill }, // 68
  244. { INDEX_DrvAlphaBlend, (PFN) DrvAlphaBlend }, // 71
  245. { INDEX_DrvTransparentBlt, (PFN) DrvTransparentBlt }, // 74
  246. #endif
  247. { INDEX_DrvNotify, (PFN) DrvNotify }, // 87
  248. //azn { INDEX_DrvDeriveSurface, (PFN) DrvDeriveSurface },
  249. #endif // (_WIN32_WINNT >= 0x500)
  250. };
  251. #endif // DBG || !SYNCHRONIZEACCESS_WORKS
  252. ULONG gcdrvfn = sizeof(gadrvfn) / sizeof(DRVFN);
  253. /******************************Public*Routine******************************\
  254. * BOOL DrvResetPDEV
  255. *
  256. * Notifies the driver of a dynamic mode change.
  257. *
  258. \**************************************************************************/
  259. BOOL DrvResetPDEV(
  260. DHPDEV dhpdevOld,
  261. DHPDEV dhpdevNew)
  262. {
  263. PDEV* ppdevNew = (PDEV*) dhpdevNew;
  264. PDEV* ppdevOld = (PDEV*) dhpdevOld;
  265. BOOL bRet = TRUE;
  266. DISPDBG((DBGLVL, "DrvResetPDEV called: oldPDEV = 0x%x, newPDEV = 0x%x",
  267. ppdevOld, ppdevNew));
  268. #if WNT_DDRAW
  269. _DD_DDE_ResetPPDEV(ppdevOld, ppdevNew);
  270. #endif
  271. return(bRet);
  272. }
  273. /******************************Public*Routine******************************\
  274. * BOOL DrvEnableDriver
  275. *
  276. * Enables the driver by retrieving the drivers function table and version.
  277. *
  278. \**************************************************************************/
  279. // We define here DDI_DRIVER_VERSION_NT5_01 in order to be able to compile
  280. // inside the DX DDK. In the Whistler DDK this shouldn't be necessary
  281. #ifndef DDI_DRIVER_VERSION_NT5_01
  282. #define DDI_DRIVER_VERSION_NT5_01 0x00030100
  283. #endif
  284. BOOL DrvEnableDriver(
  285. ULONG iEngineVersion,
  286. ULONG cj,
  287. DRVENABLEDATA* pded)
  288. {
  289. // Set up the indirect information, a multi-boardsystem will call
  290. // the mul functions a single board system will use the one functions
  291. DISPDBG((DBGLVL, "DrvEnableDriver called: gc %d, ga 0x%x",
  292. gcdrvfn, gadrvfn));
  293. // Engine Version is passed down so future drivers can support previous
  294. // engine versions. A next generation driver can support both the old
  295. // and new engine conventions if told what version of engine it is
  296. // working with. For the first version the driver does nothing with it.
  297. // Fill in as much as we can.
  298. if (cj >= (sizeof(ULONG) *3))
  299. {
  300. pded->pdrvfn = gadrvfn;
  301. }
  302. if (cj >= (sizeof(ULONG) * 2))
  303. {
  304. pded->c = gcdrvfn;
  305. }
  306. // DDI version this driver was targeted for is passed back to engine.
  307. // Future graphic's engine may break calls down to old driver format.
  308. if (cj >= sizeof(ULONG))
  309. {
  310. // Ordered list of supported DDI versions
  311. ULONG SupportedVersions[] = {
  312. DDI_DRIVER_VERSION_NT5,
  313. DDI_DRIVER_VERSION_NT5_01,
  314. };
  315. int i = sizeof(SupportedVersions)/sizeof(SupportedVersions[0]);
  316. // Look for highest version also supported by engine
  317. while (--i >= 0)
  318. {
  319. if (SupportedVersions[i] <= iEngineVersion)
  320. {
  321. break;
  322. }
  323. }
  324. // Fail if there is no common DDI support
  325. if (i < 0)
  326. {
  327. return FALSE;
  328. }
  329. pded->iDriverVersion = SupportedVersions[i];
  330. }
  331. // Initialize sync semaphore.
  332. g_cs = EngCreateSemaphore();
  333. if (g_cs)
  334. {
  335. return(TRUE);
  336. }
  337. else
  338. {
  339. return(FALSE);
  340. }
  341. }
  342. /******************************Public*Routine******************************\
  343. * VOID DrvDisableDriver
  344. *
  345. * Tells the driver it is being disabled. Release any resources allocated in
  346. * DrvEnableDriver.
  347. *
  348. \**************************************************************************/
  349. VOID DrvDisableDriver(VOID)
  350. {
  351. DISPDBG((DBGLVL, "DrvDisableDriver called:"));
  352. return;
  353. }
  354. /******************************Public*Routine******************************\
  355. * DHPDEV DrvEnablePDEV
  356. *
  357. * Initializes a bunch of fields for GDI, based on the mode we've been asked
  358. * to do. This is the first thing called after DrvEnableDriver, when GDI
  359. * wants to get some information about us.
  360. *
  361. \**************************************************************************/
  362. DHPDEV DrvEnablePDEV(
  363. DEVMODEW* pdm, // Contains data pertaining to requested mode
  364. PWSTR pwszLogAddr, // Logical address
  365. ULONG cPat, // Count of standard patterns
  366. HSURF* phsurfPatterns, // Buffer for standard patterns
  367. ULONG cjCaps, // Size of buffer for device caps 'pdevcaps'
  368. ULONG* pdevcaps, // Buffer for device caps, also known as 'gdiinfo'
  369. ULONG cjDevInfo, // Number of bytes in device info 'pdi'
  370. DEVINFO* pdi, // Device information
  371. HDEV hdev, // HDEV, used for callbacks
  372. PWSTR pwszDeviceName, // Device name
  373. HANDLE hDriver) // Kernel driver handle
  374. {
  375. PDEV* ppdev;
  376. ULONG cjOut;
  377. // Future versions of NT had better supply 'devcaps' and 'devinfo'
  378. // structures that are the same size or larger than the current
  379. // structures:
  380. if ((cjCaps < sizeof(GDIINFO)) || (cjDevInfo < sizeof(DEVINFO)))
  381. {
  382. DISPDBG((ERRLVL, "DrvEnablePDEV - Buffer size too small"));
  383. goto ReturnFailure0;
  384. }
  385. // Allocate a physical device structure. Note that we definitely
  386. // rely on the zero initialization:
  387. ppdev = (PDEV*) ENGALLOCMEM(FL_ZERO_MEMORY, sizeof(PDEV), ALLOC_TAG_GDI(2));
  388. if (ppdev == NULL)
  389. {
  390. DISPDBG((ERRLVL, "DrvEnablePDEV - Failed memory allocation"));
  391. goto ReturnFailure0;
  392. }
  393. ppdev->hDriver = hDriver;
  394. if (!bAllocateGlintInfo(ppdev))
  395. {
  396. DISPDBG((ERRLVL, "DrvEnablePDEV - Failed bAllocateGlintInfo"));
  397. goto ReturnFailure1;
  398. }
  399. // initially assume we are allowed to create our off-screen resources.
  400. // If we decide not to create them, unset the appropriate bit. After,
  401. // initialization, we can temporarily disable a resource by unsetting
  402. // its ENABLE bit.
  403. ppdev->flStatus = ENABLE_DEV_BITMAPS;
  404. #if (_WIN32_WINNT >= 0x500 && WNT_DDRAW)
  405. // Any DX capable card can support linear heaps. Assume we can support
  406. // linear heaps here, this value may be updated in bEnableOffscreenHeap()
  407. ppdev->flStatus |= ENABLE_LINEAR_HEAP;
  408. #endif //(_WIN32_WINNT >= 0x500)
  409. // Get the current screen mode information. Set up device caps and
  410. // devinfo:
  411. if (!bInitializeModeFields(ppdev, (GDIINFO*) pdevcaps, pdi, pdm))
  412. {
  413. DISPDBG((ERRLVL, "DrvEnablePDEV - Failed bInitializeModeFields"));
  414. goto ReturnFailure1;
  415. }
  416. // Initialize palette information.
  417. if (!bInitializePalette(ppdev, pdi))
  418. {
  419. DISPDBG((ERRLVL, "DrvEnablePDEV - Failed bInitializePalette"));
  420. goto ReturnFailure1;
  421. }
  422. // initialize the image download scratch area and the TexelLUT palette
  423. ppdev->pohImageDownloadArea = NULL;
  424. ppdev->cbImageDownloadArea = 0;
  425. ppdev->iPalUniq = (ULONG)-1;
  426. ppdev->cPalLUTInvalidEntries = 0;
  427. #if WNT_DDRAW
  428. // Create the DirectDraw structures associated with this new pdev
  429. if (!_DD_DDE_CreatePPDEV(ppdev))
  430. {
  431. goto ReturnFailure1;
  432. }
  433. #endif
  434. return((DHPDEV) ppdev);
  435. ReturnFailure1:
  436. DrvDisablePDEV((DHPDEV) ppdev);
  437. ReturnFailure0:
  438. DISPDBG((ERRLVL, "Failed DrvEnablePDEV"));
  439. return(0);
  440. }
  441. /******************************Public*Routine******************************\
  442. * DrvDisablePDEV
  443. *
  444. * Release the resources allocated in DrvEnablePDEV. If a surface has been
  445. * enabled DrvDisableSurface will have already been called.
  446. *
  447. * Note: In an error, we may call this before DrvEnablePDEV is done.
  448. *
  449. \**************************************************************************/
  450. VOID DrvDisablePDEV(
  451. DHPDEV dhpdev)
  452. {
  453. PDEV* ppdev;
  454. ppdev = (PDEV*) dhpdev;
  455. #if WNT_DDRAW
  456. // Free the DirectDraw info associated with the pdev
  457. _DD_DDE_DestroyPPDEV(ppdev);
  458. #endif
  459. vUninitializePalette(ppdev);
  460. ENGFREEMEM(ppdev);
  461. }
  462. /******************************Public*Routine******************************\
  463. * VOID DrvCompletePDEV
  464. *
  465. * Store the HPDEV, the engines handle for this PDEV, in the DHPDEV.
  466. *
  467. \**************************************************************************/
  468. VOID DrvCompletePDEV(
  469. DHPDEV dhpdev,
  470. HDEV hdev)
  471. {
  472. ((PDEV*) dhpdev)->hdevEng = hdev;
  473. }
  474. /******************************Public*Routine******************************\
  475. * HSURF DrvEnableSurface
  476. *
  477. * Creates the drawing surface and initializes the hardware. This is called
  478. * after DrvEnablePDEV, and performs the final device initialization.
  479. *
  480. \**************************************************************************/
  481. HSURF DrvEnableSurface(
  482. DHPDEV dhpdev)
  483. {
  484. PDEV* ppdev;
  485. HSURF hsurf;
  486. SIZEL sizl;
  487. DSURF* pdsurf;
  488. VOID* pvTmpBuffer;
  489. ppdev = (PDEV*) dhpdev;
  490. if (!bEnableHardware(ppdev))
  491. goto ReturnFailure;
  492. if (!bEnableOffscreenHeap(ppdev))
  493. goto ReturnFailure;
  494. /////////////////////////////////////////////////////////////////////
  495. // First, create our private surface structure.
  496. //
  497. // Whenever we get a call to draw directly to the screen, we'll get
  498. // passed a pointer to a SURFOBJ whose 'dhpdev' field will point
  499. // to our PDEV structure, and whose 'dhsurf' field will point to the
  500. // following DSURF structure.
  501. //
  502. // Every device bitmap we create in DrvCreateDeviceBitmap will also
  503. // have its own unique DSURF structure allocated (but will share the
  504. // same PDEV). To make our code more polymorphic for handling drawing
  505. // to either the screen or an off-screen bitmap, we have the same
  506. // structure for both.
  507. pdsurf = ENGALLOCMEM(FL_ZERO_MEMORY, sizeof(DSURF), ALLOC_TAG_GDI(3));
  508. if (pdsurf == NULL)
  509. {
  510. DISPDBG((ERRLVL, "DrvEnableSurface - Failed pdsurf memory allocation"));
  511. goto ReturnFailure;
  512. }
  513. ppdev->pdsurfScreen = pdsurf; // Remember it for clean-up
  514. pdsurf->poh = ppdev->pohScreen; // The screen is a surface, too
  515. pdsurf->poh->pdsurf = pdsurf;
  516. pdsurf->dt = DT_SCREEN; // Not to be confused with a DIB DFB
  517. pdsurf->bOffScreen = FALSE; // it's the screen, not offscreen
  518. pdsurf->sizl.cx = ppdev->cxScreen;
  519. pdsurf->sizl.cy = ppdev->cyScreen;
  520. pdsurf->ppdev = ppdev;
  521. /////////////////////////////////////////////////////////////////////
  522. // Next, have GDI create the actual SURFOBJ.
  523. //
  524. // Our drawing surface is going to be 'device-managed', meaning that
  525. // GDI cannot draw on the framebuffer bits directly, and as such we
  526. // create the surface via EngCreateDeviceSurface. By doing this, we ensure
  527. // that GDI will only ever access the bitmaps bits via the Drv calls
  528. // that we've HOOKed.
  529. sizl.cx = ppdev->cxScreen;
  530. sizl.cy = ppdev->cyScreen;
  531. hsurf = EngCreateDeviceSurface((DHSURF) pdsurf, sizl, ppdev->iBitmapFormat);
  532. if (hsurf == 0)
  533. {
  534. DISPDBG((ERRLVL, "DrvEnableSurface - Failed EngCreateDeviceSurface"));
  535. goto ReturnFailure;
  536. }
  537. ppdev->hsurfScreen = hsurf; // Remember it for clean-up
  538. ppdev->bEnabled = TRUE; // We'll soon be in graphics mode
  539. /////////////////////////////////////////////////////////////////////
  540. // Now associate the surface and the PDEV.
  541. //
  542. // We have to associate the surface we just created with our physical
  543. // device so that GDI can get information related to the PDEV when
  544. // it's drawing to the surface (such as, for example, the length of
  545. // styles on the device when simulating styled lines).
  546. //
  547. if (!EngAssociateSurface(hsurf, ppdev->hdevEng, ppdev->flHooks))
  548. {
  549. DISPDBG((ERRLVL, "DrvEnableSurface - Failed EngAssociateSurface"));
  550. goto ReturnFailure;
  551. }
  552. // Create our generic temporary buffer, which may be used by any
  553. // component. Because this may get swapped out of memory any time
  554. // the driver is not active, we want to minimize the number of pages
  555. // it takes up. We use 'VirtualAlloc' to get an exactly page-aligned
  556. // allocation (which 'LocalAlloc' will not do):
  557. pvTmpBuffer = ENGALLOCMEM(FL_ZERO_MEMORY, TMP_BUFFER_SIZE, ALLOC_TAG_GDI(4));
  558. if (pvTmpBuffer == NULL)
  559. {
  560. DISPDBG((ERRLVL, "DrvEnableSurface - Failed TmpBuffer allocation"));
  561. goto ReturnFailure;
  562. }
  563. ppdev->pvTmpBuffer = pvTmpBuffer;
  564. /////////////////////////////////////////////////////////////////////
  565. // Now enable all the subcomponents.
  566. //
  567. // Note that the order in which these 'Enable' functions are called
  568. // may be significant in low off-screen memory conditions, because
  569. // the off-screen heap manager may fail some of the later
  570. // allocations...
  571. if (!bInitializeGlint(ppdev))
  572. goto ReturnFailure;
  573. // We could simply let GDI synchronize every time it draws on the screen
  574. // but this would be even slower. So unset the sync hook if the rendering
  575. // is done in software.
  576. //
  577. if (!bCreateScreenDIBForOH(ppdev, pdsurf->poh, HOOK_SYNCHRONIZE))
  578. goto ReturnFailure;
  579. if (!bEnablePalette(ppdev))
  580. goto ReturnFailure;
  581. if (!bEnablePointer(ppdev))
  582. goto ReturnFailure;
  583. //@@BEGIN_DDKSPLIT
  584. #if 0
  585. if (!bEnablePointerCache(ppdev))
  586. {
  587. DISPDBG((ERRLVL, "Pointer cache failed to initialise"));
  588. }
  589. #endif
  590. //@@END_DDKSPLIT
  591. #if WNT_DDRAW
  592. if (!_DD_DDE_bEnableDirectDraw(ppdev))
  593. {
  594. goto ReturnFailure;
  595. }
  596. #endif // WNT_DDRAW
  597. DISPDBG((DBGLVL, "Passed DrvEnableSurface"));
  598. return(hsurf);
  599. ReturnFailure:
  600. DrvDisableSurface((DHPDEV) ppdev);
  601. DISPDBG((ERRLVL, "Failed DrvEnableSurface"));
  602. return(0);
  603. }
  604. /******************************Public*Routine******************************\
  605. * VOID DrvDisableSurface
  606. *
  607. * Free resources allocated by DrvEnableSurface. Release the surface.
  608. *
  609. * Note: In an error case, we may call this before DrvEnableSurface is
  610. * completely done.
  611. *
  612. \**************************************************************************/
  613. VOID DrvDisableSurface(
  614. DHPDEV dhpdev)
  615. {
  616. PDEV* ppdev;
  617. DSURF* pdsurf;
  618. ppdev = (PDEV*) dhpdev;
  619. pdsurf = ppdev->pdsurfScreen;
  620. // Note: In an error case, some of the following relies on the
  621. // fact that the PDEV is zero-initialized, so fields like
  622. // 'hsurfScreen' will be zero unless the surface has been
  623. // sucessfully initialized, and makes the assumption that
  624. // EngDeleteSurface can take '0' as a parameter.
  625. #if WNT_DDRAW
  626. _DD_DDE_vDisableDirectDraw(ppdev);
  627. #endif // WNT_DDRAW
  628. //@@BEGIN_DDKSPLIT
  629. #if 0
  630. vDisablePointerCache(ppdev);
  631. #endif
  632. //@@END_DDKSPLIT
  633. vDisablePalette(ppdev);
  634. vDisablePointer(ppdev);
  635. if (pdsurf != NULL)
  636. vDeleteScreenDIBFromOH(pdsurf->poh);
  637. vDisableGlint(ppdev);
  638. vDisableOffscreenHeap(ppdev);
  639. vDisableHardware(ppdev);
  640. ENGFREEMEM(ppdev->pvTmpBuffer);
  641. EngDeleteSurface(ppdev->hsurfScreen);
  642. ENGFREEMEM(pdsurf);
  643. }
  644. /******************************Public*Routine******************************\
  645. * BOOL/VOID DrvAssertMode
  646. *
  647. * This asks the device to reset itself to the mode of the pdev passed in.
  648. *
  649. \**************************************************************************/
  650. BOOL DrvAssertMode(
  651. DHPDEV dhpdev,
  652. BOOL bEnable)
  653. {
  654. PDEV* ppdev;
  655. ppdev = (PDEV*) dhpdev;
  656. if (!bEnable)
  657. {
  658. //////////////////////////////////////////////////////////////
  659. // Disable - Switch to full-screen mode
  660. #if WNT_DDRAW
  661. _DD_DDE_vAssertModeDirectDraw(ppdev, FALSE);
  662. #endif WNT_DDRAW
  663. vAssertModePalette(ppdev, FALSE);
  664. vAssertModePointer(ppdev, FALSE);
  665. if (bAssertModeOffscreenHeap(ppdev, FALSE))
  666. {
  667. vAssertModeGlint(ppdev, FALSE);
  668. if (bAssertModeHardware(ppdev, FALSE))
  669. {
  670. ppdev->bEnabled = FALSE;
  671. return(TRUE);
  672. }
  673. //////////////////////////////////////////////////////////
  674. // We failed to switch to full-screen. So undo everything:
  675. vAssertModeGlint(ppdev, TRUE);
  676. bAssertModeOffscreenHeap(ppdev, TRUE); // We don't need to check
  677. } // return code with TRUE
  678. vAssertModePointer(ppdev, TRUE);
  679. vAssertModePalette(ppdev, TRUE);
  680. #if WNT_DDRAW
  681. _DD_DDE_vAssertModeDirectDraw(ppdev, TRUE);
  682. #endif WNT_DDRAW
  683. }
  684. else
  685. {
  686. //////////////////////////////////////////////////////////////
  687. // Enable - Switch back to graphics mode
  688. // We have to enable every subcomponent in the reverse order
  689. // in which it was disabled:
  690. if (bAssertModeHardware(ppdev, TRUE))
  691. {
  692. vAssertModeGlint(ppdev, TRUE);
  693. bAssertModeOffscreenHeap(ppdev, TRUE);
  694. vAssertModePointer(ppdev, TRUE);
  695. vAssertModePalette(ppdev, TRUE);
  696. #if WNT_DDRAW
  697. _DD_DDE_vAssertModeDirectDraw(ppdev, TRUE);
  698. #endif // WNT_DDRAW
  699. #if (_WIN32_WINNT >= 0x500 && FALSE)
  700. // There is probably a neater way to do this, but: currently the display driver isn't notified
  701. // about entering / exiting hibernation so it can't save away those GC registers that it has
  702. // initialized at the start of day and hasn't bothered to context switch. DrvAssertMode(TRUE)
  703. // is the first display driver call made upon return from hibernation so we take the
  704. // opportunity to re-initialize these registers now. Reinitializing these registers at other
  705. // times when DrvAssertMode(TRUE) is called (e.g. mode change) should do no harm. Non-GC
  706. // registers are dealt with in the miniport's PowerOnReset() and HibernationMode() functions
  707. {
  708. extern void ReinitialiseGlintExtContext(PDEV *ppdev);
  709. // currently, only the extension context initializes but doesn't context switch certain registers
  710. ReinitialiseGlintExtContext(ppdev);
  711. }
  712. #endif //(_WIN32_WINNT >= 0x500)
  713. ppdev->bEnabled = TRUE;
  714. return(TRUE);
  715. }
  716. }
  717. return(FALSE);
  718. }
  719. /******************************Public*Routine******************************\
  720. * ULONG DrvGetModes
  721. *
  722. * Returns the list of available modes for the device.
  723. *
  724. \**************************************************************************/
  725. ULONG DrvGetModes(
  726. HANDLE hDriver,
  727. ULONG cjSize,
  728. DEVMODEW* pdm)
  729. {
  730. DWORD cModes;
  731. DWORD cbOutputSize;
  732. PVIDEO_MODE_INFORMATION pVideoModeInformation;
  733. PVIDEO_MODE_INFORMATION pVideoTemp;
  734. DWORD cOutputModes = cjSize / (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
  735. DWORD cbModeSize;
  736. cModes = getAvailableModes(hDriver,
  737. (PVIDEO_MODE_INFORMATION *) &pVideoModeInformation,
  738. &cbModeSize);
  739. if (cModes == 0)
  740. {
  741. DISPDBG((ERRLVL, "DrvGetModes failed to get mode information"));
  742. return(0);
  743. }
  744. if (pdm == NULL)
  745. {
  746. cbOutputSize = cModes * (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
  747. }
  748. else
  749. {
  750. //
  751. // Now copy the information for the supported modes back into the
  752. // output buffer
  753. //
  754. cbOutputSize = 0;
  755. pVideoTemp = pVideoModeInformation;
  756. do {
  757. if (pVideoTemp->Length != 0)
  758. {
  759. if (cOutputModes == 0)
  760. {
  761. break;
  762. }
  763. //
  764. // Zero the entire structure to start off with.
  765. //
  766. memset(pdm, 0, sizeof(DEVMODEW));
  767. //
  768. // Set the name of the device to the name of the DLL.
  769. //
  770. memcpy(pdm->dmDeviceName, DLL_NAME, sizeof(DLL_NAME));
  771. pdm->dmSpecVersion = DM_SPECVERSION;
  772. pdm->dmDriverVersion = DM_SPECVERSION;
  773. //
  774. // We currently do not support Extra information in the driver
  775. //
  776. pdm->dmDriverExtra = DRIVER_EXTRA_SIZE;
  777. pdm->dmSize = sizeof(DEVMODEW);
  778. pdm->dmBitsPerPel = pVideoTemp->NumberOfPlanes *
  779. pVideoTemp->BitsPerPlane;
  780. pdm->dmPelsWidth = pVideoTemp->VisScreenWidth;
  781. pdm->dmPelsHeight = pVideoTemp->VisScreenHeight;
  782. pdm->dmDisplayFrequency = pVideoTemp->Frequency;
  783. pdm->dmDisplayFlags = 0;
  784. pdm->dmPanningWidth = pdm->dmPelsWidth;
  785. pdm->dmPanningHeight = pdm->dmPelsHeight;
  786. pdm->dmFields = DM_BITSPERPEL |
  787. DM_PELSWIDTH |
  788. DM_PELSHEIGHT |
  789. DM_DISPLAYFREQUENCY |
  790. DM_DISPLAYFLAGS;
  791. //
  792. // Go to the next DEVMODE entry in the buffer.
  793. //
  794. cOutputModes--;
  795. pdm = (LPDEVMODEW) ( ((UINT_PTR)pdm) + sizeof(DEVMODEW) +
  796. DRIVER_EXTRA_SIZE);
  797. cbOutputSize += (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
  798. }
  799. pVideoTemp = (PVIDEO_MODE_INFORMATION)
  800. (((UINT_PTR)pVideoTemp) + cbModeSize);
  801. } while (--cModes);
  802. }
  803. ENGFREEMEM(pVideoModeInformation);
  804. return(cbOutputSize);
  805. }
  806. /******************************Public*Routine******************************\
  807. * BOOL bAssertModeHardware
  808. *
  809. * Sets the appropriate hardware state for graphics mode or full-screen.
  810. *
  811. \**************************************************************************/
  812. BOOL bAssertModeHardware(
  813. PDEV* ppdev,
  814. BOOL bEnable)
  815. {
  816. DWORD ReturnedDataLength;
  817. ULONG ulReturn;
  818. VIDEO_MODE_INFORMATION VideoModeInfo;
  819. GLINT_DECL;
  820. if (bEnable)
  821. {
  822. DISPDBG((DBGLVL, "enabling hardware"));
  823. // Call the miniport via an IOCTL to set the graphics mode.
  824. if (EngDeviceIoControl(ppdev->hDriver,
  825. IOCTL_VIDEO_SET_CURRENT_MODE,
  826. &ppdev->ulMode, // input buffer
  827. sizeof(DWORD),
  828. NULL,
  829. 0,
  830. &ReturnedDataLength) != NO_ERROR)
  831. {
  832. DISPDBG((ERRLVL, "bAssertModeHardware - Failed VIDEO_SET_CURRENT_MODE"));
  833. goto ReturnFalse;
  834. }
  835. if (EngDeviceIoControl(ppdev->hDriver,
  836. IOCTL_VIDEO_QUERY_CURRENT_MODE,
  837. NULL,
  838. 0,
  839. &VideoModeInfo,
  840. sizeof(VideoModeInfo),
  841. &ReturnedDataLength) != NO_ERROR)
  842. {
  843. DISPDBG((ERRLVL, "bAssertModeHardware - failed VIDEO_QUERY_CURRENT_MODE"));
  844. goto ReturnFalse;
  845. }
  846. #if DEBUG_HEAP
  847. VideoModeInfo.VideoMemoryBitmapWidth = VideoModeInfo.VisScreenWidth;
  848. DISPDBG((ERRLVL, "Video Memory Bitmap width and height set to %d x %d",
  849. VideoModeInfo.VideoMemoryBitmapWidth,
  850. VideoModeInfo.VideoMemoryBitmapHeight));
  851. #endif
  852. // The following variables are determined only after the initial
  853. // modeset:
  854. ppdev->cxMemory = VideoModeInfo.VideoMemoryBitmapWidth;
  855. ppdev->cyMemory = VideoModeInfo.VideoMemoryBitmapHeight;
  856. ppdev->lDelta = VideoModeInfo.ScreenStride;
  857. ppdev->Vrefresh = VideoModeInfo.Frequency;
  858. ppdev->flCaps = VideoModeInfo.DriverSpecificAttributeFlags;
  859. DISPDBG((DBGLVL, "Got flCaps 0x%x", ppdev->flCaps));
  860. }
  861. else
  862. {
  863. // Call the kernel driver to reset the device to a known state.
  864. // NTVDM will take things from there:
  865. DISPDBG((DBGLVL, "IOCTL_VIDEO_RESET_DEVICE"));
  866. if (EngDeviceIoControl(ppdev->hDriver,
  867. IOCTL_VIDEO_RESET_DEVICE,
  868. NULL,
  869. 0,
  870. NULL,
  871. 0,
  872. &ulReturn) != NO_ERROR)
  873. {
  874. DISPDBG((ERRLVL, "bAssertModeHardware - Failed reset IOCTL"));
  875. goto ReturnFalse;
  876. }
  877. }
  878. DISPDBG((DBGLVL, "Passed bAssertModeHardware"));
  879. return(TRUE);
  880. ReturnFalse:
  881. DISPDBG((ERRLVL, "Failed bAssertModeHardware"));
  882. return(FALSE);
  883. }
  884. /******************************Public*Routine******************************\
  885. * BOOL bEnableHardware
  886. *
  887. * Puts the hardware in the requested mode and initializes it.
  888. *
  889. \**************************************************************************/
  890. BOOL bEnableHardware(
  891. PDEV* ppdev)
  892. {
  893. VIDEO_MEMORY VideoMemory;
  894. VIDEO_MEMORY_INFORMATION VideoMemoryInfo;
  895. DWORD ReturnedDataLength;
  896. LONG i;
  897. VIDEO_PUBLIC_ACCESS_RANGES VideoAccessRange[3];
  898. DISPDBG((DBGLVL, "bEnableHardware Reached"));
  899. // Map control registers into virtual memory:
  900. VideoMemory.RequestedVirtualAddress = NULL;
  901. if (EngDeviceIoControl(ppdev->hDriver,
  902. IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES,
  903. &VideoMemory, // input buffer
  904. sizeof(VIDEO_MEMORY),
  905. &VideoAccessRange[0], // output buffer
  906. sizeof (VideoAccessRange),
  907. &ReturnedDataLength) != NO_ERROR)
  908. {
  909. RIP("bEnableHardware - Initialization error mapping control registers");
  910. goto ReturnFalse;
  911. }
  912. ppdev->pulCtrlBase[0] = (ULONG*) VideoAccessRange[0].VirtualAddress;
  913. ppdev->pulCtrlBase[1] = (ULONG*) VideoAccessRange[1].VirtualAddress;
  914. ppdev->pulCtrlBase[2] = (ULONG*) VideoAccessRange[2].VirtualAddress;
  915. DISPDBG((DBGLVL, "Mapped GLINT control registers[0] at 0x%x", ppdev->pulCtrlBase[0]));
  916. DISPDBG((DBGLVL, "Mapped GLINT control registers[1] at 0x%x", ppdev->pulCtrlBase[1]));
  917. DISPDBG((DBGLVL, "Mapped GLINT control registers[2] at 0x%x", ppdev->pulCtrlBase[2]));
  918. DISPDBG((DBGLVL, "bEnableHardware: ppdev 0x%x", ppdev));
  919. // Get the linear memory address range.
  920. VideoMemory.RequestedVirtualAddress = NULL;
  921. if (EngDeviceIoControl(ppdev->hDriver,
  922. IOCTL_VIDEO_MAP_VIDEO_MEMORY,
  923. &VideoMemory, // input buffer
  924. sizeof(VIDEO_MEMORY),
  925. &VideoMemoryInfo, // output buffer
  926. sizeof(VideoMemoryInfo),
  927. &ReturnedDataLength) != NO_ERROR)
  928. {
  929. DISPDBG((ERRLVL, "bEnableHardware - Error mapping buffer address"));
  930. goto ReturnFalse;
  931. }
  932. DISPDBG((DBGLVL, "FrameBufferBase: %lx", VideoMemoryInfo.FrameBufferBase));
  933. // Record the Frame Buffer Linear Address.
  934. ppdev->pjScreen = (BYTE*) VideoMemoryInfo.FrameBufferBase;
  935. ppdev->FrameBufferLength = VideoMemoryInfo.FrameBufferLength;
  936. if (!bAssertModeHardware(ppdev, TRUE))
  937. goto ReturnFalse;
  938. DISPDBG((DBGLVL, "Width: %li Height: %li Stride: %li Flags: 0x%lx",
  939. ppdev->cxMemory, ppdev->cyMemory,
  940. ppdev->lDelta, ppdev->flCaps));
  941. DISPDBG((DBGLVL, "Passed bEnableHardware"));
  942. return(TRUE);
  943. ReturnFalse:
  944. DISPDBG((ERRLVL, "Failed bEnableHardware"));
  945. return(FALSE);
  946. }
  947. /******************************Public*Routine******************************\
  948. * VOID vDisableHardware
  949. *
  950. * Undoes anything done in bEnableHardware.
  951. *
  952. * Note: In an error case, we may call this before bEnableHardware is
  953. * completely done.
  954. *
  955. \**************************************************************************/
  956. VOID vDisableHardware(
  957. PDEV* ppdev)
  958. {
  959. DWORD ReturnedDataLength;
  960. VIDEO_MEMORY VideoMemory[3];
  961. VideoMemory[0].RequestedVirtualAddress = ppdev->pjScreen;
  962. if (EngDeviceIoControl(ppdev->hDriver,
  963. IOCTL_VIDEO_UNMAP_VIDEO_MEMORY,
  964. &VideoMemory[0],
  965. sizeof(VIDEO_MEMORY),
  966. NULL,
  967. 0,
  968. &ReturnedDataLength) != NO_ERROR)
  969. {
  970. DISPDBG((ERRLVL, "vDisableHardware failed IOCTL_VIDEO_UNMAP_VIDEO"));
  971. }
  972. VideoMemory[0].RequestedVirtualAddress = ppdev->pulCtrlBase[0];
  973. VideoMemory[1].RequestedVirtualAddress = ppdev->pulCtrlBase[1];
  974. VideoMemory[2].RequestedVirtualAddress = ppdev->pulCtrlBase[2];
  975. if (EngDeviceIoControl(ppdev->hDriver,
  976. IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES,
  977. &VideoMemory[0],
  978. sizeof(VideoMemory),
  979. NULL,
  980. 0,
  981. &ReturnedDataLength) != NO_ERROR)
  982. {
  983. DISPDBG((ERRLVL, "vDisableHardware failed IOCTL_VIDEO_FREE_PUBLIC_ACCESS"));
  984. }
  985. }
  986. /******************************Public*Routine******************************\
  987. * BOOL bInitializeModeFields
  988. *
  989. * Initializes a bunch of fields in the pdev, devcaps (aka gdiinfo), and
  990. * devinfo based on the requested mode.
  991. *
  992. \**************************************************************************/
  993. BOOL bInitializeModeFields(
  994. PDEV* ppdev,
  995. GDIINFO* pgdi,
  996. DEVINFO* pdi,
  997. DEVMODEW* pdm)
  998. {
  999. ULONG cModes;
  1000. PVIDEO_MODE_INFORMATION pVideoBuffer;
  1001. PVIDEO_MODE_INFORMATION pVideoModeSelected;
  1002. PVIDEO_MODE_INFORMATION pVideoTemp;
  1003. BOOL bSelectDefault;
  1004. VIDEO_MODE_INFORMATION VideoModeInformation;
  1005. ULONG cbModeSize;
  1006. // Call the miniport to get mode information
  1007. cModes = getAvailableModes(ppdev->hDriver, &pVideoBuffer, &cbModeSize);
  1008. if (cModes == 0)
  1009. goto ReturnFalse;
  1010. // Determine if we are looking for a default mode:
  1011. if ( ((pdm->dmPelsWidth) ||
  1012. (pdm->dmPelsHeight) ||
  1013. (pdm->dmBitsPerPel) ||
  1014. (pdm->dmDisplayFlags) ||
  1015. (pdm->dmDisplayFrequency)) == 0)
  1016. {
  1017. bSelectDefault = TRUE;
  1018. }
  1019. else
  1020. {
  1021. bSelectDefault = FALSE;
  1022. }
  1023. // Now see if the requested mode has a match in that table.
  1024. pVideoModeSelected = NULL;
  1025. pVideoTemp = pVideoBuffer;
  1026. if ((pdm->dmPelsWidth == 0) &&
  1027. (pdm->dmPelsHeight == 0) &&
  1028. (pdm->dmBitsPerPel == 0) &&
  1029. (pdm->dmDisplayFrequency == 0))
  1030. {
  1031. DISPDBG((DBGLVL, "Default mode requested"));
  1032. }
  1033. else
  1034. {
  1035. DISPDBG((DBGLVL, "Requested mode..."));
  1036. DISPDBG((DBGLVL, " Screen width -- %li", pdm->dmPelsWidth));
  1037. DISPDBG((DBGLVL, " Screen height -- %li", pdm->dmPelsHeight));
  1038. DISPDBG((DBGLVL, " Bits per pel -- %li", pdm->dmBitsPerPel));
  1039. DISPDBG((DBGLVL, " Frequency -- %li", pdm->dmDisplayFrequency));
  1040. }
  1041. while (cModes--)
  1042. {
  1043. if (pVideoTemp->Length != 0)
  1044. {
  1045. DISPDBG((DBGLVL, " Checking against miniport mode:"));
  1046. DISPDBG((DBGLVL, " Screen width -- %li", pVideoTemp->VisScreenWidth));
  1047. DISPDBG((DBGLVL, " Screen height -- %li", pVideoTemp->VisScreenHeight));
  1048. DISPDBG((DBGLVL, " Bits per pel -- %li", pVideoTemp->BitsPerPlane *
  1049. pVideoTemp->NumberOfPlanes));
  1050. DISPDBG((DBGLVL, " Frequency -- %li", pVideoTemp->Frequency));
  1051. if (bSelectDefault ||
  1052. ((pVideoTemp->VisScreenWidth == pdm->dmPelsWidth) &&
  1053. (pVideoTemp->VisScreenHeight == pdm->dmPelsHeight) &&
  1054. (pVideoTemp->BitsPerPlane *
  1055. pVideoTemp->NumberOfPlanes == pdm->dmBitsPerPel)) &&
  1056. (pVideoTemp->Frequency == pdm->dmDisplayFrequency))
  1057. {
  1058. pVideoModeSelected = pVideoTemp;
  1059. DISPDBG((DBGLVL, "...Found a mode match!"));
  1060. break;
  1061. }
  1062. }
  1063. pVideoTemp = (PVIDEO_MODE_INFORMATION)
  1064. (((PUCHAR)pVideoTemp) + cbModeSize);
  1065. }
  1066. // If no mode has been found, return an error
  1067. if (pVideoModeSelected == NULL)
  1068. {
  1069. DISPDBG((DBGLVL, "...Couldn't find a mode match!"));
  1070. ENGFREEMEM(pVideoBuffer);
  1071. goto ReturnFalse;
  1072. }
  1073. // We have chosen the one we want. Save it in a stack buffer and
  1074. // get rid of allocated memory before we forget to free it.
  1075. VideoModeInformation = *pVideoModeSelected;
  1076. ENGFREEMEM(pVideoBuffer);
  1077. // Set up screen information from the mini-port:
  1078. ppdev->ulMode = VideoModeInformation.ModeIndex;
  1079. ppdev->cxScreen = VideoModeInformation.VisScreenWidth;
  1080. ppdev->cyScreen = VideoModeInformation.VisScreenHeight;
  1081. DISPDBG((DBGLVL, "ScreenStride: %li", VideoModeInformation.ScreenStride));
  1082. ppdev->flHooks = (HOOK_BITBLT |
  1083. HOOK_TEXTOUT |
  1084. HOOK_FILLPATH |
  1085. HOOK_COPYBITS |
  1086. HOOK_STROKEPATH |
  1087. HOOK_LINETO |
  1088. HOOK_PAINT |
  1089. // HOOK_STRETCHBLT |
  1090. #if (_WIN32_WINNT >= 0x500)
  1091. #if defined(_NT5GDI)
  1092. HOOK_GRADIENTFILL |
  1093. HOOK_TRANSPARENTBLT |
  1094. HOOK_ALPHABLEND |
  1095. #endif
  1096. #endif // (_WIN32_WINNT >= 0x500)
  1097. 0);
  1098. // Fill in the GDIINFO data structure with the default 8bpp values:
  1099. *pgdi = ggdiDefault;
  1100. // Now overwrite the defaults with the relevant information returned
  1101. // from the kernel driver:
  1102. pgdi->ulHorzSize = VideoModeInformation.XMillimeter;
  1103. pgdi->ulVertSize = VideoModeInformation.YMillimeter;
  1104. pgdi->ulHorzRes = VideoModeInformation.VisScreenWidth;
  1105. pgdi->ulVertRes = VideoModeInformation.VisScreenHeight;
  1106. pgdi->ulPanningHorzRes = VideoModeInformation.VisScreenWidth;
  1107. pgdi->ulPanningVertRes = VideoModeInformation.VisScreenHeight;
  1108. pgdi->cBitsPixel = VideoModeInformation.BitsPerPlane;
  1109. pgdi->cPlanes = VideoModeInformation.NumberOfPlanes;
  1110. pgdi->ulVRefresh = VideoModeInformation.Frequency;
  1111. pgdi->ulDACRed = VideoModeInformation.NumberRedBits;
  1112. pgdi->ulDACGreen = VideoModeInformation.NumberGreenBits;
  1113. pgdi->ulDACBlue = VideoModeInformation.NumberBlueBits;
  1114. pgdi->ulLogPixelsX = pdm->dmLogPixels;
  1115. pgdi->ulLogPixelsY = pdm->dmLogPixels;
  1116. // Fill in the devinfo structure with the default 8bpp values:
  1117. *pdi = gdevinfoDefault;
  1118. if (VideoModeInformation.BitsPerPlane == 8)
  1119. {
  1120. ppdev->cjPelSize = 1;
  1121. ppdev->cPelSize = 0;
  1122. ppdev->iBitmapFormat = BMF_8BPP;
  1123. if (VideoModeInformation.AttributeFlags & VIDEO_MODE_PALETTE_DRIVEN)
  1124. {
  1125. ppdev->ulWhite = 0xff;
  1126. }
  1127. else
  1128. {
  1129. ppdev->flRed = VideoModeInformation.RedMask;
  1130. ppdev->flGreen = VideoModeInformation.GreenMask;
  1131. ppdev->flBlue = VideoModeInformation.BlueMask;
  1132. ppdev->ulWhite = VideoModeInformation.RedMask |
  1133. VideoModeInformation.GreenMask |
  1134. VideoModeInformation.BlueMask;
  1135. pdi->flGraphicsCaps &= ~(GCAPS_PALMANAGED | GCAPS_COLOR_DITHER);
  1136. pgdi->ulNumColors = (ULONG) 256;
  1137. pgdi->ulNumPalReg = (ULONG) 256;
  1138. pgdi->ulHTOutputFormat = HT_FORMAT_8BPP;
  1139. }
  1140. }
  1141. else if ((VideoModeInformation.BitsPerPlane == 16) ||
  1142. (VideoModeInformation.BitsPerPlane == 15))
  1143. {
  1144. ppdev->cjPelSize = 2;
  1145. ppdev->cPelSize = 1;
  1146. ppdev->iBitmapFormat = BMF_16BPP;
  1147. ppdev->flRed = VideoModeInformation.RedMask;
  1148. ppdev->flGreen = VideoModeInformation.GreenMask;
  1149. ppdev->flBlue = VideoModeInformation.BlueMask;
  1150. pgdi->ulNumColors = (ULONG) -1;
  1151. pgdi->ulNumPalReg = 0;
  1152. pgdi->ulHTOutputFormat = HT_FORMAT_16BPP;
  1153. pdi->iDitherFormat = BMF_16BPP;
  1154. pdi->flGraphicsCaps &= ~(GCAPS_PALMANAGED | GCAPS_COLOR_DITHER);
  1155. ppdev->ulWhite = VideoModeInformation.RedMask |
  1156. VideoModeInformation.GreenMask |
  1157. VideoModeInformation.BlueMask;
  1158. }
  1159. else if (VideoModeInformation.BitsPerPlane == 24)
  1160. {
  1161. ppdev->cjPelSize = 3;
  1162. ppdev->cPelSize = 4;
  1163. ppdev->flRed = VideoModeInformation.RedMask;
  1164. ppdev->flGreen = VideoModeInformation.GreenMask;
  1165. ppdev->flBlue = VideoModeInformation.BlueMask;
  1166. ppdev->iBitmapFormat = BMF_24BPP;
  1167. pgdi->ulNumColors = (ULONG) -1;
  1168. pgdi->ulNumPalReg = 0;
  1169. pgdi->ulHTOutputFormat = HT_FORMAT_24BPP;
  1170. pdi->iDitherFormat = BMF_24BPP;
  1171. pdi->flGraphicsCaps &= ~(GCAPS_PALMANAGED | GCAPS_COLOR_DITHER);
  1172. ppdev->ulWhite = VideoModeInformation.RedMask |
  1173. VideoModeInformation.GreenMask |
  1174. VideoModeInformation.BlueMask;
  1175. }
  1176. else
  1177. {
  1178. ASSERTDD((VideoModeInformation.BitsPerPlane == 32) ||
  1179. (VideoModeInformation.BitsPerPlane == 12),
  1180. "This driver supports only 8, 16 and 32bpp");
  1181. ppdev->cjPelSize = 4;
  1182. ppdev->cPelSize = 2;
  1183. ppdev->flRed = VideoModeInformation.RedMask;
  1184. ppdev->flGreen = VideoModeInformation.GreenMask;
  1185. ppdev->flBlue = VideoModeInformation.BlueMask;
  1186. ppdev->iBitmapFormat = BMF_32BPP;
  1187. pgdi->ulNumColors = (ULONG) -1;
  1188. pgdi->ulNumPalReg = 0;
  1189. pgdi->ulHTOutputFormat = HT_FORMAT_32BPP;
  1190. pdi->iDitherFormat = BMF_32BPP;
  1191. pdi->flGraphicsCaps &= ~(GCAPS_PALMANAGED | GCAPS_COLOR_DITHER);
  1192. ppdev->ulWhite = VideoModeInformation.RedMask |
  1193. VideoModeInformation.GreenMask |
  1194. VideoModeInformation.BlueMask;
  1195. }
  1196. DISPDBG((DBGLVL, "Passed bInitializeModeFields"));
  1197. return(TRUE);
  1198. ReturnFalse:
  1199. DISPDBG((ERRLVL, "Failed bInitializeModeFields"));
  1200. return(FALSE);
  1201. }
  1202. /******************************Public*Routine******************************\
  1203. * DWORD getAvailableModes
  1204. *
  1205. * Calls the miniport to get the list of modes supported by the kernel driver,
  1206. * and returns the list of modes supported by the diplay driver among those
  1207. *
  1208. * returns the number of entries in the videomode buffer.
  1209. * 0 means no modes are supported by the miniport or that an error occured.
  1210. *
  1211. * NOTE: the buffer must be freed up by the caller.
  1212. *
  1213. \**************************************************************************/
  1214. DWORD getAvailableModes(
  1215. HANDLE hDriver,
  1216. PVIDEO_MODE_INFORMATION* modeInformation,
  1217. DWORD* cbModeSize)
  1218. {
  1219. ULONG ulTemp;
  1220. VIDEO_NUM_MODES modes;
  1221. PVIDEO_MODE_INFORMATION pVideoTemp;
  1222. //
  1223. // Get the number of modes supported by the mini-port
  1224. //
  1225. if (EngDeviceIoControl(hDriver,
  1226. IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES,
  1227. NULL,
  1228. 0,
  1229. &modes,
  1230. sizeof(VIDEO_NUM_MODES),
  1231. &ulTemp) != NO_ERROR)
  1232. {
  1233. DISPDBG((ERRLVL, "getAvailableModes - Failed VIDEO_QUERY_NUM_AVAIL_MODES"));
  1234. return(0);
  1235. }
  1236. *cbModeSize = modes.ModeInformationLength;
  1237. //
  1238. // Allocate the buffer for the mini-port to write the modes in.
  1239. //
  1240. *modeInformation = (PVIDEO_MODE_INFORMATION)
  1241. ENGALLOCMEM(FL_ZERO_MEMORY,
  1242. modes.NumModes * modes.ModeInformationLength,
  1243. ALLOC_TAG_GDI(5));
  1244. if (*modeInformation == (PVIDEO_MODE_INFORMATION) NULL)
  1245. {
  1246. DISPDBG((ERRLVL, "getAvailableModes - Failed memory allocation"));
  1247. return 0;
  1248. }
  1249. //
  1250. // Ask the mini-port to fill in the available modes.
  1251. //
  1252. if (EngDeviceIoControl(hDriver,
  1253. IOCTL_VIDEO_QUERY_AVAIL_MODES,
  1254. NULL,
  1255. 0,
  1256. *modeInformation,
  1257. modes.NumModes * modes.ModeInformationLength,
  1258. &ulTemp) != NO_ERROR)
  1259. {
  1260. DISPDBG((ERRLVL, "getAvailableModes - Failed VIDEO_QUERY_AVAIL_MODES"));
  1261. ENGFREEMEM(*modeInformation);
  1262. *modeInformation = (PVIDEO_MODE_INFORMATION) NULL;
  1263. return(0);
  1264. }
  1265. //
  1266. // Now see which of these modes are supported by the display driver.
  1267. // As an internal mechanism, set the length to 0 for the modes we
  1268. // DO NOT support.
  1269. //
  1270. ulTemp = modes.NumModes;
  1271. pVideoTemp = *modeInformation;
  1272. //
  1273. // Mode is rejected if it is not one plane, or not graphics, or is not
  1274. // one of 8, 15, 16 or 32 bits per pel.
  1275. //
  1276. while (ulTemp--)
  1277. {
  1278. if ((pVideoTemp->NumberOfPlanes != 1 ) ||
  1279. !(pVideoTemp->AttributeFlags & VIDEO_MODE_GRAPHICS) ||
  1280. ((pVideoTemp->BitsPerPlane != 8) &&
  1281. (pVideoTemp->BitsPerPlane != 12) &&
  1282. (pVideoTemp->BitsPerPlane != 15) &&
  1283. (pVideoTemp->BitsPerPlane != 16) &&
  1284. (pVideoTemp->BitsPerPlane != 24) &&
  1285. (pVideoTemp->BitsPerPlane != 32)))
  1286. {
  1287. DISPDBG((WRNLVL, "Rejecting miniport mode:"));
  1288. DISPDBG((WRNLVL, " Screen width -- %li", pVideoTemp->VisScreenWidth));
  1289. DISPDBG((WRNLVL, " Screen height -- %li", pVideoTemp->VisScreenHeight));
  1290. DISPDBG((WRNLVL, " Bits per pel -- %li", pVideoTemp->BitsPerPlane *
  1291. pVideoTemp->NumberOfPlanes));
  1292. DISPDBG((WRNLVL, " Frequency -- %li", pVideoTemp->Frequency));
  1293. pVideoTemp->Length = 0;
  1294. }
  1295. pVideoTemp = (PVIDEO_MODE_INFORMATION)
  1296. (((PUCHAR)pVideoTemp) + modes.ModeInformationLength);
  1297. }
  1298. return(modes.NumModes);
  1299. }
  1300. //*****************************************************************************
  1301. // FUNC: DrvEscape
  1302. // ARGS: pso (I) - the surface affected by this notification
  1303. //
  1304. //*****************************************************************************
  1305. ULONG APIENTRY DrvEscape(
  1306. SURFOBJ *pso,
  1307. ULONG iEsc,
  1308. ULONG cjIn,
  1309. PVOID pvIn,
  1310. ULONG cjOut,
  1311. PVOID pvOut
  1312. )
  1313. {
  1314. PDEV *ppdev = (PDEV *) pso->dhpdev;
  1315. ULONG ulResult = 0;
  1316. INT iQuery;
  1317. DISPDBG((DBGLVL,"In DrvEscape"));
  1318. switch (iEsc)
  1319. {
  1320. case QUERYESCSUPPORT:
  1321. iQuery = *(int *)pvIn;
  1322. switch(iQuery)
  1323. {
  1324. case ESCAPE_TRACK_FUNCTION_COVERAGE:
  1325. case ESCAPE_TRACK_CODE_COVERAGE:
  1326. case ESCAPE_TRACK_MEMORY_ALLOCATION:
  1327. DISPDBG((DBGLVL,"In DrvEscape QUERYESCSUPPORT"));
  1328. ulResult = 1;
  1329. default:
  1330. ulResult = 0;
  1331. }
  1332. break;
  1333. case ESCAPE_TRACK_FUNCTION_COVERAGE:
  1334. ulResult = 0;
  1335. #if DBG
  1336. Debug_Func_Report_And_Reset();
  1337. ulResult = 1;
  1338. #endif // DBG
  1339. break;
  1340. case ESCAPE_TRACK_CODE_COVERAGE:
  1341. ulResult = 0;
  1342. #if DBG
  1343. Debug_Code_Report_And_Reset();
  1344. ulResult = 1;
  1345. #endif // DBG
  1346. break;
  1347. case ESCAPE_TRACK_MEMORY_ALLOCATION:
  1348. ulResult = 0;
  1349. #if DBG
  1350. #endif // DBG
  1351. break;
  1352. #ifdef DBG_EA_TAGS
  1353. case ESCAPE_EA_TAG:
  1354. if (pvIn)
  1355. {
  1356. DWORD dwEnable, dwTag;
  1357. dwTag = *(DWORD *) pvIn; // tag and enable flag
  1358. dwEnable = dwTag & EA_TAG_ENABLE; // get enable flag
  1359. dwTag &= ~EA_TAG_ENABLE; // strip enable flag for range comparison
  1360. if ((dwTag < MIN_EA_TAG) || (dwTag > MAX_EA_TAG))
  1361. {
  1362. ulResult = -3;
  1363. } // Invalid tag value
  1364. else
  1365. {
  1366. g_dwTag = dwTag | dwEnable;
  1367. ulResult = 1;
  1368. } // Valid tag for value
  1369. }
  1370. else
  1371. {
  1372. ulResult = -2;
  1373. } // NULL tag pointer
  1374. break;
  1375. #endif // DBG_EA_TAGS
  1376. default:
  1377. DISPDBG((WRNLVL, "DrvEscape: unknown escape %d", iEsc));
  1378. ulResult = 0;
  1379. }
  1380. return ulResult;
  1381. }
  1382. #if(_WIN32_WINNT >= 0x500)
  1383. //*****************************************************************************
  1384. // FUNC: DrvNotify
  1385. // ARGS: pso (I) - the surface affected by this notification
  1386. // iType (I) - notification type
  1387. // pvData (I) - notification data: format depends on iType
  1388. // RETN: void
  1389. //-----------------------------------------------------------------------------
  1390. //*****************************************************************************
  1391. VOID DrvNotify(IN SURFOBJ *pso, IN ULONG iType, IN PVOID pvData)
  1392. {
  1393. PDEV *ppdev;
  1394. ASSERTDD(pso->iType != STYPE_BITMAP, "ERROR - DrvNotify called for DIB surface!");
  1395. ppdev = (PDEV *)pso->dhpdev;
  1396. switch(iType)
  1397. {
  1398. case DN_ACCELERATION_LEVEL:
  1399. {
  1400. ULONG ul = *(ULONG *)pvData;
  1401. DISPDBG((DBGLVL, "DrvNotify: DN_ACCELERATION_LEVEL = %d", ul));
  1402. }
  1403. break;
  1404. case DN_DEVICE_ORIGIN:
  1405. {
  1406. POINTL ptl = *(POINTL *)pvData;
  1407. DISPDBG((DBGLVL, "DrvNotify: DN_DEVICE_ORIGIN xy == (%xh,%xh)", ptl.x, ptl.y));
  1408. }
  1409. break;
  1410. case DN_SLEEP_MODE:
  1411. DISPDBG((DBGLVL, "DrvNotify: DN_SLEEP_MODE"));
  1412. break;
  1413. case DN_DRAWING_BEGIN:
  1414. DISPDBG((DBGLVL, "DrvNotify: DN_DRAWING_BEGIN"));
  1415. #if ENABLE_DXMANAGED_LINEAR_HEAP
  1416. if((ppdev->flStatus & (ENABLE_LINEAR_HEAP | STAT_DEV_BITMAPS)) == (ENABLE_LINEAR_HEAP | STAT_DEV_BITMAPS))
  1417. {
  1418. if(ppdev->heap.cLinearHeaps)
  1419. {
  1420. // finally free to use the DX heap manager
  1421. DISPDBG((DBGLVL, "DrvNotify: enabling DX heap manager"));
  1422. ppdev->flStatus |= STAT_LINEAR_HEAP;
  1423. }
  1424. else
  1425. {
  1426. DISPDBG((ERRLVL, "DrvNotify: DX heap manager not enabled - there are no DX heaps! Remain using the 2D heap manager"));
  1427. }
  1428. }
  1429. #endif //ENABLE_DXMANAGED_LINEAR_HEAP
  1430. break;
  1431. default:
  1432. DISPDBG((WRNLVL, "DrvNotify: unknown notification type %d", iType));
  1433. }
  1434. }
  1435. #endif //(_WIN32_WINNT >= 0x500)