Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

dssiuiclient.hpp

00001 /****************************************************************************
00002     
00003     dssiuiclient.hpp - a class that makes writing DSSI GUIs easier
00004     
00005     Copyright (C) 2005  Lars Luthman <larsl@users.sourceforge.net>
00006     
00007     This program is free software; you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation; either version 2 of the License, or
00010     (at your option) any later version.
00011     
00012     This program is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015     GNU General Public License for more details.
00016     
00017     You should have received a copy of the GNU General Public License
00018     along with this program; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 01222-1307  USA
00020 
00021 ****************************************************************************/
00022 
00023 #ifndef DSSIUICLIENT_HPP
00024 #define DSSIUICLIENT_HPP
00025 
00026 #include <queue>
00027 #include <string>
00028 #include <utility>
00029 #include <vector>
00030 
00031 #include <glibmm.h>
00032 #include <gtkmm.h>
00033 #include <lo/lo.h>
00034 #include <sigc++/sigc++.h>
00035 
00036 
00037 using namespace Glib;
00038 using namespace Gtk;
00039 using namespace sigc;
00040 using namespace std;
00041 
00042 
00106 class DSSIUIClient {
00107 public:
00108   
00118   DSSIUIClient(int argc, char** argv);
00119   
00123   ~DSSIUIClient();
00124   
00125   
00128   bool is_valid() const;
00129   
00131   const string& get_identifier() const;
00132   
00133   /* XXX This function should be moved to a subclass (DSSIGladeClient?) so
00134          we get rid of all libglademm dependencies in this class. */
00137   // void connect_gui(RefPtr<Xml> xml);
00138   
00139   /* XXX This function should be moved to a subclass (DSSIGTKClient?) so
00140          we get rid of all gtkmm dependencies in this class. */
00145   void connect_adjustment(Adjustment* adj, int port);
00146 
00147   
00148   // C++ wrappers for OSC methods specified in the DSSI RFC:
00149   
00150   // UI to host
00151   
00154   void send_control(int port, float value);
00155   
00157   void send_program(int bank, int program);
00158   
00163   void send_update_request();
00164   
00166   void send_configure(const string& key, const string& value);
00167   
00170   void send_midi(const char event[4]);
00171   
00175   void send_exiting();
00176   
00177   
00178   // Host to UI
00179   
00182   signal<void, int, float> control_received;
00183   
00186   signal<void, int, int> program_received;
00187   
00190   signal<void, const string, const string> configure_received;
00191   
00194   Dispatcher show_received;
00195   
00197   Dispatcher hide_received;
00198   
00202   Dispatcher quit_received;
00203   
00204   
00205   // Shared memory handling
00206   
00222   void* allocate_shared_memory(int bytes);
00223   
00229   template <class T> T* create_shared_object() {
00230     T* ptr = reinterpret_cast<T*>(allocate_shared_memory(sizeof(T)));
00231     if (ptr)
00232       new (ptr) T();
00233     return ptr;
00234   }
00235   
00237   signal<void> plugin_attached;
00238   
00240   bool plugin_has_attached();
00241   
00242 private:
00243   
00244   // Adjustment connection handling (for host->UI messages)
00245   void update_adjustments(int port, float value);
00246   
00247   // Static callbacks for OSC method calls (liblo is not C++)
00248   static int control_handler(const char *path, const char *types,
00249                              lo_arg **argv, int argc, 
00250                              void *data, void *user_data);
00251   static int program_handler(const char *path, const char *types,
00252                              lo_arg **argv, int argc, 
00253                              void *data, void *user_data);
00254   static int configure_handler(const char *path, const char *types,
00255                                lo_arg **argv, int argc, 
00256                                void *data, void *user_data);
00257   static int show_handler(const char *path, const char *types,
00258                           lo_arg **argv, int argc, 
00259                           void *data, void *user_data);
00260   static int hide_handler(const char *path, const char *types,
00261                           lo_arg **argv, int argc, 
00262                           void *data, void *user_data);
00263   static int quit_handler(const char *path, const char *types,
00264                           lo_arg **argv, int argc, 
00265                           void *data, void *user_data);
00266   
00267   // Dispatchers that get the signals from the OSC thread to the GUI thread
00268   // (the queues and receiver functions are needed for passing data since 
00269   // Dispatchers don't take parameters)
00270   Dispatcher m_control_dispatcher;
00271   queue<pair<int, float> > m_control_queue;
00272   void control_receiver() {
00273     int port = m_control_queue.front().first;
00274     float value = m_control_queue.front().second;
00275     m_control_queue.pop();
00276     if (unsigned(port) < m_adjustments.size() && m_adjustments[port] != NULL)
00277       m_adjustments[port]->set_value(value);
00278     control_received(port, value);
00279   }
00280   Dispatcher m_program_dispatcher;
00281   queue<pair<int, int> > m_program_queue;
00282   void program_receiver() {
00283     /* The plugin should update all it's control widgets when it receives
00284        a program change, but it should NOT send all those control changes
00285        back to the host. We block all /control and /program messages
00286        while the UI is handling the program change. */
00287     m_blocking = true;
00288     int bank = m_program_queue.front().first;
00289     int program = m_program_queue.front().second;
00290     m_program_queue.pop();
00291     program_received(bank, program);
00292     m_blocking = false;
00293   }
00294   Dispatcher m_configure_dispatcher;
00295   queue<pair<string, string> > m_configure_queue;
00296   void configure_receiver() {
00297     string key = m_configure_queue.front().first;
00298     string value = m_configure_queue.front().second;
00299     m_configure_queue.pop();
00300     configure_received(key, value);
00301   }
00302   
00303   bool check_shared_memory();
00304   
00305   lo_address m_plugin_address;
00306   string m_plugin_path;
00307   lo_server_thread m_server_thread;
00308   string m_shm_key;
00309   char* m_plugin_flag;
00310   
00311   bool m_valid;
00312   string m_identifier;
00313   
00314   vector<Adjustment*> m_adjustments;
00315   bool m_blocking;
00316 };
00317 
00318 
00319 #endif
00320 

Generated on Wed Mar 1 17:12:44 2006 for DSSI support libraries by  doxygen 1.4.4