1 /*
2  * ReactOS Generic Framebuffer display driver
3  *
4  * Copyright (C) 2004 Filip Navara
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 #include "framebuf.h"
22 
23 /*
24  * Standard color that must be in palette, because they're used for
25  * drawing window borders and other GUI elements.
26  */
27 
28 const PALETTEENTRY BASEPALETTE[20] =
29 {
30    { 0x00, 0x00, 0x00, 0x00 },
31    { 0x80, 0x00, 0x00, 0x00 },
32    { 0x00, 0x80, 0x00, 0x00 },
33    { 0x80, 0x80, 0x00, 0x00 },
34    { 0x00, 0x00, 0x80, 0x00 },
35    { 0x80, 0x00, 0x80, 0x00 },
36    { 0x00, 0x80, 0x80, 0x00 },
37    { 0xC0, 0xC0, 0xC0, 0x00 },
38    { 0xC0, 0xDC, 0xC0, 0x00 },
39    { 0xD4, 0xD0, 0xC8, 0x00 },
40    { 0xFF, 0xFB, 0xF0, 0x00 },
41    { 0x3A, 0x6E, 0xA5, 0x00 },
42    { 0x80, 0x80, 0x80, 0x00 },
43    { 0xFF, 0x00, 0x00, 0x00 },
44    { 0x00, 0xFF, 0x00, 0x00 },
45    { 0xFF, 0xFF, 0x00, 0x00 },
46    { 0x00, 0x00, 0xFF, 0x00 },
47    { 0xFF, 0x00, 0xFF, 0x00 },
48    { 0x00, 0xFF, 0xFF, 0x00 },
49    { 0xFF, 0xFF, 0xFF, 0x00 },
50 };
51 
52 /*
53  * IntInitDefaultPalette
54  *
55  * Initializes default palette for PDEV and fill it with the colors specified
56  * by the GDI standard.
57  */
58 
59 BOOL
60 IntInitDefaultPalette(
61    PPDEV ppdev,
62    PDEVINFO pDevInfo)
63 {
64    ULONG ColorLoop;
65    PPALETTEENTRY PaletteEntryPtr;
66 
67    if (ppdev->BitsPerPixel > 8)
68    {
69       ppdev->DefaultPalette = pDevInfo->hpalDefault =
70          EngCreatePalette(PAL_BITFIELDS, 0, NULL,
71             ppdev->RedMask, ppdev->GreenMask, ppdev->BlueMask);
72    }
73    else
74    {
75       ppdev->PaletteEntries = EngAllocMem(0, sizeof(PALETTEENTRY) << 8, ALLOC_TAG);
76       if (ppdev->PaletteEntries == NULL)
77       {
78          return FALSE;
79       }
80 
81       for (ColorLoop = 256, PaletteEntryPtr = ppdev->PaletteEntries;
82            ColorLoop != 0;
83            ColorLoop--, PaletteEntryPtr++)
84       {
85          PaletteEntryPtr->peRed = ((ColorLoop >> 5) & 7) * 255 / 7;
86          PaletteEntryPtr->peGreen = ((ColorLoop >> 3) & 3) * 255 / 3;
87          PaletteEntryPtr->peBlue = (ColorLoop & 7) * 255 / 7;
88          PaletteEntryPtr->peFlags = 0;
89       }
90 
91       memcpy(ppdev->PaletteEntries, BASEPALETTE, 10 * sizeof(PALETTEENTRY));
92       memcpy(ppdev->PaletteEntries + 246, BASEPALETTE + 10, 10 * sizeof(PALETTEENTRY));
93 
94       ppdev->DefaultPalette = pDevInfo->hpalDefault =
95          EngCreatePalette(PAL_INDEXED, 256, (PULONG)ppdev->PaletteEntries, 0, 0, 0);
96     }
97 
98     return ppdev->DefaultPalette != NULL;
99 }
100 
101 /*
102  * IntSetPalette
103  *
104  * Requests that the driver realize the palette for a specified device. The
105  * driver sets the hardware palette to match the entries in the given palette
106  * as closely as possible.
107  */
108 
109 BOOL APIENTRY
110 IntSetPalette(
111    IN DHPDEV dhpdev,
112    IN PPALETTEENTRY ppalent,
113    IN ULONG iStart,
114    IN ULONG cColors)
115 {
116    PVIDEO_CLUT pClut;
117    ULONG ClutSize;
118 
119    ClutSize = sizeof(VIDEO_CLUT) + (cColors * sizeof(ULONG));
120    pClut = EngAllocMem(0, ClutSize, ALLOC_TAG);
121    pClut->FirstEntry = iStart;
122    pClut->NumEntries = cColors;
123    memcpy(&pClut->LookupTable[0].RgbLong, ppalent, sizeof(ULONG) * cColors);
124 
125    if (((PPDEV)dhpdev)->PaletteShift)
126    {
127       while (cColors--)
128       {
129          pClut->LookupTable[cColors].RgbArray.Red >>= ((PPDEV)dhpdev)->PaletteShift;
130          pClut->LookupTable[cColors].RgbArray.Green >>= ((PPDEV)dhpdev)->PaletteShift;
131          pClut->LookupTable[cColors].RgbArray.Blue >>= ((PPDEV)dhpdev)->PaletteShift;
132          pClut->LookupTable[cColors].RgbArray.Unused = 0;
133       }
134    }
135    else
136    {
137       while (cColors--)
138       {
139          pClut->LookupTable[cColors].RgbArray.Unused = 0;
140       }
141    }
142 
143    /*
144     * Set the palette registers.
145     */
146 
147    if (EngDeviceIoControl(((PPDEV)dhpdev)->hDriver, IOCTL_VIDEO_SET_COLOR_REGISTERS,
148                           pClut, ClutSize, NULL, 0, &cColors))
149    {
150       EngFreeMem(pClut);
151       return FALSE;
152    }
153 
154    EngFreeMem(pClut);
155    return TRUE;
156 }
157 
158 /*
159  * DrvSetPalette
160  *
161  * Requests that the driver realize the palette for a specified device. The
162  * driver sets the hardware palette to match the entries in the given palette
163  * as closely as possible.
164  *
165  * Status
166  *    @implemented
167  */
168 
169 BOOL APIENTRY
170 DrvSetPalette(
171    IN DHPDEV dhpdev,
172    IN PALOBJ *ppalo,
173    IN FLONG fl,
174    IN ULONG iStart,
175    IN ULONG cColors)
176 {
177    PPALETTEENTRY PaletteEntries;
178    BOOL bRet;
179 
180    if (cColors == 0)
181        return FALSE;
182 
183    PaletteEntries = EngAllocMem(0, cColors * sizeof(ULONG), ALLOC_TAG);
184    if (PaletteEntries == NULL)
185    {
186       return FALSE;
187    }
188 
189    if (PALOBJ_cGetColors(ppalo, iStart, cColors, (PULONG)PaletteEntries) !=
190        cColors)
191    {
192       EngFreeMem(PaletteEntries);
193       return FALSE;
194    }
195 
196    bRet = IntSetPalette(dhpdev, PaletteEntries, iStart, cColors);
197    EngFreeMem(PaletteEntries);
198    return bRet;
199 }
200