mikew@wyse.wyse.com (Mike Wexler) (02/21/89)
Submitted-by: kmw@ardent (Ken Wallich) Posting-number: Volume 3, Issue 21 Archive-name: awm2/part05 #! /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 5 (of 12)." # Contents: Pause.c awm.h menus/track_menu.c # Wrapped by mikew@wyse on Fri Feb 17 10:50:23 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'Pause.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Pause.c'\" else echo shar: Extracting \"'Pause.c'\" \(3003 characters\) sed "s/^X//" >'Pause.c' <<'END_OF_FILE' X X X X#ifndef lint Xstatic char *rcsid_Pause_c = "$Header: /usr/graph2/X11.3/contrib/windowmgrs/awm/RCS/Pause.c,v 1.2 89/02/07 21:23:15 jkh Exp $"; X#endif lint X X#include "X11/copyright.h" 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/* 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, Ardent Computer X * Changes for awm. X */ X X#include "awm.h" X X/*ARGSUSED*/ XBoolean Pause(window, mask, button, x, y) XWindow window; /* Event window. */ Xint mask; /* Button/key mask. */ Xint button; /* Button event detail. */ Xint x, y; /* Event mouse position. */ X{ X Entry("Pause") X X XGrabServer(dpy); X Leave(FALSE) X} X X/*ARGSUSED*/ XBoolean Continue(window, mask, button, x, y) XWindow window; /* Event window. */ Xint mask; /* Button/key mask. */ Xint button; /* Button event detail. */ Xint x, y; /* Event mouse position. */ X{ X Entry("Continue") X X XUngrabServer(dpy); X Leave(FALSE) X} END_OF_FILE if test 3003 -ne `wc -c <'Pause.c'`; then echo shar: \"'Pause.c'\" unpacked with wrong size! fi # end of 'Pause.c' fi if test -f 'awm.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'awm.h'\" else echo shar: Extracting \"'awm.h'\" \(22317 characters\) sed "s/^X//" >'awm.h' <<'END_OF_FILE' X#ifndef lint Xstatic char *rcsid_awm_h = "$Header: /usr/graph2/X11.3/contrib/windowmgrs/awm/RCS/awm.h,v 1.2 89/02/07 21:24:27 jkh Exp $"; X#endif lint X X#include <X11/copyright.h> 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/* X * MODIFICATION HISTORY X * X * 000 -- M. Gancarz, DEC Ultrix Engineering Group X * 001 -- R. Kittell, DEC Storage A/D May 19, 1986 X * Added global vars for warp options. X * 002 -- Loretta Guarino Reid, DEC Ultrix Engineering Group, X * Western Software Lab, Port to X11 X * 003 -- Jordan Hubbard, Ardent Computer X * Many additional declarations for awm. X * 1.3 -- Support for WM_STATE (Mike Wexler) X */ X X#ifndef AWM_INCLUDE X#define AWM_INCLUDE X#include <errno.h> X#include <stdio.h> X#include <X11/Intrinsic.h> X#include <X11/Xatom.h> X X#include "menus/rtlmenu.h" X#include "support.h" X X#define MIN(x, y) ((x) <= (y) ? (x) : (y)) X#define MAX(x, y) ((x) >= (y) ? (x) : (y)) X#define VOLUME_PERCENTAGE(x) ((x)*14) X#define ModMask 0xFF X#define ButtonMask(b) (((b)==Button1) ? Button1Mask : \ X (((b)==Button2) ? Button2Mask : Button3Mask)) X X#define DEF_DELTA 1 X#define DEF_FUNC GXcopy X#define DEF_ICON_BORDER_WIDTH 2 X#define DEF_ICON_PAD 4 X#define DEF_POP_BORDER_WIDTH 2 X#define DEF_POP_PAD 4 X#define DEF_MENU_BORDER_WIDTH 2 X#define DEF_MENU_PAD 4 X#define DEF_GADGET_PAD 3 X#define DEF_GADGET_BORDER 1 X#define DEF_TITLE_PAD 2 X#define DEF_VOLUME 4 X#define DEF_PUSH 5 X#define DEF_BCONTEXT_WIDTH 0 X#define DEF_RAISE_DELAY 100 /* milliseconds */ X#define DEF_MAX_COLORS 0 /* 0 means take as many as we can */ X#ifndef DEF_BCONTEXT_CURSOR X#define DEF_BCONTEXT_CURSOR XC_plus X#endif DEF_BCONTEXT_CURSOR X#ifndef DEF_TITLE_CURSOR X#define DEF_TITLE_CURSOR XC_left_ptr X#endif DEF_TITLE_CURSOR X#ifndef NAME X#define NAME "awm" X#endif NAME X#ifndef CLASS X#define CLASS "Wm" X#endif CLASS X#ifndef DEF_FONT X#define DEF_FONT "fixed" X#endif DEF_FONT X#ifndef DEF_TITLE_FONT X#define DEF_TITLE_FONT "8x13" X#endif DEF_TITLE_FONT X#ifndef DEF_ICON_FONT X#define DEF_ICON_FONT "8x13" X#endif DEF_ICON_FONT X#ifndef DEF_POPUP_FONT X#define DEF_POPUP_FONT "9x15" X#endif DEF_POPUP_FONT X#ifndef DEF_GADGET_FONT X#define DEF_GADGET_FONT "fixed" X#endif DEF_GADGET_FONT X#ifndef DEF_MENU_FONT X#define DEF_MENU_FONT "8x13" X#endif DEF_MENU_FONT X#ifndef DEF_BOLD_FONT X#define DEF_BOLD_FONT "8x13bold" X#endif DEF_BOLD_FONT X#define DEF_MENU_DELTA 20 X#ifndef DEF_NAME X#define DEF_NAME "NoName" /* for clients w/no name */ X#endif X X#define INIT_PTEXT {'0', '0', '0', 'x', '0', '0', '0'} X X#ifndef TEMPFILE X#define TEMPFILE "/tmp/awm.XXXXXX" X#endif TEMPFILE X X#define CURSOR_WIDTH 16 X#define CURSOR_HEIGHT 16 X X#define MAX_ZAP_VECTORS 8 X#define MAX_BOX_VECTORS 20 X X#define DRAW_WIDTH 0 /* use fastest hardware draw */ X#define DRAW_VALUE 0xfd X#define DRAW_FUNC GXxor X#define DRAW_PLANES 1 X X#define NOCOLOR -1 X X/* X * The first BITS_USED bits of the mask are used to define the most generic X * types. All other bits are free for storing peripheral information. X * For now, we use the extra bits to specify which gadget(s) are bound X * to an action. MAX_GADGETS depends on BITS_USED to determine the maximum X * number of gadgets possible. If you add a new context type, be sure to X * increment BITS_USED. X */ X#define ROOT 0x1 X#define WINDOW 0x2 X#define ICON 0x4 X#define TITLE 0x8 X#define BORDER 0x10 X#define GADGET 0x20 X X#define BITS_USED 6 X X/* Window states */ X#define ST_WINDOW 0x1 X#define ST_ICON 0x2 X#define ST_PLACED 0x4 X#define ST_DECORATED 0x8 X X#define DECORATED(a) (a && (a->state & ST_DECORATED)) X X/* Window attributes */ X#define AT_NONE 0x0 X#define AT_TITLE 0x1 X#define AT_GADGETS 0x2 X#define AT_RAISE 0x4 X#define AT_BORDER 0x8 X#define AT_INPUT 0x10 X#define AT_ICONLABEL 0x20 X X/* X * Gadgets aren't the sort of embellishments that one uses in quantitity X * (unless one is designing a truly odd interface), so we keep the information X * in an array instead of using the usual linked list. MAX_GADGETS is a derived X * macro (see BITS_USED) that is used to determine the size of the X * Array. X * X */ X#define MAX_GADGETS ((sizeof(int) * 8) - BITS_USED) X X#ifndef FAILURE X#define FAILURE 0 X#endif FAILURE X X#define NAME_LEN 256L /* Maximum length string names */ X#define EVENTMASK (ButtonPressMask | ButtonReleaseMask) X X X#define DrawBox() XDrawSegments(dpy, RootWindow(dpy, scr),DrawGC,box,num_vectors) X#define DrawZap() XDrawSegments(dpy, RootWindow(dpy, scr),DrawGC,zap,num_vectors) X X#define gray_width 16 X#define gray_height 16 Xextern char gray_bits[]; X X#define solid_width 16 X#define solid_height 16 Xextern char solid_bits[]; X X#define xlogo32_width 32 X#define xlogo32_height 32 Xextern char xlogo32_bits[]; X X/* X * All one needs to know about an awm managed window.. (so far...) X */ X#ifdef WMSTATE X#define WithdrawState 0 X#define NormalState 1 X#define IconicState 3 X Xtypedef struct { X int state; X Window icon; X} WM_STATE; X Xextern Atom wm_state_atom; X#endif /* WMSTATE */ X X Xtypedef struct _awminfo { X Window title, client, frame, icon; /* Associated windows */ X Window *gadgets; /* associated gadgets */ X char *name; /* The formatted window name */ X Boolean own; /* Do we own the icon window? */ X Pixmap back, bold, iconPixmap; /* background, bold and icon pix */ X Pixmap BC_back, BC_bold; /* BC back and bold pixmaps */ X#ifdef RAINBOW X /* Per window versions of the globals colours */ X Pixmap grayPixmap, solidPixmap; X Pixmap iBackPixmap; X Pixel foreColor, backColor; X Pixel iBorder; X Pixel iBackground, iForeground; X Pixel iTextForeground, iTextBackground; X#endif X unsigned int border_width; /* original border width */ X int state; /* The state of the window */ X int attrs; /* Window "attributes" */ X GC winGC; /* GC at proper depth for window */ X#ifdef WMSTATE X WM_STATE wm_state; X#endif /* WMSTATE */ X} AwmInfo, *AwmInfoPtr; X X/* X * This whole section has changed substantially. Basically, since all the X * variables have vanished into the resource manager, the keyword table X * only needs to keep track of function pointers, boolean pointers and X * "special" keywords like menu and gagdet. Since some things are still X * modifiable from menus (only booleans, currently, though this will change), X * we keep these in the keyword table even though X * they're no longer directly modifable from the .awmrc X */ X X/* X * Keyword table entry. X */ Xtypedef struct _keyword { X char *name; X int type; X Boolean *bptr; X Boolean (*fptr)(); X} Keyword; X X/* X * Keyword table type entry. X */ X#define IsFunction 1 X#define IsMenuMap 2 X#define IsMenu 3 X#define IsDownFunction 4 X#define IsParser 5 X#define IsQuitFunction 6 X#define IsGadget 7 X#define IsBoolean 8 X#define IsAction 9 X X/* X * Button/key binding type. X */ Xtypedef struct _binding { X struct _binding *next; X int context; X unsigned int mask; X int button; X Boolean (*func)(); X char *menuname; X RTLMenu menu; X} Binding; X X/* X * Key expression type. X */ Xtypedef struct _keyexpr { X char *name; X int mask; X} KeyExpr; X X/* X * Context expression type. X */ Xtypedef struct _contexpr { X char *name; X int mask; X} ContExpr; X X/* X * Button modifier type. X */ Xtypedef struct _buttonmodifier { X char *name; X int mask; X} ButtonModifier; X X/* X * Gravity expression type. X */ Xtypedef struct _gravityexpr { X char *name; X int mask; X} GravityExpr; X X/* X * Button modifier mask definitions. X * bits 13 and 14 unused in key masks, according to X.h X * steal bit 15, since we don't use AnyModifier X */ X X#define DeltaMotion (1<<13) X#define ButtonUp (1<<14) X#define ButtonDown AnyModifier X#define ButtonMods DeltaMotion+ButtonUp+ButtonDown X X/* X * Button and mask redefinitions, for X11 X */ X#define LeftMask Button1Mask X#define MiddleMask Button2Mask X#define RightMask Button3Mask X#define LeftButton Button1 X#define MiddleButton Button2 X#define RightButton Button3 X X/* X * Declaration specific information for gadgets. This defines only gadget X * types, not the actual gadgets. The pixmap member is only used if a pixmap X * is being displayed. Gravity and offset are purely optional. X */ X X#define NoGadgetGravity 0 X#define LeftGadgetGravity 1 X#define RightGadgetGravity 2 X#define CenterGadgetGravity 3 X Xtypedef struct _gadgetdecl { /* Declaration (type) information */ X unsigned char *name; /* Either text label or pixmap file name */ X unsigned char *data; /* If pixmap file, this is the data from it */ X char *forecolor; /* foreground color for pixmap */ X char *backcolor; /* background color for pixmap */ X XFontStruct *fontInfo; /* font for text */ X int high, wide; /* width and height of pixmap or text */ X int gravity; /* stick to the left or right? */ X int offset; /* offset from previous item */ X} GadgetDecl; X X/* X * MenuInfo data type. X */ Xtypedef struct _menuinfo { X char *name; /* Name of this menu. */ X char *pixmapname; /* Name of label pixmap (opt) */ X RTLMenu menu; /* RTL menu handle for destroy */ X struct _actionline *line; /* Linked list of menu items. */ X} MenuInfo; X X/* X * Action Line data type. X */ Xtypedef struct _actionline { X struct _actionline *next; /* Pointer to next line. */ X char *name; /* Name of this line. */ X char *pixmapname; /* Name of the backing pixmap (opt) */ X int type; /* IsShellCommand, IsText, IsTextNL... */ X RTLMenuItem item; /* RTL item handle */ X char *text; /* Text string to be acted upon. */ X Boolean (*func)(); /* Window manager function to be invoked. */ X} ActionLine; X X/* X * ActionLine->type definitions. X */ X#define IsShellCommand 1 X#define IsText 2 X#define IsTextNL 3 X#define IsUwmFunction 4 X#define IsMenuFunction 5 X#define IsImmFunction 6 /* Immediate (context-less) function. */ X#define IsVar 7 /* we're setting a boolean variable */ X X/* X * Menu Link data type. Used by the parser when creating a linked list X * of menus. X */ Xtypedef struct _menulink { X struct _menulink *next; /* Pointer to next MenuLink. */ X struct _menuinfo *menu; /* Pointer to the menu in this link. */ X} MenuLink; X X/* X * External variable definitions. X */ Xextern int errno; Xextern Window Pop; /* Pop-up dimension display window. */ Xextern Window Frozen; /* Contains window id of "gridded" window. */ Xextern XFontStruct *IFontInfo; /* Icon text font information. */ Xextern XFontStruct *PFontInfo; /* Pop-up text font information. */ Xextern XFontStruct *TFontInfo; /* Title text font information. */ Xextern XFontStruct *TFontBoldInfo;/* Title text (bold) font information. */ Xextern XFontStruct *GFontInfo; /* Gadget box text font */ Xextern XFontStruct *MFontInfo; /* Menu font */ Xextern XFontStruct *MBoldFontInfo;/* Menu bold font */ Xextern Pixmap GrayPixmap; /* Gray pixmap. */ Xextern Pixmap SolidPixmap; Xextern Pixmap IBackPixmap; /* Icon window background pixmap. */ Xextern Pixmap IDefPixmap; /* Icon pixmap for twm style icons */ Xextern char *BForeground; /* Border Context (pixmap) foreground pixel */ Xextern char *BBackground; /* Border Context (pixmap) background pixel */ Xextern char *WBorder; /* Window border pixel */ Xextern char *TTextForeground; /* Title text foreground pixel */ Xextern char *TTextBackground; /* Title text background pixel */ Xextern char *TForeground; /* Title (pixmap) foreground pixel */ Xextern char *TBackground; /* Title (pixmap) background pixel */ Xextern char *Foreground; /* default forground color (text) */ Xextern char *Background; /* default background color (text) */ Xextern Pixel IBorder; /* Icon window border pixel. */ Xextern Pixel ITextForeground; /* Icon window text forground color. */ Xextern Pixel ITextBackground; /* Icon window text background color. */ Xextern Pixel IForeground; /* Icon pixmap foreground color */ Xextern Pixel IBackground; /* Icon pixmap background color */ Xextern Pixel PForeground; /* Pop-up window forground color. */ Xextern Pixel PBackground; /* Pop-up window background color. */ Xextern Pixel PBorder; /* Pop-Up Window border pixel. */ Xextern Pixel ForeColor; /* default foreground color */ Xextern Pixel BackColor; /* default background color */ Xextern Pixel MBorder; /* Menu border color */ Xextern Pixel MForeground; /* Menu foreground color */ Xextern Pixel MBackground; /* Menu background color */ Xextern Cursor ArrowCrossCursor; /* Arrow cross cursor. */ Xextern Cursor TextCursor; /* Text cursor used in icon windows. */ Xextern Cursor IconCursor; /* Icon Cursor. */ Xextern Cursor LeftButtonCursor; /* Left button main cursor. */ Xextern Cursor MiddleButtonCursor;/* Middle button main cursor. */ Xextern Cursor RightButtonCursor;/* Right button main cursor. */ Xextern Cursor TargetCursor; /* Target (select-a-window) cursor. */ Xextern Cursor TitleCursor; /* Title bar cursor */ Xextern Cursor FrameCursor; /* Frame cursor */ Xextern Cursor GumbyCursor; /* Used in icons if not type-in */ Xextern unsigned int GadgetBorder; /* Width of gadget borders */ Xextern int ScreenWidth; /* Display screen width. */ Xextern int ScreenHeight; /* Display screen height. */ Xextern int TitleHeight; /* Height in pixels of title bar(s) */ Xextern int titleHeight; /* Derived height of title bar(s) */ Xextern int gadgetHeight; /* Height of highest gadget */ Xextern int NameOffset; /* Offset for window name */ Xextern int IBorderWidth; /* Icon window border width. */ Xextern int PWidth; /* Pop-up window width (including borders). */ Xextern int PHeight; /* Pop-up window height (including borders). */ Xextern unsigned int PBorderWidth; /* Pop-up window border width. */ Xextern int PPadding; /* Pop-up window padding. */ Xextern int Delta; /* Mouse movement slop. */ Xextern int HIconPad; /* Icon horizontal padding. */ Xextern int VIconPad; /* Icon vertical padding. */ Xextern int Pushval; /* Number of pixels to push window by. */ Xextern int BContext; /* Width of border context area in pixels */ Xextern int RaiseDelay; /* Delay in milliseconds before autoraising windows */ Xextern int Volume; /* Audible alarm volume. */ Xextern int NumGadgets; /* Number of gadgets used */ Xextern int GadgetPad; /* Padding between gadgets */ Xextern int TitlePad; /* Title text padding */ Xextern int status; /* Routine return status. */ Xextern int MPad; /* menu padding */ Xextern int MDelta; /* Menu subitem delta */ Xextern int MBorderWidth; /* Menu border width */ Xextern int MItemBorder; /* Menu item border width */ Xextern unsigned int BCursor; /* Border context cursor */ Xextern unsigned int TCursor; /* Title context cursor */ Xextern MenuLink *Menus; /* Linked list of menus. */ Xextern GC IconGC; /* graphics context for icon */ Xextern GC PopGC; /* graphics context for pop */ Xextern GC DrawGC; /* graphics context for zap */ X Xextern Boolean Autoraise; /* Raise window on input focus? */ Xextern Boolean Autoselect; /* Warp mouse to default menu selection? */ Xextern Boolean Borders; /* Display border context areas? */ Xextern Boolean ConstrainResize; /* Don't resize until pointer leaves window */ Xextern Boolean Freeze; /* Freeze server during move/resize? */ Xextern Boolean Grid; /* Should the m/r box contain a 9 seg. grid. */ Xextern Boolean Hilite; /* Should we highlight titles on focus? */ Xextern Boolean BorderHilite; /* Should we highlight borders on focus? */ Xextern Boolean FrameFocus; /* Should frame be considered part of window */ Xextern Boolean ShowName; /* Display names in title bars */ Xextern Boolean NWindow; /* Normalize windows? */ Xextern Boolean NIcon; /* Normalize icons? */ Xextern Boolean RootResizeBox; /* Should resize box obscure window? */ Xextern Boolean InstallColormap; /* Install colormap for clients? */ Xextern Boolean Push; /* Relative=TRUE, Absolute=FALSE. */ Xextern Boolean ResizeRelative; /* Relative=TRUE, Absolute=FALSE. */ Xextern Boolean Reverse; /* Reverse video? */ Xextern Boolean SaveUnder; /* Save unders? */ Xextern Boolean Snatched; /* We're in the middle of an no-highlight/raise op */ Xextern Boolean Titles; /* Title bars on windows? */ Xextern Boolean IconLabels; /* Labels on pixmap icons? (twm style) */ Xextern Boolean ILabelTop; /* label top of icon? */ Xextern Boolean PushDown; /* Down=TRUE, Up=FALSE */ Xextern Boolean UseGadgets; /* Gadget boxes in title bars? */ Xextern Boolean Wall; /* Don't allow windows past edges of screen */ Xextern Boolean WarpOnRaise; /* Warp to upper right corner on raise. */ Xextern Boolean WarpOnIconify; /* Warp to icon center on iconify. */ Xextern Boolean WarpOnDeIconify; /* Warp to upper right corner on de-iconify. */ Xextern Boolean Zap; /* Should the the zap effect be used. */ Xextern Boolean FocusSetByUser; /* True if f.focus called */ Xextern Boolean FocusSetByWM; /* True if awm set the focus */ X Xextern char PText[]; /* Pop-up window dummy text. */ Xextern int PTextSize; /* Pop-up window dummy text size. */ X Xextern int Lineno; /* Line count for parser. */ Xextern Boolean Startup_File_Error; /* Startup file error flag. */ Xextern char Startup_File[]; /* Startup file name. */ Xextern char *IFontName; /* Icon font name. */ Xextern char *PFontName; /* Pop-up font name. */ Xextern char *TFontName; /* Title font name. */ Xextern char *GFontName; /* Gadget font name */ Xextern char *TFontBoldName; /* Bold Title font name. */ Xextern char *TBoldPixmapName; /* Title (highlighted) pixmap file */ Xextern char *TBackPixmapData; /* Bitmap data file title background */ Xextern char *TBoldPixmapData; /* ditto, except highlighted */ Xextern char *BBackPixmapData; /* Border Context area background pixmap data */ Xextern char *BBoldPixmapData; /* Border Context bold pixmap data */ Xextern char *awmPath; /* Pathlist for pixmap files */ Xextern char **Argv; /* Pointer to command line parameters. */ Xextern char **Environ; /* Pointer to environment. */ X Xextern char *DefaultBindings[]; /* Default bindings string array. */ Xextern Keyword KeywordTable[]; /* Keyword lookup table. */ Xextern Binding *Blist; /* Button/key bindings list. */ Xextern KeyExpr KeyExprTbl[]; /* Key expression table. */ Xextern ContExpr ContExprTbl[]; /* Context expression table. */ Xextern ButtonModifier ButtModTbl[];/* Button modifier table. */ Xextern GravityExpr GravityExprTbl[]; /* Gravity expression table. */ X Xextern GadgetDecl **Gadgets; /* Gadgets declared. See gram.y */ Xextern int scr; Xextern Display *dpy; /* Display info pointer. */ X X#ifdef PROFIL Xint ptrap(); X#endif X X/* X * External routine typing. X */ Xextern Boolean Beep(); Xextern Boolean CircleDown(); Xextern Boolean CircleUp(); Xextern Boolean Continue(); Xextern Boolean Focus(); Xextern Boolean UnFocus(); Xextern Boolean GetButton(); Xextern Boolean Iconify(); Xextern Boolean Lower(); Xextern Boolean DoMenu(); Xextern Boolean DoAction(); Xextern Boolean Lock(); Xextern Boolean Move(); Xextern Boolean MoveOpaque(); Xextern Boolean Neaten(); Xextern Boolean NewIconify(); Xextern Boolean Pause(); Xextern Boolean ShoveDown(); Xextern Boolean ShoveLeft(); Xextern Boolean ShoveRight(); Xextern Boolean ShoveUp(); Xextern Boolean Quit(); Xextern Boolean Raise(); Xextern Boolean Redraw(); Xextern Boolean Refresh(); Xextern Boolean ResetBindings(); Xextern Boolean ResetMenus(); Xextern Boolean ResetGadgets(); Xextern Boolean Resize(); Xextern Boolean Restart(); Xextern Boolean FDecorate(); Xextern Boolean FNoDecorate(); Xextern Boolean DestroyClient(); Xextern Boolean GetBoolRes(); Xextern Boolean ConfigureWindow(); Xextern int StoreCursors(); Xextern int StoreBox(); Xextern int StoreTitleBox(); Xextern int StoreGridBox(); Xextern int StoreTitleGridBox(); Xextern int StoreZap(); Xextern int Error(); Xextern int XError(); Xextern int GetIntRes(); Xextern Window Reparent(), Decorate(); Xextern unsigned char *expand_metachars(); Xextern char *stash(); Xextern char *GetIconName(); Xextern char *expand_from_path(); Xextern char *GetStringRes(); Xextern char *GetPixmapDataRes(); Xextern Pixmap GetPixmapRes(); Xextern Pixel GetColorRes(); Xextern Pixel GetPixel(); Xextern XFontStruct *GetFontRes(); Xextern Drawable GetPixmapFromCache(); Xextern AwmInfoPtr GetAwmInfo(); Xextern AwmInfoPtr RegisterWindow(); Xextern AwmInfoPtr IsTitled(); Xextern AwmInfoPtr IsGadgetWin(); X Xextern void Init_Titles(), Init_Frames(); Xextern void NoDecorate(); Xextern void PaintTitle(); Xextern void SetBorderPixmaps(); Xextern void FreePixmapFromCache(); X X#ifdef NEATEN X#define DEFAULT_ABS_MIN 64 X#define SEPARATION 2 X#define DEF_PRIMARY_PLACEMENT "Top" X#define DEF_SECONDARY_PLACEMENT "Left" X Xextern int AbsMinWidth; Xextern int AbsMinHeight; Xextern Boolean RetainSize; Xextern Boolean KeepOpen; Xextern Boolean Fill; Xextern Boolean UsePriorities; Xextern Boolean FixTopOfStack; Xextern char *PrimaryIconPlacement; Xextern char *SecondaryIconPlacement; X#endif NEATEN X#endif AWM_INCLUDE END_OF_FILE if test 22317 -ne `wc -c <'awm.h'`; then echo shar: \"'awm.h'\" unpacked with wrong size! fi # end of 'awm.h' fi if test -f 'menus/track_menu.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'menus/track_menu.c'\" else echo shar: Extracting \"'menus/track_menu.c'\" \(26567 characters\) sed "s/^X//" >'menus/track_menu.c' <<'END_OF_FILE' X X#ifndef lint X static char sccs_id[] = "@(#)track_menu.c 2.1 12/16/87 Siemens Corporate Research and Support, Inc."; X#endif X X X#include "X11/copyright.h" X X/* X RTL Menu Package Version 1.0 X by Joe Camaratta and Mike Berman, Siemens RTL, Princeton NJ, 1987 X X track_menu.c: bring up menus and track the mouse X */ X 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/* X X Copyright 1987 by X Siemens Corporate Research and Support, Inc., Princeton, New Jersey X X Permission to use, copy, modify, and distribute this software X and its documentation for any purpose and without fee is X hereby granted, provided that the above copyright notice X appear in all copies and that both that copyright notice and X this permission notice appear in supporting documentation, and X that the name of Siemens not be used in advertising or X publicity pertaining to distribution of the software without X specific, written prior permission. Siemens makes no X representations about the suitability of this software for any X purpose. It is provided "as is" without express or implied X warranty. X X */ X X/* X * The menu package will break if you don't define this, but X * it's there in case you want to see just how and where the X * "eventstack" stuff is used and, if necessary, replace it. X */ X#define SAVE_EVENTS X X X#include <stdio.h> X#include "X11/Xlib.h" X#include "X11/cursorfont.h" X#include "arrow_icon.h" X#include "null_icon.h" X#include "menu.h" X#include "menu.def.h" X#include "menu.ext.h" X#include "dbug.h" X#ifdef SAVE_EVENTS X#include "eventstack.h" X#endif X X#define MIN(x,y) (((x) <= (y))? x:y) X#define MAX(x,y) (((x) >= (y))? x:y) X X#define CLICK_TIME 290 /* in milliseconds */ X X#define CursorLockMask (ButtonReleaseMask | ExposureMask) X X/* Event macros */ X X#define EventGetXCoord(rep) ((rep).xmotion.x) X#define EventGetYCoord(rep) ((rep).xmotion.y) X#define EventType(rep) ((rep).type) X#define EventXWindow(rep) ((rep).xcrossing.window) X#define EventXTime(rep) ((rep).xcrossing.time) X#define EventXMode(rep) ((rep).xcrossing.mode) X#define EventXRootX(rep) ((rep).xcrossing.x_root) X#define EventXRootY(rep) ((rep).xcrossing.y_root) X#define EventXDetail(rep) ((rep).xcrossing.detail) X#define EventMWindow(rep) ((rep).xmotion.window) X#define EventMTime(rep) ((rep).xmotion.time) X#define EventButton(rep) ((rep).xbutton.button) X#define EventBWindow(rep) ((rep).xbutton.window) X#define EventBTime(rep) ((rep).xbutton.time) X#define EventEX(rep) ((rep).xexpose.x) X#define EventEY(rep) ((rep).xexpose.y) X#define EventEWidth(rep) ((rep).xexpose.width) X#define EventEHeight(rep) ((rep).xexpose.height) X#define PointerEvent(rep) \ X ((EventType(rep) == ButtonPress) || \ X (EventType(rep) == ButtonRelease) || \ X (EventType(rep) == MotionNotify) || \ X (EventType(rep) == EnterNotify) || \ X (EventType(rep) == LeaveNotify) || \ X (EventType(rep) == FocusIn) || \ X (EventType(rep) == FocusOut)) X#define KeyEvent(rep) \ X ((EventType(rep) == KeyPress) || (EventType(rep) == KeyRelease)) X/* Possible states for the state machine */ Xtypedef enum X{ X Initial, /* Inside a submenu, but not any item */ X CheckTrigger, /* Inside an item that has submenu, checking for pullright */ X Leaf, /* Inside an item with no submenu */ X Exit, /* Preparing to exit */ X LevelControl /* Not in any submenu, waiting to enter something */ X } State; X XState InitialState(), CheckTriggerState(), LeafState(), LevelControlState(), X GetItemState(); XBoolean EventNotSignificant(), PushSubmenu(); X Xvoid OutputEvent(), GetNextSignificantEvent(), PopSubmenu(), X Highlight(), Unhighlight(), DisplayInitialMenus(), LockCursor(), X TossExtraMoves(), UnlockCursor(); X Xvoid ProcessExposeEvents(); X Xvoid SaveTest(); X XMenuItem *MenuGetItem(); XMenu *MenuGetMenu(); X X/* global state variables */ X Xstatic MenuItem *current_item; Xstatic Menu *current_menu; Xstatic Window root_window; Xextern Display *dpy; Xextern int scr; Xstatic int level; /* submenu level */ Xstatic Time button_time; /* time button press invoked */ Xstatic Cursor wait_cursor = None; /* empty cursor for lock state */ Xstatic Boolean click_allowed; Xstatic Boolean lock_event_mask, unlock_event_mask; X Xextern Boolean Autoselect; Xextern int MDelta; X X#ifdef SAVE_EVENTS Xstatic struct Ev_q *ev_save = 0; X#endif X X XMenuItem *TrackMenu(root_menu, root_x, root_y, X init_button, root, buttime) XMenu *root_menu; /* Pointer to root menu requested to pop up */ Xint root_x, root_y; /* Position to start menu */ Xint init_button; /* The # of button used to pop up menu */ XWindow root; /* Window label for parent of menu */ XTime buttime; /* timestamp for button (or 0, if CLICK == 0) */ X{ X State CurrentState = LevelControl; X XEvent Event_Reply; X int open_x; X Boolean selected = FALSE; X MenuItem *selected_item; X X Entry("TrackMenu") X X /* Initialize globals */ X X button_time = buttime; X root_window = root; X level = 0; X current_menu = root_menu; X click_allowed = (TestOptionFlag(current_menu, clickokay))? TRUE : FALSE; X unlock_event_mask = (TestOptionFlag(current_menu, savebits))? X MenuEventMask : (MenuEventMask | ExposureMask); X lock_event_mask = (TestOptionFlag(current_menu, savebits))? X CursorLockMask : (CursorLockMask | ExposureMask); X X /* If not already done, set up the null cursor for lock state */ X if (wait_cursor == None) X { X Pixmap wc_pixmap; X XColor fg, bg; X X wc_pixmap = XCreateBitmapFromData (dpy, root_window, X null_icon_bits, X null_icon_width, null_icon_height); X wait_cursor = XCreatePixmapCursor (dpy, wc_pixmap, wc_pixmap, X &fg, &bg, 1, 1); X } X X X /* Block all other action by grabbing the server */ X /* XGrabServer (dpy); */ X /* Don't think we need to grab the server... so for now, we won't */ X X#ifdef SAVE_EVENTS X /* Get the present state, so it can be restored later */ X /* Any events on the queue when we start get saved now, restored later */ X SaveEvents (dpy, &ev_save, ~(unsigned long) ButtonReleaseMask); X#endif X X LockCursor(root_window); X if (!(current_item = X Display_Menu(current_menu, NULLMENU, root_x, root_y))) X { X CurrentState = Exit; X } X /* X * First item is a label and autoselect is on, so we want X * to push on to the first "real" item. X */ X if (ItemIsDeaf(current_item) && Autoselect) X current_item = current_item->nextItem; X LockCursor(ItemWindow(current_item)); X open_x = root_x; X X /* Push to appropriate previous item, if any */ X while (MenuHasInitialItem(current_menu) && (CurrentState != Exit)) X { X current_item = GetInitialItem(current_menu); X ClearInitialItem(current_menu); X X /* if the initial item can't be selected, take first in list */ X if (ItemIsNull(current_item) || ItemIsDisabled(current_item)) X { X current_item = MenuItems(current_menu); X break; X } X else if (ItemIsLeaf(current_item)) /* then we're done */ X break; X else X { X open_x += ItemGetArrowPosition(current_item); X if (!ItemIsDeaf(current_item)) X Highlight(current_item); X TossExtraMoves(ItemWindow(current_item)); X (void)PushSubmenu(open_x); X } X } X ProcessExposeEvents(); X if (CurrentState != Exit) X CurrentState = (ItemIsLeaf(current_item)) ? Leaf : CheckTrigger; X if (!ItemIsDeaf(current_item)) X Highlight(current_item); X XSync (dpy, 0); /* get release click, if it's in queue */ X#ifdef SAVE_EVENTS X DisposeEvents(dpy, (PointerMotionMask | EnterWindowMask | X LeaveWindowMask | ExposureMask)); X#endif X LockCursor(ItemWindow(current_item)); X PlacePointer(current_menu,current_item); X UnlockCursor(); X X /* State Machine */ X X while (CurrentState != Exit) X { X GetNextSignificantEvent(&Event_Reply, init_button); X switch (CurrentState) X { X case LevelControl: X CurrentState = LevelControlState(Event_Reply); X break; X case Initial: X CurrentState = InitialState(Event_Reply); X break; X case CheckTrigger: X CurrentState = CheckTriggerState(Event_Reply); X break; X case Leaf: X CurrentState = LeafState(Event_Reply, &selected); X break; X default: X Retch("(RTLmenu) YOW! Unknown State! (%d)\n", X CurrentState); X CurrentState = Exit; X break; X } X } X /* Clean up and exit */ X X selected_item = (selected)? current_item : NULLITEM; X while (level) X { X if (selected) X SetInitialItem(current_menu, current_item); X PopSubmenu(); X } X if (selected) X { X SetInitialItem(current_menu, current_item); X } X X Undisplay_Menu(current_menu); X UnlockCursor(); X XUngrabPointer(dpy, CurrentTime); X X /* Throw out any left over events from menu world */ X /* if (TestOptionFlag(current_menu, savebits)) { X XSync(dpy,1); X XUngrabServer(dpy, CurrentTime); add this if grab added! X } X else X XSync(dpy,0);*/ X X /* Push back any events that were lying around when menus started */ X X XFlush(dpy); X#ifdef SAVE_EVENTS X DisposeEvents(dpy, (PointerMotionMask | EnterWindowMask | X LeaveWindowMask | ExposureMask)); X RestoreEvents(dpy, &ev_save); X#endif X Leave(selected_item) X} X X/* Used for debugging */ X Xvoid OutputEvent(Event_Reply) XXEvent Event_Reply; X{ X Entry("OutputEvent") X X switch (EventType(Event_Reply)) X { X case ButtonPress: X case ButtonRelease: X DBUG_5("RTLmenu","Button Press/Release, button %d on window %d at time %d\n", X EventButton(Event_Reply), EventBWindow(Event_Reply), X EventBTime(Event_Reply)); X break; X case MotionNotify: X DBUG_5("RTLmenu","Motion Notify on window %d at time %d, x=%d\n", X EventMWindow(Event_Reply), EventMTime(Event_Reply), X EventGetXCoord(Event_Reply)); X break; X case EnterNotify: X DBUG_4("RTLmenu","Enter Notify on window %d at time %d\n", X EventXWindow(Event_Reply), EventXTime(Event_Reply)); X break; X case LeaveNotify: X DBUG_4("RTLmenu","Leave Notify on window %d at time %d\n", X EventXWindow(Event_Reply), EventXTime(Event_Reply)); X break; X default: X DBUG_3("RTLmenu","Unexpected event type %d\n", EventType(Event_Reply)); X break; X } X Leave_void X} X Xstatic Boolean locked = FALSE; X X/* Lock the cursor: make it disappear, and ignore events it generates. */ X/* Optionally, confine it to a single window. */ X/* (Using "None" for confine_window doesn't confine it. ) */ Xvoid LockCursor(confine_window) XWindow confine_window; X{ X int result; X X Entry("LockCursor") X X locked = TRUE; X result = XGrabPointer(dpy, X RootWindow(dpy, MenuScreen(current_menu)), X True, lock_event_mask, GrabModeSync, X GrabModeAsync, confine_window, X wait_cursor, CurrentTime); X DBUG_3("RTLmenu","Lock Cursor grab = %d\n",result); X Leave_void X} X X/* Unlock (and unconfine) the cursor. If cursor lock is not set, */ X/* this does nothing. */ X Xvoid UnlockCursor() X{ X int result; X X Entry("UnlockCursor") X X if (locked) X { X locked = FALSE; X result = XGrabPointer(dpy, X RootWindow(dpy, MenuScreen(current_menu)), X True, unlock_event_mask, X GrabModeAsync, GrabModeAsync, None, X MenuCursor(current_menu), CurrentTime); X DBUG_3("RTLmenu","Unlock Cursor grab = %d\n",result); X } X Leave_void X} X X/* Keep getting the X events, until finding one that may be interesting */ X/* to the operation of the state machine. */ X Xvoid GetNextSignificantEvent(Event_Reply,init_button) XXEvent *Event_Reply; Xint init_button; /* the button that initiated the menu */ X{ X XEvent Next_Event_Reply; X Boolean InsignificantEvent = True; X X Entry("GetNextSignificantEvent") X X /* Loop as long as any of a number of "insignificant" events */ X /* are found; when the event no longer matches one of the tests, */ X /* it is assumed to be "significant" and returned.*/ X do X { X XNextEvent(dpy, Event_Reply); X DBUG_EXECUTE("RTLmenu", OutputEvent(*Event_Reply)); X X /* If this event is an "enter", check whether there is a */ X /* "leave" for the same window already in the queue, */ X /* immediately following it; if so, throw them both out */ X /* and get the next event */ X /* NOTE: might try to look further ahead, but this is */ X /* tricky because other events might intervene. */ X X if ((EventType(*Event_Reply) == EnterNotify) && X (EventXMode(*Event_Reply) == NotifyNormal) && X (QLength(dpy) > 0) && X (MenuGetMenu(current_menu, EventXWindow(*Event_Reply)) X != current_menu)) X { X XPeekEvent(dpy, &Next_Event_Reply); X if ((EventType(Next_Event_Reply) == LeaveNotify) && X (EventXMode(Next_Event_Reply) == NotifyNormal) && X (EventXWindow(Next_Event_Reply) == EventXWindow(*Event_Reply))) X { X DBUG_2("RTLmenu","TOSS: Enter/leave pair.\n"); X XNextEvent(dpy, Event_Reply); X XNextEvent(dpy, Event_Reply); X } X } X#ifdef SAVE_EVENTS X if (EventNotSignificant(*Event_Reply, init_button)) X { X if (!(PointerEvent(*Event_Reply) || KeyEvent(*Event_Reply) X || EventType(*Event_Reply) == Expose)) X { X /* might be significant elsewhere -- save it for later */ X AddEventToStore(&ev_save, *Event_Reply); X } X } X else X#else X if (!EventNotSignificant(*Event_Reply, init_button)) X#endif X InsignificantEvent = FALSE; X } X while (InsignificantEvent); X X DBUG_2("RTLmenu","--->"); X Leave_void X} X X/* Check whether the event matches one of the events considered */ X/* "not significant".*/ XBoolean EventNotSignificant(Event_Reply, init_button) XXEvent Event_Reply; Xint init_button; X{ X Entry("EventNotSignificant") X X /* Insignificant if not in following list */ X Leave(!((EventType(Event_Reply) == ButtonRelease) || X (EventType(Event_Reply) == ButtonPress) || X (EventType(Event_Reply) == MotionNotify) || X (EventType(Event_Reply) == EnterNotify) || X (EventType(Event_Reply) == Expose) || X (EventType(Event_Reply) == LeaveNotify)) X || X /* Insignificant if leave or enter is not "Normal" */ X (((EventType(Event_Reply) == LeaveNotify) || X (EventType(Event_Reply) == EnterNotify)) && X (EventXMode(Event_Reply) != NotifyNormal)) X || X /* Insignificant if hit button other than initial one */ X ((EventType(Event_Reply) == ButtonRelease) && X (EventButton(Event_Reply) != init_button)) X || X /* Insignificant if tail end of a click -- and clicks allowed */ X (click_allowed && X (EventType(Event_Reply) == ButtonRelease) && X (EventBTime(Event_Reply) - button_time < CLICK_TIME)) X ) X} X XState LevelControlState(rep) XXEvent rep; X{ X State next_state; X Menu *entered_menu; X MenuItem *entered_item; X X Entry("LevelControlState") X switch (EventType(rep)) X { X case MotionNotify: X case LeaveNotify: X next_state = LevelControl; /* loop back to this state */ X break; X case EnterNotify: X /* Decide whether we've entered a menu window or item window */ X entered_menu = MenuGetMenu(current_menu, EventXWindow(rep)); X entered_item = MenuGetItem(current_menu,EventXWindow(rep)); X X if ((MenuIsNull(entered_menu)) && (ItemIsNull(entered_item))) X /* Must be some other window; carry on */ X next_state = LevelControl; X else if (!ItemIsNull(entered_item) && X MenuIsDisplayed(ItemMenu(entered_item))) X { X /* we entered an item, but not a window. This should only happen */ X /* when we stayed in the parent of the current submenu. So, */ X /* Pop that submenu and get to the item. */ X if (level) X { X LockCursor(ItemWindow(entered_item)); X PopSubmenu(); X ProcessExposeEvents(); X UnlockCursor(); X current_item = entered_item; X Highlight(current_item); X next_state = GetItemState(rep); X } X else X { X Retch("(RTLmenu) Tried to pop the root menu...\n"); X next_state = Exit; X } X } X X else if (!MenuIsNull(entered_menu)&& X MenuIsDisplayed(entered_menu)) X { X /* entered a menu that is displayed */ X while ((current_menu != entered_menu) && level) X /* drop down the menu that was entered */ X PopSubmenu(); X ProcessExposeEvents(); X UnlockCursor(); X if (current_menu == entered_menu) X next_state = Initial; X else X { X next_state = Exit; X Retch("(RTLmenu) Couldn't find the menu I entered!!\n"); X } X } X else X next_state = LevelControl; X break; X case ButtonRelease: X next_state = Exit; X break; X default: X Retch("RTLmenu","YOW! Unexpected event! (%d)\n", rep.type); X next_state = Exit; X break; X } X Leave(next_state) X} X X/* Figure out the status of the item we've just entered */ XState GetItemState(rep) XXEvent rep; X{ X int open_x; X State next_state; X X Entry("GetItemState") X if (ItemIsNull(current_item)) X { X Retch("(RTLmenu) null current item!"); X next_state = Exit; X } X else if (MenuIsNull(current_menu)) X { X Retch("(RTLmenu) null current menu!"); X next_state = Exit; X } X else if (ItemIsLeaf(current_item)) X { X if (MenuHasInitialItem(current_menu)) X ClearInitialItem(current_menu); X next_state = Leaf; X } X else if (EventGetXCoord(rep) >= (int)(ItemGetArrowPosition(current_item) - 4)) X { X /* entered item in "auto pop-up zone", i.e., over pull-right arrow. */ X LockCursor(ItemWindow(current_item)); X TossExtraMoves(ItemWindow(current_item)); X if (PushSubmenu(EventXRootX(rep))) X { X LockCursor(ItemWindow(current_item)); X PlacePointer(current_menu, current_item); X next_state = Initial; X ProcessExposeEvents(); X } X else X next_state = CheckTrigger; X UnlockCursor(); X } X else if (MenuHasInitialItem(current_menu)) X { X /* Entered menu has initial item -- move to it */ X DBUG_2("RTLmenu","Pushing for initial item."); X current_item = GetInitialItem(current_menu); X open_x = ItemGetArrowPosition(current_item) + X EventXRootX(rep); X ClearInitialItem(current_menu); X LockCursor(ItemWindow(current_item)); X if (PushSubmenu(open_x)) X { X ProcessExposeEvents(); X LockCursor(ItemWindow(current_item)); X PlacePointer(current_menu, current_item); X next_state = Initial; X } X UnlockCursor(); X } X else /* parent pull */ X next_state = CheckTrigger; X Leave(next_state) X} X XState InitialState( rep) XXEvent rep; X{ X State next_state; X X Entry("Initial") X switch (EventType(rep)) X { X case EnterNotify: X if (MenuIsNull(current_menu)) X { X Retch("(RTLmenu) null current menu!?!?"); X next_state = Exit; X } X else if (EventXDetail(rep) == NotifyInferior) X next_state = Initial; X else X { X current_item = MenuGetItem(current_menu, EventXWindow(rep)); X if (ItemIsNull(current_item)) X { X /* Retch("(RTLmenu) Window entered not an item!\n"); */ X next_state = Initial; X } X else X { X Highlight(current_item); X next_state = GetItemState(rep); X } X } X break; X case LeaveNotify: X /* Decide whether we're actually leaving */ X /* this menu for another submenu or the root, */ X /* or going into an item. */ X next_state = (EventXDetail(rep) == NotifyInferior)? X Initial : LevelControl; X break; X case ButtonRelease: X next_state = Exit; X break; X case MotionNotify: X next_state = Initial; X break; X default: X Retch("(RTLmenu) YOW! Unexpected event! (%d)\n", rep.type); X next_state = Exit; X break; X } X Leave(next_state) X} X X#define NotSet -1 X/* Look to see if pull-right is requested */ XState CheckTriggerState(rep) XXEvent rep; X{ X State next_state = CheckTrigger; X static int Trigger = NotSet; X static int OldX, NewX, childX, button; X X Entry("CheckTrigger") X if (MenuIsNull(current_menu) || ItemIsNull(current_item)) X { X Retch("(RTLmenu) Null menu or item..."); X next_state = Exit; X goto exit; X } X if (Trigger == NotSet) /* set it */ X { X Trigger = MIN(EventGetXCoord(rep) + MenuDelta(current_menu), X ItemGetArrowPosition(current_item)); X NewX = NotSet; X } X switch (EventType(rep)) X { X case LeaveNotify: X next_state = Initial; X Unhighlight(MenuGetItem(current_menu, EventXWindow(rep))); X Trigger = NotSet; X break; X case ButtonRelease: X next_state = Exit; X Trigger = NotSet; X break; X X case ButtonPress: X button = rep.xbutton.button; X while (TRUE) { X XNextEvent(dpy, &rep); X if (rep.type == ButtonRelease && X rep.xbutton.button == button) X break; X } X next_state = CheckTrigger; X childX = TestOptionFlag(current_menu, fixedchild) ? X (MenuX(current_menu) + ItemGetArrowPosition(current_item)) : X EventXRootX(rep); X Trigger = NotSet; X if (PushSubmenu(childX)) X { X next_state = LevelControl; X ProcessExposeEvents(); X LockCursor(ItemWindow(current_item)); X PlacePointer(current_menu, current_item); X } X UnlockCursor(); X break; X X case MotionNotify: X next_state = CheckTrigger; X OldX = NewX; X NewX = EventGetXCoord(rep); X if (NewX >= Trigger) X { X LockCursor(ItemWindow(current_item)); X childX = TestOptionFlag(current_menu, fixedchild)? X (MenuX(current_menu) + ItemGetArrowPosition(current_item)): X EventXRootX(rep); X Trigger = NotSet; X if (PushSubmenu(childX)) X { X next_state = LevelControl; X ProcessExposeEvents(); X LockCursor(ItemWindow(current_item)); X PlacePointer(current_menu, current_item); X } X UnlockCursor(); X } X else if (NewX < OldX) /* reverse motion */ X Trigger = MIN(Trigger, NewX + MenuDelta(current_menu)); X break; X X default: X Retch("(RTLmenu) YOW! Unexpected event!\n"); X next_state = Exit; X break; X } X exit: X Leave(next_state) X} X XState LeafState(rep,selected) XXEvent rep; XBoolean *selected; X{ X State next_state; X X Entry("LeafState") X switch(EventType(rep)) X { X case LeaveNotify: X Unhighlight(MenuGetItem(current_menu, EventXWindow(rep))); X next_state = Initial; X break; X X case ButtonRelease: X *selected = TRUE; X next_state = Exit; X break; X X case ButtonPress: X case EnterNotify: X case MotionNotify: /* if events set right, this never happens */ X next_state = Leaf; X break; X X default: X Retch("(RTLMenu) YOW! Unexpected event! (%d)\n", X rep.type); X next_state = Exit; X break; X } X Leave(next_state) X} X XBoolean PushSubmenu(x) Xint x; X{ X int y; X Boolean pushed; X MenuItem *new_current_item; X X Entry("PushSubmenu") X X if (ItemIsNull(current_item)) X { X Retch("(RTLMenu) Can't push from null item.\n"); X pushed = FALSE; X } X else if (MenuIsNull(ItemSubmenu(current_item))) X { X Retch("(RTLmenu) Null submenu.\n"); X pushed = FALSE; X } X else if (ItemIsNull(MenuItems(ItemSubmenu(current_item)))) X /* submenu has no items -- don't push, but not an error */ X pushed = FALSE; X else X { X y = ItemGetMiddleY(current_item); X ++level; X X if (new_current_item = X Display_Menu(ItemSubmenu(current_item), current_menu, x, y)) X { X XFlush(dpy); X current_menu = ItemSubmenu(current_item); X current_item = new_current_item; X if (ItemIsDeaf(current_item) && Autoselect) X current_item = current_item->nextItem; X pushed = TRUE; X } X else X { X Retch("(RTLmenu) Display_Menu failed!\n"); X pushed = FALSE; X } X } X Leave(pushed) X} X Xvoid PopSubmenu() X{ X Menu *parent; X MenuItem *item; X X Entry("PopSubmenu") X --level; X parent = current_menu->parentMenu; X Undisplay_Menu(current_menu); X current_menu = parent; X if (!MenuIsNull(current_menu)) X { X item = MenuItemHighlighted(current_menu); X if (!ItemIsNull(item)) X { X current_item = item; X } X } X X Leave_void X} X Xvoid Highlight(item) XMenuItem *item; X{ X MenuItem *old_highlight; X X Entry("Highlight") X X old_highlight = MenuItemHighlighted(current_menu); X if ((item != old_highlight) && /* else, already highlighted */ X (!ItemIsNull(item))) X { X if (!ItemIsNull(old_highlight) && !ItemIsDeaf(item)) X Unhighlight(old_highlight); X SetHighlightItem(ItemMenu(item), item); X Draw_Item(ItemMenu(item), item); X } X Leave_void X} X Xvoid Unhighlight(item) XMenuItem *item; X{ X Entry("Unhighlight") X if (!ItemIsNull(item)) X { X if (MenuItemHighlighted(current_menu) == item) X { X ResetHighlightItem(ItemMenu(item)); X Draw_Item(ItemMenu(item), item); X } X } X Leave_void X} X Xvoid TossExtraMoves(window) XWindow window; X{ X XEvent ev; X X Entry("TossExtraMoves") X while (XCheckTypedWindowEvent(dpy, window, MotionNotify, &ev)) X DBUG_2("RTLmenu","Tossing extra motion.\n"); X Leave_void X} X X Xvoid ProcessExposeEvents() X{ X MenuItem *item; X XEvent ev; X X Entry("ProcessExposeEvents") X X XSync(dpy,0); X while (XCheckTypedEvent(dpy, Expose, &ev)) X { X item = MenuGetItem(current_menu, EventXWindow(ev)); X if (!ItemIsNull(item)) X Draw_Item(ItemMenu(item), item); X } X Leave_void X} END_OF_FILE if test 26567 -ne `wc -c <'menus/track_menu.c'`; then echo shar: \"'menus/track_menu.c'\" unpacked with wrong size! fi # end of 'menus/track_menu.c' fi echo shar: End of archive 5 \(of 12\). cp /dev/null ark5isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 12 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 Moderator of comp.sources.x