1 /*
2  * Copyright (c) 2002 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., 675 Mass Ave, Cambridge, MA 02139, USA.
17  *
18  */
19 #define LOCAL_DEBUG
20 
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  * This routine is responsible for reading and parsing the config file
33  *
34  ****************************************************************************/
35 
36 extern SyntaxDef AlignSyntax;
37 
38 
39 #define WINLIST_FEEL_TERMS \
40     ASCF_DEFINE_KEYWORD(WINLIST, TF_DONT_SPLIT	, Action		, TT_TEXT, NULL), \
41     ASCF_DEFINE_KEYWORD(WINLIST, 0				, FillRowsFirst	, TT_FLAG, NULL), \
42     ASCF_DEFINE_KEYWORD(WINLIST, 0				, UseSkipList	, TT_FLAG, NULL)
43 
44 #define WINLIST_LOOK_TERMS \
45     ASCF_DEFINE_KEYWORD_S(WINLIST, 0				, UseName			, TT_INTEGER, NULL,WinListConfig), \
46     ASCF_DEFINE_KEYWORD_S(WINLIST, 0			    , Align				, TT_FLAG	, &AlignSyntax,WinListConfig), \
47     ASCF_DEFINE_KEYWORD(WINLIST, 0			    , Bevel				, TT_FLAG	, &BevelSyntax), \
48     ASCF_DEFINE_KEYWORD_S(WINLIST, 0			    , FBevel			, TT_FLAG	, &BevelSyntax,WinListConfig), \
49     ASCF_DEFINE_KEYWORD_S(WINLIST, 0			    , UBevel			, TT_FLAG	, &BevelSyntax,WinListConfig), \
50     ASCF_DEFINE_KEYWORD_S(WINLIST, 0			    , SBevel			, TT_FLAG	, &BevelSyntax,WinListConfig), \
51     ASCF_DEFINE_KEYWORD_SA(WINLIST, 0			    , FocusedBevel		, TT_FLAG	, &BevelSyntax,WinListConfig,FBevel), \
52     ASCF_DEFINE_KEYWORD_SA(WINLIST, 0			    , StickyBevel		, TT_FLAG	, &BevelSyntax,WinListConfig,SBevel), \
53     ASCF_DEFINE_KEYWORD_SA(WINLIST, 0			    , UnfocusedBevel	, TT_FLAG	, &BevelSyntax,WinListConfig,UBevel), \
54     ASCF_DEFINE_KEYWORD(WINLIST, 0			    , CompositionMethod	, TT_UINTEGER, NULL), \
55     ASCF_DEFINE_KEYWORD_S(WINLIST, 0			    , FCompositionMethod, TT_UINTEGER, NULL,WinListConfig), \
56     ASCF_DEFINE_KEYWORD_S(WINLIST, 0			    , UCompositionMethod, TT_UINTEGER, NULL,WinListConfig), \
57     ASCF_DEFINE_KEYWORD_S(WINLIST, 0			    , SCompositionMethod, TT_UINTEGER, NULL,WinListConfig), \
58     ASCF_DEFINE_KEYWORD(WINLIST, 0			    , Spacing			, TT_UINTEGER, NULL), \
59     ASCF_DEFINE_KEYWORD_S(WINLIST, 0			    , HSpacing			, TT_UINTEGER, NULL,WinListConfig), \
60     ASCF_DEFINE_KEYWORD_S(WINLIST, 0			    , VSpacing			, TT_UINTEGER, NULL,WinListConfig), \
61     ASCF_DEFINE_KEYWORD_S(WINLIST, TF_QUOTES_OPTIONAL, UnfocusedStyle	, TT_QUOTED_TEXT	,  NULL,WinListConfig), \
62     ASCF_DEFINE_KEYWORD_S(WINLIST, TF_QUOTES_OPTIONAL, FocusedStyle		, TT_QUOTED_TEXT	,  NULL,WinListConfig), \
63     ASCF_DEFINE_KEYWORD_S(WINLIST, TF_QUOTES_OPTIONAL, StickyStyle		, TT_QUOTED_TEXT	,  NULL,WinListConfig), \
64     ASCF_DEFINE_KEYWORD_S(WINLIST, TF_QUOTES_OPTIONAL, UrgentStyle		, TT_QUOTED_TEXT	,  NULL,WinListConfig), \
65     ASCF_DEFINE_KEYWORD(WINLIST, 0			    , ShapeToContents	, TT_FLAG	,  NULL), \
66     ASCF_DEFINE_KEYWORD(WINLIST, 0			    , ShowIcon			, TT_FLAG	,  NULL), \
67     ASCF_DEFINE_KEYWORD_S(WINLIST, 0			    , IconLocation		, TT_UINTEGER, NULL,WinListConfig), \
68     ASCF_DEFINE_KEYWORD_S(WINLIST, 0			    , IconAlign			, TT_FLAG	, &AlignSyntax,WinListConfig), \
69     ASCF_DEFINE_KEYWORD_S(WINLIST, 0			    , IconSize			, TT_GEOMETRY, NULL,WinListConfig), \
70     ASCF_DEFINE_KEYWORD(WINLIST, 0			    , ScaleIconToTextHeight, TT_FLAG,  NULL), \
71     ASCF_DEFINE_KEYWORD_S(WINLIST, 0					,ShowHints  	, TT_FLAG		, &BalloonContentsSyntax,WinListConfig)
72 
73 #define WINLIST_PRIVATE_TERMS \
74     ASCF_DEFINE_KEYWORD_S(WINLIST, 0			    , Geometry			, TT_GEOMETRY	, NULL,WinListConfig), \
75     ASCF_DEFINE_KEYWORD_S(WINLIST, 0			    , MinSize			, TT_GEOMETRY	, NULL,WinListConfig), \
76     ASCF_DEFINE_KEYWORD_S(WINLIST, 0			    , MaxSize			, TT_GEOMETRY	, NULL,WinListConfig), \
77     ASCF_DEFINE_KEYWORD_S(WINLIST, 0			    , MaxRows			, TT_INTEGER	, NULL,WinListConfig), \
78     ASCF_DEFINE_KEYWORD_S(WINLIST, 0			    , MaxColumns		, TT_INTEGER	, NULL,WinListConfig), \
79     ASCF_DEFINE_KEYWORD_S(WINLIST, 0			    , MaxColWidth		, TT_INTEGER	, NULL,WinListConfig), \
80     ASCF_DEFINE_KEYWORD_S(WINLIST, 0			    , MinColWidth		, TT_INTEGER	, NULL,WinListConfig), \
81     ASCF_DEFINE_KEYWORD_S(WINLIST, 0			    , MinColWidth		, TT_INTEGER	, NULL,WinListConfig), \
82     ASCF_DEFINE_KEYWORD_S(WINLIST, 0			    , NoCollidesSpacing	, TT_INTEGER	, NULL,WinListConfig), \
83     ASCF_DEFINE_KEYWORD(WINLIST, TF_DONT_SPLIT		, NoCollides	    , TT_TEXT		, NULL), \
84     ASCF_DEFINE_KEYWORD(WINLIST, TF_DONT_SPLIT		, AllowCollides	    , TT_TEXT		, NULL), \
85     ASCF_DEFINE_KEYWORD(WINLIST, TF_OBSOLETE	, MaxWidth			, TT_UINTEGER	, NULL)
86 
87 
88 TermDef WinListFeelTerms[] = {
89 	/* Feel */
90 	WINLIST_FEEL_TERMS,
91 	BALLOON_FEEL_TERMS,
92 	{0, NULL, 0, 0, 0}
93 };
94 
95 TermDef WinListLookTerms[] = {
96 	/* Look */
97 	WINLIST_LOOK_TERMS,
98 /* now special cases that should be processed by it's own handlers */
99 	BALLOON_LOOK_TERMS,
100 	{0, NULL, 0, 0, 0}
101 };
102 
103 TermDef WinListPrivateTerms[] = {
104 	WINLIST_PRIVATE_TERMS,
105 	BALLOON_FLAG_TERM,
106 	{0, NULL, 0, 0, 0}
107 };
108 
109 #define WINLIST_ALL_TERMS	WINLIST_PRIVATE_TERMS,WINLIST_FEEL_TERMS, WINLIST_LOOK_TERMS
110 
111 
112 TermDef WinListDefaultsTerms[] = {
113 
114 	WINLIST_ALL_TERMS,
115 	{TF_OBSOLETE, "Orientation", 11, TT_TEXT, WINLIST_Orientation_ID, NULL},
116 /* now special cases that should be processed by it's own handlers */
117 	BALLOON_TERMS,
118 	INCLUDE_MODULE_DEFAULTS_END,
119 	{0, NULL, 0, 0, 0}
120 };
121 
122 SyntaxDef WinListDefaultsSyntax =
123 		{ '\n', '\0', WinListDefaultsTerms, 0, ' ', "", "\t",
124 "Module:WinList_defaults", "WinList",
125 	"AfterStep module displaying list of opened windows", NULL, 0
126 };
127 
128 
129 TermDef WinListTerms[] = {
130 	INCLUDE_MODULE_DEFAULTS (&WinListDefaultsSyntax),
131 
132 	WINLIST_ALL_TERMS,
133 
134 	{TF_OBSOLETE, "Orientation", 11, TT_TEXT, WINLIST_Orientation_ID, NULL},
135 /* including MyStyles definitions processing */
136 	INCLUDE_MYSTYLE,
137 /* now special cases that should be processed by it's own handlers */
138 	BALLOON_TERMS,
139 	{0, NULL, 0, 0, 0}
140 };
141 
142 
143 SyntaxDef WinListFeelSyntax =
144 		{ '\n', '\0', WinListFeelTerms, 0, '\t', "", "\t", "WinListFeel",
145 "WinListFeel",
146 	"AfterStep window list module feel", NULL, 0
147 };
148 
149 SyntaxDef WinListLookSyntax =
150 		{ '\n', '\0', WinListLookTerms, 0, '\t', "", "\t", "WinListLook",
151 "WinListLook",
152 	"AfterStep window list module look", NULL, 0
153 };
154 
155 SyntaxDef WinListPrivateSyntax =
156 		{ '\n', '\0', WinListPrivateTerms, 0, '\t', "", "\t", "WinList",
157 "WinList", "AfterStep window list module", NULL,
158 	0
159 };
160 
161 SyntaxDef WinListSyntax =
162 		{ '\n', '\0', WinListTerms, 0, ' ', "", "\t", "Module:WinList",
163 "WinList",
164 	"AfterStep module displaying list of opened windows", NULL, 0
165 };
166 
167 /*
168 	int        type ;
169 	ASFlagType flags ;
170 
171 	char *private_config_file ;
172 
173 	ASModuleConfig* (*create_config_func)();
174 	void  (*free_storage2config_func)(ASModuleConfig *config, struct FreeStorageElem *storage);
175 	void  (*merge_config_func)( ASModuleConfig *to, ASModuleConfig *from);
176 	void  (*destroy_config_func)( ASModuleConfig *config);
177 
178 	struct SyntaxDef *module_syntax ;
179 	struct SyntaxDef *look_syntax ;
180 	struct SyntaxDef *feel_syntax ;
181 
182 	struct flag_options_xref *flags_xref ;
183 	ptrdiff_t 		   set_flags_field_offset ;
184 */
185 
186 flag_options_xref WinListFlags[] = {
187 	ASCF_DEFINE_MODULE_FLAG_XREF (WINLIST, FillRowsFirst, WinListConfig),
188 	ASCF_DEFINE_MODULE_FLAG_XREF (WINLIST, UseSkipList, WinListConfig),
189 	ASCF_DEFINE_MODULE_FLAG_XREF (WINLIST, ShapeToContents, WinListConfig),
190 	ASCF_DEFINE_MODULE_FLAG_XREF (WINLIST, ShowIcon, WinListConfig),
191 	ASCF_DEFINE_MODULE_FLAG_XREF (WINLIST, ScaleIconToTextHeight,
192 																WinListConfig),
193 	{0, 0, 0}
194 };
195 
196 static void InitWinListConfig (ASModuleConfig * asm_config,
197 															 Bool free_resources);
198 void WinList_fs2config (ASModuleConfig * asmodule_config,
199 												FreeStorageElem * Storage);
200 void MergeWinListOptions (ASModuleConfig * to, ASModuleConfig * from);
201 
202 
203 static ASModuleConfigClass _winlist_config_class = { CONFIG_WinList_ID,
204 	0,
205 	sizeof (WinListConfig),
206 	"winlist",
207 	InitWinListConfig,
208 	WinList_fs2config,
209 	MergeWinListOptions,
210 	&WinListSyntax,
211 	&WinListLookSyntax,
212 	&WinListFeelSyntax,
213 	WinListFlags,
214 	offsetof (WinListConfig, set_flags),
215 
216 	ASDefaultBalloonTypes
217 };
218 
getWinListConfigClass()219 ASModuleConfigClass *getWinListConfigClass ()
220 {
221 	return &_winlist_config_class;
222 }
223 
224 
225 static void
InitWinListConfig(ASModuleConfig * asm_config,Bool free_resources)226 InitWinListConfig (ASModuleConfig * asm_config, Bool free_resources)
227 {
228 	WinListConfig *config = AS_WINLIST_CONFIG (asm_config);
229 
230 	if (config) {
231 		if (free_resources) {
232 			int i;
233 
234 			destroy_string (&(config->UnfocusedStyle));
235 			destroy_string (&(config->FocusedStyle));
236 			destroy_string (&(config->StickyStyle));
237 			destroy_string (&(config->UrgentStyle));
238 
239 			for (i = 0; i < MAX_MOUSE_BUTTONS; ++i)
240 				if (config->Action[i])
241 					destroy_string_list (config->Action[i], 0);
242 
243 #define FREE_COLLIDES(type) do { \
244 			destroy_string_list(&(config->type##Collides[0]),config->type##Collides_nitems); \
245 			if( config->type##Collides_wrexp ) { \
246 				for( i = 0 ; i < config->type##Collides_nitems ; ++i ) destroy_wild_reg_exp(config->type##Collides_wrexp[i]); \
247 				free( config->type##Collides_wrexp ); \
248 			}}while(0)
249 
250 			if (config->NoCollides_nitems > 0)
251 				FREE_COLLIDES (No);
252 			if (config->AllowCollides_nitems > 0)
253 				FREE_COLLIDES (Allow);
254 		}
255 //      memset( config, 0x00, sizeof(WinListConfig));
256 		config->flags = WINLIST_ShowIcon | WINLIST_ScaleIconToTextHeight;
257 		init_asgeometry (&(config->Geometry));
258 		config->gravity = StaticGravity;
259 		config->MaxRows = 1;
260 		config->UseName = ASN_Name;
261 		config->Align = ALIGN_CENTER;
262 		config->HSpacing = DEFAULT_TBAR_HSPACING;
263 		config->VSpacing = DEFAULT_TBAR_VSPACING;
264 		config->FBevel = config->UBevel = config->SBevel = DEFAULT_TBAR_HILITE;
265 		config->IconAlign = NO_ALIGN;
266 		config->IconLocation = 0;
267 		config->ShowHints = WINLIST_DEFAULT_ShowHints;
268 		if (!free_resources) {
269 			config->NoCollides = safecalloc (2, sizeof (char *));;
270 			config->NoCollides[0] = mystrdup (CLASS_PAGER);
271 			config->NoCollides[1] = mystrdup (CLASS_WHARF);
272 			config->NoCollides_nitems = 2;
273 		}
274 		config->NoCollidesSpacing = 1;
275 	}
276 }
277 
PrintWinListConfig(WinListConfig * config)278 void PrintWinListConfig (WinListConfig * config)
279 {
280 	int i;
281 
282 	fprintf (stderr, "WinListConfig = %p;\n", config);
283 	if (config == NULL)
284 		return;
285 
286 	fprintf (stderr, "WinListConfig.flags = 0x%lX;\n", config->flags);
287 	fprintf (stderr, "WinListConfig.set_flags = 0x%lX;\n",
288 					 config->set_flags);
289 	ASCF_PRINT_FLAG_KEYWORD (stderr, WINLIST, config, FillRowsFirst);
290 	ASCF_PRINT_FLAG_KEYWORD (stderr, WINLIST, config, UseSkipList);
291 	ASCF_PRINT_GEOMETRY_KEYWORD (stderr, WINLIST, config, Geometry);
292 	ASCF_PRINT_SIZE_KEYWORD (stderr, WINLIST, config, MinSize);
293 	ASCF_PRINT_SIZE_KEYWORD (stderr, WINLIST, config, MaxSize);
294 	ASCF_PRINT_INT_KEYWORD (stderr, WINLIST, config, MaxRows);
295 	ASCF_PRINT_INT_KEYWORD (stderr, WINLIST, config, MaxColumns);
296 	ASCF_PRINT_INT_KEYWORD (stderr, WINLIST, config, MinColWidth);
297 	ASCF_PRINT_INT_KEYWORD (stderr, WINLIST, config, MaxColWidth);
298 
299 	ASCF_PRINT_INT_KEYWORD (stderr, WINLIST, config, UseName);
300 	ASCF_PRINT_FLAGS_KEYWORD (stderr, WINLIST, config, Align);
301 	ASCF_PRINT_FLAGS_KEYWORD (stderr, WINLIST, config, FBevel);
302 	ASCF_PRINT_FLAGS_KEYWORD (stderr, WINLIST, config, UBevel);
303 	ASCF_PRINT_FLAGS_KEYWORD (stderr, WINLIST, config, SBevel);
304 	ASCF_PRINT_INT_KEYWORD (stderr, WINLIST, config, FCompositionMethod);
305 	ASCF_PRINT_INT_KEYWORD (stderr, WINLIST, config, UCompositionMethod);
306 	ASCF_PRINT_INT_KEYWORD (stderr, WINLIST, config, SCompositionMethod);
307 	ASCF_PRINT_INT_KEYWORD (stderr, WINLIST, config, HSpacing);
308 	ASCF_PRINT_INT_KEYWORD (stderr, WINLIST, config, VSpacing);
309 
310 	ASCF_PRINT_STRING_KEYWORD (stderr, WINLIST, config, UnfocusedStyle);
311 	ASCF_PRINT_STRING_KEYWORD (stderr, WINLIST, config, FocusedStyle);
312 	ASCF_PRINT_STRING_KEYWORD (stderr, WINLIST, config, StickyStyle);
313 	ASCF_PRINT_STRING_KEYWORD (stderr, WINLIST, config, UrgentStyle);
314 
315 	ASCF_PRINT_INT_KEYWORD (stderr, WINLIST, config, IconLocation);
316 	ASCF_PRINT_FLAGS_KEYWORD (stderr, WINLIST, config, IconAlign);
317 	ASCF_PRINT_SIZE_KEYWORD (stderr, WINLIST, config, IconSize);
318 	ASCF_PRINT_FLAGS_KEYWORD (stderr, WINLIST, config, ShowHints);
319 
320 	fprintf (stderr, "WinListConfig.gravity = %d;\n", config->gravity);
321 
322 	for (i = 0; i < MAX_MOUSE_BUTTONS; ++i)
323 		ASCF_PRINT_IDX_COMPOUND_STRING_KEYWORD (stderr, WINLIST, config,
324 																						Action, ',', i);
325 
326 	ASCF_PRINT_INT_KEYWORD (stderr, WINLIST, config, NoCollidesSpacing);
327 
328 }
329 
330 void
WinList_fs2config(ASModuleConfig * asmodule_config,FreeStorageElem * Storage)331 WinList_fs2config (ASModuleConfig * asmodule_config,
332 									 FreeStorageElem * Storage)
333 {
334 	FreeStorageElem *pCurr;
335 	ConfigItem item;
336 	WinListConfig *config = AS_WINLIST_CONFIG (asmodule_config);
337 
338 	if (config == NULL)
339 		return;
340 
341 	item.memory = NULL;
342 	for (pCurr = Storage; pCurr; pCurr = pCurr->next) {
343 		if (pCurr->term == NULL)
344 			continue;
345 
346 		if (pCurr->term->type == TT_FLAG) {
347 			if (pCurr->term->id == WINLIST_Bevel_ID) {
348 				set_scalar_value (&(config->FBevel),
349 													ParseBevelOptions (pCurr->sub),
350 													&(config->set_flags), WINLIST_Bevel);
351 				config->UBevel = config->SBevel = config->FBevel;
352 			}
353 		} else {
354 			if (!ReadConfigItem (&item, pCurr))
355 				continue;
356 
357 			switch (pCurr->term->id) {
358 			case WINLIST_Spacing_ID:
359 				set_flags (config->set_flags, WINLIST_Spacing);
360 				config->HSpacing = config->VSpacing = item.data.integer;
361 				break;
362 			case WINLIST_CompositionMethod_ID:
363 				set_flags (config->set_flags, WINLIST_CompositionMethod);
364 				config->FCompositionMethod =
365 						config->UCompositionMethod = config->SCompositionMethod =
366 						item.data.integer;
367 				break;
368 			case WINLIST_MaxWidth_ID:
369 				set_flags (config->set_flags, WINLIST_MinSize | WINLIST_MaxSize);
370 				config->MaxSize.width = config->MinSize.width = item.data.integer;
371 				break;
372 
373 			case WINLIST_Action_ID:
374 				{
375 					char *ptr = item.data.string;
376 					int action_no = 0, i;
377 
378 					if (mystrncasecmp (ptr, "Click", 5) == 0)
379 						ptr += 5;
380 					if (isdigit (ptr[0])) {
381 						action_no = atoi (ptr);
382 						if (action_no <= 0)
383 							action_no = 1;
384 						--action_no;
385 						action_no %= MAX_MOUSE_BUTTONS;
386 						i = 0;
387 						while (!isspace (ptr[i]) && ptr[i])
388 							++i;
389 						while (isspace (ptr[i]) && ptr[i])
390 							++i;
391 						ptr += i;
392 					}
393 					if (*ptr) {
394 						destroy_string_list (config->Action[action_no], 0);
395 						config->Action[action_no] = comma_string2list (ptr);
396 					}
397 					item.ok_to_free = 1;
398 				}
399 				break;
400 
401 #define HANDLE_COLLIDES_ITEM(type) \
402 	if( item.data.string != NULL ) { \
403 		config->type##Collides = saferealloc( config->type##Collides, (config->type##Collides_nitems+1)*sizeof(char*)); \
404 		config->type##Collides[config->type##Collides_nitems] = item.data.string ; \
405 		++config->type##Collides_nitems ; }	break
406 
407 			case WINLIST_NoCollides_ID:
408 				HANDLE_COLLIDES_ITEM (No);
409 			case WINLIST_AllowCollides_ID:
410 				HANDLE_COLLIDES_ITEM (Allow);
411 
412 			default:
413 				item.ok_to_free = 1;
414 			}
415 		}
416 	}
417 
418 	ReadConfigItem (&item, NULL);
419 }
420 
421 void
MergeWinListOptions(ASModuleConfig * asm_to,ASModuleConfig * asm_from)422 MergeWinListOptions (ASModuleConfig * asm_to, ASModuleConfig * asm_from)
423 {
424 	int i;
425 
426 	START_TIME (option_time);
427 
428 	WinListConfig *to = AS_WINLIST_CONFIG (asm_to);
429 	WinListConfig *from = AS_WINLIST_CONFIG (asm_from);
430 
431 	if (to && from) {
432 
433 		/* Need to merge new config with what we have already : */
434 		/* now lets check the config sanity : */
435 		/* mixing set and default flags : */
436 		ASCF_MERGE_FLAGS (to, from);
437 
438 		ASCF_MERGE_GEOMETRY_KEYWORD (WINLIST, to, from, Geometry);
439 		ASCF_MERGE_SCALAR_KEYWORD (WINLIST, to, from, MinSize);
440 		ASCF_MERGE_SCALAR_KEYWORD (WINLIST, to, from, MaxSize);
441 
442 		ASCF_MERGE_SCALAR_KEYWORD (WINLIST, to, from, MaxRows);
443 		ASCF_MERGE_SCALAR_KEYWORD (WINLIST, to, from, MaxColumns);
444 		ASCF_MERGE_SCALAR_KEYWORD (WINLIST, to, from, MaxColWidth);
445 		ASCF_MERGE_SCALAR_KEYWORD (WINLIST, to, from, MinColWidth);
446 
447 		ASCF_MERGE_STRING_KEYWORD (WINLIST, to, from, FocusedStyle);
448 		ASCF_MERGE_STRING_KEYWORD (WINLIST, to, from, UnfocusedStyle);
449 		ASCF_MERGE_STRING_KEYWORD (WINLIST, to, from, StickyStyle);
450 		ASCF_MERGE_STRING_KEYWORD (WINLIST, to, from, UrgentStyle);
451 
452 		ASCF_MERGE_SCALAR_KEYWORD (WINLIST, to, from, UseName);
453 		ASCF_MERGE_SCALAR_KEYWORD (WINLIST, to, from, Align);
454 		ASCF_MERGE_SCALAR_KEYWORD (WINLIST, to, from, FBevel);
455 		ASCF_MERGE_SCALAR_KEYWORD (WINLIST, to, from, UBevel);
456 		ASCF_MERGE_SCALAR_KEYWORD (WINLIST, to, from, SBevel);
457 
458 		ASCF_MERGE_SCALAR_KEYWORD (WINLIST, to, from, FCompositionMethod);
459 		ASCF_MERGE_SCALAR_KEYWORD (WINLIST, to, from, UCompositionMethod);
460 		ASCF_MERGE_SCALAR_KEYWORD (WINLIST, to, from, SCompositionMethod);
461 
462 		ASCF_MERGE_SCALAR_KEYWORD (WINLIST, to, from, HSpacing);
463 		ASCF_MERGE_SCALAR_KEYWORD (WINLIST, to, from, VSpacing);
464 
465 		ASCF_MERGE_SCALAR_KEYWORD (WINLIST, to, from, IconAlign);
466 		ASCF_MERGE_SCALAR_KEYWORD (WINLIST, to, from, IconLocation);
467 		ASCF_MERGE_SCALAR_KEYWORD (WINLIST, to, from, IconSize);
468 		ASCF_MERGE_SCALAR_KEYWORD (WINLIST, to, from, NoCollidesSpacing);
469 		ASCF_MERGE_SCALAR_KEYWORD (WINLIST, to, from, ShowHints);
470 
471 		for (i = 0; i < MAX_MOUSE_BUTTONS; ++i)
472 			if (from->Action[i]) {
473 				destroy_string_list (to->Action[i], 0);
474 				to->Action[i] = from->Action[i];
475 				from->Action[i] = NULL;
476 			}
477 #define MERGE_COLLIDES_ITEM(type) \
478 	 	do{ to->type##Collides = saferealloc( to->type##Collides, (from->type##Collides_nitems+to->type##Collides_nitems)*sizeof(char*)); \
479 		memcpy(&(to->type##Collides[to->type##Collides_nitems]), from->type##Collides, from->type##Collides_nitems*sizeof(char*) ) ; \
480 		to->type##Collides_nitems += from->type##Collides_nitems; \
481 		from->type##Collides_nitems = 0 ; free( from->type##Collides ); from->type##Collides = NULL ; }while(0)
482 
483 		if (from->NoCollides_nitems > 0)
484 			MERGE_COLLIDES_ITEM (No);
485 		if (from->AllowCollides_nitems > 0)
486 			MERGE_COLLIDES_ITEM (Allow);
487 	}
488 	SHOW_TIME ("to parsing", option_time);
489 }
490 
DigestWinListAlign(WinListConfig * Config,ASFlagType align)491 ASFlagType DigestWinListAlign (WinListConfig * Config, ASFlagType align)
492 {
493 	LOCAL_DEBUG_OUT ("Align = 0x%8.8lx, IconAlign = 0x%8.8lx, Location = %d",
494 									 align, Config->IconAlign, Config->IconLocation);
495 
496 	if (!get_flags (Config->set_flags, WINLIST_IconLocation)) {
497 		if (get_flags (align, PAD_H_MASK) == ALIGN_RIGHT)
498 			Config->IconLocation = 6;
499 		else if (get_flags (align, PAD_H_MASK) == ALIGN_LEFT)
500 			Config->IconLocation = 4;
501 	}
502 	if (!get_flags (Config->set_flags, WINLIST_IconAlign)) {
503 		if (get_flags (align, PAD_H_MASK) == PAD_H_MASK) {
504 			if (Config->IconLocation == 0 || Config->IconLocation == 4) {
505 				Config->IconAlign = ALIGN_RIGHT;
506 				align = (align & (~PAD_H_MASK)) | ALIGN_LEFT;
507 			} else if (Config->IconLocation == 6) {
508 				Config->IconAlign = ALIGN_LEFT;
509 				align = (align & (~PAD_H_MASK)) | ALIGN_RIGHT;
510 			}
511 		} else if (get_flags (align, PAD_H_MASK) == ALIGN_LEFT &&
512 							 (Config->IconLocation == 0 || Config->IconLocation == 4))
513 			Config->IconAlign = ALIGN_VCENTER;
514 		else if (get_flags (align, PAD_H_MASK) == ALIGN_RIGHT
515 						 && Config->IconLocation == 6)
516 			Config->IconAlign = ALIGN_VCENTER;
517 	}
518 	LOCAL_DEBUG_OUT ("Align = 0x%8.8lx, IconAlign = 0x%8.8lx, Location = %d",
519 									 align, Config->IconAlign, Config->IconLocation);
520 	return align;
521 
522 }
523 
524 void
CheckWinListConfigSanity(WinListConfig * Config,ASGeometry * default_geometry,int default_gravity,int max_columns_override,int max_rows_override)525 CheckWinListConfigSanity (WinListConfig * Config,
526 													ASGeometry * default_geometry,
527 													int default_gravity, int max_columns_override,
528 													int max_rows_override)
529 {
530 	int i;
531 
532 	if (Config == NULL)
533 		Config =
534 				AS_WINLIST_CONFIG (create_ASModule_config
535 													 (getWinListConfigClass ()));
536 
537 	if (max_columns_override > 0)
538 		Config->MaxColumns = max_columns_override;
539 
540 	if (max_rows_override > 0)
541 		Config->MaxRows = max_rows_override;
542 
543 	if (Config->MaxRows > MAX_WINLIST_WINDOW_COUNT || Config->MaxRows == 0)
544 		Config->MaxRows = MAX_WINLIST_WINDOW_COUNT;
545 
546 	if (Config->MaxColumns > MAX_WINLIST_WINDOW_COUNT
547 			|| Config->MaxColumns == 0)
548 		Config->MaxColumns = MAX_WINLIST_WINDOW_COUNT;
549 
550 	if (max_columns_override > 0 && max_rows_override > 0) {
551 		if (Config->MaxColumns > Config->MaxRows)
552 			set_flags (Config->flags, ASWL_RowsFirst);
553 		else
554 			clear_flags (Config->flags, ASWL_RowsFirst);
555 	}
556 
557 	if (default_geometry && default_geometry->flags != 0)
558 		Config->Geometry = *default_geometry;
559 
560 	if (get_flags (Config->Geometry.flags, WidthValue)
561 			&& Config->Geometry.width > 0)
562 		Config->MinSize.width = Config->MaxSize.width = Config->Geometry.width;
563 
564 	Config->gravity = StaticGravity;
565 	if (get_flags (Config->Geometry.flags, XNegative))
566 		Config->gravity =
567 				get_flags (Config->Geometry.flags,
568 									 YNegative) ? SouthEastGravity : NorthEastGravity;
569 	else if (get_flags (Config->Geometry.flags, YNegative))
570 		Config->gravity = SouthWestGravity;
571 
572 	LOCAL_DEBUG_OUT ("gravity = %d, default_gravity = %d", Config->gravity,
573 									 default_gravity);
574 	if (default_gravity != ForgetGravity)
575 		Config->gravity = default_gravity;
576 
577 	Config->anchor_x =
578 			get_flags (Config->Geometry.flags, XValue) ? Config->Geometry.x : 0;
579 	if (get_flags (Config->Geometry.flags, XNegative))
580 		Config->anchor_x += Scr.MyDisplayWidth;
581 
582 	Config->anchor_y =
583 			get_flags (Config->Geometry.flags, YValue) ? Config->Geometry.y : 0;
584 	if (get_flags (Config->Geometry.flags, YNegative))
585 		Config->anchor_y += Scr.MyDisplayHeight;
586 
587 	/* ASN_NameTypes - is a valid value now - meaning that there won't be any name - only an icon */
588 	Config->UseName %= ASN_NameTypes + 1;
589 
590 	if (Config->UseName == ASN_NameTypes) {
591 		if (get_flags (Config->flags, WINLIST_ShowIcon)) {
592 			/* clear_flags(Config->flags, WINLIST_ScaleIconToTextHeight);
593 			   - can use xml vars to determine text instead or icons turn out too big */
594 		} else
595 			Config->UseName = 0;			/* default - ASN_Name */
596 	}
597 
598 	if (get_flags (Config->flags, WINLIST_ShowIcon))
599 		Config->Align = DigestWinListAlign (Config, Config->Align);
600 
601 #define MAKE_COLLIDES_WREXP(type)	do{ \
602 		Config->type##Collides_wrexp = safecalloc( Config->type##Collides_nitems, sizeof(wild_reg_exp)); \
603 		for( i = 0 ; i < Config->type##Collides_nitems ; ++i ) \
604 			Config->type##Collides_wrexp[i] = compile_wild_reg_exp( Config->type##Collides[i] ); \
605 	}while(0)
606 
607 	if (Config->NoCollides_nitems > 0)
608 		MAKE_COLLIDES_WREXP (No);
609 	if (Config->AllowCollides_nitems > 0)
610 		MAKE_COLLIDES_WREXP (Allow);
611 }
612