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

KWin

effects.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) 2006 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 "effects.h"
00022 
00023 #include "deleted.h"
00024 #include "client.h"
00025 #include "group.h"
00026 #include "scene_xrender.h"
00027 #include "scene_opengl.h"
00028 #include "unmanaged.h"
00029 #include "workspace.h"
00030 #include "kwinglutils.h"
00031 
00032 #include <QFile>
00033 
00034 #include "kdebug.h"
00035 #include "klibloader.h"
00036 #include "kdesktopfile.h"
00037 #include "kconfiggroup.h"
00038 #include "kstandarddirs.h"
00039 #include <kservice.h>
00040 #include <kservicetypetrader.h>
00041 #include <kplugininfo.h>
00042 
00043 #include <assert.h>
00044 
00045 
00046 namespace KWin
00047 {
00048 
00049 
00050 EffectsHandlerImpl::EffectsHandlerImpl(CompositingType type)
00051     : EffectsHandler(type)
00052     , keyboard_grab_effect( NULL )
00053     , fullscreen_effect( 0 )
00054     , next_window_quad_type( EFFECT_QUAD_TYPE_START )
00055     {
00056     reconfigure();
00057     }
00058 
00059 EffectsHandlerImpl::~EffectsHandlerImpl()
00060     {
00061     if( keyboard_grab_effect != NULL )
00062         ungrabKeyboard();
00063     foreach( const EffectPair &ep, loaded_effects )
00064         unloadEffect( ep.first );
00065     foreach( const InputWindowPair &pos, input_windows )
00066         XDestroyWindow( display(), pos.second );
00067     }
00068 
00069 void EffectsHandlerImpl::reconfigure()
00070     {
00071     KSharedConfig::Ptr _config = KGlobal::config();
00072     KConfigGroup conf(_config, "Plugins");
00073 
00074     KService::List offers = KServiceTypeTrader::self()->query("KWin/Effect");
00075     QStringList effectsToBeLoaded;
00076     // First unload necessary effects
00077     foreach( const KService::Ptr &service, offers )
00078         {
00079         KPluginInfo plugininfo( service );
00080         plugininfo.load( conf );
00081 
00082         bool isloaded = isEffectLoaded( plugininfo.pluginName() );
00083         bool shouldbeloaded = plugininfo.isPluginEnabled();
00084         if( !shouldbeloaded && isloaded )
00085             unloadEffect( plugininfo.pluginName() );
00086         if( shouldbeloaded )
00087             effectsToBeLoaded.append( plugininfo.pluginName() );
00088         }
00089     QStringList newLoaded;
00090     // Then load those that should be loaded
00091     foreach( const QString &effectName, effectsToBeLoaded )
00092         {
00093         if( !isEffectLoaded( effectName ))
00094             {
00095             loadEffect( effectName );
00096             newLoaded.append( effectName );
00097             }
00098         }
00099     foreach( const EffectPair &ep, loaded_effects )
00100         {
00101         if( !newLoaded.contains( ep.first )) // don't reconfigure newly loaded effects
00102             ep.second->reconfigure( Effect::ReconfigureAll );
00103         }
00104     }
00105 
00106 // the idea is that effects call this function again which calls the next one
00107 void EffectsHandlerImpl::prePaintScreen( ScreenPrePaintData& data, int time )
00108     {
00109     if( current_paint_screen < loaded_effects.size())
00110         {
00111         loaded_effects[current_paint_screen++].second->prePaintScreen( data, time );
00112         --current_paint_screen;
00113         }
00114     // no special final code
00115     }
00116 
00117 void EffectsHandlerImpl::paintScreen( int mask, QRegion region, ScreenPaintData& data )
00118     {
00119     if( current_paint_screen < loaded_effects.size())
00120         {
00121         loaded_effects[current_paint_screen++].second->paintScreen( mask, region, data );
00122         --current_paint_screen;
00123         }
00124     else
00125         scene->finalPaintScreen( mask, region, data );
00126     }
00127 
00128 void EffectsHandlerImpl::postPaintScreen()
00129     {
00130     if( current_paint_screen < loaded_effects.size())
00131         {
00132         loaded_effects[current_paint_screen++].second->postPaintScreen();
00133         --current_paint_screen;
00134         }
00135     // no special final code
00136     }
00137 
00138 void EffectsHandlerImpl::prePaintWindow( EffectWindow* w, WindowPrePaintData& data, int time )
00139     {
00140     if( current_paint_window < loaded_effects.size())
00141         {
00142         loaded_effects[current_paint_window++].second->prePaintWindow( w, data, time );
00143         --current_paint_window;
00144         }
00145     // no special final code
00146     }
00147 
00148 void EffectsHandlerImpl::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
00149     {
00150     if( current_paint_window < loaded_effects.size())
00151         {
00152         loaded_effects[current_paint_window++].second->paintWindow( w, mask, region, data );
00153         --current_paint_window;
00154         }
00155     else
00156         scene->finalPaintWindow( static_cast<EffectWindowImpl*>( w ), mask, region, data );
00157     }
00158 
00159 void EffectsHandlerImpl::postPaintWindow( EffectWindow* w )
00160     {
00161     if( current_paint_window < loaded_effects.size())
00162         {
00163         loaded_effects[current_paint_window++].second->postPaintWindow( w );
00164         --current_paint_window;
00165         }
00166     // no special final code
00167     }
00168 
00169 void EffectsHandlerImpl::drawWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
00170     {
00171     if( current_draw_window < loaded_effects.size())
00172         {
00173         loaded_effects[current_draw_window++].second->drawWindow( w, mask, region, data );
00174         --current_draw_window;
00175         }
00176     else
00177         scene->finalDrawWindow( static_cast<EffectWindowImpl*>( w ), mask, region, data );
00178     }
00179 
00180 void EffectsHandlerImpl::buildQuads( EffectWindow* w, WindowQuadList& quadList )
00181     {
00182     if( current_build_quads < loaded_effects.size())
00183         {
00184         loaded_effects[current_build_quads++].second->buildQuads( w, quadList );
00185         --current_build_quads;
00186         }
00187     }
00188 
00189 bool EffectsHandlerImpl::hasDecorationShadows() const
00190     {
00191     return Workspace::self()->hasDecorationShadows();
00192     }
00193 
00194 QList< QList<QImage> > EffectsHandlerImpl::shadowTextures()
00195     {
00196     return Workspace::self()->decorationShadowTextures();
00197     }
00198 
00199 int EffectsHandlerImpl::shadowTextureList( ShadowType type ) const
00200     {
00201     return Workspace::self()->decorationShadowTextureList( type );
00202     }
00203 
00204 // start another painting pass
00205 void EffectsHandlerImpl::startPaint()
00206     {
00207     assert( current_paint_screen == 0 );
00208     assert( current_paint_window == 0 );
00209     assert( current_draw_window == 0 );
00210     assert( current_build_quads == 0 );
00211     assert( current_transform == 0 );
00212     }
00213 
00214 void EffectsHandlerImpl::windowUserMovedResized( EffectWindow* c, bool first, bool last )
00215     {
00216     foreach( const EffectPair &ep, loaded_effects )
00217         ep.second->windowUserMovedResized( c, first, last );
00218     }
00219 
00220 void EffectsHandlerImpl::windowOpacityChanged( EffectWindow* c, double old_opacity )
00221     {
00222     if( static_cast<EffectWindowImpl*>(c)->window()->opacity() == old_opacity )
00223         return;
00224     foreach( const EffectPair &ep, loaded_effects )
00225         ep.second->windowOpacityChanged( c, old_opacity );
00226     }
00227 
00228 void EffectsHandlerImpl::windowAdded( EffectWindow* c )
00229     {
00230     foreach( const EffectPair &ep, loaded_effects )
00231         ep.second->windowAdded( c );
00232     }
00233 
00234 void EffectsHandlerImpl::windowDeleted( EffectWindow* c )
00235     {
00236     foreach( const EffectPair &ep, loaded_effects )
00237         ep.second->windowDeleted( c );
00238     elevated_windows.removeAll( c );
00239     }
00240 
00241 void EffectsHandlerImpl::windowClosed( EffectWindow* c )
00242     {
00243     foreach( const EffectPair &ep, loaded_effects )
00244         ep.second->windowClosed( c );
00245     }
00246 
00247 void EffectsHandlerImpl::windowActivated( EffectWindow* c )
00248     {
00249     foreach( const EffectPair &ep, loaded_effects )
00250         ep.second->windowActivated( c );
00251     }
00252 
00253 void EffectsHandlerImpl::windowMinimized( EffectWindow* c )
00254     {
00255     foreach( const EffectPair &ep, loaded_effects )
00256         ep.second->windowMinimized( c );
00257     }
00258 
00259 void EffectsHandlerImpl::windowUnminimized( EffectWindow* c )
00260     {
00261     foreach( const EffectPair &ep, loaded_effects )
00262         ep.second->windowUnminimized( c );
00263     }
00264 
00265 void EffectsHandlerImpl::desktopChanged( int old )
00266     {
00267     foreach( const EffectPair &ep, loaded_effects )
00268         ep.second->desktopChanged( old );
00269     }
00270 
00271 void EffectsHandlerImpl::windowDamaged( EffectWindow* w, const QRect& r )
00272     {
00273     if( w == NULL )
00274         return;
00275     foreach( const EffectPair &ep, loaded_effects )
00276         ep.second->windowDamaged( w, r );
00277     }
00278 
00279 void EffectsHandlerImpl::windowGeometryShapeChanged( EffectWindow* w, const QRect& old )
00280     {
00281     if( w == NULL ) // during late cleanup effectWindow() may be already NULL
00282         return;     // in some functions that may still call this
00283     foreach( const EffectPair &ep, loaded_effects )
00284         ep.second->windowGeometryShapeChanged( w, old );
00285     }
00286 
00287 void EffectsHandlerImpl::tabBoxAdded( int mode )
00288     {
00289     foreach( const EffectPair &ep, loaded_effects )
00290         ep.second->tabBoxAdded( mode );
00291     }
00292 
00293 void EffectsHandlerImpl::tabBoxClosed()
00294     {
00295     foreach( const EffectPair &ep, loaded_effects )
00296         ep.second->tabBoxClosed();
00297     }
00298 
00299 void EffectsHandlerImpl::tabBoxUpdated()
00300     {
00301     foreach( const EffectPair &ep, loaded_effects )
00302         ep.second->tabBoxUpdated();
00303     }
00304 
00305 void EffectsHandlerImpl::setActiveFullScreenEffect( Effect* e )
00306     {
00307     fullscreen_effect = e;
00308     Workspace::self()->checkUnredirect();
00309     }
00310 
00311 Effect* EffectsHandlerImpl::activeFullScreenEffect() const
00312     {
00313     return fullscreen_effect;
00314     }
00315 
00316 bool EffectsHandlerImpl::borderActivated( ElectricBorder border )
00317     {
00318     bool ret = false;
00319     foreach( const EffectPair &ep, loaded_effects )
00320         if( ep.second->borderActivated( border ))
00321             ret = true; // bail out or tell all?
00322     return ret;
00323     }
00324 
00325 void EffectsHandlerImpl::mouseChanged( const QPoint& pos, const QPoint& oldpos,
00326     Qt::MouseButtons buttons, Qt::MouseButtons oldbuttons,
00327     Qt::KeyboardModifiers modifiers, Qt::KeyboardModifiers oldmodifiers )
00328     {
00329     foreach( const EffectPair &ep, loaded_effects )
00330         ep.second->mouseChanged( pos, oldpos, buttons, oldbuttons, modifiers, oldmodifiers );
00331     }
00332 
00333 bool EffectsHandlerImpl::grabKeyboard( Effect* effect )
00334     {
00335     if( keyboard_grab_effect != NULL )
00336         return false;
00337     bool ret = grabXKeyboard();
00338     if( !ret )
00339         return false;
00340     keyboard_grab_effect = effect;
00341     return true;
00342     }
00343 
00344 void EffectsHandlerImpl::ungrabKeyboard()
00345     {
00346     assert( keyboard_grab_effect != NULL );
00347     ungrabXKeyboard();
00348     keyboard_grab_effect = NULL;
00349     }
00350 
00351 void EffectsHandlerImpl::grabbedKeyboardEvent( QKeyEvent* e )
00352     {
00353     if( keyboard_grab_effect != NULL )
00354         keyboard_grab_effect->grabbedKeyboardEvent( e );
00355     }
00356 
00357 bool EffectsHandlerImpl::hasKeyboardGrab() const
00358     {
00359     return keyboard_grab_effect != NULL;
00360     }
00361 
00362 void EffectsHandlerImpl::propertyNotify( EffectWindow* c, long atom )
00363     {
00364     if( !registered_atoms.contains( atom ))
00365         return;
00366     foreach( const EffectPair &ep, loaded_effects )
00367         ep.second->propertyNotify( c, atom );
00368     }
00369 
00370 void EffectsHandlerImpl::registerPropertyType( long atom, bool reg )
00371     {
00372     if( reg )
00373         ++registered_atoms[ atom ]; // initialized to 0 if not present yet
00374     else
00375         {
00376         if( --registered_atoms[ atom ] == 0 )
00377             registered_atoms.remove( atom );
00378         }
00379     }
00380 
00381 void EffectsHandlerImpl::activateWindow( EffectWindow* c )
00382     {
00383     if( Client* cl = dynamic_cast< Client* >( static_cast<EffectWindowImpl*>(c)->window()))
00384         Workspace::self()->activateClient( cl, true );
00385     }
00386 
00387 EffectWindow* EffectsHandlerImpl::activeWindow() const
00388     {
00389     return Workspace::self()->activeClient() ? Workspace::self()->activeClient()->effectWindow() : NULL;
00390     }
00391 
00392 void EffectsHandlerImpl::moveWindow( EffectWindow* w, const QPoint& pos )
00393     {
00394     Client* cl = dynamic_cast< Client* >( static_cast<EffectWindowImpl*>(w)->window());
00395     if( cl && cl->isMovable())
00396         cl->move( pos );
00397     }
00398 
00399 void EffectsHandlerImpl::windowToDesktop( EffectWindow* w, int desktop )
00400     {
00401     Client* cl = dynamic_cast< Client* >( static_cast<EffectWindowImpl*>(w)->window());
00402     if( cl && !cl->isDesktop() && !cl->isDock() && !cl->isTopMenu())
00403         Workspace::self()->sendClientToDesktop( cl, desktop, true );
00404     }
00405 
00406 int EffectsHandlerImpl::currentDesktop() const
00407     {
00408     return Workspace::self()->currentDesktop();
00409     }
00410 
00411 int EffectsHandlerImpl::numberOfDesktops() const
00412     {
00413     return Workspace::self()->numberOfDesktops();
00414     }
00415 
00416 void EffectsHandlerImpl::setCurrentDesktop( int desktop )
00417     {
00418     Workspace::self()->setCurrentDesktop( desktop );
00419     }
00420 
00421 QString EffectsHandlerImpl::desktopName( int desktop ) const
00422     {
00423     return Workspace::self()->desktopName( desktop );
00424     }
00425 
00426 void EffectsHandlerImpl::calcDesktopLayout(int* x, int* y, Qt::Orientation* orientation) const
00427     {
00428     Workspace::self()->calcDesktopLayout( x, y, orientation );
00429     }
00430 
00431 bool EffectsHandlerImpl::optionRollOverDesktops() const
00432     {
00433     return options->rollOverDesktops;
00434     }
00435 
00436 int EffectsHandlerImpl::desktopToLeft( int desktop, bool wrap ) const
00437     {
00438     return Workspace::self()->desktopToLeft( desktop, wrap );
00439     }
00440 
00441 int EffectsHandlerImpl::desktopToRight( int desktop, bool wrap ) const
00442     {
00443     return Workspace::self()->desktopToRight( desktop, wrap );
00444     }
00445 
00446 int EffectsHandlerImpl::desktopUp( int desktop, bool wrap ) const
00447     {
00448     return Workspace::self()->desktopUp( desktop, wrap );
00449     }
00450 
00451 int EffectsHandlerImpl::desktopDown( int desktop, bool wrap ) const
00452     {
00453     return Workspace::self()->desktopDown( desktop, wrap );
00454     }
00455 
00456 double EffectsHandlerImpl::animationTimeFactor() const
00457     {
00458     return options->animationTimeFactor();
00459     }
00460 
00461 WindowQuadType EffectsHandlerImpl::newWindowQuadType()
00462     {
00463     return WindowQuadType( next_window_quad_type++ );
00464     }
00465 
00466 int EffectsHandlerImpl::displayWidth() const
00467     {
00468     return KWin::displayWidth();
00469     }
00470 
00471 int EffectsHandlerImpl::displayHeight() const
00472     {
00473     return KWin::displayWidth();
00474     }
00475 
00476 EffectWindow* EffectsHandlerImpl::findWindow( WId id ) const
00477     {
00478     if( Client* w = Workspace::self()->findClient( WindowMatchPredicate( id )))
00479         return w->effectWindow();
00480     if( Unmanaged* w = Workspace::self()->findUnmanaged( WindowMatchPredicate( id )))
00481         return w->effectWindow();
00482     return NULL;
00483     }
00484 
00485 EffectWindowList EffectsHandlerImpl::stackingOrder() const
00486     {
00487     ClientList list = Workspace::self()->stackingOrder();
00488     EffectWindowList ret;
00489     foreach( Client* c, list )
00490         ret.append( effectWindow( c ));
00491     return ret;
00492     }
00493 
00494 void EffectsHandlerImpl::setElevatedWindow( EffectWindow* w, bool set )
00495     {
00496     elevated_windows.removeAll( w );
00497     if( set )
00498         elevated_windows.append( w );
00499     }
00500 
00501 void EffectsHandlerImpl::setTabBoxWindow(EffectWindow* w)
00502     {
00503     if( Client* c = dynamic_cast< Client* >( static_cast< EffectWindowImpl* >( w )->window()))
00504         Workspace::self()->setTabBoxClient( c );
00505     }
00506 
00507 void EffectsHandlerImpl::setTabBoxDesktop(int desktop)
00508     {
00509     Workspace::self()->setTabBoxDesktop( desktop );
00510     }
00511 
00512 EffectWindowList EffectsHandlerImpl::currentTabBoxWindowList() const
00513     {
00514     EffectWindowList ret;
00515     ClientList clients = Workspace::self()->currentTabBoxClientList();
00516     foreach( Client* c, clients )
00517         ret.append( c->effectWindow());
00518     return ret;
00519     }
00520 
00521 void EffectsHandlerImpl::refTabBox()
00522     {
00523     Workspace::self()->refTabBox();
00524     }
00525 
00526 void EffectsHandlerImpl::unrefTabBox()
00527     {
00528     Workspace::self()->unrefTabBox();
00529     }
00530 
00531 void EffectsHandlerImpl::closeTabBox()
00532     {
00533     Workspace::self()->closeTabBox();
00534     }
00535 
00536 QList< int > EffectsHandlerImpl::currentTabBoxDesktopList() const
00537     {
00538     return Workspace::self()->currentTabBoxDesktopList();
00539     }
00540 
00541 int EffectsHandlerImpl::currentTabBoxDesktop() const
00542     {
00543     return Workspace::self()->currentTabBoxDesktop();
00544     }
00545 
00546 EffectWindow* EffectsHandlerImpl::currentTabBoxWindow() const
00547     {
00548     if( Client* c = Workspace::self()->currentTabBoxClient())
00549         return c->effectWindow();
00550     return NULL;
00551     }
00552 
00553 void EffectsHandlerImpl::pushRenderTarget(GLRenderTarget* target)
00554 {
00555 #ifdef KWIN_HAVE_OPENGL_COMPOSITING
00556     target->enable();
00557     render_targets.push(target);
00558 #endif
00559 }
00560 
00561 GLRenderTarget* EffectsHandlerImpl::popRenderTarget()
00562 {
00563 #ifdef KWIN_HAVE_OPENGL_COMPOSITING
00564     GLRenderTarget* ret = render_targets.pop();
00565     ret->disable();
00566     if( !render_targets.isEmpty() )
00567         render_targets.top()->enable();
00568     return ret;
00569 #else
00570     return 0;
00571 #endif
00572 }
00573 
00574 void EffectsHandlerImpl::addRepaintFull()
00575     {
00576     Workspace::self()->addRepaintFull();
00577     }
00578 
00579 void EffectsHandlerImpl::addRepaint( const QRect& r )
00580     {
00581     Workspace::self()->addRepaint( r );
00582     }
00583 
00584 void EffectsHandlerImpl::addRepaint( const QRegion& r )
00585     {
00586     Workspace::self()->addRepaint( r );
00587     }
00588 
00589 void EffectsHandlerImpl::addRepaint( int x, int y, int w, int h )
00590     {
00591     Workspace::self()->addRepaint( x, y, w, h );
00592     }
00593 
00594 int EffectsHandlerImpl::activeScreen() const
00595     {
00596     return Workspace::self()->activeScreen();
00597     }
00598 
00599 int EffectsHandlerImpl::numScreens() const
00600     {
00601     return Workspace::self()->numScreens();
00602     }
00603 
00604 int EffectsHandlerImpl::screenNumber( const QPoint& pos ) const
00605     {
00606     return Workspace::self()->screenNumber( pos );
00607     }
00608 
00609 QRect EffectsHandlerImpl::clientArea( clientAreaOption opt, int screen, int desktop ) const
00610     {
00611     return Workspace::self()->clientArea( opt, screen, desktop );
00612     }
00613 
00614 QRect EffectsHandlerImpl::clientArea( clientAreaOption opt, const EffectWindow* c ) const
00615     {
00616     const Toplevel* t = static_cast< const EffectWindowImpl* >(c)->window();
00617     if( const Client* cl = dynamic_cast< const Client* >( t ))
00618         return Workspace::self()->clientArea( opt, cl );
00619     else
00620         return Workspace::self()->clientArea( opt, t->geometry().center(), Workspace::self()->currentDesktop());
00621     }
00622 
00623 QRect EffectsHandlerImpl::clientArea( clientAreaOption opt, const QPoint& p, int desktop ) const
00624     {
00625     return Workspace::self()->clientArea( opt, p, desktop );
00626     }
00627 
00628 Window EffectsHandlerImpl::createInputWindow( Effect* e, int x, int y, int w, int h, const QCursor& cursor )
00629     {
00630     XSetWindowAttributes attrs;
00631     attrs.override_redirect = True;
00632     Window win = XCreateWindow( display(), rootWindow(), x, y, w, h, 0, 0, InputOnly, CopyFromParent,
00633         CWOverrideRedirect, &attrs );
00634     // TODO keeping on top?
00635     // TODO enter/leave notify?
00636     XSelectInput( display(), win, ButtonPressMask | ButtonReleaseMask | PointerMotionMask );
00637     XDefineCursor( display(), win, cursor.handle());
00638     XMapWindow( display(), win );
00639     input_windows.append( qMakePair( e, win ));
00640     return win;
00641     }
00642 
00643 void EffectsHandlerImpl::destroyInputWindow( Window w )
00644     {
00645     foreach( const InputWindowPair &pos, input_windows )
00646         {
00647         if( pos.second == w )
00648             {
00649             input_windows.removeAll( pos );
00650             XDestroyWindow( display(), w );
00651             return;
00652             }
00653         }
00654     abort();
00655     }
00656 
00657 bool EffectsHandlerImpl::checkInputWindowEvent( XEvent* e )
00658     {
00659     if( e->type != ButtonPress && e->type != ButtonRelease && e->type != MotionNotify )
00660         return false;
00661     foreach( const InputWindowPair &pos, input_windows )
00662         {
00663         if( pos.second == e->xany.window )
00664             {
00665             switch( e->type )
00666                 {
00667                 case ButtonPress:
00668                     {
00669                     XButtonEvent* e2 = &e->xbutton;
00670                     Qt::MouseButton button = x11ToQtMouseButton( e2->button );
00671                     Qt::MouseButtons buttons = x11ToQtMouseButtons( e2->state ) | button;
00672                     QMouseEvent ev( QEvent::MouseButtonPress,
00673                         QPoint( e2->x, e2->y ), QPoint( e2->x_root, e2->y_root ),
00674                         button, buttons, x11ToQtKeyboardModifiers( e2->state ));
00675                     pos.first->windowInputMouseEvent( pos.second, &ev );
00676                     break; // --->
00677                     }
00678                 case ButtonRelease:
00679                     {
00680                     XButtonEvent* e2 = &e->xbutton;
00681                     Qt::MouseButton button = x11ToQtMouseButton( e2->button );
00682                     Qt::MouseButtons buttons = x11ToQtMouseButtons( e2->state ) & ~button;
00683                     QMouseEvent ev( QEvent::MouseButtonRelease,
00684                         QPoint( e2->x, e2->y ), QPoint( e2->x_root, e2->y_root ),
00685                         button, buttons, x11ToQtKeyboardModifiers( e2->state ));
00686                     pos.first->windowInputMouseEvent( pos.second, &ev );
00687                     break; // --->
00688                     }
00689                 case MotionNotify:
00690                     {
00691                     XMotionEvent* e2 = &e->xmotion;
00692                     QMouseEvent ev( QEvent::MouseMove, QPoint( e2->x, e2->y ), QPoint( e2->x_root, e2->y_root ),
00693                         Qt::NoButton, x11ToQtMouseButtons( e2->state ), x11ToQtKeyboardModifiers( e2->state ));
00694                     pos.first->windowInputMouseEvent( pos.second, &ev );
00695                     break; // --->
00696                     }
00697                 }
00698             return true; // eat event
00699             }
00700         }
00701     return false;
00702     }
00703 
00704 void EffectsHandlerImpl::checkInputWindowStacking()
00705     {
00706     if( input_windows.count() == 0 )
00707         return;
00708     Window* wins = new Window[ input_windows.count() ];
00709     int pos = 0;
00710     foreach( const InputWindowPair &it, input_windows )
00711         wins[ pos++ ] = it.second;
00712     XRaiseWindow( display(), wins[ 0 ] );
00713     XRestackWindows( display(), wins, pos );
00714     delete[] wins;
00715     }
00716 
00717 QPoint EffectsHandlerImpl::cursorPos() const
00718     {
00719     return Workspace::self()->cursorPos();
00720     }
00721 
00722 void EffectsHandlerImpl::checkElectricBorder(const QPoint &pos, Time time)
00723     {
00724     Workspace::self()->checkElectricBorder( pos, time );
00725     }
00726 
00727 void EffectsHandlerImpl::reserveElectricBorder( ElectricBorder border )
00728     {
00729     Workspace::self()->reserveElectricBorder( border );
00730     }
00731 
00732 void EffectsHandlerImpl::unreserveElectricBorder( ElectricBorder border )
00733     {
00734     Workspace::self()->unreserveElectricBorder( border );
00735     }
00736 
00737 void EffectsHandlerImpl::reserveElectricBorderSwitching( bool reserve )
00738     {
00739     Workspace::self()->reserveElectricBorderSwitching( reserve );
00740     }
00741 
00742 unsigned long EffectsHandlerImpl::xrenderBufferPicture()
00743     {
00744 #ifdef KWIN_HAVE_XRENDER_COMPOSITING
00745     if( SceneXrender* s = dynamic_cast< SceneXrender* >( scene ))
00746         return s->bufferPicture();
00747 #endif
00748     return None;
00749     }
00750 
00751 KLibrary* EffectsHandlerImpl::findEffectLibrary( KService* service )
00752     {
00753     QString libname = service->library();
00754     KLibrary* library = KLibLoader::self()->library(libname);
00755     if( !library )
00756         {
00757         kError( 1212 ) << "couldn't open library for effect '" <<
00758                 service->name() << "'" << endl;
00759         return 0;
00760         }
00761 
00762     return library;
00763     }
00764 
00765 void EffectsHandlerImpl::toggleEffect( const QString& name )
00766     {
00767     if( isEffectLoaded( name ))
00768         unloadEffect( name );
00769     else
00770         loadEffect( name );
00771     }
00772 
00773 QStringList EffectsHandlerImpl::loadedEffects() const
00774     {
00775     QStringList listModules;
00776     for(QVector< EffectPair >::const_iterator it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it)
00777         {
00778         listModules <<(*it).first;
00779         }
00780     return listModules;
00781     }
00782 
00783 QStringList EffectsHandlerImpl::listOfEffects() const
00784     {
00785     KService::List offers = KServiceTypeTrader::self()->query("KWin/Effect");
00786     QStringList listOfModules;
00787     // First unload necessary effects
00788     foreach( const KService::Ptr &service, offers )
00789         {
00790         KPluginInfo plugininfo( service );
00791         listOfModules<<plugininfo.pluginName();
00792         }
00793     return listOfModules;
00794     }
00795 
00796 bool EffectsHandlerImpl::loadEffect( const QString& name )
00797     {
00798     Workspace::self()->addRepaintFull();
00799     assert( current_paint_screen == 0 );
00800     assert( current_paint_window == 0 );
00801     assert( current_draw_window == 0 );
00802     assert( current_build_quads == 0 );
00803     assert( current_transform == 0 );
00804 
00805     if( !name.startsWith("kwin4_effect_") )
00806         kWarning( 1212 ) << "Effect names usually have kwin4_effect_ prefix" ;
00807 
00808     // Make sure a single effect won't be loaded multiple times
00809     for(QVector< EffectPair >::const_iterator it = loaded_effects.constBegin(); it != loaded_effects.constEnd(); ++it)
00810         {
00811         if( (*it).first == name )
00812             {
00813             kDebug( 1212 ) << "EffectsHandler::loadEffect : Effect already loaded : " << name;
00814             return true;
00815             }
00816         }
00817 
00818 
00819     kDebug( 1212 ) << "Trying to load " << name;
00820     QString internalname = name.toLower();
00821 
00822     QString constraint = QString("[X-KDE-PluginInfo-Name] == '%1'").arg(internalname);
00823     KService::List offers = KServiceTypeTrader::self()->query("KWin/Effect", constraint);
00824     if(offers.isEmpty())
00825     {
00826         kError( 1212 ) << "Couldn't find effect " << name << endl;
00827         return false;
00828     }
00829     KService::Ptr service = offers.first();
00830 
00831     KLibrary* library = findEffectLibrary( service.data() );
00832     if( !library )
00833         {
00834         return false;
00835         }
00836 
00837     QString version_symbol = "effect_version_" + name;
00838     KLibrary::void_function_ptr version_func = library->resolveFunction(version_symbol.toAscii());
00839     if( version_func == NULL )
00840         {
00841         kWarning( 1212 ) << "Effect " << name << " does not provide required API version, ignoring.";
00842         return false;
00843         }
00844     typedef int (*t_versionfunc)();
00845     int version = reinterpret_cast< t_versionfunc >( version_func )(); // call it
00846     // Version must be the same or less, but major must be the same.
00847     // With major 0 minor must match exactly.
00848     if( version > KWIN_EFFECT_API_VERSION
00849         || ( version >> 8 ) != KWIN_EFFECT_API_VERSION_MAJOR
00850         || ( KWIN_EFFECT_API_VERSION_MAJOR == 0 && version != KWIN_EFFECT_API_VERSION ))
00851         {
00852         kWarning( 1212 ) << "Effect " << name << " requires unsupported API version " << version;
00853         return false;
00854         }
00855     QString supported_symbol = "effect_supported_" + name;
00856     KLibrary::void_function_ptr supported_func = library->resolveFunction(supported_symbol.toAscii().data());
00857     QString create_symbol = "effect_create_" + name;
00858     KLibrary::void_function_ptr create_func = library->resolveFunction(create_symbol.toAscii().data());
00859     if( supported_func )
00860         {
00861         typedef bool (*t_supportedfunc)();
00862         t_supportedfunc supported = reinterpret_cast<t_supportedfunc>(supported_func);
00863         if(!supported())
00864             {
00865             kWarning( 1212 ) << "EffectsHandler::loadEffect : Effect " << name << " is not supported" ;
00866             library->unload();
00867             return false;
00868             }
00869         }
00870     if(!create_func)
00871         {
00872         kError( 1212 ) << "EffectsHandler::loadEffect : effect_create function not found" << endl;
00873         library->unload();
00874         return false;
00875         }
00876     typedef Effect* (*t_createfunc)();
00877     t_createfunc create = reinterpret_cast<t_createfunc>(create_func);
00878 
00879     // Make sure all depenedencies have been loaded
00880     // TODO: detect circular deps
00881     KPluginInfo plugininfo( service );
00882     QStringList dependencies = plugininfo.dependencies();
00883     foreach( const QString &depName, dependencies )
00884         {
00885         if( !loadEffect(depName))
00886             {
00887             kError(1212) << "EffectsHandler::loadEffect : Couldn't load dependencies for effect " << name << endl;
00888             library->unload();
00889             return false;
00890             }
00891         }
00892 
00893     Effect* e = create();
00894 
00895     effect_order.insert( service->property( "X-KDE-Ordering" ).toInt(), EffectPair( name, e ));
00896     effectsChanged();
00897     effect_libraries[ name ] = library;
00898 
00899     return true;
00900     }
00901 
00902 void EffectsHandlerImpl::unloadEffect( const QString& name )
00903     {
00904     Workspace::self()->addRepaintFull();
00905     assert( current_paint_screen == 0 );
00906     assert( current_paint_window == 0 );
00907     assert( current_draw_window == 0 );
00908     assert( current_build_quads == 0 );
00909     assert( current_transform == 0 );
00910 
00911     for( QMap< int, EffectPair >::iterator it = effect_order.begin(); it != effect_order.end(); ++it)
00912         {
00913         if ( it.value().first == name )
00914             {
00915             kDebug( 1212 ) << "EffectsHandler::unloadEffect : Unloading Effect : " << name;
00916             if( activeFullScreenEffect() == it.value().second )
00917                 {
00918                 setActiveFullScreenEffect( 0 );
00919                 }
00920             delete it.value().second;
00921             effect_order.erase(it);
00922             effectsChanged();
00923             effect_libraries[ name ]->unload();
00924             return;
00925             }
00926         }
00927 
00928     kDebug( 1212 ) << "EffectsHandler::unloadEffect : Effect not loaded : " << name;
00929     }
00930 
00931 void EffectsHandlerImpl::reconfigureEffect( const QString& name )
00932     {
00933     for( QVector< EffectPair >::iterator it = loaded_effects.begin(); it != loaded_effects.end(); ++it)
00934         if ( (*it).first == name )
00935             {
00936             (*it).second->reconfigure( Effect::ReconfigureAll );
00937             return;
00938             }
00939     }
00940 
00941 bool EffectsHandlerImpl::isEffectLoaded( const QString& name )
00942     {
00943     for( QVector< EffectPair >::iterator it = loaded_effects.begin(); it != loaded_effects.end(); ++it)
00944         if ( (*it).first == name )
00945             return true;
00946 
00947     return false;
00948     }
00949 
00950 void EffectsHandlerImpl::effectsChanged()
00951     {
00952     loaded_effects.clear();
00953 //    kDebug(1212) << "Recreating effects' list:";
00954     foreach( const EffectPair &effect, effect_order )
00955         {
00956 //        kDebug(1212) << effect.first;
00957         loaded_effects.append( effect );
00958         }
00959     }
00960 
00961 
00962 //****************************************
00963 // EffectWindowImpl
00964 //****************************************
00965 
00966 EffectWindowImpl::EffectWindowImpl() : EffectWindow()
00967     , toplevel( NULL )
00968     , sw( NULL )
00969     {
00970     }
00971 
00972 EffectWindowImpl::~EffectWindowImpl()
00973     {
00974     }
00975 
00976 bool EffectWindowImpl::isPaintingEnabled()
00977     {
00978     return sceneWindow()->isPaintingEnabled();
00979     }
00980 
00981 void EffectWindowImpl::enablePainting( int reason )
00982     {
00983     sceneWindow()->enablePainting( reason );
00984     }
00985 
00986 void EffectWindowImpl::disablePainting( int reason )
00987     {
00988     sceneWindow()->disablePainting( reason );
00989     }
00990 
00991 void EffectWindowImpl::addRepaint( const QRect& r )
00992     {
00993     toplevel->addRepaint( r );
00994     }
00995 
00996 void EffectWindowImpl::addRepaint( int x, int y, int w, int h )
00997     {
00998     toplevel->addRepaint( x, y, w, h );
00999     }
01000 
01001 void EffectWindowImpl::addRepaintFull()
01002     {
01003     toplevel->addRepaintFull();
01004     }
01005 
01006 int EffectWindowImpl::desktop() const
01007     {
01008     return toplevel->desktop();
01009     }
01010 
01011 bool EffectWindowImpl::isOnAllDesktops() const
01012     {
01013     return desktop() == NET::OnAllDesktops;
01014     }
01015 
01016 QString EffectWindowImpl::caption() const
01017     {
01018     if( Client* c = dynamic_cast<Client*>( toplevel ))
01019         return c->caption();
01020     else
01021         return "";
01022     }
01023 
01024 QString EffectWindowImpl::windowClass() const
01025     {
01026     return toplevel->resourceName() + ' ' + toplevel->resourceClass();
01027     }
01028 
01029 QString EffectWindowImpl::windowRole() const
01030     {
01031     return toplevel->windowRole();
01032     }
01033 
01034 QPixmap EffectWindowImpl::icon() const
01035     {
01036     if( Client* c = dynamic_cast<Client*>( toplevel ))
01037         return c->icon();
01038     return QPixmap(); // TODO
01039     }
01040 
01041 const EffectWindowGroup* EffectWindowImpl::group() const
01042     {
01043     if( Client* c = dynamic_cast< Client* >( toplevel ))
01044         return c->group()->effectGroup();
01045     return NULL; // TODO
01046     }
01047 
01048 bool EffectWindowImpl::isMinimized() const
01049     {
01050     if( Client* c = dynamic_cast<Client*>( toplevel ))
01051         return c->isMinimized();
01052     else
01053         return false;
01054     }
01055 
01056 double EffectWindowImpl::opacity() const
01057     {
01058     return toplevel->opacity();
01059     }
01060 
01061 bool EffectWindowImpl::isDeleted() const
01062     {
01063     return (dynamic_cast<Deleted*>( toplevel ) != 0);
01064     }
01065 
01066 void EffectWindowImpl::refWindow()
01067     {
01068     if( Deleted* d = dynamic_cast< Deleted* >( toplevel ))
01069         return d->refWindow();
01070     abort(); // TODO
01071     }
01072 
01073 void EffectWindowImpl::unrefWindow()
01074     {
01075     if( Deleted* d = dynamic_cast< Deleted* >( toplevel ))
01076         return d->unrefWindow( true ); // delayed
01077     abort(); // TODO
01078     }
01079 
01080 void EffectWindowImpl::setWindow( Toplevel* w )
01081     {
01082     toplevel = w;
01083     }
01084 
01085 void EffectWindowImpl::setSceneWindow( Scene::Window* w )
01086     {
01087     sw = w;
01088     }
01089 
01090 int EffectWindowImpl::x() const
01091     {
01092     return toplevel->x();
01093     }
01094 
01095 int EffectWindowImpl::y() const
01096     {
01097     return toplevel->y();
01098     }
01099 
01100 int EffectWindowImpl::width() const
01101     {
01102     return toplevel->width();
01103     }
01104 
01105 int EffectWindowImpl::height() const
01106     {
01107     return toplevel->height();
01108     }
01109 
01110 QRect EffectWindowImpl::geometry() const
01111     {
01112     return toplevel->geometry();
01113     }
01114 
01115 QRegion EffectWindowImpl::shape() const
01116     {
01117     return sw ? sw->shape() : geometry();
01118     }
01119 
01120 int EffectWindowImpl::screen() const
01121     {
01122     return toplevel->screen();
01123     }
01124 
01125 bool EffectWindowImpl::hasOwnShape() const
01126     {
01127     return toplevel->shape();
01128     }
01129 
01130 QSize EffectWindowImpl::size() const
01131     {
01132     return toplevel->size();
01133     }
01134 
01135 QPoint EffectWindowImpl::pos() const
01136     {
01137     return toplevel->pos();
01138     }
01139 
01140 QRect EffectWindowImpl::rect() const
01141     {
01142     return toplevel->rect();
01143     }
01144 
01145 QRect EffectWindowImpl::contentsRect() const
01146     {
01147     return QRect( toplevel->clientPos(), toplevel->clientSize());
01148     }
01149 
01150 QByteArray EffectWindowImpl::readProperty( long atom, long type, int format ) const
01151     {
01152     int len = 32768;
01153     for(;;)
01154         {
01155         unsigned char* data;
01156         Atom rtype;
01157         int rformat;
01158         unsigned long nitems, after;
01159         if( XGetWindowProperty( QX11Info::display(), window()->window(),
01160             atom, 0, len, False, AnyPropertyType,
01161             &rtype, &rformat, &nitems, &after, &data ) == Success )
01162             {
01163             if( after > 0 )
01164                 {
01165                 XFree( data );
01166                 len *= 2;
01167                 continue;
01168                 }
01169             if( long( rtype ) == type && rformat == format )
01170                 {
01171                 int bytelen = format == 8 ? nitems : format == 16 ? nitems * sizeof( short ) : nitems * sizeof( long );
01172                 QByteArray ret( reinterpret_cast< const char* >( data ), bytelen );
01173                 XFree( data );
01174                 return ret;
01175                 }
01176             else // wrong format, type or something
01177                 {
01178                 XFree( data );
01179                 return QByteArray();
01180                 }
01181             }
01182         else // XGetWindowProperty() failed
01183             return QByteArray();
01184         }
01185     }
01186 
01187 bool EffectWindowImpl::isMovable() const
01188     {
01189     if( Client* c = dynamic_cast< Client* >( toplevel ))
01190         return c->isMovable();
01191     return false;
01192     }
01193 
01194 bool EffectWindowImpl::isMovableAcrossScreens() const
01195     {
01196     if( Client* c = dynamic_cast< Client* >( toplevel ))
01197         return c->isMovableAcrossScreens();
01198     return false;
01199     }
01200 
01201 bool EffectWindowImpl::isUserMove() const
01202     {
01203     if( Client* c = dynamic_cast< Client* >( toplevel ))
01204         return c->isMove();
01205     return false;
01206     }
01207 
01208 bool EffectWindowImpl::isUserResize() const
01209     {
01210     if( Client* c = dynamic_cast< Client* >( toplevel ))
01211         return c->isResize();
01212     return false;
01213     }
01214 
01215 QRect EffectWindowImpl::iconGeometry() const
01216     {
01217     if( Client* c = dynamic_cast< Client* >( toplevel ))
01218         return c->iconGeometry();
01219     return QRect();
01220     }
01221 
01222 bool EffectWindowImpl::isDesktop() const
01223     {
01224     return toplevel->isDesktop();
01225     }
01226 
01227 bool EffectWindowImpl::isDock() const
01228     {
01229     return toplevel->isDock();
01230     }
01231 
01232 bool EffectWindowImpl::isToolbar() const
01233     {
01234     return toplevel->isToolbar();
01235     }
01236 
01237 bool EffectWindowImpl::isTopMenu() const
01238     {
01239     return toplevel->isTopMenu();
01240     }
01241 
01242 bool EffectWindowImpl::isMenu() const
01243     {
01244     return toplevel->isMenu();
01245     }
01246 
01247 bool EffectWindowImpl::isNormalWindow() const
01248     {
01249     return toplevel->isNormalWindow();
01250     }
01251 
01252 bool EffectWindowImpl::isSpecialWindow() const
01253     {
01254     if( Client* c = dynamic_cast<Client*>( toplevel ))
01255         return c->isSpecialWindow();
01256     else
01257         return true;
01258     }
01259 
01260 bool EffectWindowImpl::isDialog() const
01261     {
01262     return toplevel->isDialog();
01263     }
01264 
01265 bool EffectWindowImpl::isSplash() const
01266     {
01267     return toplevel->isSplash();
01268     }
01269 
01270 bool EffectWindowImpl::isUtility() const
01271     {
01272     return toplevel->isUtility();
01273     }
01274 
01275 bool EffectWindowImpl::isDropdownMenu() const
01276     {
01277     return toplevel->isDropdownMenu();
01278     }
01279 
01280 bool EffectWindowImpl::isPopupMenu() const
01281     {
01282     return toplevel->isPopupMenu();
01283     }
01284 
01285 bool EffectWindowImpl::isTooltip() const
01286     {
01287     return toplevel->isTooltip();
01288     }
01289 
01290 bool EffectWindowImpl::isNotification() const
01291     {
01292     return toplevel->isNotification();
01293     }
01294 
01295 bool EffectWindowImpl::isComboBox() const
01296     {
01297     return toplevel->isComboBox();
01298     }
01299 
01300 bool EffectWindowImpl::isDNDIcon() const
01301     {
01302     return toplevel->isDNDIcon();
01303     }
01304 
01305 bool EffectWindowImpl::isManaged() const
01306     {
01307     return dynamic_cast< const Client* >( toplevel ) != NULL;
01308     }
01309 
01310 bool EffectWindowImpl::isModal() const
01311     {
01312     if( Client* c = dynamic_cast< Client* >( toplevel ))
01313         return c->isModal();
01314     return false;
01315     }
01316 
01317 EffectWindow* EffectWindowImpl::findModal()
01318     {
01319     if( Client* c = dynamic_cast< Client* >( toplevel ))
01320         {
01321         if( Client* c2 = c->findModal())
01322             return c2->effectWindow();
01323         }
01324     return NULL;
01325     }
01326 
01327 EffectWindowList EffectWindowImpl::mainWindows() const
01328     {
01329     if( Client* c = dynamic_cast< Client* >( toplevel ))
01330         {
01331         EffectWindowList ret;
01332         ClientList mainclients = c->mainClients();
01333         foreach( Client* tmp, mainclients )
01334             ret.append( tmp->effectWindow());
01335         return ret;
01336         }
01337     return EffectWindowList();
01338     }
01339 
01340 QList<QRect> EffectWindowImpl::shadowQuads( ShadowType type ) const
01341     {
01342     if( type == ShadowBorderedActive ||  type == ShadowBorderedInactive )
01343         {
01344         if( Client* c = dynamic_cast< Client* >( toplevel ))
01345             return c->shadowQuads( type );
01346         return QList<QRect>();
01347         }
01348     return toplevel->workspace()->decorationShadowQuads( type, toplevel->size() );
01349     }
01350 
01351 double EffectWindowImpl::shadowOpacity( ShadowType type ) const
01352     {
01353     if( type == ShadowBorderedActive ||  type == ShadowBorderedInactive )
01354         {
01355         if( Client* c = dynamic_cast< Client* >( toplevel ))
01356             return c->shadowOpacity( type );
01357         return 1.0;
01358         }
01359     return toplevel->workspace()->decorationShadowOpacity( type );
01360     }
01361 
01362 double EffectWindowImpl::shadowBrightness( ShadowType type ) const
01363     {
01364     if( type == ShadowBorderedActive ||  type == ShadowBorderedInactive )
01365         {
01366         if( Client* c = dynamic_cast< Client* >( toplevel ))
01367             return c->shadowBrightness( type );
01368         return 1.0;
01369         }
01370     return toplevel->workspace()->decorationShadowBrightness( type );
01371     }
01372 
01373 double EffectWindowImpl::shadowSaturation( ShadowType type ) const
01374     {
01375     if( type == ShadowBorderedActive ||  type == ShadowBorderedInactive )
01376         {
01377         if( Client* c = dynamic_cast< Client* >( toplevel ))
01378             return c->shadowSaturation( type );
01379         return 1.0;
01380         }
01381     return toplevel->workspace()->decorationShadowSaturation( type );
01382     }
01383 
01384 WindowQuadList EffectWindowImpl::buildQuads( bool force ) const
01385     {
01386     return sceneWindow()->buildQuads( force );
01387     }
01388 
01389 EffectWindow* effectWindow( Toplevel* w )
01390     {
01391     EffectWindowImpl* ret = w->effectWindow();
01392     return ret;
01393     }
01394 
01395 EffectWindow* effectWindow( Scene::Window* w )
01396     {
01397     EffectWindowImpl* ret = w->window()->effectWindow();
01398     ret->setSceneWindow( w );
01399     return ret;
01400     }
01401 
01402 //****************************************
01403 // EffectWindowGroupImpl
01404 //****************************************
01405 
01406 
01407 EffectWindowList EffectWindowGroupImpl::members() const
01408     {
01409     EffectWindowList ret;
01410     foreach( Toplevel* c, group->members())
01411         ret.append( c->effectWindow());
01412     return ret;
01413     }
01414 
01415 } // namespace

KWin

Skip menu "KWin"
  • Main Page
  • 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