Capturing screenshot from a minimized window
I've been using XGetImage to capture screenshots, at the moment saving
them to xpm files. I'm having two problems though:
1. It's very slow and freezes my system for a few seconds.
2. On the unmap the XGetImage doesn't take a screenshot until after
the window has been unmapped, so I just get an image of what was
behind it. Similarly, if I try it on the map event then I seem to
catch it in the middle of painting the window.
Does anyone have any suggestions of a better way to go about capturing
an image of a window before it's unmapped, or where I might be going
wrong with my current method? Thanks.
Re: Capturing screenshot from a minimized window
Rich <rich.midwinter@gmail.com> writes:
[color=blue]
> I've been using XGetImage to capture screenshots, at the moment saving
> them to xpm files. I'm having two problems though:
>
> 1. It's very slow and freezes my system for a few seconds.[/color]
Use XShmGetImage instead of XGetImage.
[color=blue]
> 2. On the unmap the XGetImage doesn't take a screenshot until after
> the window has been unmapped, so I just get an image of what was
> behind it. Similarly, if I try it on the map event then I seem to
> catch it in the middle of painting the window.[/color]
You're a bit vague on where these events are originating, and how you
are capturing them. I'm going to assume your program requests events
on various windows using XSelectInput(), and attempts to take a
screenshot when an UnmapNotify event is received. This, as you have
seen, will not work. This is because the X server generates the event
after the window has already been unmapped. Similarly, a MapNotify
event is generated immediately when a window is mapped, typically
followed by an Expose event. When the client responsible for the
window receives the Expose event, it will (typically) redraw the
contents. You have no way of knowing when the client is finished with
this (which could be never, in the case of an animation).
--
M錸s Rullg錼d
[email]mans@mansr.com[/email]
Re: Capturing screenshot from a minimized window
On 20 Aug, 19:10, M錸s Rullg錼d <m...@mansr.com> wrote:[color=blue]
> Rich <rich.midwin...@gmail.com> writes:[color=green]
> > I've been using XGetImage to capture screenshots, at the moment saving
> > them to xpm files. I'm having two problems though:[/color]
>[color=green]
> > 1. It's very slow and freezes my system for a few seconds.[/color]
>
> Use XShmGetImage instead of XGetImage.
>[color=green]
> > 2. On the unmap the XGetImage doesn't take a screenshot until after
> > the window has been unmapped, so I just get an image of what was
> > behind it. Similarly, if I try it on the map event then I seem to
> > catch it in the middle of painting the window.[/color]
>
> You're a bit vague on where these events are originating, and how you
> are capturing them. *I'm going to assume your program requests events
> on various windows using XSelectInput(), and attempts to take a
> screenshot when an UnmapNotify event is received. *This, as you have
> seen, will not work. *This is because the X server generates the event
> after the window has already been unmapped. *Similarly, a MapNotify
> event is generated immediately when a window is mapped, typically
> followed by an Expose event. *When the client responsible for the
> window receives the Expose event, it will (typically) redraw the
> contents. *You have no way of knowing when the client is finished with
> this (which could be never, in the case of an animation).
>
> --
> M錸s Rullg錼d
> m...@mansr.com[/color]
Thanks, XShmGetImage seems to have bought me some performance, I'm
still slightly surprised at how slow it is though, I haven't tried any
concrete timing yet but it seems significantly slower than saving the
image to the hard disk.
I am using XSelectInput(), with SubstructureNotifyMask on the root
window to get the UnmapNotify events.
What I'm basically heading for is having a taskbar-like object on the
screen with thumbnails of the minimized windows (not sure if there's a
method to get the images that has better performance if I just need
enough for them for, say, a 120x90 pixel image instead of a whole
window). It sounds as though if I try and get the thumbnail after an
Expose event that at least that should be further along the chain than
the Map so I'll give that a go, maybe adding a small sleep after it
would do the trick.
Thanks
Re: Capturing screenshot from a minimized window
Rich wrote:[color=blue]
> On 20 Aug, 19:10, M錸s Rullg錼d <m...@mansr.com> wrote:[color=green]
>> Rich <rich.midwin...@gmail.com> writes:[color=darkred]
>> > I've been using XGetImage to capture screenshots, at the moment saving
>> > them to xpm files. I'm having two problems though:[/color]
>>[color=darkred]
>> > 1. It's very slow and freezes my system for a few seconds.[/color]
>>
>> Use XShmGetImage instead of XGetImage.
>>[color=darkred]
>> > 2. On the unmap the XGetImage doesn't take a screenshot until after
>> > the window has been unmapped, so I just get an image of what was
>> > behind it. Similarly, if I try it on the map event then I seem to
>> > catch it in the middle of painting the window.[/color]
>>
>> You're a bit vague on where these events are originating, and how you
>> are capturing them. *I'm going to assume your program requests events
>> on various windows using XSelectInput(), and attempts to take a
>> screenshot when an UnmapNotify event is received. *This, as you have
>> seen, will not work. *This is because the X server generates the event
>> after the window has already been unmapped. *Similarly, a MapNotify
>> event is generated immediately when a window is mapped, typically
>> followed by an Expose event. *When the client responsible for the
>> window receives the Expose event, it will (typically) redraw the
>> contents. *You have no way of knowing when the client is finished with
>> this (which could be never, in the case of an animation).
>>
>> --
>> M錸s Rullg錼d
>> m...@mansr.com[/color]
>
> Thanks, XShmGetImage seems to have bought me some performance, I'm
> still slightly surprised at how slow it is though, I haven't tried any
> concrete timing yet but it seems significantly slower than saving the
> image to the hard disk.
>
> I am using XSelectInput(), with SubstructureNotifyMask on the root
> window to get the UnmapNotify events.
>
> What I'm basically heading for is having a taskbar-like object on the
> screen with thumbnails of the minimized windows (not sure if there's a
> method to get the images that has better performance if I just need
> enough for them for, say, a 120x90 pixel image instead of a whole
> window). It sounds as though if I try and get the thumbnail after an
> Expose event that at least that should be further along the chain than
> the Map so I'll give that a go, maybe adding a small sleep after it
> would do the trick.
>
> Thanks[/color]
You could try using an XShm Pixmap assuming your X server supports them,
and then XCopyArea the RootWindow() to the XShm Pixmap. Then you can
continuously read and process the data from the shared memory pointer.
Oh, and it's very important that you get the bytes_per_line right when
allocating shared memory for an XShm image or pixmap.
The basic pattern (with error checking removed):
win->image = XShmCreateImage (ntk->platform.display, CopyFromParent,
win->depth, ZPixmap, NULL, &win->shminfo, win->width, win->height);
s = win->image->bytes_per_line * win->height;
win->shminfo.shmid = shmget (IPC_PRIVATE, s, IPC_CREAT | 0666);
...
win->shminfo.shmaddr = shmat (win->shminfo.shmid, NULL, 0);
XShmAttach (ntk->platform.display, &win->shminfo)
win->shm_pixmap = XShmCreatePixmap (ntk->platform.display,
win->window, win->shminfo.shmaddr, &win->shminfo, win->width,
win->height, win->depth);
XSync() is useful for sending a reqest and waiting for completion,
you'll probably need to use with XShm pixmaps.
An alternative way you may want to explore to solving your problem, is
to use Composite, Render, and Damage. Composite can make the windows
render offscreen, and you can render them scaled into your thumbnail
area, and use Damage to detect changes/damage/redraws to your windows
that you have redirected.
George
Re: Capturing screenshot from a minimized window
M氓ns Rullg氓rd writes:[color=blue]
> Rich <rich.midwinter@gmail.com> writes:[/color]
[color=blue][color=green]
>> I've been using XGetImage to capture screenshots, at the moment saving
>> them to xpm files. I'm having two problems though:
>>
>> 1. It's very slow and freezes my system for a few seconds.[/color][/color]
[color=blue]
> Use XShmGetImage instead of XGetImage.[/color]
[color=blue][color=green]
>> 2. On the unmap the XGetImage doesn't take a screenshot until after
>> the window has been unmapped, so I just get an image of what was
>> behind it. Similarly, if I try it on the map event then I seem to
>> catch it in the middle of painting the window.[/color][/color]
[color=blue]
> You're a bit vague on where these events are originating, and how you
> are capturing them. I'm going to assume your program requests events
> on various windows using XSelectInput(), and attempts to take a
> screenshot when an UnmapNotify event is received. This, as you have
> seen, will not work. This is because the X server generates the event
> after the window has already been unmapped. Similarly, a MapNotify
> event is generated immediately when a window is mapped, typically
> followed by an Expose event. When the client responsible for the
> window receives the Expose event, it will (typically) redraw the
> contents. You have no way of knowing when the client is finished with
> this (which could be never, in the case of an animation).[/color]
Okay, since window manager is responsible for unmapping the window,
the only way to get notified is to ask WM. Is there any standard way
of achieving this, probably something in ICCCM, hmm...?
Thanks
Ashish Shukla
--
路-- 路- 路路路路 路--- 路- 路路路- 路- 路--路-路 --路 -- 路- 路路 路-路路 路-路-路- -路-路 --- --
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
iEYEARECAAYFAkivHgQACgkQHy+EEHYuXnQQJgCeKMgb4J0Ny+ct9fakllMXEXhQ
GCgAnjy61ArrQhA4KQknXiRfOQzoK0qZ
=2zss
-----END PGP SIGNATURE-----
Re: Capturing screenshot from a minimized window
[email]wahjava@gmail.com[/email] (Ashish Shukla "???? ?????") writes:
[color=blue]
> M錸s Rullg錼d writes:[color=green]
>> Rich <rich.midwinter@gmail.com> writes:[/color]
>[color=green][color=darkred]
>>> I've been using XGetImage to capture screenshots, at the moment saving
>>> them to xpm files. I'm having two problems though:
>>>
>>> 1. It's very slow and freezes my system for a few seconds.[/color][/color]
>[color=green]
>> Use XShmGetImage instead of XGetImage.[/color]
>[color=green][color=darkred]
>>> 2. On the unmap the XGetImage doesn't take a screenshot until after
>>> the window has been unmapped, so I just get an image of what was
>>> behind it. Similarly, if I try it on the map event then I seem to
>>> catch it in the middle of painting the window.[/color][/color]
>[color=green]
>> You're a bit vague on where these events are originating, and how you
>> are capturing them. I'm going to assume your program requests events
>> on various windows using XSelectInput(), and attempts to take a
>> screenshot when an UnmapNotify event is received. This, as you have
>> seen, will not work. This is because the X server generates the event
>> after the window has already been unmapped. Similarly, a MapNotify
>> event is generated immediately when a window is mapped, typically
>> followed by an Expose event. When the client responsible for the
>> window receives the Expose event, it will (typically) redraw the
>> contents. You have no way of knowing when the client is finished with
>> this (which could be never, in the case of an animation).[/color]
>
> Okay, since window manager is responsible for unmapping the window,
> the only way to get notified is to ask WM. Is there any standard way
> of achieving this, probably something in ICCCM, hmm...?[/color]
The window manager is not solely responsible for this. An unmap can
be requested by any client. Usually it's the WM (through user action)
or the window owner, of course. The WM always gets notified (so it
can remove decorations). AFAIK, the window contents could already be
gone when this notification is sent.
--
M錸s Rullg錼d
[email]mans@mansr.com[/email]
Re: Capturing screenshot from a minimized window
On 21 Aug, 08:33, Rich <rich.midwin...@gmail.com> wrote:[color=blue]
> On 20 Aug, 19:10, M錸s Rullg錼d <m...@mansr.com> wrote:
>
>
>
>
>
>
>[color=green]
> > Rich <rich.midwin...@gmail.com> writes:[color=darkred]
> > > I've been using XGetImage to capture screenshots, at the moment saving
> > > them to xpm files. I'm having two problems though:[/color][/color]
>[color=green][color=darkred]
> > > 1. It's very slow and freezes my system for a few seconds.[/color][/color]
>[color=green]
> > Use XShmGetImage instead of XGetImage.[/color]
>[color=green][color=darkred]
> > > 2. On the unmap the XGetImage doesn't take a screenshot until after
> > > the window has been unmapped, so I just get an image of what was
> > > behind it. Similarly, if I try it on the map event then I seem to
> > > catch it in the middle of painting the window.[/color][/color]
>[color=green]
> > You're a bit vague on where these events are originating, and how you
> > are capturing them. *I'm going to assume your program requests events
> > on various windows using XSelectInput(), and attempts to take a
> > screenshot when an UnmapNotify event is received. *This, as you have
> > seen, will not work. *This is because the X server generates the event
> > after the window has already been unmapped. *Similarly, a MapNotify
> > event is generated immediately when a window is mapped, typically
> > followed by an Expose event. *When the client responsible for the
> > window receives the Expose event, it will (typically) redraw the
> > contents. *You have no way of knowing when the client is finished with
> > this (which could be never, in the case of an animation).[/color]
>[color=green]
> > --
> > M錸s Rullg錼d
> > m...@mansr.com[/color]
>
> Thanks, XShmGetImage seems to have bought me some performance, I'm
> still slightly surprised at how slow it is though, I haven't tried any
> concrete timing yet but it seems significantly slower than saving the
> image to the hard disk.
>
> I am using XSelectInput(), with SubstructureNotifyMask on the root
> window to get the UnmapNotify events.
>
> What I'm basically heading for is having a taskbar-like object on the
> screen with thumbnails of the minimized windows (not sure if there's a
> method to get the images that has better performance if I just need
> enough for them for, say, a 120x90 pixel image instead of a whole
> window). It sounds as though if I try and get the thumbnail after an
> Expose event that at least that should be further along the chain than
> the Map so I'll give that a go, maybe adding a small sleep after it
> would do the trick.
>
> Thanks[/color]
I found a way to take the screenshot using Imlib2, it's just about
instant now.
Thanks