v12i067: olvwm - Open Look Virtual Window Manager, Part11/16

Scott Oaks - Sun Consulting NYC sdo at soliado.East.Sun.COM
Mon Apr 29 03:30:44 AEST 1991


Submitted-by: sdo at soliado.East.Sun.COM (Scott Oaks - Sun Consulting NYC)
Posting-number: Volume 12, Issue 67
Archive-name: olvwm/part11

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 11 (of 16)."
# Contents:  virtual.c
# Wrapped by sdo at piccolo on Fri Apr 26 17:31:08 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'virtual.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'virtual.c'\"
else
echo shar: Extracting \"'virtual.c'\" \(28215 characters\)
sed "s/^X//" >'virtual.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include <X11/X.h>
X#include <X11/Xatom.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include <X11/keysym.h>
X#include <X11/keysymdef.h>
X#include <math.h>
X#include "olwm.h"
X#include "win.h"
X#include "globals.h"
X#include "defaults.h"
X#include "resources.h"
X#include "st.h"
X
static char     sccsid[] = "@(#)virtual.c	1.3 olvwm version 4/17/91";
X
X#define TRUE	(1)
X#define FALSE	(0)
X
X#define ICON_SIZE	67
X
typedef struct deltas {
X    double	delta_x, delta_y;
X};
X
XXContext	VirtualContext;
X
char	pixdata[] = { 0xaa, 0x55 };
X
X#include "vdm.icon"
X
int	VirtualDesktopWidth, VirtualDesktopHeight;
int	VirtualDesktopX, VirtualDesktopY;
Window	VDM, VDMFrame;
int	VDMWidth, VDMHeight;
int	VDMOutlineX, VDMOutlineY;
int	VDMOutlineWidth, VDMOutlineHeight;
extern long WorkspaceColorPixel;
X
int	VirtualBackgroundColorSet = FALSE;
int	VirtualForegroundColorSet = FALSE;
int	VirtualFontColorSet = FALSE;
X
extern GC RootGC;
static GC	VDMGC = NULL;
X
MakeVirtualDesktop(dpy)
X    Display	*dpy;
X
X{
X    int	width, height;
X
X    sscanf(GRV.VirtualDesktop, "%dx%d", &width, &height);
X    if (width < DisplayWidth(dpy,DefaultScreen(dpy)))
X       width = width * DisplayWidth(dpy,DefaultScreen(dpy));
X    if (height < DisplayHeight(dpy,DefaultScreen(dpy)))
X       height = height * DisplayHeight(dpy,DefaultScreen(dpy));
X
X    VirtualDesktopWidth = width;
X    VirtualDesktopHeight = height;
X    VirtualDesktopX = 0;
X    VirtualDesktopY = 0;
X    VirtualContext = XUniqueContext();
X}
X
MakeVDM(dpy)
X    Display	*dpy;
X
X{
static XTextProperty	wName = {(unsigned char *) "Virtual Desktop",
X					XA_STRING, 8, 15 };
static XTextProperty	iName = {(unsigned char *) "Desktop",
X					XA_STRING, 8, 7 };
X    XSetWindowAttributes attr;
X    XSizeHints *sizeHints;
X    XWMHints *wmHints;
X    XClassHint *classHints;
X    int x, y, width, height, dummy, flags;
X    Pixmap pm = None;
X    unsigned attrMask;
X 
X    width = VirtualDesktopWidth / GRV.VDMScale + 1;
X    height = VirtualDesktopHeight / GRV.VDMScale + 1;
X
X    sizeHints = XAllocSizeHints();
X    sizeHints->flags = PBaseSize;
X    sizeHints->base_width = width;
X    sizeHints->base_height = height;
X    sizeHints->min_width = DisplayWidth(dpy, DefaultScreen(dpy)) /
X				GRV.VDMScale + 1;
X    sizeHints->min_height = DisplayHeight(dpy, DefaultScreen(dpy)) /
X				GRV.VDMScale + 1;
X    sizeHints->flags = USPosition|PMinSize;
X    flags = XParseGeometry(GRV.VirtualGeometry, &x, &y, &dummy, &dummy);
X    if (flags & XValue)
X	if (flags & XNegative)
X	    sizeHints->x =
X		DisplayWidth(dpy, DefaultScreen(dpy)) + x - width;
X	else sizeHints->x = x;
X    else sizeHints->x = 0;
X    if (flags & YValue)
X	if (flags & YNegative)
X	    sizeHints->y =
X		DisplayHeight(dpy, DefaultScreen(dpy)) + y - height;
X	else sizeHints->y = y;
X    else sizeHints->y = 0;
X    if (sizeHints->x > DisplayWidth(dpy, DefaultScreen(dpy)) - width)
X	sizeHints->x = DisplayWidth(dpy, DefaultScreen(dpy)) - width;
X    if (sizeHints->y > DisplayHeight(dpy, DefaultScreen(dpy)) - height)
X	sizeHints->y = DisplayHeight(dpy, DefaultScreen(dpy)) - height;
X       
X    wmHints = XAllocWMHints();
X    if (GRV.VirtualIconic)
X	wmHints->initial_state = IconicState;
X    else wmHints->initial_state = NormalState;
X    wmHints->flags = StateHint | InputHint | IconPixmapHint | IconPositionHint;
X    wmHints->input = TRUE;
X    wmHints->icon_pixmap = XCreateBitmapFromData(dpy,
X		DefaultRootWindow(dpy), vdm_bits,
X		vdm_width, vdm_height,
X		GRV.Fg1Color, GRV.Bg1Color, 1);
X    flags = XParseGeometry(GRV.VirtualIconGeometry, &x, &y, &dummy, &dummy);
X    if (flags & XValue)
X	if (flags & XNegative)
X	    wmHints->icon_x = DisplayWidth(dpy, DefaultScreen(dpy)) + x - ICON_SIZE;
X	else wmHints->icon_x = x;
X    else wmHints->icon_x = 0;
X    if (flags & YValue)
X	if (flags & YNegative)
X	    wmHints->icon_y = DisplayHeight(dpy, DefaultScreen(dpy)) + y - ICON_SIZE;
X	else wmHints->icon_y = y;
X    else wmHints->icon_y = 0;
X    if (wmHints->icon_x > DisplayWidth(dpy, DefaultScreen(dpy)) - ICON_SIZE)
X	wmHints->icon_x = DisplayWidth(dpy, DefaultScreen(dpy)) - ICON_SIZE;
X    if (wmHints->icon_y > DisplayHeight(dpy, DefaultScreen(dpy)) - ICON_SIZE)
X	wmHints->icon_y = DisplayHeight(dpy, DefaultScreen(dpy)) - ICON_SIZE;
X 
X    classHints = XAllocClassHint();
X    classHints->res_name = "virtualDesktop";
X    classHints->res_class = "olvwm";
X 
X    attrMask = CWBackPixmap|CWEventMask;
X    attrMask &= ~CWBackPixmap;
X    attrMask |= CWBackPixel;
X    attr.background_pixel = (VirtualBackgroundColorSet) ?
X		GRV.VirtualBackgroundColor : GRV.Bg2Color;
X    attr.event_mask = ExposureMask | ButtonPressMask | ButtonReleaseMask |
X	ButtonMotionMask | KeyPressMask | StructureNotifyMask;
X    if (DefaultDepth(dpy, DefaultScreen(dpy)) == 1) {
X	attrMask &= ~CWBackPixel;
X        attrMask |= CWBackPixmap;
X        pm = XCreatePixmapFromBitmapData(dpy, DefaultRootWindow(dpy),
X		    pixdata, 8, 2, GRV.Fg1Color, GRV.Bg1Color, 1);
X	attr.background_pixmap = pm;
X    }
X
X    VDMGC = XCreateGC(dpy, DefaultRootWindow(dpy), 0, NULL);
X    XCopyGC(dpy, RootGC, GCFunction | GCPlaneMask | GCForeground |
X                GCBackground | GCLineWidth | GCLineStyle | GCCapStyle |
X                GCJoinStyle | GCFillRule | GCFont, VDMGC);
X    XSetFunction(dpy, VDMGC, GXset);
X    XSetFont(dpy, VDMGC, GRV.VirtualFont->fid);
X    if (VirtualFontColorSet)
X	XSetForeground(dpy, VDMGC, GRV.VirtualFontColor);
X    if (VirtualForegroundColorSet)
X	XSetBackground(dpy, VDMGC, GRV.VirtualForegroundColor);
X    else XSetBackground(dpy, VDMGC, GRV.Bg1Color);
X    if (GRV.VirtualBackgroundMap) {
X	if (pm != None)
X	    XFreePixmap(dpy, pm);
X	if (pm = CreateVirtualPixmap(dpy)) {
X	    attrMask &= ~CWBackPixel;
X            attrMask |= CWBackPixmap;
X	    attr.background_pixmap = pm;
X	}
X    }
X
X    VDM = XCreateWindow(dpy, RootWindow(dpy, DefaultScreen(dpy)),
X	    sizeHints->x, sizeHints->y,
X            sizeHints->base_width, sizeHints->base_height, 1,
X            DefaultDepth(dpy, DefaultScreen(dpy)), InputOutput,
X            CopyFromParent, attrMask, &attr);
X    if (pm != None)
X	XFreePixmap(dpy, pm);
X
X    VDMWidth = sizeHints->base_width;
X    VDMHeight = sizeHints->base_height;
X    VDMOutlineWidth = VDMWidth /
X			((width * GRV.VDMScale) /
X				DisplayWidth(dpy,DefaultScreen(dpy)));
X    VDMOutlineHeight = VDMHeight /
X			((height * GRV.VDMScale)
X				/ DisplayHeight(dpy,DefaultScreen(dpy)));
X    VDMOutlineX = 0;
X    VDMOutlineY = 0;
X
X    XSetWMProperties(dpy, VDM, &wName, &iName, NULL, 0,
X        sizeHints, wmHints, classHints);
X    XFree(sizeHints);
X    XFree(wmHints);
X    XFree(classHints);
X    XMapRaised(dpy, VDM);
X
X}
X
VirtualSetUpFrame(cli, frame)
X    Client	*cli;
X    Window	frame;
X{
XXWindowAttributes	attr;
int x, y, dx = 0, dy = 0, dummy, flags;
X
X    XSaveContext(cli->dpy, VDM, VirtualContext, cli);
X    VDMFrame = frame;
X    /*
X     * Okay, now that we finally have the client handle, we can really
X     * reposition the VDM to account for window decorations
X     */
X    flags = XParseGeometry(GRV.VirtualGeometry, &x, &y, &dummy, &dummy);
X    if (flags & XValue && flags & XNegative)
X	dx = widthRightFrame(cli->framewin) + widthLeftFrame(cli->framewin);
X    if (flags & YValue && flags & YNegative)
X	dy = heightTopFrame(cli->framewin) + heightBottomFrame(cli->framewin);
X    if (dx || dy) {
X        GFrameSetConfig(cli->framewin, cli->framewin->core.x - dx,
X		cli->framewin->core.y - dy,
X		cli->framewin->core.width, cli->framewin->core.height);
X	/*cli->framewin->core.x -= dx;
X	cli->framewin->core.y -= dy;*/
X    }
X}
X
Client *
VirtualGetClient(dpy, w)
X    Display	*dpy;
X    Window	w;
X
X{
Client	*cli;
X
X    if (XFindContext(dpy, w, VirtualContext, &cli) != 0)
X	return NULL;
X    return cli;
X}
X
MakeVirtual(cli, dpy)
X    Client	*cli;
X    Display	*dpy;
X
X{
int	width, height;
int	x, y;
Window	virtual, MakeVirtualIcon();
X
X    /*
X     * Subtract 1 for those window borders
X     */
X    width = cli->framewin->core.width / GRV.VDMScale - 1;
X    height = cli->framewin->core.height / GRV.VDMScale - 1;
X
X    x = cli->framewin->core.x / GRV.VDMScale + VDMOutlineX;
X    y = cli->framewin->core.y / GRV.VDMScale + VDMOutlineY;
X
X    if (width <= 0)
X	width = 1;
X    if (height <= 0)
X	height = 1;
X    virtual = XCreateSimpleWindow(dpy, VDM, x, y,
X	width, height, 1, GRV.BorderColor, 
X	VirtualForegroundColorSet ? GRV.VirtualForegroundColor : GRV.Bg1Color);
X    if (PANEWINOFCLIENT(cli) != VDM)
X        XSelectInput(dpy, virtual, ButtonPressMask | ExposureMask);
X    else XSelectInput(dpy, virtual, ExposureMask);
X    XSaveContext(dpy, virtual, VirtualContext, cli);
X    cli->virtualWindow = virtual;
X    cli->virtualInactive = MakeVirtualIcon(cli, dpy);
X}
X
LowerWindow(win, virtualWindow, sticky, dpy)
X    Window	win, virtualWindow;
X    int		sticky;
X    Display	*dpy;
X
X{
X    XLowerWindow(dpy, win);
X    if (virtualWindow)
X	XLowerWindow(dpy, virtualWindow);
X}
X
RaiseWindow(win, virtualWindow, sticky, dpy)
X    Window	win, virtualWindow;
X    int		sticky;
X    Display	*dpy;
X
X{
X    XRaiseWindow(dpy, win);
X    if (virtualWindow)
X	XRaiseWindow(dpy, virtualWindow);
X}
X
PaintVirtualWindow(dpy, ev)
X    Display	*dpy;
X    XEvent	*ev;
X
X{
Client	*cli;
X
X    if (XFindContext(dpy, ev->xany.window, VirtualContext, &cli) != 0)
X	return;		/* Window is destroyed . . . */
X
X    XClearArea(dpy, ev->xany.window, 1, 1, 0, 0, False);
X    XDrawImageString(dpy, ev->xany.window, VDMGC, 1, 
X    			GRV.VirtualFont->max_bounds.ascent + 1,
X			cli->framewin->fcore.name,
X			cli->framewin->nameLength);
X}
X
Window
MakeVirtualIcon(cli, dpy)
X    Client	*cli;
X    Display	*dpy;
X
X{
int	width, height;
int	x, y;
Window	virtual;
X
X    width = cli->iconwin->core.width / GRV.VDMScale;
X    height = cli->iconwin->core.height / GRV.VDMScale;
X
X    x = cli->iconwin->core.x / GRV.VDMScale + VDMOutlineX;
X    y = cli->iconwin->core.y / GRV.VDMScale + VDMOutlineY;
X
X    if (width <= 0)
X	width = 1;
X    if (height <= 0)
X	height = 1;
X    virtual = XCreateSimpleWindow(dpy, VDM, x, y,
X		width, height, 1, GRV.BorderColor,
X	VirtualForegroundColorSet ? GRV.VirtualForegroundColor : GRV.Bg1Color);
X    XSelectInput(dpy, virtual, ButtonPressMask | KeyPressMask | ExposureMask);
X    XSaveContext(dpy, virtual, VirtualContext, cli);
X    return virtual;
X}
X
HandleVDMExpose(dpy, ev)
X    XEvent	*ev;
X    Display	*dpy;
X
X{
XXEvent	dummy;
X
X    if (ev->xexpose.count)
X	return;
X
X    XClearArea(dpy, VDM, 0, 0, 0, 0, 0);
X    XDrawRectangle(dpy, VDM, VDMGC,
X		   VDMOutlineX, VDMOutlineY,
X		   VDMOutlineWidth, VDMOutlineHeight);
X    while (XCheckTypedWindowEvent(dpy, VDM, Expose, &dummy));
X}
X
VDMEvents(dpy, ev)
X    XEvent	*ev;
X    Display	*dpy;
X
X{
static int	state = 0;
X
X    switch(ev->xany.type) {
X	case Expose:
X	    HandleVDMExpose(dpy, ev);
X	    break;
X	case KeyPress:
X	    if (!CheckVDMMove(dpy, ev) && GRV.Beep == BeepAlways)
X		XBell(dpy, 100);
X	    break;
X	case ButtonPress:
X	    if (MouseButton(dpy, ev) != MB_SELECT)
X		return;
X	    if (HandleVDMButtonPress(dpy, ev))
X		state = 1;
X	    break;
X	case ButtonRelease:
X	    if (!state)
X		return;
X	    if (MouseButton(dpy, ev) != MB_SELECT)
X		return;
X	    state = 0;
X	    HandleVDMButtonRelease(dpy, ev);
X	    break;
X	case MotionNotify:
X	    if (!state)
X		return;
X	    HandleVDMMotionNotify(dpy, ev);
X	    break;
X	case ConfigureNotify:
X	    ResizeVDM(dpy, ev->xconfigure.width, ev->xconfigure.height);
X	    break;
X    }
X}
X
X#ifdef TESTING
char	*eventMasks[] = {
X	"KeyPressMask", "KeyReleaseMask",
X"ButtonPressMask",
X"ButtonReleaseMask",
X"EnterWindowMask",
X"LeaveWindowMask",
X"PointerMotionMask",
X"PointerMotionHintMask",
X"Button1MotionMask",
X"Button2MotionMask",
X"Button3MotionMask",
X"Button4MotionMask",
X"Button5MotionMask",
X"ButtonMotionMask",
X"KeymapStateMask",
X"ExposureMask",
X"VisibilityChangeMask",
X"StructureNotifyMask",
X"ResizeRedirectMask",
X"SubstructureNotifyMask",
X"SubstructureRedirectMask",
X"FocusChangeMask",
X"PropertyChangeMask",
X"ColormapChangeMask",
X"OwnerGrabButtonMask",
X};
X
DumpAttributes(dpy, win)
X    Window	*win;
X    Display	*dpy;
X
X{
XXWindowAttributes	attr;
int			i;
static int	foo = 1;
int		ret;
X
X    if (!foo)
X	return;
X    ret = XGetWindowAttributes(dpy, win, &attr);
X    if (!ret)
X	fprintf(stderr, "Can't get attr!\n");
X    else {
X        fprintf(stderr, "Attr mask is %u = ", attr.all_event_masks);
X        for (i = 0; i < 31; i++)
X	    if (attr.all_event_masks & (1 << i))
X	        fprintf(stderr, "%s | ", eventMasks[i]);
X	fprintf(stderr, "\n");
X    }
X    XFlush(dpy);
X}
X#endif
X
IsVirtual(w)
X    Window	w;
X
X{
X    if (w == VDM)
X	return TRUE;
X    if (!WIGetInfo(w))
X	return TRUE;
X    return FALSE;
X}
X
VirtualEvents(dpy, ev)
X    Display	*dpy;
X    XEvent	*ev;
X
X{
Client	*cli;
X
X    if (ev->xany.window == VDM)
X	VDMEvents(dpy, ev);
X    else switch(ev->xany.type) {
X	case Expose:
X	    PaintVirtualWindow(dpy, ev);
X	    break;
X	case ButtonPress:
X	    /*
X	     * Really I should do a select here and then maybe move many, but
X	     * I'm too lazy
X	     */
X	    if (MouseButton(dpy, ev) != MB_SELECT)
X		return;
X	    if (XFindContext(dpy, ev->xany.window, VirtualContext, &cli) != 0)
X		return;
X	    UserMoveVirtualWindow(dpy, ev, cli);
X	    break;
X	case EnterNotify:
X	    if (GRV.FocusFollowsMouse &&
X			(ev->xcrossing.detail != NotifyInferior)) {
X		XSetInputFocus(dpy, ev->xany.window,
X			RevertToPointerRoot, CurrentTime);
X	    }
X	    break;
X    }
X}
X
CheckVDMMove(dpy, ev)
X    Display	*dpy;
X    XEvent	*ev;
X
X{
struct deltas	deltas;
int	doit = FALSE;
int	dw = DisplayWidth(dpy, DefaultScreen(dpy));
int	dh = DisplayHeight(dpy, DefaultScreen(dpy));
KeySym	symbol;
enum st_retval ReplaceSticky();
X
X    deltas.delta_x = deltas.delta_y = 0;
X    symbol = XLookupKeysym(ev, 0);
X    switch(symbol) {
X	case XK_Left:
X	    deltas.delta_x = -dw;
X	    doit = TRUE;
X	    break;
X	case XK_Up:
X	    deltas.delta_y = -dh;
X	    doit = TRUE;
X	    break;
X	case XK_Right:
X	    deltas.delta_x = dw;
X	    doit = TRUE;
X	    break;
X	case XK_Down:
X	    deltas.delta_y = dh;
X	    doit = TRUE;
X	    break;
X	case XK_R7:
X	    deltas.delta_x = -dw;
X	    deltas.delta_y = -dh;
X	    doit = TRUE;
X	    break;
X	case XK_R9:
X	    deltas.delta_x = dw;
X	    deltas.delta_y = -dh;
X	    doit = TRUE;
X	    break;
X	case XK_R11:
X	    deltas.delta_x = VirtualDesktopX;
X	    deltas.delta_y = VirtualDesktopY;
X	    doit = TRUE;
X	    break;
X	case XK_R13:
X	    deltas.delta_x = -dw;
X	    deltas.delta_y = dh;
X	    doit = TRUE;
X	    break;
X	case XK_R15:
X	    deltas.delta_x = dw;
X	    deltas.delta_y = dh;
X	    doit = TRUE;
X	    break;
X	default:
X	    break;
X    }
X    if (!doit)
X	return FALSE;
X
X    if (VirtualDesktopX - deltas.delta_x < dw - VirtualDesktopWidth)
X	deltas.delta_x = VirtualDesktopX + VirtualDesktopWidth - dw;
X    else if (VirtualDesktopX - deltas.delta_x > 0)
X	deltas.delta_x = VirtualDesktopX;
X    if (VirtualDesktopY - deltas.delta_y < dh - VirtualDesktopHeight)
X	deltas.delta_y = VirtualDesktopY + VirtualDesktopHeight - dh;
X    else if (VirtualDesktopY - deltas.delta_y > 0)
X	deltas.delta_y = VirtualDesktopY;
X
X    if (fabs(deltas.delta_x) < 0.1 && fabs(deltas.delta_y) < 0.1)
X	return FALSE;
X
X    VDMOutlineX = (-VirtualDesktopX + deltas.delta_x) / GRV.VDMScale;
X    VDMOutlineY = (-VirtualDesktopY + deltas.delta_y) / GRV.VDMScale;
X
X    MoveDesktop(dpy, &deltas);
X    return TRUE;
X}
X
MoveDesktop(dpy, deltas)
X    Display	*dpy;
X    struct deltas	*deltas;
X
X{
XXEvent	event;
X
X    VirtualDesktopX -= deltas->delta_x;
X    VirtualDesktopY -= deltas->delta_y;
X    WIApply(ReplaceSticky, deltas);
X    event.xexpose.count = 0;
X    HandleVDMExpose(dpy, &event);
X}
X
VirtualDestroy(dpy, cli)
X    Display	*dpy;
X    Client	*cli;
X
X{
X    XDeleteContext(dpy, cli->virtualWindow, VirtualContext);
X    XDeleteContext(dpy, cli->virtualInactive, VirtualContext);
X    XDestroyWindow(dpy, cli->virtualWindow);
X    XDestroyWindow(dpy, cli->virtualInactive);
X}
X
enum st_retval
ReplaceSticky(w, win, c)
Window w;
WinGeneric *win;
struct deltas	*c;
X{
Client	*cli;
Window		vIcon;
X
X    cli = win->core.client;
X    if (cli && !cli->sticky) {
X        switch(win->core.kind) {
X	    case WIN_FRAME:
X        	GFrameSetConfig(win, (int) (win->core.x - c->delta_x),
X			(int) (win->core.y - c->delta_y),
X			win->core.width, win->core.height);
X		break;
X	    case WIN_ICON:
X        	GFrameSetConfig(win, (int) (win->core.x - c->delta_x),
X			(int) (win->core.y - c->delta_y),
X			win->core.width, win->core.height);
X	    default:
X		break;
X	}
X    }
X    else if (cli) {
X	switch(win->core.kind) {
X	    case WIN_FRAME:
X		if (cli->wmState != NormalState)
X	    	    vIcon = cli->virtualInactive;
X		else vIcon = cli->virtualWindow;
X		XMoveWindow(cli->dpy, vIcon,
X			(win->core.x) / GRV.VDMScale + VDMOutlineX,
X			(win->core.y) / GRV.VDMScale + VDMOutlineY);
X		break;
X	    case WIN_ICON:
X		if (cli->wmState == NormalState)
X	    	    vIcon = cli->virtualInactive;
X		else vIcon = cli->virtualWindow;
X		XMoveWindow(cli->dpy, vIcon,
X			(win->core.x) / GRV.VDMScale + VDMOutlineX,
X			(win->core.y) / GRV.VDMScale + VDMOutlineY);
X		break;
X	    default:
X		break;
X	}
X    }
X    return ST_CONTINUE;
X}
X
int	VDMPointerX = -1;
int	VDMPointerY;
int	VDMInitX, VDMInitY;
X
HandleVDMButtonPress(dpy, ev)
X    Display	*dpy;
X    XEvent	*ev;
X
X{
X    VDMPointerX = ev->xbutton.x;
X    VDMPointerY = ev->xbutton.y;
X    if (VDMPointerX < VDMOutlineX ||
X			VDMPointerX > VDMOutlineX + VDMOutlineWidth)
X	return FALSE;
X    if (VDMPointerY < VDMOutlineY ||
X			VDMPointerY > VDMOutlineY + VDMOutlineHeight)
X	return FALSE;
X    XClearWindow(dpy, VDM);
X    XDrawRectangle(dpy, VDM, VDMGC,
X	VDMOutlineX, VDMOutlineY,
X	VDMOutlineWidth, VDMOutlineHeight);
X    VDMInitX = VDMOutlineX;
X    VDMInitY = VDMOutlineY;
X    return TRUE;
X}
X
HandleVDMButtonRelease(dpy, ev)
X    Display	*dpy;
X    XEvent	*ev;
X
X{
struct deltas	deltas;
X
X    XClearWindow(dpy, VDM);
X    constrain_vdm_outline(ev->xbutton.x, ev->xbutton.y);
X    XDrawRectangle(dpy, VDM, VDMGC, VDMOutlineX, VDMOutlineY,
X	VDMOutlineWidth, VDMOutlineHeight);
X    deltas.delta_x = (VDMOutlineX - VDMInitX) * GRV.VDMScale;
X    deltas.delta_y = (VDMOutlineY - VDMInitY) * GRV.VDMScale;
X    MoveDesktop(dpy, &deltas);
X    VDMPointerX = -1;
X}
X
HandleVDMMotionNotify(dpy, ev)
X    Display	*dpy;
X    XEvent	*ev;
X
X{
X    if (VDMPointerX == -1)
X	return;
X    XClearWindow(dpy, VDM);
X    constrain_vdm_outline(ev->xmotion.x, ev->xmotion.y);
X
X    XDrawRectangle(dpy, VDM, VDMGC,
X	VDMOutlineX, VDMOutlineY,
X	VDMOutlineWidth, VDMOutlineHeight);
X}
X
constrain_vdm_outline(x, y)
X    int x, y;
X
X{
X    VDMOutlineX = x - VDMPointerX + VDMInitX;
X    VDMOutlineY = y - VDMPointerY + VDMInitY;
X    
X    if (VDMOutlineX < 0)
X	VDMOutlineX = 0;
X    else if (VDMOutlineX + VDMOutlineWidth >= VDMWidth)
X	VDMOutlineX = VDMWidth - VDMOutlineWidth - 1;
X
X    if (VDMOutlineY < 0)
X	VDMOutlineY = 0;
X    else if (VDMOutlineY + VDMOutlineHeight >= VDMHeight)
X	VDMOutlineY = VDMHeight - VDMOutlineHeight - 1;
X}
X
int	SaveVDX = -1, SaveVDY;
X
VirtualSaveDesktop(dpy, x, y)
X    Display	*dpy;
X    int		x, y;
X
X{
struct deltas	deltas;
X
X    SaveVDX = VirtualDesktopX;
X    SaveVDY = VirtualDesktopY;
X    deltas.delta_x = VirtualDesktopX - x;
X    deltas.delta_y = VirtualDesktopY - y;
X    MoveDesktop(dpy, &deltas);
X}
X
VirtualRestoreDesktop(dpy)
X    Display	*dpy;
X
X{
struct deltas	deltas;
X
X    deltas.delta_x = -SaveVDX;
X    deltas.delta_y = -SaveVDY;
X    MoveDesktop(dpy, &deltas);
X}
X
Bool
UpdVirtualFont( dpy, rmIndex, isUpdate )
X    Display	*dpy;
X    int		rmIndex;
X    Bool	isUpdate;
X
X{
X    if (isUpdate && VDMGC) {
X        XSetFont(dpy, VDMGC, GRV.VirtualFont->fid);
X        RecursiveRefresh(dpy, VDM);
X    }
X    return TRUE;
X}
X
UpdVirtualDesktop(dpy, rmIndex, isUpdate)
X    Display	*dpy;
X    int		rmIndex;
X    Bool	isUpdate;
X
X{
int	width, height;
Client	*cli;
X
X    if (isUpdate) {
X        sscanf(GRV.VirtualDesktop, "%dx%d", &width, &height);
X        if (width < DisplayWidth(dpy,DefaultScreen(dpy)))
X           width = width * DisplayWidth(dpy,DefaultScreen(dpy));
X        if (height < DisplayHeight(dpy,DefaultScreen(dpy)))
X           height = height * DisplayHeight(dpy,DefaultScreen(dpy));
X	if (XFindContext(dpy, VDM, VirtualContext, &cli) != 0)
X		return TRUE;
X        GFrameSetConfig(cli->framewin, (int) cli->framewin->core.x,
X		(int) cli->framewin->core.y,
X		width / GRV.VDMScale + 1 +
X		widthLeftFrame(cli->framewin) + widthRightFrame(cli->framewin),
X		height / GRV.VDMScale + 1 +
X		heightTopFrame(cli->framewin) + heightBottomFrame(cli->framewin));
X    }
X    return TRUE;
X}
X
Bool
UpdVirtualGeometry(dpy, rmIndex, isUpdate)
X    Display	*dpy;
X    int		rmIndex;
X    Bool	isUpdate;
X
X{
int	x, y, width, height;
int	changed;
Client	*cli;
int	newx, newy;
int	border;
X
X    if (isUpdate) {
X        changed = XParseGeometry(GRV.VirtualGeometry, &x, &y,
X			 &width, &height);
X	if (changed & XValue || changed & YValue) {
X    	    if (XFindContext(dpy, VDM, VirtualContext, &cli) != 0)
X		return;
X	    border = widthRightFrame(cli->framewin) +
X		     widthLeftFrame(cli->framewin);
X	    if (changed & XValue) {
X		if (changed & XNegative)
X		    newx = DisplayWidth(dpy,DefaultScreen(dpy)) + x  -
X				VDMWidth - border;
X		else newx = x;
X	    }
X	    else newx = cli->framewin->core.x;
X	    if (newx > DisplayWidth(dpy, DefaultScreen(dpy)) - VDMWidth -
X			border)
X	        newx = DisplayWidth(dpy, DefaultScreen(dpy)) - VDMWidth -
X			border;
X	    border = heightTopFrame(cli->framewin) +
X		     heightBottomFrame(cli->framewin);
X	    if (changed & YValue)
X		newy = (changed & YNegative) ?
X		   	    DisplayHeight(dpy,DefaultScreen(dpy)) + y  -
X			    VDMHeight - border
X			    : y;
X	    else newy = cli->framewin->core.y;
X	    if (newy > DisplayHeight(dpy,DefaultScreen(dpy)) - VDMHeight -
X			border)
X	        newy = DisplayHeight(dpy,DefaultScreen(dpy)) - VDMHeight -
X			border;
X            GFrameSetConfig(cli->framewin, newx, newy,
X		cli->framewin->core.width, cli->framewin->core.height);
X	}
X    }
X    return TRUE;
X}
X
char *
VirtualRemakeVirtual(cli)
X    Client	*cli;
X
X{
Window	tmp;
X
X    XDeleteContext(cli->dpy, cli->virtualWindow, VirtualContext);
X    XDeleteContext(cli->dpy, cli->virtualInactive, VirtualContext);
X    XDestroyWindow(cli->dpy, cli->virtualWindow);
X    XDestroyWindow(cli->dpy, cli->virtualInactive);
X    MakeVirtual(cli, cli->dpy);
X    if (cli->wmState == IconicState) {
X	tmp = cli->virtualWindow;
X	cli->virtualWindow = cli->virtualInactive;
X	cli->virtualInactive = tmp;
X    }
X    XMapWindow(cli->dpy, cli->virtualWindow);
X    return NULL;
X}
X
Bool
UpdVDMScale(dpy, rmIndex, isUpdate)
X    Display	*dpy;
X    int		rmIndex;
X    Bool	isUpdate;
X
X{
int	width, height;
Client	*cli;
X
X    if (isUpdate) {
X	ListApply(ActiveClientList, VirtualRemakeVirtual, 0);
X	width = VirtualDesktopWidth / GRV.VDMScale + 1;
X	height = VirtualDesktopHeight / GRV.VDMScale + 1;
X        VDMOutlineWidth = width /
X			((width * GRV.VDMScale) /
X				DisplayWidth(dpy,DefaultScreen(dpy)));
X        VDMOutlineHeight = height /
X			((height * GRV.VDMScale)
X				/ DisplayHeight(dpy,DefaultScreen(dpy)));
X	if (XFindContext(dpy, VDM, VirtualContext, &cli) != 0)
X		return TRUE;
X        GFrameSetConfig(cli->framewin, (int) cli->framewin->core.x,
X		(int) cli->framewin->core.y,
X		width + widthLeftFrame(cli->framewin) +
X			widthRightFrame(cli->framewin),
X		height + heightTopFrame(cli->framewin) +
X			heightBottomFrame(cli->framewin));
X   }
X   return TRUE;
X}
X
VirtualCleanup(dpy)
X    Display	*dpy;
X
X{
X    VirtualSaveDesktop(dpy, 0, 0);
X}
X
UpdVirtualBgColor(dpy, rmIndex, isUpdate)
X    Display	*dpy;
X    int		rmIndex;
X    Bool	isUpdate;
X
X{
X    if (isUpdate) {
X	XSetWindowBackground(dpy, VDM, GRV.VirtualBackgroundColor);
X	XClearWindow(dpy, VDM);
X    }
X    return TRUE;
X}
X
VirtualChangeFgColor(cli)
X    Client	*cli;
X
X{
X    XSetWindowBackground(cli->dpy, cli->virtualWindow,
X				GRV.VirtualForegroundColor);
X    XSetWindowBackground(cli->dpy, cli->virtualInactive,
X				GRV.VirtualForegroundColor);
X    return NULL;
X}
X
UpdVirtualFgColor(dpy, rmIndex, isUpdate)
X    Display	*dpy;
X    int		rmIndex;
X    Bool	isUpdate;
X
X{
X    if (isUpdate) {
X	ListApply(ActiveClientList, VirtualChangeFgColor, 0);
X	XSetBackground(dpy, VDMGC, GRV.VirtualForegroundColor);
X       	RecursiveRefresh(dpy, VDM);
X    }
X    return TRUE;
X}
X
UpdVirtualFontColor(dpy, rmIndex, isUpdate)
X    Display	*dpy;
X    int		rmIndex;
X    Bool	isUpdate;
X
X{
X    if (isUpdate) {
X	XSetForeground(dpy, VDMGC, GRV.VirtualFontColor);
X       	RecursiveRefresh(dpy, VDM);
X    }
X    return TRUE;
X}
X
UpdVirtualMap(dpy, rmIndex, isUpdate)
X    Display	*dpy;
X    int		rmIndex;
X    Bool	isUpdate;
X
X{
Pixmap	write;
X
X    if (isUpdate) {
X	if (write = CreateVirtualPixmap(dpy)) {
X	    XSetWindowBackgroundPixmap(dpy, VDM, write);
X	    XClearWindow(dpy, VDM);
X	    XFreePixmap(dpy, write);
X	}
X    }
X    return TRUE;
X}
X
CreateVirtualPixmap(dpy)
X    Display	*dpy;
X
X{
Pixmap	read, write;
int	w, h, dummy;
GC	gc;
X
X    if (XReadBitmapFile(dpy, RootWindow(dpy, DefaultScreen(dpy)),
X			GRV.VirtualBackgroundMap, &w, &h,
X			&read, &dummy, &dummy) == BitmapSuccess) {
X	write = XCreatePixmap(dpy, RootWindow(dpy, DefaultScreen(dpy)),
X			w, h, DefaultDepth(dpy, DefaultScreen(dpy)));
X	gc = XCreateGC(dpy, VDM, 0, NULL);
X        XCopyGC(dpy, VDMGC, GCForeground | GCBackground, gc);
X	/*
X	 * Why doesn't this color stuff work on startup?
X	 */
X	if (VirtualForegroundColorSet)
X	    XSetForeground(dpy, gc, GRV.VirtualForegroundColor);
X	if (VirtualBackgroundColorSet)
X	    XSetBackground(dpy, gc, GRV.VirtualBackgroundColor);
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    return None;
X}
X
X
ResizeVDM(dpy, width, height)
X    Display	*dpy;
X    int		width, height;
X
X{
int	doit;
struct deltas	deltas;
int	temp;
X
X    VirtualDesktopHeight = (height - 1) * GRV.VDMScale;
X    VirtualDesktopWidth = (width - 1) * GRV.VDMScale;
X    temp = nint((double) VirtualDesktopHeight / 
X		(double) DisplayHeight(dpy, DefaultScreen(dpy))) *
X		DisplayHeight(dpy, DefaultScreen(dpy));
X    if (abs(temp - VirtualDesktopHeight) <= GRV.VDMScale)
X	VirtualDesktopHeight = temp;
X    temp = nint((double) VirtualDesktopWidth / 
X		(double) DisplayWidth(dpy, DefaultScreen(dpy))) *
X		DisplayWidth(dpy, DefaultScreen(dpy));
X    if (abs(temp - VirtualDesktopWidth) <= GRV.VDMScale)
X	VirtualDesktopWidth = temp;
X    VDMWidth = width;
X    VDMHeight = height;
X    doit = FALSE;
X    deltas.delta_x = deltas.delta_y = 0;
X    if (VDMOutlineX + VDMOutlineWidth > VDMWidth - 1) {
X	doit = TRUE;
X	deltas.delta_x = (VDMWidth - VDMOutlineWidth - 1 -
X		VDMOutlineX) * GRV.VDMScale;
X    	VDMOutlineX = (-VirtualDesktopX + deltas.delta_x) /
X				GRV.VDMScale;
X    }
X    if (VDMOutlineY + VDMOutlineHeight > VDMHeight - 1) {
X	doit = TRUE;
X	deltas.delta_y = (VDMHeight - VDMOutlineHeight - 1 -
X		VDMOutlineY) * GRV.VDMScale;
X    	VDMOutlineY = (-VirtualDesktopY + deltas.delta_y) /
X				GRV.VDMScale;
X    }
X    if (doit) {
X        MoveDesktop(dpy, &deltas);
X       	RecursiveRefresh(dpy, VDM);
X   }
X}
X
Bool
UpdVirtualIconGeometry(dpy, rmIndex, isUpdate)
X    Display	*dpy;
X    int		rmIndex;
X    Bool	isUpdate;
X
X{
int	x, y, width, height;
int	changed;
Client	*cli;
int	newx, newy;
X
X    if (isUpdate) {
X        changed = XParseGeometry(GRV.VirtualIconGeometry, &x, &y,
X			 &width, &height);
X	if (changed & XValue || changed & YValue) {
X    	    if (XFindContext(dpy, VDM, VirtualContext, &cli) != 0)
X		return TRUE;
X	    if (changed & XValue)
X		newx = (changed & XNegative) ?
X			DisplayWidth(dpy,DefaultScreen(dpy)) + x - ICON_SIZE: x;
X	    else newx = cli->iconwin->core.x;
X	    if (changed & YValue)
X		newy = (changed & YNegative) ?
X			DisplayHeight(dpy,DefaultScreen(dpy)) + y - ICON_SIZE: y;
X	    else newy = cli->iconwin->core.y;
X	    if (newx > DisplayWidth(dpy, DefaultScreen(dpy)) - ICON_SIZE)
X	        newx = DisplayWidth(dpy, DefaultScreen(dpy)) - ICON_SIZE;
X	    if (newy > DisplayHeight(dpy, DefaultScreen(dpy)) - ICON_SIZE)
X	        newy = DisplayHeight(dpy, DefaultScreen(dpy)) - ICON_SIZE;
X            GFrameSetConfig(cli->iconwin, newx, newy,
X		cli->iconwin->core.width, cli->iconwin->core.height);
X	}
X    }
X    return TRUE;
X}
X
VirtualSetColor( dpy, rmIndex, newValue, varSet )
Display	*dpy;
int	rmIndex;
char	*newValue;
Bool	varSet;
X{
X    if (rmIndex == RM_VIRTUALBGCOLOR && newValue)
X	VirtualBackgroundColorSet = TRUE;
X    else if (rmIndex == RM_VIRTUALFGCOLOR && newValue)
X	VirtualForegroundColorSet = TRUE;
X    else if (rmIndex == RM_VIRTUALFONTCOLOR && newValue)
X	VirtualFontColorSet = TRUE;
X    return setColor(dpy, rmIndex, newValue, varSet);
X}
END_OF_FILE
if test 28215 -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 11 \(of 16\).
cp /dev/null ark11isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 16 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

--
Dan Heller
O'Reilly && Associates       Z-Code Software    Comp-sources-x:
Senior Writer                President          comp-sources.x at uunet.uu.net
argv at ora.com                 argv at zipcode.com



More information about the Comp.sources.x mailing list