XShape example?

Carsten Haitzler (The Rasterman) raster at rasterman.com
Sat Oct 29 02:34:53 PDT 2005


On Sat, 29 Oct 2005 03:42:53 -0500 Matt Garman <garman at raw-sewage.net> babbled:

> 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?

xcomposite +compositing manager +xrender +32bit visuals. - but only supported
in the absolute latest and even then buggy/iffy and may be dead slow. not
something i would RELY on yet.

> As a general disclaimer, I'm just getting into Xlib programming, so
> it's safe to assume total ignorance on my part!

use shape first. u dont want to know fo the complexity of the other stuff yet :)

> > 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!).

i've been doing xlib stuff for about 9 years now. iu still learn new stuff
every day i didn't know :) writign a wm teaches u a lot fo xlib - fast, via the
"way of pain". writing a toolkit (gtk/qt) is the other "way of pain" to
learn :) somewhere betwene tooplkit authors and wm authors - u might find
peolpe who know most of x from the xlib/client side. but still - they will miss
bits :)

> 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).

reading LOTs of source helps. personally i have scriunged the source of
multiple wm's (including my own when i forget how something was done and i need
it later), some toolkits and any other source i can find.

> 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;
> }
> 
> 
> _______________________________________________
> xorg mailing list
> xorg at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/xorg
> 


-- 
------------- Codito, ergo sum - "I code, therefore I am" --------------
The Rasterman (Carsten Haitzler)    raster at rasterman.com
裸好多
Tokyo, Japan (東京 日本)



More information about the xorg mailing list