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