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.

1050 lines
33 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: screen.c
  3. *
  4. * This file contains the virtual driver that is used for user-mode GDI+
  5. * painting on the desktop screen.
  6. *
  7. * Copyright (c) 1998-1999 Microsoft Corporation
  8. *
  9. * Created: 29-Apr-1998
  10. * Author: J. Andrew Goossen [andrewgo]
  11. *
  12. \**************************************************************************/
  13. // @@@ Re-visit headers:
  14. #define NO_DDRAWINT_NO_COM
  15. // @@@ Temporary:
  16. #include <stddef.h>
  17. #include <stdarg.h>
  18. #include <limits.h>
  19. #include <windef.h>
  20. #include <winerror.h>
  21. #include <ddraw.h>
  22. #include <wingdi.h>
  23. #include <winddi.h>
  24. #include <math.h>
  25. VOID vFreeMem(VOID*);
  26. VOID* pAllocMem(ULONG, ULONG);
  27. #define RIP(x) OutputDebugString(x)
  28. #define WARNING(x) OutputDebugString(x)
  29. #define ASSERTGDI(x, y) if (!(x)) OutputDebugString(y)
  30. #define PALLOCMEM(size, tag) pAllocMem(size, tag);
  31. #define VFREEMEM(p) vFreeMem(p);
  32. ULONG
  33. DbgPrint(
  34. PCH Format,
  35. ...
  36. );
  37. typedef struct _GPDEV
  38. {
  39. HDEV hdev;
  40. HWND hwnd; // @@@ Hwnd this HDEV was created from
  41. HSURF hsurfScreen; // Handle to the screen surface
  42. SIZEL sizlScreen; // Size of the screen
  43. ULONG iBitmapFormat; // The color depth
  44. ULONG flRed; // The RGB color masks
  45. ULONG flGreen;
  46. ULONG flBlue;
  47. HPALETTE hpalDefault; // The GDI palette handle
  48. PALETTEENTRY* pPal; // The palette table if palette managed
  49. LPDIRECTDRAW lpDD; // DirectDraw object
  50. LPDIRECTDRAWSURFACE lpDDPrimary; // DirectDraw primary surface
  51. LPDIRECTDRAWSURFACE lpDDBuffer; // DirectDraw buffer surface
  52. LPDIRECTDRAWCLIPPER lpDDClipper; // Primary surface DirectDraw clipper
  53. SURFOBJ* psoBuffer; // GDI surface wrapped around buffer
  54. } GDEV;
  55. /******************************Public*Structure****************************\
  56. * GDIINFO ggdiGdiPlusDefault
  57. *
  58. * This contains the default GDIINFO fields that are passed back to GDI
  59. * during DrvEnablePDEV.
  60. *
  61. * NOTE: This structure defaults to values for an 8bpp palette device.
  62. * Some fields are overwritten for different colour depths.
  63. \**************************************************************************/
  64. GDIINFO ggdiGdiPlusDefault = {
  65. GDI_DRIVER_VERSION,
  66. DT_RASDISPLAY, // ulTechnology
  67. 320, // ulHorzSize
  68. 240, // ulVertSize
  69. 0, // ulHorzRes (filled in later)
  70. 0, // ulVertRes (filled in later)
  71. 0, // cBitsPixel (filled in later)
  72. 0, // cPlanes (filled in later)
  73. 20, // ulNumColors (palette managed)
  74. 0, // flRaster (DDI reserved field)
  75. 0, // ulLogPixelsX (filled in later)
  76. 0, // ulLogPixelsY (filled in later)
  77. TC_RA_ABLE, // flTextCaps -- If we had wanted console windows
  78. // to scroll by repainting the entire window,
  79. // instead of doing a screen-to-screen blt, we
  80. // would have set TC_SCROLLBLT (yes, the flag is
  81. // bass-ackwards).
  82. 8, // ulDACRed (possibly overwritten later)
  83. 8, // ulDACGreen (possibly overwritten later)
  84. 8, // ulDACBlue (possibly overwritten later)
  85. 0x0024, // ulAspectX
  86. 0x0024, // ulAspectY
  87. 0x0033, // ulAspectXY (one-to-one aspect ratio)
  88. 1, // xStyleStep
  89. 1, // yStyleSte;
  90. 3, // denStyleStep -- Styles have a one-to-one aspect
  91. // ratio, and every 'dot' is 3 pixels long
  92. { 0, 0 }, // ptlPhysOffset
  93. { 0, 0 }, // szlPhysSize
  94. 256, // ulNumPalReg
  95. // These fields are for halftone initialization. The actual values are
  96. // a bit magic, but seem to work well on our display.
  97. { // ciDevice
  98. { 6700, 3300, 0 }, // Red
  99. { 2100, 7100, 0 }, // Green
  100. { 1400, 800, 0 }, // Blue
  101. { 1750, 3950, 0 }, // Cyan
  102. { 4050, 2050, 0 }, // Magenta
  103. { 4400, 5200, 0 }, // Yellow
  104. { 3127, 3290, 0 }, // AlignmentWhite
  105. 20000, // RedGamma
  106. 20000, // GreenGamma
  107. 20000, // BlueGamma
  108. 0, 0, 0, 0, 0, 0 // No dye correction for raster displays
  109. },
  110. 0, // ulDevicePelsDPI (for printers only)
  111. PRIMARY_ORDER_CBA, // ulPrimaryOrder
  112. HT_PATSIZE_4x4_M, // ulHTPatternSize
  113. HT_FORMAT_8BPP, // ulHTOutputFormat
  114. HT_FLAG_ADDITIVE_PRIMS, // flHTFlags
  115. 0, // ulVRefresh
  116. 0, // ulPanningHorzRes
  117. 0, // ulPanningVertRes
  118. 0, // ulBltAlignment
  119. };
  120. /******************************Public*Structure****************************\
  121. * DEVINFO gdevinfoGdiPlusDefault
  122. *
  123. * This contains the default DEVINFO fields that are passed back to GDI
  124. * during DrvEnablePDEV.
  125. *
  126. * NOTE: This structure defaults to values for an 8bpp palette device.
  127. * Some fields are overwritten for different colour depths.
  128. \**************************************************************************/
  129. #define SYSTM_LOGFONT {16,7,0,0,700,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,\
  130. CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,\
  131. VARIABLE_PITCH | FF_DONTCARE,L"System"}
  132. #define HELVE_LOGFONT {12,9,0,0,400,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,\
  133. CLIP_STROKE_PRECIS,PROOF_QUALITY,\
  134. VARIABLE_PITCH | FF_DONTCARE,L"MS Sans Serif"}
  135. #define COURI_LOGFONT {12,9,0,0,400,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,\
  136. CLIP_STROKE_PRECIS,PROOF_QUALITY,\
  137. FIXED_PITCH | FF_DONTCARE, L"Courier"}
  138. DEVINFO gdevinfoGdiPlusDefault = {
  139. (GCAPS_OPAQUERECT |
  140. GCAPS_PALMANAGED |
  141. GCAPS_MONO_DITHER |
  142. GCAPS_COLOR_DITHER),
  143. // flGraphicsFlags
  144. SYSTM_LOGFONT, // lfDefaultFont
  145. HELVE_LOGFONT, // lfAnsiVarFont
  146. COURI_LOGFONT, // lfAnsiFixFont
  147. 0, // cFonts
  148. BMF_8BPP, // iDitherFormat
  149. 8, // cxDither
  150. 8, // cyDither
  151. 0 // hpalDefault (filled in later)
  152. };
  153. /******************************Public*Routine******************************\
  154. * VOID vGpsUninitializeDirectDraw
  155. *
  156. \**************************************************************************/
  157. VOID vGpsUninitializeDirectDraw(
  158. GDEV* pgdev)
  159. {
  160. HSURF hsurf;
  161. if (pgdev->psoBuffer != NULL)
  162. {
  163. hsurf = pgdev->psoBuffer->hsurf;
  164. EngUnlockSurface(pgdev->psoBuffer);
  165. EngDeleteSurface(hsurf);
  166. }
  167. if (pgdev->lpDDClipper != NULL)
  168. {
  169. pgdev->lpDDClipper->lpVtbl->Release(pgdev->lpDDClipper);
  170. pgdev->lpDDClipper = NULL;
  171. }
  172. if (pgdev->lpDDBuffer != NULL)
  173. {
  174. pgdev->lpDDBuffer->lpVtbl->Release(pgdev->lpDDBuffer);
  175. pgdev->lpDDBuffer = NULL;
  176. }
  177. if (pgdev->lpDDPrimary != NULL)
  178. {
  179. pgdev->lpDDPrimary->lpVtbl->Release(pgdev->lpDDPrimary);
  180. pgdev->lpDDPrimary = NULL;
  181. }
  182. if (pgdev->lpDD != NULL)
  183. {
  184. pgdev->lpDD->lpVtbl->Release(pgdev->lpDD);
  185. pgdev->lpDD = NULL;
  186. }
  187. }
  188. /******************************Public*Routine******************************\
  189. * BOOL bGpsInitializeDirectDraw
  190. *
  191. \**************************************************************************/
  192. BOOL bGpsInitializeDirectDraw(
  193. GDEV* pgdev,
  194. HWND hwnd,
  195. ULONG* pScreenWidth,
  196. ULONG* pScreenHeight,
  197. ULONG* pBitsPerPlane,
  198. ULONG* pRedMask,
  199. ULONG* pGreenMask,
  200. ULONG* pBlueMask)
  201. {
  202. LPDIRECTDRAW lpDD;
  203. DDSURFACEDESC DDMode;
  204. DDSURFACEDESC ddsd;
  205. LPDIRECTDRAWSURFACE lpDDPrimary;
  206. LPDIRECTDRAWSURFACE lpDDBuffer;
  207. LPDIRECTDRAWCLIPPER lpDDClipper;
  208. SURFOBJ* psoBuffer;
  209. SIZEL sizl;
  210. ULONG iFormat;
  211. HSURF hsurf;
  212. DDMode.dwSize = sizeof(DDMode);
  213. if (DirectDrawCreate(NULL, &lpDD, NULL) == DD_OK)
  214. {
  215. if ((lpDD->lpVtbl->SetCooperativeLevel(lpDD, hwnd, DDSCL_NORMAL) == DD_OK) &&
  216. (lpDD->lpVtbl->GetDisplayMode(lpDD, &DDMode) == DD_OK))
  217. {
  218. *pScreenWidth = DDMode.dwWidth;
  219. *pScreenHeight = DDMode.dwHeight;
  220. *pBitsPerPlane = DDMode.ddpfPixelFormat.dwRGBBitCount;
  221. *pRedMask = DDMode.ddpfPixelFormat.dwRBitMask;
  222. *pGreenMask = DDMode.ddpfPixelFormat.dwGBitMask;
  223. *pBlueMask = DDMode.ddpfPixelFormat.dwBBitMask;
  224. // Create a primary surface:
  225. RtlZeroMemory(&ddsd, sizeof(ddsd));
  226. ddsd.dwSize = sizeof(ddsd);
  227. ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
  228. if (lpDD->lpVtbl->CreateSurface(lpDD, &ddsd, &lpDDPrimary, NULL) == DD_OK)
  229. {
  230. if (lpDD->lpVtbl->CreateClipper(lpDD, 0, &lpDDClipper, NULL) == DD_OK)
  231. {
  232. if ((lpDDClipper->lpVtbl->SetHWnd(lpDDClipper, 0, hwnd) == DD_OK) &&
  233. (lpDDPrimary->lpVtbl->SetClipper(lpDDPrimary, lpDDClipper) == DD_OK))
  234. {
  235. // Create a temporary DirectDraw surface that's used
  236. // as a staging area.
  237. //
  238. // @@@ This darn well better be temporary!
  239. RtlZeroMemory(&ddsd, sizeof(ddsd));
  240. ddsd.dwSize = sizeof(ddsd);
  241. ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
  242. ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;
  243. ddsd.dwWidth = DDMode.dwWidth;
  244. ddsd.dwHeight = DDMode.dwHeight;
  245. if (lpDD->lpVtbl->CreateSurface(lpDD, &ddsd, &lpDDBuffer, NULL) == DD_OK)
  246. {
  247. if (lpDDBuffer->lpVtbl->Lock(lpDDBuffer, NULL, &ddsd, DDLOCK_WAIT, NULL)
  248. == DD_OK)
  249. {
  250. // Create a GDI surface to wrap around the temporary
  251. // buffer:
  252. sizl.cx = ddsd.dwWidth;
  253. sizl.cy = ddsd.dwHeight;
  254. switch (DDMode.ddpfPixelFormat.dwRGBBitCount)
  255. {
  256. case 4: iFormat = BMF_4BPP; break;
  257. case 8: iFormat = BMF_8BPP; break;
  258. case 16: iFormat = BMF_16BPP; break;
  259. case 24: iFormat = BMF_24BPP; break;
  260. case 32: iFormat = BMF_32BPP; break;
  261. default: RIP("Unexpected dwRGBBitCount");
  262. }
  263. // !!! @@@ Why did I have to specify BMF_TOPDOWN?
  264. hsurf = (HSURF) EngCreateBitmap(sizl,
  265. ddsd.lPitch,
  266. iFormat,
  267. BMF_TOPDOWN,
  268. ddsd.lpSurface);
  269. lpDDBuffer->lpVtbl->Unlock(lpDDBuffer, ddsd.lpSurface);
  270. if (hsurf != NULL)
  271. {
  272. psoBuffer = EngLockSurface(hsurf);
  273. pgdev->hwnd = hwnd;
  274. pgdev->lpDD = lpDD;
  275. pgdev->lpDDPrimary = lpDDPrimary;
  276. pgdev->lpDDBuffer = lpDDBuffer;
  277. pgdev->psoBuffer = psoBuffer;
  278. return(TRUE);
  279. }
  280. }
  281. lpDDBuffer->lpVtbl->Release(lpDDBuffer);
  282. }
  283. }
  284. lpDDClipper->lpVtbl->Release(lpDDClipper);
  285. }
  286. lpDDPrimary->lpVtbl->Release(lpDDPrimary);
  287. }
  288. }
  289. lpDD->lpVtbl->Release(lpDD);
  290. }
  291. WARNING("Failed bGpsInitializeDirectDraw");
  292. return(FALSE);
  293. }
  294. /******************************Public*Routine******************************\
  295. * BOOL bGpsInitializeModeFields
  296. *
  297. * Fill in the GDIINFO and DEVINFO structures required by the engine.
  298. *
  299. \**************************************************************************/
  300. BOOL bGpsInitializeModeFields(
  301. GDEV* pgdev,
  302. ULONG* pScreenWidth,
  303. ULONG* pScreenHeight,
  304. ULONG* pBitsPerPlane,
  305. ULONG* pRedMask,
  306. ULONG* pGreenMask,
  307. ULONG* pBlueMask,
  308. GDIINFO* pgdi,
  309. DEVINFO* pdi)
  310. {
  311. ULONG BitsPerPlane;
  312. ULONG RedMask;
  313. ULONG GreenMask;
  314. ULONG BlueMask;
  315. ULONG ScreenWidth;
  316. ULONG ScreenHeight;
  317. RedMask = *pRedMask;
  318. GreenMask = *pGreenMask;
  319. BlueMask = *pBlueMask;
  320. BitsPerPlane = *pBitsPerPlane;
  321. ScreenWidth = *pScreenWidth;
  322. ScreenHeight = *pScreenHeight;
  323. pgdev->sizlScreen.cx = ScreenWidth;
  324. pgdev->sizlScreen.cy = ScreenHeight;
  325. // Fill in the GDIINFO data structure with the default 8bpp values:
  326. *pgdi = ggdiGdiPlusDefault;
  327. // Now overwrite the defaults with the relevant information returned
  328. // from the kernel driver:
  329. pgdi->ulHorzRes = ScreenWidth;
  330. pgdi->ulVertRes = ScreenHeight;
  331. pgdi->ulPanningHorzRes = ScreenWidth;
  332. pgdi->ulPanningVertRes = ScreenHeight;
  333. pgdi->cBitsPixel = BitsPerPlane;
  334. pgdi->cPlanes = 1;
  335. pgdi->ulLogPixelsX = 120; // @@@
  336. pgdi->ulLogPixelsY = 120;
  337. // Fill in the devinfo structure with the default 8bpp values:
  338. *pdi = gdevinfoGdiPlusDefault;
  339. if (BitsPerPlane == 8)
  340. {
  341. pgdev->iBitmapFormat = BMF_8BPP;
  342. pgdi->ulDACRed = 0;
  343. pgdi->ulDACGreen = 0;
  344. pgdi->ulDACBlue = 0;
  345. }
  346. else if ((BitsPerPlane == 16) || (BitsPerPlane == 15))
  347. {
  348. pgdev->iBitmapFormat = BMF_16BPP;
  349. pgdev->flRed = RedMask;
  350. pgdev->flGreen = GreenMask;
  351. pgdev->flBlue = BlueMask;
  352. pgdi->ulNumColors = (ULONG) -1;
  353. pgdi->ulNumPalReg = 0;
  354. pgdi->ulHTOutputFormat = HT_FORMAT_16BPP;
  355. pdi->iDitherFormat = BMF_16BPP;
  356. pdi->flGraphicsCaps &= ~(GCAPS_PALMANAGED | GCAPS_COLOR_DITHER);
  357. }
  358. else if (BitsPerPlane == 24)
  359. {
  360. pgdev->iBitmapFormat = BMF_24BPP;
  361. pgdev->flRed = RedMask;
  362. pgdev->flGreen = GreenMask;
  363. pgdev->flBlue = BlueMask;
  364. pgdi->ulNumColors = (ULONG) -1;
  365. pgdi->ulNumPalReg = 0;
  366. pgdi->ulHTOutputFormat = HT_FORMAT_24BPP;
  367. pdi->iDitherFormat = BMF_24BPP;
  368. pdi->flGraphicsCaps &= ~(GCAPS_PALMANAGED | GCAPS_COLOR_DITHER);
  369. }
  370. else
  371. {
  372. ASSERTGDI(BitsPerPlane == 32,
  373. "This driver supports only 8, 16, 24 and 32bpp");
  374. pgdev->iBitmapFormat = BMF_32BPP;
  375. pgdev->flRed = RedMask;
  376. pgdev->flGreen = GreenMask;
  377. pgdev->flBlue = BlueMask;
  378. pgdi->ulNumColors = (ULONG) -1;
  379. pgdi->ulNumPalReg = 0;
  380. pgdi->ulHTOutputFormat = HT_FORMAT_32BPP;
  381. pdi->iDitherFormat = BMF_32BPP;
  382. pdi->flGraphicsCaps &= ~(GCAPS_PALMANAGED | GCAPS_COLOR_DITHER);
  383. }
  384. return(TRUE);
  385. }
  386. /******************************Public*Routine******************************\
  387. * BOOL bGpsInitializePalette
  388. *
  389. * Initializes default palette for PDEV.
  390. *
  391. \**************************************************************************/
  392. BOOL bGpsInitializePalette(
  393. GDEV* pgdev,
  394. DEVINFO* pdi)
  395. {
  396. PALETTEENTRY* ppal;
  397. PALETTEENTRY* ppalTmp;
  398. ULONG ulLoop;
  399. BYTE jRed;
  400. BYTE jGre;
  401. BYTE jBlu;
  402. HPALETTE hpal;
  403. if (pgdev->iBitmapFormat == BMF_8BPP)
  404. {
  405. // Allocate our palette:
  406. ppal = EngAllocMem(FL_ZERO_MEMORY, sizeof(PALETTEENTRY) * 256, 'zzzG');
  407. if (ppal == NULL)
  408. goto ReturnFalse;
  409. pgdev->pPal = ppal;
  410. // Create handle for palette.
  411. hpal = EngCreatePalette(PAL_INDEXED, 256, (ULONG*) ppal, 0, 0, 0);
  412. }
  413. else
  414. {
  415. ASSERTGDI((pgdev->iBitmapFormat == BMF_16BPP) ||
  416. (pgdev->iBitmapFormat == BMF_24BPP) ||
  417. (pgdev->iBitmapFormat == BMF_32BPP),
  418. "This case handles only 16, 24 or 32bpp");
  419. hpal = EngCreatePalette(PAL_BITFIELDS, 0, NULL,
  420. pgdev->flRed, pgdev->flGreen, pgdev->flBlue);
  421. }
  422. pgdev->hpalDefault = hpal;
  423. pdi->hpalDefault = hpal;
  424. if (hpal == 0)
  425. goto ReturnFalse;
  426. return(TRUE);
  427. ReturnFalse:
  428. WARNING("Failed bInitializePalette");
  429. return(FALSE);
  430. }
  431. /******************************Public*Routine******************************\
  432. * VOID vGpsUninitializePalette
  433. *
  434. * Frees resources allocated by bInitializePalette.
  435. *
  436. * Note: In an error case, this may be called before bInitializePalette.
  437. *
  438. \**************************************************************************/
  439. VOID vGpsUninitializePalette(GDEV* gpdev)
  440. {
  441. // Delete the default palette if we created one:
  442. if (gpdev->hpalDefault != 0)
  443. EngDeletePalette(gpdev->hpalDefault);
  444. if (gpdev->pPal != (PALETTEENTRY*) NULL)
  445. EngFreeMem(gpdev->pPal);
  446. }
  447. /******************************Public*Routine******************************\
  448. * GpsDisablePDEV
  449. *
  450. \**************************************************************************/
  451. VOID GpsDisablePDEV(
  452. DHPDEV dhpdev)
  453. {
  454. GDEV* pgdev;
  455. pgdev = (GDEV*) dhpdev;
  456. vGpsUninitializePalette(pgdev);
  457. vGpsUninitializeDirectDraw(pgdev);
  458. VFREEMEM(pgdev);
  459. }
  460. /******************************Public*Routine******************************\
  461. * DHPDEV GpsEnablePDEV
  462. *
  463. \**************************************************************************/
  464. DHPDEV GpsEnablePDEV(
  465. DEVMODEW* pdm,
  466. PWSTR pwszLogAddr,
  467. ULONG cPat,
  468. HSURF* phsurfPatterns,
  469. ULONG cjCaps,
  470. ULONG* pdevcaps,
  471. ULONG cjDevInfo,
  472. DEVINFO* pdi,
  473. HDEV hdev,
  474. PWSTR pwszDeviceName,
  475. HANDLE hDriver)
  476. {
  477. GDEV* pgdev;
  478. HWND hwnd;
  479. ULONG BitsPerPlane;
  480. ULONG RedMask;
  481. ULONG GreenMask;
  482. ULONG BlueMask;
  483. ULONG ScreenWidth;
  484. ULONG ScreenHeight;
  485. pgdev = PALLOCMEM(sizeof(GDEV), 'zzzG');
  486. if (pgdev == NULL)
  487. {
  488. goto ReturnFailure0;
  489. }
  490. hwnd = (HWND) pdm;
  491. if (!bGpsInitializeDirectDraw(pgdev, hwnd, &ScreenWidth, &ScreenHeight,
  492. &BitsPerPlane, &RedMask, &GreenMask,
  493. &BlueMask))
  494. {
  495. goto ReturnFailure0;
  496. }
  497. if (!bGpsInitializeModeFields(pgdev, &ScreenWidth, &ScreenHeight,
  498. &BitsPerPlane, &RedMask, &GreenMask,
  499. &BlueMask, (GDIINFO*) pdevcaps, pdi))
  500. {
  501. goto ReturnFailure0;
  502. }
  503. if (!bGpsInitializePalette(pgdev, pdi))
  504. {
  505. goto ReturnFailure1;
  506. }
  507. return((DHPDEV) pgdev);
  508. ReturnFailure1:
  509. GpsDisablePDEV((DHPDEV) pgdev);
  510. ReturnFailure0:
  511. return(0);
  512. }
  513. /******************************Public*Routine******************************\
  514. * VOID GpsCompletePDEV
  515. *
  516. \**************************************************************************/
  517. VOID GpsCompletePDEV(
  518. DHPDEV dhpdev,
  519. HDEV hdev)
  520. {
  521. ((GDEV*) dhpdev)->hdev = hdev;
  522. }
  523. /******************************Public*Routine******************************\
  524. * VOID GpsDisableSurface
  525. *
  526. \**************************************************************************/
  527. VOID GpsDisableSurface(
  528. DHPDEV dhpdev)
  529. {
  530. GDEV* pgdev;
  531. pgdev = (GDEV*) dhpdev;
  532. EngDeleteSurface(pgdev->hsurfScreen);
  533. }
  534. /******************************Public*Routine******************************\
  535. * HSURF GpsEnableSurface
  536. *
  537. \**************************************************************************/
  538. HSURF GpsEnableSurface(
  539. DHPDEV dhpdev)
  540. {
  541. HSURF hsurf;
  542. GDEV* pgdev;
  543. pgdev = (GDEV*) dhpdev;
  544. hsurf = EngCreateDeviceSurface(NULL, pgdev->sizlScreen, pgdev->iBitmapFormat);
  545. if (hsurf == 0)
  546. {
  547. goto ReturnFailure;
  548. }
  549. // Associate surface with a physical device now
  550. if (!EngAssociateSurface(hsurf, pgdev->hdev, HOOK_BITBLT
  551. | HOOK_COPYBITS
  552. | HOOK_STROKEPATH
  553. | HOOK_TEXTOUT))
  554. {
  555. goto ReturnFailure;
  556. }
  557. pgdev->hsurfScreen = hsurf; // Remember it for clean-up
  558. return(hsurf);
  559. ReturnFailure:
  560. GpsDisableSurface((DHPDEV) pgdev);
  561. return(0);
  562. }
  563. /******************************Public*Routine******************************\
  564. * VOID vGpsWindowOffset
  565. *
  566. * Hack function to account for the window offset.
  567. *
  568. \**************************************************************************/
  569. VOID
  570. vGpsWindowOffset(
  571. GDEV* pgdev,
  572. RECTL* prcl,
  573. RECT* prc)
  574. {
  575. RECT rcWindow;
  576. GetWindowRect(pgdev->hwnd, &rcWindow);
  577. prc->left = rcWindow.left + prcl->left;
  578. prc->right = rcWindow.left + prcl->right;
  579. prc->top = rcWindow.top + prcl->top;
  580. prc->bottom = rcWindow.top + prcl->bottom;
  581. }
  582. /******************************Public*Routine******************************\
  583. * BOOL GpsCopyBits
  584. *
  585. \**************************************************************************/
  586. BOOL GpsCopyBits(
  587. SURFOBJ *psoDst,
  588. SURFOBJ *psoSrc,
  589. CLIPOBJ *pco,
  590. XLATEOBJ *pxlo,
  591. RECTL *prclDst,
  592. POINTL *pptlSrc)
  593. {
  594. GDEV* pgdev;
  595. RECTL rclSrc;
  596. HRESULT hr;
  597. RECT rcWindow;
  598. RECT rcSrc;
  599. rclSrc.left = pptlSrc->x;
  600. rclSrc.top = pptlSrc->y;
  601. rclSrc.right = pptlSrc->x + (prclDst->right - prclDst->left);
  602. rclSrc.bottom = pptlSrc->y + (prclDst->bottom - prclDst->top);
  603. if (psoSrc->dhpdev == NULL)
  604. {
  605. // DIB-to-screen:
  606. pgdev = (GDEV*) psoDst->dhpdev;
  607. vGpsWindowOffset(pgdev, prclDst, &rcWindow);
  608. if ((pco != NULL) && (pco->iDComplexity != DC_TRIVIAL))
  609. {
  610. // Read in a copy of the destination bits in order to handle
  611. // complex clipping because we're going to write everything
  612. // back out:
  613. Repeat1:
  614. hr = pgdev->lpDDBuffer->lpVtbl->Blt(pgdev->lpDDBuffer,
  615. (RECT*) prclDst,
  616. pgdev->lpDDPrimary,
  617. &rcWindow,
  618. DDBLT_WAIT,
  619. NULL);
  620. if (hr == DDERR_SURFACELOST)
  621. {
  622. DbgPrint("Lost!\n");
  623. pgdev->lpDDPrimary->lpVtbl->Restore(pgdev->lpDDPrimary);
  624. goto Repeat1;
  625. }
  626. }
  627. EngCopyBits(pgdev->psoBuffer, psoSrc, pco, pxlo, prclDst, pptlSrc);
  628. Repeat2:
  629. hr = pgdev->lpDDPrimary->lpVtbl->Blt(pgdev->lpDDPrimary,
  630. &rcWindow,
  631. pgdev->lpDDBuffer,
  632. (RECT*) prclDst,
  633. DDBLT_WAIT,
  634. NULL);
  635. if (hr == DDERR_SURFACELOST)
  636. {
  637. DbgPrint("Lost2\n");
  638. pgdev->lpDDPrimary->lpVtbl->Restore(pgdev->lpDDPrimary);
  639. goto Repeat2;
  640. }
  641. }
  642. else if (psoDst->dhpdev == NULL)
  643. {
  644. // Screen-to-DIB:
  645. pgdev = (GDEV*) psoSrc->dhpdev;
  646. vGpsWindowOffset(pgdev, &rclSrc, &rcWindow);
  647. pgdev->lpDDPrimary->lpVtbl->Blt(pgdev->lpDDBuffer,
  648. (RECT*) &rclSrc,
  649. pgdev->lpDDPrimary,
  650. &rcWindow,
  651. DDBLT_WAIT,
  652. NULL);
  653. EngCopyBits(psoDst, pgdev->psoBuffer, pco, pxlo, prclDst, pptlSrc);
  654. }
  655. else
  656. {
  657. // Screen-to-screen:
  658. pgdev = (GDEV*) psoDst->dhpdev;
  659. vGpsWindowOffset(pgdev, prclDst, &rcWindow);
  660. vGpsWindowOffset(pgdev, &rclSrc, &rcSrc);
  661. pgdev->lpDDPrimary->lpVtbl->Blt(pgdev->lpDDPrimary,
  662. &rcWindow,
  663. pgdev->lpDDPrimary,
  664. &rcSrc,
  665. DDBLT_WAIT,
  666. NULL);
  667. }
  668. return(TRUE);
  669. }
  670. /******************************Public*Routine******************************\
  671. * BOOL GpsBitBlt
  672. *
  673. * An 's' is appended to this function name so that we don't conflict
  674. * with 'GpsBitBlt' exported from gdiplus.dll.
  675. *
  676. \**************************************************************************/
  677. BOOL GpsBitBlt(
  678. SURFOBJ* psoDst,
  679. SURFOBJ* psoSrc,
  680. SURFOBJ* psoMsk,
  681. CLIPOBJ* pco,
  682. XLATEOBJ* pxlo,
  683. RECTL* prclDst,
  684. POINTL* pptlSrc,
  685. POINTL* pptlMsk,
  686. BRUSHOBJ* pbo,
  687. POINTL* pptlBrush,
  688. ROP4 rop4)
  689. {
  690. GDEV* pgdev;
  691. HRESULT hr;
  692. RECT rcWindow;
  693. if (psoSrc == NULL)
  694. {
  695. // Patblt to screen:
  696. pgdev = (GDEV*) psoDst->dhpdev;
  697. vGpsWindowOffset(pgdev, prclDst, &rcWindow);
  698. if ((pco != NULL) && (pco->iDComplexity != DC_TRIVIAL))
  699. {
  700. // Read in a copy of the destination bits in order to handle
  701. // complex clipping because we're going to write everything
  702. // back out:
  703. Repeat1:
  704. hr = pgdev->lpDDBuffer->lpVtbl->Blt(pgdev->lpDDBuffer,
  705. (RECT*) prclDst,
  706. pgdev->lpDDPrimary,
  707. &rcWindow,
  708. DDBLT_WAIT,
  709. NULL);
  710. if (hr == DDERR_SURFACELOST)
  711. {
  712. DbgPrint("Lost!\n");
  713. pgdev->lpDDPrimary->lpVtbl->Restore(pgdev->lpDDPrimary);
  714. goto Repeat1;
  715. }
  716. }
  717. EngBitBlt(pgdev->psoBuffer, psoSrc, psoMsk, pco, pxlo, prclDst,
  718. pptlSrc, pptlMsk, pbo, pptlBrush, rop4);
  719. Repeat2:
  720. hr = pgdev->lpDDPrimary->lpVtbl->Blt(pgdev->lpDDPrimary,
  721. &rcWindow,
  722. pgdev->lpDDBuffer,
  723. (RECT*) prclDst,
  724. DDBLT_WAIT,
  725. NULL);
  726. if (hr == DDERR_SURFACELOST)
  727. {
  728. DbgPrint("Lost2\n");
  729. pgdev->lpDDPrimary->lpVtbl->Restore(pgdev->lpDDPrimary);
  730. goto Repeat2;
  731. }
  732. return(TRUE);
  733. }
  734. else
  735. {
  736. return(EngBitBlt(psoDst, psoSrc, psoMsk, pco, pxlo, prclDst, pptlSrc,
  737. pptlMsk, pbo, pptlBrush, rop4));
  738. }
  739. }
  740. /******************************Public*Routine******************************\
  741. * BOOL GpsStrokePath
  742. *
  743. \**************************************************************************/
  744. BOOL GpsStrokePath(
  745. SURFOBJ* pso,
  746. PATHOBJ* ppo,
  747. CLIPOBJ* pco,
  748. XFORMOBJ* pxlo,
  749. BRUSHOBJ* pbo,
  750. POINTL* pptlBrush,
  751. LINEATTRS* pla,
  752. MIX mix)
  753. {
  754. GDEV* pgdev;
  755. HRESULT hr;
  756. RECT rcWindow;
  757. Repeat1:
  758. pgdev = (GDEV*) pso->dhpdev;
  759. vGpsWindowOffset(pgdev, &pco->rclBounds, &rcWindow);
  760. hr = pgdev->lpDDBuffer->lpVtbl->Blt(pgdev->lpDDBuffer,
  761. (RECT*) &pco->rclBounds,
  762. pgdev->lpDDPrimary,
  763. &rcWindow,
  764. DDBLT_WAIT,
  765. NULL);
  766. if (hr == DDERR_SURFACELOST)
  767. {
  768. DbgPrint("Lost!\n");
  769. pgdev->lpDDPrimary->lpVtbl->Restore(pgdev->lpDDPrimary);
  770. goto Repeat1;
  771. }
  772. EngStrokePath(pgdev->psoBuffer, ppo, pco, pxlo, pbo, pptlBrush,
  773. pla, mix);
  774. hr = pgdev->lpDDPrimary->lpVtbl->Blt(pgdev->lpDDPrimary,
  775. &rcWindow,
  776. pgdev->lpDDBuffer,
  777. (RECT*) &pco->rclBounds,
  778. DDBLT_WAIT,
  779. NULL);
  780. return(TRUE);
  781. }
  782. /******************************Public*Routine******************************\
  783. * BOOL GpsTextOut
  784. *
  785. \**************************************************************************/
  786. BOOL GpsTextOut(
  787. SURFOBJ* pso,
  788. STROBJ* pstro,
  789. FONTOBJ* pfo,
  790. CLIPOBJ* pco,
  791. RECTL* prclExtra,
  792. RECTL* prclOpaque,
  793. BRUSHOBJ* pboFore,
  794. BRUSHOBJ* pboOpaque,
  795. POINTL* pptlOrg,
  796. MIX mix)
  797. {
  798. GDEV* pgdev;
  799. HRESULT hr;
  800. RECT rcWindow;
  801. RECTL* prclDraw;
  802. Repeat1:
  803. pgdev = (GDEV*) pso->dhpdev;
  804. prclDraw = (prclOpaque != NULL) ? prclOpaque : &pstro->rclBkGround;
  805. vGpsWindowOffset(pgdev, prclDraw, &rcWindow);
  806. hr = pgdev->lpDDBuffer->lpVtbl->Blt(pgdev->lpDDBuffer,
  807. (RECT*) prclDraw,
  808. pgdev->lpDDPrimary,
  809. &rcWindow,
  810. DDBLT_WAIT,
  811. NULL);
  812. if (hr == DDERR_SURFACELOST)
  813. {
  814. DbgPrint("Lost!\n");
  815. pgdev->lpDDPrimary->lpVtbl->Restore(pgdev->lpDDPrimary);
  816. goto Repeat1;
  817. }
  818. EngTextOut(pgdev->psoBuffer, pstro, pfo, pco, prclExtra, prclOpaque,
  819. pboFore, pboOpaque, pptlOrg, mix);
  820. hr = pgdev->lpDDPrimary->lpVtbl->Blt(pgdev->lpDDPrimary,
  821. &rcWindow,
  822. pgdev->lpDDBuffer,
  823. (RECT*) prclDraw,
  824. DDBLT_WAIT,
  825. NULL);
  826. return(TRUE);
  827. }
  828. /******************************Public*Structure****************************\
  829. * DFVFN gadrvfnGdiPlus[]
  830. *
  831. \**************************************************************************/
  832. DRVFN gadrvfnGdiPlus[] = {
  833. { INDEX_DrvEnablePDEV, (PFN) GpsEnablePDEV },
  834. { INDEX_DrvCompletePDEV, (PFN) GpsCompletePDEV },
  835. { INDEX_DrvDisablePDEV, (PFN) GpsDisablePDEV },
  836. { INDEX_DrvEnableSurface, (PFN) GpsEnableSurface },
  837. { INDEX_DrvDisableSurface, (PFN) GpsDisableSurface },
  838. { INDEX_DrvCopyBits, (PFN) GpsCopyBits },
  839. { INDEX_DrvBitBlt, (PFN) GpsBitBlt },
  840. { INDEX_DrvStrokePath, (PFN) GpsStrokePath },
  841. { INDEX_DrvTextOut, (PFN) GpsTextOut },
  842. };
  843. ULONG gcdrvfnGdiPlus = sizeof(gadrvfnGdiPlus) / sizeof(DRVFN);
  844. /******************************Public*Routine******************************\
  845. * BOOL GpsEnableDriver
  846. *
  847. \**************************************************************************/
  848. BOOL GpsEnableDriver(
  849. ULONG iEngineVersion,
  850. ULONG cj,
  851. DRVENABLEDATA* pded)
  852. {
  853. pded->pdrvfn = gadrvfnGdiPlus;
  854. pded->c = gcdrvfnGdiPlus;
  855. pded->iDriverVersion = DDI_DRIVER_VERSION;
  856. return(TRUE);
  857. }