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