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