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