28.2 A Bitmap Display Utility
The xshowbitmap program is a useful utility for reviewing a group of bitmap files. The filenames for the bitmaps can
be specified on the command line, sent through a pipe, or typed into stdin. All of the bitmaps are drawn into a
pixmap, which is rendered into a DrawingArea widget. The DrawingArea is used as the work window for a
ScrolledWindow, so that we can demonstrate application−defined scrolling for the Motif ScrolledWindow. The
bitmaps are displayed in an equal number of rows and columns if possible. Alternatively, you can specify either the
number of rows or the number of columns using the −rows or −columns command−line option, respectively.
The example in the source code demonstrates the use of Xt mechanisms for adding command−line options and
application−level resources in an application. For an explanation of these Xt features, see Volume Four, X Toolkit
Intrinsics Programming Manual. For details on the Xlib functions for reading and manipulating bitmaps, see
Volume One, Xlib Programming Manual. XtSetLanguageProc() is only available in X11R5; there is no
corresponding function in X11R4.
/* 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.
*
* Usage: xshowbitmap
* −s sorts the bitmaps in order of size with largest first
* −v verbose mode for when input is redirected to stdin
* −w width of viewport window
* −h height of viewport window
* −fg foreground color
* −bg background color
* −label labels each bitmap with its corresponding filename; default
* −nolabel doesn't label each bitmap with its filename
* −grid N line width for grid between bitmaps; defaults to 1
* −rows N number of rows; cannot be used with −cols
* −cols N number of columns; cannot be used with −rows
* −fn font font for bitmap filenames
* −bw max−width excludes bitmaps larger than this width; defaults to 64
* −bh max−height excludes bitmaps larger than this height; defaults to 64
* − indicates to read from stdin; piping doesn't require the '−'
* argument
* no arguments reads from stdin
*
* Example usage:
* xshowbitmaps /usr/include/X11/bitmaps/*
*/
#include <stdio.h>
#include <X11/Xos.h>
#include <Xm/ScrolledW.h>
#include <Xm/DrawingA.h>
#include <Xm/ScrollBar.h>
#ifdef max
#undef max
#endif
#define max(a,b) ((int)(a)>(int)(b)?(int)(a):(int)(b))
#define min(a,b) ((int)(a)<(int)(b)?(int)(a):(int)(b))
typedef struct {
char *name;
int len;
28 Additional Example Programs 28.2 A Bitmap Display Utility
750
unsigned int width, height;
Pixmap bitmap;
} Bitmap;
/* Resrcs is an object that contains global variables that we want the
* user to be able to initialize through resources or command line options.
* XtAppInitialize() initializes the fields in this data structure to values
* indicated by the XrmOptionsDescRec structure defined later.
*/
struct _resrcs {
Boolean sort; /* sort the bitmaps */
Boolean verbose; /* loading bitmaps verbosely */
Boolean label_bitmap; /* whether to label bitmaps */
int max_width, max_height; /* largest allowable bitmap */
unsigned int grid; /* line width between bitmaps */
Pixel fg, bg; /* colors of bitmaps */
XFontStruct *font; /* font for bitmap labels */
Dimension view_width, view_height; /* initial clip window size */
int rows, cols; /* forcefully set #rows/cols */
} Resrcs;
/* .Xdefaults or app−defaults resources. The last field in each structure
* is used as the default values for the field in the Resrcs struct above.
*/
static XtResource resources[] = {
{ "sort", "Sort", XmRBoolean, sizeof (Boolean),
XtOffsetOf (struct _resrcs, sort), XmRImmediate, False },
{ "verbose", "Verbose", XmRBoolean, sizeof (Boolean),
XtOffsetOf (struct _resrcs,verbose), XmRImmediate, False },
{ "labelBitmap", "LabelBitmap", XmRBoolean, sizeof (Boolean),
XtOffsetOf (struct _resrcs, label_bitmap), XmRImmediate,
(char *) True },
{ "grid", "Grid", XmRInt, sizeof (int),
XtOffsetOf (struct _resrcs, grid), XmRImmediate, (char *) 1 },
{ "bitmapWidth", "BitmapWidth", XmRInt, sizeof (int),
XtOffsetOf (struct _resrcs, max_width), XmRImmediate, (char *) 64 },
{ "bitmapHeight", "BitmapHeight", XmRInt, sizeof (int),
XtOffsetOf (struct _resrcs, max_height), XmRImmediate, (char *) 64 },
{ XmNfont, XmCFont, XmRFontStruct, sizeof (XFontStruct *),
XtOffsetOf (struct _resrcs, font), XmRString, XtDefaultFont },
{ XmNforeground, XmCForeground, XmRPixel, sizeof (Pixel),
XtOffsetOf (struct _resrcs, fg), XmRString, XtDefaultForeground },
{ XmNbackground, XmCBackground, XmRPixel, sizeof (Pixel),
XtOffsetOf (struct _resrcs, bg), XmRString, XtDefaultBackground },
{ "view−width", "View−width", XmRDimension, sizeof (Dimension),
XtOffsetOf (struct _resrcs, view_width), XmRImmediate,
(char *) 500 },
{ "view−height", "View−height", XmRDimension, sizeof (Dimension),
XtOffsetOf (struct _resrcs, view_height), XmRImmediate,
(char *) 300 },
{ "rows", "Rows", XmRInt, sizeof (int),
XtOffsetOf (struct _resrcs, rows), XmRImmediate, 0 },
{ "cols", "Cols", XmRInt, sizeof (int),
XtOffsetOf (struct _resrcs, cols), XmRImmediate, 0 },
};
/* If the following command line args (1st field) are found, set the
* associated resource values (2nd field) to the given value (4th field).
*/
static XrmOptionDescRec options[] = {
{ "−sort", "sort", XrmoptionNoArg, "True" },
28 Additional Example Programs 28.2 A Bitmap Display Utility
751
{ "−v", "verbose", XrmoptionNoArg, "True" },
{ "−fn", "font", XrmoptionSepArg, NULL },
{ "−fg", "foreground", XrmoptionSepArg, NULL },
{ "−bg", "background", XrmoptionSepArg, NULL },
{ "−w", "view−width", XrmoptionSepArg, NULL },
{ "−h", "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 },
{ "−label", "labelBitmap", XrmoptionNoArg, "True" },
{ "−nolabel", "labelBitmap", XrmoptionNoArg, "False" },
{ "−grid", "grid", XrmoptionSepArg, NULL },
};
/* size_cmp() −− used by qsort to sort bitmaps into alphabetical order
* This is used when the "sort" resource is true or when −sort is given.
*/
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);
}
/* int_sqrt() −− get the integer square root of n. Used to put the
* bitmaps in an equal number of rows and colums.
*/
int_sqrt(n)
register int n;
{
register int i, s = 0, t;
for (i = 15; i >= 0; i−−) {
t = (s | (1L << i));
if (t * t <= n)
s = t;
}
return s;
}
/* global variables that are not changable thru resources or command
* line options.
*/
Widget drawing_a, vsb, hsb;
Pixmap pixmap; /* used the as image for Label widget */
GC gc;
Display *dpy;
unsigned int cell_width, cell_height;
unsigned int pix_hoffset, pix_voffset, sw_hoffset, sw_voffset;
void redraw();
main(argc, argv)
int argc;
char *argv[];
{
extern char *strcpy();
XtAppContext app;
28 Additional Example Programs 28.2 A Bitmap Display Utility
752
Widget toplevel, scrolled_w;
Bitmap *list = (Bitmap *) NULL;
char buf[128], *p;
XFontStruct *font;
int istty = isatty(0), redirect = !istty, i = 0, total = 0;
unsigned int bitmap_error;
int j, k;
void scrolled(), expose_resize();
XtSetLanguageProc (NULL, NULL, NULL);
toplevel = XtAppInitialize (&app, "XShowbitmap",
options, XtNumber (options), &argc, argv, NULL, NULL, 0);
dpy = XtDisplay (toplevel);
XtGetApplicationResources (toplevel, &Resrcs,
resources, XtNumber (resources), NULL, 0);
if (Resrcs.rows && Resrcs.cols)
XtWarning ("You can't specify both rows *and* columns.");
font = Resrcs.font;
/* check to see if we have to load the bitmaps from stdin */
if (!argv[1] || !strcmp(argv[1], "−")) {
printf ("Loading bitmap names from standard 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.0,
argv[0]);
exit (1);
}
/* Now, load the bitmap file names */
while (*++argv || redirect) {
if (!redirect)
/* this may appear at the end of a list of filenames */
if (!strcmp (*argv, "−"))
redirect++; /* switch to stdin prompting */
else
(void) strcpy (buf, *argv);
if (redirect) {
if (istty)
printf ("Bitmap file: "), fflush(stdout);
if (!fgets (buf, sizeof buf − 1, stdin) || !strcmp (buf, ".0))
break;
buf[strlen (buf) − 1] = 0; /* plug a null at the newline */
}
if (!buf[0])
continue;
if (Resrcs.verbose)
printf ("Loading
if (i == total) {
total += 10; /* allocate bitmap structures in groups of 10 */
if (!(list = (Bitmap *) XtRealloc
28 Additional Example Programs 28.2 A Bitmap Display Utility
753
(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,
&j, &k)) == 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 big0, p);
XFreePixmap (dpy, list[i].bitmap);
continue;
}
list[i].len = strlen (p);
list[i].name = strcpy (XtMalloc (list[i].len + 1), p);
if (Resrcs.verbose)
printf ("size: %dx%d0, list[i].width, list[i].height);
i++;
}
else {
printf ("Couldn't load bitmap: ");
if (!istty && !Resrcs.verbose)
printf("
switch (bitmap_error) {
case BitmapOpenFailed : puts ("open failed."); break;
case BitmapFileInvalid : puts ("bad file format."); break;
case BitmapNoMemory : puts ("not enough memory."); break;
}
}
}
if ((total = i) == 0) {
puts ("couldn't load any bitmaps.");
exit (1);
}
printf ("Total bitmaps loaded: %d0, total);
if (Resrcs.sort) {
printf ("Sorting bitmaps...");
fflush (stdout);
qsort (list, total, sizeof (Bitmap), size_cmp);
putchar ('0);
}
/* 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;
if (Resrcs.label_bitmap && (j = XTextWidth
(font, list[i].name, list[i].len)) > cell_width)
cell_width = j;
}
/* Compensate for vertical font height if label_bitmap is true.
* Add value of grid line weight and a 6 pixel padding for aesthetics.
*/
28 Additional Example Programs 28.2 A Bitmap Display Utility
754
Get Volume 6A: Motif Programming Manual now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.