multivis.c revision 1233
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh/*-
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * multivis.c - Mechanism for GetImage across Multiple Visuals
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh *
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Original author:
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Milind M. Pansare
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Window Systems Group
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Sun Microsystems, Inc.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh *
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Revision History:
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * 11-15-90 Written
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh/* Copyright (c) 1990, 2011, Oracle and/or its affiliates. All rights reserved.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh *
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 *
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 *
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 */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#include <stdlib.h>
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#include <X11/Xlib.h>
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#include <X11/Xutil.h>
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#ifdef SHAPE
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#include <X11/extensions/shape.h>
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#include "multivis.h"
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic MVColmap *mvFindColormap(Colormap cmap);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic XVisualInfo *mvMatchVisual(VisualID vid);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic void mvGetColormap(MVWinVisInfo *pWI);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic void mvCalculateComposite(MVWinVisInfo *pWI);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic unsigned long mvCompositePixel(unsigned long i, MVColmap *pCmp);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic Display *mvDpy; /* Display */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic int mvScreen; /* Screen */
dd69425007680aafc47fdd994e1985625571d252brycestatic XVisualInfo *mvVlist; /* List of Visuals */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic int mvNumVis; /* Number of visuals in list */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#ifdef SHAPE
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic Bool mvShape; /* Shape extension ? */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic MVWinVisInfoList winList; /* Here we'll grow a list of windows
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh Sorted back to front */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic MVColmap *colMaps; /* list of colormaps we encounter */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic MVPel *mvImg; /* mvImg is what we compose the image
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh into */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic int request_width,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh request_height; /* size of requested rectangle */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic int request_x, request_y; /* The top left of requested
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh rectangle in Root Space */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#ifdef UPDATE_HACK
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic void *mvCallbackData;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic mvCallbackFunc mvCallbackFunction;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* UPDATE_HACK */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh/*
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Initialise the mvLib routines ...
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh*/
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshvoid
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#ifdef UPDATE_HACK
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshmvInit(
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh Display *dpy,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh int screen,
d444ed610362dab3c3e727d1b110312318b84cb8miklosh XVisualInfo *vlist,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh int num_vis,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh void *callbackData,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh mvCallbackFunc callbackFunction)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#else
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshmvInit(
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh Display *dpy,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh int screen,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XVisualInfo *vlist,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh int num_vis)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* UPDATE_HACK */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh{
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#ifdef SHAPE
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh int tmp;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* Initialise screen info */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh mvDpy = dpy;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh mvScreen = screen;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh mvVlist = vlist;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh mvNumVis = num_vis;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#ifdef SHAPE
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh mvShape = XShapeQueryExtension(dpy, &tmp, &tmp);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#ifdef UPDATE_HACK
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh mvCallbackData = callbackData;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh mvCallbackFunction = callbackFunction;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* UPDATE_HACK */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh}
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh/*
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*/
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshint
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshmvCreatImg(int wd, int ht, int x, int y)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh{
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* Create mvImg */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh request_width = wd;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh request_height = ht;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh request_x = x;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh request_y = y;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if ((mvImg = (MVPel *) calloc(sizeof(MVPel), request_width * request_height))
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh != NULL) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh return 1;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh return 0;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh}
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh/*
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Reset the mvLib routines
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh*/
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshvoid
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshmvReset(void)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh{
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#ifdef SHAPE
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh int i;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* Free mvImg */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (mvImg)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh free(mvImg);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* Clean winList */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (winList.wins) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#ifdef SHAPE
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh i = winList.used;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh while (i--) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (winList.wins[i].region)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XDestroyRegion(winList.wins[i].region);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh free(winList.wins);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh winList.wins = NULL;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh winList.used = winList.allocated = 0;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* Clean colmap list */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh while (colMaps) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh MVColmap *pCmap;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pCmap = colMaps;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh colMaps = pCmap->next;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (pCmap->Colors)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh free(pCmap->Colors);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh free(pCmap);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh}
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh/*
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*/
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshvoid
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshmvWalkTree(
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh Window win, /* This window */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh int px, int py, /* parent's origin in root space */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh int x, int y, /* Top left of requested rectangle in root space */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh int wi, int hi, /* size of requested rectangle */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#ifdef SHAPE
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh Bool ancestorShaped, /* ancestor was a Shaped window */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh Region ancestorRegion /* parent rel. effective Bounding region of ancestors */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh )
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh{
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XWindowAttributes xwa;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh int width, height, x1, y1;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh Window root, parent, *children;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh int n;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh unsigned int nchild;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh MVWinVisInfo *pWinInfo;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#ifdef SHAPE
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh Bool isShaped = False;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh Bool bdg, clp;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh int xb, yb, xc, yc;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh unsigned int wb, hb, wc, hc;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh int count, ordering;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh Region tmpancestorRegion, tmpreg;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XRectangle *rects, *rect, tmprct;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (!XGetWindowAttributes(mvDpy, win, &xwa)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh || xwa.map_state != IsViewable
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh || xwa.class == InputOnly) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh return;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* compute top-left of image in root space */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh x1 = max(x, xwa.x+px);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh y1 = max(y, xwa.y+py);
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
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (width <=0 || height <= 0) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh return;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* We're interested ... */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (winList.used >= winList.allocated) { /* expand or create the array */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh winList.allocated = (winList.allocated?winList.allocated*MV_WIN_TUNE2:
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh MV_WIN_TUNE1);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh winList.wins = (MVWinVisInfo *)(winList.wins ?
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh realloc(winList.wins,winList.allocated*sizeof(MVWinVisInfo)):
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh malloc(winList.allocated*sizeof(MVWinVisInfo)));
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pWinInfo = &(winList.wins[winList.used++]);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pWinInfo->window = win;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pWinInfo->depth = xwa.depth;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pWinInfo->visinfo = mvMatchVisual(XVisualIDFromVisual(xwa.visual));
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pWinInfo->colmap = mvFindColormap(xwa.colormap);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pWinInfo->x = x1-xwa.border_width-xwa.x-px;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pWinInfo->y = y1-xwa.border_width-xwa.y-py;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pWinInfo->width = width;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pWinInfo->height = height;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pWinInfo->x1 = x1;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pWinInfo->y1 = y1;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#ifdef SHAPE
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pWinInfo->region = NULL;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* Is it a Shaped Window ? Help ! */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if ((XShapeQueryExtents(mvDpy, win, &bdg, &xb, &yb, &wb, &hb,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh &clp, &xc, &yc, &wc, &hc)) && bdg) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if ((wb == 0) || (hb == 0) || (wb > 2000) || (hb > 2000)) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* Empty shape, ignore it */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh winList.used--;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh return;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh isShaped = True;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pWinInfo->region = XCreateRegion();
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh rect = rects =
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XShapeGetRectangles(mvDpy, win, ShapeBounding, &count, &ordering);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh while (count--) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XUnionRectWithRegion(rect++, pWinInfo->region, pWinInfo->region);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (rects != NULL) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XFree((caddr_t)rects);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh tmpreg = XCreateRegion();
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh tmprct.x = pWinInfo->x; tmprct.y = pWinInfo->y;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh tmprct.width = pWinInfo->width; tmprct.height = pWinInfo->height;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XUnionRectWithRegion(&tmprct, tmpreg, tmpreg);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XIntersectRegion(pWinInfo->region, tmpreg, pWinInfo->region);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XDestroyRegion(tmpreg);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (ancestorShaped) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* make a local copy */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh tmpancestorRegion = XCreateRegion();
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 -(xwa.y + xwa.border_width));
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (isShaped) { /* Compute effective bdg shape */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XIntersectRegion(tmpancestorRegion, pWinInfo->region, pWinInfo->region);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh else {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pWinInfo->region = XCreateRegion();
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XUnionRegion(tmpancestorRegion, pWinInfo->region, pWinInfo->region);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh tmpreg = XCreateRegion();
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh tmprct.x = pWinInfo->x; tmprct.y = pWinInfo->y;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh tmprct.width = pWinInfo->width; tmprct.height = pWinInfo->height;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XUnionRectWithRegion(&tmprct, tmpreg, tmpreg);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XIntersectRegion(pWinInfo->region, tmpreg, pWinInfo->region);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XDestroyRegion(tmpreg);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XDestroyRegion(tmpancestorRegion);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* Find children, back to front */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (XQueryTree(mvDpy, win, &root, &parent, &children, &nchild)) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#ifdef SHAPE
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh tmpreg = pWinInfo->region;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh for (n=0; n<nchild; n++) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#ifdef SHAPE
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh mvWalkTree(children[n], px+xwa.x+xwa.border_width,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh py+xwa.y+xwa.border_width,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh x1, y1, width, height, (ancestorShaped || isShaped),
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh tmpreg);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#else /* !SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh mvWalkTree(children[n], px+xwa.x+xwa.border_width,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh py+xwa.y+xwa.border_width,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh x1, y1, width, height);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* free children */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (nchild > 0)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XFree((caddr_t)children);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh return;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh}
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh/*
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * CHANGE
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 * CHANGE
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*/
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshint
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshmvIsMultiVis(void)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh{
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh int retcode = 0;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh int i = winList.used;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh while (i--) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if(winList.wins[i].depth != winList.wins[0].depth)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh return 1;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (winList.wins[i].visinfo != winList.wins[0].visinfo)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh retcode = 2;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (winList.wins[i].colmap != winList.wins[0].colmap)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh retcode = 2;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh return retcode;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh}
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh/*
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*/
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshvoid
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshmvDoWindowsFrontToBack(void)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh{
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh int i;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh MVWinVisInfo *pWI;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XImage *xim;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh int xi, yi;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh int nPixelsUnLabeled = request_width*request_height;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh for (i=winList.used-1; ((nPixelsUnLabeled > 0) && i >= 0); i--) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pWI = &(winList.wins[i]);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (!(xim = XGetImage(mvDpy, pWI->window, pWI->x, pWI->y, pWI->width,
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pWI->height, (~0), ZPixmap))) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh return;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh mvGetColormap(pWI);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* For each pixel in the returned Image */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh for (yi = 0; yi < pWI->height; yi++) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#ifdef UPDATE_HACK
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if ((yi % 128) == 0) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh (*mvCallbackFunction)(mvCallbackData);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* UPDATE_HACK */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh for (xi = 0; xi < pWI->width; xi++) {
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 /*
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 */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#ifdef SHAPE
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (!(pWI->region) ||
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh (pWI->region && (XPointInRegion(pWI->region, xi+pWI->x, yi+pWI->y))
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#ifdef XNEWS
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 )
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh ) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pPel->colmap = pWI->colmap;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* and pixel value */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pPel->pixel = XGetPixel(xim, xi, yi);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh nPixelsUnLabeled--;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#ifdef SHAPE
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh#endif /* SHAPE */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* free image */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XDestroyImage(xim);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh}
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh/*
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*/
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic void
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshmvGetColormap(MVWinVisInfo *pWI)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh{
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (!pWI->colmap->Colors) { /* This is the first time we're visiting */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh MVColmap *pCmp = pWI->colmap;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XVisualInfo *pVis = pWI->visinfo;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XColor *pCol;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh int size = pVis->colormap_size;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
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 mvCalculateComposite(pWI);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh for (i = 0; i < (unsigned long)(size);i++, pCol++) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pCol->pixel = mvCompositePixel(i, pCmp);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh else {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh unsigned long i;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* Fill in the pixel values by hand */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh for (i = 0; i < (unsigned long)(size);) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pCol++->pixel = i++;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XQueryColors(mvDpy, pCmp->cmap, pCmp->Colors, size);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh}
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh/*
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*/
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic XVisualInfo *
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshmvMatchVisual(VisualID vid)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh{
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XVisualInfo *pVis = mvVlist;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh while (pVis < (mvVlist+mvNumVis)) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (vid == pVis->visualid) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh return pVis;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pVis++;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh return NULL;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh}
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh/*
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Calculate a composite pixel value that indexes into all
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * three primaries . Assumes Composite Calcs have been performed
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * already on the colmap.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh*/
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic unsigned long
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshmvCompositePixel(unsigned long i, MVColmap *pCmp)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh{
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh unsigned long val = 0;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (i < pCmp->rmax) val |= i << pCmp->rshft;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (i < pCmp->gmax) val |= i << pCmp->gshft;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (i < pCmp->bmax) val |= i << pCmp->bshft;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh return val;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh}
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh/*
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*/
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic void
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshmvCalculateComposite(MVWinVisInfo *pWI)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh{
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh MVColmap *pCmp = pWI->colmap;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh XVisualInfo *pVis = pWI->visinfo;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* Check if this has been done before */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (!pCmp->doComposite) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pCmp->doComposite = True;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* These are the sizes of each primary map ... */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pCmp->red_mask = pVis->red_mask;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pCmp->green_mask = pVis->green_mask;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pCmp->blue_mask = pVis->blue_mask;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pCmp->rmax = 1 << mvOnes(pVis->red_mask);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pCmp->gmax = 1 << mvOnes(pVis->green_mask);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pCmp->bmax = 1 << mvOnes(pVis->blue_mask);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pCmp->rshft = mvShifts(pVis->red_mask);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pCmp->gshft = mvShifts(pVis->green_mask);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pCmp->bshft = mvShifts(pVis->blue_mask);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pCmp->rgbshft = (16 - pVis->bits_per_rgb);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh}
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh/*
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Calculate number of 1 bits in mask
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Classic hack not written by this author.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh*/
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshint
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshmvOnes(unsigned long mask)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh{
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh unsigned long y;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh y = (mask >> 1) &033333333333;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh y = mask - y - ((y >> 1) & 033333333333);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh return (((y + (y >> 3)) & 030707070707) % 077);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh}
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh/*
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Calculate the number of shifts till we hit the mask
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh*/
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshint
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshmvShifts(unsigned long mask)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh{
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh int y = 0;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (mask) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh while(!(mask&0x1)) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh mask = mask >> 1;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh y++;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh return y;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh}
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh/*
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * find & creat a colmap struct for this cmap
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * Assumes that colMaps was cleared before the first time
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh * it is called.
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh*/
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshstatic MVColmap *
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshmvFindColormap(Colormap cmap)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh{
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh MVColmap *pCmap;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* if we've seen this cmap before, return its struct colmap */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh for (pCmap = colMaps; pCmap; pCmap = pCmap->next) {
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh if (cmap == pCmap->cmap)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh return pCmap;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh /* First time for this cmap, creat & link */
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pCmap = (MVColmap *) calloc(sizeof(MVColmap), 1);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pCmap->next = colMaps;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh pCmap->cmap = cmap;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh colMaps = pCmap;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh return pCmap;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh}
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh/*
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*/
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshXColor *
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6mikloshmvFindColorInColormap(int x, int y)
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh{
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh MVPel *pPel = mvFindPel(x, y);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh MVColmap *pCmap = pPel->colmap;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh static XColor scratch;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh
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 pix = pPel->pixel;
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;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh scratch.blue=pCmap->Colors[(pix & pCmap->blue_mask)>>pCmap->bshft].blue;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh scratch.pixel=pix;
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh return(&scratch);
b7f07692f95074fdcf74c7350fbf5f3099ffc1b6miklosh }
else { /* This is simple */
return &(pCmap->Colors[pPel->pixel]);
}
}