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