|
|
1.1 ! root 1: #ifndef lint ! 2: static char *rcsid_GetButton_c = "$Header: GetButton.c,v 1.24 87/09/09 19:20:45 swick Exp $"; ! 3: #endif lint ! 4: ! 5: #include <X11/copyright.h> ! 6: ! 7: /* ! 8: * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. ! 9: * ! 10: * All Rights Reserved ! 11: * ! 12: * Permission to use, copy, modify, and distribute this software and its ! 13: * documentation for any purpose and without fee is hereby granted, ! 14: * provided that the above copyright notice appear in all copies and that ! 15: * both that copyright notice and this permission notice appear in ! 16: * supporting documentation, and that the name of Digital Equipment ! 17: * Corporation not be used in advertising or publicity pertaining to ! 18: * distribution of the software without specific, written prior permission. ! 19: * ! 20: * ! 21: * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 22: * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 23: * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 24: * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 25: * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 26: * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 27: * SOFTWARE. ! 28: */ ! 29: ! 30: ! 31: ! 32: /* ! 33: * MODIFICATION HISTORY ! 34: * ! 35: * 000 -- M. Gancarz, DEC Ultrix Engineering Group ! 36: * 001 -- L. Guarino Reid, DEC Ultrix Engineering Group, Western Software Lab ! 37: * February 16, 1987 ! 38: * Add EnterWindow, LeaveWindow, and MouseMotion as recognized ! 39: * uwm buttons for uwm menus. Add bug fixes to prevent mem faults ! 40: * if icon_str is NULL. ! 41: * 002 -- L. Guarino Reid, DEC Ultrix Engineering Group ! 42: * April 16, 1987 ! 43: * Convert to X11 ! 44: */ ! 45: ! 46: #ifndef lint ! 47: static char *sccsid = "@(#)GetButton.c 3.8 1/24/86"; ! 48: #endif ! 49: /* ! 50: * GetButton - This subroutine is used by the Ultrix Window Manager (uwm) ! 51: * to acquire button events. It waits for a button event to occur ! 52: * and handles all event traffic in the interim. ! 53: * ! 54: * File: GetButton.c ! 55: */ ! 56: ! 57: #include "uwm.h" ! 58: #include <X11/Xutil.h> ! 59: #include <X11/Xatom.h> ! 60: ! 61: #define ICONSTR (icon_str ? icon_str : "") ! 62: ! 63: Bool GetButton(button_event) ! 64: XEvent *button_event; /* Button event packet. */ ! 65: { ! 66: #define STRLEN 50 ! 67: XKeyPressedEvent *kp_event; /* Key pressed event. */ ! 68: char *icon_str; /* Icon's name string. */ ! 69: register int icon_str_len; /* Icon name string lenght. */ ! 70: register int key_char; /* Key press character code. */ ! 71: register int icon_x; /* Icon window X coordinate. */ ! 72: register int icon_y; /* Icon window Y coordinate. */ ! 73: register int icon_w; /* Icon window width. */ ! 74: register int icon_h; /* Icon window height. */ ! 75: int status; /* Routine call return status. */ ! 76: Window icon; /* Icon window. */ ! 77: Window appl; /* Application window. */ ! 78: XWindowAttributes icon_info; /* Icon window info structure. */ ! 79: char kbd_str[STRLEN]; /* Keyboard string. */ ! 80: int nbytes; /* Keyboard string length. */ ! 81: int i; /* Iteration counter. */ ! 82: ! 83: ! 84: /* ! 85: * Get next event from input queue and store it in the event packet ! 86: * passed to GetButton. ! 87: */ ! 88: XNextEvent(dpy, button_event); ! 89: ! 90: /* ! 91: * The event occured on the root window, check for substructure ! 92: * changes. Otherwise, it must be a mouse button event. ! 93: */ ! 94: if (((XAnyEvent *)button_event)->window == RootWindow(dpy, scr)) { ! 95: ! 96: switch (button_event->type) { ! 97: ! 98: case CreateNotify: ! 99: case UnmapNotify: ! 100: case ReparentNotify: ! 101: case ConfigureNotify: ! 102: case GravityNotify: ! 103: case MapNotify: ! 104: case MappingNotify: ! 105: case CirculateNotify: return(FALSE); ! 106: ! 107: case MapRequest: ! 108: CheckMap(((XMapEvent *)button_event)->window); ! 109: return(FALSE); ! 110: ! 111: case ConfigureRequest: ! 112: Configure((XConfigureEvent *)button_event); ! 113: return(FALSE); ! 114: ! 115: case CirculateRequest: ! 116: Circulate((XCirculateEvent *)button_event); ! 117: return(FALSE); ! 118: ! 119: case DestroyNotify: ! 120: RemoveIcon(((XDestroyWindowEvent *)button_event)->window); ! 121: return(FALSE); ! 122: ! 123: case FocusIn: ! 124: if (((XFocusInEvent *)button_event)->detail ! 125: == NotifyPointerRoot) { ! 126: if (FocusSetByUser) { ! 127: XSetInputFocus(dpy, PointerRoot, None, CurrentTime); ! 128: FocusSetByUser = FALSE; ! 129: } ! 130: } ! 131: return (FALSE); ! 132: ! 133: case FocusOut: ! 134: if (((XFocusOutEvent *)button_event)->detail ! 135: == NotifyPointerRoot) { ! 136: if (!FocusSetByUser) { ! 137: XSetInputFocus(dpy, PointerRoot, None, CurrentTime); ! 138: } ! 139: } ! 140: return (FALSE); ! 141: ! 142: case ButtonPress: ! 143: case ButtonRelease: ! 144: return(TRUE); ! 145: ! 146: default: ! 147: printf("uwm internal error: unexpected event on Root Window\n"); ! 148: return(FALSE); ! 149: } ! 150: } ! 151: ! 152: /* ! 153: * If the event type is EnterWindow, LeaveWindow, or MouseMoved, ! 154: * we are processing a menu. ! 155: * If the event type is ButtonPress or ButtonRelease, ! 156: * we have a button event. */ ! 157: switch (button_event->type) { ! 158: case EnterNotify: ! 159: case LeaveNotify: ! 160: case MotionNotify: ! 161: case ButtonPress: ! 162: case ButtonRelease: ! 163: return(TRUE); ! 164: default: break; ! 165: } ! 166: ! 167: /* ! 168: * Ok, if the event is not on the root window it must be an event on ! 169: * one of the icons owned by uwm. ! 170: */ ! 171: icon = ((XAnyEvent *)button_event)->window; ! 172: ! 173: /* ! 174: * Find out current information about the icon window. ! 175: */ ! 176: status = XGetWindowAttributes(dpy, icon, &icon_info); ! 177: if (status == FAILURE) return(FALSE); ! 178: ! 179: /* ! 180: * If the event is an UnmapWindow event or a ConfigureNotify event, ! 181: * then return FALSE. ! 182: */ ! 183: if (button_event->type == MapNotify || ! 184: button_event->type == UnmapNotify || ! 185: button_event->type == CreateNotify || ! 186: button_event->type == ReparentNotify || ! 187: button_event->type == GravityNotify || ! 188: button_event->type == CirculateNotify || ! 189: button_event->type == ConfigureNotify) ! 190: return(FALSE); ! 191: ! 192: /* ! 193: * Initialize the icon position variables. ! 194: */ ! 195: icon_x = icon_info.x; ! 196: icon_y = icon_info.y; ! 197: ! 198: /* ! 199: * Get the name of the window associated with the icon and ! 200: * determine its length. ! 201: */ ! 202: if (!IsIcon(icon, icon_x, icon_y, FALSE, &appl)) return(FALSE); ! 203: icon_str = GetIconName(appl); ! 204: icon_str_len = icon_str ? strlen(icon_str) : 0; ! 205: ! 206: /* ! 207: * If the event is a window exposure event and the icon's name string ! 208: * is not of zero length, simply repaint the text in the icon window ! 209: * and return FALSE. ! 210: */ ! 211: if (button_event->type == Expose && (!Freeze || Frozen == 0)) { ! 212: if (icon_info.width != ! 213: XTextWidth(IFontInfo, ICONSTR, strlen(ICONSTR))+(HIconPad << 1)) { ! 214: XResizeWindow(dpy, icon, ! 215: XTextWidth(IFontInfo, ICONSTR, strlen(ICONSTR))+(HIconPad << 1), ! 216: IFontInfo->ascent + IFontInfo->descent + (VIconPad << 1)); ! 217: } ! 218: XClearWindow(dpy, icon); ! 219: if (icon_str_len != 0) { ! 220: XDrawImageString(dpy, icon, ! 221: IconGC, HIconPad, VIconPad+IFontInfo->ascent, ! 222: icon_str, icon_str_len); ! 223: /* ! 224: * Remember to free the icon name string. ! 225: */ ! 226: free(icon_str); ! 227: } ! 228: return(FALSE); ! 229: } ! 230: ! 231: /* ! 232: * If we have gotten this far event can only be a key pressed event. ! 233: */ ! 234: kp_event = (XKeyPressedEvent *) button_event; ! 235: ! 236: /* ! 237: * We convert the key pressed event to ascii. ! 238: */ ! 239: nbytes = XLookupString(kp_event, kbd_str, STRLEN, NULL); ! 240: ! 241: /* ! 242: * If kbd_str is a "non-string", then don't do anything. ! 243: */ ! 244: if (nbytes == 0) { ! 245: if (icon_str) free(icon_str); ! 246: return(FALSE); ! 247: } ! 248: for (i = 0; i < nbytes; i++) { ! 249: key_char = kbd_str[i]; ! 250: /* ! 251: * If the key was <DELETE>, then delete a character from the end of ! 252: * the name, return FALSE. ! 253: * ! 254: * If the key was <CTRL-U>, then wipe out the entire window name ! 255: * and return FALSE. ! 256: * ! 257: * All other ctrl keys are squashed and we return FALSE. ! 258: * ! 259: * All printable characters are appended to the window's name, which ! 260: * may have to be grown to allow for the extra length. ! 261: */ ! 262: if (key_char == '\177') { ! 263: /* ! 264: * <DELETE> ! 265: */ ! 266: if (icon_str_len > 0) { ! 267: icon_str_len--; ! 268: icon_str[icon_str_len] = '\0'; ! 269: } ! 270: } ! 271: else if (key_char == '\025') { ! 272: /* ! 273: * <CTRL-U> ! 274: */ ! 275: if (icon_str_len > 0) { ! 276: icon_str_len = 0; ! 277: icon_str[0] = '\0'; ! 278: } ! 279: } ! 280: else if (key_char < IFontInfo->min_char_or_byte2 || ! 281: key_char > IFontInfo->max_char_or_byte2) { ! 282: /* ! 283: * Any other random (non-printable) key; ignore it. ! 284: */ ! 285: /* do nothing */ ; ! 286: } ! 287: else { ! 288: /* ! 289: * ASCII Alphanumerics. ! 290: */ ! 291: if (icon_str == NULL) ! 292: icon_str = (char *) malloc (icon_str_len + 2); ! 293: else ! 294: icon_str = (char *)realloc(icon_str, (icon_str_len + 2)); ! 295: if (icon_str == NULL) { ! 296: errno = ENOMEM; ! 297: Error("GetButton -> Realloc of window name string memory failed."); ! 298: } ! 299: icon_str[icon_str_len] = key_char; ! 300: icon_str[icon_str_len + 1] = '\0'; ! 301: icon_str_len += 1; ! 302: } ! 303: } ! 304: ! 305: /* ! 306: * Now that we have changed the size of the icon we have to reconfigure ! 307: * it so that everything looks good. Oh yes, don't forget to move the ! 308: * mouse so that it stays in the window! ! 309: */ ! 310: ! 311: /* ! 312: * Set the window name to the new string. ! 313: */ ! 314: XSetIconName(dpy, appl, ICONSTR); ! 315: ! 316: /* ! 317: * Determine the new icon window configuration. ! 318: */ ! 319: icon_h = IFontInfo->ascent + IFontInfo->descent + (VIconPad << 1); ! 320: icon_w = XTextWidth(IFontInfo, ICONSTR, strlen(ICONSTR)); ! 321: if (icon_w == 0) { ! 322: icon_w = icon_h; ! 323: } ! 324: else { ! 325: icon_w += (HIconPad << 1); ! 326: } ! 327: ! 328: if (icon_x < 0) icon_x = 0; ! 329: if (icon_y < 0) icon_y = 0; ! 330: if (icon_x - 1 + icon_w + (IBorderWidth << 1) > ScreenWidth) { ! 331: icon_x = ScreenWidth - icon_w - (IBorderWidth << 1) + 1; ! 332: } ! 333: if (icon_y - 1 + icon_h + (IBorderWidth << 1) > ScreenHeight) { ! 334: icon_y = ScreenHeight - icon_h - (IBorderWidth << 1) + 1; ! 335: } ! 336: ! 337: XMoveResizeWindow(dpy, icon, icon_x, icon_y, icon_w, icon_h); ! 338: XWarpPointer(dpy, None, icon, ! 339: 0, 0, 0, 0, (icon_w >> 1), (icon_h >> 1)); ! 340: ! 341: /* ! 342: * Free the local storage and return FALSE. ! 343: */ ! 344: if (icon_str) free(icon_str); ! 345: return(FALSE); ! 346: } ! 347: ! 348: CheckMap(window) ! 349: Window window; ! 350: { ! 351: XSizeHints sizehints; ! 352: XWMHints *wmhints; ! 353: int x, y, w, h; ! 354: XWMHints *XGetWMHints(); ! 355: Window transient_for; ! 356: Bool configureit = False; ! 357: Window jW; ! 358: int border_width, j; ! 359: ! 360: /* ! 361: * Gather info about the event window. ! 362: */ ! 363: ! 364: /* if it's a transient window, we won't rubber-band ! 365: * note that this call always sets transient_for. ! 366: */ ! 367: if (XGetTransientForHint( dpy, window, &transient_for )) { ! 368: XGetGeometry( dpy, window, &jW, &x, &y, &w, &h, &border_width, &j ); ! 369: } ! 370: else { ! 371: if ((wmhints = XGetWMHints(dpy, window)) && ! 372: (wmhints->flags&StateHint) && ! 373: (wmhints->initial_state == IconicState)) { ! 374: /* window will remain created size -- no rubberbanding */ ! 375: /* note that Iconify only uses its first argument */ ! 376: Iconify(window, 0, 0, 0, 0); ! 377: return; ! 378: } ! 379: ! 380: sizehints.flags = 0; ! 381: ! 382: XGetSizeHints(dpy, window, &sizehints, XA_WM_NORMAL_HINTS); ! 383: CheckConsistency(&sizehints); ! 384: AskUser(dpy, scr, window, &x, &y, &w, &h, &sizehints); ! 385: if (x != sizehints.x || y != sizehints.y || ! 386: w != sizehints.width || h != sizehints.height) ! 387: configureit = True; ! 388: ! 389: sizehints.flags |= (USPosition | USSize); ! 390: sizehints.x = x; ! 391: sizehints.y = y; ! 392: sizehints.width = w; ! 393: sizehints.height = h; ! 394: XSetSizeHints(dpy, window, &sizehints, XA_WM_NORMAL_HINTS); ! 395: } ! 396: ! 397: if (x<0 || y<0) { ! 398: if (transient_for == None) /* need the border width */ ! 399: XGetGeometry( dpy, window, &jW, &j, &j, &j, &j, &border_width, &j ); ! 400: ! 401: if (x<0) x += DisplayWidth(dpy, scr) - w - (border_width<<1); ! 402: if (y<0) y += DisplayHeight(dpy, scr) - h - (border_width<<1); ! 403: ! 404: configureit = True; ! 405: } ! 406: ! 407: if (configureit) ! 408: XMoveResizeWindow(dpy, window, x, y, w, h); ! 409: ! 410: XMapRaised(dpy, window); ! 411: } ! 412: ! 413: Configure(event) ! 414: XConfigureRequestEvent *event; ! 415: { ! 416: XWindowChanges values; ! 417: ! 418: values.x = event->x; ! 419: values.y = event->y; ! 420: values.width = event->width; ! 421: values.height = event->height; ! 422: values.border_width = event->border_width; ! 423: values.stack_mode = event->detail; ! 424: values.sibling = event->above; ! 425: ! 426: XConfigureWindow(event->display, event->window, event->value_mask, &values); ! 427: } ! 428: ! 429: Circulate(event) ! 430: XCirculateEvent *event; ! 431: { ! 432: if (event->place == PlaceOnTop) ! 433: XRaiseWindow(event->display, event->window); ! 434: else ! 435: XLowerWindow(event->display, event->window); ! 436: } ! 437:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.