]> git.decadent.org.uk Git - ion3.git/blob - de/init.c
[svn-inject] Installing original source of ion3
[ion3.git] / de / init.c
1 /*
2  * ion/de/init.c
3  *
4  * Copyright (c) Tuomo Valkonen 1999-2006. 
5  *
6  * Ion is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; either version 2.1 of the License, or
9  * (at your option) any later version.
10  */
11
12 #include <string.h>
13
14 #include <libextl/readconfig.h>
15 #include <libextl/extl.h>
16
17 #include <ioncore/common.h>
18 #include <ioncore/global.h>
19 #include <ioncore/rootwin.h>
20 #include <ioncore/extlconv.h>
21 #include <ioncore/ioncore.h>
22
23 #include "brush.h"
24 #include "font.h"
25 #include "colour.h"
26 #include "private.h"
27 #include "init.h"
28 #include "exports.h"
29
30
31 /*{{{ Borders */
32
33
34 #define CF_BORDER_VAL_SANITY_CHECK 16
35
36 void de_get_border_val(uint *val, ExtlTab tab, const char *what)
37 {
38     int g;
39     
40     if(extl_table_gets_i(tab, what, &g)){
41         if(g>CF_BORDER_VAL_SANITY_CHECK || g<0)
42             warn(TR("Border attribute %s sanity check failed."), what);
43         else
44             *val=g;
45     }
46 }
47
48
49 void de_get_border_style(uint *ret, ExtlTab tab)
50 {
51     char *style=NULL;
52     
53     if(!extl_table_gets_s(tab, "border_style", &style))
54         return;
55     
56     if(strcmp(style, "inlaid")==0)
57         *ret=DEBORDER_INLAID;
58     else if(strcmp(style, "elevated")==0)
59         *ret=DEBORDER_ELEVATED;
60     else if(strcmp(style, "groove")==0)
61         *ret=DEBORDER_GROOVE;
62     else if(strcmp(style, "ridge")==0)
63         *ret=DEBORDER_RIDGE;
64     else
65         warn(TR("Unknown border style \"%s\"."), style);
66     
67     free(style);
68 }
69
70
71 void de_get_border(DEBorder *border, ExtlTab tab)
72 {
73     de_get_border_val(&(border->sh), tab, "shadow_pixels");
74     de_get_border_val(&(border->hl), tab, "highlight_pixels");
75     de_get_border_val(&(border->pad), tab, "padding_pixels");
76     de_get_border_style(&(border->style), tab);
77 }
78
79
80 /*}}}*/
81
82
83 /*{{{ Colours */
84
85
86 bool de_get_colour(WRootWin *rootwin, DEColour *ret, 
87                    ExtlTab tab, DEStyle *based_on,
88                    const char *what, DEColour substitute)
89 {
90     char *name=NULL;
91     bool ok=FALSE;
92     
93     if(extl_table_gets_s(tab, what, &name)){
94         ok=de_alloc_colour(rootwin, ret, name);
95     
96         if(!ok)
97             warn(TR("Unable to allocate colour \"%s\"."), name);
98
99         free(name);
100     }else if(based_on!=NULL){
101         return de_get_colour(rootwin, ret, based_on->data_table,
102                              based_on->based_on, what, substitute);
103     }
104     
105     if(!ok)
106         ok=de_duplicate_colour(rootwin, substitute, ret);
107     
108     return ok;
109 }
110
111
112 void de_get_colour_group(WRootWin *rootwin, DEColourGroup *cg, 
113                          ExtlTab tab, DEStyle *based_on)
114 {
115     de_get_colour(rootwin, &(cg->hl), tab, based_on, "highlight_colour",
116                   DE_WHITE(rootwin));
117     de_get_colour(rootwin, &(cg->sh), tab, based_on, "shadow_colour",
118                   DE_WHITE(rootwin));
119     de_get_colour(rootwin, &(cg->bg), tab, based_on, "background_colour",
120                   DE_BLACK(rootwin));
121     de_get_colour(rootwin, &(cg->fg), tab, based_on, "foreground_colour",
122                   DE_WHITE(rootwin));
123     de_get_colour(rootwin, &(cg->pad), tab, based_on, "padding_colour", 
124                   cg->bg);
125 }
126
127
128 void de_get_extra_cgrps(WRootWin *rootwin, DEStyle *style, ExtlTab tab)
129 {
130     
131     uint i=0, nfailed=0, n=extl_table_get_n(tab);
132     char *name;
133     ExtlTab sub;
134     
135     if(n==0)
136         return;
137     
138     style->extra_cgrps=ALLOC_N(DEColourGroup, n);
139     
140     if(style->extra_cgrps==NULL)
141         return;
142
143     for(i=0; i<n-nfailed; i++){
144         if(!extl_table_geti_t(tab, i+1, &sub))
145             goto err;
146         if(!extl_table_gets_s(sub, "substyle_pattern", &name)){
147             extl_unref_table(sub);
148             goto err;
149         }
150         
151         /*de_init_colour_group(rootwin, style->extra_cgrps+i-nfailed);*/
152         style->extra_cgrps[i-nfailed].spec=name;
153         de_get_colour_group(rootwin, style->extra_cgrps+i-nfailed, sub, 
154                             style);
155         
156         extl_unref_table(sub);
157         continue;
158         
159     err:
160         warn(TR("Corrupt substyle table %d."), i);
161         nfailed++;
162     }
163     
164     if(n-nfailed==0){
165         free(style->extra_cgrps);
166         style->extra_cgrps=NULL;
167     }
168     
169     style->n_extra_cgrps=n-nfailed;
170 }
171
172
173 /*}}}*/
174
175
176 /*{{{ Misc. */
177
178
179 void de_get_text_align(int *alignret, ExtlTab tab)
180 {
181     char *align=NULL;
182     
183     if(!extl_table_gets_s(tab, "text_align", &align))
184         return;
185     
186     if(strcmp(align, "left")==0)
187         *alignret=DEALIGN_LEFT;
188     else if(strcmp(align, "right")==0)
189         *alignret=DEALIGN_RIGHT;
190     else if(strcmp(align, "center")==0)
191         *alignret=DEALIGN_CENTER;
192     else
193         warn(TR("Unknown text alignment \"%s\"."), align);
194     
195     free(align);
196 }
197
198
199 void de_get_transparent_background(uint *mode, ExtlTab tab)
200 {
201     bool b;
202     
203     if(extl_table_gets_b(tab, "transparent_background", &b))
204         *mode=b;
205 }
206
207
208 /*}}}*/
209
210
211 /*{{{ de_defstyle */
212
213
214 void de_get_nonfont(WRootWin *rootwin, DEStyle *style, ExtlTab tab)
215 {
216     DEStyle *based_on=style->based_on;
217     
218     style->data_table=extl_ref_table(tab);
219
220     if(based_on!=NULL){
221         style->border=based_on->border;
222         style->transparency_mode=based_on->transparency_mode;
223         style->textalign=based_on->textalign;
224         style->spacing=based_on->spacing;
225     }
226     
227     de_get_border(&(style->border), tab);
228     de_get_border_val(&(style->spacing), tab, "spacing");
229
230     de_get_text_align(&(style->textalign), tab);
231
232     de_get_transparent_background(&(style->transparency_mode), tab);
233
234     style->cgrp_alloced=TRUE;
235     de_get_colour_group(rootwin, &(style->cgrp), tab, based_on);
236     de_get_extra_cgrps(rootwin, style, tab);
237 }
238
239
240 /*EXTL_DOC
241  * Define a style for the root window \var{rootwin}. 
242  */
243 EXTL_EXPORT
244 bool de_defstyle_rootwin(WRootWin *rootwin, const char *name, ExtlTab tab)
245 {
246     DEStyle *style;
247     char *fnt;
248     uint n;
249     DEStyle *based_on=NULL;
250     char *based_on_name=NULL;
251
252     if(name==NULL)
253         return FALSE;
254     
255     style=de_create_style(rootwin, name);
256
257     if(style==NULL)
258         return FALSE;
259
260     if(extl_table_gets_s(tab, "based_on", &based_on_name)){
261         based_on=de_get_style(rootwin, based_on_name);
262         if(based_on==style){
263             warn(TR("'based_on' for %s points back to the style itself."),
264                  name);
265         }else if(based_on==NULL){
266             warn(TR("Unknown base style \"%s\"."), based_on);
267         }else{
268             style->based_on=based_on;
269             based_on->usecount++;
270             /* Copy simple parameters */
271         }
272         free(based_on_name);
273     }
274
275     de_get_nonfont(rootwin, style, tab);
276
277     if(extl_table_gets_s(tab, "font", &fnt)){
278         de_load_font_for_style(style, fnt);
279         free(fnt);
280     }else if(based_on!=NULL && based_on->font!=NULL){
281         de_set_font_for_style(style, based_on->font);
282     }
283     
284     if(style->font==NULL)
285         de_load_font_for_style(style, CF_FALLBACK_FONT_NAME);
286     
287     return TRUE;
288 }
289
290
291 /*EXTL_DOC
292  * Define a style.
293  */
294 EXTL_EXPORT
295 bool de_defstyle(const char *name, ExtlTab tab)
296 {
297     bool ok=TRUE;
298     WRootWin *rw;
299     
300     FOR_ALL_ROOTWINS(rw){
301         if(!de_defstyle_rootwin(rw, name, tab))
302             ok=FALSE;
303     }
304     
305     return ok;
306 }
307
308
309 /*EXTL_DOC
310  * Define a substyle.
311  */
312 EXTL_SAFE
313 EXTL_EXPORT
314 ExtlTab de_substyle(const char *pattern, ExtlTab tab)
315 {
316     extl_table_sets_s(tab, "substyle_pattern", pattern);
317     return extl_ref_table(tab);
318 }
319
320
321 /*}}}*/
322
323
324 /*{{{ Module initialisation */
325
326
327 #include "../version.h"
328
329 char de_ion_api_version[]=ION_API_VERSION;
330
331
332 bool de_init()
333 {
334     WRootWin *rootwin;
335     DEStyle *style;
336     
337     if(!de_register_exports())
338         return FALSE;
339     
340     if(!gr_register_engine("de", (GrGetBrushFn*)&de_get_brush))
341         goto fail;
342     
343     /* Create fallback brushes */
344     FOR_ALL_ROOTWINS(rootwin){
345         style=de_create_style(rootwin, "*");
346         if(style!=NULL){
347             style->is_fallback=TRUE;
348             de_load_font_for_style(style, CF_FALLBACK_FONT_NAME);
349         }
350     }
351     
352     return TRUE;
353     
354 fail:
355     de_unregister_exports();
356     return FALSE;
357 }
358
359
360 void de_deinit()
361 {
362     gr_unregister_engine("de");
363     de_unregister_exports();
364     de_deinit_styles();
365 }
366
367
368 /*}}}*/
369