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 * Copyright 1992 Claude Lecommandeur.
8 */
9
10/***********************************************************************
11 *
12 * $XConsortium: gram.y,v 1.91 91/02/08 18:21:56 dave Exp $
13 *
14 * .twmrc command grammer
15 *
16 * 07-Jan-86 Thomas E. LaStrange	File created
17 * 11-Nov-90 Dave Sternlicht            Adding SaveColors
18 * 10-Oct-90 David M. Sternlicht        Storing saved colors on root
19 * 22-April-92 Claude Lecommandeur	modifications for ctwm.
20 *
21 ***********************************************************************/
22
23%{
24#include "ctwm.h"
25
26#include <stdio.h>
27#include <string.h>
28#include <strings.h>
29
30#include "otp.h"
31#include "iconmgr.h"
32#include "icons.h"
33#ifdef WINBOX
34#include "windowbox.h"
35#endif
36#include "functions_defs.h"
37#include "list.h"
38#include "util.h"
39#include "occupation.h"
40#include "screen.h"
41#include "parse.h"
42#include "parse_be.h"
43#include "parse_yacc.h"
44#include "cursor.h"
45#include "win_decorations_init.h"
46#include "win_regions.h"
47#include "workspace_config.h"
48#ifdef SOUNDS
49#	include "sound.h"
50#endif
51
52static char *curWorkSpc = NULL;
53static char *client = NULL;
54static char *workspace = NULL;
55static MenuItem *lastmenuitem = NULL;
56static name_list **curplist = NULL;
57static int color = 0;
58extern char *yytext; // Have to manually pull this in
59
60int yylex(void);
61%}
62
63%union
64{
65    int num;
66    char *ptr;
67};
68
69
70%token <num> LB RB LP RP MENUS MENU BUTTON DEFAULT_FUNCTION PLUS MINUS
71%token <num> ALL OR CURSORS PIXMAPS ICONS COLOR SAVECOLOR MONOCHROME FUNCTION
72%token <num> ICONMGR_SHOW ICONMGR ALTER WINDOW_FUNCTION ZOOM ICONMGRS
73%token <num> ICONMGR_GEOMETRY ICONMGR_NOSHOW MAKE_TITLE
74%token <num> ICONIFY_BY_UNMAPPING DONT_ICONIFY_BY_UNMAPPING
75%token <num> AUTO_POPUP
76%token <num> NO_BORDER NO_ICON_TITLE NO_TITLE AUTO_RAISE NO_HILITE ICON_REGION
77%token <num> WINDOW_REGION META SHIFT LOCK CONTROL WINDOW TITLE ICON ROOT FRAME
78%token <num> COLON EQUALS SQUEEZE_TITLE DONT_SQUEEZE_TITLE
79%token <num> WARP_ON_DEICONIFY
80%token <num> START_ICONIFIED NO_TITLE_HILITE TITLE_HILITE
81%token <num> MOVE RESIZE WAITC SELECT KILL LEFT_TITLEBUTTON RIGHT_TITLEBUTTON
82%token <num> NUMBER KEYWORD NKEYWORD CKEYWORD CLKEYWORD FKEYWORD FSKEYWORD
83%token <num> FNKEYWORD PRIORITY_SWITCHING PRIORITY_NOT_SWITCHING
84%token <num> SKEYWORD SSKEYWORD WINDOW_RING WINDOW_RING_EXCLUDE WARP_CURSOR ERRORTOKEN
85%token <num> GRAVITY /* N/S/E/W */
86%token <num> SIJENUM /* SqueezeTitle justifications, SIJust enum */
87%token <num> NO_STACKMODE ALWAYS_ON_TOP WORKSPACE WORKSPACES WORKSPCMGR_GEOMETRY
88%token <num> OCCUPYALL OCCUPYLIST MAPWINDOWCURRENTWORKSPACE MAPWINDOWDEFAULTWORKSPACE
89%token <num> ON_TOP_PRIORITY
90%token <num> UNMAPBYMOVINGFARAWAY OPAQUEMOVE NOOPAQUEMOVE OPAQUERESIZE NOOPAQUERESIZE
91%token <num> DONTSETINACTIVE CHANGE_WORKSPACE_FUNCTION DEICONIFY_FUNCTION ICONIFY_FUNCTION
92%token <num> AUTOSQUEEZE STARTSQUEEZED DONT_SAVE AUTO_LOWER ICONMENU_DONTSHOW WINDOW_BOX
93%token <num> IGNOREMODIFIER WINDOW_GEOMETRIES ALWAYSSQUEEZETOGRAVITY VIRTUAL_SCREENS
94%token <num> IGNORE_TRANSIENT
95%token <num> EWMH_IGNORE
96%token <num> MWM_IGNORE
97%token <num> MONITOR_LAYOUT
98%token <num> RPLAY_SOUNDS
99%token <num> FORCE_FOCUS
100%token <ptr> STRING
101
102%type <ptr> string
103%type <num> action button number signed_number keyaction full fullkey
104%type <num> vgrav hgrav
105
106%start twmrc
107
108%%
109twmrc		: { InitGramVariables(); }
110                  stmts
111		;
112
113stmts		: /* Empty */
114		| stmts stmt
115		;
116
117stmt		: error
118		| noarg
119		| sarg
120		| narg
121		| squeeze
122		| ICON_REGION string vgrav hgrav number number {
123		      AddIconRegion($2, $3, $4, $5, $6, "undef", "undef", "undef");
124		  }
125		| ICON_REGION string vgrav hgrav number number string {
126		      AddIconRegion($2, $3, $4, $5, $6, $7, "undef", "undef");
127		  }
128		| ICON_REGION string vgrav hgrav number number string string {
129		      AddIconRegion($2, $3, $4, $5, $6, $7, $8, "undef");
130		  }
131		| ICON_REGION string vgrav hgrav number number string string string {
132		      AddIconRegion($2, $3, $4, $5, $6, $7, $8, $9);
133		  }
134		| ICON_REGION string vgrav hgrav number number {
135		      curplist = AddIconRegion($2, $3, $4, $5, $6, "undef", "undef", "undef");
136		  }
137		  win_list
138		| ICON_REGION string vgrav hgrav number number string {
139		      curplist = AddIconRegion($2, $3, $4, $5, $6, $7, "undef", "undef");
140		  }
141		  win_list
142		| ICON_REGION string vgrav hgrav number number string string {
143		      curplist = AddIconRegion($2, $3, $4, $5, $6, $7, $8, "undef");
144		  }
145		  win_list
146		| ICON_REGION string vgrav hgrav number number string string string {
147		      curplist = AddIconRegion($2, $3, $4, $5, $6, $7, $8, $9);
148		  }
149		  win_list
150
151		| WINDOW_REGION string vgrav hgrav {
152		      curplist = AddWindowRegion ($2, $3, $4);
153		  }
154		  win_list
155
156		| WINDOW_BOX string string {
157#ifdef WINBOX
158		      curplist = addWindowBox ($2, $3);
159#endif
160		  }
161		  win_list
162
163		| ICONMGR_GEOMETRY string number	{ if (Scr->FirstTime)
164						  {
165						    Scr->iconmgr->geometry= (char*)$2;
166						    Scr->iconmgr->columns=$3;
167						  }
168						}
169		| ICONMGR_GEOMETRY string	{ if (Scr->FirstTime)
170						    Scr->iconmgr->geometry = (char*)$2;
171						}
172		| WORKSPCMGR_GEOMETRY string number	{ if (Scr->FirstTime)
173				{
174				    Scr->workSpaceMgr.geometry= (char*)$2;
175				    Scr->workSpaceMgr.columns=$3;
176				}
177						}
178		| WORKSPCMGR_GEOMETRY string	{ if (Scr->FirstTime)
179				    Scr->workSpaceMgr.geometry = (char*)$2;
180						}
181		| MAPWINDOWCURRENTWORKSPACE {}
182		  curwork
183
184		| MAPWINDOWDEFAULTWORKSPACE {}
185		  defwork
186
187		| ZOOM number		{ if (Scr->FirstTime)
188					  {
189						Scr->DoZoom = true;
190						Scr->ZoomCount = $2;
191					  }
192					}
193		| ZOOM			{ if (Scr->FirstTime)
194						Scr->DoZoom = true; }
195		| PIXMAPS pixmap_list	{}
196		| CURSORS cursor_list	{}
197		| ICONIFY_BY_UNMAPPING	{ curplist = &Scr->IconifyByUn; }
198		  win_list
199		| ICONIFY_BY_UNMAPPING	{ if (Scr->FirstTime)
200		    Scr->IconifyByUnmapping = true; }
201
202		| OPAQUEMOVE	{ curplist = &Scr->OpaqueMoveList; }
203		  win_list
204		| OPAQUEMOVE	{ if (Scr->FirstTime) Scr->DoOpaqueMove = true; }
205		| NOOPAQUEMOVE	{ curplist = &Scr->NoOpaqueMoveList; }
206		  win_list
207		| NOOPAQUEMOVE	{ if (Scr->FirstTime) Scr->DoOpaqueMove = false; }
208		| OPAQUERESIZE	{ curplist = &Scr->OpaqueMoveList; }
209		  win_list
210		| OPAQUERESIZE	{ if (Scr->FirstTime) Scr->DoOpaqueResize = true; }
211		| NOOPAQUERESIZE	{ curplist = &Scr->NoOpaqueResizeList; }
212		  win_list
213		| NOOPAQUERESIZE	{ if (Scr->FirstTime) Scr->DoOpaqueResize = false; }
214
215		| LEFT_TITLEBUTTON string EQUALS action {
216					  GotTitleButton ($2, $4, false);
217					}
218		| RIGHT_TITLEBUTTON string EQUALS action {
219					  GotTitleButton ($2, $4, true);
220					}
221		| LEFT_TITLEBUTTON string { CreateTitleButton($2, 0, NULL, NULL, false, true); }
222		  binding_list
223		| RIGHT_TITLEBUTTON string { CreateTitleButton($2, 0, NULL, NULL, true, true); }
224		  binding_list
225		| button string		{
226		    root = GetRoot($2, NULL, NULL);
227		    AddFuncButton ($1, C_ROOT, 0, F_MENU, root, NULL);
228		}
229		| button action		{
230			if ($2 == F_MENU) {
231			    pull->prev = NULL;
232			    AddFuncButton ($1, C_ROOT, 0, $2, pull, NULL);
233			}
234			else {
235			    MenuItem *item;
236
237			    root = GetRoot(TWM_ROOT,NULL,NULL);
238			    item = AddToMenu (root, "x", Action,
239					NULL, $2, NULL, NULL);
240			    AddFuncButton ($1, C_ROOT, 0, $2, NULL, item);
241			}
242			Action = "";
243			pull = NULL;
244		}
245		| string fullkey	{ GotKey($1, $2); }
246		| button full		{ GotButton($1, $2); }
247
248		| DONT_ICONIFY_BY_UNMAPPING { curplist = &Scr->DontIconify; }
249		  win_list
250		| WORKSPACES {}
251		  workspc_list
252		| IGNOREMODIFIER
253			{ mods = 0; }
254			LB keys
255			{ Scr->IgnoreModifier |= mods; mods = 0; }
256			RB
257		| OCCUPYALL		{ curplist = &Scr->OccupyAll; }
258		  win_list
259		| ICONMENU_DONTSHOW	{ curplist = &Scr->IconMenuDontShow; }
260		  win_list
261		| OCCUPYLIST {}
262		  occupy_list
263		| UNMAPBYMOVINGFARAWAY	{ curplist = &Scr->UnmapByMovingFarAway; }
264		  win_list
265		| AUTOSQUEEZE		{ curplist = &Scr->AutoSqueeze; }
266		  win_list
267		| STARTSQUEEZED		{ curplist = &Scr->StartSqueezed; }
268		  win_list
269		| ALWAYSSQUEEZETOGRAVITY	{ Scr->AlwaysSqueezeToGravity = true; }
270		| ALWAYSSQUEEZETOGRAVITY	{ curplist = &Scr->AlwaysSqueezeToGravityL; }
271		  win_list
272		| DONTSETINACTIVE	{ curplist = &Scr->DontSetInactive; }
273		  win_list
274		| ICONMGR_NOSHOW	{ curplist = &Scr->IconMgrNoShow; }
275		  win_list
276		| ICONMGR_NOSHOW	{ Scr->IconManagerDontShow = true; }
277		| ICONMGRS		{ curplist = &Scr->IconMgrs; }
278		  iconm_list
279		| ICONMGR_SHOW		{ curplist = &Scr->IconMgrShow; }
280		  win_list
281		| NO_TITLE_HILITE	{ curplist = &Scr->NoTitleHighlight; }
282		  win_list
283		| NO_TITLE_HILITE	{ if (Scr->FirstTime)
284						Scr->TitleHighlight = false; }
285		| NO_HILITE		{ curplist = &Scr->NoHighlight; }
286		  win_list
287		| NO_HILITE		{ if (Scr->FirstTime)
288						Scr->Highlight = false; }
289                | ON_TOP_PRIORITY signed_number
290                                        { OtpScrSetZero(Scr, WinWin, $2); }
291		| ON_TOP_PRIORITY ICONS signed_number
292                                        { OtpScrSetZero(Scr, IconWin, $3); }
293		| ON_TOP_PRIORITY signed_number
294                                        { curplist = OtpScrPriorityL(Scr, WinWin, $2); }
295		  win_list
296		| ON_TOP_PRIORITY ICONS signed_number
297                                        { curplist = OtpScrPriorityL(Scr, IconWin, $3); }
298		  win_list
299		| ALWAYS_ON_TOP		{ curplist = OtpScrPriorityL(Scr, WinWin, 8); }
300		  win_list
301		| PRIORITY_SWITCHING	{ OtpScrSetSwitching(Scr, WinWin, false);
302		                          curplist = OtpScrSwitchingL(Scr, WinWin); }
303		  win_list
304		| PRIORITY_NOT_SWITCHING { OtpScrSetSwitching(Scr, WinWin, true);
305		                          curplist = OtpScrSwitchingL(Scr, WinWin); }
306		  win_list
307		| PRIORITY_SWITCHING ICONS
308                                        { OtpScrSetSwitching(Scr, IconWin, false);
309                                        curplist = OtpScrSwitchingL(Scr, IconWin); }
310		  win_list
311		| PRIORITY_NOT_SWITCHING ICONS
312                                        { OtpScrSetSwitching(Scr, IconWin, true);
313		                          curplist = OtpScrSwitchingL(Scr, IconWin); }
314		  win_list
315
316		  win_list
317		| NO_STACKMODE		{ curplist = &Scr->NoStackModeL; }
318		  win_list
319		| NO_STACKMODE		{ if (Scr->FirstTime)
320						Scr->StackMode = false; }
321		| NO_BORDER		{ curplist = &Scr->NoBorder; }
322		  win_list
323		| AUTO_POPUP		{ Scr->AutoPopup = true; }
324		| AUTO_POPUP		{ curplist = &Scr->AutoPopupL; }
325		  win_list
326		| DONT_SAVE		{
327#ifndef SESSION
328			twmrc_error_prefix();
329			fprintf(stderr, "DontSave ignored; session support "
330					"disabled.\n");
331#endif
332				curplist = &Scr->DontSave;
333			}
334		  win_list
335		| NO_ICON_TITLE		{ curplist = &Scr->NoIconTitle; }
336		  win_list
337		| NO_ICON_TITLE		{ if (Scr->FirstTime)
338						Scr->NoIconTitlebar = true; }
339		| NO_TITLE		{ curplist = &Scr->NoTitle; }
340		  win_list
341		| NO_TITLE		{ if (Scr->FirstTime)
342						Scr->NoTitlebar = true; }
343		| IGNORE_TRANSIENT	{ curplist = &Scr->IgnoreTransientL; }
344		  win_list
345		| MAKE_TITLE		{ curplist = &Scr->MakeTitle; }
346		  win_list
347		| START_ICONIFIED	{ curplist = &Scr->StartIconified; }
348		  win_list
349		| AUTO_RAISE		{ curplist = &Scr->AutoRaise; }
350		  win_list
351		| AUTO_RAISE		{ Scr->AutoRaiseDefault = true; }
352		| WARP_ON_DEICONIFY	{ curplist = &Scr->WarpOnDeIconify; }
353		  win_list
354		| AUTO_LOWER		{ curplist = &Scr->AutoLower; }
355		  win_list
356		| AUTO_LOWER		{ Scr->AutoLowerDefault = true; }
357		| MENU string LP string COLON string RP	{
358					root = GetRoot($2, $4, $6); }
359		  menu			{ root->real_menu = true;}
360		| MENU string		{ root = GetRoot($2, NULL, NULL); }
361		  menu			{ root->real_menu = true; }
362		| FUNCTION string	{ root = GetRoot($2, NULL, NULL); }
363		  function
364		| ICONS			{ curplist = &Scr->IconNames; }
365		  icon_list
366		| COLOR			{ color = COLOR; }
367		  color_list
368		| SAVECOLOR		{}
369		  save_color_list
370		| MONOCHROME		{ color = MONOCHROME; }
371		  color_list
372		| DEFAULT_FUNCTION action { Scr->DefaultFunction.func = $2;
373					  if ($2 == F_MENU)
374					  {
375					    pull->prev = NULL;
376					    Scr->DefaultFunction.menu = pull;
377					  }
378					  else
379					  {
380					    root = GetRoot(TWM_ROOT,NULL,NULL);
381					    Scr->DefaultFunction.item =
382						AddToMenu(root,"x",Action,
383							  NULL,$2, NULL, NULL);
384					  }
385					  Action = "";
386					  pull = NULL;
387					}
388		| WINDOW_FUNCTION action { Scr->WindowFunction.func = $2;
389					   root = GetRoot(TWM_ROOT,NULL,NULL);
390					   Scr->WindowFunction.item =
391						AddToMenu(root,"x",Action,
392							  NULL,$2, NULL, NULL);
393					   Action = "";
394					   pull = NULL;
395					}
396		| CHANGE_WORKSPACE_FUNCTION action { Scr->ChangeWorkspaceFunction.func = $2;
397					   root = GetRoot(TWM_ROOT,NULL,NULL);
398					   Scr->ChangeWorkspaceFunction.item =
399						AddToMenu(root,"x",Action,
400							  NULL,$2, NULL, NULL);
401					   Action = "";
402					   pull = NULL;
403					}
404		| DEICONIFY_FUNCTION action { Scr->DeIconifyFunction.func = $2;
405					   root = GetRoot(TWM_ROOT,NULL,NULL);
406					   Scr->DeIconifyFunction.item =
407						AddToMenu(root,"x",Action,
408							  NULL,$2, NULL, NULL);
409					   Action = "";
410					   pull = NULL;
411					}
412		| ICONIFY_FUNCTION action { Scr->IconifyFunction.func = $2;
413					   root = GetRoot(TWM_ROOT,NULL,NULL);
414					   Scr->IconifyFunction.item =
415						AddToMenu(root,"x",Action,
416							  NULL,$2, NULL, NULL);
417					   Action = "";
418					   pull = NULL;
419					}
420		| WARP_CURSOR		{ curplist = &Scr->WarpCursorL; }
421		  win_list
422		| WARP_CURSOR		{ if (Scr->FirstTime)
423					    Scr->WarpCursor = true; }
424		| WINDOW_RING		{ curplist = &Scr->WindowRingL; }
425		  win_list
426		| WINDOW_RING		{ Scr->WindowRingAll = true; }
427		| WINDOW_RING_EXCLUDE	{ if (!Scr->WindowRingL)
428					    Scr->WindowRingAll = true;
429					  curplist = &Scr->WindowRingExcludeL; }
430		  win_list
431		| WINDOW_GEOMETRIES	{  }
432		  wingeom_list
433		| VIRTUAL_SCREENS	{ }
434		  vscreen_geom_list
435		| EWMH_IGNORE		{ }
436		  ewmh_ignore_list
437		| MWM_IGNORE		{ }
438		  mwm_ignore_list
439		| MONITOR_LAYOUT { init_layout_override(); }
440			layout_geom_list
441		| RPLAY_SOUNDS { }
442		  rplay_sounds_list
443		| FORCE_FOCUS { Scr->ForceFocus = true; }
444		| FORCE_FOCUS { curplist = &Scr->ForceFocusL; }
445		  win_list
446		;
447
448noarg		: KEYWORD		{ if (!do_single_keyword ($1)) {
449					    twmrc_error_prefix();
450					    fprintf (stderr,
451					"unknown singleton keyword %d\n",
452						     $1);
453					    ParseError = true;
454					  }
455					}
456		;
457
458sarg		: SKEYWORD string	{ if (!do_string_keyword ($1, $2)) {
459					    twmrc_error_prefix();
460					    fprintf (stderr,
461				"unknown string keyword %d (value \"%s\")\n",
462						     $1, $2);
463					    ParseError = true;
464					  }
465					}
466		| SKEYWORD		{ if (!do_string_keyword ($1, DEFSTRING)) {
467					    twmrc_error_prefix();
468					    fprintf (stderr,
469				"unknown string keyword %d (no value)\n",
470						     $1);
471					    ParseError = true;
472					  }
473					}
474		;
475
476sarg		: SSKEYWORD string string
477					{ if (!do_string_string_keyword ($1, $2, $3)) {
478					    twmrc_error_prefix();
479					    fprintf (stderr,
480				"unknown strings keyword %d (value \"%s\" and \"%s\")\n",
481						     $1, $2, $3);
482					    ParseError = true;
483					  }
484					}
485		| SSKEYWORD string	{ if (!do_string_string_keyword ($1, $2, NULL)) {
486					    twmrc_error_prefix();
487					    fprintf (stderr,
488				"unknown string keyword %d (value \"%s\")\n",
489						     $1, $2);
490					    ParseError = true;
491					  }
492					}
493		| SSKEYWORD		{ if (!do_string_string_keyword ($1, NULL, NULL)) {
494					    twmrc_error_prefix();
495					    fprintf (stderr,
496				"unknown string keyword %d (no value)\n",
497						     $1);
498					    ParseError = true;
499					  }
500					}
501		;
502
503narg		: NKEYWORD number	{ if (!do_number_keyword ($1, $2)) {
504					    twmrc_error_prefix();
505					    fprintf (stderr,
506				"unknown numeric keyword %d (value %d)\n",
507						     $1, $2);
508					    ParseError = true;
509					  }
510					}
511		;
512
513
514
515keyaction	: EQUALS keys COLON action  { $$ = $4; }
516		;
517
518full		: EQUALS keys COLON contexts COLON action  { $$ = $6; }
519		;
520
521fullkey		: EQUALS keys COLON contextkeys COLON action  { $$ = $6; }
522		;
523
524keys		: /* Empty */
525		| keys key
526		;
527
528key		: META			{ mods |= Mod1Mask; }
529		| SHIFT			{ mods |= ShiftMask; }
530		| LOCK			{ mods |= LockMask; }
531		| CONTROL		{ mods |= ControlMask; }
532		| ALTER number		{ if ($2 < 1 || $2 > 5) {
533					     twmrc_error_prefix();
534					     fprintf (stderr,
535				"bad altkeymap number (%d), must be 1-5\n",
536						      $2);
537					     ParseError = true;
538					  } else {
539					     mods |= (Alt1Mask << ($2 - 1));
540					  }
541					}
542		| META number		{ if ($2 < 1 || $2 > 5) {
543					     twmrc_error_prefix();
544					     fprintf (stderr,
545				"bad modifier number (%d), must be 1-5\n",
546						      $2);
547					     ParseError = true;
548					  } else {
549					     mods |= (Mod1Mask << ($2 - 1));
550					  }
551					}
552		| OR			{ }
553		;
554
555vgrav	: GRAVITY {
556			switch($1) {
557				case GRAV_NORTH:
558				case GRAV_SOUTH:
559					/* OK */
560					$$ = $1;
561					break;
562				default:
563					twmrc_error_prefix();
564					fprintf(stderr, "Bad vertical gravity '%s'\n", yytext);
565					ParseError = true;
566					YYERROR;
567			}
568		}
569
570hgrav	: GRAVITY {
571			switch($1) {
572				case GRAV_EAST:
573				case GRAV_WEST:
574					/* OK */
575					$$ = $1;
576					break;
577				default:
578					twmrc_error_prefix();
579					fprintf(stderr, "Bad horiz gravity '%s'\n", yytext);
580					ParseError = true;
581					YYERROR;
582			}
583		}
584
585contexts	: /* Empty */
586		| contexts context
587		;
588
589context		: WINDOW		{ cont |= C_WINDOW_BIT; }
590		| TITLE			{ cont |= C_TITLE_BIT; }
591		| ICON			{ cont |= C_ICON_BIT; }
592		| ROOT			{ cont |= C_ROOT_BIT; }
593		| FRAME			{ cont |= C_FRAME_BIT; }
594		| WORKSPACE		{ cont |= C_WORKSPACE_BIT; }
595		| ICONMGR		{ cont |= C_ICONMGR_BIT; }
596		| META			{ cont |= C_ICONMGR_BIT; }
597		| ALTER			{ cont |= C_ALTER_BIT; }
598		| ALL			{ cont |= C_ALL_BITS; }
599		| OR			{ }
600		;
601
602contextkeys	: /* Empty */
603		| contextkeys contextkey
604		;
605
606contextkey	: WINDOW		{ cont |= C_WINDOW_BIT; }
607		| TITLE			{ cont |= C_TITLE_BIT; }
608		| ICON			{ cont |= C_ICON_BIT; }
609		| ROOT			{ cont |= C_ROOT_BIT; }
610		| FRAME			{ cont |= C_FRAME_BIT; }
611		| WORKSPACE		{ cont |= C_WORKSPACE_BIT; }
612		| ICONMGR		{ cont |= C_ICONMGR_BIT; }
613		| META			{ cont |= C_ICONMGR_BIT; }
614		| ALTER			{ cont |= C_ALTER_BIT; }
615		| ALL			{ cont |= C_ALL_BITS; }
616		| OR			{ }
617		| string		{ Name = (char*)$1; cont |= C_NAME_BIT; }
618		;
619
620
621binding_list    : LB binding_entries RB {}
622		;
623
624binding_entries : /* Empty */
625		| binding_entries binding_entry
626		;
627
628binding_entry   : button keyaction { SetCurrentTBAction($1, mods, $2, Action, pull); mods = 0;}
629		| button EQUALS action { SetCurrentTBAction($1, 0, $3, Action, pull);}
630		| button COLON action {
631			/* Deprecated since 3.8, no longer supported */
632			yyerror("Title buttons specifications without = are no "
633			        "longer supported.");
634		}
635		;
636
637
638pixmap_list	: LB pixmap_entries RB {}
639		;
640
641pixmap_entries	: /* Empty */
642		| pixmap_entries pixmap_entry
643		;
644
645pixmap_entry	: TITLE_HILITE string { Scr->HighlightPixmapName = strdup($2); }
646		;
647
648
649cursor_list	: LB cursor_entries RB {}
650		;
651
652cursor_entries	: /* Empty */
653		| cursor_entries cursor_entry
654		;
655
656cursor_entry	: FRAME string string {
657			NewBitmapCursor(&Scr->FrameCursor, $2, $3); }
658		| FRAME string	{
659			NewFontCursor(&Scr->FrameCursor, $2); }
660		| TITLE string string {
661			NewBitmapCursor(&Scr->TitleCursor, $2, $3); }
662		| TITLE string {
663			NewFontCursor(&Scr->TitleCursor, $2); }
664		| ICON string string {
665			NewBitmapCursor(&Scr->IconCursor, $2, $3); }
666		| ICON string {
667			NewFontCursor(&Scr->IconCursor, $2); }
668		| ICONMGR string string {
669			NewBitmapCursor(&Scr->IconMgrCursor, $2, $3); }
670		| ICONMGR string {
671			NewFontCursor(&Scr->IconMgrCursor, $2); }
672		| BUTTON string string {
673			NewBitmapCursor(&Scr->ButtonCursor, $2, $3); }
674		| BUTTON string {
675			NewFontCursor(&Scr->ButtonCursor, $2); }
676		| MOVE string string {
677			NewBitmapCursor(&Scr->MoveCursor, $2, $3); }
678		| MOVE string {
679			NewFontCursor(&Scr->MoveCursor, $2); }
680		| RESIZE string string {
681			NewBitmapCursor(&Scr->ResizeCursor, $2, $3); }
682		| RESIZE string {
683			NewFontCursor(&Scr->ResizeCursor, $2); }
684		| WAITC string string {
685			NewBitmapCursor(&Scr->WaitCursor, $2, $3); }
686		| WAITC string {
687			NewFontCursor(&Scr->WaitCursor, $2); }
688		| MENU string string {
689			NewBitmapCursor(&Scr->MenuCursor, $2, $3); }
690		| MENU string {
691			NewFontCursor(&Scr->MenuCursor, $2); }
692		| SELECT string string {
693			NewBitmapCursor(&Scr->SelectCursor, $2, $3); }
694		| SELECT string {
695			NewFontCursor(&Scr->SelectCursor, $2); }
696		| KILL string string {
697			NewBitmapCursor(&Scr->DestroyCursor, $2, $3); }
698		| KILL string {
699			NewFontCursor(&Scr->DestroyCursor, $2); }
700		;
701
702color_list	: LB color_entries RB {}
703		;
704
705
706color_entries	: /* Empty */
707		| color_entries color_entry
708		;
709
710color_entry	: CLKEYWORD string	{ if (!do_colorlist_keyword ($1, color,
711								     $2)) {
712					    twmrc_error_prefix();
713					    fprintf (stderr,
714			"unhandled list color keyword %d (string \"%s\")\n",
715						     $1, $2);
716					    ParseError = true;
717					  }
718					}
719		| CLKEYWORD string	{ curplist = do_colorlist_keyword($1,color,
720								      $2);
721					  if (!curplist) {
722					    twmrc_error_prefix();
723					    fprintf (stderr,
724			"unhandled color list keyword %d (string \"%s\")\n",
725						     $1, $2);
726					    ParseError = true;
727					  }
728					}
729		  win_color_list
730		| CKEYWORD string	{ if (!do_color_keyword ($1, color,
731								 $2)) {
732					    twmrc_error_prefix();
733					    fprintf (stderr,
734			"unhandled color keyword %d (string \"%s\")\n",
735						     $1, $2);
736					    ParseError = true;
737					  }
738					}
739		;
740
741save_color_list : LB s_color_entries RB {}
742		;
743
744s_color_entries : /* Empty */
745		| s_color_entries s_color_entry
746		;
747
748s_color_entry   : string		{ do_string_savecolor(color, $1); }
749		| CLKEYWORD		{ do_var_savecolor($1); }
750		;
751
752win_color_list	: LB win_color_entries RB {}
753		;
754
755win_color_entries	: /* Empty */
756		| win_color_entries win_color_entry
757		;
758
759win_color_entry	: string string		{ if (Scr->FirstTime &&
760					      color == Scr->Monochrome)
761					    AddToList(curplist, $1, $2); }
762		;
763
764wingeom_list	: LB wingeom_entries RB {}
765		;
766
767wingeom_entries	: /* Empty */
768		| wingeom_entries wingeom_entry
769		;
770/* added a ';' after call to AddToList */
771wingeom_entry	: string string	{ AddToList (&Scr->WindowGeometries, $1, $2); }
772		;
773
774vscreen_geom_list	: LB vscreen_geom_entries RB {}
775		;
776
777vscreen_geom_entries	: /* Empty */
778		| vscreen_geom_entries vscreen_geom_entry
779		;
780
781vscreen_geom_entry	: string {
782#ifdef VSCREEN
783				   AddToList (&Scr->VirtualScreens, $1, "");
784#endif
785				   }
786		;
787
788
789ewmh_ignore_list	: LB ewmh_ignore_entries RB { proc_ewmh_ignore(); }
790		;
791
792ewmh_ignore_entries	: /* Empty */
793		| ewmh_ignore_entries ewmh_ignore_entry
794		;
795
796ewmh_ignore_entry	: string { add_ewmh_ignore($1); }
797		;
798
799
800mwm_ignore_list	: LB mwm_ignore_entries RB { proc_mwm_ignore(); }
801		;
802
803mwm_ignore_entries	: /* Empty */
804		| mwm_ignore_entries mwm_ignore_entry
805		;
806
807mwm_ignore_entry	: string { add_mwm_ignore($1); }
808		;
809
810
811layout_geom_list	: LB layout_geom_entries RB { proc_layout_override(); }
812		;
813
814layout_geom_entries	: /* Empty */
815		| layout_geom_entries layout_geom_entry
816		;
817
818layout_geom_entry	: string { add_layout_override_entry($1); }
819		;
820
821
822squeeze		: SQUEEZE_TITLE {
823				    if (HasShape) Scr->SqueezeTitle = true;
824				}
825		| SQUEEZE_TITLE { curplist = &Scr->SqueezeTitleL;
826				  if (HasShape)
827				    Scr->SqueezeTitle = true;
828				}
829		  LB win_sqz_entries RB
830		| DONT_SQUEEZE_TITLE { Scr->SqueezeTitle = false; }
831		| DONT_SQUEEZE_TITLE { curplist = &Scr->DontSqueezeTitleL; }
832		  win_list
833		;
834
835win_sqz_entries	: /* Empty */
836		| win_sqz_entries string SIJENUM signed_number number	{
837				if (Scr->FirstTime) {
838				   do_squeeze_entry (curplist, $2, $3, $4, $5);
839				}
840			}
841		;
842
843
844iconm_list	: LB iconm_entries RB {}
845		;
846
847iconm_entries	: /* Empty */
848		| iconm_entries iconm_entry
849		;
850
851iconm_entry	: string string number	{ if (Scr->FirstTime)
852					    AddToList(curplist, $1,
853						AllocateIconManager($1, NULL,
854							$2,$3));
855					}
856		| string string string number
857					{ if (Scr->FirstTime)
858					    AddToList(curplist, $1,
859						AllocateIconManager($1,$2,
860						$3, $4));
861					}
862		;
863
864workspc_list	: LB workspc_entries RB {}
865		;
866
867workspc_entries	: /* Empty */
868		| workspc_entries workspc_entry
869		;
870
871workspc_entry	: string	{
872			AddWorkSpace ($1, NULL, NULL, NULL, NULL, NULL);
873		}
874		| string	{
875			curWorkSpc = (char*)$1;
876		}
877		workapp_list
878		;
879
880workapp_list	: LB workapp_entries RB {}
881		;
882
883workapp_entries	: /* Empty */
884		| workapp_entries workapp_entry
885		;
886
887workapp_entry	: string		{
888			AddWorkSpace (curWorkSpc, $1, NULL, NULL, NULL, NULL);
889		}
890		| string string		{
891			AddWorkSpace (curWorkSpc, $1, $2, NULL, NULL, NULL);
892		}
893		| string string string	{
894			AddWorkSpace (curWorkSpc, $1, $2, $3, NULL, NULL);
895		}
896		| string string string string	{
897			AddWorkSpace (curWorkSpc, $1, $2, $3, $4, NULL);
898		}
899		| string string string string string	{
900			AddWorkSpace (curWorkSpc, $1, $2, $3, $4, $5);
901		}
902		;
903
904curwork		: LB string RB {
905		    WMapCreateCurrentBackGround ($2, NULL, NULL, NULL);
906		}
907		| LB string string RB {
908		    WMapCreateCurrentBackGround ($2, $3, NULL, NULL);
909		}
910		| LB string string string RB {
911		    WMapCreateCurrentBackGround ($2, $3, $4, NULL);
912		}
913		| LB string string string string RB {
914		    WMapCreateCurrentBackGround ($2, $3, $4, $5);
915		}
916		;
917
918defwork		: LB string RB {
919		    WMapCreateDefaultBackGround ($2, NULL, NULL, NULL);
920		}
921		| LB string string RB {
922		    WMapCreateDefaultBackGround ($2, $3, NULL, NULL);
923		}
924		| LB string string string RB {
925		    WMapCreateDefaultBackGround ($2, $3, $4, NULL);
926		}
927		| LB string string string string RB {
928		    WMapCreateDefaultBackGround ($2, $3, $4, $5);
929		}
930		;
931
932win_list	: LB win_entries RB {}
933		;
934
935win_entries	: /* Empty */
936		| win_entries win_entry
937		;
938
939win_entry	: string		{ if (Scr->FirstTime)
940					    AddToList(curplist, $1, 0);
941					}
942		;
943
944occupy_list	: LB occupy_entries RB {}
945		;
946
947occupy_entries	:  /* Empty */
948		| occupy_entries occupy_entry
949		;
950
951occupy_entry	: string {client = (char*)$1;}
952		  occupy_workspc_list
953		| WINDOW    string {client = (char*)$2;}
954		  occupy_workspc_list
955		| WORKSPACE string {workspace = (char*)$2;}
956		  occupy_window_list
957		;
958
959occupy_workspc_list	: LB occupy_workspc_entries RB {}
960			;
961
962occupy_workspc_entries	:   /* Empty */
963			| occupy_workspc_entries occupy_workspc_entry
964			;
965
966occupy_workspc_entry	: string {
967				if(!AddToClientsList ($1, client)) {
968					twmrc_error_prefix();
969					fprintf(stderr, "unknown workspace '%s'\n", $1);
970				}
971			  }
972			;
973
974occupy_window_list	: LB occupy_window_entries RB {}
975			;
976
977occupy_window_entries	:   /* Empty */
978			| occupy_window_entries occupy_window_entry
979			;
980
981occupy_window_entry	: string {
982				if(!AddToClientsList (workspace, $1)) {
983					twmrc_error_prefix();
984					fprintf(stderr, "unknown workspace '%s'\n", workspace);
985				}
986			  }
987			;
988
989icon_list	: LB icon_entries RB {}
990		;
991
992icon_entries	: /* Empty */
993		| icon_entries icon_entry
994		;
995
996icon_entry	: string string		{ if (Scr->FirstTime) AddToList(curplist, $1, $2); }
997		;
998
999rplay_sounds_list	: LB rplay_sounds_entries RB {
1000#ifndef SOUNDS
1001			twmrc_error_prefix();
1002			fprintf(stderr, "RplaySounds ignored; rplay support "
1003					"not configured.\n");
1004#else
1005			sound_set_from_config();
1006#endif
1007		}
1008		;
1009
1010rplay_sounds_entries	: /* Empty */
1011		| rplay_sounds_entries rplay_sounds_entry
1012		;
1013
1014rplay_sounds_entry	: string string {
1015#ifdef SOUNDS
1016			if(set_sound_event_name($1, $2) != 0) {
1017				twmrc_error_prefix();
1018				fprintf(stderr, "Failed adding sound for %s; "
1019						"maybe event name is invalid?\n", $1);
1020			}
1021#endif
1022		}
1023		;
1024
1025function	: LB function_entries RB {}
1026		;
1027
1028function_entries: /* Empty */
1029		| function_entries function_entry
1030		;
1031
1032function_entry	: action		{ AddToMenu(root, "", Action, NULL, $1,
1033						    NULL, NULL);
1034					  Action = "";
1035					}
1036		;
1037
1038menu		: LB menu_entries RB {lastmenuitem = NULL;}
1039		;
1040
1041menu_entries	: /* Empty */
1042		| menu_entries menu_entry
1043		;
1044
1045menu_entry	: string action		{
1046			if ($2 == F_SEPARATOR) {
1047			    if (lastmenuitem) lastmenuitem->separated = true;
1048			}
1049			else {
1050			    lastmenuitem = AddToMenu(root, $1, Action, pull, $2, NULL, NULL);
1051			    Action = "";
1052			    pull = NULL;
1053			}
1054		}
1055		| string LP string COLON string RP action {
1056			if ($7 == F_SEPARATOR) {
1057			    if (lastmenuitem) lastmenuitem->separated = true;
1058			}
1059			else {
1060			    lastmenuitem = AddToMenu(root, $1, Action, pull, $7, $3, $5);
1061			    Action = "";
1062			    pull = NULL;
1063			}
1064		}
1065		;
1066
1067action		: FKEYWORD	{ $$ = $1; }
1068		| FSKEYWORD string {
1069				$$ = $1;
1070				Action = (char*)$2;
1071				switch ($1) {
1072				  case F_MENU:
1073				    pull = GetRoot ($2, NULL,NULL);
1074				    pull->prev = root;
1075				    break;
1076				  case F_WARPRING:
1077				    if (!CheckWarpRingArg (Action)) {
1078					twmrc_error_prefix();
1079					fprintf (stderr,
1080			"ignoring invalid f.warptoring argument \"%s\"\n",
1081						 Action);
1082					$$ = F_NOP;
1083				    }
1084				    break;
1085				  case F_WARPTOSCREEN:
1086				    if (!CheckWarpScreenArg (Action)) {
1087					twmrc_error_prefix();
1088					fprintf (stderr,
1089			"ignoring invalid f.warptoscreen argument \"%s\"\n",
1090						 Action);
1091					$$ = F_NOP;
1092				    }
1093				    break;
1094				  case F_COLORMAP:
1095				    if (CheckColormapArg (Action)) {
1096					$$ = F_COLORMAP;
1097				    } else {
1098					twmrc_error_prefix();
1099					fprintf (stderr,
1100			"ignoring invalid f.colormap argument \"%s\"\n",
1101						 Action);
1102					$$ = F_NOP;
1103				    }
1104				    break;
1105				} /* end switch */
1106				   }
1107		;
1108
1109
1110signed_number	: number		{ $$ = $1; }
1111		| PLUS number		{ $$ = $2; }
1112		| MINUS number		{ $$ = -($2); }
1113		;
1114
1115button		: BUTTON number		{ $$ = $2;
1116					  if ($2 == 0)
1117						yyerror("bad button 0");
1118
1119					  if ($2 > MAX_BUTTONS)
1120					  {
1121						$$ = 0;
1122						yyerror("button number too large");
1123					  }
1124					}
1125		;
1126
1127string		: STRING		{ char *ptr = strdup($1);
1128					  RemoveDQuote(ptr);
1129					  $$ = ptr;
1130					}
1131		;
1132
1133number		: NUMBER		{ $$ = $1; }
1134		;
1135
1136%%
1137