477f749e69f286aa5225e38bd303ba7a2609b234
[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         strcpy(globals.lrdf_path, "/usr/share/ladspa/rdf:/usr/local/share/ladspa/rdf");
135         globals.fullscreen_enabled=0;
136         globals.confirm_events=0;
137         globals.compress_set_files=0;
138         
139         globals.vtt_inertia=10.0;
140         
141         globals.alsa_free_hwstats=0;
142         globals.filename_length=20;
143         globals.restore_midi_connections=1;
144         
145         strcpy(globals.wav_display_bg_focus, "#00004C");
146         strcpy(globals.wav_display_bg_no_focus, "#000000");
147
148         strcpy(globals.wav_display_fg_focus, "#FFFF00");
149         strcpy(globals.wav_display_fg_no_focus, "#00FF00");
150
151         strcpy(globals.wav_display_cursor, "#FF6666");
152         strcpy(globals.wav_display_cursor_mute, "#FFFFFF");     
153         
154         strcpy(globals.vu_meter_bg, "#000000");
155         strcpy(globals.vu_meter_loud, "#FF0000");
156         strcpy(globals.vu_meter_normal, "#00FF00");     
157         globals.vu_meter_border_intensity=0.7;
158         globals.quit_confirm=1;
159 }
160
161 int load_globals_xml() {
162         char rc_name[PATH_MAX]="";      
163         char device_type[16]="oss";
164         xmlDocPtr doc;
165         xmlNodePtr cur;
166         int elementFound;
167         double dvalue;
168         char tmp_xml_buffer[4096];
169         
170         get_rc_name(rc_name);
171         
172         doc = xmlParseFile(rc_name);
173         
174         if (doc == NULL ) {
175                 fprintf(stderr, "tX: err: Error parsing terminatorXrc.\n");
176                 return 1;
177         }
178         
179         cur = xmlDocGetRootElement(doc);
180         
181         if (cur == NULL) {
182                 fprintf(stderr,"tX: err: terminatorXrc contains no elements.\n");
183                 xmlFreeDoc(doc);
184                 return 2;
185         }
186         
187         if (xmlStrcmp(cur->name, (const xmlChar *) "terminatorXrc")) {
188                 fprintf(stderr,"tX: err: This terminatorXrc is not a terminatorXrc.");
189                 xmlFreeDoc(doc);
190                 return 3;
191         }
192                 
193         for (cur=cur->xmlChildrenNode; cur != NULL; cur = cur->next) {
194                 if (cur->type == XML_ELEMENT_NODE) {                    
195                         elementFound=0;
196
197                         restore_int("store_globals", globals.store_globals);
198
199                         restore_string("audio_driver", device_type);
200                         
201                         restore_string("oss_device", globals.oss_device);
202                         restore_int("oss_buff_no", globals.oss_buff_no);
203                         restore_int("oss_buff_size", globals.oss_buff_size);
204                         restore_int("oss_samplerate", globals.oss_samplerate);
205
206                         restore_string("alsa_device_id", globals.alsa_device_id);
207                         restore_int("alsa_buffer_time", globals.alsa_buffer_time);
208                         restore_int("alsa_period_time", globals.alsa_period_time);
209                         restore_int("alsa_samplerate", globals.alsa_samplerate);
210                         restore_int("alsa_free_hwstats", globals.alsa_free_hwstats);
211                         
212                         restore_string("xinput_device", globals.xinput_device);
213                         restore_int("xinput_enable", globals.xinput_enable);
214                         restore_int("update_idle", globals.update_idle);
215                         restore_int("update_delay", globals.update_delay);
216                         restore_int("sense_cycles", globals.sense_cycles);
217                         restore_float("mouse_speed", globals.mouse_speed);
218                         restore_int("width", globals.width);
219                         restore_int("height", globals.height);
220                         restore_int("filename_length", globals.filename_length);
221                         restore_int("tooltips", globals.tooltips);
222                         restore_int("use_stdout", globals.use_stdout);
223                         restore_int("show_nag", globals.show_nag);
224                         restore_int("prelis", globals.prelis);
225                         restore_string("last_fn", globals.last_fn);
226                         restore_float("pitch", globals.pitch);
227                         restore_float("volume", globals.volume);
228                         restore_float("flash_response", globals.flash_response);
229                         restore_int("button_type", globals.button_type);
230                         restore_string("tables_filename", globals.tables_filename);
231                         restore_string("record_filename", globals.record_filename);
232                         restore_string("file_editor", globals.file_editor);
233                         restore_string("lrdf_path", globals.lrdf_path);
234                         restore_string("last_path", globals.current_path);
235                         
236                         restore_int("compress_set_files", globals.compress_set_files);
237                         restore_int("fullscreen_enabled", globals.fullscreen_enabled);
238                         restore_int("confirm_events", globals.confirm_events);
239                         restore_float("vtt_inertia", globals.vtt_inertia);
240                         restore_int("restore_midi_connections", globals.restore_midi_connections);
241                         
242                         restore_string("wav_display_bg_focus", globals.wav_display_bg_focus);
243                         restore_string("wav_display_bg_no_focus", globals.wav_display_bg_no_focus);
244                         restore_string("wav_display_fg_focus", globals.wav_display_fg_focus);
245                         restore_string("wav_display_fg_no_focus", globals.wav_display_fg_no_focus);
246                         restore_string("wav_display_cursor", globals.wav_display_cursor);
247                         restore_string("wav_display_cursor_mute", globals.wav_display_cursor_mute);
248                         
249                         restore_string("vu_meter_bg", globals.vu_meter_bg);
250                         restore_string("vu_meter_normal", globals.vu_meter_normal);
251                         restore_string("vu_meter_loud", globals.vu_meter_loud);
252                         
253                         restore_float("vu_meter_border_intensity", globals.vu_meter_border_intensity);
254
255                         restore_int("quit_confirm", globals.quit_confirm);
256
257 #ifdef USE_ALSA_MIDI_IN
258                         if (!elementFound && (xmlStrcmp(cur->name, (xmlChar *) "midi_connections")==0)) {
259                                 if (globals.restore_midi_connections) {
260                                         tX_midiin_restore_connections(cur);
261                                 }
262                                 elementFound=1;
263                         }
264 #endif                  
265
266                         if (!elementFound) {
267                                 fprintf(stderr, "tX: Unhandled XML element: \"%s\"\n", cur->name);
268                         }
269                 }
270         }
271
272         xmlFreeDoc(doc);
273         
274         if (strcmp(device_type, "alsa")==0) globals.audiodevice_type=ALSA;
275         else if (strcmp(device_type, "jack")==0) globals.audiodevice_type=JACK;
276         else globals.audiodevice_type=OSS;
277         
278         return 0;
279 }
280
281 void store_globals() {
282         char rc_name[PATH_MAX+256]="";
283         char device_type[16];
284         char indent[32]="\t";
285         FILE *rc=NULL;
286         gzFile rz=NULL;
287         char tmp_xml_buffer[4096];
288         _store_compress_xml=0;
289         
290         get_rc_name(rc_name);
291
292         rc=fopen(rc_name, "w");
293         
294         switch (globals.audiodevice_type) {
295                 case JACK:
296                         strcpy(device_type, "jack");
297                         break;
298                 case ALSA:
299                         strcpy(device_type, "alsa");
300                         break;
301                 case OSS:
302                 default:
303                         strcpy(device_type, "oss");
304                 
305         }
306         
307         if (rc) {               
308                 fprintf(rc, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n");
309                 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" );
310                 fprintf(rc, "<terminatorXrc version=\"%s\">\n", TX_XML_RC_VERSION);
311
312                 store_int("store_globals", globals.store_globals);
313
314                 store_string("audio_driver", device_type);
315                 
316                 store_string("oss_device", globals.oss_device);
317                 store_int("oss_buff_no", globals.oss_buff_no);
318                 store_int("oss_buff_size", globals.oss_buff_size);
319                 store_int("oss_samplerate", globals.oss_samplerate);
320
321                 store_string("alsa_device_id", globals.alsa_device_id);
322                 store_int("alsa_buffer_time", globals.alsa_buffer_time);
323                 store_int("alsa_period_time", globals.alsa_period_time);
324                 store_int("alsa_samplerate", globals.alsa_samplerate);          
325                 store_int("alsa_free_hwstats", globals.alsa_free_hwstats);
326                 
327                 store_string("xinput_device", globals.xinput_device);
328                 store_int("xinput_enable", globals.xinput_enable);
329                 store_int("update_idle", globals.update_idle);
330                 store_int("update_delay", globals.update_delay);
331                 store_int("sense_cycles", globals.sense_cycles);
332                 store_float("mouse_speed", globals.mouse_speed);
333                 store_int("width", globals.width);
334                 store_int("height", globals.height);
335                 store_int("filename_length", globals.filename_length);
336                 store_int("tooltips", globals.tooltips);
337                 store_int("use_stdout", globals.use_stdout);
338                 // globals.use_stdout_from_conf_file=0; What the heck is this?
339                 store_int("show_nag", globals.show_nag);
340                 store_int("prelis", globals.prelis);
341                 store_string("last_fn", globals.last_fn);
342                 store_float("pitch", globals.pitch);
343                 store_float("volume", globals.volume);
344                 store_float("flash_response", globals.flash_response);
345                 store_int("button_type", globals.button_type);
346                 store_string("tables_filename", globals.tables_filename);
347                 store_string("record_filename", globals.record_filename);
348                 store_string("file_editor", globals.file_editor);
349                 store_string("lrdf_path", globals.lrdf_path);
350                 store_int("compress_set_files", globals.compress_set_files);
351                 store_int("fullscreen_enabled", globals.fullscreen_enabled);
352                 store_int("confirm_events", globals.confirm_events);
353                 store_float("vtt_inertia", globals.vtt_inertia);
354
355                 store_string("last_path", globals.current_path);
356                 store_int("restore_midi_connections", globals.restore_midi_connections);
357
358                 store_string("wav_display_bg_focus", globals.wav_display_bg_focus);
359                 store_string("wav_display_bg_no_focus", globals.wav_display_bg_no_focus);
360                 store_string("wav_display_fg_focus", globals.wav_display_fg_focus);
361                 store_string("wav_display_fg_no_focus", globals.wav_display_fg_no_focus);
362                 store_string("wav_display_cursor", globals.wav_display_cursor);
363                 store_string("wav_display_cursor_mute", globals.wav_display_cursor_mute);
364
365                 store_string("vu_meter_bg", globals.vu_meter_bg);
366                 store_string("vu_meter_normal", globals.vu_meter_normal);
367                 store_string("vu_meter_loud", globals.vu_meter_loud);
368                         
369                 store_float("vu_meter_border_intensity", globals.vu_meter_border_intensity);
370
371                 store_int("quit_confirm", globals.quit_confirm);
372                 
373 #ifdef USE_ALSA_MIDI_IN
374                 tX_midiin_store_connections(rc, indent);
375 #endif          
376
377                 fprintf(rc,"</terminatorXrc>\n");
378         }
379 }
380
381 #ifdef ENABLE_TX_LEGACY
382 extern void load_globals_old();
383 #endif
384
385 void load_globals() {
386         set_global_defaults();
387
388         if (load_globals_xml()!=0) {
389                 fprintf(stderr, "tX: Failed loading terminatorXrc - trying to load old binary rc.\n");
390 #ifdef ENABLE_TX_LEGACY         
391                 load_globals_old();
392 #endif          
393         }
394 }
395
396 char *encode_xml(char *dest, const char *src) {
397         int i, t, max;
398         char tmp[4096];
399         int outlen=4096;
400         int inlen;
401         int res;
402         
403         tmp[0]=0;
404         t=0;
405         max=strlen(src);
406         
407         for (i=0; i<max; i++) {
408                 switch (src[i]) {
409                         case '<': tmp[t]=0; strcat(tmp, "&lt;"); t+=4; break;
410                         case '>': tmp[t]=0; strcat(tmp, "&gt;"); t+=4; break;
411                         case '&': tmp[t]=0; strcat(tmp, "&amp;"); t+=5; break;
412                         case '"': tmp[t]=0; strcat(tmp, "&quot;"); t+=6; break;
413                         case '\'': strcat(tmp, "&apos;"); t+=7; break;
414                         default: tmp[t]=src[i]; t++;
415                 }
416         }
417         tmp[t]=0;
418
419         inlen=t;
420         res=isolat1ToUTF8((unsigned char *) dest, &outlen, (unsigned char *) tmp, &inlen);
421         dest[outlen]=0;
422         if (res<0) {
423                 tX_error("failed to encode string (%s) to UTF-8.", src);
424         }
425         
426         return dest;
427 }
428
429 char *decode_xml(char *dest, const char *src) {
430         int inlen=strlen(src);
431         int outlen=4096;
432         
433         int res=UTF8Toisolat1(dest, &outlen, src, &inlen);
434         dest[outlen]=0;
435         
436         if (res<0) {
437                 tX_error("failed to decode UTF-8 string (%s).", src);
438         }
439         
440         return dest;
441 }