#include #include #include "FvwmIconMan.h" #include "readconfig.h" static char const rcsid[] = "$Id: readconfig.c,v 1.1.1.1 2006/11/26 10:53:50 matthieu Exp $"; /************************************************************************ * * Builtin functions: * ************************************************************************/ extern int builtin_quit (int numargs, BuiltinArg *args); extern int builtin_printdebug (int numargs, BuiltinArg *args); extern int builtin_gotobutton (int numargs, BuiltinArg *args); extern int builtin_gotomanager (int numargs, BuiltinArg *args); extern int builtin_refresh (int numargs, BuiltinArg *args); extern int builtin_select (int numargs, BuiltinArg *args); extern int builtin_sendcommand (int numargs, BuiltinArg *args); extern int builtin_bif (int numargs, BuiltinArg *args); extern int builtin_bifn (int numargs, BuiltinArg *args); extern int builtin_print (int numargs, BuiltinArg *args); extern int builtin_jmp (int numargs, BuiltinArg *args); extern int builtin_ret (int numargs, BuiltinArg *args); extern int builtin_searchforward (int numargs, BuiltinArg *args); extern int builtin_searchback (int numargs, BuiltinArg *args); extern int builtin_warp (int numargs, BuiltinArg *args); /* compiler pseudo-functions */ static int builtin_label (int numargs, BuiltinArg *args); typedef struct { char *name; int (*func)(int numargs, BuiltinArg *args); int numargs; BuiltinArgType args[MAX_ARGS]; } FunctionType; /* * these are now sorted so we can use bsearch on them. */ FunctionType builtin_functions[] = { { "bif", builtin_bif, 2, { ButtonArg, JmpArg } }, { "bifn", builtin_bifn, 2, { ButtonArg, JmpArg } }, { "gotobutton", builtin_gotobutton, 1, { ButtonArg } }, { "gotomanager", builtin_gotomanager, 1, { ManagerArg } }, { "jmp", builtin_jmp, 1, { JmpArg } }, { "label", builtin_label, 1, { StringArg } }, { "print", builtin_print, 1, { StringArg } }, { "printdebug", builtin_printdebug, 0 }, { "quit", builtin_quit, 0 }, { "refresh", builtin_refresh, 0 }, { "ret", builtin_ret, 0 }, { "searchback", builtin_searchback, 1, { StringArg } }, { "searchforward", builtin_searchforward, 1, { StringArg } }, { "select", builtin_select, 0 }, { "sendcommand", builtin_sendcommand, 1, { StringArg } }, { "warp", builtin_warp, 0 } }; static int num_builtins = sizeof (builtin_functions) / sizeof (FunctionType); /************************************************************************/ struct charstring { char key; int value; }; struct charstring key_modifiers[]= { {'s',ShiftMask}, {'c',ControlMask}, {'m',Mod1Mask}, {'1',Mod1Mask}, {'2',Mod2Mask}, {'3',Mod3Mask}, {'4',Mod4Mask}, {'5',Mod5Mask}, {'a',AnyModifier}, {'n',0}, {0,0} }; #if FVWM_VERSION == 1 static FILE *config_fp = NULL; #endif /* This is only used for printing out the .fvwmrc line if an error occured */ #define PRINT_LINE_LENGTH 80 static char current_line[PRINT_LINE_LENGTH]; static void save_current_line (char *s) { char *p = current_line; while (*s && p < current_line + PRINT_LINE_LENGTH - 1) { if (*s == '\n') { *p = '\0'; return; } else { *p++ = *s++; } } *p = '\0'; } void print_args (int numargs, BuiltinArg *args) { #ifdef PRINT_DEBUG int i; for (i = 0; i < numargs; i++) { switch (args[i].type) { case NoArg: ConsoleDebug (CONFIG, "NoArg "); break; case IntArg: ConsoleDebug (CONFIG, "Int: %d ", args[i].value.int_value); break; case StringArg: ConsoleDebug (CONFIG, "String: %s ", args[i].value.string_value); break; case ButtonArg: ConsoleDebug (CONFIG, "Button: %d %d ", args[i].value.button_value.offset, args[i].value.button_value.base); break; case WindowArg: ConsoleDebug (CONFIG, "Window: %d %d ", args[i].value.button_value.offset, args[i].value.button_value.base); break; case ManagerArg: ConsoleDebug (CONFIG, "Manager: %d %d ", args[i].value.button_value.offset, args[i].value.button_value.base); break; case JmpArg: ConsoleDebug (CONFIG, "Unprocessed Label Jump: %s ", args[i].value.string_value); break; default: ConsoleDebug (CONFIG, "bad "); break; } } ConsoleDebug (CONFIG, "\n"); #endif } #ifdef PRINT_DEBUG static void print_binding (Binding *binding) { int i; Function *func; if (binding->IsMouse) { ConsoleDebug (CONFIG, "\tMouse: %d\n", binding->Button_Key); } else { ConsoleDebug (CONFIG, "\tKey or action: %d %s\n", binding->Button_Key, binding->key_name); } ConsoleDebug (CONFIG, "\tModifiers: %d\n", binding->Modifier); ConsoleDebug (CONFIG, "\tAction: %s\n", binding->Action); ConsoleDebug (CONFIG, "\tFunction struct: %p\n", binding->Function); func = binding->Function; while (func) { for (i = 0; i < num_builtins; i++) { if (func->func == builtin_functions[i].func) { ConsoleDebug (CONFIG, "\tFunction: %s %p ", builtin_functions[i].name, func->func); break; } } if (i > num_builtins) { ConsoleDebug (CONFIG, "\tFunction: not found %p ", func->func); } print_args (func->numargs, func->args); func = func->next; } } #endif void print_bindings (Binding *list) { #ifdef PRINT_DEBUG ConsoleDebug (CONFIG, "binding list:\n"); while (list != NULL) { print_binding (list); ConsoleDebug (CONFIG, "\n"); list = list->NextBinding; } #endif } static int iswhite (char c) { if (c == ' ' || c == '\t' || c == '\0') return 1; return 0; } static void skip_space (char **p) { while (**p == ' ' || **p == '\t') (*p)++; } static void add_to_binding (Binding **list, Binding *binding) { ConsoleDebug (CONFIG, "In add_to_binding:\n"); if (*list == NULL) { *list = binding; } else { binding->LastBinding->NextBinding = *list; *list = binding; } } static int extract_int (char *p, int *n) { char *s; int sign = 1; while (isspace (*p) && *p) p++; if (*p == '-') { sign = -1; p++; } else if (*p == '+') { sign = 1; p++; } if (*p == '\0') { return 0; } for (s = p; *s; s++) { if (*s < '0' || *s > '9') { return 0; } } *n = atoi (p) * sign; return 1; } /**************************************************************************** * * Gets the next "word" of input from char string indata. * "word" is a string with no spaces, or a qouted string. * Return value is ptr to indata,updated to point to text after the word * which is extracted. * token is the extracted word, which is copied into a malloced * space, and must be freed after use. * **************************************************************************/ static void find_context(char *string, int *output, struct charstring *table, char *tline) { int i=0,j=0; Bool matched; char tmp1; *output=0; i=0; while(itype = ButtonArg; bv = &arg->value.button_value; bv->offset = 0; bv->base = AbsoluteButton; rest = DoGetNextToken (string, &token, NULL, ",", pstop_char); if (token == NULL) { bv->base = NoButton; *flag = 0; Free(token); return NULL; } if (!strcasecmp (token, "focus")) { bv->base = FocusButton; } else if (!strcasecmp (token, "select")) { bv->base = SelectButton; } else if (!strcasecmp (token, "up")) { bv->base = UpButton; } else if (!strcasecmp (token, "down")) { bv->base = DownButton; } else if (!strcasecmp (token, "left")) { bv->base = LeftButton; } else if (!strcasecmp (token, "right")) { bv->base = RightButton; } else if (!strcasecmp (token, "next")) { bv->base = NextButton; } else if (!strcasecmp (token, "prev")) { bv->base = PrevButton; } else if (extract_int (token, &n)) { bv->base = AbsoluteButton; bv->offset = n; } else { ConsoleMessage ("Bad button: %s\n", token); bv->base = NoButton; Free (token); *flag = 0; return NULL; } Free (token); return rest; } static void free_function_list (Function *func) { int i; Function *fp = func; while (fp) { for (i = 0; i < fp->numargs; i++) { if (fp->args[i].type == StringArg) Free (fp->args[i].value.string_value); } func = fp; fp = fp->next; Free (func); } } static int funccasecmp(const void *key /* actually char* */, const void *member /* actually FunctionType* */) { return strcasecmp((char *)key, ((FunctionType *)member)->name); } /* * The label function. Should never be called, but we need a pointer to it, * and it's useful for debugging purposes to have it defined. */ static int builtin_label (int numargs, BuiltinArg *args) { int j; /* we should _never_ be called */ ConsoleMessage ( "label" ); for (j=0; jfunc = builtin_functions_i->func; ftype->numargs = builtin_functions_i->numargs; ftype->next = NULL; for (j = 0; j < builtin_functions_i->numargs && *pstop_char != ','; j++) { ftype->args[j].type = builtin_functions_i->args[j]; switch (builtin_functions_i->args[j]) { case IntArg: ptr = DoGetNextToken (ptr, &tok, NULL, ",", pstop_char); if (!tok) { ConsoleMessage ("%s: too few arguments\n", builtin_functions_i->name); Free(ftype); *line = NULL; return NULL; } if (extract_int (tok, &ftype->args[j].value.int_value) == 0) { ConsoleMessage ("%s: expect integer argument: %s\n", builtin_functions_i->name, tok); Free (tok); Free(ftype); *line = NULL; return NULL; } Free (tok); break; case StringArg: ptr = DoGetNextToken (ptr, &ftype->args[j].value.string_value,NULL, ",", pstop_char); if (!ftype->args[j].value.string_value) { ConsoleMessage ("%s: too few arguments\n", builtin_functions_i->name); *line = NULL; Free(ftype->args[j].value.string_value); Free(ftype); return NULL; } ftype->args[j].type = builtin_functions_i->args[j]; break; case ButtonArg: case WindowArg: case ManagerArg: ptr = parse_button (ptr, &ftype->args[j], &flag, pstop_char); if (!flag) { ConsoleMessage ("%s: too few arguments\n", builtin_functions_i->name); Free(ftype); *line = NULL; return NULL; } ftype->args[j].type = builtin_functions_i->args[j]; break; /* JmpArg can be a string or an int. However, if 'JmpArg' * is recorded as the argument type in the argument array * for a command, it means it is a string; the code for * 'IntArg' is used instead for numbers. Note also that * if the C function recieves a 'JmpArg' argument it means something * went wrong, since they should all be translated to integer * jump offsets at compile time. */ case JmpArg: ptr = DoGetNextToken (ptr, &tok, NULL, ",", pstop_char); if (!tok) { ConsoleMessage ("%s: too few arguments\n", builtin_functions_i->name); Free(tok); Free(ftype); *line=NULL; return NULL; } if (extract_int(tok, &ftype->args[j].value.int_value) == 0) { ftype->args[j].value.string_value=tok; ftype->args[j].type = JmpArg; ++JmpArgs; } else { ftype->args[j].type = IntArg; Free(tok); } break; default: ConsoleMessage ("internal error in parse_function\n"); Free(ftype); *line = NULL; return NULL; } } if (j != builtin_functions_i->numargs) { ConsoleMessage ("%s: too few arguments\n", builtin_functions_i->name); Free(ftype); *line = NULL; return NULL; } *line = ptr; return ftype; } ConsoleMessage ("Unknown function: %s\n", name); Free (name); *line = NULL; return NULL; } /* This is O(N^2) where N = number of instructions. Seems we could do better. We'll see how this addition settles before monkeying with it */ static Function *parse_function_list (char *line) { Function *ret = NULL, *tail = NULL, *f, *i; char *token; int jump_count, j; char stop_char; char c; JmpArgs=0; while (line && (f = parse_function(&line, &stop_char))) { ConsoleDebug (CONFIG, "parse_function: %p\n", f->func); /* extra code to check for and remove a 'label' pseudo-function */ if (f->func==builtin_label) { /* scan backwards to fix up references */ jump_count=0; for (i=tail; i!=NULL; i=i->prev) { /* scan the command arguments for a 'JmpArg' type */ for (j=0; j<(i->numargs); ++j) { if (i->args[j].type==JmpArg) { /* we have a winner! */ if (!strcasecmp(f->args[0].value.string_value, i->args[j].value.string_value)) { /* the label matches it, so replace with the jump_count */ i->args[j].type = IntArg; i->args[j].value.int_value = jump_count; --JmpArgs; } } } ++jump_count; } Free(f); /* label pseudo-functions never get added to the chain */ } else { if (tail) tail->next = f; else ret = f; f->prev=tail; tail = f; } DoGetNextToken (line, &token, NULL, ",", &c); if (token && stop_char != ',') { ConsoleMessage ("Bad function list, comma expected\n"); Free (token); return NULL; } stop_char = c; Free(token); } if (JmpArgs!=0) { /* someone made a typo and we need to scan to find out what it * was. */ for (f=tail; f; f=f->prev) { for (j=0; j<(f->numargs); ++j) { if (f->args[j].type==JmpArg) { ConsoleMessage ("Attempt to jump to non-existant label %s; " "aborting function list.\n", f->args[j].value.string_value); --JmpArgs; } } } if (JmpArgs!=0) ConsoleMessage ( "Internal Error: JmpArgs %d not accounted for!\n", JmpArgs ); tail=NULL; f=NULL; free_function_list(ret); ret=NULL; return NULL; } if (ret == NULL) ConsoleMessage ("No function defined\n"); return ret; } Binding *ParseMouseEntry (char *tline) { char modifiers[20],*action,*token; Binding *new; int button; int n1=0,n2=0; int mods; /* tline points after the key word "key" */ action = DoGetNextToken(tline,&token, NULL, ",", NULL); if(token != NULL) { n1 = sscanf(token,"%d",&button); Free(token); } action = DoGetNextToken(action,&token, NULL, ",", NULL); if(token != NULL) { n2 = sscanf(token,"%19s",modifiers); Free(token); } if((n1 != 1)||(n2 != 1)) ConsoleMessage ("Mouse binding: Syntax error"); find_context(modifiers,&mods,key_modifiers,tline); if((mods & AnyModifier)&&(mods&(~AnyModifier))) { ConsoleMessage ("Binding specified AnyModifier and other modifers too. Excess modifiers will be ignored."); } new = (Binding *)safemalloc(sizeof(Binding)); new->IsMouse = 1; new->Button_Key = button; new->key_name = NULL; new->Modifier = mods; new->Action = stripcpy(action); new->Function = parse_function_list (action); new->NextBinding = NULL; new->LastBinding = new; if (!new->Function) { ConsoleMessage ("Bad action: %s\n", action); Free (new->Action); Free (new); return NULL; } ConsoleDebug (CONFIG, "Mouse: %d %d %s\n", new->Button_Key, new->Modifier, new->Action); return new; } static Binding *ParseKeyEntry (char *tline) { char *action,modifiers[20],key[20],*ptr, *token, *actionstring, *keystring; Binding *new = NULL, *temp, *last = NULL; Function *func = NULL; int i,min,max; int n1=0,n2=0; KeySym keysym; int mods; /* tline points after the key word "key" */ ptr = tline; ptr = DoGetNextToken(ptr,&token, NULL, ",", NULL); if(token != NULL) { n1 = sscanf(token,"%19s",key); Free(token); } action = DoGetNextToken(ptr,&token, NULL, ",", NULL); if(token != NULL) { n2 = sscanf(token,"%19s",modifiers); Free(token); } if((n1 != 1)||(n2 != 1)) ConsoleMessage ("Syntax error in line %s",tline); find_context(modifiers,&mods,key_modifiers,tline); if((mods & AnyModifier)&&(mods&(~AnyModifier))) { ConsoleMessage ("Binding specified AnyModifier and other modifers too. Excess modifiers will be ignored."); } /* * Don't let a 0 keycode go through, since that means AnyKey to the * XGrabKey call in GrabKeys(). */ if ((keysym = XStringToKeysym(key)) == NoSymbol || XKeysymToKeycode(theDisplay, keysym) == 0) { ConsoleMessage ("Can't find keysym: %s\n", key); return NULL; } XDisplayKeycodes(theDisplay, &min, &max); for (i=min; i<=max; i++) { if (XKeycodeToKeysym(theDisplay, i, 0) == keysym) { if (!func) { func = parse_function_list (action); if (!func) { ConsoleMessage ("Bad action: %s\n", action); return NULL; } actionstring = stripcpy(action); keystring = stripcpy(key); } temp = new; new = (Binding *)safemalloc(sizeof(Binding)); new->IsMouse = 0; new->Button_Key = i; new->key_name = keystring; new->Modifier = mods; new->Action = actionstring; new->Function = func; new->NextBinding = temp; if (!last) { last = new; } new->LastBinding = last; ConsoleDebug (CONFIG, "Key: %d %s %d %s\n", i, new->key_name, mods, new->Action); } } return new; } static Binding *ParseSimpleEntry (char *tline) { Binding *new; Function *func; func = parse_function_list (tline); if (func == NULL) return NULL; new = (Binding *)safemalloc (sizeof (Binding)); new->IsMouse = 0; new->Button_Key = 0; new->key_name = "select"; new->Modifier = 0; new->Action = stripcpy (tline); new->Function = func; new->NextBinding = NULL; new->LastBinding = new; return new; } void run_binding (WinManager *man, Action action) { Binding *binding = man->bindings[action]; ConsoleDebug (CONFIG, "run_binding:\n"); print_bindings (binding); if (binding && binding->Function && binding->Function->func) { run_function_list (binding->Function); } } void execute_function (char *string) { Function *func = parse_function_list (string); if (func == NULL) { return; } else { run_function_list (func); free_function_list (func); } } static int GetConfigLineWrapper (int *fd, char **tline) { #if FVWM_VERSION == 1 static char buffer[1024]; char *temp; if (fgets (buffer, 1024, config_fp)) { *tline = buffer; temp = strchr (*tline, '\n'); if (temp) { *temp = '\0'; } else { ConsoleMessage (stderr, "line too long\n"); exit (1); } return 1; } #else char *temp; GetConfigLine (fd, tline); if (*tline) { temp = strchr (*tline, '\n'); if (temp) { *temp = '\0'; } return 1; } #endif return 0; } static char *read_next_cmd (ReadOption flag) { static ReadOption status; static char *buffer; static char *retstring, displaced, *cur_pos; retstring = NULL; if (flag != READ_LINE && !(flag & status)) return NULL; switch (flag) { case READ_LINE: while (GetConfigLineWrapper (Fvwm_fd, &buffer)) { cur_pos = buffer; skip_space (&cur_pos); if (!strncasecmp (Module, cur_pos, ModuleLen)) { retstring = cur_pos; cur_pos += ModuleLen; displaced = *cur_pos; if (displaced == '*') status = READ_OPTION; else if (displaced == '\0') status = READ_LINE; else if (iswhite (displaced)) status = READ_ARG; else status = READ_LINE; break; } } break; case READ_OPTION: *cur_pos = displaced; retstring = ++cur_pos; while (*cur_pos != '*' && !iswhite (*cur_pos)) cur_pos++; displaced = *cur_pos; *cur_pos = '\0'; if (displaced == '*') status = READ_OPTION; else if (displaced == '\0') status = READ_LINE; else if (iswhite (displaced)) status = READ_ARG; else status = READ_LINE; break; case READ_ARG: *cur_pos = displaced; skip_space (&cur_pos); retstring = cur_pos; while (!iswhite (*cur_pos)) cur_pos++; displaced = *cur_pos; *cur_pos = '\0'; if (displaced == '\0') status = READ_LINE; else if (iswhite (displaced)) status = READ_ARG; else status = READ_LINE; break; case READ_REST_OF_LINE: status = READ_LINE; *cur_pos = displaced; skip_space (&cur_pos); retstring = cur_pos; break; } if (retstring && retstring[0] == '\0') retstring = NULL; return retstring; } static char *conditional_copy_string (char **s1, char *s2) { if (*s1) return *s1; else return copy_string (s1, s2); } static NameType parse_format_dependencies (char *format) { NameType flags = NO_NAME; ConsoleDebug (CONFIG, "Parsing format: %s\n", format); while (*format) { if (*format != '%') { format++; } else { format++; if (*format == 'i') flags |= ICON_NAME; else if (*format == 't') flags |= TITLE_NAME; else if (*format == 'c') flags |= CLASS_NAME; else if (*format == 'r') flags |= RESOURCE_NAME; else if (*format != '%') ConsoleMessage ("Bad format string: %s\n", format); } } #ifdef PRINT_DEBUG ConsoleDebug (CONFIG, "Format depends on: "); if (flags & ICON_NAME) ConsoleDebug (CONFIG, "Icon "); if (flags & TITLE_NAME) ConsoleDebug (CONFIG, "Title "); if (flags & CLASS_NAME) ConsoleDebug (CONFIG, "Class "); if (flags & RESOURCE_NAME) ConsoleDebug (CONFIG, "Resource "); ConsoleDebug (CONFIG, "\n"); #endif return flags; } #define SET_MANAGER(manager,field,value) \ do { \ int id = manager; \ if (id == -1) { \ for (id = 0; id < globals.num_managers; id++) { \ globals.managers[id].field = value; \ } \ } \ else if (id < globals.num_managers) { \ globals.managers[id].field = value; \ } \ else { \ ConsoleMessage ("Internal error in SET_MANAGER: %d\n", id); \ } \ } while (0) static void handle_button_config (int manager, int context, char *option) { char *p; ButtonState state; p = read_next_cmd (READ_ARG); if (!p) { ConsoleMessage ("Bad line: %s\n", current_line); ConsoleMessage ("Need argument to %s\n", option); return; } else if (!strcasecmp (p, "flat")) { state = BUTTON_FLAT; } else if (!strcasecmp (p, "up")) { state = BUTTON_UP; } else if (!strcasecmp (p, "down")) { state = BUTTON_DOWN; } else if (!strcasecmp (p, "raisededge")) { state = BUTTON_EDGEUP; } else if (!strcasecmp (p, "sunkedge")) { state = BUTTON_EDGEDOWN; } else { ConsoleMessage ("Bad line: %s\n", current_line); ConsoleMessage ("This isn't a valid button state: %s\n", p); return; } ConsoleDebug (CONFIG, "Setting buttonState[%s] to %s\n", contextDefaults[context].name, p); SET_MANAGER (manager, buttonState[context], state); /* check for optional fore color */ p = read_next_cmd (READ_ARG); if ( !p ) return; SET_MANAGER (manager, foreColorName[context], copy_string (&globals.managers[id].foreColorName[context], p)); /* check for optional back color */ p = read_next_cmd (READ_ARG); if ( !p ) return; ConsoleDebug (CONFIG, "Setting backColorName[%s] to %s\n", contextDefaults[context].name, p); SET_MANAGER (manager, backColorName[context], copy_string (&globals.managers[id].backColorName[context], p)); } void read_in_resources (char *file) { char *p, *q; int i, n, manager; char *option1; Binding *binding; Resolution r; if (!init_config_file (file)) return; while ((p = read_next_cmd (READ_LINE))) { ConsoleDebug (CONFIG, "line: %s\n", p); save_current_line (p); option1 = read_next_cmd (READ_OPTION); if (option1 == NULL) continue; ConsoleDebug (CONFIG, "option1: %s\n", option1); if (!strcasecmp (option1, "nummanagers")) { /* If in transient mode, just use the default of 1 manager */ if (!globals.transient) { p = read_next_cmd (READ_ARG); if (!p) { ConsoleMessage ("Bad line: %s\n", current_line); continue; } if (extract_int (p, &n) == 0) { ConsoleMessage ("This is not a number: %s\n", p); ConsoleMessage ("Bad line: %s\n", current_line); continue; } if (n > 0) { allocate_managers (n); ConsoleDebug (CONFIG, "num managers: %d\n", n); } else { ConsoleMessage ("Bad line: %s\n", current_line); ConsoleMessage ("You can't have zero managers. " "I'll give you one.\n"); allocate_managers (1); } } } else { /* these all can specify a specific manager */ if (globals.managers == NULL) { ConsoleDebug (CONFIG, "I'm assuming you only want one manager\n"); allocate_managers (1); } manager = 0; if (option1[0] >= '0' && option1[0] <= '9') { if (globals.transient) { ConsoleDebug (CONFIG, "In transient mode. Ignoring this line\n"); continue; } if (extract_int (option1, &manager) == 0 || manager <= 0 || manager > globals.num_managers) { ConsoleMessage ("Bad line: %s\n", current_line); ConsoleMessage ("This is not a valid manager: %s.\n", option1); manager = 0; } option1 = read_next_cmd (READ_OPTION); if (!option1) { ConsoleMessage ("Bad line: %s\n", current_line); continue; } } else if (!strcasecmp (option1, "transient")) { if (globals.transient) { ConsoleDebug (CONFIG, "Transient manager config line\n"); manager = 1; option1 = read_next_cmd (READ_OPTION); if (!option1) { ConsoleMessage ("Bad line: %s\n", current_line); continue; } } else { ConsoleDebug (CONFIG, "Not in transient mode. Ignoring this line\n"); continue; } } manager--; /* -1 means global */ ConsoleDebug (CONFIG, "Applying %s to manager %d\n", option1, manager); if (!strcasecmp (option1, "action")) { p = read_next_cmd (READ_ARG); if (!p) { ConsoleMessage ("Bad line: %s\n", current_line); continue; } if (!strcasecmp (p, "mouse")) { i = MOUSE; } else if (!strcasecmp (p, "key")) { i = KEYPRESS; } else if (!strcasecmp (p, "select")) { i = SELECT; } else { ConsoleMessage ("Bad line: %s\n", current_line); ConsoleMessage ("This isn't a valid action name: %s\n", p); continue; } q = read_next_cmd (READ_REST_OF_LINE); if (!q) { ConsoleMessage ("Bad line: %s\n", current_line); ConsoleMessage ("Need an action\n"); continue; } switch (i) { case MOUSE: binding = ParseMouseEntry (q); break; case KEYPRESS: binding = ParseKeyEntry (q); break; case SELECT: binding = ParseSimpleEntry (q); break; } if (binding == NULL) { ConsoleMessage ("Offending line: %s\n", current_line); ConsoleMessage ("Bad action\n"); continue; } if (manager == -1) { int j; for (j = 0; j < globals.num_managers; j++) { add_to_binding (&globals.managers[j].bindings[i], binding); } } else if (manager < globals.num_managers) { add_to_binding (&globals.managers[manager].bindings[i], binding); } else { ConsoleMessage ("Bad line: %s\n", current_line); ConsoleMessage ("There's no manager %d\n", manager); } } else if (!strcasecmp (option1, "background")) { p = read_next_cmd (READ_ARG); if (!p) { ConsoleMessage ("Bad line: %s\n", current_line); continue; } ConsoleDebug (CONFIG, "default background: %s\n", p); for ( i = 0; i < NUM_CONTEXTS; i++ ) SET_MANAGER (manager, backColorName[i], conditional_copy_string (&globals.managers[id].backColorName[i], p)); } else if (!strcasecmp (option1, "buttongeometry")) { p = read_next_cmd (READ_ARG); if (!p) { ConsoleMessage ("Bad line: %s\n", current_line); continue; } SET_MANAGER (manager, button_geometry_str, copy_string (&globals.managers[id].button_geometry_str, p)); } else if (!strcasecmp (option1, "dontshow")) { char *token = NULL; p = read_next_cmd (READ_REST_OF_LINE); if (!p) { ConsoleMessage ("Bad line: %s\n", current_line); continue; } p = DoGetNextToken (p, &token, NULL, ",", NULL); if (!token) { ConsoleMessage ("Bad line: %s\n", current_line); continue; } do { ConsoleDebug (CONFIG, "dont show: %s\n", token); if (manager == -1) { int i; for (i = 0; i < globals.num_managers; i++) add_to_stringlist (&globals.managers[i].dontshow, token); } else { add_to_stringlist (&globals.managers[manager].dontshow, token); } Free (token); p = DoGetNextToken (p, &token, NULL, ",", NULL); } while (token); if (token) Free(token); } else if (!strcasecmp (option1, "drawicons")) { #ifdef MINI_ICONS p = read_next_cmd (READ_ARG); if (!p) { ConsoleMessage ("Bad line: %s\n", current_line); ConsoleMessage ("Need argument to drawicons\n"); continue; } if (!strcasecmp (p, "true")) { i = 1; } /* [NFM 3 Dec 97] added support for FvwmIconMan*drawicons "always" */ else if (!strcasecmp (p, "always")) { i = 2; } else if (!strcasecmp (p, "false")) { i = 0; } else { ConsoleMessage ("Bad line: %s\n", current_line); ConsoleMessage ("What is this: %s?\n", p); continue; } ConsoleDebug (CONFIG, "Setting drawicons to: %d\n", i); SET_MANAGER (manager, draw_icons, i); #else ConsoleMessage ("DrawIcons support not compiled in\n"); #endif } else if (!strcasecmp (option1, "followfocus")) { p = read_next_cmd (READ_ARG); if (!p) { ConsoleMessage ("Bad line: %s\n", current_line); ConsoleMessage ("Need argument to followfocus\n"); continue; } if (!strcasecmp (p, "true")) { i = 1; } else if (!strcasecmp (p, "false")) { i = 0; } else { ConsoleMessage ("Bad line: %s\n", current_line); ConsoleMessage ("What is this: %s?\n", p); continue; } ConsoleDebug (CONFIG, "Setting followfocus to: %d\n", i); SET_MANAGER (manager, followFocus, i); } else if (!strcasecmp (option1, "font")) { p = read_next_cmd (READ_ARG); if (!p) { ConsoleMessage ("Bad line: %s\n", current_line); continue; } ConsoleDebug (CONFIG, "font: %s\n", p); SET_MANAGER (manager, fontname, copy_string (&globals.managers[id].fontname, p)); } else if (!strcasecmp (option1, "foreground")) { p = read_next_cmd (READ_ARG); if (!p) { ConsoleMessage ("Bad line: %s\n", current_line); continue; } ConsoleDebug (CONFIG, "default foreground: %s\n", p); for ( i = 0; i < NUM_CONTEXTS; i++ ) SET_MANAGER (manager, foreColorName[i], conditional_copy_string (&globals.managers[id].foreColorName[i], p)); } else if (!strcasecmp (option1, "format")) { char *token; NameType flags; p = read_next_cmd (READ_REST_OF_LINE); if (!p) { ConsoleMessage ("Bad line: %s\n", current_line); continue; } DoGetNextToken (p, &token, NULL, ",", NULL); if (!token) { token = (char *)safemalloc(1); *token = 0; } SET_MANAGER (manager, formatstring, copy_string (&globals.managers[id].formatstring, token)); flags = parse_format_dependencies (token); SET_MANAGER (manager, format_depend, flags); Free (token); } else if (!strcasecmp (option1, "geometry")) { ConsoleMessage ("Geometry option no longer supported.\n"); ConsoleMessage ("Use ManagerGeometry and ButtonGeometry.\n"); } else if (!strcasecmp (option1, "iconname")) { char *token; p = read_next_cmd (READ_REST_OF_LINE); if (!p) { ConsoleMessage ("Bad line: %s\n", current_line); continue; } DoGetNextToken (p, &token, NULL, ",", NULL); if (!token) { token = (char *)safemalloc(1); *token = 0; } SET_MANAGER (manager, iconname, copy_string (&globals.managers[id].iconname, token)); Free (token); } else if (!strcasecmp (option1, "managergeometry")) { p = read_next_cmd (READ_ARG); if (!p) { ConsoleMessage ("Bad line: %s\n", current_line); continue; } SET_MANAGER (manager, geometry_str, copy_string (&globals.managers[id].geometry_str, p)); } else if (!strcasecmp (option1, "resolution")) { p = read_next_cmd (READ_ARG); if (!p) { ConsoleMessage ("Bad line: %s\n", current_line); continue; } ConsoleDebug (CONFIG, "resolution: %s\n", p); if (!strcasecmp (p, "global")) r = SHOW_GLOBAL; else if (!strcasecmp (p, "desk")) r = SHOW_DESKTOP; else if (!strcasecmp (p, "page")) r = SHOW_PAGE; else { ConsoleMessage ("Bad line: %s\n", current_line); ConsoleMessage ("What kind of resolution is this?\n"); continue; } SET_MANAGER (manager, res, r); } else if (!strcasecmp (option1, "shape")) { p = read_next_cmd (READ_ARG); if (!p) { ConsoleMessage ("Bad line: %s\n", current_line); ConsoleMessage ("Need argument to followfocus\n"); continue; } if (!strcasecmp (p, "true")) { i = 1; } else if (!strcasecmp (p, "false")) { i = 0; } else { ConsoleMessage ("Bad line: %s\n", current_line); ConsoleMessage ("What is this: %s?\n", p); continue; } if (i && globals.shapes_supported == 0) { ConsoleMessage ("Shape support not compiled in\n"); continue; } ConsoleDebug (CONFIG, "Setting shape to: %d\n", i); SET_MANAGER (manager, shaped, i); } else if (!strcasecmp (option1, "show")) { char *token = NULL; p = read_next_cmd (READ_REST_OF_LINE); if (!p) { ConsoleMessage ("Bad line: %s\n", current_line); continue; } p = DoGetNextToken (p, &token, NULL, ",", NULL); if (!token) { ConsoleMessage ("Bad line: %s\n", current_line); continue; } do { ConsoleDebug (CONFIG, "show: %s\n", token); if (manager == -1) { int i; for (i = 0; i < globals.num_managers; i++) add_to_stringlist (&globals.managers[i].show, token); } else { add_to_stringlist (&globals.managers[manager].show, token); } Free (token); p = DoGetNextToken (p, &token, NULL, ",", NULL); } while (token); if (token) Free(token); } else if (!strcasecmp (option1, "showtitle")) { ConsoleMessage ("Bad line: %s\n", current_line); ConsoleMessage ("showtitle is no longer an option. Use format\n"); continue; } else if (!strcasecmp (option1, "sort")) { p = read_next_cmd (READ_ARG); if (!p) { ConsoleMessage ("Bad line: %s\n", current_line); ConsoleMessage ("Need argument to sort\n"); continue; } if (!strcasecmp (p, "name")) { i = SortName; } else if (!strcasecmp (p, "namewithcase")) { i = SortNameCase; } else if (!strcasecmp (p, "id")) { i = SortId; } else if (!strcasecmp (p, "none")) { i = SortNone; } else if (!strcasecmp (p, "false") || !strcasecmp (p, "true")) { /* Old options */ ConsoleMessage ("FvwmIconMan*sort option no longer takes " "true or false value\n" "Please read the latest manpage\n"); continue; } else { ConsoleMessage ("Bad line: %s\n", current_line); ConsoleMessage ("What is this: %s?\n", p); continue; } ConsoleDebug (CONFIG, "Setting sort to: %d\n", i); SET_MANAGER (manager, sort, i); } else if (!strcasecmp (option1, "title")) { char *token; p = read_next_cmd (READ_REST_OF_LINE); if (!p) { ConsoleMessage ("Bad line: %s\n", current_line); continue; } DoGetNextToken (p, &token, NULL, ",", NULL); if (!token) { token = (char *)safemalloc(1); *token = 0; } SET_MANAGER (manager, titlename, copy_string (&globals.managers[id].titlename, token)); Free (token); } else if (!strcasecmp (option1, "plainButton")) { handle_button_config (manager, PLAIN_CONTEXT, option1); } else if (!strcasecmp (option1, "selectButton")) { handle_button_config (manager, SELECT_CONTEXT, option1); } else if (!strcasecmp (option1, "focusButton")) { handle_button_config (manager, FOCUS_CONTEXT, option1); } else if (!strcasecmp (option1, "focusandselectButton")) { handle_button_config (manager, FOCUS_SELECT_CONTEXT, option1); } else if (!strcasecmp (option1, "titlebutton")) { handle_button_config (manager, TITLE_CONTEXT, option1); } else if (!strcasecmp (option1, "usewinlist")) { p = read_next_cmd (READ_ARG); if (!p) { ConsoleMessage ("Bad line: %s\n", current_line); ConsoleMessage ("Need argument to usewinlist\n"); continue; } if (!strcasecmp (p, "true")) { i = 1; } else if (!strcasecmp (p, "false")) { i = 0; } else { ConsoleMessage ("Bad line: %s\n", current_line); ConsoleMessage ("What is this: %s?\n", p); continue; } ConsoleDebug (CONFIG, "Setting usewinlist to: %d\n", i); SET_MANAGER (manager, usewinlist, i); } else { ConsoleMessage ("Bad line: %s\n", current_line); ConsoleMessage ("Unknown option: %s\n", p); } } } if (globals.managers == NULL) { ConsoleDebug (CONFIG, "I'm assuming you only want one manager\n"); allocate_managers (1); } print_managers(); close_config_file(); }