1 /*****************************************************************************/
2 /**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
3 /**                          Salt Lake City, Utah                           **/
4 /**  Portions Copyright 1989 by the Massachusetts Institute of Technology   **/
5 /**                        Cambridge, Massachusetts                         **/
6 /**                                                                         **/
7 /**                           All Rights Reserved                           **/
8 /**                                                                         **/
9 /**    Permission to use, copy, modify, and distribute this software and    **/
10 /**    its documentation  for  any  purpose  and  without  fee is hereby    **/
11 /**    granted, provided that the above copyright notice appear  in  all    **/
12 /**    copies and that both  that  copyright  notice  and  this  permis-    **/
13 /**    sion  notice appear in supporting  documentation,  and  that  the    **/
14 /**    names of Evans & Sutherland and M.I.T. not be used in advertising    **/
15 /**    in publicity pertaining to distribution of the  software  without    **/
16 /**    specific, written prior permission.                                  **/
17 /**                                                                         **/
18 /**    EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD    **/
19 /**    TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES  OF  MERCHANT-    **/
20 /**    ABILITY  AND  FITNESS,  IN  NO  EVENT SHALL EVANS & SUTHERLAND OR    **/
21 /**    M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL  DAM-    **/
22 /**    AGES OR  ANY DAMAGES WHATSOEVER  RESULTING FROM LOSS OF USE, DATA    **/
23 /**    OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER    **/
24 /**    TORTIOUS ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE    **/
25 /**    OR PERFORMANCE OF THIS SOFTWARE.                                     **/
26 /*****************************************************************************/
27 
28 
29 /***********************************************************************
30  *
31  * $XConsortium: parse.c,v 1.45 90/03/15 14:23:02 jim Exp $
32  *
33  * parse the .twmrc file
34  *
35  * 17-Nov-87 Thomas E. LaStrange		File created
36  *
37  ***********************************************************************/
38 
39 #if !defined(lint) && !defined(SABER)
40 static char RCSinfo[]=
41 "$XConsortium: parse.c,v 1.45 90/03/15 14:23:02 jim Exp $";
42 #endif
43 
44 #include <stdlib.h>
45 #include <stdio.h>
46 #include <ctype.h>
47 #include <X11/Xos.h>
48 #include <X11/Xmu/CharSet.h>
49 #include "twm.h"
50 #include "screen.h"
51 #include "menus.h"
52 #include "util.h"
53 #include "list.h"
54 #include "gram.h"
55 #include "parse.h"
56 #include "vdt.h"
57 
58 /* For m4... */
59 #include <sys/param.h>
60 #include <sys/types.h>
61 #include <sys/socket.h>
62 #include <netdb.h>
63 
64 #define BUF_LEN 300
65 
66 static FILE *twmrc;
67 static int ptr = 0;
68 static int len = 0;
69 static char buff[BUF_LEN+1];
70 static char **stringListSource, *currentString;
71 static int ParseUsePPosition(char *s);
72 static int ParseState(char *s);
73 static FILE *start_m4(FILE *fraw);
74 
75 extern int yylineno;
76 extern int mods;
77 extern int PieMenuWait;
78 
79 int ConstrainedMoveTime = 400;		/* milliseconds, event times */
80 
81 static int twmFileInput(), twmStringListInput();
82 void twmUnput();
83 int (*twmInputFunc)();
84 
85 extern char *defTwmrc[];        /* default bindings */
86 
87 
88 /***********************************************************************
89  *
90  *  Procedure:
91  *  ParseTwmrc - parse the .twmrc file
92  *
93  *  Inputs:
94  *  filename  - the filename to parse.  A NULL indicates $HOME/.twmrc
95  *
96  ***********************************************************************
97  */
98 
99 static int
100 doparse (ifunc, srctypename, srcname)
101 	int (*ifunc)();
102 	char *srctypename;
103 	char *srcname;
104 {
105 	mods = 0;
106 	ptr = 0;
107 	len = 0;
108 	yylineno = 1;
109 	ParseError = FALSE;
110 	twmInputFunc = ifunc;
111 
112 	yyparse();
113 
114 	if (ParseError) {
115 		fprintf(stderr, "%s: errors found in twm %s",
116 			ProgramName, srctypename);
117 		if (srcname) fprintf (stderr, " \"%s\"", srcname);
118 		fprintf (stderr, "\n");
119 	}
120 	return (ParseError ? 0 : 1);
121 }
122 
123 int
ParseTwmrc(filename)124 ParseTwmrc (filename)
125 	char *filename;
126 {
127 	int i;
128 	char *home = NULL;
129 	int homelen = 0;
130 	char *cp = NULL;
131 	char tmpfilename[257];
132 	static FILE *raw;
133 
134 	/*
135 	 * If filename given, try it, else try ~/.twmrc.# then ~/.twmrc.  Then
136 	 *   0.  -f filename
137 	 *   1.  .piewmrc.#
138 	 *   2.  .piewmrc
139 	 *   3.  .tvtwmrc.#
140 	 *   4.  .tvtwmrc
141 	 *   5.  .twmrc.#
142 	 *   6.  .twmrc
143 	 *   7.  system.twmrc
144 	 */
145 	for (twmrc = NULL, i = 0; !twmrc && i < 8; i++) {
146 	switch (i) {
147 	  case 0:           /* -f filename */
148 		cp = filename;
149 		break;
150 
151 	  case 1:           /* ~/.piewmrc.screennum */
152 		if (!filename) {
153 			home = getenv ("HOME");
154 			if (home) {
155 				homelen = strlen (home);
156 				cp = tmpfilename;
157 				(void) sprintf (tmpfilename, "%s/.piewmrc.%d",
158 					home, Scr->screen);
159 				break;
160 			}
161 		}
162 		continue;
163 
164 	  case 2:			/* ~/.piewmrc */
165 		if (home) {
166 			tmpfilename[homelen + 9] = '\0';
167 		}
168 		break;
169 
170 	  case 3:           /* ~/.tvtwmrc.screennum */
171 		if (!filename) {
172 			home = getenv ("HOME");
173 			if (home) {
174 				homelen = strlen (home);
175 				cp = tmpfilename;
176 				(void) sprintf (tmpfilename, "%s/.tvtwmrc.%d",
177 					home, Scr->screen);
178 				break;
179 			}
180 		}
181 		continue;
182 
183 	  case 4:			/* ~/.tvtwmrc */
184 		if (home) {
185 			tmpfilename[homelen + 9] = '\0';
186 		}
187 		break;
188 
189 	  case 5:			/* ~/.twmrc.screennum */
190 		if (!filename) {
191 			home = getenv ("HOME");
192 			if (home) {
193 				homelen = strlen (home);
194 				cp = tmpfilename;
195 				(void) sprintf (tmpfilename, "%s/.twmrc.%d",
196 					home, Scr->screen);
197 				break;
198 			}
199 		}
200 		continue;
201 
202 	  case 6:			/* ~/.twmrc */
203 		if (home) {
204 			tmpfilename[homelen + 7] = '\0';
205 		}
206 		break;
207 
208 	  case 7:			/* system.twmrc */
209 		sprintf(tmpfilename, "%s/default.twmrc", PIEWMDIR);
210 		break;
211 	}
212 
213 	if (cp) {
214 		raw = fopen (cp, "r");
215 		twmrc = raw;
216 	}
217 	}
218 
219     if (raw) {
220 		int status;
221 		int ignore;
222 
223 		if (filename && cp != filename) {
224 			fprintf (stderr,
225 				"%s:  unable to open twmrc file %s, using %s instead\n",
226 				ProgramName, filename, cp);
227 		}
228 		twmrc = start_m4(raw);
229 		status = doparse (twmFileInput, "file", cp);
230 		fclose (twmrc);
231 		wait (&ignore);
232 		fclose (raw);
233 		return status;
234 	} else {
235 	if (filename) {
236 	    fprintf (stderr,
237 	"%s:  unable to open twmrc file %s, using built-in defaults instead\n",
238 		     ProgramName, filename);
239 	}
240 	return ParseStringList (defTwmrc);
241     }
242 }
243 
244 int
ParseStringList(sl)245 ParseStringList (sl)
246     char **sl;
247 {
248     stringListSource = sl;
249     currentString = *sl;
250     return doparse (twmStringListInput, "string list", (char *)NULL);
251 }
252 
253 
254 /***********************************************************************
255  *
256  *  Procedure:
257  *	twmFileInput - redefinition of the lex input routine for file input
258  *
259  *  Returned Value:
260  *	the next input character
261  *
262  ***********************************************************************
263  */
264 
265 #ifdef NO_M4
266 
267 /* This has Tom's include() funtionality.  This is utterly useless if you
268  * can use m4 for the same thing.		Chris P. Ross */
269 
270 #define MAX_INCLUDES 10
271 
272 static struct incl {
273      FILE *fp;
274      char *name;
275      int lineno;
276 } rc_includes[MAX_INCLUDES];
277 static int include_file = 0;
278 
279 static int
twmFileInput()280 twmFileInput()
281 {
282     while (ptr == len)
283     {
284 	while (include_file) {
285 	     if (fgets(buff, BUF_LEN, rc_includes[include_file].fp) == NULL) {
286 		  free(rc_includes[include_file].name);
287 		  fclose(rc_includes[include_file].fp);
288 		  yylineno = rc_includes[include_file--].lineno;
289 	     } else
290 		  break;
291 	}
292 	if (!include_file)
293 	     if (fgets(buff, BUF_LEN, twmrc) == NULL)
294 		  return NULL;
295 
296 	yylineno++;
297 
298 	if (strncmp(buff, "include", 7) == 0) {
299 	     /* Whoops, an include file! */
300 	     char *p = buff + 7, *q;
301 	     FILE *fp;
302 
303 	     while (isspace(*p)) p++;
304 	     for (q = p; *q && !isspace(*q); q++)
305 		  continue;
306 	     *q = 0;
307 
308 	     if ((fp = fopen(p, "r")) == NULL) {
309 		  fprintf(stderr, "%s: Unable to open included init file %s\n",
310 			  ProgramName, p);
311 		  continue;
312 	     }
313 	     if (++include_file >= MAX_INCLUDES) {
314 		  fprintf(stderr, "%s: init file includes nested too deep\n",
315 			  ProgramName);
316 		  continue;
317 	     }
318 	     rc_includes[include_file].fp = fp;
319 	     rc_includes[include_file].lineno = yylineno;
320 	     yylineno = 0;
321 	     rc_includes[include_file].name = malloc(strlen(p)+1);
322 	     strcpy(rc_includes[include_file].name, p);
323 	     continue;
324 	}
325 	ptr = 0;
326 	len = strlen(buff);
327     }
328     return ((int)buff[ptr++]);
329 }
330 #else
331 
332 /* If you're going to use m4, use this version instead.  Much simpler.
333  * m4 ism's credit to Josh Osborne (stripes) */
334 
335 static int
twmFileInput()336 twmFileInput()
337 {
338 	while (ptr == len) {
339 		if (fgets(buff, BUF_LEN, twmrc) == NULL) return(EOF);
340 		if (!strncmp(buff, "#line", 5)) {
341 			yylineno = atoi(buff + 6);
342 			continue;
343 		} else {
344 			yylineno++;
345 		}
346 
347 		ptr = 0;
348 		len = strlen(buff);
349 	}
350 	return ((int)buff[ptr++]);
351 }
352 #endif  /* NO_M4 */
353 
354 static int
twmStringListInput()355 twmStringListInput()
356 {
357     /*
358      * return the character currently pointed to
359      */
360     if (currentString) {
361 	unsigned int c = (unsigned int) *currentString++;
362 
363 	if (c) return c;		/* if non-nul char */
364 	currentString = *++stringListSource;  /* advance to next bol */
365 	return '\n';			/* but say that we hit last eol */
366     }
367     return EOF;				/* eof */
368 }
369 
370 
371 /**********************************************************************
372  *
373  *  Parsing table and routines
374  *
375  ***********************************************************************/
376 
377 typedef struct _TwmKeyword {
378     char *name;
379     int value;
380     int subnum;
381 } TwmKeyword;
382 
383 #define kw0_NoDefaults			1
384 #define kw0_AutoRelativeResize		2
385 #define kw0_ForceIcons			3
386 #define kw0_NoIconManagers		4
387 #define kw0_OpaqueMove			5
388 #define kw0_InterpolateMenuColors	6
389 #define kw0_NoVersion			7
390 #define kw0_SortIconManager		8
391 #define kw0_NoGrabServer		9
392 #define kw0_NoMenuShadows		10
393 #define kw0_NoRaiseOnMove		11
394 #define kw0_NoRaiseOnResize		12
395 #define kw0_NoRaiseOnDeiconify		13
396 #define kw0_DontMoveOff			14
397 #define kw0_NoBackingStore		15
398 #define kw0_NoSaveUnders		16
399 #define kw0_RestartPreviousState	17
400 #define kw0_ClientBorderWidth		18
401 #define kw0_NoTitleFocus		19
402 #define kw0_RandomPlacement		20
403 #define kw0_DecorateTransients		21
404 #define kw0_ShowIconManager		22
405 #define kw0_NoCaseSensitive		23
406 #define kw0_NoRaiseOnWarp		24
407 #define kw0_WarpUnmapped		25
408 #define kw0_ShowVirtualNames		26
409 #define kw0_StickyAbove			27
410 #define kw0_StayUpMenus			28
411 #define kw0_PannerOpaqueScroll		29
412 #define kw0_ListRings			30
413 
414 #define kws_UsePPosition		1
415 #define kws_IconFont			2
416 #define kws_ResizeFont			3
417 #define kws_MenuFont			4
418 #define kws_TitleFont			5
419 #define kws_IconManagerFont		6
420 #define kws_UnknownIcon			7
421 #define kws_IconDirectory		8
422 #define kws_MaxWindowSize		9
423 #define kws_VirtualDesktop		10
424 #define kws_PannerState			11
425 #define kws_PannerGeometry		12
426 #define kws_VirtualFont			15
427 #define kws_MenuTitleFont               16
428 
429 #define kwn_ConstrainedMoveTime		1
430 #define kwn_MoveDelta			2
431 #define kwn_XorValue			3
432 #define kwn_FramePadding		4
433 #define kwn_TitlePadding		5
434 #define kwn_ButtonIndent		6
435 #define kwn_BorderWidth			7
436 #define kwn_IconBorderWidth		8
437 #define kwn_TitleButtonBorderWidth	9
438 #define kwn_PannerScale			10
439 #define kwn_ScrollDistanceX		11
440 #define kwn_ScrollDistanceY		12
441 #define kwn_MenuLineWidth               13
442 #define kwn_TitleFontPadding            14
443 #define kwn_PieMenuWait			15
444 
445 #define kwcl_BorderColor		1
446 #define kwcl_IconManagerHighlight	2
447 #define kwcl_BorderTileForeground	3
448 #define kwcl_BorderTileBackground	4
449 #define kwcl_TitleForeground		5
450 #define kwcl_TitleBackground		6
451 #define kwcl_IconForeground		7
452 #define kwcl_IconBackground		8
453 #define kwcl_IconBorderColor		9
454 #define kwcl_IconManagerForeground	10
455 #define kwcl_IconManagerBackground	11
456 #define kwcl_VirtualForeground		12
457 #define kwcl_VirtualBackground		13
458 
459 #define kwc_DefaultForeground		1
460 #define kwc_DefaultBackground		2
461 #define kwc_MenuForeground		3
462 #define kwc_MenuBackground		4
463 #define kwc_MenuTitleForeground		5
464 #define kwc_MenuTitleBackground		6
465 #define kwc_MenuShadowColor		7
466 #define kwc_VirtualDesktopForeground	8
467 #define kwc_VirtualDesktopBackground	9
468 #define kwc_PannerForeground		10
469 #define kwc_PannerBackground		11
470 
471 #define kwp_TitleHighlight              1
472 #define kwp_TitleHighlightLeft          2
473 #define kwp_TitleHighlightRight         3
474 #define kwp_PannerBackgroundPixmap      4
475 #define kwp_VirtualDesktopBackgroundPixmap 5
476 
477 /*
478  * The following is sorted alphabetically according to name (which must be
479  * in lowercase and only contain the letters a-z).  It is fed to a binary
480  * search to parse keywords.
481  */
482 static TwmKeyword keytable[] = {
483     { "all",			ALL, 0 },
484     { "autoraise",		AUTO_RAISE, 0 },
485     { "autorelativeresize",	KEYWORD, kw0_AutoRelativeResize },
486     { "bordercolor",		CLKEYWORD, kwcl_BorderColor },
487     { "bordertilebackground",	CLKEYWORD, kwcl_BorderTileBackground },
488     { "bordertileforeground",	CLKEYWORD, kwcl_BorderTileForeground },
489     { "borderwidth",		NKEYWORD, kwn_BorderWidth },
490     { "button",			BUTTON, 0 },
491     { "buttonindent",		NKEYWORD, kwn_ButtonIndent },
492     { "c",			CONTROL, 0 },
493     { "center",			JKEYWORD, J_CENTER },
494     { "clientborderwidth",	KEYWORD, kw0_ClientBorderWidth },
495     { "color",			COLOR, 0 },
496     { "constrainedmovetime",	NKEYWORD, kwn_ConstrainedMoveTime },
497     { "control",		CONTROL, 0 },
498     { "cursors",		CURSORS, 0 },
499     { "decoratetransients",	KEYWORD, kw0_DecorateTransients },
500     { "defaultbackground",	CKEYWORD, kwc_DefaultBackground },
501     { "defaultforeground",	CKEYWORD, kwc_DefaultForeground },
502     { "defaultfunction",	DEFAULT_FUNCTION, 0 },
503     { "destroy",		KILL, 0 },
504     { "donticonifybyunmapping",	DONT_ICONIFY_BY_UNMAPPING, 0 },
505     { "dontmoveoff",		KEYWORD, kw0_DontMoveOff },
506     { "dontsqueezetitle",	DONT_SQUEEZE_TITLE, 0 },
507     { "east",			DKEYWORD, D_EAST },
508     { "f",			FRAME, 0 },
509     { "f.autoraise",		FKEYWORD, F_AUTORAISE },
510     { "f.backiconmgr",		FKEYWORD, F_BACKICONMGR },
511     { "f.beep",			FKEYWORD, F_BEEP },
512     { "f.bottomzoom",		FKEYWORD, F_BOTTOMZOOM },
513     { "f.circledown",		FKEYWORD, F_CIRCLEDOWN },
514     { "f.circleup",		FKEYWORD, F_CIRCLEUP },
515     { "f.colormap",		FSKEYWORD, F_COLORMAP },
516     { "f.constrainedmove",	FKEYWORD, F_CONSTRAINEDMOVE },
517     { "f.cut",			FSKEYWORD, F_CUT },
518     { "f.cutfile",		FKEYWORD, F_CUTFILE },
519     { "f.deiconify",		FKEYWORD, F_DEICONIFY },
520     { "f.delete",		FKEYWORD, F_DELETE },
521     { "f.deltastop",		FKEYWORD, F_DELTASTOP },
522     { "f.destroy",		FKEYWORD, F_DESTROY },
523     { "f.downiconmgr",		FKEYWORD, F_DOWNICONMGR },
524     { "f.exec",			FSKEYWORD, F_EXEC },
525     { "f.file",			FSKEYWORD, F_FILE },
526     { "f.focus",		FKEYWORD, F_FOCUS },
527     { "f.forcemove",		FKEYWORD, F_FORCEMOVE },
528     { "f.forwiconmgr",		FKEYWORD, F_FORWICONMGR },
529     { "f.fullzoom",		FKEYWORD, F_FULLZOOM },
530     { "f.function",		FSKEYWORD, F_FUNCTION },
531     { "f.hbzoom",		FKEYWORD, F_BOTTOMZOOM },
532     { "f.hideiconmgr",		FKEYWORD, F_HIDELIST },
533     { "f.horizoom",		FKEYWORD, F_HORIZOOM },
534     { "f.htzoom",		FKEYWORD, F_TOPZOOM },
535     { "f.hzoom",		FKEYWORD, F_HORIZOOM },
536     { "f.iconify",		FKEYWORD, F_ICONIFY },
537     { "f.identify",		FKEYWORD, F_IDENTIFY },
538     { "f.lefticonmgr",		FKEYWORD, F_LEFTICONMGR },
539     { "f.leftzoom",		FKEYWORD, F_LEFTZOOM },
540     { "f.lower",		FKEYWORD, F_LOWER },
541     { "f.menu",			FSKEYWORD, F_MENU },
542     { "f.menufunc",		FSKEYWORD, F_MENUFUNC },
543     { "f.move",			FKEYWORD, F_MOVE },
544     { "f.nexticonmgr",		FKEYWORD, F_NEXTICONMGR },
545     { "f.nop",			FKEYWORD, F_NOP },
546     { "f.opaquemove",		FKEYWORD, F_OPAQUEMOVE },
547     { "f.pandown",		FKEYWORD, F_SCROLLDOWN },
548     { "f.panleft",		FKEYWORD, F_SCROLLLEFT },
549     { "f.panner",		FKEYWORD, F_PANNER },
550     { "f.panright",		FKEYWORD, F_SCROLLRIGHT },
551     { "f.panup",		FKEYWORD, F_SCROLLUP },
552     { "f.piemenu",		FSKEYWORD, F_PIEMENU },
553     { "f.previconmgr",		FKEYWORD, F_PREVICONMGR },
554     { "f.quit",			FKEYWORD, F_QUIT },
555     { "f.raise",		FKEYWORD, F_RAISE },
556     { "f.raiselower",		FKEYWORD, F_RAISELOWER },
557     { "f.refresh",		FKEYWORD, F_REFRESH },
558     { "f.relativeresize",	FKEYWORD, F_RELATIVERESIZE },
559     { "f.resize",		FKEYWORD, F_RESIZE },
560     { "f.restart",		FKEYWORD, F_RESTART },
561     { "f.righticonmgr",		FKEYWORD, F_RIGHTICONMGR },
562     { "f.rightzoom",		FKEYWORD, F_RIGHTZOOM },
563     { "f.saveyourself",		FKEYWORD, F_SAVEYOURSELF },
564     { "f.scroll",		FSKEYWORD, F_SCROLL },
565     { "f.scrollback",		FKEYWORD, F_SCROLLBACK },
566     { "f.scrolldown",		FKEYWORD, F_SCROLLDOWN },
567     { "f.scrollhome",		FKEYWORD, F_SCROLLHOME },
568     { "f.scrollleft",		FKEYWORD, F_SCROLLLEFT },
569     { "f.scrollright",		FKEYWORD, F_SCROLLRIGHT },
570     { "f.scrollup",		FKEYWORD, F_SCROLLUP },
571     { "f.showiconmgr",		FKEYWORD, F_SHOWLIST },
572     { "f.sorticonmgr",		FKEYWORD, F_SORTICONMGR },
573     { "f.source",		FSKEYWORD, F_BEEP },  /* XXX - don't work */
574     { "f.stick",		FKEYWORD, F_STICK },
575     { "f.test",                 FKEYWORD, F_TESTEXEC },
576     { "f.title",		FKEYWORD, F_TITLE },
577     { "f.topzoom",		FKEYWORD, F_TOPZOOM },
578     { "f.twmrc",		FKEYWORD, F_RESTART },
579     { "f.unfocus",		FKEYWORD, F_UNFOCUS },
580     { "f.upiconmgr",		FKEYWORD, F_UPICONMGR },
581     { "f.version",		FKEYWORD, F_VERSION },
582     { "f.vlzoom",		FKEYWORD, F_LEFTZOOM },
583     { "f.vrzoom",		FKEYWORD, F_RIGHTZOOM },
584     { "f.warpring",		FSKEYWORD, F_WARPRING },
585     { "f.warpto",		FSKEYWORD, F_WARPTO },
586     { "f.warptoiconmgr",	FSKEYWORD, F_WARPTOICONMGR },
587     { "f.warptoscreen",		FSKEYWORD, F_WARPTOSCREEN },
588     { "f.winrefresh",		FKEYWORD, F_WINREFRESH },
589     { "f.zoom",			FKEYWORD, F_ZOOM },
590     { "forceicons",		KEYWORD, kw0_ForceIcons },
591     { "frame",			FRAME, 0 },
592     { "framepadding",		NKEYWORD, kwn_FramePadding },
593     { "function",		FUNCTION, 0 },
594     { "i",			ICON, 0 },
595     { "icon",			ICON, 0 },
596     { "iconbackground",		CLKEYWORD, kwcl_IconBackground },
597     { "iconbordercolor",	CLKEYWORD, kwcl_IconBorderColor },
598     { "iconborderwidth",	NKEYWORD, kwn_IconBorderWidth },
599     { "icondirectory",		SKEYWORD, kws_IconDirectory },
600     { "iconfont",		SKEYWORD, kws_IconFont },
601     { "iconforeground",		CLKEYWORD, kwcl_IconForeground },
602     { "iconifybyunmapping",	ICONIFY_BY_UNMAPPING, 0 },
603     { "iconmanagerbackground",	CLKEYWORD, kwcl_IconManagerBackground },
604     { "iconmanagerdontshow",	ICONMGR_NOSHOW, 0 },
605     { "iconmanagerfont",	SKEYWORD, kws_IconManagerFont },
606     { "iconmanagerforeground",	CLKEYWORD, kwcl_IconManagerForeground },
607     { "iconmanagergeometry",	ICONMGR_GEOMETRY, 0 },
608     { "iconmanagerhighlight",	CLKEYWORD, kwcl_IconManagerHighlight },
609     { "iconmanagers",		ICONMGRS, 0 },
610     { "iconmanagershow",	ICONMGR_SHOW, 0 },
611     { "iconmgr",		ICONMGR, 0 },
612     { "iconregion",		ICON_REGION, 0 },
613     { "icons",			ICONS, 0 },
614     { "icontitle",		ICON_TITLE, 0 },
615     { "interpolatemenucolors",	KEYWORD, kw0_InterpolateMenuColors },
616 	{ "l",            LOCK, 0 },
617     { "left",			JKEYWORD, J_LEFT },
618     { "lefttitlebutton",	LEFT_TITLEBUTTON, 0 },
619 	{ "lock",         LOCK, 0 },
620     { "listrings",	        KEYWORD, kw0_ListRings },
621     { "m",			META, 0 },
622     { "maketitle",		MAKE_TITLE, 0 },
623     { "maxwindowsize",		SKEYWORD, kws_MaxWindowSize },
624     { "menu",			MENU, 0 },
625     { "menubackground",		CKEYWORD, kwc_MenuBackground },
626     { "menufont",		SKEYWORD, kws_MenuFont },
627     { "menuforeground",		CKEYWORD, kwc_MenuForeground },
628     { "menulinewidth",		NKEYWORD, kwn_MenuLineWidth },
629     { "menushadowcolor",	CKEYWORD, kwc_MenuShadowColor },
630     { "menutitlebackground",	CKEYWORD, kwc_MenuTitleBackground },
631     { "menutitlefont",		SKEYWORD, kws_MenuTitleFont },
632     { "menutitleforeground",	CKEYWORD, kwc_MenuTitleForeground },
633     { "meta",			META, 0 },
634     { "mod",			META, 0 },  /* fake it */
635     { "monochrome",		MONOCHROME, 0 },
636     { "move",			MOVE, 0 },
637     { "movedelta",		NKEYWORD, kwn_MoveDelta },
638     { "nobackingstore",		KEYWORD, kw0_NoBackingStore },
639     { "nocasesensitive",	KEYWORD, kw0_NoCaseSensitive },
640     { "nodefaults",		KEYWORD, kw0_NoDefaults },
641     { "nograbserver",		KEYWORD, kw0_NoGrabServer },
642     { "nohighlight",		NO_HILITE, 0 },
643     { "noiconmanagers",		KEYWORD, kw0_NoIconManagers },
644     { "noicontitle",		NO_ICON_TITLE, 0 },
645     { "nomenushadows",		KEYWORD, kw0_NoMenuShadows },
646     { "noraiseondeiconify",	KEYWORD, kw0_NoRaiseOnDeiconify },
647     { "noraiseonmove",		KEYWORD, kw0_NoRaiseOnMove },
648     { "noraiseonresize",	KEYWORD, kw0_NoRaiseOnResize },
649     { "noraiseonwarp",		KEYWORD, kw0_NoRaiseOnWarp },
650     { "north",			DKEYWORD, D_NORTH },
651     { "nosaveunders",		KEYWORD, kw0_NoSaveUnders },
652     { "nostackmode",		NO_STACKMODE, 0 },
653     { "notitle",		NO_TITLE, 0 },
654     { "notitlefocus",		KEYWORD, kw0_NoTitleFocus },
655     { "notitlehighlight",	NO_TITLE_HILITE, 0 },
656     { "noversion",		KEYWORD, kw0_NoVersion },
657     { "opaquemove",		KEYWORD, kw0_OpaqueMove },
658     { "pannerbackground",	CKEYWORD, kwc_PannerBackground },
659     { "pannerbackgroundpixmap",	PKEYWORD, kwp_PannerBackgroundPixmap },
660     { "pannerforeground",	CKEYWORD, kwc_PannerForeground },
661     { "pannergeometry",		SKEYWORD, kws_PannerGeometry },
662     { "panneropaquescroll",       KEYWORD, kw0_PannerOpaqueScroll },
663     { "pannerscale",		NKEYWORD, kwn_PannerScale },
664     { "pannerstate",		SKEYWORD, kws_PannerState },
665     { "piemenu",		PIEMENU, 0 },
666     { "piemenuwait",		NKEYWORD, kwn_PieMenuWait },
667     { "pixmaps",		PIXMAPS, 0 },
668     { "r",			ROOT, 0 },
669     { "randomplacement",	KEYWORD, kw0_RandomPlacement },
670     { "resize",			RESIZE, 0 },
671     { "resizefont",		SKEYWORD, kws_ResizeFont },
672     { "restartpreviousstate",	KEYWORD, kw0_RestartPreviousState },
673     { "right",			JKEYWORD, J_RIGHT },
674     { "righttitlebutton",	RIGHT_TITLEBUTTON, 0 },
675     { "root",			ROOT, 0 },
676     { "s",			SHIFT, 0 },
677     { "scrolldistancex",	NKEYWORD, kwn_ScrollDistanceX },
678     { "scrolldistancey",	NKEYWORD, kwn_ScrollDistanceY },
679     { "select",			SELECT, 0 },
680     { "shift",			SHIFT, 0 },
681     { "showiconmanager",	KEYWORD, kw0_ShowIconManager },
682     { "showvirtualnames",	KEYWORD, kw0_ShowVirtualNames },
683     { "sorticonmanager",	KEYWORD, kw0_SortIconManager },
684     { "south",			DKEYWORD, D_SOUTH },
685     { "squeezetitle",		SQUEEZE_TITLE, 0 },
686     { "starticonified",		START_ICONIFIED, 0 },
687     { "stayupmenus",		KEYWORD, kw0_StayUpMenus },
688     { "sticky",			STICKY, 0 },
689     { "stickyabove",		KEYWORD, kw0_StickyAbove },
690     { "t",			TITLE, 0 },
691     { "title",			TITLE, 0 },
692     { "titlebackground",	CLKEYWORD, kwcl_TitleBackground },
693     { "titlebuttonborderwidth",	NKEYWORD, kwn_TitleButtonBorderWidth },
694     { "titlefont",		SKEYWORD, kws_TitleFont },
695     { "titlefontpadding",       NKEYWORD, kwn_TitleFontPadding },
696     { "titleforeground",	CLKEYWORD, kwcl_TitleForeground },
697     { "titlehighlight",		PKEYWORD, kwp_TitleHighlight },
698     { "titlehighlightleft",	PKEYWORD, kwp_TitleHighlightLeft },
699     { "titlehighlightright",	PKEYWORD, kwp_TitleHighlightRight },
700     { "titlepadding",		NKEYWORD, kwn_TitlePadding },
701     { "unknownicon",		SKEYWORD, kws_UnknownIcon },
702     { "usepposition",		SKEYWORD, kws_UsePPosition },
703     { "virtualbackground",	CLKEYWORD, kwcl_VirtualBackground },
704     { "virtualdesktop",		SKEYWORD, kws_VirtualDesktop },
705     { "virtualdesktopbackground",CKEYWORD, kwc_VirtualDesktopBackground },
706     { "virtualdesktopbackgroundpixmap",PKEYWORD,
707 				    kwp_VirtualDesktopBackgroundPixmap },
708     { "virtualdesktopforeground",CKEYWORD, kwc_VirtualDesktopForeground },
709     { "virtualfont",		SKEYWORD, kws_VirtualFont },
710     { "virtualforeground",	CLKEYWORD, kwcl_VirtualForeground },
711     { "w",			WINDOW, 0 },
712     { "wait",			WAIT, 0 },
713     { "warpcursor",		WARP_CURSOR, 0 },
714     { "warpunmapped",		KEYWORD, kw0_WarpUnmapped },
715     { "west",			DKEYWORD, D_WEST },
716     { "window",			WINDOW, 0 },
717     { "windowfunction",		WINDOW_FUNCTION, 0 },
718     { "windowring",		WINDOW_RING, 0 },
719     { "xorvalue",		NKEYWORD, kwn_XorValue },
720     { "zoom",			ZOOM, 0 },
721 };
722 
723 static int numkeywords = (sizeof(keytable)/sizeof(keytable[0]));
724 
725 int
parse_keyword(s,nump)726 parse_keyword (s, nump)
727     char *s;
728     int *nump;
729 {
730     register int lower = 0, upper = numkeywords - 1;
731 
732     XmuCopyISOLatin1Lowered (s, s);
733     while (lower <= upper) {
734         int middle = (lower + upper) / 2;
735 	TwmKeyword *p = &keytable[middle];
736         int res = strcmp (p->name, s);
737 
738         if (res < 0) {
739             lower = middle + 1;
740         } else if (res == 0) {
741 	    *nump = p->subnum;
742             return p->value;
743         } else {
744             upper = middle - 1;
745         }
746     }
747     return ERRORTOKEN;
748 }
749 
750 
751 
752 /*
753  * action routines called by grammar
754  */
755 
756 int
do_single_keyword(keyword)757 do_single_keyword (keyword)
758     int keyword;
759 {
760     switch (keyword) {
761       case kw0_NoDefaults:
762 	Scr->NoDefaults = TRUE;
763 	return 1;
764 
765       case kw0_StickyAbove:
766 	Scr->StickyAbove = TRUE;
767 	return 1;
768 
769       case kw0_PannerOpaqueScroll:
770 	Scr->PannerOpaqueScroll = TRUE;
771 	return 1;
772 
773       case kw0_AutoRelativeResize:
774 	Scr->AutoRelativeResize = TRUE;
775 	return 1;
776 
777       case kw0_ForceIcons:
778 	if (Scr->FirstTime) Scr->ForceIcon = TRUE;
779 	return 1;
780 
781       case kw0_NoIconManagers:
782 	Scr->NoIconManagers = TRUE;
783 	return 1;
784 
785       case kw0_OpaqueMove:
786 	Scr->OpaqueMove = TRUE;
787 	return 1;
788 
789       case kw0_InterpolateMenuColors:
790 	if (Scr->FirstTime) Scr->InterpolateMenuColors = TRUE;
791 	return 1;
792 
793       case kw0_NoVersion:
794 	/* obsolete */
795 	return 1;
796 
797       case kw0_SortIconManager:
798 	if (Scr->FirstTime) Scr->SortIconMgr = TRUE;
799 	return 1;
800 
801       case kw0_NoGrabServer:
802 	Scr->NoGrabServer = TRUE;
803 	return 1;
804 
805       case kw0_NoMenuShadows:
806 	if (Scr->FirstTime) Scr->Shadow = FALSE;
807 	return 1;
808 
809       case kw0_NoRaiseOnMove:
810 	if (Scr->FirstTime) Scr->NoRaiseMove = TRUE;
811 	return 1;
812 
813       case kw0_NoRaiseOnResize:
814 	if (Scr->FirstTime) Scr->NoRaiseResize = TRUE;
815 	return 1;
816 
817       case kw0_NoRaiseOnDeiconify:
818 	if (Scr->FirstTime) Scr->NoRaiseDeicon = TRUE;
819 	return 1;
820 
821       case kw0_DontMoveOff:
822 	Scr->DontMoveOff = TRUE;
823 	return 1;
824 
825       case kw0_NoBackingStore:
826 	Scr->BackingStore = FALSE;
827 	return 1;
828 
829       case kw0_NoSaveUnders:
830 	Scr->SaveUnder = FALSE;
831 	return 1;
832 
833       case kw0_RestartPreviousState:
834 	RestartPreviousState = True;
835 	return 1;
836 
837       case kw0_ClientBorderWidth:
838 	if (Scr->FirstTime) Scr->ClientBorderWidth = TRUE;
839 	return 1;
840 
841       case kw0_NoTitleFocus:
842 	Scr->TitleFocus = FALSE;
843 	return 1;
844 
845       case kw0_RandomPlacement:
846 	Scr->RandomPlacement = TRUE;
847 	return 1;
848 
849       case kw0_DecorateTransients:
850 	Scr->DecorateTransients = TRUE;
851 	return 1;
852 
853       case kw0_ShowIconManager:
854 	Scr->ShowIconManager = TRUE;
855 	return 1;
856 
857       case kw0_ShowVirtualNames:
858 	Scr->ShowVirtualNames = TRUE;
859 	return 1;
860 
861       case kw0_StayUpMenus:
862 	if (Scr->FirstTime) Scr->StayUpMenus = TRUE;
863 	return 1;
864 
865       case kw0_NoCaseSensitive:
866 	Scr->CaseSensitive = FALSE;
867 	return 1;
868 
869       case kw0_NoRaiseOnWarp:
870 	Scr->NoRaiseWarp = TRUE;
871 	return 1;
872 
873       case kw0_WarpUnmapped:
874 	Scr->WarpUnmapped = TRUE;
875 	return 1;
876 
877       case kw0_ListRings:
878 	if (Scr->FirstTime) Scr->ListRings = TRUE;
879 	return 1;
880     }
881 
882     return 0;
883 }
884 
885 
886 int
do_string_keyword(keyword,s)887 do_string_keyword (keyword, s)
888     int keyword;
889     char *s;
890 {
891     switch (keyword) {
892 
893       case kws_VirtualDesktop:
894 	{
895 	    int status, x, y;
896 	    unsigned int width, height;
897 
898 	    status = XParseGeometry(s, &x, &y, &width, &height);
899 	    if ((status & (WidthValue & HeightValue)) != (WidthValue & HeightValue)) {
900 		twmrc_error_prefix();
901 		fprintf (stderr,
902 			 "ignoring invalid VirtualDesktop geometry \"%s\"\n", s);
903 	    } else {
904 	   	Scr->VirtualDesktop = True;
905 		Scr->vdtWidth = width;
906 		Scr->vdtHeight = height;
907 	    }
908 	    return 1;
909 	}
910 
911       case kws_PannerState:
912 	{
913 	    int state = ParseState(s);
914 	    if (state < 0) {
915 		twmrc_error_prefix();
916 		fprintf (stderr,
917 			 "ignoring invalid PannerState argument \"%s\"\n", s);
918 	    } else {
919 		Scr->PannerState = state;
920 	    }
921 	    return 1;
922 	}
923 
924       case kws_PannerGeometry:
925 	{
926 	    int status, x, y;
927 	    unsigned int width, height;
928 
929 	    status = XParseGeometry(s, &x, &y, &width, &height);
930 	    if ((status & (XValue & YValue)) != (XValue & YValue)) {
931 		twmrc_error_prefix();
932 		fprintf (stderr,
933 			 "ignoring invalid PannerGeometry \"%s\"\n", s);
934 	    } else {
935 		Scr->PannerGeometry = s;
936 	    }
937 	    return 1;
938 	}
939 
940       case kws_UsePPosition:
941 	{
942 	    int ppos = ParseUsePPosition (s);
943 	    if (ppos < 0) {
944 		twmrc_error_prefix();
945 		fprintf (stderr,
946 			 "ignoring invalid UsePPosition argument \"%s\"\n", s);
947 	    } else {
948 		Scr->UsePPosition = ppos;
949 	    }
950 	    return 1;
951 	}
952 
953       case kws_VirtualFont:
954 	if (!Scr->HaveFonts) Scr->VirtualFont.name = s;
955 	return 1;
956 
957       case kws_IconFont:
958 	if (!Scr->HaveFonts) Scr->IconFont.name = s;
959 	return 1;
960 
961       case kws_ResizeFont:
962 	if (!Scr->HaveFonts) Scr->SizeFont.name = s;
963 	return 1;
964 
965       case kws_MenuFont:
966 	if (!Scr->HaveFonts) Scr->MenuFont.name = s;
967 	return 1;
968 
969       case kws_MenuTitleFont:
970 	if (!Scr->HaveFonts) Scr->MenuTitleFont.name = s;
971 	return 1;
972 
973       case kws_TitleFont:
974 	if (!Scr->HaveFonts) Scr->TitleBarFont.name = s;
975 	return 1;
976 
977       case kws_IconManagerFont:
978 	if (!Scr->HaveFonts) Scr->IconManagerFont.name = s;
979 	return 1;
980 
981       case kws_UnknownIcon:
982 	if (Scr->FirstTime) GetUnknownIcon (s);
983 	return 1;
984 
985       case kws_IconDirectory:
986 	if (Scr->FirstTime) Scr->IconDirectory = ExpandFilename (s);
987 	return 1;
988 
989       case kws_MaxWindowSize:
990 	JunkMask = XParseGeometry (s, &JunkX, &JunkY, &JunkWidth, &JunkHeight);
991 	if ((JunkMask & (WidthValue | HeightValue)) !=
992 	    (WidthValue | HeightValue)) {
993 	    twmrc_error_prefix();
994 	    fprintf (stderr, "bad MaxWindowSize \"%s\"\n", s);
995 	    return 0;
996 	}
997 	if (JunkWidth <= 0 || JunkHeight <= 0) {
998 	    twmrc_error_prefix();
999 	    fprintf (stderr, "MaxWindowSize \"%s\" must be positive\n", s);
1000 	    return 0;
1001 	}
1002 	Scr->MaxWindowWidth = JunkWidth;
1003 	Scr->MaxWindowHeight = JunkHeight;
1004 	return 1;
1005     }
1006 
1007     return 0;
1008 }
1009 
1010 
1011 int
do_number_keyword(keyword,num)1012 do_number_keyword (keyword, num)
1013     int keyword;
1014     int num;
1015 {
1016     switch (keyword) {
1017       case kwn_PannerScale:
1018 	if (num > 0)
1019 	    Scr->PannerScale = num;
1020 	return 1;
1021 
1022       case kwn_ScrollDistanceX:
1023 	if (Scr->FirstTime)
1024 		Scr->vdtScrollDistanceX = (num * Scr->MyDisplayWidth) / 100;
1025 	return 1;
1026 
1027       case kwn_ScrollDistanceY:
1028 	if (Scr->FirstTime)
1029 		Scr->vdtScrollDistanceY = (num * Scr->MyDisplayHeight) / 100;
1030 	return 1;
1031 
1032       case kwn_ConstrainedMoveTime:
1033 	ConstrainedMoveTime = num;
1034 	return 1;
1035 
1036       case kwn_MenuLineWidth:
1037 	Scr->MenuLineWidth = num;
1038 	return 1;
1039 
1040       case kwn_TitleFontPadding:
1041 	Scr->TitleFontPadding = num;
1042 	return 1;
1043 
1044       case kwn_MoveDelta:
1045 	Scr->MoveDelta = num;
1046 	return 1;
1047 
1048       case kwn_PieMenuWait:
1049 	PieMenuWait = num;
1050 	return 1;
1051 
1052       case kwn_XorValue:
1053 	if (Scr->FirstTime) Scr->XORvalue = num;
1054 	return 1;
1055 
1056       case kwn_FramePadding:
1057 	if (Scr->FirstTime) Scr->FramePadding = num;
1058 	return 1;
1059 
1060       case kwn_TitlePadding:
1061 	if (Scr->FirstTime) Scr->TitlePadding = num;
1062 	return 1;
1063 
1064       case kwn_ButtonIndent:
1065 	if (Scr->FirstTime) Scr->ButtonIndent = num;
1066 	return 1;
1067 
1068       case kwn_BorderWidth:
1069 	if (Scr->FirstTime) Scr->BorderWidth = num;
1070 	return 1;
1071 
1072       case kwn_IconBorderWidth:
1073 	if (Scr->FirstTime) Scr->IconBorderWidth = num;
1074 	return 1;
1075 
1076       case kwn_TitleButtonBorderWidth:
1077 	if (Scr->FirstTime) Scr->TBInfo.border = num;
1078 	return 1;
1079 
1080     }
1081 
1082     return 0;
1083 }
1084 
1085 name_list **
do_colorlist_keyword(keyword,colormode,s)1086 do_colorlist_keyword (keyword, colormode, s)
1087     int keyword;
1088     int colormode;
1089     char *s;
1090 {
1091     switch (keyword) {
1092       case kwcl_BorderColor:
1093 	GetColor (colormode, &Scr->BorderColor, s);
1094 	return &Scr->BorderColorL;
1095 
1096       case kwcl_IconManagerHighlight:
1097 	GetColor (colormode, &Scr->IconManagerHighlight, s);
1098 	return &Scr->IconManagerHighlightL;
1099 
1100       case kwcl_BorderTileForeground:
1101 	GetColor (colormode, &Scr->BorderTileC.fore, s);
1102 	return &Scr->BorderTileForegroundL;
1103 
1104       case kwcl_BorderTileBackground:
1105 	GetColor (colormode, &Scr->BorderTileC.back, s);
1106 	return &Scr->BorderTileBackgroundL;
1107 
1108       case kwcl_TitleForeground:
1109 	GetColor (colormode, &Scr->TitleC.fore, s);
1110 	return &Scr->TitleForegroundL;
1111 
1112       case kwcl_TitleBackground:
1113 	GetColor (colormode, &Scr->TitleC.back, s);
1114 	return &Scr->TitleBackgroundL;
1115 
1116       case kwcl_VirtualForeground:
1117 	GetColor (colormode, &Scr->VirtualC.fore, s);
1118 	return &Scr->VirtualForegroundL;
1119 
1120       case kwcl_VirtualBackground:
1121 	GetColor (colormode, &Scr->VirtualC.back, s);
1122 	return &Scr->VirtualBackgroundL;
1123 
1124       case kwcl_IconForeground:
1125 	GetColor (colormode, &Scr->IconC.fore, s);
1126 	return &Scr->IconForegroundL;
1127 
1128       case kwcl_IconBackground:
1129 	GetColor (colormode, &Scr->IconC.back, s);
1130 	return &Scr->IconBackgroundL;
1131 
1132       case kwcl_IconBorderColor:
1133 	GetColor (colormode, &Scr->IconBorderColor, s);
1134 	return &Scr->IconBorderColorL;
1135 
1136       case kwcl_IconManagerForeground:
1137 	GetColor (colormode, &Scr->IconManagerC.fore, s);
1138 	return &Scr->IconManagerFL;
1139 
1140       case kwcl_IconManagerBackground:
1141 	GetColor (colormode, &Scr->IconManagerC.back, s);
1142 	return &Scr->IconManagerBL;
1143     }
1144 
1145     return NULL;
1146 }
1147 
1148 int
do_color_keyword(keyword,colormode,s)1149 do_color_keyword (keyword, colormode, s)
1150     int keyword;
1151     int colormode;
1152     char *s;
1153 {
1154     switch (keyword) {
1155       case kwc_PannerBackground:
1156 	GetColor (colormode, &Scr->PannerC.back, s);
1157 	Scr->PannerBackgroundSet = True;
1158 	return 1;
1159 
1160       case kwc_PannerForeground:
1161 	GetColor (colormode, &Scr->PannerC.fore, s);
1162 	return 1;
1163 
1164       case kwc_VirtualDesktopBackground:
1165 	if (GetColor (colormode, &Scr->vdtC.back, s))
1166 	    Scr->vdtBackgroundSet = True;
1167 	return 1;
1168 
1169       case kwc_VirtualDesktopForeground:
1170 	GetColor (colormode, &Scr->vdtC.fore, s);
1171 	return 1;
1172 
1173       case kwc_DefaultForeground:
1174 	GetColor (colormode, &Scr->DefaultC.fore, s);
1175 	return 1;
1176 
1177       case kwc_DefaultBackground:
1178 	GetColor (colormode, &Scr->DefaultC.back, s);
1179 	return 1;
1180 
1181       case kwc_MenuForeground:
1182 	GetColor (colormode, &Scr->MenuC.fore, s);
1183 	return 1;
1184 
1185       case kwc_MenuBackground:
1186 	GetColor (colormode, &Scr->MenuC.back, s);
1187 	return 1;
1188 
1189       case kwc_MenuTitleForeground:
1190 	GetColor (colormode, &Scr->MenuTitleC.fore, s);
1191 	return 1;
1192 
1193       case kwc_MenuTitleBackground:
1194 	GetColor (colormode, &Scr->MenuTitleC.back, s);
1195 	return 1;
1196 
1197       case kwc_MenuShadowColor:
1198 	GetColor (colormode, &Scr->MenuShadowColor, s);
1199 	return 1;
1200 
1201     }
1202 
1203     return 0;
1204 }
1205 
1206 int
do_pixmap_keyword(keyword,filename)1207 do_pixmap_keyword(keyword, filename)
1208     int keyword;
1209     char *filename;
1210 {
1211     unsigned int JunkWidth, JunkHeight;
1212     Pixmap pm;
1213 
1214     switch (keyword) {
1215 
1216     case kwp_TitleHighlight:
1217         pm = FindPixmap(filename, &JunkWidth, &JunkHeight,
1218 			JunkIsXpm, NULL, NULL);
1219 
1220 	if (pm) {
1221 	    if (Scr->hilitePm) {
1222 	        XFreePixmap (dpy, Scr->hilitePm);
1223 	    }
1224 	    Scr->hilitePm = pm;
1225 	    Scr->hilite_pm_width = JunkWidth;
1226 	    Scr->hilite_pm_height = JunkHeight;
1227 	    Scr->hilite_pm_isXpm = *JunkIsXpm;
1228 	}
1229 	return 1;
1230 
1231     case kwp_TitleHighlightLeft:
1232 	pm = FindPixmap(filename, &JunkWidth, &JunkHeight,
1233 			JunkIsXpm, NULL, NULL);
1234 	if (pm) {
1235 	    if (Scr->hiliteLeftPm) {
1236 	        XFreePixmap (dpy, Scr->hiliteLeftPm);
1237 	    }
1238 	    Scr->hiliteLeftPm = pm;
1239 	    Scr->hilite_left_pm_width = JunkWidth;
1240 	    Scr->hilite_left_pm_height = JunkHeight;
1241 	    Scr->hilite_left_pm_isXpm = *JunkIsXpm;
1242 	}
1243 	return 1;
1244 
1245     case kwp_TitleHighlightRight:
1246 	pm = FindPixmap(filename, &JunkWidth, &JunkHeight,
1247 			JunkIsXpm, NULL, NULL);
1248 	if (pm) {
1249 	    if (Scr->hiliteRightPm) {
1250 	        XFreePixmap (dpy, Scr->hiliteRightPm);
1251 	    }
1252 	    Scr->hiliteRightPm = pm;
1253 	    Scr->hilite_right_pm_width = JunkWidth;
1254 	    Scr->hilite_right_pm_height = JunkHeight;
1255 	    Scr->hilite_right_pm_isXpm = *JunkIsXpm;
1256 	}
1257 	return 1;
1258 
1259     case kwp_PannerBackgroundPixmap:
1260 	Scr->PannerPixmap = filename;
1261 	return 1;
1262 
1263     case kwp_VirtualDesktopBackgroundPixmap:
1264 	Scr->vdtPixmap = filename;
1265 	return 1;
1266     }
1267     return 0;
1268 }
1269 
1270 static int
ParseUsePPosition(char * s)1271 ParseUsePPosition(char *s)
1272 {
1273     XmuCopyISOLatin1Lowered (s, s);
1274 
1275     if (strcmp (s, "off") == 0) {
1276 	return PPOS_OFF;
1277     } else if (strcmp (s, "on") == 0) {
1278 	return PPOS_ON;
1279     } else if (strcmp (s, "non-zero") == 0 ||
1280 	       strcmp (s, "nonzero") == 0) {
1281 	return PPOS_NON_ZERO;
1282     }
1283 
1284     return -1;
1285 }
1286 
1287 static int
ParseState(char * s)1288 ParseState(char *s)
1289 {
1290     XmuCopyISOLatin1Lowered (s, s);
1291 
1292     if (strcmp (s, "withdrawn") == 0) {
1293 	return WithdrawnState;
1294     } else if (strcmp (s, "normal") == 0) {
1295 	return NormalState;
1296     } else if (strcmp (s, "iconic") == 0) {
1297 	return IconicState;
1298     }
1299 
1300     return -1;
1301 }
1302 
1303 void
do_squeeze_entry(name_list ** list,char * name,int justify,int num,int denom)1304 do_squeeze_entry (name_list **list,			/* squeeze or dont-squeeze list */
1305     char *name,				/* window name */
1306     int justify,			/* left, center, right */
1307     int num,				/* signed num */
1308     int denom				/* 0 or indicates fraction denom */)
1309 {
1310     int absnum = (num < 0 ? -num : num);
1311 
1312     if (denom < 0) {
1313 	twmrc_error_prefix();
1314 	fprintf (stderr, "negative SqueezeTitle denominator %d\n", denom);
1315 	return;
1316     }
1317     if (absnum > denom && denom != 0) {
1318 	twmrc_error_prefix();
1319 	fprintf (stderr, "SqueezeTitle fraction %d/%d outside window\n",
1320 		 num, denom);
1321 	return;
1322     }
1323     if (denom == 1) {
1324 	twmrc_error_prefix();
1325 	fprintf (stderr, "useless SqueezeTitle faction %d/%d, assuming 0/0\n",
1326 		 num, denom);
1327 	num = 0;
1328 	denom = 0;
1329     }
1330 
1331 #ifdef SHAPE
1332     if (HasShape) {
1333 	SqueezeInfo *sinfo;
1334 	sinfo = (SqueezeInfo *) malloc (sizeof(SqueezeInfo));
1335 
1336 	if (!sinfo) {
1337 	    twmrc_error_prefix();
1338 	    fprintf (stderr, "unable to allocate %d bytes for squeeze info\n",
1339 		     sizeof(SqueezeInfo));
1340 	    return;
1341 	}
1342 	sinfo->justify = justify;
1343 	sinfo->num = num;
1344 	sinfo->denom = denom;
1345 	AddToList (list, name, (char *) sinfo);
1346     }
1347 #endif
1348 }
1349 
1350 static char *m4_defs(Display *display, char *host);
1351 
1352 static FILE *
start_m4(FILE * fraw)1353 start_m4(FILE *fraw)
1354 {
1355 	int fno;
1356 	int fids[2];
1357 	int fres;		/* Fork result */
1358 
1359 	fno = fileno(fraw);
1360 	/* if (-1 == fcntl(fno, F_SETFD, 0)) perror("fcntl()"); */
1361 	pipe(fids);
1362 	fres = fork();
1363 	if (fres < 0) {
1364 		perror("Fork for m4 failed");
1365 		exit(23);
1366 	}
1367 	if (fres == 0) {
1368 		extern Display *dpy;
1369 		extern char *display_name;
1370 		char *tmp_file;
1371 
1372 		/* Child */
1373 		close(0);			/* stdin */
1374 		close(1);			/* stdout */
1375 		dup2(fno, 0);		/* stdin = fraw */
1376 		dup2(fids[1], 1);	/* stdout = pipe to parent */
1377 		/* get_defs("m4", dpy, display_name) */
1378 		tmp_file = m4_defs(dpy, display_name);
1379 		execlp("m4", "m4", tmp_file, "-", NULL);
1380 		/* If we get here we are screwed... */
1381 		perror("Can't execlp() m4");
1382 		exit(124);
1383 	}
1384 	/* Parent */
1385 	close(fids[1]);
1386 	return(fdopen(fids[0], "r"));
1387 }
1388 
1389 /* Code taken and munged from xrdb.c */
1390 #define MAXHOSTNAME 255
1391 #define Resolution(pixels, mm)	((((pixels) * 100000 / (mm)) + 50) / 100)
1392 #define EXTRA	12
1393 
1394 static char *
MkDef(char * name,const char * def)1395 MkDef(char *name, const char *def)
1396 {
1397 	static char *cp = NULL;
1398 	static int maxsize = 0;
1399 	int n, nl;
1400 
1401 	/* The char * storage only lasts for 1 call... */
1402 	if ((n = EXTRA + ((nl = strlen(name)) +  strlen(def))) > maxsize) {
1403 		if (cp) free(cp);
1404 		cp = malloc(n);
1405 	}
1406 	/* Otherwise cp is aready big 'nuf */
1407 	if (cp == NULL) {
1408 		fprintf(stderr, "Can't get %d bytes for arg parm\n", n);
1409 		exit(468);
1410 	}
1411 	strcpy(cp, "define(");
1412 	strcpy(cp+7, name);
1413 	*(cp + nl + 7) = ',';
1414 	*(cp + nl + 8) = ' ';
1415 	strcpy(cp + nl + 9, def);
1416 	strcat(cp + nl + 9, ")\n");
1417 	return(cp);
1418 }
1419 
1420 static char *
MkNum(name,def)1421 MkNum(name, def)
1422 char *name;
1423 int def;
1424 {
1425 	char num[20];
1426 
1427 	sprintf(num, "%d", def);
1428 	return(MkDef(name, num));
1429 }
1430 
1431 #ifdef NOSTEMP
1432 int
mkstemp(char * str)1433 mkstemp(char *str)
1434 {
1435 	int fd;
1436 
1437 	mktemp(str);
1438 	fd = creat(str, 0744);
1439 	if (fd == -1) perror("mkstemp's creat");
1440 	return(fd);
1441 }
1442 #endif
1443 
1444 static char *
m4_defs(Display * display,char * host)1445 m4_defs(Display *display, char *host)
1446 {
1447 	extern int KeepTmpFile;
1448 	Screen *screen;
1449 	Visual *visual;
1450 	char client[MAXHOSTNAME], server[MAXHOSTNAME], *colon;
1451 	struct hostent *hostname;
1452 	char *vc;		/* Visual Class */
1453 	static char tmp_name[] = "/tmp/twmrcXXXXXX";
1454 	int fd;
1455 	FILE *tmpf;
1456 
1457 	fd = mkstemp(tmp_name);	/* I *hope* mkstemp exists, because */
1458 				/* I tried to find the "portable" */
1459 				/* mktmp... */
1460 	if (fd < 0) {
1461 		perror("mkstemp failed in m4_defs");
1462 		exit(377);
1463 	}
1464 	tmpf = fdopen(fd, "w+");
1465 	XmuGetHostname(client, MAXHOSTNAME);
1466 	hostname = gethostbyname(client);
1467 	strcpy(server, XDisplayName(host));
1468 	colon = index(server, ':');
1469 	if (colon != NULL) *colon = '\0';
1470 	if ((server[0] == '\0') || (!strcmp(server, "unix")))
1471 		strcpy(server, client); /* must be connected to :0 or unix:0 */
1472 	/* The machine running the X server */
1473 	fputs(MkDef("SERVERHOST", server), tmpf);
1474 	/* The machine running the window manager process */
1475 	fputs(MkDef("CLIENTHOST", client), tmpf);
1476 	if (hostname)
1477 		fputs(MkDef("HOSTNAME", hostname->h_name), tmpf);
1478 	else
1479 		fputs(MkDef("HOSTNAME", client), tmpf);
1480 	fputs(MkDef("USER", getenv("USER")), tmpf);
1481 	fputs(MkDef("HOME", getenv("HOME")), tmpf);
1482 	fputs(MkNum("VERSION", ProtocolVersion(display)), tmpf);
1483 	fputs(MkNum("REVISION", ProtocolRevision(display)), tmpf);
1484 	fputs(MkDef("VENDOR", ServerVendor(display)), tmpf);
1485 	fputs(MkNum("RELEASE", VendorRelease(display)), tmpf);
1486 	screen = ScreenOfDisplay(display, Scr->screen);
1487 	visual = DefaultVisualOfScreen(screen);
1488 	fputs(MkNum("WIDTH", screen->width), tmpf);
1489 	fputs(MkNum("HEIGHT", screen->height), tmpf);
1490 	fputs(MkNum("X_RESOLUTION",Resolution(screen->width,screen->mwidth)), tmpf);
1491 	fputs(MkNum("Y_RESOLUTION",Resolution(screen->height,screen->mheight)),tmpf);
1492 	fputs(MkNum("PLANES",DisplayPlanes(display, DefaultScreen(display))), tmpf);
1493 	fputs(MkNum("BITS_PER_RGB", visual->bits_per_rgb), tmpf);
1494 	fputs(MkDef("TWM_TYPE", "piewm"), tmpf);
1495 	switch(visual->class) {
1496 		case(StaticGray):	vc = "StaticGray";	break;
1497 		case(GrayScale):	vc = "GrayScale";	break;
1498 		case(StaticColor):	vc = "StaticColor";	break;
1499 		case(PseudoColor):	vc = "PseudoColor";	break;
1500 		case(TrueColor):	vc = "TrueColor";	break;
1501 		case(DirectColor):	vc = "DirectColor";	break;
1502 		default:		vc = "NonStandard";	break;
1503 	}
1504 	fputs(MkDef("CLASS", vc), tmpf);
1505 	if (visual->class != StaticGray && visual->class != GrayScale) {
1506 		fputs(MkDef("COLOR", "Yes"), tmpf);
1507 	} else {
1508 		fputs(MkDef("COLOR", "No"), tmpf);
1509 	}
1510 	if (KeepTmpFile) {
1511 		fprintf(stderr, "Left file: %s\n", tmp_name);
1512 	} else {
1513 		fprintf(tmpf, "syscmd(/bin/rm %s)\n", tmp_name);
1514 	}
1515 	fclose(tmpf);
1516 	return(tmp_name);
1517 }
1518