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.

3376 lines
97 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: palobj.cxx
  3. *
  4. * Palette user object functions
  5. *
  6. * Created: 07-Nov-1990 21:30:19
  7. * Author: Patrick Haluptzok patrickh
  8. *
  9. * Copyright (c) 1990-1999 Microsoft Corporation
  10. \**************************************************************************/
  11. #include "precomp.hxx"
  12. extern "C" BOOL bInitPALOBJ();
  13. #pragma alloc_text(INIT, bInitPALOBJ)
  14. #define MAX_PAL_ERROR (3 * (256*256))
  15. // ulXlatePalUnique is used for the uniquess of the xlates and palettes.
  16. ULONG ulXlatePalUnique = 3;
  17. // gpRGBXlate is a global RGBXlate for the rainbow palette
  18. PBYTE gpRGBXlate = NULL;
  19. UINT *pArrayOfSquares;
  20. UINT aArrayOfSquares[511];
  21. typedef BYTE FAR *PIMAP;
  22. typedef struct {BYTE r,g,b,x;} RGBX;
  23. BOOL MakeITable(PIMAP lpITable, RGBX FAR *prgb, int nColors);
  24. /******************************Public*Data*********************************\
  25. * Default Monochrome Palette
  26. *
  27. * History:
  28. * 16-Nov-1992 -by- Patrick Haluptzok patrickh
  29. * Wrote it.
  30. \**************************************************************************/
  31. ULONG gaulMono[2] =
  32. {
  33. 0,
  34. 0xFFFFFF
  35. };
  36. /******************************Public*Data*********************************\
  37. * Default Logical Palette
  38. *
  39. * Default Palette Data Structure, Taken straight from Win 3.1
  40. * This is the default palette, the stock palette.
  41. * This contains the 20 default colors.
  42. * This is the default logical palette put in every DC when it is created.
  43. *
  44. * History:
  45. * 16-Nov-1992 -by- Patrick Haluptzok patrickh
  46. * Wrote it.
  47. \**************************************************************************/
  48. PAL_LOGPALETTE logDefaultPal =
  49. {
  50. 0x300, // version number
  51. 20, // number of entries
  52. {
  53. { 0, 0, 0, 0 }, // 0
  54. { 0x80,0, 0, 0 }, // 1
  55. { 0, 0x80,0, 0 }, // 2
  56. { 0x80,0x80,0, 0 }, // 3
  57. { 0, 0, 0x80,0 }, // 4
  58. { 0x80,0, 0x80,0 }, // 5
  59. { 0, 0x80,0x80,0 }, // 6
  60. { 0xC0,0xC0,0xC0,0 }, // 7
  61. { 192, 220, 192, 0 }, // 8
  62. { 166, 202, 240, 0 }, // 9
  63. { 255, 251, 240, 0 }, // 10
  64. { 160, 160, 164, 0 }, // 11
  65. { 0x80,0x80,0x80,0 }, // 12
  66. { 0xFF,0, 0, 0 }, // 13
  67. { 0, 0xFF,0, 0 }, // 14
  68. { 0xFF,0xFF,0, 0 }, // 15
  69. { 0, 0, 0xFF,0 }, // 16
  70. { 0xFF,0, 0xFF,0 }, // 17
  71. { 0, 0xFF,0xFF,0 }, // 18
  72. { 0xFF,0xFF,0xFF,0 } // 19
  73. }
  74. };
  75. /******************************Public*Data**********************************\
  76. *
  77. * This is the same as color table as logDefaultPal except
  78. * entries for magic colors. These are 0x0 to prevent a match.
  79. * We now only match magic colors exactly, otherwise nearest-match
  80. * to this palette
  81. *
  82. \**************************************************************************/
  83. PAL_ULONG aPalDefaultVGA[20] =
  84. {
  85. { 0, 0, 0, 0 }, // 0
  86. { 0x80,0, 0, 0 }, // 1
  87. { 0, 0x80,0, 0 }, // 2
  88. { 0x80,0x80,0, 0 }, // 3
  89. { 0, 0, 0x80,0 }, // 4
  90. { 0x80,0, 0x80,0 }, // 5
  91. { 0, 0x80,0x80,0 }, // 6
  92. { 0xC0,0xC0,0xC0,0 }, // 7
  93. { 000, 000, 000, 0 }, // 8
  94. { 000, 000, 000, 0 }, // 9
  95. { 000, 000, 000, 0 }, // 10
  96. { 000, 000, 000, 0 }, // 11
  97. { 0x80,0x80,0x80,0 }, // 12
  98. { 0xFF,0, 0, 0 }, // 13
  99. { 0, 0xFF,0, 0 }, // 14
  100. { 0xFF,0xFF,0, 0 }, // 15
  101. { 0, 0, 0xFF,0 }, // 16
  102. { 0xFF,0, 0xFF,0 }, // 17
  103. { 0, 0xFF,0xFF,0 }, // 18
  104. { 0xFF,0xFF,0xFF,0 } // 19
  105. };
  106. /******************************Public*Data*********************************\
  107. * This is the default 16 color palette which matches the VGA palette
  108. * exactly.
  109. *
  110. * History:
  111. * 05-Nov-1991 -by- Patrick Haluptzok patrickh
  112. * Wrote it.
  113. \**************************************************************************/
  114. PAL_ULONG aPalVGA[16] =
  115. {
  116. { 0, 0, 0, 0 }, // 0
  117. { 0x80,0, 0, 0 }, // 1
  118. { 0, 0x80,0, 0 }, // 2
  119. { 0x80,0x80,0, 0 }, // 3
  120. { 0, 0, 0x80,0 }, // 4
  121. { 0x80,0, 0x80,0 }, // 5
  122. { 0, 0x80,0x80,0 }, // 6
  123. { 0x80,0x80,0x80,0 }, // 7
  124. { 0xC0,0xC0,0xC0,0 }, // 8
  125. { 0xFF,0, 0, 0 }, // 9
  126. { 0, 0xFF,0, 0 }, // 10
  127. { 0xFF,0xFF,0, 0 }, // 11
  128. { 0, 0, 0xFF,0 }, // 12
  129. { 0xFF,0, 0xFF,0 }, // 13
  130. { 0, 0xFF,0xFF,0 }, // 14
  131. { 0xFF,0xFF,0xFF,0 } // 15
  132. };
  133. /******************************Public*Routine******************************\
  134. *
  135. * win95 halftone palette
  136. *
  137. * History:
  138. *
  139. * 11/27/1996 Mark Enstrom [marke]
  140. *
  141. * 03-Feb-1999 Wed 01:47:31 updated -by- Daniel Chou (danielc)
  142. * Even though this is the one copy from win95, it is wrong for halftone
  143. * to be use correctly, it missing high luminance green color, I added
  144. * this back, and the low r/b/m/c luminance color (20% of that color) are
  145. * patch into gray color. All window system halftone does not use any
  146. * gray color in 256 color mode any more.
  147. *
  148. * Index 10: 0x04:0x04:0x04 --> 0x00:0x00:0x33
  149. * Index 11: 0x08:0x08:0x08 --> 0x33:0x00:0x00
  150. * Index 12: 0x0c:0x0c:0x0c --> 0x33:0x00:0x33
  151. * Index 13: 0x11:0x11:0x11 --> 0x00:0x33:0x33
  152. * Index 39: 0x33:0x00:0x00 --> 0x33:0xFF:0x00
  153. * Index 60: 0x00:0x00:0x33 --> 0x00:0xFF:0x33
  154. * Index 61: 0x33:0x00:0x33 --> 0x33:0x00:0xFF
  155. * Index 66: 0x00:0x33:0x33 --> 0x00:0x33:0xFF
  156. *
  157. \**************************************************************************/
  158. PAL_ULONG aPalHalftone[256] =
  159. {
  160. {0x00,0x00,0x00,0x00},{0x80,0x00,0x00,0x00},{0x00,0x80,0x00,0x00},{0x80,0x80,0x00,0x00},
  161. {0x00,0x00,0x80,0x00},{0x80,0x00,0x80,0x00},{0x00,0x80,0x80,0x00},{0xc0,0xc0,0xc0,0x00},
  162. {0xc0,0xdc,0xc0,0x00},{0xa6,0xca,0xf0,0x00},{0x00,0x00,0x33,0x04},{0x33,0x00,0x00,0x04},
  163. {0x33,0x00,0x33,0x04},{0x00,0x33,0x33,0x04},{0x16,0x16,0x16,0x04},{0x1c,0x1c,0x1c,0x04},
  164. //1
  165. {0x22,0x22,0x22,0x04},{0x29,0x29,0x29,0x04},{0x55,0x55,0x55,0x04},{0x4d,0x4d,0x4d,0x04},
  166. {0x42,0x42,0x42,0x04},{0x39,0x39,0x39,0x04},{0xFF,0x7C,0x80,0x04},{0xFF,0x50,0x50,0x04},
  167. {0xD6,0x00,0x93,0x04},{0xCC,0xEC,0xFF,0x04},{0xEF,0xD6,0xC6,0x04},{0xE7,0xE7,0xD6,0x04},
  168. {0xAD,0xA9,0x90,0x04},{0x33,0xFF,0x00,0x04},{0x66,0x00,0x00,0x04},{0x99,0x00,0x00,0x04},
  169. //2
  170. {0xcc,0x00,0x00,0x04},{0x00,0x33,0x00,0x04},{0x33,0x33,0x00,0x04},{0x66,0x33,0x00,0x04},
  171. {0x99,0x33,0x00,0x04},{0xcc,0x33,0x00,0x04},{0xff,0x33,0x00,0x04},{0x00,0x66,0x00,0x04},
  172. {0x33,0x66,0x00,0x04},{0x66,0x66,0x00,0x04},{0x99,0x66,0x00,0x04},{0xcc,0x66,0x00,0x04},
  173. {0xff,0x66,0x00,0x04},{0x00,0x99,0x00,0x04},{0x33,0x99,0x00,0x04},{0x66,0x99,0x00,0x04},
  174. //3
  175. {0x99,0x99,0x00,0x04},{0xcc,0x99,0x00,0x04},{0xff,0x99,0x00,0x04},{0x00,0xcc,0x00,0x04},
  176. {0x33,0xcc,0x00,0x04},{0x66,0xcc,0x00,0x04},{0x99,0xcc,0x00,0x04},{0xcc,0xcc,0x00,0x04},
  177. {0xff,0xcc,0x00,0x04},{0x66,0xff,0x00,0x04},{0x99,0xff,0x00,0x04},{0xcc,0xff,0x00,0x04},
  178. {0x00,0xFF,0x33,0x04},{0x33,0x00,0xFF,0x04},{0x66,0x00,0x33,0x04},{0x99,0x00,0x33,0x04},
  179. //4
  180. {0xcc,0x00,0x33,0x04},{0xff,0x00,0x33,0x04},{0x00,0x33,0xFF,0x04},{0x33,0x33,0x33,0x04},
  181. {0x66,0x33,0x33,0x04},{0x99,0x33,0x33,0x04},{0xcc,0x33,0x33,0x04},{0xff,0x33,0x33,0x04},
  182. {0x00,0x66,0x33,0x04},{0x33,0x66,0x33,0x04},{0x66,0x66,0x33,0x04},{0x99,0x66,0x33,0x04},
  183. {0xcc,0x66,0x33,0x04},{0xff,0x66,0x33,0x04},{0x00,0x99,0x33,0x04},{0x33,0x99,0x33,0x04},
  184. //5
  185. {0x66,0x99,0x33,0x04},{0x99,0x99,0x33,0x04},{0xcc,0x99,0x33,0x04},{0xff,0x99,0x33,0x04},
  186. {0x00,0xcc,0x33,0x04},{0x33,0xcc,0x33,0x04},{0x66,0xcc,0x33,0x04},{0x99,0xcc,0x33,0x04},
  187. {0xcc,0xcc,0x33,0x04},{0xff,0xcc,0x33,0x04},{0x33,0xff,0x33,0x04},{0x66,0xff,0x33,0x04},
  188. {0x99,0xff,0x33,0x04},{0xcc,0xff,0x33,0x04},{0xff,0xff,0x33,0x04},{0x00,0x00,0x66,0x04},
  189. //6
  190. {0x33,0x00,0x66,0x04},{0x66,0x00,0x66,0x04},{0x99,0x00,0x66,0x04},{0xcc,0x00,0x66,0x04},
  191. {0xff,0x00,0x66,0x04},{0x00,0x33,0x66,0x04},{0x33,0x33,0x66,0x04},{0x66,0x33,0x66,0x04},
  192. {0x99,0x33,0x66,0x04},{0xcc,0x33,0x66,0x04},{0xff,0x33,0x66,0x04},{0x00,0x66,0x66,0x04},
  193. {0x33,0x66,0x66,0x04},{0x66,0x66,0x66,0x04},{0x99,0x66,0x66,0x04},{0xcc,0x66,0x66,0x04},
  194. //7
  195. {0x00,0x99,0x66,0x04},{0x33,0x99,0x66,0x04},{0x66,0x99,0x66,0x04},{0x99,0x99,0x66,0x04},
  196. {0xcc,0x99,0x66,0x04},{0xff,0x99,0x66,0x04},{0x00,0xcc,0x66,0x04},{0x33,0xcc,0x66,0x04},
  197. {0x99,0xcc,0x66,0x04},{0xcc,0xcc,0x66,0x04},{0xff,0xcc,0x66,0x04},{0x00,0xff,0x66,0x04},
  198. {0x33,0xff,0x66,0x04},{0x99,0xff,0x66,0x04},{0xcc,0xff,0x66,0x04},{0xff,0x00,0xcc,0x04},
  199. //8
  200. {0xcc,0x00,0xff,0x04},{0x00,0x99,0x99,0x04},{0x99,0x33,0x99,0x04},{0x99,0x00,0x99,0x04},
  201. {0xcc,0x00,0x99,0x04},{0x00,0x00,0x99,0x04},{0x33,0x33,0x99,0x04},{0x66,0x00,0x99,0x04},
  202. {0xcc,0x33,0x99,0x04},{0xff,0x00,0x99,0x04},{0x00,0x66,0x99,0x04},{0x33,0x66,0x99,0x04},
  203. {0x66,0x33,0x99,0x04},{0x99,0x66,0x99,0x04},{0xcc,0x66,0x99,0x04},{0xff,0x33,0x99,0x04},
  204. //9
  205. {0x33,0x99,0x99,0x04},{0x66,0x99,0x99,0x04},{0x99,0x99,0x99,0x04},{0xcc,0x99,0x99,0x04},
  206. {0xff,0x99,0x99,0x04},{0x00,0xcc,0x99,0x04},{0x33,0xcc,0x99,0x04},{0x66,0xcc,0x66,0x04},
  207. {0x99,0xcc,0x99,0x04},{0xcc,0xcc,0x99,0x04},{0xff,0xcc,0x99,0x04},{0x00,0xff,0x99,0x04},
  208. {0x33,0xff,0x99,0x04},{0x66,0xcc,0x99,0x04},{0x99,0xff,0x99,0x04},{0xcc,0xff,0x99,0x04},
  209. //a
  210. {0xff,0xff,0x99,0x04},{0x00,0x00,0xcc,0x04},{0x33,0x00,0x99,0x04},{0x66,0x00,0xcc,0x04},
  211. {0x99,0x00,0xcc,0x04},{0xcc,0x00,0xcc,0x04},{0x00,0x33,0x99,0x04},{0x33,0x33,0xcc,0x04},
  212. {0x66,0x33,0xcc,0x04},{0x99,0x33,0xcc,0x04},{0xcc,0x33,0xcc,0x04},{0xff,0x33,0xcc,0x04},
  213. {0x00,0x66,0xcc,0x04},{0x33,0x66,0xcc,0x04},{0x66,0x66,0x99,0x04},{0x99,0x66,0xcc,0x04},
  214. //b
  215. {0xcc,0x66,0xcc,0x04},{0xff,0x66,0x99,0x04},{0x00,0x99,0xcc,0x04},{0x33,0x99,0xcc,0x04},
  216. {0x66,0x99,0xcc,0x04},{0x99,0x99,0xcc,0x04},{0xcc,0x99,0xcc,0x04},{0xff,0x99,0xcc,0x04},
  217. {0x00,0xcc,0xcc,0x04},{0x33,0xcc,0xcc,0x04},{0x66,0xcc,0xcc,0x04},{0x99,0xcc,0xcc,0x04},
  218. {0xcc,0xcc,0xcc,0x04},{0xff,0xcc,0xcc,0x04},{0x00,0xff,0xcc,0x04},{0x33,0xff,0xcc,0x04},
  219. //c
  220. {0x66,0xff,0x99,0x04},{0x99,0xff,0xcc,0x04},{0xcc,0xff,0xcc,0x04},{0xff,0xff,0xcc,0x04},
  221. {0x33,0x00,0xcc,0x04},{0x66,0x00,0xff,0x04},{0x99,0x00,0xff,0x04},{0x00,0x33,0xcc,0x04},
  222. {0x33,0x33,0xff,0x04},{0x66,0x33,0xff,0x04},{0x99,0x33,0xff,0x04},{0xcc,0x33,0xff,0x04},
  223. {0xff,0x33,0xff,0x04},{0x00,0x66,0xff,0x04},{0x33,0x66,0xff,0x04},{0x66,0x66,0xcc,0x04},
  224. //d
  225. {0x99,0x66,0xff,0x04},{0xcc,0x66,0xff,0x04},{0xff,0x66,0xcc,0x04},{0x00,0x99,0xff,0x04},
  226. {0x33,0x99,0xff,0x04},{0x66,0x99,0xff,0x04},{0x99,0x99,0xff,0x04},{0xcc,0x99,0xff,0x04},
  227. {0xff,0x99,0xff,0x04},{0x00,0xcc,0xff,0x04},{0x33,0xcc,0xff,0x04},{0x66,0xcc,0xff,0x04},
  228. {0x99,0xcc,0xff,0x04},{0xcc,0xcc,0xff,0x04},{0xff,0xcc,0xff,0x04},{0x33,0xff,0xff,0x04},
  229. //e
  230. {0x66,0xff,0xcc,0x04},{0x99,0xff,0xff,0x04},{0xcc,0xff,0xff,0x04},{0xff,0x66,0x66,0x04},
  231. {0x66,0xff,0x66,0x04},{0xff,0xff,0x66,0x04},{0x66,0x66,0xff,0x04},{0xff,0x66,0xff,0x04},
  232. {0x66,0xff,0xff,0x04},{0xA5,0x00,0x21,0x04},{0x5f,0x5f,0x5f,0x04},{0x77,0x77,0x77,0x04},
  233. {0x86,0x86,0x86,0x04},{0x96,0x96,0x96,0x04},{0xcb,0xcb,0xcb,0x04},{0xb2,0xb2,0xb2,0x04},
  234. //f
  235. {0xd7,0xd7,0xd7,0x04},{0xdd,0xdd,0xdd,0x04},{0xe3,0xe3,0xe3,0x04},{0xea,0xea,0xea,0x04},
  236. {0xf1,0xf1,0xf1,0x04},{0xf8,0xf8,0xf8,0x04},{0xff,0xfb,0xf0,0x00},{0xa0,0xa0,0xa4,0x00},
  237. {0x80,0x80,0x80,0x00},{0xff,0x00,0x00,0x00},{0x00,0xff,0x00,0x00},{0xff,0xff,0x00,0x00},
  238. {0x00,0x00,0xff,0x00},{0xff,0x00,0xff,0x00},{0x00,0xff,0xff,0x00},{0xff,0xff,0xff,0x00}
  239. };
  240. // ppalDefault is the pointer to the default palette info
  241. // We lock the default palette down at creation and never unlock
  242. // it so that multiple apps can access the default palette simultaneously.
  243. PPALETTE ppalDefault = (PPALETTE) NULL;
  244. PPALETTE gppalRGB = (PPALETTE) NULL;
  245. // ppalDefaultSurface8bpp is the pointer to the default 8bpp surface palette.
  246. // This is used for dynamic mode changes when converting a Device Dependent
  247. // Bitmap, which has no color table, to a Device Indepdent Bitmap, which
  248. // has a color table -- this is what we use for the color table.
  249. // We lock the default palette down at creation and never unlock
  250. // it so that multiple surface can access the default palette simultaneously.
  251. PPALETTE ppalDefaultSurface8bpp = (PPALETTE) NULL;
  252. // This is the global palette for the monochrome bitmaps.
  253. HPALETTE hpalMono = (HPALETTE) 0;
  254. PPALETTE ppalMono = (PPALETTE) NULL;
  255. /******************************Public*Routine******************************\
  256. * RGB_ERROR
  257. *
  258. * Returns a measure of error between two RGB entries.
  259. *
  260. * History:
  261. * 14-Jan-1991 -by- Patrick Haluptzok patrickh
  262. * Wrote it.
  263. \**************************************************************************/
  264. inline ULONG RGB_ERROR(PALETTEENTRY palDst, PALETTEENTRY palSrc)
  265. {
  266. INT lTemp, lTemp1;
  267. lTemp = ((INT) (UINT) (palDst.peRed)) -
  268. ((INT) (UINT) (palSrc.peRed));
  269. lTemp1 = lTemp * lTemp;
  270. lTemp = ((INT) (UINT) (palDst.peGreen)) -
  271. ((INT) (UINT) (palSrc.peGreen));
  272. lTemp1 += lTemp * lTemp;
  273. lTemp = ((INT) (UINT) (palDst.peBlue)) -
  274. ((INT) (UINT) (palSrc.peBlue));
  275. lTemp1 += lTemp * lTemp;
  276. return((ULONG) lTemp1);
  277. }
  278. /******************************Public*Routine******************************\
  279. * BOOL XEPALOBJ::bSwap(ppalSrc)
  280. *
  281. * This is for swapping palettes, necesary for ResizePalette.
  282. *
  283. * History:
  284. * Sun 21-Jun-1992 -by- Patrick Haluptzok [patrickh]
  285. * Make it a Safe swap under MLOCK.
  286. *
  287. * Fri 18-Jan-1991 -by- Patrick Haluptzok [patrickh]
  288. * Wrote it.
  289. \**************************************************************************/
  290. BOOL
  291. XEPALOBJ::bSwap(
  292. PPALETTE *pppalSrc,
  293. ULONG cShareCountDst,
  294. ULONG cShareCountSrc
  295. )
  296. {
  297. PPALETTE ppalSrc = *pppalSrc;
  298. BOOL bRet;
  299. bRet = HmgSwapLockedHandleContents((HOBJ)ppal->hGet(),
  300. cShareCountDst,
  301. (HOBJ)ppalSrc->hGet(),
  302. cShareCountSrc,
  303. PAL_TYPE);
  304. //
  305. // swap user pointers to palette objects
  306. //
  307. if (bRet)
  308. {
  309. *pppalSrc = ppal;
  310. ppal = ppalSrc;
  311. }
  312. return(bRet);
  313. }
  314. /******************************Public*Routine******************************\
  315. * XEPALOBJ::ulBitfieldToRGB
  316. *
  317. * Converts an index into an RGB for Bitfield palettes.
  318. *
  319. * History:
  320. * Tue 31-Mar-1992 -by- Patrick Haluptzok [patrickh]
  321. * Does better mapping.
  322. *
  323. * 08-Nov-1991 -by- Patrick Haluptzok patrickh
  324. * Wrote it.
  325. \**************************************************************************/
  326. ULONG XEPALOBJ::ulBitfieldToRGB(ULONG ulIndex)
  327. {
  328. ASSERTGDI(bIsBitfields(), "Error ulBitfieldToRGB not bitfields");
  329. ULONG ulRed = (ulIndex & flRed()) >> cRedRight();
  330. if (cRedMiddle() < 8)
  331. {
  332. ulRed = ulRed << (8 - cRedMiddle());
  333. ulRed = ulRed | (ulRed >> cRedMiddle());
  334. }
  335. ULONG ulGre = (ulIndex & flGre()) >> cGreRight();
  336. if (cGreMiddle() < 8)
  337. {
  338. ulGre = ulGre << (8 - cGreMiddle());
  339. ulGre = ulGre | (ulGre >> cGreMiddle());
  340. }
  341. ulGre = ulGre << 8;
  342. ULONG ulBlu = (ulIndex & flBlu()) >> cBluRight();
  343. if (cBluMiddle() < 8)
  344. {
  345. ulBlu = ulBlu << (8 - cBluMiddle());
  346. ulBlu = ulBlu | (ulBlu >> cBluMiddle());
  347. }
  348. ulBlu = ulBlu << 16;
  349. return(ulRed | ulBlu | ulGre);
  350. }
  351. /******************************Public*Routine******************************\
  352. * XEPALOBJ::ulIndexToRGB
  353. *
  354. * Converts an index to an RGB for a palette.
  355. *
  356. * History:
  357. * 05-Dec-1991 -by- Patrick Haluptzok patrickh
  358. * Wrote it.
  359. \**************************************************************************/
  360. ULONG XEPALOBJ::ulIndexToRGB(ULONG ulIndex)
  361. {
  362. if (bIsIndexed())
  363. {
  364. if (cEntries() > ulIndex)
  365. ulIndex = (ulEntryGet(ulIndex) & 0xFFFFFF);
  366. else
  367. ulIndex = 0;
  368. }
  369. else if (bIsBitfields())
  370. {
  371. ulIndex = ulBitfieldToRGB(ulIndex);
  372. }
  373. else if (bIsBGR())
  374. {
  375. BGR_ULONG palOld;
  376. PAL_ULONG palNew;
  377. palOld.ul = ulIndex;
  378. palNew.pal.peRed = palOld.rgb.rgbRed;
  379. palNew.pal.peGreen = palOld.rgb.rgbGreen;
  380. palNew.pal.peBlue = palOld.rgb.rgbBlue;
  381. palNew.pal.peFlags = 0;
  382. ulIndex = palNew.ul;
  383. }
  384. else
  385. {
  386. // 0 out the flags.
  387. ASSERTGDI(bIsRGB(), "ERROR another type not accounted for\n");
  388. ulIndex &= 0xFFFFFF;
  389. }
  390. return(ulIndex);
  391. }
  392. /******************************Public*Routine******************************\
  393. * ParseBits
  394. *
  395. * This routine computes how much the left and right shifts are for
  396. * PAL_BITFIELDS 16 and 32 bit masks.
  397. *
  398. * History:
  399. * 09-Nov-1991 -by- Patrick Haluptzok patrickh
  400. * Wrote it.
  401. \**************************************************************************/
  402. VOID ParseBits(FLONG flag, ULONG *pcRight, ULONG *pcLeft, ULONG *pcMiddle, ULONG cForColor)
  403. {
  404. ULONG ulRight = 0;
  405. ULONG ulMiddle;
  406. ASSERTGDI(flag != 0, "ERROR flag");
  407. while((flag & 1) == 0)
  408. {
  409. flag >>= 1;
  410. ulRight++;
  411. }
  412. ulMiddle = ulRight;
  413. do
  414. {
  415. flag >>= 1;
  416. ulMiddle++;
  417. } while(flag & 1);
  418. *pcMiddle = ulMiddle = ulMiddle - ulRight;
  419. *pcRight = (ulMiddle > 8) ? (ulRight + ulMiddle - 8) : (ulRight);
  420. *pcLeft = (ulMiddle > 8) ? (cForColor) : (cForColor + (8 - ulMiddle));
  421. }
  422. /******************************Public*Routine******************************\
  423. * PALMEMOBJ::bCreatePalette
  424. *
  425. * Constructor for creating palettes.
  426. *
  427. * Returns: True for success, False for error.
  428. *
  429. * History:
  430. * 18-Feb-1992 -by- Patrick Haluptzok patrickh
  431. * Wrote it.
  432. \**************************************************************************/
  433. BOOL
  434. PALMEMOBJ::bCreatePalette(
  435. ULONG iMode, // The mode the palette is.
  436. ULONG cColors, // Number of RGB's if indexed palette.
  437. ULONG *pulColors, // Pointer to RGB's if indexed.
  438. FLONG flRedd, // Mask for Red if bitfields
  439. FLONG flGreen, // Mask for Green if bitfields
  440. FLONG flBlue, // Mask for Blue if bitfields
  441. ULONG iType) // The type it will be, fixed, free, managed, DC.
  442. {
  443. ASSERTGDI(bKeep == FALSE, "ERROR bCreatePalette bKeep is not False");
  444. ASSERTGDI(ppal == (PPALETTE) NULL, "ERROR bCreatePalette ppal is NULL");
  445. PAL_ULONG palul;
  446. BOOL bDataStatus = TRUE;
  447. // This data may be coming accross the DDI from a newer driver or from a
  448. // journal file or from a app, so we must validate everything, make sure
  449. // only valid iType flags are set for the iMode.
  450. // Validate the iMode, calculate the size needed into palul.
  451. palul.ul = sizeof(PALETTE);
  452. switch(iMode)
  453. {
  454. case PAL_BITFIELDS:
  455. // Bitfields palette is always fixed, we ASSERT values that should
  456. // be correct to detect bad code in testing, but still assign correct
  457. // values so that corrupt journal files don't create bad palettes.
  458. ASSERTGDI(iType & PAL_FIXED, "ERROR bCreatePalette PAL_BITFIELDS");
  459. ASSERTGDI(cColors == 0, "ERROR GDI EngCreatePalette PAL_BITFIELDS");
  460. iType = iType & (PAL_FIXED | PAL_HT | PAL_DC);
  461. cColors = 0;
  462. // We need to check these so we don't fault ourselves.
  463. if ((flRedd == 0) || (flBlue == 0) || (flGreen == 0))
  464. {
  465. WARNING1("ERROR bCreatePalette 0 flags for PAL_BITFIELDS\n");
  466. return(FALSE);
  467. }
  468. palul.ul += sizeof(P_BITFIELDS);
  469. break;
  470. case PAL_BGR:
  471. case PAL_RGB:
  472. case PAL_CMYK:
  473. // RGB and CMYK palette is always fixed.
  474. ASSERTGDI(iType & PAL_FIXED, "bCreatePalette PAL_RGB/PAL_CMYK: iType not PAL_FIXED");
  475. ASSERTGDI((iType & ~(PAL_FIXED | PAL_DC | PAL_HT)) == 0, "bCreatePal PAL_RGB/PAL_CMYK: extra flags in iType ");
  476. ASSERTGDI(cColors == 0, "bCreatePalette PAL_RGB/PAL_CMYK: cColors not 0");
  477. iType = (iType & (PAL_DC | PAL_HT)) | PAL_FIXED;
  478. cColors = 0;
  479. if (iMode != PAL_CMYK)
  480. {
  481. if (iMode == PAL_RGB)
  482. {
  483. flRedd = 0x0000FF;
  484. flGreen = 0x00FF00;
  485. flBlue = 0xFF0000;
  486. }
  487. else if (iMode == PAL_BGR)
  488. {
  489. flRedd = 0xFF0000;
  490. flGreen = 0x00FF00;
  491. flBlue = 0x0000FF;
  492. }
  493. palul.ul += sizeof(P_BITFIELDS);
  494. }
  495. break;
  496. case PAL_INDEXED:
  497. palul.ul += (sizeof(PAL_ULONG) * cColors);
  498. // ASSERT for valid flags to detect bad code, mask off invalid flags so in
  499. // retail we work fine with journal files, bad drivers.
  500. ASSERTGDI((iType & ~(PAL_MONOCHROME | PAL_DC | PAL_FREE | PAL_FIXED | PAL_MANAGED | PAL_HT)) == 0,
  501. "ERROR bCreatePal PAL_INDEXED iType");
  502. iType = iType & (PAL_MONOCHROME | PAL_DC | PAL_FREE | PAL_FIXED | PAL_MANAGED | PAL_HT);
  503. if (cColors == 0)
  504. {
  505. RIP("ERROR PAL_INDEXED bCreatePalette cColors 0\n");
  506. return(FALSE);
  507. }
  508. break;
  509. default:
  510. RIP("bCreatePalette theses modes are not supported at this time\n");
  511. return(FALSE);
  512. }
  513. // Allocate the palette.
  514. PPALETTE ppalTemp;
  515. ppal = ppalTemp = (PPALETTE) ALLOCOBJ(palul.ul, PAL_TYPE, FALSE);
  516. if (ppalTemp == (PPALETTE)NULL)
  517. {
  518. WARNING("bCreatePalette failed memory allocation\n");
  519. return(FALSE);
  520. }
  521. //
  522. // Initialize the palette.
  523. //
  524. ppalTemp->flPal = iMode | iType;
  525. ppalTemp->cEntries = cColors;
  526. ppalTemp->ulTime = ulGetNewUniqueness(ulXlatePalUnique);
  527. ppalTemp->hdcHead = (HDC) 0;
  528. ppalTemp->hSelected.ppal = (PPALETTE) NULL;
  529. ppalTemp->cRefRegular = 0;
  530. ppalTemp->cRefhpal = 0;
  531. ppalTemp->ptransFore = NULL;
  532. ppalTemp->ptransCurrent = NULL;
  533. ppalTemp->ptransOld = NULL;
  534. ppalTemp->ulRGBTime = 0;
  535. ppalTemp->pRGBXlate = NULL;
  536. ppalTemp->ppalColor = ppalTemp;
  537. ppalTemp->apalColor = &ppalTemp->apalColorTable[0];
  538. switch(iMode)
  539. {
  540. case PAL_BITFIELDS:
  541. case PAL_RGB:
  542. case PAL_BGR:
  543. {
  544. // It won't kill us if any of these flags are 0, but it is
  545. // definitely an error on someones behalf.
  546. ASSERTGDI(flRedd != 0, "ERROR flGre");
  547. ASSERTGDI(flGreen != 0, "ERROR flGre");
  548. ASSERTGDI(flBlue != 0, "ERROR flBlu");
  549. // Save away the Masks
  550. flRed(flRedd);
  551. flGre(flGreen);
  552. flBlu(flBlue);
  553. if ((flRedd == 0x0000ff) &&
  554. (flGreen == 0x00ff00) &&
  555. (flBlue == 0xff0000))
  556. {
  557. ppalTemp->flPal |= PAL_RGB;
  558. }
  559. else if ((flRedd == 0xf800) &&
  560. (flGreen == 0x07e0) &&
  561. (flBlue == 0x001f))
  562. {
  563. ppalTemp->flPal |= PAL_RGB16_565;
  564. }
  565. else if ((flRedd == 0x7c00) &&
  566. (flGreen == 0x03e0) &&
  567. (flBlue == 0x001f))
  568. {
  569. ppalTemp->flPal |= PAL_RGB16_555;
  570. }
  571. // Let ParseBits calculate the left and right shifts we need.
  572. ParseBits(flRedd, &cRedRight(), &cRedLeft(), &cRedMiddle(), 0);
  573. ParseBits(flGreen, &cGreRight(), &cGreLeft(), &cGreMiddle(), 8);
  574. ParseBits(flBlue, &cBluRight(), &cBluLeft(), &cBluMiddle(), 16);
  575. }
  576. break;
  577. case PAL_INDEXED:
  578. {
  579. UINT uiTemp;
  580. PAL_ULONG *ppalstruc = apalColorGet();
  581. if (pulColors != (PULONG) NULL)
  582. {
  583. //
  584. // Copy the palette values in.
  585. // Make sure only valid entries are copied.
  586. //
  587. __try
  588. {
  589. for (uiTemp = 0; uiTemp < cColors; uiTemp++)
  590. {
  591. palul.ul = *(pulColors++);
  592. (ppalstruc++)->pal = palul.pal;
  593. }
  594. }
  595. __except(EXCEPTION_EXECUTE_HANDLER)
  596. {
  597. // SetLastError(GetExceptionCode());
  598. bDataStatus = FALSE;
  599. }
  600. }
  601. else
  602. {
  603. // Initialize the palette with 0's.
  604. for (uiTemp = 0; uiTemp < cColors; uiTemp++)
  605. (ppalstruc++)->ul = 0;
  606. }
  607. }
  608. } // switch
  609. // Now that all the other appropriate fields have been computed, compute
  610. // the call tables.
  611. XEPALOBJ pal(ppalTemp);
  612. pal.vComputeCallTables();
  613. // Add it to the handle table.
  614. if (bDataStatus)
  615. {
  616. if (HmgInsertObject(ppalTemp,
  617. HMGR_MAKE_PUBLIC | HMGR_ALLOC_ALT_LOCK,
  618. PAL_TYPE) != (HOBJ) 0)
  619. {
  620. return(TRUE);
  621. }
  622. WARNING("bCreatePalette failed HmgInsertObject\n");
  623. }
  624. else
  625. {
  626. WARNING("bCreatePalette failed Copying user data\n");
  627. }
  628. // Clean up the allocated memory.
  629. FREEOBJ(ppalTemp, PAL_TYPE);
  630. ppal = NULL;
  631. return(FALSE);
  632. }
  633. PALETTEENTRY apalMono[2] =
  634. {
  635. { 0, 0, 0, 0 },
  636. { 0xFF,0xFF,0xFF,0 }
  637. };
  638. PALETTEENTRY apal3BPP[8] =
  639. {
  640. {0, 0, 0, 0 },
  641. {0, 0, 0xFF, 0 },
  642. {0, 0xFF,0, 0 },
  643. {0, 0xFF,0xFF, 0 },
  644. {0xFF,0, 0, 0 },
  645. {0xFF,0, 0xFF, 0 },
  646. {0xFF,0xFF,0, 0 },
  647. {0xFF,0xFF,0xFF, 0 }
  648. };
  649. PALETTEENTRY apalVGA[16] =
  650. {
  651. {0, 0, 0, 0 },
  652. {0x80,0, 0, 0 },
  653. {0, 0x80,0, 0 },
  654. {0x80,0x80,0, 0 },
  655. {0, 0, 0x80, 0 },
  656. {0x80,0, 0x80, 0 },
  657. {0, 0x80,0x80, 0 },
  658. {0x80,0x80,0x80, 0 },
  659. {0xC0,0xC0,0xC0, 0 },
  660. {0xFF,0, 0, 0 },
  661. {0, 0xFF,0, 0 },
  662. {0xFF,0xFF,0, 0 },
  663. {0, 0, 0xFF, 0 },
  664. {0xFF,0, 0xFF, 0 },
  665. {0, 0xFF,0xFF, 0 },
  666. {0xFF,0xFF,0xFF, 0 }
  667. };
  668. #define COLOR_SWAP_BC 0x01
  669. #define COLOR_SWAP_AB 0x02
  670. #define COLOR_SWAP_AC 0x04
  671. /******************************Member*Function*****************************\
  672. * PALMEMOBJ::bCreateHTPalette
  673. *
  674. * Constructor for creating halftone palettes.
  675. *
  676. * Returns: True for success, False for error.
  677. *
  678. * History:
  679. * 04-Jun-1993 -by- Wendy Wu [wendywu]
  680. * Wrote it.
  681. \**************************************************************************/
  682. BOOL PALMEMOBJ::bCreateHTPalette(LONG iFormatHT, GDIINFO *pGdiInfo)
  683. {
  684. if ((iFormatHT == HT_FORMAT_32BPP) ||
  685. (iFormatHT == HT_FORMAT_24BPP) ||
  686. (iFormatHT == HT_FORMAT_16BPP)) {
  687. // 32BPP halftone use lower 3 bytes as RGB, same as 24bpp, but with extra
  688. // pad byte at end, the order can be any of PRIMARY_ORDER_xxx
  689. ULONG ulPrimaryOrder = pGdiInfo->ulPrimaryOrder;
  690. ULONG ulR;
  691. ULONG ulG;
  692. ULONG ulB;
  693. ULONG ulTmp;
  694. if (iFormatHT == HT_FORMAT_16BPP) {
  695. //
  696. // 16BPP_555 for now, we should also do 16bpp_565
  697. ulR = 0x00007c00;
  698. ulG = 0x000003e0;
  699. ulB = 0x0000001f;
  700. } else {
  701. ulR = 0x00FF0000;
  702. ulG = 0x0000FF00;
  703. ulB = 0x000000FF;
  704. }
  705. if (ulPrimaryOrder & COLOR_SWAP_BC) {
  706. ulTmp = ulG;
  707. ulG = ulB;
  708. ulB = ulTmp;
  709. }
  710. if (ulPrimaryOrder & COLOR_SWAP_AB) {
  711. ulTmp = ulR;
  712. ulR = ulG;
  713. ulG = ulTmp;
  714. } else if (ulPrimaryOrder & COLOR_SWAP_AC) {
  715. ulTmp = ulR;
  716. ulR = ulB;
  717. ulB = ulTmp;
  718. }
  719. if (!bCreatePalette(PAL_BITFIELDS, 0, (PULONG)NULL,
  720. ulR, ulG, ulB, PAL_FIXED|PAL_HT)) {
  721. return(FALSE);
  722. }
  723. #if 0
  724. } else if (iFormatHT == HT_FORMAT_24BPP) {
  725. // 24BPP halftone always does BGR
  726. if (!bCreatePalette(PAL_BGR, 0, (PULONG)NULL,
  727. 0x0,0x0,0x0,PAL_FIXED|PAL_HT))
  728. {
  729. return(FALSE);
  730. }
  731. } else if (iFormatHT == HT_FORMAT_16BPP) {
  732. // 16BPP halftone always does 555 for red, green, and blue.
  733. if (!bCreatePalette(PAL_BITFIELDS, 0, (PULONG)NULL,
  734. 0x7c00,0x3e0,0x1f,PAL_FIXED|PAL_HT))
  735. {
  736. return(FALSE);
  737. }
  738. #endif
  739. }
  740. else
  741. {
  742. ULONG cEntries;
  743. BOOL bAlloc = FALSE;
  744. PPALETTEENTRY ppalentry;
  745. PALETTEENTRY apalentry[8];
  746. switch(iFormatHT)
  747. {
  748. case HT_FORMAT_1BPP:
  749. cEntries = 2;
  750. ppalentry = &apalMono[0];
  751. if (pGdiInfo->flHTFlags & HT_FLAG_OUTPUT_CMY)
  752. {
  753. ppalentry = &apalentry[0];
  754. *((ULONG *)&apalentry[0]) = 0x0FFFFFF;
  755. *((ULONG *)&apalentry[1]) = 0;
  756. }
  757. break;
  758. case HT_FORMAT_4BPP_IRGB:
  759. cEntries = 16;
  760. ppalentry = &apalVGA[0];
  761. break;
  762. default:
  763. WARNING("unsupported halftone format, use default VGA format\n");
  764. case HT_FORMAT_4BPP:
  765. {
  766. cEntries = 8;
  767. ppalentry = &apalentry[0];
  768. RtlCopyMemory(apalentry, apal3BPP, sizeof(PALETTEENTRY) * 8);
  769. ULONG ulPrimaryOrder = pGdiInfo->ulPrimaryOrder;
  770. BYTE jTmp;
  771. int i;
  772. if (ulPrimaryOrder & COLOR_SWAP_BC)
  773. {
  774. for (i = 1; i < 7; i++)
  775. {
  776. // Swap Green and Blue entries.
  777. jTmp = apalentry[i].peGreen;
  778. apalentry[i].peGreen = apalentry[i].peBlue;
  779. apalentry[i].peBlue = jTmp;
  780. }
  781. }
  782. if (ulPrimaryOrder & COLOR_SWAP_AB)
  783. {
  784. for (i = 1; i < 7; i++)
  785. {
  786. // Swap Red and Green.
  787. jTmp = apalentry[i].peRed;
  788. apalentry[i].peRed = apalentry[i].peGreen;
  789. apalentry[i].peGreen = jTmp;
  790. }
  791. }
  792. else if (ulPrimaryOrder & COLOR_SWAP_AC)
  793. {
  794. for (i = 1; i < 7; i++)
  795. {
  796. // Swap Red and Blue entries.
  797. jTmp = apalentry[i].peRed;
  798. apalentry[i].peRed = apalentry[i].peBlue;
  799. apalentry[i].peBlue = jTmp;
  800. }
  801. }
  802. if (pGdiInfo->flHTFlags & HT_FLAG_OUTPUT_CMY)
  803. {
  804. // Substrative device.
  805. for (int i = 0; i < 8; i++)
  806. *((ULONG *)&apalentry[i]) ^= 0x0FFFFFF;
  807. }
  808. }
  809. break;
  810. case HT_FORMAT_8BPP:
  811. // Query the palette entries from Daniel's halftone library.
  812. // Query the number of entries on the first call. Get the
  813. // color entries on the second.
  814. PCOLORINFO pci = &pGdiInfo->ciDevice;
  815. cEntries = HT_Get8BPPMaskPalette((LPPALETTEENTRY)NULL,
  816. (BOOL)(pGdiInfo->flHTFlags &
  817. HT_FLAG_USE_8BPP_BITMASK),
  818. (BYTE)((pGdiInfo->flHTFlags &
  819. HT_FLAG_8BPP_CMY332_MASK)
  820. >> 24),
  821. (UDECI4)pci->RedGamma,
  822. (UDECI4)pci->GreenGamma,
  823. (UDECI4)pci->BlueGamma);
  824. ppalentry = (PPALETTEENTRY)
  825. PALLOCNOZ (sizeof(PALETTEENTRY) * cEntries, 'laPG');
  826. if (ppalentry == (PPALETTEENTRY)NULL)
  827. return(FALSE);
  828. if (pGdiInfo->flHTFlags & HT_FLAG_INVERT_8BPP_BITMASK_IDX) {
  829. HT_SET_BITMASKPAL2RGB(ppalentry);
  830. } else {
  831. ppalentry->peRed =
  832. ppalentry->peGreen =
  833. ppalentry->peBlue =
  834. ppalentry->peFlags = 0;
  835. }
  836. HT_Get8BPPMaskPalette(ppalentry,
  837. (BOOL)(pGdiInfo->flHTFlags &
  838. HT_FLAG_USE_8BPP_BITMASK),
  839. (BYTE)((pGdiInfo->flHTFlags &
  840. HT_FLAG_8BPP_CMY332_MASK) >> 24),
  841. (UDECI4)pci->RedGamma,
  842. (UDECI4)pci->GreenGamma,
  843. (UDECI4)pci->BlueGamma);
  844. bAlloc = TRUE;
  845. break;
  846. }
  847. if (!bCreatePalette(PAL_INDEXED, cEntries,
  848. (PULONG)ppalentry,0,0,0,PAL_FREE|PAL_HT))
  849. {
  850. if (bAlloc)
  851. VFREEMEM(ppalentry);
  852. return(FALSE);
  853. }
  854. if (bAlloc)
  855. {
  856. // 8bpp case. halftone palette is not the same as the device palette.
  857. VFREEMEM(ppalentry);
  858. }
  859. }
  860. return(TRUE);
  861. }
  862. /******************************Public*Routine******************************\
  863. * PALMEMOBJ destructor
  864. *
  865. * destructor for palette memory objects
  866. *
  867. * History:
  868. * 07-Nov-1990 -by- Patrick Haluptzok patrickh
  869. * Wrote it.
  870. \**************************************************************************/
  871. PALMEMOBJ::~PALMEMOBJ()
  872. {
  873. PVOID pvRemove;
  874. if (ppal != (PPALETTE) NULL)
  875. {
  876. if (bKeep)
  877. {
  878. DEC_SHARE_REF_CNT(ppal);
  879. }
  880. else
  881. {
  882. if (ppal != ppalColor())
  883. {
  884. //
  885. // Remove a reference to the palette who owns the color
  886. // table.
  887. //
  888. XEPALOBJ palColor(ppalColor());
  889. palColor.vUnrefPalette();
  890. }
  891. if (ppal->pRGBXlate != NULL)
  892. {
  893. if (ppal->pRGBXlate != gpRGBXlate)
  894. VFREEMEM(ppal->pRGBXlate);
  895. ppal->pRGBXlate = NULL;
  896. }
  897. pvRemove = HmgRemoveObject((HOBJ)ppal->hGet(), 0, 1, TRUE, PAL_TYPE);
  898. ASSERTGDI(pvRemove != NULL, "Remove failed. Havoc will result.");
  899. FREEOBJ(ppal,PAL_TYPE);
  900. }
  901. ppal = (PPALETTE) NULL; // prevent ~PALOBJ from doing anything
  902. }
  903. }
  904. /******************************Public*Routine******************************\
  905. * ulGetNearestFromPalentryNoExactMatchFirst
  906. *
  907. * Given a palette entry finds the index of the closest matching entry.
  908. *
  909. * History:
  910. * 02-Sep-1991 -by- Patrick Haluptzok patrickh
  911. * Wrote it.
  912. *
  913. * 16-Jan-1993 -by- Michael Abrash [mikeab]
  914. * Checked for exact match first.
  915. \**************************************************************************/
  916. ULONG XEPALOBJ::ulGetNearestFromPalentryNoExactMatchFirst(
  917. CONST PALETTEENTRY palentry)
  918. {
  919. if (!bIsIndexed())
  920. {
  921. return(ulGetMatchFromPalentry(palentry));
  922. }
  923. //
  924. // We should only be called when there wouldn't be an exact match.
  925. // We don't need to check BGR, RGB, bitfields, or explicit
  926. // index, because those always produce an exact match.
  927. // We assume the palette is non-explicitly indexed at this point.
  928. //
  929. ASSERTGDI(bIsIndexed(), "ERROR ulGetNearestFromPalentry not indexed");
  930. ASSERTGDI(cEntries() != 0, "ERROR ulGetNearestFromPalentry cEntries is 0");
  931. PALETTEENTRY *ppalTemp, *ppalMax, *ppalBase;
  932. PALETTEENTRY *ppalBest;
  933. if (ppal == ppalDefault)
  934. {
  935. ppalTemp = &aPalDefaultVGA[0].pal;
  936. }
  937. else
  938. {
  939. ppalTemp = &ppal->apalColor[0].pal;
  940. }
  941. //
  942. // last palette entry.
  943. //
  944. ppalBase = ppalTemp;
  945. ppalMax = ppalTemp + cEntries();
  946. #if defined(_X86_)
  947. ULONG ulRed = palentry.peRed;
  948. ULONG ulGre = palentry.peGreen;
  949. ULONG ulBlu = palentry.peBlue;
  950. _asm
  951. {
  952. ;eax is a work buffer
  953. mov ebx, ulBlu
  954. mov ecx,ppalTemp
  955. mov edx,MAX_PAL_ERROR
  956. mov esi,ppalMax
  957. ;edi is used to accum ulErrTemp
  958. jmp Begin_Loop
  959. align 16
  960. Check_For_Done:
  961. add ecx, 4
  962. cmp ecx, esi
  963. jz short Done
  964. Begin_Loop:
  965. mov edi, edx // Put best error so far in
  966. movzx eax, BYTE PTR [ecx+2] // Get the blue byte from log pal
  967. sub eax, ebx // Subtract out the blue component
  968. sub edi, DWORD PTR [aArrayOfSquares+1020+eax*4] // Sub the square of the
  969. // the red diff from the best so far
  970. jbe short Check_For_Done // If it's 0 or below jump to done
  971. movzx eax, BYTE PTR [ecx+1] // Get green byte from log pal
  972. sub eax, ulGre // Subtract out the green component
  973. sub edi, DWORD PTR [aArrayOfSquares+1020+eax*4] // Sub the square of the
  974. // blue diff with the best so far.
  975. jbe short Check_For_Done // If it's 0 or below jump to done
  976. movzx eax, BYTE PTR [ecx] // Put red byte from log pal
  977. sub eax, ulRed // Subtract out red component
  978. sub edi, DWORD PTR [aArrayOfSquares+1020+eax*4] // Sub square of diff
  979. jbe short Check_For_Done // If it's 0 or below jump to done
  980. // New_Best:
  981. mov ppalBest, ecx // Remember our best entry so far
  982. sub edx,edi // Subtract out what remains to
  983. // get our new best error.
  984. jnz Check_For_Done // If it's 0 error we are done.
  985. Done:
  986. }
  987. #else
  988. #if defined(_MIPS_)
  989. ppalBest = ppalSearchNearestEntry(ppalTemp,
  990. palentry,
  991. cEntries(),
  992. pArrayOfSquares);
  993. #else
  994. ULONG ulError; // The least error for ppalBest
  995. ULONG ulErrTemp;
  996. ulError = MAX_PAL_ERROR;
  997. do
  998. {
  999. if ((ulErrTemp =
  1000. pArrayOfSquares[ppalTemp->peRed - palentry.peRed] +
  1001. pArrayOfSquares[ppalTemp->peGreen - palentry.peGreen] +
  1002. pArrayOfSquares[ppalTemp->peBlue - palentry.peBlue]) < ulError)
  1003. {
  1004. ppalBest = ppalTemp;
  1005. if ((ulError = ulErrTemp) == 0)
  1006. {
  1007. break;
  1008. }
  1009. }
  1010. } while (++ppalTemp < ppalMax);
  1011. #endif // #if defined(_MIPS_)
  1012. #endif // #if defined(_X86_)
  1013. ASSERTGDI( ((ULONG)(ppalBest - ppalBase) < cEntries()), "index too big ulGetNearestFromPalentry");
  1014. // Sundown safe truncation
  1015. return (ULONG)(ppalBest - ppalBase);
  1016. }
  1017. /******************************Public*Routine******************************\
  1018. * ulIndexedGetMatchFromPalentry
  1019. *
  1020. * Given a PALETTEENTRY, finds the index of the matching entry in the
  1021. * specified palette, or returns 0xFFFFFFFF if there's no exact match.
  1022. *
  1023. * Note: This function does not use any semaphoring, nor does it expect the
  1024. * calling code to have done so. Palettes belong to DCs, and DCs are unique
  1025. * on a per-process basis; therefore, the only risk is that a multithreaded
  1026. * app acting on a palette-managed DC (because non-palette-managed palettes
  1027. * can never change) might have one thread change the palette while another
  1028. * thread is creating a brush or doing something similar that reads the
  1029. * palette. In that case, the app's in trouble anyway, because unless it
  1030. * does its own synchronization (and if it does, there's no issue here at all),
  1031. * then it can't be sure which palette will be in effect for the brush, and
  1032. * it would get indeterminate results even if we did protect the palette
  1033. * while we did this.
  1034. *
  1035. * History:
  1036. * Sun 27-Dec-1992 -by- Michael Abrash [mikeab]
  1037. * Wrote it.
  1038. \**************************************************************************/
  1039. ULONG FASTCALL ulIndexedGetMatchFromPalentry(PALETTE* ppal, ULONG ulRGB)
  1040. {
  1041. ULONG ulIndex;
  1042. PAL_ULONG palentryTemp, *ppalTemp, *ppalMax;
  1043. XEPALOBJ pal(ppal);
  1044. //
  1045. // make a copy we can access as a ULONG
  1046. //
  1047. palentryTemp.ul = ulRGB;
  1048. ASSERTGDI(pal.cEntries() != 0, "ERROR ulGetNearestFromPalentry cEntries==0");
  1049. if (palentryTemp.pal.peFlags == PC_EXPLICIT)
  1050. {
  1051. //
  1052. // This is an explicit index, so we can just use it directly.
  1053. // Explicit indices are limited to 8 bits, so mask off high three bytes,
  1054. // then keep within the number of palette entries, if necessary
  1055. //
  1056. ulIndex = palentryTemp.ul & 0x000000FF;
  1057. if (ulIndex >= pal.cEntries())
  1058. {
  1059. ulIndex = ulIndex % pal.cEntries();
  1060. }
  1061. return(ulIndex);
  1062. }
  1063. //
  1064. // We only care about the RGB fields from now on
  1065. //
  1066. palentryTemp.ul &= 0x00FFFFFF;
  1067. //
  1068. // Scan through the palette until we either find an exact match or have
  1069. // rejected all the palette entries
  1070. //
  1071. ppalTemp = pal.apalColorGet(); // point to the first palette entry
  1072. ppalMax = ppalTemp + pal.cEntries(); // last palette entry
  1073. while (ppalTemp != ppalMax)
  1074. {
  1075. //
  1076. // Does the current palette entry match the color we're searching for?
  1077. //
  1078. if ((ppalTemp->ul & 0x00FFFFFF) == palentryTemp.ul)
  1079. {
  1080. //
  1081. // Yes, we've found an exact match.
  1082. //
  1083. goto ExactMatch;
  1084. }
  1085. ppalTemp++;
  1086. }
  1087. //
  1088. // We didn't find an exact match.
  1089. //
  1090. return(0xFFFFFFFF);
  1091. //
  1092. // We've found an exact match.
  1093. //
  1094. ExactMatch:
  1095. //Sundown safe truncation
  1096. return(ULONG)(ppalTemp - pal.apalColorGet());
  1097. }
  1098. /******************************Public*Routine******************************\
  1099. * ulIndexedGetNearestFromPalentry
  1100. *
  1101. * For an indexed palette, finds the index of the matching entry in the
  1102. * specified palette by first doing an exact search, then doing a nearest
  1103. * search.
  1104. *
  1105. * Note that this routine isn't in-line because it is sometimes the target
  1106. * of indirect calls.
  1107. \**************************************************************************/
  1108. ULONG FASTCALL ulIndexedGetNearestFromPalentry(PALETTE* ppal, ULONG ulRGB)
  1109. {
  1110. ULONG ul = ulIndexedGetMatchFromPalentry(ppal, ulRGB);
  1111. if (ul == 0xffffffff)
  1112. {
  1113. XEPALOBJ pal(ppal);
  1114. ul = pal.ulGetNearestFromPalentryNoExactMatchFirst(*((PALETTEENTRY*) &ulRGB));
  1115. }
  1116. return(ul);
  1117. }
  1118. /******************************Public*Routine******************************\
  1119. * ulRGBToBitfield
  1120. *
  1121. * Converts an RGB into an index for Bitfield palettes.
  1122. *
  1123. * History:
  1124. * 08-Nov-1991 -by- Patrick Haluptzok patrickh
  1125. * Wrote it.
  1126. \**************************************************************************/
  1127. ULONG FASTCALL ulRGBToBitfield(PALETTE* ppal, ULONG ulRGB)
  1128. {
  1129. XEPALOBJ pal(ppal);
  1130. ASSERTGDI(pal.bIsBitfields(), "Error ulRGBToBitfield not bitfields");
  1131. return((((ulRGB >> pal.cRedLeft()) << pal.cRedRight()) & pal.flRed()) |
  1132. (((ulRGB >> pal.cGreLeft()) << pal.cGreRight()) & pal.flGre()) |
  1133. (((ulRGB >> pal.cBluLeft()) << pal.cBluRight()) & pal.flBlu()));
  1134. }
  1135. /******************************Public*Routine******************************\
  1136. * ulRGBTo565
  1137. *
  1138. * Converts an RGB into an index for 5-6-5 bitfield palettes.
  1139. \**************************************************************************/
  1140. ULONG FASTCALL ulRGBTo565(PALETTE* ppal, ULONG ulRGB)
  1141. {
  1142. ASSERTGDI((((XEPALOBJ) ppal).bIsBitfields()) &&
  1143. (((XEPALOBJ) ppal).flRed() == 0xf800) &&
  1144. (((XEPALOBJ) ppal).flGre() == 0x07e0) &&
  1145. (((XEPALOBJ) ppal).flBlu() == 0x001f), "Error not 5-6-5");
  1146. return(((ulRGB >> 19) & 0x001f) |
  1147. ((ulRGB >> 5) & 0x07e0) |
  1148. ((ulRGB << 8) & 0xf800));
  1149. }
  1150. /******************************Public*Routine******************************\
  1151. * ulRGBTo555
  1152. *
  1153. * Converts an RGB into an index for 5-5-5 bitfield palettes.
  1154. \**************************************************************************/
  1155. ULONG FASTCALL ulRGBTo555(PALETTE* ppal, ULONG ulRGB)
  1156. {
  1157. ASSERTGDI((((XEPALOBJ) ppal).bIsBitfields()) &&
  1158. (((XEPALOBJ) ppal).flRed() == 0x7c00) &&
  1159. (((XEPALOBJ) ppal).flGre() == 0x03e0) &&
  1160. (((XEPALOBJ) ppal).flBlu() == 0x001f), "Error not 5-5-5");
  1161. return(((ulRGB >> 19) & 0x001f) |
  1162. ((ulRGB >> 6) & 0x03e0) |
  1163. ((ulRGB << 7) & 0x7c00));
  1164. }
  1165. /******************************Public*Routine******************************\
  1166. * ulRGBToBGR
  1167. *
  1168. * Converts an RGB into an index for BGR palettes.
  1169. \**************************************************************************/
  1170. ULONG FASTCALL ulRGBToBGR(PALETTE* ppal, ULONG ulRGB)
  1171. {
  1172. ASSERTGDI(((XEPALOBJ) ppal).bIsBGR(), "Error not BGR");
  1173. return(((ulRGB & 0x0000ff) << 16) |
  1174. ((ulRGB & 0x00ff00)) |
  1175. ((ulRGB & 0xff0000) >> 16));
  1176. }
  1177. /******************************Public*Routine******************************\
  1178. * ulRGBToRGB
  1179. *
  1180. * Converts an RGB into an index for RGB palettes.
  1181. \**************************************************************************/
  1182. ULONG FASTCALL ulRGBToRGB(PALETTE* ppal, ULONG ulRGB)
  1183. {
  1184. ASSERTGDI(((XEPALOBJ) ppal).bIsRGB(), "Error not RGB");
  1185. return(ulRGB & 0xffffff);
  1186. }
  1187. /******************************Public*Routine******************************\
  1188. * ulRawToRaw
  1189. *
  1190. * No Converts, just pass through original data
  1191. \**************************************************************************/
  1192. ULONG FASTCALL ulRawToRaw(PALETTE* ppal, ULONG ulRGB)
  1193. {
  1194. UNREFERENCED_PARAMETER(ppal);
  1195. return(ulRGB);
  1196. }
  1197. /******************************Public*Routine******************************\
  1198. * vComputeCallTables
  1199. *
  1200. * Updates the pfnGetMatchFromPalentry and pfnGetNearestFromPalentry
  1201. * function pointers to reflect the current palette settings.
  1202. \**************************************************************************/
  1203. VOID XEPALOBJ::vComputeCallTables()
  1204. {
  1205. PFN_GetFromPalentry pfnGetMatchFromPalentry;
  1206. PFN_GetFromPalentry pfnGetNearestFromPalentry;
  1207. if (bIsIndexed())
  1208. {
  1209. pfnGetMatchFromPalentry = ulIndexedGetMatchFromPalentry;
  1210. pfnGetNearestFromPalentry = ulIndexedGetNearestFromPalentry;
  1211. }
  1212. else
  1213. {
  1214. if (bIsBitfields())
  1215. {
  1216. if ((flBlu() == 0x001f) &&
  1217. (flGre() == 0x07e0) &&
  1218. (flRed() == 0xf800))
  1219. {
  1220. pfnGetMatchFromPalentry = ulRGBTo565;
  1221. }
  1222. else if ((flBlu() == 0x001f) &&
  1223. (flGre() == 0x03e0) &&
  1224. (flRed() == 0x7c00))
  1225. {
  1226. pfnGetMatchFromPalentry = ulRGBTo555;
  1227. }
  1228. else
  1229. {
  1230. pfnGetMatchFromPalentry = ulRGBToBitfield;
  1231. }
  1232. }
  1233. else if (bIsBGR())
  1234. {
  1235. pfnGetMatchFromPalentry = ulRGBToBGR;
  1236. }
  1237. else if (bIsCMYK())
  1238. {
  1239. //
  1240. // In CMYK color case, Palette index == CMYK color data.
  1241. //
  1242. pfnGetMatchFromPalentry = ulRawToRaw;
  1243. }
  1244. else
  1245. {
  1246. ASSERTGDI(bIsRGB(), "ERROR invalid type in palette");
  1247. pfnGetMatchFromPalentry = ulRGBToRGB;
  1248. }
  1249. //
  1250. // For non-indexed palettes, an exact match can always be found,
  1251. // so GetMatch and GetNearest can be the same function:
  1252. //
  1253. pfnGetNearestFromPalentry = pfnGetMatchFromPalentry;
  1254. }
  1255. ppal->pfnGetMatchFromPalentry = pfnGetMatchFromPalentry;
  1256. ppal->pfnGetNearestFromPalentry = pfnGetNearestFromPalentry;
  1257. }
  1258. /******************************Public*Routine******************************\
  1259. * XEPALOBJ::ulGetEntries
  1260. *
  1261. * This function copies the requested palette entries out.
  1262. *
  1263. * History:
  1264. * 18-Nov-1990 -by- Patrick Haluptzok patrickh
  1265. * Wrote it.
  1266. \**************************************************************************/
  1267. extern "C" ULONG PALOBJ_cGetColors(
  1268. PALOBJ *ppo,
  1269. ULONG iStart,
  1270. ULONG cEntry,
  1271. ULONG *ppalentry
  1272. )
  1273. {
  1274. XEPALOBJ *ppal = (XEPALOBJ *)ppo;
  1275. //
  1276. // Get color data from PALOBJ
  1277. //
  1278. ULONG ulRet = ppal->ulGetEntries(iStart, cEntry, (PPALETTEENTRY)ppalentry,FALSE);
  1279. //
  1280. // Correct GammaRamp if nessesary.
  1281. //
  1282. if (ppal->bNeedGammaCorrection())
  1283. {
  1284. //
  1285. // Correct color based on GammaRamp table
  1286. //
  1287. ppal->CorrectColors((PPALETTEENTRY)ppalentry,ulRet);
  1288. }
  1289. return (ulRet);
  1290. }
  1291. ULONG XEPALOBJ::ulGetEntries(ULONG iStart, ULONG cEntry,
  1292. PPALETTEENTRY ppalentry, BOOL bZeroFlags)
  1293. {
  1294. // See if the number of entries in the palette is being requested.
  1295. if (ppalentry == (PPALETTEENTRY) NULL)
  1296. return(ppal->cEntries);
  1297. // Make sure the start index is valid, this checks RGB case also.
  1298. if (iStart >= ppal->cEntries)
  1299. return(0);
  1300. // Make sure we don't ask for more than we have
  1301. if (cEntry > (ppal->cEntries - iStart))
  1302. cEntry = ppal->cEntries - iStart;
  1303. // Copy them to the buffer
  1304. PPALETTEENTRY ppalstruc = (PPALETTEENTRY) &(ppal->apalColor[iStart]);
  1305. RtlCopyMemory(ppalentry, ppalstruc, cEntry*sizeof(PALETTEENTRY));
  1306. if (bZeroFlags)
  1307. {
  1308. ppalstruc = ppalentry + cEntry;
  1309. while (ppalentry < ppalstruc)
  1310. {
  1311. ppalentry->peFlags = 0;
  1312. ppalentry++;
  1313. }
  1314. }
  1315. return(cEntry);
  1316. }
  1317. /******************************Public*Routine******************************\
  1318. * XEPALOBJ::ulSetEntries
  1319. *
  1320. * This function copies the requested palette entries into the palette
  1321. *
  1322. * History:
  1323. * 18-Nov-1990 -by- Patrick Haluptzok patrickh
  1324. * Wrote it.
  1325. \**************************************************************************/
  1326. ULONG XEPALOBJ::ulSetEntries(ULONG iStart, ULONG cEntry, CONST PALETTEENTRY *ppalentry)
  1327. {
  1328. ASSERTGDI(bIsPalDC(), "ERROR: ulSetEntries called on non-DC palette");
  1329. // Make sure they aren't trying to change the default or halftone palette.
  1330. // Make sure they aren't trying to pass us NULL.
  1331. // Make sure the start index is valid, this checks the RGB case also.
  1332. if ((ppal == ppalDefault) ||
  1333. bIsHTPal() ||
  1334. (ppalentry == (PPALETTEENTRY) NULL) ||
  1335. (iStart >= ppal->cEntries))
  1336. {
  1337. return(0);
  1338. }
  1339. // Make sure we don't try to copy off the end of the buffer
  1340. if (iStart + cEntry > ppal->cEntries)
  1341. cEntry = ppal->cEntries - iStart;
  1342. // Let's not update the palette time if we don't have to.
  1343. if (cEntry == 0)
  1344. return(0);
  1345. // Copy the new values in
  1346. PPALETTEENTRY ppalstruc = (PPALETTEENTRY) &(ppal->apalColor[iStart]);
  1347. PBYTE pjFore = NULL;
  1348. PBYTE pjCurrent = NULL;
  1349. // Mark the foreground translate dirty so we get a new realization done
  1350. // in the next RealizePaletette.
  1351. if (ptransFore() != NULL)
  1352. {
  1353. ptransFore()->iUniq = 0;
  1354. pjFore = &(ptransFore()->ajVector[iStart]);
  1355. }
  1356. if (ptransCurrent() != NULL)
  1357. {
  1358. ptransCurrent()->iUniq = 0;
  1359. pjCurrent = &(ptransCurrent()->ajVector[iStart]);
  1360. }
  1361. // Hold the orginal values in temporary vars.
  1362. ULONG ulReturn = cEntry;
  1363. while(cEntry--)
  1364. {
  1365. *ppalstruc = *ppalentry;
  1366. if (pjFore)
  1367. {
  1368. *pjFore = 0;
  1369. pjFore++;
  1370. }
  1371. if (pjCurrent)
  1372. {
  1373. *pjCurrent = 0;
  1374. pjCurrent++;
  1375. }
  1376. ppalentry++;
  1377. ppalstruc++;
  1378. }
  1379. // Set in the new palette time.
  1380. vUpdateTime();
  1381. // Mark foreground translate and current translate invalid so they get rerealized.
  1382. return(ulReturn);
  1383. }
  1384. /******************************Public*Routine******************************\
  1385. * XEPALOBJ::vUnrefPalette()
  1386. *
  1387. * Palettes are referenced when put into a surface. If the reference count
  1388. * is one when vUnreference is called it mean the last surface using the
  1389. * palette is being deleted so the palette should be deleted. Otherwise the
  1390. * reference count should just be decremented.
  1391. *
  1392. * History:
  1393. * 09-Nov-1992 -by- Patrick Haluptzok patrickh
  1394. * Wrote it.
  1395. \**************************************************************************/
  1396. VOID XEPALOBJ::vUnrefPalette()
  1397. {
  1398. if (ppal != (PPALETTE) NULL)
  1399. {
  1400. ASSERTGDI(!bIsPalDC(), "ERROR should not be called on DC palette");
  1401. if (HmgRemoveObject((HOBJ)ppal->hGet(), 0, 1, FALSE, PAL_TYPE))
  1402. {
  1403. if (bIsPalManaged() && ppalOriginal())
  1404. {
  1405. //
  1406. // We have to delete the original palette.
  1407. //
  1408. PVOID ppalOld = HmgRemoveObject((HOBJ)ppalOriginal()->hGet(), 0, 0, FALSE, PAL_TYPE);
  1409. ASSERTGDI(ppalOld != NULL, "ERROR it failed to remove object handle");
  1410. FREEOBJ(ppalOriginal(), PAL_TYPE);
  1411. }
  1412. if (ppal != ppalColor())
  1413. {
  1414. //
  1415. // Remove a reference to the palette who owns the color
  1416. // table.
  1417. //
  1418. XEPALOBJ palColor(ppalColor());
  1419. palColor.vUnrefPalette();
  1420. }
  1421. if (ppal->pRGBXlate != NULL)
  1422. {
  1423. if (ppal->pRGBXlate != gpRGBXlate)
  1424. VFREEMEM(ppal->pRGBXlate);
  1425. ppal->pRGBXlate = NULL;
  1426. }
  1427. ASSERTGDI(ppal != ppalMono, "ERROR mono palette went to 0");
  1428. FREEOBJ(ppal, PAL_TYPE);
  1429. }
  1430. else
  1431. {
  1432. //
  1433. // Just decrement the reference count.
  1434. //
  1435. DEC_SHARE_REF_CNT(ppal);
  1436. }
  1437. ppal = (PPALETTE) NULL;
  1438. }
  1439. }
  1440. /******************************Public*Routine******************************\
  1441. * bDeletePalette
  1442. *
  1443. * This attempts to delete a palette. It will fail if the palette
  1444. * is currently selected into more than one DC or is busy.
  1445. *
  1446. * History:
  1447. * Wed 04-Sep-1991 -by- Patrick Haluptzok [patrickh]
  1448. * Simplified and renamed.
  1449. *
  1450. * 27-Nov-1990 -by- Patrick Haluptzok patrickh
  1451. * Wrote it.
  1452. \**************************************************************************/
  1453. BOOL bDeletePalette(HPAL hpal, BOOL bCleanup, CLEANUPTYPE cutype)
  1454. {
  1455. //
  1456. // Need to grab the palette semaphore so this guy can't get selected in
  1457. // anymore. Only once we know he isn't selected anywhere and we hold the
  1458. // semaphore so he can't be selected anywhere can we delete the translates.
  1459. // This is because to access the translates you must either hold the palette
  1460. // semaphore or have a lock on a DC that the palette is selected in.
  1461. // Grab the semaphore so ResizePalette doesn't change the palette out from
  1462. // under you.
  1463. //
  1464. SEMOBJ semo(ghsemPalette);
  1465. EPALOBJ palobj((HPALETTE)hpal);
  1466. return(palobj.bDeletePalette(bCleanup,cutype));
  1467. }
  1468. /******************************Public*Routine******************************\
  1469. * XEPALOBJ::bDeletePalette()
  1470. *
  1471. * This attempts to delete a palette. It will fail if the palette
  1472. * is currently selected into more than one DC or is busy.
  1473. *
  1474. * History:
  1475. * 27-Nov-1990 -by- Patrick Haluptzok patrickh
  1476. * Wrote it.
  1477. \**************************************************************************/
  1478. BOOL XEPALOBJ::bDeletePalette(BOOL bCleanup, CLEANUPTYPE cutype)
  1479. {
  1480. BOOL bReturn = TRUE;
  1481. if ((ppal != ppalDefault) &&
  1482. (ppal != (PPALETTE) NULL) &&
  1483. (ppal != ppalMono))
  1484. {
  1485. if (ppal->pRGBXlate != NULL)
  1486. {
  1487. if (ppal->pRGBXlate != gpRGBXlate)
  1488. VFREEMEM(ppal->pRGBXlate);
  1489. ppal->pRGBXlate = NULL;
  1490. }
  1491. if (bIsPalDC())
  1492. {
  1493. if (ppal->cRefhpal != 0)
  1494. {
  1495. WARNING("bDelete failed palette is selected into a DC\n");
  1496. return(FALSE);
  1497. }
  1498. vMakeNoXlate();
  1499. }
  1500. ASSERTGDI(HmgQueryLock((HOBJ)ppal->hGet()) == 0, "bDeletePalette cLock != 0");
  1501. //
  1502. // Need to make sure we are not being used in a palette API somewhere.
  1503. //
  1504. if (HmgRemoveObject((HOBJ)ppal->hGet(), 0, 1, FALSE, PAL_TYPE))
  1505. {
  1506. if (cutype != CLEANUP_SESSION)
  1507. {
  1508. if (bIsPalManaged() && ppalOriginal())
  1509. {
  1510. //
  1511. // We have to delete the original palette.
  1512. //
  1513. PVOID ppalOld = HmgRemoveObject((HOBJ)ppalOriginal()->hGet(), 0, 0, FALSE, PAL_TYPE);
  1514. ASSERTGDI(ppalOld != NULL, "ERROR it failed to remove object handle");
  1515. FREEOBJ(ppalOriginal(), PAL_TYPE);
  1516. }
  1517. if (ppal != ppalColor())
  1518. {
  1519. //
  1520. // Remove a reference to the palette who owns the color
  1521. // table.
  1522. //
  1523. XEPALOBJ palColor(ppalColor());
  1524. palColor.vUnrefPalette();
  1525. }
  1526. }
  1527. FREEOBJ(ppal, PAL_TYPE);
  1528. ppal = (PPALETTE) NULL;
  1529. }
  1530. else
  1531. {
  1532. //
  1533. // force deletion of palette at cleanup time
  1534. //
  1535. if (bCleanup)
  1536. {
  1537. WARNING ("DRIVER is leaking palette, we force cleanup here\n");
  1538. if (cutype != CLEANUP_SESSION)
  1539. {
  1540. //
  1541. // HmgFree will call FREEOBJ after the handle manager entry is freed
  1542. //
  1543. if (bIsPalManaged() && ppalOriginal())
  1544. {
  1545. //
  1546. // We have to delete the original palette.
  1547. //
  1548. PVOID ppalOld = HmgRemoveObject((HOBJ)ppalOriginal()->hGet(), 0, 0, FALSE, PAL_TYPE);
  1549. ASSERTGDI(ppalOld != NULL, "ERROR it failed to remove object handle");
  1550. FREEOBJ(ppalOriginal(), PAL_TYPE);
  1551. }
  1552. if (ppal != ppalColor())
  1553. {
  1554. //
  1555. // Remove a reference to the palette who owns the color
  1556. // table.
  1557. //
  1558. XEPALOBJ palColor(ppalColor());
  1559. palColor.vUnrefPalette();
  1560. }
  1561. }
  1562. HmgFree((HOBJ)ppal->hGet());
  1563. ppal = (PPALETTE) NULL;
  1564. bReturn = TRUE;
  1565. }
  1566. else
  1567. {
  1568. #if DBG
  1569. DbgPrint("The count is %lu\n", HmgQueryLock((HOBJ)ppal->hGet()));
  1570. #endif
  1571. WARNING("App error, trying to delete palette that's in use\n");
  1572. bReturn = FALSE;
  1573. }
  1574. }
  1575. }
  1576. return(bReturn);
  1577. }
  1578. /******************************Public*Routine******************************\
  1579. * XEPALOBJ::vCopy_rgbquad
  1580. *
  1581. * copies in rgbquad values, used by CreateDIBitmap
  1582. *
  1583. * History:
  1584. * 10-Dec-1990 -by- Patrick Haluptzok patrickh
  1585. * Wrote it.
  1586. \**************************************************************************/
  1587. VOID XEPALOBJ::vCopy_rgbquad(RGBQUAD *prgbquad, ULONG iStart, ULONG cEntries)
  1588. {
  1589. ASSERTGDI(iStart < ppal->cEntries,"vCopy_rgbquad iStart > cEntries\n");
  1590. PPALETTEENTRY ppalstruc = (PPALETTEENTRY) &ppal->apalColor[iStart];
  1591. if (iStart + cEntries > ppal->cEntries)
  1592. cEntries = ppal->cEntries - iStart;
  1593. #if defined(_X86_)
  1594. _asm
  1595. {
  1596. mov ecx, cEntries
  1597. mov esi, prgbquad
  1598. mov edi, ppalstruc
  1599. shr ecx, 1
  1600. jz Done_Unroll
  1601. Begin_Loop:
  1602. mov eax, [esi]
  1603. mov edx, [esi+4]
  1604. bswap eax
  1605. bswap edx
  1606. shr eax, 8
  1607. shr edx, 8
  1608. mov [edi], eax
  1609. mov [edi+4], edx
  1610. add esi, 8
  1611. add edi, 8
  1612. dec ecx
  1613. jnz Begin_Loop
  1614. Done_Unroll:
  1615. test cEntries, 1
  1616. jz Done
  1617. mov eax, [esi]
  1618. bswap eax
  1619. shr eax, 8
  1620. mov [edi], eax
  1621. Done:
  1622. }
  1623. #else
  1624. while(cEntries--)
  1625. {
  1626. ppalstruc->peFlags = 0;
  1627. ppalstruc->peBlue = prgbquad->rgbBlue;
  1628. ppalstruc->peRed = prgbquad->rgbRed;
  1629. ppalstruc->peGreen = prgbquad->rgbGreen;
  1630. ppalstruc++;
  1631. prgbquad++;
  1632. }
  1633. #endif
  1634. vUpdateTime();
  1635. }
  1636. /******************************Public*Routine******************************\
  1637. * XEPALOBJ::vCopy_cmykquad
  1638. *
  1639. * copies in cmykquad values, used by CreateDIBitmap
  1640. *
  1641. * History:
  1642. * 24-Mar-1997 -by- Hideyuki Nagase hideyukn
  1643. * Wrote it.
  1644. \**************************************************************************/
  1645. VOID XEPALOBJ::vCopy_cmykquad(ULONG *pcmykquad, ULONG iStart, ULONG cEntries)
  1646. {
  1647. ASSERTGDI(iStart < ppal->cEntries,"vCopy_cmykquad iStart > cEntries\n");
  1648. PULONG ppalCMYK = (PULONG) &ppal->apalColor[iStart];
  1649. if (iStart + cEntries > ppal->cEntries)
  1650. cEntries = ppal->cEntries - iStart;
  1651. RtlCopyMemory(ppalCMYK,pcmykquad,cEntries*sizeof(ULONG));
  1652. vUpdateTime();
  1653. }
  1654. /******************************Public*Routine******************************\
  1655. * BOOL XEPALOBJ::bSet_hdev
  1656. *
  1657. * Attempts to set the hdev owner of a DC palette.
  1658. *
  1659. * Returns: True if successful, False for failure.
  1660. *
  1661. * This operation must be protected by the palette semaphore.
  1662. *
  1663. * History:
  1664. * 08-Jan-1991 -by- Patrick Haluptzok patrickh
  1665. * Wrote it.
  1666. \**************************************************************************/
  1667. BOOL XEPALOBJ::bSet_hdev(HDEV hdevNew)
  1668. {
  1669. ASSERTGDI(ppal->flPal & PAL_DC, "bSet_() passed invalid palette type\n");
  1670. ASSERTGDI(hdevNew != (HDEV) 0, "ERROR hdev is 0");
  1671. if (hdev() != hdevNew)
  1672. {
  1673. if (ppal->cRefhpal == 0)
  1674. {
  1675. // It is not selected into a DC yet so it is safe to delete xlates
  1676. // without holding the DEVLOCK for the device. because no output
  1677. // can be occuring now.
  1678. vMakeNoXlate();
  1679. hdev(hdevNew);
  1680. }
  1681. else
  1682. return(FALSE);
  1683. }
  1684. return(TRUE);
  1685. }
  1686. /******************************Member*Function*****************************\
  1687. * BOOL XEPALOBJ::bEqualEntries
  1688. *
  1689. * Return TRUE if the given two palettes have same color entries.
  1690. *
  1691. * History:
  1692. * 04-Jun-1993 -by- Wendy Wu [wendywu]
  1693. * Wrote it.
  1694. \**************************************************************************/
  1695. BOOL XEPALOBJ::bEqualEntries(XEPALOBJ pal)
  1696. {
  1697. if (!pal.bValid())
  1698. return(FALSE);
  1699. if (cEntries() == pal.cEntries())
  1700. {
  1701. if (flPal() & PAL_INDEXED)
  1702. {
  1703. if (!(pal.flPal() & PAL_INDEXED))
  1704. return(FALSE);
  1705. ULONG ulTemp, ulSource, ulDest;
  1706. ULONG cComp = cEntries();
  1707. for (ulTemp = 0; ulTemp < cComp; ulTemp++)
  1708. {
  1709. ulSource = apalColorGet()[ulTemp].ul;
  1710. ulDest = pal.apalColorGet()[ulTemp].ul;
  1711. if ((ulSource ^ ulDest) << 8)
  1712. {
  1713. return(FALSE);
  1714. }
  1715. }
  1716. return(TRUE);
  1717. }
  1718. else if (flPal() & PAL_BITFIELDS)
  1719. {
  1720. if (!(pal.flPal() & PAL_BITFIELDS))
  1721. return(FALSE);
  1722. return(!memcmp(apalColorGet(), pal.apalColorGet(),
  1723. sizeof(PALETTEENTRY) * 3));
  1724. }
  1725. else if (flPal() & PAL_RGB)
  1726. {
  1727. if (pal.flPal() & PAL_RGB)
  1728. return(TRUE);
  1729. else
  1730. return(FALSE);
  1731. }
  1732. else if (flPal() & PAL_BGR)
  1733. {
  1734. if (pal.flPal() & PAL_BGR)
  1735. return(TRUE);
  1736. else
  1737. return(FALSE);
  1738. }
  1739. else
  1740. RIP("There is another type we didn't know about");
  1741. }
  1742. return(FALSE);
  1743. }
  1744. /******************************Public*Routine******************************\
  1745. * bInitPALOBJ
  1746. *
  1747. * Initialize the PALOBJ component
  1748. *
  1749. * History:
  1750. * 10-Jan-1991 -by- Patrick Haluptzok patrickh
  1751. * Wrote it.
  1752. \**************************************************************************/
  1753. extern "C" BOOL bInitPALOBJ()
  1754. {
  1755. INT iTemp;
  1756. pArrayOfSquares = &(aArrayOfSquares[255]);
  1757. for (iTemp = 0; iTemp < 256; iTemp++)
  1758. {
  1759. pArrayOfSquares[iTemp] =
  1760. pArrayOfSquares[-(iTemp)] = iTemp * iTemp;
  1761. }
  1762. if ((ghsemPalette = GreCreateSemaphore()) == NULL)
  1763. return(FALSE);
  1764. // Now initialize 20 color default DC palette
  1765. if (!bSetStockObject(GreCreatePalette((LOGPALETTE *) &logDefaultPal),DEFAULT_PALETTE))
  1766. {
  1767. return(FALSE);
  1768. }
  1769. {
  1770. EPALOBJ palDefault((HPALETTE) STOCKOBJ_PAL);
  1771. ASSERTGDI(palDefault.bValid(), "ERROR invalid default palette");
  1772. palDefault.vSetPID(OBJECT_OWNER_PUBLIC);
  1773. ppalDefault = palDefault.ppalGet();
  1774. dclevelDefault.hpal = STOCKOBJ_PAL;
  1775. dclevelDefault.ppal = ppalDefault;
  1776. // Now initialize default surface palette for 8bpp displays
  1777. PALMEMOBJ palDefaultSurface8bpp;
  1778. if (!palDefaultSurface8bpp.bCreatePalette(PAL_INDEXED,
  1779. 256,
  1780. NULL,
  1781. 0,
  1782. 0,
  1783. 0,
  1784. PAL_FREE))
  1785. {
  1786. return(FALSE);
  1787. }
  1788. ppalDefaultSurface8bpp = palDefaultSurface8bpp.ppalGet();
  1789. // Copy the 20 default colours. The middle entries will be black
  1790. PALETTEENTRY palEntry;
  1791. ULONG ulReturn;
  1792. ULONG ulNumReserved = palDefault.cEntries() >> 1;
  1793. for (ulReturn = 0; ulReturn < ulNumReserved; ulReturn++)
  1794. {
  1795. palEntry = palDefault.palentryGet(ulReturn);
  1796. palDefaultSurface8bpp.palentrySet(ulReturn, palEntry);
  1797. }
  1798. ULONG ulCurrentPal = 256;
  1799. ULONG ulCurrentDef = 20;
  1800. for (ulReturn = 0; ulReturn < ulNumReserved; ulReturn++)
  1801. {
  1802. ulCurrentPal--;
  1803. ulCurrentDef--;
  1804. palEntry = palDefault.palentryGet(ulCurrentDef);
  1805. palDefaultSurface8bpp.palentrySet(ulCurrentPal, palEntry);
  1806. }
  1807. // Leave a reference count of 1 so that it never gets deleted
  1808. palDefaultSurface8bpp.ppalSet(NULL);
  1809. }
  1810. // Now initialize default monochrome surface palette.
  1811. PALMEMOBJ palMono;
  1812. if (!palMono.bCreatePalette(PAL_INDEXED, 2, gaulMono,
  1813. 0, 0, 0, PAL_FIXED | PAL_MONOCHROME))
  1814. {
  1815. WARNING("GDI failed mono palette create\n");
  1816. return(FALSE);
  1817. }
  1818. palMono.vKeepIt();
  1819. hpalMono = palMono.hpal();
  1820. ppalMono = palMono.ppalGet();
  1821. //
  1822. // Now initialize default RGB palette for gradient fill source
  1823. //
  1824. PALMEMOBJ palRGB;
  1825. if (!palRGB.bCreatePalette(
  1826. PAL_BGR,
  1827. 0,
  1828. NULL,
  1829. 0,
  1830. 0,
  1831. 0,
  1832. PAL_FIXED))
  1833. {
  1834. WARNING("GDI failed RGB palette create\n");
  1835. return(FALSE);
  1836. }
  1837. gppalRGB = palRGB.ppalGet();
  1838. // Leave a reference count of 1 so that it never gets deleted
  1839. palRGB.ppalSet(NULL);
  1840. return(TRUE);
  1841. }
  1842. /******************************Public*Routine******************************\
  1843. * ULONG XEPALOBJ::ulAnimatePalette
  1844. *
  1845. * This function changes the requested palette entries in the palette.
  1846. *
  1847. * History:
  1848. * 16-Jan-1991 -by- Patrick Haluptzok patrickh
  1849. * Wrote it.
  1850. \**************************************************************************/
  1851. ULONG XEPALOBJ::ulAnimatePalette(ULONG iStart, ULONG cEntry, CONST PALETTEENTRY *ppalSrc)
  1852. {
  1853. ASSERTGDI(bIsPalDC(), "ERROR this is not a DC palette");
  1854. // Make sure they aren't trying to change the default palette.
  1855. // Make sure they aren't trying to pass us NULL.
  1856. // Make sure the start index is valid, this checks the RGB case also.
  1857. if ((ppal == ppalDefault) ||
  1858. (ppalSrc == (PPALETTEENTRY) NULL) ||
  1859. (iStart >= ppal->cEntries))
  1860. {
  1861. return(0);
  1862. }
  1863. // Make sure we don't try to copy off the end of the buffer
  1864. if (iStart + cEntry > ppal->cEntries)
  1865. cEntry = ppal->cEntries - iStart;
  1866. // Let's not update the palette if we don't have to.
  1867. if (cEntry == 0)
  1868. return(0);
  1869. // Save the Original values
  1870. ULONG ulReturn = 0;
  1871. ULONG ulTemp = cEntry;
  1872. // Copy the new values in
  1873. PAL_ULONG *ppalLogical = (PAL_ULONG *) &(ppal->apalColor[iStart]);
  1874. PAL_ULONG palentry, palPhys;
  1875. TRANSLATE *ptransCurrent = NULL;
  1876. PBYTE pjCurrent = NULL;
  1877. XEPALOBJ palSurf;
  1878. // Grab the SEMOBJ so you can access the translates, and can look at cEntries.
  1879. {
  1880. SEMOBJ semo(ghsemPalette);
  1881. if (cRefhpal())
  1882. {
  1883. PDEVOBJ po(hdev());
  1884. ASSERTGDI(po.bValid(), "ERROR invalid pdev");
  1885. if (po.bIsPalManaged())
  1886. {
  1887. palSurf.ppalSet(po.ppalSurf());
  1888. ASSERTGDI(palSurf.bValid(), "ERROR GDI ulAnimatePalette dc");
  1889. ASSERTGDI(palSurf.bIsPalManaged(), "ERROR pdev palmanaged but not palette ???");
  1890. if (ppal->ptransCurrent != NULL)
  1891. {
  1892. ptransCurrent = ppal->ptransCurrent;
  1893. pjCurrent = &(ppal->ptransCurrent->ajVector[iStart]);
  1894. }
  1895. }
  1896. }
  1897. while(ulTemp--)
  1898. {
  1899. palentry.pal = *ppalSrc;
  1900. if (ppalLogical->pal.peFlags & PC_RESERVED)
  1901. {
  1902. ppalLogical->ul = palentry.ul;
  1903. ulReturn++;
  1904. if (pjCurrent != NULL)
  1905. {
  1906. palPhys.ul = palSurf.ulEntryGet((ULONG) *pjCurrent);
  1907. if (palPhys.pal.peFlags & PC_RESERVED)
  1908. {
  1909. palentry.pal.peFlags = palPhys.pal.peFlags;
  1910. palSurf.ulEntrySet(*pjCurrent, palentry.ul);
  1911. }
  1912. }
  1913. }
  1914. if (pjCurrent != NULL)
  1915. pjCurrent++;
  1916. ppalSrc++;
  1917. ppalLogical++;
  1918. }
  1919. // Release the palette semaphore, we are done accessing protected stuff.
  1920. }
  1921. // Don't set in a new time, Animate doesn't do that.
  1922. if (pjCurrent)
  1923. {
  1924. PDEVOBJ po(hdev());
  1925. // Lock the screen semaphore so that we don't get flipped into
  1926. // full screen after checking the bit.
  1927. GreAcquireSemaphoreEx(po.hsemDevLock(), SEMORDER_DEVLOCK, NULL);
  1928. GreEnterMonitoredSection(po.ppdev, WD_DEVLOCK);
  1929. // Make sure we're still a palettized device -- a dynamic mode change
  1930. // may have occured between the time we released the palette semaphore
  1931. // and acquired the devlock.
  1932. if (po.bIsPalManaged())
  1933. {
  1934. SEMOBJ so(po.hsemPointer());
  1935. if (!po.bDisabled())
  1936. {
  1937. po.pfnSetPalette()(
  1938. po.dhpdevParent(),
  1939. (PALOBJ *) &palSurf,
  1940. 0,
  1941. 0,
  1942. palSurf.cEntries());
  1943. }
  1944. }
  1945. GreExitMonitoredSection(po.ppdev, WD_DEVLOCK);
  1946. GreReleaseSemaphoreEx(po.hsemDevLock());
  1947. }
  1948. return(ulReturn);
  1949. }
  1950. /******************************Public*Routine******************************\
  1951. * VOID XEPALOBJ::vMakeNoXlate()
  1952. *
  1953. * deletes the pxlate if it exists
  1954. *
  1955. * History:
  1956. * 19-Jan-1991 -by- Patrick Haluptzok patrickh
  1957. * Wrote it.
  1958. \**************************************************************************/
  1959. VOID XEPALOBJ::vMakeNoXlate()
  1960. {
  1961. ASSERTGDI(bIsPalDC(), "ERROR trying to delete pxlate from non-dc palette");
  1962. // Caller should grab the DEVLOCK to ensure the engine
  1963. // isn't in the middle of blt before calling.
  1964. if (ppal->ptransOld)
  1965. {
  1966. if (ppal->ptransOld != ppal->ptransFore)
  1967. VFREEMEM(ppal->ptransOld);
  1968. ppal->ptransOld = NULL;
  1969. }
  1970. if (ppal->ptransCurrent)
  1971. {
  1972. if (ppal->ptransCurrent != ppal->ptransFore)
  1973. VFREEMEM(ppal->ptransCurrent);
  1974. ppal->ptransCurrent = NULL;
  1975. }
  1976. if (ppal->ptransFore)
  1977. {
  1978. VFREEMEM(ppal->ptransFore);
  1979. ppal->ptransFore = NULL;
  1980. }
  1981. }
  1982. /******************************Public*Routine******************************\
  1983. * vAddToList
  1984. *
  1985. * Add DC to linked list of DC's attached to palette. The MLOCKOBJ must be
  1986. * grabbed before calling this function.
  1987. *
  1988. * History:
  1989. * 16-Dec-1992 -by- Patrick Haluptzok patrickh
  1990. * Wrote it.
  1991. \**************************************************************************/
  1992. VOID XEPALOBJ::vAddToList(XDCOBJ& dco)
  1993. {
  1994. ASSERTGDI(dco.bLocked(), "ERROR 14939");
  1995. ASSERTGDI(bValid(), "ERROR dj945kd");
  1996. ASSERTGDI(bIsPalDC(), "ERROR 234343");
  1997. if (!bIsPalDefault())
  1998. {
  1999. // Well it's a new live hpal. Add the DC to it's linked list
  2000. // and inc it's cRef count.
  2001. vInc_cRef();
  2002. dco.pdc->hdcNext(hdcHead());
  2003. hdcHead(dco.hdc());
  2004. dco.pdc->hdcPrev((HDC) 0);
  2005. if (dco.pdc->hdcNext() != (HDC) 0)
  2006. {
  2007. MDCOBJA dcoNext(dco.pdc->hdcNext());
  2008. dcoNext.pdc->hdcPrev(dco.hdc());
  2009. }
  2010. }
  2011. else
  2012. {
  2013. dco.pdc->hdcNext((HDC) 0);
  2014. dco.pdc->hdcPrev((HDC) 0);
  2015. }
  2016. }
  2017. /******************************Public*Routine******************************\
  2018. * vRemoveFromList
  2019. *
  2020. * Remove DC from linked list of DC's. MLOCKOBJ must be grabbed before call.
  2021. *
  2022. * History:
  2023. * 16-Dec-1992 -by- Patrick Haluptzok patrickh
  2024. * Wrote it.
  2025. \**************************************************************************/
  2026. VOID XEPALOBJ::vRemoveFromList(XDCOBJ& dco)
  2027. {
  2028. ASSERTGDI(dco.bLocked(), "ERROR 1");
  2029. ASSERTGDI(bIsPalDC(), "ERROR 2");
  2030. // Take care of the old hpal. Remove from linked list. Decrement cRef.
  2031. // Remove the hdc from the linked list of DC's associated with palette.
  2032. if (!bIsPalDefault())
  2033. {
  2034. // Remove this DC from the linked list.
  2035. if (dco.pdc->hdcNext() != (HDC) 0)
  2036. {
  2037. MDCOBJA dcoNext(dco.pdc->hdcNext());
  2038. dcoNext.pdc->hdcPrev(dco.pdc->hdcPrev());
  2039. }
  2040. if (dco.pdc->hdcPrev() == (HDC) 0)
  2041. {
  2042. // New head of hdc list for hpal
  2043. hdcHead(dco.pdc->hdcNext());
  2044. }
  2045. else
  2046. {
  2047. MDCOBJA dcoPrev(dco.pdc->hdcPrev());
  2048. dcoPrev.pdc->hdcNext(dco.pdc->hdcNext());
  2049. }
  2050. // Decrement the reference count correctly.
  2051. vDec_cRef();
  2052. }
  2053. dco.pdc->hdcPrev((HDC) 0);
  2054. dco.pdc->hdcNext((HDC) 0);
  2055. }
  2056. /******************************Public*Routine******************************\
  2057. * vFill_triples
  2058. *
  2059. * For GetDIBits we need to copy a palette out to triples.
  2060. *
  2061. * History:
  2062. * 08-May-1991 -by- Patrick Haluptzok patrickh
  2063. * Wrote it.
  2064. \**************************************************************************/
  2065. VOID XEPALOBJ::vFill_triples(
  2066. RGBTRIPLE *prgb, // array of quads to fill
  2067. ULONG iStart, // first index in palette to copy out
  2068. ULONG cEntry) // max # of entries to copy out
  2069. {
  2070. PALETTEENTRY palentry;
  2071. RGBTRIPLE rgbtrip;
  2072. cEntry = MIN((iStart + cEntry), cEntries());
  2073. ASSERTGDI(cEntries() != 0, "ERROR cEntries");
  2074. ASSERTGDI(!bIsBitfields(), "ERROR bIsBitfields");
  2075. ASSERTGDI(!bIsRGB(), "ERROR bIsRGB");
  2076. ASSERTGDI(!bIsBGR(), "ERROR bIsBGR");
  2077. while (iStart < cEntry)
  2078. {
  2079. palentry = palentryGet(iStart);
  2080. rgbtrip.rgbtRed = palentry.peRed;
  2081. rgbtrip.rgbtBlue = palentry.peBlue;
  2082. rgbtrip.rgbtGreen = palentry.peGreen;
  2083. *prgb++ = rgbtrip;
  2084. iStart++;
  2085. }
  2086. }
  2087. /******************************Public*Routine******************************\
  2088. * vFill_rgbquads
  2089. *
  2090. * For GetDIBits we need to copy a palette out to rgbquads
  2091. *
  2092. * History:
  2093. * 08-May-1991 -by- Patrick Haluptzok patrickh
  2094. * Wrote it.
  2095. \**************************************************************************/
  2096. VOID XEPALOBJ::vFill_rgbquads(
  2097. RGBQUAD *prgb, // array of quads to fill
  2098. ULONG iStart, // first index in palette to copy out
  2099. ULONG cEntry) // max # of entries to copy out
  2100. {
  2101. if (bIsBGR())
  2102. {
  2103. ((PDWORD) prgb)[0] = 0x00FF0000;
  2104. ((PDWORD) prgb)[1] = 0x0000FF00;
  2105. ((PDWORD) prgb)[2] = 0x000000FF;
  2106. }
  2107. else if (bIsBitfields() && cEntry == 3)
  2108. {
  2109. ((PDWORD) prgb)[0] = flRed();
  2110. ((PDWORD) prgb)[1] = flGre();
  2111. ((PDWORD) prgb)[2] = flBlu();
  2112. }
  2113. else if (bIsRGB())
  2114. {
  2115. ((PDWORD) prgb)[0] = 0x000000FF;
  2116. ((PDWORD) prgb)[1] = 0x0000FF00;
  2117. ((PDWORD) prgb)[2] = 0x00FF0000;
  2118. }
  2119. else
  2120. {
  2121. PALETTEENTRY palentry;
  2122. RGBQUAD rgbquad;
  2123. cEntry = MIN((iStart + cEntry), cEntries());
  2124. while (iStart < cEntry)
  2125. {
  2126. palentry = palentryGet(iStart);
  2127. rgbquad.rgbRed = palentry.peRed;
  2128. rgbquad.rgbBlue = palentry.peBlue;
  2129. rgbquad.rgbGreen = palentry.peGreen;
  2130. rgbquad.rgbReserved = 0;
  2131. *prgb++ = rgbquad;
  2132. iStart++;
  2133. }
  2134. }
  2135. }
  2136. /******************************Public*Routine******************************\
  2137. * vGetEntriesFrom
  2138. *
  2139. * This is for the DIB_PAL_COLORS case of CreateDIBitmap.
  2140. * This uses the array of ushorts in bmiColors and the DC palette to
  2141. * initialize the surface palette. You need to create a palette that
  2142. * represents the essence of a DC palette. That means if DC palette
  2143. * has a PC_EXPLICIT in it, reach down into the surface palette for the
  2144. * palette entry.
  2145. *
  2146. * History:
  2147. * Thu 03-Feb-1994 -by- Patrick Haluptzok [patrickh]
  2148. * Chicago compatability, grab the colors out of the VGA palette if the
  2149. * system palette is not available.
  2150. *
  2151. * 09-May-1991 -by- Patrick Haluptzok patrickh
  2152. * Wrote it.
  2153. \**************************************************************************/
  2154. VOID XEPALOBJ::vGetEntriesFrom(XEPALOBJ palDC, XEPALOBJ palSurf, PUSHORT pusIndices, ULONG cEntry)
  2155. {
  2156. //
  2157. // We assume if the palette was invalid (which indicates it was a compatible
  2158. // bitmap on a palette managed device) then the caller has passed the
  2159. // PDEV surface palette instead which is valid.
  2160. //
  2161. ASSERTGDI(palDC.bValid(), "ERROR palDC not valid");
  2162. ASSERTGDI(palSurf.bValid(), "ERROR palSurf not valid");
  2163. ASSERTGDI(palDC.cEntries() != 0, "ERROR 0 entry palDC");
  2164. ASSERTGDI(cEntry <= cEntries(), "ERROR bGetEntriesFrom cEntry too big");
  2165. PAL_ULONG palentry;
  2166. ULONG cEntryDC;
  2167. ULONG cEntrySurf;
  2168. cEntryDC = palDC.cEntries();
  2169. //
  2170. // We need the PDEV palette for the screen if this is a compatible
  2171. // bitmap on a palette managed device which is indicated by have a
  2172. // NULL ppalSurf.
  2173. //
  2174. cEntrySurf = palSurf.bIsPalManaged() ? palSurf.cEntries() : 0;
  2175. while (cEntry--)
  2176. {
  2177. palentry.ul = (ULONG) pusIndices[cEntry];
  2178. if (palentry.ul >= cEntryDC)
  2179. palentry.ul = palentry.ul % cEntryDC;
  2180. palentry.pal = palDC.palentryGet(palentry.ul);
  2181. if (palentry.pal.peFlags == PC_EXPLICIT)
  2182. {
  2183. if (cEntrySurf)
  2184. {
  2185. // Grab the RGB out of the system palette.
  2186. palentry.ul = palentry.ul & 0x0000FFFF;
  2187. if (palentry.ul >= cEntrySurf)
  2188. palentry.ul = palentry.ul % cEntrySurf;
  2189. palentry.pal = palSurf.palentryGet(palentry.ul);
  2190. }
  2191. else
  2192. {
  2193. // Get color entries from the VGA palette. This
  2194. // is Chicago compatible.
  2195. palentry.ul = palentry.ul & 0x0000F;
  2196. palentry.pal = apalVGA[palentry.ul];
  2197. }
  2198. }
  2199. //
  2200. // Always 0 out the flags.
  2201. //
  2202. palentry.pal.peFlags = 0;
  2203. palentrySet(cEntry, palentry.pal);
  2204. }
  2205. }
  2206. /******************************Public*Routine******************************\
  2207. * XEPALOBJ::vInitMono
  2208. *
  2209. * This initializes a monochrome palette.
  2210. *
  2211. * History:
  2212. * 24-Jun-1991 -by- Patrick Haluptzok patrickh
  2213. * Wrote it.
  2214. \**************************************************************************/
  2215. VOID XEPALOBJ::vInitMono()
  2216. {
  2217. PAL_ULONG palentry;
  2218. palentry.ul = 0;
  2219. palentrySet(0, palentry.pal);
  2220. palentry.ul = 0x00FFFFFF;
  2221. palentrySet(1, palentry.pal);
  2222. }
  2223. /******************************Public*Routine******************************\
  2224. * XEPALOBJ::vInitVGA
  2225. *
  2226. * This initializes a 16 color palette to be just like the VGA.
  2227. *
  2228. * History:
  2229. * Wed 02-Oct-1991 -by- Patrick Haluptzok [patrickh]
  2230. * Re-did to be Win3.0 compatible.
  2231. *
  2232. * 22-Jun-1991 -by- Patrick Haluptzok patrickh
  2233. * Wrote it.
  2234. \**************************************************************************/
  2235. VOID XEPALOBJ::vInitVGA()
  2236. {
  2237. ULONG ulIndex;
  2238. for (ulIndex = 0; ulIndex < 16; ulIndex++)
  2239. {
  2240. palentrySet(ulIndex, aPalVGA[ulIndex].pal);
  2241. }
  2242. }
  2243. /******************************Public*Routine******************************\
  2244. * XEPALOBJ::vInit256Rainbow
  2245. *
  2246. * This initializes a 256 color palette with the default colors at the ends
  2247. * and a rainbow in the middle.
  2248. *
  2249. * History:
  2250. * 22-Jun-1991 -by- Patrick Haluptzok patrickh
  2251. * Wrote it.
  2252. \**************************************************************************/
  2253. VOID XEPALOBJ::vInit256Rainbow()
  2254. {
  2255. ULONG ulIndex;
  2256. PAL_ULONG palentry;
  2257. PBYTE gTmp;
  2258. // Generate 256 (= 8*8*4) RGB combinations to fill
  2259. // in the palette.
  2260. BYTE red, green, blue;
  2261. red = green = blue = 0;
  2262. for (ulIndex = 0; ulIndex < 256; ulIndex++)
  2263. {
  2264. palentry.pal.peRed = red;
  2265. palentry.pal.peGreen = green;
  2266. palentry.pal.peBlue = blue;
  2267. palentry.pal.peFlags = 0;
  2268. palentrySet(ulIndex, palentry.pal);
  2269. if (!(red += 32))
  2270. if (!(green += 32))
  2271. blue += 64;
  2272. }
  2273. vInit256Default();
  2274. if (gpRGBXlate == NULL)
  2275. {
  2276. gTmp = (PBYTE)PALLOCNOZ(32768,'bgrG');
  2277. if (gTmp)
  2278. {
  2279. //
  2280. // use InterlockedCompareExchangePointer to set
  2281. // gpRGBXlate, so that another thread won't
  2282. // try to do this at the same time
  2283. //
  2284. MakeITable(gTmp,(RGBX *)ppal->apalColor,256);
  2285. if (InterlockedCompareExchangePointer((PVOID *)&gpRGBXlate,
  2286. gTmp,
  2287. NULL) != NULL)
  2288. {
  2289. //
  2290. // if we failed the InterlockedCompareExchangePointer,
  2291. // it means gpRGBXlate is already set by another thread
  2292. // free the temp buffer here
  2293. //
  2294. if (gTmp)
  2295. {
  2296. VFREEMEM(gTmp);
  2297. }
  2298. }
  2299. }
  2300. else
  2301. {
  2302. WARNING("Failed to allocate memory in XEPALOBJ::vInit256Rainbow\n");
  2303. // set this to NULL to be safe
  2304. ppal->pRGBXlate = NULL;
  2305. return;
  2306. }
  2307. }
  2308. ppal->ulRGBTime = ulTime();
  2309. ASSERTGDI(gpRGBXlate, "gpRGBXlate == NULL!\n");
  2310. ppal->pRGBXlate = gpRGBXlate;
  2311. }
  2312. /******************************Public*Routine******************************\
  2313. * XEPALOBJ::vInit256Default
  2314. *
  2315. * Initialize 256 color palette with the default colors.
  2316. *
  2317. * History:
  2318. * 02-Mar-1993 -by- Patrick Haluptzok patrickh
  2319. * Wrote it.
  2320. \**************************************************************************/
  2321. VOID XEPALOBJ::vInit256Default()
  2322. {
  2323. // Fill in 20 reserved colors at beginning and end.
  2324. UINT uiIndex;
  2325. for (uiIndex = 0; uiIndex < 10; uiIndex++)
  2326. {
  2327. palentrySet(uiIndex, logDefaultPal.palPalEntry[uiIndex]);
  2328. palentrySet((ULONG)(255 - uiIndex), logDefaultPal.palPalEntry[19 - uiIndex]);
  2329. }
  2330. }
  2331. /**************************************************************************\
  2332. * XEPALOBJ::pGetRGBXlate
  2333. *
  2334. *
  2335. * Arguments:
  2336. *
  2337. *
  2338. *
  2339. * Return Value:
  2340. *
  2341. *
  2342. *
  2343. * History:
  2344. *
  2345. * 2/19/1997 Mark Enstrom [marke]
  2346. *
  2347. \**************************************************************************/
  2348. PRGB555XLATE
  2349. XEPALOBJ::pGetRGBXlate()
  2350. {
  2351. //
  2352. // palette semaphore?
  2353. //
  2354. PRGB555XLATE prgb555 = NULL;
  2355. if (ppal != NULL)
  2356. {
  2357. prgb555 = ppal->pRGBXlate;
  2358. if (
  2359. (prgb555 == NULL) ||
  2360. (ppal->ulRGBTime != ulTime())
  2361. )
  2362. {
  2363. if (bGenColorXlate555())
  2364. {
  2365. prgb555 = ppal->pRGBXlate;
  2366. }
  2367. else
  2368. {
  2369. prgb555 = NULL;
  2370. }
  2371. }
  2372. }
  2373. else
  2374. {
  2375. WARNING("XEPALOBJ::pGetRGBXlate called with NULL ppal\n");
  2376. }
  2377. return(prgb555);
  2378. }
  2379. /**************************************************************************\
  2380. * XEPALOBJ::bGenColorXlate555
  2381. *
  2382. *
  2383. * Arguments:
  2384. *
  2385. *
  2386. *
  2387. * Return Value:
  2388. *
  2389. *
  2390. *
  2391. * History:
  2392. *
  2393. * 2/12/1997 Mark Enstrom [marke]
  2394. *
  2395. \**************************************************************************/
  2396. BOOL
  2397. XEPALOBJ::bGenColorXlate555()
  2398. {
  2399. BOOL bRet = FALSE;
  2400. //
  2401. // allocate rgb555 xlate table if needed
  2402. //
  2403. if ((ppal->pRGBXlate == NULL) || (ppal->pRGBXlate == gpRGBXlate))
  2404. {
  2405. ppal->pRGBXlate = (PRGB555XLATE)PALLOCNOZ(32768,'bgrG');
  2406. }
  2407. if (ppal->pRGBXlate)
  2408. {
  2409. MakeITable((PIMAP)ppal->pRGBXlate,(RGBX *)apalColorGet(),cEntries());
  2410. bRet = TRUE;
  2411. ppal->ulRGBTime = ulTime();
  2412. }
  2413. return(bRet);
  2414. }
  2415. /******************************Public*Routine******************************\
  2416. * ColorMatch
  2417. *
  2418. * Direct from Win3.1 to you. This function returns the best index to use
  2419. * when realizing a palette. It also returns the error incurred with using
  2420. * that index.
  2421. *
  2422. * Converted from Win3.1 colormat.asm - the ColorMatch function
  2423. *
  2424. * The only difference is we return a 32-bit error difference, and a 32-bit
  2425. * index. They compress both into 16-bit ax,dx.
  2426. *
  2427. * History:
  2428. * 11-May-1993 -by- Patrick Haluptzok patrickh
  2429. * Wrote it.
  2430. \**************************************************************************/
  2431. ULONG ColorMatch(XEPALOBJ palSurf, PAL_ULONG palRGB, ULONG *pulError)
  2432. {
  2433. if (palRGB.pal.peFlags & PC_EXPLICIT)
  2434. {
  2435. // Return the low word index.
  2436. palRGB.ul &= 0x0000FFFF;
  2437. // This is an error case Win3.1 does not test for, but we do.
  2438. if (palRGB.ul >= palSurf.cEntries())
  2439. {
  2440. palRGB.ul = 0;
  2441. }
  2442. *pulError = 0;
  2443. return(palRGB.ul);
  2444. }
  2445. if (palRGB.pal.peFlags & PC_RESERVED)
  2446. {
  2447. *pulError = 0x0FFFFFFF;
  2448. return(0);
  2449. }
  2450. ULONG ulTemp, ulError, ulBestIndex, ulBestError;
  2451. PAL_ULONG palTemp;
  2452. ulBestIndex = 0;
  2453. ulBestError = 0x0FFFFFFF;
  2454. for (ulTemp = 0; ulTemp < palSurf.cEntries(); ulTemp++)
  2455. {
  2456. palTemp.ul = palSurf.ulEntryGet(ulTemp);
  2457. if (palTemp.pal.peFlags & PC_USED)
  2458. {
  2459. if (!(palTemp.pal.peFlags & PC_RESERVED))
  2460. {
  2461. ulError = RGB_ERROR(palTemp.pal, palRGB.pal);
  2462. if (ulError < ulBestError)
  2463. {
  2464. ulBestIndex = ulTemp;
  2465. ulBestError = ulError;
  2466. }
  2467. if (ulBestError == 0)
  2468. break;
  2469. }
  2470. }
  2471. }
  2472. if (palRGB.pal.peFlags & PC_NOCOLLAPSE)
  2473. {
  2474. // He doesn't really want to match, so give it a big error.
  2475. *pulError = 0x0FFFFFFF;
  2476. }
  2477. else
  2478. *pulError = ulBestError;
  2479. return(ulBestIndex);
  2480. }
  2481. /******************************Public*Routine******************************\
  2482. * ptransMatchAPal
  2483. *
  2484. * Direct from Win3.1 to you. Builds a foreground translate just like Windows
  2485. * does.
  2486. *
  2487. * History:
  2488. * 12-May-1993 -by- Patrick Haluptzok patrickh
  2489. * Wrote it.
  2490. \**************************************************************************/
  2491. PTRANSLATE
  2492. ptransMatchAPal(
  2493. PDC pdc,
  2494. XEPALOBJ palSurf,
  2495. XEPALOBJ palDC,
  2496. BOOL bForeground,
  2497. ULONG *pulnPhysChanged,
  2498. ULONG *pulnTransChanged
  2499. )
  2500. {
  2501. ASSERTGDI(palDC.bValid(), "ERROR invalid DC pal");
  2502. ASSERTGDI(palSurf.bValid(), "ERROR invalid Surface pal");
  2503. ASSERTGDI(!palDC.bIsPalDefault(), "ERROR ptransMapIn default palette");
  2504. ASSERTGDI(palSurf.cEntries() == 256, "Error: dinky palette in");
  2505. ASSERTGDI(palDC.bIsPalDC(), "Error: palDC is not a DC");
  2506. ASSERTGDI(*pulnPhysChanged == 0, "ERROR 1349456 ptransMapIn");
  2507. ASSERTGDI(*pulnTransChanged == 0, "ERROR not 0");
  2508. //
  2509. // Determine how many entries are reserved
  2510. //
  2511. ULONG ulReserved;
  2512. if (palSurf.bIsNoStatic())
  2513. {
  2514. ulReserved = 1;
  2515. }
  2516. else if (palSurf.bIsNoStatic256())
  2517. {
  2518. ulReserved = 0;
  2519. }
  2520. else
  2521. {
  2522. ulReserved = palSurf.ulNumReserved() >> 1;
  2523. }
  2524. ULONG ulStartFill = ulReserved;
  2525. ULONG ulMaxInsert = 256 - ulReserved;
  2526. PAL_ULONG palLog, palPhys;
  2527. ULONG ulTemp;
  2528. ULONG iInsertIndex, iLogPal;
  2529. ULONG nPhysChanged = 0;
  2530. ULONG nTransChanged = 0;
  2531. //
  2532. // We allocate the vector that converts logical palette indices to physical
  2533. // palette indices. Note we subtract out the extra ULONG at compile time
  2534. // rather than run-time.
  2535. //
  2536. PTRANSLATE pTrans = (PTRANSLATE)
  2537. PALLOCNOZ((sizeof(TRANSLATE) - sizeof(BYTE)) +
  2538. (palDC.cEntries() * sizeof(BYTE)), 'laPG');
  2539. if (pTrans == NULL)
  2540. {
  2541. WARNING("Allocation for pTransMapIn failed\n");
  2542. return(NULL);
  2543. }
  2544. nTransChanged = palDC.cEntries();
  2545. if (bForeground)
  2546. {
  2547. //
  2548. // This is a foreground realize. Clear all PC_FOREGROUND and PC_RESERVED
  2549. // flags in the non-reserved entries of the surface palette.
  2550. //
  2551. //
  2552. // Update the time because we are removing foreground entries.
  2553. //
  2554. palSurf.vUpdateTime();
  2555. //
  2556. // match_fore_pal:
  2557. //
  2558. for (ulTemp = ulReserved; ulTemp < ulMaxInsert; ulTemp++)
  2559. {
  2560. palPhys.ul = palSurf.ulEntryGet(ulTemp);
  2561. // WINBUG #2621 5-4-2000 bhouse Foreground realization does not match Win9X
  2562. // We now clear PC_USED thus allowing us to match Win9X palette realization
  2563. // behavior. Note, we really should not clear PC_USED if we are in a WOW
  2564. // thread but have decided it is not necessary to maintain WOW compat.
  2565. palPhys.pal.peFlags &= (~(PC_FOREGROUND | PC_RESERVED | PC_USED));
  2566. palSurf.ulEntrySet(ulTemp, palPhys.ul);
  2567. }
  2568. }
  2569. BYTE fNotOverwritable = PC_FOREGROUND | PC_USED;
  2570. //
  2571. // match_back_loop:
  2572. //
  2573. for (iLogPal = 0; iLogPal < palDC.cEntries(); iLogPal++)
  2574. {
  2575. palLog.ul = palDC.ulEntryGet(iLogPal);
  2576. iInsertIndex = ColorMatch(palSurf, palLog, &ulTemp);
  2577. if (ulTemp == 0)
  2578. {
  2579. //
  2580. // Awesome, nothing to change.
  2581. //
  2582. if (!(palLog.pal.peFlags & PC_EXPLICIT))
  2583. {
  2584. //
  2585. // Mark it used if not PC_EXPLICIT log pal entry.
  2586. //
  2587. palPhys.ul = palSurf.ulEntryGet(iInsertIndex);
  2588. palPhys.pal.peFlags |= (PC_USED | PC_FOREGROUND);
  2589. palSurf.ulEntrySet(iInsertIndex, palPhys.ul);
  2590. }
  2591. }
  2592. else
  2593. {
  2594. //
  2595. // imperfect_match:
  2596. //
  2597. if (ulStartFill || palSurf.bIsNoStatic256())
  2598. {
  2599. //
  2600. // There is room to jam in an entry.
  2601. //
  2602. // look_for_overwrite:
  2603. //
  2604. look_for_overwriteable_loop:
  2605. for (ulTemp = ulStartFill; ulTemp < ulMaxInsert; ulTemp++)
  2606. {
  2607. palPhys.ul = palSurf.ulEntryGet(ulTemp);
  2608. if (!(palPhys.pal.peFlags & fNotOverwritable))
  2609. {
  2610. //
  2611. // replace_opening:
  2612. //
  2613. iInsertIndex = ulStartFill = ulTemp; // New start point for search.
  2614. palLog.pal.peFlags |= (PC_USED | PC_FOREGROUND);
  2615. palSurf.ulEntrySet(ulTemp, palLog.ul);
  2616. nPhysChanged++;
  2617. goto entry_back_matched;
  2618. }
  2619. }
  2620. if (fNotOverwritable & PC_USED)
  2621. {
  2622. //
  2623. // Can't be so picky, kick out used entries.
  2624. //
  2625. fNotOverwritable &= (~PC_USED);
  2626. ulStartFill = ulReserved;
  2627. goto look_for_overwriteable_loop;
  2628. }
  2629. else
  2630. {
  2631. //
  2632. // all_filled_for_back:
  2633. //
  2634. ulStartFill = 0;
  2635. }
  2636. }
  2637. }
  2638. entry_back_matched:
  2639. pTrans->ajVector[iLogPal] = (BYTE) iInsertIndex;
  2640. }
  2641. //
  2642. // finished_back_match
  2643. //
  2644. palDC.vUpdateTime();
  2645. pTrans->iUniq = palSurf.ulTime();
  2646. *pulnPhysChanged = nPhysChanged;
  2647. *pulnTransChanged = nTransChanged;
  2648. return(pTrans);
  2649. }
  2650. /******************************Public*Routine******************************\
  2651. * vMatchAPal
  2652. *
  2653. * This maps the foreground realization into the palette.
  2654. *
  2655. * History:
  2656. * 23-Nov-1992 -by- Patrick Haluptzok patrickh
  2657. * Wrote it.
  2658. \**************************************************************************/
  2659. VOID
  2660. vMatchAPal(
  2661. PDC pdc,
  2662. XEPALOBJ palSurf,
  2663. XEPALOBJ palDC,
  2664. ULONG *pulnPhysChanged,
  2665. ULONG *pulnTransChanged
  2666. )
  2667. {
  2668. ASSERTGDI(palDC.bValid(), "ERROR invalid DC pal");
  2669. ASSERTGDI(palSurf.bValid(), "ERROR invalid Surface pal");
  2670. ASSERTGDI(!palDC.bIsPalDefault(), "ERROR ptransMapIn default palette");
  2671. ASSERTGDI(palSurf.cEntries() == 256, "Error: dinky palette in");
  2672. ASSERTGDI(palDC.bIsPalDC(), "Error: palDC is not a DC");
  2673. ASSERTGDI(*pulnPhysChanged == 0, "ERROR 1349456 ptransMapIn");
  2674. ASSERTGDI(*pulnTransChanged == 0, "ERROR not 0");
  2675. //
  2676. // Determine how many entries are reserved
  2677. //
  2678. ULONG ulReserved;
  2679. if (palSurf.bIsNoStatic())
  2680. {
  2681. ulReserved = 1;
  2682. }
  2683. else if (palSurf.bIsNoStatic256())
  2684. {
  2685. ulReserved = 0;
  2686. }
  2687. else
  2688. {
  2689. ulReserved = palSurf.ulNumReserved() >> 1;
  2690. }
  2691. ULONG ulMaxInsert = 256 - ulReserved;
  2692. PAL_ULONG palLog, palPhys;
  2693. ULONG iLogPal;
  2694. ULONG nPhysChanged = 0;
  2695. ULONG nTransChanged = 0;
  2696. PTRANSLATE pTransFore = palDC.ptransFore();
  2697. PTRANSLATE pTransCur = palDC.ptransCurrent();
  2698. ASSERTGDI(pTransFore != NULL, "ERROR this NULL");
  2699. //
  2700. // un_use_palette_loop: Remove all foreground and reserved flags.
  2701. //
  2702. for (iLogPal = ulReserved; iLogPal < ulMaxInsert; iLogPal++)
  2703. {
  2704. palPhys.ul = palSurf.ulEntryGet(iLogPal);
  2705. palPhys.pal.peFlags &= (~(PC_FOREGROUND | PC_RESERVED));
  2706. palSurf.ulEntrySet(iLogPal, palPhys.ul);
  2707. }
  2708. for (iLogPal = 0; iLogPal < palDC.cEntries(); iLogPal++)
  2709. {
  2710. //
  2711. // slam_foreground_palette_loop
  2712. //
  2713. if ((pTransCur == NULL) ||
  2714. (pTransCur->ajVector[iLogPal] != pTransFore->ajVector[iLogPal]))
  2715. {
  2716. nTransChanged++;
  2717. }
  2718. //
  2719. // fore_no_trans_change:
  2720. //
  2721. palPhys.ul = palSurf.ulEntryGet(pTransFore->ajVector[iLogPal]);
  2722. if (!(palPhys.pal.peFlags & PC_FOREGROUND))
  2723. {
  2724. //
  2725. // Index is not foreground, we have to at least mark it.
  2726. //
  2727. palLog.ul = palDC.ulEntryGet(iLogPal);
  2728. if (!(palLog.pal.peFlags & PC_EXPLICIT))
  2729. {
  2730. //
  2731. // Not explicit, we better make sure it's the same entry.
  2732. //
  2733. if ((palLog.pal.peRed != palPhys.pal.peRed) ||
  2734. (palLog.pal.peGreen != palPhys.pal.peGreen) ||
  2735. (palLog.pal.peBlue != palPhys.pal.peBlue) ||
  2736. ((palLog.pal.peFlags & PC_RESERVED) != (palPhys.pal.peFlags & PC_RESERVED)))
  2737. {
  2738. //
  2739. // Not the same as logical palette, stick it in the palette.
  2740. //
  2741. palLog.pal.peFlags &= PC_RESERVED;
  2742. palPhys.ul = palLog.ul;
  2743. nPhysChanged++;
  2744. }
  2745. }
  2746. //
  2747. // fore_entry_slammed
  2748. //
  2749. palPhys.pal.peFlags |= (PC_FOREGROUND | PC_USED);
  2750. palSurf.ulEntrySet((ULONG) pTransFore->ajVector[iLogPal], palPhys.ul);
  2751. }
  2752. }
  2753. //
  2754. // Increment the palette's time, we changed removed the foreground flags.
  2755. //
  2756. palSurf.vUpdateTime();
  2757. palDC.vUpdateTime();
  2758. pTransFore->iUniq = palSurf.ulTime();
  2759. *pulnPhysChanged = nPhysChanged;
  2760. *pulnTransChanged = nTransChanged;
  2761. }