1: #include <X/mit-copyright.h> 2: 3: /* Copyright Massachusetts Institute of Technology 1985 */ 4: 5: /* 6: * Change - This subroutine implements window size manipulation 7: * for the X Window System window manager (xwm). 8: * 9: */ 10: 11: #ifndef lint 12: static char *rcsid_Change_c = "$Header: Change.c,v 10.3 86/02/01 16:09:10 tony Rel $"; 13: #endif 14: 15: #include "xwm.h" 16: 17: Bool Change(window, x0, y0) 18: Window window; /* Event window. */ 19: int x0, y0; /* Event mouse coordinates. */ 20: { 21: register WindowInfo window_info; /* Event window info. */ 22: register WindowInfo assoc_info; /* Icon's associated window info. */ 23: int d; /* ??? */ 24: int t; /* ??? */ 25: int x, y; /* ??? */ 26: int h0, hinc, w0, winc, wadd, hadd; /* ??? */ 27: int x1, y1, x2, y2; /* ??? */ 28: int mx, my; /* ??? */ 29: int ox, oy; /* ??? */ 30: int lx, ly; /* ??? */ 31: int pop_x, pop_y; /* ??? */ 32: int hsize, vsize; /* ??? */ 33: int dx, dy; /* ??? */ 34: int status; /* Routine call return status. */ 35: int num_vectors; /* Number of vectors to XDraw. */ 36: Window assoc; /* Window represented by the icon. */ 37: Window sub_win; /* Mouse query sub window. */ 38: XButtonEvent button_event; /* Button event packet. */ 39: Vertex box[MAX_BOX_VECTORS]; /* Box drawing vertex buffer. */ 40: Vertex zap[MAX_ZAP_VECTORS]; /* Zap drawing vertex buffer. */ 41: Bool domult; /* ??? */ 42: Bool stop; /* Should the window stop changing? */ 43: Bool changing; /* Is the window changing? */ 44: 45: /* 46: * Clear the vector buffers. 47: */ 48: bzero(box, sizeof(box)); 49: if (Zap) bzero(zap, sizeof(zap)); 50: 51: /* 52: * Gather info about the event window. 53: */ 54: status = XQueryWindow(window, &window_info); 55: if (status == FAILURE) { 56: /* 57: * If there is a query error, abort the operation. 58: */ 59: return(FALSE); 60: } 61: 62: /* 63: * Check to see if we have an icon window. 64: */ 65: if (window_info.type == IsIcon) { 66: /* 67: * We have an uniconify event, wait for a change in button state. 68: */ 69: assoc = window_info.assoc_wind; 70: 71: /* 72: * Gather info about the assoc window. 73: */ 74: status = XQueryWindow(assoc, &assoc_info); 75: if (status == FAILURE) { 76: /* 77: * If there is a query error, abort the operation. 78: */ 79: return(FALSE); 80: } 81: 82: /* 83: * Spin our wheels untill there is a button event. 84: */ 85: while (!GetButton(&button_event)); 86: 87: /* 88: * Ok, we have a button event, process it. 89: */ 90: if ( 91: (button_event.type == ButtonReleased) && 92: ((button_event.detail & ValueMask) == MiddleButton) 93: ){ 94: /* 95: * Middle button came up, this means we have to uniconify the 96: * window. 97: */ 98: 99: if (Zap) { 100: /* 101: * Store the zap vector buffer. 102: */ 103: num_vectors = StoreZap( 104: zap, 105: assoc_info.x - 1, 106: assoc_info.y - 1, 107: assoc_info.x + assoc_info.width + 108: (assoc_info.bdrwidth << 1), 109: assoc_info.y + assoc_info.height + 110: (assoc_info.bdrwidth << 1), 111: window_info.x - 1, 112: window_info.y - 1, 113: window_info.x + window_info.width + 114: (window_info.bdrwidth << 1), 115: window_info.y + window_info.height + 116: (window_info.bdrwidth << 1) 117: ); 118: } 119: 120: /* 121: * Map the window and synchronize. 122: */ 123: XMapWindow(assoc); 124: 125: if (Zap) { 126: /* 127: * Draw the zap lines. 128: */ 129: XDraw( 130: RootWindow, 131: zap, num_vectors, 132: DRAW_HEIGHT, DRAW_WIDTH, 133: DRAW_VALUE, DRAW_FUNC, DRAW_PLANES 134: ); 135: XDraw( 136: RootWindow, 137: zap, num_vectors, 138: DRAW_HEIGHT, DRAW_WIDTH, 139: DRAW_VALUE, DRAW_FUNC, DRAW_PLANES 140: ); 141: } 142: 143: /* 144: * Unmap the icon window. 145: */ 146: XUnmapWindow(window); 147: 148: /* 149: * This changed the window, return TRUE. 150: */ 151: return(TRUE); 152: } 153: else { 154: /* 155: * Some other button event occured. 156: * Don't change window, return FALSE. 157: */ 158: return(FALSE); 159: } 160: } 161: 162: /* 163: * If we are here then we have a resize operation in progress. 164: */ 165: 166: /* 167: * Get the event window resize hint. 168: */ 169: XGetResizeHint(window, &w0, &h0, &winc, &hinc); 170: 171: /* 172: * If I ever have the time to REALLY figure the rest of this out I will 173: * comment it better. 174: */ 175: wadd = winc >> 1; 176: hadd = hinc >> 1; 177: x1 = window_info.x; 178: y1 = window_info.y; 179: x2 = x1 + window_info.width + (window_info.bdrwidth << 1) - 1; 180: y2 = y1 + window_info.height + (window_info.bdrwidth << 1) - 1; 181: domult = (winc > 3 && hinc > 3 && 182: (window_info.width - w0) % winc == 0 && 183: (window_info.height - h0) % hinc == 0) ? TRUE : FALSE; 184: if (w0 == 0 && winc == 1 && h0 == 0 && hinc == 1) { 185: w0 = 1; 186: h0 = 1; 187: } 188: mx = x2 - window_info.width + w0 + winc; 189: my = y2 - window_info.height + h0 + hinc; 190: w0 += (window_info.bdrwidth << 1) - 1; 191: h0 += (window_info.bdrwidth << 1) - 1; 192: x = x2; 193: y = y2; 194: dx = 1; 195: dy = 1; 196: if (x0 - x1 < x2 - x0) { 197: dx = -1; 198: x = x1; 199: mx = x2 - (mx - x1); 200: t = x1; x1 = x2; x2 = t; 201: } 202: if (y0 - y1 < y2 - y0) { 203: dy = -1; 204: y = y1; 205: my = y2 - (my - y1); 206: t = y1; y1 = y2; y2 = t; 207: } 208: ox = ((x0 - window_info.x - window_info.bdrwidth) * 3) / 209: window_info.width; 210: oy = ((y0 - window_info.y - window_info.bdrwidth) * 3) / 211: window_info.height; 212: if (window_info.width > 2 && window_info.height > 2 && ((ox + oy) & 1)) { 213: if (ox & 1) 214: dx = 0; 215: else 216: dy = 0; 217: } 218: 219: stop = FALSE; 220: changing = FALSE; 221: ox = -1; 222: oy = -1; 223: lx = -1; 224: ly = -1; 225: 226: while (!stop) { 227: if (x != ox || y != oy) { 228: if (Grid) { 229: num_vectors = StoreGridBox( 230: box, 231: min(x1, x), min(y1, y), 232: max(x1, x), max(y1, y) 233: ); 234: } 235: else { 236: num_vectors = StoreBox( 237: box, 238: min(x1, x), min(y1, y), 239: max(x1, x), max(y1, y) 240: ); 241: } 242: if (domult && changing) { 243: hsize = (abs(x - x1) - w0) / winc; 244: vsize = (abs(y - y1) - h0) / hinc; 245: PText[0] = hsize / 100 + '0'; 246: PText[1] = (hsize / 10) % 10 + '0'; 247: PText[2] = hsize % 10 + '0'; 248: PText[4] = vsize / 100 + '0'; 249: PText[5] = (vsize / 10) % 10 + '0'; 250: PText[6] = vsize % 10 + '0'; 251: 252: /* 253: * If the font is not fixed width we have to 254: * clear the window to guarantee that the characters 255: * that were there before are erased. 256: */ 257: if (!(PFontInfo.fixedwidth)) XClear(Pop); 258: XTextPad ( 259: Pop, 260: PPadding, PPadding, 261: PText, PTextSize, 262: PFont, 0, 0, 263: PTextForground, PTextBackground, 264: GXcopy, AllPlanes 265: ); 266: } 267: ox = x; 268: oy = y; 269: } 270: 271: if (changing) { 272: XDraw( 273: RootWindow, 274: box, num_vectors, 275: DRAW_HEIGHT, DRAW_WIDTH, 276: DRAW_VALUE, DRAW_FUNC, DRAW_PLANES 277: ); 278: XDraw( 279: RootWindow, 280: box, num_vectors, 281: DRAW_HEIGHT, DRAW_WIDTH, 282: DRAW_VALUE, DRAW_FUNC, DRAW_PLANES 283: ); 284: } 285: 286: if (XPending() && GetButton(&button_event)) { 287: if ( 288: (button_event.type == ButtonReleased) && 289: ((button_event.detail & ValueMask) == MiddleButton) 290: ){ 291: x = button_event.x; 292: y = button_event.y; 293: stop = TRUE; 294: } 295: else { 296: if (domult && changing) { 297: XUnmapWindow(Pop); 298: } 299: return(FALSE); 300: } 301: } 302: else { 303: XQueryMouse(RootWindow, &x, &y, &sub_win); 304: } 305: 306: if (x == lx && y == ly) { 307: x = ox; 308: y = oy; 309: continue; 310: } 311: 312: lx = x; 313: ly = y; 314: 315: if (!changing) { 316: if (abs(x - x0) < Delta && abs(y - y0) < Delta) { 317: x = ox; 318: y = oy; 319: continue; 320: } 321: if (dx) 322: ox = -1; 323: else 324: oy = -1; 325: changing = TRUE; 326: if (domult) { 327: if (dx > 0) 328: pop_x = x1 + window_info.bdrwidth; 329: else if (dx < 0) 330: pop_x = x1 - PWidth - window_info.bdrwidth + 1; 331: else 332: pop_x = window_info.x + window_info.bdrwidth + 333: (window_info.width - PWidth) / 2; 334: if (dy > 0) 335: pop_y = y1 + window_info.bdrwidth; 336: else if (dy < 0) 337: pop_y = y1 - PHeight - window_info.bdrwidth + 1; 338: else 339: pop_y = window_info.y + window_info.bdrwidth + 340: (window_info.height - PHeight) / 2; 341: XMoveWindow(Pop, pop_x, pop_y); 342: XMapWindow(Pop); 343: } 344: } 345: if (dx) { 346: if ((d = abs(x - x0) + wadd) < 0) 347: d = 0; 348: d = (d / winc) * winc; 349: if (x < x0) { 350: x = x2 - d; 351: if (dx > 0 && x < mx) 352: x = mx; 353: } else { 354: x = x2 + d; 355: if (dx < 0 && x > mx) 356: x = mx; 357: } 358: } else 359: x = ox; 360: if (dy) { 361: if ((d = abs(y - y0) + hadd) < 0) 362: d = 0; 363: d = (d / hinc) * hinc; 364: if (y < y0) { 365: y = y2 - d; 366: if (dy > 0 && y < my) 367: y = my; 368: } else { 369: y = y2 + d; 370: if (dy < 0 && y > my) 371: y = my; 372: } 373: } else 374: y = oy; 375: } 376: if (!changing) return(FALSE); 377: if (x == x2 && y == y2) { 378: XUnmapWindow(Pop); 379: XRaiseWindow(window); 380: } else { 381: if (x < x1) { 382: t = x1; x1 = x; x = t; 383: } 384: if (y < y1) { 385: t = y1; y1 = y; y = t; 386: } 387: dx = x - x1 + 1 - (window_info.bdrwidth << 1); 388: dy = y - y1 + 1 - (window_info.bdrwidth << 1); 389: if ( 390: (PWidth > window_info.width) || 391: (PHeight > window_info.height) || 392: (PWidth > dx) || 393: (PHeight > dy) 394: ) { 395: XUnmapWindow(Pop); 396: } 397: else { 398: XUnmapTransparent(Pop); 399: } 400: XConfigureWindow(window, x1, y1, dx, dy); 401: } 402: return(TRUE); 403: }