chiark / gitweb /
debian/changelog: start -4~
[vtwm.git] / gram.y
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.91 91/02/08 18:21:56 dave Exp $
32  *
33  * .twmrc command grammer
34  *
35  * 07-Jan-86 Thomas E. LaStrange        File created
36  * 11-Nov-90 Dave Sternlicht            Adding SaveColors
37  * 10-Oct-90 David M. Sternlicht        Storing saved colors on root
38  *
39  ***********************************************************************/
40
41 %{
42 #include <stdio.h>
43 #include <string.h>
44 #include <ctype.h>
45 #include "twm.h"
46 #include "menus.h"
47 #include "list.h"
48 #include "util.h"
49 #include "screen.h"
50 #include "parse.h"
51 #include "doors.h"
52 /* djhjr - 10/30/02 */
53 #include "iconmgr.h"
54 /* djhjr - 4/26/99 */
55 #include "regions.h"
56 #include <X11/Xos.h>
57 #include <X11/Xmu/CharSet.h>
58
59 /* Submitted by Nelson H. F. Beebe */
60 #ifdef __NeXT__
61 #undef isascii
62 #define isascii(c) ((0 <= (int)(c)) && ((int)(c) <= 127))
63 #endif
64
65 static char *Action = "";
66 static char *Name = "";
67 static MenuRoot *root, *pull = NULL;
68
69 static MenuRoot *GetRoot();
70 /* was type 'void' - djhjr - 10/20/01 */
71 static char *RemoveDQuote();
72 /* djhjr - 10/20/01 */
73 static char *RemoveRESlash();
74 /* djhjr - 10/16/02 */
75 static int ParseWarpCentered();
76 /* djhjr - 9/24/02 */
77 static int ParseUsePPosition();
78 void twmrc_error_prefix();
79
80 /* djhjr - 4/30/96 */
81 static MenuItem *lastmenuitem = (MenuItem*) 0;
82
83 static Bool CheckWarpScreenArg(), CheckWarpRingArg();
84 static Bool CheckColormapArg();
85 static void GotButton(), GotKey(), GotTitleButton();
86 static void yyerror();
87 static name_list **list;
88 /* djhjr - 4/26/99 */
89 static RootRegion *ARlist;
90 static int cont = 0;
91 static int color;
92 int mods = 0;
93 unsigned int mods_used = (ShiftMask | ControlMask | Mod1Mask);
94 /* djhjr - 9/24/02 */
95 static int ppos;
96 /* djhjr - 10/16/02 */
97 static int warpc;
98
99 extern void SetHighlightPixmap();
100 extern void SetVirtualPixmap(), SetVirtualDesktop(), SetRealScreenPixmap();
101 extern void NewBitmapCursor();
102 extern void AddIconRegion();
103 /* next two - djhjr - 4/26/99 */
104 extern RootRegion *AddAppletRegion();
105 extern int AddToAppletList();
106 extern int do_single_keyword(), do_string_keyword(), do_number_keyword();
107 extern name_list **do_colorlist_keyword();
108 extern int do_color_keyword();
109 extern void do_string_savecolor(), do_var_savecolor(), do_squeeze_entry();
110 /* djhjr - 6/22/01 */
111 extern int SetSound();
112
113 /*
114  * this used to be the definition - now making the assumption it's
115  * defined in lex's skeleton file (submitted by Nelson H. F. Beebe)
116  *
117  * djhjr - 1/16/98
118  */
119 extern int yylineno;
120
121 %}
122
123 %union
124 {
125     int num;
126     char *ptr;
127     /* djhjr - 10/20/01 */
128     struct
129     {
130         short ltype;
131         char *lval;
132     } match;
133 };
134
135 %token <num> LP RP MENUS MENU BUTTON DEFAULT_FUNCTION PLUS MINUS
136 %token <num> ALL OR CURSORS PIXMAPS ICONS COLOR MONOCHROME FUNCTION
137 %token <num> ICONMGR_SHOW ICONMGR WINDOW_FUNCTION ZOOM ICONMGRS
138 %token <num> ICONMGR_GEOMETRY ICONMGR_NOSHOW MAKE_TITLE
139 %token <num> ICONIFY_BY_UNMAPPING DONT_ICONIFY_BY_UNMAPPING
140 %token <num> NO_TITLE AUTO_RAISE NO_HILITE NO_ICONMGR_HILITE ICON_REGION
141 /* djhjr - 10/16/02 */
142 %token <num> WARP_CENTERED
143 /* djhjr - 9/24/02 */
144 %token <num> USE_PPOSITION
145 /* submitted by Tim Wiess - 8/23/02 */
146 %token <num> NO_BORDER
147 /* djhjr - 4/26/99 */
148 %token <num> APPLET_REGION
149 %token <num> META SHIFT LOCK CONTROL WINDOW TITLE ICON ROOT FRAME VIRTUAL VIRTUAL_WIN
150 /* TILDE - djhjr - 10/20/01 */
151 %token <num> COLON EQUALS TILDE SQUEEZE_TITLE DONT_SQUEEZE_TITLE
152 /* opaque stuff - djhjr - 4/7/98 */
153 %token <num> OPAQUE_MOVE NO_OPAQUE_MOVE OPAQUE_RESIZE NO_OPAQUE_RESIZE
154 %token <num> START_ICONIFIED NO_TITLE_HILITE TITLE_HILITE
155 %token <num> MOVE RESIZE WAIT SELECT KILL LEFT_TITLEBUTTON RIGHT_TITLEBUTTON
156 /* MKEYWORD - djhjr - 10/20/01 */
157 %token <num> NUMBER KEYWORD MKEYWORD NKEYWORD CKEYWORD CLKEYWORD FKEYWORD FSKEYWORD
158 /* SNKEYWORD - djhjr - 10/18/02 */
159 /* NO_WINDOW_RING submitted by Jonathan Paisley - 10/27/02 */
160 %token <num> SNKEYWORD SKEYWORD DKEYWORD JKEYWORD WINDOW_RING NO_WINDOW_RING WARP_CURSOR
161 %token <num> ERRORTOKEN NO_STACKMODE NAILEDDOWN VIRTUALDESKTOP NO_SHOW_IN_DISPLAY
162 /* Submitted by Erik Agsjo <erik.agsjo@aktiedirekt.com> */
163 %token <num> NO_SHOW_IN_TWMWINDOWS
164 %token DOORS DOOR
165 /*RFB PIXMAP:*/
166 %token <num> VIRTUALMAP
167 %token <num> REALSCREENMAP
168 /* two pixmaps - djhjr - 10/30/02 */
169 %token <num> ICONMGRICONMAP
170 %token <num> MENUICONMAP
171 /*<RFB PIXMAP*/
172 /* djhjr - 6/22/01 */
173 %token SOUNDS
174 /* REGEXP - djhjr - 10/20/01 */
175 %token <ptr> STRING REGEXP
176 /* djhjr - 9/10/03 */
177 %token <num> IGNORE_MODS
178 %token SAVECOLOR
179 %token LB
180 %token RB
181
182 /* regex stuff - djhjr - 10/20/01 */
183 %type <match> matcher
184 %type <ptr> string regexp
185 %type <num> action button number signed_number full fullkey
186
187 %start twmrc
188
189 %%
190 twmrc           : stmts
191                 ;
192
193 stmts           : /* Empty */
194                 | stmts stmt
195                 ;
196
197 stmt            : error
198                 | noarg
199                 | sarg
200                 | narg
201                 | snarg
202                 | squeeze
203                 | doors
204                 | ICON_REGION string DKEYWORD DKEYWORD number number
205                                         { AddIconRegion($2, $3, $4, $5, $6); }
206                 | APPLET_REGION string DKEYWORD DKEYWORD number number
207                                         { ARlist = AddAppletRegion($2, $3, $4, $5, $6); }
208                   applet_list
209                 | ICONMGR_GEOMETRY string number        { if (Scr->FirstTime)
210                                                   {
211                                                     Scr->iconmgr.geometry=$2;
212                                                     Scr->iconmgr.columns=$3;
213                                                   }
214                                                 }
215                 | ICONMGR_GEOMETRY string       { if (Scr->FirstTime)
216                                                     Scr->iconmgr.geometry = $2;
217                                                 }
218                 | ZOOM number           { if (Scr->FirstTime)
219                                           {
220                                                 Scr->DoZoom = TRUE;
221                                                 Scr->ZoomCount = $2;
222                                           }
223                                         }
224                 | ZOOM                  { if (Scr->FirstTime)
225                                                 Scr->DoZoom = TRUE; }
226                 | PIXMAPS pixmap_list   {}
227                 | CURSORS cursor_list   {}
228                 | ICONIFY_BY_UNMAPPING  { list = &Scr->IconifyByUn; }
229                   win_list
230                 | ICONIFY_BY_UNMAPPING  { if (Scr->FirstTime)
231                     Scr->IconifyByUnmapping = TRUE; }
232
233                 | OPAQUE_MOVE { list = &Scr->OpaqueMoveL; }
234                   win_list
235                 | OPAQUE_MOVE { if (Scr->FirstTime) Scr->OpaqueMove = TRUE; }
236                 | NO_OPAQUE_MOVE { list = &Scr->NoOpaqueMoveL; }
237                   win_list
238                 | NO_OPAQUE_MOVE { if (Scr->FirstTime) Scr->OpaqueMove = FALSE; }
239                 | OPAQUE_RESIZE { list = &Scr->OpaqueResizeL; }
240                   win_list
241                 | OPAQUE_RESIZE { if (Scr->FirstTime) Scr->OpaqueResize = TRUE; }
242                 | NO_OPAQUE_RESIZE { list = &Scr->NoOpaqueResizeL; }
243                   win_list
244                 | NO_OPAQUE_RESIZE { if (Scr->FirstTime) Scr->OpaqueResize = FALSE; }
245
246                 | LEFT_TITLEBUTTON string EQUALS action {
247                                           GotTitleButton ($2, $4, False);
248                                         }
249                 | RIGHT_TITLEBUTTON string EQUALS action {
250                                           GotTitleButton ($2, $4, True);
251                                         }
252                 | button string         { root = GetRoot($2, NULLSTR, NULLSTR);
253                                           Scr->Mouse[$1][C_ROOT][0].func = F_MENU;
254                                           Scr->Mouse[$1][C_ROOT][0].menu = root;
255                                         }
256                 | button action         { Scr->Mouse[$1][C_ROOT][0].func = $2;
257                                           if ($2 == F_MENU)
258                                           {
259                                             pull->prev = NULL;
260                                             Scr->Mouse[$1][C_ROOT][0].menu = pull;
261                                           }
262                                           else
263                                           {
264                                             root = GetRoot(TWM_ROOT,NULLSTR,NULLSTR);
265                                             Scr->Mouse[$1][C_ROOT][0].item =
266                                                 AddToMenu(root,"x",Action,
267                                                           NULLSTR,$2,NULLSTR,NULLSTR);
268                                           }
269                                           Action = "";
270                                           pull = NULL;
271                                         }
272                 | string fullkey        { GotKey($1, $2); }
273                 | button full           { GotButton($1, $2); }
274                 | IGNORE_MODS keys      { Scr->IgnoreModifiers = mods;
275                                           mods = 0;
276                                         }
277                 | DONT_ICONIFY_BY_UNMAPPING { list = &Scr->DontIconify; }
278                   win_list
279                 | ICONMGR_NOSHOW        { list = &Scr->IconMgrNoShow; }
280                   win_list
281                 | ICONMGR_NOSHOW        { Scr->IconManagerDontShow = TRUE; }
282                 | ICONMGRS              { list = &Scr->IconMgrs; }
283                   iconm_list
284                 | ICONMGR_SHOW          { list = &Scr->IconMgrShow; }
285                   win_list
286                 | NO_TITLE_HILITE       { list = &Scr->NoTitleHighlight; }
287                   win_list
288                 | NO_TITLE_HILITE       { if (Scr->FirstTime)
289                                                 Scr->TitleHighlight = FALSE; }
290                 | NO_ICONMGR_HILITE             { Scr->IconMgrHighlight = FALSE; }
291                 | NO_HILITE             { list = &Scr->NoHighlight; }
292                   win_list
293                 | NO_HILITE             { if (Scr->FirstTime)
294                                                 Scr->Highlight = FALSE; }
295                 | NO_STACKMODE          { list = &Scr->NoStackModeL; }
296                   win_list
297                 | NO_STACKMODE          { if (Scr->FirstTime)
298                                                 Scr->StackMode = FALSE; }
299                 | NO_TITLE              { list = &Scr->NoTitle; }
300                   win_list
301                 | NO_TITLE              { if (Scr->FirstTime)
302                                                 Scr->NoTitlebar = TRUE; }
303                 | NO_BORDER             { list = &Scr->NoBorder; }
304                   win_list
305                 | NO_BORDER             { if (Scr->FirstTime)
306                                                 Scr->NoBorders = TRUE; }
307                 | MAKE_TITLE            { list = &Scr->MakeTitle; }
308                   win_list
309                 | START_ICONIFIED       { list = &Scr->StartIconified; }
310                   win_list
311                 | AUTO_RAISE            { list = &Scr->AutoRaise; }
312                   win_list
313                 | AUTO_RAISE            { Scr->AutoRaiseDefault = TRUE; }
314                 | WARP_CENTERED string  { if (Scr->FirstTime) {
315                                                 if ((warpc = ParseWarpCentered($2)) != -1)
316                                                         Scr->WarpCentered = warpc;
317                                           }
318                                         }
319                 | USE_PPOSITION string  { if (Scr->FirstTime) {
320                                                 if ((ppos = ParseUsePPosition($2)) != -1)
321                                                         Scr->UsePPosition = ppos;
322                                           }
323                                         }
324                 | USE_PPOSITION         { list = &Scr->UsePPositionL; }
325                   ppos_list
326                 | USE_PPOSITION string  { if (Scr->FirstTime) {
327                                                 if ((ppos = ParseUsePPosition($2)) != -1)
328                                                         Scr->UsePPosition = ppos;
329                                           }
330                                           list = &Scr->UsePPositionL;
331                                         }
332                   ppos_list
333                 | MENU string LP string COLON string RP {
334                                         root = GetRoot($2, $4, $6); }
335                   menu                  { root->real_menu = TRUE;}
336                 | MENU string           { root = GetRoot($2, NULLSTR, NULLSTR); }
337                   menu                  { root->real_menu = TRUE; }
338                 | FUNCTION string       { root = GetRoot($2, NULLSTR, NULLSTR); }
339                   function
340                 | ICONS                 { list = &Scr->IconNames; }
341                   icon_list
342                 | SOUNDS
343                   sound_list
344                 | COLOR                 { color = COLOR; }
345                   color_list
346                 | SAVECOLOR
347                   save_color_list
348                 | MONOCHROME            { color = MONOCHROME; }
349                   color_list
350                 | DEFAULT_FUNCTION action { Scr->DefaultFunction.func = $2;
351                                           if ($2 == F_MENU)
352                                           {
353                                             pull->prev = NULL;
354                                             Scr->DefaultFunction.menu = pull;
355                                           }
356                                           else
357                                           {
358                                             root = GetRoot(TWM_ROOT,NULLSTR,NULLSTR);
359                                             Scr->DefaultFunction.item =
360                                                 AddToMenu(root,"x",Action,
361                                                           NULLSTR,$2, NULLSTR, NULLSTR);
362                                           }
363                                           Action = "";
364                                           pull = NULL;
365                                         }
366                 | WINDOW_FUNCTION action { Scr->WindowFunction.func = $2;
367                                            root = GetRoot(TWM_ROOT,NULLSTR,NULLSTR);
368                                            Scr->WindowFunction.item =
369                                                 AddToMenu(root,"x",Action,
370                                                           NULLSTR,$2, NULLSTR, NULLSTR);
371                                            Action = "";
372                                            pull = NULL;
373                                         }
374                 | WARP_CURSOR           { list = &Scr->WarpCursorL; }
375                   win_list
376                 | WARP_CURSOR           { if (Scr->FirstTime)
377                                             Scr->WarpCursor = TRUE; }
378                 | WINDOW_RING           { list = &Scr->WindowRingL; }
379                   win_list
380                 | WINDOW_RING       {   if (Scr->FirstTime)
381                                                 Scr->UseWindowRing = TRUE; }
382                 | NO_WINDOW_RING        { list = &Scr->NoWindowRingL; }
383                   win_list
384                 | NAILEDDOWN            { list = &Scr->NailedDown; }
385                   win_list
386                 | VIRTUALDESKTOP string number
387                                         { SetVirtualDesktop($2, $3); }
388                 | NO_SHOW_IN_DISPLAY    { list = &Scr->DontShowInDisplay; }
389                   win_list
390                 | NO_SHOW_IN_TWMWINDOWS { list = &Scr->DontShowInTWMWindows; }
391                   win_list
392                 ;
393
394
395 noarg           : KEYWORD               { if (!do_single_keyword ($1)) {
396                                             twmrc_error_prefix();
397                                             fprintf (stderr,
398                                         "unknown singleton keyword %d\n",
399                                                      $1);
400                                             ParseError = 1;
401                                           }
402                                         }
403                 ;
404
405 sarg            : SKEYWORD string       { if (!do_string_keyword ($1, $2)) {
406                                             twmrc_error_prefix();
407                                             fprintf (stderr,
408                                 "unknown string keyword %d (value \"%s\")\n",
409                                                      $1, $2);
410                                             ParseError = 1;
411                                           }
412                                         }
413                 ;
414
415 narg            : NKEYWORD number       { if (!do_number_keyword ($1, $2)) {
416                                             twmrc_error_prefix();
417                                             fprintf (stderr,
418                                 "unknown numeric keyword %d (value %d)\n",
419                                                      $1, $2);
420                                             ParseError = 1;
421                                           }
422                                         }
423                 ;
424
425 /* djhjr - 10/18/02 */
426 snarg           : SNKEYWORD signed_number       { if (!do_number_keyword ($1, $2)) {
427                                             twmrc_error_prefix();
428                                             fprintf (stderr,
429                                 "unknown signed keyword %d (value %d)\n",
430                                                      $1, $2);
431                                             ParseError = 1;
432                                           }
433                                         }
434                 ;
435
436
437
438 full            : EQUALS keys COLON contexts COLON action  { $$ = $6; }
439                 ;
440
441 fullkey         : EQUALS keys COLON contextkeys COLON action  { $$ = $6; }
442                 ;
443
444 keys            : /* Empty */
445                 | keys key
446                 ;
447
448 key             : META                  { mods |= Mod1Mask; }
449                 | SHIFT                 { mods |= ShiftMask; }
450                 | LOCK                  { mods |= LockMask; }
451                 | CONTROL               { mods |= ControlMask; }
452                 | META number           { if ($2 < 1 || $2 > 5) {
453                                              twmrc_error_prefix();
454                                              fprintf (stderr,
455                                 "bad modifier number (%d), must be 1-5\n",
456                                                       $2);
457                                              ParseError = 1;
458                                           } else {
459                                              mods |= (Mod1Mask << ($2 - 1));
460                                           }
461                                         }
462                 | OR                    { }
463                 ;
464
465 contexts        : /* Empty */
466                 | contexts context
467                 ;
468
469 context         : WINDOW                { cont |= C_WINDOW_BIT; }
470                 | TITLE                 { cont |= C_TITLE_BIT; }
471                 | ICON                  { cont |= C_ICON_BIT; }
472                 | ROOT                  { cont |= C_ROOT_BIT; }
473                 | FRAME                 { cont |= C_FRAME_BIT; }
474                 | ICONMGR               { cont |= C_ICONMGR_BIT; }
475                 | META                  { cont |= C_ICONMGR_BIT; }
476                 | VIRTUAL               { cont |= C_VIRTUAL_BIT; }
477                 | VIRTUAL_WIN           { cont |= C_VIRTUAL_WIN_BIT; }
478                 | DOOR                  { cont |= C_DOOR_BIT; }
479                 | ALL                   { cont |= C_ALL_BITS; }
480                 | OR                    {  }
481                 ;
482
483 contextkeys     : /* Empty */
484                 | contextkeys contextkey
485                 ;
486
487 contextkey      : WINDOW                { cont |= C_WINDOW_BIT; }
488                 | TITLE                 { cont |= C_TITLE_BIT; }
489                 | ICON                  { cont |= C_ICON_BIT; }
490                 | ROOT                  { cont |= C_ROOT_BIT; }
491                 | FRAME                 { cont |= C_FRAME_BIT; }
492                 | ICONMGR               { cont |= C_ICONMGR_BIT; }
493                 | META                  { cont |= C_ICONMGR_BIT; }
494                 | VIRTUAL               { cont |= C_VIRTUAL_BIT; }
495                 | VIRTUAL_WIN           { cont |= C_VIRTUAL_WIN_BIT; }
496                 | DOOR                  { cont |= C_DOOR_BIT; }
497                 | ALL                   { cont |= C_ALL_BITS; }
498                 | OR                    { }
499                 | string                { Name = $1; cont |= C_NAME_BIT; }
500                 ;
501
502
503 pixmap_list     : LB pixmap_entries RB
504                 ;
505
506 pixmap_entries  : /* Empty */
507                 | pixmap_entries pixmap_entry
508                 ;
509
510 pixmap_entry    : TITLE_HILITE string { SetHighlightPixmap ($2); }
511                 | VIRTUALMAP string { SetVirtualPixmap ($2); }/*RFB PIXMAP*/
512                 | REALSCREENMAP string { SetRealScreenPixmap ($2); }/*RFB PIXMAP*/
513                 | ICONMGRICONMAP string { SetIconMgrPixmap($2); } /* djhjr - 10/30/02 */
514                 | MENUICONMAP string { SetMenuIconPixmap($2); } /* djhjr - 10/30/02 */
515                 ;
516
517
518 cursor_list     : LB cursor_entries RB
519                 ;
520
521 cursor_entries  : /* Empty */
522                 | cursor_entries cursor_entry
523                 ;
524
525 cursor_entry    : FRAME string string {
526                         NewBitmapCursor(&Scr->FrameCursor, $2, $3); }
527                 | FRAME string  {
528                         NewFontCursor(&Scr->FrameCursor, $2); }
529                 | TITLE string string {
530                         NewBitmapCursor(&Scr->TitleCursor, $2, $3); }
531                 | TITLE string {
532                         NewFontCursor(&Scr->TitleCursor, $2); }
533                 | ICON string string {
534                         NewBitmapCursor(&Scr->IconCursor, $2, $3); }
535                 | ICON string {
536                         NewFontCursor(&Scr->IconCursor, $2); }
537                 | ICONMGR string string {
538                         NewBitmapCursor(&Scr->IconMgrCursor, $2, $3); }
539                 | ICONMGR string {
540                         NewFontCursor(&Scr->IconMgrCursor, $2); }
541                 | BUTTON string string {
542                         NewBitmapCursor(&Scr->ButtonCursor, $2, $3); }
543                 | BUTTON string {
544                         NewFontCursor(&Scr->ButtonCursor, $2); }
545                 | MOVE string string {
546                         NewBitmapCursor(&Scr->MoveCursor, $2, $3); }
547                 | MOVE string {
548                         NewFontCursor(&Scr->MoveCursor, $2); }
549                 | RESIZE string string {
550                         NewBitmapCursor(&Scr->ResizeCursor, $2, $3); }
551                 | RESIZE string {
552                         NewFontCursor(&Scr->ResizeCursor, $2); }
553                 | WAIT string string {
554                         NewBitmapCursor(&Scr->WaitCursor, $2, $3); }
555                 | WAIT string {
556                         NewFontCursor(&Scr->WaitCursor, $2); }
557                 | MENU string string {
558                         NewBitmapCursor(&Scr->MenuCursor, $2, $3); }
559                 | MENU string {
560                         NewFontCursor(&Scr->MenuCursor, $2); }
561                 | SELECT string string {
562                         NewBitmapCursor(&Scr->SelectCursor, $2, $3); }
563                 | SELECT string {
564                         NewFontCursor(&Scr->SelectCursor, $2); }
565                 | KILL string string {
566                         NewBitmapCursor(&Scr->DestroyCursor, $2, $3); }
567                 | KILL string {
568                         NewFontCursor(&Scr->DestroyCursor, $2); }
569                 | DOOR string string {/*RFBCURSOR*/
570                         NewBitmapCursor(&Scr->DoorCursor, $2, $3); }/*RFBCURSOR*/
571                 | DOOR string {/*RFBCURSOR*/
572                         NewFontCursor(&Scr->DoorCursor, $2); }/*RFBCURSOR*/
573                 | VIRTUAL string string {/*RFBCURSOR*/
574                         NewBitmapCursor(&Scr->VirtualCursor, $2, $3); }/*RFBCURSOR*/
575                 | VIRTUAL string {/*RFBCURSOR*/
576                         NewFontCursor(&Scr->VirtualCursor, $2); }/*RFBCURSOR*/
577                 | VIRTUAL_WIN string string {/*RFBCURSOR*/
578                         NewBitmapCursor(&Scr->DesktopCursor, $2, $3); }/*RFBCURSOR*/
579                 | VIRTUAL_WIN string {/*RFBCURSOR*/
580                         NewFontCursor(&Scr->DesktopCursor, $2); }/*RFBCURSOR*/
581                 ;
582
583 color_list      : LB color_entries RB
584                 ;
585
586
587 color_entries   : /* Empty */
588                 | color_entries color_entry
589                 ;
590
591 color_entry     : CLKEYWORD string      { if (!do_colorlist_keyword ($1, color,
592                                                                      $2)) {
593                                             twmrc_error_prefix();
594                                             fprintf (stderr,
595                         "unhandled list color keyword %d (string \"%s\")\n",
596                                                      $1, $2);
597                                             ParseError = 1;
598                                           }
599                                         }
600                 | CLKEYWORD string      { list = do_colorlist_keyword($1,color,
601                                                                       $2);
602                                           if (!list) {
603                                             twmrc_error_prefix();
604                                             fprintf (stderr,
605                         "unhandled color list keyword %d (string \"%s\")\n",
606                                                      $1, $2);
607                                             ParseError = 1;
608                                           }
609                                         }
610                   win_color_list
611                 | CKEYWORD string       { if (!do_color_keyword ($1, color,
612                                                                  $2)) {
613                                             twmrc_error_prefix();
614                                             fprintf (stderr,
615                         "unhandled color keyword %d (string \"%s\")\n",
616                                                      $1, $2);
617                                             ParseError = 1;
618                                           }
619                                         }
620                 ;
621
622 save_color_list : LB s_color_entries RB
623                 ;
624
625 s_color_entries : /* Empty */
626                 | s_color_entries s_color_entry
627                 ;
628
629 s_color_entry   : string            { do_string_savecolor(color, $1); }
630                 | CLKEYWORD         { do_var_savecolor($1); }
631                 ;
632
633 win_color_list  : LB win_color_entries RB
634                 ;
635
636 win_color_entries       : /* Empty */
637                 | win_color_entries win_color_entry
638                 ;
639
640 /* 'matcher', mods to 'AddToList()' - djhjr - 10/20/01 */
641 win_color_entry : matcher string        { if (Scr->FirstTime &&
642                                               color == Scr->Monochrome)
643                                             AddToList(list, $1.lval, $1.ltype,
644                                                         $2); }
645                 ;
646
647 squeeze         : SQUEEZE_TITLE {
648                                     if (HasShape) Scr->SqueezeTitle = TRUE;
649                                 }
650                 | SQUEEZE_TITLE { list = &Scr->SqueezeTitleL;
651                                   if (HasShape && Scr->SqueezeTitle == -1)
652                                     Scr->SqueezeTitle = TRUE;
653                                 }
654                   LB win_sqz_entries RB
655                 | DONT_SQUEEZE_TITLE { Scr->SqueezeTitle = FALSE; }
656                 | DONT_SQUEEZE_TITLE { list = &Scr->DontSqueezeTitleL; }
657                   win_list
658                 ;
659
660 /* 'matcher', mods to 'do_sqeeze_entry()' - djhjr - 10/20/01 */
661 win_sqz_entries : /* Empty */
662                 | win_sqz_entries matcher JKEYWORD signed_number signed_number  {
663                                 if (Scr->FirstTime) {
664                                    do_squeeze_entry (list, $2.lval, $2.ltype,
665                                                         $3, $4, $5);
666                                 }
667                         }
668                 ;
669
670 doors           : DOORS LB door_list RB
671                 ;
672
673 door_list       : /* Empty */
674                 | door_list door_entry
675                 ;
676
677 door_entry      : string string string
678                         {
679                                 (void) door_add($1, $2, $3);
680                         }
681                 ;
682
683 iconm_list      : LB iconm_entries RB
684                 ;
685
686 iconm_entries   : /* Empty */
687                 | iconm_entries iconm_entry
688                 ;
689
690 /* 'matcher', mods to 'AddToList()', 'AllocateIconManager()' - djhjr - 10/20/01 */
691 iconm_entry     : matcher string number { if (Scr->FirstTime)
692                                             AddToList(list, $1.lval, $1.ltype, (char *)
693                                                 AllocateIconManager($1.lval,
694                                                         NULLSTR, $2, $3));
695                                         }
696                 | matcher string string number
697                                         { if (Scr->FirstTime)
698                                             AddToList(list, $1.lval, $1.ltype, (char *)
699                                                 AllocateIconManager($1.lval,
700                                                         $2, $3, $4));
701                                         }
702                 ;
703
704 win_list        : LB win_entries RB
705                 ;
706
707 win_entries     : /* Empty */
708                 | win_entries win_entry
709                 ;
710
711 /* 'matcher', mods to 'AddToList()' - djhjr - 10/20/01 */
712 win_entry       : matcher               { if (Scr->FirstTime)
713                                             AddToList(list, $1.lval, $1.ltype, 0);
714                                         }
715                 ;
716
717 icon_list       : LB icon_entries RB
718                 ;
719
720 icon_entries    : /* Empty */
721                 | icon_entries icon_entry
722                 ;
723
724 /* 'matcher', mods to 'AddToList()' - djhjr - 10/20/01 */
725 icon_entry      : matcher string        { if (Scr->FirstTime)
726                                             AddToList(list, $1.lval, $1.ltype, $2);
727                                         }
728                 ;
729
730 /* djhjr - 9/24/02 */
731 ppos_list       : LB ppos_entries RB
732                 ;
733
734 ppos_entries    : /* Empty */
735                 | ppos_entries ppos_entry
736                 ;
737
738 /* 'matcher', mods to 'AddToList()' - djhjr - 10/20/01 */
739 ppos_entry      : matcher string        { if (Scr->FirstTime) {
740                                             if ((ppos = ParseUsePPosition($2)) != -1)
741                                               AddToList(list, $1.lval, $1.ltype, (char *)&ppos);
742                                           }
743                                         }
744                 ;
745
746 /* djhjr - 6/22/01 */
747 sound_list      : LB sound_entries RB
748                 ;
749
750 /* djhjr - 6/22/01 */
751 sound_entries   : /* Empty */
752                 | sound_entries sound_entry
753                 ;
754
755 /* djhjr - 8/16/01 */
756 sound_entry     : string string         { if (Scr->FirstTime) SetSound($1, $2, -1); }
757                 | string string number  { if (Scr->FirstTime) SetSound($1, $2, $3); }
758                 ;
759
760 /* djhjr - 4/26/99 */
761 applet_list     : LB applet_entries RB
762                 ;
763
764 /* djhjr - 4/26/99 */
765 applet_entries  : /* Empty */
766                 | applet_entries applet_entry
767                 ;
768
769 /* djhjr - 4/26/99 */
770 /* 'matcher', mods to 'AddToAppletList()' - djhjr - 10/20/01 */
771 applet_entry    : matcher               { if (Scr->FirstTime)
772                                               AddToAppletList(ARlist,
773                                                         $1.lval, $1.ltype);
774                                         }
775                 ;
776
777 function        : LB function_entries RB
778                 ;
779
780 function_entries: /* Empty */
781                 | function_entries function_entry
782                 ;
783
784 function_entry  : action                { AddToMenu(root, "", Action, NULLSTR, $1,
785                                                 NULLSTR, NULLSTR);
786                                           Action = "";
787                                         }
788                 ;
789
790 /* djhjr - 4/30/96
791 menu            : LB menu_entries RB
792 */
793 menu            : LB menu_entries RB {lastmenuitem = (MenuItem*) 0;}
794                 ;
795
796 menu_entries    : /* Empty */
797                 | menu_entries menu_entry
798                 ;
799
800 /* djhjr - 4/30/96
801 menu_entry      : string action         { AddToMenu(root, $1, Action, pull, $2,
802                                                 NULLSTR, NULLSTR);
803                                           Action = "";
804                                           pull = NULL;
805                                         }
806                 | string LP string COLON string RP action {
807                                           AddToMenu(root, $1, Action, pull, $7,
808                                                 $3, $5);
809                                           Action = "";
810                                           pull = NULL;
811                                         }
812                 ;
813 */
814 menu_entry      : string action         {
815                         if ($2 == F_SEPARATOR) {
816                             if (lastmenuitem) lastmenuitem->separated = 1;
817                         }
818                         else {
819                             lastmenuitem = AddToMenu(root, $1, Action, pull, $2, NULLSTR, NULLSTR);
820                             Action = "";
821                             pull = NULL;
822                         }
823                 }
824                 | string LP string COLON string RP action {
825                         if ($7 == F_SEPARATOR) {
826                             if (lastmenuitem) lastmenuitem->separated = 1;
827                         }
828                         else {
829                             lastmenuitem = AddToMenu(root, $1, Action, pull, $7, $3, $5);
830                             Action = "";
831                             pull = NULL;
832                         }
833                 }
834                 ;
835
836 action          : FKEYWORD      { $$ = $1; }
837                 | FSKEYWORD string {
838                                 $$ = $1;
839                                 Action = $2;
840                                 switch ($1) {
841                                   case F_MENU:
842                                     pull = GetRoot ($2, NULLSTR,NULLSTR);
843                                     pull->prev = root;
844                                     break;
845                                   case F_WARPRING:
846                                     if (!CheckWarpRingArg (Action)) {
847                                         twmrc_error_prefix();
848                                         fprintf (stderr,
849                         "ignoring invalid f.warptoring argument \"%s\"\n",
850                                                  Action);
851                                         $$ = F_NOP;
852                                     }
853                                   case F_WARPTOSCREEN:
854                                     if (!CheckWarpScreenArg (Action)) {
855                                         twmrc_error_prefix();
856                                         fprintf (stderr,
857                         "ignoring invalid f.warptoscreen argument \"%s\"\n",
858                                                  Action);
859                                         $$ = F_NOP;
860                                     }
861                                     break;
862                                   case F_COLORMAP:
863                                     if (CheckColormapArg (Action)) {
864                                         $$ = F_COLORMAP;
865                                     } else {
866                                         twmrc_error_prefix();
867                                         fprintf (stderr,
868                         "ignoring invalid f.colormap argument \"%s\"\n",
869                                                  Action);
870                                         $$ = F_NOP;
871                                     }
872                                     break;
873                                 } /* end switch */
874                                    }
875                 ;
876
877
878 button          : BUTTON number         { $$ = $2;
879                                           if ($2 == 0)
880                                                 yyerror("bad button 0");
881
882                                           if ($2 > MAX_BUTTONS)
883                                           {
884                                                 $$ = 0;
885                                                 yyerror("button number too large");
886                                           }
887                                         }
888                 ;
889
890 /* djhjr - 10/20/01 */
891 matcher         : string                { $$.ltype = LTYPE_ANY_STRING;
892                                           $$.lval = $1;
893                                         }
894                 | regexp                { $$.ltype = LTYPE_ANY_REGEXP;
895                                           $$.lval = $1;
896                                         }
897                 | MKEYWORD EQUALS string { $$.ltype = $1 | LTYPE_STRING;
898                                            $$.lval = $3;
899                                          }
900                 | MKEYWORD TILDE regexp { $$.ltype = $1 | LTYPE_REGEXP;
901                                           $$.lval = $3;
902                                         }
903                 ;
904
905 string          : STRING                { $$ = RemoveDQuote($1); }
906                 ;
907
908 /* djhjr - 10/20/01 */
909 regexp          : REGEXP                { $$ = RemoveRESlash($1); }
910                 ;
911
912 signed_number   : number                { $$ = $1; }
913                 | PLUS number           { $$ = $2; }
914                 | MINUS number          { $$ = -($2); }
915                 ;
916
917 number          : NUMBER                { $$ = $1; }
918                 ;
919
920 %%
921 static void
922 yyerror(s) char *s;
923 {
924     twmrc_error_prefix();
925     fprintf (stderr, "error in input file:  %s\n", s ? s : "");
926     ParseError = 1;
927 }
928
929 /* do manipulations in place, then copy it - djhjr - 10/20/01 */
930 static char *RemoveDQuote(str)
931 char *str;
932 {
933     register char *i, *o;
934     register int n, count;
935     int length = 0;
936     char *ptr = "";
937
938     for (i = str + 1, o = str; *i && *i != '\"'; o++)
939     {
940         if (*i == '\\')
941         {
942             switch (*++i)
943             {
944             case 'n':
945                 *o = '\n';
946                 i++;
947                 break;
948             case 'b':
949                 *o = '\b';
950                 i++;
951                 break;
952             case 'r':
953                 *o = '\r';
954                 i++;
955                 break;
956             case 't':
957                 *o = '\t';
958                 i++;
959                 break;
960             case 'f':
961                 *o = '\f';
962                 i++;
963                 break;
964             case '0':
965                 if (*++i == 'x')
966                     goto hex;
967                 else
968                     --i;
969             case '1': case '2': case '3':
970             case '4': case '5': case '6': case '7':
971                 n = 0;
972                 count = 0;
973                 while (*i >= '0' && *i <= '7' && count < 3)
974                 {
975                     n = (n << 3) + (*i++ - '0');
976                     count++;
977                 }
978                 *o = n;
979                 break;
980             hex:
981             case 'x':
982                 n = 0;
983                 count = 0;
984                 while (i++, count++ < 2)
985                 {
986                     if (*i >= '0' && *i <= '9')
987                         n = (n << 4) + (*i - '0');
988                     else if (*i >= 'a' && *i <= 'f')
989                         n = (n << 4) + (*i - 'a') + 10;
990                     else if (*i >= 'A' && *i <= 'F')
991                         n = (n << 4) + (*i - 'A') + 10;
992                     else
993                     {
994                         length--; /* account for length++ at loop end */
995                         break;
996                     }
997                 }
998                 *o = n;
999                 break;
1000             case '\n':
1001                 i++;    /* punt */
1002                 o--;    /* to account for o++ at end of loop */
1003                 length--; /* account for length++ at loop end */
1004                 break;
1005             case '\"':
1006             case '\'':
1007             case '\\':
1008             default:
1009                 *o = *i++;
1010                 break;
1011             }
1012         }
1013         else
1014             *o = *i++;
1015
1016         length++;
1017     }
1018     *o = '\0';
1019
1020     if (length > 0)
1021     {
1022         ptr = (char *)malloc(length + 1);
1023         memcpy(ptr, str, length);
1024         ptr[length] = '\0';
1025
1026 #ifdef DEBUG
1027         fprintf(stderr, "RemoveDQuote(): '");
1028         for (n = 0; n < length; n++)
1029             fprintf(stderr, "%c", ptr[n]);
1030         fprintf(stderr, "'\n", ptr);
1031 #endif
1032     }
1033
1034     return (ptr);
1035 }
1036
1037 /* djhjr - 10/20/01 */
1038 static char *RemoveRESlash(str)
1039 char *str;
1040 {
1041     char *ptr = "";
1042 #ifndef NO_REGEX_SUPPORT
1043     int length = strlen(str);
1044
1045     if (length > 2)
1046     {
1047         ptr = (char *)malloc(length - 1);
1048         memcpy(ptr, str + 1, length - 2);
1049         ptr[length - 2] = '\0';
1050
1051 #ifdef DEBUG
1052         fprintf(stderr, "RemoveRESlash(): '%s'\n", ptr);
1053 #endif
1054     }
1055 #else
1056     twmrc_error_prefix();
1057     fprintf(stderr, "no regex support for %s\n", str);
1058     ParseError = 1;
1059 #endif
1060
1061     return (ptr);
1062 }
1063
1064 /* was in parse.c - djhjr - 9/24/02 */
1065 static int ParseUsePPosition(s)
1066 char *s;
1067 {
1068     XmuCopyISOLatin1Lowered (s, s);
1069
1070     if (strcmp(s, "off") == 0)
1071         return PPOS_OFF;
1072     else if (strcmp(s, "on") == 0)
1073         return PPOS_ON;
1074     else if (strcmp(s, "non-zero") == 0 || strcmp(s, "nonzero") == 0)
1075         return PPOS_NON_ZERO;
1076
1077     twmrc_error_prefix();
1078     fprintf(stderr, "ignoring invalid UsePPosition argument \"%s\"\n", s);
1079     return -1;
1080 }
1081
1082 /* djhjr - 10/16/02 */
1083 static int ParseWarpCentered(s)
1084 char *s;
1085 {
1086     XmuCopyISOLatin1Lowered (s, s);
1087
1088     if (strcmp(s, "off") == 0)
1089         return WARPC_OFF;
1090     else if (strcmp(s, "on") == 0)
1091         return WARPC_ON;
1092     else if (strcmp(s, "titled") == 0)
1093         return WARPC_TITLED;
1094     else if (strcmp(s, "untitled") == 0)
1095         return WARPC_UNTITLED;
1096
1097     twmrc_error_prefix();
1098     fprintf(stderr, "ignoring invalid WarpCentered argument \"%s\"\n", s);
1099     return -1;
1100 }
1101
1102 static MenuRoot *GetRoot(name, fore, back)
1103 char *name;
1104 char *fore, *back;
1105 {
1106     MenuRoot *tmp;
1107
1108     tmp = FindMenuRoot(name);
1109     if (tmp == NULL)
1110         tmp = NewMenuRoot(name);
1111
1112     if (fore)
1113     {
1114         int save;
1115
1116         save = Scr->FirstTime;
1117         Scr->FirstTime = TRUE;
1118
1119 /* djhjr - 4/22/96
1120         GetColor(COLOR, &tmp->hi_fore, fore);
1121         GetColor(COLOR, &tmp->hi_back, back);
1122 */
1123         GetColor(COLOR, &tmp->highlight.fore, fore);
1124         GetColor(COLOR, &tmp->highlight.back, back);
1125
1126         Scr->FirstTime = save;
1127     }
1128
1129     return tmp;
1130 }
1131
1132 static void GotButton(butt, func)
1133 int butt, func;
1134 {
1135     int i;
1136
1137     for (i = 0; i < NUM_CONTEXTS; i++)
1138     {
1139         if ((cont & (1 << i)) == 0)
1140             continue;
1141
1142         Scr->Mouse[butt][i][mods].func = func;
1143
1144         if (func == F_MENU)
1145         {
1146             pull->prev = NULL;
1147
1148             Scr->Mouse[butt][i][mods].menu = pull;
1149         }
1150         else
1151         {
1152             root = GetRoot(TWM_ROOT, NULLSTR, NULLSTR);
1153
1154             Scr->Mouse[butt][i][mods].item = AddToMenu(root,"x",Action,
1155                     NULLSTR, func, NULLSTR, NULLSTR);
1156
1157         }
1158     }
1159     Action = "";
1160     pull = NULL;
1161     cont = 0;
1162     mods_used |= mods;
1163     mods = 0;
1164 }
1165
1166 static void GotKey(key, func)
1167 char *key;
1168 int func;
1169 {
1170     int i;
1171
1172     for (i = 0; i < NUM_CONTEXTS; i++)
1173     {
1174         if ((cont & (1 << i)) == 0)
1175           continue;
1176         if (!AddFuncKey(key, i, mods, func, Name, Action))
1177           break;
1178     }
1179
1180     Action = "";
1181     pull = NULL;
1182     cont = 0;
1183     mods_used |= mods;
1184     mods = 0;
1185 }
1186
1187
1188 static void GotTitleButton (bitmapname, func, rightside)
1189     char *bitmapname;
1190     int func;
1191     Bool rightside;
1192 {
1193     if (!CreateTitleButton (bitmapname, func, Action, pull, rightside, True)) {
1194         twmrc_error_prefix();
1195         fprintf (stderr,
1196                  "unable to create %s titlebutton \"%s\"\n",
1197                  rightside ? "right" : "left", bitmapname);
1198     }
1199     Action = "";
1200     pull = NULL;
1201 }
1202
1203 static Bool CheckWarpScreenArg (s)
1204     register char *s;
1205 {
1206     XmuCopyISOLatin1Lowered (s, s);
1207
1208     if (strcmp (s,  WARPSCREEN_NEXT) == 0 ||
1209         strcmp (s,  WARPSCREEN_PREV) == 0 ||
1210         strcmp (s,  WARPSCREEN_BACK) == 0)
1211       return True;
1212
1213     for (; *s && isascii(*s) && isdigit(*s); s++) ; /* SUPPRESS 530 */
1214     return (*s ? False : True);
1215 }
1216
1217
1218 static Bool CheckWarpRingArg (s)
1219     register char *s;
1220 {
1221     XmuCopyISOLatin1Lowered (s, s);
1222
1223     if (strcmp (s,  WARPSCREEN_NEXT) == 0 ||
1224         strcmp (s,  WARPSCREEN_PREV) == 0)
1225       return True;
1226
1227     return False;
1228 }
1229
1230
1231 static Bool CheckColormapArg (s)
1232     register char *s;
1233 {
1234     XmuCopyISOLatin1Lowered (s, s);
1235
1236     if (strcmp (s, COLORMAP_NEXT) == 0 ||
1237         strcmp (s, COLORMAP_PREV) == 0 ||
1238         strcmp (s, COLORMAP_DEFAULT) == 0)
1239       return True;
1240
1241     return False;
1242 }
1243
1244
1245 void twmrc_error_prefix ()
1246 {
1247     fprintf (stderr, "%s:  line %d:  ", ProgramName, yylineno);
1248 }