Correct target
[jack2.git] / windows / JackdmpWIN32.cpp
blob9fb5bbca78071c19221ffb3c6806795609c9c241
1 /*
2 Copyright (C) 2001 Paul Davis
3 Copyright (C) 2004-2006 Grame
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include <iostream>
22 #include <assert.h>
23 #include <process.h>
24 #include <getopt.h>
26 #include "JackServer.h"
27 #include "JackConstants.h"
28 #include "driver_interface.h"
29 #include "JackDriverLoader.h"
30 #include "shm.h"
32 using namespace Jack;
34 static JackServer* fServer;
35 static char *server_name = "default";
36 static int realtime_priority = 10;
37 static int do_mlock = 1;
38 static unsigned int port_max = 128;
39 static int realtime = 0;
40 static int loopback = 0;
41 static int temporary = 0;
42 static int client_timeout = 0; /* msecs; if zero, use period size. */
43 static int do_unlock = 0;
44 static JSList* drivers = NULL;
45 static int sync = 0;
46 static int xverbose = 0;
48 #define DEFAULT_TMP_DIR "/tmp"
49 char *jack_tmpdir = DEFAULT_TMP_DIR;
51 void jack_print_driver_options (jack_driver_desc_t * desc, FILE *file);
52 void jack_print_driver_param_usage (jack_driver_desc_t * desc, unsigned long param, FILE *file);
53 int jack_parse_driver_params (jack_driver_desc_t * desc, int argc, char* argv[], JSList ** param_ptr);
54 static void silent_jack_error_callback (const char *desc)
57 static void copyright(FILE* file)
59 fprintf (file, "jackdmp " VERSION "\n"
60 "Copyright 2001-2005 Paul Davis and others.\n"
61 "Copyright 2004-2006 Grame.\n"
62 "jackdmp comes with ABSOLUTELY NO WARRANTY\n"
63 "This is free software, and you are welcome to redistribute it\n"
64 "under certain conditions; see the file COPYING for details\n");
67 static void usage (FILE *file)
69 copyright (file);
70 fprintf (file, "\n"
71 "usage: jackdmp [ --realtime OR -R [ --realtime-priority OR -P priority ] ]\n"
72 " [ --name OR -n server-name ]\n"
73 // " [ --no-mlock OR -m ]\n"
74 // " [ --unlock OR -u ]\n"
75 " [ --timeout OR -t client-timeout-in-msecs ]\n"
76 " [ --loopback OR -L loopback-port-number ]\n"
77 // " [ --port-max OR -p maximum-number-of-ports]\n"
78 " [ --verbose OR -v ]\n"
79 " [ --silent OR -s ]\n"
80 " [ --sync OR -S ]\n"
81 " [ --version OR -V ]\n"
82 " -d driver [ ... driver args ... ]\n"
83 " where driver can be `alsa', `coreaudio', 'portaudio' or `dummy'\n"
84 " jackdmp -d driver --help\n"
85 " to display options for each driver\n\n");
88 static int JackStart(jack_driver_desc_t* driver_desc, JSList* driver_params, int sync, int time_out_ms, int rt, int priority, int loopback, int verbose)
90 printf("Jackdmp: sync = %ld timeout = %ld rt = %ld priority = %ld verbose = %ld \n", sync, time_out_ms, rt, priority, verbose);
91 fServer = new JackServer(sync, time_out_ms, rt, priority, loopback, verbose);
92 int res = fServer->Open(driver_desc, driver_params);
93 return (res < 0) ? res : fServer->Start();
96 static int JackStop()
98 fServer->Stop();
99 fServer->Close();
100 printf("Jackdmp: server close\n");
101 delete fServer;
102 printf("Jackdmp: delete server\n");
103 return 0;
106 static int JackDelete()
108 delete fServer;
109 printf("Jackdmp: delete server\n");
110 return 0;
114 static char* jack_default_server_name(void)
116 char *server_name;
117 if ((server_name = getenv("JACK_DEFAULT_SERVER")) == NULL)
118 server_name = "default";
119 return server_name;
122 // returns the name of the per-user subdirectory of jack_tmpdir
123 static char* jack_user_dir(void)
125 static char user_dir[PATH_MAX] = "";
127 // format the path name on the first call
128 if (user_dir[0] == '\0') {
129 snprintf (user_dir, sizeof (user_dir), "%s/jack-%d",
130 jack_tmpdir, _getuid ());
133 return user_dir;
136 // returns the name of the per-server subdirectory of jack_user_dir()
138 static char* get_jack_server_dir(const char * toto)
140 static char server_dir[PATH_MAX] = "";
142 // format the path name on the first call
143 if (server_dir[0] == '\0') {
144 snprintf (server_dir, sizeof (server_dir), "%s/%s",
145 jack_user_dir (), server_name);
148 return server_dir;
151 static void jack_cleanup_files (const char *server_name)
153 DIR *dir;
154 struct dirent *dirent;
155 char *dir_name = get_jack_server_dir (server_name);
157 // nothing to do if the server directory does not exist
158 if ((dir = opendir (dir_name)) == NULL) {
159 return;
162 // unlink all the files in this directory, they are mine
163 while ((dirent = readdir (dir)) != NULL) {
165 char fullpath[PATH_MAX];
167 if ((strcmp (dirent->d_name, ".") == 0)
168 || (strcmp (dirent->d_name, "..") == 0)) {
169 continue;
172 snprintf (fullpath, sizeof (fullpath), "%s/%s",
173 dir_name, dirent->d_name);
175 if (unlink (fullpath)) {
176 jack_error ("cannot unlink `%s' (%s)", fullpath,
177 strerror (errno));
181 closedir (dir);
183 // now, delete the per-server subdirectory, itself
184 if (rmdir (dir_name)) {
185 jack_error ("cannot remove `%s' (%s)", dir_name,
186 strerror (errno));
189 // finally, delete the per-user subdirectory, if empty
190 if (rmdir (jack_user_dir ())) {
191 if (errno != ENOTEMPTY) {
192 jack_error ("cannot remove `%s' (%s)",
193 jack_user_dir (), strerror (errno));
199 int main(int argc, char* argv[])
201 jack_driver_desc_t * driver_desc;
202 const char *options = "-ad:P:uvshVRL:STFl:t:mn:p:";
203 struct option long_options[] = {
204 { "driver", 1, 0, 'd'
206 { "verbose", 0, 0, 'v' },
207 { "help", 0, 0, 'h' },
208 { "port-max", 1, 0, 'p' },
209 { "no-mlock", 0, 0, 'm' },
210 { "name", 0, 0, 'n' },
211 { "unlock", 0, 0, 'u' },
212 { "realtime", 0, 0, 'R' },
213 { "loopback", 0, 0, 'L' },
214 { "realtime-priority", 1, 0, 'P' },
215 { "timeout", 1, 0, 't' },
216 { "temporary", 0, 0, 'T' },
217 { "version", 0, 0, 'V' },
218 { "silent", 0, 0, 's' },
219 { "sync", 0, 0, 'S' },
220 { 0, 0, 0, 0 }
222 int opt = 0;
223 int option_index = 0;
224 int seen_driver = 0;
225 char *driver_name = NULL;
226 char **driver_args = NULL;
227 JSList * driver_params;
228 int driver_nargs = 1;
229 int show_version = 0;
230 int sync = 0;
231 int i;
232 int rc;
233 char c;
235 opterr = 0;
236 while (!seen_driver &&
237 (opt = getopt_long(argc, argv, options,
238 long_options, &option_index)) != EOF) {
239 switch (opt) {
241 case 'd':
242 seen_driver = 1;
243 driver_name = optarg;
244 break;
246 case 'v':
247 xverbose = 1;
248 break;
250 case 's':
251 // steph
252 //jack_set_error_function(silent_jack_error_callback);
253 break;
255 case 'S':
256 sync = 1;
257 break;
259 case 'n':
260 server_name = optarg;
261 break;
263 case 'm':
264 do_mlock = 0;
265 break;
267 case 'p':
268 port_max = (unsigned int)atol(optarg);
269 break;
271 case 'P':
272 realtime_priority = atoi(optarg);
273 break;
275 case 'R':
276 realtime = 1;
277 break;
279 case 'L':
280 loopback = atoi(optarg);
281 break;
283 case 'T':
284 temporary = 1;
285 break;
287 case 't':
288 client_timeout = atoi(optarg);
289 break;
291 case 'u':
292 do_unlock = 1;
293 break;
295 case 'V':
296 show_version = 1;
297 break;
299 default:
300 fprintf(stderr, "unknown option character %c\n",
301 optopt);
302 /*fallthru*/
303 case 'h':
304 usage(stdout);
305 return -1;
309 if (!seen_driver) {
310 usage (stderr);
311 exit (1);
314 drivers = jack_drivers_load (drivers);
315 if (!drivers) {
316 fprintf (stderr, "jackdmp: no drivers found; exiting\n");
317 exit (1);
320 driver_desc = jack_find_driver_descriptor (drivers, driver_name);
321 if (!driver_desc) {
322 fprintf (stderr, "jackdmp: unknown driver '%s'\n", driver_name);
323 exit (1);
326 if (optind < argc) {
327 driver_nargs = 1 + argc - optind;
328 } else {
329 driver_nargs = 1;
332 if (driver_nargs == 0) {
333 fprintf (stderr, "No driver specified ... hmm. JACK won't do"
334 " anything when run like this.\n");
335 return -1;
338 driver_args = (char **) malloc (sizeof (char *) * driver_nargs);
339 driver_args[0] = driver_name;
341 for (i = 1; i < driver_nargs; i++) {
342 driver_args[i] = argv[optind++];
345 if (jack_parse_driver_params (driver_desc, driver_nargs,
346 driver_args, &driver_params)) {
347 exit (0);
350 //if (server_name == NULL)
351 // server_name = jack_default_server_name ();
353 copyright (stdout);
355 rc = jack_register_server (server_name);
356 switch (rc) {
357 case EEXIST:
358 fprintf (stderr, "`%s' server already active\n", server_name);
359 exit (1);
360 case ENOSPC:
361 fprintf (stderr, "too many servers already active\n");
362 exit (2);
363 case ENOMEM:
364 fprintf (stderr, "no access to shm registry\n");
365 exit (3);
366 default:
367 if (xverbose)
368 fprintf (stderr, "server `%s' registered\n",
369 server_name);
373 /* clean up shared memory and files from any previous
374 * instance of this server name */
375 jack_cleanup_shm();
376 // jack_cleanup_files(server_name);
378 if (!realtime && client_timeout == 0)
379 client_timeout = 500; /* 0.5 sec; usable when non realtime. */
381 int res = JackStart(driver_desc, driver_params, sync, client_timeout, realtime, realtime_priority, loopback, xverbose);
382 if (res < 0) {
383 printf("Cannot start server... exit\n");
384 JackDelete();
385 return 0;
388 printf("Type 'q' to quit\n");
390 while ((c = getchar()) != 'q') {}
392 JackStop();
394 jack_cleanup_shm();
395 // jack_cleanup_files(server_name);
396 jack_unregister_server(server_name);
398 return 1;