summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dsimple.c523
-rw-r--r--dsimple.h81
-rw-r--r--xlsfonts.c621
-rw-r--r--xlsfonts.man102
4 files changed, 1327 insertions, 0 deletions
diff --git a/dsimple.c b/dsimple.c
new file mode 100644
index 0000000..210d121
--- /dev/null
+++ b/dsimple.c
@@ -0,0 +1,523 @@
+/* $Xorg: dsimple.c,v 1.4 2001/02/09 02:05:54 xorgcvs Exp $ */
+/*
+
+Copyright 1993, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+#include <X11/Xos.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/cursorfont.h>
+#include <stdio.h>
+/*
+ * Other_stuff.h: Definitions of routines in other_stuff.
+ *
+ * Written by Mark Lillibridge. Last updated 7/1/87
+ */
+
+unsigned long Resolve_Color();
+Pixmap Bitmap_To_Pixmap();
+Window Select_Window();
+void out();
+void blip();
+Window Window_With_Name();
+void Fatal_Error();
+
+/*
+ * Just_display: A group of routines designed to make the writting of simple
+ * X11 applications which open a display but do not open
+ * any windows much faster and easier. Unless a routine says
+ * otherwise, it may be assumed to require program_name, dpy,
+ * and screen already defined on entry.
+ *
+ * Written by Mark Lillibridge. Last updated 7/1/87
+ */
+
+
+/* This stuff is defined in the calling program by just_display.h */
+extern char *program_name;
+extern Display *dpy;
+extern int screen;
+
+
+/*
+ * Malloc: like malloc but handles out of memory using Fatal_Error.
+ */
+char *Malloc(size)
+ unsigned size;
+{
+ char *data, *malloc();
+
+ if (!(data = malloc(size)))
+ Fatal_Error("Out of memory!");
+
+ return(data);
+}
+
+
+/*
+ * Realloc: like Malloc except for realloc, handles NULL using Malloc.
+ */
+char *Realloc(ptr, size)
+ char *ptr;
+ int size;
+{
+ char *new_ptr, *realloc();
+
+ if (!ptr)
+ return(Malloc(size));
+
+ if (!(new_ptr = realloc(ptr, size)))
+ Fatal_Error("Out of memory!");
+
+ return(new_ptr);
+}
+
+
+/*
+ * Get_Display_Name (argc, argv) Look for -display, -d, or host:dpy (obselete)
+ * If found, remove it from command line. Don't go past a lone -.
+ */
+char *Get_Display_Name(pargc, argv)
+ int *pargc; /* MODIFIED */
+ char **argv; /* MODIFIED */
+{
+ int argc = *pargc;
+ char **pargv = argv+1;
+ char *displayname = NULL;
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ char *arg = argv[i];
+
+ if (!strcmp (arg, "-display") || !strcmp (arg, "-d")) {
+ if (++i >= argc) usage ();
+
+ displayname = argv[i];
+ *pargc -= 2;
+ continue;
+ }
+ if (!strcmp(arg,"-")) {
+ while (i<argc)
+ *pargv++ = argv[i++];
+ break;
+ }
+ *pargv++ = arg;
+ }
+
+ *pargv = NULL;
+ return (displayname);
+}
+
+
+/*
+ * Open_Display: Routine to open a display with correct error handling.
+ * Does not require dpy or screen defined on entry.
+ */
+Display *Open_Display(display_name)
+char *display_name;
+{
+ Display *d;
+
+ d = XOpenDisplay(display_name);
+ if (d == NULL) {
+ fprintf (stderr, "%s: unable to open display '%s'\n",
+ program_name, XDisplayName (display_name));
+ usage ();
+ /* doesn't return */
+ }
+
+ return(d);
+}
+
+
+/*
+ * Setup_Display_And_Screen: This routine opens up the correct display (i.e.,
+ * it calls Get_Display_Name) and then stores a
+ * pointer to it in dpy. The default screen
+ * for this display is then stored in screen.
+ * Does not require dpy or screen defined.
+ */
+void Setup_Display_And_Screen(argc, argv)
+int *argc; /* MODIFIED */
+char **argv; /* MODIFIED */
+{
+ dpy = Open_Display (Get_Display_Name(argc, argv));
+ screen = DefaultScreen(dpy);
+}
+
+
+/*
+ * Open_Font: This routine opens a font with error handling.
+ */
+XFontStruct *Open_Font(name)
+char *name;
+{
+ XFontStruct *font;
+
+ if (!(font=XLoadQueryFont(dpy, name)))
+ Fatal_Error("Unable to open font %s!", name);
+
+ return(font);
+}
+
+
+/*
+ * Beep: Routine to beep the display.
+ */
+void Beep()
+{
+ XBell(dpy, 50);
+}
+
+
+/*
+ * ReadBitmapFile: same as XReadBitmapFile except it returns the bitmap
+ * directly and handles errors using Fatal_Error.
+ */
+static void _bitmap_error(status, filename)
+ int status;
+ char *filename;
+{
+ if (status == BitmapOpenFailed)
+ Fatal_Error("Can't open file %s!", filename);
+ else if (status == BitmapFileInvalid)
+ Fatal_Error("file %s: Bad bitmap format.", filename);
+ else
+ Fatal_Error("Out of memory!");
+}
+
+Pixmap ReadBitmapFile(d, filename, width, height, x_hot, y_hot)
+ Drawable d;
+ char *filename;
+ int *width, *height, *x_hot, *y_hot;
+{
+ Pixmap bitmap;
+ int status;
+
+ status = XReadBitmapFile(dpy, RootWindow(dpy, screen), filename,
+ (unsigned int *)width, (unsigned int *)height,
+ &bitmap, x_hot, y_hot);
+ if (status != BitmapSuccess)
+ _bitmap_error(status, filename);
+
+ return(bitmap);
+}
+
+
+/*
+ * WriteBitmapFile: same as XWriteBitmapFile except it handles errors
+ * using Fatal_Error.
+ */
+void WriteBitmapFile(filename, bitmap, width, height, x_hot, y_hot)
+ char *filename;
+ Pixmap bitmap;
+ int width, height, x_hot, y_hot;
+{
+ int status;
+
+ status= XWriteBitmapFile(dpy, filename, bitmap, width, height, x_hot,
+ y_hot);
+ if (status != BitmapSuccess)
+ _bitmap_error(status, filename);
+}
+
+
+/*
+ * Select_Window_Args: a rountine to provide a common interface for
+ * applications that need to allow the user to select one
+ * window on the screen for special consideration.
+ * This routine implements the following command line
+ * arguments:
+ *
+ * -root Selects the root window.
+ * -id <id> Selects window with id <id>. <id> may
+ * be either in decimal or hex.
+ * -name <name> Selects the window with name <name>.
+ *
+ * Call as Select_Window_Args(&argc, argv) in main before
+ * parsing any of your program's command line arguments.
+ * Select_Window_Args will remove its arguments so that
+ * your program does not have to worry about them.
+ * The window returned is the window selected or 0 if
+ * none of the above arguments was present. If 0 is
+ * returned, Select_Window should probably be called after
+ * all command line arguments, and other setup is done.
+ * For examples of usage, see xwininfo, xwd, or xprop.
+ */
+Window Select_Window_Args(rargc, argv)
+ int *rargc;
+ char **argv;
+#define ARGC (*rargc)
+{
+ int nargc=1;
+ int argc;
+ char **nargv;
+ Window w=0;
+
+ nargv = argv+1; argc = ARGC;
+#define OPTION argv[0]
+#define NXTOPTP ++argv, --argc>0
+#define NXTOPT if (++argv, --argc==0) usage()
+#define COPYOPT nargv++[0]=OPTION, nargc++
+
+ while (NXTOPTP) {
+ if (!strcmp(OPTION, "-")) {
+ COPYOPT;
+ while (NXTOPTP)
+ COPYOPT;
+ break;
+ }
+ if (!strcmp(OPTION, "-root")) {
+ w=RootWindow(dpy, screen);
+ continue;
+ }
+ if (!strcmp(OPTION, "-name")) {
+ NXTOPT;
+ w = Window_With_Name(dpy, RootWindow(dpy, screen),
+ OPTION);
+ if (!w)
+ Fatal_Error("No window with name %s exists!",OPTION);
+ continue;
+ }
+ if (!strcmp(OPTION, "-id")) {
+ NXTOPT;
+ w=0;
+ sscanf(OPTION, "0x%lx", &w);
+ if (!w)
+ sscanf(OPTION, "%ld", &w);
+ if (!w)
+ Fatal_Error("Invalid window id format: %s.", OPTION);
+ continue;
+ }
+ COPYOPT;
+ }
+ ARGC = nargc;
+
+ return(w);
+}
+
+/*
+ * Other_stuff: A group of routines which do common X11 tasks.
+ *
+ * Written by Mark Lillibridge. Last updated 7/1/87
+ */
+
+extern Display *dpy;
+extern int screen;
+
+/*
+ * Resolve_Color: This routine takes a color name and returns the pixel #
+ * that when used in the window w will be of color name.
+ * (WARNING: The colormap of w MAY be modified! )
+ * If colors are run out of, only the first n colors will be
+ * as correct as the hardware can make them where n depends
+ * on the display. This routine does not require wind to
+ * be defined.
+ */
+unsigned long Resolve_Color(w, name)
+ Window w;
+ char *name;
+{
+ XColor c;
+ Colormap colormap;
+ XWindowAttributes wind_info;
+
+ /*
+ * The following is a hack to insure machines without a rgb table
+ * handle at least white & black right.
+ */
+ if (!strcmp(name, "white"))
+ name="#ffffffffffff";
+ if (!strcmp(name, "black"))
+ name="#000000000000";
+
+ XGetWindowAttributes(dpy, w, &wind_info);
+ colormap = wind_info.colormap;
+
+ if (!XParseColor(dpy, colormap, name, &c))
+ Fatal_Error("Bad color format '%s'.", name);
+
+ if (!XAllocColor(dpy, colormap, &c))
+ Fatal_Error("XAllocColor failed!");
+
+ return(c.pixel);
+}
+
+
+/*
+ * Bitmap_To_Pixmap: Convert a bitmap to a 2 colored pixmap. The colors come
+ * from the foreground and background colors of the gc.
+ * Width and height are required solely for efficiency.
+ * If needed, they can be obtained via. XGetGeometry.
+ */
+Pixmap Bitmap_To_Pixmap(dpy, d, gc, bitmap, width, height)
+ Display *dpy;
+ Drawable d;
+ GC gc;
+ Pixmap bitmap;
+ int width, height;
+{
+ Pixmap pix;
+ int x;
+ unsigned int i, depth;
+ Drawable root;
+
+ if (!XGetGeometry(dpy, d, &root, &x, &x, &i, &i, &i, &depth))
+ return(0);
+
+ pix = XCreatePixmap(dpy, d, width, height, (int)depth);
+
+ XCopyPlane(dpy, bitmap, pix, gc, 0, 0, width, height, 0, 0, 1);
+
+ return(pix);
+}
+
+
+/*
+ * blip: a debugging routine. Prints Blip! on stderr with flushing.
+ */
+void blip()
+{
+ outl("blip!");
+}
+
+
+/*
+ * Routine to let user select a window using the mouse
+ */
+
+Window Select_Window(dpy)
+ Display *dpy;
+{
+ int status;
+ Cursor cursor;
+ XEvent event;
+ Window target_win = None, root = RootWindow(dpy,screen);
+ int buttons = 0;
+
+ /* Make the target cursor */
+ cursor = XCreateFontCursor(dpy, XC_crosshair);
+
+ /* Grab the pointer using target cursor, letting it room all over */
+ status = XGrabPointer(dpy, root, False,
+ ButtonPressMask|ButtonReleaseMask, GrabModeSync,
+ GrabModeAsync, root, cursor, CurrentTime);
+ if (status != GrabSuccess) Fatal_Error("Can't grab the mouse.");
+
+ /* Let the user select a window... */
+ while ((target_win == None) || (buttons != 0)) {
+ /* allow one more event */
+ XAllowEvents(dpy, SyncPointer, CurrentTime);
+ XWindowEvent(dpy, root, ButtonPressMask|ButtonReleaseMask, &event);
+ switch (event.type) {
+ case ButtonPress:
+ if (target_win == None) {
+ target_win = event.xbutton.subwindow; /* window selected */
+ if (target_win == None) target_win = root;
+ }
+ buttons++;
+ break;
+ case ButtonRelease:
+ if (buttons > 0) /* there may have been some down before we started */
+ buttons--;
+ break;
+ }
+ }
+
+ XUngrabPointer(dpy, CurrentTime); /* Done with pointer */
+
+ return(target_win);
+}
+
+
+/*
+ * Window_With_Name: routine to locate a window with a given name on a display.
+ * If no window with the given name is found, 0 is returned.
+ * If more than one window has the given name, the first
+ * one found will be returned. Only top and its subwindows
+ * are looked at. Normally, top should be the RootWindow.
+ */
+Window Window_With_Name(dpy, top, name)
+ Display *dpy;
+ Window top;
+ char *name;
+{
+ Window *children, dummy;
+ unsigned int nchildren;
+ int i;
+ Window w=0;
+ char *window_name;
+
+ if (XFetchName(dpy, top, &window_name) && !strcmp(window_name, name))
+ return(top);
+
+ if (!XQueryTree(dpy, top, &dummy, &dummy, &children, &nchildren))
+ return(0);
+
+ for (i=0; i<nchildren; i++) {
+ w = Window_With_Name(dpy, children[i], name);
+ if (w)
+ break;
+ }
+ if (children) XFree ((char *)children);
+ return(w);
+}
+
+/*
+ * outl: a debugging routine. Flushes stdout then prints a message on stderr
+ * and flushes stderr. Used to print messages when past certain points
+ * in code so we can tell where we are. Outl may be invoked like
+ * printf with up to 7 arguments.
+ */
+/* VARARGS1 */
+outl(msg, arg0,arg1,arg2,arg3,arg4,arg5,arg6)
+ char *msg;
+ char *arg0, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6;
+{
+ fflush(stdout);
+ fprintf(stderr, msg, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
+ fprintf(stderr, "\n");
+ fflush(stderr);
+}
+
+
+/*
+ * Standard fatal error routine - call like printf but maximum of 7 arguments.
+ * Does not require dpy or screen defined.
+ */
+/* VARARGS1 */
+void Fatal_Error(msg, arg0,arg1,arg2,arg3,arg4,arg5,arg6)
+char *msg;
+char *arg0, *arg1, *arg2, *arg3, *arg4, *arg5, *arg6;
+{
+ fflush(stdout);
+ fflush(stderr);
+ fprintf(stderr, "%s: error: ", program_name);
+ fprintf(stderr, msg, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
+ fprintf(stderr, "\n");
+ exit(1);
+}
diff --git a/dsimple.h b/dsimple.h
new file mode 100644
index 0000000..a634848
--- /dev/null
+++ b/dsimple.h
@@ -0,0 +1,81 @@
+/* $Xorg: dsimple.h,v 1.4 2001/02/09 02:05:54 xorgcvs Exp $ */
+/*
+
+Copyright 1993, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+/*
+ * Just_display.h: This file contains the definitions needed to use the
+ * functions in just_display.c. It also declares the global
+ * variables dpy, screen, and program_name which are needed to
+ * use just_display.c.
+ *
+ * Written by Mark Lillibridge. Last updated 7/1/87
+ *
+ * Send bugs, etc. to chariot@athena.mit.edu.
+ */
+
+ /* Global variables used by routines in just_display.c */
+
+char *program_name = "unknown_program"; /* Name of this program */
+Display *dpy; /* The current display */
+int screen; /* The current screen */
+
+#define INIT_NAME program_name=argv[0] /* use this in main to setup
+ program_name */
+
+ /* Declaritions for functions in just_display.c */
+
+void Fatal_Error();
+char *Malloc();
+char *Realloc();
+char *Get_Display_Name();
+Display *Open_Display();
+void Setup_Display_And_Screen();
+XFontStruct *Open_Font();
+void Beep();
+Pixmap ReadBitmapFile();
+void WriteBitmapFile();
+Window Select_Window_Args();
+
+#define X_USAGE "[host:display]" /* X arguments handled by
+ Get_Display_Name */
+#define SELECT_USAGE "[{-root|-id <id>|-font <font>|-name <name>}]"
+
+/*
+ * Other_stuff.h: Definitions of routines in other_stuff.
+ *
+ * Written by Mark Lillibridge. Last updated 7/1/87
+ *
+ * Send bugs, etc. to chariot@athena.mit.edu.
+ */
+
+unsigned long Resolve_Color();
+Pixmap Bitmap_To_Pixmap();
+Window Select_Window();
+void out();
+void blip();
+Window Window_With_Name();
diff --git a/xlsfonts.c b/xlsfonts.c
new file mode 100644
index 0000000..2ccdf49
--- /dev/null
+++ b/xlsfonts.c
@@ -0,0 +1,621 @@
+/*
+ * $Xorg: xlsfonts.c,v 1.4 2001/02/09 02:05:54 xorgcvs Exp $
+ *
+ *
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ * */
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xos.h>
+#include <stdio.h>
+#include "dsimple.h"
+
+#define N_START 1000 /* Maximum # of fonts to start with */
+
+int max_output_line_width = 79;
+int output_line_padding = 3;
+int columns = 0;
+
+#define L_SHORT 0
+#define L_MEDIUM 1
+#define L_LONG 2
+#define L_VERYLONG 3
+
+Bool sort_output = True;
+Bool open_instead_of_list = False;
+int long_list = L_SHORT;
+int nnames = N_START;
+int font_cnt;
+int min_max;
+typedef struct {
+ char *name;
+ XFontStruct *info;
+} FontList;
+FontList *font_list;
+
+
+usage()
+{
+ fprintf (stderr,"usage: %s [-options] [-fn pattern]\n", program_name);
+ fprintf (stderr, "where options include:\n");
+ fprintf (stderr,
+ " -l[l[l]] give long info about each font\n");
+ fprintf (stderr,
+ " -m give character min and max bounds\n");
+ fprintf (stderr,
+ " -C force columns\n");
+ fprintf (stderr,
+ " -1 force single column\n");
+ fprintf (stderr,
+ " -u keep output unsorted\n");
+ fprintf (stderr,
+ " -o use OpenFont/QueryFont instead of ListFonts\n");
+ fprintf (stderr,
+ " -w width maximum width for multiple columns\n");
+ fprintf (stderr,
+ " -n columns number of columns if multi column\n");
+ fprintf (stderr,
+ " -display displayname X server to contact\n");
+ fprintf (stderr,
+ "\n");
+ exit(1);
+}
+
+main(argc, argv)
+int argc;
+char **argv;
+{
+ int argcnt = 0, i;
+
+ INIT_NAME;
+
+ /* Handle command line arguments, open display */
+ Setup_Display_And_Screen(&argc, argv);
+ for (argv++, argc--; argc; argv++, argc--) {
+ if (argv[0][0] == '-') {
+ if (argcnt > 0) usage ();
+ for (i=1; argv[0][i]; i++)
+ switch(argv[0][i]) {
+ case 'l':
+ long_list++;
+ break;
+ case 'm':
+ min_max++;
+ break;
+ case 'C':
+ columns = 0;
+ break;
+ case '1':
+ columns = 1;
+ break;
+ case 'f':
+ if (--argc <= 0) usage ();
+ argcnt++;
+ argv++;
+ get_list(argv[0]);
+ goto next;
+ case 'w':
+ if (--argc <= 0) usage ();
+ argv++;
+ max_output_line_width = atoi(argv[0]);
+ goto next;
+ case 'n':
+ if (--argc <= 0) usage ();
+ argv++;
+ columns = atoi(argv[0]);
+ goto next;
+ case 'o':
+ open_instead_of_list = True;
+ break;
+ case 'u':
+ sort_output = False;
+ break;
+ default:
+ usage();
+ break;
+ }
+ if (i == 1)
+ usage();
+ } else {
+ argcnt++;
+ get_list(argv[0]);
+ }
+ next: ;
+ }
+ if (argcnt == 0)
+ get_list("*");
+ show_fonts();
+ exit(0);
+}
+
+get_list(pattern)
+ char *pattern;
+{
+ int available = nnames+1,
+ i;
+ char **fonts;
+ XFontStruct *info;
+
+ /* Get list of fonts matching pattern */
+ for (;;) {
+ if (open_instead_of_list) {
+ info = XLoadQueryFont (dpy, pattern);
+
+ if (info) {
+ fonts = &pattern;
+ available = 1;
+ XUnloadFont (dpy, info->fid);
+ } else {
+ fonts = NULL;
+ }
+ break;
+ }
+
+ if (long_list == L_MEDIUM)
+ fonts = XListFontsWithInfo(dpy,
+ pattern, nnames, &available, &info);
+ else
+ fonts = XListFonts(dpy, pattern, nnames, &available);
+ if (fonts == NULL || available < nnames)
+ break;
+ if (long_list == L_MEDIUM)
+ XFreeFontInfo(fonts, info, available);
+ else
+ XFreeFontNames(fonts);
+ nnames = available * 2;
+ }
+
+ if (fonts == NULL) {
+ fprintf(stderr, "%s: pattern \"%s\" unmatched\n",
+ program_name, pattern);
+ return;
+ }
+
+ font_list = (FontList *)Realloc((char *)font_list,
+ (font_cnt + available) * sizeof(FontList));
+ for (i=0; i<available; i++) {
+ font_list[font_cnt].name = fonts[i];
+ if (long_list == L_MEDIUM)
+ font_list[font_cnt].info = info + i;
+ else
+ font_list[font_cnt].info = NULL;
+ font_cnt++;
+ }
+}
+
+compare(f1, f2)
+ FontList *f1, *f2;
+{
+ char *p1 = f1->name,
+ *p2 = f2->name;
+
+ while (*p1 && *p2 && *p1 == *p2)
+ p1++, p2++;
+ return(*p1 - *p2);
+}
+
+show_fonts()
+{
+ int i;
+
+ if (font_cnt == 0)
+ return;
+
+ /* first sort the output */
+ if (sort_output) qsort(font_list, font_cnt, sizeof(FontList), compare);
+
+ if (long_list > L_MEDIUM) {
+ for (i = 0; i < font_cnt; i++) {
+ do_query_font (dpy, font_list[i].name);
+ }
+ return;
+ }
+
+ if (long_list == L_MEDIUM) {
+ XFontStruct *pfi;
+ char *string;
+
+ printf("DIR ");
+ printf("MIN ");
+ printf("MAX ");
+ printf("EXIST ");
+ printf("DFLT ");
+ printf("PROP ");
+ printf("ASC ");
+ printf("DESC ");
+ printf("NAME");
+ printf("\n");
+ for (i=0; i<font_cnt; i++) {
+ pfi = font_list[i].info;
+ if (!pfi) {
+ fprintf (stderr,
+ "%s: no font information for font \"%s\".\n",
+ program_name,
+ font_list[i].name ?
+ font_list[i].name : "");
+ continue;
+ }
+ switch(pfi->direction) {
+ case FontLeftToRight: string = "-->"; break;
+ case FontRightToLeft: string = "<--"; break;
+ default: string = "???"; break;
+ }
+ printf("%-4s", string);
+ if (pfi->min_byte1 == 0
+ && pfi->max_byte1 == 0) {
+ printf(" %3d ", pfi->min_char_or_byte2);
+ printf(" %3d ", pfi->max_char_or_byte2);
+ } else {
+ printf("*%3d ", pfi->min_byte1);
+ printf("*%3d ", pfi->max_byte1);
+ }
+ printf("%5s ", pfi->all_chars_exist ? "all" : "some");
+ printf("%4d ", pfi->default_char);
+ printf("%4d ", pfi->n_properties);
+ printf("%3d ", pfi->ascent);
+ printf("%4d ", pfi->descent);
+ printf("%s\n", font_list[i].name);
+ if (min_max) {
+ char min[ BUFSIZ ],
+ max[ BUFSIZ ];
+ char *pmax = max,
+ *pmin = min;
+
+ strcpy(pmin, " min(l,r,w,a,d) = (");
+ strcpy(pmax, " max(l,r,w,a,d) = (");
+ pmin += strlen(pmin);
+ pmax += strlen(pmax);
+
+ copy_number(&pmin, &pmax,
+ pfi->min_bounds.lbearing,
+ pfi->max_bounds.lbearing);
+ *pmin++ = *pmax++ = ',';
+ copy_number(&pmin, &pmax,
+ pfi->min_bounds.rbearing,
+ pfi->max_bounds.rbearing);
+ *pmin++ = *pmax++ = ',';
+ copy_number(&pmin, &pmax,
+ pfi->min_bounds.width,
+ pfi->max_bounds.width);
+ *pmin++ = *pmax++ = ',';
+ copy_number(&pmin, &pmax,
+ pfi->min_bounds.ascent,
+ pfi->max_bounds.ascent);
+ *pmin++ = *pmax++ = ',';
+ copy_number(&pmin, &pmax,
+ pfi->min_bounds.descent,
+ pfi->max_bounds.descent);
+ *pmin++ = *pmax++ = ')';
+ *pmin = *pmax = '\0';
+ printf("%s\n", min);
+ printf("%s\n", max);
+ }
+ }
+ return;
+ }
+
+ if ((columns == 0 && isatty(1)) || columns > 1) {
+ int width,
+ max_width = 0,
+ lines_per_column,
+ j,
+ index;
+
+ for (i=0; i<font_cnt; i++) {
+ width = strlen(font_list[i].name);
+ if (width > max_width)
+ max_width = width;
+ }
+ if (max_width == 0)
+ Fatal_Error("all %d fontnames listed are zero length",
+ font_cnt);
+
+ if (columns == 0) {
+ if ((max_width * 2) + output_line_padding >
+ max_output_line_width) {
+ columns = 1;
+ } else {
+ max_width += output_line_padding;
+ columns = ((max_output_line_width +
+ output_line_padding) / max_width);
+ }
+ } else {
+ max_width += output_line_padding;
+ }
+ if (columns <= 1) goto single_column;
+
+ if (font_cnt < columns)
+ columns = font_cnt;
+ lines_per_column = (font_cnt + columns - 1) / columns;
+
+ for (i=0; i<lines_per_column; i++) {
+ for (j=0; j<columns; j++) {
+ index = j * lines_per_column + i;
+ if (index >= font_cnt)
+ break;
+ if (j+1 == columns)
+ printf("%s", font_list[ index ].name);
+ else
+ printf("%-*s",
+ max_width,
+ font_list[ index ].name);
+ }
+ printf("\n");
+ }
+ return;
+ }
+
+ single_column:
+ for (i=0; i<font_cnt; i++)
+ printf("%s\n", font_list[i].name);
+}
+
+max(i, j)
+ int i, j;
+{
+ if (i > j)
+ return (i);
+ return(j);
+}
+
+copy_number(pp1, pp2, n1, n2)
+ char **pp1, **pp2;
+ int n1, n2;
+{
+ char *p1 = *pp1;
+ char *p2 = *pp2;
+ int w;
+
+ sprintf(p1, "%d", n1);
+ sprintf(p2, "%d", n2);
+ w = max(strlen(p1), strlen(p2));
+ sprintf(p1, "%*d", w, n1);
+ sprintf(p2, "%*d", w, n2);
+ p1 += strlen(p1);
+ p2 += strlen(p2);
+ *pp1 = p1;
+ *pp2 = p2;
+}
+
+
+
+/* ARGSUSED */
+static int IgnoreError(disp, event)
+ Display *disp;
+ XErrorEvent *event;
+{
+ return 0;
+}
+
+static char *bounds_metrics_title =
+ "width left right asc desc attr keysym\n";
+static char *char_metrics_fmt =
+"\t0x%02x%02x (%u)\t%4d %4d %4d %4d %4d 0x%04x %s\n";
+static char *bounds_metrics_fmt =
+"\t%3s\t\t%4d %4d %4d %4d %4d 0x%04x\n";
+
+
+#define PrintBounds(_what,_ptr) \
+{ register XCharStruct *p = (_ptr); \
+ printf (bounds_metrics_fmt, _what, p->width, p->lbearing, \
+ p->rbearing, p->ascent, p->descent, p->attributes); }
+
+
+static char* stringValued [] = { /* values are atoms */
+ "FAMILY_NAME",
+ "FOUNDRY",
+ "STYLE",
+ "MONOSPACED",
+ "RELATIVE_WEIGHT",
+ "RELATIVE_SET",
+ "CLASSIFICATION",
+ "CHARSET_REGISTRY",
+ "CHARSET_ENCODING",
+ "QUALITY",
+ "CHARSET_COLLECTIONS",
+ "FULL_NAME",
+ "COPYRIGHT",
+ "WEIGHT_NAME",
+ "SETWIDTH_NAME",
+ "SLANT",
+ "SPACING",
+ "ADD_STYLE_NAME",
+ "FONTNAME_REGISTRY",
+ "FONT",
+ "DEVICE_FONT_NAME",
+ NULL
+ };
+
+static void PrintProperty (prop)
+ XFontProp *prop;
+{
+ char *atom, *value;
+ char nosuch[40];
+ int i;
+ int (*oldhandler)() = XSetErrorHandler (IgnoreError);
+
+ atom = XGetAtomName(dpy, prop->name);
+ if (!atom) {
+ atom = nosuch;
+ nosuch[0] = '\0';
+ (void)sprintf (atom, "No such atom = %d", prop->name);
+ }
+ printf (" %s", atom);
+ for (i = strlen(atom); i < 22; i++) printf (" ");
+ for (i = 0; ; i++) {
+ if (stringValued[i] == NULL) {
+ printf ("%d\n", prop->card32);
+ break;
+ }
+ if (strcmp(stringValued[i], atom) == 0) {
+ value = XGetAtomName(dpy, prop->card32);
+ if (value == NULL)
+ printf ("%d (expected string value)\n", prop->card32);
+ else {
+ printf ("%s\n", value);
+ XFree (value);
+ }
+ break;
+ }
+ }
+ if (atom != nosuch) XFree (atom);
+ XSetErrorHandler (oldhandler);
+}
+
+
+ComputeFontType (fs)
+ XFontStruct *fs;
+{
+ int i;
+ Bool char_cell = True;
+ char *reason = NULL;
+ XCharStruct *cs;
+ Atom awatom = XInternAtom (dpy, "AVERAGE_WIDTH", False);
+
+ printf (" font type:\t\t");
+ if (fs->min_bounds.width != fs->max_bounds.width) {
+ printf ("Proportional (min and max widths not equal)\n");
+ return;
+ }
+
+ if (awatom) {
+ for (i = 0; i < fs->n_properties; i++) {
+ if (fs->properties[i].name == awatom &&
+ (fs->max_bounds.width * 10) != fs->properties[i].card32) {
+ char_cell = False;
+ reason = "font width not equal to AVERAGE_WIDTH";
+ break;
+ }
+ }
+ }
+
+ if (fs->per_char) {
+ for (i = fs->min_char_or_byte2, cs = fs->per_char;
+ i <= fs->max_char_or_byte2; i++, cs++) {
+ if (cs->width == 0) continue;
+ if (cs->width != fs->max_bounds.width) {
+ /* this shouldn't happen since we checked above */
+ printf ("Proportional (characters not all the same width)\n");
+ return;
+ }
+ if (char_cell) {
+ if (cs->width < 0) {
+ if (!(cs->width <= cs->lbearing &&
+ cs->lbearing <= cs->rbearing &&
+ cs->rbearing <= 0)) {
+ char_cell = False;
+ reason = "ink outside bounding box";
+ }
+ } else {
+ if (!(0 <= cs->lbearing &&
+ cs->lbearing <= cs->rbearing &&
+ cs->rbearing <= cs->width)) {
+ char_cell = False;
+ reason = "ink outside bounding box";
+ }
+ }
+ if (!(cs->ascent <= fs->ascent &&
+ cs->descent <= fs->descent)) {
+ char_cell = False;
+ reason = "characters not all same ascent or descent";
+ }
+ }
+ }
+ }
+
+ printf ("%s", char_cell ? "Character Cell" : "Monospaced");
+ if (reason) printf (" (%s)", reason);
+ printf ("\n");
+
+ return;
+}
+
+
+print_character_metrics (info)
+ register XFontStruct *info;
+{
+ register XCharStruct *pc = info->per_char;
+ register int i, j;
+ unsigned n, saven;
+
+ printf (" character metrics:\n");
+ saven = ((info->min_byte1 << 8) | info->min_char_or_byte2);
+ for (j = info->min_byte1; j <= info->max_byte1; j++) {
+ n = saven;
+ for (i = info->min_char_or_byte2; i <= info->max_char_or_byte2; i++) {
+ char *s = XKeysymToString ((KeySym) n);
+ printf (char_metrics_fmt, j, i, n, pc->width, pc->lbearing,
+ pc->rbearing, pc->ascent, pc->descent, pc->attributes,
+ s ? s : ".");
+ pc++;
+ n++;
+ }
+ saven += 256;
+ }
+}
+
+
+do_query_font (dpy, name)
+ Display *dpy;
+ char *name;
+{
+ register int i;
+ register XFontStruct *info = XLoadQueryFont (dpy, name);
+
+ if (!info) {
+ fprintf (stderr, "%s: unable to get info about font \"%s\"\n",
+ program_name, name);
+ return;
+ }
+ printf ("name: %s\n", name ? name : "(nil)");
+ printf (" direction:\t\t%s\n", ((info->direction == FontLeftToRight)
+ ? "left to right" : "right to left"));
+ printf (" indexing:\t\t%s\n",
+ ((info->min_byte1 == 0 && info->max_byte1 == 0) ? "linear" :
+ "matrix"));
+ printf (" rows:\t\t\t0x%02x thru 0x%02x (%d thru %d)\n",
+ info->min_byte1, info->max_byte1,
+ info->min_byte1, info->max_byte1);
+ printf (" columns:\t\t0x%02x thru 0x%02x (%d thru %d)\n",
+ info->min_char_or_byte2, info->max_char_or_byte2,
+ info->min_char_or_byte2, info->max_char_or_byte2);
+ printf (" all chars exist:\t%s\n",
+ (info->all_chars_exist) ? "yes" : "no");
+ printf (" default char:\t\t0x%04x (%d)\n",
+ info->default_char, info->default_char);
+ printf (" ascent:\t\t%d\n", info->ascent);
+ printf (" descent:\t\t%d\n", info->descent);
+ ComputeFontType (info);
+ printf (" bounds:\t\t%s", bounds_metrics_title);
+ PrintBounds ("min", &info->min_bounds);
+ PrintBounds ("max", &info->max_bounds);
+ if (info->per_char && long_list >= L_VERYLONG)
+ print_character_metrics (info);
+ printf (" properties:\t\t%d\n", info->n_properties);
+ for (i = 0; i < info->n_properties; i++)
+ PrintProperty (&info->properties[i]);
+ printf ("\n");
+
+ XFreeFontInfo (NULL, info, 1);
+}
diff --git a/xlsfonts.man b/xlsfonts.man
new file mode 100644
index 0000000..9ac6a24
--- /dev/null
+++ b/xlsfonts.man
@@ -0,0 +1,102 @@
+.\" $Xorg: xlsfonts.man,v 1.4 2001/02/09 02:05:55 xorgcvs Exp $
+.\" Copyright 1988, 1998 The Open Group
+.\"
+.\" Permission to use, copy, modify, distribute, and sell this software and its
+.\" documentation for any purpose is hereby granted without fee, provided that
+.\" the above copyright notice appear in all copies and that both that
+.\" copyright notice and this permission notice appear in supporting
+.\" documentation.
+.\"
+.\" The above copyright notice and this permission notice shall be included
+.\" in all copies or substantial portions of the Software.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+.\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+.\" OTHER DEALINGS IN THE SOFTWARE.
+.\"
+.\" Except as contained in this notice, the name of The Open Group shall
+.\" not be used in advertising or otherwise to promote the sale, use or
+.\" other dealings in this Software without prior written authorization
+.\" from The Open Group.
+.TH XLSFONTS 1 "Release 6.4" "X Version 11"
+.SH NAME
+xlsfonts \- server font list displayer for X
+.SH SYNOPSIS
+.B xlsfonts
+[\-options ...] [\-fn pattern]
+.SH DESCRIPTION
+.I Xlsfonts
+lists the fonts that match the given \fIpattern\fP.
+The wildcard character "*" may be used to match any sequence of
+characters (including none), and "?" to match any single character.
+If no pattern is given, "*" is assumed.
+.PP
+The "*" and "?" characters must be quoted to prevent them from
+being expanded by the shell.
+.SH "OPTIONS"
+.PP
+.TP 8
+.B \-display \fIhost\fP:\fIdpy\fP
+This option specifies the X server to contact.
+.PP
+.TP 8
+.B \-l
+Lists some attributes of the font on one line in addition to its name.
+.TP 8
+.B \-ll
+Lists font properties in addition to \fB\-l\fP output.
+.TP 8
+.B \-lll
+Lists character metrics in addition to \fB\-ll\fP output.
+.TP 8
+.B \-m
+This option indicates that long listings should also print the minimum and
+maximum bounds of each font.
+.TP 8
+.B \-C
+This option indicates that listings should use multiple columns. This is the
+same as \fB\-n 0\fP.
+.TP 8
+.B \-1
+This option indicates that listings should use a single column. This is the
+same as \fB\-n 1\fP.
+.TP 8
+.B \-w \fIwidth\fP
+This option specifies the width in characters that should be used in
+figuring out how many columns to print. The default is 79.
+.TP 8
+.B \-n \fIcolumns\fP
+This option specifies the number of columns to use in displaying the output.
+By default, it will attempt to fit as many columns of font names into the
+number of character specified by \fB\-w \fIwidth\fR.
+.TP 8
+.B \-u
+This option indicates that the output should be left unsorted.
+.TP 8
+.B \-o
+This option indicates that \fIxlsfonts\fP should do an \fBOpenFont\fP (and
+\fBQueryFont\fP, if appropriate) rather than a \fBListFonts\fP. This is
+useful if \fBListFonts\fP or \fBListFontsWithInfo\fP fail to list a known
+font (as is the case with some scaled font systems).
+.TP 8
+.B \-fn \fIpattern\fP
+This option specifies the font name pattern to match.
+.PP
+.SH "SEE ALSO"
+X(1), Xserver(1), xset(1), xfd(1),
+.I "X Logical Font Description Conventions"
+.SH ENVIRONMENT
+.TP 8
+.B DISPLAY
+to get the default host and display to use.
+.SH BUGS
+Doing ``xlsfonts -l'' can tie up your server for a very long time.
+This is really a bug with single-threaded non-preemptable servers, not with
+this program.
+.SH AUTHOR
+Mark Lillibridge, MIT Project Athena; Jim Fulton, MIT X Consortium;
+Phil Karlton, SGI