Added some comments to the new string allocation routines.
[nedit.git] / util / fontsel.c
blobab89b964d7145035168e512c70c9cbe13cbc8679
1 static const char CVSID[] = "$Id: fontsel.c,v 1.25 2003/05/02 19:19:03 edg Exp $";
2 /*******************************************************************************
3 * *
4 * fontsel.c -- Nirvana Font Selector *
5 * *
6 * Copyright (C) 1999 Mark Edel *
7 * *
8 * This is free software; you can redistribute it and/or modify it under the *
9 * terms of the GNU General Public License as published by the Free Software *
10 * Foundation; either version 2 of the License, or (at your option) any later *
11 * version. *
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 *******************************************************************************/
29 #ifdef HAVE_CONFIG_H
30 #include "../config.h"
31 #endif
33 #include "fontsel.h"
34 #include "misc.h"
35 #include "DialogF.h"
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <math.h>
42 #include <X11/Intrinsic.h>
43 #include <Xm/Xm.h>
44 #include <Xm/Form.h>
45 #include <Xm/PushB.h>
46 #include <Xm/List.h>
47 #include <Xm/Label.h>
48 #include <Xm/Text.h>
49 #include <Xm/TextF.h>
50 #include <Xm/ToggleB.h>
51 #include <Xm/MessageB.h>
52 #include <Xm/DialogS.h>
54 #ifdef HAVE_DEBUG_H
55 #include "../debug.h"
56 #endif
58 #define MAX_ARGS 20
59 #define MAX_NUM_FONTS 32767
60 #define MAX_FONT_NAME_LEN 256
61 #define MAX_ENTRIES_IN_LIST 5000
62 #define MAX_DISPLAY_SIZE 150
63 #define DELIM '-'
64 #define NUM_COMPONENTS_FONT_NAME 14
65 #define TEMP_BUF_SIZE 256
66 #define DISPLAY_HEIGHT 90
68 enum listSpecifier { NONE, FONT, STYLE, SIZE };
71 /* local data structures and types */
73 typedef struct
75 Widget form; /* widget id */
76 Widget okButton; /* widget id */
77 Widget cancelButton; /* widget id */
78 Widget fontList; /* widget id */
79 Widget styleList; /* widget id */
80 Widget sizeList; /* widget id */
81 Widget fontNameField; /* widget id */
82 Widget sizeToggle; /* widget id */
83 Widget propFontToggle; /* widget id */
84 Widget dispField; /* widget id */
85 char **fontData; /* font name info */
86 int numFonts; /* number of fonts */
87 char *sel1; /* selection from list 1 */
88 char *sel2; /* selection from list 2 */
89 char *sel3; /* selection from list 3 */
90 int showPropFonts; /* toggle state - show prop fonts */
91 int showSizeInPixels;/* toggle state - size in pixels */
92 char *fontName; /* current font name */
93 XFontStruct *oldFont; /* font data structure for dispSample */
94 XmFontList oldFontList; /* font data structure for dispSample */
95 int exitFlag; /* used for program exit control */
96 int destroyedFlag; /* used to prevent double destruction */
97 Pixel sampleFG; /* Colors for the sample field */
98 Pixel sampleBG;
99 } xfselControlBlkType;
102 /* local function prototypes */
104 static void getStringComponent(const char *inStr, int pos, char *outStr);
105 static void setupScrollLists(int dontChange, xfselControlBlkType ctrlBlk);
106 static int notPropFont(const char *font);
107 static int styleMatch(xfselControlBlkType *ctrlBlk, const char *font);
108 static int sizeMatch(xfselControlBlkType *ctrlBlk, const char *font);
109 static int fontMatch(xfselControlBlkType *ctrlBlk, const char *font);
110 static void addItemToList(char **buf, const char *item, int *count);
111 static void getFontPart(const char *font, char *buff1);
112 static void getStylePart(const char *font, char *buff1);
113 static void getSizePart(const char *font, char *buff1, int inPixels);
114 static void propFontToggleAction(Widget widget,
115 xfselControlBlkType *ctrlBlk,
116 XmToggleButtonCallbackStruct *call_data);
117 static void sizeToggleAction(Widget widget,
118 xfselControlBlkType *ctrlBlk,
119 XmToggleButtonCallbackStruct *call_data);
120 static void fontAction(Widget widget, xfselControlBlkType *ctrlBlk,
121 XmListCallbackStruct *call_data);
122 static void styleAction(Widget widget, xfselControlBlkType *ctrlBlk,
123 XmListCallbackStruct *call_data);
124 static void sizeAction(Widget widget, xfselControlBlkType *ctrlBlk,
125 XmListCallbackStruct *call_data);
126 static void choiceMade(xfselControlBlkType *ctrlBlk);
127 static void dispSample(xfselControlBlkType *ctrlBlk);
128 static void destroyCB(Widget widget, xfselControlBlkType *ctrlBlk,
129 XmListCallbackStruct *call_data);
130 static void cancelAction(Widget widget, xfselControlBlkType *ctrlBlk,
131 XmListCallbackStruct *call_data);
132 static void okAction(Widget widget, xfselControlBlkType *ctrlBlk,
133 XmPushButtonCallbackStruct *call_data);
134 static void startupFont(xfselControlBlkType *ctrlBlk, const char *font);
135 static void setFocus(Widget w, xfselControlBlkType *ctrlBlk, XEvent *event,
136 Boolean *continueToDispatch);
137 static void FindBigFont(xfselControlBlkType *ctrlBlk, char *bigFont);
138 static void enableSample(xfselControlBlkType *ctrlBlk, Bool turn_on,
139 XmFontList *fontList);
141 /*******************************************************************************
143 * FontSel () *
146 * Function to put up a modal font selection dialog box. The purpose *
147 * of this routine is to allow the user to interactively view sample *
148 * fonts and to choose a font for current use. *
150 * Arguments: *
152 * Widget parent - parent widget ID *
154 * int showPropFont - ONLY_FIXED : shows only fixed fonts *
155 * doesn't show prop font *
156 * toggle button also. *
157 * PREF_FIXED : can select either fixed *
158 * or proportional fonts; *
159 * but starting option is *
160 * Fixed fonts. *
161 * PREF_PROP : can select either fixed *
162 * or proportional fonts; *
163 * but starting option is *
164 * proportional fonts. *
166 * char * currFont - ASCII string that contains the name *
167 * of the currently selected font. *
169 * Pixel sampleFG, sampleBG - Foreground/Background colors in *
170 * which to display the sample *
171 * text. *
174 * Returns: *
176 * pointer to an ASCII character string that contains the name of *
177 * the selected font (in X format for naming fonts); it is the users *
178 * responsibility to free the space allocated to this string. *
180 * Comments: *
182 * The calling function has to call the appropriate routines to set *
183 * the current font to the one represented by the returned string. *
185 *******************************************************************************/
187 char *FontSel(Widget parent, int showPropFonts, const char *currFont,
188 Pixel sampleFG, Pixel sampleBG)
190 Widget dialog, form, okButton, cancelButton;
191 Widget styleList, sizeList, fontName, fontList;
192 Widget sizeToggle, propFontToggle = NULL, dispField;
193 Widget nameLabel, sampleLabel;
194 Arg args[MAX_ARGS];
195 int n;
196 XmString tempStr;
197 char bigFont[MAX_FONT_NAME_LEN];
198 xfselControlBlkType ctrlBlk;
199 Display *theDisplay;
201 ctrlBlk.fontData = XListFonts(XtDisplay(parent),
202 "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
203 MAX_NUM_FONTS, &ctrlBlk.numFonts);
204 FindBigFont(&ctrlBlk, bigFont);
205 ctrlBlk.oldFont = XLoadQueryFont(XtDisplay(parent), bigFont);
206 ctrlBlk.oldFontList = XmFontListCreate(ctrlBlk.oldFont,
207 XmSTRING_DEFAULT_CHARSET);
208 ctrlBlk.sampleFG = sampleFG;
209 ctrlBlk.sampleBG = sampleBG;
211 dialog = CreateDialogShell(parent, "Font Selector", args, 0);
213 /* Set up window sizes for form widget */
215 n = 0;
216 XtSetArg(args[n], XmNautoUnmanage, FALSE); n++;
217 XtSetArg(args[n], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); n++;
219 /* Create form popup dialog widget */
221 form = XtCreateWidget ("Font Selector", xmFormWidgetClass, dialog,
222 args, n);
224 /* Create pushbutton widgets */
226 n = 0;
227 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
228 XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
229 XtSetArg(args[n], XmNbottomOffset, 4); n++;
230 XtSetArg(args[n], XmNtopOffset, 1); n++;
231 XtSetArg(args[n], XmNrightPosition, 45); n++;
232 XtSetArg(args[n], XmNwidth, 110); n++;
233 XtSetArg(args[n], XmNheight, 28); n++;
234 XtSetArg(args[n], XmNshowAsDefault, TRUE); n++;
235 okButton = XtCreateManagedWidget("OK", xmPushButtonWidgetClass, form,
236 args, n);
238 n = 0;
239 XtSetArg(args[n], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
240 XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
241 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
242 XtSetArg(args[n], XmNtopWidget, okButton); n++;
243 XtSetArg(args[n], XmNbottomWidget, okButton); n++;
244 XtSetArg(args[n], XmNleftPosition, 55); n++;
245 XtSetArg(args[n], XmNwidth, 110); n++;
246 XtSetArg(args[n], XmNheight, 28); n++;
247 cancelButton = XtCreateManagedWidget("Cancel", xmPushButtonWidgetClass,
248 form, args, n);
250 /* create font name text widget and the corresponding label */
252 n = 0;
253 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
254 XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
255 XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
256 XtSetArg(args[n], XmNbottomWidget, okButton); n++;
257 XtSetArg(args[n], XmNleftPosition, 1); n++;
258 XtSetArg(args[n], XmNrightPosition, 99); n++;
259 XtSetArg(args[n], XmNeditable, True); n++;
260 XtSetArg(args[n], XmNeditMode, XmSINGLE_LINE_EDIT); n++;
261 XtSetArg(args[n], XmNmaxLength, MAX_FONT_NAME_LEN); n++;
262 fontName = XtCreateManagedWidget("fontname", xmTextWidgetClass, form,
263 args, n);
264 RemapDeleteKey(fontName); /* kludge to handle delete and BS */
266 n = 0;
267 tempStr = XmStringCreate("Font Name:", XmSTRING_DEFAULT_CHARSET);
268 XtSetArg(args[n], XmNlabelString, tempStr); n++;
269 XtSetArg(args[n], XmNmnemonic, 'N'); n++;
270 XtSetArg(args[n], XmNuserData, fontName); n++;
271 XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
272 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
273 XtSetArg(args[n], XmNleftWidget, fontName); n++;
274 XtSetArg(args[n], XmNbottomWidget, fontName); n++;
275 XtSetArg(args[n], XmNtopOffset, 1); n++;
276 nameLabel = XtCreateManagedWidget("Font Name:", xmLabelWidgetClass,
277 form, args, n);
278 XmStringFree(tempStr);
280 /* create sample display text field widget */
282 n = 0;
283 XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
284 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
285 XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
286 XtSetArg(args[n], XmNrightPosition, 99); n++;
287 XtSetArg(args[n], XmNbottomWidget, nameLabel); n++;
288 XtSetArg(args[n], XmNleftPosition, 1); n++;
289 XtSetArg(args[n], XmNalignment, XmALIGNMENT_BEGINNING); n++;
290 XtSetArg(args[n], XmNvalue,
291 "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789");
292 n++;
293 XtSetArg(args[n], XmNforeground, sampleFG); n++;
294 XtSetArg(args[n], XmNbackground, sampleBG); n++;
295 dispField = XtCreateManagedWidget(" ", xmTextFieldWidgetClass, form,
296 args, n);
298 n = 0;
299 tempStr = XmStringCreate("Sample:", XmSTRING_DEFAULT_CHARSET);
300 XtSetArg(args[n], XmNlabelString, tempStr); n++;
301 XtSetArg(args[n], XmNmnemonic, 'S'); n++;
302 XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
303 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
304 XtSetArg(args[n], XmNleftWidget, dispField); n++;
305 XtSetArg(args[n], XmNbottomWidget, dispField); n++;
306 XtSetArg(args[n], XmNtopOffset, 1); n++;
307 sampleLabel = XtCreateManagedWidget("Font Name:", xmLabelWidgetClass,
308 form, args, n);
309 XmStringFree(tempStr);
311 /* create toggle buttons */
313 n = 0;
314 tempStr = XmStringCreate("Show Size in Points",
315 XmSTRING_DEFAULT_CHARSET);
316 XtSetArg(args[n], XmNlabelString, tempStr); n++;
317 XtSetArg(args[n], XmNmnemonic, 'P'); n++;
318 XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
319 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
320 XtSetArg(args[n], XmNleftPosition, 2); n++;
321 XtSetArg(args[n], XmNtopOffset, 1); n++;
322 XtSetArg(args[n], XmNbottomWidget, sampleLabel); n++;
323 sizeToggle = XtCreateManagedWidget("sizetoggle",
324 xmToggleButtonWidgetClass, form, args, n);
325 XmStringFree(tempStr);
327 if (showPropFonts != ONLY_FIXED)
329 n = 0;
330 tempStr = XmStringCreate("Show Proportional Width Fonts",
331 XmSTRING_DEFAULT_CHARSET);
332 XtSetArg(args[n], XmNlabelString, tempStr); n++;
333 XtSetArg(args[n], XmNmnemonic, 'W'); n++;
334 XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
335 XtSetArg(args[n], XmNtopAttachment,
336 XmATTACH_OPPOSITE_WIDGET); n++;
337 XtSetArg(args[n], XmNbottomAttachment,
338 XmATTACH_OPPOSITE_WIDGET); n++;
339 XtSetArg(args[n], XmNrightPosition, 98); n++;
340 XtSetArg(args[n], XmNtopWidget, sizeToggle); n++;
341 XtSetArg(args[n], XmNbottomWidget, sizeToggle); n++;
342 XtSetArg(args[n], XmNtopOffset, 1); n++;
343 propFontToggle = XtCreateManagedWidget("propfonttoggle",
344 xmToggleButtonWidgetClass, form, args, n);
345 XmStringFree(tempStr);
348 /* create scroll list widgets */
349 /* "Font" list */
351 n = 0;
352 tempStr = XmStringCreate("Font:", XmSTRING_DEFAULT_CHARSET);
353 XtSetArg(args[n], XmNlabelString, tempStr); n++;
354 XtSetArg(args[n], XmNmnemonic, 'F'); n++;
355 XtSetArg(args[n], XmNtopOffset, 2); n++;
356 XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
357 XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
358 XtSetArg(args[n], XmNleftPosition, 1); n++;
359 nameLabel = XtCreateManagedWidget("Font:", xmLabelWidgetClass, form,
360 args, n);
361 XmStringFree(tempStr);
363 n = 0;
364 XtSetArg(args[n], XmNvisibleItemCount, 15); n++;
365 XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
366 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
367 XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
368 XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
369 XtSetArg(args[n], XmNbottomWidget, sizeToggle); n++;
370 XtSetArg(args[n], XmNtopWidget, nameLabel); n++;
371 XtSetArg(args[n], XmNleftWidget, nameLabel); n++;
372 XtSetArg(args[n], XmNrightPosition, 52); n++;
373 fontList = XmCreateScrolledList(form, "fontlist", args, n);
374 AddMouseWheelSupport(fontList);
375 XtManageChild(fontList);
376 XtVaSetValues(nameLabel, XmNuserData, fontList, NULL);
378 /* "Style" list */
380 n = 0;
381 XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
382 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
383 XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
384 XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
385 XtSetArg(args[n], XmNtopWidget, nameLabel); n++;
386 XtSetArg(args[n], XmNleftOffset, 5); n++;
387 XtSetArg(args[n], XmNleftWidget, XtParent(fontList)); n++;
388 XtSetArg(args[n], XmNbottomWidget, XtParent(fontList)); n++;
389 XtSetArg(args[n], XmNrightPosition, 85); n++;
390 styleList = XmCreateScrolledList(form, "stylelist", args, n);
391 AddMouseWheelSupport(styleList);
392 XtManageChild(styleList);
394 n = 0;
395 tempStr = XmStringCreate("Style:", XmSTRING_DEFAULT_CHARSET);
396 XtSetArg(args[n], XmNmnemonic, 'y'); n++;
397 XtSetArg(args[n], XmNuserData, styleList); n++;
398 XtSetArg(args[n], XmNlabelString, tempStr); n++;
399 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
400 XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
401 XtSetArg(args[n], XmNbottomWidget, XtParent(styleList)); n++;
402 XtSetArg(args[n], XmNleftWidget, XtParent(styleList)); n++;
403 XtCreateManagedWidget("Style:", xmLabelWidgetClass, form, args, n);
404 XmStringFree(tempStr);
406 /* "Size" list */
408 n = 0;
409 XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
410 XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
411 XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
412 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
413 XtSetArg(args[n], XmNtopWidget, nameLabel); n++;
414 XtSetArg(args[n], XmNleftWidget, XtParent(styleList)); n++;
415 XtSetArg(args[n], XmNbottomWidget, XtParent(fontList)); n++;
416 XtSetArg(args[n], XmNleftOffset, 5); n++;
417 XtSetArg(args[n], XmNrightPosition, 99); n++;
418 sizeList = XmCreateScrolledList(form, "sizelist", args, n);
419 AddMouseWheelSupport(sizeList);
420 XtManageChild(sizeList);
422 n = 0;
423 tempStr = XmStringCreate("Size:", XmSTRING_DEFAULT_CHARSET);
424 XtSetArg(args[n], XmNlabelString, tempStr); n++;
425 XtSetArg(args[n], XmNmnemonic, 'z'); n++;
426 XtSetArg(args[n], XmNuserData, sizeList); n++;
427 XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
428 XtSetArg(args[n], XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET); n++;
429 XtSetArg(args[n], XmNbottomWidget, XtParent(sizeList)); n++;
430 XtSetArg(args[n], XmNleftWidget, XtParent(sizeList)); n++;
431 XtCreateManagedWidget("Size:", xmLabelWidgetClass, form, args, n);
432 XmStringFree(tempStr);
434 /* update form widgets cancel button */
436 n = 0;
437 XtSetArg(args[n], XmNcancelButton, cancelButton); n++;
438 XtSetValues(form, args, n);
441 /* update application's control block structure */
443 ctrlBlk.form = form;
444 ctrlBlk.okButton = okButton;
445 ctrlBlk.cancelButton = cancelButton;
446 ctrlBlk.fontList = fontList;
447 ctrlBlk.styleList = styleList;
448 ctrlBlk.sizeList = sizeList;
449 ctrlBlk.fontNameField = fontName;
450 ctrlBlk.sizeToggle = sizeToggle;
451 if (showPropFonts != ONLY_FIXED)
452 ctrlBlk.propFontToggle = propFontToggle;
453 ctrlBlk.dispField = dispField;
454 ctrlBlk.exitFlag = FALSE;
455 ctrlBlk.destroyedFlag = FALSE;
456 ctrlBlk.showPropFonts = showPropFonts;
457 ctrlBlk.showSizeInPixels = TRUE;
458 ctrlBlk.sel1 = NULL;
459 ctrlBlk.sel2 = NULL;
460 ctrlBlk.sel3 = NULL;
461 ctrlBlk.fontName = NULL;
463 setupScrollLists(NONE, ctrlBlk); /* update scroll lists */
465 if (showPropFonts == PREF_PROP)
466 XmToggleButtonSetState(propFontToggle, TRUE, FALSE);
468 /* Register callback functions */
470 if (showPropFonts != ONLY_FIXED)
471 XtAddCallback(propFontToggle, XmNvalueChangedCallback,
472 (XtCallbackProc)propFontToggleAction, (char *)&ctrlBlk);
473 XtAddCallback(sizeToggle, XmNvalueChangedCallback,
474 (XtCallbackProc)sizeToggleAction, (char *)&ctrlBlk);
475 XtAddCallback(fontList, XmNbrowseSelectionCallback,
476 (XtCallbackProc)fontAction, (char *)&ctrlBlk);
477 XtAddCallback(styleList, XmNbrowseSelectionCallback,
478 (XtCallbackProc)styleAction, (char *)&ctrlBlk);
479 XtAddCallback(sizeList, XmNbrowseSelectionCallback,
480 (XtCallbackProc)sizeAction, (char *)&ctrlBlk);
481 XtAddCallback(okButton, XmNactivateCallback,
482 (XtCallbackProc)okAction, (char *)&ctrlBlk);
483 XtAddCallback(cancelButton, XmNactivateCallback,
484 (XtCallbackProc)cancelAction, (char *)&ctrlBlk);
486 /* add event handler to setup input focus at start to scroll list */
488 XtAddEventHandler(fontList, FocusChangeMask, FALSE,
489 (XtEventHandler)setFocus, (char *)&ctrlBlk);
490 XmProcessTraversal(fontList, XmTRAVERSE_CURRENT);
492 /* setup tabgroups */
494 XmAddTabGroup(fontList);
495 XmAddTabGroup(styleList);
496 XmAddTabGroup(sizeList);
497 XmAddTabGroup(sizeToggle);
498 if (showPropFonts != ONLY_FIXED)
499 XmAddTabGroup(propFontToggle);
500 XmAddTabGroup(fontName);
501 XmAddTabGroup(okButton);
502 XmAddTabGroup(cancelButton);
504 /* Make sure that we don't try to access the dialog if the user
505 destroyed it (possibly indirectly, by destroying the parent). */
506 XtAddCallback(dialog, XmNdestroyCallback,
507 (XtCallbackProc)destroyCB, (char *)&ctrlBlk);
509 /* Link Motif Close option to cancel action */
511 AddMotifCloseCallback(dialog, (XtCallbackProc)cancelAction, &ctrlBlk);
513 /* Handle dialog mnemonics */
515 AddDialogMnemonicHandler(form, FALSE);
517 /* Realize Widgets */
519 ManageDialogCenteredOnPointer(form);
521 /* set up current font parameters */
523 if (currFont[0] != '\0')
524 startupFont(&ctrlBlk, currFont);
526 /* Make sure that we can still access the display in case the form
527 gets destroyed */
528 theDisplay = XtDisplay(form);
530 /* enter event loop */
532 while (! ctrlBlk.exitFlag && ! ctrlBlk.destroyedFlag)
533 XtAppProcessEvent(XtWidgetToApplicationContext(form), XtIMAll);
535 if (! ctrlBlk.destroyedFlag) {
536 /* Don't let the callback destroy the font name */
537 XtRemoveCallback(dialog, XmNdestroyCallback,
538 (XtCallbackProc)destroyCB, (char *)&ctrlBlk);
539 XtDestroyWidget(dialog);
542 if (ctrlBlk.oldFont != NULL)
544 XFreeFont(theDisplay, ctrlBlk.oldFont);
545 XmFontListFree(ctrlBlk.oldFontList);
548 return(ctrlBlk.fontName);
552 /* gets a specific substring from a string */
554 static void getStringComponent(const char *inStr, int pos, char *outStr)
556 int i, j;
558 *outStr = '\0';
560 if (pos > NUM_COMPONENTS_FONT_NAME)
562 fprintf(stderr, "Warning: getStringComponent being used for ");
563 fprintf(stderr, "pos > %d\nIf such ", NUM_COMPONENTS_FONT_NAME);
564 fprintf(stderr, "use is intended remove these warning lines\n");
567 for (i = 0; (pos > 0) && (inStr[i] != '\0'); i++)
568 if (inStr[i] == DELIM)
569 pos--;
571 if (inStr[i] == '\0')
572 return;
574 for (j = 0; (inStr[i] != DELIM) && (inStr[i] != '\0'); i++, j++)
575 outStr[j] = inStr[i];
576 outStr[j] = '\0';
580 /* parse through the fontlist data and set up the three scroll lists */
582 static void setupScrollLists(int dontChange, xfselControlBlkType ctrlBlk)
584 char *itemBuf1[MAX_ENTRIES_IN_LIST];
585 char *itemBuf2[MAX_ENTRIES_IN_LIST];
586 char *itemBuf3[MAX_ENTRIES_IN_LIST];
587 int itemCount1, itemCount2, itemCount3;
588 char buff1[TEMP_BUF_SIZE];
589 XmString items[MAX_ENTRIES_IN_LIST];
590 int i;
592 itemCount1 = 0;
593 itemCount2 = 0;
594 itemCount3 = 0;
596 for (i = 0; i < ctrlBlk.numFonts && i < MAX_ENTRIES_IN_LIST; i++)
598 if ((dontChange != FONT) &&
599 (styleMatch(&ctrlBlk, ctrlBlk.fontData[i])) &&
600 (sizeMatch (&ctrlBlk, ctrlBlk.fontData[i])) &&
601 ((ctrlBlk.showPropFonts == PREF_PROP) ||
602 (notPropFont(ctrlBlk.fontData[i]))))
604 getFontPart(ctrlBlk.fontData[i], buff1);
605 addItemToList(itemBuf1, buff1, &itemCount1);
608 if ((dontChange != STYLE) &&
609 (fontMatch(&ctrlBlk, ctrlBlk.fontData[i])) &&
610 (sizeMatch (&ctrlBlk, ctrlBlk.fontData[i])) &&
611 ((ctrlBlk.showPropFonts == PREF_PROP) ||
612 (notPropFont(ctrlBlk.fontData[i]))))
614 getStylePart(ctrlBlk.fontData[i], buff1);
615 addItemToList(itemBuf2, buff1, &itemCount2);
618 if ((dontChange != SIZE) &&
619 (fontMatch(&ctrlBlk, ctrlBlk.fontData[i])) &&
620 (styleMatch (&ctrlBlk, ctrlBlk.fontData[i])) &&
621 ((ctrlBlk.showPropFonts == PREF_PROP) ||
622 (notPropFont(ctrlBlk.fontData[i]))))
624 getSizePart(ctrlBlk.fontData[i], buff1, ctrlBlk.showSizeInPixels);
625 addItemToList(itemBuf3, buff1, &itemCount3);
627 } /* end - for (i = 0; i < ctrlBlk.numFonts; i++) */
629 /* recreate all three scroll lists where necessary */
630 if (dontChange != FONT)
632 for (i = 0; i < itemCount1; i++)
634 items[i] = XmStringCreate(itemBuf1[i], XmSTRING_DEFAULT_CHARSET);
635 XtFree(itemBuf1[i]);
637 XmListDeleteAllItems(ctrlBlk.fontList);
638 XmListAddItems(ctrlBlk.fontList, items, itemCount1, 1);
639 if (ctrlBlk.sel1 != NULL)
641 XmStringFree(items[0]);
642 items[0] = XmStringCreate(ctrlBlk.sel1, XmSTRING_DEFAULT_CHARSET);
643 XmListSelectItem(ctrlBlk.fontList, items[0], FALSE);
644 XmListSetBottomItem(ctrlBlk.fontList, items[0]);
646 for (i = 0; i < itemCount1; i++)
647 XmStringFree(items[i]);
650 if (dontChange != STYLE)
652 for (i = 0; i < itemCount2; i++)
654 items[i] = XmStringCreate(itemBuf2[i], XmSTRING_DEFAULT_CHARSET);
655 XtFree(itemBuf2[i]);
657 XmListDeleteAllItems(ctrlBlk.styleList);
658 XmListAddItems(ctrlBlk.styleList, items, itemCount2, 1);
659 if (ctrlBlk.sel2 != NULL)
661 XmStringFree(items[0]);
662 items[0] = XmStringCreate(ctrlBlk.sel2, XmSTRING_DEFAULT_CHARSET);
663 XmListSelectItem(ctrlBlk.styleList, items[0], FALSE);
664 XmListSetBottomItem(ctrlBlk.styleList, items[0]);
666 for (i = 0; i < itemCount2; i++)
667 XmStringFree(items[i]);
670 if (dontChange != SIZE)
672 for (i = 0; i < itemCount3; i++)
674 items[i] = XmStringCreate(itemBuf3[i],
675 XmSTRING_DEFAULT_CHARSET);
676 XtFree(itemBuf3[i]);
678 XmListDeleteAllItems(ctrlBlk.sizeList);
679 XmListAddItems(ctrlBlk.sizeList, items, itemCount3, 1);
680 if (ctrlBlk.sel3 != NULL)
682 XmStringFree(items[0]);
683 items[0] = XmStringCreate(ctrlBlk.sel3, XmSTRING_DEFAULT_CHARSET);
684 XmListSelectItem(ctrlBlk.sizeList, items[0], FALSE);
685 XmListSetBottomItem(ctrlBlk.sizeList, items[0]);
687 for (i = 0; i < itemCount3; i++)
688 XmStringFree(items[i]);
693 /* returns TRUE if argument is not name of a proportional font */
695 static int notPropFont(const char *font)
697 char buff1[TEMP_BUF_SIZE];
699 getStringComponent(font, 11, buff1);
700 if ((strcmp(buff1, "p") == 0) || (strcmp(buff1, "P") == 0))
701 return(FALSE);
702 else
703 return(TRUE);
707 /* returns TRUE if the style portion of the font matches the currently
708 selected style */
710 static int styleMatch(xfselControlBlkType *ctrlBlk, const char *font)
712 char buff[TEMP_BUF_SIZE];
714 if (ctrlBlk->sel2 == NULL)
715 return(TRUE);
717 getStylePart(font, buff);
719 if (strcmp(buff, ctrlBlk->sel2) == 0)
720 return(TRUE);
721 else
722 return(FALSE);
726 /* returns TRUE if the size portion of the font matches the currently
727 selected size */
729 static int sizeMatch(xfselControlBlkType *ctrlBlk, const char *font)
731 char buff[TEMP_BUF_SIZE];
733 if (ctrlBlk->sel3 == NULL)
734 return(TRUE);
736 getSizePart(font, buff, ctrlBlk->showSizeInPixels);
737 if (strcmp(buff, ctrlBlk->sel3) == 0)
738 return(TRUE);
739 else
740 return(FALSE);
744 /* returns TRUE if the font portion of the font matches the currently
745 selected font */
747 static int fontMatch(xfselControlBlkType *ctrlBlk, const char *font)
749 char buff[TEMP_BUF_SIZE];
751 if (ctrlBlk->sel1 == NULL)
752 return(TRUE);
754 getFontPart(font, buff);
755 if (strcmp(buff, ctrlBlk->sel1) == 0)
756 return(TRUE);
757 else
758 return(FALSE);
762 /* inserts a string into correct sorted position in a list */
764 static void addItemToList(char **buf, const char *item, int *count)
766 int i, j;
768 if (*count == MAX_ENTRIES_IN_LIST)
770 fprintf(stderr, "Trying to add more than MAX_ENTRIES_IN_LIST ");
771 fprintf(stderr, "(%d) entries to array\n", MAX_ENTRIES_IN_LIST);
772 return;
775 for (i = 0; i < *count; i++)
777 if (strcmp(buf[i], item) == 0)
778 return;
779 if (strcmp(buf[i], item) > 0)
780 break;
783 for (j = *count; j > i; j--)
784 buf[j] = buf[j-1];
785 buf[i] = XtMalloc(strlen(item) + 1);
786 strcpy(buf[i], item);
787 (*count)++;
791 /* given a font name this function returns the part used in the first
792 scroll list */
794 static void getFontPart(const char *font, char *buff1)
796 char buff2[TEMP_BUF_SIZE], buff3[TEMP_BUF_SIZE];
797 char buff4[TEMP_BUF_SIZE];
799 getStringComponent(font, 2, buff1);
800 getStringComponent(font, 1, buff2);
802 sprintf(buff3, "%s (%s", buff1, buff2);
804 getStringComponent(font, 13, buff1);
805 getStringComponent(font, 14, buff4);
807 if (((strncmp(buff1, "iso8859", 7) == 0) ||
808 (strncmp(buff1, "ISO8859", 7) == 0)) && (strcmp(buff4, "1") == 0))
809 sprintf(buff1, "%s)", buff3);
810 else
812 sprintf(buff2, "%s, %s,", buff3, buff1);
813 sprintf(buff1, "%s %s)", buff2, buff4);
818 /* given a font name this function returns the part used in the second
819 scroll list */
821 static void getStylePart(const char *font, char *buff1)
823 char buff2[TEMP_BUF_SIZE], buff3[TEMP_BUF_SIZE];
825 getStringComponent(font, 3, buff3);
826 getStringComponent(font, 5, buff2);
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);
834 getStringComponent(font, 6, buff2);
836 if (buff2[0] != '\0')
837 sprintf(buff3, "%s %s", buff1, buff2);
838 else
839 strcpy(buff3, buff1);
841 getStringComponent(font, 4, buff2);
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);
848 if (strcmp(buff1, " ") == 0)
849 strcpy(buff1, "-");
853 /* given a font name this function returns the part used in the third
854 scroll list */
856 static void getSizePart(const char *font, char *buff1, int inPixels)
858 int size;
860 if (inPixels)
862 getStringComponent(font, 7, buff1);
863 size = atoi(buff1);
864 sprintf(buff1, "%2d", size);
866 else
868 double temp;
870 getStringComponent(font, 8, buff1);
871 size = atoi(buff1);
872 temp = (double)size / 10.0;
873 if (buff1[strlen(buff1) - 1] == '0')
875 size = (int)floor(temp+0.5);
876 sprintf(buff1, "%2d", size);
878 else
879 sprintf(buff1, "%4.1f", temp);
884 /* Call back functions start from here - suffix Action in the function name
885 is for the callback function for the corresponding widget */
887 static void propFontToggleAction(Widget widget,
888 xfselControlBlkType *ctrlBlk,
889 XmToggleButtonCallbackStruct *call_data)
891 if (call_data->reason == XmCR_VALUE_CHANGED)
893 if (ctrlBlk->showPropFonts == PREF_FIXED)
894 ctrlBlk->showPropFonts = PREF_PROP;
895 else
896 ctrlBlk->showPropFonts = PREF_FIXED;
898 if (ctrlBlk->sel1 != NULL)
899 XtFree(ctrlBlk->sel1);
900 ctrlBlk->sel1 = NULL;
902 if (ctrlBlk->sel2 != NULL)
903 XtFree(ctrlBlk->sel2);
904 ctrlBlk->sel2 = NULL;
906 if (ctrlBlk->sel3 != NULL)
907 XtFree(ctrlBlk->sel3);
908 ctrlBlk->sel3 = NULL;
910 setupScrollLists(NONE, *ctrlBlk);
912 XmTextSetString(ctrlBlk->fontNameField, "");
913 enableSample(ctrlBlk, False, NULL);
918 static void sizeToggleAction(Widget widget,
919 xfselControlBlkType *ctrlBlk,
920 XmToggleButtonCallbackStruct *call_data)
922 int i, makeSelection;
923 char newSize[10];
924 XmString str;
926 if (call_data->reason == XmCR_VALUE_CHANGED)
928 makeSelection = (ctrlBlk->sel3 != NULL);
930 for (i = 0; (makeSelection) && (i < ctrlBlk->numFonts); i++)
931 if ((fontMatch(ctrlBlk, ctrlBlk->fontData[i])) &&
932 (styleMatch(ctrlBlk, ctrlBlk->fontData[i])) &&
933 (sizeMatch(ctrlBlk, ctrlBlk->fontData[i])))
935 getSizePart(ctrlBlk->fontData[i], newSize,
936 !ctrlBlk->showSizeInPixels);
937 break;
940 if (ctrlBlk->showSizeInPixels)
941 ctrlBlk->showSizeInPixels = FALSE;
942 else
943 ctrlBlk->showSizeInPixels = TRUE;
945 if (ctrlBlk->sel3 != NULL)
946 XtFree(ctrlBlk->sel3);
948 ctrlBlk->sel3 = NULL;
949 setupScrollLists(NONE, *ctrlBlk);
951 if (makeSelection)
953 str = XmStringCreate(newSize, XmSTRING_DEFAULT_CHARSET);
954 XmListSelectItem(ctrlBlk->sizeList, str, TRUE);
955 XmListSetBottomItem(ctrlBlk->sizeList, str);
956 XmStringFree(str);
962 static void enableSample(xfselControlBlkType *ctrlBlk, Bool turn_on,
963 XmFontList *fontList)
965 int n=0;
966 Arg args[4];
968 XtSetArg(args[n], XmNeditable, turn_on); n++;
969 XtSetArg(args[n], XmNcursorPositionVisible, turn_on); n++;
970 if( turn_on ) {
971 if( !fontList ) {
972 fprintf(stderr, "nedit: Internal error in fontsel.c, line %i\n", \
973 __LINE__);
974 } else {
975 XtSetArg(args[n], XmNfontList, *fontList); n++;
977 XtSetArg(args[n], XmNforeground, ctrlBlk->sampleFG); n++;
978 } else {
979 XtSetArg(args[n], XmNforeground, ctrlBlk->sampleBG); n++;
981 XtSetValues(ctrlBlk->dispField, args, n);
982 /* Make sure the sample area gets resized if the font size changes */
983 XtUnmanageChild(ctrlBlk->dispField);
984 XtManageChild(ctrlBlk->dispField);
988 static void fontAction(Widget widget, xfselControlBlkType *ctrlBlk,
989 XmListCallbackStruct *call_data)
991 char *sel;
993 XmStringGetLtoR(call_data->item, XmSTRING_DEFAULT_CHARSET, &sel);
995 if (ctrlBlk->sel1 == NULL)
997 ctrlBlk->sel1 = XtMalloc(strlen(sel) + 1);
998 strcpy(ctrlBlk->sel1, sel);
1000 else
1002 if (strcmp(ctrlBlk->sel1, sel) == 0)
1003 { /* Unselecting current selection */
1004 XtFree(ctrlBlk->sel1);
1005 ctrlBlk->sel1 = NULL;
1006 XmListDeselectItem(widget, call_data->item);
1008 else
1010 XtFree(ctrlBlk->sel1);
1011 ctrlBlk->sel1 = XtMalloc(strlen(sel) + 1);
1012 strcpy(ctrlBlk->sel1, sel);
1016 XtFree(sel);
1017 setupScrollLists(FONT, *ctrlBlk);
1018 if ((ctrlBlk->sel1 != NULL) && (ctrlBlk->sel2 != NULL) &&
1019 (ctrlBlk->sel3 != NULL))
1020 choiceMade(ctrlBlk);
1021 else
1023 enableSample(ctrlBlk, False, NULL);
1024 XmTextSetString(ctrlBlk->fontNameField, "");
1029 static void styleAction(Widget widget, xfselControlBlkType *ctrlBlk,
1030 XmListCallbackStruct *call_data)
1032 char *sel;
1034 XmStringGetLtoR(call_data->item, XmSTRING_DEFAULT_CHARSET, &sel);
1036 if (ctrlBlk->sel2 == NULL)
1038 ctrlBlk->sel2 = XtMalloc(strlen(sel) + 1);
1039 strcpy(ctrlBlk->sel2, sel);
1041 else
1043 if (strcmp(ctrlBlk->sel2, sel) == 0)
1044 { /* unselecting current selection */
1045 XtFree(ctrlBlk->sel2);
1046 ctrlBlk->sel2 = NULL;
1047 XmListDeselectItem(widget, call_data->item);
1049 else
1051 XtFree(ctrlBlk->sel2);
1052 ctrlBlk->sel2 = XtMalloc(strlen(sel) + 1);
1053 strcpy(ctrlBlk->sel2, sel);
1057 XtFree(sel);
1058 setupScrollLists(STYLE, *ctrlBlk);
1059 if ((ctrlBlk->sel1 != NULL) && (ctrlBlk->sel2 != NULL) &&
1060 (ctrlBlk->sel3 != NULL))
1061 choiceMade(ctrlBlk);
1062 else
1064 enableSample(ctrlBlk, False, NULL);
1065 XmTextSetString(ctrlBlk->fontNameField, "");
1069 static void sizeAction(Widget widget, xfselControlBlkType *ctrlBlk,
1070 XmListCallbackStruct *call_data)
1072 char *sel;
1074 XmStringGetLtoR(call_data->item, XmSTRING_DEFAULT_CHARSET, &sel);
1076 if (ctrlBlk->sel3 == NULL)
1078 ctrlBlk->sel3 = XtMalloc(strlen(sel) + 1);
1079 strcpy(ctrlBlk->sel3, sel);
1081 else
1083 if (strcmp(ctrlBlk->sel3, sel) == 0)
1084 { /* unselecting current selection */
1085 XtFree(ctrlBlk->sel3);
1086 ctrlBlk->sel3 = NULL;
1087 XmListDeselectItem(widget, call_data->item);
1089 else
1091 XtFree(ctrlBlk->sel3);
1092 ctrlBlk->sel3 = XtMalloc(strlen(sel) + 1);
1093 strcpy(ctrlBlk->sel3, sel);
1097 XtFree(sel);
1098 setupScrollLists(SIZE, *ctrlBlk);
1099 if ((ctrlBlk->sel1 != NULL) && (ctrlBlk->sel2 != NULL) &&
1100 (ctrlBlk->sel3 != NULL))
1101 choiceMade(ctrlBlk);
1102 else
1104 enableSample(ctrlBlk, False, NULL);
1105 XmTextSetString(ctrlBlk->fontNameField, "");
1109 /* function called when all three choices have been made; sets up font
1110 name and displays sample font */
1112 static void choiceMade(xfselControlBlkType *ctrlBlk)
1114 int i;
1116 if (ctrlBlk->fontName != NULL)
1117 XtFree(ctrlBlk->fontName);
1118 ctrlBlk->fontName = NULL;
1120 for (i = 0; i < ctrlBlk->numFonts; i++)
1122 if ((fontMatch(ctrlBlk, ctrlBlk->fontData[i])) &&
1123 (styleMatch(ctrlBlk, ctrlBlk->fontData[i])) &&
1124 (sizeMatch (ctrlBlk, ctrlBlk->fontData[i])))
1126 ctrlBlk->fontName = XtMalloc(
1127 strlen(ctrlBlk->fontData[i]) + 1);
1128 strcpy(ctrlBlk->fontName, ctrlBlk->fontData[i]);
1129 break;
1133 if (ctrlBlk->fontName != NULL)
1135 XmTextSetString(ctrlBlk->fontNameField, ctrlBlk->fontName);
1136 dispSample(ctrlBlk);
1138 else
1140 DialogF (DF_ERR, ctrlBlk->form, 1, "Font Specification",
1141 "Invalid Font Specification", "Dismiss");
1146 /* loads selected font and displays sample text in that font */
1148 static void dispSample(xfselControlBlkType *ctrlBlk)
1150 XFontStruct *font;
1151 XmFontList fontList;
1152 Display *display;
1154 display = XtDisplay(ctrlBlk->form);
1155 font = XLoadQueryFont(display, ctrlBlk->fontName);
1156 fontList = XmFontListCreate(font, XmSTRING_DEFAULT_CHARSET);
1158 enableSample(ctrlBlk, True, &fontList);
1160 if (ctrlBlk->oldFont != NULL)
1162 XFreeFont(display, ctrlBlk->oldFont);
1163 XmFontListFree(ctrlBlk->oldFontList);
1165 ctrlBlk->oldFont = font;
1166 ctrlBlk->oldFontList = fontList;
1170 static void destroyCB(Widget widget, xfselControlBlkType *ctrlBlk,
1171 XmListCallbackStruct *call_data)
1173 /* Prevent double destruction of the font selection dialog */
1174 ctrlBlk->destroyedFlag = TRUE;
1175 cancelAction(widget, ctrlBlk, call_data);
1178 static void cancelAction(Widget widget, xfselControlBlkType *ctrlBlk,
1179 XmListCallbackStruct *call_data)
1181 if (ctrlBlk->sel1 != NULL)
1182 XtFree(ctrlBlk->sel1);
1183 if (ctrlBlk->sel2 != NULL)
1184 XtFree(ctrlBlk->sel2);
1185 if (ctrlBlk->sel3 != NULL)
1186 XtFree(ctrlBlk->sel3);
1187 if (ctrlBlk->fontName != NULL)
1188 XtFree(ctrlBlk->fontName);
1190 ctrlBlk->fontName = NULL;
1191 XFreeFontNames(ctrlBlk->fontData);
1193 ctrlBlk->exitFlag = TRUE;
1197 static void okAction(Widget widget, xfselControlBlkType *ctrlBlk,
1198 XmPushButtonCallbackStruct *call_data)
1200 char *fontPattern;
1201 char **fontName;
1202 int i;
1204 fontPattern = XmTextGetString(ctrlBlk->fontNameField);
1205 fontName = XListFonts(XtDisplay(ctrlBlk->form), fontPattern, 1, &i);
1206 XtFree(fontPattern);
1208 if (i != 1)
1210 DialogF (DF_ERR, ctrlBlk->okButton, 1, "Font Specification",
1211 "Invalid Font Specification", "Dismiss");
1212 XFreeFontNames(fontName);
1214 else
1216 if (ctrlBlk->fontName != NULL)
1217 XtFree(ctrlBlk->fontName);
1218 ctrlBlk->fontName = XtMalloc(strlen(fontName[0]) + 1);
1219 strcpy(ctrlBlk->fontName, fontName[0]);
1221 if (ctrlBlk->sel1 != NULL)
1222 XtFree(ctrlBlk->sel1);
1223 if (ctrlBlk->sel2 != NULL)
1224 XtFree(ctrlBlk->sel2);
1225 if (ctrlBlk->sel3 != NULL)
1226 XtFree(ctrlBlk->sel3);
1228 XFreeFontNames(fontName);
1229 XFreeFontNames(ctrlBlk->fontData);
1231 ctrlBlk->exitFlag = TRUE;
1236 /* if current font is passed as an argument then this function is
1237 invoked and sets up initial entries */
1239 static void startupFont(xfselControlBlkType *ctrlBlk, const char *font)
1241 int i;
1242 char **fontName;
1243 char part[TEMP_BUF_SIZE];
1244 XmString str;
1246 fontName = XListFonts(XtDisplay(ctrlBlk->form), font, 1, &i);
1248 if (i == 0)
1249 { /* invalid font passed in at startup */
1250 XFreeFontNames(fontName);
1251 return;
1254 ctrlBlk->fontName = XtMalloc(strlen(fontName[0]) + 1);
1255 strcpy(ctrlBlk->fontName, fontName[0]);
1257 getFontPart(fontName[0], part);
1258 XFreeFontNames(fontName);
1259 str = XmStringCreate(part, XmSTRING_DEFAULT_CHARSET);
1260 XmListSetBottomItem(ctrlBlk->fontList, str);
1261 XmListSelectItem(ctrlBlk->fontList, str, TRUE);
1262 XmListSelectItem(ctrlBlk->fontList, str, TRUE);
1263 XmStringFree(str);
1265 dispSample(ctrlBlk);
1266 XmTextSetString(ctrlBlk->fontNameField, ctrlBlk->fontName);
1270 /* hacked code to move initial input focus to first scroll list and at the
1271 same time have the OK button as the default button */
1273 static void setFocus(Widget w, xfselControlBlkType *ctrlBlk, XEvent *event,
1274 Boolean *continueToDispatch)
1276 int n;
1277 Arg args[2];
1279 *continueToDispatch = TRUE;
1281 n = 0;
1282 XtSetArg(args[n], XmNdefaultButton, ctrlBlk->okButton); n++;
1283 XtSetValues(ctrlBlk->form, args, n);
1287 /* finds the name of the biggest font less than the given limit
1288 MAX_DISPLAY_SIZE used to set up the initial height of the display widget
1291 static void FindBigFont(xfselControlBlkType *ctrlBlk, char *bigFont)
1293 int i, maxSize, ind = -1, size;
1294 char sizeStr[10];
1296 for (i = 0, maxSize = 0; i < ctrlBlk->numFonts; i++)
1298 getStringComponent(ctrlBlk->fontData[i], 7, sizeStr);
1299 size = atoi(sizeStr);
1300 if ((size > maxSize) && (size < MAX_DISPLAY_SIZE))
1302 ind = i;
1303 maxSize = size;
1306 if (ind >= 0) {
1307 strcpy(bigFont, ctrlBlk->fontData[ind]);
1309 else {
1310 bigFont[0] = 0;