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 
38 static int ParseRandomPlacement(const char *s);
39 static int ParseButtonStyle(const char *s);
40 static int ParseUsePPosition(const char *s);
41 static int ParseIconifyStyle(const char *s);
42 
43 
44 
45 /**********************************************************************
46  *
47  *  Parsing table and routines
48  *
49  ***********************************************************************/
50 
51 typedef 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  */
222 static 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 
485 static 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 
495 static int
kt_compare(const void * lhs,const void * rhs)496 kt_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 
503 int
parse_keyword(const char * s,int * nump)504 parse_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  */
544 void
chk_keytable_order(void)545 chk_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 
572 bool
do_single_keyword(int keyword)573 do_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 
889 bool
do_string_string_keyword(int keyword,const char * s1,const char * s2)890 do_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 
947 bool
do_string_keyword(int keyword,char * s)948 do_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 
1158 bool
do_number_keyword(int keyword,int num)1159 do_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 
1447 name_list **
do_colorlist_keyword(int keyword,int colormode,char * s)1448 do_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 
1508 bool
do_color_keyword(int keyword,int colormode,char * s)1509 do_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  */
1548 static void
put_pixel_on_root(Pixel pixel)1549 put_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  */
1580 void
do_string_savecolor(int colormode,char * s)1581 do_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  */
1592 typedef struct _cnode {
1593 	int i;
1594 	struct _cnode *next;
1595 } Cnode, *Cptr;
1596 static Cptr chead = NULL;
1597 
1598 void
do_var_savecolor(int key)1599 do_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  */
1624 void
assign_var_savecolor(void)1625 assign_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  */
1682 static int
ParseRandomPlacement(const char * s)1683 ParseRandomPlacement(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  */
1710 int
ParseIRJustification(const char * s)1711 ParseIRJustification(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  */
1736 int
ParseTitleJustification(const char * s)1737 ParseTitleJustification(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  */
1765 int
ParseAlignement(const char * s)1766 ParseAlignement(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 
1784 static int
ParseUsePPosition(const char * s)1785 ParseUsePPosition(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 
1802 static int
ParseButtonStyle(const char * s)1803 ParseButtonStyle(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 
1820 static int
ParseIconifyStyle(const char * s)1821 ParseIconifyStyle(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 
1840 void
do_squeeze_entry(name_list ** slist,const char * name,SIJust justify,int num,int denom)1841 do_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  */
1906 void
proc_ewmh_ignore(void)1907 proc_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 }
1918 void
add_ewmh_ignore(char * s)1919 add_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  */
1949 void
proc_mwm_ignore(void)1950 proc_mwm_ignore(void)
1951 {
1952 	/* Nothing to do */
1953 	return;
1954 }
1955 void
add_mwm_ignore(char * s)1956 add_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