/*
* ion/de/init.c
*
- * Copyright (c) Tuomo Valkonen 1999-2007.
+ * Copyright (c) Tuomo Valkonen 1999-2009.
*
- * Ion is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
+ * See the included file LICENSE for details.
*/
#include <string.h>
}
+void de_get_border_sides(uint *ret, ExtlTab tab)
+{
+ char *style=NULL;
+
+ if(!extl_table_gets_s(tab, "border_sides", &style))
+ return;
+
+ if(strcmp(style, "all")==0)
+ *ret=DEBORDER_ALL;
+ else if(strcmp(style, "tb")==0)
+ *ret=DEBORDER_TB;
+ else if(strcmp(style, "lr")==0)
+ *ret=DEBORDER_LR;
+ else
+ warn(TR("Unknown border side configuration \"%s\"."), style);
+
+ free(style);
+}
+
+
void de_get_border(DEBorder *border, ExtlTab tab)
{
de_get_border_val(&(border->sh), tab, "shadow_pixels");
de_get_border_val(&(border->hl), tab, "highlight_pixels");
de_get_border_val(&(border->pad), tab, "padding_pixels");
de_get_border_style(&(border->style), tab);
+ de_get_border_sides(&(border->sides), tab);
}
/*{{{ Colours */
-bool de_get_colour(WRootWin *rootwin, DEColour *ret,
- ExtlTab tab, DEStyle *based_on,
- const char *what, DEColour substitute)
+static bool de_get_colour_(WRootWin *rootwin, DEColour *ret,
+ ExtlTab tab, const char *what,
+ DEColour substitute, DEColour inherit)
{
char *name=NULL;
- bool ok=FALSE;
+ bool set=FALSE;
if(extl_table_gets_s(tab, what, &name)){
- ok=de_alloc_colour(rootwin, ret, name);
+ if(strcmp(name, "inherit")==0){
+ set=de_duplicate_colour(rootwin, inherit, ret);
+ }else{
+ set=de_alloc_colour(rootwin, ret, name);
- if(!ok)
- warn(TR("Unable to allocate colour \"%s\"."), name);
-
+ if(!set)
+ warn(TR("Unable to allocate colour \"%s\"."), name);
+ }
free(name);
- }else if(based_on!=NULL){
- return de_get_colour(rootwin, ret, based_on->data_table,
- based_on->based_on, what, substitute);
}
- if(!ok)
- ok=de_duplicate_colour(rootwin, substitute, ret);
+ if(!set)
+ de_duplicate_colour(rootwin, substitute, ret);
- return ok;
+ return set;
}
+static bool de_get_colour(WRootWin *rootwin, DEColour *ret,
+ ExtlTab tab, const char *what, DEColour substitute)
+{
+ return de_get_colour_(rootwin, ret, tab, what, substitute, substitute);
+}
+
+
void de_get_colour_group(WRootWin *rootwin, DEColourGroup *cg,
ExtlTab tab, DEStyle *based_on)
{
- de_get_colour(rootwin, &(cg->hl), tab, based_on, "highlight_colour",
- DE_WHITE(rootwin));
- de_get_colour(rootwin, &(cg->sh), tab, based_on, "shadow_colour",
- DE_WHITE(rootwin));
- de_get_colour(rootwin, &(cg->bg), tab, based_on, "background_colour",
- DE_BLACK(rootwin));
- de_get_colour(rootwin, &(cg->fg), tab, based_on, "foreground_colour",
- DE_WHITE(rootwin));
- de_get_colour(rootwin, &(cg->pad), tab, based_on, "padding_colour",
- cg->bg);
+ bool bgset;
+ DEColour padinh;
+
+ de_get_colour(rootwin, &(cg->hl), tab, "highlight_colour",
+ (based_on ? based_on->cgrp.hl : DE_WHITE(rootwin)));
+ de_get_colour(rootwin, &(cg->sh), tab, "shadow_colour",
+ (based_on ? based_on->cgrp.sh : DE_WHITE(rootwin)));
+ de_get_colour(rootwin, &(cg->fg), tab, "foreground_colour",
+ (based_on ? based_on->cgrp.fg : DE_WHITE(rootwin)));
+ bgset=de_get_colour(rootwin, &(cg->bg), tab, "background_colour",
+ (based_on ? based_on->cgrp.bg : DE_BLACK(rootwin)));
+
+ padinh=(based_on ? based_on->cgrp.pad : DE_WHITE(rootwin));
+
+ de_get_colour_(rootwin, &(cg->pad), tab, "padding_colour",
+ (bgset ? cg->bg : padinh), padinh);
}
/*}}}*/
+/*{{{ Extras filter/copy */
+
+
+static const char * const known_values[]={
+ "based_on",
+ "font",
+ "shadow_pixels",
+ "highlight_pixels",
+ "padding_pixels",
+ "border_style",
+ "border_sides",
+ "spacing",
+ "foreground_colour",
+ "background_colour",
+ "shadow_colour",
+ "highlight_colour",
+ "padding_colour",
+ "text_align",
+ NULL
+};
+
+
+static bool filter_extras_iter_fn(ExtlAny k, ExtlAny v, void *p)
+{
+ ExtlTab *tgt=(ExtlTab*)p;
+ const char *s;
+ int i;
+
+ if(k.type!='s' && k.type!='S')
+ return TRUE;
+
+ for(i=0; known_values[i]; i++){
+ if(strcmp(known_values[i], k.value.s)==0)
+ return TRUE;
+ }
+
+ if(*tgt==extl_table_none())
+ *tgt=extl_create_table();
+
+ extl_table_set(*tgt, 'a', 'a', k, v);
+
+ return TRUE;
+}
+
+
+static void filter_extras(ExtlTab *tgt, ExtlTab src)
+{
+ /* Copy any unknown string-keyed values from src to tgt,
+ * possibly creating tgt.
+ */
+ extl_table_iter(src, filter_extras_iter_fn, tgt);
+}
+
+
+/*}}}*/
+
+
/*{{{ de_defstyle */
{
DEStyle *based_on=style->based_on;
- style->data_table=extl_ref_table(tab);
-
if(based_on!=NULL){
style->border=based_on->border;
style->transparency_mode=based_on->transparency_mode;
EXTL_EXPORT
bool de_defstyle_rootwin(WRootWin *rootwin, const char *name, ExtlTab tab)
{
- DEStyle *style;
- char *fnt;
+ DEStyle *style, *based_on=NULL;
+ int based_on_score=-1;
+ char *fnt, *bss;
uint n;
- char *based_on_name;
- DEStyle *based_on=NULL;
- GrStyleSpec based_on_spec;
if(name==NULL)
return FALSE;
style=de_create_style(rootwin, name);
-
+
if(style==NULL)
return FALSE;
-
- if(get_spec(tab, "based_on", &based_on_spec, &based_on_name)){
- based_on=de_get_style(rootwin, &based_on_spec);
+
+ if(extl_table_gets_s(tab, "based_on", &bss)){
+ GrStyleSpec bs;
- gr_stylespec_unalloc(&based_on_spec);
-
- if(based_on==style){
- warn(TR("'based_on' for %s points back to the style itself."),
- name);
- }else if(based_on==NULL){
- warn(TR("Unknown base style. \"%s\""), based_on_name);
- }else{
- style->based_on=based_on;
- based_on->usecount++;
- /* Copy simple parameters */
- }
+ gr_stylespec_load(&bs, bss);
- free(based_on_name);
+ based_on=de_get_style(rootwin, &bs);
+
+ gr_stylespec_unalloc(&bs);
+ free(bss);
+ }else{
+ based_on=de_get_style(rootwin, &style->spec);
}
-
+
+ if(based_on!=NULL){
+ style->based_on=based_on;
+ based_on->usecount++;
+ }
+
de_get_nonfont(rootwin, style, tab);
if(extl_table_gets_s(tab, "font", &fnt)){
if(style->font==NULL)
de_load_font_for_style(style, CF_FALLBACK_FONT_NAME);
+ if(based_on!=NULL &&
+ gr_stylespec_equals(&based_on->spec, &style->spec)){
+
+ /* The new style replaces based_on, so it may be dumped. */
+ if(!based_on->is_fallback)
+ destyle_dump(based_on);
+
+ if(based_on->usecount==1){
+ uint nb=based_on->n_extra_cgrps;
+ uint ns=style->n_extra_cgrps;
+ /* Nothing else is using based_on: optimise and move
+ * extra colour groups here, so that based_on can be freed.
+ */
+
+ if(nb>0){
+ DEColourGroup *cgs=ALLOC_N(DEColourGroup, nb+ns);
+
+ if(cgs!=NULL){
+ memcpy(cgs, based_on->extra_cgrps, sizeof(DEColourGroup)*nb);
+ memcpy(cgs+nb, style->extra_cgrps, sizeof(DEColourGroup)*ns);
+
+ free(style->extra_cgrps);
+ style->extra_cgrps=cgs;
+ style->n_extra_cgrps=nb+ns;
+
+ free(based_on->extra_cgrps);
+ based_on->extra_cgrps=NULL;
+ based_on->n_extra_cgrps=0;
+
+ }
+ }
+
+ /* style->extras_table should be none still */
+ style->extras_table=based_on->extras_table;
+ based_on->extras_table=extl_table_none();
+
+ style->based_on=based_on->based_on;
+ based_on->based_on=NULL;
+
+ destyle_unref(based_on);
+ }
+
+ }
+
+ filter_extras(&style->extras_table, tab);
+
+ destyle_add(style);
+
return TRUE;
}