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;
137 /* Should never happen. */
140 PDestroyFvwmPicture(dpy
, destmf
->u
.p
);
146 destmf
->u
.p
= PCacheFvwmPicture(
147 dpy
, Scr
.NoFocusWin
, NULL
, origmf
->u
.p
->name
,
151 destmf
->type
= origmf
->type
;
160 * Reads a menu face line into a structure (veliaa@rpi.edu)
163 static Boolean
menustyle_parse_face(char *s
, MenuFace
*mf
, int verbose
)
168 FvwmPictureAttributes fpa
;
170 s
= GetNextToken(s
, &style
);
171 if (style
&& strncasecmp(style
, "--", 2) == 0)
177 menustyle_free_face(mf
);
178 mf
->type
= SimpleMenu
;
180 /* determine menu style */
185 else if (StrEquals(style
,"Solid"))
187 s
= GetNextToken(s
, &token
);
190 mf
->type
= SolidMenu
;
191 mf
->u
.back
= GetColor(token
);
198 fvwm_msg(ERR
, "menustyle_parse_face",
199 "no color given for Solid face type:"
207 else if (StrEquals(style
+1, "Gradient"))
210 int npixels
, nsegs
, *perc
;
213 if (!IsGradientTypeSupported(style
[0]))
218 /* translate the gradient string into an array of colors etc */
219 npixels
= ParseGradient(s
, NULL
, &s_colors
, &perc
, &nsegs
);
225 mf
->u
.grad
.do_dither
= False
;
228 mf
->u
.grad
.do_dither
= True
;
230 /* grab the colors */
231 xcs
= AllocAllGradientColors(
232 s_colors
, perc
, nsegs
, npixels
, mf
->u
.grad
.do_dither
);
238 mf
->u
.grad
.xcs
= xcs
;
239 mf
->u
.grad
.npixels
= npixels
;
240 mf
->type
= GradientMenu
;
241 mf
->gradient_type
= toupper(style
[0]);
244 else if (StrEquals(style
,"Pixmap") || StrEquals(style
,"TiledPixmap"))
246 s
= GetNextToken(s
, &token
);
247 fpa
.mask
= (Pdepth
<= 8)? FPAM_DITHER
:0;
250 mf
->u
.p
= PCacheFvwmPicture(
251 dpy
, Scr
.NoFocusWin
, NULL
, token
, fpa
);
256 fvwm_msg(ERR
, "menustyle_parse_face",
257 "couldn't load pixmap %s",
265 mf
->type
= (StrEquals(style
,"TiledPixmap")) ?
266 TiledPixmapMenu
: PixmapMenu
;
272 fvwm_msg(ERR
, "menustyle_parse_face",
273 "missing pixmap name for style %s",
286 "menustyle_parse_face", "unknown style %s: %s",
297 static void parse_vertical_spacing_line(
298 char *args
, signed char *above
, signed char *below
,
299 signed char above_default
, signed char below_default
)
303 if (GetIntegerArguments(args
, NULL
, val
, 2) != 2 ||
304 val
[0] < MIN_VERTICAL_SPACING
|| val
[0] > MAX_VERTICAL_SPACING
||
305 val
[1] < MIN_VERTICAL_SPACING
|| val
[1] > MAX_VERTICAL_SPACING
)
307 /* illegal or missing parameters, return to default */
308 *above
= above_default
;
309 *below
= below_default
;
318 static void parse_vertical_margins_line(
319 char *args
, unsigned char *top
, unsigned char *bottom
,
320 signed char top_default
, signed char bottom_default
)
324 if (GetIntegerArguments(args
, NULL
, val
, 2) != 2 ||
325 val
[0] < 0 || val
[0] > MAX_MENU_MARGIN
||
326 val
[1] < 0 || val
[1] > MAX_MENU_MARGIN
)
328 /* invalid or missing parameters, return to default */
330 *bottom
= bottom_default
;
339 static MenuStyle
*menustyle_parse_old_style(F_CMD_ARGS
)
342 char *fore
, *back
, *stipple
, *font
, *style
, *animated
;
343 MenuStyle
*ms
= NULL
;
345 rest
= GetNextToken(action
,&fore
);
346 rest
= GetNextToken(rest
,&back
);
347 rest
= GetNextToken(rest
,&stipple
);
348 rest
= GetNextToken(rest
,&font
);
349 rest
= GetNextToken(rest
,&style
);
350 rest
= GetNextToken(rest
,&animated
);
352 if (!fore
|| !back
|| !stipple
|| !font
|| !style
)
354 fvwm_msg(ERR
, "menustyle_parse_old_style",
355 "error in %s style specification", action
);
359 buffer
= (char *)alloca(strlen(action
) + 100);
361 "* \"%s\", Foreground \"%s\", Background \"%s\", "
362 "Greyed \"%s\", Font \"%s\", \"%s\"",
363 style
, fore
, back
, stipple
, font
,
364 (animated
&& StrEquals(animated
, "anim")) ?
365 "Animation" : "AnimationOff");
366 fvwm_msg(OLD
, "menustyle_parse_old_style",
367 "The old MenuStyle snytax has been deprecated. "
368 "Use 'MenuStyle %s' instead of 'MenuStyle %s'\n",
371 ms
= menustyle_parse_style(F_PASS_ARGS
);
402 static int menustyle_get_styleopt_index(char *option
)
405 "fvwm", "mwm", "win",
406 "Foreground", "Background", "Greyed",
407 "HilightBack", "HilightBackOff",
408 "ActiveFore", "ActiveForeOff",
409 "Hilight3DThick", "Hilight3DThin", "Hilight3DOff",
410 "Animation", "AnimationOff",
413 "PopupDelay", "PopupOffset",
414 "TitleWarp", "TitleWarpOff",
415 "TitleUnderlines0", "TitleUnderlines1", "TitleUnderlines2",
416 "SeparatorsLong", "SeparatorsShort",
417 "TrianglesSolid", "TrianglesRelief",
418 "PopupImmediately", "PopupDelayed",
420 "SidePic", "SideColor",
421 "PopupAsRootmenu", "PopupAsSubmenu",
422 "RemoveSubmenus", "HoldSubmenus",
423 "SubmenusRight", "SubmenusLeft",
425 "Hilight3DThickness",
427 "AutomaticHotkeys", "AutomaticHotkeysOff",
428 "VerticalItemSpacing",
429 "VerticalTitleSpacing",
430 "MenuColorset", "ActiveColorset", "GreyedColorset",
432 "PopdownImmediately", "PopdownDelayed",
435 "PopupIgnore", "PopupClose",
436 "MouseWheel", "ScrollOffPage",
438 "TitleColorset", "HilightTitleBack",
444 return GetTokenIndex(option
, optlist
, 0, NULL
);
447 static void change_or_make_gc(GC
*gc
, unsigned long gcm
, XGCValues
*gcv
)
451 XChangeGC(dpy
, *gc
, gcm
, gcv
);
455 *gc
= fvwmlib_XCreateGC(dpy
, Scr
.NoFocusWin
, gcm
, gcv
);
461 /* ---------------------------- interface functions ------------------------ */
463 MenuStyle
*menustyle_get_default_style(void)
465 return default_menu_style
;
468 void menustyle_free(MenuStyle
*ms
)
470 MenuStyle
*before
= default_menu_style
;
476 menustyle_free_face(&ST_FACE(ms
));
477 if (FORE_GC(ST_MENU_INACTIVE_GCS(ms
)))
479 XFreeGC(dpy
, FORE_GC(ST_MENU_INACTIVE_GCS(ms
)));
481 if (FORE_GC(ST_MENU_ACTIVE_GCS(ms
)))
483 XFreeGC(dpy
, FORE_GC(ST_MENU_ACTIVE_GCS(ms
)));
485 if (BACK_GC(ST_MENU_ACTIVE_GCS(ms
)))
487 XFreeGC(dpy
, BACK_GC(ST_MENU_ACTIVE_GCS(ms
)));
489 if (HILIGHT_GC(ST_MENU_ACTIVE_GCS(ms
)))
491 XFreeGC(dpy
, HILIGHT_GC(ST_MENU_ACTIVE_GCS(ms
)));
493 if (SHADOW_GC(ST_MENU_ACTIVE_GCS(ms
)))
495 XFreeGC(dpy
, SHADOW_GC(ST_MENU_ACTIVE_GCS(ms
)));
497 if (HILIGHT_GC(ST_MENU_INACTIVE_GCS(ms
)))
499 XFreeGC(dpy
, HILIGHT_GC(ST_MENU_INACTIVE_GCS(ms
)));
501 if (SHADOW_GC(ST_MENU_INACTIVE_GCS(ms
)))
503 XFreeGC(dpy
, SHADOW_GC(ST_MENU_INACTIVE_GCS(ms
)));
505 if (FORE_GC(ST_MENU_STIPPLE_GCS(ms
)))
507 XFreeGC(dpy
, FORE_GC(ST_MENU_STIPPLE_GCS(ms
)));
509 if (FORE_GC(ST_MENU_TITLE_GCS(ms
)))
511 XFreeGC(dpy
, FORE_GC(ST_MENU_TITLE_GCS(ms
)));
513 if (BACK_GC(ST_MENU_TITLE_GCS(ms
)))
515 XFreeGC(dpy
, BACK_GC(ST_MENU_TITLE_GCS(ms
)));
517 if (HILIGHT_GC(ST_MENU_TITLE_GCS(ms
)))
519 XFreeGC(dpy
, HILIGHT_GC(ST_MENU_TITLE_GCS(ms
)));
521 if (SHADOW_GC(ST_MENU_TITLE_GCS(ms
)))
523 XFreeGC(dpy
, SHADOW_GC(ST_MENU_TITLE_GCS(ms
)));
527 PDestroyFvwmPicture(dpy
, ST_SIDEPIC(ms
));
529 if (ST_HAS_SIDE_COLOR(ms
) == 1)
531 fvwmlib_free_colors(dpy
, &ST_SIDE_COLOR(ms
), 1, True
);
533 if (ST_PSTDFONT(ms
) && !ST_USING_DEFAULT_FONT(ms
))
535 FlocaleUnloadFont(dpy
, ST_PSTDFONT(ms
));
537 if (ST_PTITLEFONT(ms
) && !ST_USING_DEFAULT_TITLEFONT(ms
))
539 FlocaleUnloadFont(dpy
, ST_PTITLEFONT(ms
));
541 if (ST_ITEM_FORMAT(ms
))
543 free(ST_ITEM_FORMAT(ms
));
546 fvwmlib_free_colors(dpy
, &ST_MENU_COLORS(ms
).back
,1,True
);
547 fvwmlib_free_colors(dpy
, &ST_MENU_COLORS(ms
).fore
,1,True
);
548 if (ST_HAS_STIPPLE_FORE(ms
))
551 dpy
, &ST_MENU_STIPPLE_COLORS(ms
).fore
,1,True
);
553 if (ST_HAS_ACTIVE_BACK(ms
))
556 dpy
, &ST_MENU_ACTIVE_COLORS(ms
).back
,1,True
);
558 if (ST_HAS_ACTIVE_FORE(ms
))
561 dpy
, &ST_MENU_ACTIVE_COLORS(ms
).fore
,1,True
);
564 while (ST_NEXT_STYLE(before
) != ms
)
566 /* Not too many checks, may segfault in race conditions */
567 before
= ST_NEXT_STYLE(before
);
570 ST_NEXT_STYLE(before
) = ST_NEXT_STYLE(ms
);
577 MenuStyle
*menustyle_find(char *name
)
579 MenuStyle
*ms
= default_menu_style
;
583 if (strcasecmp(ST_NAME(ms
),name
)==0)
587 ms
= ST_NEXT_STYLE(ms
);
593 void menustyle_update(MenuStyle
*ms
)
597 color_quad c_inactive
;
599 color_quad c_stipple
;
601 colorset_t
*menu_cs
= &Colorset
[ST_CSET_MENU(ms
)];
602 colorset_t
*active_cs
= &Colorset
[ST_CSET_ACTIVE(ms
)];
603 colorset_t
*greyed_cs
= &Colorset
[ST_CSET_GREYED(ms
)];
604 colorset_t
*title_cs
= &Colorset
[ST_CSET_TITLE(ms
)];
606 if (ST_USAGE_COUNT(ms
) != 0)
608 fvwm_msg(ERR
,"menustyle_update", "menu style %s is in use",
612 ST_IS_UPDATED(ms
) = 1;
613 if (ST_USING_DEFAULT_FONT(ms
))
615 ST_PSTDFONT(ms
) = Scr
.DefaultFont
;
617 if (ST_USING_DEFAULT_TITLEFONT(ms
))
619 ST_PTITLEFONT(ms
) = ST_PSTDFONT(ms
);
621 /* calculate colors based on foreground */
622 if (!ST_HAS_ACTIVE_FORE(ms
))
624 ST_MENU_ACTIVE_COLORS(ms
).fore
= ST_MENU_COLORS(ms
).fore
;
626 /* calculate colors based on background */
627 if (!ST_HAS_ACTIVE_BACK(ms
))
629 ST_MENU_ACTIVE_COLORS(ms
).back
= ST_MENU_COLORS(ms
).back
;
631 if (!ST_HAS_STIPPLE_FORE(ms
))
633 ST_MENU_STIPPLE_COLORS(ms
).fore
= ST_MENU_COLORS(ms
).back
;
635 ST_MENU_STIPPLE_COLORS(ms
).back
= ST_MENU_COLORS(ms
).back
;
636 /* prepare colours for changing the gcs */
637 if (ST_HAS_MENU_CSET(ms
))
639 c_inactive
.fore
= menu_cs
->fg
;
640 c_inactive
.back
= menu_cs
->bg
;
641 c_inactive
.hilight
= menu_cs
->hilite
;
642 c_inactive
.shadow
= menu_cs
->shadow
;
646 c_inactive
.fore
= ST_MENU_COLORS(ms
).fore
;
647 c_inactive
.back
= ST_MENU_COLORS(ms
).back
;
650 c_inactive
.hilight
= GetHilite(ST_MENU_COLORS(ms
).back
);
651 c_inactive
.shadow
= GetShadow(ST_MENU_COLORS(ms
).back
);
655 c_inactive
.hilight
= GetColor(DEFAULT_HILIGHT_COLOR
);
656 c_inactive
.shadow
= GetColor(DEFAULT_SHADOW_COLOR
);
659 if (ST_HAS_ACTIVE_CSET(ms
))
661 c_active
.fore
= active_cs
->fg
;
662 c_active
.back
= active_cs
->bg
;
663 c_active
.hilight
= active_cs
->hilite
;
664 c_active
.shadow
= active_cs
->shadow
;
668 c_active
.fore
= ST_MENU_ACTIVE_COLORS(ms
).fore
;
669 c_active
.back
= ST_MENU_ACTIVE_COLORS(ms
).back
;
673 GetHilite(ST_MENU_ACTIVE_COLORS(ms
).back
);
675 GetShadow(ST_MENU_ACTIVE_COLORS(ms
).back
);
679 c_active
.hilight
= GetColor(DEFAULT_HILIGHT_COLOR
);
680 c_active
.shadow
= GetColor(DEFAULT_SHADOW_COLOR
);
683 if (ST_HAS_GREYED_CSET(ms
))
685 c_stipple
.fore
= greyed_cs
->fg
;
686 c_stipple
.back
= greyed_cs
->fg
;
690 c_stipple
.fore
= ST_MENU_STIPPLE_COLORS(ms
).fore
;
691 c_stipple
.back
= ST_MENU_STIPPLE_COLORS(ms
).back
;
693 if (ST_HAS_TITLE_CSET(ms
))
695 c_title
.fore
= title_cs
->fg
;
696 c_title
.back
= title_cs
->bg
;
697 c_title
.hilight
= title_cs
->hilite
;
698 c_title
.shadow
= title_cs
->shadow
;
702 c_title
.fore
= c_inactive
.fore
;
703 c_title
.back
= c_inactive
.back
;
704 c_title
.hilight
= c_inactive
.hilight
;
705 c_title
.shadow
= c_inactive
.shadow
;
707 /* override hilighting colours if necessary */
708 if (!ST_DO_HILIGHT_FORE(ms
))
710 c_active
.fore
= c_inactive
.fore
;
712 if (!ST_DO_HILIGHT_BACK(ms
))
714 c_active
.back
= c_inactive
.back
;
715 c_active
.hilight
= c_inactive
.hilight
;
716 c_active
.shadow
= c_inactive
.shadow
;
718 if (!ST_DO_HILIGHT_TITLE_BACK(ms
))
720 c_title
.fore
= c_inactive
.fore
;
721 c_title
.back
= c_inactive
.back
;
722 c_title
.hilight
= c_inactive
.hilight
;
723 c_title
.shadow
= c_inactive
.shadow
;
726 gcm
= GCFunction
|GCLineWidth
|GCForeground
|GCBackground
;
727 if (ST_PSTDFONT(ms
)->font
!= NULL
)
730 gcv
.font
= ST_PSTDFONT(ms
)->font
->fid
;
732 gcv
.function
= GXcopy
;
734 /* update inactive menu gcs */
735 gcv
.foreground
= c_inactive
.fore
;
736 gcv
.background
= c_inactive
.back
;
737 change_or_make_gc(&FORE_GC(ST_MENU_INACTIVE_GCS(ms
)), gcm
, &gcv
);
738 BACK_GC(ST_MENU_INACTIVE_GCS(ms
)) = FORE_GC(ST_MENU_INACTIVE_GCS(ms
));
739 gcv
.foreground
= c_inactive
.hilight
;
740 gcv
.background
= c_inactive
.shadow
;
741 change_or_make_gc(&HILIGHT_GC(ST_MENU_INACTIVE_GCS(ms
)), gcm
, &gcv
);
742 gcv
.foreground
= c_inactive
.shadow
;
743 gcv
.background
= c_inactive
.hilight
;
744 change_or_make_gc(&SHADOW_GC(ST_MENU_INACTIVE_GCS(ms
)), gcm
, &gcv
);
745 /* update active menu gcs */
746 gcv
.foreground
= c_active
.fore
;
747 gcv
.background
= c_active
.back
;
748 change_or_make_gc(&FORE_GC(ST_MENU_ACTIVE_GCS(ms
)), gcm
, &gcv
);
749 gcv
.foreground
= c_active
.back
;
750 gcv
.background
= c_active
.fore
;
752 if (ST_HAS_ACTIVE_CSET(ms
) && active_cs
->pixmap
&&
753 active_cs
->pixmap_type
== PIXMAP_TILED
)
755 gcv
.tile
= active_cs
->pixmap
;
756 gcv
.fill_style
= FillTiled
;
757 change_or_make_gc(&BACK_GC(ST_MENU_ACTIVE_GCS(ms
)),
758 gcm
| GCFillStyle
| GCTile
, &gcv
);
762 gcv
.fill_style
= FillSolid
;
763 change_or_make_gc(&BACK_GC(ST_MENU_ACTIVE_GCS(ms
)),
764 gcm
| GCFillStyle
, &gcv
);
768 gcv
.foreground
= c_active
.hilight
;
769 gcv
.background
= c_active
.shadow
;
770 change_or_make_gc(&HILIGHT_GC(ST_MENU_ACTIVE_GCS(ms
)), gcm
, &gcv
);
771 gcv
.foreground
= c_active
.shadow
;
772 gcv
.background
= c_active
.hilight
;
773 change_or_make_gc(&SHADOW_GC(ST_MENU_ACTIVE_GCS(ms
)), gcm
, &gcv
);
774 /* update title gcs */
775 if (ST_PTITLEFONT(ms
)->font
!= NULL
&& ST_PSTDFONT(ms
)->font
== NULL
)
777 if (ST_PSTDFONT(ms
)->font
== NULL
)
781 gcv
.font
= ST_PTITLEFONT(ms
)->font
->fid
;
783 gcv
.foreground
= c_title
.fore
;
784 gcv
.background
= c_title
.back
;
785 change_or_make_gc(&FORE_GC(ST_MENU_TITLE_GCS(ms
)), gcm
, &gcv
);
786 gcv
.foreground
= c_title
.back
;
787 gcv
.background
= c_title
.fore
;
789 if (ST_HAS_TITLE_CSET(ms
) && title_cs
->pixmap
&&
790 title_cs
->pixmap_type
== PIXMAP_TILED
)
792 gcv
.tile
= title_cs
->pixmap
;
793 gcv
.fill_style
= FillTiled
;
794 change_or_make_gc(&BACK_GC(ST_MENU_TITLE_GCS(ms
)),
795 gcm
| GCFillStyle
| GCTile
, &gcv
);
799 gcv
.fill_style
= FillSolid
;
800 change_or_make_gc(&BACK_GC(ST_MENU_TITLE_GCS(ms
)),
801 gcm
| GCFillStyle
, &gcv
);
804 gcv
.foreground
= c_title
.hilight
;
805 gcv
.background
= c_title
.shadow
;
806 change_or_make_gc(&HILIGHT_GC(ST_MENU_TITLE_GCS(ms
)), gcm
, &gcv
);
807 gcv
.foreground
= c_title
.shadow
;
808 gcv
.background
= c_title
.hilight
;
809 change_or_make_gc(&SHADOW_GC(ST_MENU_TITLE_GCS(ms
)), gcm
, &gcv
);
810 /* update stipple menu gcs */
811 SHADOW_GC(ST_MENU_STIPPLE_GCS(ms
)) =
812 SHADOW_GC(ST_MENU_INACTIVE_GCS(ms
));
815 gcv
.fill_style
= FillStippled
;
816 gcv
.stipple
= Scr
.gray_bitmap
;
817 /* no need to reset fg/bg, FillStipple wins */
818 gcm
|= GCStipple
| GCFillStyle
;
819 HILIGHT_GC(ST_MENU_STIPPLE_GCS(ms
)) =
820 SHADOW_GC(ST_MENU_INACTIVE_GCS(ms
));
824 gcv
.foreground
= c_stipple
.fore
;
825 gcv
.background
= c_stipple
.back
;
826 HILIGHT_GC(ST_MENU_STIPPLE_GCS(ms
)) =
827 HILIGHT_GC(ST_MENU_INACTIVE_GCS(ms
));
829 change_or_make_gc(&FORE_GC(ST_MENU_STIPPLE_GCS(ms
)), gcm
, &gcv
);
830 BACK_GC(ST_MENU_STIPPLE_GCS(ms
)) = BACK_GC(ST_MENU_INACTIVE_GCS(ms
));
835 MenuStyle
*menustyle_parse_style(F_CMD_ARGS
)
839 char *poption
= NULL
;
840 char *optstring
= NULL
;
847 Bool is_initialised
= True
;
848 Bool has_gc_changed
= False
;
849 Bool is_default_style
= False
;
852 FlocaleFont
*new_font
= NULL
;
855 FvwmPictureAttributes fpa
;
857 action
= GetNextToken(action
, &name
);
860 fvwm_msg(ERR
, "NewMenuStyle",
861 "error in %s style specification",action
);
865 ms
= menustyle_find(name
);
866 if (ms
&& ST_USAGE_COUNT(ms
) != 0)
868 fvwm_msg(ERR
,"NewMenuStyle", "menu style %s is in use", name
);
871 tmpms
= (MenuStyle
*)safemalloc(sizeof(MenuStyle
));
874 /* copy the structure over our temporary menu face. */
875 memcpy(tmpms
, ms
, sizeof(MenuStyle
));
876 if (ms
== default_menu_style
)
878 is_default_style
= True
;
884 memset(tmpms
, 0, sizeof(MenuStyle
));
885 ST_NAME(tmpms
) = name
;
886 is_initialised
= False
;
888 ST_IS_UPDATED(tmpms
) = 1;
890 /* Parse the options. */
891 while (!is_initialised
|| (action
&& *action
))
896 /* some default configuration goes here for the new
898 ST_MENU_COLORS(tmpms
).back
=
899 GetColor(DEFAULT_BACK_COLOR
);
900 ST_MENU_COLORS(tmpms
).fore
=
901 GetColor(DEFAULT_FORE_COLOR
);
902 ST_PSTDFONT(tmpms
) = Scr
.DefaultFont
;
903 ST_USING_DEFAULT_FONT(tmpms
) = True
;
904 ST_FACE(tmpms
).type
= SimpleMenu
;
905 ST_HAS_ACTIVE_FORE(tmpms
) = 0;
906 ST_HAS_ACTIVE_BACK(tmpms
) = 0;
907 ST_DO_POPUP_AS(tmpms
) = MDP_POST_MENU
;
908 ST_DOUBLE_CLICK_TIME(tmpms
) = DEFAULT_MENU_CLICKTIME
;
909 ST_POPUP_DELAY(tmpms
) = DEFAULT_POPUP_DELAY
;
910 ST_POPDOWN_DELAY(tmpms
) = DEFAULT_POPDOWN_DELAY
;
911 ST_MOUSE_WHEEL(tmpms
) = MMW_POINTER
;
912 ST_SCROLL_OFF_PAGE(tmpms
) = 1;
913 ST_DO_HILIGHT_TITLE_BACK(tmpms
) = 0;
914 ST_USING_DEFAULT_TITLEFONT(tmpms
) = True
;
915 has_gc_changed
= True
;
920 /* Read next option specification (delimited by a comma
923 action
= GetQuotedString(
924 action
, &optstring
, ",", NULL
, NULL
, NULL
);
929 args
= GetNextToken(optstring
, &option
);
935 nextarg
= GetNextToken(args
, &arg1
);
938 while (poption
[0] == '!')
943 switch((i
= menustyle_get_styleopt_index(poption
)))
950 ST_POPUP_OFFSET_PERCENT(tmpms
) = 67;
951 ST_POPUP_OFFSET_ADD(tmpms
) = 0;
952 ST_DO_POPUP_IMMEDIATELY(tmpms
) = 0;
953 ST_DO_WARP_TO_TITLE(tmpms
) = 1;
954 ST_DO_UNMAP_SUBMENU_ON_POPDOWN(tmpms
) = 0;
955 ST_RELIEF_THICKNESS(tmpms
) = 1;
956 ST_TITLE_UNDERLINES(tmpms
) = 1;
957 ST_HAS_LONG_SEPARATORS(tmpms
) = 0;
958 ST_HAS_TRIANGLE_RELIEF(tmpms
) = 1;
959 ST_DO_HILIGHT_BACK(tmpms
) = 0;
960 ST_DO_HILIGHT_FORE(tmpms
) = 0;
964 ST_POPUP_OFFSET_PERCENT(tmpms
) = 100;
965 ST_POPUP_OFFSET_ADD(tmpms
) =
966 -DEFAULT_MENU_BORDER_WIDTH
- 1;
967 ST_DO_POPUP_IMMEDIATELY(tmpms
) = 1;
968 ST_DO_WARP_TO_TITLE(tmpms
) = 0;
969 ST_DO_UNMAP_SUBMENU_ON_POPDOWN(tmpms
) = 0;
970 ST_RELIEF_THICKNESS(tmpms
) = 2;
971 ST_TITLE_UNDERLINES(tmpms
) = 2;
972 ST_HAS_LONG_SEPARATORS(tmpms
) = 1;
973 ST_HAS_TRIANGLE_RELIEF(tmpms
) = 1;
974 ST_DO_HILIGHT_BACK(tmpms
) = 0;
975 ST_DO_HILIGHT_FORE(tmpms
) = 0;
979 ST_POPUP_OFFSET_PERCENT(tmpms
) = 100;
980 ST_POPUP_OFFSET_ADD(tmpms
) =
981 -DEFAULT_MENU_BORDER_WIDTH
- 3;
982 ST_DO_POPUP_IMMEDIATELY(tmpms
) = 1;
983 ST_DO_WARP_TO_TITLE(tmpms
) = 0;
984 ST_DO_UNMAP_SUBMENU_ON_POPDOWN(tmpms
) = 1;
985 ST_RELIEF_THICKNESS(tmpms
) = 0;
986 ST_TITLE_UNDERLINES(tmpms
) = 1;
987 ST_HAS_LONG_SEPARATORS(tmpms
) = 0;
988 ST_HAS_TRIANGLE_RELIEF(tmpms
) = 0;
989 ST_DO_HILIGHT_BACK(tmpms
) = 1;
990 ST_DO_HILIGHT_FORE(tmpms
) = 1;
993 /* common settings */
994 ST_VERTICAL_MARGIN_TOP(tmpms
) = 0;
995 ST_VERTICAL_MARGIN_BOTTOM(tmpms
) = 0;
996 ST_CSET_MENU(tmpms
) = 0;
997 ST_HAS_MENU_CSET(tmpms
) = 0;
998 ST_CSET_ACTIVE(tmpms
) = 0;
999 ST_HAS_ACTIVE_CSET(tmpms
) = 0;
1000 ST_CSET_GREYED(tmpms
) = 0;
1001 ST_HAS_GREYED_CSET(tmpms
) = 0;
1002 ST_BORDER_WIDTH(tmpms
) = DEFAULT_MENU_BORDER_WIDTH
;
1003 ST_ACTIVE_AREA_PERCENT(tmpms
) =
1004 DEFAULT_MENU_POPUP_NOW_RATIO
;
1005 ST_ITEM_GAP_ABOVE(tmpms
) =
1006 DEFAULT_MENU_ITEM_TEXT_Y_OFFSET
;
1007 ST_ITEM_GAP_BELOW(tmpms
) =
1008 DEFAULT_MENU_ITEM_TEXT_Y_OFFSET2
;
1009 ST_TITLE_GAP_ABOVE(tmpms
) =
1010 DEFAULT_MENU_TITLE_TEXT_Y_OFFSET
;
1011 ST_TITLE_GAP_BELOW(tmpms
) =
1012 DEFAULT_MENU_TITLE_TEXT_Y_OFFSET2
;
1013 ST_USE_LEFT_SUBMENUS(tmpms
) = 0;
1014 ST_IS_ANIMATED(tmpms
) = 0;
1015 ST_USE_AUTOMATIC_HOTKEYS(tmpms
) = 0;
1016 menustyle_free_face(&ST_FACE(tmpms
));
1017 ST_FACE(tmpms
).type
= SimpleMenu
;
1018 if (ST_PSTDFONT(tmpms
) && !ST_USING_DEFAULT_FONT(tmpms
))
1020 FlocaleUnloadFont(dpy
, ST_PSTDFONT(tmpms
));
1022 ST_PSTDFONT(tmpms
) = Scr
.DefaultFont
;
1023 ST_USING_DEFAULT_FONT(tmpms
) = True
;
1024 has_gc_changed
= True
;
1025 if (ST_HAS_SIDE_COLOR(tmpms
) == 1)
1027 fvwmlib_free_colors(
1028 dpy
, &ST_SIDE_COLOR(tmpms
), 1, True
);
1029 ST_HAS_SIDE_COLOR(tmpms
) = 0;
1031 ST_HAS_SIDE_COLOR(tmpms
) = 0;
1032 if (ST_SIDEPIC(tmpms
))
1034 PDestroyFvwmPicture(dpy
, ST_SIDEPIC(tmpms
));
1035 ST_SIDEPIC(tmpms
) = NULL
;
1038 if (is_initialised
== False
)
1040 /* now begin the real work */
1041 is_initialised
= True
;
1046 case 3: /* Foreground */
1047 fvwmlib_free_colors(
1048 dpy
, &ST_MENU_COLORS(tmpms
).fore
, 1, True
);
1051 ST_MENU_COLORS(tmpms
).fore
= GetColor(arg1
);
1055 ST_MENU_COLORS(tmpms
).fore
=
1056 GetColor(DEFAULT_FORE_COLOR
);
1058 has_gc_changed
= True
;
1061 case 4: /* Background */
1062 fvwmlib_free_colors(
1063 dpy
, &ST_MENU_COLORS(tmpms
).back
, 1, True
);
1066 ST_MENU_COLORS(tmpms
).back
= GetColor(arg1
);
1070 ST_MENU_COLORS(tmpms
).back
=
1071 GetColor(DEFAULT_BACK_COLOR
);
1073 has_gc_changed
= True
;
1076 case 5: /* Greyed */
1077 if (ST_HAS_STIPPLE_FORE(tmpms
))
1079 fvwmlib_free_colors(
1081 &ST_MENU_STIPPLE_COLORS(tmpms
).fore
, 1,
1086 ST_HAS_STIPPLE_FORE(tmpms
) = 0;
1090 ST_MENU_STIPPLE_COLORS(tmpms
).fore
=
1092 ST_HAS_STIPPLE_FORE(tmpms
) = 1;
1094 has_gc_changed
= True
;
1097 case 7: /* HilightBackOff */
1100 case 6: /* HilightBack */
1101 if (ST_HAS_ACTIVE_BACK(tmpms
))
1103 fvwmlib_free_colors(
1105 &ST_MENU_ACTIVE_COLORS(tmpms
).back
, 1,
1108 if (arg1
== NULL
|| !on
)
1110 ST_HAS_ACTIVE_BACK(tmpms
) = 0;
1114 ST_MENU_ACTIVE_COLORS(tmpms
).back
=
1116 ST_HAS_ACTIVE_BACK(tmpms
) = 1;
1118 ST_DO_HILIGHT_BACK(tmpms
) = on
;
1119 has_gc_changed
= True
;
1122 case 9: /* ActiveForeOff */
1125 case 8: /* ActiveFore */
1126 if (ST_HAS_ACTIVE_FORE(tmpms
))
1128 fvwmlib_free_colors(
1130 &ST_MENU_ACTIVE_COLORS(tmpms
).fore
, 1,
1133 if (arg1
== NULL
|| !on
)
1135 ST_HAS_ACTIVE_FORE(tmpms
) = 0;
1139 ST_MENU_ACTIVE_COLORS(tmpms
).fore
=
1141 ST_HAS_ACTIVE_FORE(tmpms
) = 1;
1143 ST_DO_HILIGHT_FORE(tmpms
) = on
;
1144 has_gc_changed
= True
;
1147 case 10: /* Hilight3DThick */
1148 ST_RELIEF_THICKNESS(tmpms
) = 2;
1151 case 11: /* Hilight3DThin */
1152 ST_RELIEF_THICKNESS(tmpms
) = 1;
1155 case 12: /* Hilight3DOff */
1156 ST_RELIEF_THICKNESS(tmpms
) = 0;
1159 case 13: /* Animation */
1160 ST_IS_ANIMATED(tmpms
) = on
;
1163 case 14: /* AnimationOff */
1164 ST_IS_ANIMATED(tmpms
) = !on
;
1169 !(new_font
= FlocaleLoadFont(dpy
, arg1
, "fvwm")))
1171 fvwm_msg(ERR
, "NewMenuStyle",
1172 "Couldn't load font '%s'\n", arg1
);
1175 if (ST_PSTDFONT(tmpms
) && !ST_USING_DEFAULT_FONT(tmpms
))
1177 FlocaleUnloadFont(dpy
, ST_PSTDFONT(tmpms
));
1181 /* reset to screen font */
1182 ST_PSTDFONT(tmpms
) = Scr
.DefaultFont
;
1183 ST_USING_DEFAULT_FONT(tmpms
) = True
;
1187 ST_PSTDFONT(tmpms
) = new_font
;
1188 ST_USING_DEFAULT_FONT(tmpms
) = False
;
1190 has_gc_changed
= True
;
1193 case 16: /* MenuFace */
1194 while (args
&& *args
!= '\0' &&
1195 isspace((unsigned char)*args
))
1199 menustyle_parse_face(args
, &ST_FACE(tmpms
), True
);
1202 case 17: /* PopupDelay */
1203 if (GetIntegerArguments(args
, NULL
, val
, 1) == 0 ||
1206 ST_POPUP_DELAY(tmpms
) = DEFAULT_POPUP_DELAY
;
1210 ST_POPUP_DELAY(tmpms
) = (*val
+9)/10;
1214 case 18: /* PopupOffset */
1215 if ((n
= GetIntegerArguments(args
, NULL
, val
, 2)) == 0)
1217 fvwm_msg(ERR
,"NewMenuStyle",
1218 "PopupOffset requires one or two"
1223 ST_POPUP_OFFSET_ADD(tmpms
) = val
[0];
1224 if (n
== 2 && val
[1] <= 100 && val
[1] >= 0)
1226 ST_POPUP_OFFSET_PERCENT(tmpms
) = val
[1];
1230 ST_POPUP_OFFSET_PERCENT(tmpms
) = 100;
1235 case 19: /* TitleWarp */
1236 ST_DO_WARP_TO_TITLE(tmpms
) = on
;
1239 case 20: /* TitleWarpOff */
1240 ST_DO_WARP_TO_TITLE(tmpms
) = !on
;
1243 case 21: /* TitleUnderlines0 */
1244 ST_TITLE_UNDERLINES(tmpms
) = 0;
1247 case 22: /* TitleUnderlines1 */
1248 ST_TITLE_UNDERLINES(tmpms
) = 1;
1251 case 23: /* TitleUnderlines2 */
1252 ST_TITLE_UNDERLINES(tmpms
) = 2;
1255 case 24: /* SeparatorsLong */
1256 ST_HAS_LONG_SEPARATORS(tmpms
) = on
;
1259 case 25: /* SeparatorsShort */
1260 ST_HAS_LONG_SEPARATORS(tmpms
) = !on
;
1263 case 26: /* TrianglesSolid */
1264 ST_HAS_TRIANGLE_RELIEF(tmpms
) = !on
;
1267 case 27: /* TrianglesRelief */
1268 ST_HAS_TRIANGLE_RELIEF(tmpms
) = on
;
1271 case 28: /* PopupImmediately */
1272 ST_DO_POPUP_IMMEDIATELY(tmpms
) = on
;
1275 case 29: /* PopupDelayed */
1276 ST_DO_POPUP_IMMEDIATELY(tmpms
) = !on
;
1279 case 30: /* DoubleClickTime */
1280 if (GetIntegerArguments(args
, NULL
, val
, 1) == 0 ||
1283 ST_DOUBLE_CLICK_TIME(tmpms
) =
1284 DEFAULT_MENU_CLICKTIME
;
1288 ST_DOUBLE_CLICK_TIME(tmpms
) = *val
;
1292 case 31: /* SidePic */
1293 if (ST_SIDEPIC(tmpms
))
1295 PDestroyFvwmPicture(dpy
, ST_SIDEPIC(tmpms
));
1296 ST_SIDEPIC(tmpms
) = NULL
;
1300 fpa
.mask
= (Pdepth
<= 8)? FPAM_DITHER
:0;
1301 ST_SIDEPIC(tmpms
) = PCacheFvwmPicture(
1302 dpy
, Scr
.NoFocusWin
, NULL
, arg1
, fpa
);
1303 if (!ST_SIDEPIC(tmpms
))
1305 fvwm_msg(WARN
, "NewMenuStyle",
1306 "Couldn't find pixmap %s",
1312 case 32: /* SideColor */
1313 if (ST_HAS_SIDE_COLOR(tmpms
) == 1)
1315 fvwmlib_free_colors(
1316 dpy
, &ST_SIDE_COLOR(tmpms
), 1, True
);
1317 ST_HAS_SIDE_COLOR(tmpms
) = 0;
1321 ST_SIDE_COLOR(tmpms
) = GetColor(arg1
);
1322 ST_HAS_SIDE_COLOR(tmpms
) = 1;
1326 case 33: /* PopupAsRootmenu */
1327 ST_DO_POPUP_AS(tmpms
) = MDP_ROOT_MENU
;
1330 case 34: /* PopupAsSubmenu */
1331 ST_DO_POPUP_AS(tmpms
) = MDP_POST_MENU
;
1334 case 35: /* RemoveSubmenus */
1335 ST_DO_UNMAP_SUBMENU_ON_POPDOWN(tmpms
) = on
;
1338 case 36: /* HoldSubmenus */
1339 ST_DO_UNMAP_SUBMENU_ON_POPDOWN(tmpms
) = !on
;
1342 case 37: /* SubmenusRight */
1343 ST_USE_LEFT_SUBMENUS(tmpms
) = !on
;
1346 case 38: /* SubmenusLeft */
1347 ST_USE_LEFT_SUBMENUS(tmpms
) = on
;
1350 case 39: /* BorderWidth */
1351 if (GetIntegerArguments(args
, NULL
, val
, 1) == 0 ||
1352 *val
< 0 || *val
> MAX_MENU_BORDER_WIDTH
)
1354 ST_BORDER_WIDTH(tmpms
) =
1355 DEFAULT_MENU_BORDER_WIDTH
;
1359 ST_BORDER_WIDTH(tmpms
) = *val
;
1363 case 40: /* Hilight3DThickness */
1364 if (GetIntegerArguments(args
, NULL
, val
, 1) > 0)
1369 ST_IS_ITEM_RELIEF_REVERSED(tmpms
) = 1;
1373 ST_IS_ITEM_RELIEF_REVERSED(tmpms
) = 0;
1375 if (*val
> MAX_MENU_ITEM_RELIEF_THICKNESS
)
1376 *val
= MAX_MENU_ITEM_RELIEF_THICKNESS
;
1377 ST_RELIEF_THICKNESS(tmpms
) = *val
;
1381 case 41: /* ItemFormat */
1382 if (ST_ITEM_FORMAT(tmpms
))
1384 free(ST_ITEM_FORMAT(tmpms
));
1385 ST_ITEM_FORMAT(tmpms
) = NULL
;
1389 ST_ITEM_FORMAT(tmpms
) = safestrdup(arg1
);
1393 case 42: /* AutomaticHotkeys */
1394 ST_USE_AUTOMATIC_HOTKEYS(tmpms
) = on
;
1397 case 43: /* AutomaticHotkeysOff */
1398 ST_USE_AUTOMATIC_HOTKEYS(tmpms
) = !on
;
1401 case 44: /* VerticalItemSpacing */
1402 parse_vertical_spacing_line(
1403 args
, &ST_ITEM_GAP_ABOVE(tmpms
),
1404 &ST_ITEM_GAP_BELOW(tmpms
),
1405 DEFAULT_MENU_ITEM_TEXT_Y_OFFSET
,
1406 DEFAULT_MENU_ITEM_TEXT_Y_OFFSET2
);
1409 case 45: /* VerticalTitleSpacing */
1410 parse_vertical_spacing_line(
1411 args
, &ST_TITLE_GAP_ABOVE(tmpms
),
1412 &ST_TITLE_GAP_BELOW(tmpms
),
1413 DEFAULT_MENU_TITLE_TEXT_Y_OFFSET
,
1414 DEFAULT_MENU_TITLE_TEXT_Y_OFFSET2
);
1416 case 46: /* MenuColorset */
1417 if (GetIntegerArguments(args
, NULL
, val
, 1) == 0 ||
1420 ST_HAS_MENU_CSET(tmpms
) = 0;
1421 ST_CSET_MENU(tmpms
) = 0;
1425 ST_HAS_MENU_CSET(tmpms
) = 1;
1426 ST_CSET_MENU(tmpms
) = *val
;
1427 alloc_colorset(*val
);
1429 has_gc_changed
= True
;
1431 case 47: /* ActiveColorset */
1432 if (GetIntegerArguments(args
, NULL
, val
, 1) == 0 ||
1435 ST_HAS_ACTIVE_CSET(tmpms
) = 0;
1436 ST_CSET_ACTIVE(tmpms
) = 0;
1440 ST_HAS_ACTIVE_CSET(tmpms
) = 1;
1441 ST_CSET_ACTIVE(tmpms
) = *val
;
1442 alloc_colorset(*val
);
1444 has_gc_changed
= True
;
1447 case 48: /* GreyedColorset */
1448 if (GetIntegerArguments(args
, NULL
, val
, 1) == 0 ||
1451 ST_HAS_GREYED_CSET(tmpms
) = 0;
1452 ST_CSET_GREYED(tmpms
) = 0;
1456 ST_HAS_GREYED_CSET(tmpms
) = 1;
1457 ST_CSET_GREYED(tmpms
) = *val
;
1458 alloc_colorset(*val
);
1460 has_gc_changed
= True
;
1463 case 49: /* SelectOnRelease */
1467 keycode
= XKeysymToKeycode(
1468 dpy
, FvwmStringToKeysym(dpy
, arg1
));
1470 ST_SELECT_ON_RELEASE_KEY(tmpms
) = keycode
;
1473 case 50: /* PopdownImmediately */
1474 ST_DO_POPDOWN_IMMEDIATELY(tmpms
) = 1;
1477 case 51: /* PopdownDelayed */
1478 ST_DO_POPDOWN_IMMEDIATELY(tmpms
) = 0;
1481 case 52: /* PopdownDelay */
1482 if (GetIntegerArguments(args
, NULL
, val
, 1) == 0 ||
1485 ST_POPDOWN_DELAY(tmpms
) = DEFAULT_POPDOWN_DELAY
;
1489 ST_POPDOWN_DELAY(tmpms
) = (*val
+9)/10;
1493 case 53: /* PopupActiveArea */
1494 if (GetIntegerArguments(args
, NULL
, val
, 1) == 0 ||
1495 *val
<= 50 || *val
> 100)
1497 ST_ACTIVE_AREA_PERCENT(tmpms
) =
1498 DEFAULT_MENU_POPUP_NOW_RATIO
;
1502 ST_ACTIVE_AREA_PERCENT(tmpms
) = *val
;
1506 case 54: /* PopupIgnore */
1507 ST_DO_POPUP_AS(tmpms
) = MDP_IGNORE
;
1510 case 55: /* PopupClose */
1511 ST_DO_POPUP_AS(tmpms
) = MDP_CLOSE
;
1514 case 56: /* MouseWheel */
1517 if (StrEquals(arg1
, "ActivatesItem"))
1519 ST_MOUSE_WHEEL(tmpms
) = MMW_OFF
;
1521 else if (StrEquals(arg1
,
1522 "ScrollsMenuBackwards"))
1524 ST_MOUSE_WHEEL(tmpms
) =
1527 else if (StrEquals(arg1
, "ScrollsMenu"))
1529 ST_MOUSE_WHEEL(tmpms
) = MMW_MENU
;
1531 else if (StrEquals(arg1
, "ScrollsPointer"))
1533 ST_MOUSE_WHEEL(tmpms
) = MMW_POINTER
;
1538 ERR
, "NewMenuStyle",
1539 "unknown argument to"
1542 ST_MOUSE_WHEEL(tmpms
) = MMW_POINTER
;
1547 ST_MOUSE_WHEEL(tmpms
) =
1548 (on
) ? MMW_POINTER
: MMW_OFF
;
1551 case 57: /* ScrollOffPage */
1552 ST_SCROLL_OFF_PAGE(tmpms
) = on
;
1555 case 58: /* TrianglesUseFore */
1556 ST_TRIANGLES_USE_FORE(tmpms
) = on
;
1558 case 59: /* TitleColorset */
1559 if (GetIntegerArguments(args
, NULL
, val
, 1) == 0 ||
1562 ST_HAS_TITLE_CSET(tmpms
) = 0;
1563 ST_CSET_TITLE(tmpms
) = 0;
1567 ST_HAS_TITLE_CSET(tmpms
) = 1;
1568 ST_CSET_TITLE(tmpms
) = *val
;
1569 alloc_colorset(*val
);
1571 has_gc_changed
= True
;
1573 case 60: /* TitleHilightBack */
1574 ST_DO_HILIGHT_TITLE_BACK(tmpms
) = on
;
1575 has_gc_changed
= True
;
1577 case 61: /* TitleFont */
1579 !(new_font
= FlocaleLoadFont(dpy
, arg1
, "fvwm")))
1581 fvwm_msg(ERR
, "NewMenuStyle",
1582 "Couldn't load font '%s'\n", arg1
);
1586 ST_PTITLEFONT(tmpms
) &&
1587 !ST_USING_DEFAULT_TITLEFONT(tmpms
))
1589 FlocaleUnloadFont(dpy
, ST_PTITLEFONT(tmpms
));
1593 /* reset to screen font */
1594 ST_PTITLEFONT(tmpms
) = Scr
.DefaultFont
;
1595 ST_USING_DEFAULT_TITLEFONT(tmpms
) = True
;
1599 ST_PTITLEFONT(tmpms
) = new_font
;
1600 ST_USING_DEFAULT_TITLEFONT(tmpms
) = False
;
1602 has_gc_changed
= True
;
1604 case 62: /* VerticalMargins */
1605 parse_vertical_margins_line(
1606 args
, &ST_VERTICAL_MARGIN_TOP(tmpms
),
1607 &ST_VERTICAL_MARGIN_BOTTOM(tmpms
),
1612 case 99: /* PositionHints */
1613 /* to be implemented */
1618 fvwm_msg(ERR
, "NewMenuStyle", "unknown option '%s'",
1639 menustyle_update(tmpms
);
1642 if (default_menu_style
== NULL
)
1644 /* First MenuStyle MUST be the default style */
1645 default_menu_style
= tmpms
;
1646 ST_NEXT_STYLE(tmpms
) = NULL
;
1650 /* copy our new menu face over the old one */
1651 memcpy(ms
, tmpms
, sizeof(MenuStyle
));
1657 MenuStyle
*before
= default_menu_style
;
1659 /* add a new menu face to list */
1660 ST_NEXT_STYLE(tmpms
) = NULL
;
1661 while (ST_NEXT_STYLE(before
))
1662 before
= ST_NEXT_STYLE(before
);
1663 ST_NEXT_STYLE(before
) = tmpms
;
1669 void menustyle_copy(MenuStyle
*origms
, MenuStyle
*destms
)
1671 FvwmPictureAttributes fpa
;
1672 /* Copy origms to destms, be aware of all pointers in the MenuStyle
1673 strcture. Use the same order as in menustyle_parse_style */
1677 dpy
, &ST_MENU_COLORS(destms
).fore
,
1678 &ST_MENU_COLORS(origms
).fore
, True
, True
);
1680 dpy
, &ST_MENU_COLORS(destms
).back
,
1681 &ST_MENU_COLORS(origms
).back
, True
, True
);
1684 dpy
, &ST_MENU_STIPPLE_COLORS(destms
).fore
,
1685 &ST_MENU_STIPPLE_COLORS(origms
).fore
,
1686 ST_HAS_STIPPLE_FORE(destms
), ST_HAS_STIPPLE_FORE(origms
));
1687 ST_MENU_STIPPLE_COLORS(destms
).back
=
1688 ST_MENU_STIPPLE_COLORS(origms
).back
;
1689 ST_HAS_STIPPLE_FORE(destms
) = ST_HAS_STIPPLE_FORE(origms
);
1693 dpy
, &ST_MENU_ACTIVE_COLORS(destms
).back
,
1694 &ST_MENU_ACTIVE_COLORS(origms
).back
,
1695 ST_HAS_ACTIVE_BACK(destms
), ST_HAS_ACTIVE_BACK(origms
));
1696 ST_HAS_ACTIVE_BACK(destms
) = ST_HAS_ACTIVE_BACK(origms
);
1697 ST_DO_HILIGHT_BACK(destms
) = ST_DO_HILIGHT_BACK(origms
);
1701 dpy
, &ST_MENU_ACTIVE_COLORS(destms
).fore
,
1702 &ST_MENU_ACTIVE_COLORS(origms
).fore
,
1703 ST_HAS_ACTIVE_FORE(destms
), ST_HAS_ACTIVE_FORE(origms
));
1704 ST_HAS_ACTIVE_FORE(destms
) = ST_HAS_ACTIVE_FORE(origms
);
1705 ST_DO_HILIGHT_FORE(destms
) = ST_DO_HILIGHT_FORE(origms
);
1708 ST_RELIEF_THICKNESS(destms
) = ST_RELIEF_THICKNESS(origms
);
1710 ST_IS_ANIMATED(destms
) = ST_IS_ANIMATED(origms
);
1713 if (ST_PSTDFONT(destms
) && !ST_USING_DEFAULT_FONT(destms
))
1715 FlocaleUnloadFont(dpy
, ST_PSTDFONT(destms
));
1717 if (ST_PSTDFONT(origms
) && !ST_USING_DEFAULT_FONT(origms
))
1719 if (!(ST_PSTDFONT(destms
) =
1720 FlocaleLoadFont(dpy
, ST_PSTDFONT(origms
)->name
, "fvwm")))
1722 ST_PSTDFONT(destms
) = Scr
.DefaultFont
;
1723 ST_USING_DEFAULT_FONT(destms
) = True
;
1724 fvwm_msg(ERR
, "CopyMenuStyle",
1725 "Couldn't load font '%s' use Default Font\n",
1726 ST_PSTDFONT(origms
)->name
);
1730 ST_USING_DEFAULT_FONT(destms
) = False
;
1735 ST_USING_DEFAULT_FONT(destms
) = True
;
1736 ST_PSTDFONT(destms
) = Scr
.DefaultFont
;
1739 if (ST_PTITLEFONT(destms
) && !ST_USING_DEFAULT_TITLEFONT(destms
))
1741 FlocaleUnloadFont(dpy
, ST_PTITLEFONT(destms
));
1743 if (ST_PTITLEFONT(origms
) && !ST_USING_DEFAULT_TITLEFONT(origms
))
1746 !(ST_PTITLEFONT(destms
) = FlocaleLoadFont(
1747 dpy
, ST_PTITLEFONT(origms
)->name
, "fvwm")))
1749 ST_PTITLEFONT(destms
) = Scr
.DefaultFont
;
1750 ST_USING_DEFAULT_TITLEFONT(destms
) = True
;
1751 fvwm_msg(ERR
, "CopyMenuStyle",
1752 "Couldn't load font '%s' use Default Font\n",
1753 ST_PTITLEFONT(origms
)->name
);
1757 ST_USING_DEFAULT_TITLEFONT(destms
) = False
;
1762 ST_USING_DEFAULT_TITLEFONT(destms
) = True
;
1763 ST_PTITLEFONT(destms
) = Scr
.DefaultFont
;
1766 menustyle_copy_face(&ST_FACE(destms
), &ST_FACE(origms
));
1769 ST_POPUP_DELAY(destms
) = ST_POPUP_DELAY(origms
);
1771 ST_POPUP_OFFSET_PERCENT(destms
) = ST_POPUP_OFFSET_PERCENT(origms
);
1772 ST_POPUP_OFFSET_ADD(destms
) = ST_POPUP_OFFSET_ADD(origms
);
1774 ST_DO_WARP_TO_TITLE(destms
) = ST_DO_WARP_TO_TITLE(origms
);
1775 /* TitleUnderlines */
1776 ST_TITLE_UNDERLINES(destms
) = ST_TITLE_UNDERLINES(origms
);
1778 ST_HAS_LONG_SEPARATORS(destms
) = ST_HAS_LONG_SEPARATORS(origms
);
1780 ST_HAS_TRIANGLE_RELIEF(destms
) = ST_HAS_TRIANGLE_RELIEF(origms
);
1782 ST_DO_POPUP_IMMEDIATELY(destms
) = ST_DO_POPUP_IMMEDIATELY(origms
);
1783 /* DoubleClickTime */
1784 ST_DOUBLE_CLICK_TIME(destms
) = ST_DOUBLE_CLICK_TIME(origms
);
1785 /* VerticalMargins */
1786 ST_VERTICAL_MARGIN_TOP(destms
) = ST_VERTICAL_MARGIN_TOP(origms
);
1787 ST_VERTICAL_MARGIN_BOTTOM(destms
) = ST_VERTICAL_MARGIN_BOTTOM(origms
);
1790 if (ST_SIDEPIC(destms
))
1792 PDestroyFvwmPicture(dpy
, ST_SIDEPIC(destms
));
1793 ST_SIDEPIC(destms
) = NULL
;
1795 if (ST_SIDEPIC(origms
))
1797 fpa
.mask
= (Pdepth
<= 8)? FPAM_DITHER
:0;
1798 ST_SIDEPIC(destms
) = PCacheFvwmPicture(
1799 dpy
, Scr
.NoFocusWin
, NULL
, ST_SIDEPIC(origms
)->name
,
1805 dpy
, &ST_SIDE_COLOR(destms
), &ST_SIDE_COLOR(origms
),
1806 ST_HAS_SIDE_COLOR(destms
), ST_HAS_SIDE_COLOR(origms
));
1807 ST_HAS_SIDE_COLOR(destms
) = ST_HAS_SIDE_COLOR(origms
);
1809 /* PopupAsRootmenu */
1810 ST_DO_POPUP_AS(destms
) = ST_DO_POPUP_AS(origms
);
1811 /* RemoveSubmenus */
1812 ST_DO_UNMAP_SUBMENU_ON_POPDOWN(destms
) =
1813 ST_DO_UNMAP_SUBMENU_ON_POPDOWN(origms
);
1815 ST_USE_LEFT_SUBMENUS(destms
) = ST_USE_LEFT_SUBMENUS(origms
);
1817 ST_BORDER_WIDTH(destms
) = ST_BORDER_WIDTH(origms
);
1818 /* Hilight3DThickness */
1819 ST_IS_ITEM_RELIEF_REVERSED(destms
) =
1820 ST_IS_ITEM_RELIEF_REVERSED(origms
);
1823 if (ST_ITEM_FORMAT(destms
))
1825 free(ST_ITEM_FORMAT(destms
));
1826 ST_ITEM_FORMAT(destms
) = NULL
;
1828 if (ST_ITEM_FORMAT(origms
))
1830 ST_ITEM_FORMAT(destms
) = safestrdup(ST_ITEM_FORMAT(origms
));
1833 /* AutomaticHotkeys */
1834 ST_USE_AUTOMATIC_HOTKEYS(destms
) = ST_USE_AUTOMATIC_HOTKEYS(origms
);
1835 /* Item and Title Spacing */
1836 ST_ITEM_GAP_ABOVE(destms
) = ST_ITEM_GAP_ABOVE(origms
);
1837 ST_ITEM_GAP_BELOW(destms
) = ST_ITEM_GAP_BELOW(origms
);
1838 ST_TITLE_GAP_ABOVE(destms
) = ST_TITLE_GAP_ABOVE(origms
);
1839 ST_TITLE_GAP_BELOW(destms
) = ST_TITLE_GAP_BELOW(origms
);
1841 ST_HAS_MENU_CSET(destms
) = ST_HAS_MENU_CSET(origms
);
1842 ST_CSET_MENU(destms
) = ST_CSET_MENU(origms
);
1843 /* ActiveColorset */
1844 ST_HAS_ACTIVE_CSET(destms
) = ST_HAS_ACTIVE_CSET(origms
);
1845 ST_CSET_ACTIVE(destms
) = ST_CSET_ACTIVE(origms
);
1847 ST_HAS_GREYED_CSET(destms
) = ST_HAS_GREYED_CSET(origms
);
1848 ST_CSET_GREYED(destms
) = ST_CSET_GREYED(origms
);
1850 ST_HAS_TITLE_CSET(destms
) = ST_HAS_TITLE_CSET(origms
);
1851 ST_CSET_TITLE(destms
) = ST_CSET_TITLE(origms
);
1852 /* SelectOnRelease */
1853 ST_SELECT_ON_RELEASE_KEY(destms
) = ST_SELECT_ON_RELEASE_KEY(origms
);
1854 /* PopdownImmediately */
1855 ST_DO_POPDOWN_IMMEDIATELY(destms
) = ST_DO_POPDOWN_IMMEDIATELY(origms
);
1857 ST_POPDOWN_DELAY(destms
) = ST_POPDOWN_DELAY(origms
);
1859 ST_MOUSE_WHEEL(destms
) = ST_MOUSE_WHEEL(origms
);
1861 ST_SCROLL_OFF_PAGE(destms
) = ST_SCROLL_OFF_PAGE(origms
);
1862 /* TrianglesUseFore */
1863 ST_TRIANGLES_USE_FORE(destms
) = ST_TRIANGLES_USE_FORE(origms
);
1865 ST_DO_HILIGHT_TITLE_BACK(destms
) = ST_DO_HILIGHT_TITLE_BACK(origms
);
1867 menustyle_update(destms
);
1872 /* ---------------------------- builtin commands --------------------------- */
1874 void CMD_CopyMenuStyle(F_CMD_ARGS
)
1876 char *origname
= NULL
;
1877 char *destname
= NULL
;
1882 origname
= PeekToken(action
, &action
);
1883 if (origname
== NULL
)
1885 fvwm_msg(ERR
,"CopyMenuStyle", "need two arguments");
1889 origms
= menustyle_find(origname
);
1892 fvwm_msg(ERR
, "CopyMenuStyle", "%s: no such menu style",
1897 destname
= PeekToken(action
, &action
);
1898 if (destname
== NULL
)
1900 fvwm_msg(ERR
,"CopyMenuStyle", "need two arguments");
1904 if (action
&& *action
)
1906 fvwm_msg(ERR
,"CopyMenuStyle", "too many arguments");
1910 destms
= menustyle_find(destname
);
1913 /* create destms menu style */
1914 buffer
= (char *)safemalloc(strlen(destname
) + 3);
1915 sprintf(buffer
,"\"%s\"",destname
);
1917 destms
= menustyle_parse_style(F_PASS_ARGS
);
1921 /* this must never happen */
1922 fvwm_msg(ERR
, "CopyMenuStyle",
1923 "impossible to create %s menu style",
1929 if (strcasecmp("*",destname
) == 0)
1931 fvwm_msg(ERR
, "CopyMenuStyle",
1932 "You cannot copy on the default menu style");
1935 if (strcasecmp(ST_NAME(origms
),destname
) == 0)
1937 fvwm_msg(ERR
, "CopyMenuStyle",
1938 "%s and %s identify the same menu style",
1939 ST_NAME(origms
),destname
);
1943 if (ST_USAGE_COUNT(destms
) != 0)
1945 fvwm_msg(ERR
, "CopyMenuStyle", "menu style %s is in use",
1950 menustyle_copy(origms
, destms
);
1955 void CMD_MenuStyle(F_CMD_ARGS
)
1961 GetNextSimpleOption(SkipNTokens(action
, 1), &option
);
1963 while (poption
&& poption
[0] == '!')
1967 if (option
== NULL
|| menustyle_get_styleopt_index(poption
) != -1)
1969 dummy
= menustyle_parse_style(F_PASS_ARGS
);
1973 dummy
= menustyle_parse_old_style(F_PASS_ARGS
);