|
|
1.1 root 1: #include <X/mit-copyright.h>
2:
3: /* Copyright Massachusetts Institute of Technology 1985 */
4:
5: /*
6: * xwm - X Window System window manager main routine.
7: *
8: */
9:
10: #include "xwm.h"
11:
12: #ifdef PROFIL
13: #include <signal.h>
14:
15: #ifndef lint
16: static char *rcsid_main_c = "$Header: main.c,v 10.6 86/02/01 16:10:36 tony Rel $";
17: #endif
18: /*
19: * Dummy handler for profiling.
20: */
21: ptrap()
22: {
23: exit(0);
24: }
25: #endif
26:
27: static short gray_bits[16] = {
28: 0xaaaa, 0x5555, 0xaaaa, 0x5555,
29: 0xaaaa, 0x5555, 0xaaaa, 0x5555,
30: 0xaaaa, 0x5555, 0xaaaa, 0x5555,
31: 0xaaaa, 0x5555, 0xaaaa, 0x5555
32: };
33:
34: main(argc, argv)
35: int argc; /* Argument count. */
36: char **argv; /* Argument vector. */
37: {
38: register int i; /* Loop index. */
39: register int status; /* Routine call return status. */
40: register char *arg; /* Current argument pointer. */
41: int x, y; /* Mouse X and Y coordinates. */
42: int str_width; /* Width in pixels of output string. */
43: int pop_width, pop_height; /* Pop up window width and height. */
44: int temp_button_mask = 0; /* Temporary button event mask. */
45: char *def_val; /* X Default value. */
46: char *i_font_name; /* Icon font name. */
47: char *p_font_name; /* Pop up font name. */
48: char display[256]; /* Display identifier string. */
49: char message[128]; /* Error message buffer. */
50: Bitmap gray_bitmap; /* Gray bitmap used for gray pixmap. */
51: Window event_win; /* Event window. */
52: Window focus_win; /* Keyboard focus window. */
53: WindowInfo root_info; /* Root window info. */
54: XButtonEvent button_event; /* Button input event. */
55: Bool focus_seq = FALSE; /* Has a focus sequence begun? */
56: Bool changed = FALSE; /* Has the window changed? */
57: Bool none = FALSE; /* Allow the mouse with no keys. */
58: Bool focus = FALSE; /* Allow input focusing? */
59: Bool reverse = FALSE; /* Reverse video? */
60:
61: #ifdef PROFIL
62: signal(SIGTERM, ptrap);
63: #endif
64:
65: /*
66: * Set up internal defaults.
67: */
68: i_font_name = DEF_I_FONT;
69: p_font_name = DEF_P_FONT;
70: CursorFunc = DEF_FUNC;
71: ButtonMask = DEF_BUTTON_MASK;
72: Delta = DEF_DELTA;
73: IBorderWidth = DEF_ICON_BORDER_WIDTH;
74: IPadding = DEF_ICON_PADDING;
75: PBorderWidth = DEF_POP_BORDER_WIDTH;
76: PPadding = DEF_POP_PADDING;
77:
78: /*
79: * Initialize fixed globals.
80: */
81: Grid = FALSE;
82: Zap = FALSE;
83:
84: /*
85: * Set XErrorFunction to be non-terminating.
86: */
87: XErrorHandler(XError);
88:
89: /*
90: * Check for X defaults.
91: */
92: def_val = XGetDefault(argv[0], "IconFont");
93: if (def_val != NULL) i_font_name = def_val;
94:
95: def_val = XGetDefault(argv[0], "BodyFont");
96: if (def_val != NULL) p_font_name = def_val;
97:
98: def_val = XGetDefault(argv[0], "InternalBorder");
99: if (def_val != NULL) {
100: IPadding = atoi(def_val);
101: PPadding = atoi(def_val);
102: }
103:
104: def_val = XGetDefault(argv[0], "BorderWidth");
105: if (def_val != NULL) {
106: IBorderWidth = atoi(def_val);
107: PBorderWidth = atoi(def_val);
108: }
109:
110: def_val = XGetDefault(argv[0], "ReverseVideo");
111: if (def_val != NULL) {
112: if (strcmp (def_val, "on") == 0) reverse = TRUE;
113: }
114:
115: /*
116: * Parse the command line arguments.
117: */
118: for (i = 1; i < argc; i++) {
119: arg = argv[i];
120: switch (*arg) {
121: case '\0':
122: continue;
123: case '-':
124: arg++;
125: if (*arg == '\0') break;
126: for (; *arg; arg++) {
127: switch (*arg) {
128: case 'c':
129: /*
130: * Add the control key to the mouse button mask.
131: */
132: temp_button_mask |= ControlMask;
133: break;
134: case 'd':
135: /*
136: * Check for a debug flag.
137: */
138: Debug = TRUE;
139: break;
140: case 's':
141: /*
142: * Add the shift key to the mouse button mask.
143: */
144: temp_button_mask |= ShiftMask;
145: break;
146: case 'm':
147: /*
148: * Add the meta key to the mouse button mask.
149: */
150: temp_button_mask |= MetaMask;
151: break;
152: case 'n':
153: /*
154: * No keys are needed with the mouse.
155: */
156: none = TRUE;
157: break;
158: case 'f':
159: /*
160: * Require double clicking to focus input.
161: */
162: focus = TRUE;
163: break;
164: case 'g':
165: /*
166: * Display the tic tac toe grid on window change.
167: */
168: Grid = TRUE;
169: break;
170: case 'r':
171: /*
172: * Make icons and pop-ups reverse video.
173: */
174: reverse = TRUE;
175: break;
176: case 'z':
177: /*
178: * Use zap effect?
179: */
180: Zap = TRUE;
181: break;
182: }
183: }
184: break;
185: case '+':
186: CursorFunc = atoi(arg + 1);
187: if (CursorFunc <= 0 || CursorFunc > 15) {
188: /*
189: * Oops, cursor function code out of range!
190: */
191: errno = EDOM;
192: sprintf(
193: message,
194: "Cursor function code '%d' out of range (0 - 14).",
195: CursorFunc
196: );
197: Error(message);
198: }
199: break;
200: case '@':
201: Delta = atoi(arg + 1);
202: if (Delta <= 0 || Delta > 100) {
203: /*
204: * Oops, delta value out of range!
205: */
206: errno = EDOM;
207: sprintf(
208: message,
209: "Delta value '%d' out of range (1 - 99).",
210: Delta
211: );
212: Error(message);
213: }
214: break;
215: case 'f':
216: if ((arg[1] == 'n') && (arg[2] == '=')) {
217: p_font_name = arg + 3;
218: }
219: else if ((arg[1] == 'i') && (arg[2] == '=')) {
220: i_font_name = arg + 3;
221: }
222: break;
223: default:
224: /*
225: * All that is left is a possible display string.
226: */
227: strcpy(display, arg);
228: }
229: }
230:
231: /*
232: * Set the global mouse button event mask.
233: */
234:
235: if (temp_button_mask) ButtonMask = temp_button_mask;
236:
237: if (none) ButtonMask = 0;
238:
239: /*
240: * Open the Display.
241: */
242: if (XOpenDisplay(display) == NULL) {
243: /*
244: * Oops, can't open the display!
245: */
246: sprintf(message, "Unable to open display '%s'.", display);
247: Error(message);
248: }
249:
250: /*
251: * Gather information about the root window.
252: */
253: status = XQueryWindow(RootWindow, &root_info);
254: if (status == FAILURE) {
255: Error("Can't acquire root window information from X server.");
256: }
257:
258: ScreenHeight = root_info.height; /* True height of entire screen. */
259: ScreenWidth = root_info.width; /* True width of entire screen. */
260:
261: /*
262: * Create and store the icon background pixmap.
263: */
264: gray_bitmap = XStoreBitmap(16, 16, gray_bits);
265: GrayPixmap = XMakePixmap(gray_bitmap, BlackPixel, WhitePixel);
266:
267:
268: /*
269: * Set up icon window, icon cursor and pop-up window color parameters.
270: */
271: if (reverse) {
272: IconCursorFunc = GXcopyInverted;
273: IBorder = WhitePixmap;
274: IBackground = GrayPixmap;
275: ITextForground = WhitePixel;
276: ITextBackground = BlackPixel;
277: PBorder = BlackPixmap;
278: PBackground = WhitePixmap;
279: PTextForground = BlackPixel;
280: PTextBackground = WhitePixel;
281: }
282: else {
283: IconCursorFunc = GXcopy;
284: IBorder = BlackPixmap;
285: IBackground = GrayPixmap;
286: ITextForground = BlackPixel;
287: ITextBackground = WhitePixel;
288: PBorder = WhitePixmap;
289: PBackground = BlackPixmap;
290: PTextForground = WhitePixel;
291: PTextBackground = BlackPixel;
292: }
293:
294: /*
295: * Store all the cursors.
296: */
297: StoreCursors();
298:
299: /*
300: * Grab all 3 mouse buttons w/ respect to the root window. Grab
301: * pressed status with the mouse button mask.
302: */
303: status = XGrabButton(
304: RootWindow,
305: DotCursor,
306: (LeftMask | ButtonMask),
307: (ButtonPressed | ButtonReleased)
308: );
309: if (status == FAILURE) Error("Can't grab left mouse button.");
310: status = XGrabButton(
311: RootWindow,
312: ArrowCrossCursor,
313: (MiddleMask | ButtonMask),
314: (ButtonPressed | ButtonReleased)
315: );
316: if (status == FAILURE) Error("Can't grab middle mouse button.");
317: status = XGrabButton(
318: RootWindow,
319: CircleCursor,
320: (RightMask | ButtonMask),
321: (ButtonPressed | ButtonReleased)
322: );
323: if (status == FAILURE) Error("Can't grab right mouse button.");
324:
325: /*
326: * Load the selected fonts and retrieve the information structure
327: * for each. Set global font information pointers.
328: */
329: IFont = XGetFont(i_font_name);
330: if (IFont == FAILURE) {
331: sprintf(message, "Unable to get icon font '%s'.", i_font_name);
332: Error(message);
333: }
334:
335: status = XQueryFont(IFont, &IFontInfo);
336: if (status == FAILURE) {
337: Error("Unable to query X server for icon font information.");
338: }
339:
340: PFont = XGetFont(p_font_name);
341: if (PFont == FAILURE) {
342: sprintf(message, "Unable to get pop up font '%s'.", p_font_name);
343: Error(message);
344: }
345:
346: status = XQueryFont(PFont, &PFontInfo);
347: if (status == FAILURE) {
348: Error("Unable to query X server for pop up font information.");
349: }
350:
351: /*
352: * Calculate size of the resize pop-up window.
353: */
354: str_width = XQueryWidth(PText, PFont);
355: pop_width = str_width + (PPadding << 1);
356: PWidth = pop_width + (PBorderWidth << 1);
357: pop_height = PFontInfo.height + (PPadding << 1);
358: PHeight = pop_height + (PBorderWidth << 1);
359:
360: /*
361: * Create the pop-up window. Create it at (0, 0) for now, we will
362: * move it where we want later.
363: */
364: Pop = XCreateWindow(
365: RootWindow,
366: 0, 0,
367: pop_width, pop_height,
368: PBorderWidth,
369: PBorder, PBackground
370: );
371: if (Pop == FAILURE) Error("Can't open pop-up dimension display window.");
372:
373: /*
374: * Main command loop.
375: */
376: while (TRUE) {
377: /*
378: * Get the next mouse button event. Spin our wheels until
379: * a button event is returned (ie. GetButton == TRUE).
380: * Note that mouse events within an icon window are handled
381: * in the "GetButton" function or by the icon's owner if
382: * it is not xwm.
383: */
384: if (!GetButton(&button_event)) continue;
385:
386: /*
387: * If the button event recieved is not a ButtonPressed event
388: * then continue until we find one.
389: */
390: if (button_event.type != ButtonPressed) continue;
391:
392: /*
393: * Ok, determine the event window and mouse coordinates.
394: */
395: status = XInterpretLocator(
396: RootWindow,
397: &x, &y,
398: &event_win,
399: button_event.location
400: );
401: if (status == FAILURE) continue;
402:
403: /*
404: * If the event subwindow is 0 then the event
405: * occured on the root window.
406: */
407: if (event_win == 0) {
408: event_win = RootWindow;
409: }
410:
411: /*
412: * Invoke a function based on which button was pressed.
413: */
414: switch (button_event.detail & ValueMask) {
415: case LeftButton:
416: /*
417: * LeftDown is used to lower or iconify a window if
418: * the event window is not the root window. If it is the
419: * RoowWindow then circulate all windows down.
420: */
421:
422: /*
423: * Abort any focus sequence that is in progress.
424: */
425: focus_seq = FALSE;
426:
427: if (event_win == RootWindow) {
428: XCircWindowDown(RootWindow);
429: }
430: else {
431: LowerIconify(event_win, x, y);
432: }
433: break;
434:
435: case MiddleButton:
436: /*
437: * MiddleDown is used to resize a window and establish the
438: * focus window.
439: */
440:
441: /*
442: * If this is not the root window, go ahead and allow it
443: * to be changed.
444: */
445: changed = FALSE;
446: if (event_win != RootWindow) {
447: changed = Change(event_win, x, y);
448: }
449:
450: if (focus) {
451: /*
452: * Two middle clicks will focus the keyboard...
453: */
454: if (focus_seq) {
455: /*
456: * ... and this is the second ...
457: */
458: if (focus_win == event_win) {
459: /*
460: * ... and both have the same event window then
461: * focus the keyboard provided the window did not
462: * change. This also ends the focus sequence.
463: */
464: if (!changed) XFocusKeyboard(event_win);
465: focus_seq = FALSE;
466: focus_win = RootWindow;
467: }
468: else {
469: /*
470: * ... both don't have the same window. This
471: * ends the focus sequence.
472: */
473: focus_seq = FALSE;
474: focus_win = RootWindow;
475: }
476: }
477: else {
478: /*
479: * Begin a focus sequence, salt away the
480: * perspective focus window.
481: */
482: focus_seq = TRUE;
483: focus_win = event_win;
484: }
485: }
486: break;
487:
488: case RightButton:
489: /*
490: * RightDown is used to move a window or bring it to the
491: * top of the window stack if the event window is not
492: * the root window. If it is the root window then circulate
493: * all windows up.
494: */
495:
496: /*
497: * Abort any focus sequence that is in progress.
498: */
499: focus_seq = FALSE;
500:
501: if (event_win == RootWindow) {
502: XCircWindowUp(RootWindow);
503: }
504: else {
505: Move(event_win, x, y);
506: }
507: break;
508:
509: }
510: }
511: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.