80331e7950e41fc88ae50f3be543da614198dd4d
[manmower/obtheme.git] / obtheme.y
1 %pure-parser
2 %name-prefix "obtheme"
3 %parse-param {struct parser_control *pc}
4 %{
5 #include <assert.h>
6 #include <stdio.h>
7 #include <string.h>
8 #include <stdlib.h>
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #include <limits.h>
12 #include <unistd.h>
13 #include "frame.h"
14 #include "misc.h"
15 #include "render.h"
16 #include "obtheme.h"
17 #include "obtheme.tab.h"
18
19 YY_DECL;
20
21 struct context_table_item {
22         char *name;
23         ObFrameContext val;
24 };
25
26 /* some of these contexts don't make any sense for a theme... */
27 static struct context_table_item contexts[OB_FRAME_NUM_CONTEXTS] = {
28         {"none", OB_FRAME_CONTEXT_NONE},
29         {"desktop", OB_FRAME_CONTEXT_DESKTOP},
30         {"root", OB_FRAME_CONTEXT_ROOT},
31         {"client", OB_FRAME_CONTEXT_CLIENT},
32         {"titlebar", OB_FRAME_CONTEXT_TITLEBAR},
33         {"frame", OB_FRAME_CONTEXT_FRAME},
34         {"blcorner", OB_FRAME_CONTEXT_BLCORNER},
35         {"brcorner", OB_FRAME_CONTEXT_BRCORNER},
36         {"tlcorner", OB_FRAME_CONTEXT_TLCORNER},
37         {"trcorner", OB_FRAME_CONTEXT_TRCORNER},
38         {"top", OB_FRAME_CONTEXT_TOP},
39         {"bottom", OB_FRAME_CONTEXT_BOTTOM},
40         {"left", OB_FRAME_CONTEXT_LEFT},
41         {"right", OB_FRAME_CONTEXT_RIGHT},
42         {"maximize", OB_FRAME_CONTEXT_MAXIMIZE},
43         {"alldesktops", OB_FRAME_CONTEXT_ALLDESKTOPS},
44         {"shade", OB_FRAME_CONTEXT_SHADE},
45         {"iconify", OB_FRAME_CONTEXT_ICONIFY},
46         {"icon", OB_FRAME_CONTEXT_ICON},
47         {"close", OB_FRAME_CONTEXT_CLOSE},
48         {"moveresize", OB_FRAME_CONTEXT_MOVE_RESIZE}
49 };
50
51 static ObFrameContext context_from_string(char *str)
52 {
53         int i;
54         for (i = 0; i < OB_FRAME_NUM_CONTEXTS; i++)
55                 if (strcmp(contexts[i].name, str) == 1)
56                         return contexts[i].val;
57         return -1;
58 }
59
60 struct gradient_table_item {
61         char *name;
62         RrSurfaceColorType val;
63 };
64
65 struct gradient_table_item gradients[RR_SURFACE_NUM_TYPES] = {
66         {"none", RR_SURFACE_NONE},
67         {"parentrel", RR_SURFACE_PARENTREL},
68         {"solid", RR_SURFACE_SOLID},
69         {"split", RR_SURFACE_SPLIT_VERTICAL},
70         {"horizontal", RR_SURFACE_HORIZONTAL},
71         {"vertical", RR_SURFACE_VERTICAL},
72         {"diagonal", RR_SURFACE_DIAGONAL},
73         {"cross_diagonal", RR_SURFACE_CROSS_DIAGONAL},
74         {"pyramid", RR_SURFACE_PYRAMID},
75         {"mirror_horizontal", RR_SURFACE_MIRROR_HORIZONTAL},
76 };
77
78 static RrSurfaceColorType gradient_from_string(char *str)
79 {
80         int i;
81
82         for (i = 0; i < RR_SURFACE_NUM_TYPES; i++)
83                 if (strcmp(gradients[i].name, str) == 1)
84                         return gradients[i].val;
85
86         return -1;
87 }
88
89 struct parser_control *parser_init(struct obthemedata *otd)
90 {
91         struct parser_control *out;
92         out = calloc(1, sizeof(struct parser_control));
93         out->include_stack_ptr = 0;
94         out->target = otd;
95         return out;
96 }
97
98 void parser_finish(struct parser_control *c)
99 {
100         free(c);
101 }
102
103 struct expression *exdup(struct expression in)
104 {
105         struct expression *out;
106         out = malloc(sizeof(struct expression));
107         *out = in;
108         return out;
109 }
110
111 %}
112 %start theme_objects
113
114 %union {
115         int integer;
116         float realnum;
117         char *string;
118         struct decor decor;
119         struct space space;
120         struct theme theme;
121         struct material material;
122         struct style style;
123         GSList *list;
124         GHashTable *hash;
125         struct vector vector;
126         ObCursor dir;
127         ObFrameContext context;
128         RrSurfaceColorType gradient;
129         struct expression expr;
130         struct variable var;
131         struct texture tex;
132         struct material *matptr;
133         struct box box;
134         struct geometry geometry;
135 }
136
137 %token NORTH NORTHEAST EAST SOUTHEAST SOUTH SOUTHWEST
138 %token WEST NORTHWEST NONE UNCHANGED
139 %token LCB RCB LB RB TO
140 %token LEFT_ARROW RIGHT_ARROW DOUBLE_ARROW
141 %token SEMICOLON AT COLON DEFAULT NOT
142 %token PLUS MINUS STAR SLASH COMMA BOX
143 %token <string> STRING ID
144 %token <integer> NUMBER SUBST BULK BIG LITTLE
145 %token THEME FRAME SPACE GEOMETRY MATERIAL GRADIENT
146 %token CONTEXT CURSOR UP ANCHOR STYLE TEXTURE OPACITY
147 %token SHAPEOF DECOR DOT IMAGE
148 %type <decor> decor
149 %type <decor> decoritems styleitem
150 %type <space> space
151 %type <style> style styleitems
152 %type <hash> styles
153 %type <material> material_props
154 %type <realnum> opacity
155 %type <space> spaceconstraints
156 %type <vector> up anchor
157 %type <dir> cursor
158 %type <context> context
159 %type <gradient> gradient
160 %type <expr> expression
161 %type <var> variable
162 %type <tex> texture image texitems
163 %type <matptr> material_use
164 %type <box> box
165 %type <geometry> geometry geometry_item
166 %left PLUS MINUS
167 %left STAR SLASH
168 %left LB
169 %%
170
171 theme_object    : material_decl
172                 | theme
173                 ;
174
175 theme_objects   : /* empty */
176                 | theme_objects theme_object
177                 ;
178
179 theme           : THEME ID LCB styles RCB {
180                         struct theme *out;
181                         out = malloc(sizeof(struct theme));
182                         out->name = $2;
183                         out->styles = $4;
184                         g_hash_table_insert(pc->target->themes, $2, out);
185                 }
186                 ;
187
188 opacity         : OPACITY LB NUMBER RB { $$ = $3; }
189                 ;
190
191 material_props  : /* empty */ { memset(&$$, 0, sizeof($$)); }
192                 | material_props opacity { $$ = $1; $$.opacity = $2;}
193                 | material_props gradient
194                 ;
195
196 material_decl   : MATERIAL ID LCB material_props RCB {
197                         struct material *out;
198                         out = malloc(sizeof(struct material));
199                         *out = $4;
200                         g_hash_table_insert(pc->target->materials, $2, out);
201                 }
202                 ;
203
204 anchor          : ANCHOR LB expression COMMA expression COMMA expression RB {
205                         $$.x = $3;
206                         $$.y = $5;
207                         $$.z = $7;
208                 }
209                 ;
210
211 up              : UP LB expression COMMA expression COMMA expression RB {
212                         $$.x = $3;
213                         $$.y = $5;
214                         $$.z = $7;
215                 }
216                 ;
217
218 spaceconstraints: /* empty */ { memset(&$$, 0, sizeof($$));
219                         $$.anchor.x.op = OB_THEME_EQL;
220                         $$.anchor.x.v.number = 1;
221                         $$.anchor.y.op = OB_THEME_EQL;
222                         $$.anchor.y.v.number = 1;
223                         $$.anchor.z.op = OB_THEME_EQL;
224                         $$.anchor.z.v.number = 1;
225                         $$.up.x.op = OB_THEME_EQL;
226                         $$.up.x.v.number = 1;
227                         $$.up.y.op = OB_THEME_EQL;
228                         $$.up.y.v.number = 1;
229                         $$.up.z.op = OB_THEME_EQL;
230                         $$.up.z.v.number = 1;
231                 }
232                 | spaceconstraints anchor { $1.anchor = $2; $$ = $1; }
233                 | spaceconstraints up     { $1.up = $2; $$ = $1; }
234                 ;
235
236 space           : SPACE LCB spaceconstraints RCB {
237                         $$ = $3;
238                 }
239                 ;
240
241 shape           : SHAPEOF LB ID RB
242                 ;
243
244 box             : BOX LB expression COMMA expression COMMA expression RB TO
245                    LB expression COMMA expression COMMA expression RB {
246                         
247                 }
248                 ;
249
250 geometry_item   : /* empty */
251                 | shape
252                 | box { $$.box = $1; }
253                 ;
254
255 geometry        : GEOMETRY LCB geometry_item RCB {
256                         $$ = $3;
257                 }
258                 ;
259
260 material_use    : MATERIAL LB ID RB {
261                         $$ = g_hash_table_lookup(pc->target->materials, $3);
262                         if ($$ == NULL) {
263                                 snprintf(pc->error_buf, 4000, "No definition for material '%s'\n", $3);
264                                 obthemeerror(pc, pc->error_buf);
265                                 return 1;
266                         }
267                 }
268                 ;
269
270 styleitem       : decor
271                 ;
272
273 styleitems      : /* empty */ { $$.tree = NULL; $$.name = NULL; }
274                 | styleitems styleitem {
275                         struct decor *out = malloc(sizeof(struct decor));
276                         *out = $2;
277                         $1.tree = g_slist_prepend($1.tree, out);
278                         $$ = $1;
279                 }
280                 ;
281
282 styles          : /* empty */ { $$ = g_hash_table_new(g_str_hash, g_str_equal); }
283                 | styles style {
284                         struct style *out = malloc(sizeof(struct style));
285                         *out = $2;
286                         $$ = $1;
287                         g_hash_table_insert($1, out->name, out);
288                 }
289                 ;
290
291 style           : STYLE ID LCB styleitems RCB {
292                         $$ = $4;
293                         $$.name = $2;
294                 }
295                 ;
296
297 decoritems      : /* empty */ {
298                         memset(&$$, 0, sizeof($$));
299 //                      $$.space.up.y = -1;  XXX need a sane default!
300                         $$.cursor = OB_CURSOR_NONE;
301                         $$.space.anchor.x.op = OB_THEME_EQL;
302                         $$.space.anchor.x.v.number = 1;
303                         $$.space.anchor.y.op = OB_THEME_EQL;
304                         $$.space.anchor.y.v.number = 1;
305                         $$.space.anchor.z.op = OB_THEME_EQL;
306                         $$.space.anchor.z.v.number = 1;
307                         $$.space.up.x.op = OB_THEME_EQL;
308                         $$.space.up.x.v.number = 1;
309                         $$.space.up.y.op = OB_THEME_EQL;
310                         $$.space.up.y.v.number = 1;
311                         $$.space.up.z.op = OB_THEME_EQL;
312                         $$.space.up.z.v.number = 1;
313                         $$.texture.present = 0;
314                         $$.material = NULL;
315                 }
316                 | decoritems decor {
317                         struct decor *out = malloc(sizeof(struct decor));
318                         *out = $2;
319                         $$ = $1;
320                         $$.children = g_slist_append($1.children, out);
321                 }
322                 | decoritems space { $1.space = $2; $$ = $1; }
323                 | decoritems material_use { $1.material = $2; $$ = $1; }
324                 | decoritems geometry { $1.geometry = $2; $$ = $1;}
325                 | decoritems texture { $1.texture = $2; $$ = $1; } //XXX multitexture?
326                 | decoritems context { $1.context = $2; $$ = $1; }
327                 | decoritems cursor { $1.cursor = $2; $$ = $1; }
328                 ;
329
330                 ;
331
332 decor           : DECOR ID LCB decoritems RCB {
333                         $$ = $4;
334                         $$.name = $2;
335                 }
336                 ;
337
338 image           : IMAGE LB STRING RB {
339                         $$.present = 1;
340                         $$.internal = 0;
341                         $$.name = $3;
342                 }
343                 | IMAGE LB ID RB {
344                         $$.present = 1;
345                         $$.internal = 1;
346                         $$.name = $3;
347                 }
348                 ;
349
350 texitems        : image { $$ = $1; }
351                 ;
352
353 texture         : TEXTURE LCB texitems RCB { $$ = $3; }
354                 ;
355
356 context         : CONTEXT LB ID RB {
357                         ObFrameContext frc;
358                         frc = context_from_string($3);
359                         if (frc == -1) {
360                                 snprintf(pc->error_buf, 4000, "Illegal context '%s'\n", $3);
361                                 obthemeerror(pc, pc->error_buf);
362                                 return 1;
363                         }
364                 }
365                 ;
366
367 cursor          : CURSOR LB NORTH RB { $$ = OB_CURSOR_NORTH; }
368                 | CURSOR LB NORTHEAST RB { $$ = OB_CURSOR_NORTHEAST; }
369                 | CURSOR LB EAST RB { $$ = OB_CURSOR_EAST; }
370                 | CURSOR LB SOUTHEAST RB { $$ = OB_CURSOR_SOUTHEAST; }
371                 | CURSOR LB SOUTH RB { $$ = OB_CURSOR_SOUTH; }
372                 | CURSOR LB SOUTHWEST RB { $$ = OB_CURSOR_SOUTHWEST; }
373                 | CURSOR LB WEST RB { $$ = OB_CURSOR_WEST; }
374                 | CURSOR LB NORTHWEST RB { $$ = OB_CURSOR_NORTHWEST; }
375 //              | CURSOR LB NONE RB { $$ = OB_CURSOR_NORTHEAST; }
376                 | CURSOR LB UNCHANGED RB { $$ = OB_CURSOR_NONE; }
377                 ;
378 gradient        : GRADIENT LB ID RB {
379                         $$ = gradient_from_string($3);
380                         if ($$ == -1) {
381                                 snprintf(pc->error_buf, 4000, "No gradient named '%s'\n", $3);
382                                 obthemeerror(pc, pc->error_buf);
383                                 return 1;
384                         }
385                 }
386                 ;
387
388 variable        : ID DOT ID { $$.base = $1; $$.member = $3; }
389                 | ID        { $$.base = $1; $$.member = NULL; }
390                 | NUMBER    { $$.base = NULL; $$.number = $1; }
391                 ;
392
393 expression      : expression STAR expression {
394                         $$.op = OB_THEME_MUL;
395                         $$.a = exdup($1);
396                         $$.b = exdup($3);
397                 }
398                 | expression SLASH expression {
399                         $$.op = OB_THEME_DIV;
400                         $$.a = exdup($1);
401                         $$.b = exdup($3);
402                 }
403                 | expression PLUS expression {
404                         $$.op = OB_THEME_ADD;
405                         $$.a = exdup($1);
406                         $$.b = exdup($3);
407                 }
408                 | expression MINUS expression {
409                         $$.op = OB_THEME_SUB;
410                         $$.a = exdup($1);
411                         $$.b = exdup($3);
412                 }
413                 | variable {
414                         $$.op = OB_THEME_EQL;
415                         $$.v = $1;
416                 }
417                 | LB expression RB { $$ = $2; }
418                 ;
419
420 %%