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

1.1       root        1: #include "wm.h"
                      2: 
                      3: #ifndef lint
                      4: static char *rcsid_wmsubs_c = "$Header: xnwm.c,v 10.4 86/02/01 16:02:23 tony Rel $";
                      5: #endif
                      6: 
                      7: #define default_frame_width 5
                      8: #define default_mask MetaMask
                      9: #define default_menu_font "8x13"
                     10: #define default_size_font "8x13"
                     11: #define default_icon_font "8x13"
                     12: #define default_iconify_delta 5
                     13: #define default_menu_x 0
                     14: #define default_menu_y 0
                     15: 
                     16: /* Default button assignments; the numbers are indices into the
                     17:    menuOp array */
                     18: 
                     19: #define default_left 0
                     20: #define default_middle 1
                     21: #define default_right 2
                     22: #define unassigned_button -1
                     23: #define popup_button -2
                     24: 
                     25: /* Convert 0,1,2 into XRight(Middle,Left)Mask */
                     26: #define Button(i) (1 << (8 + (i)))
                     27: 
                     28: #include "wm.cursor"
                     29: 
                     30: #include "buttons.raster"
                     31: Pixmap buttonPixmap[3];
                     32: 
                     33: Window menu;
                     34: typedef int (*ptrToFunc) ();
                     35: int Raise(), Lower(), Move(), Resize(), IconifyOrDeIconify(),
                     36:        Select(), Circulate(), Assign(), Unassigned();
                     37: char *label[] = {"Select", "Raise", "Move", "(De)Iconify",
                     38:        "Lower", "Resize", "Circulate", "Assign", ""};
                     39: ptrToFunc menuOp[] = {Select, Raise, Move, IconifyOrDeIconify,
                     40:        Lower, Resize, Circulate, Assign};
                     41: int needsWindow[] = {TRUE, TRUE, TRUE, TRUE,
                     42:        TRUE, TRUE, FALSE, TRUE};
                     43: int canDoToMenu[] = {FALSE, TRUE, TRUE, FALSE,
                     44:        TRUE, FALSE, TRUE, TRUE};
                     45: /* "item" needs an extra entry at the end */
                     46: Window item[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
                     47: int buttonFunc[3] = {default_right, default_middle, default_left};
                     48: int itemcount, itemWidth, itemHeight;
                     49: int menuWidth, menuHeight, menuX, menuY;
                     50: char code[] = "srmilzc";       /* button assignment codes for command line */
                     51: int skinny = FALSE, twoRows = FALSE, vertical = FALSE;
                     52: int lastMenuOp = -1;
                     53: int doingOp = FALSE;
                     54: 
                     55: int savex, savey;              /* Where and what the popup menu obscures */
                     56: Pixmap saveScreen;
                     57: Pixmap menuImage = 0;          /* What the popup menu looks like */
                     58: int popupSaved = FALSE;                /* True if a popup image is saved */
                     59: 
                     60: int reverse;                   /* whether to reverse the normal colors */
                     61: int buttonGXfunc;              /* function to put up the button picture */
                     62: 
                     63: char *index();
                     64: 
                     65: main(argc, argv)
                     66:        int argc;
                     67:        char **argv;
                     68: {
                     69:        Window w;
                     70:        BEvent button;
                     71:        int raisedMenu = FALSE;
                     72: 
                     73:        SetUpEverything(argc, argv);
                     74: 
                     75:        while (TRUE) {
                     76:            GetButton(&button);
                     77: 
                     78:            /* If it's a ButtonReleased ignore; it's just left
                     79:               over from some old click */
                     80: 
                     81:            if (button.type == ButtonReleased) continue;
                     82: 
                     83:            InterpretLocatorW(RootWindow, &w, button.location);
                     84: 
                     85:            /* If in background, raise menu or move back if just raised.
                     86:               If using popup windows, map the popup window.  Only do this
                     87:               as long as the button is not bound to Select */
                     88: 
                     89:            if (w == 0 && NonSelect(&button)) {
                     90:                if (popup) MapPopup(button.location);
                     91:                else {
                     92:                    if (raisedMenu) XMoveWindow(menu, menuX, menuY);
                     93:                    else XRaiseWindow(menu);
                     94:                    raisedMenu = TRUE;
                     95:                }
                     96:                continue;
                     97:            } else raisedMenu = FALSE;
                     98: 
                     99:            /* If in menu, do appropriate function */
                    100: 
                    101:            if (w == menu) {
                    102:                ProcessMenuFunction(&button);
                    103:                if (popup) UnmapPopup();
                    104:                continue;
                    105:            }
                    106: 
                    107:            /* Otherwise do preassigned button function */
                    108: 
                    109:            DoButtonFunc(&button, w);
                    110:        }
                    111: }
                    112: 
                    113: SetUpEverything(argc, argv)
                    114:        int argc;
                    115:        char **argv;
                    116: {
                    117:        char *mfname = default_menu_font;       /* font to use */
                    118:        char *sfname = default_size_font;       /* font to use */
                    119:        char *ifname = default_icon_font;       /* font to use */
                    120:        char *location = "";
                    121:        char display[256];              /* display to use */
                    122: 
                    123:        frameWidth = default_frame_width;
                    124:        mask = default_mask;
                    125:        iconifyDelta = default_iconify_delta;
                    126:        menuX = menuY = 0;
                    127:        freeze = TRUE;
                    128:        popup = FALSE;
                    129:        reverse = FALSE;
                    130: 
                    131:        GetDefaults(argv[0], &mfname, &sfname, &ifname, &location);
                    132:        ProcessArgs(argc, argv, display, &mfname, &sfname, &ifname, &location);
                    133:        OpenDisplay (display);
                    134:        StoreCursors();
                    135:        StorePixmaps();
                    136:        SetUpFonts(mfname, sfname, ifname);
                    137:        SetUpMenu(location);
                    138:        GrabButtons();
                    139:        InitializeWm();
                    140: }
                    141: 
                    142: GetDefaults(progname, mfname, sfname, ifname, location)
                    143:        char *progname;
                    144:        char **mfname, **sfname, **ifname, **location;
                    145: {
                    146:        register char *option;
                    147:        int newmask = 0;
                    148: 
                    149:        if ((option = XGetDefault(progname,"MenuFont")) != NULL) {
                    150:            *mfname = option;
                    151:        }
                    152:        if ((option = XGetDefault(progname,"SizeFont")) != NULL) {
                    153:            *sfname = option;
                    154:        }
                    155:        if ((option = XGetDefault(progname,"IconFont")) != NULL) {
                    156:            *ifname = option;
                    157:        }       
                    158:        if ((option = XGetDefault(progname,"ReverseVideo")) != NULL) {
                    159:            if (strcmp(option, "on") == 0) reverse = TRUE;
                    160:        }
                    161:        if ((option = XGetDefault(progname,"FrameWidth")) != NULL) {
                    162:            frameWidth = atoi(option);
                    163:        }
                    164:        if ((option = XGetDefault(progname,"IconifyDelta")) != NULL) {
                    165:            iconifyDelta = atoi(option);
                    166:        }
                    167:        if ((option = XGetDefault(progname,"MenuFormat")) != NULL) {
                    168:            if (index(option, 't') != NULL) skinny = TRUE;
                    169:            if (index(option, '2') != NULL) twoRows = skinny = TRUE;
                    170:            if (index(option, 'v') != NULL) vertical = skinny = TRUE;
                    171:        }
                    172:        if ((option = XGetDefault(progname,"Freeze")) != NULL) {
                    173:            if (strcmp(option, "off") == 0) freeze = FALSE;
                    174:        }
                    175:        if ((option = XGetDefault(progname,"KeyCombination")) != NULL) {
                    176:            if (index(option, 'c') != NULL) newmask |= ControlMask;
                    177:            if (index(option, 's') != NULL) newmask |= ShiftMask;
                    178:            if (index(option, 'm') != NULL) newmask |= MetaMask;
                    179:            if (index(option, 'l') != NULL) newmask |= ShiftLockMask;
                    180:            if (index(option, 'n') != NULL) mask = 0;
                    181:            else if (newmask) mask = newmask;
                    182:        }
                    183:        if ((option = XGetDefault(progname,"LeftButton")) != NULL) {
                    184:            AssignButton(LeftButton, option[0]);
                    185:        }
                    186:        if ((option = XGetDefault(progname,"MiddleButton")) != NULL) {
                    187:            AssignButton(MiddleButton, option[0]);
                    188:        }
                    189:        if ((option = XGetDefault(progname,"RightButton")) != NULL) {
                    190:            AssignButton(RightButton, option[0]);
                    191:        }
                    192:        if ((option = XGetDefault(progname,"Geometry")) != NULL) {
                    193:            *location = option;
                    194:        }
                    195: 
                    196: }
                    197: 
                    198: ProcessArgs(argc, argv, display, mfname, sfname, ifname, location)
                    199:        int argc;
                    200:        char **argv;
                    201:        char *display;
                    202:        char **mfname, **sfname, **ifname, **location;
                    203: {
                    204:        int i, newmask = 0, none = FALSE;
                    205:        register char *arg;
                    206: 
                    207:        for (i = 1; i < argc; i++) {
                    208:            arg = argv[i];
                    209:            switch (*arg) {
                    210:                case '\0':
                    211:                    continue;
                    212: 
                    213:                case '-':
                    214:                    arg++;
                    215:                    if (*arg == '\0') mask = 0;
                    216:                    else {
                    217:                        newmask = 0;
                    218:                        for (; *arg; arg++) {
                    219:                            switch (*arg) {
                    220:                                case 'h':
                    221:                                    Syntax();
                    222:                                    break;
                    223: 
                    224:                                case 'c':
                    225:                                    newmask |= ControlMask;
                    226:                                    break;
                    227: 
                    228:                                case 's':
                    229:                                    newmask |= ShiftMask;
                    230:                                    break;
                    231: 
                    232:                                case 'm':
                    233:                                    newmask |= MetaMask;
                    234:                                    break;
                    235: 
                    236:                                case 'l':
                    237:                                    newmask |= ShiftLockMask;
                    238:                                    break;
                    239: 
                    240:                                case 'n':
                    241:                                    none = TRUE;
                    242:                                    break;
                    243: 
                    244:                                case 'f':
                    245:                                    freeze = FALSE;
                    246:                                    break;                              
                    247: 
                    248:                                case 'r':
                    249:                                    reverse = TRUE;
                    250:                                    break;
                    251: 
                    252:                                case '2':
                    253:                                    twoRows = skinny = TRUE;
                    254:                                    vertical = FALSE;
                    255:                                    break;
                    256: 
                    257:                                case 'v':
                    258:                                    vertical = skinny = TRUE;
                    259:                                    twoRows = FALSE;
                    260:                                    break;
                    261: 
                    262:                                case 't':
                    263:                                    skinny = TRUE;
                    264:                                    vertical = twoRows = FALSE;
                    265:                                    break;
                    266: 
                    267:                                default:
                    268:                                    Syntax();
                    269:                                    break;
                    270:                            }
                    271:                        }
                    272:                        if (newmask) mask = newmask;
                    273:                        if (none) mask = 0;
                    274:                    }
                    275:                    break;
                    276: 
                    277:                case '@':
                    278:                    frameWidth = atoi(arg+1);
                    279:                    if (frameWidth < 0 || frameWidth > 100) {
                    280:                        errno = EDOM;
                    281:                        perror("xnwm:");
                    282:                    }
                    283:                    break;
                    284: 
                    285:                case '%':
                    286:                    iconifyDelta = atoi(arg+1);
                    287:                    break;
                    288: 
                    289:                case '=':
                    290:                    *location = arg+1;
                    291:                    break;
                    292: 
                    293:                default:
                    294:                    if (arg[1] == '=') {
                    295:                        switch (*arg) {
                    296:                            case 'l':
                    297:                                AssignButton(LeftButton, arg[2]);
                    298:                                break;
                    299: 
                    300:                            case 'm':
                    301:                                AssignButton(MiddleButton, arg[2]);
                    302:                                break;
                    303: 
                    304:                            case 'r':
                    305:                                AssignButton(RightButton, arg[2]);
                    306:                                break;
                    307: 
                    308:                            default:
                    309:                                Syntax();
                    310:                                break;                          
                    311:                        }
                    312:                    } else if (arg[0] == 'f' && arg[2] == '=') {
                    313:                        switch (arg[1]) {
                    314:                            case 'm':
                    315:                                *mfname = arg+3;
                    316:                                break;
                    317: 
                    318:                            case 's':
                    319:                                *sfname = arg+3;
                    320:                                break;
                    321: 
                    322:                            case 'i':
                    323:                                *ifname = arg+3;
                    324:                                break;
                    325: 
                    326:                            default:
                    327:                                Syntax();
                    328:                                break;
                    329:                        }
                    330:                    } else strcpy(display, arg);
                    331:            }
                    332:        }
                    333: 
                    334:        if (buttonFunc[RightButton] == popup_button ||
                    335:                buttonFunc[MiddleButton] == popup_button ||
                    336:                buttonFunc[LeftButton] == popup_button) {
                    337:            popup = vertical = skinny = TRUE;
                    338:        }
                    339: }
                    340: 
                    341: AssignButton(which, arg)
                    342:        int which;
                    343:        char arg;
                    344: {
                    345:        char *ch;
                    346: 
                    347:        if (arg == '\0') {
                    348:            buttonFunc[which] = unassigned_button;
                    349:            return;
                    350:        } else if (arg == 'p') {
                    351:            buttonFunc[which] = popup_button;
                    352:            return;
                    353:        }
                    354:        ch = index(code, arg);
                    355:        if (ch == NULL) {
                    356:            errno = EDOM;
                    357:            perror ("xnwm:");
                    358:        } else buttonFunc[which] = ch - code;
                    359: }
                    360: 
                    361: Syntax()
                    362: {
                    363:        puts("Usage: xnwm {-csmln} {-f} {-r} {-2vt} {@[framewidth]}");
                    364:        puts("       {%[iconifyDelta]} {=[{+-}xoff[{+-}yoff]]}");
                    365:        puts("       {l={srmilzcp}} {m={srmilzcp}} {r={srmilzcp}}");
                    366:        puts("       {fm=menu_font} {fs=size_font} {fi=icon_font}");
                    367:        puts("       {[host]:vs}");     /* whew */
                    368: 
                    369:        exit(0);
                    370: }
                    371: 
                    372: OpenDisplay(display)
                    373:        char *display;
                    374: {
                    375:        WindowInfo winfo;
                    376: 
                    377:        if (XOpenDisplay(display) == NULL) {
                    378:            Error ("Couldn't open display in OpenDisplay");
                    379:        }
                    380: 
                    381:        QueryWindow(RootWindow, &winfo);
                    382:        screen_height = winfo.height;
                    383:        screen_width = winfo.width;
                    384: 
                    385:        XSelectInput(RootWindow,
                    386:                ButtonPressed | ButtonReleased | UnmapWindow | FocusChange);
                    387: 
                    388:        if (reverse) {
                    389:            bgColor = BlackPixel;
                    390:            bgPixmap = BlackPixmap;
                    391:            fgColor = WhitePixel;
                    392:            fgPixmap = WhitePixmap;
                    393:            buttonGXfunc = GXor;
                    394:        } else {
                    395:            bgColor = WhitePixel;
                    396:            bgPixmap = WhitePixmap;
                    397:            fgColor = BlackPixel;
                    398:            fgPixmap = BlackPixmap;
                    399:            buttonGXfunc = GXand;
                    400:        }
                    401: }
                    402: 
                    403: StoreCursors()
                    404: {
                    405:        wmCursor = XCreateCursor(nwm_width, nwm_height, 
                    406:                (caddr_t) nwm_bits, (caddr_t) NULL,
                    407:                1, 1,
                    408:                fgColor, bgColor,
                    409:                GXcopyInverted);
                    410:        if (wmCursor == NULL) {
                    411:            Error("Couldn't store wmCursor in StoreCursors");
                    412:        }
                    413: }
                    414: 
                    415: StorePixmaps()
                    416: {
                    417:        static short gray_bits[] = {
                    418:            0xaaaa, 0x5555, 0xaaaa, 0x5555,
                    419:            0xaaaa, 0x5555, 0xaaaa, 0x5555,
                    420:            0xaaaa, 0x5555, 0xaaaa, 0x5555,
                    421:            0xaaaa, 0x5555, 0xaaaa, 0x5555
                    422:        };
                    423: 
                    424:        buttonPixmap[RightButton] =
                    425:                MakePixmap(button_width, button_height,
                    426:                (caddr_t) rbutton_bits, bgColor, fgColor);
                    427: 
                    428:        buttonPixmap[MiddleButton] =
                    429:                MakePixmap(button_width, button_height,
                    430:                (caddr_t) mbutton_bits, bgColor, fgColor);
                    431: 
                    432:        buttonPixmap[LeftButton] =
                    433:                MakePixmap(button_width, button_height,
                    434:                (caddr_t) lbutton_bits, bgColor, fgColor);
                    435: 
                    436:        gray = MakePixmap(16, 16,
                    437:                (caddr_t) gray_bits, bgColor, fgColor);
                    438: }
                    439: 
                    440: Pixmap MakePixmap(width, height, bits, fg, bg)
                    441:        int width, height;
                    442:        caddr_t bits;
                    443:        int fg, bg;
                    444: {
                    445:        Bitmap b;
                    446:        Pixmap p;
                    447: 
                    448:        b = XStoreBitmap(width, height, bits);
                    449:        if (b == NULL) Error("Couldn't store bitmap in MakePixmap");
                    450:        p = XMakePixmap (b, fg, bg);
                    451:        if (p == NULL) Error("Couldn't make pixmap in MakePixmap");
                    452:        XFreeBitmap(b);
                    453:        return p;
                    454: }
                    455: 
                    456: SetUpFonts(mfname, sfname, ifname)
                    457:        char *mfname, *sfname, *ifname;
                    458: {
                    459:        menufont = XGetFont(mfname);
                    460:        if (menufont == NULL) Error("Couldn't store menu font in SetUpFont");
                    461:        sizefont = XGetFont(sfname);
                    462:        if (sizefont == NULL) Error("Couldn't store size font in SetUpFont");
                    463:        iconfont = XGetFont(ifname);
                    464:        if (iconfont == NULL) Error("Couldn't store icon font in SetUpFont");
                    465: }
                    466: 
                    467: SetUpMenu(location)
                    468:        char *location;
                    469: {
                    470:        register int i = 0;
                    471:        int width = 0, textwidth;
                    472:        int x, y;
                    473:        char xSign, ySign;
                    474: 
                    475:        while (label[i][0] != '\0') {
                    476:            textwidth = XQueryWidth(label[i], menufont);
                    477:            if (textwidth == 0) {
                    478:                Error("Couldn't query string width in SetUpMenu");
                    479:            }
                    480:            if (textwidth > width) width = textwidth;
                    481:            i++;
                    482:        }
                    483: 
                    484:        itemcount = i;
                    485:        if (skinny) {
                    486:            itemWidth = 1 + 3 + width + 3 + button_width + 3 + 1;
                    487:        } else itemWidth = screen_width / itemcount;
                    488:        itemHeight = 20;
                    489: 
                    490:        if (vertical) {
                    491:            menuWidth = itemWidth;
                    492:            menuHeight = itemcount * itemHeight;
                    493:        } else if (twoRows) {
                    494:            menuWidth = itemWidth * ((itemcount+1) >> 1);
                    495:            menuHeight =  itemHeight * 2;
                    496:        } else {
                    497:            menuWidth = itemWidth * itemcount;
                    498:            menuHeight = itemHeight;
                    499:        }
                    500:        if (!popup && *location != '\0') {
                    501:            /* Interpret the location string */
                    502: 
                    503:            InterpLocation(location, &x, &y, &xSign, &ySign);
                    504: 
                    505:            if (xSign == '+') menuX = x;
                    506:            else menuX = screen_width - x - menuWidth;
                    507: 
                    508:            if (ySign == '+') menuY = y;
                    509:            else menuY = screen_height - y - menuHeight;
                    510:        }
                    511: 
                    512:        menu = XCreateWindow(RootWindow, menuX, menuY, menuWidth, menuHeight,
                    513:                1, fgPixmap, bgPixmap);
                    514:        if (menu == NULL) Error ("Couldn't open menu in SetUpMenu");
                    515:        XStoreName(menu, "xnwm menu");
                    516:        XDefineCursor(menu, wmCursor);
                    517: 
                    518:        if (popup) XSelectInput(menu, LeaveWindow);
                    519:        else XSelectInput(menu, ExposeWindow);
                    520: 
                    521:        if (!popup) {
                    522:            x = y = -1;
                    523: 
                    524:            for (i = 0; i < itemcount; i++) {
                    525:                if (twoRows && i == (itemcount+1) >> 1) {
                    526:                    y = itemHeight;
                    527:                    x = -1;
                    528:                }
                    529:                item[i] = XCreateWindow (menu, x, y, itemWidth, itemHeight, 1,
                    530:                        fgPixmap, bgPixmap);
                    531:                if (item[i] == NULL) Error ("Couldn't open item in SetUpMenu");
                    532:                if (vertical) y += itemHeight;
                    533:                else x += itemWidth;
                    534:            }
                    535:            XMapSubwindows(menu);
                    536:            XMapWindow(menu);
                    537:        }
                    538: 
                    539:        menuWidth += 2;         /* Consider the border in from now on */
                    540:        menuHeight += 2;
                    541: 
                    542:        /* Don't draw anything; the expose event will cause that */
                    543: }
                    544: 
                    545: InterpLocation(location, x, y, xSign, ySign)
                    546:        register char *location;
                    547:        register int *x, *y;
                    548:        char *xSign, *ySign;
                    549: {
                    550:        *xSign = *location;
                    551: 
                    552:        switch (*location) {
                    553:            case '+':
                    554:            case '-':
                    555:                location++;
                    556:                *x = 0;
                    557:                while(*location >= '0' && *location <= '9') {
                    558:                    *x = 10 * *x + (*location++ - '0');
                    559:                }
                    560:                break;
                    561: 
                    562:            default:
                    563:                Syntax();
                    564:                break;
                    565:        }
                    566: 
                    567:        *ySign = *location;
                    568: 
                    569:        switch (*location) {
                    570:            case '+':
                    571:            case '-':
                    572:                location++;
                    573:                *y = 0;
                    574:                while(*location >= '0' && *location <= '9') {
                    575:                    *y = 10 * *y + (*location++ - '0');
                    576:                }
                    577:                break;
                    578: 
                    579:            default:
                    580:                Syntax();
                    581:                break;
                    582:        }
                    583: 
                    584:        if (*location != '\0') Syntax();
                    585: }
                    586: 
                    587: GrabButtons()
                    588: {
                    589:        register int i;
                    590: 
                    591:        for (i = 0; i < 3; i++) {
                    592:            if (buttonFunc[i] != unassigned_button) {
                    593:                status = XGrabButton(RootWindow, wmCursor,
                    594:                        mask | Button(i),
                    595:                        ButtonPressed|ButtonReleased);
                    596:                if (status == NULL) {
                    597:                    Error("Couldn't grab button in GrabButtons");
                    598:                }
                    599:            }
                    600:        }
                    601: }
                    602: 
                    603: ProcessMenuFunction(button)
                    604:        BEvent *button;
                    605: {
                    606:        Window w;
                    607:        register int i = 0;
                    608: 
                    609:        InterpretLocatorW(menu, &w, button->location);
                    610:        while (item[i] != NULL && item[i] != w) i++;
                    611: 
                    612:        if (item[i]) {
                    613:            InvertButton(i);
                    614:            DoOperation(i, button->detail);
                    615:            DisplayButton(i);
                    616:            lastMenuOp = i;
                    617:        }
                    618: }
                    619: 
                    620: DoOperation(i, which)
                    621:        int i, which;
                    622: {
                    623:        BEvent newbutton;
                    624:        Window w;
                    625:        WindowInfo winfo;
                    626: 
                    627:        /* First wait for the upbutton; if it doesn't occur or
                    628:           occurs in a different window abort */
                    629: 
                    630:        GetButton(&newbutton);
                    631:        InterpretLocatorW(menu, &w, newbutton.location);
                    632:        if (!MatchUp(newbutton, which) || w != item[i]) return;
                    633: 
                    634:        doingOp = TRUE;
                    635: 
                    636:        /* If the function needs a window, get one */
                    637: 
                    638:        if (needsWindow[i]) {
                    639:            status = XGrabMouse(RootWindow, wmCursor,
                    640:                    ButtonPressed | ButtonReleased);
                    641:            if (status  == NULL) Error ("Couldn't grab mouse in DoOperation");
                    642:            GetButton(&newbutton);
                    643: 
                    644:            /* This should be the same button as was pushed to select
                    645:               the function */
                    646: 
                    647:            if (!MatchDown(newbutton, which)) {
                    648:                XUngrabMouse();
                    649:                doingOp = FALSE;
                    650:                return;
                    651:            }
                    652: 
                    653:            InterpretLocatorW(RootWindow, &w, newbutton.location);
                    654:            if (w == 0) w = RootWindow;
                    655:            QueryWindow(w, &winfo);
                    656:        }
                    657: 
                    658:        /* Now call the appropriate function */
                    659: 
                    660:        if (canDoToMenu[i] || w != menu) {
                    661:            (*menuOp[i])(which, newbutton.location, w, &winfo);
                    662:        }
                    663:        doingOp = FALSE;
                    664: 
                    665:        if (needsWindow[i]) XUngrabMouse();
                    666: }
                    667: 
                    668: /* Returns whether or not the button is bound to Select */
                    669: 
                    670: int NonSelect(button)
                    671:        BEvent *button;
                    672: {
                    673:        int which = button->detail & 0xff;      /* 0, 1, or 2 */
                    674:        int func = buttonFunc[which];
                    675: 
                    676:        return (func < 0 || menuOp[func] != Select);
                    677: }
                    678: 
                    679: DoButtonFunc(button, w)
                    680:        BEvent *button;
                    681:        Window w;
                    682: {
                    683:        int which = button->detail & 0xff;      /* 0, 1, or 2 */
                    684:        register int func = buttonFunc[which];
                    685:        WindowInfo winfo;
                    686: 
                    687:        if (func == unassigned_button) {
                    688:            Unassigned();
                    689:            return;
                    690:        }
                    691: 
                    692:        /* popup_button signifies the button to map the popup window */
                    693: 
                    694:        if (func == popup_button) {
                    695:            MapPopup(button->location);
                    696:            return;
                    697:        }
                    698: 
                    699:        if (w == 0) w = RootWindow;
                    700: 
                    701:        if (needsWindow[func]) {
                    702:            status = XGrabMouse(RootWindow, wmCursor,
                    703:                    ButtonPressed|ButtonReleased);
                    704:            if (status == 0) Error ("Couldn't grab mouse in DoButtonFunc");
                    705:            QueryWindow(w, &winfo);
                    706:        }
                    707: 
                    708:        InvertButton(func);
                    709:        (*menuOp[func])(which, button->location, w, &winfo);
                    710:        DisplayButton(func);
                    711: 
                    712:        if (needsWindow[func]) XUngrabMouse();
                    713: }
                    714: 
                    715: Unassigned()
                    716: {
                    717:        XFeep (3);
                    718: }
                    719: 
                    720: MapPopup(loc)
                    721:        Locator loc;
                    722: {
                    723:        int x, y;
                    724:        Window w;
                    725:        register int i;
                    726: 
                    727:        /* If there's not a saved popup image, create the buttons */
                    728: 
                    729:        if (!popupSaved) {      /* Create the items */
                    730:            XDestroySubwindows(menu);   /* Get rid of old items */
                    731:            x = y = -1;
                    732:            for (i = 0; i < itemcount; i++) {
                    733:                item[i] = XCreateWindow (menu, x, y, itemWidth, itemHeight, 1,
                    734:                        fgPixmap, bgPixmap);
                    735:                if (item[i] == NULL) Error ("Couldn't open item in MapPopup");
                    736:                y += itemHeight;
                    737:            }
                    738:            XMapSubwindows(menu);
                    739:        }
                    740: 
                    741:        InterpretLocatorXY(RootWindow, &x, &y, loc);
                    742: 
                    743:        x -= menuWidth >> 1;
                    744:        if (lastMenuOp == -1) y -= menuHeight >> 1;
                    745:        else y -= lastMenuOp * (itemHeight+1) + (itemHeight >> 1);
                    746: 
                    747:        if (x < 0) x = 0;
                    748:        else if (x + menuWidth > screen_width) {
                    749:            x = screen_width - menuWidth;
                    750:        }
                    751: 
                    752:        if (y < 0) y = 0;
                    753:        else if (y + menuHeight > screen_height) {
                    754:            y = screen_height - menuHeight;
                    755:        }
                    756: 
                    757:        if (freeze) {
                    758:            savex = x;
                    759:            savey = y;
                    760:            XGrabServer();
                    761:            saveScreen = XPixmapSave(RootWindow, x, y, menuWidth, menuHeight);
                    762:            if (saveScreen == 0) Error("Couldn't save screen in MapPopup");
                    763:        }
                    764: 
                    765:        XMoveWindow(menu, x, y);
                    766:        XMapWindow(menu);
                    767: 
                    768:        if (popupSaved) {
                    769:            XPixmapPut(menu, 0, 0, 0, 0, menuWidth-2, menuHeight-2,
                    770:                    menuImage, GXcopy, AllPlanes);
                    771:        } else {
                    772:            for (i = 0; i < itemcount; i++) DisplayButton(i);;
                    773:            menuImage = XPixmapSave(menu, 0, 0, menuWidth-2, menuHeight-2);
                    774:            if (menuImage == 0) Error("Couldn't save menu in MapPopup");
                    775:        }
                    776:        QueryMouse(RootWindow, &x, &y, &w);
                    777:        if (w != menu) UnmapPopup();
                    778: }
                    779: 
                    780: UnmapPopup()
                    781: {
                    782:        register int x, y, i;
                    783: 
                    784:        if (freeze && saveScreen != 0) {
                    785:            XUnmapTransparent(menu);
                    786:            XPixmapPut(RootWindow, 0, 0, savex, savey, menuWidth, menuHeight,
                    787:                    saveScreen, GXcopy, AllPlanes);
                    788:            XFreePixmap(saveScreen);
                    789:            XUngrabServer();
                    790:            saveScreen = 0;
                    791:        } else XUnmapWindow(menu);
                    792: 
                    793:        /* Now set things up so we don't have to map everything next time */
                    794: 
                    795:        if (!popupSaved) {
                    796:            if (menuImage != 0) {
                    797:                XDestroySubwindows(menu);       /* Get rid of old items */
                    798:                x = y = 0;
                    799:                for (i = 0; i < itemcount; i++) {
                    800:                    item[i] = XCreateTransparency(menu, x, y,
                    801:                            itemWidth, itemHeight);
                    802:                    if (item[i] == NULL) {
                    803:                        Error("Couldn't open item in UnmapPopup");
                    804:                    }
                    805:                    y += itemHeight;
                    806:                }
                    807:                XMapSubwindows(menu);
                    808:                popupSaved = TRUE;
                    809:            }
                    810:        }
                    811: }
                    812: 
                    813: /* Undo the popup menu caching.  We can't just test popupSaved, since
                    814:    it gets set in UnmapPopup and we might be called in between */
                    815: 
                    816: UnsavePopup()
                    817: {
                    818:        if (menuImage != 0) {
                    819:            XFreePixmap(menuImage);
                    820:            menuImage = 0;
                    821:        }
                    822: 
                    823:        if (popupSaved) popupSaved = FALSE;
                    824: }
                    825: 
                    826: InvertButton(i)
                    827:        int i;
                    828: {
                    829:        if (item[i] == 0) return;
                    830: 
                    831:        XPixFill(item[i], -1, -1, 200, 200, 0, (Bitmap) 0,
                    832:                GXinvert, 1);
                    833: }
                    834: 
                    835: DisplayButton(i)
                    836:        int i;
                    837: {
                    838:        register int j;
                    839: 
                    840:        if (item[i] == 0) return;
                    841: 
                    842:        XPixSet(item[i], -1, -1, 200, 200, bgColor);
                    843:        XText(item[i], 3, 3, label[i], strlen(label[i]), menufont,
                    844:                fgColor, bgColor);
                    845:        for (j = 0; j < 3; j++) {
                    846:            if (buttonFunc[j] == i) {
                    847:                XPixmapPut (item[buttonFunc[j]], 0, 0,
                    848:                        itemWidth - button_width - 3, 4,
                    849:                        button_width, button_height, buttonPixmap[j],
                    850:                        buttonGXfunc, AllPlanes);
                    851:            }
                    852:        }
                    853: }
                    854: 
                    855: IconifyOrDeIconify(which, loc, w, winfo)
                    856:        int which;
                    857:        Locator loc;
                    858:        Window w;
                    859:        WindowInfo *winfo;
                    860: {
                    861:        if (w == RootWindow) return;
                    862: 
                    863:        /* If we're trying to iconify an icon deiconify instead */
                    864: 
                    865:        if (winfo->type == IsIcon) Deiconify(which, loc, w, winfo);
                    866:        else Iconify(which, loc, w, winfo);
                    867: }
                    868: 
                    869: /* ARGSUSED */
                    870: 
                    871: Assign(which, loc, w, winfo)
                    872:        int which;
                    873:        Locator loc;
                    874:        Window w;
                    875:        WindowInfo *winfo;
                    876: {
                    877:        register int i;
                    878:        int choice, cleared = FALSE;
                    879:        BEvent newbutton;
                    880:        Window neww;
                    881: 
                    882:        /* First make sure the new click was in the menu; if not
                    883:           clear that button */
                    884: 
                    885:        if (w != menu) return;
                    886: 
                    887:        /* Now get rid of the old function assigned this button. But, don't
                    888:           deassign the popup window button! */
                    889: 
                    890:        choice = buttonFunc[which];
                    891:        if (choice == popup_button) return;
                    892: 
                    893:        if (popup) UnsavePopup();       /* The saved popup menu is invalid */
                    894: 
                    895:        if (choice >= 0) {
                    896:            XClear(item[choice]);
                    897:            buttonFunc[which] = unassigned_button;
                    898:            DisplayButton(choice);
                    899:            cleared = TRUE;
                    900:        }
                    901: 
                    902:        /* Now find out which subwindow we were in */
                    903: 
                    904:        InterpretLocatorW(menu, &w, loc);
                    905:        for (i = 0; item[i] != NULL && item[i] != w; i++) {}
                    906: 
                    907:        /* Can't assign Assign */
                    908: 
                    909:        if (menuOp[i] == NULL || menuOp[i] == Assign) {
                    910:            if (cleared) XUngrabButton(mask | Button(which));
                    911:            return;
                    912:        }
                    913: 
                    914:        /* Now wait for the release; if it doesn't occur abort */
                    915: 
                    916:        GetButton(&newbutton);
                    917:        if (!MatchUp(newbutton, which)) {
                    918:            if (cleared) XUngrabButton(mask | Button(which));
                    919:            return;
                    920:        }
                    921: 
                    922:        InterpretLocatorW(menu, &neww, loc);
                    923: 
                    924:        if (neww != w) {
                    925:            if (cleared) XUngrabButton(mask | Button(which));
                    926:            return;
                    927:        }
                    928: 
                    929:        /* Now assign that function to the button */
                    930: 
                    931:        buttonFunc[which] = i;
                    932: 
                    933:        XPixmapPut(item[i], 0, 0,
                    934:                itemWidth - button_width - 3, 4,
                    935:                button_width, button_height, buttonPixmap[which],
                    936:                buttonGXfunc, AllPlanes);
                    937: 
                    938:        if (!cleared) {                 /* New assignment */
                    939:                status = XGrabButton(RootWindow, wmCursor,
                    940:                        mask | Button(which),
                    941:                        ButtonPressed|ButtonReleased);
                    942:                if (status == 0) Error ("Couldn't grab button in Assign");
                    943:        }
                    944: }
                    945: 
                    946: /* Returns whether or not this is a real event */
                    947: 
                    948: int GetEvent(event)
                    949:        XEvent *event;
                    950: {
                    951:        XButtonEvent *be = (XButtonEvent *) event;
                    952:        XLeaveWindowEvent *lwe = (XLeaveWindowEvent *) event;
                    953:        XExposeEvent *ee = (XExposeEvent *) event;
                    954:        XUnmapEvent *ue = (XUnmapEvent *) event;
                    955:        XFocusChangeEvent *fce = (XFocusChangeEvent *) event;
                    956:        WindowInfo winfo;
                    957:        char *iconName;
                    958: 
                    959:        XNextEvent(event);
                    960: 
                    961:        /* If it's in the base window, no trouble */
                    962: 
                    963:        if (event->window == RootWindow) {
                    964:            if (event->type == FocusChange) {
                    965:                if (fce->detail == EnterWindow && fce->subwindow == 0) {
                    966:                    FocusOn(RootWindow);
                    967:                    FrameFocus();
                    968:                }
                    969:                return FALSE;
                    970: 
                    971:            } else if (event->type == UnmapWindow) {
                    972:                FrameFocus();   /* The background has changed */
                    973:                return FALSE;
                    974:            }
                    975: 
                    976:            be->detail &= 0xff; /* mask out state of shift keys */
                    977:            return TRUE;
                    978:        }
                    979: 
                    980:        /* Is it the menu window? */
                    981: 
                    982:        if (event->window == menu) {
                    983:            if (event->type == ExposeWindow) {
                    984:                if (ee->subwindow != 0) RefreshMenu(ee->subwindow);
                    985:                return FALSE;
                    986:            }
                    987:            if (event->type == LeaveWindow) {
                    988:                if (lwe->subwindow == 0 && !doingOp) UnmapPopup();
                    989:                return FALSE;
                    990:            }
                    991:        }
                    992: 
                    993:        /* Let's see if it's in an icon */
                    994: 
                    995:        QueryWindow(event->window, &winfo);
                    996: 
                    997:        if (winfo.type != IsIcon) return FALSE; /* Nope -- nothing */
                    998: 
                    999:        if (event->type == UnmapWindow) return FALSE;
                   1000: 
                   1001:        status = XFetchName(winfo.assoc_wind, &iconName);
                   1002:        if (status == 0) Error ("Couldn't fetch name in GetButton");
                   1003: 
                   1004:        if (event->type == ExposeWindow) {      /* Just refresh the icon */
                   1005:            XClear(ee->window);
                   1006:            if (iconName != NULL && iconName[0] != '\0') {
                   1007:                XText(ee->window, 4, 4, iconName, strlen(iconName), iconfont,
                   1008:                        fgColor, bgColor);
                   1009:            }
                   1010:        } else EditIconName((XKeyPressedEvent *)be, iconName);
                   1011:        if (iconName) free(iconName);
                   1012:        return FALSE;
                   1013: }
                   1014: 
                   1015: GetButton(event)
                   1016:        BEvent *event;
                   1017: {
                   1018:        while (!GetEvent(event)) ;
                   1019: }
                   1020: 
                   1021: RefreshMenu(w)
                   1022:        Window w;
                   1023: {
                   1024:        register int i;
                   1025:        
                   1026:        for (i = 0; i < itemcount && item[i] != w; i++) {}
                   1027:        if (i >= itemcount) return;
                   1028:        DisplayButton(i);
                   1029: }
                   1030: 
                   1031: Error(string)
                   1032:        char *string;
                   1033: {
                   1034:        fprintf(stderr, "\nxmwm: %s", string);
                   1035:        fprintf(stderr, "\n\n");
                   1036: 
                   1037:        if (errno != 0) {
                   1038:                perror("xwm");
                   1039:                fprintf(stderr, "\n");
                   1040:        }
                   1041: 
                   1042:        exit(1);
                   1043: }
                   1044: 
                   1045: Flush()
                   1046: {
                   1047:        XFlush();
                   1048: }
                   1049: 
                   1050: Sync()
                   1051: {
                   1052:        XSync(FALSE);
                   1053: }

unix.superglobalmegacorp.com

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