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