4ae9d9902b4a484929d6f64f6019bbdfd88cfc24
2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 static int PALETTE_firstFree
= 0;
28 static unsigned char PALETTE_freeList
[256];
31 int PALETTE_PaletteFlags
= 0;
32 PALETTEENTRY
*COLOR_sysPal
= NULL
;
38 PPALETTEENTRY FASTCALL
ReturnSystemPalette (VOID
)
44 PALETTE_Cleanup(PVOID ObjectBody
)
46 PPALGDI pPal
= (PPALGDI
)ObjectBody
;
47 if (NULL
!= pPal
->IndexedColors
)
49 ExFreePool(pPal
->IndexedColors
);
56 PALETTE_AllocPalette(ULONG Mode
,
66 NewPalette
= (HPALETTE
) GDIOBJ_AllocObj(GDI_OBJECT_TYPE_PALETTE
);
67 if (NULL
== NewPalette
)
72 PalGDI
= PALETTE_LockPalette(NewPalette
);
73 /* FIXME - PalGDI can be NULL!!! Don't assert here! */
76 PalGDI
->Self
= NewPalette
;
81 PalGDI
->IndexedColors
= ExAllocatePoolWithTag(PagedPool
, sizeof(PALETTEENTRY
) * NumColors
, TAG_PALETTE
);
82 if (NULL
== PalGDI
->IndexedColors
)
84 PALETTE_UnlockPalette(PalGDI
);
85 PALETTE_FreePalette(NewPalette
);
88 RtlCopyMemory(PalGDI
->IndexedColors
, Colors
, sizeof(PALETTEENTRY
) * NumColors
);
91 if (PAL_INDEXED
== Mode
)
93 PalGDI
->NumColors
= NumColors
;
95 else if (PAL_BITFIELDS
== Mode
)
97 PalGDI
->RedMask
= Red
;
98 PalGDI
->GreenMask
= Green
;
99 PalGDI
->BlueMask
= Blue
;
102 PALETTE_UnlockPalette(PalGDI
);
108 PALETTE_AllocPaletteIndexedRGB(ULONG NumColors
,
109 CONST RGBQUAD
*Colors
)
115 NewPalette
= (HPALETTE
) GDIOBJ_AllocObj(GDI_OBJECT_TYPE_PALETTE
);
116 if (NULL
== NewPalette
)
121 PalGDI
= PALETTE_LockPalette(NewPalette
);
122 /* FIXME - PalGDI can be NULL!!! Don't assert here! */
125 PalGDI
->Self
= NewPalette
;
126 PalGDI
->Mode
= PAL_INDEXED
;
128 PalGDI
->IndexedColors
= ExAllocatePoolWithTag(PagedPool
, sizeof(PALETTEENTRY
) * NumColors
, TAG_PALETTE
);
129 if (NULL
== PalGDI
->IndexedColors
)
131 PALETTE_UnlockPalette(PalGDI
);
132 PALETTE_FreePalette(NewPalette
);
135 for (i
= 0; i
< NumColors
; i
++)
137 PalGDI
->IndexedColors
[i
].peRed
= Colors
[i
].rgbRed
;
138 PalGDI
->IndexedColors
[i
].peGreen
= Colors
[i
].rgbGreen
;
139 PalGDI
->IndexedColors
[i
].peBlue
= Colors
[i
].rgbBlue
;
140 PalGDI
->IndexedColors
[i
].peFlags
= 0;
143 PalGDI
->NumColors
= NumColors
;
145 PALETTE_UnlockPalette(PalGDI
);
150 // Create the system palette
151 HPALETTE FASTCALL
PALETTE_Init(VOID
)
159 const PALETTEENTRY
* __sysPalTemplate
= (const PALETTEENTRY
*)COLOR_GetSystemPaletteTemplate();
161 // create default palette (20 system colors)
162 palPtr
= ExAllocatePoolWithTag(PagedPool
, sizeof(LOGPALETTE
) + (NB_RESERVED_COLORS
* sizeof(PALETTEENTRY
)), TAG_PALETTE
);
163 if (!palPtr
) return FALSE
;
165 palPtr
->palVersion
= 0x300;
166 palPtr
->palNumEntries
= NB_RESERVED_COLORS
;
167 for(i
=0; i
<NB_RESERVED_COLORS
; i
++)
169 palPtr
->palPalEntry
[i
].peRed
= __sysPalTemplate
[i
].peRed
;
170 palPtr
->palPalEntry
[i
].peGreen
= __sysPalTemplate
[i
].peGreen
;
171 palPtr
->palPalEntry
[i
].peBlue
= __sysPalTemplate
[i
].peBlue
;
172 palPtr
->palPalEntry
[i
].peFlags
= 0;
175 hpalette
= NtGdiCreatePalette(palPtr
);
179 palObj
= (PALOBJ
*)PALETTE_LockPalette(hpalette
);
182 if (!(palObj
->mapping
= ExAllocatePool(PagedPool
, sizeof(int) * 20)))
184 DbgPrint("Win32k: Can not create palette mapping -- out of memory!");
187 PALETTE_UnlockPalette(palObj
);
191 /* palette_size = visual->map_entries; */
197 static void FASTCALL
PALETTE_FormatSystemPalette(void)
199 // Build free list so we'd have an easy way to find
200 // out if there are any available colorcells.
202 int i
, j
= PALETTE_firstFree
= NB_RESERVED_COLORS
/2;
204 COLOR_sysPal
[j
].peFlags
= 0;
205 for(i
= (NB_RESERVED_COLORS
>>1) + 1 ; i
< 256 - (NB_RESERVED_COLORS
>>1) ; i
++)
207 if( i
< COLOR_gapStart
|| i
> COLOR_gapEnd
)
209 COLOR_sysPal
[i
].peFlags
= 0; // unused tag
210 PALETTE_freeList
[j
] = i
; // next
214 PALETTE_freeList
[j
] = 0;
218 VOID FASTCALL
PALETTE_ValidateFlags(PALETTEENTRY
* lpPalE
, INT size
)
221 for( ; i
<size
; i
++ )
222 lpPalE
[i
].peFlags
= PC_SYS_USED
| (lpPalE
[i
].peFlags
& 0x07);
226 // Set the color-mapping table for selected palette.
227 // Return number of entries which mapping has changed.
228 INT STDCALL
PALETTE_SetMapping(PALOBJ
*palPtr
, UINT uStart
, UINT uNum
, BOOL mapOnly
)
231 int prevMapping
= (palPtr
->mapping
) ? 1 : 0;
232 int index
, iRemapped
= 0;
234 HPALETTE hSysPal
= NtGdiGetStockObject(DEFAULT_PALETTE
);
235 PPALGDI pSysPal
= PALETTE_LockPalette(hSysPal
);
236 PPALGDI palGDI
= (PPALGDI
) palPtr
;
237 /* FIXME - handle pSysPal == NULL!!!!!!! */
239 COLOR_sysPal
= pSysPal
->IndexedColors
;
240 PALETTE_UnlockPalette(pSysPal
); // FIXME: Is this a right way to obtain pointer to the system palette?
243 // reset dynamic system palette entries
245 if( !mapOnly
&& PALETTE_firstFree
!= -1) PALETTE_FormatSystemPalette();
247 // initialize palette mapping table
249 //mapping = HeapReAlloc( GetProcessHeap(), 0, palPtr->mapping,
250 // sizeof(int)*palPtr->logpalette->palNumEntries);
251 ExFreePool(palPtr
->mapping
);
252 mapping
= ExAllocatePoolWithTag(PagedPool
, sizeof(int)*palGDI
->NumColors
, TAG_PALETTEMAP
);
254 palPtr
->mapping
= mapping
;
256 for(uNum
+= uStart
; uStart
< uNum
; uStart
++)
261 switch( palGDI
->IndexedColors
[uStart
].peFlags
& 0x07 )
263 case PC_EXPLICIT
: // palette entries are indices into system palette
264 // The PC_EXPLICIT flag is used to copy an entry from the system palette into the logical palette
265 index
= *(WORD
*)(palGDI
->IndexedColors
+ uStart
);
266 if(index
> 255 || (index
>= COLOR_gapStart
&& index
<= COLOR_gapEnd
))
268 DbgPrint("Win32k: PC_EXPLICIT: idx %d out of system palette, assuming black.\n", index
);
273 case PC_RESERVED
: // forbid future mappings to this entry
274 // For palette animation, the entries in the logical palette need the PC_RESERVED flag
275 flag
|= PC_SYS_RESERVED
;
278 default: // try to collapse identical colors
279 index
= COLOR_PaletteLookupExactIndex(COLOR_sysPal
, 256,
280 *(COLORREF
*)(palGDI
->IndexedColors
+ uStart
));
284 // If an entry in the logical palette is marked with the PC_NOCOLLAPSE flag, the palette
285 // manager allocates a free entry in the system palette if one is available and only uses the
286 // closest colour match if there are no (more) free entries in the system palette
288 DbgPrint("Win32k: WARNING: PC_NOCOLLAPSE is not yet working properly\n");
292 if(PALETTE_firstFree
> 0 /* && !(PALETTE_PaletteFlags & PALETTE_FIXED) FIXME */ )
294 DbgPrint("Win32k: Unimplemented Palette Operation: PC_NOCOLLAPSE [objects/palette.c]\n");
296 index = PALETTE_firstFree; // ought to be available
297 PALETTE_firstFree = PALETTE_freeList[index];
299 color.pixel = (PALETTE_PaletteToXPixel) ? PALETTE_PaletteToXPixel[index] : index;
300 color.red = palPtr->logpalette->palPalEntry[uStart].peRed << 8;
301 color.green = palPtr->logpalette->palPalEntry[uStart].peGreen << 8;
302 color.blue = palPtr->logpalette->palPalEntry[uStart].peBlue << 8;
303 color.flags = DoRed | DoGreen | DoBlue;
304 TSXStoreColor(display, PALETTE_PaletteXColormap, &color);
306 COLOR_sysPal[index] = palPtr->logpalette->palPalEntry[uStart];
307 COLOR_sysPal[index].peFlags = flag;
308 PALETTE_freeList[index] = 0;
310 if(PALETTE_PaletteToXPixel) index = PALETTE_PaletteToXPixel[index]; */
313 /* else if (PALETTE_PaletteFlags & PALETTE_VIRTUAL)
315 index = PALETTE_ToPhysical(NULL, 0x00ffffff &
316 *(COLORREF*)(palPtr->logpalette->palPalEntry + uStart));
320 // we have to map to existing entry in the system palette
322 index
= COLOR_PaletteLookupPixel(COLOR_sysPal
, 256, NULL
,
323 *(COLORREF
*)(palGDI
->IndexedColors
+ uStart
), TRUE
);
325 palGDI
->IndexedColors
[uStart
].peFlags
|= PC_SYS_USED
;
327 /* if(PALETTE_PaletteToXPixel) index = PALETTE_PaletteToXPixel[index]; FIXME */
331 if( !prevMapping
|| palPtr
->mapping
[uStart
] != index
) iRemapped
++;
332 palPtr
->mapping
[uStart
] = index
;