1 /*
2 * Copyright (c) 2000 Andrew Ferguson <andrew@owsla.cjb.net>
3 * Copyright (c) 1998 Sasha Vasko <sasha at aftercode.net>
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 *
19 */
20
21
22 #define LOCAL_DEBUG
23 #include "../configure.h"
24 #include "../libAfterStep/asapp.h"
25 #include "../libAfterStep/afterstep.h"
26 #include "../libAfterStep/screen.h"
27 #include "../libAfterStep/parser.h"
28 #include "../libAfterStep/session.h"
29 #include "../libAfterImage/afterimage.h"
30
31 #include "afterconf.h"
32
33
34 /*****************************************************************************
35 *
36 * This routine is responsible for reading and parsing the base.<bpp> config
37 * file
38 *
39 ****************************************************************************/
40
41 TermDef BaseTerms[] = {
42 {TF_NO_MYNAME_PREPENDING, "ModulePath", 10, TT_PATHNAME,
43 BASE_MODULE_PATH_ID, NULL}
44 ,
45 {TF_NO_MYNAME_PREPENDING, "SoundPath", 9, TT_PATHNAME,
46 BASE_SOUND_PATH_ID, NULL}
47 ,
48 {TF_NO_MYNAME_PREPENDING, "IconPath", 8, TT_PATHNAME, BASE_ICON_PATH_ID,
49 NULL}
50 ,
51 {TF_NO_MYNAME_PREPENDING, "PixmapPath", 10, TT_PATHNAME,
52 BASE_PIXMAP_PATH_ID, NULL}
53 ,
54 {TF_NO_MYNAME_PREPENDING, "FontPath", 8, TT_PATHNAME, BASE_FONT_PATH_ID,
55 NULL}
56 ,
57 {TF_NO_MYNAME_PREPENDING, "CursorPath", 10, TT_PATHNAME,
58 BASE_CURSOR_PATH_ID, NULL}
59 ,
60 {TF_NO_MYNAME_PREPENDING, "Path", 4, TT_PATHNAME, BASE_MYNAME_PATH_ID,
61 NULL}
62 ,
63 {TF_NO_MYNAME_PREPENDING, "gtkrcPath", 9, TT_PATHNAME,
64 BASE_GTKRC_PATH_ID, NULL}
65 ,
66 {TF_NO_MYNAME_PREPENDING, "gtkrc20Path", 11, TT_PATHNAME,
67 BASE_GTKRC20_PATH_ID, NULL}
68 ,
69 {TF_NO_MYNAME_PREPENDING, "DeskTopSize", 11, TT_GEOMETRY,
70 BASE_DESKTOP_SIZE_ID, NULL}
71 ,
72 {TF_NO_MYNAME_PREPENDING, "DeskTopScale", 12, TT_INTEGER,
73 BASE_DESKTOP_SCALE_ID, NULL}
74 ,
75 {TF_NO_MYNAME_PREPENDING | TF_INDEXED, "TermCommand", 11, TT_TEXT,
76 BASE_TermCommand_ID, NULL}
77 ,
78 {TF_NO_MYNAME_PREPENDING | TF_INDEXED, "BrowserCommand", 14, TT_TEXT,
79 BASE_BrowserCommand_ID, NULL}
80 ,
81 {TF_NO_MYNAME_PREPENDING | TF_INDEXED, "EditorCommand", 13, TT_TEXT,
82 BASE_EditorCommand_ID, NULL}
83 ,
84 {TF_NO_MYNAME_PREPENDING, "DisableSharedMemory", 19, TT_FLAG,
85 BASE_NoSharedMemory_ID, NULL}
86 ,
87 {TF_NO_MYNAME_PREPENDING, "DisableKDEGlobalsTheming", 24, TT_FLAG,
88 BASE_NoKDEGlobalsTheming_ID, NULL}
89 ,
90 {TF_NO_MYNAME_PREPENDING, "NoModuleNameCollisions", 22, TT_INTEGER,
91 BASE_NoModuleNameCollisions_ID, NULL}
92 ,
93 {TF_NO_MYNAME_PREPENDING, "IconTheme", 9, TT_TEXT, BASE_IconTheme_ID,
94 NULL}
95 ,
96 {TF_NO_MYNAME_PREPENDING, "IconThemePath", 14, TT_PATHNAME,
97 BASE_IconThemePath_ID, NULL}
98 ,
99 {TF_NO_MYNAME_PREPENDING, "IconThemeFallback", 18, TT_PATHNAME,
100 BASE_IconThemeFallback_ID, NULL}
101 ,
102 {0, NULL, 0, 0, 0}
103 };
104
105 SyntaxDef BaseSyntax = {
106 '\n',
107 '\0',
108 BaseTerms,
109 0, /* use default hash size */
110 ' ',
111 "",
112 "\t",
113 "AfterStep Base configuration",
114 "Base",
115 "essential AfterStep configuration options",
116 NULL,
117 0
118 };
119
120 flag_options_xref BaseFlags[] = {
121 {BASE_NO_SHARED_MEMORY, BASE_NoSharedMemory_ID, 0}
122 ,
123 {BASE_NO_KDEGLOBALS_THEMING, BASE_NoKDEGlobalsTheming_ID, 0}
124 ,
125 {0, 0, 0}
126 };
127
128
CreateBaseConfig()129 BaseConfig *CreateBaseConfig ()
130 {
131 BaseConfig *config = safecalloc (1, sizeof (BaseConfig));
132
133 /* let's initialize Base config with some nice values: */
134 config->desktop_size.flags = WidthValue | HeightValue;
135 config->desktop_size.width = config->desktop_size.height = 1;
136 config->desktop_size.x = config->desktop_size.y = 0;
137 config->desktop_scale = 32;
138
139 return config;
140 }
141
DestroyBaseConfig(BaseConfig * config)142 void DestroyBaseConfig (BaseConfig * config)
143 {
144 int i = MAX_TOOL_COMMANDS;
145
146 destroy_string (&(config->module_path));
147 destroy_string (&(config->sound_path));
148 destroy_string (&(config->icon_path));
149 destroy_string (&(config->pixmap_path));
150 destroy_string (&(config->font_path));
151 destroy_string (&(config->cursor_path));
152 destroy_string (&(config->myname_path));
153 destroy_string (&(config->gtkrc_path));
154 destroy_string (&(config->gtkrc20_path));
155 destroy_string (&(config->IconTheme));
156 destroy_string (&(config->IconThemePath));
157 destroy_string (&(config->IconThemeFallback));
158
159 while (--i >= 0) {
160 destroy_string (&(config->term_command[i]));
161 destroy_string (&(config->browser_command[i]));
162 destroy_string (&(config->editor_command[i]));
163 }
164
165 DestroyFreeStorage (&(config->more_stuff));
166 free (config);
167 }
168
ParseBaseOptions(const char * filename,char * myname)169 BaseConfig *ParseBaseOptions (const char *filename, char *myname)
170 {
171 BaseConfig *config = CreateBaseConfig ();
172 FreeStorageElem *Storage = NULL, *pCurr;
173 ConfigItem item;
174
175 Storage =
176 file2free_storage (filename, myname, &BaseSyntax, NULL,
177 &(config->more_stuff));
178 if (Storage == NULL)
179 return config;
180
181 item.memory = NULL;
182
183 for (pCurr = Storage; pCurr; pCurr = pCurr->next) {
184 if (pCurr->term == NULL)
185 continue;
186 if (ReadFlagItem
187 (&(config->set_flags), &(config->flags), pCurr, BaseFlags))
188 continue;
189 if (!ReadConfigItem (&item, pCurr))
190 continue;
191 switch (pCurr->term->id) {
192 case BASE_MODULE_PATH_ID:
193 set_string (&(config->module_path), item.data.string);
194 break;
195 case BASE_SOUND_PATH_ID:
196 set_string (&(config->sound_path), item.data.string);
197 break;
198 case BASE_ICON_PATH_ID:
199 set_string (&(config->icon_path), item.data.string);
200 break;
201 case BASE_PIXMAP_PATH_ID:
202 set_string (&(config->pixmap_path), item.data.string);
203 break;
204 case BASE_FONT_PATH_ID:
205 set_string (&(config->font_path), item.data.string);
206 break;
207 case BASE_CURSOR_PATH_ID:
208 set_string (&(config->cursor_path), item.data.string);
209 break;
210 case BASE_MYNAME_PATH_ID:
211 set_string (&(config->myname_path), item.data.string);
212 break;
213 case BASE_GTKRC_PATH_ID:
214 set_string (&(config->gtkrc_path), item.data.string);
215 break;
216 case BASE_GTKRC20_PATH_ID:
217 set_string (&(config->gtkrc20_path), item.data.string);
218 break;
219 case BASE_DESKTOP_SIZE_ID:
220 set_flags (config->set_flags, BASE_DESKTOP_SIZE_SET);
221 config->desktop_size = item.data.geometry;
222 /* errorneous value check */
223 if (!(config->desktop_size.flags & WidthValue))
224 config->desktop_size.width = 1;
225 if (!(config->desktop_size.flags & HeightValue))
226 config->desktop_size.height = 1;
227 config->desktop_size.flags = WidthValue | HeightValue;
228 break;
229 case BASE_DESKTOP_SCALE_ID:
230 set_flags (config->set_flags, BASE_DESKTOP_SCALE_SET);
231 config->desktop_scale = item.data.integer;
232 /* errorneous value check */
233 if (config->desktop_scale < 1)
234 config->desktop_scale = 1;
235 break;
236 case BASE_NoModuleNameCollisions_ID:
237 set_flags (config->set_flags, BASE_NoModuleNameCollisions_SET);
238 config->NoModuleNameCollisions = item.data.integer;
239 break;
240 case BASE_TermCommand_ID:
241 if (item.index < MAX_TOOL_COMMANDS && item.index >= 0)
242 set_string (&(config->term_command[item.index]), item.data.string);
243 else
244 item.ok_to_free = 1;
245 break;
246 case BASE_BrowserCommand_ID:
247 if (item.index < MAX_TOOL_COMMANDS && item.index >= 0)
248 set_string (&(config->browser_command[item.index]),
249 item.data.string);
250 else
251 item.ok_to_free = 1;
252 break;
253 case BASE_EditorCommand_ID:
254 if (item.index < MAX_TOOL_COMMANDS && item.index >= 0)
255 set_string (&(config->editor_command[item.index]),
256 item.data.string);
257 else
258 item.ok_to_free = 1;
259 break;
260 case BASE_IconTheme_ID:
261 set_string (&(config->IconTheme), item.data.string);
262 break;
263 case BASE_IconThemePath_ID:
264 set_string (&(config->IconThemePath), item.data.string);
265 break;
266 case BASE_IconThemeFallback_ID:
267 set_string (&(config->IconThemeFallback), item.data.string);
268 break;
269 default:
270 item.ok_to_free = 1;
271 }
272 }
273 ReadConfigItem (&item, NULL);
274
275 DestroyFreeStorage (&Storage);
276 return config;
277 }
278
279 /* returns:
280 * 0 on success
281 * 1 if data is empty
282 * 2 if ConfigWriter cannot be initialized
283 *
284 */
285 int
WriteBaseOptions(const char * filename,char * myname,BaseConfig * config,unsigned long flags)286 WriteBaseOptions (const char *filename, char *myname, BaseConfig * config,
287 unsigned long flags)
288 {
289 ConfigDef *BaseConfigWriter = NULL;
290 FreeStorageElem *Storage = NULL, **tail = &Storage;
291 ConfigData cd;
292
293 if (config == NULL)
294 return 1;
295 cd.filename = filename;
296 if ((BaseConfigWriter =
297 InitConfigWriter (myname, &BaseSyntax, CDT_Filename, cd)) == NULL)
298 return 2;
299
300 CopyFreeStorage (&Storage, config->more_stuff);
301
302 /* building free storage here */
303
304 /* module_path */
305 tail =
306 String2FreeStorage (&BaseSyntax, tail, config->module_path,
307 BASE_MODULE_PATH_ID);
308
309 /* icon_path */
310 tail =
311 String2FreeStorage (&BaseSyntax, tail, config->icon_path,
312 BASE_ICON_PATH_ID);
313
314 /* pixmap_path */
315 tail =
316 String2FreeStorage (&BaseSyntax, tail, config->pixmap_path,
317 BASE_PIXMAP_PATH_ID);
318
319 /* cursor_path */
320 tail =
321 String2FreeStorage (&BaseSyntax, tail, config->cursor_path,
322 BASE_CURSOR_PATH_ID);
323
324 /* sound_path */
325 tail =
326 String2FreeStorage (&BaseSyntax, tail, config->sound_path,
327 BASE_SOUND_PATH_ID);
328
329 /* myname_path */
330 tail =
331 String2FreeStorage (&BaseSyntax, tail, config->myname_path,
332 BASE_MYNAME_PATH_ID);
333
334 /* IconTheme */
335 tail =
336 String2FreeStorage (&BaseSyntax, tail, config->IconTheme,
337 BASE_IconTheme_ID);
338 /* IconThemePath */
339 tail =
340 String2FreeStorage (&BaseSyntax, tail, config->IconThemePath,
341 BASE_IconThemePath_ID);
342 /* IconThemeFallback */
343 tail =
344 String2FreeStorage (&BaseSyntax, tail, config->IconThemeFallback,
345 BASE_IconThemeFallback_ID);
346
347 /* desktop_size */
348 tail =
349 Geometry2FreeStorage (&BaseSyntax, tail, &(config->desktop_size),
350 BASE_DESKTOP_SIZE_ID);
351
352 /* desktop_scale */
353 tail =
354 Integer2FreeStorage (&BaseSyntax, tail, NULL, config->desktop_scale,
355 BASE_DESKTOP_SCALE_ID);
356
357 cd.filename = filename;
358 /* writing config into the file */
359 WriteConfig (BaseConfigWriter, Storage, CDT_Filename, &cd, flags);
360 DestroyFreeStorage (&Storage);
361 DestroyConfig (BaseConfigWriter);
362
363 return 0;
364 }
365
366 /*************************************************************************
367 * Supplementary functionality to handle Base configuration changes.
368 *************************************************************************/
369 void
ExtractPath(BaseConfig * config,char ** module_path,char ** sound_path,char ** icon_path,char ** pixmap_path,char ** font_path,char ** cursor_path,char ** myname_path,char ** gtkrc_path,char ** gtkrc20_path)370 ExtractPath (BaseConfig * config,
371 char **module_path,
372 char **sound_path,
373 char **icon_path,
374 char **pixmap_path,
375 char **font_path, char **cursor_path, char **myname_path,
376 char **gtkrc_path, char **gtkrc20_path)
377 {
378 register char *tmp;
379
380 if (config) {
381 if (module_path && config->module_path) {
382 tmp = copy_replace_envvar (config->module_path);
383 set_string (module_path, tmp);
384 }
385 if (sound_path && config->sound_path) {
386 tmp = copy_replace_envvar (config->sound_path);
387 set_string (sound_path, tmp);
388 }
389 if (icon_path && config->icon_path) {
390 tmp = copy_replace_envvar (config->icon_path);
391 set_string (icon_path, tmp);
392 }
393 if (pixmap_path && config->pixmap_path) {
394 tmp = copy_replace_envvar (config->pixmap_path);
395 set_string (pixmap_path, tmp);
396 }
397 if (font_path && config->font_path) {
398 tmp = copy_replace_envvar (config->font_path);
399 set_string (font_path, tmp);
400 }
401 if (cursor_path && config->cursor_path) {
402 tmp = copy_replace_envvar (config->cursor_path);
403 set_string (cursor_path, tmp);
404 }
405 if (myname_path && config->myname_path) {
406 tmp = copy_replace_envvar (config->myname_path);
407 set_string (myname_path, tmp);
408 }
409 if (gtkrc_path && config->gtkrc_path) {
410 tmp = make_session_rc_file (Session, config->gtkrc_path);
411 set_string (gtkrc_path, tmp);
412 }
413 if (gtkrc20_path && config->gtkrc20_path) {
414 tmp = make_session_rc_file (Session, config->gtkrc20_path);
415 set_string (gtkrc20_path, tmp);
416 }
417 }
418 }
419
420 void
BaseConfig2ASEnvironment(register BaseConfig * config,ASEnvironment ** penv)421 BaseConfig2ASEnvironment (register BaseConfig * config,
422 ASEnvironment ** penv)
423 {
424 register ASEnvironment *env = *penv;
425
426 if (env == NULL)
427 env = make_default_environment ();
428 ExtractPath (config, &(env->module_path),
429 &(env->sound_path),
430 &(env->icon_path),
431 &(env->pixmap_path),
432 &(env->font_path), &(env->cursor_path), NULL,
433 &(env->gtkrc_path), &(env->gtkrc20_path));
434 set_string (&(env->IconTheme), mystrdup (config->IconTheme));
435 set_string (&(env->IconThemePath), mystrdup (config->IconThemePath));
436 set_string (&(env->IconThemeFallback), mystrdup (config->IconThemeFallback));
437
438 if (config->desktop_size.flags & WidthValue)
439 env->desk_pages_h = config->desktop_size.width;
440 else
441 env->desk_pages_h = 0;
442
443 if (config->desktop_size.flags & HeightValue)
444 env->desk_pages_v = config->desktop_size.height;
445 else
446 env->desk_pages_v = 0;
447 env->desk_scale = config->desktop_scale;
448
449 switch (config->NoModuleNameCollisions % 3) {
450 case 0:
451 env->module_name_collision = ASE_AllowModuleNameCollision;
452 break;
453 case 1:
454 env->module_name_collision = ASE_KillOldModuleOnNameCollision;
455 break;
456 case 2:
457 env->module_name_collision = ASE_KillNewModuleOnNameCollision;
458 break;
459 }
460
461 set_environment_tool_from_list (env, ASTool_Term, config->term_command,
462 MAX_TOOL_COMMANDS);
463 set_environment_tool_from_list (env, ASTool_Browser,
464 config->browser_command,
465 MAX_TOOL_COMMANDS);
466 set_environment_tool_from_list (env, ASTool_Editor,
467 config->editor_command,
468 MAX_TOOL_COMMANDS);
469
470 if (get_flags (config->set_flags, BASE_NO_SHARED_MEMORY)) {
471 if (get_flags (config->flags, BASE_NO_SHARED_MEMORY))
472 set_flags (env->flags, ASE_NoSharedMemory);
473 else
474 clear_flags (env->flags, ASE_NoSharedMemory);
475 }
476 if (get_flags (config->set_flags, BASE_NO_KDEGLOBALS_THEMING)) {
477 if (get_flags (config->flags, BASE_NO_KDEGLOBALS_THEMING))
478 set_flags (env->flags, ASE_NoKDEGlobalsTheming);
479 else
480 clear_flags (env->flags, ASE_NoKDEGlobalsTheming);
481 }
482 *penv = env;
483 }
484
485 Bool
ReloadASEnvironment(ASImageManager ** old_imageman,ASFontManager ** old_fontman,BaseConfig ** config_return,Bool flush_images,Bool support_shared_images)486 ReloadASEnvironment (ASImageManager ** old_imageman,
487 ASFontManager ** old_fontman,
488 BaseConfig ** config_return, Bool flush_images,
489 Bool support_shared_images)
490 {
491 char *old_pixmap_path = NULL;
492 char *old_font_path = NULL;
493 char *configfile = NULL;
494 BaseConfig *config = NULL;
495 ASEnvironment *e = NULL;
496 ScreenInfo *scr = get_current_screen ();
497
498 if (Environment != NULL) {
499 old_pixmap_path = Environment->pixmap_path;
500 Environment->pixmap_path = NULL;
501 old_font_path = Environment->font_path;
502 Environment->font_path = NULL;
503 }
504
505 configfile = Session->overriding_file;
506 if (configfile == NULL)
507 configfile =
508 make_session_file (Session, BASE_FILE,
509 False /* no longer use #bpp in filenames */ );
510 if (configfile != NULL) {
511 config = ParseBaseOptions (configfile, MyName);
512 if (config != NULL)
513 show_progress ("BASE configuration loaded from \"%s\" ...",
514 configfile);
515 else
516 show_progress ("BASE could not be loaded from \"%s\" ...",
517 configfile);
518 if (configfile != Session->overriding_file)
519 free (configfile);
520 } else
521 show_warning ("BASE configuration file cannot be found");
522
523 if (config == NULL) {
524 if (Environment != NULL) {
525 Environment->pixmap_path = old_pixmap_path;
526 Environment->font_path = old_font_path;
527 return False;
528 }
529 /* otherwise we should use default values - Environment should never be NULL */
530 Environment = make_default_environment ();
531 } else {
532 BaseConfig2ASEnvironment (config, &Environment);
533 if (config_return)
534 *config_return = config;
535 else
536 DestroyBaseConfig (config);
537 }
538
539 e = Environment;
540 /* Save base filename to pass to modules */
541 if (mystrcmp (old_pixmap_path, e->pixmap_path) == 0 ||
542 (e->pixmap_path != NULL && scr->image_manager == NULL)
543 || flush_images) {
544 reload_screen_image_manager (scr, old_imageman);
545 }
546 if (old_pixmap_path && old_pixmap_path != e->pixmap_path)
547 free (old_pixmap_path);
548
549 if (mystrcmp (old_font_path, e->font_path) == 0
550 || (e->font_path != NULL && scr->font_manager == NULL)) {
551 if (old_fontman) {
552 *old_fontman = scr->font_manager;
553 } else if (scr->font_manager)
554 destroy_font_manager (scr->font_manager, False);
555
556 scr->font_manager = create_font_manager (dpy, e->font_path, NULL);
557 set_xml_font_manager (scr->font_manager);
558 show_progress ("Font Path changed to \"%s\" ...",
559 e->font_path ? e->font_path : "");
560 }
561 if (old_font_path && old_font_path != e->font_path)
562 free (old_font_path);
563
564 if (e->desk_pages_h > 0) {
565 if (e->desk_pages_h <= 100)
566 scr->VxMax = (e->desk_pages_h - 1) * scr->MyDisplayWidth;
567 else {
568 scr->VxMax =
569 MAX (e->desk_pages_h, scr->MyDisplayWidth) - scr->MyDisplayWidth;
570 e->desk_pages_h =
571 (e->desk_pages_h + scr->MyDisplayWidth -
572 1) / scr->MyDisplayWidth;
573 }
574 } else
575 scr->VxMax = 0;
576 if (e->desk_pages_v > 0) {
577 if (e->desk_pages_v <= 100)
578 scr->VyMax = (e->desk_pages_v - 1) * scr->MyDisplayHeight;
579 else {
580 scr->VyMax =
581 MAX (e->desk_pages_v,
582 scr->MyDisplayHeight) - scr->MyDisplayHeight;
583 e->desk_pages_v =
584 (e->desk_pages_v + scr->MyDisplayHeight -
585 1) / scr->MyDisplayHeight;
586 }
587 } else
588 scr->VyMax = 0;
589
590 scr->VScale = e->desk_scale;
591 if (scr->VScale <= 1)
592 scr->VScale = 2;
593 else if (scr->VScale >= scr->MyDisplayHeight / 2)
594 scr->VScale = scr->MyDisplayHeight / 2;
595
596 #ifdef XSHMIMAGE
597 if (support_shared_images) {
598 if (get_flags (e->flags, ASE_NoSharedMemory))
599 disable_shmem_images ();
600 else
601 enable_shmem_images ();
602 }
603 SHOW_CHECKPOINT;
604 #endif
605
606
607 return (config != NULL);
608 }
609