2 /* This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "FvwmIconMan.h"
20 #include "readconfig.h"
22 #include "libs/defaults.h"
23 #include "libs/fvwmlib.h"
24 #include "libs/FScreen.h"
25 #include "libs/FShape.h"
26 #include "libs/Module.h"
27 #include "libs/Parse.h"
28 #include "libs/Strings.h"
36 extern int builtin_quit(int numargs
, BuiltinArg
*args
);
37 extern int builtin_printdebug(int numargs
, BuiltinArg
*args
);
38 extern int builtin_gotobutton(int numargs
, BuiltinArg
*args
);
39 extern int builtin_gotomanager(int numargs
, BuiltinArg
*args
);
40 extern int builtin_refresh(int numargs
, BuiltinArg
*args
);
41 extern int builtin_select(int numargs
, BuiltinArg
*args
);
42 extern int builtin_sendcommand(int numargs
, BuiltinArg
*args
);
43 extern int builtin_bif(int numargs
, BuiltinArg
*args
);
44 extern int builtin_bifn(int numargs
, BuiltinArg
*args
);
45 extern int builtin_print(int numargs
, BuiltinArg
*args
);
46 extern int builtin_jmp(int numargs
, BuiltinArg
*args
);
47 extern int builtin_ret(int numargs
, BuiltinArg
*args
);
48 extern int builtin_searchforward(int numargs
, BuiltinArg
*args
);
49 extern int builtin_searchback(int numargs
, BuiltinArg
*args
);
50 extern int builtin_warp(int numargs
, BuiltinArg
*args
);
52 /* compiler pseudo-functions */
53 static int builtin_label(int numargs
, BuiltinArg
*args
);
57 int (*func
)(int numargs
, BuiltinArg
*args
);
59 BuiltinArgType args
[MAX_ARGS
];
63 * these are now sorted so we can use bsearch on them.
65 FunctionType builtin_functions
[] = {
66 { "bif", builtin_bif
, 2, { ButtonArg
, JmpArg
} },
67 { "bifn", builtin_bifn
, 2, { ButtonArg
, JmpArg
} },
68 { "gotobutton", builtin_gotobutton
, 1, { ButtonArg
} },
69 { "gotomanager", builtin_gotomanager
, 1, { ManagerArg
} },
70 { "jmp", builtin_jmp
, 1, { JmpArg
} },
71 { "label", builtin_label
, 1, { StringArg
} },
72 { "print", builtin_print
, 1, { StringArg
} },
73 { "printdebug", builtin_printdebug
, 0, {0} },
74 { "quit", builtin_quit
, 0, {0} },
75 { "refresh", builtin_refresh
, 0, {0} },
76 { "ret", builtin_ret
, 0, {0} },
77 { "searchback", builtin_searchback
, 1, { StringArg
} },
78 { "searchforward", builtin_searchforward
, 1, { StringArg
} },
79 { "select", builtin_select
, 0, {0} },
80 { "sendcommand", builtin_sendcommand
, 1, { StringArg
} },
81 { "warp", builtin_warp
, 0, {0} }
84 static int num_builtins
= sizeof(builtin_functions
) / sizeof(FunctionType
);
86 /* This is only used for printing out the .fvwmrc line if an error
89 #define PRINT_LINE_LENGTH 80
90 static char current_line
[PRINT_LINE_LENGTH
];
92 static void save_current_line(char *s
)
94 char *p
= current_line
;
96 while (*s
&& p
< current_line
+ PRINT_LINE_LENGTH
- 1) {
110 void print_args(int numargs
, BuiltinArg
*args
)
112 #ifdef FVWM_DEBUG_MSGS
115 for (i
= 0; i
< numargs
; i
++) {
116 switch (args
[i
].type
) {
118 ConsoleDebug(CONFIG
, "NoArg ");
123 CONFIG
, "Int: %d ", args
[i
].value
.int_value
);
128 CONFIG
, "String: %s ",
129 args
[i
].value
.string_value
);
134 CONFIG
, "Button: %d %d ",
135 args
[i
].value
.button_value
.offset
,
136 args
[i
].value
.button_value
.base
);
141 CONFIG
, "Window: %d %d ",
142 args
[i
].value
.button_value
.offset
,
143 args
[i
].value
.button_value
.base
);
148 CONFIG
, "Manager: %d %d ",
149 args
[i
].value
.button_value
.offset
,
150 args
[i
].value
.button_value
.base
);
155 CONFIG
, "Unprocessed Label Jump: %s ",
156 args
[i
].value
.string_value
);
160 ConsoleDebug(CONFIG
, "bad ");
164 ConsoleDebug(CONFIG
, "\n");
168 #ifdef FVWM_DEBUG_MSGS
169 static void print_binding(Binding
*binding
)
174 if (binding
->type
== BIND_BUTTONPRESS
)
176 ConsoleDebug(CONFIG
, "\tMouse: %d\n", binding
->Button_Key
);
181 CONFIG
, "\tKey or action: %d %s\n",
182 binding
->Button_Key
, binding
->key_name
);
185 ConsoleDebug(CONFIG
, "\tModifiers: %d\n", binding
->Modifier
);
186 ConsoleDebug(CONFIG
, "\tAction: %s\n", (char *) binding
->Action
);
187 ConsoleDebug(CONFIG
, "\tFunction struct: 0x%x\n",
188 (unsigned int) binding
->Action2
);
189 func
= (Function
*)(binding
->Action2
);
192 for (i
= 0; i
< num_builtins
; i
++)
194 if (func
->func
== builtin_functions
[i
].func
)
197 CONFIG
, "\tFunction: %s 0x%x ",
198 builtin_functions
[i
].name
,
199 (unsigned int) func
->func
);
203 if (i
> num_builtins
)
206 CONFIG
, "\tFunction: not found 0x%x ",
207 (unsigned int) func
->func
);
209 print_args(func
->numargs
, func
->args
);
214 void print_bindings(Binding
*list
)
216 ConsoleDebug(CONFIG
, "binding list:\n");
220 ConsoleDebug(CONFIG
, "\n");
221 list
= list
->NextBinding
;
225 void print_bindings(Binding
*list
)
230 static int iswhite(char c
)
232 if (c
== ' ' || c
== '\t' || c
== '\0')
239 static void trim(char *p
)
241 int length
= strlen(p
) -1;
243 for (index
= length
; index
> 0; index
--)
245 if (p
[index
] == ' ' || p
[index
] == '\t')
256 static void skip_space(char **p
)
258 while (**p
== ' ' || **p
== '\t')
264 static void add_to_binding(Binding
**list
, Binding
*binding
)
266 ConsoleDebug(CONFIG
, "In add_to_binding:\n");
268 binding
->NextBinding
= *list
;
273 static int extract_int(char *p
, int *n
)
278 while (isspace((unsigned char)*p
) && *p
)
288 else if (*p
== '+') {
300 if (*s
< '0' || *s
> '9')
311 static char *parse_button(char *string
, BuiltinArg
*arg
, int *flag
,
318 ConsoleDebug(CONFIG
, "parse_term: %s\n", string
);
322 arg
->type
= ButtonArg
;
323 bv
= &arg
->value
.button_value
;
325 bv
->base
= AbsoluteButton
;
327 rest
= DoGetNextToken(string
, &token
, NULL
, ",", pstop_char
);
335 if (!strcasecmp(token
, "focus"))
337 bv
->base
= FocusButton
;
339 else if (!strcasecmp(token
, "select"))
341 bv
->base
= SelectButton
;
343 else if (!strcasecmp(token
, "up"))
347 else if (!strcasecmp(token
, "down"))
349 bv
->base
= DownButton
;
351 else if (!strcasecmp(token
, "left"))
353 bv
->base
= LeftButton
;
355 else if (!strcasecmp(token
, "right"))
357 bv
->base
= RightButton
;
359 else if (!strcasecmp(token
, "next"))
361 bv
->base
= NextButton
;
363 else if (!strcasecmp(token
, "prev"))
365 bv
->base
= PrevButton
;
367 else if (extract_int(token
, &n
))
369 bv
->base
= AbsoluteButton
;
374 ConsoleMessage("Bad button: %s\n", token
);
385 static void free_function_list(Function
*func
)
392 for (i
= 0; i
< fp
->numargs
; i
++)
394 if (fp
->args
[i
].type
== StringArg
)
396 Free(fp
->args
[i
].value
.string_value
);
405 static int funccasecmp(
406 const void *key
/* actually char* */,
407 const void *member
/* actually FunctionType* */)
409 return strcasecmp((char *)key
, ((FunctionType
*)member
)->name
);
413 * The label function. Should never be called, but we need a pointer to it,
414 * and it's useful for debugging purposes to have it defined.
416 static int builtin_label(int numargs
, BuiltinArg
*args
)
419 /* we should _never_ be called */
420 ConsoleMessage( "label" );
421 for (j
=0; j
<numargs
; ++j
)
423 switch (args
[j
].type
)
426 ConsoleMessage(" %s", args
[j
].value
.string_value
);
430 ConsoleMessage(" [unknown arg #: %d]", args
[j
].type
);
433 ConsoleMessage(" was called. This should not happen.\n");
437 /* the number of JmpArg arguments that have been created, but not yet
438 resolved into IntArgs. */
439 static int JmpArgs
= 0;
440 /* icky, I know, but it'll save unnecessary error-checking. */
442 static Function
*parse_function(char **line
, char *pstop_char
)
444 Function
*ftype
= (Function
*)safemalloc(sizeof(Function
));
445 char *ptr
, *name
, *tok
;
447 FunctionType
*builtin_functions_i
;
449 ConsoleDebug(CONFIG
, "in parse_function\n");
451 ptr
= DoGetNextToken(*line
, &name
, NULL
, ",", pstop_char
);
458 builtin_functions_i
=bsearch((void *)name
, (void *)builtin_functions
,
459 num_builtins
, sizeof(FunctionType
),
461 if (builtin_functions_i
) {
463 ftype
->func
= builtin_functions_i
->func
;
464 ftype
->numargs
= builtin_functions_i
->numargs
;
467 for (j
= 0; j
< builtin_functions_i
->numargs
&& *pstop_char
!= ','; j
++) {
468 ftype
->args
[j
].type
= builtin_functions_i
->args
[j
];
469 switch (builtin_functions_i
->args
[j
]) {
471 ptr
= DoGetNextToken(ptr
, &tok
, NULL
, ",", pstop_char
);
473 ConsoleMessage("%s: too few arguments\n",
474 builtin_functions_i
->name
);
479 if (extract_int(tok
, &ftype
->args
[j
].value
.int_value
) == 0) {
480 ConsoleMessage("%s: expect integer argument: %s\n",
481 builtin_functions_i
->name
, tok
);
491 ptr
= DoGetNextToken(ptr
, &ftype
->args
[j
].value
.string_value
,NULL
,
493 if (!ftype
->args
[j
].value
.string_value
) {
494 ConsoleMessage("%s: too few arguments\n",
495 builtin_functions_i
->name
);
497 Free(ftype
->args
[j
].value
.string_value
);
501 ftype
->args
[j
].type
= builtin_functions_i
->args
[j
];
507 ptr
= parse_button(ptr
, &ftype
->args
[j
], &flag
, pstop_char
);
509 ConsoleMessage("%s: too few arguments\n",
510 builtin_functions_i
->name
);
515 ftype
->args
[j
].type
= builtin_functions_i
->args
[j
];
518 /* JmpArg can be a string or an int. However, if 'JmpArg'
519 * is recorded as the argument type in the argument array
520 * for a command, it means it is a string; the code for
521 * 'IntArg' is used instead for numbers. Note also that
522 * if the C function recieves a 'JmpArg' argument it means something
523 * went wrong, since they should all be translated to integer
524 * jump offsets at compile time.
527 ptr
= DoGetNextToken(ptr
, &tok
, NULL
, ",", pstop_char
);
529 ConsoleMessage("%s: too few arguments\n",
530 builtin_functions_i
->name
);
536 if (extract_int(tok
, &ftype
->args
[j
].value
.int_value
) == 0) {
537 ftype
->args
[j
].value
.string_value
=tok
;
538 ftype
->args
[j
].type
= JmpArg
;
541 ftype
->args
[j
].type
= IntArg
;
547 ConsoleMessage("internal error in parse_function\n");
554 if (j
!= builtin_functions_i
->numargs
) {
555 ConsoleMessage("%s: too few arguments\n", builtin_functions_i
->name
);
565 ConsoleMessage("Unknown function: %s\n", name
);
573 /* This is O(N^2) where N = number of instructions. Seems we could do better.
574 We'll see how this addition settles before monkeying with it */
576 static Function
*parse_function_list(char *line
)
578 Function
*ret
= NULL
, *tail
= NULL
, *f
, *i
;
585 while (line
&& (f
= parse_function(&line
, &stop_char
))) {
586 ConsoleDebug(CONFIG
, "parse_function: 0x%lx\n", (unsigned long)f
->func
);
587 /* extra code to check for and remove a 'label' pseudo-function */
588 if (f
->func
==builtin_label
) {
589 /* scan backwards to fix up references */
591 for (i
=tail
; i
!=NULL
; i
=i
->prev
) {
592 /* scan the command arguments for a 'JmpArg' type */
593 for (j
=0; j
<(i
->numargs
); ++j
) {
594 if (i
->args
[j
].type
==JmpArg
) {
595 /* we have a winner! */
596 if (!strcasecmp(f
->args
[0].value
.string_value
,
597 i
->args
[j
].value
.string_value
)) {
598 /* the label matches it, so replace with the jump_count */
599 i
->args
[j
].type
= IntArg
;
600 i
->args
[j
].value
.int_value
= jump_count
;
607 Free(f
); /* label pseudo-functions never get added to the chain */
616 DoGetNextToken(line
, &token
, NULL
, ",", &c
);
617 if (token
&& stop_char
!= ',') {
618 ConsoleMessage("Bad function list, comma expected\n");
627 /* someone made a typo and we need to scan to find out what it
630 for (f
=tail
; f
; f
=f
->prev
) {
631 for (j
=0; j
<(f
->numargs
); ++j
) {
632 if (f
->args
[j
].type
==JmpArg
) {
633 ConsoleMessage("Attempt to jump to non-existant label %s; "
634 "aborting function list.\n",
635 f
->args
[j
].value
.string_value
);
641 ConsoleMessage( "Internal Error: JmpArgs %d not accounted for!\n",
645 free_function_list(ret
);
650 ConsoleMessage("No function defined\n");
655 Binding
*ParseMouseEntry(char *tline
)
657 char modifiers
[20],*action
,*token
;
663 /* tline points after the key word "key" */
664 action
= DoGetNextToken(tline
,&token
, NULL
, ",", NULL
);
666 n1
= sscanf(token
,"%d",&button
);
667 if (n1
== 1 && (button
< 0 || button
> NUMBER_OF_EXTENDED_MOUSE_BUTTONS
))
675 action
= DoGetNextToken(action
,&token
, NULL
, ",", NULL
);
677 n2
= sscanf(token
,"%19s",modifiers
);
680 if((n1
!= 1)||(n2
!= 1))
681 ConsoleMessage("Mouse binding: Syntax error");
683 modifiers_string_to_modmask(modifiers
, &mods
);
684 if((mods
& AnyModifier
)&&(mods
&(~AnyModifier
))) {
685 ConsoleMessage("Binding specified AnyModifier and other modifers too. "
686 "Excess modifiers will be ignored.");
689 new = (Binding
*)safemalloc(sizeof(Binding
));
690 memset(new, 0, sizeof(Binding
));
691 new->type
= BIND_BUTTONPRESS
;
692 new->Button_Key
= button
;
693 new->Modifier
= mods
;
694 new->Action
= stripcpy(action
);
695 new->Action2
= parse_function_list(action
);
698 ConsoleMessage("Bad action: %s\n", action
);
704 ConsoleDebug(CONFIG
, "Mouse: %d %d %s\n", new->Button_Key
,
705 new->Modifier
, (char*)new->Action
);
710 static Binding
*ParseKeyEntry(char *tline
)
712 char *action
,modifiers
[20],key
[20],*ptr
, *token
, *actionstring
, *keystring
;
713 Binding
*new = NULL
, *temp
, *last
= NULL
;
714 Function
*func
= NULL
;
720 /* tline points after the key word "key" */
723 ptr
= DoGetNextToken(ptr
,&token
, NULL
, ",", NULL
);
725 n1
= sscanf(token
,"%19s",key
);
729 action
= DoGetNextToken(ptr
,&token
, NULL
, ",", NULL
);
731 n2
= sscanf(token
,"%19s",modifiers
);
735 if((n1
!= 1)||(n2
!= 1))
736 ConsoleMessage("Syntax error in line %s",tline
);
738 modifiers_string_to_modmask(modifiers
, &mods
);
739 if((mods
& AnyModifier
)&&(mods
&(~AnyModifier
))) {
740 ConsoleMessage("Binding specified AnyModifier and other modifers too. Excess modifiers will be ignored.");
744 * Don't let a 0 keycode go through, since that means AnyKey to the
745 * XGrabKey call in GrabKeys().
747 if ((keysym
= XStringToKeysym(key
)) == NoSymbol
||
748 XKeysymToKeycode(theDisplay
, keysym
) == 0) {
749 ConsoleMessage("Can't find keysym: %s\n", key
);
754 XDisplayKeycodes(theDisplay
, &min
, &max
);
755 for (i
=min
; i
<=max
; i
++) {
756 if (XKeycodeToKeysym(theDisplay
, i
, 0) == keysym
) {
758 func
= parse_function_list(action
);
760 ConsoleMessage("Bad action: %s\n", action
);
763 actionstring
= stripcpy(action
);
764 keystring
= stripcpy(key
);
766 actionstring
= keystring
= NULL
;
769 new = (Binding
*)safemalloc(sizeof(Binding
));
770 memset(new, 0, sizeof(Binding
));
771 new->type
= BIND_KEYPRESS
;
773 new->key_name
= keystring
;
774 new->Modifier
= mods
;
775 new->Action
= actionstring
;
777 new->NextBinding
= temp
;
782 ConsoleDebug(CONFIG
, "Key: %d %s %d %s\n", i
, new->key_name
,
783 mods
, (char*)new->Action
);
789 static Binding
*ParseSimpleEntry(char *tline
)
794 func
= parse_function_list(tline
);
800 new = (Binding
*)safemalloc(sizeof(Binding
));
801 memset(new, 0, sizeof(Binding
));
802 new->type
= BIND_KEYPRESS
;
803 new->key_name
= "select";
804 new->Action
= stripcpy(tline
);
810 void run_binding(WinManager
*man
, Action action
)
812 Binding
*binding
= man
->bindings
[action
];
813 ConsoleDebug(CONFIG
, "run_binding:\n");
814 print_bindings(binding
);
816 if (binding
&& binding
->Action2
&&
817 ((Function
*)(binding
->Action2
))->func
)
819 run_function_list(binding
->Action2
);
823 void execute_function(char *string
)
825 Function
*func
= parse_function_list(string
);
832 run_function_list(func
);
833 free_function_list(func
);
837 static int GetConfigLineWrapper(int *fd
, char **tline
)
841 GetConfigLine(fd
, tline
);
844 if (strncasecmp(*tline
, "Colorset", 8) == 0)
846 LoadColorset(&(*tline
)[8]);
848 else if (strncasecmp(
849 *tline
, XINERAMA_CONFIG_STRING
,
850 sizeof(XINERAMA_CONFIG_STRING
) - 1) == 0)
852 FScreenConfigureModule(
853 (*tline
) + sizeof(XINERAMA_CONFIG_STRING
) - 1);
855 else if (strncasecmp(*tline
, "IgnoreModifiers", 15) == 0)
857 sscanf((*tline
) + 16, "%d", &mods_unused
);
859 temp
= strchr(*tline
, '\n');
864 /* grok the global config lines */
872 static char *read_next_cmd(ReadOption flag
)
874 static ReadOption status
;
876 static char *retstring
, *cur_pos
;
880 if (flag
!= READ_LINE
&& !(flag
& status
))
888 while (GetConfigLineWrapper(fvwm_fd
, &buffer
))
891 skip_space(&cur_pos
);
892 if (!strncasecmp(Module
, cur_pos
, ModuleLen
))
895 cur_pos
+= ModuleLen
;
901 skip_space(&cur_pos
);
903 if (isalnum(*cur_pos
))
905 status
= READ_OPTION
;
918 while (*cur_pos
!= '*' && !iswhite(*cur_pos
))
928 skip_space(&cur_pos
);
934 else if (isdigit(*retstring
) || !strncmp(
935 retstring
, "transient", 9))
937 status
= READ_OPTION
;
949 while (!iswhite(*cur_pos
))
955 skip_space(&cur_pos
);
969 case READ_REST_OF_LINE
:
975 if (retstring
&& retstring
[0] == '\0')
983 static char *conditional_copy_string(char **s1
, char *s2
)
991 return copy_string(s1
, s2
);
995 static NameType
parse_format_dependencies(char *format
)
997 NameType flags
= NO_NAME
;
999 ConsoleDebug(CONFIG
, "Parsing format: %s\n", format
);
1013 else if (*format
== 't')
1015 flags
|= TITLE_NAME
;
1017 else if (*format
== 'c')
1019 flags
|= CLASS_NAME
;
1021 else if (*format
== 'r')
1023 flags
|= RESOURCE_NAME
;
1025 else if (*format
!= '%')
1028 "Bad format string: %s\n", format
);
1032 #ifdef FVWM_DEBUG_MSGS
1033 ConsoleDebug(CONFIG
, "Format depends on: ");
1034 if (flags
& ICON_NAME
)
1036 ConsoleDebug(CONFIG
, "Icon ");
1038 if (flags
& TITLE_NAME
)
1040 ConsoleDebug(CONFIG
, "Title ");
1042 if (flags
& CLASS_NAME
)
1044 ConsoleDebug(CONFIG
, "Class ");
1046 if (flags
& RESOURCE_NAME
)
1048 ConsoleDebug(CONFIG
, "Resource ");
1050 ConsoleDebug(CONFIG
, "\n");
1056 #define SET_MANAGER(manager,field,value) \
1062 for (id = 0; id < globals.num_managers; id++) \
1064 globals.managers[id]. field = value; \
1067 else if (id < globals.num_managers) \
1069 globals.managers[id]. field = value; \
1074 "Internal error in SET_MANAGER: %d\n", id); \
1078 static void handle_button_config(int manager
, int context
, char *option
)
1083 p
= read_next_cmd(READ_ARG
);
1086 ConsoleMessage("Bad line: %s\n", current_line
);
1087 ConsoleMessage("Need argument to %s\n", option
);
1090 else if (!strcasecmp(p
, "flat"))
1092 state
= BUTTON_FLAT
;
1094 else if (!strcasecmp(p
, "up"))
1098 else if (!strcasecmp(p
, "down"))
1100 state
= BUTTON_DOWN
;
1102 else if (!strcasecmp(p
, "raisededge"))
1104 state
= BUTTON_EDGEUP
;
1106 else if (!strcasecmp(p
, "sunkedge"))
1108 state
= BUTTON_EDGEDOWN
;
1112 ConsoleMessage("Bad line: %s\n", current_line
);
1113 ConsoleMessage("This isn't a valid button state: %s\n", p
);
1117 CONFIG
, "Setting buttonState[%s] to %s\n",
1118 contextDefaults
[context
].name
, p
);
1119 SET_MANAGER(manager
, buttonState
[context
], state
);
1121 /* check for optional fore color */
1122 p
= read_next_cmd(READ_ARG
);
1129 manager
, foreColorName
[context
],
1130 copy_string(&globals
.managers
[id
]. foreColorName
[context
], p
));
1132 /* check for optional back color */
1133 p
= read_next_cmd(READ_ARG
);
1140 CONFIG
, "Setting backColorName[%s] to %s\n",
1141 contextDefaults
[context
].name
, p
);
1143 manager
, backColorName
[context
],
1144 copy_string(&globals
.managers
[id
].backColorName
[context
], p
));
1147 static void add_weighted_sort(WinManager
*man
, WeightedSort
*weighted_sort
)
1152 if (man
->weighted_sorts_len
== man
->weighted_sorts_size
)
1154 i
= man
->weighted_sorts_size
;
1155 man
->weighted_sorts_size
+= 16;
1156 man
->weighted_sorts
= (WeightedSort
*)saferealloc(
1157 (char *)man
->weighted_sorts
,
1158 man
->weighted_sorts_size
* sizeof(WeightedSort
));
1160 p
= &man
->weighted_sorts
[man
->weighted_sorts_len
];
1162 p
->classname
= NULL
;
1163 p
->titlename
= NULL
;
1165 if (weighted_sort
->resname
)
1167 copy_string(&p
->resname
, weighted_sort
->resname
);
1169 if (weighted_sort
->classname
)
1171 copy_string(&p
->classname
, weighted_sort
->classname
);
1173 if (weighted_sort
->titlename
)
1175 copy_string(&p
->titlename
, weighted_sort
->titlename
);
1177 if (weighted_sort
->iconname
)
1179 copy_string(&p
->iconname
, weighted_sort
->iconname
);
1181 p
->weight
= weighted_sort
->weight
;
1182 ++man
->weighted_sorts_len
;
1185 void read_in_resources(void)
1190 Binding
*binding
= NULL
;
1194 InitGetConfigLine(fvwm_fd
, Module
);
1196 while ((p
= read_next_cmd(READ_LINE
))) {
1197 ConsoleDebug(CONFIG
, "line: %s\n", p
);
1198 save_current_line(p
);
1200 option1
= read_next_cmd(READ_OPTION
);
1201 if (option1
== NULL
)
1204 ConsoleDebug(CONFIG
, "option1: %s\n", option1
);
1205 if (!strcasecmp(option1
, "nummanagers")) {
1206 /* If in transient mode, just use the default of 1 manager */
1207 if (!globals
.transient
) {
1208 p
= read_next_cmd(READ_ARG
);
1210 ConsoleMessage("Bad line: %s\n", current_line
);
1213 if (extract_int(p
, &n
) == 0) {
1214 ConsoleMessage("This is not a number: %s\n", p
);
1215 ConsoleMessage("Bad line: %s\n", current_line
);
1219 allocate_managers(n
);
1220 ConsoleDebug(CONFIG
, "num managers: %d\n", n
);
1223 ConsoleMessage("Bad line: %s\n", current_line
);
1224 ConsoleMessage("You can't have zero managers. "
1225 "I'll give you one.\n");
1226 allocate_managers(1);
1231 /* these all can specify a specific manager */
1233 if (globals
.managers
== NULL
) {
1234 ConsoleDebug(CONFIG
, "I'm assuming you only want one manager\n");
1235 allocate_managers(1);
1240 if (option1
[0] >= '0' && option1
[0] <= '9') {
1241 if (globals
.transient
) {
1242 ConsoleDebug(CONFIG
, "In transient mode. Ignoring this line\n");
1245 if (extract_int(option1
, &manager
) == 0 ||
1246 manager
<= 0 || manager
> globals
.num_managers
) {
1247 ConsoleMessage("Bad line: %s\n", current_line
);
1248 ConsoleMessage("This is not a valid manager: %s.\n", option1
);
1251 option1
= read_next_cmd(READ_OPTION
);
1253 ConsoleMessage("Bad line: %s\n", current_line
);
1257 else if (!strcasecmp(option1
, "transient")) {
1258 if (globals
.transient
) {
1259 ConsoleDebug(CONFIG
, "Transient manager config line\n");
1261 option1
= read_next_cmd(READ_OPTION
);
1263 ConsoleMessage("Bad line: %s\n", current_line
);
1268 ConsoleDebug(CONFIG
, "Not in transient mode. Ignoring this line\n");
1273 manager
--; /* -1 means global */
1275 ConsoleDebug(CONFIG
, "Applying %s to manager %d\n", option1
, manager
);
1277 if (!strcasecmp(option1
, "action")) {
1278 p
= read_next_cmd(READ_ARG
);
1280 ConsoleMessage("Bad line: %s\n", current_line
);
1284 if (!strcasecmp(p
, "mouse")) {
1287 else if (!strcasecmp(p
, "key")) {
1290 else if (!strcasecmp(p
, "select")) {
1294 ConsoleMessage("Bad line: %s\n", current_line
);
1295 ConsoleMessage("This isn't a valid action name: %s\n", p
);
1299 q
= read_next_cmd(READ_REST_OF_LINE
);
1301 ConsoleMessage("Bad line: %s\n", current_line
);
1302 ConsoleMessage("Need an action\n");
1308 binding
= ParseMouseEntry(q
);
1312 binding
= ParseKeyEntry(q
);
1316 binding
= ParseSimpleEntry(q
);
1320 if (binding
== NULL
) {
1321 ConsoleMessage("Offending line: %s\n", current_line
);
1322 ConsoleMessage("Bad action\n");
1326 if (manager
== -1) {
1328 for (j
= 0; j
< globals
.num_managers
; j
++) {
1329 add_to_binding(&globals
.managers
[j
].bindings
[i
], binding
);
1332 else if (manager
< globals
.num_managers
) {
1333 add_to_binding(&globals
.managers
[manager
].bindings
[i
], binding
);
1336 ConsoleMessage("Bad line: %s\n", current_line
);
1337 ConsoleMessage("There's no manager %d\n", manager
);
1340 else if (!strcasecmp(option1
, "colorset")) {
1341 p
= read_next_cmd(READ_ARG
);
1343 ConsoleMessage("Bad line: %s\n", current_line
);
1346 if (extract_int(p
, &n
) == 0) {
1347 ConsoleMessage("This is not a number: %s\n", p
);
1348 ConsoleMessage("Bad line: %s\n", current_line
);
1351 for ( i
= 0; i
< NUM_CONTEXTS
; i
++ ) {
1352 if (i
!= DEFAULT
&& i
!= TITLE_CONTEXT
)
1353 SET_MANAGER(manager
, colorsets
[i
], -2);
1355 SET_MANAGER(manager
, colorsets
[i
], n
);
1359 else if (!strcasecmp(option1
, "background")) {
1360 p
= read_next_cmd(READ_ARG
);
1362 ConsoleMessage("Bad line: %s\n", current_line
);
1365 ConsoleDebug(CONFIG
, "default background: %s\n", p
);
1367 for ( i
= 0; i
< NUM_CONTEXTS
; i
++ )
1368 SET_MANAGER(manager
, backColorName
[i
],
1369 conditional_copy_string(&globals
.managers
[id
].backColorName
[i
],
1372 else if (!strcasecmp(option1
, "buttongeometry")) {
1373 p
= read_next_cmd(READ_ARG
);
1375 ConsoleMessage("Bad line: %s\n", current_line
);
1379 SET_MANAGER(manager
, button_geometry_str
,
1380 copy_string(&globals
.managers
[id
].button_geometry_str
, p
));
1382 else if (!strcasecmp(option1
, "maxbuttonwidth")) {
1383 p
= read_next_cmd(READ_ARG
);
1387 else if (extract_int(p
, &n
) == 0) {
1388 ConsoleMessage("This is not a number: %s\n", p
);
1389 ConsoleMessage("Bad line: %s\n", current_line
);
1392 SET_MANAGER(manager
, max_button_width
, n
);
1393 SET_MANAGER(manager
, max_button_width_columns
, 0);
1395 else if (!strcasecmp(option1
, "maxbuttonwidthbycolumns")) {
1396 p
= read_next_cmd(READ_ARG
);
1400 else if (extract_int(p
, &n
) == 0) {
1401 ConsoleMessage("This is not a number: %s\n", p
);
1402 ConsoleMessage("Bad line: %s\n", current_line
);
1405 SET_MANAGER(manager
, max_button_width
, 0);
1406 SET_MANAGER(manager
, max_button_width_columns
, n
);
1408 else if (!strcasecmp(option1
, "dontshow")) {
1410 p
= read_next_cmd(READ_REST_OF_LINE
);
1412 ConsoleMessage("Bad line: %s\n", current_line
);
1415 p
= DoGetNextToken(p
, &token
, NULL
, ",", NULL
);
1417 ConsoleMessage("Bad line: %s\n", current_line
);
1421 ConsoleDebug(CONFIG
, "dont show: %s\n", token
);
1422 if (manager
== -1) {
1424 for (i
= 0; i
< globals
.num_managers
; i
++)
1425 add_to_stringlist(&globals
.managers
[i
].dontshow
, token
);
1428 add_to_stringlist(&globals
.managers
[manager
].dontshow
, token
);
1431 p
= DoGetNextToken(p
, &token
, NULL
, ",", NULL
);
1436 else if (!strcasecmp(option1
, "drawicons")) {
1437 if (!FMiniIconsSupported
)
1439 ConsoleMessage("DrawIcons support not compiled in\n");
1443 p
= read_next_cmd(READ_ARG
);
1445 ConsoleMessage("Bad line: %s\n", current_line
);
1446 ConsoleMessage("Need argument to drawicons\n");
1449 if (!strcasecmp(p
, "true")) {
1452 /* [NFM 3 Dec 97] added support for drawicons "always" */
1453 else if (!strcasecmp(p
, "always")) {
1456 else if (!strcasecmp(p
, "false")) {
1460 ConsoleMessage("Bad line: %s\n", current_line
);
1461 ConsoleMessage("What is this: %s?\n", p
);
1464 ConsoleDebug(CONFIG
, "Setting drawicons to: %d\n", i
);
1465 SET_MANAGER(manager
, draw_icons
, i
);
1468 else if (!strcasecmp(option1
, "followfocus")) {
1469 p
= read_next_cmd(READ_ARG
);
1471 ConsoleMessage("Bad line: %s\n", current_line
);
1472 ConsoleMessage("Need argument to followfocus\n");
1475 if (!strcasecmp(p
, "true")) {
1478 else if (!strcasecmp(p
, "false")) {
1482 ConsoleMessage("Bad line: %s\n", current_line
);
1483 ConsoleMessage("What is this: %s?\n", p
);
1486 ConsoleDebug(CONFIG
, "Setting followfocus to: %d\n", i
);
1487 SET_MANAGER(manager
, followFocus
, i
);
1489 else if (!strcasecmp(option1
, "showtransient")) {
1490 p
= read_next_cmd(READ_ARG
);
1492 ConsoleMessage("Bad line: %s\n", current_line
);
1493 ConsoleMessage("Need argument to showtransient\n");
1496 if (!strcasecmp(p
, "true")) {
1499 else if (!strcasecmp(p
, "false")) {
1503 ConsoleMessage("Bad line: %s\n", current_line
);
1504 ConsoleMessage("What is this: %s?\n", p
);
1507 ConsoleDebug(CONFIG
, "Setting showtransient to: %d\n", i
);
1508 SET_MANAGER(manager
, showtransient
, i
);
1510 else if( !strcasecmp(option1
, "showonlyfocused")) {
1511 p
= read_next_cmd(READ_ARG
);
1513 ConsoleMessage("Bad line: %s\n", current_line
);
1514 ConsoleMessage("Need argument to showonlyfocused\n");
1517 if (!strcasecmp(p
, "true")) {
1520 else if (!strcasecmp(p
, "false")) {
1524 ConsoleMessage("Bad line: %s\n", current_line
);
1525 ConsoleMessage("What is this: %s?\n", p
);
1528 ConsoleMessage("Show only focused to: %d\n", i
);
1529 SET_MANAGER( manager
, showonlyfocused
, i
);
1531 else if (!strcasecmp(option1
, "showonlyicons")) {
1532 p
= read_next_cmd(READ_ARG
);
1534 ConsoleMessage("Bad line: %s\n", current_line
);
1535 ConsoleMessage("Need argument to showonlyicons\n");
1538 if (!strcasecmp(p
, "true")) {
1541 else if (!strcasecmp(p
, "false")) {
1545 ConsoleMessage("Bad line: %s\n", current_line
);
1546 ConsoleMessage("What is this: %s?\n", p
);
1549 ConsoleDebug(CONFIG
, "Setting showonlyicons to: %d\n", i
);
1550 SET_MANAGER(manager
, showonlyiconic
, i
);
1552 else if (!strcasecmp(option1
, "shownoicons")) {
1553 p
= read_next_cmd(READ_ARG
);
1555 ConsoleMessage("Bad line: %s\n", current_line
);
1556 ConsoleMessage("Need argument to shownoicons\n");
1559 if (!strcasecmp(p
, "true")) {
1562 else if (!strcasecmp(p
, "false")) {
1566 ConsoleMessage("Bad line: %s\n", current_line
);
1567 ConsoleMessage("What is this: %s?\n", p
);
1570 ConsoleDebug(CONFIG
, "Setting shownoicons to: %d\n", i
);
1571 SET_MANAGER(manager
, shownoiconic
, i
);
1573 else if (!strcasecmp(option1
, "font")) {
1575 p
= read_next_cmd(READ_REST_OF_LINE
);
1578 ConsoleMessage("Bad line: %s\n", current_line
);
1581 CopyStringWithQuotes(&f
, p
);
1582 ConsoleDebug(CONFIG
, "font: %s\n", f
);
1584 SET_MANAGER(manager
, fontname
,
1585 copy_string(&globals
.managers
[id
].fontname
, f
));
1588 else if (!strcasecmp(option1
, "foreground")) {
1589 p
= read_next_cmd(READ_ARG
);
1591 ConsoleMessage("Bad line: %s\n", current_line
);
1594 ConsoleDebug(CONFIG
, "default foreground: %s\n", p
);
1596 for ( i
= 0; i
< NUM_CONTEXTS
; i
++ )
1597 SET_MANAGER(manager
, foreColorName
[i
],
1598 conditional_copy_string(&globals
.managers
[id
].foreColorName
[i
],
1601 else if (!strcasecmp(option1
, "format")) {
1605 p
= read_next_cmd(READ_REST_OF_LINE
);
1607 ConsoleMessage("Bad line: %s\n", current_line
);
1610 DoGetNextToken(p
, &token
, NULL
, ",", NULL
);
1613 token
= (char *)safemalloc(1);
1617 SET_MANAGER(manager
, formatstring
,
1618 copy_string (&globals
.managers
[id
].formatstring
, token
));
1619 flags
= parse_format_dependencies(token
);
1620 SET_MANAGER(manager
, format_depend
, flags
);
1623 else if (!strcasecmp(option1
, "geometry")) {
1624 ConsoleMessage("Geometry option no longer supported.\n");
1625 ConsoleMessage("Use ManagerGeometry and ButtonGeometry.\n");
1627 else if (!strcasecmp(option1
, "iconname")) {
1629 p
= read_next_cmd(READ_REST_OF_LINE
);
1631 ConsoleMessage("Bad line: %s\n", current_line
);
1634 DoGetNextToken(p
, &token
, NULL
, ",", NULL
);
1637 token
= (char *)safemalloc(1);
1641 SET_MANAGER(manager
, iconname
,
1642 copy_string(&globals
.managers
[id
].iconname
, token
));
1645 else if (!strcasecmp(option1
, "managergeometry")) {
1646 p
= read_next_cmd(READ_ARG
);
1648 ConsoleMessage("Bad line: %s\n", current_line
);
1652 SET_MANAGER(manager
, geometry_str
,
1653 copy_string(&globals
.managers
[id
].geometry_str
, p
));
1655 else if (!strcasecmp(option1
, "resolution")) {
1656 p
= read_next_cmd(READ_ARG
);
1658 ConsoleMessage("Bad line: %s\n", current_line
);
1661 ConsoleDebug(CONFIG
, "resolution: %s\n", p
);
1662 if (!strcasecmp(p
, "global"))
1664 else if (!strcasecmp(p
, "desk"))
1666 else if (!strcasecmp(p
, "page"))
1668 else if (!strcasecmp(p
, "screen"))
1670 else if (!strcasecmp(p
, "!desk"))
1671 r
= NO_SHOW_DESKTOP
;
1672 else if (!strcasecmp(p
, "!page"))
1674 else if (!strcasecmp(p
, "!screen"))
1677 ConsoleMessage("Bad line: %s\n", current_line
);
1678 ConsoleMessage("What kind of resolution is this?\n");
1682 SET_MANAGER(manager
, res
, r
);
1684 else if (!strcasecmp(option1
, "reverse")) {
1685 p
= read_next_cmd(READ_ARG
);
1687 ConsoleMessage("Bad line: %s\n", current_line
);
1690 ConsoleDebug(CONFIG
, "reverse: %s\n", p
);
1691 if (!strcasecmp(p
, "none"))
1693 else if (!strcasecmp(p
, "icon"))
1695 else if (!strcasecmp(p
, "normal"))
1696 rv
= REVERSE_NORMAL
;
1698 ConsoleMessage("Bad line: %s\n", current_line
);
1699 ConsoleMessage("What kind of reverse is this?\n");
1703 SET_MANAGER(manager
, rev
, rv
);
1705 else if (!strcasecmp(option1
, "shape")) {
1706 p
= read_next_cmd(READ_ARG
);
1708 ConsoleMessage("Bad line: %s\n", current_line
);
1709 ConsoleMessage("Need argument to shape\n");
1712 if (!strcasecmp(p
, "true")) {
1715 else if (!strcasecmp(p
, "false")) {
1719 ConsoleMessage("Bad line: %s\n", current_line
);
1720 ConsoleMessage("What is this: %s?\n", p
);
1723 if (!FHaveShapeExtension
&& i
) {
1724 ConsoleMessage("Shape support not compiled in\n");
1727 ConsoleDebug(CONFIG
, "Setting shape to: %d\n", i
);
1728 SET_MANAGER(manager
, shaped
, i
);
1730 else if (!strcasecmp(option1
, "show")) {
1732 p
= read_next_cmd(READ_REST_OF_LINE
);
1734 ConsoleMessage("Bad line: %s\n", current_line
);
1737 p
= DoGetNextToken(p
, &token
, NULL
, ",", NULL
);
1739 ConsoleMessage("Bad line: %s\n", current_line
);
1743 ConsoleDebug(CONFIG
, "show: %s\n", token
);
1744 if (manager
== -1) {
1746 for (i
= 0; i
< globals
.num_managers
; i
++)
1747 add_to_stringlist(&globals
.managers
[i
].show
, token
);
1750 add_to_stringlist(&globals
.managers
[manager
].show
, token
);
1753 p
= DoGetNextToken(p
, &token
, NULL
, ",", NULL
);
1758 else if (!strcasecmp(option1
, "showtitle")) {
1759 ConsoleMessage("Bad line: %s\n", current_line
);
1760 ConsoleMessage("showtitle is no longer an option. Use format\n");
1763 else if (!strcasecmp(option1
, "sort")) {
1764 p
= read_next_cmd(READ_ARG
);
1766 ConsoleMessage("Bad line: %s\n", current_line
);
1767 ConsoleMessage("Need argument to sort\n");
1770 if (!strcasecmp(p
, "name")) {
1773 else if (!strcasecmp(p
, "namewithcase")) {
1776 else if (!strcasecmp(p
, "id")) {
1779 else if (!strcasecmp(p
, "none")) {
1782 else if (!strcasecmp(p
, "weighted")) {
1785 else if (!strcasecmp(p
, "false") || !strcasecmp(p
, "true")) {
1787 ConsoleMessage("FvwmIconMan: sort option no longer takes "
1788 "true or false value\n"
1789 "Please read the latest manpage\n");
1793 ConsoleMessage("Bad line: %s\n", current_line
);
1794 ConsoleMessage("What is this: %s?\n", p
);
1797 ConsoleDebug(CONFIG
, "Setting sort to: %d\n", i
);
1798 SET_MANAGER(manager
, sort
, i
);
1800 else if (!strcasecmp(option1
, "sortweight")) {
1801 WeightedSort weighted_sort
;
1802 p
= read_next_cmd(READ_ARG
);
1804 ConsoleMessage("Bad line: %s\n", current_line
);
1807 if (extract_int(p
, &n
) == 0) {
1808 ConsoleMessage("This is not a number: %s\n", p
);
1809 ConsoleMessage("Bad line: %s\n", current_line
);
1812 weighted_sort
.resname
= NULL
;
1813 weighted_sort
.classname
= NULL
;
1814 weighted_sort
.titlename
= NULL
;
1815 weighted_sort
.iconname
= NULL
;
1816 weighted_sort
.weight
= n
;
1817 p
= read_next_cmd(READ_ARG
);
1819 if (!strncasecmp(p
, "resource=", 9)) {
1820 copy_string(&weighted_sort
.resname
, p
+ 9);
1821 } else if (!strncasecmp(p
, "class=", 6)) {
1822 copy_string(&weighted_sort
.classname
, p
+ 6);
1823 } else if (!strncasecmp(p
, "title=", 6)) {
1824 copy_string(&weighted_sort
.titlename
, p
+ 6);
1825 } else if (!strncasecmp(p
, "icon=", 5)) {
1826 copy_string(&weighted_sort
.iconname
, p
+ 5);
1828 ConsoleMessage("Unknown sortweight field: %s\n", p
);
1829 ConsoleMessage("Bad line: %s\n", current_line
);
1831 p
= read_next_cmd(READ_ARG
);
1833 if (manager
== -1) {
1834 for (i
= 0; i
< globals
.num_managers
; i
++) {
1835 add_weighted_sort(&globals
.managers
[i
], &weighted_sort
);
1839 add_weighted_sort(&globals
.managers
[manager
], &weighted_sort
);
1841 if (weighted_sort
.resname
) {
1842 Free(weighted_sort
.resname
);
1844 if (weighted_sort
.resname
) {
1845 Free(weighted_sort
.classname
);
1847 if (weighted_sort
.resname
) {
1848 Free(weighted_sort
.titlename
);
1850 if (weighted_sort
.resname
) {
1851 Free(weighted_sort
.iconname
);
1854 else if (!strcasecmp(option1
, "NoIconAction")) {
1856 p
= read_next_cmd(READ_REST_OF_LINE
);
1858 ConsoleMessage("Bad line: %s\n", current_line
);
1861 DoGetNextToken(p
, &token
, NULL
, ",", NULL
);
1864 token
= (char *)safemalloc(1);
1868 SET_MANAGER(manager
, AnimCommand
,
1869 copy_string(&globals
.managers
[id
].AnimCommand
, token
));
1872 else if (!strcasecmp(option1
, "title")) {
1874 p
= read_next_cmd(READ_REST_OF_LINE
);
1876 ConsoleMessage("Bad line: %s\n", current_line
);
1879 DoGetNextToken(p
, &token
, NULL
, ",", NULL
);
1882 token
= (char *)safemalloc(1);
1886 SET_MANAGER(manager
, titlename
,
1887 copy_string(&globals
.managers
[id
].titlename
, token
));
1890 else if (!strcasecmp(option1
, "iconButton")) {
1891 handle_button_config(manager
, ICON_CONTEXT
, option1
);
1893 else if (!strcasecmp(option1
, "plainButton")) {
1894 handle_button_config(manager
, PLAIN_CONTEXT
, option1
);
1896 else if (!strcasecmp(option1
, "selectButton")) {
1897 handle_button_config(manager
, SELECT_CONTEXT
, option1
);
1899 else if (!strcasecmp(option1
, "focusButton")) {
1900 handle_button_config(manager
, FOCUS_CONTEXT
, option1
);
1902 else if (!strcasecmp(option1
, "focusandselectButton")) {
1903 handle_button_config(manager
, FOCUS_SELECT_CONTEXT
, option1
);
1905 else if (!strcasecmp(option1
, "titlebutton")) {
1906 handle_button_config(manager
, TITLE_CONTEXT
, option1
);
1908 else if (!strcasecmp(option1
, "titlecolorset")) {
1909 p
= read_next_cmd(READ_ARG
);
1911 ConsoleMessage("Bad line: %s\n", current_line
);
1914 if (extract_int(p
, &n
) == 0) {
1915 ConsoleMessage("This is not a number: %s\n", p
);
1916 ConsoleMessage("Bad line: %s\n", current_line
);
1919 SET_MANAGER(manager
, colorsets
[TITLE_CONTEXT
], n
);
1922 else if (!strcasecmp(option1
, "focusandselectcolorset")) {
1923 p
= read_next_cmd(READ_ARG
);
1925 ConsoleMessage("Bad line: %s\n", current_line
);
1928 if (extract_int(p
, &n
) == 0) {
1929 ConsoleMessage("This is not a number: %s\n", p
);
1930 ConsoleMessage("Bad line: %s\n", current_line
);
1933 SET_MANAGER(manager
, colorsets
[FOCUS_SELECT_CONTEXT
], n
);
1936 else if (!strcasecmp(option1
, "focuscolorset")) {
1937 p
= read_next_cmd(READ_ARG
);
1939 ConsoleMessage("Bad line: %s\n", current_line
);
1942 if (extract_int(p
, &n
) == 0) {
1943 ConsoleMessage("This is not a number: %s\n", p
);
1944 ConsoleMessage("Bad line: %s\n", current_line
);
1947 SET_MANAGER(manager
, colorsets
[FOCUS_CONTEXT
], n
);
1950 else if (!strcasecmp(option1
, "selectcolorset")) {
1951 p
= read_next_cmd(READ_ARG
);
1953 ConsoleMessage("Bad line: %s\n", current_line
);
1956 if (extract_int(p
, &n
) == 0) {
1957 ConsoleMessage("This is not a number: %s\n", p
);
1958 ConsoleMessage("Bad line: %s\n", current_line
);
1961 SET_MANAGER(manager
, colorsets
[SELECT_CONTEXT
], n
);
1964 else if (!strcasecmp(option1
, "plaincolorset")) {
1965 p
= read_next_cmd(READ_ARG
);
1967 ConsoleMessage("Bad line: %s\n", current_line
);
1970 if (extract_int(p
, &n
) == 0) {
1971 ConsoleMessage("This is not a number: %s\n", p
);
1972 ConsoleMessage("Bad line: %s\n", current_line
);
1975 SET_MANAGER(manager
, colorsets
[PLAIN_CONTEXT
], n
);
1978 else if (!strcasecmp(option1
, "iconcolorset")) {
1979 p
= read_next_cmd(READ_ARG
);
1981 ConsoleMessage("Bad line: %s\n", current_line
);
1984 if (extract_int(p
, &n
) == 0) {
1985 ConsoleMessage("This is not a number: %s\n", p
);
1986 ConsoleMessage("Bad line: %s\n", current_line
);
1989 SET_MANAGER(manager
, colorsets
[ICON_CONTEXT
], n
);
1992 else if (!strcasecmp(option1
, "usewinlist")) {
1993 p
= read_next_cmd(READ_ARG
);
1995 ConsoleMessage("Bad line: %s\n", current_line
);
1996 ConsoleMessage("Need argument to usewinlist\n");
1999 if (!strcasecmp(p
, "true")) {
2002 else if (!strcasecmp(p
, "false")) {
2006 ConsoleMessage("Bad line: %s\n", current_line
);
2007 ConsoleMessage("What is this: %s?\n", p
);
2010 ConsoleDebug(CONFIG
, "Setting usewinlist to: %d\n", i
);
2011 SET_MANAGER(manager
, usewinlist
, i
);
2013 else if (!strcasecmp(option1
, "reliefthickness")) {
2014 p
= read_next_cmd(READ_ARG
);
2016 ConsoleMessage("Bad line: %s\n", current_line
);
2019 if (extract_int(p
, &n
) == 0) {
2020 ConsoleMessage("This is not a number: %s\n", p
);
2021 ConsoleMessage("Bad line: %s\n", current_line
);
2024 SET_MANAGER(manager
, relief_thickness
, n
);
2026 else if (!strcasecmp(option1
, "tips")) {
2027 p
= read_next_cmd(READ_ARG
);
2029 ConsoleMessage("Bad line: %s\n", current_line
);
2032 if (!strcasecmp(p
, "always")) {
2036 else if (!strcasecmp(p
, "false")) {
2039 else if (!strcasecmp(p
, "needed")) {
2043 ConsoleMessage("Bad line: %s\n", current_line
);
2044 ConsoleMessage("What is this: %s?\n", p
);
2047 SET_MANAGER(manager
, tips
, i
);
2049 else if (!strcasecmp(option1
, "tipsfont")) {
2051 p
= read_next_cmd(READ_REST_OF_LINE
);
2054 ConsoleMessage("Bad line: %s\n", current_line
);
2057 CopyStringWithQuotes(&f
, p
);
2058 ConsoleDebug(CONFIG
, "tipsfont: %s\n", f
);
2060 SET_MANAGER(manager
, tips_fontname
,
2061 copy_string(&globals
.managers
[id
].tips_fontname
, f
));
2064 else if (!strcasecmp(option1
, "tipscolorset")) {
2065 p
= read_next_cmd(READ_ARG
);
2067 ConsoleMessage("Bad line: %s\n", current_line
);
2070 if (extract_int(p
, &n
) == 0) {
2071 ConsoleMessage("This is not a number: %s\n", p
);
2072 ConsoleMessage("Bad line: %s\n", current_line
);
2075 SET_MANAGER(manager
, tips_conf
->colorset
, n
);
2081 else if (!strcasecmp(option1
, "tipsdelays")) {
2082 p
= read_next_cmd(READ_ARG
);
2084 ConsoleMessage("Bad line: %s\n", current_line
);
2087 if (extract_int(p
, &n
) == 0) {
2088 ConsoleMessage("This is not a number: %s\n", p
);
2089 ConsoleMessage("Bad line: %s\n", current_line
);
2093 ConsoleMessage("No negative delay: %s\n", p
);
2094 ConsoleMessage("Bad line: %s\n", current_line
);
2097 SET_MANAGER(manager
, tips_conf
->delay
, n
);
2098 p
= read_next_cmd(READ_ARG
);
2101 SET_MANAGER(manager
, tips_conf
->mapped_delay
, n
);
2104 if (extract_int(p
, &n
) == 0) {
2105 ConsoleMessage("This is not a number: %s\n", p
);
2106 ConsoleMessage("Bad line: %s\n", current_line
);
2110 ConsoleMessage("No negative delay: %s\n", p
);
2111 ConsoleMessage("Bad line: %s\n", current_line
);
2114 SET_MANAGER(manager
, tips_conf
->mapped_delay
, n
);
2116 else if (!strcasecmp(option1
, "tipsformat")) {
2120 p
= read_next_cmd(READ_REST_OF_LINE
);
2122 ConsoleMessage("Bad line: %s\n", current_line
);
2125 DoGetNextToken(p
, &token
, NULL
, ",", NULL
);
2128 token
= (char *)safemalloc(1);
2132 SET_MANAGER(manager
, tips_formatstring
,
2134 &globals
.managers
[id
].tips_formatstring
, token
));
2136 flags
= parse_format_dependencies(token
);
2137 SET_MANAGER(manager
, format_depend
, flags
);
2141 else if (!strcasecmp(option1
, "tipsborderwidth")) {
2142 p
= read_next_cmd(READ_ARG
);
2144 ConsoleMessage("Bad line: %s\n", current_line
);
2147 if (extract_int(p
, &n
) == 0) {
2148 ConsoleMessage("This is not a number: %s\n", p
);
2149 ConsoleMessage("Bad line: %s\n", current_line
);
2156 SET_MANAGER(manager
, tips_conf
->border_width
, n
);
2158 else if (!strcasecmp(option1
, "tipsoffsets")) {
2159 p
= read_next_cmd(READ_ARG
);
2161 ConsoleMessage("Bad line: %s\n", current_line
);
2164 if (extract_int(p
, &n
) == 0) {
2165 ConsoleMessage("This is not a number: %s\n", p
);
2166 ConsoleMessage("Bad line: %s\n", current_line
);
2170 ConsoleMessage("A tips offset must be positive: %s\n", p
);
2171 ConsoleMessage("Bad line: %s\n", current_line
);
2174 SET_MANAGER(manager
, tips_conf
->placement_offset
, n
);
2175 p
= read_next_cmd(READ_ARG
);
2178 ConsoleMessage("Bad line: %s\n", current_line
);
2181 if (extract_int(p
, &n
) == 0) {
2182 ConsoleMessage("This is not a number: %s\n", p
);
2183 ConsoleMessage("Bad line: %s\n", current_line
);
2187 ConsoleMessage("A tips offset must be positive: %s\n", p
);
2188 ConsoleMessage("Bad line: %s\n", current_line
);
2191 SET_MANAGER(manager
, tips_conf
->justification_offset
, n
);
2193 else if (!strcasecmp(option1
, "tipsplacement")) {
2194 p
= read_next_cmd(READ_ARG
);
2196 ConsoleMessage("Bad line: %s\n", current_line
);
2199 if (!strcasecmp(p
, "up")) {
2200 i
= FTIPS_PLACEMENT_UP
;
2202 else if (!strcasecmp(p
, "down")) {
2203 i
= FTIPS_PLACEMENT_DOWN
;
2205 else if (!strcasecmp(p
, "left")) {
2206 i
= FTIPS_PLACEMENT_LEFT
;
2208 else if (!strcasecmp(p
, "right")) {
2209 i
= FTIPS_PLACEMENT_RIGHT
;
2211 else if (!strcasecmp(p
, "updown")) {
2212 i
= FTIPS_PLACEMENT_AUTO_UPDOWN
;
2214 else if (!strcasecmp(p
, "leftright")) {
2215 i
= FTIPS_PLACEMENT_AUTO_LEFTRIGHT
;
2218 ConsoleMessage("Bad line: %s\n", current_line
);
2219 ConsoleMessage("What is this: %s?\n", p
);
2222 SET_MANAGER(manager
, tips_conf
->placement
, i
);
2224 else if (!strcasecmp(option1
, "tipsjustification")) {
2225 p
= read_next_cmd(READ_ARG
);
2227 ConsoleMessage("Bad line: %s\n", current_line
);
2230 if (!strcasecmp(p
, "center")) {
2231 i
= FTIPS_JUSTIFICATION_CENTER
;
2233 else if (!strcasecmp(p
, "leftup")) {
2234 i
= FTIPS_JUSTIFICATION_LEFT_UP
;
2236 else if (!strcasecmp(p
, "rightdown")) {
2237 i
= FTIPS_JUSTIFICATION_RIGHT_DOWN
;
2240 ConsoleMessage("Bad line: %s\n", current_line
);
2241 ConsoleMessage("What is this: %s?\n", p
);
2244 SET_MANAGER(manager
, tips_conf
->justification
, i
);
2247 ConsoleMessage("Bad line: %s\n", current_line
);
2248 ConsoleMessage("Unknown option: %s\n", p
);
2253 if (globals
.managers
== NULL
) {
2254 ConsoleDebug(CONFIG
, "I'm assuming you only want one manager\n");
2255 allocate_managers(1);
2260 void process_dynamic_config_line(char *line
)
2264 extern void remanage_winlist(void);
2266 /* don't support dynamic config for transient */
2267 if (globals
.transient
)
2273 line
= GetNextToken(line
, &token
);
2274 if (token
&& isdigit(*token
))
2276 if (extract_int(token
, &manager
) == 0
2277 || manager
<= 0 || manager
> globals
.num_managers
)
2282 line
= GetNextToken(line
, &token
);
2291 /* currently supports only "resolution" and "tips" */
2292 if (strcasecmp(token
, "resolution") == 0)
2297 line
= GetNextToken(line
, &token
);
2302 if (!strcasecmp(token
, "global"))
2303 value
= SHOW_GLOBAL
;
2304 else if (!strcasecmp(token
, "desk"))
2305 value
= SHOW_DESKTOP
;
2306 else if (!strcasecmp(token
, "page"))
2308 else if (!strcasecmp(token
, "screen"))
2309 value
= SHOW_SCREEN
;
2310 else if (!strcasecmp(token
, "!desk"))
2311 value
= NO_SHOW_DESKTOP
;
2312 else if (!strcasecmp(token
, "!page"))
2313 value
= NO_SHOW_PAGE
;
2314 else if (!strcasecmp(token
, "!screen"))
2315 value
= NO_SHOW_SCREEN
;
2319 stderr
, "%s: unknown resolution %s.\n",
2325 SET_MANAGER(manager
, res
, value
);
2328 else if (strcasecmp(token
, "tips") == 0)
2333 line
= GetNextToken(line
, &token
);
2338 if (!strcasecmp(token
, "always"))
2340 value
= TIPS_ALWAYS
;
2342 else if (!strcasecmp(token
, "false"))
2346 else if (!strcasecmp(token
, "needed"))
2348 value
= TIPS_NEEDED
;
2352 ConsoleMessage("Bad line: %s\n", line
);
2353 ConsoleMessage("What is this: %s?\n", token
);
2357 SET_MANAGER(manager
, tips
, value
);
2364 tips_cancel(&globals
.managers
[manager
]);