Discovering a window's background - Xwindows

This is a discussion on Discovering a window's background - Xwindows ; I know the identity of some window. I want to know the details of its background (whether pixel or pixmap). But how can I acces it? I can indeed set it with XChangeWindowAttributes, but that information is not subsequently available ...

+ Reply to Thread
Results 1 to 7 of 7

Thread: Discovering a window's background

  1. Discovering a window's background

    I know the identity of some window. I want to know the details of its
    background (whether pixel or pixmap). But how can I acces it?

    I can indeed set it with XChangeWindowAttributes, but that information is
    not subsequently available if I use XGetWindowAttributes.

    --
    Charles H. Lindsey ---------At Home, doing my own thing------------------------
    Tel: +44 161 436 6131 Fax: +44 161 436 6133 Web: http://www.cs.man.ac.uk/~chl
    Email: chl@clerew.man.ac.uk Snail: 5 Clerewood Ave, CHEADLE, SK8 3JU, U.K.
    PGP: 2C15F1A9 Fingerprint: 73 6D C2 51 93 A0 01 E7 65 E8 64 7E 14 A4 AB A5

  2. Re: Discovering a window's background

    On Oct 22, 4:37*am, "Charles Lindsey" wrote:
    > I know the identity of some window. I want to know the details of its
    > background (whether pixel or pixmap). But how can I acces it?
    >
    > I can indeed set it with XChangeWindowAttributes, but that information is
    > not subsequently available if I use XGetWindowAttributes.
    >

    You'll have to be more specific about what it is you want.
    What do you mean by wanting to know "the details of its background"?

    A window's background is not a pixmap, but a pixmap can be copied to
    a
    window (A pixmap is a drawable, and a window is a drawable,
    but a window is not a pixmap).
    A window does not "know" that it is displaying a pixmap.
    A window may have many pixmaps copied to various portions of it.

    You'll have to be more specific about what it is you want.
    What do you mean by wanting to know "the details of its background"?
    --
    Fred Kleinschmidt

  3. Re: Discovering a window's background

    Charles Lindsey wrote:

    > I know the identity of some window. I want to know the details of its
    > background (whether pixel or pixmap). But how can I acces it?


    If the window in question is the root window, you can /usually/ retrieve
    the pixmap ID from the _XROOTPMAP_ID property. If it's some other
    window, you're out of luck[1].

    [1] http://www.faqs.org/faqs/x-faq/part7/section-26.html

    --
    Huibert
    "Hey! HEY! Curious cat, here!" -- Krosp I (GG)

  4. Re: Discovering a window's background

    In Huibert Bol writes:

    >Charles Lindsey wrote:


    >> I know the identity of some window. I want to know the details of its
    >> background (whether pixel or pixmap). But how can I acces it?


    >If the window in question is the root window, you can /usually/ retrieve
    >the pixmap ID from the _XROOTPMAP_ID property. If it's some other
    >window, you're out of luck[1].


    >[1] http://www.faqs.org/faqs/x-faq/part7/section-26.html


    Yes, that site does indicate it cannot be done, except for the case of a
    simple background pixel, where it suggests clearing out a single pixel,
    and then using XGetImage to see what background is left.

    However, I think it can be done simpler than that.

    Here is line out of XftGlyphCore in libxft:

    image = XGetImage (dpy, pix, 0, 0, gi.width, gi.height, AllPlanes,
    ZPixmap);

    Apparently, ZPixmap is supposed to show you what is left after leaving out
    all the planes you have specified, so if you specify AllPlanes, then all
    that is left is the background.

    At least, that appears to be what is meant to happen, because XftGlyphCore
    deals with anti-aliased fonts by, for the pixels to be shown at reduced
    densities, looking at the background of that pixel, and if, say that pixel
    is to be displayed at half intensity, is shows 50% of the background pixel
    and 50% of the ink pixel. So you apparently see the background showing
    through the fainter bits of the glyph. So if, for example, the background
    is green and wou are drawing glyphs in blue, then the central part of the
    glyph will appear in saturated blue, but the pixels drawn in the "corners"
    to give the impression of a smooth outline will be shown in a carefully
    calculated mixture of blue and green. And indeed, text that has
    been anti-aliassed looks much better than it did in the days of old
    PseudoColor screens that could not afford to have 16 million colours at
    their disposal.

    So, if my interpretation of ZPixmap is correct, then it would seem that a
    normal window is effectively composed of 24 planes for what you draw, plus
    a further 24 planes of background.

    But the plot thickens, because I then discovered that my application
    (which is the Opera browser, which is built on top of QT, which is built
    on top of libxft) is actually calling XftGlyphCore with a Pixmap, and not
    with a Window, and it still seems to work (well, sort of, because I have
    been monitoring what XGetimage with ZPixmap actually returns, and it seems
    to start of returning the background pixels, but later on it seems to
    return all sorts of things, though is still displays as expected). I
    shall have to investigate that further. But when it has filled in the
    whole of the Pixmap, it copies it to the proper Window with XCopyArea.

    This seems a stupid behaviour (and there are worse stupidities), but I do
    not know whether it is QT that decides to do it that way, of Opera itself.

    So please can someone confirm whether my understanding is correct so far,
    and could someone also confirm my understanding that Pixmaps can have
    backgrounds, and also that the effect of XCopyArea is always to copy to
    the background of the destination, and you have to use XDrawRectangle if
    you want to put stuff in the foreground?

    --
    Charles H. Lindsey ---------At Home, doing my own thing------------------------
    Tel: +44 161 436 6131 Fax: +44 161 436 6133 Web: http://www.cs.man.ac.uk/~chl
    Email: chl@clerew.man.ac.uk Snail: 5 Clerewood Ave, CHEADLE, SK8 3JU, U.K.
    PGP: 2C15F1A9 Fingerprint: 73 6D C2 51 93 A0 01 E7 65 E8 64 7E 14 A4 AB A5

  5. Re: Discovering a window's background

    Charles Lindsey wrote:

    > In Huibert Bol writes:
    >
    >>Charles Lindsey wrote:

    >
    >>> I know the identity of some window. I want to know the details of its
    >>> background (whether pixel or pixmap). But how can I acces it?

    >
    >>If the window in question is the root window, you can /usually/ retrieve
    >>the pixmap ID from the _XROOTPMAP_ID property. If it's some other
    >>window, you're out of luck[1].

    >
    >>[1] http://www.faqs.org/faqs/x-faq/part7/section-26.html

    >
    > Yes, that site does indicate it cannot be done, except for the case of a
    > simple background pixel, where it suggests clearing out a single pixel,
    > and then using XGetImage to see what background is left.
    >
    > However, I think it can be done simpler than that.
    >
    > Here is line out of XftGlyphCore in libxft:
    >
    > image = XGetImage (dpy, pix, 0, 0, gi.width, gi.height, AllPlanes,
    > ZPixmap);


    XftGlyphCore is used to retrieve the bitmap for *core* (i.e., server)
    fonts: it draws a character onto a pixmap and then reads it back.
    That's what XGetImage(3) does: reading the *current* contents of a
    window or pixmap.

    If that is what you want, fine. I was under the impression that you
    were interrested background as set by XSetWindowBackgroundPixmap(3).

    --
    Huibert
    "Hey! HEY! Curious cat, here!" -- Krosp I (GG)

  6. Re: Discovering a window's background

    In Huibert Bol writes:

    >Charles Lindsey wrote:


    >> In Huibert Bol writes:
    >>
    >>>Charles Lindsey wrote:

    >>
    >>>> I know the identity of some window. I want to know the details of its
    >>>> background (whether pixel or pixmap). But how can I acces it?

    >>
    >> Here is line out of XftGlyphCore in libxft:
    >>
    >> image = XGetImage (dpy, pix, 0, 0, gi.width, gi.height, AllPlanes,
    >> ZPixmap);


    >XftGlyphCore is used to retrieve the bitmap for *core* (i.e., server)
    >fonts: it draws a character onto a pixmap and then reads it back.
    >That's what XGetImage(3) does: reading the *current* contents of a
    >window or pixmap.


    No, that is not right. I have now investigated further, and it seems
    things are happening as follows:

    XGetImage and XPutImage do indeed Get and Put the complete image,
    background foreground and everything else. The only difference when
    XGetImage is called with ZPixmap is that all the planes not mentioned in
    your plane_mask are shown as empty (all zeroes), whereas with XYPixmap
    they are omitted. So if you specify AllPlanes, the effect is the same in
    both cases (so the use of ZPixmap in XftGlyphCore was just a red herring).

    I also found that if you call XFillRectangle, it fills with the
    foreforeground colour of the GC, and not with the backgropund colour
    (which I find slightly odd, since it is usally called in order to fill
    some Drawable with a background).

    As for what is going on in XftGlyphCore when it is trying to display
    anti-aliassed fonts, it seems to be as follows:

    Firstly, it does not use XGetImage to discover how to draw individual
    characters from your font. It gets that information by calling
    XftFontLoadGlyphs, and however that works internally, it certainly does
    not call XGetImage.

    It seems that if you want to creat a window full of text, then you first
    fill it with the background (be it a single color, of a tiled pixmap, or
    even a pretty picture of the Eiffel Tower). Then you use XftGlyphCore to
    draw your text in the required positions (usually called from
    XftDrawString, or somesuch). In order to let the background show through
    the semi-transparent parts of the anti-aliassed glyphs, it first has to
    call XGetImage on the area where the text it to go. That shows it the
    background to be merged with that text (be it a simple color, or whatever
    bit of the Eiffel Tower happens to lie behind there). Then it calculates
    the merge, and uses XPutImage to write it back. All of which can be
    somewhat wasteful of resources, since every such call of XGetImage costs
    you a round-trip to the Xserver.

    BUT, if what you are writing is an editor, so that you need to be able to
    overwrite some of the text you wrote previously, then life gets more
    complicated>

    Each time you want to change the image, you have to constuct a brand new
    Pixmap, fill it with the correct background, rewrite the new text using
    XftGlyphCore, and then use XCopyArea to copy the whole Pixmap back onto
    the original Window.

    Well, that's how the Opera Browser plus QT thinks it is tying to do it (I
    can well imagine some shortcuts that would make it simpler). Here, by
    coding some printfs into XGlyphcore, I can show what it is actually doing.
    It was trying to display a Window with a single letter 'f' in it on a pure
    white background, so you can see that GetImage is showing the white
    background, and the PutImage shows how it was modified by the image of the
    actual glyph, which is shown between them.

    DRAWABLE 0x 10804f4 579x281
    GETIMAGE 4,157,7x7
    ffffff ffffff ffffff ffffff ffffff ffffff ffffff
    ffffff ffffff ffffff ffffff ffffff ffffff ffffff
    ffffff ffffff ffffff ffffff ffffff ffffff ffffff
    ffffff ffffff ffffff ffffff ffffff ffffff ffffff
    ffffff ffffff ffffff ffffff ffffff ffffff ffffff
    ffffff ffffff ffffff ffffff ffffff ffffff ffffff
    ffffff ffffff ffffff ffffff ffffff ffffff ffffff
    00 00 a2 af 99 88 01
    00 00 ff 03 00 00 00
    27 90 ff 90 90 51 00
    00 00 ff 00 00 00 00
    00 00 ff 00 00 00 00
    00 00 ff 00 00 00 00
    27 90 ff 90 90 51 00
    PUTIMAGE 4,157,7x7
    ffffff ffffff 5d5d5d 505050 666666 777777 fefefe
    ffffff ffffff 000000 fcfcfc ffffff ffffff ffffff
    d8d8d8 6f6f6f 000000 6f6f6f 6f6f6f aeaeae ffffff
    ffffff ffffff 000000 ffffff ffffff ffffff ffffff
    ffffff ffffff 000000 ffffff ffffff ffffff ffffff
    ffffff ffffff 000000 ffffff ffffff ffffff ffffff
    d8d8d8 6f6f6f 000000 6f6f6f 6f6f6f aeaeae ffffff

    However, the real BUG in Opera is that, instead of doing all that only
    when you have changed something in the Edit window. it tries to do it
    continuously once every second. Moreover it gets it wrong, because instead
    of creating a Pixmap of the same size as the Window, it ceates it of some
    stupid size (e.g. 3x15) and then tries to draw strings (occupying say
    150x7) into that much smaller Pixmap, causing BadMatches in XGetImage
    (which causes XftGlyphCore to revert to its backup mechanism, but even that
    cannot prevent it from trying to Get and Put stuff into areas that do not
    even overlap the bad Pixmap).

    Fortunately, whenever there has been a real change to the text, it comes
    to its senses and creates and writes into a Pixmap of the proper size. But
    in the meantime all the extra work has slowed down the editing process to
    a crawl where you have to wait many seconds for what you have typed to
    appear in the Window. And fortunately, again, it seems that the wastage
    can be avoided by coding a test into XftGlyphCore that just bails out if
    the areas to be altered do not overlap the Pixmap provided. But what a
    mess!

    But the hacks I want to do to XftGlyphCore would be much easier if there
    were some way to tell whether the Drawable provided was a Pixmap or a
    Window, and whether the background that had been given to it was a plain
    colour, or some (possibly tiled) Pixmap. So I am still looking for
    suggestions in those areas.

    --
    Charles H. Lindsey ---------At Home, doing my own thing------------------------
    Tel: +44 161 436 6131 Fax: +44 161 436 6133 Web: http://www.cs.man.ac.uk/~chl
    Email: chl@clerew.man.ac.uk Snail: 5 Clerewood Ave, CHEADLE, SK8 3JU, U.K.
    PGP: 2C15F1A9 Fingerprint: 73 6D C2 51 93 A0 01 E7 65 E8 64 7E 14 A4 AB A5

  7. Re: Discovering a window's background

    In "Charles Lindsey" writes:

    >However, the real BUG in Opera is that, instead of doing all that only
    >when you have changed something in the Edit window. it tries to do it
    >continuously once every second. Moreover it gets it wrong, because instead
    >of creating a Pixmap of the same size as the Window, it ceates it of some
    >stupid size (e.g. 3x15) and then tries to draw strings (occupying say
    >150x7) into that much smaller Pixmap, causing BadMatches in XGetImage
    >(which causes XftGlyphCore to revert to its backup mechanism, but even that
    >cannot prevent it from trying to Get and Put stuff into areas that do not
    >even overlap the bad Pixmap).


    I spoke too soon. Sometimes the glyphs to be drawn are entirely outside
    the Pixmap, but sometime they do have an intersection with it, so you
    cannot bail out of XGlyphcore just because the glyphs are not entirely
    within it, but OTOH you are not supposed to call XGetImage unless the piece
    you want is entirely inside the Drawable (Pixmap), and XGlyphCore was in
    fact being asked to do just that on a regular basis, forcing it to go into
    its slower mode of operation really intended for when the Drawable was a
    partially obscured Window.

    But I have now discovered that all those 3x15 Pixmaps were, in fact, the
    Cursor!. No, it is not trying to draw the Cursor itself, but the Cursor is
    considered part of the background, and when the background changes, you
    have to re-anti-alias all the glyphs that overlap that bit of background.

    And the cursor was blinking (1/2 second on, 1/2 second off).

    The Real Stupidity (whether within Opera or QT, I don't know) is that,
    whenever the cursor blinked on or off, it called XGlyphcore with that 3x15
    Pixmap, but it did not have the wit to discover which glyphs actually
    occupied that tiny bit of the Window. Instead, it tried to redraw the
    whole window (several hundred calls to XGlyphCore) over that small Pixmap,
    and only one of those calls actually needed to DO anything. So, in many
    cases, it could occupy more than the available capacity of one CPU just to
    keep the Cursor blinking :-( . What a shambles!

    So, my next move will be to hack XGlyphcore so that it bails out unless
    there is some intersection between the glyphs and the drawable, and so
    that it can, if necessary, draw just the fraction of the glyph(s) that
    lie within that intersection.

    >But the hacks I want to do to XftGlyphCore would be much easier if there
    >were some way to tell whether the Drawable provided was a Pixmap or a
    >Window, and whether the background that had been given to it was a plain
    >colour, or some (possibly tiled) Pixmap. So I am still looking for
    >suggestions in those areas.


    But yes, those questions still remain.

    --
    Charles H. Lindsey ---------At Home, doing my own thing------------------------
    Tel: +44 161 436 6131 Fax: +44 161 436 6133 Web: http://www.cs.man.ac.uk/~chl
    Email: chl@clerew.man.ac.uk Snail: 5 Clerewood Ave, CHEADLE, SK8 3JU, U.K.
    PGP: 2C15F1A9 Fingerprint: 73 6D C2 51 93 A0 01 E7 65 E8 64 7E 14 A4 AB A5

+ Reply to Thread