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.

551 lines
18 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: screen.c
  3. *
  4. * Initializes the GDIINFO and DEVINFO structures for DrvEnablePDEV.
  5. *
  6. * Copyright (c) 1992 Microsoft Corporation
  7. \**************************************************************************/
  8. #include "driver.h"
  9. #define SYSTM_LOGFONT {16,7,0,0,700,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS, \
  10. CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,VARIABLE_PITCH | \
  11. FF_DONTCARE,L"System"}
  12. #define HELVE_LOGFONT {12,9,0,0,400,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS, \
  13. CLIP_STROKE_PRECIS,PROOF_QUALITY,VARIABLE_PITCH | \
  14. FF_DONTCARE,L"MS Sans Serif"}
  15. #define COURI_LOGFONT {12,9,0,0,400,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS, \
  16. CLIP_STROKE_PRECIS,PROOF_QUALITY,FIXED_PITCH | \
  17. FF_DONTCARE, L"Courier"}
  18. // This is the basic devinfo for a default driver. This is used as a base and customized based
  19. // on information passed back from the miniport driver.
  20. const DEVINFO gDevInfoFrameBuffer = {
  21. (GCAPS_OPAQUERECT | GCAPS_MONO_DITHER), /* Graphics capabilities */
  22. // Should also implement GCAPS_HORIZSTRIKE so that the underlines
  23. // aren't drawn using DrvBitBlt
  24. SYSTM_LOGFONT, // Default font description
  25. HELVE_LOGFONT, // ANSI variable font description
  26. COURI_LOGFONT, // ANSI fixed font description
  27. 0, // Count of device fonts
  28. BMF_16BPP, // Preferred DIB format
  29. 8, // Width of dither
  30. 8, // Height of dither
  31. 0 // Default palette to use for this device
  32. };
  33. /******************************Public*Routine******************************\
  34. * bInitSURF
  35. *
  36. * Enables the surface. Maps the frame buffer into memory.
  37. *
  38. \**************************************************************************/
  39. BOOL bInitSURF(PPDEV ppdev, BOOL bFirst)
  40. {
  41. VIDEO_MEMORY VideoMemory;
  42. VIDEO_MEMORY_INFORMATION VideoMemoryInfo;
  43. DWORD ReturnedDataLength;
  44. // Set the mode.
  45. if (EngDeviceIoControl(ppdev->hDriver,
  46. IOCTL_VIDEO_SET_CURRENT_MODE,
  47. (LPVOID) &ppdev->ulMode, // input buffer
  48. sizeof(DWORD),
  49. NULL,
  50. 0,
  51. &ReturnedDataLength))
  52. {
  53. DISPDBG((0, "vga64k.dll: Failed SET_CURRENT_MODE\n"));
  54. return(FALSE);
  55. }
  56. if (bFirst)
  57. {
  58. // Get the linear memory address range.
  59. VideoMemory.RequestedVirtualAddress = NULL;
  60. if (EngDeviceIoControl(ppdev->hDriver,
  61. IOCTL_VIDEO_MAP_VIDEO_MEMORY,
  62. (PVOID) &VideoMemory, // input buffer
  63. sizeof (VIDEO_MEMORY),
  64. (PVOID) &VideoMemoryInfo, // output buffer
  65. sizeof (VideoMemoryInfo),
  66. &ReturnedDataLength))
  67. {
  68. DISPDBG((0, "vga64k.dll: Failed MAP_VIDEO_MEMORY\n"));
  69. return(FALSE);
  70. }
  71. }
  72. // Record the Frame Buffer Linear Address.
  73. if (bFirst)
  74. {
  75. ppdev->pjScreen = (PBYTE) VideoMemoryInfo.FrameBufferBase;
  76. }
  77. // Set the various write mode values, so we don't have to read before write
  78. // later on
  79. vSetWriteModes(&ppdev->ulrm0_wmX);
  80. // Initialize the VGA registers to their default states, so that we
  81. // can be sure of drawing properly even when the miniport didn't
  82. // happen to set them the way we like them:
  83. vInitRegs(ppdev);
  84. // Since we just did a mode-set, we'll be in non-planar mode. And make
  85. // sure we reset the bank manager (otherwise, after a switch from full-
  86. // screen, we may think we've got one bank mapped in, when in fact there's
  87. // a different one mapped in, and bad things would happen...).
  88. ppdev->flBank &= ~BANK_PLANAR;
  89. ppdev->rcl1WindowClip.bottom = -1;
  90. ppdev->rcl2WindowClip[0].bottom = -1;
  91. ppdev->rcl2WindowClip[1].bottom = -1;
  92. ppdev->rcl1PlanarClip.bottom = -1;
  93. ppdev->rcl2PlanarClip[0].bottom = -1;
  94. ppdev->rcl2PlanarClip[1].bottom = -1;
  95. return(TRUE);
  96. }
  97. /******************************Public*Routine******************************\
  98. * vDisableSURF
  99. *
  100. * Disable the surface. Un-Maps the frame in memory.
  101. *
  102. \**************************************************************************/
  103. VOID vDisableSURF(PPDEV ppdev)
  104. {
  105. DWORD returnedDataLength;
  106. VIDEO_MEMORY videoMemory;
  107. videoMemory.RequestedVirtualAddress = (PVOID) ppdev->pjScreen;
  108. if (EngDeviceIoControl(ppdev->hDriver,
  109. IOCTL_VIDEO_UNMAP_VIDEO_MEMORY,
  110. (LPVOID) &videoMemory,
  111. sizeof(VIDEO_MEMORY),
  112. NULL,
  113. 0,
  114. &returnedDataLength))
  115. {
  116. RIP("Failed UNMAP_VIDEO_MEMORY");
  117. }
  118. }
  119. /******************************Public*Routine******************************\
  120. * bInitPDEV
  121. *
  122. * Determine the mode we should be in based on the DEVMODE passed in.
  123. * Query mini-port to get information needed to fill in the DevInfo and the
  124. * GdiInfo .
  125. *
  126. \**************************************************************************/
  127. BOOL bInitPDEV(
  128. PPDEV ppdev,
  129. DEVMODEW *pDevMode)
  130. {
  131. GDIINFO *pGdiInfo;
  132. ULONG cModes;
  133. PVIDEO_MODE_INFORMATION pVideoBuffer, pVideoModeSelected, pVideoTemp;
  134. VIDEO_COLOR_CAPABILITIES colorCapabilities;
  135. ULONG ulTemp;
  136. BOOL bSelectDefault;
  137. ULONG cbModeSize;
  138. BANK_POSITION BankPosition;
  139. ULONG ulReturn;
  140. pGdiInfo = ppdev->pGdiInfo;
  141. //
  142. // calls the miniport to get mode information.
  143. //
  144. cModes = getAvailableModes(ppdev->hDriver, &pVideoBuffer, &cbModeSize);
  145. if (cModes == 0)
  146. {
  147. DISPDBG((0, "vga64k.dll: no available modes\n"));
  148. return(FALSE);
  149. }
  150. //
  151. // Determine if we are looking for a default mode.
  152. //
  153. if ( ((pDevMode->dmPelsWidth) ||
  154. (pDevMode->dmPelsHeight) ||
  155. (pDevMode->dmBitsPerPel) ||
  156. (pDevMode->dmDisplayFlags) ||
  157. (pDevMode->dmDisplayFrequency)) == 0)
  158. {
  159. bSelectDefault = TRUE;
  160. }
  161. else
  162. {
  163. bSelectDefault = FALSE;
  164. }
  165. //
  166. // Now see if the requested mode has a match in that table.
  167. //
  168. pVideoModeSelected = NULL;
  169. pVideoTemp = pVideoBuffer;
  170. while (cModes--)
  171. {
  172. if (pVideoTemp->Length != 0)
  173. {
  174. if (bSelectDefault ||
  175. ((pVideoTemp->VisScreenWidth == pDevMode->dmPelsWidth) &&
  176. (pVideoTemp->VisScreenHeight == pDevMode->dmPelsHeight) &&
  177. (pVideoTemp->BitsPerPlane *
  178. pVideoTemp->NumberOfPlanes == pDevMode->dmBitsPerPel) &&
  179. (pVideoTemp->Frequency == pDevMode->dmDisplayFrequency)))
  180. {
  181. pVideoModeSelected = pVideoTemp;
  182. DISPDBG((2, "vga64k: Found a match\n")) ;
  183. break;
  184. }
  185. }
  186. pVideoTemp = (PVIDEO_MODE_INFORMATION)
  187. (((PUCHAR)pVideoTemp) + cbModeSize);
  188. }
  189. //
  190. // If no mode has been found, return an error
  191. //
  192. if (pVideoModeSelected == NULL)
  193. {
  194. DISPDBG((0, "vga64k.dll: no valid modes\n"));
  195. EngFreeMem(pVideoBuffer);
  196. return(FALSE);
  197. }
  198. //
  199. // Fill in the GDIINFO data structure with the information returned from
  200. // the kernel driver.
  201. //
  202. ppdev->ulMode = pVideoModeSelected->ModeIndex;
  203. ppdev->cxScreen = pVideoModeSelected->VisScreenWidth;
  204. ppdev->cyScreen = pVideoModeSelected->VisScreenHeight;
  205. ppdev->ulBitCount = pVideoModeSelected->BitsPerPlane *
  206. pVideoModeSelected->NumberOfPlanes;
  207. ppdev->lDeltaScreen = pVideoModeSelected->ScreenStride;
  208. ppdev->flRed = pVideoModeSelected->RedMask;
  209. ppdev->flGreen = pVideoModeSelected->GreenMask;
  210. ppdev->flBlue = pVideoModeSelected->BlueMask;
  211. if (!(pVideoModeSelected->AttributeFlags & VIDEO_MODE_NO_OFF_SCREEN))
  212. {
  213. ppdev->fl |= DRIVER_USE_OFFSCREEN;
  214. }
  215. pGdiInfo->ulVersion = GDI_DRIVER_VERSION;
  216. pGdiInfo->ulTechnology = DT_RASDISPLAY;
  217. pGdiInfo->ulHorzSize = pVideoModeSelected->XMillimeter;
  218. pGdiInfo->ulVertSize = pVideoModeSelected->YMillimeter;
  219. pGdiInfo->ulHorzRes = ppdev->cxScreen;
  220. pGdiInfo->ulVertRes = ppdev->cyScreen;
  221. pGdiInfo->ulPanningHorzRes = ppdev->cxScreen;
  222. pGdiInfo->ulPanningVertRes = ppdev->cyScreen;
  223. pGdiInfo->cBitsPixel = pVideoModeSelected->BitsPerPlane;
  224. pGdiInfo->cPlanes = pVideoModeSelected->NumberOfPlanes;
  225. pGdiInfo->ulVRefresh = pVideoModeSelected->Frequency;
  226. pGdiInfo->ulBltAlignment = 1; // We're not accelerated, and we don't
  227. // care about window alignment
  228. pGdiInfo->ulLogPixelsX = pDevMode->dmLogPixels;
  229. pGdiInfo->ulLogPixelsY = pDevMode->dmLogPixels;
  230. pGdiInfo->flTextCaps = TC_RA_ABLE | TC_SCROLLBLT;
  231. pGdiInfo->flRaster = 0; // DDI reservers flRaster
  232. pGdiInfo->ulDACRed = pVideoModeSelected->NumberRedBits;
  233. pGdiInfo->ulDACGreen = pVideoModeSelected->NumberGreenBits;
  234. pGdiInfo->ulDACBlue = pVideoModeSelected->NumberBlueBits;
  235. pGdiInfo->ulAspectX = 0x24; // One-to-one aspect ratio
  236. pGdiInfo->ulAspectY = 0x24;
  237. pGdiInfo->ulAspectXY = 0x33;
  238. pGdiInfo->xStyleStep = 1; // A style unit is 3 pels
  239. pGdiInfo->yStyleStep = 1;
  240. pGdiInfo->denStyleStep = 3;
  241. pGdiInfo->ptlPhysOffset.x = 0;
  242. pGdiInfo->ptlPhysOffset.y = 0;
  243. pGdiInfo->szlPhysSize.cx = 0;
  244. pGdiInfo->szlPhysSize.cy = 0;
  245. // RGB and CMY color info.
  246. // try to get it from the miniport.
  247. // if the miniport doesn ot support this feature, use defaults.
  248. if (EngDeviceIoControl(ppdev->hDriver,
  249. IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES,
  250. NULL,
  251. 0,
  252. &colorCapabilities,
  253. sizeof(VIDEO_COLOR_CAPABILITIES),
  254. &ulTemp))
  255. {
  256. DISPDBG((1, "vga64k DISP getcolorCapabilities failed \n"));
  257. pGdiInfo->ciDevice.Red.x = 6700;
  258. pGdiInfo->ciDevice.Red.y = 3300;
  259. pGdiInfo->ciDevice.Red.Y = 0;
  260. pGdiInfo->ciDevice.Green.x = 2100;
  261. pGdiInfo->ciDevice.Green.y = 7100;
  262. pGdiInfo->ciDevice.Green.Y = 0;
  263. pGdiInfo->ciDevice.Blue.x = 1400;
  264. pGdiInfo->ciDevice.Blue.y = 800;
  265. pGdiInfo->ciDevice.Blue.Y = 0;
  266. pGdiInfo->ciDevice.AlignmentWhite.x = 3127;
  267. pGdiInfo->ciDevice.AlignmentWhite.y = 3290;
  268. pGdiInfo->ciDevice.AlignmentWhite.Y = 0;
  269. pGdiInfo->ciDevice.RedGamma = 20000;
  270. pGdiInfo->ciDevice.GreenGamma = 20000;
  271. pGdiInfo->ciDevice.BlueGamma = 20000;
  272. }
  273. else
  274. {
  275. pGdiInfo->ciDevice.Red.x = colorCapabilities.RedChromaticity_x;
  276. pGdiInfo->ciDevice.Red.y = colorCapabilities.RedChromaticity_y;
  277. pGdiInfo->ciDevice.Red.Y = 0;
  278. pGdiInfo->ciDevice.Green.x = colorCapabilities.GreenChromaticity_x;
  279. pGdiInfo->ciDevice.Green.y = colorCapabilities.GreenChromaticity_y;
  280. pGdiInfo->ciDevice.Green.Y = 0;
  281. pGdiInfo->ciDevice.Blue.x = colorCapabilities.BlueChromaticity_x;
  282. pGdiInfo->ciDevice.Blue.y = colorCapabilities.BlueChromaticity_y;
  283. pGdiInfo->ciDevice.Blue.Y = 0;
  284. pGdiInfo->ciDevice.AlignmentWhite.x = colorCapabilities.WhiteChromaticity_x;
  285. pGdiInfo->ciDevice.AlignmentWhite.y = colorCapabilities.WhiteChromaticity_y;
  286. pGdiInfo->ciDevice.AlignmentWhite.Y = colorCapabilities.WhiteChromaticity_Y;
  287. // if we have a color device store the three color gamma values,
  288. // otherwise store the unique gamma value in all three.
  289. if (colorCapabilities.AttributeFlags & VIDEO_DEVICE_COLOR)
  290. {
  291. pGdiInfo->ciDevice.RedGamma = colorCapabilities.RedGamma;
  292. pGdiInfo->ciDevice.GreenGamma = colorCapabilities.GreenGamma;
  293. pGdiInfo->ciDevice.BlueGamma = colorCapabilities.BlueGamma;
  294. }
  295. else
  296. {
  297. pGdiInfo->ciDevice.RedGamma = colorCapabilities.WhiteGamma;
  298. pGdiInfo->ciDevice.GreenGamma = colorCapabilities.WhiteGamma;
  299. pGdiInfo->ciDevice.BlueGamma = colorCapabilities.WhiteGamma;
  300. }
  301. };
  302. pGdiInfo->ciDevice.Cyan.x = 0;
  303. pGdiInfo->ciDevice.Cyan.y = 0;
  304. pGdiInfo->ciDevice.Cyan.Y = 0;
  305. pGdiInfo->ciDevice.Magenta.x = 0;
  306. pGdiInfo->ciDevice.Magenta.y = 0;
  307. pGdiInfo->ciDevice.Magenta.Y = 0;
  308. pGdiInfo->ciDevice.Yellow.x = 0;
  309. pGdiInfo->ciDevice.Yellow.y = 0;
  310. pGdiInfo->ciDevice.Yellow.Y = 0;
  311. // No dye correction for raster displays.
  312. pGdiInfo->ciDevice.MagentaInCyanDye = 0;
  313. pGdiInfo->ciDevice.YellowInCyanDye = 0;
  314. pGdiInfo->ciDevice.CyanInMagentaDye = 0;
  315. pGdiInfo->ciDevice.YellowInMagentaDye = 0;
  316. pGdiInfo->ciDevice.CyanInYellowDye = 0;
  317. pGdiInfo->ciDevice.MagentaInYellowDye = 0;
  318. // Fill in the rest of the devinfo and GdiInfo structures.
  319. pGdiInfo->ulNumColors = (ULONG)-1;
  320. pGdiInfo->ulNumPalReg = 0;
  321. pGdiInfo->ulDevicePelsDPI = 0; // For printers only
  322. pGdiInfo->ulPrimaryOrder = PRIMARY_ORDER_CBA;
  323. pGdiInfo->ulHTPatternSize = HT_PATSIZE_4x4_M;
  324. pGdiInfo->ulHTOutputFormat = HT_FORMAT_16BPP;
  325. pGdiInfo->flHTFlags = HT_FLAG_ADDITIVE_PRIMS;
  326. // Fill in the basic devinfo structure
  327. *(ppdev->pDevInfo) = gDevInfoFrameBuffer;
  328. EngFreeMem(pVideoBuffer);
  329. //
  330. // Check to see if the miniport supports
  331. // IOCTL_VIDEO_SET_BANK_POSITION.
  332. //
  333. BankPosition.ReadBankPosition = 0;
  334. BankPosition.WriteBankPosition = 0;
  335. if (EngDeviceIoControl(ppdev->hDriver,
  336. IOCTL_VIDEO_SET_BANK_POSITION,
  337. &BankPosition,
  338. sizeof(BANK_POSITION),
  339. NULL,
  340. 0,
  341. &ulReturn) == NO_ERROR)
  342. {
  343. ppdev->BankIoctlSupported = TRUE;
  344. } else {
  345. ppdev->BankIoctlSupported = FALSE;
  346. }
  347. return(TRUE);
  348. }
  349. /******************************Public*Routine******************************\
  350. * getAvailableModes
  351. *
  352. * Calls the miniport to get the list of modes supported by the kernel driver,
  353. * and returns the list of modes supported by the diplay driver among those
  354. *
  355. * returns the number of entries in the videomode buffer.
  356. * 0 means no modes are supported by the miniport or that an error occured.
  357. *
  358. * NOTE: the buffer must be freed up by the caller.
  359. *
  360. \**************************************************************************/
  361. DWORD getAvailableModes(
  362. HANDLE hDriver,
  363. PVIDEO_MODE_INFORMATION *modeInformation,
  364. DWORD *cbModeSize)
  365. {
  366. ULONG ulTemp;
  367. VIDEO_NUM_MODES modes;
  368. PVIDEO_MODE_INFORMATION pVideoTemp;
  369. //
  370. // Get the number of modes supported by the mini-port
  371. //
  372. if (EngDeviceIoControl(hDriver,
  373. IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES,
  374. NULL,
  375. 0,
  376. &modes,
  377. sizeof(VIDEO_NUM_MODES),
  378. &ulTemp))
  379. {
  380. DISPDBG((0, "vga64k getAvailableModes failed VIDEO_QUERY_NUM_AVAIL_MODES\n"));
  381. return(0);
  382. }
  383. *cbModeSize = modes.ModeInformationLength;
  384. //
  385. // Allocate the buffer for the mini-port to write the modes in.
  386. //
  387. *modeInformation = (PVIDEO_MODE_INFORMATION)
  388. EngAllocMem(FL_ZERO_MEMORY,
  389. modes.NumModes *
  390. modes.ModeInformationLength, ALLOC_TAG);
  391. if (*modeInformation == (PVIDEO_MODE_INFORMATION) NULL)
  392. {
  393. DISPDBG((0, "vga64k getAvailableModes failed EngAllocMem\n"));
  394. return 0;
  395. }
  396. //
  397. // Ask the mini-port to fill in the available modes.
  398. //
  399. if (EngDeviceIoControl(hDriver,
  400. IOCTL_VIDEO_QUERY_AVAIL_MODES,
  401. NULL,
  402. 0,
  403. *modeInformation,
  404. modes.NumModes * modes.ModeInformationLength,
  405. &ulTemp))
  406. {
  407. DISPDBG((0, "vga64k getAvailableModes failed VIDEO_QUERY_AVAIL_MODES\n"));
  408. EngFreeMem(*modeInformation);
  409. *modeInformation = (PVIDEO_MODE_INFORMATION) NULL;
  410. return(0);
  411. }
  412. //
  413. // Now see which of these modes are supported by the display driver.
  414. // As an internal mechanism, set the length to 0 for the modes we
  415. // DO NOT support.
  416. //
  417. ulTemp = modes.NumModes;
  418. pVideoTemp = *modeInformation;
  419. //
  420. // Mode is rejected if it is not one plane, or not graphics, or is not
  421. // one of 16 bits per pel (that is all the vga64k currently supports)
  422. //
  423. while (ulTemp--)
  424. {
  425. if ((pVideoTemp->NumberOfPlanes != 1 ) ||
  426. !(pVideoTemp->AttributeFlags & VIDEO_MODE_GRAPHICS) ||
  427. (pVideoTemp->AttributeFlags & VIDEO_MODE_LINEAR) ||
  428. (pVideoTemp->BitsPerPlane != 16) ||
  429. //
  430. // This next condition says that either the mode doesn't
  431. // require broken rasters, or else the ScreenStride has
  432. // already been set to some funky value. Some miniports
  433. // choose strides that have broken rasters, but they're
  434. // limited to unused areas of video memory. I only know of
  435. // 1928, so we'll special case that.
  436. //
  437. (BROKEN_RASTERS(pVideoTemp->ScreenStride,
  438. pVideoTemp->VisScreenHeight) &&
  439. (pVideoTemp->ScreenStride != 1928)))
  440. {
  441. pVideoTemp->Length = 0;
  442. }
  443. pVideoTemp = (PVIDEO_MODE_INFORMATION)
  444. (((PUCHAR)pVideoTemp) + modes.ModeInformationLength);
  445. }
  446. return modes.NumModes;
  447. }