3 * FvwmButtons, copyright 1996, Jarl Totland
5 * This module, and the entire GoodStuff program, and the concept for
6 * interfacing this module to the Window Manager, are all original work
9 * Copyright 1993, Robert Nation. No guarantees or warantees or anything
10 * are provided or implied in any way whatsoever. Use this program at your
11 * own risk. Permission to use this program for any purpose is given,
12 * as long as the copyright is kept intact.
16 /* This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
37 #include <X11/Intrinsic.h>
39 #include "libs/fvwmlib.h"
40 #include "libs/FScreen.h"
41 #include "libs/Module.h"
42 #include "libs/Colorset.h"
43 #include "libs/Parse.h"
44 #include "libs/Strings.h"
45 #include "FvwmButtons.h"
49 extern int w
, h
, x
, y
, xneg
, yneg
; /* used in ParseConfigLine */
50 extern char *config_file
;
51 extern int button_width
;
52 extern int button_height
;
53 extern int has_button_geometry
;
56 /* contains the character that terminated the last string from seekright */
57 static char terminator
= '\0';
59 /* ----------------------------------- macros ------------------------------ */
61 static char *trimleft(char *s
)
63 while (s
&& isspace((unsigned char)*s
))
73 *** split off the first continous section of the string into a new allocated
74 *** string and move the old pointer forward. Accepts and strips quoting with
75 *** ['"`], and the current quote q can be escaped inside the string with \q.
77 static char *seekright(char **s
)
82 line
= DoGetNextToken(line
, &token
, NULL
, "),", &terminator
);
83 if (*s
!= NULL
&& line
== NULL
)
85 line
= strchr(*s
, '\0');
92 static char *my_get_font(char **s
)
97 *s
= GetNextFullOption(*s
, &option
);
100 for (len
= strlen(option
) - 1; len
>= 0 && isspace(option
[len
]); len
--)
102 /* remove trailing whitespace */
105 for ( ; *option
&& isspace(*option
); option
++)
107 /* remove leading whitespace */
111 len
= strlen(option
) -1;
112 if (option
[len
] == ')' )
122 *** Parses the options possible to Back
123 *** This function appears to be obsolete & should be removed -- SS.
125 static int ParseBack(char **ss
)
135 while (*s
&& *s
!= ')')
144 switch (GetTokenIndex(s
, opts
, -1, &s
))
149 "%s: Back(Icon) not supported yet\n",
155 "%s: Illegal back option \"%s\"\n",
156 MyName
, (t
) ? t
: "");
174 *** Parses the options possible to BoxSize
176 static void ParseBoxSize(char **ss
, flags_type
*flags
)
192 *ss
= GetNextTokenIndex(*ss
, opts
, 0, &m
);
196 flags
->b_SizeFixed
= 0;
197 flags
->b_SizeSmart
= 0;
200 flags
->b_SizeFixed
= 1;
201 flags
->b_SizeSmart
= 0;
204 flags
->b_SizeSmart
= 1;
205 flags
->b_SizeFixed
= 0;
208 flags
->b_SizeFixed
= 0;
209 flags
->b_SizeSmart
= 0;
211 "%s: Illegal boxsize option \"%s\"\n",
220 *** Parses the options possible to Title
222 static void ParseTitle(char **ss
, byte
*flags
, byte
*mask
)
234 while (*s
&& *s
!= ')')
243 switch (GetTokenIndex(s
, titleopts
, -1, &s
))
246 *flags
&= ~b_TitleHoriz
;
248 *mask
|= b_TitleHoriz
;
251 *flags
&= ~b_TitleHoriz
;
254 *mask
|= b_TitleHoriz
;
257 *flags
&= ~b_TitleHoriz
;
260 *mask
|= b_TitleHoriz
;
263 *flags
|= b_Horizontal
;
265 *mask
|= b_Horizontal
;
270 "%s: Illegal title option \"%s\"\n",
271 MyName
, (t
) ? t
: "");
287 *** Parses the options possible to Swallow
289 static void ParseSwallow(
290 char **ss
, unsigned int *flags
, unsigned int *mask
, button_info
*b
)
292 char *swallowopts
[] =
297 "respawn", "norespawn",
299 "usetitle", "notitle",
300 "fvwmmodule", "nofvwmmodule",
306 while (*s
&& *s
!= ')')
315 switch (GetTokenIndex(s
, swallowopts
, -1, &s
))
317 case 0: /* NoHints */
322 *flags
&= ~b_NoHints
;
333 case 4: /* NoClose */
338 *flags
&= ~b_NoClose
;
341 case 6: /* Respawn */
344 b
->newflags
.do_swallow_new
= 0;
346 case 7: /* NoRespawn */
347 *flags
&= ~b_Respawn
;
349 b
->newflags
.do_swallow_new
= 0;
359 case 10: /* UseTitle */
360 *flags
|= b_UseTitle
;
363 case 11: /* NoTitle */
364 *flags
&= ~b_UseTitle
;
367 case 12: /* FvwmModule */
368 *flags
|= b_FvwmModule
;
369 *mask
|= b_FvwmModule
;
371 case 13: /* NoFvwmModule */
372 *flags
&= ~b_FvwmModule
;
373 *mask
|= b_FvwmModule
;
375 case 14: /* SwallowNew */
376 *flags
&= ~b_Respawn
;
378 b
->newflags
.do_swallow_new
= 1;
383 "%s: Illegal Swallow option \"%s\"\n", MyName
,
400 *** Parses the options possible to Panel
402 static void ParsePanel(
403 char **ss
, unsigned int *flags
, unsigned int *mask
, char *direction
,
404 int *steps
, int *delay
, panel_flags_type
*panel_flags
,
405 int *indicator_size
, int *rela_x
, int *rela_y
, char *position
,
408 char *swallowopts
[] =
413 "respawn", "norespawn",
415 "usetitle", "notitle",
416 "up", "down", "left", "right",
426 char *positionopts
[] =
428 "button", "module", "root", "center", "left", "top", "right",
429 "bottom", "noplr", "noptb", "mlr", "mtb", NULL
435 while (*s
&& *s
!= ')')
444 switch (GetTokenIndex(s
, swallowopts
, -1, &s
))
446 case 0: /* NoHints */
451 *flags
&= ~b_NoHints
;
462 case 4: /* NoClose */
467 *flags
&= ~b_NoClose
;
470 case 6: /* Respawn */
474 case 7: /* NoRespawn */
475 *flags
&= ~b_Respawn
;
486 case 10: /* UseTitle */
487 *flags
|= b_UseTitle
;
490 case 11: /* NoTitle */
491 *flags
&= ~b_UseTitle
;
495 *direction
= SLIDE_UP
;
498 *direction
= SLIDE_DOWN
;
501 *direction
= SLIDE_LEFT
;
504 *direction
= SLIDE_RIGHT
;
507 sscanf(s
, "%d%n", steps
, &n
);
511 sscanf(s
, "%d%n", delay
, &n
);
514 case 18: /* smooth */
515 (*panel_flags
).smooth
= 1;
517 case 19: /* noborder */
518 (*panel_flags
).ignore_lrborder
= 1;
519 (*panel_flags
).ignore_tbborder
= 1;
521 case 20: /* indicator */
523 (*panel_flags
).panel_indicator
= 1;
525 sscanf(s
, "%d%n", indicator_size
, &n
);
526 if (*indicator_size
< 0 || *indicator_size
> 100)
532 case 21: /* position */
534 *rela_x
= *rela_y
= 0;
535 while (*s
!= ',' && *s
!= ')' && *s
)
538 /* get x and y offset */
539 if (isdigit(*s
) || *s
== '+' || *s
== '-')
541 sscanf(s
, "%i%n", rela_x
, &n
);
543 if (*s
== 'p' || *s
== 'P')
545 (*panel_flags
).relative_x_pixel
= 1;
550 sscanf(s
, "%i%n", rela_y
, &n
);
552 if (*s
== 'p' || *s
== 'P')
554 (*panel_flags
).relative_y_pixel
= 1;
559 switch (GetTokenIndex(s
, positionopts
, -1, &s
))
562 *context
= SLIDE_CONTEXT_PB
;
565 *context
= SLIDE_CONTEXT_MODULE
;
568 *context
= SLIDE_CONTEXT_ROOT
;
571 *position
= SLIDE_POSITION_CENTER
;
574 *position
= SLIDE_POSITION_LEFT_TOP
;
577 *position
= SLIDE_POSITION_LEFT_TOP
;
580 *position
= SLIDE_POSITION_RIGHT_BOTTOM
;
583 *position
= SLIDE_POSITION_RIGHT_BOTTOM
;
586 (*panel_flags
).ignore_lrborder
= 1;
589 (*panel_flags
).ignore_tbborder
= 1;
592 (*panel_flags
).buttons_lrborder
= 1;
595 (*panel_flags
).buttons_tbborder
= 1;
604 "position option %s\n",
605 MyName
, (t
) ? t
: "");
614 "%s: Illegal Panel option \"%s\"\n", MyName
,
631 *** Parses the options possible to Container
633 static void ParseContainer(char **ss
,button_info
*b
)
652 char *t
, *o
, *s
= *ss
;
655 while (*s
&& *s
!= ')')
664 switch (GetTokenIndex(s
, conts
, -1, &s
))
666 case 0: /* Columns */
667 b
->c
->num_columns
= max(1, strtol(s
, &t
, 10));
671 b
->c
->num_rows
= max(1, strtol(s
, &t
, 10));
675 if (b
->c
->font_string
)
677 free(b
->c
->font_string
);
679 b
->c
->font_string
= my_get_font(&s
);
680 b
->c
->flags
.b_Font
= (b
->c
->font_string
? 1 : 0);
683 b
->c
->framew
= strtol(s
, &t
, 10);
684 b
->c
->flags
.b_Frame
= 1;
689 if (*s
== '(' && s
++ && ParseBack(&s
))
691 b
->c
->flags
.b_IconBack
= 1;
697 b
->c
->back
= seekright(&s
);
700 b
->c
->flags
.b_Back
= 1;
704 b
->c
->flags
.b_IconBack
= 0;
705 b
->c
->flags
.b_Back
= 0;
709 if (b
->c
->fore
) free(b
->c
->fore
);
710 b
->c
->fore
= seekright(&s
);
711 b
->c
->flags
.b_Fore
= (b
->c
->fore
? 1 : 0);
713 case 6: /* Padding */
714 i
= strtol(s
, &t
, 10);
717 b
->c
->xpad
= b
->c
->ypad
= i
;
719 i
= strtol(s
, &t
, 10);
725 b
->c
->flags
.b_Padding
= 1;
728 fprintf(stderr
,"%s: Illegal padding argument\n",MyName
);
730 case 7: /* Title - flags */
732 if (*s
== '(' && s
++)
735 b
->c
->justify_mask
= 0;
736 ParseTitle(&s
, &b
->c
->justify
, &b
->c
->justify_mask
);
737 if (b
->c
->justify_mask
)
739 b
->c
->flags
.b_Justify
= 1;
746 "%s: Illegal title in container options\n",
748 temp
= seekright(&s
);
755 case 8: /* Swallow - flags */
760 if (b
->c
->flags
.b_Swallow
|| b
->c
->flags
.b_Panel
)
762 fprintf(stderr
, "%s: Multiple Swallow or Panel options are not"
763 " allowed in a single button", MyName
);
766 else if (*s
== '(' && s
++)
769 b
->c
->swallow_mask
= 0;
770 ParseSwallow(&s
, &b
->c
->swallow
, &b
->c
->swallow_mask
, b
);
771 if (b
->c
->swallow_mask
)
773 b
->c
->flags
.b_Swallow
= 1;
779 "%s: Illegal swallow or panel in container options\n",
787 temp
= seekright(&s
);
794 b
->c
->flags
.b_Size
= 1;
795 b
->c
->minx
= b
->c
->miny
= 0;
799 i
= strtol(s
, &t
, 10);
800 j
= strtol(t
, &o
, 10);
805 b
->c
->flags
.b_Size
= 1;
809 fprintf(stderr
,"%s: Illegal size arguments\n",MyName
);
812 case 11: /* BoxSize */
813 ParseBoxSize(&s
, &b
->c
->flags
);
816 case 12: /* Colorset */
817 i
= strtol(s
, &t
, 10);
821 b
->c
->flags
.b_Colorset
= 1;
827 b
->c
->flags
.b_Colorset
= 0;
833 fprintf(stderr
,"%s: Illegal container option \"%s\"\n",MyName
, (t
)?t
:"");
848 *** parse a buttonconfig string.
849 *** *FvwmButtons: (option[ options]) title iconname command
851 /*#define DEBUG_PARSER*/
852 static void ParseButton(button_info
**uberb
, char *s
)
854 button_info
*b
, *ub
= *uberb
;
858 b
= alloc_button(ub
, (ub
->c
->num_buttons
)++);
861 if (*s
== '(' && s
++)
874 "actionignoresclientwindow",
896 while (*s
&& *s
!= ')')
898 Bool is_swallow
= False
;
906 if (isdigit(*s
) || *s
== '+' || *s
== '-')
911 geom
= seekright(&s
);
914 flags
= XParseGeometry(geom
, &x
, &y
, &w
, &h
);
915 if (flags
&WidthValue
)
919 if (flags
&HeightValue
)
926 b
->flags
.b_PosFixed
= 1;
931 b
->flags
.b_PosFixed
= 1;
933 if (flags
& XNegative
)
937 if (flags
& YNegative
)
946 switch (GetTokenIndex(s
, opts
, -1, &s
))
950 if (*s
== '(' && s
++ && ParseBack(&s
))
952 b
->flags
.b_IconBack
= 1;
954 if (b
->flags
.b_Back
&& b
->back
)
958 b
->back
= seekright(&s
);
965 b
->flags
.b_IconBack
= 0;
971 if (b
->flags
.b_Fore
&& b
->fore
)
975 b
->fore
= seekright(&s
);
976 b
->flags
.b_Fore
= (b
->fore
? 1 : 0);
980 if (b
->flags
.b_Font
&& b
->font_string
)
982 free(b
->font_string
);
984 b
->font_string
= my_get_font(&s
);
985 b
->flags
.b_Font
= (b
->font_string
? 1 : 0);
988 /* ----------------- title --------------- */
992 if (*s
== '(' && s
++)
1001 b
->flags
.b_Justify
= 1;
1005 if (t
&& *t
&& (t
[0] != '-' || t
[1] != 0))
1014 "PARSE: Title \"%s\"\n",
1017 b
->flags
.b_Title
= 1;
1022 "%s: Missing title argument\n",
1031 /* ------------------ icon --------------- */
1035 if (t
&& *t
&& (t
[0] != '-' || t
[1] != 0))
1037 if (b
->flags
.b_Swallow
)
1040 "%s: a button can not "
1041 "have an icon and a "
1042 "swallowed window at "
1054 b
->flags
.b_Icon
= 1;
1060 "%s: Missing Icon argument\n",
1069 /* ----------------- frame --------------- */
1072 i
= strtol(s
, &t
, 10);
1075 b
->flags
.b_Frame
= 1;
1082 "%s: Illegal frame argument\n",
1087 /* ---------------- padding -------------- */
1089 case 6: /* Padding */
1090 i
= strtol(s
,&t
,10);
1093 b
->xpad
= b
->ypad
= i
;
1094 b
->flags
.b_Padding
= 1;
1096 i
= strtol(s
, &t
, 10);
1106 "%s: Illegal padding "
1107 "argument\n", MyName
);
1111 /* ---------------- swallow -------------- */
1113 case 7: /* Swallow */
1122 b
->swallow_mask
= 0;
1127 b
->swallow
= b_Respawn
;
1128 b
->swallow_mask
= b_Respawn
;
1129 b
->slide_direction
= SLIDE_UP
;
1130 b
->slide_position
= SLIDE_POSITION_CENTER
;
1131 b
->slide_context
= SLIDE_CONTEXT_PB
;
1134 b
->slide_steps
= 12;
1135 b
->slide_delay_ms
= 5;
1137 if (*s
== '(' && s
++)
1143 &b
->swallow_mask
, b
);
1150 &b
->slide_direction
,
1172 if (b
->flags
.b_Icon
)
1175 "%s: a button can not "
1176 "have an icon and a "
1177 "swallowed window at "
1181 b
->flags
.b_Icon
= 0;
1184 b
->flags
.b_Swallow
= 1;
1185 b
->flags
.b_Hangon
= 1;
1189 b
->flags
.b_Panel
= 1;
1190 b
->flags
.b_Hangon
= 1;
1191 b
->newflags
.is_panel
= 1;
1192 b
->newflags
.panel_mapped
= 0;
1195 if (!(b
->swallow
& b_NoHints
))
1197 b
->hints
= (XSizeHints
*)
1198 mymalloc(sizeof(XSizeHints
));
1204 p
= module_expand_action(
1205 Dpy
, screen
, o
, NULL
,
1206 UberButton
->c
->fore
,
1207 UberButton
->c
->back
);
1210 if (!(buttonSwallow(b
)&b_UseOld
))
1219 /* Might be needed if
1220 * respawning sometime
1230 "%s: Missing swallow "
1231 "argument\n", MyName
);
1241 /* check if it is a module by command line inspection if
1242 * this hints has not been given in the swallow option */
1243 if (is_swallow
&& !(b
->swallow_mask
& b_FvwmModule
))
1245 if (b
->spawn
!= NULL
&&
1246 (strncasecmp(b
->spawn
, "module", 6) == 0 ||
1247 strncasecmp(b
->spawn
, "fvwm", 4) == 0))
1249 b
->swallow
|= b_FvwmModule
;
1254 case 9: /* ActionIgnoresClientWindow */
1255 b
->flags
.b_ActionIgnoresClientWindow
= 1;
1258 case 10: /* ActionOnPress */
1259 b
->flags
.b_ActionOnPress
= 1;
1262 /* ---------------- container ------------ */
1264 case 11: /* Container */
1266 * SS: This looks very buggy! The FvwmButtons
1267 * man page suggests it's here to restrict the
1268 * options used with "Container", but it only
1269 * restricts those options appearing _before_
1270 * the "Container" keyword for a button.
1271 * b->flags&=b_Frame|b_Back|b_Fore|b_Padding|b_Action;
1277 if (*s
== '(' && s
++)
1279 ParseContainer(&s
,b
);
1284 *uberb
= ub
->parent
;
1285 ub
->c
->buttons
[--(ub
->c
->num_buttons
)] = NULL
;
1289 fprintf(stderr
,"%s: Unmatched END in config file\n",MyName
);
1292 if (ub
->parent
->c
->flags
.b_Colorset
||
1293 ub
->parent
->c
->flags
.b_ColorsetParent
)
1295 ub
->c
->flags
.b_ColorsetParent
= 1;
1297 if (ub
->parent
->c
->flags
.b_IconBack
|| ub
->parent
->c
->flags
.b_IconParent
)
1299 ub
->c
->flags
.b_IconParent
= 1;
1303 case 13: /* NoSize */
1304 b
->flags
.b_Size
= 1;
1305 b
->minx
= b
->miny
= 0;
1309 i
= strtol(s
, &t
, 10);
1310 j
= strtol(t
, &o
, 10);
1315 b
->flags
.b_Size
= 1;
1321 "%s: Illegal size arguments\n",
1327 b
->flags
.b_Left
= 1;
1328 b
->flags
.b_Right
= 0;
1331 case 16: /* Right */
1332 b
->flags
.b_Right
= 1;
1333 b
->flags
.b_Left
= 0;
1336 case 17: /* Center */
1337 b
->flags
.b_Right
= 0;
1338 b
->flags
.b_Left
= 0;
1341 case 18: /* Colorset */
1342 i
= strtol(s
, &t
, 10);
1346 b
->flags
.b_Colorset
= 1;
1352 b
->flags
.b_Colorset
= 0;
1356 /* ----------------- action -------------- */
1358 case 19: /* Action */
1364 if (strncasecmp(s
, "mouse", 5) != 0)
1367 "%s: Couldn't parse "
1368 "action\n", MyName
);
1371 i
= strtol(s
, &t
, 10);
1373 while (*s
&& *s
!= ')')
1386 s
= GetQuotedString(s
, &t
, ",)", NULL
, "(", ")");
1390 /* remove unquoted trailing spaces */
1392 while (r
>= u
&& isspace(*r
))
1399 t
[strlen(t
) - (s
- r
- 1)] = 0;
1405 AddButtonAction(b
,i
,t
);
1411 "%s: Missing action argument\n",
1418 s
= DoGetNextToken(s
, &t
, NULL
, ",)", &terminator
);
1420 /* it should include the delimiter */
1421 if (s
&& terminator
== ')')
1430 /* should check for duplicate ids first... */
1436 CopyString(&b
->id
, t
);
1441 "%s: Incorrect id '%s' "
1442 "ignored\n", MyName
, t
);
1449 "%s: Missing id argument\n",
1454 /* ------------------ ActiveIcon --------------- */
1455 case 21: /* ActiveIcon */
1457 if (t
&& *t
&& (t
[0] != '-' || t
[1] != 0))
1459 if (b
->flags
.b_Swallow
)
1462 "%s: a button can not "
1463 "have a ActiveIcon and "
1464 "a swallowed window at "
1466 "Ignoring ActiveIcon.\n",
1471 if (b
->active_icon_file
)
1473 free(b
->active_icon_file
);
1475 b
->active_icon_file
= t
;
1476 b
->flags
.b_ActiveIcon
= 1;
1482 "%s: Missing ActiveIcon "
1483 "argument\n", MyName
);
1491 /* --------------- ActiveTitle --------------- */
1492 case 22: /* ActiveTitle */
1497 "%s: justification not allowed "
1498 "for ActiveTitle.\n", MyName
);
1501 if (t
&& *t
&& (t
[0] != '-' || t
[1] != 0))
1505 free(b
->activeTitle
);
1510 "PARSE: ActiveTitle \"%s\"\n",
1513 b
->flags
.b_ActiveTitle
= 1;
1518 "%s: Missing ActiveTitle "
1519 "argument\n", MyName
);
1527 /* --------------- PressIcon --------------- */
1528 case 23: /* PressIcon */
1530 if (t
&& *t
&& (t
[0] != '-' || t
[1] != 0))
1532 if (b
->flags
.b_Swallow
)
1535 "%s: a button can not "
1536 "have a PressIcon and "
1537 "a swallowed window at "
1539 "Ignoring PressIcon.\n",
1544 if (b
->press_icon_file
)
1546 free(b
->press_icon_file
);
1548 b
->press_icon_file
= t
;
1549 b
->flags
.b_PressIcon
= 1;
1555 "%s: Missing PressIcon "
1556 "argument\n", MyName
);
1564 /* --------------- PressTitle --------------- */
1565 case 24: /* PressTitle */
1570 "%s: justification not allowed "
1571 "for PressTitle.\n", MyName
);
1574 if (t
&& *t
&& (t
[0] != '-' || t
[1] != 0))
1578 free(b
->pressTitle
);
1583 "PARSE: PressTitle \"%s\"\n",
1586 b
->flags
.b_PressTitle
= 1;
1591 "%s: Missing PressTitle "
1592 "argument\n", MyName
);
1600 /* --------------- --------------- */
1601 case 25: /* ActiveColorset */
1602 i
= strtol(s
, &t
, 10);
1605 b
->activeColorset
= i
;
1606 b
->flags
.b_ActiveColorset
= 1;
1612 b
->flags
.b_ActiveColorset
= 0;
1616 /* --------------- --------------- */
1617 case 26: /* PressColorset */
1618 i
= strtol(s
, &t
, 10);
1621 b
->pressColorset
= i
;
1622 b
->flags
.b_PressColorset
= 1;
1628 b
->flags
.b_PressColorset
= 0;
1635 /* --------------- --------------- */
1639 "%s: Illegal button option \"%s\"\n",
1640 MyName
, (t
) ? t
: "");
1656 /* get title and iconname */
1657 if (!b
->flags
.b_Title
)
1659 b
->title
= seekright(&s
);
1660 if (b
->title
&& *b
->title
&&
1661 ((b
->title
)[0] != '-' || (b
->title
)[1] != 0))
1663 b
->flags
.b_Title
= 1;
1673 temp
= seekright(&s
);
1680 if (!b
->flags
.b_Icon
)
1682 b
->icon_file
= seekright(&s
);
1683 if (b
->icon_file
&& b
->icon_file
&&
1684 ((b
->icon_file
)[0] != '-'||(b
->icon_file
)[1] != 0))
1686 b
->flags
.b_Icon
= 1;
1688 else if (b
->icon_file
)
1696 temp
= seekright(&s
);
1705 /* Swallow hangon command */
1706 if (strncasecmp(s
, "swallow", 7) == 0 || strncasecmp(s
, "panel", 7) == 0)
1708 if (b
->flags
.b_Swallow
|| b
->flags
.b_Panel
)
1711 "%s: Illegal with both old and new swallow!\n",
1717 * Swallow old 'swallowmodule' command
1719 if (strncasecmp(s
, "module", 6) == 0)
1727 b
->hangon
= seekright(&s
);
1730 b
->hangon
= safestrdup("");
1732 if (tolower(*s
) == 's')
1734 b
->flags
.b_Swallow
= 1;
1735 b
->flags
.b_Hangon
= 1;
1739 b
->flags
.b_Panel
= 1;
1740 b
->flags
.b_Hangon
= 1;
1744 if (!(b
->swallow
& b_NoHints
))
1746 b
->hints
= (XSizeHints
*)mymalloc(sizeof(XSizeHints
));
1750 if (!(buttonSwallow(b
) & b_UseOld
))
1754 b
->spawn
= safestrdup(s
);
1759 AddButtonAction(b
, 0, s
);
1767 static void ParseConfigLine(button_info
**ubb
, char *s
)
1769 button_info
*ub
= *ubb
;
1791 switch (GetTokenIndex(s
, opts
, -1, &s
))
1793 case 0:/* Geometry */
1797 i
= sscanf(s
, "%63s", geom
);
1800 parse_window_geometry(geom
, 0);
1804 case 1:/* ButtonGeometry */
1808 i
= sscanf(s
, "%63s", geom
);
1811 parse_window_geometry(geom
, 1);
1816 if (ub
->c
->font_string
)
1818 free(ub
->c
->font_string
);
1820 CopyStringWithQuotes(&ub
->c
->font_string
, s
);
1822 case 3:/* Padding */
1823 i
= sscanf(s
, "%d %d", &j
, &k
);
1826 ub
->c
->xpad
= ub
->c
->ypad
= j
;
1833 case 4:/* Columns */
1834 i
= sscanf(s
, "%d", &j
);
1837 ub
->c
->num_columns
= j
;
1841 i
= sscanf(s
, "%d", &j
);
1844 ub
->c
->num_rows
= j
;
1852 CopyString(&(ub
->c
->back
), s
);
1859 CopyString(&(ub
->c
->fore
), s
);
1862 i
= sscanf(s
,"%d",&j
);
1874 config_file
= seekright(&s
);
1876 case 10:/* Pixmap */
1878 if (strncasecmp(s
, "none", 4) == 0)
1880 ub
->c
->flags
.b_TransBack
= 1;
1884 if (ub
->c
->back_file
)
1886 free(ub
->c
->back_file
);
1888 CopyString(&(ub
->c
->back_file
),s
);
1890 ub
->c
->flags
.b_IconBack
= 1;
1892 case 11: /* BoxSize */
1893 ParseBoxSize(&s
, &ub
->c
->flags
);
1895 case 12: /* Colorset */
1896 i
= sscanf(s
, "%d", &j
);
1899 ub
->c
->colorset
= j
;
1900 ub
->c
->flags
.b_Colorset
= 1;
1905 ub
->c
->flags
.b_Colorset
= 0;
1908 case 13: /* ActiveColorset */
1909 i
= sscanf(s
, "%d", &j
);
1912 ub
->c
->activeColorset
= j
;
1913 ub
->c
->flags
.b_ActiveColorset
= 1;
1918 ub
->c
->flags
.b_ActiveColorset
= 0;
1921 case 14: /* PressColorset */
1922 i
= sscanf(s
, "%d", &j
);
1925 ub
->c
->pressColorset
= j
;
1926 ub
->c
->flags
.b_PressColorset
= 1;
1931 ub
->c
->flags
.b_PressColorset
= 0;
1937 ParseButton(ubb
, s
);
1943 *** ParseConfigFile()
1944 *** Parses optional separate configuration file for FvwmButtons
1946 static void ParseConfigFile(button_info
*ub
)
1949 FILE *f
= fopen(config_file
, "r");
1954 "%s: Couldn't open config file %s\n", MyName
,
1959 while (fgets(s
, 1023, f
))
1961 /* Allow for line continuation: */
1962 while ((l
= strlen(s
)) < sizeof(s
)
1963 && l
>= 2 && s
[l
- 1] == '\n' && s
[l
- 2] == '\\')
1965 fgets(s
+ l
- 2, sizeof(s
) - l
, f
);
1972 if (*t
== '#' && (t
== s
|| *(t
- 1) != '\\'))
1983 ParseConfigLine(&ub
, t
);
1990 void parse_window_geometry(char *geom
, int is_button_geometry
)
1996 unsigned int height
;
1998 flags
= FScreenParseGeometry(geom
, &g_x
, &g_y
, &width
, &height
);
2003 if (is_button_geometry
)
2005 if (flags
&WidthValue
)
2007 button_width
= width
;
2009 if (flags
&HeightValue
)
2011 button_height
= height
;
2016 if (flags
&WidthValue
)
2020 if (flags
&HeightValue
)
2027 UberButton
->x
= g_x
;
2031 UberButton
->y
= g_y
;
2033 if (flags
&XNegative
)
2037 if (flags
&YNegative
)
2041 has_button_geometry
= is_button_geometry
;
2049 void ParseConfiguration(button_info
*ub
)
2054 NULL
, /* filled out below */
2057 XINERAMA_CONFIG_STRING
,
2061 items
[0] = mymalloc(strlen(MyName
) + 2);
2062 sprintf(items
[0], "*%s", MyName
);
2064 /* send config lines with MyName */
2065 InitGetConfigLine(fd
, items
[0]);
2066 GetConfigLine(fd
, &s
);
2070 switch (GetTokenIndex(s
,items
,-1,&rest
))
2075 if (rest
&& rest
[0] && !config_file
)
2077 ParseConfigLine(&ub
, rest
);
2085 CopyString(&imagePath
, rest
);
2088 /* store colorset sent by fvwm */
2092 /* Xinerama state */
2093 FScreenConfigureModule(rest
);
2096 GetConfigLine(fd
,&s
);
2101 ParseConfigFile(ub
);