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