summaryrefslogtreecommitdiffstats
path: root/kdm/kfrontend/kgapp.cpp
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2011-08-13 02:31:25 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2011-08-13 02:31:25 +0000
commitf50ce50331053efe6b06b3917bf07a5a64398736 (patch)
tree3b6de07bf3f62b177816725b61650cf4589a9db0 /kdm/kfrontend/kgapp.cpp
parentecb591aa8446dd7b133e1674287924a5e2c0ac14 (diff)
downloadtdebase-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.cpp120
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"