xserver-multidpi/hw/xfree86/vgahw/vgaCmap.c

303 lines
7.6 KiB
C

/*
* Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Thomas Roell not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Thomas Roell makes no representations
* about the suitability of this software for any purpose. It is provided
* "as is" without express or implied warranty.
*
* THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THOMAS ROELL BE LIABLE 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 HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#include <X11/X.h>
#include <X11/Xproto.h>
#include "windowstr.h"
#include "compiler.h"
#include "mipointer.h"
#include "micmap.h"
#include "xf86.h"
#include "vgaHW.h"
#define _XF86DGA_SERVER_
#include <X11/extensions/xf86dgastr.h>
#include "dgaproc.h"
#define NOMAPYET (ColormapPtr) 0
int
vgaListInstalledColormaps(pScreen, pmaps)
ScreenPtr pScreen;
Colormap *pmaps;
{
/* By the time we are processing requests, we can guarantee that there
* is always a colormap installed */
*pmaps = miInstalledMaps[pScreen->myNum]->mid;
return(1);
}
int
vgaGetInstalledColormaps(pScreen, pmaps)
ScreenPtr pScreen;
ColormapPtr *pmaps;
{
/* By the time we are processing requests, we can guarantee that there
* is always a colormap installed */
*pmaps = miInstalledMaps[pScreen->myNum];
return(1);
}
int vgaCheckColorMap(ColormapPtr pmap)
{
return (pmap != miInstalledMaps[pmap->pScreen->myNum]);
}
void
vgaStoreColors(pmap, ndef, pdefs)
ColormapPtr pmap;
int ndef;
xColorItem *pdefs;
{
int i;
unsigned char *cmap, *tmp = NULL;
xColorItem directDefs[256];
Bool new_overscan = FALSE;
Bool writeColormap;
/* This can get called before the ScrnInfoRec is installed so we
can't rely on getting it with XF86SCRNINFO() */
int scrnIndex = pmap->pScreen->myNum;
ScrnInfoPtr scrninfp = xf86Screens[scrnIndex];
vgaHWPtr hwp = VGAHWPTR(scrninfp);
unsigned char overscan = hwp->ModeReg.Attribute[OVERSCAN];
unsigned char tmp_overscan = 0;
if (vgaCheckColorMap(pmap))
return;
if ((pmap->pVisual->class | DynamicClass) == DirectColor)
{
ndef = miExpandDirectColors (pmap, ndef, pdefs, directDefs);
pdefs = directDefs;
}
writeColormap = scrninfp->vtSema;
if (DGAAvailable(scrnIndex))
{
writeColormap = writeColormap ||
(DGAGetDirectMode(scrnIndex) &&
!(DGAGetFlags(scrnIndex) & XF86DGADirectColormap)) ||
(DGAGetFlags(scrnIndex) & XF86DGAHasColormap);
}
if (writeColormap)
hwp->enablePalette(hwp);
for(i = 0; i < ndef; i++)
{
if (pdefs[i].pixel == overscan)
{
new_overscan = TRUE;
}
cmap = &(hwp->ModeReg.DAC[pdefs[i].pixel*3]);
if (scrninfp->rgbBits == 8) {
cmap[0] = pdefs[i].red >> 8;
cmap[1] = pdefs[i].green >> 8;
cmap[2] = pdefs[i].blue >> 8;
}
else {
cmap[0] = pdefs[i].red >> 10;
cmap[1] = pdefs[i].green >> 10;
cmap[2] = pdefs[i].blue >> 10;
}
#if 0
if (clgd6225Lcd)
{
/* The LCD doesn't like white */
if (cmap[0] == 63) cmap[0]= 62;
if (cmap[1] == 63) cmap[1]= 62;
if (cmap[2] == 63) cmap[2]= 62;
}
#endif
if (writeColormap)
{
if (hwp->ShowOverscan && i == 255)
continue;
hwp->writeDacWriteAddr(hwp, pdefs[i].pixel);
DACDelay(hwp);
hwp->writeDacData(hwp, cmap[0]);
DACDelay(hwp);
hwp->writeDacData(hwp, cmap[1]);
DACDelay(hwp);
hwp->writeDacData(hwp, cmap[2]);
DACDelay(hwp);
}
}
if (new_overscan && !hwp->ShowOverscan)
{
new_overscan = FALSE;
for(i = 0; i < ndef; i++)
{
if (pdefs[i].pixel == overscan)
{
if ((pdefs[i].red != 0) ||
(pdefs[i].green != 0) ||
(pdefs[i].blue != 0))
{
new_overscan = TRUE;
tmp_overscan = overscan;
tmp = &(hwp->ModeReg.DAC[pdefs[i].pixel*3]);
}
break;
}
}
if (new_overscan)
{
/*
* Find a black pixel, or the nearest match.
*/
for (i=255; i >= 0; i--)
{
cmap = &(hwp->ModeReg.DAC[i*3]);
if ((cmap[0] == 0) && (cmap[1] == 0) && (cmap[2] == 0))
{
overscan = i;
break;
}
else
{
if ((cmap[0] < tmp[0]) &&
(cmap[1] < tmp[1]) && (cmap[2] < tmp[2]))
{
tmp = cmap;
tmp_overscan = i;
}
}
}
if (i < 0)
{
overscan = tmp_overscan;
}
hwp->ModeReg.Attribute[OVERSCAN] = overscan;
if (writeColormap)
{
hwp->writeAttr(hwp, OVERSCAN, overscan);
}
}
}
if (writeColormap)
hwp->disablePalette(hwp);
}
void
vgaInstallColormap(pmap)
ColormapPtr pmap;
{
ColormapPtr oldmap = miInstalledMaps[pmap->pScreen->myNum];
int entries;
Pixel * ppix;
xrgb * prgb;
xColorItem *defs;
int i;
if (pmap == oldmap)
return;
if ((pmap->pVisual->class | DynamicClass) == DirectColor)
entries = (pmap->pVisual->redMask |
pmap->pVisual->greenMask |
pmap->pVisual->blueMask) + 1;
else
entries = pmap->pVisual->ColormapEntries;
ppix = (Pixel *)xalloc( entries * sizeof(Pixel));
prgb = (xrgb *)xalloc( entries * sizeof(xrgb));
defs = (xColorItem *)xalloc(entries * sizeof(xColorItem));
if ( oldmap != NOMAPYET)
WalkTree( pmap->pScreen, TellLostMap, &oldmap->mid);
miInstalledMaps[pmap->pScreen->myNum] = pmap;
for ( i=0; i<entries; i++) ppix[i] = i;
QueryColors( pmap, entries, ppix, prgb);
for ( i=0; i<entries; i++) /* convert xrgbs to xColorItems */
{
defs[i].pixel = ppix[i];
defs[i].red = prgb[i].red;
defs[i].green = prgb[i].green;
defs[i].blue = prgb[i].blue;
defs[i].flags = DoRed|DoGreen|DoBlue;
}
pmap->pScreen->StoreColors(pmap, entries, defs);
WalkTree(pmap->pScreen, TellGainedMap, &pmap->mid);
xfree(ppix);
xfree(prgb);
xfree(defs);
}
void
vgaUninstallColormap(pmap)
ColormapPtr pmap;
{
ColormapPtr defColormap;
if ( pmap != miInstalledMaps[pmap->pScreen->myNum] )
return;
dixLookupResourceByType((pointer *)&defColormap, pmap->pScreen->defColormap,
RT_COLORMAP, serverClient, DixInstallAccess);
if (defColormap == miInstalledMaps[pmap->pScreen->myNum])
return;
(*pmap->pScreen->InstallColormap) (defColormap);
}
void
vgaHandleColormaps(ScreenPtr pScreen, ScrnInfoPtr scrnp)
{
if (scrnp->bitsPerPixel > 1) {
if (scrnp->bitsPerPixel <= 8) { /* For 8bpp SVGA and VGA16 */
pScreen->InstallColormap = vgaInstallColormap;
pScreen->UninstallColormap = vgaUninstallColormap;
pScreen->ListInstalledColormaps = vgaListInstalledColormaps;
pScreen->StoreColors = vgaStoreColors;
}
}
}