mirror of
https://github.com/Stichting-MINIX-Research-Foundation/xsrc.git
synced 2025-09-15 15:45:00 -04:00
569 lines
14 KiB
C
569 lines
14 KiB
C
/*-
|
|
* amigaC.c --
|
|
* Functions for handling the amiga BWTWO board.
|
|
*
|
|
* Copyright (c) 1987 by the Regents of the University of California
|
|
* Copyright (c) 1987 by Adam de Boor, UC Berkeley
|
|
*
|
|
* Permission to use, copy, modify, and distribute this
|
|
* software and its documentation for any purpose and without
|
|
* fee is hereby granted, provided that the above copyright
|
|
* notice appear in all copies. The University of California
|
|
* makes no representations about the suitability of this
|
|
* software for any purpose. It is provided "as is" without
|
|
* express or implied warranty.
|
|
*
|
|
*
|
|
*/
|
|
|
|
/************************************************************
|
|
Copyright (c) 1995 by Daniver Limited (Gary Henderson)
|
|
Copyright 1994 by Eduardo Horvath
|
|
Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
|
|
|
|
All Rights Reserved
|
|
|
|
Permission to use, copy, modify, and distribute this
|
|
software and its documentation for any purpose and without
|
|
fee is hereby granted, provided that the above copyright no-
|
|
tice appear in all copies and that both that copyright no-
|
|
tice and this permission notice appear in supporting docu-
|
|
mentation, and that the names of Sun or MIT not be used in
|
|
advertising or publicity pertaining to distribution of the
|
|
software without specific prior written permission. Sun and
|
|
M.I.T. make no representations about the suitability of this
|
|
software for any purpose. It is provided "as is" without any
|
|
express or implied warranty.
|
|
|
|
SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
|
|
NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
|
|
ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
|
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
|
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
|
|
THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
********************************************************/
|
|
|
|
#ifdef AMIGA_CC_COLOR
|
|
|
|
#ifndef lint
|
|
static char sccsid[] = "%W %G Copyright 1987 Sun Micro";
|
|
#endif
|
|
|
|
/*-
|
|
* Copyright (c) 1987 by Sun Microsystems, Inc.
|
|
*/
|
|
|
|
#include "amiga.h"
|
|
#include "afb.h"
|
|
#include "resource.h"
|
|
#include "miline.h"
|
|
|
|
#define GXZEROLINEBIAS (OCTANT1 | OCTANT3 | OCTANT4 | OCTANT6)
|
|
|
|
#include <sys/mman.h>
|
|
|
|
#if defined(__NetBSD__) && !defined(MAP_FILE)
|
|
#define MAP_FILE 0
|
|
#endif
|
|
|
|
|
|
extern void *mmap();
|
|
static void amigaCInstallColormap ();
|
|
static void amigaCUninstallColormap ();
|
|
static int amigaCListInstalledColormaps ();
|
|
static void amigaCStoreColors ();
|
|
static void amigaCUpdateColormap ();
|
|
|
|
/* These are set by ddxProcessArgument */
|
|
int amigaCCWidth = 700;
|
|
int amigaCCHeight = 430;
|
|
int amigaCCDepth = 4;
|
|
int numColors = 16;
|
|
int amigaCCXOffset;
|
|
int amigaCCYOffset;
|
|
|
|
/*-
|
|
*-----------------------------------------------------------------------
|
|
* amigaCInit --
|
|
* Attempt to find and initialize a bw2 framebuffer
|
|
*
|
|
* Results:
|
|
* None
|
|
*
|
|
* Side Effects:
|
|
* Most of the elements of the ScreenRec are filled in. The
|
|
* video is enabled for the frame buffer...
|
|
*
|
|
*-----------------------------------------------------------------------
|
|
*/
|
|
#define StaticGrayMask (1 << StaticGray)
|
|
#define GrayScaleMask (1 << GrayScale)
|
|
#define StaticColorMask (1 << StaticColor)
|
|
#define PseudoColorMask (1 << PseudoColor)
|
|
#define TrueColorMask (1 << TrueColor)
|
|
#define DirectColorMask (1 << DirectColor)
|
|
|
|
#define ALL_VISUALS (StaticGrayMask|\
|
|
GrayScaleMask|\
|
|
StaticColorMask|\
|
|
PseudoColorMask|\
|
|
TrueColorMask|\
|
|
DirectColorMask)
|
|
|
|
/*ARGSUSED*/
|
|
Bool
|
|
amigaCInit (index, pScreen, argc, argv)
|
|
int index; /* The index of pScreen in the ScreenInfo */
|
|
ScreenPtr pScreen; /* The Screen to initialize */
|
|
int argc; /* The number of the Server's arguments. */
|
|
char **argv; /* The arguments themselves. Don't change! */
|
|
{
|
|
amigaScreenPtr pPrivate;
|
|
unsigned long visuals = 0;
|
|
colormap_t *colormap = &amigaFbs[index].view.colormap;
|
|
|
|
if (colormap->type != CM_COLOR)
|
|
{
|
|
if (colormap->type == CM_MONO)
|
|
visuals = StaticGrayMask;
|
|
else /* CM_GREYSCALE */
|
|
visuals = StaticGrayMask | GrayScaleMask;
|
|
}
|
|
else
|
|
switch (amigaCCDepth)
|
|
{
|
|
case 1:
|
|
visuals = StaticGrayMask;
|
|
break;
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
case 5:
|
|
visuals = StaticGrayMask | GrayScaleMask | StaticColorMask |
|
|
PseudoColorMask;
|
|
break;
|
|
|
|
default:
|
|
visuals = ALL_VISUALS;
|
|
break;
|
|
}
|
|
|
|
if (!afbSetVisualTypes (amigaCCDepth, visuals,
|
|
colormap->red_mask == 0xff ? 8 : 4))
|
|
{
|
|
ErrorF ("afbSetVisualTypes: FALSE\n");
|
|
return (FALSE);
|
|
}
|
|
|
|
if (!afbScreenInit(pScreen,
|
|
amigaFbs[index].fb,
|
|
amigaFbs[index].view.vs.width,
|
|
amigaFbs[index].view.vs.height,
|
|
monitorResolution, monitorResolution,
|
|
amigaFbs[index].view.vs.width))
|
|
{
|
|
ErrorF ("afbScreenInit: FALSE\n");
|
|
return (FALSE);
|
|
}
|
|
|
|
pScreen->InstallColormap = amigaCInstallColormap;
|
|
pScreen->UninstallColormap = amigaCUninstallColormap;
|
|
pScreen->ListInstalledColormaps = amigaCListInstalledColormaps;
|
|
pScreen->StoreColors = amigaCStoreColors;
|
|
|
|
if (!amigaScreenAllocate (pScreen))
|
|
{
|
|
ErrorF ("amigaScreenAllocate: FALSE\n");
|
|
return (FALSE);
|
|
}
|
|
|
|
if (!amigaScreenInit (pScreen))
|
|
{
|
|
ErrorF ("amigaScreenInit: FALSE\n");
|
|
return FALSE;
|
|
}
|
|
|
|
pPrivate = (amigaScreenPtr) pScreen->devPrivates[amigaScreenIndex].ptr;
|
|
pPrivate->UpdateColormap = amigaCUpdateColormap;
|
|
|
|
/*
|
|
* Enable video output...?
|
|
*/
|
|
(void) amigaSaveScreen(pScreen, SCREEN_SAVER_OFF);
|
|
|
|
if (!afbCreateDefColormap (pScreen))
|
|
{
|
|
ErrorF ("afbCreateDefColormap: FALSE\n");
|
|
return (FALSE);
|
|
}
|
|
|
|
miSetZeroLineBias(pScreen, GXZEROLINEBIAS);
|
|
|
|
return TRUE;
|
|
}
|
|
/*-
|
|
*-----------------------------------------------------------------------
|
|
* xopen_view (void) --
|
|
* Scan for and initialize a view to use.
|
|
*
|
|
* Results:
|
|
* Returns fd of opened view.
|
|
*
|
|
* Side Effects:
|
|
* none
|
|
*
|
|
*-----------------------------------------------------------------------
|
|
*/
|
|
int
|
|
xopen_view (void)
|
|
{
|
|
u_char buffer[13];
|
|
int i, fd;
|
|
|
|
for (i=0; i < 100; i++) {
|
|
sprintf (buffer, "/dev/view%02d", i);
|
|
fd = open (buffer, O_RDWR);
|
|
if (fd < 0 && errno != EBUSY) {
|
|
perror ("xopen_view()");
|
|
return (-1);
|
|
} else if (fd >= 0) {
|
|
return (fd);
|
|
}
|
|
}
|
|
Error ("Ran out of views");
|
|
return (-1);
|
|
}
|
|
|
|
/*-
|
|
*-----------------------------------------------------------------------
|
|
* amigaCProbe --
|
|
* Attempt to find and initialize a bw2 framebuffer
|
|
*
|
|
* Results:
|
|
* None
|
|
*
|
|
* Side Effects:
|
|
* Memory is allocated for the frame buffer and the buffer is mapped.
|
|
*
|
|
*-----------------------------------------------------------------------
|
|
*/
|
|
|
|
/*ARGSUSED*/
|
|
Bool
|
|
amigaCProbe(pScreenInfo, index, fbNum, argc, argv)
|
|
ScreenInfo *pScreenInfo; /* The screenInfo struct */
|
|
int index; /* The index of pScreen in the ScreenInfo */
|
|
int fbNum; /* Index into the amigaFbData array */
|
|
int argc; /* The number of the Server's arguments. */
|
|
char **argv; /* The arguments themselves. Don't change! */
|
|
{
|
|
int fd;
|
|
int pagemask, mapsize;
|
|
caddr_t addr, mapaddr;
|
|
struct view_size vs;
|
|
bmap_t bm;
|
|
colormap_t colormap;
|
|
|
|
if ((fd = xopen_view()) < 0)
|
|
return FALSE;
|
|
|
|
if (ioctl(fd, VIOCGSIZE, &vs)) {
|
|
Error("ioctl VIOCGSIZE");
|
|
return FALSE;
|
|
}
|
|
|
|
vs.width = amigaCCWidth;
|
|
vs.height = amigaCCHeight;
|
|
vs.depth = amigaCCDepth;
|
|
vs.x = amigaCCXOffset;
|
|
vs.y = amigaCCYOffset;
|
|
|
|
if (ioctl(fd, VIOCSSIZE, &vs)) {
|
|
Error("ioctl VIOCGSIZE");
|
|
return FALSE;
|
|
}
|
|
|
|
if (ioctl(fd, VIOCGSIZE, &vs)) {
|
|
Error("ioctl VIOCGSIZE");
|
|
return FALSE;
|
|
}
|
|
|
|
amigaCCDepth = vs.depth;
|
|
numColors = 1 << amigaCCDepth;
|
|
|
|
if (ioctl(fd, VIOCGBMAP, &bm)) {
|
|
Error ("ioctl VIOCGBMAP");
|
|
return FALSE;
|
|
}
|
|
|
|
if ((mapaddr = (caddr_t) mmap(0, bm.bytes_per_row*bm.rows*bm.depth,
|
|
PROT_READ | PROT_WRITE, MAP_FILE, fd, (off_t)0)) == (caddr_t) -1) {
|
|
Error("mmapping bitmap");
|
|
(void) close(fd);
|
|
return FALSE;
|
|
}
|
|
|
|
if (mapaddr) {
|
|
unsigned long endaddr, guardaddr, pagesize;
|
|
caddr_t guardp, guardp1;
|
|
|
|
pagesize = getpagesize();
|
|
|
|
endaddr = (unsigned long)mapaddr + bm.bytes_per_row*bm.rows*bm.depth-1;
|
|
guardaddr = endaddr + 8;
|
|
if ((guardaddr ^ endaddr) & ~(pagesize-1)) {
|
|
/* need guard page */
|
|
guardp = (caddr_t)(guardaddr & ~(pagesize-1));
|
|
guardp1 = mmap(guardp, pagesize, PROT_READ|PROT_WRITE,
|
|
MAP_ANON|MAP_FIXED, -1, 0);
|
|
if (guardp1 == (caddr_t)-1) {
|
|
Error("Can't allocate guard page");
|
|
}
|
|
}
|
|
}
|
|
|
|
if (mapaddr == 0)
|
|
mapaddr = addr;
|
|
|
|
colormap.first = 0;
|
|
colormap.size = numColors;
|
|
colormap.entry = amigaFbs[fbNum].view.entry;
|
|
|
|
if(ioctl (fd, VIOCGCMAP, &colormap)== -1)
|
|
Error("getting colormap");
|
|
|
|
amigaFbs[fbNum].fb = (pointer)mapaddr;
|
|
amigaFbs[fbNum].fd = fd;
|
|
amigaFbs[fbNum].view.bm = bm;
|
|
amigaFbs[fbNum].view.vs = vs;
|
|
amigaFbs[fbNum].view.colormap = colormap;
|
|
amigaFbs[fbNum].EnterLeave = NULL;
|
|
|
|
#ifndef GDBUG
|
|
if (ioctl(fd, VIOCDISPLAY, 0)) {
|
|
Error ("ioctl VIOCDISPLAY");
|
|
return FALSE;
|
|
}
|
|
#endif
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
Bool
|
|
amigaCCreate(pScreenInfo, argc, argv)
|
|
ScreenInfo *pScreenInfo;
|
|
int argc;
|
|
char **argv;
|
|
{
|
|
return (AddScreen(amigaCInit, argc, argv) >= 0);
|
|
}
|
|
|
|
static void
|
|
amigaCUpdateColormap(pScreen, index, count, rmap, gmap, bmap)
|
|
ScreenPtr pScreen;
|
|
int index, count;
|
|
u_char *rmap, *gmap, *bmap;
|
|
{
|
|
colormap_t *colormap = &amigaFbs[pScreen->myNum].view.colormap;
|
|
|
|
while (count--)
|
|
{
|
|
colormap->entry [index]= (rmap[index] << 16) | (gmap[index] << 8) |
|
|
bmap[index] ;
|
|
index++;
|
|
}
|
|
if (ioctl (amigaFbs [pScreen->myNum].fd, VIOCSCMAP, colormap) == -1)
|
|
Error ("Setting colormap");
|
|
}
|
|
|
|
|
|
/*-
|
|
*-----------------------------------------------------------------------
|
|
* amigaCInstallColormap --
|
|
* Install given colormap.
|
|
*
|
|
* Results:
|
|
* None
|
|
*
|
|
* Side Effects:
|
|
* Existing map is uninstalled.
|
|
* All clients requesting ColormapNotify are notified
|
|
*
|
|
*-----------------------------------------------------------------------
|
|
*/
|
|
static void
|
|
amigaCInstallColormap(cmap)
|
|
ColormapPtr cmap;
|
|
{
|
|
SetupScreen(cmap->pScreen);
|
|
register int i;
|
|
register Entry *pent;
|
|
register VisualPtr pVisual = cmap->pVisual;
|
|
register int bitshift = 8;
|
|
u_char rmap[MAX_COLORS], gmap[MAX_COLORS], bmap[MAX_COLORS];
|
|
|
|
if (cmap == pPrivate->installedMap)
|
|
return;
|
|
|
|
bitshift = 16 - cmap->pVisual->bitsPerRGBValue;
|
|
|
|
if (pPrivate->installedMap)
|
|
WalkTree(pPrivate->installedMap->pScreen, TellLostMap,
|
|
(pointer) &(pPrivate->installedMap->mid));
|
|
if ((pVisual->class | DynamicClass) == DirectColor) {
|
|
for (i = 0; i < numColors; i++) {
|
|
pent = &cmap->red[(i & pVisual->redMask) >>
|
|
pVisual->offsetRed];
|
|
rmap[i] = pent->co.local.red >> bitshift;
|
|
pent = &cmap->green[(i & pVisual->greenMask) >>
|
|
pVisual->offsetGreen];
|
|
gmap[i] = pent->co.local.green >> bitshift;
|
|
pent = &cmap->blue[(i & pVisual->blueMask) >>
|
|
pVisual->offsetBlue];
|
|
bmap[i] = pent->co.local.blue >> bitshift;
|
|
}
|
|
} else {
|
|
for (i = 0, pent = cmap->red;
|
|
i < pVisual->ColormapEntries;
|
|
i++, pent++) {
|
|
if (pent->fShared) {
|
|
rmap[i] = pent->co.shco.red->color >> bitshift;
|
|
gmap[i] = pent->co.shco.green->color >> bitshift;
|
|
bmap[i] = pent->co.shco.blue->color >> bitshift;
|
|
}
|
|
else {
|
|
rmap[i] = pent->co.local.red >> bitshift;
|
|
gmap[i] = pent->co.local.green >> bitshift;
|
|
bmap[i] = pent->co.local.blue >> bitshift;
|
|
}
|
|
}
|
|
}
|
|
pPrivate->installedMap = cmap;
|
|
(*pPrivate->UpdateColormap) (cmap->pScreen, 0, numColors, rmap, gmap, bmap);
|
|
WalkTree(cmap->pScreen, TellGainedMap, (pointer) &(cmap->mid));
|
|
}
|
|
|
|
/*-
|
|
*-----------------------------------------------------------------------
|
|
* amigaCUninstallColormap --
|
|
* Uninstall given colormap.
|
|
*
|
|
* Results:
|
|
* None
|
|
*
|
|
* Side Effects:
|
|
* default map is installed
|
|
* All clients requesting ColormapNotify are notified
|
|
*
|
|
*-----------------------------------------------------------------------
|
|
*/
|
|
static void
|
|
amigaCUninstallColormap(cmap)
|
|
ColormapPtr cmap;
|
|
{
|
|
SetupScreen(cmap->pScreen);
|
|
if (cmap == pPrivate->installedMap) {
|
|
Colormap defMapID = cmap->pScreen->defColormap;
|
|
|
|
if (cmap->mid != defMapID) {
|
|
ColormapPtr defMap = (ColormapPtr) LookupIDByType(defMapID,
|
|
RT_COLORMAP);
|
|
|
|
if (defMap)
|
|
(*cmap->pScreen->InstallColormap)(defMap);
|
|
else
|
|
ErrorF("amigaC: Can't find default colormap\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
/*-
|
|
*-----------------------------------------------------------------------
|
|
* amigaCListInstalledColormaps --
|
|
* Fills in the list with the IDs of the installed maps
|
|
*
|
|
* Results:
|
|
* Returns the number of IDs in the list
|
|
*
|
|
* Side Effects:
|
|
* None
|
|
*
|
|
*-----------------------------------------------------------------------
|
|
*/
|
|
/*ARGSUSED*/
|
|
static int
|
|
amigaCListInstalledColormaps(pScreen, pCmapList)
|
|
ScreenPtr pScreen;
|
|
Colormap *pCmapList;
|
|
{
|
|
SetupScreen(pScreen);
|
|
*pCmapList = pPrivate->installedMap->mid;
|
|
return (1);
|
|
}
|
|
|
|
|
|
/*-
|
|
*-----------------------------------------------------------------------
|
|
* amigaCStoreColors --
|
|
* Sets the pixels in pdefs into the specified map.
|
|
*
|
|
* Results:
|
|
* None
|
|
*
|
|
* Side Effects:
|
|
* None
|
|
*
|
|
*-----------------------------------------------------------------------
|
|
*/
|
|
static void
|
|
amigaCStoreColors(pmap, ndef, pdefs)
|
|
ColormapPtr pmap;
|
|
int ndef;
|
|
xColorItem *pdefs;
|
|
{
|
|
SetupScreen(pmap->pScreen);
|
|
u_char rmap[MAX_COLORS], gmap[MAX_COLORS], bmap[MAX_COLORS];
|
|
xColorItem expanddefs[MAX_COLORS];
|
|
register int i;
|
|
register int first = -256;
|
|
register int priv = -256;
|
|
register int count = 0;
|
|
register int bitshift = 8;
|
|
|
|
if (pmap != pPrivate->installedMap)
|
|
return;
|
|
if ((pmap->pVisual->class | DynamicClass) == DirectColor) {
|
|
ndef = afbExpandDirectColors(pmap, ndef, pdefs, expanddefs);
|
|
pdefs = expanddefs;
|
|
}
|
|
|
|
if (pmap->pVisual->redMask == 0xf)
|
|
bitshift = 16 - pmap->pVisual->bitsPerRGBValue;
|
|
|
|
while (ndef--) {
|
|
i = pdefs->pixel;
|
|
|
|
if (i != priv + 1)
|
|
{
|
|
if (count)
|
|
(*pPrivate->UpdateColormap) (pmap->pScreen, first, count, rmap,
|
|
gmap, bmap);
|
|
first = i;
|
|
count = 0;
|
|
}
|
|
priv = i;
|
|
rmap[i] = pdefs->red >> bitshift;
|
|
gmap[i] = pdefs->green >> bitshift;
|
|
bmap[i] = pdefs->blue >> bitshift;
|
|
pdefs++;
|
|
count++;
|
|
}
|
|
if (count)
|
|
(*pPrivate->UpdateColormap) (pmap->pScreen, first, count, rmap, gmap,
|
|
bmap);
|
|
}
|
|
#endif /* AMIGA_CC_COLOR */
|