v00i011: Ardent Window Manager(X11), Part10/13
Mike Wexler
mikew at wyse.wyse.com
Thu Aug 11 08:00:12 AEST 1988
Submitted-by: unido!pcsbst!jkh (Jordan Hubbard)
Posting-number: Volume 0, Issue 11
Archive-name: awm/part10
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 10 (of 13)."
# Contents: awm/gram.y
# Wrapped by mikew at wyse on Mon Aug 8 12:01:47 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f awm/gram.y -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"awm/gram.y\"
else
echo shar: Extracting \"awm/gram.y\" \(26836 characters\)
sed "s/^X//" >awm/gram.y <<'END_OF_awm/gram.y'
X/*
X *
X * Copyright 1987, 1988 by Ardent Computer Corporation, Sunnyvale, Ca.
X *
X * Copyright 1987 by Jordan Hubbard.
X *
X *
X * All Rights Reserved
X *
X * Permission to use, copy, modify, and distribute this software and its
X * documentation for any purpose and without fee is hereby granted,
X * provided that the above copyright notice appear in all copies and that
X * both that copyright notice and this permission notice appear in
X * supporting documentation, and that the name of Ardent Computer
X * Corporation or Jordan Hubbard not be used in advertising or publicity
X * pertaining to distribution of the software without specific, written
X * prior permission.
X *
X */
X
X/*
X * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
X *
X * All Rights Reserved
X *
X * Permission to use, copy, modify, and distribute this software and its
X * documentation for any purpose and without fee is hereby granted,
X * provided that the above copyright notice appear in all copies and that
X * both that copyright notice and this permission notice appear in
X * supporting documentation, and that the name of Digital Equipment
X * Corporation not be used in advertising or publicity pertaining to
X * distribution of the software without specific, written prior permission.
X *
X *
X * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
X * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
X * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
X * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
X * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
X * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
X * SOFTWARE.
X */
X
X
X/*
X * MODIFICATION HISTORY
X *
X * 000 -- M. Gancarz, DEC Ultrix Engineering Group
X * 001 -- Loretta Guarino Reid, DEC Ultrix Engineering Group
X * Western Software Lab. Convert to X11.
X * 002 -- Jordan Hubbard, U.C. Berkeley. New keywords. Menu
X * changes, gadget boxes, title bars, the kitchen sink.
X */
X
X%{
X
X#ident "%W% %G%"
X
X
X
X#ifndef lint
Xstatic char *rcsid_gram_y = "$Header: gram.y,v 1.4 88/07/24 01:01:04 jkh Exp $";
X#endif lint
X
X#include "X11/Xlib.h"
X#include "X11/Xutil.h"
X#include "awm.h"
X#include <signal.h>
X
X/*
X * Values returned by complex expression parser.
X */
X#define C_STRING 1 /* IsString. */
X#define C_MENU 2 /* IsMenu. */
X#define C_MAP 3 /* IsMap. */
X#define C_MENUMAP 4 /* IsMenuMap */
X#define C_PIXMAP 5 /* IsPixmap */
X#define C_ACTION 6 /* IsAction */
X
X static int ki; /* Keyword index. */
X static int gadgnum; /* # of gadget we're initing */
X static int g_offset; /* The gadget offset specified */
X static int g_gravity; /* The gadget gravity specified */
X static char *g_forecolor; /* gadget foreground color */
X static char *g_backcolor; /* gadget background color */
X static XFontStruct *g_font; /* gadget font */
X static int bkmask; /* Button/key mask. */
X static int cmask; /* Context mask. */
X static char msg[BUFSIZ]; /* Error message buffer. */
X static char *menu_name; /* Menu name. */
X static char *menu_pixmap; /* Name of pixmap for menu label */
X static MenuInfo *menu_info; /* Menu info. */
X static ActionLine *ml_ptr; /* Temporary menu line pointer. */
X static ActionLine *action; /* Temporary action pointer */
X MenuLink *menu_link; /* Temporary menu link pointer. */
X GadgetDecl **Gadgets; /* Pointer to gadget info structs */
X char *calloc();
X
X %}
X
X%union {
X char *sval;
X int ival;
X short shval;
X struct _actionline *alval;
X struct _menuinfo *mival;
X char **cval;
X}
X
X%token NL
X %token <sval> STRING
X %token <ival> COMMENT
X %type <sval> pixmap_file
X %type <ival> gadget_subscript
X %type <ival> keyword
X %type <ival> compexpr
X %type <ival> keyexpr
X %type <ival> kmask
X %type <ival> contexpr
X %type <ival> contmask
X %type <ival> buttmodexpr
X %type <ival> buttmodifier
X %type <ival> buttexpr
X %type <sval> menuname
X %type <sval> strings
X %type <alval> textaction
X %type <alval> menuexpr
X %type <alval> menulist
X %type <alval> menuline
X %type <alval> menuaction
X
X %% /* beginning of rules section */
X
X input: | input command
X | input error command { yyerrok; }
X;
X
X command: boolvar term
X | expr term
X | COMMENT { Lineno++; }
X | term
X ;
X
X term: NL { Lineno++; }
X| ';'
X ;
X
X expr: keyword '=' compexpr
X{
X switch (KeywordTable[$1].type) {
X case IsQuitFunction:
X case IsFunction:
X if ($3 == C_MAP) {
X bindtofunc($1, bkmask, cmask, NULL);
X } else yyerror("illegal construct");
X break;
X
X case IsDownFunction:
X if (bkmask & ButtonUp) {
X sprintf(msg,
X "cannot bind %s to button up",
X KeywordTable[$1].name);
X yyerror(msg);
X }
X if ($3 == C_MAP) {
X bindtofunc($1, bkmask, cmask, NULL);
X } else yyerror("illegal construct");
X break;
X
X case IsMenuMap:
X if (bkmask & ButtonUp) {
X sprintf(msg,
X "cannot bind %s to button up",
X KeywordTable[$1].name);
X yyerror(msg);
X }
X if ($3 == C_MENUMAP) {
X bindtofunc
X ($1, bkmask, cmask, menu_name);
X } else yyerror("illegal construct");
X break;
X
X case IsAction:
X if ($3 == C_ACTION) {
X /*
X * We pass a structure pointer here where a char pointer
X * is supposed to go. It was a hack, what can I say.
X */
X bindtofunc
X ($1, bkmask, cmask, (char *)action);
X } else yyerror("illegal construct");
X break;
X
X case IsMenu:
X if ($3 == C_MENU) {
X /*
X * create a menu definition entry.
X */
X menu_info = stashmenuinfo(menu_name, ml_ptr, menu_pixmap);
X menu_link = stashmenulink(menu_info);
X Menus = appendmenulink(Menus, menu_link);
X } else yyerror("illegal menu construct");
X break;
X
X case IsGadget:
X if (gadgnum < 0) {
X sprintf(msg, "Gadget number must be >= 0\n");
X yyerror(msg);
X }
X /* Bump NumGadgets if necessary */
X else if (gadgnum >= NumGadgets)
X NumGadgets = gadgnum + 1;
X if (NumGadgets > MAX_GADGETS) {
X sprintf(msg, "\"numgadgets\" (%d) is > MAX_GADGETS (%d)\n",
X NumGadgets, MAX_GADGETS);
X yyerror(msg);
X }
X else {
X if ($3 != C_STRING && $3 != C_PIXMAP)
X yyerror("Illegal gadget assignment");
X else
X stashGadget(gadgnum, yylval.sval, $3);
X }
X break;
X
X default:
X yyerror("internal binding error");
X break;
X }
X}
X;
X pixmap_file: '(' STRING ')' {
X $$ = $2;
X }
X;
X compexpr: keyexpr ':' contexpr ':' buttexpr
X{
X $$ = C_MAP;
X bkmask = $1 | $5;
X cmask = $3;
X}
X| keyexpr ':' contexpr ':' buttexpr ':' menuname
X{
X $$ = C_MENUMAP;
X bkmask = $1 | $5;
X cmask = $3;
X menu_name = $7;
X}
X| keyexpr ':' contexpr ':' buttexpr ':' textaction
X{
X $$ = C_ACTION;
X bkmask = $1 | $5;
X cmask = $3;
X action = $7;
X}
X| STRING menuexpr
X{
X $$ = C_MENU;
X menu_name = $1;
X menu_pixmap = 0;
X ml_ptr = $2;
X}
X| pixmap_file STRING menuexpr
X{
X $$ = C_MENU;
X menu_name = $2;
X menu_pixmap = $1;
X ml_ptr = $3;
X}
X| STRING '^' gadgetspec
X{ yylval.sval = $1; $$ = C_STRING; }
X| pixmap_file '^' gadgetspec
X{ yylval.sval = $1; $$ = C_PIXMAP; }
X| STRING
X{
X $$ = C_STRING;
X /* just in case it's a gadget, set defaults */
X g_forecolor = Foreground;
X g_backcolor = Background;
X g_gravity = NoGadgetGravity;
X g_offset = 0;
X g_font = 0;
X}
X| pixmap_file
X{
X $$ = C_PIXMAP;
X /* just in case it's a gadget, set defaults */
X g_forecolor = Foreground;
X g_backcolor = Background;
X g_gravity = NoGadgetGravity;
X g_offset = 0;
X g_font = 0;
X}
X;
X gadgetspec: offset
X| offset '|' gravity
X| offset '|' gravity '|' forecolor
X| offset '|' gravity '|' forecolor '|' backcolor
X| offset '|' gravity '|' forecolor '|' backcolor '|' fontspec
X;
X offset: /* empty */
X{ g_offset = 0; }
X| STRING
X{
X g_offset = y_atoi($1);
X g_gravity = NoGadgetGravity;
X g_forecolor = Foreground;
X g_backcolor = Background;
X g_font = (XFontStruct *)NULL;
X}
X;
X gravity: /* empty */
X{ g_gravity = NoGadgetGravity; }
X| STRING
X{
X g_gravity = gravitylookup($1);
X g_forecolor = Foreground;
X g_backcolor = Background;
X g_font = (XFontStruct *)NULL;
X}
X;
X forecolor: /* empty */
X{ g_forecolor = Foreground; }
X| STRING
X{
X g_forecolor = $1;
X g_backcolor = Background;
X g_font = (XFontStruct *)NULL;
X}
X;
X backcolor: /* empty */
X{ g_backcolor = Background; }
X| STRING
X{
X g_backcolor = $1;
X g_font = (XFontStruct *)NULL;
X}
X;
X fontspec: /* empty */
X{ g_font = 0; }
X| STRING
X{
X g_font = XLoadQueryFont(dpy, $1);
X if (!g_font) {
X sprintf(msg, "Can't open gadget font '%s'\n", $1);
X yywarn(msg);
X }
X}
X;
X
X boolvar: STRING
X{
X ki = keywordlookup(yylval.sval);
X switch (KeywordTable[ki].type) {
X case IsParser:
X (*KeywordTable[ki].fptr)();
X break;
X default:
X yyerror("keyword error");
X }
X}
X;
X
X keyword: STRING {
X $$ = keywordlookup(yylval.sval);
X }
X| STRING gadget_subscript {
X $$ = keywordlookup("gadget");
X gadgnum = $2;
X}
X;
X
X gadget_subscript: '[' STRING ']' {
X $$ = y_atoi(yylval.sval);
X }
X;
X
X keyexpr: /* empty */
X{ $$ = 0; }
X| kmask
X{ $$ = $1; }
X| kmask '|' keyexpr
X{ $$ = $1 | $3; }
X;
X
X contexpr: /* empty */
X{ $$ = 0xffffffff; }
X| contmask
X{ $$ = $1; }
X| contmask '|' contexpr
X{ $$ = $1 | $3; }
X;
X
X buttexpr: buttmodexpr
X{ $$ = CheckButtonState($1); }
X;
X
X kmask: STRING { $$ = keyexprlookup(yylval.sval); }
X
X contmask: STRING
X{ $$ = contexprlookup(yylval.sval); }
X| STRING gadget_subscript
X{
X if ($2 < 0 || $2 >= NumGadgets) {
X sprintf(msg, "Bad subscript, gadget #%d must be >= 0 and < %d\n",
X $2, NumGadgets);
X yyerror(msg);
X }
X else {
X $$ = contexprlookup("gadget") | (1 << (BITS_USED + $2));
X }
X}
X;
X buttmodexpr: buttmodifier
X{ $$ = $1; }
X| buttmodexpr buttmodifier
X{ $$ = $1 | $2; }
X;
X
X buttmodifier: STRING
X{ $$ = buttexprlookup(yylval.sval); }
X;
X
X menuname: STRING
X{ $$ = $1; }
X;
X
X menuexpr: '{' menulist '}'
X{ $$ = $2; }
X;
X
X menulist: menuline
X{ $$ = $1; }
X| menulist menuline
X{ $$ = appendmenuline($1, $2); }
X| menulist COMMENT
X{
X Lineno++;
X $$ = $1;
X}
X| COMMENT
X{
X Lineno++;
X $$ = NULL;
X}
X| term
X{ $$ = NULL; }
X| menulist term
X{ $$ = $1; }
X| error term
X{
X $$ = NULL;
X yyerrok;
X}
X;
X
X menuline: strings ':' menuaction term
X{
X $3->name = $1;
X $3->pixmapname = (char *)0;
X $$ = $3;
X}
X| '(' strings ')' ':' menuaction term
X{
X $5->pixmapname = $2;
X $5->name = $2;
X $$ = $5;
X}
X;
X
X menuaction: STRING
X{
X ki = keywordlookup(yylval.sval);
X if ((ki != -1) &&
X (KeywordTable[ki].type != IsFunction) &&
X (KeywordTable[ki].type != IsImmFunction) &&
X (KeywordTable[ki].type != IsQuitFunction) &&
X (KeywordTable[ki].type != IsBoolean) &&
X (KeywordTable[ki].type != IsDownFunction)) {
X sprintf(msg,
X "menu action \"%s\" not a function or variable",
X KeywordTable[ki].name);
X yyerror(msg);
X }
X ml_ptr = AllocActionLine();
X if (KeywordTable[ki].type == IsQuitFunction ||
X KeywordTable[ki].type == IsImmFunction)
X ml_ptr->type = IsImmFunction;
X else if (KeywordTable[ki].type == IsBoolean) {
X ml_ptr->type = IsVar;
X ml_ptr->text = (char *)KeywordTable[ki].bptr;
X }
X else
X ml_ptr->type = IsUwmFunction;
X ml_ptr->func = KeywordTable[ki].fptr;
X $$ = ml_ptr;
X}
X| STRING ':' menuname
X{
X ki = keywordlookup($1);
X if (ki != -1 &&
X KeywordTable[ki].type != IsMenuMap) {
X sprintf(msg,
X "menu action \"%s\" not a menu function",
X KeywordTable[ki].name);
X yyerror(msg);
X }
X ml_ptr = AllocActionLine();
X ml_ptr->type = IsMenuFunction;
X ml_ptr->text = $3;
X $$ = ml_ptr;
X}
X| textaction
X{ $$ = $1; }
X;
X
X textaction: '!' strings
X{
X $$ = StashActionLine(IsShellCommand, $2);
X}
X| '^' strings
X{
X $$ = StashActionLine(IsTextNL, $2);
X}
X| '|' strings
X{
X $$ = StashActionLine(IsText, $2);
X}
X;
X
X strings: STRING { $$ = yylval.sval; }
X| strings STRING
X{ $$ = strconcat($1, $2); }
X;
X
X%%
X
X/*
X * Look up color named by "string" and return pixel value.
X */
XPixel LookupColor(string, cmap, fail)
Xchar *string;
XColormap cmap;
XBoolean *fail;
X{
X XColor vis_ret, act_ret;
X
X Entry("LookupColor")
X
X if (!XAllocNamedColor(dpy, cmap, string, &vis_ret, &act_ret)) {
X sprintf(msg, "Can't allocate color '%s', using default\n", string);
X yywarn(msg);
X if (fail)
X *fail = TRUE;
X Leave((Pixel)0)
X }
X if (fail)
X *fail = FALSE;
X Leave(vis_ret.pixel)
X}
X
X/*
X * Like LookupColor, but provides its own fallback in case of failure
X * (currently 0).
X */
XPixel GetPixel(string, cmap)
Xchar *string;
XColormap cmap;
X{
X XColor vis_ret, act_ret;
X
X Entry("GetPixel")
X
X if (!string)
X Leave((Pixel)0)
X if (!XAllocNamedColor(dpy, cmap, string, &vis_ret, &act_ret))
X Leave((Pixel)0)
X Leave(vis_ret.pixel)
X}
X
X/*
X * Look up a string in the keyword table and return its index, else
X * return -1.
X */
Xint keywordlookup(string)
Xchar *string;
X{
X int i;
X
X Entry("keywordlookup")
X
X for (i = 0; KeywordTable[i].name; i++) {
X if (!strcmp(KeywordTable[i].name, string)) {
X free(string);
X Leave(i)
X }
X }
X sprintf(msg,"keyword error: \"%s\"", string);
X yyerror(msg);
X free(string);
X Leave(-1)
X}
X
X/*
X * Look up a string in the key expression table and return its mask, else
X * return -1.
X */
Xint keyexprlookup(string)
Xchar *string;
X{
X int i;
X
X Entry("keyexprlookup")
X
X for (i = 0; KeyExprTbl[i].name; i++) {
X if (!strcmp(KeyExprTbl[i].name, string)) {
X free(string);
X Leave(KeyExprTbl[i].mask)
X }
X }
X sprintf(msg,"key expression error: \"%s\"", string);
X yyerror(msg);
X free(string);
X Leave(-1)
X}
X
Xint gravitylookup(string)
Xchar *string;
X{
X int i;
X
X Entry("gravitylookup")
X
X for (i = 0; GravityExprTbl[i].name; i++) {
X if (!strcmp(GravityExprTbl[i].name, string)) {
X free(string);
X Leave(GravityExprTbl[i].mask)
X }
X }
X sprintf(msg, "gravity expression error: \"%s\"", string);
X yyerror(msg);
X free(string);
X Leave(-1);
X}
X
X/*
X * Look up a string in the context expression table and return its mask, else
X * return -1.
X */
Xcontexprlookup(string)
Xchar *string;
X{
X int i;
X
X Entry("contexprlookup")
X
X for (i = 0; ContExprTbl[i].name; i++) {
X if (!strcmp(ContExprTbl[i].name, string)) {
X free(string);
X Leave(ContExprTbl[i].mask)
X }
X }
X sprintf(msg,"context expression error: \"%s\"", string);
X yyerror(msg);
X free(string);
X Leave(-1)
X}
X
X/*
X * Look up a string in the button expression table and return its mask, else
X * return -1.
X */
Xbuttexprlookup(string)
Xchar *string;
X{
X int i;
X
X Entry("buttexprlookup")
X
X for (i = 0; ButtModTbl[i].name; i++) {
X if (!strcmp(ButtModTbl[i].name, string)) {
X free(string);
X Leave(ButtModTbl[i].mask)
X }
X }
X sprintf(msg,"button modifier error: \"%s\"", string);
X yyerror(msg);
X free(string);
X Leave(-1)
X}
X
X/*
X * Scan a string and return an integer. Report an error if any
X * non-numeric characters are found.
X */
Xy_atoi(s)
Xchar *s;
X{
X int n = 0;
X
X Entry("y_atoi")
X
X while (*s) {
X if (*s >= '0' && *s <= '9')
X n = 10 * n + *s - '0';
X else {
X yyerror("non-numeric argument");
X Leave(-1)
X }
X s++;
X }
X Leave(n)
X}
X
X/*
X * Append s2 to s1, extending s1 as necessary.
X */
Xchar *
X strconcat(s1, s2)
Xchar *s1, *s2;
X{
X char *malloc();
X char *p;
X
X Entry("strconcat")
X
X p = malloc(strlen(s1) + strlen(s2) + 2);
X sprintf(p, "%s %s", s1, s2);
X free(s1);
X free(s2);
X s1 = p;
X Leave(s1)
X}
X
X/*
X * Check a button expression for errors.
X */
Xint CheckButtonState(expr)
Xint expr;
X{
X Entry("CheckButtonState")
X
X /*
X * Check for one (and only one) button.
X */
X switch (expr & (LeftMask | MiddleMask | RightMask)) {
X case 0:
X yyerror("no button specified");
X break;
X case LeftMask:
X break;
X case MiddleMask:
X break;
X case RightMask:
X break;
X default:
X yyerror("more than one button specified");
X }
X
X /*
X * Check for one (and only one) up/down/motion modifier.
X */
X switch (expr & (ButtonUp | ButtonDown | DeltaMotion)) {
X case 0:
X yyerror("no button action specified");
X break;
X case ButtonUp:
X break;
X case ButtonDown:
X break;
X case DeltaMotion:
X break;
X default:
X yyerror("only one of up/down/motion may be specified");
X }
X Leave(expr)
X}
X
X/*
X * Bind button/key/context to a function.
X */
Xbindtofunc(index, mask, context, name)
Xint index; /* Index into keyword table. */
Xint mask; /* Button/key/modifier mask. */
Xint context; /* ROOT, WINDOW, TITLE, ICON, GADGET or BORDER */
Xchar *name; /* Menu, if needed. */
X{
X Entry("bindtofunc")
X
X setbinding(context, index, mask, name);
X Leave_void
X}
X
X/*
X * Allocate a Binding type and return a pointer.
X */
XBinding *
X AllocBinding()
X{
X Binding *ptr;
X
X Entry("AllocBinding")
X
X if (!(ptr = (Binding *)calloc(1, sizeof(Binding)))) {
X sprintf(msg, "Can't allocate binding--out of space\n");
X yyerror(msg);
X exit(1);
X }
X Leave(ptr)
X}
X
X/*
X * Stash the data in a Binding.
X */
Xsetbinding(cont, i, m, mname)
Xint cont; /* Context: ROOT, WINDOW, or ICON. */
Xint i; /* Keyword table index. */
Xint m; /* Key/button/modifier mask. */
Xchar *mname; /* Pointer to menu name, if needed. */
X{
X Binding *ptr;
X MenuInfo *mi;
X
X Entry("setbinding")
X
X ptr = AllocBinding();
X ptr->context = cont;
X ptr->mask = m;
X ptr->func = KeywordTable[i].fptr;
X ptr->menuname = mname;
X switch (m & (LeftMask | MiddleMask | RightMask)) {
X case LeftMask:
X ptr->button = LeftButton;
X break;
X case MiddleMask:
X ptr->button = MiddleButton;
X break;
X case RightMask:
X ptr->button = RightButton;
X break;
X }
X appendbinding(ptr);
X Leave_void
X}
X
X/*
X * Append a Binding to the Bindings list.
X */
Xappendbinding(binding)
XBinding *binding;
X{
X Binding *ptr;
X
X Entry("appendbinding")
X
X if (Blist == NULL)
X Blist = binding;
X else {
X for(ptr = Blist; ptr->next; ptr = ptr->next) /* NULL */;
X ptr->next = binding;
X ptr = ptr->next;
X ptr->next = NULL;
X }
X Leave_void
X}
X
X/*
X * Allocate an action line and return a pointer.
X */
XActionLine *AllocActionLine()
X{
X ActionLine *ptr;
X
X Entry("AllocActionLine")
X
X if (!(ptr = (ActionLine *)calloc(1, sizeof(ActionLine)))) {
X sprintf(msg, "Can't allocate action line--out of space\n");
X yyerror(msg);
X }
X Leave(ptr)
X}
X
X/*
X * Allocate a MenuInfo structure and return a pointer.
X */
XMenuInfo *AllocMenuInfo()
X{
X MenuInfo *ptr;
X
X Entry("AllocMenuInfo")
X
X if (!(ptr = (MenuInfo *)calloc(1, sizeof(MenuInfo)))) {
X sprintf(msg, "Can't allocate menu storage--out of space\n");
X yyerror(msg);
X }
X Leave(ptr)
X}
X
X/*
X * Allocate a MenuLink structure and return a pointer.
X */
XMenuLink *AllocMenuLink()
X{
X MenuLink *ptr;
X
X Entry("AllocMenuLink")
X
X if (!(ptr = (MenuLink *)calloc(1, sizeof(MenuLink)))) {
X sprintf(msg, "Can't allocate menu linked list storage--out of space\n");
X yyerror(msg);
X }
X Leave(ptr)
X}
X
X/*
X * Return storage for Gadgets[] array.
X */
XGadgetDecl **allocate_gadgets()
X{
X GadgetDecl **tmp;
X int i;
X
X Entry("allocate_gadgets")
X
X tmp = (GadgetDecl **)malloc(MAX_GADGETS * sizeof(GadgetDecl *));
X if (!tmp) {
X sprintf(msg, "Can't allocate storage for Gadgets -- out of space\n");
X yyerror(msg);
X Leave(NULL)
X }
X for (i = 0; i < MAX_GADGETS; i++)
X tmp[i] = (GadgetDecl *)0;
X Leave(tmp)
X}
X
X/*
X * Stash a gadget record
X */
XGadgetDecl *stashGadget(n, s, type)
Xint n;
Xchar *s;
Xint type;
X{
X GadgetDecl *tmp;
X
X Entry("stashGadget")
X
X if (!Gadgets)
X Gadgets = (GadgetDecl **)allocate_gadgets();
X if (n < 0 || n >= NumGadgets) {
X sprintf(msg, "stashGadget on gadget #%d when maxgadget = %d\n",
X n, NumGadgets);
X yyerror(msg);
X Leave(NULL)
X }
X if (Gadgets[n]) {
X sprintf(msg, "gadget #%d redefined\n", n);
X yywarn(msg);
X FreeGadget(n);
X tmp = Gadgets[n];
X }
X else
X Gadgets[n] = tmp = (GadgetDecl *)malloc(sizeof(GadgetDecl));
X if (!Gadgets[n]) {
X sprintf(msg, "Can't allocate new gadget, out of space!\n");
X yyerror(msg);
X Leave(NULL)
X }
X tmp->data = (unsigned char *)NULL;
X tmp->name = (unsigned char *)NULL;
X tmp->high = tmp->wide = 0;
X tmp->gravity = g_gravity;
X tmp->offset = g_offset;
X tmp->forecolor = g_forecolor;
X tmp->backcolor = g_backcolor;
X tmp->fontInfo = g_font;
X if (type != C_STRING && type != C_PIXMAP) {
X sprintf(msg, "Invalid gadget specification for gadget #%d\n", n);
X yyerror(msg);
X NumGadgets = 0;
X Leave(NULL)
X }
X if (type == C_PIXMAP) {
X int junk;
X char *nm = s;
X
X s = expand_from_path(s);
X if (!s) {
X sprintf(msg, "Can't find pixmap file '%s' for gadget #%d\n",
X nm, n);
X yywarn(msg);
X tmp->data = (unsigned char *)gray_bits;
X tmp->high = gray_height;
X tmp->wide = gray_width;
X }
X else if (XReadBitmapFileData(s, &(tmp->wide),
X &(tmp->high), &(tmp->data), &junk, &junk)
X != BitmapSuccess) {
X sprintf(msg, "Can't open pixmap file '%s' for gadget #%d.\n", s, n);
X yyerror(msg);
X tmp->data = (unsigned char *)gray_bits;
X tmp->high = gray_height;
X tmp->wide = gray_width;
X }
X free(s);
X if (tmp->high > gadgetHeight)
X gadgetHeight = tmp->high;
X }
X else if (type == C_STRING) { /* it's a label */
X tmp->name = expand_metachars(s);
X if (!tmp->fontInfo) {
X if (!GFontInfo) {
X GFontInfo = GetFontRes("gadget.font", DEF_GADGET_FONT);
X if (!GFontInfo) {
X sprintf(msg, "Can't get a default gadget font.\n");
X yyerror(msg);
X Leave(NULL)
X }
X }
X tmp->fontInfo = GFontInfo;
X }
X if (strlen(tmp->name) > 1) {
X tmp->wide = XTextWidth(tmp->fontInfo, tmp->name, strlen(tmp->name));
X tmp->high = tmp->fontInfo->max_bounds.ascent +
X tmp->fontInfo->max_bounds.descent + 2;
X }
X else {
X XCharStruct chinfo;
X int asc, desc, dir;
X
X XTextExtents(tmp->fontInfo, tmp->name, 1, &dir, &asc,
X &desc, &chinfo);
X tmp->wide = chinfo.width;
X tmp->high = chinfo.ascent + chinfo.descent;
X }
X tmp->wide += 2 * GadgetBorder;
X if (tmp->high > gadgetHeight)
X gadgetHeight = tmp->high;
X }
X Leave(tmp)
X}
X
X/*
X * This routine expands '\' notation in a string, ala C. Mostly useful for
X * imbedding weird characters in strings that turn into interesting symbols
X * from some font. Unlike C, however, numeric constants (\nnn) are in
X * decimal, not octal. This was done because the most popular glyphs
X * (in cursorfont.h) are identified in decimal. There are some other cute
X * "metacharacters" that expand to the window name, icon name, etc.
X */
Xunsigned char *expand_metachars(s)
Xregister unsigned char *s;
X{
X register int i, len, val, n;
X unsigned char *cp, num[5];
X
X Entry("expand_metachars")
X
X if (!s)
X Leave(s)
X len = strlen(s);
X for (i = 0; i < len; i++)
X if (s[i] == '\\')
X break;
X if (i == len)
X Leave(s)
X /* we know the string is going to get shorter, len is correct */
X cp = (unsigned char *)malloc(len);
X i = n = 0;
X while (*s) {
X if (*s == '\\') {
X s++;
X while (*s && *s >= '0' && *s <= '9') {
X num[n++] = *s;
X s++;
X }
X if (n) {
X if (n > 4)
X n = 4;
X num[n] = '\0';
X cp[i++] = (char)atoi(num);
X n = 0;
X }
X else if (*s) {
X switch(*s) {
X
X case 'b':
X val = 8;
X break;
X
X case 'f':
X val = 12;
X
X case 'n':
X val = 10;
X break;
X
X case 'r':
X val = 13;
X break;
X
X case 't':
X val = 9;
X break;
X
X default:
X val = *s;
X break;
X }
X cp[i++] = val;
X s++;
X }
X }
X else {
X cp[i++] = *s;
X s++;
X }
X }
X cp[i] = '\0';
X Leave(cp)
X}
X
X/*
X * Stash the data in an action line.
X */
XActionLine *StashActionLine(type, string)
Xint type;
Xchar *string;
X{
X ActionLine *ptr;
X
X Entry("StashActionLine")
X
X ptr = AllocActionLine();
X ptr->type = type;
X ptr->text = string;
X Leave(ptr)
X}
X
X/*
X * Stash menu data in a MenuInfo structure;
X */
XMenuInfo *stashmenuinfo(name, line, pixmap)
Xchar *name;
XActionLine *line;
Xchar *pixmap;
X{
X MenuInfo *ptr;
X
X Entry("stashmenuinfo")
X
X ptr = AllocMenuInfo();
X ptr->name = name;
X ptr->line = line;
X ptr->pixmapname = pixmap;
X ptr->menu = 0;
X Leave(ptr)
X}
X
X/*
X * Stash menu info data in a MenuLink structure;
X */
XMenuLink *stashmenulink(menuinfo)
XMenuInfo *menuinfo;
X{
X MenuLink *ptr;
X
X Entry("stashmenulink")
X
X ptr = AllocMenuLink();
X ptr->next = NULL;
X ptr->menu = menuinfo;
X Leave(ptr)
X}
X
X/*
X * Append an action line to a linked list of menu lines.
X */
XActionLine *appendmenuline(list, line)
XActionLine *list;
XActionLine *line;
X{
X ActionLine *ptr;
X
X Entry("appendmenuline")
X
X if (list == NULL)
X list = line;
X else {
X for(ptr = list; ptr->next; ptr = ptr->next) /* NULL */;
X ptr->next = line;
X ptr = ptr->next;
X ptr->next = NULL;
X }
X Leave(list)
X}
X
X/*
X * Append a menu to a linked list of menus.
X */
XMenuLink *
X appendmenulink(list, link)
XMenuLink *list;
XMenuLink *link;
X{
X MenuLink *ptr;
X
X Entry("appendmenulink")
X
X if (list == NULL)
X list = link;
X else {
X for(ptr = list; ptr->next; ptr = ptr->next) /* NULL */;
X ptr->next = link;
X ptr = ptr->next;
X ptr->next = NULL;
X }
X Leave(list)
X}
X
X/*
X * Reset all previous bindings and free the space allocated to them.
X */
XBoolean ResetBindings()
X{
X Binding *ptr, *nextptr;
X
X Entry("ResetBindings")
X
X for(ptr = Blist; ptr; ptr = nextptr) {
X nextptr = ptr->next;
X free(ptr);
X }
X Blist = NULL;
X Leave_void
X}
X
X/*
X * De-allocate all menus.
X */
XBoolean ResetMenus()
X{
X MenuLink *mptr, *next_mptr;
X register ActionLine *lptr, *next_lptr;
X
X Entry("ResetMenus")
X if (!Menus)
X Leave_void
X for(mptr = Menus; mptr; mptr = next_mptr) {
X free(mptr->menu->name);
X RTLMenu_Destroy(mptr->menu->menu);
X for(lptr = mptr->menu->line; lptr; lptr = next_lptr) {
X free(lptr->name);
X if (lptr->text) free(lptr->text);
X next_lptr = lptr->next;
X free(lptr);
X }
X next_mptr = mptr->next;
X free(mptr);
X }
X Menus = NULL;
X Leave_void
X}
END_OF_awm/gram.y
if test 26836 -ne `wc -c <awm/gram.y`; then
echo shar: \"awm/gram.y\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 10 \(of 13\).
cp /dev/null ark10isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 13 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
Mike Wexler(wyse!mikew) Phone: (408)433-1000 x1330
More information about the Comp.sources.x
mailing list