rofi  1.5.1
xrmoptions.c
Go to the documentation of this file.
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 #include <config.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <unistd.h>
33 #include <xcb/xcb.h>
34 #include <xcb/xkb.h>
35 #include <xcb/xcb_xrm.h>
36 #include <glib.h>
37 #include "xcb.h"
38 #include "xcb-internal.h"
39 #include "rofi.h"
40 #include "xrmoptions.h"
41 #include "settings.h"
42 #include "helper.h"
43 #include "rofi-types.h"
44 
46 const char * const ConfigSourceStr[] = {
47  "Default",
48  "XResources",
49  "File",
50  "Rasi File",
51  "Commandline",
52 };
55 {
61 };
62 
63 typedef struct
64 {
65  int type;
66  const char * name;
67  union
68  {
69  unsigned int * num;
70  int * snum;
71  char ** str;
72  void *pointer;
73  char * charc;
74  } value;
75  char *mem;
76  const char *comment;
77  enum ConfigSource source;
78 } XrmOption;
83 static XrmOption xrmOptions[] = {
84  { xrm_String, "switchers", { .str = &config.modi }, NULL,
85  "", CONFIG_DEFAULT },
86  { xrm_String, "modi", { .str = &config.modi }, NULL,
87  "Enabled modi", CONFIG_DEFAULT },
88  { xrm_SNumber, "width", { .snum = &config.menu_width }, NULL,
89  "Window width", CONFIG_DEFAULT },
90  { xrm_Number, "lines", { .num = &config.menu_lines }, NULL,
91  "Number of lines", CONFIG_DEFAULT },
92  { xrm_Number, "columns", { .num = &config.menu_columns }, NULL,
93  "Number of columns", CONFIG_DEFAULT },
94 
95  { xrm_String, "font", { .str = &config.menu_font }, NULL,
96  "Font to use", CONFIG_DEFAULT },
97  { xrm_Number, "borderwidth", { .num = &config.menu_bw }, NULL,
98  "", CONFIG_DEFAULT },
99  { xrm_Number, "bw", { .num = &config.menu_bw }, NULL,
100  "Border width", CONFIG_DEFAULT },
101 
102  { xrm_Number, "location", { .num = &config.location }, NULL,
103  "Location on screen", CONFIG_DEFAULT },
104 
105  { xrm_Number, "padding", { .num = &config.padding }, NULL,
106  "Padding", CONFIG_DEFAULT },
107  { xrm_SNumber, "yoffset", { .snum = &config.y_offset }, NULL,
108  "Y-offset relative to location", CONFIG_DEFAULT },
109  { xrm_SNumber, "xoffset", { .snum = &config.x_offset }, NULL,
110  "X-offset relative to location", CONFIG_DEFAULT },
111  { xrm_Boolean, "fixed-num-lines", { .num = &config.fixed_num_lines }, NULL,
112  "Always show number of lines", CONFIG_DEFAULT },
113 
114  { xrm_Boolean, "show-icons", { .snum = &config.show_icons }, NULL,
115  "Whether to load and show icons", CONFIG_DEFAULT },
116 
117  { xrm_String, "terminal", { .str = &config.terminal_emulator }, NULL,
118  "Terminal to use", CONFIG_DEFAULT },
119  { xrm_String, "ssh-client", { .str = &config.ssh_client }, NULL,
120  "Ssh client to use", CONFIG_DEFAULT },
121  { xrm_String, "ssh-command", { .str = &config.ssh_command }, NULL,
122  "Ssh command to execute", CONFIG_DEFAULT },
123  { xrm_String, "run-command", { .str = &config.run_command }, NULL,
124  "Run command to execute", CONFIG_DEFAULT },
125  { xrm_String, "run-list-command", { .str = &config.run_list_command }, NULL,
126  "Command to get extra run targets", CONFIG_DEFAULT },
127  { xrm_String, "run-shell-command", { .str = &config.run_shell_command }, NULL,
128  "Run command to execute that runs in shell", CONFIG_DEFAULT },
129  { xrm_String, "window-command", { .str = &config.window_command }, NULL,
130  "Command executed on accep-entry-custom for window modus", CONFIG_DEFAULT },
131  { xrm_String, "window-match-fields", { .str = &config.window_match_fields }, NULL,
132  "Window fields to match in window mode", CONFIG_DEFAULT },
133  { xrm_String, "drun-icon-theme", { .str = &config.drun_icon_theme }, NULL,
134  "Theme to use to look for icons", CONFIG_DEFAULT },
135 
136  { xrm_String, "drun-match-fields", { .str = &config.drun_match_fields }, NULL,
137  "Desktop entry fields to match in drun", CONFIG_DEFAULT },
138  { xrm_Boolean, "disable-history", { .num = &config.disable_history }, NULL,
139  "Disable history in run/ssh", CONFIG_DEFAULT },
140  { xrm_Boolean, "sort", { .num = &config.sort }, NULL,
141  "Use sorting", CONFIG_DEFAULT },
142  { xrm_Boolean, "levenshtein-sort", { .num = &config.levenshtein_sort }, NULL,
143  "Use levenshtein sorting also for fuzzy matching", CONFIG_DEFAULT },
144  { xrm_Boolean, "case-sensitive", { .num = &config.case_sensitive }, NULL,
145  "Set case-sensitivity", CONFIG_DEFAULT },
146  { xrm_Boolean, "cycle", { .num = &config.cycle }, NULL,
147  "Cycle through the results list", CONFIG_DEFAULT },
148  { xrm_Boolean, "sidebar-mode", { .num = &config.sidebar_mode }, NULL,
149  "Enable sidebar-mode", CONFIG_DEFAULT },
150  { xrm_SNumber, "eh", { .snum = &config.element_height }, NULL,
151  "Row height (in chars)", CONFIG_DEFAULT },
152  { xrm_Boolean, "auto-select", { .num = &config.auto_select }, NULL,
153  "Enable auto select mode", CONFIG_DEFAULT },
154  { xrm_Boolean, "parse-hosts", { .num = &config.parse_hosts }, NULL,
155  "Parse hosts file for ssh mode", CONFIG_DEFAULT },
156  { xrm_Boolean, "parse-known-hosts", { .num = &config.parse_known_hosts }, NULL,
157  "Parse known_hosts file for ssh mode", CONFIG_DEFAULT },
158  { xrm_String, "combi-modi", { .str = &config.combi_modi }, NULL,
159  "Set the modi to combine in combi mode", CONFIG_DEFAULT },
160  { xrm_String, "matching", { .str = &config.matching }, NULL,
161  "Set the matching algorithm. (normal, regex, glob, fuzzy)", CONFIG_DEFAULT },
162  { xrm_Boolean, "tokenize", { .num = &config.tokenize }, NULL,
163  "Tokenize input string", CONFIG_DEFAULT },
164  { xrm_String, "monitor", { .str = &config.monitor }, NULL,
165  "", CONFIG_DEFAULT },
166  /* Alias for dmenu compatibility. */
167  { xrm_String, "m", { .str = &config.monitor }, NULL,
168  "Monitor id to show on", CONFIG_DEFAULT },
169  { xrm_Number, "line-margin", { .num = &config.line_margin }, NULL,
170  "Margin between rows *DEPRECATED*", CONFIG_DEFAULT },
171  { xrm_Number, "line-padding", { .num = &config.line_padding }, NULL,
172  "Padding within rows *DEPRECATED*", CONFIG_DEFAULT },
173  { xrm_String, "filter", { .str = &config.filter }, NULL,
174  "Pre-set filter", CONFIG_DEFAULT },
175  { xrm_String, "separator-style", { .str = &config.separator_style }, NULL,
176  "Separator style (none, dash, solid) *DEPRECATED*", CONFIG_DEFAULT },
177  { xrm_Boolean, "hide-scrollbar", { .num = &config.hide_scrollbar }, NULL,
178  "Hide scroll-bar *DEPRECATED*", CONFIG_DEFAULT },
179  { xrm_Boolean, "fullscreen", { .num = &config.fullscreen }, NULL,
180  "Fullscreen", CONFIG_DEFAULT },
181  { xrm_Boolean, "fake-transparency", { .num = &config.fake_transparency }, NULL,
182  "Fake transparency *DEPRECATED*", CONFIG_DEFAULT },
183  { xrm_SNumber, "dpi", { .snum = &config.dpi }, NULL,
184  "DPI", CONFIG_DEFAULT },
185  { xrm_Number, "threads", { .num = &config.threads }, NULL,
186  "Threads to use for string matching", CONFIG_DEFAULT },
187  { xrm_Number, "scrollbar-width", { .num = &config.scrollbar_width }, NULL,
188  "Scrollbar width *DEPRECATED*", CONFIG_DEFAULT },
189  { xrm_Number, "scroll-method", { .num = &config.scroll_method }, NULL,
190  "Scrolling method. (0: Page, 1: Centered)", CONFIG_DEFAULT },
191  { xrm_String, "fake-background", { .str = &config.fake_background }, NULL,
192  "Background to use for fake transparency. (background or screenshot)", CONFIG_DEFAULT },
193  { xrm_String, "window-format", { .str = &config.window_format }, NULL,
194  "Window Format. w (desktop name), t (title), n (name), r (role), c (class) *DEPRECATED*", CONFIG_DEFAULT },
195  { xrm_Boolean, "click-to-exit", { .snum = &config.click_to_exit }, NULL,
196  "Click outside the window to exit", CONFIG_DEFAULT },
197  { xrm_Boolean, "show-match", { .snum = &config.show_match }, NULL,
198  "Indicate how it match by underlining it.", CONFIG_DEFAULT },
199  { xrm_String, "theme", { .str = &config.theme }, NULL,
200  "New style theme file", CONFIG_DEFAULT },
201  { xrm_String, "color-normal", { .str = &config.color_normal }, NULL,
202  "Color scheme for normal row", CONFIG_DEFAULT },
203  { xrm_String, "color-urgent", { .str = &config.color_urgent }, NULL,
204  "Color scheme for urgent row", CONFIG_DEFAULT },
205  { xrm_String, "color-active", { .str = &config.color_active }, NULL,
206  "Color scheme for active row", CONFIG_DEFAULT },
207  { xrm_String, "color-window", { .str = &config.color_window }, NULL,
208  "Color scheme window", CONFIG_DEFAULT },
209  { xrm_Number, "max-history-size", { .num = &config.max_history_size }, NULL,
210  "Max history size (WARNING: can cause slowdowns when set to high).", CONFIG_DEFAULT },
211  { xrm_Boolean, "combi-hide-mode-prefix", { .snum = &config.combi_hide_mode_prefix }, NULL,
212  "Hide the prefix mode prefix on the combi view.", CONFIG_DEFAULT },
213 };
214 
218 unsigned int num_extra_options = 0;
219 
220 void config_parser_add_option ( XrmOptionType type, const char *key, void **value, const char *comment )
221 {
222  extra_options = g_realloc ( extra_options, ( num_extra_options + 1 ) * sizeof ( XrmOption ) );
223 
229  switch ( type )
230  {
231  case xrm_String:
232  extra_options[num_extra_options].mem = ( (char *) ( *value ) );
233  break;
234  default:
236  break;
237  }
238 
240 }
241 
242 static void config_parser_set ( XrmOption *option, char *xrmValue, enum ConfigSource source )
243 {
244  switch ( option->type )
245  {
246  case xrm_String:
247  if ( ( option )->mem != NULL ) {
248  g_free ( option->mem );
249  option->mem = NULL;
250  }
251  *( option->value.str ) = g_strchomp ( g_strdup ( xrmValue ) );
252 
253  // Memory
254  ( option )->mem = *( option->value.str );
255  break;
256  case xrm_Number:
257  *( option->value.num ) = (unsigned int) g_ascii_strtoull ( xrmValue, NULL, 10 );
258  break;
259  case xrm_SNumber:
260  *( option->value.snum ) = (int) g_ascii_strtoll ( xrmValue, NULL, 10 );
261  break;
262  case xrm_Boolean:
263  if ( strlen ( xrmValue ) > 0 &&
264  g_ascii_strcasecmp ( xrmValue, "true" ) == 0 ) {
265  *( option->value.num ) = TRUE;
266  }
267  else{
268  *( option->value.num ) = FALSE;
269  }
270  break;
271  case xrm_Char:
272  *( option->value.charc ) = helper_parse_char ( xrmValue );
273  break;
274  }
275  option->source = source;
276 }
277 
278 static void __config_parse_xresource_options ( xcb_xrm_database_t *xDB, enum ConfigSource source )
279 {
280  const char * namePrefix = "rofi";
281 
282  for ( unsigned int i = 0; i < sizeof ( xrmOptions ) / sizeof ( XrmOption ); ++i ) {
283  char *name = g_strdup_printf ( "%s.%s", namePrefix, xrmOptions[i].name );
284 
285  char *xrmValue = NULL;
286  if ( xcb_xrm_resource_get_string ( xDB, name, NULL, &xrmValue ) == 0 ) {
287  config_parser_set ( &( xrmOptions[i] ), xrmValue, source );
288  }
289  if ( xrmValue ) {
290  free ( xrmValue );
291  }
292 
293  g_free ( name );
294  }
295 }
296 static void __config_parse_xresource_options_dynamic ( xcb_xrm_database_t *xDB, enum ConfigSource source )
297 {
298  const char * namePrefix = "rofi";
299 
300  for ( unsigned int i = 0; i < num_extra_options; ++i ) {
301  char *name;
302 
303  name = g_strdup_printf ( "%s.%s", namePrefix, extra_options[i].name );
304  char *xrmValue = NULL;
305  if ( xcb_xrm_resource_get_string ( xDB, name, NULL, &xrmValue ) == 0 ) {
306  config_parser_set ( &( extra_options[i] ), xrmValue, source );
307  }
308  if ( xrmValue ) {
309  free ( xrmValue );
310  }
311 
312  g_free ( name );
313  }
314 }
316 {
317  xcb_xrm_database_t *xDB = xcb_xrm_database_from_default ( xcb->connection );
318  if ( xDB ) {
321  xcb_xrm_database_free ( xDB );
322  }
323 }
324 void config_parse_xresource_options_file ( const char *filename )
325 {
326  if ( !filename ) {
327  return;
328  }
329  // Map Xresource entries to rofi config options.
330  xcb_xrm_database_t *xDB = xcb_xrm_database_from_file ( filename );
331  if ( xDB == NULL ) {
332  return;
333  }
336  xcb_xrm_database_free ( xDB );
337 }
338 
342 static void config_parse_cmd_option ( XrmOption *option )
343 {
344  // Prepend a - to the option name.
345  char *key = g_strdup_printf ( "-%s", option->name );
346  switch ( option->type )
347  {
348  case xrm_Number:
349  if ( find_arg_uint ( key, option->value.num ) == TRUE ) {
350  option->source = CONFIG_CMDLINE;
351  }
352  break;
353  case xrm_SNumber:
354  if ( find_arg_int ( key, option->value.snum ) == TRUE ) {
355  option->source = CONFIG_CMDLINE;
356  }
357  break;
358  case xrm_String:
359  if ( find_arg_str ( key, option->value.str ) == TRUE ) {
360  if ( option->mem != NULL ) {
361  g_free ( option->mem );
362  option->mem = NULL;
363  }
364  option->source = CONFIG_CMDLINE;
365  }
366  break;
367  case xrm_Boolean:
368  if ( find_arg ( key ) >= 0 ) {
369  *( option->value.num ) = TRUE;
370  option->source = CONFIG_CMDLINE;
371  }
372  else {
373  g_free ( key );
374  key = g_strdup_printf ( "-no-%s", option->name );
375  if ( find_arg ( key ) >= 0 ) {
376  *( option->value.num ) = FALSE;
377  option->source = CONFIG_CMDLINE;
378  }
379  }
380  break;
381  case xrm_Char:
382  if ( find_arg_char ( key, option->value.charc ) == TRUE ) {
383  option->source = CONFIG_CMDLINE;
384  }
385  break;
386  default:
387  break;
388  }
389  g_free ( key );
390 }
391 
393 {
394  for ( unsigned int i = 0; i < sizeof ( xrmOptions ) / sizeof ( XrmOption ); ++i ) {
395  XrmOption *op = &( xrmOptions[i] );
397  }
398  for ( unsigned int i = 0; i < num_extra_options; ++i ) {
399  XrmOption *op = &( extra_options[i] );
401  }
402 }
403 
404 static gboolean __config_parser_set_property ( XrmOption *option, const Property *p, char **error )
405 {
406  if ( option->type == xrm_String ) {
407  if ( p->type != P_STRING && p->type != P_LIST ) {
408  *error = g_strdup_printf ( "Option: %s needs to be set with a string not a %s.", option->name, PropertyTypeName[p->type] );
409  return TRUE;
410  }
411  gchar *value = NULL;
412  if ( p->type == P_LIST ) {
413  for ( GList *iter = p->value.list; iter != NULL; iter = g_list_next ( iter ) ) {
414  if ( value == NULL ) {
415  value = g_strdup ( (char *) ( iter->data ) );
416  }
417  else {
418  char *nv = g_strjoin ( ",", value, (char *) ( iter->data ), NULL );
419  g_free ( value );
420  value = nv;
421  }
422  }
423  }
424  else {
425  value = g_strdup ( p->value.s );
426  }
427  if ( ( option )->mem != NULL ) {
428  g_free ( option->mem );
429  option->mem = NULL;
430  }
431  *( option->value.str ) = value;
432 
433  // Memory
434  ( option )->mem = *( option->value.str );
435  option->source = CONFIG_FILE_THEME;
436  }
437  else if ( option->type == xrm_Number ) {
438  if ( p->type != P_INTEGER ) {
439  *error = g_strdup_printf ( "Option: %s needs to be set with a numger not a %s.", option->name, PropertyTypeName[p->type] );
440  return TRUE;
441  }
442  *( option->value.snum ) = p->value.i;
443  option->source = CONFIG_FILE_THEME;
444  }
445  else if ( option->type == xrm_SNumber ) {
446  if ( p->type != P_INTEGER ) {
447  *error = g_strdup_printf ( "Option: %s needs to be set with a numger not a %s.", option->name, PropertyTypeName[p->type] );
448  return TRUE;
449  }
450  *( option->value.num ) = (unsigned int ) ( p->value.i );
451  option->source = CONFIG_FILE_THEME;
452  }
453  else if ( option->type == xrm_Boolean ) {
454  if ( p->type != P_BOOLEAN ) {
455  *error = g_strdup_printf ( "Option: %s needs to be set with a boolean not a %s.", option->name, PropertyTypeName[p->type] );
456  return TRUE;
457  }
458  *( option->value.num ) = ( p->value.b );
459  option->source = CONFIG_FILE_THEME;
460  }
461  else {
462  // TODO add type
463  *error = g_strdup_printf ( "Option: %s is not of a supported type: %s.", option->name, PropertyTypeName[p->type] );
464  return TRUE;
465  }
466  return FALSE;
467 }
468 
469 gboolean config_parse_set_property ( const Property *p, char **error )
470 {
471  for ( unsigned int i = 0; i < sizeof ( xrmOptions ) / sizeof ( XrmOption ); ++i ) {
472  XrmOption *op = &( xrmOptions[i] );
473  if ( g_strcmp0 ( op->name, p->name ) == 0 ) {
474  return __config_parser_set_property ( op, p, error );
475  }
476  }
477  for ( unsigned int i = 0; i < num_extra_options; ++i ) {
478  XrmOption *op = &( extra_options[i] );
479  if ( g_strcmp0 ( op->name, p->name ) == 0 ) {
480  return __config_parser_set_property ( op, p, error );
481  }
482  }
483  *error = g_strdup_printf ( "Option: %s is not found.", p->name );
484  return TRUE;
485 }
486 
488 {
489  for ( unsigned int i = 0; i < ( sizeof ( xrmOptions ) / sizeof ( *xrmOptions ) ); ++i ) {
490  if ( xrmOptions[i].mem != NULL ) {
491  g_free ( xrmOptions[i].mem );
492  xrmOptions[i].mem = NULL;
493  }
494  }
495  for ( unsigned int i = 0; i < num_extra_options; ++i ) {
496  if ( extra_options[i].mem != NULL ) {
497  g_free ( extra_options[i].mem );
498  extra_options[i].mem = NULL;
499  }
500  }
501  if ( extra_options != NULL ) {
502  g_free ( extra_options );
503  }
504 }
505 
506 static void xresource_dump_entry ( const char *namePrefix, XrmOption *option )
507 {
508  printf ( "! \"%s\" ", option->comment );
509  printf ( "Set from: %s\n", ConfigSourceStr[option->source] );
510  if ( option->source == CONFIG_DEFAULT ) {
511  printf ( "! " );
512  }
513  printf ( "%s.%s: %*s", namePrefix, option->name,
514  (int) ( 30 - strlen ( option->name ) ), "" );
515  switch ( option->type )
516  {
517  case xrm_Number:
518  printf ( "%u", *( option->value.num ) );
519  break;
520  case xrm_SNumber:
521  printf ( "%i", *( option->value.snum ) );
522  break;
523  case xrm_String:
524  if ( ( *( option->value.str ) ) != NULL ) {
525  printf ( "%s", *( option->value.str ) );
526  }
527  break;
528  case xrm_Boolean:
529  printf ( "%s", ( *( option->value.num ) == TRUE ) ? "true" : "false" );
530  break;
531  case xrm_Char:
532  if ( *( option->value.charc ) > 32 && *( option->value.charc ) < 127 ) {
533  printf ( "%c", *( option->value.charc ) );
534  }
535  else {
536  printf ( "\\x%02X", *( option->value.charc ) );
537  }
538  break;
539  default:
540  break;
541  }
542  printf ( "\n" );
543 }
544 
546 {
547  const char * namePrefix = "rofi";
548  unsigned int entries = sizeof ( xrmOptions ) / sizeof ( *xrmOptions );
549  for ( unsigned int i = 0; i < entries; ++i ) {
550  // Skip duplicates.
551  if ( ( i + 1 ) < entries ) {
552  if ( xrmOptions[i].value.str == xrmOptions[i + 1].value.str ) {
553  continue;
554  }
555  }
556  xresource_dump_entry ( namePrefix, &( xrmOptions[i] ) );
557  }
558  for ( unsigned int i = 0; i < num_extra_options; i++ ) {
559  xresource_dump_entry ( namePrefix, &( extra_options[i] ) );
560  }
561 }
562 
564 {
565  if ( option->type == xrm_Char || option->source == CONFIG_DEFAULT ) {
566  printf ( "/*" );
567  }
568  printf ( "\t%s: ", option->name );
569  switch ( option->type )
570  {
571  case xrm_Number:
572  printf ( "%u", *( option->value.num ) );
573  break;
574  case xrm_SNumber:
575  printf ( "%i", *( option->value.snum ) );
576  break;
577  case xrm_String:
578  if ( ( *( option->value.str ) ) != NULL ) {
579  // TODO should this be escaped?
580  printf ( "\"%s\"", *( option->value.str ) );
581  }
582  break;
583  case xrm_Boolean:
584  printf ( "%s", ( *( option->value.num ) == TRUE ) ? "true" : "false" );
585  break;
586  case xrm_Char:
587  // TODO
588  if ( *( option->value.charc ) > 32 && *( option->value.charc ) < 127 ) {
589  printf ( "'%c'", *( option->value.charc ) );
590  }
591  else {
592  printf ( "'\\x%02X'", *( option->value.charc ) );
593  }
594  printf ( " /* unsupported */" );
595  break;
596  default:
597  break;
598  }
599 
600  printf ( ";" );
601  if ( option->type == xrm_Char || option->source == CONFIG_DEFAULT ) {
602  printf ( "*/" );
603  }
604  printf ( "\n" );
605 }
606 
607 void config_parse_dump_config_rasi_format ( gboolean changes )
608 {
609  printf ( "configuration {\n" );
610 
611  unsigned int entries = sizeof ( xrmOptions ) / sizeof ( *xrmOptions );
612  for ( unsigned int i = 0; i < entries; ++i ) {
613  // Skip duplicates.
614  if ( ( i + 1 ) < entries ) {
615  if ( xrmOptions[i].value.str == xrmOptions[i + 1].value.str ) {
616  continue;
617  }
618  }
619  if ( !changes || xrmOptions[i].source != CONFIG_DEFAULT ) {
621  }
622  }
623  for ( unsigned int i = 0; i < num_extra_options; i++ ) {
624  if ( !changes || extra_options[i].source != CONFIG_DEFAULT ) {
626  }
627  }
628 
629  printf ( "}\n" );
630 }
631 
632 static void print_option_string ( XrmOption *xo, int is_term )
633 {
634  int l = strlen ( xo->name );
635  if ( is_term ) {
636  printf ( "\t"color_bold "-%s"color_reset " [string]%-*c%s\n", xo->name, 30 - l, ' ', xo->comment );
637  printf ( "\t"color_italic "%s"color_reset, ( *( xo->value.str ) == NULL ) ? "(unset)" : ( *( xo->value.str ) ) );
638  printf ( " "color_green "(%s)"color_reset "\n", ConfigSourceStr[xo->source] );
639  }
640  else {
641  printf ( "\t-%s [string]%-*c%s\n", xo->name, 30 - l, ' ', xo->comment );
642  printf ( "\t\t%s", ( *( xo->value.str ) == NULL ) ? "(unset)" : ( *( xo->value.str ) ) );
643  printf ( " (%s)\n", ConfigSourceStr[xo->source] );
644  }
645 }
646 static void print_option_number ( XrmOption *xo, int is_term )
647 {
648  int l = strlen ( xo->name );
649  if ( is_term ) {
650  printf ( "\t"color_bold "-%s"color_reset " [number]%-*c%s\n", xo->name, 30 - l, ' ', xo->comment );
651  printf ( "\t"color_italic "%u"color_reset, *( xo->value.num ) );
652  printf ( " "color_green "(%s)"color_reset "\n", ConfigSourceStr[xo->source] );
653  }
654  else {
655  printf ( "\t-%s [number]%-*c%s\n", xo->name, 30 - l, ' ', xo->comment );
656  printf ( "\t\t%u", *( xo->value.num ) );
657  printf ( " (%s)\n", ConfigSourceStr[xo->source] );
658  }
659 }
660 static void print_option_snumber ( XrmOption *xo, int is_term )
661 {
662  int l = strlen ( xo->name );
663  if ( is_term ) {
664  printf ( "\t"color_bold "-%s"color_reset " [number]%-*c%s\n", xo->name, 30 - l, ' ', xo->comment );
665  printf ( "\t"color_italic "%d"color_reset, *( xo->value.snum ) );
666  printf ( " "color_green "(%s)"color_reset "\n", ConfigSourceStr[xo->source] );
667  }
668  else {
669  printf ( "\t-%s [number]%-*c%s\n", xo->name, 30 - l, ' ', xo->comment );
670  printf ( "\t\t%d", *( xo->value.snum ) );
671  printf ( " (%s)\n", ConfigSourceStr[xo->source] );
672  }
673 }
674 static void print_option_char ( XrmOption *xo, int is_term )
675 {
676  int l = strlen ( xo->name );
677  if ( is_term ) {
678  printf ( "\t"color_bold "-%s"color_reset " [character]%-*c%s\n", xo->name, 30 - l, ' ', xo->comment );
679  printf ( "\t"color_italic "%c"color_reset, *( xo->value.charc ) );
680  printf ( " "color_green "(%s)"color_reset "\n", ConfigSourceStr[xo->source] );
681  }
682  else {
683  printf ( "\t-%s [character]%-*c%s\n", xo->name, 30 - l, ' ', xo->comment );
684  printf ( "\t\t%c", *( xo->value.charc ) );
685  printf ( " (%s)\n", ConfigSourceStr[xo->source] );
686  }
687 }
688 static void print_option_boolean ( XrmOption *xo, int is_term )
689 {
690  int l = strlen ( xo->name );
691  if ( is_term ) {
692  printf ( "\t"color_bold "-[no-]%s"color_reset " %-*c%s\n", xo->name, 33 - l, ' ', xo->comment );
693  printf ( "\t"color_italic "%s"color_reset, ( *( xo->value.snum ) ) ? "True" : "False" );
694  printf ( " "color_green "(%s)"color_reset "\n", ConfigSourceStr[xo->source] );
695  }
696  else {
697  printf ( "\t-[no-]%s %-*c%s\n", xo->name, 33 - l, ' ', xo->comment );
698  printf ( "\t\t%s", ( *( xo->value.snum ) ) ? "True" : "False" );
699  printf ( " (%s)\n", ConfigSourceStr[xo->source] );
700  }
701 }
702 
703 static void print_option ( XrmOption *xo, int is_term )
704 {
705  switch ( xo->type )
706  {
707  case xrm_String:
708  print_option_string ( xo, is_term );
709  break;
710  case xrm_Number:
711  print_option_number ( xo, is_term );
712  break;
713  case xrm_SNumber:
714  print_option_snumber ( xo, is_term );
715  break;
716  case xrm_Boolean:
717  print_option_boolean ( xo, is_term );
718  break;
719  case xrm_Char:
720  print_option_char ( xo, is_term );
721  break;
722  default:
723  break;
724  }
725 }
726 void print_options ( void )
727 {
728  // Check output filedescriptor
729  int is_term = isatty ( fileno ( stdout ) );
730  unsigned int entries = sizeof ( xrmOptions ) / sizeof ( *xrmOptions );
731  for ( unsigned int i = 0; i < entries; ++i ) {
732  if ( ( i + 1 ) < entries ) {
733  if ( xrmOptions[i].value.str == xrmOptions[i + 1].value.str ) {
734  continue;
735  }
736  }
737  print_option ( &xrmOptions[i], is_term );
738  }
739  for ( unsigned int i = 0; i < num_extra_options; i++ ) {
740  print_option ( &extra_options[i], is_term );
741  }
742 }
743 
744 void print_help_msg ( const char *option, const char *type, const char*text, const char *def, int isatty )
745 {
746  int l = 37 - strlen ( option ) - strlen ( type );
747  if ( isatty ) {
748  printf ( "\t%s%s%s %s %-*c%s\n", color_bold, option, color_reset, type, l, ' ', text );
749  if ( def != NULL ) {
750  printf ( "\t\t%s%s%s\n", color_italic, def, color_reset );
751  }
752  }
753  else{
754  printf ( "\t%s %s %-*c%s\n", option, type, l, ' ', text );
755  if ( def != NULL ) {
756  printf ( "\t\t%s\n", def );
757  }
758  }
759 }
760 
761 static char * config_parser_return_display_help_entry ( XrmOption *option, size_t l )
762 {
763  int ll = (int) l;
764  switch ( option->type )
765  {
766  case xrm_Number:
767  return g_markup_printf_escaped ( "<b%-*s</b> (%u) <span style='italic' size='small'>%s</span>",
768  ll, option->name, *( option->value.num ), option->comment );
769  case xrm_SNumber:
770  return g_markup_printf_escaped ( "<b%-*s</b> (%d) <span style='italic' size='small'>%s</span>",
771  ll, option->name, *( option->value.snum ), option->comment );
772  case xrm_String:
773  return g_markup_printf_escaped ( "<b>%-*s</b> (%s) <span style='italic' size='small'>%s</span>",
774  ll, option->name,
775  ( *( option->value.str ) != NULL ) ? *( option->value.str ) : "null",
776  option->comment
777  );
778  case xrm_Boolean:
779  return g_markup_printf_escaped ( "<b>%-*s</b> (%s) <span style='italic' size='small'>%s</span>",
780  ll, option->name, ( *( option->value.num ) == TRUE ) ? "true" : "false", option->comment );
781  case xrm_Char:
782  if ( *( option->value.charc ) > 32 && *( option->value.charc ) < 127 ) {
783  return g_markup_printf_escaped ( "<b>%-*s</b> (%c) <span style='italic' size='small'>%s</span>",
784  ll, option->name, *( option->value.charc ), option->comment );
785  }
786  else {
787  return g_markup_printf_escaped ( "<b%-*s</b> (\\x%02X) <span style='italic' size='small'>%s</span>",
788  ll, option->name, *( option->value.charc ), option->comment );
789  }
790  default:
791  break;
792  }
793 
794  return g_strdup ( "failed" );
795 }
796 
797 char ** config_parser_return_display_help ( unsigned int *length )
798 {
799  unsigned int entries = sizeof ( xrmOptions ) / sizeof ( *xrmOptions );
800  char **retv = NULL;
804  size_t max_length = 0;
805  for ( unsigned int i = 0; i < entries; ++i ) {
806  size_t l = strlen ( xrmOptions[i].name );
807  max_length = MAX ( max_length, l );
808  }
809  for ( unsigned int i = 0; i < num_extra_options; i++ ) {
810  size_t l = strlen ( extra_options[i].name );
811  max_length = MAX ( max_length, l );
812  }
816  for ( unsigned int i = 0; i < entries; ++i ) {
817  if ( ( i + 1 ) < entries ) {
818  if ( xrmOptions[i].value.str == xrmOptions[i + 1].value.str ) {
819  continue;
820  }
821  }
822  if ( strncmp ( xrmOptions[i].name, "kb", 2 ) != 0 && strncmp ( xrmOptions[i].name, "ml", 2 ) != 0 && strncmp ( xrmOptions[i].name, "me", 2 ) != 0 ) {
823  continue;
824  }
825 
826  retv = g_realloc ( retv, ( ( *length ) + 2 ) * sizeof ( char* ) );
827 
828  retv[( *length )] = config_parser_return_display_help_entry ( &xrmOptions[i], max_length );
829  ( *length )++;
830  }
831  for ( unsigned int i = 0; i < num_extra_options; i++ ) {
832  if ( strncmp ( extra_options[i].name, "kb", 2 ) != 0 && strncmp ( extra_options[i].name, "ml", 2 ) != 0 && strncmp ( extra_options[i].name, "me", 2 ) != 0 ) {
833  continue;
834  }
835  retv = g_realloc ( retv, ( ( *length ) + 2 ) * sizeof ( char* ) );
836  retv[( *length )] = config_parser_return_display_help_entry ( &extra_options[i], max_length );
837  ( *length )++;
838  }
839  if ( ( *length ) > 0 ) {
840  retv[( *length )] = NULL;
841  }
842  return retv;
843 }
const char * comment
Definition: xrmoptions.c:76
static void print_option_string(XrmOption *xo, int is_term)
Definition: xrmoptions.c:632
unsigned int cycle
Definition: settings.h:114
char * window_command
Definition: settings.h:87
ConfigSource
Definition: xrmoptions.c:54
unsigned int auto_select
Definition: settings.h:122
static XrmOption xrmOptions[]
Definition: xrmoptions.c:83
unsigned int fake_transparency
Definition: settings.h:146
char * monitor
Definition: settings.h:133
static void xresource_dump_entry(const char *namePrefix, XrmOption *option)
Definition: xrmoptions.c:506
WindowLocation location
Definition: settings.h:94
int find_arg_char(const char *const key, char *val)
Definition: helper.c:399
unsigned int tokenize
Definition: settings.h:131
unsigned int case_sensitive
Definition: settings.h:112
union XrmOption::@2 value
char * window_format
Definition: settings.h:156
unsigned int sidebar_mode
Definition: settings.h:118
unsigned int parse_known_hosts
Definition: settings.h:126
char * matching
Definition: settings.h:129
unsigned int menu_columns
Definition: settings.h:61
unsigned int menu_lines
Definition: settings.h:59
unsigned int padding
Definition: settings.h:96
unsigned int menu_bw
Definition: settings.h:55
xcb_stuff * xcb
Definition: xcb.c:85
static void config_parse_cmd_option(XrmOption *option)
Definition: xrmoptions.c:342
void * pointer
Definition: xrmoptions.c:72
unsigned int sort
Definition: settings.h:106
void config_parse_xresource_dump(void)
Definition: xrmoptions.c:545
unsigned int scroll_method
Definition: settings.h:151
unsigned int scrollbar_width
Definition: settings.h:152
char * combi_modi
Definition: settings.h:128
#define color_green
Definition: rofi.h:96
int * snum
Definition: xrmoptions.c:70
const char * name
Definition: xrmoptions.c:66
gboolean combi_hide_mode_prefix
Definition: settings.h:167
char * color_normal
Definition: settings.h:66
int find_arg_uint(const char *const key, unsigned int *val)
Definition: helper.c:347
PropertyValue value
Definition: rofi-types.h:217
enum ConfigSource source
Definition: xrmoptions.c:77
char * modi
Definition: settings.h:53
int find_arg_str(const char *const key, char **val)
Definition: helper.c:305
int find_arg_int(const char *const key, int *val)
Definition: helper.c:337
static char * config_parser_return_display_help_entry(XrmOption *option, size_t l)
Definition: xrmoptions.c:761
char * fake_background
Definition: settings.h:154
void config_parse_xresource_options_file(const char *filename)
Definition: xrmoptions.c:324
int dpi
Definition: settings.h:148
PropertyType type
Definition: rofi-types.h:215
int y_offset
Definition: settings.h:98
static void print_option(XrmOption *xo, int is_term)
Definition: xrmoptions.c:703
int type
Definition: xrmoptions.c:65
char * run_command
Definition: settings.h:81
int click_to_exit
Definition: settings.h:158
gboolean b
Definition: rofi-types.h:188
char * ssh_command
Definition: settings.h:79
unsigned int max_history_size
Definition: settings.h:166
void print_help_msg(const char *option, const char *type, const char *text, const char *def, int isatty)
Definition: xrmoptions.c:744
void config_parse_xresource_options(xcb_stuff *xcb)
Definition: xrmoptions.c:315
int menu_width
Definition: settings.h:57
static void print_option_number(XrmOption *xo, int is_term)
Definition: xrmoptions.c:646
char * window_match_fields
Definition: settings.h:89
int x_offset
Definition: settings.h:100
char * drun_match_fields
Definition: settings.h:108
char * run_shell_command
Definition: settings.h:83
char * name
Definition: rofi-types.h:213
void config_xresource_free(void)
Definition: xrmoptions.c:487
char * mem
Definition: xrmoptions.c:75
char * color_window
Definition: settings.h:69
char * charc
Definition: xrmoptions.c:73
char * menu_font
Definition: settings.h:63
char * ssh_client
Definition: settings.h:77
static void __config_parse_xresource_options(xcb_xrm_database_t *xDB, enum ConfigSource source)
Definition: xrmoptions.c:278
static void print_option_char(XrmOption *xo, int is_term)
Definition: xrmoptions.c:674
static void print_option_boolean(XrmOption *xo, int is_term)
Definition: xrmoptions.c:688
gboolean show_match
Definition: settings.h:159
char ** config_parser_return_display_help(unsigned int *length)
Definition: xrmoptions.c:797
xcb_connection_t * connection
Definition: xcb-internal.h:47
char * run_list_command
Definition: settings.h:85
char * filter
Definition: settings.h:138
int element_height
Definition: settings.h:116
char * color_active
Definition: settings.h:67
char * separator_style
Definition: settings.h:140
unsigned int * num
Definition: xrmoptions.c:69
static void print_option_snumber(XrmOption *xo, int is_term)
Definition: xrmoptions.c:660
static void config_parser_set(XrmOption *option, char *xrmValue, enum ConfigSource source)
Definition: xrmoptions.c:242
unsigned int parse_hosts
Definition: settings.h:124
static void __config_parse_xresource_options_dynamic(xcb_xrm_database_t *xDB, enum ConfigSource source)
Definition: xrmoptions.c:296
static void config_parse_dump_config_option(XrmOption *option)
Definition: xrmoptions.c:563
gboolean show_icons
Definition: settings.h:72
unsigned int levenshtein_sort
Definition: settings.h:110
unsigned int hide_scrollbar
Definition: settings.h:142
const char *const PropertyTypeName[P_NUM_TYPES]
Definition: rofi-types.c:6
char * color_urgent
Definition: settings.h:68
GList * list
Definition: rofi-types.h:204
#define color_italic
Definition: rofi.h:94
void config_parse_dump_config_rasi_format(gboolean changes)
Dump configuration in rasi format.
Definition: xrmoptions.c:607
void print_options(void)
Definition: xrmoptions.c:726
unsigned int line_margin
Definition: settings.h:135
void config_parse_cmd_options(void)
Definition: xrmoptions.c:392
Settings config
int find_arg(const char *const key)
Definition: helper.c:295
gboolean config_parse_set_property(const Property *p, char **error)
Set config option.
Definition: xrmoptions.c:469
void config_parser_add_option(XrmOptionType type, const char *key, void **value, const char *comment)
Definition: xrmoptions.c:220
static gboolean __config_parser_set_property(XrmOption *option, const Property *p, char **error)
Definition: xrmoptions.c:404
unsigned int threads
Definition: settings.h:150
char helper_parse_char(const char *arg)
Definition: helper.c:358
#define color_bold
Definition: rofi.h:92
unsigned int num_extra_options
Definition: xrmoptions.c:218
unsigned int disable_history
Definition: settings.h:104
unsigned int fixed_num_lines
Definition: settings.h:102
#define color_reset
Definition: rofi.h:90
XrmOption * extra_options
Definition: xrmoptions.c:216
char * theme
Definition: settings.h:161
char * drun_icon_theme
Definition: settings.h:91
unsigned int fullscreen
Definition: settings.h:144
unsigned int line_padding
Definition: settings.h:136
char * terminal_emulator
Definition: settings.h:75
char ** str
Definition: xrmoptions.c:71
const char *const ConfigSourceStr[]
Definition: xrmoptions.c:46
XrmOptionType
Definition: xrmoptions.h:69