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.

2639 lines
76 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: palgdi.cxx
  3. *
  4. * This module provides the API level interface functions for dealing with
  5. * palettes.
  6. *
  7. * Created: 07-Nov-1990 22:21:11
  8. * Author: Patrick Haluptzok patrickh
  9. *
  10. * Copyright (c) 1990-1999 Microsoft Corporation
  11. \**************************************************************************/
  12. #include "precomp.hxx"
  13. // hForePalette is a global variable that tells which palette is currently
  14. // realized in the foreground.
  15. HPALETTE hForePalette = 0;
  16. PW32PROCESS hForePID = 0;
  17. #if DBG
  18. ULONG DbgPal = 0;
  19. #define PAL_DEBUG(l,x) {if (l <= DbgPal) {DbgPrint("%p ", hpalDC); DbgPrint(x);}}
  20. #else
  21. #define PAL_DEBUG(l,x)
  22. #endif
  23. /******************************Public*Routine******************************\
  24. * GreGetDIBColorTable
  25. *
  26. * Get the color table of the DIB section currently selected into the dc
  27. * identified by the given hdc. If the surface is not a DIB section,
  28. * this function will fail.
  29. *
  30. * History:
  31. * 07-Sep-1993 -by- Wendy Wu [wendywu]
  32. * Wrote it.
  33. \**************************************************************************/
  34. #if ((BMF_1BPP != 1) || (BMF_4BPP != 2) || (BMF_8BPP != 3))
  35. #error GetDIBColorTable BAD FORMAT
  36. #endif
  37. UINT
  38. APIENTRY
  39. GreGetDIBColorTable(
  40. HDC hdc,
  41. UINT iStart,
  42. UINT cEntries,
  43. RGBQUAD *pRGB
  44. )
  45. {
  46. UINT iRet = 0;
  47. DCOBJ dco(hdc);
  48. if (pRGB != (RGBQUAD *)NULL)
  49. {
  50. if (dco.bValid())
  51. {
  52. //
  53. // Protect against dynamic mode changes while we go grunging
  54. // around in the surface.
  55. //
  56. DEVLOCKOBJ dlo;
  57. dlo.vLockNoDrawing(dco);
  58. //
  59. // Fail if the selected in surface is not a DIB or the depth is more than
  60. // 8BPP.
  61. //
  62. SURFACE *pSurf = dco.pSurfaceEff();
  63. ULONG iFormat = pSurf->iFormat();
  64. if ((pSurf->bDIBSection() || (pSurf->pPal != NULL)) &&
  65. (iFormat <= BMF_8BPP) && (iFormat >= BMF_1BPP))
  66. {
  67. //
  68. // Lock the surface palette and figure out the max index allowed on the
  69. // palette. Win95 does not return un-used entries.
  70. //
  71. XEPALOBJ pal(pSurf->ppal());
  72. ASSERTGDI(pal.bValid(), "GetDIBColorTable: invalid pal\n");
  73. UINT iMax = (UINT) pal.cEntries();
  74. if (iStart >= iMax)
  75. {
  76. return(0);
  77. }
  78. UINT iLast = iStart + cEntries;
  79. if (iLast > iMax)
  80. {
  81. iLast = iMax;
  82. }
  83. pal.vFill_rgbquads(pRGB, iStart, iRet = iLast - iStart);
  84. }
  85. else
  86. {
  87. SAVE_ERROR_CODE(ERROR_INVALID_HANDLE);
  88. }
  89. }
  90. else
  91. {
  92. SAVE_ERROR_CODE(ERROR_INVALID_HANDLE);
  93. }
  94. }
  95. else
  96. {
  97. SAVE_ERROR_CODE(ERROR_INVALID_PARAMETER);
  98. }
  99. return(iRet);
  100. }
  101. /******************************Public*Routine******************************\
  102. * GreSetDIBColorTable
  103. *
  104. * Set the color table of the DIB section currently selected into the dc
  105. * identified by the given hdc. If the surface is not a DIB section,
  106. * this function will fail.
  107. *
  108. * History:
  109. * 07-Sep-1993 -by- Wendy Wu [wendywu]
  110. * Wrote it.
  111. \**************************************************************************/
  112. UINT
  113. APIENTRY
  114. GreSetDIBColorTable(
  115. HDC hdc,
  116. UINT iStart,
  117. UINT cEntries,
  118. RGBQUAD *pRGB
  119. )
  120. {
  121. UINT iRet = 0;
  122. DCOBJ dco(hdc);
  123. if (dco.bValid())
  124. {
  125. //
  126. // Protect against dynamic mode changes while we go grunging
  127. // around in the surface.
  128. //
  129. DEVLOCKOBJ dlo;
  130. dlo.vLockNoDrawing(dco);
  131. //
  132. // Fail if the selected in surface is not a DIB or the depth is more than
  133. // 8BPP.
  134. //
  135. SURFACE *pSurf = dco.pSurfaceEff();
  136. ULONG iFormat = pSurf->iFormat();
  137. if (pSurf->bDIBSection() &&
  138. (iFormat <= BMF_8BPP) && (iFormat >= BMF_1BPP))
  139. {
  140. //
  141. // Mark the brushes dirty.
  142. //
  143. dco.ulDirty(dco.ulDirty() | DIRTY_BRUSHES);
  144. //
  145. // Lock the surface palette and figure out the max
  146. // index allowed on the palette.
  147. //
  148. XEPALOBJ pal(pSurf->ppal());
  149. ASSERTGDI(pal.bValid(), "GetDIBColorTable: invalid pal\n");
  150. UINT iMax = (UINT) pal.cEntries();
  151. if (iStart < iMax)
  152. {
  153. UINT iLast = iStart + cEntries;
  154. if (iLast > iMax)
  155. iLast = iMax;
  156. pal.vCopy_rgbquad(pRGB, iStart, iRet = iLast - iStart);
  157. }
  158. }
  159. else
  160. {
  161. SAVE_ERROR_CODE(ERROR_INVALID_HANDLE);
  162. }
  163. }
  164. else
  165. {
  166. SAVE_ERROR_CODE(ERROR_INVALID_HANDLE);
  167. }
  168. return(iRet);
  169. }
  170. /******************************Public*Routine******************************\
  171. * GreCreatePalette - creates a palette from the logpal information given
  172. *
  173. * API function.
  174. *
  175. * returns HPALETTE for succes, (HPALETTE) 0 for failure
  176. *
  177. * History:
  178. * 07-Nov-1990 -by- Patrick Haluptzok patrickh
  179. * Wrote it.
  180. \**************************************************************************/
  181. HPALETTE
  182. APIENTRY
  183. GreCreatePalette(
  184. LPLOGPALETTE pLogPal
  185. )
  186. {
  187. return(GreCreatePaletteInternal(pLogPal,pLogPal->palNumEntries));
  188. }
  189. HPALETTE
  190. APIENTRY
  191. GreCreatePaletteInternal(
  192. LPLOGPALETTE pLogPal,
  193. UINT cEntries
  194. )
  195. {
  196. if ((pLogPal->palVersion != 0x300) || (cEntries == 0))
  197. {
  198. WARNING("GreCreatePalette failed, 0 entries or wrong version\n");
  199. return((HPALETTE) 0);
  200. }
  201. //
  202. // The constructor checks for invalid flags and fails if they are found.
  203. //
  204. PALMEMOBJ pal;
  205. if (!pal.bCreatePalette(PAL_INDEXED,
  206. cEntries,
  207. (PULONG) pLogPal->palPalEntry,
  208. 0, 0, 0,
  209. (PAL_DC | PAL_FREE)))
  210. {
  211. return((HPALETTE) 0);
  212. }
  213. ASSERTGDI(pal.cEntries() != 0, "ERROR can't be 0, bGetEntriesFrom depends on that");
  214. pal.vKeepIt();
  215. GreSetPaletteOwner((HPALETTE)pal.hpal(), OBJECT_OWNER_CURRENT);
  216. return((HPALETTE) pal.hpal());
  217. }
  218. /******************************Public*Routine******************************\
  219. * NtGdiCreatePaletteInternal()
  220. *
  221. * History:
  222. * 01-Nov-1994 -by- Eric Kutter [erick]
  223. * Wrote it.
  224. \**************************************************************************/
  225. HPALETTE
  226. APIENTRY
  227. NtGdiCreatePaletteInternal(
  228. LPLOGPALETTE pLogPal,
  229. UINT cEntries
  230. )
  231. {
  232. HPALETTE hpalRet = (HPALETTE)1;
  233. //
  234. // verify cEntries
  235. //
  236. if (cEntries <= 65536)
  237. {
  238. int cj = cEntries * sizeof(PALETTEENTRY) + offsetof(LOGPALETTE,palPalEntry);
  239. WORD Version;
  240. PULONG pPaletteEntry;
  241. __try
  242. {
  243. // it is safe to do a byte here. If we can access dword's on byte boundries
  244. // this will work. If not we will hit an exception under a try except. Winhelp
  245. // passes in an unaligned palette but only on x86.
  246. ProbeForRead(pLogPal,cj, sizeof(BYTE));
  247. Version = pLogPal->palVersion;
  248. pPaletteEntry = (PULONG) pLogPal->palPalEntry;
  249. }
  250. __except(EXCEPTION_EXECUTE_HANDLER)
  251. {
  252. // SetLastError(GetExceptionCode());
  253. hpalRet = (HPALETTE)0;
  254. }
  255. if (hpalRet)
  256. {
  257. if ((Version != 0x300) || (cEntries == 0))
  258. {
  259. WARNING("GreCreatePalette failed, 0 entries or wrong version\n");
  260. hpalRet = (HPALETTE)0;
  261. }
  262. if (hpalRet)
  263. {
  264. //
  265. // The constructor checks for invalid flags and fails if they are found.
  266. //
  267. PALMEMOBJ pal;
  268. BOOL bStatus;
  269. //
  270. // bCreatePalette must use a try-except when accessing pPaletteEntry
  271. //
  272. bStatus = pal.bCreatePalette(PAL_INDEXED,
  273. cEntries,
  274. pPaletteEntry,
  275. 0,
  276. 0,
  277. 0,
  278. (PAL_DC | PAL_FREE));
  279. if (bStatus)
  280. {
  281. ASSERTGDI(pal.cEntries() != 0, "ERROR can't be 0, bGetEntriesFrom depends on that");
  282. bStatus = GreSetPaletteOwner((HPALETTE)pal.hpal(), OBJECT_OWNER_CURRENT);
  283. if (bStatus)
  284. {
  285. pal.vKeepIt();
  286. hpalRet = pal.hpal();
  287. }
  288. else
  289. {
  290. hpalRet = (HPALETTE)0;
  291. }
  292. }
  293. else
  294. {
  295. hpalRet = (HPALETTE)0;
  296. }
  297. }
  298. }
  299. }
  300. else
  301. {
  302. hpalRet = 0;
  303. WARNING("GreCreatePalette failed,cEntries too large\n");
  304. }
  305. return(hpalRet);
  306. }
  307. /******************************Public*Routine******************************\
  308. * GreCreateCompatibleHalftonePalette
  309. *
  310. * Creates the win95 compatible halftone palette
  311. *
  312. * Arguments:
  313. *
  314. *
  315. *
  316. * Return Value:
  317. *
  318. *
  319. *
  320. * History:
  321. *
  322. * 11/27/1996 Mark Enstrom [marke]
  323. *
  324. \**************************************************************************/
  325. HPALETTE
  326. APIENTRY
  327. GreCreateCompatibleHalftonePalette(
  328. HDC hdc
  329. )
  330. {
  331. HPALETTE hpalRet;
  332. PALMEMOBJ pal;
  333. BOOL bStatus;
  334. //
  335. // bCreatePalette must use a try-except when accessing pPaletteEntry
  336. //
  337. bStatus = pal.bCreatePalette(PAL_INDEXED,
  338. 256,
  339. (PULONG)&aPalHalftone[0].ul,
  340. 0,
  341. 0,
  342. 0,
  343. (PAL_DC | PAL_FREE | PAL_HT));
  344. if (bStatus)
  345. {
  346. ASSERTGDI(pal.cEntries() != 0, "ERROR can't be 0, bGetEntriesFrom depends on that");
  347. pal.flPal(PAL_HT);
  348. bStatus = GreSetPaletteOwner((HPALETTE)pal.hpal(), OBJECT_OWNER_CURRENT);
  349. if (bStatus)
  350. {
  351. pal.vKeepIt();
  352. hpalRet = pal.hpal();
  353. }
  354. else
  355. {
  356. hpalRet = (HPALETTE)0;
  357. }
  358. }
  359. else
  360. {
  361. hpalRet = (HPALETTE)0;
  362. }
  363. return(hpalRet);
  364. }
  365. /******************************Public*Routine******************************\
  366. * GreCreateHalftonePalette(hdc)
  367. *
  368. * Create a halftone palette for the given DC.
  369. *
  370. * History:
  371. * 31-Aug-1992 -by- Wendy Wu [wendywu]
  372. * Wrote it.
  373. \**************************************************************************/
  374. HPALETTE
  375. APIENTRY
  376. GreCreateHalftonePalette(
  377. HDC hdc
  378. )
  379. {
  380. //
  381. // Validate and lock down the DC. NOTE: Even though the surface is accessed
  382. // in this function, it is only for information purposes. No reading or
  383. // writing of the surface occurs.
  384. //
  385. DCOBJ dco(hdc);
  386. if (!dco.bValid())
  387. {
  388. SAVE_ERROR_CODE(ERROR_INVALID_HANDLE);
  389. return((HPALETTE) 0);
  390. }
  391. //
  392. // Get the PDEV from the DC.
  393. //
  394. PDEVOBJ po(dco.hdev());
  395. //
  396. // Acquire the devlock to protect against dynamic mode changes while
  397. // we enable halftoning for the PDEV and we construct the halftone
  398. // palette from this information.
  399. //
  400. DEVLOCKOBJ dlo(po);
  401. //
  402. // Create the halftone block if it has not existed yet.
  403. //
  404. if ((po.pDevHTInfo() == NULL) &&
  405. !po.bEnableHalftone((PCOLORADJUSTMENT)NULL))
  406. return((HPALETTE) 0);
  407. DEVICEHALFTONEINFO *pDevHTInfo = (DEVICEHALFTONEINFO *)po.pDevHTInfo();
  408. //
  409. // Use the entries in the halftone palette in the halftone block to create
  410. // the palette.
  411. //
  412. EPALOBJ palHT((HPALETTE)pDevHTInfo->DeviceOwnData);
  413. ASSERTGDI(palHT.bValid(), "GreCreateHalftonePalette: invalid HT pal\n");
  414. PALMEMOBJ pal;
  415. if (palHT.cEntries())
  416. {
  417. if (!pal.bCreatePalette(PAL_INDEXED, palHT.cEntries(),
  418. (PULONG)palHT.apalColorGet(), 0, 0, 0,
  419. (PAL_DC | PAL_FREE | PAL_HT)))
  420. {
  421. return((HPALETTE) 0);
  422. }
  423. }
  424. else
  425. {
  426. //
  427. // 16BPP halftone uses 555 for RGB. We can't create a zero
  428. // entry palette at the API level, so lets create a default palette.
  429. //
  430. if (!pal.bCreatePalette(PAL_INDEXED, (ULONG)logDefaultPal.palNumEntries,
  431. (PULONG)logDefaultPal.palPalEntry, 0, 0, 0,
  432. PAL_DC | PAL_FREE | PAL_HT))
  433. {
  434. return(FALSE);
  435. }
  436. }
  437. pal.vKeepIt();
  438. GreSetPaletteOwner((HPALETTE)pal.hpal(), OBJECT_OWNER_CURRENT);
  439. return((HPALETTE) pal.hpal());
  440. }
  441. /******************************Public*Routine******************************\
  442. * GreGetNearestPaletteIndex - returns the nearest palette index to crColor
  443. * in the hpalette. Can only fail if hpal passed in is busy or bad.
  444. *
  445. * API function.
  446. *
  447. * returns value >= 0 for success, -1 for failure.
  448. *
  449. * History:
  450. * 09-Nov-1990 -by- Patrick Haluptzok patrickh
  451. * Wrote it.
  452. \**************************************************************************/
  453. UINT
  454. APIENTRY
  455. NtGdiGetNearestPaletteIndex(
  456. HPALETTE hpal,
  457. COLORREF crColor
  458. )
  459. {
  460. EPALOBJ pal((HPALETTE) hpal);
  461. if (pal.bValid())
  462. {
  463. //
  464. // If the palette has 0 entries return the color passed in.
  465. //
  466. if (pal.cEntries())
  467. {
  468. if (crColor & 0x01000000)
  469. {
  470. crColor &= 0x0000FFFF;
  471. if (crColor >= pal.cEntries())
  472. crColor = 0;
  473. }
  474. else
  475. {
  476. crColor &= 0x00FFFFFF;
  477. crColor = pal.ulGetNearestFromPalentry(*((PPALETTEENTRY) &crColor));
  478. }
  479. }
  480. }
  481. else
  482. {
  483. SAVE_ERROR_CODE(ERROR_INVALID_HANDLE);
  484. crColor = CLR_INVALID;
  485. }
  486. return((UINT) crColor);
  487. }
  488. /******************************Public*Routine******************************\
  489. * GreAnimatePalette
  490. *
  491. * API function
  492. *
  493. * Returns: The number of logical palette entries animated, 0 for error.
  494. *
  495. * History:
  496. * 17-Nov-1990 -by- Patrick Haluptzok patrickh
  497. * Wrote it.
  498. \**************************************************************************/
  499. BOOL APIENTRY GreAnimatePalette(HPALETTE hpal, UINT ulStartIndex,
  500. UINT ulNumEntries, CONST PALETTEENTRY *lpPaletteColors)
  501. {
  502. BOOL bReturn = FALSE;
  503. EPALOBJ pal((HPALETTE) hpal);
  504. if (pal.bValid())
  505. {
  506. bReturn = (BOOL) pal.ulAnimatePalette(ulStartIndex, ulNumEntries, lpPaletteColors);
  507. }
  508. return(bReturn);
  509. }
  510. /******************************Public*Routine******************************\
  511. * GreGetPaletteEntries
  512. *
  513. * API function
  514. *
  515. * returns: 0 for failure, else number of entries retrieved.
  516. *
  517. * History:
  518. * 18-Nov-1990 -by- Patrick Haluptzok patrickh
  519. * Wrote it.
  520. \**************************************************************************/
  521. UINT APIENTRY GreGetPaletteEntries(HPALETTE hpal, UINT ulStartIndex,
  522. UINT ulNumEntries, LPPALETTEENTRY pRGB)
  523. {
  524. //
  525. // Note on this call we can just let the default palette go through
  526. // since it isn't getting modified, and the constructor is smart
  527. // enough not to really lock it down.
  528. //
  529. EPALOBJ pal((HPALETTE) hpal);
  530. if (!pal.bValid())
  531. {
  532. SAVE_ERROR_CODE(ERROR_INVALID_HANDLE);
  533. return(0);
  534. }
  535. return(pal.ulGetEntries(ulStartIndex, ulNumEntries, pRGB, FALSE));
  536. }
  537. /******************************Public*Routine******************************\
  538. * GreSetPaletteEntries
  539. *
  540. * API function
  541. *
  542. * returns: 0 for failure, else number of entries retrieved.
  543. *
  544. * History:
  545. * 18-Nov-1990 -by- Patrick Haluptzok patrickh
  546. * Wrote it.
  547. \**************************************************************************/
  548. UINT
  549. GreSetPaletteEntries(
  550. HPALETTE hpal,
  551. UINT ulStartIndex,
  552. UINT ulNumEntries,
  553. CONST PALETTEENTRY *pRGB
  554. )
  555. {
  556. //
  557. // Note on this call we don't worry about STOCKOBJ_PAL because ulSetEntries
  558. // won't let the default palette get modified.
  559. //
  560. UINT uiReturn = 0;
  561. EPALOBJ pal((HPALETTE) hpal);
  562. if (pal.bValid())
  563. {
  564. //
  565. // You must grab the palette semaphore to touch the linked list of DC's.
  566. //
  567. SEMOBJ semo(ghsemPalette);
  568. uiReturn = (UINT) pal.ulSetEntries(ulStartIndex, ulNumEntries, pRGB);
  569. //
  570. // Run down all the DC's for this palette.
  571. // Set the flags to dirty the brushes, since we changed the palette!
  572. //
  573. {
  574. MLOCKFAST mlo;
  575. HDC hdcNext = pal.hdcHead();
  576. while ( hdcNext != (HDC)0 )
  577. {
  578. MDCOBJA dco(hdcNext);
  579. //
  580. // WINBUG #55203 2-1-2000 bhouse Remove temporary fix to avoid AV when setting DIRTY_BRUSHES
  581. // This is just a temp fix (since '95 hehehe) to keep
  582. // this from doing an AV. Lingyun, making the
  583. // brush flags all be in kernel memory will
  584. // fix this.
  585. //
  586. // this should just be
  587. // dco.ulDirty(dco.ulDirty() | DIRTY_BRUSHES);
  588. //
  589. if (GreGetObjectOwner((HOBJ)hdcNext,DC_TYPE) == W32GetCurrentPID())
  590. {
  591. dco.ulDirty(dco.ulDirty() | DIRTY_BRUSHES);
  592. }
  593. else
  594. {
  595. dco.pdc->flbrushAdd(DIRTY_FILL);
  596. }
  597. hdcNext = dco.pdc->hdcNext();
  598. }
  599. }
  600. }
  601. return(uiReturn);
  602. }
  603. /******************************Public*Routine******************************\
  604. * GreGetNearestColor
  605. *
  606. * This function returns the color that will be displayed on the device
  607. * if a solid brush was created with the given colorref.
  608. *
  609. * History:
  610. * Mon 29-Nov-1993 -by- Patrick Haluptzok [patrickh]
  611. * Don't round the color on non-indexed devices
  612. *
  613. * 15-Jan-1991 -by- Patrick Haluptzok patrickh
  614. * Wrote it.
  615. \**************************************************************************/
  616. COLORREF APIENTRY GreGetNearestColor(HDC hdc, COLORREF crColor)
  617. {
  618. ULONG ulRet;
  619. DCOBJ dco(hdc);
  620. if (dco.bValid())
  621. {
  622. //
  623. // Protect against dynamic mode changes while we go grunging
  624. // around in the surface.
  625. //
  626. DEVLOCKOBJ dlo;
  627. dlo.vLockNoDrawing(dco);
  628. XEPALOBJ palDC(dco.ppal());
  629. XEPALOBJ palSurf;
  630. SURFACE *pSurf = dco.pSurfaceEff();
  631. if ((dco.dctp() == DCTYPE_INFO) || (dco.dctp() == DCTYPE_DIRECT))
  632. {
  633. PDEVOBJ po(dco.hdev());
  634. ASSERTGDI(po.bValid(), "ERROR GreGetNearestColor invalid PDEV\n");
  635. palSurf.ppalSet(po.ppalSurf());
  636. ASSERTGDI(palSurf.bValid(), "ERROR GreGetNearestColor invalid palDefault");
  637. }
  638. else
  639. {
  640. ASSERTGDI(dco.dctp() == DCTYPE_MEMORY, "Not a memory DC type");
  641. palSurf.ppalSet(pSurf->ppal());
  642. }
  643. //
  644. // if ICM translate the color to CMYK, just return the passed CMYK color.
  645. //
  646. if (dco.pdc->bIsCMYKColor())
  647. {
  648. ulRet = crColor;
  649. }
  650. else
  651. {
  652. if (((crColor & 0x01000000) == 0) &&
  653. (palSurf.bValid() && !(palSurf.bIsIndexed())))
  654. {
  655. //
  656. // Well if it isn't index it's RGB,BGR, or Bitfields.
  657. // In any case to support Win3.1 we need to return exactly
  658. // what was passed in otherwise they think we are a monochrome
  659. // device. Bitfields could result is some messy rounding so
  660. // it's more exact to just return the RGB passed in.
  661. //
  662. ulRet = crColor & 0x00FFFFFF; // mask off the highest byte
  663. }
  664. else
  665. {
  666. ulRet = ulIndexToRGB(palSurf, palDC, ulGetNearestIndexFromColorref(palSurf, palDC, crColor));
  667. }
  668. }
  669. }
  670. else
  671. {
  672. ulRet = CLR_INVALID;
  673. }
  674. return(ulRet);
  675. }
  676. /******************************Public*Routine******************************\
  677. * GreGetSystemPaletteEntries
  678. *
  679. * API Function - copies out the range of palette entries from the DC's
  680. * surface's palette.
  681. *
  682. * returns: number of entries retrieved from the surface palette, 0 for FAIL
  683. *
  684. * History:
  685. * 15-Jan-1991 -by- Patrick Haluptzok patrickh
  686. * Wrote it.
  687. \**************************************************************************/
  688. UINT APIENTRY GreGetSystemPaletteEntries(HDC hdc, UINT ulStartIndex,
  689. UINT ulNumEntries, PPALETTEENTRY pRGB)
  690. {
  691. UINT uiReturn = 0;
  692. DCOBJ dco(hdc);
  693. if (dco.bValid())
  694. {
  695. PDEVOBJ po(dco.hdev());
  696. //
  697. // Acquire the devlock while grunging in the surface palette to
  698. // protect against dynamic mode changes.
  699. //
  700. DEVLOCKOBJ dlo(po);
  701. if (po.bIsPalManaged())
  702. {
  703. XEPALOBJ palSurf(po.ppalSurf());
  704. uiReturn = (UINT) palSurf.ulGetEntries(ulStartIndex, ulNumEntries,
  705. pRGB, TRUE);
  706. }
  707. }
  708. return(uiReturn);
  709. }
  710. /******************************Public*Routine******************************\
  711. * GreGetSystemPaletteUse
  712. *
  713. * API function
  714. *
  715. * returns: SYSPAL_STATIC or SYSPAL_NOSTATIC, 0 for an error
  716. *
  717. * History:
  718. * 15-Jan-1991 -by- Patrick Haluptzok patrickh
  719. * Wrote it.
  720. \**************************************************************************/
  721. UINT APIENTRY GreGetSystemPaletteUse(HDC hdc)
  722. {
  723. ULONG ulReturn = SYSPAL_ERROR;
  724. DCOBJ dco(hdc);
  725. if (dco.bValid())
  726. {
  727. PDEVOBJ po(dco.hdev());
  728. //
  729. // Acquire the devlock while grunging in the surface palette to
  730. // protect against dynamic mode changes.
  731. //
  732. DEVLOCKOBJ dlo(po);
  733. if (po.bIsPalManaged())
  734. {
  735. XEPALOBJ palSurf(po.ppalSurf());
  736. if (palSurf.bIsNoStatic())
  737. {
  738. ulReturn = SYSPAL_NOSTATIC;
  739. }
  740. else if (palSurf.bIsNoStatic256())
  741. {
  742. ulReturn = SYSPAL_NOSTATIC256;
  743. }
  744. else
  745. {
  746. ulReturn = SYSPAL_STATIC;
  747. }
  748. }
  749. }
  750. return(ulReturn);
  751. }
  752. /******************************Public*Routine******************************\
  753. * GreSetSystemPaletteUse
  754. *
  755. * API function - Sets the number of reserved entries if palette managed
  756. *
  757. * returns - the old flag for the palette, 0 for error
  758. *
  759. * History:
  760. * 15-Jan-1991 -by- Patrick Haluptzok patrickh
  761. * Wrote it.
  762. \**************************************************************************/
  763. UINT APIENTRY GreSetSystemPaletteUse(HDC hdc, UINT ulUsage)
  764. {
  765. //
  766. // Validate the parameters, Win3.1 sets the flag to static if it's invalid.
  767. //
  768. if ((ulUsage != SYSPAL_STATIC) && (ulUsage != SYSPAL_NOSTATIC) &&
  769. (ulUsage != SYSPAL_NOSTATIC256))
  770. ulUsage = SYSPAL_STATIC;
  771. //
  772. // Initialize return value.
  773. //
  774. ULONG ulReturn = SYSPAL_ERROR;
  775. BOOL bPalChanged = FALSE;
  776. ULONG i;
  777. DCOBJ dco(hdc);
  778. if (dco.bValid())
  779. {
  780. //
  781. // Lock the screen semaphore so that we don't get flipped into
  782. // full screen after checking the bit. This also protects us
  783. // from dynamic mode changes that change the 'bIsPalManaged'
  784. // status.
  785. //
  786. PDEVOBJ po(dco.hdev());
  787. DEVLOCKOBJ dlo(po);
  788. XEPALOBJ palSurf(po.ppalSurf());
  789. XEPALOBJ palDC(dco.ppal());
  790. if (po.bIsPalManaged())
  791. {
  792. //
  793. // The palette managed case.
  794. //
  795. {
  796. //
  797. // Protect access to the goodies in the system palette
  798. // with the SEMOBJ. We don't want a realize happening
  799. // while we fiddle flags.
  800. //
  801. SEMOBJ semo(ghsemPalette);
  802. if (palSurf.bIsNoStatic())
  803. {
  804. ulReturn = SYSPAL_NOSTATIC;
  805. }
  806. else if (palSurf.bIsNoStatic256())
  807. {
  808. ulReturn = SYSPAL_NOSTATIC256;
  809. }
  810. else
  811. {
  812. ulReturn = SYSPAL_STATIC;
  813. }
  814. if (ulUsage == SYSPAL_STATIC)
  815. {
  816. //
  817. // reset the colors from their original copy in the devinfo palette.
  818. // The copy already has the flags properly set.
  819. //
  820. if (palSurf.bIsNoStatic() || palSurf.bIsNoStatic256())
  821. {
  822. //
  823. // Change the palette that GDI manages, copy over up to
  824. // 20 static colors from ppalDefault
  825. //
  826. XEPALOBJ palOriginal(ppalDefault);
  827. ASSERTGDI(palOriginal.bValid(), "ERROR ulMakeStatic0");
  828. ULONG ulNumReserved = palSurf.ulNumReserved() >> 1;
  829. if (ulNumReserved > 10)
  830. {
  831. ulNumReserved = 10;
  832. }
  833. //
  834. // set the beginning entries
  835. //
  836. for (i = 0; i < ulNumReserved; i++)
  837. {
  838. PALETTEENTRY palEntry = palOriginal.palentryGet(i);
  839. palEntry.peFlags = PC_USED | PC_FOREGROUND;
  840. palSurf.palentrySet(i,palEntry);
  841. }
  842. //
  843. // set the ending entries
  844. //
  845. ULONG ulCurrentPal = palSurf.cEntries();
  846. ULONG ulCurrentDef = 20;
  847. for (i = 0; i < ulNumReserved; i++)
  848. {
  849. PALETTEENTRY palEntry;
  850. ulCurrentPal--;
  851. ulCurrentDef--;
  852. palEntry = palOriginal.palentryGet(ulCurrentDef);
  853. palEntry.peFlags = PC_USED | PC_FOREGROUND;
  854. palSurf.palentrySet(ulCurrentPal,palEntry);
  855. }
  856. //
  857. // Mark the brushes dirty for this DC.
  858. //
  859. dco.ulDirty(dco.ulDirty() | DIRTY_BRUSHES);
  860. palSurf.flPalSet(palSurf.flPal() & ~PAL_NOSTATIC & ~PAL_NOSTATIC256);
  861. palSurf.vUpdateTime();
  862. bPalChanged = TRUE;
  863. }
  864. }
  865. else if (ulUsage == SYSPAL_NOSTATIC)
  866. {
  867. //
  868. // unmark all the static colors, with the exception of black and
  869. // white that stay with us.
  870. //
  871. for (i = 1; i < (palSurf.cEntries()-1); i++)
  872. {
  873. palSurf.apalColorGet()[i].pal.peFlags = 0;
  874. }
  875. palSurf.vSetNoStatic();
  876. }
  877. else //SYSPAL_NOSTATIC256
  878. {
  879. //
  880. // unmark all the static colors
  881. //
  882. for (i = 0; i < (palSurf.cEntries()); i++)
  883. {
  884. palSurf.apalColorGet()[i].pal.peFlags = 0;
  885. }
  886. palSurf.vSetNoStatic256();
  887. }
  888. }
  889. if (bPalChanged)
  890. {
  891. SEMOBJ so(po.hsemPointer());
  892. if (!po.bDisabled())
  893. {
  894. po.pfnSetPalette()(
  895. po.dhpdevParent(),
  896. (PALOBJ *) &palSurf,
  897. 0,
  898. 0,
  899. palSurf.cEntries());
  900. }
  901. }
  902. }
  903. }
  904. return(ulReturn);
  905. }
  906. /******************************Public*Routine******************************\
  907. * NtGdiResizePalette()
  908. *
  909. * API function
  910. *
  911. * returns: TRUE for success, FALSE for failure
  912. *
  913. * History:
  914. * Tue 10-Sep-1991 -by- Patrick Haluptzok [patrickh]
  915. * rewrite to be multi-threaded safe
  916. *
  917. * 19-Jan-1991 -by- Patrick Haluptzok patrickh
  918. * Wrote it.
  919. \**************************************************************************/
  920. #define PAL_MAX_SIZE 1024
  921. BOOL
  922. APIENTRY
  923. NtGdiResizePalette(
  924. HPALETTE hpal,
  925. UINT cEntry
  926. )
  927. {
  928. //
  929. // Check for quick out before constructors
  930. //
  931. if ((cEntry > PAL_MAX_SIZE) || (cEntry == 0))
  932. {
  933. WARNING("GreResizePalette failed - invalid size\n");
  934. return(FALSE);
  935. }
  936. BOOL bReturn = FALSE;
  937. //
  938. // Validate the parameter.
  939. //
  940. EPALOBJ palOld(hpal);
  941. if ((palOld.bValid()) && (!palOld.bIsPalDefault()) && (palOld.bIsPalDC()))
  942. {
  943. //
  944. // Create a new palette. Don't mark it to keep because after
  945. // bSwap it will be palOld and we want it to be deleted.
  946. //
  947. PALMEMOBJ pal;
  948. if (pal.bCreatePalette(PAL_INDEXED,
  949. cEntry,
  950. (PULONG) NULL,
  951. 0, 0, 0,
  952. PAL_DC | PAL_FREE))
  953. {
  954. //
  955. // Grab the palette semaphore which stops any palettes from being selected
  956. // in or out. It protects the linked DC list, can't copy DC head until
  957. // we hold it.
  958. //
  959. SEMOBJ semo(ghsemPalette);
  960. //
  961. // Copy the data from old palette.
  962. //
  963. pal.vCopyEntriesFrom(palOld);
  964. pal.flPalSet(palOld.flPal());
  965. pal.hdcHead(palOld.hdcHead());
  966. pal.hdev(palOld.hdev());
  967. pal.cRefhpal(palOld.cRefhpal());
  968. pal.vComputeCallTables();
  969. HDC hdcNext, hdcTemp;
  970. MLOCKFAST mlo;
  971. //
  972. // Run down the list and exclusive lock all the handles.
  973. //
  974. {
  975. hdcNext = pal.hdcHead();
  976. while (hdcNext != (HDC) 0)
  977. {
  978. MDCOBJ dcoLock(hdcNext);
  979. if (!dcoLock.bLocked())
  980. {
  981. WARNING1("ResizePalette failed because a DC the hpal is in is busy\n");
  982. break;
  983. }
  984. hdcNext = dcoLock.pdc->hdcNext();
  985. dcoLock.vDontUnlockDC();
  986. }
  987. }
  988. if (hdcNext == (HDC) 0)
  989. {
  990. //
  991. // We have the palette semaphore and all the DC's exclusively locked. Noone else
  992. // can be accessing the translates because you must hold one of those things to
  993. // access them. So we can delete the translates.
  994. //
  995. palOld.vMakeNoXlate();
  996. palOld.vUpdateTime();
  997. //
  998. // Note that bSwap calls locked SpapHandle vesrion so the Hmgr Resource
  999. // is required (luckily it was grabbed earlier).
  1000. //
  1001. //
  1002. // try to swap palettes, bSwap can only succedd if
  1003. // this routine owns the only locks on the objecs
  1004. //
  1005. bReturn = pal.bSwap((PPALETTE *) &palOld,1,1);
  1006. if (bReturn)
  1007. {
  1008. ASSERTGDI(bReturn, "ERROR no way");
  1009. //
  1010. // Run down all the DC's for this palette and update the pointer.
  1011. // Set the flags to dirty the brushes since we changed the palette.
  1012. //
  1013. {
  1014. hdcNext = pal.hdcHead();
  1015. while (hdcNext != (HDC)0)
  1016. {
  1017. MDCOBJA dcoAltLock(hdcNext);
  1018. dcoAltLock.pdc->ppal(palOld.ppalGet());
  1019. dcoAltLock.ulDirty(dcoAltLock.ulDirty() | DIRTY_BRUSHES);
  1020. hdcNext = dcoAltLock.pdc->hdcNext();
  1021. }
  1022. }
  1023. }
  1024. else
  1025. {
  1026. WARNING1("ResizePalette failed - ref count != 1\n");
  1027. }
  1028. }
  1029. else
  1030. {
  1031. WARNING1("ResizePalette failed lock of DC in chain\n");
  1032. }
  1033. //
  1034. // Unlock all the DC we have locked and return FALSE
  1035. //
  1036. {
  1037. hdcTemp = pal.hdcHead();
  1038. while (hdcTemp != hdcNext)
  1039. {
  1040. MDCOBJ dcoUnlock(hdcTemp);
  1041. ASSERTGDI(dcoUnlock.bLocked(), "ERROR couldn't re-lock to unlock");
  1042. DEC_EXCLUSIVE_REF_CNT(dcoUnlock.pdc);
  1043. hdcTemp = dcoUnlock.pdc->hdcNext();
  1044. }
  1045. }
  1046. }
  1047. else
  1048. {
  1049. WARNING("GreResizePalette failed palette creation\n");
  1050. }
  1051. }
  1052. else
  1053. {
  1054. WARNING("GreResizePalette failed invalid hpal\n");
  1055. }
  1056. return(bReturn);
  1057. }
  1058. /******************************Public*Routine******************************\
  1059. * GreUpdateColors
  1060. *
  1061. * API function - Updates the colors in the Visible Region for a Window on
  1062. * a palette mangaged device.
  1063. *
  1064. * This is an example of how UpdateColors is used:
  1065. *
  1066. * case WM_PALETTECHANGED:
  1067. *
  1068. * // if NTPAL was not responsible for palette change and if
  1069. * // palette realization causes a palette change, do a redraw.
  1070. *
  1071. * if ((HWND)wParam != hWnd)
  1072. * {
  1073. * if (bLegitDraw)
  1074. * {
  1075. * hDC = GetDC(hWnd);
  1076. * hOldPal = SelectPalette(hDC, hpalCurrent, 0);
  1077. *
  1078. * i = RealizePalette(hDC);
  1079. *
  1080. * if (i)
  1081. * {
  1082. * if (bUpdateColors)
  1083. * {
  1084. * UpdateColors(hDC);
  1085. * UpdateCount++;
  1086. * }
  1087. * else
  1088. * InvalidateRect(hWnd, (LPRECT) (NULL), 1);
  1089. * }
  1090. *
  1091. * SelectPalette(hDC, hOldPal, 0);
  1092. * ReleaseDC(hWnd, hDC);
  1093. * }
  1094. * }
  1095. * break;
  1096. *
  1097. * The hpal can only be selected into 1 type of device DC at a time.
  1098. * Xlates from the DC palette to the surface palette are only done on DC's
  1099. * that are for the PDEV surface. Since an hpal can only be selected into
  1100. * one of these and creation and deletion of the pxlate needs to be semaphored
  1101. * we use the PDEV semaphore to protect it's access.
  1102. *
  1103. * An xlate vector mapping the DC palette to the surface palette is created
  1104. * during a RealizePalette if the surface is a palette managed device. This
  1105. * is put in pxlate in the hpal. The old pxlate is moved into pxlateOld
  1106. * and the xlate in pxlateOld is deleted. UpdateColors works by looking at
  1107. * the difference between the current xlate mapping and the old xlate mapping
  1108. * and updating the pixels in the VisRgn to get a closest mapping.
  1109. *
  1110. * This API can only be called once for a palette. The old xlate is deleted
  1111. * during UpdateColors so that the next time it is called it will fail. This
  1112. * is because it only makes sense to update the pixels once. Doing it more
  1113. * than once would give ugly unpredictable results.
  1114. *
  1115. * History:
  1116. * 12-Dec-1991 -by- Patrick Haluptzok patrickh
  1117. * Wrote it.
  1118. \**************************************************************************/
  1119. BOOL APIENTRY NtGdiUpdateColors(HDC hdc)
  1120. {
  1121. BOOL bReturn = FALSE;
  1122. DCOBJ dco(hdc);
  1123. if (!dco.bValidSurf())
  1124. {
  1125. return(FALSE);
  1126. }
  1127. PDEVOBJ pdo(dco.hdev());
  1128. //
  1129. // Grab DEVLOCK for output and to lock the surface
  1130. //
  1131. DEVLOCKOBJ dlo(dco);
  1132. if (pdo.bIsPalManaged())
  1133. {
  1134. SURFACE *pSurf = dco.pSurface();
  1135. //
  1136. // This only works on palette managed surfaces.
  1137. //
  1138. if (pSurf == pdo.pSurface())
  1139. {
  1140. XEPALOBJ palSurf(pSurf->ppal());
  1141. XEPALOBJ palDC(dco.ppal());
  1142. //
  1143. // Accumulate bounds. We can do this before knowing if the operation is
  1144. // successful because bounds can be loose.
  1145. //
  1146. if (dco.fjAccum())
  1147. dco.vAccumulate(dco.erclWindow());
  1148. if (dlo.bValid())
  1149. {
  1150. if ((palDC.ptransCurrent() != NULL) &&
  1151. (palDC.ptransOld() != NULL))
  1152. {
  1153. XLATEMEMOBJ xlo(palSurf, palDC);
  1154. if (xlo.bValid())
  1155. {
  1156. ECLIPOBJ co(dco.prgnEffRao(), dco.erclWindow());
  1157. //
  1158. // Check the destination which is reduced by clipping.
  1159. //
  1160. if (!co.erclExclude().bEmpty())
  1161. {
  1162. //
  1163. // Exclude the pointer.
  1164. //
  1165. DEVEXCLUDEOBJ dxo(dco,&co.erclExclude(),&co);
  1166. //
  1167. // Inc the target surface uniqueness
  1168. //
  1169. INC_SURF_UNIQ(pSurf);
  1170. if (!pdo.bMetaDriver())
  1171. {
  1172. //
  1173. // Dispatch the call. Give it no mask.
  1174. //
  1175. bReturn = (*PPFNGET(pdo, CopyBits, pSurf->flags())) (
  1176. pSurf->pSurfobj(),
  1177. pSurf->pSurfobj(),
  1178. &co,
  1179. xlo.pxlo(),
  1180. (RECTL *) &co.erclExclude(),
  1181. (POINTL *) &co.erclExclude());
  1182. }
  1183. else
  1184. {
  1185. //
  1186. // Dispatch to DDML.
  1187. //
  1188. bReturn = MulUpdateColors(
  1189. pSurf->pSurfobj(),
  1190. &co,
  1191. xlo.pxlo());
  1192. }
  1193. }
  1194. else
  1195. bReturn = TRUE;
  1196. }
  1197. }
  1198. else
  1199. bReturn = TRUE; // Nothing to update
  1200. }
  1201. else
  1202. {
  1203. bReturn = dco.bFullScreen();
  1204. }
  1205. }
  1206. }
  1207. return(bReturn);
  1208. }
  1209. /******************************Public*Routine******************************\
  1210. * RealizeDefaultPalette
  1211. *
  1212. * Take away colors that have been realized by other Windows. Reset it to
  1213. * state where no colors have been taken. Return number of colors
  1214. *
  1215. * History:
  1216. * 07-Jan-1993 -by- Patrick Haluptzok patrickh
  1217. * Wrote it.
  1218. \**************************************************************************/
  1219. extern "C"
  1220. ULONG GreRealizeDefaultPalette(
  1221. HDC hdcScreen,
  1222. BOOL bClearDefaultPalette)
  1223. {
  1224. DCOBJ dco(hdcScreen);
  1225. if (dco.bValid())
  1226. {
  1227. PDEVOBJ po(dco.hdev());
  1228. //
  1229. // Block out the GreRealizePalette code. Also protect us from
  1230. // dynamic mode changes while we grunge in the surface palette.
  1231. //
  1232. DEVLOCKOBJ dlo(po);
  1233. SEMOBJ semo(ghsemPalette);
  1234. if (po.bIsPalManaged())
  1235. {
  1236. XEPALOBJ palSurf(po.ppalSurf());
  1237. ASSERTGDI(palSurf.bIsPalManaged(), "GreRealizeDefaultPalette");
  1238. //
  1239. // Now map back to static colors if necesary. Win3.1 does not do this but we do
  1240. // just in case naughty app died and left the palette hosed.
  1241. //
  1242. //
  1243. if (palSurf.bIsNoStatic() || palSurf.bIsNoStatic256())
  1244. {
  1245. GreSetSystemPaletteUse(hdcScreen, SYSPAL_STATIC);
  1246. }
  1247. //
  1248. // Get rid of the PC_FOREGROUND flag from the non-reserved entries.
  1249. //
  1250. ULONG ulTemp = palSurf.ulNumReserved() >> 1;
  1251. ULONG ulMax = palSurf.cEntries() - ulTemp;
  1252. for (; ulTemp < ulMax; ulTemp++)
  1253. {
  1254. palSurf.apalColorGet()[ulTemp].pal.peFlags &= (~PC_FOREGROUND);
  1255. }
  1256. if (bClearDefaultPalette)
  1257. {
  1258. hForePalette = NULL;
  1259. }
  1260. palSurf.vUpdateTime();
  1261. //
  1262. // Mark the brushes dirty.
  1263. //
  1264. dco.ulDirty(dco.ulDirty() | DIRTY_BRUSHES);
  1265. }
  1266. }
  1267. else
  1268. {
  1269. WARNING("ERROR User called RealizeDefaultPalette with bad hdc\n");
  1270. }
  1271. //
  1272. // What should this return value be ?
  1273. //
  1274. return(0);
  1275. }
  1276. /******************************Public*Routine******************************\
  1277. * UnrealizeObject
  1278. *
  1279. * Resets a logical palette.
  1280. *
  1281. * History:
  1282. * 16-May-1993 -by- Patrick Haluptzok patrickh
  1283. * Wrote it.
  1284. \**************************************************************************/
  1285. BOOL GreUnrealizeObject(HANDLE hpal)
  1286. {
  1287. BOOL bReturn = FALSE;
  1288. EPALOBJ pal((HPALETTE) hpal);
  1289. if (pal.bValid())
  1290. {
  1291. //
  1292. // You must grab the palette semaphore to access the translates.
  1293. //
  1294. SEMOBJ semo(ghsemPalette);
  1295. if (pal.ptransFore() != NULL)
  1296. {
  1297. pal.ptransFore()->iUniq = 0;
  1298. }
  1299. if (pal.ptransCurrent() != NULL)
  1300. {
  1301. pal.ptransCurrent()->iUniq = 0;
  1302. }
  1303. bReturn = TRUE;
  1304. }
  1305. return(bReturn);
  1306. }
  1307. /******************************Public*Routine******************************\
  1308. * GreRealizePalette
  1309. *
  1310. * Re-written to be Win3.1 compatible.
  1311. *
  1312. * History:
  1313. * 22-Nov-1992 -by- Patrick Haluptzok patrickh
  1314. * Wrote it.
  1315. \**************************************************************************/
  1316. extern "C" DWORD GreRealizePalette(HDC hdc)
  1317. {
  1318. ULONG nTransChanged = 0;
  1319. ULONG nPhysChanged = 0;
  1320. DCOBJ dco(hdc);
  1321. if (dco.bValid())
  1322. {
  1323. PDEVOBJ po(dco.hdev());
  1324. //
  1325. // Lock the screen semaphore so that we don't get flipped into
  1326. // full screen after checking the bit. This also protects us
  1327. // from dynamic mode changes that change the 'bIsPalManaged'
  1328. // status.
  1329. //
  1330. DEVLOCKOBJ dlo(po);
  1331. XEPALOBJ palSurf(po.ppalSurf());
  1332. XEPALOBJ palDC(dco.ppal());
  1333. HPALETTE hpalDC = palDC.hpal();
  1334. HDC hdcNext, hdcTemp;
  1335. if (po.bIsPalManaged())
  1336. {
  1337. ASSERTGDI(palSurf.bIsPalManaged(), "GreRealizePalette");
  1338. //
  1339. // Access to the ptrans and the fields of the hpal are protected by
  1340. // this semaphore.
  1341. //
  1342. SEMOBJ semo(ghsemPalette);
  1343. if ((SAMEHANDLE(hpalDC,hForePalette)) ||
  1344. ((dco.pdc->iGraphicsMode() == GM_COMPATIBLE) &&
  1345. (SAMEINDEX(hpalDC, hForePalette)) &&
  1346. (hForePID == W32GetCurrentProcess())))
  1347. {
  1348. //
  1349. // Check for early out.
  1350. //
  1351. if (palDC.bIsPalDefault())
  1352. {
  1353. //
  1354. // Do nothing.
  1355. //
  1356. PAL_DEBUG(2,"DC has default palette quick out\n");
  1357. }
  1358. else
  1359. {
  1360. if ((palDC.ptransFore() != NULL) &&
  1361. (palDC.ptransFore() == palDC.ptransCurrent()) &&
  1362. (palDC.ptransFore()->iUniq == palSurf.ulTime()))
  1363. {
  1364. //
  1365. // Everything is valid.
  1366. //
  1367. PAL_DEBUG(2,"ptransCurrent == ptransFore quick out\n");
  1368. }
  1369. else
  1370. {
  1371. MLOCKFAST mlo;
  1372. //
  1373. // Run down the list and exclusive lock all the handles.
  1374. //
  1375. {
  1376. hdcNext = palDC.hdcHead();
  1377. while (hdcNext != (HDC) 0)
  1378. {
  1379. MDCOBJ dcoLock(hdcNext);
  1380. if (!dcoLock.bLocked())
  1381. {
  1382. WARNING1("GreRealizePalette failed because a DC the hpal is in is busy\n");
  1383. break;
  1384. }
  1385. dcoLock.ulDirty(dco.ulDirty() | DIRTY_BRUSHES);
  1386. hdcNext = dcoLock.pdc->hdcNext();
  1387. dcoLock.vDontUnlockDC();
  1388. }
  1389. }
  1390. if (hdcNext == (HDC) 0)
  1391. {
  1392. //
  1393. // Get rid of the old mapping, it is useless now.
  1394. //
  1395. if (palDC.ptransOld())
  1396. {
  1397. if (palDC.ptransOld() != palDC.ptransFore())
  1398. VFREEMEM(palDC.ptransOld());
  1399. palDC.ptransOld(NULL);
  1400. }
  1401. //
  1402. // Check if we have stale translates.
  1403. // UnrealizeObject and SetPaletteEntries can cause it.
  1404. //
  1405. if ((palDC.ptransFore()) && (palDC.ptransFore()->iUniq == 0))
  1406. {
  1407. if (palDC.ptransCurrent() != palDC.ptransFore())
  1408. VFREEMEM(palDC.ptransFore());
  1409. palDC.ptransFore(NULL);
  1410. }
  1411. //
  1412. // Check if we need a new foreground realization.
  1413. //
  1414. if (palDC.ptransFore() == NULL)
  1415. {
  1416. //
  1417. // Need to force ourselves in for the first time.
  1418. //
  1419. PAL_DEBUG(2,"Creating a foreground realization\n");
  1420. palDC.ptransFore(ptransMatchAPal(dco.pdc,palSurf, palDC, TRUE, &nPhysChanged, &nTransChanged));
  1421. if (palDC.ptransFore() == NULL)
  1422. {
  1423. WARNING("RealizePalette failed initial foreground realize\n");
  1424. }
  1425. }
  1426. else
  1427. {
  1428. //
  1429. // Foreground Realize already done and isn't stale.
  1430. // Force the foreground mapping into the physical palette.
  1431. //
  1432. PAL_DEBUG(2,"Forcing a foreground realization in to palette\n");
  1433. vMatchAPal(dco.pdc,palSurf, palDC, &nPhysChanged, &nTransChanged);
  1434. }
  1435. palDC.ptransOld(palDC.ptransCurrent());
  1436. palDC.ptransCurrent(palDC.ptransFore());
  1437. }
  1438. else
  1439. {
  1440. WARNING("GreRealizePalette failed to lock down all DC's in linked list\n");
  1441. }
  1442. //
  1443. // Unlock all the DC we have locked.
  1444. //
  1445. {
  1446. hdcTemp = palDC.hdcHead();
  1447. while (hdcTemp != hdcNext)
  1448. {
  1449. MDCOBJ dcoUnlock(hdcTemp);
  1450. ASSERTGDI(dcoUnlock.bLocked(), "ERROR couldn't re-lock to unlock");
  1451. DEC_EXCLUSIVE_REF_CNT(dcoUnlock.pdc);
  1452. hdcTemp = dcoUnlock.pdc->hdcNext();
  1453. }
  1454. }
  1455. }
  1456. }
  1457. }
  1458. else
  1459. {
  1460. //
  1461. // We are a background palette.
  1462. //
  1463. if (!palDC.bIsPalDefault())
  1464. {
  1465. //
  1466. // Check for the quick out.
  1467. //
  1468. if ((palDC.ptransCurrent() != NULL) &&
  1469. (palDC.ptransCurrent()->iUniq == palSurf.ulTime()))
  1470. {
  1471. //
  1472. // Well it's good enough. Nothing has changed that
  1473. // would give us any better mapping.
  1474. //
  1475. PAL_DEBUG(2,"ptransCurrent not foreground but good enough\n");
  1476. }
  1477. else
  1478. {
  1479. MLOCKFAST mlo;
  1480. //
  1481. // Run down the list and exclusive lock all the handles.
  1482. //
  1483. {
  1484. hdcNext = palDC.hdcHead();
  1485. while (hdcNext != (HDC) 0)
  1486. {
  1487. MDCOBJ dcoLock(hdcNext);
  1488. if (!dcoLock.bLocked())
  1489. {
  1490. WARNING1("GreRealizePalette failed because a DC the hpal is in is busy\n");
  1491. break;
  1492. }
  1493. dcoLock.ulDirty(dco.ulDirty() | DIRTY_BRUSHES);
  1494. hdcNext = dcoLock.pdc->hdcNext();
  1495. dcoLock.vDontUnlockDC();
  1496. }
  1497. }
  1498. if (hdcNext == (HDC) 0)
  1499. {
  1500. //
  1501. // We have work to do, get rid of the old translate.
  1502. //
  1503. if (palDC.ptransOld())
  1504. {
  1505. if (palDC.ptransOld() != palDC.ptransFore())
  1506. VFREEMEM(palDC.ptransOld());
  1507. palDC.ptransOld(NULL);
  1508. }
  1509. //
  1510. // Check if we have stale translates.
  1511. // UnrealizeObject and SetPaletteEntries can cause it.
  1512. //
  1513. if ((palDC.ptransFore()) && (palDC.ptransFore()->iUniq == 0))
  1514. {
  1515. if (palDC.ptransCurrent() != palDC.ptransFore())
  1516. {
  1517. VFREEMEM(palDC.ptransFore());
  1518. }
  1519. palDC.ptransFore(NULL);
  1520. }
  1521. //
  1522. // Check for initial foreground realization.
  1523. //
  1524. PAL_DEBUG(2,"Realizing in the background\n");
  1525. if (palDC.ptransFore() == NULL)
  1526. {
  1527. //
  1528. // Create a scratch pad to establish a foreground realize.
  1529. //
  1530. PAL_DEBUG(2,"Making ptransFore in the background\n");
  1531. PALMEMOBJ palTemp;
  1532. if (palTemp.bCreatePalette(PAL_INDEXED,
  1533. palSurf.cEntries(),
  1534. NULL,
  1535. 0, 0, 0, PAL_MANAGED))
  1536. {
  1537. ULONG ulTemp = 0;
  1538. ASSERTGDI(palTemp.cEntries() == 256, "ERROR palTemp invalid");
  1539. palTemp.vCopyEntriesFrom(palSurf);
  1540. palTemp.ulNumReserved(palSurf.ulNumReserved());
  1541. palTemp.flPalSet(palSurf.flPal());
  1542. palTemp.vComputeCallTables();
  1543. PAL_DEBUG(2,"Need to make a foreground realize first\n");
  1544. //
  1545. // Need to map ourselves for the first time. This actually doesn't
  1546. // change the current surface palette but instead computes the
  1547. // translate vector that would result if it was to be mapped in now.
  1548. //
  1549. palDC.ptransFore(ptransMatchAPal(dco.pdc,palTemp, palDC, TRUE, &ulTemp, &ulTemp));
  1550. }
  1551. #if DBG
  1552. if (palDC.ptransFore() == NULL)
  1553. {
  1554. WARNING("RealizePalette failed initial foreground realize\n");
  1555. }
  1556. #endif
  1557. }
  1558. //
  1559. // Save the Current mapping into Old.
  1560. //
  1561. palDC.ptransOld(palDC.ptransCurrent());
  1562. if (palDC.ptransFore() == NULL)
  1563. {
  1564. //
  1565. // The Current can't be set if the Fore
  1566. // is NULL so we're done.
  1567. //
  1568. palDC.ptransCurrent(NULL);
  1569. }
  1570. else
  1571. {
  1572. //
  1573. // Get the new Current mapping.
  1574. //
  1575. PAL_DEBUG(2,"Making ptransCurrent\n");
  1576. palDC.ptransCurrent(ptransMatchAPal(dco.pdc,palSurf, palDC, FALSE, &nPhysChanged, &nTransChanged));
  1577. if (palDC.ptransCurrent() == NULL)
  1578. {
  1579. //
  1580. // Well we can't have the foreground set
  1581. // and the current being NULL so just
  1582. // make it foreground for this memory
  1583. // failure case.
  1584. //
  1585. palDC.ptransCurrent(palDC.ptransFore());
  1586. WARNING("ptransCurrent failed allocation in RealizePalette");
  1587. }
  1588. }
  1589. }
  1590. //
  1591. // Unlock all the DC we have locked.
  1592. //
  1593. {
  1594. hdcTemp = palDC.hdcHead();
  1595. while (hdcTemp != hdcNext)
  1596. {
  1597. MDCOBJ dcoUnlock(hdcTemp);
  1598. ASSERTGDI(dcoUnlock.bLocked(), "ERROR couldn't re-lock to unlock");
  1599. DEC_EXCLUSIVE_REF_CNT(dcoUnlock.pdc);
  1600. hdcTemp = dcoUnlock.pdc->hdcNext();
  1601. }
  1602. }
  1603. }
  1604. }
  1605. }
  1606. }
  1607. //
  1608. // Check if the device needs to be notified.
  1609. //
  1610. if (nPhysChanged)
  1611. {
  1612. //
  1613. // Lock the screen semaphore so that we don't get flipped into
  1614. // full screen after checking the bit.
  1615. //
  1616. GreAcquireSemaphoreEx(po.hsemDevLock(), SEMORDER_DEVLOCK, NULL);
  1617. GreEnterMonitoredSection(po.ppdev, WD_DEVLOCK);
  1618. {
  1619. SEMOBJ so(po.hsemPointer());
  1620. if (!po.bDisabled())
  1621. {
  1622. po.pfnSetPalette()(
  1623. po.dhpdevParent(),
  1624. (PALOBJ *) &palSurf,
  1625. 0,
  1626. 0,
  1627. palSurf.cEntries());
  1628. }
  1629. }
  1630. GreExitMonitoredSection(po.ppdev, WD_DEVLOCK);
  1631. GreReleaseSemaphoreEx(po.hsemDevLock());
  1632. //
  1633. // mark palsurf if it is a halftone palette
  1634. //
  1635. if (palSurf.cEntries() == 256)
  1636. {
  1637. ULONG ulIndex;
  1638. for (ulIndex=0;ulIndex<256;ulIndex++)
  1639. {
  1640. if (
  1641. (palSurf.ulEntryGet(ulIndex) & 0xffffff) !=
  1642. (aPalHalftone[ulIndex].ul & 0xffffff)
  1643. )
  1644. {
  1645. break;
  1646. }
  1647. }
  1648. if (ulIndex == 256)
  1649. {
  1650. palSurf.flPal(PAL_HT);
  1651. }
  1652. else
  1653. {
  1654. FLONG fl = palSurf.flPal();
  1655. fl &= ~PAL_HT;
  1656. palSurf.flPalSet(fl);
  1657. }
  1658. }
  1659. }
  1660. }
  1661. return(nTransChanged | (nPhysChanged << 16));
  1662. }
  1663. /******************************Public*Routine******************************\
  1664. * IsDCCurrentPalette
  1665. *
  1666. * Returns TRUE if the palette is the foreground palette.
  1667. *
  1668. * History:
  1669. * 18-May-1993 -by- Patrick Haluptzok patrickh
  1670. * Wrote it.
  1671. \**************************************************************************/
  1672. extern "C" BOOL IsDCCurrentPalette(HDC hdc)
  1673. {
  1674. BOOL bReturn = FALSE;
  1675. DCOBJ dco(hdc);
  1676. if (dco.bValid())
  1677. {
  1678. if ((SAMEHANDLE(dco.hpal(), (HPAL)hForePalette)) ||
  1679. ((dco.pdc->iGraphicsMode() == GM_COMPATIBLE) &&
  1680. (SAMEINDEX(dco.hpal(), hForePalette)) &&
  1681. (hForePID == W32GetCurrentProcess())))
  1682. {
  1683. bReturn = TRUE;
  1684. }
  1685. }
  1686. return(bReturn);
  1687. }
  1688. /******************************Public*Routine******************************\
  1689. * GreSelectPalette
  1690. *
  1691. * API function for selecting palette into the DC.
  1692. *
  1693. * Returns previous hpal if successful, (HPALETTE) 0 for failure.
  1694. *
  1695. * History:
  1696. * 17-Nov-1990 -by- Patrick Haluptzok patrickh
  1697. * Wrote it.
  1698. \**************************************************************************/
  1699. extern "C"
  1700. HPALETTE GreSelectPalette(
  1701. HDC hdc,
  1702. HPALETTE hpalNew,
  1703. BOOL bForceBackground)
  1704. {
  1705. //
  1706. // The palette semaphore serializes access to the reference count and
  1707. // the linked list of DC's a palette is selected into. We don't want
  1708. // 2 people trying to select at the same time. We must hold this between
  1709. // the setting of the hsem and the incrementing of the reference count.
  1710. //
  1711. SEMOBJ semo(ghsemPalette);
  1712. //
  1713. // Validate and lock down the DC and new palette.
  1714. //
  1715. DCOBJ dco(hdc);
  1716. EPALOBJ palNew(hpalNew);
  1717. #if DBG
  1718. if (DbgPal >= 2)
  1719. {
  1720. DbgPrint("GreSelectPalette %p\n",palNew.ppalGet());
  1721. }
  1722. #endif
  1723. if ((!dco.bLocked()) ||
  1724. (!palNew.bValid())|| (!palNew.bIsPalDC()))
  1725. {
  1726. //
  1727. // Error code logged by failed lock.
  1728. //
  1729. WARNING1("GreSelectPalette failed, invalid palette or DC\n");
  1730. return((HPALETTE)NULL);
  1731. }
  1732. if (!bForceBackground)
  1733. {
  1734. hForePID = W32GetCurrentProcess();
  1735. hForePalette = hpalNew;
  1736. }
  1737. HPAL hpalOld = (HPAL) dco.hpal();
  1738. if (SAMEHANDLE(hpalOld,(HPAL)hpalNew))
  1739. {
  1740. return((HPALETTE)hpalOld);
  1741. }
  1742. PDEVOBJ po(dco.hdev());
  1743. XEPALOBJ palOld(dco.ppal());
  1744. //
  1745. // Check that we aren't trying to select the palette into a
  1746. // device incompatible with a type we are already selected into.
  1747. // We need to be able to translate from the DC hpal to the surface hpal
  1748. // to do Animate, ect. So we can only be selected into one
  1749. // surface with a PAL_MANAGED hpal because we only maintain one
  1750. // translate table in the DC hpal.
  1751. //
  1752. if (!palNew.bIsPalDefault())
  1753. {
  1754. if (!palNew.bSet_hdev(dco.hdev()))
  1755. {
  1756. WARNING("GreSelectPalette failed hsemDisplay check\n");
  1757. return((HPALETTE)NULL);
  1758. }
  1759. }
  1760. //
  1761. // Grab the multi-lock semaphore to run the DC link list.
  1762. //
  1763. MLOCKFAST mlo;
  1764. //
  1765. // Take care of the old hpal. Remove from linked list. Decrement cRef.
  1766. // Remove the hdc from the linked list of DC's associated with palette.
  1767. //
  1768. palOld.vRemoveFromList(dco);
  1769. //
  1770. // Set the new palette in so the old hpal is truly gone.
  1771. //
  1772. dco.pdc->hpal((HPAL)hpalNew);
  1773. dco.pdc->ppal(palNew.ppalGet());
  1774. dco.ulDirty(dco.ulDirty() | DIRTY_BRUSHES);
  1775. //
  1776. // Associate the palette with the bitmap for use when converting DDBs
  1777. // to DIBs for dynamic mode changes. We don't associate the default
  1778. // palette because the normal usage pattern is:
  1779. //
  1780. // hpalOld = SelectPalette(hdc, hpal);
  1781. // RealizePalette(hdc);
  1782. // BitBlt(hdc);
  1783. // SelectPalette(hdc, hpalOld);
  1784. //
  1785. if ((dco.bHasSurface()) && (!palNew.bIsPalDefault()))
  1786. {
  1787. dco.pSurface()->hpalHint(hpalNew);
  1788. }
  1789. //
  1790. // Take care of the new hpal.
  1791. //
  1792. palNew.vAddToList(dco);
  1793. return((HPALETTE)hpalOld);
  1794. }
  1795. /******************************Public*Routine******************************\
  1796. * ulMagicFind - look for given magic color in default palette
  1797. *
  1798. * Arguments:
  1799. *
  1800. * clrMagic - COLORREF of color to search for
  1801. *
  1802. * Return Value:
  1803. *
  1804. * Index if found, 0xffffffff if not found.
  1805. *
  1806. * History:
  1807. *
  1808. * 15-Nov-1995 -by- Mark Enstrom [marke]
  1809. *
  1810. \**************************************************************************/
  1811. ULONG
  1812. ulMagicFind(
  1813. PALETTEENTRY peMagic
  1814. )
  1815. {
  1816. XEPALOBJ xePalDefault(ppalDefault);
  1817. return(xePalDefault.ulGetMatchFromPalentry(peMagic));
  1818. }
  1819. /******************************Public*Routine******************************\
  1820. * bSetMagicColor - set the specified magic color in both the device
  1821. * palette and the default palette
  1822. *
  1823. * Arguments:
  1824. *
  1825. * hdev - hdev
  1826. * Index - magic color index (8,9,246,247)
  1827. * palSurf - surface palette
  1828. * palDC - logical palette
  1829. * palColor - magic color
  1830. *
  1831. * Return Value:
  1832. *
  1833. * Status
  1834. *
  1835. * History:
  1836. *
  1837. * 15-Nov-1995 -by- Mark Enstrom [marke]
  1838. *
  1839. \**************************************************************************/
  1840. extern PPALETTE gppalHalftone;
  1841. BOOL
  1842. bSetMagicColor(
  1843. XEPALOBJ palSurf,
  1844. ULONG ulIndex,
  1845. PAL_ULONG PalEntry
  1846. )
  1847. {
  1848. BOOL bRet = FALSE;
  1849. ASSERTGDI(((ulIndex == 8) || (ulIndex == 9) || (ulIndex == 246) || (ulIndex == 247)),
  1850. "bSetMagicColor Error, wrong palette index");
  1851. //
  1852. // make sure there are 20 reserved entries, and the static
  1853. // colors are in use
  1854. //
  1855. if (
  1856. (palSurf.ulNumReserved() == 20) &&
  1857. (!palSurf.bIsNoStatic()) &&
  1858. (!palSurf.bIsNoStatic256())
  1859. )
  1860. {
  1861. //
  1862. // set the entrie in the surface palette
  1863. //
  1864. PalEntry.pal.peFlags = PC_FOREGROUND | PC_USED;
  1865. palSurf.ulEntrySet(ulIndex,PalEntry.ul);
  1866. //
  1867. // update the palette time stamp
  1868. //
  1869. palSurf.vUpdateTime();
  1870. //
  1871. // set colors in the defaukt halftone palette for multimon system
  1872. //
  1873. if (gppalHalftone)
  1874. {
  1875. XEPALOBJ palHalftone(gppalHalftone);
  1876. palHalftone.ulEntrySet(ulIndex,PalEntry.ul);
  1877. }
  1878. //
  1879. // offset to upper half of default palette if needed
  1880. //
  1881. if (ulIndex > 10)
  1882. {
  1883. ulIndex = ulIndex - 236;
  1884. }
  1885. PalEntry.pal.peFlags = 0;
  1886. //
  1887. // set colors in the default Logical palette.
  1888. //
  1889. logDefaultPal.palPalEntry[ulIndex] = PalEntry.pal;
  1890. //
  1891. // set colors in the default palette and default log palette
  1892. //
  1893. XEPALOBJ palDefault(ppalDefault);
  1894. palDefault.ulEntrySet(ulIndex,PalEntry.ul);
  1895. bRet = TRUE;
  1896. }
  1897. return(bRet);
  1898. }
  1899. /******************************Public*Routine******************************\
  1900. * vResetSurfacePalette - copy the magic colors from the default palette
  1901. * to the surface palette, and call the driver to set the palette
  1902. *
  1903. * NOTE: The devlock and pointer semaphore must already be held!
  1904. *
  1905. * Arguments:
  1906. *
  1907. * po - PDEV object
  1908. * palSurf - surface palette
  1909. *
  1910. * Return Value:
  1911. *
  1912. * Status
  1913. *
  1914. * History:
  1915. *
  1916. * 21-Mar-1996 -by- J. Andrew Goossen [andrewgo]
  1917. *
  1918. \**************************************************************************/
  1919. VOID
  1920. vResetSurfacePalette(
  1921. HDEV hdev
  1922. )
  1923. {
  1924. PDEVOBJ po(hdev);
  1925. if (po.bIsPalManaged())
  1926. {
  1927. XEPALOBJ palSurf(po.ppalSurf());
  1928. ASSERTGDI(palSurf.bValid(), "Invalid surface palette");
  1929. if (
  1930. (palSurf.ulNumReserved() == 20) &&
  1931. (!palSurf.bIsNoStatic()) &&
  1932. (!palSurf.bIsNoStatic256())
  1933. )
  1934. {
  1935. PAL_ULONG PalEntry;
  1936. XEPALOBJ palDefault(ppalDefault);
  1937. //
  1938. // set the entries in the surface palette
  1939. //
  1940. PalEntry.pal = palDefault.palentryGet(8);
  1941. PalEntry.pal.peFlags = PC_FOREGROUND | PC_USED;
  1942. palSurf.ulEntrySet(8,PalEntry.ul);
  1943. PalEntry.pal = palDefault.palentryGet(9);
  1944. PalEntry.pal.peFlags = PC_FOREGROUND | PC_USED;
  1945. palSurf.ulEntrySet(9,PalEntry.ul);
  1946. PalEntry.pal = palDefault.palentryGet(246 - 236);
  1947. PalEntry.pal.peFlags = PC_FOREGROUND | PC_USED;
  1948. palSurf.ulEntrySet(246,PalEntry.ul);
  1949. PalEntry.pal = palDefault.palentryGet(247 - 236);
  1950. PalEntry.pal.peFlags = PC_FOREGROUND | PC_USED;
  1951. palSurf.ulEntrySet(247,PalEntry.ul);
  1952. }
  1953. if (!po.bDisabled())
  1954. {
  1955. (*PPFNDRV(po,SetPalette))(
  1956. po.dhpdev(),
  1957. (PALOBJ *) &palSurf,
  1958. 0,
  1959. 0,
  1960. palSurf.cEntries());
  1961. }
  1962. }
  1963. }
  1964. /******************************Public*Routine******************************\
  1965. *
  1966. * GreSetMagicColor win95 compatible: set surface and default palette
  1967. * "magic" entries. This changes the default palette,
  1968. * and will affect bitmaps that think they have the
  1969. * correct 20 default colors already...
  1970. *
  1971. * Arguments:
  1972. *
  1973. * hdc - DC, specifies device surface
  1974. * Index - magic index, 1 of 8,9,246,247
  1975. * peMagic - new color
  1976. *
  1977. * Return Value:
  1978. *
  1979. * Status
  1980. *
  1981. * History:
  1982. *
  1983. * 10-Nov-1995 -by- Mark Enstrom [marke]
  1984. *
  1985. \**************************************************************************/
  1986. BOOL
  1987. NtGdiSetMagicColors(
  1988. HDC hdc,
  1989. PALETTEENTRY peMagic,
  1990. ULONG Index
  1991. )
  1992. {
  1993. return(GreSetMagicColors(hdc,peMagic,Index));
  1994. }
  1995. BOOL
  1996. GreSetMagicColors(
  1997. HDC hdc,
  1998. PALETTEENTRY peMagic,
  1999. ULONG Index
  2000. )
  2001. {
  2002. DCOBJ dco(hdc);
  2003. BOOL bRet = FALSE;
  2004. BOOL bPaletteChange = FALSE;
  2005. BOOL bChildDriver = FALSE;
  2006. if (dco.bValid())
  2007. {
  2008. if (
  2009. (Index == 8) ||
  2010. (Index == 9) ||
  2011. (Index == 246) ||
  2012. (Index == 247)
  2013. )
  2014. {
  2015. PAL_ULONG PalEntry;
  2016. PalEntry.pal = peMagic;
  2017. //
  2018. // must be RGB or PALETTERGB
  2019. //
  2020. if (
  2021. ((PalEntry.ul & 0xff000000) == 0) ||
  2022. ((PalEntry.ul & 0xff000000) == 0x02000000)
  2023. )
  2024. {
  2025. PDEVOBJ po(dco.hdev());
  2026. BOOL bSetColor = FALSE;
  2027. //
  2028. // Lock the screen semaphore so that we don't get flipped into
  2029. // full screen after checking the bit. Plus it also protects
  2030. // us from a dynamic mode change, which can change the
  2031. // bIsPalManaged status.
  2032. //
  2033. DEVLOCKOBJ dlo(po);
  2034. if (po.bIsPalManaged())
  2035. {
  2036. bSetColor = TRUE;
  2037. }
  2038. else if (po.bMetaDriver())
  2039. {
  2040. //
  2041. // If this is meta-driver, check if there is any palette device
  2042. //
  2043. PVDEV pvdev = (VDEV*) po.dhpdev();
  2044. PDISPSURF pds = pvdev->pds;
  2045. LONG csurf = pvdev->cSurfaces;
  2046. do
  2047. {
  2048. po.vInit(pds->hdev);
  2049. if (po.bIsPalManaged())
  2050. {
  2051. bSetColor = TRUE;
  2052. bChildDriver = TRUE;
  2053. break;
  2054. }
  2055. pds = pds->pdsNext;
  2056. } while (--csurf);
  2057. }
  2058. if (bSetColor)
  2059. {
  2060. XEPALOBJ palSurf(po.ppalSurf());
  2061. //
  2062. // palette sem scope
  2063. //
  2064. {
  2065. SEMOBJ semPalette(ghsemPalette);
  2066. //
  2067. // look for color
  2068. //
  2069. ULONG ulMagicIndex = ulMagicFind(PalEntry.pal);
  2070. if (ulMagicIndex != 0xffffffff)
  2071. {
  2072. //
  2073. // found exact match
  2074. //
  2075. if (ulMagicIndex >= 10)
  2076. {
  2077. //
  2078. // the returned index must be adjusted for surface palette
  2079. //
  2080. ulMagicIndex += 236;
  2081. }
  2082. if (ulMagicIndex == Index)
  2083. {
  2084. if (bChildDriver)
  2085. {
  2086. // If this is child of meta driver, we still need to call
  2087. // driver to update palette. (in the ppalDefault, doesn't
  2088. // mean in the child surface palette).
  2089. //
  2090. // set magic color
  2091. //
  2092. bPaletteChange = bSetMagicColor(palSurf,Index,PalEntry);
  2093. bRet = bPaletteChange;
  2094. }
  2095. else
  2096. {
  2097. //
  2098. // already set
  2099. //
  2100. bRet = TRUE;
  2101. }
  2102. }
  2103. else
  2104. {
  2105. //
  2106. // make sure RGB is not a non-magic VGA color,
  2107. // if there is a match, it can only be a magic
  2108. // color
  2109. //
  2110. if (
  2111. (ulMagicIndex == 8) ||
  2112. (ulMagicIndex == 9) ||
  2113. (ulMagicIndex == 246) ||
  2114. (ulMagicIndex == 247)
  2115. )
  2116. {
  2117. //
  2118. // set magic color
  2119. //
  2120. bPaletteChange = bSetMagicColor(palSurf,Index,PalEntry);
  2121. bRet = bPaletteChange;
  2122. }
  2123. else
  2124. {
  2125. //
  2126. // bad rgb, restore Index with
  2127. // default color
  2128. //
  2129. if (Index == 8)
  2130. {
  2131. PalEntry.ul = 0x00C0DCC0;
  2132. }
  2133. else if (Index == 9)
  2134. {
  2135. PalEntry.ul = 0x00F0CAA6;
  2136. }
  2137. else if (Index == 246)
  2138. {
  2139. PalEntry.ul = 0x00F0FBFF;
  2140. }
  2141. else
  2142. {
  2143. PalEntry.ul = 0x00A4A0A0;
  2144. }
  2145. bPaletteChange = bSetMagicColor(palSurf,Index,PalEntry);
  2146. bRet = FALSE;
  2147. }
  2148. }
  2149. }
  2150. else
  2151. {
  2152. //
  2153. // set magic color
  2154. //
  2155. bPaletteChange = bSetMagicColor(palSurf,Index,PalEntry);
  2156. bRet = bPaletteChange;
  2157. }
  2158. }
  2159. if (bPaletteChange)
  2160. {
  2161. SEMOBJ so(po.hsemPointer());
  2162. if (!po.bDisabled())
  2163. {
  2164. po.pfnSetPalette()(
  2165. po.dhpdevParent(),
  2166. (PALOBJ *) &palSurf,
  2167. 0,
  2168. 0,
  2169. palSurf.cEntries());
  2170. }
  2171. }
  2172. }
  2173. }
  2174. }
  2175. }
  2176. return(bRet);
  2177. }