1: #ifndef lint 2: static char *rcsid_GetButton_c = "$Header: GetButton.c,v 10.4 86/02/01 16:22:53 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 = "@(#)GetButton.c 3.8 1/24/86"; 45: #endif 46: /* 47: * GetButton - This subroutine is used by the Ultrix Window Manager (uwm) 48: * to acquire button events. It waits for a button event to occur 49: * and handles all event traffic in the interim. 50: * 51: * File: GetButton.c 52: */ 53: 54: #include "uwm.h" 55: 56: Bool GetButton(button_event) 57: XButtonEvent *button_event; /* Button event packet. */ 58: { 59: XKeyPressedEvent *kp_event; /* Key pressed event. */ 60: char *icon_str; /* Icon's name string. */ 61: register int icon_str_len; /* Icon name string lenght. */ 62: register int key_char; /* Key press character code. */ 63: register int icon_x; /* Icon window X coordinate. */ 64: register int icon_y; /* Icon window Y coordinate. */ 65: register int icon_w; /* Icon window width. */ 66: register int icon_h; /* Icon window height. */ 67: int status; /* Routine call return status. */ 68: Window icon; /* Icon window. */ 69: WindowInfo icon_info; /* Icon window info structure. */ 70: char *kbd_str; /* Keyboard string. */ 71: int nbytes; /* Keyboard string length. */ 72: int i; /* Iteration counter. */ 73: 74: 75: /* 76: * Get next event from input queue and store it in the event packet 77: * passed to GetButton. 78: */ 79: XNextEvent(button_event); 80: 81: /* 82: * The event occured on the root window, it must be a mouse 83: * button event. 84: */ 85: if (button_event->window == RootWindow) { 86: return(TRUE); 87: } 88: 89: /* 90: * Ok, if the event is not on the root window it must be an event on 91: * one of the icons owned by uwm. 92: */ 93: icon = button_event->window; 94: 95: /* 96: * Find out current information about the icon window. 97: */ 98: status = XQueryWindow(icon, &icon_info); 99: if (status == FAILURE) return(FALSE); 100: 101: /* 102: * If the icon's normal window is gone, then 103: * destroy the icon window and return FALSE. 104: */ 105: if (icon_info.assoc_wind == 0) { 106: XDestroyWindow(icon); 107: return(FALSE); 108: } 109: 110: /* 111: * If the event is an UnmapWindow event, 112: * then return FALSE. 113: */ 114: if (button_event->type == UnmapWindow) 115: return(FALSE); 116: 117: /* 118: * Initialize the icon position variables. 119: */ 120: icon_x = icon_info.x; 121: icon_y = icon_info.y; 122: 123: /* 124: * Get the name of the window associated with the icon and 125: * determine its length. 126: */ 127: status = XFetchName(icon_info.assoc_wind, &icon_str); 128: if (status == FAILURE) return(FALSE); 129: icon_str_len = icon_str ? strlen(icon_str) : 0; 130: 131: /* 132: * If the event is a window exposure event and the icon's name string 133: * is not of zero length, simply repaint the text in the icon window 134: * and return FALSE. 135: */ 136: if (button_event->type == ExposeWindow && Frozen == 0) { 137: XClear(icon); 138: if (icon_str_len != 0) { 139: XTextPad(icon, 140: HIconPad, VIconPad, 141: icon_str, icon_str_len, 142: IFont, 0, 0, 143: ITextForground, ITextBackground, 144: GXcopy, AllPlanes); 145: /* 146: * Remember to free the icon name string. 147: */ 148: free(icon_str); 149: } 150: return(FALSE); 151: } 152: 153: /* 154: * If we have gotten this far event can only be a key pressed event. 155: */ 156: kp_event = (XKeyPressedEvent *) button_event; 157: 158: /* 159: * We convert the key pressed event to ascii. 160: */ 161: kbd_str = XLookupMapping(kp_event, &nbytes); 162: 163: /* 164: * If kbd_str is a "non-string", then don't do anything. 165: */ 166: if (nbytes == 0) { 167: if (icon_str) free(icon_str); 168: return(FALSE); 169: } 170: for (i = 0; i < nbytes; i++) { 171: key_char = kbd_str[i]; 172: /* 173: * If the key was <DELETE>, then delete a character from the end of 174: * the name, return FALSE. 175: * 176: * If the key was <CTRL-U>, then wipe out the entire window name 177: * and return FALSE. 178: * 179: * All other ctrl keys are squashed and we return FALSE. 180: * 181: * All printable characters are appended to the window's name, which 182: * may have to be grown to allow for the extra length. 183: */ 184: if (key_char == '\177') { 185: /* 186: * <DELETE> 187: */ 188: if (icon_str_len > 0) { 189: icon_str_len--; 190: icon_str[icon_str_len] = '\0'; 191: } 192: } 193: else if (key_char == '\025') { 194: /* 195: * <CTRL-U> 196: */ 197: if (icon_str_len > 0) { 198: icon_str_len = 0; 199: icon_str = '\0'; 200: } 201: } 202: else if (key_char < IFontInfo.firstchar || 203: key_char > IFontInfo.lastchar) { 204: /* 205: * Any other random (non-printable) key; ignore it. 206: */ 207: /* do nothing */ ; 208: } 209: else { 210: /* 211: * ASCII Alphanumerics. 212: */ 213: if (icon_str == NULL) 214: icon_str = (char *) malloc (icon_str_len + 2); 215: else 216: icon_str = (char *)realloc(icon_str, (icon_str_len + 2)); 217: if (icon_str == NULL) { 218: errno = ENOMEM; 219: Error("GetButton -> Realloc of window name string memory failed."); 220: } 221: icon_str[icon_str_len] = key_char; 222: icon_str[icon_str_len + 1] = '\0'; 223: icon_str_len += 1; 224: } 225: } 226: 227: /* 228: * Now that we have changed the size of the icon we have to reconfigure 229: * it so that everything looks good. Oh yes, don't forget to move the 230: * mouse so that it stays in the window! 231: */ 232: 233: /* 234: * Set the window name to the new string. 235: */ 236: XStoreName(icon_info.assoc_wind, icon_str); 237: 238: /* 239: * Determine the new icon window configuration. 240: */ 241: icon_h = IFontInfo.height + (VIconPad << 1); 242: icon_w = XQueryWidth(icon_str, IFont); 243: if (icon_w == 0) { 244: icon_w = icon_h; 245: } 246: else { 247: icon_w += (HIconPad << 1); 248: } 249: 250: if (icon_x < 0) icon_x = 0; 251: if (icon_y < 0) icon_y = 0; 252: if (icon_x - 1 + icon_w + (IBorderWidth << 1) > ScreenWidth) { 253: icon_x = ScreenWidth - icon_w - (IBorderWidth << 1) + 1; 254: } 255: if (icon_y - 1 + icon_h + (IBorderWidth << 1) > ScreenHeight) { 256: icon_y = ScreenHeight - icon_h - (IBorderWidth << 1) + 1; 257: } 258: 259: XConfigureWindow(icon, icon_x, icon_y, icon_w, icon_h); 260: XWarpMouse(icon, (icon_w >> 1), (icon_h >> 1)); 261: 262: /* 263: * Free the local storage and return FALSE. 264: */ 265: if (icon_str) free(icon_str); 266: return(FALSE); 267: }