audiofile support + improved sample rate support + results of a -Wall -Werr
[terminatorX.git] / src / tX_global.c
1 /*
2     terminatorX - realtime audio scratching software
3     Copyright (C) 1999-2002  Alexander K├Ânig
4  
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.
9  
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.
14  
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.
18  
19     File: tX_global.c
20  
21     Description:  This file contains the routines for handling the
22                   "globals" block. Intializing, reading setup from
23                   disk and storing it.
24                   
25     Changes:
26     
27     21 Jul 1999: introduced the lowpass globals.
28         There were some changes in between...
29         14 Jul 2002: switched to libxml instead of binary saving.
30 */    
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include "tX_types.h"
35 #include "tX_global.h"
36 #include "string.h"
37 #include <libxml/xmlmemory.h>
38 #include <libxml/parser.h>
39
40 #define TX_XML_RC_VERSION "1.0"
41
42 tx_global globals;
43
44 void get_rc_name_old(char *buffer)
45 {
46         strcpy(buffer,"");
47
48         if (getenv("HOME"))
49         {
50                 strcpy(buffer, getenv("HOME"));
51                 if (buffer[strlen(buffer)-1]!='/')
52                 strcat(buffer, "/");
53         }
54         
55         strcat(buffer, ".terminatorX3rc.bin");
56 }
57
58 void get_rc_name(char *buffer)
59 {
60         strcpy(buffer,"");
61         if (globals.alternate_rc)
62         {
63                 strcpy(buffer, globals.alternate_rc);
64         }
65         else 
66         {
67                 if (getenv("HOME"))
68                 {
69                         strcpy(buffer, getenv("HOME"));
70                         if (buffer[strlen(buffer)-1]!='/')
71                         strcat(buffer, "/");
72                 }
73                 strcat(buffer, ".terminatorXrc");
74         }
75 }
76
77 void set_global_defaults() {
78         globals.startup_set = 0;
79         globals.store_globals = 1;
80         globals.no_gui = 0;
81         globals.alternate_rc = 0;
82         
83         strcpy(globals.audio_device, "/dev/dsp");
84         
85         strcpy(globals.xinput_device, "");
86         globals.xinput_enable=0;
87         
88         globals.update_idle=18;
89         globals.update_delay=1;
90         
91         globals.buff_no=2;
92         globals.buff_size=9;
93         
94         globals.sense_cycles=12;
95         
96         globals.mouse_speed=0.8;
97         
98         globals.width=800;
99         globals.height=440;     
100         
101         globals.tooltips=1;
102         
103         globals.use_stdout=0;
104         globals.use_stdout_from_conf_file=0;
105         
106         globals.show_nag=1;
107         globals.prelis=1;
108         
109         strcpy(globals.last_fn,"");
110         
111         globals.pitch=1.0;
112         globals.volume=1.0;
113         globals.gui_wrap=3;
114         
115         globals.flash_response=0.95;
116         
117         globals.button_type=BUTTON_TYPE_BOTH;
118                 
119         globals.true_block_size=0;
120         
121         strcpy(globals.tables_filename, "");
122         strcpy(globals.record_filename, "tX_record.wav");
123         strcpy(globals.file_editor, "");
124                 
125 #ifdef USE_OSS
126         globals.audiodevice_type=TX_AUDIODEVICE_TYPE_OSS;               
127 #else
128 #ifdef USE_ALSA
129         globals.audiodevice_type=TX_AUDIODEVICE_TYPE_ALSA;
130 #endif  
131 #endif          
132         globals.audiodevice_buffersize=4096;
133         strcpy(globals.audiodevice_oss_devicename, "/dev/dsp");
134         globals.audiodevice_alsa_card=0;
135         globals.audiodevice_alsa_pcm=0;         
136
137         globals.use_stdout_cmdline=0;
138         globals.current_path = NULL;
139         globals.pitch=1.0;
140         globals.volume=1.0;     
141         if (!globals.true_block_size) globals.true_block_size=1<globals.buff_size;
142
143 }
144
145 void load_globals_old()
146 {       
147         char rc_name[PATH_MAX]="";      
148         FILE *rc;
149         get_rc_name_old(rc_name);
150         
151         rc=fopen(rc_name, "r");
152         if (rc)
153         {
154                 fread(&globals, sizeof(tx_global), 1, rc);
155                 fclose(rc);
156         }
157         else
158         {
159                 fprintf(stderr, "tX: .rc-file '%s' doesn't exist, reverting to defaults\n", rc_name);
160                 set_global_defaults();
161         }
162
163         /* i'll have to keep these as they're in the code
164           everywhere but I think it doesn't make sense resetting
165           to old values on startup....
166         */
167         globals.use_stdout_cmdline=0;
168         globals.current_path = NULL;
169         globals.pitch=1.0;
170         globals.volume=1.0;     
171         if (!globals.true_block_size) globals.true_block_size=1<globals.buff_size;
172 }
173
174 #define restore_int(s, i); if ((!elementFound) && (!xmlStrcmp(cur->name, (const xmlChar *) s))) { elementFound=1; if (xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)) { sscanf(xmlNodeListGetString(doc, cur->xmlChildrenNode, 1), "%i", &i); }}
175 #define restore_float(s, i); if ((!elementFound) && (!xmlStrcmp(cur->name, (const xmlChar *) s))) { elementFound=1; if  (xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)) {sscanf(xmlNodeListGetString(doc, cur->xmlChildrenNode, 1), "%lf", &dvalue); i=dvalue;}}
176 #define restore_string(s, i); if ((!elementFound) && (!xmlStrcmp(cur->name, (const xmlChar *) s))) { elementFound=1; if (xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)) {strcpy(i, xmlNodeListGetString(doc, cur->xmlChildrenNode, 1)); }}
177
178 int load_globals_xml() {
179         char rc_name[PATH_MAX]="";      
180         xmlDocPtr doc;
181         xmlNodePtr cur;
182         int elementFound;
183         double dvalue;
184
185         set_global_defaults();
186         get_rc_name(rc_name);
187         
188         doc = xmlParseFile(rc_name);
189         
190         if (doc == NULL ) {
191                 fprintf(stderr, "tX: err: Error parsing terminatorXrc.\n");
192                 return 1;
193         }
194         
195         cur = xmlDocGetRootElement(doc);
196         
197         if (cur == NULL) {
198                 fprintf(stderr,"tX: err: terminatorXrc contains no elements.\n");
199                 xmlFreeDoc(doc);
200                 return 2;
201         }
202         
203         if (xmlStrcmp(cur->name, (const xmlChar *) "terminatorXrc")) {
204                 fprintf(stderr,"tX: err: This terminatorXrc is not a terminatorXrc.");
205                 xmlFreeDoc(doc);
206                 return 3;
207         }
208         
209         for (cur=cur->xmlChildrenNode; cur != NULL; cur = cur->next) {
210                 if (cur->type == XML_ELEMENT_NODE) {                    
211                         elementFound=0;
212
213                         restore_int("store_globals", globals.store_globals);
214                         restore_string("audio_device", globals.audio_device);
215                         restore_string("xinput_device", globals.xinput_device);
216                         restore_int("xinput_enable", globals.xinput_enable);
217                         restore_int("update_idle", globals.update_idle);
218                         restore_int("update_delay", globals.update_delay);
219                         restore_int("buff_no", globals.buff_no);
220                         restore_int("buff_size", globals.buff_size);
221                         restore_int("sense_cycles", globals.sense_cycles);
222                         restore_float("mouse_speed", globals.mouse_speed);
223                         restore_int("width", globals.width);
224                         restore_int("height", globals.height);
225                         restore_int("tooltips", globals.tooltips);
226                         restore_int("use_stdout", globals.use_stdout);
227                         restore_int("show_nag", globals.show_nag);
228                         restore_int("prelis", globals.prelis);
229                         restore_string("last_fn", globals.last_fn);
230                         restore_float("pitch", globals.pitch);
231                         restore_float("volume", globals.volume);
232                         restore_float("flash_response", globals.flash_response);
233                         restore_int("button_type", globals.button_type);
234                         restore_int("true_block_size", globals.true_block_size);
235                         restore_string("tables_filename", globals.tables_filename);
236                         restore_string("record_filename", globals.record_filename);
237                         restore_string("file_editor", globals.file_editor);
238
239                         if (!elementFound) {
240                                 fprintf(stderr, "tX: Unhandled XML element: \"%s\"\n", cur->name);
241                         }
242                 }
243         }
244         
245         return 0;
246 }
247
248 #define store_int(s, i); fprintf(rc, "\t<%s>%i</%s>\n", s,(int) i, s);
249 #define store_float(s, i); fprintf(rc, "\t<%s>%lf</%s>\n", s,(double) i, s);
250 #define store_string(s, i); fprintf(rc, "\t<%s>%s</%s>\n", s, i, s);
251
252 void store_globals() {
253         char rc_name[PATH_MAX]="";
254         FILE *rc;
255         
256         get_rc_name(rc_name);
257
258         rc=fopen(rc_name, "w");
259         
260         if (rc) {               
261                 fprintf(rc, "<?xml version=\"1.0\" encoding=\"US-ASCII\"?>\n\n");
262                 fprintf(rc, "<!-- Warning: this file will be rewritten by terminatorX on exit!\n     Don\'t waste your time adding comments - they will be erased -->\n\n" );
263                 fprintf(rc, "<terminatorXrc version=\"%s\">\n", TX_XML_RC_VERSION);
264
265                 store_int("store_globals", globals.store_globals);
266                 store_string("audio_device", globals.audio_device);
267                 store_string("xinput_device", globals.xinput_device);
268                 store_int("xinput_enable", globals.xinput_enable);
269                 store_int("update_idle", globals.update_idle);
270                 store_int("update_delay", globals.update_delay);
271                 store_int("buff_no", globals.buff_no);
272                 store_int("buff_size", globals.buff_size);
273                 store_int("sense_cycles", globals.sense_cycles);
274                 store_float("mouse_speed", globals.mouse_speed);
275                 store_int("width", globals.width);
276                 store_int("height", globals.height);
277                 store_int("tooltips", globals.tooltips);
278                 store_int("use_stdout", globals.use_stdout);
279                 // globals.use_stdout_from_conf_file=0; What the heck is this?
280                 store_int("show_nag", globals.show_nag);
281                 store_int("prelis", globals.prelis);
282                 store_string("last_fn", globals.last_fn);
283                 store_float("pitch", globals.pitch);
284                 store_float("volume", globals.volume);
285                 store_float("flash_response", globals.flash_response);
286                 store_int("button_type", globals.button_type);
287                 store_int("true_block_size", globals.true_block_size);
288                 store_string("tables_filename", globals.tables_filename);
289                 store_string("record_filename", globals.record_filename);
290                 store_string("file_editor", globals.file_editor);
291                 
292                 fprintf(rc,"</terminatorXrc>\n");
293         }
294 }
295
296 void load_globals() {
297         if (load_globals_xml()!=0) {
298                 fprintf(stderr, "tX: Failed loading terminatorXrc - trying to load old binary rc.\n");
299                 load_globals_old();
300         }
301 }