Xlib pseudo transparency example (needs polish)
Web Server forum
Back To The Forum Home!Search!Private Messaging System

Web Server Talk Web Server Talk > Unix and Linux reviews > Free Unix support > Unix Programming > Xlib pseudo transparency example (needs polish)




  Last Thread   Next Thread Next
  Show Printable Version Email this Page Subscribe to this Thread      Post New Thread    Post A Reply      

    Xlib pseudo transparency example (needs polish)  
Matt Garman


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
11-18-05 10:54 PM

Recently I posted a message to this group titled "XShape
example(s)?" [http://tinyurl.com/7qndk].  With much assistance, I
was able to generate a simple example program for using the XShape
extension to achieve true transparency in Xlib.

So now I'm experimenting with pseudo-transparency.  If you're
interested, see the attached program below.  For the most part, it
works, however, the pseudo-transparent background is skewed a bit.
I believe that is simply a matter of correcting where I crop from
the root image (e.g. make up for window manager borders).

What I'm really struggling with is XGetGeometry().  Regardless of
*my* window's position, XGetGeometry() always returns (0, 0).  Using
XGetGeometry() my window's parent gives me non-zero---but still
constant---values.  Using the grandparent of my window actually
yields the "true" window position (I say "true" in quotes because
I'm not sure if it's the exact position or not, but it's pretty
close).

The point is, I'm not sure if this is the most generic way to get
the window position.  I was playing with this a bit on a Windows box
using Exceed, and I was able to get window position updates using my
window's parent.

Anyway, for those who are interested, here's my pseudo-transparency
example (as a work-in-progress).

Thanks!
Matt




#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <unistd.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 }
};

Pixmap x_get_root_pixmap_by_property(Display *dpy);
Pixmap x_get_cropped_pixmap(Display *dpy, Pixmap src, int x, int y,
unsigned width, unsigned height);

int main(int argc, char **argv)
{
Display *dpy = NULL;
Window w;
Pixmap pmap = None;
GC win_gc;
XGCValues xgcv;
int run = 1; /* loop control variable */


/* open the display */
if (!(dpy = XOpenDisplay(0))) {
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);
XSetWindowBackgroundPixmap(dpy, w, x_get_root_pixmap_by_property(dpy));

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

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

/* map the window - tell the world that it is to be seen */
XMapWindow(dpy, w);

XSync(dpy, False);

while (run) {
XEvent xe;
XNextEvent(dpy, &xe);

Window root, parent, *children;
int x, y;
unsigned int width, height, border_width, depth, nchildren;
static int expose_count = 0;

switch (xe.type) {
case GraphicsExpose:
printf("GraphicsExpose\n");
break;

case Expose:
printf("Expose %i\n", expose_count++);

XQueryTree(dpy, w, &root, &parent, &children, &nchildren);
XQueryTree(dpy, parent, &root, &parent, &children,
&nchildren);
XGetGeometry(dpy, parent, &root, &x, &y, &width, &height,
&border_width, &depth);

printf("x = %i, y = %i\n", x, y);

pmap = x_get_cropped_pixmap(dpy,
x_get_root_pixmap_by_property(dpy), x, y, width,
height);

/* whenever we get an expose, draw the rectangles */
XClearWindow(dpy, w);
XSetWindowBackgroundPixmap(dpy, w, pmap);

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;

case NoExpose:
printf("NoExpose\n");
break;

default:
printf("Caught event %i\n", xe.type);
}
}

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

return EXIT_SUCCESS;
}

Pixmap x_get_root_pixmap_by_property(Display *dpy)
{
Pixmap root_pixmap = None;
static Atom id = None;
const char* pixmap_id_names[] = {
"_XROOTPMAP_ID", "ESETROOT_PMAP_ID", NULL
};
int i = 0;

for (i=0; (pixmap_id_names[i] && (None == root_pixmap)); i++) {

if (None == id) {
id = XInternAtom(dpy, pixmap_id_names[i], True);
}

if (None != id) {
Atom actual_type = None;
int actual_format = 0;
unsigned long nitems = 0;
unsigned long bytes_after = 0;
unsigned char *properties = NULL;
int rc = 0;

rc = XGetWindowProperty(dpy, DefaultRootWindow(dpy), id, 0, 1,
False, XA_PIXMAP, &actual_type, &actual_format, &nitems,
&bytes_after, &properties);

if (Success == rc && properties) {
root_pixmap = *((Pixmap*)properties);
}
}
}

return root_pixmap;
}


Pixmap x_get_cropped_pixmap(Display *dpy, Pixmap src, int x, int y,
unsigned width, unsigned height)
{
Pixmap dest = None;
Status rc;

Window root_return = None;
int x_return = 0;
int y_return = 0;
unsigned int width_return = 0;
unsigned int height_return = 0;
unsigned int border_width_return = 0;
unsigned int depth_return = 0;

rc = XGetGeometry(dpy, src, &root_return, &x_return, &y_return,
&width_return, &height_return, &border_width_return,
&depth_return);

dest = XCreatePixmap(dpy, src, width, height, depth_return);

if (None != dest) {
rc = XCopyArea(dpy, src, dest, DefaultGC(dpy, 0), x, y, width,
height, 0, 0);
}

return dest;
}







[ Post a follow-up to this message ]



    Re: Xlib pseudo transparency example (needs polish)  
Måns Rullgård


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
11-19-05 12:47 PM

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

> Recently I posted a message to this group titled "XShape
> example(s)?" [http://tinyurl.com/7qndk].  With much assistance, I
> was able to generate a simple example program for using the XShape
> extension to achieve true transparency in Xlib.
>
> So now I'm experimenting with pseudo-transparency.  If you're
> interested, see the attached program below.  For the most part, it
> works, however, the pseudo-transparent background is skewed a bit.
> I believe that is simply a matter of correcting where I crop from
> the root image (e.g. make up for window manager borders).
>
> What I'm really struggling with is XGetGeometry().  Regardless of
> *my* window's position, XGetGeometry() always returns (0, 0).  Using
> XGetGeometry() my window's parent gives me non-zero---but still
> constant---values.  Using the grandparent of my window actually
> yields the "true" window position (I say "true" in quotes because
> I'm not sure if it's the exact position or not, but it's pretty
> close).

You can use XTranslateCoordinates with the root window and your window
as two of the arguments.

Followups set to c.w.x, as that is more appropriate than c.u.p.

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





[ Post a follow-up to this message ]



    Re: Xlib pseudo transparency example (needs polish)  
E. Rosten


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
11-19-05 12:47 PM

On Fri, 18 Nov 2005 23:33:23 +0000, Matt Garman wrote:


> What I'm really struggling with is XGetGeometry().  Regardless of
> *my* window's position, XGetGeometry() always returns (0, 0).  Using
> XGetGeometry() my window's parent gives me non-zero---but still
> constant---values.  Using the grandparent of my window actually
> yields the "true" window position (I say "true" in quotes because
> I'm not sure if it's the exact position or not, but it's pretty
> close).
>
> The point is, I'm not sure if this is the most generic way to get
> the window position.  I was playing with this a bit on a Windows box
> using Exceed, and I was able to get window position updates using my
> window's parent.

This is correct: the window manager reparents any windows on the root
window and sticks them inside its own window, so that it can add
decorations, etc. You probably want XGetGeometry relative to the root
window. There was a previous discussion about that here, and I believe
that the conclusion was that it is pretty much impossible to do this
without a round trip to the server.

You can in general snip out one branch of the window tree and move it
elsewhere with XReparentWindow.


-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&#
123;roll}d f 5/m
{moveto}d -1 r 230 350 m 0 1 179{1 index show 88 rotate 4 mul 0 rm
oveto}
for /s 15 d f pop 240 420 m 0 1 3 { 4 2 1 r sub -1 r show } for showpag
e






[ Post a follow-up to this message ]



    Sponsored Links  




 





   All times are GMT. The time now is 09:27 PM.      Post New Thread    Post A Reply      
  Last Thread   Next Thread Next


Most Popular forums 

Forum Jump:
Rate This Thread:

Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is OFF
vB code is ON
Smilies are ON
[IMG] code is OFF
 
Medical and Health forum | Computer Games Reviews | Graphics design forum

Back To The Top
Home | Usercp | Faq | Register