tlastran@esunix.UUCP (Tom LaStrange) (06/04/88)
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting test in a file
# 3. Execute the file with /bin/sh (not csh) to create the files:
#
#menus.c
#util.c
#version.c
#
# Created by tlastran (Tom LaStrange) on Fri Jun 3 11:32:50 MDT 1988
#
if test -f 'menus.c'
then
echo shar: will not over-write existing file "menus.c"
else
echo extracting "menus.c"
sed 's/^X//' >menus.c <<'SHAR_EOF'
X/*****************************************************************************/
X/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/
X/** Salt Lake City, Utah **/
X/** **/
X/** All Rights Reserved **/
X/** **/
X/** Permission to use, copy, modify, and distribute this software and **/
X/** its documentation for any purpose and without fee is hereby **/
X/** granted, provided that the above copyright notice appear in all **/
X/** copies and that both that copyright notice and this permis- **/
X/** sion notice appear in supporting documentation, and that the **/
X/** name of Evans & Sutherland not be used in advertising or publi- **/
X/** city pertaining to distribution of the software without specif- **/
X/** ic, written prior permission. **/
X/** **/
X/** EVANS & SUTHERLAND DISCLAIMS ALL WARRANTIES WITH REGARD TO **/
X/** THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILI- **/
X/** TY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND BE LIABLE **/
X/** FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAM- **/
X/** AGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, **/
X/** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS **/
X/** ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PER- **/
X/** FORMANCE OF THIS SOFTWARE. **/
X/*****************************************************************************/
X
X/***********************************************************************
X *
X * $Header: menus.c,v 1.34 88/06/03 10:45:54 tlastran Exp $
X *
X * twm menu code
X *
X * 17-Nov-87 Thomas E. LaStrange File created
X *
X ***********************************************************************/
X
X#ifndef lint
Xstatic char RCSinfo[] =
X"$Header: menus.c,v 1.34 88/06/03 10:45:54 tlastran Exp $";
X#endif
X
X#include <stdio.h>
X#include <signal.h>
X#include "twm.h"
X#include "gc.h"
X#include "menus.h"
X#include "events.h"
X#include "util.h"
X#include "gram.h"
X
X#include "pull.bm"
X
Xint RootFunction = NULL;
XMenuRoot *MenuList = NULL; /* head of the menu list */
XMenuRoot *LastMenu = NULL; /* the last menu */
XMenuRoot *ActiveMenu = NULL; /* the active menu */
XMenuItem *ActiveItem = NULL; /* the active menu item */
XMouseButton Mouse[MAX_BUTTONS+1][NUM_CONTEXTS][MOD_SIZE];
X
X/***********************************************************************
X *
X * Procedure:
X * InitMenus - initialize menu roots
X *
X ***********************************************************************
X */
X
Xvoid
XInitMenus()
X{
X int i, j, k;
X
X for (i = 0; i < MAX_BUTTONS+1; i++)
X for (j = 0; j < NUM_CONTEXTS; j++)
X for (k = 0; k < MOD_SIZE; k++)
X Mouse[i][j][k].func = NULL;
X
X Mouse[1][C_TITLE][0].func = F_RAISE;
X Mouse[2][C_TITLE][0].func = F_MOVE;
X Mouse[3][C_TITLE][0].func = F_LOWER;
X
X Mouse[1][C_ICON][0].func = F_RAISE;
X Mouse[2][C_ICON][0].func = F_MOVE;
X Mouse[3][C_ICON][0].func = F_LOWER;
X}
X
X/***********************************************************************
X *
X * Procedure:
X * NewMenuRoot - create a new menu root
X *
X * Returned Value:
X * (MenuRoot *)
X *
X * Inputs:
X * name - the name of the menu root
X *
X ***********************************************************************
X */
X
XMenuRoot *
XNewMenuRoot(name)
X char *name;
X{
X MenuRoot *tmp;
X
X CreateGCs();
X
X tmp = (MenuRoot *) malloc(sizeof(MenuRoot));
X tmp->name = name;
X tmp->prev = NULL;
X tmp->first = NULL;
X tmp->last = NULL;
X tmp->items = 0;
X tmp->width = 0;
X tmp->mapped = FALSE;
X tmp->pull = FALSE;
X tmp->active = TRUE;
X tmp->shadow = XCreateSimpleWindow(dpy, Root,
X 0, 0, 10, 10, 1, MenuShadowColor, MenuShadowColor);
X tmp->w = XCreateSimpleWindow(dpy, Root,
X 0, 0, 10, 10, 1, MenuForeground, MenuBackground);
X XSelectInput(dpy, tmp->w, LeaveWindowMask);
X
X if (MenuList == NULL)
X {
X MenuList = tmp;
X MenuList->next = NULL;
X }
X
X if (LastMenu == NULL)
X {
X LastMenu = tmp;
X LastMenu->next = NULL;
X }
X else
X {
X LastMenu->next = tmp;
X LastMenu = tmp;
X LastMenu->next = NULL;
X }
X
X return (tmp);
X}
X
X/***********************************************************************
X *
X * Procedure:
X * AddToMenu - add an item to a root menu
X *
X * Returned Value:
X * (MenuItem *)
X *
X * Inputs:
X * menu - pointer to the root menu to add the item
X * item - the text to appear in the menu
X * action - the string to possibly execute
X * sub - the menu root if it is a pull-right entry
X * func - the numeric function
X *
X ***********************************************************************
X */
X
XMenuItem *
XAddToMenu(menu, item, action, sub, func)
X MenuRoot *menu;
X char *item, *action;
X MenuRoot *sub;
X int func;
X{
X unsigned long valuemask;
X XSetWindowAttributes attributes;
X MenuItem *tmp;
X int width;
X
X#ifdef DEBUG
X fprintf(stderr, "adding menu item=\"%s\", action=%s, sub=%d, f=%d\n",
X item, action, sub, func);
X#endif
X
X tmp = (MenuItem *) malloc(sizeof(MenuItem));
X tmp->root = menu;
X
X if (menu->first == NULL)
X {
X menu->first = tmp;
X tmp->prev = NULL;
X }
X else
X {
X menu->last->next = tmp;
X tmp->prev = menu->last;
X }
X menu->last = tmp;
X
X tmp->item = item;
X tmp->action = action;
X tmp->next = NULL;
X tmp->sub = NULL;
X tmp->pull = NULL;
X tmp->state = 0;
X tmp->func = func;
X
X width = XTextWidth(MenuFont, item, strlen(item));
X if (width <= 0)
X width = 1;
X if (width > menu->width)
X menu->width = width;
X
X if (tmp->func != F_TITLE)
X {
X tmp->w = XCreateSimpleWindow(dpy, menu->w,
X 0, menu->items * (MenuFontHeight + 4),
X width, MenuFontHeight + 4,
X 0,
X MenuForeground, MenuBackground);
X XSelectInput(dpy, tmp->w, EnterWindowMask
X | LeaveWindowMask | ExposureMask);
X }
X else
X {
X tmp->w = XCreateSimpleWindow(dpy, menu->w,
X -1, menu->items * (MenuFontHeight + 4),
X width, MenuFontHeight + 2,
X 1,
X MenuForeground, MenuTitleBackground);
X XSelectInput(dpy, tmp->w, ExposureMask);
X }
X
X if (sub != NULL)
X {
X Pixmap pm;
X
X tmp->sub = sub;
X pm = MakeCenteredPixmap(tmp->w, MenuNormalGC,
X pull_width, MenuFontHeight + 4,
X pull_bits, pull_width, pull_height);
X
X valuemask = CWEventMask | CWBackPixmap;
X attributes.background_pixmap = pm;
X attributes.event_mask = EnterWindowMask | LeaveWindowMask;
X
X tmp->pull = XCreateWindow(dpy, tmp->w,
X 0, 0,
X pull_width, MenuFontHeight + 4,
X 0, DefaultDepth(dpy, 0), CopyFromParent, DefaultVisual(dpy, 0),
X valuemask, &attributes);
X
X XMapWindow(dpy, tmp->pull);
X
X menu->pull = TRUE;
X XSaveContext(dpy, tmp->pull, MenuContext, tmp);
X }
X menu->items += 1;
X
X XSaveContext(dpy, tmp->w, MenuContext, tmp);
X
X if (menu->items == 1)
X XSaveContext(dpy, tmp->root->w, MenuContext, tmp);
X
X return (tmp);
X}
X
X/***********************************************************************
X *
X * Procedure:
X * PopUpMenu - pop up a pull down menu
X *
X * Inputs:
X * menu - the root pointer of the menu to pop up
X * x - the x location of the mouse
X * y - the y location of the mouse
X *
X ***********************************************************************
X */
X
Xvoid
XPopUpMenu(menu, x, y)
X MenuRoot *menu;
X int x, y;
X{
X int d_width, d_height, m_height;
X XWindowChanges xwc, pwc;
X unsigned int xwcm, pwcm;
X MenuItem *tmp;
X
X if (menu == NULL)
X return;
X
X if (ActiveMenu != NULL)
X ActiveMenu->active = FALSE;
X
X menu->active = TRUE;
X ActiveMenu = menu;
X if (menu->mapped != TRUE)
X {
X if (menu->pull == TRUE)
X {
X menu->width += pull_width + 10;
X }
X
X xwcm = 0;
X xwcm |= CWWidth;
X xwc.width = menu->width + 10;
X
X pwcm = 0;
X pwcm |= CWX;
X pwc.x = xwc.width - pull_width;
X
X for (tmp = menu->first; tmp != NULL; tmp = tmp->next)
X {
X XConfigureWindow(dpy, tmp->w, xwcm, &xwc);
X if (tmp->pull != NULL)
X {
X XConfigureWindow(dpy, tmp->pull, pwcm, &pwc);
X }
X if (tmp->func != F_TITLE)
X tmp->y = 5;
X else
X {
X tmp->y = xwc.width - XTextWidth(MenuFont, tmp->item,
X strlen(tmp->item));
X tmp->y /= 2;
X }
X }
X }
X menu->mapped = TRUE;
X
X d_width = DisplayWidth(dpy, DefaultScreen(dpy));
X d_height = DisplayHeight(dpy, DefaultScreen(dpy));
X m_height = menu->items * (MenuFontHeight + 4);
X
X if ((x + menu->width + 10) > d_width)
X x = (d_width - menu->width - 20);
X
X if ((y + m_height + 10) > d_height)
X y = (d_height - m_height - 20);
X
X xwcm = 0;
X xwcm |= CWX;
X xwc.x = x - 1;
X xwcm |= CWY;
X xwc.y = y - ((MenuFontHeight + 4) / 2);
X xwcm |= CWWidth;
X xwc.width = menu->width + 10;
X xwcm |= CWHeight;
X xwc.height = m_height;
X
X XConfigureWindow(dpy, menu->w, xwcm, &xwc);
X
X xwc.x = xwc.x + 5;
X xwc.y = xwc.y + 5;
X /* xwc.width -= 20; xwc.height -= 20; */
X
X XConfigureWindow(dpy, menu->shadow, xwcm, &xwc);
X XWarpPointer(dpy, None, menu->w, 0, 0, 0, 0, 1, (MenuFontHeight + 4) / 2);
X XMapSubwindows(dpy, menu->w);
X XRaiseWindow(dpy, menu->shadow);
X XMapRaised(dpy, menu->w);
X XMapWindow(dpy, menu->shadow);
X}
X
X/***********************************************************************
X *
X * Procedure:
X * FindMenuRoot - look for a menu root
X *
X * Returned Value:
X * (MenuRoot *) - a pointer to the menu root structure
X *
X * Inputs:
X * name - the name of the menu root
X *
X ***********************************************************************
X */
X
XMenuRoot *
XFindMenuRoot(name)
X char *name;
X{
X MenuRoot *tmp;
X
X for (tmp = MenuList; tmp != NULL; tmp = tmp->next)
X {
X if (strcmp(name, tmp->name) == 0)
X return (tmp);
X }
X return NULL;
X}
X
X/***********************************************************************
X *
X * Procedure:
X * ExecuteFunction - execute a twm root function
X *
X * Inputs:
X * func - the function to execute
X * menu - the menu item to execute
X * w - the window to execute this function on
X * tmp_win - the twm window structure
X * event - the event that caused the function
X * context - the context in which the button was pressed
X * pulldown- flag indicating execution from pull down mene
X *
X ***********************************************************************
X */
X
Xvoid
XExecuteFunction(func, menu, w, tmp_win, event, context, pulldown)
X int func;
X MenuItem *menu;
X Window w;
X TwmWindow *tmp_win;
X XEvent event;
X int context;
X int pulldown;
X{
X static Time last_time = 0;
X
X char tmp[200];
X char *ptr;
X int len;
X char buff[MAX_FILE_SIZE];
X int count, fd;
X MenuRoot *root, *tmp_root;
X MenuItem *item, *tmp_item;
X
X XGrabPointer(dpy, Root, True,
X ButtonReleaseMask,
X GrabModeAsync, GrabModeSync,
X Root, ClockCursor, CurrentTime);
X
X switch (func)
X {
X case F_NOP:
X case F_TITLE:
X break;
X
X case F_RESIZE:
X if (DeferExecution(context, func, MoveCursor))
X return;
X
X if (pulldown)
X XWarpPointer(dpy, None, Root,
X 0, 0, 0, 0, event.xbutton.x_root, event.xbutton.y_root);
X
X if (w != tmp_win->icon_w)
X {
X EventHandler[EnterNotify] = HandleUnknown;
X EventHandler[LeaveNotify] = HandleUnknown;
X EventHandler[Expose] = HandleUnknown;
X StartResize(event, tmp_win);
X return;
X }
X break;
X
X case F_MOVE:
X if (DeferExecution(context, func, MoveCursor))
X return;
X
X if (pulldown)
X XWarpPointer(dpy, None, Root,
X 0, 0, 0, 0, event.xbutton.x_root, event.xbutton.y_root);
X
X EventHandler[EnterNotify] = HandleUnknown;
X EventHandler[LeaveNotify] = HandleUnknown;
X EventHandler[Expose] = HandleUnknown;
X
X /* redraw the text in the title bar or the icon window if
X * needed, we have disabled expose event handling so we must
X * do it here
X */
X if (context == C_TITLE)
X {
X XDrawImageString(dpy, tmp_win->title_w,
X TitleNormalGC,
X TitleBarX, TitleBarY,
X tmp_win->name, strlen(tmp_win->name));
X }
X else if (context == C_ICON)
X {
X XDrawImageString(dpy, tmp_win->icon_w,
X IconNormalGC,
X tmp_win->icon_x, tmp_win->icon_y,
X tmp_win->icon_name, strlen(tmp_win->icon_name));
X }
X
X XGrabServer(dpy);
X XGrabPointer(dpy, event.xbutton.root, True,
X ButtonReleaseMask,
X GrabModeAsync, GrabModeSync,
X Root, MoveCursor, CurrentTime);
X
X if (context == C_ICON)
X w = tmp_win->icon_w;
X else if (w != tmp_win->icon_w)
X w = tmp_win->frame;
X
X DragX = event.xbutton.x;
X DragY = event.xbutton.y;
X
X if (context == C_WINDOW)
X DragY += tmp_win->title_height;
X
X DragWindow = w;
X
X XGetGeometry(dpy, w, &JunkRoot, &JunkX, &JunkY,
X &DragWidth, &DragHeight, &JunkBW,
X &JunkDepth);
X
X MoveOutline((Window)event.xbutton.root,
X event.xbutton.x_root-DragX-BorderWidth,
X event.xbutton.y_root-DragY-BorderWidth,
X DragWidth + 2 * BorderWidth,
X DragHeight + 2 * BorderWidth);
X
X if ((event.xbutton.time - last_time) < 400)
X {
X int width, height;
X
X ConstMove = TRUE;
X ConstMoveDir = MOVE_NONE;
X ConstMoveX = event.xbutton.x_root - DragX - BorderWidth;
X ConstMoveY = event.xbutton.y_root - DragY - BorderWidth;
X width = DragWidth + 2 * BorderWidth;
X height = DragHeight + 2 * BorderWidth;
X ConstMoveXL = ConstMoveX + width/3;
X ConstMoveXR = ConstMoveX + 2*(width/3);
X ConstMoveYT = ConstMoveY + height/3;
X ConstMoveYB = ConstMoveY + 2*(height/3);
X
X XWarpPointer(dpy, None, DragWindow,
X 0, 0, 0, 0, DragWidth/2, DragHeight/2);
X
X XQueryPointer(dpy, DragWindow, &JunkRoot, &JunkChild,
X &JunkX, &JunkY, &DragX, &DragY, &JunkMask);
X }
X last_time = event.xbutton.time;
X return;
X break;
X
X case F_ICONIFY:
X if (DeferExecution(context, func, DotCursor))
X return;
X
X if (tmp_win->icon)
X {
X Zoom(tmp_win->icon_w, tmp_win->frame);
X
X XUnmapWindow(dpy, tmp_win->icon_w);
X XMapWindow(dpy, tmp_win->w);
X if (NoRaiseDeicon)
X XMapWindow(dpy, tmp_win->frame);
X else
X XMapRaised(dpy, tmp_win->frame);
X
X if (WarpCursor)
X {
X XWarpPointer(dpy, None, tmp_win->frame,
X 0, 0, 0, 0, 30, 8);
X }
X tmp_win->icon = FALSE;
X }
X else
X {
X if (!tmp_win->iconified)
X {
X int final_x, final_y;
X
X if (tmp_win->wmhints &&
X tmp_win->wmhints->flags & IconPositionHint)
X {
X final_x = tmp_win->wmhints->icon_x;
X final_y = tmp_win->wmhints->icon_y;
X }
X else
X {
X final_x = event.xbutton.x_root - 5;
X final_y = event.xbutton.y_root - 5;
X }
X
X if (final_x > MyDisplayWidth)
X final_x = MyDisplayWidth - tmp_win->icon_w_width -
X (2 * BorderWidth);
X
X if (final_y > MyDisplayHeight)
X final_y = MyDisplayHeight - tmp_win->icon_height -
X IconFontHeight - 4 - (2 * BorderWidth);
X
X XMoveWindow(dpy, tmp_win->icon_w, final_x, final_y);
X tmp_win->iconified = TRUE;
X }
X
X Zoom(tmp_win->frame, tmp_win->icon_w);
X XUnmapWindow(dpy, tmp_win->frame);
X XMapSubwindows(dpy, tmp_win->icon_w);
X XMapRaised(dpy, tmp_win->icon_w);
X if (tmp_win == Focus)
X {
X XSetInputFocus(dpy, Root, RevertToPointerRoot,
X CurrentTime);
X Focus = NULL;
X FocusRoot = TRUE;
X }
X tmp_win->icon = TRUE;
X }
X SetHints(tmp_win);
X break;
X
X case F_RAISE:
X if (DeferExecution(context, func, DotCursor))
X return;
X
X if (w == tmp_win->icon_w)
X {
X Zoom(tmp_win->icon_w, tmp_win->frame);
X XUnmapWindow(dpy, tmp_win->icon_w);
X XMapWindow(dpy, tmp_win->w);
X if (NoRaiseDeicon)
X XMapWindow(dpy, tmp_win->frame);
X else
X XMapRaised(dpy, tmp_win->frame);
X
X if (WarpCursor)
X {
X XWarpPointer(dpy, None, tmp_win->frame,
X 0, 0, 0, 0, 30, 8);
X }
X tmp_win->icon = FALSE;
X }
X else
X {
X XRaiseWindow(dpy, tmp_win->frame);
X }
X break;
X
X case F_LOWER:
X if (DeferExecution(context, func, DotCursor))
X return;
X
X XLowerWindow(dpy, tmp_win->frame);
X break;
X
X case F_FOCUS:
X if (DeferExecution(context, func, DotCursor))
X return;
X
X if (w != tmp_win->icon_w)
X {
X if (Focus != NULL && Focus != tmp_win)
X {
X XUnmapWindow(dpy, Focus->hilite_w);
X }
X XMapWindow(dpy, tmp_win->hilite_w);
X /*
X XSetWindowBorder(dpy, tmp_win->frame, Foreground);
X */
X XSetInputFocus(dpy, tmp_win->w, RevertToPointerRoot,
X CurrentTime);
X FocusRoot = FALSE;
X Focus = tmp_win;
X }
X break;
X
X case F_DESTROY:
X if (DeferExecution(context, func, SkullCursor))
X return;
X
X XKillClient(dpy, tmp_win->w);
X break;
X
X case F_CIRCLEUP:
X XCirculateSubwindowsUp(dpy, Root);
X break;
X
X case F_CIRCLEDOWN:
X XCirculateSubwindowsDown(dpy, Root);
X break;
X
X case F_VERSION:
X XMapRaised(dpy, VersionWindow);
X break;
X
X case F_EXEC:
X Execute(menu->action);
X break;
X
X case F_UNFOCUS:
X FocusOnRoot();
X break;
X
X case F_CUT:
X strcpy(tmp, menu->action);
X strcat(tmp, "\n");
X XStoreBytes(dpy, tmp, strlen(tmp));
X break;
X
X case F_CUTFILE:
X ptr = XFetchBytes(dpy, &count);
X if (count != 0)
X {
X if (sscanf(ptr, "%s", tmp) == 1)
X {
X ptr = ExpandFilename(tmp);
X fd = open(ptr, 0);
X if (fd >= 0)
X {
X count = read(fd, buff, MAX_FILE_SIZE - 1);
X if (count > 0)
X XStoreBytes(dpy, buff, count);
X
X close(fd);
X }
X else
X {
X fprintf(stderr, "twm: couldn't open \"%s\"\n", tmp);
X }
X }
X XFree(ptr);
X }
X else
X {
X fprintf(stderr, "twm: nothing in the cut buffer\n");
X }
X break;
X
X case F_FILE:
X menu->action = ExpandFilename(menu->action);
X fd = open(menu->action, 0);
X if (fd >= 0)
X {
X count = read(fd, buff, MAX_FILE_SIZE - 1);
X if (count > 0)
X XStoreBytes(dpy, buff, count);
X
X close(fd);
X }
X else
X {
X fprintf(stderr, "twm: couldn't open \"%s\"\n", menu->action);
X }
X break;
X
X case F_TWMRC:
X len = strlen(menu->action);
X if (len == 0)
X ptr = NULL;
X else
X {
X ptr = (char *)malloc(len+1);
X if (ptr == NULL)
X {
X fprintf(stderr, "twm: out of memory\n");
X exit(1);
X }
X strcpy(ptr, menu->action);
X }
X
X /* first get rid of the existing menu structure and destroy all
X * windows */
X for (root = MenuList; root != NULL;)
X {
X for (item = root->last; item != NULL;)
X {
X if (item->pull != NULL)
X {
X XDeleteContext(dpy, item->pull, MenuContext);
X XDestroyWindow(dpy, item->pull);
X }
X XDeleteContext(dpy, item->w, MenuContext);
X XDestroyWindow(dpy, item->w);
X
X free(item->item);
X free(item->action);
X
X tmp_item = item;
X item = item->prev;
X free(tmp_item);
X }
X
X XDeleteContext(dpy, root->w, MenuContext);
X XDestroyWindow(dpy, root->shadow);
X XDestroyWindow(dpy, root->w);
X free(root->name);
X
X tmp_root = root;
X root = root->next;
X free(tmp_root);
X }
X MenuList = NULL;
X LastMenu = NULL;
X ActiveMenu = NULL;
X ActiveItem = NULL;
X
X /* ungrab the buttons currently grabbed */
X for (tmp_win = TwmRoot.next; tmp_win != NULL; tmp_win = tmp_win->next)
X {
X UngrabButtons(tmp_win);
X }
X
X ParseTwmrc(ptr);
X
X /* now we have to redo the button grab mask for all windows */
X for (tmp_win = TwmRoot.next; tmp_win != NULL; tmp_win = tmp_win->next)
X {
X GrabButtons(tmp_win);
X }
X break;
X
X case F_REFRESH:
X w = XCreateSimpleWindow(dpy, Root,
X 0, 0, 9999, 9999, 0, Black, Black);
X XMapWindow(dpy, w);
X XDestroyWindow(dpy, w);
X XFlush(dpy);
X break;
X
X case F_WINREFRESH:
X if (DeferExecution(context, func, DotCursor))
X return;
X
X if (context == C_ICON)
X w = XCreateSimpleWindow(dpy, tmp_win->icon_w,
X 0, 0, 9999, 9999, 0, Black, Black);
X else
X w = XCreateSimpleWindow(dpy, tmp_win->frame,
X 0, 0, 9999, 9999, 0, Black, Black);
X
X XMapWindow(dpy, w);
X XDestroyWindow(dpy, w);
X XFlush(dpy);
X break;
X
X case F_QUIT:
X Done();
X break;
X }
X XUngrabPointer(dpy, CurrentTime);
X}
X
X/***********************************************************************
X *
X * Procedure:
X * DeferExecution - defer the execution of a function to the
X * next button press if the context is C_ROOT
X *
X * Inputs:
X * context - the context in which the mouse button was pressed
X * func - the function to defer
X * cursor - the cursor to display while waiting
X *
X ***********************************************************************
X */
X
Xint
XDeferExecution(context, func, cursor)
Xint context, func;
XCursor cursor;
X{
X if (context == C_ROOT)
X {
X XGrabPointer(dpy, Root, True,
X ButtonReleaseMask,
X GrabModeAsync, GrabModeSync,
X Root, cursor, CurrentTime);
X
X RootFunction = func;
X return (TRUE);
X }
X
X return (FALSE);
X}
X
X/***********************************************************************
X *
X * Procedure:
X * Execute - execute the string by /bin/sh
X *
X * Inputs:
X * s - the string containing the command
X *
X ***********************************************************************
X */
X
Xvoid
XExecute(s)
X char *s;
X{
X int status, pid, w;
X register int (*istat) (), (*qstat) ();
X
X if ((pid = vfork()) == 0)
X {
X signal(SIGINT, SIG_DFL);
X signal(SIGQUIT, SIG_DFL);
X signal(SIGHUP, SIG_DFL);
X execl("/bin/sh", "sh", "-c", s, 0);
X _exit(127);
X }
X istat = signal(SIGINT, SIG_IGN);
X qstat = signal(SIGQUIT, SIG_IGN);
X while ((w = wait(&status)) != pid && w != -1);
X if (w == -1)
X status = -1;
X signal(SIGINT, istat);
X signal(SIGQUIT, qstat);
X}
X
X/***********************************************************************
X *
X * Procedure:
X * FocusOnRoot - put input focus on the root window
X *
X ***********************************************************************
X */
X
Xvoid
XFocusOnRoot()
X{
X XSetInputFocus(dpy, Root, RevertToPointerRoot, CurrentTime);
X if (Focus != NULL)
X {
X XUnmapWindow(dpy, Focus->hilite_w);
X }
X Focus = NULL;
X FocusRoot = TRUE;
X}
X
SHAR_EOF
if test 21724 -ne "`wc -c < menus.c`"
then
echo shar: error transmitting "menus.c" '(should have been 21724 characters)'
fi
fi
if test -f 'util.c'
then
echo shar: will not over-write existing file "util.c"
else
echo extracting "util.c"
sed 's/^X//' >util.c <<'SHAR_EOF'
X/*****************************************************************************/
X/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/
X/** Salt Lake City, Utah **/
X/** **/
X/** All Rights Reserved **/
X/** **/
X/** Permission to use, copy, modify, and distribute this software and **/
X/** its documentation for any purpose and without fee is hereby **/
X/** granted, provided that the above copyright notice appear in all **/
X/** copies and that both that copyright notice and this permis- **/
X/** sion notice appear in supporting documentation, and that the **/
X/** name of Evans & Sutherland not be used in advertising or publi- **/
X/** city pertaining to distribution of the software without specif- **/
X/** ic, written prior permission. **/
X/** **/
X/** EVANS & SUTHERLAND DISCLAIMS ALL WARRANTIES WITH REGARD TO **/
X/** THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILI- **/
X/** TY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND BE LIABLE **/
X/** FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAM- **/
X/** AGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, **/
X/** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS **/
X/** ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PER- **/
X/** FORMANCE OF THIS SOFTWARE. **/
X/*****************************************************************************/
X
X/***********************************************************************
X *
X * $Header: util.c,v 1.17 88/06/03 06:39:10 tlastran Exp $
X *
X * utility routines for twm
X *
X * 28-Oct-87 Thomas E. LaStrange File created
X *
X ***********************************************************************/
X
X#ifndef lint
Xstatic char RCSinfo[]=
X"$Header: util.c,v 1.17 88/06/03 06:39:10 tlastran Exp $";
X#endif
X
X#include <stdio.h>
X#include "twm.h"
X#include "util.h"
X#include "gram.h"
X
X#define ZOOM_COUNT 8 /* number of outlines to draw while zooming */
X
X/***********************************************************************
X *
X * Procedure:
X * MoveOutline - move a window outline
X *
X * Inputs:
X * root - the window we are outlining
X * x - upper left x coordinate
X * y - upper left y coordinate
X * width - the width of the rectangle
X * height - the height of the rectangle
X *
X ***********************************************************************
X */
X
Xvoid
XMoveOutline(root, x, y, width, height)
X Window root;
X int x, y, width, height;
X{
X static int lastx = 0;
X static int lasty = 0;
X static int lastWidth = 0;
X static int lastHeight = 0;
X int xl, xr, yt, yb;
X int xthird, ythird;
X XSegment outline[16];
X XSegment *r = outline;
X
X if (x == lastx && y == lasty && width == lastWidth && height == lastHeight)
X return;
X
X xthird = lastWidth/3;
X ythird = lastHeight/3;
X xl = lastx;
X xr = lastx + lastWidth - 1;
X yt = lasty;
X yb = lasty + lastHeight - 1;
X
X if (lastWidth || lastHeight)
X {
X r->x1 = xl;
X r->y1 = yt;
X r->x2 = xr;
X r++->y2 = yt;
X
X r->x1 = xl;
X r->y1 = yb;
X r->x2 = xr;
X r++->y2 = yb;
X
X r->x1 = xl;
X r->y1 = yt;
X r->x2 = xl;
X r++->y2 = yb;
X
X r->x1 = xr;
X r->y1 = yt;
X r->x2 = xr;
X r++->y2 = yb;
X
X r->x1 = xl + xthird;
X r->y1 = yt;
X r->x2 = r->x1;
X r++->y2 = yb;
X
X r->x1 = xl + (2 * xthird);
X r->y1 = yt;
X r->x2 = r->x1;
X r++->y2 = yb;
X
X r->x1 = xl;
X r->y1 = yt + ythird;
X r->x2 = xr;
X r->y2 = r->y1;
X r++;
X
X r->x1 = xl;
X r->y1 = yt + (2 * ythird);
X r->x2 = xr;
X r->y2 = r->y1;
X r++;
X }
X
X lastx = x;
X lasty = y;
X lastWidth = width;
X lastHeight = height;
X xthird = lastWidth/3;
X ythird = lastHeight/3;
X xl = lastx;
X xr = lastx + lastWidth - 1;
X yt = lasty;
X yb = lasty + lastHeight - 1;
X
X if (lastWidth || lastHeight)
X {
X r->x1 = xl;
X r->y1 = yt;
X r->x2 = xr;
X r++->y2 = yt;
X
X r->x1 = xl;
X r->y1 = yb;
X r->x2 = xr;
X r++->y2 = yb;
X
X r->x1 = xl;
X r->y1 = yt;
X r->x2 = xl;
X r++->y2 = yb;
X
X r->x1 = xr;
X r->y1 = yt;
X r->x2 = xr;
X r++->y2 = yb;
X
X r->x1 = xl + xthird;
X r->y1 = yt;
X r->x2 = r->x1;
X r++->y2 = yb;
X
X r->x1 = xl + (2 * xthird);
X r->y1 = yt;
X r->x2 = r->x1;
X r++->y2 = yb;
X
X r->x1 = xl;
X r->y1 = yt + ythird;
X r->x2 = xr;
X r->y2 = r->y1;
X r++;
X
X r->x1 = xl;
X r->y1 = yt + (2 * ythird);
X r->x2 = xr;
X r->y2 = r->y1;
X r++;
X }
X if (r != outline)
X {
X XDrawSegments(dpy, root, DrawGC, outline, r - outline);
X }
X}
X
X/***********************************************************************
X *
X * Procedure:
X * Zoom - zoom in or out of an icon
X *
X * Inputs:
X * wf - window to zoom from
X * wt - window to zoom to
X *
X ***********************************************************************
X */
X
Xvoid
XZoom(wf, wt)
X{
X int fx, fy, fw, fh;
X int tx, ty, tw, th;
X int xl, yt, xr, yb;
X int dx, dy, dw, dh;
X int w, h, i;
X XSegment outline[4];
X
X if (!DoZoom)
X return;
X
X XGetGeometry(dpy, wf, &JunkRoot, &fx, &fy, &fw, &fh, &JunkBW, &JunkDepth);
X XGetGeometry(dpy, wt, &JunkRoot, &tx, &ty, &tw, &th, &JunkBW, &JunkDepth);
X
X dx = (tx - fx) / ZOOM_COUNT;
X dy = (ty - fy) / ZOOM_COUNT;
X dw = (tw - fw) / ZOOM_COUNT;
X dh = (th - fh) / ZOOM_COUNT;
X
X xl = fx;
X yt = fy;
X xr = fx + fw;
X yb = fy + fh;
X w = fw;
X h = fh;
X
X for (i = 0; i < ZOOM_COUNT; i++)
X {
X outline[0].x1 = xl;
X outline[0].y1 = yt;
X outline[0].x2 = xr;
X outline[0].y2 = yt;
X
X outline[1].x1 = xr;
X outline[1].y1 = yt;
X outline[1].x2 = xr;
X outline[1].y2 = yb;
X
X outline[2].x1 = xr;
X outline[2].y1 = yb;
X outline[2].x2 = xl;
X outline[2].y2 = yb;
X
X outline[3].x1 = xl;
X outline[3].y1 = yb;
X outline[3].x2 = xl;
X outline[3].y2 = yt;
X
X XDrawSegments(dpy, Root, DrawGC, outline, 4);
X
X w += dw;
X h += dh;
X xl += dx;
X yt += dy;
X xr = xl + w;
X yb = yt + h;
X }
X
X xl = fx;
X yt = fy;
X xr = fx + fw;
X yb = fy + fh;
X w = fw;
X h = fh;
X
X for (i = 0; i < ZOOM_COUNT; i++)
X {
X outline[0].x1 = xl;
X outline[0].y1 = yt;
X outline[0].x2 = xr;
X outline[0].y2 = yt;
X
X outline[1].x1 = xr;
X outline[1].y1 = yt;
X outline[1].x2 = xr;
X outline[1].y2 = yb;
X
X outline[2].x1 = xr;
X outline[2].y1 = yb;
X outline[2].x2 = xl;
X outline[2].y2 = yb;
X
X outline[3].x1 = xl;
X outline[3].y1 = yb;
X outline[3].x2 = xl;
X outline[3].y2 = yt;
X
X XDrawSegments(dpy, Root, DrawGC, outline, 4);
X
X w += dw;
X h += dh;
X xl += dx;
X yt += dy;
X xr = xl + w;
X yb = yt + h;
X }
X}
X
X/***********************************************************************
X *
X * Procedure:
X * MakeCenteredPixmap - make a pixmap centered in a space
X *
X * Returned Value:
X * pid - the pixmap id
X *
X * Inputs:
X * w - the window to associate the pixmap with
X * gc - the graphics context to use
X * width - the width of the pixmap to create
X * height - the height of the pixmap to create
X * data - pointer to the pixmap data
X * pwidth - the width of the pixmap
X * pheight - the height of the pixmap
X *
X ***********************************************************************
X */
X
XPixmap
XMakeCenteredPixmap(w, gc, width, height, data, pwidth, pheight)
X Drawable w;
X GC gc;
X int width, height;
X short *data;
X int pwidth, pheight;
X{
X XImage ximage;
X Pixmap pid;
X int dx, dy;
X
X pid = XCreatePixmap(dpy, w, width, height, DefaultDepth(dpy, 0));
X
X ximage.height = pheight;
X ximage.width = pwidth;
X ximage.xoffset = 0;
X ximage.format = XYBitmap;
X ximage.data = (char *) data;
X ximage.byte_order = LSBFirst;
X ximage.bitmap_unit = 16;
X ximage.bitmap_bit_order = LSBFirst;
X ximage.bitmap_pad = 16;
X ximage.bytes_per_line = (pwidth + 15) / 16 * 2;
X ximage.depth = 1;
X
X dx = (width - pwidth) / 2;
X dy = (height - pheight) / 2;
X
X XPutImage(dpy, pid, gc, &ximage, 0, 0, dx, dy, pwidth, pheight);
X return (pid);
X}
X
X/***********************************************************************
X *
X * Procedure:
X * MakePixmap - make a pixmap
X *
X * Returned Value:
X * pid - the pixmap id
X *
X * Inputs:
X * w - the window to associate the pixmap with
X * gc - the graphics context to use
X * data - pointer to the pixmap data
X * width - the width of the pixmap
X * height - the height of the pixmap
X *
X ***********************************************************************
X */
X
XPixmap
XMakePixmap(w, gc, data, width, height)
X Drawable w;
X GC gc;
X short *data;
X int width, height;
X{
X return MakeCenteredPixmap(w, gc, width, height, data, width, height);
X}
X
X/***********************************************************************
X *
X * Procedure:
X * ExpandFilename - expand the tilde character to HOME
X * if it is the first character of the filename
X *
X * Returned Value:
X * a pointer to the new name
X *
X * Inputs:
X * name - the filename to expand
X *
X ***********************************************************************
X */
X
Xchar *
XExpandFilename(name)
Xchar *name;
X{
X char *newname;
X
X if (name[0] != '~')
X return (name);
X
X newname = (char *)malloc(HomeLen + strlen(name) + 2);
X sprintf(newname, "%s/%s", Home, &name[1]);
X
X return (newname);
X}
X
X/***********************************************************************
X *
X * Procedure:
X * GetUnknownIcon - read in the bitmap file for the unknown icon
X *
X * Inputs:
X * name - the filename to read
X *
X ***********************************************************************
X */
X
Xvoid
XGetUnknownIcon(name)
Xchar *name;
X{
X UnknownPm = GetBitmap(name);
X if (UnknownPm != NULL)
X {
X XGetGeometry(dpy, UnknownPm, &JunkRoot, &JunkX, &JunkY,
X &UnknownWidth, &UnknownHeight, &JunkBW, &JunkDepth);
X }
X}
X
X/***********************************************************************
X *
X * Procedure:
X * GetBitmap - read in a bitmap file
X *
X * Returned Value:
X * the pixmap associated with the bitmap
X *
X * Inputs:
X * name - the filename to read
X *
X ***********************************************************************
X */
X
XPixmap
XGetBitmap(name)
Xchar *name;
X{
X char *bigname;
X int status, junk_hotx, junk_hoty;
X Pixmap pm;
X
X if (name == NULL)
X return (NULL);
X
X name = ExpandFilename(name);
X bigname = name;
X
X status = XReadBitmapFile(dpy, Root, bigname, &JunkWidth,
X &JunkHeight, &pm, &junk_hotx, &junk_hoty);
X
X if (status != BitmapSuccess && IconDirectory && name[0] != '/')
X {
X bigname = (char *)malloc(strlen(name) + strlen(IconDirectory) + 2);
X sprintf(bigname, "%s/%s", IconDirectory, name);
X status = XReadBitmapFile(dpy, Root, bigname, &JunkWidth,
X &JunkHeight, &pm, &junk_hotx, &junk_hoty);
X }
X
X if (status != BitmapSuccess && name[0] != '/')
X {
X bigname = (char *)malloc(strlen(name) + strlen(BITMAPS) + 2);
X sprintf(bigname, "%s/%s", BITMAPS, name);
X status = XReadBitmapFile(dpy, Root, bigname, &JunkWidth,
X &JunkHeight, &pm, &junk_hotx, &junk_hoty);
X }
X
X switch(status)
X {
X case BitmapSuccess:
X break;
X
X case BitmapFileInvalid:
X fprintf(stderr, ".twmrc: invalid bitmap file \"%s\"\n", bigname);
X break;
X
X case BitmapNoMemory:
X fprintf(stderr, ".twmrc: out of memory \"%s\"\n", bigname);
X break;
X
X case BitmapOpenFailed:
X fprintf(stderr, ".twmrc: failed to open bitmap file \"%s\"\n",
X bigname);
X break;
X
X default:
X fprintf(stderr,".twmrc: bitmap error = 0x%x on file \"%s\"\n",
X status, bigname);
X break;
X }
X
X if (status != BitmapSuccess)
X return (NULL);
X
X return (pm);
X}
X
Xint
XGetColor(kind, what, name)
Xint kind;
Xint *what;
Xchar *name;
X{
X int stat;
X XColor color, junkcolor;
X
X if (!FirstTime)
X return;
X
X if (Monochrome != kind)
X return;
X
X stat = XAllocNamedColor(dpy, CMap, name, &color, &junkcolor);
X switch (stat)
X {
X case BadAlloc:
X case BadColor:
X case BadName:
X fprintf(stderr, "twm: invalid color \"%s\" %d\n", name, stat);
X break;
X
X default:
X *what = color.pixel;
X }
X}
SHAR_EOF
if test 12175 -ne "`wc -c < util.c`"
then
echo shar: error transmitting "util.c" '(should have been 12175 characters)'
fi
fi
if test -f 'version.c'
then
echo shar: will not over-write existing file "version.c"
else
echo extracting "version.c"
sed 's/^X//' >version.c <<'SHAR_EOF'
X/*****************************************************************************/
X/** Copyright 1988 by Evans & Sutherland Computer Corporation, **/
X/** Salt Lake City, Utah **/
X/** **/
X/** All Rights Reserved **/
X/** **/
X/** Permission to use, copy, modify, and distribute this software and **/
X/** its documentation for any purpose and without fee is hereby **/
X/** granted, provided that the above copyright notice appear in all **/
X/** copies and that both that copyright notice and this permis- **/
X/** sion notice appear in supporting documentation, and that the **/
X/** name of Evans & Sutherland not be used in advertising or publi- **/
X/** city pertaining to distribution of the software without specif- **/
X/** ic, written prior permission. **/
X/** **/
X/** EVANS & SUTHERLAND DISCLAIMS ALL WARRANTIES WITH REGARD TO **/
X/** THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILI- **/
X/** TY AND FITNESS, IN NO EVENT SHALL EVANS & SUTHERLAND BE LIABLE **/
X/** FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAM- **/
X/** AGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, **/
X/** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS **/
X/** ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PER- **/
X/** FORMANCE OF THIS SOFTWARE. **/
X/*****************************************************************************/
X
X/***********************************************************************
X *
X * $Header: version.c,v 3.0 88/06/03 11:32:05 tlastran Exp $
X *
X * twm version number
X *
X * 14-Dec-87 Thomas E. LaStrange File created
X *
X ***********************************************************************/
X
Xstatic char RCSinfo[]=
X"$Header: version.c,v 3.0 88/06/03 11:32:05 tlastran Exp $";
X
Xchar *Revision = "$Revision: 3.0 $";
Xchar *Date = "$Date: 88/06/03 11:32:05 $";
SHAR_EOF
if test 2376 -ne "`wc -c < version.c`"
then
echo shar: error transmitting "version.c" '(should have been 2376 characters)'
fi
fi
# end of shell archive
exit 0