1 /*******************************************************************************
2 *                                                                              *
3 * fontsel.c -- Nirvana Font Selector                                           *
4 *                                                                              *
5 * Copyright (C) 1999 Mark Edel                                                 *
6 *                                                                              *
7 * This is free software; you can redistribute it and/or modify it under the    *
8 * terms of the GNU General Public License as published by the Free Software    *
9 * Foundation; either version 2 of the License, or (at your option) any later   *
10 * version. In addition, you may distribute version of this program linked to   *
11 * Motif or Open Motif. See README for details.                                 *
12 *                                                                              *
13 * This software is distributed in the hope that it will be useful, but WITHOUT *
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or        *
15 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License        *
16 * for more details.                                                            *
17 *                                                                              *
18 * You should have received a copy of the GNU General Public License along with *
19 * software; if not, write to the Free Software Foundation, Inc., 59 Temple     *
20 * Place, Suite 330, Boston, MA  02111-1307 USA                                 *
21 *                                                                              *
22 * Nirvana Text Editor                                                          *
23 * June 2, 1993                                                                 *
24 *                                                                              *
25 * Written by Suresh Ravoor (assisted by Mark Edel)                             *
26 *                                                                              *
27 *******************************************************************************/
28 
29 #ifdef HAVE_CONFIG_H
30 #include "../config.h"
31 #endif
32 
33 #include "fontsel.h"
34 #include "misc.h"
35 #include "nedit_malloc.h"
36 #include "DialogF.h"
37 
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <math.h>
42 
43 #include <X11/Intrinsic.h>
44 #include <Xm/Xm.h>
45 #include <Xm/Form.h>
46 #include <Xm/PushB.h>
47 #include <Xm/List.h>
48 #include <Xm/Label.h>
49 #include <Xm/Text.h>
50 #include <Xm/TextF.h>
51 #include <Xm/ToggleB.h>
52 #include <Xm/MessageB.h>
53 #include <Xm/DialogS.h>
54 
55 #ifdef HAVE_DEBUG_H
56 #include "../debug.h"
57 #endif
58 
59 #define MAX_ARGS                        20
60 #define MAX_NUM_FONTS                   32767
61 #define MAX_FONT_NAME_LEN               256
62 #define MAX_ENTRIES_IN_LIST             5000
63 #define MAX_DISPLAY_SIZE                150
64 #define DELIM                           '-'
65 #define NUM_COMPONENTS_FONT_NAME        14
66 #define TEMP_BUF_SIZE                   256
67 #define DISPLAY_HEIGHT                  90
68 
69 enum listSpecifier { NONE, FONT, STYLE, SIZE };
70 
71 
72 /* local data structures and types */
73 
74 typedef struct
75 {
76         Widget          form;           /* widget id */
77         Widget          okButton;       /* widget id */
78         Widget          cancelButton;   /* widget id */
79         Widget          fontList;       /* widget id */
80         Widget          styleList;      /* widget id */
81         Widget          sizeList;       /* widget id */
82         Widget          fontNameField;  /* widget id */
83         Widget          sizeToggle;     /* widget id */
84         Widget          propFontToggle; /* widget id */
85         Widget          dispField;      /* widget id */
86         char            **fontData;     /* font name info  */
87         int             numFonts;       /* number of fonts */
88         char            *sel1;          /* selection from list 1 */
89         char            *sel2;          /* selection from list 2 */
90         char            *sel3;          /* selection from list 3 */
91         int             showPropFonts;  /* toggle state - show prop fonts */
92         int             showSizeInPixels;/* toggle state - size in pixels  */
93         char            *fontName;      /* current font name */
94         XFontStruct     *oldFont;       /* font data structure for dispSample */
95         XmFontList      oldFontList;    /* font data structure for dispSample */
96         int     exitFlag;               /* used for program exit control */
97         int     destroyedFlag;          /* used to prevent double destruction */
98         Pixel   sampleFG;               /* Colors for the sample field */
99         Pixel   sampleBG;
100 }       xfselControlBlkType;
101 
102 
103 /* local function prototypes */
104 
105 static void     getStringComponent(const char *inStr, int pos, char *outStr);
106 static void     setupScrollLists(int dontChange, xfselControlBlkType ctrlBlk);
107 static int      notPropFont(const char *font);
108 static int      styleMatch(xfselControlBlkType *ctrlBlk, const char *font);
109 static int      sizeMatch(xfselControlBlkType *ctrlBlk, const char *font);
110 static int      fontMatch(xfselControlBlkType *ctrlBlk, const char *font);
111 static void     addItemToList(char **buf, const char *item, int *count);
112 static void     getFontPart(const char *font, char *buff1);
113 static void     getStylePart(const char *font, char *buff1);
114 static void     getSizePart(const char *font, char *buff1, int inPixels);
115 static void     propFontToggleAction(Widget widget,
116                                      xfselControlBlkType *ctrlBlk,
117                                      XmToggleButtonCallbackStruct *call_data);
118 static void     sizeToggleAction(Widget widget,
119                                  xfselControlBlkType *ctrlBlk,
120                                  XmToggleButtonCallbackStruct *call_data);
121 static void     fontAction(Widget widget, xfselControlBlkType *ctrlBlk,
122                                  XmListCallbackStruct *call_data);
123 static void     styleAction(Widget widget, xfselControlBlkType *ctrlBlk,
124                                  XmListCallbackStruct *call_data);
125 static void     sizeAction(Widget widget, xfselControlBlkType *ctrlBlk,
126                                  XmListCallbackStruct *call_data);
127 static void     choiceMade(xfselControlBlkType *ctrlBlk);
128 static void     dispSample(xfselControlBlkType *ctrlBlk);
129 static void     destroyCB(Widget widget, xfselControlBlkType *ctrlBlk,
130                                  XmListCallbackStruct *call_data);
131 static void     cancelAction(Widget widget, xfselControlBlkType *ctrlBlk,
132                                  XmListCallbackStruct *call_data);
133 static void     okAction(Widget widget, xfselControlBlkType *ctrlBlk,
134                                  XmPushButtonCallbackStruct *call_data);
135 static void     startupFont(xfselControlBlkType *ctrlBlk, const char *font);
136 static void     setFocus(Widget w, xfselControlBlkType *ctrlBlk, XEvent *event,
137                                                 Boolean *continueToDispatch);
138 static void     FindBigFont(xfselControlBlkType *ctrlBlk, char *bigFont);
139 static void     enableSample(xfselControlBlkType *ctrlBlk, Bool turn_on,
140                              XmFontList *fontList);
141 
142 /*******************************************************************************
143 *                                                                              *
144 *     FontSel ()                                                               *
145 *                                                                              *
146 *                                                                              *
147 *            Function to put up a modal font selection dialog box. The purpose *
148 *            of this routine is to allow the user to interactively view sample *
149 *            fonts and to choose a font for current use.                       *
150 *                                                                              *
151 *     Arguments:                                                               *
152 *                                                                              *
153 *            Widget     parent          - parent widget ID                     *
154 *                                                                              *
155 *            int        showPropFont    - ONLY_FIXED : shows only fixed fonts  *
156 *                                                      doesn't show prop font  *
157 *                                                      toggle button also.     *
158 *                                         PREF_FIXED : can select either fixed *
159 *                                                      or proportional fonts;  *
160 *                                                      but starting option is  *
161 *                                                      Fixed fonts.            *
162 *                                         PREF_PROP  : can select either fixed *
163 *                                                      or proportional fonts;  *
164 *                                                      but starting option is  *
165 *                                                      proportional fonts.     *
166 *                                                                              *
167 *           char *      currFont        - ASCII string that contains the name  *
168 *                                         of the currently selected font.      *
169 *                                                                              *
170 *           Pixel   sampleFG, sampleBG      - Foreground/Background colors in  *
171 *                                               which to display the sample    *
172 *                                               text.                          *
173 *                                                                              *
174 *                                                                              *
175 *     Returns:                                                                 *
176 *                                                                              *
177 *           pointer to an ASCII character string that contains the name of     *
178 *           the selected font (in X format for naming fonts); it is the users  *
179 *           responsibility to free the space allocated to this string.         *
180 *                                                                              *
181 *     Comments:                                                                *
182 *                                                                              *
183 *           The calling function has to call the appropriate routines to set   *
184 *           the current font to the one represented by the returned string.    *
185 *                                                                              *
186 *******************************************************************************/
187 
FontSel(Widget parent,int showPropFonts,const char * currFont,Pixel sampleFG,Pixel sampleBG)188 char    *FontSel(Widget parent, int showPropFonts, const char *currFont,
189             Pixel sampleFG, Pixel sampleBG)
190 {
191     Widget          dialog, form, okButton, cancelButton;
192     Widget          styleList, sizeList, fontName, fontList;
193     Widget          sizeToggle, propFontToggle = NULL, dispField;
194     Widget          nameLabel, sampleLabel;
195     Arg             args[MAX_ARGS];
196     int             n;
197     XmString        tempStr;
198     char            bigFont[MAX_FONT_NAME_LEN];
199     xfselControlBlkType ctrlBlk;
200     Display         *theDisplay;
201 
202     ctrlBlk.fontData    = XListFonts(XtDisplay(parent),
203                                      "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
204                                      MAX_NUM_FONTS, &ctrlBlk.numFonts);
205     FindBigFont(&ctrlBlk, bigFont);
206     ctrlBlk.oldFont = XLoadQueryFont(XtDisplay(parent), bigFont);
207     ctrlBlk.oldFontList = XmFontListCreate(ctrlBlk.oldFont,
208                                             XmSTRING_DEFAULT_CHARSET);
209     ctrlBlk.sampleFG = sampleFG;
210     ctrlBlk.sampleBG = sampleBG;
211 
212     dialog  = CreateDialogShell(parent, "Font Selector", args, 0);
213 
214     /*  Set up window sizes for form widget */
215 
216     n = 0;
217     XtSetArg(args[n], XmNautoUnmanage, FALSE); n++;
218     XtSetArg(args[n], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); n++;
219 
220     /*  Create form popup dialog widget */
221 
222     form    = XtCreateWidget ("Font Selector", xmFormWidgetClass, dialog,
223                               args, n);
224 
225     /*  Create pushbutton widgets */
226 
227     n = 0;
228     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
229     XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
230     XtSetArg(args[n], XmNbottomOffset, 4); n++;
231     XtSetArg(args[n], XmNtopOffset, 1); n++;
232     XtSetArg(args[n], XmNrightPosition, 45); n++;
233     XtSetArg(args[n], XmNwidth, 110); n++;
234     XtSetArg(args[n], XmNheight, 28); n++;
235     XtSetArg(args[n], XmNshowAsDefault, TRUE); n++;
236     okButton = XtCreateManagedWidget("OK", xmPushButtonWidgetClass, form,
237                                       args, n);
238 
239     n = 0;
240     XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
241     XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
242     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
243     XtSetArg(args[n], XmNtopWidget, okButton); n++;
244     XtSetArg(args[n], XmNbottomWidget, okButton); n++;
245     XtSetArg(args[n], XmNleftPosition, 55); n++;
246     XtSetArg(args[n], XmNwidth, 110); n++;
247     XtSetArg(args[n], XmNheight, 28); n++;
248     cancelButton = XtCreateManagedWidget("Cancel", xmPushButtonWidgetClass,
249                                          form, args, n);
250 
251     /*  create font name text widget and the corresponding label */
252 
253     n = 0;
254     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
255     XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
256     XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
257     XtSetArg(args[n], XmNbottomWidget, okButton); n++;
258     XtSetArg(args[n], XmNleftPosition, 1); n++;
259     XtSetArg(args[n], XmNrightPosition, 99); n++;
260     XtSetArg(args[n], XmNeditable, True); n++;
261     XtSetArg(args[n], XmNeditMode, XmSINGLE_LINE_EDIT); n++;
262     XtSetArg(args[n], XmNmaxLength, MAX_FONT_NAME_LEN); n++;
263     fontName = XtCreateManagedWidget("fontname", xmTextWidgetClass, form,
264                                      args, n);
265     RemapDeleteKey(fontName);   /* kludge to handle delete and BS */
266 
267     n = 0;
268     tempStr = XmStringCreate("Font Name:", XmSTRING_DEFAULT_CHARSET);
269     XtSetArg(args[n], XmNlabelString, tempStr); n++;
270     XtSetArg(args[n], XmNmnemonic, 'N'); n++;
271     XtSetArg(args[n], XmNuserData, fontName); n++;
272     XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
273     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
274     XtSetArg(args[n], XmNleftWidget, fontName); n++;
275     XtSetArg(args[n], XmNbottomWidget, fontName); n++;
276     XtSetArg(args[n], XmNtopOffset, 1); n++;
277     nameLabel = XtCreateManagedWidget("Font Name:", xmLabelWidgetClass,
278                                       form, args, n);
279     XmStringFree(tempStr);
280 
281     /*  create sample display text field widget */
282 
283     n = 0;
284     XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
285     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
286     XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
287     XtSetArg(args[n], XmNrightPosition, 99); n++;
288     XtSetArg(args[n], XmNbottomWidget, nameLabel); n++;
289     XtSetArg(args[n], XmNleftPosition, 1); n++;
290     XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
291     XtSetArg(args[n], XmNvalue,
292             "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789");
293             n++;
294     XtSetArg(args[n], XmNforeground, sampleFG); n++;
295     XtSetArg(args[n], XmNbackground, sampleBG); n++;
296     dispField = XtCreateManagedWidget(" ", xmTextFieldWidgetClass, form,
297                                        args, n);
298 
299     n = 0;
300     tempStr = XmStringCreate("Sample:", XmSTRING_DEFAULT_CHARSET);
301     XtSetArg(args[n], XmNlabelString, tempStr); n++;
302     XtSetArg(args[n], XmNmnemonic, 'S'); n++;
303     XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
304     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
305     XtSetArg(args[n], XmNleftWidget, dispField); n++;
306     XtSetArg(args[n], XmNbottomWidget, dispField); n++;
307     XtSetArg(args[n], XmNtopOffset, 1); n++;
308     sampleLabel = XtCreateManagedWidget("Font Name:", xmLabelWidgetClass,
309             form, args, n);
310     XmStringFree(tempStr);
311 
312     /*  create toggle buttons */
313 
314     n = 0;
315     tempStr = XmStringCreate("Show Size in Points",
316                               XmSTRING_DEFAULT_CHARSET);
317     XtSetArg(args[n], XmNlabelString, tempStr); n++;
318     XtSetArg(args[n], XmNmnemonic, 'P'); n++;
319     XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
320     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
321     XtSetArg(args[n], XmNleftPosition, 2); n++;
322     XtSetArg(args[n], XmNtopOffset, 1); n++;
323     XtSetArg(args[n], XmNbottomWidget, sampleLabel); n++;
324     sizeToggle = XtCreateManagedWidget("sizetoggle",
325                       xmToggleButtonWidgetClass, form, args, n);
326     XmStringFree(tempStr);
327 
328     if (showPropFonts != ONLY_FIXED)
329     {
330         n = 0;
331         tempStr = XmStringCreate("Show Proportional Width Fonts",
332                                  XmSTRING_DEFAULT_CHARSET);
333         XtSetArg(args[n], XmNlabelString, tempStr); n++;
334         XtSetArg(args[n], XmNmnemonic, 'W'); n++;
335         XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
336         XtSetArg(args[n], XmNtopAttachment,
337                         XmATTACH_OPPOSITE_WIDGET); n++;
338         XtSetArg(args[n], XmNbottomAttachment,
339                         XmATTACH_OPPOSITE_WIDGET); n++;
340         XtSetArg(args[n], XmNrightPosition, 98); n++;
341         XtSetArg(args[n], XmNtopWidget, sizeToggle); n++;
342         XtSetArg(args[n], XmNbottomWidget, sizeToggle); n++;
343         XtSetArg(args[n], XmNtopOffset, 1); n++;
344         propFontToggle = XtCreateManagedWidget("propfonttoggle",
345                             xmToggleButtonWidgetClass, form, args, n);
346         XmStringFree(tempStr);
347     }
348 
349     /*  create scroll list widgets */
350     /*  "Font" list */
351 
352     n = 0;
353     tempStr = XmStringCreate("Font:", XmSTRING_DEFAULT_CHARSET);
354     XtSetArg(args[n], XmNlabelString, tempStr); n++;
355     XtSetArg(args[n], XmNmnemonic, 'F'); n++;
356     XtSetArg(args[n], XmNtopOffset, 2); n++;
357     XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
358     XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
359     XtSetArg(args[n], XmNleftPosition, 1); n++;
360     nameLabel = XtCreateManagedWidget("Font:", xmLabelWidgetClass, form,
361                                       args, n);
362     XmStringFree(tempStr);
363 
364     n = 0;
365     XtSetArg(args[n], XmNvisibleItemCount, 15); n++;
366     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
367     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
368     XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
369     XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
370     XtSetArg(args[n], XmNbottomWidget, sizeToggle); n++;
371     XtSetArg(args[n], XmNtopWidget, nameLabel); n++;
372     XtSetArg(args[n], XmNleftWidget, nameLabel); n++;
373     XtSetArg(args[n], XmNrightPosition, 52); n++;
374     fontList = XmCreateScrolledList(form, "fontlist", args, n);
375     AddMouseWheelSupport(fontList);
376     XtManageChild(fontList);
377     XtVaSetValues(nameLabel, XmNuserData, fontList, NULL);
378 
379     /* "Style" list */
380 
381     n = 0;
382     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
383     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
384     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
385     XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
386     XtSetArg(args[n], XmNtopWidget, nameLabel); n++;
387     XtSetArg(args[n], XmNleftOffset, 5); n++;
388     XtSetArg(args[n], XmNleftWidget, XtParent(fontList)); n++;
389     XtSetArg(args[n], XmNbottomWidget, XtParent(fontList)); n++;
390     XtSetArg(args[n], XmNrightPosition, 85); n++;
391     styleList = XmCreateScrolledList(form, "stylelist", args, n);
392     AddMouseWheelSupport(styleList);
393     XtManageChild(styleList);
394 
395     n = 0;
396     tempStr = XmStringCreate("Style:", XmSTRING_DEFAULT_CHARSET);
397     XtSetArg(args[n], XmNmnemonic, 'y'); n++;
398     XtSetArg(args[n], XmNuserData, styleList); n++;
399     XtSetArg(args[n], XmNlabelString, tempStr); n++;
400     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
401     XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
402     XtSetArg(args[n], XmNbottomWidget, XtParent(styleList)); n++;
403     XtSetArg(args[n], XmNleftWidget, XtParent(styleList)); n++;
404     XtCreateManagedWidget("Style:", xmLabelWidgetClass, form, args, n);
405     XmStringFree(tempStr);
406 
407     /*  "Size" list */
408 
409     n = 0;
410     XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
411     XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
412     XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
413     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
414     XtSetArg(args[n], XmNtopWidget, nameLabel); n++;
415     XtSetArg(args[n], XmNleftWidget, XtParent(styleList)); n++;
416     XtSetArg(args[n], XmNbottomWidget, XtParent(fontList)); n++;
417     XtSetArg(args[n], XmNleftOffset, 5); n++;
418     XtSetArg(args[n], XmNrightPosition, 99); n++;
419     sizeList = XmCreateScrolledList(form, "sizelist", args, n);
420     AddMouseWheelSupport(sizeList);
421     XtManageChild(sizeList);
422 
423     n = 0;
424     tempStr = XmStringCreate("Size:", XmSTRING_DEFAULT_CHARSET);
425     XtSetArg(args[n], XmNlabelString, tempStr); n++;
426     XtSetArg(args[n], XmNmnemonic, 'z'); n++;
427     XtSetArg(args[n], XmNuserData, sizeList); n++;
428     XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
429     XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
430     XtSetArg(args[n], XmNbottomWidget, XtParent(sizeList)); n++;
431     XtSetArg(args[n], XmNleftWidget, XtParent(sizeList)); n++;
432     XtCreateManagedWidget("Size:", xmLabelWidgetClass, form, args, n);
433     XmStringFree(tempStr);
434 
435     /*  update form widgets cancel button */
436 
437     n = 0;
438     XtSetArg(args[n], XmNcancelButton, cancelButton); n++;
439     XtSetValues(form, args, n);
440 
441 
442     /*  update application's control block structure */
443 
444     ctrlBlk.form            = form;
445     ctrlBlk.okButton        = okButton;
446     ctrlBlk.cancelButton    = cancelButton;
447     ctrlBlk.fontList        = fontList;
448     ctrlBlk.styleList       = styleList;
449     ctrlBlk.sizeList        = sizeList;
450     ctrlBlk.fontNameField   = fontName;
451     ctrlBlk.sizeToggle      = sizeToggle;
452     if (showPropFonts != ONLY_FIXED)
453         ctrlBlk.propFontToggle  = propFontToggle;
454     ctrlBlk.dispField       = dispField;
455     ctrlBlk.exitFlag        = FALSE;
456     ctrlBlk.destroyedFlag   = FALSE;
457     ctrlBlk.showPropFonts   = showPropFonts;
458     ctrlBlk.showSizeInPixels = TRUE;
459     ctrlBlk.sel1            = NULL;
460     ctrlBlk.sel2            = NULL;
461     ctrlBlk.sel3            = NULL;
462     ctrlBlk.fontName        = NULL;
463 
464     setupScrollLists(NONE, ctrlBlk);    /* update scroll lists */
465 
466     if (showPropFonts == PREF_PROP)
467         XmToggleButtonSetState(propFontToggle, TRUE, FALSE);
468 
469     /*  Register callback functions */
470 
471     if (showPropFonts != ONLY_FIXED)
472         XtAddCallback(propFontToggle, XmNvalueChangedCallback,
473                 (XtCallbackProc)propFontToggleAction, (char *)&ctrlBlk);
474     XtAddCallback(sizeToggle, XmNvalueChangedCallback,
475             (XtCallbackProc)sizeToggleAction, (char *)&ctrlBlk);
476     XtAddCallback(fontList, XmNbrowseSelectionCallback,
477             (XtCallbackProc)fontAction, (char *)&ctrlBlk);
478     XtAddCallback(styleList, XmNbrowseSelectionCallback,
479             (XtCallbackProc)styleAction, (char *)&ctrlBlk);
480     XtAddCallback(sizeList, XmNbrowseSelectionCallback,
481             (XtCallbackProc)sizeAction, (char *)&ctrlBlk);
482     XtAddCallback(okButton, XmNactivateCallback,
483             (XtCallbackProc)okAction, (char *)&ctrlBlk);
484     XtAddCallback(cancelButton, XmNactivateCallback,
485             (XtCallbackProc)cancelAction, (char *)&ctrlBlk);
486 
487     /* add event handler to setup input focus at start to scroll list */
488 
489     XtAddEventHandler(fontList, FocusChangeMask, FALSE,
490             (XtEventHandler)setFocus, (char *)&ctrlBlk);
491     XmProcessTraversal(fontList, XmTRAVERSE_CURRENT);
492 
493     /*  setup tabgroups */
494 
495     XmAddTabGroup(fontList);
496     XmAddTabGroup(styleList);
497     XmAddTabGroup(sizeList);
498     XmAddTabGroup(sizeToggle);
499     if (showPropFonts != ONLY_FIXED)
500         XmAddTabGroup(propFontToggle);
501     XmAddTabGroup(fontName);
502     XmAddTabGroup(okButton);
503     XmAddTabGroup(cancelButton);
504 
505     /* Make sure that we don't try to access the dialog if the user
506        destroyed it (possibly indirectly, by destroying the parent). */
507     XtAddCallback(dialog, XmNdestroyCallback,
508             (XtCallbackProc)destroyCB, (char *)&ctrlBlk);
509 
510     /*  Link Motif Close option to cancel action */
511 
512     AddMotifCloseCallback(dialog, (XtCallbackProc)cancelAction, &ctrlBlk);
513 
514     /*  Handle dialog mnemonics  */
515 
516     AddDialogMnemonicHandler(form, FALSE);
517 
518     /*  Realize Widgets  */
519 
520     ManageDialogCenteredOnPointer(form);
521 
522     /* set up current font parameters */
523 
524     if (currFont[0] != '\0')
525         startupFont(&ctrlBlk, currFont);
526 
527     /* Make sure that we can still access the display in case the form
528        gets destroyed */
529     theDisplay = XtDisplay(form);
530 
531     /*  enter event loop */
532 
533     while (! ctrlBlk.exitFlag && ! ctrlBlk.destroyedFlag)
534         XtAppProcessEvent(XtWidgetToApplicationContext(form), XtIMAll);
535 
536     if (! ctrlBlk.destroyedFlag) {
537         /* Don't let the callback destroy the font name */
538         XtRemoveCallback(dialog, XmNdestroyCallback,
539                 (XtCallbackProc)destroyCB, (char *)&ctrlBlk);
540         XtDestroyWidget(dialog);
541     }
542 
543     if (ctrlBlk.oldFont != NULL)
544     {
545         XFreeFont(theDisplay, ctrlBlk.oldFont);
546         XmFontListFree(ctrlBlk.oldFontList);
547     }
548 
549     return(ctrlBlk.fontName);
550 }
551 
552 
553 /*  gets a specific substring from a string */
554 
getStringComponent(const char * inStr,int pos,char * outStr)555 static void getStringComponent(const char *inStr, int pos, char *outStr)
556 {
557     int i, j;
558 
559     *outStr = '\0';
560 
561     if (pos > NUM_COMPONENTS_FONT_NAME)
562     {
563         fprintf(stderr, "Warning: getStringComponent being used for ");
564         fprintf(stderr, "pos > %d\nIf such ", NUM_COMPONENTS_FONT_NAME);
565         fprintf(stderr, "use is intended remove these warning lines\n");
566     }
567 
568     for (i = 0; (pos > 0) && (inStr[i] != '\0'); i++)
569         if (inStr[i] == DELIM)
570             pos--;
571 
572     if (inStr[i] == '\0')
573         return;
574 
575     for (j = 0; (inStr[i] != DELIM) && (inStr[i] != '\0'); i++, j++)
576         outStr[j] = inStr[i];
577     outStr[j] = '\0';
578 }
579 
580 
581 /* parse through the fontlist data and set up the three scroll lists */
582 
setupScrollLists(int dontChange,xfselControlBlkType ctrlBlk)583 static void setupScrollLists(int dontChange, xfselControlBlkType ctrlBlk)
584 {
585     char        *itemBuf1[MAX_ENTRIES_IN_LIST];
586     char        *itemBuf2[MAX_ENTRIES_IN_LIST];
587     char        *itemBuf3[MAX_ENTRIES_IN_LIST];
588     int         itemCount1, itemCount2, itemCount3;
589     char        buff1[TEMP_BUF_SIZE];
590     XmString    items[MAX_ENTRIES_IN_LIST];
591     int         i;
592 
593     itemCount1 = 0;
594     itemCount2 = 0;
595     itemCount3 = 0;
596 
597     for (i = 0; i < ctrlBlk.numFonts && i < MAX_ENTRIES_IN_LIST; i++)
598     {
599         if ((dontChange != FONT) &&
600             (styleMatch(&ctrlBlk, ctrlBlk.fontData[i])) &&
601             (sizeMatch (&ctrlBlk, ctrlBlk.fontData[i])) &&
602             ((ctrlBlk.showPropFonts == PREF_PROP) ||
603              (notPropFont(ctrlBlk.fontData[i]))))
604         {
605             getFontPart(ctrlBlk.fontData[i], buff1);
606             addItemToList(itemBuf1, buff1, &itemCount1);
607         }
608 
609         if ((dontChange != STYLE) &&
610             (fontMatch(&ctrlBlk, ctrlBlk.fontData[i])) &&
611             (sizeMatch (&ctrlBlk, ctrlBlk.fontData[i])) &&
612             ((ctrlBlk.showPropFonts == PREF_PROP) ||
613              (notPropFont(ctrlBlk.fontData[i]))))
614         {
615             getStylePart(ctrlBlk.fontData[i], buff1);
616             addItemToList(itemBuf2, buff1, &itemCount2);
617         }
618 
619         if ((dontChange != SIZE) &&
620             (fontMatch(&ctrlBlk, ctrlBlk.fontData[i])) &&
621             (styleMatch (&ctrlBlk, ctrlBlk.fontData[i])) &&
622             ((ctrlBlk.showPropFonts == PREF_PROP) ||
623              (notPropFont(ctrlBlk.fontData[i]))))
624         {
625             getSizePart(ctrlBlk.fontData[i], buff1, ctrlBlk.showSizeInPixels);
626             addItemToList(itemBuf3, buff1, &itemCount3);
627         }
628     }   /* end - for (i = 0; i < ctrlBlk.numFonts; i++) */
629 
630     /*  recreate all three scroll lists where necessary */
631     if (dontChange != FONT)
632     {
633         for (i = 0; i < itemCount1; i++)
634         {
635             items[i] = XmStringCreate(itemBuf1[i], XmSTRING_DEFAULT_CHARSET);
636             NEditFree(itemBuf1[i]);
637         }
638         XmListDeleteAllItems(ctrlBlk.fontList);
639         XmListAddItems(ctrlBlk.fontList, items, itemCount1, 1);
640         if (ctrlBlk.sel1 != NULL)
641         {
642             XmStringFree(items[0]);
643             items[0] = XmStringCreate(ctrlBlk.sel1, XmSTRING_DEFAULT_CHARSET);
644             XmListSelectItem(ctrlBlk.fontList, items[0], FALSE);
645             XmListSetBottomItem(ctrlBlk.fontList, items[0]);
646         }
647         for (i = 0; i < itemCount1; i++)
648             XmStringFree(items[i]);
649     }
650 
651     if (dontChange != STYLE)
652     {
653         for (i = 0; i < itemCount2; i++)
654         {
655             items[i] = XmStringCreate(itemBuf2[i], XmSTRING_DEFAULT_CHARSET);
656             NEditFree(itemBuf2[i]);
657         }
658         XmListDeleteAllItems(ctrlBlk.styleList);
659         XmListAddItems(ctrlBlk.styleList, items, itemCount2, 1);
660         if (ctrlBlk.sel2 != NULL)
661         {
662             XmStringFree(items[0]);
663             items[0] = XmStringCreate(ctrlBlk.sel2, XmSTRING_DEFAULT_CHARSET);
664             XmListSelectItem(ctrlBlk.styleList, items[0], FALSE);
665             XmListSetBottomItem(ctrlBlk.styleList, items[0]);
666         }
667         for (i = 0; i < itemCount2; i++)
668             XmStringFree(items[i]);
669     }
670 
671     if (dontChange != SIZE)
672     {
673         for (i = 0; i < itemCount3; i++)
674         {
675             items[i] = XmStringCreate(itemBuf3[i],
676                               XmSTRING_DEFAULT_CHARSET);
677             NEditFree(itemBuf3[i]);
678         }
679         XmListDeleteAllItems(ctrlBlk.sizeList);
680         XmListAddItems(ctrlBlk.sizeList, items, itemCount3, 1);
681         if (ctrlBlk.sel3 != NULL)
682         {
683             XmStringFree(items[0]);
684             items[0] = XmStringCreate(ctrlBlk.sel3, XmSTRING_DEFAULT_CHARSET);
685             XmListSelectItem(ctrlBlk.sizeList, items[0], FALSE);
686             XmListSetBottomItem(ctrlBlk.sizeList, items[0]);
687         }
688         for (i = 0; i < itemCount3; i++)
689             XmStringFree(items[i]);
690     }
691 }
692 
693 
694 /*  returns TRUE if argument is not name of a proportional font */
695 
notPropFont(const char * font)696 static int  notPropFont(const char *font)
697 {
698     char    buff1[TEMP_BUF_SIZE];
699 
700     getStringComponent(font, 11, buff1);
701     if ((strcmp(buff1, "p") == 0) || (strcmp(buff1, "P") == 0))
702         return(FALSE);
703     else
704         return(TRUE);
705 }
706 
707 
708 /*  returns TRUE if the style portion of the font matches the currently
709     selected style */
710 
styleMatch(xfselControlBlkType * ctrlBlk,const char * font)711 static int  styleMatch(xfselControlBlkType *ctrlBlk, const char *font)
712 {
713     char    buff[TEMP_BUF_SIZE];
714 
715     if (ctrlBlk->sel2 == NULL)
716         return(TRUE);
717 
718     getStylePart(font, buff);
719 
720     if (strcmp(buff, ctrlBlk->sel2) == 0)
721         return(TRUE);
722     else
723         return(FALSE);
724 }
725 
726 
727 /*  returns TRUE if the size portion of the font matches the currently
728     selected size */
729 
sizeMatch(xfselControlBlkType * ctrlBlk,const char * font)730 static int  sizeMatch(xfselControlBlkType *ctrlBlk, const char *font)
731 {
732     char    buff[TEMP_BUF_SIZE];
733 
734     if (ctrlBlk->sel3 == NULL)
735         return(TRUE);
736 
737     getSizePart(font, buff, ctrlBlk->showSizeInPixels);
738     if (strcmp(buff, ctrlBlk->sel3) == 0)
739         return(TRUE);
740     else
741         return(FALSE);
742 }
743 
744 
745 /*  returns TRUE if the font portion of the font matches the currently
746     selected font */
747 
fontMatch(xfselControlBlkType * ctrlBlk,const char * font)748 static int  fontMatch(xfselControlBlkType *ctrlBlk, const char *font)
749 {
750     char    buff[TEMP_BUF_SIZE];
751 
752     if (ctrlBlk->sel1 == NULL)
753         return(TRUE);
754 
755     getFontPart(font, buff);
756     if (strcmp(buff, ctrlBlk->sel1) == 0)
757         return(TRUE);
758     else
759         return(FALSE);
760 }
761 
762 
763 /*  inserts a string into correct sorted position in a list */
764 
addItemToList(char ** buf,const char * item,int * count)765 static void addItemToList(char **buf, const char *item, int *count)
766 {
767     int i, j;
768 
769     if (*count == MAX_ENTRIES_IN_LIST)
770     {
771         fprintf(stderr, "Trying to add more than MAX_ENTRIES_IN_LIST ");
772         fprintf(stderr, "(%d) entries to array\n", MAX_ENTRIES_IN_LIST);
773         return;
774     }
775 
776     for (i = 0; i < *count; i++)
777     {
778         if (strcmp(buf[i], item) == 0)
779             return;
780         if (strcmp(buf[i], item) > 0)
781             break;
782     }
783 
784     for (j = *count; j > i; j--)
785         buf[j] = buf[j-1];
786     buf[i] = NEditStrdup(item);
787     (*count)++;
788 }
789 
790 
791 /*  given a font name this function returns the part used in the first
792     scroll list */
793 
getFontPart(const char * font,char * buff1)794 static void getFontPart(const char *font, char *buff1)
795 {
796     char    buff2[TEMP_BUF_SIZE], buff3[TEMP_BUF_SIZE];
797     char    buff4[TEMP_BUF_SIZE];
798 
799     getStringComponent(font, 2, buff1);
800     getStringComponent(font, 1, buff2);
801 
802     sprintf(buff3, "%s (%s", buff1, buff2);
803 
804     getStringComponent(font, 13, buff1);
805     getStringComponent(font, 14, buff4);
806 
807     if (((strncmp(buff1, "iso8859", 7) == 0) ||
808          (strncmp(buff1, "ISO8859", 7) == 0)) && (strcmp(buff4, "1") == 0))
809         sprintf(buff1, "%s)", buff3);
810     else
811     {
812         sprintf(buff2, "%s, %s,", buff3, buff1);
813         sprintf(buff1, "%s %s)", buff2, buff4);
814     }
815 }
816 
817 
818 /*  given a font name this function returns the part used in the second
819     scroll list */
820 
getStylePart(const char * font,char * buff1)821 static void getStylePart(const char *font, char *buff1)
822 {
823     char    buff2[TEMP_BUF_SIZE], buff3[TEMP_BUF_SIZE];
824 
825     getStringComponent(font, 3, buff3);
826     getStringComponent(font, 5, buff2);
827 
828     if ((strcmp(buff2, "normal") != 0) && (strcmp(buff2, "Normal") != 0) &&
829         (strcmp(buff2, "NORMAL") != 0))
830         sprintf(buff1, "%s %s", buff3, buff2);
831     else
832         strcpy(buff1, buff3);
833 
834     getStringComponent(font, 6, buff2);
835 
836     if (buff2[0] != '\0')
837         sprintf(buff3, "%s %s", buff1, buff2);
838     else
839         strcpy(buff3, buff1);
840 
841     getStringComponent(font, 4, buff2);
842 
843     if ((strcmp(buff2, "o") == 0) || (strcmp(buff2, "O") == 0))
844         sprintf(buff1, "%s oblique", buff3);
845     else if ((strcmp(buff2, "i") == 0) || (strcmp(buff2, "I") == 0))
846         sprintf(buff1, "%s italic", buff3);
847 
848     if (strcmp(buff1, " ") == 0)
849         strcpy(buff1, "-");
850 }
851 
852 
853 /*  given a font name this function returns the part used in the third
854     scroll list */
855 
getSizePart(const char * font,char * buff1,int inPixels)856 static void getSizePart(const char *font, char *buff1, int inPixels)
857 {
858     int size;
859 
860     if (inPixels)
861     {
862         getStringComponent(font, 7, buff1);
863         size = atoi(buff1);
864         sprintf(buff1, "%2d", size);
865     }
866     else
867     {
868         double temp;
869 
870         getStringComponent(font, 8, buff1);
871         size = atoi(buff1);
872         temp = (double)size / 10.0;
873         if (buff1[strlen(buff1) - 1] == '0')
874         {
875             size = (int)floor(temp+0.5);
876             sprintf(buff1, "%2d", size);
877         }
878         else
879             sprintf(buff1, "%4.1f", temp);
880     }
881 }
882 
883 
884 /*  Call back functions start from here - suffix Action in the function name
885     is for the callback function for the corresponding widget */
886 
propFontToggleAction(Widget widget,xfselControlBlkType * ctrlBlk,XmToggleButtonCallbackStruct * call_data)887 static void propFontToggleAction(Widget widget,
888                      xfselControlBlkType *ctrlBlk,
889                      XmToggleButtonCallbackStruct *call_data)
890 {
891     if (call_data->reason == XmCR_VALUE_CHANGED)
892     {
893         if (ctrlBlk->showPropFonts == PREF_FIXED)
894             ctrlBlk->showPropFonts = PREF_PROP;
895         else
896             ctrlBlk->showPropFonts = PREF_FIXED;
897 
898         NEditFree(ctrlBlk->sel1);
899         ctrlBlk->sel1 = NULL;
900 
901         NEditFree(ctrlBlk->sel2);
902         ctrlBlk->sel2 = NULL;
903 
904         NEditFree(ctrlBlk->sel3);
905         ctrlBlk->sel3 = NULL;
906 
907         setupScrollLists(NONE, *ctrlBlk);
908 
909         XmTextSetString(ctrlBlk->fontNameField, "");
910         enableSample(ctrlBlk, False, NULL);
911     }
912 }
913 
914 
sizeToggleAction(Widget widget,xfselControlBlkType * ctrlBlk,XmToggleButtonCallbackStruct * call_data)915 static void sizeToggleAction(Widget widget,
916                  xfselControlBlkType *ctrlBlk,
917                  XmToggleButtonCallbackStruct *call_data)
918 {
919     int         i, makeSelection;
920     char        newSize[10];
921     XmString    str;
922 
923     if (call_data->reason == XmCR_VALUE_CHANGED)
924     {
925         makeSelection = (ctrlBlk->sel3 != NULL);
926 
927         for (i = 0; (makeSelection) && (i < ctrlBlk->numFonts); i++)
928             if ((fontMatch(ctrlBlk, ctrlBlk->fontData[i])) &&
929                 (styleMatch(ctrlBlk, ctrlBlk->fontData[i])) &&
930                 (sizeMatch(ctrlBlk, ctrlBlk->fontData[i])))
931             {
932                 getSizePart(ctrlBlk->fontData[i], newSize,
933                             !ctrlBlk->showSizeInPixels);
934                 break;
935             }
936 
937         if (ctrlBlk->showSizeInPixels)
938             ctrlBlk->showSizeInPixels = FALSE;
939         else
940             ctrlBlk->showSizeInPixels = TRUE;
941 
942         NEditFree(ctrlBlk->sel3);
943 
944         ctrlBlk->sel3 = NULL;
945         setupScrollLists(NONE, *ctrlBlk);
946 
947         if (makeSelection)
948         {
949             str = XmStringCreate(newSize, XmSTRING_DEFAULT_CHARSET);
950             XmListSelectItem(ctrlBlk->sizeList, str, TRUE);
951             XmListSetBottomItem(ctrlBlk->sizeList, str);
952             XmStringFree(str);
953         }
954     }
955 }
956 
957 
enableSample(xfselControlBlkType * ctrlBlk,Bool turn_on,XmFontList * fontList)958 static void enableSample(xfselControlBlkType *ctrlBlk, Bool turn_on,
959         XmFontList *fontList)
960 {
961     int n=0;
962     Arg args[4];
963 
964     XtSetArg(args[n], XmNeditable, turn_on); n++;
965     XtSetArg(args[n], XmNcursorPositionVisible, turn_on); n++;
966     if( turn_on ) {
967         if( !fontList ) {
968             fprintf(stderr, "nedit: Internal error in fontsel.c, line %i\n", \
969                     __LINE__);
970         } else {
971             XtSetArg(args[n], XmNfontList, *fontList); n++;
972         }
973         XtSetArg(args[n], XmNforeground, ctrlBlk->sampleFG); n++;
974     } else {
975         XtSetArg(args[n], XmNforeground, ctrlBlk->sampleBG); n++;
976     }
977     XtSetValues(ctrlBlk->dispField, args, n);
978     /* Make sure the sample area gets resized if the font size changes */
979     XtUnmanageChild(ctrlBlk->dispField);
980     XtManageChild(ctrlBlk->dispField);
981 }
982 
983 
fontAction(Widget widget,xfselControlBlkType * ctrlBlk,XmListCallbackStruct * call_data)984 static void fontAction(Widget widget, xfselControlBlkType *ctrlBlk,
985                  XmListCallbackStruct *call_data)
986 {
987     char    *sel;
988 
989     XmStringGetLtoR(call_data->item, XmSTRING_DEFAULT_CHARSET, &sel);
990 
991     if (ctrlBlk->sel1 == NULL)
992     {
993         ctrlBlk->sel1 = NEditStrdup(sel);
994     }
995     else
996     {
997         if (strcmp(ctrlBlk->sel1, sel) == 0)
998         {           /* Unselecting current selection */
999             NEditFree(ctrlBlk->sel1);
1000             ctrlBlk->sel1 = NULL;
1001             XmListDeselectItem(widget, call_data->item);
1002         }
1003         else
1004         {
1005             NEditFree(ctrlBlk->sel1);
1006             ctrlBlk->sel1 = NEditStrdup(sel);
1007         }
1008     }
1009 
1010     NEditFree(sel);
1011     setupScrollLists(FONT, *ctrlBlk);
1012     if ((ctrlBlk->sel1 != NULL) && (ctrlBlk->sel2 != NULL) &&
1013         (ctrlBlk->sel3 != NULL))
1014         choiceMade(ctrlBlk);
1015     else
1016     {
1017         enableSample(ctrlBlk, False, NULL);
1018         XmTextSetString(ctrlBlk->fontNameField, "");
1019     }
1020 }
1021 
1022 
styleAction(Widget widget,xfselControlBlkType * ctrlBlk,XmListCallbackStruct * call_data)1023 static void styleAction(Widget widget, xfselControlBlkType *ctrlBlk,
1024                  XmListCallbackStruct *call_data)
1025 {
1026     char    *sel;
1027 
1028     XmStringGetLtoR(call_data->item, XmSTRING_DEFAULT_CHARSET, &sel);
1029 
1030     if (ctrlBlk->sel2 == NULL)
1031     {
1032         ctrlBlk->sel2 = NEditStrdup(sel);
1033     }
1034     else
1035     {
1036         if (strcmp(ctrlBlk->sel2, sel) == 0)
1037         {           /* unselecting current selection */
1038             NEditFree(ctrlBlk->sel2);
1039             ctrlBlk->sel2 = NULL;
1040             XmListDeselectItem(widget, call_data->item);
1041         }
1042         else
1043         {
1044             NEditFree(ctrlBlk->sel2);
1045             ctrlBlk->sel2 = NEditStrdup(sel);
1046         }
1047     }
1048 
1049     NEditFree(sel);
1050     setupScrollLists(STYLE, *ctrlBlk);
1051     if ((ctrlBlk->sel1 != NULL) && (ctrlBlk->sel2 != NULL) &&
1052         (ctrlBlk->sel3 != NULL))
1053         choiceMade(ctrlBlk);
1054     else
1055     {
1056         enableSample(ctrlBlk, False, NULL);
1057         XmTextSetString(ctrlBlk->fontNameField, "");
1058     }
1059 }
1060 
sizeAction(Widget widget,xfselControlBlkType * ctrlBlk,XmListCallbackStruct * call_data)1061 static void sizeAction(Widget widget, xfselControlBlkType *ctrlBlk,
1062                  XmListCallbackStruct *call_data)
1063 {
1064     char    *sel;
1065 
1066     XmStringGetLtoR(call_data->item, XmSTRING_DEFAULT_CHARSET, &sel);
1067 
1068     if (ctrlBlk->sel3 == NULL)
1069     {
1070         ctrlBlk->sel3 = NEditStrdup(sel);
1071     }
1072     else
1073     {
1074         if (strcmp(ctrlBlk->sel3, sel) == 0)
1075         {           /* unselecting current selection */
1076             NEditFree(ctrlBlk->sel3);
1077             ctrlBlk->sel3 = NULL;
1078             XmListDeselectItem(widget, call_data->item);
1079         }
1080         else
1081         {
1082             NEditFree(ctrlBlk->sel3);
1083             ctrlBlk->sel3 = NEditStrdup(sel);
1084         }
1085     }
1086 
1087     NEditFree(sel);
1088     setupScrollLists(SIZE, *ctrlBlk);
1089     if ((ctrlBlk->sel1 != NULL) && (ctrlBlk->sel2 != NULL) &&
1090         (ctrlBlk->sel3 != NULL))
1091         choiceMade(ctrlBlk);
1092     else
1093     {
1094         enableSample(ctrlBlk, False, NULL);
1095         XmTextSetString(ctrlBlk->fontNameField, "");
1096     }
1097 }
1098 
1099 /*  function called when all three choices have been made; sets up font
1100     name and displays sample font */
1101 
choiceMade(xfselControlBlkType * ctrlBlk)1102 static void choiceMade(xfselControlBlkType *ctrlBlk)
1103 {
1104     int i;
1105 
1106     NEditFree(ctrlBlk->fontName);
1107     ctrlBlk->fontName = NULL;
1108 
1109     for (i = 0; i < ctrlBlk->numFonts; i++)
1110     {
1111         if ((fontMatch(ctrlBlk, ctrlBlk->fontData[i])) &&
1112             (styleMatch(ctrlBlk, ctrlBlk->fontData[i])) &&
1113             (sizeMatch (ctrlBlk, ctrlBlk->fontData[i])))
1114         {
1115             ctrlBlk->fontName = NEditStrdup(ctrlBlk->fontData[i]);
1116             break;
1117         }
1118     }
1119 
1120     if (ctrlBlk->fontName != NULL)
1121     {
1122         XmTextSetString(ctrlBlk->fontNameField, ctrlBlk->fontName);
1123         dispSample(ctrlBlk);
1124     }
1125     else
1126     {
1127         DialogF (DF_ERR, ctrlBlk->form, 1, "Font Specification",
1128                 "Invalid Font Specification", "OK");
1129     }
1130 }
1131 
1132 
1133 /*  loads selected font and displays sample text in that font */
1134 
dispSample(xfselControlBlkType * ctrlBlk)1135 static void dispSample(xfselControlBlkType *ctrlBlk)
1136 {
1137     XFontStruct     *font;
1138     XmFontList      fontList;
1139     Display         *display;
1140 
1141     display     = XtDisplay(ctrlBlk->form);
1142     font        = XLoadQueryFont(display, ctrlBlk->fontName);
1143     fontList    = XmFontListCreate(font, XmSTRING_DEFAULT_CHARSET);
1144 
1145     enableSample(ctrlBlk, True, &fontList);
1146 
1147     if (ctrlBlk->oldFont != NULL)
1148     {
1149         XFreeFont(display, ctrlBlk->oldFont);
1150         XmFontListFree(ctrlBlk->oldFontList);
1151     }
1152     ctrlBlk->oldFont    = font;
1153     ctrlBlk->oldFontList    = fontList;
1154 }
1155 
1156 
destroyCB(Widget widget,xfselControlBlkType * ctrlBlk,XmListCallbackStruct * call_data)1157 static void destroyCB(Widget widget, xfselControlBlkType *ctrlBlk,
1158                  XmListCallbackStruct *call_data)
1159 {
1160     /* Prevent double destruction of the font selection dialog */
1161     ctrlBlk->destroyedFlag = TRUE;
1162     cancelAction(widget, ctrlBlk, call_data);
1163 }
1164 
cancelAction(Widget widget,xfselControlBlkType * ctrlBlk,XmListCallbackStruct * call_data)1165 static void cancelAction(Widget widget, xfselControlBlkType *ctrlBlk,
1166                  XmListCallbackStruct *call_data)
1167 {
1168     NEditFree(ctrlBlk->sel1);
1169     NEditFree(ctrlBlk->sel2);
1170     NEditFree(ctrlBlk->sel3);
1171     NEditFree(ctrlBlk->fontName);
1172 
1173     ctrlBlk->fontName = NULL;
1174     XFreeFontNames(ctrlBlk->fontData);
1175 
1176     ctrlBlk->exitFlag = TRUE;
1177 }
1178 
1179 
okAction(Widget widget,xfselControlBlkType * ctrlBlk,XmPushButtonCallbackStruct * call_data)1180 static void okAction(Widget widget, xfselControlBlkType *ctrlBlk,
1181                  XmPushButtonCallbackStruct *call_data)
1182 {
1183     char    *fontPattern;
1184     char    **fontName;
1185     int i;
1186 
1187     fontPattern = XmTextGetString(ctrlBlk->fontNameField);
1188     fontName    = XListFonts(XtDisplay(ctrlBlk->form), fontPattern, 1, &i);
1189     NEditFree(fontPattern);
1190 
1191     if ((fontName == NULL) || (i == 0))
1192     {
1193         DialogF (DF_ERR, ctrlBlk->okButton, 1, "Font Specification",
1194                 "Invalid Font Specification", "OK");
1195         XFreeFontNames(fontName);
1196     }
1197     else
1198     {
1199         NEditFree(ctrlBlk->fontName);
1200         ctrlBlk->fontName = NEditStrdup(fontName[0]);
1201 
1202         NEditFree(ctrlBlk->sel1);
1203         NEditFree(ctrlBlk->sel2);
1204         NEditFree(ctrlBlk->sel3);
1205 
1206         XFreeFontNames(fontName);
1207         XFreeFontNames(ctrlBlk->fontData);
1208 
1209         ctrlBlk->exitFlag = TRUE;
1210     }
1211 }
1212 
1213 
1214 /*  if current font is passed as an argument then this function is
1215     invoked and sets up initial entries */
1216 
startupFont(xfselControlBlkType * ctrlBlk,const char * font)1217 static void startupFont(xfselControlBlkType *ctrlBlk, const char *font)
1218 {
1219     int         i;
1220     char        **fontName;
1221     char        part[TEMP_BUF_SIZE];
1222     XmString    str;
1223 
1224     fontName = XListFonts(XtDisplay(ctrlBlk->form), font, 1, &i);
1225 
1226     if ((fontName == NULL) || (i == 0))
1227     {           /*  invalid font passed in at startup */
1228         XFreeFontNames(fontName);
1229         return;
1230     }
1231 
1232     ctrlBlk->fontName = NEditStrdup(fontName[0]);
1233 
1234     getFontPart(fontName[0], part);
1235     XFreeFontNames(fontName);
1236     str = XmStringCreate(part, XmSTRING_DEFAULT_CHARSET);
1237     XmListSetBottomItem(ctrlBlk->fontList, str);
1238     XmListSelectItem(ctrlBlk->fontList, str, TRUE);
1239     XmListSelectItem(ctrlBlk->fontList, str, TRUE);
1240     XmStringFree(str);
1241 
1242     dispSample(ctrlBlk);
1243     XmTextSetString(ctrlBlk->fontNameField, ctrlBlk->fontName);
1244 }
1245 
1246 
1247 /*  hacked code to move initial input focus to first scroll list and at the
1248     same time have the OK button as the default button */
1249 
setFocus(Widget w,xfselControlBlkType * ctrlBlk,XEvent * event,Boolean * continueToDispatch)1250 static void     setFocus(Widget w, xfselControlBlkType *ctrlBlk, XEvent *event,
1251                         Boolean *continueToDispatch)
1252 {
1253     int n;
1254     Arg args[2];
1255 
1256     *continueToDispatch = TRUE;
1257 
1258     n = 0;
1259     XtSetArg(args[n], XmNdefaultButton, ctrlBlk->okButton); n++;
1260     XtSetValues(ctrlBlk->form, args, n);
1261 }
1262 
1263 
1264 /*  finds the name of the biggest font less than the given limit
1265     MAX_DISPLAY_SIZE used to set up the initial height of the display widget
1266 */
1267 
FindBigFont(xfselControlBlkType * ctrlBlk,char * bigFont)1268 static void FindBigFont(xfselControlBlkType *ctrlBlk, char *bigFont)
1269 {
1270     int     i, maxSize, ind = -1, size;
1271     char    sizeStr[10];
1272 
1273     for (i = 0, maxSize = 0; i < ctrlBlk->numFonts; i++)
1274     {
1275         getStringComponent(ctrlBlk->fontData[i], 7, sizeStr);
1276         size = atoi(sizeStr);
1277         if ((size > maxSize) && (size < MAX_DISPLAY_SIZE))
1278         {
1279             ind   = i;
1280             maxSize = size;
1281         }
1282     }
1283     if (ind >= 0) {
1284         strcpy(bigFont, ctrlBlk->fontData[ind]);
1285     }
1286     else {
1287         bigFont[0] = 0;
1288     }
1289 }
1290