316 lines
8.1 KiB
C++
316 lines
8.1 KiB
C++
|
|
/*******************************************************************************/
|
|
/* Copyright (C) 2012 Jonathan Moore Liles */
|
|
/* */
|
|
/* This program is free software; you can redistribute it and/or modify it */
|
|
/* under the terms of the GNU General Public License as published by the */
|
|
/* Free Software Foundation; either version 2 of the License, or (at your */
|
|
/* option) any later version. */
|
|
/* */
|
|
/* This program is distributed in the hope that it will be useful, but WITHOUT */
|
|
/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
|
|
/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */
|
|
/* more details. */
|
|
/* */
|
|
/* You should have received a copy of the GNU General Public License along */
|
|
/* with This program; see the file COPYING. If not,write to the Free Software */
|
|
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
/*******************************************************************************/
|
|
|
|
#include "nsmclient.h"
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
|
|
#ifndef COMPILER_MSVC
|
|
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
|
#else
|
|
#include <process.h> // Needed for 'getpid()'
|
|
|
|
#include <lo/lo_osc_types.h>
|
|
#define LO_TT_IMMEDIATE lo_get_tt_immediate()
|
|
lo_timetag lo_get_tt_immediate() { lo_timetag tt = {0U,1U}; return tt; }
|
|
#endif
|
|
|
|
namespace NSM
|
|
{
|
|
|
|
/************************/
|
|
/* OSC Message Handlers */
|
|
/************************/
|
|
|
|
#undef OSC_REPLY
|
|
#undef OSC_REPLY_ERR
|
|
|
|
#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)
|
|
|
|
#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)
|
|
|
|
Client::Client ()
|
|
{
|
|
nsm_addr = 0;
|
|
_nsm_client_id = 0;
|
|
_nsm_client_path = 0;
|
|
_session_manager_name = 0;
|
|
nsm_url = "";
|
|
nsm_is_active = false;
|
|
_server = 0;
|
|
_st = 0;
|
|
}
|
|
|
|
Client::~Client ()
|
|
{
|
|
if (_st) {
|
|
stop();
|
|
}
|
|
|
|
if (_st) {
|
|
lo_server_thread_free (_st);
|
|
} else {
|
|
lo_server_free (_server);
|
|
}
|
|
}
|
|
|
|
void
|
|
Client::announce (const char *application_name, const char *capabilities, const char *process_name)
|
|
{
|
|
|
|
lo_address to = lo_address_new_from_url (nsm_url);
|
|
|
|
if (!to)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int pid = (int)getpid();
|
|
|
|
lo_send_from (to, _server, LO_TT_IMMEDIATE, "/nsm/server/announce", "sssiii",
|
|
application_name,
|
|
capabilities,
|
|
process_name,
|
|
1, /* api_major_version */
|
|
0, /* api_minor_version */
|
|
pid);
|
|
|
|
lo_address_free (to);
|
|
}
|
|
|
|
void
|
|
Client::progress (float p)
|
|
{
|
|
if (nsm_is_active)
|
|
{
|
|
lo_send_from (nsm_addr, _server, LO_TT_IMMEDIATE, "/nsm/client/progress", "f", p);
|
|
}
|
|
}
|
|
|
|
void
|
|
Client::is_dirty (void)
|
|
{
|
|
if (nsm_is_active)
|
|
{
|
|
lo_send_from (nsm_addr, _server, LO_TT_IMMEDIATE, "/nsm/client/is_dirty", "");
|
|
}
|
|
}
|
|
|
|
void
|
|
Client::is_clean (void)
|
|
{
|
|
if (nsm_is_active)
|
|
{
|
|
lo_send_from (nsm_addr, _server, LO_TT_IMMEDIATE, "/nsm/client/is_clean", "");
|
|
}
|
|
}
|
|
|
|
void
|
|
Client::message (int priority, const char *msg)
|
|
{
|
|
if (nsm_is_active)
|
|
{
|
|
lo_send_from (nsm_addr, _server, LO_TT_IMMEDIATE, "/nsm/client/message", "is", priority, msg);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
Client::broadcast (lo_message msg)
|
|
{
|
|
if (nsm_is_active)
|
|
{
|
|
lo_send_message_from (nsm_addr, _server, "/nsm/server/broadcast", msg);
|
|
}
|
|
}
|
|
|
|
void
|
|
Client::check (int timeout)
|
|
{
|
|
if (lo_server_wait (_server, timeout)) {
|
|
while (lo_server_recv_noblock (_server, 0));
|
|
}
|
|
}
|
|
|
|
void
|
|
Client::start ()
|
|
{
|
|
lo_server_thread_start (_st);
|
|
}
|
|
|
|
void
|
|
Client::stop ()
|
|
{
|
|
lo_server_thread_stop (_st);
|
|
}
|
|
|
|
int
|
|
Client::init (const char *nsm_url)
|
|
{
|
|
this->nsm_url = nsm_url;
|
|
|
|
lo_address addr = lo_address_new_from_url (nsm_url);
|
|
int proto = lo_address_get_protocol (addr);
|
|
lo_address_free (addr);
|
|
|
|
_server = lo_server_new_with_proto (NULL, proto, NULL);
|
|
|
|
if (!_server) {
|
|
return -1;
|
|
}
|
|
|
|
lo_server_add_method (_server, "/error", "sis", &Client::osc_error, this);
|
|
lo_server_add_method (_server, "/reply", "ssss", &Client::osc_announce_reply, this);
|
|
lo_server_add_method (_server, "/nsm/client/open", "sss", &Client::osc_open, this);
|
|
lo_server_add_method (_server, "/nsm/client/save", "", &Client::osc_save, this);
|
|
lo_server_add_method (_server, "/nsm/client/session_is_loaded", "", &Client::osc_session_is_loaded, this);
|
|
lo_server_add_method (_server, NULL, NULL, &Client::osc_broadcast, this);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
Client::init_thread (const char *nsm_url)
|
|
{
|
|
this->nsm_url = nsm_url;
|
|
|
|
lo_address addr = lo_address_new_from_url (nsm_url);
|
|
int proto = lo_address_get_protocol (addr);
|
|
lo_address_free (addr);
|
|
|
|
_st = lo_server_thread_new_with_proto (NULL, proto, NULL);
|
|
_server = lo_server_thread_get_server (_st);
|
|
|
|
if (! _server || ! _st) {
|
|
return -1;
|
|
}
|
|
|
|
lo_server_thread_add_method (_st, "/error", "sis", &Client::osc_error, this);
|
|
lo_server_thread_add_method (_st, "/reply", "ssss", &Client::osc_announce_reply, this);
|
|
lo_server_thread_add_method (_st, "/nsm/client/open", "sss", &Client::osc_open, this);
|
|
lo_server_thread_add_method (_st, "/nsm/client/save", "", &Client::osc_save, this);
|
|
lo_server_thread_add_method (_st, "/nsm/client/session_is_loaded", "", &Client::osc_session_is_loaded, this);
|
|
lo_server_thread_add_method (_st, NULL, NULL, &Client::osc_broadcast, this);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/************************/
|
|
/* OSC Message Handlers */
|
|
/************************/
|
|
|
|
int
|
|
Client::osc_broadcast (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data)
|
|
{
|
|
return ((NSM::Client*)user_data)->command_broadcast (path, msg);
|
|
}
|
|
|
|
int
|
|
Client::osc_save (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data)
|
|
{
|
|
char *out_msg = NULL;
|
|
|
|
int r = ((NSM::Client*)user_data)->command_save(&out_msg);
|
|
|
|
if (r) {
|
|
OSC_REPLY_ERR (r, (out_msg ? out_msg : ""));
|
|
} else {
|
|
OSC_REPLY ("OK");
|
|
}
|
|
|
|
if (out_msg) {
|
|
free (out_msg);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
Client::osc_open (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data)
|
|
{
|
|
char *out_msg = NULL;
|
|
|
|
NSM::Client *nsm = (NSM::Client*)user_data;
|
|
|
|
nsm->_nsm_client_id = strdup (&argv[2]->s);
|
|
nsm->_nsm_client_path = strdup (&argv[0]->s);
|
|
|
|
int r = ((NSM::Client*)user_data)->command_open (&argv[0]->s, &argv[1]->s, &argv[2]->s, &out_msg);
|
|
|
|
if (r) {
|
|
OSC_REPLY_ERR (r, (out_msg ? out_msg : ""));
|
|
} else {
|
|
OSC_REPLY ("OK");
|
|
}
|
|
|
|
if (out_msg) {
|
|
free(out_msg);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
Client::osc_session_is_loaded (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data)
|
|
{
|
|
NSM::Client *nsm = (NSM::Client*)user_data;
|
|
|
|
nsm->command_session_is_loaded();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
Client::osc_error (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data)
|
|
{
|
|
if (strcmp (&argv[0]->s, "/nsm/server/announce")) {
|
|
return -1;
|
|
}
|
|
|
|
NSM::Client *nsm = (NSM::Client*)user_data;
|
|
|
|
|
|
nsm->nsm_is_active = false;
|
|
|
|
nsm->command_active (nsm->nsm_is_active);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
Client::osc_announce_reply (const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data)
|
|
{
|
|
if (strcmp (&argv[0]->s, "/nsm/server/announce")) {
|
|
return -1;
|
|
}
|
|
|
|
NSM::Client *nsm = (NSM::Client*)user_data;
|
|
|
|
nsm->nsm_is_active = true;
|
|
nsm->_session_manager_name = strdup (&argv[2]->s);
|
|
nsm->nsm_addr = lo_address_new_from_url (lo_address_get_url (lo_message_get_source (msg)));
|
|
|
|
nsm->command_active (nsm->nsm_is_active);
|
|
|
|
return 0;
|
|
}
|
|
};
|