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