parse_be.c revision 0bbfda8a
1/*
2 * Parser backend routines.
3 *
4 * Roughly, these are the routines that the lex/yacc output calls to do
5 * its work.
6 *
7 * This is very similar to the meaning of parse_yacc.c; the two may be
8 * merged at some point.
9 */
10
11#include "ctwm.h"
12
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <strings.h>
17
18#include <X11/Xatom.h>
19
20#include "ctwm_atoms.h"
21#include "screen.h"
22#include "util.h"
23#include "animate.h"
24#include "functions_defs.h"
25#include "image.h"
26#include "list.h"
27#include "occupation.h"
28#include "parse.h"
29#include "parse_be.h"
30#include "parse_yacc.h"
31#ifdef SOUNDS
32#  include "sound.h"
33#endif
34
35#include "gram.tab.h"
36
37
38static int ParseRandomPlacement(const char *s);
39static int ParseButtonStyle(const char *s);
40static int ParseUsePPosition(const char *s);
41static int ParseIconifyStyle(const char *s);
42
43
44
45/**********************************************************************
46 *
47 *  Parsing table and routines
48 *
49 ***********************************************************************/
50
51typedef struct _TwmKeyword {
52	const char *name;
53	int value;
54	int subnum;
55} TwmKeyword;
56
57#define kw0_NoDefaults                  1
58#define kw0_AutoRelativeResize          2
59#define kw0_ForceIcons                  3
60#define kw0_NoIconManagers              4
61#define kw0_InterpolateMenuColors       6
62//#define kw0_NoVersion                 7
63#define kw0_SortIconManager             8
64#define kw0_NoGrabServer                9
65#define kw0_NoMenuShadows               10
66#define kw0_NoRaiseOnMove               11
67#define kw0_NoRaiseOnResize             12
68#define kw0_NoRaiseOnDeiconify          13
69#define kw0_DontMoveOff                 14
70#define kw0_NoBackingStore              15
71#define kw0_NoSaveUnders                16
72#define kw0_RestartPreviousState        17
73#define kw0_ClientBorderWidth           18
74#define kw0_NoTitleFocus                19
75#define kw0_DecorateTransients          21
76#define kw0_ShowIconManager             22
77#define kw0_NoCaseSensitive             23
78#define kw0_NoRaiseOnWarp               24
79#define kw0_WarpUnmapped                25
80#define kw0_ShowWorkspaceManager        27
81#define kw0_StartInMapState             28
82#define kw0_NoShowOccupyAll             29
83#define kw0_AutoOccupy                  30
84#define kw0_TransientHasOccupation      31
85#define kw0_DontPaintRootWindow         32
86#define kw0_Use3DMenus                  33
87#define kw0_Use3DTitles                 34
88#define kw0_Use3DIconManagers           35
89#define kw0_Use3DBorders                36
90#define kw0_SunkFocusWindowTitle        37
91#define kw0_BeNiceToColormap            38
92#define kw0_WarpRingOnScreen            40
93#define kw0_NoIconManagerFocus          41
94#define kw0_StayUpMenus                 42
95#define kw0_ClickToFocus                43
96#define kw0_BorderResizeCursors         44
97#define kw0_ReallyMoveInWorkspaceManager 45
98#define kw0_ShowWinWhenMovingInWmgr     46
99#define kw0_Use3DWMap                   47
100#define kw0_ReverseCurrentWorkspace     48
101#define kw0_DontWarpCursorInWMap        49
102#define kw0_CenterFeedbackWindow        50
103#define kw0_WarpToDefaultMenuEntry      51
104#define kw0_ShrinkIconTitles            52
105#define kw0_AutoRaiseIcons              53
106//#define kw0_use3DIconBorders            54
107#define kw0_UseSunkTitlePixmap          55
108#define kw0_ShortAllWindowsMenus        56
109#define kw0_RaiseWhenAutoUnSqueeze      57
110#define kw0_RaiseOnClick                58
111#define kw0_IgnoreLockModifier          59
112#define kw0_AutoFocusToTransients       60 /* kai */
113#define kw0_PackNewWindows              61
114#define kw0_IgnoreCaseInMenuSelection   62
115#define kw0_SloppyFocus                 63
116#define kw0_NoImagesInWorkSpaceManager  64
117#define kw0_NoWarpToMenuTitle           65
118#define kw0_SaveWorkspaceFocus          66 /* blais */
119#define kw0_RaiseOnWarp                 67
120#define kw0_DontShowWelcomeWindow       68
121#define kw0_AutoPriority                69
122#define kw0_DontToggleWorkspacemanagerState 70
123#define kw0_BackingStore                71
124#define kw0_StartInButtonState          72
125#define kw0_NoSortIconManager           73
126#define kw0_NoRestartPreviousState      74
127#define kw0_NoDecorateTransients        75
128#define kw0_GrabServer                  76
129#define kw0_DontNameDecorations         77
130#define kw0_StrictWinNameEncoding       78
131
132#define kws_UsePPosition                1
133#define kws_IconFont                    2
134#define kws_ResizeFont                  3
135#define kws_MenuFont                    4
136#define kws_TitleFont                   5
137#define kws_IconManagerFont             6
138#define kws_UnknownIcon                 7
139#define kws_IconDirectory               8
140#define kws_MaxWindowSize               9
141#define kws_PixmapDirectory             10
142/* RandomPlacement moved because it's now a string string keyword */
143#define kws_IconJustification           12
144#define kws_TitleJustification          13
145#define kws_IconRegionJustification     14
146#define kws_IconRegionAlignement        15
147#define kws_SoundHost                   16
148#define kws_WMgrButtonStyle             17
149#define kws_WorkSpaceFont               18
150#define kws_IconifyStyle                19
151#define kws_IconSize                    20
152#define kws_RplaySoundHost              21
153
154#define kwss_RandomPlacement            1
155
156#define kwn_ConstrainedMoveTime         1
157#define kwn_MoveDelta                   2
158#define kwn_XorValue                    3
159#define kwn_FramePadding                4
160#define kwn_TitlePadding                5
161#define kwn_ButtonIndent                6
162#define kwn_BorderWidth                 7
163#define kwn_IconBorderWidth             8
164#define kwn_TitleButtonBorderWidth      9
165#define kwn_RaiseDelay                  10
166#define kwn_TransientOnTop              11
167#define kwn_OpaqueMoveThreshold         12
168#define kwn_OpaqueResizeThreshold       13
169#define kwn_WMgrVertButtonIndent        14
170#define kwn_WMgrHorizButtonIndent       15
171#define kwn_ClearShadowContrast         16
172#define kwn_DarkShadowContrast          17
173#define kwn_WMgrButtonShadowDepth       18
174#define kwn_MaxIconTitleWidth           19
175#define kwn_AnimationSpeed              20
176#define kwn_ThreeDBorderWidth           21
177#define kwn_MoveOffResistance           22
178#define kwn_BorderShadowDepth           23
179#define kwn_TitleShadowDepth            24
180#define kwn_TitleButtonShadowDepth      25
181#define kwn_MenuShadowDepth             26
182#define kwn_IconManagerShadowDepth      27
183#define kwn_MovePackResistance          28
184#define kwn_XMoveGrid                   29
185#define kwn_YMoveGrid                   30
186#define kwn_OpenWindowTimeout           31
187#define kwn_RaiseOnClickButton          32
188
189#define kwn_BorderTop                   33
190#define kwn_BorderBottom                34
191#define kwn_BorderLeft                  35
192#define kwn_BorderRight                 36
193
194#define kwcl_BorderColor                1
195#define kwcl_IconManagerHighlight       2
196#define kwcl_BorderTileForeground       3
197#define kwcl_BorderTileBackground       4
198#define kwcl_TitleForeground            5
199#define kwcl_TitleBackground            6
200#define kwcl_IconForeground             7
201#define kwcl_IconBackground             8
202#define kwcl_IconBorderColor            9
203#define kwcl_IconManagerForeground      10
204#define kwcl_IconManagerBackground      11
205#define kwcl_MapWindowBackground        12
206#define kwcl_MapWindowForeground        13
207
208#define kwc_DefaultForeground           1
209#define kwc_DefaultBackground           2
210#define kwc_MenuForeground              3
211#define kwc_MenuBackground              4
212#define kwc_MenuTitleForeground         5
213#define kwc_MenuTitleBackground         6
214#define kwc_MenuShadowColor             7
215
216
217/*
218 * The following is sorted alphabetically according to name (which must be
219 * in lowercase and only contain the letters a-z).  It is fed to a binary
220 * search to parse keywords.
221 */
222static const TwmKeyword keytable[] = {
223	{ "a",                      ALTER, 0 },
224	{ "all",                    ALL, 0 },
225	{ "alter",                  ALTER, 0 },
226	{ "alwaysontop",            ALWAYS_ON_TOP, 0 },
227	{ "alwaysshowwindowwhenmovingfromworkspacemanager", KEYWORD, kw0_ShowWinWhenMovingInWmgr },
228	{ "alwayssqueezetogravity", ALWAYSSQUEEZETOGRAVITY, 0 },
229	{ "animationspeed",         NKEYWORD, kwn_AnimationSpeed },
230	{ "autofocustotransients",  KEYWORD, kw0_AutoFocusToTransients }, /* kai */
231	{ "autolower",              AUTO_LOWER, 0 },
232	{ "autooccupy",             KEYWORD, kw0_AutoOccupy },
233	{ "autopopup",              AUTO_POPUP, 0 },
234	{ "autopriority",           KEYWORD, kw0_AutoPriority },
235	{ "autoraise",              AUTO_RAISE, 0 },
236	{ "autoraiseicons",         KEYWORD, kw0_AutoRaiseIcons },
237	{ "autorelativeresize",     KEYWORD, kw0_AutoRelativeResize },
238	{ "autosqueeze",            AUTOSQUEEZE, 0 },
239	{ "backingstore",           KEYWORD, kw0_BackingStore },
240	{ "benicetocolormap",       KEYWORD, kw0_BeNiceToColormap },
241	{ "borderbottom",           NKEYWORD, kwn_BorderBottom },
242	{ "bordercolor",            CLKEYWORD, kwcl_BorderColor },
243	{ "borderleft",             NKEYWORD, kwn_BorderLeft },
244	{ "borderresizecursors",    KEYWORD, kw0_BorderResizeCursors },
245	{ "borderright",            NKEYWORD, kwn_BorderRight },
246	{ "bordershadowdepth",      NKEYWORD, kwn_BorderShadowDepth },
247	{ "bordertilebackground",   CLKEYWORD, kwcl_BorderTileBackground },
248	{ "bordertileforeground",   CLKEYWORD, kwcl_BorderTileForeground },
249	{ "bordertop",              NKEYWORD, kwn_BorderTop },
250	{ "borderwidth",            NKEYWORD, kwn_BorderWidth },
251	{ "button",                 BUTTON, 0 },
252	{ "buttonindent",           NKEYWORD, kwn_ButtonIndent },
253	{ "c",                      CONTROL, 0 },
254	{ "center",                 SIJENUM, SIJ_CENTER },
255	{ "centerfeedbackwindow",   KEYWORD, kw0_CenterFeedbackWindow },
256	{ "changeworkspacefunction", CHANGE_WORKSPACE_FUNCTION, 0 },
257	{ "clearshadowcontrast",    NKEYWORD, kwn_ClearShadowContrast },
258	{ "clicktofocus",           KEYWORD, kw0_ClickToFocus },
259	{ "clientborderwidth",      KEYWORD, kw0_ClientBorderWidth },
260	{ "color",                  COLOR, 0 },
261	{ "constrainedmovetime",    NKEYWORD, kwn_ConstrainedMoveTime },
262	{ "control",                CONTROL, 0 },
263	{ "cursors",                CURSORS, 0 },
264	{ "darkshadowcontrast",     NKEYWORD, kwn_DarkShadowContrast },
265	{ "decoratetransients",     KEYWORD, kw0_DecorateTransients },
266	{ "defaultbackground",      CKEYWORD, kwc_DefaultBackground },
267	{ "defaultforeground",      CKEYWORD, kwc_DefaultForeground },
268	{ "defaultfunction",        DEFAULT_FUNCTION, 0 },
269	{ "deiconifyfunction",      DEICONIFY_FUNCTION, 0 },
270	{ "destroy",                KILL, 0 },
271	{ "donticonifybyunmapping", DONT_ICONIFY_BY_UNMAPPING, 0 },
272	{ "dontmoveoff",            KEYWORD, kw0_DontMoveOff },
273	{ "dontnamedecorations",    KEYWORD, kw0_DontNameDecorations },
274	{ "dontpaintrootwindow",    KEYWORD, kw0_DontPaintRootWindow },
275	{ "dontsave",               DONT_SAVE, 0 },
276	{ "dontsetinactive",        DONTSETINACTIVE, 0 },
277	{ "dontshowwelcomewindow",  KEYWORD, kw0_DontShowWelcomeWindow },
278	{ "dontsqueezetitle",       DONT_SQUEEZE_TITLE, 0 },
279	{ "donttoggleworkspacemanagerstate", KEYWORD, kw0_DontToggleWorkspacemanagerState},
280	{ "dontwarpcursorinwmap",   KEYWORD, kw0_DontWarpCursorInWMap },
281	{ "east",                   GRAVITY, GRAV_EAST },
282	{ "ewmhignore",             EWMH_IGNORE, 0 },
283	{ "f",                      FRAME, 0 },
284	{ "forcefocus",             FORCE_FOCUS, 0 },
285	{ "forceicons",             KEYWORD, kw0_ForceIcons },
286	{ "frame",                  FRAME, 0 },
287	{ "framepadding",           NKEYWORD, kwn_FramePadding },
288	{ "function",               FUNCTION, 0 },
289	{ "grabserver",             KEYWORD, kw0_GrabServer },
290	{ "i",                      ICON, 0 },
291	{ "icon",                   ICON, 0 },
292	{ "iconbackground",         CLKEYWORD, kwcl_IconBackground },
293	{ "iconbordercolor",        CLKEYWORD, kwcl_IconBorderColor },
294	{ "iconborderwidth",        NKEYWORD, kwn_IconBorderWidth },
295	{ "icondirectory",          SKEYWORD, kws_IconDirectory },
296	{ "iconfont",               SKEYWORD, kws_IconFont },
297	{ "iconforeground",         CLKEYWORD, kwcl_IconForeground },
298	{ "iconifybyunmapping",     ICONIFY_BY_UNMAPPING, 0 },
299	{ "iconifyfunction",        ICONIFY_FUNCTION, 0 },
300	{ "iconifystyle",           SKEYWORD, kws_IconifyStyle },
301	{ "iconjustification",      SKEYWORD, kws_IconJustification },
302	{ "iconmanagerbackground",  CLKEYWORD, kwcl_IconManagerBackground },
303	{ "iconmanagerdontshow",    ICONMGR_NOSHOW, 0 },
304	{ "iconmanagerfont",        SKEYWORD, kws_IconManagerFont },
305	{ "iconmanagerforeground",  CLKEYWORD, kwcl_IconManagerForeground },
306	{ "iconmanagergeometry",    ICONMGR_GEOMETRY, 0 },
307	{ "iconmanagerhighlight",   CLKEYWORD, kwcl_IconManagerHighlight },
308	{ "iconmanagers",           ICONMGRS, 0 },
309	{ "iconmanagershadowdepth", NKEYWORD, kwn_IconManagerShadowDepth },
310	{ "iconmanagershow",        ICONMGR_SHOW, 0 },
311	{ "iconmenudontshow",       ICONMENU_DONTSHOW, 0 },
312	{ "iconmgr",                ICONMGR, 0 },
313	{ "iconregion",             ICON_REGION, 0 },
314	{ "iconregionalignement",   SKEYWORD, kws_IconRegionAlignement },
315	{ "iconregionjustification", SKEYWORD, kws_IconRegionJustification },
316	{ "icons",                  ICONS, 0 },
317	{ "iconsize",               SKEYWORD, kws_IconSize },
318	{ "ignorecaseinmenuselection",      KEYWORD, kw0_IgnoreCaseInMenuSelection },
319	{ "ignorelockmodifier",     KEYWORD, kw0_IgnoreLockModifier },
320	{ "ignoremodifier",         IGNOREMODIFIER, 0 },
321	{ "ignoretransient",        IGNORE_TRANSIENT, 0 },
322	{ "interpolatemenucolors",  KEYWORD, kw0_InterpolateMenuColors },
323	{ "l",                      LOCK, 0 },
324	{ "left",                   SIJENUM, SIJ_LEFT },
325	{ "lefttitlebutton",        LEFT_TITLEBUTTON, 0 },
326	{ "lock",                   LOCK, 0 },
327	{ "m",                      META, 0 },
328	{ "maketitle",              MAKE_TITLE, 0 },
329	{ "mapwindowbackground",    CLKEYWORD, kwcl_MapWindowBackground },
330	{ "mapwindowcurrentworkspace", MAPWINDOWCURRENTWORKSPACE, 0},
331	{ "mapwindowdefaultworkspace", MAPWINDOWDEFAULTWORKSPACE, 0},
332	{ "mapwindowforeground",    CLKEYWORD, kwcl_MapWindowForeground },
333	{ "maxicontitlewidth",      NKEYWORD, kwn_MaxIconTitleWidth },
334	{ "maxwindowsize",          SKEYWORD, kws_MaxWindowSize },
335	{ "menu",                   MENU, 0 },
336	{ "menubackground",         CKEYWORD, kwc_MenuBackground },
337	{ "menufont",               SKEYWORD, kws_MenuFont },
338	{ "menuforeground",         CKEYWORD, kwc_MenuForeground },
339	{ "menushadowcolor",        CKEYWORD, kwc_MenuShadowColor },
340	{ "menushadowdepth",        NKEYWORD, kwn_MenuShadowDepth },
341	{ "menutitlebackground",    CKEYWORD, kwc_MenuTitleBackground },
342	{ "menutitleforeground",    CKEYWORD, kwc_MenuTitleForeground },
343	{ "meta",                   META, 0 },
344	{ "mod",                    META, 0 },  /* fake it */
345	{ "monochrome",             MONOCHROME, 0 },
346	{ "move",                   MOVE, 0 },
347	{ "movedelta",              NKEYWORD, kwn_MoveDelta },
348	{ "moveoffresistance",      NKEYWORD, kwn_MoveOffResistance },
349	{ "movepackresistance",     NKEYWORD, kwn_MovePackResistance },
350	{ "mwmignore",              MWM_IGNORE, 0 },
351	{ "nobackingstore",         KEYWORD, kw0_NoBackingStore },
352	{ "noborder",               NO_BORDER, 0 },
353	{ "nocasesensitive",        KEYWORD, kw0_NoCaseSensitive },
354	{ "nodecoratetransients",   KEYWORD, kw0_NoDecorateTransients },
355	{ "nodefaults",             KEYWORD, kw0_NoDefaults },
356	{ "nograbserver",           KEYWORD, kw0_NoGrabServer },
357	{ "nohighlight",            NO_HILITE, 0 },
358	{ "noiconmanagerfocus",     KEYWORD, kw0_NoIconManagerFocus },
359	{ "noiconmanagers",         KEYWORD, kw0_NoIconManagers },
360	{ "noicontitle",            NO_ICON_TITLE, 0  },
361	{ "noimagesinworkspacemanager", KEYWORD, kw0_NoImagesInWorkSpaceManager },
362	{ "nomenushadows",          KEYWORD, kw0_NoMenuShadows },
363	{ "noopaquemove",           NOOPAQUEMOVE, 0 },
364	{ "noopaqueresize",         NOOPAQUERESIZE, 0 },
365	{ "noraiseondeiconify",     KEYWORD, kw0_NoRaiseOnDeiconify },
366	{ "noraiseonmove",          KEYWORD, kw0_NoRaiseOnMove },
367	{ "noraiseonresize",        KEYWORD, kw0_NoRaiseOnResize },
368	{ "noraiseonwarp",          KEYWORD, kw0_NoRaiseOnWarp },
369	{ "norestartpreviousstate", KEYWORD, kw0_NoRestartPreviousState },
370	{ "north",                  GRAVITY, GRAV_NORTH },
371	{ "nosaveunders",           KEYWORD, kw0_NoSaveUnders },
372	{ "noshowoccupyall",        KEYWORD, kw0_NoShowOccupyAll },
373	{ "nosorticonmanager",      KEYWORD, kw0_NoSortIconManager },
374	{ "nostackmode",            NO_STACKMODE, 0 },
375	{ "notitle",                NO_TITLE, 0 },
376	{ "notitlefocus",           KEYWORD, kw0_NoTitleFocus },
377	{ "notitlehighlight",       NO_TITLE_HILITE, 0 },
378	{ "nowarptomenutitle",      KEYWORD, kw0_NoWarpToMenuTitle },
379	{ "occupy",                 OCCUPYLIST, 0 },
380	{ "occupyall",              OCCUPYALL, 0 },
381	{ "ontoppriority",          ON_TOP_PRIORITY, 0 },
382	{ "opaquemove",             OPAQUEMOVE, 0 },
383	{ "opaquemovethreshold",    NKEYWORD, kwn_OpaqueMoveThreshold },
384	{ "opaqueresize",           OPAQUERESIZE, 0 },
385	{ "opaqueresizethreshold",  NKEYWORD, kwn_OpaqueResizeThreshold },
386	{ "openwindowtimeout",      NKEYWORD, kwn_OpenWindowTimeout },
387	{ "packnewwindows",         KEYWORD, kw0_PackNewWindows },
388	{ "pixmapdirectory",        SKEYWORD, kws_PixmapDirectory },
389	{ "pixmaps",                PIXMAPS, 0 },
390	{ "prioritynotswitching",   PRIORITY_NOT_SWITCHING, 0 },
391	{ "priorityswitching",      PRIORITY_SWITCHING, 0 },
392	{ "r",                      ROOT, 0 },
393	{ "raisedelay",             NKEYWORD, kwn_RaiseDelay },
394	{ "raiseonclick",           KEYWORD, kw0_RaiseOnClick },
395	{ "raiseonclickbutton",     NKEYWORD, kwn_RaiseOnClickButton },
396	{ "raiseonwarp",            KEYWORD, kw0_RaiseOnWarp },
397	{ "raisewhenautounsqueeze", KEYWORD, kw0_RaiseWhenAutoUnSqueeze },
398	{ "randomplacement",        SSKEYWORD, kwss_RandomPlacement },
399	{ "reallymoveinworkspacemanager",   KEYWORD, kw0_ReallyMoveInWorkspaceManager },
400	{ "resize",                 RESIZE, 0 },
401	{ "resizefont",             SKEYWORD, kws_ResizeFont },
402	{ "restartpreviousstate",   KEYWORD, kw0_RestartPreviousState },
403	{ "reversecurrentworkspace", KEYWORD, kw0_ReverseCurrentWorkspace },
404	{ "right",                  SIJENUM, SIJ_RIGHT },
405	{ "righttitlebutton",       RIGHT_TITLEBUTTON, 0 },
406	{ "root",                   ROOT, 0 },
407	{ "rplaysoundhost",         SKEYWORD, kws_RplaySoundHost },
408	{ "rplaysounds",            RPLAY_SOUNDS, 0 },
409	{ "s",                      SHIFT, 0 },
410	{ "savecolor",              SAVECOLOR, 0},
411	{ "saveworkspacefocus",     KEYWORD, kw0_SaveWorkspaceFocus },
412	{ "schrinkicontitles",      KEYWORD, kw0_ShrinkIconTitles },
413	{ "select",                 SELECT, 0 },
414	{ "shift",                  SHIFT, 0 },
415	{ "shortallwindowsmenus",   KEYWORD, kw0_ShortAllWindowsMenus },
416	{ "showiconmanager",        KEYWORD, kw0_ShowIconManager },
417	{ "showworkspacemanager",   KEYWORD, kw0_ShowWorkspaceManager },
418	{ "shrinkicontitles",       KEYWORD, kw0_ShrinkIconTitles },
419	{ "sloppyfocus",            KEYWORD, kw0_SloppyFocus },
420	{ "sorticonmanager",        KEYWORD, kw0_SortIconManager },
421	{ "soundhost",              SKEYWORD, kws_SoundHost },
422	{ "south",                  GRAVITY, GRAV_SOUTH },
423	{ "squeezetitle",           SQUEEZE_TITLE, 0 },
424	{ "starticonified",         START_ICONIFIED, 0 },
425	{ "startinbuttonstate",     KEYWORD, kw0_StartInButtonState },
426	{ "startinmapstate",        KEYWORD, kw0_StartInMapState },
427	{ "startsqueezed",          STARTSQUEEZED, 0 },
428	{ "stayupmenus",            KEYWORD, kw0_StayUpMenus },
429	{ "strictwinnameencoding",  KEYWORD, kw0_StrictWinNameEncoding  },
430	{ "sunkfocuswindowtitle",   KEYWORD, kw0_SunkFocusWindowTitle },
431	{ "t",                      TITLE, 0 },
432	{ "threedborderwidth",      NKEYWORD, kwn_ThreeDBorderWidth },
433	{ "title",                  TITLE, 0 },
434	{ "titlebackground",        CLKEYWORD, kwcl_TitleBackground },
435	{ "titlebuttonborderwidth", NKEYWORD, kwn_TitleButtonBorderWidth },
436	{ "titlebuttonshadowdepth", NKEYWORD, kwn_TitleButtonShadowDepth },
437	{ "titlefont",              SKEYWORD, kws_TitleFont },
438	{ "titleforeground",        CLKEYWORD, kwcl_TitleForeground },
439	{ "titlehighlight",         TITLE_HILITE, 0 },
440	{ "titlejustification",     SKEYWORD, kws_TitleJustification },
441	{ "titlepadding",           NKEYWORD, kwn_TitlePadding },
442	{ "titleshadowdepth",       NKEYWORD, kwn_TitleShadowDepth },
443	{ "transienthasoccupation", KEYWORD, kw0_TransientHasOccupation },
444	{ "transientontop",         NKEYWORD, kwn_TransientOnTop },
445	{ "unknownicon",            SKEYWORD, kws_UnknownIcon },
446	{ "unmapbymovingfaraway",   UNMAPBYMOVINGFARAWAY, 0 },
447	{ "usepposition",           SKEYWORD, kws_UsePPosition },
448	{ "usesunktitlepixmap",     KEYWORD, kw0_UseSunkTitlePixmap },
449	{ "usethreedborders",       KEYWORD, kw0_Use3DBorders },
450	{ "usethreediconmanagers",  KEYWORD, kw0_Use3DIconManagers },
451	{ "usethreedmenus",         KEYWORD, kw0_Use3DMenus },
452	{ "usethreedtitles",        KEYWORD, kw0_Use3DTitles },
453	{ "usethreedwmap",          KEYWORD, kw0_Use3DWMap },
454	{ "virtualscreens",         VIRTUAL_SCREENS, 0 },
455	{ "w",                      WINDOW, 0 },
456	{ "wait",                   WAITC, 0 },
457	{ "warpcursor",             WARP_CURSOR, 0 },
458	{ "warpondeiconify",        WARP_ON_DEICONIFY, 0 },
459	{ "warpringonscreen",       KEYWORD, kw0_WarpRingOnScreen },
460	{ "warptodefaultmenuentry", KEYWORD, kw0_WarpToDefaultMenuEntry },
461	{ "warpunmapped",           KEYWORD, kw0_WarpUnmapped },
462	{ "west",                   GRAVITY, GRAV_WEST },
463	{ "window",                 WINDOW, 0 },
464	{ "windowbox",              WINDOW_BOX, 0 },
465	{ "windowfunction",         WINDOW_FUNCTION, 0 },
466	{ "windowgeometries",       WINDOW_GEOMETRIES, 0 },
467	{ "windowregion",           WINDOW_REGION, 0 },
468	{ "windowring",             WINDOW_RING, 0 },
469	{ "windowringexclude",      WINDOW_RING_EXCLUDE, 0},
470	{ "wmgrbuttonshadowdepth",  NKEYWORD, kwn_WMgrButtonShadowDepth },
471	{ "wmgrbuttonstyle",        SKEYWORD, kws_WMgrButtonStyle },
472	{ "wmgrhorizbuttonindent",  NKEYWORD, kwn_WMgrHorizButtonIndent },
473	{ "wmgrvertbuttonindent",   NKEYWORD, kwn_WMgrVertButtonIndent },
474	{ "workspace",              WORKSPACE, 0 },
475	{ "workspacefont",          SKEYWORD, kws_WorkSpaceFont },
476	{ "workspacemanagergeometry", WORKSPCMGR_GEOMETRY, 0 },
477	{ "workspaces",             WORKSPACES, 0},
478	{ "xmovegrid",              NKEYWORD, kwn_XMoveGrid },
479	{ "xorvalue",               NKEYWORD, kwn_XorValue },
480	{ "xpmicondirectory",       SKEYWORD, kws_PixmapDirectory },
481	{ "ymovegrid",              NKEYWORD, kwn_YMoveGrid },
482	{ "zoom",                   ZOOM, 0 },
483};
484
485static const size_t numkeywords = (sizeof(keytable) / sizeof(keytable[0]));
486
487
488/*
489 * The lookup table for functions is generated.
490 */
491#include "functions_parse_table.h"
492
493
494
495static int
496kt_compare(const void *lhs, const void *rhs)
497{
498	const TwmKeyword *l = lhs;
499	const TwmKeyword *r = rhs;
500	return strcasecmp(l->name, r->name);
501}
502
503int
504parse_keyword(const char *s, int *nump)
505{
506	const TwmKeyword srch = { .name = s };
507	TwmKeyword *ret;
508	const TwmKeyword *srchtab;
509	size_t nstab;
510
511	/* Guard; nothing can't be a valid keyword */
512	if(s == NULL || strlen(s) < 1) {
513		return ERRORTOKEN;
514	}
515
516	/*
517	 * Functions are in their own table, so check for them there.
518	 *
519	 * This is safe as long as (strlen >= 1), which we already checked.
520	 */
521	if(s[0] == 'f' && s[1] == '.') {
522		srchtab = funckeytable;
523		nstab = numfunckeywords;
524	}
525	else {
526		srchtab = keytable;
527		nstab = numkeywords;
528	}
529
530	/* Find it */
531	ret = bsearch(&srch, srchtab, nstab, sizeof(TwmKeyword), kt_compare);
532	if(ret) {
533		*nump = ret->subnum;
534		return ret->value;
535	}
536
537	return ERRORTOKEN;
538}
539
540
541/*
542 * Simple tester function
543 */
544void
545chk_keytable_order(void)
546{
547	int i;
548
549	for(i = 0 ; i < (numkeywords - 1) ; i++) {
550		if(strcasecmp(keytable[i].name, keytable[i + 1].name) >= 0) {
551			fprintf(stderr, "%s: INTERNAL ERROR: keytable sorting: "
552			        "'%s' >= '%s'\n", ProgramName,
553			        keytable[i].name, keytable[i + 1].name);
554		}
555	}
556
557	for(i = 0 ; i < (numfunckeywords - 1) ; i++) {
558		if(strcasecmp(funckeytable[i].name, funckeytable[i + 1].name) >= 0) {
559			fprintf(stderr, "%s: INTERNAL ERROR: funckeytable sorting: "
560			        "'%s' >= '%s'\n", ProgramName,
561			        funckeytable[i].name, funckeytable[i + 1].name);
562		}
563	}
564}
565
566
567
568/*
569 * action routines called by grammar
570 */
571
572bool
573do_single_keyword(int keyword)
574{
575	switch(keyword) {
576		case kw0_NoDefaults:
577			Scr->NoDefaults = true;
578			return true;
579
580		case kw0_AutoRelativeResize:
581			Scr->AutoRelativeResize = true;
582			return true;
583
584		case kw0_ForceIcons:
585			if(Scr->FirstTime) {
586				Scr->ForceIcon = true;
587			}
588			return true;
589
590		case kw0_NoIconManagers:
591			Scr->NoIconManagers = true;
592			return true;
593
594		case kw0_InterpolateMenuColors:
595			if(Scr->FirstTime) {
596				Scr->InterpolateMenuColors = true;
597			}
598			return true;
599
600		case kw0_SortIconManager:
601			if(Scr->FirstTime) {
602				Scr->SortIconMgr = true;
603			}
604			return true;
605
606		case kw0_NoSortIconManager:
607			if(Scr->FirstTime) {
608				Scr->SortIconMgr = false;
609			}
610			return true;
611
612		case kw0_GrabServer:
613			Scr->NoGrabServer = false;
614			return true;
615
616		case kw0_NoGrabServer:
617			Scr->NoGrabServer = true;
618			return true;
619
620		case kw0_NoMenuShadows:
621			if(Scr->FirstTime) {
622				Scr->Shadow = false;
623			}
624			return true;
625
626		case kw0_NoRaiseOnMove:
627			if(Scr->FirstTime) {
628				Scr->NoRaiseMove = true;
629			}
630			return true;
631
632		case kw0_NoRaiseOnResize:
633			if(Scr->FirstTime) {
634				Scr->NoRaiseResize = true;
635			}
636			return true;
637
638		case kw0_NoRaiseOnDeiconify:
639			if(Scr->FirstTime) {
640				Scr->NoRaiseDeicon = true;
641			}
642			return true;
643
644		case kw0_DontMoveOff:
645			Scr->DontMoveOff = true;
646			return true;
647
648		case kw0_NoBackingStore:
649			Scr->BackingStore = false;
650			return true;
651
652		case kw0_BackingStore:
653			Scr->BackingStore = true;
654			return true;
655
656		case kw0_NoSaveUnders:
657			Scr->SaveUnder = false;
658			return true;
659
660		// XXX Shouldn't these be in Scr too?
661		case kw0_RestartPreviousState:
662			RestartPreviousState = true;
663			return true;
664
665		case kw0_NoRestartPreviousState:
666			RestartPreviousState = false;
667			return true;
668
669		case kw0_ClientBorderWidth:
670			if(Scr->FirstTime) {
671				Scr->ClientBorderWidth = true;
672			}
673			return true;
674
675		case kw0_NoTitleFocus:
676			Scr->TitleFocus = false;
677			return true;
678
679		case kw0_DecorateTransients:
680			Scr->DecorateTransients = true;
681			return true;
682
683		case kw0_NoDecorateTransients:
684			Scr->DecorateTransients = false;
685			return true;
686
687		case kw0_ShowIconManager:
688			Scr->ShowIconManager = true;
689			return true;
690
691		case kw0_ShowWorkspaceManager:
692			Scr->ShowWorkspaceManager = true;
693			return true;
694
695		case kw0_StartInButtonState:
696			Scr->workSpaceMgr.initialstate = WMS_buttons;
697			return true;
698
699		case kw0_StartInMapState:
700			Scr->workSpaceMgr.initialstate = WMS_map;
701			return true;
702
703		case kw0_NoShowOccupyAll:
704			Scr->workSpaceMgr.noshowoccupyall = true;
705			return true;
706
707		case kw0_AutoOccupy:
708			Scr->AutoOccupy = true;
709			return true;
710
711		case kw0_AutoPriority:
712			Scr->AutoPriority = true;
713			return true;
714
715		case kw0_TransientHasOccupation:
716			Scr->TransientHasOccupation = true;
717			return true;
718
719		case kw0_DontPaintRootWindow:
720			Scr->DontPaintRootWindow = true;
721			return true;
722
723		case kw0_UseSunkTitlePixmap:
724			Scr->UseSunkTitlePixmap = true;
725			return true;
726
727		case kw0_Use3DBorders:
728			Scr->use3Dborders = true;
729			return true;
730
731		case kw0_Use3DIconManagers:
732			Scr->use3Diconmanagers = true;
733			return true;
734
735		case kw0_Use3DMenus:
736			Scr->use3Dmenus = true;
737			return true;
738
739		case kw0_Use3DTitles:
740			Scr->use3Dtitles = true;
741			return true;
742
743		case kw0_Use3DWMap:
744			Scr->use3Dwmap = true;
745			return true;
746
747		case kw0_SunkFocusWindowTitle:
748			Scr->SunkFocusWindowTitle = true;
749			return true;
750
751		case kw0_BeNiceToColormap:
752			Scr->BeNiceToColormap = true;
753			return true;
754
755		case kw0_BorderResizeCursors:
756			Scr->BorderCursors = true;
757			return true;
758
759		case kw0_NoCaseSensitive:
760			Scr->CaseSensitive = false;
761			return true;
762
763		case kw0_NoRaiseOnWarp:
764			Scr->RaiseOnWarp = false;
765			return true;
766
767		case kw0_RaiseOnWarp:
768			Scr->RaiseOnWarp = true;
769			return true;
770
771		case kw0_WarpUnmapped:
772			Scr->WarpUnmapped = true;
773			return true;
774
775		case kw0_WarpRingOnScreen:
776			Scr->WarpRingAnyWhere = false;
777			return true;
778
779		case kw0_NoIconManagerFocus:
780			Scr->IconManagerFocus = false;
781			return true;
782
783		case kw0_StayUpMenus:
784			Scr->StayUpMenus = true;
785			return true;
786
787		case kw0_ClickToFocus:
788			Scr->ClickToFocus = true;
789			return true;
790
791		case kw0_ReallyMoveInWorkspaceManager:
792			Scr->ReallyMoveInWorkspaceManager = true;
793			return true;
794
795		case kw0_ShowWinWhenMovingInWmgr:
796			Scr->ShowWinWhenMovingInWmgr = true;
797			return true;
798
799		case kw0_ReverseCurrentWorkspace:
800			Scr->ReverseCurrentWorkspace = true;
801			return true;
802
803		case kw0_DontWarpCursorInWMap:
804			Scr->DontWarpCursorInWMap = true;
805			return true;
806
807		case kw0_CenterFeedbackWindow:
808			Scr->CenterFeedbackWindow = true;
809			return true;
810
811		case kw0_WarpToDefaultMenuEntry:
812			Scr->WarpToDefaultMenuEntry = true;
813			return true;
814
815		case kw0_ShrinkIconTitles:
816			Scr->ShrinkIconTitles = true;
817			return true;
818
819		case kw0_AutoRaiseIcons:
820			Scr->AutoRaiseIcons = true;
821			return true;
822
823		/* kai */
824		case kw0_AutoFocusToTransients:
825			Scr->AutoFocusToTransients = true;
826			return true;
827
828		case kw0_ShortAllWindowsMenus:
829			Scr->ShortAllWindowsMenus = true;
830			return true;
831
832		case kw0_RaiseWhenAutoUnSqueeze:
833			Scr->RaiseWhenAutoUnSqueeze = true;
834			return true;
835
836		case kw0_RaiseOnClick:
837			Scr->RaiseOnClick = true;
838			return true;
839
840		case kw0_IgnoreLockModifier:
841			Scr->IgnoreModifier |= LockMask;
842			return true;
843
844		case kw0_PackNewWindows:
845			Scr->PackNewWindows = true;
846			return true;
847
848		case kw0_IgnoreCaseInMenuSelection:
849			Scr->IgnoreCaseInMenuSelection = true;
850			return true;
851
852		case kw0_SloppyFocus:
853			Scr->SloppyFocus = true;
854			return true;
855
856		case kw0_SaveWorkspaceFocus:
857			Scr->SaveWorkspaceFocus = true;
858			return true;
859
860		case kw0_NoImagesInWorkSpaceManager:
861			Scr->NoImagesInWorkSpaceManager = true;
862			return true;
863
864		case kw0_NoWarpToMenuTitle:
865			Scr->NoWarpToMenuTitle = true;
866			return true;
867
868		case kw0_DontShowWelcomeWindow:
869			Scr->ShowWelcomeWindow = false;
870			return true;
871
872		case kw0_DontToggleWorkspacemanagerState:
873			Scr->DontToggleWorkspaceManagerState = true;
874			return true;
875
876		case kw0_DontNameDecorations:
877			Scr->NameDecorations = false;
878			return true;
879
880		case kw0_StrictWinNameEncoding:
881			Scr->StrictWinNameEncoding = true;
882			return true;
883
884	}
885	return false;
886}
887
888
889bool
890do_string_string_keyword(int keyword, const char *s1, const char *s2)
891{
892	switch(keyword) {
893		case kwss_RandomPlacement: {
894			/* RandomPlacement {on,off,all,unmapped} [displacement geom] */
895			int rp;
896			int gmask, gx, gy;     // Geometry mask/x/y values
897			unsigned int gjw, gjh; // width/height (ignored)
898			int exmask = (XValue | YValue); // Bits we need in the mask
899
900			rp = ParseRandomPlacement(s1);
901			if(rp < 0) {
902				twmrc_error_prefix();
903				fprintf(stderr,
904				        "ignoring invalid RandomPlacement argument 1 \"%s\"\n",
905				        s1);
906			}
907			else {
908				Scr->RandomPlacement = rp;
909			}
910
911			/* If no geom, we're done */
912			if(s2 == NULL) {
913				return true;
914			}
915
916			/*
917			 * Figure what the geom means.  We actually don't care about
918			 * the size (it probably won't even be provided), so the
919			 * width/height are junk.  The X/Y offsets are what we need.
920			 * But we do need them.
921			 */
922			gmask = XParseGeometry(s2, &gx, &gy, &gjw, &gjh);
923#ifdef DEBUG
924			fprintf(stderr, "DEBUG:: Mask = %x, Width = %d, Height = %d\n",
925			        gmask, gjw, gjh);
926			fprintf(stderr, "DEBUG:: X = %d, Y = %d\n", gx, gy);
927#endif
928			if((gmask & exmask) != exmask) {
929				/* Didn't get X and Y */
930				twmrc_error_prefix();
931				fprintf(stderr,
932				        "ignoring invalid RandomPlacement displacement \"%s\"\n", s2);
933			}
934			else {
935				Scr->RandomDisplacementX = gx;
936				Scr->RandomDisplacementY = gy;
937			}
938
939			/* Done */
940			return true;
941		}
942	}
943	return false;
944}
945
946
947bool
948do_string_keyword(int keyword, char *s)
949{
950	switch(keyword) {
951		case kws_UsePPosition: {
952			int ppos = ParseUsePPosition(s);
953			if(ppos < 0) {
954				twmrc_error_prefix();
955				fprintf(stderr,
956				        "ignoring invalid UsePPosition argument \"%s\"\n", s);
957			}
958			else {
959				Scr->UsePPosition = ppos;
960			}
961			return true;
962		}
963
964		case kws_IconFont:
965			if(!Scr->HaveFonts) {
966				Scr->IconFont.basename = s;
967			}
968			return true;
969
970		case kws_ResizeFont:
971			if(!Scr->HaveFonts) {
972				Scr->SizeFont.basename = s;
973			}
974			return true;
975
976		case kws_MenuFont:
977			if(!Scr->HaveFonts) {
978				Scr->MenuFont.basename = s;
979			}
980			return true;
981
982		case kws_WorkSpaceFont:
983			if(!Scr->HaveFonts) {
984				Scr->workSpaceMgr.windowFont.basename = s;
985			}
986			return true;
987
988		case kws_TitleFont:
989			if(!Scr->HaveFonts) {
990				Scr->TitleBarFont.basename = s;
991			}
992			return true;
993
994		case kws_IconManagerFont:
995			if(!Scr->HaveFonts) {
996				Scr->IconManagerFont.basename = s;
997			}
998			return true;
999
1000		case kws_UnknownIcon:
1001			if(Scr->FirstTime) {
1002				Scr->UnknownImage = GetImage(s, Scr->IconC);
1003			}
1004			return true;
1005
1006		case kws_IconDirectory:
1007			if(Scr->FirstTime) {
1008				Scr->IconDirectory = ExpandFilePath(s);
1009			}
1010			return true;
1011
1012		case kws_PixmapDirectory:
1013			if(Scr->FirstTime) {
1014				Scr->PixmapDirectory = ExpandFilePath(s);
1015			}
1016			return true;
1017
1018		case kws_MaxWindowSize: {
1019			int gmask;
1020			int exmask = (WidthValue | HeightValue);
1021			unsigned int gw, gh; // Stuff we care about
1022			int gjx, gjy;        // Stuff we don't
1023
1024			gmask = XParseGeometry(s, &gjx, &gjy, &gw, &gh);
1025			if((gmask & exmask) != exmask) {
1026				twmrc_error_prefix();
1027				fprintf(stderr, "bad MaxWindowSize \"%s\"\n", s);
1028				return false;
1029			}
1030			if(gw == 0 || gh == 0) {
1031				twmrc_error_prefix();
1032				fprintf(stderr, "MaxWindowSize \"%s\" must be non-zero\n", s);
1033				return false;
1034			}
1035			Scr->MaxWindowWidth = gw;
1036			Scr->MaxWindowHeight = gh;
1037			return true;
1038		}
1039
1040		case kws_IconJustification: {
1041			int just = ParseTitleJustification(s);
1042
1043			if((just < 0) || (just == TJ_UNDEF)) {
1044				twmrc_error_prefix();
1045				fprintf(stderr,
1046				        "ignoring invalid IconJustification argument \"%s\"\n", s);
1047			}
1048			else {
1049				Scr->IconJustification = just;
1050			}
1051			return true;
1052		}
1053		case kws_IconRegionJustification: {
1054			int just = ParseIRJustification(s);
1055
1056			if(just < 0 || (just == IRJ_UNDEF)) {
1057				twmrc_error_prefix();
1058				fprintf(stderr,
1059				        "ignoring invalid IconRegionJustification argument \"%s\"\n", s);
1060			}
1061			else {
1062				Scr->IconRegionJustification = just;
1063			}
1064			return true;
1065		}
1066		case kws_IconRegionAlignement: {
1067			int just = ParseAlignement(s);
1068
1069			if(just < 0) {
1070				twmrc_error_prefix();
1071				fprintf(stderr,
1072				        "ignoring invalid IconRegionAlignement argument \"%s\"\n", s);
1073			}
1074			else {
1075				Scr->IconRegionAlignement = just;
1076			}
1077			return true;
1078		}
1079
1080		case kws_TitleJustification: {
1081			int just = ParseTitleJustification(s);
1082
1083			if((just < 0) || (just == TJ_UNDEF)) {
1084				twmrc_error_prefix();
1085				fprintf(stderr,
1086				        "ignoring invalid TitleJustification argument \"%s\"\n", s);
1087			}
1088			else {
1089				Scr->TitleJustification = just;
1090			}
1091			return true;
1092		}
1093		case kws_RplaySoundHost:
1094		case kws_SoundHost:
1095			if(Scr->FirstTime) {
1096				/* Warning to be enabled in the future before removal */
1097				if(0 && keyword == kws_SoundHost) {
1098					twmrc_error_prefix();
1099					fprintf(stderr, "SoundHost is deprecated, please "
1100					        "use RplaySoundHost instead.\n");
1101				}
1102#ifdef SOUNDS
1103				set_sound_host(s);
1104#else
1105				twmrc_error_prefix();
1106				fprintf(stderr, "Ignoring %sSoundHost; rplay not ronfigured.\n",
1107				        (keyword == kws_RplaySoundHost ? "Rplay" : ""));
1108#endif
1109			}
1110			return true;
1111
1112		case kws_WMgrButtonStyle: {
1113			int style = ParseButtonStyle(s);
1114
1115			if(style < 0) {
1116				twmrc_error_prefix();
1117				fprintf(stderr,
1118				        "ignoring invalid WMgrButtonStyle argument \"%s\"\n", s);
1119			}
1120			else {
1121				Scr->workSpaceMgr.buttonStyle = style;
1122			}
1123			return true;
1124		}
1125
1126		case kws_IconifyStyle: {
1127			int style = ParseIconifyStyle(s);
1128
1129			if(style < 0) {
1130				twmrc_error_prefix();
1131				fprintf(stderr, "ignoring invalid IconifyStyle argument \"%s\"\n", s);
1132			}
1133			else {
1134				Scr->IconifyStyle = style;
1135			}
1136			return true;
1137		}
1138
1139#ifdef EWMH
1140		case kws_IconSize:
1141			if(sscanf(s, "%dx%d", &Scr->PreferredIconWidth,
1142			                &Scr->PreferredIconHeight) == 2) {
1143				/* ok */
1144			}
1145			else if(sscanf(s, "%d", &Scr->PreferredIconWidth) == 1) {
1146				Scr->PreferredIconHeight = Scr->PreferredIconWidth;
1147			}
1148			else {
1149				Scr->PreferredIconHeight = Scr->PreferredIconWidth = 48;
1150			}
1151			return true;
1152#endif
1153	}
1154	return false;
1155}
1156
1157
1158bool
1159do_number_keyword(int keyword, int num)
1160{
1161	switch(keyword) {
1162		case kwn_ConstrainedMoveTime:
1163			ConstrainedMoveTime = num;
1164			return true;
1165
1166		case kwn_MoveDelta:
1167			Scr->MoveDelta = num;
1168			return true;
1169
1170		case kwn_MoveOffResistance:
1171			Scr->MoveOffResistance = num;
1172			return true;
1173
1174		case kwn_MovePackResistance:
1175			if(num < 0) {
1176				num = 20;
1177			}
1178			Scr->MovePackResistance = num;
1179			return true;
1180
1181		case kwn_XMoveGrid:
1182			if(num < 1) {
1183				num = 1;
1184			}
1185			if(num > 100) {
1186				num = 100;
1187			}
1188			Scr->XMoveGrid = num;
1189			return true;
1190
1191		case kwn_YMoveGrid:
1192			if(num < 1) {
1193				num = 1;
1194			}
1195			if(num > 100) {
1196				num = 100;
1197			}
1198			Scr->YMoveGrid = num;
1199			return true;
1200
1201		case kwn_XorValue:
1202			if(Scr->FirstTime) {
1203				Scr->XORvalue = num;
1204			}
1205			return true;
1206
1207		case kwn_FramePadding:
1208			if(Scr->FirstTime) {
1209				Scr->FramePadding = num;
1210			}
1211			return true;
1212
1213		case kwn_TitlePadding:
1214			if(Scr->FirstTime) {
1215				Scr->TitlePadding = num;
1216			}
1217			return true;
1218
1219		case kwn_ButtonIndent:
1220			if(Scr->FirstTime) {
1221				Scr->ButtonIndent = num;
1222			}
1223			return true;
1224
1225		case kwn_ThreeDBorderWidth:
1226			if(Scr->FirstTime) {
1227				Scr->ThreeDBorderWidth = num;
1228			}
1229			return true;
1230
1231		case kwn_BorderWidth:
1232			if(Scr->FirstTime) {
1233				Scr->BorderWidth = num;
1234			}
1235			return true;
1236
1237		case kwn_IconBorderWidth:
1238			if(Scr->FirstTime) {
1239				Scr->IconBorderWidth = num;
1240			}
1241			return true;
1242
1243		case kwn_TitleButtonBorderWidth:
1244			if(Scr->FirstTime) {
1245				Scr->TBInfo.border = num;
1246			}
1247			return true;
1248
1249		case kwn_RaiseDelay:
1250			RaiseDelay = num;
1251			return true;
1252
1253		case kwn_TransientOnTop:
1254			if(Scr->FirstTime) {
1255				Scr->TransientOnTop = num;
1256			}
1257			return true;
1258
1259		case kwn_OpaqueMoveThreshold:
1260			if(Scr->FirstTime) {
1261				Scr->OpaqueMoveThreshold = num;
1262			}
1263			return true;
1264
1265		case kwn_OpaqueResizeThreshold:
1266			if(Scr->FirstTime) {
1267				Scr->OpaqueResizeThreshold = num;
1268			}
1269			return true;
1270
1271		case kwn_WMgrVertButtonIndent:
1272			if(Scr->FirstTime) {
1273				Scr->WMgrVertButtonIndent = num;
1274			}
1275			if(Scr->WMgrVertButtonIndent < 0) {
1276				Scr->WMgrVertButtonIndent = 0;
1277			}
1278			Scr->workSpaceMgr.vspace = Scr->WMgrVertButtonIndent;
1279			Scr->workSpaceMgr.occupyWindow->vspace = Scr->WMgrVertButtonIndent;
1280			return true;
1281
1282		case kwn_WMgrHorizButtonIndent:
1283			if(Scr->FirstTime) {
1284				Scr->WMgrHorizButtonIndent = num;
1285			}
1286			if(Scr->WMgrHorizButtonIndent < 0) {
1287				Scr->WMgrHorizButtonIndent = 0;
1288			}
1289			Scr->workSpaceMgr.hspace = Scr->WMgrHorizButtonIndent;
1290			Scr->workSpaceMgr.occupyWindow->hspace = Scr->WMgrHorizButtonIndent;
1291			return true;
1292
1293		case kwn_WMgrButtonShadowDepth:
1294			if(Scr->FirstTime) {
1295				Scr->WMgrButtonShadowDepth = num;
1296			}
1297			if(Scr->WMgrButtonShadowDepth < 1) {
1298				Scr->WMgrButtonShadowDepth = 1;
1299			}
1300			return true;
1301
1302		case kwn_MaxIconTitleWidth:
1303			if(Scr->FirstTime) {
1304				Scr->MaxIconTitleWidth = num;
1305			}
1306			return true;
1307
1308		case kwn_ClearShadowContrast:
1309			if(Scr->FirstTime) {
1310				Scr->ClearShadowContrast = num;
1311			}
1312			if(Scr->ClearShadowContrast < 0) {
1313				Scr->ClearShadowContrast = 0;
1314			}
1315			if(Scr->ClearShadowContrast > 100) {
1316				Scr->ClearShadowContrast = 100;
1317			}
1318			return true;
1319
1320		case kwn_DarkShadowContrast:
1321			if(Scr->FirstTime) {
1322				Scr->DarkShadowContrast = num;
1323			}
1324			if(Scr->DarkShadowContrast < 0) {
1325				Scr->DarkShadowContrast = 0;
1326			}
1327			if(Scr->DarkShadowContrast > 100) {
1328				Scr->DarkShadowContrast = 100;
1329			}
1330			return true;
1331
1332		case kwn_AnimationSpeed:
1333			if(num < 0) {
1334				num = 0;
1335			}
1336			SetAnimationSpeed(num);
1337			return true;
1338
1339		case kwn_BorderShadowDepth:
1340			if(Scr->FirstTime) {
1341				Scr->BorderShadowDepth = num;
1342			}
1343			if(Scr->BorderShadowDepth < 0) {
1344				Scr->BorderShadowDepth = 2;
1345			}
1346			return true;
1347
1348		case kwn_BorderLeft:
1349			if(Scr->FirstTime) {
1350				Scr->BorderLeft = num;
1351			}
1352			if(Scr->BorderLeft < 0) {
1353				Scr->BorderLeft = 0;
1354			}
1355			return true;
1356
1357		case kwn_BorderRight:
1358			if(Scr->FirstTime) {
1359				Scr->BorderRight = num;
1360			}
1361			if(Scr->BorderRight < 0) {
1362				Scr->BorderRight = 0;
1363			}
1364			return true;
1365
1366		case kwn_BorderTop:
1367			if(Scr->FirstTime) {
1368				Scr->BorderTop = num;
1369			}
1370			if(Scr->BorderTop < 0) {
1371				Scr->BorderTop = 0;
1372			}
1373			return true;
1374
1375		case kwn_BorderBottom:
1376			if(Scr->FirstTime) {
1377				Scr->BorderBottom = num;
1378			}
1379			if(Scr->BorderBottom < 0) {
1380				Scr->BorderBottom = 0;
1381			}
1382			return true;
1383
1384		case kwn_TitleButtonShadowDepth:
1385			if(Scr->FirstTime) {
1386				Scr->TitleButtonShadowDepth = num;
1387			}
1388			if(Scr->TitleButtonShadowDepth < 0) {
1389				Scr->TitleButtonShadowDepth = 2;
1390			}
1391			return true;
1392
1393		case kwn_TitleShadowDepth:
1394			if(Scr->FirstTime) {
1395				Scr->TitleShadowDepth = num;
1396			}
1397			if(Scr->TitleShadowDepth < 0) {
1398				Scr->TitleShadowDepth = 2;
1399			}
1400			return true;
1401
1402		case kwn_IconManagerShadowDepth:
1403			if(Scr->FirstTime) {
1404				Scr->IconManagerShadowDepth = num;
1405			}
1406			if(Scr->IconManagerShadowDepth < 0) {
1407				Scr->IconManagerShadowDepth = 2;
1408			}
1409			return true;
1410
1411		case kwn_MenuShadowDepth:
1412			if(Scr->FirstTime) {
1413				Scr->MenuShadowDepth = num;
1414			}
1415			if(Scr->MenuShadowDepth < 0) {
1416				Scr->MenuShadowDepth = 2;
1417			}
1418			return true;
1419
1420		case kwn_OpenWindowTimeout:
1421			if(Scr->FirstTime) {
1422				Scr->OpenWindowTimeout = num;
1423			}
1424			if(Scr->OpenWindowTimeout < 0) {
1425				Scr->OpenWindowTimeout = 0;
1426			}
1427			return true;
1428
1429		case kwn_RaiseOnClickButton:
1430			if(Scr->FirstTime) {
1431				Scr->RaiseOnClickButton = num;
1432			}
1433			if(Scr->RaiseOnClickButton < 1) {
1434				Scr->RaiseOnClickButton = 1;
1435			}
1436			if(Scr->RaiseOnClickButton > MAX_BUTTONS) {
1437				Scr->RaiseOnClickButton = MAX_BUTTONS;
1438			}
1439			return true;
1440
1441
1442	}
1443
1444	return false;
1445}
1446
1447name_list **
1448do_colorlist_keyword(int keyword, int colormode, char *s)
1449{
1450	switch(keyword) {
1451		case kwcl_BorderColor:
1452			GetColor(colormode, &Scr->BorderColorC.back, s);
1453			return &Scr->BorderColorL;
1454
1455		case kwcl_IconManagerHighlight:
1456			GetColor(colormode, &Scr->IconManagerHighlight, s);
1457			return &Scr->IconManagerHighlightL;
1458
1459		case kwcl_BorderTileForeground:
1460			GetColor(colormode, &Scr->BorderTileC.fore, s);
1461			return &Scr->BorderTileForegroundL;
1462
1463		case kwcl_BorderTileBackground:
1464			GetColor(colormode, &Scr->BorderTileC.back, s);
1465			return &Scr->BorderTileBackgroundL;
1466
1467		case kwcl_TitleForeground:
1468			GetColor(colormode, &Scr->TitleC.fore, s);
1469			return &Scr->TitleForegroundL;
1470
1471		case kwcl_TitleBackground:
1472			GetColor(colormode, &Scr->TitleC.back, s);
1473			return &Scr->TitleBackgroundL;
1474
1475		case kwcl_IconForeground:
1476			GetColor(colormode, &Scr->IconC.fore, s);
1477			return &Scr->IconForegroundL;
1478
1479		case kwcl_IconBackground:
1480			GetColor(colormode, &Scr->IconC.back, s);
1481			return &Scr->IconBackgroundL;
1482
1483		case kwcl_IconBorderColor:
1484			GetColor(colormode, &Scr->IconBorderColor, s);
1485			return &Scr->IconBorderColorL;
1486
1487		case kwcl_IconManagerForeground:
1488			GetColor(colormode, &Scr->IconManagerC.fore, s);
1489			return &Scr->IconManagerFL;
1490
1491		case kwcl_IconManagerBackground:
1492			GetColor(colormode, &Scr->IconManagerC.back, s);
1493			return &Scr->IconManagerBL;
1494
1495		case kwcl_MapWindowBackground:
1496			GetColor(colormode, &Scr->workSpaceMgr.windowcp.back, s);
1497			Scr->workSpaceMgr.windowcpgiven = true;
1498			return &Scr->workSpaceMgr.windowBackgroundL;
1499
1500		case kwcl_MapWindowForeground:
1501			GetColor(colormode, &Scr->workSpaceMgr.windowcp.fore, s);
1502			Scr->workSpaceMgr.windowcpgiven = true;
1503			return &Scr->workSpaceMgr.windowForegroundL;
1504	}
1505	return NULL;
1506}
1507
1508bool
1509do_color_keyword(int keyword, int colormode, char *s)
1510{
1511	switch(keyword) {
1512		case kwc_DefaultForeground:
1513			GetColor(colormode, &Scr->DefaultC.fore, s);
1514			return true;
1515
1516		case kwc_DefaultBackground:
1517			GetColor(colormode, &Scr->DefaultC.back, s);
1518			return true;
1519
1520		case kwc_MenuForeground:
1521			GetColor(colormode, &Scr->MenuC.fore, s);
1522			return true;
1523
1524		case kwc_MenuBackground:
1525			GetColor(colormode, &Scr->MenuC.back, s);
1526			return true;
1527
1528		case kwc_MenuTitleForeground:
1529			GetColor(colormode, &Scr->MenuTitleC.fore, s);
1530			return true;
1531
1532		case kwc_MenuTitleBackground:
1533			GetColor(colormode, &Scr->MenuTitleC.back, s);
1534			return true;
1535
1536		case kwc_MenuShadowColor:
1537			GetColor(colormode, &Scr->MenuShadowColor, s);
1538			return true;
1539
1540	}
1541
1542	return false;
1543}
1544
1545/*
1546 * put_pixel_on_root() Save a pixel value in twm root window color property.
1547 */
1548static void
1549put_pixel_on_root(Pixel pixel)
1550{
1551	int           i, addPixel = 1;
1552	Atom          retAtom;
1553	int           retFormat;
1554	unsigned long nPixels, retAfter;
1555	Pixel        *retProp;
1556
1557	if(XGetWindowProperty(dpy, Scr->Root, XA__MIT_PRIORITY_COLORS, 0, 8192,
1558	                      False, XA_CARDINAL, &retAtom,
1559	                      &retFormat, &nPixels, &retAfter,
1560	                      (unsigned char **)&retProp) != Success || !retProp) {
1561		return;
1562	}
1563
1564	for(i = 0; i < nPixels; i++)
1565		if(pixel == retProp[i]) {
1566			addPixel = 0;
1567		}
1568
1569	XFree(retProp);
1570
1571	if(addPixel)
1572		XChangeProperty(dpy, Scr->Root, XA__MIT_PRIORITY_COLORS,
1573		                XA_CARDINAL, 32, PropModeAppend,
1574		                (unsigned char *)&pixel, 1);
1575}
1576
1577/*
1578 * do_string_savecolor() save a color from a string in the twmrc file.
1579 */
1580void
1581do_string_savecolor(int colormode, char *s)
1582{
1583	Pixel p;
1584	GetColor(colormode, &p, s);
1585	put_pixel_on_root(p);
1586	return;
1587}
1588
1589/*
1590 * do_var_savecolor() save a color from a var in the twmrc file.
1591 */
1592typedef struct _cnode {
1593	int i;
1594	struct _cnode *next;
1595} Cnode, *Cptr;
1596static Cptr chead = NULL;
1597
1598void
1599do_var_savecolor(int key)
1600{
1601	Cptr cptrav, cpnew;
1602	if(!chead) {
1603		chead = malloc(sizeof(Cnode));
1604		chead->i = key;
1605		chead->next = NULL;
1606	}
1607	else {
1608		cptrav = chead;
1609		while(cptrav->next != NULL) {
1610			cptrav = cptrav->next;
1611		}
1612		cpnew = malloc(sizeof(Cnode));
1613		cpnew->i = key;
1614		cpnew->next = NULL;
1615		cptrav->next = cpnew;
1616	}
1617	return;
1618}
1619
1620/*
1621 * assign_var_savecolor() traverse the var save color list placeing the pixels
1622 *                        in the root window property.
1623 */
1624void
1625assign_var_savecolor(void)
1626{
1627	Cptr cp = chead;
1628	while(cp != NULL) {
1629		switch(cp->i) {
1630			case kwcl_BorderColor:
1631				put_pixel_on_root(Scr->BorderColorC.back);
1632				break;
1633			case kwcl_IconManagerHighlight:
1634				put_pixel_on_root(Scr->IconManagerHighlight);
1635				break;
1636			case kwcl_BorderTileForeground:
1637				put_pixel_on_root(Scr->BorderTileC.fore);
1638				break;
1639			case kwcl_BorderTileBackground:
1640				put_pixel_on_root(Scr->BorderTileC.back);
1641				break;
1642			case kwcl_TitleForeground:
1643				put_pixel_on_root(Scr->TitleC.fore);
1644				break;
1645			case kwcl_TitleBackground:
1646				put_pixel_on_root(Scr->TitleC.back);
1647				break;
1648			case kwcl_IconForeground:
1649				put_pixel_on_root(Scr->IconC.fore);
1650				break;
1651			case kwcl_IconBackground:
1652				put_pixel_on_root(Scr->IconC.back);
1653				break;
1654			case kwcl_IconBorderColor:
1655				put_pixel_on_root(Scr->IconBorderColor);
1656				break;
1657			case kwcl_IconManagerForeground:
1658				put_pixel_on_root(Scr->IconManagerC.fore);
1659				break;
1660			case kwcl_IconManagerBackground:
1661				put_pixel_on_root(Scr->IconManagerC.back);
1662				break;
1663			case kwcl_MapWindowForeground:
1664				put_pixel_on_root(Scr->workSpaceMgr.windowcp.fore);
1665				break;
1666			case kwcl_MapWindowBackground:
1667				put_pixel_on_root(Scr->workSpaceMgr.windowcp.back);
1668				break;
1669		}
1670		cp = cp->next;
1671	}
1672	if(chead) {
1673		free(chead);
1674		chead = NULL;
1675	}
1676}
1677
1678
1679/*
1680 * RandomPlacement [...] parse
1681 */
1682static int
1683ParseRandomPlacement(const char *s)
1684{
1685	/* No first arg -> 'all' */
1686	if(s == NULL) {
1687		return RP_ALL;
1688	}
1689	if(strlen(s) == 0) {
1690		return RP_ALL;
1691	}
1692
1693#define CHK(str, ret) if(strcasecmp(s, str) == 0) { return RP_##ret; }
1694	CHK(DEFSTRING,  ALL);
1695	CHK("on",       ALL);
1696	CHK("all",      ALL);
1697	CHK("off",      OFF);
1698	CHK("unmapped", UNMAPPED);
1699#undef CHK
1700
1701	return -1;
1702}
1703
1704
1705/*
1706 * Parse out IconRegionJustification string.
1707 *
1708 * X-ref comment on ParseAlignement about return value.
1709 */
1710int
1711ParseIRJustification(const char *s)
1712{
1713	if(strlen(s) == 0) {
1714		return -1;
1715	}
1716
1717#define CHK(str, ret) if(strcasecmp(s, str) == 0) { return IRJ_##ret; }
1718	CHK(DEFSTRING, CENTER);
1719	CHK("undef",   UNDEF);
1720	CHK("left",    LEFT);
1721	CHK("center",  CENTER);
1722	CHK("right",   RIGHT);
1723	CHK("border",  BORDER);
1724#undef CHK
1725
1726	return -1;
1727}
1728
1729
1730/*
1731 * Parse out string for title justification.  From TitleJustification,
1732 * IconJustification, iconjust arg to IconRegion.
1733 *
1734 * X-ref comment on ParseAlignement about return value.
1735 */
1736int
1737ParseTitleJustification(const char *s)
1738{
1739	if(strlen(s) == 0) {
1740		return -1;
1741	}
1742
1743#define CHK(str, ret) if(strcasecmp(s, str) == 0) { return TJ_##ret; }
1744	/* XXX Different uses really have different defaults... */
1745	CHK(DEFSTRING, CENTER);
1746	CHK("undef",   UNDEF);
1747	CHK("left",    LEFT);
1748	CHK("center",  CENTER);
1749	CHK("right",   RIGHT);
1750#undef CHK
1751
1752	return -1;
1753}
1754
1755
1756/*
1757 * Parse out the string specifier for IconRegion Alignement[sic].
1758 * Strictly speaking, this [almost always] returns an IRAlignement enum
1759 * value.  However, it's specified as int to allow the -1 return for
1760 * invalid values.  enum's start numbering from 0 (unless specific values
1761 * are given), so that's a safe out-of-bounds value.  And making an
1762 * IRA_INVALID value would just add unnecessary complication, since
1763 * during parsing is the only time it makes sense.
1764 */
1765int
1766ParseAlignement(const char *s)
1767{
1768	if(strlen(s) == 0) {
1769		return -1;
1770	}
1771
1772#define CHK(str, ret) if(strcasecmp(s, str) == 0) { return IRA_##ret; }
1773	CHK(DEFSTRING, CENTER);
1774	CHK("center",  CENTER);
1775	CHK("top",     TOP);
1776	CHK("bottom",  BOTTOM);
1777	CHK("border",  BORDER);
1778	CHK("undef",   UNDEF);
1779#undef CHK
1780
1781	return -1;
1782}
1783
1784static int
1785ParseUsePPosition(const char *s)
1786{
1787	if(strlen(s) == 0) {
1788		return -1;
1789	}
1790
1791#define CHK(str, ret) if(strcasecmp(s, str) == 0) { return PPOS_##ret; }
1792	CHK(DEFSTRING,  OFF);
1793	CHK("off",      OFF);
1794	CHK("on",       ON);
1795	CHK("non-zero", NON_ZERO);
1796	CHK("nonzero",  NON_ZERO);
1797#undef CHK
1798
1799	return -1;
1800}
1801
1802static int
1803ParseButtonStyle(const char *s)
1804{
1805	if(s == NULL || strlen(s) == 0) {
1806		return -1;
1807	}
1808
1809#define CHK(str, ret) if(strcasecmp(s, str) == 0) { return STYLE_##ret; }
1810	CHK(DEFSTRING, NORMAL);
1811	CHK("normal",  NORMAL);
1812	CHK("style1",  STYLE1);
1813	CHK("style2",  STYLE2);
1814	CHK("style3",  STYLE3);
1815#undef CHK
1816
1817	return -1;
1818}
1819
1820static int
1821ParseIconifyStyle(const char *s)
1822{
1823	if(s == NULL || strlen(s) == 0) {
1824		return -1;
1825	}
1826
1827#define CHK(str, ret) if(strcasecmp(s, str) == 0) { return ICONIFY_##ret; }
1828	CHK(DEFSTRING, NORMAL);
1829	CHK("normal",  NORMAL);
1830	CHK("mosaic",  MOSAIC);
1831	CHK("zoomin",  ZOOMIN);
1832	CHK("zoomout", ZOOMOUT);
1833	CHK("fade",    FADE);
1834	CHK("sweep",   SWEEP);
1835#undef CHK
1836
1837	return -1;
1838}
1839
1840void
1841do_squeeze_entry(name_list **slist, // squeeze or dont-squeeze list
1842                 const char *name,  // window name
1843                 SIJust justify,    // left, center, right
1844                 int num,           // signed num
1845                 int denom)         // 0 or indicates fraction denom
1846{
1847	int absnum = (num < 0 ? -num : num);
1848
1849	if(denom < 0) {
1850		twmrc_error_prefix();
1851		fprintf(stderr, "negative SqueezeTitle denominator %d\n", denom);
1852		ParseError = true;
1853		return;
1854	}
1855	if(absnum > denom && denom != 0) {
1856		twmrc_error_prefix();
1857		fprintf(stderr, "SqueezeTitle fraction %d/%d outside window\n",
1858		        num, denom);
1859		ParseError = true;
1860		return;
1861	}
1862	/* Process the special cases from the manual here rather than
1863	 * each time we calculate the position of the title bar
1864	 * in ComputeTitleLocation().
1865	 * In fact, it's better to get rid of them entirely, but we
1866	 * probably should not do that for compatibility's sake.
1867	 * By using a non-zero denominator the position will be relative.
1868	 */
1869	if(denom == 0 && num == 0) {
1870		if(justify == SIJ_CENTER) {
1871			num = 1;
1872			denom = 2;
1873		}
1874		else if(justify == SIJ_RIGHT) {
1875			num = 2;
1876			denom = 2;
1877		}
1878		twmrc_error_prefix();
1879		fprintf(stderr, "deprecated SqueezeTitle faction 0/0, assuming %d/%d\n",
1880		        num, denom);
1881	}
1882
1883	if(HasShape) {
1884		SqueezeInfo *sinfo;
1885		sinfo = malloc(sizeof(SqueezeInfo));
1886
1887		if(!sinfo) {
1888			twmrc_error_prefix();
1889			fprintf(stderr, "unable to allocate %lu bytes for squeeze info\n",
1890			        (unsigned long) sizeof(SqueezeInfo));
1891			ParseError = true;
1892			return;
1893		}
1894		sinfo->justify = justify;
1895		sinfo->num = num;
1896		sinfo->denom = denom;
1897		AddToList(slist, name, sinfo);
1898	}
1899	return;
1900}
1901
1902
1903/*
1904 * Parsing for EWMHIgnore { } lists
1905 */
1906void
1907proc_ewmh_ignore(void)
1908{
1909#ifndef EWMH
1910	twmrc_error_prefix();
1911	fprintf(stderr, "EWMH not enabled, EWMHIgnore { } ignored.\n");
1912	ParseError = true;
1913	return;
1914#endif
1915	/* else nada */
1916	return;
1917}
1918void
1919add_ewmh_ignore(char *s)
1920{
1921#ifndef EWMH
1922	return;
1923#else
1924
1925#define HANDLE(x) \
1926        if(strcasecmp(s, (x)) == 0) { \
1927                AddToList(&Scr->EWMHIgnore, (x), ""); \
1928                return; \
1929        }
1930	HANDLE("STATE_MAXIMIZED_VERT");
1931	HANDLE("STATE_MAXIMIZED_HORZ");
1932	HANDLE("STATE_FULLSCREEN");
1933	HANDLE("STATE_SHADED");
1934	HANDLE("STATE_ABOVE");
1935	HANDLE("STATE_BELOW");
1936#undef HANDLE
1937
1938	twmrc_error_prefix();
1939	fprintf(stderr, "Unexpected EWMHIgnore value '%s'\n", s);
1940	ParseError = true;
1941	return;
1942#endif /* EWMH */
1943}
1944
1945
1946/*
1947 * Parsing for MWMIgnore { } lists
1948 */
1949void
1950proc_mwm_ignore(void)
1951{
1952	/* Nothing to do */
1953	return;
1954}
1955void
1956add_mwm_ignore(char *s)
1957{
1958#define HANDLE(x) \
1959        if(strcasecmp(s, (x)) == 0) { \
1960                AddToList(&Scr->MWMIgnore, (x), ""); \
1961                return; \
1962        }
1963	HANDLE("DECOR_BORDER");
1964	HANDLE("DECOR_TITLE");
1965#undef HANDLE
1966
1967	twmrc_error_prefix();
1968	fprintf(stderr, "Unexpected MWMIgnore value '%s'\n", s);
1969	ParseError = true;
1970	return;
1971}
1972