1: #include <X/mit-copyright.h> 2: 3: /* Copyright Massachusetts Institute of Technology 1985 */ 4: 5: /* 6: * LowerIconify - This subroutine implements window lowering and 7: * iconifing for the X Window System window manager (xwm). 8: * 9: * File: LowerIconify.c 10: * Modified: ADF 29-May-85 Converted to X version 8.0 11: */ 12: 13: #include "xwm.h" 14: #ifndef lint 15: static char *rcsid_LowerIconify_c = "$Header: LowerIconify.c,v 10.4 86/02/01 16:09:38 tony Rel $"; 16: #endif 17: 18: LowerIconify(window, x, y) 19: Window window; /* Event window. */ 20: int x, y; /* Event mouse position. */ 21: { 22: register WindowInfo window_info; /* Event window info. */ 23: register WindowInfo icon_info; /* Icon window info. */ 24: char *name; /* Event window name. */ 25: int mse_x, mse_y; /* Mouse X and Y coordinates. */ 26: int icon_x, icon_y; /* Icon U. L. X and Y coordinates. */ 27: int icon_w, icon_h; /* Icon width and height. */ 28: int icon_bdr; /* Icon border width. */ 29: int status; /* Routine call return status. */ 30: int num_vectors; /* Number of vectors in zap buffer. */ 31: Window icon; /* Icon window. */ 32: Window sub_win; /* Mouse position sub-window. */ 33: XButtonEvent button_event; /* Button event packet. */ 34: Vertex zap[MAX_ZAP_VECTORS]; /* Zap effect vertex buffer. */ 35: Bool iconifying; /* Are we iconifying? */ 36: 37: /* 38: * Clear the vector buffer. 39: */ 40: if (Zap) bzero(zap, sizeof(zap)); 41: 42: /* 43: * Get info on the event window. 44: */ 45: status = XQueryWindow(window, &window_info); 46: if (status == FAILURE) return; 47: 48: /* 49: * If the mouse is in an icon window simply lower the window and return. 50: */ 51: if (window_info.type == IsIcon) { 52: 53: /* 54: * Wait for the button to come back up. 55: */ 56: while (!GetButton(&button_event)); 57: 58: if ( 59: (button_event.type == ButtonReleased) && 60: ((button_event.detail & ValueMask) == LeftButton) 61: ){ 62: XLowerWindow(window); 63: } 64: 65: return; 66: } 67: 68: /* 69: * If we are here then the event was not on an iconified window. 70: * This flag denotes whether the window we're on is being 71: * iconified or not. 72: */ 73: iconifying = FALSE; 74: 75: /* 76: * We spin our wheels here looking for mouse movement or a change 77: * in the status of the buttons. 78: */ 79: while (TRUE) { 80: 81: /* 82: * Check to see if we have a change in mouse button status. 83: * This is how we get out of this "while" loop. 84: */ 85: if (XPending() && GetButton(&button_event)) { 86: mse_x = button_event.x; 87: mse_y = button_event.y; 88: if ( 89: !iconifying && 90: ((abs(mse_x - x) > Delta) || (abs(mse_y - y) > Delta)) 91: ){ 92: /* 93: * The mouse has moved Delta pixels without the left button 94: * going up. This means we are iconifying a window. 95: * We warn the user by changing the mouse cursor to the 96: * funny icon cursor. 97: */ 98: iconifying = TRUE; 99: status = XGrabButton( 100: RootWindow, 101: IconCursor, 102: (LeftMask | ButtonMask), 103: (ButtonPressed | ButtonReleased) 104: ); 105: if (status == FAILURE) { 106: Error("LowerIconify -> Unable to grab left button and change cursor."); 107: } 108: } 109: break; 110: } 111: else if (!iconifying) { 112: /* 113: * Continue to track the mouse untill we exceed delta or 114: * get a change in button status. 115: */ 116: XQueryMouse(RootWindow, &mse_x, &mse_y, &sub_win); 117: 118: if ((abs(mse_x - x) > Delta) || (abs(mse_y - y) > Delta)) { 119: /* 120: * The mouse has moved Delta pixels without the left button 121: * going up. This means we are iconifying a window. 122: * We warn the user by changing the mouse cursor to the 123: * funny icon cursor. 124: */ 125: iconifying = TRUE; 126: status = XGrabButton( 127: RootWindow, 128: IconCursor, 129: (LeftMask | ButtonMask), 130: (ButtonPressed | ButtonReleased) 131: ); 132: if (status == FAILURE) { 133: Error("LowerIconify -> Unable to grab left button and change cursor."); 134: } 135: } 136: } 137: } 138: 139: if (iconifying) { 140: /* 141: * Restore the window manager mouse cursor. 142: */ 143: status = XGrabButton( 144: RootWindow, 145: DotCursor, 146: (LeftMask | ButtonMask), 147: (ButtonPressed | ButtonReleased) 148: ); 149: if (status == FAILURE) { 150: Error("LowerIconify -> Unable to grab left button and change cursor."); 151: } 152: } 153: 154: /* 155: * If the left button is released and we are not iconifying then 156: * lower the window and return. If any other button event occured 157: * abort the operation. 158: */ 159: if ( 160: (button_event.type == ButtonReleased) && 161: ((button_event.detail & ValueMask) == LeftButton) 162: ){ 163: if (!iconifying) { 164: XLowerWindow(window); 165: return; 166: } 167: } 168: else { 169: /* 170: * Abort! 171: */ 172: return; 173: } 174: 175: /* 176: * If we are here we have committed to iconifying the window. 177: */ 178: 179: if (window_info.assoc_wind == 0) { 180: /* 181: * We need to make an icon window for the event window. 182: */ 183: 184: /* 185: * Set the icon border width. 186: */ 187: icon_bdr = IBorderWidth; 188: 189: /* 190: * Determine the size of the icon window. 191: */ 192: status = XFetchName(window, &name); 193: if (status == FAILURE) return; 194: icon_h = IFontInfo.height + (IPadding << 1); 195: icon_w = XQueryWidth(name, IFont); 196: if (icon_w == 0) { 197: icon_w = icon_h; 198: } 199: else { 200: icon_w += (IPadding << 1); 201: } 202: 203: /* 204: * Determine the coordinates of the icon window; 205: * normalize so that we don't lose the icon off the 206: * edge of the screen. 207: */ 208: icon_x = mse_x - (icon_w >> 1) + 1; 209: if (icon_x < 0) icon_x = 0; 210: icon_y = mse_y - (icon_h >> 1) + 1; 211: if (icon_y < 0) icon_y = 0; 212: if ((icon_x - 1 + icon_w + (icon_bdr << 1)) > ScreenWidth) { 213: icon_x = ScreenWidth - icon_w - (icon_bdr << 1) + 1; 214: } 215: if ((icon_y - 1 + icon_h + (icon_bdr << 1)) > ScreenHeight) { 216: icon_y = ScreenHeight - icon_h - (icon_bdr << 1) + 1; 217: } 218: 219: /* 220: * Create the icon window. 221: */ 222: icon = XCreateWindow( 223: RootWindow, 224: icon_x, icon_y, 225: icon_w, icon_h, 226: icon_bdr, 227: IBorder, IBackground 228: ); 229: if (icon == FAILURE) return; 230: 231: /* 232: * Use the text cursor whenever the mouse is in the icon window. 233: */ 234: XDefineCursor(icon, TextCursor); 235: 236: /* 237: * Select "key pressed", "window exposure" and "unmap window" 238: * events for the icon window. 239: */ 240: XSelectInput(icon, (KeyPressed | ExposeWindow | UnmapWindow)); 241: 242: /* 243: * Set the event window's icon window to be the new icon window. 244: */ 245: XSetIconWindow(window, icon); 246: } 247: else { 248: /* 249: * If we already have an icon window all we have to do is 250: * retrieve the info on it and move it into place. 251: */ 252: icon = window_info.assoc_wind; 253: 254: /* 255: * Get info on the icon window. 256: */ 257: status = XQueryWindow(icon, &icon_info); 258: if (status == FAILURE) return; 259: 260: /* 261: * Set the icon border width. 262: */ 263: icon_bdr = icon_info.bdrwidth; 264: 265: /* 266: * Determine the size of the icon window. 267: */ 268: icon_h = icon_info.height; 269: icon_w = icon_info.width; 270: 271: /* 272: * Determine the coordinates of the icon window; 273: * normalize so that we don't lose the icon off the 274: * edge of the screen. 275: */ 276: icon_x = mse_x - (icon_w >> 1) + 1; 277: if (icon_x < 0) icon_x = 0; 278: icon_y = mse_y - (icon_h >> 1) + 1; 279: if (icon_y < 0) icon_y = 0; 280: if ((icon_x - 1 + icon_w + (icon_bdr << 1)) > ScreenWidth) { 281: icon_x = ScreenWidth - icon_w - (icon_bdr << 1) + 1; 282: } 283: if ((icon_y - 1 + icon_h + (icon_bdr << 1)) > ScreenHeight) { 284: icon_y = ScreenHeight - icon_h - (icon_bdr << 1) + 1; 285: } 286: 287: /* 288: * Move the window into place. 289: */ 290: XMoveWindow(icon, icon_x, icon_y); 291: } 292: 293: if (Zap) { 294: /* 295: * Store the zap effect vectors. 296: */ 297: num_vectors = StoreZap( 298: zap, 299: window_info.x - 1, 300: window_info.y - 1, 301: window_info.x + window_info.width + (window_info.bdrwidth << 1), 302: window_info.y + window_info.height + (window_info.bdrwidth << 1), 303: icon_x - 1, 304: icon_y - 1, 305: icon_x + icon_w + (icon_bdr << 1), 306: icon_y + icon_h + (icon_bdr << 1) 307: ); 308: } 309: 310: /* 311: * Map the icon window. 312: */ 313: XMapWindow(icon); 314: 315: if (Zap) { 316: /* 317: * Draw zap lines from the window to its icon. 318: */ 319: XDraw( 320: RootWindow, 321: zap, num_vectors, 322: DRAW_HEIGHT, DRAW_WIDTH, 323: DRAW_VALUE, DRAW_FUNC, DRAW_PLANES 324: ); 325: XDraw( 326: RootWindow, 327: zap, num_vectors, 328: DRAW_HEIGHT, DRAW_WIDTH, 329: DRAW_VALUE, DRAW_FUNC, DRAW_PLANES 330: ); 331: } 332: 333: /* 334: * Unmap the event window. 335: */ 336: XUnmapWindow(window); 337: }