10bbfda8aSnia/*
20bbfda8aSnia * Parser backend routines.
30bbfda8aSnia *
40bbfda8aSnia * Roughly, these are the routines that the lex/yacc output calls to do
50bbfda8aSnia * its work.
60bbfda8aSnia *
70bbfda8aSnia * This is very similar to the meaning of parse_yacc.c; the two may be
80bbfda8aSnia * merged at some point.
90bbfda8aSnia */
100bbfda8aSnia
110bbfda8aSnia#include "ctwm.h"
120bbfda8aSnia
130bbfda8aSnia#include <stdio.h>
140bbfda8aSnia#include <stdlib.h>
150bbfda8aSnia#include <string.h>
160bbfda8aSnia#include <strings.h>
170bbfda8aSnia
180bbfda8aSnia#include <X11/Xatom.h>
190bbfda8aSnia
200bbfda8aSnia#include "ctwm_atoms.h"
210bbfda8aSnia#include "screen.h"
220bbfda8aSnia#include "util.h"
230bbfda8aSnia#include "animate.h"
240bbfda8aSnia#include "functions_defs.h"
250bbfda8aSnia#include "image.h"
260bbfda8aSnia#include "list.h"
270bbfda8aSnia#include "occupation.h"
280bbfda8aSnia#include "parse.h"
290bbfda8aSnia#include "parse_be.h"
300bbfda8aSnia#include "parse_yacc.h"
31b18c2d1eSnia#include "r_area.h"
32b18c2d1eSnia#include "r_area_list.h"
33b18c2d1eSnia#include "r_layout.h"
340bbfda8aSnia#ifdef SOUNDS
350bbfda8aSnia#  include "sound.h"
360bbfda8aSnia#endif
370bbfda8aSnia
380bbfda8aSnia#include "gram.tab.h"
390bbfda8aSnia
400bbfda8aSnia
410bbfda8aSniastatic int ParseRandomPlacement(const char *s);
420bbfda8aSniastatic int ParseButtonStyle(const char *s);
430bbfda8aSniastatic int ParseUsePPosition(const char *s);
440bbfda8aSniastatic int ParseIconifyStyle(const char *s);
450bbfda8aSnia
460bbfda8aSnia
470bbfda8aSnia
480bbfda8aSnia/**********************************************************************
490bbfda8aSnia *
500bbfda8aSnia *  Parsing table and routines
510bbfda8aSnia *
520bbfda8aSnia ***********************************************************************/
530bbfda8aSnia
540bbfda8aSniatypedef struct _TwmKeyword {
550bbfda8aSnia	const char *name;
560bbfda8aSnia	int value;
570bbfda8aSnia	int subnum;
580bbfda8aSnia} TwmKeyword;
590bbfda8aSnia
600bbfda8aSnia#define kw0_NoDefaults                  1
610bbfda8aSnia#define kw0_AutoRelativeResize          2
620bbfda8aSnia#define kw0_ForceIcons                  3
630bbfda8aSnia#define kw0_NoIconManagers              4
640bbfda8aSnia#define kw0_InterpolateMenuColors       6
650bbfda8aSnia//#define kw0_NoVersion                 7
660bbfda8aSnia#define kw0_SortIconManager             8
670bbfda8aSnia#define kw0_NoGrabServer                9
680bbfda8aSnia#define kw0_NoMenuShadows               10
690bbfda8aSnia#define kw0_NoRaiseOnMove               11
700bbfda8aSnia#define kw0_NoRaiseOnResize             12
710bbfda8aSnia#define kw0_NoRaiseOnDeiconify          13
720bbfda8aSnia#define kw0_DontMoveOff                 14
730bbfda8aSnia#define kw0_NoBackingStore              15
740bbfda8aSnia#define kw0_NoSaveUnders                16
750bbfda8aSnia#define kw0_RestartPreviousState        17
760bbfda8aSnia#define kw0_ClientBorderWidth           18
770bbfda8aSnia#define kw0_NoTitleFocus                19
780bbfda8aSnia#define kw0_DecorateTransients          21
790bbfda8aSnia#define kw0_ShowIconManager             22
800bbfda8aSnia#define kw0_NoCaseSensitive             23
810bbfda8aSnia#define kw0_NoRaiseOnWarp               24
820bbfda8aSnia#define kw0_WarpUnmapped                25
830bbfda8aSnia#define kw0_ShowWorkspaceManager        27
840bbfda8aSnia#define kw0_StartInMapState             28
850bbfda8aSnia#define kw0_NoShowOccupyAll             29
860bbfda8aSnia#define kw0_AutoOccupy                  30
870bbfda8aSnia#define kw0_TransientHasOccupation      31
880bbfda8aSnia#define kw0_DontPaintRootWindow         32
890bbfda8aSnia#define kw0_Use3DMenus                  33
900bbfda8aSnia#define kw0_Use3DTitles                 34
910bbfda8aSnia#define kw0_Use3DIconManagers           35
920bbfda8aSnia#define kw0_Use3DBorders                36
930bbfda8aSnia#define kw0_SunkFocusWindowTitle        37
940bbfda8aSnia#define kw0_BeNiceToColormap            38
950bbfda8aSnia#define kw0_WarpRingOnScreen            40
960bbfda8aSnia#define kw0_NoIconManagerFocus          41
970bbfda8aSnia#define kw0_StayUpMenus                 42
980bbfda8aSnia#define kw0_ClickToFocus                43
990bbfda8aSnia#define kw0_BorderResizeCursors         44
1000bbfda8aSnia#define kw0_ReallyMoveInWorkspaceManager 45
1010bbfda8aSnia#define kw0_ShowWinWhenMovingInWmgr     46
1020bbfda8aSnia#define kw0_Use3DWMap                   47
1030bbfda8aSnia#define kw0_ReverseCurrentWorkspace     48
1040bbfda8aSnia#define kw0_DontWarpCursorInWMap        49
1050bbfda8aSnia#define kw0_CenterFeedbackWindow        50
1060bbfda8aSnia#define kw0_WarpToDefaultMenuEntry      51
1070bbfda8aSnia#define kw0_ShrinkIconTitles            52
1080bbfda8aSnia#define kw0_AutoRaiseIcons              53
1090bbfda8aSnia//#define kw0_use3DIconBorders            54
1100bbfda8aSnia#define kw0_UseSunkTitlePixmap          55
1110bbfda8aSnia#define kw0_ShortAllWindowsMenus        56
1120bbfda8aSnia#define kw0_RaiseWhenAutoUnSqueeze      57
1130bbfda8aSnia#define kw0_RaiseOnClick                58
1140bbfda8aSnia#define kw0_IgnoreLockModifier          59
1150bbfda8aSnia#define kw0_AutoFocusToTransients       60 /* kai */
1160bbfda8aSnia#define kw0_PackNewWindows              61
1170bbfda8aSnia#define kw0_IgnoreCaseInMenuSelection   62
1180bbfda8aSnia#define kw0_SloppyFocus                 63
1190bbfda8aSnia#define kw0_NoImagesInWorkSpaceManager  64
1200bbfda8aSnia#define kw0_NoWarpToMenuTitle           65
1210bbfda8aSnia#define kw0_SaveWorkspaceFocus          66 /* blais */
1220bbfda8aSnia#define kw0_RaiseOnWarp                 67
1230bbfda8aSnia#define kw0_DontShowWelcomeWindow       68
1240bbfda8aSnia#define kw0_AutoPriority                69
1250bbfda8aSnia#define kw0_DontToggleWorkspacemanagerState 70
1260bbfda8aSnia#define kw0_BackingStore                71
1270bbfda8aSnia#define kw0_StartInButtonState          72
1280bbfda8aSnia#define kw0_NoSortIconManager           73
1290bbfda8aSnia#define kw0_NoRestartPreviousState      74
1300bbfda8aSnia#define kw0_NoDecorateTransients        75
1310bbfda8aSnia#define kw0_GrabServer                  76
1320bbfda8aSnia#define kw0_DontNameDecorations         77
1330bbfda8aSnia#define kw0_StrictWinNameEncoding       78
1340bbfda8aSnia
1350bbfda8aSnia#define kws_UsePPosition                1
1360bbfda8aSnia#define kws_IconFont                    2
1370bbfda8aSnia#define kws_ResizeFont                  3
1380bbfda8aSnia#define kws_MenuFont                    4
1390bbfda8aSnia#define kws_TitleFont                   5
1400bbfda8aSnia#define kws_IconManagerFont             6
1410bbfda8aSnia#define kws_UnknownIcon                 7
1420bbfda8aSnia#define kws_IconDirectory               8
1430bbfda8aSnia#define kws_MaxWindowSize               9
1440bbfda8aSnia#define kws_PixmapDirectory             10
1450bbfda8aSnia/* RandomPlacement moved because it's now a string string keyword */
1460bbfda8aSnia#define kws_IconJustification           12
1470bbfda8aSnia#define kws_TitleJustification          13
1480bbfda8aSnia#define kws_IconRegionJustification     14
1490bbfda8aSnia#define kws_IconRegionAlignement        15
1500bbfda8aSnia#define kws_SoundHost                   16
1510bbfda8aSnia#define kws_WMgrButtonStyle             17
1520bbfda8aSnia#define kws_WorkSpaceFont               18
1530bbfda8aSnia#define kws_IconifyStyle                19
1540bbfda8aSnia#define kws_IconSize                    20
1550bbfda8aSnia#define kws_RplaySoundHost              21
1560bbfda8aSnia
1570bbfda8aSnia#define kwss_RandomPlacement            1
1580bbfda8aSnia
1590bbfda8aSnia#define kwn_ConstrainedMoveTime         1
1600bbfda8aSnia#define kwn_MoveDelta                   2
1610bbfda8aSnia#define kwn_XorValue                    3
1620bbfda8aSnia#define kwn_FramePadding                4
1630bbfda8aSnia#define kwn_TitlePadding                5
1640bbfda8aSnia#define kwn_ButtonIndent                6
1650bbfda8aSnia#define kwn_BorderWidth                 7
1660bbfda8aSnia#define kwn_IconBorderWidth             8
1670bbfda8aSnia#define kwn_TitleButtonBorderWidth      9
1680bbfda8aSnia#define kwn_RaiseDelay                  10
1690bbfda8aSnia#define kwn_TransientOnTop              11
1700bbfda8aSnia#define kwn_OpaqueMoveThreshold         12
1710bbfda8aSnia#define kwn_OpaqueResizeThreshold       13
1720bbfda8aSnia#define kwn_WMgrVertButtonIndent        14
1730bbfda8aSnia#define kwn_WMgrHorizButtonIndent       15
1740bbfda8aSnia#define kwn_ClearShadowContrast         16
1750bbfda8aSnia#define kwn_DarkShadowContrast          17
1760bbfda8aSnia#define kwn_WMgrButtonShadowDepth       18
1770bbfda8aSnia#define kwn_MaxIconTitleWidth           19
1780bbfda8aSnia#define kwn_AnimationSpeed              20
1790bbfda8aSnia#define kwn_ThreeDBorderWidth           21
1800bbfda8aSnia#define kwn_MoveOffResistance           22
1810bbfda8aSnia#define kwn_BorderShadowDepth           23
1820bbfda8aSnia#define kwn_TitleShadowDepth            24
1830bbfda8aSnia#define kwn_TitleButtonShadowDepth      25
1840bbfda8aSnia#define kwn_MenuShadowDepth             26
1850bbfda8aSnia#define kwn_IconManagerShadowDepth      27
1860bbfda8aSnia#define kwn_MovePackResistance          28
1870bbfda8aSnia#define kwn_XMoveGrid                   29
1880bbfda8aSnia#define kwn_YMoveGrid                   30
1890bbfda8aSnia#define kwn_OpenWindowTimeout           31
1900bbfda8aSnia#define kwn_RaiseOnClickButton          32
1910bbfda8aSnia
1920bbfda8aSnia#define kwn_BorderTop                   33
1930bbfda8aSnia#define kwn_BorderBottom                34
1940bbfda8aSnia#define kwn_BorderLeft                  35
1950bbfda8aSnia#define kwn_BorderRight                 36
1960bbfda8aSnia
1970bbfda8aSnia#define kwcl_BorderColor                1
1980bbfda8aSnia#define kwcl_IconManagerHighlight       2
1990bbfda8aSnia#define kwcl_BorderTileForeground       3
2000bbfda8aSnia#define kwcl_BorderTileBackground       4
2010bbfda8aSnia#define kwcl_TitleForeground            5
2020bbfda8aSnia#define kwcl_TitleBackground            6
2030bbfda8aSnia#define kwcl_IconForeground             7
2040bbfda8aSnia#define kwcl_IconBackground             8
2050bbfda8aSnia#define kwcl_IconBorderColor            9
2060bbfda8aSnia#define kwcl_IconManagerForeground      10
2070bbfda8aSnia#define kwcl_IconManagerBackground      11
2080bbfda8aSnia#define kwcl_MapWindowBackground        12
2090bbfda8aSnia#define kwcl_MapWindowForeground        13
2100bbfda8aSnia
2110bbfda8aSnia#define kwc_DefaultForeground           1
2120bbfda8aSnia#define kwc_DefaultBackground           2
2130bbfda8aSnia#define kwc_MenuForeground              3
2140bbfda8aSnia#define kwc_MenuBackground              4
2150bbfda8aSnia#define kwc_MenuTitleForeground         5
2160bbfda8aSnia#define kwc_MenuTitleBackground         6
2170bbfda8aSnia#define kwc_MenuShadowColor             7
2180bbfda8aSnia
2190bbfda8aSnia
2200bbfda8aSnia/*
2210bbfda8aSnia * The following is sorted alphabetically according to name (which must be
2220bbfda8aSnia * in lowercase and only contain the letters a-z).  It is fed to a binary
2230bbfda8aSnia * search to parse keywords.
2240bbfda8aSnia */
2250bbfda8aSniastatic const TwmKeyword keytable[] = {
2260bbfda8aSnia	{ "a",                      ALTER, 0 },
2270bbfda8aSnia	{ "all",                    ALL, 0 },
2280bbfda8aSnia	{ "alter",                  ALTER, 0 },
2290bbfda8aSnia	{ "alwaysontop",            ALWAYS_ON_TOP, 0 },
2300bbfda8aSnia	{ "alwaysshowwindowwhenmovingfromworkspacemanager", KEYWORD, kw0_ShowWinWhenMovingInWmgr },
2310bbfda8aSnia	{ "alwayssqueezetogravity", ALWAYSSQUEEZETOGRAVITY, 0 },
2320bbfda8aSnia	{ "animationspeed",         NKEYWORD, kwn_AnimationSpeed },
2330bbfda8aSnia	{ "autofocustotransients",  KEYWORD, kw0_AutoFocusToTransients }, /* kai */
2340bbfda8aSnia	{ "autolower",              AUTO_LOWER, 0 },
2350bbfda8aSnia	{ "autooccupy",             KEYWORD, kw0_AutoOccupy },
2360bbfda8aSnia	{ "autopopup",              AUTO_POPUP, 0 },
2370bbfda8aSnia	{ "autopriority",           KEYWORD, kw0_AutoPriority },
2380bbfda8aSnia	{ "autoraise",              AUTO_RAISE, 0 },
2390bbfda8aSnia	{ "autoraiseicons",         KEYWORD, kw0_AutoRaiseIcons },
2400bbfda8aSnia	{ "autorelativeresize",     KEYWORD, kw0_AutoRelativeResize },
2410bbfda8aSnia	{ "autosqueeze",            AUTOSQUEEZE, 0 },
2420bbfda8aSnia	{ "backingstore",           KEYWORD, kw0_BackingStore },
2430bbfda8aSnia	{ "benicetocolormap",       KEYWORD, kw0_BeNiceToColormap },
2440bbfda8aSnia	{ "borderbottom",           NKEYWORD, kwn_BorderBottom },
2450bbfda8aSnia	{ "bordercolor",            CLKEYWORD, kwcl_BorderColor },
2460bbfda8aSnia	{ "borderleft",             NKEYWORD, kwn_BorderLeft },
2470bbfda8aSnia	{ "borderresizecursors",    KEYWORD, kw0_BorderResizeCursors },
2480bbfda8aSnia	{ "borderright",            NKEYWORD, kwn_BorderRight },
2490bbfda8aSnia	{ "bordershadowdepth",      NKEYWORD, kwn_BorderShadowDepth },
2500bbfda8aSnia	{ "bordertilebackground",   CLKEYWORD, kwcl_BorderTileBackground },
2510bbfda8aSnia	{ "bordertileforeground",   CLKEYWORD, kwcl_BorderTileForeground },
2520bbfda8aSnia	{ "bordertop",              NKEYWORD, kwn_BorderTop },
2530bbfda8aSnia	{ "borderwidth",            NKEYWORD, kwn_BorderWidth },
2540bbfda8aSnia	{ "button",                 BUTTON, 0 },
2550bbfda8aSnia	{ "buttonindent",           NKEYWORD, kwn_ButtonIndent },
2560bbfda8aSnia	{ "c",                      CONTROL, 0 },
2570bbfda8aSnia	{ "center",                 SIJENUM, SIJ_CENTER },
2580bbfda8aSnia	{ "centerfeedbackwindow",   KEYWORD, kw0_CenterFeedbackWindow },
2590bbfda8aSnia	{ "changeworkspacefunction", CHANGE_WORKSPACE_FUNCTION, 0 },
2600bbfda8aSnia	{ "clearshadowcontrast",    NKEYWORD, kwn_ClearShadowContrast },
2610bbfda8aSnia	{ "clicktofocus",           KEYWORD, kw0_ClickToFocus },
2620bbfda8aSnia	{ "clientborderwidth",      KEYWORD, kw0_ClientBorderWidth },
2630bbfda8aSnia	{ "color",                  COLOR, 0 },
2640bbfda8aSnia	{ "constrainedmovetime",    NKEYWORD, kwn_ConstrainedMoveTime },
2650bbfda8aSnia	{ "control",                CONTROL, 0 },
2660bbfda8aSnia	{ "cursors",                CURSORS, 0 },
2670bbfda8aSnia	{ "darkshadowcontrast",     NKEYWORD, kwn_DarkShadowContrast },
2680bbfda8aSnia	{ "decoratetransients",     KEYWORD, kw0_DecorateTransients },
2690bbfda8aSnia	{ "defaultbackground",      CKEYWORD, kwc_DefaultBackground },
2700bbfda8aSnia	{ "defaultforeground",      CKEYWORD, kwc_DefaultForeground },
2710bbfda8aSnia	{ "defaultfunction",        DEFAULT_FUNCTION, 0 },
2720bbfda8aSnia	{ "deiconifyfunction",      DEICONIFY_FUNCTION, 0 },
2730bbfda8aSnia	{ "destroy",                KILL, 0 },
2740bbfda8aSnia	{ "donticonifybyunmapping", DONT_ICONIFY_BY_UNMAPPING, 0 },
2750bbfda8aSnia	{ "dontmoveoff",            KEYWORD, kw0_DontMoveOff },
2760bbfda8aSnia	{ "dontnamedecorations",    KEYWORD, kw0_DontNameDecorations },
2770bbfda8aSnia	{ "dontpaintrootwindow",    KEYWORD, kw0_DontPaintRootWindow },
2780bbfda8aSnia	{ "dontsave",               DONT_SAVE, 0 },
2790bbfda8aSnia	{ "dontsetinactive",        DONTSETINACTIVE, 0 },
2800bbfda8aSnia	{ "dontshowwelcomewindow",  KEYWORD, kw0_DontShowWelcomeWindow },
2810bbfda8aSnia	{ "dontsqueezetitle",       DONT_SQUEEZE_TITLE, 0 },
2820bbfda8aSnia	{ "donttoggleworkspacemanagerstate", KEYWORD, kw0_DontToggleWorkspacemanagerState},
2830bbfda8aSnia	{ "dontwarpcursorinwmap",   KEYWORD, kw0_DontWarpCursorInWMap },
2840bbfda8aSnia	{ "east",                   GRAVITY, GRAV_EAST },
2850bbfda8aSnia	{ "ewmhignore",             EWMH_IGNORE, 0 },
2860bbfda8aSnia	{ "f",                      FRAME, 0 },
2870bbfda8aSnia	{ "forcefocus",             FORCE_FOCUS, 0 },
2880bbfda8aSnia	{ "forceicons",             KEYWORD, kw0_ForceIcons },
2890bbfda8aSnia	{ "frame",                  FRAME, 0 },
2900bbfda8aSnia	{ "framepadding",           NKEYWORD, kwn_FramePadding },
2910bbfda8aSnia	{ "function",               FUNCTION, 0 },
2920bbfda8aSnia	{ "grabserver",             KEYWORD, kw0_GrabServer },
2930bbfda8aSnia	{ "i",                      ICON, 0 },
2940bbfda8aSnia	{ "icon",                   ICON, 0 },
2950bbfda8aSnia	{ "iconbackground",         CLKEYWORD, kwcl_IconBackground },
2960bbfda8aSnia	{ "iconbordercolor",        CLKEYWORD, kwcl_IconBorderColor },
2970bbfda8aSnia	{ "iconborderwidth",        NKEYWORD, kwn_IconBorderWidth },
2980bbfda8aSnia	{ "icondirectory",          SKEYWORD, kws_IconDirectory },
2990bbfda8aSnia	{ "iconfont",               SKEYWORD, kws_IconFont },
3000bbfda8aSnia	{ "iconforeground",         CLKEYWORD, kwcl_IconForeground },
3010bbfda8aSnia	{ "iconifybyunmapping",     ICONIFY_BY_UNMAPPING, 0 },
3020bbfda8aSnia	{ "iconifyfunction",        ICONIFY_FUNCTION, 0 },
3030bbfda8aSnia	{ "iconifystyle",           SKEYWORD, kws_IconifyStyle },
3040bbfda8aSnia	{ "iconjustification",      SKEYWORD, kws_IconJustification },
3050bbfda8aSnia	{ "iconmanagerbackground",  CLKEYWORD, kwcl_IconManagerBackground },
3060bbfda8aSnia	{ "iconmanagerdontshow",    ICONMGR_NOSHOW, 0 },
3070bbfda8aSnia	{ "iconmanagerfont",        SKEYWORD, kws_IconManagerFont },
3080bbfda8aSnia	{ "iconmanagerforeground",  CLKEYWORD, kwcl_IconManagerForeground },
3090bbfda8aSnia	{ "iconmanagergeometry",    ICONMGR_GEOMETRY, 0 },
3100bbfda8aSnia	{ "iconmanagerhighlight",   CLKEYWORD, kwcl_IconManagerHighlight },
3110bbfda8aSnia	{ "iconmanagers",           ICONMGRS, 0 },
3120bbfda8aSnia	{ "iconmanagershadowdepth", NKEYWORD, kwn_IconManagerShadowDepth },
3130bbfda8aSnia	{ "iconmanagershow",        ICONMGR_SHOW, 0 },
3140bbfda8aSnia	{ "iconmenudontshow",       ICONMENU_DONTSHOW, 0 },
3150bbfda8aSnia	{ "iconmgr",                ICONMGR, 0 },
3160bbfda8aSnia	{ "iconregion",             ICON_REGION, 0 },
3170bbfda8aSnia	{ "iconregionalignement",   SKEYWORD, kws_IconRegionAlignement },
3180bbfda8aSnia	{ "iconregionjustification", SKEYWORD, kws_IconRegionJustification },
3190bbfda8aSnia	{ "icons",                  ICONS, 0 },
3200bbfda8aSnia	{ "iconsize",               SKEYWORD, kws_IconSize },
3210bbfda8aSnia	{ "ignorecaseinmenuselection",      KEYWORD, kw0_IgnoreCaseInMenuSelection },
3220bbfda8aSnia	{ "ignorelockmodifier",     KEYWORD, kw0_IgnoreLockModifier },
3230bbfda8aSnia	{ "ignoremodifier",         IGNOREMODIFIER, 0 },
3240bbfda8aSnia	{ "ignoretransient",        IGNORE_TRANSIENT, 0 },
3250bbfda8aSnia	{ "interpolatemenucolors",  KEYWORD, kw0_InterpolateMenuColors },
3260bbfda8aSnia	{ "l",                      LOCK, 0 },
3270bbfda8aSnia	{ "left",                   SIJENUM, SIJ_LEFT },
3280bbfda8aSnia	{ "lefttitlebutton",        LEFT_TITLEBUTTON, 0 },
3290bbfda8aSnia	{ "lock",                   LOCK, 0 },
3300bbfda8aSnia	{ "m",                      META, 0 },
3310bbfda8aSnia	{ "maketitle",              MAKE_TITLE, 0 },
3320bbfda8aSnia	{ "mapwindowbackground",    CLKEYWORD, kwcl_MapWindowBackground },
3330bbfda8aSnia	{ "mapwindowcurrentworkspace", MAPWINDOWCURRENTWORKSPACE, 0},
3340bbfda8aSnia	{ "mapwindowdefaultworkspace", MAPWINDOWDEFAULTWORKSPACE, 0},
3350bbfda8aSnia	{ "mapwindowforeground",    CLKEYWORD, kwcl_MapWindowForeground },
3360bbfda8aSnia	{ "maxicontitlewidth",      NKEYWORD, kwn_MaxIconTitleWidth },
3370bbfda8aSnia	{ "maxwindowsize",          SKEYWORD, kws_MaxWindowSize },
3380bbfda8aSnia	{ "menu",                   MENU, 0 },
3390bbfda8aSnia	{ "menubackground",         CKEYWORD, kwc_MenuBackground },
3400bbfda8aSnia	{ "menufont",               SKEYWORD, kws_MenuFont },
3410bbfda8aSnia	{ "menuforeground",         CKEYWORD, kwc_MenuForeground },
3420bbfda8aSnia	{ "menushadowcolor",        CKEYWORD, kwc_MenuShadowColor },
3430bbfda8aSnia	{ "menushadowdepth",        NKEYWORD, kwn_MenuShadowDepth },
3440bbfda8aSnia	{ "menutitlebackground",    CKEYWORD, kwc_MenuTitleBackground },
3450bbfda8aSnia	{ "menutitleforeground",    CKEYWORD, kwc_MenuTitleForeground },
3460bbfda8aSnia	{ "meta",                   META, 0 },
3470bbfda8aSnia	{ "mod",                    META, 0 },  /* fake it */
348b18c2d1eSnia	{ "monitorlayout",          MONITOR_LAYOUT, 0 },
3490bbfda8aSnia	{ "monochrome",             MONOCHROME, 0 },
3500bbfda8aSnia	{ "move",                   MOVE, 0 },
3510bbfda8aSnia	{ "movedelta",              NKEYWORD, kwn_MoveDelta },
3520bbfda8aSnia	{ "moveoffresistance",      NKEYWORD, kwn_MoveOffResistance },
3530bbfda8aSnia	{ "movepackresistance",     NKEYWORD, kwn_MovePackResistance },
3540bbfda8aSnia	{ "mwmignore",              MWM_IGNORE, 0 },
3550bbfda8aSnia	{ "nobackingstore",         KEYWORD, kw0_NoBackingStore },
3560bbfda8aSnia	{ "noborder",               NO_BORDER, 0 },
3570bbfda8aSnia	{ "nocasesensitive",        KEYWORD, kw0_NoCaseSensitive },
3580bbfda8aSnia	{ "nodecoratetransients",   KEYWORD, kw0_NoDecorateTransients },
3590bbfda8aSnia	{ "nodefaults",             KEYWORD, kw0_NoDefaults },
3600bbfda8aSnia	{ "nograbserver",           KEYWORD, kw0_NoGrabServer },
3610bbfda8aSnia	{ "nohighlight",            NO_HILITE, 0 },
3620bbfda8aSnia	{ "noiconmanagerfocus",     KEYWORD, kw0_NoIconManagerFocus },
3630bbfda8aSnia	{ "noiconmanagers",         KEYWORD, kw0_NoIconManagers },
3640bbfda8aSnia	{ "noicontitle",            NO_ICON_TITLE, 0  },
3650bbfda8aSnia	{ "noimagesinworkspacemanager", KEYWORD, kw0_NoImagesInWorkSpaceManager },
3660bbfda8aSnia	{ "nomenushadows",          KEYWORD, kw0_NoMenuShadows },
3670bbfda8aSnia	{ "noopaquemove",           NOOPAQUEMOVE, 0 },
3680bbfda8aSnia	{ "noopaqueresize",         NOOPAQUERESIZE, 0 },
3690bbfda8aSnia	{ "noraiseondeiconify",     KEYWORD, kw0_NoRaiseOnDeiconify },
3700bbfda8aSnia	{ "noraiseonmove",          KEYWORD, kw0_NoRaiseOnMove },
3710bbfda8aSnia	{ "noraiseonresize",        KEYWORD, kw0_NoRaiseOnResize },
3720bbfda8aSnia	{ "noraiseonwarp",          KEYWORD, kw0_NoRaiseOnWarp },
3730bbfda8aSnia	{ "norestartpreviousstate", KEYWORD, kw0_NoRestartPreviousState },
3740bbfda8aSnia	{ "north",                  GRAVITY, GRAV_NORTH },
3750bbfda8aSnia	{ "nosaveunders",           KEYWORD, kw0_NoSaveUnders },
3760bbfda8aSnia	{ "noshowoccupyall",        KEYWORD, kw0_NoShowOccupyAll },
3770bbfda8aSnia	{ "nosorticonmanager",      KEYWORD, kw0_NoSortIconManager },
3780bbfda8aSnia	{ "nostackmode",            NO_STACKMODE, 0 },
3790bbfda8aSnia	{ "notitle",                NO_TITLE, 0 },
3800bbfda8aSnia	{ "notitlefocus",           KEYWORD, kw0_NoTitleFocus },
3810bbfda8aSnia	{ "notitlehighlight",       NO_TITLE_HILITE, 0 },
3820bbfda8aSnia	{ "nowarptomenutitle",      KEYWORD, kw0_NoWarpToMenuTitle },
3830bbfda8aSnia	{ "occupy",                 OCCUPYLIST, 0 },
3840bbfda8aSnia	{ "occupyall",              OCCUPYALL, 0 },
3850bbfda8aSnia	{ "ontoppriority",          ON_TOP_PRIORITY, 0 },
3860bbfda8aSnia	{ "opaquemove",             OPAQUEMOVE, 0 },
3870bbfda8aSnia	{ "opaquemovethreshold",    NKEYWORD, kwn_OpaqueMoveThreshold },
3880bbfda8aSnia	{ "opaqueresize",           OPAQUERESIZE, 0 },
3890bbfda8aSnia	{ "opaqueresizethreshold",  NKEYWORD, kwn_OpaqueResizeThreshold },
3900bbfda8aSnia	{ "openwindowtimeout",      NKEYWORD, kwn_OpenWindowTimeout },
3910bbfda8aSnia	{ "packnewwindows",         KEYWORD, kw0_PackNewWindows },
3920bbfda8aSnia	{ "pixmapdirectory",        SKEYWORD, kws_PixmapDirectory },
3930bbfda8aSnia	{ "pixmaps",                PIXMAPS, 0 },
3940bbfda8aSnia	{ "prioritynotswitching",   PRIORITY_NOT_SWITCHING, 0 },
3950bbfda8aSnia	{ "priorityswitching",      PRIORITY_SWITCHING, 0 },
3960bbfda8aSnia	{ "r",                      ROOT, 0 },
3970bbfda8aSnia	{ "raisedelay",             NKEYWORD, kwn_RaiseDelay },
3980bbfda8aSnia	{ "raiseonclick",           KEYWORD, kw0_RaiseOnClick },
3990bbfda8aSnia	{ "raiseonclickbutton",     NKEYWORD, kwn_RaiseOnClickButton },
4000bbfda8aSnia	{ "raiseonwarp",            KEYWORD, kw0_RaiseOnWarp },
4010bbfda8aSnia	{ "raisewhenautounsqueeze", KEYWORD, kw0_RaiseWhenAutoUnSqueeze },
4020bbfda8aSnia	{ "randomplacement",        SSKEYWORD, kwss_RandomPlacement },
4030bbfda8aSnia	{ "reallymoveinworkspacemanager",   KEYWORD, kw0_ReallyMoveInWorkspaceManager },
4040bbfda8aSnia	{ "resize",                 RESIZE, 0 },
4050bbfda8aSnia	{ "resizefont",             SKEYWORD, kws_ResizeFont },
4060bbfda8aSnia	{ "restartpreviousstate",   KEYWORD, kw0_RestartPreviousState },
4070bbfda8aSnia	{ "reversecurrentworkspace", KEYWORD, kw0_ReverseCurrentWorkspace },
4080bbfda8aSnia	{ "right",                  SIJENUM, SIJ_RIGHT },
4090bbfda8aSnia	{ "righttitlebutton",       RIGHT_TITLEBUTTON, 0 },
4100bbfda8aSnia	{ "root",                   ROOT, 0 },
4110bbfda8aSnia	{ "rplaysoundhost",         SKEYWORD, kws_RplaySoundHost },
4120bbfda8aSnia	{ "rplaysounds",            RPLAY_SOUNDS, 0 },
4130bbfda8aSnia	{ "s",                      SHIFT, 0 },
4140bbfda8aSnia	{ "savecolor",              SAVECOLOR, 0},
4150bbfda8aSnia	{ "saveworkspacefocus",     KEYWORD, kw0_SaveWorkspaceFocus },
4160bbfda8aSnia	{ "schrinkicontitles",      KEYWORD, kw0_ShrinkIconTitles },
4170bbfda8aSnia	{ "select",                 SELECT, 0 },
4180bbfda8aSnia	{ "shift",                  SHIFT, 0 },
4190bbfda8aSnia	{ "shortallwindowsmenus",   KEYWORD, kw0_ShortAllWindowsMenus },
4200bbfda8aSnia	{ "showiconmanager",        KEYWORD, kw0_ShowIconManager },
4210bbfda8aSnia	{ "showworkspacemanager",   KEYWORD, kw0_ShowWorkspaceManager },
4220bbfda8aSnia	{ "shrinkicontitles",       KEYWORD, kw0_ShrinkIconTitles },
4230bbfda8aSnia	{ "sloppyfocus",            KEYWORD, kw0_SloppyFocus },
4240bbfda8aSnia	{ "sorticonmanager",        KEYWORD, kw0_SortIconManager },
4250bbfda8aSnia	{ "soundhost",              SKEYWORD, kws_SoundHost },
4260bbfda8aSnia	{ "south",                  GRAVITY, GRAV_SOUTH },
4270bbfda8aSnia	{ "squeezetitle",           SQUEEZE_TITLE, 0 },
4280bbfda8aSnia	{ "starticonified",         START_ICONIFIED, 0 },
4290bbfda8aSnia	{ "startinbuttonstate",     KEYWORD, kw0_StartInButtonState },
4300bbfda8aSnia	{ "startinmapstate",        KEYWORD, kw0_StartInMapState },
4310bbfda8aSnia	{ "startsqueezed",          STARTSQUEEZED, 0 },
4320bbfda8aSnia	{ "stayupmenus",            KEYWORD, kw0_StayUpMenus },
4330bbfda8aSnia	{ "strictwinnameencoding",  KEYWORD, kw0_StrictWinNameEncoding  },
4340bbfda8aSnia	{ "sunkfocuswindowtitle",   KEYWORD, kw0_SunkFocusWindowTitle },
4350bbfda8aSnia	{ "t",                      TITLE, 0 },
4360bbfda8aSnia	{ "threedborderwidth",      NKEYWORD, kwn_ThreeDBorderWidth },
4370bbfda8aSnia	{ "title",                  TITLE, 0 },
4380bbfda8aSnia	{ "titlebackground",        CLKEYWORD, kwcl_TitleBackground },
4390bbfda8aSnia	{ "titlebuttonborderwidth", NKEYWORD, kwn_TitleButtonBorderWidth },
4400bbfda8aSnia	{ "titlebuttonshadowdepth", NKEYWORD, kwn_TitleButtonShadowDepth },
4410bbfda8aSnia	{ "titlefont",              SKEYWORD, kws_TitleFont },
4420bbfda8aSnia	{ "titleforeground",        CLKEYWORD, kwcl_TitleForeground },
4430bbfda8aSnia	{ "titlehighlight",         TITLE_HILITE, 0 },
4440bbfda8aSnia	{ "titlejustification",     SKEYWORD, kws_TitleJustification },
4450bbfda8aSnia	{ "titlepadding",           NKEYWORD, kwn_TitlePadding },
4460bbfda8aSnia	{ "titleshadowdepth",       NKEYWORD, kwn_TitleShadowDepth },
4470bbfda8aSnia	{ "transienthasoccupation", KEYWORD, kw0_TransientHasOccupation },
4480bbfda8aSnia	{ "transientontop",         NKEYWORD, kwn_TransientOnTop },
4490bbfda8aSnia	{ "unknownicon",            SKEYWORD, kws_UnknownIcon },
4500bbfda8aSnia	{ "unmapbymovingfaraway",   UNMAPBYMOVINGFARAWAY, 0 },
4510bbfda8aSnia	{ "usepposition",           SKEYWORD, kws_UsePPosition },
4520bbfda8aSnia	{ "usesunktitlepixmap",     KEYWORD, kw0_UseSunkTitlePixmap },
4530bbfda8aSnia	{ "usethreedborders",       KEYWORD, kw0_Use3DBorders },
4540bbfda8aSnia	{ "usethreediconmanagers",  KEYWORD, kw0_Use3DIconManagers },
4550bbfda8aSnia	{ "usethreedmenus",         KEYWORD, kw0_Use3DMenus },
4560bbfda8aSnia	{ "usethreedtitles",        KEYWORD, kw0_Use3DTitles },
4570bbfda8aSnia	{ "usethreedwmap",          KEYWORD, kw0_Use3DWMap },
458b18c2d1eSnia#ifdef VSCREEN
4590bbfda8aSnia	{ "virtualscreens",         VIRTUAL_SCREENS, 0 },
460b18c2d1eSnia#endif
4610bbfda8aSnia	{ "w",                      WINDOW, 0 },
4620bbfda8aSnia	{ "wait",                   WAITC, 0 },
4630bbfda8aSnia	{ "warpcursor",             WARP_CURSOR, 0 },
4640bbfda8aSnia	{ "warpondeiconify",        WARP_ON_DEICONIFY, 0 },
4650bbfda8aSnia	{ "warpringonscreen",       KEYWORD, kw0_WarpRingOnScreen },
4660bbfda8aSnia	{ "warptodefaultmenuentry", KEYWORD, kw0_WarpToDefaultMenuEntry },
4670bbfda8aSnia	{ "warpunmapped",           KEYWORD, kw0_WarpUnmapped },
4680bbfda8aSnia	{ "west",                   GRAVITY, GRAV_WEST },
4690bbfda8aSnia	{ "window",                 WINDOW, 0 },
470b18c2d1eSnia#ifdef WINBOX
4710bbfda8aSnia	{ "windowbox",              WINDOW_BOX, 0 },
472b18c2d1eSnia#endif
4730bbfda8aSnia	{ "windowfunction",         WINDOW_FUNCTION, 0 },
4740bbfda8aSnia	{ "windowgeometries",       WINDOW_GEOMETRIES, 0 },
4750bbfda8aSnia	{ "windowregion",           WINDOW_REGION, 0 },
4760bbfda8aSnia	{ "windowring",             WINDOW_RING, 0 },
4770bbfda8aSnia	{ "windowringexclude",      WINDOW_RING_EXCLUDE, 0},
4780bbfda8aSnia	{ "wmgrbuttonshadowdepth",  NKEYWORD, kwn_WMgrButtonShadowDepth },
4790bbfda8aSnia	{ "wmgrbuttonstyle",        SKEYWORD, kws_WMgrButtonStyle },
4800bbfda8aSnia	{ "wmgrhorizbuttonindent",  NKEYWORD, kwn_WMgrHorizButtonIndent },
4810bbfda8aSnia	{ "wmgrvertbuttonindent",   NKEYWORD, kwn_WMgrVertButtonIndent },
4820bbfda8aSnia	{ "workspace",              WORKSPACE, 0 },
4830bbfda8aSnia	{ "workspacefont",          SKEYWORD, kws_WorkSpaceFont },
4840bbfda8aSnia	{ "workspacemanagergeometry", WORKSPCMGR_GEOMETRY, 0 },
4850bbfda8aSnia	{ "workspaces",             WORKSPACES, 0},
4860bbfda8aSnia	{ "xmovegrid",              NKEYWORD, kwn_XMoveGrid },
4870bbfda8aSnia	{ "xorvalue",               NKEYWORD, kwn_XorValue },
4880bbfda8aSnia	{ "xpmicondirectory",       SKEYWORD, kws_PixmapDirectory },
4890bbfda8aSnia	{ "ymovegrid",              NKEYWORD, kwn_YMoveGrid },
4900bbfda8aSnia	{ "zoom",                   ZOOM, 0 },
4910bbfda8aSnia};
4920bbfda8aSnia
4930bbfda8aSniastatic const size_t numkeywords = (sizeof(keytable) / sizeof(keytable[0]));
4940bbfda8aSnia
4950bbfda8aSnia
4960bbfda8aSnia/*
4970bbfda8aSnia * The lookup table for functions is generated.
4980bbfda8aSnia */
4990bbfda8aSnia#include "functions_parse_table.h"
5000bbfda8aSnia
5010bbfda8aSnia
5020bbfda8aSnia
5030bbfda8aSniastatic int
5040bbfda8aSniakt_compare(const void *lhs, const void *rhs)
5050bbfda8aSnia{
5060bbfda8aSnia	const TwmKeyword *l = lhs;
5070bbfda8aSnia	const TwmKeyword *r = rhs;
5080bbfda8aSnia	return strcasecmp(l->name, r->name);
5090bbfda8aSnia}
5100bbfda8aSnia
5110bbfda8aSniaint
5120bbfda8aSniaparse_keyword(const char *s, int *nump)
5130bbfda8aSnia{
5140bbfda8aSnia	const TwmKeyword srch = { .name = s };
5150bbfda8aSnia	TwmKeyword *ret;
5160bbfda8aSnia	const TwmKeyword *srchtab;
5170bbfda8aSnia	size_t nstab;
5180bbfda8aSnia
5190bbfda8aSnia	/* Guard; nothing can't be a valid keyword */
5200bbfda8aSnia	if(s == NULL || strlen(s) < 1) {
5210bbfda8aSnia		return ERRORTOKEN;
5220bbfda8aSnia	}
5230bbfda8aSnia
5240bbfda8aSnia	/*
5250bbfda8aSnia	 * Functions are in their own table, so check for them there.
5260bbfda8aSnia	 *
5270bbfda8aSnia	 * This is safe as long as (strlen >= 1), which we already checked.
5280bbfda8aSnia	 */
5290bbfda8aSnia	if(s[0] == 'f' && s[1] == '.') {
5300bbfda8aSnia		srchtab = funckeytable;
5310bbfda8aSnia		nstab = numfunckeywords;
5320bbfda8aSnia	}
5330bbfda8aSnia	else {
5340bbfda8aSnia		srchtab = keytable;
5350bbfda8aSnia		nstab = numkeywords;
5360bbfda8aSnia	}
5370bbfda8aSnia
5380bbfda8aSnia	/* Find it */
5390bbfda8aSnia	ret = bsearch(&srch, srchtab, nstab, sizeof(TwmKeyword), kt_compare);
5400bbfda8aSnia	if(ret) {
5410bbfda8aSnia		*nump = ret->subnum;
5420bbfda8aSnia		return ret->value;
5430bbfda8aSnia	}
5440bbfda8aSnia
5450bbfda8aSnia	return ERRORTOKEN;
5460bbfda8aSnia}
5470bbfda8aSnia
5480bbfda8aSnia
5490bbfda8aSnia/*
5500bbfda8aSnia * Simple tester function
5510bbfda8aSnia */
5520bbfda8aSniavoid
5530bbfda8aSniachk_keytable_order(void)
5540bbfda8aSnia{
5550bbfda8aSnia	int i;
5560bbfda8aSnia
5570bbfda8aSnia	for(i = 0 ; i < (numkeywords - 1) ; i++) {
5580bbfda8aSnia		if(strcasecmp(keytable[i].name, keytable[i + 1].name) >= 0) {
5590bbfda8aSnia			fprintf(stderr, "%s: INTERNAL ERROR: keytable sorting: "
5600bbfda8aSnia			        "'%s' >= '%s'\n", ProgramName,
5610bbfda8aSnia			        keytable[i].name, keytable[i + 1].name);
5620bbfda8aSnia		}
5630bbfda8aSnia	}
5640bbfda8aSnia
5650bbfda8aSnia	for(i = 0 ; i < (numfunckeywords - 1) ; i++) {
5660bbfda8aSnia		if(strcasecmp(funckeytable[i].name, funckeytable[i + 1].name) >= 0) {
5670bbfda8aSnia			fprintf(stderr, "%s: INTERNAL ERROR: funckeytable sorting: "
5680bbfda8aSnia			        "'%s' >= '%s'\n", ProgramName,
5690bbfda8aSnia			        funckeytable[i].name, funckeytable[i + 1].name);
5700bbfda8aSnia		}
5710bbfda8aSnia	}
5720bbfda8aSnia}
5730bbfda8aSnia
5740bbfda8aSnia
5750bbfda8aSnia
5760bbfda8aSnia/*
5770bbfda8aSnia * action routines called by grammar
5780bbfda8aSnia */
5790bbfda8aSnia
5800bbfda8aSniabool
5810bbfda8aSniado_single_keyword(int keyword)
5820bbfda8aSnia{
5830bbfda8aSnia	switch(keyword) {
5840bbfda8aSnia		case kw0_NoDefaults:
5850bbfda8aSnia			Scr->NoDefaults = true;
5860bbfda8aSnia			return true;
5870bbfda8aSnia
5880bbfda8aSnia		case kw0_AutoRelativeResize:
5890bbfda8aSnia			Scr->AutoRelativeResize = true;
5900bbfda8aSnia			return true;
5910bbfda8aSnia
5920bbfda8aSnia		case kw0_ForceIcons:
5930bbfda8aSnia			if(Scr->FirstTime) {
5940bbfda8aSnia				Scr->ForceIcon = true;
5950bbfda8aSnia			}
5960bbfda8aSnia			return true;
5970bbfda8aSnia
5980bbfda8aSnia		case kw0_NoIconManagers:
5990bbfda8aSnia			Scr->NoIconManagers = true;
6000bbfda8aSnia			return true;
6010bbfda8aSnia
6020bbfda8aSnia		case kw0_InterpolateMenuColors:
6030bbfda8aSnia			if(Scr->FirstTime) {
6040bbfda8aSnia				Scr->InterpolateMenuColors = true;
6050bbfda8aSnia			}
6060bbfda8aSnia			return true;
6070bbfda8aSnia
6080bbfda8aSnia		case kw0_SortIconManager:
6090bbfda8aSnia			if(Scr->FirstTime) {
6100bbfda8aSnia				Scr->SortIconMgr = true;
6110bbfda8aSnia			}
6120bbfda8aSnia			return true;
6130bbfda8aSnia
6140bbfda8aSnia		case kw0_NoSortIconManager:
6150bbfda8aSnia			if(Scr->FirstTime) {
6160bbfda8aSnia				Scr->SortIconMgr = false;
6170bbfda8aSnia			}
6180bbfda8aSnia			return true;
6190bbfda8aSnia
6200bbfda8aSnia		case kw0_GrabServer:
6210bbfda8aSnia			Scr->NoGrabServer = false;
6220bbfda8aSnia			return true;
6230bbfda8aSnia
6240bbfda8aSnia		case kw0_NoGrabServer:
6250bbfda8aSnia			Scr->NoGrabServer = true;
6260bbfda8aSnia			return true;
6270bbfda8aSnia
6280bbfda8aSnia		case kw0_NoMenuShadows:
6290bbfda8aSnia			if(Scr->FirstTime) {
6300bbfda8aSnia				Scr->Shadow = false;
6310bbfda8aSnia			}
6320bbfda8aSnia			return true;
6330bbfda8aSnia
6340bbfda8aSnia		case kw0_NoRaiseOnMove:
6350bbfda8aSnia			if(Scr->FirstTime) {
6360bbfda8aSnia				Scr->NoRaiseMove = true;
6370bbfda8aSnia			}
6380bbfda8aSnia			return true;
6390bbfda8aSnia
6400bbfda8aSnia		case kw0_NoRaiseOnResize:
6410bbfda8aSnia			if(Scr->FirstTime) {
6420bbfda8aSnia				Scr->NoRaiseResize = true;
6430bbfda8aSnia			}
6440bbfda8aSnia			return true;
6450bbfda8aSnia
6460bbfda8aSnia		case kw0_NoRaiseOnDeiconify:
6470bbfda8aSnia			if(Scr->FirstTime) {
6480bbfda8aSnia				Scr->NoRaiseDeicon = true;
6490bbfda8aSnia			}
6500bbfda8aSnia			return true;
6510bbfda8aSnia
6520bbfda8aSnia		case kw0_DontMoveOff:
6530bbfda8aSnia			Scr->DontMoveOff = true;
6540bbfda8aSnia			return true;
6550bbfda8aSnia
6560bbfda8aSnia		case kw0_NoBackingStore:
6570bbfda8aSnia			Scr->BackingStore = false;
6580bbfda8aSnia			return true;
6590bbfda8aSnia
6600bbfda8aSnia		case kw0_BackingStore:
6610bbfda8aSnia			Scr->BackingStore = true;
6620bbfda8aSnia			return true;
6630bbfda8aSnia
6640bbfda8aSnia		case kw0_NoSaveUnders:
6650bbfda8aSnia			Scr->SaveUnder = false;
6660bbfda8aSnia			return true;
6670bbfda8aSnia
6680bbfda8aSnia		// XXX Shouldn't these be in Scr too?
6690bbfda8aSnia		case kw0_RestartPreviousState:
6700bbfda8aSnia			RestartPreviousState = true;
6710bbfda8aSnia			return true;
6720bbfda8aSnia
6730bbfda8aSnia		case kw0_NoRestartPreviousState:
6740bbfda8aSnia			RestartPreviousState = false;
6750bbfda8aSnia			return true;
6760bbfda8aSnia
6770bbfda8aSnia		case kw0_ClientBorderWidth:
6780bbfda8aSnia			if(Scr->FirstTime) {
6790bbfda8aSnia				Scr->ClientBorderWidth = true;
6800bbfda8aSnia			}
6810bbfda8aSnia			return true;
6820bbfda8aSnia
6830bbfda8aSnia		case kw0_NoTitleFocus:
6840bbfda8aSnia			Scr->TitleFocus = false;
6850bbfda8aSnia			return true;
6860bbfda8aSnia
6870bbfda8aSnia		case kw0_DecorateTransients:
6880bbfda8aSnia			Scr->DecorateTransients = true;
6890bbfda8aSnia			return true;
6900bbfda8aSnia
6910bbfda8aSnia		case kw0_NoDecorateTransients:
6920bbfda8aSnia			Scr->DecorateTransients = false;
6930bbfda8aSnia			return true;
6940bbfda8aSnia
6950bbfda8aSnia		case kw0_ShowIconManager:
6960bbfda8aSnia			Scr->ShowIconManager = true;
6970bbfda8aSnia			return true;
6980bbfda8aSnia
6990bbfda8aSnia		case kw0_ShowWorkspaceManager:
7000bbfda8aSnia			Scr->ShowWorkspaceManager = true;
7010bbfda8aSnia			return true;
7020bbfda8aSnia
7030bbfda8aSnia		case kw0_StartInButtonState:
7040bbfda8aSnia			Scr->workSpaceMgr.initialstate = WMS_buttons;
7050bbfda8aSnia			return true;
7060bbfda8aSnia
7070bbfda8aSnia		case kw0_StartInMapState:
7080bbfda8aSnia			Scr->workSpaceMgr.initialstate = WMS_map;
7090bbfda8aSnia			return true;
7100bbfda8aSnia
7110bbfda8aSnia		case kw0_NoShowOccupyAll:
7120bbfda8aSnia			Scr->workSpaceMgr.noshowoccupyall = true;
7130bbfda8aSnia			return true;
7140bbfda8aSnia
7150bbfda8aSnia		case kw0_AutoOccupy:
7160bbfda8aSnia			Scr->AutoOccupy = true;
7170bbfda8aSnia			return true;
7180bbfda8aSnia
7190bbfda8aSnia		case kw0_AutoPriority:
7200bbfda8aSnia			Scr->AutoPriority = true;
7210bbfda8aSnia			return true;
7220bbfda8aSnia
7230bbfda8aSnia		case kw0_TransientHasOccupation:
7240bbfda8aSnia			Scr->TransientHasOccupation = true;
7250bbfda8aSnia			return true;
7260bbfda8aSnia
7270bbfda8aSnia		case kw0_DontPaintRootWindow:
7280bbfda8aSnia			Scr->DontPaintRootWindow = true;
7290bbfda8aSnia			return true;
7300bbfda8aSnia
7310bbfda8aSnia		case kw0_UseSunkTitlePixmap:
7320bbfda8aSnia			Scr->UseSunkTitlePixmap = true;
7330bbfda8aSnia			return true;
7340bbfda8aSnia
7350bbfda8aSnia		case kw0_Use3DBorders:
7360bbfda8aSnia			Scr->use3Dborders = true;
7370bbfda8aSnia			return true;
7380bbfda8aSnia
7390bbfda8aSnia		case kw0_Use3DIconManagers:
7400bbfda8aSnia			Scr->use3Diconmanagers = true;
7410bbfda8aSnia			return true;
7420bbfda8aSnia
7430bbfda8aSnia		case kw0_Use3DMenus:
7440bbfda8aSnia			Scr->use3Dmenus = true;
7450bbfda8aSnia			return true;
7460bbfda8aSnia
7470bbfda8aSnia		case kw0_Use3DTitles:
7480bbfda8aSnia			Scr->use3Dtitles = true;
7490bbfda8aSnia			return true;
7500bbfda8aSnia
7510bbfda8aSnia		case kw0_Use3DWMap:
7520bbfda8aSnia			Scr->use3Dwmap = true;
7530bbfda8aSnia			return true;
7540bbfda8aSnia
7550bbfda8aSnia		case kw0_SunkFocusWindowTitle:
7560bbfda8aSnia			Scr->SunkFocusWindowTitle = true;
7570bbfda8aSnia			return true;
7580bbfda8aSnia
7590bbfda8aSnia		case kw0_BeNiceToColormap:
7600bbfda8aSnia			Scr->BeNiceToColormap = true;
7610bbfda8aSnia			return true;
7620bbfda8aSnia
7630bbfda8aSnia		case kw0_BorderResizeCursors:
7640bbfda8aSnia			Scr->BorderCursors = true;
7650bbfda8aSnia			return true;
7660bbfda8aSnia
7670bbfda8aSnia		case kw0_NoCaseSensitive:
7680bbfda8aSnia			Scr->CaseSensitive = false;
7690bbfda8aSnia			return true;
7700bbfda8aSnia
7710bbfda8aSnia		case kw0_NoRaiseOnWarp:
7720bbfda8aSnia			Scr->RaiseOnWarp = false;
7730bbfda8aSnia			return true;
7740bbfda8aSnia
7750bbfda8aSnia		case kw0_RaiseOnWarp:
7760bbfda8aSnia			Scr->RaiseOnWarp = true;
7770bbfda8aSnia			return true;
7780bbfda8aSnia
7790bbfda8aSnia		case kw0_WarpUnmapped:
7800bbfda8aSnia			Scr->WarpUnmapped = true;
7810bbfda8aSnia			return true;
7820bbfda8aSnia
7830bbfda8aSnia		case kw0_WarpRingOnScreen:
7840bbfda8aSnia			Scr->WarpRingAnyWhere = false;
7850bbfda8aSnia			return true;
7860bbfda8aSnia
7870bbfda8aSnia		case kw0_NoIconManagerFocus:
7880bbfda8aSnia			Scr->IconManagerFocus = false;
7890bbfda8aSnia			return true;
7900bbfda8aSnia
7910bbfda8aSnia		case kw0_StayUpMenus:
7920bbfda8aSnia			Scr->StayUpMenus = true;
7930bbfda8aSnia			return true;
7940bbfda8aSnia
7950bbfda8aSnia		case kw0_ClickToFocus:
7960bbfda8aSnia			Scr->ClickToFocus = true;
7970bbfda8aSnia			return true;
7980bbfda8aSnia
7990bbfda8aSnia		case kw0_ReallyMoveInWorkspaceManager:
8000bbfda8aSnia			Scr->ReallyMoveInWorkspaceManager = true;
8010bbfda8aSnia			return true;
8020bbfda8aSnia
8030bbfda8aSnia		case kw0_ShowWinWhenMovingInWmgr:
8040bbfda8aSnia			Scr->ShowWinWhenMovingInWmgr = true;
8050bbfda8aSnia			return true;
8060bbfda8aSnia
8070bbfda8aSnia		case kw0_ReverseCurrentWorkspace:
8080bbfda8aSnia			Scr->ReverseCurrentWorkspace = true;
8090bbfda8aSnia			return true;
8100bbfda8aSnia
8110bbfda8aSnia		case kw0_DontWarpCursorInWMap:
8120bbfda8aSnia			Scr->DontWarpCursorInWMap = true;
8130bbfda8aSnia			return true;
8140bbfda8aSnia
8150bbfda8aSnia		case kw0_CenterFeedbackWindow:
8160bbfda8aSnia			Scr->CenterFeedbackWindow = true;
8170bbfda8aSnia			return true;
8180bbfda8aSnia
8190bbfda8aSnia		case kw0_WarpToDefaultMenuEntry:
8200bbfda8aSnia			Scr->WarpToDefaultMenuEntry = true;
8210bbfda8aSnia			return true;
8220bbfda8aSnia
8230bbfda8aSnia		case kw0_ShrinkIconTitles:
8240bbfda8aSnia			Scr->ShrinkIconTitles = true;
8250bbfda8aSnia			return true;
8260bbfda8aSnia
8270bbfda8aSnia		case kw0_AutoRaiseIcons:
8280bbfda8aSnia			Scr->AutoRaiseIcons = true;
8290bbfda8aSnia			return true;
8300bbfda8aSnia
8310bbfda8aSnia		/* kai */
8320bbfda8aSnia		case kw0_AutoFocusToTransients:
8330bbfda8aSnia			Scr->AutoFocusToTransients = true;
8340bbfda8aSnia			return true;
8350bbfda8aSnia
8360bbfda8aSnia		case kw0_ShortAllWindowsMenus:
8370bbfda8aSnia			Scr->ShortAllWindowsMenus = true;
8380bbfda8aSnia			return true;
8390bbfda8aSnia
8400bbfda8aSnia		case kw0_RaiseWhenAutoUnSqueeze:
8410bbfda8aSnia			Scr->RaiseWhenAutoUnSqueeze = true;
8420bbfda8aSnia			return true;
8430bbfda8aSnia
8440bbfda8aSnia		case kw0_RaiseOnClick:
8450bbfda8aSnia			Scr->RaiseOnClick = true;
8460bbfda8aSnia			return true;
8470bbfda8aSnia
8480bbfda8aSnia		case kw0_IgnoreLockModifier:
8490bbfda8aSnia			Scr->IgnoreModifier |= LockMask;
8500bbfda8aSnia			return true;
8510bbfda8aSnia
8520bbfda8aSnia		case kw0_PackNewWindows:
8530bbfda8aSnia			Scr->PackNewWindows = true;
8540bbfda8aSnia			return true;
8550bbfda8aSnia
8560bbfda8aSnia		case kw0_IgnoreCaseInMenuSelection:
8570bbfda8aSnia			Scr->IgnoreCaseInMenuSelection = true;
8580bbfda8aSnia			return true;
8590bbfda8aSnia
8600bbfda8aSnia		case kw0_SloppyFocus:
8610bbfda8aSnia			Scr->SloppyFocus = true;
8620bbfda8aSnia			return true;
8630bbfda8aSnia
8640bbfda8aSnia		case kw0_SaveWorkspaceFocus:
8650bbfda8aSnia			Scr->SaveWorkspaceFocus = true;
8660bbfda8aSnia			return true;
8670bbfda8aSnia
8680bbfda8aSnia		case kw0_NoImagesInWorkSpaceManager:
8690bbfda8aSnia			Scr->NoImagesInWorkSpaceManager = true;
8700bbfda8aSnia			return true;
8710bbfda8aSnia
8720bbfda8aSnia		case kw0_NoWarpToMenuTitle:
8730bbfda8aSnia			Scr->NoWarpToMenuTitle = true;
8740bbfda8aSnia			return true;
8750bbfda8aSnia
8760bbfda8aSnia		case kw0_DontShowWelcomeWindow:
8770bbfda8aSnia			Scr->ShowWelcomeWindow = false;
8780bbfda8aSnia			return true;
8790bbfda8aSnia
8800bbfda8aSnia		case kw0_DontToggleWorkspacemanagerState:
8810bbfda8aSnia			Scr->DontToggleWorkspaceManagerState = true;
8820bbfda8aSnia			return true;
8830bbfda8aSnia
8840bbfda8aSnia		case kw0_DontNameDecorations:
8850bbfda8aSnia			Scr->NameDecorations = false;
8860bbfda8aSnia			return true;
8870bbfda8aSnia
8880bbfda8aSnia		case kw0_StrictWinNameEncoding:
8890bbfda8aSnia			Scr->StrictWinNameEncoding = true;
8900bbfda8aSnia			return true;
8910bbfda8aSnia
8920bbfda8aSnia	}
8930bbfda8aSnia	return false;
8940bbfda8aSnia}
8950bbfda8aSnia
8960bbfda8aSnia
8970bbfda8aSniabool
8980bbfda8aSniado_string_string_keyword(int keyword, const char *s1, const char *s2)
8990bbfda8aSnia{
9000bbfda8aSnia	switch(keyword) {
9010bbfda8aSnia		case kwss_RandomPlacement: {
9020bbfda8aSnia			/* RandomPlacement {on,off,all,unmapped} [displacement geom] */
9030bbfda8aSnia			int rp;
9040bbfda8aSnia			int gmask, gx, gy;     // Geometry mask/x/y values
9050bbfda8aSnia			unsigned int gjw, gjh; // width/height (ignored)
9060bbfda8aSnia			int exmask = (XValue | YValue); // Bits we need in the mask
9070bbfda8aSnia
9080bbfda8aSnia			rp = ParseRandomPlacement(s1);
9090bbfda8aSnia			if(rp < 0) {
9100bbfda8aSnia				twmrc_error_prefix();
9110bbfda8aSnia				fprintf(stderr,
9120bbfda8aSnia				        "ignoring invalid RandomPlacement argument 1 \"%s\"\n",
9130bbfda8aSnia				        s1);
9140bbfda8aSnia			}
9150bbfda8aSnia			else {
9160bbfda8aSnia				Scr->RandomPlacement = rp;
9170bbfda8aSnia			}
9180bbfda8aSnia
9190bbfda8aSnia			/* If no geom, we're done */
9200bbfda8aSnia			if(s2 == NULL) {
9210bbfda8aSnia				return true;
9220bbfda8aSnia			}
9230bbfda8aSnia
9240bbfda8aSnia			/*
9250bbfda8aSnia			 * Figure what the geom means.  We actually don't care about
9260bbfda8aSnia			 * the size (it probably won't even be provided), so the
9270bbfda8aSnia			 * width/height are junk.  The X/Y offsets are what we need.
9280bbfda8aSnia			 * But we do need them.
9290bbfda8aSnia			 */
9300bbfda8aSnia			gmask = XParseGeometry(s2, &gx, &gy, &gjw, &gjh);
9310bbfda8aSnia#ifdef DEBUG
9320bbfda8aSnia			fprintf(stderr, "DEBUG:: Mask = %x, Width = %d, Height = %d\n",
9330bbfda8aSnia			        gmask, gjw, gjh);
9340bbfda8aSnia			fprintf(stderr, "DEBUG:: X = %d, Y = %d\n", gx, gy);
9350bbfda8aSnia#endif
9360bbfda8aSnia			if((gmask & exmask) != exmask) {
9370bbfda8aSnia				/* Didn't get X and Y */
9380bbfda8aSnia				twmrc_error_prefix();
9390bbfda8aSnia				fprintf(stderr,
9400bbfda8aSnia				        "ignoring invalid RandomPlacement displacement \"%s\"\n", s2);
9410bbfda8aSnia			}
9420bbfda8aSnia			else {
9430bbfda8aSnia				Scr->RandomDisplacementX = gx;
9440bbfda8aSnia				Scr->RandomDisplacementY = gy;
9450bbfda8aSnia			}
9460bbfda8aSnia
9470bbfda8aSnia			/* Done */
9480bbfda8aSnia			return true;
9490bbfda8aSnia		}
9500bbfda8aSnia	}
9510bbfda8aSnia	return false;
9520bbfda8aSnia}
9530bbfda8aSnia
9540bbfda8aSnia
9550bbfda8aSniabool
9560bbfda8aSniado_string_keyword(int keyword, char *s)
9570bbfda8aSnia{
9580bbfda8aSnia	switch(keyword) {
9590bbfda8aSnia		case kws_UsePPosition: {
9600bbfda8aSnia			int ppos = ParseUsePPosition(s);
9610bbfda8aSnia			if(ppos < 0) {
9620bbfda8aSnia				twmrc_error_prefix();
9630bbfda8aSnia				fprintf(stderr,
9640bbfda8aSnia				        "ignoring invalid UsePPosition argument \"%s\"\n", s);
9650bbfda8aSnia			}
9660bbfda8aSnia			else {
9670bbfda8aSnia				Scr->UsePPosition = ppos;
9680bbfda8aSnia			}
9690bbfda8aSnia			return true;
9700bbfda8aSnia		}
9710bbfda8aSnia
9720bbfda8aSnia		case kws_IconFont:
9730bbfda8aSnia			if(!Scr->HaveFonts) {
9740bbfda8aSnia				Scr->IconFont.basename = s;
9750bbfda8aSnia			}
9760bbfda8aSnia			return true;
9770bbfda8aSnia
9780bbfda8aSnia		case kws_ResizeFont:
9790bbfda8aSnia			if(!Scr->HaveFonts) {
9800bbfda8aSnia				Scr->SizeFont.basename = s;
9810bbfda8aSnia			}
9820bbfda8aSnia			return true;
9830bbfda8aSnia
9840bbfda8aSnia		case kws_MenuFont:
9850bbfda8aSnia			if(!Scr->HaveFonts) {
9860bbfda8aSnia				Scr->MenuFont.basename = s;
9870bbfda8aSnia			}
9880bbfda8aSnia			return true;
9890bbfda8aSnia
9900bbfda8aSnia		case kws_WorkSpaceFont:
9910bbfda8aSnia			if(!Scr->HaveFonts) {
9920bbfda8aSnia				Scr->workSpaceMgr.windowFont.basename = s;
9930bbfda8aSnia			}
9940bbfda8aSnia			return true;
9950bbfda8aSnia
9960bbfda8aSnia		case kws_TitleFont:
9970bbfda8aSnia			if(!Scr->HaveFonts) {
9980bbfda8aSnia				Scr->TitleBarFont.basename = s;
9990bbfda8aSnia			}
10000bbfda8aSnia			return true;
10010bbfda8aSnia
10020bbfda8aSnia		case kws_IconManagerFont:
10030bbfda8aSnia			if(!Scr->HaveFonts) {
10040bbfda8aSnia				Scr->IconManagerFont.basename = s;
10050bbfda8aSnia			}
10060bbfda8aSnia			return true;
10070bbfda8aSnia
10080bbfda8aSnia		case kws_UnknownIcon:
10090bbfda8aSnia			if(Scr->FirstTime) {
10100bbfda8aSnia				Scr->UnknownImage = GetImage(s, Scr->IconC);
10110bbfda8aSnia			}
10120bbfda8aSnia			return true;
10130bbfda8aSnia
10140bbfda8aSnia		case kws_IconDirectory:
10150bbfda8aSnia			if(Scr->FirstTime) {
10160bbfda8aSnia				Scr->IconDirectory = ExpandFilePath(s);
10170bbfda8aSnia			}
10180bbfda8aSnia			return true;
10190bbfda8aSnia
10200bbfda8aSnia		case kws_PixmapDirectory:
10210bbfda8aSnia			if(Scr->FirstTime) {
10220bbfda8aSnia				Scr->PixmapDirectory = ExpandFilePath(s);
10230bbfda8aSnia			}
10240bbfda8aSnia			return true;
10250bbfda8aSnia
10260bbfda8aSnia		case kws_MaxWindowSize: {
10270bbfda8aSnia			int gmask;
10280bbfda8aSnia			int exmask = (WidthValue | HeightValue);
10290bbfda8aSnia			unsigned int gw, gh; // Stuff we care about
10300bbfda8aSnia			int gjx, gjy;        // Stuff we don't
10310bbfda8aSnia
10320bbfda8aSnia			gmask = XParseGeometry(s, &gjx, &gjy, &gw, &gh);
10330bbfda8aSnia			if((gmask & exmask) != exmask) {
10340bbfda8aSnia				twmrc_error_prefix();
10350bbfda8aSnia				fprintf(stderr, "bad MaxWindowSize \"%s\"\n", s);
10360bbfda8aSnia				return false;
10370bbfda8aSnia			}
10380bbfda8aSnia			if(gw == 0 || gh == 0) {
10390bbfda8aSnia				twmrc_error_prefix();
10400bbfda8aSnia				fprintf(stderr, "MaxWindowSize \"%s\" must be non-zero\n", s);
10410bbfda8aSnia				return false;
10420bbfda8aSnia			}
10430bbfda8aSnia			Scr->MaxWindowWidth = gw;
10440bbfda8aSnia			Scr->MaxWindowHeight = gh;
10450bbfda8aSnia			return true;
10460bbfda8aSnia		}
10470bbfda8aSnia
10480bbfda8aSnia		case kws_IconJustification: {
10490bbfda8aSnia			int just = ParseTitleJustification(s);
10500bbfda8aSnia
10510bbfda8aSnia			if((just < 0) || (just == TJ_UNDEF)) {
10520bbfda8aSnia				twmrc_error_prefix();
10530bbfda8aSnia				fprintf(stderr,
10540bbfda8aSnia				        "ignoring invalid IconJustification argument \"%s\"\n", s);
10550bbfda8aSnia			}
10560bbfda8aSnia			else {
10570bbfda8aSnia				Scr->IconJustification = just;
10580bbfda8aSnia			}
10590bbfda8aSnia			return true;
10600bbfda8aSnia		}
10610bbfda8aSnia		case kws_IconRegionJustification: {
10620bbfda8aSnia			int just = ParseIRJustification(s);
10630bbfda8aSnia
10640bbfda8aSnia			if(just < 0 || (just == IRJ_UNDEF)) {
10650bbfda8aSnia				twmrc_error_prefix();
10660bbfda8aSnia				fprintf(stderr,
10670bbfda8aSnia				        "ignoring invalid IconRegionJustification argument \"%s\"\n", s);
10680bbfda8aSnia			}
10690bbfda8aSnia			else {
10700bbfda8aSnia				Scr->IconRegionJustification = just;
10710bbfda8aSnia			}
10720bbfda8aSnia			return true;
10730bbfda8aSnia		}
10740bbfda8aSnia		case kws_IconRegionAlignement: {
10750bbfda8aSnia			int just = ParseAlignement(s);
10760bbfda8aSnia
10770bbfda8aSnia			if(just < 0) {
10780bbfda8aSnia				twmrc_error_prefix();
10790bbfda8aSnia				fprintf(stderr,
10800bbfda8aSnia				        "ignoring invalid IconRegionAlignement argument \"%s\"\n", s);
10810bbfda8aSnia			}
10820bbfda8aSnia			else {
10830bbfda8aSnia				Scr->IconRegionAlignement = just;
10840bbfda8aSnia			}
10850bbfda8aSnia			return true;
10860bbfda8aSnia		}
10870bbfda8aSnia
10880bbfda8aSnia		case kws_TitleJustification: {
10890bbfda8aSnia			int just = ParseTitleJustification(s);
10900bbfda8aSnia
10910bbfda8aSnia			if((just < 0) || (just == TJ_UNDEF)) {
10920bbfda8aSnia				twmrc_error_prefix();
10930bbfda8aSnia				fprintf(stderr,
10940bbfda8aSnia				        "ignoring invalid TitleJustification argument \"%s\"\n", s);
10950bbfda8aSnia			}
10960bbfda8aSnia			else {
10970bbfda8aSnia				Scr->TitleJustification = just;
10980bbfda8aSnia			}
10990bbfda8aSnia			return true;
11000bbfda8aSnia		}
11010bbfda8aSnia		case kws_RplaySoundHost:
11020bbfda8aSnia		case kws_SoundHost:
11030bbfda8aSnia			if(Scr->FirstTime) {
11040bbfda8aSnia				/* Warning to be enabled in the future before removal */
11050bbfda8aSnia				if(0 && keyword == kws_SoundHost) {
11060bbfda8aSnia					twmrc_error_prefix();
11070bbfda8aSnia					fprintf(stderr, "SoundHost is deprecated, please "
11080bbfda8aSnia					        "use RplaySoundHost instead.\n");
11090bbfda8aSnia				}
11100bbfda8aSnia#ifdef SOUNDS
11110bbfda8aSnia				set_sound_host(s);
11120bbfda8aSnia#else
11130bbfda8aSnia				twmrc_error_prefix();
11140bbfda8aSnia				fprintf(stderr, "Ignoring %sSoundHost; rplay not ronfigured.\n",
11150bbfda8aSnia				        (keyword == kws_RplaySoundHost ? "Rplay" : ""));
11160bbfda8aSnia#endif
11170bbfda8aSnia			}
11180bbfda8aSnia			return true;
11190bbfda8aSnia
11200bbfda8aSnia		case kws_WMgrButtonStyle: {
11210bbfda8aSnia			int style = ParseButtonStyle(s);
11220bbfda8aSnia
11230bbfda8aSnia			if(style < 0) {
11240bbfda8aSnia				twmrc_error_prefix();
11250bbfda8aSnia				fprintf(stderr,
11260bbfda8aSnia				        "ignoring invalid WMgrButtonStyle argument \"%s\"\n", s);
11270bbfda8aSnia			}
11280bbfda8aSnia			else {
11290bbfda8aSnia				Scr->workSpaceMgr.buttonStyle = style;
11300bbfda8aSnia			}
11310bbfda8aSnia			return true;
11320bbfda8aSnia		}
11330bbfda8aSnia
11340bbfda8aSnia		case kws_IconifyStyle: {
11350bbfda8aSnia			int style = ParseIconifyStyle(s);
11360bbfda8aSnia
11370bbfda8aSnia			if(style < 0) {
11380bbfda8aSnia				twmrc_error_prefix();
11390bbfda8aSnia				fprintf(stderr, "ignoring invalid IconifyStyle argument \"%s\"\n", s);
11400bbfda8aSnia			}
11410bbfda8aSnia			else {
11420bbfda8aSnia				Scr->IconifyStyle = style;
11430bbfda8aSnia			}
11440bbfda8aSnia			return true;
11450bbfda8aSnia		}
11460bbfda8aSnia
11470bbfda8aSnia#ifdef EWMH
11480bbfda8aSnia		case kws_IconSize:
11490bbfda8aSnia			if(sscanf(s, "%dx%d", &Scr->PreferredIconWidth,
11500bbfda8aSnia			                &Scr->PreferredIconHeight) == 2) {
11510bbfda8aSnia				/* ok */
11520bbfda8aSnia			}
11530bbfda8aSnia			else if(sscanf(s, "%d", &Scr->PreferredIconWidth) == 1) {
11540bbfda8aSnia				Scr->PreferredIconHeight = Scr->PreferredIconWidth;
11550bbfda8aSnia			}
11560bbfda8aSnia			else {
11570bbfda8aSnia				Scr->PreferredIconHeight = Scr->PreferredIconWidth = 48;
11580bbfda8aSnia			}
11590bbfda8aSnia			return true;
11600bbfda8aSnia#endif
11610bbfda8aSnia	}
11620bbfda8aSnia	return false;
11630bbfda8aSnia}
11640bbfda8aSnia
11650bbfda8aSnia
11660bbfda8aSniabool
11670bbfda8aSniado_number_keyword(int keyword, int num)
11680bbfda8aSnia{
11690bbfda8aSnia	switch(keyword) {
11700bbfda8aSnia		case kwn_ConstrainedMoveTime:
11710bbfda8aSnia			ConstrainedMoveTime = num;
11720bbfda8aSnia			return true;
11730bbfda8aSnia
11740bbfda8aSnia		case kwn_MoveDelta:
11750bbfda8aSnia			Scr->MoveDelta = num;
11760bbfda8aSnia			return true;
11770bbfda8aSnia
11780bbfda8aSnia		case kwn_MoveOffResistance:
11790bbfda8aSnia			Scr->MoveOffResistance = num;
11800bbfda8aSnia			return true;
11810bbfda8aSnia
11820bbfda8aSnia		case kwn_MovePackResistance:
11830bbfda8aSnia			if(num < 0) {
11840bbfda8aSnia				num = 20;
11850bbfda8aSnia			}
11860bbfda8aSnia			Scr->MovePackResistance = num;
11870bbfda8aSnia			return true;
11880bbfda8aSnia
11890bbfda8aSnia		case kwn_XMoveGrid:
11900bbfda8aSnia			if(num < 1) {
11910bbfda8aSnia				num = 1;
11920bbfda8aSnia			}
11930bbfda8aSnia			if(num > 100) {
11940bbfda8aSnia				num = 100;
11950bbfda8aSnia			}
11960bbfda8aSnia			Scr->XMoveGrid = num;
11970bbfda8aSnia			return true;
11980bbfda8aSnia
11990bbfda8aSnia		case kwn_YMoveGrid:
12000bbfda8aSnia			if(num < 1) {
12010bbfda8aSnia				num = 1;
12020bbfda8aSnia			}
12030bbfda8aSnia			if(num > 100) {
12040bbfda8aSnia				num = 100;
12050bbfda8aSnia			}
12060bbfda8aSnia			Scr->YMoveGrid = num;
12070bbfda8aSnia			return true;
12080bbfda8aSnia
12090bbfda8aSnia		case kwn_XorValue:
12100bbfda8aSnia			if(Scr->FirstTime) {
12110bbfda8aSnia				Scr->XORvalue = num;
12120bbfda8aSnia			}
12130bbfda8aSnia			return true;
12140bbfda8aSnia
12150bbfda8aSnia		case kwn_FramePadding:
12160bbfda8aSnia			if(Scr->FirstTime) {
12170bbfda8aSnia				Scr->FramePadding = num;
12180bbfda8aSnia			}
12190bbfda8aSnia			return true;
12200bbfda8aSnia
12210bbfda8aSnia		case kwn_TitlePadding:
12220bbfda8aSnia			if(Scr->FirstTime) {
12230bbfda8aSnia				Scr->TitlePadding = num;
12240bbfda8aSnia			}
12250bbfda8aSnia			return true;
12260bbfda8aSnia
12270bbfda8aSnia		case kwn_ButtonIndent:
12280bbfda8aSnia			if(Scr->FirstTime) {
12290bbfda8aSnia				Scr->ButtonIndent = num;
12300bbfda8aSnia			}
12310bbfda8aSnia			return true;
12320bbfda8aSnia
12330bbfda8aSnia		case kwn_ThreeDBorderWidth:
12340bbfda8aSnia			if(Scr->FirstTime) {
12350bbfda8aSnia				Scr->ThreeDBorderWidth = num;
12360bbfda8aSnia			}
12370bbfda8aSnia			return true;
12380bbfda8aSnia
12390bbfda8aSnia		case kwn_BorderWidth:
12400bbfda8aSnia			if(Scr->FirstTime) {
12410bbfda8aSnia				Scr->BorderWidth = num;
12420bbfda8aSnia			}
12430bbfda8aSnia			return true;
12440bbfda8aSnia
12450bbfda8aSnia		case kwn_IconBorderWidth:
12460bbfda8aSnia			if(Scr->FirstTime) {
12470bbfda8aSnia				Scr->IconBorderWidth = num;
12480bbfda8aSnia			}
12490bbfda8aSnia			return true;
12500bbfda8aSnia
12510bbfda8aSnia		case kwn_TitleButtonBorderWidth:
12520bbfda8aSnia			if(Scr->FirstTime) {
12530bbfda8aSnia				Scr->TBInfo.border = num;
12540bbfda8aSnia			}
12550bbfda8aSnia			return true;
12560bbfda8aSnia
12570bbfda8aSnia		case kwn_RaiseDelay:
12580bbfda8aSnia			RaiseDelay = num;
12590bbfda8aSnia			return true;
12600bbfda8aSnia
12610bbfda8aSnia		case kwn_TransientOnTop:
12620bbfda8aSnia			if(Scr->FirstTime) {
12630bbfda8aSnia				Scr->TransientOnTop = num;
12640bbfda8aSnia			}
12650bbfda8aSnia			return true;
12660bbfda8aSnia
12670bbfda8aSnia		case kwn_OpaqueMoveThreshold:
12680bbfda8aSnia			if(Scr->FirstTime) {
12690bbfda8aSnia				Scr->OpaqueMoveThreshold = num;
12700bbfda8aSnia			}
12710bbfda8aSnia			return true;
12720bbfda8aSnia
12730bbfda8aSnia		case kwn_OpaqueResizeThreshold:
12740bbfda8aSnia			if(Scr->FirstTime) {
12750bbfda8aSnia				Scr->OpaqueResizeThreshold = num;
12760bbfda8aSnia			}
12770bbfda8aSnia			return true;
12780bbfda8aSnia
12790bbfda8aSnia		case kwn_WMgrVertButtonIndent:
12800bbfda8aSnia			if(Scr->FirstTime) {
12810bbfda8aSnia				Scr->WMgrVertButtonIndent = num;
12820bbfda8aSnia			}
12830bbfda8aSnia			if(Scr->WMgrVertButtonIndent < 0) {
12840bbfda8aSnia				Scr->WMgrVertButtonIndent = 0;
12850bbfda8aSnia			}
12860bbfda8aSnia			Scr->workSpaceMgr.vspace = Scr->WMgrVertButtonIndent;
12870bbfda8aSnia			Scr->workSpaceMgr.occupyWindow->vspace = Scr->WMgrVertButtonIndent;
12880bbfda8aSnia			return true;
12890bbfda8aSnia
12900bbfda8aSnia		case kwn_WMgrHorizButtonIndent:
12910bbfda8aSnia			if(Scr->FirstTime) {
12920bbfda8aSnia				Scr->WMgrHorizButtonIndent = num;
12930bbfda8aSnia			}
12940bbfda8aSnia			if(Scr->WMgrHorizButtonIndent < 0) {
12950bbfda8aSnia				Scr->WMgrHorizButtonIndent = 0;
12960bbfda8aSnia			}
12970bbfda8aSnia			Scr->workSpaceMgr.hspace = Scr->WMgrHorizButtonIndent;
12980bbfda8aSnia			Scr->workSpaceMgr.occupyWindow->hspace = Scr->WMgrHorizButtonIndent;
12990bbfda8aSnia			return true;
13000bbfda8aSnia
13010bbfda8aSnia		case kwn_WMgrButtonShadowDepth:
13020bbfda8aSnia			if(Scr->FirstTime) {
13030bbfda8aSnia				Scr->WMgrButtonShadowDepth = num;
13040bbfda8aSnia			}
13050bbfda8aSnia			if(Scr->WMgrButtonShadowDepth < 1) {
13060bbfda8aSnia				Scr->WMgrButtonShadowDepth = 1;
13070bbfda8aSnia			}
13080bbfda8aSnia			return true;
13090bbfda8aSnia
13100bbfda8aSnia		case kwn_MaxIconTitleWidth:
13110bbfda8aSnia			if(Scr->FirstTime) {
13120bbfda8aSnia				Scr->MaxIconTitleWidth = num;
13130bbfda8aSnia			}
13140bbfda8aSnia			return true;
13150bbfda8aSnia
13160bbfda8aSnia		case kwn_ClearShadowContrast:
13170bbfda8aSnia			if(Scr->FirstTime) {
13180bbfda8aSnia				Scr->ClearShadowContrast = num;
13190bbfda8aSnia			}
13200bbfda8aSnia			if(Scr->ClearShadowContrast < 0) {
13210bbfda8aSnia				Scr->ClearShadowContrast = 0;
13220bbfda8aSnia			}
13230bbfda8aSnia			if(Scr->ClearShadowContrast > 100) {
13240bbfda8aSnia				Scr->ClearShadowContrast = 100;
13250bbfda8aSnia			}
13260bbfda8aSnia			return true;
13270bbfda8aSnia
13280bbfda8aSnia		case kwn_DarkShadowContrast:
13290bbfda8aSnia			if(Scr->FirstTime) {
13300bbfda8aSnia				Scr->DarkShadowContrast = num;
13310bbfda8aSnia			}
13320bbfda8aSnia			if(Scr->DarkShadowContrast < 0) {
13330bbfda8aSnia				Scr->DarkShadowContrast = 0;
13340bbfda8aSnia			}
13350bbfda8aSnia			if(Scr->DarkShadowContrast > 100) {
13360bbfda8aSnia				Scr->DarkShadowContrast = 100;
13370bbfda8aSnia			}
13380bbfda8aSnia			return true;
13390bbfda8aSnia
13400bbfda8aSnia		case kwn_AnimationSpeed:
13410bbfda8aSnia			if(num < 0) {
13420bbfda8aSnia				num = 0;
13430bbfda8aSnia			}
13440bbfda8aSnia			SetAnimationSpeed(num);
13450bbfda8aSnia			return true;
13460bbfda8aSnia
13470bbfda8aSnia		case kwn_BorderShadowDepth:
13480bbfda8aSnia			if(Scr->FirstTime) {
13490bbfda8aSnia				Scr->BorderShadowDepth = num;
13500bbfda8aSnia			}
13510bbfda8aSnia			if(Scr->BorderShadowDepth < 0) {
13520bbfda8aSnia				Scr->BorderShadowDepth = 2;
13530bbfda8aSnia			}
13540bbfda8aSnia			return true;
13550bbfda8aSnia
13560bbfda8aSnia		case kwn_BorderLeft:
13570bbfda8aSnia			if(Scr->FirstTime) {
13580bbfda8aSnia				Scr->BorderLeft = num;
13590bbfda8aSnia			}
13600bbfda8aSnia			if(Scr->BorderLeft < 0) {
13610bbfda8aSnia				Scr->BorderLeft = 0;
13620bbfda8aSnia			}
13630bbfda8aSnia			return true;
13640bbfda8aSnia
13650bbfda8aSnia		case kwn_BorderRight:
13660bbfda8aSnia			if(Scr->FirstTime) {
13670bbfda8aSnia				Scr->BorderRight = num;
13680bbfda8aSnia			}
13690bbfda8aSnia			if(Scr->BorderRight < 0) {
13700bbfda8aSnia				Scr->BorderRight = 0;
13710bbfda8aSnia			}
13720bbfda8aSnia			return true;
13730bbfda8aSnia
13740bbfda8aSnia		case kwn_BorderTop:
13750bbfda8aSnia			if(Scr->FirstTime) {
13760bbfda8aSnia				Scr->BorderTop = num;
13770bbfda8aSnia			}
13780bbfda8aSnia			if(Scr->BorderTop < 0) {
13790bbfda8aSnia				Scr->BorderTop = 0;
13800bbfda8aSnia			}
13810bbfda8aSnia			return true;
13820bbfda8aSnia
13830bbfda8aSnia		case kwn_BorderBottom:
13840bbfda8aSnia			if(Scr->FirstTime) {
13850bbfda8aSnia				Scr->BorderBottom = num;
13860bbfda8aSnia			}
13870bbfda8aSnia			if(Scr->BorderBottom < 0) {
13880bbfda8aSnia				Scr->BorderBottom = 0;
13890bbfda8aSnia			}
13900bbfda8aSnia			return true;
13910bbfda8aSnia
13920bbfda8aSnia		case kwn_TitleButtonShadowDepth:
13930bbfda8aSnia			if(Scr->FirstTime) {
13940bbfda8aSnia				Scr->TitleButtonShadowDepth = num;
13950bbfda8aSnia			}
13960bbfda8aSnia			if(Scr->TitleButtonShadowDepth < 0) {
13970bbfda8aSnia				Scr->TitleButtonShadowDepth = 2;
13980bbfda8aSnia			}
13990bbfda8aSnia			return true;
14000bbfda8aSnia
14010bbfda8aSnia		case kwn_TitleShadowDepth:
14020bbfda8aSnia			if(Scr->FirstTime) {
14030bbfda8aSnia				Scr->TitleShadowDepth = num;
14040bbfda8aSnia			}
14050bbfda8aSnia			if(Scr->TitleShadowDepth < 0) {
14060bbfda8aSnia				Scr->TitleShadowDepth = 2;
14070bbfda8aSnia			}
14080bbfda8aSnia			return true;
14090bbfda8aSnia
14100bbfda8aSnia		case kwn_IconManagerShadowDepth:
14110bbfda8aSnia			if(Scr->FirstTime) {
14120bbfda8aSnia				Scr->IconManagerShadowDepth = num;
14130bbfda8aSnia			}
14140bbfda8aSnia			if(Scr->IconManagerShadowDepth < 0) {
14150bbfda8aSnia				Scr->IconManagerShadowDepth = 2;
14160bbfda8aSnia			}
14170bbfda8aSnia			return true;
14180bbfda8aSnia
14190bbfda8aSnia		case kwn_MenuShadowDepth:
14200bbfda8aSnia			if(Scr->FirstTime) {
14210bbfda8aSnia				Scr->MenuShadowDepth = num;
14220bbfda8aSnia			}
14230bbfda8aSnia			if(Scr->MenuShadowDepth < 0) {
14240bbfda8aSnia				Scr->MenuShadowDepth = 2;
14250bbfda8aSnia			}
14260bbfda8aSnia			return true;
14270bbfda8aSnia
14280bbfda8aSnia		case kwn_OpenWindowTimeout:
14290bbfda8aSnia			if(Scr->FirstTime) {
14300bbfda8aSnia				Scr->OpenWindowTimeout = num;
14310bbfda8aSnia			}
14320bbfda8aSnia			if(Scr->OpenWindowTimeout < 0) {
14330bbfda8aSnia				Scr->OpenWindowTimeout = 0;
14340bbfda8aSnia			}
14350bbfda8aSnia			return true;
14360bbfda8aSnia
14370bbfda8aSnia		case kwn_RaiseOnClickButton:
14380bbfda8aSnia			if(Scr->FirstTime) {
14390bbfda8aSnia				Scr->RaiseOnClickButton = num;
14400bbfda8aSnia			}
14410bbfda8aSnia			if(Scr->RaiseOnClickButton < 1) {
14420bbfda8aSnia				Scr->RaiseOnClickButton = 1;
14430bbfda8aSnia			}
14440bbfda8aSnia			if(Scr->RaiseOnClickButton > MAX_BUTTONS) {
14450bbfda8aSnia				Scr->RaiseOnClickButton = MAX_BUTTONS;
14460bbfda8aSnia			}
14470bbfda8aSnia			return true;
14480bbfda8aSnia
14490bbfda8aSnia
14500bbfda8aSnia	}
14510bbfda8aSnia
14520bbfda8aSnia	return false;
14530bbfda8aSnia}
14540bbfda8aSnia
14550bbfda8aSnianame_list **
14560bbfda8aSniado_colorlist_keyword(int keyword, int colormode, char *s)
14570bbfda8aSnia{
14580bbfda8aSnia	switch(keyword) {
14590bbfda8aSnia		case kwcl_BorderColor:
14600bbfda8aSnia			GetColor(colormode, &Scr->BorderColorC.back, s);
14610bbfda8aSnia			return &Scr->BorderColorL;
14620bbfda8aSnia
14630bbfda8aSnia		case kwcl_IconManagerHighlight:
14640bbfda8aSnia			GetColor(colormode, &Scr->IconManagerHighlight, s);
14650bbfda8aSnia			return &Scr->IconManagerHighlightL;
14660bbfda8aSnia
14670bbfda8aSnia		case kwcl_BorderTileForeground:
14680bbfda8aSnia			GetColor(colormode, &Scr->BorderTileC.fore, s);
14690bbfda8aSnia			return &Scr->BorderTileForegroundL;
14700bbfda8aSnia
14710bbfda8aSnia		case kwcl_BorderTileBackground:
14720bbfda8aSnia			GetColor(colormode, &Scr->BorderTileC.back, s);
14730bbfda8aSnia			return &Scr->BorderTileBackgroundL;
14740bbfda8aSnia
14750bbfda8aSnia		case kwcl_TitleForeground:
14760bbfda8aSnia			GetColor(colormode, &Scr->TitleC.fore, s);
14770bbfda8aSnia			return &Scr->TitleForegroundL;
14780bbfda8aSnia
14790bbfda8aSnia		case kwcl_TitleBackground:
14800bbfda8aSnia			GetColor(colormode, &Scr->TitleC.back, s);
14810bbfda8aSnia			return &Scr->TitleBackgroundL;
14820bbfda8aSnia
14830bbfda8aSnia		case kwcl_IconForeground:
14840bbfda8aSnia			GetColor(colormode, &Scr->IconC.fore, s);
14850bbfda8aSnia			return &Scr->IconForegroundL;
14860bbfda8aSnia
14870bbfda8aSnia		case kwcl_IconBackground:
14880bbfda8aSnia			GetColor(colormode, &Scr->IconC.back, s);
14890bbfda8aSnia			return &Scr->IconBackgroundL;
14900bbfda8aSnia
14910bbfda8aSnia		case kwcl_IconBorderColor:
14920bbfda8aSnia			GetColor(colormode, &Scr->IconBorderColor, s);
14930bbfda8aSnia			return &Scr->IconBorderColorL;
14940bbfda8aSnia
14950bbfda8aSnia		case kwcl_IconManagerForeground:
14960bbfda8aSnia			GetColor(colormode, &Scr->IconManagerC.fore, s);
14970bbfda8aSnia			return &Scr->IconManagerFL;
14980bbfda8aSnia
14990bbfda8aSnia		case kwcl_IconManagerBackground:
15000bbfda8aSnia			GetColor(colormode, &Scr->IconManagerC.back, s);
15010bbfda8aSnia			return &Scr->IconManagerBL;
15020bbfda8aSnia
15030bbfda8aSnia		case kwcl_MapWindowBackground:
15040bbfda8aSnia			GetColor(colormode, &Scr->workSpaceMgr.windowcp.back, s);
15050bbfda8aSnia			Scr->workSpaceMgr.windowcpgiven = true;
15060bbfda8aSnia			return &Scr->workSpaceMgr.windowBackgroundL;
15070bbfda8aSnia
15080bbfda8aSnia		case kwcl_MapWindowForeground:
15090bbfda8aSnia			GetColor(colormode, &Scr->workSpaceMgr.windowcp.fore, s);
15100bbfda8aSnia			Scr->workSpaceMgr.windowcpgiven = true;
15110bbfda8aSnia			return &Scr->workSpaceMgr.windowForegroundL;
15120bbfda8aSnia	}
15130bbfda8aSnia	return NULL;
15140bbfda8aSnia}
15150bbfda8aSnia
15160bbfda8aSniabool
15170bbfda8aSniado_color_keyword(int keyword, int colormode, char *s)
15180bbfda8aSnia{
15190bbfda8aSnia	switch(keyword) {
15200bbfda8aSnia		case kwc_DefaultForeground:
15210bbfda8aSnia			GetColor(colormode, &Scr->DefaultC.fore, s);
15220bbfda8aSnia			return true;
15230bbfda8aSnia
15240bbfda8aSnia		case kwc_DefaultBackground:
15250bbfda8aSnia			GetColor(colormode, &Scr->DefaultC.back, s);
15260bbfda8aSnia			return true;
15270bbfda8aSnia
15280bbfda8aSnia		case kwc_MenuForeground:
15290bbfda8aSnia			GetColor(colormode, &Scr->MenuC.fore, s);
15300bbfda8aSnia			return true;
15310bbfda8aSnia
15320bbfda8aSnia		case kwc_MenuBackground:
15330bbfda8aSnia			GetColor(colormode, &Scr->MenuC.back, s);
15340bbfda8aSnia			return true;
15350bbfda8aSnia
15360bbfda8aSnia		case kwc_MenuTitleForeground:
15370bbfda8aSnia			GetColor(colormode, &Scr->MenuTitleC.fore, s);
15380bbfda8aSnia			return true;
15390bbfda8aSnia
15400bbfda8aSnia		case kwc_MenuTitleBackground:
15410bbfda8aSnia			GetColor(colormode, &Scr->MenuTitleC.back, s);
15420bbfda8aSnia			return true;
15430bbfda8aSnia
15440bbfda8aSnia		case kwc_MenuShadowColor:
15450bbfda8aSnia			GetColor(colormode, &Scr->MenuShadowColor, s);
15460bbfda8aSnia			return true;
15470bbfda8aSnia
15480bbfda8aSnia	}
15490bbfda8aSnia
15500bbfda8aSnia	return false;
15510bbfda8aSnia}
15520bbfda8aSnia
15530bbfda8aSnia/*
15540bbfda8aSnia * put_pixel_on_root() Save a pixel value in twm root window color property.
15550bbfda8aSnia */
15560bbfda8aSniastatic void
15570bbfda8aSniaput_pixel_on_root(Pixel pixel)
15580bbfda8aSnia{
1559b18c2d1eSnia	bool addone = true;
15600bbfda8aSnia	Atom          retAtom;
15610bbfda8aSnia	int           retFormat;
15620bbfda8aSnia	unsigned long nPixels, retAfter;
15630bbfda8aSnia	Pixel        *retProp;
15640bbfda8aSnia
1565b18c2d1eSnia	// Get current list
15660bbfda8aSnia	if(XGetWindowProperty(dpy, Scr->Root, XA__MIT_PRIORITY_COLORS, 0, 8192,
15670bbfda8aSnia	                      False, XA_CARDINAL, &retAtom,
15680bbfda8aSnia	                      &retFormat, &nPixels, &retAfter,
15690bbfda8aSnia	                      (unsigned char **)&retProp) != Success || !retProp) {
15700bbfda8aSnia		return;
15710bbfda8aSnia	}
15720bbfda8aSnia
1573b18c2d1eSnia	// See if we already have this one
1574b18c2d1eSnia	for(int i = 0; i < nPixels; i++) {
15750bbfda8aSnia		if(pixel == retProp[i]) {
1576b18c2d1eSnia			addone = false;
15770bbfda8aSnia		}
1578b18c2d1eSnia	}
15790bbfda8aSnia	XFree(retProp);
15800bbfda8aSnia
1581b18c2d1eSnia	// If not, append it
1582b18c2d1eSnia	if(addone) {
15830bbfda8aSnia		XChangeProperty(dpy, Scr->Root, XA__MIT_PRIORITY_COLORS,
15840bbfda8aSnia		                XA_CARDINAL, 32, PropModeAppend,
15850bbfda8aSnia		                (unsigned char *)&pixel, 1);
1586b18c2d1eSnia	}
15870bbfda8aSnia}
15880bbfda8aSnia
1589b18c2d1eSnia/*
1590b18c2d1eSnia * Stash for SaveColor{} values during config parsing.
1591b18c2d1eSnia */
1592b18c2d1eSniatypedef struct _cnode {
1593b18c2d1eSnia	int i;
1594b18c2d1eSnia	int cmode;
1595b18c2d1eSnia	char *sname;
1596b18c2d1eSnia	struct _cnode *next;
1597b18c2d1eSnia} Cnode;
1598b18c2d1eSniastatic Cnode *chead = NULL;
1599b18c2d1eSnia
1600b18c2d1eSnia/**
1601b18c2d1eSnia * Add a SaveColor{} entry to our stash.
1602b18c2d1eSnia */
1603b18c2d1eSniastatic void
1604b18c2d1eSniaadd_cnode(int kwcl, int cmode, char *colname)
1605b18c2d1eSnia{
1606b18c2d1eSnia	Cnode *cnew;
1607b18c2d1eSnia
1608b18c2d1eSnia	cnew = calloc(1, sizeof(Cnode));
1609b18c2d1eSnia	cnew->i     = kwcl;
1610b18c2d1eSnia	cnew->cmode = cmode;
1611b18c2d1eSnia	cnew->sname = colname;
1612b18c2d1eSnia
1613b18c2d1eSnia	if(!chead) {
1614b18c2d1eSnia		chead = cnew;
1615b18c2d1eSnia	}
1616b18c2d1eSnia	else {
1617b18c2d1eSnia		cnew->next = chead;
1618b18c2d1eSnia		chead = cnew;
1619b18c2d1eSnia	}
1620b18c2d1eSnia
1621b18c2d1eSnia	return;
1622b18c2d1eSnia}
1623b18c2d1eSnia
1624b18c2d1eSnia
16250bbfda8aSnia/*
16260bbfda8aSnia * do_string_savecolor() save a color from a string in the twmrc file.
16270bbfda8aSnia */
16280bbfda8aSniavoid
16290bbfda8aSniado_string_savecolor(int colormode, char *s)
16300bbfda8aSnia{
1631b18c2d1eSnia	add_cnode(0, colormode, s);
16320bbfda8aSnia}
16330bbfda8aSnia
16340bbfda8aSnia/*
16350bbfda8aSnia * do_var_savecolor() save a color from a var in the twmrc file.
16360bbfda8aSnia */
16370bbfda8aSniavoid
16380bbfda8aSniado_var_savecolor(int key)
16390bbfda8aSnia{
1640b18c2d1eSnia	add_cnode(key, 0, NULL);
16410bbfda8aSnia}
16420bbfda8aSnia
16430bbfda8aSnia/*
16440bbfda8aSnia * assign_var_savecolor() traverse the var save color list placeing the pixels
16450bbfda8aSnia *                        in the root window property.
16460bbfda8aSnia */
16470bbfda8aSniavoid
16480bbfda8aSniaassign_var_savecolor(void)
16490bbfda8aSnia{
1650b18c2d1eSnia	Cnode *cp = chead;
1651b18c2d1eSnia
1652b18c2d1eSnia	// Start with an empty property
1653b18c2d1eSnia	XChangeProperty(dpy, Scr->Root, XA__MIT_PRIORITY_COLORS,
1654b18c2d1eSnia	                XA_CARDINAL, 32, PropModeReplace, NULL, 0);
1655b18c2d1eSnia
1656b18c2d1eSnia	// Loop over, stash 'em, and clean up
16570bbfda8aSnia	while(cp != NULL) {
1658b18c2d1eSnia		Cnode *tmp_cp = cp;
1659b18c2d1eSnia
16600bbfda8aSnia		switch(cp->i) {
16610bbfda8aSnia			case kwcl_BorderColor:
16620bbfda8aSnia				put_pixel_on_root(Scr->BorderColorC.back);
16630bbfda8aSnia				break;
16640bbfda8aSnia			case kwcl_IconManagerHighlight:
16650bbfda8aSnia				put_pixel_on_root(Scr->IconManagerHighlight);
16660bbfda8aSnia				break;
16670bbfda8aSnia			case kwcl_BorderTileForeground:
16680bbfda8aSnia				put_pixel_on_root(Scr->BorderTileC.fore);
16690bbfda8aSnia				break;
16700bbfda8aSnia			case kwcl_BorderTileBackground:
16710bbfda8aSnia				put_pixel_on_root(Scr->BorderTileC.back);
16720bbfda8aSnia				break;
16730bbfda8aSnia			case kwcl_TitleForeground:
16740bbfda8aSnia				put_pixel_on_root(Scr->TitleC.fore);
16750bbfda8aSnia				break;
16760bbfda8aSnia			case kwcl_TitleBackground:
16770bbfda8aSnia				put_pixel_on_root(Scr->TitleC.back);
16780bbfda8aSnia				break;
16790bbfda8aSnia			case kwcl_IconForeground:
16800bbfda8aSnia				put_pixel_on_root(Scr->IconC.fore);
16810bbfda8aSnia				break;
16820bbfda8aSnia			case kwcl_IconBackground:
16830bbfda8aSnia				put_pixel_on_root(Scr->IconC.back);
16840bbfda8aSnia				break;
16850bbfda8aSnia			case kwcl_IconBorderColor:
16860bbfda8aSnia				put_pixel_on_root(Scr->IconBorderColor);
16870bbfda8aSnia				break;
16880bbfda8aSnia			case kwcl_IconManagerForeground:
16890bbfda8aSnia				put_pixel_on_root(Scr->IconManagerC.fore);
16900bbfda8aSnia				break;
16910bbfda8aSnia			case kwcl_IconManagerBackground:
16920bbfda8aSnia				put_pixel_on_root(Scr->IconManagerC.back);
16930bbfda8aSnia				break;
16940bbfda8aSnia			case kwcl_MapWindowForeground:
16950bbfda8aSnia				put_pixel_on_root(Scr->workSpaceMgr.windowcp.fore);
16960bbfda8aSnia				break;
16970bbfda8aSnia			case kwcl_MapWindowBackground:
16980bbfda8aSnia				put_pixel_on_root(Scr->workSpaceMgr.windowcp.back);
16990bbfda8aSnia				break;
1700b18c2d1eSnia			case 0: {
1701b18c2d1eSnia				// This means it's a string, not one of our keywords
1702b18c2d1eSnia				Pixel p;
1703b18c2d1eSnia				GetColor(cp->cmode, &p, cp->sname);
1704b18c2d1eSnia				put_pixel_on_root(p);
1705b18c2d1eSnia			}
17060bbfda8aSnia		}
1707b18c2d1eSnia
17080bbfda8aSnia		cp = cp->next;
1709b18c2d1eSnia		free(tmp_cp);
17100bbfda8aSnia	}
17110bbfda8aSnia	if(chead) {
17120bbfda8aSnia		chead = NULL;
17130bbfda8aSnia	}
17140bbfda8aSnia}
17150bbfda8aSnia
17160bbfda8aSnia
17170bbfda8aSnia/*
17180bbfda8aSnia * RandomPlacement [...] parse
17190bbfda8aSnia */
17200bbfda8aSniastatic int
17210bbfda8aSniaParseRandomPlacement(const char *s)
17220bbfda8aSnia{
17230bbfda8aSnia	/* No first arg -> 'all' */
17240bbfda8aSnia	if(s == NULL) {
17250bbfda8aSnia		return RP_ALL;
17260bbfda8aSnia	}
17270bbfda8aSnia	if(strlen(s) == 0) {
17280bbfda8aSnia		return RP_ALL;
17290bbfda8aSnia	}
17300bbfda8aSnia
17310bbfda8aSnia#define CHK(str, ret) if(strcasecmp(s, str) == 0) { return RP_##ret; }
17320bbfda8aSnia	CHK(DEFSTRING,  ALL);
17330bbfda8aSnia	CHK("on",       ALL);
17340bbfda8aSnia	CHK("all",      ALL);
17350bbfda8aSnia	CHK("off",      OFF);
17360bbfda8aSnia	CHK("unmapped", UNMAPPED);
17370bbfda8aSnia#undef CHK
17380bbfda8aSnia
17390bbfda8aSnia	return -1;
17400bbfda8aSnia}
17410bbfda8aSnia
17420bbfda8aSnia
17430bbfda8aSnia/*
17440bbfda8aSnia * Parse out IconRegionJustification string.
17450bbfda8aSnia *
17460bbfda8aSnia * X-ref comment on ParseAlignement about return value.
17470bbfda8aSnia */
17480bbfda8aSniaint
17490bbfda8aSniaParseIRJustification(const char *s)
17500bbfda8aSnia{
17510bbfda8aSnia	if(strlen(s) == 0) {
17520bbfda8aSnia		return -1;
17530bbfda8aSnia	}
17540bbfda8aSnia
17550bbfda8aSnia#define CHK(str, ret) if(strcasecmp(s, str) == 0) { return IRJ_##ret; }
17560bbfda8aSnia	CHK(DEFSTRING, CENTER);
17570bbfda8aSnia	CHK("undef",   UNDEF);
17580bbfda8aSnia	CHK("left",    LEFT);
17590bbfda8aSnia	CHK("center",  CENTER);
17600bbfda8aSnia	CHK("right",   RIGHT);
17610bbfda8aSnia	CHK("border",  BORDER);
17620bbfda8aSnia#undef CHK
17630bbfda8aSnia
17640bbfda8aSnia	return -1;
17650bbfda8aSnia}
17660bbfda8aSnia
17670bbfda8aSnia
17680bbfda8aSnia/*
17690bbfda8aSnia * Parse out string for title justification.  From TitleJustification,
17700bbfda8aSnia * IconJustification, iconjust arg to IconRegion.
17710bbfda8aSnia *
17720bbfda8aSnia * X-ref comment on ParseAlignement about return value.
17730bbfda8aSnia */
17740bbfda8aSniaint
17750bbfda8aSniaParseTitleJustification(const char *s)
17760bbfda8aSnia{
17770bbfda8aSnia	if(strlen(s) == 0) {
17780bbfda8aSnia		return -1;
17790bbfda8aSnia	}
17800bbfda8aSnia
17810bbfda8aSnia#define CHK(str, ret) if(strcasecmp(s, str) == 0) { return TJ_##ret; }
17820bbfda8aSnia	/* XXX Different uses really have different defaults... */
17830bbfda8aSnia	CHK(DEFSTRING, CENTER);
17840bbfda8aSnia	CHK("undef",   UNDEF);
17850bbfda8aSnia	CHK("left",    LEFT);
17860bbfda8aSnia	CHK("center",  CENTER);
17870bbfda8aSnia	CHK("right",   RIGHT);
17880bbfda8aSnia#undef CHK
17890bbfda8aSnia
17900bbfda8aSnia	return -1;
17910bbfda8aSnia}
17920bbfda8aSnia
17930bbfda8aSnia
17940bbfda8aSnia/*
17950bbfda8aSnia * Parse out the string specifier for IconRegion Alignement[sic].
17960bbfda8aSnia * Strictly speaking, this [almost always] returns an IRAlignement enum
17970bbfda8aSnia * value.  However, it's specified as int to allow the -1 return for
17980bbfda8aSnia * invalid values.  enum's start numbering from 0 (unless specific values
17990bbfda8aSnia * are given), so that's a safe out-of-bounds value.  And making an
18000bbfda8aSnia * IRA_INVALID value would just add unnecessary complication, since
18010bbfda8aSnia * during parsing is the only time it makes sense.
18020bbfda8aSnia */
18030bbfda8aSniaint
18040bbfda8aSniaParseAlignement(const char *s)
18050bbfda8aSnia{
18060bbfda8aSnia	if(strlen(s) == 0) {
18070bbfda8aSnia		return -1;
18080bbfda8aSnia	}
18090bbfda8aSnia
18100bbfda8aSnia#define CHK(str, ret) if(strcasecmp(s, str) == 0) { return IRA_##ret; }
18110bbfda8aSnia	CHK(DEFSTRING, CENTER);
18120bbfda8aSnia	CHK("center",  CENTER);
18130bbfda8aSnia	CHK("top",     TOP);
18140bbfda8aSnia	CHK("bottom",  BOTTOM);
18150bbfda8aSnia	CHK("border",  BORDER);
18160bbfda8aSnia	CHK("undef",   UNDEF);
18170bbfda8aSnia#undef CHK
18180bbfda8aSnia
18190bbfda8aSnia	return -1;
18200bbfda8aSnia}
18210bbfda8aSnia
18220bbfda8aSniastatic int
18230bbfda8aSniaParseUsePPosition(const char *s)
18240bbfda8aSnia{
18250bbfda8aSnia	if(strlen(s) == 0) {
18260bbfda8aSnia		return -1;
18270bbfda8aSnia	}
18280bbfda8aSnia
18290bbfda8aSnia#define CHK(str, ret) if(strcasecmp(s, str) == 0) { return PPOS_##ret; }
18300bbfda8aSnia	CHK(DEFSTRING,  OFF);
18310bbfda8aSnia	CHK("off",      OFF);
18320bbfda8aSnia	CHK("on",       ON);
18330bbfda8aSnia	CHK("non-zero", NON_ZERO);
18340bbfda8aSnia	CHK("nonzero",  NON_ZERO);
18350bbfda8aSnia#undef CHK
18360bbfda8aSnia
18370bbfda8aSnia	return -1;
18380bbfda8aSnia}
18390bbfda8aSnia
18400bbfda8aSniastatic int
18410bbfda8aSniaParseButtonStyle(const char *s)
18420bbfda8aSnia{
18430bbfda8aSnia	if(s == NULL || strlen(s) == 0) {
18440bbfda8aSnia		return -1;
18450bbfda8aSnia	}
18460bbfda8aSnia
18470bbfda8aSnia#define CHK(str, ret) if(strcasecmp(s, str) == 0) { return STYLE_##ret; }
18480bbfda8aSnia	CHK(DEFSTRING, NORMAL);
18490bbfda8aSnia	CHK("normal",  NORMAL);
18500bbfda8aSnia	CHK("style1",  STYLE1);
18510bbfda8aSnia	CHK("style2",  STYLE2);
18520bbfda8aSnia	CHK("style3",  STYLE3);
18530bbfda8aSnia#undef CHK
18540bbfda8aSnia
18550bbfda8aSnia	return -1;
18560bbfda8aSnia}
18570bbfda8aSnia
18580bbfda8aSniastatic int
18590bbfda8aSniaParseIconifyStyle(const char *s)
18600bbfda8aSnia{
18610bbfda8aSnia	if(s == NULL || strlen(s) == 0) {
18620bbfda8aSnia		return -1;
18630bbfda8aSnia	}
18640bbfda8aSnia
18650bbfda8aSnia#define CHK(str, ret) if(strcasecmp(s, str) == 0) { return ICONIFY_##ret; }
18660bbfda8aSnia	CHK(DEFSTRING, NORMAL);
18670bbfda8aSnia	CHK("normal",  NORMAL);
18680bbfda8aSnia	CHK("mosaic",  MOSAIC);
18690bbfda8aSnia	CHK("zoomin",  ZOOMIN);
18700bbfda8aSnia	CHK("zoomout", ZOOMOUT);
18710bbfda8aSnia	CHK("fade",    FADE);
18720bbfda8aSnia	CHK("sweep",   SWEEP);
18730bbfda8aSnia#undef CHK
18740bbfda8aSnia
18750bbfda8aSnia	return -1;
18760bbfda8aSnia}
18770bbfda8aSnia
18780bbfda8aSniavoid
18790bbfda8aSniado_squeeze_entry(name_list **slist, // squeeze or dont-squeeze list
18800bbfda8aSnia                 const char *name,  // window name
18810bbfda8aSnia                 SIJust justify,    // left, center, right
18820bbfda8aSnia                 int num,           // signed num
18830bbfda8aSnia                 int denom)         // 0 or indicates fraction denom
18840bbfda8aSnia{
18850bbfda8aSnia	int absnum = (num < 0 ? -num : num);
18860bbfda8aSnia
18870bbfda8aSnia	if(denom < 0) {
18880bbfda8aSnia		twmrc_error_prefix();
18890bbfda8aSnia		fprintf(stderr, "negative SqueezeTitle denominator %d\n", denom);
18900bbfda8aSnia		ParseError = true;
18910bbfda8aSnia		return;
18920bbfda8aSnia	}
18930bbfda8aSnia	if(absnum > denom && denom != 0) {
18940bbfda8aSnia		twmrc_error_prefix();
18950bbfda8aSnia		fprintf(stderr, "SqueezeTitle fraction %d/%d outside window\n",
18960bbfda8aSnia		        num, denom);
18970bbfda8aSnia		ParseError = true;
18980bbfda8aSnia		return;
18990bbfda8aSnia	}
19000bbfda8aSnia	/* Process the special cases from the manual here rather than
19010bbfda8aSnia	 * each time we calculate the position of the title bar
19020bbfda8aSnia	 * in ComputeTitleLocation().
19030bbfda8aSnia	 * In fact, it's better to get rid of them entirely, but we
19040bbfda8aSnia	 * probably should not do that for compatibility's sake.
19050bbfda8aSnia	 * By using a non-zero denominator the position will be relative.
19060bbfda8aSnia	 */
19070bbfda8aSnia	if(denom == 0 && num == 0) {
19080bbfda8aSnia		if(justify == SIJ_CENTER) {
19090bbfda8aSnia			num = 1;
19100bbfda8aSnia			denom = 2;
19110bbfda8aSnia		}
19120bbfda8aSnia		else if(justify == SIJ_RIGHT) {
19130bbfda8aSnia			num = 2;
19140bbfda8aSnia			denom = 2;
19150bbfda8aSnia		}
19160bbfda8aSnia		twmrc_error_prefix();
19170bbfda8aSnia		fprintf(stderr, "deprecated SqueezeTitle faction 0/0, assuming %d/%d\n",
19180bbfda8aSnia		        num, denom);
19190bbfda8aSnia	}
19200bbfda8aSnia
19210bbfda8aSnia	if(HasShape) {
19220bbfda8aSnia		SqueezeInfo *sinfo;
19230bbfda8aSnia		sinfo = malloc(sizeof(SqueezeInfo));
19240bbfda8aSnia
19250bbfda8aSnia		if(!sinfo) {
19260bbfda8aSnia			twmrc_error_prefix();
19270bbfda8aSnia			fprintf(stderr, "unable to allocate %lu bytes for squeeze info\n",
19280bbfda8aSnia			        (unsigned long) sizeof(SqueezeInfo));
19290bbfda8aSnia			ParseError = true;
19300bbfda8aSnia			return;
19310bbfda8aSnia		}
19320bbfda8aSnia		sinfo->justify = justify;
19330bbfda8aSnia		sinfo->num = num;
19340bbfda8aSnia		sinfo->denom = denom;
19350bbfda8aSnia		AddToList(slist, name, sinfo);
19360bbfda8aSnia	}
19370bbfda8aSnia	return;
19380bbfda8aSnia}
19390bbfda8aSnia
19400bbfda8aSnia
19410bbfda8aSnia/*
19420bbfda8aSnia * Parsing for EWMHIgnore { } lists
19430bbfda8aSnia */
19440bbfda8aSniavoid
19450bbfda8aSniaproc_ewmh_ignore(void)
19460bbfda8aSnia{
19470bbfda8aSnia#ifndef EWMH
19480bbfda8aSnia	twmrc_error_prefix();
19490bbfda8aSnia	fprintf(stderr, "EWMH not enabled, EWMHIgnore { } ignored.\n");
19500bbfda8aSnia	ParseError = true;
19510bbfda8aSnia	return;
19520bbfda8aSnia#endif
19530bbfda8aSnia	/* else nada */
19540bbfda8aSnia	return;
19550bbfda8aSnia}
19560bbfda8aSniavoid
19570bbfda8aSniaadd_ewmh_ignore(char *s)
19580bbfda8aSnia{
19590bbfda8aSnia#ifndef EWMH
19600bbfda8aSnia	return;
19610bbfda8aSnia#else
19620bbfda8aSnia
19630bbfda8aSnia#define HANDLE(x) \
19640bbfda8aSnia        if(strcasecmp(s, (x)) == 0) { \
19650bbfda8aSnia                AddToList(&Scr->EWMHIgnore, (x), ""); \
19660bbfda8aSnia                return; \
19670bbfda8aSnia        }
19680bbfda8aSnia	HANDLE("STATE_MAXIMIZED_VERT");
19690bbfda8aSnia	HANDLE("STATE_MAXIMIZED_HORZ");
19700bbfda8aSnia	HANDLE("STATE_FULLSCREEN");
19710bbfda8aSnia	HANDLE("STATE_SHADED");
19720bbfda8aSnia	HANDLE("STATE_ABOVE");
19730bbfda8aSnia	HANDLE("STATE_BELOW");
19740bbfda8aSnia#undef HANDLE
19750bbfda8aSnia
19760bbfda8aSnia	twmrc_error_prefix();
19770bbfda8aSnia	fprintf(stderr, "Unexpected EWMHIgnore value '%s'\n", s);
19780bbfda8aSnia	ParseError = true;
19790bbfda8aSnia	return;
19800bbfda8aSnia#endif /* EWMH */
19810bbfda8aSnia}
19820bbfda8aSnia
19830bbfda8aSnia
19840bbfda8aSnia/*
19850bbfda8aSnia * Parsing for MWMIgnore { } lists
19860bbfda8aSnia */
19870bbfda8aSniavoid
19880bbfda8aSniaproc_mwm_ignore(void)
19890bbfda8aSnia{
19900bbfda8aSnia	/* Nothing to do */
19910bbfda8aSnia	return;
19920bbfda8aSnia}
19930bbfda8aSniavoid
19940bbfda8aSniaadd_mwm_ignore(char *s)
19950bbfda8aSnia{
19960bbfda8aSnia#define HANDLE(x) \
19970bbfda8aSnia        if(strcasecmp(s, (x)) == 0) { \
19980bbfda8aSnia                AddToList(&Scr->MWMIgnore, (x), ""); \
19990bbfda8aSnia                return; \
20000bbfda8aSnia        }
20010bbfda8aSnia	HANDLE("DECOR_BORDER");
20020bbfda8aSnia	HANDLE("DECOR_TITLE");
20030bbfda8aSnia#undef HANDLE
20040bbfda8aSnia
20050bbfda8aSnia	twmrc_error_prefix();
20060bbfda8aSnia	fprintf(stderr, "Unexpected MWMIgnore value '%s'\n", s);
20070bbfda8aSnia	ParseError = true;
20080bbfda8aSnia	return;
20090bbfda8aSnia}
2010b18c2d1eSnia
2011b18c2d1eSnia
2012b18c2d1eSnia/*
2013b18c2d1eSnia * Parsing for Layout { } lists, to override the monitor layout we
2014b18c2d1eSnia * assumed or got from RANDR.
2015b18c2d1eSnia */
2016b18c2d1eSniastatic RAreaList *override_monitors;
2017b18c2d1eSniastatic struct {
2018b18c2d1eSnia	char **names;
2019b18c2d1eSnia	int len;
2020b18c2d1eSnia	int cap;
2021b18c2d1eSnia} override_monitors_names;
2022b18c2d1eSnia
2023b18c2d1eSnia
2024b18c2d1eSnia/**
2025b18c2d1eSnia * Allocate space for our monitor override list.
2026b18c2d1eSnia */
2027b18c2d1eSniavoid
2028b18c2d1eSniainit_layout_override(void)
2029b18c2d1eSnia{
2030b18c2d1eSnia	// 4 seems like a good guess.  If we're doing this, we're probably
2031b18c2d1eSnia	// making at least 2 monitors, and >4 is gonna be pretty rare, so...
2032b18c2d1eSnia	const int initsz = 4;
2033b18c2d1eSnia
2034b18c2d1eSnia	override_monitors = RAreaListNew(initsz, NULL);
2035b18c2d1eSnia	if(override_monitors == NULL) {
2036b18c2d1eSnia		twmrc_error_prefix();
2037b18c2d1eSnia		fprintf(stderr, "Failed allocating RAreaList for monitors.\n");
2038b18c2d1eSnia		ParseError = true;
2039b18c2d1eSnia		return;
2040b18c2d1eSnia		// Maybe we should just abort(); if malloc failed allocating a
2041b18c2d1eSnia		// few dozen bytes this early, we're _screwed_.
2042b18c2d1eSnia	}
2043b18c2d1eSnia
2044b18c2d1eSnia	override_monitors_names.names = calloc(initsz, sizeof(char *));
2045b18c2d1eSnia	override_monitors_names.len = 0;
2046b18c2d1eSnia	override_monitors_names.cap = initsz;
2047b18c2d1eSnia
2048b18c2d1eSnia	return;
2049b18c2d1eSnia}
2050b18c2d1eSnia
2051b18c2d1eSnia/**
2052b18c2d1eSnia * Add an entry to our monitor list
2053b18c2d1eSnia *
2054b18c2d1eSnia * Expecting: [Name:]WxH[+X[+Y]]
2055b18c2d1eSnia */
2056b18c2d1eSniavoid
2057b18c2d1eSniaadd_layout_override_entry(const char *s)
2058b18c2d1eSnia{
2059b18c2d1eSnia	const char *tmp;
2060b18c2d1eSnia	int xpgret;
2061b18c2d1eSnia	int x, y;
2062b18c2d1eSnia	unsigned int width, height;
2063b18c2d1eSnia
2064b18c2d1eSnia	if(override_monitors == NULL) {
2065b18c2d1eSnia		// alloc failed, so just give up; we'll fail in the end anyway...
2066b18c2d1eSnia		return;
2067b18c2d1eSnia	}
2068b18c2d1eSnia
2069b18c2d1eSnia	// Got a name?
2070b18c2d1eSnia	tmp = strchr(s, ':');
2071b18c2d1eSnia	if(tmp != NULL && tmp != s) {
2072b18c2d1eSnia		// Stash the name
2073b18c2d1eSnia		override_monitors_names.names[override_monitors_names.len]
2074b18c2d1eSnia		        = strndup(s, tmp - s);
2075b18c2d1eSnia		// len advances below
2076b18c2d1eSnia
2077b18c2d1eSnia		// Advance to geom
2078b18c2d1eSnia		s = tmp + 1;
2079b18c2d1eSnia	}
2080b18c2d1eSnia	// Advance whether we got a name or not, to keep in sync.
2081b18c2d1eSnia	override_monitors_names.len++;
2082b18c2d1eSnia
2083b18c2d1eSnia
2084b18c2d1eSnia	// Either way, s points at the geom now
2085b18c2d1eSnia	xpgret = XParseGeometry(s, &x, &y, &width, &height);
2086b18c2d1eSnia
2087b18c2d1eSnia	// Width and height are non-optional.  If x/y aren't given, we assume
2088b18c2d1eSnia	// +0+0.  If we're given -0's, well, we don't _support_ that, but
2089b18c2d1eSnia	// XPG() turns them into positives for us, so just accept it...
2090b18c2d1eSnia	const int has_hw = (WidthValue | HeightValue);
2091b18c2d1eSnia	if((xpgret & has_hw) != has_hw) {
2092b18c2d1eSnia		twmrc_error_prefix();
2093b18c2d1eSnia		fprintf(stderr, "Need both height and width in '%s'\n", s);
2094b18c2d1eSnia		ParseError = true;
2095b18c2d1eSnia		// Don't bother free()'ing stuff, we're going to exit after
2096b18c2d1eSnia		// parse completes
2097b18c2d1eSnia		return;
2098b18c2d1eSnia	}
2099b18c2d1eSnia	if(!(xpgret & XValue)) {
2100b18c2d1eSnia		x = 0;
2101b18c2d1eSnia	}
2102b18c2d1eSnia	if(!(xpgret & YValue)) {
2103b18c2d1eSnia		y = 0;
2104b18c2d1eSnia	}
2105b18c2d1eSnia
2106b18c2d1eSnia
2107b18c2d1eSnia	// And stash it
2108b18c2d1eSnia	RAreaListAdd(override_monitors, RAreaNewStatic(x, y, width, height));
2109b18c2d1eSnia
2110b18c2d1eSnia	// Whether we had a name for this 'monitor' or not, we need to
2111b18c2d1eSnia	// possibly grow the names list, since it has to stay in lockstep
2112b18c2d1eSnia	// with the areas as we add 'em.
2113b18c2d1eSnia	{
2114b18c2d1eSnia		char ***names = &override_monitors_names.names;
2115b18c2d1eSnia		int len = override_monitors_names.len;
2116b18c2d1eSnia
2117b18c2d1eSnia		if(len == override_monitors_names.cap) {
2118b18c2d1eSnia			char **tnames = realloc(*names, (len + 1) * sizeof(char *));
2119b18c2d1eSnia			if(tnames == NULL) {
2120b18c2d1eSnia				abort();
2121b18c2d1eSnia			}
2122b18c2d1eSnia			*names = tnames;
2123b18c2d1eSnia			override_monitors_names.cap++;
2124b18c2d1eSnia		}
2125b18c2d1eSnia	}
2126b18c2d1eSnia
2127b18c2d1eSnia	return;
2128b18c2d1eSnia}
2129b18c2d1eSnia
2130b18c2d1eSnia/**
2131b18c2d1eSnia * Finalize the override layout and store it up globally.
2132b18c2d1eSnia */
2133b18c2d1eSniavoid
2134b18c2d1eSniaproc_layout_override(void)
2135b18c2d1eSnia{
2136b18c2d1eSnia	RLayout *new_layout;
2137b18c2d1eSnia
2138b18c2d1eSnia	// Guard
2139b18c2d1eSnia	if(RAreaListLen(override_monitors) < 1) {
2140b18c2d1eSnia		// Make this non-fatal, so an empty spec not-quite-quietly does
2141b18c2d1eSnia		// nothing.
2142b18c2d1eSnia		twmrc_error_prefix();
2143b18c2d1eSnia		fprintf(stderr, "no monitors specified, ignoring MonitorLayout\n");
2144b18c2d1eSnia
2145b18c2d1eSnia		// Since it's non-fatal, we _do_ need to cleanup more
2146b18c2d1eSnia		// carefully...
2147b18c2d1eSnia		RAreaListFree(override_monitors);
2148b18c2d1eSnia		for(int i = 0; i < override_monitors_names.len ; i++) {
2149b18c2d1eSnia			free(override_monitors_names.names[i]);
2150b18c2d1eSnia		}
2151b18c2d1eSnia		free(override_monitors_names.names);
2152b18c2d1eSnia		return;
2153b18c2d1eSnia	}
2154b18c2d1eSnia
2155b18c2d1eSnia	new_layout = RLayoutNew(override_monitors);
2156b18c2d1eSnia	RLayoutSetMonitorsNames(new_layout, override_monitors_names.names);
2157b18c2d1eSnia	// Silently stop paying attention to o_m_n.  Don't free() anything,
2158b18c2d1eSnia	// since new_layout now owns it.  If we get another MonitorLayout{}
2159b18c2d1eSnia	// block, it'll start over again with init(), and allocate new space.
2160b18c2d1eSnia
2161b18c2d1eSnia#ifdef DEBUG
2162b18c2d1eSnia	fprintf(stderr, "Overridden layout: ");
2163b18c2d1eSnia	RLayoutPrint(new_layout);
2164b18c2d1eSnia#endif
2165b18c2d1eSnia
2166b18c2d1eSnia	RLayoutFree(Scr->Layout);
2167b18c2d1eSnia	Scr->Layout = new_layout;
2168b18c2d1eSnia	return;
2169b18c2d1eSnia}
2170