X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;f=de%2Finit.c;h=60c87156375883d50a5b872b2d85ce34f6dd97d6;hb=ae4260bb64817c11f9a7140324cd3e3ba113e297;hp=ad403236d9ee20cae83bfa52e52a18e2ff1e3e31;hpb=803afbc1cd633f6c025bcd9537e9b7e9aedadd0d;p=ion3.git diff --git a/de/init.c b/de/init.c index ad40323..60c8715 100644 --- a/de/init.c +++ b/de/init.c @@ -3,10 +3,7 @@ * * Copyright (c) Tuomo Valkonen 1999-2007. * - * 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 @@ -94,12 +91,33 @@ void de_get_border_style(uint *ret, ExtlTab tab) } +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); } @@ -109,45 +127,58 @@ void de_get_border(DEBorder *border, ExtlTab 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); } @@ -237,6 +268,63 @@ void de_get_transparent_background(uint *mode, ExtlTab tab) /*}}}*/ +/*{{{ 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 */ @@ -244,8 +332,6 @@ void de_get_nonfont(WRootWin *rootwin, DEStyle *style, ExtlTab tab) { 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; @@ -274,40 +360,37 @@ void de_get_nonfont(WRootWin *rootwin, DEStyle *style, ExtlTab tab) 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)){ @@ -320,6 +403,54 @@ bool de_defstyle_rootwin(WRootWin *rootwin, const char *name, ExtlTab tab) 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; }