Source Code (Use browser search to find items of interest.)
Class Index
kdelibs'KUniqueApplication (./kdelibs/kdecore/kuniqueapp.h:40)
class KUniqueApplication : public KApplication, DCOPObject
{
Q_OBJECT
public:
/**
* @depreciated
* Constructor. Parses command-line arguments.
* Parameters : See @ref KApplication constructor.
*/
KUniqueApplication( int& argc, char** argv,
const QCString& rAppName = 0,
bool allowStyles=true,
bool GUIenabled=true);
/**
* Constructor. Takes command line arguments from KCmdLineArgs
* Parameters : See @ref KApplication constructor.
*/
KUniqueApplication( bool allowStyles=true,
bool GUIenabled=true);
/**
* Add command line options specific for KUniqueApplication
*
* Should be called before calling KUniqueApplication constructor
* and / or start().
*/
static void addCmdLineOptions();
/**
* Fork and register with dcop.
*
* The command line arguments are being sent via DCOP to @ref newInstance()
* and will be received once the application enters the event loop.
* @return @p true if registration is succesful.
* @p false if another process was already running.
*
* Typically this is used like:
* <pre>
* int main(int argc, char **argv) {
* KAboutData about("myappname", "myAppName", .....);
* KCmdLineArgs::init(argc, argv, &about);
* KCmdLineArgs::addCmdLineOptions( myCmdOptions );
* KUniqueApplication::addCmdLineOptions();
*
* if (!KUniqueApplication::start()) {
* fprintf(stderr, "myAppName is already running!\n");
* exit(0);
* }
* KUniqueApplication a;
* a.exec();
* }
* </pre>
* or
* <pre>
* int main(int argc, char **argv) {
* KAboutData about("myappname", "myAppName", .....);
* KCmdLineArgs::init(argc, argv, &about);
* KCmdLineArgs::addCmdLineOptions( myCmdOptions );
* KUniqueApplication::addCmdLineOptions();
*
* if (!KUniqueApplication::start())
* exit(0);
* KUniqueApplication a;
* a.exec();
* }
* </pre>
* Although it is not necassery to call @ref start() before creating a
* @ref KUniqueApplication it is adviced to so because it is about
* 40% faster if the application was already running:
* If you use @ref start() the @ref KApplication constructor will not be
* called if this isn't necessary.
*/
static bool start();
static bool start(int& argc, char** argv, const QCString &rAppName);
/** Destructor */
virtual ~KUniqueApplication();
/**
* Retrieve the DCOP client object.
**/
virtual DCOPClient *dcopClient();
/**
* Dispatch any incoming DCOP message for a new instance.
*
* If
* it is not a request for a new instance, return @p false.
*/
bool process(const QCString &fun, const QByteArray &data,
QCString &replyType, QByteArray &replyData);
/**
* Create a new "instance" of the application.
*
* Usually this
* will involve making some calls into the GUI portion of your
* application asking for a new window to be created, possibly with
* some data already loaded based on the arguments received.
*
* Command line arguments have been passed to KCmdLineArgs before this
* function is called and can be checked in the usual way.
*
* @return An exit value. The calling process will exit with this value.
*/
virtual int newInstance();
/**
* @depreciated
*/
virtual int newInstance(QValueList<QCString> params);
private:
static DCOPClient *s_DCOPClient;
KUniqueApplicationPrivate *d;
};
kdelibs'KUniqueApplication::dcopClient() (./kdelibs/kdecore/kuniqueapp.cpp:45)
KUniqueApplication::dcopClient()
{
assert( s_DCOPClient);
return s_DCOPClient;
}
void
kdelibs'KUniqueApplication::addCmdLineOptions() (./kdelibs/kdecore/kuniqueapp.cpp:52)
KUniqueApplication::addCmdLineOptions()
{
KCmdLineArgs::addCmdLineOptions(kunique_options, 0, "kuniqueapp", "kde" );
}
bool
kdelibs'KUniqueApplication::start() (./kdelibs/kdecore/kuniqueapp.cpp:58)
KUniqueApplication::start(int& argc, char** argv,
const QCString& rAppName)
{
bool nofork = false;
for(int i = 1; i < argc; i++)
{
if (strcmp(argv[i], "--nofork") == 0)
nofork = true;
}
if (nofork)
{
s_DCOPClient = new DCOPClient();
s_DCOPClient->registerAs(rAppName, false);
return true;
}
DCOPClient *dc;
int fd[2];
char result;
if (0 > pipe(fd))
{
qDebug("KUniqueApplication: pipe() failed!\n");
::exit(255);
}
switch(fork()) {
case -1:
qDebug("KUniqueApplication: fork() failed!\n");
::exit(255);
break;
case 0:
// Child
::close(fd[0]);
dc = new DCOPClient();
{
QCString regName = dc->registerAs(rAppName, false);
if (regName.isEmpty())
{
qDebug("KUniqueApplication: Child can't attach to DCOP.\n");
result = -1;
delete dc; // Clean up DCOP commmunication
::write(fd[1], &result, 1);
::exit(255);
}
if (regName != rAppName)
{
// Already running. Ok.
result = 0;
delete dc; // Clean up DCOP commmunication
::write(fd[1], &result, 1);
::close(fd[1]);
return false;
}
}
s_DCOPClient = dc;
result = 0;
::write(fd[1], &result, 1);
::close(fd[1]);
return true; // Finished.
break;
default:
// Parent
::close(fd[1]);
for(;;)
{
int n = ::read(fd[0], &result, 1);
if (n == 1) break;
if (n == 0)
{
qDebug("KUniqueApplication: Pipe closed unexpected.\n");
::exit(255);
}
if (errno != EINTR)
{
qDebug("KUniqueApplication: Error reading from pipe.\n");
::exit(255);
}
}
::close(fd[0]);
if (result != 0)
::exit(result); // Error occured in child.
dc = new DCOPClient();
if (!dc->attach())
{
qDebug("KUniqueApplication: Parent can't attach to DCOP.\n");
delete dc; // Clean up DCOP commmunication
::exit(255);
}
if (!dc->isApplicationRegistered(rAppName)) {
qDebug("KUniqueApplication: Registering failed!\n");
}
QByteArray data, reply;
QDataStream ds(data, IO_WriteOnly);
QValueList<QCString> params;
for (int i = 0; i < argc; i++)
params.append(argv[i]);
ds << params;
QCString replyType;
if (!dc->call(rAppName, rAppName, "newInstance(QValueList<QCString>)", data, replyType, reply))
{
qDebug("KUniqueApplication: DCOP communication error!");
delete dc; // Clean up DCOP commmunication
::exit(255);
}
if (replyType != "int")
{
qDebug("KUniqueApplication: DCOP communication error!");
delete dc; // Clean up DCOP commmunication
::exit(255);
}
QDataStream rs(reply, IO_ReadOnly);
int exitCode;
rs >> exitCode;
delete dc; // Clean up DCOP commmunication
::exit(exitCode);
break;
}
}
bool
kdelibs'KUniqueApplication::start() (./kdelibs/kdecore/kuniqueapp.cpp:180)
KUniqueApplication::start()
{
addCmdLineOptions(); // Make sure to add cmd line options
KCmdLineArgs *args = KCmdLineArgs::parsedArgs("kuniqueapp");
bool nofork = !args->isSet("fork");
delete args;
const char *appName = KCmdLineArgs::about->appName();
if (nofork)
{
s_DCOPClient = new DCOPClient();
s_DCOPClient->registerAs(appName, false);
return true;
}
DCOPClient *dc;
int fd[2];
char result;
if (0 > pipe(fd))
{
qDebug("KUniqueApplication: pipe() failed!\n");
::exit(255);
}
switch(fork()) {
case -1:
qDebug("KUniqueApplication: fork() failed!\n");
::exit(255);
break;
case 0:
// Child
::close(fd[0]);
dc = new DCOPClient();
{
QCString regName = dc->registerAs(appName, false);
if (regName.isEmpty())
{
qDebug("KUniqueApplication: Child can't attach to DCOP.\n");
result = -1;
delete dc; // Clean up DCOP commmunication
::write(fd[1], &result, 1);
::exit(255);
}
if (regName != appName)
{
// Already running. Ok.
result = 0;
delete dc; // Clean up DCOP commmunication
::write(fd[1], &result, 1);
::close(fd[1]);
return false;
}
}
s_DCOPClient = dc;
result = 0;
::write(fd[1], &result, 1);
::close(fd[1]);
return true; // Finished.
break;
default:
// Parent
::close(fd[1]);
for(;;)
{
int n = ::read(fd[0], &result, 1);
if (n == 1) break;
if (n == 0)
{
qDebug("KUniqueApplication: Pipe closed unexpected.\n");
::exit(255);
}
if (errno != EINTR)
{
qDebug("KUniqueApplication: Error reading from pipe.\n");
::exit(255);
}
}
::close(fd[0]);
if (result != 0)
::exit(result); // Error occured in child.
dc = new DCOPClient();
if (!dc->attach())
{
qDebug("KUniqueApplication: Parent can't attach to DCOP.\n");
delete dc; // Clean up DCOP commmunication
::exit(255);
}
if (!dc->isApplicationRegistered(appName)) {
qDebug("KUniqueApplication: Registering failed!\n");
}
QByteArray data, reply;
QDataStream ds(data, IO_WriteOnly);
KCmdLineArgs::saveAppArgs(ds);
QCString replyType;
if (!dc->call(appName, appName, "newInstance()", data, replyType, reply))
{
qDebug("KUniqueApplication: DCOP communication error!");
delete dc; // Clean up DCOP commmunication
::exit(255);
}
if (replyType != "int")
{
qDebug("KUniqueApplication: DCOP communication error!");
delete dc; // Clean up DCOP commmunication
::exit(255);
}
QDataStream rs(reply, IO_ReadOnly);
int exitCode;
rs >> exitCode;
delete dc; // Clean up DCOP commmunication
::exit(exitCode);
break;
}
}
kdelibs'KUniqueApplication::KUniqueApplication() (./kdelibs/kdecore/kuniqueapp.cpp:300)
KUniqueApplication::KUniqueApplication(bool allowStyles, bool GUIenabled)
: KApplication(allowStyles, GUIenabled),
DCOPObject(KCmdLineArgs::about->appName())
{
if (!s_DCOPClient)
{
if (!start())
{
// Already running
::exit(0);
}
}
s_DCOPClient->bindToApp(); // Make sure we get events from the DCOPClient.
}
kdelibs'KUniqueApplication::KUniqueApplication() (./kdelibs/kdecore/kuniqueapp.cpp:315)
KUniqueApplication::KUniqueApplication(int& argc, char** argv,
const QCString& rAppName,
bool allowStyles, bool GUIenabled)
: KApplication(argc, argv, rAppName, allowStyles, GUIenabled), DCOPObject(rAppName)
{
if (!s_DCOPClient)
{
if (!start(argc, argv, rAppName))
{
// Already running
::exit(0);
}
}
s_DCOPClient->bindToApp(); // Make sure we get events from the DCOPClient.
}
kdelibs'KUniqueApplication::~KUniqueApplication() (./kdelibs/kdecore/kuniqueapp.cpp:331)
KUniqueApplication::~KUniqueApplication()
{
}
kdelibs'KUniqueApplication::process() (./kdelibs/kdecore/kuniqueapp.cpp:335)
bool KUniqueApplication::process(const QCString &fun, const QByteArray &data,
QCString &replyType, QByteArray &replyData)
{
if (fun == "newInstance(QValueList<QCString>)") {
QDataStream ds(data, IO_ReadOnly);
QValueList<QCString> params;
ds >> params;
int exitCode = newInstance(params);
QDataStream rs(replyData, IO_WriteOnly);
rs << exitCode;
replyType = "int";
return true;
} else
if (fun == "newInstance()") {
QDataStream ds(data, IO_ReadOnly);
KCmdLineArgs::loadAppArgs(ds);
int exitCode = newInstance();
QDataStream rs(replyData, IO_WriteOnly);
rs << exitCode;
replyType = "int";
return true;
} else
return false;
}
kdelibs'KUniqueApplication::newInstance() (./kdelibs/kdecore/kuniqueapp.cpp:360)
int KUniqueApplication::newInstance(QValueList<QCString> /*params*/)
{
return 0; // do nothing in default implementation
}
kdelibs'KUniqueApplication::newInstance() (./kdelibs/kdecore/kuniqueapp.cpp:365)
int KUniqueApplication::newInstance()
{
return 0; // do nothing in default implementation
}