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