home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / clients / twm / parse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-11  |  29.7 KB  |  1,072 lines

  1. /*****************************************************************************/
  2. /**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
  3. /**                          Salt Lake City, Utah                           **/
  4. /**  Portions Copyright 1989 by the Massachusetts Institute of Technology   **/
  5. /**                        Cambridge, Massachusetts                         **/
  6. /**                                                                         **/
  7. /**                           All Rights Reserved                           **/
  8. /**                                                                         **/
  9. /**    Permission to use, copy, modify, and distribute this software and    **/
  10. /**    its documentation  for  any  purpose  and  without  fee is hereby    **/
  11. /**    granted, provided that the above copyright notice appear  in  all    **/
  12. /**    copies and that both  that  copyright  notice  and  this  permis-    **/
  13. /**    sion  notice appear in supporting  documentation,  and  that  the    **/
  14. /**    names of Evans & Sutherland and M.I.T. not be used in advertising    **/
  15. /**    in publicity pertaining to distribution of the  software  without    **/
  16. /**    specific, written prior permission.                                  **/
  17. /**                                                                         **/
  18. /**    EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD    **/
  19. /**    TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES  OF  MERCHANT-    **/
  20. /**    ABILITY  AND  FITNESS,  IN  NO  EVENT SHALL EVANS & SUTHERLAND OR    **/
  21. /**    M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL  DAM-    **/
  22. /**    AGES OR  ANY DAMAGES WHATSOEVER  RESULTING FROM LOSS OF USE, DATA    **/
  23. /**    OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER    **/
  24. /**    TORTIOUS ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE    **/
  25. /**    OR PERFORMANCE OF THIS SOFTWARE.                                     **/
  26. /*****************************************************************************/
  27.  
  28.  
  29. /***********************************************************************
  30.  *
  31.  * $XConsortium: parse.c,v 1.52 91/07/12 09:59:37 dave Exp $
  32.  *
  33.  * parse the .twmrc file
  34.  *
  35.  * 17-Nov-87 Thomas E. LaStrange       File created
  36.  * 10-Oct-90 David M. Sternlicht       Storing saved colors on root
  37.  ***********************************************************************/
  38.  
  39. #include <stdio.h>
  40. #include <X11/Xos.h>
  41. #include <X11/Xmu/CharSet.h>
  42. #include "twm.h"
  43. #include "screen.h"
  44. #include "menus.h"
  45. #include "util.h"
  46. #include "gram.h"
  47. #include "parse.h"
  48. #include <X11/Xatom.h> 
  49.  
  50. #ifndef SYSTEM_INIT_FILE
  51. #define SYSTEM_INIT_FILE "/usr/lib/X11/twm/system.twmrc"
  52. #endif
  53. #define BUF_LEN 300
  54.  
  55. static FILE *twmrc;
  56. static int ptr = 0;
  57. static int len = 0;
  58. static char buff[BUF_LEN+1];
  59. static char overflowbuff[20];        /* really only need one */
  60. static int overflowlen;
  61. static char **stringListSource, *currentString;
  62. static int ParseUsePPosition();
  63.  
  64. extern int yylineno;
  65. extern int mods;
  66.  
  67. int ConstrainedMoveTime = 400;        /* milliseconds, event times */
  68.  
  69. static int twmFileInput(), twmStringListInput();
  70. void twmUnput();
  71. int (*twmInputFunc)();
  72.  
  73. extern char *defTwmrc[];        /* default bindings */
  74.  
  75.  
  76. /***********************************************************************
  77.  *
  78.  *  Procedure:
  79.  *    ParseTwmrc - parse the .twmrc file
  80.  *
  81.  *  Inputs:
  82.  *    filename  - the filename to parse.  A NULL indicates $HOME/.twmrc
  83.  *
  84.  ***********************************************************************
  85.  */
  86.  
  87. static int doparse (ifunc, srctypename, srcname)
  88.     int (*ifunc)();
  89.     char *srctypename;
  90.     char *srcname;
  91. {
  92.     mods = 0;
  93.     ptr = 0;
  94.     len = 0;
  95.     yylineno = 1;
  96.     ParseError = FALSE;
  97.     twmInputFunc = ifunc;
  98.     overflowlen = 0;
  99.  
  100.     yyparse();
  101.  
  102.     if (ParseError) {
  103.     fprintf (stderr, "%s:  errors found in twm %s",
  104.          ProgramName, srctypename);
  105.     if (srcname) fprintf (stderr, " \"%s\"", srcname);
  106.     fprintf (stderr, "\n");
  107.     }
  108.     return (ParseError ? 0 : 1);
  109. }
  110.  
  111.  
  112. int ParseTwmrc (filename)
  113.     char *filename;
  114. {
  115.     int i;
  116.     char *home = NULL;
  117.     int homelen = 0;
  118.     char *cp = NULL;
  119.     char tmpfilename[257];
  120.  
  121.     /*
  122.      * If filename given, try it, else try ~/.twmrc.# then ~/.twmrc.  Then
  123.      * try system.twmrc; finally using built-in defaults.
  124.      */
  125.     for (twmrc = NULL, i = 0; !twmrc && i < 4; i++) {
  126.     switch (i) {
  127.       case 0:            /* -f filename */
  128.         cp = filename;
  129.         break;
  130.  
  131.       case 1:            /* ~/.twmrc.screennum */
  132.         if (!filename) {
  133.         home = getenv ("HOME");
  134.         if (home) {
  135.             homelen = strlen (home);
  136.             cp = tmpfilename;
  137.             (void) sprintf (tmpfilename, "%s/.twmrc.%d",
  138.                     home, Scr->screen);
  139.             break;
  140.         }
  141.         }
  142.         continue;
  143.  
  144.       case 2:            /* ~/.twmrc */
  145.         if (home) {
  146.         tmpfilename[homelen + 7] = '\0';
  147.         }
  148.         break;
  149.  
  150.       case 3:            /* system.twmrc */
  151.         cp = SYSTEM_INIT_FILE;
  152.         break;
  153.     }
  154.  
  155.     if (cp) twmrc = fopen (cp, "r");
  156.     }
  157.  
  158.     if (twmrc) {
  159.     int status;
  160.  
  161.     if (filename && cp != filename) {
  162.         fprintf (stderr,
  163.              "%s:  unable to open twmrc file %s, using %s instead\n",
  164.              ProgramName, filename, cp);
  165.     }
  166.     status = doparse (twmFileInput, "file", cp);
  167.     fclose (twmrc);
  168.     return status;
  169.     } else {
  170.     if (filename) {
  171.         fprintf (stderr,
  172.     "%s:  unable to open twmrc file %s, using built-in defaults instead\n",
  173.              ProgramName, filename);
  174.     }
  175.     return ParseStringList (defTwmrc);
  176.     }
  177. }
  178.  
  179. int ParseStringList (sl)
  180.     char **sl;
  181. {
  182.     stringListSource = sl;
  183.     currentString = *sl;
  184.     return doparse (twmStringListInput, "string list", (char *)NULL);
  185. }
  186.  
  187.  
  188. /***********************************************************************
  189.  *
  190.  *  Procedure:
  191.  *    twmFileInput - redefinition of the lex input routine for file input
  192.  *
  193.  *  Returned Value:
  194.  *    the next input character
  195.  *
  196.  ***********************************************************************
  197.  */
  198.  
  199. static int twmFileInput()
  200. {
  201.     if (overflowlen) return (int) overflowbuff[--overflowlen];
  202.  
  203.     while (ptr == len)
  204.     {
  205.     if (fgets(buff, BUF_LEN, twmrc) == NULL)
  206.         return 0;
  207.  
  208.     yylineno++;
  209.  
  210.     ptr = 0;
  211.     len = strlen(buff);
  212.     }
  213.     return ((int)buff[ptr++]);
  214. }
  215.  
  216. static int twmStringListInput()
  217. {
  218.     if (overflowlen) return (int) overflowbuff[--overflowlen];
  219.  
  220.     /*
  221.      * return the character currently pointed to
  222.      */
  223.     if (currentString) {
  224.     unsigned int c = (unsigned int) *currentString++;
  225.  
  226.     if (c) return c;        /* if non-nul char */
  227.     currentString = *++stringListSource;  /* advance to next bol */
  228.     return '\n';            /* but say that we hit last eol */
  229.     }
  230.     return 0;                /* eof */
  231. }
  232.  
  233.  
  234. /***********************************************************************
  235.  *
  236.  *  Procedure:
  237.  *    twmUnput - redefinition of the lex unput routine
  238.  *
  239.  *  Inputs:
  240.  *    c    - the character to push back onto the input stream
  241.  *
  242.  ***********************************************************************
  243.  */
  244.  
  245. void twmUnput (c)
  246.     int c;
  247. {
  248.     if (overflowlen < sizeof overflowbuff) {
  249.     overflowbuff[overflowlen++] = (char) c;
  250.     } else {
  251.     twmrc_error_prefix ();
  252.     fprintf (stderr, "unable to unput character (%d)\n",
  253.          c);
  254.     }
  255. }
  256.  
  257.  
  258. /***********************************************************************
  259.  *
  260.  *  Procedure:
  261.  *    TwmOutput - redefinition of the lex output routine
  262.  *
  263.  *  Inputs:
  264.  *    c    - the character to print
  265.  *
  266.  ***********************************************************************
  267.  */
  268.  
  269. void
  270. TwmOutput(c)
  271. {
  272.     putchar(c);
  273. }
  274.  
  275.  
  276. /**********************************************************************
  277.  *
  278.  *  Parsing table and routines
  279.  * 
  280.  ***********************************************************************/
  281.  
  282. typedef struct _TwmKeyword {
  283.     char *name;
  284.     int value;
  285.     int subnum;
  286. } TwmKeyword;
  287.  
  288. #define kw0_NoDefaults            1
  289. #define kw0_AutoRelativeResize        2
  290. #define kw0_ForceIcons            3
  291. #define kw0_NoIconManagers        4
  292. #define kw0_OpaqueMove            5
  293. #define kw0_InterpolateMenuColors    6
  294. #define kw0_NoVersion            7
  295. #define kw0_SortIconManager        8
  296. #define kw0_NoGrabServer        9
  297. #define kw0_NoMenuShadows        10
  298. #define kw0_NoRaiseOnMove        11
  299. #define kw0_NoRaiseOnResize        12
  300. #define kw0_NoRaiseOnDeiconify        13
  301. #define kw0_DontMoveOff            14
  302. #define kw0_NoBackingStore        15
  303. #define kw0_NoSaveUnders        16
  304. #define kw0_RestartPreviousState    17
  305. #define kw0_ClientBorderWidth        18
  306. #define kw0_NoTitleFocus        19
  307. #define kw0_RandomPlacement        20
  308. #define kw0_DecorateTransients        21
  309. #define kw0_ShowIconManager        22
  310. #define kw0_NoCaseSensitive        23
  311. #define kw0_NoRaiseOnWarp        24
  312. #define kw0_WarpUnmapped        25
  313.  
  314. #define kws_UsePPosition        1
  315. #define kws_IconFont            2
  316. #define kws_ResizeFont            3
  317. #define kws_MenuFont            4
  318. #define kws_TitleFont            5
  319. #define kws_IconManagerFont        6
  320. #define kws_UnknownIcon            7
  321. #define kws_IconDirectory        8
  322. #define kws_MaxWindowSize        9
  323.  
  324. #define kwn_ConstrainedMoveTime        1
  325. #define kwn_MoveDelta            2
  326. #define kwn_XorValue            3
  327. #define kwn_FramePadding        4
  328. #define kwn_TitlePadding        5
  329. #define kwn_ButtonIndent        6
  330. #define kwn_BorderWidth            7
  331. #define kwn_IconBorderWidth        8
  332. #define kwn_TitleButtonBorderWidth    9
  333.  
  334. #define kwcl_BorderColor        1
  335. #define kwcl_IconManagerHighlight    2
  336. #define kwcl_BorderTileForeground    3
  337. #define kwcl_BorderTileBackground    4
  338. #define kwcl_TitleForeground        5
  339. #define kwcl_TitleBackground        6
  340. #define kwcl_IconForeground        7
  341. #define kwcl_IconBackground        8
  342. #define kwcl_IconBorderColor        9
  343. #define kwcl_IconManagerForeground    10
  344. #define kwcl_IconManagerBackground    11
  345.  
  346. #define kwc_DefaultForeground        1
  347. #define kwc_DefaultBackground        2
  348. #define kwc_MenuForeground        3
  349. #define kwc_MenuBackground        4
  350. #define kwc_MenuTitleForeground        5
  351. #define kwc_MenuTitleBackground        6
  352. #define kwc_MenuShadowColor        7
  353.  
  354.  
  355. /*
  356.  * The following is sorted alphabetically according to name (which must be
  357.  * in lowercase and only contain the letters a-z).  It is fed to a binary
  358.  * search to parse keywords.
  359.  */
  360. static TwmKeyword keytable[] = { 
  361.     { "all",            ALL, 0 },
  362.     { "autoraise",        AUTO_RAISE, 0 },
  363.     { "autorelativeresize",    KEYWORD, kw0_AutoRelativeResize },
  364.     { "bordercolor",        CLKEYWORD, kwcl_BorderColor },
  365.     { "bordertilebackground",    CLKEYWORD, kwcl_BorderTileBackground },
  366.     { "bordertileforeground",    CLKEYWORD, kwcl_BorderTileForeground },
  367.     { "borderwidth",        NKEYWORD, kwn_BorderWidth },
  368.     { "button",            BUTTON, 0 },
  369.     { "buttonindent",        NKEYWORD, kwn_ButtonIndent },
  370.     { "c",            CONTROL, 0 },
  371.     { "center",            JKEYWORD, J_CENTER },
  372.     { "clientborderwidth",    KEYWORD, kw0_ClientBorderWidth },
  373.     { "color",            COLOR, 0 },
  374.     { "constrainedmovetime",    NKEYWORD, kwn_ConstrainedMoveTime },
  375.     { "control",        CONTROL, 0 },
  376.     { "cursors",        CURSORS, 0 },
  377.     { "decoratetransients",    KEYWORD, kw0_DecorateTransients },
  378.     { "defaultbackground",    CKEYWORD, kwc_DefaultBackground },
  379.     { "defaultforeground",    CKEYWORD, kwc_DefaultForeground },
  380.     { "defaultfunction",    DEFAULT_FUNCTION, 0 },
  381.     { "destroy",        KILL, 0 },
  382.     { "donticonifybyunmapping",    DONT_ICONIFY_BY_UNMAPPING, 0 },
  383.     { "dontmoveoff",        KEYWORD, kw0_DontMoveOff },
  384.     { "dontsqueezetitle",    DONT_SQUEEZE_TITLE, 0 },
  385.     { "east",            DKEYWORD, D_EAST },
  386.     { "f",            FRAME, 0 },
  387.     { "f.autoraise",        FKEYWORD, F_AUTORAISE },
  388.     { "f.backiconmgr",        FKEYWORD, F_BACKICONMGR },
  389.     { "f.beep",            FKEYWORD, F_BEEP },
  390.     { "f.bottomzoom",        FKEYWORD, F_BOTTOMZOOM },
  391.     { "f.circledown",        FKEYWORD, F_CIRCLEDOWN },
  392.     { "f.circleup",        FKEYWORD, F_CIRCLEUP },
  393.     { "f.colormap",        FSKEYWORD, F_COLORMAP },
  394.     { "f.cut",            FSKEYWORD, F_CUT },
  395.     { "f.cutfile",        FKEYWORD, F_CUTFILE },
  396.     { "f.deiconify",        FKEYWORD, F_DEICONIFY },
  397.     { "f.delete",        FKEYWORD, F_DELETE },
  398.     { "f.deltastop",        FKEYWORD, F_DELTASTOP },
  399.     { "f.destroy",        FKEYWORD, F_DESTROY },
  400.     { "f.downiconmgr",        FKEYWORD, F_DOWNICONMGR },
  401.     { "f.exec",            FSKEYWORD, F_EXEC },
  402.     { "f.file",            FSKEYWORD, F_FILE },
  403.     { "f.focus",        FKEYWORD, F_FOCUS },
  404.     { "f.forcemove",        FKEYWORD, F_FORCEMOVE },
  405.     { "f.forwiconmgr",        FKEYWORD, F_FORWICONMGR },
  406.     { "f.fullzoom",        FKEYWORD, F_FULLZOOM },
  407.     { "f.function",        FSKEYWORD, F_FUNCTION },
  408.     { "f.hbzoom",        FKEYWORD, F_BOTTOMZOOM },
  409.     { "f.hideiconmgr",        FKEYWORD, F_HIDELIST },
  410.     { "f.horizoom",        FKEYWORD, F_HORIZOOM },
  411.     { "f.htzoom",        FKEYWORD, F_TOPZOOM },
  412.     { "f.hzoom",        FKEYWORD, F_HORIZOOM },
  413.     { "f.iconify",        FKEYWORD, F_ICONIFY },
  414.     { "f.identify",        FKEYWORD, F_IDENTIFY },
  415.     { "f.lefticonmgr",        FKEYWORD, F_LEFTICONMGR },
  416.     { "f.leftzoom",        FKEYWORD, F_LEFTZOOM },
  417.     { "f.lower",        FKEYWORD, F_LOWER },
  418.     { "f.menu",            FSKEYWORD, F_MENU },
  419.     { "f.move",            FKEYWORD, F_MOVE },
  420.     { "f.nexticonmgr",        FKEYWORD, F_NEXTICONMGR },
  421.     { "f.nop",            FKEYWORD, F_NOP },
  422.     { "f.previconmgr",        FKEYWORD, F_PREVICONMGR },
  423.     { "f.quit",            FKEYWORD, F_QUIT },
  424.     { "f.raise",        FKEYWORD, F_RAISE },
  425.     { "f.raiselower",        FKEYWORD, F_RAISELOWER },
  426.     { "f.refresh",        FKEYWORD, F_REFRESH },
  427.     { "f.resize",        FKEYWORD, F_RESIZE },
  428.     { "f.restart",        FKEYWORD, F_RESTART },
  429.     { "f.righticonmgr",        FKEYWORD, F_RIGHTICONMGR },
  430.     { "f.rightzoom",        FKEYWORD, F_RIGHTZOOM },
  431.     { "f.saveyourself",        FKEYWORD, F_SAVEYOURSELF },
  432.     { "f.showiconmgr",        FKEYWORD, F_SHOWLIST },
  433.     { "f.sorticonmgr",        FKEYWORD, F_SORTICONMGR },
  434.     { "f.source",        FSKEYWORD, F_BEEP },  /* XXX - don't work */
  435.     { "f.title",        FKEYWORD, F_TITLE },
  436.     { "f.topzoom",        FKEYWORD, F_TOPZOOM },
  437.     { "f.twmrc",        FKEYWORD, F_RESTART },
  438.     { "f.unfocus",        FKEYWORD, F_UNFOCUS },
  439.     { "f.upiconmgr",        FKEYWORD, F_UPICONMGR },
  440.     { "f.version",        FKEYWORD, F_VERSION },
  441.     { "f.vlzoom",        FKEYWORD, F_LEFTZOOM },
  442.     { "f.vrzoom",        FKEYWORD, F_RIGHTZOOM },
  443.     { "f.warpring",        FSKEYWORD, F_WARPRING },
  444.     { "f.warpto",        FSKEYWORD, F_WARPTO },
  445.     { "f.warptoiconmgr",    FSKEYWORD, F_WARPTOICONMGR },
  446.     { "f.warptoscreen",        FSKEYWORD, F_WARPTOSCREEN },
  447.     { "f.winrefresh",        FKEYWORD, F_WINREFRESH },
  448.     { "f.zoom",            FKEYWORD, F_ZOOM },
  449.     { "forceicons",        KEYWORD, kw0_ForceIcons },
  450.     { "frame",            FRAME, 0 },
  451.     { "framepadding",        NKEYWORD, kwn_FramePadding },
  452.     { "function",        FUNCTION, 0 },
  453.     { "i",            ICON, 0 },
  454.     { "icon",            ICON, 0 },
  455.     { "iconbackground",        CLKEYWORD, kwcl_IconBackground },
  456.     { "iconbordercolor",    CLKEYWORD, kwcl_IconBorderColor },
  457.     { "iconborderwidth",    NKEYWORD, kwn_IconBorderWidth },
  458.     { "icondirectory",        SKEYWORD, kws_IconDirectory },
  459.     { "iconfont",        SKEYWORD, kws_IconFont },
  460.     { "iconforeground",        CLKEYWORD, kwcl_IconForeground },
  461.     { "iconifybyunmapping",    ICONIFY_BY_UNMAPPING, 0 },
  462.     { "iconmanagerbackground",    CLKEYWORD, kwcl_IconManagerBackground },
  463.     { "iconmanagerdontshow",    ICONMGR_NOSHOW, 0 },
  464.     { "iconmanagerfont",    SKEYWORD, kws_IconManagerFont },
  465.     { "iconmanagerforeground",    CLKEYWORD, kwcl_IconManagerForeground },
  466.     { "iconmanagergeometry",    ICONMGR_GEOMETRY, 0 },
  467.     { "iconmanagerhighlight",    CLKEYWORD, kwcl_IconManagerHighlight },
  468.     { "iconmanagers",        ICONMGRS, 0 },
  469.     { "iconmanagershow",    ICONMGR_SHOW, 0 },
  470.     { "iconmgr",        ICONMGR, 0 },
  471.     { "iconregion",        ICON_REGION, 0 },
  472.     { "icons",            ICONS, 0 },
  473.     { "interpolatemenucolors",    KEYWORD, kw0_InterpolateMenuColors },
  474.     { "l",            LOCK, 0 },
  475.     { "left",            JKEYWORD, J_LEFT },
  476.     { "lefttitlebutton",    LEFT_TITLEBUTTON, 0 },
  477.     { "lock",            LOCK, 0 },
  478.     { "m",            META, 0 },
  479.     { "maketitle",        MAKE_TITLE, 0 },
  480.     { "maxwindowsize",        SKEYWORD, kws_MaxWindowSize },
  481.     { "menu",            MENU, 0 },
  482.     { "menubackground",        CKEYWORD, kwc_MenuBackground },
  483.     { "menufont",        SKEYWORD, kws_MenuFont },
  484.     { "menuforeground",        CKEYWORD, kwc_MenuForeground },
  485.     { "menushadowcolor",    CKEYWORD, kwc_MenuShadowColor },
  486.     { "menutitlebackground",    CKEYWORD, kwc_MenuTitleBackground },
  487.     { "menutitleforeground",    CKEYWORD, kwc_MenuTitleForeground },
  488.     { "meta",            META, 0 },
  489.     { "mod",            META, 0 },  /* fake it */
  490.     { "monochrome",        MONOCHROME, 0 },
  491.     { "move",            MOVE, 0 },
  492.     { "movedelta",        NKEYWORD, kwn_MoveDelta },
  493.     { "nobackingstore",        KEYWORD, kw0_NoBackingStore },
  494.     { "nocasesensitive",    KEYWORD, kw0_NoCaseSensitive },
  495.     { "nodefaults",        KEYWORD, kw0_NoDefaults },
  496.     { "nograbserver",        KEYWORD, kw0_NoGrabServer },
  497.     { "nohighlight",        NO_HILITE, 0 },
  498.     { "noiconmanagers",        KEYWORD, kw0_NoIconManagers },
  499.     { "nomenushadows",        KEYWORD, kw0_NoMenuShadows },
  500.     { "noraiseondeiconify",    KEYWORD, kw0_NoRaiseOnDeiconify },
  501.     { "noraiseonmove",        KEYWORD, kw0_NoRaiseOnMove },
  502.     { "noraiseonresize",    KEYWORD, kw0_NoRaiseOnResize },
  503.     { "noraiseonwarp",        KEYWORD, kw0_NoRaiseOnWarp },
  504.     { "north",            DKEYWORD, D_NORTH },
  505.     { "nosaveunders",        KEYWORD, kw0_NoSaveUnders },
  506.     { "nostackmode",        NO_STACKMODE, 0 },
  507.     { "notitle",        NO_TITLE, 0 },
  508.     { "notitlefocus",        KEYWORD, kw0_NoTitleFocus },
  509.     { "notitlehighlight",    NO_TITLE_HILITE, 0 },
  510.     { "noversion",        KEYWORD, kw0_NoVersion },
  511.     { "opaquemove",        KEYWORD, kw0_OpaqueMove },
  512.     { "pixmaps",        PIXMAPS, 0 },
  513.     { "r",            ROOT, 0 },
  514.     { "randomplacement",    KEYWORD, kw0_RandomPlacement },
  515.     { "resize",            RESIZE, 0 },
  516.     { "resizefont",        SKEYWORD, kws_ResizeFont },
  517.     { "restartpreviousstate",    KEYWORD, kw0_RestartPreviousState },
  518.     { "right",            JKEYWORD, J_RIGHT },
  519.     { "righttitlebutton",    RIGHT_TITLEBUTTON, 0 },
  520.     { "root",            ROOT, 0 },
  521.     { "s",            SHIFT, 0 },
  522.     { "savecolor",              SAVECOLOR, 0},
  523.     { "select",            SELECT, 0 },
  524.     { "shift",            SHIFT, 0 },
  525.     { "showiconmanager",    KEYWORD, kw0_ShowIconManager },
  526.     { "sorticonmanager",    KEYWORD, kw0_SortIconManager },
  527.     { "south",            DKEYWORD, D_SOUTH },
  528.     { "squeezetitle",        SQUEEZE_TITLE, 0 },
  529.     { "starticonified",        START_ICONIFIED, 0 },
  530.     { "t",            TITLE, 0 },
  531.     { "title",            TITLE, 0 },
  532.     { "titlebackground",    CLKEYWORD, kwcl_TitleBackground },
  533.     { "titlebuttonborderwidth",    NKEYWORD, kwn_TitleButtonBorderWidth },
  534.     { "titlefont",        SKEYWORD, kws_TitleFont },
  535.     { "titleforeground",    CLKEYWORD, kwcl_TitleForeground },
  536.     { "titlehighlight",        TITLE_HILITE, 0 },
  537.     { "titlepadding",        NKEYWORD, kwn_TitlePadding },
  538.     { "unknownicon",        SKEYWORD, kws_UnknownIcon },
  539.     { "usepposition",        SKEYWORD, kws_UsePPosition },
  540.     { "w",            WINDOW, 0 },
  541.     { "wait",            WAIT, 0 },
  542.     { "warpcursor",        WARP_CURSOR, 0 },
  543.     { "warpunmapped",        KEYWORD, kw0_WarpUnmapped },
  544.     { "west",            DKEYWORD, D_WEST },
  545.     { "window",            WINDOW, 0 },
  546.     { "windowfunction",        WINDOW_FUNCTION, 0 },
  547.     { "windowring",        WINDOW_RING, 0 },
  548.     { "xorvalue",        NKEYWORD, kwn_XorValue },
  549.     { "zoom",            ZOOM, 0 },
  550. };
  551.  
  552. static int numkeywords = (sizeof(keytable)/sizeof(keytable[0]));
  553.  
  554. int parse_keyword (s, nump)
  555.     char *s;
  556.     int *nump;
  557. {
  558.     register int lower = 0, upper = numkeywords - 1;
  559.  
  560.     XmuCopyISOLatin1Lowered (s, s);
  561.     while (lower <= upper) {
  562.         int middle = (lower + upper) / 2;
  563.     TwmKeyword *p = &keytable[middle];
  564.         int res = strcmp (p->name, s);
  565.  
  566.         if (res < 0) {
  567.             lower = middle + 1;
  568.         } else if (res == 0) {
  569.         *nump = p->subnum;
  570.             return p->value;
  571.         } else {
  572.             upper = middle - 1;
  573.         }
  574.     }
  575.     return ERRORTOKEN;
  576. }
  577.  
  578.  
  579.  
  580. /*
  581.  * action routines called by grammar
  582.  */
  583.  
  584. int do_single_keyword (keyword)
  585.     int keyword;
  586. {
  587.     switch (keyword) {
  588.       case kw0_NoDefaults:
  589.     Scr->NoDefaults = TRUE;
  590.     return 1;
  591.  
  592.       case kw0_AutoRelativeResize:
  593.     Scr->AutoRelativeResize = TRUE;
  594.     return 1;
  595.  
  596.       case kw0_ForceIcons:
  597.     if (Scr->FirstTime) Scr->ForceIcon = TRUE;
  598.     return 1;
  599.  
  600.       case kw0_NoIconManagers:
  601.     Scr->NoIconManagers = TRUE;
  602.     return 1;
  603.  
  604.       case kw0_OpaqueMove:
  605.     Scr->OpaqueMove = TRUE;
  606.     return 1;
  607.  
  608.       case kw0_InterpolateMenuColors:
  609.     if (Scr->FirstTime) Scr->InterpolateMenuColors = TRUE;
  610.     return 1;
  611.  
  612.       case kw0_NoVersion:
  613.     /* obsolete */
  614.     return 1;
  615.  
  616.       case kw0_SortIconManager:
  617.     if (Scr->FirstTime) Scr->SortIconMgr = TRUE;
  618.     return 1;
  619.  
  620.       case kw0_NoGrabServer:
  621.     Scr->NoGrabServer = TRUE;
  622.     return 1;
  623.  
  624.       case kw0_NoMenuShadows:
  625.     if (Scr->FirstTime) Scr->Shadow = FALSE;
  626.     return 1;
  627.  
  628.       case kw0_NoRaiseOnMove:
  629.     if (Scr->FirstTime) Scr->NoRaiseMove = TRUE;
  630.     return 1;
  631.  
  632.       case kw0_NoRaiseOnResize:
  633.     if (Scr->FirstTime) Scr->NoRaiseResize = TRUE;
  634.     return 1;
  635.  
  636.       case kw0_NoRaiseOnDeiconify:
  637.     if (Scr->FirstTime) Scr->NoRaiseDeicon = TRUE;
  638.     return 1;
  639.  
  640.       case kw0_DontMoveOff:
  641.     Scr->DontMoveOff = TRUE;
  642.     return 1;
  643.  
  644.       case kw0_NoBackingStore:
  645.     Scr->BackingStore = FALSE;
  646.     return 1;
  647.  
  648.       case kw0_NoSaveUnders:
  649.     Scr->SaveUnder = FALSE;
  650.     return 1;
  651.  
  652.       case kw0_RestartPreviousState:
  653.     RestartPreviousState = True;
  654.     return 1;
  655.  
  656.       case kw0_ClientBorderWidth:
  657.     if (Scr->FirstTime) Scr->ClientBorderWidth = TRUE;
  658.     return 1;
  659.  
  660.       case kw0_NoTitleFocus:
  661.     Scr->TitleFocus = FALSE;
  662.     return 1;
  663.  
  664.       case kw0_RandomPlacement:
  665.     Scr->RandomPlacement = TRUE;
  666.     return 1;
  667.  
  668.       case kw0_DecorateTransients:
  669.     Scr->DecorateTransients = TRUE;
  670.     return 1;
  671.  
  672.       case kw0_ShowIconManager:
  673.     Scr->ShowIconManager = TRUE;
  674.     return 1;
  675.  
  676.       case kw0_NoCaseSensitive:
  677.     Scr->CaseSensitive = FALSE;
  678.     return 1;
  679.  
  680.       case kw0_NoRaiseOnWarp:
  681.     Scr->NoRaiseWarp = TRUE;
  682.     return 1;
  683.  
  684.       case kw0_WarpUnmapped:
  685.     Scr->WarpUnmapped = TRUE;
  686.     return 1;
  687.     }
  688.  
  689.     return 0;
  690. }
  691.  
  692.  
  693. int do_string_keyword (keyword, s)
  694.     int keyword;
  695.     char *s;
  696. {
  697.     switch (keyword) {
  698.       case kws_UsePPosition:
  699.     { 
  700.         int ppos = ParseUsePPosition (s);
  701.         if (ppos < 0) {
  702.         twmrc_error_prefix();
  703.         fprintf (stderr,
  704.              "ignoring invalid UsePPosition argument \"%s\"\n", s);
  705.         } else {
  706.         Scr->UsePPosition = ppos;
  707.         }
  708.         return 1;
  709.     }
  710.  
  711.       case kws_IconFont:
  712.     if (!Scr->HaveFonts) Scr->IconFont.name = s;
  713.     return 1;
  714.  
  715.       case kws_ResizeFont:
  716.     if (!Scr->HaveFonts) Scr->SizeFont.name = s;
  717.     return 1;
  718.  
  719.       case kws_MenuFont:
  720.     if (!Scr->HaveFonts) Scr->MenuFont.name = s;
  721.     return 1;
  722.  
  723.       case kws_TitleFont:
  724.     if (!Scr->HaveFonts) Scr->TitleBarFont.name = s;
  725.     return 1;
  726.  
  727.       case kws_IconManagerFont:
  728.     if (!Scr->HaveFonts) Scr->IconManagerFont.name = s;
  729.     return 1;
  730.  
  731.       case kws_UnknownIcon:
  732.     if (Scr->FirstTime) GetUnknownIcon (s);
  733.     return 1;
  734.  
  735.       case kws_IconDirectory:
  736.     if (Scr->FirstTime) Scr->IconDirectory = ExpandFilename (s);
  737.     return 1;
  738.  
  739.       case kws_MaxWindowSize:
  740.     JunkMask = XParseGeometry (s, &JunkX, &JunkY, &JunkWidth, &JunkHeight);
  741.     if ((JunkMask & (WidthValue | HeightValue)) != 
  742.         (WidthValue | HeightValue)) {
  743.         twmrc_error_prefix();
  744.         fprintf (stderr, "bad MaxWindowSize \"%s\"\n", s);
  745.         return 0;
  746.     }
  747.     if (JunkWidth <= 0 || JunkHeight <= 0) {
  748.         twmrc_error_prefix();
  749.         fprintf (stderr, "MaxWindowSize \"%s\" must be positive\n", s);
  750.         return 0;
  751.     }
  752.     Scr->MaxWindowWidth = JunkWidth;
  753.     Scr->MaxWindowHeight = JunkHeight;
  754.     return 1;
  755.     }
  756.  
  757.     return 0;
  758. }
  759.  
  760.  
  761. int do_number_keyword (keyword, num)
  762.     int keyword;
  763.     int num;
  764. {
  765.     switch (keyword) {
  766.       case kwn_ConstrainedMoveTime:
  767.     ConstrainedMoveTime = num;
  768.     return 1;
  769.  
  770.       case kwn_MoveDelta:
  771.     Scr->MoveDelta = num;
  772.     return 1;
  773.  
  774.       case kwn_XorValue:
  775.     if (Scr->FirstTime) Scr->XORvalue = num;
  776.     return 1;
  777.  
  778.       case kwn_FramePadding:
  779.     if (Scr->FirstTime) Scr->FramePadding = num;
  780.     return 1;
  781.  
  782.       case kwn_TitlePadding:
  783.     if (Scr->FirstTime) Scr->TitlePadding = num;
  784.     return 1;
  785.  
  786.       case kwn_ButtonIndent:
  787.     if (Scr->FirstTime) Scr->ButtonIndent = num;
  788.     return 1;
  789.  
  790.       case kwn_BorderWidth:
  791.     if (Scr->FirstTime) Scr->BorderWidth = num;
  792.     return 1;
  793.  
  794.       case kwn_IconBorderWidth:
  795.     if (Scr->FirstTime) Scr->IconBorderWidth = num;
  796.     return 1;
  797.  
  798.       case kwn_TitleButtonBorderWidth:
  799.     if (Scr->FirstTime) Scr->TBInfo.border = num;
  800.     return 1;
  801.  
  802.     }
  803.  
  804.     return 0;
  805. }
  806.  
  807. name_list **do_colorlist_keyword (keyword, colormode, s)
  808.     int keyword;
  809.     int colormode;
  810.     char *s;
  811. {
  812.     switch (keyword) {
  813.       case kwcl_BorderColor:
  814.     GetColor (colormode, &Scr->BorderColor, s);
  815.     return &Scr->BorderColorL;
  816.  
  817.       case kwcl_IconManagerHighlight:
  818.     GetColor (colormode, &Scr->IconManagerHighlight, s);
  819.     return &Scr->IconManagerHighlightL;
  820.  
  821.       case kwcl_BorderTileForeground:
  822.     GetColor (colormode, &Scr->BorderTileC.fore, s);
  823.     return &Scr->BorderTileForegroundL;
  824.  
  825.       case kwcl_BorderTileBackground:
  826.     GetColor (colormode, &Scr->BorderTileC.back, s);
  827.     return &Scr->BorderTileBackgroundL;
  828.  
  829.       case kwcl_TitleForeground:
  830.     GetColor (colormode, &Scr->TitleC.fore, s);
  831.     return &Scr->TitleForegroundL;
  832.  
  833.       case kwcl_TitleBackground:
  834.     GetColor (colormode, &Scr->TitleC.back, s);
  835.     return &Scr->TitleBackgroundL;
  836.  
  837.       case kwcl_IconForeground:
  838.     GetColor (colormode, &Scr->IconC.fore, s);
  839.     return &Scr->IconForegroundL;
  840.  
  841.       case kwcl_IconBackground:
  842.     GetColor (colormode, &Scr->IconC.back, s);
  843.     return &Scr->IconBackgroundL;
  844.  
  845.       case kwcl_IconBorderColor:
  846.     GetColor (colormode, &Scr->IconBorderColor, s);
  847.     return &Scr->IconBorderColorL;
  848.  
  849.       case kwcl_IconManagerForeground:
  850.     GetColor (colormode, &Scr->IconManagerC.fore, s);
  851.     return &Scr->IconManagerFL;
  852.  
  853.       case kwcl_IconManagerBackground:
  854.     GetColor (colormode, &Scr->IconManagerC.back, s);
  855.     return &Scr->IconManagerBL;
  856.     }
  857.     return NULL;
  858. }
  859.  
  860. int do_color_keyword (keyword, colormode, s)
  861.     int keyword;
  862.     int colormode;
  863.     char *s;
  864. {
  865.     switch (keyword) {
  866.       case kwc_DefaultForeground:
  867.     GetColor (colormode, &Scr->DefaultC.fore, s);
  868.     return 1;
  869.  
  870.       case kwc_DefaultBackground:
  871.     GetColor (colormode, &Scr->DefaultC.back, s);
  872.     return 1;
  873.  
  874.       case kwc_MenuForeground:
  875.     GetColor (colormode, &Scr->MenuC.fore, s);
  876.     return 1;
  877.  
  878.       case kwc_MenuBackground:
  879.     GetColor (colormode, &Scr->MenuC.back, s);
  880.     return 1;
  881.  
  882.       case kwc_MenuTitleForeground:
  883.     GetColor (colormode, &Scr->MenuTitleC.fore, s);
  884.     return 1;
  885.  
  886.       case kwc_MenuTitleBackground:
  887.     GetColor (colormode, &Scr->MenuTitleC.back, s);
  888.     return 1;
  889.  
  890.       case kwc_MenuShadowColor:
  891.     GetColor (colormode, &Scr->MenuShadowColor, s);
  892.     return 1;
  893.  
  894.     }
  895.  
  896.     return 0;
  897. }
  898.  
  899. /*
  900.  * put_pixel_on_root() Save a pixel value in twm root window color property.
  901.  */
  902. put_pixel_on_root(pixel)                                 
  903.     Pixel pixel;                                         
  904. {                                                        
  905.   int           i, addPixel = 1;
  906.   Atom          pixelAtom, retAtom;                     
  907.   int           retFormat;
  908.   unsigned long nPixels, retAfter;                     
  909.   Pixel        *retProp;
  910.   pixelAtom = XInternAtom(dpy, "_MIT_PRIORITY_COLORS", True);        
  911.   XGetWindowProperty(dpy, Scr->Root, pixelAtom, 0, 8192, 
  912.              False, XA_CARDINAL, &retAtom,       
  913.              &retFormat, &nPixels, &retAfter,    
  914.              (unsigned char **)&retProp);
  915.  
  916.   for (i=0; i< nPixels; i++)                             
  917.       if (pixel == retProp[i]) addPixel = 0;             
  918.                                                          
  919.   if (addPixel)                                          
  920.       XChangeProperty (dpy, Scr->Root, _XA_MIT_PRIORITY_COLORS,
  921.                XA_CARDINAL, 32, PropModeAppend,  
  922.                (unsigned char *)&pixel, 1);                       
  923. }                                                        
  924.  
  925. /*
  926.  * do_string_savecolor() save a color from a string in the twmrc file.
  927.  */
  928. int do_string_savecolor(colormode, s)
  929.      int colormode;
  930.      char *s;
  931. {
  932.   Pixel p;
  933.   GetColor(colormode, &p, s);
  934.   put_pixel_on_root(p);
  935. }
  936.  
  937. /*
  938.  * do_var_savecolor() save a color from a var in the twmrc file.
  939.  */
  940. typedef struct _cnode {int i; struct _cnode *next;} Cnode, *Cptr;
  941. Cptr chead = NULL;
  942.  
  943. int do_var_savecolor(key)
  944. int key;
  945. {
  946.   Cptr cptrav, cpnew;
  947.   if (!chead) {
  948.     chead = (Cptr)malloc(sizeof(Cnode));
  949.     chead->i = key; chead->next = NULL;
  950.   }
  951.   else {
  952.     cptrav = chead;
  953.     while (cptrav->next != NULL) { cptrav = cptrav->next; }
  954.     cpnew = (Cptr)malloc(sizeof(Cnode));
  955.     cpnew->i = key; cpnew->next = NULL; cptrav->next = cpnew;
  956.   }
  957. }
  958.  
  959. /*
  960.  * assign_var_savecolor() traverse the var save color list placeing the pixels
  961.  *                        in the root window property.
  962.  */
  963. void assign_var_savecolor()
  964. {
  965.   Cptr cp = chead;
  966.   while (cp != NULL) {
  967.     switch (cp->i) {
  968.     case kwcl_BorderColor:
  969.       put_pixel_on_root(Scr->BorderColor);
  970.       break;
  971.     case kwcl_IconManagerHighlight:
  972.       put_pixel_on_root(Scr->IconManagerHighlight);
  973.       break;
  974.     case kwcl_BorderTileForeground:
  975.       put_pixel_on_root(Scr->BorderTileC.fore);
  976.       break;
  977.     case kwcl_BorderTileBackground:
  978.       put_pixel_on_root(Scr->BorderTileC.back);
  979.       break;
  980.     case kwcl_TitleForeground:
  981.       put_pixel_on_root(Scr->TitleC.fore);
  982.       break;
  983.     case kwcl_TitleBackground:
  984.       put_pixel_on_root(Scr->TitleC.back);
  985.       break;
  986.     case kwcl_IconForeground:
  987.       put_pixel_on_root(Scr->IconC.fore);
  988.       break;
  989.     case kwcl_IconBackground:
  990.       put_pixel_on_root(Scr->IconC.back);
  991.       break;
  992.     case kwcl_IconBorderColor:
  993.       put_pixel_on_root(Scr->IconBorderColor);
  994.       break;
  995.     case kwcl_IconManagerForeground:
  996.       put_pixel_on_root(Scr->IconManagerC.fore);
  997.       break;
  998.     case kwcl_IconManagerBackground:
  999.       put_pixel_on_root(Scr->IconManagerC.back);
  1000.       break;
  1001.     }
  1002.     cp = cp->next;
  1003.   }
  1004.   if (chead) {
  1005.     free(chead);
  1006.     chead = NULL;
  1007.   }
  1008. }
  1009.  
  1010. static int ParseUsePPosition (s)
  1011.     register char *s;
  1012. {
  1013.     XmuCopyISOLatin1Lowered (s, s);
  1014.  
  1015.     if (strcmp (s, "off") == 0) {
  1016.     return PPOS_OFF;
  1017.     } else if (strcmp (s, "on") == 0) {
  1018.     return PPOS_ON;
  1019.     } else if (strcmp (s, "non-zero") == 0 ||
  1020.            strcmp (s, "nonzero") == 0) {
  1021.     return PPOS_NON_ZERO;
  1022.     }
  1023.  
  1024.     return -1;
  1025. }
  1026.  
  1027.  
  1028. do_squeeze_entry (list, name, justify, num, denom)
  1029.     name_list **list;            /* squeeze or dont-squeeze list */
  1030.     char *name;                /* window name */
  1031.     int justify;            /* left, center, right */
  1032.     int num;                /* signed num */
  1033.     int denom;                /* 0 or indicates fraction denom */
  1034. {
  1035.     int absnum = (num < 0 ? -num : num);
  1036.  
  1037.     if (denom < 0) {
  1038.     twmrc_error_prefix();
  1039.     fprintf (stderr, "negative SqueezeTitle denominator %d\n", denom);
  1040.     return;
  1041.     }
  1042.     if (absnum > denom && denom != 0) {
  1043.     twmrc_error_prefix();
  1044.     fprintf (stderr, "SqueezeTitle fraction %d/%d outside window\n",
  1045.          num, denom);
  1046.     return;
  1047.     }
  1048.     if (denom == 1) {
  1049.     twmrc_error_prefix();
  1050.     fprintf (stderr, "useless SqueezeTitle faction %d/%d, assuming 0/0\n",
  1051.          num, denom);
  1052.     num = 0;
  1053.     denom = 0;
  1054.     }
  1055.  
  1056.     if (HasShape) {
  1057.     SqueezeInfo *sinfo;
  1058.     sinfo = (SqueezeInfo *) malloc (sizeof(SqueezeInfo));
  1059.  
  1060.     if (!sinfo) {
  1061.         twmrc_error_prefix();
  1062.         fprintf (stderr, "unable to allocate %d bytes for squeeze info\n",
  1063.              sizeof(SqueezeInfo));
  1064.         return;
  1065.     }
  1066.     sinfo->justify = justify;
  1067.     sinfo->num = num;
  1068.     sinfo->denom = denom;
  1069.     AddToList (list, name, (char *) sinfo);
  1070.     }
  1071. }
  1072.