xfd.c revision 492e1cfe
1492e1cfeSmrg/*
2492e1cfeSmrg * $Xorg: xfd.c,v 1.4 2001/02/09 02:05:42 xorgcvs Exp $
3492e1cfeSmrg *
4492e1cfeSmrg *
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
31492e1cfeSmrg#include <X11/Intrinsic.h>
32492e1cfeSmrg#include <X11/StringDefs.h>
33492e1cfeSmrg#include <X11/Xos.h>
34492e1cfeSmrg#include <X11/Xatom.h>
35492e1cfeSmrg#include <X11/Shell.h>
36492e1cfeSmrg#include <X11/Xaw/Cardinals.h>
37492e1cfeSmrg#include <X11/Xaw/Paned.h>
38492e1cfeSmrg#include <X11/Xaw/Box.h>
39492e1cfeSmrg#include <X11/Xaw/Form.h>
40492e1cfeSmrg#include <X11/Xaw/Command.h>
41492e1cfeSmrg#include <stdio.h>
42492e1cfeSmrg#include <stdlib.h>
43492e1cfeSmrg#include "grid.h"
44492e1cfeSmrg#ifdef XRENDER
45492e1cfeSmrg#include <X11/Xft/Xft.h>
46492e1cfeSmrg#include <X11/extensions/Xrender.h>
47492e1cfeSmrg#endif
48492e1cfeSmrg
49492e1cfeSmrgchar *ProgramName;
50492e1cfeSmrg
51492e1cfeSmrgstatic XrmOptionDescRec xfd_options[] = {
52492e1cfeSmrg{"-fn",		"*grid.font",	XrmoptionSepArg,	(caddr_t) NULL },
53492e1cfeSmrg#ifdef XRENDER
54492e1cfeSmrg{"-fa",		"*grid.face", XrmoptionSepArg,		(caddr_t) NULL },
55492e1cfeSmrg#endif
56492e1cfeSmrg{"-start",	"*startChar",	XrmoptionSepArg, 	(caddr_t) NULL },
57492e1cfeSmrg{"-box",	"*grid.boxChars", XrmoptionNoArg,	(caddr_t) "on" },
58492e1cfeSmrg{"-bc",		"*grid.boxColor", XrmoptionSepArg, 	(caddr_t) NULL },
59492e1cfeSmrg{"-center",	"*grid.centerChars", XrmoptionNoArg,	(caddr_t) "on" },
60492e1cfeSmrg{"-rows",	"*grid.cellRows", XrmoptionSepArg,	(caddr_t) NULL },
61492e1cfeSmrg{"-columns",	"*grid.cellColumns", XrmoptionSepArg,	(caddr_t) NULL },
62492e1cfeSmrg};
63492e1cfeSmrg
64492e1cfeSmrgstatic void usage(void);
65492e1cfeSmrgstatic void SelectChar(Widget w, XtPointer closure, XtPointer data);
66492e1cfeSmrgstatic void do_quit(Widget w, XEvent *event, String *params,
67492e1cfeSmrg		    Cardinal *num_params);
68492e1cfeSmrgstatic void change_page(int page);
69492e1cfeSmrgstatic void set_button_state(void);
70492e1cfeSmrgstatic void do_prev(Widget w, XEvent *event, String *params,
71492e1cfeSmrg		    Cardinal *num_params);
72492e1cfeSmrgstatic void do_next(Widget w, XEvent *event, String *params,
73492e1cfeSmrg		    Cardinal *num_params);
74492e1cfeSmrgstatic void do_prev16(Widget w, XEvent *event, String *params,
75492e1cfeSmrg		      Cardinal *num_params);
76492e1cfeSmrgstatic void do_next16(Widget w, XEvent *event, String *params,
77492e1cfeSmrg		      Cardinal *num_params);
78492e1cfeSmrgstatic char *get_font_name(Display *dpy, XFontStruct *fs);
79492e1cfeSmrgstatic void CatchFontConversionWarning(String name, String type, String class,
80492e1cfeSmrg				       String defaultp, String *params,
81492e1cfeSmrg				       Cardinal *np);
82492e1cfeSmrg
83492e1cfeSmrgstatic XtActionsRec xfd_actions[] = {
84492e1cfeSmrg  { "Quit", do_quit },
85492e1cfeSmrg  { "Prev16", do_prev16 },
86492e1cfeSmrg  { "Prev", do_prev },
87492e1cfeSmrg  { "Next", do_next },
88492e1cfeSmrg  { "Next16", do_next16 },
89492e1cfeSmrg};
90492e1cfeSmrg
91492e1cfeSmrgstatic Atom wm_delete_window;
92492e1cfeSmrg
93492e1cfeSmrgWidget quitButton, prev16Button, prevButton, nextButton, next16Button;
94492e1cfeSmrg
95492e1cfeSmrg
96492e1cfeSmrg#define DEF_SELECT_FORMAT "character 0x%04x%02x (%u,%u) (%#o,%#o)"
97492e1cfeSmrg#define DEF_METRICS_FORMAT "width %d; left %d, right %d; ascent %d, descent %d (font %d, %d)"
98492e1cfeSmrg#define DEF_RANGE_FORMAT "range:  0x%04x%02x (%u,%u) thru 0x%04x%02x (%u,%u)"
99492e1cfeSmrg#define DEF_START_FORMAT "upper left:  0x%06x (%d,%d)"
100492e1cfeSmrg#define DEF_NOCHAR_FORMAT "no such character 0x%04x%02x (%u,%u) (%#o,%#o)"
101492e1cfeSmrg
102492e1cfeSmrgstatic struct _xfd_resources {
103492e1cfeSmrg  char *select_format;
104492e1cfeSmrg  char *metrics_format;
105492e1cfeSmrg  char *range_format;
106492e1cfeSmrg  char *start_format;
107492e1cfeSmrg  char *nochar_format;
108492e1cfeSmrg} xfd_resources;
109492e1cfeSmrg
110492e1cfeSmrg#define Offset(field) XtOffsetOf(struct _xfd_resources, field)
111492e1cfeSmrg
112492e1cfeSmrgstatic XtResource Resources[] = {
113492e1cfeSmrg  { "selectFormat", "SelectFormat", XtRString, sizeof(char *),
114492e1cfeSmrg      Offset(select_format), XtRString, DEF_SELECT_FORMAT },
115492e1cfeSmrg  { "metricsFormat", "MetricsFormat", XtRString, sizeof(char *),
116492e1cfeSmrg      Offset(metrics_format), XtRString, DEF_METRICS_FORMAT },
117492e1cfeSmrg  { "rangeFormat", "RangeFormat", XtRString, sizeof(char *),
118492e1cfeSmrg      Offset(range_format), XtRString, DEF_RANGE_FORMAT },
119492e1cfeSmrg  { "startFormat", "StartFormat", XtRString, sizeof(char *),
120492e1cfeSmrg      Offset(start_format), XtRString, DEF_START_FORMAT },
121492e1cfeSmrg  { "nocharFormat", "NocharFormat", XtRString, sizeof(char *),
122492e1cfeSmrg      Offset(nochar_format), XtRString, DEF_NOCHAR_FORMAT },
123492e1cfeSmrg};
124492e1cfeSmrg
125492e1cfeSmrg#undef Offset
126492e1cfeSmrg
127492e1cfeSmrgstatic void
128492e1cfeSmrgusage(void)
129492e1cfeSmrg{
130492e1cfeSmrg    fprintf (stderr, "usage:  %s [-options ...] -fn font\n", ProgramName);
131492e1cfeSmrg#ifdef XRENDER
132492e1cfeSmrg    fprintf (stderr, "        %s [-options ...] -fa font\n", ProgramName);
133492e1cfeSmrg#endif
134492e1cfeSmrg    fprintf (stderr, "where options include:\n");
135492e1cfeSmrg    fprintf (stderr,
136492e1cfeSmrg	"    -display dpy           X server to contact\n");
137492e1cfeSmrg    fprintf (stderr,
138492e1cfeSmrg	"    -geometry geom         size and location of window\n");
139492e1cfeSmrg    fprintf (stderr,
140492e1cfeSmrg	"    -start num             first character to show\n");
141492e1cfeSmrg    fprintf (stderr,
142492e1cfeSmrg	"    -box                   show a box around each character\n");
143492e1cfeSmrg    fprintf (stderr,
144492e1cfeSmrg	"    -center                center each character inside its grid\n");
145492e1cfeSmrg    fprintf (stderr,
146492e1cfeSmrg	"    -rows number           number of rows in grid\n");
147492e1cfeSmrg    fprintf (stderr,
148492e1cfeSmrg	"    -columns number        number of columns in grid\n");
149492e1cfeSmrg    fprintf (stderr, "\n");
150492e1cfeSmrg    exit (1);
151492e1cfeSmrg}
152492e1cfeSmrg
153492e1cfeSmrg
154492e1cfeSmrgstatic Widget selectLabel, metricsLabel, rangeLabel, startLabel, fontGrid;
155492e1cfeSmrg
156492e1cfeSmrgstatic Boolean fontConversionFailed = False;
157492e1cfeSmrgstatic XtErrorMsgHandler oldWarningHandler;
158492e1cfeSmrg
159492e1cfeSmrgint
160492e1cfeSmrgmain(int argc, char *argv[])
161492e1cfeSmrg{
162492e1cfeSmrg    XtAppContext xtcontext;
163492e1cfeSmrg    Widget toplevel, pane, toplabel, box, form;
164492e1cfeSmrg    char buf[256];
165492e1cfeSmrg    Arg av[10];
166492e1cfeSmrg    Cardinal i;
167492e1cfeSmrg    static XtCallbackRec cb[2] = { { SelectChar, NULL }, { NULL, NULL } };
168492e1cfeSmrg    XFontStruct *fs;
169492e1cfeSmrg#ifdef XRENDER
170492e1cfeSmrg    XftFont *xft;
171492e1cfeSmrg#endif
172492e1cfeSmrg    char *fontname;
173492e1cfeSmrg    long minn, maxn;
174492e1cfeSmrg
175492e1cfeSmrg    ProgramName = argv[0];
176492e1cfeSmrg
177492e1cfeSmrg    toplevel = XtAppInitialize (&xtcontext, "Xfd",
178492e1cfeSmrg				xfd_options, XtNumber(xfd_options),
179492e1cfeSmrg				&argc, argv, NULL, NULL, 0);
180492e1cfeSmrg    if (argc != 1) usage ();
181492e1cfeSmrg    XtAppAddActions (xtcontext, xfd_actions, XtNumber (xfd_actions));
182492e1cfeSmrg    XtOverrideTranslations
183492e1cfeSmrg        (toplevel, XtParseTranslationTable ("<Message>WM_PROTOCOLS: Quit()"));
184492e1cfeSmrg
185492e1cfeSmrg    XtGetApplicationResources (toplevel, (XtPointer) &xfd_resources, Resources,
186492e1cfeSmrg			       XtNumber (Resources), NULL, ZERO);
187492e1cfeSmrg
188492e1cfeSmrg
189492e1cfeSmrg    /* pane wrapping everything */
190492e1cfeSmrg    pane = XtCreateManagedWidget ("pane", panedWidgetClass, toplevel,
191492e1cfeSmrg				  NULL, ZERO);
192492e1cfeSmrg
193492e1cfeSmrg    /* font name */
194492e1cfeSmrg    toplabel = XtCreateManagedWidget ("fontname", labelWidgetClass, pane,
195492e1cfeSmrg				      NULL, ZERO);
196492e1cfeSmrg
197492e1cfeSmrg    /* button box */
198492e1cfeSmrg    box = XtCreateManagedWidget ("box", boxWidgetClass, pane, NULL, ZERO);
199492e1cfeSmrg    quitButton = XtCreateManagedWidget ("quit", commandWidgetClass, box,
200492e1cfeSmrg					NULL, ZERO);
201492e1cfeSmrg    prev16Button = XtCreateManagedWidget ("prev16", commandWidgetClass, box,
202492e1cfeSmrg					NULL, ZERO);
203492e1cfeSmrg    prevButton = XtCreateManagedWidget ("prev", commandWidgetClass, box,
204492e1cfeSmrg					NULL, ZERO);
205492e1cfeSmrg    nextButton = XtCreateManagedWidget ("next", commandWidgetClass, box,
206492e1cfeSmrg					NULL, ZERO);
207492e1cfeSmrg    next16Button = XtCreateManagedWidget ("next16", commandWidgetClass, box,
208492e1cfeSmrg					NULL, ZERO);
209492e1cfeSmrg
210492e1cfeSmrg
211492e1cfeSmrg    /* and labels in which to put information */
212492e1cfeSmrg    selectLabel = XtCreateManagedWidget ("select", labelWidgetClass,
213492e1cfeSmrg					 pane, NULL, ZERO);
214492e1cfeSmrg
215492e1cfeSmrg    metricsLabel = XtCreateManagedWidget ("metrics", labelWidgetClass,
216492e1cfeSmrg					  pane, NULL, ZERO);
217492e1cfeSmrg
218492e1cfeSmrg    rangeLabel = XtCreateManagedWidget ("range", labelWidgetClass, pane,
219492e1cfeSmrg					NULL, ZERO);
220492e1cfeSmrg
221492e1cfeSmrg    startLabel = XtCreateManagedWidget ("start", labelWidgetClass, pane,
222492e1cfeSmrg					NULL, ZERO);
223492e1cfeSmrg
224492e1cfeSmrg    /* form in which to draw */
225492e1cfeSmrg    form = XtCreateManagedWidget ("form", formWidgetClass, pane, NULL, ZERO);
226492e1cfeSmrg
227492e1cfeSmrg    i = 0;
228492e1cfeSmrg    XtSetArg (av[i], XtNtop, XtChainTop); i++;
229492e1cfeSmrg    XtSetArg (av[i], XtNbottom, XtChainBottom); i++;
230492e1cfeSmrg    XtSetArg (av[i], XtNleft, XtChainLeft); i++;
231492e1cfeSmrg    XtSetArg (av[i], XtNright, XtChainRight); i++;
232492e1cfeSmrg    XtSetArg (av[i], XtNcallback, cb); i++;
233492e1cfeSmrg
234492e1cfeSmrg    oldWarningHandler = XtAppSetWarningMsgHandler(xtcontext,
235492e1cfeSmrg						  CatchFontConversionWarning);
236492e1cfeSmrg
237492e1cfeSmrg    fontGrid = XtCreateManagedWidget ("grid", fontgridWidgetClass, form,
238492e1cfeSmrg				      av, i);
239492e1cfeSmrg
240492e1cfeSmrg    XtAppSetWarningMsgHandler(xtcontext, oldWarningHandler);
241492e1cfeSmrg
242492e1cfeSmrg    /* set the label at the top to tell us which font this is */
243492e1cfeSmrg#ifdef XRENDER
244492e1cfeSmrg    i = 0;
245492e1cfeSmrg    XtSetArg (av[i], XtNface, &xft); i++;
246492e1cfeSmrg    XtGetValues (fontGrid, av, i);
247492e1cfeSmrg    if (xft)
248492e1cfeSmrg    {
249492e1cfeSmrg	FcChar8	*family;
250492e1cfeSmrg	FcChar8	*style;
251492e1cfeSmrg	FcPattern   *p;
252492e1cfeSmrg	double	size;
253492e1cfeSmrg	family = (FcChar8 *) "";
254492e1cfeSmrg	FcPatternGetString (xft->pattern, FC_FAMILY, 0, &family);
255492e1cfeSmrg	style = (FcChar8 *) "";
256492e1cfeSmrg	FcPatternGetString (xft->pattern, FC_STYLE, 0, &style);
257492e1cfeSmrg	size = 0;
258492e1cfeSmrg	FcPatternGetDouble (xft->pattern, FC_SIZE, 0, &size);
259492e1cfeSmrg	p = FcPatternBuild (0,
260492e1cfeSmrg			    FC_FAMILY, FcTypeString, family,
261492e1cfeSmrg			    FC_STYLE, FcTypeString, style,
262492e1cfeSmrg			    FC_SIZE, FcTypeDouble, size,
263492e1cfeSmrg			    NULL);
264492e1cfeSmrg	fontname = (char *) FcNameUnparse (p);
265492e1cfeSmrg	FcPatternDestroy (p);
266492e1cfeSmrg    }
267492e1cfeSmrg    else
268492e1cfeSmrg#endif
269492e1cfeSmrg    {
270492e1cfeSmrg	i = 0;
271492e1cfeSmrg	XtSetArg (av[i], XtNfont, &fs); i++;
272492e1cfeSmrg	XtGetValues (fontGrid, av, i);
273492e1cfeSmrg	if (!fs || fontConversionFailed) {
274492e1cfeSmrg	    fprintf (stderr, "%s:  no font to display\n", ProgramName);
275492e1cfeSmrg	    exit (1);
276492e1cfeSmrg	}
277492e1cfeSmrg	fontname = get_font_name (XtDisplay(toplevel), fs);
278492e1cfeSmrg    }
279492e1cfeSmrg    i = 0;
280492e1cfeSmrg    XtSetArg (av[i], XtNlabel, fontname); i++;
281492e1cfeSmrg    XtSetValues (toplabel, av, i);
282492e1cfeSmrg
283492e1cfeSmrg    minn = GridFirstChar (fontGrid);
284492e1cfeSmrg    maxn = GridLastChar (fontGrid);
285492e1cfeSmrg    sprintf (buf, xfd_resources.range_format,
286492e1cfeSmrg	     minn >> 8, minn & 0xff,
287492e1cfeSmrg	     minn >> 8, minn & 0xff,
288492e1cfeSmrg	     maxn >> 8, maxn & 0xff,
289492e1cfeSmrg	     maxn >> 8, maxn & 0xff);
290492e1cfeSmrg
291492e1cfeSmrg    i = 0;
292492e1cfeSmrg    XtSetArg (av[i], XtNlabel, buf); i++;
293492e1cfeSmrg    XtSetValues (rangeLabel, av, i);
294492e1cfeSmrg
295492e1cfeSmrg    XtRealizeWidget (toplevel);
296492e1cfeSmrg
297492e1cfeSmrg    wm_delete_window = XInternAtom(XtDisplay(toplevel), "WM_DELETE_WINDOW",
298492e1cfeSmrg                                   False);
299492e1cfeSmrg    (void) XSetWMProtocols (XtDisplay(toplevel), XtWindow(toplevel),
300492e1cfeSmrg                            &wm_delete_window, 1);
301492e1cfeSmrg
302492e1cfeSmrg    change_page (0);
303492e1cfeSmrg    XtAppMainLoop (xtcontext);
304492e1cfeSmrg    exit(0);
305492e1cfeSmrg}
306492e1cfeSmrg
307492e1cfeSmrg/*ARGSUSED*/
308492e1cfeSmrgstatic void
309492e1cfeSmrgSelectChar(Widget w, XtPointer closure, XtPointer data)
310492e1cfeSmrg{
311492e1cfeSmrg    FontGridCharRec *p = (FontGridCharRec *) data;
312492e1cfeSmrg    XFontStruct *fs = p->thefont;
313492e1cfeSmrg    long n = p->thechar;
314492e1cfeSmrg    int direction, fontascent, fontdescent;
315492e1cfeSmrg    XCharStruct metrics;
316492e1cfeSmrg    char buf[256];
317492e1cfeSmrg    Arg arg;
318492e1cfeSmrg    Boolean has_char = 1;
319492e1cfeSmrg
320492e1cfeSmrg    XtSetArg (arg, XtNlabel, buf);
321492e1cfeSmrg
322492e1cfeSmrg    buf[0] = '\0';
323492e1cfeSmrg#ifdef XRENDER
324492e1cfeSmrg    if (p->theface)
325492e1cfeSmrg    {
326492e1cfeSmrg	XftFont	*xft = p->theface;
327492e1cfeSmrg	FcChar32    c = (FcChar32) n;
328492e1cfeSmrg	has_char = (Boolean) FcCharSetHasChar (xft->charset, n);
329492e1cfeSmrg	if (has_char)
330492e1cfeSmrg	{
331492e1cfeSmrg	    XGlyphInfo	extents;
332492e1cfeSmrg	    XftTextExtents32 (XtDisplay (w), xft, &c, 1, &extents);
333492e1cfeSmrg	    sprintf (buf, xfd_resources.metrics_format,
334492e1cfeSmrg		     extents.xOff, - extents.x,
335492e1cfeSmrg		     extents.xOff - extents.width + extents.x,
336492e1cfeSmrg		     extents.y, extents.height - extents.y,
337492e1cfeSmrg		     xft->ascent, xft->descent);
338492e1cfeSmrg	}
339492e1cfeSmrg    }
340492e1cfeSmrg    else
341492e1cfeSmrg#endif
342492e1cfeSmrg    {
343492e1cfeSmrg	if ((!fs->min_byte1 && !fs->max_byte1) ?
344492e1cfeSmrg	    (n < fs->min_char_or_byte2 || n > fs->max_char_or_byte2) :
345492e1cfeSmrg	    (n >> 8 < fs->min_byte1 || n >> 8 > fs->max_byte1 ||
346492e1cfeSmrg	     (n & 0xff)  < fs->min_char_or_byte2 ||
347492e1cfeSmrg	     (n & 0xff) > fs->max_char_or_byte2))
348492e1cfeSmrg	{
349492e1cfeSmrg	    has_char = 0;
350492e1cfeSmrg	}
351492e1cfeSmrg	else
352492e1cfeSmrg	{
353492e1cfeSmrg	    XChar2b char2b;
354492e1cfeSmrg	    char2b.byte1 = p->thechar >> 8;
355492e1cfeSmrg	    char2b.byte2 = p->thechar & 0xff;
356492e1cfeSmrg	    XTextExtents16 (fs, &char2b, 1, &direction, &fontascent, &fontdescent,
357492e1cfeSmrg			    &metrics);
358492e1cfeSmrg	    sprintf (buf, xfd_resources.metrics_format,
359492e1cfeSmrg		     metrics.width, metrics.lbearing, metrics.rbearing,
360492e1cfeSmrg		     metrics.ascent, metrics.descent, fontascent, fontdescent);
361492e1cfeSmrg	}
362492e1cfeSmrg    }
363492e1cfeSmrg    XtSetValues (metricsLabel, &arg, ONE);
364492e1cfeSmrg
365492e1cfeSmrg    if (has_char)
366492e1cfeSmrg    {
367492e1cfeSmrg	sprintf (buf, xfd_resources.select_format,
368492e1cfeSmrg		 n >> 8, n & 0xff,
369492e1cfeSmrg		 n >> 8, n & 0xff,
370492e1cfeSmrg		 n >> 8, n & 0xff);
371492e1cfeSmrg    }
372492e1cfeSmrg    else
373492e1cfeSmrg    {
374492e1cfeSmrg	    sprintf (buf, xfd_resources.nochar_format,
375492e1cfeSmrg		     n >> 8, n & 0xff,
376492e1cfeSmrg		     n >> 8, n & 0xff,
377492e1cfeSmrg		     n >> 8, n & 0xff);
378492e1cfeSmrg    }
379492e1cfeSmrg    XtSetValues (selectLabel, &arg, ONE);
380492e1cfeSmrg
381492e1cfeSmrg    return;
382492e1cfeSmrg}
383492e1cfeSmrg
384492e1cfeSmrg
385492e1cfeSmrg/*ARGSUSED*/
386492e1cfeSmrgstatic void
387492e1cfeSmrgdo_quit (Widget w, XEvent *event, String *params, Cardinal *num_params)
388492e1cfeSmrg{
389492e1cfeSmrg    exit (0);
390492e1cfeSmrg}
391492e1cfeSmrg
392492e1cfeSmrgstatic void
393492e1cfeSmrgchange_page(int page)
394492e1cfeSmrg{
395492e1cfeSmrg    long oldstart, newstart;
396492e1cfeSmrg    int ncols, nrows;
397492e1cfeSmrg    char buf[256];
398492e1cfeSmrg    Arg arg;
399492e1cfeSmrg
400492e1cfeSmrg    arg.name = XtNstartChar;
401492e1cfeSmrg    GetFontGridCellDimensions (fontGrid, &oldstart, &ncols, &nrows);
402492e1cfeSmrg
403492e1cfeSmrg    if (page) {
404492e1cfeSmrg	long start = (oldstart +
405492e1cfeSmrg			   ((long) ncols) * ((long) nrows) * ((long) page));
406492e1cfeSmrg
407492e1cfeSmrg	arg.value = (XtArgVal) start;
408492e1cfeSmrg	XtSetValues (fontGrid, &arg, ONE);
409492e1cfeSmrg    }
410492e1cfeSmrg
411492e1cfeSmrg    /* find out what it got set to */
412492e1cfeSmrg    arg.value = (XtArgVal) &newstart;
413492e1cfeSmrg    XtGetValues (fontGrid, &arg, ONE);
414492e1cfeSmrg
415492e1cfeSmrg    /* if not paging, then initialize it, else only do it actually changed */
416492e1cfeSmrg    if (!page || newstart != oldstart) {
417492e1cfeSmrg	unsigned int row = (unsigned int) ((newstart >> 8));
418492e1cfeSmrg	unsigned int col = (unsigned int) (newstart & 0xff);
419492e1cfeSmrg
420492e1cfeSmrg	XtSetArg (arg, XtNlabel, buf);
421492e1cfeSmrg	sprintf (buf, xfd_resources.start_format, newstart, row, col);
422492e1cfeSmrg	XtSetValues (startLabel, &arg, ONE);
423492e1cfeSmrg    }
424492e1cfeSmrg
425492e1cfeSmrg    set_button_state ();
426492e1cfeSmrg
427492e1cfeSmrg    return;
428492e1cfeSmrg}
429492e1cfeSmrg
430492e1cfeSmrg
431492e1cfeSmrgstatic void
432492e1cfeSmrgset_button_state(void)
433492e1cfeSmrg{
434492e1cfeSmrg    Bool prevvalid, nextvalid, prev16valid, next16valid;
435492e1cfeSmrg    Arg arg;
436492e1cfeSmrg
437492e1cfeSmrg    GetPrevNextStates (fontGrid, &prevvalid, &nextvalid, &prev16valid, &next16valid);
438492e1cfeSmrg    arg.name = XtNsensitive;
439492e1cfeSmrg    arg.value = (XtArgVal) (prevvalid ? TRUE : FALSE);
440492e1cfeSmrg    XtSetValues (prevButton, &arg, ONE);
441492e1cfeSmrg    arg.value = (XtArgVal) (nextvalid ? TRUE : FALSE);
442492e1cfeSmrg    XtSetValues (nextButton, &arg, ONE);
443492e1cfeSmrg    arg.name = XtNsensitive;
444492e1cfeSmrg    arg.value = (XtArgVal) (prev16valid ? TRUE : FALSE);
445492e1cfeSmrg    XtSetValues (prev16Button, &arg, ONE);
446492e1cfeSmrg    arg.value = (XtArgVal) (next16valid ? TRUE : FALSE);
447492e1cfeSmrg    XtSetValues (next16Button, &arg, ONE);
448492e1cfeSmrg}
449492e1cfeSmrg
450492e1cfeSmrg
451492e1cfeSmrg/* ARGSUSED */
452492e1cfeSmrgstatic void
453492e1cfeSmrgdo_prev16(Widget w, XEvent *event, String *params, Cardinal *num_params)
454492e1cfeSmrg{
455492e1cfeSmrg    change_page (-16);
456492e1cfeSmrg}
457492e1cfeSmrg
458492e1cfeSmrg
459492e1cfeSmrgstatic void
460492e1cfeSmrgdo_prev(Widget w, XEvent *event, String *params, Cardinal *num_params)
461492e1cfeSmrg{
462492e1cfeSmrg    change_page (-1);
463492e1cfeSmrg}
464492e1cfeSmrg
465492e1cfeSmrg
466492e1cfeSmrg/* ARGSUSED */
467492e1cfeSmrgstatic void
468492e1cfeSmrgdo_next(Widget w, XEvent *event, String *params, Cardinal *num_params)
469492e1cfeSmrg{
470492e1cfeSmrg    change_page (1);
471492e1cfeSmrg}
472492e1cfeSmrg
473492e1cfeSmrg/* ARGSUSED */
474492e1cfeSmrgstatic void
475492e1cfeSmrgdo_next16(Widget w, XEvent *event, String *params, Cardinal *num_params)
476492e1cfeSmrg{
477492e1cfeSmrg    change_page (16);
478492e1cfeSmrg}
479492e1cfeSmrg
480492e1cfeSmrg
481492e1cfeSmrgstatic char *
482492e1cfeSmrgget_font_name(Display *dpy, XFontStruct *fs)
483492e1cfeSmrg{
484492e1cfeSmrg    register XFontProp *fp;
485492e1cfeSmrg    register int i;
486492e1cfeSmrg    Atom fontatom = XInternAtom (dpy, "FONT", False);
487492e1cfeSmrg
488492e1cfeSmrg    for (i = 0, fp = fs->properties; i < fs->n_properties; i++, fp++) {
489492e1cfeSmrg	if (fp->name == fontatom) {
490492e1cfeSmrg	    return (XGetAtomName (dpy, fp->card32));
491492e1cfeSmrg	}
492492e1cfeSmrg    }
493492e1cfeSmrg    return NULL;
494492e1cfeSmrg}
495492e1cfeSmrg
496492e1cfeSmrg
497492e1cfeSmrgstatic void
498492e1cfeSmrgCatchFontConversionWarning(String name, String type, String class,
499492e1cfeSmrg			   String defaultp, String *params, Cardinal *np)
500492e1cfeSmrg{
501492e1cfeSmrg    if (np && *np > 1 &&
502492e1cfeSmrg	strcmp(name, "conversionError") == 0 &&
503492e1cfeSmrg	strcmp(type, "string") == 0 &&
504492e1cfeSmrg	strcmp(class, "XtToolkitError") == 0 &&
505492e1cfeSmrg	strcmp(params[1], "FontStruct") == 0) fontConversionFailed = True;
506492e1cfeSmrg
507492e1cfeSmrg    (*oldWarningHandler)(name, type, class, defaultp, params, np);
508492e1cfeSmrg}
509