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
}