c8cff990e2b0e9e1a5c22aaed4ee060e685c1cb9
[reactos.git] / reactos / win32ss / drivers / displays / framebuf_new / palette.c
1 /*
2 * PROJECT: ReactOS Framebuffer Display Driver
3 * LICENSE: Microsoft NT4 DDK Sample Code License
4 * FILE: boot/drivers/video/displays/framebuf/palette.c
5 * PURPOSE: Palette Support
6 * PROGRAMMERS: Copyright (c) 1992-1995 Microsoft Corporation
7 */
8
9 #include "driver.h"
10
11 // Global Table defining the 20 Window Default Colors. For 256 color
12 // palettes the first 10 must be put at the beginning of the palette
13 // and the last 10 at the end of the palette.
14
15 const PALETTEENTRY BASEPALETTE[20] =
16 {
17 { 0, 0, 0, 0 }, // 0
18 { 0x80,0, 0, 0 }, // 1
19 { 0, 0x80,0, 0 }, // 2
20 { 0x80,0x80,0, 0 }, // 3
21 { 0, 0, 0x80,0 }, // 4
22 { 0x80,0, 0x80,0 }, // 5
23 { 0, 0x80,0x80,0 }, // 6
24 { 0xC0,0xC0,0xC0,0 }, // 7
25 { 192, 220, 192, 0 }, // 8
26 { 166, 202, 240, 0 }, // 9
27 { 255, 251, 240, 0 }, // 10
28 { 160, 160, 164, 0 }, // 11
29 { 0x80,0x80,0x80,0 }, // 12
30 { 0xFF,0, 0 ,0 }, // 13
31 { 0, 0xFF,0 ,0 }, // 14
32 { 0xFF,0xFF,0 ,0 }, // 15
33 { 0 ,0, 0xFF,0 }, // 16
34 { 0xFF,0, 0xFF,0 }, // 17
35 { 0, 0xFF,0xFF,0 }, // 18
36 { 0xFF,0xFF,0xFF,0 }, // 19
37 };
38
39 BOOL bInitDefaultPalette(PPDEV ppdev, DEVINFO *pDevInfo);
40
41 /******************************Public*Routine******************************\
42 * bInitPaletteInfo
43 *
44 * Initializes the palette information for this PDEV.
45 *
46 * Called by DrvEnablePDEV.
47 *
48 \**************************************************************************/
49
50 BOOL bInitPaletteInfo(PPDEV ppdev, DEVINFO *pDevInfo)
51 {
52 if (!bInitDefaultPalette(ppdev, pDevInfo))
53 return(FALSE);
54
55 return(TRUE);
56 }
57
58 /******************************Public*Routine******************************\
59 * vDisablePalette
60 *
61 * Frees resources allocated by bInitPaletteInfo.
62 *
63 \**************************************************************************/
64
65 VOID vDisablePalette(PPDEV ppdev)
66 {
67 // Delete the default palette if we created one.
68
69 if (ppdev->hpalDefault)
70 {
71 EngDeletePalette(ppdev->hpalDefault);
72 ppdev->hpalDefault = (HPALETTE) 0;
73 }
74
75 if (ppdev->pPal != (PPALETTEENTRY)NULL)
76 EngFreeMem((PVOID)ppdev->pPal);
77 }
78
79 /******************************Public*Routine******************************\
80 * bInitDefaultPalette
81 *
82 * Initializes default palette for PDEV.
83 *
84 \**************************************************************************/
85
86 BOOL bInitDefaultPalette(PPDEV ppdev, DEVINFO *pDevInfo)
87 {
88 if (ppdev->ulBitCount == 8)
89 {
90 ULONG ulLoop;
91 BYTE jRed,jGre,jBlu;
92
93 //
94 // Allocate our palette
95 //
96
97 ppdev->pPal = (PPALETTEENTRY)EngAllocMem(0, sizeof(PALETTEENTRY) * 256,
98 ALLOC_TAG);
99
100 if ((ppdev->pPal) == NULL) {
101 RIP("DISP bInitDefaultPalette() failed EngAllocMem\n");
102 return(FALSE);
103 }
104
105 //
106 // Generate 256 (8*4*4) RGB combinations to fill the palette
107 //
108
109 jRed = jGre = jBlu = 0;
110
111 for (ulLoop = 0; ulLoop < 256; ulLoop++)
112 {
113 ppdev->pPal[ulLoop].peRed = jRed;
114 ppdev->pPal[ulLoop].peGreen = jGre;
115 ppdev->pPal[ulLoop].peBlue = jBlu;
116 ppdev->pPal[ulLoop].peFlags = (BYTE)0;
117
118 if (!(jRed += 32))
119 if (!(jGre += 32))
120 jBlu += 64;
121 }
122
123 //
124 // Fill in Windows Reserved Colors from the WIN 3.0 DDK
125 // The Window Manager reserved the first and last 10 colors for
126 // painting windows borders and for non-palette managed applications.
127 //
128
129 for (ulLoop = 0; ulLoop < 10; ulLoop++)
130 {
131 //
132 // First 10
133 //
134
135 ppdev->pPal[ulLoop] = BASEPALETTE[ulLoop];
136
137 //
138 // Last 10
139 //
140
141 ppdev->pPal[246 + ulLoop] = BASEPALETTE[ulLoop+10];
142 }
143
144 //
145 // Create handle for palette.
146 //
147
148 ppdev->hpalDefault =
149 pDevInfo->hpalDefault = EngCreatePalette(PAL_INDEXED,
150 256,
151 (PULONG) ppdev->pPal,
152 0,0,0);
153
154 if (ppdev->hpalDefault == (HPALETTE) 0)
155 {
156 RIP("DISP bInitDefaultPalette failed EngCreatePalette\n");
157 EngFreeMem(ppdev->pPal);
158 return(FALSE);
159 }
160
161 //
162 // Initialize the hardware with the initial palette.
163 //
164
165 return(TRUE);
166
167 } else {
168
169 ppdev->hpalDefault =
170 pDevInfo->hpalDefault = EngCreatePalette(PAL_BITFIELDS,
171 0,(PULONG) NULL,
172 ppdev->flRed,
173 ppdev->flGreen,
174 ppdev->flBlue);
175
176 if (ppdev->hpalDefault == (HPALETTE) 0)
177 {
178 RIP("DISP bInitDefaultPalette failed EngCreatePalette\n");
179 return(FALSE);
180 }
181 }
182
183 return(TRUE);
184 }
185
186 /******************************Public*Routine******************************\
187 * bInit256ColorPalette
188 *
189 * Initialize the hardware's palette registers.
190 *
191 \**************************************************************************/
192
193 BOOL bInit256ColorPalette(PPDEV ppdev)
194 {
195 BYTE ajClutSpace[MAX_CLUT_SIZE];
196 PVIDEO_CLUT pScreenClut;
197 ULONG ulReturnedDataLength;
198 ULONG cColors;
199 PVIDEO_CLUTDATA pScreenClutData;
200
201 if (ppdev->ulBitCount == 8)
202 {
203 //
204 // Fill in pScreenClut header info:
205 //
206
207 pScreenClut = (PVIDEO_CLUT) ajClutSpace;
208 pScreenClut->NumEntries = 256;
209 pScreenClut->FirstEntry = 0;
210
211 //
212 // Copy colours in:
213 //
214
215 cColors = 256;
216 pScreenClutData = (PVIDEO_CLUTDATA) (&(pScreenClut->LookupTable[0]));
217
218 while(cColors--)
219 {
220 pScreenClutData[cColors].Red = ppdev->pPal[cColors].peRed >>
221 ppdev->cPaletteShift;
222 pScreenClutData[cColors].Green = ppdev->pPal[cColors].peGreen >>
223 ppdev->cPaletteShift;
224 pScreenClutData[cColors].Blue = ppdev->pPal[cColors].peBlue >>
225 ppdev->cPaletteShift;
226 pScreenClutData[cColors].Unused = 0;
227 }
228
229 //
230 // Set palette registers:
231 //
232
233 if (EngDeviceIoControl(ppdev->hDriver,
234 IOCTL_VIDEO_SET_COLOR_REGISTERS,
235 pScreenClut,
236 MAX_CLUT_SIZE,
237 NULL,
238 0,
239 &ulReturnedDataLength))
240 {
241 DISPDBG((0, "Failed bEnablePalette"));
242 return(FALSE);
243 }
244 }
245
246 DISPDBG((5, "Passed bEnablePalette"));
247
248 return(TRUE);
249 }
250
251 /******************************Public*Routine******************************\
252 * DrvSetPalette
253 *
254 * DDI entry point for manipulating the palette.
255 *
256 \**************************************************************************/
257
258 BOOL DrvSetPalette(
259 DHPDEV dhpdev,
260 PALOBJ* ppalo,
261 FLONG fl,
262 ULONG iStart,
263 ULONG cColors)
264 {
265 BYTE ajClutSpace[MAX_CLUT_SIZE];
266 PVIDEO_CLUT pScreenClut;
267 PVIDEO_CLUTDATA pScreenClutData;
268 PDEV* ppdev;
269
270 UNREFERENCED_PARAMETER(fl);
271
272 ppdev = (PDEV*) dhpdev;
273
274 //
275 // Fill in pScreenClut header info:
276 //
277
278 pScreenClut = (PVIDEO_CLUT) ajClutSpace;
279 pScreenClut->NumEntries = (USHORT) cColors;
280 pScreenClut->FirstEntry = (USHORT) iStart;
281
282 pScreenClutData = (PVIDEO_CLUTDATA) (&(pScreenClut->LookupTable[0]));
283
284 if (cColors != PALOBJ_cGetColors(ppalo, iStart, cColors,
285 (ULONG*) pScreenClutData))
286 {
287 DISPDBG((0, "DrvSetPalette failed PALOBJ_cGetColors\n"));
288 return (FALSE);
289 }
290
291 //
292 // Set the high reserved byte in each palette entry to 0.
293 // Do the appropriate palette shifting to fit in the DAC.
294 //
295
296 if (ppdev->cPaletteShift)
297 {
298 while(cColors--)
299 {
300 pScreenClutData[cColors].Red >>= ppdev->cPaletteShift;
301 pScreenClutData[cColors].Green >>= ppdev->cPaletteShift;
302 pScreenClutData[cColors].Blue >>= ppdev->cPaletteShift;
303 pScreenClutData[cColors].Unused = 0;
304 }
305 }
306 else
307 {
308 while(cColors--)
309 {
310 pScreenClutData[cColors].Unused = 0;
311 }
312 }
313
314 //
315 // Set palette registers
316 //
317
318 if (EngDeviceIoControl(ppdev->hDriver,
319 IOCTL_VIDEO_SET_COLOR_REGISTERS,
320 pScreenClut,
321 MAX_CLUT_SIZE,
322 NULL,
323 0,
324 &cColors))
325 {
326 DISPDBG((0, "DrvSetPalette failed EngDeviceIoControl\n"));
327 return (FALSE);
328 }
329
330 return(TRUE);
331
332 }