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 /kdm/kfrontend/kgapp.cpp | |
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
Diffstat (limited to 'kdm/kfrontend/kgapp.cpp')
-rw-r--r-- | kdm/kfrontend/kgapp.cpp | 120 |
1 files changed, 113 insertions, 7 deletions
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" |