29 #define G_LOG_DOMAIN "Theme" 39 #include "theme-parser.h" 47 void yyerror ( YYLTYPE *yylloc,
const char *,
const char * );
56 return g_strdup ( data );
61 for (
unsigned int i = 0; i < base->
num_widgets; i++ ) {
62 if ( g_strcmp0 ( base->
widgets[i]->
name, name ) == 0 ) {
71 retv->
name = g_strdup ( name );
197 GHashTable *table = g_hash_table_new_full ( g_str_hash, g_str_equal, NULL, (GDestroyNotify)
rofi_theme_property_free );
204 ptc->
name = g_strdup (
"text-color" );
205 g_hash_table_replace ( table, ptc->
name, ptc );
208 ptb->
name = g_strdup (
"background-color" );
213 g_hash_table_replace ( table, ptb->
name, ptb );
220 pts->
name = g_strdup (
"size" );
221 g_hash_table_replace ( table, pts->
name, pts );
226 g_hash_table_destroy ( table );
229 psp->
name = g_strdup (
"spacing" );
232 g_hash_table_replace ( table, psp->
name, psp );
234 g_hash_table_destroy ( table );
251 if (
widget->properties ) {
252 g_hash_table_destroy (
widget->properties );
253 widget->properties = NULL;
258 for (
unsigned int i = 0; i <
widget->num_widgets; i++ ) {
261 g_free (
widget->widgets );
271 char buf[G_ASCII_DTOSTR_BUF_SIZE];
272 g_ascii_formatd ( buf, G_ASCII_DTOSTR_BUF_SIZE,
"%.4lf", d );
273 fputs ( buf, stdout );
279 fputs (
"( ", stdout );
286 fputs (
" + ", stdout );
289 fputs (
" - ", stdout );
292 fputs (
" / ", stdout );
295 fputs (
" * ", stdout );
298 fputs (
" % ", stdout );
301 fputs (
" min ", stdout );
304 fputs (
" max ", stdout );
312 printf (
"%upx ", (
unsigned int) unit->
distance );
316 fputs (
"mm ", stdout );
320 fputs (
"% ", stdout );
324 fputs (
"ch ", stdout );
328 fputs (
"em ", stdout );
332 fputs (
" )", stdout );
339 fputs (
"calc( ", stdout );
343 fputs (
")", stdout );
368 for ( GList *iter = p->
value.
list; iter != NULL; iter = g_list_next ( iter ) ) {
369 printf (
"%s", (
char *) ( iter->data ) );
370 if ( iter->next != NULL ) {
384 printf (
"underline " );
387 printf (
"strikethrough " );
390 printf (
"italic " );
393 printf (
"rgba ( %.0f, %.0f, %.0f, %.0f %% )",
404 printf (
"\"%s\"", p->
value.
s );
407 printf (
"%d", p->
value.
i );
410 printf (
"%.2f", p->
value.
f );
413 printf (
"%s", p->
value.
b ?
"true" :
"false" );
416 printf (
"rgba ( %.0f, %.0f, %.0f, %.0f %% )",
457 printf (
"inherit" );
466 int pl = strlen ( p->
name );
467 printf (
"%*s%s:%*s ",
depth,
"", p->
name, (
int) pnl - pl,
"" );
480 for (
unsigned int i = 0; i <
widget->num_widgets; i++ ) {
486 if (
widget->properties ) {
490 if ( g_strcmp0 ( w->
name,
"Root" ) == 0 ) {
496 list = g_list_prepend ( list, w->
name );
499 if ( g_list_length ( list ) > 0 ) {
500 printf (
"%*s", index,
"" );
501 for ( GList *iter = g_list_first ( list ); iter != NULL; iter = g_list_next ( iter ) ) {
502 char *name = (
char *) iter->data;
503 fputs ( name, stdout );
504 if ( iter->prev == NULL && iter->next ) {
507 else if ( iter->next ) {
514 printf (
"%*s* {\n", index,
"" );
516 size_t property_name_length = 0;
517 g_hash_table_iter_init ( &iter,
widget->properties );
518 while ( g_hash_table_iter_next ( &iter, &key, &value ) ) {
520 property_name_length = MAX ( strlen ( p->
name ), property_name_length );
522 g_hash_table_iter_init ( &iter,
widget->properties );
523 while ( g_hash_table_iter_next ( &iter, &key, &value ) ) {
527 printf (
"%*s}\n", index,
"" );
528 g_list_free ( list );
530 for (
unsigned int i = 0; i <
widget->num_widgets; i++ ) {
539 printf (
"/**\n * rofi -dump-theme output.\n * Rofi version: %s\n **/\n", PACKAGE_VERSION );
566 void yyerror ( YYLTYPE *yylloc,
const char *what,
const char* s )
568 char *what_esc = what ? g_markup_escape_text ( what, -1 ) : g_strdup (
"" );
569 GString *str = g_string_new (
"" );
570 g_string_printf ( str,
"<big><b>Error while parsing theme:</b></big> <i>%s</i>\n", what_esc );
572 char *esc = g_markup_escape_text ( s, -1 );
573 g_string_append_printf ( str,
"\tParser error: <span size=\"smaller\" style=\"italic\">%s</span>\n", esc );
575 if ( yylloc->filename != NULL ) {
576 g_string_append_printf ( str,
"\tLocation: line %d column %d to line %d column %d.\n" \
577 "\tFile '%s'\n", yylloc->first_line, yylloc->first_column, yylloc->last_line, yylloc->last_column, yylloc->filename );
580 g_string_append_printf ( str,
"\tLocation: line %d column %d to line %d column %d\n", yylloc->first_line, yylloc->first_column, yylloc->last_line, yylloc->last_column );
582 g_log (
"Parser", G_LOG_LEVEL_DEBUG,
"Failed to parse theme:\n%s", str->str );
588 GHashTable *table = (GHashTable *) user_data;
590 g_hash_table_replace ( table, p->
name, p );
594 if ( table == NULL ) {
597 if (
widget->properties == NULL ) {
609 for (
unsigned int j = 0;
widget && j <
widget->num_widgets; j++ ) {
610 if ( g_strcmp0 (
widget->widgets[j]->
name, name ) == 0 ) {
611 return widget->widgets[j];
619 if (
widget == NULL || name == NULL ) {
622 char *tname = g_strdup ( name );
623 char *saveptr = NULL;
625 for (
const char *iter = strtok_r ( tname,
".", &saveptr ); iter != NULL; iter = strtok_r ( NULL,
".", &saveptr ) ) {
637 if ( !exact || found ) {
651 g_warning (
"Found more then 20 redirects for property. Stopping." );
686 if (
widget->properties && g_hash_table_contains (
widget->properties, property ) ) {
687 Property *p = g_hash_table_lookup (
widget->properties, property );
700 if ( p->
type == type ) {
707 g_debug (
"Found property: '%s' on '%s', but type %s does not match expected type %s.",
856 return (
double) p->
value.
i;
872 cairo_set_source_rgba ( d,
920 char **r = defaults ? g_strsplit ( defaults,
",", 0 ) : NULL;
923 for (
int i = 0; r[i] != NULL; i++ ) {
924 l = g_list_append ( l, r[i] );
963 val = ( unit->
distance * height ) / ( 100.0 );
968 val = ( unit->
distance * width ) / ( 100.0 );
1012 return MIN ( a, b );
1018 return MAX ( a, b );
1034 const double dashes[1] = { 4 };
1035 cairo_set_dash ( draw, dashes, 1, 0.0 );
1038 cairo_set_dash ( draw, NULL, 0, 0.0 );
1063 #ifdef THEME_CONVERTER 1065 static char * rofi_theme_convert_color (
char *col )
1067 char *r = g_strstrip ( col );
1068 if ( *r ==
'#' && strlen ( r ) == 9 ) {
1083 void rofi_theme_convert_old (
void )
1092 const char *
const conf[] = {
1093 "* { background: %s; }",
1094 "* { border-color: %s; }",
1095 "* { separatorcolor: %s; }" 1097 for (
int i = 0; retv && i < 3 && retv[i]; i++ ) {
1098 char *str = g_strdup_printf ( conf[i], rofi_theme_convert_color ( retv[i] ) );
1102 g_strfreev ( retv );
1106 const char *
const conf[] = {
1107 "* { normal-background: %s; }",
1108 "* { foreground: %s; normal-foreground: @foreground; alternate-normal-foreground: @foreground; }",
1109 "* { alternate-normal-background: %s; }",
1110 "* { selected-normal-background: %s; }",
1111 "* { selected-normal-foreground: %s; }" 1113 for (
int i = 0; retv && retv[i] && i < 5; i++ ) {
1114 char *str = g_strdup_printf ( conf[i], rofi_theme_convert_color ( retv[i] ) );
1118 g_strfreev ( retv );
1122 const char *
const conf[] = {
1123 "* { urgent-background: %s; }",
1124 "* { urgent-foreground: %s; alternate-urgent-foreground: @urgent-foreground;}",
1125 "* { alternate-urgent-background: %s; }",
1126 "* { selected-urgent-background: %s; }",
1127 "* { selected-urgent-foreground: %s; }" 1129 for (
int i = 0; retv && retv[i] && i < 5; i++ ) {
1130 char *str = g_strdup_printf ( conf[i], rofi_theme_convert_color ( retv[i] ) );
1134 g_strfreev ( retv );
1138 const char *
const conf[] = {
1139 "* { active-background: %s; }",
1140 "* { active-foreground: %s; alternate-active-foreground: @active-foreground;}",
1141 "* { alternate-active-background: %s; }",
1142 "* { selected-active-background: %s; }",
1143 "* { selected-active-foreground: %s; }" 1145 for (
int i = 0; retv && retv[i] && i < 5; i++ ) {
1146 char *str = g_strdup_printf ( conf[i], rofi_theme_convert_color ( retv[i] ) );
1150 g_strfreev ( retv );
1155 const char *
const str =
"#listview { border: 0px; }";
1157 const char *
const str2 =
"#mode-switcher { border: 0px; }";
1159 const char *
const str3 =
"#message { border: 0px; }";
1163 const char *
const str =
"#listview { border: 2px solid 0px 0px 0px; }";
1165 const char *
const str2 =
"#mode-switcher { border: 2px solid 0px 0px 0px; }";
1167 const char *
const str3 =
"#message { border: 2px solid 0px 0px 0px; }";
1173 char *str = g_strdup_printf (
"#listview { spacing: %dpx;}",
config.
line_margin );
1179 char *str = g_strdup_printf (
"#element, inputbar, message { padding: %dpx;}",
config.
line_padding );
1184 const char *str =
"#listview { scrollbar: false; }";
1188 const char *str =
"#listview { scrollbar: true; }";
1200 #endif // THEME_CONVERTER 1206 if ( parent_file != NULL && !g_path_is_absolute ( filename ) ) {
1207 char *basedir = g_path_get_dirname ( parent_file );
1208 char *path = g_build_filename ( basedir, filename, NULL );
1209 g_free ( filename );
1213 GFile *gf = g_file_new_for_path ( filename );
1214 g_free ( filename );
1215 filename = g_file_get_path ( gf );
1216 g_object_unref ( gf );
1223 g_assert ( parent != NULL );
1224 g_assert ( child != NULL );
1226 if ( parent ==
rofi_theme && g_strcmp0 ( child->
name,
"*" ) == 0 ) {
1233 for (
unsigned int i = 0; i < child->
num_widgets; i++ ) {
1239 g_assert ( parent != NULL );
1240 g_assert ( child != NULL );
1242 if ( parent ==
rofi_theme && g_strcmp0 ( child->
name,
"*" ) == 0 ) {
1248 if ( child->
media ) {
1253 for (
unsigned int i = 0; i < child->
num_widgets; i++ ) {
1260 if ( rwidget == NULL ) {
1263 for (
unsigned int i = 0; i < rwidget->
num_widgets; i++ ) {
1266 if (
widget->media != NULL ) {
1271 int w =
widget->media->value;
1273 for (
unsigned int x = 0; x <
widget->num_widgets; x++ ) {
1281 int w =
widget->media->value;
1283 for (
unsigned int x = 0; x <
widget->num_widgets; x++ ) {
1291 int h =
widget->media->value;
1293 for (
unsigned int x = 0; x <
widget->num_widgets; x++ ) {
1301 int h =
widget->media->value;
1303 for (
unsigned int x = 0; x <
widget->num_widgets; x++ ) {
1312 for (
unsigned int x = 0; x <
widget->num_widgets; x++ ) {
1320 double r =
widget->media->value;
1321 if ( (
mon.
w / (
double)
mon.
h ) >= r ) {
1322 for (
unsigned int x = 0; x <
widget->num_widgets; x++ ) {
1330 double r =
widget->media->value;
1331 if ( (
mon.
w / (
double)
mon.
h ) < r ) {
1332 for (
unsigned int x = 0; x <
widget->num_widgets; x++ ) {
1355 if ( g_strcmp0 ( type,
"monitor-id" ) == 0 ) {
1358 else if ( g_strcmp0 ( type,
"min-width" ) == 0 ) {
1361 else if ( g_strcmp0 ( type,
"min-height" ) == 0 ) {
1364 else if ( g_strcmp0 ( type,
"max-width" ) == 0 ) {
1367 else if ( g_strcmp0 ( type,
"max-height" ) == 0 ) {
1370 else if ( g_strcmp0 ( type,
"min-aspect-ratio" ) == 0 ) {
1373 else if ( g_strcmp0 ( type,
"max-aspect-ratio" ) == 0 ) {
RofiHighlightColorStyle highlight
static void rofi_theme_print_property_index(size_t pnl, int depth, Property *p)
void rofi_theme_free(ThemeWidget *widget)
GList * rofi_theme_get_list(const widget *widget, const char *property, const char *defaults)
void rofi_view_get_current_monitor(int *width, int *height)
ThemeWidget * rofi_theme_find_or_create_name(ThemeWidget *base, const char *name)
unsigned int fake_transparency
static int get_pixels(RofiDistanceUnit *unit, RofiOrientation ori)
struct RofiDistanceUnit * right
static void int_rofi_theme_print_property(Property *p)
void rofi_theme_get_color(const widget *widget, const char *property, cairo_t *d)
void rofi_theme_widget_add_properties(ThemeWidget *widget, GHashTable *table)
static void rofi_theme_print_distance_unit(RofiDistanceUnit *unit)
Property * rofi_theme_property_copy(Property *p)
ThemeWidget * rofi_theme_find_widget(const char *name, const char *state, gboolean exact)
static void printf_double(double d)
static int distance_unit_get_pixel(RofiDistanceUnit *unit, RofiOrientation ori)
void rofi_theme_parse_process_conditionals(void)
char * rofi_theme_parse_prepare_file(const char *file, const char *parent_file)
Property * rofi_theme_find_property(ThemeWidget *widget, PropertyType type, const char *property, gboolean exact)
const char * rofi_theme_get_string(const widget *widget, const char *property, const char *def)
struct Property * def_value
unsigned int scrollbar_width
double rofi_theme_get_double(const widget *widget, const char *property, double def)
RofiPadding rofi_theme_get_padding(const widget *widget, const char *property, RofiPadding pad)
static void rofi_theme_parse_process_conditionals_int(workarea mon, ThemeWidget *rwidget)
int rofi_theme_get_boolean(const widget *widget, const char *property, int def)
RofiDistance rofi_theme_get_distance(const widget *widget, const char *property, int def)
static void rofi_theme_print_index(ThemeWidget *widget, int index)
static void rofi_theme_distance_unit_property_free(RofiDistanceUnit *unit)
void rofi_theme_parse_merge_widgets(ThemeWidget *parent, ThemeWidget *child)
static void rofi_theme_print_distance(RofiDistance d)
void rofi_theme_property_free(Property *p)
RofiHighlightColorStyle rofi_theme_get_highlight(widget *widget, const char *property, RofiHighlightColorStyle th)
static void rofi_theme_resolve_link_property(Property *p, int depth)
void yyerror(YYLTYPE *yylloc, const char *, const char *)
Property * rofi_theme_property_create(PropertyType type)
RofiDistanceModifier modtype
gboolean rofi_theme_has_property(const widget *widget, const char *property)
double textbox_get_estimated_ch(void)
static void rofi_theme_distance_property_free(RofiDistance *distance)
void rofi_theme_reset(void)
static void rofi_theme_insert_listview_backwards_fix(void)
static gpointer rofi_g_list_strdup(gconstpointer data, G_GNUC_UNUSED gpointer user_data)
void rofi_add_error_message(GString *str)
char * rofi_expand_path(const char *input)
void rofi_theme_print(ThemeWidget *widget)
int distance_get_pixel(RofiDistance d, RofiOrientation ori)
struct _PropertyValue::@4 link
const char *const WindowLocationStr[9]
int monitor_active(workarea *mon)
RofiOrientation rofi_theme_get_orientation(const widget *widget, const char *property, RofiOrientation def)
unsigned int hide_scrollbar
const char *const PropertyTypeName[P_NUM_TYPES]
static void rofi_theme_copy_property_int(G_GNUC_UNUSED gpointer key, gpointer value, gpointer user_data)
int rofi_theme_get_position(const widget *widget, const char *property, int def)
RofiDistance rofi_theme_property_copy_distance(RofiDistance const distance)
static RofiDistanceUnit * rofi_theme_property_copy_distance_unit(RofiDistanceUnit *unit)
static ThemeWidget * rofi_theme_find(ThemeWidget *widget, const char *name, const gboolean exact)
ThemeMediaType rofi_theme_parse_media_type(const char *type)
static gboolean distance_compare(RofiDistance d, RofiDistance e)
static ThemeWidget * rofi_theme_find_single(ThemeWidget *widget, const char *name)
double textbox_get_estimated_char_height(void)
struct RofiDistanceUnit * left
int rofi_theme_get_integer(const widget *widget, const char *property, int def)
gboolean rofi_theme_parse_string(const char *string)
gboolean rofi_theme_is_empty(void)
unsigned int line_padding
void distance_get_linestyle(RofiDistance d, cairo_t *draw)
static void rofi_theme_parse_merge_widgets_no_media(ThemeWidget *parent, ThemeWidget *child)