xfd.c revision b78bb896
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
33492e1cfeSmrg#include <X11/Intrinsic.h>
34492e1cfeSmrg#include <X11/StringDefs.h>
35492e1cfeSmrg#include <X11/Xos.h>
36492e1cfeSmrg#include <X11/Xatom.h>
37492e1cfeSmrg#include <X11/Shell.h>
38492e1cfeSmrg#include <X11/Xaw/Cardinals.h>
39492e1cfeSmrg#include <X11/Xaw/Paned.h>
40492e1cfeSmrg#include <X11/Xaw/Box.h>
41492e1cfeSmrg#include <X11/Xaw/Form.h>
42492e1cfeSmrg#include <X11/Xaw/Command.h>
43492e1cfeSmrg#include <stdio.h>
44492e1cfeSmrg#include <stdlib.h>
459e0146f7Smrg#ifdef USE_GETTEXT
469e0146f7Smrg# include <X11/Xlocale.h>
479e0146f7Smrg# include <libintl.h>
489e0146f7Smrg#else
499e0146f7Smrg# define gettext(a) (a)
509e0146f7Smrg#endif
51492e1cfeSmrg#include "grid.h"
52492e1cfeSmrg#ifdef XRENDER
53492e1cfeSmrg#include <X11/Xft/Xft.h>
54492e1cfeSmrg#include <X11/extensions/Xrender.h>
55492e1cfeSmrg#endif
56492e1cfeSmrg
579e0146f7Smrgstatic char *ProgramName;
58492e1cfeSmrg
59492e1cfeSmrgstatic XrmOptionDescRec xfd_options[] = {
60492e1cfeSmrg{"-fn",		"*grid.font",	XrmoptionSepArg,	(caddr_t) NULL },
61492e1cfeSmrg#ifdef XRENDER
62492e1cfeSmrg{"-fa",		"*grid.face", XrmoptionSepArg,		(caddr_t) NULL },
63492e1cfeSmrg#endif
64492e1cfeSmrg{"-start",	"*startChar",	XrmoptionSepArg, 	(caddr_t) NULL },
65492e1cfeSmrg{"-box",	"*grid.boxChars", XrmoptionNoArg,	(caddr_t) "on" },
66492e1cfeSmrg{"-bc",		"*grid.boxColor", XrmoptionSepArg, 	(caddr_t) NULL },
67492e1cfeSmrg{"-center",	"*grid.centerChars", XrmoptionNoArg,	(caddr_t) "on" },
68492e1cfeSmrg{"-rows",	"*grid.cellRows", XrmoptionSepArg,	(caddr_t) NULL },
69492e1cfeSmrg{"-columns",	"*grid.cellColumns", XrmoptionSepArg,	(caddr_t) NULL },
70492e1cfeSmrg};
71492e1cfeSmrg
72492e1cfeSmrgstatic void usage(void);
73492e1cfeSmrgstatic void SelectChar(Widget w, XtPointer closure, XtPointer data);
743538fbe3Smrgstatic void do_quit(Widget w, XEvent *event, String *params,
751afad795Smrg		    Cardinal *num_params) _X_NORETURN;
76492e1cfeSmrgstatic void change_page(int page);
77492e1cfeSmrgstatic void set_button_state(void);
783538fbe3Smrgstatic void do_prev(Widget w, XEvent *event, String *params,
79492e1cfeSmrg		    Cardinal *num_params);
803538fbe3Smrgstatic void do_next(Widget w, XEvent *event, String *params,
81492e1cfeSmrg		    Cardinal *num_params);
823538fbe3Smrgstatic void do_prev16(Widget w, XEvent *event, String *params,
83492e1cfeSmrg		      Cardinal *num_params);
843538fbe3Smrgstatic void do_next16(Widget w, XEvent *event, String *params,
85492e1cfeSmrg		      Cardinal *num_params);
86492e1cfeSmrgstatic char *get_font_name(Display *dpy, XFontStruct *fs);
873538fbe3Smrgstatic void CatchFontConversionWarning(String name, String type, String class,
883538fbe3Smrg				       String defaultp, String *params,
89492e1cfeSmrg				       Cardinal *np);
90492e1cfeSmrg
91492e1cfeSmrgstatic XtActionsRec xfd_actions[] = {
92492e1cfeSmrg  { "Quit", do_quit },
93492e1cfeSmrg  { "Prev16", do_prev16 },
94492e1cfeSmrg  { "Prev", do_prev },
95492e1cfeSmrg  { "Next", do_next },
96492e1cfeSmrg  { "Next16", do_next16 },
97492e1cfeSmrg};
98492e1cfeSmrg
99492e1cfeSmrgstatic Atom wm_delete_window;
100492e1cfeSmrg
1019e0146f7Smrgstatic Widget quitButton, prev16Button, prevButton, nextButton, next16Button;
102492e1cfeSmrg
103492e1cfeSmrg
104492e1cfeSmrg#define DEF_SELECT_FORMAT "character 0x%04x%02x (%u,%u) (%#o,%#o)"
105492e1cfeSmrg#define DEF_METRICS_FORMAT "width %d; left %d, right %d; ascent %d, descent %d (font %d, %d)"
106492e1cfeSmrg#define DEF_RANGE_FORMAT "range:  0x%04x%02x (%u,%u) thru 0x%04x%02x (%u,%u)"
107492e1cfeSmrg#define DEF_START_FORMAT "upper left:  0x%06x (%d,%d)"
108492e1cfeSmrg#define DEF_NOCHAR_FORMAT "no such character 0x%04x%02x (%u,%u) (%#o,%#o)"
109492e1cfeSmrg
110492e1cfeSmrgstatic struct _xfd_resources {
111492e1cfeSmrg  char *select_format;
112492e1cfeSmrg  char *metrics_format;
113492e1cfeSmrg  char *range_format;
114492e1cfeSmrg  char *start_format;
115492e1cfeSmrg  char *nochar_format;
116492e1cfeSmrg} xfd_resources;
117492e1cfeSmrg
118492e1cfeSmrg#define Offset(field) XtOffsetOf(struct _xfd_resources, field)
119492e1cfeSmrg
120492e1cfeSmrgstatic XtResource Resources[] = {
1213538fbe3Smrg  { "selectFormat", "SelectFormat", XtRString, sizeof(char *),
122492e1cfeSmrg      Offset(select_format), XtRString, DEF_SELECT_FORMAT },
1233538fbe3Smrg  { "metricsFormat", "MetricsFormat", XtRString, sizeof(char *),
124492e1cfeSmrg      Offset(metrics_format), XtRString, DEF_METRICS_FORMAT },
1253538fbe3Smrg  { "rangeFormat", "RangeFormat", XtRString, sizeof(char *),
126492e1cfeSmrg      Offset(range_format), XtRString, DEF_RANGE_FORMAT },
1273538fbe3Smrg  { "startFormat", "StartFormat", XtRString, sizeof(char *),
128492e1cfeSmrg      Offset(start_format), XtRString, DEF_START_FORMAT },
1293538fbe3Smrg  { "nocharFormat", "NocharFormat", XtRString, sizeof(char *),
130492e1cfeSmrg      Offset(nochar_format), XtRString, DEF_NOCHAR_FORMAT },
131492e1cfeSmrg};
132492e1cfeSmrg
133492e1cfeSmrg#undef Offset
134492e1cfeSmrg
135492e1cfeSmrgstatic void
136492e1cfeSmrgusage(void)
137492e1cfeSmrg{
1389e0146f7Smrg    fprintf (stderr, gettext("usage:  %s [-options ...] "), ProgramName);
1399e0146f7Smrg    fprintf (stderr, "-fn ");
1409e0146f7Smrg    fprintf (stderr, gettext("font\n\n"));
141492e1cfeSmrg#ifdef XRENDER
1429e0146f7Smrg    fprintf (stderr, gettext("        %s [-options ...] "), ProgramName);
1439e0146f7Smrg    fprintf (stderr, "-fa ");
1449e0146f7Smrg    fprintf (stderr, gettext("font\n\n"));
145492e1cfeSmrg#endif
1469e0146f7Smrg    fprintf (stderr, gettext("where options include:\n"));
1479e0146f7Smrg    fprintf (stderr, "    -display ");
1489e0146f7Smrg    fprintf (stderr, gettext("display       X server to contact\n"));
1499e0146f7Smrg    fprintf (stderr, "    -geometry ");
1509e0146f7Smrg    fprintf (stderr, gettext("geometry     size and location of window\n"));
1519e0146f7Smrg    fprintf (stderr, "    -bc ");
1529e0146f7Smrg    fprintf (stderr, gettext("color              color for ImageText boxes\n"));
1539e0146f7Smrg    fprintf (stderr, "    -start ");
1549e0146f7Smrg    fprintf (stderr, gettext("number          first character to show\n"));
1559e0146f7Smrg    fprintf (stderr, "    -box                   ");
1569e0146f7Smrg    fprintf (stderr, gettext("show a box around each character\n"));
1579e0146f7Smrg    fprintf (stderr, "    -center                ");
1589e0146f7Smrg    fprintf (stderr, gettext("center each character inside its grid\n"));
1599e0146f7Smrg    fprintf (stderr, "    -rows ");
1609e0146f7Smrg    fprintf (stderr, gettext("number           number of rows in grid\n"));
1619e0146f7Smrg    fprintf (stderr, "    -columns ");
1629e0146f7Smrg    fprintf (stderr, gettext("number        number of columns in grid\n"));
163492e1cfeSmrg    exit (1);
164492e1cfeSmrg}
165492e1cfeSmrg
166492e1cfeSmrg
167492e1cfeSmrgstatic Widget selectLabel, metricsLabel, rangeLabel, startLabel, fontGrid;
168492e1cfeSmrg
169492e1cfeSmrgstatic Boolean fontConversionFailed = False;
170492e1cfeSmrgstatic XtErrorMsgHandler oldWarningHandler;
171492e1cfeSmrg
172492e1cfeSmrgint
1733538fbe3Smrgmain(int argc, char *argv[])
174492e1cfeSmrg{
175492e1cfeSmrg    XtAppContext xtcontext;
176492e1cfeSmrg    Widget toplevel, pane, toplabel, box, form;
177492e1cfeSmrg    char buf[256];
178492e1cfeSmrg    Arg av[10];
179492e1cfeSmrg    Cardinal i;
180492e1cfeSmrg    static XtCallbackRec cb[2] = { { SelectChar, NULL }, { NULL, NULL } };
181492e1cfeSmrg    XFontStruct *fs;
182492e1cfeSmrg#ifdef XRENDER
183492e1cfeSmrg    XftFont *xft;
184492e1cfeSmrg#endif
185492e1cfeSmrg    char *fontname;
186492e1cfeSmrg    long minn, maxn;
187492e1cfeSmrg
1889e0146f7Smrg    XtSetLanguageProc(NULL, NULL, NULL);
1899e0146f7Smrg
190492e1cfeSmrg    ProgramName = argv[0];
191492e1cfeSmrg
192492e1cfeSmrg    toplevel = XtAppInitialize (&xtcontext, "Xfd",
193492e1cfeSmrg				xfd_options, XtNumber(xfd_options),
194492e1cfeSmrg				&argc, argv, NULL, NULL, 0);
1959e0146f7Smrg
1969e0146f7Smrg#ifdef USE_GETTEXT
197b78bb896Smrg    {
198b78bb896Smrg	const char *domaindir;
1999e0146f7Smrg
200b78bb896Smrg	textdomain("xfd");
201b78bb896Smrg
202b78bb896Smrg        /* mainly for debugging */
203b78bb896Smrg	if ((domaindir = getenv ("TEXTDOMAINDIR")) == NULL) {
204b78bb896Smrg	    domaindir = LOCALEDIR;
205b78bb896Smrg	}
206b78bb896Smrg	bindtextdomain ("xfd", domaindir);
2079e0146f7Smrg    }
2089e0146f7Smrg#endif
2099e0146f7Smrg
2109e0146f7Smrg    Resources[0].default_addr = gettext(DEF_SELECT_FORMAT);
2119e0146f7Smrg    Resources[1].default_addr = gettext(DEF_METRICS_FORMAT);
2129e0146f7Smrg    Resources[2].default_addr = gettext(DEF_RANGE_FORMAT);
2139e0146f7Smrg    Resources[3].default_addr = gettext(DEF_START_FORMAT);
2149e0146f7Smrg    Resources[4].default_addr = gettext(DEF_NOCHAR_FORMAT);
2159e0146f7Smrg
216492e1cfeSmrg    if (argc != 1) usage ();
217492e1cfeSmrg    XtAppAddActions (xtcontext, xfd_actions, XtNumber (xfd_actions));
218492e1cfeSmrg    XtOverrideTranslations
219492e1cfeSmrg        (toplevel, XtParseTranslationTable ("<Message>WM_PROTOCOLS: Quit()"));
220492e1cfeSmrg
221492e1cfeSmrg    XtGetApplicationResources (toplevel, (XtPointer) &xfd_resources, Resources,
222492e1cfeSmrg			       XtNumber (Resources), NULL, ZERO);
223492e1cfeSmrg
224492e1cfeSmrg
225492e1cfeSmrg    /* pane wrapping everything */
226492e1cfeSmrg    pane = XtCreateManagedWidget ("pane", panedWidgetClass, toplevel,
227492e1cfeSmrg				  NULL, ZERO);
228492e1cfeSmrg
229492e1cfeSmrg    /* font name */
2303538fbe3Smrg    toplabel = XtCreateManagedWidget ("fontname", labelWidgetClass, pane,
231492e1cfeSmrg				      NULL, ZERO);
232492e1cfeSmrg
233492e1cfeSmrg    /* button box */
234492e1cfeSmrg    box = XtCreateManagedWidget ("box", boxWidgetClass, pane, NULL, ZERO);
235492e1cfeSmrg    quitButton = XtCreateManagedWidget ("quit", commandWidgetClass, box,
236492e1cfeSmrg					NULL, ZERO);
237492e1cfeSmrg    prev16Button = XtCreateManagedWidget ("prev16", commandWidgetClass, box,
238492e1cfeSmrg					NULL, ZERO);
239492e1cfeSmrg    prevButton = XtCreateManagedWidget ("prev", commandWidgetClass, box,
240492e1cfeSmrg					NULL, ZERO);
241492e1cfeSmrg    nextButton = XtCreateManagedWidget ("next", commandWidgetClass, box,
242492e1cfeSmrg					NULL, ZERO);
243492e1cfeSmrg    next16Button = XtCreateManagedWidget ("next16", commandWidgetClass, box,
244492e1cfeSmrg					NULL, ZERO);
245492e1cfeSmrg
246492e1cfeSmrg
247492e1cfeSmrg    /* and labels in which to put information */
248492e1cfeSmrg    selectLabel = XtCreateManagedWidget ("select", labelWidgetClass,
249492e1cfeSmrg					 pane, NULL, ZERO);
250492e1cfeSmrg
251492e1cfeSmrg    metricsLabel = XtCreateManagedWidget ("metrics", labelWidgetClass,
252492e1cfeSmrg					  pane, NULL, ZERO);
253492e1cfeSmrg
2543538fbe3Smrg    rangeLabel = XtCreateManagedWidget ("range", labelWidgetClass, pane,
255492e1cfeSmrg					NULL, ZERO);
256492e1cfeSmrg
2573538fbe3Smrg    startLabel = XtCreateManagedWidget ("start", labelWidgetClass, pane,
258492e1cfeSmrg					NULL, ZERO);
259492e1cfeSmrg
260492e1cfeSmrg    /* form in which to draw */
261492e1cfeSmrg    form = XtCreateManagedWidget ("form", formWidgetClass, pane, NULL, ZERO);
2623538fbe3Smrg
263492e1cfeSmrg    i = 0;
264492e1cfeSmrg    XtSetArg (av[i], XtNtop, XtChainTop); i++;
265492e1cfeSmrg    XtSetArg (av[i], XtNbottom, XtChainBottom); i++;
266492e1cfeSmrg    XtSetArg (av[i], XtNleft, XtChainLeft); i++;
267492e1cfeSmrg    XtSetArg (av[i], XtNright, XtChainRight); i++;
268492e1cfeSmrg    XtSetArg (av[i], XtNcallback, cb); i++;
269492e1cfeSmrg
2703538fbe3Smrg    oldWarningHandler = XtAppSetWarningMsgHandler(xtcontext,
271492e1cfeSmrg						  CatchFontConversionWarning);
272492e1cfeSmrg
273492e1cfeSmrg    fontGrid = XtCreateManagedWidget ("grid", fontgridWidgetClass, form,
274492e1cfeSmrg				      av, i);
275492e1cfeSmrg
276492e1cfeSmrg    XtAppSetWarningMsgHandler(xtcontext, oldWarningHandler);
277492e1cfeSmrg
278492e1cfeSmrg    /* set the label at the top to tell us which font this is */
279492e1cfeSmrg#ifdef XRENDER
280492e1cfeSmrg    i = 0;
281492e1cfeSmrg    XtSetArg (av[i], XtNface, &xft); i++;
282492e1cfeSmrg    XtGetValues (fontGrid, av, i);
283492e1cfeSmrg    if (xft)
284492e1cfeSmrg    {
285492e1cfeSmrg	FcChar8	*family;
286492e1cfeSmrg	FcChar8	*style;
287492e1cfeSmrg	FcPattern   *p;
288492e1cfeSmrg	double	size;
289492e1cfeSmrg	family = (FcChar8 *) "";
290492e1cfeSmrg	FcPatternGetString (xft->pattern, FC_FAMILY, 0, &family);
291492e1cfeSmrg	style = (FcChar8 *) "";
292492e1cfeSmrg	FcPatternGetString (xft->pattern, FC_STYLE, 0, &style);
293492e1cfeSmrg	size = 0;
294492e1cfeSmrg	FcPatternGetDouble (xft->pattern, FC_SIZE, 0, &size);
2959e0146f7Smrg	p = FcPatternBuild (NULL,
296492e1cfeSmrg			    FC_FAMILY, FcTypeString, family,
297492e1cfeSmrg			    FC_STYLE, FcTypeString, style,
298492e1cfeSmrg			    FC_SIZE, FcTypeDouble, size,
299492e1cfeSmrg			    NULL);
300492e1cfeSmrg	fontname = (char *) FcNameUnparse (p);
301492e1cfeSmrg	FcPatternDestroy (p);
302492e1cfeSmrg    }
303492e1cfeSmrg    else
304492e1cfeSmrg#endif
305492e1cfeSmrg    {
306492e1cfeSmrg	i = 0;
307492e1cfeSmrg	XtSetArg (av[i], XtNfont, &fs); i++;
308492e1cfeSmrg	XtGetValues (fontGrid, av, i);
309492e1cfeSmrg	if (!fs || fontConversionFailed) {
3109e0146f7Smrg	    fprintf (stderr, gettext("%s:  no font to display\n"), ProgramName);
311492e1cfeSmrg	    exit (1);
312492e1cfeSmrg	}
313492e1cfeSmrg	fontname = get_font_name (XtDisplay(toplevel), fs);
3149e0146f7Smrg	if (!fontname) fontname = gettext("unknown font!");
315492e1cfeSmrg    }
316492e1cfeSmrg    i = 0;
317492e1cfeSmrg    XtSetArg (av[i], XtNlabel, fontname); i++;
318492e1cfeSmrg    XtSetValues (toplabel, av, i);
319492e1cfeSmrg
320492e1cfeSmrg    minn = GridFirstChar (fontGrid);
321492e1cfeSmrg    maxn = GridLastChar (fontGrid);
3221afad795Smrg    snprintf (buf, sizeof(buf), xfd_resources.range_format,
3231afad795Smrg	      minn >> 8, minn & 0xff,
3241afad795Smrg	      minn >> 8, minn & 0xff,
3251afad795Smrg	      maxn >> 8, maxn & 0xff,
3261afad795Smrg	      maxn >> 8, maxn & 0xff);
3273538fbe3Smrg
328492e1cfeSmrg    i = 0;
329492e1cfeSmrg    XtSetArg (av[i], XtNlabel, buf); i++;
330492e1cfeSmrg    XtSetValues (rangeLabel, av, i);
331492e1cfeSmrg
332492e1cfeSmrg    XtRealizeWidget (toplevel);
333492e1cfeSmrg
334492e1cfeSmrg    wm_delete_window = XInternAtom(XtDisplay(toplevel), "WM_DELETE_WINDOW",
335492e1cfeSmrg                                   False);
336492e1cfeSmrg    (void) XSetWMProtocols (XtDisplay(toplevel), XtWindow(toplevel),
337492e1cfeSmrg                            &wm_delete_window, 1);
338492e1cfeSmrg
339492e1cfeSmrg    change_page (0);
340492e1cfeSmrg    XtAppMainLoop (xtcontext);
341492e1cfeSmrg    exit(0);
342492e1cfeSmrg}
343492e1cfeSmrg
344492e1cfeSmrg/*ARGSUSED*/
3453538fbe3Smrgstatic void
346492e1cfeSmrgSelectChar(Widget w, XtPointer closure, XtPointer data)
347492e1cfeSmrg{
348492e1cfeSmrg    FontGridCharRec *p = (FontGridCharRec *) data;
349492e1cfeSmrg    XFontStruct *fs = p->thefont;
350492e1cfeSmrg    long n = p->thechar;
351492e1cfeSmrg    int direction, fontascent, fontdescent;
352492e1cfeSmrg    XCharStruct metrics;
353492e1cfeSmrg    char buf[256];
354492e1cfeSmrg    Arg arg;
355492e1cfeSmrg    Boolean has_char = 1;
356492e1cfeSmrg
357492e1cfeSmrg    XtSetArg (arg, XtNlabel, buf);
358492e1cfeSmrg
359492e1cfeSmrg    buf[0] = '\0';
360492e1cfeSmrg#ifdef XRENDER
361492e1cfeSmrg    if (p->theface)
362492e1cfeSmrg    {
363492e1cfeSmrg	XftFont	*xft = p->theface;
364492e1cfeSmrg	FcChar32    c = (FcChar32) n;
365492e1cfeSmrg	has_char = (Boolean) FcCharSetHasChar (xft->charset, n);
366492e1cfeSmrg	if (has_char)
367492e1cfeSmrg	{
368492e1cfeSmrg	    XGlyphInfo	extents;
369492e1cfeSmrg	    XftTextExtents32 (XtDisplay (w), xft, &c, 1, &extents);
3701afad795Smrg	    snprintf (buf, sizeof(buf), xfd_resources.metrics_format,
3711afad795Smrg		      extents.xOff, - extents.x,
3721afad795Smrg		      extents.xOff - extents.width + extents.x,
3731afad795Smrg		      extents.y, extents.height - extents.y,
3741afad795Smrg		      xft->ascent, xft->descent);
375492e1cfeSmrg	}
376492e1cfeSmrg    }
377492e1cfeSmrg    else
378492e1cfeSmrg#endif
379492e1cfeSmrg    {
380492e1cfeSmrg	if ((!fs->min_byte1 && !fs->max_byte1) ?
381492e1cfeSmrg	    (n < fs->min_char_or_byte2 || n > fs->max_char_or_byte2) :
382492e1cfeSmrg	    (n >> 8 < fs->min_byte1 || n >> 8 > fs->max_byte1 ||
383492e1cfeSmrg	     (n & 0xff)  < fs->min_char_or_byte2 ||
3843538fbe3Smrg	     (n & 0xff) > fs->max_char_or_byte2))
385492e1cfeSmrg	{
386492e1cfeSmrg	    has_char = 0;
387492e1cfeSmrg	}
388492e1cfeSmrg	else
389492e1cfeSmrg	{
390492e1cfeSmrg	    XChar2b char2b;
391492e1cfeSmrg	    char2b.byte1 = p->thechar >> 8;
392492e1cfeSmrg	    char2b.byte2 = p->thechar & 0xff;
393492e1cfeSmrg	    XTextExtents16 (fs, &char2b, 1, &direction, &fontascent, &fontdescent,
394492e1cfeSmrg			    &metrics);
3951afad795Smrg	    snprintf (buf, sizeof(buf), xfd_resources.metrics_format,
3961afad795Smrg		      metrics.width, metrics.lbearing, metrics.rbearing,
3971afad795Smrg		      metrics.ascent, metrics.descent, fontascent, fontdescent);
398492e1cfeSmrg	}
399492e1cfeSmrg    }
400492e1cfeSmrg    XtSetValues (metricsLabel, &arg, ONE);
401492e1cfeSmrg
402492e1cfeSmrg    if (has_char)
403492e1cfeSmrg    {
4041afad795Smrg	snprintf (buf, sizeof(buf), xfd_resources.select_format,
4051afad795Smrg		  n >> 8, n & 0xff,
4061afad795Smrg		  n >> 8, n & 0xff,
4071afad795Smrg		  n >> 8, n & 0xff);
408492e1cfeSmrg    }
409492e1cfeSmrg    else
410492e1cfeSmrg    {
4111afad795Smrg	snprintf (buf, sizeof(buf), xfd_resources.nochar_format,
4121afad795Smrg		  n >> 8, n & 0xff,
4131afad795Smrg		  n >> 8, n & 0xff,
4141afad795Smrg		  n >> 8, n & 0xff);
415492e1cfeSmrg    }
416492e1cfeSmrg    XtSetValues (selectLabel, &arg, ONE);
417492e1cfeSmrg
418492e1cfeSmrg    return;
419492e1cfeSmrg}
420492e1cfeSmrg
421492e1cfeSmrg
422492e1cfeSmrg/*ARGSUSED*/
4233538fbe3Smrgstatic void
424492e1cfeSmrgdo_quit (Widget w, XEvent *event, String *params, Cardinal *num_params)
425492e1cfeSmrg{
426492e1cfeSmrg    exit (0);
427492e1cfeSmrg}
428492e1cfeSmrg
4293538fbe3Smrgstatic void
430492e1cfeSmrgchange_page(int page)
431492e1cfeSmrg{
432492e1cfeSmrg    long oldstart, newstart;
433492e1cfeSmrg    int ncols, nrows;
434492e1cfeSmrg    char buf[256];
435492e1cfeSmrg    Arg arg;
436492e1cfeSmrg
437492e1cfeSmrg    arg.name = XtNstartChar;
438492e1cfeSmrg    GetFontGridCellDimensions (fontGrid, &oldstart, &ncols, &nrows);
439492e1cfeSmrg
440492e1cfeSmrg    if (page) {
4413538fbe3Smrg	long start = (oldstart +
442492e1cfeSmrg			   ((long) ncols) * ((long) nrows) * ((long) page));
443492e1cfeSmrg
444492e1cfeSmrg	arg.value = (XtArgVal) start;
445492e1cfeSmrg	XtSetValues (fontGrid, &arg, ONE);
446492e1cfeSmrg    }
447492e1cfeSmrg
448492e1cfeSmrg    /* find out what it got set to */
449492e1cfeSmrg    arg.value = (XtArgVal) &newstart;
450492e1cfeSmrg    XtGetValues (fontGrid, &arg, ONE);
451492e1cfeSmrg
452492e1cfeSmrg    /* if not paging, then initialize it, else only do it actually changed */
453492e1cfeSmrg    if (!page || newstart != oldstart) {
454492e1cfeSmrg	unsigned int row = (unsigned int) ((newstart >> 8));
455492e1cfeSmrg	unsigned int col = (unsigned int) (newstart & 0xff);
456492e1cfeSmrg
457492e1cfeSmrg	XtSetArg (arg, XtNlabel, buf);
4581afad795Smrg	snprintf (buf, sizeof(buf), xfd_resources.start_format,
4591afad795Smrg		  newstart, row, col);
460492e1cfeSmrg	XtSetValues (startLabel, &arg, ONE);
461492e1cfeSmrg    }
462492e1cfeSmrg
463492e1cfeSmrg    set_button_state ();
464492e1cfeSmrg
465492e1cfeSmrg    return;
466492e1cfeSmrg}
467492e1cfeSmrg
468492e1cfeSmrg
4693538fbe3Smrgstatic void
470492e1cfeSmrgset_button_state(void)
471492e1cfeSmrg{
472492e1cfeSmrg    Bool prevvalid, nextvalid, prev16valid, next16valid;
473492e1cfeSmrg    Arg arg;
474492e1cfeSmrg
475492e1cfeSmrg    GetPrevNextStates (fontGrid, &prevvalid, &nextvalid, &prev16valid, &next16valid);
476492e1cfeSmrg    arg.name = XtNsensitive;
477492e1cfeSmrg    arg.value = (XtArgVal) (prevvalid ? TRUE : FALSE);
478492e1cfeSmrg    XtSetValues (prevButton, &arg, ONE);
479492e1cfeSmrg    arg.value = (XtArgVal) (nextvalid ? TRUE : FALSE);
480492e1cfeSmrg    XtSetValues (nextButton, &arg, ONE);
481492e1cfeSmrg    arg.name = XtNsensitive;
482492e1cfeSmrg    arg.value = (XtArgVal) (prev16valid ? TRUE : FALSE);
483492e1cfeSmrg    XtSetValues (prev16Button, &arg, ONE);
484492e1cfeSmrg    arg.value = (XtArgVal) (next16valid ? TRUE : FALSE);
485492e1cfeSmrg    XtSetValues (next16Button, &arg, ONE);
486492e1cfeSmrg}
487492e1cfeSmrg
488492e1cfeSmrg
489492e1cfeSmrg/* ARGSUSED */
4903538fbe3Smrgstatic void
491492e1cfeSmrgdo_prev16(Widget w, XEvent *event, String *params, Cardinal *num_params)
492492e1cfeSmrg{
493492e1cfeSmrg    change_page (-16);
494492e1cfeSmrg}
495492e1cfeSmrg
496492e1cfeSmrg
4973538fbe3Smrgstatic void
498492e1cfeSmrgdo_prev(Widget w, XEvent *event, String *params, Cardinal *num_params)
499492e1cfeSmrg{
500492e1cfeSmrg    change_page (-1);
501492e1cfeSmrg}
502492e1cfeSmrg
503492e1cfeSmrg
504492e1cfeSmrg/* ARGSUSED */
5053538fbe3Smrgstatic void
506492e1cfeSmrgdo_next(Widget w, XEvent *event, String *params, Cardinal *num_params)
507492e1cfeSmrg{
508492e1cfeSmrg    change_page (1);
509492e1cfeSmrg}
510492e1cfeSmrg
511492e1cfeSmrg/* ARGSUSED */
5123538fbe3Smrgstatic void
513492e1cfeSmrgdo_next16(Widget w, XEvent *event, String *params, Cardinal *num_params)
514492e1cfeSmrg{
515492e1cfeSmrg    change_page (16);
516492e1cfeSmrg}
517492e1cfeSmrg
518492e1cfeSmrg
519492e1cfeSmrgstatic char *
520492e1cfeSmrgget_font_name(Display *dpy, XFontStruct *fs)
521492e1cfeSmrg{
522492e1cfeSmrg    register XFontProp *fp;
523492e1cfeSmrg    register int i;
524492e1cfeSmrg    Atom fontatom = XInternAtom (dpy, "FONT", False);
525492e1cfeSmrg
526492e1cfeSmrg    for (i = 0, fp = fs->properties; i < fs->n_properties; i++, fp++) {
527492e1cfeSmrg	if (fp->name == fontatom) {
528492e1cfeSmrg	    return (XGetAtomName (dpy, fp->card32));
529492e1cfeSmrg	}
530492e1cfeSmrg    }
531492e1cfeSmrg    return NULL;
532492e1cfeSmrg}
533492e1cfeSmrg
534492e1cfeSmrg
5353538fbe3Smrgstatic void
5363538fbe3SmrgCatchFontConversionWarning(String name, String type, String class,
537492e1cfeSmrg			   String defaultp, String *params, Cardinal *np)
538492e1cfeSmrg{
539492e1cfeSmrg    if (np && *np > 1 &&
540492e1cfeSmrg	strcmp(name, "conversionError") == 0 &&
541492e1cfeSmrg	strcmp(type, "string") == 0 &&
542492e1cfeSmrg	strcmp(class, "XtToolkitError") == 0 &&
543492e1cfeSmrg	strcmp(params[1], "FontStruct") == 0) fontConversionFailed = True;
544492e1cfeSmrg
545492e1cfeSmrg    (*oldWarningHandler)(name, type, class, defaultp, params, np);
546492e1cfeSmrg}
547