Capturing screenshot from a minimized window - Xwindows

This is a discussion on Capturing screenshot from a minimized window - Xwindows ; 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 ...

+ Reply to Thread
Results 1 to 7 of 7

Thread: Capturing screenshot from a minimized window

  1. 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.

  2. Re: Capturing screenshot from a minimized window

    Rich writes:

    > 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.


    Use XShmGetImage instead of XGetImage.

    > 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.


    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
    mans@mansr.com

  3. Re: Capturing screenshot from a minimized window

    On 20 Aug, 19:10, M錸s Rullg錼d wrote:
    > Rich writes:
    > > 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.

    >
    > Use XShmGetImage instead of XGetImage.
    >
    > > 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.

    >
    > 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


    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

  4. Re: Capturing screenshot from a minimized window

    Rich wrote:
    > On 20 Aug, 19:10, M錸s Rullg錼d wrote:
    >> Rich writes:
    >> > 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.

    >>
    >> Use XShmGetImage instead of XGetImage.
    >>
    >> > 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.

    >>
    >> 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

    >
    > 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



    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

  5. Re: Capturing screenshot from a minimized window

    M氓ns Rullg氓rd writes:
    > Rich writes:


    >> 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.


    > Use XShmGetImage instead of XGetImage.


    >> 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.


    > 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).


    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-----

  6. Re: Capturing screenshot from a minimized window

    wahjava@gmail.com (Ashish Shukla "???? ?????") writes:

    > M錸s Rullg錼d writes:
    >> Rich writes:

    >
    >>> 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.

    >
    >> Use XShmGetImage instead of XGetImage.

    >
    >>> 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.

    >
    >> 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).

    >
    > 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...?


    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
    mans@mansr.com

  7. Re: Capturing screenshot from a minimized window

    On 21 Aug, 08:33, Rich wrote:
    > On 20 Aug, 19:10, M錸s Rullg錼d wrote:
    >
    >
    >
    >
    >
    >
    >
    > > Rich writes:
    > > > 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.

    >
    > > Use XShmGetImage instead of XGetImage.

    >
    > > > 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.

    >
    > > 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

    >
    > 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


    I found a way to take the screenshot using Imlib2, it's just about
    instant now.

    Thanks

+ Reply to Thread