XShape example?
Matt Garman
garman at raw-sewage.net
Sat Oct 29 01:42:53 PDT 2005
On Sat, Oct 29, 2005 at 01:38:59PM +0900, Carsten Haitzler wrote:
> On Fri, 28 Oct 2005 23:20:17 -0500 Matt Garman
> <garman at raw-sewage.net> babbled:
> > eyes looks as though it's transparent). [BTW, I know it's not true
> > transparency, but as long as it *looks* transparent, that's good
> > enough for me.]
>
> it is true transparency. no pixels exist in the "shaped out" areas
> - you see right through it - events go through the holes too. its
> the oldes form of transparency x has - but effectively only
> provides 1 bit of accuracy :) (i wont go into how its implemented
> with rectangle lists) :)
Ahh, now that I have a working example, I see that it is in fact
true transparency.
When you say that this is the "oldest form of transparency x has",
does that imply there are *better* ways of doing transparency?
As a general disclaimer, I'm just getting into Xlib programming, so
it's safe to assume total ignorance on my part!
> see where you draw the rectangles - you want to ALSO draw them to
> the shape pixmap and combine that shape pixmap (again) as when you
> SET the shape its SEPARATe from the pixel contents of the window.
> you set up a blank shape (nothing in it). you want to fill it with
> 1 rects of value "1" (0 == blank in the mask, 1 = visible). you
> can also set the shape rectangles directly if that tickles your
> fancy :)
You are a godsend, thank you so much! I've been struggling with
this for so long now (does this stuff take a while for everybody?
Man, I hope so, and please don't say otherwise if only for my ego!).
Anyway, I have a working version of the program now. I'm not sure
if I'm doing it 100% correctly, but it does work as advertised!
I'll take that as a victory, given the amount of time I've spent
trying to get it to work (and not knowing where to get additional
information).
I've attached the little sample program below; hopefully it will be
useful for posterity (if nothing else!).
Thanks again!
Matt
--
Matt Garman
email at: http://raw-sewage.net/index.php?file=email
/* This program creates a transparent window (using the XShape
* extension) and draw four white (opaque) squares in each corner of
* the window
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <unistd.h>
#include <X11/Xutil.h>
#include <X11/extensions/shape.h>
/* size of the window */
#define W_WIDTH 640
#define W_HEIGHT 480
/* size of the four rectangles that will be drawn in the window */
#define R_WIDTH 80
#define R_HEIGHT 60
/* the four rectangles that will be drawn: one in each corner of the
* window */
XRectangle rectangles[4] =
{
{ 0, 0, R_WIDTH, R_HEIGHT },
{ 0, W_HEIGHT-R_HEIGHT, R_WIDTH, R_HEIGHT },
{ W_WIDTH-R_WIDTH, W_HEIGHT-R_HEIGHT, R_WIDTH, R_HEIGHT },
{ W_WIDTH-R_WIDTH, 0, R_WIDTH, R_HEIGHT }
};
int main(int argc, char **argv)
{
Display *dpy;
Window w;
Pixmap pmap;
GC shape_gc;
GC win_gc;
XGCValues xgcv;
int run = 1; /* loop control variable */
/* open the display */
if(!(dpy = XOpenDisplay(getenv("DISPLAY")))) {
fprintf(stderr, "can't open display\n");
return EXIT_FAILURE;
}
/* create the window */
w = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, W_WIDTH,
W_HEIGHT, 0, CopyFromParent, InputOutput,
CopyFromParent, 0, NULL);
/* create a graphics context for drawing on the window */
xgcv.foreground = WhitePixel(dpy, DefaultScreen(dpy));
xgcv.line_width = 1;
xgcv.line_style = LineSolid;
win_gc = XCreateGC(dpy, w,
GCForeground | GCLineWidth | GCLineStyle, &xgcv);
/* create the pixmap that we'll use for shaping the window */
pmap = XCreatePixmap(dpy, w, W_WIDTH, W_HEIGHT, 1);
/* create a graphics context for drawing on the pixmap */
shape_gc = XCreateGC(dpy, pmap, 0, &xgcv);
/* register events: ExposureMask for re-drawing, ButtonPressMask
* to capture mouse button press events */
XSelectInput(dpy, w, ButtonPressMask | StructureNotifyMask);
XMapWindow(dpy, w);
XSync(dpy, False);
while(run) {
XEvent xe;
XNextEvent(dpy, &xe);
switch (xe.type) {
case ConfigureNotify:
printf("ConfigureNotify\n");
/* whenever we get an expose, draw the rectangles */
XSetForeground(dpy, shape_gc, 0);
XFillRectangle(dpy, pmap, shape_gc, 0, 0, W_WIDTH,
W_HEIGHT);
XSetForeground(dpy, shape_gc, 1);
XDrawRectangles(dpy, pmap, shape_gc, rectangles, 4);
XFillRectangles(dpy, pmap, shape_gc, rectangles, 4);
XSetForeground(dpy, win_gc, WhitePixel(dpy,
DefaultScreen(dpy)));
XDrawRectangles(dpy, w, win_gc, rectangles, 4);
XFillRectangles(dpy, w, win_gc, rectangles, 4);
XShapeCombineMask (dpy, w, ShapeBounding,
0, 0, pmap, ShapeSet);
XSync(dpy, False);
break;
case ButtonPress: /* quit if a button is pressed */
printf("ButtonPress\n");
run = 0;
break;
default:
printf("Caught event %i\n", xe.type);
}
}
XFreePixmap(dpy, pmap);
XDestroyWindow(dpy, w);
XCloseDisplay(dpy);
return 0;
}
More information about the xorg
mailing list