rofi  1.7.0
xrmoptions.c
Go to the documentation of this file.
1 /*
2  * rofi
3  *
4  * MIT/X11 License
5  * Copyright © 2013-2021 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  */
28 #define G_LOG_DOMAIN "XrmOptions"
29 
30 #include "xrmoptions.h"
31 #include "helper.h"
32 #include "rofi-types.h"
33 #include "rofi.h"
34 #include "settings.h"
35 #include "xcb-internal.h"
36 #include "xcb.h"
37 #include <ctype.h>
38 #include <glib.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <unistd.h>
43 #include <xcb/xcb.h>
44 #include <xcb/xkb.h>
45 
47 
49 const char *const ConfigSourceStr[] = {
50  "Default",
51  "File",
52  "Rasi File",
53  "Commandline",
54 };
60  CONFIG_CMDLINE = 3
61 };
62 
63 typedef struct {
64  int type;
65  const char *name;
66  union {
67  unsigned int *num;
68  int *snum;
69  char **str;
70  void *pointer;
71  char *charc;
72  } value;
73  char *mem;
74  const char *comment;
75  enum ConfigSource source;
76 } XrmOption;
81 static XrmOption xrmOptions[] = {
82  {xrm_String, "switchers", {.str = &config.modi}, NULL, "", CONFIG_DEFAULT},
83  {xrm_String,
84  "modi",
85  {.str = &config.modi},
86  NULL,
87  "Enabled modi",
89  {xrm_String,
90  "font",
91  {.str = &config.menu_font},
92  NULL,
93  "Font to use",
95  {xrm_Number,
96  "location",
97  {.num = &config.location},
98  NULL,
99  "Location on screen",
101  {xrm_SNumber,
102  "yoffset",
103  {.snum = &config.y_offset},
104  NULL,
105  "Y-offset relative to location",
107  {xrm_SNumber,
108  "xoffset",
109  {.snum = &config.x_offset},
110  NULL,
111  "X-offset relative to location",
113  {xrm_Boolean,
114  "fixed-num-lines",
115  {.num = &config.fixed_num_lines},
116  NULL,
117  "Always show number of lines",
119 
120  {xrm_Boolean,
121  "show-icons",
122  {.snum = &config.show_icons},
123  NULL,
124  "Whether to load and show icons",
126 
127  {xrm_String,
128  "terminal",
129  {.str = &config.terminal_emulator},
130  NULL,
131  "Terminal to use",
133  {xrm_String,
134  "ssh-client",
135  {.str = &config.ssh_client},
136  NULL,
137  "Ssh client to use",
139  {xrm_String,
140  "ssh-command",
141  {.str = &config.ssh_command},
142  NULL,
143  "Ssh command to execute",
145  {xrm_String,
146  "run-command",
147  {.str = &config.run_command},
148  NULL,
149  "Run command to execute",
151  {xrm_String,
152  "run-list-command",
153  {.str = &config.run_list_command},
154  NULL,
155  "Command to get extra run targets",
157  {xrm_String,
158  "run-shell-command",
159  {.str = &config.run_shell_command},
160  NULL,
161  "Run command to execute that runs in shell",
163  {xrm_String,
164  "window-command",
165  {.str = &config.window_command},
166  NULL,
167  "Command to executed when -kb-accept-alt binding is hit on selected "
168  "window ",
170  {xrm_String,
171  "window-match-fields",
172  {.str = &config.window_match_fields},
173  NULL,
174  "Window fields to match in window mode",
176  {xrm_String,
177  "icon-theme",
178  {.str = &config.icon_theme},
179  NULL,
180  "Theme to use to look for icons",
182 
183  {xrm_String,
184  "drun-match-fields",
185  {.str = &config.drun_match_fields},
186  NULL,
187  "Desktop entry fields to match in drun",
189  {xrm_String,
190  "drun-categories",
191  {.str = &config.drun_categories},
192  NULL,
193  "Only show Desktop entry from these categories",
195  {xrm_Boolean,
196  "drun-show-actions",
197  {.num = &config.drun_show_actions},
198  NULL,
199  "Desktop entry show actions.",
201  {xrm_String,
202  "drun-display-format",
203  {.str = &config.drun_display_format},
204  NULL,
205  "DRUN format string. (Supports: generic,name,comment,exec,categories)",
207  {xrm_String,
208  "drun-url-launcher",
209  {.str = &config.drun_url_launcher},
210  NULL,
211  "Command to open a Desktop Entry that is a Link.",
213 
214  {xrm_Boolean,
215  "disable-history",
216  {.num = &config.disable_history},
217  NULL,
218  "Disable history in run/ssh",
220  {xrm_String,
221  "ignored-prefixes",
222  {.str = &config.ignored_prefixes},
223  NULL,
224  "Programs ignored for history",
226  {xrm_Boolean,
227  "sort",
228  {.num = &config.sort},
229  NULL,
230  "Use sorting",
232  {xrm_String,
233  "sorting-method",
234  {.str = &config.sorting_method},
235  NULL,
236  "Choose the strategy used for sorting: normal (levenshtein) or fzf.",
238  {xrm_Boolean,
239  "case-sensitive",
240  {.num = &config.case_sensitive},
241  NULL,
242  "Set case-sensitivity",
244  {xrm_Boolean,
245  "cycle",
246  {.num = &config.cycle},
247  NULL,
248  "Cycle through the results list",
250  {xrm_Boolean,
251  "sidebar-mode",
252  {.num = &config.sidebar_mode},
253  NULL,
254  "Enable sidebar-mode",
256  {xrm_Boolean,
257  "hover-select",
258  {.snum = &config.hover_select},
259  NULL,
260  "Enable hover-select",
262  {xrm_SNumber,
263  "eh",
264  {.snum = &config.element_height},
265  NULL,
266  "Row height (in chars)",
268  {xrm_Boolean,
269  "auto-select",
270  {.num = &config.auto_select},
271  NULL,
272  "Enable auto select mode",
274  {xrm_Boolean,
275  "parse-hosts",
276  {.num = &config.parse_hosts},
277  NULL,
278  "Parse hosts file for ssh mode",
280  {xrm_Boolean,
281  "parse-known-hosts",
282  {.num = &config.parse_known_hosts},
283  NULL,
284  "Parse known_hosts file for ssh mode",
286  {xrm_String,
287  "combi-modi",
288  {.str = &config.combi_modi},
289  NULL,
290  "Set the modi to combine in combi mode",
292  {xrm_String,
293  "matching",
294  {.str = &config.matching},
295  NULL,
296  "Set the matching algorithm. (normal, regex, glob, fuzzy, prefix)",
298  {xrm_Boolean,
299  "tokenize",
300  {.num = &config.tokenize},
301  NULL,
302  "Tokenize input string",
304  {xrm_String, "monitor", {.str = &config.monitor}, NULL, "", CONFIG_DEFAULT},
305  /* Alias for dmenu compatibility. */
306  {xrm_String,
307  "m",
308  {.str = &config.monitor},
309  NULL,
310  "Monitor id to show on",
312  {xrm_String,
313  "filter",
314  {.str = &config.filter},
315  NULL,
316  "Pre-set filter",
318  {xrm_SNumber, "dpi", {.snum = &config.dpi}, NULL, "DPI", CONFIG_DEFAULT},
319  {xrm_Number,
320  "threads",
321  {.num = &config.threads},
322  NULL,
323  "Threads to use for string matching",
325  {xrm_Number,
326  "scroll-method",
327  {.num = &config.scroll_method},
328  NULL,
329  "Scrolling method. (0: Page, 1: Centered)",
331  {xrm_String,
332  "window-format",
333  {.str = &config.window_format},
334  NULL,
335  "Window Format. w (desktop name), t (title), n (name), r (role), c "
336  "(class)",
338  {xrm_Boolean,
339  "click-to-exit",
340  {.snum = &config.click_to_exit},
341  NULL,
342  "Click outside the window to exit",
344  {xrm_String,
345  "theme",
346  {.str = &config.theme},
347  NULL,
348  "New style theme file",
350  {xrm_Number,
351  "max-history-size",
352  {.num = &config.max_history_size},
353  NULL,
354  "Max history size (WARNING: can cause slowdowns when set too high).",
356  {xrm_Boolean,
357  "combi-hide-mode-prefix",
358  {.snum = &config.combi_hide_mode_prefix},
359  NULL,
360  "Hide the prefix mode prefix on the combi view.",
362  {xrm_Char,
363  "matching-negate-char",
364  {.charc = &config.matching_negate_char},
365  NULL,
366  "Set the character used to negate the matching. ('\\0' to disable)",
368  {xrm_String,
369  "cache-dir",
370  {.str = &config.cache_dir},
371  NULL,
372  "Directory where history and temporary files are stored.",
374  {xrm_Boolean,
375  "window-thumbnail",
376  {.snum = &config.window_thumbnail},
377  NULL,
378  "Show window thumbnail (if available) as icon in window switcher.",
380  {xrm_Boolean,
381  "drun-use-desktop-cache",
382  {.snum = &config.drun_use_desktop_cache},
383  NULL,
384  "DRUN: build and use a cache with desktop file content.",
386  {xrm_Boolean,
387  "drun-reload-desktop-cache",
389  NULL,
390  "DRUN: If enabled, reload the cache with desktop file content.",
392  {xrm_Boolean,
393  "normalize-match",
394  {.snum = &config.normalize_match},
395  NULL,
396  "Normalize string when matching (disables match highlighting).",
398  {xrm_Boolean,
399  "steal-focus",
400  {.snum = &config.steal_focus},
401  NULL,
402  "Steal focus on launch and restore to window that had it on rofi start on "
403  "close .",
405  {xrm_String,
406  "application-fallback-icon",
407  {.str = &(config.application_fallback_icon)},
408  NULL,
409  "Fallback icon to use when the application icon is not found in run/drun.",
411 };
412 
416 unsigned int num_extra_options = 0;
417 
419 GList *extra_parsed_options = NULL;
420 
421 static gboolean __config_parser_set_property(XrmOption *option,
422  const Property *p, char **error);
423 
424 void config_parser_add_option(XrmOptionType type, const char *key, void **value,
425  const char *comment) {
426  extra_options =
427  g_realloc(extra_options, (num_extra_options + 1) * sizeof(XrmOption));
428 
434  switch (type) {
435  case xrm_String:
436  extra_options[num_extra_options].mem = ((char *)(*value));
437  break;
438  default:
440  break;
441  }
442 
443  for (GList *iter = g_list_first(extra_parsed_options); iter != NULL;
444  iter = g_list_next(iter)) {
445  if (g_strcmp0(((Property *)(iter->data))->name, key) == 0) {
446  char *error = NULL;
447  g_debug("Setting property from backup list: %s", key);
449  (Property *)(iter->data), &error)) {
450  g_debug("Failed to set property on custom entry: %s", key);
451  g_free(error);
452  }
454  return;
455  }
456  }
458 }
459 
463 static void config_parse_cmd_option(XrmOption *option) {
464  // Prepend a - to the option name.
465  char *key = g_strdup_printf("-%s", option->name);
466  switch (option->type) {
467  case xrm_Number:
468  if (find_arg_uint(key, option->value.num) == TRUE) {
469  option->source = CONFIG_CMDLINE;
470  }
471  break;
472  case xrm_SNumber:
473  if (find_arg_int(key, option->value.snum) == TRUE) {
474  option->source = CONFIG_CMDLINE;
475  }
476  break;
477  case xrm_String:
478  if (find_arg_str(key, option->value.str) == TRUE) {
479  if (option->mem != NULL) {
480  g_free(option->mem);
481  option->mem = NULL;
482  }
483  option->source = CONFIG_CMDLINE;
484  }
485  break;
486  case xrm_Boolean:
487  if (find_arg(key) >= 0) {
488  *(option->value.num) = TRUE;
489  option->source = CONFIG_CMDLINE;
490  } else {
491  g_free(key);
492  key = g_strdup_printf("-no-%s", option->name);
493  if (find_arg(key) >= 0) {
494  *(option->value.num) = FALSE;
495  option->source = CONFIG_CMDLINE;
496  }
497  }
498  break;
499  case xrm_Char:
500  if (find_arg_char(key, option->value.charc) == TRUE) {
501  option->source = CONFIG_CMDLINE;
502  }
503  break;
504  default:
505  break;
506  }
507  g_free(key);
508 }
509 
511  for (unsigned int i = 0; i < sizeof(xrmOptions) / sizeof(XrmOption); ++i) {
512  XrmOption *op = &(xrmOptions[i]);
514  }
515  for (unsigned int i = 0; i < num_extra_options; ++i) {
516  XrmOption *op = &(extra_options[i]);
518  }
519 
521  extern int stored_argc;
523  extern char **stored_argv;
524  for (int in = 1; in < (stored_argc - 1); in++) {
525  if (stored_argv[in][0] == '-') {
527  char **tokens = g_strsplit(stored_argv[in], "-", 3);
528  int count = 1;
529  for (int j = 1; tokens && tokens[j]; j++) {
530  count++;
531  }
532  if (count > 2 && g_strcmp0(tokens[1], "no") != 0) {
533  GString *str = g_string_new("configuration { ");
534  for (int j = 1; j < (count - 1); j++) {
535  g_string_append_printf(str, "%s { ", tokens[j]);
536  }
537  g_string_append_printf(str, "%s: %s;", tokens[count - 1],
538  stored_argv[in + 1]);
539  for (int j = 0; j < (count - 1); j++) {
540  g_string_append(str, " } ");
541  }
542  if (rofi_theme_parse_string(str->str) == 1) {
545  g_string_assign(str, "configuration { ");
546  for (int j = 1; j < (count - 1); j++) {
547  g_string_append_printf(str, "%s { ", tokens[j]);
548  }
549  char *esc = g_strescape(stored_argv[in + 1], NULL);
550  g_string_append_printf(str, "%s: \"%s\";", tokens[count - 1], esc);
551  g_free(esc);
552  for (int j = 0; j < (count - 1); j++) {
553  g_string_append(str, " } ");
554  }
555  if (rofi_theme_parse_string(str->str) == 1) {
556  printf("failed\n");
557  }
558  }
559  g_string_free(str, TRUE);
560  in++;
561  }
562  g_strfreev(tokens);
563  }
564  }
565 }
566 
567 static gboolean __config_parser_set_property(XrmOption *option,
568  const Property *p, char **error) {
569  if (option->type == xrm_String) {
570  if (p->type != P_STRING && p->type != P_LIST) {
571  *error =
572  g_strdup_printf("Option: %s needs to be set with a string not a %s.",
573  option->name, PropertyTypeName[p->type]);
574  return TRUE;
575  }
576  gchar *value = NULL;
577  if (p->type == P_LIST) {
578  for (GList *iter = p->value.list; iter != NULL;
579  iter = g_list_next(iter)) {
580  if (value == NULL) {
581  value = g_strdup((char *)(iter->data));
582  } else {
583  char *nv = g_strjoin(",", value, (char *)(iter->data), NULL);
584  g_free(value);
585  value = nv;
586  }
587  }
588  } else {
589  value = g_strdup(p->value.s);
590  }
591  if ((option)->mem != NULL) {
592  g_free(option->mem);
593  option->mem = NULL;
594  }
595  *(option->value.str) = value;
596 
597  // Memory
598  (option)->mem = *(option->value.str);
599  option->source = CONFIG_FILE_THEME;
600  } else if (option->type == xrm_Number) {
601  if (p->type != P_INTEGER) {
602  *error =
603  g_strdup_printf("Option: %s needs to be set with a number not a %s.",
604  option->name, PropertyTypeName[p->type]);
605  return TRUE;
606  }
607  *(option->value.snum) = p->value.i;
608  option->source = CONFIG_FILE_THEME;
609  } else if (option->type == xrm_SNumber) {
610  if (p->type != P_INTEGER) {
611  *error =
612  g_strdup_printf("Option: %s needs to be set with a number not a %s.",
613  option->name, PropertyTypeName[p->type]);
614  return TRUE;
615  }
616  *(option->value.num) = (unsigned int)(p->value.i);
617  option->source = CONFIG_FILE_THEME;
618  } else if (option->type == xrm_Boolean) {
619  if (p->type != P_BOOLEAN) {
620  *error =
621  g_strdup_printf("Option: %s needs to be set with a boolean not a %s.",
622  option->name, PropertyTypeName[p->type]);
623  return TRUE;
624  }
625  *(option->value.num) = (p->value.b);
626  option->source = CONFIG_FILE_THEME;
627  } else if (option->type == xrm_Char) {
628  if (p->type != P_CHAR) {
629  *error = g_strdup_printf(
630  "Option: %s needs to be set with a character not a %s.", option->name,
631  PropertyTypeName[p->type]);
632  return TRUE;
633  }
634  *(option->value.charc) = (p->value.c);
635  option->source = CONFIG_FILE_THEME;
636  } else {
637  // TODO add type
638  *error = g_strdup_printf("Option: %s is not of a supported type: %s.",
639  option->name, PropertyTypeName[p->type]);
640  return TRUE;
641  }
642  return FALSE;
643 }
644 
645 gboolean config_parse_set_property(const Property *p, char **error) {
646  for (unsigned int i = 0; i < sizeof(xrmOptions) / sizeof(XrmOption); ++i) {
647  XrmOption *op = &(xrmOptions[i]);
648  if (g_strcmp0(op->name, p->name) == 0) {
649  return __config_parser_set_property(op, p, error);
650  }
651  }
652  for (unsigned int i = 0; i < num_extra_options; ++i) {
653  XrmOption *op = &(extra_options[i]);
654  if (g_strcmp0(op->name, p->name) == 0) {
655  return __config_parser_set_property(op, p, error);
656  }
657  }
658  *error = g_strdup_printf("Option: %s is not found.", p->name);
659 
660  for (GList *iter = g_list_first(extra_parsed_options); iter != NULL;
661  iter = g_list_next(iter)) {
662  if (g_strcmp0(((Property *)(iter->data))->name, p->name) == 0) {
663  rofi_theme_property_free((Property *)(iter->data));
664  iter->data = (void *)rofi_theme_property_copy(p);
665  return TRUE;
666  }
667  }
668  g_debug("Adding option: %s to backup list.", p->name);
671 
672  return TRUE;
673 }
674 
676  for (unsigned int i = 0; i < (sizeof(xrmOptions) / sizeof(*xrmOptions));
677  ++i) {
678  if (xrmOptions[i].mem != NULL) {
679  g_free(xrmOptions[i].mem);
680  xrmOptions[i].mem = NULL;
681  }
682  }
683  for (unsigned int i = 0; i < num_extra_options; ++i) {
684  if (extra_options[i].mem != NULL) {
685  g_free(extra_options[i].mem);
686  extra_options[i].mem = NULL;
687  }
688  }
689  if (extra_options != NULL) {
690  g_free(extra_options);
691  }
692  g_list_free_full(extra_parsed_options,
693  (GDestroyNotify)rofi_theme_property_free);
694 }
695 
696 static void config_parse_dump_config_option(FILE *out, XrmOption *option) {
697  if (option->type == xrm_Char || option->source == CONFIG_DEFAULT) {
698  fprintf(out, "/*");
699  }
700  fprintf(out, "\t%s: ", option->name);
701  switch (option->type) {
702  case xrm_Number:
703  fprintf(out, "%u", *(option->value.num));
704  break;
705  case xrm_SNumber:
706  fprintf(out, "%i", *(option->value.snum));
707  break;
708  case xrm_String:
709  if ((*(option->value.str)) != NULL) {
710  // TODO should this be escaped?
711  fprintf(out, "\"%s\"", *(option->value.str));
712  }
713  break;
714  case xrm_Boolean:
715  fprintf(out, "%s", (*(option->value.num) == TRUE) ? "true" : "false");
716  break;
717  case xrm_Char:
718  // TODO
719  if (*(option->value.charc) > 32 && *(option->value.charc) < 127) {
720  fprintf(out, "'%c'", *(option->value.charc));
721  } else {
722  fprintf(out, "'\\x%02X'", *(option->value.charc));
723  }
724  fprintf(out, " /* unsupported */");
725  break;
726  default:
727  break;
728  }
729 
730  fprintf(out, ";");
731  if (option->type == xrm_Char || option->source == CONFIG_DEFAULT) {
732  fprintf(out, "*/");
733  }
734  fprintf(out, "\n");
735 }
736 
737 void config_parse_dump_config_rasi_format(FILE *out, gboolean changes) {
738  fprintf(out, "configuration {\n");
739 
740  unsigned int entries = sizeof(xrmOptions) / sizeof(*xrmOptions);
741  for (unsigned int i = 0; i < entries; ++i) {
742  // Skip duplicates.
743  if ((i + 1) < entries) {
744  if (xrmOptions[i].value.str == xrmOptions[i + 1].value.str) {
745  continue;
746  }
747  }
748  if (!changes || xrmOptions[i].source != CONFIG_DEFAULT) {
750  }
751  }
752  for (unsigned int i = 0; i < num_extra_options; i++) {
753  if (!changes || extra_options[i].source != CONFIG_DEFAULT) {
755  }
756  }
757 
758  for (unsigned int index = 0; index < rofi_configuration->num_widgets;
759  index++) {
761  }
762 
763  fprintf(out, "}\n");
764 }
765 
766 static void print_option_string(XrmOption *xo, int is_term) {
767  int l = strlen(xo->name);
768  if (is_term) {
769  printf("\t" color_bold "-%s" color_reset " [string]%-*c%s\n", xo->name,
770  30 - l, ' ', xo->comment);
771  printf("\t" color_italic "%s" color_reset,
772  (*(xo->value.str) == NULL) ? "(unset)" : (*(xo->value.str)));
773  printf(" " color_green "(%s)" color_reset "\n",
774  ConfigSourceStr[xo->source]);
775  } else {
776  printf("\t-%s [string]%-*c%s\n", xo->name, 30 - l, ' ', xo->comment);
777  printf("\t\t%s",
778  (*(xo->value.str) == NULL) ? "(unset)" : (*(xo->value.str)));
779  printf(" (%s)\n", ConfigSourceStr[xo->source]);
780  }
781 }
782 static void print_option_number(XrmOption *xo, int is_term) {
783  int l = strlen(xo->name);
784  if (is_term) {
785  printf("\t" color_bold "-%s" color_reset " [number]%-*c%s\n", xo->name,
786  30 - l, ' ', xo->comment);
787  printf("\t" color_italic "%u" color_reset, *(xo->value.num));
788  printf(" " color_green "(%s)" color_reset "\n",
789  ConfigSourceStr[xo->source]);
790  } else {
791  printf("\t-%s [number]%-*c%s\n", xo->name, 30 - l, ' ', xo->comment);
792  printf("\t\t%u", *(xo->value.num));
793  printf(" (%s)\n", ConfigSourceStr[xo->source]);
794  }
795 }
796 static void print_option_snumber(XrmOption *xo, int is_term) {
797  int l = strlen(xo->name);
798  if (is_term) {
799  printf("\t" color_bold "-%s" color_reset " [number]%-*c%s\n", xo->name,
800  30 - l, ' ', xo->comment);
801  printf("\t" color_italic "%d" color_reset, *(xo->value.snum));
802  printf(" " color_green "(%s)" color_reset "\n",
803  ConfigSourceStr[xo->source]);
804  } else {
805  printf("\t-%s [number]%-*c%s\n", xo->name, 30 - l, ' ', xo->comment);
806  printf("\t\t%d", *(xo->value.snum));
807  printf(" (%s)\n", ConfigSourceStr[xo->source]);
808  }
809 }
810 static void print_option_char(XrmOption *xo, int is_term) {
811  int l = strlen(xo->name);
812  if (is_term) {
813  printf("\t" color_bold "-%s" color_reset " [character]%-*c%s\n", xo->name,
814  30 - l, ' ', xo->comment);
815  printf("\t" color_italic "%c" color_reset, *(xo->value.charc));
816  printf(" " color_green "(%s)" color_reset "\n",
817  ConfigSourceStr[xo->source]);
818  } else {
819  printf("\t-%s [character]%-*c%s\n", xo->name, 30 - l, ' ', xo->comment);
820  printf("\t\t%c", *(xo->value.charc));
821  printf(" (%s)\n", ConfigSourceStr[xo->source]);
822  }
823 }
824 static void print_option_boolean(XrmOption *xo, int is_term) {
825  int l = strlen(xo->name);
826  if (is_term) {
827  printf("\t" color_bold "-[no-]%s" color_reset " %-*c%s\n", xo->name, 33 - l,
828  ' ', xo->comment);
829  printf("\t" color_italic "%s" color_reset,
830  (*(xo->value.snum)) ? "True" : "False");
831  printf(" " color_green "(%s)" color_reset "\n",
832  ConfigSourceStr[xo->source]);
833  } else {
834  printf("\t-[no-]%s %-*c%s\n", xo->name, 33 - l, ' ', xo->comment);
835  printf("\t\t%s", (*(xo->value.snum)) ? "True" : "False");
836  printf(" (%s)\n", ConfigSourceStr[xo->source]);
837  }
838 }
839 
840 static void print_option(XrmOption *xo, int is_term) {
841  switch (xo->type) {
842  case xrm_String:
843  print_option_string(xo, is_term);
844  break;
845  case xrm_Number:
846  print_option_number(xo, is_term);
847  break;
848  case xrm_SNumber:
849  print_option_snumber(xo, is_term);
850  break;
851  case xrm_Boolean:
852  print_option_boolean(xo, is_term);
853  break;
854  case xrm_Char:
855  print_option_char(xo, is_term);
856  break;
857  default:
858  break;
859  }
860 }
861 void print_options(void) {
862  // Check output filedescriptor
863  int is_term = isatty(fileno(stdout));
864  unsigned int entries = sizeof(xrmOptions) / sizeof(*xrmOptions);
865  for (unsigned int i = 0; i < entries; ++i) {
866  if ((i + 1) < entries) {
867  if (xrmOptions[i].value.str == xrmOptions[i + 1].value.str) {
868  continue;
869  }
870  }
871  print_option(&xrmOptions[i], is_term);
872  }
873  for (unsigned int i = 0; i < num_extra_options; i++) {
874  print_option(&extra_options[i], is_term);
875  }
876 }
877 
878 void print_help_msg(const char *option, const char *type, const char *text,
879  const char *def, int isatty) {
880  int l = 37 - strlen(option) - strlen(type);
881  if (isatty) {
882  printf("\t%s%s%s %s %-*c%s\n", color_bold, option, color_reset, type, l,
883  ' ', text);
884  if (def != NULL) {
885  printf("\t\t%s%s%s\n", color_italic, def, color_reset);
886  }
887  } else {
888  printf("\t%s %s %-*c%s\n", option, type, l, ' ', text);
889  if (def != NULL) {
890  printf("\t\t%s\n", def);
891  }
892  }
893 }
894 
896  size_t l) {
897  int ll = (int)l;
898  switch (option->type) {
899  case xrm_Number:
900  return g_markup_printf_escaped(
901  "<b%-*s</b> (%u) <span style='italic' size='small'>%s</span>", ll,
902  option->name, *(option->value.num), option->comment);
903  case xrm_SNumber:
904  return g_markup_printf_escaped(
905  "<b%-*s</b> (%d) <span style='italic' size='small'>%s</span>", ll,
906  option->name, *(option->value.snum), option->comment);
907  case xrm_String:
908  return g_markup_printf_escaped(
909  "<b>%-*s</b> (%s) <span style='italic' size='small'>%s</span>", ll,
910  option->name,
911  (*(option->value.str) != NULL) ? *(option->value.str) : "null",
912  option->comment);
913  case xrm_Boolean:
914  return g_markup_printf_escaped(
915  "<b>%-*s</b> (%s) <span style='italic' size='small'>%s</span>", ll,
916  option->name, (*(option->value.num) == TRUE) ? "true" : "false",
917  option->comment);
918  case xrm_Char:
919  if (*(option->value.charc) > 32 && *(option->value.charc) < 127) {
920  return g_markup_printf_escaped(
921  "<b>%-*s</b> (%c) <span style='italic' size='small'>%s</span>", ll,
922  option->name, *(option->value.charc), option->comment);
923  } else {
924  return g_markup_printf_escaped(
925  "<b%-*s</b> (\\x%02X) <span style='italic' size='small'>%s</span>",
926  ll, option->name, *(option->value.charc), option->comment);
927  }
928  default:
929  break;
930  }
931 
932  return g_strdup("failed");
933 }
934 
935 char **config_parser_return_display_help(unsigned int *length) {
936  unsigned int entries = sizeof(xrmOptions) / sizeof(*xrmOptions);
937  char **retv = NULL;
941  size_t max_length = 0;
942  for (unsigned int i = 0; i < entries; ++i) {
943  size_t l = strlen(xrmOptions[i].name);
944  max_length = MAX(max_length, l);
945  }
946  for (unsigned int i = 0; i < num_extra_options; i++) {
947  size_t l = strlen(extra_options[i].name);
948  max_length = MAX(max_length, l);
949  }
953  for (unsigned int i = 0; i < entries; ++i) {
954  if ((i + 1) < entries) {
955  if (xrmOptions[i].value.str == xrmOptions[i + 1].value.str) {
956  continue;
957  }
958  }
959  if (strncmp(xrmOptions[i].name, "kb", 2) != 0 &&
960  strncmp(xrmOptions[i].name, "ml", 2) != 0 &&
961  strncmp(xrmOptions[i].name, "me", 2) != 0) {
962  continue;
963  }
964 
965  retv = g_realloc(retv, ((*length) + 2) * sizeof(char *));
966 
967  retv[(*length)] =
969  (*length)++;
970  }
971  for (unsigned int i = 0; i < num_extra_options; i++) {
972  if (strncmp(extra_options[i].name, "kb", 2) != 0 &&
973  strncmp(extra_options[i].name, "ml", 2) != 0 &&
974  strncmp(extra_options[i].name, "me", 2) != 0) {
975  continue;
976  }
977  retv = g_realloc(retv, ((*length) + 2) * sizeof(char *));
978  retv[(*length)] =
980  (*length)++;
981  }
982  if ((*length) > 0) {
983  retv[(*length)] = NULL;
984  }
985  return retv;
986 }
void config_parse_cmd_options(void)
Definition: xrmoptions.c:510
void print_options(void)
Definition: xrmoptions.c:861
void config_parser_add_option(XrmOptionType type, const char *key, void **value, const char *comment)
Definition: xrmoptions.c:424
XrmOptionType
Definition: xrmoptions.h:72
void print_help_msg(const char *option, const char *type, const char *text, const char *def, int isatty)
Definition: xrmoptions.c:878
gboolean config_parse_set_property(const Property *p, char **error)
Set config option.
Definition: xrmoptions.c:645
void config_parse_dump_config_rasi_format(FILE *out, gboolean changes)
Dump configuration in rasi format.
Definition: xrmoptions.c:737
char ** config_parser_return_display_help(unsigned int *length)
Definition: xrmoptions.c:935
@ xrm_SNumber
Definition: xrmoptions.h:78
@ xrm_Boolean
Definition: xrmoptions.h:80
@ xrm_Number
Definition: xrmoptions.h:76
@ xrm_Char
Definition: xrmoptions.h:82
@ xrm_String
Definition: xrmoptions.h:74
void config_xresource_free(void)
Definition: xrmoptions.c:675
int find_arg_char(const char *const key, char *val)
Definition: helper.c:407
int find_arg_int(const char *const key, int *val)
Definition: helper.c:340
int find_arg_str(const char *const key, char **val)
Definition: helper.c:310
int find_arg_uint(const char *const key, unsigned int *val)
Definition: helper.c:349
int find_arg(const char *const key)
Definition: helper.c:301
#define color_reset
Definition: rofi.h:95
#define color_bold
Definition: rofi.h:97
void rofi_clear_error_messages(void)
Definition: rofi.c:92
#define color_italic
Definition: rofi.h:99
#define color_green
Definition: rofi.h:101
char ** stored_argv
Definition: helper.c:66
int stored_argc
Definition: helper.c:64
const char *const PropertyTypeName[P_NUM_TYPES]
Definition: rofi-types.c:6
@ P_INTEGER
Definition: rofi-types.h:12
@ P_CHAR
Definition: rofi-types.h:18
@ P_LIST
Definition: rofi-types.h:34
@ P_BOOLEAN
Definition: rofi-types.h:20
@ P_STRING
Definition: rofi-types.h:16
Settings config
PropertyValue value
Definition: rofi-types.h:290
PropertyType type
Definition: rofi-types.h:288
char * name
Definition: rofi-types.h:286
WindowLocation location
Definition: settings.h:84
unsigned int threads
Definition: settings.h:143
unsigned int disable_history
Definition: settings.h:92
char * combi_modi
Definition: settings.h:132
char * application_fallback_icon
Definition: settings.h:177
char * matching
Definition: settings.h:133
int x_offset
Definition: settings.h:88
unsigned int parse_known_hosts
Definition: settings.h:130
char * cache_dir
Definition: settings.h:161
char * window_format
Definition: settings.h:146
unsigned int scroll_method
Definition: settings.h:144
gboolean drun_reload_desktop_cache
Definition: settings.h:168
char * drun_match_fields
Definition: settings.h:103
unsigned int tokenize
Definition: settings.h:135
char * drun_url_launcher
Definition: settings.h:111
char * run_command
Definition: settings.h:71
char * ignored_prefixes
Definition: settings.h:94
unsigned int fixed_num_lines
Definition: settings.h:90
gboolean normalize_match
Definition: settings.h:173
int y_offset
Definition: settings.h:86
char * terminal_emulator
Definition: settings.h:65
char * theme
Definition: settings.h:150
char * run_shell_command
Definition: settings.h:73
char * window_command
Definition: settings.h:77
unsigned int drun_show_actions
Definition: settings.h:107
gboolean steal_focus
Definition: settings.h:175
unsigned int auto_select
Definition: settings.h:126
int click_to_exit
Definition: settings.h:148
char * filter
Definition: settings.h:139
unsigned int max_history_size
Definition: settings.h:155
unsigned int case_sensitive
Definition: settings.h:114
char * run_list_command
Definition: settings.h:75
unsigned int parse_hosts
Definition: settings.h:128
char * sorting_method
Definition: settings.h:100
char * drun_display_format
Definition: settings.h:109
char * modi
Definition: settings.h:57
gboolean combi_hide_mode_prefix
Definition: settings.h:156
char * drun_categories
Definition: settings.h:105
char * icon_theme
Definition: settings.h:81
char * ssh_command
Definition: settings.h:69
unsigned int sort
Definition: settings.h:96
char * window_match_fields
Definition: settings.h:79
gboolean show_icons
Definition: settings.h:62
gboolean window_thumbnail
Definition: settings.h:164
char * menu_font
Definition: settings.h:59
unsigned int sidebar_mode
Definition: settings.h:120
char matching_negate_char
Definition: settings.h:158
int dpi
Definition: settings.h:141
gboolean drun_use_desktop_cache
Definition: settings.h:167
char * ssh_client
Definition: settings.h:67
gboolean hover_select
Definition: settings.h:122
int element_height
Definition: settings.h:118
char * monitor
Definition: settings.h:137
unsigned int cycle
Definition: settings.h:116
struct ThemeWidget ** widgets
Definition: theme.h:73
unsigned int num_widgets
Definition: theme.h:72
int type
Definition: xrmoptions.c:64
char * mem
Definition: xrmoptions.c:73
const char * comment
Definition: xrmoptions.c:74
void * pointer
Definition: xrmoptions.c:70
char ** str
Definition: xrmoptions.c:69
const char * name
Definition: xrmoptions.c:65
unsigned int * num
Definition: xrmoptions.c:67
enum ConfigSource source
Definition: xrmoptions.c:75
int * snum
Definition: xrmoptions.c:68
char * charc
Definition: xrmoptions.c:71
union XrmOption::@5 value
Property * rofi_theme_property_copy(const Property *p)
Definition: theme.c:111
void rofi_theme_print_index(ThemeWidget *widget, int index)
Definition: theme.c:479
void rofi_theme_property_free(Property *p)
Definition: theme.c:182
gboolean rofi_theme_parse_string(const char *string)
GList * list
Definition: rofi-types.h:278
gboolean b
Definition: rofi-types.h:259
unsigned long long count
Definition: view.c:117
static void print_option_snumber(XrmOption *xo, int is_term)
Definition: xrmoptions.c:796
static void print_option(XrmOption *xo, int is_term)
Definition: xrmoptions.c:840
const char *const ConfigSourceStr[]
Definition: xrmoptions.c:49
XrmOption * extra_options
Definition: xrmoptions.c:414
static gboolean __config_parser_set_property(XrmOption *option, const Property *p, char **error)
Definition: xrmoptions.c:567
static char * config_parser_return_display_help_entry(XrmOption *option, size_t l)
Definition: xrmoptions.c:895
static void print_option_char(XrmOption *xo, int is_term)
Definition: xrmoptions.c:810
GList * extra_parsed_options
Definition: xrmoptions.c:419
ThemeWidget * rofi_configuration
Definition: xrmoptions.c:46
static XrmOption xrmOptions[]
Definition: xrmoptions.c:81
ConfigSource
Definition: xrmoptions.c:56
@ CONFIG_DEFAULT
Definition: xrmoptions.c:57
@ CONFIG_FILE
Definition: xrmoptions.c:58
@ CONFIG_FILE_THEME
Definition: xrmoptions.c:59
@ CONFIG_CMDLINE
Definition: xrmoptions.c:60
static void print_option_boolean(XrmOption *xo, int is_term)
Definition: xrmoptions.c:824
unsigned int num_extra_options
Definition: xrmoptions.c:416
static void print_option_number(XrmOption *xo, int is_term)
Definition: xrmoptions.c:782
static void config_parse_cmd_option(XrmOption *option)
Definition: xrmoptions.c:463
static void config_parse_dump_config_option(FILE *out, XrmOption *option)
Definition: xrmoptions.c:696
static void print_option_string(XrmOption *xo, int is_term)
Definition: xrmoptions.c:766