/[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 1558 by capela, Thu Dec 6 09:35:33 2007 UTC revision 1739 by capela, Wed May 14 17:37:45 2008 UTC
# Line 1  Line 1 
1  // qsamplerMainForm.cpp  // qsamplerMainForm.cpp
2  //  //
3  /****************************************************************************  /****************************************************************************
4     Copyright (C) 2004-2007, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2008, 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 390  void MainForm::setup ( Options *pOptions Line 391  void MainForm::setup ( Options *pOptions
391  #else  #else
392          viewInstrumentsAction->setEnabled(false);          viewInstrumentsAction->setEnabled(false);
393  #endif  #endif
394            // Setup messages logging appropriately...
395            m_pMessages->setLogging(
396                    m_pOptions->bMessagesLog,
397                    m_pOptions->sMessagesLogPath);
398          // Set message defaults...          // Set message defaults...
399          updateMessagesFont();          updateMessagesFont();
400          updateMessagesLimit();          updateMessagesLimit();
# Line 471  bool MainForm::queryClose (void) Line 476  bool MainForm::queryClose (void)
476                          if (m_pDeviceForm)                          if (m_pDeviceForm)
477                                  m_pDeviceForm->close();                                  m_pDeviceForm->close();
478                          // Stop client and/or server, gracefully.                          // Stop client and/or server, gracefully.
479                          stopServer();                          stopServer(true /*interactive*/);
480                  }                  }
481          }          }
482    
# Line 481  bool MainForm::queryClose (void) Line 486  bool MainForm::queryClose (void)
486    
487  void MainForm::closeEvent ( QCloseEvent *pCloseEvent )  void MainForm::closeEvent ( QCloseEvent *pCloseEvent )
488  {  {
489          if (queryClose())          if (queryClose()) {
490                    DeviceStatusForm::deleteAllInstances();
491                  pCloseEvent->accept();                  pCloseEvent->accept();
492          else          } else
493                  pCloseEvent->ignore();                  pCloseEvent->ignore();
494  }  }
495    
# Line 551  void MainForm::customEvent(QEvent* pCust Line 557  void MainForm::customEvent(QEvent* pCust
557          // For the time being, just pump it to messages.          // For the time being, just pump it to messages.
558          if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {          if (pCustomEvent->type() == QSAMPLER_CUSTOM_EVENT) {
559                  CustomEvent *pEvent = static_cast<CustomEvent *> (pCustomEvent);                  CustomEvent *pEvent = static_cast<CustomEvent *> (pCustomEvent);
560                  if (pEvent->event() == LSCP_EVENT_CHANNEL_INFO) {                  switch (pEvent->event()) {
561                          int iChannelID = pEvent->data().toInt();                          case LSCP_EVENT_CHANNEL_COUNT:
562                          ChannelStrip *pChannelStrip = channelStrip(iChannelID);                                  updateAllChannelStrips(true);
563                          if (pChannelStrip)                                  break;
564                                  channelStripChanged(pChannelStrip);                          case LSCP_EVENT_CHANNEL_INFO: {
565                  } else {                                  int iChannelID = pEvent->data().toInt();
566                          appendMessagesColor(tr("Notify event: %1 data: %2")                                  ChannelStrip *pChannelStrip = channelStrip(iChannelID);
567                                  .arg(::lscp_event_to_text(pEvent->event()))                                  if (pChannelStrip)
568                                  .arg(pEvent->data()), "#996699");                                          channelStripChanged(pChannelStrip);
569                                    break;
570                            }
571                            case LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT:
572                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
573                                    DeviceStatusForm::onDevicesChanged();
574                                    updateViewMidiDeviceStatusMenu();
575                                    break;
576                            case LSCP_EVENT_MIDI_INPUT_DEVICE_INFO: {
577                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
578                                    const int iDeviceID = pEvent->data().section(' ', 0, 0).toInt();
579                                    DeviceStatusForm::onDeviceChanged(iDeviceID);
580                                    break;
581                            }
582                            case LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT:
583                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
584                                    break;
585                            case LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO:
586                                    if (m_pDeviceForm) m_pDeviceForm->refreshDevices();
587                                    break;
588    #if CONFIG_EVENT_CHANNEL_MIDI
589                            case LSCP_EVENT_CHANNEL_MIDI: {
590                                    const int iChannelID = pEvent->data().section(' ', 0, 0).toInt();
591                                    ChannelStrip *pChannelStrip = channelStrip(iChannelID);
592                                    if (pChannelStrip)
593                                            pChannelStrip->midiArrived();
594                                    break;
595                            }
596    #endif
597    #if CONFIG_EVENT_DEVICE_MIDI
598                            case LSCP_EVENT_DEVICE_MIDI: {
599                                    const int iDeviceID = pEvent->data().section(' ', 0, 0).toInt();
600                                    const int iPortID   = pEvent->data().section(' ', 1, 1).toInt();
601                                    DeviceStatusForm* pDeviceStatusForm =
602                                            DeviceStatusForm::getInstance(iDeviceID);
603                                    if (pDeviceStatusForm)
604                                            pDeviceStatusForm->midiArrived(iPortID);
605                                    break;
606                            }
607    #endif
608                            default:
609                                    appendMessagesColor(tr("Notify event: %1 data: %2")
610                                            .arg(::lscp_event_to_text(pEvent->event()))
611                                            .arg(pEvent->data()), "#996699");
612                  }                  }
613          }          }
614  }  }
615    
616    void MainForm::updateViewMidiDeviceStatusMenu() {
617            m_ui.viewMidiDeviceStatusMenu->clear();
618            const std::map<int, DeviceStatusForm*> statusForms =
619                    DeviceStatusForm::getInstances();
620            for (
621                    std::map<int, DeviceStatusForm*>::const_iterator iter = statusForms.begin();
622                    iter != statusForms.end(); ++iter
623            ) {
624                    DeviceStatusForm* pForm = iter->second;
625                    m_ui.viewMidiDeviceStatusMenu->addAction(
626                            pForm->visibleAction()
627                    );
628            }
629    }
630    
631  // Context menu event handler.  // Context menu event handler.
632  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )  void MainForm::contextMenuEvent( QContextMenuEvent *pEvent )
633  {  {
# Line 1556  void MainForm::viewOptions (void) Line 1620  void MainForm::viewOptions (void)
1620                  int     iOldServerTimeout   = m_pOptions->iServerTimeout;                  int     iOldServerTimeout   = m_pOptions->iServerTimeout;
1621                  bool    bOldServerStart     = m_pOptions->bServerStart;                  bool    bOldServerStart     = m_pOptions->bServerStart;
1622                  QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;                  QString sOldServerCmdLine   = m_pOptions->sServerCmdLine;
1623                    bool    bOldMessagesLog     = m_pOptions->bMessagesLog;
1624                    QString sOldMessagesLogPath = m_pOptions->sMessagesLogPath;
1625                  QString sOldDisplayFont     = m_pOptions->sDisplayFont;                  QString sOldDisplayFont     = m_pOptions->sDisplayFont;
1626                  bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;                  bool    bOldDisplayEffect   = m_pOptions->bDisplayEffect;
1627                  int     iOldMaxVolume       = m_pOptions->iMaxVolume;                  int     iOldMaxVolume       = m_pOptions->iMaxVolume;
# Line 1583  void MainForm::viewOptions (void) Line 1649  void MainForm::viewOptions (void)
1649                                  updateMessagesCapture();                                  updateMessagesCapture();
1650                          }                          }
1651                          // Check wheather something immediate has changed.                          // Check wheather something immediate has changed.
1652                            if (( bOldMessagesLog && !m_pOptions->bMessagesLog) ||
1653                                    (!bOldMessagesLog &&  m_pOptions->bMessagesLog) ||
1654                                    (sOldMessagesLogPath != m_pOptions->sMessagesLogPath))
1655                                    m_pMessages->setLogging(
1656                                            m_pOptions->bMessagesLog, m_pOptions->sMessagesLogPath);
1657                          if (( bOldCompletePath && !m_pOptions->bCompletePath) ||                          if (( bOldCompletePath && !m_pOptions->bCompletePath) ||
1658                                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||                                  (!bOldCompletePath &&  m_pOptions->bCompletePath) ||
1659                                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))                                  (iOldMaxRecentFiles != m_pOptions->iMaxRecentFiles))
# Line 1911  void MainForm::updateSession (void) Line 1982  void MainForm::updateSession (void)
1982          }          }
1983  #endif  #endif
1984    
1985            updateAllChannelStrips(false);
1986    
1987            // Do we auto-arrange?
1988            if (m_pOptions && m_pOptions->bAutoArrange)
1989                    channelsArrange();
1990    
1991            // Remember to refresh devices and instruments...
1992            if (m_pInstrumentListForm)
1993                    m_pInstrumentListForm->refreshInstruments();
1994            if (m_pDeviceForm)
1995                    m_pDeviceForm->refreshDevices();
1996    }
1997    
1998    void MainForm::updateAllChannelStrips(bool bRemoveDeadStrips) {
1999          // Retrieve the current channel list.          // Retrieve the current channel list.
2000          int *piChannelIDs = ::lscp_list_channels(m_pClient);          int *piChannelIDs = ::lscp_list_channels(m_pClient);
2001          if (piChannelIDs == NULL) {          if (piChannelIDs == NULL) {
# Line 1927  void MainForm::updateSession (void) Line 2012  void MainForm::updateSession (void)
2012                          if (!channelStrip(piChannelIDs[iChannel]))                          if (!channelStrip(piChannelIDs[iChannel]))
2013                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));                                  createChannelStrip(new Channel(piChannelIDs[iChannel]));
2014                  }                  }
                 m_pWorkspace->setUpdatesEnabled(true);  
         }  
2015    
2016          // Do we auto-arrange?                  // Do we auto-arrange?
2017          if (m_pOptions && m_pOptions->bAutoArrange)                  if (m_pOptions && m_pOptions->bAutoArrange)
2018                  channelsArrange();                          channelsArrange();
2019    
2020          // Remember to refresh devices and instruments...                  stabilizeForm();
         if (m_pInstrumentListForm)  
                 m_pInstrumentListForm->refreshInstruments();  
         if (m_pDeviceForm)  
                 m_pDeviceForm->refreshDevices();  
 }  
2021    
2022                    // remove dead channel strips
2023                    if (bRemoveDeadStrips) {
2024                            for (int i = 0; channelStripAt(i); ++i) {
2025                                    ChannelStrip* pChannelStrip = channelStripAt(i);
2026                                    bool bExists = false;
2027                                    for (int j = 0; piChannelIDs[j] >= 0; ++j) {
2028                                            if (!pChannelStrip->channel()) break;
2029                                            if (piChannelIDs[j] == pChannelStrip->channel()->channelID()) {
2030                                                    // strip exists, don't touch it
2031                                                    bExists = true;
2032                                                    break;
2033                                            }
2034                                    }
2035                                    if (!bExists) destroyChannelStrip(pChannelStrip);
2036                            }
2037                    }
2038                    m_pWorkspace->setUpdatesEnabled(true);
2039            }
2040    }
2041    
2042  // Update the recent files list and menu.  // Update the recent files list and menu.
2043  void MainForm::updateRecentFiles ( const QString& sFilename )  void MainForm::updateRecentFiles ( const QString& sFilename )
# Line 2219  ChannelStrip* MainForm::createChannelStr Line 2316  ChannelStrip* MainForm::createChannelStr
2316          return pChannelStrip;          return pChannelStrip;
2317  }  }
2318    
2319    void MainForm::destroyChannelStrip(ChannelStrip* pChannelStrip) {
2320            // Just delete the channel strip.
2321            delete pChannelStrip;
2322    
2323            // Do we auto-arrange?
2324            if (m_pOptions && m_pOptions->bAutoArrange)
2325                    channelsArrange();
2326    
2327            stabilizeForm();
2328    }
2329    
2330  // Retrieve the active channel strip.  // Retrieve the active channel strip.
2331  ChannelStrip* MainForm::activeChannelStrip (void)  ChannelStrip* MainForm::activeChannelStrip (void)
# Line 2230  ChannelStrip* MainForm::activeChannelStr Line 2337  ChannelStrip* MainForm::activeChannelStr
2337  // Retrieve a channel strip by index.  // Retrieve a channel strip by index.
2338  ChannelStrip* MainForm::channelStripAt ( int iChannel )  ChannelStrip* MainForm::channelStripAt ( int iChannel )
2339  {  {
2340            if (!m_pWorkspace) return NULL;
2341    
2342          QWidgetList wlist = m_pWorkspace->windowList();          QWidgetList wlist = m_pWorkspace->windowList();
2343          if (wlist.isEmpty())          if (wlist.isEmpty())
2344                  return NULL;                  return NULL;
2345    
2346          return static_cast<ChannelStrip *> (wlist.at(iChannel));          if (iChannel < 0 || iChannel >= wlist.size())
2347                    return NULL;
2348    
2349            return dynamic_cast<ChannelStrip *> (wlist.at(iChannel));
2350  }  }
2351    
2352    
# Line 2390  void MainForm::startServer (void) Line 2502  void MainForm::startServer (void)
2502                  switch (QMessageBox::warning(this,                  switch (QMessageBox::warning(this,
2503                          QSAMPLER_TITLE ": " + tr("Warning"),                          QSAMPLER_TITLE ": " + tr("Warning"),
2504                          tr("Could not start the LinuxSampler server.\n\n"                          tr("Could not start the LinuxSampler server.\n\n"
2505                          "Maybe it ss already started."),                          "Maybe it is already started."),
2506                          tr("Stop"), tr("Kill"), tr("Cancel"))) {                          tr("Stop"), tr("Kill"), tr("Cancel"))) {
2507                  case 0:                  case 0:
2508                          m_pServer->terminate();                          m_pServer->terminate();
# Line 2410  void MainForm::startServer (void) Line 2522  void MainForm::startServer (void)
2522                  return;                  return;
2523    
2524          // OK. Let's build the startup process...          // OK. Let's build the startup process...
2525          m_pServer = new QProcess(this);          m_pServer = new QProcess();
2526            bForceServerStop = true;
2527    
2528          // Setup stdout/stderr capture...          // Setup stdout/stderr capture...
2529  //      if (m_pOptions->bStdoutCapture) {  //      if (m_pOptions->bStdoutCapture) {
2530                  //m_pServer->setProcessChannelMode(  #if QT_VERSION >= 0x040200
2531                  //      QProcess::StandardOutput);                  m_pServer->setProcessChannelMode(QProcess::ForwardedChannels);
2532    #endif
2533                  QObject::connect(m_pServer,                  QObject::connect(m_pServer,
2534                          SIGNAL(readyReadStandardOutput()),                          SIGNAL(readyReadStandardOutput()),
2535                          SLOT(readServerStdout()));                          SLOT(readServerStdout()));
# Line 2426  void MainForm::startServer (void) Line 2540  void MainForm::startServer (void)
2540    
2541          // The unforgiveable signal communication...          // The unforgiveable signal communication...
2542          QObject::connect(m_pServer,          QObject::connect(m_pServer,
2543                  SIGNAL(finished(int,QProcess::ExitStatus)),                  SIGNAL(finished(int, QProcess::ExitStatus)),
2544                  SLOT(processServerExit()));                  SLOT(processServerExit()));
2545    
2546          // Build process arguments...          // Build process arguments...
# Line 2457  void MainForm::startServer (void) Line 2571  void MainForm::startServer (void)
2571    
2572    
2573  // Stop linuxsampler server...  // Stop linuxsampler server...
2574  void MainForm::stopServer (void)  void MainForm::stopServer (bool bInteractive)
2575  {  {
2576          // Stop client code.          // Stop client code.
2577          stopClient();          stopClient();
2578    
2579            if (m_pServer && bInteractive) {
2580                    if (QMessageBox::question(this,
2581                            QSAMPLER_TITLE ": " + tr("The backend's fate ..."),
2582                            tr("You have the option to keep the sampler backend (LinuxSampler)\n"
2583                            "running in the background. The sampler would continue to work\n"
2584                            "according to your current sampler session and you could alter the\n"
2585                            "sampler session at any time by relaunching QSampler.\n\n"
2586                            "Do you want LinuxSampler to stop or to keep running in\n"
2587                            "the background?"),
2588                            tr("Stop"), tr("Keep Running")) == 1)
2589                    {
2590                            bForceServerStop = false;
2591                    }
2592            }
2593    
2594          // And try to stop server.          // And try to stop server.
2595          if (m_pServer) {          if (m_pServer && bForceServerStop) {
2596                  appendMessages(tr("Server is stopping..."));                  appendMessages(tr("Server is stopping..."));
2597                  if (m_pServer->state() == QProcess::Running)                  if (m_pServer->state() == QProcess::Running) {
2598    #if defined(WIN32)
2599                            // Try harder...
2600                            m_pServer->kill();
2601    #else
2602                            // Try softly...
2603                          m_pServer->terminate();                          m_pServer->terminate();
2604          }  #endif
2605                    }
2606            }       // Do final processing anyway.
2607            else processServerExit();
2608    
2609          // Give it some time to terminate gracefully and stabilize...          // Give it some time to terminate gracefully and stabilize...
2610          QTime t;          QTime t;
2611          t.start();          t.start();
2612          while (t.elapsed() < QSAMPLER_TIMER_MSECS)          while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2613                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);                  QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
   
         // Do final processing anyway.  
         processServerExit();  
2614  }  }
2615    
2616    
# Line 2498  void MainForm::processServerExit (void) Line 2632  void MainForm::processServerExit (void)
2632          if (m_pMessages)          if (m_pMessages)
2633                  m_pMessages->flushStdoutBuffer();                  m_pMessages->flushStdoutBuffer();
2634    
2635          if (m_pServer) {          if (m_pServer && bForceServerStop) {
2636                    if (m_pServer->state() != QProcess::NotRunning) {
2637                            appendMessages(tr("Server is being forced..."));
2638                            // Force final server shutdown...
2639                            m_pServer->kill();
2640                            // Give it some time to terminate gracefully and stabilize...
2641                            QTime t;
2642                            t.start();
2643                            while (t.elapsed() < QSAMPLER_TIMER_MSECS)
2644                                    QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
2645                    }
2646                  // Force final server shutdown...                  // Force final server shutdown...
2647                  appendMessages(                  appendMessages(
2648                          tr("Server was stopped with exit status %1.")                          tr("Server was stopped with exit status %1.")
2649                          .arg(m_pServer->exitStatus()));                          .arg(m_pServer->exitStatus()));
                 m_pServer->terminate();  
                 if (!m_pServer->waitForFinished(2000))  
                         m_pServer->kill();  
                 // Destroy it.  
2650                  delete m_pServer;                  delete m_pServer;
2651                  m_pServer = NULL;                  m_pServer = NULL;
2652          }          }
# Line 2576  bool MainForm::startClient (void) Line 2716  bool MainForm::startClient (void)
2716                  .arg(::lscp_client_get_timeout(m_pClient)));                  .arg(::lscp_client_get_timeout(m_pClient)));
2717    
2718          // Subscribe to channel info change notifications...          // Subscribe to channel info change notifications...
2719            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT) != LSCP_OK)
2720                    appendMessagesClient("lscp_client_subscribe(CHANNEL_COUNT)");
2721          if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)          if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO) != LSCP_OK)
2722                  appendMessagesClient("lscp_client_subscribe");                  appendMessagesClient("lscp_client_subscribe(CHANNEL_INFO)");
2723    
2724            DeviceStatusForm::onDevicesChanged(); // initialize
2725            updateViewMidiDeviceStatusMenu();
2726            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT) != LSCP_OK)
2727                    appendMessagesClient("lscp_client_subscribe(MIDI_INPUT_DEVICE_COUNT)");
2728            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO) != LSCP_OK)
2729                    appendMessagesClient("lscp_client_subscribe(MIDI_INPUT_DEVICE_INFO)");
2730            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT) != LSCP_OK)
2731                    appendMessagesClient("lscp_client_subscribe(AUDIO_OUTPUT_DEVICE_COUNT)");
2732            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO) != LSCP_OK)
2733                    appendMessagesClient("lscp_client_subscribe(AUDIO_OUTPUT_DEVICE_INFO)");
2734    
2735    #if CONFIG_EVENT_CHANNEL_MIDI
2736            // Subscribe to channel MIDI data notifications...
2737            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_CHANNEL_MIDI) != LSCP_OK)
2738                    appendMessagesClient("lscp_client_subscribe(CHANNEL_MIDI)");
2739    #endif
2740    
2741    #if CONFIG_EVENT_DEVICE_MIDI
2742            // Subscribe to channel MIDI data notifications...
2743            if (::lscp_client_subscribe(m_pClient, LSCP_EVENT_DEVICE_MIDI) != LSCP_OK)
2744                    appendMessagesClient("lscp_client_subscribe(DEVICE_MIDI)");
2745    #endif
2746    
2747          // We may stop scheduling around.          // We may stop scheduling around.
2748          stopSchedule();          stopSchedule();
# Line 2631  void MainForm::stopClient (void) Line 2796  void MainForm::stopClient (void)
2796          closeSession(false);          closeSession(false);
2797    
2798          // Close us as a client...          // Close us as a client...
2799    #if CONFIG_EVENT_DEVICE_MIDI
2800            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_DEVICE_MIDI);
2801    #endif
2802    #if CONFIG_EVENT_CHANNEL_MIDI
2803            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_MIDI);
2804    #endif
2805            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO);
2806            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT);
2807            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO);
2808            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT);
2809          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);          ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_INFO);
2810            ::lscp_client_unsubscribe(m_pClient, LSCP_EVENT_CHANNEL_COUNT);
2811          ::lscp_client_destroy(m_pClient);          ::lscp_client_destroy(m_pClient);
2812          m_pClient = NULL;          m_pClient = NULL;
2813    

Legend:
Removed from v.1558  
changed lines
  Added in v.1739

  ViewVC Help
Powered by ViewVC