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.

567 lines
16 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: enable.c
  3. *
  4. * This module contains the functions that enable and disable the
  5. * driver, the pdev, and the surface.
  6. *
  7. * Copyright (c) 1992 Microsoft Corporation
  8. \**************************************************************************/
  9. #include "driver.h"
  10. //
  11. // Build the driver function table gadrvfn with function index/address pairs
  12. //
  13. DRVFN gadrvfn[] = {
  14. { INDEX_DrvEnablePDEV, (PFN) DrvEnablePDEV },
  15. { INDEX_DrvCompletePDEV, (PFN) DrvCompletePDEV },
  16. { INDEX_DrvDisablePDEV, (PFN) DrvDisablePDEV },
  17. { INDEX_DrvEnableSurface, (PFN) DrvEnableSurface },
  18. { INDEX_DrvDisableSurface, (PFN) DrvDisableSurface },
  19. { INDEX_DrvAssertMode, (PFN) DrvAssertMode },
  20. { INDEX_DrvDitherColor, (PFN) DrvDitherColor },
  21. { INDEX_DrvGetModes, (PFN) DrvGetModes },
  22. { INDEX_DrvCopyBits, (PFN) DrvCopyBits },
  23. { INDEX_DrvBitBlt, (PFN) DrvBitBlt },
  24. { INDEX_DrvTextOut, (PFN) DrvTextOut },
  25. { INDEX_DrvStrokePath, (PFN) DrvStrokePath },
  26. { INDEX_DrvPaint, (PFN) DrvPaint },
  27. { INDEX_DrvDisableDriver, (PFN) DrvDisableDriver }
  28. };
  29. BOOL bInitDefaultPalette(PPDEV ppdev, DEVINFO *pDevInfo);
  30. /******************************Public*Routine******************************\
  31. * DrvEnableDriver
  32. *
  33. * Enables the driver by retrieving the drivers function table and version.
  34. *
  35. \**************************************************************************/
  36. BOOL DrvEnableDriver(
  37. ULONG iEngineVersion,
  38. ULONG cj,
  39. PDRVENABLEDATA pded)
  40. {
  41. UNREFERENCED_PARAMETER(iEngineVersion);
  42. // Engine Version is passed down so future drivers can support previous
  43. // engine versions. A next generation driver can support both the old
  44. // and new engine conventions if told what version of engine it is
  45. // working with. For the first version the driver does nothing with it.
  46. // Fill in as much as we can.
  47. if (cj >= sizeof(DRVENABLEDATA))
  48. pded->pdrvfn = gadrvfn;
  49. if (cj >= (sizeof(ULONG) * 2))
  50. pded->c = sizeof(gadrvfn) / sizeof(DRVFN);
  51. // DDI version this driver was targeted for is passed back to engine.
  52. // Future graphic's engine may break calls down to old driver format.
  53. if (cj >= sizeof(ULONG))
  54. pded->iDriverVersion = DDI_DRIVER_VERSION_NT4;
  55. return(TRUE);
  56. }
  57. /******************************Public*Routine******************************\
  58. * DrvDisableDriver
  59. *
  60. * Tells the driver it is being disabled. Release any resources allocated in
  61. * DrvEnableDriver.
  62. *
  63. \**************************************************************************/
  64. VOID DrvDisableDriver(VOID)
  65. {
  66. return;
  67. }
  68. /******************************Public*Routine******************************\
  69. * DrvEnablePDEV
  70. *
  71. * DDI function, Enables the Physical Device.
  72. *
  73. * Return Value: device handle to pdev.
  74. *
  75. \**************************************************************************/
  76. DHPDEV DrvEnablePDEV(
  77. DEVMODEW *pDevmode, // Pointer to DEVMODE
  78. PWSTR pwszLogAddress, // Logical address
  79. ULONG cPatterns, // number of patterns
  80. HSURF *ahsurfPatterns, // return standard patterns
  81. ULONG cjGdiInfo, // Length of memory pointed to by pGdiInfo
  82. ULONG *pGdiInfo, // Pointer to GdiInfo structure
  83. ULONG cjDevInfo, // Length of following PDEVINFO structure
  84. DEVINFO *pDevInfo, // physical device information structure
  85. HDEV hdev, // HDEV, used for callbacks
  86. PWSTR pwszDeviceName, // DeviceName - not used
  87. HANDLE hDriver) // Handle to base driver
  88. {
  89. GDIINFO GdiInfo;
  90. DEVINFO DevInfo;
  91. PPDEV ppdev;
  92. UNREFERENCED_PARAMETER(pwszLogAddress);
  93. UNREFERENCED_PARAMETER(pwszDeviceName);
  94. // Allocate a physical device structure.
  95. ppdev = (PPDEV) EngAllocMem(FL_ZERO_MEMORY, sizeof(PDEV), ALLOC_TAG);
  96. if (ppdev == (PPDEV) NULL)
  97. {
  98. DISPDBG((0, "VGA64K: Couldn't allocate PDEV buffer"));
  99. goto error0;
  100. }
  101. // Set up pointers in PDEV to temporary structures we build up to return.
  102. ppdev->pGdiInfo = &GdiInfo;
  103. ppdev->pDevInfo = &DevInfo;
  104. // Save the screen handle in the PDEV.
  105. ppdev->hDriver = hDriver;
  106. // Get the current screen mode information. Set up device caps and devinfo.
  107. if (!bInitPDEV(ppdev,pDevmode))
  108. {
  109. DISPDBG((0,"vga64k Couldn't initialize PDEV"));
  110. goto error1;
  111. }
  112. // Initialize palette information.
  113. if (!bInitDefaultPalette(ppdev, &DevInfo))
  114. {
  115. DISPDBG((0, "VGA64K: DrvEnablePDEV failed bInitPalette"));
  116. goto error1a;
  117. }
  118. // Copy the devinfo into the engine buffer.
  119. memcpy(pDevInfo, ppdev->pDevInfo, min(sizeof(DEVINFO), cjDevInfo));
  120. // Set the pdevCaps with GdiInfo we have prepared to the list of caps for this
  121. // pdev.
  122. memcpy(pGdiInfo, ppdev->pGdiInfo, min(cjGdiInfo, sizeof(GDIINFO)));
  123. // Set NULL into pointers for stack allocated memory.
  124. ppdev->pGdiInfo = (GDIINFO *) NULL;
  125. ppdev->pDevInfo = (DEVINFO *) NULL;
  126. // Create a clip object we can use when we're given a NULL clip object:
  127. ppdev->pcoNull = EngCreateClip();
  128. if (ppdev->pcoNull == NULL)
  129. {
  130. RIP("Couldn't create clip");
  131. goto error2;
  132. }
  133. ppdev->pcoNull->iDComplexity = DC_RECT;
  134. ppdev->pcoNull->rclBounds.left = 0;
  135. ppdev->pcoNull->rclBounds.top = 0;
  136. ppdev->pcoNull->rclBounds.right = ppdev->cxScreen;
  137. ppdev->pcoNull->rclBounds.bottom = ppdev->cyScreen;
  138. ppdev->pcoNull->fjOptions = OC_BANK_CLIP;
  139. // pvSaveScan0 is non-NULL only when enumerating banks:
  140. ppdev->pvSaveScan0 = NULL;
  141. // We're all done:
  142. return((DHPDEV) ppdev);
  143. error2: //@@@
  144. error1a: //@@@
  145. error1:
  146. EngFreeMem(ppdev);
  147. error0:
  148. return((DHPDEV) 0);
  149. }
  150. /******************************Public*Routine******************************\
  151. * DrvCompletePDEV
  152. *
  153. * Store the HPDEV, the engines handle for this PDEV, in the DHPDEV.
  154. *
  155. \**************************************************************************/
  156. VOID DrvCompletePDEV(
  157. DHPDEV dhpdev,
  158. HDEV hdev)
  159. {
  160. ((PPDEV) dhpdev)->hdevEng = hdev;
  161. }
  162. /******************************Public*Routine******************************\
  163. * DrvDisablePDEV
  164. *
  165. * Release the resources allocated in DrvEnablePDEV. If a surface has been
  166. * enabled DrvDisableSurface will have already been called.
  167. *
  168. \**************************************************************************/
  169. VOID DrvDisablePDEV(
  170. DHPDEV dhpdev)
  171. {
  172. PPDEV ppdev = (PPDEV) dhpdev;
  173. EngDeleteClip(ppdev->pcoNull);
  174. EngFreeMem(dhpdev);
  175. }
  176. /******************************Public*Routine******************************\
  177. * DrvEnableSurface
  178. *
  179. * Enable the surface for the device. Hook the calls this driver supports.
  180. *
  181. * Return: Handle to the surface if successful, 0 for failure.
  182. *
  183. \**************************************************************************/
  184. HSURF DrvEnableSurface(
  185. DHPDEV dhpdev)
  186. {
  187. PPDEV ppdev;
  188. HSURF hsurf;
  189. HSURF hsurfBm;
  190. SIZEL sizl;
  191. ULONG ulBitmapType;
  192. FLONG flHooks;
  193. // Create engine bitmap around frame buffer.
  194. ppdev = (PPDEV) dhpdev;
  195. if (!bInitSURF(ppdev, TRUE))
  196. goto error0;
  197. sizl.cx = ppdev->cxScreen;
  198. sizl.cy = ppdev->cyScreen;
  199. ulBitmapType = BMF_16BPP;
  200. flHooks = HOOKS_BMF16BPP;
  201. ASSERTVGA(ppdev->ulBitCount == 16, "Can only handle 16bpp VGAs");
  202. hsurfBm = (HSURF) EngCreateBitmap(sizl,
  203. ppdev->lDeltaScreen,
  204. (ULONG) (ulBitmapType),
  205. (FLONG) (((ppdev->lDeltaScreen > 0)
  206. ? BMF_TOPDOWN
  207. : 0)),
  208. (PVOID) (ppdev->pjScreen));
  209. if (hsurfBm == 0)
  210. {
  211. RIP("Couldn't create surface");
  212. goto error0;
  213. }
  214. if (!EngAssociateSurface(hsurfBm, ppdev->hdevEng, 0))
  215. {
  216. RIP("Couldn't create or associate surface");
  217. goto error1;
  218. }
  219. ppdev->hsurfBm = hsurfBm;
  220. ppdev->pSurfObj = EngLockSurface(hsurfBm);
  221. if (ppdev->pSurfObj == NULL)
  222. {
  223. RIP("Couldn't lock surface");
  224. goto error1;
  225. }
  226. hsurf = EngCreateDeviceSurface((DHSURF) ppdev, sizl, BMF_16BPP);
  227. if (hsurf == 0)
  228. {
  229. RIP("Couldn't create surface");
  230. goto error2;
  231. }
  232. if (!EngAssociateSurface(hsurf, ppdev->hdevEng, flHooks))
  233. {
  234. RIP("Couldn't associate surface");
  235. goto error3;
  236. }
  237. ppdev->hsurfEng = hsurf;
  238. // Disable all the clipping.
  239. if (!bEnableBanking(ppdev))
  240. {
  241. RIP("Couldn't initialize banking");
  242. goto error3;
  243. }
  244. ppdev->pvTmp = (PVOID) EngAllocMem(0, TMP_BUFFER_SIZE, ALLOC_TAG);
  245. if (ppdev->pvTmp == NULL)
  246. {
  247. DISPDBG((0, "VGA64K: Couldn't allocate temporary buffer"));
  248. goto error4;
  249. }
  250. ASSERTVGA(ppdev->lNextScan != 0, "lNextScan shouldn't be zero");
  251. sizl.cx = ppdev->cxScreen;
  252. sizl.cy = TMP_BUFFER_SIZE / (sizl.cx * 2);
  253. ppdev->hbmTmp = EngCreateBitmap(sizl, sizl.cx*2, BMF_16BPP, 0,
  254. ppdev->pvTmp);
  255. if (ppdev->hbmTmp == (HBITMAP) 0)
  256. {
  257. RIP("Couldn't create temporary bitmap");
  258. goto error5;
  259. }
  260. ppdev->psoTmp = EngLockSurface((HSURF) ppdev->hbmTmp);
  261. if (ppdev->psoTmp == (SURFOBJ*) NULL)
  262. {
  263. RIP("Couldn't lock temporary surface");
  264. goto error6;
  265. }
  266. return(hsurf);
  267. error6:
  268. EngDeleteSurface((HSURF) ppdev->hbmTmp);
  269. error5:
  270. EngFreeMem(ppdev->pvTmp);
  271. error4:
  272. vDisableBanking(ppdev);
  273. error3:
  274. EngDeleteSurface(hsurf);
  275. error2:
  276. EngUnlockSurface(ppdev->pSurfObj);
  277. error1:
  278. EngDeleteSurface(hsurfBm);
  279. error0:
  280. //@@@
  281. DISPDBG((0,"Exiting DrvEnableSurface... \n"));
  282. //@@@
  283. return((HSURF) 0);
  284. }
  285. /******************************Public*Routine******************************\
  286. * DrvDisableSurface
  287. *
  288. * Free resources allocated by DrvEnableSurface. Release the surface.
  289. *
  290. \**************************************************************************/
  291. VOID DrvDisableSurface(
  292. DHPDEV dhpdev)
  293. {
  294. PPDEV ppdev = (PPDEV) dhpdev;
  295. EngUnlockSurface(ppdev->psoTmp);
  296. EngDeleteSurface((HSURF) ppdev->hbmTmp);
  297. EngFreeMem(ppdev->pvTmp);
  298. EngDeleteSurface(ppdev->hsurfEng);
  299. vDisableSURF(ppdev);
  300. ppdev->hsurfEng = (HSURF) 0;
  301. vDisableBanking(ppdev);
  302. }
  303. /******************************Public*Routine******************************\
  304. * DrvAssertMode
  305. *
  306. * This asks the device to reset itself to the mode of the pdev passed in.
  307. *
  308. \**************************************************************************/
  309. BOOL
  310. DrvAssertMode(
  311. DHPDEV dhpdev,
  312. BOOL bEnable)
  313. {
  314. PPDEV ppdev = (PPDEV) dhpdev;
  315. ULONG ulReturn;
  316. if (bEnable)
  317. {
  318. // The screen must be reenabled, reinitialize the device to
  319. // a clean state.
  320. return(bInitSURF(ppdev, FALSE));
  321. }
  322. else
  323. {
  324. // Call the kernel driver to reset the device to a known state.
  325. if (EngDeviceIoControl(ppdev->hDriver,
  326. IOCTL_VIDEO_RESET_DEVICE,
  327. NULL,
  328. 0,
  329. NULL,
  330. 0,
  331. &ulReturn))
  332. {
  333. RIP("VIDEO_RESET_DEVICE failed");
  334. return(FALSE);
  335. }
  336. else
  337. {
  338. return(TRUE);
  339. }
  340. }
  341. }
  342. /******************************Public*Routine******************************\
  343. * DrvGetModes
  344. *
  345. * Returns the list of available modes for the device.
  346. *
  347. \**************************************************************************/
  348. ULONG DrvGetModes(
  349. HANDLE hDriver,
  350. ULONG cjSize,
  351. DEVMODEW *pdm)
  352. {
  353. DWORD cModes;
  354. DWORD cbOutputSize;
  355. PVIDEO_MODE_INFORMATION pVideoModeInformation, pVideoTemp;
  356. DWORD cOutputModes = cjSize / (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
  357. DWORD cbModeSize;
  358. DISPDBG((2, "Vga64k.dll: DrvGetModes\n"));
  359. cModes = getAvailableModes(hDriver,
  360. (PVIDEO_MODE_INFORMATION *) &pVideoModeInformation,
  361. &cbModeSize);
  362. if (cModes == 0)
  363. {
  364. DISPDBG((0, "VGA64k DISP DrvGetModes failed to get mode information"));
  365. return 0;
  366. }
  367. if (pdm == NULL)
  368. {
  369. cbOutputSize = cModes * (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
  370. }
  371. else
  372. {
  373. //
  374. // Now copy the information for the supported modes back into the output
  375. // buffer
  376. //
  377. cbOutputSize = 0;
  378. pVideoTemp = pVideoModeInformation;
  379. do
  380. {
  381. if (pVideoTemp->Length != 0)
  382. {
  383. if (cOutputModes == 0)
  384. {
  385. break;
  386. }
  387. //
  388. // Zero the entire structure to start off with.
  389. //
  390. memset(pdm, 0, sizeof(DEVMODEW));
  391. //
  392. // Set the name of the device to the name of the DLL.
  393. //
  394. memcpy(pdm->dmDeviceName, DLL_NAME, sizeof(DLL_NAME));
  395. pdm->dmSpecVersion = DM_SPECVERSION;
  396. pdm->dmDriverVersion = DM_SPECVERSION;
  397. pdm->dmSize = sizeof(DEVMODEW);
  398. pdm->dmDriverExtra = DRIVER_EXTRA_SIZE;
  399. pdm->dmBitsPerPel = pVideoTemp->NumberOfPlanes *
  400. pVideoTemp->BitsPerPlane;
  401. pdm->dmPelsWidth = pVideoTemp->VisScreenWidth;
  402. pdm->dmPelsHeight = pVideoTemp->VisScreenHeight;
  403. pdm->dmDisplayFrequency = pVideoTemp->Frequency;
  404. pdm->dmDisplayFlags = 0;
  405. pdm->dmFields = DM_BITSPERPEL |
  406. DM_PELSWIDTH |
  407. DM_PELSHEIGHT |
  408. DM_DISPLAYFREQUENCY |
  409. DM_DISPLAYFLAGS ;
  410. //
  411. // Go to the next DEVMODE entry in the buffer.
  412. //
  413. cOutputModes--;
  414. pdm = (LPDEVMODEW) ( ((ULONG)pdm) + sizeof(DEVMODEW) +
  415. DRIVER_EXTRA_SIZE);
  416. cbOutputSize += (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
  417. }
  418. pVideoTemp = (PVIDEO_MODE_INFORMATION)
  419. (((PUCHAR)pVideoTemp) + cbModeSize);
  420. } while (--cModes);
  421. }
  422. EngFreeMem(pVideoModeInformation);
  423. return cbOutputSize;
  424. }
  425. /******************************Public*Routine******************************\
  426. * bInitDefaultPalette
  427. *
  428. * Initializes default palette for PDEV.
  429. *
  430. \**************************************************************************/
  431. BOOL bInitDefaultPalette(PPDEV ppdev, DEVINFO *pDevInfo)
  432. {
  433. ppdev->hpalDefault =
  434. pDevInfo->hpalDefault = EngCreatePalette(PAL_BITFIELDS,
  435. 0,(PULONG) NULL,
  436. ppdev->flRed,
  437. ppdev->flGreen,
  438. ppdev->flBlue);
  439. if (ppdev->hpalDefault == (HPALETTE) 0)
  440. {
  441. RIP("DISP bInitDefaultPalette failed EngCreatePalette\n");
  442. return(FALSE);
  443. }
  444. return(TRUE);
  445. }