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