diff options
Diffstat (limited to 'kdm')
-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 |
9 files changed, 246 insertions, 36 deletions
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; |