1 //  ----------------------------------------------------------
2 //
3 //  Copyright (C) 2002 Brad Wasson <bard@systemtoolbox.com>
4 //
5 //  This file is part of 3ddesktop.
6 //
7 //  3ddesktop is free software; you can redistribute it and/or modify it
8 //  under the terms of the GNU General Public License as published by
9 //  the Free Software Foundation; either version 2, or (at your option)
10 //  any later version.
11 //
12 //  3ddesktop is distributed in the hope that it will be useful, but
13 //  WITHOUT ANY WARRANTY; without even the implied warranty of
14 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 //  GNU General Public License for more details.
16 //
17 //  You should have received a copy of the GNU General Public License
18 //  along with 3ddesktop; see the file COPYING.   If not, write to
19 //  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20 //
21 
22 #include "config.hpp"
23 
24 static void
usage_and_bye(void)25 usage_and_bye (void)
26 {
27     msgout(INFO,
28            "usage: 3ddeskd [ OPTIONS ]\n\n"
29            "  where:\n"
30            "    --version        Display version information\n"
31            "    --acquire[=#]    Grab images for all the desktops by cycling thru\n"
32            "                       (sleep for # millisecs at each screen for refresh)\n"
33            "    --mirror         Grab image from current desktop and use for all\n"
34            "    --dir=/path      the install dir if different than /usr/share/3ddesktop\n"
35            "    --texturesize=#  size of textures (larger for more detail) in powers of 2\n"
36            "    --wm=            Specify the Windowmanager type so all the virtual \n"
37            "                     desktops are found correctly.  Available options are:\n"
38            "                       kde2, kde3, gnome1, gnome2, ewmh, fluxbox, windowmaker,\n"
39            "                       enlightenment, sawfishonly, workspaces\n"
40            "    --fastest        hog the CPU for smoothest operation\n"
41            "    -v               verbose/debug information\n\n");
42     exit (1);
43 } // END usage_and_bye
44 
45 
46 static int
get_boolean(char * value)47 get_boolean (char *value)
48 {
49     if (!value) return 0;
50 
51     if (!strcmp(value, "0") ||
52         !strcmp(value, "false") ||
53         !strcmp(value, "no") ||
54         !strcmp(value, "off"))
55         return 0;
56 
57     if (!strcmp(value, "1") ||
58         !strcmp(value, "true") ||
59         !strcmp(value, "yes") ||
60         !strcmp(value, "on"))
61         return 1;
62 
63     return 0;  // default false (?)
64 }
65 
66 
Options(char * n)67 Options::Options(char *n)
68 {
69     n = NULL;
70 
71     if (n)
72         strncpy(name, n, sizeof(name));
73 
74 
75     acquire = 0;
76     glcompression = 0;
77     show_fps = 0;
78     show_digits = 1;
79     do_fullscreen = 1;
80     entry_exit_movement = 1;
81     use_breathing = 1;
82     random_fun_delay = 15;
83     face_type = FACE_TYPE_CAROUSEL;
84     default_z_offset_distance = 0;
85     daemonized = 0;
86     goto_column = NO_GOTO;
87     goto_row = NO_GOTO;
88 
89     strcpy(base_dir, SHAREDIR);
90 
91     digit_size = 50;
92     digit_color = COLOR_RED;
93 
94     frame_color = COLOR_GRAY;
95     use_wireframe = false;
96 
97     linear_spacing = 2.0;
98 
99     recalc = 1;
100 
101     animation_speed = 10;
102 
103     face_change_steps = 40;
104     zoom_steps = 45;
105 
106     disable_exit_after_goto = 0;
107 
108     reverse_mousewheel = 0;
109     swap_mousebuttons = 0;
110     alt_mousebuttons = 0;
111 
112 //        __default_background[0] = 0;
113     background[0] = 0;
114     // ----
115     //arrangement = NULL;
116 
117 }  // END Options::Options
118 
set_color(int * v,char * color)119 void Options::set_color (int *v, char *color)
120 {
121     if (strcmp(color, "red") == 0) {
122         *v = COLOR_RED;
123     } else if (strcmp(color, "green") == 0) {
124         *v = COLOR_GREEN;
125     } else if (strcmp(color, "blue") == 0) {
126         *v = COLOR_BLUE;
127     } else if (strcmp(color, "lightblue") == 0) {
128         *v = COLOR_LIGHTBLUE;
129     } else if (strcmp(color, "white") == 0) {
130         *v = COLOR_WHITE;
131     } else if (strcmp(color, "gray") == 0) {
132         *v = COLOR_GRAY;
133     } else if (strcmp(color, "purple") == 0) {
134         *v = COLOR_PURPLE;
135     } else if (strcmp(color, "yellow") == 0) {
136         *v = COLOR_YELLOW;
137     } else {
138         msgout (DEBUG, "conf file: invalid color '%s' (red,green,blue,yellow,white,purple,orange)\n", color);
139         //*v = COLOR_WHITE;
140     }
141 }  // END Options::set_color
142 
143 int
set_option(char * option,char * value,bool from_cmdline)144 Options::set_option (char *option, char *value, bool from_cmdline)
145 {
146     int tmpint;
147     float tmpfloat;
148 
149     if (!option)
150         return 1;
151 
152     if (strcmp(option, "mode") == 0) {
153 
154         if (strcmp(value, "cylinder") == 0) {
155             face_type = FACE_TYPE_CYLINDER;
156         } else if (strcmp(value, "linear") == 0) {
157             face_type = FACE_TYPE_LINEAR;
158         } else if (strcmp(value, "viewmaster") == 0) {
159             face_type = FACE_TYPE_VIEWMASTER;
160         } else if (strcmp(value, "carousel") == 0) {
161             face_type = FACE_TYPE_CAROUSEL;
162         } else if (strcmp(value, "priceisright") == 0) {
163             face_type = FACE_TYPE_PRICEISRIGHT;
164         } else if (strcmp(value, "flip") == 0) {
165             face_type = FACE_TYPE_FLIP;
166         } else if (strcmp(value, "random") == 0) {
167             face_type = FACE_TYPE_RANDOM;
168         } else {
169             return 1;
170         }
171 
172     } else if (strcmp(option, "zoomspeed") == 0) {
173         float tmp = atof(value);
174         if (tmp >= 1.0 && tmp <= 300.0) {
175             zoom_steps = tmp;
176         }
177 
178     } else if (strcmp(option, "changespeed") == 0) {
179         float tmp = atof(value);
180         if (tmp >= 1.0 && tmp <= 300.0) {
181             face_change_steps = tmp;
182         }
183 
184     } else if (strcmp(option, "animation_speed") == 0) {
185         float tmp = atof(value);
186         if (tmp >= 1.0 && tmp <= 100.0) {
187             animation_speed = tmp;
188         }
189 
190     } else if (strcmp(option, "linear_spacing") == 0) {
191         float tmp = atof(value);
192         if (tmp >= 0.0 && tmp <= 20) {
193             linear_spacing = tmp;
194             recalc = 1;
195         }
196     } else if (strcmp(option, "use_breathing") == 0) {
197         use_breathing = get_boolean (value);
198 
199     } else if (strcmp(option, "digit_size") == 0) {
200         digit_size = atoi(value);
201 
202     } else if (strcmp(option, "digit_color") == 0) {
203         set_color (&digit_color, value);
204 
205     } else if (strcmp(option, "frame_color") == 0) {
206         set_color (&frame_color, value);
207 
208     } else if (strcmp(option, "use_wireframe") == 0) {
209         use_wireframe = get_boolean (value);
210 
211     } else if (strcmp(option, "fps") == 0) {
212         show_fps = get_boolean (value);
213 
214     } else if (strcmp(option, "show_digit") == 0) {
215         show_digits = get_boolean (value);;
216 
217     } else if (strcmp(option, "dir") == 0) {
218         strncpy(base_dir, value, sizeof(base_dir));
219 
220     } else if (strcmp(option, "randdelay") == 0) {
221         tmpint = atoi (value);
222         if (0 <= tmpint && tmpint < 60)
223             random_fun_delay = tmpint;
224 
225     } else if (strcmp(option, "depth") == 0) {
226         tmpfloat = (float)atof(value);
227         if (3.5 <= tmpfloat && tmpfloat < 40.0)
228             default_z_offset_distance = tmpfloat;
229 
230     } else if (strcmp(option, "win") == 0) {
231         do_fullscreen = from_cmdline ? 0 : get_boolean (value);
232 
233     } else if (strcmp(option, "acquire") == 0) {
234         acquire = 1;
235         if (value) {
236             tmpint = atoi (value);
237             // must be between 10ms and 3sec for now
238             if (10 < tmpint && tmpint < 3000)
239                 acquire = tmpint;
240         }
241 
242     } else if (strcmp(option, "nozoom") == 0) {
243         entry_exit_movement = !get_boolean (value);
244 
245     } else if (strcmp(option, "zoom") == 0) {
246         entry_exit_movement = get_boolean (value);
247 
248     } else if (strcmp(option, "gotocolumn") == 0) {
249         if (!value)
250             return 1;
251         goto_column = atoi(value);
252         if (goto_column < 1)
253             return 1;
254     } else if (strcmp(option, "gotorow") == 0) {
255         if (!value)
256             return 1;
257         goto_row = atoi(value);
258         if (goto_row < 1)
259             return 1;
260 
261     } else if (strcmp(option, "gotoright") == 0) {
262         goto_column = GOTO_FACE_RIGHT;
263     } else if (strcmp(option, "gotoleft") == 0) {
264         goto_column = GOTO_FACE_LEFT;
265     } else if (strcmp(option, "gotoup") == 0) {
266         goto_row = GOTO_FACE_UP;
267     } else if (strcmp(option, "gotodown") == 0) {
268         goto_row = GOTO_FACE_DOWN;
269 
270     } else if (strcmp(option, "dontexit") == 0) {
271         disable_exit_after_goto = get_boolean (value);
272 
273     } else if (strcmp(option, "glcompression") == 0) {
274         glcompression = get_boolean (value);
275 
276     } else if (strcmp(option, "reverse_mousewheel") == 0) {
277         reverse_mousewheel = get_boolean (value);
278 
279     } else if (strcmp(option, "swap_mousebuttons") == 0) {
280         swap_mousebuttons = get_boolean (value);
281 
282     } else if (strcmp(option, "alt_mousebuttons") == 0) {
283         alt_mousebuttons = get_boolean (value);
284 
285 //      } else if (strcmp(option, "background") == 0) {
286 //          strncpy(background, value, sizeof(background));
287 //            use_background_image = 1;
288 
289     } else {  // not found
290         return 1;
291     }
292 
293     return 0;  // success
294 }  // END Options::set_option
295 
296 
297 
Config()298 Config::Config ()
299 {
300 
301     // defaults
302     verbose = 0;
303 
304     use_kde = 0;
305     use_ewmh = 0;
306     sawfish_only = 0;
307     use_workspaces = 0;
308     use_viewareas = 0;
309     early_desktop_switch = 1;
310     disable_keys_in_goto = 1;
311     autoacquire = 0;
312     priority = 12;
313     use_context_switch = 1;
314     texture_size = 1024;
315     bg_texture_size = 256;
316     use_background_image = 0;
317     use_context_switch = 1;
318     mirror = 0;
319 
320     screen_width = 0;
321     screen_height = 0;
322 
323     strcpy(working_dir, "/tmp/3ddesktop");
324     pidfile[0] = 0;
325 
326     default_options = new Options("cmdline");
327     if (!default_options) {
328         msgout(ERROR, "out of memory: Config\n");
329         end_program(-1);
330     }
331     options = default_options;
332 } // END Config::Config
333 
~Config()334 Config::~Config ()
335 {
336     if (pidfile[0])
337         unlink(pidfile);
338     delete default_options;
339     list<Options *>::iterator k;
340     for (k = config_options.begin(); k != config_options.end(); k++)
341         delete *k;
342     config_options.clear();
343 
344     list<Config::keybinding *>::iterator i;
345     for (i = keybindings.begin(); i != keybindings.end(); i++)
346         delete *i;
347     keybindings.clear();
348 
349     list<Config::mousebinding *>::iterator i2;
350     for (i2 = mousebindings.begin(); i2 != mousebindings.end(); i2++)
351         delete *i2;
352     mousebindings.clear();
353 
354 } // END Config::~Config
355 
init_from_command_line(int argc,char ** argv)356 void Config::init_from_command_line (int argc, char **argv)
357 {
358 
359     int c;
360     int option_index;
361 
362     // these are cmd line options to the daemon
363     static struct option long_options[] = {
364         //{"fps", 0, 0, 0},
365         {"dir", 1, 0, 0},
366         {"workspaces", 0, 0, 0},
367         {"texturesize", 1, 0, 0},
368         {"fastest", 0, 0, 0},
369         {"win", 0, 0, 0},
370         {"sawfish", 0, 0, 0},
371         {"acquire", 2, 0, 0},
372         {"wm", 1, 0, 0},
373         {"kde", 0, 0, 0},
374         {"gnome2", 0, 0, 0},
375         {"ewmh", 0, 0, 0},
376         {"kde2", 0, 0, 0},
377         {"kde3", 0, 0, 0},
378         {"gnome", 0, 0, 0},
379         {"gnome1", 0, 0, 0},
380         {"version", 0, 0, 0},
381         {"mirror", 0, 0, 0},
382         {0, 0, 0, 0}
383     };
384 
385     while (1) {
386 
387         c = getopt_long (argc, argv, "v",
388                          long_options, &option_index);
389         if (c == -1)
390             break;
391 
392         switch (c) {
393         case 0: // long option
394 
395             if (strcmp((char *)long_options[option_index].name, "version") == 0) {
396                 printf("3ddesktop %s (3ddeskd server)\nWritten by Brad Wasson.\n\nCopyright (C) 2002 - 2005 Brad Wasson.\n"
397                        "This is free software; see the source for copying conditions.  There is NO\n"
398                        "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
399                        "This binary compiled %s %s.\n\n",
400                        VERSION, __DATE__, __TIME__);
401                 exit(0);
402             }
403 
404                 //msgout (DEBUG, "option %s", long_options[option_index].name);
405             if (set_global_option ((char *)long_options[option_index].name,
406                                    optarg, 1))
407             {
408                 if (default_options->set_option((char *)long_options[option_index].name,
409                                                 optarg, 1))
410                 {
411                     usage_and_bye();
412                 }
413             }
414 
415             break;
416         case 'v':
417             verbose = 1;
418             msgout (INFO, "Verbose is ON\n");
419             break;
420         default:
421             usage_and_bye();
422             break;
423         }
424     }  // end while args
425 } // END Config::init_from_command_line
426 
427 
set_global_option(char * option,char * value,bool from_cmdline)428 int Config::set_global_option(char *option, char *value, bool from_cmdline)
429 {
430 
431     if (strcmp(option, "verbose") == 0) {
432         verbose = get_boolean (value);
433 
434     } else if (strcmp(option, "texturesize") == 0) {
435         texture_size = atoi (value);
436 
437         switch (texture_size) {
438         case  16: case  32: case   64: case  128:
439         case 256: case 512: case 1024: case 2048:
440             break;
441         default:
442             // I now use gluBuild2DMipmaps so this isn't
443             // really necessary because it converts it however
444             // it is sooooo slow.  To use glTexImage2D it is
445             // necessary.
446             msgout (ERROR, "Texture size must be a power of 2 (such as 256, 512, 1024 ...)\n");
447             end_program(-1);  // should I ignore this error?
448             break;
449         }
450     } else if (strcmp(option, "default_background_texturesize") == 0) {
451         bg_texture_size = atoi (value);
452 
453         switch (bg_texture_size) {
454         case  16: case  32: case   64: case  128:
455         case 256: case 512: case 1024: case 2048:
456             break;
457         default:
458             // I now use gluBuild2DMipmaps so this isn't
459             // really necessary because it converts it however
460             // it is sooooo slow.  To use glTexImage2D it is
461             // necessary.
462             msgout (ERROR, "BG Texture size must be a power of 2 (such as 256, 512, 1024 ...)\n");
463             use_background_image = 0;
464             break;
465         }
466 
467     } else if (strcmp(option, "wm") == 0) {
468         if (!value)
469             return 1;
470 
471         if (strcmp (value, "sawfishonly") == 0) {
472             sawfish_only = 1;
473         } else if (strcmp (value, "kde") == 0 ||
474                    strcmp (value, "kde2") == 0) {
475             use_kde = 1;
476             use_ewmh = 0;
477         } else if (strcmp (value, "kde3") == 0) {
478             use_ewmh = 1;
479         } else if (strcmp (value, "gnome") == 0 ||
480                    strcmp (value, "gnome1") == 0 ||
481                    strcmp (value, "enlightenment") == 0) {
482             use_viewareas = 1;
483             use_workspaces = 1;
484             use_ewmh = 0;
485         } else if (strcmp (value, "gnome2") == 0 ||
486                    strcmp (value, "ewmh") == 0) {
487             use_ewmh = 1;
488         } else if (strcmp (value, "gnomeworkspaces") == 0 ||
489                    strcmp (value, "windowmaker") == 0 ||
490                    strcmp (value, "workspaces") == 0) {
491             use_workspaces = 1;
492             use_ewmh = 0;
493         } else if (strcmp (value, "fluxbox") == 0) {
494             use_ewmh = 1;
495             early_desktop_switch = 0;
496         } else {
497             return 1;
498         }
499 
500     } else if (strcmp(option, "sawfish") == 0) {
501         sawfish_only = from_cmdline ? 1 : get_boolean (value);
502 
503     } else if (strcmp(option, "kde") == 0) {
504         use_kde = from_cmdline ? 1 : get_boolean (value);
505 
506     } else if (strcmp(option, "kde2") == 0) {
507         use_kde = from_cmdline ? 1 : get_boolean (value);
508 
509     } else if (strcmp(option, "kde3") == 0) {
510         use_ewmh = from_cmdline ? 1 : get_boolean (value);
511 
512     } else if (strcmp(option, "gnome") == 0) {
513         // "gnome off" will actaully enable in .conf ... but oh well
514         use_ewmh = 0;
515         use_workspaces = 1;
516 
517     } else if (strcmp(option, "gnome1") == 0) {
518         use_ewmh = 0;
519         use_workspaces = 1;
520 
521     } else if (strcmp(option, "gnome2") == 0) {
522         use_ewmh = from_cmdline ? 1 : get_boolean (value);
523 
524     } else if (strcmp(option, "ewmh") == 0) {
525         use_ewmh = from_cmdline ? 1 : get_boolean (value);
526 
527     } else if (strcmp(option, "workspaces") == 0) {
528         use_workspaces = from_cmdline ? 1 : get_boolean (value);
529 
530     } else if (strcmp(option, "fastest") == 0) {
531         use_context_switch = !get_boolean (value);
532 
533     } else if (strcmp(option, "early_desktop_switch") == 0) {
534         early_desktop_switch = get_boolean (value);
535 
536     } else if (strcmp(option, "disable_keys_in_goto") == 0) {
537         disable_keys_in_goto = get_boolean (value);
538 
539     } else if (strcmp(option, "autoacquire") == 0) {
540         if (!strcmp(value, "off") ||
541             !strcmp(value, "no") ||
542             !strcmp(value, "false"))
543         {
544             autoacquire = 0;
545         } else {
546             autoacquire = atoi (value);
547         }
548 
549     } else if (strcmp(option, "mirror") == 0) {
550         mirror = 1;
551 
552     } else if (strcmp(option, "priority") == 0) {
553         priority = atoi (value);
554 
555     } else if (strcmp(option, "default_background") == 0) {
556         strncpy(default_background, value, sizeof(default_background));
557         use_background_image = 1;
558 
559     } else if (strcmp(option, "screen_width") == 0) {
560         screen_width = atoi (value);
561         if (screen_width < 10 || screen_width > 10000)
562             screen_width = 0;
563 
564     } else if (strcmp(option, "screen_height") == 0) {
565         screen_height = atoi (value);
566         if (screen_height < 10 || screen_height > 10000)
567             screen_height = 0;
568     } else if (strcmp(option, "keybinding_left") == 0) {
569         long tmp = strtol(value, NULL, 0);
570         keybindings.push_back(new keybinding(tmp, LEFT));
571 
572     } else if (strcmp(option, "keybinding_right") == 0) {
573         long tmp = strtol(value, NULL, 0);
574         keybindings.push_back(new keybinding(tmp, RIGHT));
575 
576     } else if (strcmp(option, "keybinding_up") == 0) {
577         long tmp = strtol(value, NULL, 0);
578         keybindings.push_back(new keybinding(tmp, UP));
579 
580     } else if (strcmp(option, "keybinding_down") == 0) {
581         long tmp = strtol(value, NULL, 0);
582         keybindings.push_back(new keybinding(tmp, DOWN));
583 
584     } else if (strcmp(option, "keybinding_select") == 0) {
585         long tmp = strtol(value, NULL, 0);
586         keybindings.push_back(new keybinding(tmp, SELECT));
587 
588     } else if (strcmp(option, "mousebinding_left") == 0) {
589         long tmp = strtol(value, NULL, 0);
590         mousebindings.push_back(new mousebinding(tmp, LEFT));
591 
592     } else if (strcmp(option, "mousebinding_right") == 0) {
593         long tmp = strtol(value, NULL, 0);
594         mousebindings.push_back(new mousebinding(tmp, RIGHT));
595 
596     } else if (strcmp(option, "mousebinding_up") == 0) {
597         long tmp = strtol(value, NULL, 0);
598         mousebindings.push_back(new mousebinding(tmp, UP));
599 
600     } else if (strcmp(option, "mousebinding_down") == 0) {
601         long tmp = strtol(value, NULL, 0);
602         mousebindings.push_back(new mousebinding(tmp, DOWN));
603 
604     } else if (strcmp(option, "mousebinding_select") == 0) {
605         long tmp = strtol(value, NULL, 0);
606         mousebindings.push_back(new mousebinding(tmp, SELECT));
607 
608     } else {
609         return 1;
610     }
611 
612     return 0;
613 } // END Config::set_global_option
614 
615 void
init(int argc,char ** argv)616 Config::init (int argc, char **argv)
617 {
618     init_from_command_line(argc, argv);
619 
620 //    sync_global_options();
621 
622     create_working_dir_if_necessary();
623 }
624 
625 void
set_config_set(char * name)626 Config::set_config_set (char *name)
627 {
628     if (!strcmp(name, "default") || !strcmp(name, "cmdline")) {
629         options = default_options;
630         return;
631     }
632 
633     int do_random = -1;
634     if (!strcmp(name, "random")) {
635         msgout (DEBUG, "*** picking random view\n");
636         do_random = get_randomi(0, config_options.size());
637     }
638 
639     list<Options *>::iterator k;
640     int cnt = 0;
641     for (k = config_options.begin(); k != config_options.end(); k++, cnt++) {
642 
643         if ( (do_random != -1 && cnt == do_random)
644              ||
645              (do_random == -1 && !strcmp ((*k)->name, name)) )
646         {
647             options = *k;
648             msgout (DEBUG, "*** FOUND cfg set %s\n", (*k)->name);
649             break;
650         }
651     }
652 }  // END Config::set_config_set
653 
654 
655 void
reload(void)656 Config::reload (void)
657 {
658     // FIXME: track .conf timestamp for reloading efficiency?
659 
660     list<Config::keybinding *>::iterator i;
661     for (i = keybindings.begin(); i != keybindings.end(); i++)
662         delete *i;
663     keybindings.clear();
664 
665     list<Config::mousebinding *>::iterator i2;
666     for (i2 = mousebindings.begin(); i2 != mousebindings.end(); i2++)
667         delete *i2;
668     mousebindings.clear();
669 
670     list<Options *>::iterator k;
671     for (k = config_options.begin(); k != config_options.end(); k++)
672         delete *k;
673     config_options.clear();
674     options = default_options;
675     load_conf();
676 }
677 
load_conf(void)678 void Config::load_conf (void)
679 {
680     // FIXME: track .conf timestamp for reloading efficiency?
681 
682     // Try opening  ~/.3ddesktop/3ddesktop.conf
683     //       then   /usr/share/3ddesktop/3ddesktop.conf
684 
685     sprintf(config_file, "%s/3ddesktop.conf", working_dir);
686 
687     FILE *fp = fopen(config_file, "r");
688     if (!fp) {
689 
690         sprintf(config_file, SYSCONFDIR "/3ddesktop.conf");
691 
692         fp = fopen(config_file, "r");
693         if (!fp) {
694 
695             // don't error on this - may not be there
696             msgout (DEBUG, "Could not open config file: 3ddesktop.conf: %s\n",
697                     strerror(errno));
698             return;
699         }
700     }
701 
702     msgout (DEBUG, "load_conf: opened %s\n", config_file);
703 
704     // init some things so they aren't 'sticky'
705     use_background_image = 0;
706 //        default_options->__use_background_image = 0;
707 
708 
709     char var1[100];
710     char var2[100];
711     char var3[100];
712     char var4[100];
713     char var5[100];
714 
715     char buf[1000];
716     int buf_size = 1000;
717 
718     char *p = NULL;
719     int n, line = 0;;
720 
721     Options *o = NULL;
722 
723     while (fgets (buf, buf_size, fp) ) {
724 
725         line++;
726 
727         //msgout (DEBUG, "config load: line %d read -> %s\n", line, buf);
728 
729         // null terminate at comment
730         p = strpbrk (buf, "#");
731         if (p)
732             *p = 0;
733 
734         // now see if blank line
735         n = strspn(buf, " \t\n");
736         if (n == (int)strlen (buf))
737             continue;
738 
739         n = sscanf(buf, "%s %s %s %s %s", var1, var2, var3, var4, var5);
740 
741         if (n < 2) {
742             msgout (DEBUG, "config load: see %d vars only (line %d)\n", n, line);
743             continue;
744         }
745 
746         // ok something meaningful(less?) in vars
747 
748         //msgout (DEBUG, "config load: line %d found: %s %s\n", line, var1, var2);
749 
750         if (strcmp(var1, "view") == 0) {
751             if (strcmp(var2, "default") == 0) {
752                 o = default_options;
753 
754             } else {
755                 o = new Options(var2);
756                 if (!o) {
757                     msgout (ERROR, "out of memory for Options\n");
758                     end_program(-1);
759                 }
760                 msgout (DEBUG, "Found view: %s\n", var2);
761                 config_options.push_back(o);
762             }
763 
764             continue;
765         }
766 
767         if (!o) {
768             //msgout(DEBUG, "not in a option set\n");
769 
770             // Treat these as "global" options
771             if (set_global_option(var1, var2, 0)) {
772                 // option not found try default
773                 default_options->set_option(var1, var2, 0);
774             }
775 
776 //                sync_global_options();
777         } else {
778             o->set_option(var1, var2, 0);
779         }
780     }
781 
782     fclose (fp);
783 } // END Config::load_conf
784 
785 void
create_working_dir_if_necessary(void)786 Config::create_working_dir_if_necessary (void)
787 {
788     // first formulat the full path to location
789     char *home_dir = getenv("HOME");
790     char *username = getenv("USER");
791     char failsafe[] = "noname";
792 
793     if (username == NULL) {
794         username = getenv("LOGNAME");
795         if (username == NULL) {
796             username = getlogin();
797             if (username == NULL)
798                 username = failsafe;
799         }
800     }
801 
802     if (home_dir == NULL || use_tmp) {
803         //msgout (DEBUG, "$HOME not set: using /tmp/.3ddesktop-user\n");
804         sprintf(working_dir, "/tmp/.3ddesktop-%s", username);
805     } else {
806         sprintf(working_dir, "%s/.3ddesktop", home_dir);
807     }
808 
809 
810     DIR *dir_p = opendir (working_dir);
811     if (dir_p == NULL) {
812         if (errno == ENOENT) {
813             // try to make the dir now
814 
815             //char cmd[100];
816             //sprintf (cmd, "mkdir %s", working_dir);
817             //system (cmd);
818             if (mkdir (working_dir, S_IRWXU) < 0) {
819                 msgout(ERROR, "Could not make directory %s: %s\n",
820                        working_dir, strerror(errno));
821                 end_program(1);
822             }
823         } else {
824             msgout(ERROR, "Could not open directory %s: %s\n",
825                    working_dir, strerror(errno));
826             end_program (1);
827         }
828     } else {
829         closedir(dir_p);
830     }
831 } // END Config::create_working_dir_if_necessary
832 
833 int
make_pidfile(void)834 Config::make_pidfile (void)
835 {
836     pid_t pid;
837 
838     sprintf (pidfile, "%s/pid", working_dir);
839 
840     FILE *fh = fopen (pidfile, "w");
841     if (fh == NULL) {
842         msgout (ERROR, "Could not open %s: %s\n",
843                 pidfile, strerror(errno));
844         return -1;
845     }
846 
847     pid = getpid();
848 
849     fprintf (fh, "%d", pid);
850 
851     fclose (fh);
852 
853     return 0;
854 } // END Config::make_pidfile
855