From: root Date: Tue, 11 May 2010 21:53:30 +0000 (-0400) Subject: initial import X-Git-Url: http://git.openbox.org/?p=manmower%2Fobtheme.git;a=commitdiff_plain;h=6dd728bcb59e330a8d2d7c637e69435f9d6c8bad initial import --- 6dd728bcb59e330a8d2d7c637e69435f9d6c8bad diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..610580e --- /dev/null +++ b/Makefile @@ -0,0 +1,17 @@ +CFLAGS=-g -Wall -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include + +.PRECIOUS: %.tab.h %.lex.c %.tab.c + +%.tab.h %.tab.c: %.y %.h + bison -t -p $* -d $< + +%.lex.c: %.l %.tab.h %.h + flex -P$* -o$@ $< + +all: obtheme + +obtheme: main.o obtheme.tab.o obtheme.lex.o obtheme.tab.h + $(CC) $(CFLAGS) -o obtheme main.o obtheme.tab.o obtheme.lex.o -lm -lglib-2.0 + +clean: + rm -f obtheme *.lex.* *.tab.* *.o obtheme.c diff --git a/main.c b/main.c new file mode 100644 index 0000000..b93ef08 --- /dev/null +++ b/main.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include "obtheme.h" + +static void decor_print(gpointer data, gpointer user_data) +{ + struct decor *decor = data; + printf(" decor id %s\n", decor->name); + printf(" anchor (%d %d %d)\n", decor->space.anchor.x, decor->space.anchor.y, decor->space.anchor.z); + printf(" up (%d %d %d)\n", decor->space.up.x, decor->space.up.y, decor->space.up.z); + if (decor->children) + g_slist_foreach(decor->children, decor_print, NULL); +} + +static void class_print(gpointer key, gpointer value, gpointer user_data) +{ + char *classname = key; + struct class *class = value; + + printf(" Class %s\n", classname); + g_slist_foreach(class->tree, decor_print, NULL); +} + +static void theme_print(gpointer key, gpointer value, gpointer user_data) +{ + char *name = key; + struct theme *thm = value; + printf("name = %s\n", name); + g_hash_table_foreach(thm->classes, class_print, NULL); +} + +static void material_print(gpointer key, gpointer value, gpointer user_data) +{ + char *name = key; + struct material *mat = value; + printf("name = %s\n", name); + printf(" opacity = %f\n", mat->opacity); +} + +int main(int argc, char **argv) +{ + int err; + struct obthemedata themedata; + + themedata.themes = g_hash_table_new(g_str_hash, g_str_equal); + themedata.materials = g_hash_table_new(g_str_hash, g_str_equal); + err = obtheme_parse(&themedata, argv[1]); + printf("err = %d\n", err); + + g_hash_table_foreach(themedata.materials, material_print, NULL); + + g_hash_table_foreach(themedata.themes, theme_print, NULL); + + return 0; +} diff --git a/obtheme.h b/obtheme.h new file mode 100644 index 0000000..6c67788 --- /dev/null +++ b/obtheme.h @@ -0,0 +1,68 @@ +#ifndef __THEME_PARSE_H__ +#define __THEME_PARSE_H__ + +#include + +#undef YY_DECL +#define YY_DECL int obthemelex(YYSTYPE *yylval, struct parser_control *pc) + +#define YYDEBUG 1 +#define YYLEX_PARAM pc + +#define MAX_INCLUDE_DEPTH 32 +#define LINE pc->currline[pc->include_stack_ptr] + +extern int themedebug; + +struct material { + float opacity; +}; + +struct class { + char *name; + GSList *tree; +}; + +struct obthemedata { + GHashTable *themes; + GHashTable *materials; +}; + +struct theme { + char *name; + GHashTable *classes; +}; + +struct vector { + int x; + int y; + int z; +}; + +struct space { + struct vector anchor; + struct vector up; +}; + +struct decor { + char *name; + GSList *children; + struct space space; +}; + +struct parser_control { + struct yy_buffer_state *include_stack[MAX_INCLUDE_DEPTH]; + int currline[MAX_INCLUDE_DEPTH]; + char currfile[MAX_INCLUDE_DEPTH][501]; + int include_stack_ptr; + char error_buf[4096]; + struct obthemedata *target; +}; + +void obthemeerror(struct parser_control *pc, char *s); +int obtheme_parse(struct obthemedata *td, const char *filename); +struct parser_control *parser_init(struct obthemedata *td); +int obthemeparse(struct parser_control *); +void parser_finish(struct parser_control *); + +#endif /* __THEME_PARSE_H__ */ diff --git a/obtheme.l b/obtheme.l new file mode 100644 index 0000000..c87dc4d --- /dev/null +++ b/obtheme.l @@ -0,0 +1,156 @@ +%{ +#include +#include +#include +#include +#include +#include "obtheme.h" +#include "obtheme.tab.h" + +int yylex(YYSTYPE *yylval, struct parser_control *pc); + +void obthemeerror(struct parser_control *pc, char *s) +{ + printf("Parse error in file %s on line %d\n%s" + , pc->currfile[pc->include_stack_ptr] + , pc->currline[pc->include_stack_ptr] + 1 + , pc->error_buf); +} + +extern int parserparse(void *); + +int yywrap(void) +{ + return 1; +} + +int obtheme_parse(struct obthemedata *td, const char *filename) +{ + FILE *input; + int ret; + struct parser_control *pc; +//illdebug = 1; + pc = parser_init(td); + input = fopen(filename, "r"); + if (!input) + return 2; + yyin = input; + yyrestart(input); + BEGIN 0; + pc->include_stack_ptr = 0; + pc->currline[pc->include_stack_ptr] = 0; + strncpy(pc->currfile[pc->include_stack_ptr], filename, 500); + ret = obthemeparse(pc); + if (ret != 0) { + //XXX I THINK I NEED TO CLOSE ALL INCLUDE FILES HERE + //probably also fclose input and call parser_finish? + return ret; + } + fclose(input); + parser_finish(pc); + return ret; +} + +%} +%x comment +%x incl +%% + +include BEGIN(incl); +[ \t]* /* eat the whitespace */ +[^ \t\n]+ { /* got the include file name */ + char *incfile; + if ( pc->include_stack_ptr >= MAX_INCLUDE_DEPTH) { + fprintf( stderr, "Includes nested too deeply" ); + exit(1); + } + + pc->include_stack[pc->include_stack_ptr++] = YY_CURRENT_BUFFER; + incfile = malloc(strlen(yytext) + strlen("include/")+ 1); + strcpy(incfile, "include/"); + strcat(incfile, yytext); + yyin = fopen( incfile, "r" ); + free(incfile); + strncpy(pc->currfile[pc->include_stack_ptr], yytext, 500); + pc->currline[pc->include_stack_ptr] = 0; + if ( ! yyin ) { + printf("Could not find include file %s (%s)\n", yytext, incfile); + exit(1); + } + yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); + + BEGIN(INITIAL); + } + +<> { + if ( --(pc->include_stack_ptr) < 0 ) + { + yy_delete_buffer(YY_CURRENT_BUFFER); + yyterminate(); + } + + else + { + yy_delete_buffer( YY_CURRENT_BUFFER ); + fclose(yyin); + yy_switch_to_buffer( + pc->include_stack[pc->include_stack_ptr] ); + } + } + + +"//"+[^\n]* ; +"/*" BEGIN(comment); +[^*\n]* ; +"*"+[^*/\n]* ; +"*"+"/" BEGIN(INITIAL); +\n LINE++; + +theme return THEME; +frame return FRAME; +decor return DECOR; +space return SPACE; +geometry return GEOMETRY; +material return MATERIAL; +gradient return GRADIENT; +context return CONTEXT; +cursor return CURSOR; +class return CLASS; +up return UP; +anchor return ANCHOR; +opacity return OPACITY; +shapeof return SHAPEOF; +texture return TEXTURE; + +0x[0-9A-Z]+ yylval->integer = strtol(yytext, (char **)NULL, 16); return NUMBER; +[0-9]+ yylval->integer = atoi(yytext); return NUMBER; +[a-zA-Z_][a-zA-Z0-9_]* yylval->string = g_strdup(yytext); return ID; +\".*\" { + yylval->string = g_strdup(yytext+1); + yylval->string[strlen(yylval->string)-1] = 0; + return STRING; + } +\`[^`]*\` { + yylval->string = g_strdup(yytext+1); + yylval->string[strlen(yylval->string)-1] = 0; + return STRING; + } + +\$[a-zA-Z_][a-zA-Z0-9_]* yylval->string = g_strdup(yytext+1); return ID; +\$[0-9]* yylval->integer = strtol(yytext + 1, (char **)NULL, 16); return SUBST; +\@ return AT; +: return COLON; +; return SEMICOLON; +"+" return PLUS; +"-" return MINUS; +"}" return RCB; +"{" return LCB; +")" return RB; +"(" return LB; +"<-" return LEFT_ARROW; +"->" return RIGHT_ARROW; +"<->" return DOUBLE_ARROW; +\n LINE++; /* zap EOL */ +[ \t]+ ; /* and whitespace */ +. return 0; +%% diff --git a/obtheme.y b/obtheme.y new file mode 100644 index 0000000..2146130 --- /dev/null +++ b/obtheme.y @@ -0,0 +1,206 @@ +%pure-parser +%name-prefix "obtheme" +%parse-param {struct parser_control *pc} +%{ +#include +#include +#include +#include +#include +#include +#include +#include +#include "obtheme.h" +#include "obtheme.tab.h" + +YY_DECL; + +struct parser_control *parser_init(struct obthemedata *otd) +{ + struct parser_control *out; + out = calloc(1, sizeof(struct parser_control)); + out->include_stack_ptr = 0; + out->target = otd; + return out; +} + +void parser_finish(struct parser_control *c) +{ + free(c); +} + +%} +%start theme_objects + +%union { + int integer; + float realnum; + char *string; + struct decor decor; + struct space space; + struct theme theme; + struct material material; + struct class class; + GSList *list; + GHashTable *hash; + struct vector vector; +} + +%token LCB RCB LB RB +%token LEFT_ARROW RIGHT_ARROW DOUBLE_ARROW +%token SEMICOLON AT COLON DEFAULT NOT +%token PLUS MINUS +%token STRING ID +%token NUMBER SUBST BULK BIG LITTLE +%token THEME FRAME SPACE GEOMETRY MATERIAL GRADIENT +%token CONTEXT CURSOR UP ANCHOR CLASS TEXTURE OPACITY +%token SHAPEOF DECOR +%type decor +%type decoritems classitem +%type space +%type class classitems +%type classes +%type material_props +%type opacity +%type spaceconstraints +%type up anchor +%% + +theme_object : material_decl + | theme + ; + +theme_objects : /* empty */ + | theme_objects theme_object + ; + +theme : THEME ID LCB classes RCB { + struct theme *out; + out = malloc(sizeof(struct theme)); + out->name = $2; + out->classes = $4; + g_hash_table_insert(pc->target->themes, $2, out); + } + ; + +opacity : OPACITY LB NUMBER RB { $$ = $3; } + ; + +material_props : /* empty */ { memset(&$$, 0, sizeof($$)); } + | material_props opacity { + $$ = $1; + $$.opacity = $2; + } + ; + +material_decl : MATERIAL ID LCB material_props RCB { + struct material *out; + out = malloc(sizeof(struct material)); + *out = $4; + g_hash_table_insert(pc->target->materials, $2, out); + } + ; + +anchor : ANCHOR LB NUMBER NUMBER NUMBER RB { + $$.x = $3; + $$.y = $4; + $$.z = $5; + } + ; + +up : UP LB NUMBER NUMBER NUMBER RB { + $$.x = $3; + $$.y = $4; + $$.z = $5; + } + ; + +spaceconstraints: /* empty */ { memset(&$$, 0, sizeof($$)); } + | spaceconstraints anchor { $1.anchor = $2; $$ = $1; } + | spaceconstraints up { $1.up = $2; $$ = $1; } + ; + +space : SPACE LCB spaceconstraints RCB { + $$ = $3; + } + ; + +shape : SHAPEOF LB ID RB + ; + +geometry_item : /* empty */ + | shape + ; + +geometry : GEOMETRY LCB geometry_item RCB + ; + +material_use : MATERIAL LB ID RB + ; + +classitem : decor + ; + +classitems : /* empty */ { $$.tree = NULL; $$.name = NULL; } + | classitems classitem { + struct decor *out = malloc(sizeof(struct decor)); + *out = $2; + $1.tree = g_slist_prepend($1.tree, out); + $$ = $1; + } + ; + +classes : /* empty */ { $$ = g_hash_table_new(g_str_hash, g_str_equal); } + | classes class { + struct class *out = malloc(sizeof(struct class)); + *out = $2; + $$ = $1; + g_hash_table_insert($1, out->name, out); + } + ; + +class : CLASS ID LCB classitems RCB { + $$ = $4; + $$.name = $2; + } + ; + +decoritems : /* empty */ { + memset(&$$, 0, sizeof($$)); + $$.space.up.y = -1; + } + | decoritems decor { + struct decor *out = malloc(sizeof(struct decor)); + *out = $2; + $$ = $1; + $$.children = g_slist_append($1.children, out); + } + | decoritems space { $1.space = $2; $$ = $1; } + | decoritems material_use + | decoritems geometry + | decoritems texture + | decoritems context + | decoritems gradient + | decoritems cursor + ; + + ; + +decor : DECOR ID LCB decoritems RCB { + $$ = $4; + $$.name = $2; + } + ; + +texture : TEXTURE LCB RCB + ; + +context : CONTEXT LB ID RB + ; + +cursor : CURSOR LB ID RB + +gradient : GRADIENT LB ID RB + ; + +%% diff --git a/theme.obtheme b/theme.obtheme new file mode 100644 index 0000000..8d574fa --- /dev/null +++ b/theme.obtheme @@ -0,0 +1,62 @@ +//#include materials.obtheme + +material flat { + opacity(1) +} + +theme awesome { + class regular_window { + decor clientwindow { + space { + anchor(10 9 8) + up(1 0 0) + } + geometry { + shapeof(client) + } + material(flat) + texture { //$CLIENT.contents + } + + decor titlebar { + context(OB_FRAME_CONTEXT_TITLEBAR) + geometry { + // box (0, 0, 0) to (100% of $CLIENT, 100%, 0) + } + material(flat) + gradient(split) +//texture { + decor title { + geometry { +// text(client.title) +// justify(center) + } + } + decor minbutton { + material(none) + context(OB_FRAME_CONTEXT_MINIMIZE) + } + decor maxbutton { + material(none) + context(OB_FRAME_CONTEXT_MAXIMIZE) + } + } + decor handle { + space { + anchor(0 0 0) + up(0 0 0) + } + decor leftgrip { + context(OB_FRAME_CONTEXT_BLCORNER) + cursor(SOUTHWEST) + } + decor rightgrip { + context(OB_FRAME_CONTEXT_BRCORNER) + cursor(SOUTHEAST) + } + context(OB_FRAME_CONTEXT_BOTTOM) + cursor(SOUTH) + } + } + } +}