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