1 /*
2 * Copyright (c) 2000 Sasha Vasko <sasha at aftercode.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 *
18 */
19
20 #define LOCAL_DEBUG
21 #include "../configure.h"
22 #include "../libAfterStep/asapp.h"
23 #include "../libAfterStep/afterstep.h"
24 #include "../libAfterStep/mystyle.h"
25 #include "../libAfterStep/parser.h"
26 #include "../libAfterStep/balloon.h"
27
28 #include "afterconf.h"
29
30
31 /*****************************************************************************
32 *
33 * This routine is responsible for reading and parsing the base.<bpp> config
34 * file
35 *
36 ****************************************************************************/
37
38 #define WHARF_FOLDER_END "~Folder"
39
40
41 TermDef WhevTerms[] = {
42 {TF_NO_MYNAME_PREPENDING | TF_SYNTAX_TERMINATOR, "push", 4, TT_FILENAME,
43 WHEV_PUSH_ID, NULL}
44 ,
45 {TF_NO_MYNAME_PREPENDING | TF_SYNTAX_TERMINATOR, "close_folder", 12,
46 TT_FILENAME, WHEV_CLOSE_FOLDER_ID, NULL}
47 ,
48 {TF_NO_MYNAME_PREPENDING | TF_SYNTAX_TERMINATOR, "open_folder", 11,
49 TT_FILENAME, WHEV_OPEN_FOLDER_ID, NULL}
50 ,
51 {TF_NO_MYNAME_PREPENDING | TF_SYNTAX_TERMINATOR, "close_main", 10,
52 TT_FILENAME, WHEV_CLOSE_MAIN_ID, NULL}
53 ,
54 {TF_NO_MYNAME_PREPENDING | TF_SYNTAX_TERMINATOR, "open_main", 9,
55 TT_FILENAME, WHEV_OPEN_MAIN_ID, NULL}
56 ,
57 {TF_NO_MYNAME_PREPENDING | TF_SYNTAX_TERMINATOR, "drop", 4, TT_FILENAME,
58 WHEV_DROP_ID, NULL}
59 ,
60 {0, NULL, 0, 0, 0, NULL}
61 };
62
63 SyntaxDef WhevSyntax = {
64 '\0',
65 '\n',
66 WhevTerms,
67 0, /* use default hash size */
68 ' ',
69 "",
70 "\t",
71 "Module:Wharf sound definition",
72 "WharfSounds",
73 "types of events for which sound could be played by Wharf",
74 NULL,
75 0
76 };
77
78 #define WHARF_FEEL_TERMS \
79 {0, "WithdrawStyle", 13, TT_UINTEGER, WHARF_WithdrawStyle_ID, NULL}, \
80 {0, "AnimateStepsMain", 16, TT_UINTEGER, WHARF_AnimateStepsMain_ID, NULL}, \
81 {0, "AnimateSteps", 12, TT_UINTEGER, WHARF_AnimateSteps_ID, NULL}, \
82 {0, "AnimateDelay", 12, TT_UINTEGER, WHARF_AnimateDelay_ID, NULL}, \
83 {0, "AnimateMain", 11, TT_FLAG, WHARF_AnimateMain_ID, NULL}, \
84 {0, "Animate", 7, TT_FLAG, WHARF_Animate_ID, NULL}
85
86 #define WHARF_LOOK_TERMS \
87 {0, "ShowLabel", 9, TT_FLAG, WHARF_ShowLabel_ID, NULL}, \
88 ASCF_DEFINE_KEYWORD(WHARF, 0, LabelLocation , TT_UINTEGER , NULL), \
89 ASCF_DEFINE_KEYWORD(WHARF, 0, FlipLabel , TT_FLAG , NULL), \
90 ASCF_DEFINE_KEYWORD(WHARF, 0, FitContents , TT_FLAG , NULL), \
91 ASCF_DEFINE_KEYWORD(WHARF, 0, ShapeToContents , TT_FLAG , NULL), \
92 ASCF_DEFINE_KEYWORD(WHARF, 0, StretchBackground , TT_FLAG , NULL), \
93 ASCF_DEFINE_KEYWORD(WHARF, 0, AlignContents , TT_FLAG , &AlignSyntax), \
94 ASCF_DEFINE_KEYWORD(WHARF, 0, Bevel , TT_FLAG , &BevelSyntax), \
95 ASCF_DEFINE_KEYWORD(WHARF, 0, CompositionMethod , TT_INTEGER , NULL), \
96 ASCF_DEFINE_KEYWORD(WHARF, 0, FolderOffset , TT_INTEGER , NULL), \
97 ASCF_DEFINE_KEYWORD(WHARF, 0, OrthogonalFolderOffset, TT_INTEGER , NULL), \
98 ASCF_DEFINE_KEYWORD(WHARF, 0, ShowHints , TT_FLAG , &BalloonContentsSyntax)
99
100
101 #define WHARF_PRIVATE_TERMS \
102 {0, "Sound", 5, TT_FILENAME, WHARF_Sound_ID, &WhevSyntax}, \
103 {0, "Geometry", 8, TT_GEOMETRY, WHARF_Geometry_ID, NULL}, \
104 {0, "Rows", 4, TT_UINTEGER, WHARF_Rows_ID, NULL}, \
105 {0, "Columns", 7, TT_UINTEGER, WHARF_Columns_ID, NULL}, \
106 {0, "ForceSize", 9, TT_GEOMETRY, WHARF_ForceSize_ID, NULL}
107
108 #define WHARF_FOLDER_TERMS \
109 {TF_SPECIAL_PROCESSING|TF_NAMED|TF_USE_TOKENS(1), "", 0, TT_ICON_LIST, WHARF_Wharf_ID, &DummyFuncSyntax}, \
110 {TF_SYNTAX_TERMINATOR, WHARF_FOLDER_END, 7, TT_FLAG, WHARF_FolderEnd_ID, NULL}
111
112
113 TermDef WharfTerms[] = {
114 /* the NoWithdraw option is undocumented, deprecated, and
115 ** may be removed at Wharf's maintainer's discretion */
116 {TF_OBSOLETE, "NoWithdraw", 10, TT_FLAG, WHARF_NoWithdraw_ID, NULL}
117 ,
118 /* TextureType, MaxColors, BgColor, TextureColor, and Pixmap are obsolete */
119 {TF_OBSOLETE, "TextureType", 11, TT_UINTEGER, WHARF_TextureType_ID, NULL}
120 ,
121 {TF_OBSOLETE, "BgColor", 7, TT_COLOR, WHARF_BgColor_ID, NULL}
122 ,
123 {TF_OBSOLETE, "TextureColor", 12, TT_COLOR, WHARF_TextureColor_ID, NULL}
124 ,
125 {TF_OBSOLETE, "Pixmap", 6, TT_FILENAME, WHARF_Pixmap_ID, NULL}
126 ,
127 {TF_OBSOLETE, "NoBorder", 8, TT_FLAG, WHARF_NoBorder_ID, NULL}
128 ,
129 {TF_OBSOLETE, "NoPush", 6, TT_FLAG, WHARF_NoPush_ID, NULL}
130 ,
131 {TF_OBSOLETE, "FullPush", 8, TT_FLAG, WHARF_FullPush_ID, NULL}
132 ,
133 /* Private */
134 WHARF_PRIVATE_TERMS,
135 /* Folders */
136 WHARF_FOLDER_TERMS,
137 /* Look */
138 WHARF_LOOK_TERMS,
139 /* Feel */
140 WHARF_FEEL_TERMS,
141
142
143 /* now special cases that should be processed by it's own handlers */
144 BALLOON_TERMS,
145 /* including MyStyles definitions processing */
146 INCLUDE_MYSTYLE,
147 {0, NULL, 0, 0, 0}
148 };
149
150 TermDef WharfFeelTerms[] = {
151 /* Feel */
152 WHARF_FEEL_TERMS,
153 BALLOON_FEEL_TERMS,
154 {0, NULL, 0, 0, 0}
155 };
156
157 TermDef WharfLookTerms[] = {
158 /* Look */
159 WHARF_LOOK_TERMS,
160 /* now special cases that should be processed by it's own handlers */
161 BALLOON_LOOK_TERMS,
162 {0, NULL, 0, 0, 0}
163 };
164
165 TermDef WharfPrivateTerms[] = {
166 WHARF_PRIVATE_TERMS,
167 BALLOON_FLAG_TERM,
168 {0, NULL, 0, 0, 0}
169 };
170
171 TermDef WharfFolderTerms[] = {
172 WHARF_FOLDER_TERMS,
173 {0, NULL, 0, 0, 0}
174 };
175
176 SyntaxDef WharfFeelSyntax =
177 { '\n', '\0', WharfFeelTerms, 0, '\t', "", "\t", "WharfFeel",
178 "WharfFeel", "AfterStep wharf module feel", NULL, 0 };
179 SyntaxDef WharfLookSyntax =
180 { '\n', '\0', WharfLookTerms, 0, '\t', "", "\t", "WharfLook",
181 "WharfLook", "AfterStep wharf module look", NULL, 0 };
182 SyntaxDef WharfPrivateSyntax =
183 { '\n', '\0', WharfPrivateTerms, 0, '\t', "", "\t", "Wharf", "Wharf",
184 "AfterStep wharf module", NULL, 0 };
185 SyntaxDef WharfFolderSyntax =
186 { '\n', '\0', WharfFolderTerms, 0, '\t', "", "\t", "Wharf Folders",
187 "WharfFolders", "AfterStep wharf module", NULL,
188 0
189 };
190
191 SyntaxDef WharfSyntax =
192 { '\n', '\0', WharfTerms, 0, ' ', "", "", "Module:Wharf", "Wharf",
193 "AfterStep module for launching or docking applications aka button bar",
194 NULL, 0
195 };
196
197
198 flag_options_xref WharfFlags[] = {
199 {WHARF_NO_PUSH, WHARF_NoPush_ID, 0}
200 ,
201 {WHARF_FULL_PUSH, 0, WHARF_FullPush_ID}
202 ,
203 {WHARF_NO_BORDER, WHARF_NoBorder_ID, WHARF_Bevel_ID}
204 ,
205 {WHARF_NO_WITHDRAW, WHARF_NoWithdraw_ID, 0}
206 ,
207 {WHARF_ANIMATE_MAIN, WHARF_AnimateMain_ID, 0}
208 ,
209 {WHARF_ANIMATE, WHARF_Animate_ID, 0}
210 ,
211 {WHARF_SHOW_LABEL, WHARF_ShowLabel_ID, 0}
212 ,
213 {WHARF_FlipLabel, WHARF_FlipLabel_ID, 0}
214 ,
215 {WHARF_FitContents, WHARF_FitContents_ID, 0}
216 ,
217 {WHARF_ShapeToContents, WHARF_ShapeToContents_ID, 0}
218 ,
219 {WHARF_StretchBackground, WHARF_StretchBackground_ID, 0}
220 ,
221 {0, 0, 0}
222 };
223
CreateWharfButton()224 WharfButton *CreateWharfButton ()
225 {
226 WharfButton *btn = (WharfButton *) safecalloc (1, sizeof (WharfButton));
227
228 return btn;
229 }
230
DestroyWharfButton(WharfButton ** pbtn)231 void DestroyWharfButton (WharfButton ** pbtn)
232 {
233 WharfButton *btn = *pbtn;
234
235 if (btn == NULL)
236 return;
237 *pbtn = btn->next;
238
239 /* delete members */
240 if (btn->title != NULL)
241 free (btn->title);
242 if (btn->comment != NULL)
243 free (btn->comment);
244
245 if (btn->contents) {
246 int k;
247
248 for (k = 0; k < btn->contents_num; ++k) {
249 char **icon = btn->contents[k].icon;
250 FunctionData *function = btn->contents[k].function;
251
252 if (icon != NULL)
253 destroy_string_list (icon, 0);
254
255 if (function) {
256 free_func_data (function);
257 free (function);
258 }
259 }
260 free (btn->contents);
261 }
262
263
264 while (btn->folder)
265 DestroyWharfButton (&(btn->folder));
266
267 free (btn);
268 }
269
270
CreateWharfConfig()271 WharfConfig *CreateWharfConfig ()
272 {
273 WharfConfig *config =
274 (WharfConfig *) safecalloc (1, sizeof (WharfConfig));
275
276 /* let's initialize Base config with some nice values: */
277 config->geometry.flags = WidthValue | HeightValue;
278 config->geometry.width = config->geometry.height = 64;
279 config->withdraw_style = WITHDRAW_ON_EDGE_BUTTON_AND_SHOW;
280
281 config->AlignContents = WHARF_DEFAULT_AlignContents;
282 config->ShowHints = WHARF_DEFAULT_ShowHints;
283
284 config->more_stuff = NULL;
285
286 config->CompositionMethod = WHARF_DEFAULT_CompositionMethod;
287 config->FolderOffset = WHARF_DEFAULT_FolderOffset;
288 config->OrthogonalFolderOffset = WHARF_DEFAULT_OrthogonalFolderOffset;
289
290 return config;
291 }
292
DestroyWharfConfig(WharfConfig * config)293 void DestroyWharfConfig (WharfConfig * config)
294 {
295 register int i;
296
297 if (config->bg_color)
298 free (config->bg_color);
299 if (config->texture_color)
300 free (config->texture_color);
301 if (config->pixmap)
302 free (config->pixmap);
303 for (i = 0; i < WHEV_MAX_EVENTS; i++)
304 if (config->sounds[i])
305 free (config->sounds[i]);
306
307 while (config->root_folder)
308 DestroyWharfButton (&(config->root_folder));
309
310 Destroy_balloonConfig (config->balloon_conf);
311 DestroyFreeStorage (&(config->more_stuff));
312 free (config);
313 }
314
print_wharf_folder(WharfButton * folder,int level)315 int print_wharf_folder (WharfButton * folder, int level)
316 {
317 int count = 1;
318 int my_level = level;
319
320 while (folder) {
321 int i = 0;
322
323 show_progress ("WHARF.FOLDER[%d].BUTTON[%d].set_flags=0x%lX;",
324 my_level, count, folder->set_flags);
325 show_progress ("WHARF.FOLDER[%d].BUTTON[%d].title=\"%s\";", my_level,
326 count, folder->title);
327 show_progress ("WHARF.FOLDER[%d].BUTTON[%d].width=%d;", my_level,
328 count, folder->width);
329 show_progress ("WHARF.FOLDER[%d].BUTTON[%d].height=%d;", my_level,
330 count, folder->height);
331 if (folder->contents) {
332 int k;
333
334 for (k = 0; k < folder->contents_num; ++k) {
335 char **icon = folder->contents[k].icon;
336 FunctionData *function = folder->contents[k].function;
337
338 i = 0;
339 if (icon)
340 while (icon[i] != NULL) {
341 show_progress
342 ("WHARF.FOLDER[%d].BUTTON[%d].CONTNTS[%d].icon[%d]=\"%s\";",
343 my_level, count, k, i, icon[i]);
344 ++i;
345 }
346 if (function)
347 print_func_data (__FILE__, __FUNCTION__, __LINE__, function);
348 else
349 show_progress ("no function attached");
350 }
351 } else
352 show_progress ("no contents attached");
353
354 if (folder->folder)
355 level = print_wharf_folder (folder->folder, level + 1);
356 ++count;
357 folder = folder->next;
358 }
359 return level;
360 }
361
PrintWharfConfig(WharfConfig * config)362 void PrintWharfConfig (WharfConfig * config)
363 {
364 show_progress ("WHARF.flags=0x%lX;", config->flags);
365 show_progress ("WHARF.set_flags=0x%lX;", config->set_flags);
366 if (get_flags (config->set_flags, WHARF_ROWS))
367 show_progress ("WHARF.rows=%d;", config->rows);
368
369 if (get_flags (config->set_flags, WHARF_COLUMNS))
370 show_progress ("WHARF.columns=%d;", config->columns);
371
372 if (get_flags (config->set_flags, WHARF_GEOMETRY))
373 show_progress ("WHARF.geometry=(0x%lx,%dx%d%+d%+d);",
374 config->geometry.flags, config->geometry.width,
375 config->geometry.height, config->geometry.x,
376 config->geometry.y);
377
378 if (get_flags (config->set_flags, WHARF_WITHDRAW_STYLE))
379 show_progress ("WHARF.withdraw_style=%d;", config->withdraw_style);
380
381 if (get_flags (config->set_flags, WHARF_FORCE_SIZE))
382 show_progress ("WHARF.force_size=(0x%lx,%dx%d%+d%+d);",
383 config->force_size.flags, config->force_size.width,
384 config->force_size.height, config->force_size.x,
385 config->force_size.y);
386
387 if (get_flags (config->set_flags, WHARF_ANIMATE_STEPS))
388 show_progress ("WHARF.animate_steps=%d;", config->animate_steps);
389 if (get_flags (config->set_flags, WHARF_ANIMATE_STEPS_MAIN))
390 show_progress ("WHARF.animate_steps_main=%d;",
391 config->animate_steps_main);
392 if (get_flags (config->set_flags, WHARF_ANIMATE_DELAY))
393 show_progress ("WHARF.animate_delay=%d;", config->animate_delay);
394
395 if (get_flags (config->set_flags, WHARF_SOUND)) {
396 int i;
397
398 for (i = 0; i < WHEV_MAX_EVENTS; ++i)
399 show_progress ("WHARF.sounds[%d]=\"%s\";", i, config->sounds[i]);
400 }
401
402 ASCF_PRINT_INT_KEYWORD (stderr, WHARF, config, LabelLocation);
403 ASCF_PRINT_FLAG_KEYWORD (stderr, WHARF, config, FlipLabel);
404 ASCF_PRINT_FLAG_KEYWORD (stderr, WHARF, config, FitContents);
405 ASCF_PRINT_FLAG_KEYWORD (stderr, WHARF, config, ShapeToContents);
406 ASCF_PRINT_FLAG_KEYWORD (stderr, WHARF, config, StretchBackground);
407 ASCF_PRINT_FLAGS_KEYWORD (stderr, WHARF, config, AlignContents);
408 ASCF_PRINT_FLAGS_KEYWORD (stderr, WHARF, config, Bevel);
409 ASCF_PRINT_FLAGS_KEYWORD (stderr, WHARF, config, ShowHints);
410 ASCF_PRINT_INT_KEYWORD (stderr, WHARF, config, CompositionMethod);
411 ASCF_PRINT_INT_KEYWORD (stderr, WHARF, config, FolderOffset);
412 ASCF_PRINT_INT_KEYWORD (stderr, WHARF, config, OrthogonalFolderOffset);
413
414 print_wharf_folder (config->root_folder, 1);
415
416 }
417
418 void print_trimmed_str (char *prompt, char *str);
419
WharfSpecialFunc(ConfigDef * config)420 unsigned long WharfSpecialFunc (ConfigDef * config)
421 {
422 TermDef *pterm;
423 register char *cur;
424
425 LOCAL_DEBUG_CALLER_OUT ("%p", config);
426 if (config == NULL)
427 return SPECIAL_BREAK;
428
429 /* checking if we have ~Folders in here */
430 LOCAL_DEBUG_OUT ("checking for ~folders at :%s", "");
431 print_trimmed_str ("config->tdata", config->tdata);
432 print_trimmed_str ("config->tline", config->tline);
433 print_trimmed_str ("config->cursor", config->cursor);
434 if ((pterm = FindStatementTerm (config->tdata, &WharfSyntax)) == NULL)
435 if (mystrncasecmp (config->tdata, "~Folders", 7) == 0) {
436 show_error
437 (" config line %d: ~Folders keyword is no longer supported. \nPlease Update your configuration to use ~Folder instead!\n Please Accept our apologies for any inconvinience.",
438 config->line_count);
439 pterm = FindStatementTerm (WHARF_FOLDER_END, &WharfSyntax);
440 }
441
442 if (pterm != NULL) {
443 LOCAL_DEBUG_OUT ("term %p found keyword :[%s]", pterm, pterm->keyword);
444 if (pterm->id == WHARF_FolderEnd_ID) {
445 config->current_term = pterm;
446 /* we are 2 levels deep, and FolderEnd will get us only 1 level up
447 so we need to climb another level ourselves : */
448 LOCAL_DEBUG_OUT ("folder end - Poping out%s", "");
449 PopSyntax (config);
450 PopStorage (config);
451 return SPECIAL_SKIP; /* don't care what will happen */
452 }
453 }
454 /* processing wharf item name and icons : */
455 ProcessStatement (config);
456 /* since we have have subconfig of Functions that has \n as line terminator
457 * we are going to get entire line again at config->cursor
458 * so lets skip 3 tokens of <name> <icon>, since those are not parts
459 * of following function */
460 print_trimmed_str ("skiping 2 tokens at", config->tdata);
461 cur = tokenskip (config->tdata, 2);
462 print_trimmed_str ("skipped to", cur);
463 if (*cur != '\0') {
464 char *good_cursor;
465 TermDef *pterm;
466
467 good_cursor = config->cursor;
468 config->cursor = cur;
469 /* we are at the beginning of the function definition right now - lets process it : */
470 /* read in entire function definition */
471 GetNextStatement (config);
472 /* lets find us the term for this definition */
473 print_trimmed_str ("config->current_data", config->current_data);
474 LOCAL_DEBUG_OUT ("curr_data_len = %d", config->current_data_len);
475 print_trimmed_str ("checking keyword at", config->tline);
476 if ((pterm = FindStatementTerm (config->tline, config->syntax)) == NULL) { /* courtesy check for mistyped Folder keyword : */
477 if (mystrncasecmp (config->tline, "Folders", 7) == 0) {
478 show_error
479 (" config line %d: Folders keyword is no longer supported. \nPlease Update your configuration to use Folder instead!\n Please Accept our apologies for any inconvinience.",
480 config->line_count);
481 pterm = FindStatementTerm ("Folder", config->syntax);
482 }
483 }
484
485 if (pterm == NULL) {
486 /* we are 2 levels deep, and FolderEnd will get us only 1 level up
487 so we need to climb another level ourselves : */
488 PopSyntax (config);
489 PopStorage (config);
490 } else { /* we have a valid function definition : */
491 config->current_term = pterm;
492 /* we do not want to continue processing the rest of the config as
493 * a functions : */
494 config->current_flags |= CF_LAST_OPTION;
495 /* some wierd code to handle the fact that Folder is not really a function,
496 * but instead a start for new nested set of Wharf items : */
497 LOCAL_DEBUG_OUT ("processing function definition statement...%s",
498 "");
499 ProcessStatement (config);
500 if (config->current_term->id == F_Folder) { /* in which case we let parser to carry on the parsing of the Folder item,
501 * which will get us into nested WharfSyntax subsyntax */
502 config->current_flags &= ~CF_LAST_OPTION;
503 }
504 }
505 /* restarting parsing from the same location : */
506 if (config->cursor < good_cursor)
507 config->cursor = good_cursor;
508 LOCAL_DEBUG_OUT ("done processing function definition statement...%s",
509 "");
510 } else {
511 show_error
512 (" config line %d: Function is not defined for the button. Use Nop if no action is desired..",
513 config->line_count);
514 /* function is ommited ! */
515 PopSyntax (config);
516 PopStorage (config);
517 }
518 print_trimmed_str ("config->tdata", config->tdata);
519 print_trimmed_str ("config->tline", config->tline);
520 print_trimmed_str ("config->cursor", config->cursor);
521 /* already done processing current statement - let parser know about it : */
522 return SPECIAL_SKIP;
523 }
524
525 void ParseWharfFolder (FreeStorageElem ** storage_tail,
526 WharfButton ** tail);
527
ParseWharfItem(FreeStorageElem * storage,WharfButton ** folder)528 void ParseWharfItem (FreeStorageElem * storage, WharfButton ** folder)
529 {
530 WharfButton *wb = *folder, **insert = folder;
531 Bool no_title;
532 WharfButtonContent wbc = { NULL, NULL };
533
534 if (storage == NULL || folder == NULL)
535 return;
536 if (storage->argc < 2)
537 return;
538 no_title = (storage->argv[0][0] == '-' && storage->argv[0][1] == '\0') ||
539 (mystrcasecmp (storage->argv[0], "nil") == 0);
540 insert = folder;
541 if (!no_title) {
542 while (wb != NULL
543 && (wb->title == NULL
544 || strcmp (wb->title, storage->argv[0]) != 0)) {
545 insert = &(wb->next);
546 wb = wb->next;
547 }
548 } else
549 while (wb != NULL) {
550 insert = &(wb->next);
551 wb = wb->next;
552 }
553
554 if (wb == NULL) {
555 if ((wb = CreateWharfButton ()) == NULL)
556 return;
557 *insert = wb;
558 }
559 if (wb->title)
560 free (wb->title);
561 wb->title = mystrdup (storage->argv[0]);
562
563 {
564 char **new_icon_list = comma_string2list (storage->argv[1]);
565
566 if (new_icon_list) {
567 register char *ptr;
568 register int null_icon = 0;
569
570 if ((ptr = new_icon_list[0]) == NULL)
571 null_icon++;
572 else if (*(ptr) == '-' && *(ptr + 1) == '\0')
573 null_icon++;
574 else if (mystrcasecmp (ptr, "nil") == 0)
575 null_icon++;
576
577 if (null_icon > 0) {
578 destroy_string_list (new_icon_list, 0);
579 new_icon_list = NULL;
580 }
581 }
582
583 wbc.icon = new_icon_list;
584 }
585
586 LOCAL_DEBUG_OUT ("wharf button \"%s\" has substorage set to %p",
587 wb->title, storage->sub);
588 if (storage->sub) {
589 FreeStorageElem *pstorage = storage->sub;
590 register TermDef *pterm = pstorage->term;
591
592 if (pterm != NULL) {
593 LOCAL_DEBUG_OUT ("term for keyword \"%s\" found in substorage",
594 pterm->keyword);
595 if (pterm->id == F_Folder) {
596 if (pstorage->sub) {
597 pstorage = pstorage->sub;
598 ParseWharfFolder (&pstorage, &(wb->folder));
599 }
600 } else if (pterm->id == F_Transient) {
601 set_flags (wb->set_flags, WHARF_BUTTON_TRANSIENT);
602 } else if (pterm->type == TT_FUNCTION) {
603 ConfigItem item;
604
605 item.memory = NULL;
606 if (ReadConfigItem (&item, pstorage)) {
607 if (pterm->id == F_Size) {
608 set_flags (wb->set_flags, WHARF_BUTTON_SIZE);
609 wb->width = item.data.function->func_val[0];
610 wb->height = item.data.function->func_val[1];
611 item.ok_to_free = 1;
612 } else {
613 wbc.function = item.data.function;
614 item.ok_to_free = 0;
615 }
616 ReadConfigItem (&item, NULL);
617 }
618 }
619 }
620 }
621 if (wbc.function != NULL || wbc.icon != NULL) {
622 int c = wb->contents_num;
623
624 ++(wb->contents_num);
625 wb->contents =
626 realloc (wb->contents,
627 wb->contents_num * sizeof (WharfButtonContent));
628 wb->contents[c] = wbc;
629 }
630 }
631
632 void
ParseWharfFolder(FreeStorageElem ** storage_tail,WharfButton ** folder)633 ParseWharfFolder (FreeStorageElem ** storage_tail, WharfButton ** folder)
634 {
635 if (storage_tail != NULL && folder != NULL) {
636 register FreeStorageElem *folder_storage = (*storage_tail);
637
638 while (folder_storage != NULL) {
639 if (folder_storage->term->id != WHARF_Wharf_ID)
640 break;
641 ParseWharfItem (folder_storage, folder);
642 /* keep parameter pointing to the last processed item */
643 *storage_tail = folder_storage;
644 /* while advancing internal pointer ahead.
645 we have to do that as our caller will
646 expect storage_tail to be pointing to last processed item */
647 folder_storage = folder_storage->next;
648 }
649 }
650 }
651
652
653
ParseWharfOptions(const char * filename,char * myname)654 WharfConfig *ParseWharfOptions (const char *filename, char *myname)
655 {
656 ConfigData cd;
657 ConfigDef *ConfigReader;
658 WharfConfig *config = CreateWharfConfig ();
659 FreeStorageElem *Storage = NULL, *pCurr;
660 ConfigItem item;
661 TermDef *folder_term = func2fterm (F_Folder, False);
662
663 cd.filename = filename;
664 ConfigReader =
665 InitConfigReader (myname, &WharfSyntax, CDT_Filename, cd,
666 NULL /*WharfSpecialFunc */ );
667 if (!ConfigReader)
668 return config;
669
670 folder_term->sub_syntax = &WharfSyntax;
671
672 item.memory = NULL;
673 PrintConfigReader (ConfigReader);
674 ParseConfig (ConfigReader, &Storage);
675
676 /* getting rid of all the crap first */
677 StorageCleanUp (&Storage, &(config->more_stuff), CF_DISABLED_OPTION);
678 config->balloon_conf =
679 Process_balloonOptions (Storage, NULL, BALLOON_ID_START);
680 config->style_defs = free_storage2MyStyleDefinitionsList (Storage);
681
682 for (pCurr = Storage; pCurr; pCurr = pCurr->next) {
683 if (pCurr->term == NULL)
684 continue;
685 if (ReadFlagItem
686 (&(config->set_flags), &(config->flags), pCurr, WharfFlags)) {
687 continue;
688 }
689 if (!ReadConfigItem (&item, pCurr))
690 continue;
691 switch (pCurr->term->id) {
692 case WHARF_Wharf_ID:
693 item.ok_to_free = 1;
694 ParseWharfFolder (&pCurr, &(config->root_folder));
695 break;
696 case WHARF_Geometry_ID:
697 set_flags (config->set_flags, WHARF_GEOMETRY);
698 config->geometry = item.data.geometry;
699 break;
700 case WHARF_Rows_ID:
701 set_flags (config->set_flags, WHARF_ROWS);
702 config->rows = item.data.integer;
703 break;
704 case WHARF_Columns_ID:
705 set_flags (config->set_flags, WHARF_COLUMNS);
706 clear_flags (config->set_flags, WHARF_ROWS);
707 config->columns = item.data.integer;
708 break;
709 case WHARF_WithdrawStyle_ID:
710 set_flags (config->set_flags, WHARF_WITHDRAW_STYLE);
711 config->withdraw_style = item.data.integer;
712 break;
713 case WHARF_ForceSize_ID:
714 set_flags (config->set_flags, WHARF_FORCE_SIZE);
715 config->force_size = item.data.geometry;
716 /* errorneous value check */
717 if (!(config->force_size.flags & WidthValue))
718 config->force_size.width = 64;
719 if (!(config->force_size.flags & HeightValue))
720 config->force_size.height = 64;
721 config->force_size.flags = WidthValue | HeightValue;
722 break;
723 case WHARF_TextureType_ID:
724 set_flags (config->set_flags, WHARF_TEXTURE_TYPE);
725 config->texture_type = item.data.integer;
726 break;
727 case WHARF_BgColor_ID:
728 set_string_value (&(config->bg_color), item.data.string,
729 &(config->set_flags), WHARF_BG_COLOR);
730 break;
731 case WHARF_TextureColor_ID:
732 set_string_value (&(config->texture_color), item.data.string,
733 &(config->set_flags), WHARF_TEXTURE_COLOR);
734 break;
735 case WHARF_Pixmap_ID:
736 set_string_value (&(config->pixmap), item.data.string,
737 &(config->set_flags), WHARF_PIXMAP);
738 break;
739 case WHARF_AnimateStepsMain_ID:
740 set_flags (config->set_flags, WHARF_ANIMATE_STEPS_MAIN);
741 config->animate_steps_main = item.data.integer;
742 break;
743 case WHARF_AnimateSteps_ID:
744 set_flags (config->set_flags, WHARF_ANIMATE_STEPS);
745 config->animate_steps = item.data.integer;
746 break;
747 case WHARF_AnimateDelay_ID:
748 set_flags (config->set_flags, WHARF_ANIMATE_DELAY);
749 config->animate_delay = item.data.integer;
750 break;
751 case WHARF_Sound_ID:
752 if (pCurr->sub == NULL) {
753 if (pCurr->argc > 0) {
754 register char *sound = mystrdup (pCurr->argv[pCurr->argc - 1]);
755
756 set_string_value (&(config->sounds[WHEV_PUSH]), sound,
757 &(config->set_flags), WHARF_SOUND);
758 }
759 } else if (pCurr->sub->argc > 0) {
760 register char *sound = mystrdup (pCurr->sub->argv[0]);
761
762 set_string_value (&
763 (config->
764 sounds[WHEV_Id2Code (pCurr->sub->term->id)]),
765 sound, &(config->set_flags), WHARF_SOUND);
766 }
767 item.ok_to_free = 1;
768 break;
769 ASCF_HANDLE_INTEGER_KEYWORD_CASE (WHARF, config, item,
770 LabelLocation);
771 ASCF_HANDLE_ALIGN_KEYWORD_CASE (WHARF, config, pCurr, AlignContents);
772 ASCF_HANDLE_BEVEL_KEYWORD_CASE (WHARF, config, pCurr, Bevel);
773 ASCF_HANDLE_SUBSYNTAX_KEYWORD_CASE (WHARF, config, pCurr, ShowHints,
774 BalloonContents);
775 ASCF_HANDLE_INTEGER_KEYWORD_CASE (WHARF, config, item,
776 CompositionMethod);
777 ASCF_HANDLE_INTEGER_KEYWORD_CASE (WHARF, config, item, FolderOffset);
778 ASCF_HANDLE_INTEGER_KEYWORD_CASE (WHARF, config, item,
779 OrthogonalFolderOffset);
780 default:
781 if (pCurr->term->type != TT_FLAG)
782 item.ok_to_free = 1;
783 }
784 }
785 if (get_flags (config->set_flags, WHARF_Bevel))
786 clear_flags (config->flags, WHARF_NO_BORDER);
787
788
789 ReadConfigItem (&item, NULL);
790 SHOW_CHECKPOINT;
791 DestroyConfig (ConfigReader);
792 SHOW_CHECKPOINT;
793 DestroyFreeStorage (&Storage);
794 SHOW_CHECKPOINT;
795 return config;
796 }
797
798
799 #if 0
800
801 FreeStorageElem **WharfFolder2FreeStorage (SyntaxDef * syntax,
802 FreeStorageElem ** tail,
803 WharfButton * folder, int root);
804
805 FreeStorageElem **WharfButton2FreeStorage (SyntaxDef * syntax,
806 FreeStorageElem ** tail,
807 WharfButton * button)
808 {
809 FreeStorageElem *new_elem = NULL;
810 TermDef *pterm = FindTerm (syntax, TT_ANY, WHARF_Wharf_ID);
811
812 if (pterm == NULL || button == NULL || tail == NULL)
813 return tail;
814 if (button->title == NULL)
815 return tail;
816
817 /* adding WharfButton free storage here */
818
819 if ((new_elem =
820 AddFreeStorageElem (syntax, tail, pterm, WHARF_Wharf_ID)) != NULL) {
821 char *icon = list2comma_string (button->icon);
822 int title_len, len;
823
824 len = title_len = strlen (button->title) + 1;
825 len += ((icon) ? strlen (icon) : 1) + 1;
826 if (len > 0) {
827 new_elem->argc = 2;
828 new_elem->argv = CreateStringArray (2);
829 new_elem->argv[0] = safemalloc (len);
830 new_elem->argv[1] = &(new_elem->argv[0][title_len + 1]);
831 strcpy (new_elem->argv[0], button->title);
832 if (icon == NULL)
833 strcpy (new_elem->argv[1], "-");
834 else {
835 strcpy (new_elem->argv[1], icon);
836 free (icon);
837 }
838 tail = &(new_elem->next);
839
840 if (button->folder) {
841 FunctionData tmp;
842
843 memset (&tmp, 0x00, sizeof (FunctionData));
844 tmp.func = F_Folder;
845 Func2FreeStorage (pFuncSyntax, &(new_elem->sub), &tmp);
846 WharfFolder2FreeStorage (syntax, &(new_elem->sub->sub),
847 button->folder, False);
848
849 } else if (button->function) {
850 Func2FreeStorage (pFuncSyntax, &(new_elem->sub), button->function);
851 }
852
853 }
854 }
855 return tail;
856 }
857
858 FreeStorageElem **WharfFolder2FreeStorage (SyntaxDef * syntax,
859 FreeStorageElem ** tail,
860 WharfButton * folder, int root)
861 {
862 if (folder == NULL || tail == NULL)
863 return tail;
864
865 /* adding balloon free storage here */
866 while (folder) {
867 tail = WharfButton2FreeStorage (syntax, tail, folder);
868 folder = folder->next;
869 }
870 if (!root) {
871 char *fend = WHARF_FOLDER_END;
872
873 tail = String2FreeStorage (syntax, tail, fend, WHARF_Wharf_ID);
874 }
875
876 return tail;
877 }
878
879 /* returns:
880 * 0 on success
881 * 1 if data is empty
882 * 2 if ConfigWriter cannot be initialized
883 *
884 */
885 int
886 WriteWharfOptions (const char *filename, char *myname,
887 WharfConfig * config, unsigned long flags)
888 {
889 ConfigDef *WharfConfigWriter = NULL;
890 FreeStorageElem *Storage = NULL, **tail = &Storage;
891 TermDef *folder_term = func2fterm (F_Folder, True);
892 int i;
893
894 if (config == NULL)
895 return 1;
896
897 folder_term->sub_syntax = &WharfSyntax;
898
899 if ((WharfConfigWriter =
900 InitConfigWriter (myname, &WharfSyntax, CDT_Filename,
901 (void *)filename)) == NULL)
902 return 2;
903
904 CopyFreeStorage (&Storage, config->more_stuff);
905
906 if (config->style_defs)
907 *tail =
908 MyStyleDefinitionsList2free_storage (config->style_defs,
909 &WharfSyntax);
910
911 if (config->balloon_conf)
912 tail = balloon2FreeStorage (&WharfSyntax, tail, config->balloon_conf);
913
914 /* building free storage here */
915 /* geometry */
916 if (get_flags (config->set_flags, WHARF_GEOMETRY))
917 tail =
918 Geometry2FreeStorage (&WharfSyntax, tail, &(config->geometry),
919 WHARF_Geometry_ID);
920 if (get_flags (config->set_flags, WHARF_FORCE_SIZE))
921 tail =
922 Geometry2FreeStorage (&WharfSyntax, tail, &(config->force_size),
923 WHARF_ForceSize_ID);
924 /* Integer values : */
925 /* rows */
926 if (get_flags (config->set_flags, WHARF_ROWS))
927 tail =
928 Integer2FreeStorage (&WharfSyntax, tail, NULL, config->rows,
929 WHARF_Rows_ID);
930 /* columns */
931 if (get_flags (config->set_flags, WHARF_COLUMNS))
932 tail =
933 Integer2FreeStorage (&WharfSyntax, tail, NULL, config->columns,
934 WHARF_Columns_ID);
935 /* withdraw_style */
936 if (get_flags (config->set_flags, WHARF_WITHDRAW_STYLE))
937 tail =
938 Integer2FreeStorage (&WharfSyntax, tail, NULL,
939 config->withdraw_style,
940 WHARF_WithdrawStyle_ID);
941 /* texture_type */
942 if (get_flags (config->set_flags, WHARF_TEXTURE_TYPE))
943 tail =
944 Integer2FreeStorage (&WharfSyntax, tail, NULL,
945 config->texture_type, WHARF_TextureType_ID);
946 /* animate_steps */
947 if (get_flags (config->set_flags, WHARF_ANIMATE_STEPS))
948 tail =
949 Integer2FreeStorage (&WharfSyntax, tail, NULL,
950 config->animate_steps, WHARF_AnimateSteps_ID);
951 /* animate_steps_main */
952 if (get_flags (config->set_flags, WHARF_ANIMATE_STEPS_MAIN))
953 tail =
954 Integer2FreeStorage (&WharfSyntax, tail, NULL,
955 config->animate_steps_main,
956 WHARF_AnimateStepsMain_ID);
957 /* animate_delay */
958 if (get_flags (config->set_flags, WHARF_ANIMATE_DELAY))
959 tail =
960 Integer2FreeStorage (&WharfSyntax, tail, NULL,
961 config->animate_delay, WHARF_AnimateDelay_ID);
962
963
964 /* Flags : */
965 tail =
966 Flags2FreeStorage (&WharfSyntax, tail, WharfFlags, 0xFFFFFFFF,
967 config->set_flags);
968
969 /* StringValues */
970 /* bg_color */
971 if (get_flags (config->set_flags, WHARF_BG_COLOR))
972 tail =
973 String2FreeStorage (&WharfSyntax, tail, config->bg_color,
974 WHARF_BgColor_ID);
975
976 /* texture_color */
977 if (get_flags (config->set_flags, WHARF_TEXTURE_COLOR))
978 tail =
979 String2FreeStorage (&WharfSyntax, tail, config->texture_color,
980 WHARF_TextureColor_ID);
981
982 /* pixmap name */
983 if (get_flags (config->set_flags, WHARF_PIXMAP))
984 tail =
985 String2FreeStorage (&WharfSyntax, tail, config->pixmap,
986 WHARF_Pixmap_ID);
987
988 /* sound */
989 if (get_flags (config->set_flags, WHARF_SOUND))
990 for (i = 0; i < WHEV_MAX_EVENTS; i++)
991 tail =
992 String2FreeStorage (&WharfSyntax, tail, config->sounds[i],
993 WHARF_Sound_ID);
994
995 /* Writing Wharf Entries : */
996 if (config->root_folder)
997 tail =
998 WharfFolder2FreeStorage (&WharfSyntax, tail, config->root_folder,
999 True);
1000
1001 /* writing config into the file */
1002 WriteConfig (WharfConfigWriter, Storage, CDT_Filename,
1003 (void **)&filename, flags);
1004 DestroyFreeStorage (&Storage);
1005 DestroyConfig (WharfConfigWriter);
1006
1007 if (Storage) {
1008 fprintf (stderr,
1009 "\n%s:Config Writing warning: Not all Free Storage discarded! Trying again...",
1010 myname);
1011 DestroyFreeStorage (&Storage);
1012 fprintf (stderr, (Storage != NULL) ? " failed." : " success.");
1013 }
1014 return 0;
1015 }
1016
1017 #endif
1018