8890b4ef9230b8c9f78fc9395f1105edfcde0ea8
[terminatorX.git] / src / tX_global.c
1 /*
2     terminatorX - realtime audio scratching software
3     Copyright (C) 1999-2003  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 <config.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include "tX_types.h"
36 #include "tX_global.h"
37 #include "string.h"
38 #include <libxml/xmlmemory.h>
39 #include <libxml/parser.h>
40 #include <libxml/encoding.h>
41
42
43 #define TX_XML_RC_VERSION "1.0"
44
45 tx_global globals;
46 int _store_compress_xml=0;
47
48 #ifdef USE_ALSA_MIDI_IN
49 extern void tX_midiin_store_connections(FILE *rc, char *indent);
50 extern void tX_midiin_restore_connections(xmlNodePtr node);
51 #endif
52
53 void get_rc_name(char *buffer)
54 {
55         strcpy(buffer,"");
56         if (globals.alternate_rc)
57         {
58                 strcpy(buffer, globals.alternate_rc);
59         }
60         else 
61         {
62                 if (getenv("HOME"))
63                 {
64                         strcpy(buffer, getenv("HOME"));
65                         if (buffer[strlen(buffer)-1]!='/')
66                         strcat(buffer, "/");
67                 }
68                 strcat(buffer, ".terminatorXrc");
69         }
70 }
71
72 void set_global_defaults() {
73         globals.startup_set = 0;
74         globals.store_globals = 1;
75         globals.no_gui = 0;
76         globals.alternate_rc = 0;
77         
78         strcpy(globals.xinput_device, "");
79         globals.xinput_enable=0;
80         
81         globals.update_idle=14;
82         globals.update_delay=1;
83         
84         strcpy(globals.oss_device, "/dev/dsp");
85         globals.oss_buff_no=2;
86         globals.oss_buff_size=9;
87         globals.oss_samplerate=44100;
88
89         strcpy(globals.alsa_device_id, "hw:0,0");       
90         globals.alsa_buffer_time=80000;
91         globals.alsa_period_time=20000;
92         globals.alsa_samplerate=44100;
93         
94         globals.sense_cycles=80;
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=OSS;           
127 #else
128 #ifdef USE_ALSA
129         globals.audiodevice_type=ALSA;
130 #endif  
131 #endif          
132         globals.use_stdout_cmdline=0;
133         strcpy(globals.current_path, "");
134         globals.pitch=1.0;
135         globals.volume=1.0;
136         
137         strcpy(globals.lrdf_path, "/usr/share/ladspa/rdf:/usr/local/share/ladspa/rdf");
138         globals.fullscreen_enabled=0;
139         globals.confirm_events=0;
140         globals.compress_set_files=0;
141         
142         globals.vtt_inertia=10.0;
143         
144         globals.alsa_free_hwstats=1;
145         globals.filename_length=20;
146         globals.restore_midi_connections=1;
147 }
148
149 int load_globals_xml() {
150         char rc_name[PATH_MAX]="";      
151         char device_type[16]="oss";
152         xmlDocPtr doc;
153         xmlNodePtr cur;
154         int elementFound;
155         double dvalue;
156         char tmp_xml_buffer[4096];
157         
158         get_rc_name(rc_name);
159         
160         doc = xmlParseFile(rc_name);
161         
162         if (doc == NULL ) {
163                 fprintf(stderr, "tX: err: Error parsing terminatorXrc.\n");
164                 return 1;
165         }
166         
167         cur = xmlDocGetRootElement(doc);
168         
169         if (cur == NULL) {
170                 fprintf(stderr,"tX: err: terminatorXrc contains no elements.\n");
171                 xmlFreeDoc(doc);
172                 return 2;
173         }
174         
175         if (xmlStrcmp(cur->name, (const xmlChar *) "terminatorXrc")) {
176                 fprintf(stderr,"tX: err: This terminatorXrc is not a terminatorXrc.");
177                 xmlFreeDoc(doc);
178                 return 3;
179         }
180                 
181         for (cur=cur->xmlChildrenNode; cur != NULL; cur = cur->next) {
182                 if (cur->type == XML_ELEMENT_NODE) {                    
183                         elementFound=0;
184
185                         restore_int("store_globals", globals.store_globals);
186
187                         restore_string("audio_driver", device_type);
188                         
189                         restore_string("oss_device", globals.oss_device);
190                         restore_int("oss_buff_no", globals.oss_buff_no);
191                         restore_int("oss_buff_size", globals.oss_buff_size);
192                         restore_int("oss_samplerate", globals.oss_samplerate);
193
194                         restore_string("alsa_device_id", globals.alsa_device_id);
195                         restore_int("alsa_buffer_time", globals.alsa_buffer_time);
196                         restore_int("alsa_period_time", globals.alsa_period_time);
197                         restore_int("alsa_samplerate", globals.alsa_samplerate);
198                         restore_int("alsa_free_hwstats", globals.alsa_free_hwstats);
199                         
200                         restore_string("xinput_device", globals.xinput_device);
201                         restore_int("xinput_enable", globals.xinput_enable);
202                         restore_int("update_idle", globals.update_idle);
203                         restore_int("update_delay", globals.update_delay);
204                         restore_int("sense_cycles", globals.sense_cycles);
205                         restore_float("mouse_speed", globals.mouse_speed);
206                         restore_int("width", globals.width);
207                         restore_int("height", globals.height);
208                         restore_int("filename_length", globals.filename_length);
209                         restore_int("tooltips", globals.tooltips);
210                         restore_int("use_stdout", globals.use_stdout);
211                         restore_int("show_nag", globals.show_nag);
212                         restore_int("prelis", globals.prelis);
213                         restore_string("last_fn", globals.last_fn);
214                         restore_float("pitch", globals.pitch);
215                         restore_float("volume", globals.volume);
216                         restore_float("flash_response", globals.flash_response);
217                         restore_int("button_type", globals.button_type);
218                         restore_string("tables_filename", globals.tables_filename);
219                         restore_string("record_filename", globals.record_filename);
220                         restore_string("file_editor", globals.file_editor);
221                         restore_string("lrdf_path", globals.lrdf_path);
222                         restore_string("last_path", globals.current_path);
223                         
224                         restore_int("compress_set_files", globals.compress_set_files);
225                         restore_int("fullscreen_enabled", globals.fullscreen_enabled);
226                         restore_int("confirm_events", globals.confirm_events);
227                         restore_float("vtt_inertia", globals.vtt_inertia);
228                         restore_int("restore_midi_connections", globals.restore_midi_connections);
229
230 #ifdef USE_ALSA_MIDI_IN
231                         if (!elementFound && (xmlStrcmp(cur->name, (xmlChar *) "midi_connections")==0)) {
232                                 if (globals.restore_midi_connections) {
233                                         tX_midiin_restore_connections(cur);
234                                 }
235                                 elementFound=1;
236                         }
237 #endif                  
238
239                         if (!elementFound) {
240                                 fprintf(stderr, "tX: Unhandled XML element: \"%s\"\n", cur->name);
241                         }
242                 }
243         }
244
245         xmlFreeDoc(doc);
246         
247         if (strcmp(device_type, "alsa")==0) globals.audiodevice_type=ALSA;
248         else if (strcmp(device_type, "jack")==0) globals.audiodevice_type=JACK;
249         else globals.audiodevice_type=OSS;
250         
251         return 0;
252 }
253
254 void store_globals() {
255         char rc_name[PATH_MAX+256]="";
256         char device_type[16];
257         char indent[32]="\t";
258         FILE *rc=NULL;
259         gzFile rz=NULL;
260         char tmp_xml_buffer[4096];
261         _store_compress_xml=0;
262         
263         get_rc_name(rc_name);
264
265         rc=fopen(rc_name, "w");
266         
267         switch (globals.audiodevice_type) {
268                 case JACK:
269                         strcpy(device_type, "jack");
270                         break;
271                 case ALSA:
272                         strcpy(device_type, "alsa");
273                         break;
274                 case OSS:
275                 default:
276                         strcpy(device_type, "oss");
277                 
278         }
279         
280         if (rc) {               
281                 fprintf(rc, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n");
282                 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" );
283                 fprintf(rc, "<terminatorXrc version=\"%s\">\n", TX_XML_RC_VERSION);
284
285                 store_int("store_globals", globals.store_globals);
286
287                 store_string("audio_driver", device_type);
288                 
289                 store_string("oss_device", globals.oss_device);
290                 store_int("oss_buff_no", globals.oss_buff_no);
291                 store_int("oss_buff_size", globals.oss_buff_size);
292                 store_int("oss_samplerate", globals.oss_samplerate);
293
294                 store_string("alsa_device_id", globals.alsa_device_id);
295                 store_int("alsa_buffer_time", globals.alsa_buffer_time);
296                 store_int("alsa_period_time", globals.alsa_period_time);
297                 store_int("alsa_samplerate", globals.alsa_samplerate);          
298                 store_int("alsa_free_hwstats", globals.alsa_free_hwstats);
299                 
300                 store_string("xinput_device", globals.xinput_device);
301                 store_int("xinput_enable", globals.xinput_enable);
302                 store_int("update_idle", globals.update_idle);
303                 store_int("update_delay", globals.update_delay);
304                 store_int("sense_cycles", globals.sense_cycles);
305                 store_float("mouse_speed", globals.mouse_speed);
306                 store_int("width", globals.width);
307                 store_int("height", globals.height);
308                 store_int("filename_length", globals.filename_length);
309                 store_int("tooltips", globals.tooltips);
310                 store_int("use_stdout", globals.use_stdout);
311                 // globals.use_stdout_from_conf_file=0; What the heck is this?
312                 store_int("show_nag", globals.show_nag);
313                 store_int("prelis", globals.prelis);
314                 store_string("last_fn", globals.last_fn);
315                 store_float("pitch", globals.pitch);
316                 store_float("volume", globals.volume);
317                 store_float("flash_response", globals.flash_response);
318                 store_int("button_type", globals.button_type);
319                 store_string("tables_filename", globals.tables_filename);
320                 store_string("record_filename", globals.record_filename);
321                 store_string("file_editor", globals.file_editor);
322                 store_string("lrdf_path", globals.lrdf_path);
323                 store_int("compress_set_files", globals.compress_set_files);
324                 store_int("fullscreen_enabled", globals.fullscreen_enabled);
325                 store_int("confirm_events", globals.confirm_events);
326                 store_float("vtt_inertia", globals.vtt_inertia);
327
328                 store_string("last_path", globals.current_path);
329                 store_int("restore_midi_connections", globals.restore_midi_connections);
330
331 #ifdef USE_ALSA_MIDI_IN
332                 tX_midiin_store_connections(rc, indent);
333 #endif          
334
335                 fprintf(rc,"</terminatorXrc>\n");
336         }
337 }
338
339 #ifdef ENABLE_TX_LEGACY
340 extern void load_globals_old();
341 #endif
342
343 void load_globals() {
344         set_global_defaults();
345
346         if (load_globals_xml()!=0) {
347                 fprintf(stderr, "tX: Failed loading terminatorXrc - trying to load old binary rc.\n");
348 #ifdef ENABLE_TX_LEGACY         
349                 load_globals_old();
350 #endif          
351         }
352 }
353
354 char *encode_xml(char *dest, const char *src) {
355         int i, t, max;
356         char tmp[4096];
357         int outlen=4096;
358         int inlen;
359         int res;
360         
361         tmp[0]=0;
362         t=0;
363         max=strlen(src);
364         
365         for (i=0; i<max; i++) {
366                 switch (src[i]) {
367                         case '<': tmp[t]=0; strcat(tmp, "&lt;"); t+=4; break;
368                         case '>': tmp[t]=0; strcat(tmp, "&gt;"); t+=4; break;
369                         case '&': tmp[t]=0; strcat(tmp, "&amp;"); t+=5; break;
370                         case '"': tmp[t]=0; strcat(tmp, "&quot;"); t+=6; break;
371                         case '\'': strcat(tmp, "&apos;"); t+=7; break;
372                         default: tmp[t]=src[i]; t++;
373                 }
374         }
375         tmp[t]=0;
376
377         inlen=t;
378         res=isolat1ToUTF8((unsigned char *) dest, &outlen, (unsigned char *) tmp, &inlen);
379         dest[outlen]=0;
380         if (res<0) {
381                 tX_error("failed to encode string (%s) to UTF-8.", src);
382         }
383         
384         return dest;
385 }
386
387 char *decode_xml(char *dest, const char *src) {
388         int inlen=strlen(src);
389         int outlen=4096;
390         
391         int res=UTF8Toisolat1(dest, &outlen, src, &inlen);
392         dest[outlen]=0;
393         
394         if (res<0) {
395                 tX_error("failed to decode UTF-8 string (%s).", src);
396         }
397         
398         return dest;
399 }