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