| @@ -1891,4 +1891,12 @@ EXPORT jack_session_command_t *jack_session_notify(jack_client_t* ext_client, co | |||
| } | |||
| } | |||
| EXPORT void jack_session_event_free(jack_session_event_t* ev) | |||
| { | |||
| free((void *)ev->session_dir); | |||
| free((void *)ev->client_uuid); | |||
| if (ev->command_line) | |||
| free(ev->command_line); | |||
| free(ev); | |||
| } | |||
| @@ -127,7 +127,7 @@ class JackClientChannelInterface | |||
| virtual void InternalClientUnload(int refnum, int int_ref, int* status, int* result) | |||
| {} | |||
| virtual void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char *path, int *result) | |||
| virtual void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char *path, jack_session_command_t **result) | |||
| {} | |||
| }; | |||
| @@ -272,6 +272,22 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync, | |||
| fInfoShutdown = NULL; | |||
| } | |||
| break; | |||
| case kSessionCallback: | |||
| jack_log("JackClient::kSessionCallback"); | |||
| if (fSession) { | |||
| jack_session_event_t *event = (jack_session_event_t *) malloc( sizeof(jack_session_event_t) ); | |||
| char uuid_buf[32]; | |||
| event->type = (jack_session_event_type_t) value1; | |||
| event->session_dir = strdup( message ); | |||
| event->command_line = NULL; | |||
| event->flags = (jack_session_flags_t) 0; | |||
| snprintf( uuid_buf, sizeof(uuid_buf), "%d", GetClientControl()->fSessionID ); | |||
| event->client_uuid = strdup( uuid_buf ); | |||
| fSession(event, fSessionArg); | |||
| } | |||
| break; | |||
| } | |||
| } | |||
| @@ -1057,7 +1073,11 @@ void JackClient::InternalClientUnload(int ref, jack_status_t* status) | |||
| jack_session_command_t *JackClient::SessionNotify( const char* target, jack_session_event_type_t type, const char* path ) | |||
| { | |||
| return NULL; | |||
| printf( "yo man\n" ); | |||
| sleep(1); | |||
| jack_session_command_t *res; | |||
| fChannel->SessionNotify( GetClientControl()->fRefNum, target, type, path, &res ); | |||
| return res; | |||
| } | |||
| @@ -26,6 +26,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| #include "JackSynchro.h" | |||
| #include "JackNotification.h" | |||
| #include "jack/session.h" | |||
| namespace Jack | |||
| { | |||
| @@ -44,6 +46,10 @@ struct JackClientControl : public JackShmMemAble | |||
| int fPID; | |||
| bool fActive; | |||
| int fSessionID; | |||
| char fSessionCommand[256 + 1]; | |||
| jack_session_flags_t fSessionFlags; | |||
| JackClientControl(const char* name, int pid, int refnum) | |||
| { | |||
| Init(name, pid, refnum); | |||
| @@ -77,6 +83,8 @@ struct JackClientControl : public JackShmMemAble | |||
| fTransportSync = false; | |||
| fTransportTimebase = false; | |||
| fActive = false; | |||
| fSessionID = 0; | |||
| } | |||
| } POST_PACKED_STRUCTURE; | |||
| @@ -863,10 +863,45 @@ int JackEngine::PortRename(int refnum, jack_port_id_t port, const char* name) | |||
| return 0; | |||
| } | |||
| void JackEngine::SessionNotify(int refnum, const char *target, jack_session_event_type_t type, const char *path, int *result ) | |||
| void JackEngine::SessionNotify(int refnum, const char *target, jack_session_event_type_t type, const char *path, JackChannelTransaction *socket ) | |||
| { | |||
| if (fSessionPendingReplies != 0) { | |||
| JackSessionNotifyResult res(-1); | |||
| res.Write(socket); | |||
| return; | |||
| } | |||
| fSessionResult = new JackSessionNotifyResult(); | |||
| for (int i = 0; i < CLIENT_NUM; i++) { | |||
| JackClientInterface* client = fClientTable[i]; | |||
| if (client && client->GetClientControl()->fCallback[kSessionCallback]) { | |||
| // check if this is a notification to a specific client. | |||
| if (target!=NULL && strlen(target)!=0) { | |||
| if (strcmp(target, client->GetClientControl()->fName)) { | |||
| continue; | |||
| } | |||
| } | |||
| int result = client->ClientNotify(i, client->GetClientControl()->fName, kSessionCallback, true, path, (int) type, 0); | |||
| if (result == 2) { | |||
| fSessionPendingReplies += 1; | |||
| } else if (result == 1) { | |||
| char uuid_buf[32]; | |||
| snprintf( uuid_buf, sizeof(uuid_buf), "%d", client->GetClientControl()->fSessionID ); | |||
| fSessionResult->fCommandList.push_back( JackSessionCommand( uuid_buf, | |||
| client->GetClientControl()->fName, | |||
| client->GetClientControl()->fSessionCommand, | |||
| client->GetClientControl()->fSessionFlags )); | |||
| } | |||
| } | |||
| } | |||
| // yay... :( | |||
| *result = 0; | |||
| //*result = 0; | |||
| } | |||
| @@ -52,6 +52,11 @@ class SERVER_EXPORT JackEngine : public JackLockAble | |||
| JackProcessSync fSignal; | |||
| jack_time_t fLastSwitchUsecs; | |||
| int fSessionPendingReplies; | |||
| JackChannelTransaction *fSessionTransaction; | |||
| JackSessionNotifyResult *fSessionResult; | |||
| int ClientCloseAux(int refnum, JackClientInterface* client, bool wait); | |||
| void CheckXRun(jack_time_t callback_usecs); | |||
| @@ -132,7 +137,7 @@ class SERVER_EXPORT JackEngine : public JackLockAble | |||
| void NotifyFreewheel(bool onoff); | |||
| void NotifyQuit(); | |||
| void SessionNotify( int refnum, const char *target, jack_session_event_type_t type, const char *path, int *result ); | |||
| void SessionNotify( int refnum, const char *target, jack_session_event_type_t type, const char *path, JackChannelTransaction *socket ); | |||
| }; | |||
| @@ -307,11 +307,11 @@ class SERVER_EXPORT JackLockedEngine | |||
| CATCH_EXCEPTION | |||
| } | |||
| void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char *path, int *result) | |||
| void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char *path, JackChannelTransaction *socket) | |||
| { | |||
| TRY_CALL | |||
| JackLock lock(&fEngine); | |||
| return fEngine.SessionNotify( refnum, target, type, path, result ); | |||
| fEngine.SessionNotify( refnum, target, type, path, socket ); | |||
| CATCH_EXCEPTION | |||
| } | |||
| @@ -26,6 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
| #include "types.h" | |||
| #include <string.h> | |||
| #include <stdio.h> | |||
| #include <list> | |||
| namespace Jack | |||
| { | |||
| @@ -1071,28 +1072,69 @@ struct JackClientNotificationRequest : public JackRequest | |||
| } POST_PACKED_STRUCTURE; | |||
| struct JackSessionCommand | |||
| { | |||
| char fUUID[32]; | |||
| char fClientName[JACK_CLIENT_NAME_SIZE+1]; | |||
| char fCommand[MAX_PATH+1]; | |||
| jack_session_flags_t fFlags; | |||
| JackSessionCommand() | |||
| {} | |||
| JackSessionCommand( const char *uuid, const char *clientname, const char *command, jack_session_flags_t flags ) | |||
| { | |||
| strncpy( fUUID, uuid, sizeof(fUUID)); | |||
| strncpy( fClientName, clientname, sizeof(fClientName)); | |||
| strncpy( fCommand, command, sizeof(fCommand)); | |||
| fFlags = flags; | |||
| } | |||
| }; | |||
| struct JackSessionNotifyResult : public JackResult | |||
| { | |||
| int fStatus; | |||
| std::list<JackSessionCommand> fCommandList; | |||
| JackSessionNotifyResult(): JackResult() | |||
| {} | |||
| JackSessionNotifyResult(int32_t result, int status) | |||
| : JackResult(result), fStatus(status) | |||
| JackSessionNotifyResult(int32_t result) | |||
| : JackResult(result) | |||
| {} | |||
| int Read(JackChannelTransaction* trans) | |||
| { | |||
| CheckRes(JackResult::Read(trans)); | |||
| CheckRes(trans->Read(&fStatus, sizeof(int))); | |||
| while(1) { | |||
| JackSessionCommand buffer; | |||
| CheckRes(trans->Read(buffer.fUUID, sizeof(buffer.fUUID))); | |||
| if (buffer.fUUID[0] == '\0') | |||
| break; | |||
| CheckRes(trans->Read(buffer.fClientName, sizeof(buffer.fClientName))); | |||
| CheckRes(trans->Read(buffer.fCommand, sizeof(buffer.fCommand))); | |||
| CheckRes(trans->Read(&(buffer.fFlags), sizeof(buffer.fFlags))); | |||
| fCommandList.push_back(buffer); | |||
| } | |||
| return 0; | |||
| } | |||
| int Write(JackChannelTransaction* trans) | |||
| { | |||
| char terminator[32]; | |||
| terminator[0] = '\0'; | |||
| CheckRes(JackResult::Write(trans)); | |||
| CheckRes(trans->Write(&fStatus, sizeof(int))); | |||
| for (std::list<JackSessionCommand>::iterator i=fCommandList.begin(); i!=fCommandList.end(); i++) { | |||
| CheckRes(trans->Write(i->fUUID, sizeof(i->fUUID))); | |||
| CheckRes(trans->Write(i->fClientName, sizeof(i->fClientName))); | |||
| CheckRes(trans->Write(i->fCommand, sizeof(i->fCommand))); | |||
| CheckRes(trans->Write(&(i->fFlags), sizeof(i->fFlags))); | |||
| } | |||
| CheckRes(trans->Write(terminator, sizeof(terminator))); | |||
| return 0; | |||
| } | |||
| @@ -345,11 +345,16 @@ enum JackOptions { | |||
| * Pass optional <em>(char *) load_init</em> string to the | |||
| * jack_initialize() entry point of an internal client. | |||
| */ | |||
| JackLoadInit = 0x10 | |||
| JackLoadInit = 0x10, | |||
| /** | |||
| * pass a SessionID Token this allows the sessionmanager to identify the client again. | |||
| */ | |||
| JackSessionID = 0x20 | |||
| }; | |||
| /** Valid options for opening an external client. */ | |||
| #define JackOpenOptions (JackServerName|JackNoStartServer|JackUseExactName) | |||
| #define JackOpenOptions (JackSessionID|JackServerName|JackNoStartServer|JackUseExactName) | |||
| /** Valid options for loading an internal client. */ | |||
| #define JackLoadOptions (JackLoadInit|JackLoadName|JackUseExactName) | |||
| @@ -0,0 +1,183 @@ | |||
| /* | |||
| * session_notify.c -- ultra minimal session manager | |||
| * | |||
| * Copyright (C) 2010 Torben Hohn. | |||
| * | |||
| * 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; if not, write to the Free Software | |||
| * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||
| */ | |||
| #include <stdio.h> | |||
| #include <errno.h> | |||
| #include <unistd.h> | |||
| #include <signal.h> | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| #include <jack/jack.h> | |||
| #include <jack/types.h> | |||
| #include <jack/jslist.h> | |||
| #include <jack/transport.h> | |||
| #include <jack/session.h> | |||
| char *package; /* program name */ | |||
| jack_client_t *client; | |||
| jack_session_event_type_t notify_type; | |||
| char *save_path = NULL; | |||
| void jack_shutdown(void *arg) | |||
| { | |||
| fprintf(stderr, "JACK shut down, exiting ...\n"); | |||
| exit(1); | |||
| } | |||
| void signal_handler(int sig) | |||
| { | |||
| jack_client_close(client); | |||
| fprintf(stderr, "signal received, exiting ...\n"); | |||
| exit(0); | |||
| } | |||
| void parse_arguments(int argc, char *argv[]) | |||
| { | |||
| /* basename $0 */ | |||
| package = strrchr(argv[0], '/'); | |||
| if (package == 0) | |||
| package = argv[0]; | |||
| else | |||
| package++; | |||
| if (argc==2) { | |||
| if( !strcmp( argv[1], "quit" ) ) { | |||
| notify_type = JackSessionSaveAndQuit; | |||
| return; | |||
| } | |||
| } | |||
| if (argc==3) { | |||
| if( !strcmp( argv[1], "save" ) ) { | |||
| notify_type = JackSessionSave; | |||
| save_path = argv[2]; | |||
| return; | |||
| } | |||
| } | |||
| fprintf(stderr, "usage: %s quit|save [path]\n", package); | |||
| exit(9); | |||
| } | |||
| typedef struct { | |||
| char name[32]; | |||
| char uuid[16]; | |||
| } uuid_map_t; | |||
| JSList *uuid_map = NULL; | |||
| void add_uuid_mapping( const char *uuid ) { | |||
| char *clientname = jack_get_client_name_by_uuid( client, uuid ); | |||
| if( !clientname ) { | |||
| printf( "error... cant find client for uuid" ); | |||
| return; | |||
| } | |||
| uuid_map_t *mapping = malloc( sizeof(uuid_map_t) ); | |||
| snprintf( mapping->uuid, sizeof(mapping->uuid), "%s", uuid ); | |||
| snprintf( mapping->name, sizeof(mapping->name), "%s", clientname ); | |||
| uuid_map = jack_slist_append( uuid_map, mapping ); | |||
| } | |||
| char *map_port_name_to_uuid_port( const char *port_name ) | |||
| { | |||
| JSList *node; | |||
| char retval[300]; | |||
| char *port_component = strchr( port_name,':' ); | |||
| char *client_component = strdup( port_name ); | |||
| strchr( client_component, ':' )[0] = '\0'; | |||
| sprintf( retval, "%s", port_name ); | |||
| for( node=uuid_map; node; node=jack_slist_next(node) ) { | |||
| uuid_map_t *mapping = node->data; | |||
| if( !strcmp( mapping->name, client_component ) ) { | |||
| sprintf( retval, "%s%s", mapping->uuid, port_component ); | |||
| break; | |||
| } | |||
| } | |||
| return strdup(retval); | |||
| } | |||
| int main(int argc, char *argv[]) | |||
| { | |||
| parse_arguments(argc, argv); | |||
| jack_session_command_t *retval; | |||
| int k,i,j; | |||
| /* become a JACK client */ | |||
| if ((client = jack_client_open(package, JackNullOption, NULL)) == 0) { | |||
| fprintf(stderr, "JACK server not running?\n"); | |||
| exit(1); | |||
| } | |||
| signal(SIGQUIT, signal_handler); | |||
| signal(SIGTERM, signal_handler); | |||
| signal(SIGHUP, signal_handler); | |||
| signal(SIGINT, signal_handler); | |||
| jack_on_shutdown(client, jack_shutdown, 0); | |||
| jack_activate(client); | |||
| retval = jack_session_notify( client, NULL, notify_type, save_path ); | |||
| printf( "retval = %p\n", retval ); | |||
| for(i=0; retval[i].uuid; i++ ) { | |||
| printf( "export SESSION_DIR=\"%s%s/\"\n", save_path, retval[i].client_name ); | |||
| printf( "%s &\n", retval[i].command ); | |||
| add_uuid_mapping(retval[i].uuid); | |||
| } | |||
| printf( "sleep 10\n" ); | |||
| for(k=0; retval[k].uuid; k++ ) { | |||
| char* port_regexp = alloca( jack_client_name_size()+3 ); | |||
| char* client_name = jack_get_client_name_by_uuid( client, retval[k].uuid ); | |||
| snprintf( port_regexp, jack_client_name_size()+3, "%s:.*", client_name ); | |||
| jack_free(client_name); | |||
| const char **ports = jack_get_ports( client, port_regexp, NULL, 0 ); | |||
| if( !ports ) { | |||
| continue; | |||
| } | |||
| for (i = 0; ports[i]; ++i) { | |||
| const char **connections; | |||
| if ((connections = jack_port_get_all_connections (client, jack_port_by_name(client, ports[i]))) != 0) { | |||
| for (j = 0; connections[j]; j++) { | |||
| char *src = map_port_name_to_uuid_port( ports[i] ); | |||
| char *dst = map_port_name_to_uuid_port( connections[j] ); | |||
| printf( "jack_connect -u \"%s\" \"%s\"\n", src, dst ); | |||
| } | |||
| jack_free (connections); | |||
| } | |||
| } | |||
| jack_free(ports); | |||
| } | |||
| jack_session_commands_free(retval); | |||
| jack_client_close(client); | |||
| return 0; | |||
| } | |||
| @@ -0,0 +1,202 @@ | |||
| /** @file simple_session_client.c | |||
| * | |||
| * @brief This simple client demonstrates the most basic features of JACK | |||
| * as they would be used by many applications. | |||
| * this version also adds session manager functionality. | |||
| */ | |||
| #include <stdio.h> | |||
| #include <errno.h> | |||
| #include <unistd.h> | |||
| #include <stdlib.h> | |||
| #include <string.h> | |||
| #include <jack/jack.h> | |||
| #include <jack/types.h> | |||
| #include <jack/session.h> | |||
| jack_port_t *input_port; | |||
| jack_port_t *output_port; | |||
| jack_client_t *client; | |||
| int simple_quit = 0; | |||
| /** | |||
| * The process callback for this JACK application is called in a | |||
| * special realtime thread once for each audio cycle. | |||
| * | |||
| * This client does nothing more than copy data from its input | |||
| * port to its output port. It will exit when stopped by | |||
| * the user (e.g. using Ctrl-C on a unix-ish operating system) | |||
| */ | |||
| int | |||
| process (jack_nframes_t nframes, void *arg) | |||
| { | |||
| jack_default_audio_sample_t *in, *out; | |||
| in = jack_port_get_buffer (input_port, nframes); | |||
| out = jack_port_get_buffer (output_port, nframes); | |||
| memcpy (out, in, | |||
| sizeof (jack_default_audio_sample_t) * nframes); | |||
| return 0; | |||
| } | |||
| void | |||
| session_callback (jack_session_event_t *event, void *arg) | |||
| { | |||
| char retval[100]; | |||
| printf ("session notification\n"); | |||
| printf ("path %s, uuid %s, type: %s\n", event->session_dir, event->client_uuid, event->type == JackSessionSave ? "save" : "quit"); | |||
| snprintf (retval, 100, "jack_simple_session_client %s", event->client_uuid); | |||
| event->command_line = strdup (retval); | |||
| jack_session_reply( client, event ); | |||
| if (event->type == JackSessionSaveAndQuit) { | |||
| simple_quit = 1; | |||
| } | |||
| jack_session_event_free (event); | |||
| } | |||
| /** | |||
| * JACK calls this shutdown_callback if the server ever shuts down or | |||
| * decides to disconnect the client. | |||
| */ | |||
| void | |||
| jack_shutdown (void *arg) | |||
| { | |||
| exit (1); | |||
| } | |||
| int | |||
| main (int argc, char *argv[]) | |||
| { | |||
| const char **ports; | |||
| const char *client_name = "simple"; | |||
| jack_status_t status; | |||
| /* open a client connection to the JACK server */ | |||
| if( argc == 1 ) | |||
| client = jack_client_open (client_name, JackNullOption, &status ); | |||
| else if( argc == 2 ) | |||
| client = jack_client_open (client_name, JackSessionID, &status, argv[1] ); | |||
| if (client == NULL) { | |||
| fprintf (stderr, "jack_client_open() failed, " | |||
| "status = 0x%2.0x\n", status); | |||
| if (status & JackServerFailed) { | |||
| fprintf (stderr, "Unable to connect to JACK server\n"); | |||
| } | |||
| exit (1); | |||
| } | |||
| if (status & JackServerStarted) { | |||
| fprintf (stderr, "JACK server started\n"); | |||
| } | |||
| if (status & JackNameNotUnique) { | |||
| client_name = jack_get_client_name(client); | |||
| fprintf (stderr, "unique name `%s' assigned\n", client_name); | |||
| } | |||
| /* tell the JACK server to call `process()' whenever | |||
| there is work to be done. | |||
| */ | |||
| jack_set_process_callback (client, process, 0); | |||
| /* tell the JACK server to call `jack_shutdown()' if | |||
| it ever shuts down, either entirely, or if it | |||
| just decides to stop calling us. | |||
| */ | |||
| jack_on_shutdown (client, jack_shutdown, 0); | |||
| /* tell the JACK server to call `session_callback()' if | |||
| the session is saved. | |||
| */ | |||
| jack_set_session_callback (client, session_callback, NULL); | |||
| /* display the current sample rate. | |||
| */ | |||
| printf ("engine sample rate: %" PRIu32 "\n", | |||
| jack_get_sample_rate (client)); | |||
| /* create two ports */ | |||
| input_port = jack_port_register (client, "input", | |||
| JACK_DEFAULT_AUDIO_TYPE, | |||
| JackPortIsInput, 0); | |||
| output_port = jack_port_register (client, "output", | |||
| JACK_DEFAULT_AUDIO_TYPE, | |||
| JackPortIsOutput, 0); | |||
| if ((input_port == NULL) || (output_port == NULL)) { | |||
| fprintf(stderr, "no more JACK ports available\n"); | |||
| exit (1); | |||
| } | |||
| /* Tell the JACK server that we are ready to roll. Our | |||
| * process() callback will start running now. */ | |||
| if (jack_activate (client)) { | |||
| fprintf (stderr, "cannot activate client"); | |||
| exit (1); | |||
| } | |||
| /* Connect the ports. You can't do this before the client is | |||
| * activated, because we can't make connections to clients | |||
| * that aren't running. Note the confusing (but necessary) | |||
| * orientation of the driver backend ports: playback ports are | |||
| * "input" to the backend, and capture ports are "output" from | |||
| * it. | |||
| */ | |||
| /* only do the autoconnect when not reloading from a session. | |||
| * in case of a session reload, the SM will restore our connections | |||
| */ | |||
| if (argc==1) { | |||
| ports = jack_get_ports (client, NULL, NULL, | |||
| JackPortIsPhysical|JackPortIsOutput); | |||
| if (ports == NULL) { | |||
| fprintf(stderr, "no physical capture ports\n"); | |||
| exit (1); | |||
| } | |||
| if (jack_connect (client, ports[0], jack_port_name (input_port))) { | |||
| fprintf (stderr, "cannot connect input ports\n"); | |||
| } | |||
| free (ports); | |||
| ports = jack_get_ports (client, NULL, NULL, | |||
| JackPortIsPhysical|JackPortIsInput); | |||
| if (ports == NULL) { | |||
| fprintf(stderr, "no physical playback ports\n"); | |||
| exit (1); | |||
| } | |||
| if (jack_connect (client, jack_port_name (output_port), ports[0])) { | |||
| fprintf (stderr, "cannot connect output ports\n"); | |||
| } | |||
| free (ports); | |||
| } | |||
| /* keep running until until we get a quit event */ | |||
| while (!simple_quit) | |||
| sleep(1); | |||
| jack_client_close (client); | |||
| exit (0); | |||
| } | |||
| @@ -22,6 +22,8 @@ example_programs = { | |||
| 'jack_monitor_client' : 'monitor_client.c', | |||
| 'jack_thru' : 'thru_client.c', | |||
| 'jack_cpu_load' : 'cpu_load.c', | |||
| 'jack_simple_session_client' : 'simple_session_client.c', | |||
| 'jack_session_notify' : 'session_notify.c', | |||
| 'jack_server_control' : 'server_control.cpp', | |||
| } | |||
| @@ -246,14 +246,29 @@ void JackSocketClientChannel::SetFreewheel(int onoff, int* result) | |||
| ServerSyncCall(&req, &res, result); | |||
| } | |||
| void JackSocketClientChannel::SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, int* result) | |||
| void JackSocketClientChannel::SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, jack_session_command_t ** result) | |||
| { | |||
| JackSessionNotifyRequest req(refnum, target, type, path); | |||
| JackResult res; | |||
| JackSessionNotifyResult res; | |||
| int intresult; | |||
| ServerSyncCall(&req, &res, &intresult); | |||
| *result = 0; | |||
| jack_session_command_t *session_command = (jack_session_command_t *)malloc( sizeof(jack_session_command_t) * (res.fCommandList.size()+1) ); | |||
| int i=0; | |||
| for (std::list<JackSessionCommand>::iterator ci=res.fCommandList.begin(); ci!=res.fCommandList.end(); ci++) { | |||
| session_command[i].uuid = strdup( ci->fUUID ); | |||
| session_command[i].client_name = strdup( ci->fClientName ); | |||
| session_command[i].command = strdup( ci->fCommand ); | |||
| session_command[i].flags = ci->fFlags; | |||
| i+=1; | |||
| } | |||
| session_command[i].uuid = NULL; | |||
| *result = session_command; | |||
| } | |||
| void JackSocketClientChannel::ReleaseTimebase(int refnum, int* result) | |||
| @@ -95,7 +95,7 @@ class JackSocketClientChannel : public detail::JackClientChannelInterface, publi | |||
| bool Init(); | |||
| bool Execute(); | |||
| void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, int* result); | |||
| void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char* path, jack_session_command_t** result); | |||
| }; | |||
| } // end of namespace | |||
| @@ -405,10 +405,8 @@ bool JackSocketServerChannel::HandleRequest(int fd) | |||
| JackSessionNotifyRequest req; | |||
| JackSessionNotifyResult res; | |||
| if (req.Read(socket) == 0) { | |||
| fServer->GetEngine()->SessionNotify(req.fRefNum, req.fDst, req.fEventType, req.fPath, &res.fStatus); | |||
| fServer->GetEngine()->SessionNotify(req.fRefNum, req.fDst, req.fEventType, req.fPath, socket); | |||
| } | |||
| if (res.Write(socket) < 0) | |||
| jack_error("JackRequest::SessionNotify write error ref = %d", req.fRefNum); | |||
| break; | |||
| } | |||