[comp.windows.x] Clip Masks

battle@alphard.cs.utk.edu (David Battle) (12/15/89)

I would like to create a clip mask from within an application I am writing.
I thought the obvious way would be to create an XImage structure and then
XPutImage it into a depth 1 pixmap.  The only problem is that:

	1) XCreateImage requires a visual which must "match the visual
           of the window [or pixmap, I presume] the image is to be displayed
           in".
	2) My server does not support any depth 1 visuals.
	3) A clip_mask must be a depth 1 pixmap.

Thus, I don't see any way of doing what I want to do.

What I really want to do is the following:

 1) Do an XGetImage from portion of my "main" window (actually a pixmap which
    I use as a backing store for my main window).
 2) *Somehow* create a Pixmap to be used as a clip_mask which is the same size
    as the XImage I got from the main window.  The Pixmap should be depth 1
    and its bits should be set such that for a particular pixel (x,y):
    if XGetImage(ximage, x,y) is equal to "white" then the
    corresponding pixel in the Pixmap is 0.  Otherwise it should be 1.

The whole point of this exercise is to implement something similar to the
lasso in MacPaint.

Here is my best attempt (which does not work):


/* Make a clip mask with 1 bits where any non white pixels occur in
   "image". */

Pixmap MakeClipMask(image, width, height)
XImage *image;
{
    Pixmap clip_mask;
    XImage *tmpimage;
    int white = ClosestColor(0xff,0xff,0xff);  /* typically 255 */
    int i, j;
    char *data;


    data = valloc((width+32)*(height+32));  /* not exactely sure how much
                                               space is needed here but this
                                               should be *plenty*. */
    tmpimage = XCreateImage(display, DefaultVisual(display, screen),
                1, XYBitmap, 0, data, width, height, 32, 0);
    for(i = 0; i < width; i++) {
        for(j = 0; j < height; j++) {
            if(XGetPixel(image, i,j) != white) {
                XPutPixel(tmpimage, i,j, 0);
            }
            else {
                XPutPixel(tmpimage, i,j, 1);
            }
        }
    }
    clip_mask = XCreatePixmap(display, win, width, height, 1);
    XPutImage(display, clip_mask, gc, tmpimage, 0, 0, 0, 0, width, height);
    XDestroyImage(tmpimage);
    return clip_mask;
}


Note that I specify that both clip_mask and tmpimage be depth one.
But aparently that isn't enough; it bombs in XPutImage:

X Protocol error detected by server: parameter mismatch
  Failed request major op code 72 X_PutImage
  Failed request minor op code 0 (if applicable)
  ResourceID 0x0 in failed request (if applicable)
  Serial number of failed request 1110
  Current serial number in output stream 1110


Can someone tell me how this could be done?  

					-David L. Battle
					 battle@battle.esd.ornl.gov
					 battle@utkvx2.BITNET

rws@EXPO.LCS.MIT.EDU (Bob Scheifler) (12/15/89)

	1) XCreateImage requires a visual which must "match the visual
           of the window [or pixmap, I presume] the image is to be displayed
           in".

You can just pass NULL for the visual.  The visual is really only used to
set the red/green/blue_mask components in the image, and those components
are actually never used by Xlib itself.

    XPutImage(display, clip_mask, gc, tmpimage, 0, 0, 0, 0, width, height);

You didn't show the code that created the gc.  My guess is that you created
the gc for the wrong depth, e.g. depth 8 instead of depth 1.

madd@world.std.com (jim frost) (12/15/89)

battle@alphard.cs.utk.edu (David Battle) writes:
>The only problem is that:
>	1) XCreateImage requires a visual which must "match the visual
>           of the window [or pixmap, I presume] the image is to be displayed
>           in".
>	2) My server does not support any depth 1 visuals.
>	3) A clip_mask must be a depth 1 pixmap.

You can create depth 1 pixmaps anyway.  I usually do something like
the following:

  pixmap= XCreatePixmap(disp, RootWindow(disp, scrn), width, height, 1);

Works fine.  Depth 1 is a special case; I'd quote chapter line and
verse but my documentation isn't handy, only my source.

jim frost
jimf@saber.com