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
IntInitDefaultPalette(PPDEV ppdev,PDEVINFO pDevInfo)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
IntSetPalette(IN DHPDEV dhpdev,IN PPALETTEENTRY ppalent,IN ULONG iStart,IN ULONG cColors)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
DrvSetPalette(IN DHPDEV dhpdev,IN PALOBJ * ppalo,IN FLONG fl,IN ULONG iStart,IN ULONG cColors)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