1492e1cfeSmrg/*
2492e1cfeSmrg *
33538fbe3Smrg *
4492e1cfeSmrgCopyright 1989, 1998  The Open Group
5492e1cfeSmrg
6492e1cfeSmrgPermission to use, copy, modify, distribute, and sell this software and its
7492e1cfeSmrgdocumentation for any purpose is hereby granted without fee, provided that
8492e1cfeSmrgthe above copyright notice appear in all copies and that both that
9492e1cfeSmrgcopyright notice and this permission notice appear in supporting
10492e1cfeSmrgdocumentation.
11492e1cfeSmrg
12492e1cfeSmrgThe above copyright notice and this permission notice shall be included in
13492e1cfeSmrgall copies or substantial portions of the Software.
14492e1cfeSmrg
15492e1cfeSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16492e1cfeSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17492e1cfeSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
18492e1cfeSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19492e1cfeSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20492e1cfeSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21492e1cfeSmrg
22492e1cfeSmrgExcept as contained in this notice, the name of The Open Group shall not be
23492e1cfeSmrgused in advertising or otherwise to promote the sale, use or other dealings
24492e1cfeSmrgin this Software without prior written authorization from The Open Group.
25492e1cfeSmrg * *
26492e1cfeSmrg * Author:  Jim Fulton, MIT X Consortium
27492e1cfeSmrg */
28492e1cfeSmrg
299e0146f7Smrg#ifdef HAVE_CONFIG_H
309e0146f7Smrg# include "config.h"
319e0146f7Smrg#endif
329e0146f7Smrg
3331e5d586Smrg#include <X11/Xfuncproto.h>
34492e1cfeSmrg#include <X11/Intrinsic.h>
35492e1cfeSmrg#include <X11/StringDefs.h>
36492e1cfeSmrg#include <X11/Xos.h>
37492e1cfeSmrg#include <X11/Xatom.h>
38492e1cfeSmrg#include <X11/Shell.h>
39492e1cfeSmrg#include <X11/Xaw/Cardinals.h>
40492e1cfeSmrg#include <X11/Xaw/Paned.h>
41492e1cfeSmrg#include <X11/Xaw/Box.h>
42492e1cfeSmrg#include <X11/Xaw/Form.h>
43492e1cfeSmrg#include <X11/Xaw/Command.h>
44492e1cfeSmrg#include <stdio.h>
45492e1cfeSmrg#include <stdlib.h>
469e0146f7Smrg#ifdef USE_GETTEXT
479e0146f7Smrg# include <X11/Xlocale.h>
489e0146f7Smrg# include <libintl.h>
499e0146f7Smrg#else
509e0146f7Smrg# define gettext(a) (a)
519e0146f7Smrg#endif
52492e1cfeSmrg#include "grid.h"
53492e1cfeSmrg#ifdef XRENDER
54492e1cfeSmrg#include <X11/Xft/Xft.h>
55492e1cfeSmrg#include <X11/extensions/Xrender.h>
56492e1cfeSmrg#endif
57492e1cfeSmrg
589e0146f7Smrgstatic char *ProgramName;
59492e1cfeSmrg
60492e1cfeSmrgstatic XrmOptionDescRec xfd_options[] = {
61492e1cfeSmrg{"-fn",		"*grid.font",	XrmoptionSepArg,	(caddr_t) NULL },
62492e1cfeSmrg#ifdef XRENDER
63492e1cfeSmrg{"-fa",		"*grid.face", XrmoptionSepArg,		(caddr_t) NULL },
64492e1cfeSmrg#endif
65492e1cfeSmrg{"-start",	"*startChar",	XrmoptionSepArg, 	(caddr_t) NULL },
66492e1cfeSmrg{"-box",	"*grid.boxChars", XrmoptionNoArg,	(caddr_t) "on" },
67492e1cfeSmrg{"-bc",		"*grid.boxColor", XrmoptionSepArg, 	(caddr_t) NULL },
68492e1cfeSmrg{"-center",	"*grid.centerChars", XrmoptionNoArg,	(caddr_t) "on" },
69492e1cfeSmrg{"-rows",	"*grid.cellRows", XrmoptionSepArg,	(caddr_t) NULL },
70492e1cfeSmrg{"-columns",	"*grid.cellColumns", XrmoptionSepArg,	(caddr_t) NULL },
71492e1cfeSmrg};
72492e1cfeSmrg
7331e5d586Smrgstatic void usage(void) _X_NORETURN _X_COLD;
74492e1cfeSmrgstatic void SelectChar(Widget w, XtPointer closure, XtPointer data);
753538fbe3Smrgstatic void do_quit(Widget w, XEvent *event, String *params,
761afad795Smrg		    Cardinal *num_params) _X_NORETURN;
77492e1cfeSmrgstatic void change_page(int page);
78492e1cfeSmrgstatic void set_button_state(void);
793538fbe3Smrgstatic void do_prev(Widget w, XEvent *event, String *params,
80492e1cfeSmrg		    Cardinal *num_params);
813538fbe3Smrgstatic void do_next(Widget w, XEvent *event, String *params,
82492e1cfeSmrg		    Cardinal *num_params);
833538fbe3Smrgstatic void do_prev16(Widget w, XEvent *event, String *params,
84492e1cfeSmrg		      Cardinal *num_params);
853538fbe3Smrgstatic void do_next16(Widget w, XEvent *event, String *params,
86492e1cfeSmrg		      Cardinal *num_params);
87492e1cfeSmrgstatic char *get_font_name(Display *dpy, XFontStruct *fs);
883538fbe3Smrgstatic void CatchFontConversionWarning(String name, String type, String class,
893538fbe3Smrg				       String defaultp, String *params,
90492e1cfeSmrg				       Cardinal *np);
91492e1cfeSmrg
92492e1cfeSmrgstatic XtActionsRec xfd_actions[] = {
93492e1cfeSmrg  { "Quit", do_quit },
94492e1cfeSmrg  { "Prev16", do_prev16 },
95492e1cfeSmrg  { "Prev", do_prev },
96492e1cfeSmrg  { "Next", do_next },
97492e1cfeSmrg  { "Next16", do_next16 },
98492e1cfeSmrg};
99492e1cfeSmrg
100492e1cfeSmrgstatic Atom wm_delete_window;
101492e1cfeSmrg
1029e0146f7Smrgstatic Widget quitButton, prev16Button, prevButton, nextButton, next16Button;
103492e1cfeSmrg
104492e1cfeSmrg
105492e1cfeSmrg#define DEF_SELECT_FORMAT "character 0x%04x%02x (%u,%u) (%#o,%#o)"
106492e1cfeSmrg#define DEF_METRICS_FORMAT "width %d; left %d, right %d; ascent %d, descent %d (font %d, %d)"
107492e1cfeSmrg#define DEF_RANGE_FORMAT "range:  0x%04x%02x (%u,%u) thru 0x%04x%02x (%u,%u)"
108492e1cfeSmrg#define DEF_START_FORMAT "upper left:  0x%06x (%d,%d)"
109492e1cfeSmrg#define DEF_NOCHAR_FORMAT "no such character 0x%04x%02x (%u,%u) (%#o,%#o)"
110492e1cfeSmrg
111492e1cfeSmrgstatic struct _xfd_resources {
112492e1cfeSmrg  char *select_format;
113492e1cfeSmrg  char *metrics_format;
114492e1cfeSmrg  char *range_format;
115492e1cfeSmrg  char *start_format;
116492e1cfeSmrg  char *nochar_format;
117492e1cfeSmrg} xfd_resources;
118492e1cfeSmrg
119492e1cfeSmrg#define Offset(field) XtOffsetOf(struct _xfd_resources, field)
120492e1cfeSmrg
121492e1cfeSmrgstatic XtResource Resources[] = {
1223538fbe3Smrg  { "selectFormat", "SelectFormat", XtRString, sizeof(char *),
123492e1cfeSmrg      Offset(select_format), XtRString, DEF_SELECT_FORMAT },
1243538fbe3Smrg  { "metricsFormat", "MetricsFormat", XtRString, sizeof(char *),
125492e1cfeSmrg      Offset(metrics_format), XtRString, DEF_METRICS_FORMAT },
1263538fbe3Smrg  { "rangeFormat", "RangeFormat", XtRString, sizeof(char *),
127492e1cfeSmrg      Offset(range_format), XtRString, DEF_RANGE_FORMAT },
1283538fbe3Smrg  { "startFormat", "StartFormat", XtRString, sizeof(char *),
129492e1cfeSmrg      Offset(start_format), XtRString, DEF_START_FORMAT },
1303538fbe3Smrg  { "nocharFormat", "NocharFormat", XtRString, sizeof(char *),
131492e1cfeSmrg      Offset(nochar_format), XtRString, DEF_NOCHAR_FORMAT },
132492e1cfeSmrg};
133492e1cfeSmrg
134492e1cfeSmrg#undef Offset
135492e1cfeSmrg
136492e1cfeSmrgstatic void
137492e1cfeSmrgusage(void)
138492e1cfeSmrg{
1399e0146f7Smrg    fprintf (stderr, gettext("usage:  %s [-options ...] "), ProgramName);
1409e0146f7Smrg    fprintf (stderr, "-fn ");
1419e0146f7Smrg    fprintf (stderr, gettext("font\n\n"));
142492e1cfeSmrg#ifdef XRENDER
1439e0146f7Smrg    fprintf (stderr, gettext("        %s [-options ...] "), ProgramName);
1449e0146f7Smrg    fprintf (stderr, "-fa ");
1459e0146f7Smrg    fprintf (stderr, gettext("font\n\n"));
146492e1cfeSmrg#endif
1479e0146f7Smrg    fprintf (stderr, gettext("where options include:\n"));
1489e0146f7Smrg    fprintf (stderr, "    -display ");
1499e0146f7Smrg    fprintf (stderr, gettext("display       X server to contact\n"));
1509e0146f7Smrg    fprintf (stderr, "    -geometry ");
1519e0146f7Smrg    fprintf (stderr, gettext("geometry     size and location of window\n"));
1529e0146f7Smrg    fprintf (stderr, "    -bc ");
1539e0146f7Smrg    fprintf (stderr, gettext("color              color for ImageText boxes\n"));
1549e0146f7Smrg    fprintf (stderr, "    -start ");
1559e0146f7Smrg    fprintf (stderr, gettext("number          first character to show\n"));
1569e0146f7Smrg    fprintf (stderr, "    -box                   ");
1579e0146f7Smrg    fprintf (stderr, gettext("show a box around each character\n"));
1589e0146f7Smrg    fprintf (stderr, "    -center                ");
1599e0146f7Smrg    fprintf (stderr, gettext("center each character inside its grid\n"));
1609e0146f7Smrg    fprintf (stderr, "    -rows ");
1619e0146f7Smrg    fprintf (stderr, gettext("number           number of rows in grid\n"));
1629e0146f7Smrg    fprintf (stderr, "    -columns ");
1639e0146f7Smrg    fprintf (stderr, gettext("number        number of columns in grid\n"));
164492e1cfeSmrg    exit (1);
165492e1cfeSmrg}
166492e1cfeSmrg
167492e1cfeSmrg
168492e1cfeSmrgstatic Widget selectLabel, metricsLabel, rangeLabel, startLabel, fontGrid;
169492e1cfeSmrg
170492e1cfeSmrgstatic Boolean fontConversionFailed = False;
171492e1cfeSmrgstatic XtErrorMsgHandler oldWarningHandler;
172492e1cfeSmrg
173492e1cfeSmrgint
1743538fbe3Smrgmain(int argc, char *argv[])
175492e1cfeSmrg{
176492e1cfeSmrg    XtAppContext xtcontext;
177492e1cfeSmrg    Widget toplevel, pane, toplabel, box, form;
178492e1cfeSmrg    char buf[256];
179492e1cfeSmrg    Arg av[10];
180492e1cfeSmrg    Cardinal i;
181492e1cfeSmrg    static XtCallbackRec cb[2] = { { SelectChar, NULL }, { NULL, NULL } };
182492e1cfeSmrg    XFontStruct *fs;
183492e1cfeSmrg#ifdef XRENDER
184492e1cfeSmrg    XftFont *xft;
185492e1cfeSmrg#endif
186492e1cfeSmrg    char *fontname;
187492e1cfeSmrg    long minn, maxn;
188492e1cfeSmrg
1899e0146f7Smrg    XtSetLanguageProc(NULL, NULL, NULL);
1909e0146f7Smrg
191492e1cfeSmrg    ProgramName = argv[0];
192492e1cfeSmrg
193492e1cfeSmrg    toplevel = XtAppInitialize (&xtcontext, "Xfd",
194492e1cfeSmrg				xfd_options, XtNumber(xfd_options),
195492e1cfeSmrg				&argc, argv, NULL, NULL, 0);
1969e0146f7Smrg
1979e0146f7Smrg#ifdef USE_GETTEXT
198b78bb896Smrg    {
199b78bb896Smrg	const char *domaindir;
2009e0146f7Smrg
201b78bb896Smrg	textdomain("xfd");
202b78bb896Smrg
203b78bb896Smrg        /* mainly for debugging */
204b78bb896Smrg	if ((domaindir = getenv ("TEXTDOMAINDIR")) == NULL) {
205b78bb896Smrg	    domaindir = LOCALEDIR;
206b78bb896Smrg	}
207b78bb896Smrg	bindtextdomain ("xfd", domaindir);
2089e0146f7Smrg    }
2099e0146f7Smrg#endif
2109e0146f7Smrg
2119e0146f7Smrg    Resources[0].default_addr = gettext(DEF_SELECT_FORMAT);
2129e0146f7Smrg    Resources[1].default_addr = gettext(DEF_METRICS_FORMAT);
2139e0146f7Smrg    Resources[2].default_addr = gettext(DEF_RANGE_FORMAT);
2149e0146f7Smrg    Resources[3].default_addr = gettext(DEF_START_FORMAT);
2159e0146f7Smrg    Resources[4].default_addr = gettext(DEF_NOCHAR_FORMAT);
2169e0146f7Smrg
217492e1cfeSmrg    if (argc != 1) usage ();
218492e1cfeSmrg    XtAppAddActions (xtcontext, xfd_actions, XtNumber (xfd_actions));
219492e1cfeSmrg    XtOverrideTranslations
220492e1cfeSmrg        (toplevel, XtParseTranslationTable ("<Message>WM_PROTOCOLS: Quit()"));
221492e1cfeSmrg
222492e1cfeSmrg    XtGetApplicationResources (toplevel, (XtPointer) &xfd_resources, Resources,
223492e1cfeSmrg			       XtNumber (Resources), NULL, ZERO);
224492e1cfeSmrg
225492e1cfeSmrg
226492e1cfeSmrg    /* pane wrapping everything */
227492e1cfeSmrg    pane = XtCreateManagedWidget ("pane", panedWidgetClass, toplevel,
228492e1cfeSmrg				  NULL, ZERO);
229492e1cfeSmrg
230492e1cfeSmrg    /* font name */
2313538fbe3Smrg    toplabel = XtCreateManagedWidget ("fontname", labelWidgetClass, pane,
232492e1cfeSmrg				      NULL, ZERO);
233492e1cfeSmrg
234492e1cfeSmrg    /* button box */
235492e1cfeSmrg    box = XtCreateManagedWidget ("box", boxWidgetClass, pane, NULL, ZERO);
236492e1cfeSmrg    quitButton = XtCreateManagedWidget ("quit", commandWidgetClass, box,
237492e1cfeSmrg					NULL, ZERO);
238492e1cfeSmrg    prev16Button = XtCreateManagedWidget ("prev16", commandWidgetClass, box,
239492e1cfeSmrg					NULL, ZERO);
240492e1cfeSmrg    prevButton = XtCreateManagedWidget ("prev", commandWidgetClass, box,
241492e1cfeSmrg					NULL, ZERO);
242492e1cfeSmrg    nextButton = XtCreateManagedWidget ("next", commandWidgetClass, box,
243492e1cfeSmrg					NULL, ZERO);
244492e1cfeSmrg    next16Button = XtCreateManagedWidget ("next16", commandWidgetClass, box,
245492e1cfeSmrg					NULL, ZERO);
246492e1cfeSmrg
247492e1cfeSmrg
248492e1cfeSmrg    /* and labels in which to put information */
249492e1cfeSmrg    selectLabel = XtCreateManagedWidget ("select", labelWidgetClass,
250492e1cfeSmrg					 pane, NULL, ZERO);
251492e1cfeSmrg
252492e1cfeSmrg    metricsLabel = XtCreateManagedWidget ("metrics", labelWidgetClass,
253492e1cfeSmrg					  pane, NULL, ZERO);
254492e1cfeSmrg
2553538fbe3Smrg    rangeLabel = XtCreateManagedWidget ("range", labelWidgetClass, pane,
256492e1cfeSmrg					NULL, ZERO);
257492e1cfeSmrg
2583538fbe3Smrg    startLabel = XtCreateManagedWidget ("start", labelWidgetClass, pane,
259492e1cfeSmrg					NULL, ZERO);
260492e1cfeSmrg
261492e1cfeSmrg    /* form in which to draw */
262492e1cfeSmrg    form = XtCreateManagedWidget ("form", formWidgetClass, pane, NULL, ZERO);
2633538fbe3Smrg
264492e1cfeSmrg    i = 0;
265492e1cfeSmrg    XtSetArg (av[i], XtNtop, XtChainTop); i++;
266492e1cfeSmrg    XtSetArg (av[i], XtNbottom, XtChainBottom); i++;
267492e1cfeSmrg    XtSetArg (av[i], XtNleft, XtChainLeft); i++;
268492e1cfeSmrg    XtSetArg (av[i], XtNright, XtChainRight); i++;
269492e1cfeSmrg    XtSetArg (av[i], XtNcallback, cb); i++;
270492e1cfeSmrg
2713538fbe3Smrg    oldWarningHandler = XtAppSetWarningMsgHandler(xtcontext,
272492e1cfeSmrg						  CatchFontConversionWarning);
273492e1cfeSmrg
274492e1cfeSmrg    fontGrid = XtCreateManagedWidget ("grid", fontgridWidgetClass, form,
275492e1cfeSmrg				      av, i);
276492e1cfeSmrg
277492e1cfeSmrg    XtAppSetWarningMsgHandler(xtcontext, oldWarningHandler);
278492e1cfeSmrg
279492e1cfeSmrg    /* set the label at the top to tell us which font this is */
280492e1cfeSmrg#ifdef XRENDER
281492e1cfeSmrg    i = 0;
282492e1cfeSmrg    XtSetArg (av[i], XtNface, &xft); i++;
283492e1cfeSmrg    XtGetValues (fontGrid, av, i);
284492e1cfeSmrg    if (xft)
285492e1cfeSmrg    {
286492e1cfeSmrg	FcChar8	*family;
287492e1cfeSmrg	FcChar8	*style;
288492e1cfeSmrg	FcPattern   *p;
289492e1cfeSmrg	double	size;
290492e1cfeSmrg	family = (FcChar8 *) "";
291492e1cfeSmrg	FcPatternGetString (xft->pattern, FC_FAMILY, 0, &family);
292492e1cfeSmrg	style = (FcChar8 *) "";
293492e1cfeSmrg	FcPatternGetString (xft->pattern, FC_STYLE, 0, &style);
294492e1cfeSmrg	size = 0;
295492e1cfeSmrg	FcPatternGetDouble (xft->pattern, FC_SIZE, 0, &size);
2969e0146f7Smrg	p = FcPatternBuild (NULL,
297492e1cfeSmrg			    FC_FAMILY, FcTypeString, family,
298492e1cfeSmrg			    FC_STYLE, FcTypeString, style,
299492e1cfeSmrg			    FC_SIZE, FcTypeDouble, size,
300492e1cfeSmrg			    NULL);
301492e1cfeSmrg	fontname = (char *) FcNameUnparse (p);
302492e1cfeSmrg	FcPatternDestroy (p);
303492e1cfeSmrg    }
304492e1cfeSmrg    else
305492e1cfeSmrg#endif
306492e1cfeSmrg    {
307492e1cfeSmrg	i = 0;
308492e1cfeSmrg	XtSetArg (av[i], XtNfont, &fs); i++;
309492e1cfeSmrg	XtGetValues (fontGrid, av, i);
310492e1cfeSmrg	if (!fs || fontConversionFailed) {
3119e0146f7Smrg	    fprintf (stderr, gettext("%s:  no font to display\n"), ProgramName);
312492e1cfeSmrg	    exit (1);
313492e1cfeSmrg	}
314492e1cfeSmrg	fontname = get_font_name (XtDisplay(toplevel), fs);
3159e0146f7Smrg	if (!fontname) fontname = gettext("unknown font!");
316492e1cfeSmrg    }
317492e1cfeSmrg    i = 0;
318492e1cfeSmrg    XtSetArg (av[i], XtNlabel, fontname); i++;
319492e1cfeSmrg    XtSetValues (toplabel, av, i);
320492e1cfeSmrg
321492e1cfeSmrg    minn = GridFirstChar (fontGrid);
322492e1cfeSmrg    maxn = GridLastChar (fontGrid);
3231afad795Smrg    snprintf (buf, sizeof(buf), xfd_resources.range_format,
3241afad795Smrg	      minn >> 8, minn & 0xff,
3251afad795Smrg	      minn >> 8, minn & 0xff,
3261afad795Smrg	      maxn >> 8, maxn & 0xff,
3271afad795Smrg	      maxn >> 8, maxn & 0xff);
3283538fbe3Smrg
329492e1cfeSmrg    i = 0;
330492e1cfeSmrg    XtSetArg (av[i], XtNlabel, buf); i++;
331492e1cfeSmrg    XtSetValues (rangeLabel, av, i);
332492e1cfeSmrg
333492e1cfeSmrg    XtRealizeWidget (toplevel);
334492e1cfeSmrg
335492e1cfeSmrg    wm_delete_window = XInternAtom(XtDisplay(toplevel), "WM_DELETE_WINDOW",
336492e1cfeSmrg                                   False);
337492e1cfeSmrg    (void) XSetWMProtocols (XtDisplay(toplevel), XtWindow(toplevel),
338492e1cfeSmrg                            &wm_delete_window, 1);
339492e1cfeSmrg
340492e1cfeSmrg    change_page (0);
341492e1cfeSmrg    XtAppMainLoop (xtcontext);
342492e1cfeSmrg    exit(0);
343492e1cfeSmrg}
344492e1cfeSmrg
345492e1cfeSmrg/*ARGSUSED*/
3463538fbe3Smrgstatic void
34731e5d586SmrgSelectChar(Widget w, XtPointer closure _X_UNUSED, XtPointer data)
348492e1cfeSmrg{
349492e1cfeSmrg    FontGridCharRec *p = (FontGridCharRec *) data;
350492e1cfeSmrg    XFontStruct *fs = p->thefont;
351492e1cfeSmrg    long n = p->thechar;
352492e1cfeSmrg    int direction, fontascent, fontdescent;
353492e1cfeSmrg    XCharStruct metrics;
354492e1cfeSmrg    char buf[256];
355492e1cfeSmrg    Arg arg;
356492e1cfeSmrg    Boolean has_char = 1;
357492e1cfeSmrg
358492e1cfeSmrg    XtSetArg (arg, XtNlabel, buf);
359492e1cfeSmrg
360492e1cfeSmrg    buf[0] = '\0';
361492e1cfeSmrg#ifdef XRENDER
362492e1cfeSmrg    if (p->theface)
363492e1cfeSmrg    {
364492e1cfeSmrg	XftFont	*xft = p->theface;
365492e1cfeSmrg	FcChar32    c = (FcChar32) n;
366492e1cfeSmrg	has_char = (Boolean) FcCharSetHasChar (xft->charset, n);
367492e1cfeSmrg	if (has_char)
368492e1cfeSmrg	{
369492e1cfeSmrg	    XGlyphInfo	extents;
370492e1cfeSmrg	    XftTextExtents32 (XtDisplay (w), xft, &c, 1, &extents);
3711afad795Smrg	    snprintf (buf, sizeof(buf), xfd_resources.metrics_format,
3721afad795Smrg		      extents.xOff, - extents.x,
3731afad795Smrg		      extents.xOff - extents.width + extents.x,
3741afad795Smrg		      extents.y, extents.height - extents.y,
3751afad795Smrg		      xft->ascent, xft->descent);
376492e1cfeSmrg	}
377492e1cfeSmrg    }
378492e1cfeSmrg    else
379492e1cfeSmrg#endif
380492e1cfeSmrg    {
381492e1cfeSmrg	if ((!fs->min_byte1 && !fs->max_byte1) ?
382492e1cfeSmrg	    (n < fs->min_char_or_byte2 || n > fs->max_char_or_byte2) :
383492e1cfeSmrg	    (n >> 8 < fs->min_byte1 || n >> 8 > fs->max_byte1 ||
384492e1cfeSmrg	     (n & 0xff)  < fs->min_char_or_byte2 ||
3853538fbe3Smrg	     (n & 0xff) > fs->max_char_or_byte2))
386492e1cfeSmrg	{
387492e1cfeSmrg	    has_char = 0;
388492e1cfeSmrg	}
389492e1cfeSmrg	else
390492e1cfeSmrg	{
391492e1cfeSmrg	    XChar2b char2b;
392492e1cfeSmrg	    char2b.byte1 = p->thechar >> 8;
393492e1cfeSmrg	    char2b.byte2 = p->thechar & 0xff;
394492e1cfeSmrg	    XTextExtents16 (fs, &char2b, 1, &direction, &fontascent, &fontdescent,
395492e1cfeSmrg			    &metrics);
3961afad795Smrg	    snprintf (buf, sizeof(buf), xfd_resources.metrics_format,
3971afad795Smrg		      metrics.width, metrics.lbearing, metrics.rbearing,
3981afad795Smrg		      metrics.ascent, metrics.descent, fontascent, fontdescent);
399492e1cfeSmrg	}
400492e1cfeSmrg    }
401492e1cfeSmrg    XtSetValues (metricsLabel, &arg, ONE);
402492e1cfeSmrg
403492e1cfeSmrg    if (has_char)
404492e1cfeSmrg    {
4051afad795Smrg	snprintf (buf, sizeof(buf), xfd_resources.select_format,
4061afad795Smrg		  n >> 8, n & 0xff,
4071afad795Smrg		  n >> 8, n & 0xff,
4081afad795Smrg		  n >> 8, n & 0xff);
409492e1cfeSmrg    }
410492e1cfeSmrg    else
411492e1cfeSmrg    {
4121afad795Smrg	snprintf (buf, sizeof(buf), xfd_resources.nochar_format,
4131afad795Smrg		  n >> 8, n & 0xff,
4141afad795Smrg		  n >> 8, n & 0xff,
4151afad795Smrg		  n >> 8, n & 0xff);
416492e1cfeSmrg    }
417492e1cfeSmrg    XtSetValues (selectLabel, &arg, ONE);
418492e1cfeSmrg
419492e1cfeSmrg    return;
420492e1cfeSmrg}
421492e1cfeSmrg
422492e1cfeSmrg
423492e1cfeSmrg/*ARGSUSED*/
4243538fbe3Smrgstatic void
42531e5d586Smrgdo_quit (Widget w _X_UNUSED, XEvent *event _X_UNUSED,
42631e5d586Smrg	 String *params _X_UNUSED, Cardinal *num_params _X_UNUSED)
427492e1cfeSmrg{
428492e1cfeSmrg    exit (0);
429492e1cfeSmrg}
430492e1cfeSmrg
4313538fbe3Smrgstatic void
432492e1cfeSmrgchange_page(int page)
433492e1cfeSmrg{
434492e1cfeSmrg    long oldstart, newstart;
435492e1cfeSmrg    int ncols, nrows;
436492e1cfeSmrg    Arg arg;
437492e1cfeSmrg
438492e1cfeSmrg    arg.name = XtNstartChar;
439492e1cfeSmrg    GetFontGridCellDimensions (fontGrid, &oldstart, &ncols, &nrows);
440492e1cfeSmrg
441492e1cfeSmrg    if (page) {
4423538fbe3Smrg	long start = (oldstart +
443492e1cfeSmrg			   ((long) ncols) * ((long) nrows) * ((long) page));
444492e1cfeSmrg
445492e1cfeSmrg	arg.value = (XtArgVal) start;
446492e1cfeSmrg	XtSetValues (fontGrid, &arg, ONE);
447492e1cfeSmrg    }
448492e1cfeSmrg
449492e1cfeSmrg    /* find out what it got set to */
450492e1cfeSmrg    arg.value = (XtArgVal) &newstart;
451492e1cfeSmrg    XtGetValues (fontGrid, &arg, ONE);
452492e1cfeSmrg
453492e1cfeSmrg    /* if not paging, then initialize it, else only do it actually changed */
454492e1cfeSmrg    if (!page || newstart != oldstart) {
455492e1cfeSmrg	unsigned int row = (unsigned int) ((newstart >> 8));
456492e1cfeSmrg	unsigned int col = (unsigned int) (newstart & 0xff);
45731e5d586Smrg	char buf[256];
458492e1cfeSmrg
459492e1cfeSmrg	XtSetArg (arg, XtNlabel, buf);
4601afad795Smrg	snprintf (buf, sizeof(buf), xfd_resources.start_format,
4611afad795Smrg		  newstart, row, col);
462492e1cfeSmrg	XtSetValues (startLabel, &arg, ONE);
463492e1cfeSmrg    }
464492e1cfeSmrg
465492e1cfeSmrg    set_button_state ();
466492e1cfeSmrg
467492e1cfeSmrg    return;
468492e1cfeSmrg}
469492e1cfeSmrg
470492e1cfeSmrg
4713538fbe3Smrgstatic void
472492e1cfeSmrgset_button_state(void)
473492e1cfeSmrg{
474492e1cfeSmrg    Bool prevvalid, nextvalid, prev16valid, next16valid;
475492e1cfeSmrg    Arg arg;
476492e1cfeSmrg
477492e1cfeSmrg    GetPrevNextStates (fontGrid, &prevvalid, &nextvalid, &prev16valid, &next16valid);
478492e1cfeSmrg    arg.name = XtNsensitive;
479492e1cfeSmrg    arg.value = (XtArgVal) (prevvalid ? TRUE : FALSE);
480492e1cfeSmrg    XtSetValues (prevButton, &arg, ONE);
481492e1cfeSmrg    arg.value = (XtArgVal) (nextvalid ? TRUE : FALSE);
482492e1cfeSmrg    XtSetValues (nextButton, &arg, ONE);
483492e1cfeSmrg    arg.name = XtNsensitive;
484492e1cfeSmrg    arg.value = (XtArgVal) (prev16valid ? TRUE : FALSE);
485492e1cfeSmrg    XtSetValues (prev16Button, &arg, ONE);
486492e1cfeSmrg    arg.value = (XtArgVal) (next16valid ? TRUE : FALSE);
487492e1cfeSmrg    XtSetValues (next16Button, &arg, ONE);
488492e1cfeSmrg}
489492e1cfeSmrg
490492e1cfeSmrg
491492e1cfeSmrg/* ARGSUSED */
4923538fbe3Smrgstatic void
49331e5d586Smrgdo_prev16(Widget w _X_UNUSED, XEvent *event _X_UNUSED,
49431e5d586Smrg	  String *params _X_UNUSED, Cardinal *num_params _X_UNUSED)
495492e1cfeSmrg{
496492e1cfeSmrg    change_page (-16);
497492e1cfeSmrg}
498492e1cfeSmrg
499492e1cfeSmrg
5003538fbe3Smrgstatic void
50131e5d586Smrgdo_prev(Widget w _X_UNUSED, XEvent *event _X_UNUSED,
50231e5d586Smrg	String *params _X_UNUSED, Cardinal *num_params _X_UNUSED)
503492e1cfeSmrg{
504492e1cfeSmrg    change_page (-1);
505492e1cfeSmrg}
506492e1cfeSmrg
507492e1cfeSmrg
508492e1cfeSmrg/* ARGSUSED */
5093538fbe3Smrgstatic void
51031e5d586Smrgdo_next(Widget w _X_UNUSED, XEvent *event _X_UNUSED,
51131e5d586Smrg	String *params _X_UNUSED, Cardinal *num_params _X_UNUSED)
512492e1cfeSmrg{
513492e1cfeSmrg    change_page (1);
514492e1cfeSmrg}
515492e1cfeSmrg
516492e1cfeSmrg/* ARGSUSED */
5173538fbe3Smrgstatic void
51831e5d586Smrgdo_next16(Widget w _X_UNUSED, XEvent *event _X_UNUSED,
51931e5d586Smrg	  String *params _X_UNUSED, Cardinal *num_params _X_UNUSED)
520492e1cfeSmrg{
521492e1cfeSmrg    change_page (16);
522492e1cfeSmrg}
523492e1cfeSmrg
524492e1cfeSmrg
525492e1cfeSmrgstatic char *
526492e1cfeSmrgget_font_name(Display *dpy, XFontStruct *fs)
527492e1cfeSmrg{
528492e1cfeSmrg    register XFontProp *fp;
529492e1cfeSmrg    register int i;
530492e1cfeSmrg    Atom fontatom = XInternAtom (dpy, "FONT", False);
531492e1cfeSmrg
532492e1cfeSmrg    for (i = 0, fp = fs->properties; i < fs->n_properties; i++, fp++) {
533492e1cfeSmrg	if (fp->name == fontatom) {
534492e1cfeSmrg	    return (XGetAtomName (dpy, fp->card32));
535492e1cfeSmrg	}
536492e1cfeSmrg    }
537492e1cfeSmrg    return NULL;
538492e1cfeSmrg}
539492e1cfeSmrg
540492e1cfeSmrg
5413538fbe3Smrgstatic void
5423538fbe3SmrgCatchFontConversionWarning(String name, String type, String class,
543492e1cfeSmrg			   String defaultp, String *params, Cardinal *np)
544492e1cfeSmrg{
545492e1cfeSmrg    if (np && *np > 1 &&
546492e1cfeSmrg	strcmp(name, "conversionError") == 0 &&
547492e1cfeSmrg	strcmp(type, "string") == 0 &&
548492e1cfeSmrg	strcmp(class, "XtToolkitError") == 0 &&
549492e1cfeSmrg	strcmp(params[1], "FontStruct") == 0) fontConversionFailed = True;
550492e1cfeSmrg
551492e1cfeSmrg    (*oldWarningHandler)(name, type, class, defaultp, params, np);
552492e1cfeSmrg}
553