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.

945 lines
31 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: enable.c
  3. *
  4. * The initialization guts of the portable 16-colour VGA driver.
  5. *
  6. * The drawing guts of a portable 16-colour VGA driver for Windows NT. The
  7. * implementation herein may possibly be the simplest method of bringing
  8. * up a driver whose surface is not directly writable by GDI. One might
  9. * use the phrase "quick and dirty" when describing it.
  10. *
  11. * We create a 4bpp bitmap that is the size of the screen, and simply
  12. * have GDI do all the drawing to it. We update the screen directly
  13. * from the bitmap, based on the bounds of the drawing (basically
  14. * employing "dirty rectangles").
  15. *
  16. * In total, the only hardware-specific code we had to write was the
  17. * initialization code, and a routine for doing aligned srccopy blts
  18. * from a DIB to the screen.
  19. *
  20. * Obvious Note: This approach is definitely not recommended for decent
  21. * driver performance.
  22. *
  23. * Copyright (c) 1994-1995 Microsoft Corporation
  24. \**************************************************************************/
  25. #include "precomp.h"
  26. /******************************Public*Structure****************************\
  27. * DFVFN gadrvfn[]
  28. *
  29. * Build the driver function table gadrvfn with function index/address
  30. * pairs. This table tells GDI which DDI calls we support, and their
  31. * location (GDI does an indirect call through this table to call us).
  32. *
  33. \**************************************************************************/
  34. static DRVFN gadrvfn[] = {
  35. { INDEX_DrvEnablePDEV, (PFN) DrvEnablePDEV },
  36. { INDEX_DrvCompletePDEV, (PFN) DrvCompletePDEV },
  37. { INDEX_DrvDisablePDEV, (PFN) DrvDisablePDEV },
  38. { INDEX_DrvEnableSurface, (PFN) DrvEnableSurface },
  39. { INDEX_DrvDisableSurface, (PFN) DrvDisableSurface },
  40. { INDEX_DrvDitherColor, (PFN) DrvDitherColor },
  41. { INDEX_DrvAssertMode, (PFN) DrvAssertMode },
  42. { INDEX_DrvGetModes, (PFN) DrvGetModes },
  43. { INDEX_DrvBitBlt, (PFN) DrvBitBlt },
  44. { INDEX_DrvTextOut, (PFN) DrvTextOut },
  45. { INDEX_DrvStrokePath, (PFN) DrvStrokePath },
  46. { INDEX_DrvCopyBits, (PFN) DrvCopyBits },
  47. { INDEX_DrvPaint, (PFN) DrvPaint },
  48. { INDEX_DrvDisableDriver, (PFN) DrvDisableDriver }
  49. };
  50. ULONG gcdrvfn = sizeof(gadrvfn) / sizeof(DRVFN);
  51. /******************************Public*Structure****************************\
  52. * GDIINFO ggdiDefault
  53. *
  54. * This contains the default GDIINFO fields that are passed back to GDI
  55. * during DrvEnablePDEV.
  56. *
  57. * NOTE: This structure defaults to values for a 4bpp non-palette device.
  58. \**************************************************************************/
  59. GDIINFO ggdiDefault = {
  60. GDI_DRIVER_VERSION,
  61. DT_RASDISPLAY, // ulTechnology
  62. 0, // ulHorzSize
  63. 0, // ulVertSize
  64. 0, // ulHorzRes (filled in at initialization)
  65. 0, // ulVertRes (filled in at initialization)
  66. 4, // cBitsPixel
  67. 1, // cPlanes
  68. 16, // ulNumColors
  69. 0, // flRaster (DDI reserved field)
  70. 0, // ulLogPixelsX (filled in at initialization)
  71. 0, // ulLogPixelsY (filled in at initialization)
  72. TC_RA_ABLE, // flTextCaps
  73. 6, // ulDACRed
  74. 6, // ulDACGree
  75. 6, // ulDACBlue
  76. 0x0024, // ulAspectX (one-to-one aspect ratio)
  77. 0x0024, // ulAspectY
  78. 0x0033, // ulAspectXY
  79. 1, // xStyleStep
  80. 1, // yStyleSte;
  81. 3, // denStyleStep
  82. { 0, 0 }, // ptlPhysOffset
  83. { 0, 0 }, // szlPhysSize
  84. 0, // ulNumPalReg (win3.1 16 color drivers say 0 too)
  85. // These fields are for halftone initialization.
  86. { // ciDevice, ColorInfo
  87. { 6700, 3300, 0 }, // Red
  88. { 2100, 7100, 0 }, // Green
  89. { 1400, 800, 0 }, // Blue
  90. { 1750, 3950, 0 }, // Cyan
  91. { 4050, 2050, 0 }, // Magenta
  92. { 4400, 5200, 0 }, // Yellow
  93. { 3127, 3290, 0 }, // AlignmentWhite
  94. 20000, // RedGamma
  95. 20000, // GreenGamma
  96. 20000, // BlueGamma
  97. 0, 0, 0, 0, 0, 0
  98. },
  99. 0, // ulDevicePelsDPI (filled in at initialization)
  100. PRIMARY_ORDER_CBA, // ulPrimaryOrder
  101. HT_PATSIZE_4x4_M, // ulHTPatternSize
  102. HT_FORMAT_4BPP_IRGB, // ulHTOutputFormat
  103. HT_FLAG_ADDITIVE_PRIMS, // flHTFlags
  104. 0, // ulVRefresh
  105. 1, // ulBltAlignment (preferred window alignment
  106. // for fast-text routines)
  107. 0, // ulPanningHorzRes
  108. 0, // ulPanningVertRes
  109. };
  110. /******************************Public*Structure****************************\
  111. * DEVINFO gdevinfoDefault
  112. *
  113. * This contains the default DEVINFO fields that are passed back to GDI
  114. * during DrvEnablePDEV.
  115. *
  116. * NOTE: This structure defaults to values for a 4bpp non-palette device.
  117. \**************************************************************************/
  118. #define SYSTM_LOGFONT {16,7,0,0,700,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS, \
  119. CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, \
  120. VARIABLE_PITCH | FF_DONTCARE,L"System"}
  121. #define HELVE_LOGFONT {12,9,0,0,400,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS, \
  122. CLIP_STROKE_PRECIS,PROOF_QUALITY, \
  123. VARIABLE_PITCH | FF_DONTCARE, L"MS Sans Serif"}
  124. #define COURI_LOGFONT {12,9,0,0,400,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS, \
  125. CLIP_STROKE_PRECIS,PROOF_QUALITY, \
  126. FIXED_PITCH | FF_DONTCARE, L"Courier"}
  127. DEVINFO gdevinfoDefault =
  128. {
  129. (GCAPS_MONO_DITHER | GCAPS_COLOR_DITHER),
  130. // Graphics capabilities
  131. SYSTM_LOGFONT, // Default font description
  132. HELVE_LOGFONT, // ANSI variable font description
  133. COURI_LOGFONT, // ANSI fixed font description
  134. 0, // Count of device fonts
  135. BMF_4BPP, // preferred DIB format
  136. 8, // Width of color dither
  137. 8, // Height of color dither
  138. 0 // Default palette to use for this device
  139. };
  140. /******************************Public*Data*Struct*************************\
  141. * VGALOGPALETTE logPalVGA
  142. *
  143. * This is the palette for the VGA.
  144. *
  145. \**************************************************************************/
  146. typedef struct _VGALOGPALETTE
  147. {
  148. USHORT ident;
  149. USHORT NumEntries;
  150. PALETTEENTRY palPalEntry[16];
  151. } VGALOGPALETTE;
  152. const VGALOGPALETTE logPalVGA =
  153. {
  154. 0x400, // Driver version
  155. 16, // Number of entries
  156. {
  157. { 0, 0, 0, 0 }, // 0
  158. { 0x80,0, 0, 0 }, // 1
  159. { 0, 0x80,0, 0 }, // 2
  160. { 0x80,0x80,0, 0 }, // 3
  161. { 0, 0, 0x80,0 }, // 4
  162. { 0x80,0, 0x80,0 }, // 5
  163. { 0, 0x80,0x80,0 }, // 6
  164. { 0x80,0x80,0x80,0 }, // 7
  165. { 0xC0,0xC0,0xC0,0 }, // 8
  166. { 0xFF,0, 0, 0 }, // 9
  167. { 0, 0xFF,0, 0 }, // 10
  168. { 0xFF,0xFF,0, 0 }, // 11
  169. { 0, 0, 0xFF,0 }, // 12
  170. { 0xFF,0, 0xFF,0 }, // 13
  171. { 0, 0xFF,0xFF,0 }, // 14
  172. { 0xFF,0xFF,0xFF,0 } // 15
  173. }
  174. };
  175. /******************************Public*Routine******************************\
  176. * BOOL DrvEnableDriver
  177. *
  178. * Enables the driver by retrieving the drivers function table and version.
  179. *
  180. \**************************************************************************/
  181. BOOL DrvEnableDriver(
  182. ULONG iEngineVersion,
  183. ULONG cj,
  184. DRVENABLEDATA* pded)
  185. {
  186. // Engine Version is passed down so future drivers can support previous
  187. // engine versions. A next generation driver can support both the old
  188. // and new engine conventions if told what version of engine it is
  189. // working with. For the first version the driver does nothing with it.
  190. // Fill in as much as we can.
  191. if (cj >= sizeof(DRVENABLEDATA))
  192. pded->pdrvfn = gadrvfn;
  193. if (cj >= (sizeof(ULONG) * 2))
  194. pded->c = gcdrvfn;
  195. // DDI version this driver was targeted for is passed back to engine.
  196. // Future graphic's engine may break calls down to old driver format.
  197. if (cj >= sizeof(ULONG))
  198. pded->iDriverVersion = DDI_DRIVER_VERSION_NT4;
  199. return(TRUE);
  200. }
  201. /******************************Public*Routine******************************\
  202. * VOID DrvDisableDriver
  203. *
  204. * Tells the driver it is being disabled. Release any resources allocated in
  205. * DrvEnableDriver.
  206. *
  207. \**************************************************************************/
  208. VOID DrvDisableDriver(VOID)
  209. {
  210. return;
  211. }
  212. /******************************Public*Routine******************************\
  213. * DWORD getAvailableModes
  214. *
  215. * Calls the miniport to get the list of modes supported by the kernel driver,
  216. * and returns the list of modes supported by the diplay driver among those
  217. *
  218. * returns the number of entries in the videomode buffer.
  219. * 0 means no modes are supported by the miniport or that an error occured.
  220. *
  221. * NOTE: the buffer must be freed up by the caller.
  222. *
  223. \**************************************************************************/
  224. DWORD getAvailableModes(
  225. HANDLE hDriver,
  226. PVIDEO_MODE_INFORMATION* modeInformation,
  227. DWORD* cbModeSize)
  228. {
  229. ULONG ulTemp;
  230. VIDEO_NUM_MODES modes;
  231. PVIDEO_MODE_INFORMATION pVideoTemp;
  232. DWORD status;
  233. //
  234. // Get the number of modes supported by the mini-port
  235. //
  236. if (status = EngDeviceIoControl(hDriver,
  237. IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES,
  238. NULL,
  239. 0,
  240. &modes,
  241. sizeof(VIDEO_NUM_MODES),
  242. &ulTemp))
  243. {
  244. DISPDBG((0, "getAvailableModes failed VIDEO_QUERY_NUM_AVAIL_MODES"));
  245. DISPDBG((0, "Win32 Status = %x", status));
  246. return(0);
  247. }
  248. *cbModeSize = modes.ModeInformationLength;
  249. //
  250. // Allocate the buffer for the mini-port to write the modes in.
  251. //
  252. *modeInformation = (PVIDEO_MODE_INFORMATION)
  253. EngAllocMem(FL_ZERO_MEMORY,
  254. modes.NumModes *
  255. modes.ModeInformationLength, ALLOC_TAG);
  256. if (*modeInformation == (PVIDEO_MODE_INFORMATION) NULL)
  257. {
  258. DISPDBG((0, "getAvailableModes failed EngAllocMem"));
  259. return(0);
  260. }
  261. //
  262. // Ask the mini-port to fill in the available modes.
  263. //
  264. if (status = EngDeviceIoControl(hDriver,
  265. IOCTL_VIDEO_QUERY_AVAIL_MODES,
  266. NULL,
  267. 0,
  268. *modeInformation,
  269. modes.NumModes * modes.ModeInformationLength,
  270. &ulTemp))
  271. {
  272. DISPDBG((0, "getAvailableModes failed VIDEO_QUERY_AVAIL_MODES"));
  273. DISPDBG((0, "Win32 Status = %x", status));
  274. EngFreeMem(*modeInformation);
  275. *modeInformation = (PVIDEO_MODE_INFORMATION) NULL;
  276. return(0);
  277. }
  278. //
  279. // Now see which of these modes are supported by the display driver.
  280. // As an internal mechanism, set the length to 0 for the modes we
  281. // DO NOT support.
  282. //
  283. ulTemp = modes.NumModes;
  284. pVideoTemp = *modeInformation;
  285. //
  286. // Mode is rejected if it is not 4 planes, or not graphics, or is not
  287. // one of 1 bits per pel.
  288. //
  289. while (ulTemp--)
  290. {
  291. if ((pVideoTemp->NumberOfPlanes != 4 ) ||
  292. !(pVideoTemp->AttributeFlags & VIDEO_MODE_GRAPHICS) ||
  293. (pVideoTemp->BitsPerPlane != 1) ||
  294. (pVideoTemp->VisScreenWidth > 800))
  295. {
  296. pVideoTemp->Length = 0;
  297. }
  298. pVideoTemp = (PVIDEO_MODE_INFORMATION)
  299. (((PUCHAR)pVideoTemp) + modes.ModeInformationLength);
  300. }
  301. return(modes.NumModes);
  302. }
  303. /******************************Public*Routine******************************\
  304. * BOOL bInitializeModeFields
  305. *
  306. * Initializes a bunch of fields in the pdev, devcaps (aka gdiinfo), and
  307. * devinfo based on the requested mode.
  308. *
  309. \**************************************************************************/
  310. BOOL bInitializeModeFields(
  311. PDEV* ppdev,
  312. GDIINFO* pgdi,
  313. DEVINFO* pdi,
  314. DEVMODEW* pdm)
  315. {
  316. ULONG cModes;
  317. PVIDEO_MODE_INFORMATION pVideoBuffer;
  318. PVIDEO_MODE_INFORMATION pVideoModeSelected;
  319. PVIDEO_MODE_INFORMATION pVideoTemp;
  320. BOOL bSelectDefault;
  321. VIDEO_MODE_INFORMATION VideoModeInformation;
  322. ULONG cbModeSize;
  323. // Call the miniport to get mode information
  324. cModes = getAvailableModes(ppdev->hDriver, &pVideoBuffer, &cbModeSize);
  325. if (cModes == 0)
  326. goto ReturnFalse;
  327. // Now see if the requested mode has a match in that table.
  328. pVideoModeSelected = NULL;
  329. pVideoTemp = pVideoBuffer;
  330. if ((pdm->dmPelsWidth == 0) &&
  331. (pdm->dmPelsHeight == 0) &&
  332. (pdm->dmBitsPerPel == 0) &&
  333. (pdm->dmDisplayFrequency == 0))
  334. {
  335. DISPDBG((1, "Default mode requested"));
  336. bSelectDefault = TRUE;
  337. }
  338. else
  339. {
  340. DISPDBG((1, "Requested mode..."));
  341. DISPDBG((1, " Screen width -- %li", pdm->dmPelsWidth));
  342. DISPDBG((1, " Screen height -- %li", pdm->dmPelsHeight));
  343. DISPDBG((1, " Bits per pel -- %li", pdm->dmBitsPerPel));
  344. DISPDBG((1, " Frequency -- %li", pdm->dmDisplayFrequency));
  345. bSelectDefault = FALSE;
  346. }
  347. while (cModes--)
  348. {
  349. if (pVideoTemp->Length != 0)
  350. {
  351. DISPDBG((2, " Checking against miniport mode:"));
  352. DISPDBG((2, " Screen width -- %li", pVideoTemp->VisScreenWidth));
  353. DISPDBG((2, " Screen height -- %li", pVideoTemp->VisScreenHeight));
  354. DISPDBG((2, " Bits per pel -- %li", pVideoTemp->BitsPerPlane *
  355. pVideoTemp->NumberOfPlanes));
  356. DISPDBG((2, " Frequency -- %li", pVideoTemp->Frequency));
  357. if (bSelectDefault ||
  358. ((pVideoTemp->VisScreenWidth == pdm->dmPelsWidth) &&
  359. (pVideoTemp->VisScreenHeight == pdm->dmPelsHeight) &&
  360. (pVideoTemp->BitsPerPlane *
  361. pVideoTemp->NumberOfPlanes == pdm->dmBitsPerPel) &&
  362. (pVideoTemp->Frequency == pdm->dmDisplayFrequency)))
  363. {
  364. pVideoModeSelected = pVideoTemp;
  365. DISPDBG((1, "...Found a mode match!"));
  366. break;
  367. }
  368. }
  369. pVideoTemp = (PVIDEO_MODE_INFORMATION)
  370. (((PUCHAR)pVideoTemp) + cbModeSize);
  371. }
  372. // If no mode has been found, return an error
  373. if (pVideoModeSelected == NULL)
  374. {
  375. DISPDBG((1, "...Couldn't find a mode match!"));
  376. EngFreeMem(pVideoBuffer);
  377. goto ReturnFalse;
  378. }
  379. // We have chosen the one we want. Save it in a stack buffer and
  380. // get rid of allocated memory before we forget to free it.
  381. VideoModeInformation = *pVideoModeSelected;
  382. EngFreeMem(pVideoBuffer);
  383. // Set up screen information from the mini-port:
  384. ppdev->ulMode = VideoModeInformation.ModeIndex;
  385. ppdev->cxScreen = VideoModeInformation.VisScreenWidth;
  386. ppdev->cyScreen = VideoModeInformation.VisScreenHeight;
  387. ppdev->iBitmapFormat = BMF_4BPP;
  388. DISPDBG((1, "ScreenStride: %lx", VideoModeInformation.ScreenStride));
  389. ppdev->flHooks = (HOOK_BITBLT |
  390. HOOK_TEXTOUT |
  391. HOOK_COPYBITS |
  392. HOOK_STROKEPATH |
  393. HOOK_PAINT);
  394. ppdev->pjBase = INVALID_BASE_ADDRESS;
  395. // Fill in the GDIINFO data structure with the default 4bpp values:
  396. *pgdi = ggdiDefault;
  397. // Now overwrite the defaults with the relevant information returned
  398. // from the kernel driver:
  399. pgdi->ulHorzSize = VideoModeInformation.XMillimeter;
  400. pgdi->ulVertSize = VideoModeInformation.YMillimeter;
  401. pgdi->ulHorzRes = VideoModeInformation.VisScreenWidth;
  402. pgdi->ulVertRes = VideoModeInformation.VisScreenHeight;
  403. pgdi->ulPanningHorzRes = VideoModeInformation.VisScreenWidth;
  404. pgdi->ulPanningVertRes = VideoModeInformation.VisScreenHeight;
  405. pgdi->cBitsPixel = VideoModeInformation.BitsPerPlane;
  406. pgdi->cPlanes = VideoModeInformation.NumberOfPlanes;
  407. pgdi->ulVRefresh = VideoModeInformation.Frequency;
  408. pgdi->ulDACRed = VideoModeInformation.NumberRedBits;
  409. pgdi->ulDACGreen = VideoModeInformation.NumberGreenBits;
  410. pgdi->ulDACBlue = VideoModeInformation.NumberBlueBits;
  411. pgdi->ulLogPixelsX = pdm->dmLogPixels;
  412. pgdi->ulLogPixelsY = pdm->dmLogPixels;
  413. // Fill in the devinfo structure with the default 4bpp values:
  414. *pdi = gdevinfoDefault;
  415. return(TRUE);
  416. ReturnFalse:
  417. DISPDBG((0, "Failed bInitializeModeFields"));
  418. return(FALSE);
  419. }
  420. /******************************Public*Routine******************************\
  421. * BOOL bInitializePalette
  422. *
  423. * Initializes default palette for PDEV.
  424. *
  425. \**************************************************************************/
  426. BOOL bInitializePalette(
  427. PDEV* ppdev,
  428. DEVINFO* pdi)
  429. {
  430. HPALETTE hpal;
  431. hpal = EngCreatePalette(PAL_INDEXED, 16, (ULONG*) (logPalVGA.palPalEntry),
  432. 0, 0, 0);
  433. if (hpal == 0)
  434. goto ReturnFalse;
  435. ppdev->hpalDefault = hpal;
  436. pdi->hpalDefault = hpal;
  437. return(TRUE);
  438. ReturnFalse:
  439. DISPDBG((0, "Failed bInitializePalette"));
  440. return(FALSE);
  441. }
  442. /******************************Public*Routine******************************\
  443. * VOID vUninitializePalette
  444. *
  445. * Frees resources allocated by bInitializePalette.
  446. *
  447. * Note: In an error case, this may be called before bInitializePalette.
  448. *
  449. \**************************************************************************/
  450. VOID vUninitializePalette(PDEV* ppdev)
  451. {
  452. // Delete the default palette if we created one:
  453. if (ppdev->hpalDefault != 0)
  454. EngDeletePalette(ppdev->hpalDefault);
  455. }
  456. /******************************Public*Routine******************************\
  457. * DHPDEV DrvEnablePDEV
  458. *
  459. * Initializes a bunch of fields for GDI, based on the mode we've been asked
  460. * to do. This is the first thing called after DrvEnableDriver, when GDI
  461. * wants to get some information about us.
  462. *
  463. * (This function mostly returns back information; DrvEnableSurface is used
  464. * for initializing the hardware and driver components.)
  465. *
  466. \**************************************************************************/
  467. DHPDEV DrvEnablePDEV(
  468. DEVMODEW* pdm, // Contains data pertaining to requested mode
  469. PWSTR pwszLogAddr, // Logical address
  470. ULONG cPat, // Count of standard patterns
  471. HSURF* phsurfPatterns, // Buffer for standard patterns
  472. ULONG cjCaps, // Size of buffer for device caps 'pdevcaps'
  473. ULONG* pdevcaps, // Buffer for device caps, also known as 'gdiinfo'
  474. ULONG cjDevInfo, // Number of bytes in device info 'pdi'
  475. DEVINFO* pdi, // Device information
  476. HDEV hdev, // HDEV, used for callbacks
  477. PWSTR pwszDeviceName, // Device name
  478. HANDLE hDriver) // Kernel driver handle
  479. {
  480. PDEV* ppdev;
  481. // Future versions of NT had better supply 'devcaps' and 'devinfo'
  482. // structures that are the same size or larger than the current
  483. // structures:
  484. if ((cjCaps < sizeof(GDIINFO)) || (cjDevInfo < sizeof(DEVINFO)))
  485. {
  486. DISPDBG((0, "DrvEnablePDEV - Buffer size too small"));
  487. goto ReturnFailure0;
  488. }
  489. // Allocate a physical device structure. Note that we definitely
  490. // rely on the zero initialization:
  491. ppdev = (PDEV*) EngAllocMem(FL_ZERO_MEMORY, sizeof(PDEV), ALLOC_TAG);
  492. if (ppdev == NULL)
  493. {
  494. DISPDBG((0, "DrvEnablePDEV - Failed EngAllocMem"));
  495. goto ReturnFailure0;
  496. }
  497. ppdev->hDriver = hDriver;
  498. // Get the current screen mode information. Set up device caps and
  499. // devinfo:
  500. if (!bInitializeModeFields(ppdev, (GDIINFO*) pdevcaps, pdi, pdm))
  501. {
  502. DISPDBG((0, "DrvEnablePDEV - Failed bInitializeModeFields"));
  503. goto ReturnFailure1;
  504. }
  505. // Initialize palette information.
  506. if (!bInitializePalette(ppdev, pdi))
  507. {
  508. DISPDBG((0, "DrvEnablePDEV - Failed bInitializePalette"));
  509. goto ReturnFailure1;
  510. }
  511. return((DHPDEV) ppdev);
  512. ReturnFailure1:
  513. DrvDisablePDEV((DHPDEV) ppdev);
  514. ReturnFailure0:
  515. DISPDBG((0, "Failed DrvEnablePDEV"));
  516. return(0);
  517. }
  518. /******************************Public*Routine******************************\
  519. * DrvDisablePDEV
  520. *
  521. * Release the resources allocated in DrvEnablePDEV. If a surface has been
  522. * enabled DrvDisableSurface will have already been called.
  523. *
  524. * Note: In an error, we may call this before DrvEnablePDEV is done.
  525. *
  526. \**************************************************************************/
  527. VOID DrvDisablePDEV(
  528. DHPDEV dhpdev)
  529. {
  530. PDEV* ppdev;
  531. ppdev = (PDEV*) dhpdev;
  532. vUninitializePalette(ppdev);
  533. EngFreeMem(ppdev);
  534. }
  535. /******************************Public*Routine******************************\
  536. * VOID DrvCompletePDEV
  537. *
  538. * Store the HPDEV, the engines handle for this PDEV, in the DHPDEV.
  539. *
  540. \**************************************************************************/
  541. VOID DrvCompletePDEV(
  542. DHPDEV dhpdev,
  543. HDEV hdev)
  544. {
  545. ((PDEV*) dhpdev)->hdevEng = hdev;
  546. }
  547. /******************************Public*Routine******************************\
  548. * HSURF DrvEnableSurface
  549. *
  550. * Creates the drawing surface, initializes the hardware, and initializes
  551. * driver components. This function is called after DrvEnablePDEV, and
  552. * performs the final device initialization.
  553. *
  554. \**************************************************************************/
  555. HSURF DrvEnableSurface(
  556. DHPDEV dhpdev)
  557. {
  558. PDEV* ppdev;
  559. HSURF hsurfShadow;
  560. HSURF hsurfDevice;
  561. SIZEL sizl;
  562. ppdev = (PDEV*) dhpdev;
  563. /////////////////////////////////////////////////////////////////////
  564. // Have GDI create the actual SURFOBJ.
  565. //
  566. // Our drawing surface is going to be 'device-managed', meaning that
  567. // GDI cannot draw on the framebuffer bits directly, and as such we
  568. // create the surface via EngCreateSurface. By doing this, we ensure
  569. // that GDI will only ever access the bitmaps bits via the Drv calls
  570. // that we've HOOKed.
  571. sizl.cx = ppdev->cxScreen;
  572. sizl.cy = ppdev->cyScreen;
  573. hsurfDevice = EngCreateDeviceSurface(NULL, sizl, ppdev->iBitmapFormat);
  574. if (hsurfDevice == 0)
  575. {
  576. DISPDBG((0, "DrvEnableSurface - Failed EngCreateSurface"));
  577. return(0);
  578. }
  579. ppdev->hsurfScreen = hsurfDevice; // Remember it for clean-up
  580. /////////////////////////////////////////////////////////////////////
  581. // Now associate the surface and the PDEV.
  582. //
  583. // We have to associate the surface we just created with our physical
  584. // device so that GDI can get information related to the PDEV when
  585. // it's drawing to the surface (such as, for example, the length of
  586. // styles on the device when simulating styled lines).
  587. //
  588. if (!EngAssociateSurface(hsurfDevice, ppdev->hdevEng, ppdev->flHooks))
  589. {
  590. DISPDBG((0, "DrvEnableSurface - Failed EngAssociateSurface"));
  591. goto ReturnFailure;
  592. }
  593. // Create the 4bpp DIB on which we'll have GDI do all the drawing.
  594. // We'll merely occasionally blt portions to the screen to update.
  595. sizl.cx = ppdev->cxScreen;
  596. sizl.cy = ppdev->cyScreen;
  597. hsurfShadow = (HSURF) EngCreateBitmap(sizl, 0, ppdev->iBitmapFormat, 0,
  598. NULL);
  599. if (hsurfShadow == 0)
  600. goto ReturnFailure;
  601. if (!EngAssociateSurface(hsurfShadow, ppdev->hdevEng, 0))
  602. {
  603. DISPDBG((0, "DrvEnableSurface - Failed second EngAssociateSurface"));
  604. goto ReturnFailure;
  605. }
  606. ppdev->pso = EngLockSurface(hsurfShadow);
  607. if (ppdev->pso == NULL)
  608. goto ReturnFailure;
  609. /////////////////////////////////////////////////////////////////////
  610. // Now enable all the subcomponents.
  611. //
  612. // Note that the order in which these 'Enable' functions are called
  613. // may be significant in low off-screen memory conditions, because
  614. // the off-screen heap manager may fail some of the later
  615. // allocations...
  616. if (!bEnableHardware(ppdev))
  617. goto ReturnFailure;
  618. DISPDBG((5, "Passed DrvEnableSurface"));
  619. return(hsurfDevice);
  620. ReturnFailure:
  621. DrvDisableSurface((DHPDEV) ppdev);
  622. DISPDBG((0, "Failed DrvEnableSurface"));
  623. return(0);
  624. }
  625. /******************************Public*Routine******************************\
  626. * VOID DrvDisableSurface
  627. *
  628. * Free resources allocated by DrvEnableSurface. Release the surface.
  629. *
  630. * Note: In an error case, we may call this before DrvEnableSurface is
  631. * completely done.
  632. *
  633. \**************************************************************************/
  634. VOID DrvDisableSurface(
  635. DHPDEV dhpdev)
  636. {
  637. PDEV* ppdev;
  638. HSURF hsurf;
  639. ppdev = (PDEV*) dhpdev;
  640. // Note: In an error case, some of the following relies on the
  641. // fact that the PDEV is zero-initialized, so fields like
  642. // 'hsurfScreen' will be zero unless the surface has been
  643. // sucessfully initialized, and makes the assumption that
  644. // EngDeleteSurface can take '0' as a parameter.
  645. vDisableHardware(ppdev);
  646. if (ppdev->pso) {
  647. hsurf = ppdev->pso->hsurf;
  648. EngUnlockSurface(ppdev->pso);
  649. EngDeleteSurface(hsurf);
  650. }
  651. EngDeleteSurface(ppdev->hsurfScreen);
  652. }
  653. /******************************Public*Routine******************************\
  654. * VOID DrvAssertMode
  655. *
  656. * This asks the device to reset itself to the mode of the pdev passed in.
  657. *
  658. \**************************************************************************/
  659. BOOL DrvAssertMode(
  660. DHPDEV dhpdev,
  661. BOOL bEnable)
  662. {
  663. PDEV* ppdev;
  664. ppdev = (PDEV*) dhpdev;
  665. if (!bEnable)
  666. {
  667. //////////////////////////////////////////////////////////////
  668. // Disable - Switch to full-screen mode
  669. return(bAssertModeHardware(ppdev, FALSE));
  670. }
  671. else
  672. {
  673. //////////////////////////////////////////////////////////////
  674. // Enable - Switch back to graphics mode
  675. // We have to enable every subcomponent in the reverse order
  676. // in which it was disabled:
  677. return(bAssertModeHardware(ppdev, TRUE));
  678. }
  679. }
  680. /******************************Public*Routine******************************\
  681. * ULONG DrvGetModes
  682. *
  683. * Returns the list of available modes for the device.
  684. *
  685. \**************************************************************************/
  686. ULONG DrvGetModes(
  687. HANDLE hDriver,
  688. ULONG cjSize,
  689. DEVMODEW* pdm)
  690. {
  691. DWORD cModes;
  692. DWORD cbOutputSize;
  693. PVIDEO_MODE_INFORMATION pVideoModeInformation;
  694. PVIDEO_MODE_INFORMATION pVideoTemp;
  695. DWORD cOutputModes = cjSize / (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
  696. DWORD cbModeSize;
  697. cModes = getAvailableModes(hDriver,
  698. (PVIDEO_MODE_INFORMATION *) &pVideoModeInformation,
  699. &cbModeSize);
  700. if (cModes == 0)
  701. {
  702. DISPDBG((0, "DrvGetModes failed to get mode information"));
  703. return(0);
  704. }
  705. if (pdm == NULL)
  706. {
  707. cbOutputSize = cModes * (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
  708. }
  709. else
  710. {
  711. //
  712. // Now copy the information for the supported modes back into the
  713. // output buffer
  714. //
  715. cbOutputSize = 0;
  716. pVideoTemp = pVideoModeInformation;
  717. do
  718. {
  719. if (pVideoTemp->Length != 0)
  720. {
  721. if (cOutputModes == 0)
  722. {
  723. break;
  724. }
  725. //
  726. // Zero the entire structure to start off with.
  727. //
  728. memset(pdm, 0, sizeof(DEVMODEW));
  729. //
  730. // Set the name of the device to the name of the DLL.
  731. //
  732. memcpy(pdm->dmDeviceName, DLL_NAME, sizeof(DLL_NAME));
  733. pdm->dmSpecVersion = DM_SPECVERSION;
  734. pdm->dmDriverVersion = DM_SPECVERSION;
  735. pdm->dmSize = sizeof(DEVMODEW);
  736. pdm->dmDriverExtra = DRIVER_EXTRA_SIZE;
  737. pdm->dmBitsPerPel = pVideoTemp->NumberOfPlanes *
  738. pVideoTemp->BitsPerPlane;
  739. pdm->dmPelsWidth = pVideoTemp->VisScreenWidth;
  740. pdm->dmPelsHeight = pVideoTemp->VisScreenHeight;
  741. pdm->dmDisplayFrequency = pVideoTemp->Frequency;
  742. pdm->dmDisplayFlags = 0;
  743. pdm->dmFields = DM_BITSPERPEL |
  744. DM_PELSWIDTH |
  745. DM_PELSHEIGHT |
  746. DM_DISPLAYFREQUENCY |
  747. DM_DISPLAYFLAGS ;
  748. //
  749. // Go to the next DEVMODE entry in the buffer.
  750. //
  751. cOutputModes--;
  752. pdm = (LPDEVMODEW) ( ((ULONG_PTR)pdm) + sizeof(DEVMODEW) +
  753. DRIVER_EXTRA_SIZE);
  754. cbOutputSize += (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
  755. }
  756. pVideoTemp = (PVIDEO_MODE_INFORMATION)
  757. (((PUCHAR)pVideoTemp) + cbModeSize);
  758. } while (--cModes);
  759. }
  760. EngFreeMem(pVideoModeInformation);
  761. return(cbOutputSize);
  762. }