[comp.windows.x] miSprite & DirectColor

furr@mdavcr.UUCP (Steven Furr) (11/13/90)

I have been working on a 24 bit server with a DirectColor
root visual and encountered a problem with the colour of the
cursor in this configuration (it works fine for a TrueColor
visual).  The cursor was displayed as white for both source
and mask colours.

After some investigation, I determined that miSpriteFindColors
was not getting the correct pixel from FakeAllocColor (in DIX).  As a
result I changed FakeAllocColor for DirectColor as shown below
and everything worked fine.

*** colormap.c.orig	Fri Nov  9 13:40:50 1990
--- colormap.c	Fri Nov  9 17:11:24 1990
***************
*** 810,829 ****
--- 810,830 ----
  	pixR = (*pPix & pVisual->redMask) >> pVisual->offsetRed; 
  	pixG = (*pPix & pVisual->greenMask) >> pVisual->offsetGreen; 
  	pixB = (*pPix & pVisual->blueMask) >> pVisual->offsetBlue; 
  	if (FindColor(pmap, pmap->red, entries, &rgb, &pixR, REDMAP,
  		      -1, RedComp) == Success &&
  	    FindColor(pmap, pmap->green, entries, &rgb, &pixG, GREENMAP,
  		      -1, GreenComp) == Success &&
  	    FindColor(pmap, pmap->blue, entries, &rgb, &pixB, BLUEMAP,
  		      -1, BlueComp) == Success)
  	{
+             *pPix = pixR | pixG | pixB;
  	    break;
  	}
  	/* fall through ... */
      case TrueColor:
  	/* Look up each component in its own map, then OR them together */
  	pixR = FindBestPixel(pmap->red, entries, &rgb, REDMAP);
  	pixG = FindBestPixel(pmap->green, entries, &rgb, GREENMAP);
  	pixB = FindBestPixel(pmap->blue, entries, &rgb, BLUEMAP);
  	*pPix = (pixR << pVisual->offsetRed) |
  		(pixG << pVisual->offsetGreen) |

----

It seems that there hasn't been much attention paid to DirectColor visuals
in general as miSpriteStoreColors doesn't even attempt to handle DirectColor
pixel values correctly.  I have modified this as well and the diff is
given below.  This brings me to my concern regarding the cursor display and
sprite code in general.  There is no provision in the sample server for
providing machine/device specific implementations of display cursor or
sprite code.  It would be nice to have display cursor hooks and/or sprite
hooks to hang all of the function addresses from.  As things stand you
must entirely replace midispcur.c and misprite.c to accomplish this because
both of these modules declare all of their functions as static.

I think a good case can be made for this because the sprite code must make
some potentially unwarranted assumptions about the implementation of a number
of device-specific functions in order to work.  For example, the sprite code
always uses the most recently installed colormap to display the cursor, in
spite of the fact that the server could support multiple installed colormaps.
I would like to alter this slightly for my device.

I am supporting a 24 bit DirectColor visual with 8 bits of overlay.
This requires having 2 installed colormaps and the server has to be slightly
tricky in handling them.  An extension allows the user to define a colormap
as an overlay colormap and it is installed like any other, except that the
colormap belongs to a DirectColor visual, but must be treated like a
PseudoColor colormap.  For this reason, I would rather not have the sprite
code use this colormap for the cursor at all, since there seems to be some
inconsistency in the use of pMap->class versus pVisual->class.

The modification to misprite.c follows:

*** ,misprite.c	Fri Dec  8 15:28:03 1989
--- misprite.c	Fri Nov  9 17:12:54 1990
***************
*** 498,530 ****
      pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
  
      SCREEN_PROLOGUE(pScreen, StoreColors);
      
      (*pScreen->StoreColors) (pMap, ndef, pdef);
  
      SCREEN_EPILOGUE(pScreen, StoreColors, miSpriteStoreColors);
  
      if (pPriv->pColormap == pMap)
      {
  	for (i = 0; i < ndef; i++)
  	    /*
  	     * XXX direct color will affect pixels other than
  	     * pdef[i].pixel -- this will be more difficult...
  	     */
! 	    if (pdef[i].pixel == pPriv->colors[SOURCE_COLOR].pixel ||
! 	        pdef[i].pixel == pPriv->colors[MASK_COLOR].pixel)
  	    {
! 		pPriv->checkPixels = TRUE;
! 		if (pPriv->isUp && pPriv->shouldBeUp)
! 		    miSpriteRemoveCursor (pScreen);
! 		break;
  	    }
      }
  }
  
  static void
  miSpriteFindColors (pScreen)
      ScreenPtr	pScreen;
  {
      miSpriteScreenPtr	pScreenPriv = (miSpriteScreenPtr)
  			    pScreen->devPrivates[miSpriteScreenIndex].ptr;
      CursorPtr		pCursor;
--- 498,559 ----
      pPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr;
  
      SCREEN_PROLOGUE(pScreen, StoreColors);
      
      (*pScreen->StoreColors) (pMap, ndef, pdef);
  
      SCREEN_EPILOGUE(pScreen, StoreColors, miSpriteStoreColors);
  
      if (pPriv->pColormap == pMap)
      {
+         register VisualPtr pVisual = pMap->pVisual;
+         register Bool invalidate_cursor = FALSE;
  	for (i = 0; i < ndef; i++)
+         {
  	    /*
  	     * XXX direct color will affect pixels other than
  	     * pdef[i].pixel -- this will be more difficult...
  	     */
!             if (pMap->class == DirectColor)
!             {
!                /*  We could also check the values of DoRed, DoGreen, DoBlue
!                 *  but doing this every time might be more expensive than
!                 *  occassionally invalidating the cursor unnecessarily.
!                 */
! 	       if ((pdef[i].pixel && pVisual->redMask) ==
!                    (pPriv->colors[SOURCE_COLOR].pixel && pVisual->redMask) ||
! 	           (pdef[i].pixel && pVisual->greenMask) ==
!                    (pPriv->colors[SOURCE_COLOR].pixel && pVisual->greenMask) ||
! 	           (pdef[i].pixel && pVisual->blueMask) ==
!                    (pPriv->colors[SOURCE_COLOR].pixel && pVisual->blueMask) ||
! 	           (pdef[i].pixel && pVisual->redMask) ==
!                    (pPriv->colors[MASK_COLOR].pixel && pVisual->redMask) ||
! 	           (pdef[i].pixel && pVisual->greenMask) ==
!                    (pPriv->colors[MASK_COLOR].pixel && pVisual->greenMask) ||
! 	           (pdef[i].pixel && pVisual->blueMask) ==
!                    (pPriv->colors[MASK_COLOR].pixel && pVisual->blueMask))
!                   invalidate_cursor = TRUE;
!             }
!             else
!             {
! 	       if (pdef[i].pixel == pPriv->colors[SOURCE_COLOR].pixel ||
! 	           pdef[i].pixel == pPriv->colors[MASK_COLOR].pixel)
!                   invalidate_cursor = TRUE;
!             }
! 	    if (invalidate_cursor)
  	    {
! 	       pPriv->checkPixels = TRUE;
! 	       if (pPriv->isUp && pPriv->shouldBeUp)
! 	           miSpriteRemoveCursor (pScreen);
!                break;
  	    }
+         }
      }
  }
  
  static void
  miSpriteFindColors (pScreen)
      ScreenPtr	pScreen;
  {
      miSpriteScreenPtr	pScreenPriv = (miSpriteScreenPtr)
  			    pScreen->devPrivates[miSpriteScreenIndex].ptr;
      CursorPtr		pCursor;