x68kGraph.c revision 84d30d9d
1/* $NetBSD: x68kGraph.c,v 1.4 2020/11/05 16:06:08 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, pointer 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: (int)screen              : screen index
184 *            (ScreenPtr)pScreen       : DIX screen record
185 *            (int)argc, (char **)argv : standard C arguments
186 *  returns:  (Bool) : TRUE  if succeeded
187 *                     FALSE otherwise
188 *-----------------------------------------------------------------------*/
189Bool
190x68kGraphInit(int screen, ScreenPtr pScreen, int argc, char *argv[])
191{
192    X68kScreenRec *pPriv;
193
194    /* get private screen record set by X68KConfig */
195    pPriv = x68kGetScreenRecByType(X68K_FB_GRAPHIC);
196
197    /* store private record into screen */
198    if (!dixRegisterPrivateKey(&x68kScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) {
199        Error("dixRegisterPrivateKey failed");
200        return FALSE;
201    }
202    x68kSetScreenPrivate(pScreen, pPriv);
203
204    /* register normal cfb screen functions */
205    if (!fbSetupScreen(pScreen, pPriv->fb,
206                       pPriv->scr_width, pPriv->scr_height,
207                       pPriv->dpi, pPriv->dpi, pPriv->fb_width,
208		       pPriv->depth))
209	return FALSE;
210
211    /* register colormap functions */
212    pScreen->InstallColormap = x68kInstallColormap;
213    pScreen->UninstallColormap = x68kUninstallColormap;
214    pScreen->ListInstalledColormaps = x68kListInstalledColormaps;
215    pScreen->StoreColors = x68kStoreColors;
216
217    /* visual initialization and etc.. */
218    if (!x68kCfbFinishScreenInit(pScreen, pPriv->fb,
219                                 pPriv->scr_width, pPriv->scr_height,
220                                 pPriv->dpi, pPriv->dpi, pPriv->fb_width))
221        return FALSE;
222
223    if ( !miDCInitialize(pScreen, &x68kPointerScreenFuncs) )
224        return FALSE;
225
226    pScreen->whitePixel = 1;
227    pScreen->blackPixel = 0;
228    if ( !miCreateDefColormap(pScreen) )
229        return FALSE;
230
231    return TRUE;
232}
233
234/*-------------------------------------------------------------------------
235 * function "x68kCfbFinishScreenInit"
236 *
237 *  purpose:  initialize visuals and perform miscellaneous settings
238 *  argument: (ScreenPtr)pScreen     : DIX screen record
239 *            (pointer)pbits         : frame buffer
240 *            (int)xsize, (int)ysize : screen size
241 *            (int)dpix, (int)dpiy   : screen resolution in dots per inch
242 *            (int)width             : pixel width of frame buffer
243 *  returns:  (Bool) : TRUE  if succeeded
244 *                     FALSE otherwise
245 *-----------------------------------------------------------------------*/
246static Bool
247x68kCfbFinishScreenInit(
248    ScreenPtr pScreen,
249    pointer pbits,
250    int xsize, int ysize,
251    int dpix, int dpiy,
252    int width)
253{
254    X68kScreenRec *pPriv = x68kGetScreenPrivate(pScreen);
255    VisualPtr	visuals;
256    int		nvisuals;
257    DepthPtr	depths;
258    int		ndepths;
259    VisualID	defaultVisual;
260    int		rootdepth = 0;
261
262    /* for 15/16bit TrueColor visual mode */
263    if (pPriv->depth == 15 && pPriv->class == TrueColor) {
264        VisualID *vid = NULL;
265
266        ndepths = 1;
267        nvisuals = 1;
268        depths = malloc( sizeof(DepthRec) );
269        visuals = malloc( sizeof(VisualRec) );
270        vid = malloc( sizeof(VisualID) );
271        if( !depths || !visuals || !vid ) {
272            free( depths );
273            free( visuals );
274            free( vid );
275            return FALSE;
276        }
277        depths[0].depth = 15;
278        depths[0].numVids = 1;
279        depths[0].vids = vid;
280        visuals[0].class = TrueColor;
281        visuals[0].bitsPerRGBValue = 5;
282        visuals[0].ColormapEntries = 1 << 5;
283        visuals[0].nplanes = 15;
284        visuals[0].vid = *vid = FakeClientID(0);
285        visuals[0].greenMask = 0xf800;
286        visuals[0].redMask   = 0x07c0;
287        visuals[0].blueMask  = 0x003e;
288        visuals[0].offsetGreen = 11;
289        visuals[0].offsetRed   = 6;
290        visuals[0].offsetBlue  = 1;
291        rootdepth = 15;
292        defaultVisual = *vid;
293    }
294    /* for 4/16bit StaticGray visual mode */
295    else if (pPriv->depth == 4 && pPriv->class == StaticGray ) {
296        VisualID *vid = NULL;
297
298        ndepths = 1;
299        nvisuals = 1;
300        depths = malloc( sizeof(DepthRec) );
301        visuals = malloc( sizeof(VisualRec) );
302        vid = malloc( sizeof(VisualID) );
303        if( !depths || !visuals || !vid ) {
304            free( depths );
305            free( visuals );
306            free( vid );
307            return FALSE;
308        }
309        depths[0].depth = 4;
310        depths[0].numVids = 1;
311        depths[0].vids = vid;
312        visuals[0].class = StaticGray;
313        visuals[0].bitsPerRGBValue = 4;
314        visuals[0].ColormapEntries = 1 << 4;
315        visuals[0].nplanes = 4;
316        visuals[0].vid = *vid = FakeClientID(0);
317        visuals[0].greenMask = 0;
318        visuals[0].redMask   = 0;
319        visuals[0].blueMask  = 0;
320        visuals[0].offsetGreen = 0;
321        visuals[0].offsetRed   = 0;
322        visuals[0].offsetBlue  = 0;
323        rootdepth = 4;
324        defaultVisual = *vid;
325    }
326    /* for other modes ( supports all visuals ) */
327    else if (!miInitVisuals(&visuals, &depths, &nvisuals, &ndepths,
328                            &rootdepth, &defaultVisual, 1 << (16 - 1),
329                            5, PseudoColor))
330	return FALSE;
331
332    if (!miScreenInit(pScreen, pbits, xsize, ysize, dpix, dpiy, width,
333                      rootdepth, ndepths, depths,
334                      defaultVisual, nvisuals, visuals))
335	return FALSE;
336
337    pScreen->CloseScreen = fbCloseScreen;
338    pScreen->SaveScreen = x68kSaveScreen;
339    miInitializeBackingStore (pScreen);
340
341    return TRUE;
342}
343
344/*-------------------------------------------------------------------------
345 * function "x68kInstallColormap"                      [ screen function ]
346 *
347 *  purpose:  install colormap, then update hardware colormap.
348 *  argument: (ColormapPtr)cmap : colormap to install
349 *  returns:  nothing
350 *-----------------------------------------------------------------------*/
351static void
352x68kInstallColormap(ColormapPtr cmap)
353{
354    X68kScreenRec *pPriv = x68kGetScreenPrivate(cmap->pScreen);
355    register int i;
356    register Entry *pent;
357    register VisualPtr pVisual = cmap->pVisual;
358    uint8_t   rmap[256], gmap[256], bmap[256];
359    unsigned long rMask, gMask, bMask;
360    int	oRed, oGreen, oBlue;
361
362    if (cmap == pPriv->installedMap)
363	return;
364    if (pPriv->installedMap)
365	WalkTree(pPriv->installedMap->pScreen, TellLostMap,
366		 (pointer) &(pPriv->installedMap->mid));
367
368    if (pPriv->class & DynamicClass) {
369        if ((cmap->pVisual->class | DynamicClass) == DirectColor) {
370            rMask = pVisual->redMask;
371            gMask = pVisual->greenMask;
372            bMask = pVisual->blueMask;
373            oRed = pVisual->offsetRed;
374            oGreen = pVisual->offsetGreen;
375            oBlue = pVisual->offsetBlue;
376            for (i = 0; i < 1<<(pPriv->depth); i++) {
377                rmap[i] = cmap->red[(i & rMask) >> oRed].co.local.red >> 11;
378                gmap[i] = cmap->green[(i & gMask) >> oGreen].co.local.green >> 11;
379                bmap[i] = cmap->blue[(i & bMask) >> oBlue].co.local.blue >> 11;
380            }
381        } else {
382            for (i = 0, pent = cmap->red;
383                 i < pVisual->ColormapEntries;
384                 i++, pent++) {
385                if (pent->fShared) {
386                    rmap[i] = pent->co.shco.red->color >> 11;
387                    gmap[i] = pent->co.shco.green->color >> 11;
388                    bmap[i] = pent->co.shco.blue->color >> 11;
389                }
390                else {
391                    rmap[i] = pent->co.local.red >> 11;
392                    gmap[i] = pent->co.local.green >> 11;
393                    bmap[i] = pent->co.local.blue >> 11;
394                }
395            }
396        }
397        x68kUpdateColormap(cmap->pScreen, 0, 1<<(pPriv->depth), rmap, gmap, bmap);
398    }
399    pPriv->installedMap = cmap;
400    WalkTree(cmap->pScreen, TellGainedMap, (pointer) &(cmap->mid));
401}
402
403/*-------------------------------------------------------------------------
404 * function "x68kUninstallColormap"                    [ screen function ]
405 *
406 *  purpose:  uninstall colormap
407 *  argument: (ColormapPtr)cmap : colormap to uninstall
408 *  returns:  nothing
409 *-----------------------------------------------------------------------*/
410static void
411x68kUninstallColormap(ColormapPtr cmap)
412{
413    X68kScreenRec *pPriv = x68kGetScreenPrivate(cmap->pScreen);
414
415    if (cmap == pPriv->installedMap) {
416	Colormap defMapID = cmap->pScreen->defColormap;
417
418	if (cmap->mid != defMapID) {
419	    ColormapPtr defMap = (ColormapPtr) LookupIDByType(defMapID,
420							      RT_COLORMAP);
421	    (*cmap->pScreen->InstallColormap)(defMap);
422	}
423    }
424}
425
426/*-------------------------------------------------------------------------
427 * function "x68kListInstalledColormaps"               [ screen function ]
428 *
429 *  purpose:  Get the list of currently installed colormaps.
430 *            In X68k, installed colormap in always only one.
431 *  argument: (ScreenPtr)pScreen    : screen
432 *            (Colormap *)pCmapList : colormap list got
433 *  returns:  (int)
434 *-----------------------------------------------------------------------*/
435static int
436x68kListInstalledColormaps(ScreenPtr pScreen, Colormap *pCmapList)
437{
438    X68kScreenRec *pPriv = x68kGetScreenPrivate(pScreen);
439    *pCmapList = pPriv->installedMap->mid;
440    return 1;
441}
442
443/*-------------------------------------------------------------------------
444 * function "x68kStoreColors"                          [ screen function ]
445 *
446 *  purpose:  store specified color items
447 *  argument: (ColormapPtr)pmap   : colormap
448 *            (int)ndef           : the number of items
449 *            (xColorItem *)pdefs : items
450 *  returns:  nothing
451 *-----------------------------------------------------------------------*/
452static void
453x68kStoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs)
454{
455    X68kScreenRec *pPriv = x68kGetScreenPrivate(pmap->pScreen);
456    uint8_t     rmap[256], gmap[256], bmap[256];
457    xColorItem expanddefs[256];
458    register int i;
459
460    if (pPriv->installedMap != NULL && pPriv->installedMap != pmap)
461	return;
462    if ((pmap->pVisual->class | DynamicClass) == DirectColor) {
463	ndef = fbExpandDirectColors(pmap, ndef, pdefs, expanddefs);
464	pdefs = expanddefs;
465    }
466    while (ndef--) {
467	i = pdefs->pixel;
468	rmap[i] = pdefs->red >> 11;
469	gmap[i] = pdefs->green >> 11;
470	bmap[i] = pdefs->blue >> 11;
471	x68kUpdateColormap(pmap->pScreen, i, 1, rmap, gmap, bmap);
472	pdefs++;
473    }
474}
475
476/*-------------------------------------------------------------------------
477 * function "x68kUpdateColormap"
478 *
479 *  purpose:  update hardware colormap
480 *  argument: (ScreenPtr)pScreen: screen
481 *            (int)dex          : colormap index
482 *            (int)count        : count for updating
483 *            (uint8_t *)[rgb]map: each map
484 *  returns:  nothing
485 *-----------------------------------------------------------------------*/
486static void
487x68kUpdateColormap(ScreenPtr pScreen, int dex, int count,
488                               uint8_t *rmap, uint8_t *gmap, uint8_t *bmap)
489{
490    X68kScreenRec *pPriv = x68kGetScreenPrivate(pScreen);
491    volatile uint16_t *pal = pPriv->reg->gpal;
492
493    for( ; count > 0; count--,dex++ ) {
494        pal[dex] = (uint16_t)gmap[dex] << 11 |
495                   (uint16_t)rmap[dex] << 6 |
496                   (uint16_t)bmap[dex] << 1;
497    }
498}
499
500/* EOF x68kGraph.c */
501