Unix Programming - XShape example(s)?

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > November 2005 > XShape example(s)?





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author XShape example(s)?
Matt Garman

2005-10-25, 2:49 am

I was wondering if anyone out there has some simple code that
demonstrates the usage of the "X Nonrectangular Window Shape
Extension Library" (XShape)?

I've read (and re-read) Keith Packard's document:

http://www.x.org/X11R6.8.1/docs/Xext/shape.pdf
http://www.xfree86.org/current/shapelib.pdf

I've also tried to use the xeyes, xlogo and oclock sources as an
example, but I'm just not getting it (plus those example all use the
"Xt" API, whereas I'd prefer not to use that, and I'm not sure what
all the Xt stuff is doing "behind the scenes").

Right now, I'd like to create windows that have
"pseudo-transparency", such as xeyes does (e.g. the area around the
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.]

An ideal example program would be one that creates a window with a
"transparent" background, and draws a white block somewhere in the
window.

Between the scant examples that are out there and the sparse
documentation (Keith's document above, Linux man pages), I'm really
struggling trying to figure this out.

Any help would be thoroughly appreciated!

Thank you,
Matt

--
Matt Garman
email at: http://raw-sewage.net/index.php?file=email
Fredrik Roubert

2005-10-25, 2:49 am

On Tue, 25 Oct 2005 03:11:42 GMT, Matt Garman wrote:

> I was wondering if anyone out there has some simple code that
> demonstrates the usage of the "X Nonrectangular Window Shape
> Extension Library" (XShape)?


I've sent a small (292 source code lines) application I've written
that uses the XShape extension, by private e-mail.

Cheers // Fredrik Roubert

--
Sörbyplan 5 | +46 8 7609169 / +46 708 776974
SE-163 71 Spånga | http://www.df.lth.se/~roubert/
E. Rosten

2005-10-25, 7:48 am

On Tue, 25 Oct 2005 03:11:42 +0000, Matt Garman wrote:

> I was wondering if anyone out there has some simple code that
> demonstrates the usage of the "X Nonrectangular Window Shape
> Extension Library" (XShape)?
>
> I've read (and re-read) Keith Packard's document:
>
> http://www.x.org/X11R6.8.1/docs/Xext/shape.pdf
> http://www.xfree86.org/current/shapelib.pdf
>
> I've also tried to use the xeyes, xlogo and oclock sources as an
> example, but I'm just not getting it (plus those example all use the
> "Xt" API, whereas I'd prefer not to use that, and I'm not sure what
> all the Xt stuff is doing "behind the scenes").
>
> Right now, I'd like to create windows that have
> "pseudo-transparency", such as xeyes does (e.g. the area around the
> 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.]
>
> An ideal example program would be one that creates a window with a
> "transparent" background, and draws a white block somewhere in the
> window.


http://mi.eng.cam.ac.uk/~er258/code/x11/index.html

There's a shaped window example on this page. The program makes a shaped
window with a red background. You can then draw whatever you wish on to
the window. There's actually only one relavent line in the whole program:
XShapeCombineMask.

-Ed



--
(You can't go wrong with psycho-rats.) (er258)(@)(eng.cam)(.ac.uk)

/d{def}def/f{/Times findfont s scalefont setfont}d/s{10}d/r{roll}d f 5/m
{moveto}d -1 r 230 350 m 0 1 179{1 index show 88 rotate 4 mul 0 rmoveto}
for /s 15 d f pop 240 420 m 0 1 3 { 4 2 1 r sub -1 r show } for showpage

E. Rosten

2005-10-25, 7:48 am

On Tue, 25 Oct 2005 03:11:42 +0000, Matt Garman wrote:

> I was wondering if anyone out there has some simple code that
> demonstrates the usage of the "X Nonrectangular Window Shape
> Extension Library" (XShape)?
>
> I've read (and re-read) Keith Packard's document:
>
> http://www.x.org/X11R6.8.1/docs/Xext/shape.pdf
> http://www.xfree86.org/current/shapelib.pdf
>
> I've also tried to use the xeyes, xlogo and oclock sources as an
> example, but I'm just not getting it (plus those example all use the
> "Xt" API, whereas I'd prefer not to use that, and I'm not sure what
> all the Xt stuff is doing "behind the scenes").
>
> Right now, I'd like to create windows that have
> "pseudo-transparency", such as xeyes does (e.g. the area around the
> 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.]
>
> An ideal example program would be one that creates a window with a
> "transparent" background, and draws a white block somewhere in the
> window.


There's a shaped window example on my website:
http://mi.eng.cam.ac.uk/~er258/code/x11/index.html

There's only one relavent line: XShapeCombineMask, but the program is
complete (if a little silly)

All it does is bring up a window. You can then draw on it using any
standard drawing commands.

-Ed



--
(You can't go wrong with psycho-rats.) (er258)(@)(eng.cam)(.ac.uk)

/d{def}def/f{/Times findfont s scalefont setfont}d/s{10}d/r{roll}d f 5/m
{moveto}d -1 r 230 350 m 0 1 179{1 index show 88 rotate 4 mul 0 rmoveto}
for /s 15 d f pop 240 420 m 0 1 3 { 4 2 1 r sub -1 r show } for showpage

E. Rosten

2005-10-25, 7:48 am

On Tue, 25 Oct 2005 03:11:42 +0000, Matt Garman wrote:

> I was wondering if anyone out there has some simple code that
> demonstrates the usage of the "X Nonrectangular Window Shape
> Extension Library" (XShape)?
>
> I've read (and re-read) Keith Packard's document:
>
> http://www.x.org/X11R6.8.1/docs/Xext/shape.pdf
> http://www.xfree86.org/current/shapelib.pdf
>
> I've also tried to use the xeyes, xlogo and oclock sources as an
> example, but I'm just not getting it (plus those example all use the
> "Xt" API, whereas I'd prefer not to use that, and I'm not sure what
> all the Xt stuff is doing "behind the scenes").
>
> Right now, I'd like to create windows that have
> "pseudo-transparency", such as xeyes does (e.g. the area around the
> 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.]
>
> An ideal example program would be one that creates a window with a
> "transparent" background, and draws a white block somewhere in the
> window.


There's an example on my web page:

http://mi.eng.cam.ac.uk/~er258/code/x11/index.html

There's one relavent line: XShapeCombineMask.

The program brings up a window, you can then draw on it using any method
you wish.

-Ed


--
(You can't go wrong with psycho-rats.) (er258)(@)(eng.cam)(.ac.uk)

/d{def}def/f{/Times findfont s scalefont setfont}d/s{10}d/r{roll}d f 5/m
{moveto}d -1 r 230 350 m 0 1 179{1 index show 88 rotate 4 mul 0 rmoveto}
for /s 15 d f pop 240 420 m 0 1 3 { 4 2 1 r sub -1 r show } for showpage

E. Rosten

2005-10-25, 7:48 am

On Tue, 25 Oct 2005 03:11:42 +0000, Matt Garman wrote:

> I was wondering if anyone out there has some simple code that
> demonstrates the usage of the "X Nonrectangular Window Shape
> Extension Library" (XShape)?
>
> I've read (and re-read) Keith Packard's document:
>
> http://www.x.org/X11R6.8.1/docs/Xext/shape.pdf
> http://www.xfree86.org/current/shapelib.pdf
>
> I've also tried to use the xeyes, xlogo and oclock sources as an
> example, but I'm just not getting it (plus those example all use the
> "Xt" API, whereas I'd prefer not to use that, and I'm not sure what
> all the Xt stuff is doing "behind the scenes").
>
> Right now, I'd like to create windows that have
> "pseudo-transparency", such as xeyes does (e.g. the area around the
> 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.]
>
> An ideal example program would be one that creates a window with a
> "transparent" background, and draws a white block somewhere in the
> window.


I seem to have trouble posting at the moment.


Try this:
http://mi.eng.cam.ac.uk/~er258/code/x11/index.html

There's a shape example on that page. The relavent line is
XShapeCombineMask

-Ed

--
(You can't go wrong with psycho-rats.) (er258)(@)(eng.cam)(.ac.uk)

/d{def}def/f{/Times findfont s scalefont setfont}d/s{10}d/r{roll}d f 5/m
{moveto}d -1 r 230 350 m 0 1 179{1 index show 88 rotate 4 mul 0 rmoveto}
for /s 15 d f pop 240 420 m 0 1 3 { 4 2 1 r sub -1 r show } for showpage

impslayer

2005-10-25, 7:48 am


E. Rosten skrev:

>
> I seem to have trouble posting at the moment.
>


Not at all, you seem to be posting quite a lot ;)

/impslayer

Matt Garman

2005-10-28, 4:53 pm

On Tue, 25 Oct 2005 12:16:14 +0100, E. Rosten <look@my.sig> wrote:
> On Tue, 25 Oct 2005 03:11:42 +0000, Matt Garman wrote:
> http://mi.eng.cam.ac.uk/~er258/code/x11/index.html
>
> There's a shaped window example on this page. The program makes a
> shaped window with a red background. You can then draw whatever
> you wish on to the window. There's actually only one relavent
> line in the whole program: XShapeCombineMask.


Thank you very much for the example! Much thanks also to Fredrik
Roubert, who was kind enough to email another example.

However, both of these examples use pixmaps (or bitmaps) to create
the "transparent" background. I'd like to be able to create a
transparent background on the fly, for any window size.

Attached below is a program which attempts to do just that---create
a "transparent" window, and upon it draw four white boxes, one in
each corner of the window.

However, all I get is a blank "transparent" window---no boxes are
drawn, and the background does not update if the window is moved.
Also interesting is that the program does not recognize mouse button
presses.

If I remove the few lines of code that try to establish
transparency, and replace with a XSetWindowBackground(), the program
works as expected (draws the white boxes on a solid, opaque
background). So I believe I've got things mostly write, but my use
of XShapeCombineMask() isn't correct.

Any thoughts?

Thanks again,
Matt

--
Matt Garman
email at: http://raw-sewage.net/index.php?file=email




/* Save as: 'xshape_example.c'
* Compiling:
* gcc -Wall -g xshape_example.c -o xshape_example -lX11 -lXext
*/

/* This program *attempts* to create 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

Display *dpy;
Window w;

/* convenience variables */
int BLACK_PIXEL;
int WHITE_PIXEL;

/* 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)
{
XGCValues shape_xgcv;
Pixmap pmap;
GC shape_gc;
GC gc;
XGCValues gcv;
int run = 1; /* loop control variable */

/* open the display */
if(!(dpy = XOpenDisplay(getenv("DISPLAY")))) {
fprintf(stderr, "can't open display\n");
return EXIT_FAILURE;
}

/* convenience */
BLACK_PIXEL = BlackPixel(dpy, DefaultScreen(dpy));
WHITE_PIXEL = WhitePixel(dpy, DefaultScreen(dpy));

w = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0,
W_WIDTH, W_HEIGHT, 0, CopyFromParent,
InputOutput, CopyFromParent, 0, NULL);

/* Try to create a transparent background.
*
* The idea/technique attempts to mimic lines 342--360 of
* "Eyes.c", from the "xeyes" source. (The xeyes source is part
* of the X11 source package.)
*
* Every other example I've seen uses a pixmap, but I'd like to
* not have a pixmap as a requirement.
*/
pmap = XCreatePixmap(dpy, w, W_WIDTH, W_HEIGHT, 1);
shape_gc = XCreateGC(dpy, pmap, 0, &shape_xgcv);
XSetForeground(dpy, shape_gc, 0);
XFillRectangle(dpy, pmap, shape_gc, 0, 0, W_WIDTH, W_HEIGHT);

XShapeCombineMask (dpy, w, ShapeBounding,
0, 0, pmap, ShapeSet);

/* If I remove everything above (until the comment), and replace
* with the following, this application works as expected (e.g.,
* draws a black window with white rectanles at each corner */
/* XSetWindowBackground(dpy, w, BLACK_PIXEL); */

/* create a graphics context for drawing */
gcv.foreground = WHITE_PIXEL;
gcv.line_width = 1;
gcv.line_style = LineSolid;
gc = XCreateGC(dpy, w,
GCForeground | GCLineWidth | GCLineStyle, &gcv);

/* register events: ExposureMask for re-drawing, ButtonPressMask
* to capture mouse button press events */
XSelectInput(dpy, w, ExposureMask | ButtonPressMask);

XMapWindow(dpy, w);
XSync(dpy, False);

while(run) {
XEvent xe;
XNextEvent(dpy, &xe);
switch (xe.type) {
case Expose:
/* whenever we get an expose, draw the rectangles */
XSetForeground(dpy, gc, WHITE_PIXEL);
XDrawRectangles(dpy, w, gc, rectangles, 4);
XFillRectangles(dpy, w, gc, rectangles, 4);
XSync(dpy, False);
break;
case ButtonPress: /* quit if a button is pressed */
/* note that when using XShapeCombineMask(), i.e.
* trying to get a "transparent" background,
* no ButtonPress events are ever recognized
*/
printf("ButtonPress\n");
run = 0;
break;
default:
printf("Caught event %i\n", xe.type);
}
}

XDestroyWindow(dpy, w);
XCloseDisplay(dpy);

return 0;
}

Matt Garman

2005-10-29, 2:49 am

On Fri, 28 Oct 2005 19:51:20 GMT, Matt Garman <fake@not-real.bogus> wrote:
> Attached below is a program which attempts to do just
> that---create a "transparent" window, and upon it draw four white
> boxes, one in each corner of the window.


Woo-hoo! I finally got it working! I got some help on the X.org
mailing list; check the recent archives for details.

At any rate, I've posted a working version of my program below;
hopefully it will serve posterity.

--
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;
}


Måns Rullgård

2005-10-29, 7:47 am

Matt Garman <fake@not-real.bogus> writes:

> On Fri, 28 Oct 2005 19:51:20 GMT, Matt Garman <fake@not-real.bogus> wrote:
>
> Woo-hoo! I finally got it working! I got some help on the X.org
> mailing list; check the recent archives for details.
>
> At any rate, I've posted a working version of my program below;
> hopefully it will serve posterity.


> if(!(dpy = XOpenDisplay(getenv("DISPLAY")))) {


XOpenDisplay(NULL) works just as well.

> /* register events: ExposureMask for re-drawing, ButtonPressMask
> * to capture mouse button press events */
> XSelectInput(dpy, w, ButtonPressMask | StructureNotifyMask);


Where's the ExposureMask in the XSelectInput() call?

> 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 */


ConfigureNotify is not Expose. ConfigureNotify is generated if the
window is moved, and in some other situations.

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


None of this needs to be done in connection to a ConfigureNotify. The
window only needs to be shaped once, and the contents should be
redrawn after an Expose event. ConfigureNotify is not interesting in
this program.

--
Måns Rullgård
mru@inprovide.com
Matt Garman

2005-10-31, 5:58 pm

On Sat, 29 Oct 2005 10:16:00 +0100, Måns Rullgård <mru@inprovide.com> wrote:
> Where's the ExposureMask in the XSelectInput() call?
> ...
> ConfigureNotify is not Expose. ConfigureNotify is generated if
> the window is moved, and in some other situations.


That was a left-over from me screwing around for so long (to the
point where I was practically changing things at random).

Anyway, just to help anyone who has the same problem in the future,
here's a corrected version. I still can't vouche for 100%
correctness, but it's an improvement.

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 = NULL;
Window w;
Pixmap pmap;
GC shape_gc;
GC win_gc;
XGCValues xgcv;
char* display_string = NULL;
int event_base = 0; /* not used in this example */
int error_base = 0; /* not used in this example */
int run = 1; /* loop control variable */

/* open the display */
display_string = getenv("DISPLAY");
if (!(dpy = XOpenDisplay(display_string))) {
fprintf(stderr, "can't open display '%s'\n",
(display_string ? display_string : "NULL"));
return EXIT_FAILURE;
}

/* ask the server if it supports XShape; if not, this program
* isn't useful! */
if (False == XShapeQueryExtension(dpy, &event_base, &error_base)) {
fprintf(stderr, "display '%s' does not support XShape\n",
(display_string ? display_string : "NULL"));
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);

/* shape the window: first blank everything */
XSetForeground(dpy, shape_gc, 0);
XFillRectangle(dpy, pmap, shape_gc, 0, 0, W_WIDTH,
W_HEIGHT);

/* shape the window: now "unblank" everything where we want to
* draw */
XSetForeground(dpy, shape_gc, 1);
XDrawRectangles(dpy, pmap, shape_gc, rectangles, 4);
XFillRectangles(dpy, pmap, shape_gc, rectangles, 4);

/* register events: ExposureMask for re-drawing, ButtonPressMask
* to capture mouse button press events */
XSelectInput(dpy, w, ButtonPressMask | ExposureMask);

XMapWindow(dpy, w);
XSync(dpy, False);

while (run) {
XEvent xe;
XNextEvent(dpy, &xe);
switch (xe.type) {
case Expose:
printf("Expose\n");
/* whenever we get an expose, draw the rectangles */
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 EXIT_SUCCESS;
}


Måns Rullgård

2005-10-31, 5:58 pm

Matt Garman <fake@not-real.bogus> writes:

> On Sat, 29 Oct 2005 10:16:00 +0100, Måns Rullgård <mru@inprovide.com> wrote:
>
> That was a left-over from me screwing around for so long (to the
> point where I was practically changing things at random).
>
> Anyway, just to help anyone who has the same problem in the future,
> here's a corrected version. I still can't vouche for 100%
> correctness, but it's an improvement.
>
> /* 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 = NULL;
> Window w;
> Pixmap pmap;
> GC shape_gc;
> GC win_gc;
> XGCValues xgcv;
> char* display_string = NULL;
> int event_base = 0; /* not used in this example */
> int error_base = 0; /* not used in this example */
> int run = 1; /* loop control variable */
>
> /* open the display */
> display_string = getenv("DISPLAY");
> if (!(dpy = XOpenDisplay(display_string))) {
> fprintf(stderr, "can't open display '%s'\n",
> (display_string ? display_string : "NULL"));
> return EXIT_FAILURE;
> }


Still no need to mess around with getenv(). XOpenDisplay does all
that for you, if you pass it NULL as the argument. Doing it yourself
doesn't hurt either, though.

[...]

> /* shape the window: now "unblank" everything where we want to
> * draw */
> XSetForeground(dpy, shape_gc, 1);
> XDrawRectangles(dpy, pmap, shape_gc, rectangles, 4);
> XFillRectangles(dpy, pmap, shape_gc, rectangles, 4);


You should be calling XShapeCombineMask here. After that, you can
free the shape pixmap.

> /* register events: ExposureMask for re-drawing, ButtonPressMask
> * to capture mouse button press events */
> XSelectInput(dpy, w, ButtonPressMask | ExposureMask);
>
> XMapWindow(dpy, w);
> XSync(dpy, False);
>
> while (run) {
> XEvent xe;
> XNextEvent(dpy, &xe);
> switch (xe.type) {
> case Expose:
> printf("Expose\n");
> /* whenever we get an expose, draw the rectangles */
> 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);


And no need for the XShapeCombineMask() call here. The shape remains
even the window is hidden.

> 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);
> }
> }


The XSync() calls are not necessary in this program. XNextEvent()
will flush the output buffer before waiting for an event anyway. If
running over a slow link, a call to XSync() can take a noticeable time
to return, since it involves a roundtrip communication with the
server.

--
Måns Rullgård
mru@inprovide.com
Matt Garman

2005-11-18, 5:54 pm

On Mon, 31 Oct 2005 22:10:49 +0000, Måns Rullgård <mru@inprovide.com> wrote:
> Still no need to mess around with getenv(). XOpenDisplay does
> all that for you, if you pass it NULL as the argument. Doing it
> yourself doesn't hurt either, though.


The reason I use getenv() is so that if the XOpenDisplay() call
fails, I can tell the user the name of the display I was trying to
open.

Anyway, I incorporated your suggestions into the program. Again,
I'll post it for posterity:



/* 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 = NULL;
Window w;
Pixmap pmap;
GC shape_gc;
GC win_gc;
XGCValues xgcv;
char* display_string = NULL;
int event_base = 0; /* not used in this example */
int error_base = 0; /* not used in this example */
int run = 1; /* loop control variable */

/* open the display */
display_string = getenv("DISPLAY");
if (!(dpy = XOpenDisplay(display_string))) {
fprintf(stderr, "can't open display '%s'\n",
(display_string ? display_string : "NULL"));
return EXIT_FAILURE;
}

/* ask the server if it supports XShape; if not, this program
* isn't useful! */
if (False == XShapeQueryExtension(dpy, &event_base, &error_base)) {
fprintf(stderr, "display '%s' does not support XShape\n",
(display_string ? display_string : "NULL"));
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);

/* shape the window: first blank everything */
XSetForeground(dpy, shape_gc, 0);
XFillRectangle(dpy, pmap, shape_gc, 0, 0, W_WIDTH,
W_HEIGHT);

/* shape the window: now "unblank" everything where we want to
* draw */
XSetForeground(dpy, shape_gc, 1);
XDrawRectangles(dpy, pmap, shape_gc, rectangles, 4);
XFillRectangles(dpy, pmap, shape_gc, rectangles, 4);

XShapeCombineMask (dpy, w, ShapeBounding, 0, 0, pmap, ShapeSet);
XFreePixmap(dpy, pmap);

/* register events: ExposureMask for re-drawing, ButtonPressMask
* to capture mouse button press events */
XSelectInput(dpy, w, ButtonPressMask | ExposureMask);

XMapWindow(dpy, w);
XSync(dpy, False);

while (run) {
XEvent xe;
XNextEvent(dpy, &xe);
switch (xe.type) {
case Expose:
printf("Expose\n");
/* whenever we get an expose, draw the rectangles */
XSetForeground(dpy, win_gc, WhitePixel(dpy,
DefaultScreen(dpy)));
XDrawRectangles(dpy, w, win_gc, rectangles, 4);
XFillRectangles(dpy, w, win_gc, rectangles, 4);

break;
case ButtonPress: /* quit if a button is pressed */
printf("ButtonPress\n");
run = 0;
break;
default:
printf("Caught event %i\n", xe.type);
}
}

XDestroyWindow(dpy, w);
XCloseDisplay(dpy);

return EXIT_SUCCESS;
}



--
Matt Garman
email at: http://raw-sewage.net/index.php?file=email
Måns Rullgård

2005-11-19, 7:47 am

Matt Garman <fake@not-real.bogus> writes:

> On Mon, 31 Oct 2005 22:10:49 +0000, Måns Rullgård <mru@inprovide.com> wrote:
>
> The reason I use getenv() is so that if the XOpenDisplay() call
> fails, I can tell the user the name of the display I was trying to
> open.


I figured.

> Anyway, I incorporated your suggestions into the program. Again,
> I'll post it for posterity:


> XDrawRectangles(dpy, pmap, shape_gc, rectangles, 4);
> XFillRectangles(dpy, pmap, shape_gc, rectangles, 4);


You only need XFillRectangles. It includes the edges that
XDrawRectangles draws.

--
Måns Rullgård
mru@inprovide.com
Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com