1 /*
2  * Motif
3  *
4  * Copyright (c) 1987-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  *
23  */
24 #define dbg() fprintf(stderr, "file: %s - XtWidgetToApplicationContext() on line: %d\n", __FILE__, __LINE__);
25 #include <stdio.h>
26 #include <ctype.h>
27 #include <stdlib.h>
28 #include <string.h>		/* May have to be strings.h on some systems. */
29 
30 #include <Xm/Xm.h>
31 #include <Xm/FontSP.h>
32 #include <Xm/Label.h>
33 #include <Xm/PushB.h>
34 #include <Xm/RowColumn.h>
35 #include <Xm/TextF.h>
36 #include <Xm/Text.h>
37 #include <Xm/ToggleB.h>
38 #include <Xm/MenuShell.h>
39 #include <Xm/DropDown.h>
40 #include <Xm/ButtonBox.h>
41 #include <Xm/ExtP.h>
42 #include "Xm/XmI.h"
43 
44 #define NUM_XLFD_DASHES 14
45 /* max number of fonts that can be returned (CARD16) */
46 #define TRY_FONTS 	(unsigned int) 65535
47 
48 #define NUM_BUTTONS	30	/* The MAX number of encoding buttons. */
49 
50 #define ANY_FAMILY	0	/* Don't change this, without fixing */
51 				/* ProcessXldfFontData */
52 
53 #define GET_FONT_SIZE BUFSIZ
54 
55 #define ALLOC_INC 		100
56 #define FAMILY_INC 		10
57 #define WIDGET_LIST_INC 	10
58 
59 #define POINT_DIVIDE		10
60 
61 #define DEFAULT_WEIGHT  	("medium")
62 #define BOLD_WEIGHT     	("bold")
63 #define DEFAULT_SLANT   	("r")
64 #define ITALIC_SLANT    	("i")
65 #define DEFAULT_FIXED_SPACING   ("c")
66 #define OTHER_FIXED_SPACING 	("m")
67 #define PROPORTIONAL_SPACING  	("p")
68 
69 #define STAR_STRING	("*")
70 #define ANY_ENCODING	("*-*")
71 
72 #define FAMILY_COLUMNS    20
73 #define VISIBILE_FAMILIES  11
74 
75 static short GValidSizes[] = {
76     2, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,22,23,24,26,28,36,48,72
77 };
78 
79 /*
80  * A font may only be scaled in one resolution, not all resolutions.
81  */
82 
83 #define IsScaled(fsw, fam) (XmFontS_use_scaling((fsw)) &&                     \
84 			    ((CheckFlag(XmFontS_user_state((fsw)), DPI_75) && \
85 			      CheckFlag((fam)->state, SCALED_75))          || \
86 			     (CheckFlag(XmFontS_user_state((fsw)), DPI_100)&& \
87 			      CheckFlag((fam)->state, SCALED_100))))
88 
89 /************************************************************
90  *       GLOBAL DECLARATIONS
91  ************************************************************/
92 
93 /************************************************************
94  *     Private functions - for creating children widgets.
95  ************************************************************/
96 
97 static void CreateChildren(XmFontSelectorWidget, ArgList, Cardinal);
98 static void CreateTopWidgets(XmFontSelectorWidget, Widget, ArgList, Cardinal);
99 static void CreateMiddleArea(XmFontSelectorWidget, ArgList, Cardinal);
100 static void CreateSpacingBox(XmFontSelectorWidget, Widget, ArgList, Cardinal);
101 static void CreateFontChoiceBox(XmFontSelectorWidget, Widget,ArgList,Cardinal);
102 static void CreateResolutionBox(XmFontSelectorWidget, Widget,ArgList,Cardinal);
103 static void CreateFamilyBox(XmFontSelectorWidget, Widget, ArgList, Cardinal);
104 static void CreateSizesBox(XmFontSelectorWidget, Widget, ArgList, Cardinal);
105 static void CreateBoldItalicBox(XmFontSelectorWidget,Widget,ArgList, Cardinal);
106 static void CreateOtherChoiceBox(XmFontSelectorWidget,
107 				 Widget, ArgList, Cardinal);
108 
109 /************************************************************
110  *     Private functions.
111  ************************************************************/
112 
113 static void LoadFontData(Widget, FontData **, int *, String **, int *);
114 static void ProcessXlfdFontData(XmFontSelectorWidget,
115 				FontInfo *, FontData *, int);
116 static void SortOtherFontData(FontInfo *, String *, int);
117 static void AddToOtherList(char *, String **, int *, int *);
118 static void SetNonStringData(FontData *), SetFlag(Flag *, Flag, Boolean);
119 static void StoreString(register String, register String, register int);
120 static void SetLongFlag(LongFlag *, LongFlag, Boolean);
121 static void UpdateExistingFamily(FamilyInfo *, FontData *);
122 static void FillNewFamily(FamilyInfo *, FontData *);
123 static void SetResolution(XmFontSelectorWidget, FontData *);
124 static void DisplayCurrentFont(XmFontSelectorWidget, String);
125 static void UpdateBoldItalic(XmFontSelectorWidget);
126 static void UpdateFixedProportional(XmFontSelectorWidget);
127 static void UpdateFamilies(XmFontSelectorWidget);
128 static void UpdateSizes(XmFontSelectorWidget);
129 static void SetComboValue(Widget, String), UnsetSiblings(Widget);
130 static void DisplayUserError(XmFontSelectorWidget, String);
131 static void SetDisplayedFont(XmFontSelectorWidget, String);
132 static void AddToXlfdOnlyList(XmFontSelectorWidget, Widget);
133 static void AddToXlfdSensitiveList(XmFontSelectorWidget, Widget);
134 static void ChangeMode(XmFontSelectorWidget, Boolean, Boolean);
135 static void SetOtherList(XmFontSelectorWidget, Boolean);
136 static void AddToXlfdList(XmFontSelectorWidget,
137 			  char *, FontData **, int *, int *);
138 
139 static Widget CreateEncodingMenu(XmFontSelectorWidget,
140 				 Widget, ArgList, Cardinal);
141 
142 static FontInfo * LoadFontInfo(XmFontSelectorWidget);
143 
144 static int FindResolution(Widget), CmpStrings(const void *, const void *);
145 
146 static Boolean CheckFlag(Flag, Flag), CheckLongFlag(LongFlag, LongFlag);
147 static Boolean FillData(XmFontSelectorWidget, FontData *, char *);
148 static Boolean IsXlfdFont(register char *);
149 static Boolean CheckEncoding(XmFontSelectorWidget, FamilyInfo *);
150 
151 static FamilyInfo *FindFamily(register XrmQuark, FamilyInfo *, int);
152 
153 static String BuildFontString(XmFontSelectorWidget, FontData *, String, int);
154 
155 static LongFlag SizeMapping(short);
156 
157 /************************************************************
158  *  Callbacks
159  ************************************************************/
160 
161 static void ToggleMiddlePane(Widget, XtPointer, XtPointer);
162 static void ToggleNameWindow(Widget, XtPointer, XtPointer);
163 static void FamilyChanged(Widget, XtPointer, XtPointer);
164 static void SizeChanged(Widget, XtPointer, XtPointer);
165 static void ChangeEncoding(Widget, XtPointer, XtPointer);
166 static void ToggleScaling(Widget, XtPointer, XtPointer);
167 static void ToggleBold(Widget, XtPointer, XtPointer);
168 static void ToggleItalic(Widget, XtPointer, XtPointer);
169 static void Toggle75DPI(Widget, XtPointer, XtPointer);
170 static void Toggle100DPI(Widget, XtPointer, XtPointer);
171 static void ToggleBothDPI(Widget, XtPointer, XtPointer);
172 static void ToggleProportional(Widget, XtPointer, XtPointer);
173 static void ToggleFixed(Widget, XtPointer, XtPointer);
174 static void ToggleBothSpacing(Widget, XtPointer, XtPointer);
175 static void XlfdMode(Widget, XtPointer, XtPointer);
176 static void OtherMode(Widget, XtPointer, XtPointer);
177 static void RemoveUserError(Widget, XtPointer, XtPointer);
178 
179 /************************************************************
180  *  Semi-Public functions
181  ************************************************************/
182 
183 static Boolean SetValues(Widget, Widget, Widget, ArgList, Cardinal *);
184 static void GetValuesHook(Widget, ArgList, Cardinal *);
185 
186 static void Destroy(Widget);
187 static void Initialize(Widget, Widget, ArgList, Cardinal*);
188 static void ClassPartInitialize(WidgetClass w_class);
189 static void ClassInitialize();
190 
191 /*  Resource definitions for Subclasses of Primitive */
192 
193 #define SAMPLE \
194 ("abcdefghijklmonpqrstuvwxyz\n\
195 ABCDEFGHIJKLMONPQRSTUVWXYZ\n\
196 1234567890\n!@#$%^&*()")
197 
198 /************************************************************
199  *       STATIC DECLARATIONS
200  ************************************************************/
201 
202 /*
203  * This table is the list of resolutions of fonts that are supported.
204  * most machines have only 75 and 100 dpi fonts, so we only find which
205  * of those we are closest to with FindResolution().
206  */
207 
208 static int resolutions[] = { 75, 100 };
209 
210 static XtResource resources[] =
211 {
212   {
213     XmNspacing, XmCSpacing, XmRVerticalDimension,
214     sizeof(Dimension), XtOffsetOf(XmPanedRec, paned.internal_bw),
215     XmRImmediate, (XtPointer) 2
216   },
217 
218   {
219     XmNseparatorOn, XmCSeparatorOn, XmRBoolean,
220     sizeof(Boolean), XtOffsetOf(XmPanedRec, paned.separator_on),
221     XmRImmediate, (XtPointer) True
222   },
223 
224   {
225     XmNmarginHeight, XmCMargin, XmRVerticalDimension,
226     sizeof(Dimension), XtOffsetOf(XmPanedRec, paned.margin_height),
227     XmRImmediate, (XtPointer) 0
228   },
229 
230   {
231     XmNcurrentFont, XmCString, XmRString,
232     sizeof(String), XtOffsetOf(XmFontSelectorRec, fs.current_font),
233     XmRImmediate, (XtPointer)NULL
234   },
235 
236   {
237     XmNshowFontName, XmCBoolean, XmRBoolean,
238     sizeof(Boolean), XtOffsetOf(XmFontSelectorRec, fs.show_font_name),
239     XmRImmediate, (XtPointer) False
240   },
241 
242   {
243     XmNuseScaling, XmCBoolean, XmRBoolean,
244     sizeof(Boolean), XtOffsetOf(XmFontSelectorRec, fs.use_scaling),
245     XmRImmediate, (XtPointer) True
246   },
247 
248   {
249     XmNtextRows, XmCTextRows, XmRDimension,
250     sizeof(Dimension), XtOffsetOf(XmFontSelectorRec, fs.text_rows),
251     XmRImmediate, (XtPointer) 8
252   },
253 
254   {
255     XmNvalueChangedCallback, XmCCallback, XmRCallback,
256     sizeof(XtCallbackList), XtOffsetOf(XmFontSelectorRec, fs.font_changed_callback),
257     XmRImmediate, (XtPointer) NULL
258   },
259 
260   {
261     XmNsampleText, XmCSampleText, XmRXmString,
262     sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.sample_text),
263     XmRString, (XtPointer) SAMPLE
264   },
265 
266   {
267     XmNanyString, XmCAnyString, XmRXmString,
268     sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.any),
269     XmRString, (XtPointer) "Any"
270   },
271 
272   {
273     XmNanyLowerString, XmCAnyLowerString, XmRXmString,
274     sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.lower_any),
275     XmRString, (XtPointer) "any"
276   },
277 
278   {
279     XmNfamilyString, XmCFamilyString, XmRXmString,
280     sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.family),
281     XmRString, (XtPointer) "Family"
282   },
283 
284   {
285     XmNsizeString, XmCSizeString, XmRXmString,
286     sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.size),
287     XmRString, (XtPointer) "Size"
288   },
289 
290   {
291     XmNboldString, XmCBoldString, XmRXmString,
292     sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.bold),
293     XmRString, (XtPointer) "Bold"
294   },
295 
296   {
297     XmNitalicString, XmCItalicString, XmRXmString,
298     sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.italic),
299     XmRString, (XtPointer) "Italic"
300   },
301 
302   {
303       XmNoptionString, XmCOptionString, XmRXmString,
304       sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.option),
305       XmRString, (XtPointer) "Options..."
306   },
307 
308   {
309     XmNbothString, XmCBothString, XmRXmString,
310     sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.both),
311     XmRString, (XtPointer) "Both"
312   },
313 
314   {
315     XmNmonoSpaceString, XmCMonoSpaceString, XmRXmString,
316     sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.mono_space),
317     XmRString, (XtPointer) "Fixed Width Fonts"
318   },
319 
320   {
321     XmNpropSpaceString, XmCPropSpaceString, XmRXmString,
322     sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.prop_space),
323     XmRString, (XtPointer) "Proportional Fonts"
324   },
325 
326   {
327     XmNotherString, XmCOtherString, XmRXmString,
328     sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.other_font),
329     XmRString, (XtPointer) "Other Fonts"
330   },
331 
332   {
333     XmNxlfdString, XmCXlfdSpaceString, XmRXmString,
334     sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.xlfd),
335     XmRString, (XtPointer) "Xlfd Fonts"
336   },
337 
338   {
339     XmN75DPIstring, XmC75DPIString, XmRXmString,
340     sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.dpi_75),
341     XmRString, (XtPointer) "75 dpi"
342   },
343 
344   {
345     XmN100DPIstring, XmC100DPIString, XmRXmString,
346     sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.dpi_100),
347     XmRString, (XtPointer) "100 dpi"
348   },
349 
350   {
351     XmNscalingString, XmCScalingString, XmRXmString,
352     sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.scaling),
353     XmRString, (XtPointer) "Use Font Scaling"
354     },
355 
356   {
357     XmNshowNameString, XmCShowNameString, XmRXmString,
358     sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.show_name),
359     XmRString, (XtPointer) "Show Font Name"
360   },
361 
362     /*
363      * Stuff to set the valid charset/encoding pairs.
364      */
365 
366   {
367     XmNencodingString, XmCEncodingString, XmRXmString,
368     sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.encoding_only),
369     XmRString, (XtPointer) "Encoding"
370   },
371 
372     /*
373      * NOTE: This resource value must end in a comma because the resource
374      *       converter is broken in Motif1.1.4.
375      */
376 
377   {
378     XmNencodingList, XmCEncodingList, XmRStringTable,
379     sizeof(String *), XtOffsetOf(XmFontSelectorRec, fs.strings.encoding_list),
380     XmRString, (XtPointer) "iso8859-1,"
381   },
382 
383   {
384     XmNdefaultEncodingString, XmCDefaultEncodingString, XmRString,
385     sizeof(String), XtOffsetOf(XmFontSelectorRec, fs.encoding),
386     XmRString, (XtPointer) "iso8859-1"
387   }
388 };
389 
390 static XmSyntheticResource syn_resources[] =
391 {
392   {
393     XmNspacing, sizeof(Dimension),
394     XtOffsetOf(XmPanedRec, paned.internal_bw),
395     _XmFromPanedPixels, (XmImportProc) _XmToPanedPixels
396   },
397 
398   {
399     XmNmarginHeight, sizeof(Dimension),
400     XtOffsetOf(XmPanedRec, paned.margin_height),
401     XmeFromVerticalPixels, (XmImportProc) XmeToVerticalPixels
402   }
403 };
404 
405 static XtResource subresources[] =
406 {
407   {
408     XmNshowSash, XmCShowSash, XmRBoolean,
409     sizeof(Boolean), XtOffsetOf(XmPanedConstraintsRec, paned.show_sash),
410     XmRImmediate, (XtPointer) False
411   }
412 };
413 
414 #define SuperClass ((ConstraintWidgetClass) &xmPanedClassRec)
415 
416 XmFontSelectorClassRec xmFontSelectorClassRec = {
417    {
418 /* core class fields */
419     /* superclass         */   (WidgetClass) SuperClass,
420     /* class name         */   "XmFontSelector",
421     /* size               */   sizeof(XmFontSelectorRec),
422     /* class_initialize   */   ClassInitialize,
423     /* class_part init    */   ClassPartInitialize,
424     /* class_inited       */   FALSE,
425     /* initialize         */   Initialize,
426     /* initialize_hook    */   NULL,
427     /* realize            */   XtInheritRealize,
428     /* actions            */   NULL,
429     /* num_actions        */   0,
430     /* resources          */   (XtResourceList)resources,
431     /* resource_count     */   XtNumber(resources),
432     /* xrm_class          */   NULLQUARK,
433     /* compress_motion    */   TRUE,
434     /* compress_exposure  */   TRUE,
435     /* compress_enterleave*/   TRUE,
436     /* visible_interest   */   FALSE,
437     /* destroy            */   Destroy,
438     /* resize             */   XtInheritResize,
439     /* expose             */   NULL,
440     /* set_values         */   SetValues,
441     /* set_values_hook    */   NULL,
442     /* set_values_almost  */   XtInheritSetValuesAlmost,
443     /* get_values_hook    */   GetValuesHook,
444     /* accept_focus       */   NULL,
445     /* version            */   XtVersion,
446     /* callback_private   */   NULL,
447     /* tm_table           */   XtInheritTranslations,
448     /* query_geometry	  */   XtInheritQueryGeometry,
449     /* display_accelerator*/   XtInheritDisplayAccelerator,
450     /* extension          */   NULL
451    }, {
452 /* composite class fields */
453     /* geometry_manager   */   XtInheritGeometryManager,
454     /* change_managed     */   XtInheritChangeManaged,
455     /* insert_child       */   XtInheritInsertChild,
456     /* delete_child       */   XtInheritDeleteChild,
457     /* extension          */   NULL
458    }, {
459 /* constraint class fields */
460     /* subresources       */   subresources,
461     /* subresource_count  */   XtNumber(subresources),
462     /* constraint_size    */   sizeof(XmFontSelectorConstraintsRec),
463     /* initialize         */   NULL,
464     /* destroy            */   NULL,
465     /* set_values         */   NULL,
466     /* extension          */   NULL
467    }, {
468 /* manager_class fields   */
469       XtInheritTranslations,                    /* translations           */
470       syn_resources,	                        /* get resources          */
471       XtNumber(syn_resources),    		/* num get_resources      */
472       NULL,                			/* get_cont_resources     */
473       0,				        /* num_get_cont_resources */
474       XmInheritParentProcess,                   /* parent_process         */
475       NULL,                                     /* extension              */
476   }, {
477       /* paned_class fields */
478       NULL,                                     /* extension                 */
479   }, {
480       /* font selector class fields */
481       NULL,                                     /* extension                 */
482   }
483 };
484 
485 WidgetClass xmFontSelectorWidgetClass = (WidgetClass) &xmFontSelectorClassRec;
486 
487 /***********************************************************
488  *
489  * Private Functions.
490  *
491  ************************************************************/
492 
493 /*	Function Name: LoadFontInfo
494  *	Description: Loads the font information from the current screen.
495  *	Arguments: fsw - the font selector widget.
496  *	Returns: the font information.
497  */
498 
499 static FontInfo *
LoadFontInfo(XmFontSelectorWidget fsw)500 LoadFontInfo(XmFontSelectorWidget fsw)
501 {
502     FontInfo *font_info = (FontInfo *) XtMalloc(sizeof(FontInfo));
503     FontData *xlfd_font_data;
504     String *other_fonts;
505     int xlfd_num_fonts, other_num_fonts;
506 
507     font_info->resolution = FindResolution((Widget) fsw);
508     LoadFontData((Widget) fsw, &xlfd_font_data, &xlfd_num_fonts,
509 		 &other_fonts, &other_num_fonts);
510 
511     ProcessXlfdFontData(fsw, font_info, xlfd_font_data, xlfd_num_fonts);
512     SortOtherFontData(font_info, other_fonts, other_num_fonts);
513 
514     return(font_info);
515 }
516 
517 /*	Function Name: LoadFontData
518  *	Description: Loads the font data from the X Server, sorts it into
519  *                   xlfd and non xlfd fonts, and sorts out the xlfd info.
520  *	Arguments: w - any widget on the screen.
521  * RETURNED        xlfd_data, num_xlfd - The xlfd font data.
522  * RETURNED        other_fonts, num_other - The list of non xlfd fonts.
523  *	Returns: none.
524  */
525 
526 static void
LoadFontData(Widget w,FontData ** xlfd_data,int * num_xlfd,String ** other_fonts,int * num_other)527 LoadFontData(Widget w, FontData **xlfd_data, int *num_xlfd,
528 	     String **other_fonts, int *num_other)
529 {
530     XmFontSelectorWidget fsw = (XmFontSelectorWidget) w;
531     char ** fonts, **ptr;
532     int i, num, xlfd_alloc, other_alloc;
533 
534     *xlfd_data = NULL;
535     *other_fonts = NULL;
536     *num_xlfd = *num_other = xlfd_alloc = other_alloc = 0;
537 
538     fonts = XListFonts(XtDisplay(w), "*", TRY_FONTS, &num);
539 
540     /*
541      * Loop the all the fonts and add each one to the proper list.
542      */
543 
544     if (fonts != NULL)  {
545 	for (ptr = fonts, i = 0; i < num; i++, ptr++) {
546 	    if (IsXlfdFont(*ptr))
547 		AddToXlfdList(fsw, *ptr, xlfd_data, num_xlfd, &xlfd_alloc);
548 	    else
549 		AddToOtherList(*ptr, other_fonts, num_other, &other_alloc);
550 	}
551 	XFreeFontNames(fonts);
552     }
553 }
554 
555 /*	Function Name: ProcessXlfdFontData
556  *	Description: Processes the Xlfd data, to come up with lists
557  *                   of various attributes.
558  *	Arguments: fsw - The Font Selector Widget.
559  *                 font_info - the font information structure.
560  *                 data, num - the xlfd data.
561  *	Returns: none.
562  *
563  * This takes the raw XLFD data and builds lists of families and
564  * sizes, and stores all the information in the font_info structure.
565  */
566 
567 static void
ProcessXlfdFontData(XmFontSelectorWidget fsw,FontInfo * font_info,FontData * data,int num_data)568 ProcessXlfdFontData(XmFontSelectorWidget fsw,
569 		    FontInfo *font_info, FontData *data, int num_data)
570 {
571     int num, alloc, i;
572     FamilyInfo *any_fam, *fam = NULL;
573     FontData *top = data;
574     String temp;
575 
576     /*
577      * Leave space for the any family, filled in at the end of the function.
578      *
579      * NOTE:  This assumes that (ANY_FAMILY == 0)
580      */
581 
582     num = 1;
583     alloc = FAMILY_INC;
584     fam = (FamilyInfo *) XtMalloc(sizeof(FamilyInfo) * alloc);
585     fam->nameq = NULLQUARK;	/* Don't use this family yet. */
586 
587     /*
588      * Set up the "Any" family.
589      */
590 
591     for (i = 0; i < num_data; i++, data++) {
592 	register FamilyInfo *cur_family = FindFamily(data->familyq, fam, num);
593 
594 	if (cur_family == NULL) {
595 	    if ( num >= alloc ) {
596 		alloc += FAMILY_INC;
597 		fam = (FamilyInfo *) XtRealloc((XtPointer) fam,
598 					       sizeof(FamilyInfo) * alloc);
599 	    }
600 
601 	    FillNewFamily(fam + num, data);
602 	    num++;
603 	}
604 	else {
605 	    UpdateExistingFamily(cur_family, data);
606 	}
607     }
608 
609     font_info->family_info = fam;
610     font_info->num_families = num;
611 
612     any_fam = fam + ANY_FAMILY;
613     temp = _XmGetMBStringFromXmString(ANY_STRING(fsw));
614     any_fam->nameq = XrmStringToQuark(temp);
615     XtFree(temp);
616     any_fam->bold_nameq = XrmStringToQuark(BOLD_WEIGHT);
617     any_fam->medium_nameq = XrmStringToQuark(DEFAULT_WEIGHT);
618     any_fam->upright_nameq = XrmStringToQuark(DEFAULT_SLANT);
619     any_fam->italic_nameq = XrmStringToQuark(ITALIC_SLANT);
620     strcpy(any_fam->fixed_spacing, DEFAULT_FIXED_SPACING);
621 
622     any_fam->state = (Flag) 0;
623     any_fam->sizes_75 = any_fam->sizes_100 = (LongFlag) 0;
624     for (i = 1, fam++; i < num; i++, fam++) {
625 	any_fam->sizes_75 |= fam->sizes_75;
626 	any_fam->sizes_100 |= fam->sizes_100;
627 	any_fam->state |= fam->state;
628     }
629     any_fam->encodings = NULL;
630     any_fam->encoding_alloc = 0;
631 
632     XtFree((XtPointer) top);
633 }
634 
635 /*	Function Name: SortOtherFonts
636  *	Description: Sorts the list of other fonts alphabetically
637  *                   and stuffs them into the font data structure.
638  *	Arguments: font_info - the font information.
639  *                 list, num - the list of fonts.
640  *	Returns: none
641  */
642 
643 static void
SortOtherFontData(FontInfo * font_info,String * list,int num)644 SortOtherFontData(FontInfo *font_info, String *list, int num)
645 {
646     register int i = 0;
647 
648     qsort((void *) list, num, sizeof(String), CmpStrings);
649 
650     /*
651      * Remove duplicates.
652      */
653 
654     while (i < (num - 1)) {
655 	if (streq(list[i], list[i+1])) {
656 	    register int j;
657 	    register String *ptr;
658 
659 	    XtFree((char*)list[i]);
660 	    ptr = list + i;
661 	    j = i;
662 
663 	    while ( ++j < num) {
664 		ptr[0] = ptr[1];
665 		ptr++;
666 	    }
667 
668 	    num--;	/*Something has been removed, decrement count*/
669 	}
670 	else
671 	    i++;
672     }
673 
674     font_info->others = list;
675     font_info->num_others = num;
676 }
677 
678 /*	Function Name: CmpStrings
679  *	Description: Compares two strings.
680  *	Arguments: p1, p2 - two string pointers.
681  *	Returns: none
682  */
683 
684 static int
CmpStrings(const void * p1,const void * p2)685 CmpStrings(const void * p1, const void *p2)
686 {
687     String *s1 = (String *) p1;
688     String *s2 = (String *) p2;
689 
690     return(strcmp(*s1, *s2));
691 }
692 
693 /*	Function Name: FindResolution
694  *	Description: Finds the closest resolution
695  *	Arguments: w - any widget on the proper screen.
696  *	Returns: the closest allowable resolution to the real resolution.
697  */
698 
699 static int
FindResolution(Widget w)700 FindResolution(Widget w)
701 {
702     Screen *screen = XtScreen(w);
703     register int i, xres, yres, min, pref;
704 
705     /*
706      * there are 2.54 centimeters to an inch; so there are 25.4 millimeters.
707      *
708      *     dpi = N pixels / (M millimeters / (25.4 millimeters / 1 inch))
709      *         = N pixels / (M inch / 25.4)
710      *         = N * 25.4 pixels / M inch
711      *
712      *         Or in integer arithmitic
713      *
714      *         = (254 * N pixels / M inch + 5) / 10
715      */
716 
717     /* This will get us the true pixels / inch.  That is probably
718        not what we want */
719 
720     xres = (254 * WidthOfScreen(screen) / WidthMMOfScreen(screen) + 5) / 10;
721     yres = (254 * HeightOfScreen(screen) / HeightMMOfScreen(screen) + 5) / 10;
722 
723     xres *= xres;
724     yres *= yres;
725 
726     /*
727      * Find the closest resolution by using a difference of squares.
728      */
729 
730     min = 32000;
731     pref = resolutions[0];	/* We have to have some default. */
732 
733     for (i = 0; i < XtNumber(resolutions); i++) {
734 	int diffx = (xres - resolutions[i] * resolutions[i]);
735 	int diffy = (yres - resolutions[i] * resolutions[i]);
736 	int tdiff;		/* the total difference. */
737 
738 	/*
739 	 * Square 'em.
740 	 */
741 
742 	tdiff = (diffx * diffx) + (diffy * diffy);
743 	if (min > tdiff) {
744 	    pref = resolutions[i];
745 	    min = tdiff;
746 	}
747     }
748 
749     return(pref);
750 }
751 
752 /*	Function Name: IsXlfdFont
753  *	Description: Returns True if this is an LXFD font.
754  *	Arguments: str - the font name to check.
755  *	Returns: none.
756  */
757 
758 static Boolean
IsXlfdFont(register char * str)759 IsXlfdFont(register char * str)
760 {
761     register int num_dashes = 0;
762     register char c;
763 
764     for ( ; (c = *str) != '\0'; str++) {
765 	if (c == '-')
766 	    num_dashes++;
767     }
768 
769     return(num_dashes == NUM_XLFD_DASHES);
770 }
771 
772 /*	Function Name: AddToXlfdList
773  *	Description: Adds a font to the list of xlfd fonts.
774  *	Arguments: name - name of the font.
775  *                 list, num - the list of xlfd fonts to add it to.
776  *                 alloc - the number of allocated slots.
777  *	Returns: none.
778  */
779 
780 static void
AddToXlfdList(XmFontSelectorWidget fsw,char * name,FontData ** list,int * num,int * alloc)781 AddToXlfdList(XmFontSelectorWidget fsw,
782 	      char *name, FontData **list, int *num, int *alloc)
783 {
784     FontData *current;
785     if (*num >= *alloc) {
786 	*alloc += ALLOC_INC;
787 	*list = (FontData *) XtRealloc((XtPointer) *list,
788 				       sizeof(FontData) * *alloc);
789     }
790 
791     current = (*list) + *num;
792 
793     /*
794      * If filling the data succeeded, then accept this name, otherwise
795      * just ignore it.
796      */
797 
798     if (FillData(fsw, current, name))
799 	(*num)++;
800 }
801 
802 /*	Function Name: AddToOtherList
803  *	Description: Adds a font to the list of other fonts.
804  *	Arguments: name - name of the font.
805  *                 list, num - the list of other fonts to add it to.
806  *                 alloc - the number of allocated slots.
807  *	Returns: none.
808  */
809 
810 static void
AddToOtherList(char * name,String ** list,int * num,int * alloc)811 AddToOtherList(char *name, String **list, int *num, int *alloc)
812 {
813     if (*num >= *alloc) {
814 	*alloc += ALLOC_INC;
815 	*list = (String *) XtRealloc((XtPointer) *list,
816 				     sizeof(String) * *alloc);
817     }
818 
819     (*list)[(*num)++] = XtNewString(name);
820 }
821 
822 /*	Function Name: FillData(fsw, current, name);
823  *	Description: Fills the current font data from an xlfd name.
824  *	Arguments: fsw - The font selector widget.
825  *                 current - the font data structure to fill.
826  *                 name - an xlfd name of a font.
827  *	Returns: False on failure.
828  *
829  * This name may have NOT *'s in it.
830  */
831 
832 #define GET_NEXT_FIELD(ptr)                             \
833      if (((ptr) = (char *) strchr((ptr), '-')) == NULL) \
834 	 return(False);                                 \
835      (ptr)++	/* skip hyphen */                       \
836 
837 static Boolean
FillData(XmFontSelectorWidget fsw,FontData * current,char * name)838 FillData(XmFontSelectorWidget fsw, FontData *current, char *name)
839 {
840     char *ptr = name;
841     char temp[BUFSIZ];
842 
843     current->state = 0;		/* Initialize value. */
844 
845     GET_NEXT_FIELD(ptr);	/* ptr == Foundry */
846     GET_NEXT_FIELD(ptr);	/* ptr == Family */
847     StoreString(ptr, temp, BUFSIZ - 1);
848 
849     if (streq(temp, STAR_STRING)) {
850 	String str = _XmGetMBStringFromXmString(ANY_STRING(fsw));
851 	strcpy(temp, str);
852 	XtFree((XtPointer) str);
853     }
854 
855     current->familyq = XrmStringToQuark(temp);
856 
857     GET_NEXT_FIELD(ptr);	/* ptr == Weight */
858     StoreString(ptr, temp, BUFSIZ - 1);
859     current->weightq = XrmStringToQuark(temp);
860 
861     GET_NEXT_FIELD(ptr);	/* ptr == Slant */
862     StoreString(ptr, current->slant, SLANT_LEN);
863 
864     GET_NEXT_FIELD(ptr);	/* ptr == SetWidth_Name */
865     GET_NEXT_FIELD(ptr);	/* ptr == Add_Style_Name */
866     GET_NEXT_FIELD(ptr);	/* ptr == Pixel Size */
867     GET_NEXT_FIELD(ptr);	/* ptr == Point Size */
868     StoreString(ptr, temp, BUFSIZ - 1);
869     /*
870      * the string '*' will default to 0 which is exactly what I want.
871      */
872     current->point_size = (short) atoi(temp);
873 
874     GET_NEXT_FIELD(ptr);	/* ptr == Resolution X */
875     StoreString(ptr, temp, BUFSIZ - 1);
876     /*
877      * the string '*' will default to 0 which is exactly what I want.
878      */
879     current->resolution_x = (short) atoi(temp);
880 
881     GET_NEXT_FIELD(ptr);	/* ptr == Resolution Y */
882     StoreString(ptr, temp, BUFSIZ - 1);
883     /*
884      * the string '*' will default to 0 which is exactly what I want.
885      */
886     current->resolution_y = (short) atoi(temp);
887 
888     GET_NEXT_FIELD(ptr);	/* ptr == Spacing */
889     StoreString(ptr, current->spacing, SPACING_LEN);
890 
891     GET_NEXT_FIELD(ptr);	/* ptr == Average Width */
892     GET_NEXT_FIELD(ptr);	/* ptr == Registry and Encoding */
893 
894     current->encoding = XrmStringToQuark(ptr);
895 
896     SetNonStringData(current);
897     return(True);		/* success! */
898 }
899 
900 #undef GET_NEXT_FIELD
901 
902 /*	Function Name: SetNonStringData
903  *	Description: Sets the non string part of the Font Data.
904  *	Arguments: current - the font data we are working with.
905  *	Returns: none.
906  */
907 
908 static void
SetNonStringData(FontData * current)909 SetNonStringData(FontData *current)
910 {
911     char lower[BUFSIZ];
912 
913     /*
914      * Now fill in the non string fields.
915      */
916 
917     /*
918      * If the weight_name field contains the words "bold" or "demi"
919      * then this is a bold font.
920      */
921 
922     XmCopyISOLatin1Lowered(lower, XrmQuarkToString(current->weightq));
923     if ((strstr(lower, "bold") != NULL) || (strstr(lower, "demi") != NULL))
924     	SetFlag(&(current->state), BOLD, True);
925 
926     /*
927      * If the spacing is "p" then proportional, otherwize monospaced.
928      */
929 
930     XmCopyISOLatin1Lowered(lower, current->spacing);
931     if (strstr(lower, PROPORTIONAL_SPACING) != NULL)
932     	SetFlag(&(current->state), PROPORTIONAL, True);
933 
934     /*
935      * If the slant it "i" or "o" then this is an italic font.
936      */
937 
938     XmCopyISOLatin1Lowered(lower, current->slant);
939     if ((strchr(lower, 'i') != NULL) || (strchr(lower, 'o') != NULL))
940     	SetFlag(&(current->state), ITALIC, True);
941 
942     /*
943      * If the point_size is 0 then this is a scalable font.
944      */
945 
946     if (current->point_size == 0) {
947 	if ((current->resolution_x == 75) && (current->resolution_y == 75))
948 	    SetFlag(&(current->state), SCALED_75, True);
949 	else if((current->resolution_x == 100)&&(current->resolution_y == 100))
950 	    SetFlag(&(current->state), SCALED_100, True);
951 	else if ((current->resolution_x == 0)&& (current->resolution_y == 0)) {
952 	    /*
953 	     * Sun sets all scaled fonts to have a resolution of 0x0
954 	     */
955 	    SetFlag(&(current->state), SCALED_75 | SCALED_100, True);
956 	}
957     }
958     /*
959      * Check to see if resolution matches 75 or 100 dpi.
960      */
961 
962     if ((current->resolution_x == 75) && (current->resolution_y == 75))
963 	SetFlag(&(current->state), DPI_75, True);
964     else if ((current->resolution_x == 100) && (current->resolution_y == 100))
965 	SetFlag(&(current->state), DPI_100, True);
966     else if ((current->resolution_x == 0) && (current->resolution_y == 0)) {
967 	/*
968 	 * Sun sets all scaled fonts to have a resolution of 0x0
969 	 */
970 	SetFlag(&(current->state), DPI_75 | DPI_100, True);
971     }
972 }
973 
974 /*	Function Name: StoreString
975  *	Description: Stores a portion of an xlfd name into the
976  *                   string varaible passed.
977  *	Arguments: str - the portion of the string to store.
978  *                 store - the string to store it in.
979  *                 max_len - maximum length of the value.
980  *	Returns: none.
981  */
982 
983 static void
StoreString(register String str,register String store,register int max_len)984 StoreString(register String str, register String store, register int max_len)
985 {
986     register int i;
987     register int c;
988 
989     for (i = 0; i < max_len; i++, str++, store++) {
990 	if (((c = *str) == '-') || (c == '\0'))
991 	    break;
992 	*store = c;
993     }
994     *store = '\0';
995 }
996 
997 /*	Function Name: CheckFlag
998  *	Description: Checks to see if a flag value is set
999  *	Arguments: state - the state variable containing the flag.
1000  *                 flag - the location of the flag.
1001  *	Returns: True if flag set, False otherwise
1002  */
1003 
1004 static Boolean
CheckFlag(Flag state,Flag flag)1005 CheckFlag(Flag state, Flag flag)
1006 {
1007     return((state & flag) == flag);
1008 }
1009 
1010 /*	Function Name: CheckLongFlag
1011  *	Description: Checks to see if a long flag value is set
1012  *	Arguments: state - the state variable containing the flag.
1013  *                 flag - the location of the flag.
1014  *	Returns: True if flag set, False otherwise
1015  */
1016 
1017 static Boolean
CheckLongFlag(LongFlag state,LongFlag flag)1018 CheckLongFlag(LongFlag state, LongFlag flag)
1019 {
1020     return((state & flag) == flag);
1021 }
1022 
1023 /*	Function Name: SetFlag
1024  *	Description: Sets a flag value
1025  *	Arguments: state - the state variable containing the flag.
1026  *                 flag - the location of the flag.
1027  *                 value - the value of the flag.
1028  *	Returns: none.
1029  */
1030 
1031 static void
SetFlag(Flag * state,Flag flag,Boolean value)1032 SetFlag(Flag *state, Flag flag, Boolean value)
1033 {
1034     if (value)
1035 	*state |= flag;
1036     else
1037 	*state &= ~flag;
1038 }
1039 
1040 /*	Function Name: SetLongFlag
1041  *	Description: Sets a flag value that is stored in a long
1042  *	Arguments: state - the state variable containing the flag.
1043  *                 flag - the location of the flag.
1044  *                 value - the value of the flag.
1045  *	Returns: none.
1046  */
1047 
1048 static void
SetLongFlag(LongFlag * state,LongFlag flag,Boolean value)1049 SetLongFlag(LongFlag *state, LongFlag flag, Boolean value)
1050 {
1051     if (value)
1052 	*state |= flag;
1053     else
1054 	*state &= ~flag;
1055 }
1056 
1057 /*	Function Name: FindFamily
1058  *	Description: Finds family associated with the font passed.
1059  *	Arguments: font - the font data.
1060  *                 list - the list of all families
1061  *                 num - the number of families.
1062  *	Returns: a pointer to the family this font is in or NULL.
1063  *
1064  */
1065 
1066 static FamilyInfo *
FindFamily(register XrmQuark nameq,FamilyInfo * list,int num)1067 FindFamily(register XrmQuark nameq, FamilyInfo *list, int num)
1068 {
1069     register int i;
1070 
1071     for (i = 0; i < num; i++, list++) {
1072 	if (list->nameq == nameq)
1073 	    return(list);
1074     }
1075 
1076     return(NULL);
1077 }
1078 
1079 /*	Function Name: UpdateExistingFamily
1080  *	Description: Updates data, by adding another font to an
1081  *                   existion family.
1082  *	Arguments: fam - the family to update.
1083  *                 font - the font to add.
1084  *	Returns: none.
1085  */
1086 
1087 static void
UpdateExistingFamily(FamilyInfo * fam,FontData * font)1088 UpdateExistingFamily(FamilyInfo *fam, FontData *font)
1089 {
1090     int i;
1091 
1092     if (CheckFlag(font->state, BOLD))
1093 	fam->bold_nameq = font->weightq;
1094     else
1095 	fam->medium_nameq = font->weightq;
1096 
1097     if (CheckFlag(font->state, ITALIC))
1098 	fam->italic_nameq = XrmStringToQuark(font->slant);
1099     else
1100 	fam->upright_nameq = XrmStringToQuark(font->slant);
1101 
1102     if (!streq(font->spacing, PROPORTIONAL_SPACING))
1103 	strcpy(fam->fixed_spacing, font->spacing);
1104 
1105     if (font->point_size != 0) {
1106 	if ((font->resolution_x == 75) && (font->resolution_y == 75))
1107 	    SetLongFlag(&(fam->sizes_75), SizeMapping(font->point_size), True);
1108 	else if ((font->resolution_x == 100) && (font->resolution_y == 100))
1109 	    SetLongFlag(&(fam->sizes_100),SizeMapping(font->point_size), True);
1110     }
1111 
1112     fam->state |= font->state;	/* or in all bits. */
1113 
1114     for (i = 0; TRUE; i++)
1115     {
1116 	if (i == fam->encoding_alloc)
1117 	{
1118 	    fam->encoding_alloc += NUM_BUTTONS;
1119 	    fam->encodings =
1120 		(XrmQuark *) XtRealloc((char *) fam->encodings,
1121 				       sizeof(XrmQuark) * fam->encoding_alloc);
1122 	    memset((char *) (fam->encodings + i), 0,
1123 		   sizeof(XrmQuark) * NUM_BUTTONS);
1124 	}
1125 
1126 	if (fam->encodings[i] == font->encoding)
1127 	    return;
1128 
1129 	if (fam->encodings[i] == 0)
1130 	{
1131 	    fam->encodings[i] = font->encoding;
1132 	    return;
1133 	}
1134     }
1135 }
1136 
1137 /*	Function Name: FillNewFamily
1138  *	Description: Fills in the information for a new font family.
1139  *	Arguments: fam -  the family data.
1140  *                 font - the first font we found.
1141  *	Returns: none.
1142  */
1143 
1144 static void
FillNewFamily(FamilyInfo * fam,FontData * font)1145 FillNewFamily(FamilyInfo *fam, FontData *font)
1146 {
1147     fam->nameq = font->familyq;
1148 
1149     if (CheckFlag(font->state, BOLD)) {
1150 	fam->bold_nameq = font->weightq;
1151     	fam->medium_nameq = NULLQUARK;
1152     }
1153     else {
1154     	fam->bold_nameq = NULLQUARK;
1155 	fam->medium_nameq = font->weightq;
1156     }
1157 
1158     if (streq(font->spacing, PROPORTIONAL_SPACING))
1159 	strcpy(fam->fixed_spacing, DEFAULT_FIXED_SPACING);
1160     else
1161 	strcpy(fam->fixed_spacing, font->spacing);
1162 
1163     if (CheckFlag(font->state, ITALIC)) {
1164 	fam->italic_nameq = XrmStringToQuark(font->slant);
1165     	fam->upright_nameq = NULLQUARK;
1166     }
1167     else {
1168     	fam->italic_nameq = NULLQUARK;
1169 	fam->upright_nameq = XrmStringToQuark(font->slant);
1170     }
1171 
1172     fam->sizes_75 = fam->sizes_100 = 0;
1173     fam->state = font->state;
1174 
1175     if (font->point_size != 0) {
1176 	if ((font->resolution_x == 75) && (font->resolution_y == 75))
1177 	    SetLongFlag(&(fam->sizes_75), SizeMapping(font->point_size), True);
1178 	else if ((font->resolution_x == 100) && (font->resolution_y == 100))
1179 	    SetLongFlag(&(fam->sizes_100),SizeMapping(font->point_size), True);
1180     }
1181 
1182     fam->encoding_alloc = NUM_BUTTONS;
1183     fam->encodings = (XrmQuark *) XtCalloc(fam->encoding_alloc,
1184 					   sizeof(XrmQuark));
1185     fam->encodings[0] = fam->encoding_alloc;
1186 }
1187 
1188 /*	Function Name: SizeMapping
1189  *	Description: Maps the actual size to the sizes bit field
1190  *	Arguments: size - the point size to map.
1191  *	Returns: 0 if the size does not map, otherwise the bit it maps to.
1192  */
1193 
1194 static LongFlag
SizeMapping(short size)1195 SizeMapping(short size)
1196 {
1197     register int count;
1198 
1199     size /= POINT_DIVIDE;
1200 
1201     for (count = 0; count < XtNumber(GValidSizes); count++) {
1202 	if (GValidSizes[count] == size)
1203 	    return (((LongFlag) 1) << count);
1204     }
1205 
1206     return((LongFlag) 0);
1207 }
1208 
1209 /*	Function Name: DisplayCurrentFont
1210  *	Description: Displays the current font to the user.
1211  *	Arguments: fsw - the font selector widget.
1212  *                 font - the current font name.
1213  *	Returns: none.
1214  */
1215 
1216 static void
DisplayCurrentFont(XmFontSelectorWidget fsw,String font)1217 DisplayCurrentFont(XmFontSelectorWidget fsw, String font)
1218 {
1219     Arg largs[10];
1220     Cardinal num_largs;
1221     XmFontList fl;
1222     XFontStruct *fontdata;
1223     char buf[BUFSIZ * 2];
1224     Boolean	err = False;
1225 
1226     if ((fontdata = XLoadQueryFont(XtDisplay((Widget) fsw), font)) == NULL)
1227     {
1228 	sprintf(buf, "Font '%s'\nis not availiable on this machine", font);
1229 	DisplayUserError(fsw, buf);
1230 	err = True;
1231     }
1232     else
1233     {
1234 
1235 	/*
1236 	 * Always clear out old errors
1237 	 */
1238 	RemoveUserError(NULL, (XtPointer)fsw, (XtPointer)0);
1239 
1240     /*
1241      * This is a hack to work around problems with Sun scaled fonts
1242      * and the Motif Text widget.  It turns out that some sun fonts
1243      * when a size of * is specified will return a font of height 0
1244      * this causes the ascent + descent to be zero and really confuses
1245      * the XmTextField widget.
1246      */
1247 
1248     if ((fontdata->ascent + fontdata->descent) == 0) {
1249 	if (IsXlfdFont(font)) {
1250 	    char *ptr, left_buf[BUFSIZ], right_buf[BUFSIZ], fbuf[BUFSIZ];
1251 	    register int i, count;
1252 
1253 	    /*
1254 	     * This is a poorly formatted Sun Scaled font,
1255 	     *
1256 	     * Find where the size is and change it from a * to 140.
1257  	     */
1258 
1259 	    for (ptr = font, i = count = 0; *ptr != 0; i++, ptr++) {
1260 		if (*ptr != '-')
1261 		    continue;
1262 
1263 		count++;
1264 		if (count == 8)
1265 		    break;
1266 	    }
1267 
1268 	    ptr = (char *) strchr(ptr + 1, '-');
1269 	    strcpy(right_buf, ptr);
1270 	    strcpy(left_buf, font);
1271 	    left_buf[i] = '\0';
1272 	    sprintf(fbuf, "%s-140%s", left_buf, right_buf);
1273 
1274 	    if ((fontdata = XLoadQueryFont(XtDisplay((Widget) fsw),
1275 					   fbuf)) == NULL)
1276 	    {
1277 		sprintf(buf,
1278 			    "Font '%s'\nis not availiable on this machine",
1279 			    font);
1280 		DisplayUserError(fsw, buf);
1281 		    err = True;
1282 	    }
1283 	}
1284 	else {
1285 		sprintf(buf,
1286 			"Font '%s'\n%s",
1287 			font,
1288 		    "is is zero pixels high and cannot be displayed.");
1289 	    DisplayUserError(fsw, buf);
1290 		err = True;
1291 	}
1292     }
1293     }
1294 
1295     if (!err) {
1296 	fl = XmFontListCreate(fontdata, XmFONTLIST_DEFAULT_TAG);
1297 
1298 	num_largs = 0;
1299 	XtSetArg(largs[num_largs], XmNfontList, fl); num_largs++;
1300 	XtSetValues(XmFontS_text(fsw), largs, num_largs);
1301 
1302 	if (XmFontS_old_fontdata(fsw) != NULL)
1303 	{
1304 	    XFreeFont(XtDisplay((Widget) fsw), XmFontS_old_fontdata(fsw));
1305 	    XmFontListFree(XmFontS_old_fontlist(fsw));
1306 	}
1307 
1308 	XmFontS_old_fontdata(fsw) = fontdata;
1309 	XmFontS_old_fontlist(fsw) = fl;
1310     }
1311 
1312     if (XtIsManaged(XmFontS_name_label(fsw)))
1313     {
1314 	XmString xmstr = XmStringCreateLocalized(font);
1315 	num_largs = 0;
1316 	XtSetArg(largs[num_largs], XmNlabelString, xmstr); num_largs++;
1317 	XtSetValues(XmFontS_name_label(fsw), largs, num_largs);
1318 	XmStringFree(xmstr);
1319     }
1320 
1321     /*
1322      * Fire off the callback for the user.
1323      */
1324 
1325     {
1326 	FontData	*cf = XmFontS_font_info(fsw)->current_font;
1327 	String 	str_ptr;
1328 
1329 	if (XmFontS_xlfd_mode(fsw)) {
1330 	    BuildFontString(fsw, cf, XmFontS_get_font(fsw), GET_FONT_SIZE);
1331 	    str_ptr = XmFontS_get_font(fsw);
1332 	}
1333 	else
1334 	    str_ptr = XrmQuarkToString(cf->familyq);
1335 
1336 	XtCallCallbackList((Widget) fsw,
1337 			   XmFontS_font_changed_callback(fsw), (XtPointer)str_ptr);
1338     }
1339 }
1340 
1341 /*	Function Name: BuildFontString
1342  *	Description: Builds a font string from the current font.
1343  *	Arguments:   fsw - the font selector widget.
1344  *                   cf - the font data to use.
1345  *                   buf - where to stuff the font name.
1346  *                   size - the size not to exceed.
1347  *	Returns: the font string (same as buf).
1348  */
1349 
1350 /* ARGSUSED */
1351 static String
BuildFontString(XmFontSelectorWidget fsw,FontData * cf,String buf,int size)1352 BuildFontString(XmFontSelectorWidget fsw, FontData *cf, String buf, int size)
1353 {
1354     static XrmQuark anyquark2, anyquark = NULLQUARK;
1355     String family, encoding;
1356     char res_x[BUFSIZ], res_y[BUFSIZ], point_size[BUFSIZ];
1357 
1358     if (anyquark == NULLQUARK) {
1359 	String temp1 = _XmGetMBStringFromXmString(ANY_STRING(fsw));
1360 	String temp2 = _XmGetMBStringFromXmString(LOWER_ANY_STRING(fsw));
1361 
1362 	anyquark = XrmStringToQuark(temp1);
1363 	anyquark2 = XrmStringToQuark(temp2);
1364 
1365 	XtFree(temp1);
1366 	XtFree(temp2);
1367     }
1368 
1369     if ((anyquark == cf->familyq) || (anyquark2 == cf->familyq))
1370 	family = STAR_STRING;
1371     else
1372 	family = XrmQuarkToString(cf->familyq);
1373 
1374     if (cf->point_size == 0)
1375 	strcpy(point_size, STAR_STRING);
1376     else
1377 	sprintf(point_size, "%d", cf->point_size);
1378 
1379     if (cf->resolution_x == 0)
1380 	strcpy(res_x, STAR_STRING);
1381     else
1382 	sprintf(res_x, "%d", (int) cf->resolution_x);
1383 
1384     if (cf->resolution_y == 0)
1385 	strcpy(res_y, STAR_STRING);
1386     else
1387 	sprintf(res_y, "%d", (int) cf->resolution_y);
1388 
1389     encoding = ENCODING_STRING(fsw);
1390 
1391     /*
1392      * I should really check to see that the string fits, but
1393      * What would I do it I failed?
1394      */
1395 
1396     sprintf(buf, "-*-%s-%s-%s-*-*-*-%s-%s-%s-%s-*-%s",
1397 	    family, XrmQuarkToString(cf->weightq), cf->slant, point_size,
1398 	    res_x, res_y, cf->spacing, encoding);
1399 
1400     return(buf);
1401 }
1402 
1403 /*	Function Name: UpdateBoldItalic
1404  *	Description: Updates the bold and italic buttons
1405  *	Arguments: fsw - the font selector widget.
1406  *	Returns: none.
1407  */
1408 
1409 static void
UpdateBoldItalic(XmFontSelectorWidget fsw)1410 UpdateBoldItalic(XmFontSelectorWidget fsw)
1411 {
1412     Boolean set;
1413     FontData *cf = XmFontS_font_info(fsw)->current_font;
1414     FamilyInfo *fam;
1415 
1416     if ((fam = FindFamily(cf->familyq, XmFontS_font_info(fsw)->family_info,
1417 			  XmFontS_font_info(fsw)->num_families)) == NULL)
1418     {
1419 	String params[1];
1420 	Cardinal num = 1;
1421 
1422 	params[0] = XrmQuarkToString(cf->familyq);
1423 	dbg(); _XmWarningMsg((Widget) fsw, XmNcouldNotFindFamilyData,
1424 			XmNcouldNotFindFamilyDataMsg, params, num);
1425 	return;
1426     }
1427 
1428     if ((fam->medium_nameq == NULLQUARK) || (fam->bold_nameq == NULLQUARK)) {
1429 	set = (fam->medium_nameq == NULLQUARK);
1430 	XmToggleButtonSetState(XmFontS_bold_toggle(fsw), set, False);
1431 	SetFlag(&(XmFontS_user_state(fsw)), BOLD, set);
1432 	XtSetSensitive(XmFontS_bold_toggle(fsw), False);
1433     }
1434     else {
1435 	XtSetSensitive(XmFontS_bold_toggle(fsw), True);
1436     }
1437 
1438     if (CheckFlag(XmFontS_user_state(fsw), BOLD))
1439 	cf->weightq = fam->bold_nameq;
1440     else
1441 	cf->weightq = fam->medium_nameq;
1442 
1443     if ((fam->upright_nameq == NULLQUARK)|| (fam->italic_nameq == NULLQUARK)) {
1444 	set = (fam->upright_nameq == NULLQUARK);
1445 	XmToggleButtonSetState(XmFontS_italic_toggle(fsw), set, False);
1446 	SetFlag(&(XmFontS_user_state(fsw)), ITALIC, set);
1447 	XtSetSensitive(XmFontS_italic_toggle(fsw), False);
1448     }
1449     else {
1450 	XtSetSensitive(XmFontS_italic_toggle(fsw), True);
1451     }
1452 
1453     if (CheckFlag(XmFontS_user_state(fsw), ITALIC))
1454 	strcpy(cf->slant, XrmQuarkToString(fam->italic_nameq));
1455     else
1456 	strcpy(cf->slant, XrmQuarkToString(fam->upright_nameq));
1457 }
1458 
1459 /*	Function Name:  UpdateFixedProportional
1460  *	Description: Updates the string stored in the fixed/proportional
1461  *                   part of the current font data.
1462  *	Arguments: fsw - the font selector widget.
1463  *	Returns: none.
1464  */
1465 
1466 static void
UpdateFixedProportional(XmFontSelectorWidget fsw)1467 UpdateFixedProportional(XmFontSelectorWidget fsw)
1468 {
1469     FontData 	*cf = XmFontS_font_info(fsw)->current_font;
1470     FamilyInfo 	*fam;
1471     Boolean	setMono, setProp, setAny;
1472 
1473     if ((fam = FindFamily(cf->familyq, XmFontS_font_info(fsw)->family_info,
1474 			  XmFontS_font_info(fsw)->num_families)) == NULL)
1475     {
1476 	String params[1];
1477 	Cardinal num = 1;
1478 
1479 	params[0] = XrmQuarkToString(cf->familyq);
1480 	dbg(); _XmWarningMsg((Widget) fsw, XmNcouldNotFindFamilyData,
1481 		XmNcouldNotFindFamilyDataMsg, params, num);
1482 	return;
1483     }
1484 
1485     if (CheckFlag(XmFontS_user_state(fsw), USER_PROPORTIONAL)) {
1486 	if (CheckFlag(XmFontS_user_state(fsw), USER_FIXED))
1487 	{
1488 	    strcpy(cf->spacing, STAR_STRING);
1489 	    setMono = False; setProp = False; setAny = True;
1490 	}
1491 	else
1492 	{
1493 	    strcpy(cf->spacing, PROPORTIONAL_SPACING);
1494 	    setMono = False; setProp = True; setAny = False;
1495 	}
1496     }
1497     else if (CheckFlag(XmFontS_user_state(fsw), USER_FIXED))
1498     {
1499 	strcpy(cf->spacing, fam->fixed_spacing);
1500 	setMono = True; setProp = False; setAny = False;
1501     }
1502     else
1503     {
1504 	strcpy(cf->spacing, STAR_STRING);
1505 	setMono = False; setProp = False; setAny = True;
1506     }
1507     if ( XmFontS_monospace(fsw) != NULL )
1508 	XmToggleButtonSetState(XmFontS_monospace(fsw), setMono, False);
1509     if ( XmFontS_proportional(fsw) != NULL )
1510 	XmToggleButtonSetState(XmFontS_proportional(fsw), setProp, False);
1511     if ( XmFontS_any_spacing(fsw) != NULL )
1512 	XmToggleButtonSetState(XmFontS_any_spacing(fsw), setAny, False);
1513 }
1514 
1515 /*	Function Name: UpdateFamilies
1516  *	Description: Updates the displayed families.
1517  *	Arguments: fsw - the file selector widget.
1518  *	Returns: none
1519  */
1520 
1521 static void
UpdateFamilies(XmFontSelectorWidget fsw)1522 UpdateFamilies(XmFontSelectorWidget fsw)
1523 {
1524     Arg largs[10];
1525     Cardinal num_largs;
1526     register int count;
1527     register int i, num;
1528     XmString *strs;
1529     LongFlag size_flag;
1530     FamilyInfo *fam = XmFontS_font_info(fsw)->family_info;
1531     FontData *cf = XmFontS_font_info(fsw)->current_font;
1532     Boolean str_match = False;
1533     String temp;
1534 
1535     num = XmFontS_font_info(fsw)->num_families;
1536 
1537     strs = (XmString *) XtMalloc(sizeof(XmString) * num);
1538     size_flag = SizeMapping(cf->point_size);
1539     for (i = count = 0; i < num; i++, fam++) {
1540 	Boolean ok_75, ok_100, spacing_match, resolution_ok, has_sizes;
1541 
1542 	/*
1543 	 * Only add this family if:
1544 	 *
1545 	 * The size is 0 (ANY SIZE) and there is a font of the current
1546 	 * right DPI, or
1547 	 * This is a scaled font and scaling is turned on, or
1548 	 * This font has current point size in 75 dpi and 75 or any selectd, or
1549 	 * This font has current point size in 100 dpi and 100 or any selectd.
1550 	 *
1551 	 * And
1552 	 * The Charset/Encodings match or any is selected.
1553 	 * The type of spacing matches.
1554 	 * This is a scaled font or there are some valid sizes
1555 	 * in the current point size.
1556 	 */
1557 
1558 	ok_75 = ((size_flag != 0) &&
1559 		 CheckFlag(XmFontS_user_state(fsw), DPI_75) &&
1560 		 CheckLongFlag(fam->sizes_75, size_flag));
1561 
1562 	ok_100 = ((size_flag != 0) &&
1563 		  CheckFlag(XmFontS_user_state(fsw), DPI_100) &&
1564 		  CheckLongFlag(fam->sizes_100, size_flag));
1565 
1566 	resolution_ok = (cf->resolution_x == 0) && (cf->resolution_y == 0);
1567 
1568 	resolution_ok |= (CheckFlag(XmFontS_user_state(fsw), DPI_75) &&
1569 			  CheckFlag(fam->state, DPI_75));
1570 
1571 	resolution_ok |= (CheckFlag(XmFontS_user_state(fsw), DPI_100) &&
1572 			  CheckFlag(fam->state, DPI_100));
1573 
1574 	if (!(has_sizes = IsScaled(fsw, fam))) {
1575 	    has_sizes |= ((fam->sizes_75 != 0) &&
1576 			  CheckFlag(XmFontS_user_state(fsw), DPI_75));
1577 
1578 	    has_sizes |= ((fam->sizes_100 != 0) &&
1579 			  CheckFlag(XmFontS_user_state(fsw), DPI_100));
1580 	}
1581 
1582 	/*
1583 	 * The Any Family will match all spacings.
1584 	 */
1585 
1586 	spacing_match = (i == ANY_FAMILY);
1587 
1588 	spacing_match |= (CheckFlag(XmFontS_user_state(fsw), USER_PROPORTIONAL) &&
1589 			  CheckFlag(fam->state, PROPORTIONAL));
1590 
1591 	spacing_match |= (CheckFlag(XmFontS_user_state(fsw), USER_FIXED) &&
1592 			  !CheckFlag(fam->state, PROPORTIONAL));
1593 
1594 	if (((cf->point_size == 0) || IsScaled(fsw, fam) || ok_75 || ok_100) &&
1595 	    CheckEncoding(fsw, fam) && spacing_match &&
1596 	    resolution_ok && has_sizes)
1597 	{
1598 	    strs[count++] = XmStringCreateLocalized(XrmQuarkToString(fam->nameq));
1599 	    str_match |= (fam->nameq == cf->familyq);
1600 	}
1601     }
1602 
1603     num_largs = 0;
1604 
1605     /*
1606      * This font is no longer in the list, reset the list to ANY_STRING
1607      */
1608 
1609     if (!str_match) {
1610 	temp = _XmGetMBStringFromXmString(ANY_STRING(fsw));
1611 
1612 	XtSetArg(largs[num_largs], XmNvalue, temp); num_largs++;
1613     }
1614     else
1615 	temp = NULL;
1616 
1617     XtSetArg(largs[num_largs], XmNitems, strs); num_largs++;
1618     XtSetArg(largs[num_largs], XmNitemCount, count); num_largs++;
1619     XtSetValues(XmFontS_family_box(fsw), largs, num_largs);
1620 
1621     if (!str_match)
1622 	FamilyChanged(XmFontS_family_box(fsw), (XtPointer) fsw, NULL);
1623 
1624     for (count--; count >= 0; count--)
1625 	XmStringFree(strs[count]);
1626     XtFree((XtPointer) strs);
1627     XtFree((XtPointer) temp);
1628 }
1629 
1630 /*	Function Name: UpdateSizes
1631  *	Description: Updates the list of sizes.
1632  *	Arguments: fsw - the font selector widget.
1633  *	Returns: none.
1634  */
1635 
1636 static void
UpdateSizes(XmFontSelectorWidget fsw)1637 UpdateSizes(XmFontSelectorWidget fsw)
1638 {
1639     FontData * cf = XmFontS_font_info(fsw)->current_font;
1640     Arg largs[10];
1641     Cardinal num_largs = 0;
1642     register int count = 0;
1643     register int i, size;
1644     XmString *strs;
1645     LongFlag size_flag;
1646     FamilyInfo *family;
1647     Boolean editable, match = False;
1648     String temp = NULL;
1649 
1650     if ((family = FindFamily(XmFontS_font_info(fsw)->current_font->familyq,
1651 			     XmFontS_font_info(fsw)->family_info,
1652 			     XmFontS_font_info(fsw)->num_families)) == NULL)
1653     {
1654 	String params[1];
1655 	Cardinal num = 1;
1656 
1657 	params[0] = XrmQuarkToString(cf->familyq);
1658 	dbg(); _XmWarningMsg((Widget) fsw, XmNcouldNotFindFamilyData,
1659 		XmNcouldNotFindFamilyDataMsg, params, num);
1660 	return;
1661     }
1662 
1663     if (IsScaled(fsw, family)) {
1664 	family = XmFontS_font_info(fsw)->family_info + ANY_FAMILY;
1665 	editable = True;
1666     }
1667     else {
1668 	editable = False;
1669     }
1670 
1671     size_flag = 0;
1672     if (CheckFlag(XmFontS_user_state(fsw), DPI_75))
1673 	size_flag |= family->sizes_75;
1674     if (CheckFlag(XmFontS_user_state(fsw), DPI_100))
1675 	size_flag |= family->sizes_100;
1676 
1677     size = sizeof(LongFlag) * 8; /* There are 8 bits in a BYTE */
1678     strs = (XmString *) XtMalloc(sizeof(XmString) * (size + 1));
1679     /*
1680      * DMS - fix to work around apparent Motif 1.2.4 bug concerning
1681      *       XmStrings containing as the empty string
1682      */
1683     if (XmStringEmpty(ANY_STRING(fsw)))
1684         strs[count++] = XmStringCreateLocalized(" ");
1685     else
1686         strs[count++] = XmStringCopy(ANY_STRING(fsw));
1687 
1688     for (i = 0; i < XtNumber(GValidSizes); i++) {
1689 	char buf[10];
1690 	LongFlag flag = ((LongFlag) 1) << i;
1691 
1692 	if (!CheckLongFlag(size_flag, flag) && !IsScaled(fsw, family))
1693 	    continue;
1694 
1695 	sprintf(buf, "%d", GValidSizes[i]);
1696 	strs[count++] = XmStringCreateLocalized(buf);
1697 
1698 	match |= (SizeMapping(cf->point_size) == flag);
1699     }
1700 
1701     if (!match) {
1702 	temp = _XmGetMBStringFromXmString(ANY_STRING(fsw));
1703 
1704 	XtSetArg(largs[num_largs], XmNvalue, temp); num_largs++;
1705     }
1706 
1707     XtSetArg(largs[num_largs], XmNitems, strs); num_largs++;
1708     XtSetArg(largs[num_largs], XmNitemCount, count); num_largs++;
1709     XtSetArg(largs[num_largs], XmNeditable, editable); num_largs++;
1710     XtSetValues(XmFontS_size_box(fsw), largs, num_largs);
1711 
1712 
1713     if (!match)
1714 	SizeChanged(XmFontS_size_box(fsw), (XtPointer) fsw, NULL);
1715 
1716     for (count--; count >= 0; count--)
1717 	XmStringFree(strs[count]);
1718     XtFree((XtPointer) strs);
1719     XtFree((XtPointer) temp);
1720 }
1721 
1722 /*	Function Name: SetComboValue
1723  *	Description: Sets the value field of a Combination box.
1724  *	Arguments: box - the combo box.
1725  *                 value - the value to set.
1726  *	Returns: none.
1727  */
1728 
1729 static void
SetComboValue(Widget box,String value)1730 SetComboValue(Widget box, String value)
1731 {
1732     Arg largs[10];
1733     Cardinal num_largs = 0;
1734 
1735     XtSetArg(largs[num_largs], XmNvalue, value); num_largs++;
1736     XtSetValues(box, largs, num_largs);
1737 }
1738 
1739 /*	Function Name: UnsetSiblings
1740  *	Description: Unsets all sibling toggles of this toggle.
1741  *	Arguments: w - the toggle who's siblings we are unsetting.
1742  *	Returns: none.
1743  */
1744 
1745 static void
UnsetSiblings(Widget w)1746 UnsetSiblings(Widget w)
1747 {
1748     WidgetList children;
1749     Cardinal num_children;
1750     Arg largs[10];
1751     Cardinal i, num_largs = 0;
1752 
1753     XtSetArg(largs[num_largs], XmNchildren, &children); num_largs++;
1754     XtSetArg(largs[num_largs], XmNnumChildren, &num_children); num_largs++;
1755     XtGetValues(XtParent(w), largs, num_largs);
1756 
1757     for (i = 0; i < num_children; i++)
1758 	XmToggleButtonSetState(children[i], (children[i] == w), False);
1759 }
1760 
1761 /*	Function Name: DisplayUserError
1762  *	Description: Displays an error message to the user.
1763  *	Arguments: fsw - the font selector widget.
1764  *                 msg - the message to display.
1765  *	Returns: none
1766  *
1767  * NOTE: If (msg == NULL) then the value of current_text will be placed
1768  *       in the text widget.
1769  */
1770 
1771 static void
DisplayUserError(XmFontSelectorWidget fsw,String msg)1772 DisplayUserError(XmFontSelectorWidget fsw, String msg)
1773 {
1774     String temp;
1775     if (msg != NULL) {
1776 	/*
1777 	 * If the real text is already in current_text then do not
1778 	 * attempt to get it out of the widget, just use what we have
1779 	 * saved already, this hackery is necessary because of the
1780 	 * wierd state machine that is in this code.
1781 	 *
1782 	 * The problem being solved is that this should work if we call
1783 	 * DisplayUserError if a user error is already being displayed.
1784 	 */
1785 
1786 	if (XmFontS_current_text(fsw) != NULL) {
1787 	    temp = XmFontS_current_text(fsw);
1788 	    XmFontS_current_text(fsw) = NULL;
1789 	}
1790 	else
1791 	    temp = XmTextGetString(XmFontS_text(fsw));
1792 
1793 	XmTextSetString(XmFontS_text(fsw), msg);
1794 	XmFontS_current_text(fsw) = temp;
1795 
1796 	XmProcessTraversal(XmFontS_text(fsw), XmTRAVERSE_CURRENT);
1797     }
1798     else {
1799 	if (XmFontS_current_text(fsw) == NULL)
1800 	    return;		/* noting to do. */
1801 
1802 	temp = XmFontS_current_text(fsw);
1803 	XmFontS_current_text(fsw) = NULL;
1804 
1805 	XmTextSetString(XmFontS_text(fsw), temp);
1806 	XtFree((XtPointer) temp);
1807     }
1808 }
1809 
1810 /*	Function Name: SetResolution
1811  *	Description: Sets the DPI toggles based on the FontData passed.
1812  *	Arguments: fsw - the font selector widget.
1813  *                 cf - the font data to use.
1814  *	Returns: none.
1815  */
1816 
1817 static void
SetResolution(XmFontSelectorWidget fsw,FontData * cf)1818 SetResolution(XmFontSelectorWidget fsw, FontData *cf)
1819 {
1820     Boolean	set75, set100, setAny;
1821 
1822     if ( cf->resolution_x != cf->resolution_y )
1823     {
1824 	set75 = False;
1825 	set100 = False;
1826 	setAny = True;
1827     }
1828     else if ( XmFontS_font_info(fsw)->current_font->resolution_x == 75 )
1829     {
1830 	set75 = True;
1831 	set100 = False;
1832 	setAny = False;
1833     }
1834     else if ( XmFontS_font_info(fsw)->current_font->resolution_x == 100 )
1835     {
1836 	set75 = False;
1837 	set100 = True;
1838 	setAny = False;
1839     }
1840     else
1841     {
1842 	set75 = False;
1843 	set100 = False;
1844 	setAny = True;
1845     }
1846     XmToggleButtonSetState(XmFontS_dpi75(fsw), set75, False);
1847     XmToggleButtonSetState(XmFontS_dpi100(fsw), set100, False);
1848     XmToggleButtonSetState(XmFontS_dpiAny(fsw), setAny, False);
1849 }
1850 
1851 /*	Function Name: SetDisplayedFont
1852  *	Description: Sets the font to be displayed.
1853  *	Arguments: fsw - the font selector widget.
1854  *                 font - the font to be displayed.
1855  *	Returns: none.
1856  */
1857 
1858 static void
SetDisplayedFont(XmFontSelectorWidget fsw,String new_font)1859 SetDisplayedFont(XmFontSelectorWidget fsw, String new_font)
1860 {
1861     Boolean 	set;
1862     Arg 	largs[10];
1863     Cardinal 	num_largs;
1864     FontData 	*cf = XmFontS_font_info(fsw)->current_font;
1865     char 	buf[BUFSIZ];
1866 
1867     sprintf(buf, "--%s-%s-%s----0-%d-%d-*--%s",
1868 	    STAR_STRING, DEFAULT_WEIGHT, DEFAULT_SLANT,
1869 	    XmFontS_font_info(fsw)->resolution,
1870 	    XmFontS_font_info(fsw)->resolution, ENCODING_STRING(fsw));
1871 
1872     FillData(fsw, cf, buf);		/* Put in default data. */
1873 
1874     if (new_font != NULL) {
1875 	if (IsXlfdFont(new_font))
1876 	    FillData(fsw, cf, new_font);
1877 	else {
1878 	    if (strchr(new_font, '-')) {
1879 		String params[1];
1880 		Cardinal num = 1;
1881 
1882 		params[0] = new_font;
1883 		dbg(); _XmWarningMsg((Widget) fsw, XmNbadXlfdFont,
1884 			XmNbadXlfdFontMsg, params, num);
1885 	    }
1886 	    else {
1887 		ChangeMode(fsw, False, False);
1888 		SetComboValue(XmFontS_family_box(fsw), new_font);
1889 
1890 		/*
1891 		 * For optomization of FamilyChanged Only.
1892 		 */
1893 
1894 		cf->familyq = XrmStringToQuark(new_font);
1895 		return;
1896 	    }
1897 	}
1898     }
1899 
1900     num_largs = 0;
1901     set = CheckFlag(cf->state, ITALIC);
1902     SetFlag(&(XmFontS_user_state(fsw)), ITALIC, set);
1903     XtSetArg(largs[num_largs], XmNset, set); num_largs++;
1904     XtSetValues(XmFontS_italic_toggle(fsw), largs, num_largs);
1905 
1906     num_largs = 0;
1907     set = CheckFlag(cf->state, BOLD);
1908     SetFlag(&(XmFontS_user_state(fsw)), BOLD, set);
1909     XtSetArg(largs[num_largs], XmNset, set); num_largs++;
1910     XtSetValues(XmFontS_bold_toggle(fsw), largs, num_largs);
1911 
1912     SetComboValue(XmFontS_family_box(fsw), XrmQuarkToString(cf->familyq));
1913     sprintf(buf, "%d", cf->point_size / POINT_DIVIDE);
1914     SetComboValue(XmFontS_size_box(fsw), buf);
1915 
1916     SetResolution(fsw, cf);
1917 
1918     XmCopyISOLatin1Lowered(buf, cf->spacing);
1919     if ( strstr(buf, STAR_STRING) != NULL )
1920     {
1921 	SetFlag(&(XmFontS_user_state(fsw)), USER_PROPORTIONAL | USER_FIXED, True);
1922     }
1923     else if ( strstr(buf, DEFAULT_FIXED_SPACING) != NULL ||
1924 	      strstr(buf, OTHER_FIXED_SPACING)	!= NULL )
1925     {
1926 	SetFlag(&(XmFontS_user_state(fsw)), USER_FIXED, True);
1927 	SetFlag(&(XmFontS_user_state(fsw)), USER_PROPORTIONAL, False);
1928     }
1929     else if ( strstr(buf, PROPORTIONAL_SPACING) != NULL )
1930     {
1931     	SetFlag(&(XmFontS_user_state(fsw)), USER_PROPORTIONAL, True);
1932 	SetFlag(&(XmFontS_user_state(fsw)), USER_FIXED, False);
1933     }
1934     else
1935     {
1936 	SetFlag(&(XmFontS_user_state(fsw)), USER_PROPORTIONAL | USER_FIXED, True);
1937     }
1938 
1939     UpdateFixedProportional(fsw);
1940 
1941     cf->familyq = NULLQUARK;	/* work around FamilyChanged Optomization. */
1942 
1943     FamilyChanged(XmFontS_family_box(fsw), (XtPointer) fsw, NULL);
1944     UpdateFamilies(fsw);
1945 }
1946 
1947 /************************************************************
1948  *
1949  *  Routines for handling when the change from other <--> xlfd mode
1950  *
1951  ************************************************************/
1952 
1953 /*	Function Name: AddToXlfdOnlyList
1954  *	Description: Adds a widget to the xlfd only list.
1955  *	Arguments: fsw - the font selector.
1956  *                 w - the widget to add.
1957  *	Returns: none.
1958  */
1959 
1960 static void
AddToXlfdOnlyList(XmFontSelectorWidget fsw,Widget w)1961 AddToXlfdOnlyList(XmFontSelectorWidget fsw, Widget w)
1962 {
1963     int num = (int) XmFontS_num_xlfd_only(fsw);
1964     int alloc = (int) XmFontS_alloc_xlfd_only(fsw);
1965 
1966     if (num >= alloc) {
1967 	alloc += WIDGET_LIST_INC;
1968 	XmFontS_xlfd_only(fsw) = (WidgetList) XtRealloc((XtPointer)
1969 						   XmFontS_xlfd_only(fsw),
1970 						   sizeof(Widget) * alloc);
1971 	XmFontS_alloc_xlfd_only(fsw) = alloc;
1972     }
1973 
1974     XmFontS_xlfd_only(fsw)[num] = w;
1975     (XmFontS_num_xlfd_only(fsw))++;
1976 }
1977 
1978 /*	Function Name: AddToXlfdSensitiveList
1979  *	Description: Adds a widget to the xlfd sensitive list.
1980  *	Arguments: fsw - the font selector.
1981  *                 w - the widget to add.
1982  *	Returns: none.
1983  */
1984 
1985 static void
AddToXlfdSensitiveList(XmFontSelectorWidget fsw,Widget w)1986 AddToXlfdSensitiveList(XmFontSelectorWidget fsw, Widget w)
1987 {
1988     int num = (int) XmFontS_num_xlfd_sensitive(fsw);
1989     int alloc = (int) XmFontS_alloc_xlfd_sensitive(fsw);
1990 
1991     if (num >= alloc) {
1992 	alloc += WIDGET_LIST_INC;
1993 	XmFontS_xlfd_sensitive(fsw) = (WidgetList) XtRealloc((XtPointer)
1994 							XmFontS_xlfd_sensitive(fsw),
1995 							sizeof(Widget)* alloc);
1996 	XmFontS_alloc_xlfd_sensitive(fsw) = alloc;
1997     }
1998 
1999     XmFontS_xlfd_sensitive(fsw)[num] = w;
2000     (XmFontS_num_xlfd_sensitive(fsw))++;
2001 }
2002 
2003 /*	Function Name: ChangeMode
2004  *	Description: Changes the mode of the font selector.
2005  *	Arguments: fsw - the file selector widget.
2006  *                 xlfd_mode - If True then change to xlfd mode,
2007  *                             otherwize change to other mode.
2008  *		   force - For other mode - True if we're changing modes
2009  *				false if we're displaying a font
2010  *
2011  *	Returns: none.
2012  */
2013 
2014 static void
ChangeMode(XmFontSelectorWidget fsw,Boolean xlfd_mode,Boolean force)2015 ChangeMode(XmFontSelectorWidget fsw, Boolean xlfd_mode, Boolean force)
2016 {
2017     Arg largs[10];
2018     Cardinal num_largs;
2019     register WidgetList widgets;
2020     register int i, num;
2021     XmString family_label;
2022 
2023     XmFontS_xlfd_mode(fsw) = xlfd_mode; /* remember our current mode. */
2024 
2025     num = (int) XmFontS_num_xlfd_sensitive(fsw);
2026     widgets = XmFontS_xlfd_sensitive(fsw);
2027 
2028     for (i = 0; i < num; i++, widgets++)
2029 	XtSetSensitive(*widgets, xlfd_mode);
2030 
2031     num = (int) XmFontS_num_xlfd_only(fsw);
2032     widgets = XmFontS_xlfd_only(fsw);
2033 
2034     for (i = 0; i < num; i++, widgets++) {
2035 	if (xlfd_mode)
2036 	    XtManageChild(*widgets);
2037 	else
2038 	    XtUnmanageChild(*widgets);
2039     }
2040 
2041     if (xlfd_mode) {
2042 	char buf[BUFSIZ];
2043 	FontData * cf = XmFontS_font_info(fsw)->current_font;
2044 	String temp = _XmGetMBStringFromXmString(ANY_STRING(fsw));
2045 
2046 	family_label = FAMILY_STRING(fsw);
2047 
2048 	/*
2049 	 * Reset the values in the family and size boxes to "any"
2050 	 */
2051 
2052 	SetComboValue(XmFontS_family_box(fsw), temp);
2053 	SetComboValue(XmFontS_size_box(fsw), temp);
2054 
2055 	cf->familyq = XrmStringToQuark(temp);
2056 	cf->point_size = 0;
2057 
2058 	UpdateFamilies(fsw);
2059 	UpdateSizes(fsw);
2060 	UpdateBoldItalic(fsw);
2061 	UpdateFixedProportional(fsw);
2062 
2063 	DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
2064 
2065 	XtFree((XtPointer) temp);
2066     }
2067     else {
2068 	family_label = OTHER_FONT_STRING(fsw);
2069 
2070 	SetOtherList(fsw, force);
2071 
2072     }
2073 
2074     /*
2075      * Set the proper toggle buttons.
2076      */
2077 
2078     UnsetSiblings((xlfd_mode) ? XmFontS_xlfd_toggle(fsw) : XmFontS_other_toggle(fsw));
2079 
2080     num_largs = 0;
2081     XtSetArg(largs[num_largs], XmNlabelString, family_label); num_largs++;
2082     XtSetArg(largs[num_largs], XmNeditable, !xlfd_mode); num_largs++;
2083     XtSetValues(XmFontS_family_box(fsw), largs, num_largs);
2084 }
2085 
2086 /*	Function Name: SetOtherList
2087  *	Description: Fills the other list with a complete list of
2088  *                   all other fonts.
2089  *	Arguments: fsw - the font selector widget.
2090  *			force - True if toggled by user, False if user
2091  *				is setting the current font
2092  *	Returns: none
2093  */
2094 
2095 static void
SetOtherList(XmFontSelectorWidget fsw,Boolean force)2096 SetOtherList(XmFontSelectorWidget fsw, Boolean force)
2097 {
2098     Arg largs[10];
2099     Cardinal num_largs = 0;
2100     register int count;
2101     XmString *strs;
2102     String *others = XmFontS_font_info(fsw)->others;
2103     FontData * cf = XmFontS_font_info(fsw)->current_font;
2104     register int i, num = XmFontS_font_info(fsw)->num_others;
2105     String	curFont = XmFontS_current_font(fsw);
2106 
2107     /*
2108      * Set the current font to the first one on the list.
2109      */
2110 
2111     if (num > 0) {
2112 
2113 	if (force)
2114 	{
2115 	XtSetArg(largs[num_largs], XmNvalue, *others); num_largs++;
2116 
2117 	/*
2118 	 * This only to allow FamilyChanged to be more efficient.
2119 	 */
2120 	cf->familyq = XrmStringToQuark(*others);
2121 	DisplayCurrentFont(fsw, *others);
2122     }
2123 	else
2124 	{
2125 	    XtSetArg(largs[num_largs], XmNvalue, curFont); num_largs++;
2126 	    cf->familyq = XrmStringToQuark(curFont);
2127 	    DisplayCurrentFont(fsw, curFont);
2128 	}
2129     }
2130     else {
2131 	XtSetArg(largs[num_largs], XmNvalue, " "); num_largs++;
2132     }
2133 
2134     strs = (XmString *) XtMalloc(sizeof(XmString) * num);
2135     for (i = count = 0; i < num; i++, others++)
2136 	strs[count++] = XmStringCreateLocalized(*others);
2137 
2138     XtSetArg(largs[num_largs], XmNitems, strs); num_largs++;
2139     XtSetArg(largs[num_largs], XmNitemCount, count); num_largs++;
2140     XtSetValues(XmFontS_family_box(fsw), largs, num_largs);
2141 
2142     for (count--; count >= 0; count--)
2143 	XmStringFree(strs[count]);
2144     XtFree((XtPointer) strs);
2145 }
2146 
2147 /************************************************************
2148  *
2149  *  These routines actually create the children of the font
2150  *  selector.
2151  *
2152  ************************************************************/
2153 
2154 /*	Function Name: CreateChildren
2155  *	Description: Creates all children of the font selector.
2156  *	Arguments: fsw - the font selector.
2157  *                 args, num_args - the argument list.
2158  *	Returns: none.
2159  */
2160 
2161 static void
CreateChildren(XmFontSelectorWidget fsw,ArgList args,Cardinal num_args)2162 CreateChildren(XmFontSelectorWidget fsw, ArgList args, Cardinal num_args)
2163 {
2164     Arg *margs, largs[10];
2165     Cardinal num_largs;
2166     Widget temp, box;
2167     String temp_txt;
2168 
2169     CreateTopWidgets(fsw, (Widget) fsw, args, num_args);
2170     CreateMiddleArea(fsw, args, num_args);
2171 
2172     num_largs = 0;
2173     XtSetArg(largs[num_largs], XmNfillOption, XmFillAll); num_largs++;
2174     XtSetArg(largs[num_largs], XmNmarginHeight, 2); num_largs++;
2175     margs = XtMergeArgLists(largs, num_largs, args, num_args);
2176     box = XtCreateManagedWidget("box", xmButtonBoxWidgetClass,
2177 				(Widget) fsw, margs, num_args + num_largs);
2178     XtFree((XtPointer) margs);
2179 
2180     num_largs = 0;
2181     temp_txt = _XmGetMBStringFromXmString(SAMPLE_TEXT(fsw));
2182     XtSetArg(largs[num_largs], XmNvalue, temp_txt); num_largs++;
2183     XtSetArg(largs[num_largs], XmNeditMode, XmMULTI_LINE_EDIT); num_largs++;
2184     XtSetArg(largs[num_largs], XmNwordWrap, True); num_largs++;
2185     XtSetArg(largs[num_largs], XmNscrollHorizontal, False); num_largs++;
2186     XtSetArg(largs[num_largs], XmNrows, XmFontS_text_rows(fsw)); num_largs++;
2187     margs = XtMergeArgLists(largs, num_largs, args, num_args);
2188     temp = XmCreateScrolledText(box, "text", margs, num_args + num_largs);
2189     XtManageChild(XmFontS_text(fsw) = temp);
2190     XtFree((XtPointer) margs);
2191     XtFree((XtPointer) temp_txt);
2192 
2193     XtAddCallback(temp, XmNlosingFocusCallback,
2194 		  RemoveUserError, (XtPointer) fsw);
2195 
2196     XtAddCallback(temp, XmNmodifyVerifyCallback,
2197 		  RemoveUserError, (XtPointer) fsw);
2198 
2199     num_largs = 0;
2200     XtSetArg(largs[num_largs], XmNskipAdjust, True); num_largs++;
2201     margs = XtMergeArgLists(largs, num_largs, args, num_args);
2202     temp = XtCreateWidget("nameLabel", xmLabelWidgetClass,
2203 			  (Widget) fsw, margs, num_args + num_largs);
2204 
2205     if (XmFontS_show_font_name(fsw))
2206 	XtManageChild(temp);
2207 
2208     XmFontS_name_label(fsw) = temp;
2209     XtFree((XtPointer) margs);
2210 }
2211 
2212 /*	Function Name: CreateTopWidgets
2213  *	Description: Creates the children in the middle area where
2214  *                   fonts are selected.
2215  *	Arguments: fsw - the font selector.
2216  *                 parent - the parent of the created widgets.
2217  *                 args, num_args - the argument list.
2218  *	Returns: none.
2219  */
2220 
2221 static void
CreateTopWidgets(XmFontSelectorWidget fsw,Widget parent,ArgList args,Cardinal num_args)2222 CreateTopWidgets(XmFontSelectorWidget fsw, Widget parent,
2223 		 ArgList args, Cardinal num_args)
2224 {
2225     Arg *margs, largs[10];
2226     Cardinal num_largs;
2227     Widget pane, button;
2228 
2229     num_largs = 0;
2230     XtSetArg(largs[num_largs], XmNorientation, XmHORIZONTAL); num_largs++;
2231     XtSetArg(largs[num_largs], XmNspacing, 2); num_largs++;
2232     XtSetArg(largs[num_largs], XmNmarginWidth, 0); num_largs++;
2233     XtSetArg(largs[num_largs], XmNmarginHeight, 0); num_largs++;
2234     margs = XtMergeArgLists(largs, num_largs, args, num_args);
2235     pane = XtCreateManagedWidget("topPane", xmPanedWidgetClass,
2236 				 parent, margs, num_args + num_largs);
2237     XtFree((XtPointer) margs);
2238 
2239     CreateFamilyBox(fsw, pane, args, num_args);
2240     CreateSizesBox(fsw, pane, args, num_args);
2241     CreateBoldItalicBox(fsw, pane, args, num_args);
2242 
2243     num_largs = 0;
2244     XtSetArg(largs[num_largs], XmNlabelString, OPTION_STRING(fsw));num_largs++;
2245     XtSetArg(largs[num_largs], XmNshadowThickness, 2); num_largs++;
2246     XtSetArg(largs[num_largs], XmNindicatorOn, False); num_largs++;
2247     XtSetArg(largs[num_largs], XmNskipAdjust, True); num_largs++;
2248     margs = XtMergeArgLists(largs, num_largs, args, num_args);
2249     button = XtCreateManagedWidget("optionButton", xmToggleButtonWidgetClass,
2250 				   pane, margs, num_args + num_largs);
2251     XtFree((XtPointer) margs);
2252 
2253     XtAddCallback(button, XmNvalueChangedCallback,
2254 		  ToggleMiddlePane, (XtPointer) fsw);
2255 }
2256 
2257 /*	Function Name: CreateMiddleArea
2258  *	Description: Creates the widgets in the top left area.
2259  *                   These are the family, size, bold/italic and proportional
2260  *                   boxes.
2261  *	Arguments: fsw - the file selection widget.
2262  *                 args, num_args - arguments to the font selector (filtered).
2263  *	Returns: none.
2264  */
2265 
2266 static void
CreateMiddleArea(XmFontSelectorWidget fsw,ArgList args,Cardinal num_args)2267 CreateMiddleArea(XmFontSelectorWidget fsw, ArgList args, Cardinal num_args)
2268 {
2269     Arg *margs, largs[10];
2270     Cardinal num_largs;
2271     Widget pane, top_pane;
2272 
2273     num_largs = 0;
2274     XtSetArg(largs[num_largs], XmNorientation, XmVERTICAL); num_largs++;
2275     XtSetArg(largs[num_largs], XmNspacing, 2); num_largs++;
2276     XtSetArg(largs[num_largs], XmNmarginWidth, 0); num_largs++;
2277     XtSetArg(largs[num_largs], XmNmarginHeight, 0); num_largs++;
2278     margs = XtMergeArgLists(largs, num_largs, args, num_args);
2279     pane = XtCreateWidget("middlePane", xmPanedWidgetClass,
2280 			  (Widget) fsw, margs, num_args + num_largs);
2281     XtFree((XtPointer) margs);
2282     XmFontS_middle_pane(fsw) = pane;
2283 
2284     num_largs = 0;
2285     XtSetArg(largs[num_largs], XmNorientation, XmHORIZONTAL); num_largs++;
2286     XtSetArg(largs[num_largs], XmNspacing, 2); num_largs++;
2287     XtSetArg(largs[num_largs], XmNmarginWidth, 0); num_largs++;
2288     XtSetArg(largs[num_largs], XmNmarginHeight, 0); num_largs++;
2289     XtSetArg(largs[num_largs], XmNshowSash, False); num_largs++;
2290     margs = XtMergeArgLists(largs, num_largs, args, num_args);
2291     top_pane = XtCreateManagedWidget("leftPane", xmPanedWidgetClass,
2292 				      pane, margs, num_args + num_largs);
2293     XtFree((XtPointer) margs);
2294 
2295     CreateFontChoiceBox(fsw, top_pane, args, num_args);
2296     CreateResolutionBox(fsw, top_pane, args, num_args);
2297 
2298     CreateSpacingBox(fsw, pane, args, num_args);
2299     CreateOtherChoiceBox(fsw, pane, args, num_args);
2300 }
2301 
2302 /*	Function Name: CreateFamilyBox
2303  *	Description: Creates the family Family box.
2304  *	Arguments: fsw - the file selection widget.
2305  *                 parent - the parent of this area.
2306  *                 args, num_args - arguments to the font selector (filtered).
2307  *	Returns: none.
2308  */
2309 
2310 static void
CreateFamilyBox(XmFontSelectorWidget fsw,Widget parent,ArgList args,Cardinal num_args)2311 CreateFamilyBox(XmFontSelectorWidget fsw, Widget parent,
2312 		ArgList args, Cardinal num_args)
2313 {
2314     Widget c_box;
2315     Cardinal num_largs;
2316     Arg *margs, largs[15];
2317     String temp = _XmGetMBStringFromXmString(ANY_STRING(fsw));
2318 
2319     num_largs = 0;
2320     XtSetArg(largs[num_largs], XmNlabelString,FAMILY_STRING(fsw)); num_largs++;
2321     XtSetArg(largs[num_largs], XmNshowSash, False); num_largs++;
2322     XtSetArg(largs[num_largs], XmNcolumns, FAMILY_COLUMNS); num_largs++;
2323     XtSetArg(largs[num_largs], XmNpopupOffset, 0); num_largs++;
2324     XtSetArg(largs[num_largs], XmNverticalMargin, 0); num_largs++;
2325     XtSetArg(largs[num_largs], XmNhorizontalMargin, 0); num_largs++;
2326     XtSetArg(largs[num_largs], XmNverify, False); num_largs++;
2327     XtSetArg(largs[num_largs], XmNeditable, False); num_largs++;
2328     XtSetArg(largs[num_largs], XmNvisibleItemCount, VISIBILE_FAMILIES);
2329     num_largs++;
2330     /*
2331      * This may cause a problem in Motif I18N applications with 1.2
2332      */
2333 
2334     XtSetArg(largs[num_largs], XmNvalue, temp); num_largs++;
2335 
2336     margs = XtMergeArgLists(largs, num_largs, args, num_args);
2337     c_box = XtCreateManagedWidget("families", xmDropDownWidgetClass,
2338 				  parent, margs, num_args + num_largs);
2339 
2340     XtAddCallback(c_box, XmNverifyTextCallback, FamilyChanged, (XtPointer)fsw);
2341     XtAddCallback(c_box, XmNupdateTextCallback, FamilyChanged, (XtPointer)fsw);
2342 
2343     XtFree((XtPointer) margs);
2344     XtFree((XtPointer) temp);
2345     XmFontS_family_box(fsw) = c_box;
2346 }
2347 
2348 /*	Function Name: CreateSizesBox
2349  *	Description: Creates the box for the sizes
2350  *	Arguments: fsw - the file selection widget.
2351  *                 parent - the parent of this area.
2352  *                 args, num_args - arguments to the font selector (filtered).
2353  *	Returns: none.
2354  *
2355  * NOTE: List is constructed later in UpdateSizes.
2356  */
2357 
2358 static void
CreateSizesBox(XmFontSelectorWidget fsw,Widget parent,ArgList args,Cardinal num_args)2359 CreateSizesBox(XmFontSelectorWidget fsw, Widget parent,
2360 	       ArgList args, Cardinal num_args)
2361 {
2362     Widget c_box;
2363     Cardinal num_largs;
2364     Arg *margs, largs[15];
2365     String temp;
2366 
2367 
2368 
2369     num_largs = 0;
2370     XtSetArg(largs[num_largs], XmNlabelString, SIZE_STRING(fsw)); num_largs++;
2371     XtSetArg(largs[num_largs], XmNshowSash, False); num_largs++;
2372     XtSetArg(largs[num_largs], XmNcolumns, 4); num_largs++;
2373     XtSetArg(largs[num_largs], XmNmaxLength, 3); num_largs++;
2374     XtSetArg(largs[num_largs], XmNpopupOffset, 0); num_largs++;
2375     XtSetArg(largs[num_largs], XmNverticalMargin, 0); num_largs++;
2376     XtSetArg(largs[num_largs], XmNhorizontalMargin, 0); num_largs++;
2377     XtSetArg(largs[num_largs], XmNverify, False); num_largs++;
2378     XtSetArg(largs[num_largs], XmNskipAdjust, True); num_largs++;
2379     XtSetArg(largs[num_largs], XmNvisibleItemCount, VISIBILE_FAMILIES);
2380     num_largs++;
2381 
2382     temp = _XmGetMBStringFromXmString(ANY_STRING(fsw));
2383     XtSetArg(largs[num_largs], XmNvalue, temp); num_largs++;
2384 
2385     margs = XtMergeArgLists(largs, num_largs, args, num_args);
2386     c_box = XtCreateManagedWidget("sizes", xmDropDownWidgetClass,
2387 				  parent, margs, num_args + num_largs);
2388     XtFree(temp);
2389     AddToXlfdOnlyList(fsw, c_box);
2390 
2391     XtAddCallback(c_box, XmNverifyTextCallback, SizeChanged, (XtPointer)fsw);
2392     XtAddCallback(c_box, XmNupdateTextCallback, SizeChanged, (XtPointer)fsw);
2393 
2394     XtFree((XtPointer) margs);
2395     XmFontS_size_box(fsw) = c_box;
2396 }
2397 
2398 /*	Function Name: CreateBoldItalicBox
2399  *	Description: Creates the bold and italic choice box.
2400  *	Arguments: fsw - the file selection widget.
2401  *                 parent - the parent of this area.
2402  *                 args, num_args - arguments to the font selector (filtered).
2403  *	Returns: none.
2404  */
2405 
2406 static void
CreateBoldItalicBox(XmFontSelectorWidget fsw,Widget parent,ArgList args,Cardinal num_args)2407 CreateBoldItalicBox(XmFontSelectorWidget fsw, Widget parent,
2408 		    ArgList args, Cardinal num_args)
2409 {
2410     Widget box, button;
2411     Cardinal num_largs, num_str;
2412     Arg *margs, largs[10];
2413 
2414     num_largs = 0;
2415     XtSetArg(largs[num_largs], XmNorientation, XmHORIZONTAL); num_largs++;
2416     XtSetArg(largs[num_largs], XmNshowSash, False); num_largs++;
2417     XtSetArg(largs[num_largs], XmNskipAdjust, True); num_largs++;
2418     margs = XtMergeArgLists(largs, num_largs, args, num_args);
2419     box = XtCreateManagedWidget("boldItalicBox", xmButtonBoxWidgetClass,
2420 				parent, margs, num_args + num_largs);
2421     AddToXlfdOnlyList(fsw, box);
2422     XtFree((XtPointer) margs);
2423 
2424     num_largs = 0;
2425     XtSetArg(largs[num_largs], XmNlabelString, BOLD_STRING(fsw));
2426     num_str = num_largs++;
2427     XtSetArg(largs[num_largs], XmNindicatorType, XmN_OF_MANY); num_largs++;
2428     XtSetArg(largs[num_largs], XmNalignment, XmALIGNMENT_BEGINNING);
2429     num_largs++;
2430     margs = XtMergeArgLists(largs, num_largs, args, num_args);
2431     button = XtCreateManagedWidget("boldButton", xmToggleButtonWidgetClass,
2432 				   box, margs, num_args + num_largs);
2433     XmFontS_bold_toggle(fsw) = button;
2434     XtAddCallback(button, XmNvalueChangedCallback, ToggleBold, (XtPointer)fsw);
2435 
2436     margs[num_str].value = (XtArgVal) ITALIC_STRING(fsw);
2437     button = XtCreateManagedWidget("italicButton", xmToggleButtonWidgetClass,
2438 				   box, margs, num_args + num_largs);
2439     XmFontS_italic_toggle(fsw) = button;
2440     XtAddCallback(button,
2441 		  XmNvalueChangedCallback, ToggleItalic, (XtPointer) fsw);
2442 
2443     XtFree((XtPointer) margs);
2444 }
2445 
2446 /*	Function Name: CreateSpacingBox
2447  *	Description: Creates the spacing choice box.
2448  *	Arguments: fsw - the file selection widget.
2449  *                 parent - the parent of this area.
2450  *                 args, num_args - arguments to the font selector (filtered).
2451  *	Returns: none.
2452  */
2453 
2454 static void
CreateSpacingBox(XmFontSelectorWidget fsw,Widget parent,ArgList args,Cardinal num_args)2455 CreateSpacingBox(XmFontSelectorWidget fsw, Widget parent,
2456 		 ArgList args, Cardinal num_args)
2457 {
2458     Widget box, button;
2459     Cardinal num_largs, num_str, num_set;
2460     Arg *margs, largs[10];
2461 
2462     num_largs = 0;
2463     XtSetArg(largs[num_largs], XmNorientation, XmHORIZONTAL); num_largs++;
2464     XtSetArg(largs[num_largs], XmNshowSash, False); num_largs++;
2465     XtSetArg(largs[num_largs], XmNfillOption, XmFillMajor); num_largs++;
2466     XtSetArg(largs[num_largs], XmNequalSize, True); num_largs++;
2467     margs = XtMergeArgLists(largs, num_largs, args, num_args);
2468     box = XtCreateManagedWidget("spacingBox", xmButtonBoxWidgetClass,
2469 				parent, margs, num_args + num_largs);
2470     AddToXlfdSensitiveList(fsw, box);
2471     XtFree((XtPointer) margs);
2472 
2473     num_largs = 0;
2474     XtSetArg(largs[num_largs], XmNset, False); num_set = num_largs++;
2475     XtSetArg(largs[num_largs], XmNlabelString, PROPORTIONAL_STRING(fsw));
2476     num_str = num_largs++;
2477     XtSetArg(largs[num_largs], XmNindicatorType, XmONE_OF_MANY); num_largs++;
2478     XtSetArg(largs[num_largs], XmNalignment, XmALIGNMENT_BEGINNING);
2479     num_largs++;
2480     margs = XtMergeArgLists(largs, num_largs, args, num_args);
2481     button = XtCreateManagedWidget("proportionalButton",
2482 				   xmToggleButtonWidgetClass,
2483 				   box, margs, num_args + num_largs);
2484     XtAddCallback(button, XmNvalueChangedCallback, ToggleProportional,
2485 		  (XtPointer) fsw);
2486     XmFontS_proportional(fsw) = button;
2487 
2488     margs[num_str].value = (XtArgVal) MONO_SPACE_STRING(fsw);
2489     button = XtCreateManagedWidget("monoButton", xmToggleButtonWidgetClass,
2490 				   box, margs, num_args + num_largs);
2491     XtAddCallback(button, XmNvalueChangedCallback, ToggleFixed,
2492 		  (XtPointer) fsw);
2493     XmFontS_monospace(fsw) = button;
2494 
2495     margs[num_str].value = (XtArgVal) BOTH_STRING(fsw);
2496     margs[num_set].value = (XtArgVal) True;
2497     button = XtCreateManagedWidget("bothButton", xmToggleButtonWidgetClass,
2498 				   box, margs, num_args + num_largs);
2499     XtAddCallback(button, XmNvalueChangedCallback, ToggleBothSpacing,
2500 		  (XtPointer) fsw);
2501     XmFontS_any_spacing(fsw) = button;
2502     SetFlag(&(XmFontS_user_state(fsw)), USER_FIXED | USER_PROPORTIONAL, True);
2503     XtFree((XtPointer) margs);
2504 }
2505 
2506 /*	Function Name: CreateFontChoiceBox
2507  *	Description: Create a box to choose between xlfd fonts and others.
2508  *	Arguments: fsw - the file selection widget.
2509  *                 parent - the parent of this area.
2510  *                 args, num_args - arguments to the font selector (filtered).
2511  *	Returns: none.
2512  */
2513 
2514 static void
CreateFontChoiceBox(XmFontSelectorWidget fsw,Widget parent,ArgList args,Cardinal num_args)2515 CreateFontChoiceBox(XmFontSelectorWidget fsw, Widget parent,
2516 		    ArgList args, Cardinal num_args)
2517 {
2518     Widget box, button;
2519     Cardinal num_largs, num_str, num_set;
2520     Arg *margs, largs[10];
2521 
2522     num_largs = 0;
2523     XtSetArg(largs[num_largs], XmNorientation, XmHORIZONTAL); num_largs++;
2524     XtSetArg(largs[num_largs], XmNshowSash, False); num_largs++;
2525     XtSetArg(largs[num_largs], XmNfillOption, XmFillMajor); num_largs++;
2526     XtSetArg(largs[num_largs], XmNequalSize, True); num_largs++;
2527     margs = XtMergeArgLists(largs, num_largs, args, num_args);
2528     box = XtCreateManagedWidget("choiceBox", xmButtonBoxWidgetClass,
2529 				parent, margs, num_args + num_largs);
2530     XtFree((XtPointer) margs);
2531 
2532     num_largs = 0;
2533     XtSetArg(largs[num_largs], XmNlabelString, XLFD_STRING(fsw));
2534     num_str = num_largs++;
2535     XtSetArg(largs[num_largs], XmNset, True); num_set = num_largs++;
2536     XtSetArg(largs[num_largs], XmNindicatorType, XmONE_OF_MANY); num_largs++;
2537     XtSetArg(largs[num_largs], XmNalignment, XmALIGNMENT_BEGINNING);
2538     num_largs++;
2539     margs = XtMergeArgLists(largs, num_largs, args, num_args);
2540     button = XtCreateManagedWidget("xlfdButton",
2541 				   xmToggleButtonWidgetClass,
2542 				   box, margs, num_args + num_largs);
2543     XmFontS_xlfd_toggle(fsw) = button;
2544 
2545     XtAddCallback(button, XmNvalueChangedCallback, XlfdMode, (XtPointer) fsw);
2546 
2547     margs[num_str].value = (XtArgVal) OTHER_FONT_STRING(fsw);
2548     margs[num_set].value = (XtArgVal) False;
2549     button = XtCreateManagedWidget("otherButton", xmToggleButtonWidgetClass,
2550 				   box, margs, num_args + num_largs);
2551     XtAddCallback(button, XmNvalueChangedCallback, OtherMode, (XtPointer) fsw);
2552     XmFontS_other_toggle(fsw) = button;
2553 
2554     XtFree((XtPointer) margs);
2555 }
2556 
2557 /*	Function Name: CreateResolution Box
2558  *	Description: Create the box to allow resolution choice(s).
2559  *	Arguments: fsw - the file selection widget.
2560  *                 parent - the parent of this area.
2561  *                 args, num_args - arguments to the font selector (filtered).
2562  *	Returns: none.
2563  */
2564 
2565 static void
CreateResolutionBox(XmFontSelectorWidget fsw,Widget parent,ArgList args,Cardinal num_args)2566 CreateResolutionBox(XmFontSelectorWidget fsw, Widget parent,
2567 		    ArgList args, Cardinal num_args)
2568 {
2569     Widget box, button;
2570     Cardinal num_largs, num_str, num_set;
2571     Arg *margs, largs[10];
2572 
2573     num_largs = 0;
2574     XtSetArg(largs[num_largs], XmNorientation, XmHORIZONTAL); num_largs++;
2575     XtSetArg(largs[num_largs], XmNshowSash, False); num_largs++;
2576     XtSetArg(largs[num_largs], XmNfillOption, XmFillMajor); num_largs++;
2577     XtSetArg(largs[num_largs], XmNequalSize, True); num_largs++;
2578     margs = XtMergeArgLists(largs, num_largs, args, num_args);
2579     box = XtCreateManagedWidget("resolutionBox", xmButtonBoxWidgetClass,
2580 				parent, margs, num_args + num_largs);
2581     AddToXlfdSensitiveList(fsw, box);
2582     XtFree((XtPointer) margs);
2583 
2584     num_largs = 0;
2585     XtSetArg(largs[num_largs], XmNset, False); num_set = num_largs++;
2586     XtSetArg(largs[num_largs], XmNlabelString, DPI75_STRING(fsw));
2587     num_str = num_largs++;
2588     XtSetArg(largs[num_largs], XmNindicatorType, XmONE_OF_MANY); num_largs++;
2589     XtSetArg(largs[num_largs], XmNalignment, XmALIGNMENT_BEGINNING);
2590     num_largs++;
2591     margs = XtMergeArgLists(largs, num_largs, args, num_args);
2592 
2593     margs[num_set].value = (XtArgVal) (XmFontS_font_info(fsw)->resolution == 75);
2594     button = XtCreateManagedWidget("dpi75Button", xmToggleButtonWidgetClass,
2595 				   box, margs, num_args + num_largs);
2596     XtAddCallback(button, XmNvalueChangedCallback, Toggle75DPI, fsw);
2597     XmFontS_dpi75(fsw) = button;
2598 
2599     margs[num_str].value = (XtArgVal) DPI100_STRING(fsw);
2600     margs[num_set].value = (XtArgVal) (XmFontS_font_info(fsw)->resolution == 100);
2601     button = XtCreateManagedWidget("dpi100Button", xmToggleButtonWidgetClass,
2602 				   box, margs, num_args + num_largs);
2603     XtAddCallback(button, XmNvalueChangedCallback, Toggle100DPI, fsw);
2604     XmFontS_dpi100(fsw) = button;
2605 
2606     margs[num_str].value = (XtArgVal) BOTH_STRING(fsw);
2607     margs[num_set].value = (XtArgVal) False;
2608     button = XtCreateManagedWidget("anyButton", xmToggleButtonWidgetClass,
2609 				   box, margs, num_args + num_largs);
2610     XtAddCallback(button, XmNvalueChangedCallback, ToggleBothDPI, fsw);
2611     XmFontS_dpiAny(fsw) = button;
2612 
2613     XtFree((XtPointer) margs);
2614 }
2615 
2616 /*	Function Name: CreateOtherChoiceBox
2617  *	Description: Creates the box to allow other choices to be made.
2618  *	Arguments: fsw - the file selection widget.
2619  *                 parent - the parent of this area.
2620  *                 args, num_args - arguments to the font selector (filtered).
2621  *	Returns: none.
2622  */
2623 
2624 static void
CreateOtherChoiceBox(XmFontSelectorWidget fsw,Widget parent,ArgList args,Cardinal num_args)2625 CreateOtherChoiceBox(XmFontSelectorWidget fsw, Widget parent,
2626 		     ArgList args, Cardinal num_args)
2627 {
2628     Widget box, button;
2629     Cardinal num_largs, num_str, num_set;
2630     Arg *margs, largs[10];
2631 
2632     num_largs = 0;
2633     XtSetArg(largs[num_largs], XmNorientation, XmHORIZONTAL); num_largs++;
2634     XtSetArg(largs[num_largs], XmNfillOption, XmFillMajor); num_largs++;
2635     XtSetArg(largs[num_largs], XmNequalSize, True); num_largs++;
2636     XtSetArg(largs[num_largs], XmNshowSash, False); num_largs++;
2637     margs = XtMergeArgLists(largs, num_largs, args, num_args);
2638     box = XtCreateManagedWidget("otherChoiceBox", xmButtonBoxWidgetClass,
2639 				parent, margs, num_args + num_largs);
2640     XtFree((XtPointer) margs);
2641 
2642     num_largs = 0;
2643     XtSetArg(largs[num_largs], XmNset, False); num_set = num_largs++;
2644     XtSetArg(largs[num_largs], XmNlabelString, SCALING_STRING(fsw));
2645     num_str = num_largs++;
2646     XtSetArg(largs[num_largs], XmNindicatorType, XmN_OF_MANY); num_largs++;
2647     XtSetArg(largs[num_largs], XmNalignment, XmALIGNMENT_BEGINNING);
2648     num_largs++;
2649     margs = XtMergeArgLists(largs, num_largs, args, num_args);
2650 
2651     margs[num_set].value = (XtArgVal) XmFontS_use_scaling(fsw);
2652     button = XtCreateManagedWidget("scalingButton", xmToggleButtonWidgetClass,
2653 				   box, margs, num_args + num_largs);
2654     XmFontS_use_scaling_toggle(fsw) = button;
2655     AddToXlfdSensitiveList(fsw, button);
2656     XtAddCallback(button, XmNvalueChangedCallback,
2657 		  ToggleScaling, (XtPointer) fsw);
2658 
2659     margs[num_str].value = (XtArgVal) SHOW_NAME_STRING(fsw);
2660     margs[num_set].value = (XtArgVal) XmFontS_show_font_name(fsw);
2661     button = XtCreateManagedWidget("showNameButton",
2662 				   xmToggleButtonWidgetClass,
2663 				   box, margs, num_args + num_largs);
2664     XmFontS_show_font_toggle(fsw) = button;
2665 
2666     XtAddCallback(button, XmNvalueChangedCallback,
2667 		  ToggleNameWindow, (XtPointer) fsw);
2668 
2669     XmFontS_option_menu(fsw) = CreateEncodingMenu(fsw, box, args, num_args);
2670     AddToXlfdSensitiveList(fsw, XmFontS_option_menu(fsw));
2671 
2672     XtFree((XtPointer) margs);
2673 }
2674 
2675 /*	Function Name: CreateEncodingMenu
2676  *	Description: Creates the encoding option menu.
2677  *	Arguments: fsw - The font selector widget.
2678  *                 parent - The parent of the option menu.
2679  *                 args - Args used to create the font selector.
2680  *	Returns: The Id of the menu created.
2681  */
2682 
2683 static Widget
CreateEncodingMenu(XmFontSelectorWidget fsw,Widget box,ArgList args,Cardinal num_args)2684 CreateEncodingMenu(XmFontSelectorWidget fsw,
2685 		   Widget box, ArgList args, Cardinal num_args)
2686 {
2687     Widget   omenu, history = NULL, pulldownMenu, button, menuShell,
2688              destroy_old_menu;
2689     Cardinal num_largs, button_label;
2690     int      current, i;
2691     Arg      *margs, largs[10];
2692     String   *encodings;
2693 
2694     /*
2695      * Create the option menu only the first time through, otherwise
2696      * simply blow away the encoding_menu_shell and recreate that.
2697      */
2698 
2699     destroy_old_menu = XmFontS_encoding_menu_shell(fsw);
2700 
2701     if (destroy_old_menu == NULL)
2702     {
2703 	num_largs = 0;
2704 	XtSetArg(largs[num_largs],
2705 		 XmNrowColumnType, XmMENU_OPTION); num_largs++;
2706 	XtSetArg(largs[num_largs],
2707 		 XmNlabelString, ENCODING_ONLY_STRING(fsw)); num_largs++;
2708 	XtSetArg(largs[num_largs],
2709 		 XmNoptionLabel, ENCODING_ONLY_STRING(fsw)); num_largs++;
2710 	margs = XtMergeArgLists(largs, num_largs, args, num_args);
2711 	omenu = XtCreateWidget("encodingOptionMenu", xmRowColumnWidgetClass,
2712 			       box, margs, num_args + num_largs);
2713 	XtFree((XtPointer) margs);
2714     }
2715     else
2716     {
2717 	omenu = XmFontS_option_menu(fsw);
2718     }
2719 
2720     num_largs = 0;
2721     XtSetArg(largs[num_largs], XmNwidth, 1); num_largs++;
2722     XtSetArg(largs[num_largs], XmNheight, 1); num_largs++;
2723     XtSetArg(largs[num_largs], XmNancestorSensitive, True); num_largs++;
2724     margs = XtMergeArgLists(largs, num_largs, args, num_args);
2725 
2726     menuShell = XtCreatePopupShell("menuShell", xmMenuShellWidgetClass,
2727 				   box, margs, num_args + num_largs);
2728     XtFree((XtPointer) margs);
2729 
2730     XmFontS_encoding_menu_shell(fsw) = menuShell;
2731 
2732     num_largs = 0;
2733     XtSetArg(largs[num_largs], XmNrowColumnType, XmMENU_PULLDOWN); num_largs++;
2734     margs = XtMergeArgLists(largs, num_largs, args, num_args);
2735     pulldownMenu = XtCreateWidget("pulldownMenu",
2736 				  xmRowColumnWidgetClass,
2737 				  menuShell, margs, num_args + num_largs);
2738     XtFree((XtPointer) margs);
2739 
2740     num_largs = 0;
2741     XtSetArg(largs[num_largs], XmNlabelString, ANY_STRING(fsw));
2742     button_label = num_largs++;
2743     margs = XtMergeArgLists(largs, num_largs, args, num_args);
2744 
2745     button = XtCreateManagedWidget("button_0", xmPushButtonWidgetClass,
2746 				   pulldownMenu, margs,
2747 				   num_args + num_largs);
2748 
2749     XtAddCallback(button,
2750 		  XmNactivateCallback, ChangeEncoding, (XtPointer) 0);
2751 
2752     current = 0;
2753     for (i = 1, encodings = ENCODING_LIST(fsw) ;
2754 	 *encodings != NULL; i++, encodings++)
2755     {
2756 	char name[BUFSIZ];
2757 	XmString label = XmStringCreateLocalized(*encodings);
2758 
2759 	margs[button_label].value = (XtArgVal) label;
2760 	sprintf(name, "button_%d", i);
2761 	button = XtCreateManagedWidget(name, xmPushButtonWidgetClass,
2762 				       pulldownMenu, margs,
2763 				       num_args + num_largs);
2764 	XmStringFree(label);
2765 
2766 	XtAddCallback(button,
2767 		      XmNactivateCallback, ChangeEncoding, (XtPointer) i);
2768 
2769 	if (streq(*encodings, ENCODING_STRING(fsw)))
2770 	{
2771 	    current = i;
2772 	    history = button;
2773 	}
2774     }
2775 
2776     XtFree((XtPointer) margs);
2777 
2778     num_largs = 0;
2779     XtSetArg(largs[num_largs], XmNsubMenuId, pulldownMenu); num_largs++;
2780 
2781     /*
2782      * DMS - Fix 2/27/96
2783      */
2784     if (history)
2785     {
2786         XtSetArg(largs[num_largs], XmNmenuHistory, history); num_largs++;
2787     }
2788     XtSetValues(omenu, largs, num_largs);
2789 
2790     if (destroy_old_menu != NULL)
2791     {
2792 	XtDestroyWidget(destroy_old_menu);
2793     }
2794 
2795     XtManageChild(omenu);
2796 
2797     XtFree(ENCODING_STRING(fsw));
2798     if (current == 0)
2799 	ENCODING_STRING(fsw) = XtNewString(ANY_ENCODING);
2800     else
2801 	ENCODING_STRING(fsw) = XtNewString(ENCODING_LIST(fsw)[current - 1]);
2802 
2803     return(omenu);
2804 }
2805 
2806 /*	Function Name: CheckEncoding
2807  *	Description: Checks the encoding of a font to see if it matches
2808  *                   the currently selected one, and returns true on a match.
2809  *	Arguments: fsw - The font selector widget.
2810  *                 fam - The family that we are checking.
2811  *	Returns: True if the encodings matchd, or any is selected.
2812  */
2813 
2814 static Boolean
CheckEncoding(XmFontSelectorWidget fsw,FamilyInfo * fam)2815 CheckEncoding(XmFontSelectorWidget fsw, FamilyInfo *fam)
2816 {
2817     int i;
2818     XrmQuark curr;
2819 
2820     if (streq(ENCODING_STRING(fsw), ANY_ENCODING) || fam->encodings == NULL)
2821 	return(TRUE);
2822 
2823     curr = XrmStringToQuark(ENCODING_STRING(fsw));
2824     for (i = 0; TRUE; i++)
2825     {
2826 	if (fam->encodings[i] == curr)
2827 	    return(True);
2828 
2829 	if (fam->encodings[i] == 0 || i == fam->encoding_alloc)
2830 	    return(False);
2831     }
2832 }
2833 
2834 /************************************************************
2835  *
2836  *  Callbacks.
2837  *
2838  ************************************************************/
2839 
2840 /*	Function Name: FamilyChanged
2841  *	Description: Called when the user changes the family
2842  *	Arguments: w - *** UNUSED ***.
2843  *                 fsw_ptr - pointer to the font selector widget.
2844  *                 junk - *** UNUSED ***.
2845  *	Returns: none
2846  */
2847 
2848 /* ARGSUSED */
2849 static void
FamilyChanged(Widget w,XtPointer fsw_ptr,XtPointer junk)2850 FamilyChanged(Widget w, XtPointer fsw_ptr, XtPointer junk)
2851 {
2852     XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
2853     FontData * cf = XmFontS_font_info(fsw)->current_font;
2854     String str = XmDropDownGetValue(w);
2855     char buf[BUFSIZ];
2856     XrmQuark familyq = XrmStringToQuark(str);
2857 
2858     if (cf->familyq == familyq)
2859 	return;			/* no change. */
2860 
2861     cf->familyq = familyq;
2862 
2863     if (XmFontS_xlfd_mode(fsw)) {
2864 	UpdateBoldItalic(fsw);
2865 	UpdateFixedProportional(fsw);
2866 	UpdateSizes(fsw);
2867 
2868 	DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
2869     }
2870     else {
2871 	DisplayCurrentFont(fsw, str);
2872     }
2873 
2874     XtFree((XtPointer) str);
2875 }
2876 
2877 /*	Function Name: SizeChanged
2878  *	Description: Called when the user changes the Size
2879  *	Arguments: w - *** UNUSED ***.
2880  *                 fsw_ptr - pointer to the font selector widget.
2881  *                 junk - *** UNUSED ***.
2882  *	Returns: none
2883  */
2884 
2885 /* ARGSUSED */
2886 static void
SizeChanged(Widget w,XtPointer fsw_ptr,XtPointer junk)2887 SizeChanged(Widget w, XtPointer fsw_ptr, XtPointer junk)
2888 {
2889     XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
2890     FontData * cf = XmFontS_font_info(fsw)->current_font;
2891     String str = XmDropDownGetValue(w);
2892     char buf[BUFSIZ];
2893     short size;
2894 
2895     if (cf->point_size == (size = atoi(str) * 10))
2896 	{
2897 	XtFree((char*)str);
2898 	return;			/* no change. */
2899 	}
2900 
2901     cf->point_size = size;
2902 
2903     UpdateFamilies(fsw);
2904 
2905     DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
2906     XtFree((XtPointer) str);
2907 }
2908 
2909 /*	Function Name: ChangeEncoding
2910  *	Description: Called when the user changes the encoding.
2911  *	Arguments: w - a widget child of the font sel.
2912  *                 data - pointer to index of the option button.
2913  *                 junk - ***unused
2914  *	Returns: none
2915  */
2916 
2917 /* ARGSUSED */
2918 static void
ChangeEncoding(Widget w,XtPointer data,XtPointer junk)2919 ChangeEncoding(Widget w, XtPointer data, XtPointer junk)
2920 {
2921     XmFontSelectorWidget fsw;
2922     FontData *cf;
2923     char buf[BUFSIZ];
2924 
2925     for ( ; !XtIsSubclass(w, xmFontSelectorWidgetClass); w = XtParent(w)) {}
2926     fsw = (XmFontSelectorWidget) w;
2927     cf = XmFontS_font_info(fsw)->current_font;
2928 
2929     if ((int) data == 0)
2930 	{
2931 	XtFree(ENCODING_STRING(fsw));
2932 	ENCODING_STRING(fsw) = XtNewString(ANY_ENCODING);
2933 	}
2934     else
2935 	{
2936 	XtFree(ENCODING_STRING(fsw));
2937 	ENCODING_STRING(fsw) = XtNewString(ENCODING_LIST(fsw)[(int) data - 1]);
2938 	}
2939 
2940     UpdateFamilies(fsw);
2941     DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
2942 }
2943 
2944 /*	Function Name: ToggleScaling
2945  *	Description: Called when the user toggles the Font Scaling button.
2946  *	Arguments: w - *** UNUSED ***.
2947  *                 fsw_ptr - pointer to the font selector widget.
2948  *                 data - the toggle button data.
2949  *	Returns: none
2950  */
2951 
2952 /* ARGSUSED */
2953 static void
ToggleScaling(Widget w,XtPointer fsw_ptr,XtPointer data)2954 ToggleScaling(Widget w, XtPointer fsw_ptr, XtPointer data)
2955 {
2956     XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
2957     FontData * cf = XmFontS_font_info(fsw)->current_font;
2958     FamilyInfo *family;
2959     XmToggleButtonCallbackStruct *info;
2960     LongFlag map;
2961     char buf[BUFSIZ];
2962 
2963     info = (XmToggleButtonCallbackStruct *) data;
2964     if ((family = FindFamily(cf->familyq, XmFontS_font_info(fsw)->family_info,
2965 			     XmFontS_font_info(fsw)->num_families)) == NULL)
2966     {
2967 	String params[1];
2968 	Cardinal num = 1;
2969 
2970 	params[0] = XrmQuarkToString(cf->familyq);
2971 	dbg(); _XmWarningMsg((Widget) fsw, XmNcouldNotFindFamilyData,
2972 		XmNcouldNotFindFamilyDataMsg, params, num);
2973 	return;
2974     }
2975 
2976     XmFontS_use_scaling(fsw) = info->set;
2977     if (!info->set) {
2978 	Boolean map_bad = (map = SizeMapping(cf->point_size)) == 0;
2979 	Boolean bad_75 = (CheckFlag(XmFontS_user_state(fsw), DPI_75) &&
2980 			  !CheckLongFlag(family->sizes_75, map));
2981 	Boolean bad_100 = (CheckFlag(XmFontS_user_state(fsw), DPI_100) &&
2982 			   !CheckLongFlag(family->sizes_100, map));
2983 
2984 	if (map_bad || bad_75 || (bad_100 && (cf->point_size != 0))) {
2985 	    String temp = _XmGetMBStringFromXmString(ANY_STRING(fsw));
2986 
2987 	    cf->point_size = 0;	/* Reset to Any. */
2988 	    SetComboValue(XmFontS_size_box(fsw), temp);
2989 	    XtFree((XtPointer) temp);
2990 	}
2991     }
2992 
2993     UpdateSizes(fsw);
2994     UpdateFamilies(fsw);
2995     DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
2996 }
2997 
2998 /*	Function Name: ToggleBold
2999  *	Description: Called when the user toggles the bold button.
3000  *	Arguments: w - *** UNUSED ***.
3001  *                 fsw_ptr - pointer to the font selector widget.
3002  *                 data - the toggle button data.
3003  *	Returns: none
3004  */
3005 
3006 /* ARGSUSED */
3007 static void
ToggleBold(Widget w,XtPointer fsw_ptr,XtPointer data)3008 ToggleBold(Widget w, XtPointer fsw_ptr, XtPointer data)
3009 {
3010     XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
3011     FontData * cf = XmFontS_font_info(fsw)->current_font;
3012     FamilyInfo *family;
3013     XmToggleButtonCallbackStruct *info;
3014     char buf[BUFSIZ];
3015 
3016     info = (XmToggleButtonCallbackStruct *) data;
3017     if ((family = FindFamily(cf->familyq, XmFontS_font_info(fsw)->family_info,
3018 			     XmFontS_font_info(fsw)->num_families)) == NULL)
3019     {
3020 	String params[1];
3021 	Cardinal num = 1;
3022 
3023 	params[0] = XrmQuarkToString(cf->familyq);
3024 	dbg(); _XmWarningMsg((Widget) fsw, XmNcouldNotFindFamilyData,
3025 		XmNcouldNotFindFamilyDataMsg, params, num);
3026 
3027 	return;
3028     }
3029 
3030     if (info->set)
3031 	cf->weightq = family->bold_nameq;
3032     else
3033 	cf->weightq = family->medium_nameq;
3034 
3035     SetFlag(&(cf->state), BOLD, info->set);
3036     SetFlag(&(XmFontS_user_state(fsw)), BOLD, info->set);
3037 
3038     DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
3039 }
3040 
3041 /*	Function Name: ToggleItalic
3042  *	Description: Called when the user toggles the italic button.
3043  *	Arguments: w - *** UNUSED ***.
3044  *                 fsw_ptr - pointer to the font selector widget.
3045  *                 data - the toggle button data.
3046  *	Returns: none
3047  */
3048 
3049 /* ARGSUSED */
3050 static void
ToggleItalic(Widget w,XtPointer fsw_ptr,XtPointer data)3051 ToggleItalic(Widget w, XtPointer fsw_ptr, XtPointer data)
3052 {
3053     XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
3054     FontData * cf = XmFontS_font_info(fsw)->current_font;
3055     FamilyInfo *family;
3056     XmToggleButtonCallbackStruct *info;
3057     char buf[BUFSIZ];
3058 
3059     info = (XmToggleButtonCallbackStruct *) data;
3060     if ((family = FindFamily(cf->familyq, XmFontS_font_info(fsw)->family_info,
3061 			     XmFontS_font_info(fsw)->num_families)) == NULL)
3062     {
3063 	String params[1];
3064 	Cardinal num = 1;
3065 
3066 	params[0] = XrmQuarkToString(cf->familyq);
3067 	dbg(); _XmWarningMsg((Widget) fsw, XmNcouldNotFindFamilyData,
3068 		XmNcouldNotFindFamilyDataMsg, params, num);
3069 	return;
3070     }
3071 
3072     if (info->set)
3073 	strcpy(cf->slant, XrmQuarkToString(family->italic_nameq));
3074     else
3075 	strcpy(cf->slant, XrmQuarkToString(family->upright_nameq));
3076 
3077     SetFlag(&(cf->state), ITALIC, info->set);
3078     SetFlag(&(XmFontS_user_state(fsw)), ITALIC, info->set);
3079     DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
3080 }
3081 
3082 /*	Function Name: ToggleMiddlePane
3083  *	Description: toggles whether or not the middle pane is shown
3084  *	Arguments: w - *** UNUSED ***.
3085  *                 fsw_ptr - pointer to the font selector widget.
3086  *                 data - the toggle button data.
3087  *	Returns: none
3088  */
3089 
3090 /* ARGSUSED */
3091 static void
ToggleMiddlePane(Widget w,XtPointer fsw_ptr,XtPointer data)3092 ToggleMiddlePane(Widget w, XtPointer fsw_ptr, XtPointer data)
3093 {
3094     XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
3095     XmToggleButtonCallbackStruct *info;
3096 
3097     info = (XmToggleButtonCallbackStruct *) data;
3098 
3099     if (info->set)
3100 	XtManageChild(XmFontS_middle_pane(fsw));
3101     else
3102 	XtUnmanageChild(XmFontS_middle_pane(fsw));
3103 }
3104 
3105 /*	Function Name: ToggleNameWindow
3106  *	Description: toggles whether or not the middle pane is shown
3107  *	Arguments: w - *** UNUSED ***.
3108  *                 fsw_ptr - pointer to the font selector widget.
3109  *                 data - the toggle button data.
3110  *	Returns: none
3111  */
3112 
3113 /* ARGSUSED */
3114 static void
ToggleNameWindow(Widget w,XtPointer fsw_ptr,XtPointer data)3115 ToggleNameWindow(Widget w, XtPointer fsw_ptr, XtPointer data)
3116 {
3117     XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
3118     XmToggleButtonCallbackStruct *info;
3119     char buf[BUFSIZ];
3120 
3121     info = (XmToggleButtonCallbackStruct *) data;
3122 
3123     XmFontS_show_font_name(fsw) = info->set;
3124     if (info->set) {
3125 	XtManageChild(XmFontS_name_label(fsw));
3126 
3127 	if (XmFontS_xlfd_mode(fsw)) {
3128 	    DisplayCurrentFont(fsw,
3129 			       BuildFontString(fsw,
3130 					       XmFontS_font_info(fsw)->current_font,
3131 					       buf, BUFSIZ));
3132 	}
3133 	else {
3134 	    String str = XmDropDownGetValue(XmFontS_family_box(fsw));
3135 	    DisplayCurrentFont(fsw, str);
3136 	    XtFree((XtPointer) str);
3137 	}
3138     }
3139     else
3140 	XtUnmanageChild(XmFontS_name_label(fsw));
3141 }
3142 
3143 /*	Function Name: Toggle75DPI
3144  *	Description: Activated when the 75DPI button is toggled.
3145  *                 w - the toggle button widget selected.
3146  *                 fsw_ptr - pointer to the font selector widget.
3147  *                 data - the toggle button data.
3148  *	Returns: none
3149  */
3150 
3151 static void
Toggle75DPI(Widget w,XtPointer fsw_ptr,XtPointer data)3152 Toggle75DPI(Widget w, XtPointer fsw_ptr, XtPointer data)
3153 {
3154     XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
3155     FontData * cf = XmFontS_font_info(fsw)->current_font;
3156     XmToggleButtonCallbackStruct *info;
3157     char buf[BUFSIZ];
3158 
3159     info = (XmToggleButtonCallbackStruct *) data;
3160 
3161     UnsetSiblings(w);
3162 
3163     if (!info->set)
3164 	return;			/* Do nothing on an unset. */
3165 
3166     SetFlag(&(XmFontS_user_state(fsw)), DPI_75, True);
3167     SetFlag(&(XmFontS_user_state(fsw)), DPI_100, False);
3168     cf->resolution_x = cf->resolution_y = 75;
3169 
3170     UpdateFamilies(fsw);
3171     UpdateSizes(fsw);
3172     DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
3173 }
3174 
3175 /*	Function Name: Toggle100DPI
3176  *	Description: Activated when the 100DPI button is toggled.
3177  *                 w - the toggle button widget selected.
3178  *                 fsw_ptr - pointer to the font selector widget.
3179  *                 data - the toggle button data.
3180  *	Returns: none
3181  */
3182 
3183 static void
Toggle100DPI(Widget w,XtPointer fsw_ptr,XtPointer data)3184 Toggle100DPI(Widget w, XtPointer fsw_ptr, XtPointer data)
3185 {
3186     XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
3187     FontData * cf = XmFontS_font_info(fsw)->current_font;
3188     XmToggleButtonCallbackStruct *info;
3189     char buf[BUFSIZ];
3190 
3191     info = (XmToggleButtonCallbackStruct *) data;
3192 
3193     UnsetSiblings(w);
3194 
3195     if (!info->set)
3196 	return;			/* Do nothing on an unset. */
3197 
3198     SetFlag(&(XmFontS_user_state(fsw)), DPI_75, False);
3199     SetFlag(&(XmFontS_user_state(fsw)), DPI_100, True);
3200 
3201     cf->resolution_x = cf->resolution_y = 100;
3202 
3203     UpdateFamilies(fsw);
3204     UpdateSizes(fsw);
3205     DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
3206 }
3207 
3208 /*	Function Name: ToggleBothDPI
3209  *	Description: Activated when the Both DPI button is toggled.
3210  *                 w - the toggle button widget selected.
3211  *                 fsw_ptr - pointer to the font selector widget.
3212  *                 data - the toggle button data.
3213  *	Returns: none
3214  */
3215 
3216 static void
ToggleBothDPI(Widget w,XtPointer fsw_ptr,XtPointer data)3217 ToggleBothDPI(Widget w, XtPointer fsw_ptr, XtPointer data)
3218 {
3219     XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
3220     FontData * cf = XmFontS_font_info(fsw)->current_font;
3221     XmToggleButtonCallbackStruct *info;
3222     char buf[BUFSIZ];
3223 
3224     info = (XmToggleButtonCallbackStruct *) data;
3225 
3226     UnsetSiblings(w);
3227 
3228     if (!info->set)
3229 	return;			/* Do nothing on an unset. */
3230 
3231     SetFlag(&(XmFontS_user_state(fsw)), DPI_75 | DPI_100, True);
3232     cf->resolution_x = cf->resolution_y = 0; /* 0 means any */
3233 
3234     UpdateFamilies(fsw);
3235     UpdateSizes(fsw);
3236     DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
3237 }
3238 
3239 /*	Function Name: ToggleProportional
3240  *	Description: Activated when the Proportional button is toggled.
3241  *                 w - the toggle button widget selected.
3242  *                 fsw_ptr - pointer to the font selector widget.
3243  *                 data - the toggle button data.
3244  *	Returns: none
3245  */
3246 
3247 static void
ToggleProportional(Widget w,XtPointer fsw_ptr,XtPointer data)3248 ToggleProportional(Widget w, XtPointer fsw_ptr, XtPointer data)
3249 {
3250     XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
3251     FontData * cf = XmFontS_font_info(fsw)->current_font;
3252     XmToggleButtonCallbackStruct *info;
3253     char buf[BUFSIZ];
3254 
3255     info = (XmToggleButtonCallbackStruct *) data;
3256 
3257     UnsetSiblings(w);
3258 
3259     if (!info->set)
3260 	return;			/* Do nothing on an unset. */
3261 
3262     SetFlag(&(XmFontS_user_state(fsw)), USER_PROPORTIONAL, True);
3263     SetFlag(&(XmFontS_user_state(fsw)), USER_FIXED, False);
3264 
3265     UpdateFixedProportional(fsw);
3266 
3267     UpdateFamilies(fsw);
3268     UpdateSizes(fsw);
3269     DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
3270 }
3271 
3272 /*	Function Name: ToggleFixed
3273  *	Description: Activated when the Fixed button is toggled.
3274  *                 w - the toggle button widget selected.
3275  *                 fsw_ptr - pointer to the font selector widget.
3276  *                 data - the toggle button data.
3277  *	Returns: none
3278  */
3279 
3280 static void
ToggleFixed(Widget w,XtPointer fsw_ptr,XtPointer data)3281 ToggleFixed(Widget w, XtPointer fsw_ptr, XtPointer data)
3282 {
3283     XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
3284     FontData * cf = XmFontS_font_info(fsw)->current_font;
3285     XmToggleButtonCallbackStruct *info;
3286     char buf[BUFSIZ];
3287 
3288     info = (XmToggleButtonCallbackStruct *) data;
3289 
3290     UnsetSiblings(w);
3291 
3292     if (!info->set)
3293 	return;			/* Do nothing on an unset. */
3294 
3295     SetFlag(&(XmFontS_user_state(fsw)), USER_FIXED, True);
3296     SetFlag(&(XmFontS_user_state(fsw)), USER_PROPORTIONAL, False);
3297 
3298     UpdateFixedProportional(fsw);
3299     UpdateFamilies(fsw);
3300     UpdateSizes(fsw);
3301     DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
3302 }
3303 
3304 /*	Function Name: ToggleBothSpacing
3305  *	Description: Activated when the Both (any) Spacing button is toggled.
3306  *                 w - the toggle button widget selected.
3307  *                 fsw_ptr - pointer to the font selector widget.
3308  *                 data - the toggle button data.
3309  *	Returns: none
3310  */
3311 
3312 static void
ToggleBothSpacing(Widget w,XtPointer fsw_ptr,XtPointer data)3313 ToggleBothSpacing(Widget w, XtPointer fsw_ptr, XtPointer data)
3314 {
3315     XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
3316     FontData * cf = XmFontS_font_info(fsw)->current_font;
3317     XmToggleButtonCallbackStruct *info;
3318     char buf[BUFSIZ];
3319 
3320     info = (XmToggleButtonCallbackStruct *) data;
3321 
3322     UnsetSiblings(w);
3323 
3324     if (!info->set)
3325 	return;			/* Do nothing on an unset. */
3326 
3327     SetFlag(&(XmFontS_user_state(fsw)), USER_FIXED | USER_PROPORTIONAL, True);
3328 
3329     UpdateFixedProportional(fsw);
3330     UpdateFamilies(fsw);
3331     UpdateSizes(fsw);
3332     DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
3333 }
3334 
3335 /*	Function Name: XlfdMode
3336  *	Description: Called when the Xlfd Toggle is selected.
3337  *                 w - the toggle button widget selected.
3338  *                 fsw_ptr - pointer to the font selector widget.
3339  *                 data - the toggle button data.
3340  *	Returns: none
3341  */
3342 
3343 static void
XlfdMode(Widget w,XtPointer fsw_ptr,XtPointer data)3344 XlfdMode(Widget w, XtPointer fsw_ptr, XtPointer data)
3345 {
3346     XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
3347     XmToggleButtonCallbackStruct *info;
3348 
3349     info = (XmToggleButtonCallbackStruct *) data;
3350 
3351     UnsetSiblings(w);
3352 
3353     if (!info->set)
3354 	return;			/* Do nothing on an unset. */
3355 
3356     ChangeMode(fsw, True, True);	/* Set to Xlfd Mode. */
3357 }
3358 
3359 /*	Function Name: OtherMode
3360  *	Description: Called when the Other Toggle is selected.
3361  *                 w - the toggle button widget selected.
3362  *                 fsw_ptr - pointer to the font selector widget.
3363  *                 data - the toggle button data.
3364  *	Returns: none
3365  */
3366 
3367 static void
OtherMode(Widget w,XtPointer fsw_ptr,XtPointer data)3368 OtherMode(Widget w, XtPointer fsw_ptr, XtPointer data)
3369 {
3370     XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
3371     XmToggleButtonCallbackStruct *info;
3372 
3373     info = (XmToggleButtonCallbackStruct *) data;
3374 
3375     UnsetSiblings(w);
3376 
3377     if (!info->set)
3378 	return;			/* Do nothing on an unset. */
3379 
3380     ChangeMode(fsw, False, True);	/* Set to other Mode */
3381 }
3382 
3383 /*	Function Name: RemoveUserError
3384  *	Description: Removes a user error from the text widget.
3385  *                 w - the text widget.
3386  *                 fsw_ptr - pointer to the font selector widget.
3387  *                 data - *** UNUSED ***.
3388  *	Returns: none
3389  */
3390 
3391 /* ARGSUSED */
3392 static void
RemoveUserError(Widget w,XtPointer fsw_ptr,XtPointer data)3393 RemoveUserError(Widget w, XtPointer fsw_ptr, XtPointer data)
3394 {
3395     XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
3396 
3397     if (XmFontS_current_text(fsw) == NULL)
3398 	return;
3399 
3400     DisplayUserError(fsw, NULL);
3401 }
3402 
3403 /************************************************************
3404  *
3405  * Semi-public routines.
3406  *
3407  ************************************************************/
3408 
3409 /*      Function Name: Class Initlialize
3410  *      Description:   Initializes class-specific data (offsets)
3411  *      Arguments:     none
3412  *      Returns:       nothing
3413  */
3414 static void
ClassInitialize()3415 ClassInitialize()
3416 {
3417   /* do nothing */
3418 }
3419 
3420 
3421 /*
3422  * ClassPartInitialize sets up the fast subclassing for the widget.
3423  */
3424 static void
3425 #ifdef _NO_PROTO
ClassPartInitialize(w_class)3426 ClassPartInitialize(w_class)
3427         WidgetClass w_class ;
3428 #else
3429 ClassPartInitialize(WidgetClass w_class)
3430 #endif /* _NO_PROTO */
3431 {
3432     _XmFastSubclassInit (w_class, XmFONTSELECTOR_BIT);
3433 }
3434 
3435 
3436 /*	Function Name: Initialize
3437  *	Description:   Called to initialize information specific
3438  *                     to this widget.
3439  *	Arguments:     req - what was originally requested.
3440  *                     set - what will be created (our superclassed have
3441  *                           already mucked with this)
3442  *                     args, num_args - The arguments passed to
3443  *                                      the creation call.
3444  *	Returns:       none.
3445  */
3446 
3447 /* ARGSUSED */
3448 static void
Initialize(Widget request,Widget set,ArgList args,Cardinal * num_args)3449 Initialize(Widget request, Widget set, ArgList args, Cardinal * num_args)
3450 {
3451     XmFontSelectorWidget fsw = (XmFontSelectorWidget)set;
3452     ArgList f_args;
3453     Cardinal f_num_args;
3454 
3455     XmFontS_user_state(fsw) = 0;	/* Initialize user state to 0. */
3456     XmFontS_xlfd_mode(fsw) = True;	/* We start in Xlfd Mode. */
3457     XmFontS_font_info(fsw) = LoadFontInfo(fsw);
3458     XmFontS_current_text(fsw) = NULL;
3459     XmFontS_old_fontdata(fsw) = NULL;
3460     XmFontS_old_fontlist(fsw) = NULL;
3461     XmFontS_encoding_menu_shell(fsw) = NULL;
3462 
3463     XmFontS_xlfd_only(fsw) = XmFontS_xlfd_sensitive(fsw) = NULL;
3464     XmFontS_num_xlfd_only(fsw) = XmFontS_alloc_xlfd_only(fsw) = 0;
3465     XmFontS_num_xlfd_sensitive(fsw) = XmFontS_alloc_xlfd_sensitive(fsw) = 0;
3466 
3467     XmFontS_get_font(fsw) = (String) XtMalloc(sizeof(char) * GET_FONT_SIZE);
3468 
3469     /* duplicate strings so that user can query them later */
3470     ANY_STRING(fsw)		= XmStringCopy(ANY_STRING(fsw));
3471     BOLD_STRING(fsw)		= XmStringCopy(BOLD_STRING(fsw));
3472     BOTH_STRING(fsw)		= XmStringCopy(BOTH_STRING(fsw));
3473     DPI100_STRING(fsw)		= XmStringCopy(DPI100_STRING(fsw));
3474     DPI75_STRING(fsw)		= XmStringCopy(DPI75_STRING(fsw));
3475     ENCODING_ONLY_STRING(fsw)	= XmStringCopy(ENCODING_ONLY_STRING(fsw));
3476     FAMILY_STRING(fsw)		= XmStringCopy(FAMILY_STRING(fsw));
3477     ITALIC_STRING(fsw)		= XmStringCopy(ITALIC_STRING(fsw));
3478     LOWER_ANY_STRING(fsw)	= XmStringCopy(LOWER_ANY_STRING(fsw));
3479     MONO_SPACE_STRING(fsw)	= XmStringCopy(MONO_SPACE_STRING(fsw));
3480     OPTION_STRING(fsw)		= XmStringCopy(OPTION_STRING(fsw));
3481     OTHER_FONT_STRING(fsw)	= XmStringCopy(OTHER_FONT_STRING(fsw));
3482     PROPORTIONAL_STRING(fsw)	= XmStringCopy(PROPORTIONAL_STRING(fsw));
3483     SAMPLE_TEXT(fsw)		= XmStringCopy(SAMPLE_TEXT(fsw));
3484     SCALING_STRING(fsw)		= XmStringCopy(SCALING_STRING(fsw));
3485     SHOW_NAME_STRING(fsw)	= XmStringCopy(SHOW_NAME_STRING(fsw));
3486     SIZE_STRING(fsw)		= XmStringCopy(SIZE_STRING(fsw));
3487     XLFD_STRING(fsw)		= XmStringCopy(XLFD_STRING(fsw));
3488 
3489     ENCODING_STRING(fsw)	= XtNewString(ENCODING_STRING(fsw));
3490     /* XmFontS_current_font(fsw) handled internally */
3491 
3492     {
3493 	int i;
3494 	String *encodings = ENCODING_LIST(fsw);
3495 	String *newList;
3496 	for (i=0, encodings = ENCODING_LIST(fsw); *encodings != NULL; i++, encodings++)
3497 		i++;
3498 	i++;
3499 	newList = (String*)XtMalloc(sizeof(String) * i);
3500 	for (i=0, encodings = ENCODING_LIST(fsw); *encodings != NULL; i++, encodings++)
3501 		newList[i] = XtNewString(*encodings);
3502 	newList[i] = NULL;
3503 	ENCODING_LIST(fsw) = newList;
3504     }
3505 
3506     _XmFilterArgs(args, *num_args,
3507 		  xm_std_constraint_filter, &f_args, &f_num_args);
3508     CreateChildren(fsw, f_args, f_num_args);
3509     XtFree((XtPointer) f_args);
3510 
3511     SetFlag(&(XmFontS_user_state(fsw)), DPI_75,
3512 	    (XmFontS_font_info(fsw)->resolution == 75));
3513 
3514     SetFlag(&(XmFontS_user_state(fsw)), DPI_100,
3515 	    (XmFontS_font_info(fsw)->resolution == 100));
3516 
3517     /*
3518      * Load default information into the current font.
3519      */
3520 
3521     XmFontS_font_info(fsw)->current_font = (FontData *) XtMalloc(sizeof(FontData));
3522     SetDisplayedFont(fsw, XmFontS_current_font(fsw));
3523 
3524 }
3525 
3526 /*	Function Name: Destroy
3527  *	Description: Called when the widget is destroyed, cleans up.
3528  *	Arguments: w - the widget.
3529  *	Returns: none.
3530  */
3531 
3532 static void
Destroy(Widget w)3533 Destroy(Widget w)
3534 {
3535     register int i, num;
3536     register String *ptr;
3537     XmFontSelectorWidget fsw = (XmFontSelectorWidget)w;
3538 
3539     if (XmFontS_old_fontdata(fsw) != NULL) {
3540 	XFreeFont(XtDisplay(w), XmFontS_old_fontdata(fsw));
3541 	XmFontListFree(XmFontS_old_fontlist(fsw));
3542     }
3543 
3544     num = XmFontS_font_info(fsw)->num_others;
3545     ptr = XmFontS_font_info(fsw)->others;
3546     for (i = 0; i < num; i++, ptr++)
3547 	XtFree(*ptr);
3548 
3549     for (i = 0; i < XmFontS_font_info(fsw)->num_families; i++)
3550 	XtFree((char*)XmFontS_font_info(fsw)->family_info[i].encodings);
3551 
3552     XtFree((XtPointer) XmFontS_get_font(fsw));
3553     XtFree((XtPointer) XmFontS_xlfd_only(fsw));
3554     XtFree((XtPointer) XmFontS_xlfd_sensitive(fsw));
3555     XtFree((XtPointer) XmFontS_font_info(fsw)->others);
3556     XtFree((XtPointer) XmFontS_font_info(fsw)->family_info);
3557     XtFree((XtPointer) XmFontS_font_info(fsw)->current_font);
3558     XtFree((XtPointer) XmFontS_font_info(fsw));
3559 
3560 
3561     XmStringFree(ANY_STRING(fsw));
3562     XmStringFree(BOLD_STRING(fsw));
3563     XmStringFree(BOTH_STRING(fsw));
3564     XmStringFree(DPI100_STRING(fsw));
3565     XmStringFree(DPI75_STRING(fsw));
3566     XmStringFree(ENCODING_ONLY_STRING(fsw));
3567     XmStringFree(FAMILY_STRING(fsw));
3568     XmStringFree(ITALIC_STRING(fsw));
3569     XmStringFree(LOWER_ANY_STRING(fsw));
3570     XmStringFree(MONO_SPACE_STRING(fsw));
3571     XmStringFree(OPTION_STRING(fsw));
3572     XmStringFree(OTHER_FONT_STRING(fsw));
3573     XmStringFree(PROPORTIONAL_STRING(fsw));
3574     XmStringFree(SAMPLE_TEXT(fsw));
3575     XmStringFree(SCALING_STRING(fsw));
3576     XmStringFree(SHOW_NAME_STRING(fsw));
3577     XmStringFree(SIZE_STRING(fsw));
3578     XmStringFree(XLFD_STRING(fsw));
3579 
3580     XtFree(ENCODING_STRING(fsw));
3581     /* current font handled internally */
3582 
3583     {
3584 	String *encodings;
3585 	for (encodings = ENCODING_LIST(fsw); *encodings != NULL; i++, encodings++)
3586 		XtFree(*encodings);
3587 	XtFree((char*)ENCODING_LIST(fsw));
3588     }
3589 }
3590 
3591 /*	Function Name: SetValues
3592  *	Description:   Called when some widget data needs to be modified on-
3593  *                     the-fly.
3594  *	Arguments:     old - the current (old) widget values.
3595  *                     request - before superclassed have changed things.
3596  *                     set - what will acutally be the new values.
3597  *                     args, num_args - The arguments passed to the set
3598  *                                      values call.
3599  *	Returns:       none
3600  */
3601 
3602 /* ARGSUSED */
3603 static Boolean
SetValues(Widget old,Widget request,Widget set,ArgList args,Cardinal * num_args)3604 SetValues(Widget old, Widget request, Widget set,
3605 	  ArgList args, Cardinal * num_args)
3606 {
3607     Arg largs[10];
3608     Cardinal num_largs, i;
3609     XmFontSelectorWidget old_fsw = (XmFontSelectorWidget) old;
3610     XmFontSelectorWidget set_fsw = (XmFontSelectorWidget) set;
3611     Boolean new_encoding_list = False;
3612 
3613     /*
3614      * Pass argument list through to all children.
3615      */
3616 
3617     {
3618 	ArgList f_args;
3619 	Cardinal f_num_args;
3620 
3621 	_XmFilterArgs(args, *num_args,
3622 		      xm_std_constraint_filter, &f_args, &f_num_args);
3623 	_XmSetValuesOnChildren(set, f_args, f_num_args);
3624 	XtFree((XtPointer) f_args);
3625     }
3626 
3627     for (i = 0; i < *num_args; i++)
3628     {
3629 	if (streq(args[i].name, XmNencodingList))
3630 	    new_encoding_list = True;
3631     }
3632 
3633     /*
3634      * ||| Protect against any of the strings being changed.
3635      */
3636 
3637     if (XmFontS_current_font(old_fsw) != XmFontS_current_font(set_fsw)) {
3638 	SetDisplayedFont(set_fsw, XmFontS_current_font(set_fsw));
3639     }
3640 
3641     if (XmFontS_show_font_name(old_fsw) != XmFontS_show_font_name(set_fsw)) {
3642 	XmToggleButtonSetState(XmFontS_show_font_toggle(set_fsw),
3643 			       XmFontS_show_font_name(set_fsw), True);
3644     }
3645 
3646     if (XmFontS_use_scaling(old_fsw) != XmFontS_use_scaling(set_fsw)) {
3647 	XmToggleButtonSetState(XmFontS_use_scaling_toggle(set_fsw),
3648 			       XmFontS_use_scaling(set_fsw), True);
3649     }
3650 
3651     if (new_encoding_list)
3652     {
3653 	Widget parent = XtParent(XmFontS_option_menu(set_fsw));
3654 	XmFontS_option_menu(set_fsw) = CreateEncodingMenu(set_fsw,
3655 						     parent, NULL, 0);
3656     }
3657 
3658     /* if new_encoding_list is true, then CreateEncodingMenu has already
3659     ** freed and recreated the ENCODING_STRING, so avoid redoing it
3660     */
3661     if (new_encoding_list ||
3662 	(((ENCODING_STRING(old_fsw) != NULL) && (ENCODING_STRING(set_fsw) != NULL))
3663 	&& !streq(ENCODING_STRING(old_fsw), ENCODING_STRING(set_fsw)))
3664 	)
3665     {
3666 	char buf[BUFSIZ];
3667 	int current, i;
3668 	String *encodings = ENCODING_LIST(set_fsw);
3669 	Widget button;
3670 
3671 	if (!new_encoding_list)
3672 	{
3673 		XtFree(ENCODING_STRING(old_fsw));
3674 		ENCODING_STRING(set_fsw) = XtNewString(ENCODING_STRING(set_fsw));
3675 	}
3676 
3677 	/* some of this code is probably a duplicate of CreateEncodingMenu */
3678 	for (current = 0, i = 1 ; *encodings != NULL; i++, encodings++)
3679 	{
3680 	    /*
3681 	     * If the default encoding matches this one then make this
3682 	     * the current item in the option menu.
3683 	     */
3684 	    if (strcmp(*encodings, ENCODING_STRING(set_fsw)) == 0)
3685 		current = i;
3686 	}
3687 
3688 	sprintf(buf, "*button_%d", current);
3689 	if ((button =
3690 	     XtNameToWidget(XtParent(XmFontS_option_menu(set_fsw)), buf)) != NULL)
3691 	{
3692 	    num_largs = 0;
3693 	    XtSetArg(largs[num_largs], XmNmenuHistory, button); num_largs++;
3694 	    XtSetValues(XmFontS_option_menu(set_fsw), largs, num_largs);
3695 	    ChangeEncoding((Widget) set_fsw, (XtPointer) current, NULL);
3696 	}
3697 	else
3698 	{
3699 	    /* ||| ERROR. */
3700 	}
3701     }
3702 
3703     if (XmFontS_text_rows(old_fsw) != XmFontS_text_rows(set_fsw)) {
3704 	num_largs = 0;
3705 	XtSetArg(largs[num_largs], XmNrows, XmFontS_text_rows(set_fsw));num_largs++;
3706 	XtSetValues(XmFontS_text(set_fsw), largs, num_largs);
3707     }
3708 
3709 	{
3710 	Boolean reset = False;
3711 #define DoCheck(old_one,new_one)	{ reset = False; if (old_one != new_one) { XmStringFree(old_one); new_one = XmStringCopy(new_one); reset = True; } }
3712 
3713 	DoCheck( ANY_STRING(old_fsw), ANY_STRING(set_fsw)); /* PUNT! or else we need to check if on-screen right now */
3714 	DoCheck( BOLD_STRING(old_fsw), BOLD_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_bold_toggle(set_fsw), XmNlabelString, BOLD_STRING(set_fsw), NULL);
3715 	DoCheck( BOTH_STRING(old_fsw), BOTH_STRING(set_fsw)); if (reset) { XtVaSetValues( XmFontS_dpiAny(set_fsw), XmNlabelString, BOTH_STRING(set_fsw), NULL); XtVaSetValues( XmFontS_any_spacing(set_fsw), XmNlabelString, BOTH_STRING(set_fsw), NULL); }
3716 	DoCheck( DPI100_STRING(old_fsw), DPI100_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_dpi100(set_fsw), XmNlabelString, DPI100_STRING(set_fsw), NULL);
3717 	DoCheck( DPI75_STRING(old_fsw), DPI75_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_dpi75(set_fsw), XmNlabelString, DPI75_STRING(set_fsw), NULL);
3718 	DoCheck( ENCODING_ONLY_STRING(old_fsw), ENCODING_ONLY_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_option_menu(set_fsw), XmNlabelString, ENCODING_ONLY_STRING(set_fsw), NULL);
3719 	DoCheck( FAMILY_STRING(old_fsw), FAMILY_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_family_box(set_fsw), XmNlabelString, FAMILY_STRING(set_fsw), NULL);
3720 	DoCheck( ITALIC_STRING(old_fsw), ITALIC_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_italic_toggle(set_fsw), XmNlabelString, ITALIC_STRING(set_fsw), NULL);
3721 	DoCheck( LOWER_ANY_STRING(old_fsw), LOWER_ANY_STRING(set_fsw));		/* PUNT! or else we need to check if on-screen right now */
3722 	DoCheck( MONO_SPACE_STRING(old_fsw), MONO_SPACE_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_monospace(set_fsw), XmNlabelString, MONO_SPACE_STRING(set_fsw), NULL);
3723 	DoCheck( OPTION_STRING(old_fsw), OPTION_STRING(set_fsw)); if (reset) XtVaSetValues( XtNameToWidget((Widget)set_fsw, "*optionButton"), XmNlabelString, OPTION_STRING(set_fsw), NULL);
3724 	DoCheck( OTHER_FONT_STRING(old_fsw), OTHER_FONT_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_other_toggle(set_fsw), XmNlabelString, OTHER_FONT_STRING(set_fsw), NULL);
3725 	DoCheck( PROPORTIONAL_STRING(old_fsw), PROPORTIONAL_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_proportional(set_fsw), XmNlabelString, PROPORTIONAL_STRING(set_fsw), NULL);
3726 	DoCheck( SAMPLE_TEXT(old_fsw), SAMPLE_TEXT(set_fsw));
3727 		if (reset)
3728 		{
3729 		char * temp_txt = _XmGetMBStringFromXmString(SAMPLE_TEXT(set_fsw));
3730 		XtVaSetValues( XmFontS_text(set_fsw), XmNlabelString, temp_txt, NULL);
3731 		XtFree(temp_txt);
3732 		}
3733 	DoCheck( SCALING_STRING(old_fsw), SCALING_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_use_scaling_toggle(set_fsw), XmNlabelString, SCALING_STRING(set_fsw), NULL);
3734 	DoCheck( SHOW_NAME_STRING(old_fsw), SHOW_NAME_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_show_font_toggle(set_fsw), XmNlabelString, SHOW_NAME_STRING(set_fsw), NULL);
3735 	DoCheck( SIZE_STRING(old_fsw), SIZE_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_size_box(set_fsw), XmNlabelString, SIZE_STRING(set_fsw), NULL);
3736 	DoCheck( XLFD_STRING(old_fsw), XLFD_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_xlfd_toggle(set_fsw), XmNlabelString, XLFD_STRING(set_fsw), NULL);
3737 
3738 #undef DoCheck
3739 	}
3740 
3741     return (False);
3742 } /* SetValues */
3743 
3744 /*	Function Name: GetValuesHook
3745  *	Description:   Packages up the value of the current font.
3746  *	Arguments:     w - The widget.
3747  *                     args, num_args - The arguments passed to the get
3748  *                                      values call.
3749  *	Returns:       none
3750  */
3751 
3752 /* ARGSUSED */
3753 static void
GetValuesHook(Widget w,ArgList args,Cardinal * num_args)3754 GetValuesHook(Widget w, ArgList args, Cardinal * num_args)
3755 {
3756     XmFontSelectorWidget fsw = (XmFontSelectorWidget) w;
3757     FontData * cf;
3758     String *str_ptr;
3759     register int i;
3760 
3761     for (i = 0; i < *num_args; i++) {
3762 	if (streq(args[i].name, XmNcurrentFont))
3763 	{
3764 		cf = XmFontS_font_info(fsw)->current_font;
3765 
3766 		str_ptr = (String *) args[i].value;
3767 		if (XmFontS_xlfd_mode(fsw)) {
3768 		    BuildFontString(fsw, cf, XmFontS_get_font(fsw), GET_FONT_SIZE);
3769 		    *str_ptr = XmFontS_get_font(fsw);
3770 		}
3771 		else {
3772 		    *str_ptr = XrmQuarkToString(cf->familyq);
3773 		}
3774 	}
3775 	else if (streq(args[i].name, XmNanyString))		*(XmString*)args[i].value = XmStringCopy(ANY_STRING(fsw));
3776 	else if (streq(args[i].name, XmNbothString))		*(XmString*)args[i].value = XmStringCopy(BOLD_STRING(fsw));
3777 	else if (streq(args[i].name, XmNboldString))		*(XmString*)args[i].value = XmStringCopy(BOTH_STRING(fsw));
3778 	else if (streq(args[i].name, XmN100DPIstring))		*(XmString*)args[i].value = XmStringCopy(DPI100_STRING(fsw));
3779 	else if (streq(args[i].name, XmN75DPIstring))		*(XmString*)args[i].value = XmStringCopy(DPI75_STRING(fsw));
3780 	else if (streq(args[i].name, XmNencodingString))	*(XmString*)args[i].value = XmStringCopy(ENCODING_ONLY_STRING(fsw));
3781 	else if (streq(args[i].name, XmNfamilyString))		*(XmString*)args[i].value = XmStringCopy(FAMILY_STRING(fsw));
3782 	else if (streq(args[i].name, XmNitalicString))		*(XmString*)args[i].value = XmStringCopy(ITALIC_STRING(fsw));
3783 	else if (streq(args[i].name, XmNanyLowerString))	*(XmString*)args[i].value = XmStringCopy(LOWER_ANY_STRING(fsw));
3784 	else if (streq(args[i].name, XmNmonoSpaceString))	*(XmString*)args[i].value = XmStringCopy(MONO_SPACE_STRING(fsw));
3785 	else if (streq(args[i].name, XmNoptionString))		*(XmString*)args[i].value = XmStringCopy(OPTION_STRING(fsw));
3786 	else if (streq(args[i].name, XmNotherString))		*(XmString*)args[i].value = XmStringCopy(OTHER_FONT_STRING(fsw));
3787 	else if (streq(args[i].name, XmNpropSpaceString))	*(XmString*)args[i].value = XmStringCopy(PROPORTIONAL_STRING(fsw));
3788 	else if (streq(args[i].name, XmNsampleText))		*(XmString*)args[i].value = XmStringCopy(SAMPLE_TEXT(fsw));
3789 	else if (streq(args[i].name, XmNscalingString))		*(XmString*)args[i].value = XmStringCopy(SCALING_STRING(fsw));
3790 	else if (streq(args[i].name, XmNshowNameString))	*(XmString*)args[i].value = XmStringCopy(SHOW_NAME_STRING(fsw));
3791 	else if (streq(args[i].name, XmNsizeString))		*(XmString*)args[i].value = XmStringCopy(SIZE_STRING(fsw));
3792 	else if (streq(args[i].name, XmNxlfdString))		*(XmString*)args[i].value = XmStringCopy(XLFD_STRING(fsw));
3793     }
3794 }
3795 
3796 /************************************************************
3797  *
3798  * Public routines.
3799  *
3800  ************************************************************/
3801 
3802 /*	Function Name: XmCreateFontSelector
3803  *	Description: Creation Routine for UIL and ADA.
3804  *	Arguments: parent - the parent widget.
3805  *                 name - the name of the widget.
3806  *                 args, num_args - the number and list of args.
3807  *	Returns: The created widget.
3808  */
3809 
3810 Widget
XmCreateFontSelector(Widget parent,String name,ArgList args,Cardinal num_args)3811 XmCreateFontSelector(Widget parent, String name,
3812 		     ArgList args, Cardinal num_args)
3813 {
3814     return(XtCreateWidget(name, xmFontSelectorWidgetClass,
3815 			  parent, args, num_args));
3816 }
3817