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.

2071 lines
58 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: dcgdi.cxx
  3. *
  4. * APIs for GDI DC component
  5. *
  6. * Created: 13-Aug-1990 00:15:53
  7. * Author: Donald Sidoroff [donalds]
  8. *
  9. * Copyright (c) 1990-1999 Microsoft Corporation
  10. \**************************************************************************/
  11. #include "precomp.hxx"
  12. BOOL bSavePath(XDCOBJ& dco, LONG lSave);
  13. BOOL bSaveRegion(DCOBJ&, LONG);
  14. VOID vRestorePath(XDCOBJ& dco, LONG lSave);
  15. VOID vRestoreRegion(DCOBJ&, LONG);
  16. typedef BOOL (*SFN)(DCOBJ&, LONG); // Save function type
  17. typedef VOID (*RFN)(DCOBJ&, LONG); // Restore function type
  18. /******************************Public*Routine******************************\
  19. * bDeleteDCInternal
  20. *
  21. * bForce - This is set to TRUE when user calls through GreDeleteDC and
  22. * FALSE when the app calls through th client server window
  23. *
  24. * API entry point to delete a DC.
  25. *
  26. * History:
  27. * Thu 12-Sep-1991 -by- Patrick Haluptzok [patrickh]
  28. * clean it up, query User for deletability, cascade if's for code size.
  29. *
  30. * Fri 12-Jul-1991 -by- Patrick Haluptzok [patrickh]
  31. * added deletion of regions
  32. *
  33. * 18-Jun-1991 -by- Patrick Haluptzok patrickh
  34. * Wrote it.
  35. \**************************************************************************/
  36. BOOL
  37. bDeleteDCInternal(
  38. HDC hdc,
  39. BOOL bForce,
  40. BOOL bProcessCleanup)
  41. {
  42. BOOL bReturn = FALSE;
  43. // Lock it down, since this is an API lock no apps can get at it. We just
  44. // have to worry about USER having it Alt-locked now.
  45. DCOBJ dco(hdc);
  46. if (dco.bValid())
  47. {
  48. // We can do a cleanDC without affecting USER.
  49. dco.bCleanDC();
  50. // Check if User has marked the DC as undeletable or bForce is set.
  51. // bForce should only be set when user asks us to delete the dc.
  52. if (bForce || dco.bIsDeleteable())
  53. {
  54. // free client attr
  55. if (!bProcessCleanup)
  56. {
  57. GreFreeDCAttributes(hdc);
  58. }
  59. // ASSERTGDI(dco.bIsDeleteable(), "User is freeing an undeletable DC");
  60. // Decrement the reference count on the brushes in the old DC.
  61. // we do not dec the ref cnt of a brush from the client side
  62. // since sync brush never inc the ref cnt
  63. DEC_SHARE_REF_CNT_LAZY0(dco.pdc->pbrushFill());
  64. DEC_SHARE_REF_CNT_LAZY0(dco.pdc->pbrushLine());
  65. // We now need to do the same thing for the selected font
  66. DEC_SHARE_REF_CNT_LAZY_DEL_LOGFONT(dco.pdc->plfntNew());
  67. // And then color space, too
  68. DEC_SHARE_REF_CNT_LAZY_DEL_COLORSPACE(dco.pdc->pColorSpace());
  69. // Ok we are golden now. User has no holds on this DC.
  70. // Remember our PDEV.
  71. PDEVOBJ po(dco.hdev());
  72. dco.pdc->vReleaseVis();
  73. dco.pdc->vReleaseRao();
  74. if (dco.pdc->prgnRao())
  75. {
  76. dco.pdc->prgnRao()->vDeleteREGION();
  77. }
  78. // Free the memory for the DC. We don't even need to do this
  79. // under a multi-lock because we have an API lock so no other
  80. // App threads can come in and User has said that it is deleteable
  81. // and they are the only dudes who could get us with an Alt-Lock.
  82. // we may still hold a dc lock when the user mode printer driver
  83. // abnomally terminates. Ignore the counts.
  84. if (!po.bUMPD())
  85. {
  86. ASSERTGDI(HmgQueryLock((HOBJ)hdc) == 1, "bDeleteDC cLock != 1");
  87. ASSERTGDI(HmgQueryAltLock((HOBJ)hdc) == 0, "bDeleteDC cAltLock != 0");
  88. }
  89. // delete DC from handle manager.
  90. dco.bDeleteDC(bProcessCleanup);
  91. // Remove the reference to the PDEV.
  92. po.vUnreferencePdev(bProcessCleanup ? CLEANUP_PROCESS
  93. : CLEANUP_NONE);
  94. // Return success.
  95. bReturn = TRUE;
  96. }
  97. else
  98. {
  99. // User now maps CreateDC -> GetDC so that all DC's get clipped
  100. // to the same Desktop. We now have to check here and give User
  101. // a chance to clean it up.
  102. dco.vUnlock();
  103. if (UserReleaseDC(hdc))
  104. {
  105. bReturn = TRUE;
  106. }
  107. else
  108. {
  109. WARNING("FAILED to delete because it is a NON-DeletableDC\n");
  110. }
  111. }
  112. }
  113. else
  114. {
  115. // Some other thread has it locked down so fail.
  116. SAVE_ERROR_CODE(ERROR_BUSY);
  117. }
  118. return(bReturn);
  119. }
  120. BOOL
  121. GreDeleteDC(
  122. HDC hdc)
  123. {
  124. return(bDeleteDCInternal(hdc,TRUE,FALSE));
  125. }
  126. /******************************Public*Routine******************************\
  127. * BOOL GreRestoreDC(hdc, lDC)
  128. *
  129. * Restore the DC.
  130. *
  131. * History:
  132. * Mon 15-Jul-1991 -by- Patrick Haluptzok [patrickh]
  133. * bug fix, delete the DC when done with it.
  134. *
  135. * Tue 18-Jun-1991 -by- Patrick Haluptzok [patrickh]
  136. * added the brush, palette, pen, and bitmap cases.
  137. *
  138. * 13-Aug-1990 -by- Donald Sidoroff [donalds]
  139. * Wrote it.
  140. \**************************************************************************/
  141. BOOL GreRestoreDC(HDC hdc,int lDC)
  142. {
  143. DCOBJ dco(hdc); // Lock the DC
  144. BOOL bRet = TRUE;
  145. if (!dco.bValid())
  146. {
  147. SAVE_ERROR_CODE(ERROR_INVALID_HANDLE);
  148. bRet = FALSE;
  149. }
  150. else
  151. {
  152. // !! What the heck is this SYNC_DRAWING_ATTRS doing here?
  153. SYNC_DRAWING_ATTRS(dco.pdc);
  154. if (lDC < 0)
  155. lDC += (int)dco.lSaveDepth();
  156. if ((lDC < 1) || (lDC >= dco.lSaveDepth()))
  157. {
  158. SAVE_ERROR_CODE(ERROR_INVALID_PARAMETER);
  159. bRet = FALSE;
  160. }
  161. else
  162. {
  163. PDEVOBJ po(dco.hdev());
  164. // Acquire the devlock here to protect against dynamic mode changes
  165. // that affect the device palette. This also protects us if the
  166. // bitmap which selected in DC, is a Device Format Bitmap that is
  167. // owned by the display driver.
  168. DEVLOCKOBJ dlo(po);
  169. // Acquire the semaphore palette to be symmetrical with GreSaveDC
  170. // and to protect the dynamic mode change code as it walks all
  171. // the DC's, so that its changes don't get wiped out by the
  172. // vCopyTo we're about to do.
  173. SEMOBJ semo(ghsemPalette);
  174. // if we are printing using a TempInfoDC, save it. Since there is only one
  175. // of these that does not sit in the dclevel, we save and restore this state
  176. // accross save/restoreDC
  177. BOOL bTempInfoDC = dco.pdc->bTempInfoDC();
  178. if (bTempInfoDC)
  179. dco.pdc->bMakeInfoDC(FALSE);
  180. // Remember current mapping mode.
  181. ULONG ulMapModeDC = dco.pdc->ulMapMode();
  182. do
  183. {
  184. // Decrement the reference count on the brushes in the old DC.
  185. // We do not DEC the ref cnt of a brush from the client side
  186. // since sync brush never INCs the ref cnt
  187. DEC_SHARE_REF_CNT_LAZY0(dco.pdc->pbrushFill());
  188. DEC_SHARE_REF_CNT_LAZY0(dco.pdc->pbrushLine());
  189. // same thing for currently selected font:
  190. DEC_SHARE_REF_CNT_LAZY_DEL_LOGFONT(dco.pdc->plfntNew());
  191. // same thing for currently selected color space:
  192. DEC_SHARE_REF_CNT_LAZY_DEL_COLORSPACE(dco.pdc->pColorSpace());
  193. // Restore Regions and Paths.
  194. vRestoreRegion(dco, dco.lSaveDepth() - 1);
  195. vRestorePath(dco, dco.lSaveDepth() - 1);
  196. // Restore the bitmaps if necesary.
  197. if (dco.dctp() == DCTYPE_MEMORY)
  198. {
  199. hbmSelectBitmap(hdc, STOCKOBJ_BITMAP, TRUE);
  200. }
  201. // Bug #223129: We need to get a lock on the saved DC even when the process
  202. // has reached its handle quota (this is OK because the saved DC is about to
  203. // be deleted anyway). This is accomplished using the vLockAllOwners method
  204. // of the DCOBJ.
  205. DCOBJ dcoSaved;
  206. dcoSaved.vLockAllOwners(dco.hdcSave());
  207. ASSERTGDI(dcoSaved.bValid(),"GreRestoreDC(): dcoSaved is invalid\n");
  208. // Select the palette in if necessary. This will put the palette back in
  209. // the DC chain.
  210. if (dco.hpal() != dcoSaved.hpal())
  211. {
  212. GreSelectPalette((HDC)hdc, (HPALETTE)dcoSaved.ppal()->hGet(), TRUE);
  213. }
  214. else
  215. {
  216. // hpals are equal:
  217. //
  218. // ResizePalette could have changed the ppal associated with the
  219. // hpal, in this case fix the ppal
  220. if (dco.ppal() != dcoSaved.ppal())
  221. {
  222. EPALOBJ palRestore((HPALETTE)dco.hpal());
  223. if (dco.ppal() != palRestore.ppalGet())
  224. {
  225. RIP("GRE RestoreDC - hpal and ppal in invalid state");
  226. }
  227. // fix ppal in dcoSaved
  228. dcoSaved.pdc->ppal(palRestore.ppalGet());
  229. }
  230. }
  231. // Decrement its reference count if it's not the default palette. We
  232. // inced it while it's in a saved DC level to prevent it from being deleted.
  233. if (dcoSaved.ppal() != ppalDefault)
  234. {
  235. XEPALOBJ palTemp(dcoSaved.ppal());
  236. palTemp.vDec_cRef();
  237. }
  238. // Update the DC with saved information, then delete the saved level.
  239. dcoSaved.pdc->vCopyTo(dco);
  240. dcoSaved.bDeleteDC();
  241. } while (lDC < dco.lSaveDepth());
  242. // if mapping mode has been changed, invalidate xform.
  243. if (ulMapModeDC != dco.pdc->ulMapMode())
  244. dco.pdc->vXformChange(TRUE);
  245. // if we are printing using a TempInfoDC, restore it
  246. if (bTempInfoDC)
  247. dco.pdc->bMakeInfoDC(TRUE);
  248. // Assume Rao has been made dirty by the above work.
  249. dco.pdc->vReleaseRao();
  250. dco.pdc->vUpdate_VisRect(dco.pdc->prgnVis());
  251. // Assume the brushes, charset, color space and color transform are dirty.
  252. dco.ulDirtyAdd(DIRTY_BRUSHES|DIRTY_CHARSET|DIRTY_COLORSPACE|DIRTY_COLORTRANSFORM);
  253. if (dco.dctp() == DCTYPE_MEMORY)
  254. {
  255. dco.pdc->bSetDefaultRegion();
  256. }
  257. // Correctly set the bit indicating whether or not we need to
  258. // grab the Devlock before drawing
  259. SURFACE *pSurfCurrent = dco.pSurface();
  260. //
  261. // Note that this condition should match that of GreSelectBitmap
  262. // for the memory DC case:
  263. //
  264. if (dco.bDisplay() ||
  265. ((dco.dctp() == DCTYPE_MEMORY) &&
  266. (pSurfCurrent != NULL) &&
  267. (
  268. (pSurfCurrent->bUseDevlock()) ||
  269. (pSurfCurrent->bDeviceDependentBitmap() && po.bDisplayPDEV())
  270. )
  271. )
  272. )
  273. {
  274. dco.bSynchronizeAccess(TRUE);
  275. dco.bShareAccess(pSurfCurrent->bShareAccess());
  276. }
  277. else
  278. {
  279. dco.bSynchronizeAccess(FALSE);
  280. }
  281. // Update ptlFillOrigin accelerator
  282. dco.pdc->vCalcFillOrigin();
  283. }
  284. }
  285. return(bRet);
  286. }
  287. /*********************************Class************************************\
  288. * class SAVEOBJ
  289. *
  290. * This is just a call to a save/restore function pair disguised to look
  291. * like a memory object. The restore will happen automagically when the
  292. * scope is exitted, unless told not to do so.
  293. *
  294. * Note:
  295. * This is used only by GreSaveDC
  296. *
  297. * History:
  298. * 23-Apr-1991 -by- Donald Sidoroff [donalds]
  299. * Wrote it.
  300. \**************************************************************************/
  301. class SAVEOBJ /* svo */
  302. {
  303. private:
  304. LONG lLevel;
  305. BOOL bSave;
  306. DCOBJ *pdco;
  307. RFN rfn; // Restore function
  308. public:
  309. SAVEOBJ(DCOBJ& dco, LONG lLevel_, SFN sfn, RFN rfn_)
  310. {
  311. pdco = &dco;
  312. lLevel = lLevel_;
  313. rfn = rfn_;
  314. bSave = (*sfn)(dco, lLevel_ + 1);
  315. }
  316. ~SAVEOBJ()
  317. {
  318. if (bSave)
  319. (*rfn)(*pdco, lLevel);
  320. }
  321. BOOL bValid() { return(bSave); }
  322. VOID vKeepIt() { bSave = FALSE; }
  323. };
  324. /*********************************Class************************************\
  325. * class DCMODOBJ
  326. *
  327. * This class modifies the given DC. It will undo the modification, unless
  328. * told to keep it.
  329. *
  330. * Note:
  331. * This is used only by GreSaveDC
  332. *
  333. * History:
  334. * 23-Apr-1991 -by- Donald Sidoroff [donalds]
  335. * Wrote it.
  336. \**************************************************************************/
  337. class DCMODOBJ /* dcmod */
  338. {
  339. private:
  340. DCOBJ *pdco;
  341. HDC hdcSaveOld;
  342. public:
  343. DCMODOBJ(DCOBJ& dco, HDC hdcSave)
  344. {
  345. pdco = &dco;
  346. hdcSaveOld = dco.hdcSave();
  347. dco.pdc->hdcSave(hdcSave);
  348. }
  349. ~DCMODOBJ()
  350. {
  351. if (pdco != (DCOBJ *) NULL)
  352. pdco->pdc->hdcSave(hdcSaveOld);
  353. }
  354. VOID vKeepIt() { pdco = (DCOBJ *) NULL; }
  355. };
  356. /******************************Public*Routine******************************\
  357. * int GreSaveDC(hdc)
  358. *
  359. * Save the DC.
  360. *
  361. * History:
  362. * Tue 25-Jun-1991 -by- Patrick Haluptzok [patrickh]
  363. * add saving bitmaps, palettes.
  364. *
  365. * 13-Aug-1990 -by- Donald Sidoroff [donalds]
  366. * Wrote it.
  367. \**************************************************************************/
  368. int GreSaveDC(HDC hdc)
  369. {
  370. DCOBJ dco(hdc); // Lock down the DC
  371. LONG lSave;
  372. int iRet = 0;
  373. if (!dco.bValid())
  374. {
  375. SAVE_ERROR_CODE(ERROR_INVALID_HANDLE);
  376. }
  377. else
  378. {
  379. SYNC_DRAWING_ATTRS(dco.pdc);
  380. PDEVOBJ po(dco.hdev());
  381. // Acquire the devlock here to protect against dynamic mode changes
  382. // that affect the device palette. This also protects us if the
  383. // bitmap which selected in DC, is a Device Format Bitmap that is
  384. // owned by the display driver.
  385. DEVLOCKOBJ dlo(po);
  386. // We must grab the semaphore now so that ResizePalette doesn't
  387. // change the ppal in the DC before the copy is added to the list
  388. // off the palette. Also grab it to prevent the dynamic mode
  389. // changing code from falling over when it traverses saved DCs.
  390. SEMOBJ semo(ghsemPalette);
  391. // if we are printing using a TempInfoDC, save it. Since there is only one
  392. // of these that does not sit in the dclevel, we save and restore this state
  393. // accross save/restoreDC
  394. BOOL bTempInfoDC = dco.pdc->bTempInfoDC();
  395. if (bTempInfoDC)
  396. dco.pdc->bMakeInfoDC(FALSE);
  397. {
  398. DCMEMOBJ dcmo(dco); // Allocate RAM and copy the DC
  399. if (!dcmo.bValid())
  400. {
  401. SAVE_ERROR_CODE(ERROR_NOT_ENOUGH_MEMORY);
  402. }
  403. else
  404. {
  405. DCMODOBJ dcmod(dco, dcmo.hdc());
  406. SAVEOBJ svoPath(dco, dcmo.lSaveDepth(), (SFN)bSavePath, (RFN)vRestorePath);
  407. if (svoPath.bValid())
  408. {
  409. SAVEOBJ svoRgn(dco, dcmo.lSaveDepth(), bSaveRegion, vRestoreRegion);
  410. if (svoRgn.bValid())
  411. {
  412. // we are done with the objects so we can now set the owner to none
  413. // so this thing can't be deleted.
  414. if (!GreSetDCOwner(dcmo.hdc(),OBJECT_OWNER_NONE))
  415. {
  416. WARNING("GreSaveDC - couldn't set owner\n");
  417. }
  418. else
  419. {
  420. // At this point we are golden. No more errors can occur,
  421. // so we mark all the things we've allocated as permanent.
  422. svoRgn.vKeepIt();
  423. svoPath.vKeepIt();
  424. dcmod.vKeepIt();
  425. dcmo.vKeepIt();
  426. // Inc the surface ref count if appropriate
  427. if (dcmo.pSurface() != (SURFACE *) NULL)
  428. {
  429. if ((!dcmo.pSurface()->bPDEVSurface()) && (!dcmo.pSurface()->bRedirection()))
  430. {
  431. dcmo.pSurface()->vInc_cRef();
  432. }
  433. }
  434. // Increment the reference count on the brushes we saved.
  435. // No need to check ownership, since these are already
  436. // selected in
  437. INC_SHARE_REF_CNT(dco.pdc->pbrushFill());
  438. INC_SHARE_REF_CNT(dco.pdc->pbrushLine());
  439. // inc ref count for the font selected in the dc
  440. INC_SHARE_REF_CNT(dco.pdc->plfntNew());
  441. // int ref count for the color space selected in the dc
  442. INC_SHARE_REF_CNT(dco.pdc->pColorSpace());
  443. // Take care of the palette.
  444. // Increment its reference count if it's not the default palette. We
  445. // inc it while it's in a saved DC level to prevent it from being deleted.
  446. if (dco.ppal() != ppalDefault)
  447. {
  448. XEPALOBJ palTemp(dco.ppal());
  449. ASSERTGDI(palTemp.bValid(), "ERROR SaveDC not valid palette");
  450. palTemp.vInc_cRef();
  451. }
  452. // Increment and return the save level of the original DC.
  453. lSave = dco.lSaveDepth();
  454. dco.pdc->lIncSaveDepth();
  455. iRet = (int)lSave;
  456. } // GreSetDCOwner
  457. } //
  458. } // ~SAVEOBJ svoRgn
  459. } // ~DCMODOBJ dcmod
  460. } // ~DCMEMOBJ dcmo
  461. // if we are printing using a TempInfoDC, restore it
  462. if (bTempInfoDC)
  463. dco.pdc->bMakeInfoDC(TRUE);
  464. }
  465. return(iRet);
  466. }
  467. /******************************Public*Routine******************************\
  468. * BOOL GreSetDCOrg(hdc,x,y,prlc)
  469. *
  470. * Set the origin and optionally the window area of the DC.
  471. *
  472. * History:
  473. * 19-Oct-1996 -by- J. Andrew Goossen [andrewgo]
  474. * Wrote it.
  475. \**************************************************************************/
  476. BOOL GreSetDCOrg(HDC hdc,LONG x,LONG y,PRECTL prcl)
  477. {
  478. BOOL bRet = FALSE;
  479. DCOBJA dco(hdc);
  480. ASSERTDEVLOCK(dco.pdc);
  481. if (dco.bValid())
  482. {
  483. bRet = TRUE;
  484. dco.eptlOrigin().x = x;
  485. dco.eptlOrigin().y = y;
  486. dco.pdc->vCalcFillOrigin();
  487. if (prcl != NULL)
  488. {
  489. dco.erclWindow() = *(ERECTL *) prcl;
  490. }
  491. }
  492. return(bRet);
  493. }
  494. /******************************Public*Routine******************************\
  495. * BOOL GreGetDCOrg(hdc,pptl)
  496. *
  497. * Get the origin of the DC.
  498. *
  499. * History:
  500. * Sun 02-Jan-1994 -by- Patrick Haluptzok [patrickh]
  501. * smaller and faster
  502. *
  503. * 13-Aug-1990 -by- Donald Sidoroff [donalds]
  504. * Wrote it.
  505. \**************************************************************************/
  506. BOOL GreGetDCOrg(HDC hdc,LPPOINT pptl)
  507. {
  508. return(GreGetDCPoint(hdc,DCPT_DCORG,(PPOINTL)pptl));
  509. }
  510. /******************************Public*Routine******************************\
  511. * BOOL GreGetDCOrgEx(hdc,ppt,prcl)
  512. *
  513. * History:
  514. * 12-Dec-1997 -by- Vadim Gorokhovsky [vadimg]
  515. * Wrote it.
  516. \**************************************************************************/
  517. BOOL GreGetDCOrgEx(HDC hdc,PPOINT ppt,PRECT prc)
  518. {
  519. DCOBJA dco(hdc);
  520. if (dco.bValid())
  521. {
  522. *(ERECTL *)prc = dco.erclWindow();
  523. return(GreGetDCPoint(hdc,DCPT_DCORG,(PPOINTL)ppt));
  524. }
  525. return(FALSE);
  526. }
  527. /******************************Public*Routine******************************\
  528. * BOOL GreGetBounds(hdc, prcl, fl)
  529. *
  530. * Return the current bounds information and reset the bounding area.
  531. *
  532. * WARNING: USER MUST HOLD THE DEVICE LOCK BEFORE CALLING THIS ROUTINE
  533. *
  534. * History:
  535. * 28-Jul-1991 -by- Donald Sidoroff [donalds]
  536. * Wrote it.
  537. \**************************************************************************/
  538. BOOL GreGetBounds(HDC hdc, LPRECT prcl, DWORD fl)
  539. {
  540. DCOBJA doa(hdc);
  541. ERECTL erclScreen;
  542. BOOL bEmpty;
  543. if (!doa.bValid())
  544. {
  545. bEmpty = TRUE; // bEmpty == TRUE is the error condition
  546. }
  547. else
  548. {
  549. if (fl & GGB_ENABLE_WINMGR)
  550. {
  551. doa.fsSet(DC_ACCUM_WMGR);
  552. }
  553. else if (fl & GGB_DISABLE_WINMGR)
  554. {
  555. doa.fsClr(DC_ACCUM_WMGR);
  556. }
  557. // Get the state of the bounds rectangle
  558. bEmpty = (doa.erclBounds().bEmpty() ||
  559. doa.erclBounds().bWrapped());
  560. if (!bEmpty)
  561. {
  562. if (prcl != (LPRECT) NULL)
  563. {
  564. erclScreen = doa.erclBounds();
  565. erclScreen += doa.eptlOrigin();
  566. *prcl = *((LPRECT) &erclScreen);
  567. }
  568. // Force it to be empty
  569. doa.erclBounds().left = POS_INFINITY;
  570. doa.erclBounds().top = POS_INFINITY;
  571. doa.erclBounds().right = NEG_INFINITY;
  572. doa.erclBounds().bottom = NEG_INFINITY;
  573. }
  574. }
  575. return(!bEmpty);
  576. }
  577. /******************************Public*Routine******************************\
  578. * BOOL GreGetBoundsRect(hdc, prcl, fl)
  579. *
  580. * Return the current bounds info.
  581. *
  582. * History:
  583. * Thu 27-May-1993 -by- Patrick Haluptzok [patrickh]
  584. * Change to exclusive lock, not a special User call.
  585. *
  586. * 06-Apr-1992 -by- Donald Sidoroff [donalds]
  587. * Wrote it.
  588. \**************************************************************************/
  589. DWORD GreGetBoundsRect(HDC hdc, LPRECT prcl, DWORD fl)
  590. {
  591. DCOBJ dco(hdc);
  592. DWORD dwRet = DCB_SET;
  593. if (!dco.bValid())
  594. {
  595. dwRet = 0;
  596. }
  597. else
  598. {
  599. ERECTL *percl;
  600. if (fl & DCB_WINDOWMGR)
  601. {
  602. if (dco.erclBounds().bWrapped())
  603. {
  604. dwRet = DCB_RESET;
  605. }
  606. else
  607. {
  608. percl = &dco.erclBounds();
  609. *prcl = *((LPRECT) percl);
  610. }
  611. }
  612. else
  613. {
  614. if (dco.erclBoundsApp().bWrapped())
  615. {
  616. dwRet = DCB_RESET;
  617. }
  618. else
  619. {
  620. DEVLOCKOBJ dlo(dco);
  621. if (!dlo.bValid())
  622. {
  623. dwRet = dco.bFullScreen() ? DCB_RESET : 0;
  624. }
  625. else
  626. {
  627. RGNOBJ ro(dco.prgnEffRao());
  628. ERECTL ercl;
  629. ro.vGet_rcl(&ercl);
  630. ercl -= dco.eptlOrigin();
  631. percl = &dco.erclBoundsApp();
  632. prcl->left = MAX(percl->left, ercl.left);
  633. prcl->right = MIN(percl->right, ercl.right);
  634. prcl->top = MAX(percl->top, ercl.top);
  635. prcl->bottom = MIN(percl->bottom, ercl.bottom);
  636. EXFORMOBJ exoDtoW(dco, DEVICE_TO_WORLD);
  637. if (!exoDtoW.bValid())
  638. {
  639. dwRet = 0;
  640. }
  641. else if (!exoDtoW.bRotation())
  642. {
  643. if (!exoDtoW.bXform((POINTL *) prcl, 2))
  644. dwRet = 0;
  645. }
  646. else
  647. {
  648. POINTL apt[4];
  649. *((RECT *)apt) = *prcl;
  650. apt[2].x = prcl->left;
  651. apt[2].y = prcl->bottom;
  652. apt[3].x = prcl->right;
  653. apt[3].y = prcl->top;
  654. if (!exoDtoW.bXform(apt, 4))
  655. {
  656. dwRet = 0;
  657. }
  658. else
  659. {
  660. prcl->left = MIN4(apt[0].x,apt[1].x,apt[2].x,apt[3].x);
  661. prcl->right = MAX4(apt[0].x,apt[1].x,apt[2].x,apt[3].x);
  662. prcl->top = MIN4(apt[0].y,apt[1].y,apt[2].y,apt[3].y);
  663. prcl->bottom = MAX4(apt[0].y,apt[1].y,apt[2].y,apt[3].y);
  664. }
  665. }
  666. }
  667. }
  668. }
  669. if ((dwRet == DCB_SET) && (fl & DCB_RESET))
  670. {
  671. percl->left = percl->top = POS_INFINITY;
  672. percl->right = percl->bottom = NEG_INFINITY;
  673. }
  674. }
  675. return(dwRet);
  676. }
  677. /******************************Public*Routine******************************\
  678. * BOOL GreSetBoundsRect(hdc, prcl, fl)
  679. *
  680. * Set the current bounds info.
  681. *
  682. * History:
  683. * Thu 27-May-1993 -by- Patrick Haluptzok [patrickh]
  684. * Make it exclusive lock, this is a general purpose API
  685. *
  686. * 06-Apr-1992 -by- Donald Sidoroff [donalds]
  687. * Wrote it.
  688. \**************************************************************************/
  689. DWORD GreSetBoundsRect(HDC hdc, LPRECT prcl, DWORD fl)
  690. {
  691. DWORD dwState = 0;
  692. DCOBJ dco(hdc);
  693. if (dco.bValid())
  694. {
  695. ERECTL *percl;
  696. FSHORT fsEnable;
  697. BOOL bEnabled;
  698. BOOL bError = FALSE;
  699. if (fl & DCB_WINDOWMGR)
  700. {
  701. percl = &dco.erclBounds();
  702. fsEnable = DC_ACCUM_WMGR;
  703. bEnabled = dco.bAccum();
  704. }
  705. else
  706. {
  707. percl = &dco.erclBoundsApp();
  708. fsEnable = DC_ACCUM_APP;
  709. bEnabled = dco.bAccumApp();
  710. }
  711. dwState = (fl & DCB_WINDOWMGR);
  712. if (percl->bWrapped())
  713. dwState |= DCB_RESET;
  714. else
  715. dwState |= DCB_SET;
  716. if (bEnabled)
  717. dwState |= DCB_ENABLE;
  718. else
  719. dwState |= DCB_DISABLE;
  720. // Reset the rectangle if we've been asked to do so.
  721. if (fl & DCB_RESET)
  722. {
  723. percl->left = percl->top = POS_INFINITY;
  724. percl->right = percl->bottom = NEG_INFINITY;
  725. }
  726. // If we are accumulating, do the union.
  727. if (fl & DCB_ACCUMULATE)
  728. {
  729. ASSERTGDI(prcl,"GreSetBoundsRect - DCB_ACCUMULATE with no prcl\n");
  730. // Convert the incoming rectangle to DEVICE coordinates.
  731. if (!(fl & DCB_WINDOWMGR))
  732. {
  733. EXFORMOBJ exo(dco, WORLD_TO_DEVICE);
  734. if (!exo.bRotation())
  735. {
  736. if (!exo.bXform((POINTL *)prcl, 2))
  737. bError = TRUE;
  738. }
  739. else
  740. {
  741. POINTL apt[4];
  742. *((RECT *)apt) = *prcl;
  743. apt[2].x = prcl->left;
  744. apt[2].y = prcl->bottom;
  745. apt[3].x = prcl->right;
  746. apt[3].y = prcl->top;
  747. if (!exo.bXform(apt, 4))
  748. {
  749. bError = TRUE;
  750. }
  751. else
  752. {
  753. prcl->left = MIN4(apt[0].x,apt[1].x,apt[2].x,apt[3].x);
  754. prcl->right = MAX4(apt[0].x,apt[1].x,apt[2].x,apt[3].x);
  755. prcl->top = MIN4(apt[0].y,apt[1].y,apt[2].y,apt[3].y);
  756. prcl->bottom = MAX4(apt[0].y,apt[1].y,apt[2].y,apt[3].y);
  757. }
  758. }
  759. }
  760. *percl |= *((ERECTL *) prcl);
  761. }
  762. if (!bError)
  763. {
  764. // Enable or Disable accumulation
  765. if (fl & DCB_ENABLE)
  766. dco.fsSet(fsEnable);
  767. if (fl & DCB_DISABLE)
  768. dco.fsClr(fsEnable);
  769. }
  770. else
  771. {
  772. dwState = 0;
  773. }
  774. }
  775. return(dwState);
  776. }
  777. /******************************Public*Routine******************************\
  778. * GreMarkUndeletableDC
  779. *
  780. * Private API for USER.
  781. *
  782. * Mark a DC as undeletable. This must be called before the hdc is ever
  783. * passed out so that we are guranteed the lock will not fail because a
  784. * app is using it.
  785. *
  786. * History:
  787. * 13-Sep-1991 -by- Patrick Haluptzok patrickh
  788. * Wrote it.
  789. \**************************************************************************/
  790. VOID GreMarkUndeletableDC(HDC hdc)
  791. {
  792. XDCOBJ dco(hdc);
  793. if (dco.bValid())
  794. {
  795. dco.vMakeUndeletable();
  796. dco.vUnlockFast();
  797. }
  798. else
  799. {
  800. WARNING("ERROR User gives Gdi invalid DC");
  801. }
  802. }
  803. /******************************Public*Routine******************************\
  804. * GreMarkDeletableDC
  805. *
  806. * Private API for USER.
  807. *
  808. * This can be called anytime by USER to make the DC deletable.
  809. *
  810. * History:
  811. * 13-Sep-1991 -by- Patrick Haluptzok patrickh
  812. * Wrote it.
  813. \**************************************************************************/
  814. VOID GreMarkDeletableDC(HDC hdc)
  815. {
  816. XDCOBJ dcoa;
  817. dcoa.vAltLock(hdc);
  818. if (dcoa.bValid())
  819. {
  820. dcoa.vMakeDeletable();
  821. dcoa.vAltUnlockFast();
  822. }
  823. else
  824. {
  825. WARNING("ERROR User gives Gdi invalid DC");
  826. }
  827. }
  828. /******************************Public*Routine******************************\
  829. * HFONT GreGetHFONT(HDC)
  830. *
  831. * This is a private entry point user by USER when they pass the
  832. * DRAWITEMSTRUC message to the client to get the current handle.
  833. * This is done because they may have set the font on the server
  834. * side, in which case the client does not know about it.
  835. *
  836. * History:
  837. * Tue 28-Dec-1993 -by- Patrick Haluptzok [patrickh]
  838. * smaller and faster
  839. *
  840. * 16-Sep-1991 - by - Eric Kutter [erick]
  841. * Wrote it.
  842. \**************************************************************************/
  843. HFONT GreGetHFONT(HDC hdc)
  844. {
  845. XDCOBJ dco(hdc);
  846. HFONT hfont = (HFONT) 0;
  847. if (dco.bValid())
  848. {
  849. hfont = (HFONT) dco.pdc->hlfntNew();
  850. dco.vUnlockFast();
  851. }
  852. return(hfont);
  853. }
  854. /******************************Public*Routine******************************\
  855. * GreCancelDC()
  856. *
  857. * History:
  858. * 14-Apr-1992 -by- - by - Eric Kutter [erick]
  859. * Wrote it.
  860. \**************************************************************************/
  861. BOOL GreCancelDC(HDC hdc)
  862. {
  863. BOOL bReturn;
  864. //
  865. // The handle manager lock prevents the DC from being deleted while
  866. // we've got the DC alt-locked, and it also prevents the dynamic
  867. // mode change code from updating pSurface() while we're looking at
  868. // it.
  869. //
  870. MLOCKFAST mlo;
  871. XDCOBJ dco;
  872. dco.vAltCheckLock(hdc);
  873. if (bReturn = dco.bValid())
  874. {
  875. SURFACE *pSurface = dco.pSurface();
  876. if (pSurface != (SURFACE *) NULL)
  877. pSurface->vSetAbort();
  878. dco.vAltUnlockFast();
  879. }
  880. #if DBG
  881. else
  882. {
  883. WARNING("GreCancelDC passed invalid DC\n");
  884. }
  885. #endif
  886. return(bReturn);
  887. }
  888. /******************************Public*Routine******************************\
  889. * VOID GreMarkDCUnreadable(hdc)
  890. *
  891. * Mark a DC as secure.
  892. *
  893. * History:
  894. * 13-Aug-1990 -by- Donald Sidoroff [donalds]
  895. * Wrote it.
  896. \**************************************************************************/
  897. VOID APIENTRY GreMarkDCUnreadable(HDC hdc)
  898. {
  899. XDCOBJ dco;
  900. dco.vAltLock(hdc);
  901. MLOCKFAST mlo; // Protect pSurface() access
  902. if (dco.bValid())
  903. {
  904. ASSERTGDI(dco.dctp() == DCTYPE_DIRECT, "Non-screen DC marked as secure!\n");
  905. dco.pSurface()->flags(dco.pSurface()->flags() | UNREADABLE_SURFACE);
  906. PDEVOBJ pdo(dco.hdev());
  907. SPRITESTATE *pState = pdo.pSpriteState();
  908. pState->flOriginalSurfFlags |= UNREADABLE_SURFACE;
  909. pState->flSpriteSurfFlags |= UNREADABLE_SURFACE;
  910. dco.vAltUnlockFast();
  911. }
  912. else
  913. {
  914. WARNING("Invalid DC passed to GreMarkDCUnreadable\n");
  915. }
  916. }
  917. DWORD dwGetFontLanguageInfo(XDCOBJ& dco);
  918. /******************************Public*Routine******************************\
  919. * BOOL NtGdiGetDCDword(hdc,uint)
  920. *
  921. * Query DC to get a particular DWORD of info.
  922. *
  923. * History:
  924. * 9-Nov-1994 -by- Gerrit van Wingerden [gerritv]
  925. * Wrote it.
  926. \**************************************************************************/
  927. #if DBG
  928. ULONG acGetDCDword[DDW_MAX] = {0};
  929. #endif
  930. BOOL NtGdiGetDCDword( HDC hdc, UINT u, DWORD *pdwResult )
  931. {
  932. BOOL bResult = TRUE;
  933. DWORD dwTmp;
  934. XDCOBJ dco( hdc );
  935. if(!dco.bValid())
  936. {
  937. WARNING("Invalid DC or offset passed to GreGetDCDword\n");
  938. bResult = FALSE;
  939. }
  940. else
  941. {
  942. switch( u )
  943. {
  944. case DDW_JOURNAL:
  945. dwTmp = !(dco.flGraphicsCaps() & GCAPS_DONTJOURNAL);
  946. break;
  947. case DDW_RELABS:
  948. dwTmp = dco.pdc->lRelAbs();
  949. break;
  950. case DDW_BREAKEXTRA :
  951. dwTmp = dco.pdc->lBreakExtra();
  952. break;
  953. case DDW_CBREAK:
  954. dwTmp = dco.pdc->cBreak();
  955. break;
  956. case DDW_MAPMODE:
  957. dwTmp = dco.ulMapMode();
  958. break;
  959. case DDW_ARCDIRECTION:
  960. if (MIRRORED_DC(dco.pdc))
  961. dwTmp = dco.pdc->bClockwise() ? AD_COUNTERCLOCKWISE : AD_CLOCKWISE;
  962. else
  963. dwTmp = dco.pdc->bClockwise() ? AD_CLOCKWISE : AD_COUNTERCLOCKWISE;
  964. break;
  965. case DDW_SAVEDEPTH:
  966. dwTmp = dco.lSaveDepth();
  967. break;
  968. case DDW_FONTLANGUAGEINFO:
  969. dwTmp = dwGetFontLanguageInfo(dco);
  970. break;
  971. case DDW_ISMEMDC:
  972. dwTmp = ( dco.dctp() == DCTYPE_MEMORY );
  973. break;
  974. default:
  975. WARNING("Illegal offset passed to GreGetDCDword\n");
  976. bResult = FALSE;
  977. break;
  978. }
  979. if (bResult)
  980. {
  981. #if DBG
  982. acGetDCDword[u]++;
  983. #endif
  984. _try
  985. {
  986. ProbeAndWriteUlong(pdwResult, dwTmp);
  987. }
  988. _except(EXCEPTION_EXECUTE_HANDLER)
  989. {
  990. // SetLastError(GetExceptionCode());
  991. bResult = FALSE;
  992. }
  993. }
  994. dco.vUnlockFast();
  995. }
  996. return(bResult);
  997. }
  998. /******************************Public*Routine******************************\
  999. * BOOL NtGdiGetAndSetDCDword(hdc,uint,DWORD,DWORD*)
  1000. *
  1001. * Set a particular value in a DC DWORD and return the old value. Note this
  1002. * function should not be incorperated with GetDCDword because all the values
  1003. * will eventually be place in an array eliminating the need for a switch
  1004. * statement. This function, however, will need to do valiation specific
  1005. * to each particular attribute so we wil still need a switch statement.
  1006. *
  1007. * History:
  1008. * 9-Nov-1994 -by- Gerrit van Wingerden [gerritv]
  1009. * Wrote it.
  1010. \**************************************************************************/
  1011. #if DBG
  1012. ULONG acSetDCDword[GASDDW_MAX] = {0};
  1013. #endif
  1014. BOOL NtGdiGetAndSetDCDword( HDC hdc, UINT u, DWORD dwIn, DWORD *pdwResult )
  1015. {
  1016. BOOL bResult = TRUE;
  1017. DWORD dwTmp = ERROR;
  1018. XDCOBJ dco( hdc );
  1019. if(!dco.bValid())
  1020. {
  1021. WARNING("Invalid DC passed to GreGetAndSetDCDword\n");
  1022. if (u == GASDDW_TEXTCHARACTEREXTRA)
  1023. {
  1024. _try
  1025. {
  1026. ProbeAndWriteUlong(pdwResult, 0x80000000);
  1027. }
  1028. _except(EXCEPTION_EXECUTE_HANDLER)
  1029. {
  1030. // SetLastError(GetExceptionCode());
  1031. }
  1032. }
  1033. return FALSE;
  1034. }
  1035. switch( u )
  1036. {
  1037. case GASDDW_COPYCOUNT:
  1038. dwTmp = dco.ulCopyCount();
  1039. dco.ulCopyCount( dwIn );
  1040. break;
  1041. case GASDDW_EPSPRINTESCCALLED:
  1042. dwTmp = (DWORD) dco.bEpsPrintingEscape();
  1043. dco.vClearEpsPrintingEscape();
  1044. break;
  1045. case GASDDW_RELABS:
  1046. dwTmp = dco.pdc->lRelAbs();
  1047. dco.pdc->lRelAbs(dwIn);
  1048. break;
  1049. case GASDDW_SELECTFONT:
  1050. WARNING("should not be here\n");
  1051. /*
  1052. dwTmp = (DWORD) dco.pdc->hlfntNew();
  1053. dco.pdc->hlfntNew((HLFONT)dwIn);
  1054. if ((HLFONT)dwIn != dco.pdc->hlfntCur())
  1055. dco.ulDirtyAdd(DIRTY_CHARSET);
  1056. */
  1057. break;
  1058. case GASDDW_MAPPERFLAGS:
  1059. if( dwIn & (~ASPECT_FILTERING) )
  1060. {
  1061. WARNING1("gdisrv!GreSetMapperFlags(): unknown flag\n");
  1062. SAVE_ERROR_CODE(ERROR_INVALID_PARAMETER);
  1063. dwTmp = GDI_ERROR;
  1064. }
  1065. else
  1066. {
  1067. dwTmp = dco.pdc->flFontMapper();
  1068. dco.pdc->flFontMapper((DWORD) dwIn);
  1069. }
  1070. break;
  1071. case GASDDW_MAPMODE:
  1072. {
  1073. DWORD dwResult = dco.ulMapMode();
  1074. if (dwResult != dwIn)
  1075. {
  1076. dwResult = dco.pdc->iSetMapMode(dwIn);
  1077. }
  1078. dwTmp = dwResult;
  1079. }
  1080. break;
  1081. case GASDDW_ARCDIRECTION:
  1082. if (MIRRORED_DC(dco.pdc)) {
  1083. dwTmp = dco.pdc->bClockwise() ? AD_COUNTERCLOCKWISE : AD_CLOCKWISE;
  1084. if (dwIn == AD_CLOCKWISE)
  1085. dco.pdc->vClearClockwise();
  1086. else if (dwIn == AD_COUNTERCLOCKWISE)
  1087. dco.pdc->vSetClockwise();
  1088. else
  1089. {
  1090. SAVE_ERROR_CODE(ERROR_INVALID_PARAMETER);
  1091. dwTmp = ERROR;
  1092. }
  1093. }
  1094. else
  1095. {
  1096. dwTmp = dco.pdc->bClockwise() ? AD_CLOCKWISE : AD_COUNTERCLOCKWISE;
  1097. if (dwIn == AD_CLOCKWISE)
  1098. dco.pdc->vSetClockwise();
  1099. else if (dwIn == AD_COUNTERCLOCKWISE)
  1100. dco.pdc->vClearClockwise();
  1101. else
  1102. {
  1103. SAVE_ERROR_CODE(ERROR_INVALID_PARAMETER);
  1104. dwTmp = ERROR;
  1105. }
  1106. }
  1107. break;
  1108. default:
  1109. WARNING("Illegal offset passed to GreGetAndSetDCDword\n");
  1110. bResult = FALSE;
  1111. break;
  1112. }
  1113. if (bResult)
  1114. {
  1115. #if DBG
  1116. acSetDCDword[u]++;
  1117. #endif
  1118. _try
  1119. {
  1120. ProbeAndWriteUlong(pdwResult, dwTmp);
  1121. }
  1122. _except(EXCEPTION_EXECUTE_HANDLER)
  1123. {
  1124. // SetLastError(GetExceptionCode());
  1125. bResult = FALSE;
  1126. }
  1127. }
  1128. dco.vUnlockFast();
  1129. return(bResult);
  1130. }
  1131. /******************************Public*Routine******************************\
  1132. * GreGetDCPoint()
  1133. *
  1134. * History:
  1135. * 30-Nov-1994 -by- Eric Kutter [erick]
  1136. * Wrote it.
  1137. \**************************************************************************/
  1138. BOOL GreGetDCPoint(
  1139. HDC hdc,
  1140. UINT u,
  1141. PPOINTL pptOut
  1142. )
  1143. {
  1144. BOOL bResult = TRUE;
  1145. XDCOBJ dco(hdc);
  1146. if( dco.bValid() )
  1147. {
  1148. switch(u)
  1149. {
  1150. case DCPT_VPEXT:
  1151. if (dco.pdc->bPageExtentsChanged() && (dco.ulMapMode() == MM_ISOTROPIC))
  1152. dco.pdc->vMakeIso();
  1153. dco.pdc->vGet_szlViewportExt((PSIZEL)pptOut);
  1154. break;
  1155. case DCPT_WNDEXT:
  1156. dco.pdc->vGet_szlWindowExt((PSIZEL)pptOut);
  1157. if (MIRRORED_DC(dco.pdc))
  1158. pptOut->x = -pptOut->x;
  1159. break;
  1160. case DCPT_VPORG:
  1161. dco.pdc->vGet_ptlViewportOrg(pptOut);
  1162. if (MIRRORED_DC(dco.pdc))
  1163. pptOut->x = -pptOut->x;
  1164. break;
  1165. case DCPT_WNDORG:
  1166. dco.pdc->vGet_ptlWindowOrg(pptOut);
  1167. pptOut->x = dco.pdc->pDCAttr->lWindowOrgx;
  1168. break;
  1169. case DCPT_ASPECTRATIOFILTER:
  1170. bResult = GreGetAspectRatioFilter(hdc,(LPSIZE)pptOut);
  1171. break;
  1172. case DCPT_DCORG:
  1173. *pptOut = dco.eptlOrigin();
  1174. break;
  1175. default:
  1176. RIP("Illegal offset passed to GreGetAndSetDCPoint\n");
  1177. bResult = FALSE;
  1178. }
  1179. dco.vUnlockFast();
  1180. }
  1181. else
  1182. {
  1183. WARNING("Invalid DC passed to GreGetDCPoint\n");
  1184. bResult = FALSE;
  1185. }
  1186. return(bResult);
  1187. }
  1188. /******************************Public*Routine******************************\
  1189. * NtGdiGetDCObject()
  1190. *
  1191. * History:
  1192. * 01-Dec-1994 -by- Eric Kutter [erick]
  1193. * Wrote it.
  1194. \**************************************************************************/
  1195. HANDLE NtGdiGetDCObject(HDC hdc, int itype)
  1196. {
  1197. HANDLE hReturn = (HANDLE) 0;
  1198. //
  1199. // Try to lock the DC. If we fail, we just return failure.
  1200. //
  1201. XDCOBJ dco(hdc);
  1202. if (dco.bValid())
  1203. {
  1204. SYNC_DRAWING_ATTRS(dco.pdc);
  1205. //
  1206. // The DC is locked.
  1207. //
  1208. switch (itype)
  1209. {
  1210. case LO_BRUSH_TYPE:
  1211. hReturn = (HANDLE)(dco.pdc->pbrushFill())->hGet();
  1212. break;
  1213. case LO_PEN_TYPE:
  1214. case LO_EXTPEN_TYPE:
  1215. hReturn = (HANDLE)(dco.pdc->pbrushLine())->hGet();
  1216. break;
  1217. case LO_FONT_TYPE:
  1218. hReturn = (HANDLE) dco.pdc->hlfntNew();
  1219. break;
  1220. case LO_PALETTE_TYPE:
  1221. hReturn = (HANDLE) dco.hpal();
  1222. break;
  1223. case LO_BITMAP_TYPE:
  1224. {
  1225. //
  1226. // Acquire the Devlock because we're groveling
  1227. // in the DC's surface pointer, which could otherwise
  1228. // be changed asynchronously by the dyanmic mode change
  1229. // code.
  1230. //
  1231. DEVLOCKOBJ dlo;
  1232. dlo.vLockNoDrawing(dco);
  1233. hReturn = (HANDLE) dco.pSurfaceEff()->hsurf();
  1234. break;
  1235. }
  1236. default: break;
  1237. }
  1238. dco.vUnlockFast();
  1239. }
  1240. return(hReturn);
  1241. }
  1242. /******************************Public*Routine******************************\
  1243. * GreCleanDC(hdc)
  1244. *
  1245. * Set up some stuff up in the DC
  1246. *
  1247. * History:
  1248. * 20-Apr-1995 -by- Andre Vachon [andreva]
  1249. \**************************************************************************/
  1250. BOOL
  1251. GreCleanDC(
  1252. HDC hdc
  1253. )
  1254. {
  1255. DCOBJ dco(hdc);
  1256. if (dco.bValid())
  1257. {
  1258. if (dco.bCleanDC())
  1259. {
  1260. return(TRUE);
  1261. }
  1262. #if DBG
  1263. PVOID pv1, pv2;
  1264. RtlGetCallersAddress(&pv1,&pv2);
  1265. DbgPrint("GreCleanDC failed to lock DC (%p), (c1 = %p, c2 = %p)\n",
  1266. hdc, pv1, pv2);
  1267. #endif
  1268. }
  1269. return(FALSE);
  1270. }
  1271. /******************************Public*Routine******************************\
  1272. * GreSetDCOwner
  1273. *
  1274. * Set the owner of the DC
  1275. *
  1276. * if the owner is set to OBJECTOWNER_NONE, this dc will not be useable
  1277. * until GreSetDCOwner is called to explicitly give the dc to someone else.
  1278. *
  1279. * Arguments:
  1280. *
  1281. * hdc - DC to modify
  1282. * lPid - one of OBJECT_OWNER_NONE,OBJECT_OWNER_PUBLIC or
  1283. * OBJECT_OWNER_CURRENT
  1284. *
  1285. * Return Value:
  1286. *
  1287. * TRUEif DC ownership changed, FALSE otherwise
  1288. *
  1289. * History:
  1290. *
  1291. * 24-Aug-1995 Merge DC ownership routines
  1292. *
  1293. \**************************************************************************/
  1294. BOOL
  1295. GreSetDCOwner(
  1296. HDC hdc,
  1297. W32PID lPid
  1298. )
  1299. {
  1300. BOOL bStatus = FALSE;
  1301. PDC_ATTR pDcattr = NULL;
  1302. PENTRY pentry;
  1303. UINT uiIndex = (UINT) HmgIfromH(hdc);
  1304. if (uiIndex < gcMaxHmgr)
  1305. {
  1306. pentry = &gpentHmgr[uiIndex];
  1307. //
  1308. // before handle is locked, check if an allocation may
  1309. // be needed since DCATTRs can't be allocated under a handle lock.
  1310. // Note: instead, we could use a per-process mutex for process list protection.
  1311. //
  1312. if (lPid == OBJECT_OWNER_CURRENT)
  1313. {
  1314. pDcattr = HmgAllocateDcAttr();
  1315. }
  1316. //
  1317. // Acquire handle lock. Don't check PID here because owner could be
  1318. // NONE, not PUBLIC
  1319. //
  1320. HANDLELOCK HandleLock(pentry,FALSE);
  1321. if (HandleLock.bValid())
  1322. {
  1323. POBJ pobj = pentry->einfo.pobj;
  1324. if ((pentry->Objt == DC_TYPE) && (pentry->FullUnique== HmgUfromH(hdc)))
  1325. {
  1326. if ((pobj->cExclusiveLock == 0) ||
  1327. (pobj->Tid == (PW32THREAD)PsGetCurrentThread()))
  1328. {
  1329. W32PID lPidBrush = lPid;
  1330. //
  1331. // Handle is locked. It is illegal to acquire the hmgr resource
  1332. // when a handle is locked.
  1333. //
  1334. #if DBG || defined(PRERELEASE)
  1335. //
  1336. // check if the rgn selected in the DC is valid
  1337. // when USER mark the HDC to be usable again
  1338. //
  1339. if ((lPid != OBJECT_OWNER_NONE) &&
  1340. (HandleLock.Pid() == OBJECT_OWNER_NONE))
  1341. {
  1342. PDEVOBJ pdo(((PDC)pobj)->hdev());
  1343. SURFACE *pSurf = ((PDC)pobj)->pSurface();
  1344. REGION *prgn = ((PDC)pobj)->prgnVis();
  1345. BOOL bValidateVisrgn = ((PDC)pobj)->bValidateVisrgn();
  1346. if (pdo.bValid() && !pdo.bMetaDriver() &&
  1347. pSurf && bValidateVisrgn && prgn)
  1348. {
  1349. BOOL bIsOK = ((pSurf->sizl().cx >= prgn->rcl.right) &&
  1350. (pSurf->sizl().cy >= prgn->rcl.bottom)&&
  1351. (prgn->rcl.left >= 0) &&
  1352. (prgn->rcl.top >= 0));
  1353. FREASSERTGDI(bIsOK, "Rgn size is bigger than surface size");
  1354. }
  1355. }
  1356. #endif
  1357. if ((lPid == OBJECT_OWNER_NONE) ||
  1358. (lPid == OBJECT_OWNER_PUBLIC))
  1359. {
  1360. //
  1361. // free DCATTR if PID matches current process, otherwise
  1362. // fail this call. This is an ok path, it just means user has a
  1363. // DC on their delayed dc destroy queue and they are trying to
  1364. // delete it now from a different process. This doesn't work
  1365. // because we have no way of accessing or freeing DC_ATTRs of
  1366. // a different process
  1367. //
  1368. if (HandleLock.Pid() == W32GetCurrentPID())
  1369. {
  1370. //
  1371. // if user mode DC_ATTR is allocated for this dc
  1372. //
  1373. if (((PDC)pobj)->pDCAttr != &((PDC)pobj)->dcattr)
  1374. {
  1375. //
  1376. // copy pDCAttrs to dcattr, then reset pDCAttr to DC memory
  1377. //
  1378. ((PDC)pobj)->dcattr = *((PDC)pobj)->pDCAttr;
  1379. //
  1380. // free DCATTR
  1381. //
  1382. pDcattr = ((PDC)pobj)->pDCAttr;
  1383. //
  1384. // Set pDCAttr to point to internal structure
  1385. //
  1386. ((PDC)pobj)->pDCAttr = &((PDC)pobj)->dcattr;
  1387. //
  1388. // clear ENTRY
  1389. //
  1390. pentry->pUser = NULL;
  1391. }
  1392. //
  1393. // set DC owner to NONE or PUBLIC
  1394. //
  1395. HandleLock.Pid(lPid);
  1396. //
  1397. // dec process handle count
  1398. //
  1399. HmgDecProcessHandleCount(W32GetCurrentPID());
  1400. bStatus = TRUE;
  1401. }
  1402. else if (HandleLock.Pid() == OBJECT_OWNER_NONE)
  1403. {
  1404. //
  1405. // Allow to set from NONE to PUBLIC or NONE.
  1406. //
  1407. HandleLock.Pid(lPid);
  1408. bStatus = TRUE;
  1409. }
  1410. }
  1411. else if (lPid == OBJECT_OWNER_CURRENT)
  1412. {
  1413. //
  1414. // can only set to OBJECT_OWNER_CURRENT if DC is
  1415. // not owned, or already owned by current pid.
  1416. //
  1417. // Get the current PID
  1418. //
  1419. lPid = W32GetCurrentPID();
  1420. if (
  1421. (HandleLock.Pid() == lPid) ||
  1422. (HandleLock.Pid() == OBJECT_OWNER_NONE) ||
  1423. (HandleLock.Pid() == OBJECT_OWNER_PUBLIC)
  1424. )
  1425. {
  1426. BOOL bIncHandleCount = FALSE;
  1427. //
  1428. // DC may already have DC_ATTR allocated
  1429. //
  1430. bStatus = TRUE;
  1431. //
  1432. // only inc handle count if assigning a new PID
  1433. //
  1434. if (HandleLock.Pid() != lPid)
  1435. {
  1436. //
  1437. // don't check quota for DCs
  1438. //
  1439. HmgIncProcessHandleCount(lPid,DC_TYPE);
  1440. bIncHandleCount = TRUE;
  1441. }
  1442. //
  1443. // check user object not already allocated for this handle
  1444. //
  1445. if (pentry->pUser == NULL)
  1446. {
  1447. if (pDcattr != NULL)
  1448. {
  1449. //
  1450. // set DC dc_attr pointer
  1451. //
  1452. ((PDC)pobj)->pDCAttr = pDcattr;
  1453. //
  1454. // set pUser in ENTRY
  1455. //
  1456. pentry->pUser = pDcattr;
  1457. //
  1458. // copy clean attrs
  1459. //
  1460. *pDcattr = ((PDC)pobj)->dcattr;
  1461. //
  1462. // set pDcattr to NULL so it is not freed
  1463. //
  1464. pDcattr = NULL;
  1465. }
  1466. else
  1467. {
  1468. WARNING1("HmgSetDCOwnwer failed - No DC_ATTR available\n");
  1469. bStatus = FALSE;
  1470. //
  1471. // Reduce handle quota count
  1472. //
  1473. if (bIncHandleCount)
  1474. {
  1475. HmgDecProcessHandleCount(lPid);
  1476. }
  1477. }
  1478. }
  1479. if (bStatus)
  1480. {
  1481. //
  1482. // Set new owner
  1483. //
  1484. HandleLock.Pid(lPid);
  1485. }
  1486. }
  1487. else
  1488. {
  1489. WARNING("HmgSetDCOwnwer failed, trying to set directly from one PID to another\n");
  1490. }
  1491. }
  1492. else
  1493. {
  1494. WARNING("HmgSetDCOwnwer failed, bad lPid\n");
  1495. }
  1496. if((lPidBrush != OBJECT_OWNER_NONE) && bStatus)
  1497. {
  1498. if(!GreSetBrushOwner((HBRUSH)(((PDC)pobj)->hbrush()),lPidBrush)||
  1499. !GreSetBrushOwner((HBRUSH)(((PDC)pobj)->pbrushFill())->hGet(),lPidBrush)||
  1500. !GreSetBrushOwner((HBRUSH)(((PDC)pobj)->pbrushLine())->hGet(),lPidBrush))
  1501. {
  1502. WARNING("HmgSetDCOwner, Brushes could not be moved");
  1503. }
  1504. }
  1505. }
  1506. else
  1507. {
  1508. WARNING1("HmgSetDCOwnwer failed - Handle is exclusively locked\n");
  1509. }
  1510. }
  1511. else
  1512. {
  1513. WARNING1("HmgSetDCOwnwer failed - bad unique or object type");
  1514. }
  1515. HandleLock.vUnlock();
  1516. }
  1517. }
  1518. else
  1519. {
  1520. WARNING1("HmgSetOwner failed - invalid handle index\n");
  1521. }
  1522. //
  1523. // free dcattr if needed
  1524. //
  1525. if (pDcattr)
  1526. {
  1527. HmgFreeDcAttr(pDcattr);
  1528. }
  1529. return(bStatus);
  1530. }
  1531. /******************************Public*Routine******************************\
  1532. * GreSetupDCAttributes
  1533. *
  1534. * Arguments:
  1535. *
  1536. * hdc - handle to DC
  1537. * pDCAttr - pointer to memory block allocated in USER space by caller
  1538. *
  1539. * Return Value:
  1540. *
  1541. * BOOL Status
  1542. *
  1543. * History:
  1544. *
  1545. * 24-Apr-1995 -by- Mark Enstrom [marke]
  1546. *
  1547. \**************************************************************************/
  1548. BOOL
  1549. GreSetupDCAttributes(
  1550. HDC hdc
  1551. )
  1552. {
  1553. BOOL bRet = FALSE;
  1554. DCOBJ dco(hdc);
  1555. if (dco.bValid())
  1556. {
  1557. PDC_ATTR pDCAttr = HmgAllocateDcAttr();
  1558. if (pDCAttr != NULL)
  1559. {
  1560. //
  1561. // set DC dc_attr pointer
  1562. //
  1563. dco.pdc->pDCAttr = pDCAttr;
  1564. //
  1565. // make sure USER object not already allocate for this handle
  1566. //
  1567. ASSERTGDI(gpentHmgr[HmgIfromH(hdc)].pUser == NULL,
  1568. "GreSetupDCAttributes: pUser not NULL");
  1569. //
  1570. // setup shared global handle table for this DC
  1571. //
  1572. gpentHmgr[HmgIfromH(hdc)].pUser = pDCAttr;
  1573. //
  1574. // copy old attrs
  1575. //
  1576. *pDCAttr = dco.pdc->dcattr;
  1577. bRet = TRUE;
  1578. }
  1579. }
  1580. return(bRet);
  1581. }
  1582. /******************************Public*Routine******************************\
  1583. * GreFreeDCAttributes
  1584. *
  1585. * Arguments:
  1586. *
  1587. * hdc
  1588. *
  1589. * Return Value:
  1590. *
  1591. * BOOL
  1592. *
  1593. * History:
  1594. *
  1595. * 27-Apr-1995 -by- Mark Enstrom [marke]
  1596. *
  1597. \**************************************************************************/
  1598. BOOL
  1599. GreFreeDCAttributes(
  1600. HDC hdc
  1601. )
  1602. {
  1603. BOOL bStatus = FALSE;
  1604. DCOBJ dco(hdc);
  1605. if (dco.bValid())
  1606. {
  1607. //
  1608. // free dc attribute block if not default, then set to default
  1609. //
  1610. if (dco.pdc->pDCAttr != &dco.pdc->dcattr)
  1611. {
  1612. ASSERTGDI(dco.pdc->pDCAttr != NULL,"GreFreeDCAttributes: pDCAttr is NULL");
  1613. //
  1614. // copy pDCAttrs to dcattr
  1615. //
  1616. dco.pdc->dcattr = *(dco.pdc->pDCAttr);
  1617. //
  1618. // free DC_ATTR memory
  1619. //
  1620. HmgFreeDcAttr(dco.pdc->pDCAttr);
  1621. //
  1622. // Set pDCAttr to point to internal structure
  1623. //
  1624. dco.pdc->pDCAttr = &dco.pdc->dcattr;
  1625. //
  1626. // clear DCATTR in ENTRY
  1627. //
  1628. gpentHmgr[HmgIfromH(hdc)].pUser = (PDC_ATTR)NULL;
  1629. bStatus = TRUE;
  1630. }
  1631. }
  1632. return(bStatus);
  1633. }
  1634. /****************************************************************************
  1635. * NtGdiComputeXformCoefficients
  1636. *
  1637. * This function is used by the client side char-width caching code. It
  1638. * forces computation of the World To Device Transform and puts the
  1639. * coefficients in the shared attribute structure. If the world to device
  1640. * xform is not just simple scalling it returns FALSE indicating that extents
  1641. * and widths should not be cached.
  1642. *
  1643. *
  1644. * History:
  1645. * 6/12/1995 by Gerrit van Wingerden [gerritv]
  1646. * Wrote it.
  1647. *****************************************************************************/
  1648. extern "C" BOOL NtGdiComputeXformCoefficients(
  1649. HDC hdc // Handle to the DC
  1650. )
  1651. {
  1652. BOOL bRet = FALSE;
  1653. XDCOBJ dco(hdc);
  1654. if( dco.bValid() )
  1655. {
  1656. EXFORMOBJ xo(dco, WORLD_TO_DEVICE);
  1657. ASSERTGDI(xo.bValid(),"NtGdiFastWidths exformobj not valid\n");
  1658. if( xo.bScale() )
  1659. {
  1660. bRet = TRUE;
  1661. }
  1662. dco.vUnlockFast();
  1663. }
  1664. return(bRet);
  1665. }
  1666. BOOL
  1667. bUMPD(
  1668. HDC hdc)
  1669. {
  1670. XDCOBJ dco(hdc);
  1671. BOOL bRet = FALSE;
  1672. if( dco.bValid())
  1673. {
  1674. bRet = dco.bUMPD();
  1675. dco.vUnlockFast();
  1676. }
  1677. return(bRet);
  1678. }