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.

1075 lines
33 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: surfeng.cxx
  3. *
  4. * Internal surface routines
  5. *
  6. * Created: 13-May-1991 12:53:31
  7. * Author: Patrick Haluptzok patrickh
  8. *
  9. * Copyright (c) 1991-1999 Microsoft Corporation
  10. \**************************************************************************/
  11. #include "precomp.hxx"
  12. extern "C" BOOL bInitBMOBJ();
  13. #define MAX_STOCKBITMAPS 4*1024
  14. LONG gStockBitmapFree = MAX_STOCKBITMAPS;
  15. #pragma alloc_text(INIT, bInitBMOBJ)
  16. #if DBG_STOCKBITMAPS
  17. #define STOCKWARNING DbgPrint
  18. #define STOCKINFO DbgPrint
  19. #else
  20. #define STOCKWARNING
  21. #define STOCKINFO
  22. #endif
  23. /******************************Public*Routine******************************\
  24. * GreSetBitmapOwner
  25. *
  26. * Sets the bitmap owner.
  27. *
  28. \**************************************************************************/
  29. BOOL
  30. GreSetBitmapOwner(
  31. HBITMAP hbm,
  32. W32PID lPid
  33. )
  34. {
  35. BOOL bRet = FALSE;
  36. SURFREF so((HSURF)hbm);
  37. if (so.bValid())
  38. {
  39. if (!(so.ps->bDIBSection() && (lPid == OBJECT_OWNER_PUBLIC)))
  40. {
  41. if(HmgStockObj(hbm)) {
  42. WARNING("GreSetBitmapOwner: Cannot set owner for the stock bitmap\n");
  43. }
  44. else
  45. {
  46. #if TRACE_SURFACE_ALLOCS
  47. #if TRACE_SURFACE_USER_CHAIN_IN_UM
  48. BOOL bOwned;
  49. TRACED_SURFACE *pts = (TRACED_SURFACE *)so.ps;
  50. if (pts->bEnabled())
  51. {
  52. PENTRY pentTmp = &gpentHmgr[(UINT) HmgIfromH(hbm)];
  53. bOwned = ((OBJECTOWNER_PID(pentTmp->ObjectOwner) != OBJECT_OWNER_PUBLIC) &&
  54. (OBJECTOWNER_PID(pentTmp->ObjectOwner) != OBJECT_OWNER_NONE));
  55. if (bOwned && ((lPid == OBJECT_OWNER_PUBLIC) || (lPid == OBJECT_OWNER_NONE)))
  56. {
  57. pts->vProcessStackFromUM(TRUE);
  58. ASSERTGDI(pentTmp->pUser == NULL, "Object becoming unowned, but user mem is still allocated.\n");
  59. }
  60. }
  61. else
  62. {
  63. bOwned = TRUE;
  64. }
  65. #endif
  66. #endif
  67. bRet = HmgSetOwner((HOBJ)hbm,lPid,SURF_TYPE);
  68. #if TRACE_SURFACE_ALLOCS
  69. #if TRACE_SURFACE_USER_CHAIN_IN_UM
  70. if (!bRet && !bOwned)
  71. {
  72. pts->vProcessStackFromUM(TRUE);
  73. }
  74. #endif
  75. #endif
  76. }
  77. }
  78. else
  79. {
  80. WARNING ("GreSetBitmapOnwer - Setting a DIBSECTION to PUBLIC\n");
  81. }
  82. }
  83. else
  84. {
  85. WARNING1("GreSetBitmapOnwer - invalid surfobj\n");
  86. }
  87. return(bRet);
  88. }
  89. /******************************Public*Routine******************************\
  90. * GreMakeBitmapStock
  91. *
  92. * Makes the bitmap a stock object.
  93. *
  94. * Requirements:
  95. * Bitmap is already not a stock Object.
  96. * Bitmap is not a dibsection.
  97. * Bitmap should not be selected into any DCs.
  98. * Not more than MAX_STOCKBITMAPS gStockBitmaps.
  99. *
  100. \**************************************************************************/
  101. HBITMAP
  102. GreMakeBitmapStock(HBITMAP hbm)
  103. {
  104. HANDLE bRet = 0;
  105. SURFREFAPI so((HSURF)hbm);
  106. if (so.bValid())
  107. {
  108. if (!(so.ps->bDIBSection()))
  109. {
  110. if (HmgStockObj(hbm) || so.ps->cRef())
  111. {
  112. STOCKWARNING("GreMakeBitmapStock: cannot make bitmap (%p) stock\nReason:",hbm);
  113. if (HmgStockObj(hbm))
  114. STOCKWARNING(" it is already a stock bitmap\n");
  115. else
  116. STOCKWARNING(" it is selected into some DC\n");
  117. }
  118. else
  119. {
  120. bRet = (HANDLE)((ULONG_PTR)hbm | GDISTOCKOBJ);
  121. if (InterlockedDecrement(&gStockBitmapFree) >= 0 &&
  122. HmgLockAndModifyHandleType((HOBJ)bRet))
  123. {
  124. so.ps->vSetStockSurface();
  125. so.ps->hsurf(bRet);
  126. so.vSetPID(OBJECT_OWNER_PUBLIC);
  127. }
  128. else
  129. {
  130. InterlockedIncrement(&gStockBitmapFree);
  131. STOCKWARNING ("GreMakeBitmapStock - HmgLockAndModifyHandleType failed\n");
  132. bRet = 0;
  133. }
  134. }
  135. }
  136. else
  137. {
  138. WARNING ("GreMakeBitmapStock - Setting a DIBSECTION to Stock \n");
  139. }
  140. }
  141. else
  142. {
  143. WARNING1("GreMakeBitmapStock - invalid surfobj\n");
  144. }
  145. return((HBITMAP)bRet);
  146. }
  147. /******************************Public*Routine******************************\
  148. * GreMakeBitmapNonStock
  149. *
  150. * Makes the bitmap a non stock object.
  151. *
  152. * Requirements:
  153. * Bitmap is not default stock bitmap
  154. * Bitmap is a stock bitmap
  155. * Bitmap is not a dibsection
  156. * Bitmap is not selected into any DC
  157. * Some stock bitmaps should exist
  158. * Bitmap must be public
  159. *
  160. \**************************************************************************/
  161. HBITMAP
  162. GreMakeBitmapNonStock(HBITMAP hbm)
  163. {
  164. HANDLE bRet = 0;
  165. SURFREFAPI so((HSURF)hbm);
  166. ASSERTGDI(GreGetObjectOwner((HOBJ)hbm,SURF_TYPE) == OBJECT_OWNER_PUBLIC,"GreMakeBitmapNonStock() bitmap is not public\n");
  167. ASSERTGDI(gStockBitmapFree != MAX_STOCKBITMAPS,"GreMakeBitmapNonStock() no stock bitmaps\n");
  168. if (so.bValid())
  169. {
  170. if (!(so.ps->bDIBSection()))
  171. {
  172. if (hbm==STOCKOBJ_BITMAP || !HmgStockObj(hbm))
  173. {
  174. STOCKWARNING("GreMakeBitmapNonStock: Cannot make stock bitmap (%p) non Stock\nReason:",hbm);
  175. if (hbm==STOCKOBJ_BITMAP)
  176. STOCKWARNING(" it is the default stock bitmap\n");
  177. else
  178. STOCKWARNING(" it is not a stock bitmap\n");
  179. }
  180. else
  181. {
  182. bRet = (HANDLE)((ULONG_PTR)hbm & ~GDISTOCKOBJ);
  183. if (so.ps->cRef())
  184. {
  185. so.ps->vSetUndoStockSurfaceDelayed();
  186. STOCKWARNING("GreMakeBitmapNonStock: Delaying make stock bitmap (%p) non Stock\n",hbm);
  187. }
  188. else if(HmgLockAndModifyHandleType((HOBJ)bRet))
  189. {
  190. InterlockedIncrement(&gStockBitmapFree);
  191. so.ps->vClearStockSurface();
  192. so.ps->hsurf(bRet);
  193. so.vSetPID(OBJECT_OWNER_CURRENT);
  194. }
  195. else
  196. {
  197. STOCKWARNING ("GreMakeBitmapNonStock - HmgLockAndModifyHandleType failed\n");
  198. bRet = 0;
  199. }
  200. }
  201. }
  202. else
  203. {
  204. WARNING ("GreMakeBitmapNonStock - DIBSECTION to set as non stock\n");
  205. }
  206. }
  207. else
  208. {
  209. WARNING1("GreMakeBitmapNonStock - invalid surfobj\n");
  210. }
  211. return((HBITMAP)bRet);
  212. }
  213. /******************************Public*Routine******************************\
  214. * bInitBMOBJ
  215. *
  216. * Initializes the default bitmap.
  217. *
  218. * History:
  219. * 14-Apr-1991 -by- Patrick Haluptzok patrickh
  220. * Wrote it.
  221. \**************************************************************************/
  222. extern "C" BOOL bInitBMOBJ()
  223. {
  224. HBITMAP hbmTemp = GreCreateBitmap(1, 1, 1, 1, (LPBYTE) NULL);
  225. if (hbmTemp == (HBITMAP) 0)
  226. {
  227. WARNING("Failed to create default bitmap\n");
  228. return(FALSE);
  229. }
  230. SURFREF so((HSURF)hbmTemp);
  231. ASSERTGDI(so.bValid(), "ERROR it created but isn't lockable STOCKOBJ_BITMAP");
  232. ASSERTGDI(so.ps->ppal() == ppalMono, "ERROR the default bitmap has no ppalMono");
  233. so.vSetPID(OBJECT_OWNER_PUBLIC);
  234. bSetStockObject(hbmTemp,PRIV_STOCK_BITMAP);
  235. so.ps->hsurf((HANDLE)((ULONG_PTR)hbmTemp | GDISTOCKOBJ));
  236. SURFACE::pdibDefault = so.ps;
  237. return(TRUE);
  238. }
  239. /******************************Public*Routine******************************\
  240. * BOOL bDeleteSurface(HSURF)
  241. *
  242. * Delete the surface object
  243. *
  244. * History:
  245. * Sun 14-Apr-1991 -by- Patrick Haluptzok [patrickh]
  246. * Wrote it.
  247. \**************************************************************************/
  248. BOOL bDeleteSurface(HSURF hsurf)
  249. {
  250. SURFREF so;
  251. so.vAltCheckLockIgnoreStockBit(hsurf);
  252. return(so.bDeleteSurface()); // bDeleteSurface() checks bValid()
  253. }
  254. /******************************Public*Routine******************************\
  255. * hbmSelectBitmap
  256. *
  257. * Select the bitmap into a DC. Provides option to override the
  258. * DirectDraw surface check.
  259. *
  260. * History:
  261. * Wed 28-Aug-1991 -by- Patrick Haluptzok [patrickh]
  262. * update it, make palette aware.
  263. *
  264. * Mon 13-May-1991 -by- Patrick Haluptzok [patrickh]
  265. * Wrote it.
  266. \**************************************************************************/
  267. HBITMAP hbmSelectBitmap(HDC hdc, HBITMAP hsurf, BOOL bDirectDrawOverride)
  268. {
  269. HSURF hsurfReturn = (HSURF) 0;
  270. BOOL bDelete = FALSE;
  271. //
  272. // Grab multi-lock so noone can select or delete it.
  273. //
  274. MLOCKOBJ mlo;
  275. //
  276. // Lock bitmap
  277. //
  278. SURFREF SurfBoNew;
  279. SurfBoNew.vMultiLock((HSURF) hsurf);
  280. MDCOBJ dco(hdc);
  281. if (dco.bValid() && SurfBoNew.bValid())
  282. {
  283. PSURFACE pSurfNew = SurfBoNew.ps;
  284. ASSERTGDI(DIFFHANDLE(hsurf,STOCKOBJ_BITMAP) ||
  285. (pSurfNew->cRef() == 0) , "ERROR STOCKOBJ_BITMAP cRef != 0");
  286. PDEVOBJ po(dco.hdev());
  287. PPALETTE ppalSrc;
  288. PROCESS_UM_TRACE(pSurfNew, FALSE);
  289. if ((dco.dctp() == DCTYPE_MEMORY) &&
  290. ((pSurfNew->cRef() == 0 || pSurfNew->bStockSurface()) || SAMEHANDLE(pSurfNew->hdc(),dco.hdc())) &&
  291. (bIsCompatible(&ppalSrc, pSurfNew->ppal(), pSurfNew, dco.hdev())))
  292. {
  293. //
  294. // Note: pSurfOld not safe outside of the MLOCKOBJ.
  295. //
  296. SURFACE *pSurfOld = dco.pSurfaceEff();
  297. //
  298. // Only DirectDraw itself may select DirectDraw surfaces
  299. // into, or out of, DCs. This is because DirectDraw has
  300. // to track the DCs to be able to mark them as 'bInFullScreen'
  301. // when the corresponding DirectDraw surface is 'lost'.
  302. //
  303. if ((pSurfOld->bApiBitmap() && pSurfNew->bApiBitmap()) ||
  304. (bDirectDrawOverride))
  305. {
  306. //
  307. // If this DC is mirrored then turn the mirroring off
  308. // And turn it on after selecting the bitmap to set the correct
  309. // Window Org.
  310. //
  311. DWORD dwLayout = dco.pdc->dwLayout();
  312. if (dwLayout & LAYOUT_ORIENTATIONMASK)
  313. {
  314. dco.pdc->dwSetLayout(-1 , 0);
  315. }
  316. if (pSurfNew->ppal() != ppalSrc)
  317. {
  318. pSurfNew->flags(pSurfNew->flags() | PALETTE_SELECT_SET);
  319. pSurfNew->ppal(ppalSrc);
  320. }
  321. HSURF hsurfDelete = (HSURF)
  322. (pSurfOld->bLazyDelete() ? pSurfOld->hGet() : NULL);
  323. hsurfReturn = pSurfOld->hsurf();
  324. if (DIFFHANDLE((HSURF) hsurf, hsurfReturn))
  325. {
  326. if (pSurfNew->bIsDefault())
  327. {
  328. dco.pdc->pSurface((SURFACE *) NULL);
  329. }
  330. else
  331. {
  332. dco.pdc->pSurface((SURFACE *) pSurfNew);
  333. if (pSurfNew->bStockSurface())
  334. dco.pdc->bStockBitmap(TRUE);
  335. else
  336. dco.pdc->bStockBitmap(FALSE);
  337. }
  338. dco.pdc->sizl(pSurfNew->sizl());
  339. dco.pdc->ulDirtyAdd(DIRTY_BRUSHES);
  340. //
  341. // Lower the reference count on the old handle
  342. //
  343. if (!pSurfOld->bIsDefault())
  344. {
  345. pSurfOld->vDec_cRef();
  346. if (pSurfOld->cRef() == 0)
  347. {
  348. //
  349. // Remove reference to device palette if it has one.
  350. //
  351. if (pSurfOld->flags() & PALETTE_SELECT_SET)
  352. pSurfOld->ppal(NULL);
  353. pSurfOld->flags(pSurfOld->flags() & ~PALETTE_SELECT_SET);
  354. }
  355. }
  356. //
  357. // Device Format Bitmaps hooked by the driver must always
  358. // have devlock synchronization.
  359. //
  360. // Other device-dependent bitmaps must have devlock
  361. // synchronization if they can be affected by dynamic mode
  362. // changes, because they may have to be converted on-the-fly
  363. // to DIBs.
  364. //
  365. dco.bSynchronizeAccess(
  366. (pSurfNew->bUseDevlock()) ||
  367. (pSurfNew->bDeviceDependentBitmap() && po.bDisplayPDEV()));
  368. dco.bShareAccess(dco.bSynchronizeAccess() && pSurfNew->bShareAccess());
  369. //
  370. // Put the relevant DC information into the surface as long as it's not
  371. // the default surface.
  372. //
  373. if (!pSurfNew->bIsDefault())
  374. {
  375. pSurfNew->vInc_cRef();
  376. if (!pSurfNew->bStockSurface())
  377. {
  378. pSurfNew->hdc(dco.hdc());
  379. pSurfNew->hdev(dco.hdev());
  380. }
  381. }
  382. //
  383. // set DIBSection flag in DC
  384. //
  385. dco.pdc->vDIBSection(pSurfNew->bDIBSection());
  386. //
  387. // set DIBColorSpace indentifier.
  388. //
  389. if (pSurfNew->bDIBSection())
  390. {
  391. dco.pdc->dwDIBColorSpace(pSurfNew->dwDIBColorSpace());
  392. }
  393. else
  394. {
  395. dco.pdc->dwDIBColorSpace(0);
  396. }
  397. // Unref the SurfBoNew as we dont use pSurfNew anymore. This
  398. // will also make sure any mode change logic called code
  399. // like pConvertDfbSurfaceToDib will not get
  400. // tripped due to sharelocks held on the pSurfNew.
  401. SurfBoNew.vUnreference();
  402. mlo.vDisable();
  403. dco.pdc->bSetDefaultRegion();
  404. dco.pdc->vUpdate_VisRect(dco.pdc->prgnVis());
  405. if (hsurfDelete)
  406. {
  407. //
  408. // We need one shared lock for bDeleteSurface to succeed:
  409. //
  410. SURFREF so(hsurfDelete);
  411. so.bDeleteSurface();
  412. hsurfReturn = (HSURF)STOCKOBJ_BITMAP;
  413. }
  414. }
  415. //
  416. // If it was mirrored then turn back the mirroring on.
  417. //
  418. if (dwLayout & LAYOUT_ORIENTATIONMASK)
  419. {
  420. dco.pdc->dwSetLayout(-1 , dwLayout);
  421. }
  422. }
  423. else
  424. {
  425. WARNING("hbmSelectBitmap failed, unselectable surface\n");
  426. }
  427. }
  428. else
  429. {
  430. WARNING1("hbmSelectBitmap failed selection, bitmap doesn't fit into DC\n");
  431. }
  432. }
  433. else
  434. {
  435. #if DBG
  436. if (dco.bValid())
  437. {
  438. WARNING1("hbmSelectBitmap given invalid bitmap\n");
  439. }
  440. else
  441. {
  442. WARNING1("hbmSelectBitmap given invalid DC\n");
  443. }
  444. #endif
  445. }
  446. return((HBITMAP) hsurfReturn);
  447. }
  448. /******************************Public*Routine******************************\
  449. * GreSelectBitmap
  450. *
  451. * Select the bitmap into a DC. User and the like will call this function.
  452. *
  453. \**************************************************************************/
  454. HBITMAP GreSelectBitmap(HDC hdc, HBITMAP hsurf)
  455. {
  456. return(hbmSelectBitmap(hdc, hsurf, FALSE));
  457. }
  458. /******************************Public*Routine******************************\
  459. * hbmCreateClone
  460. *
  461. * Creates an engine managed clone of a bitmap.
  462. *
  463. * History:
  464. * Tue 17-May-1994 -by- Patrick Haluptzok [patrickh]
  465. * Synchronize the call if it's a DFB that needs synching.
  466. *
  467. * 19-Jun-1991 -by- Patrick Haluptzok patrickh
  468. * Wrote it.
  469. \**************************************************************************/
  470. HBITMAP hbmCreateClone(SURFACE *pSurfSrc, ULONG cx, ULONG cy)
  471. {
  472. ASSERTGDI(pSurfSrc != NULL, "ERROR hbmCreateClone invalid src");
  473. ASSERTGDI((pSurfSrc->iType() == STYPE_BITMAP) ||
  474. (pSurfSrc->iType() == STYPE_DEVBITMAP), "ERROR hbmCreateClone src type");
  475. DEVBITMAPINFO dbmi;
  476. dbmi.iFormat = pSurfSrc->iFormat();
  477. if ((cx == 0) || (cy == 0))
  478. {
  479. dbmi.cxBitmap = pSurfSrc->sizl().cx;
  480. dbmi.cyBitmap = pSurfSrc->sizl().cy;
  481. }
  482. else
  483. {
  484. ASSERTGDI(cx <= LONG_MAX, "hbmCreateClone: cx too large\n");
  485. dbmi.cxBitmap = min(pSurfSrc->sizl().cx,(LONG)cx);
  486. ASSERTGDI(cy <= LONG_MAX, "hbmCreateClone: cy too large\n");
  487. dbmi.cyBitmap = min(pSurfSrc->sizl().cy,(LONG)cy);
  488. }
  489. dbmi.hpal = (HPALETTE) 0;
  490. if (pSurfSrc->ppal() != NULL)
  491. {
  492. dbmi.hpal = (HPALETTE) pSurfSrc->ppal()->hGet();
  493. }
  494. dbmi.fl = BMF_TOPDOWN;
  495. HBITMAP hbmReturn = (HBITMAP) 0;
  496. SURFMEM SurfDimo;
  497. if (SurfDimo.bCreateDIB(&dbmi, NULL))
  498. {
  499. POINTL ptlSrc;
  500. ptlSrc.x = 0;
  501. ptlSrc.y = 0;
  502. RECTL rclDst;
  503. rclDst.left = 0;
  504. rclDst.right = dbmi.cxBitmap;
  505. rclDst.top = 0;
  506. rclDst.bottom = dbmi.cyBitmap;
  507. HSEMAPHORE hsemDevLock = NULL;
  508. PPDEV ppdev = NULL;
  509. if (pSurfSrc->bUseDevlock())
  510. {
  511. PDEVOBJ po(pSurfSrc->hdev());
  512. ASSERTGDI(po.bValid(), "PDEV invalid");
  513. hsemDevLock = po.hsemDevLock();
  514. ppdev = po.ppdev;
  515. GreAcquireSemaphoreEx(hsemDevLock, SEMORDER_DEVLOCK, NULL);
  516. GreEnterMonitoredSection(ppdev, WD_DEVLOCK);
  517. }
  518. if (EngCopyBits( SurfDimo.pSurfobj(), // Destination surfobj
  519. pSurfSrc->pSurfobj(), // Source surfobj.
  520. (CLIPOBJ *) NULL, // Clip object.
  521. &xloIdent, // Palette translation object.
  522. &rclDst, // Destination rectangle.
  523. &ptlSrc ))
  524. {
  525. SurfDimo.vKeepIt();
  526. hbmReturn = (HBITMAP) SurfDimo.ps->hsurf();
  527. }
  528. else
  529. {
  530. WARNING("ERROR hbmCreateClone failed EngBitBlt\n");
  531. }
  532. if (hsemDevLock)
  533. {
  534. GreExitMonitoredSection(ppdev, WD_DEVLOCK);
  535. GreReleaseSemaphoreEx(hsemDevLock);
  536. }
  537. }
  538. else
  539. {
  540. WARNING("ERROR hbmCreateClone failed DIB allocation\n");
  541. }
  542. return(hbmReturn);
  543. }
  544. /******************************Public*Routine******************************\
  545. * NtGdiGetDCforBitmap
  546. *
  547. * Get the DC that the bitmap is selected into
  548. *
  549. * History:
  550. * 12-12-94 -by- Lingyun Wang[lingyunw]
  551. * Wrote it.
  552. \**************************************************************************/
  553. HDC NtGdiGetDCforBitmap(HBITMAP hsurf)
  554. {
  555. HDC hdcReturn = 0;
  556. SURFREF so((HSURF) hsurf);
  557. if (so.bValid())
  558. {
  559. hdcReturn = so.ps->hdc();
  560. }
  561. return(hdcReturn);
  562. }
  563. /******************************Public*Routine******************************\
  564. * NtGdiColorSpaceforBitmap
  565. *
  566. * Get the color space data for this bitmap
  567. *
  568. * History:
  569. * 06-06-97 -by- Hideyuki Nagase [hideyukn]
  570. * Wrote it.
  571. \**************************************************************************/
  572. ULONG_PTR NtGdiGetColorSpaceforBitmap(HBITMAP hsurf)
  573. {
  574. ULONG_PTR dwReturn = 0;
  575. SURFREF so((HSURF) hsurf);
  576. if (so.bValid() && so.ps->bDIBSection())
  577. {
  578. dwReturn = so.ps->dwDIBColorSpace();
  579. }
  580. return(dwReturn);
  581. }
  582. /******************************Public*Routine******************************\
  583. * GreMakeInfoDC()
  584. *
  585. * This routine is used to take a printer DC and temporarily make it a
  586. * Metafile DC for spooled printing. This way it can be associated with
  587. * an enhanced metafile. During this period, it should look and act just
  588. * like an info DC.
  589. *
  590. * bSet determines if it should be set into the INFO DC state or restored
  591. * to the Direct state.
  592. *
  593. * History:
  594. * 04-Jan-1995 -by- Eric Kutter [erick]
  595. * Wrote it.
  596. \**************************************************************************/
  597. BOOL NtGdiMakeInfoDC(
  598. HDC hdc,
  599. BOOL bSet)
  600. {
  601. ASSERTGDI(LO_TYPE(hdc) == LO_ALTDC_TYPE,"GreMakeInfoDC - not alt type\n");
  602. BOOL bRet = FALSE;
  603. XDCOBJ dco( hdc );
  604. if (dco.bValid())
  605. {
  606. bRet = dco.pdc->bMakeInfoDC(bSet);
  607. dco.vUnlockFast();
  608. }
  609. return(bRet);
  610. }
  611. /******************************Private*Routine*****************************\
  612. * BOOL pConvertDfbSurfaceToDib
  613. *
  614. * Converts a compatible bitmap into an engine managed bitmap. Note that
  615. * if the bitmap is currently selected into a DC, bConvertDfbDcToDib should
  616. * be called.
  617. *
  618. * The devlock must be already be held.
  619. *
  620. * History:
  621. * Wed 5-May-1994 -by- Tom Zakrajsek [tomzak]
  622. * Wrote it (with lots of help from PatrickH and EricK).
  623. \*************************************************************************/
  624. SURFACE* pConvertDfbSurfaceToDib
  625. (
  626. HDEV hdev,
  627. SURFACE *pSurfOld,
  628. LONG ExpectedShareCount
  629. )
  630. {
  631. BOOL b;
  632. SURFACE *pSurfNew;
  633. SURFACE *pSurfRet;
  634. #if TEXTURE_DEMO
  635. if (ghdevTextureParent)
  636. {
  637. return(NULL);
  638. }
  639. #endif
  640. pSurfRet = NULL;
  641. ASSERTGDI((pSurfOld != NULL),
  642. "pConvertDfbSurfaceToDib: pSurf attached to the DC is NULL\n");
  643. ASSERTGDI((pSurfOld->bRedirection() == FALSE),
  644. "pConvertDfbSurfaceToDib: pSurf is a redirection surface");
  645. //
  646. // GDI surfaces wrapped around DirectDraw surfaces cannot be
  647. // converted (DirectDraw wouldn't know about its new state).
  648. //
  649. // Similarly, we can't convert surfaces that are the primary
  650. // screen!
  651. //
  652. if (pSurfOld->bDirectDraw() || pSurfOld->bPDEVSurface())
  653. {
  654. return(NULL);
  655. }
  656. //
  657. // Create a DIB (dimoCvt) with the same height,width,
  658. // and BPP as the DEVBITMAP attached to the DC and
  659. // then replace the DEVBITMAP with the DIB
  660. //
  661. SURFMEM dimoCvt;
  662. DEVBITMAPINFO dbmi;
  663. ERECTL ercl(0, 0, pSurfOld->sizl().cx, pSurfOld->sizl().cy);
  664. PDEVOBJ po(hdev);
  665. //
  666. // Figure out what format the engine should use by looking at the
  667. // size of palette. This is a clone from CreateCompatibleBitmap().
  668. //
  669. dbmi.iFormat = pSurfOld->iFormat();
  670. dbmi.cxBitmap = pSurfOld->sizl().cx;
  671. dbmi.cyBitmap = pSurfOld->sizl().cy;
  672. dbmi.hpal = 0;
  673. dbmi.fl = BMF_TOPDOWN;
  674. if (dimoCvt.bCreateDIB(&dbmi, NULL))
  675. {
  676. pSurfNew = dimoCvt.ps;
  677. //
  678. // Fill in other necessary fields
  679. //
  680. ASSERTGDI(pSurfOld->hdev() == hdev, "hdev's don't match");
  681. pSurfNew->hdev(hdev);
  682. //
  683. // Copy the area as big as the bitmap
  684. //
  685. if ((*PPFNGET(po, CopyBits, pSurfOld->flags()))
  686. (
  687. dimoCvt.pSurfobj(), // destination surface
  688. pSurfOld->pSurfobj(), // source surface
  689. (CLIPOBJ *)NULL, // clip object
  690. &xloIdent, // palette translation object
  691. (RECTL *) &ercl, // destination rectangle
  692. (POINTL *) &ercl // source origin
  693. ))
  694. {
  695. MLOCKOBJ mlo;
  696. LONG SurfTargShareCount;
  697. SurfTargShareCount = HmgQueryAltLock((HOBJ)pSurfOld->hsurf());
  698. if (SurfTargShareCount == ExpectedShareCount)
  699. {
  700. BOOL bStockSurface = pSurfOld->bStockSurface();
  701. BOOL bUndoStockSurfaceDelayed = pSurfOld->bUndoStockSurfaceDelayed();
  702. if (HmgSwapLockedHandleContents((HOBJ)pSurfOld->hsurf(),
  703. SurfTargShareCount,
  704. (HOBJ)pSurfNew->hsurf(),
  705. HmgQueryAltLock((HOBJ)pSurfNew->hsurf()),
  706. SURF_TYPE))
  707. {
  708. //
  709. // Swap necessary fields between the bitmaps
  710. // hsurf, hdc, cRef, hpalHint, sizlDim, ppal, SurfFlags
  711. //
  712. HSURF hsurfTemp = pSurfOld->hsurf();
  713. pSurfOld->hsurf(pSurfNew->hsurf());
  714. pSurfNew->hsurf(hsurfTemp);
  715. HDC hdcTemp = pSurfOld->hdc();
  716. pSurfOld->hdc(pSurfNew->hdc());
  717. pSurfNew->hdc(hdcTemp);
  718. ULONG cRefTemp = pSurfOld->cRef();
  719. pSurfOld->cRef(pSurfNew->cRef());
  720. pSurfNew->cRef(cRefTemp);
  721. HPALETTE hpalTemp = pSurfOld->hpalHint();
  722. pSurfOld->hpalHint(pSurfNew->hpalHint());
  723. pSurfNew->hpalHint(hpalTemp);
  724. SIZEL sizlTemp = pSurfOld->sizlDim();
  725. pSurfOld->sizlDim(pSurfNew->sizlDim());
  726. pSurfNew->sizlDim(sizlTemp);
  727. PPALETTE ppalTemp = pSurfOld->ppal();
  728. pSurfOld->ppal(pSurfNew->ppal());
  729. pSurfNew->ppal(ppalTemp);
  730. FLONG flagsTemp = pSurfOld->flags();
  731. pSurfOld->flags((pSurfOld->flags() & ~SURF_FLAGS) | (pSurfNew->flags() & SURF_FLAGS));
  732. pSurfNew->flags((pSurfNew->flags() & ~SURF_FLAGS) | (flagsTemp & SURF_FLAGS));
  733. //
  734. // Some flags have to stay with the original surface,
  735. // so swap them yet again to go back to the original:
  736. //
  737. #define KEEP_FLAGS ENG_CREATE_DEVICE_SURFACE
  738. flagsTemp = pSurfOld->flags();
  739. pSurfOld->flags((pSurfOld->flags() & ~KEEP_FLAGS) | (pSurfNew->flags() & KEEP_FLAGS));
  740. pSurfNew->flags((pSurfNew->flags() & ~KEEP_FLAGS) | (flagsTemp & KEEP_FLAGS));
  741. #if TRACE_SURFACE_ALLOCS
  742. // We don't care about copying the current allocation trace
  743. // to the old object.
  744. if (TRACED_SURFACE::bEnabled())
  745. {
  746. TRACED_SURFACE *ptsOld = (TRACED_SURFACE *)pSurfOld;
  747. TRACED_SURFACE *ptsNew = (TRACED_SURFACE *)pSurfNew;
  748. ptsNew->Trace = ptsOld->Trace;
  749. #if TRACE_SURFACE_USER_CHAIN_IN_UM
  750. // pUser values were swapped in HmgSwapLockedHandleContents.
  751. // Swap them back since object owners weren't swapped.
  752. // It doesn't matter if TRACED_SURFACE::bUserChainInUM
  753. // is enable, since pUser is unused if not enabled.
  754. PENTRY pEntryOld = &gpentHmgr[HmgIfromH(pSurfOld->hGet())];
  755. PENTRY pEntryNew = &gpentHmgr[HmgIfromH(pSurfNew->hGet())];
  756. PVOID pUserTemp = pEntryOld->pUser;
  757. pEntryOld->pUser = pEntryNew->pUser;
  758. pEntryNew->pUser = pUserTemp;
  759. #endif
  760. }
  761. #endif
  762. if (bStockSurface)
  763. {
  764. DC* pdc;
  765. HOBJ hObj = 0;
  766. pSurfOld->vClearStockSurface();
  767. pSurfNew->vSetStockSurface();
  768. STOCKINFO("Transfer Stock Bitmap State from %p to %p\n", pSurfOld, pSurfNew);
  769. if (bUndoStockSurfaceDelayed)
  770. {
  771. STOCKINFO("Transfer Delayed Undo Stock Bitmap State from %p to %p\n", pSurfOld, pSurfNew);
  772. pSurfNew->vSetUndoStockSurfaceDelayed();
  773. }
  774. // As its a Stock surface it may be selected into many DCs. Run thru all of them
  775. // and replace with new .
  776. while (pdc = (DC*) HmgSafeNextObjt(hObj, DC_TYPE))
  777. {
  778. hObj = (HOBJ)pdc->hGet();
  779. if ((pdc->pSurface() == pSurfOld))
  780. {
  781. STOCKINFO("Updating DC (%p) which refs old stockbmp %p with new stockbmp %p\n", pdc, pSurfOld, pSurfNew);
  782. pdc->flbrushAdd(DIRTY_BRUSHES);
  783. pdc->pSurface(pSurfNew);
  784. MDCOBJA dco((HDC)hObj);
  785. LONG lNumLeft = dco.lSaveDepth();
  786. HDC hdcSave = dco.hdcSave();
  787. while (lNumLeft > 1)
  788. {
  789. MDCOBJA dcoTmp(hdcSave);
  790. if (dcoTmp.pSurface() == pSurfOld)
  791. {
  792. dcoTmp.pdc->pSurface(pSurfNew);
  793. }
  794. lNumLeft = dcoTmp.lSaveDepth();
  795. hdcSave = dcoTmp.hdcSave();
  796. }
  797. }
  798. }
  799. }
  800. //
  801. // Destroy the DFB
  802. //
  803. // If the deletion fails, we're toast, since a bad,
  804. // stale surface will have been left in the handle
  805. // table. So on the next mode-change, when we walk
  806. // the table looking at all surfaces belonging to
  807. // this HDEV, we'd crash.
  808. //
  809. mlo.vDisable();
  810. b = pSurfOld->bDeleteSurface();
  811. ASSERTGDI(b, "A bad surface is left in handle table");
  812. //
  813. // Keep a reference to the new surface.
  814. //
  815. dimoCvt.vKeepIt();
  816. dimoCvt.ps = NULL;
  817. pSurfRet = pSurfNew;
  818. }
  819. else
  820. {
  821. WARNING("pConvertDfbSurfaceToDib failed to swap bitmap handles\n");
  822. }
  823. }
  824. else
  825. {
  826. WARNING("pConvertDfbSurfaceToDib someone else is holding a lock\n");
  827. }
  828. }
  829. else
  830. {
  831. WARNING("pConvertDfbSurfaceToDib failed copying DFB to DIB\n");
  832. }
  833. }
  834. return(pSurfRet);
  835. }
  836. /******************************Private*Routine*****************************\
  837. * BOOL bConvertDfbDcToDib
  838. *
  839. * Converts a compatible bitmap that is currently selected into a DC
  840. * into an engine managed bitmap.
  841. *
  842. * The Devlock must already be held. Some sort of lock must also be held
  843. * to prevent SaveDC/RestoreDC operations from occuring -- either via an
  844. * exclusive DC lock or some other lock.
  845. *
  846. * History:
  847. * Wed 5-May-1994 -by- Tom Zakrajsek [tomzak]
  848. * Wrote it (with lot's of help from PatrickH and EricK).
  849. \*************************************************************************/
  850. BOOL bConvertDfbDcToDib
  851. (
  852. XDCOBJ * pdco
  853. )
  854. {
  855. SURFACE *pSurfOld;
  856. SURFACE *pSurfNew;
  857. ASSERTDEVLOCK(pdco->pdc);
  858. pSurfOld = pdco->pSurface();
  859. pSurfNew = pConvertDfbSurfaceToDib(pdco->hdev(),
  860. pSurfOld,
  861. pSurfOld->cRef());
  862. if (pSurfNew)
  863. {
  864. //
  865. // Make sure that the surface pointers in any EBRUSHOBJ's get
  866. // updated, by ensuring that vInitBrush() gets called the next
  867. // time any brush is used in this DC.
  868. //
  869. pdco->pdc->flbrushAdd(DIRTY_BRUSHES);
  870. //
  871. // Replace the pSurf reference in the DCLEVEL
  872. //
  873. pdco->pdc->pSurface(pSurfNew);
  874. //
  875. // Walk the saved DC chain
  876. //
  877. LONG lNumLeft = pdco->lSaveDepth();
  878. HDC hdcSave = pdco->hdcSave();
  879. while (lNumLeft > 1)
  880. {
  881. MDCOBJA dcoTmp(hdcSave);
  882. //
  883. // Replace all references to pSurfOld with references to pSurfNew
  884. //
  885. if (dcoTmp.pSurface() == pSurfOld)
  886. {
  887. dcoTmp.pdc->pSurface(pSurfNew);
  888. }
  889. lNumLeft = dcoTmp.lSaveDepth();
  890. hdcSave = dcoTmp.hdcSave();
  891. }
  892. }
  893. return(pSurfNew != NULL);
  894. }