1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-24 23:22:30 +01:00
Files
wmaker/src/defaults.c
dan d5f177fe66 - Put back DisplayFont in defaults.c. It either was removed by error, or the
change was incomplete (it was still accessed as a 0x0 pointer from
  moveres.c at least).
- Removed innapropriate comments about sloppy focus from dialog.c.
  Even if we think it's not a good focus mode, and don't like it, there is no
  need to be rude with people who use it. Better not support sloppy focus at
  all, than to suport it and tell to its users they're stupid.
2000-01-05 21:58:04 +00:00

3115 lines
77 KiB
C

/* defaults.c - manage configuration through defaults db
*
* Window Maker window manager
*
* Copyright (c) 1997, 1998 Alfredo K. Kojima
* Copyright (c) 1998 Dan Pascu
*
* 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.
*/
#include "wconfig.h"
#include "plugin.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>
#include <signal.h>
#ifdef HAVE_DLFCN_H
# include <dlfcn.h>
#endif
#ifndef PATH_MAX
#define PATH_MAX DEFAULT_PATH_MAX
#endif
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <wraster.h>
#include "WindowMaker.h"
#include "wcore.h"
#include "framewin.h"
#include "window.h"
#include "texture.h"
#include "screen.h"
#include "resources.h"
#include "defaults.h"
#include "keybind.h"
#include "xmodifier.h"
#include "icon.h"
#include "funcs.h"
#include "actions.h"
#include "dock.h"
#include "workspace.h"
/*
* Our own proplist reader parser. This one will not accept any
* syntax errors and is more descriptive in the error messages.
* It also doesn't seem to crash.
*/
extern proplist_t ReadProplistFromFile(char *file);
/***** Global *****/
extern WDDomain *WDWindowMaker;
extern WDDomain *WDWindowAttributes;
extern WDDomain *WDRootMenu;
extern int wScreenCount;
/*
extern proplist_t wDomainName;
extern proplist_t wAttributeDomainName;
*/
extern WPreferences wPreferences;
extern WShortKey wKeyBindings[WKBD_LAST];
typedef struct {
char *key;
char *default_value;
void *extra_data;
void *addr;
int (*convert)();
int (*update)();
proplist_t plkey;
proplist_t plvalue; /* default value */
} WDefaultEntry;
/* used to map strings to integers */
typedef struct {
char *string;
short value;
char is_alias;
} WOptionEnumeration;
/* type converters */
static int getBool();
static int getInt();
static int getCoord();
#if 0
/* this is not used yet */
static int getString();
#endif
static int getPathList();
static int getEnum();
static int getTexture();
#ifdef DRAWSTRING_PLUGIN
static int getTextRenderer();
#endif
static int getWSBackground();
static int getWSSpecificBackground();
static int getFont();
static int getColor();
static int getKeybind();
static int getModMask();
#ifdef NEWSTUFF
static int getRImage();
#endif
/* value setting functions */
static int setJustify();
static int setIfDockPresent();
static int setStickyIcons();
/*
static int setPositive();
*/
static int setWidgetColor();
static int setIconTile();
static int setWinTitleFont();
static int setMenuTitleFont();
static int setMenuTextFont();
static int setIconTitleFont();
static int setIconTitleColor();
static int setIconTitleBack();
static int setDisplayFont();
static int setLargeDisplayFont();
static int setWTitleColor();
static int setFTitleBack();
static int setPTitleBack();
static int setUTitleBack();
static int setResizebarBack();
static int setWorkspaceBack();
static int setWorkspaceSpecificBack();
static int setMenuTitleColor();
static int setMenuTextColor();
static int setMenuDisabledColor();
static int setMenuTitleBack();
static int setMenuTextBack();
static int setHightlight();
static int setHightlightText();
static int setKeyGrab();
static int setDoubleClick();
static int setIconPosition();
static int setClipTitleFont();
static int setClipTitleColor();
static int setMenuStyle();
static int setMultiByte();
static int updateUsableArea();
/*
* Tables to convert strings to enumeration values.
* Values stored are char
*/
/* WARNING: sum of length of all value strings must not exceed
* this value */
#define TOTAL_VALUES_LENGTH 80
#define REFRESH_WINDOW_TEXTURES (1<<0)
#define REFRESH_MENU_TEXTURE (1<<1)
#define REFRESH_MENU_FONT (1<<2)
#define REFRESH_MENU_COLOR (1<<3)
#define REFRESH_MENU_TITLE_TEXTURE (1<<4)
#define REFRESH_MENU_TITLE_FONT (1<<5)
#define REFRESH_MENU_TITLE_COLOR (1<<6)
#define REFRESH_WINDOW_TITLE_COLOR (1<<7)
#define REFRESH_WINDOW_FONT (1<<8)
#define REFRESH_ICON_TILE (1<<9)
#define REFRESH_ICON_FONT (1<<10)
#define REFRESH_WORKSPACE_BACK (1<<11)
#define REFRESH_BUTTON_IMAGES (1<<12)
#define REFRESH_ICON_TITLE_COLOR (1<<13)
#define REFRESH_ICON_TITLE_BACK (1<<14)
static WOptionEnumeration seFocusModes[] = {
{"Manual", WKF_CLICK, 0}, {"ClickToFocus", WKF_CLICK, 1},
{"Auto", WKF_POINTER, 0}, {"FocusFollowMouse", WKF_POINTER, 1},
{"Sloppy", WKF_SLOPPY, 0}, {"SemiAuto", WKF_SLOPPY, 1},
{NULL, 0, 0}
};
static WOptionEnumeration seColormapModes[] = {
{"Manual", WKF_CLICK, 0}, {"ClickToFocus", WKF_CLICK, 1},
{"Auto", WKF_POINTER, 0}, {"FocusFollowMouse", WKF_POINTER, 1},
{NULL, 0, 0}
};
static WOptionEnumeration sePlacements[] = {
{"Auto", WPM_AUTO, 0},
{"Smart", WPM_SMART, 0},
{"Cascade", WPM_CASCADE, 0},
{"Random", WPM_RANDOM, 0},
{"Manual", WPM_MANUAL, 0},
{NULL, 0, 0}
};
static WOptionEnumeration seGeomDisplays[] = {
{"Center", WDIS_CENTER, 0},
{"Corner", WDIS_TOPLEFT, 0},
{"Floating", WDIS_FRAME_CENTER, 0},
{"Line", WDIS_NEW, 0},
{NULL, 0, 0}
};
static WOptionEnumeration seSpeeds[] = {
{"UltraFast", SPEED_ULTRAFAST, 0},
{"Fast", SPEED_FAST, 0},
{"Medium", SPEED_MEDIUM, 0},
{"Slow", SPEED_SLOW, 0},
{"UltraSlow", SPEED_ULTRASLOW, 0},
{NULL, 0, 0}
};
static WOptionEnumeration seMouseButtons[] = {
{"None", -1, 0},
{"Left", Button1, 0}, {"Button1", Button1, 1},
{"Middle", Button2, 0}, {"Button2", Button2, 1},
{"Right", Button3, 0}, {"Button3", Button3, 1},
{"Button4", Button4, 0},
{"Button5", Button5, 0},
{NULL, 0, 0}
};
static WOptionEnumeration seIconificationStyles[] = {
{"Zoom", WIS_ZOOM, 0},
{"Twist", WIS_TWIST, 0},
{"Flip", WIS_FLIP, 0},
{"None", WIS_NONE, 0},
{"random", WIS_RANDOM, 0},
{NULL, 0, 0}
};
static WOptionEnumeration seJustifications[] = {
{"Left", WTJ_LEFT, 0},
{"Center", WTJ_CENTER, 0},
{"Right", WTJ_RIGHT, 0},
{NULL, 0, 0}
};
static WOptionEnumeration seIconPositions[] = {
{"blv", IY_BOTTOM|IY_LEFT|IY_VERT, 0},
{"blh", IY_BOTTOM|IY_LEFT|IY_HORIZ, 0},
{"brv", IY_BOTTOM|IY_RIGHT|IY_VERT, 0},
{"brh", IY_BOTTOM|IY_RIGHT|IY_HORIZ, 0},
{"tlv", IY_TOP|IY_LEFT|IY_VERT, 0},
{"tlh", IY_TOP|IY_LEFT|IY_HORIZ, 0},
{"trv", IY_TOP|IY_RIGHT|IY_VERT, 0},
{"trh", IY_TOP|IY_RIGHT|IY_HORIZ, 0},
{NULL, 0, 0}
};
static WOptionEnumeration seMenuStyles[] = {
{"normal", MS_NORMAL, 0},
{"singletexture", MS_SINGLE_TEXTURE, 0},
{"flat", MS_FLAT, 0},
{NULL, 0, 0}
};
static WOptionEnumeration seDisplayPositions[] = {
{"none", WD_NONE, 0},
{"center", WD_CENTER, 0},
{"top", WD_TOP, 0},
{"bottom", WD_BOTTOM, 0},
{"topleft", WD_TOPLEFT, 0},
{"topright", WD_TOPRIGHT, 0},
{"bottomleft", WD_BOTTOMLEFT, 0},
{"bottomright", WD_BOTTOMRIGHT, 0}
};
/*
* ALL entries in the tables bellow, NEED to have a default value
* defined, and this value needs to be correct.
*/
/* these options will only affect the window manager on startup
*
* static defaults can't access the screen data, because it is
* created after these defaults are read
*/
WDefaultEntry staticOptionList[] = {
{"DisableDithering", "NO", NULL,
&wPreferences.no_dithering, getBool, NULL
},
{"ColormapSize", "4", NULL,
&wPreferences.cmap_size, getInt, NULL
},
/* static by laziness */
{"IconSize", "64", NULL,
&wPreferences.icon_size, getInt, NULL
},
{"ModifierKey", "Mod1", NULL,
&wPreferences.modifier_mask, getModMask, NULL
},
{"DisableWSMouseActions", "NO", NULL,
&wPreferences.disable_root_mouse, getBool, NULL
},
{"FocusMode", "manual", seFocusModes,
&wPreferences.focus_mode, getEnum, NULL
}, /* have a problem when switching from manual to sloppy without restart */
{"NewStyle", "NO", NULL,
&wPreferences.new_style, getBool, NULL
},
{"DisableDock", "NO", (void*) WM_DOCK,
NULL, getBool, setIfDockPresent
},
{"DisableClip", "NO", (void*) WM_CLIP,
NULL, getBool, setIfDockPresent
},
{"DisableMiniwindows", "NO", NULL,
&wPreferences.disable_miniwindows, getBool, NULL
},
{"MultiByteText", "NO", NULL,
&wPreferences.multi_byte_text, getBool, setMultiByte
}
};
WDefaultEntry optionList[] = {
/* dynamic options */
{"IconPosition", "blh", seIconPositions,
&wPreferences.icon_yard, getEnum, setIconPosition
},
{"IconificationStyle", "Zoom", seIconificationStyles,
&wPreferences.iconification_style, getEnum, NULL
},
{"SelectWindowsMouseButton", "Left", seMouseButtons,
&wPreferences.select_button, getEnum, NULL
},
{"WindowListMouseButton", "Middle", seMouseButtons,
&wPreferences.windowl_button, getEnum, NULL
},
{"ApplicationMenuMouseButton", "Right", seMouseButtons,
&wPreferences.menu_button, getEnum, NULL
},
{"PixmapPath", DEF_PIXMAP_PATHS, NULL,
&wPreferences.pixmap_path, getPathList, NULL
},
{"IconPath", DEF_ICON_PATHS, NULL,
&wPreferences.icon_path, getPathList, NULL
},
{"ColormapMode", "auto", seColormapModes,
&wPreferences.colormap_mode, getEnum, NULL
},
{"AutoFocus", "NO", NULL,
&wPreferences.auto_focus, getBool, NULL
},
{"RaiseDelay", "0", NULL,
&wPreferences.raise_delay, getInt, NULL
},
{"CirculateRaise", "NO", NULL,
&wPreferences.circ_raise, getBool, NULL
},
{"Superfluous", "NO", NULL,
&wPreferences.superfluous, getBool, NULL
},
{"AdvanceToNewWorkspace", "NO", NULL,
&wPreferences.ws_advance, getBool, NULL
},
{"CycleWorkspaces", "NO", NULL,
&wPreferences.ws_cycle, getBool, NULL
},
{"WorkspaceNameDisplayPosition", "center", seDisplayPositions,
&wPreferences.workspace_name_display_position, getEnum, NULL
},
#ifdef VIRTUAL_DESKTOP
{"VirtualEdgeThickness", "1", NULL,
&wPreferences.vedge_thickness, getInt, NULL
},
{"VirtualEdgeHorizonScrollSpeed", "1", NULL,
&wPreferences.vedge_hscrollspeed, getInt, NULL
},
{"VirtualEdgeVerticalScrollSpeed", "1", NULL,
&wPreferences.vedge_vscrollspeed, getInt, NULL
},
{"VirtualEdgeWidth", "2000", NULL,
&wPreferences.vedge_width, getInt, NULL
},
{"VirtualEdgeHeight", "2000", NULL,
&wPreferences.vedge_height, getInt, NULL
},
#endif
{"StickyIcons", "NO", NULL,
&wPreferences.sticky_icons, getBool, setStickyIcons
},
{"SaveSessionOnExit", "NO", NULL,
&wPreferences.save_session_on_exit, getBool, NULL
},
{"WrapMenus", "NO", NULL,
&wPreferences.wrap_menus, getBool, NULL
},
{"ScrollableMenus", "NO", NULL,
&wPreferences.scrollable_menus, getBool, NULL
},
{"MenuScrollSpeed", "medium", seSpeeds,
&wPreferences.menu_scroll_speed, getEnum, NULL
},
{"IconSlideSpeed", "medium", seSpeeds,
&wPreferences.icon_slide_speed, getEnum, NULL
},
{"ShadeSpeed", "medium", seSpeeds,
&wPreferences.shade_speed, getEnum, NULL
},
{"DoubleClickTime", "250", (void*) &wPreferences.dblclick_time,
&wPreferences.dblclick_time, getInt, setDoubleClick,
},
{"AlignSubmenus", "NO", NULL,
&wPreferences.align_menus, getBool, NULL
},
{"OpenTransientOnOwnerWorkspace", "NO", NULL,
&wPreferences.open_transients_with_parent, getBool, NULL
},
{"WindowPlacement", "auto", sePlacements,
&wPreferences.window_placement, getEnum, NULL
},
{"IgnoreFocusClick","NO", NULL,
&wPreferences.ignore_focus_click, getBool, NULL
},
{"UseSaveUnders", "NO", NULL,
&wPreferences.use_saveunders, getBool, NULL
},
{"OpaqueMove", "NO", NULL,
&wPreferences.opaque_move, getBool, NULL
},
{"DisableSound", "NO", NULL,
&wPreferences.no_sound, getBool, NULL
},
{"DisableAnimations", "NO", NULL,
&wPreferences.no_animations, getBool, NULL
},
{"DontLinkWorkspaces","NO", NULL,
&wPreferences.no_autowrap, getBool, NULL
},
{"AutoArrangeIcons", "NO", NULL,
&wPreferences.auto_arrange_icons, getBool, NULL
},
{"NoWindowOverDock", "NO", NULL,
&wPreferences.no_window_over_dock, getBool, updateUsableArea
},
{"NoWindowOverIcons", "NO", NULL,
&wPreferences.no_window_over_icons, getBool, updateUsableArea
},
{"WindowPlaceOrigin", "(0, 0)", NULL,
&wPreferences.window_place_origin, getCoord, NULL
},
{"ResizeDisplay", "corner", seGeomDisplays,
&wPreferences.size_display, getEnum, NULL
},
{"MoveDisplay", "corner", seGeomDisplays,
&wPreferences.move_display, getEnum, NULL
},
{"DontConfirmKill", "NO", NULL,
&wPreferences.dont_confirm_kill, getBool,NULL
},
{"WindowTitleBalloons", "NO", NULL,
&wPreferences.window_balloon, getBool, NULL
},
{"MiniwindowTitleBalloons", "NO", NULL,
&wPreferences.miniwin_balloon,getBool, NULL
},
{"AppIconBalloons", "NO", NULL,
&wPreferences.appicon_balloon,getBool, NULL
},
{"HelpBalloons", "NO", NULL,
&wPreferences.help_balloon, getBool, NULL
},
{"EdgeResistance", "30", NULL,
&wPreferences.edge_resistance,getInt, NULL
},
{"Attraction", "NO", NULL,
&wPreferences.attract, getBool, NULL
},
{"DisableBlinking", "NO", NULL,
&wPreferences.dont_blink, getBool, NULL
},
#ifdef WEENDOZE_CYCLE
{"WindozeCycling","NO", NULL,
&wPreferences.windoze_cycling, getBool, NULL
},
{"PopupSwitchMenu","YES", NULL,
&wPreferences.popup_switchmenu, getBool, NULL
},
#endif /* WEENDOZE_CYCLE */
/* style options */
{"MenuStyle", "normal", seMenuStyles,
&wPreferences.menu_style, getEnum, setMenuStyle
},
{"WidgetColor", "(solid, gray)", NULL,
NULL, getTexture, setWidgetColor,
},
{"WorkspaceSpecificBack","()", NULL,
NULL, getWSSpecificBackground, setWorkspaceSpecificBack
},
/* WorkspaceBack must come after WorkspaceSpecificBack or
* WorkspaceBack wont know WorkspaceSpecificBack was also
* specified and 2 copies of wmsetbg will be launched */
{"WorkspaceBack", "(solid, black)", NULL,
NULL, getWSBackground,setWorkspaceBack
},
{"SmoothWorkspaceBack", "NO", NULL,
NULL, getBool, NULL
},
{"IconBack", "(solid, gray)", NULL,
NULL, getTexture, setIconTile
},
{"TitleJustify", "center", seJustifications,
&wPreferences.title_justification, getEnum, setJustify
},
{"WindowTitleFont", DEF_TITLE_FONT, NULL,
NULL, getFont, setWinTitleFont,
},
{"MenuTitleFont", DEF_MENU_TITLE_FONT, NULL,
NULL, getFont, setMenuTitleFont
},
{"MenuTextFont", DEF_MENU_ENTRY_FONT, NULL,
NULL, getFont, setMenuTextFont
},
{"IconTitleFont", DEF_ICON_TITLE_FONT, NULL,
NULL, getFont, setIconTitleFont
},
{"ClipTitleFont", DEF_CLIP_TITLE_FONT, NULL,
NULL, getFont, setClipTitleFont
},
{"DisplayFont", DEF_INFO_TEXT_FONT, NULL,
NULL, getFont, setDisplayFont
},
{"LargeDisplayFont",DEF_WORKSPACE_NAME_FONT, NULL,
NULL, getFont, setLargeDisplayFont
},
{"HighlightColor", "white", NULL,
NULL, getColor, setHightlight
},
{"HighlightTextColor", "black", NULL,
NULL, getColor, setHightlightText
},
{"ClipTitleColor", "black", (void*)CLIP_NORMAL,
NULL, getColor, setClipTitleColor
},
{"CClipTitleColor", "\"#454045\"", (void*)CLIP_COLLAPSED,
NULL, getColor, setClipTitleColor
},
#ifdef DRAWSTRING_PLUGIN
{"FTitleColor", "white", (void*)WS_FOCUSED,
NULL, getTextRenderer, setWTitleColor
},
{"PTitleColor", "white", (void*)WS_PFOCUSED,
NULL, getTextRenderer, setWTitleColor
},
{"UTitleColor", "black", (void*)WS_UNFOCUSED,
NULL, getTextRenderer, setWTitleColor
},
#else
{"FTitleColor", "white", (void*)WS_FOCUSED,
NULL, getColor, setWTitleColor
},
{"PTitleColor", "white", (void*)WS_PFOCUSED,
NULL, getColor, setWTitleColor
},
{"UTitleColor", "black", (void*)WS_UNFOCUSED,
NULL, getColor, setWTitleColor
},
#endif
{"FTitleBack", "(solid, black)", NULL,
NULL, getTexture, setFTitleBack
},
{"PTitleBack", "(solid, \"#616161\")", NULL,
NULL, getTexture, setPTitleBack
},
{"UTitleBack", "(solid, gray)", NULL,
NULL, getTexture, setUTitleBack
},
{"ResizebarBack", "(solid, gray)", NULL,
NULL, getTexture, setResizebarBack
},
#ifdef DRAWSTRING_PLUGIN
{"MenuTitleColor", "white", NULL,
NULL, getTextRenderer, setMenuTitleColor
},
#else
{"MenuTitleColor", "white", NULL,
NULL, getColor, setMenuTitleColor
},
#endif
{"MenuTextColor", "black", NULL,
NULL, getColor, setMenuTextColor
},
{"MenuDisabledColor", "\"#616161\"", NULL,
NULL, getColor, setMenuDisabledColor
},
{"MenuTitleBack", "(solid, black)", NULL,
NULL, getTexture, setMenuTitleBack
},
{"MenuTextBack", "(solid, gray)", NULL,
NULL, getTexture, setMenuTextBack
},
{"IconTitleColor", "white", NULL,
NULL, getColor, setIconTitleColor
},
{"IconTitleBack", "black", NULL,
NULL, getColor, setIconTitleBack
},
/* keybindings */
#ifndef LITE
{"RootMenuKey", "None", (void*)WKBD_ROOTMENU,
NULL, getKeybind, setKeyGrab
},
{"WindowListKey", "None", (void*)WKBD_WINDOWLIST,
NULL, getKeybind, setKeyGrab
},
#endif /* LITE */
{"WindowMenuKey", "None", (void*)WKBD_WINDOWMENU,
NULL, getKeybind, setKeyGrab
},
{"ClipLowerKey", "None", (void*)WKBD_CLIPLOWER,
NULL, getKeybind, setKeyGrab
},
{"ClipRaiseKey", "None", (void*)WKBD_CLIPRAISE,
NULL, getKeybind, setKeyGrab
},
{"ClipRaiseLowerKey", "None", (void*)WKBD_CLIPRAISELOWER,
NULL, getKeybind, setKeyGrab
},
{"MiniaturizeKey", "None", (void*)WKBD_MINIATURIZE,
NULL, getKeybind, setKeyGrab
},
{"HideKey", "None", (void*)WKBD_HIDE,
NULL, getKeybind, setKeyGrab
},
{"MoveResizeKey", "None", (void*)WKBD_MOVERESIZE,
NULL, getKeybind, setKeyGrab
},
{"CloseKey", "None", (void*)WKBD_CLOSE,
NULL, getKeybind, setKeyGrab
},
{"MaximizeKey", "None", (void*)WKBD_MAXIMIZE,
NULL, getKeybind, setKeyGrab
},
{"VMaximizeKey", "None", (void*)WKBD_VMAXIMIZE,
NULL, getKeybind, setKeyGrab
},
{"RaiseKey", "\"Meta+Up\"", (void*)WKBD_RAISE,
NULL, getKeybind, setKeyGrab
},
{"LowerKey", "\"Meta+Down\"", (void*)WKBD_LOWER,
NULL, getKeybind, setKeyGrab
},
{"RaiseLowerKey", "None", (void*)WKBD_RAISELOWER,
NULL, getKeybind, setKeyGrab
},
{"ShadeKey", "None", (void*)WKBD_SHADE,
NULL, getKeybind, setKeyGrab
},
{"SelectKey", "None", (void*)WKBD_SELECT,
NULL, getKeybind, setKeyGrab
},
{"FocusNextKey", "None", (void*)WKBD_FOCUSNEXT,
NULL, getKeybind, setKeyGrab
},
{"FocusPrevKey", "None", (void*)WKBD_FOCUSPREV,
NULL, getKeybind, setKeyGrab
},
{"NextWorkspaceKey", "None", (void*)WKBD_NEXTWORKSPACE,
NULL, getKeybind, setKeyGrab
},
{"PrevWorkspaceKey", "None", (void*)WKBD_PREVWORKSPACE,
NULL, getKeybind, setKeyGrab
},
{"NextWorkspaceLayerKey", "None", (void*)WKBD_NEXTWSLAYER,
NULL, getKeybind, setKeyGrab
},
{"PrevWorkspaceLayerKey", "None", (void*)WKBD_PREVWSLAYER,
NULL, getKeybind, setKeyGrab
},
{"Workspace1Key", "None", (void*)WKBD_WORKSPACE1,
NULL, getKeybind, setKeyGrab
},
{"Workspace2Key", "None", (void*)WKBD_WORKSPACE2,
NULL, getKeybind, setKeyGrab
},
{"Workspace3Key", "None", (void*)WKBD_WORKSPACE3,
NULL, getKeybind, setKeyGrab
},
{"Workspace4Key", "None", (void*)WKBD_WORKSPACE4,
NULL, getKeybind, setKeyGrab
},
{"Workspace5Key", "None", (void*)WKBD_WORKSPACE5,
NULL, getKeybind, setKeyGrab
},
{"Workspace6Key", "None", (void*)WKBD_WORKSPACE6,
NULL, getKeybind, setKeyGrab
},
{"Workspace7Key", "None", (void*)WKBD_WORKSPACE7,
NULL, getKeybind, setKeyGrab
},
{"Workspace8Key", "None", (void*)WKBD_WORKSPACE8,
NULL, getKeybind, setKeyGrab
},
{"Workspace9Key", "None", (void*)WKBD_WORKSPACE9,
NULL, getKeybind, setKeyGrab
},
{"Workspace10Key", "None", (void*)WKBD_WORKSPACE10,
NULL, getKeybind, setKeyGrab
},
{"WindowShortcut1Key","None", (void*)WKBD_WINDOW1,
NULL, getKeybind, setKeyGrab
},
{"WindowShortcut2Key","None", (void*)WKBD_WINDOW2,
NULL, getKeybind, setKeyGrab
},
{"WindowShortcut3Key","None", (void*)WKBD_WINDOW3,
NULL, getKeybind, setKeyGrab
},
{"WindowShortcut4Key","None", (void*)WKBD_WINDOW4,
NULL, getKeybind, setKeyGrab
}
#ifdef EXTEND_WINDOWSHORTCUT
,{"WindowShortcut5Key","None", (void*)WKBD_WINDOW5,
NULL, getKeybind, setKeyGrab
},
{"WindowShortcut6Key","None", (void*)WKBD_WINDOW6,
NULL, getKeybind, setKeyGrab
},
{"WindowShortcut7Key","None", (void*)WKBD_WINDOW7,
NULL, getKeybind, setKeyGrab
},
{"WindowShortcut8Key","None", (void*)WKBD_WINDOW8,
NULL, getKeybind, setKeyGrab
},
{"WindowShortcut9Key","None", (void*)WKBD_WINDOW9,
NULL, getKeybind, setKeyGrab
},
{"WindowShortcut10Key","None", (void*)WKBD_WINDOW10,
NULL, getKeybind, setKeyGrab
}
#endif /* EXTEND_WINDOWSHORTCUT */
#ifdef KEEP_XKB_LOCK_STATUS
,{"ToggleKbdModeKey", "None", (void*)WKBD_TOGGLE,
NULL, getKeybind, setKeyGrab
},
{"KbdModeLock", "NO", NULL,
&wPreferences.modelock, getBool, NULL
}
#endif /* KEEP_XKB_LOCK_STATUS */
};
#if 0
static void rereadDefaults(void);
#endif
#if 0
static void
rereadDefaults(void)
{
/* must defer the update because accessing X data from a
* signal handler can mess up Xlib */
}
#endif
static void
initDefaults()
{
int i;
WDefaultEntry *entry;
PLSetStringCmpHook(StringCompareHook);
for (i=0; i<sizeof(optionList)/sizeof(WDefaultEntry); i++) {
entry = &optionList[i];
entry->plkey = PLMakeString(entry->key);
if (entry->default_value)
entry->plvalue = PLGetProplistWithDescription(entry->default_value);
else
entry->plvalue = NULL;
}
for (i=0; i<sizeof(staticOptionList)/sizeof(WDefaultEntry); i++) {
entry = &staticOptionList[i];
entry->plkey = PLMakeString(entry->key);
if (entry->default_value)
entry->plvalue = PLGetProplistWithDescription(entry->default_value);
else
entry->plvalue = NULL;
}
/*
wDomainName = PLMakeString(WMDOMAIN_NAME);
wAttributeDomainName = PLMakeString(WMATTRIBUTE_DOMAIN_NAME);
PLRegister(wDomainName, rereadDefaults);
PLRegister(wAttributeDomainName, rereadDefaults);
*/
}
#if 0
proplist_t
wDefaultsInit(int screen_number)
{
static int defaults_inited = 0;
proplist_t dict;
if (!defaults_inited) {
initDefaults();
}
dict = PLGetDomain(wDomainName);
if (!dict) {
wwarning(_("could not read domain \"%s\" from defaults database"),
PLGetString(wDomainName));
}
return dict;
}
#endif
void
wDefaultsDestroyDomain(WDDomain *domain)
{
if (domain->dictionary)
PLRelease(domain->dictionary);
free(domain->path);
free(domain);
}
WDDomain*
wDefaultsInitDomain(char *domain, Bool requireDictionary)
{
WDDomain *db;
struct stat stbuf;
static int inited = 0;
char path[PATH_MAX];
char *the_path;
proplist_t shared_dict=NULL;
if (!inited) {
inited = 1;
initDefaults();
}
db = wmalloc(sizeof(WDDomain));
memset(db, 0, sizeof(WDDomain));
db->domain_name = domain;
db->path = wdefaultspathfordomain(domain);
the_path = db->path;
if (the_path && stat(the_path, &stbuf)>=0) {
db->dictionary = ReadProplistFromFile(the_path);
if (db->dictionary) {
if (requireDictionary && !PLIsDictionary(db->dictionary)) {
PLRelease(db->dictionary);
db->dictionary = NULL;
wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
domain, the_path);
}
db->timestamp = stbuf.st_mtime;
} else {
wwarning(_("could not load domain %s from user defaults database"),
domain);
}
}
/* global system dictionary */
sprintf(path, "%s/WindowMaker/%s", SYSCONFDIR, domain);
if (stat(path, &stbuf)>=0) {
shared_dict = ReadProplistFromFile(path);
if (shared_dict) {
if (requireDictionary && !PLIsDictionary(shared_dict)) {
wwarning(_("Domain %s (%s) of global defaults database is corrupted!"),
domain, path);
PLRelease(shared_dict);
shared_dict = NULL;
} else {
if (db->dictionary && PLIsDictionary(shared_dict) &&
PLIsDictionary(db->dictionary)) {
PLMergeDictionaries(shared_dict, db->dictionary);
PLRelease(db->dictionary);
db->dictionary = shared_dict;
if (stbuf.st_mtime > db->timestamp)
db->timestamp = stbuf.st_mtime;
} else if (!db->dictionary) {
db->dictionary = shared_dict;
if (stbuf.st_mtime > db->timestamp)
db->timestamp = stbuf.st_mtime;
}
}
} else {
wwarning(_("could not load domain %s from global defaults database (%s)"),
domain, path);
}
}
/* set to save it in user's directory, no matter from where it was read */
if (db->dictionary) {
proplist_t tmp = PLMakeString(db->path);
PLSetFilename(db->dictionary, tmp);
PLRelease(tmp);
}
return db;
}
void
wReadStaticDefaults(proplist_t dict)
{
proplist_t plvalue;
WDefaultEntry *entry;
int i;
void *tdata;
for (i=0; i<sizeof(staticOptionList)/sizeof(WDefaultEntry); i++) {
entry = &staticOptionList[i];
if (dict)
plvalue = PLGetDictionaryEntry(dict, entry->plkey);
else
plvalue = NULL;
if (!plvalue) {
/* no default in the DB. Use builtin default */
plvalue = entry->plvalue;
}
if (plvalue) {
/* convert data */
(*entry->convert)(NULL, entry, plvalue, entry->addr, &tdata);
if (entry->update) {
(*entry->update)(NULL, entry, tdata, entry->extra_data);
}
}
}
}
void
wDefaultsCheckDomains(void *foo)
{
WScreen *scr;
struct stat stbuf;
proplist_t dict;
int i;
char path[PATH_MAX];
#ifdef HEARTBEAT
puts("Checking domains...");
#endif
if (stat(WDWindowMaker->path, &stbuf)>=0
&& WDWindowMaker->timestamp < stbuf.st_mtime) {
proplist_t shared_dict = NULL;
#ifdef HEARTBEAT
puts("Checking WindowMaker domain");
#endif
WDWindowMaker->timestamp = stbuf.st_mtime;
/* global dictionary */
sprintf(path, "%s/WindowMaker/WindowMaker", SYSCONFDIR);
if (stat(path, &stbuf)>=0) {
shared_dict = ReadProplistFromFile(path);
if (shared_dict && !PLIsDictionary(shared_dict)) {
wwarning(_("Domain %s (%s) of global defaults database is corrupted!"),
"WindowMaker", path);
PLRelease(shared_dict);
shared_dict = NULL;
} else if (!shared_dict) {
wwarning(_("could not load domain %s from global defaults database"),
"WindowMaker");
}
}
/* user dictionary */
dict = ReadProplistFromFile(WDWindowMaker->path);
if (dict) {
if (!PLIsDictionary(dict)) {
PLRelease(dict);
dict = NULL;
wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
"WindowMaker", WDWindowMaker->path);
} else {
if (shared_dict) {
PLSetFilename(shared_dict, PLGetFilename(dict));
PLMergeDictionaries(shared_dict, dict);
PLRelease(dict);
dict = shared_dict;
shared_dict = NULL;
}
for (i=0; i<wScreenCount; i++) {
scr = wScreenWithNumber(i);
if (scr)
wReadDefaults(scr, dict);
}
if (WDWindowMaker->dictionary) {
PLRelease(WDWindowMaker->dictionary);
}
WDWindowMaker->dictionary = dict;
}
} else {
wwarning(_("could not load domain %s from user defaults database"),
"WindowMaker");
}
if (shared_dict) {
PLRelease(shared_dict);
}
}
if (stat(WDWindowAttributes->path, &stbuf)>=0
&& WDWindowAttributes->timestamp < stbuf.st_mtime) {
#ifdef HEARTBEAT
puts("Checking WMWindowAttributes domain");
#endif
dict = ReadProplistFromFile(WDWindowAttributes->path);
if (dict) {
if (!PLIsDictionary(dict)) {
PLRelease(dict);
dict = NULL;
wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
"WMWindowAttributes", WDWindowAttributes->path);
} else {
if (WDWindowAttributes->dictionary)
PLRelease(WDWindowAttributes->dictionary);
WDWindowAttributes->dictionary = dict;
for (i=0; i<wScreenCount; i++) {
scr = wScreenWithNumber(i);
if (scr)
wDefaultUpdateIcons(scr);
}
}
} else {
wwarning(_("could not load domain %s from user defaults database"),
"WMWindowAttributes");
}
WDWindowAttributes->timestamp = stbuf.st_mtime;
}
#ifndef LITE
if (stat(WDRootMenu->path, &stbuf)>=0
&& WDRootMenu->timestamp < stbuf.st_mtime) {
dict = ReadProplistFromFile(WDRootMenu->path);
#ifdef HEARTBEAT
puts("Checking WMRootMenu domain");
#endif
if (dict) {
if (!PLIsArray(dict) && !PLIsString(dict)) {
PLRelease(dict);
dict = NULL;
wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
"WMRootMenu", WDRootMenu->path);
} else {
if (WDRootMenu->dictionary) {
PLRelease(WDRootMenu->dictionary);
}
WDRootMenu->dictionary = dict;
}
} else {
wwarning(_("could not load domain %s from user defaults database"),
"WMRootMenu");
}
WDRootMenu->timestamp = stbuf.st_mtime;
}
#endif /* !LITE */
if (!foo)
WMAddTimerHandler(DEFAULTS_CHECK_INTERVAL, wDefaultsCheckDomains, foo);
}
void
wReadDefaults(WScreen *scr, proplist_t new_dict)
{
proplist_t plvalue, old_value;
WDefaultEntry *entry;
int i, must_update;
int update_workspace_back = 0; /* kluge :/ */
int needs_refresh;
void *tdata;
proplist_t old_dict = (WDWindowMaker->dictionary!=new_dict
? WDWindowMaker->dictionary : NULL);
must_update = 0;
needs_refresh = 0;
for (i=0; i<sizeof(optionList)/sizeof(WDefaultEntry); i++) {
entry = &optionList[i];
if (new_dict)
plvalue = PLGetDictionaryEntry(new_dict, entry->plkey);
else
plvalue = NULL;
if (!old_dict)
old_value = NULL;
else
old_value = PLGetDictionaryEntry(old_dict, entry->plkey);
if (!plvalue && !old_value) {
/* no default in the DB. Use builtin default */
plvalue = entry->plvalue;
if (plvalue && new_dict) {
PLInsertDictionaryEntry(new_dict, entry->plkey, plvalue);
must_update = 1;
}
} else if (!plvalue) {
/* value was deleted from DB. Keep current value */
continue;
} else if (!old_value) {
/* set value for the 1st time */
} else if (!PLIsEqual(plvalue, old_value)) {
/* value has changed */
} else {
if (strcmp(entry->key, "WorkspaceBack") == 0
&& update_workspace_back
&& scr->flags.backimage_helper_launched) {
} else {
/* value was not changed since last time */
continue;
}
}
if (plvalue) {
#ifdef DEBUG
printf("Updating %s to %s\n", entry->key,
PLGetDescription(plvalue));
#endif
/* convert data */
if ((*entry->convert)(scr, entry, plvalue, entry->addr, &tdata)) {
/*
* If the WorkspaceSpecificBack data has been changed
* so that the helper will be launched now, we must be
* sure to send the default background texture config
* to the helper.
*/
if (strcmp(entry->key, "WorkspaceSpecificBack") == 0
&& !scr->flags.backimage_helper_launched) {
update_workspace_back = 1;
}
if (entry->update) {
needs_refresh |=
(*entry->update)(scr, entry, tdata, entry->extra_data);
}
}
}
}
if (needs_refresh!=0 && !scr->flags.startup) {
int foo;
foo = 0;
if (needs_refresh & REFRESH_MENU_TITLE_TEXTURE)
foo |= WTextureSettings;
if (needs_refresh & REFRESH_MENU_TITLE_FONT)
foo |= WFontSettings;
if (needs_refresh & REFRESH_MENU_TITLE_COLOR)
foo |= WColorSettings;
if (foo)
WMPostNotificationName(WNMenuTitleAppearanceSettingsChanged, NULL,
(void*)foo);
foo = 0;
if (needs_refresh & REFRESH_MENU_TEXTURE)
foo |= WTextureSettings;
if (needs_refresh & REFRESH_MENU_FONT)
foo |= WFontSettings;
if (needs_refresh & REFRESH_MENU_COLOR)
foo |= WColorSettings;
if (foo)
WMPostNotificationName(WNMenuAppearanceSettingsChanged, NULL,
(void*)foo);
foo = 0;
if (needs_refresh & REFRESH_WINDOW_FONT) {
foo |= WFontSettings;
}
if (needs_refresh & REFRESH_WINDOW_TEXTURES) {
foo |= WTextureSettings;
}
if (needs_refresh & REFRESH_WINDOW_TITLE_COLOR) {
foo |= WColorSettings;
}
if (foo)
WMPostNotificationName(WNWindowAppearanceSettingsChanged, NULL,
(void*)foo);
if (!(needs_refresh & REFRESH_ICON_TILE)) {
foo = 0;
if (needs_refresh & REFRESH_ICON_FONT) {
foo |= WFontSettings;
}
if (needs_refresh & REFRESH_ICON_TITLE_COLOR) {
foo |= WTextureSettings;
}
if (needs_refresh & REFRESH_ICON_TITLE_BACK) {
foo |= WTextureSettings;
}
if (foo)
WMPostNotificationName(WNIconAppearanceSettingsChanged, NULL,
(void*)foo);
}
if (needs_refresh & REFRESH_ICON_TILE)
WMPostNotificationName(WNIconTileSettingsChanged, NULL, NULL);
}
}
void
wDefaultUpdateIcons(WScreen *scr)
{
WAppIcon *aicon = scr->app_icon_list;
WWindow *wwin = scr->focused_window;
char *file;
while(aicon) {
file = wDefaultGetIconFile(scr, aicon->wm_instance, aicon->wm_class,
False);
if ((file && aicon->icon->file && strcmp(file, aicon->icon->file)!=0)
|| (file && !aicon->icon->file)) {
RImage *new_image;
if (aicon->icon->file)
free(aicon->icon->file);
aicon->icon->file = wstrdup(file);
new_image = wDefaultGetImage(scr, aicon->wm_instance,
aicon->wm_class);
if (new_image) {
wIconChangeImage(aicon->icon, new_image);
wAppIconPaint(aicon);
}
}
aicon = aicon->next;
}
if (!wPreferences.flags.noclip)
wClipIconPaint(scr->clip_icon);
while (wwin) {
if (wwin->icon && wwin->flags.miniaturized) {
file = wDefaultGetIconFile(scr, wwin->wm_instance, wwin->wm_class,
False);
if ((file && wwin->icon->file && strcmp(file, wwin->icon->file)!=0)
|| (file && !wwin->icon->file)) {
RImage *new_image;
if (wwin->icon->file)
free(wwin->icon->file);
wwin->icon->file = wstrdup(file);
new_image = wDefaultGetImage(scr, wwin->wm_instance,
wwin->wm_class);
if (new_image)
wIconChangeImage(wwin->icon, new_image);
}
}
wwin = wwin->prev;
}
}
/* --------------------------- Local ----------------------- */
#define GET_STRING_OR_DEFAULT(x, var) if (!PLIsString(value)) { \
wwarning(_("Wrong option format for key \"%s\". Should be %s."), \
entry->key, x); \
wwarning(_("using default \"%s\" instead"), entry->default_value); \
var = entry->default_value;\
} else var = PLGetString(value)\
static int
string2index(proplist_t key, proplist_t val, proplist_t def,
WOptionEnumeration *values)
{
char *str;
WOptionEnumeration *v;
char buffer[TOTAL_VALUES_LENGTH];
if (PLIsString(val) && (str = PLGetString(val))) {
for (v=values; v->string!=NULL; v++) {
if (strcasecmp(v->string, str)==0)
return v->value;
}
}
buffer[0] = 0;
for (v=values; v->string!=NULL; v++) {
if (!v->is_alias) {
if (buffer[0]!=0)
strcat(buffer, ", ");
strcat(buffer, v->string);
}
}
wwarning(_("wrong option value for key \"%s\". Should be one of %s"),
PLGetString(key), buffer);
if (def) {
return string2index(key, val, NULL, values);
}
return -1;
}
/*
* value - is the value in the defaults DB
* addr - is the address to store the data
* ret - is the address to store a pointer to a temporary buffer. ret
* must not be freed and is used by the set functions
*/
static int
getBool(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
void **ret)
{
static char data;
char *val;
int second_pass=0;
GET_STRING_OR_DEFAULT("Boolean", val);
again:
if ((val[1]=='\0' && (val[0]=='y' || val[0]=='Y'))
|| strcasecmp(val, "YES")==0) {
data = 1;
} else if ((val[1]=='\0' && (val[0]=='n' || val[0]=='N'))
|| strcasecmp(val, "NO")==0) {
data = 0;
} else {
int i;
if (sscanf(val, "%i", &i)==1) {
if (i!=0)
data = 1;
else
data = 0;
} else {
wwarning(_("can't convert \"%s\" to boolean for key \"%s\""),
val, entry->key);
if (second_pass==0) {
val = PLGetString(entry->plvalue);
second_pass = 1;
wwarning(_("using default \"%s\" instead"), val);
goto again;
}
return False;
}
}
if (ret)
*ret = &data;
if (addr) {
*(char*)addr = data;
}
return True;
}
static int
getInt(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
void **ret)
{
static int data;
char *val;
GET_STRING_OR_DEFAULT("Integer", val);
if (sscanf(val, "%i", &data)!=1) {
wwarning(_("can't convert \"%s\" to integer for key \"%s\""),
val, entry->key);
val = PLGetString(entry->plvalue);
wwarning(_("using default \"%s\" instead"), val);
if (sscanf(val, "%i", &data)!=1) {
return False;
}
}
if (ret)
*ret = &data;
if (addr) {
*(int*)addr = data;
}
return True;
}
static int
getCoord(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
void **ret)
{
static WCoord data;
char *val_x, *val_y;
int nelem, changed=0;
proplist_t elem_x, elem_y;
again:
if (!PLIsArray(value)) {
wwarning(_("Wrong option format for key \"%s\". Should be %s."),
entry->key, "Coordinate");
if (changed==0) {
value = entry->plvalue;
changed = 1;
wwarning(_("using default \"%s\" instead"), entry->default_value);
goto again;
}
return False;
}
nelem = PLGetNumberOfElements(value);
if (nelem != 2) {
wwarning(_("Incorrect number of elements in array for key \"%s\"."),
entry->key);
if (changed==0) {
value = entry->plvalue;
changed = 1;
wwarning(_("using default \"%s\" instead"), entry->default_value);
goto again;
}
return False;
}
elem_x = PLGetArrayElement(value, 0);
elem_y = PLGetArrayElement(value, 1);
if (!elem_x || !elem_y || !PLIsString(elem_x) || !PLIsString(elem_y)) {
wwarning(_("Wrong value for key \"%s\". Should be Coordinate."),
entry->key);
if (changed==0) {
value = entry->plvalue;
changed = 1;
wwarning(_("using default \"%s\" instead"), entry->default_value);
goto again;
}
return False;
}
val_x = PLGetString(elem_x);
val_y = PLGetString(elem_y);
if (sscanf(val_x, "%i", &data.x)!=1 || sscanf(val_y, "%i", &data.y)!=1) {
wwarning(_("can't convert array to integers for \"%s\"."), entry->key);
if (changed==0) {
value = entry->plvalue;
changed = 1;
wwarning(_("using default \"%s\" instead"), entry->default_value);
goto again;
}
return False;
}
if (data.x < 0)
data.x = 0;
else if (data.x > scr->scr_width/3)
data.x = scr->scr_width/3;
if (data.y < 0)
data.y = 0;
else if (data.y > scr->scr_height/3)
data.y = scr->scr_height/3;
if (ret)
*ret = &data;
if (addr) {
*(WCoord*)addr = data;
}
return True;
}
#if 0
/* This function is not used at the moment. */
static int
getString(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
void **ret)
{
static char *data;
GET_STRING_OR_DEFAULT("String", data);
if (!data) {
data = PLGetString(entry->plvalue);
if (!data)
return False;
}
if (ret)
*ret = &data;
if (addr)
*(char**)addr = wstrdup(data);
return True;
}
#endif
static int
getPathList(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
void **ret)
{
static char *data;
int i, count, len;
char *ptr;
proplist_t d;
int changed=0;
again:
if (!PLIsArray(value)) {
wwarning(_("Wrong option format for key \"%s\". Should be %s."),
entry->key, "an array of paths");
if (changed==0) {
value = entry->plvalue;
changed = 1;
wwarning(_("using default \"%s\" instead"), entry->default_value);
goto again;
}
return False;
}
i = 0;
count = PLGetNumberOfElements(value);
if (count < 1) {
if (changed==0) {
value = entry->plvalue;
changed = 1;
wwarning(_("using default \"%s\" instead"), entry->default_value);
goto again;
}
return False;
}
len = 0;
for (i=0; i<count; i++) {
d = PLGetArrayElement(value, i);
if (!d || !PLIsString(d)) {
count = i;
break;
}
len += strlen(PLGetString(d))+1;
}
ptr = data = wmalloc(len+1);
for (i=0; i<count; i++) {
d = PLGetArrayElement(value, i);
if (!d || !PLIsString(d)) {
break;
}
strcpy(ptr, PLGetString(d));
ptr += strlen(PLGetString(d));
*ptr = ':';
ptr++;
}
ptr--; *(ptr--) = 0;
if (*(char**)addr!=NULL) {
free(*(char**)addr);
}
*(char**)addr = data;
return True;
}
static int
getEnum(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
void **ret)
{
static signed char data;
data = string2index(entry->plkey, value, entry->default_value,
(WOptionEnumeration*)entry->extra_data);
if (data < 0)
return False;
if (ret)
*ret = &data;
if (addr)
*(signed char*)addr = data;
return True;
}
/*
* (solid <color>)
* (hgradient <color> <color>)
* (vgradient <color> <color>)
* (dgradient <color> <color>)
* (mhgradient <color> <color> ...)
* (mvgradient <color> <color> ...)
* (tpixmap <file> <color>)
* (spixmap <file> <color>)
* (cpixmap <file> <color>)
* (thgradient <file> <opaqueness> <color> <color>)
* (tvgradient <file> <opaqueness> <color> <color>)
* (tdgradient <file> <opaqueness> <color> <color>)
* (function <lib> <function> ...)
*/
static WTexture*
parse_texture(WScreen *scr, proplist_t pl)
{
proplist_t elem;
char *val;
int nelem;
WTexture *texture=NULL;
nelem = PLGetNumberOfElements(pl);
if (nelem < 1)
return NULL;
elem = PLGetArrayElement(pl, 0);
if (!elem || !PLIsString(elem))
return NULL;
val = PLGetString(elem);
if (strcasecmp(val, "solid")==0) {
XColor color;
if (nelem != 2)
return NULL;
/* get color */
elem = PLGetArrayElement(pl, 1);
if (!elem || !PLIsString(elem))
return NULL;
val = PLGetString(elem);
if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
wwarning(_("\"%s\" is not a valid color name"), val);
return NULL;
}
texture = (WTexture*)wTextureMakeSolid(scr, &color);
} else if (strcasecmp(val, "dgradient")==0
|| strcasecmp(val, "vgradient")==0
|| strcasecmp(val, "hgradient")==0) {
RColor color1, color2;
XColor xcolor;
int type;
if (nelem != 3) {
wwarning(_("bad number of arguments in gradient specification"));
return NULL;
}
if (val[0]=='d' || val[0]=='D')
type = WTEX_DGRADIENT;
else if (val[0]=='h' || val[0]=='H')
type = WTEX_HGRADIENT;
else
type = WTEX_VGRADIENT;
/* get from color */
elem = PLGetArrayElement(pl, 1);
if (!elem || !PLIsString(elem))
return NULL;
val = PLGetString(elem);
if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
wwarning(_("\"%s\" is not a valid color name"), val);
return NULL;
}
color1.alpha = 255;
color1.red = xcolor.red >> 8;
color1.green = xcolor.green >> 8;
color1.blue = xcolor.blue >> 8;
/* get to color */
elem = PLGetArrayElement(pl, 2);
if (!elem || !PLIsString(elem)) {
return NULL;
}
val = PLGetString(elem);
if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
wwarning(_("\"%s\" is not a valid color name"), val);
return NULL;
}
color2.alpha = 255;
color2.red = xcolor.red >> 8;
color2.green = xcolor.green >> 8;
color2.blue = xcolor.blue >> 8;
texture = (WTexture*)wTextureMakeGradient(scr, type, &color1, &color2);
} else if (strcasecmp(val, "mhgradient")==0
|| strcasecmp(val, "mvgradient")==0
|| strcasecmp(val, "mdgradient")==0) {
XColor color;
RColor **colors;
int i, count;
int type;
if (nelem < 3) {
wwarning(_("too few arguments in multicolor gradient specification"));
return NULL;
}
if (val[1]=='h' || val[1]=='H')
type = WTEX_MHGRADIENT;
else if (val[1]=='v' || val[1]=='V')
type = WTEX_MVGRADIENT;
else
type = WTEX_MDGRADIENT;
count = nelem-1;
colors = wmalloc(sizeof(RColor*)*(count+1));
for (i=0; i<count; i++) {
elem = PLGetArrayElement(pl, i+1);
if (!elem || !PLIsString(elem)) {
for (--i; i>=0; --i) {
free(colors[i]);
}
free(colors);
return NULL;
}
val = PLGetString(elem);
if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
wwarning(_("\"%s\" is not a valid color name"), val);
for (--i; i>=0; --i) {
free(colors[i]);
}
free(colors);
return NULL;
} else {
colors[i] = wmalloc(sizeof(RColor));
colors[i]->red = color.red >> 8;
colors[i]->green = color.green >> 8;
colors[i]->blue = color.blue >> 8;
}
}
colors[i] = NULL;
texture = (WTexture*)wTextureMakeMGradient(scr, type, colors);
} else if (strcasecmp(val, "spixmap")==0 ||
strcasecmp(val, "cpixmap")==0 ||
strcasecmp(val, "tpixmap")==0) {
XColor color;
int type;
if (nelem != 3)
return NULL;
if (val[0] == 's' || val[0] == 'S')
type = WTP_SCALE;
else if (val[0] == 'c' || val[0] == 'C')
type = WTP_CENTER;
else
type = WTP_TILE;
/* get color */
elem = PLGetArrayElement(pl, 2);
if (!elem || !PLIsString(elem)) {
return NULL;
}
val = PLGetString(elem);
if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
wwarning(_("\"%s\" is not a valid color name"), val);
return NULL;
}
/* file name */
elem = PLGetArrayElement(pl, 1);
if (!elem || !PLIsString(elem))
return NULL;
val = PLGetString(elem);
texture = (WTexture*)wTextureMakePixmap(scr, type, val, &color);
} else if (strcasecmp(val, "thgradient")==0
|| strcasecmp(val, "tvgradient")==0
|| strcasecmp(val, "tdgradient")==0) {
RColor color1, color2;
XColor xcolor;
int opacity;
int style;
if (val[1]=='h' || val[1]=='H')
style = WTEX_THGRADIENT;
else if (val[1]=='v' || val[1]=='V')
style = WTEX_TVGRADIENT;
else
style = WTEX_TDGRADIENT;
if (nelem != 5) {
wwarning(_("bad number of arguments in textured gradient specification"));
return NULL;
}
/* get from color */
elem = PLGetArrayElement(pl, 3);
if (!elem || !PLIsString(elem))
return NULL;
val = PLGetString(elem);
if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
wwarning(_("\"%s\" is not a valid color name"), val);
return NULL;
}
color1.alpha = 255;
color1.red = xcolor.red >> 8;
color1.green = xcolor.green >> 8;
color1.blue = xcolor.blue >> 8;
/* get to color */
elem = PLGetArrayElement(pl, 4);
if (!elem || !PLIsString(elem)) {
return NULL;
}
val = PLGetString(elem);
if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
wwarning(_("\"%s\" is not a valid color name"), val);
return NULL;
}
color2.alpha = 255;
color2.red = xcolor.red >> 8;
color2.green = xcolor.green >> 8;
color2.blue = xcolor.blue >> 8;
/* get opacity */
elem = PLGetArrayElement(pl, 2);
if (!elem || !PLIsString(elem))
opacity = 128;
else
val = PLGetString(elem);
if (!val || (opacity = atoi(val)) < 0 || opacity > 255) {
wwarning(_("bad opacity value for tgradient texture \"%s\". Should be [0..255]"), val);
opacity = 128;
}
/* get file name */
elem = PLGetArrayElement(pl, 1);
if (!elem || !PLIsString(elem))
return NULL;
val = PLGetString(elem);
texture = (WTexture*)wTextureMakeTGradient(scr, style, &color1, &color2,
val, opacity);
}
#ifdef TEXTURE_PLUGIN
else if (strcasecmp(val, "function")==0) {
WTexFunction *function;
void (*initFunc) (Display *, Colormap);
char *lib, *func, **argv;
int i, argc;
if (nelem < 3)
return NULL;
/* get the library name */
elem = PLGetArrayElement(pl, 1);
if (!elem || !PLIsString(elem)) {
return NULL;
}
lib = PLGetString(elem);
/* get the function name */
elem = PLGetArrayElement(pl, 2);
if (!elem || !PLIsString(elem)) {
return NULL;
}
func = PLGetString(elem);
argc = nelem - 2;
argv = (char **)wmalloc(argc * sizeof(char *));
/* get the parameters */
argv[0] = wstrdup(func);
for (i = 0; i < argc - 1; i++) {
elem = PLGetArrayElement(pl, 3 + i);
if (!elem || !PLIsString(elem)) {
free(argv);
return NULL;
}
argv[i+1] = wstrdup(PLGetString(elem));
}
function = wTextureMakeFunction(scr, lib, func, argc, argv);
#ifdef HAVE_DLFCN_H
if (function) {
initFunc = dlsym(function->handle, "initWindowMaker");
if (initFunc) {
initFunc(dpy, scr->w_colormap);
} else {
wwarning(_("could not initialize library %s"), lib);
}
} else {
wwarning(_("could not find function %s::%s"), lib, func);
}
#endif /* HAVE_DLFCN_H */
texture = (WTexture*)function;
}
#endif /* TEXTURE_PLUGIN */
else {
wwarning(_("invalid texture type %s"), val);
return NULL;
}
return texture;
}
static int
getTexture(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
void **ret)
{
static WTexture *texture;
int changed=0;
again:
if (!PLIsArray(value)) {
wwarning(_("Wrong option format for key \"%s\". Should be %s."),
entry->key, "Texture");
if (changed==0) {
value = entry->plvalue;
changed = 1;
wwarning(_("using default \"%s\" instead"), entry->default_value);
goto again;
}
return False;
}
if (strcmp(entry->key, "WidgetColor")==0 && !changed) {
proplist_t pl;
pl = PLGetArrayElement(value, 0);
if (!pl || !PLIsString(pl) || !PLGetString(pl)
|| strcasecmp(PLGetString(pl), "solid")!=0) {
wwarning(_("Wrong option format for key \"%s\". Should be %s."),
entry->key, "Solid Texture");
value = entry->plvalue;
changed = 1;
wwarning(_("using default \"%s\" instead"), entry->default_value);
goto again;
}
}
texture = parse_texture(scr, value);
if (!texture) {
wwarning(_("Error in texture specification for key \"%s\""),
entry->key);
if (changed==0) {
value = entry->plvalue;
changed = 1;
wwarning(_("using default \"%s\" instead"), entry->default_value);
goto again;
}
return False;
}
if (ret)
*ret = &texture;
if (addr)
*(WTexture**)addr = texture;
return True;
}
#ifdef DRAWSTRING_PLUGIN
static int
getTextRenderer(WScreen *scr, WDefaultEntry *entry, proplist_t value,
void *addr, void **ret)
{
proplist_t elem;
char *val, *lib, *func, **argv;
int argc, changed;
if (strcmp(entry->key, "FTitleColor")==0) {
wPluginDestroyFunction(scr->drawstring_func[changed = W_STRING_FTITLE]);
scr->drawstring_func[W_STRING_FTITLE] = NULL;
} else if (strcmp(entry->key, "UTitleColor")==0) {
wPluginDestroyFunction(scr->drawstring_func[changed = W_STRING_UTITLE]);
scr->drawstring_func[W_STRING_UTITLE] = NULL;
} else if (strcmp(entry->key, "PTitleColor")==0) {
wPluginDestroyFunction(scr->drawstring_func[changed = W_STRING_PTITLE]);
scr->drawstring_func[W_STRING_PTITLE] = NULL;
} else if (strcmp(entry->key, "MenuTitleColor")==0) {
wPluginDestroyFunction(scr->drawstring_func[changed = W_STRING_MTITLE]);
scr->drawstring_func[W_STRING_MTITLE] = NULL;
} else if (strcmp(entry->key, "MenuPluginColor")==0) {
wPluginDestroyFunction(scr->drawstring_func[changed = W_STRING_MTEXT]);
scr->drawstring_func[W_STRING_MTEXT] = NULL;
}
if (PLIsArray(value)) {
if ((argc = PLGetNumberOfElements(value)) < 4) return False;
argc -= 2;
argv = (char **)wmalloc(argc * sizeof(char *));
elem = PLGetArrayElement(value,0);
if (!elem || !PLIsString(elem)) return False;
val = PLGetString(elem);
if (strcasecmp(val, "function")==0) {
elem = PLGetArrayElement(value, 1); /* library name */
if (!elem || !PLIsString(elem)) return False;
lib = PLGetString(elem);
elem = PLGetArrayElement(value, 2); /* function name */
if (!elem || !PLIsString(elem)) return False;
func = PLGetString(elem);
scr->drawstring_func[changed] = wPluginCreateFunction (W_FUNCTION_DRAWSTRING,
lib, "initDrawString", func, NULL, value,
wPluginPackInitData(3, dpy, scr->w_colormap,"-DATA-"));
}
return getColor(scr, entry, PLGetArrayElement(value,3), addr, ret);
} else if (PLIsString(value)) {
return getColor(scr, entry, value, addr, ret);
}
return False;
}
#endif /* DRAWSTRING_PLUGIN */
static int
getWSBackground(WScreen *scr, WDefaultEntry *entry, proplist_t value,
void *addr, void **ret)
{
proplist_t elem;
int changed = 0;
char *val;
int nelem;
again:
if (!PLIsArray(value)) {
wwarning(_("Wrong option format for key \"%s\". Should be %s."),
"WorkspaceBack", "Texture or None");
if (changed==0) {
value = entry->plvalue;
changed = 1;
wwarning(_("using default \"%s\" instead"), entry->default_value);
goto again;
}
return False;
}
/* only do basic error checking and verify for None texture */
nelem = PLGetNumberOfElements(value);
if (nelem > 0) {
elem = PLGetArrayElement(value, 0);
if (!elem || !PLIsString(elem)) {
wwarning(_("Wrong type for workspace background. Should be a texture type."));
if (changed==0) {
value = entry->plvalue;
changed = 1;
wwarning(_("using default \"%s\" instead"), entry->default_value);
goto again;
}
return False;
}
val = PLGetString(elem);
if (strcasecmp(val, "None")==0)
return True;
}
*ret = PLRetain(value);
return True;
}
static int
getWSSpecificBackground(WScreen *scr, WDefaultEntry *entry, proplist_t value,
void *addr, void **ret)
{
proplist_t elem;
int nelem;
int changed = 0;
again:
if (!PLIsArray(value)) {
wwarning(_("Wrong option format for key \"%s\". Should be %s."),
"WorkspaceSpecificBack", "an array of textures");
if (changed==0) {
value = entry->plvalue;
changed = 1;
wwarning(_("using default \"%s\" instead"), entry->default_value);
goto again;
}
return False;
}
/* only do basic error checking and verify for None texture */
nelem = PLGetNumberOfElements(value);
if (nelem > 0) {
while (nelem--) {
elem = PLGetArrayElement(value, nelem);
if (!elem || !PLIsArray(elem)) {
wwarning(_("Wrong type for background of workspace %i. Should be a texture."),
nelem);
}
}
}
*ret = PLRetain(value);
#ifdef notworking
/*
* Kluge to force wmsetbg helper to set the default background.
* If the WorkspaceSpecificBack is changed once wmaker has started,
* the WorkspaceBack won't be sent to the helper, unless the user
* changes it's value too. So, we must force this by removing the
* value from the defaults DB.
*/
if (!scr->flags.backimage_helper_launched && !scr->flags.startup) {
proplist_t key = PLMakeString("WorkspaceBack");
PLRemoveDictionaryEntry(WDWindowMaker->dictionary, key);
PLRelease(key);
}
#endif
return True;
}
static int
getFont(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
void **ret)
{
static WMFont *font;
char *val;
GET_STRING_OR_DEFAULT("Font", val);
font = WMCreateFont(scr->wmscreen, val);
if (!font)
font = WMCreateFont(scr->wmscreen, "fixed");
if (!font) {
wfatal(_("could not load any usable font!!!"));
exit(1);
}
if (ret)
*ret = font;
/* can't assign font value outside update function */
wassertrv(addr == NULL, True);
return True;
}
static int
getColor(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
void **ret)
{
static XColor color;
char *val;
int second_pass=0;
GET_STRING_OR_DEFAULT("Color", val);
again:
if (!wGetColor(scr, val, &color)) {
wwarning(_("could not get color for key \"%s\""),
entry->key);
if (second_pass==0) {
val = PLGetString(entry->plvalue);
second_pass = 1;
wwarning(_("using default \"%s\" instead"), val);
goto again;
}
return False;
}
if (ret)
*ret = &color;
assert(addr==NULL);
/*
if (addr)
*(unsigned long*)addr = pixel;
*/
return True;
}
static int
getKeybind(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
void **ret)
{
static WShortKey shortcut;
KeySym ksym;
char *val;
char *k;
char buf[128], *b;
GET_STRING_OR_DEFAULT("Key spec", val);
if (!val || strcasecmp(val, "NONE")==0) {
shortcut.keycode = 0;
shortcut.modifier = 0;
if (ret)
*ret = &shortcut;
return True;
}
strcpy(buf, val);
b = (char*)buf;
/* get modifiers */
shortcut.modifier = 0;
while ((k = strchr(b, '+'))!=NULL) {
int mod;
*k = 0;
mod = wXModifierFromKey(b);
if (mod<0) {
wwarning(_("%s:invalid key modifier \"%s\""), entry->key, b);
return False;
}
shortcut.modifier |= mod;
b = k+1;
}
/* get key */
ksym = XStringToKeysym(b);
if (ksym==NoSymbol) {
wwarning(_("%s:invalid kbd shortcut specification \"%s\""), entry->key,
val);
return False;
}
shortcut.keycode = XKeysymToKeycode(dpy, ksym);
if (shortcut.keycode==0) {
wwarning(_("%s:invalid key in shortcut \"%s\""), entry->key, val);
return False;
}
if (ret)
*ret = &shortcut;
return True;
}
static int
getModMask(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
void **ret)
{
static unsigned int mask;
char *str;
GET_STRING_OR_DEFAULT("Modifier Key", str);
if (!str)
return False;
mask = wXModifierFromKey(str);
if (mask < 0) {
wwarning(_("%s: modifier key %s is not valid"), entry->key, str);
mask = 0;
return False;
}
if (addr)
*(unsigned int*)addr = mask;
if (ret)
*ret = &mask;
return True;
}
#ifdef NEWSTUFF
static int
getRImages(WScreen *scr, WDefaultEntry *entry, proplist_t value,
void *addr, void **ret)
{
unsigned int mask;
char *str;
RImage *image;
int i, n;
int w, h;
GET_STRING_OR_DEFAULT("Image File Path", str);
if (!str)
return False;
image = RLoadImage(scr->rcontext, str, 0);
if (!image) {
wwarning(_("could not load image in option %s: %s"), entry->key,
RMessageForError(RErrorCode));
return False;
}
if (*(RImage**)addr) {
RDestroyImage(*(RImage**)addr);
}
if (addr)
*(RImage**)addr = image;
assert(ret == NULL);
/*
if (ret)
*(RImage**)ret = image;
*/
return True;
}
#endif
/* ---------------- value setting functions --------------- */
static int
setJustify(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
{
return REFRESH_WINDOW_TITLE_COLOR;
}
static int
setIfDockPresent(WScreen *scr, WDefaultEntry *entry, int *flag, long which)
{
switch (which) {
case WM_DOCK:
wPreferences.flags.nodock = wPreferences.flags.nodock || *flag;
break;
case WM_CLIP:
wPreferences.flags.noclip = wPreferences.flags.noclip || *flag;
break;
default:
break;
}
return 0;
}
static int
setStickyIcons(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
{
if (scr->workspaces) {
wWorkspaceForceChange(scr, scr->current_workspace);
wArrangeIcons(scr, False);
}
return 0;
}
#if not_used
static int
setPositive(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
{
if (*value <= 0)
*(int*)foo = 1;
return 0;
}
#endif
static int
setIconTile(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
{
Pixmap pixmap;
RImage *img;
int reset = 0;
img = wTextureRenderImage(*texture, wPreferences.icon_size,
wPreferences.icon_size,
((*texture)->any.type & WREL_BORDER_MASK)
? WREL_ICON : WREL_FLAT);
if (!img) {
wwarning(_("could not render texture for icon background"));
if (!entry->addr)
wTextureDestroy(scr, *texture);
return 0;
}
RConvertImage(scr->rcontext, img, &pixmap);
if (scr->icon_tile) {
reset = 1;
RDestroyImage(scr->icon_tile);
XFreePixmap(dpy, scr->icon_tile_pixmap);
}
scr->icon_tile = img;
if (!wPreferences.flags.noclip) {
if (scr->clip_tile) {
RDestroyImage(scr->clip_tile);
}
scr->clip_tile = wClipMakeTile(scr, img);
}
scr->icon_tile_pixmap = pixmap;
if (scr->def_icon_pixmap) {
XFreePixmap(dpy, scr->def_icon_pixmap);
scr->def_icon_pixmap = None;
}
if (scr->def_ticon_pixmap) {
XFreePixmap(dpy, scr->def_ticon_pixmap);
scr->def_ticon_pixmap = None;
}
if (scr->icon_back_texture) {
wTextureDestroy(scr, (WTexture*)scr->icon_back_texture);
}
scr->icon_back_texture = wTextureMakeSolid(scr, &((*texture)->any.color));
if (scr->clip_balloon)
XSetWindowBackground(dpy, scr->clip_balloon,
(*texture)->any.color.pixel);
/*
* Free the texture as nobody else will use it, nor refer to it.
*/
if (!entry->addr)
wTextureDestroy(scr, *texture);
return (reset ? REFRESH_ICON_TILE : 0);
}
static int
setWinTitleFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
{
if (scr->title_font) {
WMReleaseFont(scr->title_font);
}
scr->title_font = font;
return REFRESH_WINDOW_FONT|REFRESH_BUTTON_IMAGES;
}
static int
setMenuTitleFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
{
if (scr->menu_title_font) {
WMReleaseFont(scr->menu_title_font);
}
scr->menu_title_font = font;
return REFRESH_MENU_TITLE_FONT;
}
static int
setMenuTextFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
{
if (scr->menu_entry_font) {
WMReleaseFont(scr->menu_entry_font);
}
scr->menu_entry_font = font;
return REFRESH_MENU_FONT;
}
static int
setIconTitleFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
{
if (scr->icon_title_font) {
WMReleaseFont(scr->icon_title_font);
}
scr->icon_title_font = font;
return REFRESH_ICON_FONT;
}
static int
setClipTitleFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
{
if (scr->clip_title_font) {
WMReleaseFont(scr->clip_title_font);
}
scr->clip_title_font = font;
return REFRESH_ICON_FONT;
}
static int
setDisplayFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
{
if (scr->info_text_font) {
WMReleaseFont(scr->info_text_font);
}
scr->info_text_font = font;
/* This test works because the scr structure is initially zeroed out
and None = 0. Any other time, the window should be valid. */
if (scr->geometry_display != None) {
wGetGeometryWindowSize(scr, &scr->geometry_display_width,
&scr->geometry_display_height);
XResizeWindow(dpy, scr->geometry_display,
scr->geometry_display_width, scr->geometry_display_height);
}
return 0;
}
static int
setLargeDisplayFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
{
if (scr->workspace_name_font) {
WMReleaseFont(scr->workspace_name_font);
}
scr->workspace_name_font = font;
return 0;
}
static int
setHightlight(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
{
if (scr->select_pixel!=scr->white_pixel &&
scr->select_pixel!=scr->black_pixel) {
wFreeColor(scr, scr->select_pixel);
}
scr->select_pixel = color->pixel;
return REFRESH_MENU_COLOR;
}
static int
setHightlightText(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
{
if (scr->select_text_pixel!=scr->white_pixel &&
scr->select_text_pixel!=scr->black_pixel) {
wFreeColor(scr, scr->select_text_pixel);
}
scr->select_text_pixel = color->pixel;
return REFRESH_MENU_COLOR;
}
static int
setClipTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
{
if (scr->clip_title_pixel[index]!=scr->white_pixel &&
scr->clip_title_pixel[index]!=scr->black_pixel) {
wFreeColor(scr, scr->clip_title_pixel[index]);
}
scr->clip_title_pixel[index] = color->pixel;
#ifdef GRADIENT_CLIP_ARROW
if (index == CLIP_NORMAL) {
RImage *image;
RColor color1, color2;
int pt = CLIP_BUTTON_SIZE*wPreferences.icon_size/64;
int as = pt - 15; /* 15 = 5+5+5 */
FREE_PIXMAP(scr->clip_arrow_gradient);
color1.red = (color->red >> 8)*6/10;
color1.green = (color->green >> 8)*6/10;
color1.blue = (color->blue >> 8)*6/10;
color2.red = WMIN((color->red >> 8)*20/10, 255);
color2.green = WMIN((color->green >> 8)*20/10, 255);
color2.blue = WMIN((color->blue >> 8)*20/10, 255);
image = RRenderGradient(as+1, as+1, &color1, &color2, RDiagonalGradient);
RConvertImage(scr->rcontext, image, &scr->clip_arrow_gradient);
RDestroyImage(image);
}
#endif /* GRADIENT_CLIP_ARROW */
return REFRESH_ICON_TITLE_COLOR;
}
static int
setWTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
{
if (scr->window_title_pixel[index]!=scr->white_pixel &&
scr->window_title_pixel[index]!=scr->black_pixel) {
wFreeColor(scr, scr->window_title_pixel[index]);
}
scr->window_title_pixel[index] = color->pixel;
if (index == WS_UNFOCUSED)
XSetForeground(dpy, scr->info_text_gc, color->pixel);
return REFRESH_WINDOW_TITLE_COLOR;
}
static int
setMenuTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
{
if (scr->menu_title_pixel[0]!=scr->white_pixel &&
scr->menu_title_pixel[0]!=scr->black_pixel) {
#ifdef DRAWSTRING_PLUGIN
if(!scr->drawstring_func[W_STRING_MTITLE])
#endif
wFreeColor(scr, scr->menu_title_pixel[0]);
}
scr->menu_title_pixel[0] = color->pixel;
XSetForeground(dpy, scr->menu_title_gc, color->pixel);
return REFRESH_MENU_TITLE_COLOR;
}
static int
setMenuTextColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
{
XGCValues gcv;
#define gcm (GCForeground|GCBackground|GCFillStyle)
if (scr->mtext_pixel!=scr->white_pixel &&
scr->mtext_pixel!=scr->black_pixel) {
wFreeColor(scr, scr->mtext_pixel);
}
scr->mtext_pixel = color->pixel;
XSetForeground(dpy, scr->menu_entry_gc, color->pixel);
if (scr->dtext_pixel == scr->mtext_pixel) {
gcv.foreground = scr->white_pixel;
gcv.background = scr->black_pixel;
gcv.fill_style = FillStippled;
} else {
gcv.foreground = scr->dtext_pixel;
gcv.fill_style = FillSolid;
}
XChangeGC(dpy, scr->disabled_menu_entry_gc, gcm, &gcv);
return REFRESH_MENU_COLOR;
#undef gcm
}
static int
setMenuDisabledColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
{
XGCValues gcv;
#define gcm (GCForeground|GCBackground|GCFillStyle)
if (scr->dtext_pixel!=scr->white_pixel &&
scr->dtext_pixel!=scr->black_pixel) {
wFreeColor(scr, scr->dtext_pixel);
}
scr->dtext_pixel = color->pixel;
if (scr->dtext_pixel == scr->mtext_pixel) {
gcv.foreground = scr->white_pixel;
gcv.background = scr->black_pixel;
gcv.fill_style = FillStippled;
} else {
gcv.foreground = scr->dtext_pixel;
gcv.fill_style = FillSolid;
}
XChangeGC(dpy, scr->disabled_menu_entry_gc, gcm, &gcv);
return REFRESH_MENU_COLOR;
#undef gcm
}
static int
setIconTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
{
XSetForeground(dpy, scr->icon_title_gc, color->pixel);
return REFRESH_ICON_TITLE_COLOR;
}
static int
setIconTitleBack(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
{
if (scr->icon_title_texture) {
wTextureDestroy(scr, (WTexture*)scr->icon_title_texture);
}
XQueryColor (dpy, scr->w_colormap, color);
scr->icon_title_texture = wTextureMakeSolid(scr, color);
return REFRESH_ICON_TITLE_BACK;
}
static void
trackDeadProcess(pid_t pid, unsigned char status, WScreen *scr)
{
close(scr->helper_fd);
scr->helper_fd = 0;
scr->helper_pid = 0;
scr->flags.backimage_helper_launched = 0;
}
static int
setWorkspaceSpecificBack(WScreen *scr, WDefaultEntry *entry, proplist_t value,
void *bar)
{
int i;
proplist_t val;
char *str;
if (scr->flags.backimage_helper_launched) {
if (PLGetNumberOfElements(value)==0) {
SendHelperMessage(scr, 'C', 0, NULL);
SendHelperMessage(scr, 'K', 0, NULL);
PLRelease(value);
return 0;
}
} else {
pid_t pid;
int filedes[2];
if (PLGetNumberOfElements(value) == 0)
return 0;
if (pipe(filedes) < 0) {
wsyserror("pipe() failed:can't set workspace specific background image");
PLRelease(value);
return 0;
}
pid = fork();
if (pid < 0) {
wsyserror("fork() failed:can't set workspace specific background image");
if (close(filedes[0]) < 0)
wsyserror("could not close pipe");
if (close(filedes[1]) < 0)
wsyserror("could not close pipe");
} else if (pid == 0) {
SetupEnvironment(scr);
if (close(0) < 0)
wsyserror("could not close pipe");
if (dup(filedes[0]) < 0) {
wsyserror("dup() failed:can't set workspace specific background image");
}
if (wPreferences.smooth_workspace_back)
execlp("wmsetbg", "wmsetbg", "-helper", "-S", "-d", NULL);
else
execlp("wmsetbg", "wmsetbg", "-helper", "-d", NULL);
wsyserror("could not execute wmsetbg");
exit(1);
} else {
if (fcntl(filedes[0], F_SETFD, FD_CLOEXEC) < 0) {
wsyserror("error setting close-on-exec flag");
}
if (fcntl(filedes[1], F_SETFD, FD_CLOEXEC) < 0) {
wsyserror("error setting close-on-exec flag");
}
scr->helper_fd = filedes[1];
scr->helper_pid = pid;
scr->flags.backimage_helper_launched = 1;
wAddDeathHandler(pid, (WDeathHandler*)trackDeadProcess, scr);
SendHelperMessage(scr, 'P', -1, wPreferences.pixmap_path);
}
}
for (i = 0; i < PLGetNumberOfElements(value); i++) {
val = PLGetArrayElement(value, i);
if (val && PLIsArray(val) && PLGetNumberOfElements(val)>0) {
str = PLGetDescription(val);
SendHelperMessage(scr, 'S', i+1, str);
free(str);
} else {
SendHelperMessage(scr, 'U', i+1, NULL);
}
}
sleep(1);
PLRelease(value);
return 0;
}
static int
setWorkspaceBack(WScreen *scr, WDefaultEntry *entry, proplist_t value,
void *bar)
{
if (scr->flags.backimage_helper_launched) {
char *str;
if (PLGetNumberOfElements(value)==0) {
SendHelperMessage(scr, 'U', 0, NULL);
} else {
/* set the default workspace background to this one */
str = PLGetDescription(value);
if (str) {
SendHelperMessage(scr, 'S', 0, str);
free(str);
SendHelperMessage(scr, 'C', scr->current_workspace+1, NULL);
} else {
SendHelperMessage(scr, 'U', 0, NULL);
}
}
} else {
char *command;
char *text;
SetupEnvironment(scr);
text = PLGetDescription(value);
command = wmalloc(strlen(text)+40);
if (wPreferences.smooth_workspace_back)
sprintf(command, "wmsetbg -d -S -p '%s' &", text);
else
sprintf(command, "wmsetbg -d -p '%s' &", text);
free(text);
system(command);
free(command);
}
PLRelease(value);
return 0;
}
static int
setWidgetColor(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
{
if (scr->widget_texture) {
wTextureDestroy(scr, (WTexture*)scr->widget_texture);
}
scr->widget_texture = *(WTexSolid**)texture;
if (scr->geometry_display != None)
XSetWindowBackground(dpy, scr->geometry_display,
scr->widget_texture->normal.pixel);
return 0;
}
static int
setFTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
{
if (scr->window_title_texture[WS_FOCUSED]) {
wTextureDestroy(scr, scr->window_title_texture[WS_FOCUSED]);
}
scr->window_title_texture[WS_FOCUSED] = *texture;
return REFRESH_WINDOW_TEXTURES;
}
static int
setPTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
{
if (scr->window_title_texture[WS_PFOCUSED]) {
wTextureDestroy(scr, scr->window_title_texture[WS_PFOCUSED]);
}
scr->window_title_texture[WS_PFOCUSED] = *texture;
return REFRESH_WINDOW_TEXTURES;
}
static int
setUTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
{
if (scr->window_title_texture[WS_UNFOCUSED]) {
wTextureDestroy(scr, scr->window_title_texture[WS_UNFOCUSED]);
}
scr->window_title_texture[WS_UNFOCUSED] = *texture;
return REFRESH_WINDOW_TEXTURES;
}
static int
setResizebarBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
{
if (scr->resizebar_texture[0]) {
wTextureDestroy(scr, scr->resizebar_texture[0]);
}
scr->resizebar_texture[0] = *texture;
return REFRESH_WINDOW_TEXTURES;
}
static int
setMenuTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
{
if (scr->menu_title_texture[0]) {
wTextureDestroy(scr, scr->menu_title_texture[0]);
}
scr->menu_title_texture[0] = *texture;
return REFRESH_MENU_TITLE_TEXTURE;
}
static int
setMenuTextBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
{
if (scr->menu_item_texture) {
wTextureDestroy(scr, scr->menu_item_texture);
wTextureDestroy(scr, (WTexture*)scr->menu_item_auxtexture);
}
scr->menu_item_texture = *texture;
scr->menu_item_auxtexture
= wTextureMakeSolid(scr, &scr->menu_item_texture->any.color);
return REFRESH_MENU_TEXTURE;
}
static int
setKeyGrab(WScreen *scr, WDefaultEntry *entry, WShortKey *shortcut, long index)
{
WWindow *wwin;
wKeyBindings[index] = *shortcut;
wwin = scr->focused_window;
while (wwin!=NULL) {
XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
if (!WFLAGP(wwin, no_bind_keys)) {
wWindowSetKeyGrabs(wwin);
}
wwin = wwin->prev;
}
return 0;
}
static int
setIconPosition(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
{
wArrangeIcons(scr, True);
return 0;
}
static int
updateUsableArea(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
{
wScreenUpdateUsableArea(scr);
return 0;
}
static int
setMenuStyle(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
{
return REFRESH_MENU_TEXTURE;
}
/*
static int
setButtonImages(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
{
return REFRESH_BUTTON_IMAGES;
}
*/
/*
* Very ugly kluge.
* Need access to the double click variables, so that all widgets in
* wmaker panels will have the same dbl-click values.
* TODO: figure a better way of dealing with it.
*/
#include "WINGsP.h"
static int
setDoubleClick(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
{
extern _WINGsConfiguration WINGsConfiguration;
if (*value <= 0)
*(int*)foo = 1;
WINGsConfiguration.doubleClickDelay = *value;
return 0;
}
static int
setMultiByte(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
{
extern _WINGsConfiguration WINGsConfiguration;
WINGsConfiguration.useMultiByte = *value;
return 0;
}