jack2 codebase
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.

185 lines
4.5KB

  1. /*
  2. * session_notify.c -- ultra minimal session manager
  3. *
  4. * Copyright (C) 2010 Torben Hohn.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. */
  20. #include <stdio.h>
  21. #include <errno.h>
  22. #include <unistd.h>
  23. #include <signal.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <jack/jack.h>
  27. #include <jack/jslist.h>
  28. #include <jack/transport.h>
  29. #include <jack/session.h>
  30. char *package; /* program name */
  31. jack_client_t *client;
  32. jack_session_event_type_t notify_type;
  33. char *save_path = NULL;
  34. void jack_shutdown(void *arg)
  35. {
  36. fprintf(stderr, "JACK shut down, exiting ...\n");
  37. exit(1);
  38. }
  39. void signal_handler(int sig)
  40. {
  41. jack_client_close(client);
  42. fprintf(stderr, "signal received, exiting ...\n");
  43. exit(0);
  44. }
  45. void parse_arguments(int argc, char *argv[])
  46. {
  47. /* basename $0 */
  48. package = strrchr(argv[0], '/');
  49. if (package == 0)
  50. package = argv[0];
  51. else
  52. package++;
  53. if (argc==2) {
  54. if( !strcmp( argv[1], "quit" ) ) {
  55. notify_type = JackSessionSaveAndQuit;
  56. return;
  57. }
  58. }
  59. if (argc==3) {
  60. if( !strcmp( argv[1], "save" ) ) {
  61. notify_type = JackSessionSave;
  62. save_path = argv[2];
  63. return;
  64. }
  65. }
  66. fprintf(stderr, "usage: %s quit|save [path]\n", package);
  67. exit(9);
  68. }
  69. typedef struct {
  70. char name[32];
  71. char uuid[16];
  72. } uuid_map_t;
  73. JSList *uuid_map = NULL;
  74. void add_uuid_mapping( const char *uuid ) {
  75. char *clientname = jack_get_client_name_by_uuid( client, uuid );
  76. if( !clientname ) {
  77. printf( "error... cant find client for uuid" );
  78. return;
  79. }
  80. uuid_map_t *mapping = malloc( sizeof(uuid_map_t) );
  81. snprintf( mapping->uuid, sizeof(mapping->uuid), "%s", uuid );
  82. snprintf( mapping->name, sizeof(mapping->name), "%s", clientname );
  83. uuid_map = jack_slist_append( uuid_map, mapping );
  84. }
  85. char *map_port_name_to_uuid_port( const char *port_name )
  86. {
  87. JSList *node;
  88. char retval[300];
  89. char *port_component = strchr( port_name,':' );
  90. char *client_component = strdup( port_name );
  91. strchr( client_component, ':' )[0] = '\0';
  92. sprintf( retval, "%s", port_name );
  93. for( node=uuid_map; node; node=jack_slist_next(node) ) {
  94. uuid_map_t *mapping = node->data;
  95. if( !strcmp( mapping->name, client_component ) ) {
  96. sprintf( retval, "%s%s", mapping->uuid, port_component );
  97. break;
  98. }
  99. }
  100. return strdup(retval);
  101. }
  102. int main(int argc, char *argv[])
  103. {
  104. parse_arguments(argc, argv);
  105. jack_session_command_t *retval;
  106. int k,i,j;
  107. /* become a JACK client */
  108. if ((client = jack_client_open(package, JackNullOption, NULL)) == 0) {
  109. fprintf(stderr, "JACK server not running?\n");
  110. exit(1);
  111. }
  112. #ifndef WIN32
  113. signal(SIGQUIT, signal_handler);
  114. signal(SIGHUP, signal_handler);
  115. #endif
  116. signal(SIGTERM, signal_handler);
  117. signal(SIGINT, signal_handler);
  118. jack_on_shutdown(client, jack_shutdown, 0);
  119. jack_activate(client);
  120. retval = jack_session_notify( client, NULL, notify_type, save_path );
  121. for (i = 0; retval[i].uuid; i++) {
  122. printf( "export SESSION_DIR=\"%s%s/\"\n", save_path, retval[i].client_name );
  123. printf( "%s &\n", retval[i].command );
  124. add_uuid_mapping(retval[i].uuid);
  125. }
  126. printf( "sleep 10\n" );
  127. for (k = 0; retval[k].uuid; k++) {
  128. char* port_regexp = alloca( jack_client_name_size()+3 );
  129. char* client_name = jack_get_client_name_by_uuid( client, retval[k].uuid );
  130. snprintf( port_regexp, jack_client_name_size()+3, "%s:.*", client_name );
  131. jack_free(client_name);
  132. const char **ports = jack_get_ports( client, port_regexp, NULL, 0 );
  133. if( !ports ) {
  134. continue;
  135. }
  136. for (i = 0; ports[i]; ++i) {
  137. const char **connections;
  138. if ((connections = jack_port_get_all_connections (client, jack_port_by_name(client, ports[i]))) != 0) {
  139. for (j = 0; connections[j]; j++) {
  140. char *src = map_port_name_to_uuid_port( ports[i] );
  141. char *dst = map_port_name_to_uuid_port( connections[j] );
  142. printf( "jack_connect -u \"%s\" \"%s\"\n", src, dst );
  143. }
  144. jack_free (connections);
  145. }
  146. }
  147. jack_free(ports);
  148. }
  149. jack_session_commands_free(retval);
  150. jack_client_close(client);
  151. return 0;
  152. }