29 #define G_LOG_DOMAIN "Theme"
39 #include "theme-parser.h"
47 void yyerror ( YYLTYPE *yylloc,
const char *,
const char * );
55 return g_strdup ( data );
60 for (
unsigned int i = 0; i < base->
num_widgets; i++ ) {
61 if ( g_strcmp0 ( base->
widgets[i]->
name, name ) == 0 ) {
70 retv->
name = g_strdup ( name );
139 if (
widget->properties ) {
140 g_hash_table_destroy (
widget->properties );
141 widget->properties = NULL;
143 for (
unsigned int i = 0; i <
widget->num_widgets; i++ ) {
146 g_free (
widget->widgets );
156 char buf[G_ASCII_DTOSTR_BUF_SIZE];
157 g_ascii_formatd ( buf, G_ASCII_DTOSTR_BUF_SIZE,
"%.4lf", d );
158 fputs ( buf, stdout );
163 printf (
"%upx ", (
unsigned int) d.
distance );
167 fputs (
"%% ", stdout );
171 fputs (
"em ", stdout );
196 for ( GList *iter = p->
value.
list; iter != NULL; iter = g_list_next ( iter ) ) {
197 printf (
"%s", (
char *) ( iter->data ) );
198 if ( iter->next != NULL ) {
212 printf (
"underline " );
215 printf (
"strikethrough " );
218 printf (
"italic " );
221 printf (
"rgba ( %.0f, %.0f, %.0f, %.0f %% )",
232 printf (
"\"%s\"", p->
value.
s );
235 printf (
"%d", p->
value.
i );
238 printf (
"%.2f", p->
value.
f );
241 printf (
"%s", p->
value.
b ?
"true" :
"false" );
244 printf (
"rgba ( %.0f, %.0f, %.0f, %.0f %% )",
284 printf (
"inherit" );
294 int pl = strlen ( p->
name );
295 printf (
"%*s%s:%*s ",
depth,
"", p->
name, (
int) pnl - pl,
"" );
305 if (
widget->properties ) {
310 if ( g_strcmp0 ( w->
name,
"Root" ) == 0 ) {
313 list = g_list_prepend ( list, w->
name );
316 if ( g_list_length ( list ) > 0 ) {
318 for ( GList *iter = g_list_first ( list ); iter != NULL; iter = g_list_next ( iter ) ) {
319 char *name = (
char *) iter->data;
320 fputs ( name, stdout );
321 if ( iter->prev == NULL && iter->next ) {
324 else if ( iter->next ) {
334 size_t property_name_length = 0;
335 g_hash_table_iter_init ( &iter,
widget->properties );
336 while ( g_hash_table_iter_next ( &iter, &key, &value ) ) {
338 property_name_length = MAX ( strlen ( p->
name ), property_name_length );
340 g_hash_table_iter_init ( &iter,
widget->properties );
341 while ( g_hash_table_iter_next ( &iter, &key, &value ) ) {
346 g_list_free ( list );
348 for (
unsigned int i = 0; i <
widget->num_widgets; i++ ) {
355 printf (
"/**\n * rofi -dump-theme output.\n * Rofi version: %s\n **/\n", PACKAGE_VERSION );
382 void yyerror ( YYLTYPE *yylloc,
const char *what,
const char* s )
384 char *what_esc = what ? g_markup_escape_text ( what, -1 ) : g_strdup (
"" );
385 GString *str = g_string_new (
"" );
386 g_string_printf ( str,
"<big><b>Error while parsing theme:</b></big> <i>%s</i>\n", what_esc );
388 char *esc = g_markup_escape_text ( s, -1 );
389 g_string_append_printf ( str,
"\tParser error: <span size=\"smaller\" style=\"italic\">%s</span>\n", esc );
391 if ( yylloc->filename != NULL ) {
392 g_string_append_printf ( str,
"\tLocation: line %d column %d to line %d column %d.\n" \
393 "\tFile '%s'\n", yylloc->first_line, yylloc->first_column, yylloc->last_line, yylloc->last_column, yylloc->filename );
396 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 );
398 g_log (
"Parser", G_LOG_LEVEL_DEBUG,
"Failed to parse theme:\n%s", str->str );
404 GHashTable *table = (GHashTable *) user_data;
406 g_hash_table_replace ( table, p->
name, p );
410 if ( table == NULL ) {
413 if (
widget->properties == NULL ) {
425 for (
unsigned int j = 0;
widget && j <
widget->num_widgets; j++ ) {
426 if ( g_strcmp0 (
widget->widgets[j]->
name, name ) == 0 ) {
427 return widget->widgets[j];
435 if (
widget == NULL || name == NULL ) {
438 char *tname = g_strdup ( name );
439 char *saveptr = NULL;
441 for (
const char *iter = strtok_r ( tname,
".", &saveptr ); iter != NULL; iter = strtok_r ( NULL,
".", &saveptr ) ) {
453 if ( !exact || found ) {
467 g_warning (
"Found more then 20 redirects for property. Stopping." );
502 if (
widget->properties && g_hash_table_contains (
widget->properties, property ) ) {
503 Property *p = g_hash_table_lookup (
widget->properties, property );
516 if ( p->
type == type ) {
523 g_debug (
"Found property: '%s' on '%s', but type %s does not match expected type %s.",
672 return (
double) p->
value.
i;
688 cairo_set_source_rgba ( d,
736 char **r = defaults ? g_strsplit ( defaults,
",", 0 ) : NULL;
739 for (
int i = 0; r[i] != NULL; i++ ) {
740 l = g_list_append ( l, r[i] );
777 return ( d.
distance * height ) / ( 100.0 );
782 return ( d.
distance * width ) / ( 100.0 );
791 const double dashes[1] = { 4 };
792 cairo_set_dash ( draw, dashes, 1, 0.0 );
795 cairo_set_dash ( draw, NULL, 0, 0.0 );
811 #ifdef THEME_CONVERTER
813 static char * rofi_theme_convert_color (
char *col )
815 char *r = g_strstrip ( col );
816 if ( *r ==
'#' && strlen ( r ) == 9 ) {
831 void rofi_theme_convert_old (
void )
840 const char *
const conf[] = {
841 "* { background: %s; }",
842 "* { border-color: %s; }",
843 "* { separatorcolor: %s; }"
845 for (
int i = 0; retv && i < 3 && retv[i]; i++ ) {
846 char *str = g_strdup_printf ( conf[i], rofi_theme_convert_color ( retv[i] ) );
854 const char *
const conf[] = {
855 "* { normal-background: %s; }",
856 "* { foreground: %s; normal-foreground: @foreground; alternate-normal-foreground: @foreground; }",
857 "* { alternate-normal-background: %s; }",
858 "* { selected-normal-background: %s; }",
859 "* { selected-normal-foreground: %s; }"
861 for (
int i = 0; retv && retv[i] && i < 5; i++ ) {
862 char *str = g_strdup_printf ( conf[i], rofi_theme_convert_color ( retv[i] ) );
870 const char *
const conf[] = {
871 "* { urgent-background: %s; }",
872 "* { urgent-foreground: %s; alternate-urgent-foreground: @urgent-foreground;}",
873 "* { alternate-urgent-background: %s; }",
874 "* { selected-urgent-background: %s; }",
875 "* { selected-urgent-foreground: %s; }"
877 for (
int i = 0; retv && retv[i] && i < 5; i++ ) {
878 char *str = g_strdup_printf ( conf[i], rofi_theme_convert_color ( retv[i] ) );
886 const char *
const conf[] = {
887 "* { active-background: %s; }",
888 "* { active-foreground: %s; alternate-active-foreground: @active-foreground;}",
889 "* { alternate-active-background: %s; }",
890 "* { selected-active-background: %s; }",
891 "* { selected-active-foreground: %s; }"
893 for (
int i = 0; retv && retv[i] && i < 5; i++ ) {
894 char *str = g_strdup_printf ( conf[i], rofi_theme_convert_color ( retv[i] ) );
903 const char *
const str =
"#listview { border: 0px; }";
905 const char *
const str2 =
"#mode-switcher { border: 0px; }";
907 const char *
const str3 =
"#message { border: 0px; }";
911 const char *
const str =
"#listview { border: 2px solid 0px 0px 0px; }";
913 const char *
const str2 =
"#mode-switcher { border: 2px solid 0px 0px 0px; }";
915 const char *
const str3 =
"#message { border: 2px solid 0px 0px 0px; }";
921 char *str = g_strdup_printf (
"#listview { spacing: %dpx;}",
config.
line_margin );
927 char *str = g_strdup_printf (
"#element, inputbar, message { padding: %dpx;}",
config.
line_padding );
932 const char *str =
"#listview { scrollbar: false; }";
936 const char *str =
"#listview { scrollbar: true; }";
948 #endif // THEME_CONVERTER
954 if ( parent_file != NULL && !g_path_is_absolute ( filename ) ) {
955 char *basedir = g_path_get_dirname ( parent_file );
956 char *path = g_build_filename ( basedir, filename, NULL );
961 GFile *gf = g_file_new_for_path ( filename );
963 filename = g_file_get_path ( gf );
964 g_object_unref ( gf );