How to edit Drawable/XdbeBackBuffer data?...

Aaron Plattner aplattner at nvidia.com
Tue Aug 21 21:29:22 PDT 2012


On 08/21/2012 03:56 PM, Lee Fallat wrote:
> Alright, well I've decided to take another approach. I'm XGetImage()ing
> the root window, then I darken my pixels, then, I go to store the data
> in a Drawable via XPutImage, but this Drawable isn't retaining the data,
> it's just white when I XCopyArea() over to what I want shown. Any
> suggestions/reasons why this is happening?
>
> Code sample:
>
> static XImage *xi;
>
> void XTintBG(Monitor *m, int x, int y, int w, int h) {
>    unsigned long new_color;
>    unsigned long r,g,b;
>
>    XCopyArea(dpy, root, m->barwin, dc.gc, x, y, w, h, x, y);
>    xi = XGetImage(dpy, m->barwin, x, y, w, h, AllPlanes, XYPixmap);

You almost certainly want ZPixmap rather than XYPixmap.  ZPixmap is your 
normal n-bits-per-pixel, pixels in scanline order image format. 
XYPixmap is the oh-god-kill-me-now image format.

The rest of the code seems reasonable, so try fixing that first.

If you need better performance and are willing to make your code even 
more complicated, you could bind the drawable in question using 
GLX_EXT_texture_from_pixmap, either as a pixmap directly, or by using 
the Composite extension to redirect the window you want and using its 
backing pixmap.  Then you can do much more complicated rendering using 
it as an OpenGL texture.  This unfortunately does not work on the root 
window but you could copy the root window's contents into a pixmap and 
then use that.

Adam's suggestion of using Render would be simpler if you can find a 
blending op that does what you want.

-- Aaron

>    for(int pix_y = 0; pix_y < h; pix_y++) {
>      for(int pix_x = 0; pix_x < w; pix_x++) {
>        new_color = XGetPixel(xi, pix_x, pix_y);
>        r = g = b = 0x00000000;
>        r = (new_color & 0x00FF0000) >> 16;
>        g = (new_color & 0x0000FF00) >> 8;
>        b = (new_color & 0x000000FF) >> 0;
>        r -= 32;
>        g -= 32;
>        b -= 32;
>        if(r > 255) r = 255;
>        if(r < 0) r = 0;
>        if(g > 255) g = 255;
>        if(g < 0) g = 0;
>        if(b > 255) b = 255;
>        if(b < 0) b = 0;
>        new_color = r << 16;
>        new_color = new_color | (g << 8);
>        new_color = new_color | (b << 0);
>        XPutPixel(xi, pix_x, pix_y, new_color);
>      }
>    }
>
>    XPutImage(dpy, m->barwin, dc.gc, xi, 0, 0, 0, 0, m->ww, bh);
>    XCopyArea(dpy, m->barwin, dc.bg <http://dc.bg>, dc.gc, 0, 0, m->ww,
> bh, 0, 0);
> }
>
> int ftime = 1;
>
> void
> drawbar(Monitor *m) {
>    int x;
>    unsigned int i, occ = 0, urg = 0;
>    XftColor *col;
>    Client *c;
>
>    if(ftime == 1) {
>    ftime = 0;
>    XTintBG(m, 0, 0, m->ww, bh);
>    }
>
>    XCopyArea(dpy, dc.bg <http://dc.bg>, dc.drawable, dc.gc, 0, 0, m->ww,
> bh, 0, 0);
>
> <More functions here but not relative to what I need>
>
> }
>
> On Mon, Aug 20, 2012 at 3:17 PM, Adam Jackson <ajax at redhat.com
> <mailto:ajax at redhat.com>> wrote:
>
>     On 8/20/12 2:08 PM, Lee Fallat wrote:
>
>         Hey,
>
>         I'm trying to darken/lighten the image data in a
>         Drawable/XdbeBackBuffer.
>         Any ideas on how to get access to the data?...I've done an
>         XGetImage() on
>         Drawable but that really slows down the application I'm editing...
>
>
>     That is, in fact, how you do it.  GetImage is not fast.  ShmGetImage
>     is faster, and as fast as you're going to get, if you insist on
>     doing this by pulling all the pixels down to the client and then
>     pushing them back up.
>
>     You may instead wish to use the Render extension, which gives you
>     the usual set of Porter-Duff blend operations, and which runs in the
>     server so you're not copying all that data around.
>
>     - ajax
>
>




More information about the xorg mailing list