1: #ifndef lint 2: static char *rcsid_Resize_c = "$Header: Resize.c,v 10.3 86/02/01 16:23:45 tony Rel $"; 3: #endif lint 4: 5: /************************************************************************ 6: * * 7: * Copyright (c) 1986 by * 8: * Digital Equipment Corporation, Maynard, MA * 9: * All Rights Reserved. * 10: * * 11: * Permission to use, copy, modify, and distribute this software * 12: * and its documentation is hereby granted only to licensees of * 13: * The Regents of the University of California pursuant to their * 14: * license agreement for the Berkeley Software Distribution * 15: * provided that the following appears on all copies. * 16: * * 17: * "LICENSED FROM DIGITAL EQUIPMENT CORPORATION * 18: * COPYRIGHT (C) 1986 * 19: * DIGITAL EQUIPMENT CORPORATION * 20: * MAYNARD, MA * 21: * ALL RIGHTS RESERVED. * 22: * * 23: * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT * 24: * NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL * 25: * EQUIPMENT CORPORATION. DIGITAL MAKES NO REPRESENTATIONS * 26: * ABOUT SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. IT IS * 27: * SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. * 28: * * 29: * IF THE UNIVERSITY OF CALIFORNIA OR ITS LICENSEES MODIFY * 30: * THE SOFTWARE IN A MANNER CREATING DERIVATIVE COPYRIGHT * 31: * RIGHTS APPROPRIATE COPYRIGHT LEGENDS MAY BE PLACED ON THE * 32: * DERIVATIVE WORK IN ADDITION TO THAT SET FORTH ABOVE." * 33: * * 34: ************************************************************************/ 35: 36: 37: /* 38: * MODIFICATION HISTORY 39: * 40: * 000 -- M. Gancarz, DEC Ultrix Engineering Group 41: */ 42: 43: #ifndef lint 44: static char *sccsid = "@(#)Resize.c 3.8 1/24/86"; 45: #endif 46: 47: #include "uwm.h" 48: 49: Bool Resize(window, mask, button, x0, y0) 50: Window window; /* Event window. */ 51: int mask; /* Button/key mask. */ 52: short button; /* Button event detail. */ 53: int x0, y0; /* Event mouse position. */ 54: { 55: register WindowInfo window_info; /* Event window info. */ 56: register WindowInfo assoc_info; /* Icon's associated window info. */ 57: int d; /* ??? */ 58: int t; /* ??? */ 59: int x, y; /* ??? */ 60: int h0, hinc, w0, winc, wadd, hadd; /* ??? */ 61: int x1, y1, x2, y2; /* ??? */ 62: int mx, my; /* ??? */ 63: int ox, oy; /* ??? */ 64: int lx, ly; /* ??? */ 65: int pop_x, pop_y; /* ??? */ 66: int hsize, vsize; /* ??? */ 67: int dx, dy; /* ??? */ 68: int num_vectors; /* Number of vectors to XDraw. */ 69: Window assoc; /* Window represented by the icon. */ 70: Window sub_win; /* Mouse query sub window. */ 71: XButtonEvent button_event; /* Button event packet. */ 72: Vertex box[MAX_BOX_VECTORS]; /* Box drawing vertex buffer. */ 73: Vertex zap[MAX_ZAP_VECTORS]; /* Zap drawing vertex buffer. */ 74: Bool domult; /* ??? */ 75: Bool stop; /* Should the window stop changing? */ 76: 77: /* 78: * Do nothing if the event window is the root window. 79: */ 80: if (window == RootWindow) 81: return(FALSE); 82: 83: /* 84: * Gather info about the event window. 85: */ 86: status = XQueryWindow(window, &window_info); 87: if (status == FAILURE) return(FALSE); 88: 89: /* 90: * Do not resize an icon window. 91: */ 92: if (window_info.type == IsIcon) 93: return(FALSE); 94: 95: /* 96: * Clear the vector buffers. 97: */ 98: bzero(box, sizeof(box)); 99: if (Zap) bzero(zap, sizeof(zap)); 100: 101: /* 102: * If we are here then we have a resize operation in progress. 103: */ 104: 105: /* 106: * Turn on the resize cursor. 107: */ 108: status = XGrabButton(RootWindow, ArrowCrossCursor, mask, EVENTMASK); 109: if (status == FAILURE) { 110: Error("Resize -> Unable to grab button and change cursor."); 111: } 112: 113: /* 114: * Get the event window resize hint. 115: */ 116: XGetResizeHint(window, &w0, &h0, &winc, &hinc); 117: 118: /* 119: * If I ever have the time to REALLY figure the rest of this out I will 120: * comment it better. 121: */ 122: wadd = winc >> 1; 123: hadd = hinc >> 1; 124: x1 = window_info.x; 125: y1 = window_info.y; 126: x2 = x1 + window_info.width + (window_info.bdrwidth << 1) - 1; 127: y2 = y1 + window_info.height + (window_info.bdrwidth << 1) - 1; 128: domult = (winc > 3 && hinc > 3 && 129: (window_info.width - w0) % winc == 0 && 130: (window_info.height - h0) % hinc == 0) ? TRUE : FALSE; 131: if (w0 == 0 && winc == 1 && h0 == 0 && hinc == 1) { 132: w0 = h0 = 1; 133: } 134: mx = x2 - window_info.width + w0 + winc; 135: my = y2 - window_info.height + h0 + hinc; 136: w0 += (window_info.bdrwidth << 1) - 1; 137: h0 += (window_info.bdrwidth << 1) - 1; 138: x = x2; 139: y = y2; 140: dx = dy = 1; 141: if (x0 - x1 < x2 - x0) { 142: dx = -1; 143: x = x1; 144: mx = x2 - (mx - x1); 145: t = x1; x1 = x2; x2 = t; 146: } 147: if (y0 - y1 < y2 - y0) { 148: dy = -1; 149: y = y1; 150: my = y2 - (my - y1); 151: t = y1; y1 = y2; y2 = t; 152: } 153: ox = ((x0 - window_info.x - window_info.bdrwidth) * 3) / 154: window_info.width; 155: oy = ((y0 - window_info.y - window_info.bdrwidth) * 3) / 156: window_info.height; 157: if (window_info.width > 2 && window_info.height > 2 && ((ox + oy) & 1)) { 158: if (ox & 1) 159: dx = 0; 160: else 161: dy = 0; 162: } 163: 164: if (Grid) { 165: num_vectors = StoreGridBox( 166: box, 167: MIN(x1, x), MIN(y1, y), 168: MAX(x1, x), MAX(y1, y) 169: ); 170: } 171: else { 172: num_vectors = StoreBox( 173: box, 174: MIN(x1, x), MIN(y1, y), 175: MAX(x1, x), MAX(y1, y) 176: ); 177: } 178: 179: /* 180: * If we freeze the server, then we will draw solid 181: * lines instead of flickering ones during resizing. 182: */ 183: if (Freeze) XGrabServer(); 184: 185: /* 186: * Process any pending exposure events before drawing the box. 187: */ 188: while (QLength() > 0) { 189: XPeekEvent(&button_event); 190: if (button_event.window == RootWindow) 191: break; 192: GetButton(&button_event); 193: } 194: 195: /* 196: * Now draw the box. 197: */ 198: DrawBox(); 199: Frozen = window; 200: 201: stop = FALSE; 202: ox = oy = lx = ly = -1; 203: 204: while (!stop) { 205: if (x != ox || y != oy) { 206: 207: /* 208: * If we've frozen the server, then erase 209: * the old box. 210: */ 211: if (Freeze) 212: DrawBox(); 213: 214: if (Grid) { 215: num_vectors = StoreGridBox( 216: box, 217: MIN(x1, x), MIN(y1, y), 218: MAX(x1, x), MAX(y1, y) 219: ); 220: } 221: else { 222: num_vectors = StoreBox( 223: box, 224: MIN(x1, x), MIN(y1, y), 225: MAX(x1, x), MAX(y1, y) 226: ); 227: } 228: 229: if (Freeze) 230: DrawBox(); 231: 232: if (domult) { 233: hsize = (abs(x - x1) - w0) / winc; 234: vsize = (abs(y - y1) - h0) / hinc; 235: PText[0] = hsize / 100 + '0'; 236: PText[1] = (hsize / 10) % 10 + '0'; 237: PText[2] = hsize % 10 + '0'; 238: PText[4] = vsize / 100 + '0'; 239: PText[5] = (vsize / 10) % 10 + '0'; 240: PText[6] = vsize % 10 + '0'; 241: 242: /* 243: * If the font is not fixed width we have to 244: * clear the window to guarantee that the characters 245: * that were there before are erased. 246: */ 247: if (!(PFontInfo.fixedwidth)) XClear(Pop); 248: XTextPad ( 249: Pop, 250: PPadding, PPadding, 251: PText, PTextSize, 252: PFont, 0, 0, 253: PTextForground, PTextBackground, 254: GXcopy, AllPlanes 255: ); 256: } 257: ox = x; 258: oy = y; 259: } 260: 261: if (!Freeze) { 262: DrawBox(); 263: DrawBox(); 264: } 265: 266: if (XPending() && GetButton(&button_event)) { 267: 268: if (Freeze) { 269: DrawBox(); 270: Frozen = (Window)0; 271: XUngrabServer(); 272: } 273: 274: if ( 275: (button_event.type == ButtonReleased) && 276: ((button_event.detail & ValueMask) == button) 277: ){ 278: x = button_event.x; 279: y = button_event.y; 280: stop = TRUE; 281: } 282: else { 283: if (domult) { 284: XUnmapWindow(Pop); 285: } 286: Grab(mask); 287: return(TRUE); 288: } 289: } 290: else { 291: XUpdateMouse(RootWindow, &x, &y, &sub_win); 292: } 293: 294: if (x == lx && y == ly) { 295: x = ox; 296: y = oy; 297: continue; 298: } 299: 300: lx = x; 301: ly = y; 302: 303: if (dx) 304: ox = -1; 305: else 306: oy = -1; 307: if (domult) { 308: if (dx > 0) 309: pop_x = x1 + window_info.bdrwidth; 310: else if (dx < 0) 311: pop_x = x1 - PWidth - window_info.bdrwidth + 1; 312: else 313: pop_x = window_info.x + window_info.bdrwidth + 314: (window_info.width - PWidth) / 2; 315: if (dy > 0) 316: pop_y = y1 + window_info.bdrwidth; 317: else if (dy < 0) 318: pop_y = y1 - PHeight - window_info.bdrwidth + 1; 319: else 320: pop_y = window_info.y + window_info.bdrwidth + 321: (window_info.height - PHeight) / 2; 322: XMoveWindow(Pop, pop_x, pop_y); 323: XMapWindow(Pop); 324: } 325: 326: if (dx) { 327: if ((d = abs(x - x0) + wadd) < 0) 328: d = 0; 329: d = (d / winc) * winc; 330: if (x < x0) { 331: x = x2 - d; 332: if (dx > 0 && x < mx) 333: x = mx; 334: } else { 335: x = x2 + d; 336: if (dx < 0 && x > mx) 337: x = mx; 338: } 339: } else 340: x = ox; 341: if (dy) { 342: if ((d = abs(y - y0) + hadd) < 0) 343: d = 0; 344: d = (d / hinc) * hinc; 345: if (y < y0) { 346: y = y2 - d; 347: if (dy > 0 && y < my) 348: y = my; 349: } else { 350: y = y2 + d; 351: if (dy < 0 && y > my) 352: y = my; 353: } 354: } else 355: y = oy; 356: } 357: if (x == x2 && y == y2) { 358: XUnmapWindow(Pop); 359: XRaiseWindow(window); 360: } else { 361: if (x < x1) { 362: t = x1; x1 = x; x = t; 363: } 364: if (y < y1) { 365: t = y1; y1 = y; y = t; 366: } 367: dx = x - x1 + 1 - (window_info.bdrwidth << 1); 368: dy = y - y1 + 1 - (window_info.bdrwidth << 1); 369: if ( 370: (PWidth > window_info.width) || 371: (PHeight > window_info.height) || 372: (PWidth > dx) || 373: (PHeight > dy) 374: ) { 375: XUnmapWindow(Pop); 376: } 377: else { 378: XUnmapTransparent(Pop); 379: } 380: XConfigureWindow(window, x1, y1, dx, dy); 381: } 382: Grab(mask); 383: return(TRUE); 384: }