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