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;
69 lo_server_thread_free (_st);
71 lo_server_free (_server);
76 Client::announce (const char *application_name, const char *capabilities, const char *process_name)
79 lo_address to = lo_address_new_from_url (nsm_url);
86 int pid = (int)getpid();
88 lo_send_from (to, _server, LO_TT_IMMEDIATE, "/nsm/server/announce", "sssiii",
92 1, /* api_major_version */
93 0, /* api_minor_version */
100 Client::progress (float p)
104 lo_send_from (nsm_addr, _server, LO_TT_IMMEDIATE, "/nsm/client/progress", "f", p);
109 Client::is_dirty (void)
113 lo_send_from (nsm_addr, _server, LO_TT_IMMEDIATE, "/nsm/client/is_dirty", "");
118 Client::is_clean (void)
122 lo_send_from (nsm_addr, _server, LO_TT_IMMEDIATE, "/nsm/client/is_clean", "");
127 Client::message (int priority, const char *msg)
131 lo_send_from (nsm_addr, _server, LO_TT_IMMEDIATE, "/nsm/client/message", "is", priority, msg);
137 Client::broadcast (lo_message msg)
141 lo_send_message_from (nsm_addr, _server, "/nsm/server/broadcast", msg);
146 Client::check (int timeout)
148 if (lo_server_wait (_server, timeout)) {
149 while (lo_server_recv_noblock (_server, 0));
156 lo_server_thread_start (_st);
162 lo_server_thread_stop (_st);
166 Client::init (const char *nsm_url)
168 this->nsm_url = nsm_url;
170 lo_address addr = lo_address_new_from_url (nsm_url);
171 int proto = lo_address_get_protocol (addr);
172 lo_address_free (addr);
174 _server = lo_server_new_with_proto (NULL, proto, NULL);
180 lo_server_add_method (_server, "/error", "sis", &Client::osc_error, this);
181 lo_server_add_method (_server, "/reply", "ssss", &Client::osc_announce_reply, this);
182 lo_server_add_method (_server, "/nsm/client/open", "sss", &Client::osc_open, this);
183 lo_server_add_method (_server, "/nsm/client/save", "", &Client::osc_save, this);
184 lo_server_add_method (_server, "/nsm/client/session_is_loaded", "", &Client::osc_session_is_loaded, this);
185 lo_server_add_method (_server, NULL, NULL, &Client::osc_broadcast, this);
191 Client::init_thread (const char *nsm_url)
193 this->nsm_url = nsm_url;
195 lo_address addr = lo_address_new_from_url (nsm_url);
196 int proto = lo_address_get_protocol (addr);
197 lo_address_free (addr);
199 _st = lo_server_thread_new_with_proto (NULL, proto, NULL);
200 _server = lo_server_thread_get_server (_st);
202 if (! _server || ! _st) {
206 lo_server_thread_add_method (_st, "/error", "sis", &Client::osc_error, this);
207 lo_server_thread_add_method (_st, "/reply", "ssss", &Client::osc_announce_reply, this);
208 lo_server_thread_add_method (_st, "/nsm/client/open", "sss", &Client::osc_open, this);
209 lo_server_thread_add_method (_st, "/nsm/client/save", "", &Client::osc_save, this);
210 lo_server_thread_add_method (_st, "/nsm/client/session_is_loaded", "", &Client::osc_session_is_loaded, this);
211 lo_server_thread_add_method (_st, NULL, NULL, &Client::osc_broadcast, this);
216 /************************/
217 /* OSC Message Handlers */
218 /************************/
221 Client::osc_broadcast (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data)
223 return ((NSM::Client*)user_data)->command_broadcast (path, msg);
227 Client::osc_save (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data)
229 char *out_msg = NULL;
231 int r = ((NSM::Client*)user_data)->command_save(&out_msg);
234 OSC_REPLY_ERR (r, (out_msg ? out_msg : ""));
247 Client::osc_open (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data)
249 char *out_msg = NULL;
251 NSM::Client *nsm = (NSM::Client*)user_data;
253 nsm->_nsm_client_id = strdup (&argv[2]->s);
254 nsm->_nsm_client_path = strdup (&argv[0]->s);
256 int r = ((NSM::Client*)user_data)->command_open (&argv[0]->s, &argv[1]->s, &argv[2]->s, &out_msg);
259 OSC_REPLY_ERR (r, (out_msg ? out_msg : ""));
272 Client::osc_session_is_loaded (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data)
274 NSM::Client *nsm = (NSM::Client*)user_data;
276 nsm->command_session_is_loaded();
282 Client::osc_error (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data)
284 if (strcmp (&argv[0]->s, "/nsm/server/announce")) {
288 NSM::Client *nsm = (NSM::Client*)user_data;
291 nsm->nsm_is_active = false;
293 nsm->command_active (nsm->nsm_is_active);
299 Client::osc_announce_reply (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data)
301 if (strcmp (&argv[0]->s, "/nsm/server/announce")) {
305 NSM::Client *nsm = (NSM::Client*)user_data;
307 nsm->nsm_is_active = true;
308 nsm->_session_manager_name = strdup (&argv[2]->s);
309 nsm->nsm_addr = lo_address_new_from_url (lo_address_get_url (lo_message_get_source (msg)));
311 nsm->command_active (nsm->nsm_is_active);