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.

733 lines
22 KiB

  1. /*******************************Module*Header*******************************\
  2. * Module Name:
  3. *
  4. * icmobj.cxx
  5. *
  6. * Abstract
  7. *
  8. * This module contains object support for COLORTRANSFORM objects and ICM
  9. * Objects
  10. *
  11. * Author:
  12. *
  13. * Feb.23.1997 -by- Hideyuki Nagase [hideyukn]
  14. *
  15. * Copyright (c) 1997-1999 Microsoft Corporation
  16. \**************************************************************************/
  17. #include "precomp.hxx"
  18. /******************************Public*Routine******************************\
  19. * COLORTRANSFORMOBJ::hCreate()
  20. *
  21. * History:
  22. *
  23. * Write it:
  24. * 23-Feb-1997 -by- Hideyuki Nagase [hideyukn]
  25. \**************************************************************************/
  26. HANDLE
  27. COLORTRANSFORMOBJ::hCreate(
  28. XDCOBJ& dco,
  29. LOGCOLORSPACEW *pLogColorSpaceW,
  30. PVOID pvSource,
  31. ULONG cjSource,
  32. PVOID pvDestination,
  33. ULONG cjDestination,
  34. PVOID pvTarget,
  35. ULONG cjTarget
  36. )
  37. {
  38. HANDLE hObject = NULL;
  39. PCOLORTRANSFORM pNewCXform = NULL;
  40. ICMAPI(("COLORTRANSFORM::hCreate()\n"));
  41. HDEV hdev = dco.hdev();
  42. //
  43. // This object should not have any existing realization.
  44. //
  45. ASSERTGDI(_pColorTransform == NULL,"COLORTRANSFORMOBJ::hCreate() object is exist\n");
  46. PDEVOBJ po(hdev);
  47. if (po.bValid())
  48. {
  49. //
  50. // Allocate ColorTransform object.
  51. //
  52. pNewCXform = (PCOLORTRANSFORM) ALLOCOBJ(sizeof(COLORTRANSFORM),ICMCXF_TYPE, FALSE);
  53. if (pNewCXform)
  54. {
  55. //
  56. // Register COLORTRANSFORM handle.
  57. //
  58. hObject = (HCOLORSPACE)HmgInsertObject(
  59. pNewCXform,
  60. HMGR_ALLOC_ALT_LOCK,
  61. ICMCXF_TYPE);
  62. if (hObject)
  63. {
  64. HANDLE hDeviceColorTransform = NULL;
  65. //
  66. // Set new object to this COLORTRANSFORMNOBJ
  67. //
  68. _pColorTransform = pNewCXform;
  69. //
  70. // Lock device
  71. //
  72. DEVLOCKOBJ devLock(po);
  73. //
  74. // Create driver's transform.
  75. //
  76. if (PPFNVALID(po,IcmCreateColorTransform))
  77. {
  78. //
  79. // Call device driver to obtain handle of device driver.
  80. //
  81. hDeviceColorTransform = (*PPFNDRV(po, IcmCreateColorTransform)) (
  82. po.dhpdev(),
  83. pLogColorSpaceW,
  84. pvSource, cjSource,
  85. pvDestination, cjDestination,
  86. pvTarget, cjTarget,
  87. 0 /* dwReserved */);
  88. }
  89. else
  90. {
  91. WARNING("CreateColorTransform called on device that does not support call\n");
  92. SAVE_ERROR_CODE(ERROR_INVALID_PARAMETER);
  93. }
  94. if (hDeviceColorTransform)
  95. {
  96. ICMMSG(("CreateColorTransform(): Succeed to get handle from driver\n"));
  97. //
  98. // Set the handle to COLORTRANSFORM object.
  99. //
  100. vSetDeviceColorTransform(hDeviceColorTransform);
  101. //
  102. // Insert this pColorTransform to this DC.
  103. //
  104. dco.bAddColorTransform(hObject);
  105. }
  106. else
  107. {
  108. ICMMSG(("CreateColorTransform(): Fail to get handle from driver\n"));
  109. //
  110. // Mark this object does not have driver's realization.
  111. //
  112. vSetDeviceColorTransform(NULL);
  113. //
  114. // We are fail to get driver's handle, delete this.
  115. //
  116. bDelete(dco);
  117. //
  118. // Invalidate hObject and pColorTransform.
  119. // (these are deleted in above bDelete())
  120. //
  121. hObject = NULL;
  122. pNewCXform = NULL;
  123. }
  124. }
  125. }
  126. else
  127. {
  128. SAVE_ERROR_CODE(ERROR_NOT_ENOUGH_MEMORY);
  129. }
  130. if ((hObject == NULL) && (pNewCXform != NULL))
  131. {
  132. FREEOBJ(pNewCXform,ICMCXF_TYPE);
  133. }
  134. }
  135. return (hObject);
  136. }
  137. /******************************Public*Routine******************************\
  138. * COLORTRANSFORMOBJ::bDelete()
  139. *
  140. * History:
  141. *
  142. * Write it:
  143. * 23-Feb-1997 -by- Hideyuki Nagase [hideyukn]
  144. \**************************************************************************/
  145. BOOL
  146. COLORTRANSFORMOBJ::bDelete(XDCOBJ& dco,BOOL bProcessCleanup)
  147. {
  148. BOOL bRet = FALSE;
  149. PCOLORTRANSFORM pDeleteXCForm;
  150. ICMAPI(("COLORTRANSFORM::bDelete()\n"));
  151. if (bValid())
  152. {
  153. BOOL bCanBeRemoved;
  154. //
  155. // Get colortransform object handle.
  156. //
  157. HANDLE hObject = _pColorTransform->hColorTransform();
  158. //
  159. // Unlock it. (this was locked in constructor).
  160. //
  161. DEC_SHARE_REF_CNT(_pColorTransform);
  162. //
  163. // Remote from object table.
  164. //
  165. bCanBeRemoved = (BOOL)(ULONG_PTR)HmgRemoveObject((HOBJ)(hObject),0,0,TRUE,ICMCXF_TYPE);
  166. if (bCanBeRemoved)
  167. {
  168. HANDLE hDeviceColorTransform;
  169. //
  170. // Yes, we can remove object from object table, try to delete driver's realization.
  171. //
  172. ICMMSG(("DeleteColorTransform(): Succeed to remove object from table\n"));
  173. //
  174. // Get device driver's handle.
  175. //
  176. hDeviceColorTransform = hGetDeviceColorTransform();
  177. if (hDeviceColorTransform)
  178. {
  179. //
  180. // Initialize PDEV object with owner.
  181. //
  182. PDEVOBJ po(dco.hdev());
  183. if (po.bValid())
  184. {
  185. if (po.bUMPD() && bProcessCleanup)
  186. {
  187. ICMMSG(("DeleteColorTransform():Will not callout to user mode since UMPD.\n"));
  188. //
  189. // Overwrite driver transform as NULL.
  190. //
  191. vSetDeviceColorTransform(NULL);
  192. }
  193. else
  194. {
  195. DEVLOCKOBJ devLock(po);
  196. //
  197. // Delete driver's realization.
  198. //
  199. if (PPFNVALID(po,IcmDeleteColorTransform))
  200. {
  201. //
  202. // Call device driver to free driver's handle
  203. //
  204. if ((*PPFNDRV(po, IcmDeleteColorTransform))(
  205. po.dhpdev(),
  206. hDeviceColorTransform))
  207. {
  208. ICMMSG(("DeleteColorTransform():Succeed to IcmDeleteColorTransform()\n"));
  209. //
  210. // This object does not have driver realization anymore.
  211. //
  212. vSetDeviceColorTransform(NULL);
  213. }
  214. else
  215. {
  216. WARNING("DeleteColorTransform():Fail to IcmDeleteColorTransform()\n");
  217. }
  218. }
  219. else
  220. {
  221. WARNING("DeleteColorTransform called on device that does not support call\n");
  222. SAVE_ERROR_CODE(ERROR_INVALID_PARAMETER);
  223. }
  224. }
  225. }
  226. }
  227. else
  228. {
  229. ICMMSG(("DeleteColorTransform(): There is no driver handle\n"));
  230. }
  231. //
  232. // We could delete object allocation if there is no driver's realization.
  233. //
  234. if (hGetDeviceColorTransform() == NULL)
  235. {
  236. //
  237. // Remove this pColorTransform from DC.
  238. //
  239. dco.bRemoveColorTransform(hObject);
  240. //
  241. // Free it.
  242. //
  243. FREEOBJ(_pColorTransform,ICMCXF_TYPE);
  244. //
  245. // Invalidate pointer.
  246. //
  247. _pColorTransform = NULL;
  248. //
  249. // Yes, everything fine!
  250. //
  251. bRet = TRUE;
  252. }
  253. }
  254. else
  255. {
  256. ICMMSG(("DeleteColorTransform(): Fail to remove object from table\n"));
  257. }
  258. //
  259. // If we could not remove this object from object table, or could not
  260. // delete object (including driver's realization)
  261. //
  262. if ((!bCanBeRemoved) || (!bRet))
  263. {
  264. //
  265. // can not delete now. somebody will using...
  266. //
  267. WARNING("COLORTRANSFORMOBJ::vDelete(): Fail to Delete object, lazy deletion may happen\n");
  268. //
  269. // Back reference counter (deconstuctor will decrement this).
  270. //
  271. INC_SHARE_REF_CNT(_pColorTransform);
  272. //
  273. // Anyway, we will delete later at cleanup.
  274. //
  275. bRet = TRUE;
  276. }
  277. }
  278. return (bRet);
  279. }
  280. /******************************Public*Routine******************************\
  281. * XDCOBJ::bAddColorTransform()
  282. *
  283. * History:
  284. *
  285. * Write it:
  286. * 27-Feb-1997 -by- Hideyuki Nagase [hideyukn]
  287. \**************************************************************************/
  288. BOOL XDCOBJ::bAddColorTransform(HANDLE hCXform)
  289. {
  290. CXFLIST *pCXFListThis;
  291. //
  292. // Allocate new cell of CXFLIST
  293. //
  294. pCXFListThis = (CXFLIST *) PALLOCMEM(sizeof(CXFLIST),'ddaG');
  295. if (pCXFListThis)
  296. {
  297. //
  298. // Fill up CXFLIST structure
  299. //
  300. pCXFListThis->hCXform = hCXform;
  301. pCXFListThis->pNext = pdc->pCXFList;
  302. //
  303. // Insert this into top of list.
  304. //
  305. pdc->pCXFList = pCXFListThis;
  306. return (TRUE);
  307. }
  308. else
  309. {
  310. ICMMSG(("XDCOBJ::bAddColorTransform() Failed\n"));
  311. return (FALSE);
  312. }
  313. }
  314. /******************************Public*Routine******************************\
  315. * XDCOBJ::bRemoveColorTransform()
  316. *
  317. * History:
  318. *
  319. * Write it:
  320. * 27-Feb-1997 -by- Hideyuki Nagase [hideyukn]
  321. \**************************************************************************/
  322. BOOL XDCOBJ::bRemoveColorTransform(HANDLE hCXform)
  323. {
  324. if (pdc->pCXFList)
  325. {
  326. PCXFLIST pPrev, pThis;
  327. pPrev = pThis = pdc->pCXFList;
  328. while (pThis)
  329. {
  330. if (pThis->hCXform == hCXform)
  331. {
  332. //
  333. // This is the cell, we need to remove.
  334. //
  335. if (pPrev == pThis)
  336. {
  337. //
  338. // We are going to remove first cell. then need to
  339. // update root.
  340. //
  341. pdc->pCXFList = pThis->pNext;
  342. }
  343. else
  344. {
  345. //
  346. // Remove this from list.
  347. //
  348. pPrev->pNext = pThis->pNext;
  349. }
  350. //
  351. // Invalidate root.
  352. //
  353. VFREEMEM(pThis);
  354. return (TRUE);
  355. }
  356. //
  357. // Move to next cell
  358. //
  359. pPrev = pThis;
  360. pThis = pThis->pNext;
  361. }
  362. }
  363. else
  364. {
  365. ICMMSG(("bRemoveColorTransform():There is no colortransform()\n"));
  366. }
  367. return (FALSE);
  368. }
  369. /******************************Public*Routine******************************\
  370. * XDCOBJ::vCleanupColorTransform()
  371. *
  372. * History:
  373. *
  374. * Write it:
  375. * 27-Feb-1997 -by- Hideyuki Nagase [hideyukn]
  376. \**************************************************************************/
  377. VOID XDCOBJ::vCleanupColorTransform(BOOL bProcessCleanup)
  378. {
  379. if (pdc->pCXFList)
  380. {
  381. PCXFLIST pLast, pThis;
  382. pThis = pdc->pCXFList;
  383. while (pThis)
  384. {
  385. COLORTRANSFORMOBJ CXformObj(pThis->hCXform);
  386. pLast = pThis;
  387. if (CXformObj.bValid())
  388. {
  389. //
  390. // Delete this color transform
  391. //
  392. if (CXformObj.bDelete(*this,bProcessCleanup))
  393. {
  394. ICMMSG(("vCleanupColorTransform():Delete colortransform in this DC\n"));
  395. }
  396. else
  397. {
  398. ICMMSG(("vCleanupColorTransform():Fail to delete colortransform in this DC\n"));
  399. }
  400. }
  401. //
  402. // we don't need to walk through the list, because above COLORTRANSFORMOBJ.bDelete()
  403. // will re-chain this list, then we just pick up the cell on the top of list everytime.
  404. //
  405. pThis = pdc->pCXFList;
  406. //
  407. // But if still new pThis is eqaul to pLast, this means we might fail to
  408. // delete object or un-chain list, then just un-chain this forcely.
  409. //
  410. if (pThis == pLast)
  411. {
  412. //
  413. // Skip pThis.
  414. //
  415. pThis = pThis->pNext;
  416. //
  417. // Update root too,
  418. //
  419. pdc->pCXFList = pThis;
  420. }
  421. }
  422. }
  423. else
  424. {
  425. // ICMMSG(("vCleanupColorTransform():There is no color transform in this DC\n"));
  426. }
  427. }
  428. /******************************Public*Routine******************************\
  429. * XEPALOBJ::CorrectColors()
  430. *
  431. * History:
  432. *
  433. * Write it:
  434. * 29-Apr-1997 -by- Hideyuki Nagase [hideyukn]
  435. \**************************************************************************/
  436. VOID XEPALOBJ::CorrectColors(PPALETTEENTRY ppalentry, ULONG cEntries)
  437. {
  438. ICMMSG(("XEPALOBJ::CorrectColors\n"));
  439. PDEVOBJ po(hdevOwner());
  440. if (po.bValid())
  441. {
  442. if (po.bHasGammaRampTable())
  443. {
  444. ICMMSG(("XEPALOBJ::CorrectColors(): Do Gamma Correction\n"));
  445. ICMMSG(("XEPALOBJ::CorrectColors(): GammaRamp Owner HDEV = %x\n",po.hdev()));
  446. PGAMMARAMP_ARRAY pGammaRampArray = (PGAMMARAMP_ARRAY)(po.pvGammaRampTable());
  447. for (ULONG i = 0; i < cEntries; i++)
  448. {
  449. //
  450. // Adjust colors based on GammaRamp table.
  451. //
  452. ppalentry->peRed = (pGammaRampArray->Red[ppalentry->peRed]) >> 8;
  453. ppalentry->peGreen = (pGammaRampArray->Green[ppalentry->peGreen]) >> 8;
  454. ppalentry->peBlue = (pGammaRampArray->Blue[ppalentry->peBlue]) >> 8;
  455. //
  456. // next palette entry
  457. //
  458. ppalentry++;
  459. }
  460. }
  461. else
  462. {
  463. ICMMSG(("XEPALOBJ::CorrectColors(): PDEV does not have Gamma Table\n"));
  464. }
  465. }
  466. else
  467. {
  468. ICMMSG(("XEPALOBJ::CorrectColors(): PDEV is invalid\n"));
  469. }
  470. }
  471. /******************************Public*Routine******************************\
  472. * UpdateGammaRampOnDevice()
  473. *
  474. * History:
  475. *
  476. * Write it:
  477. * 29-Apr-1997 -by- Hideyuki Nagase [hideyukn]
  478. \**************************************************************************/
  479. BOOL UpdateGammaRampOnDevice(HDEV hdev,BOOL bForceUpdate)
  480. {
  481. BOOL bRet = FALSE;
  482. ICMMSG(("UpdateGammaRampOnDevice()\n"));
  483. PDEVOBJ po(hdev);
  484. if (po.bValid())
  485. {
  486. ICMMSG(("UpdateGammaRampOnDevice():Set GammaRamp to HDEV = %x\n",po.hdev()));
  487. if ((po.iDitherFormat() == BMF_8BPP) ||
  488. (po.iDitherFormat() == BMF_16BPP) ||
  489. (po.iDitherFormat() == BMF_24BPP) ||
  490. (po.iDitherFormat() == BMF_32BPP))
  491. {
  492. //
  493. // Driver might provide the entry point.
  494. //
  495. if ((PPFNVALID(po, IcmSetDeviceGammaRamp)) &&
  496. (po.flGraphicsCaps2() & GCAPS2_CHANGEGAMMARAMP))
  497. {
  498. //
  499. // PDEV should have GammaRampTable
  500. //
  501. if (po.bHasGammaRampTable())
  502. {
  503. ICMMSG(("UpdateGammaRampOnDevice():Call SetDeviceGammaRamp()\n"));
  504. //
  505. // Call device driver to set new GammaRamp.
  506. //
  507. bRet = (*PPFNDRV(po, IcmSetDeviceGammaRamp))(po.dhpdev(),
  508. IGRF_RGB_256WORDS,
  509. po.pvGammaRampTable());
  510. }
  511. }
  512. else
  513. {
  514. //
  515. // if the drive does not support, we will simulate it only for 8bpp case.
  516. //
  517. if ((po.iDitherFormat() == BMF_8BPP) && (po.bIsPalManaged()))
  518. {
  519. ICMMSG(("UpdateGammaRampOnDevice(): Call SetPalette()\n"));
  520. //
  521. // Check:
  522. // 1) Are we going to reset pallete forcely ? (ex. back to default GammaRamp)
  523. // 2) Or, Adjust Palette based on GammaRamp in PDEV.
  524. //
  525. if (bForceUpdate || po.bHasGammaRampTable())
  526. {
  527. //
  528. // Get palette on device surface.
  529. //
  530. XEPALOBJ palSurf(po.ppalSurf());
  531. ASSERTGDI(palSurf.bIsIndexed(),"UpdateGammaRampOnDevice(): Palette is not indexed\n");
  532. //
  533. // Mark this palette need to Gamma correction
  534. // (if this is not default GammaRamp, default GammaRamp case
  535. // PDEV does not have table.)
  536. //
  537. palSurf.bNeedGammaCorrection(po.bHasGammaRampTable());
  538. //
  539. // And put owner of PDEV which has GammaRamp table.
  540. // (if they already has some value in there, we will
  541. // overwrite it, but actually it should be same or
  542. // uninitialized.)
  543. //
  544. palSurf.hdevOwner(po.hdev());
  545. ICMMSG(("UpdateGammaRampOnDevice():Set GammaRamp to HDEV = %x\n",po.hdev()));
  546. //
  547. // Update palettes based on new GammaRamp.
  548. //
  549. // (Color will be adjusted in PALOBJ_cGetColors())
  550. //
  551. GreAcquireSemaphoreEx(po.hsemDevLock(), SEMORDER_DEVLOCK, NULL);
  552. GreEnterMonitoredSection(po.ppdev, WD_DEVLOCK);
  553. {
  554. SEMOBJ so(po.hsemPointer());
  555. if (!po.bDisabled())
  556. {
  557. ASSERTGDI(PPFNVALID(po,SetPalette),"ERROR palette is not managed");
  558. bRet = (*PPFNDRV(po, SetPalette))(po.dhpdev(),
  559. (PALOBJ *) &palSurf,
  560. 0, 0, palSurf.cEntries());
  561. }
  562. }
  563. GreExitMonitoredSection(po.ppdev, WD_DEVLOCK);
  564. GreReleaseSemaphoreEx(po.hsemDevLock());
  565. }
  566. }
  567. else
  568. {
  569. ICMMSG(("UpdateGammaRampOnDevice():Driver doesn't have DrvSetDeviceGammaRamp()\n"));
  570. }
  571. }
  572. }
  573. else
  574. {
  575. //
  576. // Can not set GammaRamp for 1/4 bpp surface
  577. //
  578. ICMMSG(("UpdateGammaRampOnDevice():GammaRamp does not support on 1/4 bpp\n"));
  579. }
  580. if (!bRet)
  581. {
  582. ICMMSG(("UpdateGammaRampOnDevice(): device driver returns error\n"));
  583. }
  584. }
  585. else
  586. {
  587. ICMMSG(("UpdateGammaRampOnDevice(): HDEV is invalid\n"));
  588. }
  589. return (bRet);
  590. }
  591. /******************************Public*Routine******************************\
  592. * GetColorManagementCaps()
  593. *
  594. * History:
  595. *
  596. * Write it:
  597. * 24-Feb-1998 -by- Hideyuki Nagase [hideyukn]
  598. \**************************************************************************/
  599. ULONG GetColorManagementCaps(PDEVOBJ& po)
  600. {
  601. ULONG fl = CM_NONE;
  602. PDEVINFO pDevInfo = po.pdevinfoNotDynamic();
  603. //
  604. // Check CM_GAMMA_RAMP - it will be enabled when
  605. //
  606. // 0) Only for display device.
  607. // 1) DitherFormat is 8bpp. (GDI simulate regardless driver capabilities)
  608. // 2) Driver can do it.
  609. //
  610. if (po.bDisplayPDEV())
  611. {
  612. if ((pDevInfo->iDitherFormat == BMF_8BPP) ||
  613. (po.flGraphicsCaps2NotDynamic() & GCAPS2_CHANGEGAMMARAMP))
  614. {
  615. fl |= CM_GAMMA_RAMP;
  616. }
  617. }
  618. //
  619. // Check CM_CMYK_COLOR when driver can understand.
  620. //
  621. if (po.flGraphicsCapsNotDynamic() & GCAPS_CMYKCOLOR)
  622. {
  623. fl |= CM_CMYK_COLOR;
  624. }
  625. //
  626. // Check CM_DEVICE_ICM when driver can do.
  627. //
  628. if (po.flGraphicsCapsNotDynamic() & GCAPS_ICM)
  629. {
  630. fl |= CM_DEVICE_ICM;
  631. }
  632. return fl;
  633. }