I think I found the problem and sent a patch:
https://lists.x.org/archives/xorg-devel/2016-August/050544.html
https://patchwork.freedesktop.org/patch/102574/
On 08/01/2016 07:44 AM, Fabien Lelaquais wrote:
Thansk again to you, Thomas, and Carsten.
I suspect I still was not clear enough. My problem is not the hidden
pixels. I know they will be undefined (or I can use an XCopyArea and
process the GraphicsExpose events).
My problem is that visible pixels (well defined, and in this case,
white) are retrieved as black pixels.
To make things more clear, if you cannot reproduce my problem.
I have two top windows A and B.
B is smaller than A, and located on top of it.
A is entirely on my screen (and B obviously is as well).
Here what it looks like: (sorry guys, you'll need a monospaced font to
see this properly)
+------------+
| A |
| +-----+ |
| | B | |
| +-----+ |
+------------+
If I XGetImage() from A a rectangle that contains the area covered by
B (but still inside A), what I expect is:
+------------+
| |
| ####### |
| ####### |
| ####### |
+------------+
Where the # signs indicate an undefined value: all the pixels covered
by B. Makes sense.
But what I really get is:
+------------+
| |
| ######### |
| ######### |
| ######### |
+------------+
That is, more pixels are reported as undefined, to the right of the
expected 'undefined' region (the one covered by B).
My experiments show that the more I translate the capture rectangle to
the right (limited to the surface of A), the more undefined pixels I
will get.
If the capture rectangle has its left edge at 0 (on the A left-hand
border), the image is perfect. This makes no sense at all.
Unfortunately, I cannot rely on the BackingStore or other properties:
I may not be the one that created the Window (I'm working on a library
that sits on top of X).
And yes, I suspect a bug in the server but honestly I don't believe it.
I tried this today: I can work the problem around by creating a
temporary Pixmap (the size of my capture area), XCopyArea the window A
into it, then XGetImage on that Pixmap.
Then my image is fine, at the cost of an additional Pixmap
(potentially large) and a GC (where I dropped the generation of
GraphicsExpose events that I don't care about).
All my pixels are correct, except the covered ones, which is fair.
Thanks!
Fabien
-----Original Message-----
From: Carsten Haitzler [mailto:ras...@rasterman.com]
Sent: lundi 1 août 2016 00:50
To: Fabien Lelaquais <fabien.lelaqu...@roguewave.com>
Cc: x...@freedesktop.org
Subject: Re: Corrupted XImage retrieved from a Window area
On Sun, 31 Jul 2016 07:51:08 +0000 Fabien Lelaquais
<fabien.lelaqu...@roguewave.com
<mailto:fabien.lelaqu...@roguewave.com>> said:
> Thanks a lot for your answer.
> Unfortunately I may not be able to rely of the Composite extension
> (app would be deployed in environments I don't control).
>
> Regarding the XGetImage documentation, that I've read ten times:
> My drawable (mainWindow) is indeed a viewable window.
> It has no inferior, and an overlapping window on its center. The
> specified rectangle that I provide, which is the center part of the
> source window, is both fully visible on the screen and wholly
> contained in mainWindow. I have no X error. And that's why I'm calling for
help.
you won't get an x error unless the region ends up being out of screen
bounds.
if pixels of a window are clipped by the screen, a parent window, a
shape rectangle list, or are covered by another window... they "do not
exist" by default in x11. that is how it works. that is why thomas
suggested pixmap redirection to ensure that pixels DO exist and force
them to live in a pixmap irrespective of windows overlapping or the
window being offscreen. without this you are in regular old x11 mode
and if your source is a window... if at the time you grab, you cannot
SEE the pixels on a screen... they do not exist.
irrespective of if someone drew to them just before. you can never get
them.
you can "deal with it" and get pixels by setting includeinferiors in
your gc subwindowmode before you grab. this will ignore clipping of
overlapping windows and just grab whatever is there in the framebuffer
as long as your resulting rectangle at the time x performs the grab is
still within screen limits. this will get you the content including
overlapping window content. this is effectively how you do screenshots
in x11.
if the region is within screen limits of course... if it is not -
problems. if you are managed by a window manager there is always then
a race condition where the wm may have moved you off screen but you
have not seen the event yet. you can xgrabserver first, then get
geometry of your window and translate relative to root to ensure you
have the correct clipping coordinates, getimage, then xungrab server
to work around the race (and please at least xflush or xsync after the
xungrabserver.
note. i'm totally ignoring multiple visuals and depths here. :) if
your screen consists of lots of windows with differing visuals and
depths life gets complex. xv also creates problems if it is using
overlays and colorkeys. :)
> Thanks again,
>
> Cheers,
> Fabien
>
> -----Original Message-----
> From: Thomas Lübking [mailto:thomas.luebk...@gmx.de]
> Sent: samedi 30 juillet 2016 16:03
> To: Fabien Lelaquais <fabien.lelaqu...@roguewave.com
<mailto:fabien.lelaqu...@roguewave.com>>
> Cc:x...@freedesktop.org <mailto:x...@freedesktop.org>
> Subject: Re: Corrupted XImage retrieved from a Window area
>
> On Sat, Jul 30, 2016 at 08:34:20AM +0000, Fabien Lelaquais wrote:
> >Hi all,
> >I'm trying to create an XImage that represents a rectangular portion
> >of a Window (because I need to be able to access the actual pixel
> >values). My experimentations show that if the source window has an
> >hidden region (overlapping window) and if the origin of the rectangle
> >I query is not (0, 0), then the data is corrupted, resulting in
> >pixels set to 0 in the image data (and a black area in the XImage).
> >
> >I use a raw XGetImage.
>
> You want to use XCompositeRedirectWindow. This redirects the window
> into a pixmap. (What compositors like xcompmgr do)
>
>
> From man XGetImage:
> -------------------
> If the drawable is a window, the window must be viewable, and it must
> be the case that if there were no inferiors or overlapping windows,
> the specified rectangle of the window would be fully visible on the
> screen and wholly contained within the outside edges of the window, or a
BadMatch error results.
>
> Cheers,
> Thomas
> _______________________________________________
>xorg@lists.x.org <mailto:xorg@lists.x.org>: X.Org support
> Archives:http://lists.freedesktop.org/archives/xorg
> Info:https://lists.x.org/mailman/listinfo/xorg
> Your subscription address: %(user_address)s
--
------------- Codito, ergo sum - "I code, therefore I am" --------------
The Rasterman (Carsten Haitzler) ras...@rasterman.com
<mailto:ras...@rasterman.com>
_______________________________________________
xorg@lists.x.org: X.Org support
Archives: http://lists.freedesktop.org/archives/xorg
Info: https://lists.x.org/mailman/listinfo/xorg
Your subscription address: %(user_address)s
nvpublic
_______________________________________________
xorg@lists.x.org: X.Org support
Archives: http://lists.freedesktop.org/archives/xorg
Info: https://lists.x.org/mailman/listinfo/xorg
Your subscription address: %(user_address)s