1/* $Xorg: sunCfb24.c,v 1.4 2001/02/09 02:04:43 xorgcvs Exp $ */
2
3/*
4
5Copyright 1994, 1998  The Open Group
6
7Permission to use, copy, modify, distribute, and sell this software and its
8documentation for any purpose is hereby granted without fee, provided that
9the above copyright notice appear in all copies and that both that
10copyright notice and this permission notice appear in supporting
11documentation.
12
13The above copyright notice and this permission notice shall be included in all
14copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE X
19CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23Except as contained in this notice, the name of The Open Group shall not be
24used in advertising or otherwise to promote the sale, use or other dealings in
25this Software without prior written authorization from The Open Group.
26
27*/
28/* $XFree86: xc/programs/Xserver/hw/sun/sunCfb24.c,v 1.3 2001/12/14 19:59:42 dawes Exp $ */
29
30/*
31 * The CG8 is similar to the CG4 in that it has a mono plane, an enable
32 * plane, and a color plane. While the CG4 only has an 8-bit color
33 * plane the CG8 has a 24-bit color plane.
34 *
35 * If you have a CG4 you know that you can switch between the mono and
36 * the color screens merely by dragging the pointer off the edge of the
37 * screen, causing the other screen to be switched in. However this is
38 * the cause of some consternation on the part of those people who have
39 * both a CG4 and another frame buffer.
40 *
41 * Because of this problem, and some other considerations, I have chosen
42 * to ignore the mono plane of the CG8 in this code.
43 */
44
45#define PSZ 32
46#include "sun.h"
47#include "fb.h"
48
49#define PIXPG_24BIT_COLOR 5
50#define PIXPG_24BIT_COLOR_INDEX (PIXPG_24BIT_COLOR << 25)
51#define PR_FORCE_UPDATE (1 << 24)
52
53static void CG24UpdateColormap(ScreenPtr, int, int, u_char *, u_char *, u_char *);
54static void CG24StoreColors(ColormapPtr, int, xColorItem *);
55static void CG24ScreenInit(ScreenPtr);
56
57static void
58CG24UpdateColormap(ScreenPtr pScreen, int index, int count, u_char *rmap, u_char *gmap, u_char *bmap)
59{
60    struct fbcmap sunCmap;
61
62    sunCmap.index = index | PIXPG_24BIT_COLOR_INDEX | PR_FORCE_UPDATE;
63    sunCmap.count = count;
64    sunCmap.red = &rmap[index];
65    sunCmap.green = &gmap[index];
66    sunCmap.blue = &bmap[index];
67
68    if (ioctl(sunFbs[pScreen->myNum].fd, FBIOPUTCMAP, &sunCmap) == -1)
69	FatalError( "CG24UpdateColormap: FBIOPUTCMAP failed\n");
70}
71
72static void
73CG24StoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs)
74{
75  u_char rmap[256], gmap[256], bmap[256];
76  sunScreenPtr pPrivate = sunGetScreenPrivate(pmap->pScreen);
77  VisualPtr pVisual = pmap->pVisual;
78  int i;
79
80  if (pPrivate->installedMap != NULL && pPrivate->installedMap != pmap)
81    return;
82  for (i = 0; i < 256; i++) {
83    rmap[i] = pmap->red[i].co.local.red >> 8;
84    gmap[i] = pmap->green[i].co.local.green >> 8;
85    bmap[i] = pmap->blue[i].co.local.blue >> 8;
86  }
87  while (ndef--) {
88    i = pdefs->pixel;
89    if (pdefs->flags & DoRed)
90      rmap[(i & pVisual->redMask) >> pVisual->offsetRed] = (pdefs->red >> 8);
91    if (pdefs->flags & DoGreen)
92      gmap[(i & pVisual->greenMask) >> pVisual->offsetGreen] = (pdefs->green >> 8);
93    if (pdefs->flags & DoBlue)
94      bmap[(i & pVisual->blueMask) >> pVisual->offsetBlue] = (pdefs->blue >> 8);
95    pdefs++;
96  }
97  CG24UpdateColormap (pmap->pScreen, 0, 256, rmap, gmap, bmap);
98}
99
100#define CG8_COLOR_OFFSET 0x40000
101
102static void
103CG24ScreenInit(ScreenPtr pScreen)
104{
105#ifndef STATIC_COLOR
106    sunScreenPtr pPrivate = sunGetScreenPrivate(pScreen);
107#endif
108    int i;
109
110    /* Make sure the overlay plane is disabled */
111    for (i = 0; i < CG8_COLOR_OFFSET; i++)
112	sunFbs[pScreen->myNum].fb[i] = 0;
113
114#ifndef STATIC_COLOR
115    pScreen->InstallColormap = sunInstallColormap;
116    pScreen->UninstallColormap = sunUninstallColormap;
117    pScreen->ListInstalledColormaps = sunListInstalledColormaps;
118    pScreen->StoreColors = CG24StoreColors;
119    pPrivate->UpdateColormap = CG24UpdateColormap;
120    if (sunFlipPixels) {
121	Pixel pixel = pScreen->whitePixel;
122	pScreen->whitePixel = pScreen->blackPixel;
123	pScreen->blackPixel = pixel;
124    }
125#endif
126}
127
128Bool
129sunCG8Init(
130    int		    screen,    	/* what screen am I going to be */
131    ScreenPtr	    pScreen,  	/* The Screen to initialize */
132    int		    argc,    	/* The number of the Server's arguments. */
133    char	    **argv   	/* The arguments themselves. Don't change! */
134)
135{
136    sunFbs[screen].EnterLeave = (void (*)(ScreenPtr, int))NoopDDA;
137    return sunInitCommon (screen, pScreen, (off_t) 0,
138	fbScreenInit, CG24ScreenInit,
139	fbCreateDefColormap, sunSaveScreen, CG8_COLOR_OFFSET);
140}
141
142