multivis.c revision 1233
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * multivis.c - Mechanism for GetImage across Multiple Visuals
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Original author:
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Milind M. Pansare
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Window Systems Group
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Sun Microsystems, Inc.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Revision History:
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * 11-15-90 Written
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh/* Copyright (c) 1990, 2011, Oracle and/or its affiliates. All rights reserved.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Permission is hereby granted, free of charge, to any person obtaining a
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * copy of this software and associated documentation files (the "Software"),
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * to deal in the Software without restriction, including without limitation
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * the rights to use, copy, modify, merge, publish, distribute, sublicense,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * and/or sell copies of the Software, and to permit persons to whom the
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Software is furnished to do so, subject to the following conditions:
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * The above copyright notice and this permission notice (including the next
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * paragraph) shall be included in all copies or substantial portions of the
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Software.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * DEALINGS IN THE SOFTWARE.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic unsigned long mvCompositePixel(unsigned long i, MVColmap *pCmp);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic MVWinVisInfoList winList; /* Here we'll grow a list of windows
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh Sorted back to front */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic MVColmap *colMaps; /* list of colormaps we encounter */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic MVPel *mvImg; /* mvImg is what we compose the image
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic int request_x, request_y; /* The top left of requested
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh rectangle in Root Space */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* UPDATE_HACK */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Initialise the mvLib routines ...
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* UPDATE_HACK */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* Initialise screen info */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* UPDATE_HACK */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Create an Img.. Cleared to zeros.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * returns 0 if failure, non-zero for success.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Note that it is the reponsibility of the caller
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * to verify that any resulting XGetImage will
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * be within the bounds of the screen.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * i.e, x, y, wd, ht must be such that the rectangle
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * is fully within the bounds of the screen.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* Create mvImg */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if ((mvImg = (MVPel *) calloc(sizeof(MVPel), request_width * request_height))
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Reset the mvLib routines
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* Free mvImg */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* Clean winList */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh while (i--) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* Clean colmap list */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Recursively walk the window tree.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Find windows that intersect the requested region.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Create a list of such windows in global winList.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Assumes winList was cleared beforehand.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh int x, int y, /* Top left of requested rectangle in root space */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh Bool ancestorShaped, /* ancestor was a Shaped window */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh Region ancestorRegion /* parent rel. effective Bounding region of ancestors */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh unsigned int nchild;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* compute top-left of image in root space */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh width = min(x+wi, xwa.x+xwa.width+2*xwa.border_width+px)-x1;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh height=min(y+hi, xwa.y+xwa.height+2*xwa.border_width+py)-y1;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* We're interested ... */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (winList.used >= winList.allocated) { /* expand or create the array */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh winList.allocated = (winList.allocated?winList.allocated*MV_WIN_TUNE2:
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh realloc(winList.wins,winList.allocated*sizeof(MVWinVisInfo)):
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pWinInfo->visinfo = mvMatchVisual(XVisualIDFromVisual(xwa.visual));
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* Is it a Shaped Window ? Help ! */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if ((XShapeQueryExtents(mvDpy, win, &bdg, &xb, &yb, &wb, &hb,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if ((wb == 0) || (hb == 0) || (wb > 2000) || (hb > 2000)) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* Empty shape, ignore it */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XShapeGetRectangles(mvDpy, win, ShapeBounding, &count, &ordering);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh while (count--) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XUnionRectWithRegion(rect++, pWinInfo->region, pWinInfo->region);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh tmprct.width = pWinInfo->width; tmprct.height = pWinInfo->height;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XIntersectRegion(pWinInfo->region, tmpreg, pWinInfo->region);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* make a local copy */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XUnionRegion(tmpancestorRegion, ancestorRegion, tmpancestorRegion);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* Translate from relative parent's origin to this window's origin */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XOffsetRegion(tmpancestorRegion, -(xwa.x + xwa.border_width),
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XIntersectRegion(tmpancestorRegion, pWinInfo->region, pWinInfo->region);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XUnionRegion(tmpancestorRegion, pWinInfo->region, pWinInfo->region);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh tmprct.width = pWinInfo->width; tmprct.height = pWinInfo->height;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XIntersectRegion(pWinInfo->region, tmpreg, pWinInfo->region);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* Find children, back to front */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (XQueryTree(mvDpy, win, &root, &parent, &children, &nchild)) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh for (n=0; n<nchild; n++) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh x1, y1, width, height, (ancestorShaped || isShaped),
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#else /* !SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* free children */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Returns 0 if no problems,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Returns 1 if depths differ
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * returns 2 if colormap or visinfo differ
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * NOTE that this chenge & the previous change are reprehensible hacks,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * to let xmag work with pageview, and xcolor respectively.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * USED TO BE...
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Returns 0 if no problems,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Returns 1 if visinfo or depth differ
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * returns 2 if colormap only differ
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * USED TO BE...
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Returns non-zero if the winList created by mvWalkTree
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * might potentially have windows of different Visuals
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * else returns 0
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh while (i--) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (winList.wins[i].visinfo != winList.wins[0].visinfo)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (winList.wins[i].colmap != winList.wins[0].colmap)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Traverse the window list front to back. Get the entire Image
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * from each window, but only Label a pixel in the Img once.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * That is, once a pixel has been Labeled, any more fetches
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * from the same pixel position are discarded. Once all pixels
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * positions have been fetched, we're done. This will eliminate
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * windows that have nothing to contibute to the requested region,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * but will nevertheless have the problem of the painters
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * algorithm, where more pixels were fetched from a
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * window than were essential.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Assumes that winList has been filled beforehand, and Img was cleared.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh int nPixelsUnLabeled = request_width*request_height;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh for (i=winList.used-1; ((nPixelsUnLabeled > 0) && i >= 0); i--) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (!(xim = XGetImage(mvDpy, pWI->window, pWI->x, pWI->y, pWI->width,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* For each pixel in the returned Image */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* UPDATE_HACK */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh MVPel *pPel = mvFindPel(xi+pWI->x1-request_x, yi+pWI->y1-request_y);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* If the pixel hasn't been labelled before */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (!pPel->colmap) { /* pPel->colmap serves as a 'Label' */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* label the pixel in the map with this window's cmap */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * If Pixel value can be discarded, this is where
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * you get the RGB value instead.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Call a routine like mvFindColorInColormap() with the pixel
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * value, and Colormap as parameters.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * The 'Label', instead of pPel->colmap could be a scratch bit ?
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * But if its a full 32 bit pixel, and there are no
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * free bits, you need to hang in extra bits somewhere.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Maybe a bitmask associated with Img ?
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh (pWI->region && (XPointInRegion(pWI->region, xi+pWI->x, yi+pWI->y))
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh && (XPointInRegion(pWI->region, xi+pWI->x+1, yi+pWI->y))
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh && (XPointInRegion(pWI->region, xi+pWI->x, yi+pWI->y+1))
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh && (XPointInRegion(pWI->region, xi+pWI->x+1, yi+pWI->y+1))
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* XNEWS */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* and pixel value */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* free image */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Get all the colors from this window's colormap.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * That's slightly complicated when we hit
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * a true color or direct color visual.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Assumes that a global list of colmaps is present, and
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * that the Colors field was NULLed beforehand.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (!pWI->colmap->Colors) { /* This is the first time we're visiting */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* Allocate enough memory */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pCmp->Colors = pCol = (XColor *)calloc((sizeof(XColor)), size);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (pVis->class == TrueColor || pVis->class == DirectColor) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh unsigned long i;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* We have to create a composite pixel value */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh for (i = 0; i < (unsigned long)(size);i++, pCol++) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh unsigned long i;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* Fill in the pixel values by hand */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh for (i = 0; i < (unsigned long)(size);) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XQueryColors(mvDpy, pCmp->cmap, pCmp->Colors, size);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Given a VisualID, return a pointer to the VisualInfo structure.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Assumes that a global mvVlist for this screen has already
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * been created. Uses globals mvNumVis, and mvVlist.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Returns NULL if the vid is not matched.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Calculate a composite pixel value that indexes into all
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * three primaries . Assumes Composite Calcs have been performed
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * already on the colmap.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic unsigned long
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh unsigned long val = 0;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Calculate the offsets used to composite a pixel value for
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * the TrueColor & DirectColor cases
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Assumes its called only on a True or DirectColor visual.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* Check if this has been done before */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* These are the sizes of each primary map ... */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Calculate number of 1 bits in mask
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Classic hack not written by this author.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh unsigned long y;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Calculate the number of shifts till we hit the mask
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * find & creat a colmap struct for this cmap
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Assumes that colMaps was cleared before the first time
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * it is called.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* if we've seen this cmap before, return its struct colmap */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* First time for this cmap, creat & link */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Use pixel value at x, y as an index into
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * the colmap's list of Colors.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * If the pixel value were not important, this would be called
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * in mvDoWindowsFrontToBack(), with the pixel value
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * and colmap as parameters, to get RGB values directly.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (pCmap->doComposite) { /* This is either True or DirectColor */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* Treat the pixel value as 3 separate indices, composite
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh the color into scratch, return a pointer to scratch */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh unsigned long index = (pix & pCmap->red_mask) >> pCmap->rshft;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh scratch.red=pCmap->Colors[(pix & pCmap->red_mask)>>pCmap->rshft].red;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh scratch.green=pCmap->Colors[(pix & pCmap->green_mask)>>pCmap->gshft].green;