mikew@wyse.wyse.com (Mike Wexler) (09/23/88)
Submitted-by: tom%hpfctel@sde.hp.com (Tom LaStrange) Posting-number: Volume 1, Issue 52 Archive-name: twm/part07 #! /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 7 (of 7)." # Contents: events.c # Wrapped by mikew@wyse on Thu Sep 22 16:21:25 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'events.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'events.c'\" else echo shar: Extracting \"'events.c'\" \(32452 characters\) sed "s/^X//" >'events.c' <<'END_OF_FILE' 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: events.c,v 1.77 88/09/12 08:05:59 toml Exp $ X * X * twm event handling X * X * 17-Nov-87 Thomas E. LaStrange File created X * X ***********************************************************************/ X X#ifndef lint Xstatic char RCSinfo[]= X"$Header: events.c,v 1.77 88/09/12 08:05:59 toml Exp $"; X#endif X X#include <stdio.h> X#include "twm.h" X#include <X11/Xatom.h> X#include "add_window.h" X#include "menus.h" X#include "events.h" X#include "resize.h" X#include "gram.h" X#include "twm.bm" X X#ifndef WM_CHANGE_STATE X#define WM_CHANGE_STATE 0xDEAD X#endif X Xevent_proc EventHandler[LASTEvent]; /* event handler jump table */ Xstatic XEvent event; /* the current event */ Xstatic TwmWindow *tmp_win; /* the current twm window */ Xstatic Window w; /* the window that caused the event */ Xstatic int Context = C_NO_CONTEXT; /* current button press context */ Xstatic TwmWindow *ButtonWindow; /* button press window structure */ Xstatic XEvent ButtonEvent; /* button preee event */ Xstatic MouseButton ButtonMouse; /* mouse button function */ X Xint ConstMove = FALSE; /* constrained move variables */ Xint ConstMoveDir; Xint ConstMoveX; Xint ConstMoveY; Xint ConstMoveXL; Xint ConstMoveXR; Xint ConstMoveYT; Xint ConstMoveYB; X XWindow DragWindow; /* variables used in moving windows */ Xint DragX; Xint DragY; Xint DragWidth; Xint DragHeight; Xstatic int enter_flag; X X/*********************************************************************** X * X * Procedure: X * InitEvents - initialize the event jump table X * X *********************************************************************** X */ X Xvoid XInitEvents() X{ X int i; X X ResizeWindow = NULL; X DragWindow = NULL; X enter_flag = FALSE; X X for (i = 0; i < LASTEvent; i++) X EventHandler[i] = HandleUnknown; X X EventHandler[Expose] = HandleExpose; X EventHandler[DestroyNotify] = HandleDestroyNotify; X EventHandler[MapRequest] = HandleMapRequest; X EventHandler[MapNotify] = HandleMapNotify; X EventHandler[UnmapNotify] = HandleUnmapNotify; X EventHandler[MotionNotify] = HandleMotionNotify; X EventHandler[ButtonRelease] = HandleButtonRelease; X EventHandler[ButtonPress] = HandleButtonPress; X EventHandler[EnterNotify] = HandleEnterNotify; X EventHandler[LeaveNotify] = HandleLeaveNotify; X EventHandler[ConfigureRequest] = HandleConfigureRequest; X EventHandler[ClientMessage] = HandleClientMessage; X EventHandler[PropertyNotify] = HandlePropertyNotify; X EventHandler[KeyPress] = HandleKeyPress; X} X X/*********************************************************************** X * X * Procedure: X * HandleEvents - handle X events X * X *********************************************************************** X */ X Xvoid XHandleEvents() X{ X while (TRUE) X { X if ( (DragWindow || ResizeWindow) && !XPending(dpy) ) X { X /* X ** Hack to support polled dynamics. Should really X ** build up "mode" support that callers can register X ** handlers with, etc. X */ X w = DragWindow ? DragWindow : ResizeWindow; X XQueryPointer( dpy, w, &(event.xmotion.root), &JunkChild, X &(event.xmotion.x_root), &(event.xmotion.y_root), X &JunkX, &JunkY, &JunkMask); X (*EventHandler[MotionNotify])(); X } X else X { X XNextEvent(dpy, &event); X w = event.xany.window; X if (XFindContext(dpy, w, TwmContext, &tmp_win) == XCNOENT) X tmp_win = NULL; X X#ifdef DEBUG X if (event.type != MotionNotify) X if (tmp_win != NULL) X { X fprintf(stderr, "Event w=%x, t->w=%x, t->frame=%x, t->title=%x, ", X w, tmp_win->w, tmp_win->frame, tmp_win->title_w); X } X else X { X fprintf(stderr, "Event w=%x, ", w); X } X#endif X if (event.type >= 0 && event.type < LASTEvent) X (*EventHandler[event.type])(); X } X } X} X X/*********************************************************************** X * X * Procedure: X * HandleKeyPress - key press event handler X * X *********************************************************************** X */ X Xvoid XHandleKeyPress() X{ X FuncKey *key; X X Context = C_NO_CONTEXT; X X if (w == Root) X Context = C_ROOT; X if (tmp_win) X { X if (w == tmp_win->title_w) X Context = C_TITLE; X if (w == tmp_win->w) X Context = C_WINDOW; X if (w == tmp_win->icon_w) X Context = C_ICON; X if (w == tmp_win->frame) X Context = C_FRAME; X } X X if (Context == C_NO_CONTEXT) X return; X X for (key = FuncKeyRoot.next; key != NULL; key = key->next) X { X if (key->keycode == event.xkey.keycode && X key->mods == event.xkey.state && X key->cont == Context) X { X /* weed out the functions that don't make sense to execute X * from a key press X */ X if (key->func == F_MOVE || key->func == F_RESIZE) X return; X X ExecuteFunction(key->func, key->action, w, X tmp_win, event, Context, FALSE); X } X } X} X X/*********************************************************************** X * X * Procedure: X * HandlePropertyNotify - property notify event handler X * X *********************************************************************** X */ X Xvoid XHandlePropertyNotify() X{ X char *prop; X XWMHints *wmhints; X XSizeHints hints; X Atom actual; X int junk1, junk2, len; X int width, height, x, y; X unsigned long valuemask; /* mask for create windows */ X XSetWindowAttributes attributes; /* attributes for create windows */ X Pixmap pm; X X#ifdef DEBUG X fprintf(stderr, "PropertyNotify = %d\n", event.xproperty.atom); X#endif X X if (tmp_win == NULL) X return; X X XGetWindowProperty(dpy, tmp_win->w, event.xproperty.atom, 0, 200, False, X XA_STRING, &actual, &junk1, &junk2, &len, &prop); X X if (actual == None) X return; X X if (prop == NULL) X prop = NoName; X X switch (event.xproperty.atom) X { X case XA_WM_NAME: X tmp_win->full_name = prop; X tmp_win->name = prop; X X tmp_win->name_width = XTextWidth(TitleBarFont, tmp_win->name, X strlen(tmp_win->name)); X X SetupWindow(tmp_win, X tmp_win->frame_x, tmp_win->frame_y, X tmp_win->frame_width, tmp_win->frame_height); X X XClearArea(dpy, tmp_win->title_w, 0, 0, 0, 0, False); X X XDrawImageString(dpy, tmp_win->title_w, X TitleNormalGC, X TitleBarX, TitleBarY, X tmp_win->name, strlen(tmp_win->name)); X X /* if the icon name is NoName, set the name of the icon to be X * the same as the window X */ X if (tmp_win->icon_name == NoName) X { X tmp_win->icon_name = tmp_win->name; X RedoIconName(); X } X break; X X case XA_WM_ICON_NAME: X tmp_win->icon_name = prop; X X RedoIconName(); X break; X X case XA_WM_HINTS: X wmhints = XGetWMHints(dpy, w); X X if (!tmp_win->forced && tmp_win->wmhints && X tmp_win->wmhints->flags & IconWindowHint) X { X tmp_win->icon_w = tmp_win->wmhints->icon_window; X } X X if (!tmp_win->forced && wmhints && (wmhints->flags & IconPixmapHint)) X { X XGetGeometry(dpy, wmhints->icon_pixmap, &JunkRoot, &JunkX, &JunkY, X &tmp_win->icon_width, &tmp_win->icon_height, X &JunkBW, &JunkDepth); X X pm = XCreatePixmap(dpy, Root, tmp_win->icon_width, X tmp_win->icon_height, d_depth); X X XCopyPlane(dpy, wmhints->icon_pixmap, pm, IconNormalGC, X 0,0, tmp_win->icon_width, tmp_win->icon_height, 0, 0, 1 ); X X valuemask = CWBackPixmap; X attributes.background_pixmap = pm; X X if (tmp_win->icon_bm_w) X XDestroyWindow(dpy, tmp_win->icon_bm_w); X X tmp_win->icon_bm_w = XCreateWindow(dpy, tmp_win->icon_w, X 0, 0, tmp_win->icon_width, tmp_win->icon_height, X 0, d_depth, CopyFromParent, d_visual, X valuemask, &attributes); X X RedoIconName(); X } X break; X X case XA_WM_NORMAL_HINTS: X XGetNormalHints(dpy, tmp_win->w, &hints); X /* don't do anything */ X break; X X default: X#ifdef DEBUG X fprintf(stderr, "TWM Not handling property %d\n",event.xproperty.atom); X#endif X break; X } X} X X/*********************************************************************** X * X * Procedure: X * RedoIconName - procedure to re-position the icon window and name X * X *********************************************************************** X */ X XRedoIconName() X{ X int x; X X tmp_win->icon_w_width = XTextWidth(IconFont, X tmp_win->icon_name, strlen(tmp_win->icon_name)); X X tmp_win->icon_w_width += 6; X if (tmp_win->icon_w_width < tmp_win->icon_width) X { X tmp_win->icon_x = (tmp_win->icon_width - tmp_win->icon_w_width)/2; X tmp_win->icon_x += 3; X tmp_win->icon_w_width = tmp_win->icon_width; X } X else X { X tmp_win->icon_x = 3; X } X X if (tmp_win->icon_w_width == tmp_win->icon_width) X x = 0; X else X x = (tmp_win->icon_w_width - tmp_win->icon_width)/2; X X XResizeWindow(dpy, tmp_win->icon_w, tmp_win->icon_w_width, X tmp_win->icon_height + IconFontHeight + 4); X if (tmp_win->icon_bm_w) X { X XMoveWindow(dpy, tmp_win->icon_bm_w, x, 0); X XMapWindow(dpy, tmp_win->icon_bm_w); X } X if (tmp_win->icon) X { X XClearArea(dpy, tmp_win->icon_w, 0, 0, 0, 0, False); 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 X/*********************************************************************** X * X * Procedure: X * HandleClientMessage - client message event handler X * X *********************************************************************** X */ X Xvoid XHandleClientMessage() X{ X#ifdef DEBUG X fprintf(stderr, "ClientMessage = 0x%x\n", event.xclient.message_type); X#endif X X switch (event.xclient.message_type) X { X case NULL: X enter_flag = FALSE; X break; X X case WM_CHANGE_STATE: X if (tmp_win != NULL) X { X if (event.xclient.data.l[0] == IconicState && !tmp_win->icon) X { X XEvent button; X X XQueryPointer( dpy, Root, &JunkRoot, &JunkChild, X &(button.xmotion.x_root), X &(button.xmotion.y_root), X &JunkX, &JunkY, &JunkMask); X X ExecuteFunction(F_ICONIFY, NULL, w, tmp_win, button, X FRAME, FALSE); X } X } X break; X } X} X X/*********************************************************************** X * X * Procedure: X * HandleExpose - expose event handler X * X *********************************************************************** X */ X Xvoid XHandleExpose() X{ X MenuItem *tmp; X X#ifdef DEBUG X fprintf(stderr, "Expose %d\n", event.xexpose.count); X#endif X X if (event.xexpose.count != 0) X return; X X if (w == VersionWindow) X { X XDrawImageString(dpy, VersionWindow, VersionNormalGC, X twm_width + 10, X 2 + VersionFont->ascent, Version, strlen(Version)); X return; X } X X if (tmp_win != NULL) X { X if (tmp_win->title_w == w) X { X XDrawImageString(dpy, tmp_win->title_w, X TitleNormalGC, X TitleBarX, TitleBarY, X tmp_win->name, strlen(tmp_win->name)); X return; X } X X if (tmp_win->icon_w == w) 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 return; X } X } X X if (XFindContext(dpy, w, MenuContext, &tmp) == 0) X { X if (tmp->func == F_TITLE) X XDrawImageString(dpy,w, MenuTitleGC, tmp->y, MenuY, X tmp->item, strlen(tmp->item)); X else if (tmp->state) X XDrawImageString(dpy,w, MenuReverseGC, tmp->y, MenuY, X tmp->item, strlen(tmp->item)); X else X XDrawImageString(dpy,w, MenuNormalGC, tmp->y, MenuY, X tmp->item, strlen(tmp->item)); X X return; X } X} X X/*********************************************************************** X * X * Procedure: X * HandleDestroyNotify - DestroyNotify event handler X * X *********************************************************************** X */ X Xvoid XHandleDestroyNotify() X{ X#ifdef DEBUG X fprintf(stderr, "DestroyNotify\n"); X#endif X if (tmp_win == NULL) X return; X X if (tmp_win == Focus) X { X FocusOnRoot(); X } X XDeleteContext(dpy, tmp_win->w, TwmContext); X XDeleteContext(dpy, tmp_win->frame, TwmContext); X XDeleteContext(dpy, tmp_win->title_w, TwmContext); X XDeleteContext(dpy, tmp_win->iconify_w, TwmContext); X XDeleteContext(dpy, tmp_win->resize_w, TwmContext); X XDeleteContext(dpy, tmp_win->icon_w, TwmContext); X#ifndef NOFOCUS X XDeleteContext(dpy, tmp_win->focus_w, TwmContext); X#endif X XDeleteContext(dpy, tmp_win->hilite_w, TwmContext); X X XDestroyWindow(dpy, tmp_win->frame); X XDestroyWindow(dpy, tmp_win->icon_w); X tmp_win->prev->next = tmp_win->next; X if (tmp_win->next != NULL) X tmp_win->next->prev = tmp_win->prev; X X free((char *)tmp_win); X} X X/*********************************************************************** X * X * Procedure: X * HandleMapRequest - MapRequest event handler X * X *********************************************************************** X */ X Xvoid XHandleMapRequest() X{ X int stat; X XSizeHints hints; X X#ifdef DEBUG X fprintf(stderr, "MapRequest w = 0x%x\n", event.xmaprequest.window); X#endif X X w = event.xmaprequest.window; X stat = XFindContext(dpy, w, TwmContext, &tmp_win); X if (stat == XCNOENT) X tmp_win = NULL; X X if (tmp_win == NULL) X { X if (Transient(w)) X { X XMapRaised(dpy, w); X return; X } X X XGrabServer(dpy); X XGrabKeyboard(dpy, Root, False, GrabModeSync, GrabModeSync,CurrentTime); X tmp_win = AddWindow(w); X if (tmp_win->wmhints && (tmp_win->wmhints->flags & StateHint)) X { X switch (tmp_win->wmhints->initial_state) X { X case DontCareState: X case NormalState: X case ZoomState: X case InactiveState: X XMapWindow(dpy, tmp_win->w); X XMapRaised(dpy, tmp_win->frame); X break; X X case IconicState: X if (tmp_win->wmhints->flags & IconPositionHint) X { X int x, y; X X x = tmp_win->wmhints->icon_x; X y = tmp_win->wmhints->icon_y; X X if (x > MyDisplayWidth) X x = MyDisplayWidth - tmp_win->icon_w_width - X (2 * BorderWidth); X X if (y > MyDisplayHeight) X y = MyDisplayHeight - tmp_win->icon_height - X IconFontHeight - 4 - (2 * BorderWidth); X X X XMoveWindow(dpy, tmp_win->icon_w, x, y); X } X else X { X XMoveWindow(dpy, tmp_win->icon_w, 0, 0); X } X X XUnmapWindow(dpy, tmp_win->w); X XMapSubwindows(dpy, tmp_win->icon_w); X XMapRaised(dpy, tmp_win->icon_w); X tmp_win->iconified = TRUE; X tmp_win->icon = TRUE; X break; X } X } X else X { X#ifndef ICCCM X if (!tmp_win->icon) X { X#endif X XUnmapWindow(dpy, tmp_win->icon_w); X XMapWindow(dpy, tmp_win->w); X XMapRaised(dpy, tmp_win->frame); X tmp_win->icon = FALSE; X#ifndef ICCCM X } X#endif X X } X XUngrabKeyboard(dpy, CurrentTime); X XUngrabServer(dpy); X } X else X { X#ifndef ICCCM X if (!tmp_win->icon) X { X#endif X XUnmapWindow(dpy, tmp_win->icon_w); X XMapWindow(dpy, tmp_win->w); X XMapRaised(dpy, tmp_win->frame); X tmp_win->icon = FALSE; X#ifndef ICCCM X } X#endif X } X XRaiseWindow(dpy, VersionWindow); X} X X/*********************************************************************** X * X * Procedure: X * HandleMapNotify - MapNotify event handler X * X *********************************************************************** X */ X Xvoid XHandleMapNotify() X{ X#ifdef DEBUG X fprintf(stderr, "MapNotify\n"); X#endif X if (tmp_win == NULL) X return; X X XUnmapWindow(dpy, tmp_win->icon_w); X XMapSubwindows(dpy, tmp_win->title_w); X XMapSubwindows(dpy, tmp_win->frame); X if (Focus != tmp_win) X XUnmapWindow(dpy, tmp_win->hilite_w); X X if (tmp_win->title_height == 0) X XUnmapWindow(dpy, tmp_win->title_w); X X XMapRaised(dpy, tmp_win->frame); X tmp_win->mapped = TRUE; X tmp_win->icon = FALSE; X X XRaiseWindow(dpy, VersionWindow); X} X X/*********************************************************************** X * X * Procedure: X * HandleUnmapNotify - UnmapNotify event handler X * X *********************************************************************** X */ X Xvoid XHandleUnmapNotify() X{ X#ifdef DEBUG X fprintf(stderr, "UnmapNotify\n"); X#endif X if (tmp_win == NULL) X return; X X XUnmapWindow(dpy, tmp_win->frame); X tmp_win->mapped = FALSE; X} X X/*********************************************************************** X * X * Procedure: X * HandleMotionNotify - MotionNotify event handler X * X *********************************************************************** X */ X Xvoid XHandleMotionNotify() X{ X#ifdef DEBUG X /* X fprintf(stderr, "MotionNotify\n"); X */ X#endif X if (ConstMove) X { X switch (ConstMoveDir) X { X case MOVE_NONE: X if (event.xmotion.x_root < ConstMoveXL || X event.xmotion.x_root > ConstMoveXR) X ConstMoveDir = MOVE_HORIZ; X X if (event.xmotion.y_root < ConstMoveYT || X event.xmotion.y_root > ConstMoveYB) X ConstMoveDir = MOVE_VERT; X X XQueryPointer(dpy, DragWindow, &JunkRoot, &JunkChild, X &JunkX, &JunkY, &DragX, &DragY, &JunkMask); X break; X X case MOVE_VERT: X ConstMoveY = event.xmotion.y_root - DragY - BorderWidth; X break; X X case MOVE_HORIZ: X ConstMoveX= event.xmotion.x_root - DragX - BorderWidth; X break; X } X X if (ConstMoveDir != MOVE_NONE) X { X int xl, yt, xr, yb, w, h; X X xl = ConstMoveX; X yt = ConstMoveY; X w = DragWidth + 2 * BorderWidth; X h = DragHeight + 2 * BorderWidth; X X if (DontMoveOff) X { X xr = xl + w; X yb = yt + h; X X if (xl < 0) X xl = 0; X if (xr > MyDisplayWidth) X xl = MyDisplayWidth - w; X X if (yt < 0) X yt = 0; X if (yb > MyDisplayHeight) X yt = MyDisplayHeight - h; X } X MoveOutline(event.xmotion.root, xl, yt, w, h); X } X return; X } X X if (DragWindow != NULL) X { X int xl, yt, xr, yb, w, h; X X xl = event.xmotion.x_root - DragX - BorderWidth; X yt = event.xmotion.y_root - DragY - BorderWidth; X w = DragWidth + 2 * BorderWidth; X h = DragHeight + 2 * BorderWidth; X X if (DontMoveOff) X { X xr = xl + w; X yb = yt + h; X X if (xl < 0) X xl = 0; X if (xr > MyDisplayWidth) X xl = MyDisplayWidth - w; X X if (yt < 0) X yt = 0; X if (yb > MyDisplayHeight) X yt = MyDisplayHeight - h; X } X X MoveOutline(event.xmotion.root, xl, yt, w, h); X return; X } X X if (ResizeWindow != NULL) X { X XFindContext(dpy, ResizeWindow, TwmContext, &tmp_win); X DoResize(event.xmotion.x_root, event.xmotion.y_root, tmp_win); X } X} X X/*********************************************************************** X * X * Procedure: X * HandleButtonRelease - ButtonRelease event handler X * X *********************************************************************** X */ X Xvoid XHandleButtonRelease() X{ X int xl, xr, yt, yb, w, h; X X#ifdef DEBUG X fprintf(stderr, "ButtonRelease\n"); X#endif X X if (RootFunction == NULL) X { X XUngrabPointer(dpy, CurrentTime); X XUngrabServer(dpy); X EventHandler[EnterNotify] = HandleEnterNotify; X EventHandler[LeaveNotify] = HandleLeaveNotify; X EventHandler[Expose] = HandleExpose; X } X X if (DragWindow != NULL) X { X XEvent client_event; X X MoveOutline(event.xbutton.root, 0, 0, 0, 0); X X xl = event.xbutton.x_root - DragX - BorderWidth; X yt = event.xbutton.y_root - DragY - BorderWidth; X X if (ConstMove) X { X if (ConstMoveDir == MOVE_HORIZ) X yt = ConstMoveY; X X if (ConstMoveDir == MOVE_VERT) X xl = ConstMoveX; X X if (ConstMoveDir == MOVE_NONE) X { X yt = ConstMoveY; X xl = ConstMoveX; X } X } X X w = DragWidth + 2 * BorderWidth; X h = DragHeight + 2 * BorderWidth; X X if (DontMoveOff) X { X xr = xl + w; X yb = yt + h; X X if (xl < 0) X xl = 0; X if (xr > MyDisplayWidth) X xl = MyDisplayWidth - w; X X if (yt < 0) X yt = 0; X if (yb > MyDisplayHeight) X yt = MyDisplayHeight - h; X } X X XFindContext(dpy, DragWindow, TwmContext, &tmp_win); X if (DragWindow == tmp_win->frame) X { X tmp_win->frame_x = xl; X tmp_win->frame_y = yt; X } X X XMoveWindow(dpy, DragWindow, xl, yt); X if (!NoRaiseMove) X XRaiseWindow(dpy, DragWindow); X DragWindow = NULL; X ConstMove = FALSE; X X enter_flag = TRUE; X client_event.type = ClientMessage; X client_event.xclient.message_type = NULL; X client_event.xclient.format = 32; X XSendEvent(dpy, tmp_win->frame, False, 0, &client_event); X SetHints(tmp_win); X X return; X } X X if (ResizeWindow != NULL) X { X EndResize(); X EventHandler[EnterNotify] = HandleEnterNotify; X EventHandler[LeaveNotify] = HandleLeaveNotify; X XUngrabPointer(dpy, CurrentTime); X XUngrabServer(dpy); X return; X } X X if (ActiveMenu != NULL) X { X MenuRoot *tmp; X X for (tmp = ActiveMenu; tmp != NULL; tmp = tmp->prev) X { X XUnmapWindow(dpy, tmp->shadow); X XUnmapWindow(dpy, tmp->w); X } X XFlush(dpy); X ActiveMenu = NULL; X X if (ActiveItem != NULL) X { X ExecuteFunction(ActiveItem->func, ActiveItem->action, NULL, X ButtonWindow, ButtonEvent, Context, TRUE); X ActiveItem = NULL; X Context = C_NO_CONTEXT; X ButtonWindow = NULL; X } X return; X } X} X X/*********************************************************************** X * X * Procedure: X * HandleButtonPress - ButtonPress event handler X * X *********************************************************************** X */ X Xvoid XHandleButtonPress() X{ X int modifier; X X#ifdef DEBUG X fprintf(stderr, "ButtonPress\n"); X#endif X X if (ResizeWindow != NULL || X DragWindow != NULL || X ActiveMenu != NULL) X return; X X XUnmapWindow(dpy, VersionWindow); X X /* check the title bar buttons */ X X if (tmp_win && w == tmp_win->iconify_w) X { X ExecuteFunction(F_ICONIFY, NULL, w, tmp_win, event, C_TITLE, FALSE); X return; X } X X if (tmp_win && w == tmp_win->resize_w) X { X ExecuteFunction(F_RESIZE, NULL, w, tmp_win, event, C_TITLE, FALSE); X return; X } X X#ifndef NOFOCUS X if (tmp_win && w == tmp_win->focus_w) X { X ExecuteFunction(F_FOCUS, NULL, w, tmp_win, event, C_TITLE, FALSE); X return; X } X#endif X X Context = C_NO_CONTEXT; X X if (w == Root) X Context = C_ROOT; X if (tmp_win) X { X if (w == tmp_win->title_w) X Context = C_TITLE; X if (w == tmp_win->w) X Context = C_WINDOW; X if (w == tmp_win->icon_w) X Context = C_ICON; X if (w == tmp_win->frame) X Context = C_FRAME; X } X X /* this section of code checks to see if we were in the middle of X * a command executed from a menu X */ X if (RootFunction != NULL) X { X if (w == Root) X { X /* if the window was the Root, we don't know for sure it X * it was the root. We must check to see if it happened to be X * inside of a client that was getting button press events, X * such as an xterm X */ X XTranslateCoordinates(dpy, Root, Root, X event.xbutton.x, X event.xbutton.y, X &JunkX, &JunkY, &w); X X if (w == 0 || X (XFindContext(dpy, w, TwmContext, &tmp_win) == XCNOENT)) X { X RootFunction = NULL; X XBell(dpy, screen); X return; X } X X XTranslateCoordinates(dpy, Root, w, X event.xbutton.x, X event.xbutton.y, X &JunkX, &JunkY, &JunkChild); X X event.xbutton.x = JunkX; X event.xbutton.y = JunkY - tmp_win->title_height; X Context = C_WINDOW; X } X X ExecuteFunction(RootFunction, ButtonMouse.item->action, w, X tmp_win, event, Context, FALSE); X X RootFunction = NULL; X return; X } X X ButtonEvent = event; X ButtonWindow = tmp_win; X X /* if we get to here, we have to execute a function or pop up a X * menu X */ X modifier = event.xbutton.state & (ShiftMask | ControlMask | Mod1Mask); X X ButtonMouse = Mouse[event.xbutton.button][Context][modifier]; X X if (Context == C_NO_CONTEXT) X return; X X RootFunction = NULL; X if (Mouse[event.xbutton.button][Context][modifier].func == F_MENU && X Mouse[event.xbutton.button][Context][modifier].menu->items != 0) X { X XGrabPointer(dpy, Root, True, X ButtonReleaseMask, X GrabModeAsync, GrabModeSync, X Root, LeftArrowCursor, CurrentTime); X X PopUpMenu(Mouse[event.xbutton.button][Context][modifier].menu, X event.xbutton.x_root, event.xbutton.y_root); X } X else if (Mouse[event.xbutton.button][Context][modifier].func != NULL) X { X ExecuteFunction(Mouse[event.xbutton.button][Context][modifier].func, X Mouse[event.xbutton.button][Context][modifier].item->action, X w, tmp_win, event, Context, FALSE); X } X else if (DefaultFunction.func != NULL) X { X ExecuteFunction(DefaultFunction.func, DefaultFunction.item, X w, tmp_win, event, Context, FALSE); X } X} X X/*********************************************************************** X * X * Procedure: X * HandleEnterNotify - EnterNotify event handler X * X *********************************************************************** X */ X Xvoid XHandleEnterNotify() X{ X MenuItem *tmp; X X#ifdef DEBUG X fprintf(stderr, "EnterNotify\n"); X#endif X X if (ActiveMenu == NULL && tmp_win != NULL) X { X if (FocusRoot && tmp_win->mapped) X { X if (Focus != NULL && Focus != tmp_win) X XUnmapWindow(dpy, Focus->hilite_w); X X XMapWindow(dpy, tmp_win->hilite_w); X XInstallColormap(dpy, tmp_win->attr.colormap); X XSetWindowBorder(dpy, tmp_win->frame, BorderColor); X XSetWindowBorder(dpy, tmp_win->title_w, BorderColor); X if (TitleFocus) X XSetInputFocus(dpy, tmp_win->w, RevertToPointerRoot, X CurrentTime); X Focus = tmp_win; X } X if (enter_flag == FALSE && tmp_win->auto_raise) X { X XEvent client_event; X X XRaiseWindow(dpy, tmp_win->frame); X enter_flag = TRUE; X client_event.type = ClientMessage; X client_event.xclient.message_type = NULL; X client_event.xclient.format = 32; X XSendEvent(dpy, tmp_win->frame, False, 0, &client_event); X } X return; X } X X X if (XFindContext(dpy, w, MenuContext, &tmp) != 0) X return; X X if (w == tmp->w && tmp->root == ActiveMenu) X { X if (ActiveItem != NULL && ActiveItem->state != 0) X { X#ifdef DEBUG X fprintf(stderr, "turning off \"%s\"\n", ActiveItem->item); X#endif X XFillRectangle(dpy, ActiveItem->w,MenuXorGC,0,0,1000, 100); X if (tmp->pull != NULL) X XFillRectangle(dpy, ActiveItem->pull, MenuXorGC,0,0,1000, 100); X ActiveItem->state = 0; X } X X if (tmp->state == 0) X { X#ifdef DEBUG X fprintf(stderr, "turning on \"%s\"\n", tmp->item); X#endif X XFillRectangle(dpy, tmp->w,MenuXorGC,0,0,1000, 100); X if (tmp->pull) X XFillRectangle(dpy, tmp->pull, MenuXorGC,0,0,1000, 100); X tmp->state = 1; X } X ActiveItem = tmp; X X return; X } X X if (w == tmp->pull && tmp->root == ActiveMenu) X { X XGrabServer(dpy); X PopUpMenu(tmp->sub, event.xcrossing.x_root, X event.xcrossing.y_root); X XUngrabServer(dpy); X X return; X } X} X X/*********************************************************************** X * X * Procedure: X * HandleLeaveNotify - LeaveNotify event handler X * X *********************************************************************** X */ X Xvoid XHandleLeaveNotify() X{ X MenuItem *tmp; X X#ifdef DEBUG X fprintf(stderr, "LeaveNotify\n"); X#endif X if (tmp_win != NULL) X { X XUnmapWindow(dpy, VersionWindow); X if (FocusRoot) X { X if (event.xcrossing.detail != NotifyInferior) X { X XUnmapWindow(dpy, tmp_win->hilite_w); X XUninstallColormap(dpy, tmp_win->attr.colormap); X if (Highlight && tmp_win->highlight) X { X XSetWindowBorderPixmap(dpy, tmp_win->frame, GrayTile); X XSetWindowBorderPixmap(dpy, tmp_win->title_w, GrayTile); X } X if (TitleFocus) X XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, X CurrentTime); X Focus = NULL; X } X } X return; X } X X if (XFindContext(dpy, w, MenuContext, &tmp) != 0) X return; X X if (w == tmp->root->w) X { X int rootx, rooty, x, y; X int wx, wy, ww, wh; X X /* see if the mouse really left the window X * or just crossed into a sub-window X */ X X XQueryPointer(dpy, w, &JunkRoot, X &JunkChild, &rootx, &rooty, &x, &y, &JunkMask); X X XGetGeometry(dpy, w, &JunkRoot, &wx, &wy, X &ww, &wh, &JunkBW, X &JunkDepth); X X if (rootx < wx || X rootx > (wx + ww) || X rooty < wy || X rooty > (wy + wh)) X { X ActiveItem = NULL; X if (tmp->root->prev != NULL) X { X if (ActiveMenu == tmp->root) X { X XUnmapWindow(dpy, ActiveMenu->shadow); X XUnmapWindow(dpy, ActiveMenu->w); X ActiveMenu = tmp->root->prev; X } X } X } X return; X } X X if (w == tmp->w) X { X if (tmp == ActiveItem) X ActiveItem = NULL; X X if (tmp->state != 0) X { X#ifdef DEBUG X fprintf(stderr, "turning off \"%s\"\n", tmp->item); X#endif X XFillRectangle(dpy, tmp->w,MenuXorGC,0,0,1000, 100); X if (tmp->pull != NULL) X XFillRectangle(dpy, tmp->pull, MenuXorGC,0,0,1000, 100); X tmp->state = 0; X } X X return; X } X} X X/*********************************************************************** X * X * Procedure: X * HandleConfigureRequest - ConfigureRequest event handler X * X *********************************************************************** X */ X Xvoid XHandleConfigureRequest() X{ X XWindowChanges xwc; X unsigned int xwcm; X X#ifdef DEBUG X fprintf(stderr, "ConfigureRequest\n"); X if (event.xconfigurerequest.value_mask & CWX) X fprintf(stderr, " x = %d\n", event.xconfigurerequest.x); X if (event.xconfigurerequest.value_mask & CWY) X fprintf(stderr, " y = %d\n", event.xconfigurerequest.y); X if (event.xconfigurerequest.value_mask & CWWidth) X fprintf(stderr, " width = %d\n", event.xconfigurerequest.width); X if (event.xconfigurerequest.value_mask & CWHeight) X fprintf(stderr, " height = %d\n", event.xconfigurerequest.height); X#endif X X w = event.xconfigurerequest.window; X X if (tmp_win == NULL && Transient(w)) X { X#ifdef DEBUG X fprintf(stderr, " Transient\n"); X#endif X X xwcm = event.xconfigurerequest.value_mask & X (CWX | CWY | CWWidth | CWHeight); X xwc.x = event.xconfigurerequest.x; X xwc.y = event.xconfigurerequest.y; X xwc.width = event.xconfigurerequest.width; X xwc.height = event.xconfigurerequest.height; X XConfigureWindow(dpy, w, xwcm, &xwc); X return; X } X X if (tmp_win == NULL) X return; X X if (event.xconfigurerequest.value_mask & CWX) X tmp_win->frame_x = event.xconfigurerequest.x - tmp_win->title_height; X if (event.xconfigurerequest.value_mask & CWY) X tmp_win->frame_y = event.xconfigurerequest.y; X if (event.xconfigurerequest.value_mask & CWWidth) X tmp_win->frame_width = event.xconfigurerequest.width; X if (event.xconfigurerequest.value_mask & CWHeight) X tmp_win->frame_height = X event.xconfigurerequest.height + tmp_win->title_height; X X SetupWindow(tmp_win, X tmp_win->frame_x, tmp_win->frame_y, X tmp_win->frame_width, tmp_win->frame_height); X} X X/*********************************************************************** X * X * Procedure: X * HandleUnknown - unknown event handler X * X *********************************************************************** X */ X Xvoid XHandleUnknown() X{ X#ifdef DEBUG X fprintf(stderr, "type = %d\n", event.type); X#endif X} X X/*********************************************************************** X * X * Procedure: X * Transient - checks to see if the window is a transient X * X * Returned Value: X * TRUE - window is a transient X * FALSE - window is not a transient X * X * Inputs: X * w - the window to check X * X *********************************************************************** X */ X Xint XTransient(w) X Window w; X{ X Window propw; X X return (XGetTransientForHint(dpy, w, &propw)); X} END_OF_FILE if test 32452 -ne `wc -c <'events.c'`; then echo shar: \"'events.c'\" unpacked with wrong size! fi # end of 'events.c' fi echo shar: End of archive 7 \(of 7\). cp /dev/null ark7isdone MISSING="" for I in 1 2 3 4 5 6 7 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 7 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Mike Wexler(wyse!mikew) Phone: (408)433-1000 x1330