~ubuntu-branches/ubuntu/precise/puredata/precise

« back to all changes in this revision

Viewing changes to src/s_main.c

  • Committer: Bazaar Package Importer
  • Author(s): Paul Brossier
  • Date: 2009-12-22 21:29:31 UTC
  • mfrom: (1.2.6 upstream) (4.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091222212931-nhwkzapjwsmjao1l
Tags: 0.42.5-3
* debian/control:
  - add community site to homepage field
  - improve long description
  - remove Replaces and Conflicts fields
  - add Suggests on pd-csound, pd-pdp, pd-zexy, pd-aubio
* debian/rules: add per-arch configuration flags
* debian/patches/02_kfreebsd.diff:
  - also define pd_tilde_dllextent on FreeBSD
  - fix typo (really closing #414414 this time)
  - also add hurd glue
* debian/patches/04_hurd.diff:
  - add hurd glue and s_midi_dummy.c

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 1997-1999 Miller Puckette and others.
 
2
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
 
3
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.  */
 
4
 
 
5
#include "m_pd.h"
 
6
#include "m_imp.h"
 
7
#include "s_stuff.h"
 
8
#include <sys/types.h>
 
9
#include <sys/stat.h>
 
10
#include <limits.h>
 
11
#include <string.h>
 
12
#include <stdio.h>
 
13
#include <fcntl.h>
 
14
#include <stdlib.h>
 
15
 
 
16
#ifdef UNISTD
 
17
#include <unistd.h>
 
18
#endif
 
19
#ifdef MSW
 
20
#include <io.h>
 
21
#include <windows.h>
 
22
#include <winbase.h>
 
23
#endif
 
24
#ifdef _MSC_VER  /* This is only for Microsoft's compiler, not cygwin, e.g. */
 
25
#define snprintf sprintf_s
 
26
#endif
 
27
 
 
28
char *pd_version;
 
29
char pd_compiletime[] = __TIME__;
 
30
char pd_compiledate[] = __DATE__;
 
31
 
 
32
void pd_init(void);
 
33
int sys_argparse(int argc, char **argv);
 
34
void sys_findprogdir(char *progname);
 
35
int sys_startgui(const char *guipath);
 
36
int sys_rcfile(void);
 
37
int m_mainloop(void);
 
38
int m_batchmain(void);
 
39
void sys_addhelppath(char *p);
 
40
#ifdef USEAPI_ALSA
 
41
void alsa_adddev(char *name);
 
42
#endif
 
43
 
 
44
int sys_debuglevel;
 
45
int sys_verbose;
 
46
int sys_noloadbang;
 
47
int sys_nogui;
 
48
int sys_hipriority = -1;    /* -1 = don't care; 0 = no; 1 = yes */
 
49
int sys_guisetportnumber;   /* if started from the GUI, this is the port # */
 
50
int sys_nosleep = 0;  /* skip all "sleep" calls and spin instead */
 
51
 
 
52
char *sys_guicmd;
 
53
t_symbol *sys_libdir;
 
54
t_symbol *sys_guidir;
 
55
static t_namelist *sys_openlist;
 
56
static t_namelist *sys_messagelist;
 
57
static int sys_version;
 
58
int sys_oldtclversion;      /* hack to warn g_rtext.c about old text sel */
 
59
 
 
60
int sys_nmidiout = -1;
 
61
int sys_nmidiin = -1;
 
62
int sys_midiindevlist[MAXMIDIINDEV] = {1};
 
63
int sys_midioutdevlist[MAXMIDIOUTDEV] = {1};
 
64
 
 
65
char sys_font[100] = 
 
66
#ifdef MSW
 
67
    "Courier";
 
68
#else
 
69
    "Courier";
 
70
#endif
 
71
char sys_fontweight[] = "bold  "; /* currently only used for iemguis */
 
72
static int sys_main_srate;
 
73
static int sys_main_advance;
 
74
static int sys_main_callback;
 
75
static int sys_listplease;
 
76
 
 
77
int sys_externalschedlib;
 
78
char sys_externalschedlibname[MAXPDSTRING];
 
79
static int sys_batch;
 
80
int sys_extraflags;
 
81
char sys_extraflagsstring[MAXPDSTRING];
 
82
int sys_run_scheduler(const char *externalschedlibname,
 
83
    const char *sys_extraflagsstring);
 
84
int sys_noautopatch;    /* temporary hack to defeat new 0.42 editing */
 
85
 
 
86
    /* here the "-1" counts signify that the corresponding vector hasn't been
 
87
    specified in command line arguments; sys_set_audio_settings will detect it
 
88
    and fill things in. */
 
89
static int sys_nsoundin = -1;
 
90
static int sys_nsoundout = -1;
 
91
static int sys_soundindevlist[MAXAUDIOINDEV];
 
92
static int sys_soundoutdevlist[MAXAUDIOOUTDEV];
 
93
 
 
94
static int sys_nchin = -1;
 
95
static int sys_nchout = -1;
 
96
static int sys_chinlist[MAXAUDIOINDEV];
 
97
static int sys_choutlist[MAXAUDIOOUTDEV];
 
98
 
 
99
t_sample* get_sys_soundout() { return sys_soundout; }
 
100
t_sample* get_sys_soundin() { return sys_soundin; }
 
101
int* get_sys_main_advance() { return &sys_main_advance; }
 
102
double* get_sys_time_per_dsp_tick() { return &sys_time_per_dsp_tick; }
 
103
int* get_sys_schedblocksize() { return &sys_schedblocksize; }
 
104
double* get_sys_time() { return &sys_time; }
 
105
t_float* get_sys_dacsr() { return &sys_dacsr; }
 
106
int* get_sys_sleepgrain() { return &sys_sleepgrain; }
 
107
int* get_sys_schedadvance() { return &sys_schedadvance; }
 
108
 
 
109
typedef struct _fontinfo
 
110
{
 
111
    int fi_fontsize;
 
112
    int fi_maxwidth;
 
113
    int fi_maxheight;
 
114
    int fi_hostfontsize;
 
115
    int fi_width;
 
116
    int fi_height;
 
117
} t_fontinfo;
 
118
 
 
119
    /* these give the nominal point size and maximum height of the characters
 
120
    in the six fonts.  */
 
121
 
 
122
static t_fontinfo sys_fontlist[] = {
 
123
    {8, 6, 10, 0, 0, 0}, {10, 7, 13, 0, 0, 0}, {12, 9, 16, 0, 0, 0},
 
124
    {16, 10, 20, 0, 0, 0}, {24, 15, 25, 0, 0, 0}, {36, 25, 45, 0, 0, 0}};
 
125
#define NFONT (sizeof(sys_fontlist)/sizeof(*sys_fontlist))
 
126
 
 
127
/* here are the actual font size structs on msp's systems:
 
128
MSW:
 
129
font 8 5 9 8 5 11
 
130
font 10 7 13 10 6 13
 
131
font 12 9 16 14 8 16
 
132
font 16 10 20 16 10 18
 
133
font 24 15 25 16 10 18
 
134
font 36 25 42 36 22 41
 
135
 
 
136
linux:
 
137
font 8 5 9 8 5 9
 
138
font 10 7 13 12 7 13
 
139
font 12 9 16 14 9 15
 
140
font 16 10 20 16 10 19
 
141
font 24 15 25 24 15 24
 
142
font 36 25 42 36 22 41
 
143
*/
 
144
 
 
145
static t_fontinfo *sys_findfont(int fontsize)
 
146
{
 
147
    unsigned int i;
 
148
    t_fontinfo *fi;
 
149
    for (i = 0, fi = sys_fontlist; i < (NFONT-1); i++, fi++)
 
150
        if (fontsize < fi[1].fi_fontsize) return (fi);
 
151
    return (sys_fontlist + (NFONT-1));
 
152
}
 
153
 
 
154
int sys_nearestfontsize(int fontsize)
 
155
{
 
156
    return (sys_findfont(fontsize)->fi_fontsize);
 
157
}
 
158
 
 
159
int sys_hostfontsize(int fontsize)
 
160
{
 
161
    return (sys_findfont(fontsize)->fi_hostfontsize);
 
162
}
 
163
 
 
164
int sys_fontwidth(int fontsize)
 
165
{
 
166
    return (sys_findfont(fontsize)->fi_width);
 
167
}
 
168
 
 
169
int sys_fontheight(int fontsize)
 
170
{
 
171
    return (sys_findfont(fontsize)->fi_height);
 
172
}
 
173
 
 
174
int sys_defaultfont;
 
175
#ifdef MSW
 
176
#define DEFAULTFONT 12
 
177
#else
 
178
#define DEFAULTFONT 10
 
179
#endif
 
180
 
 
181
static void openit(const char *dirname, const char *filename)
 
182
{
 
183
    char dirbuf[MAXPDSTRING], *nameptr;
 
184
    int fd = open_via_path(dirname, filename, "", dirbuf, &nameptr,
 
185
        MAXPDSTRING, 0);
 
186
    if (fd >= 0)
 
187
    {
 
188
        close (fd);
 
189
        glob_evalfile(0, gensym(nameptr), gensym(dirbuf));
 
190
    }
 
191
    else
 
192
        error("%s: can't open", filename);
 
193
}
 
194
 
 
195
/* this is called from the gui process.  The first argument is the cwd, and
 
196
succeeding args give the widths and heights of known fonts.  We wait until 
 
197
these are known to open files and send messages specified on the command line.
 
198
We ask the GUI to specify the "cwd" in case we don't have a local OS to get it
 
199
from; for instance we could be some kind of RT embedded system.  However, to
 
200
really make this make sense we would have to implement
 
201
open(), read(), etc, calls to be served somehow from the GUI too. */
 
202
 
 
203
void glob_initfromgui(void *dummy, t_symbol *s, int argc, t_atom *argv)
 
204
{
 
205
    char *cwd = atom_getsymbolarg(0, argc, argv)->s_name;
 
206
    t_namelist *nl;
 
207
    unsigned int i;
 
208
    int j;
 
209
    int nhostfont = (argc-2)/3;
 
210
    sys_oldtclversion = atom_getfloatarg(1, argc, argv);
 
211
    if (argc != 2 + 3 * nhostfont) bug("glob_initfromgui");
 
212
    for (i = 0; i < NFONT; i++)
 
213
    {
 
214
        int best = 0;
 
215
        int wantheight = sys_fontlist[i].fi_maxheight;
 
216
        int wantwidth = sys_fontlist[i].fi_maxwidth;
 
217
        for (j = 1; j < nhostfont; j++)
 
218
        {
 
219
            if (atom_getintarg(3 * j + 4, argc, argv) <= wantheight &&
 
220
                atom_getintarg(3 * j + 3, argc, argv) <= wantwidth)
 
221
                    best = j;
 
222
        }
 
223
            /* best is now the host font index for the desired font index i. */
 
224
        sys_fontlist[i].fi_hostfontsize =
 
225
            atom_getintarg(3 * best + 2, argc, argv);
 
226
        sys_fontlist[i].fi_width = atom_getintarg(3 * best + 3, argc, argv);
 
227
        sys_fontlist[i].fi_height = atom_getintarg(3 * best + 4, argc, argv);
 
228
    }
 
229
#if 0
 
230
    for (i = 0; i < 6; i++)
 
231
        fprintf(stderr, "font (%d %d %d) -> (%d %d %d)\n",
 
232
            sys_fontlist[i].fi_fontsize,
 
233
            sys_fontlist[i].fi_maxwidth,
 
234
            sys_fontlist[i].fi_maxheight,
 
235
            sys_fontlist[i].fi_hostfontsize,
 
236
            sys_fontlist[i].fi_width,
 
237
            sys_fontlist[i].fi_height);
 
238
#endif
 
239
        /* load dynamic libraries specified with "-lib" args */
 
240
    for  (nl = sys_externlist; nl; nl = nl->nl_next)
 
241
        if (!sys_load_lib(0, nl->nl_string))
 
242
            post("%s: can't load library", nl->nl_string);
 
243
        /* open patches specifies with "-open" args */
 
244
    for  (nl = sys_openlist; nl; nl = nl->nl_next)
 
245
        openit(cwd, nl->nl_string);
 
246
    namelist_free(sys_openlist);
 
247
    sys_openlist = 0;
 
248
        /* send messages specified with "-send" args */
 
249
    for  (nl = sys_messagelist; nl; nl = nl->nl_next)
 
250
    {
 
251
        t_binbuf *b = binbuf_new();
 
252
        binbuf_text(b, nl->nl_string, strlen(nl->nl_string));
 
253
        binbuf_eval(b, 0, 0, 0);
 
254
        binbuf_free(b);
 
255
    }
 
256
    namelist_free(sys_messagelist);
 
257
    sys_messagelist = 0;
 
258
}
 
259
 
 
260
static void sys_afterargparse(void);
 
261
 
 
262
static void pd_makeversion(void)
 
263
{
 
264
    char foo[100];
 
265
    sprintf(foo,  "Pd version %d.%d-%d%s\n",PD_MAJOR_VERSION,
 
266
        PD_MINOR_VERSION,PD_BUGFIX_VERSION,PD_TEST_VERSION);
 
267
    pd_version = malloc(strlen(foo)+1);
 
268
    strcpy(pd_version, foo);
 
269
}
 
270
 
 
271
/* this is called from main() in s_entry.c */
 
272
int sys_main(int argc, char **argv)
 
273
{
 
274
    int i, noprefs;
 
275
    sys_externalschedlib = 0;
 
276
    sys_extraflags = 0;
 
277
#ifdef PD_DEBUG
 
278
    fprintf(stderr, "Pd: COMPILED FOR DEBUGGING\n");
 
279
#endif
 
280
    pd_init();                                  /* start the message system */
 
281
    sys_findprogdir(argv[0]);                   /* set sys_progname, guipath */
 
282
    for (i = noprefs = 0; i < argc; i++)        /* prescan args for noprefs */
 
283
        if (!strcmp(argv[i], "-noprefs"))
 
284
            noprefs = 1;
 
285
    if (!noprefs)
 
286
        sys_loadpreferences();                  /* load default settings */
 
287
#ifndef MSW
 
288
    if (!noprefs)
 
289
        sys_rcfile();                           /* parse the startup file */
 
290
#endif
 
291
    if (sys_argparse(argc-1, argv+1))           /* parse cmd line */
 
292
        return (1);
 
293
    sys_afterargparse();                    /* post-argparse settings */
 
294
        /* build version string from defines in m_pd.h */
 
295
    pd_makeversion();
 
296
    if (sys_verbose || sys_version) fprintf(stderr, "%scompiled %s %s\n",
 
297
        pd_version, pd_compiletime, pd_compiledate);
 
298
    if (sys_version)    /* if we were just asked our version, exit here. */
 
299
        return (0);
 
300
    if (sys_startgui(sys_guidir->s_name))       /* start the gui */
 
301
        return(1);
 
302
    if (sys_externalschedlib)
 
303
        return (sys_run_scheduler(sys_externalschedlibname,
 
304
            sys_extraflagsstring));
 
305
    else if (sys_batch)
 
306
        return (m_batchmain());
 
307
    else
 
308
    {
 
309
            /* open audio and MIDI */
 
310
        sys_reopen_midi();
 
311
        sys_reopen_audio();
 
312
            /* run scheduler until it quits */
 
313
        return (m_mainloop());
 
314
    }
 
315
}
 
316
 
 
317
static char *(usagemessage[]) = {
 
318
"usage: pd [-flags] [file]...\n",
 
319
"\naudio configuration flags:\n",
 
320
"-r <n>           -- specify sample rate\n",
 
321
"-audioindev ...  -- audio in devices; e.g., \"1,3\" for first and third\n",
 
322
"-audiooutdev ... -- audio out devices (same)\n",
 
323
"-audiodev ...    -- specify input and output together\n",
 
324
"-inchannels ...  -- audio input channels (by device, like \"2\" or \"16,8\")\n",
 
325
"-outchannels ... -- number of audio out channels (same)\n",
 
326
"-channels ...    -- specify both input and output channels\n",
 
327
"-audiobuf <n>    -- specify size of audio buffer in msec\n",
 
328
"-blocksize <n>   -- specify audio I/O block size in sample frames\n",
 
329
"-sleepgrain <n>  -- specify number of milliseconds to sleep when idle\n",
 
330
"-nodac           -- suppress audio output\n",
 
331
"-noadc           -- suppress audio input\n",
 
332
"-noaudio         -- suppress audio input and output (-nosound is synonym) \n",
 
333
"-listdev         -- list audio and MIDI devices\n",
 
334
 
 
335
#ifdef USEAPI_OSS
 
336
"-oss             -- use OSS audio API\n",
 
337
#endif
 
338
 
 
339
#ifdef USEAPI_ALSA
 
340
"-alsa            -- use ALSA audio API\n",
 
341
"-alsaadd <name>  -- add an ALSA device name to list\n",
 
342
#endif
 
343
 
 
344
#ifdef USEAPI_JACK
 
345
"-jack            -- use JACK audio API\n",
 
346
#endif
 
347
 
 
348
#ifdef USEAPI_PORTAUDIO
 
349
#ifdef MSW
 
350
"-asio            -- use ASIO audio driver (via Portaudio)\n",
 
351
"-pa              -- synonym for -asio\n",
 
352
#else
 
353
"-pa              -- use Portaudio API\n",
 
354
#endif
 
355
#endif
 
356
 
 
357
#ifdef USEAPI_MMIO
 
358
"-mmio            -- use MMIO audio API (default for Windows)\n",
 
359
#endif
 
360
"      (default audio API for this platform:  ", API_DEFSTRING, ")\n\n",
 
361
 
 
362
"\nMIDI configuration flags:\n",
 
363
"-midiindev ...   -- midi in device list; e.g., \"1,3\" for first and third\n",
 
364
"-midioutdev ...  -- midi out device list, same format\n",
 
365
"-mididev ...     -- specify -midioutdev and -midiindev together\n",
 
366
"-nomidiin        -- suppress MIDI input\n",
 
367
"-nomidiout       -- suppress MIDI output\n",
 
368
"-nomidi          -- suppress MIDI input and output\n",
 
369
#ifdef USEAPI_ALSA
 
370
"-alsamidi        -- use ALSA midi API\n",
 
371
#endif
 
372
 
 
373
 
 
374
"\nother flags:\n",
 
375
"-path <path>     -- add to file search path\n",
 
376
"-nostdpath       -- don't search standard (\"extra\") directory\n",
 
377
"-stdpath         -- search standard directory (true by default)\n",
 
378
"-helppath <path> -- add to help file search path\n",
 
379
"-open <file>     -- open file(s) on startup\n",
 
380
"-lib <file>      -- load object library(s)\n",
 
381
"-font-size <n>     -- specify default font size in points\n",
 
382
"-font-face <name>  -- specify default font\n",
 
383
"-font-weight <name>-- specify default font weight (normal or bold)\n",
 
384
"-verbose         -- extra printout on startup and when searching for files\n",
 
385
"-version         -- don't run Pd; just print out which version it is \n",
 
386
"-d <n>           -- specify debug level\n",
 
387
"-noloadbang      -- suppress all loadbangs\n",
 
388
"-stderr          -- send printout to standard error instead of GUI\n",
 
389
"-nogui           -- suppress starting the GUI\n",
 
390
"-guiport <n>     -- connect to pre-existing GUI over port <n>\n",
 
391
"-guicmd \"cmd...\" -- start alternatve GUI program (e.g., remote via ssh)\n",
 
392
"-send \"msg...\"   -- send a message at startup, after patches are loaded\n",
 
393
"-noprefs         -- suppress loading preferences on startup\n",
 
394
#ifdef UNISTD
 
395
"-rt or -realtime -- use real-time priority\n",
 
396
"-nrt             -- don't use real-time priority\n",
 
397
#endif
 
398
"-nosleep         -- spin, don't sleep (may lower latency on multi-CPUs)\n",
 
399
"-schedlib <file> -- plug in external scheduler\n",
 
400
"-extraflags <s>  -- string argument to send schedlib\n",
 
401
"-batch           -- run off-line as a batch process\n",
 
402
"-noautopatch     -- defeat auto-patching new from selected objects\n",
 
403
};
 
404
 
 
405
static void sys_parsedevlist(int *np, int *vecp, int max, char *str)
 
406
{
 
407
    int n = 0;
 
408
    while (n < max)
 
409
    {
 
410
        if (!*str) break;
 
411
        else
 
412
        {
 
413
            char *endp;
 
414
            vecp[n] = strtol(str, &endp, 10);
 
415
            if (endp == str)
 
416
                break;
 
417
            n++;
 
418
            if (!endp)
 
419
                break;
 
420
            str = endp + 1;
 
421
        }
 
422
    }
 
423
    *np = n;
 
424
}
 
425
 
 
426
static int sys_getmultidevchannels(int n, int *devlist)
 
427
{
 
428
    int sum = 0;
 
429
    if (n<0)return(-1);
 
430
    if (n==0)return 0;
 
431
    while(n--)sum+=*devlist++;
 
432
    return sum;
 
433
}
 
434
 
 
435
 
 
436
    /* this routine tries to figure out where to find the auxilliary files
 
437
    Pd will need to run.  This is either done by looking at the command line
 
438
    invokation for Pd, or if that fails, by consulting the variable
 
439
    INSTALL_PREFIX.  In MSW, we don't try to use INSTALL_PREFIX. */
 
440
void sys_findprogdir(char *progname)
 
441
{
 
442
    char sbuf[MAXPDSTRING], sbuf2[MAXPDSTRING], *sp;
 
443
    char *lastslash; 
 
444
#ifdef UNISTD
 
445
    struct stat statbuf;
 
446
#endif
 
447
 
 
448
    /* find out by what string Pd was invoked; put answer in "sbuf". */
 
449
#ifdef MSW
 
450
    GetModuleFileName(NULL, sbuf2, sizeof(sbuf2));
 
451
    sbuf2[MAXPDSTRING-1] = 0;
 
452
    sys_unbashfilename(sbuf2, sbuf);
 
453
#endif /* MSW */
 
454
#ifdef UNISTD
 
455
    strncpy(sbuf, progname, MAXPDSTRING);
 
456
    sbuf[MAXPDSTRING-1] = 0;
 
457
#endif
 
458
    lastslash = strrchr(sbuf, '/');
 
459
    if (lastslash)
 
460
    {
 
461
            /* bash last slash to zero so that sbuf is directory pd was in,
 
462
                e.g., ~/pd/bin */
 
463
        *lastslash = 0; 
 
464
            /* go back to the parent from there, e.g., ~/pd */
 
465
        lastslash = strrchr(sbuf, '/');
 
466
        if (lastslash)
 
467
        {
 
468
            strncpy(sbuf2, sbuf, lastslash-sbuf);
 
469
            sbuf2[lastslash-sbuf] = 0;
 
470
        }
 
471
        else strcpy(sbuf2, "..");
 
472
    }
 
473
    else
 
474
    {
 
475
            /* no slashes found.  Try INSTALL_PREFIX. */
 
476
#ifdef INSTALL_PREFIX
 
477
        strcpy(sbuf2, INSTALL_PREFIX);
 
478
#else
 
479
        strcpy(sbuf2, ".");
 
480
#endif
 
481
    }
 
482
        /* now we believe sbuf2 holds the parent directory of the directory
 
483
        pd was found in.  We now want to infer the "lib" directory and the
 
484
        "gui" directory.  In "simple" unix installations, the layout is
 
485
            .../bin/pd
 
486
            .../bin/pd-gui
 
487
            .../doc
 
488
        and in "complicated" unix installations, it's:
 
489
            .../bin/pd
 
490
            .../lib/pd/bin/pd-gui
 
491
            .../lib/pd/doc
 
492
        To decide which, we stat .../lib/pd; if that exists, we assume it's
 
493
        the complicated layout.  In MSW, it's the "simple" layout, but
 
494
        the gui program is straight wish80:
 
495
            .../bin/pd
 
496
            .../bin/wish80.exe
 
497
            .../doc
 
498
        */
 
499
#ifdef MSW
 
500
    sys_libdir = gensym(sbuf2);
 
501
    sys_guidir = &s_;   /* in MSW the guipath just depends on the libdir */
 
502
#else
 
503
    strncpy(sbuf, sbuf2, MAXPDSTRING-30);
 
504
    sbuf[MAXPDSTRING-30] = 0;
 
505
    strcat(sbuf, "/lib/pd");
 
506
    if (stat(sbuf, &statbuf) >= 0)
 
507
    {
 
508
            /* complicated layout: lib dir is the one we just stat-ed above */
 
509
        sys_libdir = gensym(sbuf);
 
510
            /* gui lives in .../lib/pd/bin */
 
511
        strncpy(sbuf, sbuf2, MAXPDSTRING-30);
 
512
        sbuf[MAXPDSTRING-30] = 0;
 
513
        strcat(sbuf, "/lib/pd/bin");
 
514
        sys_guidir = gensym(sbuf);
 
515
    }
 
516
    else
 
517
    {
 
518
            /* simple layout: lib dir is the parent */
 
519
        sys_libdir = gensym(sbuf2);
 
520
            /* gui lives in .../bin */
 
521
        strncpy(sbuf, sbuf2, MAXPDSTRING-30);
 
522
        sbuf[MAXPDSTRING-30] = 0;
 
523
        strcat(sbuf, "/bin");
 
524
        sys_guidir = gensym(sbuf);
 
525
    }
 
526
#endif
 
527
}
 
528
 
 
529
#ifdef MSW
 
530
static int sys_mmio = 1;
 
531
#else
 
532
static int sys_mmio = 0;
 
533
#endif
 
534
 
 
535
int sys_argparse(int argc, char **argv)
 
536
{
 
537
    char sbuf[MAXPDSTRING];
 
538
    int i;
 
539
    while ((argc > 0) && **argv == '-')
 
540
    {
 
541
        if (!strcmp(*argv, "-r") && argc > 1 &&
 
542
            sscanf(argv[1], "%d", &sys_main_srate) >= 1)
 
543
        {
 
544
            argc -= 2;
 
545
            argv += 2;
 
546
        }
 
547
        else if (!strcmp(*argv, "-inchannels") && (argc > 1))
 
548
        {
 
549
            sys_parsedevlist(&sys_nchin,
 
550
                sys_chinlist, MAXAUDIOINDEV, argv[1]);
 
551
 
 
552
          if (!sys_nchin)
 
553
              goto usage;
 
554
 
 
555
          argc -= 2; argv += 2;
 
556
        }
 
557
        else if (!strcmp(*argv, "-outchannels") && (argc > 1))
 
558
        {
 
559
            sys_parsedevlist(&sys_nchout, sys_choutlist,
 
560
                MAXAUDIOOUTDEV, argv[1]);
 
561
 
 
562
          if (!sys_nchout)
 
563
            goto usage;
 
564
 
 
565
          argc -= 2; argv += 2;
 
566
        }
 
567
        else if (!strcmp(*argv, "-channels") && (argc > 1))
 
568
        {
 
569
            sys_parsedevlist(&sys_nchin, sys_chinlist,MAXAUDIOINDEV,
 
570
                argv[1]);
 
571
            sys_parsedevlist(&sys_nchout, sys_choutlist,MAXAUDIOOUTDEV,
 
572
                argv[1]);
 
573
 
 
574
            if (!sys_nchout)
 
575
              goto usage;
 
576
 
 
577
            argc -= 2; argv += 2;
 
578
        }
 
579
        else if (!strcmp(*argv, "-soundbuf") || !strcmp(*argv, "-audiobuf") && (argc > 1))
 
580
        {
 
581
            sys_main_advance = atoi(argv[1]);
 
582
            argc -= 2; argv += 2;
 
583
        }
 
584
        else if (!strcmp(*argv, "-callback"))
 
585
        {
 
586
            sys_main_callback = 1;
 
587
            argc--; argv++;
 
588
        }
 
589
        else if (!strcmp(*argv, "-blocksize"))
 
590
        {
 
591
            sys_setblocksize(atoi(argv[1]));
 
592
            argc -= 2; argv += 2;
 
593
        }
 
594
        else if (!strcmp(*argv, "-sleepgrain") && (argc > 1))
 
595
        {
 
596
            sys_sleepgrain = 1000 * atof(argv[1]);
 
597
            argc -= 2; argv += 2;
 
598
        }
 
599
        else if (!strcmp(*argv, "-nodac"))
 
600
        {
 
601
            sys_nsoundout=0;
 
602
            sys_nchout = 0;
 
603
            argc--; argv++;
 
604
        }
 
605
        else if (!strcmp(*argv, "-noadc"))
 
606
        {
 
607
            sys_nsoundin=0;
 
608
            sys_nchin = 0;
 
609
            argc--; argv++;
 
610
        }
 
611
        else if (!strcmp(*argv, "-nosound") || !strcmp(*argv, "-noaudio"))
 
612
        {
 
613
            sys_nsoundin=sys_nsoundout = 0;
 
614
            sys_nchin = sys_nchout = 0;
 
615
            argc--; argv++;
 
616
        }
 
617
#ifdef USEAPI_OSS
 
618
        else if (!strcmp(*argv, "-oss"))
 
619
        {
 
620
            sys_set_audio_api(API_OSS);
 
621
            argc--; argv++;
 
622
        }
 
623
#endif
 
624
#ifdef USEAPI_ALSA
 
625
        else if (!strcmp(*argv, "-alsa"))
 
626
        {
 
627
            sys_set_audio_api(API_ALSA);
 
628
            argc--; argv++;
 
629
        }
 
630
        else if (!strcmp(*argv, "-alsaadd") && (argc > 1))
 
631
        {
 
632
            if (argc > 1)
 
633
                alsa_adddev(argv[1]);
 
634
            else goto usage;
 
635
            argc -= 2; argv +=2;
 
636
        }
 
637
        else if (!strcmp(*argv, "-alsamidi"))
 
638
        {
 
639
          sys_set_midi_api(API_ALSA);
 
640
            argc--; argv++;
 
641
        }
 
642
#endif
 
643
#ifdef USEAPI_JACK
 
644
        else if (!strcmp(*argv, "-jack"))
 
645
        {
 
646
            sys_set_audio_api(API_JACK);
 
647
            argc--; argv++;
 
648
        }
 
649
#endif
 
650
#ifdef USEAPI_PORTAUDIO
 
651
        else if (!strcmp(*argv, "-pa") || !strcmp(*argv, "-portaudio")
 
652
#ifdef MSW
 
653
            || !strcmp(*argv, "-asio")
 
654
#endif
 
655
            )
 
656
        {
 
657
            sys_set_audio_api(API_PORTAUDIO);
 
658
            sys_mmio = 0;
 
659
            argc--; argv++;
 
660
        }
 
661
#endif
 
662
#ifdef USEAPI_MMIO
 
663
        else if (!strcmp(*argv, "-mmio"))
 
664
        {
 
665
            sys_set_audio_api(API_MMIO);
 
666
            sys_mmio = 1;
 
667
            argc--; argv++;
 
668
        }
 
669
#endif
 
670
        else if (!strcmp(*argv, "-nomidiin"))
 
671
        {
 
672
            sys_nmidiin = 0;
 
673
            argc--; argv++;
 
674
        }
 
675
        else if (!strcmp(*argv, "-nomidiout"))
 
676
        {
 
677
            sys_nmidiout = 0;
 
678
            argc--; argv++;
 
679
        }
 
680
        else if (!strcmp(*argv, "-nomidi"))
 
681
        {
 
682
            sys_nmidiin = sys_nmidiout = 0;
 
683
            argc--; argv++;
 
684
        }
 
685
        else if (!strcmp(*argv, "-midiindev"))
 
686
        {
 
687
            sys_parsedevlist(&sys_nmidiin, sys_midiindevlist, MAXMIDIINDEV,
 
688
                argv[1]);
 
689
            if (!sys_nmidiin)
 
690
                goto usage;
 
691
            argc -= 2; argv += 2;
 
692
        }
 
693
        else if (!strcmp(*argv, "-midioutdev") && (argc > 1))
 
694
        {
 
695
            sys_parsedevlist(&sys_nmidiout, sys_midioutdevlist, MAXMIDIOUTDEV,
 
696
                argv[1]);
 
697
            if (!sys_nmidiout)
 
698
                goto usage;
 
699
            argc -= 2; argv += 2;
 
700
        }
 
701
        else if (!strcmp(*argv, "-mididev") && (argc > 1))
 
702
        {
 
703
            sys_parsedevlist(&sys_nmidiin, sys_midiindevlist, MAXMIDIINDEV,
 
704
                argv[1]);
 
705
            sys_parsedevlist(&sys_nmidiout, sys_midioutdevlist, MAXMIDIOUTDEV,
 
706
                argv[1]);
 
707
            if (!sys_nmidiout)
 
708
                goto usage;
 
709
            argc -= 2; argv += 2;
 
710
        }
 
711
        else if (!strcmp(*argv, "-path") && (argc > 1))
 
712
        {
 
713
            sys_searchpath = namelist_append_files(sys_searchpath, argv[1]);
 
714
            argc -= 2; argv += 2;
 
715
        }
 
716
        else if (!strcmp(*argv, "-nostdpath"))
 
717
        {
 
718
            sys_usestdpath = 0;
 
719
            argc--; argv++;
 
720
        }
 
721
        else if (!strcmp(*argv, "-stdpath"))
 
722
        {
 
723
            sys_usestdpath = 1;
 
724
            argc--; argv++;
 
725
        }
 
726
        else if (!strcmp(*argv, "-helppath"))
 
727
        {
 
728
            sys_helppath = namelist_append_files(sys_helppath, argv[1]);
 
729
            argc -= 2; argv += 2;
 
730
        }
 
731
        else if (!strcmp(*argv, "-open") && argc > 1)
 
732
        {
 
733
            sys_openlist = namelist_append_files(sys_openlist, argv[1]);
 
734
            argc -= 2; argv += 2;
 
735
        }
 
736
        else if (!strcmp(*argv, "-lib") && argc > 1)
 
737
        {
 
738
            sys_externlist = namelist_append_files(sys_externlist, argv[1]);
 
739
            argc -= 2; argv += 2;
 
740
        }
 
741
        else if ((!strcmp(*argv, "-font-size") || !strcmp(*argv, "-font"))
 
742
            && argc > 1)
 
743
        {
 
744
            sys_defaultfont = sys_nearestfontsize(atoi(argv[1]));
 
745
            argc -= 2;
 
746
            argv += 2;
 
747
        }
 
748
        else if ((!strcmp(*argv, "-font-face") || !strcmp(*argv, "-typeface"))
 
749
            && argc > 1)
 
750
        {
 
751
            strncpy(sys_font,*(argv+1),sizeof(sys_font)-1);
 
752
            sys_font[sizeof(sys_font)-1] = 0;
 
753
            argc -= 2;
 
754
            argv += 2;
 
755
        }
 
756
        else if (!strcmp(*argv, "-font-weight") && argc > 1)
 
757
        {
 
758
            strncpy(sys_fontweight,*(argv+1),sizeof(sys_fontweight)-1);
 
759
            sys_fontweight[sizeof(sys_fontweight)-1] = 0;
 
760
            argc -= 2;
 
761
            argv += 2;
 
762
        }
 
763
        else if (!strcmp(*argv, "-verbose"))
 
764
        {
 
765
            sys_verbose++;
 
766
            argc--; argv++;
 
767
        }
 
768
        else if (!strcmp(*argv, "-version"))
 
769
        {
 
770
            sys_version = 1;
 
771
            argc--; argv++;
 
772
        }
 
773
        else if (!strcmp(*argv, "-d") && argc > 1 &&
 
774
            sscanf(argv[1], "%d", &sys_debuglevel) >= 1)
 
775
        {
 
776
            argc -= 2;
 
777
            argv += 2;
 
778
        }
 
779
        else if (!strcmp(*argv, "-noloadbang"))
 
780
        {
 
781
            sys_noloadbang = 1;
 
782
            argc--; argv++;
 
783
        }
 
784
        else if (!strcmp(*argv, "-nogui"))
 
785
        {
 
786
            sys_printtostderr = sys_nogui = 1;
 
787
            argc--; argv++;
 
788
        }
 
789
        else if (!strcmp(*argv, "-guiport") && argc > 1 &&
 
790
            sscanf(argv[1], "%d", &sys_guisetportnumber) >= 1)
 
791
        {
 
792
            argc -= 2;
 
793
            argv += 2;
 
794
        }
 
795
        else if (!strcmp(*argv, "-stderr"))
 
796
        {
 
797
            sys_printtostderr = 1;
 
798
            argc--; argv++;
 
799
        }
 
800
        else if (!strcmp(*argv, "-guicmd") && argc > 1)
 
801
        {
 
802
            sys_guicmd = argv[1];
 
803
            argc -= 2; argv += 2;
 
804
        }
 
805
        else if (!strcmp(*argv, "-send") && argc > 1)
 
806
        {
 
807
            sys_messagelist = namelist_append(sys_messagelist, argv[1], 1);
 
808
            argc -= 2; argv += 2;
 
809
        }
 
810
        else if (!strcmp(*argv, "-listdev"))
 
811
        {
 
812
            sys_listplease = 1;
 
813
            argc--; argv++;
 
814
        }
 
815
        else if (!strcmp(*argv, "-schedlib") && argc > 1)
 
816
        {
 
817
            sys_externalschedlib = 1;
 
818
            strncpy(sys_externalschedlibname, argv[1],
 
819
                sizeof(sys_externalschedlibname) - 1);
 
820
            argv += 2;
 
821
            argc -= 2;
 
822
        }
 
823
        else if (!strcmp(*argv, "-extraflags") && argc > 1)
 
824
        {
 
825
            sys_extraflags = 1;
 
826
            strncpy(sys_extraflagsstring, argv[1],
 
827
                sizeof(sys_extraflagsstring) - 1);
 
828
            argv += 2;
 
829
            argc -= 2;
 
830
        }
 
831
        else if (!strcmp(*argv, "-batch"))
 
832
        {
 
833
            sys_batch = 1;
 
834
            sys_printtostderr = sys_nogui = 1;
 
835
            argc--; argv++;
 
836
        }
 
837
        else if (!strcmp(*argv, "-noautopatch"))
 
838
        {
 
839
            sys_noautopatch = 1;
 
840
            argc--; argv++;
 
841
        }
 
842
#ifdef UNISTD
 
843
        else if (!strcmp(*argv, "-rt") || !strcmp(*argv, "-realtime"))
 
844
        {
 
845
            sys_hipriority = 1;
 
846
            argc--; argv++;
 
847
        }
 
848
        else if (!strcmp(*argv, "-nrt"))
 
849
        {
 
850
            sys_hipriority = 0;
 
851
            argc--; argv++;
 
852
        }
 
853
#endif
 
854
        else if (!strcmp(*argv, "-nosleep"))
 
855
        {
 
856
            sys_nosleep = 1;
 
857
            argc--; argv++;
 
858
        }
 
859
        else if (!strcmp(*argv, "-soundindev") ||
 
860
            !strcmp(*argv, "-audioindev"))
 
861
        {
 
862
            sys_parsedevlist(&sys_nsoundin, sys_soundindevlist,
 
863
                MAXAUDIOINDEV, argv[1]);
 
864
            if (!sys_nsoundin)
 
865
                goto usage;
 
866
            argc -= 2; argv += 2;
 
867
        }
 
868
        else if (!strcmp(*argv, "-soundoutdev") ||
 
869
            !strcmp(*argv, "-audiooutdev"))
 
870
        {
 
871
            sys_parsedevlist(&sys_nsoundout, sys_soundoutdevlist,
 
872
                MAXAUDIOOUTDEV, argv[1]);
 
873
            if (!sys_nsoundout)
 
874
                goto usage;
 
875
            argc -= 2; argv += 2;
 
876
        }
 
877
        else if ((!strcmp(*argv, "-sounddev") || !strcmp(*argv, "-audiodev"))
 
878
                 && (argc > 1))
 
879
        {
 
880
            sys_parsedevlist(&sys_nsoundin, sys_soundindevlist,
 
881
                MAXAUDIOINDEV, argv[1]);
 
882
            sys_parsedevlist(&sys_nsoundout, sys_soundoutdevlist,
 
883
                MAXAUDIOOUTDEV, argv[1]);
 
884
            if (!sys_nsoundout)
 
885
                goto usage;
 
886
            argc -= 2; argv += 2;
 
887
        }
 
888
        else if (!strcmp(*argv, "-noprefs")) /* did this earlier */
 
889
            argc--, argv++;
 
890
        else
 
891
        {
 
892
            unsigned int i;
 
893
        usage:
 
894
            for (i = 0; i < sizeof(usagemessage)/sizeof(*usagemessage); i++)
 
895
                fprintf(stderr, "%s", usagemessage[i]);
 
896
            return (1);
 
897
        }
 
898
    }
 
899
    if (!sys_defaultfont)
 
900
        sys_defaultfont = DEFAULTFONT;
 
901
    for (; argc > 0; argc--, argv++) 
 
902
        sys_openlist = namelist_append_files(sys_openlist, *argv);
 
903
 
 
904
 
 
905
    return (0);
 
906
}
 
907
 
 
908
int sys_getblksize(void)
 
909
{
 
910
    return (DEFDACBLKSIZE);
 
911
}
 
912
 
 
913
    /* stuff to do, once, after calling sys_argparse() -- which may itself
 
914
    be called more than once (first from "settings, second from .pdrc, then
 
915
    from command-line arguments */
 
916
static void sys_afterargparse(void)
 
917
{
 
918
    char sbuf[MAXPDSTRING];
 
919
    int i;
 
920
    int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV];
 
921
    int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV];
 
922
    int nchindev, nchoutdev, rate, advance, callback;
 
923
    int nmidiindev = 0, midiindev[MAXMIDIINDEV];
 
924
    int nmidioutdev = 0, midioutdev[MAXMIDIOUTDEV];
 
925
            /* add "extra" library to path */
 
926
    strncpy(sbuf, sys_libdir->s_name, MAXPDSTRING-30);
 
927
    sbuf[MAXPDSTRING-30] = 0;
 
928
    strcat(sbuf, "/extra");
 
929
    sys_setextrapath(sbuf);
 
930
            /* add "doc/5.reference" library to helppath */
 
931
    strncpy(sbuf, sys_libdir->s_name, MAXPDSTRING-30);
 
932
    sbuf[MAXPDSTRING-30] = 0;
 
933
    strcat(sbuf, "/doc/5.reference");
 
934
    sys_helppath = namelist_append_files(sys_helppath, sbuf);
 
935
        /* correct to make audio and MIDI device lists zero based.  On
 
936
        MMIO, however, "1" really means the second device (the first one
 
937
        is "mapper" which is was not included when the command args were
 
938
        set up, so we leave it that way for compatibility. */
 
939
    if (!sys_mmio)
 
940
    {
 
941
        for (i = 0; i < sys_nsoundin; i++)
 
942
            sys_soundindevlist[i]--;
 
943
        for (i = 0; i < sys_nsoundout; i++)
 
944
            sys_soundoutdevlist[i]--;
 
945
    }
 
946
    for (i = 0; i < sys_nmidiin; i++)
 
947
        sys_midiindevlist[i]--;
 
948
    for (i = 0; i < sys_nmidiout; i++)
 
949
        sys_midioutdevlist[i]--;
 
950
    if (sys_listplease)
 
951
        sys_listdevs();
 
952
        
 
953
            /* get the current audio parameters.  These are set
 
954
            by the preferences mechanism (sys_loadpreferences()) or
 
955
            else are the default.  Overwrite them with any results
 
956
            of argument parsing, and store them again. */
 
957
    sys_get_audio_params(&naudioindev, audioindev, chindev,
 
958
        &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback);
 
959
    if (sys_nchin >= 0)
 
960
    {
 
961
        nchindev = sys_nchin;
 
962
        for (i = 0; i < nchindev; i++)
 
963
            chindev[i] = sys_chinlist[i];
 
964
    }
 
965
    else nchindev = naudioindev;
 
966
    if (sys_nsoundin >= 0)
 
967
    {
 
968
        naudioindev = sys_nsoundin;
 
969
        for (i = 0; i < naudioindev; i++)
 
970
            audioindev[i] = sys_soundindevlist[i];
 
971
    }
 
972
    
 
973
    if (sys_nchout >= 0)
 
974
    {
 
975
        nchoutdev = sys_nchout;
 
976
        for (i = 0; i < nchoutdev; i++)
 
977
            choutdev[i] = sys_choutlist[i];
 
978
    }
 
979
    else nchoutdev = naudiooutdev;
 
980
    if (sys_nsoundout >= 0)
 
981
    {
 
982
        naudiooutdev = sys_nsoundout;
 
983
        for (i = 0; i < naudiooutdev; i++)
 
984
            audiooutdev[i] = sys_soundoutdevlist[i];
 
985
    }
 
986
    sys_get_midi_params(&nmidiindev, midiindev, &nmidioutdev, midioutdev);
 
987
    if (sys_nmidiin >= 0)
 
988
    {
 
989
        post("sys_nmidiin %d, nmidiindev %d", sys_nmidiin, nmidiindev);
 
990
        nmidiindev = sys_nmidiin;
 
991
        for (i = 0; i < nmidiindev; i++)
 
992
            midiindev[i] = sys_midiindevlist[i];
 
993
    }
 
994
    if (sys_nmidiout >= 0)
 
995
    {
 
996
        nmidioutdev = sys_nmidiout;
 
997
        for (i = 0; i < nmidioutdev; i++)
 
998
            midioutdev[i] = sys_midioutdevlist[i];
 
999
    }
 
1000
    if (sys_main_advance)
 
1001
        advance = sys_main_advance;
 
1002
    if (sys_main_srate)
 
1003
        rate = sys_main_srate;
 
1004
    if (sys_main_callback)
 
1005
        callback = sys_main_callback;
 
1006
    sys_set_audio_settings(naudioindev, audioindev, nchindev, chindev,
 
1007
        naudiooutdev, audiooutdev, nchoutdev, choutdev, rate, advance, 
 
1008
        callback);
 
1009
    sys_open_midi(nmidiindev, midiindev, nmidioutdev, midioutdev, 0);
 
1010
}
 
1011
 
 
1012
static void sys_addreferencepath(void)
 
1013
{
 
1014
    char sbuf[MAXPDSTRING];
 
1015
}