| Unix Content | Register | FAQ | Calendar | Search | Today's Posts | Mark Forums Read |
|
#1
|
| 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
|
| On Oct 22, 4:37*am, "Charles Lindsey" > 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
|
| 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
|
| In >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
|
| Charles Lindsey wrote: > In > >>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
|
| In >Charles Lindsey wrote: >> In >> >>>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
|
| In >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 |