• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

KWinLibraries

kwinxrenderutils.cpp

Go to the documentation of this file.
00001 /********************************************************************
00002  KWin - the KDE window manager
00003  This file is part of the KDE project.
00004 
00005 Copyright (C) 2008 Lubos Lunak <l.lunak@kde.org>
00006 
00007 This program is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2 of the License, or
00010 (at your option) any later version.
00011 
00012 This program is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019 *********************************************************************/
00020 
00021 #include "kwinxrenderutils.h"
00022 
00023 #ifdef KWIN_HAVE_XRENDER_COMPOSITING
00024 
00025 #include <QVector>
00026 #include <QPixmap>
00027 #include <QPainter>
00028 #include <kdebug.h>
00029 
00030 namespace KWin
00031 {
00032 
00033 // Convert QRegion to XserverRegion. All code uses XserverRegion
00034 // only when really necessary as the shared implementation uses
00035 // QRegion.
00036 XserverRegion toXserverRegion( QRegion region )
00037     {
00038     QVector< QRect > rects = region.rects();
00039     XRectangle* xr = new XRectangle[ rects.count() ];
00040     for( int i = 0;
00041          i < rects.count();
00042          ++i )
00043         {
00044         xr[ i ].x = rects[ i ].x();
00045         xr[ i ].y = rects[ i ].y();
00046         xr[ i ].width = rects[ i ].width();
00047         xr[ i ].height = rects[ i ].height();
00048         }
00049     XserverRegion ret = XFixesCreateRegion( display(), xr, rects.count());
00050     delete[] xr;
00051     return ret;
00052     }
00053 
00054 // adapted from Qt, because this really sucks ;)
00055 XRenderColor preMultiply(const QColor &c, float opacity)
00056 {
00057     XRenderColor color;
00058     const uint A = c.alpha() * opacity,
00059                R = c.red(),
00060                G = c.green(),
00061                B = c.blue();
00062     color.alpha = (A | A << 8);
00063     color.red   = (R | R << 8) * color.alpha / 0x10000;
00064     color.green = (G | G << 8) * color.alpha / 0x10000;
00065     color.blue  = (B | B << 8) * color.alpha / 0x10000;
00066     return color;
00067 }
00068 
00069 XRenderPicture xRenderFill( const XRenderColor *xc )
00070     {
00071     Pixmap pixmap = XCreatePixmap( display(), rootWindow(), 1, 1, 32 );
00072     XRenderPictureAttributes pa; pa.repeat = True;
00073     XRenderPicture fill( pixmap, 32 );
00074     XFreePixmap( display(), pixmap );
00075     XRenderChangePicture (display(), fill, CPRepeat, &pa);
00076     XRenderFillRectangle( display(), PictOpSrc, fill, xc, 0, 0, 1, 1 );
00077     return fill;
00078     }
00079 
00080 XRenderPicture xRenderFill( const QColor &c )
00081     {
00082     XRenderColor xc = preMultiply(c);
00083     return xRenderFill( &xc );
00084     }
00085 
00086 
00087 static XRenderPicture *_circle[4] = {NULL, NULL, NULL, NULL};
00088 
00089 #define DUMP_CNR(_SECT_, _W_, _H_, _XOFF_, _YOFF_)\
00090     dump = QPixmap(_W_, _H_);\
00091     dump.fill(Qt::transparent);\
00092     p.begin(&dump);\
00093     p.drawPixmap( 0, 0, tmp, _XOFF_, _YOFF_, _W_, _H_ );\
00094     p.end();\
00095     _circle[_SECT_] = new XRenderPicture(dump);
00096 
00097 #define CS 8
00098     
00099 static XRenderPicture *circle(int i)
00100     {
00101     if (!_circle[0])
00102         {
00103         QPixmap tmp(2*CS, 2*CS);
00104         tmp.fill(Qt::transparent);
00105         QPainter p(&tmp);
00106         p.setRenderHint(QPainter::Antialiasing);
00107         p.setPen(Qt::NoPen); p.setBrush(Qt::black);
00108         p.drawEllipse(tmp.rect());
00109         p.end();
00110         QPixmap dump;
00111         DUMP_CNR(0, CS, CS, 0, 0);
00112         DUMP_CNR(1, CS, CS, CS, 0);
00113         DUMP_CNR(2, CS, CS, CS, CS);
00114         DUMP_CNR(3, CS, CS, 0, CS);
00115         }
00116     return _circle[i];
00117     }
00118 
00119 void xRenderRoundBox( Picture pict, const QRect &rect, int , const QColor &c )
00120     {
00121     XRenderPicture fill = xRenderFill(c);
00122     int op = c.alpha() == 255 ? PictOpSrc : PictOpOver;
00123     // TODO: implement second paramenter "roundness"
00124     // so rather use ?? XRenderCompositeTriFan (dpy, op, src, dst, maskFormat, xSrc, ySrc,
00125                                                     //XPointFixed *points, npoint);
00126     // this will require "points on a circle" calculation, however...
00127     
00128     int s = qMin(CS, qMin(rect.height()/2, rect.width()/2));
00129     int x,y,b,r;
00130     rect.getCoords(&x,&y,&r,&b);
00131     r -= (s - 1);
00132     b -= (s - 1);
00133     XRenderComposite( display(), PictOpOver, fill, *circle(0), pict, 0, 0, 0, 0, x, y, CS, CS );
00134     XRenderComposite( display(), PictOpOver, fill, *circle(1), pict, 0, 0, CS-s, 0, r, y, s, s );
00135     XRenderComposite( display(), PictOpOver, fill, *circle(2), pict, 0, 0, CS-s, CS-s, r, b, s, s );
00136     XRenderComposite( display(), PictOpOver, fill, *circle(3), pict, 0, 0, 0, CS-s, x, b, s, s );
00137     XRenderComposite( display(), op, fill, 0, pict, 0, 0, 0, 0, x+s, y, rect.width()-2*s, s);
00138     XRenderComposite( display(), op, fill, 0, pict, 0, 0, 0, 0, x, y+s, rect.width(), rect.height()-2*s);
00139     XRenderComposite( display(), op, fill, 0, pict, 0, 0, 0, 0, x+s, b, rect.width()-2*s, s);
00140     }
00141 
00142 #undef CS
00143 #undef DUMP_CNR
00144 
00145 // XRenderFind(Standard)Format() is a roundtrip, so cache the results
00146 static XRenderPictFormat* renderformats[ 33 ];
00147 
00148 static Picture createPicture( Pixmap pix, int depth )
00149     {
00150     if( pix == None )
00151         return None;
00152     if( renderformats[ depth ] == NULL )
00153         {
00154         switch( depth)
00155             {
00156             case 1:
00157                 renderformats[ 1 ] = XRenderFindStandardFormat( display(), PictStandardA1 );
00158               break;
00159             case 8:
00160                 renderformats[ 8 ] = XRenderFindStandardFormat( display(), PictStandardA8 );
00161               break;
00162             case 24:
00163                 renderformats[ 24 ] = XRenderFindStandardFormat( display(), PictStandardRGB24 );
00164               break;
00165             case 32:
00166                 renderformats[ 32 ] = XRenderFindStandardFormat( display(), PictStandardARGB32 );
00167               break;
00168             default:
00169                 {
00170                 XRenderPictFormat req;
00171                 long mask = PictFormatType | PictFormatDepth;
00172                 req.type = PictTypeDirect;
00173                 req.depth = depth;
00174                 renderformats[ depth ] = XRenderFindFormat( display(), mask, &req, 0 );
00175               break;
00176                 }
00177             }
00178         if( renderformats[ depth ] == NULL )
00179             {
00180             kWarning( 1212 ) << "Could not find XRender format for depth" << depth;
00181             return None;
00182             }
00183         }
00184     return XRenderCreatePicture( display(), pix, renderformats[ depth ], 0, NULL );
00185     }
00186 
00187 XRenderPicture::XRenderPicture( QPixmap pix )
00188     : d( new XRenderPictureData( createPicture( pix.handle(), pix.depth())))
00189     {
00190     }
00191 
00192 XRenderPicture::XRenderPicture( Pixmap pix, int depth )
00193     : d( new XRenderPictureData( createPicture( pix, depth )))
00194     {
00195     }
00196 
00197 } // namespace
00198 
00199 #endif

KWinLibraries

Skip menu "KWinLibraries"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • KWin
  •   KWin Libraries
  • Libraries
  •   libkworkspace
  •   libsolidcontrol
  •   libtaskmanager
  • Plasma
  •   Animators
  •   Applets
  •   Engines
  • Solid Modules
Generated for API Reference by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal