diff options
Diffstat (limited to 'kdesktop/lock/main.cc')
-rw-r--r-- | kdesktop/lock/main.cc | 309 |
1 files changed, 205 insertions, 104 deletions
diff --git a/kdesktop/lock/main.cc b/kdesktop/lock/main.cc index 132ff3094..4edd1b321 100644 --- a/kdesktop/lock/main.cc +++ b/kdesktop/lock/main.cc @@ -73,140 +73,241 @@ static KCmdLineOptions options[] = { "dontlock", I18N_NOOP("Only start screensaver"), 0 }, { "securedialog", I18N_NOOP("Launch the secure dialog"), 0 }, { "blank", I18N_NOOP("Only use the blank screensaver"), 0 }, + { "internal <pid>", I18N_NOOP("TDE internal command for background process loading"), 0 }, KCmdLineLastOption }; +static void sigusr1_handler(int) +{ + signalled_forcelock = TRUE; +} + +static void sigusr2_handler(int) +{ + signalled_dontlock = TRUE; +} + +static void sigusr3_handler(int) +{ + signalled_securedialog = TRUE; +} + +static void sigusr4_handler(int) +{ + signalled_blank = TRUE; +} + +static void sigusr5_handler(int) +{ + signalled_run = TRUE; +} + // ----------------------------------------------------------------------------- int main( int argc, char **argv ) { KLocale::setMainCatalogue("kdesktop"); - KCmdLineArgs::init( argc, argv, "kdesktop_lock", I18N_NOOP("KDesktop Locker"), I18N_NOOP("Session Locker for KDesktop"), "2.0" ); + KCmdLineArgs::init( argc, argv, "kdesktop_lock", I18N_NOOP("KDesktop Locker"), I18N_NOOP("Session Locker for KDesktop"), "2.1" ); KCmdLineArgs::addCmdLineOptions( options ); KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); - if (args->isSet( "forcelock" )) - trinity_desktop_lock_forced = TRUE; - putenv(strdup("SESSION_MANAGER=")); KApplication::disableAutoDcopRegistration(); // not needed - int kdesktop_screen_number = 0; - int starting_screen = 0; - - bool child = false; - int parent_connection = 0; // socket to the parent saver - TQValueList<int> child_sockets; - - if (KGlobalSettings::isMultiHead()) - { - Display *dpy = XOpenDisplay(NULL); - if (! dpy) { - fprintf(stderr, - "%s: FATAL ERROR: couldn't open display '%s'\n", - argv[0], XDisplayName(NULL)); - exit(1); - } + while (1 == 1) { + signalled_forcelock = FALSE; + signalled_dontlock = FALSE; + signalled_securedialog = FALSE; + signalled_blank = FALSE; + signalled_run = FALSE; - int number_of_screens = ScreenCount(dpy); - starting_screen = kdesktop_screen_number = DefaultScreen(dpy); - int pos; - TQCString display_name = XDisplayString(dpy); - XCloseDisplay(dpy); - kdDebug() << "screen " << number_of_screens << " " << kdesktop_screen_number << " " << display_name << " " << starting_screen << endl; - dpy = 0; - - if ((pos = display_name.findRev('.')) != -1) - display_name.remove(pos, 10); - - TQCString env; - if (number_of_screens != 1) { - for (int i = 0; i < number_of_screens; i++) { - if (i != starting_screen) { - int fd[2]; - if (pipe(fd)) { - perror("pipe"); - break; - } - if (fork() == 0) { - child = true; - kdesktop_screen_number = i; - parent_connection = fd[0]; - // break here because we are the child process, we don't - // want to fork() anymore - break; - } else { - child_sockets.append(fd[1]); + int kdesktop_screen_number = 0; + int starting_screen = 0; + + bool child = false; + int parent_connection = 0; // socket to the parent saver + TQValueList<int> child_sockets; + + if (KGlobalSettings::isMultiHead()) + { + Display *dpy = XOpenDisplay(NULL); + if (! dpy) { + fprintf(stderr, + "%s: FATAL ERROR: couldn't open display '%s'\n", + argv[0], XDisplayName(NULL)); + exit(1); + } + + int number_of_screens = ScreenCount(dpy); + starting_screen = kdesktop_screen_number = DefaultScreen(dpy); + int pos; + TQCString display_name = XDisplayString(dpy); + XCloseDisplay(dpy); + kdDebug() << "screen " << number_of_screens << " " << kdesktop_screen_number << " " << display_name << " " << starting_screen << endl; + dpy = 0; + + if ((pos = display_name.findRev('.')) != -1) + display_name.remove(pos, 10); + + TQCString env; + if (number_of_screens != 1) { + for (int i = 0; i < number_of_screens; i++) { + if (i != starting_screen) { + int fd[2]; + if (pipe(fd)) { + perror("pipe"); + break; + } + if (fork() == 0) { + child = true; + kdesktop_screen_number = i; + parent_connection = fd[0]; + // break here because we are the child process, we don't + // want to fork() anymore + break; + } else { + child_sockets.append(fd[1]); + } } } - } - env.sprintf("DISPLAY=%s.%d", display_name.data(), - kdesktop_screen_number); - kdDebug() << "env " << env << endl; + env.sprintf("DISPLAY=%s.%d", display_name.data(), + kdesktop_screen_number); + kdDebug() << "env " << env << endl; - if (putenv(strdup(env.data()))) { - fprintf(stderr, - "%s: WARNING: unable to set DISPLAY environment variable\n", - argv[0]); - perror("putenv()"); + if (putenv(strdup(env.data()))) { + fprintf(stderr, + "%s: WARNING: unable to set DISPLAY environment variable\n", + argv[0]); + perror("putenv()"); + } } } - } - MyApp app; - kdDebug() << "app " << kdesktop_screen_number << " " << starting_screen << " " << child << " " << child_sockets.count() << " " << parent_connection << endl; - app.disableSessionManagement(); - KGlobal::locale()->insertCatalogue("libdmctl"); - - // we need to read from the right rc file - possibly taking screen number in account - KDesktopSettings::instance("kdesktoprc"); - - trinity_desktop_lock_use_system_modal_dialogs = !KDesktopSettings::useUnmanagedLockWindows(); - trinity_desktop_lock_delay_screensaver_start = KDesktopSettings::delaySaverStart(); - trinity_desktop_lock_use_sak = KDesktopSettings::useTDESAK(); - - LockProcess process(child, args->isSet( "blank" )); - if (!child) - process.setChildren(child_sockets); - else - process.setParent(parent_connection); - - bool rt; - bool sig = false; - if( !child && args->isSet( "forcelock" )) - { - rt = process.lock(); - sig = true; - } - else if( child || args->isSet( "dontlock" )) { - rt = process.dontLock(); - } - else if( child || args->isSet( "securedialog" )) { - int retcode = tde_sak_verify_calling_process(); - if (retcode == 0) { - rt = process.runSecureDialog(); + MyApp app; + kdDebug() << "app " << kdesktop_screen_number << " " << starting_screen << " " << child << " " << child_sockets.count() << " " << parent_connection << endl; + app.disableSessionManagement(); + KGlobal::locale()->insertCatalogue("libdmctl"); + + // we need to read from the right rc file - possibly taking screen number in account + KDesktopSettings::instance("kdesktoprc"); + + trinity_desktop_lock_use_system_modal_dialogs = !KDesktopSettings::useUnmanagedLockWindows(); + trinity_desktop_lock_delay_screensaver_start = KDesktopSettings::delaySaverStart(); + trinity_desktop_lock_use_sak = KDesktopSettings::useTDESAK(); + + if (args->isSet( "internal" )) { + while (signalled_run == FALSE) { + sigset_t new_mask; + struct sigaction act; + + in_internal_mode = TRUE; + + // handle SIGUSR1 + act.sa_handler= sigusr1_handler; + sigemptyset(&(act.sa_mask)); + sigaddset(&(act.sa_mask), SIGUSR1); + act.sa_flags = 0; + sigaction(SIGUSR1, &act, 0L); + // handle SIGUSR2 + act.sa_handler= sigusr2_handler; + sigemptyset(&(act.sa_mask)); + sigaddset(&(act.sa_mask), SIGUSR2); + act.sa_flags = 0; + sigaction(SIGUSR2, &act, 0L); + // handle SIGWINCH (an ersatz SIGUSR3) + act.sa_handler= sigusr3_handler; + sigemptyset(&(act.sa_mask)); + sigaddset(&(act.sa_mask), SIGWINCH); + act.sa_flags = 0; + sigaction(SIGWINCH, &act, 0L); + // handle SIGTTIN (an ersatz SIGUSR4) + act.sa_handler= sigusr4_handler; + sigemptyset(&(act.sa_mask)); + sigaddset(&(act.sa_mask), SIGTTIN); + act.sa_flags = 0; + sigaction(SIGTTIN, &act, 0L); + // handle SIGTTOU (an ersatz SIGUSR5) + act.sa_handler= sigusr5_handler; + sigemptyset(&(act.sa_mask)); + sigaddset(&(act.sa_mask), SIGTTOU); + act.sa_flags = 0; + sigaction(SIGTTOU, &act, 0L); + + // initialize the signal masks + sigfillset(&new_mask); + sigdelset(&new_mask,SIGUSR1); + sigdelset(&new_mask,SIGUSR2); + sigdelset(&new_mask,SIGWINCH); + sigdelset(&new_mask,SIGTTIN); + sigdelset(&new_mask,SIGTTOU); + + // wait for SIGUSR1, SIGUSR2, SIGWINCH, SIGTTIN, or SIGTTOU + sigsuspend(&new_mask); + } + } + + if (args->isSet( "forcelock" ) || (signalled_forcelock == TRUE)) + trinity_desktop_lock_forced = TRUE; + + LockProcess process(child, (args->isSet( "blank" ) || (signalled_blank == TRUE))); + if (!child) + process.setChildren(child_sockets); + else + process.setParent(parent_connection); + + bool rt; + bool sig = false; + if( !child && (args->isSet( "forcelock" ) || (signalled_forcelock == TRUE))) + { + rt = process.lock(); + sig = true; + } + else if( child || (args->isSet( "dontlock" ) || (signalled_dontlock == TRUE))) { + rt = process.dontLock(); + } + else if( child || (args->isSet( "securedialog" ) || (signalled_securedialog == TRUE))) { + int retcode = tde_sak_verify_calling_process(); + if (retcode == 0) { + rt = process.runSecureDialog(); + } + else { + return 1; + } } else { + rt = process.defaultSave(); + } + if (!rt) { return 0; } - } - else { - rt = process.defaultSave(); - } - if (!rt) { - return 0; - } - if( sig ) - { - DCOPRef ref( "kdesktop", "KScreensaverIface"); - ref.send( "saverLockReady" ); - } + if( sig ) + { + DCOPRef ref( "kdesktop", "KScreensaverIface"); + ref.send( "saverLockReady" ); + } + + if (in_internal_mode == FALSE) { + return app.exec(); + } + else { + pid_t kdesktop_pid = atoi(args->getOption( "internal" )); + app.exec(); + if (kill(kdesktop_pid, SIGUSR1) < 0) { + // The controlling kdesktop process probably died. Commit suicide... + return 12; + } - return app.exec(); + // FIXME + // We should not have to return (restart) at all, + // but it seems that some X11 connections are left active, + // preventing the lock process from restarting properly in the while() loop above. + return 0; + } + } } #include "main.moc" |