v01i052: twm: Tom's Window Manager, Part07/07
Mike Wexler
mikew at wyse.wyse.com
Sat Sep 24 01:48:04 AEST 1988
Submitted-by: tom%hpfctel at 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 at 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
More information about the Comp.sources.x
mailing list