Source code of Windows XP (NT5)
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.

523 lines
14 KiB

  1. /******************************Module*Header*******************************\
  2. *
  3. * *******************
  4. * * GDI SAMPLE CODE *
  5. * *******************
  6. *
  7. * Module Name: enable.c
  8. *
  9. * This module contains the functions that enable and disable the
  10. * driver, the pdev, and the surface.
  11. *
  12. * Copyright (c) 1992-1998 Microsoft Corporation
  13. \**************************************************************************/
  14. #include "driver.h"
  15. // The driver function table with all function index/address pairs
  16. static DRVFN gadrvfn[] =
  17. {
  18. { INDEX_DrvEnablePDEV, (PFN) DrvEnablePDEV },
  19. { INDEX_DrvCompletePDEV, (PFN) DrvCompletePDEV },
  20. { INDEX_DrvDisablePDEV, (PFN) DrvDisablePDEV },
  21. { INDEX_DrvEnableSurface, (PFN) DrvEnableSurface },
  22. { INDEX_DrvOffset, (PFN) DrvOffset },
  23. { INDEX_DrvDisableSurface, (PFN) DrvDisableSurface },
  24. { INDEX_DrvAssertMode, (PFN) DrvAssertMode },
  25. { INDEX_DrvSetPalette, (PFN) DrvSetPalette },
  26. { INDEX_DrvMovePointer, (PFN) DrvMovePointer },
  27. { INDEX_DrvSetPointerShape, (PFN) DrvSetPointerShape },
  28. { INDEX_DrvDitherColor, (PFN) DrvDitherColor },
  29. { INDEX_DrvSynchronize, (PFN) DrvSynchronize },
  30. { INDEX_DrvGetModes, (PFN) DrvGetModes }
  31. };
  32. // Define the functions you want to hook for 8/16/24/32 pel formats
  33. #define HOOKS_BMF8BPP 0
  34. #define HOOKS_BMF16BPP 0
  35. #define HOOKS_BMF24BPP 0
  36. #define HOOKS_BMF32BPP 0
  37. /******************************Public*Routine******************************\
  38. * DrvEnableDriver
  39. *
  40. * Enables the driver by retrieving the drivers function table and version.
  41. *
  42. \**************************************************************************/
  43. BOOL DrvEnableDriver(
  44. ULONG iEngineVersion,
  45. ULONG cj,
  46. PDRVENABLEDATA pded)
  47. {
  48. // Engine Version is passed down so future drivers can support previous
  49. // engine versions. A next generation driver can support both the old
  50. // and new engine conventions if told what version of engine it is
  51. // working with. For the first version the driver does nothing with it.
  52. iEngineVersion;
  53. // Fill in as much as we can.
  54. if (cj >= sizeof(DRVENABLEDATA))
  55. pded->pdrvfn = gadrvfn;
  56. if (cj >= (sizeof(ULONG) * 2))
  57. pded->c = sizeof(gadrvfn) / sizeof(DRVFN);
  58. // DDI version this driver was targeted for is passed back to engine.
  59. // Future graphic's engine may break calls down to old driver format.
  60. if (cj >= sizeof(ULONG))
  61. pded->iDriverVersion = DDI_DRIVER_VERSION_NT4;
  62. return(TRUE);
  63. }
  64. /******************************Public*Routine******************************\
  65. * DrvEnablePDEV
  66. *
  67. * DDI function, Enables the Physical Device.
  68. *
  69. * Return Value: device handle to pdev.
  70. *
  71. \**************************************************************************/
  72. DHPDEV DrvEnablePDEV(
  73. DEVMODEW *pDevmode, // Pointer to DEVMODE
  74. PWSTR pwszLogAddress, // Logical address
  75. ULONG cPatterns, // number of patterns
  76. HSURF *ahsurfPatterns, // return standard patterns
  77. ULONG cjGdiInfo, // Length of memory pointed to by pGdiInfo
  78. ULONG *pGdiInfo, // Pointer to GdiInfo structure
  79. ULONG cjDevInfo, // Length of following PDEVINFO structure
  80. DEVINFO *pDevInfo, // physical device information structure
  81. HDEV hdev, // HDEV, used for callbacks
  82. PWSTR pwszDeviceName, // DeviceName - not used
  83. HANDLE hDriver) // Handle to base driver
  84. {
  85. GDIINFO GdiInfo;
  86. DEVINFO DevInfo;
  87. PPDEV ppdev = (PPDEV) NULL;
  88. UNREFERENCED_PARAMETER(pwszLogAddress);
  89. UNREFERENCED_PARAMETER(pwszDeviceName);
  90. // Allocate a physical device structure.
  91. ppdev = (PPDEV) EngAllocMem(0, sizeof(PDEV), ALLOC_TAG);
  92. if (ppdev == (PPDEV) NULL)
  93. {
  94. RIP("DISP DrvEnablePDEV failed EngAllocMem\n");
  95. return((DHPDEV) 0);
  96. }
  97. memset(ppdev, 0, sizeof(PDEV));
  98. // Save the screen handle in the PDEV.
  99. ppdev->hDriver = hDriver;
  100. // Get the current screen mode information. Set up device caps and devinfo.
  101. if (!bInitPDEV(ppdev, pDevmode, &GdiInfo, &DevInfo))
  102. {
  103. DISPDBG((0,"DISP DrvEnablePDEV failed\n"));
  104. goto error_free;
  105. }
  106. // Initialize the cursor information.
  107. if (!bInitPointer(ppdev, &DevInfo))
  108. {
  109. // Not a fatal error...
  110. DISPDBG((0, "DrvEnablePDEV failed bInitPointer\n"));
  111. }
  112. // Initialize palette information.
  113. if (!bInitPaletteInfo(ppdev, &DevInfo))
  114. {
  115. RIP("DrvEnablePDEV failed bInitPalette\n");
  116. goto error_free;
  117. }
  118. // Copy the devinfo into the engine buffer.
  119. memcpy(pDevInfo, &DevInfo, 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, &GdiInfo, min(cjGdiInfo, sizeof(GDIINFO)));
  123. return((DHPDEV) ppdev);
  124. // Error case for failure.
  125. error_free:
  126. EngFreeMem(ppdev);
  127. return((DHPDEV) 0);
  128. }
  129. /******************************Public*Routine******************************\
  130. * DrvCompletePDEV
  131. *
  132. * Store the HPDEV, the engines handle for this PDEV, in the DHPDEV.
  133. *
  134. \**************************************************************************/
  135. VOID DrvCompletePDEV(
  136. DHPDEV dhpdev,
  137. HDEV hdev)
  138. {
  139. ((PPDEV) dhpdev)->hdevEng = hdev;
  140. }
  141. /******************************Public*Routine******************************\
  142. * DrvDisablePDEV
  143. *
  144. * Release the resources allocated in DrvEnablePDEV. If a surface has been
  145. * enabled DrvDisableSurface will have already been called.
  146. *
  147. \**************************************************************************/
  148. VOID DrvDisablePDEV(
  149. DHPDEV dhpdev)
  150. {
  151. vDisablePalette((PPDEV) dhpdev);
  152. EngFreeMem(dhpdev);
  153. }
  154. /******************************Public*Routine******************************\
  155. * VOID DrvOffset
  156. *
  157. * DescriptionText
  158. *
  159. \**************************************************************************/
  160. BOOL DrvOffset(
  161. SURFOBJ* pso,
  162. LONG x,
  163. LONG y,
  164. FLONG flReserved)
  165. {
  166. PDEV* ppdev = (PDEV*) pso->dhpdev;
  167. // Add back last offset that we subtracted. I could combine the next
  168. // two statements, but I thought this was more clear. It's not
  169. // performance critical anyway.
  170. ppdev->pjScreen += ((ppdev->ptlOrg.y * ppdev->lDeltaScreen) +
  171. (ppdev->ptlOrg.x * ((ppdev->ulBitCount+1) >> 3)));
  172. // Subtract out new offset
  173. ppdev->pjScreen -= ((y * ppdev->lDeltaScreen) +
  174. (x * ((ppdev->ulBitCount+1) >> 3)));
  175. ppdev->ptlOrg.x = x;
  176. ppdev->ptlOrg.y = y;
  177. return(TRUE);
  178. }
  179. /******************************Public*Routine******************************\
  180. * DrvEnableSurface
  181. *
  182. * Enable the surface for the device. Hook the calls this driver supports.
  183. *
  184. * Return: Handle to the surface if successful, 0 for failure.
  185. *
  186. \**************************************************************************/
  187. HSURF DrvEnableSurface(
  188. DHPDEV dhpdev)
  189. {
  190. PPDEV ppdev;
  191. HSURF hsurf;
  192. SIZEL sizl;
  193. ULONG ulBitmapType;
  194. FLONG flHooks;
  195. // Create engine bitmap around frame buffer.
  196. ppdev = (PPDEV) dhpdev;
  197. ppdev->ptlOrg.x = 0;
  198. ppdev->ptlOrg.y = 0;
  199. if (!bInitSURF(ppdev, TRUE))
  200. {
  201. DISPDBG((0, "DISP DrvEnableSurface failed bInitSURF\n"));
  202. return(FALSE);
  203. }
  204. sizl.cx = ppdev->cxScreen;
  205. sizl.cy = ppdev->cyScreen;
  206. if (ppdev->ulBitCount == 8)
  207. {
  208. if (!bInit256ColorPalette(ppdev)) {
  209. RIP("DISP DrvEnableSurface failed to init the 8bpp palette\n");
  210. return(FALSE);
  211. }
  212. ulBitmapType = BMF_8BPP;
  213. flHooks = HOOKS_BMF8BPP;
  214. }
  215. else if (ppdev->ulBitCount == 16)
  216. {
  217. ulBitmapType = BMF_16BPP;
  218. flHooks = HOOKS_BMF16BPP;
  219. }
  220. else if (ppdev->ulBitCount == 24)
  221. {
  222. ulBitmapType = BMF_24BPP;
  223. flHooks = HOOKS_BMF24BPP;
  224. }
  225. else
  226. {
  227. ulBitmapType = BMF_32BPP;
  228. flHooks = HOOKS_BMF32BPP;
  229. }
  230. ppdev->flHooks = flHooks;
  231. hsurf = (HSURF)EngCreateDeviceSurface((DHSURF)ppdev,
  232. sizl,
  233. ulBitmapType);
  234. if (hsurf == (HSURF) 0)
  235. {
  236. RIP("DISP DrvEnableSurface failed EngCreateDeviceSurface\n");
  237. return(FALSE);
  238. }
  239. if ( !EngModifySurface(hsurf,
  240. ppdev->hdevEng,
  241. ppdev->flHooks | HOOK_SYNCHRONIZE,
  242. MS_NOTSYSTEMMEMORY,
  243. (DHSURF)ppdev,
  244. ppdev->pjScreen,
  245. ppdev->lDeltaScreen,
  246. NULL))
  247. {
  248. RIP("DISP DrvEnableSurface failed EngModifySurface\n");
  249. return(FALSE);
  250. }
  251. ppdev->hsurfEng = hsurf;
  252. return(hsurf);
  253. }
  254. /******************************Public*Routine******************************\
  255. * DrvDisableSurface
  256. *
  257. * Free resources allocated by DrvEnableSurface. Release the surface.
  258. *
  259. \**************************************************************************/
  260. VOID DrvDisableSurface(
  261. DHPDEV dhpdev)
  262. {
  263. EngDeleteSurface(((PPDEV) dhpdev)->hsurfEng);
  264. vDisableSURF((PPDEV) dhpdev);
  265. ((PPDEV) dhpdev)->hsurfEng = (HSURF) 0;
  266. }
  267. /******************************Public*Routine******************************\
  268. * DrvAssertMode
  269. *
  270. * This asks the device to reset itself to the mode of the pdev passed in.
  271. *
  272. \**************************************************************************/
  273. BOOL DrvAssertMode(
  274. DHPDEV dhpdev,
  275. BOOL bEnable)
  276. {
  277. PPDEV ppdev = (PPDEV) dhpdev;
  278. ULONG ulReturn;
  279. PBYTE pjScreen;
  280. if (bEnable)
  281. {
  282. //
  283. // The screen must be reenabled, reinitialize the device to clean state.
  284. //
  285. pjScreen = ppdev->pjScreen;
  286. if (!bInitSURF(ppdev, TRUE))
  287. {
  288. RIP("DISP DrvAssertMode failed bInitSURF\n");
  289. return (FALSE);
  290. }
  291. if (pjScreen != ppdev->pjScreen) {
  292. if ( !EngModifySurface(ppdev->hsurfEng,
  293. ppdev->hdevEng,
  294. ppdev->flHooks | HOOK_SYNCHRONIZE,
  295. MS_NOTSYSTEMMEMORY,
  296. (DHSURF)ppdev,
  297. ppdev->pjScreen,
  298. ppdev->lDeltaScreen,
  299. NULL))
  300. {
  301. RIP("DISP DrvAssertMode failed EngModifySurface\n");
  302. return (FALSE);
  303. }
  304. }
  305. return (TRUE);
  306. }
  307. else
  308. {
  309. //
  310. // We must give up the display.
  311. // Call the kernel driver to reset the device to a known state.
  312. //
  313. if (EngDeviceIoControl(ppdev->hDriver,
  314. IOCTL_VIDEO_RESET_DEVICE,
  315. NULL,
  316. 0,
  317. NULL,
  318. 0,
  319. &ulReturn))
  320. {
  321. RIP("DISP DrvAssertMode failed IOCTL");
  322. return FALSE;
  323. }
  324. else
  325. {
  326. return TRUE;
  327. }
  328. }
  329. }
  330. /******************************Public*Routine******************************\
  331. * DrvGetModes
  332. *
  333. * Returns the list of available modes for the device.
  334. *
  335. \**************************************************************************/
  336. ULONG DrvGetModes(
  337. HANDLE hDriver,
  338. ULONG cjSize,
  339. DEVMODEW *pdm)
  340. {
  341. DWORD cModes;
  342. DWORD cbOutputSize;
  343. PVIDEO_MODE_INFORMATION pVideoModeInformation, pVideoTemp;
  344. DWORD cOutputModes = cjSize / (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
  345. DWORD cbModeSize;
  346. DISPDBG((3, "DrvGetModes\n"));
  347. cModes = getAvailableModes(hDriver,
  348. (PVIDEO_MODE_INFORMATION *) &pVideoModeInformation,
  349. &cbModeSize);
  350. if (cModes == 0)
  351. {
  352. DISPDBG((0, "DrvGetModes failed to get mode information"));
  353. return 0;
  354. }
  355. if (pdm == NULL)
  356. {
  357. cbOutputSize = cModes * (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
  358. }
  359. else
  360. {
  361. //
  362. // Now copy the information for the supported modes back into the output
  363. // buffer
  364. //
  365. cbOutputSize = 0;
  366. pVideoTemp = pVideoModeInformation;
  367. do
  368. {
  369. if (pVideoTemp->Length != 0)
  370. {
  371. if (cOutputModes == 0)
  372. {
  373. break;
  374. }
  375. //
  376. // Zero the entire structure to start off with.
  377. //
  378. memset(pdm, 0, sizeof(DEVMODEW));
  379. //
  380. // Set the name of the device to the name of the DLL.
  381. //
  382. memcpy(pdm->dmDeviceName, DLL_NAME, sizeof(DLL_NAME));
  383. pdm->dmSpecVersion = DM_SPECVERSION;
  384. pdm->dmDriverVersion = DM_SPECVERSION;
  385. pdm->dmSize = sizeof(DEVMODEW);
  386. pdm->dmDriverExtra = DRIVER_EXTRA_SIZE;
  387. pdm->dmBitsPerPel = pVideoTemp->NumberOfPlanes *
  388. pVideoTemp->BitsPerPlane;
  389. pdm->dmPelsWidth = pVideoTemp->VisScreenWidth;
  390. pdm->dmPelsHeight = pVideoTemp->VisScreenHeight;
  391. pdm->dmDisplayFrequency = pVideoTemp->Frequency;
  392. pdm->dmDisplayFlags = 0;
  393. pdm->dmFields = DM_BITSPERPEL |
  394. DM_PELSWIDTH |
  395. DM_PELSHEIGHT |
  396. DM_DISPLAYFREQUENCY |
  397. DM_DISPLAYFLAGS ;
  398. //
  399. // Go to the next DEVMODE entry in the buffer.
  400. //
  401. cOutputModes--;
  402. pdm = (LPDEVMODEW) ( ((ULONG_PTR)pdm) + sizeof(DEVMODEW)
  403. + DRIVER_EXTRA_SIZE);
  404. cbOutputSize += (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
  405. }
  406. pVideoTemp = (PVIDEO_MODE_INFORMATION)
  407. (((PUCHAR)pVideoTemp) + cbModeSize);
  408. } while (--cModes);
  409. }
  410. EngFreeMem(pVideoModeInformation);
  411. return cbOutputSize;
  412. }
  413. VOID DrvSynchronize(
  414. IN DHPDEV dhpdev,
  415. IN RECTL *prcl)
  416. {
  417. }