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