304 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			304 lines
		
	
	
		
			7.7 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.
 | 
						|
 *
 | 
						|
 */
 | 
						|
/* $XConsortium: vgaCmap.c /main/15 1996/10/28 05:13:44 kaleb $ */
 | 
						|
 | 
						|
 | 
						|
#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 *)ALLOCATE_LOCAL( entries * sizeof(Pixel));
 | 
						|
  prgb = (xrgb *)ALLOCATE_LOCAL( entries * sizeof(xrgb));
 | 
						|
  defs = (xColorItem *)ALLOCATE_LOCAL(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);
 | 
						|
  
 | 
						|
  DEALLOCATE_LOCAL(ppix);
 | 
						|
  DEALLOCATE_LOCAL(prgb);
 | 
						|
  DEALLOCATE_LOCAL(defs);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void
 | 
						|
vgaUninstallColormap(pmap)
 | 
						|
     ColormapPtr pmap;
 | 
						|
{
 | 
						|
 | 
						|
  ColormapPtr defColormap;
 | 
						|
  
 | 
						|
  if ( pmap != miInstalledMaps[pmap->pScreen->myNum] )
 | 
						|
    return;
 | 
						|
 | 
						|
  defColormap = (ColormapPtr) LookupIDByType( pmap->pScreen->defColormap,
 | 
						|
					      RT_COLORMAP);
 | 
						|
 | 
						|
  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;
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 |