diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2011-08-13 02:31:25 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2011-08-13 02:31:25 +0000 |
commit | f50ce50331053efe6b06b3917bf07a5a64398736 (patch) | |
tree | 3b6de07bf3f62b177816725b61650cf4589a9db0 | |
parent | ecb591aa8446dd7b133e1674287924a5e2c0ac14 (diff) | |
download | tdebase-f50ce50331053efe6b06b3917bf07a5a64398736.tar.gz tdebase-f50ce50331053efe6b06b3917bf07a5a64398736.zip |
Add Xorg composition support to kdm
KDM composition can be enabled in the control center
When enabled, it provides seamless composited logins to Trinity sessions
It also gets rid of the remaining artifacts in the themed kdm login screen
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1246834 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
-rw-r--r-- | kcontrol/kdm/kdm-appear.cpp | 30 | ||||
-rw-r--r-- | kcontrol/kdm/kdm-appear.h | 1 | ||||
-rw-r--r-- | kdm/config.def | 10 | ||||
-rw-r--r-- | kdm/kfrontend/kgapp.cpp | 120 | ||||
-rw-r--r-- | kdm/kfrontend/kgapp.h | 1 | ||||
-rw-r--r-- | kdm/kfrontend/kgreeter.h | 4 | ||||
-rw-r--r-- | kdm/kfrontend/themer/kdmitem.cpp | 30 | ||||
-rw-r--r-- | kdm/kfrontend/themer/kdmpixmap.cpp | 51 | ||||
-rw-r--r-- | kdm/kfrontend/themer/kdmrect.cpp | 25 | ||||
-rw-r--r-- | kdm/kfrontend/themer/kdmthemer.cpp | 40 | ||||
-rw-r--r-- | kdm/kfrontend/themer/kdmthemer.h | 1 | ||||
-rw-r--r-- | kwin/kompmgr/kompmgr.c | 39 |
12 files changed, 306 insertions, 46 deletions
diff --git a/kcontrol/kdm/kdm-appear.cpp b/kcontrol/kdm/kdm-appear.cpp index 08c412c26..73227ca51 100644 --- a/kcontrol/kdm/kdm-appear.cpp +++ b/kcontrol/kdm/kdm-appear.cpp @@ -169,14 +169,25 @@ KDMAppearanceWidget::KDMAppearanceWidget(TQWidget *parent, const char *name) grid->addLayout(hglay, 3, 1); hglay->setColStretch(3, 1); + compositorcombo = new KBackedComboBox(group); + compositorcombo->insertItem( "", i18n("None") ); + compositorcombo->insertItem( "kompmgr", i18n("Trinity compositor") ); + label = new TQLabel(compositorcombo, i18n("Compositor:"), group); + connect(compositorcombo, TQT_SIGNAL(activated(int)), TQT_SLOT(changed())); + hglay->addWidget(label, 0, 0); + hglay->addWidget(compositorcombo, 0, 1); + wtstr = i18n("Choose a compositor to be used in KDM. Note that the chosen compositor will continue to run after login."); + TQWhatsThis::add( label, wtstr ); + TQWhatsThis::add( compositorcombo, wtstr ); + guicombo = new KBackedComboBox(group); guicombo->insertItem( "", i18n("<default>") ); loadGuiStyles(guicombo); guicombo->listBox()->sort(); label = new TQLabel(guicombo, i18n("GUI s&tyle:"), group); connect(guicombo, TQT_SIGNAL(activated(int)), TQT_SLOT(changed())); - hglay->addWidget(label, 0, 0); - hglay->addWidget(guicombo, 0, 1); + hglay->addWidget(label, 1, 0); + hglay->addWidget(guicombo, 1, 1); wtstr = i18n("You can choose a basic GUI style here that will be " "used by KDM only."); TQWhatsThis::add( label, wtstr ); @@ -188,8 +199,8 @@ KDMAppearanceWidget::KDMAppearanceWidget(TQWidget *parent, const char *name) colcombo->listBox()->sort(); label = new TQLabel(colcombo, i18n("&Color scheme:"), group); connect(colcombo, TQT_SIGNAL(activated(int)), TQT_SLOT(changed())); - hglay->addWidget(label, 1, 0); - hglay->addWidget(colcombo, 1, 1); + hglay->addWidget(label, 2, 0); + hglay->addWidget(colcombo, 2, 1); wtstr = i18n("You can choose a basic Color Scheme here that will be " "used by KDM only."); TQWhatsThis::add( label, wtstr ); @@ -201,8 +212,8 @@ KDMAppearanceWidget::KDMAppearanceWidget(TQWidget *parent, const char *name) echocombo->insertItem("ThreeStars", i18n("Three Stars")); label = new TQLabel(echocombo, i18n("Echo &mode:"), group); connect(echocombo, TQT_SIGNAL(activated(int)), TQT_SLOT(changed())); - hglay->addWidget(label, 2, 0); - hglay->addWidget(echocombo, 2, 1); + hglay->addWidget(label, 3, 0); + hglay->addWidget(echocombo, 3, 1); wtstr = i18n("You can choose whether and how KDM shows your password when you type it."); TQWhatsThis::add( label, wtstr ); TQWhatsThis::add( echocombo, wtstr ); @@ -241,6 +252,7 @@ void KDMAppearanceWidget::makeReadOnly() logoRadio->setEnabled(false); xLineEdit->setEnabled(false); yLineEdit->setEnabled(false); + compositorcombo->setEnabled(false); guicombo->setEnabled(false); colcombo->setEnabled(false); echocombo->setEnabled(false); @@ -425,6 +437,8 @@ void KDMAppearanceWidget::save() config->writeEntry("LogoPixmap", KGlobal::iconLoader()->iconPath(logopath, KIcon::Desktop, true)); + config->writeEntry("Compositor", compositorcombo->currentId()); + config->writeEntry("GUIStyle", guicombo->currentId()); config->writeEntry("ColorScheme", colcombo->currentId()); @@ -460,6 +474,9 @@ void KDMAppearanceWidget::load() // See if we use alternate logo setLogo(config->readEntry("LogoPixmap")); + // Check the current compositor type + compositorcombo->setCurrentId(config->readEntry("Compositor")); + // Check the GUI type guicombo->setCurrentId(config->readEntry("GUIStyle")); @@ -489,6 +506,7 @@ void KDMAppearanceWidget::defaults() logoRadio->setChecked( true ); slotAreaRadioClicked( KdmLogo ); setLogo( "" ); + compositorcombo->setCurrentId( "" ); guicombo->setCurrentId( "" ); colcombo->setCurrentId( "" ); echocombo->setCurrentItem( "OneStar" ); diff --git a/kcontrol/kdm/kdm-appear.h b/kcontrol/kdm/kdm-appear.h index 91aad8173..9dc451f0a 100644 --- a/kcontrol/kdm/kdm-appear.h +++ b/kcontrol/kdm/kdm-appear.h @@ -85,6 +85,7 @@ private: TQRadioButton *logoRadio; TQLineEdit *xLineEdit; TQLineEdit *yLineEdit; + KBackedComboBox *compositorcombo; KBackedComboBox *guicombo; KBackedComboBox *colcombo; KBackedComboBox *echocombo; diff --git a/kdm/config.def b/kdm/config.def index 1dfb26ba6..a90d75efd 100644 --- a/kdm/config.def +++ b/kdm/config.def @@ -1986,6 +1986,16 @@ Description: Specify the widget style for the greeter. Empty means to use the built-in default which currently is <literal>Plastik</literal>. +Key: Compositor +Type: string +Default: "" +User: greeter +Instance: #*/"" +Comment: + Compositor binary name, if compositing is desired. "" means no compositing support. +Description: + Specify the Xorg compositing manager. Currently only kompmgr is supported. + Key: UseAdminSession Type: bool Default: false diff --git a/kdm/kfrontend/kgapp.cpp b/kdm/kfrontend/kgapp.cpp index 2e40d07ef..7c158bc42 100644 --- a/kdm/kfrontend/kgapp.cpp +++ b/kdm/kfrontend/kgapp.cpp @@ -22,6 +22,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include <config.h> + #include "kdm_greet.h" #include "kdmshutdown.h" #include "kdmconfig.h" @@ -52,6 +54,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include <X11/keysym.h> #include <X11/cursorfont.h> +#ifdef HAVE_XCOMPOSITE +#include <X11/extensions/Xrender.h> +#include <X11/extensions/Xcomposite.h> +#endif + +#include <pwd.h> + +bool argb_visual_available = false; + static int ignoreXError( Display *dpy ATTR_UNUSED, XErrorEvent *event ATTR_UNUSED ) { @@ -82,6 +93,20 @@ GreeterApp::GreeterApp() } } +GreeterApp::GreeterApp(Display *dpy) : KApplication(dpy) +{ + pingInterval = _isLocal ? 0 : _pingInterval; + if (pingInterval) { + struct sigaction sa; + sigemptyset( &sa.sa_mask ); + sa.sa_flags = 0; + sa.sa_handler = sigAlarm; + sigaction( SIGALRM, &sa, 0 ); + alarm( pingInterval * 70 ); // sic! give the "proper" pinger enough time + startTimer( pingInterval * 60000 ); + } +} + void GreeterApp::timerEvent( TQTimerEvent * ) { @@ -145,13 +170,65 @@ kg_main( const char *argv0 ) kde_have_kipc = false; KApplication::disableAutoDcopRegistration(); KCrash::setSafer( true ); - GreeterApp app; + +#ifdef HAVE_XCOMPOSITE + // Begin ARGB initialization + XSetErrorHandler( ignoreXError ); + argb_visual_available = false; + char *display = 0; + + Display *dpyi = XOpenDisplay( display ); + if ( !dpyi ) { + kdError() << "cannot connect to X server " << display << endl; + exit( 1 ); + } + + int screen = DefaultScreen( dpyi ); + Colormap colormap = 0; + Visual *visual = 0; + int event_base, error_base; + + if ( XRenderQueryExtension( dpyi, &event_base, &error_base ) ) { + int nvi; + XVisualInfo templ; + templ.screen = screen; + templ.depth = 32; + templ.c_class = TrueColor; + XVisualInfo *xvi = XGetVisualInfo( dpyi, VisualScreenMask | VisualDepthMask + | VisualClassMask, &templ, &nvi ); + + for ( int i = 0; i < nvi; i++ ) { + XRenderPictFormat *format = XRenderFindVisualFormat( dpyi, xvi[i].visual ); + if ( format->type == PictTypeDirect && format->direct.alphaMask ) { + visual = xvi[i].visual; + colormap = XCreateColormap( dpyi, RootWindow( dpyi, screen ), visual, AllocNone ); + kdDebug() << "found visual with alpha support" << endl; + argb_visual_available = true; + break; + } + } + } + XSetErrorHandler( (XErrorHandler)0 ); + + GreeterApp *app; + if( argb_visual_available ) { + app = new GreeterApp(dpyi); + } + else { + app = new GreeterApp(); + } + // End ARGB initialization +#else + GreeterApp *app = new GreeterApp(); +#endif + XSetIOErrorHandler( xIOErr ); + TQString login_user; Display *dpy = qt_xdisplay(); if (!_GUIStyle.isEmpty()) - app.setStyle( _GUIStyle ); + app->setStyle( _GUIStyle ); // Load up the systemwide ICC profile TQString iccConfigFile = TQString(KDE_CONFDIR); @@ -168,14 +245,15 @@ kg_main( const char *argv0 ) if (!_colorScheme.isEmpty()) { KSimpleConfig config( _colorScheme, true ); config.setGroup( "Color Scheme" ); - app.setPalette( app.createApplicationPalette( &config, 7 ) ); + app->setPalette( app->createApplicationPalette( &config, 7 ) ); } - app.setFont( _normalFont ); + app->setFont( _normalFont ); setup_modifiers( dpy, _numLockStatus ); SecureDisplay( dpy ); KProcess *proc = 0; + KProcess *comp = 0; if (!_grabServer) { if (_useBackground) { proc = new KProcess; @@ -187,10 +265,16 @@ kg_main( const char *argv0 ) GRecvInt(); } + if (!_compositor.isEmpty()) { + comp = new KProcess; + *comp << TQCString( argv0, strrchr( argv0, '/' ) - argv0 + 2 ) + _compositor.ascii(); + comp->start(KProcess::NotifyOnExit, KProcess::Stdin); + } + GSendInt( G_Ready ); kdDebug() << timestamp() << " main1" << endl; - setCursor( dpy, app.desktop()->winId(), XC_left_ptr ); + setCursor( dpy, app->desktop()->winId(), XC_left_ptr ); for (;;) { int rslt, cmd = GRecvInt(); @@ -214,7 +298,7 @@ kg_main( const char *argv0 ) } KProcess *proc2 = 0; - app.setOverrideCursor( Qt::WaitCursor ); + app->setOverrideCursor( Qt::WaitCursor ); FDialog *dialog; #ifdef XDMCP if (cmd == G_Choose) { @@ -247,7 +331,7 @@ kg_main( const char *argv0 ) proc2->start(); } } - app.restoreOverrideCursor(); + app->restoreOverrideCursor(); Debug( "entering event loop\n" ); // Qt4 has a nasty habit of generating BadWindow errors in normal operation, so we simply ignore them // This also prevents the user from being dropped to a console login if Xorg glitches or is buggy @@ -255,6 +339,9 @@ kg_main( const char *argv0 ) rslt = dialog->exec(); XSetErrorHandler( (XErrorHandler)0 ); Debug( "left event loop\n" ); + + login_user = static_cast<KGreeter*>(dialog)->curUser; + delete dialog; delete proc2; #ifdef XDMCP @@ -274,11 +361,30 @@ kg_main( const char *argv0 ) KGVerify::done(); + if (comp) { + if (_compositor == "kompmgr") { + // Change process UID + // Get user UID + passwd* userinfo = getpwnam(login_user.ascii()); + TQString newuid = TQString("%1").arg(userinfo->pw_uid); + // kompmgr allows us to change its uid in this manner: + // 1.) Send SIGUSER1 + // 2.) Send the new UID to it on the command line + comp->kill(SIGUSR1); + comp->writeStdin(newuid.ascii(), newuid.length()); + usleep(50000); // Give the above function some time to execute. Note that on REALLY slow systems this could fail, leaving kompmgr running as root. TODO: Look into ways to make this more robust. + } + comp->closeStdin(); + comp->detach(); + delete comp; + } delete proc; UnsecureDisplay( dpy ); restore_modifiers(); XSetInputFocus( qt_xdisplay(), PointerRoot, PointerRoot, CurrentTime ); + + delete app; } } // extern "C" diff --git a/kdm/kfrontend/kgapp.h b/kdm/kfrontend/kgapp.h index f01ba1baa..38c73d3c1 100644 --- a/kdm/kfrontend/kgapp.h +++ b/kdm/kfrontend/kgapp.h @@ -34,6 +34,7 @@ class GreeterApp : public KApplication { public: GreeterApp(); + GreeterApp(Display *dpy); virtual bool x11EventFilter( XEvent * ); protected: diff --git a/kdm/kfrontend/kgreeter.h b/kdm/kfrontend/kgreeter.h index fdbd56209..8675f052a 100644 --- a/kdm/kfrontend/kgreeter.h +++ b/kdm/kfrontend/kgreeter.h @@ -72,6 +72,9 @@ class KGreeter : public KGDialog, public KGVerifyHandler { void slotSessionSelected( int ); void slotUserEntered(); + public: + TQString curUser, dName; + protected: void readFacesList(); void installUserList(); @@ -82,7 +85,6 @@ class KGreeter : public KGDialog, public KGVerifyHandler { virtual void pluginSetup(); void setPrevWM( int ); - TQString curUser, dName; KSimpleConfig *stsFile; UserListView *userView; TQStringList *userList; diff --git a/kdm/kfrontend/themer/kdmitem.cpp b/kdm/kfrontend/themer/kdmitem.cpp index 88e5a7489..eb5283cd9 100644 --- a/kdm/kfrontend/themer/kdmitem.cpp +++ b/kdm/kfrontend/themer/kdmitem.cpp @@ -38,6 +38,8 @@ #include <tqimage.h> #include <tqpainter.h> +extern bool argb_visual_available; + KdmItem::KdmItem( KdmItem *parent, const TQDomNode &node, const char *name ) : TQObject( parent, name ) , boxManager( 0 ) @@ -289,11 +291,13 @@ KdmItem::paint( TQPainter *p, const TQRect &rect ) if (myWidget || (myLayoutItem && myLayoutItem->widget())) { // KListView because it's missing a Q_OBJECT' - // FIXME: This is a nice idea intheory, but in practice it is + // FIXME: This is a nice idea in theory, but in practice it is // very confusing for the user not to see the empty list box // delineated from the rest of the greeter. // Maybe set a darker version of the background instead of an exact copy? if ( myWidget && myWidget->isA( "KListView" ) ) { + if ((_compositor.isEmpty()) || (!argb_visual_available)) { + // Software blend only (no compositing support) TQPixmap copy( myWidget->size() ); kdDebug() << myWidget->tqgeometry() << " " << area << " " << myWidget->size() << endl; bitBlt( ©, TQPoint( 0, 0), p->device(), myWidget->geometry(), TQt::CopyROP ); @@ -327,6 +331,30 @@ KdmItem::paint( TQPainter *p, const TQRect &rect ) copy = lightVersion; // Set it myWidget->setPaletteBackgroundPixmap( copy ); + } + else { + // We have compositing support! + TQRgb blend_color = tqRgba(m_backgroundModifier, m_backgroundModifier, m_backgroundModifier, 0); // RGBA overlay + float alpha = tqAlpha(blend_color) / 255.; + int pixel = tqAlpha(blend_color) << 24 | + int(tqRed(blend_color) * alpha) << 16 | + int(tqGreen(blend_color) * alpha) << 8 | + int(tqBlue(blend_color) * alpha); + + TQImage img( myWidget->size(), 32 ); + img = img.convertDepth(32); + img.setAlphaBuffer(true); + register uchar * rd = img.bits(); + for( int y = 0; y < img.height(); ++y ) + { + for( short int x = 0; x < img.width(); ++x ) + { + *reinterpret_cast<TQRgb*>(rd) = blend_color; + rd += 4; + } + } + myWidget->setPaletteBackgroundPixmap( img ); + } } return; } diff --git a/kdm/kfrontend/themer/kdmpixmap.cpp b/kdm/kfrontend/themer/kdmpixmap.cpp index af64714b8..436483c48 100644 --- a/kdm/kfrontend/themer/kdmpixmap.cpp +++ b/kdm/kfrontend/themer/kdmpixmap.cpp @@ -37,6 +37,8 @@ #include <tqpixmap.h> #include <tqimage.h> +extern bool argb_visual_available; + KdmPixmap::KdmPixmap( KdmItem *parent, const TQDomNode &node, const char *name ) : KdmItem( parent, node, name ) { @@ -47,6 +49,7 @@ KdmPixmap::KdmPixmap( KdmItem *parent, const TQDomNode &node, const char *name ) pixmap.normal.alpha = 0.0; pixmap.active.present = false; pixmap.prelight.present = false; + bool true_transparency = false; // Read PIXMAP ID // it rarely happens that a pixmap can be a button too! @@ -66,13 +69,20 @@ KdmPixmap::KdmPixmap( KdmItem *parent, const TQDomNode &node, const char *name ) pixmap.normal.alpha = el.attribute( "alpha", "1.0" ).toFloat(); if (el.attribute( "file", "" ) == "@@@KDMBACKGROUND@@@") { - // Use the preset KDM background... - KStandardDirs *m_pDirs = KGlobal::dirs(); - KSimpleConfig *config = new KSimpleConfig( TQFile::decodeName( _backgroundCfg ) ); - config->setGroup("Desktop0"); - pixmap.normal.fullpath = m_pDirs->findResource("wallpaper", config->readPathEntry("Wallpaper")); - // TODO: Detect when there is no wallpaper and use the background settings instead - delete config; + if ((_compositor.isEmpty()) || (!argb_visual_available)) { + // Software blend only (no compositing support) + // Use the preset KDM background... + KStandardDirs *m_pDirs = KGlobal::dirs(); + KSimpleConfig *config = new KSimpleConfig( TQFile::decodeName( _backgroundCfg ) ); + config->setGroup("Desktop0"); + pixmap.normal.fullpath = m_pDirs->findResource("wallpaper", config->readPathEntry("Wallpaper")); + // TODO: Detect when there is no wallpaper and use the background settings instead + delete config; + } + else { + true_transparency = true; + pixmap.normal.alpha = 0.0; + } } } else if (tagName == "active") { @@ -189,7 +199,6 @@ KdmPixmap::drawContents( TQPainter *p, const TQRect &r ) kdDebug() << "draw " << id << " " << pClass->pixmap.isNull() << endl; if (pClass->pixmap.isNull()) { - if (pClass->fullpath.isEmpty()) // if neither is set, we're empty return; @@ -246,7 +255,7 @@ KdmPixmap::drawContents( TQPainter *p, const TQRect &r ) if (haveTint || haveAlpha) { scaledImage = pClass->pixmap.convertToImage(); - // enforce rgba values for the later + // enforce rgba values for the latter scaledImage = scaledImage.convertDepth( 32 ); } else @@ -275,7 +284,31 @@ KdmPixmap::drawContents( TQPainter *p, const TQRect &r ) ls[x] = tqRgba( r, g, b, a ); } } + } + if ((_compositor.isEmpty()) || (!argb_visual_available)) { + // Software blend only (no compositing support) + } + else { + // We have a compositor! + // Apply the alpha in the same manner as above, exept we are now + // using the hardware blending engine for all painting + scaledImage = pClass->readyPixmap; + scaledImage = scaledImage.convertDepth( 32 ); + int w = scaledImage.width(); + int h = scaledImage.height(); + for (int y = 0; y < h; ++y) { + QRgb *ls = (QRgb *)scaledImage.scanLine( y ); + for (int x = 0; x < w; ++x) { + QRgb l = ls[x]; + float alpha_adjust = (tqAlpha( l )/256.0); + int r = int( tqRed( l ) * alpha_adjust ); + int g = int( tqGreen( l ) * alpha_adjust ); + int b = int( tqBlue( l ) * alpha_adjust ); + int a = int( tqAlpha( l ) * 1 ); + ls[x] = tqRgba( r, g, b, a ); + } + } } if (!scaledImage.isNull()) { diff --git a/kdm/kfrontend/themer/kdmrect.cpp b/kdm/kfrontend/themer/kdmrect.cpp index 1d854d213..1db128da0 100644 --- a/kdm/kfrontend/themer/kdmrect.cpp +++ b/kdm/kfrontend/themer/kdmrect.cpp @@ -21,6 +21,7 @@ #include "kdmrect.h" #include "kdmthemer.h" +#include "kdmconfig.h" #include <kimageeffect.h> #include <kdebug.h> @@ -30,6 +31,8 @@ #include <tqwidget.h> #include <tqlayout.h> +extern bool argb_visual_available; + KdmRect::KdmRect( KdmItem *parent, const TQDomNode &node, const char *name ) : KdmItem( parent, node, name ) { @@ -103,14 +106,20 @@ KdmRect::drawContents( TQPainter *p, const TQRect &r ) if (rClass->alpha == 1) p->fillRect( area, TQBrush( rClass->color ) ); else { - TQRect backRect = r; - backRect.moveBy( area.x(), area.y() ); - TQPixmap backPixmap( backRect.size() ); - bitBlt( &backPixmap, TQPoint( 0, 0 ), p->device(), backRect ); - TQImage backImage = backPixmap.convertToImage(); - KImageEffect::blend( rClass->color, backImage, rClass->alpha ); - p->drawImage( backRect.x(), backRect.y(), backImage ); - // area.moveBy(1,1); +// if ((_compositor.isEmpty()) || (!argb_visual_available)) { + // Software blend only (no compositing support) + TQRect backRect = r; + backRect.moveBy( area.x(), area.y() ); + TQPixmap backPixmap( backRect.size() ); + bitBlt( &backPixmap, TQPoint( 0, 0 ), p->device(), backRect ); + TQImage backImage = backPixmap.convertToImage(); + KImageEffect::blend( rClass->color, backImage, rClass->alpha ); + p->drawImage( backRect.x(), backRect.y(), backImage ); + // area.moveBy(1,1); +// } +// else { +// // We have compositing support! +// } } } diff --git a/kdm/kfrontend/themer/kdmthemer.cpp b/kdm/kfrontend/themer/kdmthemer.cpp index d6b2e6e0e..39a1abe81 100644 --- a/kdm/kfrontend/themer/kdmthemer.cpp +++ b/kdm/kfrontend/themer/kdmthemer.cpp @@ -46,6 +46,8 @@ #include <unistd.h> +extern bool argb_visual_available; + /* * KdmThemer. The main theming interface */ @@ -159,17 +161,35 @@ KdmThemer::widgetEvent( TQEvent *e ) TQRect paintRect = TQT_TQPAINTEVENT(e)->rect(); kdDebug() << timestamp() << " paint on: " << paintRect << endl; - if (!backBuffer) - backBuffer = new TQPixmap( widget()->size() ); - if (backBuffer->size() != widget()->size()) - backBuffer->resize( widget()->size() ); - - TQPainter p; - p.begin( backBuffer ); - rootItem->paint( &p, paintRect ); - p.end(); + if ((_compositor.isEmpty()) || (!argb_visual_available)) { + // Software blend only (no compositing support) + if (!backBuffer) + backBuffer = new TQPixmap( widget()->size() ); + if (backBuffer->size() != widget()->size()) + backBuffer->resize( widget()->size() ); + + TQPainter p; + p.begin( backBuffer ); + rootItem->paint( &p, paintRect ); + p.end(); + + bitBlt( widget(), paintRect.topLeft(), backBuffer, paintRect ); + } + else { + // We have compositing support! + TQRgb blend_color = tqRgba(0, 0, 0, 0); // RGBA + float alpha = tqAlpha(blend_color) / 255.; + int pixel = tqAlpha(blend_color) << 24 | + int(tqRed(blend_color) * alpha) << 16 | + int(tqGreen(blend_color) * alpha) << 8 | + int(tqBlue(blend_color) * alpha); + TQPainter p1; + p1.begin( widget() ); + p1.fillRect( paintRect, TQColor(blend_color, pixel) ); + rootItem->paint( &p1, paintRect ); + p1.end(); + } - bitBlt( widget(), paintRect.topLeft(), backBuffer, paintRect ); } break; default: diff --git a/kdm/kfrontend/themer/kdmthemer.h b/kdm/kfrontend/themer/kdmthemer.h index e5228973e..e6e5efdb4 100644 --- a/kdm/kfrontend/themer/kdmthemer.h +++ b/kdm/kfrontend/themer/kdmthemer.h @@ -24,6 +24,7 @@ #include <tqobject.h> #include <tqdom.h> +#include <tqimage.h> class KdmThemer; class KdmItem; diff --git a/kwin/kompmgr/kompmgr.c b/kwin/kompmgr/kompmgr.c index 8a7abb94e..2aef59772 100644 --- a/kwin/kompmgr/kompmgr.c +++ b/kwin/kompmgr/kompmgr.c @@ -34,6 +34,7 @@ * CHANGELOG: * http://patchwork.freedesktop.org/patch/1049/ [Add default background color option] 08/11/2011 * http://patchwork.freedesktop.org/patch/1052/ [Prevent flicker on root pixmap change] 08/11/2011 + * Added SIGUSER1 handler to change process UID [Prevent flicker on login] 08/12/2011 * * TODO: * http://patchwork.freedesktop.org/patch/1053/ [Fix window mapping with re-used window ids] @@ -50,6 +51,8 @@ check baghira.sf.net for more infos #include <math.h> #include <sys/poll.h> #include <sys/time.h> +#include <sys/types.h> +#include <signal.h> #include <time.h> #include <unistd.h> #include <X11/Xlib.h> @@ -135,6 +138,9 @@ typedef struct _fade { Bool gone; } fade; +struct sigaction usr_action; +sigset_t block_mask; + win *list; fade *fades; Display *dpy; @@ -203,6 +209,7 @@ conv *gaussianMap; #define TRANS_OPACITY 0.75 +#define NDEBUG 1 #define DEBUG_REPAINT 0 #define DEBUG_EVENTS 0 #define MONITOR_REPAINT 0 @@ -218,7 +225,7 @@ typedef enum _compMode { static void determine_mode(Display *dpy, win *w); - + static double get_opacity_percent(Display *dpy, win *w, double def); @@ -267,11 +274,28 @@ get_time_in_milliseconds () return tv.tv_sec * 1000 + tv.tv_usec / 1000; } +void handle_siguser (int sig) +{ + char newuid[1024]; +#ifndef NDEBUG + printf("Enter the new user ID:\n\r"); fflush(stdout); +#endif + char *eof; + newuid[0] = '\0'; + newuid[sizeof(newuid)-1] = '\0'; + eof = fgets(newuid, sizeof(newuid), stdin); + int uidnum = atoi(newuid); +#ifndef NDEBUG + printf("Setting kompmgr process uid to %d...\n\r", uidnum); fflush(stdout); +#endif + setuid(uidnum); +} + fade * find_fade (win *w) { fade *f; - + for (f = fades; f; f = f->next) { if (f->w == w) @@ -2509,7 +2533,7 @@ usage (char *program) fprintf (stderr, " -o opacity\n Specifies the translucency for client-side shadows. (default .75)\n"); fprintf (stderr, " -l left-offset\n Specifies the left offset for client-side shadows. (default -15)\n"); fprintf (stderr, " -t top-offset\n Specifies the top offset for clinet-side shadows. (default -15)\n"); - fprintf (stderr, " -b color\n Specifies the background color to use if no root pixmap is set. (default is a gray)\n"); + fprintf (stderr, " -b color\n Specifies the background color to use if no root pixmap is set. (default is black)\n"); fprintf (stderr, " -I fade-in-step\n Specifies the opacity change between steps while fading in. (default 0.028)\n"); fprintf (stderr, " -O fade-out-step\n Specifies the opacity change between steps while fading out. (default 0.03)\n"); fprintf (stderr, " -D fade-delta-time\n Specifies the time between steps in a fade in milliseconds. (default 10)\n"); @@ -2568,6 +2592,13 @@ main (int argc, char **argv) shadowColor.green = 0; shadowColor.blue = 0; + // Initialize signal handlers + sigfillset(&block_mask); + usr_action.sa_handler = handle_siguser; + usr_action.sa_mask = block_mask; + usr_action.sa_flags = 0; + sigaction(SIGUSR1, &usr_action, NULL); + loadConfig(NULL); /*we do that before cmdline-parsing, so config-values can be overridden*/ /*used for shadow colors*/ while ((o = getopt (argc, argv, "D:I:O:d:r:o:l:t:b:scnfFmCaSx:vh")) != -1) @@ -2739,7 +2770,7 @@ main (int argc, char **argv) } else { - fill_color.red = fill_color.green = fill_color.blue = 0x8080; + fill_color.red = fill_color.green = fill_color.blue = 0x0; } fill_color.alpha = 0xffff; |