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