summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ULabel.c864
-rw-r--r--ULabel.h141
-rw-r--r--ULabelP.h129
-rw-r--r--XFontSel.ad148
-rw-r--r--xfontsel.c1532
-rw-r--r--xfontsel.man229
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( &currentFontNameString[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.