home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume6 / xsbm / part01 / xshowbitmap.c < prev   
C/C++ Source or Header  |  1993-04-28  |  10KB  |  292 lines

  1. /* Dan Heller <argv@sun.com>
  2.  *
  3.  * xshowbitmap.c -
  4.  *    Displays a set of bitmaps specified on the command line, from
  5.  * a pipe, or typed into stdin.  Bitmaps must be specified as file names.
  6.  * All the bitmaps are drawn into one large pixmap which is used as the
  7.  * XtNbitmap for a Label Widget.  This label widget is placed in a viewport
  8.  * widget so you can scroll around in it.  The bitmaps are displayed in
  9.  * an equal number of rows and columns if possible.  You may override this
  10.  * by specify *either* the number or rows (-rows N) or the number of
  11.  * columns (-cols) to use.  You can't specify both.
  12.  *
  13.  * Usage: xshowbitmap
  14.  *   -s sorts the bitmaps in order of size (largest first)
  15.  *   -v verbose mode for when input is redirected to stdin.
  16.  *   -vw width of viewport window
  17.  *   -vh height of viewport window
  18.  *   -fg foreground_color
  19.  *   -bg background_color
  20.  *   -rows N (cannot be used with -cols)
  21.  *   -cols N (cannot be used with -rows)
  22.  *   -fn font  (bitmap filename is printed with bitmap in "font")
  23.  *   -bw max-width  (bitmaps larger than this width are excluded; default 64)
  24.  *   -bh max-height  (bitmaps larger than this height are excluded; default 64)
  25.  *   - indicates to read from stdin.  Piping doesn't require the '-'
  26.  *     argument.  With no arguments, xshowfonts reads from stdin anyway.
  27.  *
  28.  * Example:
  29.  *  xshowfont /usr/include/X11/bitmaps/*
  30.  *
  31.  * compile: (triple click and paste next line)
  32.      cc -O -s xshowbitmap.c -lXaw -lXt -lXmu -lX11 -o xshowbitmap
  33.  */
  34.  
  35. #include <stdio.h>
  36. #include <X11/Intrinsic.h>
  37. #include <X11/StringDefs.h>
  38. #include <X11/Xaw/Label.h>
  39. #include <X11/Xaw/Viewport.h>
  40.  
  41. struct _bitmap {
  42.     char *name;
  43.     int len; /* strlen(name) */
  44.     unsigned int width, height;
  45.     Pixmap bitmap;
  46. };
  47. typedef struct _bitmap Bitmap;
  48.  
  49. struct _resrcs {
  50.     int sort;
  51.     int verbose;
  52.     int max_width, max_height;
  53.     Pixel fg, bg;
  54.     XFontStruct *font;
  55.     int view_width, view_height;
  56.     int rows, cols;
  57. } Resrcs;
  58.  
  59. static XtResource resources[] = {
  60.     { "sort", "Sort", XtRBoolean, sizeof (int),
  61.     XtOffsetOf(struct _resrcs,sort), XtRImmediate, False },
  62.     { "verbose", "Verbose", XtRBoolean, sizeof (int),
  63.     XtOffsetOf(struct _resrcs,verbose), XtRImmediate, False },
  64.     { "bitmapWidth", "BitmapWidth", XtRInt, sizeof (int),
  65.     XtOffsetOf(struct _resrcs,max_width), XtRImmediate, (char *)64 },
  66.     { "bitmapHeight", "BitmapHeight", XtRInt, sizeof (int),
  67.     XtOffsetOf(struct _resrcs,max_height), XtRImmediate, (char *)64 },
  68.     { XtNfont, XtCFont, XtRFontStruct, sizeof (XFontStruct *),
  69.     XtOffsetOf(struct _resrcs,font), XtRString, XtDefaultFont },
  70.     { XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel),
  71.     XtOffsetOf(struct _resrcs,fg), XtRString, XtDefaultForeground },
  72.     { XtNforeground, XtCBackground, XtRPixel, sizeof (Pixel),
  73.     XtOffsetOf(struct _resrcs,bg), XtRString, XtDefaultBackground },
  74.     { "view-width", "View-width", XtRInt, sizeof (int),
  75.     XtOffsetOf(struct _resrcs,view_width), XtRImmediate, (char *)500 },
  76.     { "view-height", "View-height", XtRInt, sizeof (int),
  77.     XtOffsetOf(struct _resrcs,view_height), XtRImmediate, (char *)300 },
  78.     { "rows", "Rows", XtRInt, sizeof (int),
  79.     XtOffsetOf(struct _resrcs,rows), XtRImmediate, (char *)0 },
  80.     { "cols", "Cols", XtRInt, sizeof (int),
  81.     XtOffsetOf(struct _resrcs,cols), XtRImmediate, (char *)0 },
  82. };
  83.  
  84. static XrmOptionDescRec options[] = {
  85.     { "-sort", "sort", XrmoptionNoArg, "True" },
  86.     { "-v", "verbose", XrmoptionNoArg, "True" },
  87.     { "-fn", "font", XrmoptionSepArg, NULL },
  88.     { "-fg", "foreground", XrmoptionSepArg, NULL },
  89.     { "-bg", "background", XrmoptionSepArg, NULL },
  90.     { "-vw", "view-width", XrmoptionSepArg, NULL },
  91.     { "-vh", "view-height", XrmoptionSepArg, NULL },
  92.     { "-rows", "rows", XrmoptionSepArg, NULL },
  93.     { "-cols", "cols", XrmoptionSepArg, NULL },
  94.     { "-bw", "bitmapWidth", XrmoptionSepArg, NULL },
  95.     { "-bh", "bitmapHeight", XrmoptionSepArg, NULL },
  96.     { "-bitmap_width", "bitmapWidth", XrmoptionSepArg, NULL },
  97.     { "-bitmap_height", "bitmapHeight", XrmoptionSepArg, NULL },
  98. };
  99.  
  100. size_cmp(b1, b2)
  101. Bitmap *b1, *b2;
  102. {
  103.     int n = (int)(b1->width * b1->height) - (int)(b2->width * b2->height);
  104.     if (n)
  105.     return n;
  106.     return strcmp(b1->name, b2->name);
  107. }
  108.  
  109. /* get the integer square root of n */
  110. int_sqrt(n)
  111. register int n;
  112. {
  113.     register int i, s = 0, t;
  114.     for (i = 15; i >= 0; i--) {
  115.     t = (s | (1 << i));
  116.     if (t * t <= n)
  117.         s = t;
  118.     }
  119.     return s;
  120. }
  121.  
  122. main(argc, argv)
  123. int argc;
  124. char *argv[];
  125. {
  126.     extern char *strcpy();
  127.     Widget topLevel, vp;
  128.     Bitmap *list = (Bitmap *)NULL;
  129.     char buf[128], *p;
  130.     Pixmap pixmap;
  131.     XFontStruct *font;
  132.     GC gc;
  133.     Display *dpy;
  134.     int istty = isatty(0), redirect = !istty, i = 0, total = 0;
  135.     unsigned int cell_width = 0, cell_height = 0, bitmap_error;
  136.     int dummy1, dummy2;
  137.  
  138.     topLevel = XtInitialize(argv[0], argv[0], options, XtNumber(options),
  139.     &argc, argv);
  140.     dpy = XtDisplay(topLevel);
  141.  
  142.     XtGetApplicationResources(topLevel, &Resrcs,
  143.     resources, XtNumber(resources), NULL, 0);
  144.  
  145.     if (Resrcs.rows && Resrcs.cols)
  146.     XtError("You can't specify both rows *and* columns.");
  147.  
  148.     font = Resrcs.font;
  149.  
  150.     if (!argv[1] || !strcmp(argv[1], "-")) {
  151.     printf("Loading bitmap names from input. ");
  152.     if (istty) {
  153.         puts("End with EOF or .");
  154.         redirect++;
  155.     } else
  156.         puts("Use -v to view bitmap names being loaded.");
  157.     } else if (!istty && strcmp(argv[1], "-"))
  158.     printf("%s: either use pipes or specify bitmap names -- not both.\n",
  159.         argv[0]), exit(1);
  160.     while (*++argv || redirect) {
  161.     if (!redirect)
  162.         if (!strcmp(*argv, "-"))
  163.         redirect++;
  164.         else
  165.         strcpy(buf, *argv);
  166.     if (redirect) {
  167.         if (istty)
  168.         printf("Bitmap file: "), fflush(stdout);
  169.         if (!fgets(buf, sizeof buf, stdin) || !strcmp(buf, ".\n"))
  170.         break;
  171.         buf[strlen(buf)-1] = 0;
  172.     }
  173.     if (!buf[0])
  174.         continue;
  175.     if (istty || Resrcs.verbose)
  176.         printf("Loading \"%s\"...", buf), fflush(stdout);
  177.     if (i == total) {
  178.         total += 10;
  179.         if (!(list = (Bitmap *)XtRealloc(list, total * sizeof (Bitmap))))
  180.         XtError("Not enough memory for bitmap data");
  181.     }
  182.     if ((bitmap_error = XReadBitmapFile(dpy, DefaultRootWindow(dpy), buf,
  183.         &list[i].width, &list[i].height, &list[i].bitmap,
  184.         &dummy1, &dummy2)) == BitmapSuccess) {
  185.         if (p = rindex(buf, '/'))
  186.         p++;
  187.         else
  188.         p = buf;
  189.         if (Resrcs.max_height && list[i].height > Resrcs.max_height ||
  190.         Resrcs.max_width && list[i].width > Resrcs.max_width) {
  191.         printf("%s: bitmap too big\n", p);
  192.         XFreePixmap(dpy, list[i].bitmap);
  193.         continue;
  194.         }
  195.         list[i].len = strlen(p);
  196.         list[i].name = strcpy(XtMalloc(list[i].len + 1), p);
  197.         if (istty || Resrcs.verbose)
  198.         printf("size: %dx%d\n", list[i].width, list[i].height);
  199.         i++;
  200.     } else {
  201.         printf("couldn't load bitmap: ");
  202.         if (!istty && !Resrcs.verbose)
  203.         printf("\"%s\": ", buf);
  204.         switch (bitmap_error) {
  205.         case BitmapOpenFailed : puts("open failed."); break;
  206.         case BitmapFileInvalid : puts("bad file format."); break;
  207.         case BitmapNoMemory : puts("no enough memory."); break;
  208.         }
  209.     }
  210.     }
  211.     if ((total = i) == 0)
  212.     puts("No bitmaps?!"), exit(1);
  213.     printf("Total bitmaps loaded: %d\n", total);
  214.     if (Resrcs.sort) {
  215.     printf("Sorting bitmaps..."), fflush(stdout);
  216.     qsort(list, total, sizeof (Bitmap), size_cmp);
  217.     putchar('\n');
  218.     }
  219.     /* calculate size for pixmap by getting the dimensions of each bitmap */
  220.     printf("Calculating sizes for pixmap..."), fflush(stdout);
  221.     for (i = 0; i < total; i++) {
  222.     if (list[i].width > cell_width)
  223.         cell_width = list[i].width;
  224.     if (list[i].height > cell_height)
  225.         cell_height = list[i].height;
  226.     dummy1 = XTextWidth(font, list[i].name, list[i].len);
  227.     if (dummy1 > cell_width)
  228.         cell_width = dummy1;
  229.     }
  230.     cell_height += 6 + font->ascent + font->descent;
  231.     cell_width += 6;
  232.     if (!Resrcs.rows && !Resrcs.cols) {
  233.     Resrcs.cols = int_sqrt(total);
  234.     Resrcs.rows = (total + Resrcs.cols-1)/Resrcs.cols;
  235.     } else if (Resrcs.rows)
  236.     /* user specified rows -- figure out columns */
  237.     Resrcs.cols = (total + Resrcs.rows-1)/Resrcs.rows;
  238.     else
  239.     /* user specified cols -- figure out rows */
  240.     Resrcs.rows = (total + Resrcs.cols-1)/Resrcs.cols;
  241.  
  242.     /* Create pixmap & GC */
  243.     printf("Creating pixmap of size %dx%d (%d rows, %d cols)\n",
  244.     Resrcs.cols * cell_width, Resrcs.rows * cell_height,
  245.     Resrcs.rows, Resrcs.cols);
  246.     if (!(pixmap = XCreatePixmap(dpy, DefaultRootWindow(dpy),
  247.     Resrcs.cols * cell_width + 1, Resrcs.rows * cell_height + 1,
  248.     DefaultDepth(dpy, DefaultScreen(dpy)))))
  249.     XtError("Can't Create pixmap");
  250.     if (!(gc = XCreateGC(dpy, pixmap, NULL, 0)))
  251.     XtError("Can't create gc");
  252.     XSetForeground(dpy, gc, Resrcs.bg);
  253.     XFillRectangle(dpy, pixmap, gc, 0, 0,
  254.     Resrcs.cols * cell_width, Resrcs.rows * cell_height);
  255.     XSetForeground(dpy, gc, Resrcs.fg);
  256.     XSetBackground(dpy, gc, Resrcs.bg);
  257.     XSetFont(dpy, gc, font->fid);
  258.     for (dummy1 = 0; dummy1 <= Resrcs.rows * cell_height; dummy1 += cell_height)
  259.     XDrawLine(dpy, pixmap, gc, 0, dummy1, Resrcs.cols * cell_width, dummy1);
  260.     for (dummy1 = 0; dummy1 <= Resrcs.cols * cell_width; dummy1 += cell_width)
  261.     XDrawLine(dpy, pixmap, gc, dummy1, 0, dummy1, Resrcs.rows*cell_height);
  262.     for (i = 0; i < total; i++) {
  263.     int x = cell_width * (i % Resrcs.cols);
  264.     int y = cell_height * (i / Resrcs.cols);
  265.     XDrawString(dpy, pixmap, gc, x+5, y+font->ascent,
  266.         list[i].name, list[i].len);
  267.     if (DefaultDepth(dpy, DefaultScreen(dpy)) > 1)
  268.         XCopyPlane(dpy, list[i].bitmap, pixmap, gc,
  269.         0, 0, list[i].width, list[i].height,
  270.         x+5, y + font->ascent + font->descent, 1L);
  271.     else
  272.         XCopyArea(dpy, list[i].bitmap, pixmap, gc,
  273.         0, 0, list[i].width, list[i].height,
  274.         x+5, y + font->ascent + font->descent);
  275.     XFreePixmap(dpy, list[i].bitmap);
  276.     XtFree(list[i].name);
  277.     }
  278.     vp = XtVaCreateManagedWidget("viewport", viewportWidgetClass, topLevel,
  279.     XtNallowHoriz,    True,
  280.     XtNallowVert,    True,
  281.     XtNwidth,    Resrcs.view_width,
  282.     XtNheight,    Resrcs.view_height,
  283.     NULL);
  284.     XtVaCreateManagedWidget("_foo", labelWidgetClass, vp,
  285.     XtNbitmap,    pixmap,
  286.     NULL);
  287.  
  288.     XtRealizeWidget(topLevel);
  289.     XtMainLoop();
  290. }
  291.  
  292.