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: }

Defined functions

Assign defined in line 871; used 3 times
AssignButton defined in line 341; used 6 times
DisplayButton defined in line 835; used 5 times
DoButtonFunc defined in line 679; used 1 times
DoOperation defined in line 620; used 1 times
Error defined in line 1031; used 34 times
Flush defined in line 1045; never used
GetButton defined in line 1015; used 9 times
GetDefaults defined in line 142; used 1 times
GetEvent defined in line 948; used 3 times
GrabButtons defined in line 587; used 1 times
IconifyOrDeIconify defined in line 855; used 2 times
InterpLocation defined in line 545; used 1 times
InvertButton defined in line 826; used 2 times
MakePixmap defined in line 440; used 4 times
MapPopup defined in line 720; used 2 times
NonSelect defined in line 670; used 1 times
  • in line 89
OpenDisplay defined in line 372; used 1 times
ProcessArgs defined in line 198; used 1 times
ProcessMenuFunction defined in line 603; used 1 times
RefreshMenu defined in line 1021; used 1 times
SetUpEverything defined in line 113; used 1 times
  • in line 73
SetUpFonts defined in line 456; used 1 times
SetUpMenu defined in line 467; used 1 times
StoreCursors defined in line 403; used 1 times
StorePixmaps defined in line 415; used 1 times
Sync defined in line 1050; never used
Syntax defined in line 361; used 7 times
Unassigned defined in line 715; used 2 times
UnmapPopup defined in line 780; used 11 times
UnsavePopup defined in line 816; used 1 times
main defined in line 65; never used

Defined variables

buttonFunc defined in line 47; used 14 times
buttonGXfunc defined in line 61; used 4 times
buttonPixmap defined in line 31; used 5 times
canDoToMenu defined in line 43; used 1 times
code defined in line 50; used 2 times
doingOp defined in line 53; used 4 times
item defined in line 46; used 21 times
itemHeight defined in line 48; used 13 times
itemWidth defined in line 48; used 11 times
itemcount defined in line 48; used 12 times
label defined in line 37; used 4 times
lastMenuOp defined in line 52; used 3 times
menu defined in line 33; used 32 times
menuHeight defined in line 49; used 13 times
menuImage defined in line 57; used 7 times
menuWidth defined in line 49; used 13 times
menuX defined in line 49; used 5 times
menuY defined in line 49; used 5 times
needsWindow defined in line 41; used 4 times
popupSaved defined in line 58; used 6 times
rcsid_wmsubs_c defined in line 4; never used
reverse defined in line 60; used 4 times
saveScreen defined in line 56; used 6 times
savex defined in line 55; used 2 times
savey defined in line 55; used 2 times
skinny defined in line 51; used 8 times

Defined macros

Button defined in line 26; used 5 times
default_frame_width defined in line 7; used 1 times
default_icon_font defined in line 11; used 1 times
default_iconify_delta defined in line 12; used 1 times
default_left defined in line 19; used 1 times
  • in line 47
default_mask defined in line 8; used 1 times
default_menu_font defined in line 9; used 1 times
default_menu_x defined in line 13; never used
default_menu_y defined in line 14; never used
default_middle defined in line 20; used 1 times
  • in line 47
default_right defined in line 21; used 1 times
  • in line 47
default_size_font defined in line 10; used 1 times
popup_button defined in line 23; used 6 times
unassigned_button defined in line 22; used 4 times
Last modified: 1986-02-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3725
Valid CSS Valid XHTML 1.0 Strict