1 /*
2 * Copyright (c) 1998 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 #include "../configure.h"
21 #include "../libAfterStep/asapp.h"
22 #include "../libAfterStep/afterstep.h"
23 #include "../libAfterStep/parser.h"
24 #include "../libAfterStep/background.h"
25 #include "../libAfterStep/screen.h"
26 #include "../libAfterImage/afterimage.h"
27
28 #include "afterconf.h"
29
30 /*****************************************************************************
31 *
32 * This routine is responsible for reading and parsing the asetroot config
33 * file
34 *
35 ****************************************************************************/
36
37 TermDef MyBackgroundTerms[] = {
38 {TF_NO_MYNAME_PREPENDING | TF_SYNTAX_START, "MyBackground", 12,
39 TT_QUOTED_TEXT, BGR_MYBACKGROUND, NULL}
40 ,
41 {TF_NO_MYNAME_PREPENDING | TF_DONT_SPLIT | TF_DONT_REMOVE_COMMENTS |
42 TF_INDEXED, "Use", 3, TT_OPTIONAL_PATHNAME,
43 BGR_USE, NULL}
44 ,
45 {TF_NO_MYNAME_PREPENDING, "Cut", 3, TT_GEOMETRY, BGR_CUT, NULL}
46 ,
47 {TF_NO_MYNAME_PREPENDING | TF_DONT_REMOVE_COMMENTS, "Tint", 4, TT_COLOR,
48 BGR_TINT, NULL}
49 ,
50 {TF_NO_MYNAME_PREPENDING, "Scale", 5, TT_GEOMETRY, BGR_SCALE, NULL}
51 ,
52 {TF_NO_MYNAME_PREPENDING, "Align", 5, TT_INTEGER, BGR_ALIGN, NULL}
53 ,
54 {TF_NO_MYNAME_PREPENDING | TF_INDEXED, "Pad", 3, TT_COLOR, BGR_PAD, NULL}
55 ,
56 {TF_NO_MYNAME_PREPENDING | TF_SYNTAX_TERMINATOR, "~MyBackground", 13,
57 TT_FLAG, BGR_MYBACKGROUND_END, NULL}
58 ,
59 {0, NULL, 0, 0, 0}
60 };
61
62 SyntaxDef MyBackgroundSyntax = {
63 '\n',
64 '\0',
65 MyBackgroundTerms,
66 0, /* use default hash size */
67 ' ',
68 "",
69 "\t",
70 "Look MyBackground definition",
71 "MyBackground",
72 "details how background is to be rendered",
73 NULL,
74 0
75 };
76
77
78 TermDef ASetRootTerms[] = {
79 {TF_INDEXED | TF_DONT_SPLIT | TF_NO_MYNAME_PREPENDING, "DeskBack", 8,
80 TT_QUOTED_TEXT, BGR_DESK_BACK, NULL}
81 ,
82 /* including MyStyles definitions processing */
83 INCLUDE_MYSTYLE,
84 {TF_NO_MYNAME_PREPENDING, "MyBackground", 12, TT_QUOTED_TEXT,
85 BGR_MYBACKGROUND, &MyBackgroundSyntax}
86 ,
87 {0, NULL, 0, 0, 0}
88 };
89
90 SyntaxDef ASetRootSyntax = {
91 '\n',
92 '\0',
93 ASetRootTerms,
94 0, /* use default hash size */
95 ' ',
96 "",
97 "\t",
98 "asetroot configuration",
99 "Look/DeskBack",
100 "AfterStep module for rendering root backgrounds",
101 NULL,
102 0
103 };
104
105 /***************** Create/Destroy MyBackgroundConfig *****************/
CreateMyBackgroundConfig()106 MyBackgroundConfig *CreateMyBackgroundConfig ()
107 {
108 MyBackgroundConfig *config =
109 (MyBackgroundConfig *) safemalloc (sizeof (MyBackgroundConfig));
110
111 config->name = NULL;
112 config->flags = 0;
113 config->data = NULL;
114 init_asgeometry (&(config->cut));
115 config->tint = NULL;
116 init_asgeometry (&(config->scale));
117 config->pad = NULL;
118 config->next = NULL;
119
120 return config;
121 }
122
DestroyMyBackgroundConfig(MyBackgroundConfig ** head)123 void DestroyMyBackgroundConfig (MyBackgroundConfig ** head)
124 {
125 if (head) {
126 MyBackgroundConfig *cur = *head, *next;
127
128 while (cur) {
129 if (cur->name)
130 free (cur->name);
131 if (cur->data)
132 free (cur->data);
133 if (cur->tint)
134 free (cur->tint);
135 if (cur->pad)
136 free (cur->pad);
137 next = cur->next;
138 free (cur);
139 cur = next;
140 }
141 *head = NULL;
142 }
143 }
144
145 /***************** Create/Destroy DeskBackConfig *****************/
CreateDeskBackConfig()146 DeskBackConfig *CreateDeskBackConfig ()
147 {
148 DeskBackConfig *config =
149 (DeskBackConfig *) safemalloc (sizeof (DeskBackConfig));
150
151 config->desk = -1;
152 config->back_name = NULL;
153 config->back = NULL;
154 config->next = NULL;
155
156 return config;
157 }
158
DestroyDeskBackConfig(DeskBackConfig ** head)159 void DestroyDeskBackConfig (DeskBackConfig ** head)
160 {
161 if (head) {
162 DeskBackConfig *cur = *head, *next;
163
164 while (cur) {
165 if (cur->back_name)
166 free (cur->back_name);
167
168 next = cur->next;
169 free (cur);
170 cur = next;
171 }
172 *head = NULL;
173 }
174 }
175
176 /***************** Create/Destroy ASetRootConfig *****************/
177
CreateASetRootConfig()178 ASetRootConfig *CreateASetRootConfig ()
179 {
180 ASetRootConfig *config =
181 (ASetRootConfig *) safemalloc (sizeof (ASetRootConfig));
182
183 /* let's initialize ASetRoot config with some nice values: */
184 config->my_backs = NULL;
185 config->my_desks = NULL;
186 config->style_defs = NULL;
187
188 config->more_stuff = NULL;
189
190 return config;
191 }
192
DestroyASetRootConfig(ASetRootConfig * config)193 void DestroyASetRootConfig (ASetRootConfig * config)
194 {
195 if (config->my_desks)
196 DestroyDeskBackConfig (&(config->my_desks));
197 if (config->my_backs)
198 DestroyMyBackgroundConfig (&(config->my_backs));
199 DestroyMyStyleDefinitions (&(config->style_defs));
200 DestroyFreeStorage (&(config->more_stuff));
201 free (config);
202 }
203
204 /***********************************************************************/
205 /* Actual Parsing */
206 /***********************************************************************/
207
ParseMyBackgroundOptions(FreeStorageElem * Storage,char * myname)208 MyBackgroundConfig *ParseMyBackgroundOptions (FreeStorageElem * Storage,
209 char *myname)
210 {
211 MyBackgroundConfig *config = CreateMyBackgroundConfig ();
212 FreeStorageElem *pCurr;
213 ConfigItem item;
214
215 item.memory = NULL;
216 for (pCurr = Storage; pCurr; pCurr = pCurr->next) {
217 if (pCurr->term == NULL)
218 continue;
219
220 LOCAL_DEBUG_OUT ("options(%p)->keyword(\"%s\")", pCurr,
221 pCurr->term->keyword);
222
223 if (pCurr->term->id == BGR_MYBACKGROUND_END) {
224 config->flags |= BGFLAG_COMPLETE;
225 continue;
226 }
227 if (!ReadConfigItem (&item, pCurr)) {
228 if (pCurr->term->id == BGR_SCALE)
229 config->flags |= BGFLAG_SCALE;
230 continue;
231 }
232
233 switch (pCurr->term->id) {
234 case BGR_MYBACKGROUND:
235 config->name = item.data.string;
236 break;
237 case BGR_USE:
238 config->data = item.data.string;
239 config->flags &= ~(BGFLAG_FILE | BGFLAG_MYSTYLE);
240 if (item.index == 0)
241 config->flags |= BGFLAG_FILE;
242 else if (item.index == 1)
243 config->flags |= BGFLAG_MYSTYLE;
244 break;
245 case BGR_CUT:
246 config->cut = item.data.geometry;
247 config->flags |= BGFLAG_CUT;
248 break;
249 case BGR_TINT:
250 config->tint = item.data.string;
251 config->flags |= BGFLAG_TINT;
252 break;
253 case BGR_SCALE:
254 config->scale = item.data.geometry;
255 config->flags |= BGFLAG_SCALE;
256 break;
257 case BGR_ALIGN:
258 config->flags &=
259 ~(BGFLAG_ALIGN_CENTER | BGFLAG_ALIGN_RIGHT |
260 BGFLAG_ALIGN_BOTTOM);
261 config->flags |= BGFLAG_ALIGN;
262 if (item.data.integer & 0x1)
263 config->flags |= BGFLAG_ALIGN_RIGHT;
264 if (item.data.integer & 0x2)
265 config->flags |= BGFLAG_ALIGN_BOTTOM;
266 item.ok_to_free = 1;
267 break;
268 case BGR_PAD:
269 config->pad = item.data.string;
270 config->flags &= ~(BGFLAG_PAD_VERT | BGFLAG_PAD_HOR);
271 config->flags |= BGFLAG_PAD;
272 if (item.index & 0x1)
273 config->flags |= BGFLAG_PAD_HOR;
274 if (item.index & 0x2)
275 config->flags |= BGFLAG_PAD_VERT;
276 break;
277 default:
278 item.ok_to_free = 1;
279 }
280 }
281 ReadConfigItem (&item, NULL);
282
283 set_flags (config->flags, BGFLAG_BAD);
284 if (config->name == NULL)
285 show_error ("Background Definition error: name is empty !");
286 else if (!(config->flags & BGFLAG_COMPLETE))
287 show_error
288 ("Background Definition error: [%s] not terminated properly !",
289 config->name);
290 else
291 clear_flags (config->flags, BGFLAG_BAD);
292
293 if (config->flags & BGFLAG_BAD)
294 DestroyMyBackgroundConfig (&config);
295 return config;
296 }
297
ParseDeskBackOptions(ConfigItem * item,char * myname)298 DeskBackConfig *ParseDeskBackOptions (ConfigItem * item, char *myname)
299 {
300 DeskBackConfig *config = CreateDeskBackConfig ();
301 Bool failed = True;
302
303 config->desk = item->index;
304 config->back_name = item->data.string;
305 item->ok_to_free = 0;
306
307 if (config->desk < 0)
308 show_error ("Desk Background Definition error: bad desk number !");
309 else if (config->back_name == NULL)
310 show_error
311 ("Desk Background Definition error: #%d has empty background name!",
312 config->desk);
313 else
314 failed = False;
315
316 if (failed)
317 DestroyDeskBackConfig (&config);
318 return config;
319 }
320
FixDeskBacks(ASetRootConfig * config)321 void FixDeskBacks (ASetRootConfig * config)
322 {
323 DeskBackConfig *curr_desk;
324
325 if (!config)
326 return;
327 for (curr_desk = config->my_desks; curr_desk;
328 curr_desk = curr_desk->next) {
329 MyBackgroundConfig *curr_back;
330
331 for (curr_back = config->my_backs; curr_back;
332 curr_back = curr_back->next)
333 if (mystrcasecmp (curr_desk->back_name, curr_back->name) == 0) {
334 curr_desk->back = curr_back;
335 break;
336 }
337 if (curr_desk->back == NULL) { /* need to create new back as plain image file,
338 using name from desk definition */
339 curr_desk->back = CreateMyBackgroundConfig ();
340 curr_desk->back->next = config->my_backs;
341 config->my_backs = curr_desk->back;
342 curr_desk->back->name =
343 (char *)safemalloc (strlen (curr_desk->back_name) + 1);
344 strcpy (curr_desk->back->name, curr_desk->back_name);
345 curr_desk->back->data =
346 (char *)safemalloc (strlen (curr_desk->back_name) + 1);
347 strcpy (curr_desk->back->data, curr_desk->back_name);
348 curr_desk->back->flags |= BGFLAG_FILE | BGFLAG_COMPLETE;
349 }
350 }
351 }
352
ParseASetRootOptions(const char * filename,char * myname)353 ASetRootConfig *ParseASetRootOptions (const char *filename, char *myname)
354 {
355 ConfigData cd;
356 ConfigDef *ConfigReader;
357 ASetRootConfig *config = CreateASetRootConfig ();
358 MyBackgroundConfig **backs_tail = &(config->my_backs);
359 DeskBackConfig **desks_tail = &(config->my_desks);
360 FreeStorageElem *Storage = NULL, *pCurr;
361 ConfigItem item;
362
363 cd.filename = filename;
364 ConfigReader =
365 InitConfigReader (myname, &ASetRootSyntax, CDT_Filename, cd, NULL);
366
367 if (!ConfigReader)
368 return config;
369
370 item.memory = NULL;
371 PrintConfigReader (ConfigReader);
372 ParseConfig (ConfigReader, &Storage);
373
374 /* getting rid of all the crap first */
375 StorageCleanUp (&Storage, &(config->more_stuff), CF_DISABLED_OPTION);
376
377 config->style_defs = free_storage2MyStyleDefinitionsList (Storage);
378
379 for (pCurr = Storage; pCurr; pCurr = pCurr->next) {
380 if (pCurr->term == NULL)
381 continue;
382
383 if (pCurr->term->id == BGR_MYBACKGROUND) {
384 if ((*backs_tail =
385 ParseMyBackgroundOptions (pCurr->sub, myname)) != NULL)
386 backs_tail = &((*backs_tail)->next);
387 continue;
388 }
389
390 if (!ReadConfigItem (&item, pCurr))
391 continue;
392 switch (pCurr->term->id) {
393 case BGR_DESK_BACK:
394 if ((*desks_tail = ParseDeskBackOptions (&item, myname)) != NULL)
395 desks_tail = &((*desks_tail)->next);
396 break;
397 default:
398 item.ok_to_free = 1;
399 }
400 }
401 ReadConfigItem (&item, NULL);
402 FixDeskBacks (config);
403
404 DestroyConfig (ConfigReader);
405 DestroyFreeStorage (&Storage);
406 return config;
407 }
408
myback_parse(char * tline,FILE * fd,char ** myname,int * mylook)409 void myback_parse (char *tline, FILE * fd, char **myname, int *mylook)
410 {
411 FilePtrAndData fpd;
412 ConfigDef *ConfigReader;
413 MyBackgroundConfig *back_config = NULL;
414 FreeStorageElem *Storage = NULL, *more_stuff = NULL;
415 MyLook *look = (MyLook *) mylook;
416 MyBackground *myback = NULL;
417 ConfigData cd;
418
419 if (look == NULL)
420 look = get_screen_look (NULL);
421
422 fpd.fp = fd;
423 fpd.data = safemalloc (12 + 1 + strlen (tline) + 1 + 1);
424 sprintf (fpd.data, "MyBackground %s\n", tline);
425 LOCAL_DEBUG_OUT ("fd(%p)->tline(\"%s\")->fpd.data(\"%s\")", fd, tline,
426 fpd.data);
427 cd.fileptranddata = &fpd;
428 ConfigReader =
429 InitConfigReader ((char *)myname, &MyBackgroundSyntax,
430 CDT_FilePtrAndData, cd, NULL);
431 free (fpd.data);
432
433 if (!ConfigReader)
434 return;
435
436 PrintConfigReader (ConfigReader);
437 ParseConfig (ConfigReader, &Storage);
438
439 /* getting rid of all the crap first */
440 StorageCleanUp (&Storage, &more_stuff, CF_DISABLED_OPTION);
441 DestroyFreeStorage (&more_stuff);
442
443 back_config = ParseMyBackgroundOptions (Storage, (char *)myname);
444
445 DestroyConfig (ConfigReader);
446 DestroyFreeStorage (&Storage);
447
448 if (back_config == NULL)
449 return;
450
451 /* now we have to turn MyBackgroundConfig into MyBackground structure : */
452 myback = create_myback (back_config->name);
453
454 if (get_flags (back_config->flags, BGFLAG_FILE))
455 myback->type = MB_BackImage;
456 else if (get_flags (back_config->flags, BGFLAG_MYSTYLE))
457 myback->type = MB_BackMyStyle;
458 else
459 myback->type = MB_BackCmd;
460
461 myback->data = back_config->data;
462 back_config->data = NULL;
463 if (get_flags (back_config->flags, BGFLAG_CUT))
464 myback->cut = back_config->cut;
465 if (get_flags (back_config->flags, BGFLAG_SCALE)) {
466 myback->scale = back_config->scale;
467 if (!get_flags (back_config->scale.flags, WidthValue))
468 myback->scale.width = get_screen_width (NULL);
469 if (!get_flags (back_config->scale.flags, HeightValue))
470 myback->scale.height = get_screen_height (NULL);
471 set_flags (myback->scale.flags, WidthValue | HeightValue);
472 }
473
474 myback->tint = TINT_LEAVE_SAME;
475 if (get_flags (back_config->flags, BGFLAG_TINT) && back_config->tint)
476 parse_argb_color (back_config->tint, &(myback->tint));
477 myback->pad_color = ARGB32_Black;
478 if (get_flags (back_config->flags, BGFLAG_PAD) && back_config->pad)
479 parse_argb_color (back_config->pad, &(myback->pad_color));
480
481 myback->align_flags = NO_ALIGN;
482 if (get_flags (back_config->flags, BGFLAG_PAD_HOR)) {
483 if (get_flags (back_config->flags, BGFLAG_ALIGN_RIGHT))
484 myback->align_flags = ALIGN_RIGHT;
485 else if (get_flags (back_config->flags, BGFLAG_ALIGN_CENTER))
486 myback->align_flags = ALIGN_HCENTER;
487 else
488 myback->align_flags = ALIGN_LEFT;
489 }
490 if (get_flags (back_config->flags, BGFLAG_PAD_VERT)) {
491 if (get_flags (back_config->flags, BGFLAG_ALIGN_BOTTOM))
492 myback->align_flags |= ALIGN_BOTTOM;
493 else if (get_flags (back_config->flags, BGFLAG_ALIGN_CENTER))
494 myback->align_flags |= ALIGN_VCENTER;
495 else
496 myback->align_flags = ALIGN_TOP;
497 }
498 LOCAL_DEBUG_OUT ("myback added: name(\"%s\")->type(%d)->data(\"%s\")",
499 myback->name, myback->type, myback->data);
500 add_myback (look, myback);
501
502 /* final cleanup : */
503 DestroyMyBackgroundConfig (&back_config);
504 }
505