1: #include <X/mit-copyright.h>
2:
3: /* Copyright Massachusetts Institute of Technology 1985 */
4:
5: /*
6: * GetButton - This subroutine is used by the X Window Manager (xwm)
7: * to acquire button events. It waits for a button event to occur
8: * and handles all event traffic in the interim.
9: *
10: * File: GetButton.c
11: */
12: #ifndef lint
13: static char *rcsid_GetButton_c = "$Header: GetButton.c,v 10.5 86/02/01 16:09:26 tony Rel $";
14: #endif
15:
16: #include "xwm.h"
17:
18: Bool GetButton(button_event)
19: XButtonEvent *button_event; /* Button event packet. */
20: {
21: XKeyPressedEvent *kp_event; /* Key pressed event. */
22: char *icon_str; /* Icon's name string. */
23: register int icon_str_len; /* Icon name string lenght. */
24: register int key_char; /* Key press character code. */
25: register int icon_x; /* Icon window X coordinate. */
26: register int icon_y; /* Icon window Y coordinate. */
27: register int icon_w; /* Icon window width. */
28: register int icon_h; /* Icon window height. */
29: int status; /* Routine call return status. */
30: Window icon; /* Icon window. */
31: WindowInfo icon_info; /* Icon window info structure. */
32: char *kbd_str; /* Keyboard string */
33: int nbytes; /* Keyboard string length */
34: int i; /* loop over the string */
35: Bool name_changed = FALSE; /* if TRUE, must redisplay */
36:
37: /*
38: * Get next event from input queue and store it in the event packet
39: * passed to GetButton.
40: */
41: XNextEvent(button_event);
42:
43: /*
44: * The event occured on the root window, it must be a mouse
45: * button event.
46: */
47: if (button_event->window == RootWindow) {
48: return(TRUE);
49: }
50:
51: /*
52: * Ok, if the event is not on the root window it must be an event on
53: * one of the icons owned by xwm.
54: */
55: icon = button_event->window;
56:
57: /*
58: * If the event is an UnmapWindow event then delete the icon window
59: * and return FALSE.
60: */
61: if (button_event->type == UnmapWindow) {
62: XDestroyWindow(icon);
63: return(FALSE);
64: }
65:
66: /*
67: * If it is not an UnmapWindow event then it must be either an
68: * ExposeWindow event or a KeyPressed event.
69: */
70:
71: /*
72: * Find out current information about the icon window.
73: */
74: status = XQueryWindow(icon, &icon_info);
75: if (status == FAILURE) return(FALSE);
76:
77: /*
78: * Initialize the icon position variables.
79: */
80: icon_x = icon_info.x;
81: icon_y = icon_info.y;
82:
83: /*
84: * Get the name of the window associated with the icon and
85: * determine its lenght.
86: */
87: status = XFetchName(icon_info.assoc_wind, &icon_str);
88: if (status == FAILURE) return(FALSE);
89: icon_str_len = icon_str ? strlen(icon_str) : 0;
90:
91: /*
92: * If the event is a window exposure event and the icon's name string
93: * is not of zero length, simply repaint the text in the icon window
94: * and return FALSE.
95: */
96: if (button_event->type == ExposeWindow) {
97: XClear(icon);
98: if (icon_str_len != 0) {
99: XTextPad (
100: icon,
101: IPadding, IPadding,
102: icon_str, icon_str_len,
103: IFont, 0, 0,
104: ITextForground, ITextBackground,
105: GXcopy, AllPlanes
106: );
107: /*
108: * Remember to free the icon name string. (Oh Bother! Said Poo.)
109: */
110: free (icon_str);
111: }
112: return(FALSE);
113: }
114:
115: /*
116: * If we have gotten this far event can only be a key pressed event.
117: */
118: kp_event = (XKeyPressedEvent *) button_event;
119:
120: /*
121: * We convert the key pressed event to ascii.
122: */
123: kbd_str = XLookupMapping(kp_event, &nbytes);
124: for (i = 0; i < nbytes; i++) {
125: key_char = kbd_str[i];
126: /*
127: * If the key was <DELETE>, then delete a character from the end of
128: * the name.
129: *
130: * If the key was <CTRL-U>, then wipe out the entire window name.
131: *
132: * All other ctrl keys are squashed.
133: *
134: * All printable characters are appended to the window's name, which
135: * may have to be grown to allow for the extra length.
136: */
137: if (key_char == '\177') {
138: /*
139: * <DELETE>
140: */
141: if (icon_str_len > 0) {
142: icon_str_len--;
143: icon_str[icon_str_len] = '\0';
144: name_changed = TRUE;
145: }
146: }
147: else if (key_char == '\025') {
148: /*
149: * <CTRL-U>
150: */
151: if (icon_str_len > 0) {
152: icon_str_len = 0;
153: *icon_str = '\0';
154: name_changed = TRUE;
155: }
156: }
157: else if (key_char < IFontInfo.firstchar
158: || key_char > IFontInfo.lastchar)
159: /*
160: * Any other random (non-printable) key: ignore it.
161: */
162: /* do nothing */ ;
163: else {
164: /*
165: * ASCII Alphanumerics.
166: */
167: if (icon_str == NULL)
168: icon_str = (char *)malloc(icon_str_len + 2);
169: else
170: icon_str = (char *)realloc(icon_str, (icon_str_len + 2));
171: if (icon_str == NULL) {
172: errno = ENOMEM;
173: Error("GetButton -> Realloc of window name string memory failed.");
174: }
175: icon_str[icon_str_len] = key_char;
176: icon_str[icon_str_len + 1] = '\0';
177: icon_str_len += 1;
178: name_changed = TRUE;
179: }
180: }
181:
182: if (name_changed) {
183: /*
184: * Now that we have changed the size of the icon we have to reconfigure
185: * it so that everything looks good. Oh yes, don't forget to move the
186: * mouse so that it stays in the window!
187: */
188:
189: /*
190: * Set the window name to the new string.
191: */
192: XStoreName(icon_info.assoc_wind, icon_str);
193:
194: /*
195: * Determine the new icon window configuration.
196: */
197: icon_h = IFontInfo.height + (IPadding << 1);
198: icon_w = XQueryWidth(icon_str, IFont);
199: if (icon_w == 0) {
200: icon_w = icon_h;
201: }
202: else {
203: icon_w += (IPadding << 1);
204: }
205:
206: if (icon_x < 0) icon_x = 0;
207: if (icon_y < 0) icon_y = 0;
208: if (icon_x - 1 + icon_w + (IBorderWidth << 1) > ScreenWidth) {
209: icon_x = ScreenWidth - icon_w - (IBorderWidth << 1) + 1;
210: }
211: if (icon_y - 1 + icon_h + (IBorderWidth << 1) > ScreenHeight) {
212: icon_y = ScreenHeight - icon_h - (IBorderWidth << 1) + 1;
213: }
214:
215: XConfigureWindow(icon, icon_x, icon_y, icon_w, icon_h);
216: XWarpMouse(icon, (icon_w >> 1), (icon_h >> 1));
217: }
218:
219: /*
220: * Free the local storage and return FALSE.
221: */
222: if (icon_str) free(icon_str);
223: return(FALSE);
224: }
Defined functions
Defined variables