/*
* Motif
*
* Copyright (c) 1987-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these librararies and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*
*/
#define dbg() fprintf(stderr, "file: %s - XtWidgetToApplicationContext() on line: %d\n", __FILE__, __LINE__);
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h> /* May have to be strings.h on some systems. */
#include <Xm/Xm.h>
#include <Xm/FontSP.h>
#include <Xm/Label.h>
#include <Xm/PushB.h>
#include <Xm/RowColumn.h>
#include <Xm/TextF.h>
#include <Xm/Text.h>
#include <Xm/ToggleB.h>
#include <Xm/MenuShell.h>
#include <Xm/DropDown.h>
#include <Xm/ButtonBox.h>
#include <Xm/ExtP.h>
#include "Xm/XmI.h"
#define NUM_XLFD_DASHES 14
/* max number of fonts that can be returned (CARD16) */
#define TRY_FONTS (unsigned int) 65535
#define NUM_BUTTONS 30 /* The MAX number of encoding buttons. */
#define ANY_FAMILY 0 /* Don't change this, without fixing */
/* ProcessXldfFontData */
#define GET_FONT_SIZE BUFSIZ
#define ALLOC_INC 100
#define FAMILY_INC 10
#define WIDGET_LIST_INC 10
#define POINT_DIVIDE 10
#define DEFAULT_WEIGHT ("medium")
#define BOLD_WEIGHT ("bold")
#define DEFAULT_SLANT ("r")
#define ITALIC_SLANT ("i")
#define DEFAULT_FIXED_SPACING ("c")
#define OTHER_FIXED_SPACING ("m")
#define PROPORTIONAL_SPACING ("p")
#define STAR_STRING ("*")
#define ANY_ENCODING ("*-*")
#define FAMILY_COLUMNS 20
#define VISIBILE_FAMILIES 11
static short GValidSizes[] = {
2, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,22,23,24,26,28,36,48,72
};
/*
* A font may only be scaled in one resolution, not all resolutions.
*/
#define IsScaled(fsw, fam) (XmFontS_use_scaling((fsw)) && \
((CheckFlag(XmFontS_user_state((fsw)), DPI_75) && \
CheckFlag((fam)->state, SCALED_75)) || \
(CheckFlag(XmFontS_user_state((fsw)), DPI_100)&& \
CheckFlag((fam)->state, SCALED_100))))
/************************************************************
* GLOBAL DECLARATIONS
************************************************************/
/************************************************************
* Private functions - for creating children widgets.
************************************************************/
static void CreateChildren(XmFontSelectorWidget, ArgList, Cardinal);
static void CreateTopWidgets(XmFontSelectorWidget, Widget, ArgList, Cardinal);
static void CreateMiddleArea(XmFontSelectorWidget, ArgList, Cardinal);
static void CreateSpacingBox(XmFontSelectorWidget, Widget, ArgList, Cardinal);
static void CreateFontChoiceBox(XmFontSelectorWidget, Widget,ArgList,Cardinal);
static void CreateResolutionBox(XmFontSelectorWidget, Widget,ArgList,Cardinal);
static void CreateFamilyBox(XmFontSelectorWidget, Widget, ArgList, Cardinal);
static void CreateSizesBox(XmFontSelectorWidget, Widget, ArgList, Cardinal);
static void CreateBoldItalicBox(XmFontSelectorWidget,Widget,ArgList, Cardinal);
static void CreateOtherChoiceBox(XmFontSelectorWidget,
Widget, ArgList, Cardinal);
/************************************************************
* Private functions.
************************************************************/
static void LoadFontData(Widget, FontData **, int *, String **, int *);
static void ProcessXlfdFontData(XmFontSelectorWidget,
FontInfo *, FontData *, int);
static void SortOtherFontData(FontInfo *, String *, int);
static void AddToOtherList(char *, String **, int *, int *);
static void SetNonStringData(FontData *), SetFlag(Flag *, Flag, Boolean);
static void StoreString(register String, register String, register int);
static void SetLongFlag(LongFlag *, LongFlag, Boolean);
static void UpdateExistingFamily(FamilyInfo *, FontData *);
static void FillNewFamily(FamilyInfo *, FontData *);
static void SetResolution(XmFontSelectorWidget, FontData *);
static void DisplayCurrentFont(XmFontSelectorWidget, String);
static void UpdateBoldItalic(XmFontSelectorWidget);
static void UpdateFixedProportional(XmFontSelectorWidget);
static void UpdateFamilies(XmFontSelectorWidget);
static void UpdateSizes(XmFontSelectorWidget);
static void SetComboValue(Widget, String), UnsetSiblings(Widget);
static void DisplayUserError(XmFontSelectorWidget, String);
static void SetDisplayedFont(XmFontSelectorWidget, String);
static void AddToXlfdOnlyList(XmFontSelectorWidget, Widget);
static void AddToXlfdSensitiveList(XmFontSelectorWidget, Widget);
static void ChangeMode(XmFontSelectorWidget, Boolean, Boolean);
static void SetOtherList(XmFontSelectorWidget, Boolean);
static void AddToXlfdList(XmFontSelectorWidget,
char *, FontData **, int *, int *);
static Widget CreateEncodingMenu(XmFontSelectorWidget,
Widget, ArgList, Cardinal);
static FontInfo * LoadFontInfo(XmFontSelectorWidget);
static int FindResolution(Widget), CmpStrings(const void *, const void *);
static Boolean CheckFlag(Flag, Flag), CheckLongFlag(LongFlag, LongFlag);
static Boolean FillData(XmFontSelectorWidget, FontData *, char *);
static Boolean IsXlfdFont(register char *);
static Boolean CheckEncoding(XmFontSelectorWidget, FamilyInfo *);
static FamilyInfo *FindFamily(register XrmQuark, FamilyInfo *, int);
static String BuildFontString(XmFontSelectorWidget, FontData *, String, int);
static LongFlag SizeMapping(short);
/************************************************************
* Callbacks
************************************************************/
static void ToggleMiddlePane(Widget, XtPointer, XtPointer);
static void ToggleNameWindow(Widget, XtPointer, XtPointer);
static void FamilyChanged(Widget, XtPointer, XtPointer);
static void SizeChanged(Widget, XtPointer, XtPointer);
static void ChangeEncoding(Widget, XtPointer, XtPointer);
static void ToggleScaling(Widget, XtPointer, XtPointer);
static void ToggleBold(Widget, XtPointer, XtPointer);
static void ToggleItalic(Widget, XtPointer, XtPointer);
static void Toggle75DPI(Widget, XtPointer, XtPointer);
static void Toggle100DPI(Widget, XtPointer, XtPointer);
static void ToggleBothDPI(Widget, XtPointer, XtPointer);
static void ToggleProportional(Widget, XtPointer, XtPointer);
static void ToggleFixed(Widget, XtPointer, XtPointer);
static void ToggleBothSpacing(Widget, XtPointer, XtPointer);
static void XlfdMode(Widget, XtPointer, XtPointer);
static void OtherMode(Widget, XtPointer, XtPointer);
static void RemoveUserError(Widget, XtPointer, XtPointer);
/************************************************************
* Semi-Public functions
************************************************************/
static Boolean SetValues(Widget, Widget, Widget, ArgList, Cardinal *);
static void GetValuesHook(Widget, ArgList, Cardinal *);
static void Destroy(Widget);
static void Initialize(Widget, Widget, ArgList, Cardinal*);
static void ClassPartInitialize(WidgetClass w_class);
static void ClassInitialize();
/* Resource definitions for Subclasses of Primitive */
#define SAMPLE \
("abcdefghijklmonpqrstuvwxyz\n\
ABCDEFGHIJKLMONPQRSTUVWXYZ\n\
1234567890\n!@#$%^&*()")
/************************************************************
* STATIC DECLARATIONS
************************************************************/
/*
* This table is the list of resolutions of fonts that are supported.
* most machines have only 75 and 100 dpi fonts, so we only find which
* of those we are closest to with FindResolution().
*/
static int resolutions[] = { 75, 100 };
static XtResource resources[] =
{
{
XmNspacing, XmCSpacing, XmRVerticalDimension,
sizeof(Dimension), XtOffsetOf(XmPanedRec, paned.internal_bw),
XmRImmediate, (XtPointer) 2
},
{
XmNseparatorOn, XmCSeparatorOn, XmRBoolean,
sizeof(Boolean), XtOffsetOf(XmPanedRec, paned.separator_on),
XmRImmediate, (XtPointer) True
},
{
XmNmarginHeight, XmCMargin, XmRVerticalDimension,
sizeof(Dimension), XtOffsetOf(XmPanedRec, paned.margin_height),
XmRImmediate, (XtPointer) 0
},
{
XmNcurrentFont, XmCString, XmRString,
sizeof(String), XtOffsetOf(XmFontSelectorRec, fs.current_font),
XmRImmediate, (XtPointer)NULL
},
{
XmNshowFontName, XmCBoolean, XmRBoolean,
sizeof(Boolean), XtOffsetOf(XmFontSelectorRec, fs.show_font_name),
XmRImmediate, (XtPointer) False
},
{
XmNuseScaling, XmCBoolean, XmRBoolean,
sizeof(Boolean), XtOffsetOf(XmFontSelectorRec, fs.use_scaling),
XmRImmediate, (XtPointer) True
},
{
XmNtextRows, XmCTextRows, XmRDimension,
sizeof(Dimension), XtOffsetOf(XmFontSelectorRec, fs.text_rows),
XmRImmediate, (XtPointer) 8
},
{
XmNvalueChangedCallback, XmCCallback, XmRCallback,
sizeof(XtCallbackList), XtOffsetOf(XmFontSelectorRec, fs.font_changed_callback),
XmRImmediate, (XtPointer) NULL
},
{
XmNsampleText, XmCSampleText, XmRXmString,
sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.sample_text),
XmRString, (XtPointer) SAMPLE
},
{
XmNanyString, XmCAnyString, XmRXmString,
sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.any),
XmRString, (XtPointer) "Any"
},
{
XmNanyLowerString, XmCAnyLowerString, XmRXmString,
sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.lower_any),
XmRString, (XtPointer) "any"
},
{
XmNfamilyString, XmCFamilyString, XmRXmString,
sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.family),
XmRString, (XtPointer) "Family"
},
{
XmNsizeString, XmCSizeString, XmRXmString,
sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.size),
XmRString, (XtPointer) "Size"
},
{
XmNboldString, XmCBoldString, XmRXmString,
sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.bold),
XmRString, (XtPointer) "Bold"
},
{
XmNitalicString, XmCItalicString, XmRXmString,
sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.italic),
XmRString, (XtPointer) "Italic"
},
{
XmNoptionString, XmCOptionString, XmRXmString,
sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.option),
XmRString, (XtPointer) "Options..."
},
{
XmNbothString, XmCBothString, XmRXmString,
sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.both),
XmRString, (XtPointer) "Both"
},
{
XmNmonoSpaceString, XmCMonoSpaceString, XmRXmString,
sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.mono_space),
XmRString, (XtPointer) "Fixed Width Fonts"
},
{
XmNpropSpaceString, XmCPropSpaceString, XmRXmString,
sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.prop_space),
XmRString, (XtPointer) "Proportional Fonts"
},
{
XmNotherString, XmCOtherString, XmRXmString,
sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.other_font),
XmRString, (XtPointer) "Other Fonts"
},
{
XmNxlfdString, XmCXlfdSpaceString, XmRXmString,
sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.xlfd),
XmRString, (XtPointer) "Xlfd Fonts"
},
{
XmN75DPIstring, XmC75DPIString, XmRXmString,
sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.dpi_75),
XmRString, (XtPointer) "75 dpi"
},
{
XmN100DPIstring, XmC100DPIString, XmRXmString,
sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.dpi_100),
XmRString, (XtPointer) "100 dpi"
},
{
XmNscalingString, XmCScalingString, XmRXmString,
sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.scaling),
XmRString, (XtPointer) "Use Font Scaling"
},
{
XmNshowNameString, XmCShowNameString, XmRXmString,
sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.show_name),
XmRString, (XtPointer) "Show Font Name"
},
/*
* Stuff to set the valid charset/encoding pairs.
*/
{
XmNencodingString, XmCEncodingString, XmRXmString,
sizeof(XmString), XtOffsetOf(XmFontSelectorRec, fs.strings.encoding_only),
XmRString, (XtPointer) "Encoding"
},
/*
* NOTE: This resource value must end in a comma because the resource
* converter is broken in Motif1.1.4.
*/
{
XmNencodingList, XmCEncodingList, XmRStringTable,
sizeof(String *), XtOffsetOf(XmFontSelectorRec, fs.strings.encoding_list),
XmRString, (XtPointer) "iso8859-1,"
},
{
XmNdefaultEncodingString, XmCDefaultEncodingString, XmRString,
sizeof(String), XtOffsetOf(XmFontSelectorRec, fs.encoding),
XmRString, (XtPointer) "iso8859-1"
}
};
static XmSyntheticResource syn_resources[] =
{
{
XmNspacing, sizeof(Dimension),
XtOffsetOf(XmPanedRec, paned.internal_bw),
_XmFromPanedPixels, (XmImportProc) _XmToPanedPixels
},
{
XmNmarginHeight, sizeof(Dimension),
XtOffsetOf(XmPanedRec, paned.margin_height),
XmeFromVerticalPixels, (XmImportProc) XmeToVerticalPixels
}
};
static XtResource subresources[] =
{
{
XmNshowSash, XmCShowSash, XmRBoolean,
sizeof(Boolean), XtOffsetOf(XmPanedConstraintsRec, paned.show_sash),
XmRImmediate, (XtPointer) False
}
};
#define SuperClass ((ConstraintWidgetClass) &xmPanedClassRec)
XmFontSelectorClassRec xmFontSelectorClassRec = {
{
/* core class fields */
/* superclass */ (WidgetClass) SuperClass,
/* class name */ "XmFontSelector",
/* size */ sizeof(XmFontSelectorRec),
/* class_initialize */ ClassInitialize,
/* class_part init */ ClassPartInitialize,
/* class_inited */ FALSE,
/* initialize */ Initialize,
/* initialize_hook */ NULL,
/* realize */ XtInheritRealize,
/* actions */ NULL,
/* num_actions */ 0,
/* resources */ (XtResourceList)resources,
/* resource_count */ XtNumber(resources),
/* xrm_class */ NULLQUARK,
/* compress_motion */ TRUE,
/* compress_exposure */ TRUE,
/* compress_enterleave*/ TRUE,
/* visible_interest */ FALSE,
/* destroy */ Destroy,
/* resize */ XtInheritResize,
/* expose */ NULL,
/* set_values */ SetValues,
/* set_values_hook */ NULL,
/* set_values_almost */ XtInheritSetValuesAlmost,
/* get_values_hook */ GetValuesHook,
/* accept_focus */ NULL,
/* version */ XtVersion,
/* callback_private */ NULL,
/* tm_table */ XtInheritTranslations,
/* query_geometry */ XtInheritQueryGeometry,
/* display_accelerator*/ XtInheritDisplayAccelerator,
/* extension */ NULL
}, {
/* composite class fields */
/* geometry_manager */ XtInheritGeometryManager,
/* change_managed */ XtInheritChangeManaged,
/* insert_child */ XtInheritInsertChild,
/* delete_child */ XtInheritDeleteChild,
/* extension */ NULL
}, {
/* constraint class fields */
/* subresources */ subresources,
/* subresource_count */ XtNumber(subresources),
/* constraint_size */ sizeof(XmFontSelectorConstraintsRec),
/* initialize */ NULL,
/* destroy */ NULL,
/* set_values */ NULL,
/* extension */ NULL
}, {
/* manager_class fields */
XtInheritTranslations, /* translations */
syn_resources, /* get resources */
XtNumber(syn_resources), /* num get_resources */
NULL, /* get_cont_resources */
0, /* num_get_cont_resources */
XmInheritParentProcess, /* parent_process */
NULL, /* extension */
}, {
/* paned_class fields */
NULL, /* extension */
}, {
/* font selector class fields */
NULL, /* extension */
}
};
WidgetClass xmFontSelectorWidgetClass = (WidgetClass) &xmFontSelectorClassRec;
/***********************************************************
*
* Private Functions.
*
************************************************************/
/* Function Name: LoadFontInfo
* Description: Loads the font information from the current screen.
* Arguments: fsw - the font selector widget.
* Returns: the font information.
*/
static FontInfo *
LoadFontInfo(XmFontSelectorWidget fsw)
{
FontInfo *font_info = (FontInfo *) XtMalloc(sizeof(FontInfo));
FontData *xlfd_font_data;
String *other_fonts;
int xlfd_num_fonts, other_num_fonts;
font_info->resolution = FindResolution((Widget) fsw);
LoadFontData((Widget) fsw, &xlfd_font_data, &xlfd_num_fonts,
&other_fonts, &other_num_fonts);
ProcessXlfdFontData(fsw, font_info, xlfd_font_data, xlfd_num_fonts);
SortOtherFontData(font_info, other_fonts, other_num_fonts);
return(font_info);
}
/* Function Name: LoadFontData
* Description: Loads the font data from the X Server, sorts it into
* xlfd and non xlfd fonts, and sorts out the xlfd info.
* Arguments: w - any widget on the screen.
* RETURNED xlfd_data, num_xlfd - The xlfd font data.
* RETURNED other_fonts, num_other - The list of non xlfd fonts.
* Returns: none.
*/
static void
LoadFontData(Widget w, FontData **xlfd_data, int *num_xlfd,
String **other_fonts, int *num_other)
{
XmFontSelectorWidget fsw = (XmFontSelectorWidget) w;
char ** fonts, **ptr;
int i, num, xlfd_alloc, other_alloc;
*xlfd_data = NULL;
*other_fonts = NULL;
*num_xlfd = *num_other = xlfd_alloc = other_alloc = 0;
fonts = XListFonts(XtDisplay(w), "*", TRY_FONTS, &num);
/*
* Loop the all the fonts and add each one to the proper list.
*/
if (fonts != NULL) {
for (ptr = fonts, i = 0; i < num; i++, ptr++) {
if (IsXlfdFont(*ptr))
AddToXlfdList(fsw, *ptr, xlfd_data, num_xlfd, &xlfd_alloc);
else
AddToOtherList(*ptr, other_fonts, num_other, &other_alloc);
}
XFreeFontNames(fonts);
}
}
/* Function Name: ProcessXlfdFontData
* Description: Processes the Xlfd data, to come up with lists
* of various attributes.
* Arguments: fsw - The Font Selector Widget.
* font_info - the font information structure.
* data, num - the xlfd data.
* Returns: none.
*
* This takes the raw XLFD data and builds lists of families and
* sizes, and stores all the information in the font_info structure.
*/
static void
ProcessXlfdFontData(XmFontSelectorWidget fsw,
FontInfo *font_info, FontData *data, int num_data)
{
int num, alloc, i;
FamilyInfo *any_fam, *fam = NULL;
FontData *top = data;
String temp;
/*
* Leave space for the any family, filled in at the end of the function.
*
* NOTE: This assumes that (ANY_FAMILY == 0)
*/
num = 1;
alloc = FAMILY_INC;
fam = (FamilyInfo *) XtMalloc(sizeof(FamilyInfo) * alloc);
fam->nameq = NULLQUARK; /* Don't use this family yet. */
/*
* Set up the "Any" family.
*/
for (i = 0; i < num_data; i++, data++) {
register FamilyInfo *cur_family = FindFamily(data->familyq, fam, num);
if (cur_family == NULL) {
if ( num >= alloc ) {
alloc += FAMILY_INC;
fam = (FamilyInfo *) XtRealloc((XtPointer) fam,
sizeof(FamilyInfo) * alloc);
}
FillNewFamily(fam + num, data);
num++;
}
else {
UpdateExistingFamily(cur_family, data);
}
}
font_info->family_info = fam;
font_info->num_families = num;
any_fam = fam + ANY_FAMILY;
temp = _XmGetMBStringFromXmString(ANY_STRING(fsw));
any_fam->nameq = XrmStringToQuark(temp);
XtFree(temp);
any_fam->bold_nameq = XrmStringToQuark(BOLD_WEIGHT);
any_fam->medium_nameq = XrmStringToQuark(DEFAULT_WEIGHT);
any_fam->upright_nameq = XrmStringToQuark(DEFAULT_SLANT);
any_fam->italic_nameq = XrmStringToQuark(ITALIC_SLANT);
strcpy(any_fam->fixed_spacing, DEFAULT_FIXED_SPACING);
any_fam->state = (Flag) 0;
any_fam->sizes_75 = any_fam->sizes_100 = (LongFlag) 0;
for (i = 1, fam++; i < num; i++, fam++) {
any_fam->sizes_75 |= fam->sizes_75;
any_fam->sizes_100 |= fam->sizes_100;
any_fam->state |= fam->state;
}
any_fam->encodings = NULL;
any_fam->encoding_alloc = 0;
XtFree((XtPointer) top);
}
/* Function Name: SortOtherFonts
* Description: Sorts the list of other fonts alphabetically
* and stuffs them into the font data structure.
* Arguments: font_info - the font information.
* list, num - the list of fonts.
* Returns: none
*/
static void
SortOtherFontData(FontInfo *font_info, String *list, int num)
{
register int i = 0;
qsort((void *) list, num, sizeof(String), CmpStrings);
/*
* Remove duplicates.
*/
while (i < (num - 1)) {
if (streq(list[i], list[i+1])) {
register int j;
register String *ptr;
XtFree((char*)list[i]);
ptr = list + i;
j = i;
while ( ++j < num) {
ptr[0] = ptr[1];
ptr++;
}
num--; /*Something has been removed, decrement count*/
}
else
i++;
}
font_info->others = list;
font_info->num_others = num;
}
/* Function Name: CmpStrings
* Description: Compares two strings.
* Arguments: p1, p2 - two string pointers.
* Returns: none
*/
static int
CmpStrings(const void * p1, const void *p2)
{
String *s1 = (String *) p1;
String *s2 = (String *) p2;
return(strcmp(*s1, *s2));
}
/* Function Name: FindResolution
* Description: Finds the closest resolution
* Arguments: w - any widget on the proper screen.
* Returns: the closest allowable resolution to the real resolution.
*/
static int
FindResolution(Widget w)
{
Screen *screen = XtScreen(w);
register int i, xres, yres, min, pref;
/*
* there are 2.54 centimeters to an inch; so there are 25.4 millimeters.
*
* dpi = N pixels / (M millimeters / (25.4 millimeters / 1 inch))
* = N pixels / (M inch / 25.4)
* = N * 25.4 pixels / M inch
*
* Or in integer arithmitic
*
* = (254 * N pixels / M inch + 5) / 10
*/
/* This will get us the true pixels / inch. That is probably
not what we want */
xres = (254 * WidthOfScreen(screen) / WidthMMOfScreen(screen) + 5) / 10;
yres = (254 * HeightOfScreen(screen) / HeightMMOfScreen(screen) + 5) / 10;
xres *= xres;
yres *= yres;
/*
* Find the closest resolution by using a difference of squares.
*/
min = 32000;
pref = resolutions[0]; /* We have to have some default. */
for (i = 0; i < XtNumber(resolutions); i++) {
int diffx = (xres - resolutions[i] * resolutions[i]);
int diffy = (yres - resolutions[i] * resolutions[i]);
int tdiff; /* the total difference. */
/*
* Square 'em.
*/
tdiff = (diffx * diffx) + (diffy * diffy);
if (min > tdiff) {
pref = resolutions[i];
min = tdiff;
}
}
return(pref);
}
/* Function Name: IsXlfdFont
* Description: Returns True if this is an LXFD font.
* Arguments: str - the font name to check.
* Returns: none.
*/
static Boolean
IsXlfdFont(register char * str)
{
register int num_dashes = 0;
register char c;
for ( ; (c = *str) != '\0'; str++) {
if (c == '-')
num_dashes++;
}
return(num_dashes == NUM_XLFD_DASHES);
}
/* Function Name: AddToXlfdList
* Description: Adds a font to the list of xlfd fonts.
* Arguments: name - name of the font.
* list, num - the list of xlfd fonts to add it to.
* alloc - the number of allocated slots.
* Returns: none.
*/
static void
AddToXlfdList(XmFontSelectorWidget fsw,
char *name, FontData **list, int *num, int *alloc)
{
FontData *current;
if (*num >= *alloc) {
*alloc += ALLOC_INC;
*list = (FontData *) XtRealloc((XtPointer) *list,
sizeof(FontData) * *alloc);
}
current = (*list) + *num;
/*
* If filling the data succeeded, then accept this name, otherwise
* just ignore it.
*/
if (FillData(fsw, current, name))
(*num)++;
}
/* Function Name: AddToOtherList
* Description: Adds a font to the list of other fonts.
* Arguments: name - name of the font.
* list, num - the list of other fonts to add it to.
* alloc - the number of allocated slots.
* Returns: none.
*/
static void
AddToOtherList(char *name, String **list, int *num, int *alloc)
{
if (*num >= *alloc) {
*alloc += ALLOC_INC;
*list = (String *) XtRealloc((XtPointer) *list,
sizeof(String) * *alloc);
}
(*list)[(*num)++] = XtNewString(name);
}
/* Function Name: FillData(fsw, current, name);
* Description: Fills the current font data from an xlfd name.
* Arguments: fsw - The font selector widget.
* current - the font data structure to fill.
* name - an xlfd name of a font.
* Returns: False on failure.
*
* This name may have NOT *'s in it.
*/
#define GET_NEXT_FIELD(ptr) \
if (((ptr) = (char *) strchr((ptr), '-')) == NULL) \
return(False); \
(ptr)++ /* skip hyphen */ \
static Boolean
FillData(XmFontSelectorWidget fsw, FontData *current, char *name)
{
char *ptr = name;
char temp[BUFSIZ];
current->state = 0; /* Initialize value. */
GET_NEXT_FIELD(ptr); /* ptr == Foundry */
GET_NEXT_FIELD(ptr); /* ptr == Family */
StoreString(ptr, temp, BUFSIZ - 1);
if (streq(temp, STAR_STRING)) {
String str = _XmGetMBStringFromXmString(ANY_STRING(fsw));
strcpy(temp, str);
XtFree((XtPointer) str);
}
current->familyq = XrmStringToQuark(temp);
GET_NEXT_FIELD(ptr); /* ptr == Weight */
StoreString(ptr, temp, BUFSIZ - 1);
current->weightq = XrmStringToQuark(temp);
GET_NEXT_FIELD(ptr); /* ptr == Slant */
StoreString(ptr, current->slant, SLANT_LEN);
GET_NEXT_FIELD(ptr); /* ptr == SetWidth_Name */
GET_NEXT_FIELD(ptr); /* ptr == Add_Style_Name */
GET_NEXT_FIELD(ptr); /* ptr == Pixel Size */
GET_NEXT_FIELD(ptr); /* ptr == Point Size */
StoreString(ptr, temp, BUFSIZ - 1);
/*
* the string '*' will default to 0 which is exactly what I want.
*/
current->point_size = (short) atoi(temp);
GET_NEXT_FIELD(ptr); /* ptr == Resolution X */
StoreString(ptr, temp, BUFSIZ - 1);
/*
* the string '*' will default to 0 which is exactly what I want.
*/
current->resolution_x = (short) atoi(temp);
GET_NEXT_FIELD(ptr); /* ptr == Resolution Y */
StoreString(ptr, temp, BUFSIZ - 1);
/*
* the string '*' will default to 0 which is exactly what I want.
*/
current->resolution_y = (short) atoi(temp);
GET_NEXT_FIELD(ptr); /* ptr == Spacing */
StoreString(ptr, current->spacing, SPACING_LEN);
GET_NEXT_FIELD(ptr); /* ptr == Average Width */
GET_NEXT_FIELD(ptr); /* ptr == Registry and Encoding */
current->encoding = XrmStringToQuark(ptr);
SetNonStringData(current);
return(True); /* success! */
}
#undef GET_NEXT_FIELD
/* Function Name: SetNonStringData
* Description: Sets the non string part of the Font Data.
* Arguments: current - the font data we are working with.
* Returns: none.
*/
static void
SetNonStringData(FontData *current)
{
char lower[BUFSIZ];
/*
* Now fill in the non string fields.
*/
/*
* If the weight_name field contains the words "bold" or "demi"
* then this is a bold font.
*/
XmCopyISOLatin1Lowered(lower, XrmQuarkToString(current->weightq));
if ((strstr(lower, "bold") != NULL) || (strstr(lower, "demi") != NULL))
SetFlag(&(current->state), BOLD, True);
/*
* If the spacing is "p" then proportional, otherwize monospaced.
*/
XmCopyISOLatin1Lowered(lower, current->spacing);
if (strstr(lower, PROPORTIONAL_SPACING) != NULL)
SetFlag(&(current->state), PROPORTIONAL, True);
/*
* If the slant it "i" or "o" then this is an italic font.
*/
XmCopyISOLatin1Lowered(lower, current->slant);
if ((strchr(lower, 'i') != NULL) || (strchr(lower, 'o') != NULL))
SetFlag(&(current->state), ITALIC, True);
/*
* If the point_size is 0 then this is a scalable font.
*/
if (current->point_size == 0) {
if ((current->resolution_x == 75) && (current->resolution_x == 75))
SetFlag(&(current->state), SCALED_75, True);
else if((current->resolution_x == 100)&&(current->resolution_x == 100))
SetFlag(&(current->state), SCALED_100, True);
else if ((current->resolution_x == 0)&& (current->resolution_x == 0)) {
/*
* Sun sets all scaled fonts to have a resolution of 0x0
*/
SetFlag(&(current->state), SCALED_75 | SCALED_100, True);
}
}
/*
* Check to see if resolution matches 75 or 100 dpi.
*/
if ((current->resolution_x == 75) && (current->resolution_x == 75))
SetFlag(&(current->state), DPI_75, True);
else if ((current->resolution_x == 100) && (current->resolution_x == 100))
SetFlag(&(current->state), DPI_100, True);
else if ((current->resolution_x == 0) && (current->resolution_x == 0)) {
/*
* Sun sets all scaled fonts to have a resolution of 0x0
*/
SetFlag(&(current->state), DPI_75 | DPI_100, True);
}
}
/* Function Name: StoreString
* Description: Stores a portion of an xlfd name into the
* string varaible passed.
* Arguments: str - the portion of the string to store.
* store - the string to store it in.
* max_len - maximum length of the value.
* Returns: none.
*/
static void
StoreString(register String str, register String store, register int max_len)
{
register int i;
register int c;
for (i = 0; i < max_len; i++, str++, store++) {
if (((c = *str) == '-') || (c == '\0'))
break;
*store = c;
}
*store = '\0';
}
/* Function Name: CheckFlag
* Description: Checks to see if a flag value is set
* Arguments: state - the state variable containing the flag.
* flag - the location of the flag.
* Returns: True if flag set, False otherwise
*/
static Boolean
CheckFlag(Flag state, Flag flag)
{
return((state & flag) == flag);
}
/* Function Name: CheckLongFlag
* Description: Checks to see if a long flag value is set
* Arguments: state - the state variable containing the flag.
* flag - the location of the flag.
* Returns: True if flag set, False otherwise
*/
static Boolean
CheckLongFlag(LongFlag state, LongFlag flag)
{
return((state & flag) == flag);
}
/* Function Name: SetFlag
* Description: Sets a flag value
* Arguments: state - the state variable containing the flag.
* flag - the location of the flag.
* value - the value of the flag.
* Returns: none.
*/
static void
SetFlag(Flag *state, Flag flag, Boolean value)
{
if (value)
*state |= flag;
else
*state &= ~flag;
}
/* Function Name: SetLongFlag
* Description: Sets a flag value that is stored in a long
* Arguments: state - the state variable containing the flag.
* flag - the location of the flag.
* value - the value of the flag.
* Returns: none.
*/
static void
SetLongFlag(LongFlag *state, LongFlag flag, Boolean value)
{
if (value)
*state |= flag;
else
*state &= ~flag;
}
/* Function Name: FindFamily
* Description: Finds family associated with the font passed.
* Arguments: font - the font data.
* list - the list of all families
* num - the number of families.
* Returns: a pointer to the family this font is in or NULL.
*
*/
static FamilyInfo *
FindFamily(register XrmQuark nameq, FamilyInfo *list, int num)
{
register int i;
for (i = 0; i < num; i++, list++) {
if (list->nameq == nameq)
return(list);
}
return(NULL);
}
/* Function Name: UpdateExistingFamily
* Description: Updates data, by adding another font to an
* existion family.
* Arguments: fam - the family to update.
* font - the font to add.
* Returns: none.
*/
static void
UpdateExistingFamily(FamilyInfo *fam, FontData *font)
{
int i;
if (CheckFlag(font->state, BOLD))
fam->bold_nameq = font->weightq;
else
fam->medium_nameq = font->weightq;
if (CheckFlag(font->state, ITALIC))
fam->italic_nameq = XrmStringToQuark(font->slant);
else
fam->upright_nameq = XrmStringToQuark(font->slant);
if (!streq(font->spacing, PROPORTIONAL_SPACING))
strcpy(fam->fixed_spacing, font->spacing);
if (font->point_size != 0) {
if ((font->resolution_x == 75) && (font->resolution_x == 75))
SetLongFlag(&(fam->sizes_75), SizeMapping(font->point_size), True);
else if ((font->resolution_x == 100) && (font->resolution_x == 100))
SetLongFlag(&(fam->sizes_100),SizeMapping(font->point_size), True);
}
fam->state |= font->state; /* or in all bits. */
for (i = 0; TRUE; i++)
{
if (i == fam->encoding_alloc)
{
fam->encoding_alloc += NUM_BUTTONS;
fam->encodings =
(XrmQuark *) XtRealloc((char *) fam->encodings,
sizeof(XrmQuark) * fam->encoding_alloc);
memset((char *) (fam->encodings + i), 0,
sizeof(XrmQuark) * NUM_BUTTONS);
}
if (fam->encodings[i] == font->encoding)
return;
if (fam->encodings[i] == 0)
{
fam->encodings[i] = font->encoding;
return;
}
}
}
/* Function Name: FillNewFamily
* Description: Fills in the information for a new font family.
* Arguments: fam - the family data.
* font - the first font we found.
* Returns: none.
*/
static void
FillNewFamily(FamilyInfo *fam, FontData *font)
{
fam->nameq = font->familyq;
if (CheckFlag(font->state, BOLD)) {
fam->bold_nameq = font->weightq;
fam->medium_nameq = NULLQUARK;
}
else {
fam->bold_nameq = NULLQUARK;
fam->medium_nameq = font->weightq;
}
if (streq(font->spacing, PROPORTIONAL_SPACING))
strcpy(fam->fixed_spacing, DEFAULT_FIXED_SPACING);
else
strcpy(fam->fixed_spacing, font->spacing);
if (CheckFlag(font->state, ITALIC)) {
fam->italic_nameq = XrmStringToQuark(font->slant);
fam->upright_nameq = NULLQUARK;
}
else {
fam->italic_nameq = NULLQUARK;
fam->upright_nameq = XrmStringToQuark(font->slant);
}
fam->sizes_75 = fam->sizes_100 = 0;
fam->state = font->state;
if (font->point_size != 0) {
if ((font->resolution_x == 75) && (font->resolution_x == 75))
SetLongFlag(&(fam->sizes_75), SizeMapping(font->point_size), True);
else if ((font->resolution_x == 100) && (font->resolution_x == 100))
SetLongFlag(&(fam->sizes_100),SizeMapping(font->point_size), True);
}
fam->encoding_alloc = NUM_BUTTONS;
fam->encodings = (XrmQuark *) XtCalloc(fam->encoding_alloc,
sizeof(XrmQuark));
fam->encodings[0] = fam->encoding_alloc;
}
/* Function Name: SizeMapping
* Description: Maps the actual size to the sizes bit field
* Arguments: size - the point size to map.
* Returns: 0 if the size does not map, otherwise the bit it maps to.
*/
static LongFlag
SizeMapping(short size)
{
register int count;
size /= POINT_DIVIDE;
for (count = 0; count < XtNumber(GValidSizes); count++) {
if (GValidSizes[count] == size)
return (((LongFlag) 1) << count);
}
return((LongFlag) 0);
}
/* Function Name: DisplayCurrentFont
* Description: Displays the current font to the user.
* Arguments: fsw - the font selector widget.
* font - the current font name.
* Returns: none.
*/
static void
DisplayCurrentFont(XmFontSelectorWidget fsw, String font)
{
Arg largs[10];
Cardinal num_largs;
XmFontList fl;
XFontStruct *fontdata;
char buf[BUFSIZ * 2];
Boolean err = False;
if ((fontdata = XLoadQueryFont(XtDisplay((Widget) fsw), font)) == NULL)
{
sprintf(buf, "Font '%s'\nis not availiable on this machine", font);
DisplayUserError(fsw, buf);
err = True;
}
else
{
/*
* Always clear out old errors
*/
RemoveUserError(NULL, (XtPointer)fsw, (XtPointer)0);
/*
* This is a hack to work around problems with Sun scaled fonts
* and the Motif Text widget. It turns out that some sun fonts
* when a size of * is specified will return a font of height 0
* this causes the ascent + descent to be zero and really confuses
* the XmTextField widget.
*/
if ((fontdata->ascent + fontdata->descent) == 0) {
if (IsXlfdFont(font)) {
char *ptr, left_buf[BUFSIZ], right_buf[BUFSIZ], fbuf[BUFSIZ];
register int i, count;
/*
* This is a poorly formatted Sun Scaled font,
*
* Find where the size is and change it from a * to 140.
*/
for (ptr = font, i = count = 0; *ptr != 0; i++, ptr++) {
if (*ptr != '-')
continue;
count++;
if (count == 8)
break;
}
ptr = (char *) strchr(ptr + 1, '-');
strcpy(right_buf, ptr);
strcpy(left_buf, font);
left_buf[i] = '\0';
sprintf(fbuf, "%s-140%s", left_buf, right_buf);
if ((fontdata = XLoadQueryFont(XtDisplay((Widget) fsw),
fbuf)) == NULL)
{
sprintf(buf,
"Font '%s'\nis not availiable on this machine",
font);
DisplayUserError(fsw, buf);
err = True;
}
}
else {
sprintf(buf,
"Font '%s'\n%s",
font,
"is is zero pixels high and cannot be displayed.");
DisplayUserError(fsw, buf);
err = True;
}
}
}
if (!err) {
fl = XmFontListCreate(fontdata, XmFONTLIST_DEFAULT_TAG);
num_largs = 0;
XtSetArg(largs[num_largs], XmNfontList, fl); num_largs++;
XtSetValues(XmFontS_text(fsw), largs, num_largs);
if (XmFontS_old_fontdata(fsw) != NULL)
{
XFreeFont(XtDisplay((Widget) fsw), XmFontS_old_fontdata(fsw));
XmFontListFree(XmFontS_old_fontlist(fsw));
}
XmFontS_old_fontdata(fsw) = fontdata;
XmFontS_old_fontlist(fsw) = fl;
}
if (XtIsManaged(XmFontS_name_label(fsw)))
{
XmString xmstr = XmStringCreateLocalized(font);
num_largs = 0;
XtSetArg(largs[num_largs], XmNlabelString, xmstr); num_largs++;
XtSetValues(XmFontS_name_label(fsw), largs, num_largs);
XmStringFree(xmstr);
}
/*
* Fire off the callback for the user.
*/
{
FontData *cf = XmFontS_font_info(fsw)->current_font;
String str_ptr;
if (XmFontS_xlfd_mode(fsw)) {
BuildFontString(fsw, cf, XmFontS_get_font(fsw), GET_FONT_SIZE);
str_ptr = XmFontS_get_font(fsw);
}
else
str_ptr = XrmQuarkToString(cf->familyq);
XtCallCallbackList((Widget) fsw,
XmFontS_font_changed_callback(fsw), (XtPointer)str_ptr);
}
}
/* Function Name: BuildFontString
* Description: Builds a font string from the current font.
* Arguments: fsw - the font selector widget.
* cf - the font data to use.
* buf - where to stuff the font name.
* size - the size not to exceed.
* Returns: the font string (same as buf).
*/
/* ARGSUSED */
static String
BuildFontString(XmFontSelectorWidget fsw, FontData *cf, String buf, int size)
{
static XrmQuark anyquark2, anyquark = NULLQUARK;
String family, encoding;
char res_x[BUFSIZ], res_y[BUFSIZ], point_size[BUFSIZ];
if (anyquark == NULLQUARK) {
String temp1 = _XmGetMBStringFromXmString(ANY_STRING(fsw));
String temp2 = _XmGetMBStringFromXmString(LOWER_ANY_STRING(fsw));
anyquark = XrmStringToQuark(temp1);
anyquark2 = XrmStringToQuark(temp2);
XtFree(temp1);
XtFree(temp2);
}
if ((anyquark == cf->familyq) || (anyquark2 == cf->familyq))
family = STAR_STRING;
else
family = XrmQuarkToString(cf->familyq);
if (cf->point_size == 0)
strcpy(point_size, STAR_STRING);
else
sprintf(point_size, "%d", cf->point_size);
if (cf->resolution_x == 0)
strcpy(res_x, STAR_STRING);
else
sprintf(res_x, "%d", (int) cf->resolution_x);
if (cf->resolution_y == 0)
strcpy(res_y, STAR_STRING);
else
sprintf(res_y, "%d", (int) cf->resolution_y);
encoding = ENCODING_STRING(fsw);
/*
* I should really check to see that the string fits, but
* What would I do it I failed?
*/
sprintf(buf, "-*-%s-%s-%s-*-*-*-%s-%s-%s-%s-*-%s",
family, XrmQuarkToString(cf->weightq), cf->slant, point_size,
res_x, res_y, cf->spacing, encoding);
return(buf);
}
/* Function Name: UpdateBoldItalic
* Description: Updates the bold and italic buttons
* Arguments: fsw - the font selector widget.
* Returns: none.
*/
static void
UpdateBoldItalic(XmFontSelectorWidget fsw)
{
Boolean set;
FontData *cf = XmFontS_font_info(fsw)->current_font;
FamilyInfo *fam;
if ((fam = FindFamily(cf->familyq, XmFontS_font_info(fsw)->family_info,
XmFontS_font_info(fsw)->num_families)) == NULL)
{
String params[1];
Cardinal num = 1;
params[0] = XrmQuarkToString(cf->familyq);
dbg(); _XmWarningMsg((Widget) fsw, XmNcouldNotFindFamilyData,
XmNcouldNotFindFamilyDataMsg, params, num);
return;
}
if ((fam->medium_nameq == NULLQUARK) || (fam->bold_nameq == NULLQUARK)) {
set = (fam->medium_nameq == NULLQUARK);
XmToggleButtonSetState(XmFontS_bold_toggle(fsw), set, False);
SetFlag(&(XmFontS_user_state(fsw)), BOLD, set);
XtSetSensitive(XmFontS_bold_toggle(fsw), False);
}
else {
XtSetSensitive(XmFontS_bold_toggle(fsw), True);
}
if (CheckFlag(XmFontS_user_state(fsw), BOLD))
cf->weightq = fam->bold_nameq;
else
cf->weightq = fam->medium_nameq;
if ((fam->upright_nameq == NULLQUARK)|| (fam->italic_nameq == NULLQUARK)) {
set = (fam->upright_nameq == NULLQUARK);
XmToggleButtonSetState(XmFontS_italic_toggle(fsw), set, False);
SetFlag(&(XmFontS_user_state(fsw)), ITALIC, set);
XtSetSensitive(XmFontS_italic_toggle(fsw), False);
}
else {
XtSetSensitive(XmFontS_italic_toggle(fsw), True);
}
if (CheckFlag(XmFontS_user_state(fsw), ITALIC))
strcpy(cf->slant, XrmQuarkToString(fam->italic_nameq));
else
strcpy(cf->slant, XrmQuarkToString(fam->upright_nameq));
}
/* Function Name: UpdateFixedProportional
* Description: Updates the string stored in the fixed/proportional
* part of the current font data.
* Arguments: fsw - the font selector widget.
* Returns: none.
*/
static void
UpdateFixedProportional(XmFontSelectorWidget fsw)
{
FontData *cf = XmFontS_font_info(fsw)->current_font;
FamilyInfo *fam;
Boolean setMono, setProp, setAny;
if ((fam = FindFamily(cf->familyq, XmFontS_font_info(fsw)->family_info,
XmFontS_font_info(fsw)->num_families)) == NULL)
{
String params[1];
Cardinal num = 1;
params[0] = XrmQuarkToString(cf->familyq);
dbg(); _XmWarningMsg((Widget) fsw, XmNcouldNotFindFamilyData,
XmNcouldNotFindFamilyDataMsg, params, num);
return;
}
if (CheckFlag(XmFontS_user_state(fsw), USER_PROPORTIONAL)) {
if (CheckFlag(XmFontS_user_state(fsw), USER_FIXED))
{
strcpy(cf->spacing, STAR_STRING);
setMono = False; setProp = False; setAny = True;
}
else
{
strcpy(cf->spacing, PROPORTIONAL_SPACING);
setMono = False; setProp = True; setAny = False;
}
}
else if (CheckFlag(XmFontS_user_state(fsw), USER_FIXED))
{
strcpy(cf->spacing, fam->fixed_spacing);
setMono = True; setProp = False; setAny = False;
}
else
{
strcpy(cf->spacing, STAR_STRING);
setMono = False; setProp = False; setAny = True;
}
if ( XmFontS_monospace(fsw) != NULL )
XmToggleButtonSetState(XmFontS_monospace(fsw), setMono, False);
if ( XmFontS_proportional(fsw) != NULL )
XmToggleButtonSetState(XmFontS_proportional(fsw), setProp, False);
if ( XmFontS_any_spacing(fsw) != NULL )
XmToggleButtonSetState(XmFontS_any_spacing(fsw), setAny, False);
}
/* Function Name: UpdateFamilies
* Description: Updates the displayed families.
* Arguments: fsw - the file selector widget.
* Returns: none
*/
static void
UpdateFamilies(XmFontSelectorWidget fsw)
{
Arg largs[10];
Cardinal num_largs;
register int count;
register int i, num;
XmString *strs;
LongFlag size_flag;
FamilyInfo *fam = XmFontS_font_info(fsw)->family_info;
FontData *cf = XmFontS_font_info(fsw)->current_font;
Boolean str_match = False;
String temp;
num = XmFontS_font_info(fsw)->num_families;
strs = (XmString *) XtMalloc(sizeof(XmString) * num);
size_flag = SizeMapping(cf->point_size);
for (i = count = 0; i < num; i++, fam++) {
Boolean ok_75, ok_100, spacing_match, resolution_ok, has_sizes;
/*
* Only add this family if:
*
* The size is 0 (ANY SIZE) and there is a font of the current
* right DPI, or
* This is a scaled font and scaling is turned on, or
* This font has current point size in 75 dpi and 75 or any selectd, or
* This font has current point size in 100 dpi and 100 or any selectd.
*
* And
* The Charset/Encodings match or any is selected.
* The type of spacing matches.
* This is a scaled font or there are some valid sizes
* in the current point size.
*/
ok_75 = ((size_flag != 0) &&
CheckFlag(XmFontS_user_state(fsw), DPI_75) &&
CheckLongFlag(fam->sizes_75, size_flag));
ok_100 = ((size_flag != 0) &&
CheckFlag(XmFontS_user_state(fsw), DPI_100) &&
CheckLongFlag(fam->sizes_100, size_flag));
resolution_ok = (cf->resolution_x == 0) && (cf->resolution_y == 0);
resolution_ok |= (CheckFlag(XmFontS_user_state(fsw), DPI_75) &&
CheckFlag(fam->state, DPI_75));
resolution_ok |= (CheckFlag(XmFontS_user_state(fsw), DPI_100) &&
CheckFlag(fam->state, DPI_100));
if (!(has_sizes = IsScaled(fsw, fam))) {
has_sizes |= ((fam->sizes_75 != 0) &&
CheckFlag(XmFontS_user_state(fsw), DPI_75));
has_sizes |= ((fam->sizes_100 != 0) &&
CheckFlag(XmFontS_user_state(fsw), DPI_100));
}
/*
* The Any Family will match all spacings.
*/
spacing_match = (i == ANY_FAMILY);
spacing_match |= (CheckFlag(XmFontS_user_state(fsw), USER_PROPORTIONAL) &&
CheckFlag(fam->state, PROPORTIONAL));
spacing_match |= (CheckFlag(XmFontS_user_state(fsw), USER_FIXED) &&
!CheckFlag(fam->state, PROPORTIONAL));
if (((cf->point_size == 0) || IsScaled(fsw, fam) || ok_75 || ok_100) &&
CheckEncoding(fsw, fam) && spacing_match &&
resolution_ok && has_sizes)
{
strs[count++] = XmStringCreateLocalized(XrmQuarkToString(fam->nameq));
str_match |= (fam->nameq == cf->familyq);
}
}
num_largs = 0;
/*
* This font is no longer in the list, reset the list to ANY_STRING
*/
if (!str_match) {
temp = _XmGetMBStringFromXmString(ANY_STRING(fsw));
XtSetArg(largs[num_largs], XmNvalue, temp); num_largs++;
}
else
temp = NULL;
XtSetArg(largs[num_largs], XmNitems, strs); num_largs++;
XtSetArg(largs[num_largs], XmNitemCount, count); num_largs++;
XtSetValues(XmFontS_family_box(fsw), largs, num_largs);
if (!str_match)
FamilyChanged(XmFontS_family_box(fsw), (XtPointer) fsw, NULL);
for (count--; count >= 0; count--)
XmStringFree(strs[count]);
XtFree((XtPointer) strs);
XtFree((XtPointer) temp);
}
/* Function Name: UpdateSizes
* Description: Updates the list of sizes.
* Arguments: fsw - the font selector widget.
* Returns: none.
*/
static void
UpdateSizes(XmFontSelectorWidget fsw)
{
FontData * cf = XmFontS_font_info(fsw)->current_font;
Arg largs[10];
Cardinal num_largs = 0;
register int count = 0;
register int i, size;
XmString *strs;
LongFlag size_flag;
FamilyInfo *family;
Boolean editable, match = False;
String temp = NULL;
if ((family = FindFamily(XmFontS_font_info(fsw)->current_font->familyq,
XmFontS_font_info(fsw)->family_info,
XmFontS_font_info(fsw)->num_families)) == NULL)
{
String params[1];
Cardinal num = 1;
params[0] = XrmQuarkToString(cf->familyq);
dbg(); _XmWarningMsg((Widget) fsw, XmNcouldNotFindFamilyData,
XmNcouldNotFindFamilyDataMsg, params, num);
return;
}
if (IsScaled(fsw, family)) {
family = XmFontS_font_info(fsw)->family_info + ANY_FAMILY;
editable = True;
}
else {
editable = False;
}
size_flag = 0;
if (CheckFlag(XmFontS_user_state(fsw), DPI_75))
size_flag |= family->sizes_75;
if (CheckFlag(XmFontS_user_state(fsw), DPI_100))
size_flag |= family->sizes_100;
size = sizeof(LongFlag) * 8; /* There are 8 bits in a BYTE */
strs = (XmString *) XtMalloc(sizeof(XmString) * (size + 1));
/*
* DMS - fix to work around apparent Motif 1.2.4 bug concerning
* XmStrings containing as the empty string
*/
if (XmStringEmpty(ANY_STRING(fsw)))
strs[count++] = XmStringCreateLocalized(" ");
else
strs[count++] = XmStringCopy(ANY_STRING(fsw));
for (i = 0; i < XtNumber(GValidSizes); i++) {
char buf[10];
LongFlag flag = ((LongFlag) 1) << i;
if (!CheckLongFlag(size_flag, flag) && !IsScaled(fsw, family))
continue;
sprintf(buf, "%d", GValidSizes[i]);
strs[count++] = XmStringCreateLocalized(buf);
match |= (SizeMapping(cf->point_size) == flag);
}
if (!match) {
temp = _XmGetMBStringFromXmString(ANY_STRING(fsw));
XtSetArg(largs[num_largs], XmNvalue, temp); num_largs++;
}
XtSetArg(largs[num_largs], XmNitems, strs); num_largs++;
XtSetArg(largs[num_largs], XmNitemCount, count); num_largs++;
XtSetArg(largs[num_largs], XmNeditable, editable); num_largs++;
XtSetValues(XmFontS_size_box(fsw), largs, num_largs);
if (!match)
SizeChanged(XmFontS_size_box(fsw), (XtPointer) fsw, NULL);
for (count--; count >= 0; count--)
XmStringFree(strs[count]);
XtFree((XtPointer) strs);
XtFree((XtPointer) temp);
}
/* Function Name: SetComboValue
* Description: Sets the value field of a Combination box.
* Arguments: box - the combo box.
* value - the value to set.
* Returns: none.
*/
static void
SetComboValue(Widget box, String value)
{
Arg largs[10];
Cardinal num_largs = 0;
XtSetArg(largs[num_largs], XmNvalue, value); num_largs++;
XtSetValues(box, largs, num_largs);
}
/* Function Name: UnsetSiblings
* Description: Unsets all sibling toggles of this toggle.
* Arguments: w - the toggle who's siblings we are unsetting.
* Returns: none.
*/
static void
UnsetSiblings(Widget w)
{
WidgetList children;
Cardinal num_children;
Arg largs[10];
Cardinal i, num_largs = 0;
XtSetArg(largs[num_largs], XmNchildren, &children); num_largs++;
XtSetArg(largs[num_largs], XmNnumChildren, &num_children); num_largs++;
XtGetValues(XtParent(w), largs, num_largs);
for (i = 0; i < num_children; i++)
XmToggleButtonSetState(children[i], (children[i] == w), False);
}
/* Function Name: DisplayUserError
* Description: Displays an error message to the user.
* Arguments: fsw - the font selector widget.
* msg - the message to display.
* Returns: none
*
* NOTE: If (msg == NULL) then the value of current_text will be placed
* in the text widget.
*/
static void
DisplayUserError(XmFontSelectorWidget fsw, String msg)
{
String temp;
if (msg != NULL) {
/*
* If the real text is already in current_text then do not
* attempt to get it out of the widget, just use what we have
* saved already, this hackery is necessary because of the
* wierd state machine that is in this code.
*
* The problem being solved is that this should work if we call
* DisplayUserError if a user error is already being displayed.
*/
if (XmFontS_current_text(fsw) != NULL) {
temp = XmFontS_current_text(fsw);
XmFontS_current_text(fsw) = NULL;
}
else
temp = XmTextGetString(XmFontS_text(fsw));
XmTextSetString(XmFontS_text(fsw), msg);
XmFontS_current_text(fsw) = temp;
XmProcessTraversal(XmFontS_text(fsw), XmTRAVERSE_CURRENT);
}
else {
if (XmFontS_current_text(fsw) == NULL)
return; /* noting to do. */
temp = XmFontS_current_text(fsw);
XmFontS_current_text(fsw) = NULL;
XmTextSetString(XmFontS_text(fsw), temp);
XtFree((XtPointer) temp);
}
}
/* Function Name: SetResolution
* Description: Sets the DPI toggles based on the FontData passed.
* Arguments: fsw - the font selector widget.
* cf - the font data to use.
* Returns: none.
*/
static void
SetResolution(XmFontSelectorWidget fsw, FontData *cf)
{
Boolean set75, set100, setAny;
if ( cf->resolution_x != cf->resolution_y )
{
set75 = False;
set100 = False;
setAny = True;
}
else if ( XmFontS_font_info(fsw)->current_font->resolution_x == 75 )
{
set75 = True;
set100 = False;
setAny = False;
}
else if ( XmFontS_font_info(fsw)->current_font->resolution_x == 100 )
{
set75 = False;
set100 = True;
setAny = False;
}
else
{
set75 = False;
set100 = False;
setAny = True;
}
XmToggleButtonSetState(XmFontS_dpi75(fsw), set75, False);
XmToggleButtonSetState(XmFontS_dpi100(fsw), set100, False);
XmToggleButtonSetState(XmFontS_dpiAny(fsw), setAny, False);
}
/* Function Name: SetDisplayedFont
* Description: Sets the font to be displayed.
* Arguments: fsw - the font selector widget.
* font - the font to be displayed.
* Returns: none.
*/
static void
SetDisplayedFont(XmFontSelectorWidget fsw, String new_font)
{
Boolean set;
Arg largs[10];
Cardinal num_largs;
FontData *cf = XmFontS_font_info(fsw)->current_font;
char buf[BUFSIZ];
sprintf(buf, "--%s-%s-%s----0-%d-%d-*--%s",
STAR_STRING, DEFAULT_WEIGHT, DEFAULT_SLANT,
XmFontS_font_info(fsw)->resolution,
XmFontS_font_info(fsw)->resolution, ENCODING_STRING(fsw));
FillData(fsw, cf, buf); /* Put in default data. */
if (new_font != NULL) {
if (IsXlfdFont(new_font))
FillData(fsw, cf, new_font);
else {
if (strchr(new_font, '-')) {
String params[1];
Cardinal num = 1;
params[1] = new_font;
dbg(); _XmWarningMsg((Widget) fsw, XmNbadXlfdFont,
XmNbadXlfdFontMsg, params, num);
}
else {
ChangeMode(fsw, False, False);
SetComboValue(XmFontS_family_box(fsw), new_font);
/*
* For optomization of FamilyChanged Only.
*/
cf->familyq = XrmStringToQuark(new_font);
return;
}
}
}
num_largs = 0;
set = CheckFlag(cf->state, ITALIC);
SetFlag(&(XmFontS_user_state(fsw)), ITALIC, set);
XtSetArg(largs[num_largs], XmNset, set); num_largs++;
XtSetValues(XmFontS_italic_toggle(fsw), largs, num_largs);
num_largs = 0;
set = CheckFlag(cf->state, BOLD);
SetFlag(&(XmFontS_user_state(fsw)), BOLD, set);
XtSetArg(largs[num_largs], XmNset, set); num_largs++;
XtSetValues(XmFontS_bold_toggle(fsw), largs, num_largs);
SetComboValue(XmFontS_family_box(fsw), XrmQuarkToString(cf->familyq));
sprintf(buf, "%d", cf->point_size / POINT_DIVIDE);
SetComboValue(XmFontS_size_box(fsw), buf);
SetResolution(fsw, cf);
XmCopyISOLatin1Lowered(buf, cf->spacing);
if ( strstr(buf, STAR_STRING) != NULL )
{
SetFlag(&(XmFontS_user_state(fsw)), USER_PROPORTIONAL | USER_FIXED, True);
}
else if ( strstr(buf, DEFAULT_FIXED_SPACING) != NULL ||
strstr(buf, OTHER_FIXED_SPACING) != NULL )
{
SetFlag(&(XmFontS_user_state(fsw)), USER_FIXED, True);
SetFlag(&(XmFontS_user_state(fsw)), USER_PROPORTIONAL, False);
}
else if ( strstr(buf, PROPORTIONAL_SPACING) != NULL )
{
SetFlag(&(XmFontS_user_state(fsw)), USER_PROPORTIONAL, True);
SetFlag(&(XmFontS_user_state(fsw)), USER_FIXED, False);
}
else
{
SetFlag(&(XmFontS_user_state(fsw)), USER_PROPORTIONAL | USER_FIXED, True);
}
UpdateFixedProportional(fsw);
cf->familyq = NULLQUARK; /* work around FamilyChanged Optomization. */
FamilyChanged(XmFontS_family_box(fsw), (XtPointer) fsw, NULL);
UpdateFamilies(fsw);
}
/************************************************************
*
* Routines for handling when the change from other <--> xlfd mode
*
************************************************************/
/* Function Name: AddToXlfdOnlyList
* Description: Adds a widget to the xlfd only list.
* Arguments: fsw - the font selector.
* w - the widget to add.
* Returns: none.
*/
static void
AddToXlfdOnlyList(XmFontSelectorWidget fsw, Widget w)
{
int num = (int) XmFontS_num_xlfd_only(fsw);
int alloc = (int) XmFontS_alloc_xlfd_only(fsw);
if (num >= alloc) {
alloc += WIDGET_LIST_INC;
XmFontS_xlfd_only(fsw) = (WidgetList) XtRealloc((XtPointer)
XmFontS_xlfd_only(fsw),
sizeof(Widget) * alloc);
XmFontS_alloc_xlfd_only(fsw) = alloc;
}
XmFontS_xlfd_only(fsw)[num] = w;
(XmFontS_num_xlfd_only(fsw))++;
}
/* Function Name: AddToXlfdSensitiveList
* Description: Adds a widget to the xlfd sensitive list.
* Arguments: fsw - the font selector.
* w - the widget to add.
* Returns: none.
*/
static void
AddToXlfdSensitiveList(XmFontSelectorWidget fsw, Widget w)
{
int num = (int) XmFontS_num_xlfd_sensitive(fsw);
int alloc = (int) XmFontS_alloc_xlfd_sensitive(fsw);
if (num >= alloc) {
alloc += WIDGET_LIST_INC;
XmFontS_xlfd_sensitive(fsw) = (WidgetList) XtRealloc((XtPointer)
XmFontS_xlfd_sensitive(fsw),
sizeof(Widget)* alloc);
XmFontS_alloc_xlfd_sensitive(fsw) = alloc;
}
XmFontS_xlfd_sensitive(fsw)[num] = w;
(XmFontS_num_xlfd_sensitive(fsw))++;
}
/* Function Name: ChangeMode
* Description: Changes the mode of the font selector.
* Arguments: fsw - the file selector widget.
* xlfd_mode - If True then change to xlfd mode,
* otherwize change to other mode.
* force - For other mode - True if we're changing modes
* false if we're displaying a font
*
* Returns: none.
*/
static void
ChangeMode(XmFontSelectorWidget fsw, Boolean xlfd_mode, Boolean force)
{
Arg largs[10];
Cardinal num_largs;
register WidgetList widgets;
register int i, num;
XmString family_label;
XmFontS_xlfd_mode(fsw) = xlfd_mode; /* remember our current mode. */
num = (int) XmFontS_num_xlfd_sensitive(fsw);
widgets = XmFontS_xlfd_sensitive(fsw);
for (i = 0; i < num; i++, widgets++)
XtSetSensitive(*widgets, xlfd_mode);
num = (int) XmFontS_num_xlfd_only(fsw);
widgets = XmFontS_xlfd_only(fsw);
for (i = 0; i < num; i++, widgets++) {
if (xlfd_mode)
XtManageChild(*widgets);
else
XtUnmanageChild(*widgets);
}
if (xlfd_mode) {
char buf[BUFSIZ];
FontData * cf = XmFontS_font_info(fsw)->current_font;
String temp = _XmGetMBStringFromXmString(ANY_STRING(fsw));
family_label = FAMILY_STRING(fsw);
/*
* Reset the values in the family and size boxes to "any"
*/
SetComboValue(XmFontS_family_box(fsw), temp);
SetComboValue(XmFontS_size_box(fsw), temp);
cf->familyq = XrmStringToQuark(temp);
cf->point_size = 0;
UpdateFamilies(fsw);
UpdateSizes(fsw);
UpdateBoldItalic(fsw);
UpdateFixedProportional(fsw);
DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
XtFree((XtPointer) temp);
}
else {
family_label = OTHER_FONT_STRING(fsw);
SetOtherList(fsw, force);
}
/*
* Set the proper toggle buttons.
*/
UnsetSiblings((xlfd_mode) ? XmFontS_xlfd_toggle(fsw) : XmFontS_other_toggle(fsw));
num_largs = 0;
XtSetArg(largs[num_largs], XmNlabelString, family_label); num_largs++;
XtSetArg(largs[num_largs], XmNeditable, !xlfd_mode); num_largs++;
XtSetValues(XmFontS_family_box(fsw), largs, num_largs);
}
/* Function Name: SetOtherList
* Description: Fills the other list with a complete list of
* all other fonts.
* Arguments: fsw - the font selector widget.
* force - True if toggled by user, False if user
* is setting the current font
* Returns: none
*/
static void
SetOtherList(XmFontSelectorWidget fsw, Boolean force)
{
Arg largs[10];
Cardinal num_largs = 0;
register int count;
XmString *strs;
String *others = XmFontS_font_info(fsw)->others;
FontData * cf = XmFontS_font_info(fsw)->current_font;
register int i, num = XmFontS_font_info(fsw)->num_others;
String curFont = XmFontS_current_font(fsw);
/*
* Set the current font to the first one on the list.
*/
if (num > 0) {
if (force)
{
XtSetArg(largs[num_largs], XmNvalue, *others); num_largs++;
/*
* This only to allow FamilyChanged to be more efficient.
*/
cf->familyq = XrmStringToQuark(*others);
DisplayCurrentFont(fsw, *others);
}
else
{
XtSetArg(largs[num_largs], XmNvalue, curFont); num_largs++;
cf->familyq = XrmStringToQuark(curFont);
DisplayCurrentFont(fsw, curFont);
}
}
else {
XtSetArg(largs[num_largs], XmNvalue, " "); num_largs++;
}
strs = (XmString *) XtMalloc(sizeof(XmString) * num);
for (i = count = 0; i < num; i++, others++)
strs[count++] = XmStringCreateLocalized(*others);
XtSetArg(largs[num_largs], XmNitems, strs); num_largs++;
XtSetArg(largs[num_largs], XmNitemCount, count); num_largs++;
XtSetValues(XmFontS_family_box(fsw), largs, num_largs);
for (count--; count >= 0; count--)
XmStringFree(strs[count]);
XtFree((XtPointer) strs);
}
/************************************************************
*
* These routines actually create the children of the font
* selector.
*
************************************************************/
/* Function Name: CreateChildren
* Description: Creates all children of the font selector.
* Arguments: fsw - the font selector.
* args, num_args - the argument list.
* Returns: none.
*/
static void
CreateChildren(XmFontSelectorWidget fsw, ArgList args, Cardinal num_args)
{
Arg *margs, largs[10];
Cardinal num_largs;
Widget temp, box;
String temp_txt;
CreateTopWidgets(fsw, (Widget) fsw, args, num_args);
CreateMiddleArea(fsw, args, num_args);
num_largs = 0;
XtSetArg(largs[num_largs], XmNfillOption, XmFillAll); num_largs++;
XtSetArg(largs[num_largs], XmNmarginHeight, 2); num_largs++;
margs = XtMergeArgLists(largs, num_largs, args, num_args);
box = XtCreateManagedWidget("box", xmButtonBoxWidgetClass,
(Widget) fsw, margs, num_args + num_largs);
XtFree((XtPointer) margs);
num_largs = 0;
temp_txt = _XmGetMBStringFromXmString(SAMPLE_TEXT(fsw));
XtSetArg(largs[num_largs], XmNvalue, temp_txt); num_largs++;
XtSetArg(largs[num_largs], XmNeditMode, XmMULTI_LINE_EDIT); num_largs++;
XtSetArg(largs[num_largs], XmNwordWrap, True); num_largs++;
XtSetArg(largs[num_largs], XmNscrollHorizontal, False); num_largs++;
XtSetArg(largs[num_largs], XmNrows, XmFontS_text_rows(fsw)); num_largs++;
margs = XtMergeArgLists(largs, num_largs, args, num_args);
temp = XmCreateScrolledText(box, "text", margs, num_args + num_largs);
XtManageChild(XmFontS_text(fsw) = temp);
XtFree((XtPointer) margs);
XtFree((XtPointer) temp_txt);
XtAddCallback(temp, XmNlosingFocusCallback,
RemoveUserError, (XtPointer) fsw);
XtAddCallback(temp, XmNmodifyVerifyCallback,
RemoveUserError, (XtPointer) fsw);
num_largs = 0;
XtSetArg(largs[num_largs], XmNskipAdjust, True); num_largs++;
margs = XtMergeArgLists(largs, num_largs, args, num_args);
temp = XtCreateWidget("nameLabel", xmLabelWidgetClass,
(Widget) fsw, margs, num_args + num_largs);
if (XmFontS_show_font_name(fsw))
XtManageChild(temp);
XmFontS_name_label(fsw) = temp;
XtFree((XtPointer) margs);
}
/* Function Name: CreateTopWidgets
* Description: Creates the children in the middle area where
* fonts are selected.
* Arguments: fsw - the font selector.
* parent - the parent of the created widgets.
* args, num_args - the argument list.
* Returns: none.
*/
static void
CreateTopWidgets(XmFontSelectorWidget fsw, Widget parent,
ArgList args, Cardinal num_args)
{
Arg *margs, largs[10];
Cardinal num_largs;
Widget pane, button;
num_largs = 0;
XtSetArg(largs[num_largs], XmNorientation, XmHORIZONTAL); num_largs++;
XtSetArg(largs[num_largs], XmNspacing, 2); num_largs++;
XtSetArg(largs[num_largs], XmNmarginWidth, 0); num_largs++;
XtSetArg(largs[num_largs], XmNmarginHeight, 0); num_largs++;
margs = XtMergeArgLists(largs, num_largs, args, num_args);
pane = XtCreateManagedWidget("topPane", xmPanedWidgetClass,
parent, margs, num_args + num_largs);
XtFree((XtPointer) margs);
CreateFamilyBox(fsw, pane, args, num_args);
CreateSizesBox(fsw, pane, args, num_args);
CreateBoldItalicBox(fsw, pane, args, num_args);
num_largs = 0;
XtSetArg(largs[num_largs], XmNlabelString, OPTION_STRING(fsw));num_largs++;
XtSetArg(largs[num_largs], XmNshadowThickness, 2); num_largs++;
XtSetArg(largs[num_largs], XmNindicatorOn, False); num_largs++;
XtSetArg(largs[num_largs], XmNskipAdjust, True); num_largs++;
margs = XtMergeArgLists(largs, num_largs, args, num_args);
button = XtCreateManagedWidget("optionButton", xmToggleButtonWidgetClass,
pane, margs, num_args + num_largs);
XtFree((XtPointer) margs);
XtAddCallback(button, XmNvalueChangedCallback,
ToggleMiddlePane, (XtPointer) fsw);
}
/* Function Name: CreateMiddleArea
* Description: Creates the widgets in the top left area.
* These are the family, size, bold/italic and proportional
* boxes.
* Arguments: fsw - the file selection widget.
* args, num_args - arguments to the font selector (filtered).
* Returns: none.
*/
static void
CreateMiddleArea(XmFontSelectorWidget fsw, ArgList args, Cardinal num_args)
{
Arg *margs, largs[10];
Cardinal num_largs;
Widget pane, top_pane;
num_largs = 0;
XtSetArg(largs[num_largs], XmNorientation, XmVERTICAL); num_largs++;
XtSetArg(largs[num_largs], XmNspacing, 2); num_largs++;
XtSetArg(largs[num_largs], XmNmarginWidth, 0); num_largs++;
XtSetArg(largs[num_largs], XmNmarginHeight, 0); num_largs++;
margs = XtMergeArgLists(largs, num_largs, args, num_args);
pane = XtCreateWidget("middlePane", xmPanedWidgetClass,
(Widget) fsw, margs, num_args + num_largs);
XtFree((XtPointer) margs);
XmFontS_middle_pane(fsw) = pane;
num_largs = 0;
XtSetArg(largs[num_largs], XmNorientation, XmHORIZONTAL); num_largs++;
XtSetArg(largs[num_largs], XmNspacing, 2); num_largs++;
XtSetArg(largs[num_largs], XmNmarginWidth, 0); num_largs++;
XtSetArg(largs[num_largs], XmNmarginHeight, 0); num_largs++;
XtSetArg(largs[num_largs], XmNshowSash, False); num_largs++;
margs = XtMergeArgLists(largs, num_largs, args, num_args);
top_pane = XtCreateManagedWidget("leftPane", xmPanedWidgetClass,
pane, margs, num_args + num_largs);
XtFree((XtPointer) margs);
CreateFontChoiceBox(fsw, top_pane, args, num_args);
CreateResolutionBox(fsw, top_pane, args, num_args);
CreateSpacingBox(fsw, pane, args, num_args);
CreateOtherChoiceBox(fsw, pane, args, num_args);
}
/* Function Name: CreateFamilyBox
* Description: Creates the family Family box.
* Arguments: fsw - the file selection widget.
* parent - the parent of this area.
* args, num_args - arguments to the font selector (filtered).
* Returns: none.
*/
static void
CreateFamilyBox(XmFontSelectorWidget fsw, Widget parent,
ArgList args, Cardinal num_args)
{
Widget c_box;
Cardinal num_largs;
Arg *margs, largs[15];
String temp = _XmGetMBStringFromXmString(ANY_STRING(fsw));
num_largs = 0;
XtSetArg(largs[num_largs], XmNlabelString,FAMILY_STRING(fsw)); num_largs++;
XtSetArg(largs[num_largs], XmNshowSash, False); num_largs++;
XtSetArg(largs[num_largs], XmNcolumns, FAMILY_COLUMNS); num_largs++;
XtSetArg(largs[num_largs], XmNpopupOffset, 0); num_largs++;
XtSetArg(largs[num_largs], XmNverticalMargin, 0); num_largs++;
XtSetArg(largs[num_largs], XmNhorizontalMargin, 0); num_largs++;
XtSetArg(largs[num_largs], XmNverify, False); num_largs++;
XtSetArg(largs[num_largs], XmNeditable, False); num_largs++;
XtSetArg(largs[num_largs], XmNvisibleItemCount, VISIBILE_FAMILIES);
num_largs++;
/*
* This may cause a problem in Motif I18N applications with 1.2
*/
XtSetArg(largs[num_largs], XmNvalue, temp); num_largs++;
margs = XtMergeArgLists(largs, num_largs, args, num_args);
c_box = XtCreateManagedWidget("families", xmDropDownWidgetClass,
parent, margs, num_args + num_largs);
XtAddCallback(c_box, XmNverifyTextCallback, FamilyChanged, (XtPointer)fsw);
XtAddCallback(c_box, XmNupdateTextCallback, FamilyChanged, (XtPointer)fsw);
XtFree((XtPointer) margs);
XtFree((XtPointer) temp);
XmFontS_family_box(fsw) = c_box;
}
/* Function Name: CreateSizesBox
* Description: Creates the box for the sizes
* Arguments: fsw - the file selection widget.
* parent - the parent of this area.
* args, num_args - arguments to the font selector (filtered).
* Returns: none.
*
* NOTE: List is constructed later in UpdateSizes.
*/
static void
CreateSizesBox(XmFontSelectorWidget fsw, Widget parent,
ArgList args, Cardinal num_args)
{
Widget c_box;
Cardinal num_largs;
Arg *margs, largs[15];
String temp;
num_largs = 0;
XtSetArg(largs[num_largs], XmNlabelString, SIZE_STRING(fsw)); num_largs++;
XtSetArg(largs[num_largs], XmNshowSash, False); num_largs++;
XtSetArg(largs[num_largs], XmNcolumns, 4); num_largs++;
XtSetArg(largs[num_largs], XmNmaxLength, 3); num_largs++;
XtSetArg(largs[num_largs], XmNpopupOffset, 0); num_largs++;
XtSetArg(largs[num_largs], XmNverticalMargin, 0); num_largs++;
XtSetArg(largs[num_largs], XmNhorizontalMargin, 0); num_largs++;
XtSetArg(largs[num_largs], XmNverify, False); num_largs++;
XtSetArg(largs[num_largs], XmNskipAdjust, True); num_largs++;
XtSetArg(largs[num_largs], XmNvisibleItemCount, VISIBILE_FAMILIES);
num_largs++;
temp = _XmGetMBStringFromXmString(ANY_STRING(fsw));
XtSetArg(largs[num_largs], XmNvalue, temp); num_largs++;
margs = XtMergeArgLists(largs, num_largs, args, num_args);
c_box = XtCreateManagedWidget("sizes", xmDropDownWidgetClass,
parent, margs, num_args + num_largs);
XtFree(temp);
AddToXlfdOnlyList(fsw, c_box);
XtAddCallback(c_box, XmNverifyTextCallback, SizeChanged, (XtPointer)fsw);
XtAddCallback(c_box, XmNupdateTextCallback, SizeChanged, (XtPointer)fsw);
XtFree((XtPointer) margs);
XmFontS_size_box(fsw) = c_box;
}
/* Function Name: CreateBoldItalicBox
* Description: Creates the bold and italic choice box.
* Arguments: fsw - the file selection widget.
* parent - the parent of this area.
* args, num_args - arguments to the font selector (filtered).
* Returns: none.
*/
static void
CreateBoldItalicBox(XmFontSelectorWidget fsw, Widget parent,
ArgList args, Cardinal num_args)
{
Widget box, button;
Cardinal num_largs, num_str;
Arg *margs, largs[10];
num_largs = 0;
XtSetArg(largs[num_largs], XmNorientation, XmHORIZONTAL); num_largs++;
XtSetArg(largs[num_largs], XmNshowSash, False); num_largs++;
XtSetArg(largs[num_largs], XmNskipAdjust, True); num_largs++;
margs = XtMergeArgLists(largs, num_largs, args, num_args);
box = XtCreateManagedWidget("boldItalicBox", xmButtonBoxWidgetClass,
parent, margs, num_args + num_largs);
AddToXlfdOnlyList(fsw, box);
XtFree((XtPointer) margs);
num_largs = 0;
XtSetArg(largs[num_largs], XmNlabelString, BOLD_STRING(fsw));
num_str = num_largs++;
XtSetArg(largs[num_largs], XmNindicatorType, XmN_OF_MANY); num_largs++;
XtSetArg(largs[num_largs], XmNalignment, XmALIGNMENT_BEGINNING);
num_largs++;
margs = XtMergeArgLists(largs, num_largs, args, num_args);
button = XtCreateManagedWidget("boldButton", xmToggleButtonWidgetClass,
box, margs, num_args + num_largs);
XmFontS_bold_toggle(fsw) = button;
XtAddCallback(button, XmNvalueChangedCallback, ToggleBold, (XtPointer)fsw);
margs[num_str].value = (XtArgVal) ITALIC_STRING(fsw);
button = XtCreateManagedWidget("italicButton", xmToggleButtonWidgetClass,
box, margs, num_args + num_largs);
XmFontS_italic_toggle(fsw) = button;
XtAddCallback(button,
XmNvalueChangedCallback, ToggleItalic, (XtPointer) fsw);
XtFree((XtPointer) margs);
}
/* Function Name: CreateSpacingBox
* Description: Creates the spacing choice box.
* Arguments: fsw - the file selection widget.
* parent - the parent of this area.
* args, num_args - arguments to the font selector (filtered).
* Returns: none.
*/
static void
CreateSpacingBox(XmFontSelectorWidget fsw, Widget parent,
ArgList args, Cardinal num_args)
{
Widget box, button;
Cardinal num_largs, num_str, num_set;
Arg *margs, largs[10];
num_largs = 0;
XtSetArg(largs[num_largs], XmNorientation, XmHORIZONTAL); num_largs++;
XtSetArg(largs[num_largs], XmNshowSash, False); num_largs++;
XtSetArg(largs[num_largs], XmNfillOption, XmFillMajor); num_largs++;
XtSetArg(largs[num_largs], XmNequalSize, True); num_largs++;
margs = XtMergeArgLists(largs, num_largs, args, num_args);
box = XtCreateManagedWidget("spacingBox", xmButtonBoxWidgetClass,
parent, margs, num_args + num_largs);
AddToXlfdSensitiveList(fsw, box);
XtFree((XtPointer) margs);
num_largs = 0;
XtSetArg(largs[num_largs], XmNset, False); num_set = num_largs++;
XtSetArg(largs[num_largs], XmNlabelString, PROPORTIONAL_STRING(fsw));
num_str = num_largs++;
XtSetArg(largs[num_largs], XmNindicatorType, XmONE_OF_MANY); num_largs++;
XtSetArg(largs[num_largs], XmNalignment, XmALIGNMENT_BEGINNING);
num_largs++;
margs = XtMergeArgLists(largs, num_largs, args, num_args);
button = XtCreateManagedWidget("proportionalButton",
xmToggleButtonWidgetClass,
box, margs, num_args + num_largs);
XtAddCallback(button, XmNvalueChangedCallback, ToggleProportional,
(XtPointer) fsw);
XmFontS_proportional(fsw) = button;
margs[num_str].value = (XtArgVal) MONO_SPACE_STRING(fsw);
button = XtCreateManagedWidget("monoButton", xmToggleButtonWidgetClass,
box, margs, num_args + num_largs);
XtAddCallback(button, XmNvalueChangedCallback, ToggleFixed,
(XtPointer) fsw);
XmFontS_monospace(fsw) = button;
margs[num_str].value = (XtArgVal) BOTH_STRING(fsw);
margs[num_set].value = (XtArgVal) True;
button = XtCreateManagedWidget("bothButton", xmToggleButtonWidgetClass,
box, margs, num_args + num_largs);
XtAddCallback(button, XmNvalueChangedCallback, ToggleBothSpacing,
(XtPointer) fsw);
XmFontS_any_spacing(fsw) = button;
SetFlag(&(XmFontS_user_state(fsw)), USER_FIXED | USER_PROPORTIONAL, True);
XtFree((XtPointer) margs);
}
/* Function Name: CreateFontChoiceBox
* Description: Create a box to choose between xlfd fonts and others.
* Arguments: fsw - the file selection widget.
* parent - the parent of this area.
* args, num_args - arguments to the font selector (filtered).
* Returns: none.
*/
static void
CreateFontChoiceBox(XmFontSelectorWidget fsw, Widget parent,
ArgList args, Cardinal num_args)
{
Widget box, button;
Cardinal num_largs, num_str, num_set;
Arg *margs, largs[10];
num_largs = 0;
XtSetArg(largs[num_largs], XmNorientation, XmHORIZONTAL); num_largs++;
XtSetArg(largs[num_largs], XmNshowSash, False); num_largs++;
XtSetArg(largs[num_largs], XmNfillOption, XmFillMajor); num_largs++;
XtSetArg(largs[num_largs], XmNequalSize, True); num_largs++;
margs = XtMergeArgLists(largs, num_largs, args, num_args);
box = XtCreateManagedWidget("choiceBox", xmButtonBoxWidgetClass,
parent, margs, num_args + num_largs);
XtFree((XtPointer) margs);
num_largs = 0;
XtSetArg(largs[num_largs], XmNlabelString, XLFD_STRING(fsw));
num_str = num_largs++;
XtSetArg(largs[num_largs], XmNset, True); num_set = num_largs++;
XtSetArg(largs[num_largs], XmNindicatorType, XmONE_OF_MANY); num_largs++;
XtSetArg(largs[num_largs], XmNalignment, XmALIGNMENT_BEGINNING);
num_largs++;
margs = XtMergeArgLists(largs, num_largs, args, num_args);
button = XtCreateManagedWidget("xlfdButton",
xmToggleButtonWidgetClass,
box, margs, num_args + num_largs);
XmFontS_xlfd_toggle(fsw) = button;
XtAddCallback(button, XmNvalueChangedCallback, XlfdMode, (XtPointer) fsw);
margs[num_str].value = (XtArgVal) OTHER_FONT_STRING(fsw);
margs[num_set].value = (XtArgVal) False;
button = XtCreateManagedWidget("otherButton", xmToggleButtonWidgetClass,
box, margs, num_args + num_largs);
XtAddCallback(button, XmNvalueChangedCallback, OtherMode, (XtPointer) fsw);
XmFontS_other_toggle(fsw) = button;
XtFree((XtPointer) margs);
}
/* Function Name: CreateResolution Box
* Description: Create the box to allow resolution choice(s).
* Arguments: fsw - the file selection widget.
* parent - the parent of this area.
* args, num_args - arguments to the font selector (filtered).
* Returns: none.
*/
static void
CreateResolutionBox(XmFontSelectorWidget fsw, Widget parent,
ArgList args, Cardinal num_args)
{
Widget box, button;
Cardinal num_largs, num_str, num_set;
Arg *margs, largs[10];
num_largs = 0;
XtSetArg(largs[num_largs], XmNorientation, XmHORIZONTAL); num_largs++;
XtSetArg(largs[num_largs], XmNshowSash, False); num_largs++;
XtSetArg(largs[num_largs], XmNfillOption, XmFillMajor); num_largs++;
XtSetArg(largs[num_largs], XmNequalSize, True); num_largs++;
margs = XtMergeArgLists(largs, num_largs, args, num_args);
box = XtCreateManagedWidget("resolutionBox", xmButtonBoxWidgetClass,
parent, margs, num_args + num_largs);
AddToXlfdSensitiveList(fsw, box);
XtFree((XtPointer) margs);
num_largs = 0;
XtSetArg(largs[num_largs], XmNset, False); num_set = num_largs++;
XtSetArg(largs[num_largs], XmNlabelString, DPI75_STRING(fsw));
num_str = num_largs++;
XtSetArg(largs[num_largs], XmNindicatorType, XmONE_OF_MANY); num_largs++;
XtSetArg(largs[num_largs], XmNalignment, XmALIGNMENT_BEGINNING);
num_largs++;
margs = XtMergeArgLists(largs, num_largs, args, num_args);
margs[num_set].value = (XtArgVal) (XmFontS_font_info(fsw)->resolution == 75);
button = XtCreateManagedWidget("dpi75Button", xmToggleButtonWidgetClass,
box, margs, num_args + num_largs);
XtAddCallback(button, XmNvalueChangedCallback, Toggle75DPI, fsw);
XmFontS_dpi75(fsw) = button;
margs[num_str].value = (XtArgVal) DPI100_STRING(fsw);
margs[num_set].value = (XtArgVal) (XmFontS_font_info(fsw)->resolution == 100);
button = XtCreateManagedWidget("dpi100Button", xmToggleButtonWidgetClass,
box, margs, num_args + num_largs);
XtAddCallback(button, XmNvalueChangedCallback, Toggle100DPI, fsw);
XmFontS_dpi100(fsw) = button;
margs[num_str].value = (XtArgVal) BOTH_STRING(fsw);
margs[num_set].value = (XtArgVal) False;
button = XtCreateManagedWidget("anyButton", xmToggleButtonWidgetClass,
box, margs, num_args + num_largs);
XtAddCallback(button, XmNvalueChangedCallback, ToggleBothDPI, fsw);
XmFontS_dpiAny(fsw) = button;
XtFree((XtPointer) margs);
}
/* Function Name: CreateOtherChoiceBox
* Description: Creates the box to allow other choices to be made.
* Arguments: fsw - the file selection widget.
* parent - the parent of this area.
* args, num_args - arguments to the font selector (filtered).
* Returns: none.
*/
static void
CreateOtherChoiceBox(XmFontSelectorWidget fsw, Widget parent,
ArgList args, Cardinal num_args)
{
Widget box, button;
Cardinal num_largs, num_str, num_set;
Arg *margs, largs[10];
num_largs = 0;
XtSetArg(largs[num_largs], XmNorientation, XmHORIZONTAL); num_largs++;
XtSetArg(largs[num_largs], XmNfillOption, XmFillMajor); num_largs++;
XtSetArg(largs[num_largs], XmNequalSize, True); num_largs++;
XtSetArg(largs[num_largs], XmNshowSash, False); num_largs++;
margs = XtMergeArgLists(largs, num_largs, args, num_args);
box = XtCreateManagedWidget("otherChoiceBox", xmButtonBoxWidgetClass,
parent, margs, num_args + num_largs);
XtFree((XtPointer) margs);
num_largs = 0;
XtSetArg(largs[num_largs], XmNset, False); num_set = num_largs++;
XtSetArg(largs[num_largs], XmNlabelString, SCALING_STRING(fsw));
num_str = num_largs++;
XtSetArg(largs[num_largs], XmNindicatorType, XmN_OF_MANY); num_largs++;
XtSetArg(largs[num_largs], XmNalignment, XmALIGNMENT_BEGINNING);
num_largs++;
margs = XtMergeArgLists(largs, num_largs, args, num_args);
margs[num_set].value = (XtArgVal) XmFontS_use_scaling(fsw);
button = XtCreateManagedWidget("scalingButton", xmToggleButtonWidgetClass,
box, margs, num_args + num_largs);
XmFontS_use_scaling_toggle(fsw) = button;
AddToXlfdSensitiveList(fsw, button);
XtAddCallback(button, XmNvalueChangedCallback,
ToggleScaling, (XtPointer) fsw);
margs[num_str].value = (XtArgVal) SHOW_NAME_STRING(fsw);
margs[num_set].value = (XtArgVal) XmFontS_show_font_name(fsw);
button = XtCreateManagedWidget("showNameButton",
xmToggleButtonWidgetClass,
box, margs, num_args + num_largs);
XmFontS_show_font_toggle(fsw) = button;
XtAddCallback(button, XmNvalueChangedCallback,
ToggleNameWindow, (XtPointer) fsw);
XmFontS_option_menu(fsw) = CreateEncodingMenu(fsw, box, args, num_args);
AddToXlfdSensitiveList(fsw, XmFontS_option_menu(fsw));
XtFree((XtPointer) margs);
}
/* Function Name: CreateEncodingMenu
* Description: Creates the encoding option menu.
* Arguments: fsw - The font selector widget.
* parent - The parent of the option menu.
* args - Args used to create the font selector.
* Returns: The Id of the menu created.
*/
static Widget
CreateEncodingMenu(XmFontSelectorWidget fsw,
Widget box, ArgList args, Cardinal num_args)
{
Widget omenu, history = NULL, pulldownMenu, button, menuShell,
destroy_old_menu;
Cardinal num_largs, button_label;
int current, i;
Arg *margs, largs[10];
String *encodings;
/*
* Create the option menu only the first time through, otherwise
* simply blow away the encoding_menu_shell and recreate that.
*/
destroy_old_menu = XmFontS_encoding_menu_shell(fsw);
if (destroy_old_menu == NULL)
{
num_largs = 0;
XtSetArg(largs[num_largs],
XmNrowColumnType, XmMENU_OPTION); num_largs++;
XtSetArg(largs[num_largs],
XmNlabelString, ENCODING_ONLY_STRING(fsw)); num_largs++;
XtSetArg(largs[num_largs],
XmNoptionLabel, ENCODING_ONLY_STRING(fsw)); num_largs++;
margs = XtMergeArgLists(largs, num_largs, args, num_args);
omenu = XtCreateWidget("encodingOptionMenu", xmRowColumnWidgetClass,
box, margs, num_args + num_largs);
XtFree((XtPointer) margs);
}
else
{
omenu = XmFontS_option_menu(fsw);
}
num_largs = 0;
XtSetArg(largs[num_largs], XmNwidth, 1); num_largs++;
XtSetArg(largs[num_largs], XmNheight, 1); num_largs++;
XtSetArg(largs[num_largs], XmNancestorSensitive, True); num_largs++;
margs = XtMergeArgLists(largs, num_largs, args, num_args);
menuShell = XtCreatePopupShell("menuShell", xmMenuShellWidgetClass,
box, margs, num_args + num_largs);
XtFree((XtPointer) margs);
XmFontS_encoding_menu_shell(fsw) = menuShell;
num_largs = 0;
XtSetArg(largs[num_largs], XmNrowColumnType, XmMENU_PULLDOWN); num_largs++;
margs = XtMergeArgLists(largs, num_largs, args, num_args);
pulldownMenu = XtCreateWidget("pulldownMenu",
xmRowColumnWidgetClass,
menuShell, margs, num_args + num_largs);
XtFree((XtPointer) margs);
num_largs = 0;
XtSetArg(largs[num_largs], XmNlabelString, ANY_STRING(fsw));
button_label = num_largs++;
margs = XtMergeArgLists(largs, num_largs, args, num_args);
button = XtCreateManagedWidget("button_0", xmPushButtonWidgetClass,
pulldownMenu, margs,
num_args + num_largs);
XtAddCallback(button,
XmNactivateCallback, ChangeEncoding, (XtPointer) 0);
current = 0;
for (i = 1, encodings = ENCODING_LIST(fsw) ;
*encodings != NULL; i++, encodings++)
{
char name[BUFSIZ];
XmString label = XmStringCreateLocalized(*encodings);
margs[button_label].value = (XtArgVal) label;
sprintf(name, "button_%d", i);
button = XtCreateManagedWidget(name, xmPushButtonWidgetClass,
pulldownMenu, margs,
num_args + num_largs);
XmStringFree(label);
XtAddCallback(button,
XmNactivateCallback, ChangeEncoding, (XtPointer) i);
if (streq(*encodings, ENCODING_STRING(fsw)))
{
current = i;
history = button;
}
}
XtFree((XtPointer) margs);
num_largs = 0;
XtSetArg(largs[num_largs], XmNsubMenuId, pulldownMenu); num_largs++;
/*
* DMS - Fix 2/27/96
*/
if (history)
{
XtSetArg(largs[num_largs], XmNmenuHistory, history); num_largs++;
}
XtSetValues(omenu, largs, num_largs);
if (destroy_old_menu != NULL)
{
XtDestroyWidget(destroy_old_menu);
}
XtManageChild(omenu);
XtFree(ENCODING_STRING(fsw));
if (current == 0)
ENCODING_STRING(fsw) = XtNewString(ANY_ENCODING);
else
ENCODING_STRING(fsw) = XtNewString(ENCODING_LIST(fsw)[current - 1]);
return(omenu);
}
/* Function Name: CheckEncoding
* Description: Checks the encoding of a font to see if it matches
* the currently selected one, and returns true on a match.
* Arguments: fsw - The font selector widget.
* fam - The family that we are checking.
* Returns: True if the encodings matchd, or any is selected.
*/
static Boolean
CheckEncoding(XmFontSelectorWidget fsw, FamilyInfo *fam)
{
int i;
XrmQuark curr;
if (streq(ENCODING_STRING(fsw), ANY_ENCODING) || fam->encodings == NULL)
return(TRUE);
curr = XrmStringToQuark(ENCODING_STRING(fsw));
for (i = 0; TRUE; i++)
{
if (fam->encodings[i] == curr)
return(True);
if (fam->encodings[i] == 0 || i == fam->encoding_alloc)
return(False);
}
}
/************************************************************
*
* Callbacks.
*
************************************************************/
/* Function Name: FamilyChanged
* Description: Called when the user changes the family
* Arguments: w - *** UNUSED ***.
* fsw_ptr - pointer to the font selector widget.
* junk - *** UNUSED ***.
* Returns: none
*/
/* ARGSUSED */
static void
FamilyChanged(Widget w, XtPointer fsw_ptr, XtPointer junk)
{
XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
FontData * cf = XmFontS_font_info(fsw)->current_font;
String str = XmDropDownGetValue(w);
char buf[BUFSIZ];
XrmQuark familyq = XrmStringToQuark(str);
if (cf->familyq == familyq)
return; /* no change. */
cf->familyq = familyq;
if (XmFontS_xlfd_mode(fsw)) {
UpdateBoldItalic(fsw);
UpdateFixedProportional(fsw);
UpdateSizes(fsw);
DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
}
else {
DisplayCurrentFont(fsw, str);
}
XtFree((XtPointer) str);
}
/* Function Name: SizeChanged
* Description: Called when the user changes the Size
* Arguments: w - *** UNUSED ***.
* fsw_ptr - pointer to the font selector widget.
* junk - *** UNUSED ***.
* Returns: none
*/
/* ARGSUSED */
static void
SizeChanged(Widget w, XtPointer fsw_ptr, XtPointer junk)
{
XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
FontData * cf = XmFontS_font_info(fsw)->current_font;
String str = XmDropDownGetValue(w);
char buf[BUFSIZ];
short size;
if (cf->point_size == (size = atoi(str) * 10))
{
XtFree((char*)str);
return; /* no change. */
}
cf->point_size = size;
UpdateFamilies(fsw);
DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
XtFree((XtPointer) str);
}
/* Function Name: ChangeEncoding
* Description: Called when the user changes the encoding.
* Arguments: w - a widget child of the font sel.
* data - pointer to index of the option button.
* junk - ***unused
* Returns: none
*/
/* ARGSUSED */
static void
ChangeEncoding(Widget w, XtPointer data, XtPointer junk)
{
XmFontSelectorWidget fsw;
FontData *cf;
char buf[BUFSIZ];
for ( ; !XtIsSubclass(w, xmFontSelectorWidgetClass); w = XtParent(w)) {}
fsw = (XmFontSelectorWidget) w;
cf = XmFontS_font_info(fsw)->current_font;
if ((int) data == 0)
{
XtFree(ENCODING_STRING(fsw));
ENCODING_STRING(fsw) = XtNewString(ANY_ENCODING);
}
else
{
XtFree(ENCODING_STRING(fsw));
ENCODING_STRING(fsw) = XtNewString(ENCODING_LIST(fsw)[(int) data - 1]);
}
UpdateFamilies(fsw);
DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
}
/* Function Name: ToggleScaling
* Description: Called when the user toggles the Font Scaling button.
* Arguments: w - *** UNUSED ***.
* fsw_ptr - pointer to the font selector widget.
* data - the toggle button data.
* Returns: none
*/
/* ARGSUSED */
static void
ToggleScaling(Widget w, XtPointer fsw_ptr, XtPointer data)
{
XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
FontData * cf = XmFontS_font_info(fsw)->current_font;
FamilyInfo *family;
XmToggleButtonCallbackStruct *info;
LongFlag map;
char buf[BUFSIZ];
info = (XmToggleButtonCallbackStruct *) data;
if ((family = FindFamily(cf->familyq, XmFontS_font_info(fsw)->family_info,
XmFontS_font_info(fsw)->num_families)) == NULL)
{
String params[1];
Cardinal num = 1;
params[0] = XrmQuarkToString(cf->familyq);
dbg(); _XmWarningMsg((Widget) fsw, XmNcouldNotFindFamilyData,
XmNcouldNotFindFamilyDataMsg, params, num);
return;
}
XmFontS_use_scaling(fsw) = info->set;
if (!info->set) {
Boolean map_bad = (map = SizeMapping(cf->point_size)) == 0;
Boolean bad_75 = (CheckFlag(XmFontS_user_state(fsw), DPI_75) &&
!CheckLongFlag(family->sizes_75, map));
Boolean bad_100 = (CheckFlag(XmFontS_user_state(fsw), DPI_100) &&
!CheckLongFlag(family->sizes_100, map));
if (map_bad || bad_75 || (bad_100 && (cf->point_size != 0))) {
String temp = _XmGetMBStringFromXmString(ANY_STRING(fsw));
cf->point_size = 0; /* Reset to Any. */
SetComboValue(XmFontS_size_box(fsw), temp);
XtFree((XtPointer) temp);
}
}
UpdateSizes(fsw);
UpdateFamilies(fsw);
DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
}
/* Function Name: ToggleBold
* Description: Called when the user toggles the bold button.
* Arguments: w - *** UNUSED ***.
* fsw_ptr - pointer to the font selector widget.
* data - the toggle button data.
* Returns: none
*/
/* ARGSUSED */
static void
ToggleBold(Widget w, XtPointer fsw_ptr, XtPointer data)
{
XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
FontData * cf = XmFontS_font_info(fsw)->current_font;
FamilyInfo *family;
XmToggleButtonCallbackStruct *info;
char buf[BUFSIZ];
info = (XmToggleButtonCallbackStruct *) data;
if ((family = FindFamily(cf->familyq, XmFontS_font_info(fsw)->family_info,
XmFontS_font_info(fsw)->num_families)) == NULL)
{
String params[1];
Cardinal num = 1;
params[0] = XrmQuarkToString(cf->familyq);
dbg(); _XmWarningMsg((Widget) fsw, XmNcouldNotFindFamilyData,
XmNcouldNotFindFamilyDataMsg, params, num);
return;
}
if (info->set)
cf->weightq = family->bold_nameq;
else
cf->weightq = family->medium_nameq;
SetFlag(&(cf->state), BOLD, info->set);
SetFlag(&(XmFontS_user_state(fsw)), BOLD, info->set);
DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
}
/* Function Name: ToggleItalic
* Description: Called when the user toggles the italic button.
* Arguments: w - *** UNUSED ***.
* fsw_ptr - pointer to the font selector widget.
* data - the toggle button data.
* Returns: none
*/
/* ARGSUSED */
static void
ToggleItalic(Widget w, XtPointer fsw_ptr, XtPointer data)
{
XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
FontData * cf = XmFontS_font_info(fsw)->current_font;
FamilyInfo *family;
XmToggleButtonCallbackStruct *info;
char buf[BUFSIZ];
info = (XmToggleButtonCallbackStruct *) data;
if ((family = FindFamily(cf->familyq, XmFontS_font_info(fsw)->family_info,
XmFontS_font_info(fsw)->num_families)) == NULL)
{
String params[1];
Cardinal num = 1;
params[0] = XrmQuarkToString(cf->familyq);
dbg(); _XmWarningMsg((Widget) fsw, XmNcouldNotFindFamilyData,
XmNcouldNotFindFamilyDataMsg, params, num);
return;
}
if (info->set)
strcpy(cf->slant, XrmQuarkToString(family->italic_nameq));
else
strcpy(cf->slant, XrmQuarkToString(family->upright_nameq));
SetFlag(&(cf->state), ITALIC, info->set);
SetFlag(&(XmFontS_user_state(fsw)), ITALIC, info->set);
DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
}
/* Function Name: ToggleMiddlePane
* Description: toggles whether or not the middle pane is shown
* Arguments: w - *** UNUSED ***.
* fsw_ptr - pointer to the font selector widget.
* data - the toggle button data.
* Returns: none
*/
/* ARGSUSED */
static void
ToggleMiddlePane(Widget w, XtPointer fsw_ptr, XtPointer data)
{
XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
XmToggleButtonCallbackStruct *info;
info = (XmToggleButtonCallbackStruct *) data;
if (info->set)
XtManageChild(XmFontS_middle_pane(fsw));
else
XtUnmanageChild(XmFontS_middle_pane(fsw));
}
/* Function Name: ToggleNameWindow
* Description: toggles whether or not the middle pane is shown
* Arguments: w - *** UNUSED ***.
* fsw_ptr - pointer to the font selector widget.
* data - the toggle button data.
* Returns: none
*/
/* ARGSUSED */
static void
ToggleNameWindow(Widget w, XtPointer fsw_ptr, XtPointer data)
{
XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
XmToggleButtonCallbackStruct *info;
char buf[BUFSIZ];
info = (XmToggleButtonCallbackStruct *) data;
XmFontS_show_font_name(fsw) = info->set;
if (info->set) {
XtManageChild(XmFontS_name_label(fsw));
if (XmFontS_xlfd_mode(fsw)) {
DisplayCurrentFont(fsw,
BuildFontString(fsw,
XmFontS_font_info(fsw)->current_font,
buf, BUFSIZ));
}
else {
String str = XmDropDownGetValue(XmFontS_family_box(fsw));
DisplayCurrentFont(fsw, str);
XtFree((XtPointer) str);
}
}
else
XtUnmanageChild(XmFontS_name_label(fsw));
}
/* Function Name: Toggle75DPI
* Description: Activated when the 75DPI button is toggled.
* w - the toggle button widget selected.
* fsw_ptr - pointer to the font selector widget.
* data - the toggle button data.
* Returns: none
*/
static void
Toggle75DPI(Widget w, XtPointer fsw_ptr, XtPointer data)
{
XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
FontData * cf = XmFontS_font_info(fsw)->current_font;
XmToggleButtonCallbackStruct *info;
char buf[BUFSIZ];
info = (XmToggleButtonCallbackStruct *) data;
UnsetSiblings(w);
if (!info->set)
return; /* Do nothing on an unset. */
SetFlag(&(XmFontS_user_state(fsw)), DPI_75, True);
SetFlag(&(XmFontS_user_state(fsw)), DPI_100, False);
cf->resolution_x = cf->resolution_y = 75;
UpdateFamilies(fsw);
UpdateSizes(fsw);
DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
}
/* Function Name: Toggle100DPI
* Description: Activated when the 100DPI button is toggled.
* w - the toggle button widget selected.
* fsw_ptr - pointer to the font selector widget.
* data - the toggle button data.
* Returns: none
*/
static void
Toggle100DPI(Widget w, XtPointer fsw_ptr, XtPointer data)
{
XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
FontData * cf = XmFontS_font_info(fsw)->current_font;
XmToggleButtonCallbackStruct *info;
char buf[BUFSIZ];
info = (XmToggleButtonCallbackStruct *) data;
UnsetSiblings(w);
if (!info->set)
return; /* Do nothing on an unset. */
SetFlag(&(XmFontS_user_state(fsw)), DPI_75, False);
SetFlag(&(XmFontS_user_state(fsw)), DPI_100, True);
cf->resolution_x = cf->resolution_y = 100;
UpdateFamilies(fsw);
UpdateSizes(fsw);
DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
}
/* Function Name: ToggleBothDPI
* Description: Activated when the Both DPI button is toggled.
* w - the toggle button widget selected.
* fsw_ptr - pointer to the font selector widget.
* data - the toggle button data.
* Returns: none
*/
static void
ToggleBothDPI(Widget w, XtPointer fsw_ptr, XtPointer data)
{
XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
FontData * cf = XmFontS_font_info(fsw)->current_font;
XmToggleButtonCallbackStruct *info;
char buf[BUFSIZ];
info = (XmToggleButtonCallbackStruct *) data;
UnsetSiblings(w);
if (!info->set)
return; /* Do nothing on an unset. */
SetFlag(&(XmFontS_user_state(fsw)), DPI_75 | DPI_100, True);
cf->resolution_x = cf->resolution_y = 0; /* 0 means any */
UpdateFamilies(fsw);
UpdateSizes(fsw);
DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
}
/* Function Name: ToggleProportional
* Description: Activated when the Proportional button is toggled.
* w - the toggle button widget selected.
* fsw_ptr - pointer to the font selector widget.
* data - the toggle button data.
* Returns: none
*/
static void
ToggleProportional(Widget w, XtPointer fsw_ptr, XtPointer data)
{
XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
FontData * cf = XmFontS_font_info(fsw)->current_font;
XmToggleButtonCallbackStruct *info;
char buf[BUFSIZ];
info = (XmToggleButtonCallbackStruct *) data;
UnsetSiblings(w);
if (!info->set)
return; /* Do nothing on an unset. */
SetFlag(&(XmFontS_user_state(fsw)), USER_PROPORTIONAL, True);
SetFlag(&(XmFontS_user_state(fsw)), USER_FIXED, False);
UpdateFixedProportional(fsw);
UpdateFamilies(fsw);
UpdateSizes(fsw);
DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
}
/* Function Name: ToggleFixed
* Description: Activated when the Fixed button is toggled.
* w - the toggle button widget selected.
* fsw_ptr - pointer to the font selector widget.
* data - the toggle button data.
* Returns: none
*/
static void
ToggleFixed(Widget w, XtPointer fsw_ptr, XtPointer data)
{
XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
FontData * cf = XmFontS_font_info(fsw)->current_font;
XmToggleButtonCallbackStruct *info;
char buf[BUFSIZ];
info = (XmToggleButtonCallbackStruct *) data;
UnsetSiblings(w);
if (!info->set)
return; /* Do nothing on an unset. */
SetFlag(&(XmFontS_user_state(fsw)), USER_FIXED, True);
SetFlag(&(XmFontS_user_state(fsw)), USER_PROPORTIONAL, False);
UpdateFixedProportional(fsw);
UpdateFamilies(fsw);
UpdateSizes(fsw);
DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
}
/* Function Name: ToggleBothSpacing
* Description: Activated when the Both (any) Spacing button is toggled.
* w - the toggle button widget selected.
* fsw_ptr - pointer to the font selector widget.
* data - the toggle button data.
* Returns: none
*/
static void
ToggleBothSpacing(Widget w, XtPointer fsw_ptr, XtPointer data)
{
XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
FontData * cf = XmFontS_font_info(fsw)->current_font;
XmToggleButtonCallbackStruct *info;
char buf[BUFSIZ];
info = (XmToggleButtonCallbackStruct *) data;
UnsetSiblings(w);
if (!info->set)
return; /* Do nothing on an unset. */
SetFlag(&(XmFontS_user_state(fsw)), USER_FIXED | USER_PROPORTIONAL, True);
UpdateFixedProportional(fsw);
UpdateFamilies(fsw);
UpdateSizes(fsw);
DisplayCurrentFont(fsw, BuildFontString(fsw, cf, buf, BUFSIZ));
}
/* Function Name: XlfdMode
* Description: Called when the Xlfd Toggle is selected.
* w - the toggle button widget selected.
* fsw_ptr - pointer to the font selector widget.
* data - the toggle button data.
* Returns: none
*/
static void
XlfdMode(Widget w, XtPointer fsw_ptr, XtPointer data)
{
XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
XmToggleButtonCallbackStruct *info;
info = (XmToggleButtonCallbackStruct *) data;
UnsetSiblings(w);
if (!info->set)
return; /* Do nothing on an unset. */
ChangeMode(fsw, True, True); /* Set to Xlfd Mode. */
}
/* Function Name: OtherMode
* Description: Called when the Other Toggle is selected.
* w - the toggle button widget selected.
* fsw_ptr - pointer to the font selector widget.
* data - the toggle button data.
* Returns: none
*/
static void
OtherMode(Widget w, XtPointer fsw_ptr, XtPointer data)
{
XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
XmToggleButtonCallbackStruct *info;
info = (XmToggleButtonCallbackStruct *) data;
UnsetSiblings(w);
if (!info->set)
return; /* Do nothing on an unset. */
ChangeMode(fsw, False, True); /* Set to other Mode */
}
/* Function Name: RemoveUserError
* Description: Removes a user error from the text widget.
* w - the text widget.
* fsw_ptr - pointer to the font selector widget.
* data - *** UNUSED ***.
* Returns: none
*/
/* ARGSUSED */
static void
RemoveUserError(Widget w, XtPointer fsw_ptr, XtPointer data)
{
XmFontSelectorWidget fsw = (XmFontSelectorWidget) fsw_ptr;
if (XmFontS_current_text(fsw) == NULL)
return;
DisplayUserError(fsw, NULL);
}
/************************************************************
*
* Semi-public routines.
*
************************************************************/
/* Function Name: Class Initlialize
* Description: Initializes class-specific data (offsets)
* Arguments: none
* Returns: nothing
*/
static void
ClassInitialize()
{
/* do nothing */
}
/*
* ClassPartInitialize sets up the fast subclassing for the widget.
*/
static void
#ifdef _NO_PROTO
ClassPartInitialize(w_class)
WidgetClass w_class ;
#else
ClassPartInitialize(WidgetClass w_class)
#endif /* _NO_PROTO */
{
_XmFastSubclassInit (w_class, XmFONTSELECTOR_BIT);
}
/* Function Name: Initialize
* Description: Called to initialize information specific
* to this widget.
* Arguments: req - what was originally requested.
* set - what will be created (our superclassed have
* already mucked with this)
* args, num_args - The arguments passed to
* the creation call.
* Returns: none.
*/
/* ARGSUSED */
static void
Initialize(Widget request, Widget set, ArgList args, Cardinal * num_args)
{
XmFontSelectorWidget fsw = (XmFontSelectorWidget)set;
ArgList f_args;
Cardinal f_num_args;
XmFontS_user_state(fsw) = 0; /* Initialize user state to 0. */
XmFontS_xlfd_mode(fsw) = True; /* We start in Xlfd Mode. */
XmFontS_font_info(fsw) = LoadFontInfo(fsw);
XmFontS_current_text(fsw) = NULL;
XmFontS_old_fontdata(fsw) = NULL;
XmFontS_old_fontlist(fsw) = NULL;
XmFontS_encoding_menu_shell(fsw) = NULL;
XmFontS_xlfd_only(fsw) = XmFontS_xlfd_sensitive(fsw) = NULL;
XmFontS_num_xlfd_only(fsw) = XmFontS_alloc_xlfd_only(fsw) = 0;
XmFontS_num_xlfd_sensitive(fsw) = XmFontS_alloc_xlfd_sensitive(fsw) = 0;
XmFontS_get_font(fsw) = (String) XtMalloc(sizeof(char) * GET_FONT_SIZE);
/* duplicate strings so that user can query them later */
ANY_STRING(fsw) = XmStringCopy(ANY_STRING(fsw));
BOLD_STRING(fsw) = XmStringCopy(BOLD_STRING(fsw));
BOTH_STRING(fsw) = XmStringCopy(BOTH_STRING(fsw));
DPI100_STRING(fsw) = XmStringCopy(DPI100_STRING(fsw));
DPI75_STRING(fsw) = XmStringCopy(DPI75_STRING(fsw));
ENCODING_ONLY_STRING(fsw) = XmStringCopy(ENCODING_ONLY_STRING(fsw));
FAMILY_STRING(fsw) = XmStringCopy(FAMILY_STRING(fsw));
ITALIC_STRING(fsw) = XmStringCopy(ITALIC_STRING(fsw));
LOWER_ANY_STRING(fsw) = XmStringCopy(LOWER_ANY_STRING(fsw));
MONO_SPACE_STRING(fsw) = XmStringCopy(MONO_SPACE_STRING(fsw));
OPTION_STRING(fsw) = XmStringCopy(OPTION_STRING(fsw));
OTHER_FONT_STRING(fsw) = XmStringCopy(OTHER_FONT_STRING(fsw));
PROPORTIONAL_STRING(fsw) = XmStringCopy(PROPORTIONAL_STRING(fsw));
SAMPLE_TEXT(fsw) = XmStringCopy(SAMPLE_TEXT(fsw));
SCALING_STRING(fsw) = XmStringCopy(SCALING_STRING(fsw));
SHOW_NAME_STRING(fsw) = XmStringCopy(SHOW_NAME_STRING(fsw));
SIZE_STRING(fsw) = XmStringCopy(SIZE_STRING(fsw));
XLFD_STRING(fsw) = XmStringCopy(XLFD_STRING(fsw));
ENCODING_STRING(fsw) = XtNewString(ENCODING_STRING(fsw));
/* XmFontS_current_font(fsw) handled internally */
{
int i;
String *encodings = ENCODING_LIST(fsw);
String *newList;
for (i=0, encodings = ENCODING_LIST(fsw); *encodings != NULL; i++, encodings++)
i++;
i++;
newList = (String*)XtMalloc(sizeof(String) * i);
for (i=0, encodings = ENCODING_LIST(fsw); *encodings != NULL; i++, encodings++)
newList[i] = XtNewString(*encodings);
newList[i] = NULL;
ENCODING_LIST(fsw) = newList;
}
_XmFilterArgs(args, *num_args,
xm_std_constraint_filter, &f_args, &f_num_args);
CreateChildren(fsw, f_args, f_num_args);
XtFree((XtPointer) f_args);
SetFlag(&(XmFontS_user_state(fsw)), DPI_75,
(XmFontS_font_info(fsw)->resolution == 75));
SetFlag(&(XmFontS_user_state(fsw)), DPI_100,
(XmFontS_font_info(fsw)->resolution == 100));
/*
* Load default information into the current font.
*/
XmFontS_font_info(fsw)->current_font = (FontData *) XtMalloc(sizeof(FontData));
SetDisplayedFont(fsw, XmFontS_current_font(fsw));
}
/* Function Name: Destroy
* Description: Called when the widget is destroyed, cleans up.
* Arguments: w - the widget.
* Returns: none.
*/
static void
Destroy(Widget w)
{
register int i, num;
register String *ptr;
XmFontSelectorWidget fsw = (XmFontSelectorWidget)w;
if (XmFontS_old_fontdata(fsw) != NULL) {
XFreeFont(XtDisplay(w), XmFontS_old_fontdata(fsw));
XmFontListFree(XmFontS_old_fontlist(fsw));
}
num = XmFontS_font_info(fsw)->num_others;
ptr = XmFontS_font_info(fsw)->others;
for (i = 0; i < num; i++, ptr++)
XtFree(*ptr);
for (i = 0; i < XmFontS_font_info(fsw)->num_families; i++)
XtFree((char*)XmFontS_font_info(fsw)->family_info[i].encodings);
XtFree((XtPointer) XmFontS_get_font(fsw));
XtFree((XtPointer) XmFontS_xlfd_only(fsw));
XtFree((XtPointer) XmFontS_xlfd_sensitive(fsw));
XtFree((XtPointer) XmFontS_font_info(fsw)->others);
XtFree((XtPointer) XmFontS_font_info(fsw)->family_info);
XtFree((XtPointer) XmFontS_font_info(fsw)->current_font);
XtFree((XtPointer) XmFontS_font_info(fsw));
XmStringFree(ANY_STRING(fsw));
XmStringFree(BOLD_STRING(fsw));
XmStringFree(BOTH_STRING(fsw));
XmStringFree(DPI100_STRING(fsw));
XmStringFree(DPI75_STRING(fsw));
XmStringFree(ENCODING_ONLY_STRING(fsw));
XmStringFree(FAMILY_STRING(fsw));
XmStringFree(ITALIC_STRING(fsw));
XmStringFree(LOWER_ANY_STRING(fsw));
XmStringFree(MONO_SPACE_STRING(fsw));
XmStringFree(OPTION_STRING(fsw));
XmStringFree(OTHER_FONT_STRING(fsw));
XmStringFree(PROPORTIONAL_STRING(fsw));
XmStringFree(SAMPLE_TEXT(fsw));
XmStringFree(SCALING_STRING(fsw));
XmStringFree(SHOW_NAME_STRING(fsw));
XmStringFree(SIZE_STRING(fsw));
XmStringFree(XLFD_STRING(fsw));
XtFree(ENCODING_STRING(fsw));
/* current font handled internally */
{
String *encodings;
for (encodings = ENCODING_LIST(fsw); *encodings != NULL; i++, encodings++)
XtFree(*encodings);
XtFree((char*)ENCODING_LIST(fsw));
}
}
/* Function Name: SetValues
* Description: Called when some widget data needs to be modified on-
* the-fly.
* Arguments: old - the current (old) widget values.
* request - before superclassed have changed things.
* set - what will acutally be the new values.
* args, num_args - The arguments passed to the set
* values call.
* Returns: none
*/
/* ARGSUSED */
static Boolean
SetValues(Widget old, Widget request, Widget set,
ArgList args, Cardinal * num_args)
{
Arg largs[10];
Cardinal num_largs, i;
XmFontSelectorWidget old_fsw = (XmFontSelectorWidget) old;
XmFontSelectorWidget set_fsw = (XmFontSelectorWidget) set;
Boolean new_encoding_list = False;
/*
* Pass argument list through to all children.
*/
{
ArgList f_args;
Cardinal f_num_args;
_XmFilterArgs(args, *num_args,
xm_std_constraint_filter, &f_args, &f_num_args);
_XmSetValuesOnChildren(set, f_args, f_num_args);
XtFree((XtPointer) f_args);
}
for (i = 0; i < *num_args; i++)
{
if (streq(args[i].name, XmNencodingList))
new_encoding_list = True;
}
/*
* ||| Protect against any of the strings being changed.
*/
if (XmFontS_current_font(old_fsw) != XmFontS_current_font(set_fsw)) {
SetDisplayedFont(set_fsw, XmFontS_current_font(set_fsw));
}
if (XmFontS_show_font_name(old_fsw) != XmFontS_show_font_name(set_fsw)) {
XmToggleButtonSetState(XmFontS_show_font_toggle(set_fsw),
XmFontS_show_font_name(set_fsw), True);
}
if (XmFontS_use_scaling(old_fsw) != XmFontS_use_scaling(set_fsw)) {
XmToggleButtonSetState(XmFontS_use_scaling_toggle(set_fsw),
XmFontS_use_scaling(set_fsw), True);
}
if (new_encoding_list)
{
Widget parent = XtParent(XmFontS_option_menu(set_fsw));
XmFontS_option_menu(set_fsw) = CreateEncodingMenu(set_fsw,
parent, NULL, 0);
}
/* if new_encoding_list is true, then CreateEncodingMenu has already
** freed and recreated the ENCODING_STRING, so avoid redoing it
*/
if (new_encoding_list ||
(((ENCODING_STRING(old_fsw) != NULL) && (ENCODING_STRING(set_fsw) != NULL))
&& !streq(ENCODING_STRING(old_fsw), ENCODING_STRING(set_fsw)))
)
{
char buf[BUFSIZ];
int current, i;
String *encodings = ENCODING_LIST(set_fsw);
Widget button;
if (!new_encoding_list)
{
XtFree(ENCODING_STRING(old_fsw));
ENCODING_STRING(set_fsw) = XtNewString(ENCODING_STRING(set_fsw));
}
/* some of this code is probably a duplicate of CreateEncodingMenu */
for (current = 0, i = 1 ; *encodings != NULL; i++, encodings++)
{
/*
* If the default encoding matches this one then make this
* the current item in the option menu.
*/
if (strcmp(*encodings, ENCODING_STRING(set_fsw)) == 0)
current = i;
}
sprintf(buf, "*button_%d", current);
if ((button =
XtNameToWidget(XtParent(XmFontS_option_menu(set_fsw)), buf)) != NULL)
{
num_largs = 0;
XtSetArg(largs[num_largs], XmNmenuHistory, button); num_largs++;
XtSetValues(XmFontS_option_menu(set_fsw), largs, num_largs);
ChangeEncoding((Widget) set_fsw, (XtPointer) current, NULL);
}
else
{
/* ||| ERROR. */
}
}
if (XmFontS_text_rows(old_fsw) != XmFontS_text_rows(set_fsw)) {
num_largs = 0;
XtSetArg(largs[num_largs], XmNrows, XmFontS_text_rows(set_fsw));num_largs++;
XtSetValues(XmFontS_text(set_fsw), largs, num_largs);
}
{
Boolean reset = False;
#define DoCheck(old_one,new_one) { reset = False; if (old_one != new_one) { XmStringFree(old_one); new_one = XmStringCopy(new_one); reset = True; } }
DoCheck( ANY_STRING(old_fsw), ANY_STRING(set_fsw)); /* PUNT! or else we need to check if on-screen right now */
DoCheck( BOLD_STRING(old_fsw), BOLD_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_bold_toggle(set_fsw), XmNlabelString, BOLD_STRING(set_fsw), NULL);
DoCheck( BOTH_STRING(old_fsw), BOTH_STRING(set_fsw)); if (reset) { XtVaSetValues( XmFontS_dpiAny(set_fsw), XmNlabelString, BOTH_STRING(set_fsw), NULL); XtVaSetValues( XmFontS_any_spacing(set_fsw), XmNlabelString, BOTH_STRING(set_fsw), NULL); }
DoCheck( DPI100_STRING(old_fsw), DPI100_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_dpi100(set_fsw), XmNlabelString, DPI100_STRING(set_fsw), NULL);
DoCheck( DPI75_STRING(old_fsw), DPI75_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_dpi75(set_fsw), XmNlabelString, DPI75_STRING(set_fsw), NULL);
DoCheck( ENCODING_ONLY_STRING(old_fsw), ENCODING_ONLY_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_option_menu(set_fsw), XmNlabelString, ENCODING_ONLY_STRING(set_fsw), NULL);
DoCheck( FAMILY_STRING(old_fsw), FAMILY_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_family_box(set_fsw), XmNlabelString, FAMILY_STRING(set_fsw), NULL);
DoCheck( ITALIC_STRING(old_fsw), ITALIC_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_italic_toggle(set_fsw), XmNlabelString, ITALIC_STRING(set_fsw), NULL);
DoCheck( LOWER_ANY_STRING(old_fsw), LOWER_ANY_STRING(set_fsw)); /* PUNT! or else we need to check if on-screen right now */
DoCheck( MONO_SPACE_STRING(old_fsw), MONO_SPACE_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_monospace(set_fsw), XmNlabelString, MONO_SPACE_STRING(set_fsw), NULL);
DoCheck( OPTION_STRING(old_fsw), OPTION_STRING(set_fsw)); if (reset) XtVaSetValues( XtNameToWidget((Widget)set_fsw, "*optionButton"), XmNlabelString, OPTION_STRING(set_fsw), NULL);
DoCheck( OTHER_FONT_STRING(old_fsw), OTHER_FONT_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_other_toggle(set_fsw), XmNlabelString, OTHER_FONT_STRING(set_fsw), NULL);
DoCheck( PROPORTIONAL_STRING(old_fsw), PROPORTIONAL_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_proportional(set_fsw), XmNlabelString, PROPORTIONAL_STRING(set_fsw), NULL);
DoCheck( SAMPLE_TEXT(old_fsw), SAMPLE_TEXT(set_fsw));
if (reset)
{
char * temp_txt = _XmGetMBStringFromXmString(SAMPLE_TEXT(set_fsw));
XtVaSetValues( XmFontS_text(set_fsw), XmNlabelString, temp_txt, NULL);
XtFree(temp_txt);
}
DoCheck( SCALING_STRING(old_fsw), SCALING_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_use_scaling_toggle(set_fsw), XmNlabelString, SCALING_STRING(set_fsw), NULL);
DoCheck( SHOW_NAME_STRING(old_fsw), SHOW_NAME_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_show_font_toggle(set_fsw), XmNlabelString, SHOW_NAME_STRING(set_fsw), NULL);
DoCheck( SIZE_STRING(old_fsw), SIZE_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_size_box(set_fsw), XmNlabelString, SIZE_STRING(set_fsw), NULL);
DoCheck( XLFD_STRING(old_fsw), XLFD_STRING(set_fsw)); if (reset) XtVaSetValues( XmFontS_xlfd_toggle(set_fsw), XmNlabelString, XLFD_STRING(set_fsw), NULL);
#undef DoCheck
}
return (False);
} /* SetValues */
/* Function Name: GetValuesHook
* Description: Packages up the value of the current font.
* Arguments: w - The widget.
* args, num_args - The arguments passed to the get
* values call.
* Returns: none
*/
/* ARGSUSED */
static void
GetValuesHook(Widget w, ArgList args, Cardinal * num_args)
{
XmFontSelectorWidget fsw = (XmFontSelectorWidget) w;
FontData * cf;
String *str_ptr;
register int i;
for (i = 0; i < *num_args; i++) {
if (streq(args[i].name, XmNcurrentFont))
{
cf = XmFontS_font_info(fsw)->current_font;
str_ptr = (String *) args[i].value;
if (XmFontS_xlfd_mode(fsw)) {
BuildFontString(fsw, cf, XmFontS_get_font(fsw), GET_FONT_SIZE);
*str_ptr = XmFontS_get_font(fsw);
}
else {
*str_ptr = XrmQuarkToString(cf->familyq);
}
}
else if (streq(args[i].name, XmNanyString)) *(XmString*)args[i].value = XmStringCopy(ANY_STRING(fsw));
else if (streq(args[i].name, XmNbothString)) *(XmString*)args[i].value = XmStringCopy(BOLD_STRING(fsw));
else if (streq(args[i].name, XmNboldString)) *(XmString*)args[i].value = XmStringCopy(BOTH_STRING(fsw));
else if (streq(args[i].name, XmN100DPIstring)) *(XmString*)args[i].value = XmStringCopy(DPI100_STRING(fsw));
else if (streq(args[i].name, XmN75DPIstring)) *(XmString*)args[i].value = XmStringCopy(DPI75_STRING(fsw));
else if (streq(args[i].name, XmNencodingString)) *(XmString*)args[i].value = XmStringCopy(ENCODING_ONLY_STRING(fsw));
else if (streq(args[i].name, XmNfamilyString)) *(XmString*)args[i].value = XmStringCopy(FAMILY_STRING(fsw));
else if (streq(args[i].name, XmNitalicString)) *(XmString*)args[i].value = XmStringCopy(ITALIC_STRING(fsw));
else if (streq(args[i].name, XmNanyLowerString)) *(XmString*)args[i].value = XmStringCopy(LOWER_ANY_STRING(fsw));
else if (streq(args[i].name, XmNmonoSpaceString)) *(XmString*)args[i].value = XmStringCopy(MONO_SPACE_STRING(fsw));
else if (streq(args[i].name, XmNoptionString)) *(XmString*)args[i].value = XmStringCopy(OPTION_STRING(fsw));
else if (streq(args[i].name, XmNotherString)) *(XmString*)args[i].value = XmStringCopy(OTHER_FONT_STRING(fsw));
else if (streq(args[i].name, XmNpropSpaceString)) *(XmString*)args[i].value = XmStringCopy(PROPORTIONAL_STRING(fsw));
else if (streq(args[i].name, XmNsampleText)) *(XmString*)args[i].value = XmStringCopy(SAMPLE_TEXT(fsw));
else if (streq(args[i].name, XmNscalingString)) *(XmString*)args[i].value = XmStringCopy(SCALING_STRING(fsw));
else if (streq(args[i].name, XmNshowNameString)) *(XmString*)args[i].value = XmStringCopy(SHOW_NAME_STRING(fsw));
else if (streq(args[i].name, XmNsizeString)) *(XmString*)args[i].value = XmStringCopy(SIZE_STRING(fsw));
else if (streq(args[i].name, XmNxlfdString)) *(XmString*)args[i].value = XmStringCopy(XLFD_STRING(fsw));
}
}
/************************************************************
*
* Public routines.
*
************************************************************/
/* Function Name: XmCreateFontSelector
* Description: Creation Routine for UIL and ADA.
* Arguments: parent - the parent widget.
* name - the name of the widget.
* args, num_args - the number and list of args.
* Returns: The created widget.
*/
Widget
XmCreateFontSelector(Widget parent, String name,
ArgList args, Cardinal num_args)
{
return(XtCreateWidget(name, xmFontSelectorWidgetClass,
parent, args, num_args));
}