|
|
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.7 86/11/19 20:01:48 jg 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: fprintf(stderr, "%s: Can't open display '%s'\n", ! 247: argv[0], XDisplayName(display)); ! 248: exit(1); ! 249: } ! 250: ! 251: /* ! 252: * Gather information about the root window. ! 253: */ ! 254: status = XQueryWindow(RootWindow, &root_info); ! 255: if (status == FAILURE) { ! 256: Error("Can't acquire root window information from X server."); ! 257: } ! 258: ! 259: ScreenHeight = root_info.height; /* True height of entire screen. */ ! 260: ScreenWidth = root_info.width; /* True width of entire screen. */ ! 261: ! 262: /* ! 263: * Create and store the icon background pixmap. ! 264: */ ! 265: gray_bitmap = XStoreBitmap(16, 16, gray_bits); ! 266: GrayPixmap = XMakePixmap(gray_bitmap, BlackPixel, WhitePixel); ! 267: ! 268: ! 269: /* ! 270: * Set up icon window, icon cursor and pop-up window color parameters. ! 271: */ ! 272: if (reverse) { ! 273: IconCursorFunc = GXcopyInverted; ! 274: IBorder = WhitePixmap; ! 275: IBackground = GrayPixmap; ! 276: ITextForground = WhitePixel; ! 277: ITextBackground = BlackPixel; ! 278: PBorder = BlackPixmap; ! 279: PBackground = WhitePixmap; ! 280: PTextForground = BlackPixel; ! 281: PTextBackground = WhitePixel; ! 282: } ! 283: else { ! 284: IconCursorFunc = GXcopy; ! 285: IBorder = BlackPixmap; ! 286: IBackground = GrayPixmap; ! 287: ITextForground = BlackPixel; ! 288: ITextBackground = WhitePixel; ! 289: PBorder = WhitePixmap; ! 290: PBackground = BlackPixmap; ! 291: PTextForground = WhitePixel; ! 292: PTextBackground = BlackPixel; ! 293: } ! 294: ! 295: /* ! 296: * Store all the cursors. ! 297: */ ! 298: StoreCursors(); ! 299: ! 300: /* ! 301: * Grab all 3 mouse buttons w/ respect to the root window. Grab ! 302: * pressed status with the mouse button mask. ! 303: */ ! 304: status = XGrabButton( ! 305: RootWindow, ! 306: DotCursor, ! 307: (LeftMask | ButtonMask), ! 308: (ButtonPressed | ButtonReleased) ! 309: ); ! 310: if (status == FAILURE) Error("Can't grab left mouse button."); ! 311: status = XGrabButton( ! 312: RootWindow, ! 313: ArrowCrossCursor, ! 314: (MiddleMask | ButtonMask), ! 315: (ButtonPressed | ButtonReleased) ! 316: ); ! 317: if (status == FAILURE) Error("Can't grab middle mouse button."); ! 318: status = XGrabButton( ! 319: RootWindow, ! 320: CircleCursor, ! 321: (RightMask | ButtonMask), ! 322: (ButtonPressed | ButtonReleased) ! 323: ); ! 324: if (status == FAILURE) Error("Can't grab right mouse button."); ! 325: ! 326: /* ! 327: * Load the selected fonts and retrieve the information structure ! 328: * for each. Set global font information pointers. ! 329: */ ! 330: IFont = XGetFont(i_font_name); ! 331: if (IFont == FAILURE) { ! 332: sprintf(message, "Unable to get icon font '%s'.", i_font_name); ! 333: Error(message); ! 334: } ! 335: ! 336: status = XQueryFont(IFont, &IFontInfo); ! 337: if (status == FAILURE) { ! 338: Error("Unable to query X server for icon font information."); ! 339: } ! 340: ! 341: PFont = XGetFont(p_font_name); ! 342: if (PFont == FAILURE) { ! 343: sprintf(message, "Unable to get pop up font '%s'.", p_font_name); ! 344: Error(message); ! 345: } ! 346: ! 347: status = XQueryFont(PFont, &PFontInfo); ! 348: if (status == FAILURE) { ! 349: Error("Unable to query X server for pop up font information."); ! 350: } ! 351: ! 352: /* ! 353: * Calculate size of the resize pop-up window. ! 354: */ ! 355: str_width = XQueryWidth(PText, PFont); ! 356: pop_width = str_width + (PPadding << 1); ! 357: PWidth = pop_width + (PBorderWidth << 1); ! 358: pop_height = PFontInfo.height + (PPadding << 1); ! 359: PHeight = pop_height + (PBorderWidth << 1); ! 360: ! 361: /* ! 362: * Create the pop-up window. Create it at (0, 0) for now, we will ! 363: * move it where we want later. ! 364: */ ! 365: Pop = XCreateWindow( ! 366: RootWindow, ! 367: 0, 0, ! 368: pop_width, pop_height, ! 369: PBorderWidth, ! 370: PBorder, PBackground ! 371: ); ! 372: if (Pop == FAILURE) Error("Can't open pop-up dimension display window."); ! 373: ! 374: /* ! 375: * Main command loop. ! 376: */ ! 377: while (TRUE) { ! 378: /* ! 379: * Get the next mouse button event. Spin our wheels until ! 380: * a button event is returned (ie. GetButton == TRUE). ! 381: * Note that mouse events within an icon window are handled ! 382: * in the "GetButton" function or by the icon's owner if ! 383: * it is not xwm. ! 384: */ ! 385: if (!GetButton(&button_event)) continue; ! 386: ! 387: /* ! 388: * If the button event recieved is not a ButtonPressed event ! 389: * then continue until we find one. ! 390: */ ! 391: if (button_event.type != ButtonPressed) continue; ! 392: ! 393: /* ! 394: * Ok, determine the event window and mouse coordinates. ! 395: */ ! 396: status = XInterpretLocator( ! 397: RootWindow, ! 398: &x, &y, ! 399: &event_win, ! 400: button_event.location ! 401: ); ! 402: if (status == FAILURE) continue; ! 403: ! 404: /* ! 405: * If the event subwindow is 0 then the event ! 406: * occured on the root window. ! 407: */ ! 408: if (event_win == 0) { ! 409: event_win = RootWindow; ! 410: } ! 411: ! 412: /* ! 413: * Invoke a function based on which button was pressed. ! 414: */ ! 415: switch (button_event.detail & ValueMask) { ! 416: case LeftButton: ! 417: /* ! 418: * LeftDown is used to lower or iconify a window if ! 419: * the event window is not the root window. If it is the ! 420: * RoowWindow then circulate all windows down. ! 421: */ ! 422: ! 423: /* ! 424: * Abort any focus sequence that is in progress. ! 425: */ ! 426: focus_seq = FALSE; ! 427: ! 428: if (event_win == RootWindow) { ! 429: XCircWindowDown(RootWindow); ! 430: } ! 431: else { ! 432: LowerIconify(event_win, x, y); ! 433: } ! 434: break; ! 435: ! 436: case MiddleButton: ! 437: /* ! 438: * MiddleDown is used to resize a window and establish the ! 439: * focus window. ! 440: */ ! 441: ! 442: /* ! 443: * If this is not the root window, go ahead and allow it ! 444: * to be changed. ! 445: */ ! 446: changed = FALSE; ! 447: if (event_win != RootWindow) { ! 448: changed = Change(event_win, x, y); ! 449: } ! 450: ! 451: if (focus) { ! 452: /* ! 453: * Two middle clicks will focus the keyboard... ! 454: */ ! 455: if (focus_seq) { ! 456: /* ! 457: * ... and this is the second ... ! 458: */ ! 459: if (focus_win == event_win) { ! 460: /* ! 461: * ... and both have the same event window then ! 462: * focus the keyboard provided the window did not ! 463: * change. This also ends the focus sequence. ! 464: */ ! 465: if (!changed) XFocusKeyboard(event_win); ! 466: focus_seq = FALSE; ! 467: focus_win = RootWindow; ! 468: } ! 469: else { ! 470: /* ! 471: * ... both don't have the same window. This ! 472: * ends the focus sequence. ! 473: */ ! 474: focus_seq = FALSE; ! 475: focus_win = RootWindow; ! 476: } ! 477: } ! 478: else { ! 479: /* ! 480: * Begin a focus sequence, salt away the ! 481: * perspective focus window. ! 482: */ ! 483: focus_seq = TRUE; ! 484: focus_win = event_win; ! 485: } ! 486: } ! 487: break; ! 488: ! 489: case RightButton: ! 490: /* ! 491: * RightDown is used to move a window or bring it to the ! 492: * top of the window stack if the event window is not ! 493: * the root window. If it is the root window then circulate ! 494: * all windows up. ! 495: */ ! 496: ! 497: /* ! 498: * Abort any focus sequence that is in progress. ! 499: */ ! 500: focus_seq = FALSE; ! 501: ! 502: if (event_win == RootWindow) { ! 503: XCircWindowUp(RootWindow); ! 504: } ! 505: else { ! 506: Move(event_win, x, y); ! 507: } ! 508: break; ! 509: ! 510: } ! 511: } ! 512: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.