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;