xfd.c revision 3538fbe3
1492e1cfeSmrg/*
2492e1cfeSmrg * $Xorg: xfd.c,v 1.4 2001/02/09 02:05:42 xorgcvs Exp $
3492e1cfeSmrg *
43538fbe3Smrg *
5492e1cfeSmrgCopyright 1989, 1998  The Open Group
6492e1cfeSmrg
7492e1cfeSmrgPermission to use, copy, modify, distribute, and sell this software and its
8492e1cfeSmrgdocumentation for any purpose is hereby granted without fee, provided that
9492e1cfeSmrgthe above copyright notice appear in all copies and that both that
10492e1cfeSmrgcopyright notice and this permission notice appear in supporting
11492e1cfeSmrgdocumentation.
12492e1cfeSmrg
13492e1cfeSmrgThe above copyright notice and this permission notice shall be included in
14492e1cfeSmrgall copies or substantial portions of the Software.
15492e1cfeSmrg
16492e1cfeSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17492e1cfeSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18492e1cfeSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19492e1cfeSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20492e1cfeSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21492e1cfeSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22492e1cfeSmrg
23492e1cfeSmrgExcept as contained in this notice, the name of The Open Group shall not be
24492e1cfeSmrgused in advertising or otherwise to promote the sale, use or other dealings
25492e1cfeSmrgin this Software without prior written authorization from The Open Group.
26492e1cfeSmrg * *
27492e1cfeSmrg * Author:  Jim Fulton, MIT X Consortium
28492e1cfeSmrg */
29492e1cfeSmrg/* $XFree86: xc/programs/xfd/xfd.c,v 1.8 2003/02/20 02:56:40 dawes Exp $ */
30492e1cfeSmrg
319e0146f7Smrg#ifdef HAVE_CONFIG_H
329e0146f7Smrg# include "config.h"
339e0146f7Smrg#endif
349e0146f7Smrg
35492e1cfeSmrg#include <X11/Intrinsic.h>
36492e1cfeSmrg#include <X11/StringDefs.h>
37492e1cfeSmrg#include <X11/Xos.h>
38492e1cfeSmrg#include <X11/Xatom.h>
39492e1cfeSmrg#include <X11/Shell.h>
40492e1cfeSmrg#include <X11/Xaw/Cardinals.h>
41492e1cfeSmrg#include <X11/Xaw/Paned.h>
42492e1cfeSmrg#include <X11/Xaw/Box.h>
43492e1cfeSmrg#include <X11/Xaw/Form.h>
44492e1cfeSmrg#include <X11/Xaw/Command.h>
45492e1cfeSmrg#include <stdio.h>
46492e1cfeSmrg#include <stdlib.h>
479e0146f7Smrg#ifdef USE_GETTEXT
489e0146f7Smrg# include <X11/Xlocale.h>
499e0146f7Smrg# include <libintl.h>
509e0146f7Smrg#else
519e0146f7Smrg# define gettext(a) (a)
529e0146f7Smrg#endif
53492e1cfeSmrg#include "grid.h"
54492e1cfeSmrg#ifdef XRENDER
55492e1cfeSmrg#include <X11/Xft/Xft.h>
56492e1cfeSmrg#include <X11/extensions/Xrender.h>
57492e1cfeSmrg#endif
58492e1cfeSmrg
599e0146f7Smrgstatic char *ProgramName;
60492e1cfeSmrg
61492e1cfeSmrgstatic XrmOptionDescRec xfd_options[] = {
62492e1cfeSmrg{"-fn",		"*grid.font",	XrmoptionSepArg,	(caddr_t) NULL },
63492e1cfeSmrg#ifdef XRENDER
64492e1cfeSmrg{"-fa",		"*grid.face", XrmoptionSepArg,		(caddr_t) NULL },
65492e1cfeSmrg#endif
66492e1cfeSmrg{"-start",	"*startChar",	XrmoptionSepArg, 	(caddr_t) NULL },
67492e1cfeSmrg{"-box",	"*grid.boxChars", XrmoptionNoArg,	(caddr_t) "on" },
68492e1cfeSmrg{"-bc",		"*grid.boxColor", XrmoptionSepArg, 	(caddr_t) NULL },
69492e1cfeSmrg{"-center",	"*grid.centerChars", XrmoptionNoArg,	(caddr_t) "on" },
70492e1cfeSmrg{"-rows",	"*grid.cellRows", XrmoptionSepArg,	(caddr_t) NULL },
71492e1cfeSmrg{"-columns",	"*grid.cellColumns", XrmoptionSepArg,	(caddr_t) NULL },
72492e1cfeSmrg};
73492e1cfeSmrg
74492e1cfeSmrgstatic void usage(void);
75492e1cfeSmrgstatic void SelectChar(Widget w, XtPointer closure, XtPointer data);
763538fbe3Smrgstatic void do_quit(Widget w, XEvent *event, String *params,
77492e1cfeSmrg		    Cardinal *num_params);
78492e1cfeSmrgstatic void change_page(int page);
79492e1cfeSmrgstatic void set_button_state(void);
803538fbe3Smrgstatic void do_prev(Widget w, XEvent *event, String *params,
81492e1cfeSmrg		    Cardinal *num_params);
823538fbe3Smrgstatic void do_next(Widget w, XEvent *event, String *params,
83492e1cfeSmrg		    Cardinal *num_params);
843538fbe3Smrgstatic void do_prev16(Widget w, XEvent *event, String *params,
85492e1cfeSmrg		      Cardinal *num_params);
863538fbe3Smrgstatic void do_next16(Widget w, XEvent *event, String *params,
87492e1cfeSmrg		      Cardinal *num_params);
88492e1cfeSmrgstatic char *get_font_name(Display *dpy, XFontStruct *fs);
893538fbe3Smrgstatic void CatchFontConversionWarning(String name, String type, String class,
903538fbe3Smrg				       String defaultp, String *params,
91492e1cfeSmrg				       Cardinal *np);
92492e1cfeSmrg
93492e1cfeSmrgstatic XtActionsRec xfd_actions[] = {
94492e1cfeSmrg  { "Quit", do_quit },
95492e1cfeSmrg  { "Prev16", do_prev16 },
96492e1cfeSmrg  { "Prev", do_prev },
97492e1cfeSmrg  { "Next", do_next },
98492e1cfeSmrg  { "Next16", do_next16 },
99492e1cfeSmrg};
100492e1cfeSmrg
101492e1cfeSmrgstatic Atom wm_delete_window;
102492e1cfeSmrg
1039e0146f7Smrgstatic Widget quitButton, prev16Button, prevButton, nextButton, next16Button;
104492e1cfeSmrg
105492e1cfeSmrg
106492e1cfeSmrg#define DEF_SELECT_FORMAT "character 0x%04x%02x (%u,%u) (%#o,%#o)"
107492e1cfeSmrg#define DEF_METRICS_FORMAT "width %d; left %d, right %d; ascent %d, descent %d (font %d, %d)"
108492e1cfeSmrg#define DEF_RANGE_FORMAT "range:  0x%04x%02x (%u,%u) thru 0x%04x%02x (%u,%u)"
109492e1cfeSmrg#define DEF_START_FORMAT "upper left:  0x%06x (%d,%d)"
110492e1cfeSmrg#define DEF_NOCHAR_FORMAT "no such character 0x%04x%02x (%u,%u) (%#o,%#o)"
111492e1cfeSmrg
112492e1cfeSmrgstatic struct _xfd_resources {
113492e1cfeSmrg  char *select_format;
114492e1cfeSmrg  char *metrics_format;
115492e1cfeSmrg  char *range_format;
116492e1cfeSmrg  char *start_format;
117492e1cfeSmrg  char *nochar_format;
118492e1cfeSmrg} xfd_resources;
119492e1cfeSmrg
120492e1cfeSmrg#define Offset(field) XtOffsetOf(struct _xfd_resources, field)
121492e1cfeSmrg
122492e1cfeSmrgstatic XtResource Resources[] = {
1233538fbe3Smrg  { "selectFormat", "SelectFormat", XtRString, sizeof(char *),
124492e1cfeSmrg      Offset(select_format), XtRString, DEF_SELECT_FORMAT },
1253538fbe3Smrg  { "metricsFormat", "MetricsFormat", XtRString, sizeof(char *),
126492e1cfeSmrg      Offset(metrics_format), XtRString, DEF_METRICS_FORMAT },
1273538fbe3Smrg  { "rangeFormat", "RangeFormat", XtRString, sizeof(char *),
128492e1cfeSmrg      Offset(range_format), XtRString, DEF_RANGE_FORMAT },
1293538fbe3Smrg  { "startFormat", "StartFormat", XtRString, sizeof(char *),
130492e1cfeSmrg      Offset(start_format), XtRString, DEF_START_FORMAT },
1313538fbe3Smrg  { "nocharFormat", "NocharFormat", XtRString, sizeof(char *),
132492e1cfeSmrg      Offset(nochar_format), XtRString, DEF_NOCHAR_FORMAT },
133492e1cfeSmrg};
134492e1cfeSmrg
135492e1cfeSmrg#undef Offset
136492e1cfeSmrg
137492e1cfeSmrgstatic void
138492e1cfeSmrgusage(void)
139492e1cfeSmrg{
1409e0146f7Smrg    fprintf (stderr, gettext("usage:  %s [-options ...] "), ProgramName);
1419e0146f7Smrg    fprintf (stderr, "-fn ");
1429e0146f7Smrg    fprintf (stderr, gettext("font\n\n"));
143492e1cfeSmrg#ifdef XRENDER
1449e0146f7Smrg    fprintf (stderr, gettext("        %s [-options ...] "), ProgramName);
1459e0146f7Smrg    fprintf (stderr, "-fa ");
1469e0146f7Smrg    fprintf (stderr, gettext("font\n\n"));
147492e1cfeSmrg#endif
1489e0146f7Smrg    fprintf (stderr, gettext("where options include:\n"));
1499e0146f7Smrg    fprintf (stderr, "    -display ");
1509e0146f7Smrg    fprintf (stderr, gettext("display       X server to contact\n"));
1519e0146f7Smrg    fprintf (stderr, "    -geometry ");
1529e0146f7Smrg    fprintf (stderr, gettext("geometry     size and location of window\n"));
1539e0146f7Smrg    fprintf (stderr, "    -bc ");
1549e0146f7Smrg    fprintf (stderr, gettext("color              color for ImageText boxes\n"));
1559e0146f7Smrg    fprintf (stderr, "    -start ");
1569e0146f7Smrg    fprintf (stderr, gettext("number          first character to show\n"));
1579e0146f7Smrg    fprintf (stderr, "    -box                   ");
1589e0146f7Smrg    fprintf (stderr, gettext("show a box around each character\n"));
1599e0146f7Smrg    fprintf (stderr, "    -center                ");
1609e0146f7Smrg    fprintf (stderr, gettext("center each character inside its grid\n"));
1619e0146f7Smrg    fprintf (stderr, "    -rows ");
1629e0146f7Smrg    fprintf (stderr, gettext("number           number of rows in grid\n"));
1639e0146f7Smrg    fprintf (stderr, "    -columns ");
1649e0146f7Smrg    fprintf (stderr, gettext("number        number of columns in grid\n"));
165492e1cfeSmrg    exit (1);
166492e1cfeSmrg}
167492e1cfeSmrg
168492e1cfeSmrg
169492e1cfeSmrgstatic Widget selectLabel, metricsLabel, rangeLabel, startLabel, fontGrid;
170492e1cfeSmrg
171492e1cfeSmrgstatic Boolean fontConversionFailed = False;
172492e1cfeSmrgstatic XtErrorMsgHandler oldWarningHandler;
173492e1cfeSmrg
174492e1cfeSmrgint
1753538fbe3Smrgmain(int argc, char *argv[])
176492e1cfeSmrg{
177492e1cfeSmrg    XtAppContext xtcontext;
178492e1cfeSmrg    Widget toplevel, pane, toplabel, box, form;
179492e1cfeSmrg    char buf[256];
180492e1cfeSmrg    Arg av[10];
181492e1cfeSmrg    Cardinal i;
182492e1cfeSmrg    static XtCallbackRec cb[2] = { { SelectChar, NULL }, { NULL, NULL } };
183492e1cfeSmrg    XFontStruct *fs;
184492e1cfeSmrg#ifdef XRENDER
185492e1cfeSmrg    XftFont *xft;
186492e1cfeSmrg#endif
187492e1cfeSmrg    char *fontname;
1883538fbe3Smrg    const char *domaindir;
189492e1cfeSmrg    long minn, maxn;
190492e1cfeSmrg
1919e0146f7Smrg    XtSetLanguageProc(NULL, NULL, NULL);
1929e0146f7Smrg
193492e1cfeSmrg    ProgramName = argv[0];
194492e1cfeSmrg
195492e1cfeSmrg    toplevel = XtAppInitialize (&xtcontext, "Xfd",
196492e1cfeSmrg				xfd_options, XtNumber(xfd_options),
197492e1cfeSmrg				&argc, argv, NULL, NULL, 0);
1989e0146f7Smrg
1999e0146f7Smrg#ifdef USE_GETTEXT
2009e0146f7Smrg    textdomain("xfd");
2019e0146f7Smrg
2029e0146f7Smrg    /* mainly for debugging */
2039e0146f7Smrg    if ((domaindir = getenv ("TEXTDOMAINDIR")) == NULL) {
2049e0146f7Smrg	domaindir = LOCALEDIR;
2059e0146f7Smrg    }
2069e0146f7Smrg    bindtextdomain ("xfd", domaindir);
2079e0146f7Smrg#endif
2089e0146f7Smrg
2099e0146f7Smrg    Resources[0].default_addr = gettext(DEF_SELECT_FORMAT);
2109e0146f7Smrg    Resources[1].default_addr = gettext(DEF_METRICS_FORMAT);
2119e0146f7Smrg    Resources[2].default_addr = gettext(DEF_RANGE_FORMAT);
2129e0146f7Smrg    Resources[3].default_addr = gettext(DEF_START_FORMAT);
2139e0146f7Smrg    Resources[4].default_addr = gettext(DEF_NOCHAR_FORMAT);
2149e0146f7Smrg
215492e1cfeSmrg    if (argc != 1) usage ();
216492e1cfeSmrg    XtAppAddActions (xtcontext, xfd_actions, XtNumber (xfd_actions));
217492e1cfeSmrg    XtOverrideTranslations
218492e1cfeSmrg        (toplevel, XtParseTranslationTable ("<Message>WM_PROTOCOLS: Quit()"));
219492e1cfeSmrg
220492e1cfeSmrg    XtGetApplicationResources (toplevel, (XtPointer) &xfd_resources, Resources,
221492e1cfeSmrg			       XtNumber (Resources), NULL, ZERO);
222492e1cfeSmrg
223492e1cfeSmrg
224492e1cfeSmrg    /* pane wrapping everything */
225492e1cfeSmrg    pane = XtCreateManagedWidget ("pane", panedWidgetClass, toplevel,
226492e1cfeSmrg				  NULL, ZERO);
227492e1cfeSmrg
228492e1cfeSmrg    /* font name */
2293538fbe3Smrg    toplabel = XtCreateManagedWidget ("fontname", labelWidgetClass, pane,
230492e1cfeSmrg				      NULL, ZERO);
231492e1cfeSmrg
232492e1cfeSmrg    /* button box */
233492e1cfeSmrg    box = XtCreateManagedWidget ("box", boxWidgetClass, pane, NULL, ZERO);
234492e1cfeSmrg    quitButton = XtCreateManagedWidget ("quit", commandWidgetClass, box,
235492e1cfeSmrg					NULL, ZERO);
236492e1cfeSmrg    prev16Button = XtCreateManagedWidget ("prev16", commandWidgetClass, box,
237492e1cfeSmrg					NULL, ZERO);
238492e1cfeSmrg    prevButton = XtCreateManagedWidget ("prev", commandWidgetClass, box,
239492e1cfeSmrg					NULL, ZERO);
240492e1cfeSmrg    nextButton = XtCreateManagedWidget ("next", commandWidgetClass, box,
241492e1cfeSmrg					NULL, ZERO);
242492e1cfeSmrg    next16Button = XtCreateManagedWidget ("next16", commandWidgetClass, box,
243492e1cfeSmrg					NULL, ZERO);
244492e1cfeSmrg
245492e1cfeSmrg
246492e1cfeSmrg    /* and labels in which to put information */
247492e1cfeSmrg    selectLabel = XtCreateManagedWidget ("select", labelWidgetClass,
248492e1cfeSmrg					 pane, NULL, ZERO);
249492e1cfeSmrg
250492e1cfeSmrg    metricsLabel = XtCreateManagedWidget ("metrics", labelWidgetClass,
251492e1cfeSmrg					  pane, NULL, ZERO);
252492e1cfeSmrg
2533538fbe3Smrg    rangeLabel = XtCreateManagedWidget ("range", labelWidgetClass, pane,
254492e1cfeSmrg					NULL, ZERO);
255492e1cfeSmrg
2563538fbe3Smrg    startLabel = XtCreateManagedWidget ("start", labelWidgetClass, pane,
257492e1cfeSmrg					NULL, ZERO);
258492e1cfeSmrg
259492e1cfeSmrg    /* form in which to draw */
260492e1cfeSmrg    form = XtCreateManagedWidget ("form", formWidgetClass, pane, NULL, ZERO);
2613538fbe3Smrg
262492e1cfeSmrg    i = 0;
263492e1cfeSmrg    XtSetArg (av[i], XtNtop, XtChainTop); i++;
264492e1cfeSmrg    XtSetArg (av[i], XtNbottom, XtChainBottom); i++;
265492e1cfeSmrg    XtSetArg (av[i], XtNleft, XtChainLeft); i++;
266492e1cfeSmrg    XtSetArg (av[i], XtNright, XtChainRight); i++;
267492e1cfeSmrg    XtSetArg (av[i], XtNcallback, cb); i++;
268492e1cfeSmrg
2693538fbe3Smrg    oldWarningHandler = XtAppSetWarningMsgHandler(xtcontext,
270492e1cfeSmrg						  CatchFontConversionWarning);
271492e1cfeSmrg
272492e1cfeSmrg    fontGrid = XtCreateManagedWidget ("grid", fontgridWidgetClass, form,
273492e1cfeSmrg				      av, i);
274492e1cfeSmrg
275492e1cfeSmrg    XtAppSetWarningMsgHandler(xtcontext, oldWarningHandler);
276492e1cfeSmrg
277492e1cfeSmrg    /* set the label at the top to tell us which font this is */
278492e1cfeSmrg#ifdef XRENDER
279492e1cfeSmrg    i = 0;
280492e1cfeSmrg    XtSetArg (av[i], XtNface, &xft); i++;
281492e1cfeSmrg    XtGetValues (fontGrid, av, i);
282492e1cfeSmrg    if (xft)
283492e1cfeSmrg    {
284492e1cfeSmrg	FcChar8	*family;
285492e1cfeSmrg	FcChar8	*style;
286492e1cfeSmrg	FcPattern   *p;
287492e1cfeSmrg	double	size;
288492e1cfeSmrg	family = (FcChar8 *) "";
289492e1cfeSmrg	FcPatternGetString (xft->pattern, FC_FAMILY, 0, &family);
290492e1cfeSmrg	style = (FcChar8 *) "";
291492e1cfeSmrg	FcPatternGetString (xft->pattern, FC_STYLE, 0, &style);
292492e1cfeSmrg	size = 0;
293492e1cfeSmrg	FcPatternGetDouble (xft->pattern, FC_SIZE, 0, &size);
2949e0146f7Smrg	p = FcPatternBuild (NULL,
295492e1cfeSmrg			    FC_FAMILY, FcTypeString, family,
296492e1cfeSmrg			    FC_STYLE, FcTypeString, style,
297492e1cfeSmrg			    FC_SIZE, FcTypeDouble, size,
298492e1cfeSmrg			    NULL);
299492e1cfeSmrg	fontname = (char *) FcNameUnparse (p);
300492e1cfeSmrg	FcPatternDestroy (p);
301492e1cfeSmrg    }
302492e1cfeSmrg    else
303492e1cfeSmrg#endif
304492e1cfeSmrg    {
305492e1cfeSmrg	i = 0;
306492e1cfeSmrg	XtSetArg (av[i], XtNfont, &fs); i++;
307492e1cfeSmrg	XtGetValues (fontGrid, av, i);
308492e1cfeSmrg	if (!fs || fontConversionFailed) {
3099e0146f7Smrg	    fprintf (stderr, gettext("%s:  no font to display\n"), ProgramName);
310492e1cfeSmrg	    exit (1);
311492e1cfeSmrg	}
312492e1cfeSmrg	fontname = get_font_name (XtDisplay(toplevel), fs);
3139e0146f7Smrg	if (!fontname) fontname = gettext("unknown font!");
314492e1cfeSmrg    }
315492e1cfeSmrg    i = 0;
316492e1cfeSmrg    XtSetArg (av[i], XtNlabel, fontname); i++;
317492e1cfeSmrg    XtSetValues (toplabel, av, i);
318492e1cfeSmrg
319492e1cfeSmrg    minn = GridFirstChar (fontGrid);
320492e1cfeSmrg    maxn = GridLastChar (fontGrid);
3213538fbe3Smrg    sprintf (buf, xfd_resources.range_format,
322492e1cfeSmrg	     minn >> 8, minn & 0xff,
323492e1cfeSmrg	     minn >> 8, minn & 0xff,
324492e1cfeSmrg	     maxn >> 8, maxn & 0xff,
325492e1cfeSmrg	     maxn >> 8, maxn & 0xff);
3263538fbe3Smrg
327492e1cfeSmrg    i = 0;
328492e1cfeSmrg    XtSetArg (av[i], XtNlabel, buf); i++;
329492e1cfeSmrg    XtSetValues (rangeLabel, av, i);
330492e1cfeSmrg
331492e1cfeSmrg    XtRealizeWidget (toplevel);
332492e1cfeSmrg
333492e1cfeSmrg    wm_delete_window = XInternAtom(XtDisplay(toplevel), "WM_DELETE_WINDOW",
334492e1cfeSmrg                                   False);
335492e1cfeSmrg    (void) XSetWMProtocols (XtDisplay(toplevel), XtWindow(toplevel),
336492e1cfeSmrg                            &wm_delete_window, 1);
337492e1cfeSmrg
338492e1cfeSmrg    change_page (0);
339492e1cfeSmrg    XtAppMainLoop (xtcontext);
340492e1cfeSmrg    exit(0);
341492e1cfeSmrg}
342492e1cfeSmrg
343492e1cfeSmrg/*ARGSUSED*/
3443538fbe3Smrgstatic void
345492e1cfeSmrgSelectChar(Widget w, XtPointer closure, XtPointer data)
346492e1cfeSmrg{
347492e1cfeSmrg    FontGridCharRec *p = (FontGridCharRec *) data;
348492e1cfeSmrg    XFontStruct *fs = p->thefont;
349492e1cfeSmrg    long n = p->thechar;
350492e1cfeSmrg    int direction, fontascent, fontdescent;
351492e1cfeSmrg    XCharStruct metrics;
352492e1cfeSmrg    char buf[256];
353492e1cfeSmrg    Arg arg;
354492e1cfeSmrg    Boolean has_char = 1;
355492e1cfeSmrg
356492e1cfeSmrg    XtSetArg (arg, XtNlabel, buf);
357492e1cfeSmrg
358492e1cfeSmrg    buf[0] = '\0';
359492e1cfeSmrg#ifdef XRENDER
360492e1cfeSmrg    if (p->theface)
361492e1cfeSmrg    {
362492e1cfeSmrg	XftFont	*xft = p->theface;
363492e1cfeSmrg	FcChar32    c = (FcChar32) n;
364492e1cfeSmrg	has_char = (Boolean) FcCharSetHasChar (xft->charset, n);
365492e1cfeSmrg	if (has_char)
366492e1cfeSmrg	{
367492e1cfeSmrg	    XGlyphInfo	extents;
368492e1cfeSmrg	    XftTextExtents32 (XtDisplay (w), xft, &c, 1, &extents);
369492e1cfeSmrg	    sprintf (buf, xfd_resources.metrics_format,
3703538fbe3Smrg		     extents.xOff, - extents.x,
371492e1cfeSmrg		     extents.xOff - extents.width + extents.x,
372492e1cfeSmrg		     extents.y, extents.height - extents.y,
373492e1cfeSmrg		     xft->ascent, xft->descent);
374492e1cfeSmrg	}
375492e1cfeSmrg    }
376492e1cfeSmrg    else
377492e1cfeSmrg#endif
378492e1cfeSmrg    {
379492e1cfeSmrg	if ((!fs->min_byte1 && !fs->max_byte1) ?
380492e1cfeSmrg	    (n < fs->min_char_or_byte2 || n > fs->max_char_or_byte2) :
381492e1cfeSmrg	    (n >> 8 < fs->min_byte1 || n >> 8 > fs->max_byte1 ||
382492e1cfeSmrg	     (n & 0xff)  < fs->min_char_or_byte2 ||
3833538fbe3Smrg	     (n & 0xff) > fs->max_char_or_byte2))
384492e1cfeSmrg	{
385492e1cfeSmrg	    has_char = 0;
386492e1cfeSmrg	}
387492e1cfeSmrg	else
388492e1cfeSmrg	{
389492e1cfeSmrg	    XChar2b char2b;
390492e1cfeSmrg	    char2b.byte1 = p->thechar >> 8;
391492e1cfeSmrg	    char2b.byte2 = p->thechar & 0xff;
392492e1cfeSmrg	    XTextExtents16 (fs, &char2b, 1, &direction, &fontascent, &fontdescent,
393492e1cfeSmrg			    &metrics);
394492e1cfeSmrg	    sprintf (buf, xfd_resources.metrics_format,
395492e1cfeSmrg		     metrics.width, metrics.lbearing, metrics.rbearing,
396492e1cfeSmrg		     metrics.ascent, metrics.descent, fontascent, fontdescent);
397492e1cfeSmrg	}
398492e1cfeSmrg    }
399492e1cfeSmrg    XtSetValues (metricsLabel, &arg, ONE);
400492e1cfeSmrg
401492e1cfeSmrg    if (has_char)
402492e1cfeSmrg    {
4033538fbe3Smrg	sprintf (buf, xfd_resources.select_format,
404492e1cfeSmrg		 n >> 8, n & 0xff,
405492e1cfeSmrg		 n >> 8, n & 0xff,
406492e1cfeSmrg		 n >> 8, n & 0xff);
407492e1cfeSmrg    }
408492e1cfeSmrg    else
409492e1cfeSmrg    {
410492e1cfeSmrg	    sprintf (buf, xfd_resources.nochar_format,
411492e1cfeSmrg		     n >> 8, n & 0xff,
412492e1cfeSmrg		     n >> 8, n & 0xff,
413492e1cfeSmrg		     n >> 8, n & 0xff);
414492e1cfeSmrg    }
415492e1cfeSmrg    XtSetValues (selectLabel, &arg, ONE);
416492e1cfeSmrg
417492e1cfeSmrg    return;
418492e1cfeSmrg}
419492e1cfeSmrg
420492e1cfeSmrg
421492e1cfeSmrg/*ARGSUSED*/
4223538fbe3Smrgstatic void
423492e1cfeSmrgdo_quit (Widget w, XEvent *event, String *params, Cardinal *num_params)
424492e1cfeSmrg{
425492e1cfeSmrg    exit (0);
426492e1cfeSmrg}
427492e1cfeSmrg
4283538fbe3Smrgstatic void
429492e1cfeSmrgchange_page(int page)
430492e1cfeSmrg{
431492e1cfeSmrg    long oldstart, newstart;
432492e1cfeSmrg    int ncols, nrows;
433492e1cfeSmrg    char buf[256];
434492e1cfeSmrg    Arg arg;
435492e1cfeSmrg
436492e1cfeSmrg    arg.name = XtNstartChar;
437492e1cfeSmrg    GetFontGridCellDimensions (fontGrid, &oldstart, &ncols, &nrows);
438492e1cfeSmrg
439492e1cfeSmrg    if (page) {
4403538fbe3Smrg	long start = (oldstart +
441492e1cfeSmrg			   ((long) ncols) * ((long) nrows) * ((long) page));
442492e1cfeSmrg
443492e1cfeSmrg	arg.value = (XtArgVal) start;
444492e1cfeSmrg	XtSetValues (fontGrid, &arg, ONE);
445492e1cfeSmrg    }
446492e1cfeSmrg
447492e1cfeSmrg    /* find out what it got set to */
448492e1cfeSmrg    arg.value = (XtArgVal) &newstart;
449492e1cfeSmrg    XtGetValues (fontGrid, &arg, ONE);
450492e1cfeSmrg
451492e1cfeSmrg    /* if not paging, then initialize it, else only do it actually changed */
452492e1cfeSmrg    if (!page || newstart != oldstart) {
453492e1cfeSmrg	unsigned int row = (unsigned int) ((newstart >> 8));
454492e1cfeSmrg	unsigned int col = (unsigned int) (newstart & 0xff);
455492e1cfeSmrg
456492e1cfeSmrg	XtSetArg (arg, XtNlabel, buf);
457492e1cfeSmrg	sprintf (buf, xfd_resources.start_format, newstart, row, col);
458492e1cfeSmrg	XtSetValues (startLabel, &arg, ONE);
459492e1cfeSmrg    }
460492e1cfeSmrg
461492e1cfeSmrg    set_button_state ();
462492e1cfeSmrg
463492e1cfeSmrg    return;
464492e1cfeSmrg}
465492e1cfeSmrg
466492e1cfeSmrg
4673538fbe3Smrgstatic void
468492e1cfeSmrgset_button_state(void)
469492e1cfeSmrg{
470492e1cfeSmrg    Bool prevvalid, nextvalid, prev16valid, next16valid;
471492e1cfeSmrg    Arg arg;
472492e1cfeSmrg
473492e1cfeSmrg    GetPrevNextStates (fontGrid, &prevvalid, &nextvalid, &prev16valid, &next16valid);
474492e1cfeSmrg    arg.name = XtNsensitive;
475492e1cfeSmrg    arg.value = (XtArgVal) (prevvalid ? TRUE : FALSE);
476492e1cfeSmrg    XtSetValues (prevButton, &arg, ONE);
477492e1cfeSmrg    arg.value = (XtArgVal) (nextvalid ? TRUE : FALSE);
478492e1cfeSmrg    XtSetValues (nextButton, &arg, ONE);
479492e1cfeSmrg    arg.name = XtNsensitive;
480492e1cfeSmrg    arg.value = (XtArgVal) (prev16valid ? TRUE : FALSE);
481492e1cfeSmrg    XtSetValues (prev16Button, &arg, ONE);
482492e1cfeSmrg    arg.value = (XtArgVal) (next16valid ? TRUE : FALSE);
483492e1cfeSmrg    XtSetValues (next16Button, &arg, ONE);
484492e1cfeSmrg}
485492e1cfeSmrg
486492e1cfeSmrg
487492e1cfeSmrg/* ARGSUSED */
4883538fbe3Smrgstatic void
489492e1cfeSmrgdo_prev16(Widget w, XEvent *event, String *params, Cardinal *num_params)
490492e1cfeSmrg{
491492e1cfeSmrg    change_page (-16);
492492e1cfeSmrg}
493492e1cfeSmrg
494492e1cfeSmrg
4953538fbe3Smrgstatic void
496492e1cfeSmrgdo_prev(Widget w, XEvent *event, String *params, Cardinal *num_params)
497492e1cfeSmrg{
498492e1cfeSmrg    change_page (-1);
499492e1cfeSmrg}
500492e1cfeSmrg
501492e1cfeSmrg
502492e1cfeSmrg/* ARGSUSED */
5033538fbe3Smrgstatic void
504492e1cfeSmrgdo_next(Widget w, XEvent *event, String *params, Cardinal *num_params)
505492e1cfeSmrg{
506492e1cfeSmrg    change_page (1);
507492e1cfeSmrg}
508492e1cfeSmrg
509492e1cfeSmrg/* ARGSUSED */
5103538fbe3Smrgstatic void
511492e1cfeSmrgdo_next16(Widget w, XEvent *event, String *params, Cardinal *num_params)
512492e1cfeSmrg{
513492e1cfeSmrg    change_page (16);
514492e1cfeSmrg}
515492e1cfeSmrg
516492e1cfeSmrg
517492e1cfeSmrgstatic char *
518492e1cfeSmrgget_font_name(Display *dpy, XFontStruct *fs)
519492e1cfeSmrg{
520492e1cfeSmrg    register XFontProp *fp;
521492e1cfeSmrg    register int i;
522492e1cfeSmrg    Atom fontatom = XInternAtom (dpy, "FONT", False);
523492e1cfeSmrg
524492e1cfeSmrg    for (i = 0, fp = fs->properties; i < fs->n_properties; i++, fp++) {
525492e1cfeSmrg	if (fp->name == fontatom) {
526492e1cfeSmrg	    return (XGetAtomName (dpy, fp->card32));
527492e1cfeSmrg	}
528492e1cfeSmrg    }
529492e1cfeSmrg    return NULL;
530492e1cfeSmrg}
531492e1cfeSmrg
532492e1cfeSmrg
5333538fbe3Smrgstatic void
5343538fbe3SmrgCatchFontConversionWarning(String name, String type, String class,
535492e1cfeSmrg			   String defaultp, String *params, Cardinal *np)
536492e1cfeSmrg{
537492e1cfeSmrg    if (np && *np > 1 &&
538492e1cfeSmrg	strcmp(name, "conversionError") == 0 &&
539492e1cfeSmrg	strcmp(type, "string") == 0 &&
540492e1cfeSmrg	strcmp(class, "XtToolkitError") == 0 &&
541492e1cfeSmrg	strcmp(params[1], "FontStruct") == 0) fontConversionFailed = True;
542492e1cfeSmrg
543492e1cfeSmrg    (*oldWarningHandler)(name, type, class, defaultp, params, np);
544492e1cfeSmrg}
545