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.

246 lines
5.6KB

  1. /*
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation; either version 2 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program; if not, write to the Free Software
  12. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  13. */
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <signal.h>
  18. #ifndef WIN32
  19. #include <unistd.h>
  20. #endif
  21. #include <getopt.h>
  22. #include <jack/jack.h>
  23. #include <jack/intclient.h>
  24. jack_client_t *client;
  25. jack_intclient_t intclient;
  26. char *client_name;
  27. char *intclient_name;
  28. char *load_name;
  29. char *load_init = "";
  30. char *server_name = NULL;
  31. int autoclose_opt = 0;
  32. int wait_opt = 0;
  33. volatile int idling = 1;
  34. static void
  35. signal_handler (int sig)
  36. {
  37. /* do nothing if internal client closed itself */
  38. if (idling == 0)
  39. return;
  40. jack_status_t status;
  41. fprintf (stderr, "signal received, unloading...");
  42. status = jack_internal_client_unload (client, intclient);
  43. if (status & JackFailure)
  44. fprintf (stderr, "(failed), status = 0x%2.0x\n", status);
  45. else
  46. fprintf (stderr, "(succeeded)\n");
  47. if (autoclose_opt)
  48. jack_deactivate(client);
  49. jack_client_close (client);
  50. exit (0);
  51. }
  52. static void
  53. registration_callback (const char *name, int reg, void *arg)
  54. {
  55. if (reg || strcmp(intclient_name, name))
  56. return;
  57. /* this will stop the wait loop and thus close this application. */
  58. idling = 0;
  59. return;
  60. /* unused */
  61. (void)arg;
  62. }
  63. static void
  64. show_usage ()
  65. {
  66. fprintf (stderr, "usage: %s [ options ] client-name [ load-name "
  67. "[ init-string]]\n\noptions:\n", client_name);
  68. fprintf (stderr,
  69. "\t-h, --help \t\t print help message\n"
  70. "\t-a, --autoclose\t automatically close when intclient is unloaded\n"
  71. "\t-i, --init string\t initialize string\n"
  72. "\t-s, --server name\t select JACK server\n"
  73. "\t-w, --wait \t\t wait for signal, then unload\n"
  74. "\n"
  75. );
  76. }
  77. static int
  78. parse_args (int argc, char *argv[])
  79. {
  80. int c;
  81. int option_index = 0;
  82. char *short_options = "hai:s:w";
  83. struct option long_options[] = {
  84. { "help", 0, 0, 'h' },
  85. { "autoclose", 0, 0, 'a' },
  86. { "init", required_argument, 0, 'i' },
  87. { "server", required_argument, 0, 's' },
  88. { "wait", 0, 0, 'w' },
  89. { 0, 0, 0, 0 }
  90. };
  91. client_name = strrchr(argv[0], '/');
  92. if (client_name == NULL) {
  93. client_name = argv[0];
  94. } else {
  95. client_name++;
  96. }
  97. while ((c = getopt_long (argc, argv, short_options, long_options,
  98. &option_index)) >= 0) {
  99. switch (c) {
  100. case 'a':
  101. autoclose_opt = 1;
  102. break;
  103. case 'i':
  104. load_init = optarg;
  105. break;
  106. case 's':
  107. server_name = optarg;
  108. break;
  109. case 'w':
  110. wait_opt = 1;
  111. break;
  112. case 'h':
  113. default:
  114. show_usage ();
  115. return 1;
  116. }
  117. }
  118. /* autoclose makes no sense without wait */
  119. if (autoclose_opt && ! wait_opt)
  120. autoclose_opt = 0;
  121. if (optind == argc) { /* no positional args? */
  122. show_usage ();
  123. return 1;
  124. }
  125. if (optind < argc)
  126. load_name = intclient_name = argv[optind++];
  127. if (optind < argc)
  128. load_name = argv[optind++];
  129. if (optind < argc)
  130. load_init = argv[optind++];
  131. //fprintf (stderr, "client-name = `%s', load-name = `%s', "
  132. // "load-init = `%s', wait = %d\n",
  133. // intclient_name, load_name, load_init, wait_opt);
  134. return 0; /* args OK */
  135. }
  136. int
  137. main (int argc, char *argv[])
  138. {
  139. jack_status_t status;
  140. char* name;
  141. /* parse and validate command arguments */
  142. if (parse_args (argc, argv))
  143. exit (1); /* invalid command line */
  144. /* first, become a JACK client */
  145. client = jack_client_open (client_name, JackServerName,
  146. &status, server_name);
  147. if (client == NULL) {
  148. fprintf (stderr, "jack_client_open() failed, "
  149. "status = 0x%2.0x\n", status);
  150. if (status & JackServerFailed) {
  151. fprintf (stderr, "Unable to connect to JACK server\n");
  152. }
  153. exit (1);
  154. }
  155. if (status & JackServerStarted) {
  156. fprintf (stderr, "JACK server started\n");
  157. }
  158. if (status & JackNameNotUnique) {
  159. client_name = jack_get_client_name(client);
  160. fprintf (stderr, "unique name `%s' assigned\n", client_name);
  161. }
  162. /* then, load the internal client */
  163. intclient = jack_internal_client_load (client, intclient_name,
  164. (JackLoadName|JackLoadInit),
  165. &status, load_name, load_init);
  166. if (status & JackFailure) {
  167. fprintf (stderr, "could not load %s, intclient = %d status = 0x%2.0x\n",
  168. load_name, (int)intclient, status);
  169. return 2;
  170. }
  171. if (status & JackNameNotUnique) {
  172. intclient_name =
  173. jack_get_internal_client_name (client, intclient);
  174. fprintf (stderr, "unique internal client name `%s' assigned\n",
  175. intclient_name);
  176. }
  177. fprintf (stdout, "%s is running.\n", load_name);
  178. name = jack_get_internal_client_name(client, intclient);
  179. if (name) {
  180. printf("client name = %s\n", name);
  181. free(name);
  182. }
  183. if (autoclose_opt) {
  184. jack_set_client_registration_callback(client, registration_callback, NULL);
  185. jack_activate(client);
  186. }
  187. if (wait_opt) {
  188. /* define a signal handler to unload the client, then
  189. * wait for it to exit */
  190. #ifdef WIN32
  191. signal(SIGINT, signal_handler);
  192. signal(SIGABRT, signal_handler);
  193. signal(SIGTERM, signal_handler);
  194. #else
  195. signal(SIGQUIT, signal_handler);
  196. signal(SIGTERM, signal_handler);
  197. signal(SIGHUP, signal_handler);
  198. signal(SIGINT, signal_handler);
  199. #endif
  200. while (idling) {
  201. #ifdef WIN32
  202. Sleep(1000);
  203. #else
  204. sleep (1);
  205. #endif
  206. }
  207. }
  208. if (autoclose_opt) {
  209. jack_deactivate(client);
  210. }
  211. jack_client_close(client);
  212. return 0;
  213. }