aboutsummaryrefslogtreecommitdiff
path: root/pd/src/s_file.c
diff options
context:
space:
mode:
Diffstat (limited to 'pd/src/s_file.c')
-rw-r--r--pd/src/s_file.c472
1 files changed, 445 insertions, 27 deletions
diff --git a/pd/src/s_file.c b/pd/src/s_file.c
index 27825d59..ca0512fc 100644
--- a/pd/src/s_file.c
+++ b/pd/src/s_file.c
@@ -1,55 +1,473 @@
-/* Copyright (c) 1997-1999 Miller Puckette.
+/* Copyright (c) 1997-2004 Miller Puckette.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
/*
- * this file contains file-handling routines.
+ * this file implements a mechanism for storing and retrieving preferences.
+ * Should later be renamed "preferences.c" or something.
+ *
+ * In unix this is handled by the "~/.pdsettings" file, in windows by
+ * the registry, and in MacOS by the Preferences system.
*/
#include "m_pd.h"
#include "s_stuff.h"
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#ifdef UNISTD
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#endif
+#ifdef MSW
+#include <windows.h>
+#include <tchar.h>
+#endif
+
+int sys_defeatrt;
+t_symbol *sys_flags = &s_;
+void sys_doflags( void);
- /* LATER delete this? -- replaced by find_via_path() in s_path.c */
-int sys_isreadablefile(const char *s)
-{
- struct stat statbuf;
- int mode;
- if (stat(s, &statbuf) < 0) return (0);
#ifdef UNIX
- mode = statbuf.st_mode;
- if (S_ISDIR(mode)) return (0);
-#endif
+
+static char *sys_prefbuf;
+static int sys_prefbufsize;
+
+static void sys_initloadpreferences( void)
+{
+ char filenamebuf[MAXPDSTRING], *homedir = getenv("HOME");
+ int fd, length;
+
+ if (!homedir)
+ return;
+ snprintf(filenamebuf, MAXPDSTRING, "%s/.pdsettings", homedir);
+ filenamebuf[MAXPDSTRING-1] = 0;
+ if ((fd = open(filenamebuf, 0)) < 0)
+ {
+ if (sys_verbose)
+ perror(filenamebuf);
+ return;
+ }
+ length = lseek(fd, 0, 2);
+ if (length < 0)
+ {
+ if (sys_verbose)
+ perror(filenamebuf);
+ close(fd);
+ return;
+ }
+ lseek(fd, 0, 0);
+ if (!(sys_prefbuf = malloc(length + 2)))
+ {
+ error("couldn't allocate memory for preferences buffer");
+ close(fd);
+ return;
+ }
+ sys_prefbuf[0] = '\n';
+ if (read(fd, sys_prefbuf+1, length) < length)
+ {
+ perror(filenamebuf);
+ sys_prefbuf[0] = 0;
+ close(fd);
+ return;
+ }
+ sys_prefbuf[length+1] = 0;
+ close(fd);
+ if (sys_verbose)
+ post("success reading preferences from: %s", filenamebuf);
+}
+
+static int sys_getpreference(const char *key, char *value, int size)
+{
+ if (!sys_prefbuf)
+ return (0);
+ char searchfor[80], *where, *whereend;
+ sprintf(searchfor, "\n%s:", key);
+ where = strstr(sys_prefbuf, searchfor);
+ if (!where)
+ return (0);
+ where += strlen(searchfor);
+ while (*where == ' ' || *where == '\t')
+ where++;
+ for (whereend = where; *whereend && *whereend != '\n'; whereend++)
+ ;
+ if (*whereend == '\n')
+ whereend--;
+ if (whereend > where + size - 1)
+ whereend = where + size - 1;
+ strncpy(value, where, whereend+1-where);
+ value[whereend+1-where] = 0;
return (1);
}
- /* change '/' characters to the system's native file separator */
-void sys_bashfilename(const char *from, char *to)
+static void sys_doneloadpreferences( void)
+{
+ if (sys_prefbuf)
+ free(sys_prefbuf);
+}
+
+static FILE *sys_prefsavefp;
+
+static void sys_initsavepreferences( void)
{
- char c;
- while (c = *from++)
+ char filenamebuf[MAXPDSTRING], errbuf[MAXPDSTRING],
+ *homedir = getenv("HOME");
+ FILE *fp;
+
+ if (!homedir)
+ return;
+ snprintf(filenamebuf, MAXPDSTRING, "%s/.pdsettings", homedir);
+ filenamebuf[MAXPDSTRING-1] = 0;
+ if ((sys_prefsavefp = fopen(filenamebuf, "w")) == NULL)
{
+ snprintf(errbuf, MAXPDSTRING, "%s: %s",filenamebuf, strerror(errno));
+ pd_error(0, errbuf);
+ }
+}
+
+static void sys_putpreference(const char *key, const char *value)
+{
+ if (sys_prefsavefp)
+ fprintf(sys_prefsavefp, "%s: %s\n",
+ key, value);
+}
+
+static void sys_donesavepreferences( void)
+{
+ if (sys_prefsavefp)
+ {
+ fclose(sys_prefsavefp);
+ sys_prefsavefp = 0;
+ }
+}
+
+#endif /* UNIX */
+
#ifdef MSW
- if (c == '/') c = '\\';
-#endif
- *to++ = c;
+
+static void sys_initloadpreferences( void)
+{
+ fprintf(stderr, "here 1\n");
+}
+
+static int sys_getpreference(const char *key, char *value, int size)
+{
+ HKEY *hkey;
+ DWORD bigsize = size;
+ char *val2 = value;
+ LONG err = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ "Software\\Pd", 0, KEY_QUERY_VALUE, &hkey);
+ if (err != ERROR_SUCCESS)
+ {
+ fprintf(stderr, "here 3\n");
+ return (0);
}
- *to = 0;
+ err = RegQueryValueEx(hkey, key, 0, 0, value, &bigsize);
+ if (err != ERROR_SUCCESS)
+ {
+ fprintf(stderr, "here 4\n");
+ RegCloseKey(hkey);
+ return (0);
+ }
+ fprintf(stderr, "here 5\n");
+ if (val2 != value)
+ fprintf(stderr, "string moved for registry key %s", key);
+ RegCloseKey(hkey);
+ return (1);
+}
+
+static void sys_doneloadpreferences( void)
+{
+ fprintf(stderr, "here 2\n");
}
+static void sys_initsavepreferences( void)
+{
+}
- /* change the system's native file separator to '/' characters */
-void sys_unbashfilename(const char *from, char *to)
+static void sys_putpreference(const char *key, const char *value)
{
- char c;
- while (c = *from++)
+ HKEY *hkey;
+ LONG err = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
+ "Software\\Pd", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE,
+ NULL, &hkey, NULL);
+ if (err != ERROR_SUCCESS)
{
+ post("unable to create registry entry: %s\n", key);
+ return;
+ }
+ err = RegSetValueEx(hkey, key, 0, REG_SZ, value, strlen(value)+1);
+ if (err != ERROR_SUCCESS)
+ post("unable to set registry entry: %s\n", key);
+ RegCloseKey(hkey);
+}
+
+static void sys_donesavepreferences( void)
+{
+}
+
+#endif /* MSW */
+
+#ifdef MACOSX
+
+static void sys_initloadpreferences( void)
+{
+}
+
+static int sys_getpreference(const char *key, char *value, int size)
+{
+ char cmdbuf[256];
+ int nread = 0, nleft = size;
+ snprintf(cmdbuf, 256, "defaults read com.ucsd.pd %s 2> /dev/null\n", key);
+ FILE *fp = popen(cmdbuf, "r");
+ while (nread < size)
+ {
+ int newread = fread(value+nread, 1, size-nread, fp);
+ if (newread <= 0)
+ break;
+ nread += newread;
+ }
+ pclose(fp);
+ if (!nread)
+ return (0);
+ if (nread >= size)
+ nread = size-1;
+ value[nread] = 0;
+ return(1);
+}
+
+static void sys_doneloadpreferences( void)
+{
+}
+
+static void sys_initsavepreferences( void)
+{
+}
+
+static void sys_putpreference(const char *key, const char *value)
+{
+ char cmdbuf[MAXPDSTRING];
+ snprintf(cmdbuf, MAXPDSTRING,
+ "defaults write com.ucsd.pd %s \"%s\" 2> /dev/null\n", key, value);
+ system(cmdbuf);
+}
+
+static void sys_donesavepreferences( void)
+{
+}
+
+#endif /* MACOSX */
+
+void sys_loadpreferences( void)
+{
+ int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV];
+ int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV];
+ int nmidiindev, midiindev[MAXMIDIINDEV];
+ int nmidioutdev, midioutdev[MAXMIDIOUTDEV];
+ int i, rate = 0, advance = 0, api, nolib;
+ char prefbuf[MAXPDSTRING], keybuf[80];
+ sys_initloadpreferences();
+ /* load audio preferences */
+ if (sys_getpreference("audioapi", prefbuf, MAXPDSTRING)
+ && sscanf(prefbuf, "%d", &api) > 0)
+ sys_set_audio_api(api);
+ if (sys_getpreference("noaudioin", prefbuf, MAXPDSTRING))
+ naudioindev = 0;
+ else
+ {
+ for (i = 0, naudioindev = 0; i < MAXAUDIOINDEV; i++)
+ {
+ sprintf(keybuf, "audioindev%d", i+1);
+ if (!sys_getpreference(keybuf, prefbuf, MAXPDSTRING))
+ break;
+ if (sscanf(prefbuf, "%d %d", &audioindev[i], &chindev[i]) < 2)
+ break;
+ naudioindev++;
+ }
+ /* if no preferences at all, set -1 for default behavior */
+ if (naudioindev == 0)
+ naudioindev = -1;
+ }
+ if (sys_getpreference("noaudioout", prefbuf, MAXPDSTRING))
+ naudiooutdev = 0;
+ else
+ {
+ for (i = 0, naudiooutdev = 0; i < MAXAUDIOOUTDEV; i++)
+ {
+ sprintf(keybuf, "audiooutdev%d", i+1);
+ if (!sys_getpreference(keybuf, prefbuf, MAXPDSTRING))
+ break;
+ if (sscanf(prefbuf, "%d %d", &audiooutdev[i], &choutdev[i]) < 2)
+ break;
+ naudiooutdev++;
+ }
+ if (naudiooutdev == 0)
+ naudiooutdev = -1;
+ }
+ if (sys_getpreference("rate", prefbuf, MAXPDSTRING))
+ sscanf(prefbuf, "%d", &rate);
+ if (sys_getpreference("audiobuf", prefbuf, MAXPDSTRING))
+ sscanf(prefbuf, "%d", &advance);
+ sys_open_audio(naudioindev, audioindev, naudioindev, chindev,
+ naudiooutdev, audiooutdev, naudiooutdev, choutdev, rate, advance, 0);
+
+ /* load MIDI preferences */
+ for (i = 0, nmidiindev = 0; i < MAXMIDIINDEV; i++)
+ {
+ sprintf(keybuf, "midiindev%d", i+1);
+ if (!sys_getpreference(keybuf, prefbuf, MAXPDSTRING))
+ break;
+ if (sscanf(prefbuf, "%d %d", &midiindev[i], &chindev[i]) < 2)
+ break;
+ nmidiindev++;
+ }
+ for (i = 0, nmidioutdev = 0; i < MAXMIDIOUTDEV; i++)
+ {
+ sprintf(keybuf, "midioutdev%d", i+1);
+ if (!sys_getpreference(keybuf, prefbuf, MAXPDSTRING))
+ break;
+ if (sscanf(prefbuf, "%d %d", &midioutdev[i], &choutdev[i]) < 2)
+ break;
+ nmidioutdev++;
+ }
+ sys_open_midi(nmidiindev, midiindev, nmidioutdev, midioutdev, 0);
+ /* search path */
+ for (i = 0; 1; i++)
+ {
+ sprintf(keybuf, "path%d", i+1);
+ if (!sys_getpreference(keybuf, prefbuf, MAXPDSTRING))
+ break;
+ sys_searchpath = namelist_append_files(sys_searchpath, prefbuf);
+ }
+ if (sys_getpreference("standardpath", prefbuf, MAXPDSTRING))
+ sscanf(prefbuf, "%d", &sys_usestdpath);
+ if (sys_getpreference("verbose", prefbuf, MAXPDSTRING))
+ sscanf(prefbuf, "%d", &sys_verbose);
+
+ /* startup settings */
+ for (i = 0; 1; i++)
+ {
+ sprintf(keybuf, "loadlib%d", i+1);
+ if (!sys_getpreference(keybuf, prefbuf, MAXPDSTRING))
+ break;
+ sys_externlist = namelist_append_files(sys_externlist, prefbuf);
+ }
+ if (sys_getpreference("defeatrt", prefbuf, MAXPDSTRING))
+ sscanf(prefbuf, "%d", &sys_defeatrt);
+ if (sys_getpreference("flags", prefbuf, MAXPDSTRING))
+ {
+ if (strcmp(prefbuf, "."))
+ sys_flags = gensym(prefbuf);
+ }
+ sys_doflags();
+
+ if (sys_defeatrt)
+ sys_hipriority = 0;
+ else
+#ifdef UNIX
+ sys_hipriority = !geteuid();
+#else
#ifdef MSW
- if (c == '\\') c = '/';
+ sys_hipriority = 0;
+#else
+ sys_hipriority = 1;
+#endif
#endif
- *to++ = c;
- }
- *to = 0;
}
+void glob_savepreferences(t_pd *dummy)
+{
+ int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV];
+ int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV];
+ int i, rate, advance;
+ char buf1[MAXPDSTRING], buf2[MAXPDSTRING];
+ int nmidiindev, midiindev[MAXMIDIINDEV];
+ int nmidioutdev, midioutdev[MAXMIDIOUTDEV];
+
+ sys_initsavepreferences();
+
+
+ /* audio settings */
+ sprintf(buf1, "%d", sys_audioapi);
+ sys_putpreference("audioapi", buf1);
+
+ sys_get_audio_params(&naudioindev, audioindev, chindev,
+ &naudiooutdev, audiooutdev, choutdev, &rate, &advance);
+
+ if (naudioindev <= 0)
+ sys_putpreference("noaudioin", ".");
+ for (i = 0; i < naudioindev; i++)
+ {
+ sprintf(buf1, "audioindev%d", i+1);
+ sprintf(buf2, "%d %d", audioindev[i], chindev[i]);
+ sys_putpreference(buf1, buf2);
+ }
+ if (naudiooutdev <= 0)
+ sys_putpreference("noaudioout", ".");
+ for (i = 0; i < naudiooutdev; i++)
+ {
+ sprintf(buf1, "audiooutdev%d", i+1);
+ sprintf(buf2, "%d %d", audiooutdev[i], choutdev[i]);
+ sys_putpreference(buf1, buf2);
+ }
+
+ sprintf(buf1, "%d", advance);
+ sys_putpreference("audiobuf", buf1);
+
+ sprintf(buf1, "%d", rate);
+ sys_putpreference("rate", buf1);
+
+ /* MIDI settings */
+ sys_get_midi_params(&nmidiindev, midiindev, &nmidioutdev, midioutdev);
+ if (nmidiindev <= 0)
+ sys_putpreference("nomidiin", ".");
+ for (i = 0; i < nmidiindev; i++)
+ {
+ sprintf(buf1, "midiindev%d", i+1);
+ sprintf(buf2, "%d", midiindev[i]);
+ sys_putpreference(buf1, buf2);
+ }
+ if (nmidioutdev <= 0)
+ sys_putpreference("nomidiout", ".");
+ for (i = 0; i < nmidioutdev; i++)
+ {
+ sprintf(buf1, "midioutdev%d", i+1);
+ sprintf(buf2, "%d", midioutdev[i]);
+ sys_putpreference(buf1, buf2);
+ }
+ /* file search path */
+
+ for (i = 0; 1; i++)
+ {
+ char *pathelem = namelist_get(sys_searchpath, i);
+ if (!pathelem)
+ break;
+ sprintf(buf1, "path%d", i+1);
+ sys_putpreference(buf1, pathelem);
+ }
+ sprintf(buf1, "%d", sys_usestdpath);
+ sys_putpreference("standardpath", buf1);
+ sprintf(buf1, "%d", sys_verbose);
+ sys_putpreference("verbose", buf1);
+
+ /* startup */
+ for (i = 0; 1; i++)
+ {
+ char *pathelem = namelist_get(sys_externlist, i);
+ if (!pathelem)
+ break;
+ sprintf(buf1, "loadlib%d", i+1);
+ sys_putpreference(buf1, pathelem);
+ }
+ sprintf(buf1, "%d", sys_defeatrt);
+ sys_putpreference("defeatrt", buf1);
+ sys_putpreference("flags",
+ (sys_flags ? sys_flags->s_name : ""));
+ sys_donesavepreferences();
+
+}