Logo Search packages:      
Sourcecode: rosegarden version File versions  Download package

bool RosegardenGUIApp::launchSequencer ( bool  useExistingSequencer  ) 

Start the sequencer auxiliary process (built in the 'sequencer' directory)

See also:
slotSequencerExited()

Definition at line 4336 of file rosegardengui.cpp.

References RosegardenGUIDoc::getStudio(), isSequencerRunning(), isUsingSequencer(), m_doc, slotEnableTransport(), slotSequencerExited(), and RosegardenGUIDoc::syncDevices().

Referenced by RosegardenGUIApp(), and slotPlay().

{
    if (!isUsingSequencer()) {
        RG_DEBUG << "RosegardenGUIApp::launchSequencer() - not using seq. - returning\n";
        return false; // no need to launch anything
    }
    
    if (isSequencerRunning())
    {
        RG_DEBUG << "RosegardenGUIApp::launchSequencer() - sequencer already running - returning\n";
      try {
          if (m_seqManager) m_seqManager->checkSoundDriverStatus();
      } catch (...) {
          // checkSoundDriverStatus can throw an exception, but the sequence
          // manager should have reported that to the user on startup, or
          // else we'll have had a failure report in the mean time.  No
          // benefit in duplicating that report here
      }
        return true;
    }

    // Check to see if we're clearing down sequencer processes - 
    // if we're not we check DCOP for an existing sequencer and
    // try to talk to use that (that's the "developer" mode).
    //
    // User mode should clear down sequencer processes.
    //
    if (kapp->dcopClient()->isApplicationRegistered(
                QCString(ROSEGARDEN_SEQUENCER_APP_NAME)))
    {
        RG_DEBUG << "RosegardenGUIApp::launchSequencer() - "
                 << "existing DCOP registered sequencer found\n";

      if (useExisting) {
          try {
            if (m_seqManager) m_seqManager->checkSoundDriverStatus();
          } catch (...) {
            // as above
          }
          m_sequencerProcess = (KProcess*)SequencerExternal;
          return true;
      }

        KProcess *proc = new KProcess;
        *proc << "/usr/bin/killall";
        *proc << "rosegardensequencer";
        *proc << "lt-rosegardensequencer";

        proc->start(KProcess::Block, KProcess::All);

        if (!proc->normalExit() || proc->exitStatus()) {
            RG_DEBUG << "couldn't kill any sequencer processes" << endl;
      }
      delete proc;

      sleep(1);
      
      if (kapp->dcopClient()->isApplicationRegistered(
                QCString(ROSEGARDEN_SEQUENCER_APP_NAME)))
      {
          RG_DEBUG << "RosegardenGUIApp::launchSequencer() - "
                 << "failed to kill existing sequencer\n";

          KProcess *proc = new KProcess;
          *proc << "/usr/bin/killall";
          *proc << "-9";
          *proc << "rosegardensequencer";
          *proc << "lt-rosegardensequencer";

          proc->start(KProcess::Block, KProcess::All);

          if (proc->exitStatus()) {
            RG_DEBUG << "couldn't kill any sequencer processes" << endl;
          }
          delete proc;

          sleep(1);
      }
    }

    //
    // No sequencer is running, so start one
    //
    KTmpStatusMsg msg(i18n("Starting the sequencer..."), this);

    if (!m_sequencerProcess) {
        m_sequencerProcess = new KProcess;

        (*m_sequencerProcess) << "rosegardensequencer";

        // Command line arguments
        //
        KConfig *config = kapp->config();
        config->setGroup(Rosegarden::SequencerOptionsConfigGroup);
        QString options = config->readEntry("commandlineoptions");
        if (!options.isEmpty()) {
            (*m_sequencerProcess) << options;
            RG_DEBUG << "sequencer options \"" << options << "\"" << endl;
        }

    } else {
        RG_DEBUG << "RosegardenGUIApp::launchSequencer() - sequencer KProcess already created\n";
        m_sequencerProcess->disconnect(); // disconnect processExit signal
        // it will be reconnected later on
    }
    
    bool res = m_sequencerProcess->start();
    
    if (!res) {
        KMessageBox::error(0, i18n("Couldn't start the sequencer"));
        RG_DEBUG << "Couldn't start the sequencer\n";
        m_sequencerProcess = 0;
        // If starting it didn't even work, fall back to no sequencer mode
        m_useSequencer = false;
    }
    else {
        // connect processExited only after start, otherwise
        // a failed startup will call slotSequencerExited()
        // right away and we don't get to check the result
        // of m_sequencerProcess->start() and thus make the distinction
        // between the case where the sequencer was successfully launched
        // but crashed right away, or the case where the process couldn't
        // be launched at all (missing executable, etc...)
        //
        // We also re-check that the process is still running at this
        // point in case it crashed between the moment we check res above
        // and now.
        //
        //usleep(1000 * 1000); // even wait half a sec. to make sure it's actually running
        if (m_sequencerProcess->isRunning()) {

            try {
//                 if (m_seqManager) {
//                     RG_DEBUG << "RosegardenGUIApp::launchSequencer : checking sound driver status\n";
//                     m_seqManager->checkSoundDriverStatus();
//                 }
                
                stateChanged("sequencer_running");
                slotEnableTransport(true);

                connect(m_sequencerProcess, SIGNAL(processExited(KProcess*)),
                        this, SLOT(slotSequencerExited(KProcess*)));

            } catch (Rosegarden::Exception e) {
                m_sequencerProcess = 0;
                m_useSequencer = false;
                stateChanged("sequencer_running", KXMLGUIClient::StateReverse);
                slotEnableTransport(false);
            }

        } else { // if it crashed so fast, it's probably pointless
            // to try restarting it later, so also fall back to no
            // sequencer mode
            m_sequencerProcess = 0;
            m_useSequencer = false;
            stateChanged("sequencer_running", KXMLGUIClient::StateReverse);
            slotEnableTransport(false);
        }
            
    }

    // Sync current devices with the sequencer
    //
    if (m_doc) m_doc->syncDevices();

    if (m_doc && m_doc->getStudio().haveMidiDevices()) {
      stateChanged("got_midi_devices");
    } else {
      stateChanged("got_midi_devices", KXMLGUIClient::StateReverse);
    }
    
    return res;
}


Generated by  Doxygen 1.6.0   Back to index