+#include "wm.h"
+
+#include "../cursors/icon.cursor"
+#include "../cursors/xterm.cursor"
+#include "../cursors/xterm_mask.cursor"
+
+#define solid_vcount (1 + 4*2) /* We're goin' around twice */
+#define flash_vcount (1 + 4*4) /* 4 times, if flashing! */
+
+#ifndef lint
+static char *rcsid_wmsubs_c = "$Header: wmsubs.c,v 10.3 86/02/01 16:02:10 tony Rel $";
+#endif
+
+int vcount;
+Vertex solidBox[solid_vcount], flashBox[flash_vcount], *box;
+
+int iconHeight;
+Window sizeWin;
+int sizeWidth, sizeHeight;
+int variableWidth;
+int sizeX, sizeY; /* Where the size window is */
+Pixmap behindSize = 0; /* And what it obscures */
+
+Window oldfocus;
+
+InitializeWm()
+{
+ SetUpSizeWindow();
+ SetUpBox();
+ StoreWmCursors();
+
+ FocusOn(RootWindow);
+ oldfocus = 0;
+}
+
+SetUpSizeWindow()
+{
+ FontInfo finfo;
+ register int i, minwid, maxwid;
+ short cwid[10];
+
+ status = XQueryFont(sizefont, &finfo);
+ if (status == 0) Error("Couldn't query size font in SetUpSizeWindow");
+
+ status = XCharWidths("0123456789x", 11, sizefont, cwid);
+ if (status == 0) Error("Couldn't get char widths in SetUpSizeWindow");
+
+ minwid = 99999;
+ maxwid = 0;
+ for (i = 0; i <= 10; i++) {
+ if (cwid[i] < minwid) minwid = cwid[i];
+ else if (cwid[i] > maxwid) maxwid = cwid[i];
+ }
+
+ variableWidth = (minwid != maxwid);
+
+ sizeWidth = 7 * maxwid + 4;
+ sizeHeight = finfo.height + 4;
+
+ sizeWin = XCreateWindow(RootWindow, 0, 0,
+ sizeWidth - 2, sizeHeight - 2,
+ 1, bgPixmap, fgPixmap);
+ if (sizeWin == 0) Error("Couldn't create sizeWin in SetUpSizeWindow");
+
+ status = XQueryFont(iconfont, &finfo);
+ if (status == 0) Error("Couldn't query icon font in SetUpSizeWindow");
+
+ iconHeight = finfo.height + 8;
+}
+
+SetUpBox()
+{
+ register int i;
+
+ if (freeze) {
+ vcount = solid_vcount;
+ i = solid_vcount - 1;
+ box = solidBox;
+ } else {
+ vcount = flash_vcount;
+ i = flash_vcount - 1;
+ box = flashBox;
+ }
+
+ box[i--].flags = VertexRelative | VertexDrawLastPoint;
+ while (i > 0) box[i--].flags = VertexRelative;
+ box[0].flags = 0;
+
+ if (!freeze) box[solid_vcount-1].flags |= VertexDrawLastPoint;
+}
+
+StoreWmCursors()
+{
+ iconCursor = XCreateCursor(icon_width, icon_height,
+ (caddr_t) icon_bits, (caddr_t) NULL,
+ 8, 8,
+ WhitePixel, BlackPixel,
+ GXcopyInverted);
+ if (iconCursor == 0) {
+ Error("Couldn't store iconCursor in StoreWmCursors");
+ }
+ textCursor = XCreateCursor(xterm_width, xterm_height,
+ (caddr_t) xterm_bits, (caddr_t) xterm_mask_bits,
+ 8, 8,
+ bgColor, fgColor,
+ GXcopyInverted);
+ if (textCursor == 0) {
+ Error("Couldn't store textCursor in StoreWmCursors");
+ }
+}
+
+/* ARGSUSED */
+
+Raise(which, loc, w, winfo)
+ int which;
+ Locator loc;
+ Window w;
+ WindowInfo *winfo;
+{
+ BEvent newbutton;
+ Window neww;
+
+ if (w == RootWindow) return;
+
+ GetButton(&newbutton);
+ if (!MatchUp(newbutton, which)) return;
+
+ InterpretLocatorW(RootWindow, &neww, newbutton.location);
+ if (neww != w) return;
+
+ if (popup) UnmapPopup();
+
+ XRaiseWindow(w);
+}
+
+/* ARGSUSED */
+
+Lower(which, loc, w, winfo)
+ int which;
+ Locator loc;
+ Window w;
+ WindowInfo *winfo;
+{
+ BEvent newbutton;
+ Window neww;
+
+ if (w == RootWindow) return;
+
+ GetButton(&newbutton);
+ if (!MatchUp(newbutton, which)) return;
+
+ InterpretLocatorW(RootWindow, &neww, newbutton.location);
+ if (neww != w) return;
+
+ if (popup) UnmapPopup();
+
+ XLowerWindow(w);
+}
+
+Move(which, loc, w, winfo)
+ int which;
+ Locator loc;
+ Window w;
+ WindowInfo *winfo;
+{
+ Window subwindow;
+ BEvent newbutton;
+ int x, y, oldx, oldy, left, top;
+ int stop = FALSE;
+
+ if (w == RootWindow) return;
+
+ InterpretLocatorXY(RootWindow, &x, &y, loc);
+
+ left = winfo->x;
+ top = winfo->y;
+
+ oldx = x;
+ oldy = y;
+
+ StoreBox(left, top, winfo->width + (winfo->bdrwidth << 1) - 1,
+ winfo->height + (winfo->bdrwidth << 1) - 1);
+
+ /* If we're willing to freeze the server, we don't flicker the box.
+ If not, we do double inverts that draw and then erase the box,
+ so we have to do them more often */
+
+ if (freeze) XGrabServer();
+ DrawBox();
+
+ while (!stop) {
+ /* If we've moved at all, change the box and reset old x,y */
+
+ if (x != oldx || y != oldy) {
+ if (freeze) DrawBox(); /* Erase */
+ oldx = x;
+ oldy = y;
+ box[0].x = left;
+ box[0].y = top;
+ DrawBox(); /* Redraw */
+ } else if (!freeze) DrawBox();
+
+ /* Find the new x,y. If there's an event, use that; otherwise
+ query the mouse */
+
+ if (XPending()) {
+ if (!GetEvent(&newbutton)) {
+ QueryMouse(RootWindow, &x, &y, &subwindow);
+ }
+ else if (!MatchUp(newbutton, which)) break;
+ else {
+ x = newbutton.x;
+ y = newbutton.y;
+ stop = TRUE;
+ }
+ } else QueryMouse(RootWindow, &x, &y, &subwindow);
+
+ left += x - oldx;
+ top += y - oldy;
+ }
+
+ if (freeze) {
+ DrawBox(); /* Erase */
+ XUngrabServer();
+ }
+
+ if (!stop) return;
+
+ if (popup) UnmapPopup();
+
+ XMoveWindow(w, left, top);
+
+ FrameFocus(); /* Fix up frame */
+}
+
+Resize(which, loc, w, winfo)
+ int which;
+ Locator loc;
+ Window w;
+ WindowInfo *winfo;
+{
+ BEvent newbutton;
+ int t;
+ int baseheight, hinc, basewidth, winc;
+ int x0, y0; /* Initial x,y of mouse */
+ int fixedx, fixedy; /* x,y of fixed corner */
+ int movex, movey; /* x,y of movable corner */
+ int limitx, limity; /* limit to movement due to min window size */
+ int oldx, oldy; /* previous location of moving corner */
+ int newx, newy; /* new location of moving corner */
+ int lastx, lasty; /* previous cursor location */
+ int x, y; /* new cursor location */
+ int dx, dy; /* flags indicating movement direction */
+ int width, height; /* width & height of window */
+ int usesize, stop = FALSE;
+ Window subwindow;
+
+ if (w == RootWindow) return;
+
+ /* Find out about window and get resizing info */
+
+ status = XGetResizeHint(w, &basewidth, &baseheight, &winc, &hinc);
+ if (status == 0) Error("Couldn't get resize hint in Resize");
+ InterpretLocatorXY(RootWindow, &x0, &y0, loc);
+
+ /* Initially fixedx is left, fixedy top, movex right, and
+ movey bottom */
+
+ fixedx = winfo->x;
+ fixedy = winfo->y;
+ width = winfo->width + (winfo->bdrwidth << 1) - 1;
+ height = winfo->height + (winfo->bdrwidth << 1) - 1;
+ movex = fixedx + width;
+ movey = fixedy + height;
+
+ /* We only will use a size window if the increments are large
+ enough and the current window size corresponds to the hints */
+
+ usesize = (winc > 3 && hinc > 3 &&
+ (winfo->width - basewidth) % winc == 0 &&
+ (winfo->height - baseheight) % hinc == 0);
+
+ if (basewidth == 0 && winc == 1 && baseheight == 0 && hinc == 1) {
+ basewidth = 1;
+ baseheight = 1;
+ }
+
+ /* movex,y are still right and bottom */
+
+ limitx = movex - winfo->width + basewidth + winc;
+ limity = movey - winfo->height + baseheight + hinc;
+
+ basewidth += (winfo->bdrwidth << 1) - 1;
+ baseheight += (winfo->bdrwidth << 1) - 1;
+
+ /* Calculate the moving directions dx,dy */
+
+ CalculateMovingEdges(&dx, &dy, x0, fixedx, movex,
+ y0, fixedy, movey, winfo);
+
+ /* Figure out which edges to move depending upon which ninth
+ the cursor is in. Adjust fixed and move edges accordingly:
+
+ dx,y indicate which edges are fixed. Values:
+
+ dx fixedx movex dy fixedy movey
+ 1,0 left right 1,0 top bottom
+ -1 right left -1 bottom top
+
+ A value of 0 means that both edges are fixed in that direction */
+
+ /* If we're moving left edge, switch */
+
+ if (dx == -1) {
+ limitx = movex - (limitx - fixedx);
+ t = fixedx; fixedx = movex; movex = t;
+ width = -width;
+ }
+
+ /* If we're moving top edge, switch */
+
+ if (dy == -1) {
+ limity = movey - (limity - fixedy);
+ t = fixedy; fixedy = movey; movey = t;
+ height = -height;
+ }
+
+ oldx = newx = movex;
+ oldy = newy = movey;
+ lastx = x0;
+ lasty = y0;
+
+ StoreBox(fixedx, fixedy, width, height);
+
+ /* If we're willing to freeze the server, we don't flicker the box.
+ If not, we do double inverts that draw and then erase the box,
+ so we have to do them more often */
+
+ if (freeze) XGrabServer();
+ DrawBox(); /* Draw box */
+
+ if (usesize) {
+ CreateSize (dx, dy, fixedx, fixedy, winfo);
+ FillinSize ((abs(width) - basewidth) / winc,
+ (abs(height) - baseheight) / hinc);
+ }
+
+ /* Loop until a button event occurs */
+
+ while (!stop) {
+ /* If we've moved at all, change the box, fill in the
+ size window and reset old x,y */
+
+ if (newx != oldx || newy != oldy) {
+ if (freeze) DrawBox(); /* Erase */
+ StoreBox(fixedx, fixedy, width, height);
+
+ if (usesize) {
+ FillinSize ((abs(width) - basewidth) / winc,
+ (abs(height) - baseheight) / hinc);
+ }
+ oldx = newx;
+ oldy = newy;
+ DrawBox(); /* Redraw */
+ } else if (!freeze) DrawBox();
+
+ /* Find the cursor x,y -- by an event if there is one, by
+ querying if not */
+
+ if (XPending()) {
+ if (!GetEvent(&newbutton)) {
+ QueryMouse(RootWindow, &x, &y, &subwindow);
+ }
+ else if (!MatchUp(newbutton, which)) break;
+ else {
+ x = newbutton.x;
+ y = newbutton.y;
+ stop = TRUE;
+ }
+ } else QueryMouse(RootWindow, &x, &y, &subwindow);
+
+ /* If we haven't moved since last time, skip the rest */
+
+ if (x == lastx && y == lasty) continue;
+
+ lastx = x;
+ lasty = y;
+
+ newx = CalculateChange(dx, x, x0, winc, limitx, movex, oldx);
+ newy = CalculateChange(dy, y, y0, hinc, limity, movey, oldy);
+ width += newx - oldx;
+ height += newy - oldy;
+ }
+
+ if (freeze) {
+ DrawBox(); /* Erase */
+ XUngrabServer();
+ }
+
+ if (!stop) {
+ if (usesize) DestroySize();
+ return;
+ }
+
+
+ if (newx == movex && newy == movey) { /* i.e. no change */
+ if (usesize) DestroySize();
+ XRaiseWindow(w);
+ } else {
+
+ /* Re-exchange things so that fixedx,y is the left top */
+
+ if (newx < fixedx) {
+ t = fixedx; fixedx = newx; newx = t;
+ }
+ if (newy < fixedy) {
+ t = fixedy; fixedy = newy; newy = t;
+ }
+
+ /* Calculate new width and height. */
+
+ width = newx - fixedx + 1 - (winfo->bdrwidth << 1);
+ height = newy - fixedy + 1 - (winfo->bdrwidth << 1);
+
+ if (usesize) DestroySize();
+
+ if (popup) UnmapPopup();
+
+ XConfigureWindow(w, fixedx, fixedy, width, height);
+ FrameFocus();
+ }
+}
+
+CalculateMovingEdges(dx, dy, x0, fixedx, movex, y0, fixedy, movey, winfo)
+ int *dx, *dy, x0, fixedx, movex, y0, fixedy, movey;
+ WindowInfo *winfo;
+{
+ int xthird, ythird;
+
+ *dx = *dy = 1;
+
+ /* If we're closer to the left than to the right, switch */
+
+ if (x0 - fixedx < movex - x0) *dx = -1;
+
+ /* If we're closer to the top than the bottom, switch */
+
+ if (y0 - fixedy < movey - y0) *dy = -1;
+
+ /* Now, watch closely! We take the offset from the point to the
+ left edge, multiply by 3 and divide by the width. This gives
+ a value of 0, 1, or 2 depending if the point is in the left,
+ middle, or right thirds. Do the same for y. Add them together.
+ If the result is odd, the point must be in one of the edge ninths,
+ rather than a corner ninth or the middle ninth. Figure out
+ which one and set dx,y accordingly. (gag) */
+
+ if (winfo->width > 2 && winfo->height > 2) {
+ xthird = ((x0 - winfo->x - winfo->bdrwidth) * 3) / winfo->width;
+ ythird = ((y0 - winfo->y - winfo->bdrwidth) * 3) / winfo->height;
+
+ if ((xthird + ythird) & 1) {
+ if (xthird & 1) *dx = 0;
+ else *dy = 0;
+ }
+ }
+}
+
+FillinSize(hsize, vsize)
+ register int hsize, vsize;
+{
+ static char sizeText[7] = {'0', '0', '0', 'x', '0', '0', '0'};
+
+ sizeText[0] = vsize / 100 + '0';
+ sizeText[1] = (vsize / 10) % 10 + '0';
+ sizeText[2] = vsize % 10 + '0';
+ sizeText[4] = hsize / 100 + '0';
+ sizeText[5] = (hsize / 10) % 10 + '0';
+ sizeText[6] = hsize % 10 + '0';
+ if (variableWidth) XClear(sizeWin);
+ XText(sizeWin, 1, 1, sizeText, sizeof(sizeText), sizefont,
+ bgColor, fgColor);
+}
+
+CreateSize(dx, dy, fixedx, fixedy, winfo)
+ int dx, dy, fixedx, fixedy;
+ WindowInfo *winfo;
+{
+ int px, py; /* Size x, y */
+
+ /* If a corner is being moved, put the size window in the opposite
+ corner. If an edge, put in middle of opposite edge. */
+
+ if (dx > 0) px = fixedx + winfo->bdrwidth;
+ else if (dx < 0) px = fixedx - sizeWidth - winfo->bdrwidth + 1;
+ else px = winfo->x + winfo->bdrwidth +
+ (winfo->width - sizeWidth) / 2;
+
+ if (dy > 0) py = fixedy + winfo->bdrwidth;
+ else if (dy < 0) py = fixedy - sizeHeight - winfo->bdrwidth + 1;
+ else py = winfo->y + winfo->bdrwidth +
+ (winfo->height - sizeHeight) / 2;
+
+ if (freeze) {
+ sizeX = px;
+ sizeY = py;
+ behindSize = XPixmapSave(RootWindow, px, py,
+ sizeWidth, sizeHeight);
+ /* Ok to return 0; this means it wasn't on the screen */
+ }
+
+ XMoveWindow(sizeWin, px, py);
+ XMapWindow(sizeWin);
+}
+
+DestroySize()
+{
+ if (behindSize != 0) {
+ XUnmapTransparent(sizeWin);
+ XPixmapPut(RootWindow, 0, 0, sizeX, sizeY, sizeWidth, sizeHeight,
+ behindSize, GXcopy, AllPlanes);
+ XFreePixmap(behindSize);
+ behindSize = 0;
+ } else XUnmapWindow(sizeWin);
+}
+
+int CalculateChange(direction, new, orig, inc, limit, origedge, oldedge)
+ int direction, new, orig, inc, limit, origedge, oldedge;
+{
+ register int d, newedge;
+
+ if (direction) { /* If we're changing this way */
+
+ /* Calculate the change in cursor position in inc units */
+
+ d = abs(new - orig) + (inc >> 1);;
+ d = (d / inc) * inc;
+
+ /* Adjust the new position and check against the limit */
+
+ if (new < orig) {
+ newedge = origedge - d;
+ if (direction > 0 && newedge < limit) newedge = limit;
+ } else {
+ newedge = origedge + d;
+ if (direction < 0 && newedge > limit) newedge = limit;
+ }
+ } else newedge = oldedge;
+
+ return(newedge);
+}
+
+/* ARGSUSED */
+
+Iconify(which, loc, w, winfo)
+ int which;
+ Locator loc;
+ Window w;
+ WindowInfo *winfo;
+{
+ int x, y;
+ BEvent newbutton;
+ int width, height;
+ char *iconName;
+ WindowInfo iconInfo;
+ Window icon = 0;
+ struct _xy {short x, y;} *xy; /* To turn locators into xy pairs */
+ int downx, downy;
+
+ if (w == RootWindow) return;
+
+ /* First change the cursor into the icon cursor */
+
+ status = XGrabMouse(RootWindow, iconCursor,
+ ButtonPressed | ButtonReleased);
+ if (status == 0) Error("Couldn't grab mouse in Iconify");
+
+ /* Then wait for the upbutton; if it doesn't occur abort */
+
+ GetButton(&newbutton);
+ if (!MatchUp(newbutton, which)) return;
+ x = newbutton.x;
+ y = newbutton.y;
+
+ /* See if it already has an associated icon window;
+ if not, figure out the size */
+
+ if (winfo->assoc_wind == 0) {
+ height = iconHeight;
+
+ /* Now get the name of the window */
+
+ status = XFetchName(w, &iconName);
+ if (status == 0) Error("Couldn't fetch name in Iconify");
+
+ width = XQueryWidth(iconName, iconfont);
+ if (width == 0) width = height;
+ else width += 8;
+
+ } else {
+ icon = winfo->assoc_wind;
+ QueryWindow(icon, &iconInfo);
+ height = iconInfo.height;
+ width = iconInfo.width;
+
+ xy = (struct _xy *) &loc;
+ downx = xy->x;
+ downy = xy->y;
+ }
+
+ /* Center the icon on the new cursor position */
+
+ x -= width >> 1 + 1;
+ if (x < 0) x = 0;
+ if (x + width + 2 > screen_width) x = screen_width - width - 2;
+
+ y -= height >> 1 + 1;
+ if (y < 0) y = 0;
+ if (y + height + 2 > screen_height) y = screen_height - height - 2;
+
+ /* Open the icon, give it a text cursor, choose key events, and
+ map it */
+
+ if (icon == 0) {
+ icon = XCreateWindow(RootWindow, x, y, width, height,
+ 1, fgPixmap, gray);
+ if (icon == 0) Error("Couldn't create icon in Iconify");
+ XSelectInput(icon, KeyPressed|ExposeWindow|UnmapWindow);
+ XDefineCursor(icon, textCursor);
+ XSetIconWindow(w, icon);
+ } else {
+ xy = (struct _xy *) &(newbutton.location);
+ if (abs(xy->x - downx) > iconifyDelta ||
+ abs(xy->y - downy) > iconifyDelta) {
+ XMoveWindow(icon, x, y);
+ }
+ }
+
+ if (popup) UnmapPopup();
+
+ XMapWindow(icon);
+ XUnmapWindow(w);
+
+ /* If the iconified window was the focus, change to the background */
+
+ if (focus == w) FocusOn(RootWindow);
+ FrameFocus();
+}
+
+/* ARGSUSED */
+
+Deiconify(which, loc, w, winfo)
+ int which;
+ Locator loc;
+ Window w;
+ WindowInfo *winfo;
+{
+ BEvent newbutton;
+ Window neww;
+
+ if (w == RootWindow) return;
+
+ GetButton(&newbutton);
+
+ if (!MatchUp(newbutton, which)) return;
+
+ InterpretLocatorW(RootWindow, &neww, newbutton.location);
+ if (neww != w) return;
+
+ if (popup) UnmapPopup();
+
+ XUnmapWindow(w);
+ XMapWindow(winfo->assoc_wind);
+
+ /* If icon was the focus, change to the window itself */
+
+ if (focus == w) FocusOn(winfo->assoc_wind);
+ FrameFocus();
+}
+
+/* ARGSUSED */
+
+Select(which, loc, w, winfo)
+ int which;
+ Locator loc;
+ Window w;
+ WindowInfo *winfo;
+{
+ BEvent newbutton;
+ Window neww;
+
+ GetButton(&newbutton);
+ if (!MatchUp(newbutton, which)) return;
+
+ InterpretLocatorW(RootWindow, &neww, newbutton.location);
+ if (neww == 0) neww = RootWindow;
+ if (neww != w) return;
+
+ /* See if the current focus is an icon. If not, set oldfocus
+ so we can go back to it if we want to */
+
+ if (focusInfo.type != IsIcon) oldfocus = focus;
+
+ if (popup) UnmapPopup();
+
+ FocusOn(w);
+ FrameFocus(); /* Now frame the focus window */
+ XRaiseWindow(focus);
+}
+
+FocusOn(w)
+ Window w;
+{
+ focus = w;
+ QueryWindow(focus, &focusInfo);
+ XFocusKeyboard(focus);
+}
+
+FrameFocus()
+{
+ if (frameWidth == 0) return; /* Nothing to do */
+
+ /* Remove the frame from around any old focus window first */
+
+ XClear(RootWindow);
+
+ if (focus == RootWindow) return;
+ QueryWindow(focus, &focusInfo); /* Refresh it */
+
+ /* Undo the default clipmode for the base window */
+
+ XClipClipped(RootWindow);
+
+ XPixSet(RootWindow,
+ focusInfo.x - frameWidth, focusInfo.y - frameWidth,
+ focusInfo.width + 2 * (focusInfo.bdrwidth + frameWidth),
+ focusInfo.height + 2 * (focusInfo.bdrwidth + frameWidth),
+ fgColor);
+
+ XClipDrawThrough(RootWindow); /* Put it back */
+}
+
+/* ARGSUSED */
+
+Circulate(which, loc, w, winfo)
+ int which;
+ Locator loc;
+ Window w;
+ WindowInfo *winfo;
+{
+ if (popup) UnmapPopup();
+
+ XCircWindowUp(RootWindow);
+}
+
+EditIconName(be, name)
+ XKeyPressedEvent *be;
+ register char *name;
+{
+ Window w = be->window;
+ short charcode = be->detail;
+ register int nameLen, c;
+ int x0, y0, size;
+ WindowInfo winfo;
+ register char *string;
+ int nbytes;
+ register int i;
+
+ string = XLookupMapping (be, &nbytes);
+ nameLen = (name == NULL) ? 0 : strlen(name);
+
+ for (i = 0; i < nbytes; i++) {
+ c = string[i];
+
+
+ if (c == '\177') { /* a 'delete' */
+ if (nameLen > 0)
+ name[--nameLen] = '\0';
+ /* control-u if you can't read ascii */
+ } else if (c == '\025') {
+ if (nameLen > 0) {
+ *name = '\0';
+ nameLen = 0;
+ }
+
+ } else if (c == '\r') { /* return means reset focus */
+ FocusOn(oldfocus ? oldfocus : RootWindow);
+ oldfocus = 0;
+ FrameFocus();
+
+ } else if (c <= 0)
+ ; /* unknown character, ignore it */
+
+ /* Else append the letter to the name */
+
+ else {
+ if (name == NULL)
+ name = (char *) malloc (nameLen + 2);
+ else
+ name = (char *) realloc(name, nameLen + 2);
+ if (name == NULL) {
+ errno = ENOMEM;
+ perror("newwm:");
+ }
+ name[nameLen] = c;
+ name[++nameLen] = '\0';
+ }
+ }
+
+ QueryWindow(w, &winfo);
+ x0 = winfo.x;
+ y0 = winfo.y;
+
+ size = XQueryWidth(name, iconfont);
+
+ /* Make sure icon is entirely on screen */
+
+ if (x0 < 0) x0 = 0;
+ else if (x0 + size + 10 > screen_width) {
+ x0 = screen_width - size - 10;
+ }
+
+ if (y0 < 0) y0 = 0;
+ else if (y0 + iconHeight + 2 > screen_height) {
+ y0 = screen_height - iconHeight - 2;
+ }
+
+ XConfigureWindow(w, x0, y0, size + 8, iconHeight);
+ XWarpMouse(w, (size+8) >> 1, iconHeight >> 1);
+ FrameFocus(); /* Redraw frame */
+ XStoreName(winfo.assoc_wind, name);
+
+ /* Don't redraw the text yet; the expose event will cause that */
+}
+
+StoreBox (x, y, w, h)
+ int x, y, w, h;
+{
+ box[0].x = x; box[0].y = y;
+ box[1].x = w+2; box[1].y = 0;
+ box[2].x = 0; box[2].y = h+2;
+ box[3].x = -(w+2); box[3].y = 0;
+ box[4].x = 0; box[4].y = -(h+1);
+ box[5].x = w+1; box[5].y = 0;
+ box[6].x = 0; box[6].y = h;
+ box[7].x = -w; box[7].y = 0;
+ box[8].x = 0; box[8].y = -(h-1);
+
+ if (!freeze) {
+ box[9].x = 0; box[9].y = h-1;
+ box[10].x = w; box[10].y = 0;
+ box[11].x = 0; box[11].y = -h;
+ box[12].x = -(w+1); box[12].y = 0;
+ box[13].x = 0; box[13].y = h+1;
+ box[14].x = w+2; box[14].y = 0;
+ box[15].x = 0; box[15].y = -(h+2);
+ box[16].x = -(w+2); box[16].y = 0;
+ }
+}
+
+DrawBox()
+{
+ XDraw(RootWindow, box, vcount, 1, 1, 0,
+ GXinvert, AllPlanes);
+}
+
+InterpretLocator (w, x, y, subw, loc)
+ Window w;
+ Window *subw;
+ Locator loc;
+ int *x, *y;
+{
+ status = XInterpretLocator(w, x, y, subw, loc);
+ if (status == 0) Error("Couldn't interpret in InterpretLocator");
+}
+
+InterpretLocatorW (w, subw, loc)
+ Window w;
+ Window *subw;
+ Locator loc;
+{
+ int x, y;
+
+ status = XInterpretLocator(w, &x, &y, subw, loc);
+ if (status == 0) Error("Couldn't interpret in InterpretLocator");
+}
+
+InterpretLocatorXY (w, x, y, loc)
+ Window w;
+ Locator loc;
+ int *x, *y;
+{
+ Window subw;
+
+ status = XInterpretLocator(w, x, y, &subw, loc);
+ if (status == 0) Error("Couldn't interpret in InterpretLocator");
+}
+
+QueryMouse (w, x, y, subw)
+ Window w;
+ Window *subw;
+ int *x, *y;
+{
+ status = XQueryMouse(w, x, y, subw);
+ if (status == 0) Error("Couldn't query mouse in QueryMouse");
+}
+
+QueryWindow (w, info)
+ Window w;
+ WindowInfo *info;
+{
+ status = XQueryWindow(w, info);
+ if (status == 0) Error("Couldn't query windown in QueryWindow");
+}