/[svn]/qsampler/trunk/src/qsamplerMainForm.cpp
ViewVC logotype

Diff of /qsampler/trunk/src/qsamplerMainForm.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1515 by capela, Fri Nov 23 18:15:33 2007 UTC revision 1698 by schoenebeck, Sat Feb 16 19:41:05 2008 UTC
# Line 2  Line 2 
2  //  //
3  /****************************************************************************  /****************************************************************************
4     Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved.
5     Copyright (C) 2007, Christian Schoenebeck     Copyright (C) 2007, 2008 Christian Schoenebeck
6    
7     This program is free software; you can redistribute it and/or     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License     modify it under the terms of the GNU General Public License
# Line 33  Line 33 
33  #include "qsamplerInstrumentListForm.h"  #include "qsamplerInstrumentListForm.h"
34  #include "qsamplerDeviceForm.h"  #include "qsamplerDeviceForm.h"
35  #include "qsamplerOptionsForm.h"  #include "qsamplerOptionsForm.h"
36    #include "qsamplerDeviceStatusForm.h"
37    
38  #include <QApplication>  #include <QApplication>
39  #include <QWorkspace>  #include <QWorkspace>
# Line 77  static inline long lroundf ( float x ) Line 78  static inline long lroundf ( float x )
78  }  }
79  #endif  #endif
80    
81    
82    // All winsock apps needs this.
83    #if defined(WIN32)
84    static WSADATA _wsaData;
85    #endif
86    
87    
88    namespace QSampler {
89    
90  // Timer constant stuff.  // Timer constant stuff.
91  #define QSAMPLER_TIMER_MSECS    200  #define QSAMPLER_TIMER_MSECS    200
92    
# Line 87  static inline long lroundf ( float x ) Line 97  static inline long lroundf ( float x )
97  #define QSAMPLER_STATUS_SESSION 3       // Current session modification state.  #define QSAMPLER_STATUS_SESSION 3       // Current session modification state.
98    
99    
 // All winsock apps needs this.  
 #if defined(WIN32)  
 static WSADATA _wsaData;  
 #endif  
   
   
100  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
101  // qsamplerCustomEvent -- specialty for callback comunication.  // CustomEvent -- specialty for callback comunication.
102    
103  #define QSAMPLER_CUSTOM_EVENT   QEvent::Type(QEvent::User + 0)  #define QSAMPLER_CUSTOM_EVENT   QEvent::Type(QEvent::User + 0)
104    
105  class qsamplerCustomEvent : public QEvent  class CustomEvent : public QEvent
106  {  {
107  public:  public:
108    
109          // Constructor.          // Constructor.
110          qsamplerCustomEvent(lscp_event_t event, const char *pchData, int cchData)          CustomEvent(lscp_event_t event, const char *pchData, int cchData)
111                  : QEvent(QSAMPLER_CUSTOM_EVENT)                  : QEvent(QSAMPLER_CUSTOM_EVENT)
112          {          {
113                  m_event = event;                  m_event = event;
# Line 126  private: Line 130  private:
130  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
131  // qsamplerMainForm -- Main window form implementation.  // qsamplerMainForm -- Main window form implementation.
132    
 namespace QSampler {  
   
133  // Kind of singleton reference.  // Kind of singleton reference.
134  MainForm* MainForm::g_pMainForm = NULL;  MainForm* MainForm::g_pMainForm = NULL;
135    
# Line 366  MainForm::~MainForm() Line 368  MainForm::~MainForm()
368    
369    
370  // Make and set a proper setup options step.  // Make and set a proper setup options step.
371  void MainForm::setup ( qsamplerOptions *pOptions )  void MainForm::setup ( Options *pOptions )
372  {  {
373          // We got options?          // We got options?
374          m_pOptions = pOptions;          m_pOptions = pOptions;
# Line 382  void MainForm::setup ( qsamplerOptions * Line 384  void MainForm::setup ( qsamplerOptions *
384          if (m_pOptions->bKeepOnTop)          if (m_pOptions->bKeepOnTop)
385                  wflags |= Qt::Tool;                  wflags |= Qt::Tool;
386          // Some child forms are to be created right now.          // Some child forms are to be created right now.
387          m_pMessages = new qsamplerMessages(this);          m_pMessages = new Messages(this);
388          m_pDeviceForm = new DeviceForm(this, wflags);          m_pDeviceForm = new DeviceForm(this, wflags);
389  #ifdef CONFIG_MIDI_INSTRUMENT  #ifdef CONFIG_MIDI_INSTRUMENT
390          m_pInstrumentListForm = new InstrumentListForm(this, wflags);          m_pInstrumentListForm = new InstrumentListForm(this, wflags);
# Line 470  bool MainForm::queryClose (void) Line 472  bool MainForm::queryClose (void)
472                          if (m_pDeviceForm)                          if (m_pDeviceForm)
473                                  m_pDeviceForm->close();                                  m_pDeviceForm->close();
474                          // Stop client and/or server, gracefully.                          // Stop client and/or server, gracefully.
475                          stopServer();                          stopServer(true /*interactive*/);
476                  }                  }
477          }          }
478    
# Line 511  void MainForm::dropEvent ( QDropEvent* p Line 513  void MainForm::dropEvent ( QDropEvent* p
513                  QListIterator<QUrl> iter(pMimeData->urls());                  QListIterator<QUrl> iter(pMimeData->urls());
514                  while (iter.hasNext()) {                  while (iter.hasNext()) {
515                          const QString& sPath = iter.next().toLocalFile();                          const QString& sPath = iter.next().toLocalFile();
516                          if (qsamplerChannel::isInstrumentFile(sPath)) {                          if (Channel::isInstrumentFile(sPath)) {
517                                  // Try to create a new channel from instrument file...                                  // Try to create a new channel from instrument file...
518                                  qsamplerChannel *pChannel = new qsamplerChannel();                                  Channel *pChannel = new Channel();
519                                  if (pChannel == NULL)                                  if (pChannel == NULL)
520                                          return;                                          return;
521                                  // Start setting the instrument filename...                                  // Start setting the instrument filename...
# Line 549  void MainForm::customEvent(QEvent* pCust Line 551  void MainForm::customEvent(QEvent* pCust
551  {  {
552          // For the time being, just pump it to messages.          // For the time being, just pump it to messages.
553          if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {          if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {
554                  qsamplerCustomEvent *pEvent = (qsamplerCustomEvent *) pCustomEvent;                  CustomEvent *pEvent = static_cast<CustomEvent *> (pCustomEvent);
555                  if (pEvent->event() == LSCP_EVENT_CHANNEL_INFO) {                  switch (pEvent->event()) {
556                          int iChannelID = pEvent->data().toInt();                          case LSCP_EVENT_CHANNEL_INFO: {
557                          ChannelStrip *pChannelStrip = channelStrip(iChannelID);                                  int iChannelID = pEvent->data().toInt();
558                          if (pChannelStrip)                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);
559                                  channelStripChanged(pChannelStrip);                                  if (pChannelStrip)
560                  } else {                                          channelStripChanged(pChannelStrip);
561                          appendMessagesColor(tr("Notify event: %1 data: %2")                                  break;
562                                  .arg(::lscp_event_to_text(pEvent->event()))                          }
563                                  .arg(pEvent->data()), "#996699");                          case LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT:
564                                    DeviceStatusForm::onDevicesChanged();
565                                    updateViewMidiDeviceStatusMenu();
566                                    break; //TODO: refresh device dialog as well
567    #if CONFIG_LSCP_CHANNEL_MIDI
568                            case LSCP_EVENT_CHANNEL_MIDI: {
569                                    const int iChannelID = pEvent->data().section(' ', 0, 0).toInt();
570                                    ChannelStrip *pChannelStrip = channelStrip(iChannelID);
571                                    if (pChannelStrip)
572                                            pChannelStrip->midiArrived();
573                                    break;
574                            }
575    #endif
576    #if CONFIG_LSCP_DEVICE_MIDI
577                            case LSCP_EVENT_DEVICE_MIDI: {
578                                    const int iDeviceID = pEvent->data().section(' ', 0, 0).toInt();
579                                    const int iPortID   = pEvent->data().section(' ', 1, 1).toInt();
580                                    DeviceStatusForm* pDeviceStatusForm =
581                                            DeviceStatusForm::getInstance(iDeviceID);
582                                    if (pDeviceStatusForm)
583                                            pDeviceStatusForm->midiArrived(iPortID);
584                                    break;
585                            }
586    #endif
587                            default:
588                                    appendMessagesColor(tr("Notify event: %1 data: %2")
589                                            .arg(::lscp_event_to_text(pEvent->event()))
590                                            .arg(pEvent->data()), "#996699");
591                  }                  }
592          }          }
593  }  }
594    
595    void MainForm::updateViewMidiDeviceStatusMenu() {
596            m_ui.viewMidiDeviceStatusMenu->clear();
597            const std::map<int, DeviceStatusForm*> statusForms =
598                    DeviceStatusForm::getInstances();
599            for (
600                    std::map<int, DeviceStatusForm*>::const_iterator iter = statusForms.begin();
601                    iter != statusForms.end(); ++iter
602            ) {
603                    DeviceStatusForm* pForm = iter->second;
604                    m_ui.viewMidiDeviceStatusMenu->addAction(
605                            pForm->visibleAction()
606                    );
607            }
608    }
609    
610  // Context menu event handler.  // Context menu event handler.
611  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )
612  {  {
# Line 576  void MainForm::contextMenuEvent( QContex Line 620  void MainForm::contextMenuEvent( QContex
620  // qsamplerMainForm -- Brainless public property accessors.  // qsamplerMainForm -- Brainless public property accessors.
621    
622  // The global options settings property.  // The global options settings property.
623  qsamplerOptions *MainForm::options (void) const  Options *MainForm::options (void) const
624  {  {
625          return m_pOptions;          return m_pOptions;
626  }  }
# Line 737  bool MainForm::closeSession ( bool bForc Line 781  bool MainForm::closeSession ( bool bForc
781                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {                  for (int iChannel = 0; iChannel < (int) wlist.count(); iChannel++) {
782                          ChannelStrip *pChannelStrip = (ChannelStrip*) wlist.at(iChannel);                          ChannelStrip *pChannelStrip = (ChannelStrip*) wlist.at(iChannel);
783                          if (pChannelStrip) {                          if (pChannelStrip) {
784                                  qsamplerChannel *pChannel = pChannelStrip->channel();                                  Channel *pChannel = pChannelStrip->channel();
785                                  if (bForce && pChannel)                                  if (bForce && pChannel)
786                                          pChannel->removeChannel();                                          pChannel->removeChannel();
787                                  delete pChannelStrip;                                  delete pChannelStrip;
# Line 877  bool MainForm::saveSessionFile ( const Q Line 921  bool MainForm::saveSessionFile ( const Q
921    
922          // Audio device mapping.          // Audio device mapping.
923          QMap<int, int> audioDeviceMap;          QMap<int, int> audioDeviceMap;
924          piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Audio);          piDeviceIDs = Device::getDevices(m_pClient, Device::Audio);
925          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
926                  ts << endl;                  ts << endl;
927                  qsamplerDevice device(qsamplerDevice::Audio, piDeviceIDs[iDevice]);                  Device device(Device::Audio, piDeviceIDs[iDevice]);
928                  // Audio device specification...                  // Audio device specification...
929                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
930                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
931                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();                  ts << "CREATE AUDIO_OUTPUT_DEVICE " << device.driverName();
932                  qsamplerDeviceParamMap::ConstIterator deviceParam;                  DeviceParamMap::ConstIterator deviceParam;
933                  for (deviceParam = device.params().begin();                  for (deviceParam = device.params().begin();
934                                  deviceParam != device.params().end();                                  deviceParam != device.params().end();
935                                          ++deviceParam) {                                          ++deviceParam) {
936                          const qsamplerDeviceParam& param = deviceParam.value();                          const DeviceParam& param = deviceParam.value();
937                          if (param.value.isEmpty()) ts << "# ";                          if (param.value.isEmpty()) ts << "# ";
938                          ts << " " << deviceParam.key() << "='" << param.value << "'";                          ts << " " << deviceParam.key() << "='" << param.value << "'";
939                  }                  }
940                  ts << endl;                  ts << endl;
941                  // Audio channel parameters...                  // Audio channel parameters...
942                  int iPort = 0;                  int iPort = 0;
943                  QListIterator<qsamplerDevicePort *> iter(device.ports());                  QListIterator<DevicePort *> iter(device.ports());
944                  while (iter.hasNext()) {                  while (iter.hasNext()) {
945                          qsamplerDevicePort *pPort = iter.next();                          DevicePort *pPort = iter.next();
946                          qsamplerDeviceParamMap::ConstIterator portParam;                          DeviceParamMap::ConstIterator portParam;
947                          for (portParam = pPort->params().begin();                          for (portParam = pPort->params().begin();
948                                          portParam != pPort->params().end();                                          portParam != pPort->params().end();
949                                                  ++portParam) {                                                  ++portParam) {
950                                  const qsamplerDeviceParam& param = portParam.value();                                  const DeviceParam& param = portParam.value();
951                                  if (param.fix || param.value.isEmpty()) ts << "# ";                                  if (param.fix || param.value.isEmpty()) ts << "# ";
952                                  ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice                                  ts << "SET AUDIO_OUTPUT_CHANNEL_PARAMETER " << iDevice
953                                          << " " << iPort << " " << portParam.key()                                          << " " << iPort << " " << portParam.key()
# Line 919  bool MainForm::saveSessionFile ( const Q Line 963  bool MainForm::saveSessionFile ( const Q
963    
964          // MIDI device mapping.          // MIDI device mapping.
965          QMap<int, int> midiDeviceMap;          QMap<int, int> midiDeviceMap;
966          piDeviceIDs = qsamplerDevice::getDevices(m_pClient, qsamplerDevice::Midi);          piDeviceIDs = Device::getDevices(m_pClient, Device::Midi);
967          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {          for (iDevice = 0; piDeviceIDs && piDeviceIDs[iDevice] >= 0; iDevice++) {
968                  ts << endl;                  ts << endl;
969                  qsamplerDevice device(qsamplerDevice::Midi, piDeviceIDs[iDevice]);                  Device device(Device::Midi, piDeviceIDs[iDevice]);
970                  // MIDI device specification...                  // MIDI device specification...
971                  ts << "# " << device.deviceTypeName() << " " << device.driverName()                  ts << "# " << device.deviceTypeName() << " " << device.driverName()
972                          << " " << tr("Device") << " " << iDevice << endl;                          << " " << tr("Device") << " " << iDevice << endl;
973                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();                  ts << "CREATE MIDI_INPUT_DEVICE " << device.driverName();
974                  qsamplerDeviceParamMap::ConstIterator deviceParam;                  DeviceParamMap::ConstIterator deviceParam;
975                  for (deviceParam = device.params().begin();                  for (deviceParam = device.params().begin();
976                                  deviceParam != device.params().end();                                  deviceParam != device.params().end();
977                                          ++deviceParam) {                                          ++deviceParam) {
978                          const qsamplerDeviceParam& param = deviceParam.value();                          const DeviceParam& param = deviceParam.value();
979                          if (param.value.isEmpty()) ts << "# ";                          if (param.value.isEmpty()) ts << "# ";
980                          ts << " " << deviceParam.key() << "='" << param.value << "'";                          ts << " " << deviceParam.key() << "='" << param.value << "'";
981                  }                  }
982                  ts << endl;                  ts << endl;
983                  // MIDI port parameters...                  // MIDI port parameters...
984                  int iPort = 0;                  int iPort = 0;
985                  QListIterator<qsamplerDevicePort *> iter(device.ports());                  QListIterator<DevicePort *> iter(device.ports());
986                  while (iter.hasNext()) {                  while (iter.hasNext()) {
987                          qsamplerDevicePort *pPort = iter.next();                          DevicePort *pPort = iter.next();
988                          qsamplerDeviceParamMap::ConstIterator portParam;                          DeviceParamMap::ConstIterator portParam;
989                          for (portParam = pPort->params().begin();                          for (portParam = pPort->params().begin();
990                                          portParam != pPort->params().end();                                          portParam != pPort->params().end();
991                                                  ++portParam) {                                                  ++portParam) {
992                                  const qsamplerDeviceParam& param = portParam.value();                                  const DeviceParam& param = portParam.value();
993                                  if (param.fix || param.value.isEmpty()) ts << "# ";                                  if (param.fix || param.value.isEmpty()) ts << "# ";
994                                  ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice                                  ts << "SET MIDI_INPUT_PORT_PARAMETER " << iDevice
995                                  << " " << iPort << " " << portParam.key()                                  << " " << iPort << " " << portParam.key()
# Line 1037  bool MainForm::saveSessionFile ( const Q Line 1081  bool MainForm::saveSessionFile ( const Q
1081                  ChannelStrip* pChannelStrip                  ChannelStrip* pChannelStrip
1082                          = static_cast<ChannelStrip *> (wlist.at(iChannel));                          = static_cast<ChannelStrip *> (wlist.at(iChannel));
1083                  if (pChannelStrip) {                  if (pChannelStrip) {
1084                          qsamplerChannel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
1085                          if (pChannel) {                          if (pChannel) {
1086                                  ts << "# " << tr("Channel") << " " << iChannel << endl;                                  ts << "# " << tr("Channel") << " " << iChannel << endl;
1087                                  ts << "ADD CHANNEL" << endl;                                  ts << "ADD CHANNEL" << endl;
# Line 1069  bool MainForm::saveSessionFile ( const Q Line 1113  bool MainForm::saveSessionFile ( const Q
1113                                  ts << "LOAD INSTRUMENT NON_MODAL '"                                  ts << "LOAD INSTRUMENT NON_MODAL '"
1114                                          << pChannel->instrumentFile() << "' "                                          << pChannel->instrumentFile() << "' "
1115                                          << pChannel->instrumentNr() << " " << iChannel << endl;                                          << pChannel->instrumentNr() << " " << iChannel << endl;
1116                                  qsamplerChannelRoutingMap::ConstIterator audioRoute;                                  ChannelRoutingMap::ConstIterator audioRoute;
1117                                  for (audioRoute = pChannel->audioRouting().begin();                                  for (audioRoute = pChannel->audioRouting().begin();
1118                                                  audioRoute != pChannel->audioRouting().end();                                                  audioRoute != pChannel->audioRouting().end();
1119                                                          ++audioRoute) {                                                          ++audioRoute) {
# Line 1314  void MainForm::editAddChannel (void) Line 1358  void MainForm::editAddChannel (void)
1358                  return;                  return;
1359    
1360          // Just create the channel instance...          // Just create the channel instance...
1361          qsamplerChannel *pChannel = new qsamplerChannel();          Channel *pChannel = new Channel();
1362          if (pChannel == NULL)          if (pChannel == NULL)
1363                  return;                  return;
1364    
# Line 1352  void MainForm::editRemoveChannel (void) Line 1396  void MainForm::editRemoveChannel (void)
1396          if (pChannelStrip == NULL)          if (pChannelStrip == NULL)
1397                  return;                  return;
1398    
1399          qsamplerChannel *pChannel = pChannelStrip->channel();          Channel *pChannel = pChannelStrip->channel();
1400          if (pChannel == NULL)          if (pChannel == NULL)
1401                  return;                  return;
1402    
# Line 1924  void MainForm::updateSession (void) Line 1968  void MainForm::updateSession (void)
1968                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {                  for (int iChannel = 0; piChannelIDs[iChannel] >= 0; iChannel++) {
1969                          // Check if theres already a channel strip for this one...                          // Check if theres already a channel strip for this one...
1970                          if (!channelStrip(piChannelIDs[iChannel]))                          if (!channelStrip(piChannelIDs[iChannel]))
1971                                  createChannelStrip(new qsamplerChannel(piChannelIDs[iChannel]));                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));
1972                  }                  }
1973                  m_pWorkspace->setUpdatesEnabled(true);                  m_pWorkspace->setUpdatesEnabled(true);
1974          }          }
# Line 2176  void MainForm::updateMessagesCapture (vo Line 2220  void MainForm::updateMessagesCapture (vo
2220  // qsamplerMainForm -- MDI channel strip management.  // qsamplerMainForm -- MDI channel strip management.
2221    
2222  // The channel strip creation executive.  // The channel strip creation executive.
2223  ChannelStrip* MainForm::createChannelStrip ( qsamplerChannel *pChannel )  ChannelStrip* MainForm::createChannelStrip ( Channel *pChannel )
2224  {  {
2225          if (m_pClient == NULL || pChannel == NULL)          if (m_pClient == NULL || pChannel == NULL)
2226                  return NULL;                  return NULL;
# Line 2248  ChannelStrip* MainForm::channelStrip ( i Line 2292  ChannelStrip* MainForm::channelStrip ( i
2292                  ChannelStrip* pChannelStrip                  ChannelStrip* pChannelStrip
2293                          = static_cast<ChannelStrip*> (wlist.at(iChannel));                          = static_cast<ChannelStrip*> (wlist.at(iChannel));
2294                  if (pChannelStrip) {                  if (pChannelStrip) {
2295                          qsamplerChannel *pChannel = pChannelStrip->channel();                          Channel *pChannel = pChannelStrip->channel();
2296                          if (pChannel && pChannel->channelID() == iChannelID)                          if (pChannel && pChannel->channelID() == iChannelID)
2297                                  return pChannelStrip;                                  return pChannelStrip;
2298                  }                  }
# Line 2389  void MainForm::startServer (void) Line 2433  void MainForm::startServer (void)
2433                  switch (QMessageBox::warning(this,                  switch (QMessageBox::warning(this,
2434                          QSAMPLER_TITLE ": " + tr("Warning"),                          QSAMPLER_TITLE ": " + tr("Warning"),
2435                          tr("Could not start the LinuxSampler server.\n\n"                          tr("Could not start the LinuxSampler server.\n\n"
2436                          "Maybe it ss already started."),                          "Maybe it is already started."),
2437                          tr("Stop"), tr("Kill"), tr("Cancel"))) {                          tr("Stop"), tr("Kill"), tr("Cancel"))) {
2438                  case 0:                  case 0:
2439                          m_pServer->terminate();                          m_pServer->terminate();
# Line 2409  void MainForm::startServer (void) Line 2453  void MainForm::startServer (void)
2453                  return;                  return;
2454    
2455          // OK. Let's build the startup process...          // OK. Let's build the startup process...
2456          m_pServer = new QProcess(this);          m_pServer = new QProcess();
2457            bForceServerStop = true;
2458    
2459          // Setup stdout/stderr capture...          // Setup stdout/stderr capture...
2460  //      if (m_pOptions->bStdoutCapture) {  //      if (m_pOptions->bStdoutCapture) {
2461                  //m_pServer->setProcessChannelMode(  #if QT_VERSION >= 0x040200
2462                  //      QProcess::StandardOutput);                  m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);
2463    #endif
2464                  QObject::connect(m_pServer,                  QObject::connect(m_pServer,
2465                          SIGNAL(readyReadStandardOutput()),                          SIGNAL(readyReadStandardOutput()),
2466                          SLOT(readServerStdout()));                          SLOT(readServerStdout()));
# Line 2425  void MainForm::startServer (void) Line 2471  void MainForm::startServer (void)
2471    
2472          // The unforgiveable signal communication...          // The unforgiveable signal communication...
2473          QObject::connect(m_pServer,          QObject::connect(m_pServer,
2474                  SIGNAL(finished(int,QProcess::ExitStatus)),                  SIGNAL(finished(int, QProcess::ExitStatus)),
2475                  SLOT(processServerExit()));                  SLOT(processServerExit()));
2476    
2477          // Build process arguments...          // Build process arguments...
# Line 2456  void MainForm::startServer (void) Line 2502  void MainForm::startServer (void)
2502    
2503    
2504  // Stop linuxsampler server...  // Stop linuxsampler server...
2505  void MainForm::stopServer (void)  void MainForm::stopServer (bool bInteractive)
2506  {  {
2507          // Stop client code.          // Stop client code.
2508          stopClient();          stopClient();
2509    
2510            if (m_pServer && bInteractive) {
2511                    if (QMessageBox::question(this,
2512                            QSAMPLER_TITLE ": " + tr("The backend's fate ..."),
2513                            tr("You have the option to keep the sampler backend (LinuxSampler)\n"
2514                            "running in the background. The sampler would continue to work\n"
2515                            "according to your current sampler session and you could alter the\n"
2516                            "sampler session at any time by relaunching QSampler.\n\n"
2517                            "Do you want LinuxSampler to stop or to keep running in\n"
2518                            "the background?"),
2519                            tr("Stop"), tr("Keep Running")) == 1)
2520                    {
2521                            bForceServerStop = false;
2522                    }
2523            }
2524    
2525          // And try to stop server.          // And try to stop server.
2526          if (m_pServer) {          if (m_pServer && bForceServerStop) {
2527                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2528                  if (m_pServer->state() == QProcess::Running)                  if (m_pServer->state() == QProcess::Running) {
2529    #if defined(WIN32)
2530                            // Try harder...
2531                            m_pServer->kill();
2532    #else
2533                            // Try softly...
2534                          m_pServer->terminate();                          m_pServer->terminate();
2535          }  #endif
2536                    }
2537            }       // Do final processing anyway.
2538            else processServerExit();
2539    
2540          // Give it some time to terminate gracefully and stabilize...          // Give it some time to terminate gracefully and stabilize...
2541          QTime t;          QTime t;
2542          t.start();          t.start();
2543          while (t.elapsed() < QSAMPLER_TIMER_MSECS)          while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2544                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
   
         // Do final processing anyway.  
         processServerExit();  
2545  }  }
2546    
2547    
# Line 2497  void MainForm::processServerExit (void) Line 2563  void MainForm::processServerExit (void)
2563          if (m_pMessages)          if (m_pMessages)
2564                  m_pMessages->flushStdoutBuffer();                  m_pMessages->flushStdoutBuffer();
2565    
2566          if (m_pServer) {          if (m_pServer && bForceServerStop) {
2567                    if (m_pServer->state() != QProcess::NotRunning) {
2568                            appendMessages(tr("Server is being forced..."));
2569                            // Force final server shutdown...
2570                            m_pServer->kill();
2571                            // Give it some time to terminate gracefully and stabilize...
2572                            QTime t;
2573                            t.start();
2574                            while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2575                                    QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2576                    }
2577                  // Force final server shutdown...                  // Force final server shutdown...
2578                  appendMessages(                  appendMessages(
2579                          tr("Server was stopped with exit status %1.")                          tr("Server was stopped with exit status %1.")
2580                          .arg(m_pServer->exitStatus()));                          .arg(m_pServer->exitStatus()));
                 m_pServer->terminate();  
                 if (!m_pServer->waitForFinished(2000))  
                         m_pServer->kill();  
                 // Destroy it.  
2581                  delete m_pServer;                  delete m_pServer;
2582                  m_pServer = NULL;                  m_pServer = NULL;
2583          }          }
# Line 2530  lscp_status_t qsampler_client_callback ( Line 2602  lscp_status_t qsampler_client_callback (
2602          // as this is run under some other thread context.          // as this is run under some other thread context.
2603          // A custom event must be posted here...          // A custom event must be posted here...
2604          QApplication::postEvent(pMainForm,          QApplication::postEvent(pMainForm,
2605                  new qsamplerCustomEvent(event, pchData, cchData));                  new CustomEvent(event, pchData, cchData));
2606    
2607          return LSCP_OK;          return LSCP_OK;
2608  }  }
# Line 2576  bool MainForm::startClient (void) Line 2648  bool MainForm::startClient (void)
2648    
2649          // Subscribe to channel info change notifications...          // Subscribe to channel info change notifications...
2650          if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)          if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)
2651                  appendMessagesClient("lscp_client_subscribe");                  appendMessagesClient("lscp_client_subscribe(CHANNEL_INFO)");
2652    
2653            DeviceStatusForm::onDevicesChanged(); // initialize
2654            updateViewMidiDeviceStatusMenu();
2655            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT) != LSCP_OK)
2656                    appendMessagesClient("lscp_client_subscribe(MIDI_INPUT_DEVICE_COUNT)");
2657    
2658    #if CONFIG_LSCP_CHANNEL_MIDI
2659            // Subscribe to channel MIDI data notifications...
2660            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_MIDI) != LSCP_OK)
2661                    appendMessagesClient("lscp_client_subscribe(CHANNEL_MIDI)");
2662    #endif
2663    
2664    #if CONFIG_LSCP_DEVICE_MIDI
2665            // Subscribe to channel MIDI data notifications...
2666            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_DEVICE_MIDI) != LSCP_OK)
2667                    appendMessagesClient("lscp_client_subscribe(DEVICE_MIDI)");
2668    #endif
2669    
2670          // We may stop scheduling around.          // We may stop scheduling around.
2671          stopSchedule();          stopSchedule();
# Line 2630  void MainForm::stopClient (void) Line 2719  void MainForm::stopClient (void)
2719          closeSession(false);          closeSession(false);
2720    
2721          // Close us as a client...          // Close us as a client...
2722    #if CONFIG_LSCP_DEVICE_MIDI
2723            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_DEVICE_MIDI);
2724    #endif
2725    #if CONFIG_LSCP_CHANNEL_MIDI
2726            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_MIDI);
2727    #endif
2728            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT);
2729          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
2730          ::lscp_client_destroy(m_pClient);          ::lscp_client_destroy(m_pClient);
2731          m_pClient = NULL;          m_pClient = NULL;

Legend:
Removed from v.1515  
changed lines
  Added in v.1698

  ViewVC Help
Powered by ViewVC