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

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

  ViewVC Help
Powered by ViewVC