/*#define DEBUG_PARSER*/ static void ParseButton(button_info **uberb, char *s) { button_info *b, *ub = *uberb; int i, j; char *t, *o; b = alloc_button(ub, (ub->c->num_buttons)++); s = trimleft(s); if (*s == '(' && s++) { char *opts[] = { "back", "fore", "font", "title", "icon", "frame", "padding", "swallow", "panel", "actionignoresclientwindow", "actiononpress", "container", "end", "nosize", "size", "left", "right", "center", "colorset", "action", "id", "activeicon", "activetitle", "pressicon", "presstitle", "activecolorset", "presscolorset", "top", NULL }; s = trimleft(s); while (*s && *s != ')') { Bool is_swallow = False; if (*s == ',') { s++; s = trimleft(s); continue; } if (isdigit(*s) || *s == '+' || *s == '-') { char *geom; int x, y, flags; unsigned int w, h; geom = seekright(&s); if (geom) { flags = XParseGeometry(geom, &x, &y, &w, &h); if (flags&WidthValue) { b->BWidth = w; } if (flags&HeightValue) { b->BHeight = h; } if (flags & XValue) { b->BPosX = x; b->flags.b_PosFixed = 1; } if (flags & YValue) { b->BPosY = y; b->flags.b_PosFixed = 1; } if (flags & XNegative) { b->BPosX = -1 - x; } if (flags & YNegative) { b->BPosY = -1 - y; } free(geom); } s = trimleft(s); continue; } switch (GetTokenIndex(s, opts, -1, &s)) { case 0: /* Back */ s = trimleft(s); if (*s == '(' && s++ && ParseBack(&s)) { b->flags.b_IconBack = 1; } if (b->flags.b_Back && b->back) { free(b->back); } b->back = seekright(&s); if (b->back) { b->flags.b_Back = 1; } else { b->flags.b_IconBack = 0; b->flags.b_Back = 0; } break; case 1: /* Fore */ if (b->flags.b_Fore && b->fore) { free(b->fore); } b->fore = seekright(&s); b->flags.b_Fore = (b->fore ? 1 : 0); break; case 2: /* Font */ if (b->flags.b_Font && b->font_string) { free(b->font_string); } b->font_string = my_get_font(&s); b->flags.b_Font = (b->font_string ? 1 : 0); break; /* ----------------- title --------------- */ case 3: /* Title */ s = trimleft(s); if (*s == '(' && s++) { b->justify = 0; b->justify_mask = 0; ParseTitle( &s, &b->justify, &b->justify_mask); if (b->justify_mask) { b->flags.b_Justify = 1; } } t = seekright(&s); if (t && *t && (t[0] != '-' || t[1] != 0)) { if (b->title) { free(b->title); } b->title = t; #ifdef DEBUG_PARSER fprintf(stderr, "PARSE: Title \"%s\"\n", b->title); #endif b->flags.b_Title = 1; } else { fprintf(stderr, "%s: Missing title argument\n", MyName); if (t) { free(t); } } break; /* ------------------ icon --------------- */ case 4: /* Icon */ t = seekright(&s); if (t && *t && (t[0] != '-' || t[1] != 0)) { if (b->flags.b_Swallow) { fprintf(stderr, "%s: a button can not " "have an icon and a " "swallowed window at " "the same time. " "Ignoring icon\n", MyName); } else { if (b->icon_file) { free(b->icon_file); } b->icon_file = t; b->flags.b_Icon = 1; } } else { fprintf(stderr, "%s: Missing Icon argument\n", MyName); if (t) { free(t); } } break; /* ----------------- frame --------------- */ case 5: /* Frame */ i = strtol(s, &t, 10); if (t > s) { b->flags.b_Frame = 1; b->framew = i; s = t; } else { fprintf(stderr, "%s: Illegal frame argument\n", MyName); } break; /* ---------------- padding -------------- */ case 6: /* Padding */ i = strtol(s,&t,10); if (t>s) { b->xpad = b->ypad = i; b->flags.b_Padding = 1; s = t; i = strtol(s, &t, 10); if (t > s) { b->ypad = i; s = t; } } else { fprintf(stderr, "%s: Illegal padding " "argument\n", MyName); } break; /* ---------------- swallow -------------- */ case 7: /* Swallow */ is_swallow = True; /* fall through */ case 8: /* Panel */ s = trimleft(s); if (is_swallow) { b->swallow = 0; b->swallow_mask = 0; } else { /* set defaults */ b->swallow = b_Respawn; b->swallow_mask = b_Respawn; b->slide_direction = SLIDE_UP; b->slide_position = SLIDE_POSITION_CENTER; b->slide_context = SLIDE_CONTEXT_PB; b->relative_x = 0; b->relative_y = 0; b->slide_steps = 12; b->slide_delay_ms = 5; } if (*s == '(' && s++) { if (is_swallow) { ParseSwallow( &s, &b->swallow, &b->swallow_mask, b); } else { ParsePanel( &s, &b->swallow, &b->swallow_mask, &b->slide_direction, &b->slide_steps, &b->slide_delay_ms, &b->panel_flags, &b->indicator_size, &b->relative_x, &b->relative_y, &b->slide_position, &b->slide_context); } } t = seekright(&s); o = seekright(&s); if (t) { if (b->hangon) { free(b->hangon); } b->hangon = t; if (is_swallow) { if (b->flags.b_Icon) { fprintf(stderr, "%s: a button can not " "have an icon and a " "swallowed window at " "the same time. " "Ignoring icon\n", MyName); b->flags.b_Icon = 0; } b->flags.b_Swallow = 1; b->flags.b_Hangon = 1; } else { b->flags.b_Panel = 1; b->flags.b_Hangon = 1; b->newflags.is_panel = 1; b->newflags.panel_mapped = 0; } b->swallow |= 1; if (!(b->swallow & b_NoHints)) { b->hints = (XSizeHints*) mymalloc(sizeof(XSizeHints)); } if (o) { char *p; p = module_expand_action( Dpy, screen, o, NULL, UberButton->c->fore, UberButton->c->back); if (p) { if (!(buttonSwallow(b)&b_UseOld)) { exec_swallow(p,b); } if (b->spawn) { free(b->spawn); } /* Might be needed if * respawning sometime */ b->spawn = o; free(p); } } } else { fprintf(stderr, "%s: Missing swallow " "argument\n", MyName); if (t) { free(t); } if (o) { free(o); } } /* check if it is a module by command line inspection if * this hints has not been given in the swallow option */ if (is_swallow && !(b->swallow_mask & b_FvwmModule)) { if (b->spawn != NULL && (strncasecmp(b->spawn, "module", 6) == 0 || strncasecmp(b->spawn, "fvwm", 4) == 0)) { b->swallow |= b_FvwmModule; } } break; case 9: /* ActionIgnoresClientWindow */ b->flags.b_ActionIgnoresClientWindow = 1; break; case 10: /* ActionOnPress */ b->flags.b_ActionOnPress = 1; break; /* ---------------- container ------------ */ case 11: /* Container */ /* * SS: This looks very buggy! The FvwmButtons * man page suggests it's here to restrict the * options used with "Container", but it only * restricts those options appearing _before_ * the "Container" keyword for a button. * b->flags&=b_Frame|b_Back|b_Fore|b_Padding|b_Action; */ MakeContainer(b); *uberb = b; s = trimleft(s); if (*s == '(' && s++) { ParseContainer(&s,b); } break; case 12: /* End */ *uberb = ub->parent; ub->c->buttons[--(ub->c->num_buttons)] = NULL; free(b); if (!ub->parent) { fprintf(stderr,"%s: Unmatched END in config file\n",MyName); exit(1); } if (ub->parent->c->flags.b_Colorset || ub->parent->c->flags.b_ColorsetParent) { ub->c->flags.b_ColorsetParent = 1; } if (ub->parent->c->flags.b_IconBack || ub->parent->c->flags.b_IconParent) { ub->c->flags.b_IconParent = 1; } return; case 13: /* NoSize */ b->flags.b_Size = 1; b->minx = b->miny = 0; break; case 14: /* Size */ i = strtol(s, &t, 10); j = strtol(t, &o, 10); if (t > s && o > t) { b->minx = i; b->miny = j; b->flags.b_Size = 1; s = o; } else { fprintf(stderr, "%s: Illegal size arguments\n", MyName); } break; case 15: /* Left */ b->flags.b_Left = 1; b->flags.b_Right = 0; break; case 16: /* Right */ b->flags.b_Right = 1; b->flags.b_Left = 0; break; case 17: /* Center */ b->flags.b_Right = 0; b->flags.b_Left = 0; break; case 18: /* Colorset */ i = strtol(s, &t, 10); if (t > s) { b->colorset = i; b->flags.b_Colorset = 1; s = t; AllocColorset(i); } else { b->flags.b_Colorset = 0; } break; /* ----------------- action -------------- */ case 19: /* Action */ s = trimleft(s); i = 0; if (*s == '(') { s++; if (strncasecmp(s, "mouse", 5) != 0) { fprintf(stderr, "%s: Couldn't parse " "action\n", MyName); } s += 5; i = strtol(s, &t, 10); s = t; while (*s && *s != ')') { s++; } if (*s == ')') { s++; } } { char *r; char *u = s; s = GetQuotedString(s, &t, ",)", NULL, "(", ")"); r = s; if (t && r > u + 1) { /* remove unquoted trailing spaces */ r -= 2; while (r >= u && isspace(*r)) { r--; } r++; if (isspace(*r)) { t[strlen(t) - (s - r - 1)] = 0; } } } if (t) { AddButtonAction(b,i,t); free(t); } else { fprintf(stderr, "%s: Missing action argument\n", MyName); } break; case 20: /* Id */ s = trimleft(s); s = DoGetNextToken(s, &t, NULL, ",)", &terminator); /* it should include the delimiter */ if (s && terminator == ')') { s--; } if (t) { if (isalpha(t[0])) { /* should check for duplicate ids first... */ b->flags.b_Id = 1; if (b->id) { free(b->id); } CopyString(&b->id, t); } else { fprintf(stderr, "%s: Incorrect id '%s' " "ignored\n", MyName, t); } free(t); } else { fprintf(stderr, "%s: Missing id argument\n", MyName); } break; /* ------------------ ActiveIcon --------------- */ case 21: /* ActiveIcon */ t = seekright(&s); if (t && *t && (t[0] != '-' || t[1] != 0)) { if (b->flags.b_Swallow) { fprintf(stderr, "%s: a button can not " "have a ActiveIcon and " "a swallowed window at " "the same time. " "Ignoring ActiveIcon.\n", MyName); } else { if (b->active_icon_file) { free(b->active_icon_file); } b->active_icon_file = t; b->flags.b_ActiveIcon = 1; } } else { fprintf(stderr, "%s: Missing ActiveIcon " "argument\n", MyName); if (t) { free(t); } } break; /* --------------- ActiveTitle --------------- */ case 22: /* ActiveTitle */ s = trimleft(s); if (*s == '(') { fprintf(stderr, "%s: justification not allowed " "for ActiveTitle.\n", MyName); } t = seekright(&s); if (t && *t && (t[0] != '-' || t[1] != 0)) { if (b->activeTitle) { free(b->activeTitle); } b->activeTitle = t; #ifdef DEBUG_PARSER fprintf(stderr, "PARSE: ActiveTitle \"%s\"\n", b->activeTitle); #endif b->flags.b_ActiveTitle = 1; } else { fprintf(stderr, "%s: Missing ActiveTitle " "argument\n", MyName); if (t) { free(t); } } break; /* --------------- PressIcon --------------- */ case 23: /* PressIcon */ t = seekright(&s); if (t && *t && (t[0] != '-' || t[1] != 0)) { if (b->flags.b_Swallow) { fprintf(stderr, "%s: a button can not " "have a PressIcon and " "a swallowed window at " "the same time. " "Ignoring PressIcon.\n", MyName); } else { if (b->press_icon_file) { free(b->press_icon_file); } b->press_icon_file = t; b->flags.b_PressIcon = 1; } } else { fprintf(stderr, "%s: Missing PressIcon " "argument\n", MyName); if (t) { free(t); } } break; /* --------------- PressTitle --------------- */ case 24: /* PressTitle */ s = trimleft(s); if (*s == '(') { fprintf(stderr, "%s: justification not allowed " "for PressTitle.\n", MyName); } t = seekright(&s); if (t && *t && (t[0] != '-' || t[1] != 0)) { if (b->pressTitle) { free(b->pressTitle); } b->pressTitle = t; #ifdef DEBUG_PARSER fprintf(stderr, "PARSE: PressTitle \"%s\"\n", b->pressTitle); #endif b->flags.b_PressTitle = 1; } else { fprintf(stderr, "%s: Missing PressTitle " "argument\n", MyName); if (t) { free(t); } } break; /* --------------- --------------- */ case 25: /* ActiveColorset */ i = strtol(s, &t, 10); if (t > s) { b->activeColorset = i; b->flags.b_ActiveColorset = 1; s = t; AllocColorset(i); } else { b->flags.b_ActiveColorset = 0; } break; /* --------------- --------------- */ case 26: /* PressColorset */ i = strtol(s, &t, 10); if (t > s) { b->pressColorset = i; b->flags.b_PressColorset = 1; s = t; AllocColorset(i); } else { b->flags.b_PressColorset = 0; } break; case 27: /* top */ b->flags.b_Top = 1; break; /* --------------- --------------- */ default: t = seekright(&s); fprintf(stderr, "%s: Illegal button option \"%s\"\n", MyName, (t) ? t : ""); if (t) { free(t); } break; } /* end switch */ s = trimleft(s); } if (s && *s) { s++; s = trimleft(s); } } /* get title and iconname */ if (!b->flags.b_Title) { b->title = seekright(&s); if (b->title && *b->title && ((b->title)[0] != '-' || (b->title)[1] != 0)) { b->flags.b_Title = 1; } else if (b->title) { free(b->title); } } else { char *temp; temp = seekright(&s); if (temp) { free(temp); } } if (!b->flags.b_Icon) { b->icon_file = seekright(&s); if (b->icon_file && b->icon_file && ((b->icon_file)[0] != '-'||(b->icon_file)[1] != 0)) { b->flags.b_Icon = 1; } else if (b->icon_file) { free(b->icon_file); } } else { char *temp; temp = seekright(&s); if (temp) { free(temp); } } s = trimleft(s); /* Swallow hangon command */ if (strncasecmp(s, "swallow", 7) == 0 || strncasecmp(s, "panel", 7) == 0) { if (b->flags.b_Swallow || b->flags.b_Panel) { fprintf(stderr, "%s: Illegal with both old and new swallow!\n", MyName); exit(1); } s += 7; /* * Swallow old 'swallowmodule' command */ if (strncasecmp(s, "module", 6) == 0) { s += 6; } if (b->hangon) { free(b->hangon); } b->hangon = seekright(&s); if (!b->hangon) { b->hangon = safestrdup(""); } if (tolower(*s) == 's') { b->flags.b_Swallow = 1; b->flags.b_Hangon = 1; } else { b->flags.b_Panel = 1; b->flags.b_Hangon = 1; } b->swallow |= 1; s = trimleft(s); if (!(b->swallow & b_NoHints)) { b->hints = (XSizeHints*)mymalloc(sizeof(XSizeHints)); } if (*s) { if (!(buttonSwallow(b) & b_UseOld)) { SendText(fd, s, 0); } b->spawn = safestrdup(s); } } else if (*s) { AddButtonAction(b, 0, s); } return; }
/*#define DEBUG_PARSER*/ static void ParseButton(button_info **uberb,char *s) { button_info *b,*ub=*uberb; int i,j; char *t,*o; b = alloc_button(ub, (ub->c->num_buttons)++); s = trimleft(s); if(*s=='(' && s++) { char *opts[] = { "back", "fore", "font", "title", "icon", "frame", "padding", "swallow", "panel", "action", "container", "end", "nosize", "size", "left", "right", "center", "colorset", NULL }; s = trimleft(s); while(*s && *s!=')') { Bool is_swallow = False; if (*s == ',') { s++; s = trimleft(s); continue; } if((*s>='0' && *s<='9') || *s=='+' || *s=='-') { char *geom; int x,y,flags; unsigned int w,h; geom=seekright(&s); if (geom) { flags=XParseGeometry(geom, &x, &y, &w, &h); if(flags&WidthValue) b->BWidth=w; if(flags&HeightValue) b->BHeight=h; if(flags&XValue) { b->BPosX=x; b->flags|=b_PosFixed; } if(flags&YValue) { b->BPosY=y; b->flags|=b_PosFixed; } if(flags&XNegative) b->BPosX=-1-x; if(flags&YNegative) b->BPosY=-1-y; free(geom); } s = trimleft(s); continue; } switch(GetTokenIndex(s,opts,-1,&s)) { case 0: /* Back */ s = trimleft(s); if(*s=='(' && s++) if(ParseBack(&s)) b->flags|=b_IconBack; if(b->flags&b_Back && b->back) free(b->back); b->back=seekright(&s); if(b->back) { b->flags|=b_Back; } else b->flags&=~(b_IconBack|b_Back); break; case 1: /* Fore */ if(b->flags&b_Fore && b->fore) free(b->fore); b->fore=seekright(&s); if(b->fore) { b->flags|=b_Fore; } else b->flags&=~b_Fore; break; case 2: /* Font */ if(b->flags&b_Font && b->font_string) free(b->font_string); b->font_string = my_get_font(&s); if(b->font_string) { b->flags|=b_Font; } else b->flags&=~b_Font; break; /* --------------------------- Title ------------------------- */ case 3: /* Title */ s = trimleft(s); if(*s=='(' && s++) { b->justify=0; b->justify_mask=0; ParseTitle(&s,&b->justify,&b->justify_mask); if(b->justify_mask) b->flags|=b_Justify; } t=seekright(&s); if(t && *t && (t[0]!='-' || t[1]!=0)) { if (b->title) free(b->title); b->title=t; #ifdef DEBUG_PARSER fprintf(stderr,"PARSE: Title \"%s\"\n",b->title); #endif b->flags|=b_Title; } else { fprintf(stderr,"%s: Missing title argument\n",MyName); if(t)free(t); } break; /* ---------------------------- icon ------------------------- */ case 4: /* Icon */ t=seekright(&s); if(t && *t && (t[0] != '-' || t[1] != 0)) { if (b->flags & b_Swallow) { fprintf( stderr,"%s: a button can not have an icon and a swallowed window" " at the same time. Ignoring icon", MyName); } else { if (b->icon_file) free(b->icon_file); b->icon_file=t; b->IconWin=None; b->flags|=b_Icon; } } else { fprintf(stderr,"%s: Missing icon argument\n",MyName); if(t)free(t); } break; /* --------------------------- frame ------------------------- */ case 5: /* Frame */ i=strtol(s,&t,10); if(t>s) { b->flags|=b_Frame; b->framew=i; s=t; } else fprintf(stderr,"%s: Illegal frame argument\n",MyName); break; /* -------------------------- padding ------------------------ */ case 6: /* Padding */ i=strtol(s,&t,10); if(t>s) { b->xpad=b->ypad=i; b->flags |= b_Padding; s=t; i=strtol(s,&t,10); if(t>s) { b->ypad=i; s=t; } } else fprintf(stderr,"%s: Illegal padding argument\n",MyName); break; /* -------------------------- swallow ------------------------ */ case 7: /* Swallow */ is_swallow = True; /* fall through */ case 8: /* Panel */ s = trimleft(s); if (is_swallow) { b->swallow=0; b->swallow_mask=0; } else { /* set defaults */ b->swallow = b_Respawn; b->swallow_mask = b_Respawn; b->slide_direction = SLIDE_UP; b->slide_position = SLIDE_POSITION_CENTER; b->slide_context = SLIDE_CONTEXT_PB; b->relative_x = 0; b->relative_y = 0; b->slide_steps = 12; b->slide_delay_ms = 5; } if(*s=='(' && s++) { if (is_swallow) ParseSwallow(&s, &b->swallow,&b->swallow_mask); else ParsePanel(&s, &b->swallow, &b->swallow_mask, &b->slide_direction, &b->slide_steps, &b->slide_delay_ms, &b->panel_flags, &b->indicator_size, &b->relative_x, &b->relative_y, &b->slide_position, &b->slide_context); } t=seekright(&s); o=seekright(&s); if(t) { if (b->hangon) free(b->hangon); b->hangon=t; if (is_swallow) { if (b->flags & b_Icon) { fprintf( stderr,"%s: a button can not have an icon and a swallowed " " window at the same time. Ignoring icon", MyName); b->flags &= ~ b_Icon; } b->flags |= (b_Swallow | b_Hangon); } else { b->flags |= (b_Panel | b_Hangon); b->newflags.is_panel = 1; b->newflags.panel_mapped = 0; } b->swallow|=1; if(!(b->swallow&b_NoHints)) b->hints=(XSizeHints*)mymalloc(sizeof(XSizeHints)); if(o) { char *p; p = expand_action(o, NULL); if (p) { if(!(buttonSwallow(b)&b_UseOld)) SendText(fd,p,0); if (b->spawn) free(b->spawn); b->spawn=o; /* Might be needed if respawning sometime */ free(p); } } } else { fprintf(stderr,"%s: Missing swallow argument\n",MyName); if(t) free(t); if(o) free(o); } break; /* --------------------------- action ------------------------ */ case 9: /* Action */ s = trimleft(s); i=0; if(*s=='(') { s++; if(strncasecmp(s,"mouse",5)!=0) { fprintf(stderr,"%s: Couldn't parse action\n",MyName); } s+=5; i=strtol(s,&t,10); s=t; while(*s && *s!=')') s++; if(*s==')') s++; } { char *r; char *u = s; s = GetQuotedString(s, &t, ",)", NULL, "(", ")"); r = s; if (t && r > u + 1) { /* remove unquoted trailing spaces */ r -= 2; while (r >= u && isspace(*r)) r--; r++; if (isspace(*r)) { t[strlen(t) - (s - r - 1)] = 0; } } } if(t) { AddButtonAction(b,i,t); free(t); } else fprintf(stderr,"%s: Missing action argument\n",MyName); break; /* -------------------------- container ---------------------- */ case 10: /* Container */ b->flags&=b_Frame|b_Back|b_Fore|b_Padding|b_Action; MakeContainer(b); *uberb=b; s = trimleft(s); if(*s=='(' && s++) ParseContainer(&s,b); break; case 11: /* End */ *uberb=ub->parent; ub->c->buttons[--(ub->c->num_buttons)]=NULL; free(b); if(!ub->parent) { fprintf(stderr,"%s: Unmatched END in config file\n",MyName); exit(1); } return; case 12: /* NoSize */ b->flags|=b_Size; b->minx=b->miny=0; break; case 13: /* Size */ i=strtol(s,&t,10); j=strtol(t,&o,10); if(t>s && o>t) { b->minx=i; b->miny=j; b->flags|=b_Size; s=o; } else fprintf(stderr,"%s: Illegal size arguments\n",MyName); break; case 14: /* Left */ b->flags |= b_Left; b->flags &= ~b_Right; break; case 15: /* Right */ b->flags |= b_Right; b->flags &= ~b_Left; break; case 16: /* Center */ b->flags &= ~(b_Right|b_Left); break; case 17: /* Colorset */ i = strtol(s, &t, 10); if(t > s) { b->colorset = i; b->flags |= b_Colorset; s=t; AllocColorset(i); } else { b->flags &= ~b_Colorset; } break; default: t=seekright(&s); fprintf(stderr,"%s: Illegal button option \"%s\"\n",MyName, (t)?t:""); if (t) free(t); break; } s = trimleft(s); } if (s && *s) { s++; s = trimleft(s); } } /* get title and iconname */ if(!(b->flags&b_Title)) { b->title=seekright(&s); if(b->title && *b->title && ((b->title)[0]!='-'||(b->title)[1]!=0)) b->flags |= b_Title; else if(b->title)free(b->title); } else { char *temp; temp = seekright(&s); if (temp) free(temp); } if(!(b->flags&b_Icon)) { b->icon_file=seekright(&s); if(b->icon_file && b->icon_file && ((b->icon_file)[0]!='-'||(b->icon_file)[1]!=0)) { b->flags|=b_Icon; b->IconWin=None; } else if(b->icon_file)free(b->icon_file); } else { char *temp; temp = seekright(&s); if (temp) free(temp); } s = trimleft(s); /* Swallow hangon command */ if (strncasecmp(s,"swallow",7)==0 || strncasecmp(s,"panel",7)==0) { if(b->flags & (b_Swallow | b_Panel)) { fprintf(stderr,"%s: Illegal with both old and new swallow!\n", MyName); exit(1); } s+=7; /* * Swallow old 'swallowmodule' command */ if (strncasecmp(s,"module",6)==0) { s+=6; } if (b->hangon) free(b->hangon); b->hangon=seekright(&s); if (!b->hangon) b->hangon = safestrdup(""); if (tolower(*s) == 's') b->flags |= b_Swallow | b_Hangon; else b->flags |= b_Panel | b_Hangon; b->swallow|=1; s = trimleft(s); if(!(b->swallow&b_NoHints)) b->hints=(XSizeHints*)mymalloc(sizeof(XSizeHints)); if(*s) { if(!(buttonSwallow(b)&b_UseOld)) SendText(fd,s,0); b->spawn=safestrdup(s); } } else if(*s) AddButtonAction(b,0,s); return; }
/** *** MakeButton() *** To position subwindows in a button: icons and swallowed windows. **/ void MakeButton(button_info *b) { /* This is resposible for drawing the contents of a button, placing the icon and/or swallowed item in the correct position inside potential padding or frame. */ int ih,iw,ix,iy; XFontStruct *font; if(!b) { fprintf(stderr,"%s: BUG: DrawButton called with NULL pointer\n",MyName); exit(2); } if(b->flags&b_Container) { fprintf(stderr,"%s: BUG: DrawButton called with container\n",MyName); exit(2); } if(!(b->flags&b_Icon) && (buttonSwallowCount(b)<3)) return; font = buttonFont(b); GetInternalSize(b,&ix,&iy,&iw,&ih); /* At this point iw,ih,ix and iy should be correct. Now all we have to do is place title and iconwin in their proper positions */ /* For now, use the old routine in icons.h for buttons with icons */ if(b->flags&b_Icon) ConfigureIconWindow(b); /* For now, hardcoded window centered, title bottom centered, below window */ else if(buttonSwallowCount(b)==3) { long supplied; if(!b->IconWin) { fprintf(stderr,"%s: BUG: Swallowed window has no IconWin\n",MyName); exit(2); } if(b->flags&b_Title && font && !(buttonJustify(b)&b_Horizontal)) ih -= font->ascent+font->descent; b->icon_w=iw; b->icon_h=ih; if(iw>0 && ih>0) { if(!(buttonSwallow(b)&b_NoHints)) { if(!XGetWMNormalHints(Dpy,b->IconWin,b->hints,&supplied)) b->hints->flags=0; ConstrainSize(b->hints,&b->icon_w,&b->icon_h); } XMoveResizeWindow(Dpy,b->IconWin,ix+(iw-b->icon_w)/2, iy+(ih-b->icon_h)/2,b->icon_w,b->icon_h); } else XMoveWindow(Dpy,b->IconWin,2000,2000); } }
/*#define DEBUG_PARSER*/ void match_string(button_info **uberb,char *s) { button_info *b,*ub=*uberb; int i,j; char *t,*o; b=alloc_button(ub,(ub->c->num_buttons)++); trimleft(s); if(*s=='(' && s++) { char *opts[]= {"back","fore","font","title","icon","frame","padding", "swallow","action","container","end","nosize","size", NULL }; trimleft(s); while(*s && *s!=')') { if(*s>='0' && *s<='9') { sscanf(s,"%dx%d",&i,&j); if(i>0) b->BWidth=i; if(j>0) b->BHeight=j; while(*s!=' ' && *s!='\t' && *s!=')' && *s!=',') s++; trimleft(s); continue; } if(*s==',' && s++) trimleft(s); switch(MatchSeveralLines(s,opts,&s)) { case 0: /* Back */ trimleft(s); if(*s=='(' && s++) if(ParseBack(&s)) b->flags|=b_IconBack; if(b->flags&b_Back) free(b->back); b->back=seekright(&s); if(b->back) b->flags|=b_Back; else b->flags&=~b_IconBack; break; case 1: /* Fore */ if(b->flags&b_Fore) free(b->fore); b->fore=seekright(&s); b->flags|=b_Fore; break; case 2: /* Font */ if(b->flags&b_Font) free(b->font_string); b->font_string=seekright(&s); b->flags|=b_Font; break; /* --------------------------- Title ------------------------- */ case 3: /* Title */ trimleft(s); if(*s=='(' && s++) { b->justify=0; b->justify_mask=0; ParseTitle(&s,&b->justify,&b->justify_mask); if(b->justify_mask) b->flags|=b_Justify; } t=seekright(&s); if(t && (t[0]!='-' || t[1]!=0)) { b->title=t; #ifdef DEBUG_PARSER fprintf(stderr,"PARSE: Title \"%s\"\n",b->title); #endif b->flags|=b_Title; } else { fprintf(stderr,"%s: Missing title argument\n",MyName); if(t)free(t); } break; /* ---------------------------- icon ------------------------- */ case 4: /* Icon */ t=seekright(&s); if(t && (t[0]!='-' && t[1]!=0)) { b->icon_file=t; b->IconWin=None; b->flags|=b_Icon; } else { fprintf(stderr,"%s: Missing icon argument\n",MyName); if(t)free(t); } break; /* --------------------------- frame ------------------------- */ case 5: /* Frame */ i=strtol(s,&t,10); if(t>s) { b->flags|=b_Frame; b->framew=i; s=t; } else fprintf(stderr,"%s: Illegal frame argument\n",MyName); break; /* -------------------------- padding ------------------------ */ case 6: /* Padding */ i=strtol(s,&t,10); if(t>s) { b->xpad=b->ypad=i; b->flags |= b_Padding; s=t; i=strtol(s,&t,10); if(t>s) { b->ypad=i; s=t; } } else fprintf(stderr,"%s: Illegal padding argument\n",MyName); break; /* -------------------------- swallow ------------------------ */ case 7: /* Swallow */ trimleft(s); b->swallow=0; b->swallow_mask=0; if(*s=='(' && s++) ParseSwallow(&s,&b->swallow,&b->swallow_mask); t=seekright(&s); o=seekright(&s); if(t) { b->hangon=t; b->flags|=b_Hangon; b->flags|=b_Swallow; b->swallow|=1; if(!(b->swallow&b_NoHints)) b->hints=(XSizeHints*)mymalloc(sizeof(XSizeHints)); if(o) { if(!(buttonSwallow(b)&b_UseOld)) SendText(fd,o,0); b->spawn=o; /* Might be needed if respawning sometime */ } } else { fprintf(stderr,"%s: Missing swallow argument\n",MyName); if(t)free(t); if(o)free(o); } break; /* --------------------------- action ------------------------ */ case 8: /* Action */ trimleft(s); i=0; if(*s=='(') { s++; if(strncasecmp(s,"mouse",5)!=0) { fprintf(stderr,"%s: Couldn't parse action\n",MyName); } s+=5; i=strtol(s,&t,10); s=t; while(*s && *s!=')') s++; if(*s==')')s++; } t=seekright(&s); if(t) AddButtonAction(b,i,strdup(t)); else fprintf(stderr,"%s: Missing action argument\n",MyName); break; /* -------------------------- container ---------------------- */ case 9: /* Container */ b->flags&=b_Frame|b_Back|b_Fore|b_Padding|b_Action; MakeContainer(b); *uberb=b; trimleft(s); if(*s=='(' && s++) ParseContainer(&s,b); break; case 10: /* End */ *uberb=ub->parent; ub->c->buttons[--(ub->c->num_buttons)]=NULL; if(!ub->parent) { fprintf(stderr,"%s: Unmatched END in config file\n",MyName); exit(1); } break; case 11: /* NoSize */ b->flags|=b_Size; b->minx=b->miny=0; break; case 12: /* Size */ i=strtol(s,&t,10); j=strtol(t,&o,10); if(t>s && o>t) { b->minx=i; b->miny=j; b->flags|=b_Size; s=o; } else fprintf(stderr,"%s: Illegal size arguments\n",MyName); break; default: t=seekright(&s); fprintf(stderr,"%s: Illegal button option \"%s\"\n",MyName,t); free(t); break; } trimleft(s); } s++; trimleft(s); } /* get title and iconname */ if(!(b->flags&b_Title)) { b->title=seekright(&s); if(b->title && ((b->title)[0]!='-'||(b->title)[1]!=0)) b->flags |= b_Title; else if(b->title)free(b->title); } else free(seekright(&s)); if(!(b->flags&b_Icon)) { b->icon_file=seekright(&s); if(b->icon_file && ((b->icon_file)[0]!='-'||(b->icon_file)[1]!=0)) { b->flags|=b_Icon; b->IconWin=None; } else if(b->icon_file)free(b->icon_file); } else free(seekright(&s)); trimleft(s); /* Swallow hangon command */ if(strncasecmp(s,"swallow",7)==0) { if(b->flags&b_Swallow) { fprintf(stderr,"%s: Illegal with both old and new swallow!\n", MyName); exit(1); } s+=7; b->hangon=seekright(&s); b->flags|=(b_Swallow|b_Hangon); b->swallow|=1; trimleft(s); if(!(b->swallow&b_NoHints)) b->hints=(XSizeHints*)mymalloc(sizeof(XSizeHints)); if(*s) { if(!(buttonSwallow(b)&b_UseOld)) SendText(fd,s,0); b->spawn=strdup(s); } } else if(*s) AddButtonAction(b,0,strdup(s)); return; }