home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
x
/
volume15
/
olvwm-3.0
/
part02
< prev
next >
Wrap
Text File
|
1992-02-03
|
56KB
|
1,913 lines
Newsgroups: comp.sources.x
Path: uunet!usc!elroy.jpl.nasa.gov!ames!pasteur!nntp
From: scott.oaks@East.Sun.COM (Scott Oaks)
Subject: v15i148: OpenLook Virtual Window Mgr (3.0), Part02/21
Message-ID: <1992Feb4.135406.6724@pasteur.Berkeley.EDU>
Sender: dcmartin@msi.com (David C. Martin - Moderator)
Nntp-Posting-Host: postgres.berkeley.edu
Organization: University of California, at Berkeley
References: <csx-15i147-olvwm-3.0@uunet.UU.NET>
Date: Tue, 4 Feb 1992 13:54:06 GMT
Approved: dcmartin@msi.com
Submitted-by: scott.oaks@East.Sun.COM (Scott Oaks)
Posting-number: Volume 15, Issue 148
Archive-name: olvwm-3.0/part02
# 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 2 (of 21)."
# Contents: patchlevel.h virtual.c
# Wrapped by dcmartin@fascet on Tue Jan 14 05:54:41 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'patchlevel.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'patchlevel.h'\"
else
echo shar: Extracting \"'patchlevel.h'\" \(24 characters\)
sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
X#define PATCHLEVELv3 0
END_OF_FILE
if test 24 -ne `wc -c <'patchlevel.h'`; then
echo shar: \"'patchlevel.h'\" unpacked with wrong size!
fi
# end of 'patchlevel.h'
fi
if test -f 'virtual.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'virtual.c'\"
else
echo shar: Extracting \"'virtual.c'\" \(51849 characters\)
sed "s/^X//" >'virtual.c' <<'END_OF_FILE'
X/*
X * (c) Copyright 1991 Scott Oaks. See LEGAL_NOTICE file for terms of the
X * license
X */
X
X#include <stdio.h>
X#include <string.h>
X#include <dirent.h>
X#include <X11/Xos.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include <X11/keysym.h>
X#include <X11/keysymdef.h>
X#include <X11/Xatom.h>
X
X#include "i18n.h"
X#include "ollocale.h"
X#include "mem.h"
X#include "olwm.h"
X#include "st.h"
X#include "globals.h"
X#include "win.h"
X#include "menu.h"
X#include "math.h"
X#include "virtual.h"
X#include "patchlevel.h"
X
X#include "vdm.icon"
X#include "vdm.mask"
X
X/* Class Function Vector; a virtual pane is the VDM window in which all
X * the little virtual windows appear (and to which said windows are
X * parented)
X */
Xstatic ClassVirtualPane classVirtualPane;
X
X/*
X * Last select time in the VDM. This is technically different for each
X * VDM, but who can click in a VDM, move between screens, and then click
X * again?
X */
Xstatic int lastSelectTime;
X
Xextern List *ScreenInfoList;
X
Xextern Pixmap VirtualGetPixmap();
X
Xextern Button *MakeUpLeftButton(),*MakeLeftButton(),*MakeDownLeftButton(),
X *MakeUpButton(),*MakeHomeButton(),*MakeDownButton(),
X *MakeUpRightButton(),*MakeRightButton(),*MakeDownRightButton();
X
X/*
X * Semantic action associated with each of the buttons above. These must
X * be in the same order as the button array; it would be better if the Button
X * structure had an opaque entry for this purpose.
X */
X
Xstatic SemanticAction vdmButtonActions[] = {
X ACTION_UPLEFT,
X ACTION_LEFT,
X ACTION_DOWNLEFT,
X ACTION_UP,
X ACTION_HOME,
X ACTION_DOWN,
X ACTION_UPRIGHT,
X ACTION_RIGHT,
X ACTION_DOWNRIGHT,
X};
X
Xstatic char pixdata[] = { 0xaa, 0x55 };
X
X#define VDMSelectMask (ButtonPressMask | ButtonReleaseMask | \
X ButtonMotionMask | ExposureMask )
X
X/*
X * ==========================================================================
X *
X * VDM Utility/Drawing/Moving Functions
X *
X */
X
X/*
X * Draw the dotted lines on the VDM background
X */
Xstatic void
XdrawVDMGrid(dpy, vdm)
X Display *dpy;
X VirtualDesktop *vdm;
X
X{
Xint i;
XXPoint pts[5];
Xint dh = DisplayHeight(dpy, vdm->client->screen);
Xint dw = DisplayWidth(dpy, vdm->client->screen);
XScreenInfo *scrInfo = vdm->client->scrInfo;
X
X XClearArea(dpy, PANEWINOFCLIENT(vdm->client), 0, 0, 0, 0, 0);
X XSetForeground(dpy, scrInfo->gc[VDM_GC],
X scrInfo->colorInfo.virtualGridColor);
X if (vdm->resources->grid == GridVisible) {
X XSetLineAttributes(dpy, scrInfo->gc[VDM_GC], 0, LineOnOffDash,
X CapNotLast, JoinMiter);
X pts[0].y = 0;
X pts[1].y = vdm->height;
X for (i = dw; i < vdm->absoluteWidth; i += dw) {
X pts[0].x = pts[1].x = i / vdm->resources->scale;
X XDrawLines(dpy, PANEWINOFCLIENT(vdm->client), scrInfo->gc[VDM_GC],
X pts, 2, CoordModeOrigin);
X }
X pts[0].x = 0;
X pts[1].x = vdm->width;
X for (i = dh; i < vdm->absoluteHeight; i+= dh) {
X pts[0].y = pts[1].y = i / vdm->resources->scale;
X XDrawLines(dpy, PANEWINOFCLIENT(vdm->client), scrInfo->gc[VDM_GC],
X pts, 2, CoordModeOrigin);
X }
X XSetLineAttributes(dpy, scrInfo->gc[VDM_GC], 0,
X LineSolid, CapNotLast, JoinMiter);
X }
X pts[0].x = pts[4].x = -vdm->offsetX / vdm->resources->scale;
X pts[0].y = pts[4].y = -vdm->offsetY / vdm->resources->scale;
X pts[1].x = (dw - vdm->offsetX) / vdm->resources->scale;
X pts[1].y = pts[0].y;
X pts[2].x = pts[1].x;
X pts[2].y = (dh - vdm->offsetY) / vdm->resources->scale;
X pts[3].x = pts[0].x;
X pts[3].y = pts[2].y;
X XDrawLines(dpy, PANEWINOFCLIENT(vdm->client), scrInfo->gc[VDM_GC],
X pts, 5, CoordModeOrigin);
X XSetForeground(dpy, scrInfo->gc[VDM_GC], scrInfo->colorInfo.virtualFontColor);
X}
X
X/*
X * Function for re-placing (not replacing!) all windows when the view into
X * the desktop is changed
X */
Xtypedef struct _replacestickyinfo {
X struct deltas *deltas;
X int screen;
X} replaceStickyInfo;
X
Xstatic void *
XreplaceSticky(cli, c)
X Client *cli;
X replaceStickyInfo *c;
X
X{
XWinGenericFrame *win;
X
X if (cli->screen != c->screen)
X return NULL;
X if (cli && !cli->sticky) {
X win = (WinGenericFrame *) cli->framewin;
X if (win)
X GFrameSetConfig(win, (int) (win->core.x - c->deltas->delta_x),
X (int) (win->core.y - c->deltas->delta_y),
X win->core.width, win->core.height);
X win = (WinGenericFrame *) cli->iconwin;
X if (win)
X GFrameSetConfig(win, (int) (win->core.x - c->deltas->delta_x),
X (int) (win->core.y - c->deltas->delta_y),
X win->core.width, win->core.height);
X }
X else if (cli) {
X /*
X * client is sticky; its real window stays where it is but its
X * virtual window must move
X */
X if (cli->framewin)
X XMoveWindow(cli->dpy, cli->framewin->core.virtual,
X (cli->framewin->core.x) / cli->scrInfo->vdm->resources->scale +
X cli->scrInfo->vdm->screenX,
X (cli->framewin->core.y) / cli->scrInfo->vdm->resources->scale +
X cli->scrInfo->vdm->screenY);
X if (cli->iconwin)
X XMoveWindow(cli->dpy, cli->iconwin->core.virtual,
X (cli->iconwin->core.x) / cli->scrInfo->vdm->resources->scale +
X cli->scrInfo->vdm->screenX,
X (cli->iconwin->core.y) / cli->scrInfo->vdm->resources->scale +
X cli->scrInfo->vdm->screenY);
X }
X return NULL;
X}
X
Xstatic void
XmoveDesktop(dpy, deltas, vdm)
X Display *dpy;
X struct deltas *deltas;
X VirtualDesktop *vdm;
X{
Xextern List *ActiveClientList;
XreplaceStickyInfo info;
X
X vdm->offsetX -= deltas->delta_x;
X vdm->offsetY -= deltas->delta_y;
X vdm->screenX = -vdm->offsetX / vdm->resources->scale;
X vdm->screenY = -vdm->offsetY / vdm->resources->scale;
X info.screen = vdm->client->screen;
X info.deltas = deltas;
X ListApply(ActiveClientList, replaceSticky, &info);
X drawVDMGrid(dpy, vdm);
X}
X
X/*
X * Make sure the given deltas don't move off the screen
X */
Xstatic void
XconstrainDeltas(dpy, vdm, deltas)
X Display *dpy;
X VirtualDesktop *vdm;
X struct deltas *deltas;
X{
Xint dw = DisplayWidth(dpy, vdm->client->screen);
Xint dh = DisplayHeight(dpy, vdm->client->screen);
X
X if (vdm->offsetX - deltas->delta_x < dw - vdm->absoluteWidth)
X deltas->delta_x = vdm->offsetX + vdm->absoluteWidth - dw;
X else if (vdm->offsetX - deltas->delta_x > 0)
X deltas->delta_x = vdm->offsetX;
X
X if (vdm->offsetY - deltas->delta_y < dh - vdm->absoluteHeight)
X deltas->delta_y = vdm->offsetY + vdm->absoluteHeight - dh;
X else if (vdm->offsetY - deltas->delta_y > 0)
X deltas->delta_y = vdm->offsetY;
X}
X
Xstatic Bool
XvdmPerformAction(dpy, vdm, a)
X Display *dpy;
X VirtualDesktop *vdm;
X SemanticAction a;
X
X{
Xstruct deltas deltas;
Xint dh = DisplayHeight(dpy, vdm->client->screen);
Xint dw = DisplayWidth(dpy, vdm->client->screen);
X
X deltas.delta_x = deltas.delta_y = 0;
X switch(a) {
X case ACTION_UP:
X deltas.delta_y = -dh;
X break;
X case ACTION_JUMP_UP:
X deltas.delta_y = -dh * 20;
X break;
X case ACTION_HALF_UP:
X deltas.delta_y = -dh * .5;
X break;
X case ACTION_DOWN:
X deltas.delta_y = dh;
X break;
X case ACTION_JUMP_DOWN:
X deltas.delta_y = dh * 20;
X break;
X case ACTION_HALF_DOWN:
X deltas.delta_y = dh * .5;
X break;
X case ACTION_LEFT:
X deltas.delta_x = -dw;
X break;
X case ACTION_JUMP_LEFT:
X deltas.delta_x = -dw * 20;
X break;
X case ACTION_HALF_LEFT:
X deltas.delta_x = -dw * .5;
X break;
X case ACTION_RIGHT:
X deltas.delta_x = dw;
X break;
X case ACTION_JUMP_RIGHT:
X deltas.delta_x = dw * 20;
X break;
X case ACTION_HALF_RIGHT:
X deltas.delta_x = dw * .5;
X break;
X case ACTION_UPLEFT:
X case ACTION_ROW_START:
X deltas.delta_x = -dw;
X deltas.delta_y = -dh;
X break;
X case ACTION_JUMP_UPLEFT:
X deltas.delta_x = -dw * 20;
X deltas.delta_y = -dh * 20;
X break;
X case ACTION_HALF_UPLEFT:
X case ACTION_DATA_START:
X deltas.delta_x = -dw * .5;
X deltas.delta_y = -dh * .5;
X break;
X case ACTION_UPRIGHT:
X deltas.delta_x = dw;
X deltas.delta_y = -dh;
X break;
X case ACTION_JUMP_UPRIGHT:
X deltas.delta_x = dw * 20;
X deltas.delta_y = -dh * 20;
X break;
X case ACTION_HALF_UPRIGHT:
X deltas.delta_x = dw * .5;
X deltas.delta_y = -dh * .5;
X break;
X case ACTION_HOME:
X deltas.delta_x = vdm->offsetX;
X deltas.delta_y = vdm->offsetY;
X break;
X case ACTION_DOWNLEFT:
X case ACTION_ROW_END:
X deltas.delta_x = -dw;
X deltas.delta_y = dh;
X break;
X case ACTION_JUMP_DOWNLEFT:
X deltas.delta_x = -dw * 20;
X deltas.delta_y = dh * 20;
X break;
X case ACTION_HALF_DOWNLEFT:
X case ACTION_DATA_END:
X deltas.delta_x = -dw * .5;
X deltas.delta_y = dh * .5;
X break;
X case ACTION_DOWNRIGHT:
X deltas.delta_x = dw;
X deltas.delta_y = dh;
X break;
X case ACTION_JUMP_DOWNRIGHT:
X deltas.delta_x = dw * 20;
X deltas.delta_y = dh * 20;
X break;
X case ACTION_HALF_DOWNRIGHT:
X deltas.delta_x = dw * .5;
X deltas.delta_y = dh * .5;
X break;
X case ACTION_GOTO_1:
X case ACTION_GOTO_2:
X case ACTION_GOTO_3:
X case ACTION_GOTO_4:
X case ACTION_GOTO_5:
X case ACTION_GOTO_6:
X case ACTION_GOTO_7:
X case ACTION_GOTO_8:
X case ACTION_GOTO_9:
X case ACTION_GOTO_10:
X deltas.delta_x = vdm->offsetX +
X ((a - ACTION_GOTO_1) % vdm->columns) * dw;
X deltas.delta_y = vdm->offsetY +
X ((a - ACTION_GOTO_1) / vdm->columns) * dh;
X break;
X default:
X return False;
X }
X constrainDeltas(dpy, vdm, &deltas);
X
X if (fabs(deltas.delta_x) < 0.1 && fabs(deltas.delta_y) < 0.1)
X return False;
X moveDesktop(dpy, &deltas, vdm);
X return True;
X}
X
X/*
X * Given root and logical coordinates relative to the VDM, turn them into
X * absolute screen coordinates
X */
Xstatic void
XtranslateVirtualCoords(vdm, root_x, root_y, x, y)
X VirtualDesktop *vdm;
X int *root_x, *root_y, *x, *y;
X
X{
Xint tx, ty, tw, th, bw, d;
XWindow root;
X
X if (x)
X *x *= vdm->resources->scale;
X if (y)
X *y *= vdm->resources->scale;
X if (!root_x || !root_y)
X return;
X XGetGeometry(vdm->client->dpy, vdm->client->framewin->core.self,
X &root, &tx, &ty, &tw, &th, &bw, &d);
X *root_x -= tx;
X *root_y -= ty;
X XGetGeometry(vdm->client->dpy,
X vdm->client->framewin->fcore.panewin->core.self,
X &root, &tx, &ty, &tw, &th, &bw, &d);
X *root_x -= tx;
X *root_y -= ty;
X *root_x *= vdm->resources->scale;
X *root_x += vdm->offsetX;
X *root_y *= vdm->resources->scale;
X *root_y += vdm->offsetY;
X}
X
Xvoid
XcalculateVirtualDesktopSize(dpy, screen, v)
X Display *dpy;
X int screen;
X VirtualDesktop *v;
X
X{
X int width, height;
X int dw = DisplayWidth(dpy, screen);
X int dh = DisplayHeight(dpy, screen);
X
X sscanf(v->resources->size, "%dx%d", &width, &height);
X if (width < dw)
X v->columns = width;
X else v->columns = ceil((double) width / dw);
X if (height < dh)
X v->rows = height;
X else v->rows = ceil((double) height / dh);
X
X v->absoluteWidth = v->columns * dw;
X v->absoluteHeight = v->rows * dh;
X
X v->screenWidth = dw / v->resources->scale;
X v->screenHeight = dh / v->resources->scale;
X if (v->resources->grid) {
X v->width = v->columns * v->screenWidth;
X v->height = v->rows * v->screenHeight;
X }
X else {
X v->width = v->absoluteWidth / v->resources->scale;
X v->height = v->absoluteHeight / v->resources->scale;
X }
X}
X
X/*
X * Allocate a virtual desktop for the given screen.
X * See virtual.h for a definition of all the fields in the returned structure.
X *
X * This doesn't deal with the window stuff, just with the fields. The
X * window is actually created and the colors set etc. below in MakeVDM
X *
X */
X
Xstatic VirtualDesktop *
XallocVirtualDesktop(dpy, screen, rsc)
X Display *dpy;
X int screen;
X VirtualResources *rsc;
X
X{
X VirtualDesktop *v;
X
X v = (VirtualDesktop *) MemAlloc(sizeof(VirtualDesktop));
X v->resources = rsc;
X v->offsetX = 0;
X v->offsetY = 0;
X v->screenX = 0;
X v->screenY = 0;
X calculateVirtualDesktopSize(dpy, screen, v);
X return v;
X}
X
Xstatic void
XconstrainOutline(dpy, stuff, x, y, snap)
X Display *dpy;
X VDMstuff *stuff;
X int x, y, snap;
X{
Xint dw = DisplayWidth(dpy, stuff->vdm->client->screen);
Xint dh = DisplayHeight(dpy, stuff->vdm->client->screen);
X
X if (snap) {
X stuff->vdm->screenX = (((x * stuff->vdm->resources->scale) / dw) * dw) /
X stuff->vdm->resources->scale;
X stuff->vdm->screenY = (((y * stuff->vdm->resources->scale) / dh) * dh) /
X stuff->vdm->resources->scale;
X }
X else {
X stuff->vdm->screenX = x - stuff->pointerX + stuff->initX;
X stuff->vdm->screenY = y - stuff->pointerY + stuff->initY;
X }
X
X if (stuff->vdm->screenX < 0)
X stuff->vdm->screenX = 0;
X else if (stuff->vdm->screenX + stuff->vdm->screenWidth >
X stuff->vdm->width + stuff->vdm->resources->scale)
X stuff->vdm->screenX = (stuff->vdm->absoluteWidth - dw) /
X stuff->vdm->resources->scale;
X
X if (stuff->vdm->screenY < 0)
X stuff->vdm->screenY = 0;
X else if (stuff->vdm->screenY + stuff->vdm->screenHeight >
X stuff->vdm->height + stuff->vdm->resources->scale)
X stuff->vdm->screenY = (stuff->vdm->absoluteHeight - dh) /
X stuff->vdm->resources->scale;
X}
X
X/*
X * ==========================================================================
X * Interposition functions for mouse dragging
X */
X
Xstatic
XvdmMoveUpdate(ev, stuff)
X XEvent *ev;
X VDMstuff *stuff;
X{
X XDrawRectangle(stuff->vdm->client->dpy, PANEWINOFCLIENT(stuff->vdm->client),
X stuff->gc, stuff->vdm->screenX, stuff->vdm->screenY,
X stuff->vdm->screenWidth + 1, stuff->vdm->screenHeight);
X constrainOutline(stuff->vdm->client->dpy, stuff,
X ev->xmotion.x, ev->xmotion.y,
X (stuff->vdm->resources->grid) ?
X !(ev->xbutton.state & ControlMask) :
X (ev->xbutton.state & ControlMask));
X XDrawRectangle(stuff->vdm->client->dpy, PANEWINOFCLIENT(stuff->vdm->client),
X stuff->gc, stuff->vdm->screenX, stuff->vdm->screenY,
X stuff->vdm->screenWidth + 1, stuff->vdm->screenHeight);
X stuff->numMoves++;
X}
X
Xstatic
XvdmMoveDone(ev, stuff)
X XEvent *ev;
X VDMstuff *stuff;
X{
Xstruct deltas deltas;
Xint dw = DisplayWidth(stuff->vdm->client->dpy,
X stuff->vdm->client->screen);
Xint dh = DisplayHeight(stuff->vdm->client->dpy,
X stuff->vdm->client->screen);
X
X UninstallInterposer();
X XDrawRectangle(stuff->vdm->client->dpy, PANEWINOFCLIENT(stuff->vdm->client),
X stuff->gc, stuff->vdm->screenX, stuff->vdm->screenY,
X stuff->vdm->screenWidth + 1, stuff->vdm->screenHeight);
X if (ev->xbutton.time - lastSelectTime <= GRV.DoubleClickTime) {
X translateVirtualCoords(stuff->vdm,
X &ev->xbutton.x_root, &ev->xbutton.y_root,
X &ev->xbutton.x, &ev->xbutton.y);
X VDMMoveTo(stuff->vdm->client->dpy, stuff->vdm->client,
X ev->xbutton.x_root, ev->xbutton.y_root);
X return;
X }
X lastSelectTime = ev->xbutton.time;
X if (!stuff->numMoves)
X return;
X constrainOutline(stuff->vdm->client->dpy, stuff,
X ev->xmotion.x, ev->xmotion.y,
X (stuff->vdm->resources->grid) ?
X !(ev->xbutton.state & ControlMask) :
X (ev->xbutton.state & ControlMask));
X drawVDMGrid(stuff->vdm->client->dpy, stuff->vdm);
X deltas.delta_x = (stuff->vdm->screenX - stuff->initX) *
X stuff->vdm->resources->scale + stuff->vdm->resources->scale;
X deltas.delta_y = (stuff->vdm->screenY - stuff->initY) *
X stuff->vdm->resources->scale + stuff->vdm->resources->scale;
X if ((stuff->vdm->resources->grid && !(ev->xbutton.state & ControlMask)) ||
X (!stuff->vdm->resources->grid && (ev->xbutton.state & ControlMask))) {
X deltas.delta_x =
X (((int) (deltas.delta_x - stuff->vdm->offsetX) / dw) * dw) +
X stuff->vdm->offsetX;
X deltas.delta_y =
X (((int) (deltas.delta_y - stuff->vdm->offsetY) / dh) * dh) +
X stuff->vdm->offsetY;
X }
X moveDesktop(stuff->vdm->client->dpy, &deltas, stuff->vdm);
X}
X
Xstatic Bool
XvdmInterposer(dpy, event, w, stuff)
X Display *dpy;
X XEvent *event;
X WinGeneric *w;
X VDMstuff *stuff;
X{
XXEvent nextevent;
XSemanticAction action;
X
X switch(event->type) {
X case ButtonRelease:
X if (AllButtonsUp(event)) {
X vdmMoveDone(event, stuff);
X }
X break;
X case MotionNotify:
X if (!event->xmotion.same_screen)
X break;
X if (XEventsQueued(dpy, QueuedAfterReading) > 0 &&
X XPeekEvent(dpy, &nextevent), nextevent.type == MotionNotify)
X /* Ignore this event, there's another one coming */
X break;
X vdmMoveUpdate(event, stuff);
X break;
X case Expose:
X return DISPOSE_DISPATCH;
X case KeyPress:
X action = FindKeyboardAction(dpy, event);
X if (action == ACTION_STOP) {
X event->xany.type = ButtonRelease;
X event->xbutton.time = 0;
X stuff->numMoves = 0;
X vdmMoveDone(event, stuff);
X }
X else return DISPOSE_DEFER;
X break;
X default:
X return DISPOSE_DEFER;
X }
X return DISPOSE_USED;
X}
X
X/*
X * ===========================================================================
X *
X * Event functions for the VDM
X */
Xstatic
XvdmExpose(dpy, event, winInfo)
X Display *dpy;
X XEvent *event;
X WinGeneric *winInfo;
X{
XXEvent dummy;
X
X if (event->xexpose.count)
X return;
X drawVDMGrid(dpy, winInfo->core.client->scrInfo->vdm);
X while (XCheckTypedWindowEvent(dpy, event->xany.window, Expose, &dummy))
X ; /* empty */
X}
X
Xstatic
XvdmKeyPress(dpy, ev, winInfo)
X Display *dpy;
X XEvent *ev;
X WinGeneric *winInfo;
X{
X if (!KeyMoveVDM(dpy, ev))
X if (GRV.Beep == BeepAlways)
X NoFocusEventBeep(dpy, ev, winInfo);
X}
X
Xstatic
XvdmConfigure(dpy, event, winInfo)
X Display *dpy;
X XConfigureEvent *event;
X WinVirtual *winInfo;
X{
XVirtualDesktop *vdm;
Xint dw, dh;
XBool doit;
Xstruct deltas deltas;
X
X vdm = winInfo->core.client->scrInfo->vdm;
X dw = DisplayWidth(dpy, winInfo->core.client->screen);
X dh = DisplayHeight(dpy, winInfo->core.client->screen);
X vdm->width = event->width;
X vdm->height = event->height;
X if (vdm->resources->grid) {
X vdm->absoluteHeight = (vdm->height - 3) * vdm->resources->scale;
X vdm->absoluteHeight = ((vdm->absoluteHeight - 1) / dh + 1) * dh;
X vdm->absoluteWidth = (vdm->width - 3) * vdm->resources->scale;
X vdm->absoluteWidth = ((vdm->absoluteWidth - 1) / dw + 1) * dw;
X vdm->rows = ceil((double) vdm->absoluteHeight / dh);
X vdm->columns = ceil((double) vdm->absoluteWidth / dw);
X }
X else {
X vdm->absoluteHeight = vdm->height * vdm->resources->scale;
X vdm->absoluteWidth = vdm->width * vdm->resources->scale;
X vdm->rows = ceil((double) vdm->absoluteHeight / dh);
X vdm->columns = ceil((double) vdm->absoluteWidth / dw);
X }
X doit = False;
X deltas.delta_x = deltas.delta_y = 0;
X if (vdm->screenX + vdm->screenWidth > vdm->width) {
X doit = True;
X deltas.delta_x = (vdm->width - vdm->screenWidth - vdm->screenX) *
X vdm->resources->scale;
X }
X if (vdm->screenY + vdm->screenHeight > vdm->height) {
X doit = True;
X deltas.delta_y = (vdm->height - vdm->screenHeight - vdm->screenY) *
X vdm->resources->scale;
X }
X if (doit) {
X if (deltas.delta_x < 0)
X deltas.delta_x = ((int) (deltas.delta_x - vdm->resources->scale) / dw) * dw;
X else deltas.delta_x = ((int) (deltas.delta_x + vdm->resources->scale) / dw) * dw;
X if (deltas.delta_y < 0)
X deltas.delta_y = ((int) (deltas.delta_y - vdm->resources->scale) / dh) * dh;
X else deltas.delta_y = ((int) (deltas.delta_y + vdm->resources->scale) / dh) * dh;
X moveDesktop(dpy, &deltas, vdm);
X }
X}
X
Xstatic
XvdmNewConfigure(winInfo, pxcre)
X WinVirtual *winInfo;
X XConfigureRequestEvent *pxcre;
X{
Xint oldWidth, oldHeight, oldX, oldY;
XClient *cli = winInfo->core.client;
XWinPaneFrame *winFrame = cli->framewin;
X
X if (!pxcre)
X return winInfo->core.dirtyconfig;
X WinRootPos(winInfo, &oldX, &oldY);
X oldWidth = winInfo->core.width;
X oldHeight = winInfo->core.height;
X
X if ((pxcre->value_mask & CWHeight) && (pxcre->height != oldHeight)) {
X winInfo->core.height = pxcre->height;
X winInfo->core.dirtyconfig |= CWHeight;
X }
X if ((pxcre->value_mask & CWWidth) && (pxcre->width != oldWidth)) {
X winInfo->core.width = pxcre->width;
X winInfo->core.dirtyconfig |= CWWidth;
X }
X /*if (pxcre->value_mask & CWBorderWidth)
X winFrame->pcore.oldBorderWidth = pxcre->border_width;*/
X if (pxcre->value_mask & (CWX|CWY))
X FrameSetPosAbsolute(winFrame,
X (pxcre->value_mask & CWX) ? (pxcre->x) : oldX,
X (pxcre->value_mask & CWY) ? (pxcre->y) : oldY);
X if (pxcre->value_mask & (CWStackMode | CWSibling))
X GFrameSetStack(winFrame, pxcre->value_mask, pxcre->detail, pxcre->above);
X return winInfo->core.dirtyconfig;
X}
X
Xstatic
XvdmButtonPress(dpy, event, winInfo)
X Display *dpy;
X XEvent *event;
X WinGeneric *winInfo;
X{
Xstatic VDMstuff stuff;
XSemanticAction a;
XScreenInfo *scrInfo = winInfo->core.client->scrInfo;
X
X a = ResolveMouseBinding(dpy, event, ModMaskMap[MOD_CONSTRAIN] |
X ModMaskMap[MOD_INVERT] |
X ModMaskMap[MOD_REDUCE]);
X switch(a) {
X case ACTION_SELECT:
X stuff.vdm = scrInfo->vdm;
X stuff.pointerX = event->xbutton.x;
X stuff.pointerY = event->xbutton.y;
X stuff.gc = scrInfo->gc[ROOT_GC];
X stuff.initX = scrInfo->vdm->screenX;
X stuff.initY = scrInfo->vdm->screenY;
X stuff.numMoves = 0;
X XDrawRectangle(stuff.vdm->client->dpy,
X PANEWINOFCLIENT(stuff.vdm->client),
X stuff.gc, stuff.vdm->screenX, stuff.vdm->screenY,
X stuff.vdm->screenWidth + 1, stuff.vdm->screenHeight);
X InstallInterposer(vdmInterposer, &stuff);
X break;
X case ACTION_MENU:
X MenuShowSync(dpy, winInfo, scrInfo->menuTable[MENU_VDM],
X event, NULL, NULL, False, False);
X break;
X }
X}
X
Xstatic
XvdmRedraw(dpy, win)
X Display *dpy;
X WinGeneric *win;
X{
X drawVDMGrid(win->core.client->dpy, win->core.client->scrInfo->vdm);
X}
X
Xstatic
XvdmExit()
X{
X fprintf(stderr, "VDM destroy\n");
X}
X
Xstatic
XvdmButtonRelease()
X{
X/*
X * Need this for middle button presses
X */
X}
X
Xstatic
XvdmSetConfigure(dpy, winInfo)
X Display *dpy;
X WinVirtual *winInfo;
X{
XXConfigureEvent ce;
XXWindowChanges xwc;
X
X if (winInfo->core.dirtyconfig) {
X xwc.x = winInfo->core.x;
X xwc.y = winInfo->core.y;
X xwc.width = winInfo->core.width;
X xwc.height = winInfo->core.height;
X ConfigureWindow(dpy, winInfo,
X winInfo->core.dirtyconfig, &xwc);
X winInfo->core.dirtyconfig &= ~(CWX|CWY|CWWidth|CWHeight);
X }
X ce.type = ConfigureNotify;
X ce.serial = 0L;
X ce.event = winInfo->core.self;
X ce.window = winInfo->core.self;
X WinRootPos(winInfo, &ce.x, &ce.y);
X ce.width = winInfo->core.width;
X ce.height = winInfo->core.height;
X ce.border_width = 0;
X ce.above = None;
X ce.override_redirect = False;
X /*
X * Elsewhere, we send a configure event to the client, but since the
X * client is us, let's just call that function directly . . .
X */
X vdmConfigure(dpy, &ce, winInfo);
X}
X
Xstatic
XvdmButtonMotion()
X{
X/*
X * Need this for middle button presses
X */
X}
X
Xstatic vdmNewpos(win, x, y)
X WinVirtual *win;
X int x, y;
X{
X if (win->core.x != x) {
X win->core.x = x;
X win->core.dirtyconfig |= CWX;
X }
X if (win->core.y != y) {
X win->core.y = y;
X win->core.dirtyconfig |= CWY;
X }
X return win->core.dirtyconfig;
X}
X
Xstatic vdmSelect()
X{
X}
X
Xstatic
XwinIntNullFunc()
X{
X fprintf(stderr, "WinIntNULL!\n");
X}
X
X
X/*
X * setsizePane - set the pane to a particular size, and initiate a reconfigure
X */
Xstatic int
XvdmSetSize(win,w,h)
XWinVirtual *win;
Xint w, h;
X{
X if (win->core.width != w) {
X win->core.width = w;
X win->core.dirtyconfig |= CWWidth;
X }
X
X if (win->core.height != h) {
X win->core.height = h;
X win->core.dirtyconfig |= CWHeight;
X }
X}
X
X/*
X * Callback function when VDM frame is mapped
X */
Xstatic
XvdmSetupFrame(win, cli, frame)
X WinGeneric *win;
X Client *cli;
X WinGenericFrame *frame;
X{
X frame->fcore.panewin = (WinGenericPane *) win;
X cli->scrInfo->vdm->client = cli;
X cli->sticky = True;
X cli->flags |= CLOlwmOwned;
X win->core.parent = (WinGeneric *) frame;
X WinAddChild(frame, win);
X XReparentWindow(cli->dpy, win->core.self, frame->core.self,
X win->core.x, win->core.y);
X cli->wmHints->icon_pixmap = XCreateBitmapFromData(cli->dpy,
X RootWindow(cli->dpy, cli->screen), vdm_bits,
X vdm_width, vdm_height);
X cli->wmHints->icon_mask = XCreateBitmapFromData(cli->dpy,
X RootWindow(cli->dpy, cli->screen), vdmmask_bits,
X vdmmask_width, vdmmask_height);
X}
X
Xstatic
XvdmComputeWidth(dpy, event, winInfo)
X Display *dpy;
X XEvent *event;
X WinGeneric *winInfo;
X{
X}
X
Xstatic
XvdmComputeHeight(dpy, event, winInfo)
X Display *dpy;
X XEvent *event;
X WinGeneric *winInfo;
X{
X}
X
X/*
X * =======================================================================
X * VDM Service Functions
X */
X
XRedrawVDM(vdm)
X VirtualDesktop *vdm;
X{
X drawVDMGrid(vdm->client->dpy, vdm);
X}
X
XVirtualInit(dpy)
X Display *dpy;
X
X{
X classVirtualPane.core.kind = WIN_VIRTUAL;
X classVirtualPane.core.xevents[KeyPress] = vdmKeyPress;
X classVirtualPane.core.xevents[ButtonPress] = vdmButtonPress;
X classVirtualPane.core.xevents[ButtonRelease] = vdmButtonRelease;
X classVirtualPane.core.xevents[MotionNotify] = vdmButtonMotion;
X classVirtualPane.core.xevents[ConfigureNotify] = vdmConfigure;
X classVirtualPane.core.xevents[Expose] = vdmExpose;
X classVirtualPane.core.focusfunc = NULL;
X classVirtualPane.core.drawfunc = vdmRedraw;
X classVirtualPane.core.destroyfunc = vdmExit;
X classVirtualPane.core.selectfunc = vdmSelect;
X classVirtualPane.core.newconfigfunc = vdmNewConfigure;
X classVirtualPane.core.newposfunc = vdmNewpos;
X classVirtualPane.core.setconfigfunc = vdmSetConfigure;
X classVirtualPane.core.createcallback = vdmSetupFrame;
X classVirtualPane.core.heightfunc = vdmComputeHeight;
X classVirtualPane.core.widthfunc = vdmComputeWidth;
X classVirtualPane.pcore.setsizefunc = vdmSetSize;
X}
X
X/*
X * Create an instance of the VDM -- this creates the logical virtual desktop
X * and then creates the VDM representation of it.
X */
X
XMakeVDM(dpy, scrInfo, client, rsc)
X Display *dpy;
X ScreenInfo *scrInfo;
X Client *client;
X VirtualResources *rsc;
X
X{
Xstatic XTextProperty wName = {(unsigned char *) "Virtual Desktop",
X XA_STRING, 8, 15 };
Xstatic XTextProperty iName = {(unsigned char *) "Desktop",
X XA_STRING, 8, 7 };
X XSetWindowAttributes attr;
X XSizeHints *sizeHints;
X XWMHints *wmHints;
X XClassHint *classHints;
X unsigned attrMask;
X int win;
X WinVirtual *w;
X VirtualDesktop *v;
X char title[20];
X Button *vdmButtons[9];
X
X v = allocVirtualDesktop(dpy, scrInfo->screen, rsc);
X w = MemNew(WinVirtual);
X
X sizeHints = XAllocSizeHints();
X sizeHints->flags = PBaseSize;
X sizeHints->base_width = v->width;
X sizeHints->base_height = v->height;
X sizeHints->min_width = v->screenWidth;
X sizeHints->min_height = v->screenHeight;
X if (rsc->grid) {
X sizeHints->flags = PMinSize | PResizeInc;
X sizeHints->width_inc = v->screenWidth;
X sizeHints->height_inc = v->screenHeight;
X }
X else sizeHints->flags = PMinSize;
X
X /* REMIND Add an icon file attrbute */
X wmHints = XAllocWMHints();
X if (GRV.VirtualIconic)
X wmHints->initial_state = IconicState;
X else wmHints->initial_state = NormalState;
X wmHints->flags = StateHint | InputHint | IconWindowHint;
X wmHints->input = False;
X
X wmHints->icon_window = XCreateSimpleWindow(dpy,
X RootWindow(dpy, scrInfo->screen),
X 0, 0, vdm_width, vdm_height, 0, 0,
X scrInfo->colorInfo.workspaceRootPixel);
X
X classHints = XAllocClassHint();
X classHints->res_name = "virtualDesktop";
X classHints->res_class = "olvwm";
X
X attrMask = CWEventMask;
X
X if (DefaultDepth(dpy, scrInfo->screen) == 1) {
X attrMask |= CWBackPixmap;
X attr.background_pixmap = XCreatePixmapFromBitmapData(dpy,
X RootWindow(dpy, scrInfo->screen),
X pixdata, 8, 2,
X scrInfo->colorInfo.fgColor, scrInfo->colorInfo.bgColor,
X 1);
X }
X else if (!rsc->background) {
X attrMask |= CWBackPixel;
X attr.background_pixel = scrInfo->colorInfo.virtualBgColor;
X }
X else {
X attrMask |= CWBackPixmap;
X attr.background_pixmap = VirtualGetPixmap(dpy, scrInfo, rsc->background);
X }
X attr.event_mask = ExposureMask | ButtonPressMask | ButtonReleaseMask |
X ButtonMotionMask | KeyPressMask;
X
X w->class = &classVirtualPane;
X w->core.kind = WIN_VIRTUAL;
X w->core.children = NULL;
X w->core.client = client;
X w->core.x = sizeHints->x;
X w->core.y = sizeHints->y;
X w->core.width = sizeHints->base_width;
X w->core.height = sizeHints->base_height;
X w->core.dirtyconfig = CWX | CWY | CWWidth | CWHeight;
X w->core.exposures = NULL;
X w->core.helpstring = "olvwm:VDM";
X w->core.colormap = NULL; /* initialized in callback */
X
X w->core.self = XCreateWindow(dpy, RootWindow(dpy, scrInfo->screen),
X sizeHints->x, sizeHints->y,
X sizeHints->base_width, sizeHints->base_height,
X 0,
X /* REMIND olwm visual affects this? */
X DefaultDepth(dpy, scrInfo->screen), InputOutput,
X CopyFromParent, attrMask, &attr);
X XSetWMProperties(dpy, w->core.self, &wName, &iName, NULL, 0,
X sizeHints, wmHints, classHints);
X
X WIInstallInfo((WinGeneric *)w);
X scrInfo->vdm = v;
X v->client = StateNew(dpy, RootWindow(dpy, scrInfo->screen), w->core.self, False, w);
X /*
X * Sigh -- the call back was called before the icon frame was created
X * so we can't do this there like we'd like to. And it was called
X * after StateNew processes the wmHints . . .
X */
X ((WinIconPane *) v->client->iconwin->fcore.panewin)->iconPixmap =
X v->client->wmHints->icon_pixmap;
X ((WinIconPane *) v->client->iconwin->fcore.panewin)->iconMask =
X v->client->wmHints->icon_mask;
X VirtualSetGeometry(v->client->framewin,
X v->client->scrInfo->vdm->resources->geometry);
X VirtualSetGeometry(v->client->iconwin,
X v->client->scrInfo->vdm->resources->iconGeometry);
X
X /*
X * Make the VDMs menu
X */
X sprintf(title, "OLVWM 3.%0d", PATCHLEVELv3);
X vdmButtons[0] = MakeUpLeftButton(dpy, scrInfo);
X vdmButtons[1] = MakeLeftButton(dpy, scrInfo);
X vdmButtons[2] = MakeDownLeftButton(dpy, scrInfo);
X vdmButtons[3] = MakeUpButton(dpy, scrInfo);
X vdmButtons[4] = MakeHomeButton(dpy, scrInfo);
X vdmButtons[5] = MakeDownButton(dpy, scrInfo);
X vdmButtons[6] = MakeUpRightButton(dpy, scrInfo);
X vdmButtons[7] = MakeRightButton(dpy, scrInfo);
X vdmButtons[8] = MakeDownRightButton(dpy, scrInfo);
X scrInfo->menuTable[MENU_VDM] = CreateMenu(strdup(title), vdmButtons,
X sizeof(vdmButtons)/sizeof(vdmButtons[0]),
X True, "olvwm:MotionMenu");
X scrInfo->menuTable[MENU_VDM]->prefColSize = 3;
X scrInfo->menuTable[MENU_VDM]->buttonDefault = 4;
X (void) MenuInfoCreate(scrInfo->menuCache, scrInfo->rootwin,
X scrInfo->menuTable[MENU_VDM], 1);
X
X XFree(sizeHints);
X XFree(wmHints);
X XFree(classHints);
X}
X
X/*
X * Create the virtual representation of the client's frame and icon
X */
XMakeVirtual(cli)
X Client *cli;
X
X{
Xint width, height;
Xint x, y;
XWindow virtual;
X
X /*
X * Subtract 1 for those window borders
X */
X width = cli->framewin->core.width / cli->scrInfo->vdm->resources->scale - 1;
X height = cli->framewin->core.height / cli->scrInfo->vdm->resources->scale-1;
X
X x = cli->framewin->core.x / cli->scrInfo->vdm->resources->scale +
X cli->scrInfo->vdm->screenX;
X y = cli->framewin->core.y / cli->scrInfo->vdm->resources->scale +
X cli->scrInfo->vdm->screenY;
X
X if (width <= 0)
X width = 1;
X if (height <= 0)
X height = 1;
X virtual = XCreateSimpleWindow(cli->dpy,
X PANEWINOFCLIENT(cli->scrInfo->vdm->client),
X x, y, width, height, 1, cli->scrInfo->colorInfo.borderColor,
X cli->scrInfo->colorInfo.virtualFgColor);
X if (PANEWINOFCLIENT(cli) != PANEWINOFCLIENT(cli->scrInfo->vdm->client))
X XSelectInput(cli->dpy, virtual, VDMSelectMask);
X else XSelectInput(cli->dpy, virtual, ExposureMask);
X cli->framewin->core.virtual = virtual;
X VInstallInfo(cli->framewin);
X MakeVirtualIcon(cli);
X}
X
XMakeVirtualIcon(cli)
X Client *cli;
X
X{
Xint width, height;
Xint x, y;
X
X width = cli->iconwin->core.width / cli->scrInfo->vdm->resources->scale;
X height = cli->iconwin->core.height / cli->scrInfo->vdm->resources->scale;
X
X x = cli->iconwin->core.x / cli->scrInfo->vdm->resources->scale +
X cli->scrInfo->vdm->screenX;
X y = cli->iconwin->core.y / cli->scrInfo->vdm->resources->scale +
X cli->scrInfo->vdm->screenY;
X
X if (width <= 0)
X width = 1;
X if (height <= 0)
X height = 1;
X cli->iconwin->core.virtual = XCreateSimpleWindow(cli->dpy,
X PANEWINOFCLIENT(cli->scrInfo->vdm->client),
X x, y, width, height, 1,
X cli->scrInfo->colorInfo.borderColor,
X cli->scrInfo->colorInfo.virtualFgColor);
X XSelectInput(cli->dpy, cli->iconwin->core.virtual, VDMSelectMask);
X VInstallInfo(cli->iconwin);
X}
X
X/*
X * Call to set/unset the focus of the given window
X */
XVirtualChangeFocus(win, focus)
X WinGenericFrame *win;
X Bool focus;
X{
Xint length;
X
X switch(win->core.kind) {
X case WIN_ICON:
X length = ((WinIconFrame *) win)->nameLength;
X break;
X case WIN_FRAME:
X length = ((WinPaneFrame *) win)->nameLength;
X break;
X default:
X return;
X }
X if (focus)
X XSetWindowBackground(win->core.client->dpy, win->core.virtual,
X win->core.client->scrInfo->colorInfo.virtualInputColor);
X else XSetWindowBackground(win->core.client->dpy, win->core.virtual,
X win->core.client->scrInfo->colorInfo.virtualFgColor);
X XClearWindow(win->core.client->dpy, win->core.virtual);
X XDrawImageString(win->core.client->dpy, win->core.virtual,
X (focus) ? win->core.client->scrInfo->gc[VDM_INPUT_GC] :
X win->core.client->scrInfo->gc[VDM_GC],
X 1, win->core.client->scrInfo->vdm->max_ascent + 1,
X win->fcore.name, length);
X}
X
X/*
X * Refresh the window's virtual representation
X */
XPaintVirtualWindow(win)
X WinGenericFrame *win;
X{
XClient *cli = win->core.client;
Xint length;
X
X switch(win->core.kind) {
X case WIN_ICON:
X length = ((WinIconFrame *) win)->nameLength;
X break;
X case WIN_FRAME:
X length = ((WinPaneFrame *) win)->nameLength;
X break;
X default:
X return;
X }
X XClearArea(cli->dpy, win->core.virtual, 0, 0, 0, 0, False);
X XDrawImageString(cli->dpy, win->core.virtual,
X (cli->isFocus) ? cli->scrInfo->gc[VDM_INPUT_GC] :
X cli->scrInfo->gc[VDM_GC],
X 1, cli->scrInfo->vdm->max_ascent + 1,
X win->fcore.name, length);
X}
X
X/*
X * Dispatch the event to its virtual window if it belongs to a virtual window
X */
XDispatchVirtual(dpy, event)
X Display *dpy;
X XEvent *event;
X{
XWinGeneric *win, *VGetInfo();
Xstatic SemanticAction currentVDMAction;
Xunsigned int ignoremask;
X
X if (event->xany.type == KeymapNotify || event->xany.type == MappingNotify)
X return False;
X win = VGetInfo(event->xany.window);
X if (!win)
X return False;
X switch(event->xany.type) {
X case Expose:
X PaintVirtualWindow(win);
X break;
X
X /*
X * For mouse events, we generally try to pretend that the mouse event
X * happened on the frame instead of on the virtual window.
X * We pretend that adjust and select events occured on the frame
X * and just pass them to the frame's routine (after translating
X * the root coordinates). But we don't translate root coordinates
X * for menus because we want the menu to come up where the mouse
X * was
X */
X case ButtonPress:
X ignoremask = ModMaskMap[MOD_CONSTRAIN] |
X ModMaskMap[MOD_INVERT] |
X ModMaskMap[MOD_REDUCE];
X currentVDMAction = ResolveMouseBinding(dpy, event, ignoremask);
X if (currentVDMAction == ACTION_NONE)
X return True;
X if ((currentVDMAction == ACTION_SELECT) &&
X (event->xbutton.time - lastSelectTime <= GRV.DoubleClickTime)) {
X /*
X * We have a double click in the VDM. This is an exception to
X * the above rule: if we pass this to the frame, then the
X * frame will go full size, which is not very interesting.
X * So for this one we pretend it's a double click in the
X * VDM itself
X */
X translateVirtualCoords(win->core.client->scrInfo->vdm,
X &event->xmotion.x_root, &event->xmotion.y_root,
X &event->xmotion.x, &event->xmotion.y);
X VDMMoveTo(win->core.client->dpy, win->core.client,
X event->xbutton.x_root, event->xbutton.y_root);
X return True;
X }
X if (currentVDMAction == ACTION_MENU)
X translateVirtualCoords(win->core.client->scrInfo->vdm,
X NULL, NULL,
X &event->xmotion.x, &event->xmotion.y);
X else translateVirtualCoords(win->core.client->scrInfo->vdm,
X &event->xmotion.x_root, &event->xmotion.y_root,
X &event->xmotion.x, &event->xmotion.y);
X GFrameEventButtonPress(dpy, event, win);
X break;
X
X case MotionNotify:
X translateVirtualCoords(win->core.client->scrInfo->vdm,
X &event->xmotion.x_root, &event->xmotion.y_root,
X &event->xmotion.x, &event->xmotion.y);
X GFrameEventMotionNotify(dpy, event, win);
X break;
X
X case ButtonRelease:
X if (currentVDMAction == ACTION_NONE)
X return True;
X if (currentVDMAction == ACTION_MENU)
X translateVirtualCoords(win->core.client->scrInfo->vdm,
X NULL, NULL,
X &event->xmotion.x, &event->xmotion.y);
X else translateVirtualCoords(win->core.client->scrInfo->vdm,
X &event->xmotion.x_root, &event->xmotion.y_root,
X &event->xmotion.x, &event->xmotion.y);
X GFrameEventButtonRelease(dpy, event, win);
X if (currentVDMAction == ACTION_SELECT)
X lastSelectTime = event->xbutton.time;
X currentVDMAction = ACTION_NONE;
X break;
X
X default:
X fprintf(stderr, "unwanted %d event\n", event->xany.type);
X break;
X }
X return True;
X}
X
XMakeSticky(cli, sticky)
X Client *cli;
X Bool sticky;
X
X{
Xint dw, dh, x, y;
X /*
X * Can't unstick the VDM
X */
X if (cli->groupid == PANEWINOFCLIENT(cli->scrInfo->vdm->client) && !sticky)
X return !NULL;
X cli->sticky = sticky;
X dw = DisplayWidth(cli->dpy, cli->screen);
X dh = DisplayHeight(cli->dpy, cli->screen);
X if (cli->sticky) {
X x = cli->framewin->core.x;
X y = cli->framewin->core.y;
X cli->framewin->core.dirtyconfig |= CWX;
X GFrameSetConfig(cli->framewin, x, y,
X cli->framewin->core.width, cli->framewin->core.height);
X
X x = cli->iconwin->core.x;
X y = cli->iconwin->core.y;
X cli->iconwin->core.dirtyconfig |= CWX;
X IconSetPos(cli->iconwin, x + ICON_HORZBORDER, y + ICON_VERTBORDER);
X WinCallConfig(cli->dpy, cli->iconwin, NULL);
X }
X return NULL;
X}
X
X/*
X * Return true if the given key action should affect the VDM
X */
XKeyMoveVDM(dpy, ev)
X Display *dpy;
X XEvent *ev;
X{
XVirtualDesktop *vdm;
XWinGeneric *root;
XSemanticAction a;
X
X if (ev->xany.type != KeyPress)
X /* Root window uses same function for Up and Down events */
X return False;
X
X root = WIGetInfo(ev->xkey.root);
X if (!root) {
X fprintf(stderr, "NO ROOT\n");
X return False;
X }
X if (!root->core.client) {
X fprintf(stderr, "NO CLIENT\n");
X return False;
X }
X if (!root->core.client->scrInfo) {
X fprintf(stderr, "NO SCRINFO\n");
X return False;
X }
X vdm = root->core.client->scrInfo->vdm;
X
X a = FindNewKeyboardAction(dpy, ev);
X if (a == ACTION_NONE)
X return False;
X if (a == ACTION_VIRTUAL)
X return CheckForKeyProg(dpy, ev);
X
X return vdmPerformAction(dpy, vdm, a);
X}
X
X/*
X * Update the selection state of the given window's virtual representation
X */
XVirtualSelect(win, sel)
X WinGeneric *win;
X Bool sel;
X
X{
X if (win->core.virtual)
X XSetWindowBorderWidth(win->core.client->dpy,
X win->core.virtual, (sel) ? 2 : 1);
X}
X
X/*
X * Move to point x, y and save the desktop; we do this when save workspace
X * is called so that all the coordinates will be correct for startup
X * position
X */
XVirtualSaveDesktops(dpy, x, y)
X Display *dpy;
X int x, y;
X{
Xstruct deltas deltas;
XScreenInfo *si;
XList *l = ScreenInfoList;
X
X for (si = ListEnum(&l); si; si = ListEnum(&l)) {
X si->vdm->saveX = si->vdm->offsetX;
X si->vdm->saveY = si->vdm->offsetY;
X deltas.delta_x = si->vdm->offsetX - x;
X deltas.delta_y = si->vdm->offsetY - y;
X moveDesktop(dpy, &deltas, si->vdm);
X }
X}
X
XVirtualRestoreDesktops(dpy)
X Display *dpy;
X{
Xstruct deltas deltas;
XScreenInfo *si;
XList *l = ScreenInfoList;
X
X for (si = ListEnum(&l); si; si = ListEnum(&l)) {
X deltas.delta_x = -si->vdm->saveX;
X deltas.delta_y = -si->vdm->saveY;
X moveDesktop(dpy, &deltas, si->vdm);
X }
X}
X
XVirtualCleanup(dpy)
X Display *dpy;
X
X{
X VirtualSaveDesktops(dpy, 0, 0);
X}
X
XResizeVDM(vdm, size)
X VirtualDesktop *vdm;
X char *size;
X{
XWinGenericFrame *win;
X
X win = (WinGenericFrame *) vdm->client->framewin;
X if (vdm->resources->size)
X free(vdm->resources->size);
X vdm->resources->size = strdup(size);
X calculateVirtualDesktopSize(vdm->client->dpy, vdm->client->screen, vdm);
X GFrameSetConfig(win, win->core.x, win->core.y,
X vdm->width + (WinFunc(win,fcore.widthleft))(win) +
X (WinFunc(win,fcore.widthright))(win),
X vdm->height + (WinFunc(win,fcore.heighttop))(win) +
X (WinFunc(win,fcore.heightbottom))(win));
X}
X
X/*
X *============================================================================
X *
X * Functions to reflect resources changes
X */
X
Xstatic void *
XremakeVirtual(cli)
X Client *cli;
X{
XDisplay *dpy = cli->dpy;
X
X if (cli->framewin) {
X VIUninstallInfo(cli->framewin->core.virtual);
X VIUninstallInfo(cli->iconwin->core.virtual);
X XDestroyWindow(dpy, cli->framewin->core.virtual);
X XDestroyWindow(dpy, cli->iconwin->core.virtual);
X MakeVirtual(cli);
X XMapWindow(dpy, (cli->wmState == IconicState) ?
X cli->iconwin->core.virtual :
X cli->framewin->core.virtual);
X }
X return NULL;
X}
X
Xstatic void *
XupdateVirtualWindow(cli)
X Client *cli;
X
X{
XDisplay *dpy = cli->dpy;
X
X if (cli->framewin) {
X XSetWindowBackground(dpy, cli->framewin->core.virtual,
X cli->scrInfo->colorInfo.virtualFgColor);
X XSetWindowBackground(dpy, cli->iconwin->core.virtual,
X cli->scrInfo->colorInfo.virtualFgColor);
X }
X}
X
X/*
X * Resize the VDM with the new scale
X */
XRescaleVDM(vdm, scale)
X VirtualDesktop *vdm;
X int scale;
X
X{
Xint orig_scale;
XWinGenericFrame *win;
X
X orig_scale = vdm->resources->scale;
X vdm->resources->scale = scale;
X calculateVirtualDesktopSize(vdm->client->dpy, vdm->client->screen, vdm);
X vdm->screenX = (vdm->screenX * orig_scale) / scale;
X vdm->screenY = (vdm->screenY * orig_scale) / scale;
X vdm->client->normHints->width_inc = vdm->screenWidth;
X vdm->client->normHints->height_inc = vdm->screenHeight;
X win = (WinGenericFrame *) vdm->client->framewin;
X GFrameSetConfig(win, win->core.x, win->core.y,
X vdm->width + (WinFunc(win,fcore.widthleft))(win) +
X (WinFunc(win,fcore.widthright))(win),
X vdm->height + (WinFunc(win,fcore.heighttop))(win) +
X (WinFunc(win,fcore.heightbottom))(win));
X ListApply(ActiveClientList, remakeVirtual, 0);
X}
X
XVirtualUpdateVirtualWindows(cli)
X Client *cli;
X{
X ListApply(ActiveClientList, updateVirtualWindow, 0);
X ClientRefresh(cli);
X}
X
X/*
X * Size the VDM with the new geometry
X */
XVirtualSetGeometry(win, geom)
X WinGeneric *win;
X char *geom;
X{
Xint changed;
Xint newx, newy, x, y, w, h;
XDisplay *dpy = win->core.client->dpy;
XScreenInfo *scrInfo = win->core.client->scrInfo;
X
X changed = XParseGeometry(geom, &x, &y, &w, &h);
X if (changed & (XValue | YValue)) {
X if (changed & XValue)
X if (changed & XNegative)
X newx = DisplayWidth(dpy, scrInfo->screen) + x;
X else newx = x;
X else newx = win->core.x;
X w = win->core.width;
X if (newx > DisplayWidth(dpy, scrInfo->screen) - w)
X newx = DisplayWidth(dpy, scrInfo->screen) - w;
X if (changed & YValue)
X if (changed & YNegative)
X newy = DisplayHeight(dpy, scrInfo->screen) + y;
X else newy = y;
X else newy = win->core.y;
X h = win->core.height;
X if (newy > DisplayHeight(dpy, scrInfo->screen) - h)
X newy = DisplayHeight(dpy, scrInfo->screen) - h;
X GFrameSetConfig(win, newx, newy, win->core.width, win->core.height);
X }
X}
X
X/*
X * Get a background pixmap for the VDM with the VDM colors
X */
XPixmap
XVirtualGetPixmap(dpy, scrInfo, name)
X Display *dpy;
X ScreenInfo *scrInfo;
X char *name;
X
X{
XPixmap read, write;
Xint w, h, dummy;
XXGCValues gcv;
XGC gc;
X
X if (XReadBitmapFile(dpy, scrInfo->rootid, name,
X &w, &h, &read, &dummy, &dummy) == BitmapSuccess) {
X write = XCreatePixmap(dpy, scrInfo->rootid, w, h, scrInfo->depth);
X gcv.function = GXcopy;
X gc = XCreateGC(dpy, scrInfo->rootid, GCFunction, &gcv);
X XSetForeground(dpy, gc, scrInfo->colorInfo.virtualPixmapColor);
X XSetBackground(dpy, gc, scrInfo->colorInfo.virtualBgColor);
X XCopyPlane(dpy, read, write, gc, 0, 0, w, h, 0, 0, 1);
X XFreePixmap(dpy, read);
X XFreeGC(dpy, gc);
X return write;
X }
X else {
X ErrorWarning(gettext("An invalid bitmap file was named as the virtual background"));
X return None;
X }
X}
X
X/*
X * Perform an action from the VDM menu
X */
Xint
XVDMMenuAction(dpy, winInfo, menuInfo, btn)
X Display *dpy;
X WinPinMenu *winInfo;
X MenuInfo *menuInfo;
X int btn;
X
X{
X
X if (!vdmPerformAction(dpy, winInfo->core.client->scrInfo->vdm,
X vdmButtonActions[btn]) && GRV.Beep == BeepAlways)
X XBell(dpy, 100);
X}
X
X/*
X * Move to the logical screen on the desktop containing point x, y
X *
X * This move is constrained to a logical screen, even if the grid is
X * off.
X */
XVDMMoveTo(dpy, client, x, y)
X Display *dpy;
X Client *client;
X int x, y;
X{
Xint dw, dh;
Xstruct deltas deltas;
X
X dw = DisplayWidth(dpy, client->screen);
X dh = DisplayHeight(dpy, client->screen);
X deltas.delta_x = ((x - client->scrInfo->vdm->offsetX) / dw) * dw
X + client->scrInfo->vdm->offsetX;
X deltas.delta_y = ((y - client->scrInfo->vdm->offsetY) / dh) * dh
X + client->scrInfo->vdm->offsetY;
X constrainDeltas(dpy, client->scrInfo->vdm, &deltas);
X moveDesktop(dpy, &deltas, client->scrInfo->vdm);
X}
X
X/*
X * Goto logical screen passed
X */
X
XVDMGoto(dpy, client, screen)
X Display *dpy;
X Client *client;
X int screen;
X{
Xint dw, dh;
X
X screen--;
X dw = DisplayWidth(dpy, client->screen);
X dh = DisplayHeight(dpy, client->screen);
X VDMMoveTo(dpy, client, dw * (screen % client->scrInfo->vdm->rows) +
X client->scrInfo->vdm->offsetX,
X dh * (screen / client->scrInfo->vdm->rows) +
X client->scrInfo->vdm->offsetY);
X}
X
X/*
X *==========================================================================
X *
X * Utility functions to replace window mapping, configuring, etc.; these
X * functions work just like their X counterparts but affect both the
X * X window and its virtual representation.
X */
X
XMapWindow(win)
X WinGeneric *win;
X{
X XSetWindowBorderWidth(win->core.client->dpy,
X win->core.virtual, (win->core.client->isSelected) ? 2 : 1);
X XMapWindow(win->core.client->dpy, win->core.self);
X XMapWindow(win->core.client->dpy, win->core.virtual);
X if (GRV.VirtualRaiseVDM && win->core.client->scrInfo->vdm->client)
X RaiseWindow(win->core.client->scrInfo->vdm->client->framewin);
X}
X
XUnmapWindow(win)
X WinGeneric *win;
X{
X XUnmapWindow(win->core.client->dpy, win->core.self);
X XUnmapWindow(win->core.client->dpy, win->core.virtual);
X}
X
XMapRaised(win)
X WinGeneric *win;
X{
X XSetWindowBorderWidth(win->core.client->dpy,
X win->core.virtual, (win->core.client->isSelected) ? 2 : 1);
X XMapRaised(win->core.client->dpy, win->core.self);
X XMapRaised(win->core.client->dpy, win->core.virtual);
X if (GRV.VirtualRaiseVDM && win->core.client->scrInfo->vdm->client)
X RaiseWindow(win->core.client->scrInfo->vdm->client->framewin);
X}
X
XRaiseWindow(win)
X WinGeneric *win;
X{
X XRaiseWindow(win->core.client->dpy, win->core.self);
X XRaiseWindow(win->core.client->dpy, win->core.virtual);
X if (GRV.VirtualRaiseVDM &&
X win->core.client->scrInfo->vdm->client &&
X win->core.client->scrInfo->vdm->client &&
X win->core.self != win->core.client->scrInfo->vdm->client->framewin->core.self)
X RaiseWindow(win->core.client->scrInfo->vdm->client->framewin);
X}
X
XLowerWindow(win)
X WinGeneric *win;
X{
X XLowerWindow(win->core.client->dpy, win->core.self);
X XLowerWindow(win->core.client->dpy, win->core.virtual);
X if (GRV.VirtualRaiseVDM)
X RaiseWindow(win->core.client->scrInfo->vdm->client->framewin);
X}
X
XDestroyWindow(win)
X WinGeneric *win;
X{
X XDestroyWindow(win->core.client->dpy, win->core.self);
X WIUninstallInfo(win->core.self);
X if (win->core.virtual)
X XDestroyWindow(win->core.client->dpy, win->core.virtual);
X}
X
XDeleteProperty(dpy, win, atom)
X Display *dpy;
X WinGenericFrame *win;
X Atom atom;
X
X{
X XDeleteProperty(dpy, win->core.self, atom);
X if (win->core.virtual)
X XDeleteProperty(dpy, win->core.virtual, atom);
X}
X
XChangeProperty(dpy, win, property, type, format, mode, data, nelements)
X Display *dpy;
X WinGenericFrame *win;
X Atom property, type;
X int format;
X int mode;
X unsigned char *data;
X int nelements;
X{
X XChangeProperty(dpy, win->core.self, property, type, format,
X mode, data, nelements);
X if (win->core.virtual)
X XChangeProperty(dpy, win->core.virtual, property, type, format,
X mode, data, nelements);
X}
X
XConfigureWindow(dpy, win, mask, values)
X Display *dpy;
X WinGeneric *win;
X int mask;
X XWindowChanges *values;
X
X{
Xint scale;
XWinGeneric *tmp;
X
X XConfigureWindow(dpy, win->core.self, mask, values);
X scale = win->core.client->scrInfo->vdm->resources->scale;
X if (mask & CWX)
X values->x = (win->core.x - win->core.client->scrInfo->vdm->offsetX) /
X scale;
X if (mask & CWY)
X values->y = (win->core.y - win->core.client->scrInfo->vdm->offsetY) /
X scale;
X if (mask & CWWidth)
X values->width = win->core.width / scale;
X if (mask & CWHeight)
X values->height = win->core.height / scale;
X if (mask & CWSibling) {
X tmp = WIGetInfo(values->sibling);
X if (tmp)
X values->sibling = tmp->core.virtual;
X else mask |= ~(CWSibling|CWStackMode);
X }
X XConfigureWindow(dpy, win->core.virtual, mask, values);
X if (GRV.VirtualRaiseVDM)
X RaiseWindow(win->core.client->scrInfo->vdm->client->framewin);
X}
X
X/*
X * Menu generation function for DIRMENU
X *
X */
XGenDirMenuFunc(dpy, menuInfo, bindex, cache, winInfo, depth)
X Display *dpy;
X MenuInfo *menuInfo;
X int bindex;
X MenuCache *cache;
X WinGeneric *winInfo;
X int depth;
X
X{
XMenu *menu;
XDIR *dir;
Xstruct dirent *ent;
XButton *b;
Xchar s[256], *dirname;
Xextern int AppMenuFunc();
X
X MenuInfoDestroy(menuInfo->buttons[bindex].subMenu);
X menu = (Menu *) MemAlloc(sizeof(Menu));
X menu->buttons = NULL;
X menu->buttonCount = 0;
X menu->buttonDefault = NOBUTTON;
X menu->hasPushPin = False;
X menu->menudirty = True;
X menu->btnPerCol = 0;
X menu->maxLabWidth = 0;
X menu->prefColSize = 0;
X
X dirname = (char *) menuInfo->menu->buttons[bindex]->generate_args;
X if (!(dir = opendir(dirname))) {
X menuInfo->buttons[bindex].subMenu =
X MenuInfoCreate(cache, winInfo, menu, depth);
X return;
X }
X while (ent = readdir(dir)) {
X if (ent->d_name[0] == '.')
X continue;
X b = (Button *) MemAlloc(sizeof(Button));
X if (!menu->buttonCount++)
X menu->buttons = (Button **) MemAlloc(sizeof(Button *));
X else menu->buttons = (Button **)
X MemRealloc(menu->buttons, menu->buttonCount * sizeof(Button *));
X menu->buttons[menu->buttonCount - 1] = b;
X b->label[0].kind = StringLabel;
X b->label[1].kind = NoType;
X sprintf(s, "exec %s/%s", dirname, ent->d_name);
X b->label[0].string = MemNewString(ent->d_name);
X b->label[1].string = NULL;
X b->helpstring[0] = b->helpstring[1] = NULL;
X b->which = 0;
X b->stacked = False;
X b->enabled = True;
X b->visible = True;
X b->action.callback = AppMenuFunc;
X b->action.submenu = (void *) MemNewString(s);
X b->generate_func = NULL;
X }
X closedir(dir);
X menuInfo->buttons[bindex].subMenu =
X MenuInfoCreate(cache, winInfo, menu, depth);
X}
END_OF_FILE
if test 51849 -ne `wc -c <'virtual.c'`; then
echo shar: \"'virtual.c'\" unpacked with wrong size!
fi
# end of 'virtual.c'
fi
echo shar: End of archive 2 \(of 21\).
cp /dev/null ark2isdone
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