BSD 4_3 release
[unix-history] / usr / contrib / X / uwm / Resize.c
#ifndef lint
static char *rcsid_Resize_c = "$Header: Resize.c,v 10.3 86/02/01 16:23:45 tony Rel $";
#endif lint
/************************************************************************
* *
* Copyright (c) 1986 by *
* Digital Equipment Corporation, Maynard, MA *
* All Rights Reserved. *
* *
* Permission to use, copy, modify, and distribute this software *
* and its documentation is hereby granted only to licensees of *
* The Regents of the University of California pursuant to their *
* license agreement for the Berkeley Software Distribution *
* provided that the following appears on all copies. *
* *
* "LICENSED FROM DIGITAL EQUIPMENT CORPORATION *
* COPYRIGHT (C) 1986 *
* DIGITAL EQUIPMENT CORPORATION *
* MAYNARD, MA *
* ALL RIGHTS RESERVED. *
* *
* THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT *
* NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL *
* EQUIPMENT CORPORATION. DIGITAL MAKES NO REPRESENTATIONS *
* ABOUT SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. IT IS *
* SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. *
* *
* IF THE UNIVERSITY OF CALIFORNIA OR ITS LICENSEES MODIFY *
* THE SOFTWARE IN A MANNER CREATING DERIVATIVE COPYRIGHT *
* RIGHTS APPROPRIATE COPYRIGHT LEGENDS MAY BE PLACED ON THE *
* DERIVATIVE WORK IN ADDITION TO THAT SET FORTH ABOVE." *
* *
************************************************************************/
/*
* MODIFICATION HISTORY
*
* 000 -- M. Gancarz, DEC Ultrix Engineering Group
*/
#ifndef lint
static char *sccsid = "@(#)Resize.c 3.8 1/24/86";
#endif
#include "uwm.h"
Bool Resize(window, mask, button, x0, y0)
Window window; /* Event window. */
int mask; /* Button/key mask. */
short button; /* Button event detail. */
int x0, y0; /* Event mouse position. */
{
register WindowInfo window_info; /* Event window info. */
register WindowInfo assoc_info; /* Icon's associated window info. */
int d; /* ??? */
int t; /* ??? */
int x, y; /* ??? */
int h0, hinc, w0, winc, wadd, hadd; /* ??? */
int x1, y1, x2, y2; /* ??? */
int mx, my; /* ??? */
int ox, oy; /* ??? */
int lx, ly; /* ??? */
int pop_x, pop_y; /* ??? */
int hsize, vsize; /* ??? */
int dx, dy; /* ??? */
int num_vectors; /* Number of vectors to XDraw. */
Window assoc; /* Window represented by the icon. */
Window sub_win; /* Mouse query sub window. */
XButtonEvent button_event; /* Button event packet. */
Vertex box[MAX_BOX_VECTORS]; /* Box drawing vertex buffer. */
Vertex zap[MAX_ZAP_VECTORS]; /* Zap drawing vertex buffer. */
Bool domult; /* ??? */
Bool stop; /* Should the window stop changing? */
/*
* Do nothing if the event window is the root window.
*/
if (window == RootWindow)
return(FALSE);
/*
* Gather info about the event window.
*/
status = XQueryWindow(window, &window_info);
if (status == FAILURE) return(FALSE);
/*
* Do not resize an icon window.
*/
if (window_info.type == IsIcon)
return(FALSE);
/*
* Clear the vector buffers.
*/
bzero(box, sizeof(box));
if (Zap) bzero(zap, sizeof(zap));
/*
* If we are here then we have a resize operation in progress.
*/
/*
* Turn on the resize cursor.
*/
status = XGrabButton(RootWindow, ArrowCrossCursor, mask, EVENTMASK);
if (status == FAILURE) {
Error("Resize -> Unable to grab button and change cursor.");
}
/*
* Get the event window resize hint.
*/
XGetResizeHint(window, &w0, &h0, &winc, &hinc);
/*
* If I ever have the time to REALLY figure the rest of this out I will
* comment it better.
*/
wadd = winc >> 1;
hadd = hinc >> 1;
x1 = window_info.x;
y1 = window_info.y;
x2 = x1 + window_info.width + (window_info.bdrwidth << 1) - 1;
y2 = y1 + window_info.height + (window_info.bdrwidth << 1) - 1;
domult = (winc > 3 && hinc > 3 &&
(window_info.width - w0) % winc == 0 &&
(window_info.height - h0) % hinc == 0) ? TRUE : FALSE;
if (w0 == 0 && winc == 1 && h0 == 0 && hinc == 1) {
w0 = h0 = 1;
}
mx = x2 - window_info.width + w0 + winc;
my = y2 - window_info.height + h0 + hinc;
w0 += (window_info.bdrwidth << 1) - 1;
h0 += (window_info.bdrwidth << 1) - 1;
x = x2;
y = y2;
dx = dy = 1;
if (x0 - x1 < x2 - x0) {
dx = -1;
x = x1;
mx = x2 - (mx - x1);
t = x1; x1 = x2; x2 = t;
}
if (y0 - y1 < y2 - y0) {
dy = -1;
y = y1;
my = y2 - (my - y1);
t = y1; y1 = y2; y2 = t;
}
ox = ((x0 - window_info.x - window_info.bdrwidth) * 3) /
window_info.width;
oy = ((y0 - window_info.y - window_info.bdrwidth) * 3) /
window_info.height;
if (window_info.width > 2 && window_info.height > 2 && ((ox + oy) & 1)) {
if (ox & 1)
dx = 0;
else
dy = 0;
}
if (Grid) {
num_vectors = StoreGridBox(
box,
MIN(x1, x), MIN(y1, y),
MAX(x1, x), MAX(y1, y)
);
}
else {
num_vectors = StoreBox(
box,
MIN(x1, x), MIN(y1, y),
MAX(x1, x), MAX(y1, y)
);
}
/*
* If we freeze the server, then we will draw solid
* lines instead of flickering ones during resizing.
*/
if (Freeze) XGrabServer();
/*
* Process any pending exposure events before drawing the box.
*/
while (QLength() > 0) {
XPeekEvent(&button_event);
if (button_event.window == RootWindow)
break;
GetButton(&button_event);
}
/*
* Now draw the box.
*/
DrawBox();
Frozen = window;
stop = FALSE;
ox = oy = lx = ly = -1;
while (!stop) {
if (x != ox || y != oy) {
/*
* If we've frozen the server, then erase
* the old box.
*/
if (Freeze)
DrawBox();
if (Grid) {
num_vectors = StoreGridBox(
box,
MIN(x1, x), MIN(y1, y),
MAX(x1, x), MAX(y1, y)
);
}
else {
num_vectors = StoreBox(
box,
MIN(x1, x), MIN(y1, y),
MAX(x1, x), MAX(y1, y)
);
}
if (Freeze)
DrawBox();
if (domult) {
hsize = (abs(x - x1) - w0) / winc;
vsize = (abs(y - y1) - h0) / hinc;
PText[0] = hsize / 100 + '0';
PText[1] = (hsize / 10) % 10 + '0';
PText[2] = hsize % 10 + '0';
PText[4] = vsize / 100 + '0';
PText[5] = (vsize / 10) % 10 + '0';
PText[6] = vsize % 10 + '0';
/*
* If the font is not fixed width we have to
* clear the window to guarantee that the characters
* that were there before are erased.
*/
if (!(PFontInfo.fixedwidth)) XClear(Pop);
XTextPad (
Pop,
PPadding, PPadding,
PText, PTextSize,
PFont, 0, 0,
PTextForground, PTextBackground,
GXcopy, AllPlanes
);
}
ox = x;
oy = y;
}
if (!Freeze) {
DrawBox();
DrawBox();
}
if (XPending() && GetButton(&button_event)) {
if (Freeze) {
DrawBox();
Frozen = (Window)0;
XUngrabServer();
}
if (
(button_event.type == ButtonReleased) &&
((button_event.detail & ValueMask) == button)
){
x = button_event.x;
y = button_event.y;
stop = TRUE;
}
else {
if (domult) {
XUnmapWindow(Pop);
}
Grab(mask);
return(TRUE);
}
}
else {
XUpdateMouse(RootWindow, &x, &y, &sub_win);
}
if (x == lx && y == ly) {
x = ox;
y = oy;
continue;
}
lx = x;
ly = y;
if (dx)
ox = -1;
else
oy = -1;
if (domult) {
if (dx > 0)
pop_x = x1 + window_info.bdrwidth;
else if (dx < 0)
pop_x = x1 - PWidth - window_info.bdrwidth + 1;
else
pop_x = window_info.x + window_info.bdrwidth +
(window_info.width - PWidth) / 2;
if (dy > 0)
pop_y = y1 + window_info.bdrwidth;
else if (dy < 0)
pop_y = y1 - PHeight - window_info.bdrwidth + 1;
else
pop_y = window_info.y + window_info.bdrwidth +
(window_info.height - PHeight) / 2;
XMoveWindow(Pop, pop_x, pop_y);
XMapWindow(Pop);
}
if (dx) {
if ((d = abs(x - x0) + wadd) < 0)
d = 0;
d = (d / winc) * winc;
if (x < x0) {
x = x2 - d;
if (dx > 0 && x < mx)
x = mx;
} else {
x = x2 + d;
if (dx < 0 && x > mx)
x = mx;
}
} else
x = ox;
if (dy) {
if ((d = abs(y - y0) + hadd) < 0)
d = 0;
d = (d / hinc) * hinc;
if (y < y0) {
y = y2 - d;
if (dy > 0 && y < my)
y = my;
} else {
y = y2 + d;
if (dy < 0 && y > my)
y = my;
}
} else
y = oy;
}
if (x == x2 && y == y2) {
XUnmapWindow(Pop);
XRaiseWindow(window);
} else {
if (x < x1) {
t = x1; x1 = x; x = t;
}
if (y < y1) {
t = y1; y1 = y; y = t;
}
dx = x - x1 + 1 - (window_info.bdrwidth << 1);
dy = y - y1 + 1 - (window_info.bdrwidth << 1);
if (
(PWidth > window_info.width) ||
(PHeight > window_info.height) ||
(PWidth > dx) ||
(PHeight > dy)
) {
XUnmapWindow(Pop);
}
else {
XUnmapTransparent(Pop);
}
XConfigureWindow(window, x1, y1, dx, dy);
}
Grab(mask);
return(TRUE);
}