1: #ifndef lint 2: static char *rcsid_NewIconify_c = "$Header: NewIconify.c,v 10.4 86/04/07 17:04:38 jg Exp $"; 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 = "@(#)NewIconify.c 3.8 1/24/86"; 45: #endif 46: 47: #include "uwm.h" 48: 49: Bool NewIconify(window, mask, button, x, y) 50: Window window; /* Event window. */ 51: int mask; /* Button/key mask. */ 52: short button; /* Button event detail. */ 53: int x, y; /* Event mouse position. */ 54: { 55: register WindowInfo window_info; /* Event window info. */ 56: register WindowInfo icon_info; /* Icon window info. */ 57: char *name; /* Event window name. */ 58: int mse_x, mse_y; /* Mouse X and Y coordinates. */ 59: int icon_x, icon_y; /* Icon U. L. X and Y coordinates. */ 60: int icon_w, icon_h; /* Icon width and height. */ 61: int icon_bdr; /* Icon border width. */ 62: int prev_x; /* Previous event window X location. */ 63: int prev_y; /* Previous event window Y location. */ 64: int cur_x; /* Current event window X location. */ 65: int cur_y; /* Current event window Y location. */ 66: int ulx, uly; /* Event window upper left X and Y. */ 67: int lrx, lry; /* Event window lower right X and Y. */ 68: int init_ulx, init_uly; /* Init window upper left X and Y. */ 69: int init_lrx, init_lry; /* Init window lower right X and Y. */ 70: int num_vectors; /* Number of vectors in box. */ 71: int status; /* Routine call return status. */ 72: Window icon; /* Icon window. */ 73: Window sub_win; /* Mouse position sub-window. */ 74: XButtonEvent button_event; /* Button event packet. */ 75: Vertex box[MAX_BOX_VECTORS]; /* Box vertex buffer. */ 76: Vertex zap[MAX_ZAP_VECTORS]; /* Zap effect vertex buffer. */ 77: Bool iconifying; /* Are we iconifying? */ 78: 79: /* 80: * Do not lower or iconify the root window. 81: */ 82: if (window == RootWindow) 83: return(FALSE); 84: 85: /* 86: * Change the cursor to the icon cursor. 87: */ 88: status = XGrabButton(RootWindow, ArrowCrossCursor, mask, EVENTMASK); 89: if (status == FAILURE) 90: Error("NewIconify -> Unable to grab button and change cursor."); 91: 92: /* 93: * Clear the vector buffers. 94: */ 95: bzero(box, sizeof(box)); 96: if (Zap) bzero(zap, sizeof(zap)); 97: 98: /* 99: * Get info on the event window. 100: */ 101: status = XQueryWindow(window, &window_info); 102: if (status == FAILURE) return(FALSE); 103: 104: /* 105: * Are we iconifying or de-iconifying? 106: */ 107: if (window_info.type != IsIcon) { 108: 109: /* 110: * Window => Icon (Iconifying). 111: */ 112: /* 113: * If an icon window doesn't exist for the event window, then 114: * make one. 115: */ 116: if (window_info.assoc_wind == 0) { 117: 118: /* 119: * Set the icon border width. 120: */ 121: icon_bdr = IBorderWidth; 122: 123: /* 124: * Determine the size of the icon window. 125: */ 126: status = XFetchName(window, &name); 127: if (status == FAILURE) return(FALSE); 128: icon_h = IFontInfo.height + (VIconPad << 1); 129: icon_w = XQueryWidth(name, IFont); 130: if (icon_w == 0) icon_w = icon_h; 131: else icon_w += (HIconPad << 1); 132: 133: 134: /* 135: * Create the icon window. 136: */ 137: icon = XCreateWindow(RootWindow, x + (icon_w >> 1), 138: y + (icon_h >> 1), icon_w, icon_h, 139: icon_bdr, IBorder, IBackground); 140: if (icon == FAILURE) return(FALSE); 141: 142: /* 143: * Use the text cursor whenever the mouse is in the icon window. 144: */ 145: XDefineCursor(icon, TextCursor); 146: 147: /* 148: * Select "key pressed", "window exposure" and "unmap window" 149: * events for the icon window. 150: */ 151: XSelectInput(icon, (KeyPressed | ExposeWindow | UnmapWindow)); 152: 153: /* 154: * Set the event window's icon window to be the new icon window. 155: */ 156: XSetIconWindow(window, icon); 157: } 158: else { 159: /* 160: * If we already have an icon window all we have to do is 161: * retrieve the info on it and move it into place. 162: */ 163: icon = window_info.assoc_wind; 164: 165: /* 166: * Get info on the icon window. 167: */ 168: status = XQueryWindow(icon, &icon_info); 169: if (status == FAILURE) return(FALSE); 170: 171: /* 172: * Determine the height, width, and borderwidth of the icon. 173: */ 174: icon_h = icon_info.height; 175: icon_w = icon_info.width; 176: icon_bdr = icon_info.bdrwidth; 177: } 178: 179: iconifying = TRUE; 180: } 181: else { 182: 183: /* 184: * Icon => Window (DeIconifying). 185: */ 186: /* 187: * If the window is gone, destroy the icon and return. 188: */ 189: if (window_info.assoc_wind == 0) { 190: XDestroyWindow(window); 191: Grab(mask); 192: return(FALSE); 193: } 194: 195: /* 196: * We call the normal window the "icon" window only to simplify 197: * the code later on in the function. 198: */ 199: icon = window_info.assoc_wind; 200: 201: /* 202: * Get info on the icon window. 203: */ 204: status = XQueryWindow(icon, &icon_info); 205: if (status == FAILURE) return(FALSE); 206: 207: /* 208: * Determine the height, width, and borderwidth of the icon. 209: */ 210: icon_h = icon_info.height; 211: icon_w = icon_info.width; 212: icon_bdr = icon_info.bdrwidth; 213: 214: iconifying = FALSE; 215: } 216: 217: /* 218: * Initialize the movement variables. 219: */ 220: init_ulx = ulx = x - (icon_w >> 1) - icon_bdr; 221: init_uly = uly = y - (icon_h >> 1) - icon_bdr; 222: init_lrx = lrx = x + (icon_w >> 1) + icon_bdr - 1; 223: init_lry = lry = y + (icon_h >> 1) + icon_bdr - 1; 224: prev_x = x; 225: prev_y = y; 226: 227: 228: /* 229: * Store the box. 230: */ 231: if (Grid) 232: num_vectors = StoreGridBox(box, ulx, uly, lrx, lry); 233: else num_vectors = StoreBox(box, ulx, uly, lrx, lry); 234: 235: /* 236: * Freeze the server, if requested by the user. 237: * This results in a solid box instead of a flickering one. 238: */ 239: if (Freeze) 240: XGrabServer(); 241: 242: /* 243: * Process any outstanding events before drawing the box. 244: */ 245: while (QLength() > 0) { 246: XPeekEvent(&button_event); 247: if (button_event.window == RootWindow) 248: break; 249: GetButton(&button_event); 250: } 251: 252: /* 253: * Draw the box. 254: */ 255: DrawBox(); 256: if (Freeze) 257: Frozen = window; 258: 259: /* 260: * We spin our wheels here looking for mouse movement or a change 261: * in the status of the buttons. 262: */ 263: while (TRUE) { 264: 265: /* 266: * Check to see if we have a change in mouse button status. 267: * This is how we get out of this "while" loop. 268: */ 269: if (XPending() && GetButton(&button_event)) { 270: /* 271: * Process the pending events, this sequence is the only 272: * way out of the loop and the routine. 273: */ 274: 275: /* 276: * If we froze the server, then erase the last lines drawn. 277: */ 278: if (Freeze) { 279: DrawBox(); 280: Frozen = (Window)0; 281: XUngrabServer(); 282: } 283: 284: /* 285: * Save the mouse cursor location. 286: */ 287: mse_x = button_event.x; 288: mse_y = button_event.y; 289: break; 290: } 291: else { 292: /* 293: * Continue to track the mouse until we get a change 294: * in button status. 295: */ 296: XUpdateMouse(RootWindow, &cur_x, &cur_y, &sub_win); 297: 298: /* 299: * If the mouse has moved, then make sure the box follows it. 300: */ 301: if ((cur_x != prev_x) || (cur_y != prev_y)) { 302: 303: /* 304: * If we've frozen the server, then erase the old box first! 305: */ 306: if (Freeze) 307: DrawBox(); 308: 309: /* 310: * Set the new box position. 311: */ 312: ulx += cur_x - prev_x; 313: uly += cur_y - prev_y; 314: lrx += cur_x - prev_x; 315: lry += cur_y - prev_y; 316: 317: /* 318: * Calculate the vectors for the new box. 319: */ 320: if (Grid) 321: num_vectors = StoreGridBox(box, ulx, uly, lrx, lry); 322: else num_vectors = StoreBox(box, ulx, uly, lrx, lry); 323: 324: /* 325: * Draw the new box. 326: */ 327: if (Freeze) 328: DrawBox(); 329: } 330: 331: /* 332: * Save the old box position. 333: */ 334: prev_x = cur_x; 335: prev_y = cur_y; 336: 337: /* 338: * If server is not frozen, then draw the "flicker" box. 339: */ 340: if (!Freeze) { 341: DrawBox(); 342: DrawBox(); 343: } 344: } 345: } 346: 347: /* 348: * Restore the main cursor. 349: */ 350: Grab(mask); 351: 352: /* 353: * If the button is not a button release of the same button pressed, 354: * then abort the operation. 355: */ 356: if ((button_event.type != ButtonReleased) || 357: ((button_event.detail & ValueMask) != button)) { 358: return(TRUE); 359: } 360: 361: /* 362: * If we are here we have committed to iconifying/deiconifying. 363: */ 364: 365: /* 366: * Determine the coordinates of the icon or window; 367: * normalize the window or icon coordinates if the user so desires. 368: */ 369: icon_x = mse_x - (icon_w >> 1) - icon_bdr; 370: icon_y = mse_y - (icon_h >> 1) - icon_bdr; 371: if ((NIcon && iconifying) || (NWindow && !iconifying)) { 372: if (icon_x < 0) icon_x = 0; 373: if (icon_y < 0) icon_y = 0; 374: if ((icon_x - 1 + icon_w + (icon_bdr << 1)) > ScreenWidth) { 375: icon_x = ScreenWidth - icon_w - (icon_bdr << 1) + 1; 376: } 377: if ((icon_y - 1 + icon_h + (icon_bdr << 1)) > ScreenHeight) { 378: icon_y = ScreenHeight - icon_h - (icon_bdr << 1) + 1; 379: } 380: } 381: 382: /* 383: * Move the window into place. 384: */ 385: XMoveWindow(icon, icon_x, icon_y); 386: 387: /* 388: * Map the icon window. 389: */ 390: XMapWindow(icon); 391: 392: if (Zap) { 393: num_vectors = StoreZap(zap, window_info.x, window_info.y, 394: window_info.x + window_info.width + 395: (window_info.bdrwidth << 1), 396: window_info.y + window_info.height + 397: (window_info.bdrwidth << 1), 398: ulx, uly, lrx, lry); 399: DrawZap(); 400: DrawZap(); 401: } 402: 403: /* 404: * Unmap the event window. 405: */ 406: XUnmapWindow(window); 407: return(TRUE); 408: }