1 /*
2 * rofi
3 *
4 * MIT/X11 License
5 * Copyright 2013-2017 Qball Cow <qball@gmpclient.org>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sublicense, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 */
27
28 %define api.pure
29 %define parse.error verbose
30 %locations
31 %glr-parser
32 %skeleton "glr.c"
33 %debug
34 %parse-param {const char *what}
35 %code requires {
36 #include "theme.h"
37 #include "xrmoptions.h"
38 #include "css-colors.h"
39
40 typedef struct YYLTYPE {
41 int first_line;
42 int first_column;
43 int last_line;
44 int last_column;
45 char *filename;
46 } YYLTYPE;
47 # define YYLTYPE_IS_DECLARED 1 /* alert the parser that we have our own definition */
48
49 # define YYLLOC_DEFAULT(Current, Rhs, N) \
50 do \
51 if (N) \
52 { \
53 (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
54 (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
55 (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
56 (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
57 (Current).filename = YYRHSLOC (Rhs, 1).filename; \
58 } \
59 else \
60 { /* empty RHS */ \
61 (Current).first_line = (Current).last_line = \
62 YYRHSLOC (Rhs, 0).last_line; \
63 (Current).first_column = (Current).last_column = \
64 YYRHSLOC (Rhs, 0).last_column; \
65 (Current).filename = NULL; /* new */ \
66 } \
67 while (0)
68 }
69 %{
70 #include <stdio.h>
71 #include <stdlib.h>
72 #include <glib.h>
73
74 #include "theme-parser.h"
75 ThemeWidget *rofi_theme = NULL;
76 void yyerror(YYLTYPE *yylloc, const char *what, const char* s);
77 int yylex (YYSTYPE *, YYLTYPE *);
78
79
check_in_range(double index,double low,double high,YYLTYPE * loc)80 static int check_in_range ( double index, double low, double high, YYLTYPE *loc )
81 {
82 if ( index > high || index < low ){
83 gchar *str = g_strdup_printf("Value out of range: \n\t\tValue: X = %.2lf;\n\t\tRange: %.2lf <= X <= %.2lf.", index, low, high );
84 yyerror ( loc, loc->filename, str);
85 g_free(str);
86 return FALSE;
87 }
88
89 return TRUE;
90 }
91
hue2rgb(double p,double q,double t)92 static double hue2rgb(double p, double q, double t){
93 t += (t<0)?1.0:0.0;
94 t -= (t>1)?1.0:0.0;
95 if( t < (1/6.0) ) {
96 return p + (q - p) * 6 * t;
97 }
98 if( t < (1/2.0) ) {
99 return q;
100 }
101 if( t < (2/3.0) ) {
102 return p + (q - p) * (2/3.0 - t) * 6;
103 }
104 return p;
105 }
hsl_to_rgb(double h,double s,double l)106 static ThemeColor hsl_to_rgb ( double h, double s, double l )
107 {
108 ThemeColor colour;
109 colour.alpha = 1.0;
110
111 if(s < 0.001 && s > -0.001){
112 colour.red = colour.green = colour.blue = l; // achromatic
113 }else{
114
115 double q = l < 0.5 ? l * (1 + s) : l + s - l * s;
116 double p = 2 * l - q;
117 colour.red = hue2rgb(p, q, h + 1/3.0);
118 colour.green = hue2rgb(p, q, h);
119 colour.blue = hue2rgb(p, q, h - 1/3.0);
120 }
121
122 return colour;
123 }
hwb_to_rgb(double h,double w,double b)124 static ThemeColor hwb_to_rgb ( double h, double w, double b)
125 {
126 ThemeColor retv = hsl_to_rgb ( h, 1.0, 0.5);
127 retv.red *= ( 1. - w - b );
128 retv.red += w;
129 retv.green *= ( 1. - w - b );
130 retv.green += w;
131 retv.blue *= ( 1. - w - b );
132 retv.blue += w;
133 return retv;
134 }
135 %}
136
137 %union {
138 int ival;
139 double fval;
140 char *sval;
141 char cval;
142 int bval;
143 WindowLocation wloc;
144 ThemeColor colorval;
145 ThemeWidget *theme;
146 GList *list;
147 Property *property;
148 GHashTable *property_list;
149 RofiDistance distance;
150 RofiDistanceUnit *distance_unit;
151 }
152
153 %token <ival> T_END 0 "end of file"
154 %token <ival> T_ERROR 1 "error from file parser"
155 %token <ival> T_ERROR_PROPERTY 2 "invalid property value"
156 %token <ival> T_ERROR_SECTION 3 "invalid property name"
157 %token <ival> T_ERROR_NAMESTRING 4 "invalid element name"
158 %token <ival> T_ERROR_DEFAULTS 5 "invalid defaults name"
159 %token <ival> T_ERROR_INCLUDE 6 "invalid import value"
160 %token <ival> T_ERROR_ARGB_SPEC 7 "invalid argb color. Requires 8 (not 7) elements: argb:AARRGGBB."
161 %token <ival> T_INT "Integer number"
162 %token <fval> T_DOUBLE "Floating-point number"
163 %token <sval> T_STRING "UTF-8 encoded string"
164 %token <cval> T_CHAR "Character"
165 %token <sval> T_PROP_NAME "property name"
166 %token <colorval> T_COLOR_NAME "Color value by name"
167 %token <sval> T_NAME_ELEMENT "Element name"
168 %token <bval> T_BOOLEAN "Boolean value (true or false)"
169 %token <colorval> T_COLOR "Hexidecimal color value"
170 %token <sval> T_LINK "Reference"
171 %token <sval> T_ELEMENT "Name of element"
172 %token T_POS_CENTER "Center"
173 %token T_POS_EAST "East"
174 %token T_POS_WEST "West"
175 %token T_POS_NORTH "North"
176 %token T_POS_SOUTH "South"
177
178 %token T_MEDIA "@media"
179
180 %token T_NONE "None"
181 %token T_BOLD "Bold"
182 %token T_ITALIC "Italic"
183 %token T_UNDERLINE "Underline"
184 %token T_STRIKETHROUGH "Strikethrough"
185 %token T_SMALLCAPS "Small CAPS"
186 %token T_DASH "Dash"
187 %token T_SOLID "Solid"
188
189 %token T_UNIT_PX "pixels"
190 %token T_UNIT_MM "mm"
191 %token T_UNIT_EM "em"
192 %token T_UNIT_CH "ch"
193 %token T_UNIT_PERCENT "%"
194
195 %token T_ANGLE_DEG "Degrees"
196 %token T_ANGLE_GRAD "Gradians"
197 %token T_ANGLE_RAD "Radians"
198 %token T_ANGLE_TURN "Turns"
199
200 %token ORIENTATION_HORI "Horizontal"
201 %token ORIENTATION_VERT "Vertical"
202
203 %token T_COL_RGBA "rgb[a] colorscheme"
204 %token T_COL_HSL "hsl colorscheme"
205 %token T_COL_HWB "hwb colorscheme"
206 %token T_COL_CMYK "cmyk colorscheme"
207
208 %token T_PARENT_LEFT "Parent left ('(')"
209 %token T_PARENT_RIGHT "Parent right (')')"
210 %token T_COMMA "comma separator (',')"
211 %token T_OPTIONAL_COMMA "Optional comma separator (',')"
212 %token T_FORWARD_SLASH "forward slash ('/')"
213 %token T_PERCENT "Percent sign ('%')"
214 %token T_LIST_OPEN "List open ('[')"
215 %token T_LIST_CLOSE "List close (']')"
216
217 %token T_MODIFIER_ADD "Add ('+')"
218 %token T_MODIFIER_SUBTRACT "Subtract ('-')"
219 %token T_MODIFIER_MULTIPLY "Multiply ('*')"
220
221 %token T_MODIFIER_MAX "Max ('max')"
222 %token T_MODIFIER_MIN "Min ('min')"
223
224 %token T_CALC "calc"
225
226 %token T_BOPEN "bracket open ('{')"
227 %token T_BCLOSE "bracket close ('}')"
228 %token T_PSEP "property separator (':')"
229 %token T_PCLOSE "property close (';')"
230 %token T_NSEP "Name separator (' ' or '.')"
231 %token T_SSEP "Selector separator (',')"
232 %token T_NAME_PREFIX "Element section ('# {name} { ... }')"
233 %token T_WHITESPACE "White space"
234 %token T_PDEFAULTS "Default settings section ( '* { ... }')"
235 %token T_CONFIGURATION "Configuration block"
236
237 %token T_COLOR_TRANSPARENT "Transparent"
238
239 %token T_INHERIT "Inherit"
240
241 %token T_MEDIA_WIDTH "Width"
242 %token T_MEDIA_HEIGHT "Height"
243
244 %token T_MEDIA_MIN "Min"
245 %token T_MEDIA_MONITOR_ID "Monitor-ID"
246 %token T_MEDIA_MAX "Max"
247 %token T_MEDIA_SEP "-"
248
249 %type <theme> t_entry_list
250 %type <list> t_entry_name_path
251 %type <list> t_entry_name_path_selectors
252 %type <property> t_property
253 %type <property> t_property_element
254 %type <property_list> t_property_list
255 %type <property_list> t_property_list_optional
256 %type <colorval> t_property_color
257 %type <fval> t_property_color_value
258 %type <fval> t_property_color_opt_alpha_c
259 %type <fval> t_property_color_opt_alpha_ws
260 %type <fval> t_property_color_value_unit
261 %type <fval> t_property_color_value_angle
262 %type <sval> t_property_name
263 %type <distance> t_property_distance
264 %type <distance> t_property_distance_zero
265 %type <distance_unit> t_property_distance_unit_math
266 %type <distance_unit> t_property_distance_unit_math2
267 %type <distance_unit> t_property_distance_unit_math3
268 %type <distance_unit> t_property_distance_unit
269 %type <ival> t_property_unit
270 %type <wloc> t_property_position
271 %type <wloc> t_property_position_ew
272 %type <wloc> t_property_position_sn
273 %type <ival> t_property_highlight_styles
274 %type <ival> t_property_highlight_style
275 %type <ival> t_property_line_style
276 %type <list> t_property_element_list
277 %type <list> t_property_element_list_optional
278 %type <ival> t_property_orientation
279 %type <ival> t_name_prefix_optional
280 %start t_main
281
282 %%
283
284 /**
285 * First have the configuration blocks, then the theme.
286 */
287 t_main
288 : t_configuration_list t_entry_list {
289 // Dummy at this point.
290 if (rofi_theme == NULL ){
291 rofi_theme_reset();
292 }
293
294
295 rofi_theme_widget_add_properties ( rofi_theme, $2->properties );
296 for ( unsigned int i = 0; i < $2->num_widgets;i++) {
297 ThemeWidget *d = $2->widgets[i];
298 rofi_theme_parse_merge_widgets(rofi_theme, d);
299 }
300 }
301 ;
302
303 t_configuration_list:
304 %empty {}
305 | t_configuration_list T_CONFIGURATION T_BOPEN t_config_property_list_optional T_BCLOSE {};
306
307
308 /**
309 * Small dummy object to make the prefix optional.
310 */
311 t_name_prefix_optional
312 : T_NAME_PREFIX {}
313 | %empty {}
314 ;
315
316 t_entry_list:
317 %empty {
318 $$ = g_slice_new0 ( ThemeWidget );
319 }
320 | t_entry_list t_name_prefix_optional t_entry_name_path_selectors T_BOPEN t_property_list_optional T_BCLOSE
321 {
322 for ( GList *liter = g_list_first ( $3); liter; liter = g_list_next ( liter ) ) {
323 ThemeWidget *widget = $1;
324 for ( GList *iter = g_list_first ( (GList*)liter->data ); widget && iter ; iter = g_list_next ( iter ) ) {
325 widget = rofi_theme_find_or_create_name ( widget, iter->data );
326 }
327 g_list_free_full ( (GList*)liter->data, g_free );
328 widget->set = TRUE;
329 rofi_theme_widget_add_properties ( widget, $5);
330 }
331 if ( $5 ) {
332 g_hash_table_destroy ( $5 );
333 }
334 g_list_free ( $3 );
335 }
336 | t_entry_list T_PDEFAULTS T_BOPEN t_property_list_optional T_BCLOSE {
337 rofi_theme_widget_add_properties ( $1, $4);
338 if ( $4 ) {
339 g_hash_table_destroy ( $4 );
340 }
341 }
342 | t_entry_list T_MEDIA T_PARENT_LEFT T_STRING T_PSEP T_INT T_PARENT_RIGHT T_BOPEN t_entry_list T_BCLOSE {
343 gchar *name = g_strdup_printf("@media ( %s: %d )",$4, $6);
344 ThemeWidget *widget = rofi_theme_find_or_create_name ( $1, name );
345 widget->set = TRUE;
346 widget->media = g_slice_new0(ThemeMedia);
347 widget->media->type = rofi_theme_parse_media_type ( $4 );
348 widget->media->value = (double)$6;
349 for ( unsigned int i = 0; i < $9->num_widgets;i++) {
350 ThemeWidget *d = $9->widgets[i];
351 rofi_theme_parse_merge_widgets(widget, d);
352 }
353 g_free ( name );
354 }
355 | t_entry_list T_MEDIA T_PARENT_LEFT T_STRING T_PSEP T_DOUBLE T_PARENT_RIGHT T_BOPEN t_entry_list T_BCLOSE {
356 gchar *name = g_strdup_printf("@media ( %s: %f )",$4, $6);
357 ThemeWidget *widget = rofi_theme_find_or_create_name ( $1, name );
358 widget->set = TRUE;
359 widget->media = g_slice_new0(ThemeMedia);
360 widget->media->type = rofi_theme_parse_media_type ( $4 );
361 widget->media->value = $6;
362 for ( unsigned int i = 0; i < $9->num_widgets;i++) {
363 ThemeWidget *d = $9->widgets[i];
364 rofi_theme_parse_merge_widgets(widget, d);
365 }
366 g_free ( name );
367 }
368 | t_entry_list T_MEDIA T_PARENT_LEFT T_STRING T_PSEP T_INT T_UNIT_PX T_PARENT_RIGHT T_BOPEN t_entry_list T_BCLOSE {
369 gchar *name = g_strdup_printf("@media ( %s: %d px )",$4, $6);
370 ThemeWidget *widget = rofi_theme_find_or_create_name ( $1, name );
371 widget->set = TRUE;
372 widget->media = g_slice_new0(ThemeMedia);
373 widget->media->type = rofi_theme_parse_media_type ( $4 );
374 widget->media->value = (double)$6;
375 for ( unsigned int i = 0; i < $10->num_widgets;i++) {
376 ThemeWidget *d = $10->widgets[i];
377 rofi_theme_parse_merge_widgets(widget, d);
378 }
379 g_free ( name );
380 }
381 ;
382
383 t_config_property_list_optional
384 : %empty {}
385 | t_config_property_list
386 ;
387
388 t_config_property_list
389 : t_config_property {
390 }
391 | t_config_property_list t_config_property {
392 };
393
394 t_config_property
395 : t_property {
396 char *error = NULL;
397 if ( config_parse_set_property ( $1, &error ) ) {
398 // TODO Generate error.
399 #ifdef FATAL_CONFIG_ERROR
400 yyerror ( &(@$), @$.filename, error );
401 #else
402 g_warning("%s:%d:%d: %s\n", @$.filename, @$.first_line, @$.first_column, error);
403 #endif
404 g_free(error);
405 }
406 // We don't keep any reference to this after this point, so the property can be free'ed.
407 rofi_theme_property_free ( $1 );
408 }
409
410 /**
411 * properties
412 */
413 t_property_list_optional
414 : %empty { $$ = NULL; }
415 | t_property_list { $$ = $1; }
416 ;
417
418 t_property_list:
419 t_property {
420 $$ = g_hash_table_new_full ( g_str_hash, g_str_equal, NULL, (GDestroyNotify)rofi_theme_property_free );
421 g_hash_table_replace ( $$, $1->name, $1 );
422 }
423 | t_property_list t_property {
424 // Old will be free'ed, and key/value will be replaced.
425 g_hash_table_replace ( $$, $2->name, $2 );
426 }
427 ;
428
429 t_property
430 : t_property_name T_PSEP t_property_element T_PCLOSE {
431 $$ = $3;
432 $$->name = $1;
433 }
434 | t_property_name T_PSEP T_PARENT_LEFT T_ELEMENT T_PARENT_RIGHT T_PCLOSE{
435 $$ = rofi_theme_property_create ( P_LINK );
436 $$->name = $1;
437 $$->value.link.name = $4;
438 }
439 | t_property_name T_PSEP T_PARENT_LEFT T_ELEMENT T_COMMA t_property_element T_PARENT_RIGHT T_PCLOSE{
440 $$ = rofi_theme_property_create ( P_LINK );
441 $$->name = $1;
442 $$->value.link.name = $4;
443 $$->value.link.def_value = $6;
444 }
445
446 t_property_element
447 : T_INHERIT {
448 $$ = rofi_theme_property_create ( P_INHERIT );
449 }
450 | T_INT {
451 $$ = rofi_theme_property_create ( P_INTEGER );
452 $$->value.i = $1;
453 }
454 | T_DOUBLE {
455 $$ = rofi_theme_property_create ( P_DOUBLE );
456 $$->value.f = $1;
457 }
458 | T_STRING {
459 $$ = rofi_theme_property_create ( P_STRING );
460 $$->value.s = $1;
461 }
462 | T_CHAR {
463 $$ = rofi_theme_property_create ( P_CHAR );
464 $$->value.c = $1;
465 }
466 | T_LINK {
467 $$ = rofi_theme_property_create ( P_LINK );
468 $$->value.link.name = $1;
469 }
470 | T_BOOLEAN {
471 $$ = rofi_theme_property_create ( P_BOOLEAN );
472 $$->value.b = $1;
473 }
474 | t_property_distance {
475 $$ = rofi_theme_property_create ( P_PADDING );
476 $$->value.padding = (RofiPadding){ $1, rofi_theme_property_copy_distance($1), rofi_theme_property_copy_distance($1), rofi_theme_property_copy_distance($1) };
477 }
478 | t_property_distance_zero t_property_distance_zero {
479 $$ = rofi_theme_property_create ( P_PADDING );
480 $$->value.padding = (RofiPadding){ $1, $2, rofi_theme_property_copy_distance($1), rofi_theme_property_copy_distance($2) };
481 }
482 | t_property_distance_zero t_property_distance_zero t_property_distance_zero {
483 $$ = rofi_theme_property_create ( P_PADDING );
484 $$->value.padding = (RofiPadding){ $1, $2, $3, rofi_theme_property_copy_distance($2) };
485 }
486 | t_property_distance_zero t_property_distance_zero t_property_distance_zero t_property_distance_zero {
487 $$ = rofi_theme_property_create ( P_PADDING );
488 $$->value.padding = (RofiPadding){ $1, $2, $3, $4 };
489 }
490 | t_property_position {
491 $$ = rofi_theme_property_create ( P_POSITION );
492 $$->value.i = $1;
493 }
494 | t_property_highlight_styles t_property_color {
495 $$ = rofi_theme_property_create ( P_HIGHLIGHT );
496 $$->value.highlight.style = $1|ROFI_HL_COLOR;
497 $$->value.highlight.color = $2;
498 }
499 | t_property_highlight_styles {
500 $$ = rofi_theme_property_create ( P_HIGHLIGHT );
501 $$->value.highlight.style = $1;
502 }
503 | t_property_color {
504 $$ = rofi_theme_property_create ( P_COLOR );
505 $$->value.color = $1;
506 }
507 | T_LIST_OPEN t_property_element_list_optional T_LIST_CLOSE {
508 $$ = rofi_theme_property_create ( P_LIST );
509 $$->value.list = $2;
510 }
511 | t_property_orientation {
512 $$ = rofi_theme_property_create ( P_ORIENTATION );
513 $$->value.i = $1;
514 }
515 ;
516
517 /** List of elements */
518 t_property_element_list_optional
519 : %empty { $$ = NULL; }
520 | t_property_element_list { $$ = $1; }
521 ;
522
523 t_property_element_list
524 : T_ELEMENT { $$ = g_list_append ( NULL, $1); }
525 | t_property_element_list T_COMMA T_ELEMENT {
526 $$ = g_list_append ( $1, $3 );
527 }
528 ;
529
530 /**
531 * Position can be either center,
532 * East or West, North Or South
533 * Or combi of East or West and North or South
534 */
535 t_property_position
536 : T_POS_CENTER { $$ =WL_CENTER;}
537 | t_property_position_ew
538 | t_property_position_sn
539 | t_property_position_ew t_property_position_sn { $$ = $1|$2;}
540 | t_property_position_sn t_property_position_ew { $$ = $1|$2;}
541 ;
542 t_property_position_ew
543 : T_POS_EAST { $$ = WL_EAST;}
544 | T_POS_WEST { $$ = WL_WEST;}
545 ;
546 t_property_position_sn
547 : T_POS_NORTH { $$ = WL_NORTH;}
548 | T_POS_SOUTH { $$ = WL_SOUTH;}
549 ;
550
551 /**
552 * Highlight style, allow mulitple styles to be combined.
553 * Empty not allowed
554 */
555 t_property_highlight_styles
556 : t_property_highlight_style { $$ = $1;}
557 | t_property_highlight_styles t_property_highlight_style { $$ = $1|$2;}
558 ;
559 /** Single style. */
560 t_property_highlight_style
561 : T_NONE { $$ = ROFI_HL_NONE; }
562 | T_BOLD { $$ = ROFI_HL_BOLD; }
563 | T_UNDERLINE { $$ = ROFI_HL_UNDERLINE; }
564 | T_STRIKETHROUGH { $$ = ROFI_HL_STRIKETHROUGH; }
565 | T_ITALIC { $$ = ROFI_HL_ITALIC; }
566 | T_SMALLCAPS { $$ = ROFI_HL_SMALL_CAPS; }
567 ;
568
569
570 t_property_distance_zero
571 : T_INT t_property_line_style {
572 $$.base.distance = (double) $1;
573 $$.base.type = ROFI_PU_PX;
574 $$.base.left = NULL;
575 $$.base.right = NULL;
576 $$.base.modtype = ROFI_DISTANCE_MODIFIER_NONE;
577 $$.style = $2;
578 }
579 | t_property_distance { $$ = $1;}
580 ;
581
582 /** Distance. */
583 t_property_distance_unit
584 : T_INT t_property_unit {
585 $$ = g_slice_new0(RofiDistanceUnit);
586 $$->distance = (double)$1;
587 $$->type = $2;
588 $$->left = NULL;
589 $$->right = NULL;
590 $$->modtype = ROFI_DISTANCE_MODIFIER_NONE;
591 }
592 | T_INT {
593 $$ = g_slice_new0(RofiDistanceUnit);
594 $$->distance = (double)$1;
595 $$->type = ROFI_PU_PX;
596 $$->left = NULL;
597 $$->right = NULL;
598 $$->modtype = ROFI_DISTANCE_MODIFIER_NONE;
599 }
600 | T_DOUBLE t_property_unit {
601 $$ = g_slice_new0(RofiDistanceUnit);
602 $$->distance = (double)$1;
603 $$->type = $2;
604 $$->left = NULL;
605 $$->right = NULL;
606 $$->modtype = ROFI_DISTANCE_MODIFIER_NONE;
607 }
608 | T_PARENT_LEFT t_property_distance_unit_math3 T_PARENT_RIGHT {
609 $$ = g_slice_new0(RofiDistanceUnit);
610 $$->distance = 0;
611 $$->type = ROFI_PU_PX;
612 $$->left = $2;
613 $$->right = 0;
614 $$->modtype = ROFI_DISTANCE_MODIFIER_GROUP;
615 };
616
617
618 /**
619 * Multiply/divide with auto-grouping.
620 */
621 t_property_distance_unit_math
622 : t_property_distance_unit_math T_MODIFIER_MULTIPLY t_property_distance_unit {
623 $$ = g_slice_new0(RofiDistanceUnit);
624 $$->left = $1;
625 $$->right = $3;
626 $$->modtype = ROFI_DISTANCE_MODIFIER_MULTIPLY;
627 }
628 | t_property_distance_unit_math T_FORWARD_SLASH t_property_distance_unit {
629 $$ = g_slice_new0(RofiDistanceUnit);
630 $$->left = $1;
631 $$->right = $3;
632 $$->modtype = ROFI_DISTANCE_MODIFIER_DIVIDE;
633 }
634 | t_property_distance_unit_math T_PERCENT t_property_distance_unit {
635 $$ = g_slice_new0(RofiDistanceUnit);
636 $$->left = $1;
637 $$->right = $3;
638 $$->modtype = ROFI_DISTANCE_MODIFIER_MODULO;
639 }
640 | t_property_distance_unit {
641 $$ = $1;
642 };
643
644
645 /** Level 2 (+-)*/
646 t_property_distance_unit_math2
647 : t_property_distance_unit_math2 T_MODIFIER_ADD t_property_distance_unit_math {
648 $$ = g_slice_new0(RofiDistanceUnit);
649 $$->left = $1;
650 $$->right = $3;
651 $$->modtype = ROFI_DISTANCE_MODIFIER_ADD;
652 }
653 | t_property_distance_unit_math2 T_MODIFIER_SUBTRACT t_property_distance_unit_math {
654 $$ = g_slice_new0(RofiDistanceUnit);
655 $$->left = $1;
656 $$->right = $3;
657 $$->modtype = ROFI_DISTANCE_MODIFIER_SUBTRACT;
658 }
659 | t_property_distance_unit_math {
660 $$ = $1;
661 };
662 /** Level 3 (min max)*/
663 t_property_distance_unit_math3
664 : t_property_distance_unit_math3 T_MODIFIER_MIN t_property_distance_unit_math2 {
665 $$ = g_slice_new0(RofiDistanceUnit);
666 $$->left = $1;
667 $$->right = $3;
668 $$->modtype = ROFI_DISTANCE_MODIFIER_MIN;
669 }
670 | t_property_distance_unit_math3 T_MODIFIER_MAX t_property_distance_unit_math2 {
671 $$ = g_slice_new0(RofiDistanceUnit);
672 $$->left = $1;
673 $$->right = $3;
674 $$->modtype = ROFI_DISTANCE_MODIFIER_MAX;
675 }
676 | t_property_distance_unit_math2 {
677 $$ = $1;
678 };
679
680
681 t_property_distance
682 /** Integer unit and line style */
683 : T_INT t_property_unit t_property_line_style {
684 $$.base.distance = (double)$1;
685 $$.base.type = $2;
686 $$.base.left = NULL;
687 $$.base.right = NULL;
688 $$.base.modtype = ROFI_DISTANCE_MODIFIER_NONE;
689 $$.style = $3;
690 }
691 /** Double unit and line style */
692 | T_DOUBLE t_property_unit t_property_line_style {
693 $$.base.distance = (double)$1;
694 $$.base.type = $2;
695 $$.base.modtype = ROFI_DISTANCE_MODIFIER_NONE;
696 $$.base.left = NULL;
697 $$.base.right = NULL;
698 $$.style = $3;
699 }
700 | T_CALC T_PARENT_LEFT t_property_distance_unit_math3 T_PARENT_RIGHT t_property_line_style {
701 $$.base.distance = 0;
702 $$.base.type = ROFI_PU_PX;
703 $$.base.left = $3;
704 $$.base.right = NULL;
705 $$.base.modtype = ROFI_DISTANCE_MODIFIER_GROUP;
706 $$.style = $5;
707 };
708
709 /** distance unit. px, em, % */
710 t_property_unit
711 : T_UNIT_PX { $$ = ROFI_PU_PX; }
712 | T_UNIT_MM { $$ = ROFI_PU_MM; }
713 | T_UNIT_EM { $$ = ROFI_PU_EM; }
714 | T_UNIT_CH { $$ = ROFI_PU_CH; }
715 | T_PERCENT { $$ = ROFI_PU_PERCENT; }
716 ;
717 /******
718 * Line style
719 * If not set, solid.
720 */
721 t_property_line_style
722 : %empty { $$ = ROFI_HL_SOLID; }
723 | T_SOLID { $$ = ROFI_HL_SOLID; }
724 | T_DASH { $$ = ROFI_HL_DASH; }
725 ;
726
727 /**
728 * Color formats
729 */
730 t_property_color
731 /** rgba ( 0-255 , 0-255, 0-255, 0-1.0 ) */
732 : T_COL_RGBA T_PARENT_LEFT T_INT T_COMMA T_INT T_COMMA T_INT t_property_color_opt_alpha_c T_PARENT_RIGHT {
733 if ( ! check_in_range($3,0,255, &(@$)) ) { YYABORT; }
734 if ( ! check_in_range($5,0,255, &(@$)) ) { YYABORT; }
735 if ( ! check_in_range($7,0,255, &(@$)) ) { YYABORT; }
736 $$.alpha = $8;
737 $$.red = $3/255.0;
738 $$.green = $5/255.0;
739 $$.blue = $7/255.0;
740 }
741 /** rgba ( 0-255 0-255 0-255 / 0-1.0 ) */
742 | T_COL_RGBA T_PARENT_LEFT T_INT T_INT T_INT t_property_color_opt_alpha_ws T_PARENT_RIGHT {
743 if ( ! check_in_range($3,0,255, &(@$)) ) { YYABORT; }
744 if ( ! check_in_range($4,0,255, &(@$)) ) { YYABORT; }
745 if ( ! check_in_range($5,0,255, &(@$)) ) { YYABORT; }
746 $$.alpha = $6;
747 $$.red = $3/255.0;
748 $$.green = $4/255.0;
749 $$.blue = $5/255.0;
750 }
751 /** rgba ( 0-100% , 0-100%, 0-100%, 0-1.0 ) */
752 | T_COL_RGBA T_PARENT_LEFT t_property_color_value T_PERCENT T_COMMA t_property_color_value T_PERCENT T_COMMA t_property_color_value T_PERCENT t_property_color_opt_alpha_c T_PARENT_RIGHT {
753 if ( ! check_in_range($3,0,100, &(@$)) ) { YYABORT; }
754 if ( ! check_in_range($6,0,100, &(@$)) ) { YYABORT; }
755 if ( ! check_in_range($9,0,100, &(@$)) ) { YYABORT; }
756 $$.alpha = $11; $$.red = $3/100.0; $$.green = $6/100.0; $$.blue = $9/100.0;
757 }
758 /** rgba ( 0-100% 0-100% 0-100% / 0-1.0 ) */
759 | T_COL_RGBA T_PARENT_LEFT t_property_color_value T_PERCENT t_property_color_value T_PERCENT t_property_color_value T_PERCENT t_property_color_opt_alpha_ws T_PARENT_RIGHT {
760 if ( ! check_in_range($3,0,100, &(@$)) ) { YYABORT; }
761 if ( ! check_in_range($5,0,100, &(@$)) ) { YYABORT; }
762 if ( ! check_in_range($7,0,100, &(@$)) ) { YYABORT; }
763 $$.alpha = $9; $$.red = $3/100.0; $$.green = $5/100.0; $$.blue = $7/100.0;
764 }
765 /** hwb with comma */
766 | T_COL_HWB T_PARENT_LEFT t_property_color_value_angle T_COMMA t_property_color_value_unit T_COMMA t_property_color_value_unit t_property_color_opt_alpha_c T_PARENT_RIGHT {
767 double h = $3, w = $5, b = $7;
768 $$ = hwb_to_rgb ( h, w, b );
769 $$.alpha = $8;
770 }
771 /** hwb whitespace */
772 | T_COL_HWB T_PARENT_LEFT t_property_color_value_angle t_property_color_value_unit t_property_color_value_unit t_property_color_opt_alpha_ws T_PARENT_RIGHT {
773 double h = $3, w = $4, b = $5;
774 $$ = hwb_to_rgb ( h, w, b );
775 $$.alpha = $6;
776 }
777 /** cmyk with comma */
778 | T_COL_CMYK T_PARENT_LEFT t_property_color_value_unit T_COMMA t_property_color_value_unit T_COMMA t_property_color_value_unit T_COMMA t_property_color_value_unit t_property_color_opt_alpha_c T_PARENT_RIGHT {
779 $$.alpha = $10;
780 double c= $3, m= $5, y= $7, k= $9;
781 $$.red = (1.0-c)*(1.0-k);
782 $$.green = (1.0-m)*(1.0-k);
783 $$.blue = (1.0-y)*(1.0-k);
784 }
785 /** cmyk whitespace edition. */
786 | T_COL_CMYK T_PARENT_LEFT t_property_color_value_unit t_property_color_value_unit t_property_color_value_unit t_property_color_value_unit t_property_color_opt_alpha_ws T_PARENT_RIGHT {
787 $$.alpha = $7;
788 double c= $3, m= $4, y= $5, k= $6;
789 $$.red = (1.0-c)*(1.0-k);
790 $$.green = (1.0-m)*(1.0-k);
791 $$.blue = (1.0-y)*(1.0-k);
792 }
793 /** hsl ( 0-360 0-100 % 0 - 100 % / alpha) */
794 | T_COL_HSL T_PARENT_LEFT t_property_color_value_angle t_property_color_value_unit t_property_color_value_unit t_property_color_opt_alpha_ws T_PARENT_RIGHT {
795 double h = $3, s = $4, l = $5;
796 $$ = hsl_to_rgb ( h, s, l );
797 $$.alpha = $6;
798 }
799 /** hsl ( 0-360 , 0-100 %, 0 - 100 %) */
800 | T_COL_HSL T_PARENT_LEFT t_property_color_value_angle T_COMMA t_property_color_value_unit T_COMMA t_property_color_value_unit t_property_color_opt_alpha_c T_PARENT_RIGHT {
801 double h = $3, s = $5, l = $7;
802 $$ = hsl_to_rgb ( h, s, l );
803 $$.alpha = $8;
804 }
805 /** Hex colors parsed by lexer. */
806 | T_COLOR {
807 $$ = $1;
808 }
809 | T_COLOR_TRANSPARENT {
810 $$.alpha = 0.0;
811 $$.red = $$.green = $$.blue = 0.0;
812 }
813 | T_COLOR_NAME t_property_color_opt_alpha_ws {
814 $$ = $1;
815 $$.alpha = $2;
816 }
817 ;
818 t_property_color_opt_alpha_c
819 : %empty { $$ = 1.0; }
820 | T_COMMA t_property_color_value_unit { $$ = $2;}
821 ;
822 t_property_color_opt_alpha_ws
823 : %empty { $$ = 1.0; }
824 | T_FORWARD_SLASH t_property_color_value_unit { $$ = $2;}
825 ;
826 t_property_color_value_angle
827 : t_property_color_value { $$ = $1/360.0; if ( ! check_in_range ( $1, 0, 360, &(@$))){YYABORT;}}
828 | t_property_color_value T_ANGLE_DEG { $$ = $1/360.0; if ( ! check_in_range ( $1, 0, 360, &(@$))){YYABORT;}}
829 | t_property_color_value T_ANGLE_RAD { $$ = $1/(2*G_PI); if ( ! check_in_range ( $1, 0.0, (2*G_PI), &(@$))){YYABORT;}}
830 | t_property_color_value T_ANGLE_GRAD { $$ = $1/400.0; if ( ! check_in_range ( $1, 0, 400, &(@$))){YYABORT;}}
831 | t_property_color_value T_ANGLE_TURN { $$ = $1; if ( ! check_in_range ( $1, 0.0, 1.0, &(@$))){YYABORT;}}
832 ;
833
834 t_property_color_value_unit
835 : t_property_color_value T_PERCENT { $$ = $1/100.0; if ( !check_in_range ( $1, 0, 100, &(@$))){YYABORT;}}
836 | t_property_color_value { $$ = $1; if ( !check_in_range ( $1, 0.0, 1.0, &(@$))){YYABORT;}}
837 ;
838 /** Color value to be double or integer. */
839 t_property_color_value
840 : T_DOUBLE { $$ = $1; }
841 | T_INT { $$ = $1; }
842 ;
843
844 t_property_orientation
845 : ORIENTATION_HORI { $$ = ROFI_ORIENTATION_HORIZONTAL; }
846 | ORIENTATION_VERT { $$ = ROFI_ORIENTATION_VERTICAL; }
847 ;
848
849 /** Property name */
850 t_property_name
851 : T_PROP_NAME { $$ = $1; }
852 ;
853
854 t_entry_name_path_selectors:
855 t_entry_name_path { $$ = g_list_append ( NULL, $1 ); }
856 | t_entry_name_path_selectors T_SSEP t_entry_name_path {
857 $$ = g_list_append ( $1, $3);
858 }
859 | t_entry_name_path_selectors T_SSEP {
860 $$ = $1;
861 }
862
863 ;
864 t_entry_name_path:
865 T_NAME_ELEMENT { $$ = g_list_append ( NULL, $1 );}
866 | t_entry_name_path T_NSEP T_NAME_ELEMENT { $$ = g_list_append ( $1, $3);}
867 | t_entry_name_path T_NSEP { $$ = $1; }
868 ;
869
870 %%
871
872