Note that there are some explanatory texts on larger screens.

plurals
  1. POKeep QPixmap copy of screen contents using X11, XDamage, XRender, and other tricks
    text
    copied!<p>I'm attempting to solve what I thought would be a very simple problem. I want to keep a QPixmap updated with the entire screen contents. You can get such a pixmap by doing this:</p> <pre><code>QDesktopWidget *w = QApplication::desktop(); if (w) { QRect r = w-&gt;screenGeometry(); QPixmap p = QPixmap::grabWindow(w-&gt;winId(), 0, 0, r.width(), r.height()) QByteArray bitmap; } </code></pre> <p>The problem with this is that QDesktopWidget ends up re-grabbing the entire screen pixmap from the X11 server every time you ask for it, even if nothing has changed. </p> <p>I need this code to be fast, so I'm trying to do this myself. My starting point was the <a href="http://labs.trolltech.com/page/Graphics/Examples/Examples2" rel="noreferrer">qx11mirror demo</a>, however, that basically does the same thing. It uses the XDamage extension to work out when something has changed, but instead of using the damaged rectangle information to just update that part of the cached pixmap, it just sets a "dirty" flag, which triggers an entire refresh anyway.</p> <p>So I'm trying to modify the qx11mirror example to just update the damaged portion of the windows, but I can't seem to get anything to work - all I get is a blank (black) pixmap. The code I'm using is:</p> <pre><code>void QX11Mirror::x11Event(XEvent *event) { if (event-&gt;type == m_damageEvent + XDamageNotify) { XDamageNotifyEvent *e = reinterpret_cast&lt;XDamageNotifyEvent*&gt;(event); XWindowAttributes attr; XGetWindowAttributes(QX11Info::display(), m_window, &amp;attr); XRenderPictFormat *format = XRenderFindVisualFormat(QX11Info::display(), attr.visual); bool hasAlpha = ( format-&gt;type == PictTypeDirect &amp;&amp; format-&gt;direct.alphaMask ); int x = attr.x; int y = attr.y; int width = attr.width; int height = attr.height; // debug output so I can see the window pos vs the damaged area: qDebug() &lt;&lt; "repainting dirty area:" &lt;&lt; x &lt;&lt; y &lt;&lt; width &lt;&lt; height &lt;&lt; "vs" &lt;&lt; e-&gt;area.x &lt;&lt; e-&gt;area.y &lt;&lt; e-&gt;area.width &lt;&lt; e-&gt;area.height; XRenderPictureAttributes pa; pa.subwindow_mode = IncludeInferiors; // Don't clip child widgets Picture picture = XRenderCreatePicture(QX11Info::display(), m_window, format, CPSubwindowMode, &amp;pa); XserverRegion region = XFixesCreateRegionFromWindow(QX11Info::display(), m_window, WindowRegionBounding); XFixesTranslateRegion(QX11Info::display(), region, -x, -y); XFixesSetPictureClipRegion(QX11Info::display(), picture, 0, 0, region); XFixesDestroyRegion(QX11Info::display(), region); //QPixmap dest(width, height); XRenderComposite(QX11Info::display(), // display hasAlpha ? PictOpOver : PictOpSrc, // operation mode picture, // src drawable None, // src mask dest.x11PictureHandle(), // dest drawable e-&gt;area.x, // src X e-&gt;area.y, // src Y 0, // mask X 0, // mask Y e-&gt;area.x, // dest X e-&gt;area.y, // dest Y e-&gt;area.width, // width e-&gt;area.height); // height m_px = dest; XDamageSubtract(QX11Info::display(), e-&gt;damage, None, None); emit windowChanged(); } else if (event-&gt;type == ConfigureNotify) { XConfigureEvent *e = &amp;event-&gt;xconfigure; m_position = QRect(e-&gt;x, e-&gt;y, e-&gt;width, e-&gt;height); emit positionChanged(m_position); } } </code></pre> <p>Can anyone point me in the right direction? The documetnation for XRender, XDamage, and the other X11 extensions is pretty bad.</p> <p><strong>Reasons for using XRender over XCopyArea</strong></p> <p>The following text taken from <a href="http://ktown.kde.org/~fredrik/composite_howto.html" rel="noreferrer">here</a>.</p> <p>It is perfectly possible to create a GC for a window and use XCopyArea() to copy the contents of the window if you want to use the core protocol, but since the Composite extension exposes new visuals (ones with alpha channels e.g.), there's no guarantee that the format of the source drawable will match that of the destination. With the core protocol that situation will result in a match error, something that won't happen with the Xrender extension.</p> <p>In addition the core protocol has no understanding of alpha channels, which means that it can't composite windows that use the new ARGB visual. When the source and destination have the same format, there's also no performance advantage to using the core protocol as of X11R6.8. That release is also the first to support the new Composite extension.</p> <p>So in conclusion there are no drawbacks, and only advantages to choosing Xrender over the core protocol for these operations.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload