2 /*******************************************************************************/
3 /* Copyright (C) 2012 Jonathan Moore Liles */
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. */
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 */
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 /*******************************************************************************/
20 #include "nsmclient.h"
22 #include <sys/types.h>
27 #pragma GCC diagnostic ignored "-Wunused-parameter"
29 #include <process.h> // Needed for 'getpid()'
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; }
39 /************************/
40 /* OSC Message Handlers */
41 /************************/
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 )
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 )
55 _session_manager_name = 0;
57 nsm_is_active = false;
68 lo_server_thread_free( _st );
70 lo_server_free ( _server );
74 Client::announce ( const char *application_name, const char *capabilities, const char *process_name )
77 lo_address to = lo_address_new_from_url( nsm_url );
84 int pid = (int)getpid();
86 lo_send_from( to, _server, LO_TT_IMMEDIATE, "/nsm/server/announce", "sssiii",
90 1, /* api_major_version */
91 0, /* api_minor_version */
94 lo_address_free( to );
98 Client::progress ( float p )
102 lo_send_from( nsm_addr, _server, LO_TT_IMMEDIATE, "/nsm/client/progress", "f", p );
107 Client::is_dirty ( void )
111 lo_send_from( nsm_addr, _server, LO_TT_IMMEDIATE, "/nsm/client/is_dirty", "" );
116 Client::is_clean ( void )
120 lo_send_from( nsm_addr, _server, LO_TT_IMMEDIATE, "/nsm/client/is_clean", "" );
125 Client::message ( int priority, const char *msg )
129 lo_send_from( nsm_addr, _server, LO_TT_IMMEDIATE, "/nsm/client/message", "is", priority, msg );
135 Client::broadcast ( lo_message msg )
139 lo_send_message_from( nsm_addr, _server, "/nsm/server/broadcast", msg );
144 Client::check ( int timeout )
146 if ( lo_server_wait( _server, timeout ) )
147 while ( lo_server_recv_noblock( _server, 0 ) ) {}
153 lo_server_thread_start( _st );
159 lo_server_thread_stop( _st );
163 Client::init ( const char *nsm_url )
165 this->nsm_url = nsm_url;
167 lo_address addr = lo_address_new_from_url( nsm_url );
168 int proto = lo_address_get_protocol( addr );
169 lo_address_free( addr );
171 _server = lo_server_new_with_proto( NULL, proto, NULL );
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 );
187 Client::init_thread ( const char *nsm_url )
189 this->nsm_url = nsm_url;
191 lo_address addr = lo_address_new_from_url( nsm_url );
192 int proto = lo_address_get_protocol( addr );
193 lo_address_free( addr );
195 _st = lo_server_thread_new_with_proto( NULL, proto, NULL );
196 _server = lo_server_thread_get_server( _st );
198 if ( ! _server || ! _st )
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 );
211 /************************/
212 /* OSC Message Handlers */
213 /************************/
216 Client::osc_broadcast ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
218 return ((NSM::Client*)user_data)->command_broadcast( path, msg );
222 Client::osc_save ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
224 char *out_msg = NULL;
226 int r = ((NSM::Client*)user_data)->command_save(&out_msg);
229 OSC_REPLY_ERR( r, ( out_msg ? out_msg : "") );
240 Client::osc_open ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
242 char *out_msg = NULL;
244 NSM::Client *nsm = (NSM::Client*)user_data;
246 nsm->_nsm_client_id = strdup( &argv[2]->s );
247 nsm->_nsm_client_path = strdup( &argv[0]->s );
249 int r = ((NSM::Client*)user_data)->command_open( &argv[0]->s, &argv[1]->s, &argv[2]->s, &out_msg);
252 OSC_REPLY_ERR( r, ( out_msg ? out_msg : "") );
263 Client::osc_session_is_loaded ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
265 NSM::Client *nsm = (NSM::Client*)user_data;
267 nsm->command_session_is_loaded();
273 Client::osc_error ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
275 if ( strcmp( &argv[0]->s, "/nsm/server/announce" ) )
278 NSM::Client *nsm = (NSM::Client*)user_data;
281 nsm->nsm_is_active = false;
283 nsm->command_active( nsm->nsm_is_active );
289 Client::osc_announce_reply ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
291 if ( strcmp( &argv[0]->s, "/nsm/server/announce" ) )
294 NSM::Client *nsm = (NSM::Client*)user_data;
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 ) ));
300 nsm->command_active( nsm->nsm_is_active );