Assists music production by grouping standalone programs into sessions. Community version of "Non Session Manager".
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

265 lines
7.7KB

  1. /*******************************************************************************/
  2. /* Copyright (C) 2012 Jonathan Moore Liles */
  3. /* */
  4. /* This program is free software; you can redistribute it and/or modify it */
  5. /* under the terms of the GNU General Public License as published by the */
  6. /* Free Software Foundation; either version 2 of the License, or (at your */
  7. /* option) any later version. */
  8. /* */
  9. /* This program is distributed in the hope that it will be useful, but WITHOUT */
  10. /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
  11. /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */
  12. /* more details. */
  13. /* */
  14. /* You should have received a copy of the GNU General Public License along */
  15. /* with This program; see the file COPYING. If not,write to the Free Software */
  16. /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  17. /*******************************************************************************/
  18. #include "../debug.h"
  19. #include "Client.H"
  20. #include <string.h>
  21. #include <sys/types.h>
  22. #include <unistd.h>
  23. #include <stdlib.h>
  24. namespace NSM
  25. {
  26. /************************/
  27. /* OSC Message Handlers */
  28. /************************/
  29. #undef OSC_REPLY
  30. #undef OSC_REPLY_ERR
  31. #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 )
  32. #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 )
  33. Client::Client ( )
  34. {
  35. nsm_addr = 0;
  36. nsm_client_id = 0;
  37. _session_manager_name = 0;
  38. nsm_is_active = false;
  39. _server = 0;
  40. _st = 0;
  41. }
  42. Client::~Client ( )
  43. {
  44. if ( _st )
  45. stop();
  46. if ( _st )
  47. lo_server_thread_free( _st );
  48. else
  49. lo_server_free ( _server );
  50. }
  51. void
  52. Client::announce ( const char *nash_url, const char *application_name, const char *capabilities, const char *process_name )
  53. {
  54. MESSAGE( "Announcing to NSM" );
  55. lo_address to = lo_address_new_from_url( nash_url );
  56. if ( ! to )
  57. {
  58. MESSAGE( "Bad address" );
  59. return;
  60. }
  61. int pid = (int)getpid();
  62. lo_send_from( to, _server, LO_TT_IMMEDIATE, "/nsm/server/announce", "sssiii",
  63. application_name,
  64. capabilities,
  65. process_name,
  66. 0, /* api_major_version */
  67. 5, /* api_minor_version */
  68. pid );
  69. lo_address_free( to );
  70. }
  71. void
  72. Client::progress ( float p )
  73. {
  74. if ( nsm_is_active )
  75. {
  76. lo_send_from( nsm_addr, _server, LO_TT_IMMEDIATE, "/nsm/client/progress", "f", p );
  77. }
  78. }
  79. void
  80. Client::is_dirty ( void )
  81. {
  82. if ( nsm_is_active )
  83. {
  84. lo_send_from( nsm_addr, _server, LO_TT_IMMEDIATE, "/nsm/client/is_dirty", "" );
  85. }
  86. }
  87. void
  88. Client::is_clean ( void )
  89. {
  90. if ( nsm_is_active )
  91. {
  92. lo_send_from( nsm_addr, _server, LO_TT_IMMEDIATE, "/nsm/client/is_clean", "" );
  93. }
  94. }
  95. void
  96. Client::message ( int priority, const char *msg )
  97. {
  98. if ( nsm_is_active )
  99. {
  100. lo_send_from( nsm_addr, _server, LO_TT_IMMEDIATE, "/nsm/client/message", "is", priority, msg );
  101. }
  102. }
  103. void
  104. Client::check ( )
  105. {
  106. lo_server_recv_noblock( _server, 0 );
  107. }
  108. void
  109. Client::start ( )
  110. {
  111. lo_server_thread_start( _st );
  112. }
  113. void
  114. Client::stop ( )
  115. {
  116. lo_server_thread_stop( _st );
  117. }
  118. int
  119. Client::init ( )
  120. {
  121. _server = lo_server_new( NULL, NULL );
  122. if ( ! _server )
  123. return -1;
  124. lo_server_add_method( _server, "/error", "sis", &Client::osc_error, this );
  125. lo_server_add_method( _server, "/reply", "ssss", &Client::osc_announce_reply, this );
  126. lo_server_add_method( _server, "/nsm/client/open", "sss", &Client::osc_open, this );
  127. lo_server_add_method( _server, "/nsm/client/save", "", &Client::osc_save, this );
  128. return 0;
  129. }
  130. int
  131. Client::init_thread ( )
  132. {
  133. _st = lo_server_thread_new( NULL, NULL );
  134. _server = lo_server_thread_get_server( _st );
  135. if ( ! _server || ! _st )
  136. return -1;
  137. lo_server_thread_add_method( _st, "/error", "sis", &Client::osc_error, this );
  138. lo_server_thread_add_method( _st, "/reply", "ssss", &Client::osc_announce_reply, this );
  139. lo_server_thread_add_method( _st, "/nsm/client/open", "sss", &Client::osc_open, this );
  140. lo_server_thread_add_method( _st, "/nsm/client/save", "", &Client::osc_save, this );
  141. return 0;
  142. }
  143. /************************/
  144. /* OSC Message Handlers */
  145. /************************/
  146. int
  147. Client::osc_save ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  148. {
  149. char *out_msg = NULL;
  150. int r = ((NSM::Client*)user_data)->command_save(&out_msg);
  151. if ( r )
  152. OSC_REPLY_ERR( r, ( out_msg ? out_msg : "") );
  153. else
  154. OSC_REPLY( "OK" );
  155. if ( out_msg )
  156. free( out_msg );
  157. return 0;
  158. }
  159. int
  160. Client::osc_open ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  161. {
  162. char *out_msg = NULL;
  163. NSM::Client *nsm = (NSM::Client*)user_data;
  164. nsm->nsm_client_id = strdup( &argv[2]->s );
  165. int r = ((NSM::Client*)user_data)->command_open( &argv[0]->s, &argv[1]->s, &argv[2]->s, &out_msg);
  166. if ( r )
  167. OSC_REPLY_ERR( r, ( out_msg ? out_msg : "") );
  168. else
  169. OSC_REPLY( "OK" );
  170. if ( out_msg )
  171. free( out_msg );
  172. return 0;
  173. }
  174. int
  175. Client::osc_session_is_loaded ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  176. {
  177. NSM::Client *nsm = (NSM::Client*)user_data;
  178. nsm->command_session_is_loaded();
  179. return 0;
  180. }
  181. int
  182. Client::osc_error ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  183. {
  184. if ( strcmp( &argv[0]->s, "/nsm/server/announce" ) )
  185. return -1;
  186. NSM::Client *nsm = (NSM::Client*)user_data;
  187. WARNING( "Failed to register with NSM: %s", &argv[2]->s );
  188. nsm->nsm_is_active = false;
  189. nsm->command_active( nsm->nsm_is_active );
  190. return 0;
  191. }
  192. int
  193. Client::osc_announce_reply ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
  194. {
  195. if ( strcmp( &argv[0]->s, "/nsm/server/announce" ) )
  196. return -1;
  197. NSM::Client *nsm = (NSM::Client*)user_data;
  198. MESSAGE( "Successfully registered. NSM says: %s", &argv[1]->s );
  199. nsm->nsm_is_active = true;
  200. nsm->_session_manager_name = strdup( &argv[2]->s );
  201. nsm->nsm_addr = lo_address_new_from_url( lo_address_get_url( lo_message_get_source( msg ) ));
  202. nsm->command_active( nsm->nsm_is_active );
  203. return 0;
  204. }
  205. };