hydrogen 1.2.6
Nsm.h
Go to the documentation of this file.
1
2/*************************************************************************/
3/* Copyright (C) 2012 Jonathan Moore Liles */
4/* */
5/* Permission to use, copy, modify, and/or distribute this software for */
6/* any purpose with or without fee is hereby granted, provided that the */
7/* above copyright notice and this permission notice appear in all */
8/* copies. */
9/* */
10/* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL */
11/* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED */
12/* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE */
13/* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL */
14/* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR */
15/* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER */
16/* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR */
17/* PERFORMANCE OF THIS SOFTWARE. */
18/*************************************************************************/
19
20
21/*************************************************************/
22/* A simple, callback based C API for NSM clients. */
23/* */
24/* Simplified Example: */
25/* */
26/* #include "nsm.h" */
27/* */
28/* int */
29/* cb_nsm_open ( const char *name, */
30/* const char *display_name, */
31/* const char *client_id, */
32/* char **out_msg, */
33/* void *userdata ) */
34/* { */
35/* do_open_stuff(); */
36/* return ERR_OK; */
37/* } */
38/* */
39/* int */
40/* cb_nsm_save ( char **out_msg, */
41/* void *userdata ) */
42/* { */
43/* do_save_stuff(); */
44/* return ERR_OK; */
45/* } */
46/* */
47/* static nsm_client_t *nsm = 0 */
48/* */
49/* int main( int argc, char **argv ) */
50/* { */
51/* const char *nsm_url = getenv( "NSM_URL" ); */
52/* */
53/* if ( nsm_url ) */
54/* { */
55/* nsm = nsm_new(); */
56/* */
57/* nsm_set_open_callback( nsm, cb_nsm_open, 0 ); */
58/* nsm_set_save_callback( nsm, cb_nsm_save, 0 ); */
59/* */
60/* if ( 0 == nsm_init( nsm, nsm_url ) ) */
61/* { */
62/* nsm_send_announce( nsm, "FOO", "", argv[0] ); */
63/* } */
64/* else */
65/* { */
66/* nsm_free( nsm ); */
67/* nsm = 0; */
68/* } */
69/* } */
70/* } */
71/*************************************************************/
72
73#ifndef _NSM_H
74#define _NSM_H
75
76#define NSM_API_VERSION_MAJOR 1
77#define NSM_API_VERSION_MINOR 0
78
79#include <lo/lo.h>
80#include <string.h>
81#include <sys/types.h>
82#include <unistd.h>
83#include <stdlib.h>
84#include <stdio.h>
85
86typedef void * nsm_client_t;
87typedef int (nsm_open_callback)( const char *name, const char *display_name, const char *client_id, char **out_msg, void *userdata );
88typedef int (nsm_save_callback)( char **out_msg, void *userdata );
89typedef void (nsm_active_callback)( int b, void *userdata );
90typedef void (nsm_session_is_loaded_callback)( void *userdata );
91typedef int (nsm_broadcast_callback)( const char *, lo_message m, void *userdata );
92
93#define _NSM() ((struct _nsm_client_t*)nsm)
94
95#define NSM_EXPORT __attribute__((unused)) static
96
97/* private parts */
125
126enum
127{
137};
138
140int
142{
143 return _NSM()->nsm_is_active;
144}
145
147const char *
149{
150 return _NSM()->_session_manager_name;
151}
152
155nsm_new ( void )
156{
157 struct _nsm_client_t *nsm = (struct _nsm_client_t*)malloc( sizeof( struct _nsm_client_t ) );
158
159 nsm->nsm_url = 0;
160
161 nsm->nsm_is_active = 0;
162 nsm->nsm_client_id = 0;
163
164 nsm->_server = 0;
165 nsm->_st = 0;
166 nsm->nsm_addr = 0;
167 nsm->_session_manager_name = 0;
168
169 nsm->open = 0;
170 nsm->save = 0;
171 nsm->active = 0;
172 nsm->session_is_loaded = 0;
173 nsm->broadcast = 0;
174
175 return (nsm_client_t *)nsm;
176}
177
178/*******************************************/
179/* CLIENT TO SERVER INFORMATIONAL MESSAGES */
180/*******************************************/
181
183void
185{
186 if ( _NSM()->nsm_is_active )
187 lo_send_from( _NSM()->nsm_addr, _NSM()->_server, LO_TT_IMMEDIATE, "/nsm/client/is_dirty", "" );
188}
189
191void
193{
194 if ( _NSM()->nsm_is_active )
195 lo_send_from( _NSM()->nsm_addr, _NSM()->_server, LO_TT_IMMEDIATE, "/nsm/client/is_clean", "" );
196}
197
199void
201{
202 if ( _NSM()->nsm_is_active )
203 lo_send_from( _NSM()->nsm_addr, _NSM()->_server, LO_TT_IMMEDIATE, "/nsm/client/progress", "f", p );
204}
205
207void
208nsm_send_message ( nsm_client_t *nsm, int priority, const char *msg )
209{
210 if ( _NSM()->nsm_is_active )
211 lo_send_from( _NSM()->nsm_addr, _NSM()->_server, LO_TT_IMMEDIATE, "/nsm/client/message", "is", priority, msg );
212}
213
214NSM_EXPORT void
215nsm_send_announce ( nsm_client_t *nsm, const char *app_name, const char *capabilities, const char *process_name )
216{
217 lo_address to = lo_address_new_from_url( _NSM()->nsm_url );
218
219 if ( ! to )
220 {
221 fprintf( stderr, "NSM: Bad address!" );
222 return;
223 }
224
225 int pid = (int)getpid();
226
227 lo_send_from( to, _NSM()->_server, LO_TT_IMMEDIATE, "/nsm/server/announce", "sssiii",
228 app_name,
229 capabilities,
230 process_name,
233 pid );
234
235 lo_address_free( to );
236}
237
238NSM_EXPORT void
239nsm_send_broadcast ( nsm_client_t *nsm, lo_message msg )
240{
241 if ( _NSM()->nsm_is_active )
242 lo_send_message_from( _NSM()->nsm_addr, _NSM()->_server, "/nsm/server/broadcast", msg );
243}
244
245
246
248void
249nsm_check_wait ( nsm_client_t *nsm, int timeout )
250{
251 if ( lo_server_wait( _NSM()->_server, timeout ) )
252 while ( lo_server_recv_noblock( _NSM()->_server, 0 ) ) {}
253}
254
256void
258{
259 nsm_check_wait( nsm, 0 );
260}
261
262
264void
266{
267 lo_server_thread_start( _NSM()->_st );
268}
269
270
272void
274{
275 lo_server_thread_stop( _NSM()->_st );
276}
277
278
279
280NSM_EXPORT void
282{
283 if ( _NSM()->_st )
284 nsm_thread_stop( nsm );
285
286 if ( _NSM()->_st )
287 lo_server_thread_free( _NSM()->_st );
288 else
289 lo_server_free( _NSM()->_server );
290
291 free( _NSM() );
292}
293
294/*****************/
295/* SET CALLBACKS */
296/*****************/
297
299void
300nsm_set_open_callback( nsm_client_t *nsm, nsm_open_callback *open_callback, void *userdata )
301{
302 _NSM()->open = open_callback;
303 _NSM()->open_userdata = userdata;
304}
305
307void
308nsm_set_save_callback( nsm_client_t *nsm, nsm_save_callback *save_callback, void *userdata )
309{
310 _NSM()->save = save_callback;
311 _NSM()->save_userdata = userdata;
312}
313
315void
316nsm_set_active_callback( nsm_client_t *nsm, nsm_active_callback *active_callback, void *userdata )
317{
318 _NSM()->active = active_callback;
319 _NSM()->active_userdata = userdata;
320}
321
323void
324nsm_set_session_is_loaded_callback( nsm_client_t *nsm, nsm_session_is_loaded_callback *session_is_loaded_callback, void *userdata )
325{
326 _NSM()->session_is_loaded = session_is_loaded_callback;
327 _NSM()->session_is_loaded_userdata = userdata;
328}
329
330
332void
333nsm_set_broadcast_callback( nsm_client_t *nsm, nsm_broadcast_callback *broadcast_callback, void *userdata )
334{
335 _NSM()->broadcast = broadcast_callback;
336 _NSM()->broadcast_userdata = userdata;
337}
338
339
340
341/****************/
342/* OSC HANDLERS */
343/****************/
344
345#undef OSC_REPLY
346#undef OSC_REPLY_ERR
347
348#define OSC_REPLY( value ) lo_send_from( ((struct _nsm_client_t*)user_data)->nsm_addr, ((struct _nsm_client_t*)user_data)->_server, LO_TT_IMMEDIATE, "/reply", "ss", path, value )
349#define OSC_REPLY_P( path, value ) lo_send_from( ((struct _nsm_client_t*)user_data)->nsm_addr, ((struct _nsm_client_t*)user_data)->_server, LO_TT_IMMEDIATE, "/reply", "ss", path, value )
350
351#define OSC_REPLY_ERR( errcode, value ) lo_send_from( ((struct _nsm_client_t*)user_data)->nsm_addr, ((struct _nsm_client_t*)user_data)->_server, LO_TT_IMMEDIATE, "/error", "sis", path, errcode, value )
352
353
354NSM_EXPORT int _nsm_osc_open ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
355{
356 (void) types;
357 (void) argc;
358 (void) msg;
359
360 char *out_msg = NULL;
361
362 struct _nsm_client_t *nsm = (struct _nsm_client_t*)user_data;
363
364 nsm->nsm_client_id = strdup( &argv[2]->s );
365
366 if ( ! nsm->open )
367 return 0;
368
369 int r = nsm->open( &argv[0]->s, &argv[1]->s, &argv[2]->s, &out_msg, nsm->open_userdata );
370
371 if ( r )
372 OSC_REPLY_ERR( r, ( out_msg ? out_msg : "") );
373 else
374 OSC_REPLY( "OK" );
375
376 if ( out_msg )
377 free( out_msg );
378
379 return 0;
380}
381
382NSM_EXPORT int _nsm_osc_save ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
383{
384 (void) types;
385 (void) argv;
386 (void) argc;
387 (void) msg;
388
389 char *out_msg = NULL;
390
391 struct _nsm_client_t *nsm = (struct _nsm_client_t*)user_data;
392
393 if ( ! nsm->save )
394 return 0;
395
396 int r = nsm->save(&out_msg, nsm->save_userdata );
397
398 if ( r )
399 {
400 OSC_REPLY_ERR( r, ( out_msg ? out_msg : "") );
401 }
402 else
403 {
404 OSC_REPLY( "OK" );
405 }
406 if ( out_msg )
407 free( out_msg );
408
409 return 0;
410}
411
412NSM_EXPORT int _nsm_osc_announce_reply ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
413{
414 (void) path;
415 (void) types;
416 (void) argc;
417
418 if ( strcmp( &argv[0]->s, "/nsm/server/announce" ) )
419 return -1;
420
421 struct _nsm_client_t *nsm = (struct _nsm_client_t*)user_data;
422
423 fprintf( stderr, "NSM: Successfully registered. NSM says: %s", &argv[1]->s );
424
425 nsm->nsm_is_active = 1;
426 nsm->_session_manager_name = strdup( &argv[2]->s );
427 nsm->nsm_addr = lo_address_new_from_url( lo_address_get_url( lo_message_get_source( msg ) ));
428
429 if ( nsm->active )
430 nsm->active( nsm->nsm_is_active, nsm->active_userdata );
431
432 return 0;
433}
434
435NSM_EXPORT int _nsm_osc_error ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
436{
437 (void) path;
438 (void) types;
439 (void) argc;
440 (void) msg;
441
442 if ( strcmp( &argv[0]->s, "/nsm/server/announce" ) )
443 return -1;
444
445 struct _nsm_client_t *nsm = (struct _nsm_client_t*)user_data;
446
447 fprintf( stderr, "NSM: Failed to register with NSM server: %s", &argv[2]->s );
448
449 nsm->nsm_is_active = 0;
450
451 if ( nsm->active )
452 nsm->active( nsm->nsm_is_active, nsm->active_userdata );
453
454 return 0;
455}
456
457NSM_EXPORT int _nsm_osc_session_is_loaded ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
458{
459 (void) path;
460 (void) types;
461 (void) argv;
462 (void) argc;
463 (void) msg;
464
465 struct _nsm_client_t *nsm = (struct _nsm_client_t*)user_data;
466
467 if ( ! nsm->session_is_loaded )
468 return 0;
469
471
472 return 0;
473}
474
475NSM_EXPORT int _nsm_osc_broadcast ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
476{
477 (void) types;
478 (void) argv;
479 (void) argc;
480
481 struct _nsm_client_t *nsm = (struct _nsm_client_t*)user_data;
482
483 if ( ! nsm->broadcast )
484 return 0;
485
486 return nsm->broadcast( path, msg, nsm->broadcast_userdata );
487}
488
489
490
492int
493nsm_init ( nsm_client_t *nsm, const char *nsm_url )
494{
495 _NSM()->nsm_url = nsm_url;
496
497 lo_address addr = lo_address_new_from_url( nsm_url );
498 int proto = lo_address_get_protocol( addr );
499 lo_address_free( addr );
500
501 _NSM()->_server = lo_server_new_with_proto( NULL, proto, NULL );
502
503 if ( ! _NSM()->_server )
504 return -1;
505
506 lo_server_add_method( _NSM()->_server, "/error", "sis", _nsm_osc_error, _NSM() );
507 lo_server_add_method( _NSM()->_server, "/reply", "ssss", _nsm_osc_announce_reply, _NSM() );
508 lo_server_add_method( _NSM()->_server, "/nsm/client/open", "sss", _nsm_osc_open, _NSM() );
509 lo_server_add_method( _NSM()->_server, "/nsm/client/save", "", _nsm_osc_save, _NSM() );
510 lo_server_add_method( _NSM()->_server, "/nsm/client/session_is_loaded", "", _nsm_osc_session_is_loaded, _NSM() );
511 lo_server_add_method( _NSM()->_server, NULL, NULL, _nsm_osc_broadcast, _NSM() );
512
513 return 0;
514}
515
516
518int
520{
521 _NSM()->nsm_url = nsm_url;
522
523 lo_address addr = lo_address_new_from_url( nsm_url );
524 int proto = lo_address_get_protocol( addr );
525 lo_address_free( addr );
526
527 _NSM()->_st = lo_server_thread_new_with_proto( NULL, proto, NULL );
528 _NSM()->_server = lo_server_thread_get_server( _NSM()->_st );
529
530 if ( ! _NSM()->_server )
531 return -1;
532
533 lo_server_thread_add_method( _NSM()->_st, "/error", "sis", _nsm_osc_error, _NSM() );
534 lo_server_thread_add_method( _NSM()->_st, "/reply", "ssss", _nsm_osc_announce_reply, _NSM() );
535 lo_server_thread_add_method( _NSM()->_st, "/nsm/client/open", "sss", _nsm_osc_open, _NSM() );
536 lo_server_thread_add_method( _NSM()->_st, "/nsm/client/save", "", _nsm_osc_save, _NSM() );
537 lo_server_thread_add_method( _NSM()->_st, "/nsm/client/session_is_loaded", "", _nsm_osc_session_is_loaded, _NSM() );
538 lo_server_thread_add_method( _NSM()->_st, NULL, NULL, _nsm_osc_broadcast, _NSM() );
539
540 return 0;
541}
542
543#endif /* NSM_H */
NSM_EXPORT int _nsm_osc_announce_reply(const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data)
Definition Nsm.h:412
NSM_EXPORT const char * nsm_get_session_manager_name(nsm_client_t *nsm)
Definition Nsm.h:148
NSM_EXPORT nsm_client_t * nsm_new(void)
Definition Nsm.h:155
NSM_EXPORT void nsm_send_message(nsm_client_t *nsm, int priority, const char *msg)
Definition Nsm.h:208
#define NSM_API_VERSION_MINOR
Definition Nsm.h:77
#define OSC_REPLY_ERR(errcode, value)
Definition Nsm.h:351
NSM_EXPORT void nsm_thread_stop(nsm_client_t *nsm)
Definition Nsm.h:273
NSM_EXPORT int _nsm_osc_broadcast(const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data)
Definition Nsm.h:475
NSM_EXPORT void nsm_thread_start(nsm_client_t *nsm)
Definition Nsm.h:265
int nsm_broadcast_callback(const char *, lo_message m, void *userdata)
Definition Nsm.h:91
NSM_EXPORT void nsm_check_wait(nsm_client_t *nsm, int timeout)
Definition Nsm.h:249
NSM_EXPORT void nsm_set_broadcast_callback(nsm_client_t *nsm, nsm_broadcast_callback *broadcast_callback, void *userdata)
Definition Nsm.h:333
NSM_EXPORT int _nsm_osc_session_is_loaded(const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data)
Definition Nsm.h:457
#define OSC_REPLY(value)
Definition Nsm.h:348
void nsm_session_is_loaded_callback(void *userdata)
Definition Nsm.h:90
NSM_EXPORT void nsm_set_save_callback(nsm_client_t *nsm, nsm_save_callback *save_callback, void *userdata)
Definition Nsm.h:308
NSM_EXPORT int nsm_init(nsm_client_t *nsm, const char *nsm_url)
Definition Nsm.h:493
int nsm_save_callback(char **out_msg, void *userdata)
Definition Nsm.h:88
NSM_EXPORT void nsm_send_broadcast(nsm_client_t *nsm, lo_message msg)
Definition Nsm.h:239
NSM_EXPORT int _nsm_osc_open(const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data)
Definition Nsm.h:354
NSM_EXPORT void nsm_set_session_is_loaded_callback(nsm_client_t *nsm, nsm_session_is_loaded_callback *session_is_loaded_callback, void *userdata)
Definition Nsm.h:324
NSM_EXPORT void nsm_set_active_callback(nsm_client_t *nsm, nsm_active_callback *active_callback, void *userdata)
Definition Nsm.h:316
NSM_EXPORT void nsm_send_progress(nsm_client_t *nsm, float p)
Definition Nsm.h:200
#define NSM_EXPORT
Definition Nsm.h:95
#define _NSM()
Definition Nsm.h:93
void * nsm_client_t
Definition Nsm.h:86
int nsm_open_callback(const char *name, const char *display_name, const char *client_id, char **out_msg, void *userdata)
Definition Nsm.h:87
NSM_EXPORT int nsm_init_thread(nsm_client_t *nsm, const char *nsm_url)
Definition Nsm.h:519
NSM_EXPORT void nsm_send_is_clean(nsm_client_t *nsm)
Definition Nsm.h:192
NSM_EXPORT void nsm_check_nowait(nsm_client_t *nsm)
Definition Nsm.h:257
NSM_EXPORT int _nsm_osc_save(const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data)
Definition Nsm.h:382
void nsm_active_callback(int b, void *userdata)
Definition Nsm.h:89
NSM_EXPORT void nsm_send_announce(nsm_client_t *nsm, const char *app_name, const char *capabilities, const char *process_name)
Definition Nsm.h:215
NSM_EXPORT void nsm_set_open_callback(nsm_client_t *nsm, nsm_open_callback *open_callback, void *userdata)
Definition Nsm.h:300
@ ERR_UNSAVED_CHANGES
Definition Nsm.h:135
@ ERR_NO_SESSION_OPEN
Definition Nsm.h:134
@ ERR_BLACKLISTED
Definition Nsm.h:131
@ ERR_OK
Definition Nsm.h:128
@ ERR_NO_SUCH_FILE
Definition Nsm.h:133
@ ERR_NOT_NOW
Definition Nsm.h:136
@ ERR_LAUNCH_FAILED
Definition Nsm.h:132
@ ERR_INCOMPATIBLE_API
Definition Nsm.h:130
@ ERR_GENERAL
Definition Nsm.h:129
NSM_EXPORT int nsm_is_active(nsm_client_t *nsm)
Definition Nsm.h:141
NSM_EXPORT int _nsm_osc_error(const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data)
Definition Nsm.h:435
#define NSM_API_VERSION_MAJOR
Definition Nsm.h:76
NSM_EXPORT void nsm_send_is_dirty(nsm_client_t *nsm)
Definition Nsm.h:184
NSM_EXPORT void nsm_free(nsm_client_t *nsm)
Definition Nsm.h:281
void * session_is_loaded_userdata
Definition Nsm.h:120
void * save_userdata
Definition Nsm.h:114
lo_server _server
Definition Nsm.h:102
void * broadcast_userdata
Definition Nsm.h:123
char * nsm_client_id
Definition Nsm.h:107
lo_server_thread _st
Definition Nsm.h:103
void * active_userdata
Definition Nsm.h:117
const char * nsm_url
Definition Nsm.h:100
nsm_broadcast_callback * broadcast
Definition Nsm.h:122
nsm_active_callback * active
Definition Nsm.h:116
int nsm_is_active
Definition Nsm.h:106
lo_address nsm_addr
Definition Nsm.h:104
char * _session_manager_name
Definition Nsm.h:108
nsm_open_callback * open
Definition Nsm.h:110
nsm_session_is_loaded_callback * session_is_loaded
Definition Nsm.h:119
nsm_save_callback * save
Definition Nsm.h:113
void * open_userdata
Definition Nsm.h:111