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