home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume3 / awm2 / part08 / Gadget.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-02-20  |  8.8 KB  |  339 lines

  1.  
  2.  
  3.  
  4. #ifndef lint
  5. static char *rcsid_Gadget_c = "$Header: /usr/graph2/X11.3/contrib/windowmgrs/awm/RCS/Gadget.c,v 1.2 89/02/07 20:04:53 jkh Exp $";
  6. #endif  lint
  7.  
  8. #include "X11/copyright.h"
  9. /*
  10.  *
  11.  * Copyright 1987, 1988 by Ardent Computer Corporation, Sunnyvale, Ca.
  12.  *
  13.  * Copyright 1987 by Jordan Hubbard.
  14.  *
  15.  *
  16.  *                         All Rights Reserved
  17.  *
  18.  * Permission to use, copy, modify, and distribute this software and its
  19.  * documentation for any purpose and without fee is hereby granted,
  20.  * provided that the above copyright notice appear in all copies and that
  21.  * both that copyright notice and this permission notice appear in
  22.  * supporting documentation, and that the name of Ardent Computer
  23.  * Corporation or Jordan Hubbard not be used in advertising or publicity
  24.  * pertaining to distribution of the software without specific, written
  25.  * prior permission.
  26.  *
  27.  */
  28.  
  29. /*
  30.  * MODIFICATION HISTORY
  31.  *
  32.  * 001 -- Jortan Hubbard, Ardent Computer.
  33.  * Gadget boxes in title bars.
  34.  * 1.2 -- Jordan Hubbard, Ardent Computer.
  35.  *  GadgetBorders used in placement calculations, initial
  36.  *  gadget positions calculated correcly. (Chris Thewalt fixes).
  37.  * 1.3 -- Color handling changed to deal with multiple colormaps.
  38.  * 1.4 -- Fixed really silly bug with gadget offset.
  39.  *
  40.  */
  41.  
  42. #include "awm.h"
  43.  
  44. #include "X11/Xutil.h"
  45.  
  46. extern XContext AwmContext;
  47. void PaintGadgets();
  48.  
  49. AwmInfoPtr IsGadgetWin(w, gnum)
  50. Window w;
  51. int *gnum;
  52. {
  53.      AwmInfoPtr awi;
  54.      int i;
  55.  
  56.      Entry("IsGadgetWin")
  57.  
  58.      if (!XFindContext(dpy, w, AwmContext, (caddr_t *) &awi)) {
  59.           if (!awi->gadgets)
  60.                Leave((AwmInfoPtr)NULL)
  61.       for (i = 0; i < NumGadgets; i++)
  62.            if (awi->gadgets[i] == w) {
  63.                     if (gnum)
  64.                     *gnum = i;
  65.                 Leave(awi)
  66.                }
  67.      }
  68.      Leave((AwmInfoPtr)NULL)
  69. }
  70.  
  71. /*
  72.  * This routine adds and/or places  gadgets onto a title bar.
  73.  */
  74. int PutGadgets(w)
  75. Window w;
  76. {
  77.      int i, dir;
  78.      int rx, lx, nx, ny;
  79.      XWindowAttributes xwa;
  80.      XSetWindowAttributes swa;
  81.      Colormap cmap;
  82.      unsigned long valuemask;
  83.      GadgetDecl *gdec;
  84.      AwmInfo *awi;
  85.      Boolean change = FALSE;
  86.      Window tmp;
  87.  
  88.      Entry("PutGadgets")
  89.  
  90.      /* are there any gadgets declared? */
  91.      if (NumGadgets < 1)
  92.       Leave_void
  93.      /* does this window have a title? */
  94.      if (!(awi = IsTitled(w)))
  95.       Leave_void
  96.  
  97.      if (!(awi->attrs & AT_GADGETS))
  98.       Leave_void
  99.      /* if the window already has gadgets, this is a reshuffle */
  100.      if (awi->gadgets)
  101.       change = TRUE;
  102.      else
  103.       awi->gadgets = (Window *)malloc(sizeof(Window) * NumGadgets + 1);
  104.      if (!awi->gadgets) {
  105.       fprintf(stderr, "PutGadgets: Can't allocate memory for gadgets!\n");
  106.           Leave_void
  107.      }
  108.      if (XGetWindowAttributes(dpy, awi->title, &xwa) == BadWindow) {
  109.       fprintf(stderr, "PutGadgets: Can't get attrs for client window %x\n",
  110.           w);
  111.       Leave_void
  112.      }
  113.      /* define some initial positioning information */
  114.      dir = RightGadgetGravity;
  115.      lx = 0;
  116.      rx = xwa.width;
  117.      cmap = xwa.colormap;
  118.      valuemask = CWBackPixel | CWEventMask | CWColormap;
  119.      swa.event_mask = (ButtonPressMask | ButtonReleaseMask | ExposureMask);
  120.      swa.colormap = cmap;
  121.      for (i = 0; i < NumGadgets && Gadgets[i]; i++) {
  122.       gdec = Gadgets[i];
  123.  
  124.       /* Does gadget have its own gravity? */
  125.       if (gdec->gravity != NoGadgetGravity)
  126.            dir = gdec->gravity;
  127.       ny = xwa.height - gdec->high;
  128.       if (ny <= 0)
  129.                gdec->high = xwa.height;
  130.       else
  131.            ny = (ny / 2) - 1;
  132.       if (ny < 0)
  133.            ny = 0;
  134.       if (dir == LeftGadgetGravity) {
  135.            nx = lx + gdec->offset;
  136.            if (lx != 0) /* not first time through, add pad */
  137.             nx += GadgetPad;
  138.            if (nx < 0)
  139.             nx = 0;
  140.            lx = nx + gdec->wide;
  141.                dir = RightGadgetGravity;
  142.       }
  143.       else if (dir == RightGadgetGravity) {    
  144.            nx = rx - gdec->wide - gdec->offset - (2 * GadgetBorder);
  145.            if (rx != xwa.width)
  146.             nx -= GadgetPad;
  147.            rx = nx - GadgetBorder;
  148.                dir = LeftGadgetGravity;
  149.       }
  150.       else /* Center Gravity */
  151.            nx = ((xwa.width - gdec->wide) / 2) + gdec->offset;
  152.       if (change == FALSE || !awi->gadgets[i]) {
  153.            swa.background_pixel = GetPixel(gdec->backcolor, cmap);
  154.            tmp = awi->gadgets[i] = XCreateWindow(dpy, awi->title, nx, ny,
  155.                              gdec->wide, gdec->high,
  156.                              GadgetBorder,
  157.                              xwa.depth, xwa.class,
  158.                              xwa.visual, valuemask,
  159.                              &swa);
  160.            if (!tmp) {
  161.             fprintf(stderr, "PutGadgets: Can't create gadget #%d\n",
  162.                 i);
  163.             Leave_void
  164.            }
  165.            if (gdec->data) {
  166.             Pixmap pix;
  167.  
  168.             pix = XCreatePixmapFromBitmapData(dpy, tmp, gdec->data,
  169.                               gdec->wide, gdec->high,
  170.                               GetPixel(gdec->forecolor, cmap),
  171.                               GetPixel(gdec->backcolor, cmap),
  172.                               xwa.depth);
  173.             if (!pix) {
  174.              fprintf(stderr, "PutGadgets: Unable to create pixmap for #%d\n",
  175.                  i);
  176.                          fprintf(stderr, "Using grey...\n");
  177. #ifndef RAINBOW
  178.                          pix = GrayPixmap;
  179. #else
  180.                          pix = awi->grayPixmap;
  181. #endif
  182.             }
  183.             XSetWindowBackgroundPixmap(dpy, tmp, pix);
  184.             XFreePixmap(dpy, pix);
  185.            }
  186.            XMapWindow(dpy, tmp);
  187.            XSaveContext(dpy, tmp, AwmContext, (caddr_t) awi);
  188.       }
  189.       else
  190.            XMoveWindow(dpy, awi->gadgets[i], nx, ny);
  191.      }
  192.      if (change == FALSE) /* make sure the window array is null terminated */
  193.           awi->gadgets[i] = (Window)NULL;
  194.      PaintGadgets(w);
  195.      Leave_void
  196. }
  197.  
  198. int FreeGadget(n)
  199. int n;
  200. {
  201.      Entry("FreeGadget")
  202.  
  203.      if (Gadgets[n]->data)
  204.       XFree(Gadgets[n]->data);
  205.      if (Gadgets[n]->name)
  206.       free(Gadgets[n]->name);
  207.      if (Gadgets[n])
  208.       free(Gadgets[n]);
  209. }
  210.  
  211. int CheckGadgets()
  212. {
  213.      int i, status = 0;
  214.  
  215.      Entry("CheckGadgets")
  216.  
  217.      for (i = 0; i < NumGadgets; i++)
  218.       if (!Gadgets[i]) {
  219.            fprintf(stderr, "awm: Gadget #%d is not declared!\n",
  220.                i);
  221.            fprintf(stderr, "All gadgets from 0 to %d must be declared.\n",
  222.                NumGadgets - 1);
  223.            status = 1;
  224.       }
  225.      Leave(status)
  226. }
  227.  
  228. Boolean ResetGadgets()
  229. {
  230.      int i;
  231.  
  232.      Entry("ResetGadgets")
  233.  
  234.      for (i = 0; i < NumGadgets; i++) {
  235.       FreeGadget(i);
  236.       Gadgets[i] = 0;
  237.      }
  238.      NumGadgets = 0;
  239.      if (Gadgets) {
  240.       free(Gadgets);
  241.       Gadgets = 0;
  242.      }
  243. }
  244.      
  245. void DestroyGadgets(w)
  246. Window w;
  247. {
  248.      int i;
  249.      AwmInfoPtr awi;
  250.  
  251.      Entry("DestroyGadgets")
  252.  
  253.      if (!(awi = IsTitled(w)))
  254.       Leave_void
  255.      if (!awi->gadgets)
  256.       Leave_void
  257.      for (i = 0; i < NumGadgets && Gadgets[i]; i++) {
  258.       XDeleteContext(dpy, awi->gadgets[i], AwmContext);
  259.       XDestroyWindow(dpy, awi->gadgets[i]);
  260.      }
  261.      free(awi->gadgets);
  262.      awi->gadgets = 0;
  263.      Leave_void
  264. }
  265.  
  266. void PaintGadgets(w)
  267. Window w;
  268. {
  269.      int i, y, x = 0;
  270.      AwmInfoPtr awi;
  271.      GadgetDecl *gdec;
  272.      XWindowAttributes xwa;
  273.  
  274.      Entry("PaintGadgets")
  275.  
  276.      if (!(awi = IsTitled(w)))
  277.       Leave_void
  278.      if (!awi->gadgets)
  279.       Leave_void
  280.      XGetWindowAttributes(dpy, awi->client, &xwa);
  281.      for (i = 0; i < NumGadgets && Gadgets[i]; i++) {
  282.       gdec = Gadgets[i];
  283.       if (!gdec->data) {
  284.            XGCValues gcv;
  285.  
  286.            gcv.font = gdec->fontInfo->fid;
  287.            gcv.foreground = GetPixel(gdec->forecolor, xwa.colormap);
  288.            gcv.background = GetPixel(gdec->backcolor, xwa.colormap);
  289.            XChangeGC(dpy, awi->winGC, (GCFont | GCForeground |
  290.                        GCBackground), &gcv);
  291.            if (strlen(gdec->name) == 1) { /* it's a glyph (we think) */
  292.             XFontStruct *real_font;
  293.             XCharStruct char_info;
  294.             int char_number, index, byte1, byte2;
  295.  
  296.             real_font = gdec->fontInfo;
  297.             char_number = gdec->name[0];
  298.             char_info = real_font->max_bounds;
  299.             index = char_number;
  300.  
  301.             if (real_font->per_char) {
  302.              if (!real_font->min_byte1 && !real_font->max_byte1) {
  303.                   if (char_number < real_font->min_char_or_byte2 ||
  304.                   char_number > real_font->max_char_or_byte2)
  305.                    index = real_font->default_char;
  306.                   index -= real_font->min_char_or_byte2;
  307.              } else {
  308.                   byte2 = index & 0xff;
  309.                   byte1 = (index>>8) & 0xff;
  310.                   if (byte1 < real_font->min_byte1 ||
  311.                   byte1 > real_font->max_byte1 ||
  312.                   byte2 < real_font->min_char_or_byte2 ||
  313.                   byte2 > real_font->max_char_or_byte2) {
  314.                    byte2 = real_font->default_char & 0xff;
  315.                    byte1 = (real_font->default_char>>8)&0xff;
  316.                   }
  317.                   byte1 -= real_font->min_byte1;
  318.                   byte2 -= real_font->min_char_or_byte2;
  319.                   index = byte1 * (real_font->max_char_or_byte2 -
  320.                            real_font->min_char_or_byte2 + 1) +
  321.                             byte2;
  322.              }
  323.              char_info = real_font->per_char[index];
  324.             }
  325.             x = 1 - GadgetBorder - char_info.lbearing;
  326.             y = char_info.ascent;
  327.            }
  328.            else {
  329.             y = (gdec->high + (gdec->fontInfo->max_bounds.ascent -
  330.                        gdec->fontInfo->max_bounds.descent)) / 2;
  331.             x = GadgetBorder;
  332.            }
  333.            XDrawString(dpy, awi->gadgets[i], awi->winGC, x,
  334.                y, (char *) gdec->name, strlen(gdec->name));
  335.       }
  336.      }
  337.      Leave_void
  338. }
  339.