|
|
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.