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
17 /* ---------------------------- included header files ---------------------- */
23 #include <X11/keysym.h>
25 #include "libs/fvwmlib.h"
26 #include "libs/Parse.h"
27 #include "libs/ColorUtils.h"
28 #include "libs/Picture.h"
29 #include "libs/PictureUtils.h"
30 #include "libs/Graphics.h"
33 #include "execcontext.h"
34 #include "functions.h"
38 #include "menustyle.h"
40 /* ---------------------------- local definitions -------------------------- */
42 /* ---------------------------- local macros ------------------------------- */
44 /* ---------------------------- imports ------------------------------------ */
46 /* ---------------------------- included code files ------------------------ */
48 /* ---------------------------- local types -------------------------------- */
50 /* ---------------------------- forward declarations ----------------------- */
52 /* ---------------------------- local variables ---------------------------- */
54 static MenuStyle
*default_menu_style
;
56 /* ---------------------------- exported variables (globals) --------------- */
58 /* ---------------------------- local functions ---------------------------- */
60 static void menustyle_free_face(MenuFace
*mf
)
65 if (Pdepth
<= 8 && mf
->u
.grad
.npixels
> 0 &&
66 !mf
->u
.grad
.do_dither
)
71 p
= (Pixel
*)safemalloc(
72 mf
->u
.grad
.npixels
* sizeof(Pixel
));
73 for(i
=0; i
< mf
->u
.grad
.npixels
; i
++)
75 p
[i
] = mf
->u
.grad
.xcs
[i
].pixel
;
78 dpy
, Pcmap
, p
, mf
->u
.grad
.npixels
, 0, False
);
82 mf
->u
.grad
.xcs
= NULL
;
88 PDestroyFvwmPicture(dpy
, mf
->u
.p
);
93 fvwmlib_free_colors(dpy
, &mf
->u
.back
, 1, True
);
97 mf
->type
= SimpleMenu
;
102 static void menustyle_copy_face(MenuFace
*destmf
, MenuFace
*origmf
)
104 FvwmPictureAttributes fpa
;
107 menustyle_free_face(destmf
);
108 destmf
->type
= SimpleMenu
;
109 switch (origmf
->type
)
113 dpy
, &destmf
->u
.back
, &origmf
->u
.back
, False
, True
);
114 destmf
->type
= SolidMenu
;
118 (XColor
*)safemalloc(sizeof(XColor
) *
119 origmf
->u
.grad
.npixels
);
120 memcpy(destmf
->u
.grad
.xcs
,
122 sizeof(XColor
) * origmf
->u
.grad
.npixels
);
123 for (i
= 0; i
<origmf
->u
.grad
.npixels
;i
++)
125 fvwmlib_clone_color(origmf
->u
.grad
.xcs
[i
].pixel
);
128 destmf
->u
.grad
.npixels
= origmf
->u
.grad
.npixels
;
129 destmf
->u
.grad
.do_dither
= origmf
->u
.grad
.do_dither
;
130 destmf
->type
= GradientMenu
;
131 destmf
->gradient_type
= origmf
->gradient_type
;
134 case TiledPixmapMenu
:
135 fpa
.mask
= (Pdepth
<= 8)? FPAM_DITHER
:0;
141 destmf
->u
.p
= PCacheFvwmPicture(
142 dpy
, Scr
.NoFocusWin
, NULL
, origmf
->u
.p
->name
,
145 destmf
->type
= origmf
->type
;
154 * Reads a menu face line into a structure (veliaa@rpi.edu)
157 static Boolean
menustyle_parse_face(char *s
, MenuFace
*mf
, int verbose
)
162 FvwmPictureAttributes fpa
;
164 s
= GetNextToken(s
, &style
);
165 if (style
&& strncasecmp(style
, "--", 2) == 0)
171 menustyle_free_face(mf
);
172 mf
->type
= SimpleMenu
;
174 /* determine menu style */
179 else if (StrEquals(style
,"Solid"))
181 s
= GetNextToken(s
, &token
);
184 mf
->type
= SolidMenu
;
185 mf
->u
.back
= GetColor(token
);
192 fvwm_msg(ERR
, "menustyle_parse_face",
193 "no color given for Solid face type:"
201 else if (StrEquals(style
+1, "Gradient"))
204 int npixels
, nsegs
, *perc
;
207 if (!IsGradientTypeSupported(style
[0]))
212 /* translate the gradient string into an array of colors etc */
213 npixels
= ParseGradient(s
, NULL
, &s_colors
, &perc
, &nsegs
);
219 mf
->u
.grad
.do_dither
= False
;
222 mf
->u
.grad
.do_dither
= True
;
224 /* grab the colors */
225 xcs
= AllocAllGradientColors(
226 s_colors
, perc
, nsegs
, npixels
, mf
->u
.grad
.do_dither
);
232 mf
->u
.grad
.xcs
= xcs
;
233 mf
->u
.grad
.npixels
= npixels
;
234 mf
->type
= GradientMenu
;
235 mf
->gradient_type
= toupper(style
[0]);
238 else if (StrEquals(style
,"Pixmap") || StrEquals(style
,"TiledPixmap"))
240 s
= GetNextToken(s
, &token
);
241 fpa
.mask
= (Pdepth
<= 8)? FPAM_DITHER
:0;
244 mf
->u
.p
= PCacheFvwmPicture(
245 dpy
, Scr
.NoFocusWin
, NULL
, token
, fpa
);
250 fvwm_msg(ERR
, "menustyle_parse_face",
251 "couldn't load pixmap %s",
259 mf
->type
= (StrEquals(style
,"TiledPixmap")) ?
260 TiledPixmapMenu
: PixmapMenu
;
266 fvwm_msg(ERR
, "menustyle_parse_face",
267 "missing pixmap name for style %s",
280 "menustyle_parse_face", "unknown style %s: %s",
291 static void parse_vertical_spacing_line(
292 char *args
, signed char *above
, signed char *below
,
293 signed char above_default
, signed char below_default
)
297 if (GetIntegerArguments(args
, NULL
, val
, 2) != 2 ||
298 val
[0] < MIN_VERTICAL_SPACING
|| val
[0] > MAX_VERTICAL_SPACING
||
299 val
[1] < MIN_VERTICAL_SPACING
|| val
[1] > MAX_VERTICAL_SPACING
)
301 /* illegal or missing parameters, return to default */
302 *above
= above_default
;
303 *below
= below_default
;
312 static void parse_vertical_margins_line(
313 char *args
, unsigned char *top
, unsigned char *bottom
,
314 signed char top_default
, signed char bottom_default
)
318 if (GetIntegerArguments(args
, NULL
, val
, 2) != 2 ||
319 val
[0] < 0 || val
[0] > MAX_MENU_MARGIN
||
320 val
[1] < 0 || val
[1] > MAX_MENU_MARGIN
)
322 /* invalid or missing parameters, return to default */
324 *bottom
= bottom_default
;
333 static MenuStyle
*menustyle_parse_old_style(F_CMD_ARGS
)
336 char *fore
, *back
, *stipple
, *font
, *style
, *animated
;
337 MenuStyle
*ms
= NULL
;
339 rest
= GetNextToken(action
,&fore
);
340 rest
= GetNextToken(rest
,&back
);
341 rest
= GetNextToken(rest
,&stipple
);
342 rest
= GetNextToken(rest
,&font
);
343 rest
= GetNextToken(rest
,&style
);
344 rest
= GetNextToken(rest
,&animated
);
346 if (!fore
|| !back
|| !stipple
|| !font
|| !style
)
348 fvwm_msg(ERR
, "menustyle_parse_old_style",
349 "error in %s style specification", action
);
353 buffer
= (char *)alloca(strlen(action
) + 100);
355 "* \"%s\", Foreground \"%s\", Background \"%s\", "
356 "Greyed \"%s\", Font \"%s\", \"%s\"",
357 style
, fore
, back
, stipple
, font
,
358 (animated
&& StrEquals(animated
, "anim")) ?
359 "Animation" : "AnimationOff");
360 fvwm_msg(OLD
, "menustyle_parse_old_style",
361 "The old MenuStyle snytax has been deprecated. "
362 "Use 'MenuStyle %s' instead of 'MenuStyle %s'\n",
365 ms
= menustyle_parse_style(F_PASS_ARGS
);
396 static int menustyle_get_styleopt_index(char *option
)
399 "fvwm", "mwm", "win",
400 "Foreground", "Background", "Greyed",
401 "HilightBack", "HilightBackOff",
402 "ActiveFore", "ActiveForeOff",
403 "Hilight3DThick", "Hilight3DThin", "Hilight3DOff",
404 "Animation", "AnimationOff",
407 "PopupDelay", "PopupOffset",
408 "TitleWarp", "TitleWarpOff",
409 "TitleUnderlines0", "TitleUnderlines1", "TitleUnderlines2",
410 "SeparatorsLong", "SeparatorsShort",
411 "TrianglesSolid", "TrianglesRelief",
412 "PopupImmediately", "PopupDelayed",
414 "SidePic", "SideColor",
415 "PopupAsRootmenu", "PopupAsSubmenu",
416 "RemoveSubmenus", "HoldSubmenus",
417 "SubmenusRight", "SubmenusLeft",
419 "Hilight3DThickness",
421 "AutomaticHotkeys", "AutomaticHotkeysOff",
422 "VerticalItemSpacing",
423 "VerticalTitleSpacing",
424 "MenuColorset", "ActiveColorset", "GreyedColorset",
426 "PopdownImmediately", "PopdownDelayed",
429 "PopupIgnore", "PopupClose",
430 "MouseWheel", "ScrollOffPage",
432 "TitleColorset", "HilightTitleBack",
438 return GetTokenIndex(option
, optlist
, 0, NULL
);
441 static void change_or_make_gc(GC
*gc
, unsigned long gcm
, XGCValues
*gcv
)
445 XChangeGC(dpy
, *gc
, gcm
, gcv
);
449 *gc
= fvwmlib_XCreateGC(dpy
, Scr
.NoFocusWin
, gcm
, gcv
);
455 /* ---------------------------- interface functions ------------------------ */
457 MenuStyle
*menustyle_get_default_style(void)
459 return default_menu_style
;
462 void menustyle_free(MenuStyle
*ms
)
464 MenuStyle
*before
= default_menu_style
;
470 menustyle_free_face(&ST_FACE(ms
));
471 if (FORE_GC(ST_MENU_INACTIVE_GCS(ms
)))
473 XFreeGC(dpy
, FORE_GC(ST_MENU_INACTIVE_GCS(ms
)));
475 if (FORE_GC(ST_MENU_ACTIVE_GCS(ms
)))
477 XFreeGC(dpy
, FORE_GC(ST_MENU_ACTIVE_GCS(ms
)));
479 if (BACK_GC(ST_MENU_ACTIVE_GCS(ms
)))
481 XFreeGC(dpy
, BACK_GC(ST_MENU_ACTIVE_GCS(ms
)));
483 if (HILIGHT_GC(ST_MENU_ACTIVE_GCS(ms
)))
485 XFreeGC(dpy
, HILIGHT_GC(ST_MENU_ACTIVE_GCS(ms
)));
487 if (SHADOW_GC(ST_MENU_ACTIVE_GCS(ms
)))
489 XFreeGC(dpy
, SHADOW_GC(ST_MENU_ACTIVE_GCS(ms
)));
491 if (HILIGHT_GC(ST_MENU_INACTIVE_GCS(ms
)))
493 XFreeGC(dpy
, HILIGHT_GC(ST_MENU_INACTIVE_GCS(ms
)));
495 if (SHADOW_GC(ST_MENU_INACTIVE_GCS(ms
)))
497 XFreeGC(dpy
, SHADOW_GC(ST_MENU_INACTIVE_GCS(ms
)));
499 if (FORE_GC(ST_MENU_STIPPLE_GCS(ms
)))
501 XFreeGC(dpy
, FORE_GC(ST_MENU_STIPPLE_GCS(ms
)));
503 if (FORE_GC(ST_MENU_TITLE_GCS(ms
)))
505 XFreeGC(dpy
, FORE_GC(ST_MENU_TITLE_GCS(ms
)));
507 if (BACK_GC(ST_MENU_TITLE_GCS(ms
)))
509 XFreeGC(dpy
, BACK_GC(ST_MENU_TITLE_GCS(ms
)));
511 if (HILIGHT_GC(ST_MENU_TITLE_GCS(ms
)))
513 XFreeGC(dpy
, HILIGHT_GC(ST_MENU_TITLE_GCS(ms
)));
515 if (SHADOW_GC(ST_MENU_TITLE_GCS(ms
)))
517 XFreeGC(dpy
, SHADOW_GC(ST_MENU_TITLE_GCS(ms
)));
521 PDestroyFvwmPicture(dpy
, ST_SIDEPIC(ms
));
523 if (ST_HAS_SIDE_COLOR(ms
) == 1)
525 fvwmlib_free_colors(dpy
, &ST_SIDE_COLOR(ms
), 1, True
);
527 if (ST_PSTDFONT(ms
) && !ST_USING_DEFAULT_FONT(ms
))
529 FlocaleUnloadFont(dpy
, ST_PSTDFONT(ms
));
531 if (ST_PTITLEFONT(ms
) && !ST_USING_DEFAULT_TITLEFONT(ms
))
533 FlocaleUnloadFont(dpy
, ST_PTITLEFONT(ms
));
535 if (ST_ITEM_FORMAT(ms
))
537 free(ST_ITEM_FORMAT(ms
));
540 fvwmlib_free_colors(dpy
, &ST_MENU_COLORS(ms
).back
,1,True
);
541 fvwmlib_free_colors(dpy
, &ST_MENU_COLORS(ms
).fore
,1,True
);
542 if (ST_HAS_STIPPLE_FORE(ms
))
545 dpy
, &ST_MENU_STIPPLE_COLORS(ms
).fore
,1,True
);
547 if (ST_HAS_ACTIVE_BACK(ms
))
550 dpy
, &ST_MENU_ACTIVE_COLORS(ms
).back
,1,True
);
552 if (ST_HAS_ACTIVE_FORE(ms
))
555 dpy
, &ST_MENU_ACTIVE_COLORS(ms
).fore
,1,True
);
558 while (ST_NEXT_STYLE(before
) != ms
)
560 /* Not too many checks, may segfault in race conditions */
561 before
= ST_NEXT_STYLE(before
);
564 ST_NEXT_STYLE(before
) = ST_NEXT_STYLE(ms
);
571 MenuStyle
*menustyle_find(char *name
)
573 MenuStyle
*ms
= default_menu_style
;
577 if (strcasecmp(ST_NAME(ms
),name
)==0)
581 ms
= ST_NEXT_STYLE(ms
);
587 void menustyle_update(MenuStyle
*ms
)
591 color_quad c_inactive
;
593 color_quad c_stipple
;
595 colorset_t
*menu_cs
= &Colorset
[ST_CSET_MENU(ms
)];
596 colorset_t
*active_cs
= &Colorset
[ST_CSET_ACTIVE(ms
)];
597 colorset_t
*greyed_cs
= &Colorset
[ST_CSET_GREYED(ms
)];
598 colorset_t
*title_cs
= &Colorset
[ST_CSET_TITLE(ms
)];
600 if (ST_USAGE_COUNT(ms
) != 0)
602 fvwm_msg(ERR
,"menustyle_update", "menu style %s is in use",
606 ST_IS_UPDATED(ms
) = 1;
607 if (ST_USING_DEFAULT_FONT(ms
))
609 ST_PSTDFONT(ms
) = Scr
.DefaultFont
;
611 if (ST_USING_DEFAULT_TITLEFONT(ms
))
613 ST_PTITLEFONT(ms
) = ST_PSTDFONT(ms
);
615 /* calculate colors based on foreground */
616 if (!ST_HAS_ACTIVE_FORE(ms
))
618 ST_MENU_ACTIVE_COLORS(ms
).fore
= ST_MENU_COLORS(ms
).fore
;
620 /* calculate colors based on background */
621 if (!ST_HAS_ACTIVE_BACK(ms
))
623 ST_MENU_ACTIVE_COLORS(ms
).back
= ST_MENU_COLORS(ms
).back
;
625 if (!ST_HAS_STIPPLE_FORE(ms
))
627 ST_MENU_STIPPLE_COLORS(ms
).fore
= ST_MENU_COLORS(ms
).back
;
629 ST_MENU_STIPPLE_COLORS(ms
).back
= ST_MENU_COLORS(ms
).back
;
630 /* prepare colours for changing the gcs */
631 if (ST_HAS_MENU_CSET(ms
))
633 c_inactive
.fore
= menu_cs
->fg
;
634 c_inactive
.back
= menu_cs
->bg
;
635 c_inactive
.hilight
= menu_cs
->hilite
;
636 c_inactive
.shadow
= menu_cs
->shadow
;
640 c_inactive
.fore
= ST_MENU_COLORS(ms
).fore
;
641 c_inactive
.back
= ST_MENU_COLORS(ms
).back
;
644 c_inactive
.hilight
= GetHilite(ST_MENU_COLORS(ms
).back
);
645 c_inactive
.shadow
= GetShadow(ST_MENU_COLORS(ms
).back
);
649 c_inactive
.hilight
= GetColor(DEFAULT_HILIGHT_COLOR
);
650 c_inactive
.shadow
= GetColor(DEFAULT_SHADOW_COLOR
);
653 if (ST_HAS_ACTIVE_CSET(ms
))
655 c_active
.fore
= active_cs
->fg
;
656 c_active
.back
= active_cs
->bg
;
657 c_active
.hilight
= active_cs
->hilite
;
658 c_active
.shadow
= active_cs
->shadow
;
662 c_active
.fore
= ST_MENU_ACTIVE_COLORS(ms
).fore
;
663 c_active
.back
= ST_MENU_ACTIVE_COLORS(ms
).back
;
667 GetHilite(ST_MENU_ACTIVE_COLORS(ms
).back
);
669 GetShadow(ST_MENU_ACTIVE_COLORS(ms
).back
);
673 c_active
.hilight
= GetColor(DEFAULT_HILIGHT_COLOR
);
674 c_active
.shadow
= GetColor(DEFAULT_SHADOW_COLOR
);
677 if (ST_HAS_GREYED_CSET(ms
))
679 c_stipple
.fore
= greyed_cs
->fg
;
680 c_stipple
.back
= greyed_cs
->fg
;
684 c_stipple
.fore
= ST_MENU_STIPPLE_COLORS(ms
).fore
;
685 c_stipple
.back
= ST_MENU_STIPPLE_COLORS(ms
).back
;
687 if (ST_HAS_TITLE_CSET(ms
))
689 c_title
.fore
= title_cs
->fg
;
690 c_title
.back
= title_cs
->bg
;
691 c_title
.hilight
= title_cs
->hilite
;
692 c_title
.shadow
= title_cs
->shadow
;
696 c_title
.fore
= c_inactive
.fore
;
697 c_title
.back
= c_inactive
.back
;
698 c_title
.hilight
= c_inactive
.hilight
;
699 c_title
.shadow
= c_inactive
.shadow
;
701 /* override hilighting colours if necessary */
702 if (!ST_DO_HILIGHT_FORE(ms
))
704 c_active
.fore
= c_inactive
.fore
;
706 if (!ST_DO_HILIGHT_BACK(ms
))
708 c_active
.back
= c_inactive
.back
;
709 c_active
.hilight
= c_inactive
.hilight
;
710 c_active
.shadow
= c_inactive
.shadow
;
712 if (!ST_DO_HILIGHT_TITLE_BACK(ms
))
714 c_title
.fore
= c_inactive
.fore
;
715 c_title
.back
= c_inactive
.back
;
716 c_title
.hilight
= c_inactive
.hilight
;
717 c_title
.shadow
= c_inactive
.shadow
;
720 gcm
= GCFunction
|GCLineWidth
|GCForeground
|GCBackground
;
721 if (ST_PSTDFONT(ms
)->font
!= NULL
)
724 gcv
.font
= ST_PSTDFONT(ms
)->font
->fid
;
726 gcv
.function
= GXcopy
;
728 /* update inactive menu gcs */
729 gcv
.foreground
= c_inactive
.fore
;
730 gcv
.background
= c_inactive
.back
;
731 change_or_make_gc(&FORE_GC(ST_MENU_INACTIVE_GCS(ms
)), gcm
, &gcv
);
732 BACK_GC(ST_MENU_INACTIVE_GCS(ms
)) = FORE_GC(ST_MENU_INACTIVE_GCS(ms
));
733 gcv
.foreground
= c_inactive
.hilight
;
734 gcv
.background
= c_inactive
.shadow
;
735 change_or_make_gc(&HILIGHT_GC(ST_MENU_INACTIVE_GCS(ms
)), gcm
, &gcv
);
736 gcv
.foreground
= c_inactive
.shadow
;
737 gcv
.background
= c_inactive
.hilight
;
738 change_or_make_gc(&SHADOW_GC(ST_MENU_INACTIVE_GCS(ms
)), gcm
, &gcv
);
739 /* update active menu gcs */
740 gcv
.foreground
= c_active
.fore
;
741 gcv
.background
= c_active
.back
;
742 change_or_make_gc(&FORE_GC(ST_MENU_ACTIVE_GCS(ms
)), gcm
, &gcv
);
743 gcv
.foreground
= c_active
.back
;
744 gcv
.background
= c_active
.fore
;
746 if (ST_HAS_ACTIVE_CSET(ms
) && active_cs
->pixmap
&&
747 active_cs
->pixmap_type
== PIXMAP_TILED
)
749 gcv
.tile
= active_cs
->pixmap
;
750 gcv
.fill_style
= FillTiled
;
751 change_or_make_gc(&BACK_GC(ST_MENU_ACTIVE_GCS(ms
)),
752 gcm
| GCFillStyle
| GCTile
, &gcv
);
756 gcv
.fill_style
= FillSolid
;
757 change_or_make_gc(&BACK_GC(ST_MENU_ACTIVE_GCS(ms
)),
758 gcm
| GCFillStyle
, &gcv
);
762 gcv
.foreground
= c_active
.hilight
;
763 gcv
.background
= c_active
.shadow
;
764 change_or_make_gc(&HILIGHT_GC(ST_MENU_ACTIVE_GCS(ms
)), gcm
, &gcv
);
765 gcv
.foreground
= c_active
.shadow
;
766 gcv
.background
= c_active
.hilight
;
767 change_or_make_gc(&SHADOW_GC(ST_MENU_ACTIVE_GCS(ms
)), gcm
, &gcv
);
768 /* update title gcs */
769 if (ST_PTITLEFONT(ms
)->font
!= NULL
&& ST_PSTDFONT(ms
)->font
== NULL
)
771 if (ST_PSTDFONT(ms
)->font
== NULL
)
775 gcv
.font
= ST_PTITLEFONT(ms
)->font
->fid
;
777 gcv
.foreground
= c_title
.fore
;
778 gcv
.background
= c_title
.back
;
779 change_or_make_gc(&FORE_GC(ST_MENU_TITLE_GCS(ms
)), gcm
, &gcv
);
780 gcv
.foreground
= c_title
.back
;
781 gcv
.background
= c_title
.fore
;
783 if (ST_HAS_TITLE_CSET(ms
) && title_cs
->pixmap
&&
784 title_cs
->pixmap_type
== PIXMAP_TILED
)
786 gcv
.tile
= title_cs
->pixmap
;
787 gcv
.fill_style
= FillTiled
;
788 change_or_make_gc(&BACK_GC(ST_MENU_TITLE_GCS(ms
)),
789 gcm
| GCFillStyle
| GCTile
, &gcv
);
793 gcv
.fill_style
= FillSolid
;
794 change_or_make_gc(&BACK_GC(ST_MENU_TITLE_GCS(ms
)),
795 gcm
| GCFillStyle
, &gcv
);
798 gcv
.foreground
= c_title
.hilight
;
799 gcv
.background
= c_title
.shadow
;
800 change_or_make_gc(&HILIGHT_GC(ST_MENU_TITLE_GCS(ms
)), gcm
, &gcv
);
801 gcv
.foreground
= c_title
.shadow
;
802 gcv
.background
= c_title
.hilight
;
803 change_or_make_gc(&SHADOW_GC(ST_MENU_TITLE_GCS(ms
)), gcm
, &gcv
);
804 /* update stipple menu gcs */
805 SHADOW_GC(ST_MENU_STIPPLE_GCS(ms
)) =
806 SHADOW_GC(ST_MENU_INACTIVE_GCS(ms
));
809 gcv
.fill_style
= FillStippled
;
810 gcv
.stipple
= Scr
.gray_bitmap
;
811 /* no need to reset fg/bg, FillStipple wins */
812 gcm
|= GCStipple
| GCFillStyle
;
813 HILIGHT_GC(ST_MENU_STIPPLE_GCS(ms
)) =
814 SHADOW_GC(ST_MENU_INACTIVE_GCS(ms
));
818 gcv
.foreground
= c_stipple
.fore
;
819 gcv
.background
= c_stipple
.back
;
820 HILIGHT_GC(ST_MENU_STIPPLE_GCS(ms
)) =
821 HILIGHT_GC(ST_MENU_INACTIVE_GCS(ms
));
823 change_or_make_gc(&FORE_GC(ST_MENU_STIPPLE_GCS(ms
)), gcm
, &gcv
);
824 BACK_GC(ST_MENU_STIPPLE_GCS(ms
)) = BACK_GC(ST_MENU_INACTIVE_GCS(ms
));
829 MenuStyle
*menustyle_parse_style(F_CMD_ARGS
)
833 char *poption
= NULL
;
834 char *optstring
= NULL
;
841 Bool is_initialised
= True
;
842 Bool has_gc_changed
= False
;
843 Bool is_default_style
= False
;
846 FlocaleFont
*new_font
= NULL
;
849 FvwmPictureAttributes fpa
;
851 action
= GetNextToken(action
, &name
);
854 fvwm_msg(ERR
, "NewMenuStyle",
855 "error in %s style specification",action
);
859 ms
= menustyle_find(name
);
860 if (ms
&& ST_USAGE_COUNT(ms
) != 0)
862 fvwm_msg(ERR
,"NewMenuStyle", "menu style %s is in use", name
);
865 tmpms
= (MenuStyle
*)safemalloc(sizeof(MenuStyle
));
868 /* copy the structure over our temporary menu face. */
869 memcpy(tmpms
, ms
, sizeof(MenuStyle
));
870 if (ms
== default_menu_style
)
872 is_default_style
= True
;
878 memset(tmpms
, 0, sizeof(MenuStyle
));
879 ST_NAME(tmpms
) = name
;
880 is_initialised
= False
;
882 ST_IS_UPDATED(tmpms
) = 1;
884 /* Parse the options. */
885 while (!is_initialised
|| (action
&& *action
))
890 /* some default configuration goes here for the new
892 ST_MENU_COLORS(tmpms
).back
=
893 GetColor(DEFAULT_BACK_COLOR
);
894 ST_MENU_COLORS(tmpms
).fore
=
895 GetColor(DEFAULT_FORE_COLOR
);
896 ST_PSTDFONT(tmpms
) = Scr
.DefaultFont
;
897 ST_USING_DEFAULT_FONT(tmpms
) = True
;
898 ST_FACE(tmpms
).type
= SimpleMenu
;
899 ST_HAS_ACTIVE_FORE(tmpms
) = 0;
900 ST_HAS_ACTIVE_BACK(tmpms
) = 0;
901 ST_DO_POPUP_AS(tmpms
) = MDP_POST_MENU
;
902 ST_DOUBLE_CLICK_TIME(tmpms
) = DEFAULT_MENU_CLICKTIME
;
903 ST_POPUP_DELAY(tmpms
) = DEFAULT_POPUP_DELAY
;
904 ST_POPDOWN_DELAY(tmpms
) = DEFAULT_POPDOWN_DELAY
;
905 ST_MOUSE_WHEEL(tmpms
) = MMW_POINTER
;
906 ST_SCROLL_OFF_PAGE(tmpms
) = 1;
907 ST_DO_HILIGHT_TITLE_BACK(tmpms
) = 0;
908 ST_USING_DEFAULT_TITLEFONT(tmpms
) = True
;
909 has_gc_changed
= True
;
914 /* Read next option specification (delimited by a comma
917 action
= GetQuotedString(
918 action
, &optstring
, ",", NULL
, NULL
, NULL
);
923 args
= GetNextToken(optstring
, &option
);
929 nextarg
= GetNextToken(args
, &arg1
);
932 while (poption
[0] == '!')
937 switch((i
= menustyle_get_styleopt_index(poption
)))
944 ST_POPUP_OFFSET_PERCENT(tmpms
) = 67;
945 ST_POPUP_OFFSET_ADD(tmpms
) = 0;
946 ST_DO_POPUP_IMMEDIATELY(tmpms
) = 0;
947 ST_DO_WARP_TO_TITLE(tmpms
) = 1;
948 ST_DO_UNMAP_SUBMENU_ON_POPDOWN(tmpms
) = 0;
949 ST_RELIEF_THICKNESS(tmpms
) = 1;
950 ST_TITLE_UNDERLINES(tmpms
) = 1;
951 ST_HAS_LONG_SEPARATORS(tmpms
) = 0;
952 ST_HAS_TRIANGLE_RELIEF(tmpms
) = 1;
953 ST_DO_HILIGHT_BACK(tmpms
) = 0;
954 ST_DO_HILIGHT_FORE(tmpms
) = 0;
958 ST_POPUP_OFFSET_PERCENT(tmpms
) = 100;
959 ST_POPUP_OFFSET_ADD(tmpms
) =
960 -DEFAULT_MENU_BORDER_WIDTH
- 1;
961 ST_DO_POPUP_IMMEDIATELY(tmpms
) = 1;
962 ST_DO_WARP_TO_TITLE(tmpms
) = 0;
963 ST_DO_UNMAP_SUBMENU_ON_POPDOWN(tmpms
) = 0;
964 ST_RELIEF_THICKNESS(tmpms
) = 2;
965 ST_TITLE_UNDERLINES(tmpms
) = 2;
966 ST_HAS_LONG_SEPARATORS(tmpms
) = 1;
967 ST_HAS_TRIANGLE_RELIEF(tmpms
) = 1;
968 ST_DO_HILIGHT_BACK(tmpms
) = 0;
969 ST_DO_HILIGHT_FORE(tmpms
) = 0;
973 ST_POPUP_OFFSET_PERCENT(tmpms
) = 100;
974 ST_POPUP_OFFSET_ADD(tmpms
) =
975 -DEFAULT_MENU_BORDER_WIDTH
- 3;
976 ST_DO_POPUP_IMMEDIATELY(tmpms
) = 1;
977 ST_DO_WARP_TO_TITLE(tmpms
) = 0;
978 ST_DO_UNMAP_SUBMENU_ON_POPDOWN(tmpms
) = 1;
979 ST_RELIEF_THICKNESS(tmpms
) = 0;
980 ST_TITLE_UNDERLINES(tmpms
) = 1;
981 ST_HAS_LONG_SEPARATORS(tmpms
) = 0;
982 ST_HAS_TRIANGLE_RELIEF(tmpms
) = 0;
983 ST_DO_HILIGHT_BACK(tmpms
) = 1;
984 ST_DO_HILIGHT_FORE(tmpms
) = 1;
987 /* common settings */
988 ST_VERTICAL_MARGIN_TOP(tmpms
) = 0;
989 ST_VERTICAL_MARGIN_BOTTOM(tmpms
) = 0;
990 ST_CSET_MENU(tmpms
) = 0;
991 ST_HAS_MENU_CSET(tmpms
) = 0;
992 ST_CSET_ACTIVE(tmpms
) = 0;
993 ST_HAS_ACTIVE_CSET(tmpms
) = 0;
994 ST_CSET_GREYED(tmpms
) = 0;
995 ST_HAS_GREYED_CSET(tmpms
) = 0;
996 ST_BORDER_WIDTH(tmpms
) = DEFAULT_MENU_BORDER_WIDTH
;
997 ST_ACTIVE_AREA_PERCENT(tmpms
) =
998 DEFAULT_MENU_POPUP_NOW_RATIO
;
999 ST_ITEM_GAP_ABOVE(tmpms
) =
1000 DEFAULT_MENU_ITEM_TEXT_Y_OFFSET
;
1001 ST_ITEM_GAP_BELOW(tmpms
) =
1002 DEFAULT_MENU_ITEM_TEXT_Y_OFFSET2
;
1003 ST_TITLE_GAP_ABOVE(tmpms
) =
1004 DEFAULT_MENU_TITLE_TEXT_Y_OFFSET
;
1005 ST_TITLE_GAP_BELOW(tmpms
) =
1006 DEFAULT_MENU_TITLE_TEXT_Y_OFFSET2
;
1007 ST_USE_LEFT_SUBMENUS(tmpms
) = 0;
1008 ST_IS_ANIMATED(tmpms
) = 0;
1009 ST_USE_AUTOMATIC_HOTKEYS(tmpms
) = 0;
1010 menustyle_free_face(&ST_FACE(tmpms
));
1011 ST_FACE(tmpms
).type
= SimpleMenu
;
1012 if (ST_PSTDFONT(tmpms
) && !ST_USING_DEFAULT_FONT(tmpms
))
1014 FlocaleUnloadFont(dpy
, ST_PSTDFONT(tmpms
));
1016 ST_PSTDFONT(tmpms
) = Scr
.DefaultFont
;
1017 ST_USING_DEFAULT_FONT(tmpms
) = True
;
1018 has_gc_changed
= True
;
1019 if (ST_HAS_SIDE_COLOR(tmpms
) == 1)
1021 fvwmlib_free_colors(
1022 dpy
, &ST_SIDE_COLOR(tmpms
), 1, True
);
1023 ST_HAS_SIDE_COLOR(tmpms
) = 0;
1025 ST_HAS_SIDE_COLOR(tmpms
) = 0;
1026 if (ST_SIDEPIC(tmpms
))
1028 PDestroyFvwmPicture(dpy
, ST_SIDEPIC(tmpms
));
1029 ST_SIDEPIC(tmpms
) = NULL
;
1032 if (is_initialised
== False
)
1034 /* now begin the real work */
1035 is_initialised
= True
;
1040 case 3: /* Foreground */
1041 fvwmlib_free_colors(
1042 dpy
, &ST_MENU_COLORS(tmpms
).fore
, 1, True
);
1045 ST_MENU_COLORS(tmpms
).fore
= GetColor(arg1
);
1049 ST_MENU_COLORS(tmpms
).fore
=
1050 GetColor(DEFAULT_FORE_COLOR
);
1052 has_gc_changed
= True
;
1055 case 4: /* Background */
1056 fvwmlib_free_colors(
1057 dpy
, &ST_MENU_COLORS(tmpms
).back
, 1, True
);
1060 ST_MENU_COLORS(tmpms
).back
= GetColor(arg1
);
1064 ST_MENU_COLORS(tmpms
).back
=
1065 GetColor(DEFAULT_BACK_COLOR
);
1067 has_gc_changed
= True
;
1070 case 5: /* Greyed */
1071 if (ST_HAS_STIPPLE_FORE(tmpms
))
1073 fvwmlib_free_colors(
1075 &ST_MENU_STIPPLE_COLORS(tmpms
).fore
, 1,
1080 ST_HAS_STIPPLE_FORE(tmpms
) = 0;
1084 ST_MENU_STIPPLE_COLORS(tmpms
).fore
=
1086 ST_HAS_STIPPLE_FORE(tmpms
) = 1;
1088 has_gc_changed
= True
;
1091 case 7: /* HilightBackOff */
1094 case 6: /* HilightBack */
1095 if (ST_HAS_ACTIVE_BACK(tmpms
))
1097 fvwmlib_free_colors(
1099 &ST_MENU_ACTIVE_COLORS(tmpms
).back
, 1,
1102 if (arg1
== NULL
|| !on
)
1104 ST_HAS_ACTIVE_BACK(tmpms
) = 0;
1108 ST_MENU_ACTIVE_COLORS(tmpms
).back
=
1110 ST_HAS_ACTIVE_BACK(tmpms
) = 1;
1112 ST_DO_HILIGHT_BACK(tmpms
) = on
;
1113 has_gc_changed
= True
;
1116 case 9: /* ActiveForeOff */
1119 case 8: /* ActiveFore */
1120 if (ST_HAS_ACTIVE_FORE(tmpms
))
1122 fvwmlib_free_colors(
1124 &ST_MENU_ACTIVE_COLORS(tmpms
).fore
, 1,
1127 if (arg1
== NULL
|| !on
)
1129 ST_HAS_ACTIVE_FORE(tmpms
) = 0;
1133 ST_MENU_ACTIVE_COLORS(tmpms
).fore
=
1135 ST_HAS_ACTIVE_FORE(tmpms
) = 1;
1137 ST_DO_HILIGHT_FORE(tmpms
) = on
;
1138 has_gc_changed
= True
;
1141 case 10: /* Hilight3DThick */
1142 ST_RELIEF_THICKNESS(tmpms
) = 2;
1145 case 11: /* Hilight3DThin */
1146 ST_RELIEF_THICKNESS(tmpms
) = 1;
1149 case 12: /* Hilight3DOff */
1150 ST_RELIEF_THICKNESS(tmpms
) = 0;
1153 case 13: /* Animation */
1154 ST_IS_ANIMATED(tmpms
) = on
;
1157 case 14: /* AnimationOff */
1158 ST_IS_ANIMATED(tmpms
) = !on
;
1163 !(new_font
= FlocaleLoadFont(dpy
, arg1
, "fvwm")))
1165 fvwm_msg(ERR
, "NewMenuStyle",
1166 "Couldn't load font '%s'\n", arg1
);
1169 if (ST_PSTDFONT(tmpms
) && !ST_USING_DEFAULT_FONT(tmpms
))
1171 FlocaleUnloadFont(dpy
, ST_PSTDFONT(tmpms
));
1175 /* reset to screen font */
1176 ST_PSTDFONT(tmpms
) = Scr
.DefaultFont
;
1177 ST_USING_DEFAULT_FONT(tmpms
) = True
;
1181 ST_PSTDFONT(tmpms
) = new_font
;
1182 ST_USING_DEFAULT_FONT(tmpms
) = False
;
1184 has_gc_changed
= True
;
1187 case 16: /* MenuFace */
1188 while (args
&& *args
!= '\0' &&
1189 isspace((unsigned char)*args
))
1193 menustyle_parse_face(args
, &ST_FACE(tmpms
), True
);
1196 case 17: /* PopupDelay */
1197 if (GetIntegerArguments(args
, NULL
, val
, 1) == 0 ||
1200 ST_POPUP_DELAY(tmpms
) = DEFAULT_POPUP_DELAY
;
1204 ST_POPUP_DELAY(tmpms
) = (*val
+9)/10;
1208 case 18: /* PopupOffset */
1209 if ((n
= GetIntegerArguments(args
, NULL
, val
, 2)) == 0)
1211 fvwm_msg(ERR
,"NewMenuStyle",
1212 "PopupOffset requires one or two"
1217 ST_POPUP_OFFSET_ADD(tmpms
) = val
[0];
1218 if (n
== 2 && val
[1] <= 100 && val
[1] >= 0)
1220 ST_POPUP_OFFSET_PERCENT(tmpms
) = val
[1];
1224 ST_POPUP_OFFSET_PERCENT(tmpms
) = 100;
1229 case 19: /* TitleWarp */
1230 ST_DO_WARP_TO_TITLE(tmpms
) = on
;
1233 case 20: /* TitleWarpOff */
1234 ST_DO_WARP_TO_TITLE(tmpms
) = !on
;
1237 case 21: /* TitleUnderlines0 */
1238 ST_TITLE_UNDERLINES(tmpms
) = 0;
1241 case 22: /* TitleUnderlines1 */
1242 ST_TITLE_UNDERLINES(tmpms
) = 1;
1245 case 23: /* TitleUnderlines2 */
1246 ST_TITLE_UNDERLINES(tmpms
) = 2;
1249 case 24: /* SeparatorsLong */
1250 ST_HAS_LONG_SEPARATORS(tmpms
) = on
;
1253 case 25: /* SeparatorsShort */
1254 ST_HAS_LONG_SEPARATORS(tmpms
) = !on
;
1257 case 26: /* TrianglesSolid */
1258 ST_HAS_TRIANGLE_RELIEF(tmpms
) = !on
;
1261 case 27: /* TrianglesRelief */
1262 ST_HAS_TRIANGLE_RELIEF(tmpms
) = on
;
1265 case 28: /* PopupImmediately */
1266 ST_DO_POPUP_IMMEDIATELY(tmpms
) = on
;
1269 case 29: /* PopupDelayed */
1270 ST_DO_POPUP_IMMEDIATELY(tmpms
) = !on
;
1273 case 30: /* DoubleClickTime */
1274 if (GetIntegerArguments(args
, NULL
, val
, 1) == 0 ||
1277 ST_DOUBLE_CLICK_TIME(tmpms
) =
1278 DEFAULT_MENU_CLICKTIME
;
1282 ST_DOUBLE_CLICK_TIME(tmpms
) = *val
;
1286 case 31: /* SidePic */
1287 if (ST_SIDEPIC(tmpms
))
1289 PDestroyFvwmPicture(dpy
, ST_SIDEPIC(tmpms
));
1290 ST_SIDEPIC(tmpms
) = NULL
;
1294 fpa
.mask
= (Pdepth
<= 8)? FPAM_DITHER
:0;
1295 ST_SIDEPIC(tmpms
) = PCacheFvwmPicture(
1296 dpy
, Scr
.NoFocusWin
, NULL
, arg1
, fpa
);
1297 if (!ST_SIDEPIC(tmpms
))
1299 fvwm_msg(WARN
, "NewMenuStyle",
1300 "Couldn't find pixmap %s",
1306 case 32: /* SideColor */
1307 if (ST_HAS_SIDE_COLOR(tmpms
) == 1)
1309 fvwmlib_free_colors(
1310 dpy
, &ST_SIDE_COLOR(tmpms
), 1, True
);
1311 ST_HAS_SIDE_COLOR(tmpms
) = 0;
1315 ST_SIDE_COLOR(tmpms
) = GetColor(arg1
);
1316 ST_HAS_SIDE_COLOR(tmpms
) = 1;
1320 case 33: /* PopupAsRootmenu */
1321 ST_DO_POPUP_AS(tmpms
) = MDP_ROOT_MENU
;
1324 case 34: /* PopupAsSubmenu */
1325 ST_DO_POPUP_AS(tmpms
) = MDP_POST_MENU
;
1328 case 35: /* RemoveSubmenus */
1329 ST_DO_UNMAP_SUBMENU_ON_POPDOWN(tmpms
) = on
;
1332 case 36: /* HoldSubmenus */
1333 ST_DO_UNMAP_SUBMENU_ON_POPDOWN(tmpms
) = !on
;
1336 case 37: /* SubmenusRight */
1337 ST_USE_LEFT_SUBMENUS(tmpms
) = !on
;
1340 case 38: /* SubmenusLeft */
1341 ST_USE_LEFT_SUBMENUS(tmpms
) = on
;
1344 case 39: /* BorderWidth */
1345 if (GetIntegerArguments(args
, NULL
, val
, 1) == 0 ||
1346 *val
< 0 || *val
> MAX_MENU_BORDER_WIDTH
)
1348 ST_BORDER_WIDTH(tmpms
) =
1349 DEFAULT_MENU_BORDER_WIDTH
;
1353 ST_BORDER_WIDTH(tmpms
) = *val
;
1357 case 40: /* Hilight3DThickness */
1358 if (GetIntegerArguments(args
, NULL
, val
, 1) > 0)
1363 ST_IS_ITEM_RELIEF_REVERSED(tmpms
) = 1;
1367 ST_IS_ITEM_RELIEF_REVERSED(tmpms
) = 0;
1369 if (*val
> MAX_MENU_ITEM_RELIEF_THICKNESS
)
1370 *val
= MAX_MENU_ITEM_RELIEF_THICKNESS
;
1371 ST_RELIEF_THICKNESS(tmpms
) = *val
;
1375 case 41: /* ItemFormat */
1376 if (ST_ITEM_FORMAT(tmpms
))
1378 free(ST_ITEM_FORMAT(tmpms
));
1379 ST_ITEM_FORMAT(tmpms
) = NULL
;
1383 ST_ITEM_FORMAT(tmpms
) = safestrdup(arg1
);
1387 case 42: /* AutomaticHotkeys */
1388 ST_USE_AUTOMATIC_HOTKEYS(tmpms
) = on
;
1391 case 43: /* AutomaticHotkeysOff */
1392 ST_USE_AUTOMATIC_HOTKEYS(tmpms
) = !on
;
1395 case 44: /* VerticalItemSpacing */
1396 parse_vertical_spacing_line(
1397 args
, &ST_ITEM_GAP_ABOVE(tmpms
),
1398 &ST_ITEM_GAP_BELOW(tmpms
),
1399 DEFAULT_MENU_ITEM_TEXT_Y_OFFSET
,
1400 DEFAULT_MENU_ITEM_TEXT_Y_OFFSET2
);
1403 case 45: /* VerticalTitleSpacing */
1404 parse_vertical_spacing_line(
1405 args
, &ST_TITLE_GAP_ABOVE(tmpms
),
1406 &ST_TITLE_GAP_BELOW(tmpms
),
1407 DEFAULT_MENU_TITLE_TEXT_Y_OFFSET
,
1408 DEFAULT_MENU_TITLE_TEXT_Y_OFFSET2
);
1410 case 46: /* MenuColorset */
1411 if (GetIntegerArguments(args
, NULL
, val
, 1) == 0 ||
1414 ST_HAS_MENU_CSET(tmpms
) = 0;
1415 ST_CSET_MENU(tmpms
) = 0;
1419 ST_HAS_MENU_CSET(tmpms
) = 1;
1420 ST_CSET_MENU(tmpms
) = *val
;
1421 alloc_colorset(*val
);
1423 has_gc_changed
= True
;
1425 case 47: /* ActiveColorset */
1426 if (GetIntegerArguments(args
, NULL
, val
, 1) == 0 ||
1429 ST_HAS_ACTIVE_CSET(tmpms
) = 0;
1430 ST_CSET_ACTIVE(tmpms
) = 0;
1434 ST_HAS_ACTIVE_CSET(tmpms
) = 1;
1435 ST_CSET_ACTIVE(tmpms
) = *val
;
1436 alloc_colorset(*val
);
1438 has_gc_changed
= True
;
1441 case 48: /* GreyedColorset */
1442 if (GetIntegerArguments(args
, NULL
, val
, 1) == 0 ||
1445 ST_HAS_GREYED_CSET(tmpms
) = 0;
1446 ST_CSET_GREYED(tmpms
) = 0;
1450 ST_HAS_GREYED_CSET(tmpms
) = 1;
1451 ST_CSET_GREYED(tmpms
) = *val
;
1452 alloc_colorset(*val
);
1454 has_gc_changed
= True
;
1457 case 49: /* SelectOnRelease */
1461 keycode
= XKeysymToKeycode(
1462 dpy
, FvwmStringToKeysym(dpy
, arg1
));
1464 ST_SELECT_ON_RELEASE_KEY(tmpms
) = keycode
;
1467 case 50: /* PopdownImmediately */
1468 ST_DO_POPDOWN_IMMEDIATELY(tmpms
) = 1;
1471 case 51: /* PopdownDelayed */
1472 ST_DO_POPDOWN_IMMEDIATELY(tmpms
) = 0;
1475 case 52: /* PopdownDelay */
1476 if (GetIntegerArguments(args
, NULL
, val
, 1) == 0 ||
1479 ST_POPDOWN_DELAY(tmpms
) = DEFAULT_POPDOWN_DELAY
;
1483 ST_POPDOWN_DELAY(tmpms
) = (*val
+9)/10;
1487 case 53: /* PopupActiveArea */
1488 if (GetIntegerArguments(args
, NULL
, val
, 1) == 0 ||
1489 *val
<= 50 || *val
> 100)
1491 ST_ACTIVE_AREA_PERCENT(tmpms
) =
1492 DEFAULT_MENU_POPUP_NOW_RATIO
;
1496 ST_ACTIVE_AREA_PERCENT(tmpms
) = *val
;
1500 case 54: /* PopupIgnore */
1501 ST_DO_POPUP_AS(tmpms
) = MDP_IGNORE
;
1504 case 55: /* PopupClose */
1505 ST_DO_POPUP_AS(tmpms
) = MDP_CLOSE
;
1508 case 56: /* MouseWheel */
1511 if (StrEquals(arg1
, "ActivatesItem"))
1513 ST_MOUSE_WHEEL(tmpms
) = MMW_OFF
;
1515 else if (StrEquals(arg1
,
1516 "ScrollsMenuBackwards"))
1518 ST_MOUSE_WHEEL(tmpms
) =
1521 else if (StrEquals(arg1
, "ScrollsMenu"))
1523 ST_MOUSE_WHEEL(tmpms
) = MMW_MENU
;
1525 else if (StrEquals(arg1
, "ScrollsPointer"))
1527 ST_MOUSE_WHEEL(tmpms
) = MMW_POINTER
;
1532 ERR
, "NewMenuStyle",
1533 "unknown argument to"
1536 ST_MOUSE_WHEEL(tmpms
) = MMW_POINTER
;
1541 ST_MOUSE_WHEEL(tmpms
) =
1542 (on
) ? MMW_POINTER
: MMW_OFF
;
1545 case 57: /* ScrollOffPage */
1546 ST_SCROLL_OFF_PAGE(tmpms
) = on
;
1549 case 58: /* TrianglesUseFore */
1550 ST_TRIANGLES_USE_FORE(tmpms
) = on
;
1552 case 59: /* TitleColorset */
1553 if (GetIntegerArguments(args
, NULL
, val
, 1) == 0 ||
1556 ST_HAS_TITLE_CSET(tmpms
) = 0;
1557 ST_CSET_TITLE(tmpms
) = 0;
1561 ST_HAS_TITLE_CSET(tmpms
) = 1;
1562 ST_CSET_TITLE(tmpms
) = *val
;
1563 alloc_colorset(*val
);
1565 has_gc_changed
= True
;
1567 case 60: /* TitleHilightBack */
1568 ST_DO_HILIGHT_TITLE_BACK(tmpms
) = on
;
1569 has_gc_changed
= True
;
1571 case 61: /* TitleFont */
1573 !(new_font
= FlocaleLoadFont(dpy
, arg1
, "fvwm")))
1575 fvwm_msg(ERR
, "NewMenuStyle",
1576 "Couldn't load font '%s'\n", arg1
);
1580 ST_PTITLEFONT(tmpms
) &&
1581 !ST_USING_DEFAULT_TITLEFONT(tmpms
))
1583 FlocaleUnloadFont(dpy
, ST_PTITLEFONT(tmpms
));
1587 /* reset to screen font */
1588 ST_PTITLEFONT(tmpms
) = Scr
.DefaultFont
;
1589 ST_USING_DEFAULT_TITLEFONT(tmpms
) = True
;
1593 ST_PTITLEFONT(tmpms
) = new_font
;
1594 ST_USING_DEFAULT_TITLEFONT(tmpms
) = False
;
1596 has_gc_changed
= True
;
1598 case 62: /* VerticalMargins */
1599 parse_vertical_margins_line(
1600 args
, &ST_VERTICAL_MARGIN_TOP(tmpms
),
1601 &ST_VERTICAL_MARGIN_BOTTOM(tmpms
),
1606 case 99: /* PositionHints */
1607 /* to be implemented */
1612 fvwm_msg(ERR
, "NewMenuStyle", "unknown option '%s'",
1633 menustyle_update(tmpms
);
1636 if (default_menu_style
== NULL
)
1638 /* First MenuStyle MUST be the default style */
1639 default_menu_style
= tmpms
;
1640 ST_NEXT_STYLE(tmpms
) = NULL
;
1644 /* copy our new menu face over the old one */
1645 memcpy(ms
, tmpms
, sizeof(MenuStyle
));
1651 MenuStyle
*before
= default_menu_style
;
1653 /* add a new menu face to list */
1654 ST_NEXT_STYLE(tmpms
) = NULL
;
1655 while (ST_NEXT_STYLE(before
))
1656 before
= ST_NEXT_STYLE(before
);
1657 ST_NEXT_STYLE(before
) = tmpms
;
1663 void menustyle_copy(MenuStyle
*origms
, MenuStyle
*destms
)
1665 FvwmPictureAttributes fpa
;
1666 /* Copy origms to destms, be aware of all pointers in the MenuStyle
1667 strcture. Use the same order as in menustyle_parse_style */
1671 dpy
, &ST_MENU_COLORS(destms
).fore
,
1672 &ST_MENU_COLORS(origms
).fore
, True
, True
);
1674 dpy
, &ST_MENU_COLORS(destms
).back
,
1675 &ST_MENU_COLORS(origms
).back
, True
, True
);
1678 dpy
, &ST_MENU_STIPPLE_COLORS(destms
).fore
,
1679 &ST_MENU_STIPPLE_COLORS(origms
).fore
,
1680 ST_HAS_STIPPLE_FORE(destms
), ST_HAS_STIPPLE_FORE(origms
));
1681 ST_MENU_STIPPLE_COLORS(destms
).back
=
1682 ST_MENU_STIPPLE_COLORS(origms
).back
;
1683 ST_HAS_STIPPLE_FORE(destms
) = ST_HAS_STIPPLE_FORE(origms
);
1687 dpy
, &ST_MENU_ACTIVE_COLORS(destms
).back
,
1688 &ST_MENU_ACTIVE_COLORS(origms
).back
,
1689 ST_HAS_ACTIVE_BACK(destms
), ST_HAS_ACTIVE_BACK(origms
));
1690 ST_HAS_ACTIVE_BACK(destms
) = ST_HAS_ACTIVE_BACK(origms
);
1691 ST_DO_HILIGHT_BACK(destms
) = ST_DO_HILIGHT_BACK(origms
);
1695 dpy
, &ST_MENU_ACTIVE_COLORS(destms
).fore
,
1696 &ST_MENU_ACTIVE_COLORS(origms
).fore
,
1697 ST_HAS_ACTIVE_FORE(destms
), ST_HAS_ACTIVE_FORE(origms
));
1698 ST_HAS_ACTIVE_FORE(destms
) = ST_HAS_ACTIVE_FORE(origms
);
1699 ST_DO_HILIGHT_FORE(destms
) = ST_DO_HILIGHT_FORE(origms
);
1702 ST_RELIEF_THICKNESS(destms
) = ST_RELIEF_THICKNESS(origms
);
1704 ST_IS_ANIMATED(destms
) = ST_IS_ANIMATED(origms
);
1707 if (ST_PSTDFONT(destms
) && !ST_USING_DEFAULT_FONT(destms
))
1709 FlocaleUnloadFont(dpy
, ST_PSTDFONT(destms
));
1711 if (ST_PSTDFONT(origms
) && !ST_USING_DEFAULT_FONT(origms
))
1713 if (!(ST_PSTDFONT(destms
) =
1714 FlocaleLoadFont(dpy
, ST_PSTDFONT(origms
)->name
, "fvwm")))
1716 ST_PSTDFONT(destms
) = Scr
.DefaultFont
;
1717 ST_USING_DEFAULT_FONT(destms
) = True
;
1718 fvwm_msg(ERR
, "CopyMenuStyle",
1719 "Couldn't load font '%s' use Default Font\n",
1720 ST_PSTDFONT(origms
)->name
);
1724 ST_USING_DEFAULT_FONT(destms
) = False
;
1729 ST_USING_DEFAULT_FONT(destms
) = True
;
1730 ST_PSTDFONT(destms
) = Scr
.DefaultFont
;
1733 if (ST_PTITLEFONT(destms
) && !ST_USING_DEFAULT_TITLEFONT(destms
))
1735 FlocaleUnloadFont(dpy
, ST_PTITLEFONT(destms
));
1737 if (ST_PTITLEFONT(origms
) && !ST_USING_DEFAULT_TITLEFONT(origms
))
1740 !(ST_PTITLEFONT(destms
) = FlocaleLoadFont(
1741 dpy
, ST_PTITLEFONT(origms
)->name
, "fvwm")))
1743 ST_PTITLEFONT(destms
) = Scr
.DefaultFont
;
1744 ST_USING_DEFAULT_TITLEFONT(destms
) = True
;
1745 fvwm_msg(ERR
, "CopyMenuStyle",
1746 "Couldn't load font '%s' use Default Font\n",
1747 ST_PTITLEFONT(origms
)->name
);
1751 ST_USING_DEFAULT_TITLEFONT(destms
) = False
;
1756 ST_USING_DEFAULT_TITLEFONT(destms
) = True
;
1757 ST_PTITLEFONT(destms
) = Scr
.DefaultFont
;
1760 menustyle_copy_face(&ST_FACE(destms
), &ST_FACE(origms
));
1763 ST_POPUP_DELAY(destms
) = ST_POPUP_DELAY(origms
);
1765 ST_POPUP_OFFSET_PERCENT(destms
) = ST_POPUP_OFFSET_PERCENT(origms
);
1766 ST_POPUP_OFFSET_ADD(destms
) = ST_POPUP_OFFSET_ADD(origms
);
1768 ST_DO_WARP_TO_TITLE(destms
) = ST_DO_WARP_TO_TITLE(origms
);
1769 /* TitleUnderlines */
1770 ST_TITLE_UNDERLINES(destms
) = ST_TITLE_UNDERLINES(origms
);
1772 ST_HAS_LONG_SEPARATORS(destms
) = ST_HAS_LONG_SEPARATORS(origms
);
1774 ST_HAS_TRIANGLE_RELIEF(destms
) = ST_HAS_TRIANGLE_RELIEF(origms
);
1776 ST_DO_POPUP_IMMEDIATELY(destms
) = ST_DO_POPUP_IMMEDIATELY(origms
);
1777 /* DoubleClickTime */
1778 ST_DOUBLE_CLICK_TIME(destms
) = ST_DOUBLE_CLICK_TIME(origms
);
1779 /* VerticalMargins */
1780 ST_VERTICAL_MARGIN_TOP(destms
) = ST_VERTICAL_MARGIN_TOP(origms
);
1781 ST_VERTICAL_MARGIN_BOTTOM(destms
) = ST_VERTICAL_MARGIN_BOTTOM(origms
);
1784 if (ST_SIDEPIC(destms
))
1786 PDestroyFvwmPicture(dpy
, ST_SIDEPIC(destms
));
1787 ST_SIDEPIC(destms
) = NULL
;
1789 if (ST_SIDEPIC(origms
))
1791 fpa
.mask
= (Pdepth
<= 8)? FPAM_DITHER
:0;
1792 ST_SIDEPIC(destms
) = PCacheFvwmPicture(
1793 dpy
, Scr
.NoFocusWin
, NULL
, ST_SIDEPIC(origms
)->name
,
1799 dpy
, &ST_SIDE_COLOR(destms
), &ST_SIDE_COLOR(origms
),
1800 ST_HAS_SIDE_COLOR(destms
), ST_HAS_SIDE_COLOR(origms
));
1801 ST_HAS_SIDE_COLOR(destms
) = ST_HAS_SIDE_COLOR(origms
);
1803 /* PopupAsRootmenu */
1804 ST_DO_POPUP_AS(destms
) = ST_DO_POPUP_AS(origms
);
1805 /* RemoveSubmenus */
1806 ST_DO_UNMAP_SUBMENU_ON_POPDOWN(destms
) =
1807 ST_DO_UNMAP_SUBMENU_ON_POPDOWN(origms
);
1809 ST_USE_LEFT_SUBMENUS(destms
) = ST_USE_LEFT_SUBMENUS(origms
);
1811 ST_BORDER_WIDTH(destms
) = ST_BORDER_WIDTH(origms
);
1812 /* Hilight3DThickness */
1813 ST_IS_ITEM_RELIEF_REVERSED(destms
) =
1814 ST_IS_ITEM_RELIEF_REVERSED(origms
);
1817 if (ST_ITEM_FORMAT(destms
))
1819 free(ST_ITEM_FORMAT(destms
));
1820 ST_ITEM_FORMAT(destms
) = NULL
;
1822 if (ST_ITEM_FORMAT(origms
))
1824 ST_ITEM_FORMAT(destms
) = safestrdup(ST_ITEM_FORMAT(origms
));
1827 /* AutomaticHotkeys */
1828 ST_USE_AUTOMATIC_HOTKEYS(destms
) = ST_USE_AUTOMATIC_HOTKEYS(origms
);
1829 /* Item and Title Spacing */
1830 ST_ITEM_GAP_ABOVE(destms
) = ST_ITEM_GAP_ABOVE(origms
);
1831 ST_ITEM_GAP_BELOW(destms
) = ST_ITEM_GAP_BELOW(origms
);
1832 ST_TITLE_GAP_ABOVE(destms
) = ST_TITLE_GAP_ABOVE(origms
);
1833 ST_TITLE_GAP_BELOW(destms
) = ST_TITLE_GAP_BELOW(origms
);
1835 ST_HAS_MENU_CSET(destms
) = ST_HAS_MENU_CSET(origms
);
1836 ST_CSET_MENU(destms
) = ST_CSET_MENU(origms
);
1837 /* ActiveColorset */
1838 ST_HAS_ACTIVE_CSET(destms
) = ST_HAS_ACTIVE_CSET(origms
);
1839 ST_CSET_ACTIVE(destms
) = ST_CSET_ACTIVE(origms
);
1841 ST_HAS_GREYED_CSET(destms
) = ST_HAS_GREYED_CSET(origms
);
1842 ST_CSET_GREYED(destms
) = ST_CSET_GREYED(origms
);
1844 ST_HAS_TITLE_CSET(destms
) = ST_HAS_TITLE_CSET(origms
);
1845 ST_CSET_TITLE(destms
) = ST_CSET_TITLE(origms
);
1846 /* SelectOnRelease */
1847 ST_SELECT_ON_RELEASE_KEY(destms
) = ST_SELECT_ON_RELEASE_KEY(origms
);
1848 /* PopdownImmediately */
1849 ST_DO_POPDOWN_IMMEDIATELY(destms
) = ST_DO_POPDOWN_IMMEDIATELY(origms
);
1851 ST_POPDOWN_DELAY(destms
) = ST_POPDOWN_DELAY(origms
);
1853 ST_MOUSE_WHEEL(destms
) = ST_MOUSE_WHEEL(origms
);
1855 ST_SCROLL_OFF_PAGE(destms
) = ST_SCROLL_OFF_PAGE(origms
);
1856 /* TrianglesUseFore */
1857 ST_TRIANGLES_USE_FORE(destms
) = ST_TRIANGLES_USE_FORE(origms
);
1859 ST_DO_HILIGHT_TITLE_BACK(destms
) = ST_DO_HILIGHT_TITLE_BACK(origms
);
1861 menustyle_update(destms
);
1866 /* ---------------------------- builtin commands --------------------------- */
1868 void CMD_CopyMenuStyle(F_CMD_ARGS
)
1870 char *origname
= NULL
;
1871 char *destname
= NULL
;
1876 origname
= PeekToken(action
, &action
);
1877 if (origname
== NULL
)
1879 fvwm_msg(ERR
,"CopyMenuStyle", "need two arguments");
1883 origms
= menustyle_find(origname
);
1886 fvwm_msg(ERR
, "CopyMenuStyle", "%s: no such menu style",
1891 destname
= PeekToken(action
, &action
);
1892 if (destname
== NULL
)
1894 fvwm_msg(ERR
,"CopyMenuStyle", "need two arguments");
1898 if (action
&& *action
)
1900 fvwm_msg(ERR
,"CopyMenuStyle", "too many arguments");
1904 destms
= menustyle_find(destname
);
1907 /* create destms menu style */
1908 buffer
= (char *)safemalloc(strlen(destname
) + 3);
1909 sprintf(buffer
,"\"%s\"",destname
);
1911 destms
= menustyle_parse_style(F_PASS_ARGS
);
1915 /* this must never happen */
1916 fvwm_msg(ERR
, "CopyMenuStyle",
1917 "impossible to create %s menu style",
1923 if (strcasecmp("*",destname
) == 0)
1925 fvwm_msg(ERR
, "CopyMenuStyle",
1926 "You cannot copy on the default menu style");
1929 if (strcasecmp(ST_NAME(origms
),destname
) == 0)
1931 fvwm_msg(ERR
, "CopyMenuStyle",
1932 "%s and %s identify the same menu style",
1933 ST_NAME(origms
),destname
);
1937 if (ST_USAGE_COUNT(destms
) != 0)
1939 fvwm_msg(ERR
, "CopyMenuStyle", "menu style %s is in use",
1944 menustyle_copy(origms
, destms
);
1949 void CMD_MenuStyle(F_CMD_ARGS
)
1955 GetNextSimpleOption(SkipNTokens(action
, 1), &option
);
1957 while (poption
&& poption
[0] == '!')
1961 if (option
== NULL
|| menustyle_get_styleopt_index(poption
) != -1)
1963 dummy
= menustyle_parse_style(F_PASS_ARGS
);
1967 dummy
= menustyle_parse_old_style(F_PASS_ARGS
);