diff options
Diffstat (limited to 'kdesktop/main.cpp')
-rw-r--r-- | kdesktop/main.cpp | 294 |
1 files changed, 294 insertions, 0 deletions
diff --git a/kdesktop/main.cpp b/kdesktop/main.cpp new file mode 100644 index 000000000..b54c03cb7 --- /dev/null +++ b/kdesktop/main.cpp @@ -0,0 +1,294 @@ +/* This file is part of the KDE project + Copyright (C) 1999 David Faure (maintainer) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <config.h> +#include <kuniqueapplication.h> +#include <tdelocale.h> +#include <dcopclient.h> +#include <tdeaboutdata.h> +#include <tdecmdlineargs.h> +#include <kopenwith.h> +#include <kcrash.h> +#include <kdebug.h> +#include <tdeglobalsettings.h> +#include <tdeglobal.h> +#include <tdeconfig.h> +#include <kmanagerselection.h> + +#include "desktop.h" +#include "lockeng.h" +#include "init.h" +#include "krootwm.h" +#include "kdesktopsettings.h" +#include "kdesktopapp.h" + +#include <signal.h> +#include <unistd.h> +#include <fcntl.h> +#include <stdlib.h> + +#if defined(Q_WS_X11) && defined(HAVE_XRENDER) && TQT_VERSION >= 0x030300 +#define COMPOSITE +#endif + +#ifdef COMPOSITE +# include <X11/Xlib.h> +# include <X11/extensions/Xrender.h> +# include <fixx11h.h> +# include <dlfcn.h> +#endif + +static const char description[] = + I18N_NOOP("The TDE desktop"); + +static const char version[] = VERSION; + +static TDECmdLineOptions options[] = +{ + { "x-root", I18N_NOOP("Use this if the desktop window appears as a real window"), 0 }, + { "noautostart", I18N_NOOP("Obsolete"), 0 }, + { "waitforkded", I18N_NOOP("Wait for kded to finish building database"), 0 }, +#ifdef COMPOSITE + { "bg-transparency", I18N_NOOP("Enable background transparency"), 0 }, +#endif + TDECmdLineLastOption +}; + +bool argb_visual = false; +KDesktopApp *myApp = NULL; + +// ----------------------------------------------------------------------------- + +int kdesktop_screen_number = 0; +TQCString kdesktop_name, kicker_name, twin_name; + +static void crashHandler(int sigId) +{ + DCOPClient::emergencyClose(); // unregister DCOP + sleep( 1 ); + system("kdesktop &"); // try to restart + fprintf(stderr, "*** kdesktop (%ld) got signal %d\n", (long) getpid(), sigId); + ::exit(1); +} + +static void signalHandler(int sigId) +{ + fprintf(stderr, "*** kdesktop got signal %d (Exiting)\n", sigId); + TDECrash::setEmergencySaveFunction(0); // No restarts any more + // try to cleanup all windows + signal(SIGTERM, SIG_DFL); // next one kills + signal(SIGHUP, SIG_DFL); // next one kills + if (kapp) + kapp->quit(); // turn catchable signals into clean shutdown +} + +void KDesktop::slotUpAndRunning() +{ + // Activate crash recovery + if (getenv("TDE_DEBUG") == NULL) + TDECrash::setEmergencySaveFunction(crashHandler); // Try to restart on crash +} + +extern "C" KDE_EXPORT int kdemain( int argc, char **argv ) +{ + //setup signal handling + signal(SIGTERM, signalHandler); + signal(SIGHUP, signalHandler); + + { + if (TDEGlobalSettings::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); + kdesktop_screen_number = DefaultScreen(dpy); + int pos; + TQCString display_name = XDisplayString(dpy); + XCloseDisplay(dpy); + 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 != kdesktop_screen_number && fork() == 0) { + kdesktop_screen_number = i; + // break here because we are the child process, we don't + // want to fork() anymore + break; + } + } + + env.sprintf("DISPLAY=%s.%d", display_name.data(), + kdesktop_screen_number); + + if (putenv(strdup(env.data()))) { + fprintf(stderr, + "%s: WARNING: unable to set DISPLAY environment variable\n", + argv[0]); + perror("putenv()"); + } + } + } + } + + TDEGlobal::locale()->setMainCatalogue("kdesktop"); + + if (kdesktop_screen_number == 0) { + kdesktop_name = "kdesktop"; + kicker_name = "kicker"; + twin_name = "twin"; + } else { + kdesktop_name.sprintf("kdesktop-screen-%d", kdesktop_screen_number); + kicker_name.sprintf("kicker-screen-%d", kdesktop_screen_number); + twin_name.sprintf("twin-screen-%d", kdesktop_screen_number); + } + + TDEAboutData aboutData( kdesktop_name, I18N_NOOP("KDesktop"), + version, description, TDEAboutData::License_GPL, + "(c) 1998-2000, The KDesktop Authors"); + aboutData.addAuthor("David Faure", 0, "faure@kde.org"); + aboutData.addAuthor("Martin Koller", 0, "m.koller@surfeu.at"); + aboutData.addAuthor("Waldo Bastian", 0, "bastian@kde.org"); + aboutData.addAuthor("Luboš Luňák", 0, "l.lunak@kde.org"); + aboutData.addAuthor("Joseph Wenninger", 0, "kde@jowenn.at"); + aboutData.addAuthor("Tim Jansen", 0, "tim@tjansen.de"); + aboutData.addAuthor("Benoit Walter", 0, "b.walter@free.fr"); + aboutData.addAuthor("Torben Weis", 0, "weis@kde.org"); + aboutData.addAuthor("Matthias Ettrich", 0, "ettrich@kde.org"); + + TDECmdLineArgs::init( argc, argv, &aboutData ); + TDECmdLineArgs::addCmdLineOptions( options ); + + if (!KUniqueApplication::start()) { + fprintf(stderr, "kdesktop is already running!\n"); + exit(0); + } + DCOPClient* cl = new DCOPClient; + cl->attach(); + DCOPRef r( "ksmserver", "ksmserver" ); + r.setDCOPClient( cl ); + r.send( "suspendStartup", TQCString( "kdesktop" )); + delete cl; + + TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); + +#ifdef COMPOSITE + + TDECmdLineArgs *qtargs = TDECmdLineArgs::parsedArgs("qt"); + + if ( args->isSet("bg-transparency")) { + char *display = 0; + if ( qtargs->isSet("display")) + display = qtargs->getOption( "display" ).data(); + + Display *dpy = XOpenDisplay( display ); + if ( !dpy ) { + kdError() << "cannot connect to X server " << display << endl; + exit( 1 ); + } + + int screen = DefaultScreen( dpy ); + + Visual *visual = 0; + int event_base, error_base; + + if ( XRenderQueryExtension( dpy, &event_base, &error_base ) ) { + int nvi; + XVisualInfo templ; + templ.screen = screen; + templ.depth = 32; + templ.c_class = TrueColor; + XVisualInfo *xvi = XGetVisualInfo( dpy, VisualScreenMask + | VisualDepthMask | VisualClassMask, &templ, &nvi ); + + for ( int i = 0; i < nvi; i++ ) { + XRenderPictFormat *format = + XRenderFindVisualFormat( dpy, xvi[i].visual ); + if ( format->type == PictTypeDirect && format->direct.alphaMask ) { + visual = xvi[i].visual; + kdDebug() << "[kdesktop] Found visual with alpha support" << endl; + argb_visual = true; + break; + } + } + } + // The TQApplication ctor used is normally intended for applications not using Qt + // as the primary toolkit (e.g. Motif apps also using Qt), with some slightly + // unpleasant side effects (e.g. #83974). This code checks if qt-copy patch #0078 + // is applied, which allows turning this off. + bool* qt_no_foreign_hack = + static_cast< bool* >( dlsym( RTLD_DEFAULT, "qt_no_foreign_hack" )); + if( qt_no_foreign_hack ) + *qt_no_foreign_hack = true; + // else argb_visual = false ... ? *shrug* + if( argb_visual ) + myApp = new KDesktopApp( dpy, Qt::HANDLE( visual ), 0 ); + else + XCloseDisplay( dpy ); + } + if( myApp == NULL ) + myApp = new KDesktopApp; +#else + myApp = new KDesktopApp; +#endif + myApp->disableSessionManagement(); // Do SM, but don't restart. + + KDesktopSettings::instance(kdesktop_name + "rc"); + + bool x_root_hack = args->isSet("x-root"); + bool wait_for_kded = args->isSet("waitforkded"); + + // This MUST be created before any widgets are created + SaverEngine saver; + + // Do this before forking so that if a dialog box appears it won't + // be covered by other apps. + // And before creating KDesktop too, of course. + testLocalInstallation(); + + // Mark kdeskop as immutable if all of its config modules have been disabled + if (!myApp->config()->isImmutable() && + kapp->authorizeControlModules(KRootWm::configModules()).isEmpty()) + { + myApp->config()->setReadOnly(true); + myApp->config()->reparseConfiguration(); + } + + // for the KDE-already-running check in starttde + TDESelectionOwner kde_running( "_KDE_RUNNING", 0 ); + kde_running.claim( false ); + + KDesktop desktop( &saver, x_root_hack, wait_for_kded ); + + args->clear(); + + myApp->dcopClient()->setDefaultObject( "KDesktopIface" ); + + + return myApp->exec(); +} |