diff options
author | Luboš Luňák <l.lunak@suse.cz> | 2010-12-14 18:45:15 +0100 |
---|---|---|
committer | Luboš Luňák <l.lunak@suse.cz> | 2010-12-14 19:00:41 +0100 |
commit | 693c7d4b40bb7f978764d1dde70551efa1a1f64a (patch) | |
tree | f00694b1eaa6ce83845ca3eb5b643743678ba3bc | |
parent | 04d9928159c3171b9e6fa24369cf1a431dde5be0 (diff) |
do not use QPixmap::handle(), as it may be 0
See comments in code for details. The usage of Xlib's Region type
internals is not nice, but seems to be ok in practice.
-rw-r--r-- | vcl/unx/kde4/KDESalGraphics.cxx | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/vcl/unx/kde4/KDESalGraphics.cxx b/vcl/unx/kde4/KDESalGraphics.cxx index 0e250a2fd3b7..6bdb59d032d7 100644 --- a/vcl/unx/kde4/KDESalGraphics.cxx +++ b/vcl/unx/kde4/KDESalGraphics.cxx @@ -233,6 +233,39 @@ namespace } } +#if QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) +#define IMAGE_BASED_PAINTING +#else +#undef IMAGE_BASED_PAINTING +#endif + +#ifdef IMAGE_BASED_PAINTING +// There is a small catch with this function, although hopefully only philosophical. +// Officially Xlib's Region is an opaque data type, with only functions for manipulating it. +// However, whoever designed it apparently didn't give it that much thought, as it's impossible +// to find out what exactly a region actually is (except for really weird ways like XClipBox() +// and repeated XPointInRegion(), which would be awfully slow). Fortunately, the header file +// describing the structure actually happens to be installed too, and there's at least one +// widely used software using it (Compiz). So access the data directly too and assume that +// everybody who compiles with Qt4 support has Xlib new enough and good enough to support this. +// In case this doesn't work for somebody, try #include <X11/region.h> instead, or build +// without IMAGE_BASED_PAINTING (in which case QApplication::setGraphicsSystem( "native" ) may +// be needed too). +#include <X11/Xregion.h> +static QRegion XRegionToQRegion( XLIB_Region xr ) +{ + QRegion qr; + for( int i = 0; + i < xr->numRects; + ++i ) + { + BOX& b = xr->rects[ i ]; + qr |= QRect( b.x1, b.y1, b.x2 - b.x1, b.y2 - b.y1 ); // x2,y2 is outside, not the bottom-right corner + } + return qr; +} +#endif + BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, const Rectangle& rControlRegion, ControlState nControlState, const ImplControlValue& value, @@ -562,6 +595,25 @@ BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, if (returnVal) { +#ifdef IMAGE_BASED_PAINTING + // Create a wrapper QPixmap around the destination pixmap, allowing the use of QPainter. + // Using X11SalGraphics::CopyScreenArea() would require using QPixmap and if Qt uses + // other graphics system than native, QPixmap::handle() would be 0 (i.e. it wouldn't work), + // I have no idea how to create QPixmap with non-null handle() in such case, so go this way. + // See XRegionToQRegion() comment for a small catch (although not real hopefully). + QPixmap destPixmap = QPixmap::fromX11Pixmap( GetDrawable(), QPixmap::ExplicitlyShared ); + QPainter paint( &destPixmap ); + if( pTempClipRegion && pClipRegion_ ) + paint.setClipRegion( XRegionToQRegion( pTempClipRegion ) + .intersected( XRegionToQRegion( pClipRegion_ ))); + else if( pTempClipRegion ) + paint.setClipRegion( XRegionToQRegion( pTempClipRegion )); + else if( pClipRegion_ ) + paint.setClipRegion( XRegionToQRegion( pClipRegion_ )); + paint.drawImage( widgetRect.left(), widgetRect.top(), *m_image, + 0, 0, widgetRect.width(), widgetRect.height(), + Qt::ColorOnly | Qt::OrderedDither | Qt::OrderedAlphaDither ); +#else GC gc = SelectFont(); if( gc ) @@ -588,6 +640,7 @@ BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, } else returnVal = false; +#endif } if( pTempClipRegion ) XDestroyRegion( pTempClipRegion ); |