Client.C (12216B)
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 18 /*******************************************************************************/ 19 20 #include "Client.H" 21 #include <string.h> 22 #include <sys/types.h> 23 #include <unistd.h> 24 #include <stdlib.h> 25 26 #pragma GCC diagnostic ignored "-Wunused-parameter" 27 28 namespace NSM 29 { 30 /************************/ 31 /* OSC Message Handlers */ 32 /************************/ 33 34 #undef OSC_REPLY 35 #undef OSC_REPLY_ERR 36 37 #define OSC_REPLY(value) lo_send_from(((NSM::Client *)user_data)->nsm_addr, \ 38 ((NSM::Client *)user_data)->_server, \ 39 LO_TT_IMMEDIATE, \ 40 "/reply", \ 41 "ss", \ 42 path, \ 43 value) 44 45 #define OSC_REPLY_ERR(errcode, value) lo_send_from( \ 46 ((NSM::Client *)user_data)->nsm_addr, \ 47 ((NSM::Client *)user_data)->_server, \ 48 LO_TT_IMMEDIATE, \ 49 "/error", \ 50 "sis", \ 51 path, \ 52 errcode, \ 53 value) 54 55 Client::Client() 56 { 57 nsm_addr = 0; 58 nsm_client_id = 0; 59 _session_manager_name = 0; 60 nsm_is_active = false; 61 _server = 0; 62 _st = 0; 63 } 64 65 Client::~Client() 66 { 67 if(_st) 68 stop(); 69 70 if(_st) 71 lo_server_thread_free(_st); 72 else 73 lo_server_free(_server); 74 } 75 76 void 77 Client::announce(const char *application_name, 78 const char *capabilities, 79 const char *process_name) 80 { 81 // MESSAGE( "Announcing to NSM" ); 82 83 lo_address to = lo_address_new_from_url(nsm_url); 84 85 if(!to) 86 // MESSAGE( "Bad address" ); 87 return; 88 89 int pid = (int)getpid(); 90 91 lo_send_from(to, 92 _server, 93 LO_TT_IMMEDIATE, 94 "/nsm/server/announce", 95 "sssiii", 96 application_name, 97 capabilities, 98 process_name, 99 1, 100 /* api_major_version */ 101 0, 102 /* api_minor_version */ 103 pid); 104 105 lo_address_free(to); 106 } 107 108 void 109 Client::progress(float p) 110 { 111 if(nsm_is_active) 112 lo_send_from(nsm_addr, 113 _server, 114 LO_TT_IMMEDIATE, 115 "/nsm/client/progress", 116 "f", 117 p); 118 } 119 120 void 121 Client::is_dirty(void) 122 { 123 if(nsm_is_active) 124 lo_send_from(nsm_addr, 125 _server, 126 LO_TT_IMMEDIATE, 127 "/nsm/client/is_dirty", 128 ""); 129 } 130 131 void 132 Client::is_clean(void) 133 { 134 if(nsm_is_active) 135 lo_send_from(nsm_addr, 136 _server, 137 LO_TT_IMMEDIATE, 138 "/nsm/client/is_clean", 139 ""); 140 } 141 142 void 143 Client::message(int priority, const char *msg) 144 { 145 if(nsm_is_active) 146 lo_send_from(nsm_addr, 147 _server, 148 LO_TT_IMMEDIATE, 149 "/nsm/client/message", 150 "is", 151 priority, 152 msg); 153 } 154 155 156 void 157 Client::broadcast(lo_message msg) 158 { 159 if(nsm_is_active) 160 lo_send_message_from(nsm_addr, 161 _server, 162 "/nsm/server/broadcast", 163 msg); 164 } 165 166 void 167 Client::check(int timeout) 168 { 169 if(lo_server_wait(_server, timeout)) 170 while(lo_server_recv_noblock(_server, 0)) {} 171 } 172 173 void 174 Client::start() 175 { 176 lo_server_thread_start(_st); 177 } 178 179 void 180 Client::stop() 181 { 182 lo_server_thread_stop(_st); 183 } 184 185 int 186 Client::init(const char *nsm_url) 187 { 188 this->nsm_url = nsm_url; 189 190 lo_address addr = lo_address_new_from_url(nsm_url); 191 int proto = lo_address_get_protocol(addr); 192 lo_address_free(addr); 193 194 _server = lo_server_new_with_proto(NULL, proto, NULL); 195 196 if(!_server) 197 return -1; 198 199 lo_server_add_method(_server, "/error", "sis", &Client::osc_error, this); 200 lo_server_add_method(_server, 201 "/reply", 202 "ssss", 203 &Client::osc_announce_reply, 204 this); 205 lo_server_add_method(_server, 206 "/nsm/client/open", 207 "sss", 208 &Client::osc_open, 209 this); 210 lo_server_add_method(_server, 211 "/nsm/client/save", 212 "", 213 &Client::osc_save, 214 this); 215 lo_server_add_method(_server, 216 "/nsm/client/session_is_loaded", 217 "", 218 &Client::osc_session_is_loaded, 219 this); 220 lo_server_add_method(_server, NULL, NULL, &Client::osc_broadcast, this); 221 222 return 0; 223 } 224 225 int 226 Client::init_thread(const char *nsm_url) 227 { 228 this->nsm_url = nsm_url; 229 230 lo_address addr = lo_address_new_from_url(nsm_url); 231 int proto = lo_address_get_protocol(addr); 232 lo_address_free(addr); 233 234 _st = lo_server_thread_new_with_proto(NULL, proto, NULL); 235 _server = lo_server_thread_get_server(_st); 236 237 if(!_server || !_st) 238 return -1; 239 240 lo_server_thread_add_method(_st, 241 "/error", 242 "sis", 243 &Client::osc_error, 244 this); 245 lo_server_thread_add_method(_st, 246 "/reply", 247 "ssss", 248 &Client::osc_announce_reply, 249 this); 250 lo_server_thread_add_method(_st, 251 "/nsm/client/open", 252 "sss", 253 &Client::osc_open, 254 this); 255 lo_server_thread_add_method(_st, 256 "/nsm/client/save", 257 "", 258 &Client::osc_save, 259 this); 260 lo_server_thread_add_method(_st, 261 "/nsm/client/session_is_loaded", 262 "", 263 &Client::osc_session_is_loaded, 264 this); 265 lo_server_thread_add_method(_st, 266 NULL, 267 NULL, 268 &Client::osc_broadcast, 269 this); 270 271 return 0; 272 } 273 274 /************************/ 275 /* OSC Message Handlers */ 276 /************************/ 277 278 int 279 Client::osc_broadcast(const char *path, 280 const char *types, 281 lo_arg **argv, 282 int argc, 283 lo_message msg, 284 void *user_data) 285 { 286 return ((NSM::Client *)user_data)->command_broadcast(path, msg); 287 } 288 289 int 290 Client::osc_save(const char *path, 291 const char *types, 292 lo_arg **argv, 293 int argc, 294 lo_message msg, 295 void *user_data) 296 { 297 char *out_msg = NULL; 298 299 int r = ((NSM::Client *)user_data)->command_save(&out_msg); 300 301 if(r) 302 OSC_REPLY_ERR(r, (out_msg ? out_msg : "")); 303 else 304 OSC_REPLY("OK"); 305 306 if(out_msg) 307 free(out_msg); 308 309 return 0; 310 } 311 312 int 313 Client::osc_open(const char *path, 314 const char *types, 315 lo_arg **argv, 316 int argc, 317 lo_message msg, 318 void *user_data) 319 { 320 char *out_msg = NULL; 321 322 NSM::Client *nsm = (NSM::Client *)user_data; 323 324 nsm->nsm_client_id = strdup(&argv[2]->s); 325 326 int r = ((NSM::Client *)user_data)->command_open(&argv[0]->s, 327 &argv[1]->s, 328 &argv[2]->s, 329 &out_msg); 330 331 if(r) 332 OSC_REPLY_ERR(r, (out_msg ? out_msg : "")); 333 else 334 OSC_REPLY("OK"); 335 336 if(out_msg) 337 free(out_msg); 338 339 return 0; 340 } 341 342 int 343 Client::osc_session_is_loaded(const char *path, 344 const char *types, 345 lo_arg **argv, 346 int argc, 347 lo_message msg, 348 void *user_data) 349 { 350 NSM::Client *nsm = (NSM::Client *)user_data; 351 352 nsm->command_session_is_loaded(); 353 354 return 0; 355 } 356 357 int 358 Client::osc_error(const char *path, 359 const char *types, 360 lo_arg **argv, 361 int argc, 362 lo_message msg, 363 void *user_data) 364 { 365 if(strcmp(&argv[0]->s, "/nsm/server/announce")) 366 return -1; 367 368 NSM::Client *nsm = (NSM::Client *)user_data; 369 370 371 // WARNING( "Failed to register with NSM: %s", &argv[2]->s ); 372 nsm->nsm_is_active = false; 373 374 nsm->command_active(nsm->nsm_is_active); 375 376 return 0; 377 } 378 379 int 380 Client::osc_announce_reply(const char *path, 381 const char *types, 382 lo_arg **argv, 383 int argc, 384 lo_message msg, 385 void *user_data) 386 { 387 if(strcmp(&argv[0]->s, "/nsm/server/announce")) 388 return -1; 389 390 NSM::Client *nsm = (NSM::Client *)user_data; 391 392 // MESSAGE( "Successfully registered. NSM says: %s", &argv[1]->s ); 393 nsm->nsm_is_active = true; 394 nsm->_session_manager_name = strdup(&argv[2]->s); 395 nsm->nsm_addr = 396 lo_address_new_from_url(lo_address_get_url(lo_message_get_source( 397 msg))); 398 399 nsm->command_active(nsm->nsm_is_active); 400 401 return 0; 402 } 403 };