/* -*-c-*- */ /* This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* ---------------------------- included header files ---------------------- */ #include "config.h" #include #include #include #include "libs/fvwmlib.h" #include "libs/Parse.h" #include "libs/ColorUtils.h" #include "libs/Picture.h" #include "libs/PictureUtils.h" #include "libs/Graphics.h" #include "fvwm.h" #include "externs.h" #include "execcontext.h" #include "functions.h" #include "misc.h" #include "screen.h" #include "colorset.h" #include "menustyle.h" /* ---------------------------- local definitions -------------------------- */ /* ---------------------------- local macros ------------------------------- */ /* ---------------------------- imports ------------------------------------ */ /* ---------------------------- included code files ------------------------ */ /* ---------------------------- local types -------------------------------- */ /* ---------------------------- forward declarations ----------------------- */ /* ---------------------------- local variables ---------------------------- */ static MenuStyle *default_menu_style; /* ---------------------------- exported variables (globals) --------------- */ /* ---------------------------- local functions ---------------------------- */ static void menustyle_free_face(MenuFace *mf) { switch (mf->type) { case GradientMenu: if (Pdepth <= 8 && mf->u.grad.npixels > 0 && !mf->u.grad.do_dither) { Pixel *p; int i; p = (Pixel *)safemalloc( mf->u.grad.npixels * sizeof(Pixel)); for(i=0; i < mf->u.grad.npixels; i++) { p[i] = mf->u.grad.xcs[i].pixel; } PictureFreeColors( dpy, Pcmap, p, mf->u.grad.npixels, 0, False); free(p); } free(mf->u.grad.xcs); mf->u.grad.xcs = NULL; break; case PixmapMenu: case TiledPixmapMenu: if (mf->u.p) { PDestroyFvwmPicture(dpy, mf->u.p); } mf->u.p = NULL; break; case SolidMenu: fvwmlib_free_colors(dpy, &mf->u.back, 1, True); default: break; } mf->type = SimpleMenu; return; } static void menustyle_copy_face(MenuFace *destmf, MenuFace *origmf) { FvwmPictureAttributes fpa; int i; menustyle_free_face(destmf); destmf->type = SimpleMenu; switch (origmf->type) { case SolidMenu: fvwmlib_copy_color( dpy, &destmf->u.back, &origmf->u.back, False, True); destmf->type = SolidMenu; break; case GradientMenu: destmf->u.grad.xcs = (XColor *)safemalloc(sizeof(XColor) * origmf->u.grad.npixels); memcpy(destmf->u.grad.xcs, origmf->u.grad.xcs, sizeof(XColor) * origmf->u.grad.npixels); for (i = 0; iu.grad.npixels;i++) { fvwmlib_clone_color(origmf->u.grad.xcs[i].pixel); } destmf->u.grad.npixels = origmf->u.grad.npixels; destmf->u.grad.do_dither = origmf->u.grad.do_dither; destmf->type = GradientMenu; destmf->gradient_type = origmf->gradient_type; break; case PixmapMenu: case TiledPixmapMenu: fpa.mask = (Pdepth <= 8)? FPAM_DITHER:0; if (destmf->u.p) destmf->u.p = NULL; if (origmf->u.p) destmf->u.p = PCacheFvwmPicture( dpy, Scr.NoFocusWin, NULL, origmf->u.p->name, fpa); destmf->type = origmf->type; break; default: break; } } /* * * Reads a menu face line into a structure (veliaa@rpi.edu) * */ static Boolean menustyle_parse_face(char *s, MenuFace *mf, int verbose) { char *style; char *token; char *action = s; FvwmPictureAttributes fpa; s = GetNextToken(s, &style); if (style && strncasecmp(style, "--", 2) == 0) { free(style); return True; } menustyle_free_face(mf); mf->type = SimpleMenu; /* determine menu style */ if (!style) { return True; } else if (StrEquals(style,"Solid")) { s = GetNextToken(s, &token); if (token) { mf->type = SolidMenu; mf->u.back = GetColor(token); free(token); } else { if (verbose) { fvwm_msg(ERR, "menustyle_parse_face", "no color given for Solid face type:" " %s", action); } free(style); return False; } } else if (StrEquals(style+1, "Gradient")) { char **s_colors; int npixels, nsegs, *perc; XColor *xcs; if (!IsGradientTypeSupported(style[0])) { return False; } /* translate the gradient string into an array of colors etc */ npixels = ParseGradient(s, NULL, &s_colors, &perc, &nsegs); if (npixels <= 0) { return False; } /* dither ? */ mf->u.grad.do_dither = False; if (Pdepth <= 8) { mf->u.grad.do_dither = True; } /* grab the colors */ xcs = AllocAllGradientColors( s_colors, perc, nsegs, npixels, mf->u.grad.do_dither); if (xcs == None) { return False; } mf->u.grad.xcs = xcs; mf->u.grad.npixels = npixels; mf->type = GradientMenu; mf->gradient_type = toupper(style[0]); } else if (StrEquals(style,"Pixmap") || StrEquals(style,"TiledPixmap")) { s = GetNextToken(s, &token); fpa.mask = (Pdepth <= 8)? FPAM_DITHER:0; if (token) { mf->u.p = PCacheFvwmPicture( dpy, Scr.NoFocusWin, NULL, token, fpa); if (mf->u.p == NULL) { if (verbose) { fvwm_msg(ERR, "menustyle_parse_face", "couldn't load pixmap %s", token); } free(token); free(style); return False; } free(token); mf->type = (StrEquals(style,"TiledPixmap")) ? TiledPixmapMenu : PixmapMenu; } else { if (verbose) { fvwm_msg(ERR, "menustyle_parse_face", "missing pixmap name for style %s", style); } free(style); return False; } } else { if (verbose) { fvwm_msg( ERR, "menustyle_parse_face", "unknown style %s: %s", style, action); } free(style); return False; } free(style); return True; } static void parse_vertical_spacing_line( char *args, signed char *above, signed char *below, signed char above_default, signed char below_default) { int val[2]; if (GetIntegerArguments(args, NULL, val, 2) != 2 || val[0] < MIN_VERTICAL_SPACING || val[0] > MAX_VERTICAL_SPACING || val[1] < MIN_VERTICAL_SPACING || val[1] > MAX_VERTICAL_SPACING) { /* illegal or missing parameters, return to default */ *above = above_default; *below = below_default; return; } *above = val[0]; *below = val[1]; return; } static void parse_vertical_margins_line( char *args, unsigned char *top, unsigned char *bottom, signed char top_default, signed char bottom_default) { int val[2]; if (GetIntegerArguments(args, NULL, val, 2) != 2 || val[0] < 0 || val[0] > MAX_MENU_MARGIN || val[1] < 0 || val[1] > MAX_MENU_MARGIN) { /* invalid or missing parameters, return to default */ *top = top_default; *bottom = bottom_default; return; } *top = val[0]; *bottom = val[1]; return; } static MenuStyle *menustyle_parse_old_style(F_CMD_ARGS) { char *buffer, *rest; char *fore, *back, *stipple, *font, *style, *animated; MenuStyle *ms = NULL; rest = GetNextToken(action,&fore); rest = GetNextToken(rest,&back); rest = GetNextToken(rest,&stipple); rest = GetNextToken(rest,&font); rest = GetNextToken(rest,&style); rest = GetNextToken(rest,&animated); if (!fore || !back || !stipple || !font || !style) { fvwm_msg(ERR, "menustyle_parse_old_style", "error in %s style specification", action); } else { buffer = (char *)alloca(strlen(action) + 100); sprintf(buffer, "* \"%s\", Foreground \"%s\", Background \"%s\", " "Greyed \"%s\", Font \"%s\", \"%s\"", style, fore, back, stipple, font, (animated && StrEquals(animated, "anim")) ? "Animation" : "AnimationOff"); fvwm_msg(OLD, "menustyle_parse_old_style", "The old MenuStyle snytax has been deprecated. " "Use 'MenuStyle %s' instead of 'MenuStyle %s'\n", buffer, action); action = buffer; ms = menustyle_parse_style(F_PASS_ARGS); } if (fore) { free(fore); } if (back) { free(back); } if (stipple) { free(stipple); } if (font) { free(font); } if (style) { free(style); } if (animated) { free(animated); } return ms; } static int menustyle_get_styleopt_index(char *option) { char *optlist[] = { "fvwm", "mwm", "win", "Foreground", "Background", "Greyed", "HilightBack", "HilightBackOff", "ActiveFore", "ActiveForeOff", "Hilight3DThick", "Hilight3DThin", "Hilight3DOff", "Animation", "AnimationOff", "Font", "MenuFace", "PopupDelay", "PopupOffset", "TitleWarp", "TitleWarpOff", "TitleUnderlines0", "TitleUnderlines1", "TitleUnderlines2", "SeparatorsLong", "SeparatorsShort", "TrianglesSolid", "TrianglesRelief", "PopupImmediately", "PopupDelayed", "DoubleClickTime", "SidePic", "SideColor", "PopupAsRootmenu", "PopupAsSubmenu", "RemoveSubmenus", "HoldSubmenus", "SubmenusRight", "SubmenusLeft", "BorderWidth", "Hilight3DThickness", "ItemFormat", "AutomaticHotkeys", "AutomaticHotkeysOff", "VerticalItemSpacing", "VerticalTitleSpacing", "MenuColorset", "ActiveColorset", "GreyedColorset", "SelectOnRelease", "PopdownImmediately", "PopdownDelayed", "PopdownDelay", "PopupActiveArea", "PopupIgnore", "PopupClose", "MouseWheel", "ScrollOffPage", "TrianglesUseFore", "TitleColorset", "HilightTitleBack", "TitleFont", "VerticalMargins", NULL }; return GetTokenIndex(option, optlist, 0, NULL); } static void change_or_make_gc(GC *gc, unsigned long gcm, XGCValues *gcv) { if (*gc != None) { XChangeGC(dpy, *gc, gcm, gcv); } else { *gc = fvwmlib_XCreateGC(dpy, Scr.NoFocusWin, gcm, gcv); } return; } /* ---------------------------- interface functions ------------------------ */ MenuStyle *menustyle_get_default_style(void) { return default_menu_style; } void menustyle_free(MenuStyle *ms) { MenuStyle *before = default_menu_style; if (!ms) { return; } menustyle_free_face(&ST_FACE(ms)); if (FORE_GC(ST_MENU_INACTIVE_GCS(ms))) { XFreeGC(dpy, FORE_GC(ST_MENU_INACTIVE_GCS(ms))); } if (FORE_GC(ST_MENU_ACTIVE_GCS(ms))) { XFreeGC(dpy, FORE_GC(ST_MENU_ACTIVE_GCS(ms))); } if (BACK_GC(ST_MENU_ACTIVE_GCS(ms))) { XFreeGC(dpy, BACK_GC(ST_MENU_ACTIVE_GCS(ms))); } if (HILIGHT_GC(ST_MENU_ACTIVE_GCS(ms))) { XFreeGC(dpy, HILIGHT_GC(ST_MENU_ACTIVE_GCS(ms))); } if (SHADOW_GC(ST_MENU_ACTIVE_GCS(ms))) { XFreeGC(dpy, SHADOW_GC(ST_MENU_ACTIVE_GCS(ms))); } if (HILIGHT_GC(ST_MENU_INACTIVE_GCS(ms))) { XFreeGC(dpy, HILIGHT_GC(ST_MENU_INACTIVE_GCS(ms))); } if (SHADOW_GC(ST_MENU_INACTIVE_GCS(ms))) { XFreeGC(dpy, SHADOW_GC(ST_MENU_INACTIVE_GCS(ms))); } if (FORE_GC(ST_MENU_STIPPLE_GCS(ms))) { XFreeGC(dpy, FORE_GC(ST_MENU_STIPPLE_GCS(ms))); } if (FORE_GC(ST_MENU_TITLE_GCS(ms))) { XFreeGC(dpy, FORE_GC(ST_MENU_TITLE_GCS(ms))); } if (BACK_GC(ST_MENU_TITLE_GCS(ms))) { XFreeGC(dpy, BACK_GC(ST_MENU_TITLE_GCS(ms))); } if (HILIGHT_GC(ST_MENU_TITLE_GCS(ms))) { XFreeGC(dpy, HILIGHT_GC(ST_MENU_TITLE_GCS(ms))); } if (SHADOW_GC(ST_MENU_TITLE_GCS(ms))) { XFreeGC(dpy, SHADOW_GC(ST_MENU_TITLE_GCS(ms))); } if (ST_SIDEPIC(ms)) { PDestroyFvwmPicture(dpy, ST_SIDEPIC(ms)); } if (ST_HAS_SIDE_COLOR(ms) == 1) { fvwmlib_free_colors(dpy, &ST_SIDE_COLOR(ms), 1, True); } if (ST_PSTDFONT(ms) && !ST_USING_DEFAULT_FONT(ms)) { FlocaleUnloadFont(dpy, ST_PSTDFONT(ms)); } if (ST_PTITLEFONT(ms) && !ST_USING_DEFAULT_TITLEFONT(ms)) { FlocaleUnloadFont(dpy, ST_PTITLEFONT(ms)); } if (ST_ITEM_FORMAT(ms)) { free(ST_ITEM_FORMAT(ms)); } fvwmlib_free_colors(dpy, &ST_MENU_COLORS(ms).back,1,True); fvwmlib_free_colors(dpy, &ST_MENU_COLORS(ms).fore,1,True); if (ST_HAS_STIPPLE_FORE(ms)) { fvwmlib_free_colors( dpy, &ST_MENU_STIPPLE_COLORS(ms).fore,1,True); } if (ST_HAS_ACTIVE_BACK(ms)) { fvwmlib_free_colors( dpy, &ST_MENU_ACTIVE_COLORS(ms).back,1,True); } if (ST_HAS_ACTIVE_FORE(ms)) { fvwmlib_free_colors( dpy, &ST_MENU_ACTIVE_COLORS(ms).fore,1,True); } while (ST_NEXT_STYLE(before) != ms) { /* Not too many checks, may segfault in race conditions */ before = ST_NEXT_STYLE(before); } ST_NEXT_STYLE(before) = ST_NEXT_STYLE(ms); free(ST_NAME(ms)); free(ms); return; } MenuStyle *menustyle_find(char *name) { MenuStyle *ms = default_menu_style; while (ms) { if (strcasecmp(ST_NAME(ms),name)==0) { return ms; } ms = ST_NEXT_STYLE(ms); } return NULL; } void menustyle_update(MenuStyle *ms) { XGCValues gcv; unsigned long gcm; color_quad c_inactive; color_quad c_active; color_quad c_stipple; color_quad c_title; colorset_t *menu_cs = &Colorset[ST_CSET_MENU(ms)]; colorset_t *active_cs = &Colorset[ST_CSET_ACTIVE(ms)]; colorset_t *greyed_cs = &Colorset[ST_CSET_GREYED(ms)]; colorset_t *title_cs = &Colorset[ST_CSET_TITLE(ms)]; if (ST_USAGE_COUNT(ms) != 0) { fvwm_msg(ERR,"menustyle_update", "menu style %s is in use", ST_NAME(ms)); return; } ST_IS_UPDATED(ms) = 1; if (ST_USING_DEFAULT_FONT(ms)) { ST_PSTDFONT(ms) = Scr.DefaultFont; } if (ST_USING_DEFAULT_TITLEFONT(ms)) { ST_PTITLEFONT(ms) = ST_PSTDFONT(ms); } /* calculate colors based on foreground */ if (!ST_HAS_ACTIVE_FORE(ms)) { ST_MENU_ACTIVE_COLORS(ms).fore = ST_MENU_COLORS(ms).fore; } /* calculate colors based on background */ if (!ST_HAS_ACTIVE_BACK(ms)) { ST_MENU_ACTIVE_COLORS(ms).back = ST_MENU_COLORS(ms).back; } if (!ST_HAS_STIPPLE_FORE(ms)) { ST_MENU_STIPPLE_COLORS(ms).fore = ST_MENU_COLORS(ms).back; } ST_MENU_STIPPLE_COLORS(ms).back = ST_MENU_COLORS(ms).back; /* prepare colours for changing the gcs */ if (ST_HAS_MENU_CSET(ms)) { c_inactive.fore = menu_cs->fg; c_inactive.back = menu_cs->bg; c_inactive.hilight = menu_cs->hilite; c_inactive.shadow = menu_cs->shadow; } else { c_inactive.fore = ST_MENU_COLORS(ms).fore; c_inactive.back = ST_MENU_COLORS(ms).back; if (Pdepth > 2) { c_inactive.hilight = GetHilite(ST_MENU_COLORS(ms).back); c_inactive.shadow = GetShadow(ST_MENU_COLORS(ms).back); } else { c_inactive.hilight = GetColor(DEFAULT_HILIGHT_COLOR); c_inactive.shadow = GetColor(DEFAULT_SHADOW_COLOR); } } if (ST_HAS_ACTIVE_CSET(ms)) { c_active.fore = active_cs->fg; c_active.back = active_cs->bg; c_active.hilight = active_cs->hilite; c_active.shadow = active_cs->shadow; } else { c_active.fore = ST_MENU_ACTIVE_COLORS(ms).fore; c_active.back = ST_MENU_ACTIVE_COLORS(ms).back; if (Pdepth > 2) { c_active.hilight = GetHilite(ST_MENU_ACTIVE_COLORS(ms).back); c_active.shadow = GetShadow(ST_MENU_ACTIVE_COLORS(ms).back); } else { c_active.hilight = GetColor(DEFAULT_HILIGHT_COLOR); c_active.shadow = GetColor(DEFAULT_SHADOW_COLOR); } } if (ST_HAS_GREYED_CSET(ms)) { c_stipple.fore = greyed_cs->fg; c_stipple.back = greyed_cs->fg; } else { c_stipple.fore = ST_MENU_STIPPLE_COLORS(ms).fore; c_stipple.back = ST_MENU_STIPPLE_COLORS(ms).back; } if (ST_HAS_TITLE_CSET(ms)) { c_title.fore = title_cs->fg; c_title.back = title_cs->bg; c_title.hilight = title_cs->hilite; c_title.shadow = title_cs->shadow; } else { c_title.fore = c_inactive.fore; c_title.back = c_inactive.back; c_title.hilight = c_inactive.hilight; c_title.shadow = c_inactive.shadow; } /* override hilighting colours if necessary */ if (!ST_DO_HILIGHT_FORE(ms)) { c_active.fore = c_inactive.fore; } if (!ST_DO_HILIGHT_BACK(ms)) { c_active.back = c_inactive.back; c_active.hilight = c_inactive.hilight; c_active.shadow = c_inactive.shadow; } if (!ST_DO_HILIGHT_TITLE_BACK(ms)) { c_title.fore = c_inactive.fore; c_title.back = c_inactive.back; c_title.hilight = c_inactive.hilight; c_title.shadow = c_inactive.shadow; } /* make GC's */ gcm = GCFunction|GCLineWidth|GCForeground|GCBackground; if (ST_PSTDFONT(ms)->font != NULL) { gcm |= GCFont; gcv.font = ST_PSTDFONT(ms)->font->fid; } gcv.function = GXcopy; gcv.line_width = 0; /* update inactive menu gcs */ gcv.foreground = c_inactive.fore; gcv.background = c_inactive.back; change_or_make_gc(&FORE_GC(ST_MENU_INACTIVE_GCS(ms)), gcm, &gcv); BACK_GC(ST_MENU_INACTIVE_GCS(ms)) = FORE_GC(ST_MENU_INACTIVE_GCS(ms)); gcv.foreground = c_inactive.hilight; gcv.background = c_inactive.shadow; change_or_make_gc(&HILIGHT_GC(ST_MENU_INACTIVE_GCS(ms)), gcm, &gcv); gcv.foreground = c_inactive.shadow; gcv.background = c_inactive.hilight; change_or_make_gc(&SHADOW_GC(ST_MENU_INACTIVE_GCS(ms)), gcm, &gcv); /* update active menu gcs */ gcv.foreground = c_active.fore; gcv.background = c_active.back; change_or_make_gc(&FORE_GC(ST_MENU_ACTIVE_GCS(ms)), gcm, &gcv); gcv.foreground = c_active.back; gcv.background = c_active.fore; if (ST_HAS_ACTIVE_CSET(ms) && active_cs->pixmap && active_cs->pixmap_type == PIXMAP_TILED) { gcv.tile = active_cs->pixmap; gcv.fill_style = FillTiled; change_or_make_gc(&BACK_GC(ST_MENU_ACTIVE_GCS(ms)), gcm | GCFillStyle | GCTile , &gcv); } else { gcv.fill_style = FillSolid; change_or_make_gc(&BACK_GC(ST_MENU_ACTIVE_GCS(ms)), gcm | GCFillStyle , &gcv); } gcv.foreground = c_active.hilight; gcv.background = c_active.shadow; change_or_make_gc(&HILIGHT_GC(ST_MENU_ACTIVE_GCS(ms)), gcm, &gcv); gcv.foreground = c_active.shadow; gcv.background = c_active.hilight; change_or_make_gc(&SHADOW_GC(ST_MENU_ACTIVE_GCS(ms)), gcm, &gcv); /* update title gcs */ if (ST_PTITLEFONT(ms)->font != NULL && ST_PSTDFONT(ms)->font == NULL) { if (ST_PSTDFONT(ms)->font == NULL) { gcm |= GCFont; } gcv.font = ST_PTITLEFONT(ms)->font->fid; } gcv.foreground = c_title.fore; gcv.background = c_title.back; change_or_make_gc(&FORE_GC(ST_MENU_TITLE_GCS(ms)), gcm, &gcv); gcv.foreground = c_title.back; gcv.background = c_title.fore; if (ST_HAS_TITLE_CSET(ms) && title_cs->pixmap && title_cs->pixmap_type == PIXMAP_TILED) { gcv.tile = title_cs->pixmap; gcv.fill_style = FillTiled; change_or_make_gc(&BACK_GC(ST_MENU_TITLE_GCS(ms)), gcm | GCFillStyle | GCTile , &gcv); } else { gcv.fill_style = FillSolid; change_or_make_gc(&BACK_GC(ST_MENU_TITLE_GCS(ms)), gcm | GCFillStyle , &gcv); } gcv.foreground = c_title.hilight; gcv.background = c_title.shadow; change_or_make_gc(&HILIGHT_GC(ST_MENU_TITLE_GCS(ms)), gcm, &gcv); gcv.foreground = c_title.shadow; gcv.background = c_title.hilight; change_or_make_gc(&SHADOW_GC(ST_MENU_TITLE_GCS(ms)), gcm, &gcv); /* update stipple menu gcs */ SHADOW_GC(ST_MENU_STIPPLE_GCS(ms)) = SHADOW_GC(ST_MENU_INACTIVE_GCS(ms)); if (Pdepth < 2) { gcv.fill_style = FillStippled; gcv.stipple = Scr.gray_bitmap; /* no need to reset fg/bg, FillStipple wins */ gcm |= GCStipple | GCFillStyle; HILIGHT_GC(ST_MENU_STIPPLE_GCS(ms)) = SHADOW_GC(ST_MENU_INACTIVE_GCS(ms)); } else { gcv.foreground = c_stipple.fore; gcv.background = c_stipple.back; HILIGHT_GC(ST_MENU_STIPPLE_GCS(ms)) = HILIGHT_GC(ST_MENU_INACTIVE_GCS(ms)); } change_or_make_gc(&FORE_GC(ST_MENU_STIPPLE_GCS(ms)), gcm, &gcv); BACK_GC(ST_MENU_STIPPLE_GCS(ms)) = BACK_GC(ST_MENU_INACTIVE_GCS(ms)); return; } MenuStyle *menustyle_parse_style(F_CMD_ARGS) { char *name; char *option = NULL; char *poption = NULL; char *optstring = NULL; char *nextarg; char *args = NULL; char *arg1; int on; MenuStyle *ms; MenuStyle *tmpms; Bool is_initialised = True; Bool has_gc_changed = False; Bool is_default_style = False; int val[2]; int n; FlocaleFont *new_font = NULL; int i; KeyCode keycode; FvwmPictureAttributes fpa; action = GetNextToken(action, &name); if (!name) { fvwm_msg(ERR, "NewMenuStyle", "error in %s style specification",action); return NULL; } ms = menustyle_find(name); if (ms && ST_USAGE_COUNT(ms) != 0) { fvwm_msg(ERR,"NewMenuStyle", "menu style %s is in use", name); return ms; } tmpms = (MenuStyle *)safemalloc(sizeof(MenuStyle)); if (ms) { /* copy the structure over our temporary menu face. */ memcpy(tmpms, ms, sizeof(MenuStyle)); if (ms == default_menu_style) { is_default_style = True; } free(name); } else { memset(tmpms, 0, sizeof(MenuStyle)); ST_NAME(tmpms) = name; is_initialised = False; } ST_IS_UPDATED(tmpms) = 1; /* Parse the options. */ while (!is_initialised || (action && *action)) { on = 1; if (!is_initialised) { /* some default configuration goes here for the new * menu style */ ST_MENU_COLORS(tmpms).back = GetColor(DEFAULT_BACK_COLOR); ST_MENU_COLORS(tmpms).fore = GetColor(DEFAULT_FORE_COLOR); ST_PSTDFONT(tmpms) = Scr.DefaultFont; ST_USING_DEFAULT_FONT(tmpms) = True; ST_FACE(tmpms).type = SimpleMenu; ST_HAS_ACTIVE_FORE(tmpms) = 0; ST_HAS_ACTIVE_BACK(tmpms) = 0; ST_DO_POPUP_AS(tmpms) = MDP_POST_MENU; ST_DOUBLE_CLICK_TIME(tmpms) = DEFAULT_MENU_CLICKTIME; ST_POPUP_DELAY(tmpms) = DEFAULT_POPUP_DELAY; ST_POPDOWN_DELAY(tmpms) = DEFAULT_POPDOWN_DELAY; ST_MOUSE_WHEEL(tmpms) = MMW_POINTER; ST_SCROLL_OFF_PAGE(tmpms) = 1; ST_DO_HILIGHT_TITLE_BACK(tmpms) = 0; ST_USING_DEFAULT_TITLEFONT(tmpms) = True; has_gc_changed = True; option = "fvwm"; } else { /* Read next option specification (delimited by a comma * or \0). */ args = action; action = GetQuotedString( action, &optstring, ",", NULL, NULL, NULL); if (!optstring) { break; } args = GetNextToken(optstring, &option); if (!option) { free(optstring); break; } nextarg = GetNextToken(args, &arg1); } poption = option; while (poption[0] == '!') { on ^= 1; poption++; } switch((i = menustyle_get_styleopt_index(poption))) { case 0: /* fvwm */ case 1: /* mwm */ case 2: /* win */ if (i == 0) { ST_POPUP_OFFSET_PERCENT(tmpms) = 67; ST_POPUP_OFFSET_ADD(tmpms) = 0; ST_DO_POPUP_IMMEDIATELY(tmpms) = 0; ST_DO_WARP_TO_TITLE(tmpms) = 1; ST_DO_UNMAP_SUBMENU_ON_POPDOWN(tmpms) = 0; ST_RELIEF_THICKNESS(tmpms) = 1; ST_TITLE_UNDERLINES(tmpms) = 1; ST_HAS_LONG_SEPARATORS(tmpms) = 0; ST_HAS_TRIANGLE_RELIEF(tmpms) = 1; ST_DO_HILIGHT_BACK(tmpms) = 0; ST_DO_HILIGHT_FORE(tmpms) = 0; } else if (i == 1) { ST_POPUP_OFFSET_PERCENT(tmpms) = 100; ST_POPUP_OFFSET_ADD(tmpms) = -DEFAULT_MENU_BORDER_WIDTH - 1; ST_DO_POPUP_IMMEDIATELY(tmpms) = 1; ST_DO_WARP_TO_TITLE(tmpms) = 0; ST_DO_UNMAP_SUBMENU_ON_POPDOWN(tmpms) = 0; ST_RELIEF_THICKNESS(tmpms) = 2; ST_TITLE_UNDERLINES(tmpms) = 2; ST_HAS_LONG_SEPARATORS(tmpms) = 1; ST_HAS_TRIANGLE_RELIEF(tmpms) = 1; ST_DO_HILIGHT_BACK(tmpms) = 0; ST_DO_HILIGHT_FORE(tmpms) = 0; } else /* i == 2 */ { ST_POPUP_OFFSET_PERCENT(tmpms) = 100; ST_POPUP_OFFSET_ADD(tmpms) = -DEFAULT_MENU_BORDER_WIDTH - 3; ST_DO_POPUP_IMMEDIATELY(tmpms) = 1; ST_DO_WARP_TO_TITLE(tmpms) = 0; ST_DO_UNMAP_SUBMENU_ON_POPDOWN(tmpms) = 1; ST_RELIEF_THICKNESS(tmpms) = 0; ST_TITLE_UNDERLINES(tmpms) = 1; ST_HAS_LONG_SEPARATORS(tmpms) = 0; ST_HAS_TRIANGLE_RELIEF(tmpms) = 0; ST_DO_HILIGHT_BACK(tmpms) = 1; ST_DO_HILIGHT_FORE(tmpms) = 1; } /* common settings */ ST_VERTICAL_MARGIN_TOP(tmpms) = 0; ST_VERTICAL_MARGIN_BOTTOM(tmpms) = 0; ST_CSET_MENU(tmpms) = 0; ST_HAS_MENU_CSET(tmpms) = 0; ST_CSET_ACTIVE(tmpms) = 0; ST_HAS_ACTIVE_CSET(tmpms) = 0; ST_CSET_GREYED(tmpms) = 0; ST_HAS_GREYED_CSET(tmpms) = 0; ST_BORDER_WIDTH(tmpms) = DEFAULT_MENU_BORDER_WIDTH; ST_ACTIVE_AREA_PERCENT(tmpms) = DEFAULT_MENU_POPUP_NOW_RATIO; ST_ITEM_GAP_ABOVE(tmpms) = DEFAULT_MENU_ITEM_TEXT_Y_OFFSET; ST_ITEM_GAP_BELOW(tmpms) = DEFAULT_MENU_ITEM_TEXT_Y_OFFSET2; ST_TITLE_GAP_ABOVE(tmpms) = DEFAULT_MENU_TITLE_TEXT_Y_OFFSET; ST_TITLE_GAP_BELOW(tmpms) = DEFAULT_MENU_TITLE_TEXT_Y_OFFSET2; ST_USE_LEFT_SUBMENUS(tmpms) = 0; ST_IS_ANIMATED(tmpms) = 0; ST_USE_AUTOMATIC_HOTKEYS(tmpms) = 0; menustyle_free_face(&ST_FACE(tmpms)); ST_FACE(tmpms).type = SimpleMenu; if (ST_PSTDFONT(tmpms) && !ST_USING_DEFAULT_FONT(tmpms)) { FlocaleUnloadFont(dpy, ST_PSTDFONT(tmpms)); } ST_PSTDFONT(tmpms) = Scr.DefaultFont; ST_USING_DEFAULT_FONT(tmpms) = True; has_gc_changed = True; if (ST_HAS_SIDE_COLOR(tmpms) == 1) { fvwmlib_free_colors( dpy, &ST_SIDE_COLOR(tmpms), 1, True); ST_HAS_SIDE_COLOR(tmpms) = 0; } ST_HAS_SIDE_COLOR(tmpms) = 0; if (ST_SIDEPIC(tmpms)) { PDestroyFvwmPicture(dpy, ST_SIDEPIC(tmpms)); ST_SIDEPIC(tmpms) = NULL; } if (is_initialised == False) { /* now begin the real work */ is_initialised = True; continue; } break; case 3: /* Foreground */ fvwmlib_free_colors( dpy, &ST_MENU_COLORS(tmpms).fore, 1, True); if (arg1) { ST_MENU_COLORS(tmpms).fore = GetColor(arg1); } else { ST_MENU_COLORS(tmpms).fore = GetColor(DEFAULT_FORE_COLOR); } has_gc_changed = True; break; case 4: /* Background */ fvwmlib_free_colors( dpy, &ST_MENU_COLORS(tmpms).back, 1, True); if (arg1) { ST_MENU_COLORS(tmpms).back = GetColor(arg1); } else { ST_MENU_COLORS(tmpms).back = GetColor(DEFAULT_BACK_COLOR); } has_gc_changed = True; break; case 5: /* Greyed */ if (ST_HAS_STIPPLE_FORE(tmpms)) { fvwmlib_free_colors( dpy, &ST_MENU_STIPPLE_COLORS(tmpms).fore, 1, True); } if (arg1 == NULL) { ST_HAS_STIPPLE_FORE(tmpms) = 0; } else { ST_MENU_STIPPLE_COLORS(tmpms).fore = GetColor(arg1); ST_HAS_STIPPLE_FORE(tmpms) = 1; } has_gc_changed = True; break; case 7: /* HilightBackOff */ on ^= 1; /* fall throw */ case 6: /* HilightBack */ if (ST_HAS_ACTIVE_BACK(tmpms)) { fvwmlib_free_colors( dpy, &ST_MENU_ACTIVE_COLORS(tmpms).back, 1, True); } if (arg1 == NULL || !on) { ST_HAS_ACTIVE_BACK(tmpms) = 0; } else { ST_MENU_ACTIVE_COLORS(tmpms).back = GetColor(arg1); ST_HAS_ACTIVE_BACK(tmpms) = 1; } ST_DO_HILIGHT_BACK(tmpms) = on; has_gc_changed = True; break; case 9: /* ActiveForeOff */ on ^= 1; /* fall throw */ case 8: /* ActiveFore */ if (ST_HAS_ACTIVE_FORE(tmpms)) { fvwmlib_free_colors( dpy, &ST_MENU_ACTIVE_COLORS(tmpms).fore, 1, True); } if (arg1 == NULL || !on) { ST_HAS_ACTIVE_FORE(tmpms) = 0; } else { ST_MENU_ACTIVE_COLORS(tmpms).fore = GetColor(arg1); ST_HAS_ACTIVE_FORE(tmpms) = 1; } ST_DO_HILIGHT_FORE(tmpms) = on; has_gc_changed = True; break; case 10: /* Hilight3DThick */ ST_RELIEF_THICKNESS(tmpms) = 2; break; case 11: /* Hilight3DThin */ ST_RELIEF_THICKNESS(tmpms) = 1; break; case 12: /* Hilight3DOff */ ST_RELIEF_THICKNESS(tmpms) = 0; break; case 13: /* Animation */ ST_IS_ANIMATED(tmpms) = on; break; case 14: /* AnimationOff */ ST_IS_ANIMATED(tmpms) = !on; break; case 15: /* Font */ if (arg1 != NULL && !(new_font = FlocaleLoadFont(dpy, arg1, "fvwm"))) { fvwm_msg(ERR, "NewMenuStyle", "Couldn't load font '%s'\n", arg1); break; } if (ST_PSTDFONT(tmpms) && !ST_USING_DEFAULT_FONT(tmpms)) { FlocaleUnloadFont(dpy, ST_PSTDFONT(tmpms)); } if (arg1 == NULL) { /* reset to screen font */ ST_PSTDFONT(tmpms) = Scr.DefaultFont; ST_USING_DEFAULT_FONT(tmpms) = True; } else { ST_PSTDFONT(tmpms) = new_font; ST_USING_DEFAULT_FONT(tmpms) = False; } has_gc_changed = True; break; case 16: /* MenuFace */ while (args && *args != '\0' && isspace((unsigned char)*args)) { args++; } menustyle_parse_face(args, &ST_FACE(tmpms), True); break; case 17: /* PopupDelay */ if (GetIntegerArguments(args, NULL, val, 1) == 0 || *val < 0) { ST_POPUP_DELAY(tmpms) = DEFAULT_POPUP_DELAY; } else { ST_POPUP_DELAY(tmpms) = (*val+9)/10; } break; case 18: /* PopupOffset */ if ((n = GetIntegerArguments(args, NULL, val, 2)) == 0) { fvwm_msg(ERR,"NewMenuStyle", "PopupOffset requires one or two" " arguments"); } else { ST_POPUP_OFFSET_ADD(tmpms) = val[0]; if (n == 2 && val[1] <= 100 && val[1] >= 0) { ST_POPUP_OFFSET_PERCENT(tmpms) = val[1]; } else { ST_POPUP_OFFSET_PERCENT(tmpms) = 100; } } break; case 19: /* TitleWarp */ ST_DO_WARP_TO_TITLE(tmpms) = on; break; case 20: /* TitleWarpOff */ ST_DO_WARP_TO_TITLE(tmpms) = !on; break; case 21: /* TitleUnderlines0 */ ST_TITLE_UNDERLINES(tmpms) = 0; break; case 22: /* TitleUnderlines1 */ ST_TITLE_UNDERLINES(tmpms) = 1; break; case 23: /* TitleUnderlines2 */ ST_TITLE_UNDERLINES(tmpms) = 2; break; case 24: /* SeparatorsLong */ ST_HAS_LONG_SEPARATORS(tmpms) = on; break; case 25: /* SeparatorsShort */ ST_HAS_LONG_SEPARATORS(tmpms) = !on; break; case 26: /* TrianglesSolid */ ST_HAS_TRIANGLE_RELIEF(tmpms) = !on; break; case 27: /* TrianglesRelief */ ST_HAS_TRIANGLE_RELIEF(tmpms) = on; break; case 28: /* PopupImmediately */ ST_DO_POPUP_IMMEDIATELY(tmpms) = on; break; case 29: /* PopupDelayed */ ST_DO_POPUP_IMMEDIATELY(tmpms) = !on; break; case 30: /* DoubleClickTime */ if (GetIntegerArguments(args, NULL, val, 1) == 0 || *val < 0) { ST_DOUBLE_CLICK_TIME(tmpms) = DEFAULT_MENU_CLICKTIME; } else { ST_DOUBLE_CLICK_TIME(tmpms) = *val; } break; case 31: /* SidePic */ if (ST_SIDEPIC(tmpms)) { PDestroyFvwmPicture(dpy, ST_SIDEPIC(tmpms)); ST_SIDEPIC(tmpms) = NULL; } if (arg1) { fpa.mask = (Pdepth <= 8)? FPAM_DITHER:0; ST_SIDEPIC(tmpms) = PCacheFvwmPicture( dpy, Scr.NoFocusWin, NULL, arg1, fpa); if (!ST_SIDEPIC(tmpms)) { fvwm_msg(WARN, "NewMenuStyle", "Couldn't find pixmap %s", arg1); } } break; case 32: /* SideColor */ if (ST_HAS_SIDE_COLOR(tmpms) == 1) { fvwmlib_free_colors( dpy, &ST_SIDE_COLOR(tmpms), 1, True); ST_HAS_SIDE_COLOR(tmpms) = 0; } if (arg1) { ST_SIDE_COLOR(tmpms) = GetColor(arg1); ST_HAS_SIDE_COLOR(tmpms) = 1; } break; case 33: /* PopupAsRootmenu */ ST_DO_POPUP_AS(tmpms) = MDP_ROOT_MENU; break; case 34: /* PopupAsSubmenu */ ST_DO_POPUP_AS(tmpms) = MDP_POST_MENU; break; case 35: /* RemoveSubmenus */ ST_DO_UNMAP_SUBMENU_ON_POPDOWN(tmpms) = on; break; case 36: /* HoldSubmenus */ ST_DO_UNMAP_SUBMENU_ON_POPDOWN(tmpms) = !on; break; case 37: /* SubmenusRight */ ST_USE_LEFT_SUBMENUS(tmpms) = !on; break; case 38: /* SubmenusLeft */ ST_USE_LEFT_SUBMENUS(tmpms) = on; break; case 39: /* BorderWidth */ if (GetIntegerArguments(args, NULL, val, 1) == 0 || *val < 0 || *val > MAX_MENU_BORDER_WIDTH) { ST_BORDER_WIDTH(tmpms) = DEFAULT_MENU_BORDER_WIDTH; } else { ST_BORDER_WIDTH(tmpms) = *val; } break; case 40: /* Hilight3DThickness */ if (GetIntegerArguments(args, NULL, val, 1) > 0) { if (*val < 0) { *val = -*val; ST_IS_ITEM_RELIEF_REVERSED(tmpms) = 1; } else { ST_IS_ITEM_RELIEF_REVERSED(tmpms) = 0; } if (*val > MAX_MENU_ITEM_RELIEF_THICKNESS) *val = MAX_MENU_ITEM_RELIEF_THICKNESS; ST_RELIEF_THICKNESS(tmpms) = *val; } break; case 41: /* ItemFormat */ if (ST_ITEM_FORMAT(tmpms)) { free(ST_ITEM_FORMAT(tmpms)); ST_ITEM_FORMAT(tmpms) = NULL; } if (arg1) { ST_ITEM_FORMAT(tmpms) = safestrdup(arg1); } break; case 42: /* AutomaticHotkeys */ ST_USE_AUTOMATIC_HOTKEYS(tmpms) = on; break; case 43: /* AutomaticHotkeysOff */ ST_USE_AUTOMATIC_HOTKEYS(tmpms) = !on; break; case 44: /* VerticalItemSpacing */ parse_vertical_spacing_line( args, &ST_ITEM_GAP_ABOVE(tmpms), &ST_ITEM_GAP_BELOW(tmpms), DEFAULT_MENU_ITEM_TEXT_Y_OFFSET, DEFAULT_MENU_ITEM_TEXT_Y_OFFSET2); break; case 45: /* VerticalTitleSpacing */ parse_vertical_spacing_line( args, &ST_TITLE_GAP_ABOVE(tmpms), &ST_TITLE_GAP_BELOW(tmpms), DEFAULT_MENU_TITLE_TEXT_Y_OFFSET, DEFAULT_MENU_TITLE_TEXT_Y_OFFSET2); break; case 46: /* MenuColorset */ if (GetIntegerArguments(args, NULL, val, 1) == 0 || *val < 0) { ST_HAS_MENU_CSET(tmpms) = 0; ST_CSET_MENU(tmpms) = 0; } else { ST_HAS_MENU_CSET(tmpms) = 1; ST_CSET_MENU(tmpms) = *val; alloc_colorset(*val); } has_gc_changed = True; break; case 47: /* ActiveColorset */ if (GetIntegerArguments(args, NULL, val, 1) == 0 || *val < 0) { ST_HAS_ACTIVE_CSET(tmpms) = 0; ST_CSET_ACTIVE(tmpms) = 0; } else { ST_HAS_ACTIVE_CSET(tmpms) = 1; ST_CSET_ACTIVE(tmpms) = *val; alloc_colorset(*val); } has_gc_changed = True; break; case 48: /* GreyedColorset */ if (GetIntegerArguments(args, NULL, val, 1) == 0 || *val < 0) { ST_HAS_GREYED_CSET(tmpms) = 0; ST_CSET_GREYED(tmpms) = 0; } else { ST_HAS_GREYED_CSET(tmpms) = 1; ST_CSET_GREYED(tmpms) = *val; alloc_colorset(*val); } has_gc_changed = True; break; case 49: /* SelectOnRelease */ keycode = 0; if (arg1) { keycode = XKeysymToKeycode( dpy, FvwmStringToKeysym(dpy, arg1)); } ST_SELECT_ON_RELEASE_KEY(tmpms) = keycode; break; case 50: /* PopdownImmediately */ ST_DO_POPDOWN_IMMEDIATELY(tmpms) = 1; break; case 51: /* PopdownDelayed */ ST_DO_POPDOWN_IMMEDIATELY(tmpms) = 0; break; case 52: /* PopdownDelay */ if (GetIntegerArguments(args, NULL, val, 1) == 0 || *val < 0) { ST_POPDOWN_DELAY(tmpms) = DEFAULT_POPDOWN_DELAY; } else { ST_POPDOWN_DELAY(tmpms) = (*val+9)/10; } break; case 53: /* PopupActiveArea */ if (GetIntegerArguments(args, NULL, val, 1) == 0 || *val <= 50 || *val > 100) { ST_ACTIVE_AREA_PERCENT(tmpms) = DEFAULT_MENU_POPUP_NOW_RATIO; } else { ST_ACTIVE_AREA_PERCENT(tmpms) = *val; } break; case 54: /* PopupIgnore */ ST_DO_POPUP_AS(tmpms) = MDP_IGNORE; break; case 55: /* PopupClose */ ST_DO_POPUP_AS(tmpms) = MDP_CLOSE; break; case 56: /* MouseWheel */ if (arg1) { if (StrEquals(arg1, "ActivatesItem")) { ST_MOUSE_WHEEL(tmpms) = MMW_OFF; } else if (StrEquals(arg1, "ScrollsMenuBackwards")) { ST_MOUSE_WHEEL(tmpms) = MMW_MENU_BACKWARDS; } else if (StrEquals(arg1, "ScrollsMenu")) { ST_MOUSE_WHEEL(tmpms) = MMW_MENU; } else if (StrEquals(arg1, "ScrollsPointer")) { ST_MOUSE_WHEEL(tmpms) = MMW_POINTER; } else { fvwm_msg( ERR, "NewMenuStyle", "unknown argument to" " MouseWheel '%s'", arg1); ST_MOUSE_WHEEL(tmpms) = MMW_POINTER; } } else { ST_MOUSE_WHEEL(tmpms) = (on) ? MMW_POINTER : MMW_OFF; } break; case 57: /* ScrollOffPage */ ST_SCROLL_OFF_PAGE(tmpms) = on; break; case 58: /* TrianglesUseFore */ ST_TRIANGLES_USE_FORE(tmpms) = on; break; case 59: /* TitleColorset */ if (GetIntegerArguments(args, NULL, val, 1) == 0 || *val < 0) { ST_HAS_TITLE_CSET(tmpms) = 0; ST_CSET_TITLE(tmpms) = 0; } else { ST_HAS_TITLE_CSET(tmpms) = 1; ST_CSET_TITLE(tmpms) = *val; alloc_colorset(*val); } has_gc_changed = True; break; case 60: /* TitleHilightBack */ ST_DO_HILIGHT_TITLE_BACK(tmpms) = on; has_gc_changed = True; break; case 61: /* TitleFont */ if (arg1 != NULL && !(new_font = FlocaleLoadFont(dpy, arg1, "fvwm"))) { fvwm_msg(ERR, "NewMenuStyle", "Couldn't load font '%s'\n", arg1); break; } if ( ST_PTITLEFONT(tmpms) && !ST_USING_DEFAULT_TITLEFONT(tmpms)) { FlocaleUnloadFont(dpy, ST_PTITLEFONT(tmpms)); } if (arg1 == NULL) { /* reset to screen font */ ST_PTITLEFONT(tmpms) = Scr.DefaultFont; ST_USING_DEFAULT_TITLEFONT(tmpms) = True; } else { ST_PTITLEFONT(tmpms) = new_font; ST_USING_DEFAULT_TITLEFONT(tmpms) = False; } has_gc_changed = True; break; case 62: /* VerticalMargins */ parse_vertical_margins_line( args, &ST_VERTICAL_MARGIN_TOP(tmpms), &ST_VERTICAL_MARGIN_BOTTOM(tmpms), 0, 0); break; #if 0 case 99: /* PositionHints */ /* to be implemented */ break; #endif default: fvwm_msg(ERR, "NewMenuStyle", "unknown option '%s'", poption); break; } /* switch */ if (option) { free(option); option = NULL; } free(optstring); optstring = NULL; if (arg1) { free(arg1); arg1 = NULL; } } /* while */ if (has_gc_changed) { menustyle_update(tmpms); } if (default_menu_style == NULL) { /* First MenuStyle MUST be the default style */ default_menu_style = tmpms; ST_NEXT_STYLE(tmpms) = NULL; } else if (ms) { /* copy our new menu face over the old one */ memcpy(ms, tmpms, sizeof(MenuStyle)); free(tmpms); return ms; } else { MenuStyle *before = default_menu_style; /* add a new menu face to list */ ST_NEXT_STYLE(tmpms) = NULL; while (ST_NEXT_STYLE(before)) before = ST_NEXT_STYLE(before); ST_NEXT_STYLE(before) = tmpms; } return tmpms; } void menustyle_copy(MenuStyle *origms, MenuStyle *destms) { FvwmPictureAttributes fpa; /* Copy origms to destms, be aware of all pointers in the MenuStyle strcture. Use the same order as in menustyle_parse_style */ /* menu colors */ fvwmlib_copy_color( dpy, &ST_MENU_COLORS(destms).fore, &ST_MENU_COLORS(origms).fore, True, True); fvwmlib_copy_color( dpy, &ST_MENU_COLORS(destms).back, &ST_MENU_COLORS(origms).back, True, True); /* Greyed */ fvwmlib_copy_color( dpy, &ST_MENU_STIPPLE_COLORS(destms).fore, &ST_MENU_STIPPLE_COLORS(origms).fore, ST_HAS_STIPPLE_FORE(destms), ST_HAS_STIPPLE_FORE(origms)); ST_MENU_STIPPLE_COLORS(destms).back = ST_MENU_STIPPLE_COLORS(origms).back; ST_HAS_STIPPLE_FORE(destms) = ST_HAS_STIPPLE_FORE(origms); /* HilightBack */ fvwmlib_copy_color( dpy, &ST_MENU_ACTIVE_COLORS(destms).back, &ST_MENU_ACTIVE_COLORS(origms).back, ST_HAS_ACTIVE_BACK(destms), ST_HAS_ACTIVE_BACK(origms)); ST_HAS_ACTIVE_BACK(destms) = ST_HAS_ACTIVE_BACK(origms); ST_DO_HILIGHT_BACK(destms) = ST_DO_HILIGHT_BACK(origms); /* ActiveFore */ fvwmlib_copy_color( dpy, &ST_MENU_ACTIVE_COLORS(destms).fore, &ST_MENU_ACTIVE_COLORS(origms).fore, ST_HAS_ACTIVE_FORE(destms), ST_HAS_ACTIVE_FORE(origms)); ST_HAS_ACTIVE_FORE(destms) = ST_HAS_ACTIVE_FORE(origms); ST_DO_HILIGHT_FORE(destms) = ST_DO_HILIGHT_FORE(origms); /* Hilight3D */ ST_RELIEF_THICKNESS(destms) = ST_RELIEF_THICKNESS(origms); /* Animation */ ST_IS_ANIMATED(destms) = ST_IS_ANIMATED(origms); /* font */ if (ST_PSTDFONT(destms) && !ST_USING_DEFAULT_FONT(destms)) { FlocaleUnloadFont(dpy, ST_PSTDFONT(destms)); } if (ST_PSTDFONT(origms) && !ST_USING_DEFAULT_FONT(origms)) { if (!(ST_PSTDFONT(destms) = FlocaleLoadFont(dpy, ST_PSTDFONT(origms)->name, "fvwm"))) { ST_PSTDFONT(destms) = Scr.DefaultFont; ST_USING_DEFAULT_FONT(destms) = True; fvwm_msg(ERR, "CopyMenuStyle", "Couldn't load font '%s' use Default Font\n", ST_PSTDFONT(origms)->name); } else { ST_USING_DEFAULT_FONT(destms) = False; } } else { ST_USING_DEFAULT_FONT(destms) = True; ST_PSTDFONT(destms) = Scr.DefaultFont; } /* TitleFont */ if (ST_PTITLEFONT(destms) && !ST_USING_DEFAULT_TITLEFONT(destms)) { FlocaleUnloadFont(dpy, ST_PTITLEFONT(destms)); } if (ST_PTITLEFONT(origms) && !ST_USING_DEFAULT_TITLEFONT(origms)) { if ( !(ST_PTITLEFONT(destms) = FlocaleLoadFont( dpy, ST_PTITLEFONT(origms)->name, "fvwm"))) { ST_PTITLEFONT(destms) = Scr.DefaultFont; ST_USING_DEFAULT_TITLEFONT(destms) = True; fvwm_msg(ERR, "CopyMenuStyle", "Couldn't load font '%s' use Default Font\n", ST_PTITLEFONT(origms)->name); } else { ST_USING_DEFAULT_TITLEFONT(destms) = False; } } else { ST_USING_DEFAULT_TITLEFONT(destms) = True; ST_PTITLEFONT(destms) = Scr.DefaultFont; } /* MenuFace */ menustyle_copy_face(&ST_FACE(destms), &ST_FACE(origms)); /* PopupDelay */ ST_POPUP_DELAY(destms) = ST_POPUP_DELAY(origms); /* PopupOffset */ ST_POPUP_OFFSET_PERCENT(destms) = ST_POPUP_OFFSET_PERCENT(origms); ST_POPUP_OFFSET_ADD(destms) = ST_POPUP_OFFSET_ADD(origms); /* TitleWarp */ ST_DO_WARP_TO_TITLE(destms) = ST_DO_WARP_TO_TITLE(origms); /* TitleUnderlines */ ST_TITLE_UNDERLINES(destms) = ST_TITLE_UNDERLINES(origms); /* Separators */ ST_HAS_LONG_SEPARATORS(destms) = ST_HAS_LONG_SEPARATORS(origms); /* Triangles */ ST_HAS_TRIANGLE_RELIEF(destms) = ST_HAS_TRIANGLE_RELIEF(origms); /* PopupDelayed */ ST_DO_POPUP_IMMEDIATELY(destms) = ST_DO_POPUP_IMMEDIATELY(origms); /* DoubleClickTime */ ST_DOUBLE_CLICK_TIME(destms) = ST_DOUBLE_CLICK_TIME(origms); /* VerticalMargins */ ST_VERTICAL_MARGIN_TOP(destms) = ST_VERTICAL_MARGIN_TOP(origms); ST_VERTICAL_MARGIN_BOTTOM(destms) = ST_VERTICAL_MARGIN_BOTTOM(origms); /* SidePic */ if (ST_SIDEPIC(destms)) { PDestroyFvwmPicture(dpy, ST_SIDEPIC(destms)); ST_SIDEPIC(destms) = NULL; } if (ST_SIDEPIC(origms)) { fpa.mask = (Pdepth <= 8)? FPAM_DITHER:0; ST_SIDEPIC(destms) = PCacheFvwmPicture( dpy, Scr.NoFocusWin, NULL, ST_SIDEPIC(origms)->name, fpa); } /* side color */ fvwmlib_copy_color( dpy, &ST_SIDE_COLOR(destms), &ST_SIDE_COLOR(origms), ST_HAS_SIDE_COLOR(destms), ST_HAS_SIDE_COLOR(origms)); ST_HAS_SIDE_COLOR(destms) = ST_HAS_SIDE_COLOR(origms); /* PopupAsRootmenu */ ST_DO_POPUP_AS(destms) = ST_DO_POPUP_AS(origms); /* RemoveSubmenus */ ST_DO_UNMAP_SUBMENU_ON_POPDOWN(destms) = ST_DO_UNMAP_SUBMENU_ON_POPDOWN(origms); /* SubmenusRight */ ST_USE_LEFT_SUBMENUS(destms) = ST_USE_LEFT_SUBMENUS(origms); /* BorderWidth */ ST_BORDER_WIDTH(destms) = ST_BORDER_WIDTH(origms); /* Hilight3DThickness */ ST_IS_ITEM_RELIEF_REVERSED(destms) = ST_IS_ITEM_RELIEF_REVERSED(origms); /* ItemFormat */ if (ST_ITEM_FORMAT(destms)) { free(ST_ITEM_FORMAT(destms)); ST_ITEM_FORMAT(destms) = NULL; } if (ST_ITEM_FORMAT(origms)) { ST_ITEM_FORMAT(destms) = safestrdup(ST_ITEM_FORMAT(origms)); } /* AutomaticHotkeys */ ST_USE_AUTOMATIC_HOTKEYS(destms) = ST_USE_AUTOMATIC_HOTKEYS(origms); /* Item and Title Spacing */ ST_ITEM_GAP_ABOVE(destms) = ST_ITEM_GAP_ABOVE(origms); ST_ITEM_GAP_BELOW(destms) = ST_ITEM_GAP_BELOW(origms); ST_TITLE_GAP_ABOVE(destms) = ST_TITLE_GAP_ABOVE(origms); ST_TITLE_GAP_BELOW(destms) = ST_TITLE_GAP_BELOW(origms); /* MenuColorset */ ST_HAS_MENU_CSET(destms) = ST_HAS_MENU_CSET(origms); ST_CSET_MENU(destms) = ST_CSET_MENU(origms); /* ActiveColorset */ ST_HAS_ACTIVE_CSET(destms) = ST_HAS_ACTIVE_CSET(origms); ST_CSET_ACTIVE(destms) = ST_CSET_ACTIVE(origms); /* MenuColorset */ ST_HAS_GREYED_CSET(destms) = ST_HAS_GREYED_CSET(origms); ST_CSET_GREYED(destms) = ST_CSET_GREYED(origms); /* TitleColorset */ ST_HAS_TITLE_CSET(destms) = ST_HAS_TITLE_CSET(origms); ST_CSET_TITLE(destms) = ST_CSET_TITLE(origms); /* SelectOnRelease */ ST_SELECT_ON_RELEASE_KEY(destms) = ST_SELECT_ON_RELEASE_KEY(origms); /* PopdownImmediately */ ST_DO_POPDOWN_IMMEDIATELY(destms) = ST_DO_POPDOWN_IMMEDIATELY(origms); /* PopdownDelay */ ST_POPDOWN_DELAY(destms) = ST_POPDOWN_DELAY(origms); /* Scroll */ ST_MOUSE_WHEEL(destms) = ST_MOUSE_WHEEL(origms); /* ScrollOffPage */ ST_SCROLL_OFF_PAGE(destms) = ST_SCROLL_OFF_PAGE(origms); /* TrianglesUseFore */ ST_TRIANGLES_USE_FORE(destms) = ST_TRIANGLES_USE_FORE(origms); /* Title */ ST_DO_HILIGHT_TITLE_BACK(destms) = ST_DO_HILIGHT_TITLE_BACK(origms); menustyle_update(destms); return; } /* ---------------------------- builtin commands --------------------------- */ void CMD_CopyMenuStyle(F_CMD_ARGS) { char *origname = NULL; char *destname = NULL; char *buffer; MenuStyle *origms; MenuStyle *destms; origname = PeekToken(action, &action); if (origname == NULL) { fvwm_msg(ERR,"CopyMenuStyle", "need two arguments"); return; } origms = menustyle_find(origname); if (!origms) { fvwm_msg(ERR, "CopyMenuStyle", "%s: no such menu style", origname); return; } destname = PeekToken(action, &action); if (destname == NULL) { fvwm_msg(ERR,"CopyMenuStyle", "need two arguments"); return; } if (action && *action) { fvwm_msg(ERR,"CopyMenuStyle", "too many arguments"); return; } destms = menustyle_find(destname); if (!destms) { /* create destms menu style */ buffer = (char *)safemalloc(strlen(destname) + 3); sprintf(buffer,"\"%s\"",destname); action = buffer; destms = menustyle_parse_style(F_PASS_ARGS); free(buffer); if (!destms) { /* this must never happen */ fvwm_msg(ERR, "CopyMenuStyle", "impossible to create %s menu style", destname); return; } } if (strcasecmp("*",destname) == 0) { fvwm_msg(ERR, "CopyMenuStyle", "You cannot copy on the default menu style"); return; } if (strcasecmp(ST_NAME(origms),destname) == 0) { fvwm_msg(ERR, "CopyMenuStyle", "%s and %s identify the same menu style", ST_NAME(origms),destname); return; } if (ST_USAGE_COUNT(destms) != 0) { fvwm_msg(ERR, "CopyMenuStyle", "menu style %s is in use", destname); return; } menustyle_copy(origms, destms); return; } void CMD_MenuStyle(F_CMD_ARGS) { char *option; char *poption; MenuStyle *dummy; GetNextSimpleOption(SkipNTokens(action, 1), &option); poption = option; while (poption && poption[0] == '!') { poption++; } if (option == NULL || menustyle_get_styleopt_index(poption) != -1) { dummy = menustyle_parse_style(F_PASS_ARGS); } else { dummy = menustyle_parse_old_style(F_PASS_ARGS); } if (option) { free(option); } return; }