1/* $NetBSD: x68kGraph.c,v 1.10 2021/03/11 12:08:57 tsutsui Exp $ */
2/*-------------------------------------------------------------------------
3 * Copyright (c) 1996 Yasushi Yamasaki
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *-----------------------------------------------------------------------*/
26
27/* $XConsortium: sunCfb.c,v 1.15.1.2 95/01/12 18:54:42 kaleb Exp $ */
28
29/*
30Copyright (c) 1990  X Consortium
31
32Permission is hereby granted, free of charge, to any person obtaining a copy
33of this software and associated documentation files (the "Software"), to deal
34in the Software without restriction, including without limitation the rights
35to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
36copies of the Software, and to permit persons to whom the Software is
37furnished to do so, subject to the following conditions:
38
39The above copyright notice and this permission notice shall be included in
40all copies or substantial portions of the Software.
41
42THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
45X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
46AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
47CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
48
49Except as contained in this notice, the name of the X Consortium shall not be
50used in advertising or otherwise to promote the sale, use or other dealings
51in this Software without prior written authorization from the X Consortium.
52 */
53
54/************************************************************
55Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
56
57                    All Rights Reserved
58
59Permission  to  use,  copy,  modify,  and  distribute   this
60software  and  its documentation for any purpose and without
61fee is hereby granted, provided that the above copyright no-
62tice  appear  in all copies and that both that copyright no-
63tice and this permission notice appear in  supporting  docu-
64mentation,  and  that the names of Sun or X Consortium
65not be used in advertising or publicity pertaining to
66distribution  of  the software  without specific prior
67written permission. Sun and X Consortium make no
68representations about the suitability of this software for
69any purpose. It is provided "as is" without any express or
70implied warranty.
71
72SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO  THIS  SOFTWARE,
73INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
74NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE  LI-
75ABLE  FOR  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
76ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,  DATA  OR
77PROFITS,  WHETHER  IN  AN  ACTION OF CONTRACT, NEGLIGENCE OR
78OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
79THE USE OR PERFORMANCE OF THIS SOFTWARE.
80
81********************************************************/
82
83/*
84 * Copyright (c) 1987 by the Regents of the University of California
85 * Copyright (c) 1987 by Adam de Boor, UC Berkeley
86 *
87 * Permission to use, copy, modify, and distribute this
88 * software and its documentation for any purpose and without
89 * fee is hereby granted, provided that the above copyright
90 * notice appear in all copies.  The University of California
91 * makes no representations about the suitability of this
92 * software for any purpose.  It is provided "as is" without
93 * express or implied warranty.
94 */
95
96/****************************************************************/
97/* Modified from  sunCG4C.c for X11R3 by Tom Jarmolowski	*/
98/****************************************************************/
99
100/*
101 * Copyright 1991, 1992, 1993 Kaleb S. Keithley
102 *
103 * Permission to use, copy, modify, and distribute this
104 * software and its documentation for any purpose and without
105 * fee is hereby granted, provided that the above copyright
106 * notice appear in all copies.  Kaleb S. Keithley makes no
107 * representations about the suitability of this software for
108 * any purpose.  It is provided "as is" without express or
109 * implied warranty.
110 */
111
112#include "x68k.h"
113#include "mi.h"
114#include "micmap.h"
115
116#include "fb.h"
117
118/* local functions */
119static Bool x68kCfbFinishScreenInit(ScreenPtr pScreen, void *pbits,
120                                    int xsize, int ysize,
121                                    int dpix, int dpiy, int width);
122static void x68kInstallColormap(ColormapPtr cmap);
123static void x68kUninstallColormap(ColormapPtr cmap);
124static int x68kListInstalledColormaps(ScreenPtr pScreen, Colormap *pCmapList);
125static void x68kStoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs);
126
127static void x68kUpdateColormap(ScreenPtr pScreen, int dex, int count,
128                               uint8_t *rmap, uint8_t *gmap, uint8_t *bmap);
129
130/*-------------------------------------------------------------------------
131 * function "x68kGraphOpen"                          [ X68kFBProc function ]
132 *
133 *  purpose:  call common frame buffer opening procedure
134 *            then set hardware colormap for several static color modes.
135 *  argument: (X68kScreenRec *)pPriv : X68k private screen record
136 *  returns:  (Bool): TRUE  if successed
137 *                    FALSE otherwise
138 *-----------------------------------------------------------------------*/
139Bool
140x68kGraphOpen(X68kScreenRec *pPriv)
141{
142    if( !x68kFbCommonOpen(pPriv, "/dev/grf1") )
143        return FALSE;
144
145    /* initialize hardware colormap
146       in cases of static visual class */
147    if (pPriv->depth == 15 && pPriv->class == TrueColor) {
148        /* for 32768 TrueColor mode */
149	int i;
150	uint16_t x = 0x0001;
151	for ( i = 0; i < 256; ) {
152	    pPriv->reg->gpal[i++] = x;
153	    pPriv->reg->gpal[i++] = x;
154	    x += 0x0202;
155        }
156    }
157    if (pPriv->depth == 4 && pPriv->class == StaticGray ) {
158        /* for 16 StaticGray mode */
159        int i;
160        for( i = 0; i < 16; i++ )
161            pPriv->reg->gpal[i] = (i*2 << 11) | (i*2 << 6) | (i*2 << 1);
162    }
163    return TRUE;
164}
165
166/*-------------------------------------------------------------------------
167 * function "x68kGraphClose"                        [ X68kFBProc function ]
168 *
169 *  purpose:  close graphic frame buffer
170 *  argument: (X68kScreenRec *)pPriv : X68k private screen record
171 *  returns:  nothing
172 *-----------------------------------------------------------------------*/
173void
174x68kGraphClose(X68kScreenRec *pPriv)
175{
176    x68kFbCommonClose(pPriv);
177}
178
179/*-------------------------------------------------------------------------
180 * function "x68kGraphInit"                     [ called by DIX AddScreen ]
181 *
182 *  purpose:  initialize graphic frame buffer
183 *  argument: (ScreenPtr)pScreen       : DIX screen record
184 *            (int)argc, (char **)argv : standard C arguments
185 *  returns:  (Bool) : TRUE  if succeeded
186 *                     FALSE otherwise
187 *-----------------------------------------------------------------------*/
188Bool
189x68kGraphInit(ScreenPtr pScreen, int argc, char *argv[])
190{
191    X68kScreenRec *pPriv;
192
193    /* get private screen record set by X68KConfig */
194    pPriv = x68kGetScreenRecByType(X68K_FB_GRAPHIC);
195
196    /* store private record into screen */
197    if (!dixRegisterPrivateKey(&x68kScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) {
198        ErrorF("dixRegisterPrivateKey failed\n");
199        return FALSE;
200    }
201    x68kSetScreenPrivate(pScreen, pPriv);
202
203    /* register normal cfb screen functions */
204    if (!fbSetupScreen(pScreen, pPriv->fb,
205                       pPriv->scr_width, pPriv->scr_height,
206                       pPriv->dpi, pPriv->dpi, pPriv->fb_width,
207		       pPriv->depth))
208	return FALSE;
209
210    /* register colormap functions */
211    pScreen->InstallColormap = x68kInstallColormap;
212    pScreen->UninstallColormap = x68kUninstallColormap;
213    pScreen->ListInstalledColormaps = x68kListInstalledColormaps;
214    pScreen->StoreColors = x68kStoreColors;
215
216    /* visual initialization and etc.. */
217    if (!x68kCfbFinishScreenInit(pScreen, pPriv->fb,
218                                 pPriv->scr_width, pPriv->scr_height,
219                                 pPriv->dpi, pPriv->dpi, pPriv->fb_width))
220        return FALSE;
221
222    if ( !miDCInitialize(pScreen, &x68kPointerScreenFuncs) )
223        return FALSE;
224
225    pScreen->whitePixel = 1;
226    pScreen->blackPixel = 0;
227    if ( !miCreateDefColormap(pScreen) )
228        return FALSE;
229
230    return TRUE;
231}
232
233/*-------------------------------------------------------------------------
234 * function "x68kCfbFinishScreenInit"
235 *
236 *  purpose:  initialize visuals and perform miscellaneous settings
237 *  argument: (ScreenPtr)pScreen     : DIX screen record
238 *            (void *)pbits          : frame buffer
239 *            (int)xsize, (int)ysize : screen size
240 *            (int)dpix, (int)dpiy   : screen resolution in dots per inch
241 *            (int)width             : pixel width of frame buffer
242 *  returns:  (Bool) : TRUE  if succeeded
243 *                     FALSE otherwise
244 *-----------------------------------------------------------------------*/
245static Bool
246x68kCfbFinishScreenInit(
247    ScreenPtr pScreen,
248    void *pbits,
249    int xsize, int ysize,
250    int dpix, int dpiy,
251    int width)
252{
253    X68kScreenRec *pPriv = x68kGetScreenPrivate(pScreen);
254    VisualPtr	visuals;
255    int		nvisuals;
256    DepthPtr	depths;
257    int		ndepths;
258    VisualID	defaultVisual;
259    int		rootdepth = 0;
260
261    /* for 15/16bit TrueColor visual mode */
262    if (pPriv->depth == 15 && pPriv->class == TrueColor) {
263        VisualID *vid = NULL;
264
265        ndepths = 1;
266        nvisuals = 1;
267        depths = malloc( sizeof(DepthRec) );
268        visuals = malloc( sizeof(VisualRec) );
269        vid = malloc( sizeof(VisualID) );
270        if( !depths || !visuals || !vid ) {
271            free( depths );
272            free( visuals );
273            free( vid );
274            return FALSE;
275        }
276        depths[0].depth = 15;
277        depths[0].numVids = 1;
278        depths[0].vids = vid;
279        visuals[0].class = TrueColor;
280        visuals[0].bitsPerRGBValue = 5;
281        visuals[0].ColormapEntries = 1 << 5;
282        visuals[0].nplanes = 15;
283        visuals[0].vid = *vid = FakeClientID(0);
284        visuals[0].greenMask = 0xf800;
285        visuals[0].redMask   = 0x07c0;
286        visuals[0].blueMask  = 0x003e;
287        visuals[0].offsetGreen = 11;
288        visuals[0].offsetRed   = 6;
289        visuals[0].offsetBlue  = 1;
290        rootdepth = 15;
291        defaultVisual = *vid;
292    }
293    /* for 4/16bit StaticGray visual mode */
294    else if (pPriv->depth == 4 && pPriv->class == StaticGray ) {
295        VisualID *vid = NULL;
296
297        ndepths = 1;
298        nvisuals = 1;
299        depths = malloc( sizeof(DepthRec) );
300        visuals = malloc( sizeof(VisualRec) );
301        vid = malloc( sizeof(VisualID) );
302        if( !depths || !visuals || !vid ) {
303            free( depths );
304            free( visuals );
305            free( vid );
306            return FALSE;
307        }
308        depths[0].depth = 4;
309        depths[0].numVids = 1;
310        depths[0].vids = vid;
311        visuals[0].class = StaticGray;
312        visuals[0].bitsPerRGBValue = 4;
313        visuals[0].ColormapEntries = 1 << 4;
314        visuals[0].nplanes = 4;
315        visuals[0].vid = *vid = FakeClientID(0);
316        visuals[0].greenMask = 0;
317        visuals[0].redMask   = 0;
318        visuals[0].blueMask  = 0;
319        visuals[0].offsetGreen = 0;
320        visuals[0].offsetRed   = 0;
321        visuals[0].offsetBlue  = 0;
322        rootdepth = 4;
323        defaultVisual = *vid;
324    }
325    /* for other modes ( supports all visuals ) */
326    else if (!miInitVisuals(&visuals, &depths, &nvisuals, &ndepths,
327                            &rootdepth, &defaultVisual, 1 << (16 - 1),
328                            5, PseudoColor))
329	return FALSE;
330
331    if (!miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
332                      rootdepth, ndepths, depths,
333                      defaultVisual, nvisuals, visuals))
334	return FALSE;
335
336    pScreen->CloseScreen = fbCloseScreen;
337    pScreen->SaveScreen = x68kSaveScreen;
338
339    return TRUE;
340}
341
342/*-------------------------------------------------------------------------
343 * function "x68kInstallColormap"                      [ screen function ]
344 *
345 *  purpose:  install colormap, then update hardware colormap.
346 *  argument: (ColormapPtr)cmap : colormap to install
347 *  returns:  nothing
348 *-----------------------------------------------------------------------*/
349static void
350x68kInstallColormap(ColormapPtr cmap)
351{
352    X68kScreenRec *pPriv = x68kGetScreenPrivate(cmap->pScreen);
353    register int i;
354    register Entry *pent;
355    register VisualPtr pVisual = cmap->pVisual;
356    uint8_t   rmap[256], gmap[256], bmap[256];
357    unsigned long rMask, gMask, bMask;
358    int	oRed, oGreen, oBlue;
359
360    if (cmap == pPriv->installedMap)
361	return;
362    if (pPriv->installedMap)
363	WalkTree(pPriv->installedMap->pScreen, TellLostMap,
364		 (void *) &(pPriv->installedMap->mid));
365
366    if (pPriv->class & DynamicClass) {
367        if ((cmap->pVisual->class | DynamicClass) == DirectColor) {
368            rMask = pVisual->redMask;
369            gMask = pVisual->greenMask;
370            bMask = pVisual->blueMask;
371            oRed = pVisual->offsetRed;
372            oGreen = pVisual->offsetGreen;
373            oBlue = pVisual->offsetBlue;
374            for (i = 0; i < 1<<(pPriv->depth); i++) {
375                rmap[i] = cmap->red[(i & rMask) >> oRed].co.local.red >> 11;
376                gmap[i] = cmap->green[(i & gMask) >> oGreen].co.local.green >> 11;
377                bmap[i] = cmap->blue[(i & bMask) >> oBlue].co.local.blue >> 11;
378            }
379        } else {
380            for (i = 0, pent = cmap->red;
381                 i < pVisual->ColormapEntries;
382                 i++, pent++) {
383                if (pent->fShared) {
384                    rmap[i] = pent->co.shco.red->color >> 11;
385                    gmap[i] = pent->co.shco.green->color >> 11;
386                    bmap[i] = pent->co.shco.blue->color >> 11;
387                }
388                else {
389                    rmap[i] = pent->co.local.red >> 11;
390                    gmap[i] = pent->co.local.green >> 11;
391                    bmap[i] = pent->co.local.blue >> 11;
392                }
393            }
394        }
395        x68kUpdateColormap(cmap->pScreen, 0, 1<<(pPriv->depth), rmap, gmap, bmap);
396    }
397    pPriv->installedMap = cmap;
398    WalkTree(cmap->pScreen, TellGainedMap, (void *) &(cmap->mid));
399}
400
401/*-------------------------------------------------------------------------
402 * function "x68kUninstallColormap"                    [ screen function ]
403 *
404 *  purpose:  uninstall colormap
405 *  argument: (ColormapPtr)cmap : colormap to uninstall
406 *  returns:  nothing
407 *-----------------------------------------------------------------------*/
408static void
409x68kUninstallColormap(ColormapPtr cmap)
410{
411    X68kScreenRec *pPriv = x68kGetScreenPrivate(cmap->pScreen);
412
413    if (cmap == pPriv->installedMap) {
414	Colormap defMapID = cmap->pScreen->defColormap;
415
416	if (cmap->mid != defMapID) {
417	    void *retval;
418	    ColormapPtr defMap;
419	    dixLookupResourceByType(&retval, defMapID, RT_COLORMAP,
420		serverClient, DixReadAccess);
421	    defMap = (ColormapPtr) retval;
422	    (*cmap->pScreen->InstallColormap)(defMap);
423	}
424    }
425}
426
427/*-------------------------------------------------------------------------
428 * function "x68kListInstalledColormaps"               [ screen function ]
429 *
430 *  purpose:  Get the list of currently installed colormaps.
431 *            In X68k, installed colormap in always only one.
432 *  argument: (ScreenPtr)pScreen    : screen
433 *            (Colormap *)pCmapList : colormap list got
434 *  returns:  (int)
435 *-----------------------------------------------------------------------*/
436static int
437x68kListInstalledColormaps(ScreenPtr pScreen, Colormap *pCmapList)
438{
439    X68kScreenRec *pPriv = x68kGetScreenPrivate(pScreen);
440    *pCmapList = pPriv->installedMap->mid;
441    return 1;
442}
443
444/*-------------------------------------------------------------------------
445 * function "x68kStoreColors"                          [ screen function ]
446 *
447 *  purpose:  store specified color items
448 *  argument: (ColormapPtr)pmap   : colormap
449 *            (int)ndef           : the number of items
450 *            (xColorItem *)pdefs : items
451 *  returns:  nothing
452 *-----------------------------------------------------------------------*/
453static void
454x68kStoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs)
455{
456    X68kScreenRec *pPriv = x68kGetScreenPrivate(pmap->pScreen);
457    uint8_t     rmap[256], gmap[256], bmap[256];
458    xColorItem expanddefs[256];
459    register int i;
460
461    if (pPriv->installedMap != NULL && pPriv->installedMap != pmap)
462	return;
463    if ((pmap->pVisual->class | DynamicClass) == DirectColor) {
464	ndef = fbExpandDirectColors(pmap, ndef, pdefs, expanddefs);
465	pdefs = expanddefs;
466    }
467    while (ndef--) {
468	i = pdefs->pixel;
469	rmap[i] = pdefs->red >> 11;
470	gmap[i] = pdefs->green >> 11;
471	bmap[i] = pdefs->blue >> 11;
472	x68kUpdateColormap(pmap->pScreen, i, 1, rmap, gmap, bmap);
473	pdefs++;
474    }
475}
476
477/*-------------------------------------------------------------------------
478 * function "x68kUpdateColormap"
479 *
480 *  purpose:  update hardware colormap
481 *  argument: (ScreenPtr)pScreen: screen
482 *            (int)dex          : colormap index
483 *            (int)count        : count for updating
484 *            (uint8_t *)[rgb]map: each map
485 *  returns:  nothing
486 *-----------------------------------------------------------------------*/
487static void
488x68kUpdateColormap(ScreenPtr pScreen, int dex, int count,
489                               uint8_t *rmap, uint8_t *gmap, uint8_t *bmap)
490{
491    X68kScreenRec *pPriv = x68kGetScreenPrivate(pScreen);
492    volatile uint16_t *pal = pPriv->reg->gpal;
493
494    for( ; count > 0; count--,dex++ ) {
495        pal[dex] = (uint16_t)gmap[dex] << 11 |
496                   (uint16_t)rmap[dex] << 6 |
497                   (uint16_t)bmap[dex] << 1;
498    }
499}
500
501/* EOF x68kGraph.c */
502