Annotation of researchv9/X11/src/X.V11R1/demos/wm/test.c, revision 1.1.1.1

1.1       root        1: /* 
                      2:  * $Locker:  $ 
                      3:  */ 
                      4: static char     *rcsid = "$Header: test.c,v 1.2 87/06/17 16:08:52 swick Locked ";
                      5: #include <stdio.h>
                      6: #include <X11/Xlib.h>
                      7: #include <X11/Xutil.h>
                      8: #include <X11/Xatom.h>
                      9: #include <X11/X10.h>
                     10: #include "test.h"
                     11: #include "externs.h"
                     12: #include "dblArrow.h"
                     13: #include "growBox.h"
                     14: #include "cross.h"
                     15: 
                     16: XAssocTable *frameInfo;
                     17: XFontStruct *font;
                     18: Display *dpy;
                     19: int ErrorFunc();
                     20: 
                     21: extern char *malloc();
                     22: 
                     23: void MoveOutline();
                     24: 
                     25: RootInfoRec *
                     26: findRootInfo(win)
                     27:     Window win;
                     28: {
                     29:     int        i;
                     30: 
                     31:     for (i = 0; i < ScreenCount(dpy); i++) {
                     32:        if (RootInfo[i].root == win)
                     33:            return (&(RootInfo[i]));
                     34:     }
                     35:     return (NULL);
                     36: }
                     37: 
                     38: #ifdef debug
                     39: static char *eventtype[] = {
                     40:        "zero",
                     41:        "one",
                     42:        "KeyPress",
                     43:        "KeyRelease",
                     44:        "ButtonPress",
                     45:        "ButtonRelease",
                     46:        "MotionNotify",
                     47:        "EnterNotify",
                     48:        "LeaveNotify",
                     49:        "FocusIn",
                     50:        "FocusOut",
                     51:        "KeymapNotify",
                     52:        "Expose",
                     53:        "GraphicsExpose",
                     54:        "NoExpose",
                     55:        "VisibilityNotify",
                     56:        "CreateNotify",
                     57:        "DestroyNotify",
                     58:        "UnmapNotify",
                     59:        "MapNotify",
                     60:        "MapRequest",
                     61:        "ReparentNotify",
                     62:        "ConfigureNotify",
                     63:        "ConfigureRequest",
                     64:        "GravityNotify",
                     65:        "ResizeRequest",
                     66:        "CirculateNotify",
                     67:        "CirculateRequest",
                     68:        "PropertyNotify",
                     69:        "SelectionClear",
                     70:        "SelectionRequest",
                     71:        "SelectionNotify",
                     72:        "ColormapNotify",
                     73:        "ClientMessage",
                     74:        "MappingNotify",
                     75: };
                     76: #endif debug
                     77: 
                     78: main(argc, argv) int argc; char *argv[];
                     79: {
                     80:     Window      parent;
                     81:     Window     *children;
                     82:     int         nchildren;
                     83:     int         i;
                     84:     Window      dragWindow = None;
                     85:     Window      resizeWindow = None;
                     86:     Window      iconifyWindow = None;
                     87:     int         dragx, dragy;
                     88:     int         iconPressx, iconPressy;
                     89:     int         dragHeight, dragWidth;
                     90:     int         origx, origy, origWidth, origHeight;
                     91:     int         clampTop, clampBottom, clampLeft, clampRight;
                     92:     int         buttonsPressed = 0;
                     93:     int         buttonsDown[128]; /* XXX */
                     94:     int         hdrWidth;
                     95: 
                     96:     XSetWindowAttributes attributes;
                     97:     XGCValues   gcv;
                     98: 
                     99:     for (i = 0; i < 128; i++) buttonsDown[i] = 0; /* XXX */
                    100:     StartConnectionToServer(argc, argv);
                    101:     XSetErrorHandler(ErrorHandler);
                    102: #ifdef debug
                    103:     XSynchronize(dpy, 1);
                    104: #endif
                    105:     frameInfo = XCreateAssocTable(ASSOCTABLESZ);
                    106:     if (!frameInfo) {
                    107:        Error(1, "XCreateAssocTable failed\n");
                    108:     }
                    109: 
                    110:     font = XLoadQueryFont(dpy, "fixed");
                    111:     if (!font)
                    112:        Error(1, "XFont failed\n");
                    113: #ifdef debug
                    114:     printf("descent=%d, ascent=%d, width=%d\n",
                    115:           font->max_bounds.descent, font->max_bounds.ascent,
                    116:           font->max_bounds.width);
                    117: #endif
                    118: 
                    119:     RootInfo = (RootInfoRec *) malloc(ScreenCount(dpy) * sizeof(RootInfoRec));
                    120:     for (i = 0; i < ScreenCount(dpy); i++) {
                    121:        RootInfo[i].root = RootWindow(dpy, i);
                    122:        RootInfo[i].doubleArrow = MakePixmap(RootInfo[i].root,
                    123:                                             dblArrow_bits,
                    124:                                             dblArrow_width,
                    125:                                             dblArrow_height);
                    126:        RootInfo[i].growBox = MakePixmap(RootInfo[i].root,
                    127:                                         growBox_bits,
                    128:                                         growBox_width,
                    129:                                         growBox_height);
                    130:        RootInfo[i].cross = MakePixmap(RootInfo[i].root,
                    131:                                       cross_bits,
                    132:                                       cross_width,
                    133:                                       cross_height);
                    134:        gcv.font = font->fid;
                    135:        gcv.foreground = WhitePixel(dpy, i);
                    136:        gcv.background = BlackPixel(dpy, i);
                    137:        RootInfo[i].headerGC = XCreateGC(dpy, RootInfo[i].root,
                    138:                                         GCForeground | GCBackground | GCFont, &gcv);
                    139:        gcv.function = GXinvert;
                    140:        gcv.subwindow_mode = IncludeInferiors;
                    141:        RootInfo[i].xorGC = XCreateGC(dpy, RootInfo[i].root,
                    142:                                      GCFunction | GCSubwindowMode, &gcv);
                    143:        {
                    144:            Window      retroot;
                    145:            int         bw, depth;
                    146:            XGetGeometry(dpy, (Drawable) RootInfo[i].root, &retroot,
                    147:                         &RootInfo[i].rootx, &RootInfo[i].rooty,
                    148:            &RootInfo[i].rootwidth, &RootInfo[i].rootheight, &bw, &depth);
                    149:        }
                    150:        /*
                    151:         * select Substructure Redirect on the root to have MapRequest
                    152:         * events generated instead of windows getting mapped 
                    153:         */
                    154:        errorStatus = False;
                    155:        attributes.event_mask = (SubstructureRedirectMask|
                    156:                        ButtonPressMask|ButtonReleaseMask|FocusChangeMask);
                    157:        XChangeWindowAttributes(dpy, RootInfo[i].root, CWEventMask, &attributes);
                    158:        /* XSelectInput(dpy, root, SubstructureRedirectMask); */
                    159:        XSync(dpy, False);
                    160:        if (errorStatus == True) {
                    161:            fprintf(stderr, "Are you running another window manager?\n");
                    162:            exit(1);
                    163:        }
                    164:        if (XQueryTree(dpy, RootInfo[i].root, &RootInfo[i].root, &parent,
                    165:                       &children, &nchildren)) {
                    166:            int         i;
                    167: 
                    168:            for (i = 0; i < nchildren; i++) {
                    169:                if (MappedNotOverride(children[i]))
                    170:                    AddGizmos(children[i]);
                    171:            }
                    172:            if (children)
                    173:                free((char *)children);
                    174:        }
                    175:        XFlush(dpy);
                    176:     }
                    177:     XSetErrorHandler(ErrorFunc);
                    178:     while (1) {
                    179:        XEvent      ev;
                    180:        XNextEvent(dpy, &ev);
                    181: #ifdef debug
                    182:        printf("event %s ", eventtype[ev.type]);
                    183: #endif
                    184:        switch (ev.type) {
                    185:        case MapRequest:{
                    186:                Window      w;
                    187:                GenericAssoc *ga;
                    188:                w = ev.xmaprequest.window;
                    189:                ga = (GenericAssoc *) XLookUpAssoc(dpy, frameInfo, (XID) w);
                    190:                if (ga) {
                    191:                    XMapWindow(dpy, ga->frame);
                    192:                }
                    193:                else {
                    194:                    AddGizmos(w);
                    195: #ifdef debug
                    196:                    printf("delivered to %s of frame %d\n",
                    197:                           WindowType(w), Frame(w));
                    198: #endif
                    199:                }
                    200:                break;
                    201:            }
                    202:        case UnmapNotify:{
                    203:                GenericAssoc *ga;
                    204:                Window      w;
                    205:                w = ev.xunmap.window;
                    206: #ifdef debug
                    207:                printf("delivered to %s of frame %d\n",
                    208:                       WindowType(w), Frame(w));
                    209: #endif
                    210:                ga = (GenericAssoc *) XLookUpAssoc(dpy, frameInfo, (XID) w);
                    211:                if (ga && (ga->client == w))
                    212:                    XUnmapWindow(dpy, ga->frame);
                    213:                break;
                    214:            }
                    215:        case DestroyNotify:{
                    216:                GenericAssoc *ga;
                    217:                Window      w;
                    218:                w = ev.xdestroywindow.window;
                    219: #ifdef debug
                    220:                printf("delivered to %s of frame %d\n",
                    221:                       WindowType(w), Frame(w));
                    222: #endif
                    223:                ga = (GenericAssoc *) XLookUpAssoc(dpy, frameInfo, (XID) w);
                    224:                if (ga && (ga->client == w))
                    225:                    RemoveGizmos(ga);
                    226:                break;
                    227:            }
                    228:        case PropertyNotify:{
                    229:                GenericAssoc *ga;
                    230:                Window      w;
                    231:                Window      root;
                    232:                int         x, y, wd, ht, bw, d;
                    233: 
                    234:                w = ev.xproperty.window;
                    235:                XGetGeometry(dpy, (Drawable) w, &root, &x, &y, &wd, &ht, &bw, &d);
                    236:                ga = (GenericAssoc *) XLookUpAssoc(dpy, frameInfo, (XID) w);
                    237:                if (!ga || w != ga->client)
                    238:                    break;
                    239:                switch (ev.xproperty.atom) {
                    240:                case XA_WM_NAME:
                    241:                    ProcessNewName(root, ga);
                    242:                    break;
                    243:                case XA_WM_ICON_NAME:
                    244:                    ProcessNewIconName(root, ga);
                    245:                    break;
                    246:                default:
                    247:                    break;
                    248:                }
                    249:                break;
                    250:            }
                    251:        case ButtonPress:{
                    252:                GenericAssoc *ga;
                    253:                Window      w;
                    254:                w = ev.xbutton.window;
                    255: #ifdef debug
                    256:                printf("delivered to %s of frame %d\n",
                    257:                       WindowType(w), Frame(w));
                    258: #endif
                    259:                if (buttonsDown[ev.xbutton.button])
                    260:                   break;
                    261:                buttonsDown[ev.xbutton.button] = 1;
                    262:                if (buttonsPressed++) {
                    263:                    iconifyWindow = None;
                    264:                    dragWindow = None;
                    265:                    resizeWindow = None;
                    266:                    MoveOutline(ev.xbutton.root,
                    267:                                ev.xbutton.x_root - dragx - BORDERWIDTH,
                    268:                                ev.xbutton.y_root - dragy - BORDERWIDTH,
                    269:                                0, 0);
                    270:                    XUngrabServer(dpy);
                    271:                    break;
                    272:                }
                    273:                ga = (GenericAssoc *) XLookUpAssoc(dpy, frameInfo, (XID) w);
                    274:                if (ga && (ga->rbox == w) && resizeWindow == None) {
                    275:                    Window      junkRoot;
                    276:                    int         junkbw, junkDepth;
                    277:                    resizeWindow = ga->frame;
                    278:                    XGrabServer(dpy);
                    279:                    XGetGeometry(dpy, (Drawable) resizeWindow, &junkRoot,
                    280:                        &dragx, &dragy, &dragWidth, &dragHeight, &junkbw,
                    281:                                 &junkDepth);
                    282:                    dragx += BW;
                    283:                    dragy += BW;
                    284:                    origx = dragx;
                    285:                    origy = dragy;
                    286:                    origWidth = dragWidth;
                    287:                    origHeight = dragHeight;
                    288:                    clampTop = clampBottom = clampLeft = clampRight = 0;
                    289:                }
                    290:                else if (ga && (ga->iconWindow == w)) {
                    291:                    iconifyWindow = w;
                    292:                    if (ev.xbutton.state & ShiftMask) {
                    293:                        Window      junkRoot;
                    294:                        int         junkX, junkY, junkbw, junkDepth;
                    295:                        dragWindow = w;
                    296:                        dragx = ev.xbutton.x;
                    297:                        dragy = ev.xbutton.y;
                    298:                        XGrabServer(dpy);
                    299:                        XGetGeometry(dpy, (Drawable) dragWindow,
                    300:                                     &junkRoot, &junkX,
                    301:                                &junkY, &dragWidth, &dragHeight, &junkbw,
                    302:                                     &junkDepth);
                    303: #ifdef debug
                    304:                        printf("From: x=%d, y=%d, w=%d, h=%d\n",
                    305:                               junkX, junkY, dragWidth, dragHeight);
                    306: #endif
                    307:                        MoveOutline(ev.xbutton.root,
                    308:                                 ev.xbutton.x_root - dragx - BORDERWIDTH,
                    309:                                 ev.xbutton.y_root - dragy - BORDERWIDTH,
                    310:                                    dragWidth + 2 * BORDERWIDTH,
                    311:                                    dragHeight + 2 * BORDERWIDTH);
                    312:                    }
                    313:                }
                    314:                else if (ga && (ga->upbox == w)) {
                    315:                    XWindowChanges wc;
                    316:                    wc.stack_mode = Opposite;
                    317:                    XConfigureWindow(dpy, ga->frame, CWStackMode, &wc);
                    318:                }
                    319:                else if (ga && (ga->iconify == w) && (iconifyWindow == None)) {
                    320:                    Window      junkRoot;
                    321:                    int         junkX, junkY, junkbw, junkDepth;
                    322:                    iconifyWindow = w;
                    323:                    iconPressx = ev.xbutton.x_root;
                    324:                    iconPressy = ev.xbutton.y_root;
                    325:                    dragx = 0;
                    326:                    dragy = 0;
                    327:                    dragWindow = ga->iconWindow;
                    328:                    XGrabServer(dpy);
                    329:                    XGetGeometry(dpy, (Drawable) dragWindow,
                    330:                                 &junkRoot, &junkX,
                    331:                                 &junkY, &dragWidth, &dragHeight, &junkbw,
                    332:                                 &junkDepth);
                    333: #ifdef debug
                    334:                    printf("From: x=%d, y=%d, w=%d, h=%d\n",
                    335:                           junkX, junkY, dragWidth, dragHeight);
                    336: #endif
                    337:                    MoveOutline(ev.xbutton.root,
                    338:                                ev.xbutton.x_root - dragx - BORDERWIDTH,
                    339:                                ev.xbutton.y_root - dragy - BORDERWIDTH,
                    340:                                dragWidth + 2 * BORDERWIDTH,
                    341:                                dragHeight + 2 * BORDERWIDTH);
                    342:                }
                    343:                else if (ga && (ga->header == w) && dragWindow == None) {
                    344:                    Window      junkRoot;
                    345:                    int         junkX, junkY, junkbw, junkDepth;
                    346:                    dragWindow = ga->frame;
                    347:                    dragx = ev.xbutton.x + UPBOXWIDTH + ICONIFYWIDTH + BORDERWIDTH;
                    348:                    dragy = ev.xbutton.y;
                    349:                    hdrWidth = ga->headerWidth;
                    350:                    XGrabServer(dpy);
                    351:                    XGetGeometry(dpy, (Drawable) dragWindow, &junkRoot, &junkX,
                    352:                                 &junkY, &dragWidth, &dragHeight, &junkbw,
                    353:                                 &junkDepth);
                    354: #ifdef debug
                    355:                    printf("From: x=%d, y=%d, w=%d, h=%d\n",
                    356:                           junkX, junkY, dragWidth, dragHeight);
                    357: #endif
                    358:                    MoveOutline(ev.xbutton.root,
                    359:                                ev.xbutton.x_root - dragx - BORDERWIDTH,
                    360:                                ev.xbutton.y_root - dragy - BORDERWIDTH,
                    361:                                dragWidth + 2 * BORDERWIDTH,
                    362:                                dragHeight + 2 * BORDERWIDTH);
                    363:                }
                    364:                else {
                    365:                    int newx, newy;
                    366:                    Window newRoot;
                    367:                    RootInfoRec *ro = findRootInfo(ev.xbutton.root);
                    368:                    RootInfoRec *rn = ro;
                    369: 
                    370:                    if (++rn >= (RootInfo + ScreenCount(dpy)))
                    371:                        rn = RootInfo;
                    372: #ifdef debug
                    373:                    printf("Roots 0x%x: old 0x%x, new 0x%x\n", ev.xbutton.root, ro, rn);
                    374: #endif
                    375:                    if (rn != ro) {
                    376: #ifdef debug
                    377:                        printf("Warp from %d to %d new root is 0x%x\n",
                    378:                               (ro - RootInfo), (rn - RootInfo), rn->root);
                    379: #endif
                    380:                        newx = (((ev.xbutton.x_root - ro->rootx)*100/(ro->rootwidth))
                    381:                            *(rn->rootwidth))/100 + rn->rootx;
                    382:                        newy = (((ev.xbutton.y_root - ro->rooty)*100/(ro->rootheight))
                    383:                            *(rn->rootheight))/100 + rn->rooty;
                    384:                        XWarpPointer(dpy, None, rn->root, 0, 0, 0, 0, newx, newy);
                    385:                    }
                    386:                }
                    387:                break;
                    388:            }
                    389:        case MotionNotify:{
                    390:                Window      junkRoot, junkChild;
                    391:                int         junkx, junky, junkrx, junkry;
                    392:                unsigned int junkMask;
                    393:                Window      root;
                    394: #ifdef debug
                    395:                printf("\n");
                    396: #endif
                    397:                if (QLength(dpy)) {
                    398:                    XEvent      rete;
                    399:                    XPeekEvent(dpy, &rete);
                    400:                    if (rete.type == MotionNotify &&
                    401:                        rete.xmotion.window == ev.xmotion.window) {
                    402:                        break;
                    403:                    }
                    404:                }
                    405:                root = ev.xmotion.root;
                    406:                if (dragWindow != None) {
                    407:                    int         x, y;
                    408:                    x = ev.xmotion.x_root - dragx;
                    409:                    y = ev.xmotion.y_root - dragy;
                    410:                    if (iconifyWindow != None)
                    411:                        MakeReachable(root, &x, &y, dragWidth,
                    412:                                      dragHeight);
                    413:                    else {
                    414:                        x += UPBOXWIDTH + ICONIFYWIDTH + BW;
                    415:                        MakeReachable(root, &x, &y, hdrWidth,
                    416:                                      TITLEHEIGHT);
                    417:                        x -= UPBOXWIDTH + ICONIFYWIDTH + BW;
                    418:                    }
                    419:                    MoveOutline(root,
                    420:                                x - BORDERWIDTH, y - BORDERWIDTH,
                    421:                                dragWidth + 2 * BORDERWIDTH,
                    422:                                dragHeight + 2 * BORDERWIDTH);
                    423:                    XQueryPointer(dpy, root, &junkRoot, &junkChild,
                    424:                                  &junkrx, &junkry,
                    425:                                  &junkx, &junky, &junkMask);
                    426:                }
                    427:                else if (resizeWindow != None) {
                    428:                    int         action = 0;
                    429:                    if (clampTop) {
                    430:                        int         delta = ev.xmotion.y_root - dragy;
                    431:                        if (dragHeight - delta < MINHEIGHT) {
                    432:                            delta = dragHeight - MINHEIGHT;
                    433:                            clampTop = 0;
                    434:                        }
                    435:                        dragy += delta;
                    436:                        dragHeight -= delta;
                    437:                        action = 1;
                    438:                    }
                    439:                    else if (ev.xmotion.y_root <= dragy ||
                    440:                             ev.xmotion.y_root == findRootInfo(root)->rooty) {
                    441:                        dragy = ev.xmotion.y_root;
                    442:                        dragHeight = origy + origHeight -
                    443:                            ev.xmotion.y_root;
                    444:                        clampBottom = 0;
                    445:                        clampTop = 1;
                    446:                        action = 1;
                    447:                    }
                    448:                    if (clampLeft) {
                    449:                        int         delta = ev.xmotion.x_root - dragx;
                    450:                        if (dragWidth - delta < MINWIDTH) {
                    451:                            delta = dragWidth - MINWIDTH;
                    452:                            clampLeft = 0;
                    453:                        }
                    454:                        dragx += delta;
                    455:                        dragWidth -= delta;
                    456:                        action = 1;
                    457:                    }
                    458:                    else if (ev.xmotion.x_root <= dragx ||
                    459:                             ev.xmotion.x_root == findRootInfo(root)->rootx) {
                    460:                        dragx = ev.xmotion.x_root;
                    461:                        dragWidth = origx + origWidth -
                    462:                            ev.xmotion.x_root;
                    463:                        clampRight = 0;
                    464:                        clampLeft = 1;
                    465:                        action = 1;
                    466:                    }
                    467:                    if (clampBottom) {
                    468:                        int         delta = ev.xmotion.y_root - dragy - dragHeight;
                    469:                        if (dragHeight + delta < MINHEIGHT) {
                    470:                            delta = MINHEIGHT - dragHeight;
                    471:                            clampBottom = 0;
                    472:                        }
                    473:                        dragHeight += delta;
                    474:                        action = 1;
                    475:                    }
                    476:                    else if (ev.xmotion.y_root >= dragy + dragHeight - 1 ||
                    477:                           ev.xmotion.y_root == findRootInfo(root)->rooty
                    478:                           + findRootInfo(root)->rootheight - 1) {
                    479:                        dragy = origy;
                    480:                        dragHeight = 1 + ev.xmotion.y_root - dragy;
                    481:                        clampTop = 0;
                    482:                        clampBottom = 1;
                    483:                        action = 1;
                    484:                    }
                    485:                    if (clampRight) {
                    486:                        int         delta = ev.xmotion.x_root - dragx - dragWidth;
                    487:                        if (dragWidth + delta < MINWIDTH) {
                    488:                            delta = MINWIDTH - dragWidth;
                    489:                            clampRight = 0;
                    490:                        }
                    491:                        dragWidth += delta;
                    492:                        action = 1;
                    493:                    }
                    494:                    else if (ev.xmotion.x_root >= dragx + dragWidth - 1 ||
                    495:                             ev.xmotion.x_root == findRootInfo(root)->rootx +
                    496:                             findRootInfo(root)->rootwidth - 1) {
                    497:                        dragx = origx;
                    498:                        dragWidth = 1 + ev.xmotion.x_root - origx;
                    499:                        clampLeft = 0;
                    500:                        clampRight = 1;
                    501:                        action = 1;
                    502:                    }
                    503:                    if (action) {
                    504:                        MoveOutline(root,
                    505:                                    dragx - BORDERWIDTH,
                    506:                                    dragy - BORDERWIDTH,
                    507:                                    dragWidth + 2 * BORDERWIDTH,
                    508:                                    dragHeight + 2 * BORDERWIDTH);
                    509:                        XQueryPointer(dpy, root, &junkRoot, &junkChild,
                    510:                                      &junkrx, &junkry,
                    511:                                      &junkx, &junky, &junkMask);
                    512:                    }
                    513:                }
                    514:                break;
                    515:            }
                    516:        case ButtonRelease:{
                    517:                Window      w;
                    518:                GenericAssoc *ga;
                    519:                if (!buttonsDown[ev.xbutton.button])
                    520:                   break;
                    521:                buttonsDown[ev.xbutton.button] = 0;
                    522:                buttonsPressed--;
                    523:                w = ev.xbutton.window;
                    524:                ga = (GenericAssoc *) XLookUpAssoc(dpy, frameInfo,
                    525:                                                   (XID) w);
                    526: 
                    527:                if (ga && (ga->header == w)
                    528:                    && (ga->frame == dragWindow)) {
                    529:                    XWindowChanges wc;
                    530:                    wc.x = ev.xbutton.x_root - dragx;
                    531:                    wc.y = ev.xbutton.y_root - dragy;
                    532:                    wc.x += UPBOXWIDTH + ICONIFYWIDTH + BW;
                    533:                    MakeReachable(ev.xbutton.root, &wc.x, &wc.y, ga->headerWidth,
                    534:                                  TITLEHEIGHT);
                    535:                    wc.x -= UPBOXWIDTH + ICONIFYWIDTH + 2 * BW;
                    536:                    /*
                    537:                     * the extra BW is because XReconfigureWindow includes
                    538:                     * the border width in x and y, but not in width and
                    539:                     * height 
                    540:                     */
                    541:                    wc.y -= BW;
                    542: #ifdef debug
                    543:                    printf("delivered to %s of frame %d\n",
                    544:                           WindowType(w), Frame(w));
                    545: #endif
                    546:                    MoveOutline(ev.xbutton.root, 0, 0, 0, 0);
                    547:                    XUngrabServer(dpy);
                    548: #ifdef debug
                    549:                    printf("To x=%d, y=%d\n",
                    550:                           ev.xbutton.x_root - dragx,
                    551:                           ev.xbutton.y_root - dragy);
                    552: #endif
                    553:                    XConfigureWindow(dpy, dragWindow,
                    554:                                       CWX | CWY, &wc);
                    555:                    dragWindow = None;
                    556:                }
                    557:                else if (ga && (ga->rbox == w)
                    558:                         && (ga->frame == resizeWindow)) {
                    559: #ifdef debug
                    560:                    printf("delivered to %s of frame %d\n",
                    561:                           WindowType(w), Frame(w));
                    562: #endif
                    563:                    MoveOutline(ev.xbutton.root, 0, 0, 0, 0);
                    564:                    XUngrabServer(dpy);
                    565:                    ReconfigureFrameAndClient(ev.xbutton.root, ga, dragx,
                    566:                        dragy + TITLEHEIGHT + BORDERWIDTH, dragWidth,
                    567:                                 dragHeight - TITLEHEIGHT - BORDERWIDTH);
                    568:                    resizeWindow = None;
                    569:                }
                    570:                else if (ga && (ga->iconify == w) && (iconifyWindow == w)) {
                    571:                    XWindowChanges wc;
                    572: #ifdef debug
                    573:                    printf("delivered to %s of frame %d\n",
                    574:                           WindowType(w), Frame(w));
                    575: #endif
                    576:                    if (ga->iconknown && iconPressx == ev.xbutton.x_root
                    577:                        && iconPressy == ev.xbutton.y_root) {
                    578:                        wc.x = ga->iconx;
                    579:                        wc.y = ga->icony;
                    580:                    }
                    581:                    else {
                    582:                        ga->iconknown = True;
                    583:                        wc.x = ga->iconx = ev.xbutton.x_root;
                    584:                        wc.y = ga->icony = ev.xbutton.y_root;
                    585:                    }
                    586:                    MakeReachable(ev.xbutton.root, &wc.x, &wc.y,
                    587:                                  dragWidth, dragHeight);
                    588:                    wc.x -= BW;
                    589:                    wc.y -= BW;
                    590:                    MoveOutline(ev.xbutton.root, 0, 0, 0, 0);
                    591:                    XUngrabServer(dpy);
                    592:                    dragWindow = None;
                    593:                    iconifyWindow = None;
                    594:                    XConfigureWindow(dpy, ga->iconWindow, CWX | CWY, &wc);
                    595:                    XUnmapWindow(dpy, ga->frame);
                    596:                    XMapWindow(dpy, ga->iconWindow);
                    597:                }
                    598:                else if (ga && (ga->iconWindow == w) && (iconifyWindow == w)) {
                    599:                    if (dragWindow == w) {
                    600:                        XWindowChanges wc;
                    601:                        wc.x = ev.xbutton.x_root - dragx;
                    602:                        wc.y = ev.xbutton.y_root - dragy;
                    603: #ifdef debug
                    604:                        printf("delivered to %s of frame %d\n",
                    605:                               WindowType(w), Frame(w));
                    606: #endif
                    607:                        MoveOutline(ev.xbutton.root, 0, 0, 0, 0);
                    608:                        XUngrabServer(dpy);
                    609:                        ga->iconx = wc.x;
                    610:                        ga->icony = wc.y;
                    611: #ifdef debug
                    612:                        printf("To x=%d, y=%d\n",
                    613:                               ev.xbutton.x_root - dragx,
                    614:                               ev.xbutton.y_root - dragy);
                    615: #endif
                    616:                        MakeReachable(ev.xbutton.root, &wc.x, &wc.y, dragWidth,
                    617:                                      dragHeight);
                    618:                        wc.x -= BW;
                    619:                        wc.y -= BW;
                    620:                        XConfigureWindow(
                    621:                                        dpy, dragWindow, CWX | CWY, &wc);
                    622:                        dragWindow = None;
                    623:                    }
                    624:                    else {
                    625:                        XUnmapWindow(dpy, ga->iconWindow);
                    626:                        XMapWindow(dpy, ga->frame);
                    627:                    }
                    628:                    iconifyWindow = None;
                    629:                }
                    630:                else {
                    631: #ifdef debug
                    632:                    printf("delivered to ???\n");
                    633: #endif
                    634:                }
                    635:                break;
                    636:            }
                    637:        case ConfigureRequest:{
                    638:                Window      w;
                    639:                GenericAssoc *ga;
                    640:                XWindowChanges wc;
                    641:                XConfigureRequestEvent evc;
                    642:                evc = ev.xconfigurerequest;
                    643:                w = evc.window;
                    644:                ga = (GenericAssoc *) XLookUpAssoc(dpy, frameInfo, (XID) w);
                    645:                if (!ga) {
                    646: #ifdef debug
                    647:                    printf("delivered to unknown client\n");
                    648: #endif
                    649:                    wc.x = evc.x;
                    650:                    wc.y = evc.y;
                    651:                    wc.width = evc.width;
                    652:                    wc.height = evc.height;
                    653:                    wc.border_width = evc.border_width;
                    654:                    wc.sibling = evc.above;
                    655:                    wc.stack_mode = Above;
                    656:                    XConfigureWindow(dpy, w, CWX | CWY | CWWidth |
                    657:                                       CWBorderWidth | CWSibling | CWStackMode,
                    658:                                       &wc);
                    659:                }
                    660:                else if (ga->client == w) {
                    661:                    int         x, y;
                    662:                    Window      root, jc;
                    663:                    int         ht, wd, bw, d, x1, y1;
                    664: #ifdef debug
                    665:                    printf("delivered to %s of frame %d\n",
                    666:                           WindowType(w), Frame(w));
                    667: #endif
                    668:                    XGetGeometry(dpy,
                    669:                                 (Drawable) w, &root, &x1, &y1, &wd, &ht, &bw, &d);
                    670:                    XTranslateCoordinates(dpy, w, root, 0, 0, &x, &y, &jc);
                    671:                    ReconfigureFrameAndClient
                    672:                        (root, ga, x, y, evc.width, evc.height);
                    673:                }
                    674:                else {
                    675: #ifdef debug
                    676:                    printf("delivered to %s of frame %d\n",
                    677:                           WindowType(w), Frame(w));
                    678: #endif
                    679:                }
                    680:                break;
                    681:            }
                    682:        case Expose:{
                    683:                Window      w = ev.xexpose.window;
                    684:                GenericAssoc *ga;
                    685:                Window      root;
                    686:                int         x, y, wd, ht, bw, d;
                    687: 
                    688: #ifdef debug
                    689:                printf("delivered to %s of frame %d\n",
                    690:                       WindowType(w), Frame(w));
                    691: #endif
                    692:                ga = (GenericAssoc *) XLookUpAssoc(dpy, frameInfo, (XID) w);
                    693:                XGetGeometry(dpy, (Drawable) w, &root, &x, &y, &wd, &ht, &bw, &d);
                    694:                if (ga && ga->header == w) {
                    695:                    int         x;
                    696:                    x = (ga->headerWidth -
                    697:                         XTextWidth(font, ga->name, ga->namelen)) / 2;
                    698:                    XDrawString(dpy, w, findRootInfo(root)->headerGC, x,
                    699:                          font->max_bounds.ascent + 5,
                    700:                          ga->name, ga->namelen);
                    701:                }
                    702:                else if (ga && ga->iconWindow == w) {
                    703:                    if (ga->iconnamelen == 0)
                    704:                        XDrawString(dpy, w, findRootInfo(root)->headerGC, 2,
                    705:                              font->max_bounds.ascent + 5,
                    706:                              ga->name, ga->namelen);
                    707:                    else
                    708:                        XDrawString(dpy, w, findRootInfo(root)->headerGC, 2,
                    709:                              font->max_bounds.ascent + 5,
                    710:                              ga->iconname, ga->iconnamelen);
                    711:                }               /* else if (ga && (ga->upbox == w)) {
                    712:                                 * XCopyArea(dpy, doubleArrow, w,
                    713:                                 * headerGC, 0, 0, UPBOXWIDTH,
                    714:                                 * TITLEHEIGHT, 0, 0); } else if (ga &&
                    715:                                 * (ga->rbox == w)) { XCopyArea(dpy,
                    716:                                 * growBox, w, headerGC, 0, 0, UPBOXWIDTH,
                    717:                                 * TITLEHEIGHT, 0, 0); } else if (ga &&
                    718:                                 * (ga->iconify == w)) { XCopyArea(dpy,
                    719:                                 * cross, w, headerGC, 0, 0, UPBOXWIDTH,
                    720:                                 * TITLEHEIGHT, 0, 0); } */
                    721:                break;
                    722:            }
                    723:        case FocusIn: break;    /* just ignore */
                    724:        case FocusOut: {
                    725:                if (ev.xfocus.detail == NotifyPointerRoot)
                    726:                    XSetInputFocus(dpy, PointerRoot, None, CurrentTime);
                    727:                break;
                    728:            }
                    729:        default:
                    730: #ifdef debug
                    731:            printf("\n");
                    732: #endif
                    733:            ;
                    734:        }
                    735:     }
                    736: }
                    737: 
                    738: int
                    739: ErrorFunc(dpy, event)
                    740:        Display *dpy;
                    741:        XErrorEvent *event;
                    742: {
                    743:     switch (event->error_code) {
                    744:        case BadWindow:
                    745:        case BadDrawable:
                    746:                (void) fprintf(stderr, "wm: Window #0x%x disappeared!\n",
                    747:                        event->resourceid);
                    748:                break;
                    749:        default:
                    750:                _XDefaultError(dpy, event);
                    751:     }
                    752:     return (0);
                    753: }
                    754: 
                    755: Bool
                    756: MappedNotOverride(w) Window w;
                    757: {
                    758: XWindowAttributes wa;
                    759:        XGetWindowAttributes(dpy, w, &wa);
                    760:        return ((wa.map_state != IsUnmapped) && (wa.override_redirect != True));
                    761: }
                    762: 
                    763: static void
                    764: MoveOutline(root, x, y, width, height)
                    765:     Window root;
                    766:     int x, y, width, height;
                    767: {
                    768:     static int  lastx = 0;
                    769:     static int  lasty = 0;
                    770:     static int  lastWidth = 0;
                    771:     static int  lastHeight = 0;
                    772:     XRectangle  outline[8];
                    773:     XRectangle *r = outline;
                    774: 
                    775:     if (x == lastx && y == lasty && width == lastWidth && height == lastHeight)
                    776:        return;
                    777:     if (lastWidth || lastHeight) {
                    778:        r->x = lastx;
                    779:        r->y = lasty;
                    780:        r->width = lastWidth;
                    781:        r++->height = BORDERWIDTH;
                    782:        r->x = lastx;
                    783:        r->y = lasty + lastHeight - BORDERWIDTH;
                    784:        r->width = lastWidth;
                    785:        r++->height = BORDERWIDTH;
                    786:        r->x = lastx;
                    787:        r->y = lasty + BORDERWIDTH;
                    788:        r->width = BORDERWIDTH;
                    789:        r++->height = lastHeight - 2 * BORDERWIDTH;
                    790:        r->x = lastx + lastWidth - BORDERWIDTH;
                    791:        r->y = lasty + BORDERWIDTH;
                    792:        r->width = BORDERWIDTH;
                    793:        r++->height = lastHeight - 2 * BORDERWIDTH;
                    794:     }
                    795:     lastx = x;
                    796:     lasty = y;
                    797:     lastWidth = width;
                    798:     lastHeight = height;
                    799:     if (lastWidth || lastHeight) {
                    800:        r->x = lastx;
                    801:        r->y = lasty;
                    802:        r->width = lastWidth;
                    803:        r++->height = BORDERWIDTH;
                    804:        r->x = lastx;
                    805:        r->y = lasty + lastHeight - BORDERWIDTH;
                    806:        r->width = lastWidth;
                    807:        r++->height = BORDERWIDTH;
                    808:        r->x = lastx;
                    809:        r->y = lasty + BORDERWIDTH;
                    810:        r->width = BORDERWIDTH;
                    811:        r++->height = lastHeight - 2 * BORDERWIDTH;
                    812:        r->x = lastx + lastWidth - BORDERWIDTH;
                    813:        r->y = lasty + BORDERWIDTH;
                    814:        r->width = BORDERWIDTH;
                    815:        r++->height = lastHeight - 2 * BORDERWIDTH;
                    816:     }
                    817:     if (r != outline) {
                    818:        XFillRectangles(dpy, root, findRootInfo(root)->xorGC, outline, r - outline);
                    819:     }
                    820: }
                    821:                
                    822: void
                    823: AddGizmos(w)
                    824:     Window w;
                    825: {
                    826:     XWindowAttributes wa;
                    827:     Window      root, fw, gw, lw, uw, iw, iconw, hpw;
                    828:     int         hw;
                    829:     Bool        resize = False;
                    830:     int                x, y, wd, h, bw, d;
                    831: 
                    832:     /*
                    833:      * When we reparent w to fw, below, make sure w gets reparented back when
                    834:      * fw goes away.  We do this early, in case we die, otherwise the map
                    835:      * request in the client will hang forever. 
                    836:      */
                    837:     XChangeSaveSet(dpy, w, SetModeInsert);
                    838: 
                    839:     /*
                    840:      * Don't try to fiddle with InputOnly windows.
                    841:      */
                    842:     XGetWindowAttributes(dpy, w, &wa);
                    843:     if (wa.class == InputOnly) {
                    844:         XClientMessageEvent ev;
                    845: 
                    846:        ev.type = ClientMessage;
                    847:        ev.display = (Display *)NULL;
                    848:        ev.window = w;
                    849:        ev.message_type = XA_WM_HINTS;
                    850:        ev.format = 8;
                    851:        strcpy( ev.data.b, "bad window class" ); /* fix */
                    852:         XSendEvent( dpy, w, False, -1, &ev );
                    853:        return;
                    854:     }
                    855: 
                    856:     XGetGeometry(dpy, (Drawable) w, &root, &x, &y, &wd, &h, &bw, &d);
                    857:     /* set the border of the original window to 0 */
                    858:     ChangeBorderWidth(w, 0);
                    859:     /* make sure this window is big enough */
                    860:     if (wa.width < MINWIDTH) {
                    861:        resize = True;
                    862:        wa.width = MINWIDTH;
                    863:     }
                    864:     if (wa.height + TITLEHEIGHT + 2 * BW < MINHEIGHT) {
                    865:        resize = True;
                    866:        wa.height = MINHEIGHT;
                    867:     }
                    868:     if (resize == True) {
                    869:        XResizeWindow(dpy, w, wa.width, wa.height);
                    870:     }
                    871:     /* MakeFrame makes sure part of the header is on-screen */
                    872:     fw = MakeFrame(root, wa.x, wa.y - TITLEHEIGHT - BW, wa.width,
                    873:                   wa.height + TITLEHEIGHT + BW);
                    874:     if (!fw)
                    875:        return;
                    876:     hw = wa.width - GROWBOXWIDTH - UPBOXWIDTH - ICONIFYWIDTH - 2 * BW;
                    877:     hpw = MakeHeaderParent(root, fw, hw);
                    878:     gw = MakeHeader(root, hpw, hw);
                    879:     lw = MakeGrowBox(root, fw, wa.width - GROWBOXWIDTH);
                    880:     iw = MakeIconBox(root, fw, UPBOXWIDTH);
                    881:     uw = MakeUpBox(root, fw);
                    882:     iconw = MakeIcon(root, fw);
                    883:     XSync(dpy, False);
                    884:     errorStatus = False;
                    885:     {
                    886:        XWindowChanges wc;
                    887: 
                    888:        wc.sibling = w;
                    889:        wc.stack_mode = Above;
                    890:        XConfigureWindow(dpy, fw, CWSibling|CWStackMode, &wc);
                    891:     }
                    892:     XReparentWindow(dpy, w, fw, 0, TITLEHEIGHT + BW);
                    893:     XSync(dpy, False);
                    894:     if (errorStatus == True) {
                    895:        XDestroyWindow(dpy, fw);
                    896:        return;
                    897:     }
                    898:     /* register fw, w, gw, and lw in the association table */
                    899:     RegisterCompleteWindow(fw, w, gw, hpw, lw, iw, uw, iconw, hw);
                    900:     MapCompleteWindow(fw);
                    901: }
                    902: 
                    903: void
                    904: ReconfigureFrameAndClient(root, ga, x, y, width, height)
                    905:     Window root;
                    906:        GenericAssoc *ga;
                    907:        int x, y, width, height;
                    908: {
                    909:     XWindowAttributes wa;
                    910:     XWindowChanges wc;
                    911:     unsigned long mask;
                    912: 
                    913:     if (width < MINWIDTH)
                    914:        width = MINWIDTH;
                    915:     if (height < TITLEHEIGHT)
                    916:        height = TITLEHEIGHT;
                    917: 
                    918:     /* let's unmap all the inferiors, so we dont' see all the interim
                    919:      * exposure events of the inferior windows in the old sizes.
                    920:      * XXX I suspect this might actually be hiding a real bug in the
                    921:      * server, and should be reexamined someday.
                    922:      */
                    923:     XUnmapSubwindows(dpy,ga->frame);
                    924: 
                    925:     /* Reconfigure frame */
                    926:     wc.x = x + UPBOXWIDTH + ICONIFYWIDTH + BW;
                    927:     wc.y = y - TITLEHEIGHT - BW;
                    928:     MakeReachable(root, &wc.x, &wc.y, width - UPBOXWIDTH - GROWBOXWIDTH -
                    929:                  ICONIFYWIDTH - 2 * BW, TITLEHEIGHT);
                    930:     wc.x -= UPBOXWIDTH + ICONIFYWIDTH + 2 * BW;
                    931:     /* the extra BW is because XReconfigureWindow includes the border */
                    932:     /* width in x and y, but not in width and height */
                    933:     wc.y -= BW;
                    934:     wc.width = width;
                    935:     wc.height = height + TITLEHEIGHT + BW;
                    936:     mask = CWX | CWY | CWWidth | CWHeight;
                    937:     XConfigureWindow(dpy, ga->frame, mask, &wc);
                    938:     /* Reconfigure client */
                    939:     wc.x = 0;
                    940:     wc.y = TITLEHEIGHT + BW;
                    941:     wc.width = width;
                    942:     wc.height = height;
                    943:     wc.border_width = 0;
                    944:     mask = CWX | CWY | CWWidth | CWHeight | CWBorderWidth;
                    945:     XConfigureWindow(dpy, ga->client, mask, &wc);
                    946:     /* Reconfigure raise button */
                    947:     wc.x = 0;
                    948:     wc.y = 0;
                    949:     wc.width = UPBOXWIDTH;
                    950:     wc.height = TITLEHEIGHT;
                    951:     mask = CWX | CWY | CWWidth | CWHeight;
                    952:     XConfigureWindow(dpy, ga->upbox, mask, &wc);
                    953:     /* Reconfigure header parent */
                    954:     wc.x = UPBOXWIDTH + BW + ICONIFYWIDTH;
                    955:     wc.y = 0;
                    956:     wc.width = width - UPBOXWIDTH - GROWBOXWIDTH - 2 * BW - ICONIFYWIDTH;
                    957:     ga->headerWidth = wc.width;
                    958:     wc.height = TITLEHEIGHT;
                    959:     mask = CWX | CWY | CWWidth | CWHeight;
                    960:     XConfigureWindow(dpy, ga->headerParent, mask, &wc);
                    961:     /* Reconfigure header */
                    962:     wc.x = 0;
                    963:     wc.y = 0;
                    964:     wc.width = width - UPBOXWIDTH - GROWBOXWIDTH - 2 * BW - ICONIFYWIDTH;
                    965:     wc.height = TITLEHEIGHT;
                    966:     mask = CWX | CWY | CWWidth | CWHeight;
                    967:     XConfigureWindow(dpy, ga->header, mask, &wc);
                    968:     /* Reconfigure resize button */
                    969:     wc.x = width - GROWBOXWIDTH;
                    970:     wc.y = 0;
                    971:     wc.width = GROWBOXWIDTH;
                    972:     wc.height = TITLEHEIGHT;
                    973:     mask = CWX | CWY | CWWidth | CWHeight;
                    974:     XConfigureWindow(dpy, ga->rbox, mask, &wc);
                    975:     /* Reconfigure iconify button */
                    976:     wc.x = UPBOXWIDTH;
                    977:     wc.y = 0;
                    978:     wc.width = ICONIFYWIDTH;
                    979:     wc.height = TITLEHEIGHT;
                    980:     mask = CWX | CWY | CWWidth | CWHeight;
                    981:     XConfigureWindow(dpy, ga->iconify, mask, &wc);
                    982:     XGetWindowAttributes(dpy, ga->frame, &wa);
                    983: 
                    984:     XMapSubwindows(dpy,ga->frame);
                    985: }
                    986: 
                    987: Window
                    988: MakeGrowBox(root, fw, lx)
                    989:     Window root;
                    990:     Window fw;
                    991:     int lx;
                    992: {
                    993:     unsigned long valuemask;
                    994:     XSetWindowAttributes attributes;
                    995:     RootInfoRec *ri = findRootInfo(root);
                    996:     int scr = ri - RootInfo;
                    997: 
                    998:     valuemask = CWEventMask | CWBackPixmap;
                    999:     attributes.background_pixmap = ri->growBox;
                   1000:     attributes.event_mask =
                   1001:        ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
                   1002:        PointerMotionHintMask | ExposureMask;
                   1003:     return XCreateWindow(dpy, fw, lx, 0, GROWBOXWIDTH, TITLEHEIGHT, 0,
                   1004:                   DefaultDepth(dpy, scr), CopyFromParent,
                   1005:                   DefaultVisual(dpy, scr), valuemask, &attributes);
                   1006: }
                   1007: 
                   1008: Window
                   1009: MakeUpBox(root, fw)
                   1010:     Window root;
                   1011:     Window fw;
                   1012: {
                   1013:     unsigned long valuemask;
                   1014:     XSetWindowAttributes attributes;
                   1015:     RootInfoRec *ri = findRootInfo(root);
                   1016:     int scr = ri - RootInfo;
                   1017: 
                   1018:     valuemask = CWEventMask | CWBackPixmap;
                   1019:     attributes.background_pixmap = ri->doubleArrow;
                   1020:     attributes.event_mask =
                   1021:        ButtonPressMask | ButtonReleaseMask | ExposureMask;
                   1022:     return XCreateWindow(dpy, fw, 0, 0, UPBOXWIDTH, TITLEHEIGHT, 0,
                   1023:             DefaultDepth(dpy, scr), CopyFromParent, DefaultVisual(dpy, scr),
                   1024:                   valuemask, &attributes);
                   1025: }
                   1026: 
                   1027: Window
                   1028: MakeIconBox(root, fw, ix)
                   1029:     Window root;
                   1030:     Window fw;
                   1031:     int ix;
                   1032: {
                   1033:     unsigned long valuemask;
                   1034:     XSetWindowAttributes attributes;
                   1035:     RootInfoRec *ri = findRootInfo(root);
                   1036:     int         scr = ri - RootInfo;
                   1037: 
                   1038:     valuemask = CWEventMask | CWBackPixmap;
                   1039:     attributes.background_pixmap = ri->cross;
                   1040:     attributes.event_mask =
                   1041:        ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
                   1042:        PointerMotionHintMask | ExposureMask;
                   1043:     return XCreateWindow(dpy, fw, ix, 0, UPBOXWIDTH, TITLEHEIGHT, 0,
                   1044:             DefaultDepth(dpy, scr), CopyFromParent, DefaultVisual(dpy, scr),
                   1045:                   valuemask, &attributes);
                   1046: }
                   1047:        
                   1048: void
                   1049: ChangeBorderWidth(w, newWidth) Window w; int newWidth;
                   1050: {
                   1051: XWindowChanges wch;
                   1052:        wch.border_width = newWidth;
                   1053:        XConfigureWindow(dpy, w, CWBorderWidth, &wch);
                   1054: }
                   1055: 
                   1056: void
                   1057: MapCompleteWindow(frame) Window frame;
                   1058: {
                   1059:        XMapSubwindows(dpy, frame);
                   1060:        XMapWindow(dpy, frame);
                   1061: }
                   1062: 
                   1063: void
                   1064: RegisterCompleteWindow(frame, client, header, hp, rbox, iconify, upbox, iconw, headerWidth)
                   1065:        Window frame, client, header, hp, rbox, upbox, iconify, iconw;
                   1066:        int headerWidth;
                   1067: {
                   1068:     GenericAssoc *fa;
                   1069:     XWMHints   *wmhints;
                   1070:     Window      root;
                   1071:     int         x, y, wd, ht, bw, d;
                   1072: 
                   1073:     XGetGeometry(dpy, (Drawable) client, &root, &x, &y, &wd, &ht, &bw, &d);
                   1074: 
                   1075:     XSelectInput(dpy, client, PropertyChangeMask);
                   1076:     fa = GimmeAssocStruct();
                   1077:     fa->frame = frame;
                   1078:     fa->header = header;
                   1079:     fa->headerParent = hp;
                   1080:     fa->client = client;
                   1081:     fa->rbox = rbox;
                   1082:     fa->iconify = iconify;
                   1083:     fa->upbox = upbox;
                   1084:     fa->headerWidth = headerWidth;
                   1085:     fa->iconWindow = iconw;
                   1086:     fa->iconnamelen = fa->namelen = 0;
                   1087:     ProcessNewIconName(root, fa);
                   1088:     ProcessNewName(root, fa);
                   1089:     if ((wmhints = XGetWMHints(dpy, client)) &&
                   1090:        (wmhints->flags & IconPositionHint)) {
                   1091:        fa->iconx = wmhints->icon_x;
                   1092:        fa->icony = wmhints->icon_y;
                   1093:        fa->iconknown = True;
                   1094:     }
                   1095:     else
                   1096:        fa->iconknown = False;
                   1097:     if (wmhints)
                   1098:        free((char *) wmhints);
                   1099:     XMakeAssoc(dpy, frameInfo, (XID) frame, (char *) fa);
                   1100:     XMakeAssoc(dpy, frameInfo, (XID) header, (char *) fa);
                   1101:     XMakeAssoc(dpy, frameInfo, (XID) hp, (char *) fa);
                   1102:     XMakeAssoc(dpy, frameInfo, (XID) client, (char *) fa);
                   1103:     XMakeAssoc(dpy, frameInfo, (XID) rbox, (char *) fa);
                   1104:     XMakeAssoc(dpy, frameInfo, (XID) iconify, (char *) fa);
                   1105:     XMakeAssoc(dpy, frameInfo, (XID) upbox, (char *) fa);
                   1106:     XMakeAssoc(dpy, frameInfo, (XID) iconw, (char *) fa);
                   1107:     /* Xfree(pd); */
                   1108: }
                   1109: 
                   1110: Window
                   1111: MakeHeaderParent(root, fw, width)
                   1112:     Window root;
                   1113:     Window fw;
                   1114:     int width;
                   1115: {
                   1116:     unsigned long valuemask;
                   1117:     XSetWindowAttributes attributes;
                   1118:     Window      result;
                   1119:     int scr = findRootInfo(root) - RootInfo;
                   1120: 
                   1121:     valuemask = CWBackPixel;
                   1122:     attributes.background_pixel = BlackPixel(dpy, scr);
                   1123:     result = XCreateWindow(dpy, fw, UPBOXWIDTH + ICONIFYWIDTH + BW, 0,
                   1124:                     width, TITLEHEIGHT, 0,
                   1125:                     DefaultDepth(dpy, scr), CopyFromParent,
                   1126:                     DefaultVisual(dpy, scr), valuemask,
                   1127:                     &attributes);
                   1128:     return result;
                   1129: }
                   1130: 
                   1131: Window
                   1132: MakeHeader(root, hw, width)
                   1133:     Window root;
                   1134:     Window hw;
                   1135:     int width;
                   1136: {
                   1137:     unsigned long    valuemask;
                   1138:     XSetWindowAttributes attributes;
                   1139:     Window      result;
                   1140:     int         scr = findRootInfo(root) - RootInfo;
                   1141: 
                   1142:     valuemask = CWEventMask | CWBackPixel;
                   1143:     attributes.event_mask =
                   1144:        ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
                   1145:        ExposureMask | PointerMotionHintMask;
                   1146:     attributes.background_pixel = BlackPixel(dpy, scr);
                   1147:     result = XCreateWindow(dpy, hw, 0, 0, width, TITLEHEIGHT, 0,
                   1148:                     DefaultDepth(dpy, scr), CopyFromParent,
                   1149:                     DefaultVisual(dpy, scr), valuemask,
                   1150:                     &attributes);
                   1151:     return result;
                   1152: }
                   1153: 
                   1154: /* XXX fw unused? */
                   1155: MakeIcon(root, fw)
                   1156:     Window root;
                   1157:     Window fw;
                   1158: {
                   1159:     unsigned long  valuemask;
                   1160:     XSetWindowAttributes attributes;
                   1161:     Window      result;
                   1162:     int         scr = findRootInfo(root) - RootInfo;
                   1163: 
                   1164:     valuemask = CWEventMask | CWBackPixel | CWBorderPixel;
                   1165:     attributes.event_mask =
                   1166:        ButtonPressMask | ButtonReleaseMask | ButtonMotionMask |
                   1167:        ExposureMask | PointerMotionHintMask;
                   1168:     attributes.background_pixel = BlackPixel(dpy, scr);
                   1169:     attributes.border_pixel = WhitePixel(dpy, scr);
                   1170:     result = XCreateWindow(dpy, root, 0, 0, ICONWIDTH, TITLEHEIGHT, BW,
                   1171:             DefaultDepth(dpy, scr), CopyFromParent, DefaultVisual(dpy, scr),
                   1172:                     valuemask, &attributes);
                   1173:     return result;
                   1174: }
                   1175: 
                   1176: 
                   1177: Window
                   1178: MakeFrame(root, x, y, width, height)
                   1179:     Window root;
                   1180:        int x, y, width, height;
                   1181: {
                   1182:     unsigned long valuemask;
                   1183:     XSetWindowAttributes attributes;
                   1184:     int         hx, hy;
                   1185:     int         scr;
                   1186:     RootInfoRec *ri = findRootInfo(root);
                   1187: 
                   1188:     if (!ri)
                   1189:        return (NULL);
                   1190:     scr = ri - RootInfo;
                   1191:     hx = x + ICONIFYWIDTH + UPBOXWIDTH + BW;
                   1192:     hy = y;
                   1193:     MakeReachable(root, &hx, &hy, width - UPBOXWIDTH - GROWBOXWIDTH - ICONIFYWIDTH
                   1194:                  - 2 * BW, TITLEHEIGHT);
                   1195:     x = hx - (ICONIFYWIDTH + UPBOXWIDTH + BW) - BW;
                   1196:     y = hy - BW;
                   1197:     valuemask = CWEventMask | CWBorderPixel | CWBackPixel;
                   1198:     attributes.event_mask = SubstructureRedirectMask
                   1199:        | SubstructureNotifyMask;
                   1200:     attributes.background_pixel = WhitePixel(dpy, scr);
                   1201:     attributes.border_pixel = WhitePixel(dpy, scr);
                   1202:     attributes.bit_gravity = NorthWestGravity;
                   1203:     return XCreateWindow(dpy, root, x, y, width, height, BORDERWIDTH,
                   1204:             DefaultDepth(dpy, scr), CopyFromParent, DefaultVisual(dpy, scr),
                   1205:                   valuemask, &attributes);
                   1206: }
                   1207: 
                   1208: void
                   1209: RemoveGizmos(ga) GenericAssoc *ga;
                   1210: {
                   1211:        XDeleteAssoc(dpy, frameInfo, ga->frame);
                   1212:        XDeleteAssoc(dpy, frameInfo, ga->header);
                   1213:        XDeleteAssoc(dpy, frameInfo, ga->rbox);
                   1214:        XDeleteAssoc(dpy, frameInfo, ga->iconify);
                   1215:        XDeleteAssoc(dpy, frameInfo, ga->upbox);
                   1216:        XDeleteAssoc(dpy, frameInfo, ga->iconWindow);
                   1217:        XDeleteAssoc(dpy, frameInfo, ga->client);
                   1218:        XDestroyWindow(dpy, ga->frame);
                   1219:        XDestroyWindow(dpy, ga->iconWindow);
                   1220:        free((char *) ga);
                   1221: }
                   1222: 
                   1223: 
                   1224: StartConnectionToServer(argc, argv)
                   1225:        int     argc;
                   1226:        char    *argv[];
                   1227: {
                   1228:     char       *display;
                   1229:     int         i;
                   1230:     extern char *index();
                   1231: 
                   1232:     display = NULL;
                   1233:     for (i = 1; i < argc; i++) {
                   1234:        if (index(argv[i], ':') != NULL)
                   1235:            display = argv[i];
                   1236:     }
                   1237:     if (!(dpy = XOpenDisplay(display))) {
                   1238:        Error(1, "Cannot open display\n");
                   1239:     }
                   1240: }
                   1241: 
                   1242: Error(status, message) int status; char *message;
                   1243: {
                   1244:        printf("%s", message);
                   1245:        if (!status) return;
                   1246:        else exit(1);
                   1247: }
                   1248: 
                   1249: GenericAssoc *
                   1250: GimmeAssocStruct(){
                   1251:        return (GenericAssoc *) malloc(sizeof(GenericAssoc));
                   1252: }
                   1253: 
                   1254: 
                   1255: char *
                   1256: WindowType(w) Window w;
                   1257: {
                   1258: GenericAssoc *ga;
                   1259:        ga = (GenericAssoc *) XLookUpAssoc(dpy, frameInfo, w);
                   1260:        if (ga && w == ga->frame) return "frame";
                   1261:        if (ga && w == ga->header) return "header";
                   1262:        if (ga && w == ga->client) return "client";
                   1263:        if (ga && w == ga->rbox) return "resize box";
                   1264:        if (ga && w == ga->iconify) return "iconify box";
                   1265:        if (ga && w == ga->upbox) return "raise box";
                   1266:        if (ga && w == ga->iconWindow) return "icon";
                   1267:        if (ga) {
                   1268:                Error(0, "WindowType: error in association table routines\n");
                   1269:                return "error";
                   1270:        }
                   1271:        Error(0, "WindowType: window %d not found in assoc table\n", w);
                   1272:        return "error";
                   1273: }
                   1274: 
                   1275: Window
                   1276: Frame(w) Window w;
                   1277: {
                   1278: GenericAssoc *ga;
                   1279:        ga = (GenericAssoc *) XLookUpAssoc(dpy, frameInfo, w);
                   1280:        if (ga) return ga->frame;
                   1281:        Error(0, "Frame: window %d not found in assoc table\n");
                   1282:        return None;
                   1283: }
                   1284: 
                   1285: void
                   1286: MakeReachable(root, x, y, width, height)
                   1287:     Window root;
                   1288:        int *x, *y;
                   1289:        int width, height;
                   1290: {
                   1291:     RootInfoRec *ri = findRootInfo(root);
                   1292: 
                   1293:     if (!ri)
                   1294:        return;
                   1295:     if (*x <= MARGIN + ri->rootx - width)
                   1296:        *x = MARGIN + ri->rootx - width + 1;
                   1297:     if (*y <= MARGIN + ri->rooty - height)
                   1298:        *y = MARGIN + ri->rooty - height + 1;
                   1299:     if (*x >= ri->rootx + ri->rootwidth - MARGIN)
                   1300:        *x = ri->rootx + ri->rootwidth - MARGIN - 1;
                   1301:     if (*y >= ri->rooty + ri->rootheight - MARGIN)
                   1302:        *y = ri->rooty + ri->rootheight - MARGIN - 1;
                   1303: }
                   1304: 
                   1305: Bool
                   1306: FillName(ga) GenericAssoc *ga;
                   1307: {
                   1308:     Status      status;
                   1309:     char       *name;
                   1310:     Bool        noname = False;
                   1311:     int         len;
                   1312:     Bool        res;
                   1313:     extern char *strncpy();
                   1314: 
                   1315:     status = XFetchName(dpy, ga->client, &name);
                   1316:     if (!status || !name || !(*name)) {
                   1317:        name = "No name";
                   1318:        noname = True;
                   1319:     }
                   1320: 
                   1321:     len = strlen(name);
                   1322:     if (len >= MAXNAME)
                   1323:        len = MAXNAME;
                   1324:     if (len != ga->namelen || strncmp(name, ga->name, len)) {
                   1325:        ga->namelen = len;
                   1326:        (void) strncpy(ga->name, name, ga->namelen);
                   1327:        res = True;
                   1328:     }
                   1329:     else
                   1330:        res = False;
                   1331:     if (!noname)
                   1332:        free(name);
                   1333:     return res;
                   1334: }
                   1335: 
                   1336: void
                   1337: FillIconName(ga) GenericAssoc *ga;
                   1338: {
                   1339: Status status;
                   1340: long len2;
                   1341: char *pd;
                   1342: Atom at;
                   1343: int af;
                   1344: long ba;
                   1345:        status = XGetWindowProperty(dpy, ga->client, XA_WM_ICON_NAME,
                   1346:                0,  MAXNAME, False,
                   1347:                XA_STRING, &at, &af, &len2, &ba, &pd);
                   1348:        if (status != Success) {
                   1349:                ga->iconnamelen = 0;
                   1350:        } else {
                   1351:                switch (af) {
                   1352:                case 8:
                   1353:                        ga->iconnamelen = len2;
                   1354:                        if (ga->iconnamelen >= MAXNAME) ga->iconnamelen = MAXNAME;
                   1355:                        strncpy(ga->iconname, pd, ga->iconnamelen);
                   1356:                        free (pd);
                   1357:                        break;
                   1358:                default:
                   1359:                        ga->iconnamelen = 0;
                   1360:                        if (pd) free(pd);
                   1361:                }
                   1362:        } 
                   1363: }
                   1364: 
                   1365: void
                   1366: ProcessNewName(root, ga)
                   1367:     Window root;
                   1368:     GenericAssoc *ga;
                   1369: {
                   1370:        if (!FillName(ga)) return;
                   1371:        if (ga->iconnamelen == 0) {
                   1372:                Bool wasMapped;
                   1373:                int width;
                   1374:                wasMapped = MappedNotOverride(ga->iconWindow);
                   1375:                width = XTextWidth(font, ga->name, ga->namelen) + 2*BW;
                   1376:                MakeReachable(root, &ga->iconx, &ga->icony, width, TITLEHEIGHT);
                   1377:                if (wasMapped) XUnmapWindow(dpy, ga->iconWindow); 
                   1378:                XMoveResizeWindow(dpy, ga->iconWindow, ga->iconx - BW,
                   1379:                        ga->icony - BW, width, TITLEHEIGHT);
                   1380:                if (wasMapped) XMapWindow(dpy, ga->iconWindow);
                   1381:        }
                   1382:        XUnmapWindow(dpy, ga->header);
                   1383:        XMapWindow(dpy, ga->header);
                   1384: }
                   1385: 
                   1386: void
                   1387: ProcessNewIconName(root, ga)
                   1388:     Window root;
                   1389:     GenericAssoc *ga;
                   1390: {
                   1391:     int         oldIconLen;
                   1392:     Bool        wasMapped;
                   1393:     int         width;
                   1394: 
                   1395:     wasMapped = MappedNotOverride(ga->iconWindow);
                   1396:     oldIconLen = ga->iconnamelen;
                   1397:     FillIconName(ga);
                   1398:     if (ga->iconnamelen == 0) {
                   1399:        if (oldIconLen == 0)
                   1400:            return;
                   1401:        width = XTextWidth(font, ga->name, ga->namelen) + 2 * BW;
                   1402:        MakeReachable(root, &ga->iconx, &ga->icony, width, TITLEHEIGHT);
                   1403:        if (wasMapped)
                   1404:            XUnmapWindow(dpy, ga->iconWindow);
                   1405:        XMoveResizeWindow(dpy, ga->iconWindow, ga->iconx - BW,
                   1406:                         ga->icony - BW, width, TITLEHEIGHT);
                   1407:        if (wasMapped)
                   1408:            XMapWindow(dpy, ga->iconWindow);
                   1409:        return;
                   1410:     }
                   1411:     width = XTextWidth(font, ga->iconname, ga->iconnamelen) + 2 * BW;
                   1412:     MakeReachable(root, &ga->iconx, &ga->icony, width, TITLEHEIGHT);
                   1413:     if (wasMapped)
                   1414:        XUnmapWindow(dpy, ga->iconWindow);
                   1415:     XMoveResizeWindow(dpy, ga->iconWindow, ga->iconx - BW,
                   1416:                     ga->icony - BW, width, TITLEHEIGHT);
                   1417:     if (wasMapped)
                   1418:        XMapWindow(dpy, ga->iconWindow);
                   1419: }

unix.superglobalmegacorp.com

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