|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.