sdo@soliado.East.Sun.COM (Scott Oaks - Sun Consulting NYC) (04/29/91)
Submitted-by: sdo@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@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@uunet.uu.net argv@ora.com argv@zipcode.com