1/* This file is part of the KDE project
2
3 Copyright 2008 David Faure <faure@kde.org>
4
5 This library is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Library General Public License as published
7 by the Free Software Foundation; either version 2 of the License or
8 ( at your option ) version 3 or, at the discretion of KDE e.V.
9 ( which shall act as a proxy as in section 14 of the GPLv3 ), any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/
21
22#include "pimuniqueapplication.h"
23
24#include <kaboutdata.h>
25#include <kcmdlineargs.h>
26#include <kdebug.h>
27#include <kstartupinfo.h>
28#include <kwindowsystem.h>
29
30#include <qdbusconnectioninterface.h>
31#include <qdbusinterface.h>
32
33using namespace KontactInterface;
34
35//@cond PRIVATE
36class KontactInterface::PimUniqueApplication::Private
37{
38};
39//@endcond
40
41PimUniqueApplication::PimUniqueApplication()
42 : KUniqueApplication(), d( new Private() )
43{
44 // This object name is used in start(), and also in kontact's UniqueAppHandler.
45 const QString objectName = QLatin1Char( '/' ) + applicationName() + QLatin1String("_PimApplication");
46 QDBusConnection::sessionBus().registerObject(
47 objectName, this,
48 QDBusConnection::ExportScriptableSlots |
49 QDBusConnection::ExportScriptableProperties |
50 QDBusConnection::ExportAdaptors );
51}
52
53static const char _k_sessionBusName[] = "kdepimapplication_session_bus";
54
55PimUniqueApplication::~PimUniqueApplication()
56{
57 delete d;
58}
59
60static QDBusConnection tryToInitDBusConnection()
61{
62 // Check the D-Bus connection health, and connect - but not using QDBusConnection::sessionBus()
63 // since we can't close that one before forking.
64 QDBusConnection connection = QDBusConnection::connectToBus(
65 QDBusConnection::SessionBus, QLatin1String(_k_sessionBusName) );
66 if ( !connection.isConnected() ) {
67 kError() << "Cannot find the D-Bus session server" << endl; //krazy:exclude=kdebug
68 ::exit( 255 );
69 }
70 return connection;
71}
72
73bool PimUniqueApplication::start()
74{
75 return start( KUniqueApplication::StartFlags() );
76}
77
78bool PimUniqueApplication::start( KUniqueApplication::StartFlags flags )
79{
80 const QString appName = KCmdLineArgs::aboutData()->appName();
81 // Try talking to /appName_PimApplication in org.kde.appName,
82 // (which could be kontact or the standalone application),
83 // otherwise fall back to standard KUniqueApplication behavior (start appName).
84
85 const QString serviceName = QLatin1String("org.kde.") + appName;
86 if ( tryToInitDBusConnection().interface()->isServiceRegistered( serviceName ) ) {
87 QByteArray saved_args;
88 QDataStream ds( &saved_args, QIODevice::WriteOnly );
89 KCmdLineArgs::saveAppArgs( ds );
90
91 QByteArray new_asn_id;
92#if defined Q_WS_X11
93 KStartupInfoId id;
94 if ( kapp ) { // KApplication constructor unsets the env. variable
95 id.initId( kapp->startupId() );
96 } else {
97 id = KStartupInfo::currentStartupIdEnv();
98 }
99 if ( !id.none() ) {
100 new_asn_id = id.id();
101 }
102#endif
103
104 KWindowSystem::allowExternalProcessWindowActivation();
105
106 const QString objectName = QLatin1Char( '/' ) + appName + QLatin1String("_PimApplication");
107 //kDebug() << objectName;
108 QDBusInterface iface(
109 serviceName, objectName, QLatin1String("org.kde.KUniqueApplication"), QDBusConnection::sessionBus() );
110 QDBusReply<int> reply;
111 if ( iface.isValid() &&
112 ( reply = iface.call( QLatin1String("newInstance"), new_asn_id, saved_args ) ).isValid() ) {
113 return false; // success means that main() can exit now.
114 }
115 }
116
117 QDBusConnection::disconnectFromBus( QLatin1String(_k_sessionBusName) );
118
119 //kDebug() << "kontact not running -- start standalone application";
120 // kontact not running -- start standalone application.
121 return KUniqueApplication::start( flags );
122}
123