jkh@ardent.UUCP (Jordan K. Hubbard) (06/06/88)
#! /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 6 (of 8)." # Contents: GetButton.c gram.y # Wrapped by jkh@ardent on Sun Jun 5 18:56:35 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'GetButton.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'GetButton.c'\" else echo shar: Extracting \"'GetButton.c'\" \(19196 characters\) sed "s/^X//" >'GetButton.c' <<'END_OF_FILE' X#ifndef lint X static char *rcsid_GetButton_c = "$Header: GetButton.c,v 1.24 87/09/09 19:20:45 swick Exp $"; X#endif lint X X#include "X11/copyright.h" 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/* X * MODIFICATION HISTORY X * X * 000 -- M. Gancarz, DEC Ultrix Engineering Group X * 001 -- L. Guarino Reid, DEC Ultrix Engineering Group, Western Software Lab X * February 16, 1987 X * Add EnterWindow, LeaveWindow, and MouseMotion as recognized X * awm buttons for awm menus. Add bug fixes to prevent mem faults X * if icon_str is NULL. X * 002 -- L. Guarino Reid, DEC Ultrix Engineering Group X * April 16, 1987 X * Convert to X11 X * 003 -- J. Hubbard, U.C. Berkeley. Title/gadget box event handling. X * December 3, 1987. X * 004 -- J.Hubbard, Ardent Computer. More conformance with ICCCM. Merge of X * changes to R2 uwm. X */ X X#ifndef lint static char *sccsid = "@(#)GetButton.c 3.8 1/24/86"; X#endif X/* X * GetButton - This subroutine is used by the Ardent Window Manager (awm) X * to acquire button events. It waits for a button event to occur X * and handles all event traffic in the interim. X * X * File: GetButton.c X */ X X#include "awm.h" X#include "X11/Xutil.h" X extern XContext AwmContext; extern int Fheight; /* the height of a title bar */ X X#define ICONSTR (icon_str ? icon_str : "") X/* Amount of padding between text in a title bar and the edge of the bar */ X#define PAD 1 X static Icon_modified = FALSE; X Boolean GetButton(b_ev) XXEvent *b_ev; /* Button event packet. */ X{ X#define STRLEN 50 X XKeyPressedEvent *kp_event; /* Key pressed event. */ X char *icon_str; /* Icon's name string. */ X register int icon_str_len; /* Icon name string lenght. */ X register int key_char; /* Key press character code. */ X register int icon_x; /* Icon window X coordinate. */ X register int icon_y; /* Icon window Y coordinate. */ X register int icon_w; /* Icon window width. */ X register int icon_h; /* Icon window height. */ X int status; /* Routine call return status. */ X Window icon; /* Icon window. */ X Window appl; /* Application window. */ X XWindowAttributes win_info; /* Icon window info structure. */ X char kbd_str[STRLEN]; /* Keyboard string. */ X int nbytes; /* Keyboard string length. */ X int i; /* Iteration counter. */ X Window win; /* scratch */ X AwmInfoPtr awi; X X Entry("GetButton") X X /* X * Get next event from input queue and store it in the event packet X * passed to GetButton. X */ X X XNextEvent(dpy, b_ev); X /* print_event_info("mainloop", b_ev); /* debugging for event handling */ X X /* X * The event occured on the root window, check for substructure X * changes. Otherwise, it must be a mouse button event. X */ X win = b_ev->xany.window; X X if (win == RootWindow(dpy, scr)) { X switch (b_ev->xany.type) { X case CreateNotify: X case UnmapNotify: X case ReparentNotify: X case ConfigureNotify: X case GravityNotify: X case MapNotify: X case CirculateNotify: X Leave(FALSE) X X case MappingNotify: X XRefreshKeyboardMapping(b_ev); X Leave(FALSE) X X case MapRequest: X CheckMap(b_ev->xmap.window); X Leave(FALSE) X X case ConfigureRequest: X Configure((XConfigureEvent *)b_ev); X Leave(FALSE) X X case CirculateRequest: X Circulate((XCirculateEvent *)b_ev); X Leave(FALSE) X X case DestroyNotify: X RemoveIcon(b_ev->xdestroywindow.window); X Leave(FALSE) X X case FocusIn: X if (b_ev->xfocus.detail == NotifyPointerRoot) { X if (FocusSetByUser) { X XSetInputFocus(dpy, PointerRoot, None, X CurrentTime); X FocusSetByUser = FALSE; X } X } X Leave(FALSE) X X case FocusOut: X if (b_ev->xfocus.detail == NotifyPointerRoot) { X if (FocusSetByUser == FALSE) X XSetInputFocus(dpy, PointerRoot, None, X CurrentTime); X } X Leave(FALSE) X X case ButtonPress: X case ButtonRelease: X Leave(TRUE) X X default: X fprintf(stderr, "awm: Got weird event #%d on root window\n", X b_ev->xany.type); X Leave(FALSE) X } X } X X /* X * If the event type is EnterWindow, LeaveWindow, or MouseMoved, X * we are processing a menu. X * If the event type is ButtonPress or ButtonRelease, X * we have a button event. X * If it's an expose, then we may have exposed a title bar. X * If it's a Notify, we've probably frobbed a titled window. X */ X X awi = GetAwmInfo(win); X switch (b_ev->type) { X X case MotionNotify: X case ButtonPress: X case ButtonRelease: X Leave(TRUE) X X case EnterNotify: X Leave(HandleFocusIn(b_ev)) X X case LeaveNotify: X Leave(HandleFocusOut(b_ev)) X X case ConfigureRequest: X Configure((XConfigureEvent *)b_ev); X Leave(FALSE) X X case MapRequest: X CheckMap(b_ev->xmap.window); X Leave(FALSE); X X case MapNotify: X if (!awi) X Leave(FALSE) X if (IsIcon(win, FALSE)) X Leave(FALSE) X if (awi->frame) X XMapWindow(dpy, awi->frame); X else X XMapWindow(dpy, awi->client); X Leave(FALSE) X break; X X case UnmapNotify: X if (!awi) X Leave(FALSE) X if (IsIcon(win, FALSE)) X Leave(FALSE) X if (awi->frame) X XUnmapWindow(dpy, awi->frame); X else X XUnmapWindow(dpy, awi->client); X Leave(FALSE) X break; X X case DestroyNotify: X if (!awi) X Leave(FALSE) X /* remove any icon associated with this window */ X RemoveIcon(win); X /* remove the frame/titlebar (if present) */ X DestroyTitle(win); X /* punt the rest of the per-window info */ X XDeleteContext(dpy, awi->client, AwmContext); X free(awi); X Leave(FALSE) X X case PropertyNotify: X if (!awi) X Leave(FALSE) X switch(b_ev->xproperty.atom) { X X case XA_WM_COMMAND: X case XA_WM_HINTS: X case XA_WM_CLIENT_MACHINE: X break; X X case XA_WM_ICON_NAME: X /* X * Icon was modified by type-in (I still think that's a X * gross feature, but some people like it... sigh), X * ignore this event. X */ X if (Icon_modified == TRUE) { X Icon_modified = FALSE; /* reset */ X Leave(FALSE) X } X if (awi->icon) { X win = awi->icon; X status = XGetWindowAttributes(dpy, win, &win_info); X icon_str = GetIconName(awi->client); X icon_str_len = icon_str ? strlen(icon_str) : 0; X if (win_info.width != XTextWidth(IFontInfo, ICONSTR, X strlen(ICONSTR))+(HIconPad << 1)) { X XResizeWindow(dpy, win, X XTextWidth(IFontInfo, ICONSTR, strlen(ICONSTR)) + X (HIconPad << 1), IFontInfo->ascent + X IFontInfo->descent + (VIconPad << 1)); X } X XClearWindow(dpy, win); X if (icon_str_len != 0) { X XDrawImageString(dpy, win, IconGC, HIconPad, X VIconPad+IFontInfo->ascent, icon_str, X icon_str_len); X free(icon_str); X } X } X break; X X case XA_WM_ICON_SIZE: X break; X X case XA_WM_NAME: X if (awi->title) { X if (awi->name) X free(awi->name); X awi->name = (char *)GetTitleName(win); X PaintTitle(win); X } X break; X X case XA_WM_NORMAL_HINTS: X case XA_WM_SIZE_HINTS: X case XA_WM_ZOOM_HINTS: X break; X X default: X fprintf(stderr, "awm: Got unknown property %d\n", X b_ev->xproperty.atom); X } X Leave(FALSE) X break; X X X case Expose: X if (!awi) /* probably a menu */ X Leave(FALSE) X if (awi->title == win) { X if (b_ev->xexpose.count == 0) { X XEvent evt; X X while (XCheckTypedWindowEvent(dpy, awi->title, Expose, &evt)); X PaintTitle(win); X if (awi->gadgets) X PaintGadgets(win); X } X Leave(FALSE) X } X break; X X default: X break; X } X X /* X * If we got this far, the event must be for an icon. X */ X X if (!awi) X Leave(FALSE) X status = XGetWindowAttributes(dpy, win, &win_info); X if (status == FAILURE) X Leave(FALSE) X X if (b_ev->type == MapNotify || X b_ev->type == UnmapNotify || X b_ev->type == CreateNotify || X b_ev->type == ReparentNotify || X b_ev->type == GravityNotify || X b_ev->type == CirculateNotify || X b_ev->type == ConfigureNotify) X Leave(FALSE) X X /* X * Initialize the icon position variables. X */ X icon_x = win_info.x; X icon_y = win_info.y; X X /* X * Get the name of the window associated with the icon and X * determine its length. X */ X if (!awi->icon) X Leave(FALSE) X icon = awi->icon; X icon_str = GetIconName(awi->client); X icon_str_len = icon_str ? strlen(icon_str) : 0; X X /* X * If the event is a window exposure event and the icon's name string X * is not of zero length, simply repaint the text in the icon window X * and return FALSE. X */ X if (b_ev->type == Expose && (!Freeze || Frozen == 0)) { X if (win_info.width != X XTextWidth(IFontInfo, ICONSTR, strlen(ICONSTR))+(HIconPad << 1)) { X XResizeWindow(dpy, icon, X XTextWidth(IFontInfo, ICONSTR, strlen(ICONSTR))+(HIconPad << 1), X IFontInfo->ascent + IFontInfo->descent + (VIconPad << 1)); X } X XClearWindow(dpy, icon); X if (icon_str_len != 0) { X XDrawImageString(dpy, icon, X IconGC, HIconPad, VIconPad+IFontInfo->ascent, X icon_str, icon_str_len); X /* X * Remember to free the icon name string. X */ X free(icon_str); X } X Leave(FALSE) X } X X /* X * If we have gotten this far event can only be a key pressed event. X */ X kp_event = (XKeyPressedEvent *) b_ev; X X /* X * We convert the key pressed event to ascii. X */ X nbytes = XLookupString(kp_event, kbd_str, STRLEN, NULL); X X /* X * If kbd_str is a "non-string", then don't do anything. X */ X if (nbytes == 0) { X if (icon_str) X free(icon_str); X Leave(FALSE) X } X for (i = 0; i < nbytes; i++) { X key_char = kbd_str[i]; X /* X * If the key was <DELETE>, then delete a character from the end of X * the name, return FALSE. X * X * If the key was <CTRL-U>, then wipe out the entire window name X * and return FALSE. X * X * All other ctrl keys are squashed and we return FALSE. X * X * All printable characters are appended to the window's name, which X * may have to be grown to allow for the extra length. X */ X if (key_char == '\177') { X /* X * <DELETE> X */ X if (icon_str_len > 0) { X icon_str_len--; X icon_str[icon_str_len] = '\0'; X } X } X else if (key_char == '\025') { X /* X * <CTRL-U> X */ X if (icon_str_len > 0) { X icon_str_len = 0; X icon_str[0] = '\0'; X } X } X else if (key_char < IFontInfo->min_char_or_byte2 || X key_char > IFontInfo->max_char_or_byte2) { X /* X * Any other random (non-printable) key; ignore it. X */ X /* do nothing */ ; X } X else { X /* X * ASCII Alphanumerics. X */ X if (icon_str == NULL) X icon_str = (char *) malloc (icon_str_len + 2); X else X icon_str = (char *)realloc(icon_str, (icon_str_len + 2)); X if (icon_str == NULL) { X errno = ENOMEM; X Error("GetButton -> Realloc of window name string memory failed."); X } X icon_str[icon_str_len] = key_char; X icon_str[icon_str_len + 1] = '\0'; X icon_str_len += 1; X } X } X X /* X * Now that we have changed the size of the icon we have to reconfigure X * it so that everything looks good. Oh yes, don't forget to move the X * mouse so that it stays in the window! X */ X X /* X * Set the window name to the new string. Icon_modified is a kludge X * that tells us to avoid the next PropertyNotify, as it's a result of X * this call. X */ X XSetIconName(dpy, awi->client, ICONSTR); X Icon_modified = TRUE; X /* X * Determine the new icon window configuration. X */ X icon_h = IFontInfo->ascent + IFontInfo->descent + (VIconPad << 1); X icon_w = XTextWidth(IFontInfo, ICONSTR, strlen(ICONSTR)); X if (icon_w == 0) { X icon_w = icon_h; X } X else { X icon_w += (HIconPad << 1); X } X X if (icon_x < 0) icon_x = 0; X if (icon_y < 0) icon_y = 0; X if (icon_x - 1 + icon_w + (IBorderWidth << 1) > ScreenWidth) { X icon_x = ScreenWidth - icon_w - (IBorderWidth << 1) + 1; X } X if (icon_y - 1 + icon_h + (IBorderWidth << 1) > ScreenHeight) { X icon_y = ScreenHeight - icon_h - (IBorderWidth << 1) + 1; X } X X XMoveResizeWindow(dpy, icon, icon_x, icon_y, icon_w, icon_h); X XWarpPointer(dpy, None, icon, X 0, 0, 0, 0, (icon_w >> 1), (icon_h >> 1)); X X /* X * Free the local storage and return FALSE. X */ X if (icon_str) X free(icon_str); X Leave(FALSE) X} X CheckMap(window) Window window; X{ X XWMHints *XGetWMHints(); X XWMHints *wmhints; X int x, y, w, h; X Window transient_for; X Window jW; X int border_width, j; X Binding *bptr; X AwmInfoPtr awi; X X Entry("CheckMap") X X /* if it's a transient window, we won't rubber-band X * note that this call always sets transient_for. X */ X if (!XGetTransientForHint( dpy, window, &transient_for )) { X /* X * Handle any registered grabs for this window. We do this here X * because we may be about to make an icon out of this window X * and we want to register any potential grabs on it before this X * happens. X */ X awi = GetAwmInfo(window); X if (!awi) { X for (bptr = Blist; bptr; bptr = bptr->next) X if (bptr->context & WINDOW) X Grab(bptr->mask, window); X XSelectInput(dpy, window, (EnterWindowMask | LeaveWindowMask | X PropertyChangeMask)); X awi = RegisterWindow(window); X if (Titles) { X AddTitle(window); X if (UseGadgets) X PutGadgets(window); X } X } X if ((wmhints = XGetWMHints(dpy, window))) { X if ((wmhints->flags & StateHint) && (awi->state == WINDOW) && X (wmhints->initial_state == IconicState)) { X /* window wants to be created as an icon. Leave size X /* and position alone, create as icon. */ X XFree(wmhints); X Iconify(window, 0, 0, 0, 0); X Leave_void X } X XFree(wmhints); X } X } X else X if ((awi = GetAwmInfo(window)) == NULL) X awi = RegisterWindow(window); X if (awi->state == WINDOW) { X PlaceWindow(window); X if (awi->frame) { X XMapRaised(dpy, awi->frame); X XMapWindow(dpy, awi->client); X } X else X XMapRaised(dpy, awi->client); X } X Leave_void X} X Configure(event) XXConfigureRequestEvent *event; X{ X XWindowChanges values; X AwmInfoPtr awi; X X Entry("Configure") X X values.x = event->x; X values.y = event->y; X values.width = event->width; X values.height = event->height; X values.border_width = event->border_width; X values.stack_mode = event->detail; X values.sibling = event->above; X X ConfigureWindow(event->window, event->value_mask, &values); X Leave_void X} X Circulate(event) XXCirculateEvent *event; X{ X Entry("Circulate") X X if (event->place == PlaceOnTop) X XRaiseWindow(event->display, event->window); X else X XLowerWindow(event->display, event->window); X Leave_void X} X PlaceWindow(window) Window window; X{ X XSizeHints wsh; X int x, y, w, h; X Boolean configureit = False; X XWindowChanges xwc; X AwmInfoPtr awi; X long flags; X X wsh.flags = 0; X flags = CWX | CWY | CWWidth | CWHeight; X awi = GetAwmInfo(window); X XGetSizeHints(dpy, window, &wsh, XA_WM_NORMAL_HINTS); X CheckConsistency(&wsh); X AskUser(dpy, scr, window, &x, &y, &w, &h, &wsh); X X wsh.flags |= (USPosition | USSize); X wsh.x = x; X wsh.y = y; X wsh.width = w; X wsh.height = h; X if (x < 0 || y < 0) { X Window jW; X int j, border_width; X X XGetGeometry(dpy, window, &jW, &j, &j, &j, &j, &border_width, &j); X X if (x < 0) X x += DisplayWidth(dpy, scr) - w - (border_width<<1); X if (y < 0) X y += DisplayHeight(dpy, scr) - h - (border_width<<1); X } X if (IsTitled(window)) X XSetSizeHints(dpy, awi->frame, &wsh, XA_WM_NORMAL_HINTS); X XSetSizeHints(dpy, awi->client, &wsh, XA_WM_NORMAL_HINTS); X#ifdef titan /* 5x4 alignment */ X x += (x % 5); X y += (y % 4); X#endif X xwc.x = x; X xwc.y = y; X xwc.height = h; X xwc.width = w; X ConfigureWindow(window, flags, &xwc); X awi->placed = TRUE; X} X Boolean ConfigureWindow(w, mask, xwc) Window w; unsigned long mask; XXWindowChanges *xwc; X{ X XWindowAttributes xwa; X AwmInfoPtr awi; X Boolean compensate = TRUE; X X Entry("ConfigureWindow") X X awi = GetAwmInfo(w); X if (!awi) X Leave(FALSE) X if (w == awi->frame) X compensate = FALSE; X X if (awi->frame) { X if (compensate) X xwc->width += (BContext ? (BContext * 2) + 2 : 0); X XResizeWindow(dpy, awi->title, xwc->width, Fheight); X if (compensate) X xwc->height += (Fheight + 2 + (BContext ? BContext + 1 : 0)); X if (TitlePush == FALSE && compensate) { X xwc->y -= (Fheight + 2); X if (xwc->y < 0) X xwc->y = 0; X } X XConfigureWindow(dpy, awi->frame, mask, xwc); X xwc->height -= (Fheight + 2 + (BContext ? BContext + 1 : 0)); X xwc->width -= (BContext ? ((BContext * 2) + 2) : 0); X xwc->y = Fheight + 2; X if (BContext) X xwc->x = BContext; X else X xwc->x = 0; X if (awi->gadgets) X PutGadgets(w); X } X XConfigureWindow(dpy, awi->client, mask, xwc); X Leave(TRUE) X} X int ProcessRequests(box, num_vectors) XXSegment *box; int num_vectors; X{ X XEvent event; X X XPeekEvent(dpy, &event); X switch (event.type) { X X case MapRequest: X case ConfigureRequest: X case CirculateRequest: X X DrawBox(); X GetButton(&event); X DrawBox(); X return TRUE; X } X return FALSE; X} END_OF_FILE if test 19196 -ne `wc -c <'GetButton.c'`; then echo shar: \"'GetButton.c'\" unpacked with wrong size! fi # end of 'GetButton.c' fi if test -f 'gram.y' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'gram.y'\" else echo shar: Extracting \"'gram.y'\" \(25572 characters\) sed "s/^X//" >'gram.y' <<'END_OF_FILE' X/* $Header: gram.y,v 1.6 87/05/24 22:11:00 jg Exp $ */ 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#ifndef lint X static char *sccsid = "@(#)gram.y 3.8 1/24/86"; X#endif X X#include <X11/copyright.h> 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; /* the number of the gadget we're initing */ X static int g_offset; /* The gadget offset (if any) specified */ X static int g_gravity; /* The gadget gravity (if any) specified */ X static long g_forecolor; /* gadget foreground color */ X static long 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 (optional) */ 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 = ForeColor; X g_backcolor = BackColor; 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 = ForeColor; X g_backcolor = BackColor; 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{ g_offset = y_atoi($1); } X; X gravity: /* empty */ X{ g_gravity = NoGadgetGravity; } X| STRING X{ g_gravity = gravitylookup($1); } X; X forecolor: /* empty */ X{ g_forecolor = ForeColor; } X| STRING X{ g_forecolor = LookupColor($1); } X; X backcolor: /* empty */ X{ g_backcolor = BackColor; } X| STRING X{ g_backcolor = LookupColor($1); } 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 */ long LookupColor(string) char *string; X{ X XColor vis_ret, act_ret; X static int ncolors = 0; X X Entry("LookupColor"); X X if (MaxColors && ncolors >= MaxColors) { X sprintf(msg, "Can't allocate color '%s', MaxColors (%d) exceeded\n", X string, MaxColors); X yywarn(msg); X Leave(NOCOLOR) X } X if (!XAllocNamedColor(dpy, DefaultColormap(dpy, scr), string, X &vis_ret, &act_ret)) { X sprintf(msg, "Can't allocate color '%s', using default\n", string); X yywarn(msg); X Leave(NOCOLOR) X } X ncolors++; 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 */ int keywordlookup(string) char *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 */ int keyexprlookup(string) char *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 int gravitylookup(string) char *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 */ contexprlookup(string) char *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 */ buttexprlookup(string) char *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 */ y_atoi(s) char *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 */ char * X strconcat(s1, s2) char *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 */ int CheckButtonState(expr) int 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 */ bindtofunc(index, mask, context, name) int index; /* Index into keyword table. */ int mask; /* Button/key/modifier mask. */ int context; /* ROOT, WINDOW, TITLE, ICON, GADGET or BORDER */ char *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 */ Binding * 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 */ setbinding(cont, i, m, mname) int cont; /* Context: ROOT, WINDOW, or ICON. */ int i; /* Keyword table index. */ int m; /* Key/button/modifier mask. */ char *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 */ appendbinding(binding) Binding *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 */ ActionLine *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 */ MenuInfo *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 */ MenuLink *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 */ GadgetDecl **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 */ GadgetDecl *stashGadget(n, s, type) int n; char *s; int 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 = 0; X tmp->name = (unsigned char *)0; X tmp->high = tmp->wide = tmp->offset = 0; X tmp->gravity = g_gravity; X tmp->offset = g_offset; X tmp->forecolor = g_forecolor ? g_forecolor : BlackPixel(dpy, scr); X tmp->backcolor = g_backcolor ? g_backcolor : WhitePixel(dpy, scr); X tmp->fontInfo = g_font; X g_font = (XFontStruct *)NULL; 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 (Reverse) { X unsigned long foo; X X foo = tmp->forecolor; X tmp->forecolor = tmp->backcolor; X tmp->backcolor = foo; 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 s = nm; /* make it into fake text gadget */ X type = C_STRING; 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 s = nm; /* fake text gadget is better than dying */ X type = C_STRING; X } X free(s); X } X 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 tmp->high = tmp->fontInfo->max_bounds.ascent + X tmp->fontInfo->max_bounds.descent + 2; X if (strlen(tmp->name) > 1) X tmp->wide = XTextWidth(tmp->fontInfo, tmp->name, strlen(tmp->name)); 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 } X X } X Leave(tmp) X} X X/* X * This routine expands '\' notation in a string, ala C. Mostly useful for imbedding X * weird characters in strings that turn into interesting symbols from some font. X * Unlike C, however, numeric constants (\nnn) are in decimal, not octal. This X * was done because the most popular glyphs (in cursorfont.h) are identified X * in decimal. X */ unsigned char *expand_metachars(s) register 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 */ ActionLine *StashActionLine(type, string) int type; char *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 */ MenuInfo *stashmenuinfo(name, line, pixmap) char *name; ActionLine *line; char *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 */ MenuLink *stashmenulink(menuinfo) MenuInfo *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 */ ActionLine *appendmenuline(list, line) ActionLine *list; ActionLine *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 */ MenuLink * X appendmenulink(list, link) MenuLink *list; MenuLink *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 */ Boolean 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 */ Boolean 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_FILE if test 25572 -ne `wc -c <'gram.y'`; then echo shar: \"'gram.y'\" unpacked with wrong size! fi # end of 'gram.y' fi echo shar: End of archive 6 \(of 8\). cp /dev/null ark6isdone MISSING="" for I in 1 2 3 4 5 6 7 8 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 8 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0