Annotation of 43BSD/contrib/X/xwm/main.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.