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: gram.y,v 1.88 90/03/16 12:12:06 jim Exp $
32  *
33  * .twmrc command grammer
34  *
35  * 07-Jan-86 Thomas E. LaStrange	File created
36  *
37  ***********************************************************************/
38 
39 %{
40 #include <stdio.h>
41 #include <ctype.h>
42 #include "twm.h"
43 #include "menus.h"
44 #include "list.h"
45 #include "util.h"
46 #include "screen.h"
47 #include "parse.h"
48 #include <X11/Xos.h>
49 #include <X11/Xmu/CharSet.h>
50 
51 #define PI 3.1415926535897932
52 #define TWO_PI 6.2831853071795865
53 #define DEG_TO_RAD(d) (((float)(d) * TWO_PI) / 360.0)
54 
55 static char *Action = "";
56 static char *Name = "";
57 static MenuRoot	*root, *pull = NULL;
58 
59 static MenuRoot *GetRoot();
60 
61 static Bool CheckWarpScreenArg(), CheckWarpRingArg();
62 static Bool CheckColormapArg();
63 static void GotButton(), GotKey(), GotTitleButton();
64 static char *ptr;
65 static name_list **list;
66 static int cont = 0;
67 static int color;
68 int mods = 0;
69 unsigned int mods_used = (ShiftMask | ControlMask | Mod1Mask);
70 
71 extern int do_single_keyword(), do_string_keyword(), do_number_keyword();
72 extern name_list **do_colorlist_keyword();
73 extern int do_color_keyword();
74 extern int yylineno;
75 %}
76 
77 %union
78 {
79     int num;
80     char *ptr;
81 };
82 
83 %token <num> LB RB LP RP AT MENUS MENU PIEMENU BUTTON DEFAULT_FUNCTION
84 %token <num> PLUS MINUS ALL OR CURSORS PIXMAPS ICONS COLOR MONOCHROME FUNCTION
85 %token <num> ICONMGR_SHOW ICONMGR WINDOW_FUNCTION ZOOM ICONMGRS
86 %token <num> ICONMGR_GEOMETRY ICONMGR_NOSHOW MAKE_TITLE
87 %token <num> ICONIFY_BY_UNMAPPING DONT_ICONIFY_BY_UNMAPPING STICKY
88 %token <num> NO_TITLE AUTO_RAISE NO_HILITE ICON_REGION
89 %token <num> META SHIFT LOCK CONTROL WINDOW TITLE ICON ROOT FRAME
90 %token <num> COLON EQUALS SQUEEZE_TITLE DONT_SQUEEZE_TITLE
91 %token <num> START_ICONIFIED NO_TITLE_HILITE TITLE_HILITE
92 %token <num> MOVE RESIZE WAIT SELECT KILL LEFT_TITLEBUTTON RIGHT_TITLEBUTTON
93 %token <num> NUMBER KEYWORD NKEYWORD CKEYWORD CLKEYWORD FKEYWORD FSKEYWORD
94 %token <num> SKEYWORD DKEYWORD JKEYWORD PKEYWORD WINDOW_RING WARP_CURSOR ERRORTOKEN
95 %token <num> NO_STACKMODE ICON_TITLE NO_ICON_TITLE
96 %token <ptr> STRING
97 
98 %type <ptr> string
99 %type <num> action button number signed_number full fullkey
100 
101 %start twmrc
102 
103 %%
104 twmrc		: stmts
105 		;
106 
107 stmts		: /* Empty */
108 		| stmts stmt
109 		;
110 
111 stmt		: error
112 		| noarg
113 		| sarg
114 		| narg
115 		| squeeze
116 		| ICON_REGION string DKEYWORD DKEYWORD number number
117 					{ AddIconRegion($2, $3, $4, $5, $6); }
118 		| ICONMGR_GEOMETRY string number	{ if (Scr->FirstTime)
119 						  {
120 						    Scr->iconmgr.geometry=$2;
121 						    Scr->iconmgr.columns=$3;
122 						  }
123 						}
124 		| ICONMGR_GEOMETRY string	{ if (Scr->FirstTime)
125 						    Scr->iconmgr.geometry = $2;
126 						}
127 		| ZOOM number		{ if (Scr->FirstTime)
128 					  {
129 						Scr->DoZoom = TRUE;
130 						Scr->ZoomCount = $2;
131 					  }
132 					}
133 		| ZOOM			{ if (Scr->FirstTime)
134 						Scr->DoZoom = TRUE; }
135 		| PIXMAPS pixmap_list	{}
136 		| CURSORS cursor_list	{}
137 		| ICONIFY_BY_UNMAPPING	{ list = &Scr->IconifyByUn; }
138 		  win_list
139 		| ICONIFY_BY_UNMAPPING	{ if (Scr->FirstTime)
140 		    Scr->IconifyByUnmapping = TRUE; }
141 		| LEFT_TITLEBUTTON string EQUALS action {
142 					  GotTitleButton ($2, $4, False);
143 					}
144 		| RIGHT_TITLEBUTTON string EQUALS action {
145 					  GotTitleButton ($2, $4, True);
146 					}
147 		| button string		{ root = GetRoot($2, NULLSTR, NULLSTR);
148 					  Scr->Mouse[$1][C_ROOT][0].func = F_MENU;
149 					  Scr->Mouse[$1][C_ROOT][0].menu = root;
150 					}
151 		| button action		{ Scr->Mouse[$1][C_ROOT][0].func = $2;
152 					  if ($2 == F_MENU || $2 == F_PIEMENU)
153 					  {
154 					    pull->prev = NULL;
155 					    Scr->Mouse[$1][C_ROOT][0].menu = pull;
156 					  }
157 					  else
158 					  {
159 					    root = GetRoot(TWM_ROOT,NULLSTR,NULLSTR);
160 					    Scr->Mouse[$1][C_ROOT][0].item =
161 						AddToMenu(root,"x",Action,
162 							  NULL,$2,NULLSTR,NULLSTR);
163 					  }
164 					  Action = "";
165 					  pull = NULL;
166 					}
167 		| string fullkey	{ GotKey($1, $2); }
168 		| button full		{ GotButton($1, $2); }
169 		| DONT_ICONIFY_BY_UNMAPPING { list = &Scr->DontIconify; }
170 		  win_list
171 		| ICONMGR_NOSHOW	{ list = &Scr->IconMgrNoShow; }
172 		  win_list
173 		| ICONMGR_NOSHOW	{ Scr->IconManagerDontShow = TRUE; }
174 		| ICONMGRS		{ list = &Scr->IconMgrs; }
175 		  iconm_list
176 		| ICONMGR_SHOW		{ list = &Scr->IconMgrShow; }
177 		  win_list
178 		| NO_TITLE_HILITE	{ list = &Scr->NoTitleHighlight; }
179 		  win_list
180 		| NO_TITLE_HILITE	{ if (Scr->FirstTime)
181 						Scr->TitleHighlight = FALSE; }
182 		| NO_HILITE		{ list = &Scr->NoHighlight; }
183 		  win_list
184 		| NO_HILITE		{ if (Scr->FirstTime)
185 						Scr->Highlight = FALSE; }
186 		| NO_STACKMODE		{ list = &Scr->NoStackModeL; }
187 		  win_list
188 		| NO_STACKMODE		{ if (Scr->FirstTime)
189 						Scr->StackMode = FALSE; }
190 		| NO_TITLE		{ list = &Scr->NoTitle; }
191 		  win_list
192 		| NO_TITLE		{ if (Scr->FirstTime)
193 						Scr->NoTitlebar = TRUE; }
194 		| NO_ICON_TITLE		{ list = &Scr->NoIconTitleL; }
195 		  win_list
196 		| NO_ICON_TITLE		{ if (Scr->FirstTime)
197 						Scr->NoIconTitle = TRUE; }
198 		| ICON_TITLE		{ list = &Scr->IconTitleL; }
199 		  win_list
200 		| MAKE_TITLE		{ list = &Scr->MakeTitle; }
201 		  win_list
202 		| START_ICONIFIED	{ list = &Scr->StartIconified; }
203 		  win_list
204 		| AUTO_RAISE		{ list = &Scr->AutoRaise; }
205 		  win_list
206 		| STICKY		{ list = &Scr->StickyL; }
207 		  win_list
208 		| MENU string LP string COLON string RP
209 					{ root = GetRoot($2, $4, $6); }
210 		  menu			{ root->real_menu = TRUE;}
211 		| MENU string 		{ root = GetRoot($2, NULLSTR, NULLSTR); }
212 		  menu			{ root->real_menu = TRUE; }
213 		| PIEMENU string LP string COLON string RP
214 					{ root = GetRoot($2, $4, $6);
215 					  root->pie_menu = 1; }
216 		  menu			{ root->real_menu = TRUE;}
217 		| PIEMENU string	{ root = GetRoot($2, NULLSTR, NULLSTR);
218 					  root->pie_menu = 1; }
219 		  menu			{ root->real_menu = TRUE; }
220 		| PIEMENU string LP string COLON string RP AT number
221 					{ root = GetRoot($2, $4, $6);
222 					  root->pie_menu = 1;
223 					  root->initial_angle = DEG_TO_RAD($9); }
224 		  menu			{ root->real_menu = TRUE;}
225 		| PIEMENU string AT number
226 					{ root = GetRoot($2, NULLSTR, NULLSTR);
227 					  root->pie_menu = 1;
228 					  root->initial_angle = DEG_TO_RAD($4); }
229 		  menu			{ root->real_menu = TRUE; }
230 		| FUNCTION string	{ root = GetRoot($2, NULLSTR, NULLSTR); }
231 		  function
232 		| ICONS 		{ list = &Scr->IconNames; }
233 		  icon_list
234 		| COLOR 		{ color = COLOR; }
235 		  color_list
236 		| MONOCHROME 		{ color = MONOCHROME; }
237 		  color_list
238 		| DEFAULT_FUNCTION action { Scr->DefaultFunction.func = $2;
239 					  if ($2 == F_MENU || $2 == F_PIEMENU)
240 					  {
241 					    pull->prev = NULL;
242 					    Scr->DefaultFunction.menu = pull;
243 					  }
244 					  else
245 					  {
246 					    root = GetRoot(TWM_ROOT,NULLSTR,NULLSTR);
247 					    Scr->DefaultFunction.item =
248 						AddToMenu(root,"x",Action,
249 							  NULL,$2, NULLSTR, NULLSTR);
250 					  }
251 					  Action = "";
252 					  pull = NULL;
253 					}
254 		| WINDOW_FUNCTION action { Scr->WindowFunction.func = $2;
255 					   root = GetRoot(TWM_ROOT,NULLSTR,NULLSTR);
256 					   Scr->WindowFunction.item =
257 						AddToMenu(root,"x",Action,
258 							  NULL,$2, NULLSTR, NULLSTR);
259 					   Action = "";
260 					   pull = NULL;
261 					}
262 		| WARP_CURSOR		{ list = &Scr->WarpCursorL; }
263 		  win_list
264 		| WARP_CURSOR		{ if (Scr->FirstTime)
265 					    Scr->WarpCursor = TRUE; }
266 		| WINDOW_RING		{ list = &Scr->WindowRingL; }
267 		  win_list
268 		;
269 
270 
271 noarg		: KEYWORD		{ if (!do_single_keyword ($1)) {
272 					    twmrc_error_prefix();
273 					    fprintf (stderr,
274 					"unknown singleton keyword %d\n",
275 						     $1);
276 					    ParseError = 1;
277 					  }
278 					}
279 		;
280 
281 sarg		: SKEYWORD string	{ if (!do_string_keyword ($1, $2)) {
282 					    twmrc_error_prefix();
283 					    fprintf (stderr,
284 				"unknown string keyword %d (value \"%s\")\n",
285 						     $1, $2);
286 					    ParseError = 1;
287 					  }
288 					}
289 		;
290 
291 narg		: NKEYWORD number	{ if (!do_number_keyword ($1, $2)) {
292 					    twmrc_error_prefix();
293 					    fprintf (stderr,
294 				"unknown numeric keyword %d (value %d)\n",
295 						     $1, $2);
296 					    ParseError = 1;
297 					  }
298 					}
299 		;
300 
301 
302 
303 full		: EQUALS keys COLON contexts COLON action  { $$ = $6; }
304 		;
305 
306 fullkey		: EQUALS keys COLON contextkeys COLON action  { $$ = $6; }
307 		;
308 
309 keys		: /* Empty */
310 		| keys key
311 		;
312 
313 key		: META			{ mods |= Mod1Mask; }
314 		| SHIFT			{ mods |= ShiftMask; }
315 		| LOCK			{ mods |= LockMask; }
316 		| CONTROL		{ mods |= ControlMask; }
317 		| META number		{ if ($2 < 1 || $2 > 5) {
318 					     twmrc_error_prefix();
319 					     fprintf (stderr,
320 				"bad modifier number (%d), must be 1-5\n",
321 						      $2);
322 					     ParseError = 1;
323 					  } else {
324 					     mods |= (Mod1Mask << ($2 - 1));
325 					  }
326 					}
327 		| OR			{ }
328 		;
329 
330 contexts	: /* Empty */
331 		| contexts context
332 		;
333 
334 context		: WINDOW		{ cont |= C_WINDOW_BIT; }
335 		| TITLE			{ cont |= C_TITLE_BIT; }
336 		| ICON			{ cont |= C_ICON_BIT; }
337 		| ROOT			{ cont |= C_ROOT_BIT; }
338 		| FRAME			{ cont |= C_FRAME_BIT; }
339 		| ICONMGR		{ cont |= C_ICONMGR_BIT; }
340 		| META			{ cont |= C_ICONMGR_BIT; }
341 		| ALL			{ cont |= C_ALL_BITS; }
342 		| OR			{  }
343 		;
344 
345 contextkeys	: /* Empty */
346 		| contextkeys contextkey
347 		;
348 
349 contextkey	: WINDOW		{ cont |= C_WINDOW_BIT; }
350 		| TITLE			{ cont |= C_TITLE_BIT; }
351 		| ICON			{ cont |= C_ICON_BIT; }
352 		| ROOT			{ cont |= C_ROOT_BIT; }
353 		| FRAME			{ cont |= C_FRAME_BIT; }
354 		| ICONMGR		{ cont |= C_ICONMGR_BIT; }
355 		| META			{ cont |= C_ICONMGR_BIT; }
356 		| ALL			{ cont |= C_ALL_BITS; }
357 		| OR			{ }
358 		| string		{ Name = $1; cont |= C_NAME_BIT; }
359 		;
360 
361 
362 
363 pixmap_list	: LB pixmap_entries RB {}
364 		;
365 
366 pixmap_entries	: /* Empty */
367 		| pixmap_entries pixmap_entry
368 		;
369 
370 pixmap_entry	:  PKEYWORD string { do_pixmap_keyword($1,$2); }
371 		;
372 
373 
374 cursor_list	: LB cursor_entries RB {}
375 		;
376 
377 cursor_entries	: /* Empty */
378 		| cursor_entries cursor_entry
379 		;
380 
381 cursor_entry	: FRAME string string {
382 			NewBitmapCursor(&Scr->FrameCursor, $2, $3); }
383 		| FRAME string	{
384 			NewFontCursor(&Scr->FrameCursor, $2); }
385 		| TITLE string string {
386 			NewBitmapCursor(&Scr->TitleCursor, $2, $3); }
387 		| TITLE string {
388 			NewFontCursor(&Scr->TitleCursor, $2); }
389 		| ICON string string {
390 			NewBitmapCursor(&Scr->IconCursor, $2, $3); }
391 		| ICON string {
392 			NewFontCursor(&Scr->IconCursor, $2); }
393 		| ICONMGR string string {
394 			NewBitmapCursor(&Scr->IconMgrCursor, $2, $3); }
395 		| ICONMGR string {
396 			NewFontCursor(&Scr->IconMgrCursor, $2); }
397 		| BUTTON string string {
398 			NewBitmapCursor(&Scr->ButtonCursor, $2, $3); }
399 		| BUTTON string {
400 			NewFontCursor(&Scr->ButtonCursor, $2); }
401 		| MOVE string string {
402 			NewBitmapCursor(&Scr->MoveCursor, $2, $3); }
403 		| MOVE string {
404 			NewFontCursor(&Scr->MoveCursor, $2); }
405 		| RESIZE string string {
406 			NewBitmapCursor(&Scr->ResizeCursor, $2, $3); }
407 		| RESIZE string {
408 			NewFontCursor(&Scr->ResizeCursor, $2); }
409 		| WAIT string string {
410 			NewBitmapCursor(&Scr->WaitCursor, $2, $3); }
411 		| WAIT string {
412 			NewFontCursor(&Scr->WaitCursor, $2); }
413 		| MENU string string {
414 			NewBitmapCursor(&Scr->MenuCursor, $2, $3); }
415 		| MENU string {
416 			NewFontCursor(&Scr->MenuCursor, $2); }
417 		| SELECT string string {
418 			NewBitmapCursor(&Scr->SelectCursor, $2, $3); }
419 		| SELECT string {
420 			NewFontCursor(&Scr->SelectCursor, $2); }
421 		| KILL string string {
422 			NewBitmapCursor(&Scr->DestroyCursor, $2, $3); }
423 		| KILL string {
424 			NewFontCursor(&Scr->DestroyCursor, $2); }
425 		;
426 
427 color_list	: LB color_entries RB {}
428 		;
429 
430 color_entries	: /* Empty */
431 		| color_entries color_entry
432 		;
433 
434 color_entry	: CLKEYWORD string	{ if (!do_colorlist_keyword ($1, color,
435 								     $2)) {
436 					    twmrc_error_prefix();
437 					    fprintf (stderr,
438 			"unhandled list color keyword %d (string \"%s\")\n",
439 						     $1, $2);
440 					    ParseError = 1;
441 					  }
442 					}
443 		| CLKEYWORD string	{ list = do_colorlist_keyword($1,color,
444 								      $2);
445 					  if (!list) {
446 					    twmrc_error_prefix();
447 					    fprintf (stderr,
448 			"unhandled color list keyword %d (string \"%s\")\n",
449 						     $1, $2);
450 					    ParseError = 1;
451 					  }
452 					}
453 		  win_color_list
454 		| CKEYWORD string	{ if (!do_color_keyword ($1, color,
455 								 $2)) {
456 					    twmrc_error_prefix();
457 					    fprintf (stderr,
458 			"unhandled color keyword %d (string \"%s\")\n",
459 						     $1, $2);
460 					    ParseError = 1;
461 					  }
462 					}
463 		;
464 
465 
466 win_color_list	: LB win_color_entries RB {}
467 		;
468 
469 win_color_entries	: /* Empty */
470 		| win_color_entries win_color_entry
471 		;
472 
473 win_color_entry	: string string		{ if (Scr->FirstTime &&
474 					      color == Scr->Monochrome)
475 					    AddToList(list, $1, $2); }
476 		;
477 
478 squeeze		: SQUEEZE_TITLE {
479 #ifdef SHAPE
480 				    if (HasShape) Scr->SqueezeTitle = TRUE;
481 #endif
482 				}
483 		| SQUEEZE_TITLE { list = &Scr->SqueezeTitleL;
484 #ifdef SHAPE
485 				  if (HasShape && Scr->SqueezeTitle == -1)
486 				    Scr->SqueezeTitle = TRUE;
487 #endif
488 				}
489 		  LB win_sqz_entries RB
490 		| DONT_SQUEEZE_TITLE { Scr->SqueezeTitle = FALSE; }
491 		| DONT_SQUEEZE_TITLE { list = &Scr->DontSqueezeTitleL; }
492 		  win_list
493 		;
494 
495 win_sqz_entries	: /* Empty */
496 		| win_sqz_entries string JKEYWORD signed_number number	{
497 				if (Scr->FirstTime) {
498 				   do_squeeze_entry (list, $2, $3, $4, $5);
499 				}
500 			}
501 		;
502 
503 
504 iconm_list	: LB iconm_entries RB {}
505 		;
506 
507 iconm_entries	: /* Empty */
508 		| iconm_entries iconm_entry
509 		;
510 
511 iconm_entry	: string string number	{ if (Scr->FirstTime)
512 					    AddToList(list, $1, (char *)
513 						AllocateIconManager($1, NULLSTR,
514 							$2,$3));
515 					}
516 		| string string string number
517 					{ if (Scr->FirstTime)
518 					    AddToList(list, $1, (char *)
519 						AllocateIconManager($1,$2,
520 						$3, $4));
521 					}
522 		;
523 
524 win_list	: LB win_entries RB {}
525 		;
526 
527 win_entries	: /* Empty */
528 		| win_entries win_entry
529 		;
530 
531 win_entry	: string		{ if (Scr->FirstTime)
532 					    AddToList(list, $1, 0);
533 					}
534 		;
535 
536 icon_list	: LB icon_entries RB {}
537 		;
538 
539 icon_entries	: /* Empty */
540 		| icon_entries icon_entry
541 		;
542 
543 icon_entry	: string string		{ if (Scr->FirstTime) AddToList(list, $1, $2); }
544 		;
545 
546 function	: LB function_entries RB {}
547 		;
548 
549 function_entries: /* Empty */
550 		| function_entries function_entry
551 		;
552 
553 function_entry	: action		{ AddToMenu(root, "", Action, NULL, $1,
554 						NULLSTR, NULLSTR);
555 					  Action = "";
556 					}
557 		;
558 
559 menu		: LB menu_entries RB {}
560 		;
561 
562 menu_entries	: /* Empty */
563 		| menu_entries menu_entry
564 		;
565 
566 menu_entry	: string action		{ AddToMenu(root, $1, Action, pull, $2,
567 						NULLSTR, NULLSTR);
568 					  Action = "";
569 					  pull = NULL;
570 					}
571 		| string LP string COLON string RP action {
572 					  AddToMenu(root, $1, Action, pull, $7,
573 						$3, $5);
574 					  Action = "";
575 					  pull = NULL;
576 					}
577 		;
578 
579 action		: FKEYWORD	{ $$ = $1; }
580 		| FSKEYWORD string {
581 				$$ = $1;
582 				Action = $2;
583 				switch ($1) {
584 				  case F_MENU:
585 				  case F_PIEMENU:
586 				    pull = GetRoot ($2, NULLSTR,NULLSTR);
587 				    pull->prev = root;
588 				    break;
589 				  case F_WARPRING:
590 				    if (!CheckWarpRingArg (Action)) {
591 					twmrc_error_prefix();
592 					fprintf (stderr,
593 			"ignoring invalid f.warptoring argument \"%s\"\n",
594 						 Action);
595 					$$ = F_NOP;
596 				    }
597 				  case F_WARPTOSCREEN:
598 				    if (!CheckWarpScreenArg (Action)) {
599 					twmrc_error_prefix();
600 					fprintf (stderr,
601 			"ignoring invalid f.warptoscreen argument \"%s\"\n",
602 					         Action);
603 					$$ = F_NOP;
604 				    }
605 				    break;
606 				  case F_COLORMAP:
607 				    if (CheckColormapArg (Action)) {
608 					$$ = F_COLORMAP;
609 				    } else {
610 					twmrc_error_prefix();
611 					fprintf (stderr,
612 			"ignoring invalid f.colormap argument \"%s\"\n",
613 						 Action);
614 					$$ = F_NOP;
615 				    }
616 				    break;
617 				} /* end switch */
618 				   }
619 		;
620 
621 
622 signed_number	: number		{ $$ = $1; }
623 		| PLUS number		{ $$ = $2; }
624 		| MINUS number		{ $$ = -($2); }
625 		;
626 
627 button		: BUTTON number		{ $$ = $2;
628 					  if ($2 == 0)
629 						yyerror("bad button 0");
630 
631 					  if ($2 > MAX_BUTTONS)
632 					  {
633 						$$ = 0;
634 						yyerror("button number too large");
635 					  }
636 					}
637 		;
638 
639 string		: STRING		{ ptr = (char *)malloc(strlen($1)+1);
640 					  strcpy(ptr, $1);
641 					  RemoveDQuote(ptr);
642 					  $$ = ptr;
643 					}
644 number		: NUMBER		{ $$ = $1; }
645 		;
646 
647 %%
yyerror(s)648 yyerror(s) char *s;
649 {
650     twmrc_error_prefix();
651     fprintf (stderr, "error in input file:  %s\n", s ? s : "");
652     ParseError = 1;
653 }
RemoveDQuote(str)654 RemoveDQuote(str)
655 char *str;
656 {
657     register char *i, *o;
658     register n;
659     register count;
660 
661     for (i=str+1, o=str; *i && *i != '\"'; o++)
662     {
663 	if (*i == '\\')
664 	{
665 	    switch (*++i)
666 	    {
667 	    case 'n':
668 		*o = '\n';
669 		i++;
670 		break;
671 	    case 'b':
672 		*o = '\b';
673 		i++;
674 		break;
675 	    case 'r':
676 		*o = '\r';
677 		i++;
678 		break;
679 	    case 't':
680 		*o = '\t';
681 		i++;
682 		break;
683 	    case 'f':
684 		*o = '\f';
685 		i++;
686 		break;
687 	    case '0':
688 		if (*++i == 'x')
689 		    goto hex;
690 		else
691 		    --i;
692 	    case '1': case '2': case '3':
693 	    case '4': case '5': case '6': case '7':
694 		n = 0;
695 		count = 0;
696 		while (*i >= '0' && *i <= '7' && count < 3)
697 		{
698 		    n = (n<<3) + (*i++ - '0');
699 		    count++;
700 		}
701 		*o = n;
702 		break;
703 	    hex:
704 	    case 'x':
705 		n = 0;
706 		count = 0;
707 		while (i++, count++ < 2)
708 		{
709 		    if (*i >= '0' && *i <= '9')
710 			n = (n<<4) + (*i - '0');
711 		    else if (*i >= 'a' && *i <= 'f')
712 			n = (n<<4) + (*i - 'a') + 10;
713 		    else if (*i >= 'A' && *i <= 'F')
714 			n = (n<<4) + (*i - 'A') + 10;
715 		    else
716 			break;
717 		}
718 		*o = n;
719 		break;
720 	    case '\n':
721 		i++;	/* punt */
722 		o--;	/* to account for o++ at end of loop */
723 		break;
724 	    case '\"':
725 	    case '\'':
726 	    case '\\':
727 	    default:
728 		*o = *i++;
729 		break;
730 	    }
731 	}
732 	else
733 	    *o = *i++;
734     }
735     *o = '\0';
736 }
737 
GetRoot(name,fore,back)738 static MenuRoot *GetRoot(name, fore, back)
739 char *name;
740 char *fore, *back;
741 {
742     MenuRoot *tmp;
743 
744     tmp = FindMenuRoot(name);
745     if (tmp == NULL)
746 	tmp = NewMenuRoot(name);
747 
748     if (fore)
749     {
750 	int save;
751 
752 	save = Scr->FirstTime;
753 	Scr->FirstTime = TRUE;
754 	GetColor(COLOR, &tmp->hi_fore, fore);
755 	GetColor(COLOR, &tmp->hi_back, back);
756 	Scr->FirstTime = save;
757     }
758 
759     return tmp;
760 }
761 
GotButton(butt,func)762 static void GotButton(butt, func)
763 int butt, func;
764 {
765     int i;
766 
767     for (i = 0; i < NUM_CONTEXTS; i++)
768     {
769 	if ((cont & (1 << i)) == 0)
770 	    continue;
771 
772 	Scr->Mouse[butt][i][mods].func = func;
773 	if (func == F_MENU || func == F_PIEMENU)
774 	{
775 	    pull->prev = NULL;
776 	    Scr->Mouse[butt][i][mods].menu = pull;
777 	}
778 	else
779 	{
780 	    root = GetRoot(TWM_ROOT, NULLSTR, NULLSTR);
781 	    Scr->Mouse[butt][i][mods].item = AddToMenu(root,"x",Action,
782 		    NULL, func, NULLSTR, NULLSTR);
783 	}
784     }
785     Action = "";
786     pull = NULL;
787     cont = 0;
788     mods_used |= mods;
789     mods = 0;
790 }
791 
GotKey(key,func)792 static void GotKey(key, func)
793 char *key;
794 int func;
795 {
796     int i;
797 
798     for (i = 0; i < NUM_CONTEXTS; i++)
799     {
800 	if ((cont & (1 << i)) == 0)
801 	  continue;
802 	if (!AddFuncKey(key, i, mods, func, Name, Action))
803 	  break;
804     }
805 
806     Action = "";
807     pull = NULL;
808     cont = 0;
809     mods_used |= mods;
810     mods = 0;
811 }
812 
813 
GotTitleButton(bitmapname,func,rightside)814 static void GotTitleButton (bitmapname, func, rightside)
815     char *bitmapname;
816     int func;
817     Bool rightside;
818 {
819     if (!CreateTitleButton (bitmapname, func, Action, pull, rightside, True)) {
820 	twmrc_error_prefix();
821 	fprintf (stderr,
822 		 "unable to create %s titlebutton \"%s\"\n",
823 		 rightside ? "right" : "left", bitmapname);
824     }
825     Action = "";
826     pull = NULL;
827 }
828 
CheckWarpScreenArg(s)829 static Bool CheckWarpScreenArg (s)
830     register char *s;
831 {
832     XmuCopyISOLatin1Lowered (s, s);
833 
834     if (strcmp (s,  WARPSCREEN_NEXT) == 0 ||
835 	strcmp (s,  WARPSCREEN_PREV) == 0 ||
836 	strcmp (s,  WARPSCREEN_BACK) == 0)
837       return True;
838 
839     for (; *s && isascii(*s) && isdigit(*s); s++) ;
840     return (*s ? False : True);
841 }
842 
843 
CheckWarpRingArg(s)844 static Bool CheckWarpRingArg (s)
845     register char *s;
846 {
847     XmuCopyISOLatin1Lowered (s, s);
848 
849     if (strcmp (s,  WARPSCREEN_NEXT) == 0 ||
850 	strcmp (s,  WARPSCREEN_PREV) == 0)
851       return True;
852 
853     return False;
854 }
855 
856 
CheckColormapArg(s)857 static Bool CheckColormapArg (s)
858     register char *s;
859 {
860     XmuCopyISOLatin1Lowered (s, s);
861 
862     if (strcmp (s, COLORMAP_NEXT) == 0 ||
863 	strcmp (s, COLORMAP_PREV) == 0 ||
864 	strcmp (s, COLORMAP_DEFAULT) == 0)
865       return True;
866 
867     return False;
868 }
869 
870 
twmrc_error_prefix()871 twmrc_error_prefix ()
872 {
873     fprintf (stderr, "%s:  line %d:  ", ProgramName, yylineno);
874 }
875