xfd.c revision 1afad795
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;
1863538fbe3Smrg    const char *domaindir;
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
1989e0146f7Smrg    textdomain("xfd");
1999e0146f7Smrg
2009e0146f7Smrg    /* mainly for debugging */
2019e0146f7Smrg    if ((domaindir = getenv ("TEXTDOMAINDIR")) == NULL) {
2029e0146f7Smrg	domaindir = LOCALEDIR;
2039e0146f7Smrg    }
2049e0146f7Smrg    bindtextdomain ("xfd", domaindir);
2059e0146f7Smrg#endif
2069e0146f7Smrg
2079e0146f7Smrg    Resources[0].default_addr = gettext(DEF_SELECT_FORMAT);
2089e0146f7Smrg    Resources[1].default_addr = gettext(DEF_METRICS_FORMAT);
2099e0146f7Smrg    Resources[2].default_addr = gettext(DEF_RANGE_FORMAT);
2109e0146f7Smrg    Resources[3].default_addr = gettext(DEF_START_FORMAT);
2119e0146f7Smrg    Resources[4].default_addr = gettext(DEF_NOCHAR_FORMAT);
2129e0146f7Smrg
213492e1cfeSmrg    if (argc != 1) usage ();
214492e1cfeSmrg    XtAppAddActions (xtcontext, xfd_actions, XtNumber (xfd_actions));
215492e1cfeSmrg    XtOverrideTranslations
216492e1cfeSmrg        (toplevel, XtParseTranslationTable ("<Message>WM_PROTOCOLS: Quit()"));
217492e1cfeSmrg
218492e1cfeSmrg    XtGetApplicationResources (toplevel, (XtPointer) &xfd_resources, Resources,
219492e1cfeSmrg			       XtNumber (Resources), NULL, ZERO);
220492e1cfeSmrg
221492e1cfeSmrg
222492e1cfeSmrg    /* pane wrapping everything */
223492e1cfeSmrg    pane = XtCreateManagedWidget ("pane", panedWidgetClass, toplevel,
224492e1cfeSmrg				  NULL, ZERO);
225492e1cfeSmrg
226492e1cfeSmrg    /* font name */
2273538fbe3Smrg    toplabel = XtCreateManagedWidget ("fontname", labelWidgetClass, pane,
228492e1cfeSmrg				      NULL, ZERO);
229492e1cfeSmrg
230492e1cfeSmrg    /* button box */
231492e1cfeSmrg    box = XtCreateManagedWidget ("box", boxWidgetClass, pane, NULL, ZERO);
232492e1cfeSmrg    quitButton = XtCreateManagedWidget ("quit", commandWidgetClass, box,
233492e1cfeSmrg					NULL, ZERO);
234492e1cfeSmrg    prev16Button = XtCreateManagedWidget ("prev16", commandWidgetClass, box,
235492e1cfeSmrg					NULL, ZERO);
236492e1cfeSmrg    prevButton = XtCreateManagedWidget ("prev", commandWidgetClass, box,
237492e1cfeSmrg					NULL, ZERO);
238492e1cfeSmrg    nextButton = XtCreateManagedWidget ("next", commandWidgetClass, box,
239492e1cfeSmrg					NULL, ZERO);
240492e1cfeSmrg    next16Button = XtCreateManagedWidget ("next16", commandWidgetClass, box,
241492e1cfeSmrg					NULL, ZERO);
242492e1cfeSmrg
243492e1cfeSmrg
244492e1cfeSmrg    /* and labels in which to put information */
245492e1cfeSmrg    selectLabel = XtCreateManagedWidget ("select", labelWidgetClass,
246492e1cfeSmrg					 pane, NULL, ZERO);
247492e1cfeSmrg
248492e1cfeSmrg    metricsLabel = XtCreateManagedWidget ("metrics", labelWidgetClass,
249492e1cfeSmrg					  pane, NULL, ZERO);
250492e1cfeSmrg
2513538fbe3Smrg    rangeLabel = XtCreateManagedWidget ("range", labelWidgetClass, pane,
252492e1cfeSmrg					NULL, ZERO);
253492e1cfeSmrg
2543538fbe3Smrg    startLabel = XtCreateManagedWidget ("start", labelWidgetClass, pane,
255492e1cfeSmrg					NULL, ZERO);
256492e1cfeSmrg
257492e1cfeSmrg    /* form in which to draw */
258492e1cfeSmrg    form = XtCreateManagedWidget ("form", formWidgetClass, pane, NULL, ZERO);
2593538fbe3Smrg
260492e1cfeSmrg    i = 0;
261492e1cfeSmrg    XtSetArg (av[i], XtNtop, XtChainTop); i++;
262492e1cfeSmrg    XtSetArg (av[i], XtNbottom, XtChainBottom); i++;
263492e1cfeSmrg    XtSetArg (av[i], XtNleft, XtChainLeft); i++;
264492e1cfeSmrg    XtSetArg (av[i], XtNright, XtChainRight); i++;
265492e1cfeSmrg    XtSetArg (av[i], XtNcallback, cb); i++;
266492e1cfeSmrg
2673538fbe3Smrg    oldWarningHandler = XtAppSetWarningMsgHandler(xtcontext,
268492e1cfeSmrg						  CatchFontConversionWarning);
269492e1cfeSmrg
270492e1cfeSmrg    fontGrid = XtCreateManagedWidget ("grid", fontgridWidgetClass, form,
271492e1cfeSmrg				      av, i);
272492e1cfeSmrg
273492e1cfeSmrg    XtAppSetWarningMsgHandler(xtcontext, oldWarningHandler);
274492e1cfeSmrg
275492e1cfeSmrg    /* set the label at the top to tell us which font this is */
276492e1cfeSmrg#ifdef XRENDER
277492e1cfeSmrg    i = 0;
278492e1cfeSmrg    XtSetArg (av[i], XtNface, &xft); i++;
279492e1cfeSmrg    XtGetValues (fontGrid, av, i);
280492e1cfeSmrg    if (xft)
281492e1cfeSmrg    {
282492e1cfeSmrg	FcChar8	*family;
283492e1cfeSmrg	FcChar8	*style;
284492e1cfeSmrg	FcPattern   *p;
285492e1cfeSmrg	double	size;
286492e1cfeSmrg	family = (FcChar8 *) "";
287492e1cfeSmrg	FcPatternGetString (xft->pattern, FC_FAMILY, 0, &family);
288492e1cfeSmrg	style = (FcChar8 *) "";
289492e1cfeSmrg	FcPatternGetString (xft->pattern, FC_STYLE, 0, &style);
290492e1cfeSmrg	size = 0;
291492e1cfeSmrg	FcPatternGetDouble (xft->pattern, FC_SIZE, 0, &size);
2929e0146f7Smrg	p = FcPatternBuild (NULL,
293492e1cfeSmrg			    FC_FAMILY, FcTypeString, family,
294492e1cfeSmrg			    FC_STYLE, FcTypeString, style,
295492e1cfeSmrg			    FC_SIZE, FcTypeDouble, size,
296492e1cfeSmrg			    NULL);
297492e1cfeSmrg	fontname = (char *) FcNameUnparse (p);
298492e1cfeSmrg	FcPatternDestroy (p);
299492e1cfeSmrg    }
300492e1cfeSmrg    else
301492e1cfeSmrg#endif
302492e1cfeSmrg    {
303492e1cfeSmrg	i = 0;
304492e1cfeSmrg	XtSetArg (av[i], XtNfont, &fs); i++;
305492e1cfeSmrg	XtGetValues (fontGrid, av, i);
306492e1cfeSmrg	if (!fs || fontConversionFailed) {
3079e0146f7Smrg	    fprintf (stderr, gettext("%s:  no font to display\n"), ProgramName);
308492e1cfeSmrg	    exit (1);
309492e1cfeSmrg	}
310492e1cfeSmrg	fontname = get_font_name (XtDisplay(toplevel), fs);
3119e0146f7Smrg	if (!fontname) fontname = gettext("unknown font!");
312492e1cfeSmrg    }
313492e1cfeSmrg    i = 0;
314492e1cfeSmrg    XtSetArg (av[i], XtNlabel, fontname); i++;
315492e1cfeSmrg    XtSetValues (toplabel, av, i);
316492e1cfeSmrg
317492e1cfeSmrg    minn = GridFirstChar (fontGrid);
318492e1cfeSmrg    maxn = GridLastChar (fontGrid);
3191afad795Smrg    snprintf (buf, sizeof(buf), xfd_resources.range_format,
3201afad795Smrg	      minn >> 8, minn & 0xff,
3211afad795Smrg	      minn >> 8, minn & 0xff,
3221afad795Smrg	      maxn >> 8, maxn & 0xff,
3231afad795Smrg	      maxn >> 8, maxn & 0xff);
3243538fbe3Smrg
325492e1cfeSmrg    i = 0;
326492e1cfeSmrg    XtSetArg (av[i], XtNlabel, buf); i++;
327492e1cfeSmrg    XtSetValues (rangeLabel, av, i);
328492e1cfeSmrg
329492e1cfeSmrg    XtRealizeWidget (toplevel);
330492e1cfeSmrg
331492e1cfeSmrg    wm_delete_window = XInternAtom(XtDisplay(toplevel), "WM_DELETE_WINDOW",
332492e1cfeSmrg                                   False);
333492e1cfeSmrg    (void) XSetWMProtocols (XtDisplay(toplevel), XtWindow(toplevel),
334492e1cfeSmrg                            &wm_delete_window, 1);
335492e1cfeSmrg
336492e1cfeSmrg    change_page (0);
337492e1cfeSmrg    XtAppMainLoop (xtcontext);
338492e1cfeSmrg    exit(0);
339492e1cfeSmrg}
340492e1cfeSmrg
341492e1cfeSmrg/*ARGSUSED*/
3423538fbe3Smrgstatic void
343492e1cfeSmrgSelectChar(Widget w, XtPointer closure, XtPointer data)
344492e1cfeSmrg{
345492e1cfeSmrg    FontGridCharRec *p = (FontGridCharRec *) data;
346492e1cfeSmrg    XFontStruct *fs = p->thefont;
347492e1cfeSmrg    long n = p->thechar;
348492e1cfeSmrg    int direction, fontascent, fontdescent;
349492e1cfeSmrg    XCharStruct metrics;
350492e1cfeSmrg    char buf[256];
351492e1cfeSmrg    Arg arg;
352492e1cfeSmrg    Boolean has_char = 1;
353492e1cfeSmrg
354492e1cfeSmrg    XtSetArg (arg, XtNlabel, buf);
355492e1cfeSmrg
356492e1cfeSmrg    buf[0] = '\0';
357492e1cfeSmrg#ifdef XRENDER
358492e1cfeSmrg    if (p->theface)
359492e1cfeSmrg    {
360492e1cfeSmrg	XftFont	*xft = p->theface;
361492e1cfeSmrg	FcChar32    c = (FcChar32) n;
362492e1cfeSmrg	has_char = (Boolean) FcCharSetHasChar (xft->charset, n);
363492e1cfeSmrg	if (has_char)
364492e1cfeSmrg	{
365492e1cfeSmrg	    XGlyphInfo	extents;
366492e1cfeSmrg	    XftTextExtents32 (XtDisplay (w), xft, &c, 1, &extents);
3671afad795Smrg	    snprintf (buf, sizeof(buf), xfd_resources.metrics_format,
3681afad795Smrg		      extents.xOff, - extents.x,
3691afad795Smrg		      extents.xOff - extents.width + extents.x,
3701afad795Smrg		      extents.y, extents.height - extents.y,
3711afad795Smrg		      xft->ascent, xft->descent);
372492e1cfeSmrg	}
373492e1cfeSmrg    }
374492e1cfeSmrg    else
375492e1cfeSmrg#endif
376492e1cfeSmrg    {
377492e1cfeSmrg	if ((!fs->min_byte1 && !fs->max_byte1) ?
378492e1cfeSmrg	    (n < fs->min_char_or_byte2 || n > fs->max_char_or_byte2) :
379492e1cfeSmrg	    (n >> 8 < fs->min_byte1 || n >> 8 > fs->max_byte1 ||
380492e1cfeSmrg	     (n & 0xff)  < fs->min_char_or_byte2 ||
3813538fbe3Smrg	     (n & 0xff) > fs->max_char_or_byte2))
382492e1cfeSmrg	{
383492e1cfeSmrg	    has_char = 0;
384492e1cfeSmrg	}
385492e1cfeSmrg	else
386492e1cfeSmrg	{
387492e1cfeSmrg	    XChar2b char2b;
388492e1cfeSmrg	    char2b.byte1 = p->thechar >> 8;
389492e1cfeSmrg	    char2b.byte2 = p->thechar & 0xff;
390492e1cfeSmrg	    XTextExtents16 (fs, &char2b, 1, &direction, &fontascent, &fontdescent,
391492e1cfeSmrg			    &metrics);
3921afad795Smrg	    snprintf (buf, sizeof(buf), xfd_resources.metrics_format,
3931afad795Smrg		      metrics.width, metrics.lbearing, metrics.rbearing,
3941afad795Smrg		      metrics.ascent, metrics.descent, fontascent, fontdescent);
395492e1cfeSmrg	}
396492e1cfeSmrg    }
397492e1cfeSmrg    XtSetValues (metricsLabel, &arg, ONE);
398492e1cfeSmrg
399492e1cfeSmrg    if (has_char)
400492e1cfeSmrg    {
4011afad795Smrg	snprintf (buf, sizeof(buf), xfd_resources.select_format,
4021afad795Smrg		  n >> 8, n & 0xff,
4031afad795Smrg		  n >> 8, n & 0xff,
4041afad795Smrg		  n >> 8, n & 0xff);
405492e1cfeSmrg    }
406492e1cfeSmrg    else
407492e1cfeSmrg    {
4081afad795Smrg	snprintf (buf, sizeof(buf), xfd_resources.nochar_format,
4091afad795Smrg		  n >> 8, n & 0xff,
4101afad795Smrg		  n >> 8, n & 0xff,
4111afad795Smrg		  n >> 8, n & 0xff);
412492e1cfeSmrg    }
413492e1cfeSmrg    XtSetValues (selectLabel, &arg, ONE);
414492e1cfeSmrg
415492e1cfeSmrg    return;
416492e1cfeSmrg}
417492e1cfeSmrg
418492e1cfeSmrg
419492e1cfeSmrg/*ARGSUSED*/
4203538fbe3Smrgstatic void
421492e1cfeSmrgdo_quit (Widget w, XEvent *event, String *params, Cardinal *num_params)
422492e1cfeSmrg{
423492e1cfeSmrg    exit (0);
424492e1cfeSmrg}
425492e1cfeSmrg
4263538fbe3Smrgstatic void
427492e1cfeSmrgchange_page(int page)
428492e1cfeSmrg{
429492e1cfeSmrg    long oldstart, newstart;
430492e1cfeSmrg    int ncols, nrows;
431492e1cfeSmrg    char buf[256];
432492e1cfeSmrg    Arg arg;
433492e1cfeSmrg
434492e1cfeSmrg    arg.name = XtNstartChar;
435492e1cfeSmrg    GetFontGridCellDimensions (fontGrid, &oldstart, &ncols, &nrows);
436492e1cfeSmrg
437492e1cfeSmrg    if (page) {
4383538fbe3Smrg	long start = (oldstart +
439492e1cfeSmrg			   ((long) ncols) * ((long) nrows) * ((long) page));
440492e1cfeSmrg
441492e1cfeSmrg	arg.value = (XtArgVal) start;
442492e1cfeSmrg	XtSetValues (fontGrid, &arg, ONE);
443492e1cfeSmrg    }
444492e1cfeSmrg
445492e1cfeSmrg    /* find out what it got set to */
446492e1cfeSmrg    arg.value = (XtArgVal) &newstart;
447492e1cfeSmrg    XtGetValues (fontGrid, &arg, ONE);
448492e1cfeSmrg
449492e1cfeSmrg    /* if not paging, then initialize it, else only do it actually changed */
450492e1cfeSmrg    if (!page || newstart != oldstart) {
451492e1cfeSmrg	unsigned int row = (unsigned int) ((newstart >> 8));
452492e1cfeSmrg	unsigned int col = (unsigned int) (newstart & 0xff);
453492e1cfeSmrg
454492e1cfeSmrg	XtSetArg (arg, XtNlabel, buf);
4551afad795Smrg	snprintf (buf, sizeof(buf), xfd_resources.start_format,
4561afad795Smrg		  newstart, row, col);
457492e1cfeSmrg	XtSetValues (startLabel, &arg, ONE);
458492e1cfeSmrg    }
459492e1cfeSmrg
460492e1cfeSmrg    set_button_state ();
461492e1cfeSmrg
462492e1cfeSmrg    return;
463492e1cfeSmrg}
464492e1cfeSmrg
465492e1cfeSmrg
4663538fbe3Smrgstatic void
467492e1cfeSmrgset_button_state(void)
468492e1cfeSmrg{
469492e1cfeSmrg    Bool prevvalid, nextvalid, prev16valid, next16valid;
470492e1cfeSmrg    Arg arg;
471492e1cfeSmrg
472492e1cfeSmrg    GetPrevNextStates (fontGrid, &prevvalid, &nextvalid, &prev16valid, &next16valid);
473492e1cfeSmrg    arg.name = XtNsensitive;
474492e1cfeSmrg    arg.value = (XtArgVal) (prevvalid ? TRUE : FALSE);
475492e1cfeSmrg    XtSetValues (prevButton, &arg, ONE);
476492e1cfeSmrg    arg.value = (XtArgVal) (nextvalid ? TRUE : FALSE);
477492e1cfeSmrg    XtSetValues (nextButton, &arg, ONE);
478492e1cfeSmrg    arg.name = XtNsensitive;
479492e1cfeSmrg    arg.value = (XtArgVal) (prev16valid ? TRUE : FALSE);
480492e1cfeSmrg    XtSetValues (prev16Button, &arg, ONE);
481492e1cfeSmrg    arg.value = (XtArgVal) (next16valid ? TRUE : FALSE);
482492e1cfeSmrg    XtSetValues (next16Button, &arg, ONE);
483492e1cfeSmrg}
484492e1cfeSmrg
485492e1cfeSmrg
486492e1cfeSmrg/* ARGSUSED */
4873538fbe3Smrgstatic void
488492e1cfeSmrgdo_prev16(Widget w, XEvent *event, String *params, Cardinal *num_params)
489492e1cfeSmrg{
490492e1cfeSmrg    change_page (-16);
491492e1cfeSmrg}
492492e1cfeSmrg
493492e1cfeSmrg
4943538fbe3Smrgstatic void
495492e1cfeSmrgdo_prev(Widget w, XEvent *event, String *params, Cardinal *num_params)
496492e1cfeSmrg{
497492e1cfeSmrg    change_page (-1);
498492e1cfeSmrg}
499492e1cfeSmrg
500492e1cfeSmrg
501492e1cfeSmrg/* ARGSUSED */
5023538fbe3Smrgstatic void
503492e1cfeSmrgdo_next(Widget w, XEvent *event, String *params, Cardinal *num_params)
504492e1cfeSmrg{
505492e1cfeSmrg    change_page (1);
506492e1cfeSmrg}
507492e1cfeSmrg
508492e1cfeSmrg/* ARGSUSED */
5093538fbe3Smrgstatic void
510492e1cfeSmrgdo_next16(Widget w, XEvent *event, String *params, Cardinal *num_params)
511492e1cfeSmrg{
512492e1cfeSmrg    change_page (16);
513492e1cfeSmrg}
514492e1cfeSmrg
515492e1cfeSmrg
516492e1cfeSmrgstatic char *
517492e1cfeSmrgget_font_name(Display *dpy, XFontStruct *fs)
518492e1cfeSmrg{
519492e1cfeSmrg    register XFontProp *fp;
520492e1cfeSmrg    register int i;
521492e1cfeSmrg    Atom fontatom = XInternAtom (dpy, "FONT", False);
522492e1cfeSmrg
523492e1cfeSmrg    for (i = 0, fp = fs->properties; i < fs->n_properties; i++, fp++) {
524492e1cfeSmrg	if (fp->name == fontatom) {
525492e1cfeSmrg	    return (XGetAtomName (dpy, fp->card32));
526492e1cfeSmrg	}
527492e1cfeSmrg    }
528492e1cfeSmrg    return NULL;
529492e1cfeSmrg}
530492e1cfeSmrg
531492e1cfeSmrg
5323538fbe3Smrgstatic void
5333538fbe3SmrgCatchFontConversionWarning(String name, String type, String class,
534492e1cfeSmrg			   String defaultp, String *params, Cardinal *np)
535492e1cfeSmrg{
536492e1cfeSmrg    if (np && *np > 1 &&
537492e1cfeSmrg	strcmp(name, "conversionError") == 0 &&
538492e1cfeSmrg	strcmp(type, "string") == 0 &&
539492e1cfeSmrg	strcmp(class, "XtToolkitError") == 0 &&
540492e1cfeSmrg	strcmp(params[1], "FontStruct") == 0) fontConversionFailed = True;
541492e1cfeSmrg
542492e1cfeSmrg    (*oldWarningHandler)(name, type, class, defaultp, params, np);
543492e1cfeSmrg}
544