29#define G_LOG_DOMAIN "Theme"
43#include "theme-parser.h"
57 printf(
"\nParsed files:\n");
59 iter = g_list_next(iter)) {
60 printf(
"\t\u2022 %s%s%s\n", is_term ?
color_bold :
"",
61 (
const char *)(iter->data), is_term ?
color_reset :
"");
66void yyerror(YYLTYPE *yylloc,
const char *,
const char *);
75 for (
unsigned int i = 0; i < base->
num_widgets; i++) {
86 retv->
name = g_strdup(name);
124 G_GNUC_UNUSED
void *data) {
161 l = g_list_next(l)) {
237 g_hash_table_destroy(
widget->properties);
238 widget->properties = NULL;
243 for (
unsigned int i = 0; i <
widget->num_widgets; i++) {
255 char buf[G_ASCII_DTOSTR_BUF_SIZE + 1] = {
258 g_ascii_formatd(buf, G_ASCII_DTOSTR_BUF_SIZE,
"%.4f", d);
271 fputs(
" + ", stdout);
273 fputs(
" - ", stdout);
275 fputs(
" / ", stdout);
277 fputs(
" * ", stdout);
279 fputs(
" % ", stdout);
281 fputs(
" min ", stdout);
283 fputs(
" max ", stdout);
285 fputs(
" round ", stdout);
287 fputs(
" floor ", stdout);
289 fputs(
" ceil ", stdout);
297 printf(
"%upx ", (
unsigned int)unit->
distance);
300 fputs(
"mm ", stdout);
306 fputs(
"ch ", stdout);
309 fputs(
"em ", stdout);
319 g = 255 * color.
green;
321 b = 255 * color.
blue;
322 if (color.
alpha < 0.00001) {
323 printf(
"transparent");
329 if (color.
alpha < 1) {
330 printf(
"/%.0f%%", color.
alpha * 100.0);
335 printf(
"rgba ( %.0f, %.0f, %.0f, %.0f %% )", (color.
red * 255.0),
336 (color.
green * 255.0), (color.
blue * 255.0), (color.
alpha * 100.0));
340 fputs(
"calc( ", stdout);
361 for (GList *iter = p->
value.
list; iter != NULL; iter = g_list_next(iter)) {
363 if (iter->next != NULL) {
381 printf(
"underline ");
384 printf(
"strikethrough ");
390 printf(
"uppercase ");
393 printf(
"lowercase ");
396 printf(
"capitalize ");
405 fputs(
"center", stdout);
408 fputs(
"north", stdout);
411 fputs(
"south", stdout);
414 fputs(
"west", stdout);
417 fputs(
"east", stdout);
420 fputs(
"northeast", stdout);
423 fputs(
"southeast", stdout);
426 fputs(
"northwest", stdout);
429 fputs(
"southwest", stdout);
435 printf(
"\"%s\"", p->
value.
s);
441 char sign = (p->
value.
f < 0);
442 int top = (int)fabs(p->
value.
f);
443 int bottom = (fabs(fmod(p->
value.
f, 1.0))) * 100;
444 printf(
"%s%d.%02d", sign ?
"-" :
"", top, bottom);
448 printf(
"%s", p->
value.
b ?
"true" :
"false");
455 printf(
"url (\"%s\")", p->
value.
s);
457 printf(
"linear-gradient ( ");
461 l = g_list_next(l)) {
465 if (index < length) {
518 int pl = strlen(p->
name);
519 printf(
"%*s%s:%*s ",
depth,
"", p->
name, (
int)pnl - pl,
"");
531 for (
unsigned int i = 0; i <
widget->num_widgets; i++) {
540 if (g_strcmp0(w->
name,
"Root") == 0) {
546 list = g_list_prepend(list, w->
name);
549 if (g_list_length(list) > 0) {
550 printf(
"%*s", index,
"");
551 for (GList *citer = g_list_first(list); citer != NULL;
552 citer = g_list_next(citer)) {
553 char *name = (
char *)citer->data;
555 if (citer->prev == NULL && citer->next) {
557 }
else if (citer->next) {
563 printf(
"%*s* {\n", index,
"");
565 size_t property_name_length = 0;
566 g_hash_table_iter_init(&iter,
widget->properties);
567 while (g_hash_table_iter_next(&iter, &key, &value)) {
569 property_name_length = MAX(strlen(pv->
name), property_name_length);
571 g_hash_table_iter_init(&iter,
widget->properties);
572 while (g_hash_table_iter_next(&iter, &key, &value)) {
576 printf(
"%*s}\n", index,
"");
579 for (
unsigned int i = 0; i <
widget->num_widgets; i++) {
587 printf(
"/**\n * rofi -dump-theme output.\n * Rofi version: %s\n **/\n",
615void yyerror(YYLTYPE *yylloc,
const char *what,
const char *s) {
616 char *what_esc = what ? g_markup_escape_text(what, -1) : g_strdup(
"");
617 GString *str = g_string_new(
"");
619 "<big><b>Error while parsing theme:</b></big> <i>%s</i>\n",
622 char *esc = g_markup_escape_text(s, -1);
623 g_string_append_printf(
625 "\tParser error: <span size=\"smaller\" style=\"italic\">%s</span>\n",
628 if (yylloc->filename != NULL) {
629 g_string_append_printf(
631 "\tLocation: line %d column %d to line %d column %d.\n"
633 yylloc->first_line, yylloc->first_column, yylloc->last_line,
634 yylloc->last_column, yylloc->filename);
636 g_string_append_printf(
637 str,
"\tLocation: line %d column %d to line %d column %d\n",
638 yylloc->first_line, yylloc->first_column, yylloc->last_line,
639 yylloc->last_column);
641 g_log(
"Parser", G_LOG_LEVEL_DEBUG,
"Failed to parse theme:\n%s", str->str);
646 gpointer value, gpointer user_data) {
647 GHashTable *table = (GHashTable *)user_data;
649 g_hash_table_replace(table, p->
name, p);
655 if (
widget->properties == NULL) {
657 g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
669 for (
unsigned int j = 0;
widget && j <
widget->num_widgets; j++) {
670 if (g_strcmp0(
widget->widgets[j]->
name, name) == 0) {
671 return widget->widgets[j];
678 const gboolean exact) {
679 if (
widget == NULL || name == NULL) {
682 char *tname = g_strdup(name);
683 char *saveptr = NULL;
685 for (
const char *iter = strtok_r(tname,
".", &saveptr); iter != NULL;
686 iter = strtok_r(NULL,
".", &saveptr)) {
697 if (!exact || found) {
708 g_warning(
"Found more then 20 redirects for property. Stopping.");
741 const char *property, gboolean exact) {
744 g_hash_table_contains(
widget->properties, property)) {
758 if (p->
type == type) {
765 g_debug(
"Found property: '%s' on '%s', but type %s does not match "
796 const char *property,
int def) {
811 g_debug(
"Theme entry: #%s %s property %s unset.",
widget->
name,
822 const char *property,
int def) {
836 g_debug(
"Theme entry: #%s %s property %s unset.",
widget->
name,
848 const char *property,
871 g_debug(
"Theme entry: #%s %s property %s unset.",
widget->
name,
885 const char *property,
int def) {
899 g_debug(
"Theme entry: #%s %s property %s unset.",
widget->
name,
912 const char *property,
928 g_debug(
"Theme entry: #%s %s property %s unset.",
widget->
name,
933 const char *property,
942 const char *property,
958 g_debug(
"Theme entry: #%s %s property %s unset.",
widget->
name,
963 const char *property,
971 const char *property,
986 g_debug(
"Theme entry: #%s %s property %s unset.",
widget->
name,
999 const char *property,
1015 g_debug(
"Theme entry: #%s %s property %s unset.",
widget->
name,
1021 const char *property,
double def) {
1047 const char *property, cairo_t *d) {
1062 g_debug(
"Theme entry: #%s %s property %s unset.",
widget->
name,
1075 const char *property, cairo_t *d) {
1115 cairo_pattern_t *pat = cairo_pattern_create_for_surface(img);
1116 cairo_pattern_set_extend(pat, CAIRO_EXTEND_REPEAT);
1117 cairo_set_source(d, pat);
1118 cairo_pattern_destroy(pat);
1122 cairo_pattern_t *pat = NULL;
1125 pat = cairo_pattern_create_linear(0.0, 0.0,
widget->
w, 0.0);
1128 pat = cairo_pattern_create_linear(
widget->
w, 0.0, 0.0, 0.0);
1131 pat = cairo_pattern_create_linear(0.0, 0.0, 0.0,
widget->
h);
1134 pat = cairo_pattern_create_linear(0.0,
widget->
h, 0.0, 0.0);
1141 pat = cairo_pattern_create_linear(
1150 guint color_index = 0;
1152 l = g_list_next(l)) {
1154 cairo_pattern_add_color_stop_rgba(pat, (color_index) / (
double)length,
1159 cairo_set_source(d, pat);
1160 cairo_pattern_destroy(pat);
1165 cairo_pattern_add_color_stop_rgba(pat, 0, c->
red, c->
green, c->
blue,
1167 cairo_set_source(d, pat);
1168 cairo_pattern_destroy(pat);
1173 g_debug(
"Theme entry: #%s %s property %s unset.",
widget->
name,
1186 const char *property,
1209 g_debug(
"Theme entry: #%s %s property %s unset.",
widget->
name,
1221 const char *property,
1240 const char *property) {
1246 for (GList *iter = g_list_first(list); iter != NULL;
1247 iter = g_list_next(iter)) {
1252 retv = g_list_append(retv, pnew);
1260 retv = g_list_append(retv, pnew);
1262 g_warning(
"Invalid type detected in list.");
1273 for (GList *iter = g_list_first(list); iter != NULL;
1274 iter = g_list_next(iter)) {
1277 retv = g_list_append(retv, g_strdup(prop->
value.
s));
1279 g_warning(
"Invalid type detected in list.");
1287 const char *property,
1316 g_debug(
"Theme entry: #%s %s property %s unset.",
widget->
name,
1321 const char *property,
1341 val = (unit->
distance * height) / (100.0);
1345 val = (unit->
distance * width) / (100.0);
1397 return (
int)(round(a / b) * b);
1402 return (
int)(ceil(a / b) * b);
1407 return (
int)(floor(a / b) * b);
1421 const double dashes[1] = {4};
1422 cairo_set_dash(draw, dashes, 1, 0.0);
1424 cairo_set_dash(draw, NULL, 0, 0.0);
1431 if (parent_file != NULL && !g_path_is_absolute(filename)) {
1432 char *basedir = g_path_get_dirname(parent_file);
1433 char *path = g_build_filename(basedir, filename, NULL);
1438 GFile *gf = g_file_new_for_path(filename);
1440 filename = g_file_get_path(gf);
1447 g_assert(parent != NULL);
1448 g_assert(child != NULL);
1461 for (
unsigned int i = 0; i < child->
num_widgets; i++) {
1468 if (rwidget == NULL) {
1473 while (i < rwidget->num_widgets) {
1475 if (
widget->media != NULL) {
1477 for (
unsigned x = i; x < rwidget->
num_widgets; x++) {
1483 int w =
widget->media->value;
1485 for (
unsigned int x = 0; x <
widget->num_widgets; x++) {
1492 int w =
widget->media->value;
1494 for (
unsigned int x = 0; x <
widget->num_widgets; x++) {
1501 int h =
widget->media->value;
1503 for (
unsigned int x = 0; x <
widget->num_widgets; x++) {
1511 int h =
widget->media->value;
1513 for (
unsigned int x = 0; x <
widget->num_widgets; x++) {
1521 for (
unsigned int x = 0; x <
widget->num_widgets; x++) {
1528 double r =
widget->media->value;
1529 if ((
mon.
w / (
double)
mon.
h) >= r) {
1530 for (
unsigned int x = 0; x <
widget->num_widgets; x++) {
1537 double r =
widget->media->value;
1539 for (
unsigned int x = 0; x <
widget->num_widgets; x++) {
1546 if (
widget->media->boolv) {
1547 for (
unsigned int x = 0; x <
widget->num_widgets; x++) {
1568 GString *str = g_string_new(wid->
name);
1570 g_string_prepend_c(str,
' ');
1571 g_string_prepend(str, i->name);
1573 char *retv = str->str;
1574 g_string_free(str, FALSE);
1583 for (
unsigned int i = 0; i < wid->
num_widgets; i++) {
1586 if (
widget->properties == NULL) {
1589 GHashTableIter iter;
1590 gpointer key, value;
1591 g_hash_table_iter_init(&iter,
widget->properties);
1592 while (g_hash_table_iter_next(&iter, &key, &value)) {
1599 GString *str = g_string_new(NULL);
1600 g_string_printf(str,
1601 "Validating the theme failed: the variable '%s' in "
1602 "`%s { %s: var(%s);}` failed to resolve.",
1626 if (g_strcmp0(type,
"monitor-id") == 0) {
1629 if (g_strcmp0(type,
"min-width") == 0) {
1632 if (g_strcmp0(type,
"min-height") == 0) {
1635 if (g_strcmp0(type,
"max-width") == 0) {
1638 if (g_strcmp0(type,
"max-height") == 0) {
1641 if (g_strcmp0(type,
"min-aspect-ratio") == 0) {
1644 if (g_strcmp0(type,
"max-aspect-ratio") == 0) {
1647 if (g_strcmp0(type,
"enabled") == 0) {
1655 const char *property) {
const unsigned int num_CSSColors
const CSSColor CSSColors[]
char * rofi_expand_path(const char *input)
uint32_t rofi_icon_fetcher_query_advanced(const char *name, const int wsize, const int hsize)
cairo_surface_t * rofi_icon_fetcher_get(const uint32_t uid)
void rofi_add_error_message(GString *str)
void rofi_add_warning_message(GString *str)
double textbox_get_estimated_char_height(void)
double textbox_get_estimated_ch(void)
void rofi_view_get_current_monitor(int *width, int *height)
const char *const PropertyTypeName[P_NUM_TYPES]
@ ROFI_IMAGE_LINEAR_GRADIENT
@ ROFI_ORIENTATION_HORIZONTAL
@ ROFI_ORIENTATION_VERTICAL
@ ROFI_DISTANCE_MODIFIER_GROUP
@ ROFI_DISTANCE_MODIFIER_CEIL
@ ROFI_DISTANCE_MODIFIER_SUBTRACT
@ ROFI_DISTANCE_MODIFIER_MODULO
@ ROFI_DISTANCE_MODIFIER_FLOOR
@ ROFI_DISTANCE_MODIFIER_ROUND
@ ROFI_DISTANCE_MODIFIER_MULTIPLY
@ ROFI_DISTANCE_MODIFIER_MAX
@ ROFI_DISTANCE_MODIFIER_MIN
@ ROFI_DISTANCE_MODIFIER_DIVIDE
@ ROFI_DISTANCE_MODIFIER_ADD
@ ROFI_DISTANCE_MODIFIER_NONE
RofiDistanceModifier modtype
struct RofiDistanceUnit * right
struct RofiDistanceUnit * left
RofiPadding rofi_theme_get_padding(const widget *widget, const char *property, RofiPadding pad)
ThemeWidget * rofi_theme_find_or_create_name(ThemeWidget *base, const char *name)
gboolean rofi_theme_get_image(const widget *widget, const char *property, cairo_t *d)
GList * rofi_theme_get_list_strings(const widget *widget, const char *property)
void rofi_theme_free_parsed_files(void)
GList * parsed_config_files
static void rofi_theme_print_property_index(size_t pnl, int depth, Property *p)
const char *const RofiCursorTypeStr[3]
static int distance_unit_get_pixel(RofiDistanceUnit *unit, RofiOrientation ori)
static void int_rofi_theme_print_property(Property *p)
const char * rofi_theme_get_string(const widget *widget, const char *property, const char *def)
void rofi_theme_print_parsed_files(gboolean is_term)
RofiDistance rofi_theme_get_distance(const widget *widget, const char *property, int def)
int rofi_theme_get_boolean(const widget *widget, const char *property, int def)
int distance_get_pixel(RofiDistance d, RofiOrientation ori)
void rofi_theme_parse_process_links(void)
static RofiHighlightColorStyle rofi_theme_get_highlight_inside(Property *p, widget *widget, const char *property, RofiHighlightColorStyle th)
Property * rofi_theme_find_property(ThemeWidget *widget, PropertyType type, const char *property, gboolean exact)
static void rofi_theme_parse_process_links_int(ThemeWidget *wid)
RofiCursorType rofi_theme_get_cursor_type(const widget *widget, const char *property, RofiCursorType def)
ThemeWidget * rofi_config_find_widget(const char *name, const char *state, gboolean exact)
static int rofi_theme_get_integer_inside(Property *p, const widget *widget, const char *property, int def)
static RofiDistance rofi_theme_get_distance_inside(Property *p, const widget *widget, const char *property, int def)
static gboolean distance_compare(RofiDistance d, RofiDistance e)
static void rofi_theme_get_color_inside(const widget *widget, Property *p, const char *property, cairo_t *d)
void rofi_theme_parse_process_conditionals(void)
void rofi_theme_get_color(const widget *widget, const char *property, cairo_t *d)
RofiHighlightColorStyle rofi_theme_get_highlight(widget *widget, const char *property, RofiHighlightColorStyle th)
static RofiCursorType rofi_theme_get_cursor_type_inside(Property *p, const widget *widget, const char *property, RofiCursorType def)
static void rofi_theme_print_distance_unit(RofiDistanceUnit *unit)
static void rofi_theme_copy_property_int(G_GNUC_UNUSED gpointer key, gpointer value, gpointer user_data)
static void rofi_theme_distance_property_free(RofiDistance *distance)
RofiOrientation rofi_theme_get_orientation(const widget *widget, const char *property, RofiOrientation def)
static int get_pixels(RofiDistanceUnit *unit, RofiOrientation ori)
static GList * rofi_theme_get_list_inside(Property *p, const widget *widget, const char *property, PropertyType child_type)
static ThemeWidget * rofi_theme_find_single(ThemeWidget *widget, const char *name)
Property * rofi_theme_property_create(PropertyType type)
ThemeMediaType rofi_theme_parse_media_type(const char *type)
void rofi_theme_widget_add_properties(ThemeWidget *widget, GHashTable *table)
static double rofi_theme_get_double_inside(const widget *orig, Property *p, const widget *widget, const char *property, double def)
static RofiOrientation rofi_theme_get_orientation_inside(Property *p, const widget *widget, const char *property, RofiOrientation def)
double rofi_theme_get_double(const widget *widget, const char *property, double def)
static void rofi_theme_print_distance(RofiDistance d)
int rofi_theme_get_integer(const widget *widget, const char *property, int def)
void rofi_theme_print(ThemeWidget *widget)
static gboolean rofi_theme_has_property_inside(Property *p, const widget *widget, const char *property)
static RofiDistanceUnit * rofi_theme_property_copy_distance_unit(RofiDistanceUnit *unit)
static const char * rofi_theme_get_string_inside(Property *p, const widget *widget, const char *property, const char *def)
static void printf_double(double d)
gboolean rofi_theme_has_property(const widget *widget, const char *property)
static ThemeWidget * rofi_theme_find(ThemeWidget *widget, const char *name, const gboolean exact)
static char * rofi_theme_widget_get_name(ThemeWidget *wid)
void rofi_theme_reset(void)
char * rofi_theme_parse_prepare_file(const char *file, const char *parent_file)
static int rofi_theme_get_position_inside(Property *p, const widget *widget, const char *property, int def)
void rofi_theme_parse_merge_widgets(ThemeWidget *parent, ThemeWidget *child)
static void rofi_theme_distance_unit_property_free(RofiDistanceUnit *unit)
static void rofi_theme_print_color(ThemeColor color)
ThemeWidget * rofi_theme_find_widget(const char *name, const char *state, gboolean exact)
Property * rofi_theme_property_copy(const Property *p, G_GNUC_UNUSED void *data)
int rofi_theme_get_position(const widget *widget, const char *property, int def)
static void rofi_theme_resolve_link_property(Property *p, int depth)
GList * rofi_theme_get_list_distance(const widget *widget, const char *property)
static void rofi_theme_parse_process_conditionals_int(workarea mon, ThemeWidget *rwidget)
void rofi_theme_print_index(ThemeWidget *widget, int index)
void rofi_theme_free(ThemeWidget *widget)
static int rofi_theme_get_boolean_inside(Property *p, const widget *widget, const char *property, int def)
void yyerror(YYLTYPE *yylloc, const char *, const char *)
RofiDistance rofi_theme_property_copy_distance(RofiDistance const distance)
void rofi_theme_property_free(Property *p)
static RofiPadding rofi_theme_get_padding_inside(Property *p, const widget *widget, const char *property, RofiPadding pad)
static gboolean rofi_theme_get_image_inside(Property *p, const widget *widget, const char *property, cairo_t *d)
void distance_get_linestyle(RofiDistance d, cairo_t *draw)
static double rofi_theme_get_double_integer_fb_inside(Property *p, const widget *widget, const char *property, double def)
@ THEME_MEDIA_TYPE_MAX_HEIGHT
@ THEME_MEDIA_TYPE_MON_ID
@ THEME_MEDIA_TYPE_INVALID
@ THEME_MEDIA_TYPE_MIN_WIDTH
@ THEME_MEDIA_TYPE_MIN_ASPECT_RATIO
@ THEME_MEDIA_TYPE_BOOLEAN
@ THEME_MEDIA_TYPE_MAX_ASPECT_RATIO
@ THEME_MEDIA_TYPE_MAX_WIDTH
@ THEME_MEDIA_TYPE_MIN_HEIGHT
struct _PropertyValue::@6 link
RofiHighlightColorStyle highlight
struct Property * def_value
int monitor_active(workarea *mon)
ThemeWidget * rofi_configuration