diff options
-rw-r--r-- | ULabel.c | 864 | ||||
-rw-r--r-- | ULabel.h | 141 | ||||
-rw-r--r-- | ULabelP.h | 129 | ||||
-rw-r--r-- | XFontSel.ad | 148 | ||||
-rw-r--r-- | xfontsel.c | 1532 | ||||
-rw-r--r-- | xfontsel.man | 229 |
6 files changed, 3043 insertions, 0 deletions
diff --git a/ULabel.c b/ULabel.c new file mode 100644 index 0000000..c449ea3 --- /dev/null +++ b/ULabel.c @@ -0,0 +1,864 @@ +/* $XConsortium: Label.c,v 1.97 94/04/17 20:12:12 kaleb Exp $ */ + +/*********************************************************** + +Copyright (c) 1987, 1988, 1994 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XFree86: xc/programs/xfontsel/ULabel.c,v 1.3 2001/10/28 03:34:32 tsi Exp $ */ + +/* + * ULabel.c - UCSLabel widget + * + */ + +#include <X11/IntrinsicP.h> +#include <X11/StringDefs.h> +#include <X11/Xos.h> +#include <X11/Xaw/XawInit.h> +#include "ULabelP.h" +#include <X11/Xmu/Converters.h> +#include <X11/Xmu/Drawing.h> +#include <stdio.h> +#include <ctype.h> +/* needed for abs() */ +#include <stdlib.h> + +#define streq(a,b) (strcmp( (a), (b) ) == 0) + +#define MULTI_LINE_LABEL 32767 + +#ifdef CRAY +#define WORD64 +#endif + +/**************************************************************** + * + * Full class record constant + * + ****************************************************************/ + +/* Private Data */ + +#define offset(field) XtOffsetOf(UCSLabelRec, field) +static XtResource resources[] = { + {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), + offset(label.foreground), XtRString, XtDefaultForeground}, + {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *), + offset(label.font),XtRString, XtDefaultFont}, + {XtNfontSet, XtCFontSet, XtRFontSet, sizeof(XFontSet ), + offset(label.fontset),XtRString, XtDefaultFontSet}, + {XtNlabel, XtCLabel, XtRString, sizeof(String), + offset(label.label), XtRString, NULL}, + {XtNencoding, XtCEncoding, XtRUnsignedChar, sizeof(unsigned char), + offset(label.encoding), XtRImmediate, (XtPointer)XawTextEncoding8bit}, + {XtNjustify, XtCJustify, XtRJustify, sizeof(XtJustify), + offset(label.justify), XtRImmediate, (XtPointer)XtJustifyCenter}, + {XtNinternalWidth, XtCWidth, XtRDimension, sizeof(Dimension), + offset(label.internal_width), XtRImmediate, (XtPointer)4}, + {XtNinternalHeight, XtCHeight, XtRDimension, sizeof(Dimension), + offset(label.internal_height), XtRImmediate, (XtPointer)2}, + {XtNleftBitmap, XtCLeftBitmap, XtRBitmap, sizeof(Pixmap), + offset(label.left_bitmap), XtRImmediate, (XtPointer) None}, + {XtNbitmap, XtCPixmap, XtRBitmap, sizeof(Pixmap), + offset(label.pixmap), XtRImmediate, (XtPointer)None}, + {XtNresize, XtCResize, XtRBoolean, sizeof(Boolean), + offset(label.resize), XtRImmediate, (XtPointer)True}, +}; +#undef offset + +static void Initialize(); +static void Resize(); +static void Redisplay(); +static Boolean SetValues(); +static void ClassInitialize(); +static void Destroy(); +static XtGeometryResult QueryGeometry(); + +UCSLabelClassRec ucsLabelClassRec = { + { +/* core_class fields */ + /* superclass */ (WidgetClass) &simpleClassRec, + /* class_name */ "UCSLabel", + /* widget_size */ sizeof(UCSLabelRec), + /* class_initialize */ ClassInitialize, + /* class_part_initialize */ NULL, + /* class_inited */ FALSE, + /* initialize */ Initialize, + /* initialize_hook */ NULL, + /* realize */ XtInheritRealize, + /* actions */ NULL, + /* num_actions */ 0, + /* resources */ resources, + /* num_resources */ XtNumber(resources), + /* xrm_class */ NULLQUARK, + /* compress_motion */ TRUE, + /* compress_exposure */ TRUE, + /* compress_enterleave */ TRUE, + /* visible_interest */ FALSE, + /* destroy */ Destroy, + /* resize */ Resize, + /* expose */ Redisplay, + /* set_values */ SetValues, + /* set_values_hook */ NULL, + /* set_values_almost */ XtInheritSetValuesAlmost, + /* get_values_hook */ NULL, + /* accept_focus */ NULL, + /* version */ XtVersion, + /* callback_private */ NULL, + /* tm_table */ NULL, + /* query_geometry */ QueryGeometry, + /* display_accelerator */ XtInheritDisplayAccelerator, + /* extension */ NULL + }, +/* Simple class fields initialization */ + { + /* change_sensitive */ XtInheritChangeSensitive + }, +/* UCSLabel class fields initialization */ + { + /* ignore */ 0 + } +}; +WidgetClass ucsLabelWidgetClass = (WidgetClass)&ucsLabelClassRec; +/**************************************************************** + * + * Private Procedures + * + ****************************************************************/ + +static void ClassInitialize() +{ + XawInitializeWidgetSet(); + XtAddConverter( XtRString, XtRJustify, XmuCvtStringToJustify, + (XtConvertArgList)NULL, 0 ); +} + +static XChar2b *buf2b; +static int buf2blen = 0; + +#ifndef WORD64 + +#define TXT16 XChar2b + +#else + +#define TXT16 char + +static int _XawLabelWidth16(fs, str, n) + XFontStruct *fs; + char *str; + int n; +{ + int i; + XChar2b *ptr; + + if (n > buf2blen) { + buf2b = (XChar2b *)XtRealloc((char *)buf2b, n * sizeof(XChar2b)); + buf2blen = n; + } + for (ptr = buf2b, i = n; --i >= 0; ptr++) { + ptr->byte1 = *str++; + ptr->byte2 = *str++; + } + return XTextWidth16(fs, buf2b, n); +} + +static void _XawLabelDraw16(dpy, d, gc, x, y, str, n) + Display *dpy; + Drawable d; + GC gc; + int x, y; + char *str; + int n; +{ + int i; + XChar2b *ptr; + + if (n > buf2blen) { + buf2b = (XChar2b *)XtRealloc((char *)buf2b, n * sizeof(XChar2b)); + buf2blen = n; + } + for (ptr = buf2b, i = n; --i >= 0; ptr++) { + ptr->byte1 = *str++; + ptr->byte2 = *str++; + } + XDrawString16(dpy, d, gc, x, y, buf2b, n); +} + +#define XTextWidth16 _XawLabelWidth16 +#define XDrawString16 _XawLabelDraw16 + +#endif /* WORD64 */ + +static void _XawLabelDrawUCS(dpy, d, gc, x, y, str, n) + Display *dpy; + Drawable d; + GC gc; + int x, y; + char *str; + int n; +{ + char *ep; + unsigned short codepoint; + XChar2b *ptr; + + /* + * Convert to UCS2 string on the fly. + */ + + if (n > buf2blen) { + buf2b = (XChar2b *)XtRealloc((char *)buf2b, n * sizeof(XChar2b)); + buf2blen = n; + } + ep = str + n; + for (ptr = buf2b; str < ep; ptr++) { + if((str[0]&0x80)==0) { + codepoint=str[0]; + str++; + } else if((str[0]&0x20)==0) { + codepoint=(str[0]&0x1F)<<6 | (str[1]&0x3F); + str+=2; + } else if((str[0]&0x10)==0) { + codepoint=(str[0]&0x0F)<<12 | (str[1]&0x3F)<<6 | (str[2]&0x3F); + str+=3; + } else { /* wrong UTF-8 */ + codepoint=(unsigned)'?'; + str++; + } + ptr->byte1 = (codepoint >> 8) & 0xff;; + ptr->byte2 = codepoint & 0xff; + } + XDrawString16(dpy, d, gc, x, y, buf2b, ptr - buf2b); +} + +static int _XawLabelWidthUCS(fs, str, n) + XFontStruct *fs; + char *str; + int n; +{ + char *ep; + unsigned short codepoint; + XChar2b *ptr; + + /* + * Convert to UCS2 string on the fly. + */ + + if (n > buf2blen) { + buf2b = (XChar2b *)XtRealloc((char *)buf2b, n * sizeof(XChar2b)); + buf2blen = n; + } + ep = str + n; + for (ptr = buf2b; str < ep; ptr++) { + if((str[0]&0x80)==0) { + codepoint=str[0]; + str++; + } else if((str[0]&0x20)==0) { + codepoint=(str[0]&0x1F)<<6 | (str[1]&0x3F); + str+=2; + } else if((str[0]&0x10)==0) { + codepoint=(str[0]&0x0F)<<12 | (str[1]&0x3F)<<6 | (str[2]&0x3F); + str+=3; + } else { /* wrong UTF-8 */ + codepoint=(unsigned)'?'; + str++; + } + ptr->byte1 = (codepoint >> 8) & 0xff;; + ptr->byte2 = codepoint & 0xff; + } + return XTextWidth16(fs, buf2b, ptr - buf2b); +} + +#define XTextWidthUCS _XawLabelWidthUCS +#define XDrawStringUCS _XawLabelDrawUCS + +/* + * Calculate width and height of displayed text in pixels + */ + +static void SetTextWidthAndHeight(lw) + UCSLabelWidget lw; +{ + XFontStruct *fs = lw->label.font; + + char *nl; + + if (lw->label.pixmap != None) { + Window root; + int x, y; + unsigned int width, height, bw, depth; + if (XGetGeometry(XtDisplay(lw), lw->label.pixmap, &root, &x, &y, + &width, &height, &bw, &depth)) { + lw->label.label_height = height; + lw->label.label_width = width; + lw->label.label_len = depth; + return; + } + } + if ( lw->simple.international == True ) { + + XFontSet fset = lw->label.fontset; + XFontSetExtents *ext = XExtentsOfFontSet(fset); + + lw->label.label_height = ext->max_ink_extent.height; + if (lw->label.label == NULL) { + lw->label.label_len = 0; + lw->label.label_width = 0; + } + else if ((nl = index(lw->label.label, '\n')) != NULL) { + char *label; + lw->label.label_len = MULTI_LINE_LABEL; + lw->label.label_width = 0; + for (label = lw->label.label; nl != NULL; nl = index(label, '\n')) { + int width = XmbTextEscapement(fset, label, (int)(nl - label)); + + if (width > (int)lw->label.label_width) + lw->label.label_width = width; + label = nl + 1; + if (*label) + lw->label.label_height += + ext->max_ink_extent.height; + } + if (*label) { + int width = XmbTextEscapement(fset, label, strlen(label)); + + if (width > (int) lw->label.label_width) + lw->label.label_width = width; + } + } else { + lw->label.label_len = strlen(lw->label.label); + lw->label.label_width = + XmbTextEscapement(fset, lw->label.label, (int) lw->label.label_len); + } + + } else { + + lw->label.label_height = fs->max_bounds.ascent + fs->max_bounds.descent; + if (lw->label.label == NULL) { + lw->label.label_len = 0; + lw->label.label_width = 0; + } + else if ((nl = index(lw->label.label, '\n')) != NULL) { + char *label; + lw->label.label_len = MULTI_LINE_LABEL; + lw->label.label_width = 0; + for (label = lw->label.label; nl != NULL; nl = index(label, '\n')) { + int width; + + if (lw->label.encoding == XawTextEncodingChar2b) + width = XTextWidth16(fs, (TXT16*)label, (int)(nl - label)/2); + else if (lw->label.encoding == XawTextEncodingUCS) + width = XTextWidthUCS(fs, label, nl - label); + else + width = XTextWidth(fs, label, (int)(nl - label)); + if (width > (int)lw->label.label_width) + lw->label.label_width = width; + label = nl + 1; + if (*label) + lw->label.label_height += + fs->max_bounds.ascent + fs->max_bounds.descent; + } + if (*label) { + int width; + + if (lw->label.encoding == XawTextEncodingChar2b) + width = XTextWidth16(fs, (TXT16*)label, (int)strlen(label)/2); + else if (lw->label.encoding == XawTextEncodingUCS) + width = XTextWidthUCS(fs, label, strlen(label)); + else + width = XTextWidth(fs, label, strlen(label)); + if (width > (int) lw->label.label_width) + lw->label.label_width = width; + } + } else { + lw->label.label_len = strlen(lw->label.label); + if (lw->label.encoding == XawTextEncodingChar2b) + lw->label.label_width = + XTextWidth16(fs, (TXT16*)lw->label.label, + (int) lw->label.label_len/2); + else if (lw->label.encoding == XawTextEncodingUCS) + lw->label.label_width = XTextWidthUCS(fs, lw->label.label, + lw->label.label_len); + else + lw->label.label_width = + XTextWidth(fs, lw->label.label, (int) lw->label.label_len); + } + + } +} + +static void GetnormalGC(lw) + UCSLabelWidget lw; +{ + XGCValues values; + + values.foreground = lw->label.foreground; + values.background = lw->core.background_pixel; + values.font = lw->label.font->fid; + values.graphics_exposures = False; + + if ( lw->simple.international == True ) + /* Since Xmb/wcDrawString eats the font, I must use XtAllocateGC. */ + lw->label.normal_GC = XtAllocateGC( + (Widget)lw, 0, + (unsigned) GCForeground | GCBackground | GCGraphicsExposures, + &values, GCFont, 0 ); + else + lw->label.normal_GC = XtGetGC( + (Widget)lw, + (unsigned) GCForeground | GCBackground | GCFont | GCGraphicsExposures, + &values); +} + +static void GetgrayGC(lw) + UCSLabelWidget lw; +{ + XGCValues values; + + values.foreground = lw->label.foreground; + values.background = lw->core.background_pixel; + values.font = lw->label.font->fid; + values.fill_style = FillTiled; + values.tile = XmuCreateStippledPixmap(XtScreen((Widget)lw), + lw->label.foreground, + lw->core.background_pixel, + lw->core.depth); + values.graphics_exposures = False; + + lw->label.stipple = values.tile; + if ( lw->simple.international == True ) + /* Since Xmb/wcDrawString eats the font, I must use XtAllocateGC. */ + lw->label.gray_GC = XtAllocateGC((Widget)lw, 0, + (unsigned) GCForeground | GCBackground | + GCTile | GCFillStyle | + GCGraphicsExposures, + &values, GCFont, 0); + else + lw->label.gray_GC = XtGetGC((Widget)lw, + (unsigned) GCForeground | GCBackground | + GCFont | GCTile | GCFillStyle | + GCGraphicsExposures, + &values); +} + +static void compute_bitmap_offsets (lw) + UCSLabelWidget lw; +{ + /* + * bitmap will be eventually be displayed at + * (internal_width, internal_height + lbm_y) + */ + if (lw->label.lbm_height != 0) { + lw->label.lbm_y = (lw->core.height - + (lw->label.internal_height * 2 + + lw->label.lbm_height)) / 2; + } else { + lw->label.lbm_y = 0; + } +} + + +static void set_bitmap_info (lw) + UCSLabelWidget lw; +{ + Window root; + int x, y; + unsigned int bw, depth; + + if (!(lw->label.left_bitmap && + XGetGeometry (XtDisplay(lw), lw->label.left_bitmap, &root, &x, &y, + &lw->label.lbm_width, &lw->label.lbm_height, + &bw, &depth))) { + lw->label.lbm_width = lw->label.lbm_height = 0; + } + compute_bitmap_offsets (lw); +} + + + +/* ARGSUSED */ +static void Initialize(request, new, args, num_args) + Widget request, new; + ArgList args; + Cardinal *num_args; +{ + UCSLabelWidget lw = (UCSLabelWidget) new; + + if (lw->label.label == NULL) + lw->label.label = XtNewString(lw->core.name); + else { + lw->label.label = XtNewString(lw->label.label); + } + + GetnormalGC(lw); + GetgrayGC(lw); + + SetTextWidthAndHeight(lw); + + if (lw->core.height == 0) + lw->core.height = lw->label.label_height + + 2 * lw->label.internal_height; + + set_bitmap_info (lw); /* need core.height */ + + if (lw->core.width == 0) /* need label.lbm_width */ + lw->core.width = (lw->label.label_width + + 2 * lw->label.internal_width + + LEFT_OFFSET(lw)); + + lw->label.label_x = lw->label.label_y = 0; + (*XtClass(new)->core_class.resize) ((Widget)lw); + +} /* Initialize */ + +/* + * Repaint the widget window + */ + +/* ARGSUSED */ +static void Redisplay(gw, event, region) + Widget gw; + XEvent *event; + Region region; +{ + UCSLabelWidget w = (UCSLabelWidget) gw; + GC gc; + + /* + * now we'll see if we need to draw the rest of the label + */ + if (region != NULL) { + int x = w->label.label_x; + unsigned int width = w->label.label_width; + if (w->label.lbm_width) { + if (w->label.label_x > (x = w->label.internal_width)) + width += w->label.label_x - x; + } + if (XRectInRegion(region, x, w->label.label_y, + width, w->label.label_height) == RectangleOut){ + return; + } + } + + gc = XtIsSensitive(gw) ? w->label.normal_GC : w->label.gray_GC; +#ifdef notdef + if (region != NULL) + XSetRegion(XtDisplay(gw), gc, region); +#endif /*notdef*/ + + if (w->label.pixmap == None) { + int len = w->label.label_len; + char *label = w->label.label; + Position y = w->label.label_y + w->label.font->max_bounds.ascent; + Position ksy = w->label.label_y; + + /* display left bitmap */ + if (w->label.left_bitmap && w->label.lbm_width != 0) { + XCopyPlane (XtDisplay(gw), w->label.left_bitmap, XtWindow(gw), gc, + 0, 0, w->label.lbm_width, w->label.lbm_height, + (int) w->label.internal_width, + (int) w->label.internal_height + w->label.lbm_y, + (unsigned long) 1L); + } + + if ( w->simple.international == True ) { + + XFontSetExtents *ext = XExtentsOfFontSet(w->label.fontset); + + ksy += abs(ext->max_ink_extent.y); + + if (len == MULTI_LINE_LABEL) { + char *nl; + while ((nl = index(label, '\n')) != NULL) { + XmbDrawString(XtDisplay(w), XtWindow(w), w->label.fontset, gc, + w->label.label_x, ksy, label, (int)(nl - label)); + ksy += ext->max_ink_extent.height; + label = nl + 1; + } + len = strlen(label); + } + if (len) + XmbDrawString(XtDisplay(w), XtWindow(w), w->label.fontset, gc, + w->label.label_x, ksy, label, len); + + } else { /*international false, so use R5 routine */ + + if (len == MULTI_LINE_LABEL) { + char *nl; + while ((nl = index(label, '\n')) != NULL) { + if (w->label.encoding == XawTextEncodingChar2b) + XDrawString16(XtDisplay(gw), XtWindow(gw), gc, + w->label.label_x, y, + (TXT16*)label, (int)(nl - label)/2); + else if (w->label.encoding == XawTextEncodingUCS) + XDrawStringUCS(XtDisplay(gw), XtWindow(gw), gc, + w->label.label_x, y, label, (int)(nl - label)); + else + XDrawString(XtDisplay(gw), XtWindow(gw), gc, + w->label.label_x, y, label, (int)(nl - label)); + y += w->label.font->max_bounds.ascent + + w->label.font->max_bounds.descent; + label = nl + 1; + } + len = strlen(label); + } + if (len) { + if (w->label.encoding == XawTextEncodingChar2b) + XDrawString16(XtDisplay(gw), XtWindow(gw), gc, + w->label.label_x, y, (TXT16*)label, len/2); + else if (w->label.encoding == XawTextEncodingUCS) + XDrawStringUCS(XtDisplay(gw), XtWindow(gw), gc, + w->label.label_x, y, label, len); + else + XDrawString(XtDisplay(gw), XtWindow(gw), gc, + w->label.label_x, y, label, len); + } + + } /*endif international*/ + + } else if (w->label.label_len == 1) { /* depth */ + XCopyPlane(XtDisplay(gw), w->label.pixmap, XtWindow(gw), gc, + 0, 0, w->label.label_width, w->label.label_height, + w->label.label_x, w->label.label_y, 1L); + } else { + XCopyArea(XtDisplay(gw), w->label.pixmap, XtWindow(gw), gc, + 0, 0, w->label.label_width, w->label.label_height, + w->label.label_x, w->label.label_y); + } + +#ifdef notdef + if (region != NULL) + XSetClipMask(XtDisplay(gw), gc, (Pixmap)None); +#endif /* notdef */ +} + +static void _Reposition(lw, width, height, dx, dy) + UCSLabelWidget lw; + Dimension width, height; + Position *dx, *dy; +{ + Position newPos; + Position leftedge = lw->label.internal_width + LEFT_OFFSET(lw); + + switch (lw->label.justify) { + + case XtJustifyLeft : + newPos = leftedge; + break; + + case XtJustifyRight : + newPos = width - + (lw->label.label_width + lw->label.internal_width); + break; + + case XtJustifyCenter : + default: + newPos = (int)(width - lw->label.label_width) / 2; + break; + } + if (newPos < (Position)leftedge) + newPos = leftedge; + *dx = newPos - lw->label.label_x; + lw->label.label_x = newPos; + *dy = (newPos = (int)(height - lw->label.label_height) / 2) + - lw->label.label_y; + lw->label.label_y = newPos; + return; +} + +static void Resize(w) + Widget w; +{ + UCSLabelWidget lw = (UCSLabelWidget)w; + Position dx, dy; + + _Reposition(lw, w->core.width, w->core.height, &dx, &dy); + compute_bitmap_offsets (lw); +} + +/* + * Set specified arguments into widget + */ + +#define PIXMAP 0 +#define WIDTH 1 +#define HEIGHT 2 +#define NUM_CHECKS 3 + +static Boolean SetValues(current, request, new, args, num_args) + Widget current, request, new; + ArgList args; + Cardinal *num_args; +{ + UCSLabelWidget curlw = (UCSLabelWidget) current; + UCSLabelWidget reqlw = (UCSLabelWidget) request; + UCSLabelWidget newlw = (UCSLabelWidget) new; + int i; + Boolean was_resized = False, redisplay = False, checks[NUM_CHECKS]; + + for (i = 0; i < NUM_CHECKS; i++) + checks[i] = FALSE; + + for (i = 0; i < *num_args; i++) { + if (streq(XtNbitmap, args[i].name)) + checks[PIXMAP] = TRUE; + if (streq(XtNwidth, args[i].name)) + checks[WIDTH] = TRUE; + if (streq(XtNheight, args[i].name)) + checks[HEIGHT] = TRUE; + } + + if (newlw->label.label == NULL) { + newlw->label.label = newlw->core.name; + } + + /* + * resize on bitmap change + */ + if (curlw->label.left_bitmap != newlw->label.left_bitmap) { + was_resized = True; + } + + if (curlw->label.encoding != newlw->label.encoding) + was_resized = True; + + if ( (curlw->label.fontset != newlw->label.fontset) && + curlw->simple.international ){ + was_resized = True; + } + if (curlw->label.label != newlw->label.label) { + if (curlw->label.label != curlw->core.name) + XtFree( (char *)curlw->label.label ); + + if (newlw->label.label != newlw->core.name) { + newlw->label.label = XtNewString( newlw->label.label ); + } + was_resized = True; + } + + if (was_resized || (curlw->label.font != newlw->label.font) || + (curlw->label.justify != newlw->label.justify) || checks[PIXMAP]) { + + SetTextWidthAndHeight(newlw); + was_resized = True; + } + + /* recalculate the window size if something has changed. */ + if (newlw->label.resize && was_resized) { + if ((curlw->core.height == reqlw->core.height) && !checks[HEIGHT]) + newlw->core.height = (newlw->label.label_height + + 2 * newlw->label.internal_height); + + set_bitmap_info (newlw); + + if ((curlw->core.width == reqlw->core.width) && !checks[WIDTH]) + newlw->core.width = (newlw->label.label_width + + LEFT_OFFSET(newlw) + + 2 * newlw->label.internal_width); + } + + if (curlw->label.foreground != newlw->label.foreground + || curlw->core.background_pixel != newlw->core.background_pixel + || curlw->label.font->fid != newlw->label.font->fid ) { + + /* The Fontset is not in the GC - don't make a new GC if FS changes! */ + + XtReleaseGC(new, curlw->label.normal_GC); + XtReleaseGC(new, curlw->label.gray_GC); + XmuReleaseStippledPixmap( XtScreen(current), curlw->label.stipple ); + GetnormalGC(newlw); + GetgrayGC(newlw); + redisplay = True; + } + + if ((curlw->label.internal_width != newlw->label.internal_width) + || (curlw->label.internal_height != newlw->label.internal_height) + || was_resized) { + /* Resize() will be called if geometry changes succeed */ + Position dx, dy; + _Reposition(newlw, curlw->core.width, curlw->core.height, &dx, &dy); + } + + return was_resized || redisplay || + XtIsSensitive(current) != XtIsSensitive(new); +} + +static void Destroy(w) + Widget w; +{ + UCSLabelWidget lw = (UCSLabelWidget)w; + + if ( lw->label.label != lw->core.name ) + XtFree( lw->label.label ); + XtReleaseGC( w, lw->label.normal_GC ); + XtReleaseGC( w, lw->label.gray_GC); + XmuReleaseStippledPixmap( XtScreen(w), lw->label.stipple ); +} + + +static XtGeometryResult QueryGeometry(w, intended, preferred) + Widget w; + XtWidgetGeometry *intended, *preferred; +{ + UCSLabelWidget lw = (UCSLabelWidget)w; + + preferred->request_mode = CWWidth | CWHeight; + preferred->width = (lw->label.label_width + + 2 * lw->label.internal_width + + LEFT_OFFSET(lw)); + preferred->height = lw->label.label_height + + 2 * lw->label.internal_height; + if ( ((intended->request_mode & (CWWidth | CWHeight)) + == (CWWidth | CWHeight)) && + intended->width == preferred->width && + intended->height == preferred->height) + return XtGeometryYes; + else if (preferred->width == w->core.width && + preferred->height == w->core.height) + return XtGeometryNo; + else + return XtGeometryAlmost; +} diff --git a/ULabel.h b/ULabel.h new file mode 100644 index 0000000..5a9c620 --- /dev/null +++ b/ULabel.h @@ -0,0 +1,141 @@ +/* $XConsortium: Label.h,v 1.34 94/04/17 20:12:13 rws Exp $ */ + +/*********************************************************** + +Copyright (c) 1987, 1988, 1994 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XFree86: xc/programs/xfontsel/ULabel.h,v 1.1 2000/02/13 03:26:24 dawes Exp $ */ + +#ifndef _XawUCSLabel_h +#define _XawUCSLabel_h + +/*********************************************************************** + * + * UCSLabel Widget + * + ***********************************************************************/ + +#include <X11/Xaw/Label.h> +#include <X11/Xaw/Simple.h> + +/* Resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + background Background Pixel XtDefaultBackground + bitmap Pixmap Pixmap None + border BorderColor Pixel XtDefaultForeground + borderWidth BorderWidth Dimension 1 + cursor Cursor Cursor None + cursorName Cursor String NULL + destroyCallback Callback XtCallbackList NULL + encoding Encoding unsigned char XawTextEncoding8bit + font Font XFontStruct* XtDefaultFont + foreground Foreground Pixel XtDefaultForeground + height Height Dimension text height + insensitiveBorder Insensitive Pixmap Gray + internalHeight Height Dimension 2 + internalWidth Width Dimension 4 + justify Justify XtJustify XtJustifyCenter + label Label String NULL + leftBitmap LeftBitmap Pixmap None + mappedWhenManaged MappedWhenManaged Boolean True + pointerColor Foreground Pixel XtDefaultForeground + pointerColorBackground Background Pixel XtDefaultBackground + resize Resize Boolean True + sensitive Sensitive Boolean True + width Width Dimension text width + x Position Position 0 + y Position Position 0 + +*/ + +/* + * The only extra resource value needed for this widget. + */ +#define XawTextEncodingUCS 2 + +#if 0 +/* + * All of this is defined by Label.h. + */ +#define XawTextEncoding8bit 0 +#define XawTextEncodingChar2b 1 + +#define XtNleftBitmap "leftBitmap" +#define XtCLeftBitmap "LeftBitmap" +#define XtNencoding "encoding" +#define XtCEncoding "Encoding" + +#ifndef XtNfontSet +#define XtNfontSet "fontSet" +#endif + +#ifndef XtCFontSet +#define XtCFontSet "FontSet" +#endif + +#ifndef _XtStringDefs_h_ +#define XtNbitmap "bitmap" +#define XtNforeground "foreground" +#define XtNlabel "label" +#define XtNfont "font" +#define XtNinternalWidth "internalWidth" +#define XtNinternalHeight "internalHeight" +#define XtNresize "resize" +#define XtCResize "Resize" +#define XtCBitmap "Bitmap" +#endif +#endif + +/* Class record constants */ + +extern WidgetClass ucsLabelWidgetClass; + +typedef struct _UCSLabelClassRec *UCSLabelWidgetClass; +typedef struct _UCSLabelRec *UCSLabelWidget; + +#endif /* _XawUniLabel_h */ diff --git a/ULabelP.h b/ULabelP.h new file mode 100644 index 0000000..d4f2358 --- /dev/null +++ b/ULabelP.h @@ -0,0 +1,129 @@ +/* +* $XConsortium: LabelP.h,v 1.29 94/04/17 20:12:14 kaleb Exp $ +*/ + + +/*********************************************************** + +Copyright (c) 1987, 1988, 1994 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XFree86: xc/programs/xfontsel/ULabelP.h,v 1.1 2000/02/13 03:26:24 dawes Exp $ */ + +/* + * ULabelP.h - Private definitions for UCSLabel widget + * + */ + +#ifndef _XawUCSLabelP_h +#define _XawUCSLabelP_h + +/*********************************************************************** + * + * Label Widget Private Data + * + ***********************************************************************/ + +#include "ULabel.h" +#include <X11/Xaw/SimpleP.h> + +/* New fields for the UCSLabel widget class record */ + +typedef struct {int foo;} UCSLabelClassPart; + +/* Full class record declaration */ +typedef struct _UCSLabelClassRec { + CoreClassPart core_class; + SimpleClassPart simple_class; + UCSLabelClassPart label_class; +} UCSLabelClassRec; + +extern UCSLabelClassRec ucsLabelClassRec; + +/* New fields for the UCSLabel widget record */ +typedef struct { + /* resources */ + Pixel foreground; + XFontStruct *font; + XFontSet fontset; + char *label; + XtJustify justify; + Dimension internal_width; + Dimension internal_height; + Pixmap pixmap; + Boolean resize; + unsigned char encoding; + Pixmap left_bitmap; + + /* private state */ + GC normal_GC; + GC gray_GC; + Pixmap stipple; + Position label_x; + Position label_y; + Dimension label_width; + Dimension label_height; + Dimension label_len; + int lbm_y; /* where in label */ + unsigned int lbm_width, lbm_height; /* size of pixmap */ +} UCSLabelPart; + +/**************************************************************** + * + * Full instance record declaration + * + ****************************************************************/ + +typedef struct _UCSLabelRec { + CorePart core; + SimplePart simple; + UCSLabelPart label; +} UCSLabelRec; + +#define LEFT_OFFSET(lw) ((lw)->label.left_bitmap \ + ? (lw)->label.lbm_width + (lw)->label.internal_width \ + : 0) + +#endif /* _XawUCSLabelP_h */ diff --git a/XFontSel.ad b/XFontSel.ad new file mode 100644 index 0000000..c7b20ae --- /dev/null +++ b/XFontSel.ad @@ -0,0 +1,148 @@ +! $XConsortium: XFontSel.ad,v 1.12 94/04/17 20:43:40 gildea Exp $ +! +! app-defaults for XFontSel +! +! Copyright (c) 1985, 1986, 1987, 1988, 1989 X Consortium +! +! Permission is hereby granted, free of charge, to any person obtaining +! a copy of this software and associated documentation files (the +! "Software"), to deal in the Software without restriction, including +! without limitation the rights to use, copy, modify, merge, publish, +! distribute, sublicense, and/or sell copies of the Software, and to +! permit persons to whom the Software is furnished to do so, subject to +! the following conditions: +! +! The above copyright notice and this permission notice shall be included +! in all copies or substantial portions of the Software. +! +! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +! OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +! MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +! IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +! OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +! ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +! OTHER DEALINGS IN THE SOFTWARE. +! +! Except as contained in this notice, the name of the X Consortium shall +! not be used in advertising or otherwise to promote the sale, use or +! other dealings in this Software without prior written authorization +! from the X Consortium. +! +! Author: +! Ralph R. Swick, Digital Equipment Corporation/M.I.T. Project Athena +! one weekend in November, 1989 +! +! $XFree86: xc/programs/xfontsel/XFontSel.ad,v 1.2 2001/08/13 21:46:51 dawes Exp $ + +*appDefaultsVersion: 1 + +*pixelSizeList: 7, 30, 40, 50, 60 +*pointSizeList: 250, 300, 350, 400 + +XFontSel.cursor: left_ptr +*allowShellResize: true + +*commandBox.ShowGrip: false +*commandBox*top: chainTop +*commandBox*bottom: chainTop + +*quitButton.Label: quit +*quitButton.left: chainLeft +*quitButton.right: chainLeft + +*ownButton.Label: select +*ownButton.fromHoriz: quitButton +*ownButton.left: chainLeft +*ownButton.right: chainLeft + +*countLabel.BorderWidth: 0 +*countLabel.Justify: right +*countLabel.Label: 999999 fonts match +*countLabel.left: chainRight +*countLabel.right: chainRight + +*fieldBox.Orientation: horizontal +*fieldBox.HSpace: 0 +*fieldBox.HSpace: 0 + +*dash.label: - +*dash.borderWidth: 0 +*dash.internalHeight: 0 +*dash.internalWidth: 0 + +*fieldBox*MenuButton.BorderWidth: 0 +*fieldBox*MenuButton.internalHeight: 0 +*fieldBox*MenuButton.internalWidth: 0 +*fieldBox*MenuButton.shapeStyle: rectangle + +#ifdef LONG_NAMES +*fieldBox*field0.Label: foundry +*fieldBox*field1.Label: family +*fieldBox*field2.Label: weight +*fieldBox*field3.Label: slant +*fieldBox*field4.Label: set width +*fieldBox*field5.Label: add style +*fieldBox*field6.Label: pixel size +*fieldBox*field7.Label: point size +*fieldBox*field8.Label: resolutionX +*fieldBox*field9.Label: resolutionY +*fieldBox*field10.Label: spacing +*fieldBox*field11.Label: avg width +*fieldBox*field12.Label: registry +*fieldBox*field13.Label: encoding +#else +*fieldBox*field0.Label: fndry +*fieldBox*field1.Label: fmly +*fieldBox*field2.Label: wght +*fieldBox*field3.Label: slant +*fieldBox*field4.Label: sWdth +*fieldBox*field5.Label: adstyl +*fieldBox*field6.Label: pxlsz +*fieldBox*field7.Label: ptSz +*fieldBox*field8.Label: resx +*fieldBox*field9.Label: resy +*fieldBox*field10.Label: spc +*fieldBox*field11.Label: avgWdth +*fieldBox*field12.Label: rgstry +*fieldBox*field13.Label: encdng +#endif + +!*fieldBox*field11.Sensitive: False +*fieldBox*field11.menu.Options.ShowUnselectable: False + + +!*field1*menu*courier.Font: + +*fontName*skipAdjust: true + +*sampleText*international: false + +*sampleText*Label: \ +Processing fonts... + +*sampleText: \ +ABCDEFGHIJKLMNOPQRSTUVWXYZ\n\ +abcdefghijklmnopqrstuvwxyz\n\ +0123456789\n\ +\340\346\347\353\356\360\361\363\371\375\ +\300\306\307\313\316\320\321\323\331\335 + + +*sampleText16: \ +\044\042\044\044\044\046\044\050\044\052\044\053\044\055\044\057\ +\044\061\044\063\044\065\044\067\044\071\044\073\044\075\044\077\n\ +\044\101\044\104\044\106\044\110\044\112\044\113\044\114\044\115\ +\044\116\044\117\044\122\044\125\044\130\044\133\044\136\044\137\n\ +\061\042\061\044\061\046\061\050\061\052\061\053\061\055\061\057\ +\061\061\061\063\061\065\061\067\061\071\061\073\061\075\061\077\n\ +\061\101\061\104\061\106\061\110\061\112\061\113\061\114\061\115\ +\061\116\061\117\061\122\061\125\061\130\061\133\061\136\061\137\n\ + +*sampleTextUCS: \ +ABCDEFGHIJKLMNOPQRSTUVWXYZ /0123456789\n\ +abcdefghijklmnopqrstuvwxyz £©µÀÆÖÞßéöÿ\n\ +–—‘“”„†•…‰™œŠŸž€ ΑΒΓΔΩαβγδω АБВГДабвгд\n\ +∀∂∈ℝ∧∪≡∞ ↑↗↨↻⇣ ┐┼╔╘░►☺♀ fi�⑀₂ἠḂӥẄɐː⍎אԱა + +*sampleText*allowResize: true +*sampleText*Height: 50 diff --git a/xfontsel.c b/xfontsel.c new file mode 100644 index 0000000..12c437d --- /dev/null +++ b/xfontsel.c @@ -0,0 +1,1532 @@ +/* $XConsortium: xfontsel.c,v 1.35 94/04/17 20:43:41 rws Exp $ */ +/* + +Copyright (c) 1985-1989 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the X Consortium. + +Author: Ralph R. Swick, DEC/MIT Project Athena + one weekend in November, 1989 +Modified: Mark Leisher <mleisher@crl.nmsu.edu> to deal with UCS sample text. +*/ +/* $XFree86: xc/programs/xfontsel/xfontsel.c,v 1.7 2001/10/28 03:34:32 tsi Exp $ */ + +#include <stdio.h> +#include <stdlib.h> +#include <X11/Intrinsic.h> +#include <X11/StringDefs.h> +#include <X11/Xatom.h> +#include <X11/Xaw/AsciiText.h> +#include <X11/Xaw/Box.h> +#include <X11/Xaw/Cardinals.h> +#include <X11/Xaw/Command.h> +#include <X11/Xaw/Form.h> +#include <X11/Xaw/MenuButton.h> +#include <X11/Xaw/Paned.h> +#include <X11/Xaw/SimpleMenu.h> +#include <X11/Xaw/SmeBSB.h> +#include <X11/Xaw/Toggle.h> +#include <X11/Xaw/Viewport.h> +#include <X11/Xmu/Atoms.h> +#include <X11/Xmu/StdSel.h> +#include <X11/Xfuncs.h> +#include "ULabel.h" + +#define MIN_APP_DEFAULTS_VERSION 1 +#define FIELD_COUNT 14 +#define DELIM '-' + +/* number of font names to parse in each background iteration */ +#ifndef PARSE_QUANTUM +#define PARSE_QUANTUM 25 +#endif + +#define NZ NULL,ZERO +#define BACKGROUND 10 + +void GetFontNames(); +Boolean Matches(); +Boolean DoWorkPiece(); +void Quit(); +void OwnSelection(); +void SelectField(); +void ParseFontNames(); +void SortFields(); +void FixScalables(); +void MakeFieldMenu(); +void SelectValue(); +void AnyValue(); +void EnableOtherValues(); +void EnableMenu(); +void SetCurrentFont(); +void QuitAction(); + +XtActionsRec xfontsel_actions[] = { + {"Quit", QuitAction} +}; + +Atom wm_delete_window; + +Boolean IsXLFDFontName(); + +typedef void (*XtProc)(); + +static struct _appRes { + int app_defaults_version; + Cursor cursor; + String pattern; + String pixelSizeList; + String pointSizeList; + Boolean print_on_quit; + String sample_text; + String sample_text16; + String sample_textUCS; + Boolean scaled_fonts; +} AppRes; + +#define DEFAULTPATTERN "-*-*-*-*-*-*-*-*-*-*-*-*-*-*" + +static XtResource resources[] = { + { "cursor", "Cursor", XtRCursor, sizeof(Cursor), + XtOffsetOf( struct _appRes, cursor ), + XtRImmediate, NULL }, + { "pattern", "Pattern", XtRString, sizeof(String), + XtOffsetOf( struct _appRes, pattern ), + XtRString, (XtPointer)DEFAULTPATTERN }, + { "pixelSizeList", "PixelSizeList", XtRString, sizeof(String), + XtOffsetOf( struct _appRes, pixelSizeList ), + XtRString, (XtPointer)"" }, + { "pointSizeList", "PointSizeList", XtRString, sizeof(String), + XtOffsetOf( struct _appRes, pointSizeList ), + XtRString, (XtPointer)"" }, + { "printOnQuit", "PrintOnQuit", XtRBoolean, sizeof(Boolean), + XtOffsetOf( struct _appRes, print_on_quit ), + XtRImmediate, (XtPointer)False }, + { "appDefaultsVersion", "AppDefaultsVersion", XtRInt, sizeof(int), + XtOffsetOf( struct _appRes, app_defaults_version ), + XtRImmediate, (XtPointer)0 }, + { "sampleText", "Text", XtRString, sizeof(String), + XtOffsetOf( struct _appRes, sample_text ), + XtRString, (XtPointer)"" }, + { "sampleText16", "Text16", XtRString, sizeof(String), + XtOffsetOf( struct _appRes, sample_text16 ), + XtRString, (XtPointer)"" }, + { "sampleTextUCS", "TextUCS", XtRString, sizeof(String), + XtOffsetOf( struct _appRes, sample_textUCS ), + XtRString, (XtPointer)"" }, + { "scaledFonts", "ScaledFonts", XtRBoolean, sizeof(Boolean), + XtOffsetOf( struct _appRes, scaled_fonts ), + XtRImmediate, (XtPointer)False }, +}; + +static XrmOptionDescRec options[] = { +{"-pattern", "pattern", XrmoptionSepArg, NULL}, +{"-print", "printOnQuit", XrmoptionNoArg, "True"}, +{"-sample", "sampleText", XrmoptionSepArg, NULL}, +{"-sample16", "sampleText16", XrmoptionSepArg, NULL}, +{"-sampleUCS", "sampleTextUCS",XrmoptionSepArg, NULL}, +{"-scaled", "scaledFonts", XrmoptionNoArg, "True"}, +}; + +static void Syntax(call) + char *call; +{ + fprintf (stderr, "usage: %s [-options ...] -fn font\n\n", call); + fprintf (stderr, "where options include:\n"); + fprintf (stderr, + " -display dpy X server to contact\n"); + fprintf (stderr, + " -geometry geom size and location of window\n"); + fprintf (stderr, + " -pattern fontspec font name pattern to match against\n"); + fprintf (stderr, + " -print print selected font name on exit\n"); + fprintf (stderr, + " -sample string sample text to use for 1-byte fonts\n"); + fprintf (stderr, + " -sample16 string sample text to use for 2-byte fonts\n"); + fprintf (stderr, + " -sampleUCS string sample text to use for ISO10646 fonts\n"); + fprintf (stderr, + " -scaled use scaled instances of fonts\n"); + fprintf (stderr, "\n"); + exit (1); +} + + +typedef struct FieldValue FieldValue; +struct FieldValue { + int field; + String string; + Widget menu_item; + int count; /* of fonts */ + int allocated; + int *font; + Boolean enable; +}; + + +typedef struct FieldValueList FieldValueList; +struct FieldValueList { + int count; /* of values */ + int allocated; + Boolean show_unselectable; + FieldValue value[1]; /* really [allocated] */ +}; + + +typedef struct FontValues FontValues; +struct FontValues { + int value_index[FIELD_COUNT]; +}; + + +typedef struct FieldMenuRec FieldMenuRec; +struct FieldMenuRec { + int field; + Widget button; +}; + + +typedef struct Choice Choice; +struct Choice { + Choice *prev; + FieldValue *value; +}; + + +static XtResource menuResources[] = { + { "showUnselectable", "ShowUnselectable", XtRBoolean, sizeof(Boolean), + XtOffsetOf( FieldValueList, show_unselectable ), + XtRImmediate, (XtPointer)True }, +}; + + +typedef enum {ValidateCurrentField, SkipCurrentField} ValidateAction; + +static void EnableAllItems(int field); +static void EnableRemainingItems(ValidateAction current_field_action); +static void FlushXqueue(Display *dpy); +static void MarkInvalidFonts(Boolean *set, FieldValue *val); +static void ScheduleWork(XtProc proc, XtPointer closure, int priority); +static void SetCurrentFontCount(void); +static void SetNoFonts(void); +static void SetParsingFontCount(int count); + +XtAppContext appCtx; +int numFonts; +int numBadFonts; +FontValues *fonts; +int *scaledFonts; +int numScaledFonts; +FieldValueList *fieldValues[FIELD_COUNT]; +FontValues currentFont; +int matchingFontCount; +static Boolean anyDisabled = False; +Widget ownButton; +Widget fieldBox; +Widget countLabel; +Widget currentFontName; +String currentFontNameString; +int currentFontNameSize; +Widget sampleText; +int textEncoding = -1; +static XFontStruct *sampleFont = NULL; +Boolean *fontInSet; +static Choice *choiceList = NULL; +int enabledMenuIndex; +static Boolean patternFieldSpecified[FIELD_COUNT]; /* = 0 */ + +int +main(argc, argv) + int argc; + char **argv; +{ + Widget topLevel, pane; + + XtSetLanguageProc(NULL, (XtLanguageProc) NULL, NULL); + + topLevel = XtAppInitialize(&appCtx, "XFontSel", options, XtNumber(options), + &argc, argv, NULL, NULL, 0); + + if (argc != 1) Syntax(argv[0]); + + XtAppAddActions(appCtx, xfontsel_actions, XtNumber(xfontsel_actions)); + XtOverrideTranslations + (topLevel, XtParseTranslationTable ("<Message>WM_PROTOCOLS: Quit()")); + + XtGetApplicationResources( topLevel, (XtPointer)&AppRes, + resources, XtNumber(resources), NZ ); + if (AppRes.app_defaults_version < MIN_APP_DEFAULTS_VERSION) { + XrmDatabase rdb = XtDatabase(XtDisplay(topLevel)); + XtWarning( "app-defaults file not properly installed." ); + XrmPutLineResource( &rdb, +"*sampleText*UCSLabel:XFontSel app-defaults file not properly installed;\\n\ +see 'xfontsel' manual page." + ); + } + + ScheduleWork(GetFontNames, (XtPointer)XtDisplay(topLevel), 0); + + pane = XtCreateManagedWidget("pane",panedWidgetClass,topLevel,NZ); + { + Widget commandBox, /* fieldBox, currentFontName,*/ viewPort; + + commandBox = XtCreateManagedWidget("commandBox",formWidgetClass,pane,NZ); + { + Widget quitButton /*, ownButton , countLabel*/; + + quitButton = + XtCreateManagedWidget("quitButton",commandWidgetClass,commandBox,NZ); + + ownButton = + XtCreateManagedWidget("ownButton",toggleWidgetClass,commandBox,NZ); + + countLabel = + XtCreateManagedWidget("countLabel",labelWidgetClass,commandBox,NZ); + + XtAddCallback(quitButton, XtNcallback, Quit, NULL); + XtAddCallback(ownButton,XtNcallback,OwnSelection,(XtPointer)True); + } + + fieldBox = XtCreateManagedWidget("fieldBox", boxWidgetClass, pane, NZ); + { + Widget /*dash,*/ field /*[FIELD_COUNT]*/; + int f; + + for (f = 0; f < FIELD_COUNT; f++) { + char name[10]; + FieldMenuRec *makeRec = XtNew(FieldMenuRec); + sprintf( name, "field%d", f ); + XtCreateManagedWidget("dash",labelWidgetClass,fieldBox,NZ); + field = XtCreateManagedWidget(name, menuButtonWidgetClass, + fieldBox, NZ); + XtAddCallback(field, XtNcallback, SelectField, + (XtPointer)(long)f); + makeRec->field = f; + makeRec->button = field; + ScheduleWork(MakeFieldMenu, (XtPointer)makeRec, 2); + ScheduleWork(XtFree, (XtPointer)makeRec, 2); + } + } + + /* currentFontName = */ + { + Arg args[1]; + currentFontNameSize = strlen(AppRes.pattern); + if (currentFontNameSize < 128) currentFontNameSize = 128; + currentFontNameString = (String)XtMalloc(currentFontNameSize); + strcpy(currentFontNameString, AppRes.pattern); + XtSetArg(args[0], XtNlabel, currentFontNameString); + currentFontName = + XtCreateManagedWidget("fontName",labelWidgetClass,pane,args,ONE); + } + + viewPort = + XtCreateManagedWidget("viewPort",viewportWidgetClass,pane,NZ); + { +#ifdef USE_TEXT_WIDGET + Widget text = + XtCreateManagedWidget("sampleText",asciiTextWidgetClass,viewPort,NZ); + Arg args[1]; + XtSetArg( args[0], XtNtextSink, &sampleText ); + XtGetValues( text, args, ONE ); +#else + sampleText = + XtCreateManagedWidget("sampleText",ucsLabelWidgetClass,viewPort,NZ); +#endif + } + } + + XtRealizeWidget(topLevel); + XDefineCursor( XtDisplay(topLevel), XtWindow(topLevel), AppRes.cursor ); + { + int f; + for (f = 0; f < FIELD_COUNT; f++) currentFont.value_index[f] = -1; + } + wm_delete_window = XInternAtom(XtDisplay(topLevel), "WM_DELETE_WINDOW", + False); + (void) XSetWMProtocols (XtDisplay(topLevel), XtWindow(topLevel), + &wm_delete_window, 1); + XtAppMainLoop(appCtx); + + return 0; +} + + +typedef struct WorkPiece WorkPieceRec, *WorkPiece; +struct WorkPiece { + WorkPiece next; + int priority; + XtProc proc; + XtPointer closure; +}; +static WorkPiece workQueue = NULL; + + +/* + * ScheduleWork( XtProc proc, XtPointer closure, int priority ) + * + * Adds a WorkPiece to the workQueue in FIFO order by priority. + * Lower numbered priority work is completed before higher numbered + * priorities. + * + * If the workQueue was previously empty, then makes sure that + * Xt knows we have (background) work to do. + */ + +static void ScheduleWork( proc, closure, priority ) + XtProc proc; + XtPointer closure; + int priority; +{ + WorkPiece piece = XtNew(WorkPieceRec); + + piece->priority = priority; + piece->proc = proc; + piece->closure = closure; + if (workQueue == NULL) { + piece->next = NULL; + workQueue = piece; + XtAppAddWorkProc(appCtx, DoWorkPiece, NULL); + } else { + if (workQueue->priority > priority) { + piece->next = workQueue; + workQueue = piece; + } + else { + WorkPiece n; + for (n = workQueue; n->next && n->next->priority <= priority;) + n = n->next; + piece->next = n->next; + n->next = piece; + } + } +} + +/* ARGSUSED */ +Boolean DoWorkPiece(closure) + XtPointer closure; /* unused */ +{ + WorkPiece piece = workQueue; + + if (piece) { + (*piece->proc)(piece->closure); + workQueue = piece->next; + XtFree((XtPointer)piece); + if (workQueue != NULL) + return False; + } + return True; +} + + +/* + * FinishWork() + * + * Drains foreground tasks from the workQueue. + * Foreground == (priority < BACKGROUND) + */ + +void FinishWork() +{ + while (workQueue && workQueue->priority < BACKGROUND) + DoWorkPiece(NULL); +} + + +typedef struct ParseRec ParseRec; +struct ParseRec { + char **fontNames; + int num_fonts; + int start, end; + FontValues *fonts; + FieldValueList **fieldValues; +}; + + +void GetFontNames( closure ) + XtPointer closure; +{ + Display *dpy = (Display*)closure; + ParseRec *parseRec = XtNew(ParseRec); + int f, field, count; + String *fontNames; + Boolean *b; + int work_priority = 0; + + fontNames = parseRec->fontNames = + XListFonts(dpy, AppRes.pattern, 32767, &numFonts); + + fonts = (FontValues*)XtMalloc( numFonts*sizeof(FontValues) ); + fontInSet = (Boolean*)XtMalloc( numFonts*sizeof(Boolean) ); + for (f = numFonts, b = fontInSet; f; f--, b++) *b = True; + for (field = 0; field < FIELD_COUNT; field++) { + fieldValues[field] = (FieldValueList*)XtMalloc(sizeof(FieldValueList)); + fieldValues[field]->allocated = 1; + fieldValues[field]->count = 0; + } + if (numFonts == 0) { + SetNoFonts(); + return; + } + numBadFonts = 0; + parseRec->fonts = fonts; + parseRec->num_fonts = count = matchingFontCount = numFonts; + parseRec->fieldValues = fieldValues; + parseRec->start = 0; + /* this is bogus; the task should be responsible for quantizing...*/ + while (count > PARSE_QUANTUM) { + ParseRec *prevRec = parseRec; + parseRec->end = parseRec->start + PARSE_QUANTUM; + ScheduleWork(ParseFontNames, (XtPointer)parseRec, work_priority); + ScheduleWork(XtFree, (XtPointer)parseRec, work_priority); + parseRec = XtNew(ParseRec); + *parseRec = *prevRec; + parseRec->start += PARSE_QUANTUM; + parseRec->fonts += PARSE_QUANTUM; + parseRec->fontNames += PARSE_QUANTUM; + count -= PARSE_QUANTUM; + work_priority = 1; + } + parseRec->end = numFonts; + ScheduleWork(ParseFontNames,(XtPointer)parseRec,work_priority); + ScheduleWork((XtProc)XFreeFontNames,(XtPointer)fontNames,work_priority); + ScheduleWork(XtFree, (XtPointer)parseRec, work_priority); + if (AppRes.scaled_fonts) + ScheduleWork(FixScalables,(XtPointer)0,work_priority); + ScheduleWork(SortFields,(XtPointer)0,work_priority); + SetParsingFontCount(matchingFontCount); + if (strcmp(AppRes.pattern, DEFAULTPATTERN)) { + int maxField, f; + for (f = 0; f < numFonts && !IsXLFDFontName(fontNames[f]); f++); + if (f != numFonts) { + if (Matches(AppRes.pattern, fontNames[f], + patternFieldSpecified, &maxField)) { + for (f = 0; f <= maxField; f++) { + if (patternFieldSpecified[f]) + currentFont.value_index[f] = 0; + } + } + else + XtAppWarning( appCtx, + "internal error; pattern didn't match first font" ); + } + else { + SetNoFonts(); + return; + } + } + ScheduleWork(SetCurrentFont, NULL, 1); +} + + +void ParseFontNames( closure ) + XtPointer closure; +{ + ParseRec *parseRec = (ParseRec*)closure; + char **fontNames = parseRec->fontNames; + int num_fonts = parseRec->end; + FieldValueList **fieldValues = parseRec->fieldValues; + FontValues *fontValues = parseRec->fonts - numBadFonts; + int i, font; + + for (font = parseRec->start; font < num_fonts; font++) { + char *p; + int f, len; + FieldValue *v; + + if (!IsXLFDFontName(*fontNames)) { + numFonts--; + numBadFonts++; + continue; + } + + for (f = 0, p = *fontNames++; f < FIELD_COUNT; f++) { + char *fieldP; + + if (*p) ++p; + if (*p == DELIM || *p == '\0') { + fieldP = ""; + len = 0; + } else { + fieldP = p; + while (*p && *++p != DELIM); + len = p - fieldP; + } + for (i=fieldValues[f]->count,v=fieldValues[f]->value; i;i--,v++) { + if (len == 0) { + if (v->string == NULL) break; + } + else + if (v->string && + strncmp( v->string, fieldP, len ) == 0 && + (v->string)[len] == '\0') + break; + } + if (i == 0) { + int count = fieldValues[f]->count++; + if (count == fieldValues[f]->allocated) { + int allocated = (fieldValues[f]->allocated += 10); + fieldValues[f] = (FieldValueList*) + XtRealloc( (char *) fieldValues[f], + sizeof(FieldValueList) + + (allocated-1) * sizeof(FieldValue) ); + } + v = &fieldValues[f]->value[count]; + v->field = f; + if (len == 0) + v->string = NULL; + else { + v->string = (String)XtMalloc( len+1 ); + strncpy( v->string, fieldP, len ); + v->string[len] = '\0'; + } + v->font = (int*)XtMalloc( 10*sizeof(int) ); + v->allocated = 10; + v->count = 0; + v->enable = True; + i = 1; + } + fontValues->value_index[f] = fieldValues[f]->count - i; + if ((i = v->count++) == v->allocated) { + int allocated = (v->allocated += 10); + v->font = (int*)XtRealloc( (char *) v->font, + allocated * sizeof(int) ); + } + v->font[i] = font - numBadFonts; + } + fontValues++; + } + SetParsingFontCount(numFonts - num_fonts); +} + + +/* Add the list of scalable fonts to the match-list of every value instance + * for field f. Must produce sorted order. Must deal with duplicates + * since we need to do this for resolution fields which can be nonzero in + * the scalable fonts. + */ +void AddScalables(f) + int f; +{ + int i; + int max = fieldValues[f]->count; + FieldValue *fval = fieldValues[f]->value; + + for (i = 0; i < max; i++, fval++) { + int *oofonts, *ofonts, *nfonts, *fonts; + int ocount, ncount, count; + + if (fval->string && !strcmp(fval->string, "0")) + continue; + count = numScaledFonts; + fonts = scaledFonts; + ocount = fval->count; + ncount = ocount + count; + nfonts = (int *)XtMalloc( ncount * sizeof(int) ); + oofonts = ofonts = fval->font; + fval->font = nfonts; + fval->count = ncount; + fval->allocated = ncount; + while (count && ocount) { + if (*fonts < *ofonts) { + *nfonts++ = *fonts++; + count--; + } else if (*fonts == *ofonts) { + *nfonts++ = *fonts++; + count--; + ofonts++; + ocount--; + fval->count--; + } else { + *nfonts++ = *ofonts++; + ocount--; + } + } + while (ocount) { + *nfonts++ = *ofonts++; + ocount--; + } + while (count) { + *nfonts++ = *fonts++; + count--; + } + XtFree((char *)oofonts); + } +} + + +/* Merge in specific scaled sizes (specified in a comma-separated string) + * for field f. Weed out duplicates. The set of matching fonts is just + * the set of scalable fonts. + */ +void NewScalables(f, slist) + int f; + char *slist; +{ + char endc = 1; + char *str; + int i, count; + FieldValue *v; + + while (endc) { + while (*slist == ' ' || *slist == ',') + slist++; + if (!*slist) + break; + str = slist; + while ((endc = *slist) && endc != ' ' && endc != ',') + slist++; + *slist++ = '\0'; + for (i=fieldValues[f]->count,v=fieldValues[f]->value; --i >= 0; v++) { + if (v->string && !strcmp(v->string, str)) + break; + } + if (i >= 0) + continue; + count = fieldValues[f]->count++; + if (count == fieldValues[f]->allocated) { + int allocated = (fieldValues[f]->allocated += 10); + fieldValues[f] = (FieldValueList*) + XtRealloc( (char *) fieldValues[f], + sizeof(FieldValueList) + + (allocated-1) * sizeof(FieldValue) ); + } + v = &fieldValues[f]->value[count]; + v->field = f; + v->string = str; + v->count = numScaledFonts; + v->font = scaledFonts; + v->allocated = 0; + v->enable = True; + } +} + + +/* Find all scalable fonts, defined as the set matching "0" in the pixel + * size field (field 6). Augment the match-lists for all other fields + * that are scalable. Add in new scalable pixel and point sizes given + * in resources. + */ +/*ARGSUSED*/ +void FixScalables( closure ) + XtPointer closure; +{ + int i; + FieldValue *fval = fieldValues[6]->value; + + for (i = fieldValues[6]->count; --i >= 0; fval++) { + if (fval->string && !strcmp(fval->string, "0")) { + scaledFonts = fval->font; + numScaledFonts = fval->count; + AddScalables(6); + NewScalables(6, AppRes.pixelSizeList); + AddScalables(7); + NewScalables(7, AppRes.pointSizeList); + AddScalables(8); + AddScalables(9); + AddScalables(11); + break; + } + } +} + + +/* A verbatim copy from xc/lib/font/fontfile/fontdir.c */ + +/* + * Compare two strings just like strcmp, but preserve decimal integer + * sorting order, i.e. "2" < "10" or "iso8859-2" < "iso8859-10" < + * "iso10646-1". Strings are sorted as if sequences of digits were + * prefixed by a length indicator (i.e., does not ignore leading zeroes). + * + * Markus Kuhn <Markus.Kuhn@cl.cam.ac.uk> + */ +#define Xisdigit(c) ('\060' <= (c) && (c) <= '\071') + +static int strcmpn(const char *s1, const char *s2) +{ + int digits, predigits = 0; + const char *ss1, *ss2; + + while (1) { + if (*s1 == 0 && *s2 == 0) + return 0; + digits = Xisdigit(*s1) && Xisdigit(*s2); + if (digits && !predigits) { + ss1 = s1; + ss2 = s2; + while (Xisdigit(*ss1) && Xisdigit(*ss2)) + ss1++, ss2++; + if (!Xisdigit(*ss1) && Xisdigit(*ss2)) + return -1; + if (Xisdigit(*ss1) && !Xisdigit(*ss2)) + return 1; + } + if ((unsigned char)*s1 < (unsigned char)*s2) + return -1; + if ((unsigned char)*s1 > (unsigned char)*s2) + return 1; + predigits = digits; + s1++, s2++; + } +} + + +/* Order is *, (nil), rest */ +int AlphabeticSort(fval1, fval2) + FieldValue *fval1, *fval2; +{ + if (fval1->string && !strcmp(fval1->string, "*")) + return -1; + if (fval2->string && !strcmp(fval2->string, "*")) + return 1; + if (!fval1->string) + return -1; + if (!fval2->string) + return 1; + return strcmpn(fval1->string, fval2->string); +} + + +/* Order is *, (nil), rest */ +int NumericSort(fval1, fval2) + FieldValue *fval1, *fval2; +{ + if (fval1->string && !strcmp(fval1->string, "*")) + return -1; + if (fval2->string && !strcmp(fval2->string, "*")) + return 1; + if (!fval1->string) + return -1; + if (!fval2->string) + return 1; + return atoi(fval1->string) - atoi(fval2->string); +} + + +/* Resort each field, to get reasonable menus. Sort alphabetically or + * numerically, depending on the field. Since the fonts have indexes + * into the fields, we need to deal with updating those indexes after the + * sort. + */ +/*ARGSUSED*/ +void SortFields( closure ) + XtPointer closure; +{ + int i, j, count; + FieldValue *vals; + int *indexes; + int *idx; + + for (i = 0; i < FIELD_COUNT; i++) { + count = fieldValues[i]->count; + vals = fieldValues[i]->value; + indexes = (int *)XtMalloc(count * sizeof(int)); + /* temporarily use the field component, will restore it below */ + for (j = 0; j < count; j++) + vals[j].field = j; + switch (i) { + case 6: case 7: case 8: case 9: case 11: + qsort((char *)vals, count, sizeof(FieldValue), NumericSort); + break; + default: + qsort((char *)vals, count, sizeof(FieldValue), AlphabeticSort); + break; + } + for (j = 0; j < count; j++) { + indexes[vals[j].field] = j; + vals[j].field = i; + } + for (j = 0; j < numFonts; j++) { + idx = &fonts[j].value_index[i]; + if (*idx >= 0) + *idx = indexes[*idx]; + } + XtFree((char *)indexes); + } +} + + +Boolean IsXLFDFontName(fontName) + String fontName; +{ + int f; + for (f = 0; *fontName;) if (*fontName++ == DELIM) f++; + return (f == FIELD_COUNT); +} + + +void MakeFieldMenu(closure) + XtPointer closure; +{ + FieldMenuRec *makeRec = (FieldMenuRec*)closure; + Widget menu; + FieldValueList *values = fieldValues[makeRec->field]; + FieldValue *val = values->value; + int i; + Arg args[1]; + register Widget item; + + if (numFonts) + menu = + XtCreatePopupShell("menu",simpleMenuWidgetClass,makeRec->button,NZ); + else { + SetNoFonts(); + return; + } + XtGetSubresources(menu, (XtPointer) values, "options", "Options", + menuResources, XtNumber(menuResources), NZ); + XtAddCallback(menu, XtNpopupCallback, EnableOtherValues, + (XtPointer)(long)makeRec->field ); + + if (!patternFieldSpecified[val->field]) { + XtSetArg( args[0], XtNlabel, "*" ); + item = XtCreateManagedWidget("any",smeBSBObjectClass,menu,args,ONE); + XtAddCallback(item, XtNcallback, AnyValue, (XtPointer)(long)val->field); + } + + for (i = values->count; i; i--, val++) { + XtSetArg( args[0], XtNlabel, val->string ? val->string : "(nil)" ); + item = + XtCreateManagedWidget(val->string ? val->string : "nil", + smeBSBObjectClass, menu, args, ONE); + XtAddCallback(item, XtNcallback, SelectValue, (XtPointer)val); + val->menu_item = item; + } +} + + +static void SetNoFonts(void) +{ + matchingFontCount = 0; + SetCurrentFontCount(); + XtSetSensitive(fieldBox, False); + XtSetSensitive(ownButton, False); + if (AppRes.app_defaults_version >= MIN_APP_DEFAULTS_VERSION) { +#ifdef USE_TEXT_WIDGET + XtUnmapWidget(XtParent(sampleText)); +#else + XtUnmapWidget(sampleText); +#endif + } +} + + +Boolean Matches(pattern, fontName, fields, maxField) + register String pattern, fontName; + Boolean fields[/*FIELD_COUNT*/]; + int *maxField; +{ + register int field = (*fontName == DELIM) ? -1 : 0; + register Boolean marked_this_field = False; + + while (*pattern) { + if (*pattern == *fontName || *pattern == '?') { + pattern++; + if (*fontName++ == DELIM) { + field++; + marked_this_field = False; + } + else if (!marked_this_field) + fields[field] = marked_this_field = True; + continue; + } + if (*pattern == '*') { + if (*++pattern == '\0') { + *maxField = field; + return True; + } + while (*fontName) { + Boolean field_bits[FIELD_COUNT]; + int max_field; + if (*fontName == DELIM) field++; + bzero( field_bits, sizeof(field_bits) ); + if (Matches(pattern, fontName++, field_bits, &max_field)) { + int f; + *maxField = field + max_field; + for (f = 0; f <= max_field; field++, f++) + fields[field] = field_bits[f]; + return True; + } + } + return False; + } + else /* (*pattern != '*') */ + return False; + } + if (*fontName) + return False; + + *maxField = field; + return True; +} + + +/* ARGSUSED */ +void SelectValue(w, closure, callData) + Widget w; + XtPointer closure, callData; +{ + FieldValue *val = (FieldValue*)closure; +#ifdef LOG_CHOICES + Choice *choice = XtNew(Choice); +#else + static Choice pChoice; + Choice *choice = &pChoice; +#endif + +#ifdef notdef + Widget button = XtParent(XtParent(w)); + Arg args[1]; + + XtSetArg(args[0], XtNlabel, val->string); + XtSetValues( button, args, ONE ); +#endif + + currentFont.value_index[val->field] = val - fieldValues[val->field]->value; + + choice->prev = choiceList; + choice->value = val; + choiceList = choice; + + SetCurrentFont(NULL); + EnableRemainingItems(SkipCurrentField); +} + + +/* ARGSUSED */ +void AnyValue(w, closure, callData) + Widget w; + XtPointer closure, callData; +{ + int field = (long)closure; + currentFont.value_index[field] = -1; + SetCurrentFont(NULL); + EnableAllItems(field); + EnableRemainingItems(ValidateCurrentField); +} + + +static void SetCurrentFontCount(void) +{ + char label[80]; + Arg args[1]; + if (matchingFontCount == 1) + strcpy( label, "1 name matches" ); + else if (matchingFontCount) + sprintf( label, "%d names match", matchingFontCount ); + else + strcpy( label, "no names match" ); + XtSetArg( args[0], XtNlabel, label ); + XtSetValues( countLabel, args, ONE ); +} + + +static void SetParsingFontCount(int count) +{ + char label[80]; + Arg args[1]; + if (count == 1) + strcpy( label, "1 name to parse" ); + else + sprintf( label, "%d names to parse", count ); + XtSetArg( args[0], XtNlabel, label ); + XtSetValues( countLabel, args, ONE ); + FlushXqueue(XtDisplay(countLabel)); +} + +/* ARGSUSED */ +static Boolean IsISO10646(dpy, font) + Display *dpy; + XFontStruct *font; +{ + Boolean ok; + int i; + char *regname; + Atom registry; + XFontProp *xfp; + + ok = False; + registry = XInternAtom(dpy, "CHARSET_REGISTRY", False); + + for (i = 0, xfp = font->properties; + ok == False && i < font->n_properties; xfp++, i++) { + if (xfp->name == registry) { + regname = XGetAtomName(dpy, (Atom) xfp->card32); + if (strcmp(regname, "ISO10646") == 0 || + strcmp(regname, "iso10646") == 0) + ok = True; + XFree(regname); + } + } + return ok; +} + +/* ARGSUSED */ +void SetCurrentFont(closure) + XtPointer closure; /* unused */ +{ + int f; + Boolean *b; + + if (numFonts == 0) { + SetNoFonts(); + return; + } + for (f = numFonts, b = fontInSet; f; f--, b++) *b = True; + + { + int bytesLeft = currentFontNameSize; + int pos = 0; + + for (f = 0; f < FIELD_COUNT; f++) { + int len, i; + String str; + + currentFontNameString[pos++] = DELIM; + if ((i = currentFont.value_index[f]) != -1) { + FieldValue *val = &fieldValues[f]->value[i]; + if ((str = val->string)) + len = strlen(str); + else { + str = ""; + len = 0; + } + MarkInvalidFonts(fontInSet, val); + } else { + str = "*"; + len = 1; + } + if (len+1 > --bytesLeft) { + currentFontNameString = (String) + XtRealloc(currentFontNameString, currentFontNameSize+=128); + bytesLeft += 128; + } + strcpy( ¤tFontNameString[pos], str ); + pos += len; + bytesLeft -= len; + } + } + { + Arg args[1]; + XtSetArg( args[0], XtNlabel, currentFontNameString ); + XtSetValues( currentFontName, args, ONE ); + } + matchingFontCount = 0; + for (f = numFonts, b = fontInSet; f; f--, b++) { + if (*b) matchingFontCount++; + } + + SetCurrentFontCount(); + + { +#ifdef USE_TEXT_WIDGET + Widget mapWidget = XtParent(sampleText); +#else + Widget mapWidget = sampleText; +#endif + Display *dpy = XtDisplay(mapWidget); + XFontStruct *font = XLoadQueryFont(dpy, currentFontNameString); + String sample_text; + if (font == NULL) + XtUnmapWidget(mapWidget); + else { + int nargs = 1; + Arg args[3]; + int encoding; + if (font->min_byte1 || font->max_byte1) { + if (IsISO10646(dpy, font) == True) { + encoding = XawTextEncodingUCS; + sample_text = AppRes.sample_textUCS; + } else { + encoding = XawTextEncodingChar2b; + sample_text = AppRes.sample_text16; + } + } else { + encoding = XawTextEncoding8bit; + sample_text = AppRes.sample_text; + } + XtSetArg( args[0], XtNfont, font ); + if (encoding != textEncoding) { + XtSetArg(args[1], XtNencoding, encoding); + XtSetArg(args[2], XtNlabel, sample_text); + textEncoding = encoding; + nargs = 3; + } + XtSetValues( sampleText, args, nargs ); + XtMapWidget(mapWidget); + if (sampleFont) XFreeFont( dpy, sampleFont ); + sampleFont = font; + OwnSelection( sampleText, (XtPointer)False, (XtPointer)True ); + } + FlushXqueue(dpy); + } +} + + +static void MarkInvalidFonts( set, val ) + Boolean *set; + FieldValue *val; +{ + int fi = 0, vi; + int *fp = val->font; + for (vi = val->count; vi; vi--, fp++) { + while (fi < *fp) { + set[fi] = False; + fi++; + } + fi++; + } + while (fi < numFonts) { + set[fi] = False; + fi++; + } +} + + +static void EnableRemainingItems(current_field_action) + ValidateAction current_field_action; +{ + if (matchingFontCount == 0 || matchingFontCount == numFonts) { + if (anyDisabled) { + int field; + for (field = 0; field < FIELD_COUNT; field++) { + EnableAllItems(field); + } + anyDisabled = False; + } + } + else { + int field; + for (field = 0; field < FIELD_COUNT; field++) { + FieldValue *value = fieldValues[field]->value; + int count; + if (current_field_action == SkipCurrentField && + field == choiceList->value->field) + continue; + for (count = fieldValues[field]->count; count; count--, value++) { + int *fp = value->font; + int fontCount; + for (fontCount = value->count; fontCount; fontCount--, fp++) { + if (fontInSet[*fp]) { + value->enable = True; + goto NextValue; + } + } + value->enable = False; + NextValue:; + } + } + anyDisabled = True; + } + enabledMenuIndex = -1; + { + int f; + for (f = 0; f < FIELD_COUNT; f++) + ScheduleWork(EnableMenu, (XtPointer)(long)f, BACKGROUND); + } +} + + +static void EnableAllItems(int field) +{ + FieldValue *value = fieldValues[field]->value; + int count; + for (count = fieldValues[field]->count; count; count--, value++) { + value->enable = True; + } +} + + +/* ARGSUSED */ +void SelectField(w, closure, callData) + Widget w; + XtPointer closure, callData; +{ + int field = (long)closure; + FieldValue *values = fieldValues[field]->value; + int count = fieldValues[field]->count; + printf( "field %d:\n", field ); + while (count--) { + printf( " %s: %d fonts\n", values->string, values->count ); + values++; + } + printf( "\n" ); +} + + +/* When 2 out of 3 y-related scalable fields are set, we need to restrict + * the third set to only match on exact matches, that is, ignore the + * matching to scalable fonts. Because choosing a random third value + * will almost always produce an illegal font name, and it isn't worth + * trying to compute which choices might be legal to the font scaler. + */ +void DisableScaled(f, f1, f2) + int f, f1, f2; +{ + int i, j; + FieldValue *v; + int *font; + + for (i = fieldValues[f]->count, v = fieldValues[f]->value; --i >= 0; v++) { + if (!v->enable || !v->string || !strcmp(v->string, "0")) + continue; + for (j = v->count, font = v->font; --j >= 0; font++) { + if (fontInSet[*font] && + fonts[*font].value_index[f1] == currentFont.value_index[f1] && + fonts[*font].value_index[f2] == currentFont.value_index[f2]) + break; + } + if (j < 0) { + v->enable = False; + XtSetSensitive(v->menu_item, False); + } + } +} + +/* ARGSUSED */ +void EnableOtherValues(w, closure, callData) + Widget w; + XtPointer closure, callData; +{ + int field = (long)closure; + Boolean *font_in_set = (Boolean*)XtMalloc(numFonts*sizeof(Boolean)); + Boolean *b; + int f, count; + + FinishWork(); + for (f = numFonts, b = font_in_set; f; f--, b++) *b = True; + for (f = 0; f < FIELD_COUNT; f++) { + int i; + if (f != field && (i = currentFont.value_index[f]) != -1) { + MarkInvalidFonts( font_in_set, &fieldValues[f]->value[i] ); + } + } + if (scaledFonts) + { + /* Check for 2 out of 3 scalable y fields being set */ + char *str; + Bool specificPxl, specificPt, specificY; + + f = currentFont.value_index[6]; + specificPxl = (f >= 0 && + (str = fieldValues[6]->value[f].string) && + strcmp(str, "0")); + f = currentFont.value_index[7]; + specificPt = (f >= 0 && + (str = fieldValues[7]->value[f].string) && + strcmp(str, "0")); + f = currentFont.value_index[9]; + specificY = (f >= 0 && + (str = fieldValues[9]->value[f].string) && + strcmp(str, "0")); + if (specificPt && specificY) + DisableScaled(6, 7, 9); + if (specificPxl && specificY) + DisableScaled(7, 6, 9); + if (specificPxl && specificPt) + DisableScaled(9, 6, 7); + } + count = 0; + for (f = numFonts, b = font_in_set; f; f--, b++) { + if (*b) count++; + } + if (count != matchingFontCount) { + Boolean *sp = fontInSet; + FieldValueList *fieldValue = fieldValues[field]; + for (b = font_in_set, f = 0; f < numFonts; f++, b++, sp++) { + if (*b != *sp) { + int i = fonts[f].value_index[field]; + FieldValue *val = &fieldValue->value[i]; + val->enable = True; + XtSetSensitive(val->menu_item, True); + if (++count == matchingFontCount) break; + } + } + } + XtFree((char *)font_in_set); + if (enabledMenuIndex < field) + EnableMenu((XtPointer)(long)field); +} + + +void EnableMenu(closure) + XtPointer closure; +{ + int field = (long)closure; + FieldValue *val = fieldValues[field]->value; + int f; + Widget *managed = NULL, *pManaged = NULL; + Widget *unmanaged = NULL, *pUnmanaged = NULL; + Boolean showUnselectable = fieldValues[field]->show_unselectable; + + for (f = fieldValues[field]->count; f; f--, val++) { + if (showUnselectable) { + if (val->enable != XtIsSensitive(val->menu_item)) + XtSetSensitive(val->menu_item, val->enable); + } + else { + if (val->enable != XtIsManaged(val->menu_item)) { + if (val->enable) { + if (managed == NULL) { + managed = (Widget*) + XtMalloc(fieldValues[field]->count*sizeof(Widget)); + pManaged = managed; + } + *pManaged++ = val->menu_item; + } + else { + if (unmanaged == NULL) { + unmanaged = (Widget*) + XtMalloc(fieldValues[field]->count*sizeof(Widget)); + pUnmanaged = unmanaged; + } + *pUnmanaged++ = val->menu_item; + } + } + } + } + if (pManaged != managed) { + XtManageChildren(managed, pManaged - managed); + XtFree((char *) managed); + } + if (pUnmanaged != unmanaged) { + XtUnmanageChildren(unmanaged, pUnmanaged - unmanaged); + XtFree((char *) unmanaged); + } + enabledMenuIndex = field; +} + + +static void FlushXqueue(dpy) + Display *dpy; +{ + XSync(dpy, False); + while (XtAppPending(appCtx)) XtAppProcessEvent(appCtx, XtIMAll); +} + + +/* ARGSUSED */ +void Quit(w, closure, callData) + Widget w; + XtPointer closure, callData; +{ + XtCloseDisplay(XtDisplay(w)); + if (AppRes.print_on_quit) printf( "%s", currentFontNameString ); + exit(0); +} + + +Boolean ConvertSelection(w, selection, target, type, value, length, format) + Widget w; + Atom *selection, *target, *type; + XtPointer *value; + unsigned long *length; + int *format; +{ + /* XmuConvertStandardSelection will use the second parameter only when + * converting to the target TIMESTAMP. However, it will never be + * called upon to perform this conversion, because Xt will handle it + * internally. CurrentTime will never be used. + */ + if (XmuConvertStandardSelection(w, CurrentTime, selection, target, type, + (XPointer *) value, length, format)) + return True; + + if (*target == XA_STRING) { + *type = XA_STRING; + *value = currentFontNameString; + *length = strlen(*value); + *format = 8; + return True; + } + else { + return False; + } +} + +static AtomPtr _XA_PRIMARY_FONT = NULL; +#define XA_PRIMARY_FONT XmuInternAtom(XtDisplay(w),_XA_PRIMARY_FONT) + +/* ARGSUSED */ +void LoseSelection(w, selection) + Widget w; + Atom *selection; +{ + Arg args[1]; + XtSetArg( args[0], XtNstate, False ); + XtSetValues( w, args, ONE ); + if (*selection == XA_PRIMARY_FONT) { + XtSetSensitive(currentFontName, False); + } +} + + +/* ARGSUSED */ +void DoneSelection(w, selection, target) + Widget w; + Atom *selection, *target; +{ + /* do nothing */ +} + + +/* ARGSUSED */ +void OwnSelection(w, closure, callData) + Widget w; + XtPointer closure, callData; +{ + Time time = XtLastTimestampProcessed(XtDisplay(w)); + Boolean primary = (Boolean) (long) closure; + Boolean own = (Boolean) (long) callData; + + if (_XA_PRIMARY_FONT == NULL) + _XA_PRIMARY_FONT = XmuMakeAtom("PRIMARY_FONT"); + + if (own) { + XtOwnSelection( w, XA_PRIMARY_FONT, time, + ConvertSelection, LoseSelection, DoneSelection ); + if (primary) + XtOwnSelection( w, XA_PRIMARY, time, + ConvertSelection, LoseSelection, DoneSelection ); + if (!XtIsSensitive(currentFontName)) { + XtSetSensitive(currentFontName, True); + } + } + else { + XtDisownSelection(w, XA_PRIMARY_FONT, time); + if (primary) + XtDisownSelection(w, XA_PRIMARY, time); + XtSetSensitive(currentFontName, False); + } +} + +void +QuitAction () +{ + exit (0); +} diff --git a/xfontsel.man b/xfontsel.man new file mode 100644 index 0000000..cc31c73 --- /dev/null +++ b/xfontsel.man @@ -0,0 +1,229 @@ +.\" $XConsortium: xfontsel.man,v 1.14 94/06/10 14:39:10 gildea Exp $ +.\" Copyright (c) 1994 X Consortium +.\" +.\" Permission is hereby granted, free of charge, to any person obtaining +.\" a copy of this software and associated documentation files (the +.\" "Software"), to deal in the Software without restriction, including +.\" without limitation the rights to use, copy, modify, merge, publish, +.\" distribute, sublicense, and/or sell copies of the Software, and to +.\" permit persons to whom the Software is furnished to do so, subject to +.\" the following conditions: +.\" +.\" The above copyright notice and this permission notice shall be included +.\" in all copies or substantial portions of the Software. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +.\" IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +.\" OTHER DEALINGS IN THE SOFTWARE. +.\" +.\" Except as contained in this notice, the name of the X Consortium shall +.\" not be used in advertising or otherwise to promote the sale, use or +.\" other dealings in this Software without prior written authorization +.\" from the X Consortium. +.\" +.\" $XFree86: xc/programs/xfontsel/xfontsel.man,v 1.4 2002/10/12 16:06:48 herrb Exp $ +.de EX \"Begin example +.ne 5 +.if n .sp 1 +.if t .sp .5 +.nf +.in +.5i +.. +.de EE +.fi +.in -.5i +.if n .sp 1 +.if t .sp .5 +.. +.TH XFONTSEL 1 __xorgversion__ +.SH NAME +xfontsel \- point and click selection of X11 font names +.SH SYNTAX +.PP +\fBxfontsel\fP [-\fItoolkitoption\fP ...] +[\fB-pattern \fIfontname\fP] +[\fB-print\fP] +[\fB-sample \fItext\fP] +[\fB-sample16 \fItext16\fP] +[\fB-sampleUCS \fItextUCS\fP] +[\fB-scaled\fP] +.PP +.SH DESCRIPTION +.PP +The \fIxfontsel\fP application provides a simple way to display +the fonts known to your X server, examine samples of each, and +retrieve the X Logical Font Description ("XLFD") full name for a font. +.PP +If \fB-pattern\fP is not specified, all fonts with XLFD 14-part +names will be selectable. To work with only a subset of the +fonts, specify \fB-pattern\fP followed by a partially or fully +qualified font name; e.g., ``-pattern *medium*'' will +select that subset of fonts which contain the string ``medium'' +somewhere in their font name. Be careful about escaping +wildcard characters in your shell. +.PP +If \fB-print\fP is specified on the command line the selected +font specifier will be written to standard output when the \fIquit\fP +button is activated. Regardless of whether or not \fB-print\fP was +specified, the font specifier may be made the PRIMARY (text) +selection by activating the \fIselect\fP button. +.PP +The \fB-sample\fP option specifies the sample text to be used to +display the selected font if the font is linearly indexed, +overriding the default. +.PP +The \fB-sample16\fP option specifies the sample text to be used to +display the selected font if the font is matrix encoded, +overriding the default. +.PP +The \fB-sampleUCS\fP option specifies the sample text encoded in the UTF-8 +form to be used to display the selected font if the font has a +CHARSET_REGISTRY of ISO10646, overriding the default. +.PP +The \fB-scaled\fP option enables the ability to select scaled fonts +at arbitrary pixel or point sizes. +.PP +.SH INTERACTIONS +.PP +Clicking any pointer button in one of the XLFD field names will pop up +a menu of the currently-known possibilities for that field. If +previous choices of other fields were made, only values +for fonts which matched the previously selected fields will be +selectable; to make other values selectable, you must deselect +some other field(s) by choosing the ``*'' entry in that field. +Unselectable values may be omitted from the menu entirely as +a configuration option; see the \fBShowUnselectable\fP resource, below. +Whenever any change is made to a field value, \fIxfontsel\fP will +assert ownership of the PRIMARY_FONT selection. Other applications +(see, e.g., \fIxterm\fP) may then retrieve the selected font specification. +.PP +Scalable fonts come back from the server with zero for the pixel size, +point size, and average width fields. Selecting a font name with a +zero in these positions results in an implementation-dependent size. +Any pixel or point size can be selected to scale the font to a particular +size. Any average width can be selected to anamorphically scale the font +(although you may find this challenging given the size of the average +width menu). +.PP +Clicking the left pointer button in the \fIselect\fP widget will +cause the currently selected font name to become the PRIMARY text +selection as well as the PRIMARY_FONT selection. +This then allows you to paste the string into other +applications. The \fBselect\fP button remains +highlighted to remind you of this fact, and de-highlights when +some other application takes the PRIMARY selection away. The +\fIselect\fP widget is a toggle; pressing it when it is highlighted +will cause \fIxfontsel\fP to release the selection ownership and +de-highlight the widget. Activating the \fIselect\fP widget twice +is the only way to cause \fIxfontsel\fP to release the +PRIMARY_FONT selection. +.PP +.SH RESOURCES +.PP +The application class is \fBXFontSel\fP. Most of the user-interface +is configured in the app-defaults file; if this file is missing +a warning message will be printed to standard output and the +resulting window will be nearly incomprehensible. +.PP +Most of the significant parts of the widget hierarchy are documented +in +.IR __apploaddir__/XFontSel , +.PP +Application specific resources: +.PP +.TP 8 +.B "cursor (\fPclass\fB Cursor)" +Specifies the cursor for the application window. +.TP 8 +.B "pattern (\fPclass\fB Pattern)" +Specifies the font name pattern for selecting a subset of +available fonts. Equivalent to the \fB-pattern\fP option. +Most useful patterns will contain at least one field +delimiter; e.g. ``*-m-*'' for monospaced fonts. +.TP 8 +.B "pixelSizeList (\fPclass\fB PixelSizeList)" +Specifies a list of pixel sizes to add to the pixel size menu, +so that scalable fonts can be selected at those pixel sizes. +The default pixelSizeList contains 7, 30, 40, 50, and 60. +.TP 8 +.B "pointSizeList (\fPclass\fB PointSizeList)" +Specifies a list of point sizes (in units of tenths of points) to add to +the point size menu, so that scalable fonts can be selected at those +point sizes. The default pointSizeList contains 250, 300, 350, and 400. +.TP 8 +.B "printOnQuit (\fPclass\fB PrintOnQuit)" +If \fITrue\fP the currently selected font name is printed +to standard output when the quit button is activated. +Equivalent to the \fB-print\fP option. +.TP 8 +.B "sampleText (\fPclass\fB Text)" +The sample 1-byte text to use for linearly indexed fonts. +Each glyph index is a single byte, with newline separating lines. +.TP 8 +.B "sampleText16 (\fPclass\fB Text16)" +The sample 2-byte text to use for matrix-encoded fonts. +Each glyph index is two bytes, with a 1-byte newline separating lines. +.TP 8 +.B "scaledFonts (\fPclass\fB ScaledFonts)" +If \fITrue\fP then selection of arbitrary pixel and point sizes for +scalable fonts is enabled. +.PP +Widget specific resources: +.PP +.TP 8 +.B "showUnselectable (\fPclass\fB ShowUnselectable)" +Specifies, for each field menu, whether or not to show values that +are not currently selectable, based upon previous field selections. +If shown, the unselectable values are clearly identified as such +and do not highlight when the pointer is moved down the menu. +The full name of this resource is \fBfieldN.menu.options.showUnselectable\fP, +class \fBMenuButton.SimpleMenu.Options.ShowUnselectable\fP; +where N is replaced with the field +number (starting with the left-most field numbered 0). +The default is True for all but field 11 (average width of characters +in font) and False for field 11. If you never want to see +unselectable entries, '*menu.options.showUnselectable:False' is +a reasonable thing to specify in a resource file. +.PP +.SH FILES +.PP + $XFILESEARCHPATH/XFontSel +.PP +.SH SEE ALSO +xrdb(1), xfd(1) +.PP +.SH BUGS +.PP +Sufficiently ambiguous patterns can be misinterpreted and lead to an +initial selection string which may not correspond to what the user intended +and which may cause the initial sample text output to fail to match +the proffered string. Selecting any new field value will correct the +sample output, though possibly resulting in no matching font. +.PP +Should be able to return a FONT for the PRIMARY selection, not +just a STRING. +.PP +Any change in a field value will cause \fIxfontsel\fP to assert +ownership of the PRIMARY_FONT selection. Perhaps this should +be parameterized. +.PP +When running on a slow machine, it is possible for the user to +request a field menu before the font names have been completely +parsed. An error message indicating a missing menu is printed +to stderr but otherwise nothing bad (or good) happens. +.PP +The average-width menu is too large to be useful. +.SH COPYRIGHT +Copyright 1989, 1991, X Consortium +.br +See \fIX(__miscmansuffix__)\fP for a full statement of rights and permissions. +.SH AUTHOR +.PP +Ralph R. Swick, Digital Equipment Corporation/MIT Project Athena +.br +Mark Leisher <mleisher@crl.nmsu.edu> added the support for the UTF-8 sample +text. |