home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
x
/
volume15
/
olvwm-3.0
/
part15
< prev
next >
Wrap
Internet Message Format
|
1992-02-03
|
57KB
Path: uunet!sun-barr!ames!pasteur!nntp
From: scott.oaks@East.Sun.COM (Scott Oaks)
Newsgroups: comp.sources.x
Subject: v15i161: OpenLook Virtual Window Mgr (3.0), Part15/21
Message-ID: <1992Feb4.135917.7948@pasteur.Berkeley.EDU>
Date: 4 Feb 92 13:59:17 GMT
References: <csx-15i147-olvwm-3.0@uunet.UU.NET>
Sender: dcmartin@msi.com (David C. Martin - Moderator)
Organization: University of California, at Berkeley
Lines: 1973
Approved: dcmartin@msi.com
Nntp-Posting-Host: postgres.berkeley.edu
Submitted-by: scott.oaks@East.Sun.COM (Scott Oaks)
Posting-number: Volume 15, Issue 161
Archive-name: olvwm-3.0/part15
# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix@uunet.uu.net if you want that tool.
# If this archive is complete, you will see the following message at the end:
# "End of archive 15 (of 21)."
# Contents: st.h winicon.c winpinmenu.c winroot.c
# Wrapped by dcmartin@fascet on Tue Jan 14 05:54:46 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'st.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'st.h'\"
else
echo shar: Extracting \"'st.h'\" \(1252 characters\)
sed "s/^X//" >'st.h' <<'END_OF_FILE'
X
X/* This is a general purpose hash table package written by Peter Moore @ UCB. */
X#ident "@(#)st.h 26.5 91/09/14 SMI"
X
X#ifndef ST_INCLUDED
X
X#define ST_INCLUDED
X
Xtypedef struct st_table_entry st_table_entry;
X
Xstruct st_table_entry {
X char *key;
X char *record;
X st_table_entry *next;
X};
X
Xtypedef struct st_table st_table;
X
Xstruct st_table {
X int (*compare)();
X int (*hash)();
X int num_bins;
X int num_entries;
X int max_density;
X int reorder_flag;
X double grow_factor;
X st_table_entry **bins;
X};
X
X#define st_is_member(table,key) st_lookup(table,key,(char **) 0)
X
Xenum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE};
X
Xint st_delete(), st_insert(), st_foreach(), st_free_table();
Xint st_lookup(), st_find_or_add(), st_add_direct();
Xst_table *st_init_table(), *st_init_table_with_params();
X
X#define ST_NUMCMP ((int (*)()) 0)
X#define ST_NUMHASH ((int (*)()) -2)
X
X#define ST_PTRCMP ((int (*)()) 0)
X#define ST_PTRHASH ((int (*)()) -1)
X
X#define st_numcmp ST_NUMCMP
X#define st_numhash ST_NUMHASH
X#define st_ptrcmp ST_PTRCMP
X#define st_ptrhash ST_PTRHASH
X
X#define ST_DEFAULT_MAX_DENSITY 5
X#define ST_DEFAULT_INIT_TABLE_SIZE 11
X#define ST_DEFAULT_GROW_FACTOR 2.0
X#define ST_DEFAULT_REORDER_FLAG 0
X
Xint st_strhash();
X
X#endif ST_INCLUDED
END_OF_FILE
if test 1252 -ne `wc -c <'st.h'`; then
echo shar: \"'st.h'\" unpacked with wrong size!
fi
# end of 'st.h'
fi
if test -f 'winicon.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'winicon.c'\"
else
echo shar: Extracting \"'winicon.c'\" \(21256 characters\)
sed "s/^X//" >'winicon.c' <<'END_OF_FILE'
X/*
X * (c) Copyright 1989, 1990 Sun Microsystems, Inc. Sun design patents
X * pending in the U.S. and foreign countries. See LEGAL_NOTICE
X * file for terms of the license.
X */
X
X#ident "@(#)winicon.c 1.1 olvwm version 1/3/92"
X
X/*
X * Based on
X#ident "@(#)winicon.c 26.27 91/09/14 SMI"
X *
X */
X
X#include <errno.h>
X#include <stdio.h>
X#include <string.h>
X#include <X11/Xos.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include <X11/Xatom.h>
X#include <olgx/olgx.h>
X
X#include "i18n.h"
X#include "ollocale.h"
X#include "mem.h"
X#include "olwm.h"
X#include "win.h"
X#include "menu.h"
X#include "globals.h"
X#include "slots.h"
X#include "group.h"
X
Xextern Bool PropGetWMName();
Xextern Bool PropGetWMIconName();
X
X/***************************************************************************
X* private data
X***************************************************************************/
X
X/* events in the icon window that are interesting */
X#define ICON_EVENT_MASK (ButtonPressMask | ButtonReleaseMask | \
X ExposureMask | ButtonMotionMask | \
X EnterWindowMask | FocusChangeMask)
X
X/* Class function vector */
Xstatic ClassIconFrame classIconFrame;
X
X/***************************************************************************
X* forward-declared functions
X***************************************************************************/
X
X/***************************************************************************
X* private event functions
X***************************************************************************/
X
Xstatic int
XmenuPressIcon(dpy,event,iconInfo)
XDisplay *dpy;
XXEvent *event;
XWinIconFrame *iconInfo;
X{
X if (iconInfo->core.client->wmDecors->menu_type != MENU_NONE)
X ShowStandardMenu(iconInfo, event, False);
X}
X
Xstatic int
XselectDoubleClickIcon(dpy,event,iconInfo)
XDisplay *dpy;
XXEvent *event;
XWinIconFrame *iconInfo;
X{
X StateIconNorm(iconInfo->core.client);
X}
X
Xstatic int
XadjustClickIcon(dpy,event,iconInfo)
XDisplay *dpy;
XXEvent *event;
XWinIconFrame *iconInfo;
X{
X ToggleSelection(iconInfo->core.client, event->xbutton.time);
X}
X
X/***************************************************************************
X* private functions
X***************************************************************************/
X
X/*
X * iconCalcName - calc position/size of icon name
X */
Xstatic void
XiconCalcName(winIcon,pane)
X WinIconFrame *winIcon;
X Window pane;
X{
X Display *dpy = winIcon->core.client->dpy;
X
X winIcon->nameLength = strlen(winIcon->fcore.name);
X winIcon->nameWidth = XTextWidth(GRV.IconFontInfo, winIcon->fcore.name,
X winIcon->nameLength);
X winIcon->nameX = (winIcon->core.width - winIcon->nameWidth)/2;
X
X /*
X * Position the text one pixel above the ICON_VERTBORDER and
X * the descent of the font
X */
X winIcon->nameY = winIcon->core.height - ICON_VERTBORDER - 1
X - GRV.IconFontInfo->max_bounds.descent;
X}
X
X/*
X * iconSetName -- set the icon name and possibly redraw
X */
Xstatic void
XiconSetName(winIcon,pane)
X WinIconFrame *winIcon;
X Window pane;
X{
X Display *dpy = winIcon->core.client->dpy;
X
X if (winIcon->fcore.name)
X MemFree(winIcon->fcore.name);
X
X if (!PropGetWMIconName(dpy,pane,&(winIcon->fcore.name)) &&
X !PropGetWMName(dpy,pane,&(winIcon->fcore.name))) {
X winIcon->fcore.name = MemNewString(GRV.DefaultWinName);
X }
X
X iconCalcName(winIcon,pane);
X
X if (!winIcon->core.dirtyconfig)
X (WinFunc(winIcon,core.drawfunc))(dpy,winIcon);
X}
X
X/* selectDragIcon -- the user has held the select button down long enough
X * to initiate a drag. Unpin the icon slot and start a window-move.
X */
Xstatic int
XselectDragIcon(dpy, ev, iframe, lastpress)
XDisplay *dpy;
XXEvent *ev;
XWinIconFrame *iframe;
XXButtonEvent *lastpress;
X{
X SlotFree(iframe);
X iframe->fManuallyPositioned = True;
X ClientMove(iframe->core.client,lastpress);
X}
X
X
X/*
X * newconfigIcon -- compute a new configuration of icon window
X */
Xstatic int
XnewconfigIcon(winInfo, pxcre)
XWinIconFrame *winInfo;
XXConfigureRequestEvent *pxcre;
X{
X Client *cli = winInfo->core.client;
X WinPane *winPane = (WinPane *)winInfo->fcore.panewin;
X int neww,newh;
X
X neww = winInfo->fcore.panewin->core.width + 2*widthBothIcon(winInfo);
X newh = winInfo->fcore.panewin->core.height + heightTopIcon(winInfo) +
X heightBottomIcon(winInfo);
X
X if (neww != winInfo->core.width)
X {
X winInfo->core.width = neww;
X winInfo->core.dirtyconfig |= CWWidth;
X }
X
X if (newh != winInfo->core.height)
X {
X winInfo->core.height = newh;
X winInfo->core.dirtyconfig |= CWHeight;
X }
X
X if (winInfo->core.dirtyconfig)
X {
X (WinFunc(winPane,core.newposfunc))(winPane,
X widthBothIcon(winInfo), heightTopIcon(winInfo));
X }
X
X if (winInfo->core.dirtyconfig & (CWWidth | CWHeight))
X {
X iconCalcName(winInfo,PANEWINOFCLIENT(cli));
X }
X
X return winInfo->core.dirtyconfig;
X}
X
X/*
X * The icon is being moved to a new (x,y) location. If the icon slot has not
X * yet been allocated, do so if appropriate. Otherwise, blindly accept the
X * (x,y) position.
X */
Xstatic int
XnewposIcon(winInfo,x,y)
XWinIconFrame *winInfo;
Xint x,y;
X{
X WinNewPosFunc(winInfo,x,y);
X if (winInfo->iconslot == NULL &&
X !ClientIsPinnable(winInfo->core.client) &&
X winInfo->core.client->transientFor == 0) {
X SlotAlloc(winInfo, winInfo->fManuallyPositioned, GRV.FSnapToGrid);
X }
X return winInfo->core.dirtyconfig;
X}
X
X
Xstatic void
XdrawDashedRect(dpy, winInfo, win, x, y, w, h)
X Display *dpy;
X WinIconFrame *winInfo;
X Window win;
X int x, y, w, h;
X{
X XPoint pts[5];
X
X pts[0].x = x; pts[0].y = y;
X pts[1].x = x; pts[1].y = y + h;
X pts[2].x = x + w; pts[2].y = y + h;
X pts[3].x = x + w; pts[3].y = y;
X pts[4].x = x; pts[4].y = y;
X
X /*
X * The following is necessary because IconBorderGC uses the LineOnOffDash
X * line-style, which is faster than LineDoubleDash on some servers.
X */
X XDrawLines(dpy, win, WinGC(winInfo,WORKSPACE_GC),
X pts, 5, CoordModeOrigin);
X XDrawLines(dpy, win, WinGC(winInfo,ICON_BORDER_GC),
X pts, 5, CoordModeOrigin);
X}
X
X/*
X * drawIconBorder -- based on the value of select, draw the border for an icon
X */
Xstatic void
XdrawIconBorder(dpy, winInfo, select)
XDisplay *dpy;
XWinIconFrame *winInfo;
XBool select;
X{
X int x, y; /* values for use with */
X unsigned int width, height; /* rectangle drawn for border */
X Window w = winInfo->core.self;
X GC borderGC = WinGC(winInfo,BORDER_GC);
X GC workspaceGC = WinGC(winInfo,WORKSPACE_GC);
X
X x = y = 0;
X width = winInfo->core.width - 1;
X height = winInfo->core.height - 1;
X
X /*
X * If 3D is used, give "borderless" icons. Otherwise, give black and
X * white borders.
X */
X if (select) {
X XDrawRectangle(dpy, w, borderGC,
X x, y, width, height );
X XDrawRectangle(dpy, w, borderGC,
X x+1, y+1, width-2, height-2 );
X XDrawRectangle(dpy, w, borderGC,
X x+2, y+2, width-4, height-4 );
X } else {
X XDrawRectangle(dpy, w, workspaceGC,
X x, y, width, height);
X if (Win3D(winInfo)) {
X XDrawRectangle(dpy, w, workspaceGC,
X x+1, y+1, width-2, height-2);
X } else {
X#ifdef notdef
X XDrawRectangle(dpy, w, IconBorderGC,
X x+1, y+1, width-2, height-2);
X#endif /* notdef */
X drawDashedRect(dpy, winInfo, w, x+1, y+1, width-2, height-2);
X }
X
X XDrawRectangle(dpy, w, workspaceGC,
X x+2, y+2, width-4, height-4);
X }
X
X#ifdef notdef
X/*
X * This stuff was used for the attempt at 3D-look icons.
X * It has been abandoned in favor of the "borderless" icon look.
X */
X
X /* initial values for first rectangle */
X x = 0;
X y = 0;
X /* need to subtract one, based on how XDrawRectangle works */
X width = winInfo->core.width - 1;
X height = winInfo->core.height - 1;
X
X /* draw three rectangles for border */
X for ( rectangle = 0 ; rectangle < 3 ; rectangle++ )
X {
X switch( rectangle )
X {
X case 0: /* outermost rectangle */
X if (Win3D(winInfo))
X {
X if ( select )
X olgxState = OLGX_INVOKED;
X else
X olgxState = OLGX_NORMAL;
X
X olgx_draw_box( olgx_gisnormal,
X winInfo->core.self,
X x, y, width+1, height+1,
X olgxState, 0 );
X drawRectangle = False;
X }
X else
X {
X highlightGC = select
X ? DrawSelectedGC
X : DrawBackgroundGC;
X drawRectangle = True;
X }
X break;
X case 1: /* middle rectangle */
X if ( select )
X highlightGC = DrawSelectedGC;
X else if (Win3D(winInfo))
X highlightGC = DrawBackgroundGC;
X else /* REMIND eventually need to handle
X * IconBorder resource when 2d & ColorDisplay
X */
X highlightGC = IconBorderGC;
X drawRectangle = True;
X break;
X case 2: /* innermost rectangle */
X default:
X highlightGC = select ? DrawSelectedGC
X : DrawBackgroundGC;
X drawRectangle = True;
X break;
X }
X
X if ( drawRectangle )
X XDrawRectangle( dpy, winInfo->core.self, highlightGC,
X x, y, width, height );
X x++;
X y++;
X width -= 2;
X height -= 2;
X }
X#endif /* notdef */
X}
X
X/*
X * drawIcon -- draw the icon window
X */
X/*ARGSUSED*/ /* dpy arg will be used when multiple Displays supported */
Xstatic int
XdrawIcon(dpy, winInfo)
XDisplay *dpy;
XWinIconFrame *winInfo;
X{
X Window frameWin = winInfo->core.self;
X
X XFillRectangle(dpy, frameWin, WinGC(winInfo,WORKSPACE_GC),
X 0, 0, winInfo->core.width, winInfo->core.height);
X
X /* draw icon name */
X if (winInfo->core.client->wmDecors->flags & WMDecorationIconName)
X XDrawString(dpy, frameWin, WinGC(winInfo,ICON_NORMAL_GC),
X winInfo->nameX, winInfo->nameY,
X winInfo->fcore.name, winInfo->nameLength);
X
X /* draw border */
X drawIconBorder(dpy, winInfo, winInfo->core.client->isSelected);
X}
X
X
X/*
X * DestroyIcon -- destroy the icon window resources and free any allocated
X * data.
X */
Xstatic int
XdestroyIcon(dpy, winInfo)
XDisplay *dpy;
XWinIconFrame *winInfo;
X{
X /*
X * Free our data and throw away window
X */
X SlotFree(winInfo);
X ListDestroy(winInfo->core.children);
X MemFree(winInfo->fcore.name);
X XUndefineCursor(dpy, winInfo->core.self);
X DestroyWindow(winInfo);
X MemFree(winInfo);
X}
X
X/*
X * heightIconName - returns the height of the icon name portion of
X * the total icon height.
X */
Xstatic int
XheightIconName(win)
XWinIconFrame *win;
X{
X if (win->core.client->wmDecors->flags & WMDecorationIconName)
X {
X return (GRV.IconFontInfo->max_bounds.ascent +
X GRV.IconFontInfo->max_bounds.descent +
X ICON_VERTBORDER);
X } else {
X return 0;
X }
X}
X
X/*
X * heightTopIcon - returns the height of the top portion of the icon window.
X * If the IconPane (image/window) is too small then increase the
X * the top height to bring total height to the minimal icon
X * window size of ICON_WIN_HEIGHT. Otherwise use the default
X * border size.
X */
Xstatic int
XheightTopIcon(win)
XWinIconFrame *win;
X{
X WinIconPane *winPane = (WinIconPane *)(win->fcore.panewin);
X int availHeight,basicbottom;
X
X availHeight = ICON_WIN_HEIGHT - heightIconName(win);
X
X if (winPane->core.height < availHeight) {
X return (availHeight-winPane->core.height)/2;
X } else {
X return ICON_VERTBORDER;
X }
X}
X
X/*
X * heightBottomIcon - returns the height of the bottom portion of
X * the icon window - which includes the icon name string (if any).
X * If the IconPane (image/window) is too small then increase the
X * the bottom height to bring total height to the minimal icon
X * window size of ICON_WIN_HEIGHT. Otherwise use the default
X * border size.
X */
Xstatic int
XheightBottomIcon(win)
XWinIconFrame *win;
X{
X WinIconPane *winPane = (WinIconPane *)(win->fcore.panewin);
X int nameHeight,availHeight;
X
X nameHeight = heightIconName(win);
X
X availHeight = ICON_WIN_HEIGHT - nameHeight;
X
X if (winPane->core.height < availHeight) {
X return (availHeight - winPane->core.height)/2 + nameHeight;
X } else {
X return nameHeight + ICON_VERTBORDER;
X }
X}
X
X/* The icon pane has the same border width on either side, so this function
X * is used to calculate both border widths.
X */
Xstatic int
XwidthBothIcon(win)
XWinIconFrame *win;
X{
X WinIconPane *winPane = (WinIconPane *)(win->fcore.panewin);
X
X if (winPane->iconClientWindow)
X {
X return ICON_HORZBORDER;
X }
X else
X {
X if (winPane->core.width < ICON_WIN_WIDTH - 2*ICON_HORZBORDER)
X {
X return (ICON_WIN_WIDTH-winPane->core.width)/2;
X }
X else
X return ICON_HORZBORDER;
X }
X}
X
X/*
X * fullrestoreIcon
X * Switch icon menus and if this client is iconic then
X * open it.
X */
Xstatic int
XfullrestoreIcon(client)
XClient *client;
X{
X WinIconFrame *iconInfo = client->iconwin;
X
X if (client->wmState == IconicState)
X StateIconNorm(client);
X
X iconInfo->fcore.fullsize = !iconInfo->fcore.fullsize;
X}
X
X
X/***************************************************************************
X* global functions
X***************************************************************************/
X
X/*
X * MakeIcon -- create the icon window. Return a WinIconFrame structure.
X * Note that unlike most Make functions, icons are not mapped right
X * away.
X */
XWinIconFrame *
XMakeIcon(cli,panewin,paneattrs)
XClient *cli;
XWindow panewin;
XXWindowAttributes *paneattrs;
X{
X Display *dpy = cli->dpy;
X WinIconFrame *w;
X XSetWindowAttributes attributes;
X unsigned long valuemask;
X XWMHints *wmHints = cli->wmHints;
X
X /* create the window structure */
X w = MemNew(WinIconFrame);
X w->core.kind = WIN_ICON;
X w->class = &classIconFrame;
X w->core.parent = NULL;
X w->core.children = NULL;
X w->core.client = cli;
X w->core.width = ICON_WIN_WIDTH;
X w->core.height = ICON_WIN_HEIGHT;
X
X /* fill out the associated structure */
X w->core.dirtyconfig = CWX|CWY|CWWidth|CWHeight;
X w->core.colormap = None;
X w->core.exposures = NULL;
X w->core.helpstring = "olwm:Icon";
X
X /* create the icon frame */
X attributes.border_pixel = 0;
X attributes.colormap = cli->scrInfo->colormap;
X attributes.event_mask = ICON_EVENT_MASK;
X valuemask = CWBorderPixel | CWColormap | CWEventMask;
X w->core.self = XCreateWindow(dpy,
X cli->scrInfo->rootid,
X w->core.x, w->core.y, 1, 1, 0,
X cli->scrInfo->depth,
X InputOutput,
X cli->scrInfo->visual,
X valuemask, &attributes);
X
X /* install icon frame in client */
X cli->iconwin = w; /* REMIND: should be called cli->iconframe */
X
X /* set the position - either from position or icon slot */
X if (wmHints && (wmHints->flags & IconPositionHint))
X {
X w->core.x = wmHints->icon_x;
X w->core.y = wmHints->icon_y;
X w->fManuallyPositioned = True;
X }
X else
X {
X /* to be fixed up at config time */
X w->core.x = w->core.y = 0;
X w->fManuallyPositioned = False;
X }
X
X /* register the window */
X WIInstallInfo(w);
X
X /* set cursor for frame */
X XDefineCursor( dpy, w->core.self, GRV.IconPointer );
X
X iconSetName(w,panewin);
X
X w->fcore.fullsize = False;
X
X return w;
X}
X
Xvoid
XIconInit(dpy)
XDisplay *dpy;
X{
X classIconFrame.core.kind = WIN_ICON;
X classIconFrame.core.xevents[Expose] = WinEventExpose;
X classIconFrame.core.xevents[ButtonRelease] = GFrameEventButtonRelease;
X classIconFrame.core.xevents[MotionNotify] = GFrameEventMotionNotify;
X classIconFrame.core.xevents[ButtonPress] = GFrameEventButtonPress;
X classIconFrame.core.xevents[EnterNotify] = GFrameEventEnterNotify;
X classIconFrame.core.xevents[FocusIn] = GFrameEventFocus;
X classIconFrame.core.xevents[FocusOut] = GFrameEventFocus;
X classIconFrame.core.focusfunc = GFrameFocus;
X classIconFrame.core.drawfunc = drawIcon;
X classIconFrame.core.destroyfunc = destroyIcon;
X classIconFrame.core.selectfunc = GFrameSelect;
X classIconFrame.core.newconfigfunc = newconfigIcon;
X classIconFrame.core.newposfunc = newposIcon;
X classIconFrame.core.setconfigfunc = GFrameSetConfigFunc;
X classIconFrame.core.createcallback = NULL;
X classIconFrame.core.heightfunc = NULL;
X classIconFrame.core.widthfunc = NULL;
X classIconFrame.fcore.heighttop = heightTopIcon;
X classIconFrame.fcore.heightbottom = heightBottomIcon;
X classIconFrame.fcore.widthleft = widthBothIcon;
X classIconFrame.fcore.widthright = widthBothIcon;
X classIconFrame.fcore.menuPress = menuPressIcon;
X classIconFrame.fcore.adjustPress = NULL;
X classIconFrame.fcore.adjustClick = adjustClickIcon;
X classIconFrame.fcore.selectPress = NULL;
X classIconFrame.fcore.selectClick = NULL;
X classIconFrame.fcore.selectDoubleClick = selectDoubleClickIcon;
X classIconFrame.fcore.selectDrag = selectDragIcon;
X classIconFrame.fcore.fullrestoreToggle = fullrestoreIcon;
X}
X
X/*
X * DrawIconToWindowLines -- draw the open (close) lines when a window is
X * becoming an icon or vice-versa
X */
Xvoid
XDrawIconToWindowLines(dpy, iconInfo, winInfo)
XDisplay *dpy;
XWinPaneFrame *winInfo;
XWinIconFrame *iconInfo;
X{
X int ii;
X GC rootGC = WinGC(winInfo,ROOT_GC);
X Window root = WinRootID(winInfo);
X
X XGrabServer(dpy);
X
X for(ii=0; ii < GRV.IconFlashCount ; ii++)
X {
X /* draw the close lines */
X XDrawLine(dpy, root, rootGC,
X iconInfo->core.x,
X iconInfo->core.y,
X winInfo->core.x,
X winInfo->core.y);
X XDrawLine(dpy, root, rootGC,
X iconInfo->core.x,
X (int)(iconInfo->core.y + iconInfo->core.height),
X winInfo->core.x,
X (int)(winInfo->core.y + winInfo->core.height));
X XDrawLine(dpy, root, rootGC,
X (int)(iconInfo->core.x + iconInfo->core.width),
X iconInfo->core.y,
X (int)(winInfo->core.x + winInfo->core.width),
X winInfo->core.y);
X XDrawLine(dpy, root, rootGC,
X (int)(iconInfo->core.x + iconInfo->core.width),
X (int)(iconInfo->core.y + iconInfo->core.height),
X (int)(winInfo->core.x + winInfo->core.width),
X (int)(winInfo->core.y + winInfo->core.height));
X
X XFlush(dpy);
X olwm_usleep((unsigned) GRV.IconFlashOnTime);
X
X /* erase the close lines */
X XDrawLine(dpy, root, rootGC,
X iconInfo->core.x,
X iconInfo->core.y,
X winInfo->core.x,
X winInfo->core.y);
X XDrawLine(dpy, root, rootGC,
X iconInfo->core.x,
X (int)(iconInfo->core.y + iconInfo->core.height),
X winInfo->core.x,
X (int)(winInfo->core.y + winInfo->core.height));
X XDrawLine(dpy, root, rootGC,
X (int)(iconInfo->core.x + iconInfo->core.width),
X iconInfo->core.y,
X (int)(winInfo->core.x + winInfo->core.width),
X winInfo->core.y);
X XDrawLine(dpy, root, rootGC,
X (int)(iconInfo->core.x + iconInfo->core.width),
X (int)(iconInfo->core.y + iconInfo->core.height),
X (int)(winInfo->core.x + winInfo->core.width),
X (int)(winInfo->core.y + winInfo->core.height));
X XFlush(dpy);
X olwm_usleep((unsigned) GRV.IconFlashOffTime);
X }
X
X XUngrabServer(dpy);
X}
X
X/*
X * IconUpdateName -- the icon name property has been changed
X */
Xvoid
XIconUpdateName(cli,event)
X Client *cli;
X XPropertyEvent *event;
X{
X iconSetName(cli->iconwin,PANEWINOFCLIENT(cli));
X}
X
X/*
X * Set the icon's (x,y) location explicitly. This information is typically
X * taken from the WM_HINTS structure. Since the coordinates specify the
X * absolute position of the icon pane, we must subtract the icon border to get
X * the position if the icon frame.
X */
Xvoid
XIconSetPos(win,x,y)
XWinIconFrame *win;
Xint x,y;
X{
X (WinFunc(win,core.newposfunc))(win,x-ICON_HORZBORDER,y-ICON_VERTBORDER);
X}
X
X/*
X * IconShow -- map an icon onto the screen, handling reparenting and
X * save-sets for icon panes.
X */
Xvoid
XIconShow(cli, winIcon)
X Client *cli;
X WinIconFrame *winIcon;
X{
X WinIconPane *pane = (WinIconPane *)winIcon->fcore.panewin;
X
X XReparentWindow(cli->dpy, pane->core.self, winIcon->core.self,
X pane->core.x, pane->core.y);
X XMapWindow(cli->dpy, pane->core.self);
X if (pane->iconClientWindow && !(cli->flags & CLOlwmOwned))
X XChangeSaveSet(cli->dpy, pane->core.self, SetModeInsert);
X MapWindow(winIcon);
X}
X
X
X/*
X * IconHide -- remove an icon from the screen, handling reparenting and
X * save-sets for icon panes.
X */
Xvoid
XIconHide(cli, winIcon)
X Client *cli;
X WinIconFrame *winIcon;
X{
X WinIconPane *pane = (WinIconPane *)winIcon->fcore.panewin;
X
X UnmapWindow(winIcon);
X XUnmapWindow(cli->dpy, pane->core.self);
X XReparentWindow(cli->dpy, pane->core.self, cli->scrInfo->rootid,
X winIcon->core.x + pane->core.x,
X winIcon->core.y + pane->core.y);
X if (pane->iconClientWindow && !(cli->flags & CLOlwmOwned))
X XChangeSaveSet(cli->dpy, pane->core.self, SetModeDelete);
X}
END_OF_FILE
if test 21256 -ne `wc -c <'winicon.c'`; then
echo shar: \"'winicon.c'\" unpacked with wrong size!
fi
# end of 'winicon.c'
fi
if test -f 'winpinmenu.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'winpinmenu.c'\"
else
echo shar: Extracting \"'winpinmenu.c'\" \(10976 characters\)
sed "s/^X//" >'winpinmenu.c' <<'END_OF_FILE'
X/*
X * (c) Copyright 1989, 1990 Sun Microsystems, Inc. Sun design patents
X * pending in the U.S. and foreign countries. See LEGAL_NOTICE
X * file for terms of the license.
X */
X
X#ident "@(#)winpinmenu.c 1.1 olvwm version 1/3/92"
X
X/*
X * Based on
X#ident "@(#)winpinmenu.c 26.25 91/09/14 SMI"
X *
X */
X
X#include <errno.h>
X#include <stdio.h>
X#include <X11/Xos.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include <X11/Xatom.h>
X#include <olgx/olgx.h>
X
X#include "i18n.h"
X#include "ollocale.h"
X#include "mem.h"
X#include "olwm.h"
X#include "win.h"
X#include "menu.h"
X#include "globals.h"
X
X/***************************************************************************
X* global data
X***************************************************************************/
X
Xextern Atom AtomDecorAdd;
Xextern Atom AtomDecorHeader;
Xextern Atom AtomDecorPin;
Xextern Atom AtomDeleteWindow;
Xextern Atom AtomMenuLimited;
Xextern Atom AtomProtocols;
Xextern Atom AtomPushpinState;
Xextern Atom AtomWinAttr;
Xextern Atom AtomWTOther;
X
X
X/***************************************************************************
X* private data
X***************************************************************************/
X
X/* function vector for menu windows */
Xstatic ClassPinMenu classPinMenu;
X
X/***************************************************************************
X* private functions
X***************************************************************************/
X
X/*
X * afterMenuShow - called after MenuShowSync has finished showing
X * and possibly executing the menu.
X */
Xstatic void
XafterMenuShow(win)
X WinPinMenu *win;
X{
X MenuInfo *mInfo = win->menuInfo;
X Display *dpy = win->core.client->dpy;
X
X if (BUTTON_INDEX_OK(mInfo, mInfo->litButton)) {
X DrawLocCursor(dpy, mInfo, mInfo->litButton, False);
X SetButton(dpy, mInfo, mInfo->litButton, False, False);
X }
X SetButton(dpy, mInfo, mInfo->menu->buttonDefault, True, True);
X}
X
X/***************************************************************************
X* private event functions
X***************************************************************************/
X
X/*
X * eventButtonPress - a button has gone down.
X */
Xstatic int
XeventButtonPress(dpy, event, winInfo)
X Display *dpy;
X XEvent *event;
X WinPinMenu *winInfo;
X{
X if (! StartMenuGrabs(dpy, winInfo))
X return;
X
X MenuMakeFirst(winInfo->menuInfo, afterMenuShow, winInfo);
X
X MenuTrack(dpy, event, winInfo, winInfo);
X}
X
X
Xstatic int
XeventKeyEvent(dpy, event, winInfo)
X Display *dpy;
X XEvent *event;
X WinPinMenu *winInfo;
X{
X MenuMakeFirst(winInfo->menuInfo, afterMenuShow, winInfo);
X
X if (MenuHandleKeyEvent(dpy, event, winInfo, winInfo)) {
X if (! StartMenuGrabs(dpy, winInfo))
X return;
X }
X}
X
X/*
X * eventClientMessage - handle a DELETE_WINDOW message.
X */
X/*ARGSUSED*/
Xstatic int
XeventClientMessage(dpy, event, winInfo)
X Display *dpy;
X XEvent *event;
X WinPinMenu *winInfo;
X{
X if ((event->xclient.message_type == AtomProtocols) &&
X (event->xclient.data.l[0] == AtomDeleteWindow))
X {
X DestroyClient(winInfo->core.client);
X }
X}
X
X
Xstatic int
XeventEnterNotify(dpy, event, winInfo)
XDisplay *dpy;
XXEvent *event;
XWinPinMenu *winInfo;
X{
X if (event->xany.type == EnterNotify)
X ColorWindowCrossing(dpy, event, winInfo);
X}
X
X
Xstatic int
XfocusMenuFunc(dpy, winInfo, focus)
X Display *dpy;
X WinPinMenu *winInfo;
X Bool focus;
X{
X MenuInfo *mInfo = winInfo->menuInfo;
X
X if (mInfo->litButton != NOBUTTON && focus) {
X SetButton(dpy, mInfo, mInfo->menu->buttonDefault, False, True);
X SetButton(dpy, mInfo, mInfo->litButton, True, False);
X DrawLocCursor(dpy, mInfo, mInfo->litButton, True);
X } else if (! focus) {
X if (BUTTON_INDEX_OK(mInfo, mInfo->litButton)) {
X DrawLocCursor(dpy, mInfo, mInfo->litButton, False);
X SetButton(dpy, mInfo, mInfo->litButton, False, False);
X }
X SetButton(dpy, mInfo, mInfo->menu->buttonDefault, True, True);
X }
X}
X
X
X/*
X * destroyMenu -- destroy the menu window resources and free any allocated
X * data.
X */
Xstatic int
XdestroyMenu(dpy, winInfo)
X Display *dpy;
X WinPinMenu *winInfo;
X{
X MenuInfo *menuInfo = (MenuInfo *)(winInfo->menuInfo);
X
X /* tell the original menu that we're gone */
X menuInfo->origmenuInfo->pinnedBrother = NULL;
X
X /* remove window */
X XUndefineCursor(dpy, winInfo->core.self);
X DestroyWindow(winInfo);
X
X /* free memory */
X MemFree(menuInfo);
X MemFree(winInfo);
X}
X
X/*
X * newconfigMenu - recomputes the size of the menu window
X * Note that menus don't change size, so this is a no-op.
X */
X/*ARGSUSED*/
Xstatic int
XnewconfigMenu(win, pxcre)
X WinPinMenu *win;
X XConfigureRequestEvent *pxcre;
X{
X return win->core.dirtyconfig;
X}
X
X/* menuSetParent -- callback during creation. Since menus are internally-
X * created windows we must fix up certain fields that are only available
X * after the window is mapped.
X */
Xstatic int
XmenuSetParent(winInfo,cli,par)
X WinGeneric *winInfo;
X Client *cli;
X WinGenericFrame *par;
X{
X MenuInfo *mInfo;
X /* mark this client as owned by olwm itself */
X cli->flags = CLOlwmOwned;
X winInfo->core.client = cli;
X WinAddChild((WinGeneric *)par, winInfo);
X XReparentWindow(cli->dpy, winInfo->core.self, par->core.self,
X winInfo->core.x, winInfo->core.y);
X par->fcore.panewin = (WinGenericPane *)winInfo;
X mInfo = ((WinPinMenu *) winInfo)->menuInfo;
X winInfo->core.helpstring = mInfo->menu->helpstring;
X par->core.helpstring = mInfo->menu->helpstring;
X}
X
X/***************************************************************************
X* global functions
X***************************************************************************/
X
X/*
X * MakePinMenu -- create the pinned menu's menu window (around which we'll put
X * a frame). The window is mapped during the transition to normal
X * state.
X */
XWinPinMenu *
XMakePinMenu(dpy, winInfo, origMenuInfo)
X Display *dpy;
X WinGeneric *winInfo;
X MenuInfo *origMenuInfo;
X{
X WinPinMenu *w;
X Window win;
X Window rootWin;
X unsigned long valuemask;
X XSetWindowAttributes attributes;
X Atom atomList[3];
X XSizeHints sizeHints;
X XWMHints wmHints;
X MenuInfo *newMenuInfo;
X
X /* Make a copy of the original MenuInfo
X * the main difference is that a pinned menu does not have a title
X * in itself since the frame takes care of the title for us.
X * Also adjust our height to remove the title height
X */
X newMenuInfo = MemNew(MenuInfo);
X *newMenuInfo = *origMenuInfo;
X newMenuInfo->menu = origMenuInfo->menu;
X newMenuInfo->titleWidth = 0;
X newMenuInfo->titleHeight = 0;
X newMenuInfo->menuHeight = origMenuInfo->menuHeight - origMenuInfo->titleHeight;
X newMenuInfo->buttonOffset = newMenuInfo->notitleOffset;
X
X newMenuInfo->childActive = False;
X newMenuInfo->pinIn = False;
X newMenuInfo->litButton = NOBUTTON;
X newMenuInfo->ringedButton = newMenuInfo->menu->buttonDefault;
X
X /* save a back pointer to the original and mark it pinned */
X newMenuInfo->origmenuInfo = origMenuInfo;
X newMenuInfo->pinnedBrother = NULL;
X origMenuInfo->pinnedBrother = newMenuInfo;
X
X /* create the associated structure */
X w = MemNew(WinPinMenu);
X w->class = &classPinMenu;
X w->core.kind = WIN_PINMENU;
X w->core.children = NULL;
X w->core.client = winInfo->core.client;
X w->core.x = newMenuInfo->menuX;
X w->core.y = newMenuInfo->menuY;
X w->core.width = newMenuInfo->menuWidth;
X w->core.height = newMenuInfo->menuHeight;
X w->core.dirtyconfig = CWX|CWY|CWWidth|CWHeight;
X w->core.exposures = NULL;
X w->core.helpstring = (char *)0;
X w->core.colormap = winInfo->core.client->scrInfo->colormap;
X
X /* create the actual window */
X attributes.event_mask = ButtonReleaseMask | ButtonPressMask |
X ExposureMask | PropertyChangeMask | ButtonMotionMask |
X KeyPressMask | KeyReleaseMask | EnterWindowMask;
X attributes.background_pixel =
X winInfo->core.client->scrInfo->colorInfo.bg1Color;
X attributes.border_pixel = 0;
X attributes.colormap = w->core.colormap;
X attributes.cursor = GRV.MenuPointer;
X valuemask = CWEventMask | CWBackPixel | CWBorderPixel |
X CWColormap | CWCursor;
X
X win = XCreateWindow(dpy, WinRootID(winInfo),
X w->core.x, w->core.y,
X w->core.width, w->core.height,
X 0,
X WinDepth(winInfo),
X InputOutput,
X WinVisual(winInfo),
X valuemask,
X &attributes);
X w->core.self = win;
X
X /* register the window */
X WIInstallInfo((WinGeneric *)w);
X
X /* first we set the properties defining what kind of
X OpenLook window it is */
X atomList[0] = AtomWTOther;
X atomList[1] = AtomMenuLimited;
X atomList[2] = (Atom) PIN_IN;
X XChangeProperty(dpy, win, AtomWinAttr, AtomWinAttr,
X 32, PropModeReplace, (unsigned char *)atomList, 3);
X
X /* add a push-pin */
X atomList[0] = AtomDecorPin;
X atomList[1] = AtomDecorHeader;
X XChangeProperty(dpy, win, AtomDecorAdd, XA_ATOM,
X 32, PropModeReplace, (unsigned char *)atomList, 2);
X
X /* set protocols */
X atomList[0] = AtomDeleteWindow;
X XChangeProperty(dpy, win, AtomProtocols, XA_ATOM,
X 32, PropModeReplace, (unsigned char *)atomList, 1);
X
X /* now set the size hints */
X sizeHints.flags = USPosition | USSize;
X XChangeProperty(dpy, win, XA_WM_NORMAL_HINTS, XA_WM_SIZE_HINTS,
X 32, PropModeReplace, (unsigned char *)&sizeHints,
X sizeof(XSizeHints)/sizeof(long));
X
X /* and the wmHints */
X wmHints.flags = InputHint | StateHint;
X wmHints.initial_state = NormalState;
X wmHints.input = True;
X
X if (winInfo->core.kind == WIN_VIRTUAL) {
X wmHints.flags |= WindowGroupHint;
X wmHints.window_group = winInfo->core.self;
X }
X
X XChangeProperty(dpy, win, XA_WM_HINTS, XA_WM_HINTS,
X 32, PropModeReplace, (unsigned char *)&wmHints,
X sizeof(XWMHints)/sizeof(long));
X
X /* put the title into the header */
X XStoreName(dpy, win, newMenuInfo->menu->title);
X
X newMenuInfo->menuWin = (WinGeneric *)w;
X w->menuInfo = newMenuInfo;
X
X rootWin = w->core.client->scrInfo->rootid;
X StateNew(dpy, rootWin, win, False, (WinPane *)w);
X
X return w;
X}
X
X/*
X * PinMenuInit - initializes class functions
X */
X/*ARGSUSED*/
Xint
XPinMenuInit(dpy)
XDisplay *dpy;
X{
X classPinMenu.core.kind = WIN_PINMENU;
X classPinMenu.core.xevents[ButtonPress] = eventButtonPress;
X classPinMenu.core.xevents[ClientMessage] = eventClientMessage;
X classPinMenu.core.xevents[KeyPress] = eventKeyEvent;
X classPinMenu.core.xevents[KeyRelease] = eventKeyEvent;
X classPinMenu.core.xevents[EnterNotify] = eventEnterNotify;
X classPinMenu.core.xevents[Expose] = MenuEventExpose;
X classPinMenu.core.focusfunc = focusMenuFunc;
X classPinMenu.core.drawfunc = MenuEventDrawMenu;
X classPinMenu.core.destroyfunc = destroyMenu;
X classPinMenu.core.selectfunc = NULL;
X classPinMenu.core.newconfigfunc = newconfigMenu;
X classPinMenu.core.newposfunc = WinNewPosFunc;
X classPinMenu.core.setconfigfunc = WinSetConfigFunc;
X classPinMenu.core.createcallback = menuSetParent;
X classPinMenu.core.heightfunc = NULL;
X classPinMenu.core.widthfunc = NULL;
X classPinMenu.pcore.setsizefunc = NULL;
X}
END_OF_FILE
if test 10976 -ne `wc -c <'winpinmenu.c'`; then
echo shar: \"'winpinmenu.c'\" unpacked with wrong size!
fi
# end of 'winpinmenu.c'
fi
if test -f 'winroot.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'winroot.c'\"
else
echo shar: Extracting \"'winroot.c'\" \(17999 characters\)
sed "s/^X//" >'winroot.c' <<'END_OF_FILE'
X/*
X * (c) Copyright 1989, 1990 Sun Microsystems, Inc. Sun design patents
X * pending in the U.S. and foreign countries. See LEGAL_NOTICE
X * file for terms of the license.
X */
X
X#ident "@(#)winroot.c 1.1 olvwm version 1/3/92"
X
X/*
X * Based on
X#ident "@(#)winroot.c 26.48 91/09/20 SMI"
X *
X */
X
X#include <errno.h>
X#include <stdio.h>
X#include <X11/Xos.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include <X11/Xatom.h>
X#include <olgx/olgx.h>
X
X#include "i18n.h"
X#include "ollocale.h"
X#include "mem.h"
X#include "olwm.h"
X#include "win.h"
X#include "menu.h"
X#include "globals.h"
X#include "group.h"
X#include "events.h"
X#include "virtual.h"
X
X/***************************************************************************
X* global data
X***************************************************************************/
X
Xextern Time SelectionTime;
Xextern Atom AtomSunWMProtocols;
Xextern Atom AtomSunWindowState;
Xextern Atom AtomSunOLWinAttr5;
Xextern Bool DoingWindowState;
X
X/***************************************************************************
X* private data
X***************************************************************************/
X
Xstatic ClassRoot classRoot;
X
X/***************************************************************************
X* private functions
X***************************************************************************/
X
Xstatic Window
XfindLeafWindow(dpy,win,srcx,srcy,dstx,dsty)
X Display *dpy;
X Window win;
X int srcx,srcy;
X int *dstx,*dsty;
X{
X Window childwin,dstwin,srcwin;
X
X srcwin = dstwin = win;
X while (1) {
X XTranslateCoordinates(dpy,srcwin,dstwin,srcx,srcy,
X dstx,dsty,&childwin);
X if (childwin == None)
X break;
X srcx = *dstx; srcy = *dsty;
X srcwin = dstwin;
X dstwin = childwin;
X }
X return dstwin;
X}
X
Xstatic void
XredistributeKeystroke(dpy,key,dstwin,dstx,dsty )
X Display *dpy;
X XKeyEvent *key;
X Window dstwin;
X int dstx,dsty;
X{
X static Bool pressreceived = False;
X static XKeyEvent pressevent;
X Window childwin;
X
X if (key->type == KeyPress) {
X if (pressreceived == False) {
X pressevent = *key;
X pressevent.x = dstx;
X pressevent.y = dsty;
X pressevent.window = dstwin;
X pressevent.subwindow = None;
X XSendEvent( dpy, pressevent.window, True,
X KeyPressMask, (XEvent *)&pressevent );
X pressreceived = True;
X }
X } else {
X if (key->window != pressevent.window) {
X XTranslateCoordinates(dpy,key->window,pressevent.window,
X key->x,key->y,&dstx,&dsty,&childwin );
X key->window = pressevent.window;
X key->x = dstx;
X key->y = dsty;
X }
X key->subwindow = None;
X XSendEvent(dpy,pressevent.window,True,
X KeyPressMask,(XEvent *)key);
X if (key->type == KeyRelease)
X pressreceived = False;
X }
X}
X
X
X/*
X * HandleHelpKey - Figure out what window should really get the Help key.
X * If it's not an olwm window or a pane window then send the key event
X * onto that window. If it's an olwm window then bring up the help
X * info window with the window kind specific help. If it is a
X * WIN_ROOT window we need to use key->root since it is the root
X * window that the pointer was on when the event happened while
X * key->window is the window that the grab was made on.
X */
Xvoid
XHandleHelpKey(dpy, pEvent)
X Display *dpy;
X XEvent *pEvent;
X{
X static WinGeneric *olwmWin = (WinGeneric *)0;
X XKeyEvent *key = (XKeyEvent *)pEvent;
X static Window dstwin = None;
X int dstx,dsty;
X
X if (key->type == KeyPress) {
X
X dstwin = findLeafWindow(dpy,key->window,
X key->x_root,key->y_root,&dstx,&dsty);
X olwmWin = WIGetInfo(dstwin);
X if (!olwmWin) {
X olwmWin = VGetInfo(dstwin);
X if (olwmWin && olwmWin->core.client)
X olwmWin = (WinGeneric *)
X olwmWin->core.client->scrInfo->vdm->client->framewin->fcore.panewin;
X }
X
X /* send the help key to the client window */
X if (olwmWin == NULL || olwmWin->core.kind == WIN_PANE) {
X redistributeKeystroke(dpy,key,dstwin,dstx,dsty);
X olwmWin = (WinGeneric *)0;
X
X /* find out which root window is really happened on */
X } else if (olwmWin->core.kind == WIN_ROOT) {
X if (dstwin != key->root)
X olwmWin = WIGetInfo(key->root);
X WinShowHelp(dpy,olwmWin,key->x_root,key->y_root);
X
X /* it belongs to a decoration window (frame/resize/whatever) */
X } else {
X WinShowHelp(dpy,olwmWin,key->x_root,key->y_root);
X }
X } else { /* if KeyRelease */
X if (olwmWin == NULL && dstwin != None)
X redistributeKeystroke(dpy,key,dstwin,0,0);
X dstwin = None;
X }
X}
X
Xstatic Bool
XmatchKeystrokeToSpec(event,spec)
X XEvent *event;
X KeySpec *spec;
X{
X return (spec->keycode == event->xkey.keycode &&
X (spec->modmask == AnyModifier ||
X spec->modmask == event->xkey.state));
X}
X
X/***************************************************************************
X* event functions
X***************************************************************************/
X
X/*
X * eventEnterNotify - the pointer has entered the root window
X */
Xstatic int
XeventEnterNotify(dpy, pEvent, winInfo)
X Display *dpy;
X XEvent *pEvent;
X WinRoot *winInfo;
X{
X ColorWindowCrossing(dpy, pEvent, winInfo);
X
X if (GRV.FocusFollowsMouse)
X NoFocusTakeFocus(dpy, pEvent->xcrossing.time,
X winInfo->core.client->scrInfo);
X}
X
X/*
X * eventConfigureRequest - a client wants to change configuration
X */
Xstatic int
XeventConfigureRequest(dpy, pEvent, winInfo)
X Display *dpy;
X XEvent *pEvent;
X WinRoot *winInfo;
X{
X WinGeneric *clientInfo;
X#define ConfEvent (pEvent->xconfigurerequest)
X
X if ((clientInfo = WIGetInfo(ConfEvent.window)) == NULL)
X {
X /* we don't know about this window, so let it go */
X ClientConfigure(NULL,NULL,pEvent);
X }
X else /* OBSOLETE: if (ConfEvent.value_mask & (CWX | CWY | CWWidth | CWHeight)) */
X {
X /* configure the window and its frame */
X ClientConfigure(clientInfo->core.client,clientInfo,pEvent);
X }
X /* REMIND doesn't handle stacking or border width yet */
X}
X
X/*
X * eventMapRequest - a new client is mapping
X */
Xstatic int
XeventMapRequest(dpy, pEvent, winInfo)
X Display *dpy;
X XEvent *pEvent;
X WinRoot *winInfo;
X{
X#ifdef GPROF_HOOKS
X moncontrol(1);
X#endif /* GPROF_HOOKS */
X StateNew(dpy,winInfo->core.self,pEvent->xmaprequest.window,False,NULL);
X#ifdef GPROF_HOOKS
X moncontrol(0);
X#endif /* GPROF_HOOKS */
X}
X
X
Xstatic void
XselectInBox(dpy, winInfo, boxX, boxY, boxW, boxH, timestamp, closure)
X Display *dpy;
X WinRoot *winInfo;
X int boxX, boxY;
X unsigned int boxW, boxH;
X Time timestamp;
X void *closure;
X{
X ClientInBoxClosure cibclosure;
X int fuzz = GRV.SelectionFuzz;
X
X /*
X * Apply selectFunc to all clients in the box.
X * Widen the box slightly to make selections easier.
X */
X cibclosure.dpy = dpy;
X cibclosure.screen = WinScreen(winInfo);
X cibclosure.func = (int (*)()) closure;
X cibclosure.bx = boxX - fuzz;
X cibclosure.by = boxY - fuzz;
X cibclosure.bw = boxW + 2 * fuzz;
X cibclosure.bh = boxH + 2 * fuzz;
X cibclosure.timestamp = timestamp;
X ListApply(ActiveClientList, ClientInBox, &cibclosure);
X}
X
X
X/*
X * eventMotionNotify - the pointer is moving
X */
Xstatic int
XeventMotionNotify(dpy, pEvent, winInfo)
X Display *dpy;
X XEvent *pEvent;
X WinRoot *winInfo;
X{
X short boxX, boxY, boxW, boxH;
X int (*selectFunc)();
X
X if (!pEvent->xmotion.same_screen)
X return;
X
X /* If the user hasn't moved more than the threshold
X * amount, break out of here. REMIND Also, if we get a
X * MotionNotify event with no buttons down, we ignore it.
X * Ideally this shouldn't happen, but some areas of the code
X * still leave the pointer grabbed even after all the buttons
X * have gone up.
X */
X if ((ABS(pEvent->xmotion.x - winInfo->buttonPressEvent.xbutton.x) <
X GRV.MoveThreshold) &&
X (ABS(pEvent->xmotion.y - winInfo->buttonPressEvent.xbutton.y) <
X GRV.MoveThreshold))
X return;
X if (pEvent->xmotion.state == 0)
X return;
X
X /*
X * On Select: Clear existing selected clients and add new ones
X * On Adjust: Toggle selections on/off
X */
X switch(winInfo->currentAction) {
X case ACTION_SELECT:
X ClearSelections(dpy);
X selectFunc = AddSelection;
X break;
X case ACTION_ADJUST:
X selectFunc = ToggleSelection;
X break;
X default:
X selectFunc = NULL;
X break;
X }
X
X if (selectFunc)
X TraceRootBox(dpy, winInfo, &(winInfo->buttonPressEvent),
X selectInBox, selectFunc);
X}
X
X/*
X * eventButtonRelease - handle a click in the root.
X *
X * If the user clicks in the window, the focus is set to the no-focus window,
X * and the PRIMARY selection is acquired and nulled.
X */
Xstatic int
XeventButtonRelease(dpy, pEvent, winInfo)
X Display *dpy;
X XEvent *pEvent;
X WinRoot *winInfo;
X{
X if (!AllButtonsUp(pEvent))
X return;
X
X /*
X * This only happens if we did NOT get a motion notify
X * after the last button press.
X */
X if (winInfo->currentAction == ACTION_SELECT) {
X NoFocusTakeFocus(dpy,pEvent->xbutton.time,
X winInfo->core.client->scrInfo);
X ClearSelections(dpy);
X XSetSelectionOwner(dpy, XA_PRIMARY, NoFocusWin,
X pEvent->xbutton.time);
X SelectionTime = pEvent->xbutton.time;
X }
X winInfo->currentAction = ACTION_NONE;
X}
X
X/*
X * eventButtonPress - handle a button press. If the WMGRAB modifier is down,
X * we've received this event by virtue of a passive, synchronous button grab
X * on the root. We need to (1) propagate the event to the window underneath,
X * if it's a frame or an icon, (2) unfreeze the pointer either by regrabbing
X * or by issuing an AllowEvents request, and (3) ungrab the pointer if the
X * child's handler didn't issue a grab of its own.
X */
Xstatic int
XeventButtonPress(dpy, pEvent, winInfo)
X Display *dpy;
X XEvent *pEvent;
X WinRoot *winInfo;
X{
X SemanticAction a;
X WinGeneric *child;
X
X if (pEvent->xbutton.state & ModMaskMap[MOD_WMGRAB]) {
X /* redistribute to child */
X if (pEvent->xbutton.subwindow != NULL &&
X (child = WIGetInfo(pEvent->xbutton.subwindow)) != NULL &&
X (child->core.kind == WIN_FRAME ||
X child->core.kind == WIN_ICON) &&
X (GrabSuccess == XGrabPointer(dpy, child->core.self, False,
X ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
X GrabModeAsync, GrabModeAsync, None, None,
X pEvent->xbutton.time)))
X {
X PropagatePressEventToChild(dpy, pEvent, child);
X return;
X }
X
X /*
X * If the window under the pointer isn't a frame or icon, or if we
X * failed to grab the pointer, simply unfreeze the pointer and try
X * to process the event normally.
X */
X XAllowEvents(dpy, AsyncBoth, pEvent->xbutton.time);
X }
X
X a = ResolveMouseBinding(dpy, pEvent, ModMaskMap[MOD_CONSTRAIN]);
X
X winInfo->buttonPressEvent = *pEvent;
X
X switch (a) {
X case ACTION_MENU:
X RootMenuShow(dpy, winInfo, pEvent);
X /* FALL THRU */
X case ACTION_SELECT:
X case ACTION_ADJUST:
X winInfo->currentAction = a;
X break;
X }
X}
X
X
X/*
X * eventKeyPressRelease - a keystroke has happened in the root window
X */
Xstatic int
XeventKeyPressRelease(dpy, pEvent, winInfo)
X Display *dpy;
X XEvent *pEvent;
X WinRoot *winInfo;
X{
X
X Window child;
X WinGeneric *childInfo;
X Client *childClient;
X Bool samescreen;
X int destX, destY;
X extern Bool ExecuteKeyboardFunction();
X Bool isbound;
X
X isbound = ExecuteKeyboardFunction(dpy, pEvent);
X
X if (!isbound && GRV.ArrowInRoot)
X isbound = KeyMoveVDM(dpy, pEvent);
X
X if (!isbound && pEvent->type == KeyPress)
X KeyBeep(dpy,pEvent);
X
X#ifdef notdef
X samescreen = XTranslateCoordinates(dpy,
X pEvent->xkey.root, pEvent->xkey.root,
X pEvent->xkey.x_root, pEvent->xkey.y_root,
X &destX, &destY, &child );
X
X if (!samescreen)
X return;
X
X if (pEvent->type == KeyPress && child != None &&
X matchKeystrokeToSpec(pEvent, &(GRV.FrontKey))) {
X
X XWindowChanges xwc;
X xwc.stack_mode = Opposite; NOT DEF
X XConfigureWindow( dpy, child, CWStackMode, &xwc );
X
X } else if (matchKeystrokeToSpec(pEvent, &(GRV.HelpKey))) {
X
X handleHelpKey(dpy,pEvent);
X
X } else if (pEvent->type == KeyPress && child != None &&
X matchKeystrokeToSpec(pEvent, &(GRV.OpenKey))) {
X
X childInfo = WIGetInfo(child);
X if ( childInfo ) {
X childClient = childInfo->core.client;
X if (childClient != NULL) {
X ClientOpenCloseToggle(childClient);
X }
X }
X } else if (pEvent->type == KeyPress &&
X matchKeystrokeToSpec(pEvent, &(GRV.ColorLockKey))) {
X
X InstallPointerColormap(dpy, pEvent->xkey.root,
X pEvent->xkey.x_root, pEvent->xkey.y_root, True);
X
X } else if (pEvent->type == KeyPress &&
X matchKeystrokeToSpec(pEvent, &(GRV.ColorUnlockKey))) {
X
X UnlockColormap(dpy,winInfo);
X }
X#endif /* notdef */
X}
X
X/*
X * eventPropertyNotify - a root property has changed
X */
Xstatic int
XeventPropertyNotify(dpy, pEvent, winInfo)
X Display *dpy;
X XEvent *pEvent;
X WinRoot *winInfo;
X{
X unsigned long nitems, remain;
X char *resourceString;
X
X /* make sure that the property was the one we care about and
X * changed (as opposed to deleted)
X */
X if ( (pEvent->xproperty.atom != XA_RESOURCE_MANAGER)
X || (pEvent->xproperty.state != PropertyNewValue) )
X return;
X
X resourceString = GetWindowProperty(dpy, WinRootID(winInfo),
X XA_RESOURCE_MANAGER, 0L, 100000000L,
X /* REMIND use ENTIRE_CONTENTS */
X XA_STRING, 0, &nitems, &remain);
X if (resourceString != NULL) {
X UpdateGlobals(dpy, resourceString);
X XFree( resourceString );
X }
X}
X
X/*
X * eventUnmapNotify - an unreparented pane is going away
X */
Xstatic int
XeventUnmapNotify(dpy, pEvent, winInfo)
X Display *dpy;
X XEvent *pEvent;
X WinRoot *winInfo;
X{
X WinGeneric *wg;
X
X wg = WIGetInfo(pEvent->xunmap.window);
X if (wg != NULL) {
X StateWithdrawn(wg->core.client);
X }
X}
X
X/*
X * destroyRoot -- destroy the root window resources and free any allocated
X * data.
X */
Xstatic int
XdestroyRoot(dpy, winInfo)
X Display *dpy;
X WinRoot *winInfo;
X{
X /* delete the _SUN_WM_PROTOCOLS property */
X XDeleteProperty(dpy,winInfo->core.self,AtomSunWMProtocols);
X
X /* delete the WM_ICON_SIZE property */
X XDeleteProperty(dpy,winInfo->core.self,XA_WM_ICON_SIZE);
X
X /* free our data and throw away window */
X WIUninstallInfo(winInfo->core.self);
X MemFree(winInfo);
X}
X
X/*
X * writeProtocols - write the _SUN_WM_PROTOCOLS property on the root win,
X * which advertises the capabilities of the window manager.
X */
Xstatic void
XwriteProtocols(dpy,rootwin)
X Display *dpy;
X Window rootwin;
X{
X unsigned int data[10];
X int nitems = 0;
X
X /* conditionally support the _SUN_WINDOW_STATE protocol */
X if (DoingWindowState)
X data[nitems++] = AtomSunWindowState;
X
X /* support 5-word-long _OL_WIN_ATTR property */
X data[nitems++] = AtomSunOLWinAttr5;
X
X if (nitems == 0)
X return;
X
X XChangeProperty(dpy,rootwin,AtomSunWMProtocols,XA_ATOM,32,
X PropModeReplace,(unsigned char *)data,nitems);
X}
X
X/*
X * writeIconSize - write the WM_ICON_SIZE property on the root window.
X */
Xstatic void
XwriteIconSize(dpy,rootwin)
X Display *dpy;
X Window rootwin;
X{
X XIconSize iconSize;
X
X iconSize.min_width = ICON_MIN_WIDTH;
X iconSize.min_height = ICON_MIN_HEIGHT;
X iconSize.max_width = ICON_MAX_WIDTH;
X iconSize.max_height = ICON_MAX_HEIGHT;
X iconSize.width_inc = ICON_WIDTH_INC;
X iconSize.height_inc = ICON_HEIGHT_INC;
X
X XSetIconSizes(dpy,rootwin,&iconSize,1);
X}
X
X/***************************************************************************
X* global functions
X***************************************************************************/
X
X/*
X * MakeRoot -- create the root window. Return a WinGeneric structure.
X */
XWinRoot *
XMakeRoot(dpy, cli)
X Display *dpy;
X Client *cli;
X{
X XWindowAttributes attr;
X WinRoot *w;
X Window win;
X
X win = cli->scrInfo->rootid;
X
X /*
X * Tell the server we need to get mapping requests.
X * ErrorSensitive will force an exit if this fails
X * (ie another window manager is running).
X *
X * REMIND: instead of exiting, MakeRoot should probably just
X * return NULL, and callers to MakeRoot should check the return
X * value.
X */
X ErrorSensitive(
X gettext("Perhaps there is another window manager running?"));
X XSelectInput(dpy,win,
X KeyPressMask | SubstructureRedirectMask |
X ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
X EnterWindowMask | PropertyChangeMask | OwnerGrabButtonMask);
X XSync(dpy, False);
X ErrorInsensitive(dpy);
X
X if (XGetWindowAttributes(dpy, win, &attr) == 0) {
X ErrorGeneral(gettext("Could not get attributes of root window"));
X /*NOTREACHED*/
X }
X
X /* mark the client as olwm owned */
X cli->flags = CLOlwmOwned;
X
X /* create the associated structure */
X w = MemNew(WinRoot);
X w->core.self = win;
X w->class = &classRoot;
X w->core.kind = WIN_ROOT;
X w->core.parent = NULL;
X w->core.children = NULL;
X w->core.client = cli;
X w->core.x = 0;
X w->core.y = 0;
X w->core.width = attr.width;
X w->core.height = attr.height;
X w->core.dirtyconfig = False;
X w->core.colormap = cli->scrInfo->colormap;
X w->core.exposures = NULL;
X w->core.helpstring = "olwm:Workspace";
X w->currentAction = ACTION_NONE;
X
X /* Write properties on the root window */
X writeProtocols(dpy,win);
X writeIconSize(dpy,win);
X
X /* register the window */
X WIInstallInfo((WinGeneric *)w);
X
X return w;
X}
X
X/*
X * RootInit - init the WinRoot class function vector
X */
Xvoid
XRootInit(dpy)
XDisplay *dpy;
X{
X classRoot.core.kind = WIN_ROOT;
X classRoot.core.xevents[ConfigureRequest] = eventConfigureRequest;
X classRoot.core.xevents[EnterNotify] = eventEnterNotify;
X classRoot.core.xevents[MapRequest] = eventMapRequest;
X classRoot.core.xevents[MotionNotify] = eventMotionNotify;
X classRoot.core.xevents[ButtonRelease] = eventButtonRelease;
X classRoot.core.xevents[ButtonPress] = eventButtonPress;
X classRoot.core.xevents[KeyPress] = eventKeyPressRelease;
X classRoot.core.xevents[KeyRelease] = eventKeyPressRelease;
X classRoot.core.xevents[PropertyNotify] = eventPropertyNotify;
X classRoot.core.xevents[UnmapNotify] = eventUnmapNotify;
X classRoot.core.focusfunc = NULL;
X classRoot.core.drawfunc = NULL;
X classRoot.core.destroyfunc = destroyRoot;
X classRoot.core.selectfunc = NULL;
X classRoot.core.newconfigfunc = NULL;
X classRoot.core.newposfunc = NULL;
X classRoot.core.setconfigfunc = NULL;
X classRoot.core.createcallback = NULL;
X classRoot.core.heightfunc = NULL;
X classRoot.core.widthfunc = NULL;
X}
END_OF_FILE
if test 17999 -ne `wc -c <'winroot.c'`; then
echo shar: \"'winroot.c'\" unpacked with wrong size!
fi
# end of 'winroot.c'
fi
echo shar: End of archive 15 \(of 21\).
cp /dev/null ark15isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 21 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
--
Molecular Simulations, Inc. mail: dcmartin@postgres.berkeley.edu
796 N. Pastoria Avenue uucp: uwvax!ucbvax!dcmartin
Sunnyvale, California 94086 at&t: 408/522-9236