home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
x
/
volume6
/
xsbm
/
part01
/
xshowbitmap.c
< prev
Wrap
C/C++ Source or Header
|
1993-04-28
|
10KB
|
292 lines
/* Dan Heller <argv@sun.com>
*
* xshowbitmap.c -
* Displays a set of bitmaps specified on the command line, from
* a pipe, or typed into stdin. Bitmaps must be specified as file names.
* All the bitmaps are drawn into one large pixmap which is used as the
* XtNbitmap for a Label Widget. This label widget is placed in a viewport
* widget so you can scroll around in it. The bitmaps are displayed in
* an equal number of rows and columns if possible. You may override this
* by specify *either* the number or rows (-rows N) or the number of
* columns (-cols) to use. You can't specify both.
*
* Usage: xshowbitmap
* -s sorts the bitmaps in order of size (largest first)
* -v verbose mode for when input is redirected to stdin.
* -vw width of viewport window
* -vh height of viewport window
* -fg foreground_color
* -bg background_color
* -rows N (cannot be used with -cols)
* -cols N (cannot be used with -rows)
* -fn font (bitmap filename is printed with bitmap in "font")
* -bw max-width (bitmaps larger than this width are excluded; default 64)
* -bh max-height (bitmaps larger than this height are excluded; default 64)
* - indicates to read from stdin. Piping doesn't require the '-'
* argument. With no arguments, xshowfonts reads from stdin anyway.
*
* Example:
* xshowfont /usr/include/X11/bitmaps/*
*
* compile: (triple click and paste next line)
cc -O -s xshowbitmap.c -lXaw -lXt -lXmu -lX11 -o xshowbitmap
*/
#include <stdio.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Xaw/Label.h>
#include <X11/Xaw/Viewport.h>
struct _bitmap {
char *name;
int len; /* strlen(name) */
unsigned int width, height;
Pixmap bitmap;
};
typedef struct _bitmap Bitmap;
struct _resrcs {
int sort;
int verbose;
int max_width, max_height;
Pixel fg, bg;
XFontStruct *font;
int view_width, view_height;
int rows, cols;
} Resrcs;
static XtResource resources[] = {
{ "sort", "Sort", XtRBoolean, sizeof (int),
XtOffsetOf(struct _resrcs,sort), XtRImmediate, False },
{ "verbose", "Verbose", XtRBoolean, sizeof (int),
XtOffsetOf(struct _resrcs,verbose), XtRImmediate, False },
{ "bitmapWidth", "BitmapWidth", XtRInt, sizeof (int),
XtOffsetOf(struct _resrcs,max_width), XtRImmediate, (char *)64 },
{ "bitmapHeight", "BitmapHeight", XtRInt, sizeof (int),
XtOffsetOf(struct _resrcs,max_height), XtRImmediate, (char *)64 },
{ XtNfont, XtCFont, XtRFontStruct, sizeof (XFontStruct *),
XtOffsetOf(struct _resrcs,font), XtRString, XtDefaultFont },
{ XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel),
XtOffsetOf(struct _resrcs,fg), XtRString, XtDefaultForeground },
{ XtNforeground, XtCBackground, XtRPixel, sizeof (Pixel),
XtOffsetOf(struct _resrcs,bg), XtRString, XtDefaultBackground },
{ "view-width", "View-width", XtRInt, sizeof (int),
XtOffsetOf(struct _resrcs,view_width), XtRImmediate, (char *)500 },
{ "view-height", "View-height", XtRInt, sizeof (int),
XtOffsetOf(struct _resrcs,view_height), XtRImmediate, (char *)300 },
{ "rows", "Rows", XtRInt, sizeof (int),
XtOffsetOf(struct _resrcs,rows), XtRImmediate, (char *)0 },
{ "cols", "Cols", XtRInt, sizeof (int),
XtOffsetOf(struct _resrcs,cols), XtRImmediate, (char *)0 },
};
static XrmOptionDescRec options[] = {
{ "-sort", "sort", XrmoptionNoArg, "True" },
{ "-v", "verbose", XrmoptionNoArg, "True" },
{ "-fn", "font", XrmoptionSepArg, NULL },
{ "-fg", "foreground", XrmoptionSepArg, NULL },
{ "-bg", "background", XrmoptionSepArg, NULL },
{ "-vw", "view-width", XrmoptionSepArg, NULL },
{ "-vh", "view-height", XrmoptionSepArg, NULL },
{ "-rows", "rows", XrmoptionSepArg, NULL },
{ "-cols", "cols", XrmoptionSepArg, NULL },
{ "-bw", "bitmapWidth", XrmoptionSepArg, NULL },
{ "-bh", "bitmapHeight", XrmoptionSepArg, NULL },
{ "-bitmap_width", "bitmapWidth", XrmoptionSepArg, NULL },
{ "-bitmap_height", "bitmapHeight", XrmoptionSepArg, NULL },
};
size_cmp(b1, b2)
Bitmap *b1, *b2;
{
int n = (int)(b1->width * b1->height) - (int)(b2->width * b2->height);
if (n)
return n;
return strcmp(b1->name, b2->name);
}
/* get the integer square root of n */
int_sqrt(n)
register int n;
{
register int i, s = 0, t;
for (i = 15; i >= 0; i--) {
t = (s | (1 << i));
if (t * t <= n)
s = t;
}
return s;
}
main(argc, argv)
int argc;
char *argv[];
{
extern char *strcpy();
Widget topLevel, vp;
Bitmap *list = (Bitmap *)NULL;
char buf[128], *p;
Pixmap pixmap;
XFontStruct *font;
GC gc;
Display *dpy;
int istty = isatty(0), redirect = !istty, i = 0, total = 0;
unsigned int cell_width = 0, cell_height = 0, bitmap_error;
int dummy1, dummy2;
topLevel = XtInitialize(argv[0], argv[0], options, XtNumber(options),
&argc, argv);
dpy = XtDisplay(topLevel);
XtGetApplicationResources(topLevel, &Resrcs,
resources, XtNumber(resources), NULL, 0);
if (Resrcs.rows && Resrcs.cols)
XtError("You can't specify both rows *and* columns.");
font = Resrcs.font;
if (!argv[1] || !strcmp(argv[1], "-")) {
printf("Loading bitmap names from input. ");
if (istty) {
puts("End with EOF or .");
redirect++;
} else
puts("Use -v to view bitmap names being loaded.");
} else if (!istty && strcmp(argv[1], "-"))
printf("%s: either use pipes or specify bitmap names -- not both.\n",
argv[0]), exit(1);
while (*++argv || redirect) {
if (!redirect)
if (!strcmp(*argv, "-"))
redirect++;
else
strcpy(buf, *argv);
if (redirect) {
if (istty)
printf("Bitmap file: "), fflush(stdout);
if (!fgets(buf, sizeof buf, stdin) || !strcmp(buf, ".\n"))
break;
buf[strlen(buf)-1] = 0;
}
if (!buf[0])
continue;
if (istty || Resrcs.verbose)
printf("Loading \"%s\"...", buf), fflush(stdout);
if (i == total) {
total += 10;
if (!(list = (Bitmap *)XtRealloc(list, total * sizeof (Bitmap))))
XtError("Not enough memory for bitmap data");
}
if ((bitmap_error = XReadBitmapFile(dpy, DefaultRootWindow(dpy), buf,
&list[i].width, &list[i].height, &list[i].bitmap,
&dummy1, &dummy2)) == BitmapSuccess) {
if (p = rindex(buf, '/'))
p++;
else
p = buf;
if (Resrcs.max_height && list[i].height > Resrcs.max_height ||
Resrcs.max_width && list[i].width > Resrcs.max_width) {
printf("%s: bitmap too big\n", p);
XFreePixmap(dpy, list[i].bitmap);
continue;
}
list[i].len = strlen(p);
list[i].name = strcpy(XtMalloc(list[i].len + 1), p);
if (istty || Resrcs.verbose)
printf("size: %dx%d\n", list[i].width, list[i].height);
i++;
} else {
printf("couldn't load bitmap: ");
if (!istty && !Resrcs.verbose)
printf("\"%s\": ", buf);
switch (bitmap_error) {
case BitmapOpenFailed : puts("open failed."); break;
case BitmapFileInvalid : puts("bad file format."); break;
case BitmapNoMemory : puts("no enough memory."); break;
}
}
}
if ((total = i) == 0)
puts("No bitmaps?!"), exit(1);
printf("Total bitmaps loaded: %d\n", total);
if (Resrcs.sort) {
printf("Sorting bitmaps..."), fflush(stdout);
qsort(list, total, sizeof (Bitmap), size_cmp);
putchar('\n');
}
/* calculate size for pixmap by getting the dimensions of each bitmap */
printf("Calculating sizes for pixmap..."), fflush(stdout);
for (i = 0; i < total; i++) {
if (list[i].width > cell_width)
cell_width = list[i].width;
if (list[i].height > cell_height)
cell_height = list[i].height;
dummy1 = XTextWidth(font, list[i].name, list[i].len);
if (dummy1 > cell_width)
cell_width = dummy1;
}
cell_height += 6 + font->ascent + font->descent;
cell_width += 6;
if (!Resrcs.rows && !Resrcs.cols) {
Resrcs.cols = int_sqrt(total);
Resrcs.rows = (total + Resrcs.cols-1)/Resrcs.cols;
} else if (Resrcs.rows)
/* user specified rows -- figure out columns */
Resrcs.cols = (total + Resrcs.rows-1)/Resrcs.rows;
else
/* user specified cols -- figure out rows */
Resrcs.rows = (total + Resrcs.cols-1)/Resrcs.cols;
/* Create pixmap & GC */
printf("Creating pixmap of size %dx%d (%d rows, %d cols)\n",
Resrcs.cols * cell_width, Resrcs.rows * cell_height,
Resrcs.rows, Resrcs.cols);
if (!(pixmap = XCreatePixmap(dpy, DefaultRootWindow(dpy),
Resrcs.cols * cell_width + 1, Resrcs.rows * cell_height + 1,
DefaultDepth(dpy, DefaultScreen(dpy)))))
XtError("Can't Create pixmap");
if (!(gc = XCreateGC(dpy, pixmap, NULL, 0)))
XtError("Can't create gc");
XSetForeground(dpy, gc, Resrcs.bg);
XFillRectangle(dpy, pixmap, gc, 0, 0,
Resrcs.cols * cell_width, Resrcs.rows * cell_height);
XSetForeground(dpy, gc, Resrcs.fg);
XSetBackground(dpy, gc, Resrcs.bg);
XSetFont(dpy, gc, font->fid);
for (dummy1 = 0; dummy1 <= Resrcs.rows * cell_height; dummy1 += cell_height)
XDrawLine(dpy, pixmap, gc, 0, dummy1, Resrcs.cols * cell_width, dummy1);
for (dummy1 = 0; dummy1 <= Resrcs.cols * cell_width; dummy1 += cell_width)
XDrawLine(dpy, pixmap, gc, dummy1, 0, dummy1, Resrcs.rows*cell_height);
for (i = 0; i < total; i++) {
int x = cell_width * (i % Resrcs.cols);
int y = cell_height * (i / Resrcs.cols);
XDrawString(dpy, pixmap, gc, x+5, y+font->ascent,
list[i].name, list[i].len);
if (DefaultDepth(dpy, DefaultScreen(dpy)) > 1)
XCopyPlane(dpy, list[i].bitmap, pixmap, gc,
0, 0, list[i].width, list[i].height,
x+5, y + font->ascent + font->descent, 1L);
else
XCopyArea(dpy, list[i].bitmap, pixmap, gc,
0, 0, list[i].width, list[i].height,
x+5, y + font->ascent + font->descent);
XFreePixmap(dpy, list[i].bitmap);
XtFree(list[i].name);
}
vp = XtVaCreateManagedWidget("viewport", viewportWidgetClass, topLevel,
XtNallowHoriz, True,
XtNallowVert, True,
XtNwidth, Resrcs.view_width,
XtNheight, Resrcs.view_height,
NULL);
XtVaCreateManagedWidget("_foo", labelWidgetClass, vp,
XtNbitmap, pixmap,
NULL);
XtRealizeWidget(topLevel);
XtMainLoop();
}