ardour
nsmclient.cc
Go to the documentation of this file.
1 
2 /*******************************************************************************/
3 /* Copyright (C) 2012 Jonathan Moore Liles */
4 /* */
5 /* This program is free software; you can redistribute it and/or modify it */
6 /* under the terms of the GNU General Public License as published by the */
7 /* Free Software Foundation; either version 2 of the License, or (at your */
8 /* option) any later version. */
9 /* */
10 /* This program is distributed in the hope that it will be useful, but WITHOUT */
11 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
12 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */
13 /* more details. */
14 /* */
15 /* You should have received a copy of the GNU General Public License along */
16 /* with This program; see the file COPYING. If not,write to the Free Software */
17 /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 /*******************************************************************************/
19 
20 #include "nsmclient.h"
21 #include <string.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24 #include <stdlib.h>
25 
26 #ifndef COMPILER_MSVC
27 #pragma GCC diagnostic ignored "-Wunused-parameter"
28 #else
29 #include <process.h> // Needed for 'getpid()'
30 
31 #include <lo/lo_osc_types.h>
32 #define LO_TT_IMMEDIATE lo_get_tt_immediate()
33 lo_timetag lo_get_tt_immediate() { lo_timetag tt = {0U,1U}; return tt; }
34 #endif
35 
36 namespace NSM
37 {
38 
39 /************************/
40 /* OSC Message Handlers */
41 /************************/
42 
43 #undef OSC_REPLY
44 #undef OSC_REPLY_ERR
45 
46 #define OSC_REPLY( value ) lo_send_from( ((NSM::Client*)user_data)->nsm_addr, ((NSM::Client*)user_data)->_server, LO_TT_IMMEDIATE, "/reply", "ss", path, value )
47 
48 #define OSC_REPLY_ERR( errcode, value ) lo_send_from( ((NSM::Client*)user_data)->nsm_addr, ((NSM::Client*)user_data)->_server, LO_TT_IMMEDIATE, "/error", "sis", path, errcode, value )
49 
51  {
52  nsm_addr = 0;
53  _nsm_client_id = 0;
54  _nsm_client_path = 0;
56  nsm_url = "";
57  nsm_is_active = false;
58  _server = 0;
59  _st = 0;
60  }
61 
63  {
64  if ( _st )
65  stop();
66 
67  if ( _st )
68  lo_server_thread_free( _st );
69  else
70  lo_server_free ( _server );
71  }
72 
73  void
74  Client::announce ( const char *application_name, const char *capabilities, const char *process_name )
75  {
76 
77  lo_address to = lo_address_new_from_url( nsm_url );
78 
79  if ( ! to )
80  {
81  return;
82  }
83 
84  int pid = (int)getpid();
85 
86  lo_send_from( to, _server, LO_TT_IMMEDIATE, "/nsm/server/announce", "sssiii",
87  application_name,
88  capabilities,
89  process_name,
90  1, /* api_major_version */
91  0, /* api_minor_version */
92  pid );
93 
94  lo_address_free( to );
95  }
96 
97  void
98  Client::progress ( float p )
99  {
100  if ( nsm_is_active )
101  {
102  lo_send_from( nsm_addr, _server, LO_TT_IMMEDIATE, "/nsm/client/progress", "f", p );
103  }
104  }
105 
106  void
108  {
109  if ( nsm_is_active )
110  {
111  lo_send_from( nsm_addr, _server, LO_TT_IMMEDIATE, "/nsm/client/is_dirty", "" );
112  }
113  }
114 
115  void
117  {
118  if ( nsm_is_active )
119  {
120  lo_send_from( nsm_addr, _server, LO_TT_IMMEDIATE, "/nsm/client/is_clean", "" );
121  }
122  }
123 
124  void
125  Client::message ( int priority, const char *msg )
126  {
127  if ( nsm_is_active )
128  {
129  lo_send_from( nsm_addr, _server, LO_TT_IMMEDIATE, "/nsm/client/message", "is", priority, msg );
130  }
131  }
132 
133 
134  void
135  Client::broadcast ( lo_message msg )
136  {
137  if ( nsm_is_active )
138  {
139  lo_send_message_from( nsm_addr, _server, "/nsm/server/broadcast", msg );
140  }
141  }
142 
143  void
144  Client::check ( int timeout )
145  {
146  if ( lo_server_wait( _server, timeout ) )
147  while ( lo_server_recv_noblock( _server, 0 ) ) {}
148  }
149 
150  void
152  {
153  lo_server_thread_start( _st );
154  }
155 
156  void
158  {
159  lo_server_thread_stop( _st );
160  }
161 
162  int
163  Client::init ( const char *nsm_url )
164  {
165  this->nsm_url = nsm_url;
166 
167  lo_address addr = lo_address_new_from_url( nsm_url );
168  int proto = lo_address_get_protocol( addr );
169  lo_address_free( addr );
170 
171  _server = lo_server_new_with_proto( NULL, proto, NULL );
172 
173  if ( ! _server )
174  return -1;
175 
176  lo_server_add_method( _server, "/error", "sis", &Client::osc_error, this );
177  lo_server_add_method( _server, "/reply", "ssss", &Client::osc_announce_reply, this );
178  lo_server_add_method( _server, "/nsm/client/open", "sss", &Client::osc_open, this );
179  lo_server_add_method( _server, "/nsm/client/save", "", &Client::osc_save, this );
180  lo_server_add_method( _server, "/nsm/client/session_is_loaded", "", &Client::osc_session_is_loaded, this );
181  lo_server_add_method( _server, NULL, NULL, &Client::osc_broadcast, this );
182 
183  return 0;
184  }
185 
186  int
187  Client::init_thread ( const char *nsm_url )
188  {
189  this->nsm_url = nsm_url;
190 
191  lo_address addr = lo_address_new_from_url( nsm_url );
192  int proto = lo_address_get_protocol( addr );
193  lo_address_free( addr );
194 
195  _st = lo_server_thread_new_with_proto( NULL, proto, NULL );
196  _server = lo_server_thread_get_server( _st );
197 
198  if ( ! _server || ! _st )
199  return -1;
200 
201  lo_server_thread_add_method( _st, "/error", "sis", &Client::osc_error, this );
202  lo_server_thread_add_method( _st, "/reply", "ssss", &Client::osc_announce_reply, this );
203  lo_server_thread_add_method( _st, "/nsm/client/open", "sss", &Client::osc_open, this );
204  lo_server_thread_add_method( _st, "/nsm/client/save", "", &Client::osc_save, this );
205  lo_server_thread_add_method( _st, "/nsm/client/session_is_loaded", "", &Client::osc_session_is_loaded, this );
206  lo_server_thread_add_method( _st, NULL, NULL, &Client::osc_broadcast, this );
207 
208  return 0;
209  }
210 
211 /************************/
212 /* OSC Message Handlers */
213 /************************/
214 
215  int
216  Client::osc_broadcast ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
217  {
218  return ((NSM::Client*)user_data)->command_broadcast( path, msg );
219  }
220 
221  int
222  Client::osc_save ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
223  {
224  char *out_msg = NULL;
225 
226  int r = ((NSM::Client*)user_data)->command_save(&out_msg);
227 
228  if ( r )
229  OSC_REPLY_ERR( r, ( out_msg ? out_msg : "") );
230  else
231  OSC_REPLY( "OK" );
232 
233  if ( out_msg )
234  free( out_msg );
235 
236  return 0;
237  }
238 
239  int
240  Client::osc_open ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
241  {
242  char *out_msg = NULL;
243 
244  NSM::Client *nsm = (NSM::Client*)user_data;
245 
246  nsm->_nsm_client_id = strdup( &argv[2]->s );
247  nsm->_nsm_client_path = strdup( &argv[0]->s );
248 
249  int r = ((NSM::Client*)user_data)->command_open( &argv[0]->s, &argv[1]->s, &argv[2]->s, &out_msg);
250 
251  if ( r )
252  OSC_REPLY_ERR( r, ( out_msg ? out_msg : "") );
253  else
254  OSC_REPLY( "OK" );
255 
256  if ( out_msg )
257  free( out_msg );
258 
259  return 0;
260  }
261 
262  int
263  Client::osc_session_is_loaded ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
264  {
265  NSM::Client *nsm = (NSM::Client*)user_data;
266 
268 
269  return 0;
270  }
271 
272  int
273  Client::osc_error ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
274  {
275  if ( strcmp( &argv[0]->s, "/nsm/server/announce" ) )
276  return -1;
277 
278  NSM::Client *nsm = (NSM::Client*)user_data;
279 
280 
281  nsm->nsm_is_active = false;
282 
283  nsm->command_active( nsm->nsm_is_active );
284 
285  return 0;
286  }
287 
288  int
289  Client::osc_announce_reply ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
290  {
291  if ( strcmp( &argv[0]->s, "/nsm/server/announce" ) )
292  return -1;
293 
294  NSM::Client *nsm = (NSM::Client*)user_data;
295 
296  nsm->nsm_is_active = true;
297  nsm->_session_manager_name = strdup( &argv[2]->s );
298  nsm->nsm_addr = lo_address_new_from_url( lo_address_get_url( lo_message_get_source( msg ) ));
299 
300  nsm->command_active( nsm->nsm_is_active );
301 
302  return 0;
303  }
304 };
void is_clean(void)
Definition: nsmclient.cc:116
char * _session_manager_name
Definition: nsmclient.h:40
static int osc_broadcast(const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data)
Definition: nsmclient.cc:216
void announce(const char *appliction_name, const char *capabilities, const char *process_name)
Definition: nsmclient.cc:74
void message(int priority, const char *msg)
Definition: nsmclient.cc:125
void stop(void)
Definition: nsmclient.cc:157
virtual void command_active(bool)
Definition: nsmclient.h:94
static int osc_open(const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data)
Definition: nsmclient.cc:240
lo_server_thread _st
Definition: nsmclient.h:35
const char * nsm_url
Definition: nsmclient.h:32
static int osc_session_is_loaded(const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data)
Definition: nsmclient.cc:263
static int osc_error(const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data)
Definition: nsmclient.cc:273
char * _nsm_client_id
Definition: nsmclient.h:39
void check(int timeout=0)
Definition: nsmclient.cc:144
virtual void command_session_is_loaded(void)
Definition: nsmclient.h:96
bool nsm_is_active
Definition: nsmclient.h:38
lo_address nsm_addr
Definition: nsmclient.h:36
int init(const char *nsm_url)
Definition: nsmclient.cc:163
static int osc_save(const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data)
Definition: nsmclient.cc:222
virtual ~Client()
Definition: nsmclient.cc:62
lo_server _server
Definition: nsmclient.h:34
void progress(float f)
Definition: nsmclient.cc:98
void start(void)
Definition: nsmclient.cc:151
#define OSC_REPLY(value)
Definition: nsmclient.cc:46
void broadcast(lo_message msg)
Definition: nsmclient.cc:135
int init_thread(const char *nsm_url)
Definition: nsmclient.cc:187
#define OSC_REPLY_ERR(errcode, value)
Definition: nsmclient.cc:48
static int osc_announce_reply(const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data)
Definition: nsmclient.cc:289
Definition: nsmclient.cc:36
void is_dirty(void)
Definition: nsmclient.cc:107
char * _nsm_client_path
Definition: nsmclient.h:41