summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatt Turner <mattst88@gmail.com>2011-08-01 21:22:31 -0400
committerMatt Turner <mattst88@gmail.com>2011-08-01 21:22:31 -0400
commit9814d1217f19449b59ff0c1de1b8e7850e95d0fa (patch)
treeb2832ae672ce14807efe23d3be12418595b5d88d /src
parent7bbcf240f6c6999715db6e1f4c530939cf91340e (diff)
Move sources to src/.
Signed-off-by: Matt Turner <mattst88@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/AllWidgets.c124
-rw-r--r--src/AllWidgets.h37
-rw-r--r--src/AsciiSink.c693
-rw-r--r--src/AsciiSink.h91
-rw-r--r--src/AsciiSinkP.h118
-rw-r--r--src/AsciiSrc.c1438
-rw-r--r--src/AsciiSrc.h162
-rw-r--r--src/AsciiSrcP.h163
-rw-r--r--src/AsciiText.c347
-rw-r--r--src/AsciiText.h151
-rw-r--r--src/AsciiTextP.h166
-rw-r--r--src/Box.c622
-rw-r--r--src/Box.h98
-rw-r--r--src/BoxP.h108
-rw-r--r--src/Cardinals.h44
-rw-r--r--src/Command.c629
-rw-r--r--src/Command.h118
-rw-r--r--src/CommandP.h143
-rw-r--r--src/Dialog.c448
-rw-r--r--src/Dialog.h109
-rw-r--r--src/DialogP.h98
-rw-r--r--src/Form.c848
-rw-r--r--src/Form.h168
-rw-r--r--src/FormP.h143
-rw-r--r--src/Grip.c150
-rw-r--r--src/Grip.h105
-rw-r--r--src/GripP.h105
-rw-r--r--src/Imakefile157
-rw-r--r--src/Imakefrag.X11R533
-rw-r--r--src/Label.c871
-rw-r--r--src/Label.h131
-rw-r--r--src/LabelP.h137
-rw-r--r--src/Layout.c1049
-rw-r--r--src/Layout.h94
-rw-r--r--src/LayoutP.h232
-rw-r--r--src/List.c1230
-rw-r--r--src/List.h239
-rw-r--r--src/ListP.h119
-rw-r--r--src/MenuButtoP.h102
-rw-r--r--src/MenuButton.c221
-rw-r--r--src/MenuButton.h90
-rw-r--r--src/MultiSink.c780
-rw-r--r--src/MultiSink.h118
-rw-r--r--src/MultiSinkP.h157
-rw-r--r--src/MultiSrc.c1461
-rw-r--r--src/MultiSrc.h151
-rw-r--r--src/MultiSrcP.h194
-rw-r--r--src/Paned.c1947
-rw-r--r--src/Paned.h256
-rw-r--r--src/PanedP.h193
-rw-r--r--src/Panner.c975
-rw-r--r--src/Panner.h108
-rw-r--r--src/PannerP.h104
-rw-r--r--src/Porthole.c366
-rw-r--r--src/Porthole.h64
-rw-r--r--src/PortholeP.h65
-rw-r--r--src/README.XAW3D544
-rw-r--r--src/Repeater.c278
-rw-r--r--src/Repeater.h77
-rw-r--r--src/RepeaterP.h82
-rw-r--r--src/Reports.h55
-rw-r--r--src/Scrollbar.c1169
-rw-r--r--src/Scrollbar.h146
-rw-r--r--src/ScrollbarP.h122
-rw-r--r--src/Simple.c299
-rw-r--r--src/Simple.h105
-rw-r--r--src/SimpleMenP.h113
-rw-r--r--src/SimpleMenu.c1673
-rw-r--r--src/SimpleMenu.h159
-rw-r--r--src/SimpleP.h89
-rw-r--r--src/Sme.c246
-rw-r--r--src/Sme.h81
-rw-r--r--src/SmeBSB.c877
-rw-r--r--src/SmeBSB.h111
-rw-r--r--src/SmeBSBP.h120
-rw-r--r--src/SmeLine.c294
-rw-r--r--src/SmeLine.h79
-rw-r--r--src/SmeLineP.h97
-rw-r--r--src/SmeP.h107
-rw-r--r--src/SmeThreeD.c596
-rw-r--r--src/SmeThreeD.h96
-rw-r--r--src/SmeThreeDP.h82
-rw-r--r--src/StripCharP.h109
-rw-r--r--src/StripChart.c556
-rw-r--r--src/StripChart.h118
-rw-r--r--src/Template.c94
-rw-r--r--src/Template.h71
-rw-r--r--src/TemplateP.h64
-rw-r--r--src/Text.c3600
-rw-r--r--src/Text.h310
-rw-r--r--src/TextAction.c2327
-rw-r--r--src/TextP.h290
-rw-r--r--src/TextPop.c1434
-rw-r--r--src/TextSink.c779
-rw-r--r--src/TextSink.h317
-rw-r--r--src/TextSinkP.h143
-rw-r--r--src/TextSrc.c676
-rw-r--r--src/TextSrc.h237
-rw-r--r--src/TextSrcP.h164
-rw-r--r--src/TextTr.c147
-rw-r--r--src/ThreeD.c839
-rw-r--r--src/ThreeD.h119
-rw-r--r--src/ThreeDP.h77
-rw-r--r--src/Tip.c718
-rw-r--r--src/Tip.h135
-rw-r--r--src/TipP.h76
-rw-r--r--src/Toggle.c619
-rw-r--r--src/Toggle.h177
-rw-r--r--src/ToggleP.h113
-rw-r--r--src/Tree.c1008
-rw-r--r--src/Tree.h125
-rw-r--r--src/TreeP.h132
-rw-r--r--src/Vendor.c604
-rw-r--r--src/VendorEP.h81
-rw-r--r--src/Viewport.c1200
-rw-r--r--src/Viewport.h124
-rw-r--r--src/ViewportP.h108
-rw-r--r--src/Xaw3dP.c212
-rw-r--r--src/Xaw3dP.h.sed83
-rw-r--r--src/XawI18n.c88
-rw-r--r--src/XawI18n.h78
-rw-r--r--src/XawIm.c1716
-rw-r--r--src/XawImP.h240
-rw-r--r--src/XawInit.c49
-rw-r--r--src/XawInit.h31
-rw-r--r--src/laygram.y263
-rw-r--r--src/laylex.l127
-rw-r--r--src/sharedlib.c192
128 files changed, 47537 insertions, 0 deletions
diff --git a/src/AllWidgets.c b/src/AllWidgets.c
new file mode 100644
index 0000000..0dc7e16
--- /dev/null
+++ b/src/AllWidgets.c
@@ -0,0 +1,124 @@
+/* $XConsortium: AllWidgets.c,v 1.8 94/04/17 20:11:39 kaleb Exp $ */
+
+/*
+
+Copyright (c) 1991, 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.
+
+*/
+
+#include <X11/IntrinsicP.h>
+#include <X11/Xmu/WidgetNode.h>
+
+extern WidgetClass applicationShellWidgetClass;
+extern WidgetClass asciiSinkObjectClass;
+extern WidgetClass asciiSrcObjectClass;
+extern WidgetClass asciiTextWidgetClass;
+extern WidgetClass boxWidgetClass;
+extern WidgetClass commandWidgetClass;
+extern WidgetClass compositeWidgetClass;
+extern WidgetClass constraintWidgetClass;
+extern WidgetClass coreWidgetClass;
+extern WidgetClass dialogWidgetClass;
+extern WidgetClass formWidgetClass;
+extern WidgetClass gripWidgetClass;
+extern WidgetClass labelWidgetClass;
+extern WidgetClass layoutWidgetClass;
+extern WidgetClass listWidgetClass;
+extern WidgetClass menuButtonWidgetClass;
+extern WidgetClass objectClass;
+extern WidgetClass overrideShellWidgetClass;
+extern WidgetClass panedWidgetClass;
+extern WidgetClass pannerWidgetClass;
+extern WidgetClass portholeWidgetClass;
+extern WidgetClass rectObjClass;
+extern WidgetClass repeaterWidgetClass;
+extern WidgetClass scrollbarWidgetClass;
+extern WidgetClass shellWidgetClass;
+extern WidgetClass simpleMenuWidgetClass;
+extern WidgetClass simpleWidgetClass;
+extern WidgetClass smeBSBObjectClass;
+extern WidgetClass smeLineObjectClass;
+extern WidgetClass smeObjectClass;
+extern WidgetClass smeThreeDObjectClass;
+extern WidgetClass stripChartWidgetClass;
+extern WidgetClass textSinkObjectClass;
+extern WidgetClass textSrcObjectClass;
+extern WidgetClass textWidgetClass;
+extern WidgetClass threeDWidgetClass;
+extern WidgetClass toggleWidgetClass;
+extern WidgetClass topLevelShellWidgetClass;
+extern WidgetClass transientShellWidgetClass;
+extern WidgetClass treeWidgetClass;
+extern WidgetClass vendorShellWidgetClass;
+extern WidgetClass viewportWidgetClass;
+extern WidgetClass wmShellWidgetClass;
+
+XmuWidgetNode XawWidgetArray[] = {
+{ "applicationShell", &applicationShellWidgetClass },
+{ "asciiSink", &asciiSinkObjectClass },
+{ "asciiSrc", &asciiSrcObjectClass },
+{ "asciiText", &asciiTextWidgetClass },
+{ "box", &boxWidgetClass },
+{ "command", &commandWidgetClass },
+{ "composite", &compositeWidgetClass },
+{ "constraint", &constraintWidgetClass },
+{ "core", &coreWidgetClass },
+{ "dialog", &dialogWidgetClass },
+{ "form", &formWidgetClass },
+{ "grip", &gripWidgetClass },
+{ "label", &labelWidgetClass },
+{ "layout", &layoutWidgetClass },
+{ "list", &listWidgetClass },
+{ "menuButton", &menuButtonWidgetClass },
+{ "object", &objectClass },
+{ "overrideShell", &overrideShellWidgetClass },
+{ "paned", &panedWidgetClass },
+{ "panner", &pannerWidgetClass },
+{ "porthole", &portholeWidgetClass },
+{ "rect", &rectObjClass },
+{ "repeater", &repeaterWidgetClass },
+{ "scrollbar", &scrollbarWidgetClass },
+{ "shell", &shellWidgetClass },
+{ "simpleMenu", &simpleMenuWidgetClass },
+{ "simple", &simpleWidgetClass },
+{ "smeBSB", &smeBSBObjectClass },
+{ "smeLine", &smeLineObjectClass },
+{ "smeThreeD", &smeThreeDObjectClass },
+{ "sme", &smeObjectClass },
+{ "stripChart", &stripChartWidgetClass },
+{ "textSink", &textSinkObjectClass },
+{ "textSrc", &textSrcObjectClass },
+{ "text", &textWidgetClass },
+{ "threeD", &threeDWidgetClass },
+{ "toggle", &toggleWidgetClass },
+{ "topLevelShell", &topLevelShellWidgetClass },
+{ "transientShell", &transientShellWidgetClass },
+{ "tree", &treeWidgetClass },
+{ "vendorShell", &vendorShellWidgetClass },
+{ "viewport", &viewportWidgetClass },
+{ "wmShell", &wmShellWidgetClass },
+};
+
+int XawWidgetCount = XtNumber(XawWidgetArray);
+
diff --git a/src/AllWidgets.h b/src/AllWidgets.h
new file mode 100644
index 0000000..c71aa91
--- /dev/null
+++ b/src/AllWidgets.h
@@ -0,0 +1,37 @@
+/*
+ * $XConsortium: AllWidgets.h,v 1.3 94/04/17 20:11:40 jim Exp $
+ *
+Copyright (c) 1990 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.
+ */
+
+#ifndef _XawAllWidgets_h
+#define _XawAllWidgets_h
+
+/*
+ * This file matches the generated AllWidgets.c
+ */
+extern XmuWidgetNode XawWidgetArray[];
+extern int XawWidgetCount;
+
+#endif /* _XawAllWidgets_h */
diff --git a/src/AsciiSink.c b/src/AsciiSink.c
new file mode 100644
index 0000000..b427c80
--- /dev/null
+++ b/src/AsciiSink.c
@@ -0,0 +1,693 @@
+/* $XConsortium: AsciiSink.c,v 1.62 94/04/17 20:11:41 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.
+
+******************************************************************/
+
+#include <stdio.h>
+
+#include <X11/Xatom.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/AsciiSinkP.h>
+#include <X11/Xaw3d/AsciiSrcP.h> /* For source function defs. */
+#include <X11/Xaw3d/TextP.h> /* I also reach into the text widget. */
+
+#ifdef GETLASTPOS
+#undef GETLASTPOS /* We will use our own GETLASTPOS. */
+#endif
+
+#define GETLASTPOS XawTextSourceScan(source, (XawTextPosition) 0, XawstAll, XawsdRight, 1, TRUE)
+
+static void Initialize(), Destroy();
+static Boolean SetValues();
+static int MaxLines(), MaxHeight();
+static void SetTabs();
+
+static void DisplayText(), InsertCursor(), FindPosition();
+static void FindDistance(), Resolve(), GetCursorBounds();
+
+#define offset(field) XtOffsetOf(AsciiSinkRec, ascii_sink.field)
+
+static XtResource resources[] = {
+ {XtNfont, XtCFont, XtRFontStruct, sizeof (XFontStruct *),
+ offset(font), XtRString, XtDefaultFont},
+ {XtNecho, XtCOutput, XtRBoolean, sizeof(Boolean),
+ offset(echo), XtRImmediate, (XtPointer) True},
+ {XtNdisplayNonprinting, XtCOutput, XtRBoolean, sizeof(Boolean),
+ offset(display_nonprinting), XtRImmediate, (XtPointer) True},
+};
+#undef offset
+
+#define SuperClass (&textSinkClassRec)
+AsciiSinkClassRec asciiSinkClassRec = {
+ {
+/* core_class fields */
+ /* superclass */ (WidgetClass) SuperClass,
+ /* class_name */ "AsciiSink",
+ /* widget_size */ sizeof(AsciiSinkRec),
+ /* class_initialize */ XawInitializeWidgetSet,
+ /* class_part_initialize */ NULL,
+ /* class_inited */ FALSE,
+ /* initialize */ Initialize,
+ /* initialize_hook */ NULL,
+ /* obj1 */ NULL,
+ /* obj2 */ NULL,
+ /* obj3 */ 0,
+ /* resources */ resources,
+ /* num_resources */ XtNumber(resources),
+ /* xrm_class */ NULLQUARK,
+ /* obj4 */ FALSE,
+ /* obj5 */ FALSE,
+ /* obj6 */ FALSE,
+ /* obj7 */ FALSE,
+ /* destroy */ Destroy,
+ /* obj8 */ NULL,
+ /* obj9 */ NULL,
+ /* set_values */ SetValues,
+ /* set_values_hook */ NULL,
+ /* obj10 */ NULL,
+ /* get_values_hook */ NULL,
+ /* obj11 */ NULL,
+ /* version */ XtVersion,
+ /* callback_private */ NULL,
+ /* obj12 */ NULL,
+ /* obj13 */ NULL,
+ /* obj14 */ NULL,
+ /* extension */ NULL
+ },
+/* text_sink_class fields */
+ {
+ /* DisplayText */ DisplayText,
+ /* InsertCursor */ InsertCursor,
+ /* ClearToBackground */ XtInheritClearToBackground,
+ /* FindPosition */ FindPosition,
+ /* FindDistance */ FindDistance,
+ /* Resolve */ Resolve,
+ /* MaxLines */ MaxLines,
+ /* MaxHeight */ MaxHeight,
+ /* SetTabs */ SetTabs,
+ /* GetCursorBounds */ GetCursorBounds
+ },
+/* ascii_sink_class fields */
+ {
+ /* unused */ 0
+ }
+};
+
+WidgetClass asciiSinkObjectClass = (WidgetClass)&asciiSinkClassRec;
+
+/* Utilities */
+
+static int
+CharWidth (w, x, c)
+Widget w;
+int x;
+unsigned char c;
+{
+ int i, width, nonPrinting;
+ AsciiSinkObject sink = (AsciiSinkObject) w;
+ XFontStruct *font = sink->ascii_sink.font;
+ Position *tab;
+
+ if ( c == XawLF ) return(0);
+
+ if (c == XawTAB) {
+ /* Adjust for Left Margin. */
+ x -= ((TextWidget) XtParent(w))->text.margin.left;
+
+ if (x >= (int)XtParent(w)->core.width) return 0;
+ for (i = 0, tab = sink->text_sink.tabs ;
+ i < sink->text_sink.tab_count ; i++, tab++) {
+ if (x < *tab) {
+ if (*tab < (int)XtParent(w)->core.width)
+ return *tab - x;
+ else
+ return 0;
+ }
+ }
+ return 0;
+ }
+
+ if ( (nonPrinting = (c < (unsigned char) XawSP)) )
+ if (sink->ascii_sink.display_nonprinting)
+ c += '@';
+ else {
+ c = XawSP;
+ nonPrinting = False;
+ }
+
+ if (font->per_char &&
+ (c >= font->min_char_or_byte2 && c <= font->max_char_or_byte2))
+ width = font->per_char[c - font->min_char_or_byte2].width;
+ else
+ width = font->min_bounds.width;
+
+ if (nonPrinting)
+ width += CharWidth(w, x, (unsigned char) '^');
+
+ return width;
+}
+
+/* Function Name: PaintText
+ * Description: Actually paints the text into the windoe.
+ * Arguments: w - the text widget.
+ * gc - gc to paint text with.
+ * x, y - location to paint the text.
+ * buf, len - buffer and length of text to paint.
+ * Returns: the width of the text painted, or 0.
+ *
+ * NOTE: If this string attempts to paint past the end of the window
+ * then this function will return zero.
+ */
+
+static Dimension
+PaintText(w, gc, x, y, buf, len)
+Widget w;
+GC gc;
+Position x, y;
+unsigned char * buf;
+int len;
+{
+ AsciiSinkObject sink = (AsciiSinkObject) w;
+ TextWidget ctx = (TextWidget) XtParent(w);
+
+ Position max_x;
+ Dimension width = XTextWidth(sink->ascii_sink.font, (char *) buf, len);
+ max_x = (Position) ctx->core.width;
+
+ if ( ((int) width) <= -x) /* Don't draw if we can't see it. */
+ return(width);
+
+ XDrawImageString(XtDisplay(ctx), XtWindow(ctx), gc,
+ (int) x, (int) y, (char *) buf, len);
+ if ( (((Position) width + x) > max_x) && (ctx->text.margin.right != 0) ) {
+ x = ctx->core.width - ctx->text.margin.right;
+ width = ctx->text.margin.right;
+ XFillRectangle(XtDisplay((Widget) ctx), XtWindow( (Widget) ctx),
+ sink->ascii_sink.normgc, (int) x,
+ (int) y - sink->ascii_sink.font->ascent,
+ (unsigned int) width,
+ (unsigned int) (sink->ascii_sink.font->ascent +
+ sink->ascii_sink.font->descent));
+ return(0);
+ }
+ return(width);
+}
+
+/* Sink Object Functions */
+
+/*
+ * This function does not know about drawing more than one line of text.
+ */
+
+static void
+DisplayText(w, x, y, pos1, pos2, highlight)
+Widget w;
+Position x, y;
+Boolean highlight;
+XawTextPosition pos1, pos2;
+{
+ AsciiSinkObject sink = (AsciiSinkObject) w;
+ Widget source = XawTextGetSource(XtParent(w));
+ unsigned char buf[BUFSIZ];
+
+ int j, k;
+ XawTextBlock blk;
+ GC gc = highlight ? sink->ascii_sink.invgc : sink->ascii_sink.normgc;
+ GC invgc = highlight ? sink->ascii_sink.normgc : sink->ascii_sink.invgc;
+
+ if (!sink->ascii_sink.echo) return;
+
+ y += sink->ascii_sink.font->ascent;
+ for ( j = 0 ; pos1 < pos2 ; ) {
+ pos1 = XawTextSourceRead(source, pos1, &blk, (int) pos2 - pos1);
+ for (k = 0; k < blk.length; k++) {
+ if (j >= BUFSIZ) { /* buffer full, dump the text. */
+ x += PaintText(w, gc, x, y, buf, j);
+ j = 0;
+ }
+ buf[j] = blk.ptr[k];
+ if (buf[j] == XawLF) /* line feeds ('\n') are not printed. */
+ continue;
+
+ else if (buf[j] == '\t') {
+ Position temp = 0;
+ Dimension width;
+
+ if ((j != 0) && ((temp = PaintText(w, gc, x, y, buf, j)) == 0))
+ return;
+
+ x += temp;
+ width = CharWidth(w, x, (unsigned char) '\t');
+ XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w),
+ invgc, (int) x,
+ (int) y - sink->ascii_sink.font->ascent,
+ (unsigned int) width,
+ (unsigned int) (sink->ascii_sink.font->ascent +
+ sink->ascii_sink.font->descent));
+ x += width;
+ j = -1;
+ }
+ else if ( buf[j] < (unsigned char) ' ' ) {
+ if (sink->ascii_sink.display_nonprinting) {
+ buf[j + 1] = buf[j] + '@';
+ buf[j] = '^';
+ j++;
+ }
+ else
+ buf[j] = ' ';
+ }
+ j++;
+ }
+ }
+ if (j > 0)
+ (void) PaintText(w, gc, x, y, buf, j);
+}
+
+#define insertCursor_width 6
+#define insertCursor_height 3
+static char insertCursor_bits[] = {0x0c, 0x1e, 0x33};
+
+static Pixmap
+CreateInsertCursor(s)
+Screen *s;
+{
+ return (XCreateBitmapFromData (DisplayOfScreen(s), RootWindowOfScreen(s),
+ insertCursor_bits, insertCursor_width, insertCursor_height));
+}
+
+/* Function Name: GetCursorBounds
+ * Description: Returns the size and location of the cursor.
+ * Arguments: w - the text object.
+ * RETURNED rect - an X rectangle to return the cursor bounds in.
+ * Returns: none.
+ */
+
+static void
+GetCursorBounds(w, rect)
+Widget w;
+XRectangle * rect;
+{
+ AsciiSinkObject sink = (AsciiSinkObject) w;
+
+ rect->width = (unsigned short) insertCursor_width;
+ rect->height = (unsigned short) insertCursor_height;
+ rect->x = sink->ascii_sink.cursor_x - (short) (rect->width / 2);
+ rect->y = sink->ascii_sink.cursor_y - (short) rect->height;
+}
+
+/*
+ * The following procedure manages the "insert" cursor.
+ */
+
+static void
+InsertCursor (w, x, y, state)
+Widget w;
+Position x, y;
+XawTextInsertState state;
+{
+ AsciiSinkObject sink = (AsciiSinkObject) w;
+ Widget text_widget = XtParent(w);
+ XRectangle rect;
+
+ sink->ascii_sink.cursor_x = x;
+ sink->ascii_sink.cursor_y = y;
+
+ GetCursorBounds(w, &rect);
+ if (state != sink->ascii_sink.laststate && XtIsRealized(text_widget))
+ XCopyPlane(XtDisplay(text_widget),
+ sink->ascii_sink.insertCursorOn,
+ XtWindow(text_widget), sink->ascii_sink.xorgc,
+ 0, 0, (unsigned int) rect.width, (unsigned int) rect.height,
+ (int) rect.x, (int) rect.y, 1);
+ sink->ascii_sink.laststate = state;
+}
+
+/*
+ * Given two positions, find the distance between them.
+ */
+
+static void
+FindDistance (w, fromPos, fromx, toPos, resWidth, resPos, resHeight)
+Widget w;
+XawTextPosition fromPos; /* First position. */
+int fromx; /* Horizontal location of first position. */
+XawTextPosition toPos; /* Second position. */
+int *resWidth; /* Distance between fromPos and resPos. */
+XawTextPosition *resPos; /* Actual second position used. */
+int *resHeight; /* Height required. */
+{
+ AsciiSinkObject sink = (AsciiSinkObject) w;
+ Widget source = XawTextGetSource(XtParent(w));
+
+ XawTextPosition index, lastPos;
+ unsigned char c;
+ XawTextBlock blk;
+
+ /* we may not need this */
+ lastPos = GETLASTPOS;
+ XawTextSourceRead(source, fromPos, &blk, (int) toPos - fromPos);
+ *resWidth = 0;
+ for (index = fromPos; index != toPos && index < lastPos; index++) {
+ if (index - blk.firstPos >= blk.length)
+ XawTextSourceRead(source, index, &blk, (int) toPos - fromPos);
+ c = blk.ptr[index - blk.firstPos];
+ *resWidth += CharWidth(w, fromx + *resWidth, c);
+ if (c == XawLF) {
+ index++;
+ break;
+ }
+ }
+ *resPos = index;
+ *resHeight = sink->ascii_sink.font->ascent +sink->ascii_sink.font->descent;
+}
+
+
+static void
+FindPosition(w, fromPos, fromx, width, stopAtWordBreak,
+ resPos, resWidth, resHeight)
+Widget w;
+XawTextPosition fromPos; /* Starting position. */
+int fromx; /* Horizontal location of starting position.*/
+int width; /* Desired width. */
+int stopAtWordBreak; /* Whether the resulting position should be at
+ a word break. */
+XawTextPosition *resPos; /* Resulting position. */
+int *resWidth; /* Actual width used. */
+int *resHeight; /* Height required. */
+{
+ AsciiSinkObject sink = (AsciiSinkObject) w;
+ Widget source = XawTextGetSource(XtParent(w));
+
+ XawTextPosition lastPos, index, whiteSpacePosition = 0;
+ int lastWidth = 0, whiteSpaceWidth = 0;
+ Boolean whiteSpaceSeen;
+ unsigned char c;
+ XawTextBlock blk;
+
+ lastPos = GETLASTPOS;
+
+ XawTextSourceRead(source, fromPos, &blk, BUFSIZ);
+ *resWidth = 0;
+ whiteSpaceSeen = FALSE;
+ c = 0;
+ for (index = fromPos; *resWidth <= width && index < lastPos; index++) {
+ lastWidth = *resWidth;
+ if (index - blk.firstPos >= blk.length)
+ XawTextSourceRead(source, index, &blk, BUFSIZ);
+ c = blk.ptr[index - blk.firstPos];
+ *resWidth += CharWidth(w, fromx + *resWidth, c);
+
+ if ((c == XawSP || c == XawTAB) && *resWidth <= width) {
+ whiteSpaceSeen = TRUE;
+ whiteSpacePosition = index;
+ whiteSpaceWidth = *resWidth;
+ }
+ if (c == XawLF) {
+ index++;
+ break;
+ }
+ }
+ if (*resWidth > width && index > fromPos) {
+ *resWidth = lastWidth;
+ index--;
+ if (stopAtWordBreak && whiteSpaceSeen) {
+ index = whiteSpacePosition + 1;
+ *resWidth = whiteSpaceWidth;
+ }
+ }
+ if (index == lastPos && c != XawLF) index = lastPos + 1;
+ *resPos = index;
+ *resHeight = sink->ascii_sink.font->ascent +sink->ascii_sink.font->descent;
+}
+
+static void
+Resolve (w, pos, fromx, width, leftPos, rightPos)
+Widget w;
+XawTextPosition pos;
+int fromx, width;
+XawTextPosition *leftPos, *rightPos;
+{
+ int resWidth, resHeight;
+ Widget source = XawTextGetSource(XtParent(w));
+
+ FindPosition(w, pos, fromx, width, FALSE, leftPos, &resWidth, &resHeight);
+ if (*leftPos > GETLASTPOS)
+ *leftPos = GETLASTPOS;
+ *rightPos = *leftPos;
+}
+
+static void
+GetGC(sink)
+AsciiSinkObject sink;
+{
+ XtGCMask valuemask = (GCFont |
+ GCGraphicsExposures | GCForeground | GCBackground );
+ XGCValues values;
+
+ values.font = sink->ascii_sink.font->fid;
+ values.graphics_exposures = (Bool) FALSE;
+
+ values.foreground = sink->text_sink.foreground;
+ values.background = sink->text_sink.background;
+ sink->ascii_sink.normgc = XtGetGC((Widget)sink, valuemask, &values);
+
+ values.foreground = sink->text_sink.background;
+ values.background = sink->text_sink.foreground;
+ sink->ascii_sink.invgc = XtGetGC((Widget)sink, valuemask, &values);
+
+ values.function = GXxor;
+ values.background = (unsigned long) 0L; /* (pix ^ 0) = pix */
+ values.foreground = (sink->text_sink.background ^
+ sink->text_sink.foreground);
+ valuemask = GCGraphicsExposures | GCFunction | GCForeground | GCBackground;
+
+ sink->ascii_sink.xorgc = XtGetGC((Widget)sink, valuemask, &values);
+}
+
+
+/***** Public routines *****/
+
+/* Function Name: Initialize
+ * Description: Initializes the TextSink Object.
+ * Arguments: request, new - the requested and new values for the object
+ * instance.
+ * Returns: none.
+ *
+ */
+
+/* ARGSUSED */
+static void
+Initialize(request, new, args, num_args)
+Widget request, new;
+ArgList args;
+Cardinal *num_args;
+{
+ AsciiSinkObject sink = (AsciiSinkObject) new;
+
+ GetGC(sink);
+
+ sink->ascii_sink.insertCursorOn= CreateInsertCursor(XtScreenOfObject(new));
+ sink->ascii_sink.laststate = XawisOff;
+ sink->ascii_sink.cursor_x = sink->ascii_sink.cursor_y = 0;
+}
+
+/* Function Name: Destroy
+ * Description: This function cleans up when the object is
+ * destroyed.
+ * Arguments: w - the AsciiSink Object.
+ * Returns: none.
+ */
+
+static void
+Destroy(w)
+Widget w;
+{
+ AsciiSinkObject sink = (AsciiSinkObject) w;
+
+ XtReleaseGC(w, sink->ascii_sink.normgc);
+ XtReleaseGC(w, sink->ascii_sink.invgc);
+ XtReleaseGC(w, sink->ascii_sink.xorgc);
+ XFreePixmap(XtDisplayOfObject(w), sink->ascii_sink.insertCursorOn);
+}
+
+/* Function Name: SetValues
+ * Description: Sets the values for the AsciiSink
+ * Arguments: current - current state of the object.
+ * request - what was requested.
+ * new - what the object will become.
+ * Returns: True if redisplay is needed.
+ */
+
+/* ARGSUSED */
+static Boolean
+SetValues(current, request, new, args, num_args)
+Widget current, request, new;
+ArgList args;
+Cardinal *num_args;
+{
+ AsciiSinkObject w = (AsciiSinkObject) new;
+ AsciiSinkObject old_w = (AsciiSinkObject) current;
+
+ if (w->ascii_sink.font != old_w->ascii_sink.font
+ || w->text_sink.background != old_w->text_sink.background
+ || w->text_sink.foreground != old_w->text_sink.foreground) {
+ XtReleaseGC((Widget)w, w->ascii_sink.normgc);
+ XtReleaseGC((Widget)w, w->ascii_sink.invgc);
+ XtReleaseGC((Widget)w, w->ascii_sink.xorgc);
+ GetGC(w);
+ ((TextWidget)XtParent(new))->text.redisplay_needed = True;
+ } else {
+ if ( (w->ascii_sink.echo != old_w->ascii_sink.echo) ||
+ (w->ascii_sink.display_nonprinting !=
+ old_w->ascii_sink.display_nonprinting) )
+ ((TextWidget)XtParent(new))->text.redisplay_needed = True;
+ }
+
+ return False;
+}
+
+/* Function Name: MaxLines
+ * Description: Finds the Maximum number of lines that will fit in
+ * a given height.
+ * Arguments: w - the AsciiSink Object.
+ * height - height to fit lines into.
+ * Returns: the number of lines that will fit.
+ */
+
+/* ARGSUSED */
+static int
+MaxLines(w, height)
+Widget w;
+Dimension height;
+{
+ AsciiSinkObject sink = (AsciiSinkObject) w;
+ int font_height;
+
+ font_height = sink->ascii_sink.font->ascent + sink->ascii_sink.font->descent;
+ return( ((int) height) / font_height );
+}
+
+/* Function Name: MaxHeight
+ * Description: Finds the Minium height that will contain a given number
+ * lines.
+ * Arguments: w - the AsciiSink Object.
+ * lines - the number of lines.
+ * Returns: the height.
+ */
+
+/* ARGSUSED */
+static int
+MaxHeight(w, lines)
+Widget w;
+int lines;
+{
+ AsciiSinkObject sink = (AsciiSinkObject) w;
+
+ return(lines * (sink->ascii_sink.font->ascent +
+ sink->ascii_sink.font->descent));
+}
+
+/* Function Name: SetTabs
+ * Description: Sets the Tab stops.
+ * Arguments: w - the AsciiSink Object.
+ * tab_count - the number of tabs in the list.
+ * tabs - the text positions of the tabs.
+ * Returns: none
+ */
+
+static void
+SetTabs(w, tab_count, tabs)
+Widget w;
+int tab_count;
+short *tabs;
+{
+ AsciiSinkObject sink = (AsciiSinkObject) w;
+ int i;
+ Atom XA_FIGURE_WIDTH;
+ unsigned long figure_width = 0;
+ XFontStruct *font = sink->ascii_sink.font;
+
+/*
+ * Find the figure width of the current font.
+ */
+
+ XA_FIGURE_WIDTH = XInternAtom(XtDisplayOfObject(w), "FIGURE_WIDTH", FALSE);
+ if ( (XA_FIGURE_WIDTH != None) &&
+ ( (!XGetFontProperty(font, XA_FIGURE_WIDTH, &figure_width)) ||
+ (figure_width == 0)) )
+ if (font->per_char && font->min_char_or_byte2 <= '$' &&
+ font->max_char_or_byte2 >= '$')
+ figure_width = font->per_char['$' - font->min_char_or_byte2].width;
+ else
+ figure_width = font->max_bounds.width;
+
+ if (tab_count > sink->text_sink.tab_count) {
+ sink->text_sink.tabs = (Position *)
+ XtRealloc((char *) sink->text_sink.tabs,
+ (Cardinal) (tab_count * sizeof(Position)));
+ sink->text_sink.char_tabs = (short *)
+ XtRealloc((char *) sink->text_sink.char_tabs,
+ (Cardinal) (tab_count * sizeof(short)));
+ }
+
+ for ( i = 0 ; i < tab_count ; i++ ) {
+ sink->text_sink.tabs[i] = tabs[i] * figure_width;
+ sink->text_sink.char_tabs[i] = tabs[i];
+ }
+
+ sink->text_sink.tab_count = tab_count;
+
+#ifndef NO_TAB_FIX
+ { TextWidget ctx = (TextWidget)XtParent(w);
+ ctx->text.redisplay_needed = True;
+ _XawTextBuildLineTable(ctx, ctx->text.lt.top, TRUE);
+ }
+#endif
+}
diff --git a/src/AsciiSink.h b/src/AsciiSink.h
new file mode 100644
index 0000000..30ac68a
--- /dev/null
+++ b/src/AsciiSink.h
@@ -0,0 +1,91 @@
+/*
+ * $XConsortium: AsciiSink.h,v 1.9 94/04/17 20:11:43 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.
+
+******************************************************************/
+
+#ifndef _XawAsciiSink_h
+#define _XawAsciiSink_h
+
+/***********************************************************************
+ *
+ * AsciiSink Object
+ *
+ ***********************************************************************/
+
+#include <X11/Xaw3d/TextSink.h>
+
+/* Resources:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ echo Output Boolean True
+ displayNonprinting Output Boolean True
+
+*/
+
+#define XtCOutput "Output"
+
+#define XtNdisplayNonprinting "displayNonprinting"
+#define XtNecho "echo"
+
+/* Class record constants */
+
+extern WidgetClass asciiSinkObjectClass;
+
+typedef struct _AsciiSinkClassRec *AsciiSinkObjectClass;
+typedef struct _AsciiSinkRec *AsciiSinkObject;
+
+/************************************************************
+ *
+ * Public Functions.
+ *
+ ************************************************************/
+
+#endif /* _XawAsciiSrc_h */
diff --git a/src/AsciiSinkP.h b/src/AsciiSinkP.h
new file mode 100644
index 0000000..f6ba99f
--- /dev/null
+++ b/src/AsciiSinkP.h
@@ -0,0 +1,118 @@
+/*
+* $XConsortium: AsciiSinkP.h,v 1.4 94/04/17 20:11:44 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.
+
+******************************************************************/
+
+/*
+ * asciiSinkP.h - Private definitions for asciiSink object
+ *
+ */
+
+#ifndef _XawAsciiSinkP_h
+#define _XawAsciiSinkP_h
+
+/***********************************************************************
+ *
+ * AsciiSink Object Private Data
+ *
+ ***********************************************************************/
+
+#include <X11/Xaw3d/TextSinkP.h>
+#include <X11/Xaw3d/AsciiSink.h>
+
+/************************************************************
+ *
+ * New fields for the AsciiSink object class record.
+ *
+ ************************************************************/
+
+typedef struct _AsciiSinkClassPart {
+ int foo;
+} AsciiSinkClassPart;
+
+/* Full class record declaration */
+
+typedef struct _AsciiSinkClassRec {
+ ObjectClassPart object_class;
+ TextSinkClassPart text_sink_class;
+ AsciiSinkClassPart ascii_sink_class;
+} AsciiSinkClassRec;
+
+extern AsciiSinkClassRec asciiSinkClassRec;
+
+/* New fields for the AsciiSink object record */
+typedef struct {
+ /* public resources */
+ XFontStruct *font; /* Font to draw in. */
+ Boolean echo;
+ Boolean display_nonprinting;
+
+ /* private state */
+ GC normgc, invgc, xorgc;
+ Pixmap insertCursorOn;
+ XawTextInsertState laststate;
+ short cursor_x, cursor_y; /* Cursor Location. */
+} AsciiSinkPart;
+
+/****************************************************************
+ *
+ * Full instance record declaration
+ *
+ ****************************************************************/
+
+typedef struct _AsciiSinkRec {
+ ObjectPart object;
+ TextSinkPart text_sink;
+ AsciiSinkPart ascii_sink;
+} AsciiSinkRec;
+
+#endif /* _XawAsciiSinkP_h */
+
diff --git a/src/AsciiSrc.c b/src/AsciiSrc.c
new file mode 100644
index 0000000..be8cdf8
--- /dev/null
+++ b/src/AsciiSrc.c
@@ -0,0 +1,1438 @@
+/* $XConsortium: AsciiSrc.c,v 1.65 94/04/17 20:11:45 kaleb Exp $ */
+
+/*
+
+Copyright (c) 1989, 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.
+
+*/
+
+/*
+ * AsciiSrc.c - AsciiSrc object. (For use with the text widget).
+ *
+ */
+
+#include "Xaw3dP.h"
+#include <X11/IntrinsicP.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+#include <X11/StringDefs.h>
+#include <X11/Xos.h>
+#ifndef X_NOT_STDC_ENV
+#include <stdlib.h>
+#endif
+#include <X11/Xfuncs.h>
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/AsciiSrcP.h>
+#include <X11/Xmu/Misc.h>
+#include <X11/Xmu/CharSet.h>
+#ifdef XAW_INTERNATIONALIZATION
+#include <X11/Xaw3d/MultiSrcP.h>
+#endif
+
+
+#if (defined(ASCII_STRING) || defined(ASCII_DISK))
+# include <X11/Xaw3d/AsciiText.h> /* for Widget Classes. */
+#endif
+
+
+/****************************************************************
+ *
+ * Full class record constant
+ *
+ ****************************************************************/
+
+/* Private Data */
+
+static int magic_value = MAGIC_VALUE;
+
+#define offset(field) XtOffsetOf(AsciiSrcRec, ascii_src.field)
+
+static XtResource resources[] = {
+ {XtNstring, XtCString, XtRString, sizeof (char *),
+ offset(string), XtRString, NULL},
+ {XtNtype, XtCType, XtRAsciiType, sizeof (XawAsciiType),
+ offset(type), XtRImmediate, (XtPointer)XawAsciiString},
+ {XtNdataCompression, XtCDataCompression, XtRBoolean, sizeof (Boolean),
+ offset(data_compression), XtRImmediate, (XtPointer) TRUE},
+ {XtNpieceSize, XtCPieceSize, XtRInt, sizeof (XawTextPosition),
+ offset(piece_size), XtRImmediate, (XtPointer) BUFSIZ},
+ {XtNcallback, XtCCallback, XtRCallback, sizeof(XtPointer),
+ offset(callback), XtRCallback, (XtPointer)NULL},
+ {XtNuseStringInPlace, XtCUseStringInPlace, XtRBoolean, sizeof (Boolean),
+ offset(use_string_in_place), XtRImmediate, (XtPointer) FALSE},
+ {XtNlength, XtCLength, XtRInt, sizeof (int),
+ offset(ascii_length), XtRInt, (XtPointer) &magic_value},
+
+#ifdef ASCII_DISK
+ {XtNfile, XtCFile, XtRString, sizeof (String),
+ offset(filename), XtRString, NULL},
+#endif /* ASCII_DISK */
+};
+#undef offset
+
+static XawTextPosition Scan(), Search(), ReadText();
+static int ReplaceText();
+static Piece * FindPiece(), * AllocNewPiece();
+static FILE * InitStringOrFile();
+static void FreeAllPieces(), RemovePiece(), BreakPiece(), LoadPieces();
+static void RemoveOldStringOrFile(), CvtStringToAsciiType();
+static void ClassInitialize(), Initialize(), Destroy(), GetValuesHook();
+static String MyStrncpy(), StorePiecesInString();
+static Boolean SetValues(), WriteToFile();
+#ifdef X_NOT_STDC_ENV
+extern int errno;
+#endif
+
+#ifdef X_NOT_POSIX
+#define Off_t long
+#define Size_t unsigned int
+#else
+#define Off_t off_t
+#define Size_t size_t
+#endif
+
+#define superclass (&textSrcClassRec)
+AsciiSrcClassRec asciiSrcClassRec = {
+ {
+/* core_class fields */
+ /* superclass */ (WidgetClass) superclass,
+ /* class_name */ "AsciiSrc",
+ /* widget_size */ sizeof(AsciiSrcRec),
+ /* class_initialize */ ClassInitialize,
+ /* class_part_initialize */ NULL,
+ /* class_inited */ FALSE,
+ /* initialize */ Initialize,
+ /* initialize_hook */ NULL,
+ /* realize */ NULL,
+ /* actions */ NULL,
+ /* num_actions */ 0,
+ /* resources */ resources,
+ /* num_resources */ XtNumber(resources),
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ FALSE,
+ /* compress_exposure */ FALSE,
+ /* compress_enterleave */ FALSE,
+ /* visible_interest */ FALSE,
+ /* destroy */ Destroy,
+ /* resize */ NULL,
+ /* expose */ NULL,
+ /* set_values */ SetValues,
+ /* set_values_hook */ NULL,
+ /* set_values_almost */ NULL,
+ /* get_values_hook */ GetValuesHook,
+ /* accept_focus */ NULL,
+ /* version */ XtVersion,
+ /* callback_private */ NULL,
+ /* tm_table */ NULL,
+ /* query_geometry */ NULL,
+ /* display_accelerator */ NULL,
+ /* extension */ NULL
+ },
+/* textSrc_class fields */
+ {
+ /* Read */ ReadText,
+ /* Replace */ ReplaceText,
+ /* Scan */ Scan,
+ /* Search */ Search,
+ /* SetSelection */ XtInheritSetSelection,
+ /* ConvertSelection */ XtInheritConvertSelection
+ },
+/* asciiSrc_class fields */
+ {
+ /* Keep the compiler happy */ '\0'
+ }
+};
+
+WidgetClass asciiSrcObjectClass = (WidgetClass)&asciiSrcClassRec;
+
+/************************************************************
+ *
+ * Semi-Public Interfaces.
+ *
+ ************************************************************/
+
+/* Function Name: ClassInitialize
+ * Description: Class Initialize routine, called only once.
+ * Arguments: none.
+ * Returns: none.
+ */
+
+static void
+ClassInitialize()
+{
+ XawInitializeWidgetSet();
+ XtAddConverter( XtRString, XtRAsciiType, CvtStringToAsciiType,
+ NULL, (Cardinal) 0);
+}
+
+/* Function Name: Initialize
+ * Description: Initializes the simple menu widget
+ * Arguments: request - the widget requested by the argument list.
+ * new - the new widget with both resource and non
+ * resource values.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+Initialize(request, new, args, num_args)
+Widget request, new;
+ArgList args;
+Cardinal *num_args;
+{
+ AsciiSrcObject src = (AsciiSrcObject) new;
+ FILE * file;
+
+/*
+ * Set correct flags (override resources) depending upon widget class.
+ */
+
+ src->text_src.text_format = XawFmt8Bit; /* data format. */
+
+#ifdef ASCII_DISK
+ if (XtIsSubclass(XtParent(new), asciiDiskWidgetClass)) {
+ src->ascii_src.type = XawAsciiFile;
+ src->ascii_src.string = src->ascii_src.filename;
+ }
+#endif
+
+#ifdef ASCII_STRING
+ if (XtIsSubclass(XtParent(new), asciiStringWidgetClass)) {
+ src->ascii_src.use_string_in_place = TRUE;
+ src->ascii_src.type = XawAsciiString;
+ }
+#endif
+
+ src->ascii_src.changes = FALSE;
+ src->ascii_src.allocated_string = FALSE;
+
+ file = InitStringOrFile(src, src->ascii_src.type == XawAsciiFile);
+ LoadPieces(src, file, NULL);
+
+ if (file != NULL) fclose(file);
+}
+
+/* Function Name: ReadText
+ * Description: This function reads the source.
+ * Arguments: w - the AsciiSource widget.
+ * pos - position of the text to retreive.
+ * RETURNED text - text block that will contain returned text.
+ * length - maximum number of characters to read.
+ * Returns: The number of characters read into the buffer.
+ */
+
+static XawTextPosition
+ReadText(w, pos, text, length)
+Widget w;
+XawTextPosition pos;
+XawTextBlock *text;
+int length;
+{
+ AsciiSrcObject src = (AsciiSrcObject) w;
+ XawTextPosition count, start;
+ Piece * piece = FindPiece(src, pos, &start);
+
+ text->firstPos = pos;
+ text->ptr = piece->text + (pos - start);
+ count = piece->used - (pos - start);
+ text->length = (length > count) ? count : length;
+ return(pos + text->length);
+}
+
+/* Function Name: ReplaceText.
+ * Description: Replaces a block of text with new text.
+ * Arguments: w - the AsciiSource widget.
+ * startPos, endPos - ends of text that will be removed.
+ * text - new text to be inserted into buffer at startPos.
+ * Returns: XawEditError or XawEditDone.
+ */
+
+/*ARGSUSED*/
+static int
+ReplaceText (w, startPos, endPos, text)
+Widget w;
+XawTextPosition startPos, endPos;
+XawTextBlock *text;
+{
+ AsciiSrcObject src = (AsciiSrcObject) w;
+ Piece *start_piece, *end_piece, *temp_piece;
+ XawTextPosition start_first, end_first;
+ int length, firstPos;
+
+/*
+ * Editing a read only source is not allowed.
+ */
+
+ if (src->text_src.edit_mode == XawtextRead)
+ return(XawEditError);
+
+ start_piece = FindPiece(src, startPos, &start_first);
+ end_piece = FindPiece(src, endPos, &end_first);
+
+ src->ascii_src.changes = TRUE; /* We have changed the buffer. */
+
+/*
+ * Remove Old Stuff.
+ */
+
+ if (start_piece != end_piece) {
+ temp_piece = start_piece->next;
+
+/*
+ * If empty and not the only piece then remove it.
+ */
+
+ if ( ((start_piece->used = startPos - start_first) == 0) &&
+ !((start_piece->next == NULL) && (start_piece->prev == NULL)) )
+ RemovePiece(src, start_piece);
+
+ while (temp_piece != end_piece) {
+ temp_piece = temp_piece->next;
+ RemovePiece(src, temp_piece->prev);
+ }
+ end_piece->used -= endPos - end_first;
+ if (end_piece->used != 0)
+ MyStrncpy(end_piece->text, (end_piece->text + endPos - end_first),
+ (int) end_piece->used);
+ }
+ else { /* We are fully in one piece. */
+ if ( (start_piece->used -= endPos - startPos) == 0) {
+ if ( !((start_piece->next == NULL) && (start_piece->prev == NULL)) )
+ RemovePiece(src, start_piece);
+ }
+ else {
+ MyStrncpy(start_piece->text + (startPos - start_first),
+ start_piece->text + (endPos - start_first),
+ (int) (start_piece->used - (startPos - start_first)) );
+ if ( src->ascii_src.use_string_in_place &&
+ ((src->ascii_src.length - (endPos - startPos)) <
+ (src->ascii_src.piece_size - 1)) )
+ start_piece->text[src->ascii_src.length - (endPos - startPos)] = '\0';
+ }
+ }
+
+ src->ascii_src.length += -(endPos - startPos) + text->length;
+
+ if ( text->length != 0) {
+
+ /*
+ * Put in the New Stuff.
+ */
+
+ start_piece = FindPiece(src, startPos, &start_first);
+
+ length = text->length;
+ firstPos = text->firstPos;
+
+ while (length > 0) {
+ char * ptr;
+ int fill;
+
+ if (src->ascii_src.use_string_in_place) {
+ if (start_piece->used == (src->ascii_src.piece_size - 1)) {
+ /*
+ * If we are in ascii string emulation mode. Then the
+ * string is not allowed to grow.
+ */
+ start_piece->used = src->ascii_src.length =
+ src->ascii_src.piece_size - 1;
+ start_piece->text[src->ascii_src.length] = '\0';
+ return(XawEditError);
+ }
+ }
+
+
+ if (start_piece->used == src->ascii_src.piece_size) {
+ BreakPiece(src, start_piece);
+ start_piece = FindPiece(src, startPos, &start_first);
+ }
+
+ fill = Min((int)(src->ascii_src.piece_size - start_piece->used), length);
+
+ ptr = start_piece->text + (startPos - start_first);
+ MyStrncpy(ptr + fill, ptr,
+ (int) start_piece->used - (startPos - start_first));
+ strncpy(ptr, text->ptr + firstPos, fill);
+
+ startPos += fill;
+ firstPos += fill;
+ start_piece->used += fill;
+ length -= fill;
+ }
+ }
+
+ if (src->ascii_src.use_string_in_place)
+ start_piece->text[start_piece->used] = '\0';
+
+ XtCallCallbacks(w, XtNcallback, NULL); /* Call callbacks, we have changed
+ the buffer. */
+
+ return(XawEditDone);
+}
+
+/* Function Name: Scan
+ * Description: Scans the text source for the number and type
+ * of item specified.
+ * Arguments: w - the AsciiSource widget.
+ * position - the position to start scanning.
+ * type - type of thing to scan for.
+ * dir - direction to scan.
+ * count - which occurance if this thing to search for.
+ * include - whether or not to include the character found in
+ * the position that is returned.
+ * Returns: the position of the item found.
+ *
+ * Note: While there are only 'n' characters in the file there are n+1
+ * possible cursor positions (one before the first character and
+ * one after the last character.
+ */
+
+static
+XawTextPosition
+Scan (w, position, type, dir, count, include)
+Widget w;
+XawTextPosition position;
+XawTextScanType type;
+XawTextScanDirection dir;
+int count;
+Boolean include;
+{
+ AsciiSrcObject src = (AsciiSrcObject) w;
+ int inc;
+ Piece* piece;
+ XawTextPosition first, first_eol_position = 0;
+ char* ptr;
+
+ if (type == XawstAll) { /* Optomize this common case. */
+ if (dir == XawsdRight)
+ return(src->ascii_src.length);
+ return(0); /* else. */
+ }
+
+ if (position > src->ascii_src.length)
+ position = src->ascii_src.length;
+
+ if ( dir == XawsdRight ) {
+ if (position == src->ascii_src.length)
+/*
+ * Scanning right from src->ascii_src.length???
+ */
+ return(src->ascii_src.length);
+ inc = 1;
+ }
+ else {
+ if (position == 0)
+ return(0); /* Scanning left from 0??? */
+ inc = -1;
+ position--;
+ }
+
+ piece = FindPiece(src, position, &first);
+
+/*
+ * If the buffer is empty then return 0.
+ */
+
+ if ( piece->used == 0 ) return(0);
+
+ ptr = (position - first) + piece->text;
+
+ switch (type) {
+ case XawstEOL:
+ case XawstParagraph:
+ case XawstWhiteSpace:
+ for ( ; count > 0 ; count-- ) {
+ Boolean non_space = FALSE, first_eol = TRUE;
+ /* CONSTCOND */
+ while (TRUE) {
+ unsigned char c = *ptr;
+
+ ptr += inc;
+ position += inc;
+
+ if (type == XawstWhiteSpace) {
+ if (isspace(c)) {
+ if (non_space)
+ break;
+ }
+ else
+ non_space = TRUE;
+ }
+ else if (type == XawstEOL) {
+ if (c == '\n') break;
+ }
+ else { /* XawstParagraph */
+ if (first_eol) {
+ if (c == '\n') {
+ first_eol_position = position;
+ first_eol = FALSE;
+ }
+ }
+ else
+ if ( c == '\n')
+ break;
+ else if ( !isspace(c) )
+ first_eol = TRUE;
+ }
+
+
+ if ( ptr < piece->text ) {
+ piece = piece->prev;
+ if (piece == NULL) /* Begining of text. */
+ return(0);
+ ptr = piece->text + piece->used - 1;
+ }
+ else if ( ptr >= (piece->text + piece->used) ) {
+ piece = piece->next;
+ if (piece == NULL) /* End of text. */
+ return(src->ascii_src.length);
+ ptr = piece->text;
+ }
+ }
+ }
+ if (!include) {
+ if ( type == XawstParagraph)
+ position = first_eol_position;
+ position -= inc;
+ }
+ break;
+ case XawstPositions:
+ position += count * inc;
+ break;
+ case XawstAll: /* handled in special code above */
+ default:
+ break;
+ }
+
+ if ( dir == XawsdLeft )
+ position++;
+
+ if (position >= src->ascii_src.length)
+ return(src->ascii_src.length);
+ if (position < 0)
+ return(0);
+
+ return(position);
+}
+
+/* Function Name: Search
+ * Description: Searchs the text source for the text block passed
+ * Arguments: w - the AsciiSource Widget.
+ * position - the position to start scanning.
+ * dir - direction to scan.
+ * text - the text block to search for.
+ * Returns: the position of the item found.
+ */
+
+static XawTextPosition
+Search(w, position, dir, text)
+Widget w;
+XawTextPosition position;
+XawTextScanDirection dir;
+XawTextBlock * text;
+{
+ AsciiSrcObject src = (AsciiSrcObject) w;
+ int inc, count = 0;
+ char * ptr;
+ Piece * piece;
+ char * buf;
+ XawTextPosition first;
+
+ if ( dir == XawsdRight )
+ inc = 1;
+ else {
+ inc = -1;
+ if (position == 0)
+ return(XawTextSearchError); /* scanning left from 0??? */
+ position--;
+ }
+
+ buf = XtMalloc((unsigned)sizeof(unsigned char) * text->length);
+ strncpy(buf, (text->ptr + text->firstPos), text->length);
+ piece = FindPiece(src, position, &first);
+ ptr = (position - first) + piece->text;
+
+ /* CONSTCOND */
+ while (TRUE) {
+ if (*ptr == ((dir == XawsdRight) ? *(buf + count)
+ : *(buf + text->length - count - 1)) ) {
+ if (count == (text->length - 1))
+ break;
+ else
+ count++;
+ }
+ else {
+ if (count != 0) {
+ position -=inc * count;
+ ptr -= inc * count;
+ }
+ count = 0;
+ }
+
+ ptr += inc;
+ position += inc;
+
+ while ( ptr < piece->text ) {
+ piece = piece->prev;
+ if (piece == NULL) { /* Begining of text. */
+ XtFree(buf);
+ return(XawTextSearchError);
+ }
+ ptr = piece->text + piece->used - 1;
+ }
+
+ while ( ptr >= (piece->text + piece->used) ) {
+ piece = piece->next;
+ if (piece == NULL) { /* End of text. */
+ XtFree(buf);
+ return(XawTextSearchError);
+ }
+ ptr = piece->text;
+ }
+ }
+
+ XtFree(buf);
+ if (dir == XawsdLeft)
+ return(position);
+ return(position - (text->length - 1));
+}
+
+/* Function Name: SetValues
+ * Description: Sets the values for the AsciiSource.
+ * Arguments: current - current state of the widget.
+ * request - what was requested.
+ * new - what the widget will become.
+ * Returns: True if redisplay is needed.
+ */
+
+/* ARGSUSED */
+static Boolean
+SetValues(current, request, new, args, num_args)
+Widget current, request, new;
+ArgList args;
+Cardinal * num_args;
+{
+ AsciiSrcObject src = (AsciiSrcObject) new;
+ AsciiSrcObject old_src = (AsciiSrcObject) current;
+ Boolean total_reset = FALSE, string_set = FALSE;
+ FILE * file;
+ int i;
+
+ if ( old_src->ascii_src.use_string_in_place !=
+ src->ascii_src.use_string_in_place ) {
+ XtAppWarning( XtWidgetToApplicationContext(new),
+ "AsciiSrc: The XtNuseStringInPlace resource may not be changed.");
+ src->ascii_src.use_string_in_place =
+ old_src->ascii_src.use_string_in_place;
+ }
+
+ for (i = 0; i < *num_args ; i++ )
+ if (streq(args[i].name, XtNstring)) {
+ string_set = TRUE;
+ break;
+ }
+
+ if ( string_set || (old_src->ascii_src.type != src->ascii_src.type) ) {
+ RemoveOldStringOrFile(old_src, string_set); /* remove old info. */
+ file = InitStringOrFile(src, string_set); /* Init new info. */
+ LoadPieces(src, file, NULL); /* load new info into internal buffers. */
+ if (file != NULL) fclose(file);
+ XawTextSetSource( XtParent(new), new, 0); /* Tell text widget
+ what happened. */
+ total_reset = TRUE;
+ }
+
+ if ( old_src->ascii_src.ascii_length != src->ascii_src.ascii_length )
+ src->ascii_src.piece_size = src->ascii_src.ascii_length;
+
+ if ( !total_reset &&
+ (old_src->ascii_src.piece_size != src->ascii_src.piece_size) ) {
+ String string = StorePiecesInString(old_src);
+ FreeAllPieces(old_src);
+ LoadPieces(src, NULL, string);
+ XtFree(string);
+ }
+
+ return(FALSE);
+}
+
+/* Function Name: GetValuesHook
+ * Description: This is a get values hook routine that sets the
+ * values specific to the ascii source.
+ * Arguments: w - the AsciiSource Widget.
+ * args - the argument list.
+ * num_args - the number of args.
+ * Returns: none.
+ */
+
+static void
+GetValuesHook(w, args, num_args)
+Widget w;
+ArgList args;
+Cardinal * num_args;
+{
+ AsciiSrcObject src = (AsciiSrcObject) w;
+ int i;
+
+ if (src->ascii_src.type == XawAsciiString) {
+ for (i = 0; i < *num_args ; i++ )
+ if (streq(args[i].name, XtNstring)) {
+ if (src->ascii_src.use_string_in_place) {
+ *((char **) args[i].value) = src->ascii_src.first_piece->text;
+ }
+ else {
+ if (XawAsciiSave(w)) /* If save sucessful. */
+ *((char **) args[i].value) = src->ascii_src.string;
+ }
+ break;
+ }
+ }
+}
+
+/* Function Name: Destroy
+ * Description: Destroys an ascii source (frees all data)
+ * Arguments: src - the Ascii source Widget to free.
+ * Returns: none.
+ */
+
+static void
+Destroy (w)
+Widget w;
+{
+ RemoveOldStringOrFile((AsciiSrcObject) w, True);
+}
+
+/************************************************************
+ *
+ * Public routines
+ *
+ ************************************************************/
+
+/* Function Name: XawAsciiSourceFreeString
+ * Description: Frees the string returned by a get values call
+ * on the string when the source is of type string.
+ * Arguments: w - the AsciiSrc widget.
+ * Returns: none.
+ */
+
+void
+#if NeedFunctionPrototypes
+XawAsciiSourceFreeString(Widget w)
+#else
+XawAsciiSourceFreeString(w)
+Widget w;
+#endif
+{
+ AsciiSrcObject src = (AsciiSrcObject) w;
+
+ /* If the src is really a multi, call the multi routine.*/
+
+#ifdef XAW_INTERNATIONALIZATION
+ if ( XtIsSubclass( w, multiSrcObjectClass ) ) {
+ _XawMultiSourceFreeString( w );
+ return;
+ }
+ else
+#endif
+ if ( !XtIsSubclass( w, asciiSrcObjectClass ) ) {
+ XtErrorMsg("bad argument", "asciiSource", "XawError",
+#ifdef XAW_INTERNATIONALIZATION
+ "XawAsciiSourceFreeString's parameter must be an asciiSrc or multiSrc.",
+#else
+ "XawAsciiSourceFreeString's parameter must be an asciiSrc.",
+#endif
+ NULL, NULL);
+ }
+
+ if (src->ascii_src.allocated_string && src->ascii_src.type != XawAsciiFile) {
+ src->ascii_src.allocated_string = FALSE;
+ XtFree(src->ascii_src.string);
+ src->ascii_src.string = NULL;
+ }
+}
+
+/* Function Name: XawAsciiSave
+ * Description: Saves all the pieces into a file or string as required.
+ * Arguments: w - the asciiSrc Widget.
+ * Returns: TRUE if the save was successful.
+ */
+
+Boolean
+#if NeedFunctionPrototypes
+XawAsciiSave(Widget w)
+#else
+XawAsciiSave(w)
+Widget w;
+#endif
+{
+ AsciiSrcObject src = (AsciiSrcObject) w;
+
+ /* If the src is really a multi, call the multi save. */
+
+#ifdef XAW_INTERNATIONALIZATION
+ if ( XtIsSubclass( w, multiSrcObjectClass ) )
+ return( _XawMultiSave( w ) );
+ else
+#endif
+ if ( !XtIsSubclass( w, asciiSrcObjectClass ) ) {
+ XtErrorMsg("bad argument", "asciiSource", "XawError",
+#ifdef XAW_INTERNATIONALIZATION
+ "XawAsciiSave's parameter must be an asciiSrc or multiSrc.",
+#else
+ "XawAsciiSave's parameter must be an asciiSrc.",
+#endif
+ NULL, NULL);
+ }
+
+/*
+ * If using the string in place then there is no need to play games
+ * to get the internal info into a readable string.
+ */
+
+ if (src->ascii_src.use_string_in_place)
+ return(TRUE);
+
+ if (src->ascii_src.type == XawAsciiFile) {
+ char * string;
+
+ if (!src->ascii_src.changes) /* No changes to save. */
+ return(TRUE);
+
+ string = StorePiecesInString(src);
+
+ if (WriteToFile(string, src->ascii_src.string) == FALSE) {
+ XtFree(string);
+ return(FALSE);
+ }
+ XtFree(string);
+ }
+ else {
+ if (src->ascii_src.allocated_string == TRUE)
+ XtFree(src->ascii_src.string);
+ else
+ src->ascii_src.allocated_string = TRUE;
+
+ src->ascii_src.string = StorePiecesInString(src);
+ }
+ src->ascii_src.changes = FALSE;
+ return(TRUE);
+}
+
+/* Function Name: XawAsciiSaveAsFile
+ * Description: Save the current buffer as a file.
+ * Arguments: w - the AsciiSrc widget.
+ * name - name of the file to save this file into.
+ * Returns: True if the save was sucessful.
+ */
+
+Boolean
+#if NeedFunctionPrototypes
+XawAsciiSaveAsFile(Widget w, _Xconst char* name)
+#else
+XawAsciiSaveAsFile(w, name)
+Widget w;
+String name;
+#endif
+{
+ AsciiSrcObject src = (AsciiSrcObject) w;
+ String string;
+ Boolean ret;
+
+ /* If the src is really a multi, call the multi save. - */
+
+#ifdef XAW_INTERNATIONALIZATION
+ if ( XtIsSubclass( w, multiSrcObjectClass ) )
+ return( _XawMultiSaveAsFile( w, name ) );
+ else
+#endif
+ if ( !XtIsSubclass( w, asciiSrcObjectClass ) ) {
+ XtErrorMsg("bad argument", "asciiSource", "XawError",
+#ifdef XAW_INTERNATIONALIZATION
+ "XawAsciiSaveAsFile's 1st parameter must be an asciiSrc or multiSrc.",
+#else
+ "XawAsciiSaveAsFile's 1st parameter must be an asciiSrc.",
+#endif
+ NULL, NULL);
+ }
+
+ string = StorePiecesInString(src);
+
+ ret = WriteToFile(string, name);
+ XtFree(string);
+ return(ret);
+}
+
+/* Function Name: XawAsciiSourceChanged
+ * Description: Returns true if the source has changed since last saved.
+ * Arguments: w - the ascii source widget.
+ * Returns: a Boolean (see description).
+ */
+
+Boolean
+#if NeedFunctionPrototypes
+XawAsciiSourceChanged(Widget w)
+#else
+XawAsciiSourceChanged(w)
+Widget w;
+#endif
+{
+#ifdef XAW_INTERNATIONALIZATION
+ if ( XtIsSubclass( w, multiSrcObjectClass ) )
+ return( ( (MultiSrcObject) w )->multi_src.changes );
+#endif
+
+ if ( XtIsSubclass( w, asciiSrcObjectClass ) )
+ return( ( (AsciiSrcObject) w)->ascii_src.changes );
+
+ XtErrorMsg("bad argument", "asciiSource", "XawError",
+#ifdef XAW_INTERNATIONALIZATION
+ "XawAsciiSourceChanged parameter must be an asciiSrc or multiSrc.",
+#else
+ "XawAsciiSourceChanged parameter must be an asciiSrc.",
+#endif
+ NULL, NULL);
+
+ return( True ); /* for gcc -Wall */
+}
+
+/************************************************************
+ *
+ * Private Functions.
+ *
+ ************************************************************/
+
+static void
+RemoveOldStringOrFile(src, checkString)
+AsciiSrcObject src;
+Boolean checkString;
+{
+ FreeAllPieces(src);
+
+ if (checkString && src->ascii_src.allocated_string) {
+ XtFree(src->ascii_src.string);
+ src->ascii_src.allocated_string = False;
+ src->ascii_src.string = NULL;
+ }
+}
+
+/* Function Name: WriteToFile
+ * Description: Write the string specified to the begining of the file
+ * specified.
+ * Arguments: string - string to write.
+ * name - the name of the file
+ * Returns: returns TRUE if sucessful, FALSE otherwise.
+ */
+
+static Boolean
+WriteToFile(string, name)
+String string, name;
+{
+ int fd;
+
+ if ( ((fd = creat(name, 0666)) == -1 ) ||
+ (write(fd, string, sizeof(unsigned char) * strlen(string)) == -1) )
+ return(FALSE);
+
+ if ( close(fd) == -1 )
+ return(FALSE);
+
+ return(TRUE);
+}
+
+/* Function Name: StorePiecesInString
+ * Description: store the pieces in memory into a standard ascii string.
+ * Arguments: data - the ascii pointer data.
+ * Returns: none.
+ */
+
+static String
+StorePiecesInString(src)
+AsciiSrcObject src;
+{
+ String string;
+ XawTextPosition first;
+ Piece * piece;
+
+ string = XtMalloc((unsigned) sizeof(unsigned char) *
+ src->ascii_src.length + 1);
+
+ for (first = 0, piece = src->ascii_src.first_piece ; piece != NULL;
+ first += piece->used, piece = piece->next)
+ strncpy(string + first, piece->text, piece->used);
+
+ string[src->ascii_src.length] = '\0'; /* NULL terminate this sucker. */
+
+/*
+ * This will refill all pieces to capacity.
+ */
+
+ if (src->ascii_src.data_compression) {
+ FreeAllPieces(src);
+ LoadPieces(src, NULL, string);
+ }
+
+ return(string);
+}
+
+/* Function Name: InitStringOrFile.
+ * Description: Initializes the string or file.
+ * Arguments: src - the AsciiSource.
+ * Returns: none - May exit though.
+ */
+
+static FILE *
+InitStringOrFile(src, newString)
+AsciiSrcObject src;
+Boolean newString;
+{
+ char * open_mode = NULL;
+ FILE * file;
+ char fileName[TMPSIZ];
+
+ if (src->ascii_src.type == XawAsciiString) {
+
+ if (src->ascii_src.string == NULL)
+ src->ascii_src.length = 0;
+
+ else if (! src->ascii_src.use_string_in_place) {
+ src->ascii_src.string = XtNewString(src->ascii_src.string);
+ src->ascii_src.allocated_string = True;
+ src->ascii_src.length = strlen(src->ascii_src.string);
+ }
+
+ if (src->ascii_src.use_string_in_place) {
+ src->ascii_src.length = strlen(src->ascii_src.string);
+ /* In case the length resource is incorrectly set */
+ if (src->ascii_src.length > src->ascii_src.ascii_length)
+ src->ascii_src.ascii_length = src->ascii_src.length;
+
+ if (src->ascii_src.ascii_length == MAGIC_VALUE)
+ src->ascii_src.piece_size = src->ascii_src.length;
+ else
+ src->ascii_src.piece_size = src->ascii_src.ascii_length + 1;
+ }
+
+ return(NULL);
+ }
+
+/*
+ * type is XawAsciiFile.
+ */
+
+ src->ascii_src.is_tempfile = FALSE;
+
+ switch (src->text_src.edit_mode) {
+ case XawtextRead:
+ if (src->ascii_src.string == NULL)
+ XtErrorMsg("NoFile", "asciiSourceCreate", "XawError",
+ "Creating a read only disk widget and no file specified.",
+ NULL, 0);
+ open_mode = "r";
+ break;
+ case XawtextAppend:
+ case XawtextEdit:
+ if (src->ascii_src.string == NULL) {
+ src->ascii_src.string = fileName;
+ (void) tmpnam(src->ascii_src.string);
+ src->ascii_src.is_tempfile = TRUE;
+ open_mode = "w";
+ } else
+ open_mode = "r+";
+ break;
+ default:
+ XtErrorMsg("badMode", "asciiSourceCreate", "XawError",
+ "Bad editMode for ascii source; must be Read, Append or Edit.",
+ NULL, NULL);
+ }
+
+ /* Allocate new memory for the temp filename, because it is held in
+ * a stack variable, not static memory. This widget does not need
+ * to keep the private state field is_tempfile -- it is only accessed
+ * in this routine, and its former setting is unused.
+ */
+ if (newString || src->ascii_src.is_tempfile) {
+ src->ascii_src.string = XtNewString(src->ascii_src.string);
+ src->ascii_src.allocated_string = TRUE;
+ }
+
+ if (!src->ascii_src.is_tempfile) {
+ if ((file = fopen(src->ascii_src.string, open_mode)) != 0) {
+ (void) fseek(file, (Off_t)0, 2);
+ src->ascii_src.length = (XawTextPosition) ftell(file);
+ return file;
+ } else {
+ String params[2];
+ Cardinal num_params = 2;
+
+ params[0] = src->ascii_src.string;
+ params[1] = strerror(errno);
+ XtAppWarningMsg(XtWidgetToApplicationContext((Widget)src),
+ "openError", "asciiSourceCreate", "XawWarning",
+ "Cannot open file %s; %s", params, &num_params);
+ }
+ }
+ src->ascii_src.length = 0;
+ return((FILE *)NULL);
+}
+
+static void
+LoadPieces(src, file, string)
+AsciiSrcObject src;
+FILE * file;
+char * string;
+{
+ char *local_str, *ptr;
+ Piece * piece = NULL;
+ XawTextPosition left;
+
+ if (string == NULL) {
+ if (src->ascii_src.type == XawAsciiFile) {
+ local_str = XtMalloc((unsigned) (src->ascii_src.length + 1)
+ * sizeof(unsigned char));
+ if (src->ascii_src.length != 0) {
+ fseek(file, (Off_t)0, 0);
+ src->ascii_src.length = fread(local_str, (Size_t)sizeof(unsigned char),
+ (Size_t)src->ascii_src.length, file);
+ if (src->ascii_src.length <= 0)
+ XtErrorMsg("readError", "asciiSourceCreate", "XawError",
+ "fread returned error.", NULL, NULL);
+ }
+ local_str[src->ascii_src.length] = '\0';
+ }
+ else
+ local_str = src->ascii_src.string;
+ }
+ else
+ local_str = string;
+
+ if (src->ascii_src.use_string_in_place) {
+ piece = AllocNewPiece(src, piece);
+ piece->used = Min(src->ascii_src.length, src->ascii_src.piece_size);
+ piece->text = src->ascii_src.string;
+ return;
+ }
+
+ ptr = local_str;
+ left = src->ascii_src.length;
+
+ do {
+ piece = AllocNewPiece(src, piece);
+
+ piece->text = XtMalloc((unsigned)src->ascii_src.piece_size
+ * sizeof(unsigned char));
+ piece->used = Min(left, src->ascii_src.piece_size);
+ if (piece->used != 0)
+ strncpy(piece->text, ptr, piece->used);
+
+ left -= piece->used;
+ ptr += piece->used;
+ } while (left > 0);
+
+ if ( (src->ascii_src.type == XawAsciiFile) && (string == NULL) )
+ XtFree(local_str);
+}
+
+/* Function Name: AllocNewPiece
+ * Description: Allocates a new piece of memory.
+ * Arguments: src - The AsciiSrc Widget.
+ * prev - the piece just before this one, or NULL.
+ * Returns: the allocated piece.
+ */
+
+static Piece *
+AllocNewPiece(src, prev)
+AsciiSrcObject src;
+Piece * prev;
+{
+ Piece * piece = XtNew(Piece);
+
+ if (prev == NULL) {
+ src->ascii_src.first_piece = piece;
+ piece->next = NULL;
+ }
+ else {
+ if (prev->next != NULL)
+ (prev->next)->prev = piece;
+ piece->next = prev->next;
+ prev->next = piece;
+ }
+
+ piece->prev = prev;
+
+ return(piece);
+}
+
+/* Function Name: FreeAllPieces
+ * Description: Frees all the pieces
+ * Arguments: src - The AsciiSrc Widget.
+ * Returns: none.
+ */
+
+static void
+FreeAllPieces(src)
+AsciiSrcObject src;
+{
+ Piece * next, * first = src->ascii_src.first_piece;
+
+ if (first->prev != NULL)
+ (void) printf("Xaw AsciiSrc Object: possible memory leak in FreeAllPieces().\n");
+
+ for ( ; first != NULL ; first = next ) {
+ next = first->next;
+ RemovePiece(src, first);
+ }
+}
+
+/* Function Name: RemovePiece
+ * Description: Removes a piece from the list.
+ * Arguments:
+ * piece - the piece to remove.
+ * Returns: none.
+ */
+
+static void
+RemovePiece(src, piece)
+AsciiSrcObject src;
+Piece * piece;
+{
+ if (piece->prev == NULL)
+ src->ascii_src.first_piece = piece->next;
+ else
+ (piece->prev)->next = piece->next;
+
+ if (piece->next != NULL)
+ (piece->next)->prev = piece->prev;
+
+ if (!src->ascii_src.use_string_in_place)
+ XtFree(piece->text);
+
+ XtFree((char *)piece);
+}
+
+/* Function Name: FindPiece
+ * Description: Finds the piece containing the position indicated.
+ * Arguments: src - The AsciiSrc Widget.
+ * position - the position that we are searching for.
+ * RETURNED first - the position of the first character in this piece.
+ * Returns: piece - the piece that contains this position.
+ */
+
+static Piece *
+FindPiece(src, position, first)
+AsciiSrcObject src;
+XawTextPosition position, *first;
+{
+ Piece * old_piece = NULL, * piece = src->ascii_src.first_piece;
+ XawTextPosition temp;
+
+ for ( temp = 0 ; piece != NULL ; temp += piece->used, piece = piece->next ) {
+ *first = temp;
+ old_piece = piece;
+
+ if ((temp + piece->used) > position)
+ return(piece);
+ }
+ return(old_piece); /* if we run off the end the return the last piece */
+}
+
+/* Function Name: MyStrncpy
+ * Description: Just like string copy, but slower and will always
+ * work on overlapping strings.
+ * Arguments: (same as strncpy) - s1, s2 - strings to copy (2->1).
+ * n - the number of chars to copy.
+ * Returns: s1.
+ */
+
+static String
+MyStrncpy(s1, s2, n)
+char * s1, * s2;
+int n;
+{
+ char buf[256];
+ char* temp;
+
+ if (n == 0) return s1;
+
+ if (n < sizeof buf) temp = buf;
+ else temp = XtMalloc((unsigned)sizeof(unsigned char) * n);
+
+ strncpy(temp, s2, n); /* Saber has a bug that causes it to generate*/
+ strncpy(s1, temp, n); /* a bogus warning message here (CDP 6/32/89)*/
+
+ if (temp != buf) XtFree(temp);
+ return s1;
+}
+
+/* Function Name: BreakPiece
+ * Description: Breaks a full piece into two new pieces.
+ * Arguments: src - The AsciiSrc Widget.
+ * piece - the piece to break.
+ * Returns: none.
+ */
+
+#define HALF_PIECE (src->ascii_src.piece_size/2)
+
+static void
+BreakPiece(src, piece)
+AsciiSrcObject src;
+Piece * piece;
+{
+ Piece * new = AllocNewPiece(src, piece);
+
+ new->text = XtMalloc(src->ascii_src.piece_size * sizeof(unsigned char));
+ strncpy(new->text, piece->text + HALF_PIECE,
+ src->ascii_src.piece_size - HALF_PIECE);
+ piece->used = HALF_PIECE;
+ new->used = src->ascii_src.piece_size - HALF_PIECE;
+}
+
+/* ARGSUSED */
+static void
+CvtStringToAsciiType(args, num_args, fromVal, toVal)
+XrmValuePtr args; /* unused */
+Cardinal *num_args; /* unused */
+XrmValuePtr fromVal;
+XrmValuePtr toVal;
+{
+ static XawAsciiType type;
+ static XrmQuark XtQEstring = NULLQUARK;
+ static XrmQuark XtQEfile;
+ XrmQuark q;
+ char lowerName[40];
+
+ if (XtQEstring == NULLQUARK) {
+ XtQEstring = XrmPermStringToQuark(XtEstring);
+ XtQEfile = XrmPermStringToQuark(XtEfile);
+ }
+
+ if (strlen ((char*)fromVal->addr) < sizeof lowerName) {
+ XmuCopyISOLatin1Lowered(lowerName, (char *) fromVal->addr);
+ q = XrmStringToQuark(lowerName);
+
+ if (q == XtQEstring) type = XawAsciiString;
+ else if (q == XtQEfile) type = XawAsciiFile;
+ else {
+ toVal->size = 0;
+ toVal->addr = NULL;
+ return;
+ }
+ toVal->size = sizeof type;
+ toVal->addr = (XPointer) &type;
+ return;
+ }
+ toVal->size = 0;
+ toVal->addr = NULL;
+}
+
+#if (defined(ASCII_STRING) || defined(ASCII_DISK))
+# include <X11/Xaw3d/Cardinals.h>
+#endif
+
+#ifdef ASCII_STRING
+/************************************************************
+ *
+ * Compatability functions.
+ *
+ ************************************************************/
+
+/* Function Name: AsciiStringSourceCreate
+ * Description: Creates a string source.
+ * Arguments: parent - the widget that will own this source.
+ * args, num_args - the argument list.
+ * Returns: a pointer to the new text source.
+ */
+
+Widget
+XawStringSourceCreate(parent, args, num_args)
+Widget parent;
+ArgList args;
+Cardinal num_args;
+{
+ XawTextSource src;
+ ArgList ascii_args;
+ Arg temp[2];
+
+ XtSetArg(temp[0], XtNtype, XawAsciiString);
+ XtSetArg(temp[1], XtNuseStringInPlace, TRUE);
+ ascii_args = XtMergeArgLists(temp, TWO, args, num_args);
+
+ src = XtCreateWidget("genericAsciiString", asciiSrcObjectClass, parent,
+ ascii_args, num_args + TWO);
+ XtFree((char *)ascii_args);
+ return(src);
+}
+
+/*
+ * This is hacked up to try to emulate old functionality, it
+ * may not work, as I have not old code to test it on.
+ *
+ * Chris D. Peterson 8/31/89.
+ */
+
+void
+XawTextSetLastPos (w, lastPos)
+Widget w;
+XawTextPosition lastPos;
+{
+ AsciiSrcObject src = (AsciiSrcObject) XawTextGetSource(w);
+
+ src->ascii_src.piece_size = lastPos;
+}
+#endif /* ASCII_STRING */
+
+#ifdef ASCII_DISK
+/* Function Name: AsciiDiskSourceCreate
+ * Description: Creates a disk source.
+ * Arguments: parent - the widget that will own this source.
+ * args, num_args - the argument list.
+ * Returns: a pointer to the new text source.
+ */
+
+Widget
+XawDiskSourceCreate(parent, args, num_args)
+Widget parent;
+ArgList args;
+Cardinal num_args;
+{
+ XawTextSource src;
+ ArgList ascii_args;
+ Arg temp[1];
+ int i;
+
+ XtSetArg(temp[0], XtNtype, XawAsciiFile);
+ ascii_args = XtMergeArgLists(temp, ONE, args, num_args);
+ num_args++;
+
+ for (i = 0; i < num_args; i++)
+ if (streq(ascii_args[i].name, XtNfile) ||
+ streq(ascii_args[i].name, XtCFile))
+ ascii_args[i].name = XtNstring;
+
+ src = XtCreateWidget("genericAsciiDisk", asciiSrcObjectClass, parent,
+ ascii_args, num_args);
+ XtFree((char *)ascii_args);
+ return(src);
+}
+#endif /* ASCII_DISK */
diff --git a/src/AsciiSrc.h b/src/AsciiSrc.h
new file mode 100644
index 0000000..37fe4e4
--- /dev/null
+++ b/src/AsciiSrc.h
@@ -0,0 +1,162 @@
+/* $XConsortium: AsciiSrc.h,v 1.15 94/04/17 20:11:46 kaleb Exp $ */
+
+/*
+
+Copyright (c) 1989, 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.
+
+*/
+
+
+/*
+ * AsciiSrc.h - Public Header file for Ascii Text Source.
+ *
+ * This is the public header file for the Ascii Text Source.
+ * It is intended to be used with the Text widget, the simplest way to use
+ * this text source is to use the AsciiText Object.
+ *
+ * Date: June 29, 1989
+ *
+ * By: Chris D. Peterson
+ * MIT X Consortium
+ * kit@expo.lcs.mit.edu
+ */
+
+
+#ifndef _XawAsciiSrc_h
+#define _XawAsciiSrc_h
+
+#include <X11/Xaw3d/TextSrc.h>
+
+/* Resources:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ callback Callback Callback (none)
+ dataCompression DataCompression Boolean True
+ length Length int (internal)
+ pieceSize PieceSize int BUFSIZ
+ string String String NULL
+ type Type XawAsciiType XawAsciiString
+ useStringInPlace UseStringInPlace Boolean False
+
+*/
+
+/* Class record constants */
+
+extern WidgetClass asciiSrcObjectClass;
+
+typedef struct _AsciiSrcClassRec *AsciiSrcObjectClass;
+typedef struct _AsciiSrcRec *AsciiSrcObject;
+
+/*
+ * Just to make people's lives a bit easier.
+ */
+
+#define AsciiSourceObjectClass AsciiSrcObjectClass
+#define AsciiSourceObject AsciiSrcObject
+
+/*
+ * Resource Definitions.
+ */
+
+#define XtCDataCompression "DataCompression"
+#define XtCPieceSize "PieceSize"
+#define XtCType "Type"
+#define XtCUseStringInPlace "UseStringInPlace"
+
+#define XtNdataCompression "dataCompression"
+#define XtNpieceSize "pieceSize"
+#define XtNtype "type"
+#define XtNuseStringInPlace "useStringInPlace"
+
+#define XtRAsciiType "AsciiType"
+
+#define XtEstring "string"
+#define XtEfile "file"
+
+typedef enum {XawAsciiFile, XawAsciiString} XawAsciiType;
+
+/************************************************************
+ *
+ * Public routines
+ *
+ ************************************************************/
+
+_XFUNCPROTOBEGIN
+
+/* Function Name: XawAsciiSourceFreeString
+ * Description: Frees the string returned by a get values call
+ * on the string when the source is of type string.
+ * Arguments: w - the AsciiSrc object.
+ * Returns: none.
+ */
+
+extern void XawAsciiSourceFreeString(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+/* Function Name: XawAsciiSave
+ * Description: Saves all the pieces into a file or string as required.
+ * Arguments: w - the asciiSrc Object.
+ * Returns: TRUE if the save was successful.
+ */
+
+extern Boolean XawAsciiSave(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+/* Function Name: XawAsciiSaveAsFile
+ * Description: Save the current buffer as a file.
+ * Arguments: w - the asciiSrc object.
+ * name - name of the file to save this file into.
+ * Returns: True if the save was successful.
+ */
+
+extern Boolean XawAsciiSaveAsFile(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ _Xconst char* /* name */
+#endif
+);
+
+/* Function Name: XawAsciiSourceChanged
+ * Description: Returns true if the source has changed since last saved.
+ * Arguments: w - the asciiSource object.
+ * Returns: a Boolean (see description).
+ */
+
+extern Boolean XawAsciiSourceChanged(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+_XFUNCPROTOEND
+
+#endif /* _XawAsciiSrc_h */
+
diff --git a/src/AsciiSrcP.h b/src/AsciiSrcP.h
new file mode 100644
index 0000000..dcb33ff
--- /dev/null
+++ b/src/AsciiSrcP.h
@@ -0,0 +1,163 @@
+/*
+* $XConsortium: AsciiSrcP.h,v 1.10 94/04/17 20:11:49 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.
+
+******************************************************************/
+
+/*
+ * AsciiSrcP.h - Private Header for Ascii Text Source.
+ *
+ * This is the private header file for the Ascii Text Source.
+ * It is intended to be used with the Text widget, the simplest way to use
+ * this text source is to use the AsciiText Object.
+ *
+ * Date: June 29, 1989
+ *
+ * By: Chris D. Peterson
+ * MIT X Consortium
+ * kit@expo.lcs.mit.edu
+ */
+
+/*
+ * TextSrcP.h - Private definitions for AsciiSrc object
+ *
+ */
+
+#ifndef _XawAsciiSrcP_h
+#define _XawAsciiSrcP_h
+
+#include <X11/Xaw3d/TextSrcP.h>
+#include <X11/Xaw3d/AsciiSrc.h>
+
+/************************************************************
+ *
+ * Private declarations.
+ *
+ ************************************************************/
+
+#ifdef L_tmpnam
+#define TMPSIZ L_tmpnam
+#else
+#define TMPSIZ 32 /* bytes to allocate for tmpnam */
+#endif
+
+#define MAGIC_VALUE ((XawTextPosition) -1) /* Magic value. */
+
+#define streq(a, b) ( strcmp((a), (b)) == 0 )
+
+typedef struct _Piece { /* Piece of the text file of BUFSIZ allocated
+ characters. */
+ char * text; /* The text in this buffer. */
+ XawTextPosition used; /* The number of characters of this buffer
+ that have been used. */
+ struct _Piece *prev, *next; /* linked list pointers. */
+} Piece;
+
+/************************************************************
+ *
+ * New fields for the AsciiSrc object class record.
+ *
+ ************************************************************/
+
+typedef struct _AsciiSrcClassPart { char foo; } AsciiSrcClassPart;
+
+/* Full class record declaration */
+typedef struct _AsciiSrcClassRec {
+ ObjectClassPart object_class;
+ TextSrcClassPart text_src_class;
+ AsciiSrcClassPart ascii_src_class;
+} AsciiSrcClassRec;
+
+extern AsciiSrcClassRec asciiSrcClassRec;
+
+/* New fields for the AsciiSrc object record */
+
+typedef struct _AsciiSrcPart {
+
+ /* Resources. */
+
+ char *string; /* either the string, or the
+ file name, depending upon the type. */
+ XawAsciiType type; /* either string or disk. */
+ XawTextPosition piece_size; /* Size of text buffer for each piece. */
+ Boolean data_compression; /* compress to minimum memory automatically
+ on save? */
+ XtCallbackList callback; /* A callback list to call when the source is
+ changed. */
+ Boolean use_string_in_place; /* Use the string passed in place. */
+ int ascii_length; /* length field for ascii string emulation. */
+
+#ifdef ASCII_DISK
+ String filename; /* name of file for Compatability. */
+#endif /* ASCII_DISK */
+
+/* Private data. */
+
+ Boolean is_tempfile; /* Is this a temporary file? */
+ Boolean changes; /* Has this file been edited? */
+ Boolean allocated_string; /* Have I allocated the
+ string in ascii_src->string? */
+ XawTextPosition length; /* length of file */
+ Piece * first_piece; /* first piece of the text. */
+} AsciiSrcPart;
+
+/****************************************************************
+ *
+ * Full instance record declaration
+ *
+ ****************************************************************/
+
+typedef struct _AsciiSrcRec {
+ ObjectPart object;
+ TextSrcPart text_src;
+ AsciiSrcPart ascii_src;
+} AsciiSrcRec;
+
+#endif /* _XawAsciiSrcP_h */
diff --git a/src/AsciiText.c b/src/AsciiText.c
new file mode 100644
index 0000000..69bd94e
--- /dev/null
+++ b/src/AsciiText.c
@@ -0,0 +1,347 @@
+/* $XConsortium: AsciiText.c,v 1.47 95/06/06 20:50:30 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.
+
+*/
+
+/***********************************************************************
+ *
+ * AsciiText Widget
+ *
+ ***********************************************************************/
+
+/*
+ * AsciiText.c - Source code for AsciiText Widget.
+ *
+ * This Widget is intended to be used as a simple front end to the
+ * text widget with an ascii source and ascii sink attached to it.
+ *
+ * Date: June 29, 1989
+ *
+ * By: Chris D. Peterson
+ * MIT X Consortium
+ * kit@expo.lcs.mit.edu
+ */
+
+#include "Xaw3dP.h"
+#include <stdio.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/Cardinals.h>
+#include <X11/Xaw3d/AsciiTextP.h>
+#include <X11/Xaw3d/AsciiSrc.h>
+#include <X11/Xaw3d/AsciiSink.h>
+#ifdef XAW_INTERNATIONALIZATION
+#include <X11/Xaw3d/MultiSrc.h>
+#include <X11/Xaw3d/MultiSinkP.h>
+#include <X11/Xaw3d/XawImP.h>
+#endif
+
+#define TAB_COUNT 32
+
+static void Initialize(), Destroy();
+
+AsciiTextClassRec asciiTextClassRec = {
+ { /* core fields */
+ /* superclass */ (WidgetClass) &textClassRec,
+ /* class_name */ "Text",
+ /* widget_size */ sizeof(AsciiRec),
+ /* class_initialize */ XawInitializeWidgetSet,
+ /* class_part_init */ NULL,
+ /* class_inited */ FALSE,
+ /* initialize */ Initialize,
+ /* initialize_hook */ NULL,
+ /* realize */ XtInheritRealize,
+ /* actions */ NULL,
+ /* num_actions */ 0,
+ /* resources */ NULL,
+ /* num_resource */ 0,
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ TRUE,
+ /* compress_exposure*/ XtExposeGraphicsExpose | XtExposeNoExpose,
+ /* compress_enterleave*/ TRUE,
+ /* visible_interest */ FALSE,
+ /* destroy */ Destroy,
+ /* resize */ XtInheritResize,
+ /* expose */ XtInheritExpose,
+ /* set_values */ NULL,
+ /* set_values_hook */ NULL,
+ /* set_values_almost*/ XtInheritSetValuesAlmost,
+ /* get_values_hook */ NULL,
+ /* accept_focus */ XtInheritAcceptFocus,
+ /* version */ XtVersion,
+ /* callback_private */ NULL,
+ /* tm_table */ XtInheritTranslations,
+ /* query_geometry */ XtInheritQueryGeometry
+ },
+ { /* Simple fields */
+ /* change_sensitive */ XtInheritChangeSensitive
+ },
+ { /* text fields */
+ /* empty */ 0
+ },
+ { /* ascii fields */
+ /* empty */ 0
+ }
+};
+
+WidgetClass asciiTextWidgetClass = (WidgetClass)&asciiTextClassRec;
+
+
+static void
+Initialize(request, new, args, num_args)
+Widget request, new;
+ArgList args;
+Cardinal *num_args;
+{
+ AsciiWidget w = (AsciiWidget) new;
+ int i;
+ int tabs[TAB_COUNT], tab;
+
+#ifdef XAW_INTERNATIONALIZATION
+ MultiSinkObject sink;
+#endif
+
+ /* superclass Initialize can't set the following,
+ * as it didn't know the source or sink when it was called */
+
+ if (request->core.height == DEFAULT_TEXT_HEIGHT)
+ new->core.height = DEFAULT_TEXT_HEIGHT;
+
+
+ /* This is the main change for internationalization. */
+
+#ifdef XAW_INTERNATIONALIZATION
+ if ( w->simple.international == True ) { /* The multi* are international. */
+
+ w->text.source = XtCreateWidget( "textSource", multiSrcObjectClass,
+ new, args, *num_args );
+ w->text.sink = XtCreateWidget( "textSink", multiSinkObjectClass,
+ new, args, *num_args );
+ }
+ else
+#endif
+ {
+
+ w->text.source = XtCreateWidget( "textSource", asciiSrcObjectClass,
+ new, args, *num_args );
+ w->text.sink = XtCreateWidget( "textSink", asciiSinkObjectClass,
+ new, args, *num_args );
+ }
+
+ if (w->core.height == DEFAULT_TEXT_HEIGHT)
+ w->core.height = VMargins(w) + XawTextSinkMaxHeight(w->text.sink, 1);
+
+ for (i=0, tab=0 ; i < TAB_COUNT ; i++)
+ tabs[i] = (tab += 8);
+
+ XawTextSinkSetTabs(w->text.sink, TAB_COUNT, tabs);
+
+ XawTextDisableRedisplay(new);
+ XawTextEnableRedisplay(new);
+
+
+ /* If we are using a MultiSink we need to tell the input method stuff. */
+
+#ifdef XAW_INTERNATIONALIZATION
+ if ( w->simple.international == True ) {
+ Arg list[4];
+ Cardinal ac = 0;
+
+ sink = (MultiSinkObject)w->text.sink;
+ _XawImRegister( new );
+ XtSetArg (list[ac], XtNfontSet, sink->multi_sink.fontset); ac++;
+ XtSetArg (list[ac], XtNinsertPosition, w->text.insertPos); ac++;
+ XtSetArg (list[ac], XtNforeground, sink->text_sink.foreground); ac++;
+ XtSetArg (list[ac], XtNbackground, sink->text_sink.background); ac++;
+ _XawImSetValues(new, list, ac);
+ }
+#endif
+}
+
+static void
+Destroy(w)
+Widget w;
+{
+ /* Disconnect input method */
+
+#ifdef XAW_INTERNATIONALIZATION
+ if ( ((AsciiWidget)w)->simple.international == True )
+ _XawImUnregister( w );
+#endif
+
+ if (w == XtParent(((AsciiWidget)w)->text.source))
+ XtDestroyWidget( ((AsciiWidget)w)->text.source );
+
+ if (w == XtParent(((AsciiWidget)w)->text.sink))
+ XtDestroyWidget( ((AsciiWidget)w)->text.sink );
+}
+
+#ifdef ASCII_STRING
+
+/************************************************************
+ *
+ * Ascii String Compatibility Code.
+ *
+ ************************************************************/
+
+AsciiStringClassRec asciiStringClassRec = {
+ { /* core fields */
+ /* superclass */ (WidgetClass) &asciiTextClassRec,
+ /* class_name */ "Text",
+ /* widget_size */ sizeof(AsciiStringRec),
+ /* class_initialize */ NULL,
+ /* class_part_init */ NULL,
+ /* class_inited */ FALSE,
+ /* initialize */ NULL,
+ /* initialize_hook */ NULL,
+ /* realize */ XtInheritRealize,
+ /* actions */ NULL,
+ /* num_actions */ 0,
+ /* resources */ NULL,
+ /* num_ resource */ 0,
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ TRUE,
+ /* compress_exposure*/ XtExposeGraphicsExpose,
+ /* compress_enterleave*/ TRUE,
+ /* visible_interest */ FALSE,
+ /* destroy */ NULL,
+ /* resize */ XtInheritResize,
+ /* expose */ XtInheritExpose,
+ /* set_values */ NULL,
+ /* set_values_hook */ NULL,
+ /* set_values_almost*/ XtInheritSetValuesAlmost,
+ /* get_values_hook */ NULL,
+ /* accept_focus */ XtInheritAcceptFocus,
+ /* version */ XtVersion,
+ /* callback_private */ NULL,
+ /* tm_table */ XtInheritTranslations,
+ /* query_geometry */ XtInheritQueryGeometry
+ },
+ { /* Simple fields */
+ /* change_sensitive */ XtInheritChangeSensitive
+ },
+ { /* text fields */
+ /* empty */ 0
+ },
+ { /* ascii fields */
+ /* empty */ 0
+ }
+};
+
+WidgetClass asciiStringWidgetClass = (WidgetClass)&asciiStringClassRec;
+
+#endif /* ASCII_STRING */
+
+#ifdef ASCII_DISK
+
+/************************************************************
+ *
+ * Ascii Disk Compatibility Code.
+ *
+ ************************************************************/
+
+AsciiDiskClassRec asciiDiskClassRec = {
+ { /* core fields */
+ /* superclass */ (WidgetClass) &asciiTextClassRec,
+ /* class_name */ "Text",
+ /* widget_size */ sizeof(AsciiDiskRec),
+ /* class_initialize */ NULL,
+ /* class_part_init */ NULL,
+ /* class_inited */ FALSE,
+ /* initialize */ NULL,
+ /* initialize_hook */ NULL,
+ /* realize */ XtInheritRealize,
+ /* actions */ NULL,
+ /* num_actions */ 0,
+ /* resources */ NULL,
+ /* num_ resource */ 0,
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ TRUE,
+ /* compress_exposure*/ XtExposeGraphicsExpose,
+ /* compress_enterleave*/ TRUE,
+ /* visible_interest */ FALSE,
+ /* destroy */ NULL,
+ /* resize */ XtInheritResize,
+ /* expose */ XtInheritExpose,
+ /* set_values */ NULL,
+ /* set_values_hook */ NULL,
+ /* set_values_almost*/ XtInheritSetValuesAlmost,
+ /* get_values_hook */ NULL,
+ /* accept_focus */ XtInheritAcceptFocus,
+ /* version */ XtVersion,
+ /* callback_private */ NULL,
+ /* tm_table */ XtInheritTranslations,
+ /* query_geometry */ XtInheritQueryGeometry
+ },
+ { /* Simple fields */
+ /* change_sensitive */ XtInheritChangeSensitive
+ },
+ { /* text fields */
+ /* empty */ 0
+ },
+ { /* ascii fields */
+ /* empty */ 0
+ }
+};
+
+WidgetClass asciiDiskWidgetClass = (WidgetClass)&asciiDiskClassRec;
+
+#endif /* ASCII_DISK */
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/AsciiText.h b/src/AsciiText.h
new file mode 100644
index 0000000..c2d88cd
--- /dev/null
+++ b/src/AsciiText.h
@@ -0,0 +1,151 @@
+/*
+ * $XConsortium: AsciiText.h,v 1.18 94/04/17 20:11:51 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.
+
+******************************************************************/
+
+/***********************************************************************
+ *
+ * AsciiText Widget
+ *
+ ***********************************************************************/
+
+/*
+ * AsciiText.c - Public header file for AsciiText Widget.
+ *
+ * This Widget is intended to be used as a simple front end to the
+ * text widget with an ascii source and ascii sink attached to it.
+ *
+ * Date: June 29, 1989
+ *
+ * By: Chris D. Peterson
+ * MIT X Consortium
+ * kit@expo.lcs.mit.edu
+ */
+
+#ifndef _AsciiText_h
+#define _AsciiText_h
+
+/****************************************************************
+ *
+ * AsciiText widgets
+ *
+ ****************************************************************/
+
+#include "Xaw3dP.h"
+#include <X11/Xaw3d/Text.h> /* AsciiText is a subclass of Text */
+#include <X11/Xaw3d/AsciiSrc.h>
+#ifdef XAW_INTERNATIONALIZATION
+#include <X11/Xaw3d/MultiSrc.h>
+#endif
+
+/* Resources:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ autoFill AutoFill Boolean False
+ background Background Pixel XtDefaultBackground
+ border BorderColor Pixel XtDefaultForeground
+ borderWidth BorderWidth Dimension 1
+ bottomMargin Margin Position 2
+ cursor Cursor Cursor xterm
+ destroyCallback Callback Pointer NULL
+ displayCaret Output Boolean True
+ displayPosition TextPosition int 0
+ editType EditType XawTextEditType XawtextRead
+ font Font XFontStruct* Fixed
+ foreground Foreground Pixel Black
+ height Height Dimension font height
+ insertPosition TextPosition int 0
+ international International Boolean false
+ leftMargin Margin Position 2
+ mappedWhenManaged MappedWhenManaged Boolean True
+ resize Resize XawTextResizeMode XawtextResizeNever
+ rightMargin Margin Position 4
+ scrollHorizontal Scroll XawTextScrollMode XawtextScrollNever
+ scrollVertical Scroll XawTextScrollMode XawtextScrollNever
+ selectTypes SelectTypes Pointer pos/word/line/par/all
+ selection Selection Pointer (empty selection)
+ sensitive Sensitive Boolean True
+ sink TextSink Widget (none)
+ source TextSource Widget (none)
+ string String String NULL
+ topMargin Margin Position 2
+ width Width Dimension 100
+ wrap Wrap XawTextWrapMode XawtextWrapNever
+ x Position Position 0
+ y Position Position 0
+
+ (see also *Src.h and *Sink.h)
+*/
+
+/*
+ * Everything else we need is in StringDefs.h or Text.h
+ */
+
+typedef struct _AsciiTextClassRec *AsciiTextWidgetClass;
+typedef struct _AsciiRec *AsciiWidget;
+
+extern WidgetClass asciiTextWidgetClass;
+
+/************************************************************
+ *
+ * Disk and String Emulation Info.
+ *
+ ************************************************************/
+
+#ifdef ASCII_STRING
+extern WidgetClass asciiStringWidgetClass;
+#endif
+
+#ifdef ASCII_DISK
+extern WidgetClass asciiDiskWidgetClass;
+#endif
+
+#endif /* _AsciiText_h */
diff --git a/src/AsciiTextP.h b/src/AsciiTextP.h
new file mode 100644
index 0000000..c75890c
--- /dev/null
+++ b/src/AsciiTextP.h
@@ -0,0 +1,166 @@
+/*
+ * $XConsortium: AsciiTextP.h,v 1.17 94/04/17 20:11:52 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.
+
+******************************************************************/
+
+/***********************************************************************
+ *
+ * AsciiText Widget
+ *
+ ***********************************************************************/
+
+/*
+ * AsciiText.c - Private header file for AsciiText Widget.
+ *
+ * This Widget is intended to be used as a simple front end to the
+ * text widget with an ascii source and ascii sink attached to it.
+ *
+ * Date: June 29, 1989
+ *
+ * By: Chris D. Peterson
+ * MIT X Consortium
+ * kit@expo.lcs.mit.edu
+ */
+
+#ifndef _AsciiTextP_h
+#define _AsciiTextP_h
+
+#include "Xaw3dP.h"
+#include <X11/Xaw3d/TextP.h>
+#include <X11/Xaw3d/AsciiText.h>
+#include <X11/Xaw3d/AsciiSrc.h>
+#ifdef XAW_INTERNATIONALIZATION
+#include <X11/Xaw3d/MultiSrc.h>
+#endif
+
+typedef struct {int empty;} AsciiClassPart;
+
+typedef struct _AsciiTextClassRec {
+ CoreClassPart core_class;
+ SimpleClassPart simple_class;
+ TextClassPart text_class;
+ AsciiClassPart ascii_class;
+} AsciiTextClassRec;
+
+extern AsciiTextClassRec asciiTextClassRec;
+
+typedef struct { char foo; /* keep compiler happy. */ } AsciiPart;
+
+typedef struct _AsciiRec {
+ CorePart core;
+ SimplePart simple;
+ TextPart text;
+ AsciiPart ascii;
+} AsciiRec;
+
+/************************************************************
+ *
+ * Ascii String Emulation widget.
+ *
+ ************************************************************/
+
+#ifdef ASCII_STRING
+
+typedef struct {int empty;} AsciiStringClassPart;
+
+typedef struct _AsciiStringClassRec {
+ CoreClassPart core_class;
+ SimpleClassPart simple_class;
+ TextClassPart text_class;
+ AsciiClassPart ascii_class;
+ AsciiStringClassPart string_class;
+} AsciiStringClassRec;
+
+extern AsciiStringClassRec asciiStringClassRec;
+
+typedef struct { char foo; /* keep compiler happy. */ } AsciiStringPart;
+
+typedef struct _AsciiStringRec {
+ CorePart core;
+ SimplePart simple;
+ TextPart text;
+ AsciiPart ascii;
+ AsciiStringPart ascii_str;
+} AsciiStringRec;
+
+#endif /* ASCII_STRING */
+
+#ifdef ASCII_DISK
+
+/************************************************************
+ *
+ * Ascii Disk Emulation widget.
+ *
+ ************************************************************/
+
+typedef struct {int empty;} AsciiDiskClassPart;
+
+typedef struct _AsciiDiskClassRec {
+ CoreClassPart core_class;
+ SimpleClassPart simple_class;
+ TextClassPart text_class;
+ AsciiClassPart ascii_class;
+ AsciiDiskClassPart disk_class;
+} AsciiDiskClassRec;
+
+extern AsciiDiskClassRec asciiDiskClassRec;
+
+typedef struct { char foo; /* keep compiler happy. */ } AsciiDiskPart;
+
+typedef struct _AsciiDiskRec {
+ CorePart core;
+ SimplePart simple;
+ TextPart text;
+ AsciiPart ascii;
+ AsciiDiskPart ascii_disk;
+} AsciiDiskRec;
+#endif /* ASCII_DISK */
+
+#endif /* _AsciiTextP_h */
diff --git a/src/Box.c b/src/Box.c
new file mode 100644
index 0000000..640567c
--- /dev/null
+++ b/src/Box.c
@@ -0,0 +1,622 @@
+/* $XConsortium: Box.c,v 1.49 94/04/17 20:11:54 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.
+
+******************************************************************/
+
+
+/*
+ * Box.c - Box composite widget
+ *
+ */
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xmu/Misc.h>
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/BoxP.h>
+
+/****************************************************************
+ *
+ * Box Resources
+ *
+ ****************************************************************/
+
+static XtResource resources[] = {
+ { XtNhSpace, XtCHSpace, XtRDimension, sizeof(Dimension),
+ XtOffsetOf(BoxRec, box.h_space),
+ XtRImmediate, (XtPointer)4 },
+ { XtNvSpace, XtCVSpace, XtRDimension, sizeof(Dimension),
+ XtOffsetOf(BoxRec, box.v_space),
+ XtRImmediate, (XtPointer)4 },
+ { XtNorientation, XtCOrientation, XtROrientation, sizeof(XtOrientation),
+ XtOffsetOf(BoxRec, box.orientation),
+ XtRImmediate, (XtPointer)XtorientVertical },
+};
+
+/****************************************************************
+ *
+ * Full class record constant
+ *
+ ****************************************************************/
+
+static void ClassInitialize();
+static void Initialize();
+static void Realize();
+static void Resize();
+static Boolean SetValues();
+static XtGeometryResult GeometryManager();
+static void ChangeManaged();
+static XtGeometryResult PreferredSize();
+
+BoxClassRec boxClassRec = {
+ {
+/* core_class fields */
+ /* superclass */ (WidgetClass) &compositeClassRec,
+ /* class_name */ "Box",
+ /* widget_size */ sizeof(BoxRec),
+ /* class_initialize */ ClassInitialize,
+ /* class_part_init */ NULL,
+ /* class_inited */ FALSE,
+ /* initialize */ Initialize,
+ /* initialize_hook */ NULL,
+ /* realize */ Realize,
+ /* 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 */ NULL,
+ /* resize */ Resize,
+ /* expose */ NULL,
+ /* 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 */ PreferredSize,
+ /* display_accelerator*/ XtInheritDisplayAccelerator,
+ /* extension */ NULL
+ },{
+/* composite_class fields */
+ /* geometry_manager */ GeometryManager,
+ /* change_managed */ ChangeManaged,
+ /* insert_child */ XtInheritInsertChild,
+ /* delete_child */ XtInheritDeleteChild,
+ /* extension */ NULL
+ },{
+/* Box class fields */
+ /* empty */ 0,
+ }
+};
+
+WidgetClass boxWidgetClass = (WidgetClass)&boxClassRec;
+
+
+/****************************************************************
+ *
+ * Private Routines
+ *
+ ****************************************************************/
+
+/*
+ *
+ * Do a layout, either actually assigning positions, or just calculating size.
+ * Returns minimum width and height that will preserve the same layout.
+ *
+ */
+
+static void DoLayout(bbw, width, height, reply_width, reply_height, position)
+ BoxWidget bbw;
+ Dimension width, height;
+ Dimension *reply_width, *reply_height; /* bounding box */
+ Boolean position; /* actually reposition the windows? */
+{
+ Boolean vbox = (bbw->box.orientation == XtorientVertical);
+ Cardinal i;
+ Dimension w, h; /* Width and height needed for box */
+ Dimension lw, lh; /* Width and height needed for current line */
+ Dimension bw, bh; /* Width and height needed for current widget */
+ Dimension h_space; /* Local copy of bbw->box.h_space */
+ Widget widget; /* Current widget */
+ int num_mapped_children = 0;
+
+ /* Box width and height */
+ h_space = bbw->box.h_space;
+
+ w = 0;
+ for (i = 0; i < bbw->composite.num_children; i++) {
+ if ( bbw->composite.children[i]->core.width > w )
+ w = bbw->composite.children[i]->core.width;
+ }
+ w += h_space;
+ if ( w > width ) width = w;
+ h = bbw->box.v_space;
+
+ /* Line width and height */
+ lh = 0;
+ lw = h_space;
+
+ for (i = 0; i < bbw->composite.num_children; i++) {
+ widget = bbw->composite.children[i];
+ if (widget->core.managed) {
+ if (widget->core.mapped_when_managed) num_mapped_children++;
+ /* Compute widget width */
+ bw = widget->core.width + 2*widget->core.border_width + h_space;
+ if ((Dimension)(lw + bw) > width) {
+ if (lw > h_space) {
+ /* At least one widget on this line, and
+ * can't fit any more. Start new line if vbox.
+ */
+ AssignMax(w, lw);
+ if (vbox) {
+ h += lh + bbw->box.v_space;
+ lh = 0;
+ lw = h_space;
+ }
+ }
+ else if (!position) {
+ /* too narrow for this widget; we'll assume we can grow */
+ DoLayout(bbw, lw + bw, height, reply_width,
+ reply_height, position);
+ return;
+ }
+ }
+ if (position && (lw != (Dimension)widget->core.x || h != (Dimension)widget->core.y)) {
+ /* It would be nice to use window gravity, but there isn't
+ * sufficient fine-grain control to nicely handle all
+ * situations (e.g. when only the height changes --
+ * a common case). Explicit unmapping is a cheap hack
+ * to speed things up & avoid the visual jitter as
+ * things slide around.
+ *
+ * %%% perhaps there should be a client resource to
+ * control this. If so, we'll have to optimize to
+ * perform the moves from the correct end so we don't
+ * force extra exposures as children occlude each other.
+ */
+ if (XtIsRealized(widget) && widget->core.mapped_when_managed)
+ XUnmapWindow( XtDisplay(widget), XtWindow(widget) );
+ XtMoveWidget(widget, (int)lw, (int)h);
+ }
+ lw += bw;
+ bh = widget->core.height + 2*widget->core.border_width;
+ AssignMax(lh, bh);
+ } /* if managed */
+ } /* for */
+
+ if (!vbox && width && lw > width && lh < height) {
+ /* reduce width if too wide and height not filled */
+ Dimension sw = lw, sh = lh;
+ Dimension width_needed = 0;
+ XtOrientation orientation = bbw->box.orientation;
+ bbw->box.orientation = XtorientVertical;
+ while (sh < height && sw > width) {
+ width_needed = sw;
+ DoLayout(bbw, sw-1, height, &sw, &sh, False);
+ }
+ if (sh < height) width_needed = sw;
+ if (width_needed != lw) {
+ DoLayout(bbw,width_needed,height,reply_width,reply_height,position);
+ bbw->box.orientation = orientation;
+ return;
+ }
+ bbw->box.orientation = orientation;
+ }
+ if ( vbox && ( ( width < w ) || ( width < lw ) ) ) {
+ AssignMax(w, lw);
+ DoLayout( bbw, w, height, reply_width, reply_height, position );
+ return;
+ }
+ if (position && XtIsRealized((Widget)bbw)) {
+ if (bbw->composite.num_children == num_mapped_children)
+ XMapSubwindows( XtDisplay((Widget)bbw), XtWindow((Widget)bbw) );
+ else {
+ int i = bbw->composite.num_children;
+ Widget *childP = bbw->composite.children;
+ for (; i > 0; childP++, i--)
+ if (XtIsRealized(*childP) && XtIsManaged(*childP) &&
+ (*childP)->core.mapped_when_managed)
+ XtMapWidget(*childP);
+ }
+ }
+
+ /* Finish off last line */
+ if (lw > h_space) {
+ AssignMax(w, lw);
+ h += lh + bbw->box.v_space;
+ }
+
+ *reply_width = Max(w, 1);
+ *reply_height = Max(h, 1);
+}
+
+/*
+ *
+ * Calculate preferred size, given constraining box, caching it in the widget.
+ *
+ */
+
+static XtGeometryResult PreferredSize(widget, constraint, preferred)
+ Widget widget;
+ XtWidgetGeometry *constraint, *preferred;
+{
+ BoxWidget w = (BoxWidget)widget;
+ Dimension width /*, height */;
+ Dimension preferred_width = w->box.preferred_width;
+ Dimension preferred_height = w->box.preferred_height;
+
+ constraint->request_mode &= CWWidth | CWHeight;
+
+ if (constraint->request_mode == 0)
+ /* parent isn't going to change w or h, so nothing to re-compute */
+ return XtGeometryYes;
+
+ if (constraint->request_mode == w->box.last_query_mode &&
+ (!(constraint->request_mode & CWWidth) ||
+ constraint->width == w->box.last_query_width) &&
+ (!(constraint->request_mode & CWHeight) ||
+ constraint->height == w->box.last_query_height)) {
+ /* same query; current preferences are still valid */
+ preferred->request_mode = CWWidth | CWHeight;
+ preferred->width = preferred_width;
+ preferred->height = preferred_height;
+ if (constraint->request_mode == (CWWidth | CWHeight) &&
+ constraint->width == preferred_width &&
+ constraint->height == preferred_height)
+ return XtGeometryYes;
+ else
+ return XtGeometryAlmost;
+ }
+
+ /* else gotta do it the long way...
+ I have a preference for tall and narrow, so if my width is
+ constrained, I'll accept it; otherwise, I'll compute the minimum
+ width that will fit me within the height constraint */
+
+ w->box.last_query_mode = constraint->request_mode;
+ w->box.last_query_width = constraint->width;
+ w->box.last_query_height= constraint->height;
+
+ if (constraint->request_mode & CWWidth)
+ width = constraint->width;
+ else /* if (constraint->request_mode & CWHeight) */ {
+ /* let's see if I can become any narrower */
+ width = 0;
+ constraint->width = 65535;
+ }
+
+ /* height is currently ignored by DoLayout.
+ height = (constraint->request_mode & CWHeight) ? constraint->height
+ : *preferred_height;
+ */
+ DoLayout(w, width, (Dimension)0,
+ &preferred_width, &preferred_height, FALSE);
+
+ if (constraint->request_mode & CWHeight &&
+ preferred_height > constraint->height) {
+ /* find minimum width for this height */
+ if (preferred_width > constraint->width) {
+ /* punt; over-constrained */
+ }
+ else {
+ width = preferred_width;
+ do { /* find some width big enough to stay within this height */
+ width *= 2;
+ if (width > constraint->width) width = constraint->width;
+ DoLayout(w, width, 0, &preferred_width, &preferred_height, FALSE);
+ } while (preferred_height > constraint->height &&
+ width < constraint->width);
+ if (width != constraint->width) {
+ do { /* find minimum width */
+ width = preferred_width;
+ DoLayout(w, preferred_width-1, 0,
+ &preferred_width, &preferred_height, FALSE);
+ } while (preferred_height < constraint->height);
+ /* one last time */
+ DoLayout(w, width, 0, &preferred_width, &preferred_height, FALSE);
+ }
+ }
+ }
+
+ preferred->request_mode = CWWidth | CWHeight;
+ preferred->width = w->box.preferred_width = preferred_width;
+ preferred->height = w->box.preferred_height = preferred_height;
+
+ if (constraint->request_mode == (CWWidth|CWHeight)
+ && constraint->width == preferred_width
+ && constraint->height == preferred_height)
+ return XtGeometryYes;
+ else
+ return XtGeometryAlmost;
+
+}
+
+/*
+ *
+ * Actually layout the box
+ *
+ */
+
+static void Resize(w)
+ Widget w;
+{
+ Dimension junk;
+
+ DoLayout((BoxWidget)w, w->core.width, w->core.height, &junk, &junk, TRUE);
+
+} /* Resize */
+
+/*
+ *
+ * Try to do a new layout within the current width and height;
+ * if that fails try to resize and do it within the box returne
+ * by PreferredSize.
+ *
+ * TryNewLayout just says if it's possible, and doesn't actually move the kids
+ */
+
+static Boolean TryNewLayout(bbw)
+ BoxWidget bbw;
+{
+ Dimension preferred_width, preferred_height;
+ Dimension proposed_width, proposed_height;
+ int iterations;
+
+ DoLayout( bbw, bbw->core.width, bbw->core.height,
+ &preferred_width, &preferred_height, FALSE );
+
+ /* at this point, preferred_width is guaranteed to not be greater
+ than bbw->core.width unless some child is larger, so there's no
+ point in re-computing another layout */
+
+ if ((bbw->core.width == preferred_width) &&
+ (bbw->core.height == preferred_height)) {
+ /* Same size */
+ return (TRUE);
+ }
+
+ /* let's see if our parent will go for a new size. */
+ iterations = 0;
+ proposed_width = preferred_width;
+ proposed_height = preferred_height;
+ do {
+ switch (XtMakeResizeRequest((Widget)bbw,proposed_width,proposed_height,
+ &proposed_width, &proposed_height))
+ {
+ case XtGeometryYes:
+ return (TRUE);
+
+ case XtGeometryNo:
+ if (iterations > 0)
+ /* protect from malicious parents who change their minds */
+ DoLayout( bbw, bbw->core.width, bbw->core.height,
+ &preferred_width, &preferred_height, FALSE );
+ if ((preferred_width <= bbw->core.width) &&
+ (preferred_height <= bbw->core.height))
+ return (TRUE);
+ else
+ return (FALSE);
+
+ case XtGeometryAlmost:
+ if (proposed_height >= preferred_height &&
+ proposed_width >= preferred_width) {
+
+ /*
+ * Take it, and assume the parent knows what it is doing.
+ *
+ * The parent must accept this since it was returned in
+ * almost.
+ *
+ */
+ (void) XtMakeResizeRequest( (Widget)bbw,
+ proposed_width, proposed_height,
+ &proposed_width, &proposed_height);
+ return(TRUE);
+ }
+ else if (proposed_width != preferred_width) {
+ /* recalc bounding box; height might change */
+ DoLayout(bbw, proposed_width, 0,
+ &preferred_width, &preferred_height, FALSE);
+ proposed_height = preferred_height;
+ }
+ else { /* proposed_height != preferred_height */
+ XtWidgetGeometry constraints, reply;
+ constraints.request_mode = CWHeight;
+ constraints.height = proposed_height;
+ (void)PreferredSize((Widget)bbw, &constraints, &reply);
+ proposed_width = preferred_width;
+ }
+ break;
+
+ case XtGeometryDone: /* ??? */
+ default:
+ break;
+ }
+ iterations++;
+ } while (iterations < 10);
+ return (FALSE);
+}
+
+/*
+ *
+ * Geometry Manager
+ *
+ * 'reply' is unused; we say only yeay or nay, never almost.
+ *
+ */
+
+/*ARGSUSED*/
+static XtGeometryResult GeometryManager(w, request, reply)
+ Widget w;
+ XtWidgetGeometry *request;
+ XtWidgetGeometry *reply; /* RETURN */
+
+{
+ Dimension width, height, borderWidth;
+ BoxWidget bbw;
+
+ /* Position request always denied */
+ if ((request->request_mode & CWX && request->x != w->core.x) ||
+ (request->request_mode & CWY && request->y != w->core.y))
+ return (XtGeometryNo);
+
+ /* Size changes must see if the new size can be accomodated */
+ if (request->request_mode & (CWWidth | CWHeight | CWBorderWidth)) {
+
+ /* Make all three fields in the request valid */
+ if ((request->request_mode & CWWidth) == 0)
+ request->width = w->core.width;
+ if ((request->request_mode & CWHeight) == 0)
+ request->height = w->core.height;
+ if ((request->request_mode & CWBorderWidth) == 0)
+ request->border_width = w->core.border_width;
+
+ /* Save current size and set to new size */
+ width = w->core.width;
+ height = w->core.height;
+ borderWidth = w->core.border_width;
+ w->core.width = request->width;
+ w->core.height = request->height;
+ w->core.border_width = request->border_width;
+
+ /* Decide if new layout works: (1) new widget is smaller,
+ (2) new widget fits in existing Box, (3) Box can be
+ expanded to allow new widget to fit */
+
+ bbw = (BoxWidget) w->core.parent;
+
+/* whenever a child changes his geometry, we attempt to
+ * change ours to be the minimum enclosing size...
+ if (((request->width + request->border_width <= width + borderWidth) &&
+ (request->height + request->border_width <= height + borderWidth))
+ || bbw->box.preferred_width < bbw->core.width
+ || bbw->box.preferred_height < bbw->core.height
+ || TryNewLayout(bbw)) {
+ */
+ if (TryNewLayout(bbw)) {
+ /* Fits in existing or new space, relayout */
+ (*XtClass((Widget)bbw)->core_class.resize)((Widget)bbw);
+ return (XtGeometryYes);
+ } else {
+ /* Cannot satisfy request, change back to original geometry */
+ w->core.width = width;
+ w->core.height = height;
+ w->core.border_width = borderWidth;
+ return (XtGeometryNo);
+ }
+ }; /* if any size changes requested */
+
+ /* Any stacking changes don't make a difference, so allow if that's all */
+ return (XtGeometryYes);
+}
+
+static void ChangeManaged(w)
+ Widget w;
+{
+ /* Reconfigure the box */
+ (void) TryNewLayout((BoxWidget)w);
+ Resize(w);
+}
+
+static void ClassInitialize()
+{
+ XawInitializeWidgetSet();
+ XtAddConverter( XtRString, XtROrientation, XmuCvtStringToOrientation,
+ (XtConvertArgList)NULL, (Cardinal)0 );
+}
+
+/* ARGSUSED */
+static void Initialize(request, new, args, num_args)
+ Widget request, new;
+ ArgList args;
+ Cardinal *num_args;
+{
+ BoxWidget newbbw = (BoxWidget)new;
+
+ newbbw->box.last_query_mode = CWWidth | CWHeight;
+ newbbw->box.last_query_width = newbbw->box.last_query_height = 0;
+ newbbw->box.preferred_width = Max(newbbw->box.h_space, 1);
+ newbbw->box.preferred_height = Max(newbbw->box.v_space, 1);
+
+ if (newbbw->core.width == 0)
+ newbbw->core.width = newbbw->box.preferred_width;
+
+ if (newbbw->core.height == 0)
+ newbbw->core.height = newbbw->box.preferred_height;
+
+} /* Initialize */
+
+static void Realize(w, valueMask, attributes)
+ Widget w;
+ Mask *valueMask;
+ XSetWindowAttributes *attributes;
+{
+ attributes->bit_gravity = NorthWestGravity;
+ *valueMask |= CWBitGravity;
+
+ XtCreateWindow( w, (unsigned)InputOutput, (Visual *)CopyFromParent,
+ *valueMask, attributes);
+} /* Realize */
+
+/* ARGSUSED */
+static Boolean SetValues(current, request, new, args, num_args)
+ Widget current, request, new;
+ ArgList args;
+ Cardinal *num_args;
+{
+ /* need to relayout if h_space or v_space change */
+
+ return False;
+}
diff --git a/src/Box.h b/src/Box.h
new file mode 100644
index 0000000..b303c99
--- /dev/null
+++ b/src/Box.h
@@ -0,0 +1,98 @@
+/*
+* $XConsortium: Box.h,v 1.22 94/04/17 20:11:55 rws Exp $
+*/
+
+
+/***********************************************************
+
+Copyright (c) 1987, 1988 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.
+
+******************************************************************/
+
+#ifndef _XawBox_h
+#define _XawBox_h
+
+#include <X11/Xmu/Converters.h>
+
+/***********************************************************************
+ *
+ * Box Widget (subclass of CompositeClass)
+ *
+ ***********************************************************************/
+
+/* Parameters:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ background Background Pixel XtDefaultBackground
+ border BorderColor Pixel XtDefaultForeground
+ borderWidth BorderWidth Dimension 1
+ destroyCallback Callback Pointer NULL
+ hSpace HSpace Dimension 4
+ height Height Dimension 0
+ mappedWhenManaged MappedWhenManaged Boolean True
+ orientation Orientation XtOrientation vertical
+ vSpace VSpace Dimension 4
+ width Width Dimension 0
+ x Position Position 0
+ y Position Position 0
+
+*/
+
+
+/* New fields */
+#ifndef _XtStringDefs_h_
+#define XtNhSpace "hSpace"
+#define XtNvSpace "vSpace"
+#endif
+
+/* Class record constants */
+
+extern WidgetClass boxWidgetClass;
+
+typedef struct _BoxClassRec *BoxWidgetClass;
+typedef struct _BoxRec *BoxWidget;
+
+#endif /* _XawBox_h */
diff --git a/src/BoxP.h b/src/BoxP.h
new file mode 100644
index 0000000..a2c19e6
--- /dev/null
+++ b/src/BoxP.h
@@ -0,0 +1,108 @@
+/*
+* $XConsortium: BoxP.h,v 1.18 94/04/17 20:11:56 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.
+
+******************************************************************/
+
+/*
+ * BoxP.h - Private definitions for Box widget
+ *
+ */
+
+#ifndef _XawBoxP_h
+#define _XawBoxP_h
+
+/***********************************************************************
+ *
+ * Box Widget Private Data
+ *
+ ***********************************************************************/
+
+#include <X11/Xaw3d/Box.h>
+#include <X11/Xmu/Converters.h>
+
+/* New fields for the Box widget class record */
+typedef struct {int empty;} BoxClassPart;
+
+/* Full class record declaration */
+typedef struct _BoxClassRec {
+ CoreClassPart core_class;
+ CompositeClassPart composite_class;
+ BoxClassPart box_class;
+} BoxClassRec;
+
+extern BoxClassRec boxClassRec;
+
+/* New fields for the Box widget record */
+typedef struct {
+ /* resources */
+ Dimension h_space, v_space;
+ XtOrientation orientation;
+
+ /* private state */
+ Dimension preferred_width, preferred_height;
+ Dimension last_query_width, last_query_height;
+ XtGeometryMask last_query_mode;
+} BoxPart;
+
+
+/****************************************************************
+ *
+ * Full instance record declaration
+ *
+ ****************************************************************/
+
+typedef struct _BoxRec {
+ CorePart core;
+ CompositePart composite;
+ BoxPart box;
+} BoxRec;
+
+#endif /* _XawBoxP_h */
diff --git a/src/Cardinals.h b/src/Cardinals.h
new file mode 100644
index 0000000..716483f
--- /dev/null
+++ b/src/Cardinals.h
@@ -0,0 +1,44 @@
+/* $XConsortium: Cardinals.h,v 1.6 94/04/17 20:11:57 jim Exp $ */
+/*
+
+Copyright (c) 1985, 1986, 1987 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.
+
+*/
+
+#ifndef _Cardinals_h
+#define _Cardinals_h
+
+#define ZERO ((Cardinal)0)
+#define ONE ((Cardinal)1)
+#define TWO ((Cardinal)2)
+#define THREE ((Cardinal)3)
+#define FOUR ((Cardinal)4)
+#define FIVE ((Cardinal)5)
+#define SIX ((Cardinal)6)
+#define SEVEN ((Cardinal)7)
+#define EIGHT ((Cardinal)8)
+#define NINE ((Cardinal)9)
+#define TEN ((Cardinal)10)
+
+#endif /* _Cardinals_h */
diff --git a/src/Command.c b/src/Command.c
new file mode 100644
index 0000000..5fe16b6
--- /dev/null
+++ b/src/Command.c
@@ -0,0 +1,629 @@
+/* $XConsortium: Command.c,v 1.79 94/04/17 20:11:58 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.
+
+******************************************************************/
+
+/*
+ * Command.c - Command button widget
+ */
+
+#include "Xaw3dP.h"
+#include <stdio.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xmu/Misc.h>
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/CommandP.h>
+#include <X11/Xmu/Converters.h>
+#include <X11/extensions/shape.h>
+
+#define DEFAULT_HIGHLIGHT_THICKNESS 2
+#define DEFAULT_SHAPE_HIGHLIGHT 32767
+
+/****************************************************************
+ *
+ * Full class record constant
+ *
+ ****************************************************************/
+
+/* Private Data */
+
+static char defaultTranslations[] =
+ "<EnterWindow>: highlight() \n\
+ <LeaveWindow>: reset() \n\
+ <Btn1Down>: set() \n\
+ <Btn1Up>: notify() unset() ";
+
+#define offset(field) XtOffsetOf(CommandRec, field)
+static XtResource resources[] = {
+ {XtNcallback, XtCCallback, XtRCallback, sizeof(XtPointer),
+ offset(command.callbacks), XtRCallback, (XtPointer)NULL},
+ {XtNhighlightThickness, XtCThickness, XtRDimension, sizeof(Dimension),
+ offset(command.highlight_thickness), XtRImmediate,
+ (XtPointer) DEFAULT_SHAPE_HIGHLIGHT},
+ {XtNshapeStyle, XtCShapeStyle, XtRShapeStyle, sizeof(int),
+ offset(command.shape_style), XtRImmediate, (XtPointer)XawShapeRectangle},
+ {XtNcornerRoundPercent, XtCCornerRoundPercent, XtRDimension,
+ sizeof(Dimension), offset(command.corner_round), XtRImmediate,
+ (XtPointer) 25},
+ {XtNborderWidth, XtCBorderWidth, XtRDimension, sizeof(Dimension),
+ XtOffsetOf(RectObjRec,rectangle.border_width), XtRImmediate,
+ (XtPointer) 0}
+};
+#undef offset
+
+static Boolean SetValues();
+static void Initialize(), Redisplay(), Set(), Reset(), Notify(), Unset();
+static void Highlight(), Unhighlight(), Destroy(), PaintCommandWidget();
+static void ClassInitialize();
+static Boolean ShapeButton();
+static void Realize(), Resize();
+
+static XtActionsRec actionsList[] = {
+ {"set", Set},
+ {"notify", Notify},
+ {"highlight", Highlight},
+ {"reset", Reset},
+ {"unset", Unset},
+ {"unhighlight", Unhighlight}
+};
+
+#define SuperClass ((LabelWidgetClass)&labelClassRec)
+
+CommandClassRec commandClassRec = {
+ {
+ (WidgetClass) SuperClass, /* superclass */
+ "Command", /* class_name */
+ sizeof(CommandRec), /* size */
+ ClassInitialize, /* class_initialize */
+ NULL, /* class_part_initialize */
+ FALSE, /* class_inited */
+ Initialize, /* initialize */
+ NULL, /* initialize_hook */
+ Realize, /* realize */
+ actionsList, /* actions */
+ XtNumber(actionsList), /* num_actions */
+ resources, /* resources */
+ XtNumber(resources), /* resource_count */
+ NULLQUARK, /* xrm_class */
+ FALSE, /* compress_motion */
+ TRUE, /* compress_exposure */
+ TRUE, /* compress_enterleave */
+ FALSE, /* visible_interest */
+ Destroy, /* destroy */
+ Resize, /* resize */
+ Redisplay, /* expose */
+ SetValues, /* set_values */
+ NULL, /* set_values_hook */
+ XtInheritSetValuesAlmost, /* set_values_almost */
+ NULL, /* get_values_hook */
+ NULL, /* accept_focus */
+ XtVersion, /* version */
+ NULL, /* callback_private */
+ defaultTranslations, /* tm_table */
+ XtInheritQueryGeometry, /* query_geometry */
+ XtInheritDisplayAccelerator, /* display_accelerator */
+ NULL /* extension */
+ }, /* CoreClass fields initialization */
+ {
+ XtInheritChangeSensitive /* change_sensitive */
+ }, /* SimpleClass fields initialization */
+ {
+ XtInheritXaw3dShadowDraw, /* shadowdraw */
+ }, /* ThreeD Class fields initialization */
+ {
+ 0, /* field not used */
+ }, /* LabelClass fields initialization */
+ {
+ 0, /* field not used */
+ }, /* CommandClass fields initialization */
+};
+
+ /* for public consumption */
+WidgetClass commandWidgetClass = (WidgetClass) &commandClassRec;
+
+/****************************************************************
+ *
+ * Private Procedures
+ *
+ ****************************************************************/
+
+static GC
+Get_GC(cbw, fg, bg)
+CommandWidget cbw;
+Pixel fg, bg;
+{
+ XGCValues values;
+
+ values.foreground = fg;
+ values.background = bg;
+ values.font = cbw->label.font->fid;
+ values.cap_style = CapProjecting;
+
+ if (cbw->command.highlight_thickness > 1 )
+ values.line_width = cbw->command.highlight_thickness;
+ else
+ values.line_width = 0;
+
+#ifdef XAW_INTERNATIONALIZATION
+ if ( cbw->simple.international == True )
+ return XtAllocateGC((Widget)cbw, 0,
+ (GCForeground|GCBackground|GCLineWidth|GCCapStyle),
+ &values, GCFont, 0 );
+ else
+#endif
+ return XtGetGC((Widget)cbw,
+ (GCForeground|GCBackground|GCFont|GCLineWidth|GCCapStyle),
+ &values);
+}
+
+
+/* ARGSUSED */
+static void
+Initialize(request, new, args, num_args)
+Widget request, new;
+ArgList args; /* unused */
+Cardinal *num_args; /* unused */
+{
+ CommandWidget cbw = (CommandWidget) new;
+ int shape_event_base, shape_error_base;
+
+ if (cbw->command.shape_style != XawShapeRectangle
+ && !XShapeQueryExtension(XtDisplay(new), &shape_event_base,
+ &shape_error_base))
+ cbw->command.shape_style = XawShapeRectangle;
+ if (cbw->command.highlight_thickness == DEFAULT_SHAPE_HIGHLIGHT) {
+ if (cbw->command.shape_style != XawShapeRectangle)
+ cbw->command.highlight_thickness = 0;
+ else
+ cbw->command.highlight_thickness = DEFAULT_HIGHLIGHT_THICKNESS;
+ }
+
+ if (cbw->command.shape_style != XawShapeRectangle) {
+ cbw->threeD.shadow_width = 0;
+ cbw->core.border_width = 1;
+ }
+ cbw->command.shadow_width = cbw->threeD.shadow_width;
+
+ cbw->command.normal_GC = Get_GC(cbw, cbw->label.foreground,
+ cbw->core.background_pixel);
+ cbw->command.inverse_GC = Get_GC(cbw, cbw->core.background_pixel,
+ cbw->label.foreground);
+ XtReleaseGC(new, cbw->label.normal_GC);
+ cbw->label.normal_GC = cbw->command.normal_GC;
+
+ cbw->command.set = FALSE;
+ cbw->command.highlighted = HighlightNone;
+}
+
+static Region
+HighlightRegion(cbw)
+CommandWidget cbw;
+{
+ static Region outerRegion = NULL, innerRegion, emptyRegion;
+ Dimension s = cbw->threeD.shadow_width;
+ XRectangle rect;
+
+ if (cbw->command.highlight_thickness == 0 ||
+ cbw->command.highlight_thickness >
+ (Dimension) ((Dimension) Min(cbw->core.width, cbw->core.height)/2))
+ return(NULL);
+
+ if (outerRegion == NULL) {
+ /* save time by allocating scratch regions only once. */
+ outerRegion = XCreateRegion();
+ innerRegion = XCreateRegion();
+ emptyRegion = XCreateRegion();
+ }
+
+ rect.x = rect.y = s;
+ rect.width = cbw->core.width - 2 * s;
+ rect.height = cbw->core.height - 2 * s;
+ XUnionRectWithRegion( &rect, emptyRegion, outerRegion );
+ rect.x = rect.y += cbw->command.highlight_thickness;
+ rect.width -= cbw->command.highlight_thickness * 2;
+ rect.height -= cbw->command.highlight_thickness * 2;
+ XUnionRectWithRegion( &rect, emptyRegion, innerRegion );
+ XSubtractRegion( outerRegion, innerRegion, outerRegion );
+ return outerRegion;
+}
+
+/***************************
+*
+* Action Procedures
+*
+***************************/
+
+/* ARGSUSED */
+static void
+Set(w,event,params,num_params)
+Widget w;
+XEvent *event;
+String *params; /* unused */
+Cardinal *num_params; /* unused */
+{
+ CommandWidget cbw = (CommandWidget)w;
+
+ if (cbw->command.set)
+ return;
+
+ cbw->command.set= TRUE;
+ if (XtIsRealized(w))
+ PaintCommandWidget(w, event, (Region) NULL, TRUE);
+}
+
+/* ARGSUSED */
+static void
+Unset(w,event,params,num_params)
+Widget w;
+XEvent *event;
+String *params; /* unused */
+Cardinal *num_params;
+{
+ CommandWidget cbw = (CommandWidget)w;
+
+ if (!cbw->command.set)
+ return;
+
+ cbw->command.set = FALSE;
+ if (XtIsRealized(w)) {
+ XClearWindow(XtDisplay(w), XtWindow(w));
+ PaintCommandWidget(w, event, (Region) NULL, TRUE);
+ }
+}
+
+/* ARGSUSED */
+static void
+Reset(w,event,params,num_params)
+Widget w;
+XEvent *event;
+String *params; /* unused */
+Cardinal *num_params; /* unused */
+{
+ CommandWidget cbw = (CommandWidget)w;
+
+ if (cbw->command.set) {
+ cbw->command.highlighted = HighlightNone;
+ Unset(w, event, params, num_params);
+ } else
+ Unhighlight(w, event, params, num_params);
+}
+
+/* ARGSUSED */
+static void
+Highlight(w,event,params,num_params)
+Widget w;
+XEvent *event;
+String *params;
+Cardinal *num_params;
+{
+ CommandWidget cbw = (CommandWidget)w;
+
+ if ( *num_params == (Cardinal) 0)
+ cbw->command.highlighted = HighlightWhenUnset;
+ else {
+ if ( *num_params != (Cardinal) 1)
+ XtWarning("Too many parameters passed to highlight action table.");
+ switch (params[0][0]) {
+ case 'A':
+ case 'a':
+ cbw->command.highlighted = HighlightAlways;
+ break;
+ default:
+ cbw->command.highlighted = HighlightWhenUnset;
+ break;
+ }
+ }
+
+ if (XtIsRealized(w))
+ PaintCommandWidget(w, event, HighlightRegion(cbw), TRUE);
+}
+
+/* ARGSUSED */
+static void
+Unhighlight(w,event,params,num_params)
+Widget w;
+XEvent *event;
+String *params; /* unused */
+Cardinal *num_params; /* unused */
+{
+ CommandWidget cbw = (CommandWidget)w;
+
+ cbw->command.highlighted = HighlightNone;
+ if (XtIsRealized(w))
+ PaintCommandWidget(w, event, HighlightRegion(cbw), TRUE);
+}
+
+/* ARGSUSED */
+static void
+Notify(w,event,params,num_params)
+Widget w;
+XEvent *event;
+String *params; /* unused */
+Cardinal *num_params; /* unused */
+{
+ CommandWidget cbw = (CommandWidget)w;
+
+ /* check to be sure state is still Set so that user can cancel
+ the action (e.g. by moving outside the window, in the default
+ bindings.
+ */
+ if (cbw->command.set)
+ XtCallCallbackList(w, cbw->command.callbacks, (XtPointer) NULL);
+}
+
+/*
+ * Repaint the widget window
+ */
+
+/************************
+*
+* REDISPLAY (DRAW)
+*
+************************/
+
+/* ARGSUSED */
+static void
+Redisplay(w, event, region)
+Widget w;
+XEvent *event;
+Region region;
+{
+ PaintCommandWidget(w, event, region, FALSE);
+}
+
+/* Function Name: PaintCommandWidget
+ * Description: Paints the command widget.
+ * Arguments: w - the command widget.
+ * region - region to paint (passed to the superclass).
+ * change - did it change either set or highlight state?
+ * Returns: none
+ */
+
+static void
+PaintCommandWidget(w, event, region, change)
+Widget w;
+XEvent *event;
+Region region;
+Boolean change;
+{
+ CommandWidget cbw = (CommandWidget) w;
+ CommandWidgetClass cwclass = (CommandWidgetClass) XtClass (w);
+ Boolean very_thick;
+ GC norm_gc, rev_gc;
+ Dimension s = cbw->threeD.shadow_width;
+
+ very_thick = cbw->command.highlight_thickness >
+ (Dimension)((Dimension) Min(cbw->core.width, cbw->core.height)/2);
+
+ if (cbw->command.set) {
+ cbw->label.normal_GC = cbw->command.inverse_GC;
+ XFillRectangle(XtDisplay(w), XtWindow(w), cbw->command.normal_GC,
+ s, s, cbw->core.width - 2 * s, cbw->core.height - 2 * s);
+ region = NULL; /* Force label to repaint text. */
+ }
+ else
+ cbw->label.normal_GC = cbw->command.normal_GC;
+
+ if (cbw->command.highlight_thickness <= 0)
+ {
+ (*SuperClass->core_class.expose) (w, event, region);
+ (*cwclass->threeD_class.shadowdraw) (w, event, region, cbw->threeD.relief, !cbw->command.set);
+ return;
+ }
+
+/*
+ * If we are set then use the same colors as if we are not highlighted.
+ */
+
+ if (cbw->command.set == (cbw->command.highlighted == HighlightNone)) {
+ norm_gc = cbw->command.inverse_GC;
+ rev_gc = cbw->command.normal_GC;
+ }
+ else {
+ norm_gc = cbw->command.normal_GC;
+ rev_gc = cbw->command.inverse_GC;
+ }
+
+ if ( !( (!change && (cbw->command.highlighted == HighlightNone)) ||
+ ((cbw->command.highlighted == HighlightWhenUnset) &&
+ (cbw->command.set))) ) {
+ if (very_thick) {
+ cbw->label.normal_GC = norm_gc; /* Give the label the right GC. */
+ XFillRectangle(XtDisplay(w),XtWindow(w), rev_gc,
+ s, s, cbw->core.width - 2 * s, cbw->core.height - 2 * s);
+ }
+ else {
+ /* wide lines are centered on the path, so indent it */
+ int offset = cbw->command.highlight_thickness/2;
+ XDrawRectangle(XtDisplay(w),XtWindow(w), rev_gc, s + offset, s + offset,
+ cbw->core.width - cbw->command.highlight_thickness - 2 * s,
+ cbw->core.height - cbw->command.highlight_thickness - 2 * s);
+ }
+ }
+ (*SuperClass->core_class.expose) (w, event, region);
+ (*cwclass->threeD_class.shadowdraw) (w, event, region, cbw->threeD.relief, !cbw->command.set);
+}
+
+static void
+Destroy(w)
+Widget w;
+{
+ CommandWidget cbw = (CommandWidget) w;
+
+ /* so Label can release it */
+ if (cbw->label.normal_GC == cbw->command.normal_GC)
+ XtReleaseGC( w, cbw->command.inverse_GC );
+ else
+ XtReleaseGC( w, cbw->command.normal_GC );
+}
+
+/*
+ * Set specified arguments into widget
+ */
+
+/* ARGSUSED */
+static Boolean
+SetValues (current, request, new, args, num_args)
+Widget current, request, new;
+ArgList args;
+Cardinal *num_args;
+{
+ CommandWidget oldcbw = (CommandWidget) current;
+ CommandWidget cbw = (CommandWidget) new;
+ Boolean redisplay = False;
+
+ if ( oldcbw->core.sensitive != cbw->core.sensitive && !cbw->core.sensitive) {
+ /* about to become insensitive */
+ cbw->command.set = FALSE;
+ cbw->command.highlighted = HighlightNone;
+ redisplay = TRUE;
+ }
+
+ if ( (oldcbw->label.foreground != cbw->label.foreground) ||
+ (oldcbw->core.background_pixel != cbw->core.background_pixel) ||
+ (oldcbw->command.highlight_thickness !=
+ cbw->command.highlight_thickness) ||
+ (oldcbw->label.font != cbw->label.font) )
+ {
+ if (oldcbw->label.normal_GC == oldcbw->command.normal_GC)
+ /* Label has release one of these */
+ XtReleaseGC(new, cbw->command.inverse_GC);
+ else
+ XtReleaseGC(new, cbw->command.normal_GC);
+
+ cbw->command.normal_GC = Get_GC(cbw, cbw->label.foreground,
+ cbw->core.background_pixel);
+ cbw->command.inverse_GC = Get_GC(cbw, cbw->core.background_pixel,
+ cbw->label.foreground);
+ XtReleaseGC(new, cbw->label.normal_GC);
+ cbw->label.normal_GC = (cbw->command.set
+ ? cbw->command.inverse_GC
+ : cbw->command.normal_GC);
+
+ redisplay = True;
+ }
+
+ if (cbw->threeD.shadow_width != oldcbw->threeD.shadow_width) {
+ cbw->command.shadow_width = cbw->threeD.shadow_width;
+ redisplay = True;
+ }
+ if (cbw->core.border_width != oldcbw->core.border_width)
+ redisplay = True;
+
+ if ( XtIsRealized(new)
+ && oldcbw->command.shape_style != cbw->command.shape_style
+ && !ShapeButton(cbw, TRUE))
+ {
+ cbw->command.shape_style = oldcbw->command.shape_style;
+ }
+
+ if (cbw->command.shape_style != XawShapeRectangle) {
+ cbw->threeD.shadow_width = 0;
+ ShapeButton(cbw, FALSE);
+ redisplay = True;
+ }
+ if (cbw->command.shape_style == XawShapeRectangle) {
+ cbw->threeD.shadow_width =
+ (cbw->command.shadow_width) ? cbw->command.shadow_width : 2;
+ redisplay = True;
+ }
+
+ return (redisplay);
+}
+
+static void ClassInitialize()
+{
+ XawInitializeWidgetSet();
+ XtSetTypeConverter( XtRString, XtRShapeStyle, XmuCvtStringToShapeStyle,
+ (XtConvertArgList)NULL, 0, XtCacheNone, (XtDestructor)NULL );
+}
+
+
+static Boolean
+ShapeButton(cbw, checkRectangular)
+CommandWidget cbw;
+Boolean checkRectangular;
+{
+ Dimension corner_size = 0;
+
+ if ( (cbw->command.shape_style == XawShapeRoundedRectangle) ) {
+ corner_size = (cbw->core.width < cbw->core.height) ? cbw->core.width
+ : cbw->core.height;
+ corner_size = (int) (corner_size * cbw->command.corner_round) / 100;
+ }
+
+ if (checkRectangular || cbw->command.shape_style != XawShapeRectangle) {
+ if (!XmuReshapeWidget((Widget) cbw, cbw->command.shape_style,
+ corner_size, corner_size)) {
+ cbw->command.shape_style = XawShapeRectangle;
+ return(False);
+ }
+ }
+ return(TRUE);
+}
+
+static void Realize(w, valueMask, attributes)
+ Widget w;
+ Mask *valueMask;
+ XSetWindowAttributes *attributes;
+{
+ (*commandWidgetClass->core_class.superclass->core_class.realize)
+ (w, valueMask, attributes);
+
+ ShapeButton( (CommandWidget) w, FALSE);
+}
+
+static void Resize(w)
+ Widget w;
+{
+ if (XtIsRealized(w))
+ ShapeButton( (CommandWidget) w, FALSE);
+
+ (*commandWidgetClass->core_class.superclass->core_class.resize)(w);
+}
diff --git a/src/Command.h b/src/Command.h
new file mode 100644
index 0000000..43a8ef4
--- /dev/null
+++ b/src/Command.h
@@ -0,0 +1,118 @@
+/* $XConsortium: Command.h,v 1.29 94/04/17 20:11:59 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.
+
+******************************************************************/
+
+#ifndef _XawCommand_h
+#define _XawCommand_h
+
+#include <X11/Xaw3d/Label.h>
+
+/* Command widget resources:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ accelerators Accelerators AcceleratorTable NULL
+ ancestorSensitive AncestorSensitive Boolean True
+ background Background Pixel XtDefaultBackground
+ backgroundPixmap Pixmap Pixmap XtUnspecifiedPixmap
+ bitmap Pixmap Pixmap None
+ borderColor BorderColor Pixel XtDefaultForeground
+ borderPixmap Pixmap Pixmap XtUnspecifiedPixmap
+ borderWidth BorderWidth Dimension 1
+ callback Callback XtCallbackList NULL
+ colormap Colormap Colormap parent's colormap
+ cornerRoundPercent CornerRoundPercent Dimension 25
+ cursor Cursor Cursor None
+ cursorName Cursor String NULL
+ depth Depth int parent's depth
+ destroyCallback Callback XtCallbackList NULL
+ encoding Encoding UnsignedChar XawTextEncoding8bit
+ font Font XFontStruct* XtDefaultFont
+ foreground Foreground Pixel XtDefaultForeground
+ height Height Dimension text height
+ highlightThickness Thickness Dimension 0 if shaped, else 2
+ 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
+ screen Screen Screen parent's Screen
+ sensitive Sensitive Boolean True
+ shapeStyle ShapeStyle ShapeStyle Rectangle
+ translations Translations TranslationTable see doc or source
+ width Width Dimension text width
+ x Position Position 0
+ y Position Position 0
+
+*/
+
+#define XtNhighlightThickness "highlightThickness"
+
+#define XtNshapeStyle "shapeStyle"
+#define XtCShapeStyle "ShapeStyle"
+#define XtRShapeStyle "ShapeStyle"
+#define XtNcornerRoundPercent "cornerRoundPercent"
+#define XtCCornerRoundPercent "CornerRoundPercent"
+
+#define XawShapeRectangle XmuShapeRectangle
+#define XawShapeOval XmuShapeOval
+#define XawShapeEllipse XmuShapeEllipse
+#define XawShapeRoundedRectangle XmuShapeRoundedRectangle
+
+extern WidgetClass commandWidgetClass;
+
+typedef struct _CommandClassRec *CommandWidgetClass;
+typedef struct _CommandRec *CommandWidget;
+
+#endif /* _XawCommand_h */
diff --git a/src/CommandP.h b/src/CommandP.h
new file mode 100644
index 0000000..8478b43
--- /dev/null
+++ b/src/CommandP.h
@@ -0,0 +1,143 @@
+/*
+* $XConsortium: CommandP.h,v 1.31 94/04/17 20:12:01 rws Exp $
+*/
+
+
+/***********************************************************
+
+Copyright (c) 1987, 1988 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.
+
+******************************************************************/
+
+/*
+ * CommandP.h - Private definitions for Command widget
+ *
+ */
+
+#ifndef _XawCommandP_h
+#define _XawCommandP_h
+
+#include <X11/Xaw3d/Command.h>
+#include <X11/Xaw3d/LabelP.h>
+
+/***********************************************************************
+ *
+ * Command Widget Private Data
+ *
+ ***********************************************************************/
+
+typedef enum {
+ HighlightNone, /* Do not highlight. */
+ HighlightWhenUnset, /* Highlight only when unset, this is
+ to preserve current command widget
+ functionality. */
+ HighlightAlways /* Always highlight, lets the toggle widget
+ and other subclasses do the right thing. */
+} XtCommandHighlight;
+
+/************************************
+ *
+ * Class structure
+ *
+ ***********************************/
+
+
+ /* New fields for the Command widget class record */
+typedef struct _CommandClass
+ {
+ int makes_compiler_happy; /* not used */
+ } CommandClassPart;
+
+ /* Full class record declaration */
+typedef struct _CommandClassRec {
+ CoreClassPart core_class;
+ SimpleClassPart simple_class;
+ ThreeDClassPart threeD_class;
+ LabelClassPart label_class;
+ CommandClassPart command_class;
+} CommandClassRec;
+
+extern CommandClassRec commandClassRec;
+
+/***************************************
+ *
+ * Instance (widget) structure
+ *
+ **************************************/
+
+ /* New fields for the Command widget record */
+typedef struct {
+ /* resources */
+ Dimension highlight_thickness;
+ XtCallbackList callbacks;
+
+ /* private state */
+ Pixmap gray_pixmap;
+ GC normal_GC;
+ GC inverse_GC;
+ Boolean set;
+ XtCommandHighlight highlighted;
+ Dimension shadow_width;
+ /* more resources */
+ int shape_style;
+ Dimension corner_round;
+} CommandPart;
+
+
+/* XtEventsPtr eventTable;*/
+
+
+ /* Full widget declaration */
+typedef struct _CommandRec {
+ CorePart core;
+ SimplePart simple;
+ ThreeDPart threeD;
+ LabelPart label;
+ CommandPart command;
+} CommandRec;
+
+#endif /* _XawCommandP_h */
+
+
diff --git a/src/Dialog.c b/src/Dialog.c
new file mode 100644
index 0000000..aec1ace
--- /dev/null
+++ b/src/Dialog.c
@@ -0,0 +1,448 @@
+/* $XConsortium: Dialog.c,v 1.48 94/04/17 20:12:02 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.
+
+******************************************************************/
+
+/* NOTE: THIS IS NOT A WIDGET! Rather, this is an interface to a widget.
+ It implements policy, and gives a (hopefully) easier-to-use interface
+ than just directly making your own form. */
+
+
+#include <X11/IntrinsicP.h>
+#include <X11/Xos.h>
+#include <X11/StringDefs.h>
+#include <X11/Xmu/Misc.h>
+
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/AsciiText.h>
+#include <X11/Xaw3d/Command.h>
+#include <X11/Xaw3d/Label.h>
+#include <X11/Xaw3d/DialogP.h>
+#include <X11/Xaw3d/Cardinals.h>
+
+/*
+ * After we have set the string in the value widget we set the
+ * string to a magic value. So that when a SetValues request is made
+ * on the dialog value we will notice it, and reset the string.
+ */
+
+#define MAGIC_VALUE ((char *) 3)
+
+#define streq(a,b) (strcmp( (a), (b) ) == 0)
+
+static XtResource resources[] = {
+ {XtNlabel, XtCLabel, XtRString, sizeof(String),
+ XtOffsetOf(DialogRec, dialog.label), XtRString, NULL},
+ {XtNvalue, XtCValue, XtRString, sizeof(String),
+ XtOffsetOf(DialogRec, dialog.value), XtRString, NULL},
+ {XtNicon, XtCIcon, XtRBitmap, sizeof(Pixmap),
+ XtOffsetOf(DialogRec, dialog.icon), XtRImmediate, 0},
+};
+
+static void Initialize(), ConstraintInitialize(), CreateDialogValueWidget(),
+ GetValuesHook();
+
+static Boolean SetValues();
+
+DialogClassRec dialogClassRec = {
+ { /* core_class fields */
+ /* superclass */ (WidgetClass) &formClassRec,
+ /* class_name */ "Dialog",
+ /* widget_size */ sizeof(DialogRec),
+ /* class_initialize */ XawInitializeWidgetSet,
+ /* class_part init */ 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 */ NULL,
+ /* resize */ XtInheritResize,
+ /* expose */ XtInheritExpose,
+ /* set_values */ SetValues,
+ /* set_values_hook */ NULL,
+ /* set_values_almost */ XtInheritSetValuesAlmost,
+ /* get_values_hook */ GetValuesHook,
+ /* accept_focus */ NULL,
+ /* version */ XtVersion,
+ /* callback_private */ NULL,
+ /* tm_table */ NULL,
+ /* query_geometry */ XtInheritQueryGeometry,
+ /* display_accelerator*/ XtInheritDisplayAccelerator,
+ /* extension */ NULL
+ },
+ { /* composite_class fields */
+ /* geometry_manager */ XtInheritGeometryManager,
+ /* change_managed */ XtInheritChangeManaged,
+ /* insert_child */ XtInheritInsertChild,
+ /* delete_child */ XtInheritDeleteChild,
+ /* extension */ NULL
+ },
+ { /* constraint_class fields */
+ /* subresourses */ NULL,
+ /* subresource_count */ 0,
+ /* constraint_size */ sizeof(DialogConstraintsRec),
+ /* initialize */ ConstraintInitialize,
+ /* destroy */ NULL,
+ /* set_values */ NULL,
+ /* extension */ NULL
+ },
+ { /* form_class fields */
+ /* layout */ XtInheritLayout
+ },
+ { /* dialog_class fields */
+ /* empty */ 0
+ }
+};
+
+WidgetClass dialogWidgetClass = (WidgetClass)&dialogClassRec;
+
+/* ARGSUSED */
+static void Initialize(request, new, args, num_args)
+Widget request, new;
+ArgList args;
+Cardinal *num_args;
+{
+ DialogWidget dw = (DialogWidget)new;
+ Arg arglist[9];
+ Cardinal arg_cnt = 0;
+
+ XtSetArg(arglist[arg_cnt], XtNborderWidth, 0); arg_cnt++;
+ XtSetArg(arglist[arg_cnt], XtNleft, XtChainLeft); arg_cnt++;
+
+ if (dw->dialog.icon != (Pixmap)0) {
+ XtSetArg(arglist[arg_cnt], XtNbitmap, dw->dialog.icon); arg_cnt++;
+ XtSetArg(arglist[arg_cnt], XtNright, XtChainLeft); arg_cnt++;
+ dw->dialog.iconW =
+ XtCreateManagedWidget( "icon", labelWidgetClass,
+ new, arglist, arg_cnt );
+ arg_cnt = 2;
+ XtSetArg(arglist[arg_cnt], XtNfromHoriz, dw->dialog.iconW);arg_cnt++;
+ } else dw->dialog.iconW = (Widget)NULL;
+
+ XtSetArg(arglist[arg_cnt], XtNlabel, dw->dialog.label); arg_cnt++;
+ XtSetArg(arglist[arg_cnt], XtNright, XtChainRight); arg_cnt++;
+
+ dw->dialog.labelW = XtCreateManagedWidget( "label", labelWidgetClass,
+ new, arglist, arg_cnt);
+
+ if (dw->dialog.iconW != (Widget)NULL &&
+ (dw->dialog.labelW->core.height < dw->dialog.iconW->core.height)) {
+ XtSetArg( arglist[0], XtNheight, dw->dialog.iconW->core.height );
+ XtSetValues( dw->dialog.labelW, arglist, ONE );
+ }
+ if (dw->dialog.value != NULL)
+ CreateDialogValueWidget( (Widget) dw);
+ else
+ dw->dialog.valueW = NULL;
+}
+
+/* ARGSUSED */
+static void ConstraintInitialize(request, new, args, num_args)
+Widget request, new;
+ArgList args;
+Cardinal *num_args;
+{
+ DialogWidget dw = (DialogWidget)new->core.parent;
+ DialogConstraints constraint = (DialogConstraints)new->core.constraints;
+
+ if (!XtIsSubclass(new, commandWidgetClass)) /* if not a button */
+ return; /* then just use defaults */
+
+ constraint->form.left = constraint->form.right = XtChainLeft;
+ if (dw->dialog.valueW == NULL)
+ constraint->form.vert_base = dw->dialog.labelW;
+ else
+ constraint->form.vert_base = dw->dialog.valueW;
+
+ if (dw->composite.num_children > 1) {
+ WidgetList children = dw->composite.children;
+ Widget *childP;
+ for (childP = children + dw->composite.num_children - 1;
+ childP >= children; childP-- ) {
+ if (*childP == dw->dialog.labelW || *childP == dw->dialog.valueW)
+ break;
+ if (XtIsManaged(*childP) &&
+ XtIsSubclass(*childP, commandWidgetClass)) {
+ constraint->form.horiz_base = *childP;
+ break;
+ }
+ }
+ }
+}
+
+#define ICON 0
+#define LABEL 1
+#define NUM_CHECKS 2
+
+/* ARGSUSED */
+static Boolean SetValues(current, request, new, in_args, in_num_args)
+Widget current, request, new;
+ArgList in_args;
+Cardinal *in_num_args;
+{
+ DialogWidget w = (DialogWidget)new;
+ DialogWidget old = (DialogWidget)current;
+ Arg args[5];
+ Cardinal num_args;
+ int i;
+ Boolean checks[NUM_CHECKS];
+
+ for (i = 0; i < NUM_CHECKS; i++)
+ checks[i] = FALSE;
+
+ for (i = 0; i < *in_num_args; i++) {
+ if (streq(XtNicon, in_args[i].name))
+ checks[ICON] = TRUE;
+ if (streq(XtNlabel, in_args[i].name))
+ checks[LABEL] = TRUE;
+ }
+
+ if (checks[ICON]) {
+ if (w->dialog.icon != (Pixmap)0) {
+ XtSetArg( args[0], XtNbitmap, w->dialog.icon );
+ if (old->dialog.iconW != (Widget)NULL) {
+ XtSetValues( old->dialog.iconW, args, ONE );
+ } else {
+ XtSetArg( args[1], XtNborderWidth, 0);
+ XtSetArg( args[2], XtNleft, XtChainLeft);
+ XtSetArg( args[3], XtNright, XtChainLeft);
+ w->dialog.iconW =
+ XtCreateWidget( "icon", labelWidgetClass,
+ new, args, FOUR );
+ ((DialogConstraints)w->dialog.labelW->core.constraints)->
+ form.horiz_base = w->dialog.iconW;
+ XtManageChild(w->dialog.iconW);
+ }
+ } else if (old->dialog.icon != (Pixmap)0) {
+ ((DialogConstraints)w->dialog.labelW->core.constraints)->
+ form.horiz_base = (Widget)NULL;
+ XtDestroyWidget(old->dialog.iconW);
+ w->dialog.iconW = (Widget)NULL;
+ }
+ }
+
+ if ( checks[LABEL] ) {
+ num_args = 0;
+ XtSetArg( args[num_args], XtNlabel, w->dialog.label ); num_args++;
+ if (w->dialog.iconW != (Widget)NULL &&
+ (w->dialog.labelW->core.height <= w->dialog.iconW->core.height)) {
+ XtSetArg(args[num_args], XtNheight, w->dialog.iconW->core.height);
+ num_args++;
+ }
+ XtSetValues( w->dialog.labelW, args, num_args );
+ }
+
+ if ( w->dialog.value != old->dialog.value ) {
+ if (w->dialog.value == NULL) /* only get here if it
+ wasn't NULL before. */
+ XtDestroyWidget(old->dialog.valueW);
+ else if (old->dialog.value == NULL) { /* create a new value widget. */
+ w->core.width = old->core.width;
+ w->core.height = old->core.height;
+#ifdef notdef
+/* this would be correct if Form had the same semantics on Resize
+ * as on MakeGeometryRequest. Unfortunately, Form botched it, so
+ * any subclasses will currently have to deal with the fact that
+ * we're about to change our real size.
+ */
+ w->form.resize_in_layout = False;
+ CreateDialogValueWidget( (Widget) w);
+ w->core.width = w->form.preferred_width;
+ w->core.height = w->form.preferred_height;
+ w->form.resize_in_layout = True;
+#else /*notdef*/
+ CreateDialogValueWidget( (Widget) w);
+#endif /*notdef*/
+ }
+ else { /* Widget ok, just change string. */
+ Arg args[1];
+ XtSetArg(args[0], XtNstring, w->dialog.value);
+ XtSetValues(w->dialog.valueW, args, ONE);
+ w->dialog.value = MAGIC_VALUE;
+ }
+ }
+ return False;
+}
+
+/* Function Name: GetValuesHook
+ * Description: This is a get values hook routine that gets the
+ * values in the dialog.
+ * Arguments: w - the Text Widget.
+ * args - the argument list.
+ * num_args - the number of args.
+ * Returns: none.
+ */
+
+static void
+GetValuesHook(w, args, num_args)
+Widget w;
+ArgList args;
+Cardinal * num_args;
+{
+ Arg a[1];
+ String s;
+ DialogWidget src = (DialogWidget) w;
+ int i;
+
+ for (i=0; i < *num_args; i++)
+ if (streq(args[i].name, XtNvalue)) {
+ XtSetArg(a[0], XtNstring, &s);
+ XtGetValues(src->dialog.valueW, a, 1);
+ *((char **) args[i].value) = s;
+ }
+}
+
+
+/* Function Name: CreateDialogValueWidget
+ * Description: Creates the dialog widgets value widget.
+ * Arguments: w - the dialog widget.
+ * Returns: none.
+ *
+ * must be called only when w->dialog.value is non-nil.
+ */
+
+static void
+CreateDialogValueWidget(w)
+Widget w;
+{
+ DialogWidget dw = (DialogWidget) w;
+ Arg arglist[10];
+ Cardinal num_args = 0;
+
+#ifdef notdef
+ XtSetArg(arglist[num_args], XtNwidth,
+ dw->dialog.labelW->core.width); num_args++; /* ||| hack */
+#endif /*notdef*/
+ XtSetArg(arglist[num_args], XtNstring, dw->dialog.value); num_args++;
+ XtSetArg(arglist[num_args], XtNresizable, True); num_args++;
+ XtSetArg(arglist[num_args], XtNresize, XawtextResizeBoth); num_args++;
+ XtSetArg(arglist[num_args], XtNeditType, XawtextEdit); num_args++;
+ XtSetArg(arglist[num_args], XtNfromVert, dw->dialog.labelW); num_args++;
+ XtSetArg(arglist[num_args], XtNleft, XtChainLeft); num_args++;
+ XtSetArg(arglist[num_args], XtNright, XtChainRight); num_args++;
+
+ dw->dialog.valueW = XtCreateWidget("value", asciiTextWidgetClass,
+ w, arglist, num_args);
+
+ /* if the value widget is being added after buttons,
+ * then the buttons need new layout constraints.
+ */
+ if (dw->composite.num_children > 1) {
+ WidgetList children = dw->composite.children;
+ Widget *childP;
+ for (childP = children + dw->composite.num_children - 1;
+ childP >= children; childP-- ) {
+ if (*childP == dw->dialog.labelW || *childP == dw->dialog.valueW)
+ continue;
+ if (XtIsManaged(*childP) &&
+ XtIsSubclass(*childP, commandWidgetClass)) {
+ ((DialogConstraints)(*childP)->core.constraints)->
+ form.vert_base = dw->dialog.valueW;
+ }
+ }
+ }
+ XtManageChild(dw->dialog.valueW);
+
+/*
+ * Value widget gets the keyboard focus.
+ */
+
+ XtSetKeyboardFocus(w, dw->dialog.valueW);
+ dw->dialog.value = MAGIC_VALUE;
+}
+
+
+void
+#if NeedFunctionPrototypes
+XawDialogAddButton(Widget dialog, _Xconst char* name, XtCallbackProc function,
+ XtPointer param)
+#else
+XawDialogAddButton(dialog, name, function, param)
+Widget dialog;
+String name;
+XtCallbackProc function;
+XtPointer param;
+#endif
+{
+/*
+ * Correct Constraints are all set in ConstraintInitialize().
+ */
+ Widget button;
+
+ button = XtCreateManagedWidget( name, commandWidgetClass, dialog,
+ (ArgList)NULL, (Cardinal)0 );
+
+ if (function != NULL) /* don't add NULL callback func. */
+ XtAddCallback(button, XtNcallback, function, param);
+}
+
+
+char *
+#if NeedFunctionPrototypes
+XawDialogGetValueString(Widget w)
+#else
+XawDialogGetValueString(w)
+Widget w;
+#endif
+{
+ Arg args[1];
+ char * value;
+
+ XtSetArg(args[0], XtNstring, &value);
+ XtGetValues( ((DialogWidget)w)->dialog.valueW, args, ONE);
+ return(value);
+}
diff --git a/src/Dialog.h b/src/Dialog.h
new file mode 100644
index 0000000..74ddcfc
--- /dev/null
+++ b/src/Dialog.h
@@ -0,0 +1,109 @@
+/* $XConsortium: Dialog.h,v 1.28 94/04/17 20:12:03 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.
+
+******************************************************************/
+
+#ifndef _XawDialog_h
+#define _XawDialog_h
+
+#include <X11/Xaw3d/Form.h>
+
+/***********************************************************************
+ *
+ * Dialog Widget
+ *
+ ***********************************************************************/
+
+/* Parameters:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ background Background Pixel XtDefaultBackground
+ border BorderColor Pixel XtDefaultForeground
+ borderWidth BorderWidth Dimension 1
+ destroyCallback Callback Pointer NULL
+ height Height Dimension computed at create
+ icon Icon Pixmap 0
+ label Label String NULL
+ mappedWhenManaged MappedWhenManaged Boolean True
+ sensitive Sensitive Boolean True
+ value Value String NULL
+ width Width Dimension computed at create
+ x Position Position 0
+ y Position Position 0
+
+*/
+
+#define XtCIcon "Icon"
+#define XtNicon "icon"
+
+typedef struct _DialogClassRec *DialogWidgetClass;
+typedef struct _DialogRec *DialogWidget;
+
+extern WidgetClass dialogWidgetClass;
+
+_XFUNCPROTOBEGIN
+
+extern void XawDialogAddButton(
+#if NeedFunctionPrototypes
+ Widget /* dialog */,
+ _Xconst char* /* name */,
+ XtCallbackProc /* function */,
+ XtPointer /* client_data */
+#endif
+);
+
+extern char *XawDialogGetValueString(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+_XFUNCPROTOEND
+
+#endif /* _XawDialog_h */
diff --git a/src/DialogP.h b/src/DialogP.h
new file mode 100644
index 0000000..77c74f1
--- /dev/null
+++ b/src/DialogP.h
@@ -0,0 +1,98 @@
+/* $XConsortium: DialogP.h,v 1.13 94/04/17 20:12:05 kit Exp $ */
+
+
+/***********************************************************
+
+Copyright (c) 1987, 1988 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.
+
+******************************************************************/
+
+/* Private definitions for Dialog widget */
+
+#ifndef _DialogP_h
+#define _DialogP_h
+
+#include <X11/Xaw3d/Dialog.h>
+#include <X11/Xaw3d/FormP.h>
+
+typedef struct {int empty;} DialogClassPart;
+
+typedef struct _DialogClassRec {
+ CoreClassPart core_class;
+ CompositeClassPart composite_class;
+ ConstraintClassPart constraint_class;
+ FormClassPart form_class;
+ DialogClassPart dialog_class;
+} DialogClassRec;
+
+extern DialogClassRec dialogClassRec;
+
+typedef struct _DialogPart {
+ /* resources */
+ String label; /* description of the dialog */
+ String value; /* for the user response */
+ Pixmap icon; /* icon bitmap */
+ /* private data */
+ Widget iconW; /* widget to display the icon */
+ Widget labelW; /* widget to display description*/
+ Widget valueW; /* user response TextWidget */
+} DialogPart;
+
+typedef struct _DialogRec {
+ CorePart core;
+ CompositePart composite;
+ ConstraintPart constraint;
+ FormPart form;
+ DialogPart dialog;
+} DialogRec;
+
+typedef struct {int empty;} DialogConstraintsPart;
+
+typedef struct _DialogConstraintsRec {
+ FormConstraintsPart form;
+ DialogConstraintsPart dialog;
+} DialogConstraintsRec, *DialogConstraints;
+
+#endif /* _DialogP_h */
diff --git a/src/Form.c b/src/Form.c
new file mode 100644
index 0000000..c4eae4b
--- /dev/null
+++ b/src/Form.c
@@ -0,0 +1,848 @@
+/* $XConsortium: Form.c,v 1.52 94/04/17 20:12:06 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.
+
+******************************************************************/
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xmu/Converters.h>
+#include <X11/Xmu/CharSet.h>
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/FormP.h>
+
+/* Private Definitions */
+
+static int default_value = -99999;
+
+#define Offset(field) XtOffsetOf(FormRec, form.field)
+static XtResource resources[] = {
+ {XtNdefaultDistance, XtCThickness, XtRInt, sizeof(int),
+ Offset(default_spacing), XtRImmediate, (XtPointer)4}
+};
+#undef Offset
+
+static XtEdgeType defEdge = XtRubber;
+
+#define Offset(field) XtOffsetOf(FormConstraintsRec, form.field)
+static XtResource formConstraintResources[] = {
+ {XtNtop, XtCEdge, XtREdgeType, sizeof(XtEdgeType),
+ Offset(top), XtREdgeType, (XtPointer)&defEdge},
+ {XtNbottom, XtCEdge, XtREdgeType, sizeof(XtEdgeType),
+ Offset(bottom), XtREdgeType, (XtPointer)&defEdge},
+ {XtNleft, XtCEdge, XtREdgeType, sizeof(XtEdgeType),
+ Offset(left), XtREdgeType, (XtPointer)&defEdge},
+ {XtNright, XtCEdge, XtREdgeType, sizeof(XtEdgeType),
+ Offset(right), XtREdgeType, (XtPointer)&defEdge},
+ {XtNhorizDistance, XtCThickness, XtRInt, sizeof(int),
+ Offset(dx), XtRInt, (XtPointer) &default_value},
+ {XtNfromHoriz, XtCWidget, XtRWidget, sizeof(Widget),
+ Offset(horiz_base), XtRWidget, (XtPointer)NULL},
+ {XtNvertDistance, XtCThickness, XtRInt, sizeof(int),
+ Offset(dy), XtRInt, (XtPointer) &default_value},
+ {XtNfromVert, XtCWidget, XtRWidget, sizeof(Widget),
+ Offset(vert_base), XtRWidget, (XtPointer)NULL},
+ {XtNresizable, XtCBoolean, XtRBoolean, sizeof(Boolean),
+ Offset(allow_resize), XtRImmediate, (XtPointer) FALSE},
+};
+#undef Offset
+
+static void ClassInitialize(), ClassPartInitialize(), Initialize(), Resize();
+static void ConstraintInitialize();
+static Boolean SetValues(), ConstraintSetValues();
+static XtGeometryResult GeometryManager(), PreferredGeometry();
+static void ChangeManaged();
+static Boolean Layout();
+
+static void LayoutChild(), ResizeChildren();
+
+FormClassRec formClassRec = {
+ { /* core_class fields */
+ /* superclass */ (WidgetClass) &constraintClassRec,
+ /* class_name */ "Form",
+ /* widget_size */ sizeof(FormRec),
+ /* class_initialize */ ClassInitialize,
+ /* class_part_init */ ClassPartInitialize,
+ /* 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 */ NULL,
+ /* resize */ Resize,
+ /* expose */ XtInheritExpose,
+ /* 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 */ PreferredGeometry,
+ /* display_accelerator*/ XtInheritDisplayAccelerator,
+ /* extension */ NULL
+ },
+ { /* composite_class fields */
+ /* geometry_manager */ GeometryManager,
+ /* change_managed */ ChangeManaged,
+ /* insert_child */ XtInheritInsertChild,
+ /* delete_child */ XtInheritDeleteChild,
+ /* extension */ NULL
+ },
+ { /* constraint_class fields */
+ /* subresourses */ formConstraintResources,
+ /* subresource_count */ XtNumber(formConstraintResources),
+ /* constraint_size */ sizeof(FormConstraintsRec),
+ /* initialize */ ConstraintInitialize,
+ /* destroy */ NULL,
+ /* set_values */ ConstraintSetValues,
+ /* extension */ NULL
+ },
+ { /* form_class fields */
+ /* layout */ Layout
+ }
+};
+
+WidgetClass formWidgetClass = (WidgetClass)&formClassRec;
+
+/****************************************************************
+ *
+ * Private Procedures
+ *
+ ****************************************************************/
+
+
+static XrmQuark XtQChainLeft, XtQChainRight, XtQChainTop,
+ XtQChainBottom, XtQRubber;
+
+/* ARGSUSED */
+static void _CvtStringToEdgeType(args, num_args, fromVal, toVal)
+ XrmValuePtr args; /* unused */
+ Cardinal *num_args; /* unused */
+ XrmValuePtr fromVal;
+ XrmValuePtr toVal;
+{
+ static XtEdgeType edgeType;
+ XrmQuark q;
+ char lowerName[40];
+
+ if (strlen ((char*) fromVal->addr) < sizeof lowerName) {
+ XmuCopyISOLatin1Lowered (lowerName, (char*)fromVal->addr);
+ q = XrmStringToQuark(lowerName);
+ if (q == XtQChainLeft) edgeType = XtChainLeft;
+ else if (q == XtQChainRight) edgeType = XtChainRight;
+ else if (q == XtQChainTop) edgeType = XtChainTop;
+ else if (q == XtQChainBottom) edgeType = XtChainBottom;
+ else if (q == XtQRubber) edgeType = XtRubber;
+ else {
+ toVal->size = 0;
+ toVal->addr = NULL;
+ return;
+ }
+ toVal->size = sizeof edgeType;
+ toVal->addr = (XPointer) &edgeType;
+ return;
+ }
+ toVal->addr = NULL;
+ toVal->size = 0;
+}
+
+static void ClassInitialize()
+{
+ static XtConvertArgRec parentCvtArgs[] = {
+ {XtBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.parent),
+ sizeof(Widget)}
+ };
+ XawInitializeWidgetSet();
+ XtQChainLeft = XrmPermStringToQuark("chainleft");
+ XtQChainRight = XrmPermStringToQuark("chainright");
+ XtQChainTop = XrmPermStringToQuark("chaintop");
+ XtQChainBottom = XrmPermStringToQuark("chainbottom");
+ XtQRubber = XrmPermStringToQuark("rubber");
+
+ XtAddConverter( XtRString, XtREdgeType, _CvtStringToEdgeType,
+ (XtConvertArgList)NULL, 0 );
+ XtSetTypeConverter (XtRString, XtRWidget, XmuNewCvtStringToWidget,
+ parentCvtArgs, XtNumber(parentCvtArgs), XtCacheNone,
+ (XtDestructor)NULL);
+}
+
+static void ClassPartInitialize(class)
+ WidgetClass class;
+{
+ FormWidgetClass c = (FormWidgetClass)class;
+ FormWidgetClass super = (FormWidgetClass)
+ c->core_class.superclass;
+
+ if (c->form_class.layout == XtInheritLayout)
+ c->form_class.layout = super->form_class.layout;
+}
+
+/* ARGSUSED */
+static void Initialize(request, new, args, num_args)
+ Widget request, new;
+ ArgList args;
+ Cardinal *num_args;
+{
+ FormWidget fw = (FormWidget)new;
+
+ fw->form.old_width = fw->core.width;
+ fw->form.old_height = fw->core.height;
+ fw->form.no_refigure = False;
+ fw->form.needs_relayout = False;
+ fw->form.resize_in_layout = True;
+ fw->form.resize_is_no_op = False;
+}
+
+/* Function Name: ChangeFormGeometry
+ * Description: Ask the parent to change the form widget's geometry.
+ * Arguments: w - the Form widget.
+ * query_only - TRUE if this is only a query.
+ * width, height - the new width and height.
+ * ret_width, ret_height - the actual size the form is allowed
+ * to resize to.
+ * Returns: TRUE of children may always be resized.
+ */
+
+static Boolean
+ChangeFormGeometry(w, query_only, width, height, ret_width, ret_height)
+Widget w;
+Boolean query_only;
+Dimension width, height;
+Dimension *ret_width, *ret_height;
+{
+ FormWidget fw = (FormWidget) w;
+ Boolean always_resize_children;
+ XtGeometryResult result;
+ XtWidgetGeometry request, return_request;
+
+ /*
+ * If we are already at the desired size then there is no need
+ * to ask our parent of we can change size.
+ */
+
+ if ( (width == fw->core.width) && (height == fw->core.height) )
+ return(TRUE);
+
+ request.width = width;
+ request.height = height;
+ request.request_mode = CWWidth | CWHeight;
+ if (query_only)
+ request.request_mode |= XtCWQueryOnly;
+
+ /*
+ * Do no invoke the resize rules if our size changes here.
+ */
+
+ fw->form.resize_is_no_op = TRUE;
+
+ result = XtMakeGeometryRequest(w, &request, &return_request);
+ if (result == XtGeometryAlmost) {
+ request = return_request;
+ (void) XtMakeGeometryRequest(w, &request, &return_request);
+ always_resize_children = FALSE;
+ }
+ else
+ always_resize_children = (result == XtGeometryYes);
+
+ fw->form.resize_is_no_op = FALSE;
+
+ if (ret_width != NULL)
+ *ret_width = request.width;
+ if (ret_height != NULL)
+ *ret_height = request.height;
+
+ return(always_resize_children);
+}
+
+/* Function Name: Layout
+ * Description: Moves all the children around.
+ * Arguments: fw - the Form widget.
+ * width, height - ** UNUSED **.
+ * force_relayout - will force the children to be
+ * moved, even if some go past the edge
+ * of the form.
+ * Returns: True if the children are allowed to move from their
+ * current locations to the new ones.
+ */
+
+/* ARGSUSED */
+static Boolean Layout(fw, width, height, force_relayout)
+ FormWidget fw;
+ Dimension width, height;
+ Boolean force_relayout;
+{
+ int num_children = fw->composite.num_children;
+ WidgetList children = fw->composite.children;
+ Widget *childP;
+ Dimension maxx, maxy;
+ Boolean ret_val;
+
+ for (childP = children; childP - children < num_children; childP++) {
+ FormConstraints form = (FormConstraints)(*childP)->core.constraints;
+ form->form.layout_state = LayoutPending;
+ }
+
+ maxx = maxy = 1;
+ for (childP = children; childP - children < num_children; childP++) {
+ if (XtIsManaged(*childP)) {
+ FormConstraints form;
+ Position x, y;
+
+ form = (FormConstraints)(*childP)->core.constraints;
+
+ LayoutChild(*childP);
+
+ x = form->form.new_x + (*childP)->core.width +
+ ((*childP)->core.border_width << 1);
+ if (x > (int)maxx)
+ maxx = x;
+
+ y = form->form.new_y + (*childP)->core.height +
+ ((*childP)->core.border_width << 1);
+ if (y > (int)maxy)
+ maxy = y;
+ }
+ }
+
+ fw->form.preferred_width = (maxx += fw->form.default_spacing);
+ fw->form.preferred_height = (maxy += fw->form.default_spacing);
+
+ if (fw->form.resize_in_layout) {
+ Boolean always_resize_children;
+
+ always_resize_children =
+ ChangeFormGeometry( (Widget) fw, FALSE, maxx, maxy,
+ (Dimension *)NULL, (Dimension *)NULL);
+
+ fw->form.old_width = fw->core.width;
+ fw->form.old_height = fw->core.height;
+
+ ret_val = (always_resize_children || ( (fw->core.width >= maxx) &&
+ (fw->core.height >= maxy)));
+
+ if (force_relayout)
+ ret_val = TRUE;
+
+ if (ret_val)
+ ResizeChildren((Widget) fw);
+ }
+ else
+ ret_val = False;
+
+ fw->form.needs_relayout = False;
+ return ret_val;
+}
+
+/* Function Name: ResizeChildren
+ * Description: Resizes all children to new_x and new_y.
+ * Arguments: w - the form widget.
+ * Returns: none.
+ */
+
+static void ResizeChildren(w)
+Widget w;
+{
+ FormWidget fw = (FormWidget) w;
+ int num_children = fw->composite.num_children;
+ WidgetList children = fw->composite.children;
+ Widget *childP;
+
+ for (childP = children; childP - children < num_children; childP++) {
+ FormConstraints form;
+
+ if (!XtIsManaged(*childP))
+ continue;
+
+ form = (FormConstraints)(*childP)->core.constraints;
+ if (fw->form.no_refigure) {
+/*
+ * I am changing the widget wrapper w/o modifing the window. This is
+ * risky, but I can get away with it since I am the parent of this
+ * widget, and he must ask me for any geometry changes.
+ *
+ * The window will be updated when no_refigure is set back to False.
+ */
+ (*childP)->core.x = form->form.new_x;
+ (*childP)->core.y = form->form.new_y;
+ }
+ else
+ XtMoveWidget(*childP, form->form.new_x, form->form.new_y);
+ }
+}
+
+
+static void LayoutChild(w)
+ Widget w;
+{
+ FormConstraints form = (FormConstraints)w->core.constraints;
+ Widget ref;
+
+ switch (form->form.layout_state) {
+
+ case LayoutPending:
+ form->form.layout_state = LayoutInProgress;
+ break;
+
+ case LayoutDone:
+ return;
+
+ case LayoutInProgress:
+ {
+ String subs[2];
+ Cardinal num_subs = 2;
+ subs[0] = w->core.name;
+ subs[1] = w->core.parent->core.name;
+ XtAppWarningMsg(XtWidgetToApplicationContext(w),
+ "constraintLoop","xawFormLayout","XawToolkitError",
+ "constraint loop detected while laying out child '%s' in FormWidget '%s'",
+ subs, &num_subs);
+ return;
+ }
+ }
+
+ form->form.new_x = form->form.dx;
+ form->form.new_y = form->form.dy;
+ if ((ref = form->form.horiz_base) != (Widget)NULL) {
+ FormConstraints ref_form = (FormConstraints) ref->core.constraints;
+
+ LayoutChild(ref);
+ form->form.new_x += (ref_form->form.new_x +
+ ref->core.width + (ref->core.border_width << 1));
+ }
+ if ((ref = form->form.vert_base) != (Widget)NULL) {
+ FormConstraints ref_form = (FormConstraints) ref->core.constraints;
+
+ LayoutChild(ref);
+ form->form.new_y += (ref_form->form.new_y +
+ ref->core.height + (ref->core.border_width << 1));
+ }
+
+ form->form.layout_state = LayoutDone;
+}
+
+
+static Position TransformCoord(loc, old, new, type)
+ Position loc;
+ Dimension old, new;
+ XtEdgeType type;
+{
+ if (type == XtRubber) {
+ if ( ((int) old) > 0)
+ loc = (int)(loc * new) / (int)old;
+ }
+ else if (type == XtChainBottom || type == XtChainRight)
+ loc += (Position)new - (Position)old;
+
+ /* I don't see any problem with returning values less than zero. */
+
+ return (loc);
+}
+
+static void Resize(w)
+ Widget w;
+{
+ FormWidget fw = (FormWidget)w;
+ WidgetList children = fw->composite.children;
+ int num_children = fw->composite.num_children;
+ Widget *childP;
+ Position x, y;
+ Dimension width, height;
+
+ if (!fw->form.resize_is_no_op)
+ for (childP = children; childP - children < num_children; childP++) {
+ FormConstraints form= (FormConstraints)(*childP)->core.constraints;
+ if (!XtIsManaged(*childP)) continue;
+ x = TransformCoord( (*childP)->core.x, fw->form.old_width,
+ fw->core.width, form->form.left );
+ y = TransformCoord( (*childP)->core.y, fw->form.old_height,
+ fw->core.height, form->form.top );
+
+ form->form.virtual_width =
+ TransformCoord((Position)((*childP)->core.x
+ + form->form.virtual_width
+ + 2 * (*childP)->core.border_width),
+ fw->form.old_width, fw->core.width,
+ form->form.right )
+ - (x + 2 * (*childP)->core.border_width);
+
+ form->form.virtual_height =
+ TransformCoord((Position)((*childP)->core.y
+ + form->form.virtual_height
+ + 2 * (*childP)->core.border_width),
+ fw->form.old_height, fw->core.height,
+ form->form.bottom )
+ - ( y + 2 * (*childP)->core.border_width);
+
+ width = (Dimension)
+ (form->form.virtual_width < 1) ? 1 : form->form.virtual_width;
+ height = (Dimension)
+ (form->form.virtual_height < 1) ? 1 : form->form.virtual_height;
+
+ XtConfigureWidget(*childP,x,y, (Dimension)width, (Dimension)height,
+ (*childP)->core.border_width );
+ }
+
+ fw->form.old_width = fw->core.width;
+ fw->form.old_height = fw->core.height;
+}
+
+/*
+ * I don't want to even think about what ``Almost'' would mean - Chris.
+ */
+
+/* ARGSUSED */
+static XtGeometryResult GeometryManager(w, request, reply)
+ Widget w;
+ XtWidgetGeometry *request;
+ XtWidgetGeometry *reply; /* RETURN */
+{
+ Dimension old_width, old_height;
+ FormWidget fw = (FormWidget) XtParent(w);
+ FormConstraints form = (FormConstraints) w->core.constraints;
+ XtWidgetGeometry allowed;
+ XtGeometryResult ret_val;
+
+ if ((request->request_mode & ~(XtCWQueryOnly | CWWidth | CWHeight)) ||
+ !form->form.allow_resize) {
+
+ /* If GeometryManager is invoked during a SetValues call on a child
+ * then it is necessary to compute a new layout if ConstraintSetValues
+ * allowed any constraint changes. */
+
+ if (fw->form.needs_relayout)
+ (*((FormWidgetClass)fw->core.widget_class)->form_class.layout)
+ (fw, 0, 0, True);
+ return(XtGeometryNo);
+ }
+
+ if (request->request_mode & CWWidth)
+ allowed.width = request->width;
+ else
+ allowed.width = w->core.width;
+
+ if (request->request_mode & CWHeight)
+ allowed.height = request->height;
+ else
+ allowed.height = w->core.height;
+
+ if (allowed.width == w->core.width && allowed.height == w->core.height) {
+
+ /* If GeometryManager is invoked during a SetValues call on a child
+ * then it is necessary to compute a new layout if ConstraintSetValues
+ * allowed any constraint changes. */
+
+ if (fw->form.needs_relayout)
+ (*((FormWidgetClass)fw->core.widget_class)->form_class.layout)
+ (fw, 0, 0, True);
+ return(XtGeometryNo);
+ }
+
+ /*
+ * Remember the old size, and then set the size to the requested size.
+ */
+
+ old_width = w->core.width;
+ old_height = w->core.height;
+ w->core.width = allowed.width;
+ w->core.height = allowed.height;
+
+ if (request->request_mode & XtCWQueryOnly) {
+ Boolean always_resize_children;
+ Dimension ret_width, ret_height;
+
+ fw->form.resize_in_layout = FALSE;
+
+ (*((FormWidgetClass)fw->core.widget_class)->form_class.layout)
+ ( fw, w->core.width, w->core.height,
+ FALSE );
+
+ /*
+ * Reset the size of this child back to what it used to be.
+ */
+
+ w->core.width = old_width;
+ w->core.height = old_height;
+
+ fw->form.resize_in_layout = TRUE;
+
+ always_resize_children = ChangeFormGeometry(w, TRUE,
+ fw->form.preferred_width,
+ fw->form.preferred_height,
+ &ret_width, &ret_height);
+
+ if (always_resize_children ||
+ ((ret_width >= fw->form.preferred_width) &&
+ (ret_height >= fw->form.preferred_height)))
+ {
+ ret_val = XtGeometryYes;
+ }
+ else
+ ret_val = XtGeometryNo;
+ }
+ else {
+ if ((*((FormWidgetClass)fw->core.widget_class)->form_class.layout)
+ ( fw, w->core.width, w->core.height,
+ FALSE))
+ {
+ form->form.virtual_width = w->core.width; /* reset virtual */
+ form->form.virtual_height = w->core.height; /* width and height. */
+ if (fw->form.no_refigure) {
+/*
+ * I am changing the widget wrapper w/o modifing the window. This is
+ * risky, but I can get away with it since I am the parent of this
+ * widget, and he must ask me for any geometry changes.
+ *
+ * The window will be updated when no_refigure is set back to False.
+ */
+ form->form.deferred_resize = True;
+ ret_val = XtGeometryDone;
+ }
+ else
+ ret_val = XtGeometryYes;
+ }
+ else {
+ w->core.width = old_width;
+ w->core.height = old_height;
+ ret_val = XtGeometryNo;
+ }
+ }
+
+ return(ret_val);
+}
+
+
+/* ARGSUSED */
+static Boolean SetValues(current, request, new, args, num_args)
+ Widget current, request, new;
+ ArgList args;
+ Cardinal *num_args;
+{
+ return( FALSE );
+}
+
+
+/* ARGSUSED */
+static void ConstraintInitialize(request, new, args, num_args)
+ Widget request, new;
+ ArgList args;
+ Cardinal *num_args;
+{
+ FormConstraints form = (FormConstraints)new->core.constraints;
+ FormWidget fw = (FormWidget)new->core.parent;
+
+ form->form.virtual_width = (int) new->core.width;
+ form->form.virtual_height = (int) new->core.height;
+
+ if (form->form.dx == default_value)
+ form->form.dx = fw->form.default_spacing;
+
+ if (form->form.dy == default_value)
+ form->form.dy = fw->form.default_spacing;
+
+ form->form.deferred_resize = False;
+}
+
+/*ARGSUSED*/
+static Boolean ConstraintSetValues(current, request, new, args, num_args)
+ Widget current, request, new;
+ ArgList args;
+ Cardinal *num_args;
+{
+ FormConstraints cfc = (FormConstraints) current->core.constraints;
+ FormConstraints nfc = (FormConstraints) new->core.constraints;
+
+ if (cfc->form.top != nfc->form.top ||
+ cfc->form.bottom != nfc->form.bottom ||
+ cfc->form.left != nfc->form.left ||
+ cfc->form.right != nfc->form.right ||
+ cfc->form.dx != nfc->form.dx ||
+ cfc->form.dy != nfc->form.dy ||
+ cfc->form.horiz_base != nfc->form.horiz_base ||
+ cfc->form.vert_base != nfc->form.vert_base) {
+
+ FormWidget fp = (FormWidget) XtParent(new);
+
+ /* If there are no subclass ConstraintSetValues procedures remaining
+ * to be invoked, and if there is no geometry request about to be
+ * made, then invoke the new layout now; else defer it. */
+
+ if (XtClass(XtParent(new)) == formWidgetClass &&
+ current->core.x == new->core.x &&
+ current->core.y == new->core.y &&
+ current->core.width == new->core.width &&
+ current->core.height == new->core.height &&
+ current->core.border_width == new->core.border_width)
+ Layout(fp, 0, 0, True);
+ else fp->form.needs_relayout = True;
+ }
+ return( FALSE );
+}
+
+static void ChangeManaged(w)
+ Widget w;
+{
+ FormWidget fw = (FormWidget)w;
+ FormConstraints form;
+ WidgetList children, childP;
+ int num_children = fw->composite.num_children;
+ Widget child;
+
+ /*
+ * Reset virtual width and height for all children.
+ */
+
+ for (children = childP = fw->composite.children ;
+ childP - children < num_children; childP++) {
+ child = *childP;
+ if (XtIsManaged(child)) {
+ form = (FormConstraints)child->core.constraints;
+
+/*
+ * If the size is one (1) then we must not change the virtual sizes, as
+ * they contain useful information. If someone actually wants a widget of
+ * width or height one (1) in a form widget he will lose, can't win them all.
+ *
+ * Chris D. Peterson 2/9/89.
+ */
+
+ if ( child->core.width != 1)
+ form->form.virtual_width = (int) child->core.width;
+ if ( child->core.height != 1)
+ form->form.virtual_height = (int) child->core.height;
+ }
+ }
+ (*((FormWidgetClass)w->core.widget_class)->form_class.layout)
+ ((FormWidget) w, w->core.width,
+ w->core.height, TRUE);
+}
+
+
+static XtGeometryResult PreferredGeometry( widget, request, reply )
+ Widget widget;
+ XtWidgetGeometry *request, *reply;
+{
+ FormWidget w = (FormWidget)widget;
+
+ reply->width = w->form.preferred_width;
+ reply->height = w->form.preferred_height;
+ reply->request_mode = CWWidth | CWHeight;
+ if ( request->request_mode & (CWWidth | CWHeight) ==
+ (CWWidth | CWHeight)
+ && request->width == reply->width
+ && request->height == reply->height)
+ return XtGeometryYes;
+ else if (reply->width == w->core.width && reply->height == w->core.height)
+ return XtGeometryNo;
+ else
+ return XtGeometryAlmost;
+}
+
+
+/**********************************************************************
+ *
+ * Public routines
+ *
+ **********************************************************************/
+
+/*
+ * Set or reset figuring (ignored if not realized)
+ */
+
+void
+#if NeedFunctionPrototypes
+XawFormDoLayout(Widget w,
+#if NeedWidePrototypes
+ int doit)
+#else
+ Boolean doit)
+#endif
+#else
+XawFormDoLayout(w, doit)
+Widget w;
+Boolean doit;
+#endif
+{
+ Widget *childP;
+ FormWidget fw = (FormWidget)w;
+ int num_children = fw->composite.num_children;
+ WidgetList children = fw->composite.children;
+
+ if ( ((fw->form.no_refigure = !doit) == TRUE) || !XtIsRealized(w) )
+ return;
+
+ for (childP = children; childP - children < num_children; childP++) {
+ Widget w = *childP;
+ if (XtIsManaged(w)) {
+ FormConstraints form = (FormConstraints)w->core.constraints;
+
+ /*
+ * Xt Configure widget is too smart, and optimizes out
+ * my changes.
+ */
+
+ XMoveResizeWindow(XtDisplay(w), XtWindow(w),
+ w->core.x, w->core.y,
+ w->core.width, w->core.height);
+
+ if (form->form.deferred_resize &&
+ XtClass(w)->core_class.resize != (XtWidgetProc) NULL) {
+ (*(XtClass(w)->core_class.resize))(w);
+ form->form.deferred_resize = False;
+ }
+ }
+ }
+}
diff --git a/src/Form.h b/src/Form.h
new file mode 100644
index 0000000..f4c9b5c
--- /dev/null
+++ b/src/Form.h
@@ -0,0 +1,168 @@
+/* $XConsortium: Form.h,v 1.30 94/04/17 20:12:08 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.
+
+******************************************************************/
+
+#ifndef _XawForm_h
+#define _XawForm_h
+
+#include <X11/Constraint.h>
+
+/***********************************************************************
+ *
+ * Form Widget
+ *
+ ***********************************************************************/
+
+/* Parameters:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ background Background Pixel XtDefaultBackground
+ border BorderColor Pixel XtDefaultForeground
+ borderWidth BorderWidth Dimension 1
+ defaultDistance Thickness int 4
+ destroyCallback Callback Pointer NULL
+ height Height Dimension computed at realize
+ mappedWhenManaged MappedWhenManaged Boolean True
+ sensitive Sensitive Boolean True
+ width Width Dimension computed at realize
+ x Position Position 0
+ y Position Position 0
+
+*/
+
+/* Constraint parameters:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ bottom Edge XtEdgeType XtRubber
+ fromHoriz Widget Widget (left edge of form)
+ fromVert Widget Widget (top of form)
+ horizDistance Thickness int defaultDistance
+ left Edge XtEdgeType XtRubber
+ resizable Boolean Boolean False
+ right Edge XtEdgeType XtRubber
+ top Edge XtEdgeType XtRubber
+ vertDistance Thickness int defaultDistance
+
+*/
+
+
+#ifndef _XtStringDefs_h_
+#define XtNtop "top"
+#define XtRWidget "Widget"
+#endif
+
+#define XtNdefaultDistance "defaultDistance"
+#define XtNbottom "bottom"
+#define XtNleft "left"
+#define XtNright "right"
+#define XtNfromHoriz "fromHoriz"
+#define XtNfromVert "fromVert"
+#define XtNhorizDistance "horizDistance"
+#define XtNvertDistance "vertDistance"
+#define XtNresizable "resizable"
+
+#define XtCEdge "Edge"
+#define XtCWidget "Widget"
+
+#ifndef _XawEdgeType_e
+#define _XawEdgeType_e
+typedef enum {
+ XawChainTop, /* Keep this edge a constant distance from
+ the top of the form */
+ XawChainBottom, /* Keep this edge a constant distance from
+ the bottom of the form */
+ XawChainLeft, /* Keep this edge a constant distance from
+ the left of the form */
+ XawChainRight, /* Keep this edge a constant distance from
+ the right of the form */
+ XawRubber /* Keep this edge a proportional distance
+ from the edges of the form*/
+} XawEdgeType;
+#endif /* _XawEdgeType_e */
+
+/*
+ * Unfortunatly I missed this definition for R4, so I cannot
+ * protect it with XAW_BC, it looks like this particular problem is
+ * one that we will have to live with for a while.
+ *
+ * Chris D. Peterson - 3/23/90.
+ */
+
+#define XtEdgeType XawEdgeType
+
+#define XtChainTop XawChainTop
+#define XtChainBottom XawChainBottom
+#define XtChainLeft XawChainLeft
+#define XtChainRight XawChainRight
+#define XtRubber XawRubber
+
+typedef struct _FormClassRec *FormWidgetClass;
+typedef struct _FormRec *FormWidget;
+
+extern WidgetClass formWidgetClass;
+
+_XFUNCPROTOBEGIN
+
+extern void XawFormDoLayout(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+#if NeedWidePrototypes
+ /* Boolean */ int /* do_layout */
+#else
+ Boolean /* do_layout */
+#endif
+#endif
+);
+
+_XFUNCPROTOEND
+
+#endif /* _XawForm_h */
diff --git a/src/FormP.h b/src/FormP.h
new file mode 100644
index 0000000..9314015
--- /dev/null
+++ b/src/FormP.h
@@ -0,0 +1,143 @@
+/* $XConsortium: FormP.h,v 1.22 94/04/17 20:12:09 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.
+
+******************************************************************/
+
+/* Form widget private definitions */
+
+#ifndef _XawFormP_h
+#define _XawFormP_h
+
+#include <X11/Xaw3d/Form.h>
+
+#define XtREdgeType "EdgeType"
+
+typedef enum {LayoutPending, LayoutInProgress, LayoutDone} LayoutState;
+#define XtInheritLayout ((Boolean (*)())_XtInherit)
+
+typedef struct {
+ Boolean (*layout)(/* FormWidget, Dimension, Dimension */);
+} FormClassPart;
+
+/*
+ * Layout(
+ * FormWidget w - the widget whose children are to be configured
+ * Dimension w, h - bounding box of layout to be calculated
+ *
+ * Stores preferred geometry in w->form.preferred_{width,height}.
+ * If w->form.resize_in_layout is True, then a geometry request
+ * may be made for the preferred bounding box if necessary.
+ *
+ * Returns True if a geometry request was granted, False otherwise.
+ */
+
+typedef struct _FormClassRec {
+ CoreClassPart core_class;
+ CompositeClassPart composite_class;
+ ConstraintClassPart constraint_class;
+ FormClassPart form_class;
+} FormClassRec;
+
+extern FormClassRec formClassRec;
+
+typedef struct _FormPart {
+ /* resources */
+ int default_spacing; /* default distance between children */
+ /* private state */
+ Dimension old_width, old_height; /* last known dimensions */
+ int no_refigure; /* no re-layout while > 0 */
+ Boolean needs_relayout; /* next time no_refigure == 0 */
+ Boolean resize_in_layout; /* should layout() do geom request? */
+ Dimension preferred_width, preferred_height; /* cached from layout */
+ Boolean resize_is_no_op; /* Causes resize to take not action. */
+} FormPart;
+
+typedef struct _FormRec {
+ CorePart core;
+ CompositePart composite;
+ ConstraintPart constraint;
+ FormPart form;
+} FormRec;
+
+typedef struct _FormConstraintsPart {
+/*
+ * Constraint Resources.
+ */
+ XtEdgeType top, bottom, /* where to drag edge on resize */
+ left, right;
+ int dx; /* desired horiz offset */
+ int dy; /* desired vertical offset */
+ Widget horiz_base; /* measure dx from here if non-null */
+ Widget vert_base; /* measure dy from here if non-null */
+ Boolean allow_resize; /* TRUE if child may request resize */
+
+/*
+ * Private contstraint resources.
+ */
+
+/*
+ * What the size of this child would be if we did not impose the
+ * constraint the width and height must be greater than zero (0).
+ */
+ short virtual_width, virtual_height;
+
+/*
+ * Temporary Storage for children's new possible possition.
+ */
+
+ Position new_x, new_y;
+
+ LayoutState layout_state; /* temporary layout state */
+ Boolean deferred_resize; /* was resized while no_refigure is set */
+} FormConstraintsPart;
+
+typedef struct _FormConstraintsRec {
+ FormConstraintsPart form;
+} FormConstraintsRec, *FormConstraints;
+
+#endif /* _XawFormP_h */
diff --git a/src/Grip.c b/src/Grip.c
new file mode 100644
index 0000000..17c4fc0
--- /dev/null
+++ b/src/Grip.c
@@ -0,0 +1,150 @@
+/* $XConsortium: Grip.c,v 1.33 94/04/17 20:12:10 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.
+
+******************************************************************/
+
+/*
+ * Grip.c - Grip Widget (Used by Paned Widget)
+ *
+ */
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/GripP.h>
+
+static XtResource resources[] = {
+ {XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension),
+ XtOffsetOf(GripRec, core.width), XtRImmediate,
+ (XtPointer) DEFAULT_GRIP_SIZE},
+ {XtNheight, XtCHeight, XtRDimension, sizeof(Dimension),
+ XtOffsetOf(GripRec, core.height), XtRImmediate,
+ (XtPointer) DEFAULT_GRIP_SIZE},
+ {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
+ XtOffsetOf(GripRec, core.background_pixel), XtRString,
+ XtDefaultForeground},
+ {XtNborderWidth, XtCBorderWidth, XtRDimension, sizeof(Dimension),
+ XtOffsetOf(GripRec, core.border_width), XtRImmediate, (XtPointer)0},
+ {XtNcallback, XtCCallback, XtRCallback, sizeof(XtPointer),
+ XtOffsetOf(GripRec, grip.grip_action), XtRCallback, NULL},
+};
+
+static void GripAction( /* Widget, XEvent*, String*, Cardinal */ );
+
+static XtActionsRec actionsList[] =
+{
+ {"GripAction", GripAction},
+};
+
+#define SuperClass (&threeDClassRec)
+
+GripClassRec gripClassRec = {
+ {
+/* core class fields */
+ /* superclass */ (WidgetClass) SuperClass,
+ /* class name */ "Grip",
+ /* size */ sizeof(GripRec),
+ /* class initialize */ XawInitializeWidgetSet,
+ /* class_part_init */ NULL,
+ /* class_inited */ FALSE,
+ /* initialize */ NULL,
+ /* initialize_hook */ NULL,
+ /* realize */ XtInheritRealize,
+ /* actions */ actionsList,
+ /* num_actions */ XtNumber(actionsList),
+ /* resources */ resources,
+ /* resource_count */ XtNumber(resources),
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ TRUE,
+ /* compress_exposure */ TRUE,
+ /* compress_enterleave*/ TRUE,
+ /* visible_interest */ FALSE,
+ /* destroy */ NULL,
+ /* resize */ NULL,
+ /* expose */ XtInheritExpose,
+ /* set_values */ NULL,
+ /* 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 */ XtInheritQueryGeometry,
+ /* display_accelerator*/ XtInheritDisplayAccelerator,
+ /* extension */ NULL
+ },
+/* Simple class fields initialization */
+ {
+ /* change_sensitive */ XtInheritChangeSensitive
+ },
+/* ThreeD class fields initialization */
+ {
+ /* shadowdraw */ 0 /* inherited expose method knows how */
+ },
+/* Grip class fields initialization */
+ {
+ /* not used */ 0
+ }
+};
+
+WidgetClass gripWidgetClass = (WidgetClass) &gripClassRec;
+
+static void GripAction( widget, event, params, num_params )
+ Widget widget;
+ XEvent *event;
+ String *params;
+ Cardinal *num_params;
+{
+ XawGripCallDataRec call_data;
+
+ call_data.event = event;
+ call_data.params = params;
+ call_data.num_params = *num_params;
+
+ XtCallCallbacks( widget, XtNcallback, (XtPointer)&call_data );
+}
diff --git a/src/Grip.h b/src/Grip.h
new file mode 100644
index 0000000..440c1f0
--- /dev/null
+++ b/src/Grip.h
@@ -0,0 +1,105 @@
+/* $XConsortium: Grip.h,v 1.19 94/04/17 20:12:11 converse Exp $ */
+
+/***********************************************************
+
+Copyright (c) 1987, 1988 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.
+
+******************************************************************/
+
+/*
+ * Grip.h - Public Definitions for Grip widget (used by VPane Widget)
+ *
+ */
+
+#ifndef _XawGrip_h
+#define _XawGrip_h
+
+#include <X11/Xaw3d/Simple.h>
+
+/***************************************************************************
+ *
+ * Grip Widget
+ *
+ **************************************************************************/
+
+/* Parameters:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ foreground Foreground Pixel XtDefaultForeground
+ border BorderColor Pixel XtDefaultForeground
+ borderWidth BorderWidth Dimension 0
+ callback Callback Pointer GripAction
+ cursor Cursor Cursor None
+ cursorName Cursor String NULL
+ destroyCallback Callback Pointer NULL
+ height Height Dimension 8
+ mappedWhenManaged MappedWhenManaged Boolean True
+ pointerColor Foreground Pixel XtDefaultForeground
+ pointerColorBackground Background Pixel XtDefaultBackground
+ sensitive Sensitive Boolean True
+ width Width Dimension 8
+ x Position Position 0
+ y Position Position 0
+
+*/
+
+#define XtNgripTranslations "gripTranslations"
+
+typedef struct _XawGripCallData {
+ XEvent *event; /* the event causing the GripAction */
+ String *params; /* the TranslationTable params */
+ Cardinal num_params; /* count of params */
+} XawGripCallDataRec, *XawGripCallData,
+ GripCallDataRec, *GripCallData; /* supported for R4 compatibility */
+
+/* Class Record Constant */
+
+extern WidgetClass gripWidgetClass;
+
+typedef struct _GripClassRec *GripWidgetClass;
+typedef struct _GripRec *GripWidget;
+
+#endif /* _XawGrip_h */
diff --git a/src/GripP.h b/src/GripP.h
new file mode 100644
index 0000000..1fc3ae6
--- /dev/null
+++ b/src/GripP.h
@@ -0,0 +1,105 @@
+/*
+* $XConsortium: GripP.h,v 1.15 94/04/17 20:12:11 kit Exp $
+*/
+
+
+/***********************************************************
+
+Copyright (c) 1987, 1988 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.
+
+******************************************************************/
+
+/*
+ * GripP.h - Private definitions for Grip widget (Used by VPane Widget)
+ *
+ */
+
+#ifndef _XawGripP_h
+#define _XawGripP_h
+
+#include <X11/Xaw3d/Grip.h>
+#include <X11/Xaw3d/ThreeDP.h>
+
+/*****************************************************************************
+ *
+ * Grip Widget Private Data
+ *
+ *****************************************************************************/
+
+#define DEFAULT_GRIP_SIZE 8
+
+/* New fields for the Grip widget class record */
+typedef struct {int empty;} GripClassPart;
+
+/* Full Class record declaration */
+typedef struct _GripClassRec {
+ CoreClassPart core_class;
+ SimpleClassPart simple_class;
+ ThreeDClassPart threeD_class;
+ GripClassPart grip_class;
+} GripClassRec;
+
+extern GripClassRec gripClassRec;
+
+/* New fields for the Grip widget record */
+typedef struct {
+ XtCallbackList grip_action;
+} GripPart;
+
+/*****************************************************************************
+ *
+ * Full instance record declaration
+ *
+ ****************************************************************************/
+
+typedef struct _GripRec {
+ CorePart core;
+ SimplePart simple;
+ ThreeDPart threeD;
+ GripPart grip;
+} GripRec;
+
+#endif /* _XawGripP_h */
+
diff --git a/src/Imakefile b/src/Imakefile
new file mode 100644
index 0000000..81e9a0a
--- /dev/null
+++ b/src/Imakefile
@@ -0,0 +1,157 @@
+#ifndef XCOMM
+#define XCOMM #
+#endif
+
+XCOMM Build options. Have you read the README.XAW3D file yet?
+XCOMM
+XCOMM For color pixmaps, define MULTIPLANE_PIXMAPS:
+#undef MULTIPLANE_PIXMAPS
+XCOMM For grayed stipple shadows, define GRAY_BLKWHT_STIPPLES:
+#define GRAY_BLKWHT_STIPPLES
+XCOMM For scrollbars with arrows, define ARROW_SCROLLBARS:
+#undef ARROW_SCROLLBARS
+
+#define DoNormalLib NormalLibXaw
+#define DoSharedLib SharedLibXaw
+#define DoDebugLib DebugLibXaw
+#define DoProfileLib ProfileLibXaw
+#define HasSharedData YES
+#define LibName Xaw3d
+#define SoRev SOXAWREV
+#define IncSubdir X11
+#define IncSubSubdir Xaw3d
+
+XCOMM When building outside an X11 source tree:
+XCOMM EXTRA_INCLUDES = -I.
+
+#ifdef SharedXawReqs
+REQUIREDLIBS = SharedXawReqs
+#endif
+
+LINTLIBS = $(LINTXLIB) $(LINTXTOOL)
+
+BASE_HDRS = AllWidgets.h AsciiSink.h AsciiSinkP.h AsciiSrc.h AsciiSrcP.h \
+ AsciiText.h AsciiTextP.h Box.h BoxP.h Cardinals.h Command.h \
+ CommandP.h Dialog.h DialogP.h Form.h FormP.h Grip.h GripP.h \
+ Label.h LabelP.h Layout.h LayoutP.h List.h ListP.h MenuButton.h \
+ MenuButtoP.h Paned.h PanedP.h Panner.h PannerP.h Porthole.h \
+ PortholeP.h Repeater.h RepeaterP.h Reports.h Scrollbar.h \
+ ScrollbarP.h Simple.h SimpleP.h SimpleMenu.h SimpleMenP.h Sme.h \
+ SmeP.h SmeBSB.h SmeBSBP.h SmeLine.h SmeLineP.h SmeThreeD.h \
+ SmeThreeDP.h StripChart.h StripCharP.h Template.c Template.h \
+ TemplateP.h Text.h TextP.h TextSink.h TextSinkP.h TextSrc.h \
+ TextSrcP.h ThreeD.h ThreeDP.h Tip.h TipP.h Toggle.h ToggleP.h \
+ Tree.h TreeP.h Viewport.h ViewportP.h Xaw3dP.h XawInit.h
+
+I18N_HDRS = MultiSrc.h MultiSrcP.h MultiSink.h MultiSinkP.h VendorEP.h \
+ XawImP.h
+
+BASE_SRCS = AllWidgets.c AsciiSink.c AsciiSrc.c AsciiText.c Box.c \
+ Command.c Dialog.c Form.c Grip.c Label.c Layout.c List.c \
+ MenuButton.c Paned.c Panner.c Porthole.c Repeater.c Scrollbar.c \
+ Simple.c SimpleMenu.c Sme.c SmeBSB.c SmeLine.c SmeThreeD.c \
+ StripChart.c Text.c TextSink.c TextSrc.c TextAction.c TextPop.c \
+ TextTr.c ThreeD.c Tip.c Toggle.c Tree.c Vendor.c Viewport.c \
+ Xaw3dP.c XawInit.c sharedlib.c laygram.c laylex.c
+
+I18N_SRCS = MultiSrc.c MultiSink.c XawIm.c XawI18n.c
+
+#if SharedDataSeparation
+UNSHAREDOBJS = AllWidgets.o sharedlib.o
+#endif
+
+BASE_OBJS = AllWidgets.o AsciiSink.o AsciiSrc.o AsciiText.o Box.o \
+ Command.o Dialog.o Form.o Grip.o Label.o Layout.o List.o \
+ MenuButton.o Paned.o Panner.o Porthole.o Repeater.o Scrollbar.o \
+ Simple.o SimpleMenu.o Sme.o SmeBSB.o SmeLine.o SmeThreeD.o \
+ StripChart.o Text.o TextSink.o TextSrc.o TextAction.o TextPop.o \
+ TextTr.o ThreeD.o Tip.o Toggle.o Tree.o Vendor.o Viewport.o \
+ Xaw3dP.o XawInit.o laygram.o laylex.o
+
+I18N_OBJS = MultiSrc.o MultiSink.o XawIm.o XawI18n.o
+
+#ifdef XawI18nDefines
+#define INTERNATIONALIZATION
+HEADERS = $(BASE_HDRS) $(I18N_HDRS)
+SRCS = $(BASE_SRCS) $(I18N_SRCS)
+OBJS = $(BASE_OBJS) $(I18N_OBJS)
+#else
+#undef INTERNATIONALIZATION
+HEADERS = $(BASE_HDRS)
+SRCS = $(BASE_SRCS)
+OBJS = $(BASE_OBJS)
+#endif
+
+#include <Library.tmpl>
+
+#if DoSharedLib && SharedDataSeparation
+SpecialCObjectRule(sharedlib.o,NullParameter,$(SHLIBDEF))
+#endif
+
+XCOMM At least one X11R5 distribution needs this:
+XCOMM #include "Imakefrag.X11R5"
+
+#ifdef LexCmd
+LEX = LexCmd
+#endif
+#ifdef YaccCmd
+YACC = YaccCmd
+#endif
+
+#ifdef INTERNATIONALIZATION
+XAW_INTERNATIONALIZATION = \
+ -e 's/\/\* I18n support \*\//\#define XAW_INTERNATIONALIZATION/'
+#else
+XAW_INTERNATIONALIZATION = \
+ -e 's/\/\* I18n support \*\//\#undef XAW_INTERNATIONALIZATION/'
+#endif
+#ifdef MULTIPLANE_PIXMAPS
+XAW_MULTIPLANE_PIXMAPS = \
+ -e 's/\/\* XPM support \*\//\#define XAW_MULTIPLANE_PIXMAPS/'
+#else
+XAW_MULTIPLANE_PIXMAPS = \
+ -e 's/\/\* XPM support \*\//\#undef XAW_MULTIPLANE_PIXMAPS/'
+#endif
+#ifdef GRAY_BLKWHT_STIPPLES
+XAW_GRAY_BLKWHT_STIPPLES = \
+ -e 's/\/\* gray stipples \*\//\#define XAW_GRAY_BLKWHT_STIPPLES/'
+#else
+XAW_GRAY_BLKWHT_STIPPLES = \
+ -e 's/\/\* gray stipples \*\//\#undef XAW_GRAY_BLKWHT_STIPPLES/'
+#endif
+#ifdef ARROW_SCROLLBARS
+XAW_ARROW_SCROLLBARS = \
+ -e 's/\/\* arrow scrollbars \*\//\#define XAW_ARROW_SCROLLBARS/'
+#else
+XAW_ARROW_SCROLLBARS = \
+ -e 's/\/\* arrow scrollbars \*\//\#undef XAW_ARROW_SCROLLBARS/'
+#endif
+
+depend:: laygram.c laygram.h laylex.c Xaw3dP.h
+
+clean::
+ $(RM) laygram.c laygram.h laylex.c Xaw3dP.h
+
+distclean::
+ LibCleanDir(X11)
+
+laygram.c: laygram.y
+ $(YACC) -d laygram.y
+ sed -e 's/yy/LayYY/g' y.tab.c > laygram.c
+ sed -e 's/yy/LayYY/g' y.tab.h > laygram.h
+ $(RM) y.tab.c y.tab.h
+
+laylex.c: laylex.l
+ $(LEX) laylex.l
+ sed -e 's/yy/LayYY/g' lex.yy.c > laylex.c
+ $(RM) lex.yy.c
+
+Xaw3dP.h: Xaw3dP.h.sed
+ sed $(XAW_INTERNATIONALIZATION) $(XAW_MULTIPLANE_PIXMAPS) \
+ $(XAW_GRAY_BLKWHT_STIPPLES) $(XAW_ARROW_SCROLLBARS) \
+ Xaw3dP.h.sed > Xaw3dP.h
+
+$(OBJS): Xaw3dP.h
+
+DependTarget()
+
diff --git a/src/Imakefrag.X11R5 b/src/Imakefrag.X11R5
new file mode 100644
index 0000000..6c26ddc
--- /dev/null
+++ b/src/Imakefrag.X11R5
@@ -0,0 +1,33 @@
+XCOMM make rules for X11R5 -------------------------------
+
+#if DoSharedLib
+#if DoNormalLib
+SharedLibraryTarget(Xaw3d,$(SOXAWREV),$(OBJS),shared,..)
+#else
+SharedLibraryTarget(Xaw3d,$(SOXAWREV),$(OBJS),.,.)
+#endif
+SharedLibraryDataTarget(Xaw3d,$(SOXAWREV),$(UNSHAREDOBJS))
+InstallSharedLibrary(Xaw3d,$(SOXAWREV),$(USRLIBDIR))
+InstallSharedLibraryData(Xaw3d,$(SOXAWREV),$(USRLIBDIR))
+#endif
+#if DoNormalLib
+NormalLibraryTarget(Xaw3d,$(OBJS))
+InstallLibrary(Xaw3d,$(USRLIBDIR))
+#endif
+#if DoProfileLib
+ProfiledLibraryTarget(Xaw3d,$(OBJS))
+InstallLibrary(Xaw3d_p,$(USRLIBDIR))
+#endif
+#if DoDebugLib
+DebuggedLibraryTarget(Xaw3d,$(OBJS))
+InstallLibrary(Xaw3d_d,$(USRLIBDIR))
+#endif
+
+LintLibraryTarget(Xaw3d,$(SRCS))
+InstallLintLibrary(Xaw3d,$(LINTLIBDIR))
+
+BuildIncludes($(HEADERS),Xaw3d,..)
+
+InstallMultiple($(HEADERS),$(INCDIR)/Xaw3d)
+
+XCOMM end make rules for X11R5 ---------------------------
diff --git a/src/Label.c b/src/Label.c
new file mode 100644
index 0000000..5fd2e32
--- /dev/null
+++ b/src/Label.c
@@ -0,0 +1,871 @@
+/* $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.
+
+******************************************************************/
+
+/*
+ * Label.c - Label widget
+ *
+ */
+
+#include "Xaw3dP.h"
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xos.h>
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/LabelP.h>
+#include <X11/Xmu/Converters.h>
+#include <X11/Xmu/Drawing.h>
+#include <stdio.h>
+#include <ctype.h>
+
+/* needed for abs() */
+#ifndef X_NOT_STDC_ENV
+#include <stdlib.h>
+#else
+int abs();
+#endif
+
+#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(LabelRec, field)
+static XtResource resources[] = {
+ {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
+ offset(label.foreground), XtRString, XtDefaultForeground},
+ {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
+ offset(label.font),XtRString, XtDefaultFont},
+#ifdef XAW_INTERNATIONALIZATION
+ {XtNfontSet, XtCFontSet, XtRFontSet, sizeof(XFontSet ),
+ offset(label.fontset),XtRString, XtDefaultFontSet},
+#endif
+ {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},
+ {XtNborderWidth, XtCBorderWidth, XtRDimension, sizeof(Dimension),
+ XtOffsetOf(RectObjRec,rectangle.border_width), XtRImmediate,
+ (XtPointer)1}
+};
+#undef offset
+
+static void Initialize();
+static void Resize();
+static void Redisplay();
+static Boolean SetValues();
+static void ClassInitialize();
+static void Destroy();
+static XtGeometryResult QueryGeometry();
+
+LabelClassRec labelClassRec = {
+ {
+/* core_class fields */
+ /* superclass */ (WidgetClass) &threeDClassRec,
+ /* class_name */ "Label",
+ /* widget_size */ sizeof(LabelRec),
+ /* 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
+ },
+/* ThreeD class fields initialization */
+ {
+ /* shadowdraw */ XtInheritXaw3dShadowDraw
+ },
+/* Label class fields initialization */
+ {
+ /* ignore */ 0
+ }
+};
+
+WidgetClass labelWidgetClass = (WidgetClass)&labelClassRec;
+
+/****************************************************************
+ *
+ * Private Procedures
+ *
+ ****************************************************************/
+
+static void ClassInitialize()
+{
+ XawInitializeWidgetSet();
+ XtAddConverter( XtRString, XtRJustify, XmuCvtStringToJustify,
+ (XtConvertArgList)NULL, 0 );
+}
+
+#ifndef WORD64
+
+#define TXT16 XChar2b
+
+#else
+
+#define TXT16 char
+
+static XChar2b *buf2b;
+static int buf2blen = 0;
+
+_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);
+}
+
+_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 */
+
+/*
+ * Calculate width and height of displayed text in pixels
+ */
+
+static void SetTextWidthAndHeight(lw)
+ LabelWidget 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.depth = depth;
+ return;
+ }
+ }
+#ifdef XAW_INTERNATIONALIZATION
+ 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
+#endif
+ {
+ 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)
+ width = XTextWidth16(fs, (TXT16*)label, (int)(nl - label)/2);
+ 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 = XTextWidth(fs, label, strlen(label));
+
+ if (lw->label.encoding)
+ width = XTextWidth16(fs, (TXT16*)label, (int)strlen(label)/2);
+ 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)
+ lw->label.label_width =
+ XTextWidth16(fs, (TXT16*)lw->label.label,
+ (int) lw->label.label_len/2);
+ else
+ lw->label.label_width =
+ XTextWidth(fs, lw->label.label, (int) lw->label.label_len);
+ }
+
+ }
+}
+
+static void GetnormalGC(lw)
+ LabelWidget lw;
+{
+ XGCValues values;
+
+ values.foreground = lw->label.foreground;
+ values.background = lw->core.background_pixel;
+ values.font = lw->label.font->fid;
+ values.graphics_exposures = False;
+
+#ifdef XAW_INTERNATIONALIZATION
+ 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
+#endif
+ lw->label.normal_GC = XtGetGC(
+ (Widget)lw,
+ (unsigned) GCForeground | GCBackground | GCFont | GCGraphicsExposures,
+ &values);
+}
+
+static void GetgrayGC(lw)
+ LabelWidget 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;
+#ifdef XAW_INTERNATIONALIZATION
+ 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
+#endif
+ lw->label.gray_GC = XtGetGC((Widget)lw,
+ (unsigned) GCForeground | GCBackground |
+ GCFont | GCTile | GCFillStyle |
+ GCGraphicsExposures,
+ &values);
+}
+
+static void compute_bitmap_offsets (lw)
+ LabelWidget lw;
+{
+ if (lw->label.lbm_height != 0)
+ lw->label.lbm_y = (lw->core.height - lw->label.lbm_height) / 2;
+ else
+ lw->label.lbm_y = 0;
+}
+
+static void set_bitmap_info (lw)
+ LabelWidget lw;
+{
+ Window root;
+ int x, y;
+ unsigned int bw;
+
+ if (lw->label.pixmap || !(lw->label.left_bitmap &&
+ XGetGeometry (XtDisplay(lw), lw->label.left_bitmap, &root, &x, &y,
+ &lw->label.lbm_width, &lw->label.lbm_height,
+ &bw, &lw->label.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;
+{
+ extern WidgetClass commandWidgetClass;
+ LabelWidget lw = (LabelWidget) new;
+
+ /* disable shadows if we're not a subclass of Command */
+ if (!XtIsSubclass(new, commandWidgetClass))
+ lw->threeD.shadow_width = 0;
+
+ 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); /* label.label or label.pixmap */
+
+ if (lw->core.height == 0)
+ lw->core.height = lw->label.label_height +
+ 2 * lw->label.internal_height;
+
+ set_bitmap_info(lw); /* req's core.height, sets label.lbm_* */
+
+ if (lw->label.lbm_height > lw->label.label_height)
+ lw->core.height = lw->label.lbm_height +
+ 2 * lw->label.internal_height;
+
+ if (lw->core.width == 0)
+ lw->core.width = lw->label.label_width +
+ 2 * lw->label.internal_width +
+ LEFT_OFFSET(lw); /* req's label.lbm_width */
+
+ lw->label.label_x = lw->label.label_y = 0;
+ (*XtClass(new)->core_class.resize) ((Widget)lw);
+
+ lw->label.stippled = lw->label.left_stippled = None;
+} /* Initialize */
+
+/*
+ * Repaint the widget window
+ */
+
+/* ARGSUSED */
+static void Redisplay(gw, event, region)
+ Widget gw;
+ XEvent *event;
+ Region region;
+{
+ extern WidgetClass commandWidgetClass;
+ LabelWidget w = (LabelWidget) gw;
+ LabelWidgetClass lwclass = (LabelWidgetClass) XtClass (gw);
+ Pixmap pm;
+ GC gc;
+
+ /*
+ * Don't draw shadows if Command is going to redraw them.
+ * The shadow draw method is region aware, but since 99% of
+ * all labels don't have shadows, we'll check for a shadow
+ * before we incur the function call overhead.
+ */
+ if (!XtIsSubclass (gw, commandWidgetClass) && w->threeD.shadow_width > 0)
+ (*lwclass->threeD_class.shadowdraw) (gw, event, region,
+ w->threeD.relief, True);
+
+ /*
+ * 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) {
+ pm = w->label.left_bitmap;
+#ifdef XAW_MULTIPLANE_PIXMAPS
+ if (!XtIsSensitive(gw)) {
+ if (w->label.left_stippled == None)
+ w->label.left_stippled = stipplePixmap(gw,
+ w->label.left_bitmap, w->core.colormap,
+ w->core.background_pixel, w->label.depth);
+ if (w->label.left_stippled != None)
+ pm = w->label.left_stippled;
+ }
+#endif
+
+ if (w->label.depth == 1)
+ XCopyPlane(XtDisplay(gw), pm, XtWindow(gw), gc, 0, 0,
+ w->label.lbm_width, w->label.lbm_height,
+ (int) w->label.internal_width,
+ (int) w->label.lbm_y,
+ (unsigned long) 1L);
+ else
+ XCopyArea(XtDisplay(gw), pm, XtWindow(gw), gc, 0, 0,
+ w->label.lbm_width, w->label.lbm_height,
+ (int) w->label.internal_width,
+ (int) w->label.lbm_y);
+ }
+
+#ifdef XAW_INTERNATIONALIZATION
+ 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
+#endif
+ { /* international false, so use R5 routine */
+
+ if (len == MULTI_LINE_LABEL) {
+ char *nl;
+ while ((nl = index(label, '\n')) != NULL) {
+ if (w->label.encoding)
+ XDrawString16(XtDisplay(gw), XtWindow(gw), gc,
+ w->label.label_x, y,
+ (TXT16*)label, (int)(nl - label)/2);
+ 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)
+ XDrawString16(XtDisplay(gw), XtWindow(gw), gc,
+ w->label.label_x, y, (TXT16*)label, len/2);
+ else
+ XDrawString(XtDisplay(gw), XtWindow(gw), gc,
+ w->label.label_x, y, label, len);
+ }
+
+ } /* endif international */
+
+ } else {
+ pm = w->label.pixmap;
+#ifdef XAW_MULTIPLANE_PIXMAPS
+ if (!XtIsSensitive(gw)) {
+ if (w->label.stippled == None)
+ w->label.stippled = stipplePixmap(gw,
+ w->label.pixmap, w->core.colormap,
+ w->core.background_pixel, w->label.depth);
+ if (w->label.stippled != None)
+ pm = w->label.stippled;
+ }
+#endif
+
+ if (w->label.depth == 1)
+ XCopyPlane(XtDisplay(gw), pm, 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), pm, 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)
+ LabelWidget 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;
+
+ lw->label.lbm_y = (height - lw->label.lbm_height) / 2;
+
+ return;
+}
+
+static void Resize(w)
+ Widget w;
+{
+ LabelWidget lw = (LabelWidget)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;
+{
+ LabelWidget curlw = (LabelWidget) current;
+ LabelWidget reqlw = (LabelWidget) request;
+ LabelWidget newlw = (LabelWidget) 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;
+ 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 || checks[PIXMAP] ||
+ curlw->label.font != newlw->label.font ||
+#ifdef XAW_INTERNATIONALIZATION
+ (curlw->simple.international &&
+ curlw->label.fontset != newlw->label.fontset) ||
+#endif
+ curlw->label.encoding != newlw->label.encoding ||
+ curlw->label.justify != newlw->label.justify) {
+ SetTextWidthAndHeight(newlw); /* label.label or label.pixmap */
+ was_resized = True;
+ }
+
+ if (curlw->label.left_bitmap != newlw->label.left_bitmap ||
+ curlw->label.internal_width != newlw->label.internal_width ||
+ curlw->label.internal_height != newlw->label.internal_height)
+ 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); /* req's core.height, sets label.lbm_* */
+
+ if (newlw->label.lbm_height > newlw->label.label_height)
+ newlw->core.height = newlw->label.lbm_height +
+ 2 * newlw->label.internal_height;
+
+ if (curlw->core.width == reqlw->core.width && !checks[WIDTH])
+ newlw->core.width = newlw->label.label_width +
+ 2 * newlw->label.internal_width +
+ LEFT_OFFSET(newlw); /* req's label.lbm_width */
+ }
+
+ /* enforce minimum dimensions */
+ if (newlw->label.resize) {
+ if (checks[HEIGHT]) {
+ if (newlw->label.label_height > newlw->label.lbm_height)
+ i = newlw->label.label_height +
+ 2 * newlw->label.internal_height;
+ else
+ i = newlw->label.lbm_height + 2 * newlw->label.internal_height;
+ if (i > newlw->core.height)
+ newlw->core.height = i;
+ }
+ if (checks[WIDTH]) {
+ i = newlw->label.label_width + 2 * newlw->label.internal_width +
+ LEFT_OFFSET(newlw); /* req's label.lbm_width */
+ if (i > newlw->core.width)
+ newlw->core.width = i;
+ }
+ }
+
+ if (curlw->core.background_pixel != newlw->core.background_pixel ||
+ curlw->label.foreground != newlw->label.foreground ||
+ curlw->label.font->fid != newlw->label.font->fid) {
+ /* the fontset is not in the GC - no new GC if fontset 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;
+ }
+
+#ifdef XAW_MULTIPLANE_PIXMAPS
+ if (curlw->label.pixmap != newlw->label.pixmap)
+ {
+ newlw->label.stippled = None;
+ if (curlw->label.stippled != None)
+ XFreePixmap(XtDisplay(current), curlw->label.stippled);
+ }
+ if (curlw->label.left_bitmap != newlw->label.left_bitmap)
+ {
+ newlw->label.left_stippled = None;
+ if (curlw->label.left_stippled != None)
+ XFreePixmap(XtDisplay(current), curlw->label.left_stippled);
+ }
+#endif
+
+ if (was_resized) {
+ Position dx, dy;
+
+ /* Resize() will be called if geometry changes succeed */
+ _Reposition(newlw, curlw->core.width, curlw->core.height, &dx, &dy);
+ }
+
+ return was_resized || redisplay ||
+ XtIsSensitive(current) != XtIsSensitive(new);
+}
+
+static void Destroy(w)
+ Widget w;
+{
+ LabelWidget lw = (LabelWidget)w;
+
+ if ( lw->label.label != lw->core.name )
+ XtFree( lw->label.label );
+ XtReleaseGC( w, lw->label.normal_GC );
+ XtReleaseGC( w, lw->label.gray_GC);
+#ifdef XAW_MULTIPLANE_PIXMAPS
+ if (lw->label.stippled != None)
+ XFreePixmap(XtDisplay(w), lw->label.stippled);
+ if (lw->label.left_stippled != None)
+ XFreePixmap(XtDisplay(w), lw->label.left_stippled);
+#endif
+ XmuReleaseStippledPixmap( XtScreen(w), lw->label.stipple );
+}
+
+
+static XtGeometryResult QueryGeometry(w, intended, preferred)
+ Widget w;
+ XtWidgetGeometry *intended, *preferred;
+{
+ LabelWidget lw = (LabelWidget)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/src/Label.h b/src/Label.h
new file mode 100644
index 0000000..fda186f
--- /dev/null
+++ b/src/Label.h
@@ -0,0 +1,131 @@
+/* $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.
+
+******************************************************************/
+
+#ifndef _XawLabel_h
+#define _XawLabel_h
+
+/***********************************************************************
+ *
+ * Label Widget
+ *
+ ***********************************************************************/
+
+#include "Xaw3dP.h"
+#include <X11/Xaw3d/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
+
+*/
+
+#define XawTextEncoding8bit 0
+#define XawTextEncodingChar2b 1
+
+#define XtNleftBitmap "leftBitmap"
+#define XtCLeftBitmap "LeftBitmap"
+#define XtNencoding "encoding"
+#define XtCEncoding "Encoding"
+
+#ifdef XAW_INTERNATIONALIZATION
+#ifndef XtNfontSet
+#define XtNfontSet "fontSet"
+#endif
+#ifndef XtCFontSet
+#define XtCFontSet "FontSet"
+#endif
+#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
+
+/* Class record constants */
+
+extern WidgetClass labelWidgetClass;
+
+typedef struct _LabelClassRec *LabelWidgetClass;
+typedef struct _LabelRec *LabelWidget;
+
+#endif /* _XawLabel_h */
diff --git a/src/LabelP.h b/src/LabelP.h
new file mode 100644
index 0000000..e56a004
--- /dev/null
+++ b/src/LabelP.h
@@ -0,0 +1,137 @@
+/*
+* $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.
+
+******************************************************************/
+
+/*
+ * LabelP.h - Private definitions for Label widget
+ *
+ */
+
+#ifndef _XawLabelP_h
+#define _XawLabelP_h
+
+/***********************************************************************
+ *
+ * Label Widget Private Data
+ *
+ ***********************************************************************/
+
+#include "Xaw3dP.h"
+#include <X11/Xaw3d/Label.h>
+#include <X11/Xaw3d/ThreeDP.h>
+
+/* New fields for the Label widget class record */
+
+typedef struct {int foo;} LabelClassPart;
+
+/* Full class record declaration */
+typedef struct _LabelClassRec {
+ CoreClassPart core_class;
+ SimpleClassPart simple_class;
+ ThreeDClassPart threeD_class;
+ LabelClassPart label_class;
+} LabelClassRec;
+
+extern LabelClassRec labelClassRec;
+
+/* New fields for the Label widget record */
+typedef struct {
+ /* resources */
+ Pixel foreground;
+ XFontStruct *font;
+#ifdef XAW_INTERNATIONALIZATION
+ XFontSet fontset;
+#endif
+ 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;
+ Pixmap stippled; /* insensitive pixmap */
+ Pixmap left_stippled; /* ditto */
+ 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 */
+ unsigned int depth; /* depth of pixmaps */
+} LabelPart;
+
+
+/****************************************************************
+ *
+ * Full instance record declaration
+ *
+ ****************************************************************/
+
+typedef struct _LabelRec {
+ CorePart core;
+ SimplePart simple;
+ ThreeDPart threeD;
+ LabelPart label;
+} LabelRec;
+
+#define LEFT_OFFSET(lw) ((lw)->label.left_bitmap && (lw)->label.pixmap == None \
+ ? (lw)->label.lbm_width + (lw)->label.internal_width \
+ : 0)
+
+#endif /* _XawLabelP_h */
diff --git a/src/Layout.c b/src/Layout.c
new file mode 100644
index 0000000..44d391a
--- /dev/null
+++ b/src/Layout.c
@@ -0,0 +1,1049 @@
+/*
+ * $XConsortium: Layout.c,v 1.1 91/09/13 18:51:44 keith Exp $
+ *
+ * Copyright 1991 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, 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 M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. M.I.T. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
+ * 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.
+ *
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+
+#include <X11/Xmu/Misc.h>
+#include <X11/Xmu/Converters.h>
+
+#ifdef MOTIF
+# include <Xm/XmP.h>
+#endif
+
+#if defined(LAYOUT)
+# include "LayoutP.h"
+#else
+# include <X11/Xaw3d/LayoutP.h>
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+
+#undef DEBUG
+#ifdef DEBUG
+static char *DBUG_currentproc, *DBUG_lastproc;
+static int DBUG_level = 0;
+# define DBUG_ENTER(s) \
+ {DBUG_lastproc=DBUG_currentproc;DBUG_currentproc=s;\
+ fprintf(stderr,"begin: (%d) %s\n",++DBUG_level,s);}
+# define DBUG_VOID_RETURN \
+ {fprintf(stderr,"end: (%d) %s\n",DBUG_level--,DBUG_currentproc); \
+ DBUG_currentproc=DBUG_lastproc;return;}
+# define DBUG_RETURN(f,v) \
+ {fprintf(stderr,"return (%d) %s (",DBUG_level--,DBUG_currentproc); \
+ fprintf(stderr,(f),(v)); \
+ fprintf(stderr,")\n"); DBUG_currentproc=DBUG_lastproc;return (v);}
+# define DBUG_PRINT(f,s) \
+ {fprintf(stderr," (%d) %s:",DBUG_level, DBUG_currentproc); \
+ fprintf(stderr,f,s);fprintf(stderr,"\n");}
+#else
+# define DBUG_ENTER(s)
+# define DBUG_VOID_RETURN return
+# define DBUG_PRINT(f,s)
+# define DBUG_RETURN(f,v) return(v)
+#endif
+
+/*****************************************************************************
+ *
+ * Full instance record declaration
+ *
+ ****************************************************************************/
+
+#define offset(field) XtOffsetOf(LayoutRec, layout.field)
+
+static XtResource resources[] = {
+ {XtNlayout, XtCLayout, XtRLayout, sizeof (BoxPtr),
+ offset(layout), XtRLayout, NULL },
+ {XtNdebug, XtCBoolean, XtRBoolean, sizeof(Boolean),
+ offset(debug), XtRImmediate, (XtPointer) FALSE},
+};
+
+#undef offset
+
+static void ClassInitialize(), Initialize();
+static void Resize();
+static Boolean SetValues();
+static XtGeometryResult GeometryManager();
+static void ChangeManaged();
+static void InsertChild();
+static XtGeometryResult QueryGeometry ();
+static void GetDesiredSize ();
+#ifdef MOTIF
+static void Redisplay ();
+#endif
+
+static void LayoutLayout ();
+static void LayoutGetNaturalSize ();
+static void LayoutFreeLayout ();
+
+extern void LayYYsetsource(), LayYYsetdest();
+extern int LayYYparse();
+
+#ifdef MOTIF
+#define SuperClass ((ConstraintWidgetClass)&xmManagerClassRec)
+#else
+#define SuperClass ((ConstraintWidgetClass)&constraintClassRec)
+#endif
+
+LayoutClassRec layoutClassRec = {
+ {
+/* core class fields */
+ /* superclass */ (WidgetClass) SuperClass,
+ /* class name */ "Layout",
+ /* size */ sizeof(LayoutRec),
+ /* class_initialize */ ClassInitialize,
+ /* class_part init */ NULL,
+ /* class_inited */ FALSE,
+ /* initialize */ Initialize,
+ /* initialize_hook */ NULL,
+ /* realize */ XtInheritRealize,
+ /* actions */ NULL,
+ /* num_actions */ 0,
+ /* resources */ resources,
+ /* resource_count */ XtNumber(resources),
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ FALSE,
+ /* compress_exposure */ 0,
+ /* compress_enterleave*/ FALSE,
+ /* visible_interest */ FALSE,
+ /* destroy */ NULL,
+ /* resize */ Resize,
+#ifdef MOTIF
+ /* expose */ Redisplay,
+#else
+ /* expose */ NULL,
+#endif
+ /* set_values */ SetValues,
+ /* set_values_hook */ NULL,
+ /* set_values_almost */ XtInheritSetValuesAlmost,
+ /* get_values_hook */ NULL,
+ /* accept_focus */ NULL,
+ /* version */ XtVersion,
+ /* callback_private */ NULL,
+#ifdef MOTIF
+ /* tm_table */ XtInheritTranslations,
+#else
+ /* tm_table */ NULL,
+#endif
+ /* query_geometry */ QueryGeometry,
+ /* display_accelerator*/ XtInheritDisplayAccelerator,
+ /* extension */ NULL
+ }, {
+/* composite class fields */
+ /* geometry_manager */ GeometryManager,
+ /* change_managed */ ChangeManaged,
+ /* insert_child */ InsertChild,
+ /* delete_child */ XtInheritDeleteChild,
+ /* extension */ NULL
+ }, {
+/* constraint class fields */
+ /* subresources */ NULL,
+ /* subresource_count */ 0,
+ /* constraint_size */ sizeof(LayoutConstraintsRec),
+ /* initialize */ NULL,
+ /* destroy */ NULL,
+ /* set_values */ NULL,
+ /* extension */ NULL
+ },
+#ifdef MOTIF
+ {
+ /* manager class */
+ XtInheritTranslations, /* translations */
+ NULL, /* syn resources */
+ 0, /* num syn_resources */
+ NULL, /* get_cont_resources */
+ 0, /* num_get_cont_resources */
+ XmInheritParentProcess, /* parent_process */
+ NULL, /* extension */
+ },
+#endif
+ { /* layout_class fields */
+ 0
+ }
+};
+
+WidgetClass layoutWidgetClass = (WidgetClass) &layoutClassRec;
+
+#define ForAllChildren(pw, childP) \
+ for ( (childP) = (pw)->composite.children ; \
+ (childP) < (pw)->composite.children + (pw)->composite.num_children ; \
+ (childP)++ ) if (!XtIsManaged(*childP)) ; else
+
+/************************************************************
+ *
+ * Semi-public routines.
+ *
+ ************************************************************/
+
+/* Function Name: ClassInitialize
+ * Description: The Layout widgets class initialization proc.
+ * Arguments: none.
+ * Returns: none.
+ */
+
+/*ARGSUSED*/
+static Boolean
+CvtStringToLayout (dpy, args, num_args, from, to, converter_data)
+ Display *dpy;
+ XrmValue *args;
+ Cardinal *num_args;
+ XrmValue *from, *to;
+ XtPointer *converter_data;
+{
+ static BoxPtr tmp;
+
+ LayYYsetsource ((char *) from->addr);
+ if (!to->addr) to->addr = (XtPointer)&tmp;
+ LayYYsetdest ((BoxPtr *) to->addr);
+ to->size = sizeof (BoxPtr *);
+ return LayYYparse() ? FALSE : TRUE;
+}
+
+/*ARGSUSED*/
+static void
+DisposeLayout (app, to, data, args, num_args)
+ XtAppContext app;
+ XrmValue *to;
+ XtPointer data;
+ XrmValuePtr args;
+ Cardinal *num_args;
+{
+ LayoutFreeLayout (* (LayoutPtr *) to->addr);
+}
+
+static void
+ClassInitialize()
+{
+ XtSetTypeConverter ( XtRString, XtRLayout, CvtStringToLayout,
+ (XtConvertArgList)NULL, (Cardinal)0, XtCacheNone,
+ DisposeLayout );
+}
+
+#ifdef MOTIF
+static void Redisplay ( gw, event, region )
+Widget gw;
+XEvent *event;
+Region region;
+{
+ /*
+ * If the Layout widget is visible, redraw gadgets.
+ */
+
+ if ( XtIsRealized ( gw ) && gw->core.visible )
+ {
+ _XmRedisplayGadgets ( gw, event, region );
+ }
+ /* ChangeManaged(gw);*/
+}
+#endif
+
+/*ARGSUSED*/
+static XtGeometryResult GeometryManager(child, request, reply)
+ Widget child;
+ XtWidgetGeometry *request, *reply;
+{
+ LayoutWidget w = (LayoutWidget) XtParent(child);
+ SubInfoPtr p = SubInfo(child);
+ int bw;
+ Bool changed, bwChanged;
+
+ bw = p->naturalBw;
+ changed = FALSE;
+ bwChanged = FALSE;
+ if (request->request_mode & CWBorderWidth &&
+ request->border_width != child->core.border_width)
+ {
+ p->naturalBw = bw;
+ bw = request->border_width;
+ changed = TRUE;
+ bwChanged = TRUE;
+ }
+ if (bwChanged || ((request->request_mode & CWWidth) &&
+ request->width != child->core.width))
+ {
+ p->naturalSize[LayoutHorizontal] = request->width + bw * 2;
+ changed = TRUE;
+ }
+ if (bwChanged || ((request->request_mode & CWHeight) &&
+ request->height != child->core.height))
+ {
+ p->naturalSize[LayoutVertical] = request->height + bw * 2;
+ changed = TRUE;
+ }
+ if (changed)
+ LayoutLayout (w, TRUE);
+ return XtGeometryDone;
+}
+
+/* ARGSUSED */
+static void Initialize(request, new, args, num_args)
+Widget request, new;
+ArgList args;
+Cardinal *num_args;
+{
+/* LayoutWidget w = (LayoutWidget)new; */
+}
+
+static void ChangeManaged(gw)
+ Widget gw;
+{
+ LayoutWidget w = (LayoutWidget) gw;
+ Widget *children;
+
+ DBUG_ENTER("changeManaged");
+
+ ForAllChildren (w, children)
+ GetDesiredSize (*children);
+ LayoutLayout ((LayoutWidget) w, TRUE);
+#ifdef MOTIF
+ _XmNavigChangeManaged ( gw );
+#endif
+ DBUG_VOID_RETURN;
+}
+
+static void
+GetDesiredSize (child)
+ Widget child;
+{
+ XtWidgetGeometry desired;
+ SubInfoPtr p;
+
+ XtQueryGeometry (child, (XtWidgetGeometry *) NULL, &desired);
+ p = SubInfo (child);
+ p->naturalBw = desired.border_width;
+ p->naturalSize[LayoutHorizontal] = desired.width + desired.border_width * 2;
+ p->naturalSize[LayoutVertical] = desired.height + desired.border_width * 2;
+}
+
+static void InsertChild (child)
+ Widget child;
+{
+ (*SuperClass->composite_class.insert_child) (child);
+ GetDesiredSize (child);
+}
+
+static void
+Resize(gw)
+ Widget gw;
+{
+ LayoutLayout ((LayoutWidget) gw, FALSE);
+}
+
+/* ARGSUSED */
+static Boolean
+SetValues(gold, greq, gnew, args, num_args)
+ Widget gold, greq, gnew;
+ ArgList args;
+ Cardinal *num_args;
+{
+ LayoutWidget old = (LayoutWidget) gold,
+ new = (LayoutWidget) gnew;
+
+ if (old->layout.layout != new->layout.layout)
+ LayoutLayout (new, TRUE);
+ return FALSE;
+} /* SetValues */
+
+static XtGeometryResult
+QueryGeometry (gw, request, prefered_return)
+ Widget gw;
+ XtWidgetGeometry *request, *prefered_return;
+{
+ LayoutWidget w = (LayoutWidget) gw;
+ XtGeometryResult result;
+ XtWidgetGeometry prefered_size;
+
+ if (request && !(request->request_mode & (CWWidth|CWHeight)))
+ return XtGeometryYes;
+ LayoutGetNaturalSize (w, &prefered_size.width, &prefered_size.height);
+ prefered_return->request_mode = 0;
+ result = XtGeometryYes;
+ if (!request) {
+ prefered_return->width = prefered_size.width;
+ prefered_return->height= prefered_size.height;
+ if (prefered_size.width != w->core.width) {
+ prefered_return->request_mode |= CWWidth;
+ result = XtGeometryAlmost;
+ }
+ if (prefered_size.height != w->core.height) {
+ prefered_return->request_mode |= CWHeight;
+ result = XtGeometryAlmost;
+ }
+ } else {
+ if (request->request_mode & CWWidth) {
+ if (prefered_size.width > request->width)
+ {
+ if (prefered_size.width == w->core.width)
+ result = XtGeometryNo;
+ else if (result != XtGeometryNo) {
+ result = XtGeometryAlmost;
+ prefered_return->request_mode |= CWWidth;
+ prefered_return->width = prefered_size.width;
+ }
+ }
+ }
+ if (request->request_mode & CWHeight) {
+ if (prefered_size.height > request->height)
+ {
+ if (prefered_size.height == w->core.height)
+ result = XtGeometryNo;
+ else if (result != XtGeometryNo) {
+ result = XtGeometryAlmost;
+ prefered_return->request_mode |= CWHeight;
+ prefered_return->height = prefered_size.height;
+ }
+ }
+ }
+ }
+ return result;
+}
+
+/*
+ * Layout section. Exports LayoutGetNaturalSize and
+ * LayoutLayout to above section
+ */
+
+static void
+PrintGlue (g)
+ GlueRec g;
+{
+ if (g.order == 0 || g.value != 1.0)
+ (void) printf ("%g", g.value);
+ if (g.order > 0)
+ {
+ (void) printf ("%s", " inf");
+ if (g.order > 1)
+ (void) printf (" %d", g.order);
+ }
+}
+
+static void
+PrintDirection (dir)
+ LayoutDirection dir;
+{
+ switch (dir) {
+ case LayoutHorizontal:
+ (void) printf ("%s", "horizontal");
+ break;
+ case LayoutVertical:
+ (void) printf ("%s", "vertical");
+ break;
+ default:
+ (void) printf ("Unknown layout direction %d\n", dir);
+ break;
+
+ }
+}
+
+static void
+TabTo(level)
+ int level;
+{
+ while (level--)
+ (void) printf ("%s", " ");
+}
+
+static void
+PrintBox (box, level)
+ BoxPtr box;
+ int level;
+{
+ BoxPtr child;
+
+ TabTo (level);
+ (void) printf ("%s", "< ");
+ (void) printf ("%s", " + ");
+ PrintGlue (box->params.stretch[LayoutHorizontal]);
+ (void) printf ("%s", " - ");
+ PrintGlue (box->params.shrink[LayoutHorizontal]);
+ (void) printf ("%s", " * ");
+ (void) printf ("%s", " + ");
+ PrintGlue (box->params.stretch[LayoutVertical]);
+ (void) printf ("%s", " - ");
+ PrintGlue (box->params.shrink[LayoutVertical]);
+ (void) printf ("%s", " >");
+ (void) printf (" size: %d x %d", box->size[0], box->size[1]);
+ (void) printf (" natural: %d x %d ", box->natural[0], box->natural[1]);
+ switch (box->type) {
+ case BoxBox:
+ PrintDirection (box->u.box.dir);
+ (void) printf ("%s\n", "");
+ for (child = box->u.box.firstChild; child; child = child->nextSibling)
+ PrintBox (child, level+1);
+ break;
+ case WidgetBox:
+ (void) printf (" %s\n", XrmQuarkToString (box->u.widget.quark));
+ break;
+ case GlueBox:
+ (void) printf ("%s\n", " glue");
+ break;
+ case VariableBox:
+ (void) printf (" variable %s\n", XrmQuarkToString (box->u.variable.quark));
+ break;
+ }
+}
+
+static ExprPtr
+LookupVariable (child, quark)
+ BoxPtr child;
+ XrmQuark quark;
+{
+ BoxPtr parent, box;
+
+ DBUG_ENTER("LookupVariable");
+ DBUG_PRINT("name = <%s>",XrmQuarkToString(quark));
+ DBUG_PRINT("child = %p",child);
+ while ((parent = child->parent))
+ {
+ for (box = parent->u.box.firstChild;
+ box != child;
+ box = box->nextSibling)
+ {
+ if (box->type == VariableBox && box->u.variable.quark == quark)
+ DBUG_RETURN("%p", box->u.variable.expr);
+ }
+ child = parent;
+ }
+ DBUG_RETURN("failure -> %d",0);
+}
+
+static double
+Evaluate (l, box, expr, natural)
+ LayoutWidget l;
+ BoxPtr box;
+ ExprPtr expr;
+ double natural;
+{
+ double left, right, down;
+ Widget widget;
+ SubInfoPtr info;
+
+ DBUG_PRINT("Evaluate %d", expr->type);
+ switch (expr->type) {
+ case Constant:
+ return expr->u.constant;
+ case Binary:
+ left = Evaluate (l, box, expr->u.binary.left, natural);
+ right = Evaluate (l, box, expr->u.binary.right, natural);
+ switch (expr->u.binary.op) {
+ case Plus:
+ return left + right;
+ case Minus:
+ return left - right;
+ case Times:
+ return left * right;
+ case Divide:
+ return left / right;
+ case Percent:
+ return right * left / 100.0;
+ }
+ case Unary:
+ down = Evaluate (l, box, expr->u.unary.down, natural);
+ switch (expr->u.unary.op) {
+ case Percent:
+ return natural * down / 100.0;
+ case Minus:
+ return -down;
+ case Plus:
+ case Times:
+ case Divide:
+ break;
+ }
+ case Width:
+ widget = QuarkToWidget (l, expr->u.width);
+ if (!widget)
+ return 0;
+ info = SubInfo (widget);
+ return info->naturalSize[LayoutHorizontal];
+ case Height:
+ widget = QuarkToWidget (l, expr->u.height);
+ if (!widget)
+ return 0;
+ info = SubInfo (widget);
+ return info->naturalSize[LayoutVertical];
+ case Variable:
+ {
+ /* in the original code there was no nexpr,
+ expr was overwritten by LookupVariable and
+ the expression "expr->u.variable" to obtain the
+ variable name for the errormessage cause a segmentation
+ violation */
+ ExprPtr nexpr;
+ nexpr = LookupVariable (box, expr->u.variable);
+ if (!nexpr)
+ {
+ char buf[256];
+ (void) sprintf (buf, "Layout: undefined variable %s\n",
+ XrmQuarkToString (expr->u.variable));
+ XtError (buf);
+ return 0.0;
+ }
+ return Evaluate (l, box, nexpr, natural);
+ }
+ }
+ return 0.0;
+}
+
+static void
+DisposeExpr (expr)
+ ExprPtr expr;
+{
+ if (!expr)
+ return;
+ switch (expr->type) {
+ case Constant:
+ break;
+ case Binary:
+ DisposeExpr (expr->u.binary.left);
+ DisposeExpr (expr->u.binary.right);
+ break;
+ case Unary:
+ DisposeExpr (expr->u.unary.down);
+ break;
+ case Width:
+ case Height:
+ case Variable:
+ break;
+ }
+ Dispose (expr);
+}
+
+#define CheckGlue(l, box, glue, n) { \
+ if (glue.expr) \
+ glue.value = Evaluate (l, box, glue.expr, n); \
+ if (glue.order == 0 && glue.value == 0) \
+ glue.order = -1; \
+ else if (glue.order == -1 && glue.value != 0) \
+ glue.order = 0; \
+}
+
+#define DoStretch(l, box, dir) \
+ CheckGlue (l, box, box->params.stretch[dir], (double) box->natural[dir]);
+
+#define DoShrink(l, box, dir) \
+ CheckGlue (l, box, box->params.shrink[dir], (double) box->natural[dir])
+
+/* compute the natural sizes of a box */
+static void
+ComputeNaturalSizes (l, box, dir)
+ LayoutWidget l;
+ BoxPtr box;
+ LayoutDirection dir;
+{
+ BoxPtr child;
+ Widget w;
+ SubInfoPtr info;
+ int minStretchOrder, minShrinkOrder;
+ LayoutDirection thisDir;
+
+ DBUG_ENTER("ComputeNaturalSizes");
+ DBUG_PRINT("box->type=%d",box->type);
+ switch (box->type) {
+ case WidgetBox:
+ w = box->u.widget.widget = QuarkToWidget (l, box->u.widget.quark);
+ if (!w)
+ {
+ box->natural[LayoutHorizontal] = 0;
+ box->natural[LayoutVertical] = 0;
+ }
+ else
+ {
+ info = SubInfo (w);
+ box->natural[LayoutHorizontal] = info->naturalSize[LayoutHorizontal];
+ box->natural[LayoutVertical] = info->naturalSize[LayoutVertical];
+ }
+ DoStretch (l, box, dir);
+ DoShrink (l, box, dir);
+ DoStretch (l, box, !dir);
+ DoShrink (l, box, !dir);
+ break;
+ case GlueBox:
+ box->natural[dir] = Evaluate (l, box, box->u.glue.expr, 0.0);
+ box->natural[!dir] = 0;
+ DoStretch (l, box, dir);
+ DoShrink (l, box, dir);
+ break;
+ case BoxBox:
+ thisDir = box->u.box.dir;
+ box->natural[0] = 0;
+ box->natural[1] = 0;
+ minStretchOrder = 100000;
+ minShrinkOrder = 100000;
+ ZeroGlue (box->params.shrink[thisDir]);
+ ZeroGlue (box->params.stretch[thisDir]);
+ box->params.shrink[!thisDir].order = 100000;
+ box->params.stretch[!thisDir].order = 100000;
+ for (child = box->u.box.firstChild; child; child = child->nextSibling)
+ {
+ ComputeNaturalSizes (l, child, thisDir);
+ /*
+ * along box axis:
+ * normal size += child normal size
+ * shrink += child shrink
+ * stretch += child stretch
+ */
+ box->natural[thisDir] += child->natural[thisDir];
+ AddGlue (box->params.shrink[thisDir],
+ box->params.shrink[thisDir],
+ child->params.shrink[thisDir]);
+ AddGlue (box->params.stretch[thisDir],
+ box->params.stretch[thisDir],
+ child->params.stretch[thisDir]);
+ /*
+ * normal to box axis:
+ * normal size = maximum child normal size of minimum shrink order
+ * shrink = difference between normal size and minimum shrink
+ * stretch = minimum child stretch
+ */
+ if (box->natural[!thisDir] >= child->natural[!thisDir])
+ {
+ if (child->params.stretch[!thisDir].order < minShrinkOrder)
+ {
+ box->natural[!thisDir] = child->natural[!thisDir];
+ minStretchOrder = child->params.stretch[!thisDir].order;
+ if (child->params.shrink[!thisDir].order < minShrinkOrder)
+ minShrinkOrder = child->params.shrink[!thisDir].order;
+ }
+ }
+ else
+ {
+ if (child->params.shrink[!thisDir].order <= minStretchOrder)
+ {
+ box->natural[!thisDir] = child->natural[!thisDir];
+ minShrinkOrder = child->params.shrink[!thisDir].order;
+ if (child->params.stretch[!thisDir].order < minStretchOrder)
+ minStretchOrder = child->params.stretch[!thisDir].order;
+ }
+ }
+ MinGlue (box->params.stretch[!thisDir],
+ box->params.stretch[!thisDir],
+ child->params.stretch[!thisDir]);
+ MinGlue (box->params.shrink[!thisDir],
+ box->params.shrink[!thisDir],
+ child->params.shrink[!thisDir]);
+ }
+ if (box->params.shrink[!thisDir].order <= 0)
+ {
+ int minSize;
+ int largestMinSize;
+
+ largestMinSize = 0;
+ for (child = box->u.box.firstChild; child; child = child->nextSibling)
+ {
+ if (child->params.shrink[!thisDir].order <= 0)
+ {
+ minSize = child->natural[!thisDir] -
+ child->params.shrink[!thisDir].value;
+ if (minSize > largestMinSize)
+ largestMinSize = minSize;
+ }
+ }
+ box->params.shrink[!thisDir].value = box->natural[!thisDir] -
+ largestMinSize;
+ if (box->params.shrink[!thisDir].value == 0)
+ box->params.shrink[!thisDir].order = -1;
+ else
+ box->params.shrink[!thisDir].order = 0;
+ }
+ break;
+ case VariableBox:
+ break;
+ }
+ DBUG_VOID_RETURN;
+}
+
+/* given the boxs geometry, set the geometry of the pieces */
+
+#define GluePart(a,b,dist) ((a) ? ((int) (((a) * (dist)) / (b) + \
+ ((dist >= 0) ? 0.5 : -0.5))) : 0)
+
+static Bool
+ComputeSizes (box)
+ BoxPtr box;
+{
+ LayoutDirection dir;
+ BoxPtr child;
+ GlueRec stretch;
+ GlueRec shrink;
+ GlueRec totalGlue[2];
+ double remainingGlue;
+ GluePtr glue;
+ int size;
+ int totalSizes;
+ int totalChange[2];
+ int change;
+ int remainingChange;
+ Bool shrinking;
+ Bool happy;
+ int i;
+ int maxGlue;
+
+ dir = box->u.box.dir;
+ size = box->size[dir];
+
+ stretch = box->params.stretch[dir];
+ shrink = box->params.shrink[dir];
+
+ /* pick the correct adjustment parameters based on the change direction */
+
+ totalChange[0] = size - box->natural[dir];
+
+ shrinking = totalChange[0] < 0;
+
+ totalChange[1] = 0;
+ totalGlue[1].order = 100000;
+ totalGlue[1].value = 0;
+ maxGlue = 1;
+ if (shrinking)
+ {
+ totalGlue[0] = shrink;
+ /* for first-order infinites, shrink it to zero and then
+ * shrink the zero-orders
+ */
+ if (shrink.order == 1) {
+ totalSizes = 0;
+ remainingGlue = 0;
+ for (child = box->u.box.firstChild;
+ child;
+ child = child->nextSibling)
+ {
+ switch (child->params.shrink[dir].order) {
+ case 0:
+ remainingGlue += child->params.shrink[dir].value;
+ break;
+ case 1:
+ totalSizes += child->natural[dir];
+ break;
+ }
+ }
+ if (totalSizes < -totalChange[0])
+ {
+ totalGlue[1] = shrink;
+ totalGlue[0].order = 0;
+ totalGlue[0].value = remainingGlue;
+ totalChange[1] = -totalSizes;
+ totalChange[0] = totalChange[0] - totalChange[1];
+ maxGlue = 2;
+ }
+ }
+ if (totalGlue[0].order <= 0 &&
+ totalChange[0] > totalGlue[0].value)
+ {
+ totalChange[0] = totalGlue[0].value;
+ }
+ }
+ else
+ totalGlue[0] = stretch;
+
+ /* adjust each box */
+ totalSizes = 0;
+ remainingGlue = totalGlue[0].value + totalGlue[1].value;
+ remainingChange = totalChange[0] + totalChange[1];
+ happy = True;
+ for (child = box->u.box.firstChild; child; child = child->nextSibling)
+ {
+ /* never add glue or stretch to a VariableBox! */
+ if (child->type == VariableBox) continue;
+
+ if (shrinking)
+ glue = &child->params.shrink[dir];
+ else
+ glue = &child->params.stretch[dir];
+
+ child->size[dir] = child->natural[dir];
+ for (i = 0; i < maxGlue; i++)
+ {
+ if (glue->order == totalGlue[i].order)
+ {
+ remainingGlue -= glue->value;
+ if (remainingGlue <= 0)
+ change = remainingChange;
+ else
+ change = GluePart (glue->value,
+ totalGlue[i].value,
+ totalChange[i]);
+ child->size[dir] += change;
+ remainingChange -= change;
+ }
+ }
+ child->size[!dir] = box->size[!dir];
+ totalSizes += child->size[dir];
+ if (child->type == BoxBox)
+ if (!ComputeSizes (child))
+ happy = False;
+ }
+ return totalSizes == box->size[dir] && happy;
+}
+
+static void
+SetSizes (box, x, y)
+ BoxPtr box;
+ Position x, y;
+{
+ BoxPtr child;
+ int width, height;
+ int bw;
+ Widget w;
+ SubInfoPtr info;
+
+ switch (box->type) {
+ case WidgetBox:
+ w = box->u.widget.widget;
+ if (w)
+ {
+ info = SubInfo(w);
+ /* info = (SubInfoPtr) w->core.constraints; */
+ width = box->size[LayoutHorizontal];
+ height = box->size[LayoutVertical];
+ bw = info->naturalBw;
+ width -= bw * 2;
+ height -= bw * 2;
+ /* Widgets which grow too small are placed off screen */
+ if (width <= 0 || height <= 0)
+ {
+ width = 1;
+ height = 1;
+ bw = 0;
+ x = -1;
+ y = -1;
+ }
+ XtConfigureWidget (w, x, y,
+ (Dimension)width, (Dimension)height,
+ (Dimension)bw);
+ }
+ break;
+ case BoxBox:
+ for (child = box->u.box.firstChild; child; child = child->nextSibling)
+ {
+ SetSizes (child, x, y);
+ if (box->u.box.dir == LayoutHorizontal)
+ x += child->size[LayoutHorizontal];
+ else
+ y += child->size[LayoutVertical];
+ }
+ break;
+ case GlueBox:
+ case VariableBox:
+ break;
+ }
+}
+
+static void
+LayoutFreeLayout (box)
+ BoxPtr box;
+{
+ BoxPtr child, next;
+
+ switch (box->type) {
+ case BoxBox:
+ for (child = box->u.box.firstChild; child; child = next)
+ {
+ next = child->nextSibling;
+ LayoutFreeLayout (child);
+ }
+ break;
+ case GlueBox:
+ DisposeExpr (box->u.glue.expr);
+ break;
+ case WidgetBox:
+ case VariableBox:
+ default:
+ break;
+ }
+ DisposeExpr (box->params.stretch[LayoutHorizontal].expr);
+ DisposeExpr (box->params.shrink[LayoutHorizontal].expr);
+ DisposeExpr (box->params.stretch[LayoutVertical].expr);
+ DisposeExpr (box->params.shrink[LayoutVertical].expr);
+ Dispose (box);
+}
+
+
+static void
+LayoutGetNaturalSize (l, widthp, heightp)
+ LayoutWidget l;
+ Dimension *widthp, *heightp;
+{
+ BoxPtr box;
+
+ DBUG_ENTER("LayoutGetNaturalSize");
+ box = l->layout.layout;
+ if (box)
+ {
+ ComputeNaturalSizes (l, box, LayoutHorizontal);
+ *widthp = box->natural[LayoutHorizontal];
+ *heightp = box->natural[LayoutVertical];
+ }
+ else
+ {
+ *widthp = 0;
+ *heightp = 0;
+ }
+ DBUG_VOID_RETURN;
+}
+
+static void
+LayoutLayout (l, attemptResize)
+ LayoutWidget l;
+ Bool attemptResize;
+{
+ BoxPtr box;
+ Dimension width, height;
+ Dimension prefered_width, prefered_height;
+
+ DBUG_ENTER("LayoutLayout");
+ box = l->layout.layout;
+ if (!box)
+ return;
+ LayoutGetNaturalSize (l, &prefered_width, &prefered_height);
+ if (l->core.width == 0 || l->core.height == 0)
+ {
+ l->core.width = prefered_width;
+ l->core.height = prefered_height;
+ }
+ box->size[LayoutHorizontal] = l->core.width;
+ box->size[LayoutVertical] = l->core.height;
+ if (!ComputeSizes (box) && attemptResize)
+ {
+ XtMakeResizeRequest ((Widget) l,
+ prefered_width, prefered_height,
+ &width, &height);
+ if (width != box->size[LayoutHorizontal] ||
+ height != box->size[LayoutVertical])
+ {
+ box->size[LayoutHorizontal] = width;
+ box->size[LayoutVertical] = height;
+ ComputeSizes (box);
+ }
+ }
+ if (l->layout.debug)
+ {
+ PrintBox (box, 0);
+ fflush (stdout);
+ }
+ SetSizes (box, 0, 0);
+ DBUG_VOID_RETURN;
+}
+
diff --git a/src/Layout.h b/src/Layout.h
new file mode 100644
index 0000000..7d9e636
--- /dev/null
+++ b/src/Layout.h
@@ -0,0 +1,94 @@
+/*
+ * $XConsortium: Layout.h,v 1.2 92/01/22 18:03:05 keith Exp $
+ *
+ * Copyright 1991 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, 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 M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. M.I.T. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
+ * 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.
+ *
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+
+#ifndef _XawLayout_h
+#define _XawLayout_h
+
+#include <X11/Constraint.h>
+#include <X11/Xfuncproto.h>
+
+/****************************************************************
+ *
+ * Layout Widget (SubClass of CompositeClass)
+ *
+ ****************************************************************/
+
+/* RESOURCES:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ background Background Pixel XtDefaultBackground
+ border BorderColor Pixel XtDefaultForeground
+ borderWidth BorderWidth Dimension 1
+ cursor Cursor Cursor None
+ destroyCallback Callback Pointer NULL
+ height Height Dimension 0
+ mappedWhenManaged MappedWhenManaged Boolean True
+ sensitive Sensitive Boolean True
+ width Width Dimension 0
+ x Position Position 0
+ y Position Position 0
+ layout Layout Layout NULL
+
+*/
+
+/*
+ * Syntax of layout resource
+ *
+ * *layout:\
+ * <widget-name>.<edge>,<widget-name>.<edge>: distance + stretch-factor\n\
+ * ...
+ * where the null widget-name is taken to be the Layout widget
+ *
+ * e.g:
+ *
+ * *label-1.hStretch: 0
+ * *label-2.vStretch: 1
+ * *layout:\
+ * .left, label-1.left: 10 + 0\n\
+ * label-1.right, label-2.left: 10 + 1\n\
+ * label-2.right, .right: 10 + 0
+ *
+ * This layout causes label-1 to be set 10 pixels from the left edge
+ * and be whatever size the label widget requests, while label-2 will
+ * be set 10 pixels from the right edge, and take up half of the remaining
+ * space to 10 pixels from the right edge of label-1.
+ */
+
+/* New Fields */
+#define XtNlayout "layout"
+#define XtCLayout "Layout"
+#define XtRLayout "Layout"
+#define XtNdebug "debug"
+
+/* Class record constant */
+
+extern WidgetClass layoutWidgetClass;
+
+typedef struct _LayoutClassRec *LayoutWidgetClass;
+typedef struct _LayoutRec *LayoutWidget;
+
+#endif /* _Layout_h */
diff --git a/src/LayoutP.h b/src/LayoutP.h
new file mode 100644
index 0000000..ae1f2c6
--- /dev/null
+++ b/src/LayoutP.h
@@ -0,0 +1,232 @@
+/*
+ * $XConsortium: LayoutP.h,v 1.2 92/01/22 18:03:08 keith Exp $
+ *
+ * Copyright 1991 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, 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 M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. M.I.T. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
+ * 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.
+ *
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+#ifndef _XawLayoutP_h
+#define _XawLayoutP_h
+
+#if defined(LAYOUT)
+# include "Layout.h"
+#else
+# include <X11/Xaw3d/Layout.h>
+#endif
+
+#include <X11/ConstrainP.h>
+
+#ifdef MOTIF
+# include "Xm/ManagerP.h"
+#endif
+
+#define GlueEqual(a,b) ((a).order == (b).order && (a).value == (b).value)
+
+#define AddGlue(r,a,b) if (a.order == b.order) { \
+ r.order = a.order; \
+ r.value = a.value + b.value; \
+ } else { \
+ if (a.order > b.order) \
+ r = a; \
+ else \
+ r = b; \
+ }
+
+#define MinGlue(r,a,b) if (a.order == b.order) { \
+ r.order = a.order; \
+ if (a.value > b.value) \
+ r.value = b.value; \
+ else \
+ r.value = a.value; \
+ } else { \
+ if (a.order > b.order) \
+ r = b; \
+ else \
+ r = a; \
+ }
+
+#define SubGlue(r,a,b) if (a.order == b.order) { \
+ r.order = a.order; \
+ r.value = a.value - b.value; \
+ } else { \
+ if (a.order > b.order) \
+ r = a; \
+ else { \
+ r.order = b.order; \
+ r.value = -b.value; \
+ } \
+ }
+
+#define ZeroGlue(g) ((g).value = 0, (g).order = 0, (g).expr = 0)
+#define IsZeroGlue(g) ((g).value == 0)
+
+#define QuarkToWidget(l,q) XtNameToWidget((Widget) l, \
+ (char *) XrmQuarkToString(q));
+
+typedef enum _BoxType { BoxBox, WidgetBox, GlueBox, VariableBox } BoxType;
+
+typedef enum _LayoutDirection {
+ LayoutHorizontal = 0, LayoutVertical = 1
+} LayoutDirection;
+
+typedef enum _Operator {
+ Plus, Minus, Times, Divide, Percent
+} Operator;
+
+typedef enum _ExprType {
+ Constant,
+ Binary,
+ Unary,
+ Width,
+ Height,
+ Variable
+} ExprType;
+
+typedef struct _Expr *ExprPtr;
+
+typedef struct _Expr {
+ ExprType type;
+ union {
+ double constant;
+ struct {
+ Operator op;
+ ExprPtr left, right;
+ } binary;
+ struct {
+ Operator op;
+ ExprPtr down;
+ } unary;
+ XrmQuark width;
+ XrmQuark height;
+ XrmQuark variable;
+ } u;
+} ExprRec;
+
+typedef struct _Glue {
+ int order;
+ double value;
+ ExprPtr expr;
+} GlueRec, *GluePtr;
+
+typedef struct _BoxParams {
+ GlueRec stretch[2];
+ GlueRec shrink[2];
+} BoxParamsRec, *BoxParamsPtr;
+
+typedef struct _Box *BoxPtr;
+
+typedef BoxPtr LayoutPtr;
+
+typedef struct _Box {
+ BoxPtr nextSibling;
+ BoxPtr parent;
+ BoxParamsRec params;
+ int size[2];
+ int natural[2];
+ BoxType type;
+ union {
+ struct {
+ BoxPtr firstChild;
+ LayoutDirection dir;
+ } box;
+ struct {
+ XrmQuark quark;
+ Widget widget;
+ } widget;
+ struct {
+ ExprPtr expr;
+ } glue;
+ struct {
+ XrmQuark quark;
+ ExprPtr expr;
+ } variable;
+ } u;
+} LBoxRec; /* this conflicted with Box's BoxRec, besides, it's not used anywhere */
+
+typedef struct _SubInfo {
+ int naturalSize[2];
+ int naturalBw;
+} SubInfoRec, *SubInfoPtr;
+
+/* #define New(t) (t *) malloc(sizeof (t)) */
+#define New(t) (t *) XtCalloc(1,sizeof (t))
+#define Dispose(p) XtFree((char *) p)
+#define Some(t,n) (t*) XtMalloc(sizeof(t) * n)
+#define More(p,t,n) ((p)? (t *) XtRealloc((char *) p, sizeof(t)*n):Some(t,n)
+
+/*********************************************************************
+ *
+ * Layout Widget Private Data
+ *
+ *********************************************************************/
+
+/* New fields for the Layout widget class record */
+
+typedef struct _LayoutClassPart {
+ int foo; /* keep compiler happy. */
+} LayoutClassPart;
+
+/* Full Class record declaration */
+typedef struct _LayoutClassRec {
+ CoreClassPart core_class;
+ CompositeClassPart composite_class;
+ ConstraintClassPart constraint_class;
+#ifdef MOTIF
+ XmManagerClassPart manager_class;
+#endif
+ LayoutClassPart layout_class;
+} LayoutClassRec;
+
+extern LayoutClassRec layoutClassRec;
+
+typedef struct _LayoutConstraintsRec {
+#ifdef MOTIF
+ XmManagerConstraintPart manager;
+#endif
+ SubInfoRec layout;
+} LayoutConstraintsRec, *LayoutConstraints;
+
+#define SubInfo(w) (&(((LayoutConstraints) (w)->core.constraints)->layout))
+
+/* New Fields for the Layout widget record */
+
+typedef struct {
+ /* resources */
+ LayoutPtr layout;
+ Boolean debug;
+} LayoutPart;
+
+/**************************************************************************
+ *
+ * Full instance record declaration
+ *
+ **************************************************************************/
+
+typedef struct _LayoutRec {
+ CorePart core;
+ CompositePart composite;
+ ConstraintPart constraint;
+#ifdef MOTIF
+ XmManagerPart manager;
+#endif
+ LayoutPart layout;
+} LayoutRec;
+#endif
diff --git a/src/List.c b/src/List.c
new file mode 100644
index 0000000..aea8720
--- /dev/null
+++ b/src/List.c
@@ -0,0 +1,1230 @@
+/* $XConsortium: List.c,v 1.39 94/04/17 20:12:15 kaleb Exp $ */
+
+/*
+Copyright (c) 1989, 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.
+*/
+
+/*
+ * List.c - List widget
+ *
+ * This is a List widget. It allows the user to select an item in a list and
+ * notifies the application through a callback function.
+ *
+ * Created: 8/13/88
+ * By: Chris D. Peterson
+ * MIT X Consortium
+ */
+
+#include "Xaw3dP.h"
+#include <stdio.h>
+#include <ctype.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xmu/Drawing.h>
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/ListP.h>
+
+/* These added so widget knows whether its height, width are user selected.
+I also added the freedoms member of the list widget part. */
+
+#define HeightLock 1
+#define WidthLock 2
+#define LongestLock 4
+
+#define HeightFree( w ) !(((ListWidget)(w))->list.freedoms & HeightLock )
+#define WidthFree( w ) !(((ListWidget)(w))->list.freedoms & WidthLock )
+#define LongestFree( w ) !(((ListWidget)(w))->list.freedoms & LongestLock )
+
+/*
+ * Default Translation table.
+ */
+
+static char defaultTranslations[] =
+ "<Btn1Down>: Set()\n\
+ <Btn1Up>: Notify()";
+
+/****************************************************************
+ *
+ * Full class record constant
+ *
+ ****************************************************************/
+
+/* Private Data */
+
+#define offset(field) XtOffset(ListWidget, field)
+
+static XtResource resources[] = {
+ {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
+ offset(list.foreground), XtRString, XtDefaultForeground},
+ {XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor),
+ offset(simple.cursor), XtRString, "left_ptr"},
+ {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
+ offset(list.font),XtRString, XtDefaultFont},
+#ifdef XAW_INTERNATIONALIZATION
+ {XtNfontSet, XtCFontSet, XtRFontSet, sizeof(XFontSet ),
+ offset(list.fontset),XtRString, XtDefaultFontSet},
+#endif
+ {XtNlist, XtCList, XtRPointer, sizeof(char **),
+ offset(list.list), XtRString, NULL},
+ {XtNdefaultColumns, XtCColumns, XtRInt, sizeof(int),
+ offset(list.default_cols), XtRImmediate, (XtPointer)2},
+ {XtNlongest, XtCLongest, XtRInt, sizeof(int),
+ offset(list.longest), XtRImmediate, (XtPointer)0},
+ {XtNnumberStrings, XtCNumberStrings, XtRInt, sizeof(int),
+ offset(list.nitems), XtRImmediate, (XtPointer)0},
+ {XtNpasteBuffer, XtCBoolean, XtRBoolean, sizeof(Boolean),
+ offset(list.paste), XtRImmediate, (XtPointer) False},
+ {XtNforceColumns, XtCColumns, XtRBoolean, sizeof(Boolean),
+ offset(list.force_cols), XtRImmediate, (XtPointer) False},
+ {XtNverticalList, XtCBoolean, XtRBoolean, sizeof(Boolean),
+ offset(list.vertical_cols), XtRImmediate, (XtPointer) False},
+ {XtNinternalWidth, XtCWidth, XtRDimension, sizeof(Dimension),
+ offset(list.internal_width), XtRImmediate, (XtPointer)2},
+ {XtNinternalHeight, XtCHeight, XtRDimension, sizeof(Dimension),
+ offset(list.internal_height), XtRImmediate, (XtPointer)2},
+ {XtNcolumnSpacing, XtCSpacing, XtRDimension, sizeof(Dimension),
+ offset(list.column_space), XtRImmediate, (XtPointer)6},
+ {XtNrowSpacing, XtCSpacing, XtRDimension, sizeof(Dimension),
+ offset(list.row_space), XtRImmediate, (XtPointer)2},
+ {XtNcallback, XtCCallback, XtRCallback, sizeof(XtPointer),
+ offset(list.callback), XtRCallback, NULL},
+};
+
+static void Initialize();
+static void ChangeSize();
+static void Resize();
+static void Redisplay();
+static void Destroy();
+static Boolean Layout();
+static XtGeometryResult PreferredGeom();
+static Boolean SetValues();
+static void Notify(), Set(), Unset();
+
+static XtActionsRec actions[] = {
+ {"Notify", Notify},
+ {"Set", Set},
+ {"Unset", Unset},
+};
+
+ListClassRec listClassRec = {
+ {
+/* core_class fields */
+ /* superclass */ (WidgetClass) &simpleClassRec,
+ /* class_name */ "List",
+ /* widget_size */ sizeof(ListRec),
+ /* class_initialize */ XawInitializeWidgetSet,
+ /* class_part_initialize */ NULL,
+ /* class_inited */ FALSE,
+ /* initialize */ Initialize,
+ /* initialize_hook */ NULL,
+ /* realize */ XtInheritRealize,
+ /* actions */ actions,
+ /* num_actions */ XtNumber(actions),
+ /* resources */ resources,
+ /* num_resources */ XtNumber(resources),
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ TRUE,
+ /* compress_exposure */ FALSE,
+ /* 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 */ defaultTranslations,
+ /* query_geometry */ PreferredGeom,
+ },
+/* Simple class fields initialization */
+ {
+ /* change_sensitive */ XtInheritChangeSensitive
+ },
+/* List class fields initialization */
+ {
+ /* not used */ 0
+ },
+};
+
+WidgetClass listWidgetClass = (WidgetClass)&listClassRec;
+
+/****************************************************************
+ *
+ * Private Procedures
+ *
+ ****************************************************************/
+
+static void GetGCs(w)
+Widget w;
+{
+ XGCValues values;
+ ListWidget lw = (ListWidget) w;
+
+ values.foreground = lw->list.foreground;
+ values.font = lw->list.font->fid;
+
+#ifdef XAW_INTERNATIONALIZATION
+ if ( lw->simple.international == True )
+ lw->list.normgc = XtAllocateGC( w, 0, (unsigned) GCForeground,
+ &values, GCFont, 0 );
+ else
+#endif
+ lw->list.normgc = XtGetGC( w, (unsigned) GCForeground | GCFont,
+ &values);
+
+ values.foreground = lw->core.background_pixel;
+
+#ifdef XAW_INTERNATIONALIZATION
+ if ( lw->simple.international == True )
+ lw->list.revgc = XtAllocateGC( w, 0, (unsigned) GCForeground,
+ &values, GCFont, 0 );
+ else
+#endif
+ lw->list.revgc = XtGetGC( w, (unsigned) GCForeground | GCFont,
+ &values);
+
+ values.tile = XmuCreateStippledPixmap(XtScreen(w),
+ lw->list.foreground,
+ lw->core.background_pixel,
+ lw->core.depth);
+ values.fill_style = FillTiled;
+
+#ifdef XAW_INTERNATIONALIZATION
+ if ( lw->simple.international == True )
+ lw->list.graygc = XtAllocateGC( w, 0, (unsigned) GCTile | GCFillStyle,
+ &values, GCFont, 0 );
+ else
+#endif
+ lw->list.graygc = XtGetGC( w, (unsigned) GCFont | GCTile | GCFillStyle,
+ &values);
+}
+
+
+/* CalculatedValues()
+ *
+ * does routine checks/computations that must be done after data changes
+ * but won't hurt if accidently called
+ *
+ * These calculations were needed in SetValues. They were in ResetList.
+ * ResetList called ChangeSize, which made an XtGeometryRequest. You
+ * MAY NOT change your geometry from within a SetValues. (Xt man,
+ * sect. 9.7.2) So, I factored these changes out. */
+
+static void CalculatedValues( w )
+Widget w;
+{
+ int i, len;
+
+ ListWidget lw = (ListWidget) w;
+
+ /* If list is NULL then the list will just be the name of the widget. */
+
+ if (lw->list.list == NULL) {
+ lw->list.list = &(lw->core.name);
+ lw->list.nitems = 1;
+ }
+
+ /* Get number of items. */
+
+ if (lw->list.nitems == 0)
+ for ( ; lw->list.list[lw->list.nitems] != NULL ; lw->list.nitems++);
+
+ /* Get column width. */
+
+ if ( LongestFree( lw ) ) {
+
+ lw->list.longest = 0; /* so it will accumulate real longest below */
+
+ for ( i = 0 ; i < lw->list.nitems; i++) {
+#ifdef XAW_INTERNATIONALIZATION
+ if ( lw->simple.international == True )
+ len = XmbTextEscapement(lw->list.fontset, lw->list.list[i],
+ strlen(lw->list.list[i]));
+ else
+#endif
+ len = XTextWidth(lw->list.font, lw->list.list[i],
+ strlen(lw->list.list[i]));
+ if (len > lw->list.longest)
+ lw->list.longest = len;
+ }
+ }
+
+ lw->list.col_width = lw->list.longest + lw->list.column_space;
+}
+
+/* Function Name: ResetList
+ * Description: Resets the new list when important things change.
+ * Arguments: w - the widget.
+ * changex, changey - allow the height or width to change?
+ *
+ * Returns: TRUE if width or height have been changed
+ */
+
+static void
+ResetList( w, changex, changey )
+Widget w;
+Boolean changex, changey;
+{
+ Dimension width = w->core.width;
+ Dimension height = w->core.height;
+
+ CalculatedValues( w );
+
+ if( Layout( w, changex, changey, &width, &height ) )
+ ChangeSize( w, width, height );
+}
+
+/* Function Name: ChangeSize.
+ * Description: Laysout the widget.
+ * Arguments: w - the widget to try change the size of.
+ * Returns: none.
+ */
+
+static void
+ChangeSize(w, width, height)
+Widget w;
+Dimension width, height;
+{
+ XtWidgetGeometry request, reply;
+
+ request.request_mode = CWWidth | CWHeight;
+ request.width = width;
+ request.height = height;
+
+ switch ( XtMakeGeometryRequest(w, &request, &reply) ) {
+ case XtGeometryYes:
+ break;
+ case XtGeometryNo:
+ break;
+ case XtGeometryAlmost:
+ Layout(w, (request.height != reply.height),
+ (request.width != reply.width),
+ &(reply.width), &(reply.height));
+ request = reply;
+ switch (XtMakeGeometryRequest(w, &request, &reply) ) {
+ case XtGeometryYes:
+ case XtGeometryNo:
+ break;
+ case XtGeometryAlmost:
+ request = reply;
+ Layout(w, FALSE, FALSE, &(request.width), &(request.height));
+ request.request_mode = CWWidth | CWHeight;
+ XtMakeGeometryRequest(w, &request, &reply);
+ break;
+ default:
+ XtAppWarning(XtWidgetToApplicationContext(w),
+ "List Widget: Unknown geometry return.");
+ break;
+ }
+ break;
+ default:
+ XtAppWarning(XtWidgetToApplicationContext(w),
+ "List Widget: Unknown geometry return.");
+ break;
+ }
+}
+
+/* Function Name: Initialize
+ * Description: Function that initilizes the widget instance.
+ * Arguments: junk - NOT USED.
+ * new - the new widget.
+ * Returns: none
+ */
+
+/* ARGSUSED */
+static void
+Initialize(junk, new, args, num_args)
+Widget junk, new;
+ArgList args;
+Cardinal *num_args;
+{
+ ListWidget lw = (ListWidget) new;
+
+/*
+ * Initialize all private resources.
+ */
+
+ /* record for posterity if we are free */
+ lw->list.freedoms = (lw->core.width != 0) * WidthLock +
+ (lw->core.height != 0) * HeightLock +
+ (lw->list.longest != 0) * LongestLock;
+
+ GetGCs(new);
+
+ /* Set row height. based on font or fontset */
+
+#ifdef XAW_INTERNATIONALIZATION
+ if (lw->simple.international == True )
+ lw->list.row_height =
+ XExtentsOfFontSet(lw->list.fontset)->max_ink_extent.height
+ + lw->list.row_space;
+ else
+#endif
+ lw->list.row_height = lw->list.font->max_bounds.ascent
+ + lw->list.font->max_bounds.descent
+ + lw->list.row_space;
+
+ ResetList( new, WidthFree( lw ), HeightFree( lw ) );
+
+ lw->list.highlight = lw->list.is_highlighted = NO_HIGHLIGHT;
+
+} /* Initialize */
+
+/* Function Name: CvtToItem
+ * Description: Converts Xcoord to item number of item containing that
+ * point.
+ * Arguments: w - the list widget.
+ * xloc, yloc - x location, and y location.
+ * Returns: the item number.
+ */
+
+static int
+CvtToItem(w, xloc, yloc, item)
+Widget w;
+int xloc, yloc;
+int *item;
+{
+ int one, another;
+ ListWidget lw = (ListWidget) w;
+ int ret_val = OKAY;
+
+ if (lw->list.vertical_cols) {
+ one = lw->list.nrows * ((xloc - (int) lw->list.internal_width)
+ / lw->list.col_width);
+ another = (yloc - (int) lw->list.internal_height)
+ / lw->list.row_height;
+ /* If out of range, return minimum possible value. */
+ if (another >= lw->list.nrows) {
+ another = lw->list.nrows - 1;
+ ret_val = OUT_OF_RANGE;
+ }
+ }
+ else {
+ one = (lw->list.ncols * ((yloc - (int) lw->list.internal_height)
+ / lw->list.row_height)) ;
+ /* If in right margin handle things right. */
+ another = (xloc - (int) lw->list.internal_width) / lw->list.col_width;
+ if (another >= lw->list.ncols) {
+ another = lw->list.ncols - 1;
+ ret_val = OUT_OF_RANGE;
+ }
+ }
+ if ((xloc < 0) || (yloc < 0))
+ ret_val = OUT_OF_RANGE;
+ if (one < 0) one = 0;
+ if (another < 0) another = 0;
+ *item = one + another;
+ if (*item >= lw->list.nitems) return(OUT_OF_RANGE);
+ return(ret_val);
+}
+
+/* Function Name: FindCornerItems.
+ * Description: Find the corners of the rectangle in item space.
+ * Arguments: w - the list widget.
+ * event - the event structure that has the rectangle it it.
+ * ul_ret, lr_ret - the corners ** RETURNED **.
+ * Returns: none.
+ */
+
+static void
+FindCornerItems(w, event, ul_ret, lr_ret)
+Widget w;
+XEvent * event;
+int *ul_ret, *lr_ret;
+{
+ int xloc, yloc;
+
+ xloc = event->xexpose.x;
+ yloc = event->xexpose.y;
+ CvtToItem(w, xloc, yloc, ul_ret);
+ xloc += event->xexpose.width;
+ yloc += event->xexpose.height;
+ CvtToItem(w, xloc, yloc, lr_ret);
+}
+
+/* Function Name: ItemInRectangle
+ * Description: returns TRUE if the item passed is in the given rectangle.
+ * Arguments: w - the list widget.
+ * ul, lr - corners of the rectangle in item space.
+ * item - item to check.
+ * Returns: TRUE if the item passed is in the given rectangle.
+ */
+
+static Boolean
+ItemInRectangle(w, ul, lr, item)
+Widget w;
+int ul, lr, item;
+{
+ ListWidget lw = (ListWidget) w;
+ int mod_item;
+ int things;
+
+ if (item < ul || item > lr)
+ return(FALSE);
+ if (lw->list.vertical_cols)
+ things = lw->list.nrows;
+ else
+ things = lw->list.ncols;
+
+ mod_item = item % things;
+ if ( (mod_item >= ul % things) && (mod_item <= lr % things ) )
+ return(TRUE);
+ return(FALSE);
+}
+
+
+/* HighlightBackground()
+ *
+ * Paints the color of the background for the given item. It performs
+ * clipping to the interior of internal_width/height by hand, as its a
+ * simple calculation and probably much faster than using Xlib and a clip mask.
+ *
+ * x, y - ul corner of the area item occupies.
+ * gc - the gc to use to paint this rectangle */
+
+static void
+HighlightBackground( w, x, y, gc )
+Widget w;
+int x, y;
+GC gc;
+{
+ ListWidget lw = (ListWidget) w;
+
+ /* easy to clip the rectangle by hand and probably alot faster than Xlib */
+
+ Dimension width = lw->list.col_width;
+ Dimension height = lw->list.row_height;
+ Dimension frame_limited_width = w->core.width - lw->list.internal_width - x;
+ Dimension frame_limited_height= w->core.height- lw->list.internal_height- y;
+
+ /* Clip the rectangle width and height to the edge of the drawable area */
+
+ if ( width > frame_limited_width )
+ width = frame_limited_width;
+ if ( height> frame_limited_height)
+ height = frame_limited_height;
+
+ /* Clip the rectangle x and y to the edge of the drawable area */
+
+ if ( x < lw->list.internal_width ) {
+ width = width - ( lw->list.internal_width - x );
+ x = lw->list.internal_width;
+ }
+ if ( y < lw->list.internal_height) {
+ height = height - ( lw->list.internal_height - x );
+ y = lw->list.internal_height;
+ }
+ XFillRectangle( XtDisplay( w ), XtWindow( w ), gc, x, y,
+ width, height );
+}
+
+
+/* ClipToShadowInteriorAndLongest()
+ *
+ * Converts the passed gc so that any drawing done with that GC will not
+ * write in the empty margin (specified by internal_width/height) (which also
+ * prevents erasing the shadow. It also clips against the value longest.
+ * If the user doesn't set longest, this has no effect (as longest is the
+ * maximum of all item lengths). If the user does specify, say, 80 pixel
+ * columns, though, this prevents items from overwriting other items. */
+
+static void ClipToShadowInteriorAndLongest(lw, gc_p, x)
+ ListWidget lw;
+ GC* gc_p;
+ Dimension x;
+{
+ XRectangle rect;
+
+ rect.x = x;
+ rect.y = lw->list.internal_height;
+ rect.height = lw->core.height - lw->list.internal_height * 2;
+ rect.width = lw->core.width - lw->list.internal_width - x;
+ if ( rect.width > lw->list.longest )
+ rect.width = lw->list.longest;
+
+ XSetClipRectangles( XtDisplay((Widget)lw),*gc_p,0,0,&rect,1,YXBanded );
+}
+
+
+/* PaintItemName()
+ *
+ * paints the name of the item in the appropriate location.
+ * w - the list widget.
+ * item - the item to draw.
+ *
+ * NOTE: no action taken on an unrealized widget. */
+
+static void
+PaintItemName(w, item)
+Widget w;
+int item;
+{
+ char * str;
+ GC gc;
+ int x, y, str_y;
+ ListWidget lw = (ListWidget) w;
+#ifdef XAW_INTERNATIONALIZATION
+ XFontSetExtents *ext = XExtentsOfFontSet(lw->list.fontset);
+#endif
+
+ if (!XtIsRealized(w)) return; /* Just in case... */
+
+ if (lw->list.vertical_cols) {
+ x = lw->list.col_width * (item / lw->list.nrows)
+ + lw->list.internal_width;
+ y = lw->list.row_height * (item % lw->list.nrows)
+ + lw->list.internal_height;
+ }
+ else {
+ x = lw->list.col_width * (item % lw->list.ncols)
+ + lw->list.internal_width;
+ y = lw->list.row_height * (item / lw->list.ncols)
+ + lw->list.internal_height;
+ }
+
+#ifdef XAW_INTERNATIONALIZATION
+ if ( lw->simple.international == True )
+ str_y = y + abs(ext->max_ink_extent.y);
+ else
+#endif
+ str_y = y + lw->list.font->max_bounds.ascent;
+
+ if (item == lw->list.is_highlighted) {
+ if (item == lw->list.highlight) {
+ gc = lw->list.revgc;
+ HighlightBackground(w, x, y, lw->list.normgc);
+ }
+ else {
+ if (XtIsSensitive(w))
+ gc = lw->list.normgc;
+ else
+ gc = lw->list.graygc;
+ HighlightBackground(w, x, y, lw->list.revgc);
+ lw->list.is_highlighted = NO_HIGHLIGHT;
+ }
+ }
+ else {
+ if (item == lw->list.highlight) {
+ gc = lw->list.revgc;
+ HighlightBackground(w, x, y, lw->list.normgc);
+ lw->list.is_highlighted = item;
+ }
+ else {
+ if (XtIsSensitive(w))
+ gc = lw->list.normgc;
+ else
+ gc = lw->list.graygc;
+ }
+ }
+
+ /* List's overall width contains the same number of inter-column
+ column_space's as columns. There should thus be a half
+ column_width margin on each side of each column.
+ The row case is symmetric. */
+
+ x += lw->list.column_space / 2;
+ str_y += lw->list.row_space / 2;
+
+ str = lw->list.list[item]; /* draw it */
+
+ ClipToShadowInteriorAndLongest( lw, &gc, x );
+
+#ifdef XAW_INTERNATIONALIZATION
+ if ( lw->simple.international == True )
+ XmbDrawString( XtDisplay( w ), XtWindow( w ), lw->list.fontset,
+ gc, x, str_y, str, strlen( str ) );
+ else
+#endif
+ XDrawString( XtDisplay( w ), XtWindow( w ),
+ gc, x, str_y, str, strlen( str ) );
+
+ XSetClipMask( XtDisplay( w ), gc, None );
+}
+
+
+/* Redisplay()
+ *
+ * Repaints the widget window on expose events.
+ * w - the list widget.
+ * event - the expose event for this repaint.
+ * junk - not used, unless three-d patch enabled. */
+
+/* ARGSUSED */
+static void
+Redisplay(w, event, junk)
+Widget w;
+XEvent *event;
+Region junk;
+{
+ int item; /* an item to work with. */
+ int ul_item, lr_item; /* corners of items we need to paint. */
+ ListWidget lw = (ListWidget) w;
+
+ if (event == NULL) { /* repaint all. */
+ ul_item = 0;
+ lr_item = lw->list.nrows * lw->list.ncols - 1;
+ XClearWindow(XtDisplay(w), XtWindow(w));
+ }
+ else
+ FindCornerItems(w, event, &ul_item, &lr_item);
+
+ for (item = ul_item; (item <= lr_item && item < lw->list.nitems) ; item++)
+ if (ItemInRectangle(w, ul_item, lr_item, item))
+ PaintItemName(w, item);
+}
+
+
+/* PreferredGeom()
+ *
+ * This tells the parent what size we would like to be
+ * given certain constraints.
+ * w - the widget.
+ * intended - what the parent intends to do with us.
+ * requested - what we want to happen. */
+
+static XtGeometryResult
+PreferredGeom(w, intended, requested)
+Widget w;
+XtWidgetGeometry *intended, *requested;
+{
+ Dimension new_width, new_height;
+ Boolean change, width_req, height_req;
+
+ width_req = intended->request_mode & CWWidth;
+ height_req = intended->request_mode & CWHeight;
+
+ if (width_req)
+ new_width = intended->width;
+ else
+ new_width = w->core.width;
+
+ if (height_req)
+ new_height = intended->height;
+ else
+ new_height = w->core.height;
+
+ requested->request_mode = 0;
+
+/*
+ * We only care about our height and width.
+ */
+
+ if ( !width_req && !height_req)
+ return(XtGeometryYes);
+
+ change = Layout(w, !width_req, !height_req, &new_width, &new_height);
+
+ requested->request_mode |= CWWidth;
+ requested->width = new_width;
+ requested->request_mode |= CWHeight;
+ requested->height = new_height;
+
+ if (change)
+ return(XtGeometryAlmost);
+ return(XtGeometryYes);
+}
+
+
+/* Resize()
+ *
+ * resizes the widget, by changing the number of rows and columns. */
+
+static void
+Resize(w)
+ Widget w;
+{
+ Dimension width, height;
+
+ width = w->core.width;
+ height = w->core.height;
+
+ if (Layout(w, FALSE, FALSE, &width, &height))
+ XtAppWarning(XtWidgetToApplicationContext(w),
+ "List Widget: Size changed when it shouldn't have when resising.");
+}
+
+
+/* Layout()
+ *
+ * lays out the item in the list.
+ * w - the widget.
+ * xfree, yfree - TRUE if we are free to resize the widget in
+ * this direction.
+ * width, height- the is the current width and height that we are going
+ * we are going to layout the list widget to,
+ * depending on xfree and yfree of course.
+ *
+ * RETURNS: TRUE if width or height have been changed. */
+
+static Boolean
+Layout(w, xfree, yfree, width, height)
+Widget w;
+Boolean xfree, yfree;
+Dimension *width, *height;
+{
+ ListWidget lw = (ListWidget) w;
+ Boolean change = FALSE;
+
+/*
+ * If force columns is set then always use number of columns specified
+ * by default_cols.
+ */
+
+ if (lw->list.force_cols) {
+ lw->list.ncols = lw->list.default_cols;
+ if (lw->list.ncols <= 0) lw->list.ncols = 1;
+ /* 12/3 = 4 and 10/3 = 4, but 9/3 = 3 */
+ lw->list.nrows = ( ( lw->list.nitems - 1) / lw->list.ncols) + 1 ;
+ if (xfree) { /* If allowed resize width. */
+
+ /* this counts the same number
+ of inter-column column_space 's as columns. There should thus be a
+ half column_space margin on each side of each column...*/
+
+ *width = lw->list.ncols * lw->list.col_width
+ + 2 * lw->list.internal_width;
+ change = TRUE;
+ }
+ if (yfree) { /* If allowed resize height. */
+ *height = (lw->list.nrows * lw->list.row_height)
+ + 2 * lw->list.internal_height;
+ change = TRUE;
+ }
+ return(change);
+ }
+
+/*
+ * If both width and height are free to change the use default_cols
+ * to determine the number columns and set new width and height to
+ * just fit the window.
+ */
+
+ if (xfree && yfree) {
+ lw->list.ncols = lw->list.default_cols;
+ if (lw->list.ncols <= 0) lw->list.ncols = 1;
+ lw->list.nrows = ( ( lw->list.nitems - 1) / lw->list.ncols) + 1 ;
+ *width = lw->list.ncols * lw->list.col_width
+ + 2 * lw->list.internal_width;
+ *height = (lw->list.nrows * lw->list.row_height)
+ + 2 * lw->list.internal_height;
+ change = TRUE;
+ }
+/*
+ * If the width is fixed then use it to determine the number of columns.
+ * If the height is free to move (width still fixed) then resize the height
+ * of the widget to fit the current list exactly.
+ */
+ else if (!xfree) {
+ lw->list.ncols = ( (int)(*width - 2 * lw->list.internal_width)
+ / (int)lw->list.col_width);
+ if (lw->list.ncols <= 0) lw->list.ncols = 1;
+ lw->list.nrows = ( ( lw->list.nitems - 1) / lw->list.ncols) + 1 ;
+ if ( yfree ) {
+ *height = (lw->list.nrows * lw->list.row_height)
+ + 2 * lw->list.internal_height;
+ change = TRUE;
+ }
+ }
+/*
+ * The last case is xfree and !yfree we use the height to determine
+ * the number of rows and then set the width to just fit the resulting
+ * number of columns.
+ */
+ else if (!yfree) { /* xfree must be TRUE. */
+ lw->list.nrows = (int)(*height - 2 * lw->list.internal_height)
+ / (int)lw->list.row_height;
+ if (lw->list.nrows <= 0) lw->list.nrows = 1;
+ lw->list.ncols = (( lw->list.nitems - 1 ) / lw->list.nrows) + 1;
+ *width = lw->list.ncols * lw->list.col_width
+ + 2 * lw->list.internal_width;
+ change = TRUE;
+ }
+ return(change);
+}
+
+
+/* Notify() - ACTION
+ *
+ * Notifies the user that a button has been pressed, and
+ * calls the callback; if the XtNpasteBuffer resource is true
+ * then the name of the item is also put in CUT_BUFFER0. */
+
+/* ARGSUSED */
+static void
+Notify(w, event, params, num_params)
+Widget w;
+XEvent * event;
+String * params;
+Cardinal *num_params;
+{
+ ListWidget lw = ( ListWidget ) w;
+ int item, item_len;
+ XawListReturnStruct ret_value;
+
+/*
+ * Find item and if out of range then unhighlight and return.
+ *
+ * If the current item is unhighlighted then the user has aborted the
+ * notify, so unhighlight and return.
+ */
+
+ if ( ((CvtToItem(w, event->xbutton.x, event->xbutton.y, &item))
+ == OUT_OF_RANGE) || (lw->list.highlight != item) ) {
+ XawListUnhighlight(w);
+ return;
+ }
+
+ item_len = strlen(lw->list.list[item]);
+
+ if ( lw->list.paste ) /* if XtNpasteBuffer set then paste it. */
+ XStoreBytes(XtDisplay(w), lw->list.list[item], item_len);
+
+/*
+ * Call Callback function.
+ */
+
+ ret_value.string = lw->list.list[item];
+ ret_value.list_index = item;
+
+ XtCallCallbacks( w, XtNcallback, (XtPointer) &ret_value);
+}
+
+
+/* Unset() - ACTION
+ *
+ * unhighlights the current element. */
+
+/* ARGSUSED */
+static void
+Unset(w, event, params, num_params)
+Widget w;
+XEvent * event;
+String * params;
+Cardinal *num_params;
+{
+ XawListUnhighlight(w);
+}
+
+
+/* Set() - ACTION
+ *
+ * Highlights the current element. */
+
+/* ARGSUSED */
+static void
+Set(w, event, params, num_params)
+Widget w;
+XEvent * event;
+String * params;
+Cardinal *num_params;
+{
+ int item;
+ ListWidget lw = (ListWidget) w;
+
+ if ( (CvtToItem(w, event->xbutton.x, event->xbutton.y, &item))
+ == OUT_OF_RANGE)
+ XawListUnhighlight(w); /* Unhighlight current item. */
+ else if ( lw->list.is_highlighted != item ) /* If this item is not */
+ XawListHighlight(w, item); /* highlighted then do it. */
+}
+
+/*
+ * Set specified arguments into widget
+ */
+
+static Boolean
+SetValues(current, request, new, args, num_args)
+Widget current, request, new;
+ArgList args;
+Cardinal *num_args;
+{
+ ListWidget cl = (ListWidget) current;
+ ListWidget rl = (ListWidget) request;
+ ListWidget nl = (ListWidget) new;
+ Boolean redraw = FALSE;
+#ifdef XAW_INTERNATIONALIZATION
+ XFontSetExtents *ext = XExtentsOfFontSet(nl->list.fontset);
+#endif
+
+ /* If the request height/width is different, lock it. Unless its 0. If */
+ /* neither new nor 0, leave it as it was. Not in R5. */
+ if ( nl->core.width != cl->core.width )
+ nl->list.freedoms |= WidthLock;
+ if ( nl->core.width == 0 )
+ nl->list.freedoms &= ~WidthLock;
+
+ if ( nl->core.height != cl->core.height )
+ nl->list.freedoms |= HeightLock;
+ if ( nl->core.height == 0 )
+ nl->list.freedoms &= ~HeightLock;
+
+ if ( nl->list.longest != cl->list.longest )
+ nl->list.freedoms |= LongestLock;
+ if ( nl->list.longest == 0 )
+ nl->list.freedoms &= ~LongestLock;
+
+ /* _DONT_ check for fontset here - it's not in GC.*/
+
+ if ( (cl->list.foreground != nl->list.foreground) ||
+ (cl->core.background_pixel != nl->core.background_pixel) ||
+ (cl->list.font != nl->list.font) ) {
+ XGCValues values;
+ XGetGCValues(XtDisplay(current), cl->list.graygc, GCTile, &values);
+ XmuReleaseStippledPixmap(XtScreen(current), values.tile);
+ XtReleaseGC(current, cl->list.graygc);
+ XtReleaseGC(current, cl->list.revgc);
+ XtReleaseGC(current, cl->list.normgc);
+ GetGCs(new);
+ redraw = TRUE;
+ }
+
+ if ( cl->list.font != nl->list.font ) {
+#ifdef XAW_INTERNATIONALIZATION
+ if ( cl->simple.international == False )
+#endif
+ nl->list.row_height = nl->list.font->max_bounds.ascent
+ + nl->list.font->max_bounds.descent
+ + nl->list.row_space;
+ }
+#ifdef XAW_INTERNATIONALIZATION
+ else if ( ( cl->list.fontset != nl->list.fontset ) &&
+ ( cl->simple.international == True ) )
+ nl->list.row_height = ext->max_ink_extent.height + nl->list.row_space;
+
+ /* ...If the above two font(set) change checkers above both failed, check
+ if row_space was altered. If one of the above passed, row_height will
+ already have been re-calculated. */
+
+ else
+#endif
+ if ( cl->list.row_space != nl->list.row_space ) {
+#ifdef XAW_INTERNATIONALIZATION
+ if (cl->simple.international == True )
+ nl->list.row_height = ext->max_ink_extent.height + nl->list.row_space;
+ else
+#endif
+ nl->list.row_height = nl->list.font->max_bounds.ascent
+ + nl->list.font->max_bounds.descent
+ + nl->list.row_space;
+ }
+
+ if ((cl->core.width != nl->core.width) ||
+ (cl->core.height != nl->core.height) ||
+ (cl->list.internal_width != nl->list.internal_width) ||
+ (cl->list.internal_height != nl->list.internal_height) ||
+ (cl->list.column_space != nl->list.column_space) ||
+ (cl->list.row_space != nl->list.row_space) ||
+ (cl->list.default_cols != nl->list.default_cols) ||
+ ( (cl->list.force_cols != nl->list.force_cols) &&
+ (rl->list.force_cols != nl->list.ncols) ) ||
+ (cl->list.vertical_cols != nl->list.vertical_cols) ||
+ (cl->list.longest != nl->list.longest) ||
+ (cl->list.nitems != nl->list.nitems) ||
+ (cl->list.font != nl->list.font) ||
+ /* Equiv. fontsets might have different values, but the same fonts, so the
+ next comparison is sloppy but not dangerous. */
+#ifdef XAW_INTERNATIONALIZATION
+ (cl->list.fontset != nl->list.fontset) ||
+#endif
+ (cl->list.list != nl->list.list) ) {
+
+ CalculatedValues( new );
+ Layout( new, WidthFree( nl ), HeightFree( nl ),
+ &nl->core.width, &nl->core.height );
+ redraw = TRUE;
+ }
+
+ if (cl->list.list != nl->list.list)
+ nl->list.is_highlighted = nl->list.highlight = NO_HIGHLIGHT;
+
+ if ((cl->core.sensitive != nl->core.sensitive) ||
+ (cl->core.ancestor_sensitive != nl->core.ancestor_sensitive)) {
+ nl->list.highlight = NO_HIGHLIGHT;
+ redraw = TRUE;
+ }
+
+ if (!XtIsRealized(current))
+ return(FALSE);
+
+ return(redraw);
+}
+
+static void Destroy(w)
+ Widget w;
+{
+ ListWidget lw = (ListWidget) w;
+ XGCValues values;
+
+ XGetGCValues(XtDisplay(w), lw->list.graygc, GCTile, &values);
+ XmuReleaseStippledPixmap(XtScreen(w), values.tile);
+ XtReleaseGC(w, lw->list.graygc);
+ XtReleaseGC(w, lw->list.revgc);
+ XtReleaseGC(w, lw->list.normgc);
+}
+
+/* Exported Functions */
+
+/* Function Name: XawListChange.
+ * Description: Changes the list being used and shown.
+ * Arguments: w - the list widget.
+ * list - the new list.
+ * nitems - the number of items in the list.
+ * longest - the length (in Pixels) of the longest element
+ * in the list.
+ * resize - if TRUE the the list widget will
+ * try to resize itself.
+ * Returns: none.
+ * NOTE: If nitems of longest are <= 0 then they will be calculated.
+ * If nitems is <= 0 then the list needs to be NULL terminated.
+ */
+
+void
+#if NeedFunctionPrototypes
+XawListChange(Widget w, char ** list, int nitems, int longest,
+#if NeedWidePrototypes
+ int resize_it)
+#else
+ Boolean resize_it)
+#endif
+#else
+XawListChange(w, list, nitems, longest, resize_it)
+Widget w;
+char ** list;
+int nitems, longest;
+Boolean resize_it;
+#endif
+{
+ ListWidget lw = (ListWidget) w;
+ Dimension new_width = w->core.width;
+ Dimension new_height = w->core.height;
+
+ lw->list.list = list;
+
+ if ( nitems <= 0 ) nitems = 0;
+ lw->list.nitems = nitems;
+ if ( longest <= 0 ) longest = 0;
+
+ /* If the user passes 0 meaning "calculate it", it must be free */
+ if ( longest != 0 )
+ lw->list.freedoms |= LongestLock;
+ else /* the user's word is god. */
+ lw->list.freedoms &= ~LongestLock;
+
+ if ( resize_it )
+ lw->list.freedoms &= ~WidthLock & ~HeightLock;
+ /* else - still resize if its not locked */
+
+ lw->list.longest = longest;
+
+ CalculatedValues( w );
+
+ if( Layout( w, WidthFree( w ), HeightFree( w ),
+ &new_width, &new_height ) )
+ ChangeSize( w, new_width, new_height );
+
+ lw->list.is_highlighted = lw->list.highlight = NO_HIGHLIGHT;
+ if ( XtIsRealized( w ) )
+ Redisplay( w, (XEvent *)NULL, (Region)NULL );
+}
+
+/* Function Name: XawListUnhighlight
+ * Description: unlights the current highlighted element.
+ * Arguments: w - the widget.
+ * Returns: none.
+ */
+
+void
+#if NeedFunctionPrototypes
+XawListUnhighlight(Widget w)
+#else
+XawListUnhighlight(w)
+Widget w;
+#endif
+{
+ ListWidget lw = ( ListWidget ) w;
+
+ lw->list.highlight = NO_HIGHLIGHT;
+ if (lw->list.is_highlighted != NO_HIGHLIGHT)
+ PaintItemName(w, lw->list.is_highlighted); /* unhighlight this one. */
+}
+
+/* Function Name: XawListHighlight
+ * Description: Highlights the given item.
+ * Arguments: w - the list widget.
+ * item - the item to hightlight.
+ * Returns: none.
+ */
+
+void
+#if NeedFunctionPrototypes
+XawListHighlight(Widget w, int item)
+#else
+XawListHighlight(w, item)
+Widget w;
+int item;
+#endif
+{
+ ListWidget lw = ( ListWidget ) w;
+
+ if (XtIsSensitive(w)) {
+ lw->list.highlight = item;
+ if (lw->list.is_highlighted != NO_HIGHLIGHT)
+ PaintItemName(w, lw->list.is_highlighted); /* Unhighlight. */
+ PaintItemName(w, item); /* HIGHLIGHT this one. */
+ }
+}
+
+/* Function Name: XawListShowCurrent
+ * Description: returns the currently highlighted object.
+ * Arguments: w - the list widget.
+ * Returns: the info about the currently highlighted object.
+ */
+
+XawListReturnStruct *
+#if NeedFunctionPrototypes
+XawListShowCurrent(Widget w)
+#else
+XawListShowCurrent(w)
+Widget w;
+#endif
+{
+ ListWidget lw = ( ListWidget ) w;
+ XawListReturnStruct * ret_val;
+
+ ret_val = (XawListReturnStruct *)
+ XtMalloc (sizeof (XawListReturnStruct));/* SPARE MALLOC OK */
+
+ ret_val->list_index = lw->list.highlight;
+ if (ret_val->list_index == XAW_LIST_NONE)
+ ret_val->string = "";
+ else
+ ret_val->string = lw->list.list[ ret_val->list_index ];
+
+ return(ret_val);
+}
+
diff --git a/src/List.h b/src/List.h
new file mode 100644
index 0000000..a3d0abc
--- /dev/null
+++ b/src/List.h
@@ -0,0 +1,239 @@
+/* $XConsortium: List.h,v 1.22 94/04/17 20:12:17 kaleb Exp $ */
+
+/*
+Copyright (c) 1989, 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.
+*/
+
+/* This is the List widget, it is useful to display a list, without the
+ * overhead of having a widget for each item in the list. It allows
+ * the user to select an item in a list and notifies the application through
+ * a callback function.
+ *
+ * Created: 8/13/88
+ * By: Chris D. Peterson
+ * MIT X Consortium
+ */
+
+#ifndef _XawList_h
+#define _XawList_h
+
+/***********************************************************************
+ *
+ * List Widget
+ *
+ ***********************************************************************/
+
+#include "Xaw3dP.h"
+#include <X11/Xaw3d/Simple.h>
+
+/* Resources:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ background Background Pixel XtDefaultBackground
+ border BorderColor Pixel XtDefaultForeground
+ borderWidth BorderWidth Dimension 1
+ callback Callback XtCallbackList NULL **6
+ columnSpacing Spacing Dimension 6
+ cursor Cursor Cursor left_ptr
+ cursorName Cursor String NULL
+ defaultColumns Columns int 2 **5
+ destroyCallback Callback Pointer NULL
+ font Font XFontStruct* XtDefaultFont
+ forceColumns Columns Boolean False **5
+ foreground Foreground Pixel XtDefaultForeground
+ height Height Dimension 0 **1
+ insensitiveBorder Insensitive Pixmap Gray
+ internalHeight Height Dimension 2
+ internalWidth Width Dimension 4
+ list List String * NULL **2
+ longest Longest int 0 **3 **4
+ mappedWhenManaged MappedWhenManaged Boolean True
+ numberStrings NumberStrings int 0 **4
+ pasteBuffer Boolean Boolean False
+ pointerColor Foreground Pixel XtDefaultForeground
+ pointerColorBackground Background Pixel XtDefaultBackground
+ rowSpacing Spacing Dimension 4
+ sensitive Sensitive Boolean True
+ verticalList Boolean Boolean False
+ width Width Dimension 0 **1
+ x Position Position 0
+ y Position Position 0
+
+ **1 - If the Width or Height of the list widget is zero (0) then the value
+ is set to the minimum size necessay to fit the entire list.
+
+ If both Width and Height are zero then they are adjusted to fit the
+ entire list that is created width the number of default columns
+ specified in the defaultColumns resource.
+
+ **2 - This is an array of strings the specify elements of the list.
+ This resource must be specified.
+ (What good is a list widget without a list?? :-)
+
+ **3 - Longest is the length of the widest string in pixels.
+
+ **4 - If either of these values are zero (0) then the list widget calculates
+ the correct value.
+
+ (This allows you to make startup faster if you already have
+ this information calculated)
+
+ NOTE: If the numberStrings value is zero the list must
+ be NULL terminated.
+
+ **5 - By setting the List.Columns resource you can force the application to
+ have a given number of columns.
+
+ **6 - This returns the name and index of the item selected in an
+ XawListReturnStruct that is pointed to by the client_data
+ in the CallbackProc.
+
+*/
+
+
+/*
+ * Value returned when there are no highlighted objects.
+ */
+
+#define XAW_LIST_NONE -1
+
+#define XtCList "List"
+#define XtCSpacing "Spacing"
+#define XtCColumns "Columns"
+#define XtCLongest "Longest"
+#define XtCNumberStrings "NumberStrings"
+
+#define XtNcursor "cursor"
+#define XtNcolumnSpacing "columnSpacing"
+#define XtNdefaultColumns "defaultColumns"
+#define XtNforceColumns "forceColumns"
+#define XtNlist "list"
+#define XtNlongest "longest"
+#define XtNnumberStrings "numberStrings"
+#define XtNpasteBuffer "pasteBuffer"
+#define XtNrowSpacing "rowSpacing"
+#define XtNverticalList "verticalList"
+
+#ifdef XAW_INTERNATIONALIZATION
+#ifndef XtNfontSet
+#define XtNfontSet "fontSet"
+#endif
+#ifndef XtCFontSet
+#define XtCFontSet "FontSet"
+#endif
+#endif
+
+/* Class record constants */
+
+extern WidgetClass listWidgetClass;
+
+typedef struct _ListClassRec *ListWidgetClass;
+typedef struct _ListRec *ListWidget;
+
+/* The list return structure. */
+
+typedef struct _XawListReturnStruct {
+ String string;
+ int list_index;
+} XawListReturnStruct;
+
+/******************************************************************
+ *
+ * Exported Functions
+ *
+ *****************************************************************/
+
+_XFUNCPROTOBEGIN
+
+/* Function Name: XawListChange.
+ * Description: Changes the list being used and shown.
+ * Arguments: w - the list widget.
+ * list - the new list.
+ * nitems - the number of items in the list.
+ * longest - the length (in Pixels) of the longest element
+ * in the list.
+ * resize - if TRUE the the list widget will
+ * try to resize itself.
+ * Returns: none.
+ * NOTE: If nitems of longest are <= 0 then they will be caluculated.
+ * If nitems is <= 0 then the list needs to be NULL terminated.
+ */
+
+extern void XawListChange(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ String* /* list */,
+ int /* nitems */,
+ int /* longest */,
+#if NeedWidePrototypes
+ /* Boolean */ int /* resize */
+#else
+ Boolean /* resize */
+#endif
+#endif
+);
+
+/* Function Name: XawListUnhighlight
+ * Description: unlights the current highlighted element.
+ * Arguments: w - the widget.
+ * Returns: none.
+ */
+
+extern void XawListUnhighlight(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+/* Function Name: XawListHighlight
+ * Description: Highlights the given item.
+ * Arguments: w - the list widget.
+ * item - the item to highlight.
+ * Returns: none.
+ */
+
+extern void XawListHighlight(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ int /* item */
+#endif
+);
+
+
+/* Function Name: XawListShowCurrent
+ * Description: returns the currently highlighted object.
+ * Arguments: w - the list widget.
+ * Returns: the info about the currently highlighted object.
+ */
+
+extern XawListReturnStruct * XawListShowCurrent(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+_XFUNCPROTOEND
+
+#endif /* _XawList_h */
diff --git a/src/ListP.h b/src/ListP.h
new file mode 100644
index 0000000..592ef4c
--- /dev/null
+++ b/src/ListP.h
@@ -0,0 +1,119 @@
+/* $XConsortium: ListP.h,v 1.14 94/04/17 20:12:17 kaleb Exp $ */
+
+/*
+Copyright (c) 1989, 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.
+*/
+
+
+/*
+ * ListP.h - Private definitions for List widget
+ *
+ * This is a List widget. It allows the user to select an item in a list and
+ * notifies the application through a callback function.
+ *
+ * Created: 8/13/88
+ * By: Chris D. Peterson
+ * MIT - Project Athena
+ */
+
+#ifndef _XawListP_h
+#define _XawListP_h
+
+/***********************************************************************
+ *
+ * List Widget Private Data
+ *
+ ***********************************************************************/
+
+#include "Xaw3dP.h"
+#include <X11/Xaw3d/SimpleP.h>
+#include <X11/Xaw3d/List.h>
+
+#define NO_HIGHLIGHT XAW_LIST_NONE
+#define OUT_OF_RANGE -1
+#define OKAY 0
+
+/* New fields for the List widget class record */
+
+typedef struct {int foo;} ListClassPart;
+
+/* Full class record declaration */
+typedef struct _ListClassRec {
+ CoreClassPart core_class;
+ SimpleClassPart simple_class;
+ ListClassPart list_class;
+} ListClassRec;
+
+extern ListClassRec listClassRec;
+
+/* New fields for the List widget record */
+typedef struct {
+ /* resources */
+ Pixel foreground;
+ Dimension internal_width, /* if not 3d, user sets directly. */
+ internal_height,
+ column_space, /* half of *_space is add on top/bot/left of*/
+ row_space; /* each item's text bounding box. half added to longest for right */
+ int default_cols;
+ Boolean force_cols,
+ paste,
+ vertical_cols;
+ int longest; /* in pixels */
+ int nitems; /* number of items in the list. */
+ XFontStruct *font;
+#ifdef XAW_INTERNATIONALIZATION
+ XFontSet fontset; /* Sheeran, Omron KK, 93/03/05 */
+#endif
+ String * list; /* for i18n, always in multibyte format */
+ XtCallbackList callback;
+
+ /* private state */
+ int is_highlighted, /* set to the item currently highlighted. */
+ highlight, /* set to the item that should be highlighted.*/
+ col_width, /* width of each column. */
+ row_height, /* height of each row. */
+ nrows, /* number of rows in the list. */
+ ncols; /* number of columns in the list. */
+ GC normgc, /* a couple of GC's. */
+ revgc,
+ graygc; /* used when inactive. */
+
+ int freedoms; /* flags for resizing height and width */
+
+} ListPart;
+
+
+/****************************************************************
+ *
+ * Full instance record declaration
+ *
+ ****************************************************************/
+
+typedef struct _ListRec {
+ CorePart core;
+ SimplePart simple;
+ ListPart list;
+} ListRec;
+
+#endif /* _XawListP_h */
diff --git a/src/MenuButtoP.h b/src/MenuButtoP.h
new file mode 100644
index 0000000..df2f9dd
--- /dev/null
+++ b/src/MenuButtoP.h
@@ -0,0 +1,102 @@
+/* $XConsortium: MenuButtoP.h,v 1.8 94/04/17 20:12:18 converse Exp $
+ *
+Copyright (c) 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.
+ */
+
+/***********************************************************************
+ *
+ * MenuButton Widget
+ *
+ ***********************************************************************/
+
+/*
+ * MenuButtonP.h - Private Header file for MenuButton widget.
+ *
+ * This is the private header file for the Athena MenuButton widget.
+ * It is intended to provide an easy method of activating pulldown menus.
+ *
+ * Date: May 2, 1989
+ *
+ * By: Chris D. Peterson
+ * MIT X Consortium
+ * kit@expo.lcs.mit.edu
+ */
+
+#ifndef _XawMenuButtonP_h
+#define _XawMenuButtonP_h
+
+#include <X11/Xaw3d/MenuButton.h>
+#include <X11/Xaw3d/CommandP.h>
+
+/************************************
+ *
+ * Class structure
+ *
+ ***********************************/
+
+
+ /* New fields for the MenuButton widget class record */
+typedef struct _MenuButtonClass
+{
+ int makes_compiler_happy; /* not used */
+} MenuButtonClassPart;
+
+ /* Full class record declaration */
+typedef struct _MenuButtonClassRec {
+ CoreClassPart core_class;
+ SimpleClassPart simple_class;
+ ThreeDClassPart threeD_class;
+ LabelClassPart label_class;
+ CommandClassPart command_class;
+ MenuButtonClassPart menuButton_class;
+} MenuButtonClassRec;
+
+extern MenuButtonClassRec menuButtonClassRec;
+
+/***************************************
+ *
+ * Instance (widget) structure
+ *
+ **************************************/
+
+ /* New fields for the MenuButton widget record */
+typedef struct {
+ /* resources */
+ String menu_name;
+
+} MenuButtonPart;
+
+ /* Full widget declaration */
+typedef struct _MenuButtonRec {
+ CorePart core;
+ SimplePart simple;
+ ThreeDPart threeD;
+ LabelPart label;
+ CommandPart command;
+ MenuButtonPart menu_button;
+} MenuButtonRec;
+
+#endif /* _XawMenuButtonP_h */
+
+
diff --git a/src/MenuButton.c b/src/MenuButton.c
new file mode 100644
index 0000000..b96a027
--- /dev/null
+++ b/src/MenuButton.c
@@ -0,0 +1,221 @@
+/* $XConsortium: MenuButton.c,v 1.21 95/06/26 20:35:12 kaleb Exp $ */
+
+/*
+Copyright (c) 1989, 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.
+ *
+ */
+
+
+/***********************************************************************
+ *
+ * MenuButton Widget
+ *
+ ***********************************************************************/
+
+/*
+ * MenuButton.c - Source code for MenuButton widget.
+ *
+ * This is the source code for the Athena MenuButton widget.
+ * It is intended to provide an easy method of activating pulldown menus.
+ *
+ * Date: May 2, 1989
+ *
+ * By: Chris D. Peterson
+ * MIT X Consortium
+ * kit@expo.lcs.mit.edu
+ */
+
+#include <stdio.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/MenuButtoP.h>
+
+static void ClassInitialize();
+static void PopupMenu();
+
+#define superclass ((CommandWidgetClass)&commandClassRec)
+
+static char defaultTranslations[] =
+"<EnterWindow>: highlight()\n\
+ <LeaveWindow>: reset()\n\
+ Any<BtnDown>: reset() PopupMenu()";
+
+/****************************************************************
+ *
+ * Full class record constant
+ *
+ ****************************************************************/
+
+/* Private Data */
+
+#define offset(field) XtOffsetOf(MenuButtonRec, field)
+static XtResource resources[] = {
+ {
+ XtNmenuName, XtCMenuName, XtRString, sizeof(String),
+ offset(menu_button.menu_name), XtRString, (XtPointer)"menu"},
+};
+#undef offset
+
+static XtActionsRec actionsList[] =
+{
+ {"PopupMenu", PopupMenu}
+};
+
+MenuButtonClassRec menuButtonClassRec = {
+ {
+ (WidgetClass) superclass, /* superclass */
+ "MenuButton", /* class_name */
+ sizeof(MenuButtonRec), /* size */
+ ClassInitialize, /* class_initialize */
+ NULL, /* class_part_initialize */
+ FALSE, /* class_inited */
+ NULL, /* initialize */
+ NULL, /* initialize_hook */
+ XtInheritRealize, /* realize */
+ actionsList, /* actions */
+ XtNumber(actionsList), /* num_actions */
+ resources, /* resources */
+ XtNumber(resources), /* resource_count */
+ NULLQUARK, /* xrm_class */
+ FALSE, /* compress_motion */
+ TRUE, /* compress_exposure */
+ TRUE, /* compress_enterleave */
+ FALSE, /* visible_interest */
+ NULL, /* destroy */
+ XtInheritResize, /* resize */
+ XtInheritExpose, /* expose */
+ NULL, /* set_values */
+ NULL, /* set_values_hook */
+ XtInheritSetValuesAlmost, /* set_values_almost */
+ NULL, /* get_values_hook */
+ NULL, /* accept_focus */
+ XtVersion, /* version */
+ NULL, /* callback_private */
+ defaultTranslations, /* tm_table */
+ XtInheritQueryGeometry, /* query_geometry */
+ XtInheritDisplayAccelerator, /* display_accelerator */
+ NULL /* extension */
+ }, /* CoreClass fields initialization */
+ {
+ XtInheritChangeSensitive /* change_sensitive */
+ }, /* SimpleClass fields initialization */
+ {
+ XtInheritXaw3dShadowDraw, /* shadowdraw */
+ }, /* ThreeDClass fields initialization */
+ {
+ 0, /* field not used */
+ }, /* LabelClass fields initialization */
+ {
+ 0, /* field not used */
+ }, /* CommandClass fields initialization */
+ {
+ 0, /* field not used */
+ } /* MenuButtonClass fields initialization */
+};
+
+ /* for public consumption */
+WidgetClass menuButtonWidgetClass = (WidgetClass) &menuButtonClassRec;
+
+/****************************************************************
+ *
+ * Private Procedures
+ *
+ ****************************************************************/
+
+static void ClassInitialize()
+{
+ XawInitializeWidgetSet();
+ XtRegisterGrabAction(PopupMenu, True,
+ (unsigned int)(ButtonPressMask | ButtonReleaseMask),
+ GrabModeAsync, GrabModeAsync);
+}
+
+/* ARGSUSED */
+static void
+PopupMenu(w, event, params, num_params)
+Widget w;
+XEvent * event;
+String * params;
+Cardinal * num_params;
+{
+ MenuButtonWidget mbw = (MenuButtonWidget) w;
+ Widget menu = NULL, temp;
+ Arg arglist[2];
+ Cardinal num_args;
+ int menu_x, menu_y, menu_width, menu_height, button_height;
+ Position button_x, button_y;
+
+ temp = w;
+ while(temp != NULL) {
+ menu = XtNameToWidget(temp, mbw->menu_button.menu_name);
+ if (menu == NULL)
+ temp = XtParent(temp);
+ else
+ break;
+ }
+
+ if (menu == NULL) {
+ char error_buf[BUFSIZ];
+ (void) sprintf(error_buf, "MenuButton: %s %s.",
+ "Could not find menu widget named", mbw->menu_button.menu_name);
+ XtAppWarning(XtWidgetToApplicationContext(w), error_buf);
+ return;
+ }
+ if (!XtIsRealized(menu))
+ XtRealizeWidget(menu);
+
+ menu_width = menu->core.width + 2 * menu->core.border_width;
+ button_height = w->core.height + 2 * w->core.border_width;
+ menu_height = menu->core.height + 2 * menu->core.border_width;
+
+ XtTranslateCoords(w, 0, 0, &button_x, &button_y);
+ menu_x = button_x;
+ menu_y = button_y + button_height;
+
+ if (menu_x >= 0) {
+ int scr_width = WidthOfScreen(XtScreen(menu));
+ if (menu_x + menu_width > scr_width)
+ menu_x = scr_width - menu_width;
+ }
+ if (menu_x < 0)
+ menu_x = 0;
+
+ if (menu_y >= 0) {
+ int scr_height = HeightOfScreen(XtScreen(menu));
+ if (menu_y + menu_height > scr_height)
+ menu_y = scr_height - menu_height;
+ }
+ if (menu_y < 0)
+ menu_y = 0;
+
+ num_args = 0;
+ XtSetArg(arglist[num_args], XtNx, menu_x); num_args++;
+ XtSetArg(arglist[num_args], XtNy, menu_y); num_args++;
+ XtSetValues(menu, arglist, num_args);
+
+ XtPopupSpringLoaded(menu);
+}
+
diff --git a/src/MenuButton.h b/src/MenuButton.h
new file mode 100644
index 0000000..c9ee0df
--- /dev/null
+++ b/src/MenuButton.h
@@ -0,0 +1,90 @@
+/*
+ * $XConsortium: MenuButton.h,v 1.9 94/04/17 20:12:21 kaleb Exp $
+ *
+Copyright (c) 1989, 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.
+ */
+
+/***********************************************************************
+ *
+ * MenuButton Widget
+ *
+ ***********************************************************************/
+
+/*
+ * MenuButton.h - Public Header file for MenuButton widget.
+ *
+ * This is the public header file for the Athena MenuButton widget.
+ * It is intended to provide an easy method of activating pulldown menus.
+ *
+ * Date: May 2, 1989
+ *
+ * By: Chris D. Peterson
+ * MIT X Consortium
+ * kit@expo.lcs.mit.edu
+ */
+
+#ifndef _XawMenuButton_h
+#define _XawMenuButton_h
+
+#include <X11/Xaw3d/Command.h>
+
+/* Resources:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ background Background Pixel XtDefaultBackground
+ bitmap Pixmap Pixmap None
+ border BorderColor Pixel XtDefaultForeground
+ borderWidth BorderWidth Dimension 1
+ callback Callback Pointer NULL
+ cursor Cursor Cursor None
+ destroyCallback Callback Pointer NULL
+ font Font XFontStruct* XtDefaultFont
+ foreground Foreground Pixel XtDefaultForeground
+ height Height Dimension text height
+ highlightThickness Thickness Dimension 2
+ insensitiveBorder Insensitive Pixmap Gray
+ internalHeight Height Dimension 2
+ internalWidth Width Dimension 4
+ justify Justify XtJustify XtJustifyCenter
+ label Label String NULL
+ mappedWhenManaged MappedWhenManaged Boolean True
+ menuName MenuName String "menu"
+ resize Resize Boolean True
+ sensitive Sensitive Boolean True
+ width Width Dimension text width
+ x Position Position 0
+ y Position Position 0
+
+*/
+
+#define XtNmenuName "menuName"
+#define XtCMenuName "MenuName"
+
+extern WidgetClass menuButtonWidgetClass;
+
+typedef struct _MenuButtonClassRec *MenuButtonWidgetClass;
+typedef struct _MenuButtonRec *MenuButtonWidget;
+
+#endif /* _XawMenuButton_h */
diff --git a/src/MultiSink.c b/src/MultiSink.c
new file mode 100644
index 0000000..12ef85c
--- /dev/null
+++ b/src/MultiSink.c
@@ -0,0 +1,780 @@
+/* $XConsortium: MultiSink.c,v 1.6 95/01/23 18:34:46 kaleb Exp $ */
+
+/*
+ * Copyright 1991 by OMRON Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, 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 OMRON not be used in advertising
+ * or publicity pertaining to distribution of the software without specific,
+ * written prior permission. OMRON makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OMRON 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
+ * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Li Yuhong OMRON Corporation
+ */
+
+/***********************************************************
+
+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.
+
+******************************************************************/
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xatom.h>
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/MultiSinkP.h>
+#include <X11/Xaw3d/MultiSrcP.h>
+#include <X11/Xaw3d/TextP.h>
+#include "XawI18n.h"
+#include <stdio.h>
+#include <ctype.h>
+
+#ifdef GETLASTPOS
+#undef GETLASTPOS /* We will use our own GETLASTPOS. */
+#endif
+
+#define GETLASTPOS XawTextSourceScan(source, (XawTextPosition) 0, XawstAll, XawsdRight, 1, TRUE)
+
+static void Initialize(), Destroy();
+static Boolean SetValues();
+static int MaxLines(), MaxHeight();
+static void SetTabs();
+
+static void DisplayText(), InsertCursor(), FindPosition();
+static void FindDistance(), Resolve(), GetCursorBounds();
+
+#define offset(field) XtOffsetOf(MultiSinkRec, multi_sink.field)
+
+static XtResource resources[] = {
+ {XtNfontSet, XtCFontSet, XtRFontSet, sizeof (XFontSet),
+ offset(fontset), XtRString, XtDefaultFontSet},
+ {XtNecho, XtCOutput, XtRBoolean, sizeof(Boolean),
+ offset(echo), XtRImmediate, (XtPointer) True},
+ {XtNdisplayNonprinting, XtCOutput, XtRBoolean, sizeof(Boolean),
+ offset(display_nonprinting), XtRImmediate, (XtPointer) True},
+};
+#undef offset
+
+#define SuperClass (&textSinkClassRec)
+MultiSinkClassRec multiSinkClassRec = {
+ { /* core_class fields */
+ /* superclass */ (WidgetClass) SuperClass,
+ /* class_name */ "MultiSink",
+ /* widget_size */ sizeof(MultiSinkRec),
+ /* class_initialize */ XawInitializeWidgetSet,
+ /* class_part_initialize */ NULL,
+ /* class_inited */ FALSE,
+ /* initialize */ Initialize,
+ /* initialize_hook */ NULL,
+ /* obj1 */ NULL,
+ /* obj2 */ NULL,
+ /* obj3 */ 0,
+ /* resources */ resources,
+ /* num_resources */ XtNumber(resources),
+ /* xrm_class */ NULLQUARK,
+ /* obj4 */ FALSE,
+ /* obj5 */ FALSE,
+ /* obj6 */ FALSE,
+ /* obj7 */ FALSE,
+ /* destroy */ Destroy,
+ /* obj8 */ NULL,
+ /* obj9 */ NULL,
+ /* set_values */ SetValues,
+ /* set_values_hook */ NULL,
+ /* obj10 */ NULL,
+ /* get_values_hook */ NULL,
+ /* obj11 */ NULL,
+ /* version */ XtVersion,
+ /* callback_private */ NULL,
+ /* obj12 */ NULL,
+ /* obj13 */ NULL,
+ /* obj14 */ NULL,
+ /* extension */ NULL
+ },
+ { /* text_sink_class fields */
+ /* DisplayText */ DisplayText,
+ /* InsertCursor */ InsertCursor,
+ /* ClearToBackground */ XtInheritClearToBackground,
+ /* FindPosition */ FindPosition,
+ /* FindDistance */ FindDistance,
+ /* Resolve */ Resolve,
+ /* MaxLines */ MaxLines,
+ /* MaxHeight */ MaxHeight,
+ /* SetTabs */ SetTabs,
+ /* GetCursorBounds */ GetCursorBounds
+ },
+ { /* multi_sink_class fields */
+ /* unused */ 0
+ }
+};
+
+WidgetClass multiSinkObjectClass = (WidgetClass)&multiSinkClassRec;
+
+/* Utilities */
+
+static int
+#if NeedFunctionPrototypes
+CharWidth (
+ Widget w,
+ int x,
+ wchar_t c)
+#else
+CharWidth (w, x, c)
+ Widget w;
+ int x;
+ wchar_t c;
+#endif
+{
+ int i, width;
+ MultiSinkObject sink = (MultiSinkObject) w;
+ XFontSet fontset = sink->multi_sink.fontset;
+ Position *tab;
+
+ if ( c == _Xaw_atowc(XawLF) ) return(0);
+
+ if (c == _Xaw_atowc(XawTAB)) {
+ /* Adjust for Left Margin. */
+ x -= ((TextWidget) XtParent(w))->text.margin.left;
+
+ if (x >= (int)XtParent(w)->core.width) return 0;
+ for (i = 0, tab = sink->text_sink.tabs ;
+ i < sink->text_sink.tab_count ; i++, tab++) {
+ if (x < *tab) {
+ if (*tab < (int)XtParent(w)->core.width)
+ return *tab - x;
+ else
+ return 0;
+ }
+ }
+ return 0;
+ }
+
+ if (XwcTextEscapement (fontset, &c, 1) == 0)
+ if (sink->multi_sink.display_nonprinting)
+ c = _Xaw_atowc('@');
+ else {
+ c = _Xaw_atowc(XawSP);
+ }
+
+ /*
+ * if more efficiency(suppose one column is one ASCII char)
+
+ width = XwcGetColumn(fontset->font_charset, fontset->num_of_fonts, c) *
+ fontset->font_struct_list[0]->min_bounds.width;
+ *
+ * WARNING: Very Slower!!!
+ *
+ * Li Yuhong.
+ */
+
+ width = XwcTextEscapement(fontset, &c, 1);
+
+ return width;
+}
+
+/* Function Name: PaintText
+ * Description: Actually paints the text into the windoe.
+ * Arguments: w - the text widget.
+ * gc - gc to paint text with.
+ * x, y - location to paint the text.
+ * buf, len - buffer and length of text to paint.
+ * Returns: the width of the text painted, or 0.
+ *
+ * NOTE: If this string attempts to paint past the end of the window
+ * then this function will return zero.
+ */
+
+static Dimension
+PaintText(w, gc, x, y, buf, len)
+ Widget w;
+ GC gc;
+ Position x, y;
+ wchar_t* buf;
+ int len;
+{
+ MultiSinkObject sink = (MultiSinkObject) w;
+ TextWidget ctx = (TextWidget) XtParent(w);
+
+ XFontSet fontset = sink->multi_sink.fontset;
+ Position max_x;
+ Dimension width = XwcTextEscapement(fontset, buf, len);
+ XFontSetExtents *ext = XExtentsOfFontSet(fontset);
+ max_x = (Position) ctx->core.width;
+
+ if ( ((int) width) <= -x) /* Don't draw if we can't see it. */
+ return(width);
+
+ XwcDrawImageString(XtDisplay(ctx), XtWindow(ctx), fontset, gc,
+ (int) x, (int) y, buf, len);
+ if ( (((Position) width + x) > max_x) && (ctx->text.margin.right != 0) ) {
+ x = ctx->core.width - ctx->text.margin.right;
+ width = ctx->text.margin.right;
+ XFillRectangle(XtDisplay((Widget) ctx), XtWindow( (Widget) ctx),
+ sink->multi_sink.normgc, (int) x,
+ (int) y - abs(ext->max_logical_extent.y),
+ (unsigned int) width,
+ (unsigned int) ext->max_logical_extent.height);
+ return(0);
+ }
+ return(width);
+}
+
+/* Sink Object Functions */
+
+/*
+ * This function does not know about drawing more than one line of text.
+ */
+
+static void
+DisplayText(w, x, y, pos1, pos2, highlight)
+ Widget w;
+ Position x, y;
+ Boolean highlight;
+ XawTextPosition pos1, pos2;
+{
+ MultiSinkObject sink = (MultiSinkObject) w;
+ Widget source = XawTextGetSource(XtParent(w));
+ wchar_t buf[BUFSIZ];
+ XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset);
+
+ int j, k;
+ XawTextBlock blk;
+ GC gc = highlight ? sink->multi_sink.invgc : sink->multi_sink.normgc;
+ GC invgc = highlight ? sink->multi_sink.normgc : sink->multi_sink.invgc;
+
+ if (!sink->multi_sink.echo) return;
+
+ y += abs(ext->max_logical_extent.y);
+ for ( j = 0 ; pos1 < pos2 ; ) {
+ pos1 = XawTextSourceRead(source, pos1, &blk, (int) pos2 - pos1);
+ for (k = 0; k < blk.length; k++) {
+ if (j >= BUFSIZ) { /* buffer full, dump the text. */
+ x += PaintText(w, gc, x, y, buf, j);
+ j = 0;
+ }
+ buf[j] = ((wchar_t *)blk.ptr)[k];
+ if (buf[j] == _Xaw_atowc(XawLF))
+ continue;
+
+ else if (buf[j] == _Xaw_atowc(XawTAB)) {
+ Position temp = 0;
+ Dimension width;
+
+ if ((j != 0) && ((temp = PaintText(w, gc, x, y, buf, j)) == 0))
+ return;
+
+ x += temp;
+ width = CharWidth(w, x, _Xaw_atowc(XawTAB));
+ XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w),
+ invgc, (int) x,
+ (int) y - abs(ext->max_logical_extent.y),
+ (unsigned int)width,
+ (unsigned int)ext->max_logical_extent.height);
+ x += width;
+ j = -1;
+ }
+ else if (XwcTextEscapement (sink->multi_sink.fontset, &buf[j], 1) == 0) {
+ if (sink->multi_sink.display_nonprinting)
+ buf[j] = _Xaw_atowc('@');
+ else
+ buf[j] = _Xaw_atowc(' ');
+ }
+ j++;
+ }
+ }
+ if (j > 0)
+ (void) PaintText(w, gc, x, y, buf, j);
+}
+
+#define insertCursor_width 6
+#define insertCursor_height 3
+static char insertCursor_bits[] = {0x0c, 0x1e, 0x33};
+
+static Pixmap
+CreateInsertCursor(s)
+ Screen *s;
+{
+ return (XCreateBitmapFromData (DisplayOfScreen(s), RootWindowOfScreen(s),
+ insertCursor_bits, insertCursor_width, insertCursor_height));
+}
+
+/* Function Name: GetCursorBounds
+ * Description: Returns the size and location of the cursor.
+ * Arguments: w - the text object.
+ * RETURNED rect - an X rectangle to return the cursor bounds in.
+ * Returns: none.
+ */
+
+static void
+GetCursorBounds(w, rect)
+ Widget w;
+ XRectangle * rect;
+{
+ MultiSinkObject sink = (MultiSinkObject) w;
+
+ rect->width = (unsigned short) insertCursor_width;
+ rect->height = (unsigned short) insertCursor_height;
+ rect->x = sink->multi_sink.cursor_x - (short) (rect->width / 2);
+ rect->y = sink->multi_sink.cursor_y - (short) rect->height;
+}
+
+/*
+ * The following procedure manages the "insert" cursor.
+ */
+
+static void
+InsertCursor (w, x, y, state)
+ Widget w;
+ Position x, y;
+ XawTextInsertState state;
+{
+ MultiSinkObject sink = (MultiSinkObject) w;
+ Widget text_widget = XtParent(w);
+ XRectangle rect;
+
+ sink->multi_sink.cursor_x = x;
+ sink->multi_sink.cursor_y = y;
+
+ GetCursorBounds(w, &rect);
+ if (state != sink->multi_sink.laststate && XtIsRealized(text_widget))
+ XCopyPlane(XtDisplay(text_widget),
+ sink->multi_sink.insertCursorOn,
+ XtWindow(text_widget), sink->multi_sink.xorgc,
+ 0, 0, (unsigned int) rect.width, (unsigned int) rect.height,
+ (int) rect.x, (int) rect.y, 1);
+ sink->multi_sink.laststate = state;
+}
+
+/*
+ * Given two positions, find the distance between them.
+ */
+
+static void
+FindDistance (w, fromPos, fromx, toPos, resWidth, resPos, resHeight)
+ Widget w;
+ XawTextPosition fromPos; /* First position. */
+ int fromx; /* Horizontal location of first position. */
+ XawTextPosition toPos; /* Second position. */
+ int* resWidth; /* Distance between fromPos and resPos. */
+ XawTextPosition* resPos; /* Actual second position used. */
+ int* resHeight; /* Height required. */
+{
+ MultiSinkObject sink = (MultiSinkObject) w;
+ Widget source = XawTextGetSource(XtParent(w));
+
+ XawTextPosition index, lastPos;
+ wchar_t c;
+ XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset);
+ XawTextBlock blk;
+
+ /* we may not need this */
+ lastPos = GETLASTPOS;
+ XawTextSourceRead(source, fromPos, &blk, (int) toPos - fromPos);
+ *resWidth = 0;
+ for (index = fromPos; index != toPos && index < lastPos; index++) {
+ if (index - blk.firstPos >= blk.length)
+ XawTextSourceRead(source, index, &blk, (int) toPos - fromPos);
+ c = ((wchar_t *)blk.ptr)[index - blk.firstPos];
+ *resWidth += CharWidth(w, fromx + *resWidth, c);
+ if (c == _Xaw_atowc(XawLF)) {
+ index++;
+ break;
+ }
+ }
+ *resPos = index;
+ *resHeight = ext->max_logical_extent.height;
+}
+
+
+static void
+FindPosition(w, fromPos, fromx, width, stopAtWordBreak, resPos, resWidth, resHeight)
+ Widget w;
+ XawTextPosition fromPos; /* Starting position. */
+ int fromx; /* Horizontal location of starting position.*/
+ int width; /* Desired width. */
+ int stopAtWordBreak; /* Whether the resulting position should be at
+ a word break. */
+ XawTextPosition *resPos; /* Resulting position. */
+ int* resWidth; /* Actual width used. */
+ int* resHeight; /* Height required. */
+{
+ MultiSinkObject sink = (MultiSinkObject) w;
+ Widget source = XawTextGetSource(XtParent(w));
+
+ XawTextPosition lastPos, index, whiteSpacePosition = 0;
+ int lastWidth = 0, whiteSpaceWidth = 0;
+ Boolean whiteSpaceSeen;
+ wchar_t c;
+ XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset);
+ XawTextBlock blk;
+
+ lastPos = GETLASTPOS;
+
+ XawTextSourceRead(source, fromPos, &blk, BUFSIZ);
+ *resWidth = 0;
+ whiteSpaceSeen = FALSE;
+ c = 0;
+ for (index = fromPos; *resWidth <= width && index < lastPos; index++) {
+ lastWidth = *resWidth;
+ if (index - blk.firstPos >= blk.length)
+ XawTextSourceRead(source, index, &blk, BUFSIZ);
+ c = ((wchar_t *)blk.ptr)[index - blk.firstPos];
+ *resWidth += CharWidth(w, fromx + *resWidth, c);
+
+ if ((c == _Xaw_atowc(XawSP) || c == _Xaw_atowc(XawTAB)) &&
+ *resWidth <= width) {
+ whiteSpaceSeen = TRUE;
+ whiteSpacePosition = index;
+ whiteSpaceWidth = *resWidth;
+ }
+ if (c == _Xaw_atowc(XawLF)) {
+ index++;
+ break;
+ }
+ }
+ if (*resWidth > width && index > fromPos) {
+ *resWidth = lastWidth;
+ index--;
+ if (stopAtWordBreak && whiteSpaceSeen) {
+ index = whiteSpacePosition + 1;
+ *resWidth = whiteSpaceWidth;
+ }
+ }
+ if (index == lastPos && c != _Xaw_atowc(XawLF)) index = lastPos + 1;
+ *resPos = index;
+ *resHeight = ext->max_logical_extent.height;
+}
+
+static void
+Resolve (w, pos, fromx, width, leftPos, rightPos)
+ Widget w;
+ XawTextPosition pos;
+ int fromx, width;
+ XawTextPosition *leftPos, *rightPos;
+{
+ int resWidth, resHeight;
+ Widget source = XawTextGetSource(XtParent(w));
+
+ FindPosition(w, pos, fromx, width, FALSE, leftPos, &resWidth, &resHeight);
+ if (*leftPos > GETLASTPOS)
+ *leftPos = GETLASTPOS;
+ *rightPos = *leftPos;
+}
+
+static void
+GetGC(sink)
+ MultiSinkObject sink;
+{
+ XtGCMask valuemask = (GCGraphicsExposures | GCForeground | GCBackground );
+ XGCValues values;
+
+ values.graphics_exposures = (Bool) FALSE;
+
+ values.foreground = sink->text_sink.foreground;
+ values.background = sink->text_sink.background;
+
+ sink->multi_sink.normgc = XtAllocateGC( (Widget)sink, 0, valuemask, &values, GCFont, 0 );
+
+ values.foreground = sink->text_sink.background;
+ values.background = sink->text_sink.foreground;
+ sink->multi_sink.invgc = XtAllocateGC( (Widget)sink, 0, valuemask, &values, GCFont, 0 );
+
+ values.function = GXxor;
+ values.background = (unsigned long) 0L; /* (pix ^ 0) = pix */
+ values.foreground = (sink->text_sink.background ^
+ sink->text_sink.foreground);
+ valuemask = GCGraphicsExposures | GCFunction | GCForeground | GCBackground;
+
+ /* if this GC is not used for fontset rendering then AllocateGC aint needed. Dont hurt tho.*/
+ sink->multi_sink.xorgc = XtAllocateGC( (Widget)sink, 0, valuemask, &values, GCFont, 0 );
+}
+
+
+/***** Public routines *****/
+
+/* Function Name: Initialize
+ * Description: Initializes the TextSink Object.
+ * Arguments: request, new - the requested and new values for the object
+ * instance.
+ * Returns: none.
+ *
+ */
+
+/* ARGSUSED */
+static void
+Initialize(request, new, args, num_args)
+ Widget request, new;
+ ArgList args;
+ Cardinal* num_args;
+{
+ MultiSinkObject sink = (MultiSinkObject) new;
+
+ GetGC(sink);
+
+ sink->multi_sink.insertCursorOn= CreateInsertCursor(XtScreenOfObject(new));
+ sink->multi_sink.laststate = XawisOff;
+ sink->multi_sink.cursor_x = sink->multi_sink.cursor_y = 0;
+}
+
+/* Function Name: Destroy
+ * Description: This function cleans up when the object is
+ * destroyed.
+ * Arguments: w - the MultiSink Object.
+ * Returns: none.
+ */
+
+static void
+Destroy(w)
+ Widget w;
+{
+ MultiSinkObject sink = (MultiSinkObject) w;
+
+ XtReleaseGC(w, sink->multi_sink.normgc);
+ XtReleaseGC(w, sink->multi_sink.invgc);
+ XtReleaseGC(w, sink->multi_sink.xorgc);
+
+ XFreePixmap(XtDisplayOfObject(w), sink->multi_sink.insertCursorOn);
+}
+
+/* Function Name: SetValues
+ * Description: Sets the values for the MultiSink
+ * Arguments: current - current state of the object.
+ * request - what was requested.
+ * new - what the object will become.
+ * Returns: True if redisplay is needed.
+ */
+
+/* ARGSUSED */
+static Boolean
+SetValues(current, request, new, args, num_args)
+ Widget current, request, new;
+ ArgList args;
+ Cardinal* num_args;
+{
+ MultiSinkObject w = (MultiSinkObject) new;
+ MultiSinkObject old_w = (MultiSinkObject) current;
+
+ /* Font set is not in the GC! Do not make a new GC when font set changes! */
+
+ if ( w->multi_sink.fontset != old_w->multi_sink.fontset ) {
+ ((TextWidget)XtParent(new))->text.redisplay_needed = True;
+#ifndef NO_TAB_FIX
+ SetTabs( w, w->text_sink.tab_count, w->text_sink.char_tabs );
+#endif
+ }
+
+ if ( w->text_sink.background != old_w->text_sink.background ||
+ w->text_sink.foreground != old_w->text_sink.foreground ) {
+
+ XtReleaseGC((Widget)w, w->multi_sink.normgc);
+ XtReleaseGC((Widget)w, w->multi_sink.invgc);
+ XtReleaseGC((Widget)w, w->multi_sink.xorgc);
+ GetGC(w);
+ ((TextWidget)XtParent(new))->text.redisplay_needed = True;
+ } else {
+ if ( (w->multi_sink.echo != old_w->multi_sink.echo) ||
+ (w->multi_sink.display_nonprinting !=
+ old_w->multi_sink.display_nonprinting) )
+ ((TextWidget)XtParent(new))->text.redisplay_needed = True;
+ }
+
+ return False;
+}
+
+/* Function Name: MaxLines
+ * Description: Finds the Maximum number of lines that will fit in
+ * a given height.
+ * Arguments: w - the MultiSink Object.
+ * height - height to fit lines into.
+ * Returns: the number of lines that will fit.
+ */
+
+/* ARGSUSED */
+static int
+MaxLines(w, height)
+ Widget w;
+ Dimension height;
+{
+ MultiSinkObject sink = (MultiSinkObject) w;
+ int font_height;
+ XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset);
+
+ font_height = ext->max_logical_extent.height;
+ return( ((int) height) / font_height );
+}
+
+/* Function Name: MaxHeight
+ * Description: Finds the Minium height that will contain a given number
+ * lines.
+ * Arguments: w - the MultiSink Object.
+ * lines - the number of lines.
+ * Returns: the height.
+ */
+
+/* ARGSUSED */
+static int
+#if NeedFunctionPrototypes
+MaxHeight(
+ Widget w,
+ int lines )
+#else
+MaxHeight( w, lines )
+ Widget w;
+ int lines;
+#endif
+{
+ MultiSinkObject sink = (MultiSinkObject) w;
+ XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset);
+
+ return(lines * ext->max_logical_extent.height);
+}
+
+/* Function Name: SetTabs
+ * Description: Sets the Tab stops.
+ * Arguments: w - the MultiSink Object.
+ * tab_count - the number of tabs in the list.
+ * tabs - the text positions of the tabs.
+ * Returns: none
+ */
+
+static void
+#if NeedFunctionPrototypes
+SetTabs(
+ Widget w,
+ int tab_count,
+ short* tabs )
+#else
+SetTabs( w, tab_count, tabs )
+ Widget w;
+ int tab_count;
+ short* tabs;
+#endif
+{
+ MultiSinkObject sink = (MultiSinkObject) w;
+ int i;
+ Atom XA_FIGURE_WIDTH;
+ unsigned long figure_width = 0;
+ XFontStruct *font;
+
+ /*
+ * Bug:
+ * Suppose the first font of fontset stores the unit of column.
+ *
+ * By Li Yuhong, Mar. 14, 1991
+ */
+ { XFontStruct **f_list;
+ char **f_name;
+
+ (void) XFontsOfFontSet(sink->multi_sink.fontset, &f_list, &f_name);
+ font = f_list[0];
+ }
+
+/*
+ * Find the figure width of the current font.
+ */
+
+ XA_FIGURE_WIDTH = XInternAtom(XtDisplayOfObject(w), "FIGURE_WIDTH", FALSE);
+ if ( (XA_FIGURE_WIDTH != None) &&
+ ( (!XGetFontProperty(font, XA_FIGURE_WIDTH, &figure_width)) ||
+ (figure_width == 0)) )
+ if (font->per_char && font->min_char_or_byte2 <= '$' &&
+ font->max_char_or_byte2 >= '$')
+ figure_width = font->per_char['$' - font->min_char_or_byte2].width;
+ else
+ figure_width = font->max_bounds.width;
+
+ if (tab_count > sink->text_sink.tab_count) {
+ sink->text_sink.tabs = (Position *)
+ XtRealloc((char *) sink->text_sink.tabs,
+ (Cardinal) (tab_count * sizeof(Position)));
+ sink->text_sink.char_tabs = (short *)
+ XtRealloc((char *) sink->text_sink.char_tabs,
+ (Cardinal) (tab_count * sizeof(short)));
+ }
+
+ for ( i = 0 ; i < tab_count ; i++ ) {
+ sink->text_sink.tabs[i] = tabs[i] * figure_width;
+ sink->text_sink.char_tabs[i] = tabs[i];
+ }
+
+ sink->text_sink.tab_count = tab_count;
+
+#ifndef NO_TAB_FIX
+ ((TextWidget)XtParent(w))->text.redisplay_needed = True;
+#endif
+}
+
+void
+#if NeedFunctionPrototypes
+_XawMultiSinkPosToXY(
+ Widget w,
+ XawTextPosition pos,
+ Position *x,
+ Position *y )
+#else
+_XawMultiSinkPosToXY( w, pos, x, y )
+ Widget w;
+ XawTextPosition pos;
+ Position *x, *y;
+#endif
+{
+ MultiSinkObject sink = (MultiSinkObject) ((TextWidget)w)->text.sink;
+ XFontSetExtents *ext = XExtentsOfFontSet( sink->multi_sink.fontset );
+
+ _XawTextPosToXY( w, pos, x, y );
+ *y += abs( ext->max_logical_extent.y );
+}
diff --git a/src/MultiSink.h b/src/MultiSink.h
new file mode 100644
index 0000000..9cb7300
--- /dev/null
+++ b/src/MultiSink.h
@@ -0,0 +1,118 @@
+/* $XConsortium: MultiSink.h,v 1.2 94/04/17 20:12:23 kaleb Exp $ */
+
+/*
+ * Copyright 1991 by OMRON Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, 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 OMRON is not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OMRON makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OMRON 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
+ * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Li Yuhong OMRON Corporation
+ */
+
+/***********************************************************
+
+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.
+
+******************************************************************/
+
+#ifndef _XawMultiSink_h
+#define _XawMultiSink_h
+
+/***********************************************************************
+ *
+ * MultiSink Object
+ *
+ ***********************************************************************/
+
+#include <X11/Xaw3d/TextSink.h>
+
+/* Resources:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ echo Output Boolean True
+ displayNonprinting Output Boolean True
+ fontSet FontSet XFontSet XtDefaultFontSet
+
+*/
+
+#define XtCOutput "Output"
+
+#define XtNdisplayNonprinting "displayNonprinting"
+#define XtNecho "echo"
+
+#ifndef XtNfontSet /*Sheeran, Omron KK, 93/03/04*/
+#define XtNfontSet "fontSet"
+#endif
+
+#ifndef XtCFontSet /*Sheeran, Omron KK, 93/03/04*/
+#define XtCFontSet "FontSet"
+#endif
+
+/* Class record constants */
+
+extern WidgetClass multiSinkObjectClass;
+
+typedef struct _MultiSinkClassRec *MultiSinkObjectClass;
+typedef struct _MultiSinkRec *MultiSinkObject;
+
+
+#endif /* _XawMultiSrc_h */
+/* DON'T ADD STUFF AFTER THIS #endif */
diff --git a/src/MultiSinkP.h b/src/MultiSinkP.h
new file mode 100644
index 0000000..1e13914
--- /dev/null
+++ b/src/MultiSinkP.h
@@ -0,0 +1,157 @@
+/* $XConsortium: MultiSinkP.h,v 1.2 94/04/17 20:12:24 kaleb Exp $ */
+
+/*
+ * Copyright 1991 by OMRON Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, 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 OMRON not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OMRON make no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OMRON 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
+ * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Li Yuhong OMRON Corporation
+ */
+
+
+/***********************************************************
+
+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.
+
+******************************************************************/
+
+/*
+ * multiSinkP.h - Private definitions for multiSink object
+ *
+ */
+
+#ifndef _XawMultiSinkP_h
+#define _XawMultiSinkP_h
+
+/***********************************************************************
+ *
+ * MultiSink Object Private Data
+ *
+ ***********************************************************************/
+
+#include <X11/Xaw3d/TextSinkP.h>
+#include <X11/Xaw3d/MultiSink.h>
+
+/************************************************************
+ *
+ * New fields for the MultiSink object class record.
+ *
+ ************************************************************/
+
+typedef struct _MultiSinkClassPart {
+ int foo;
+} MultiSinkClassPart;
+
+/* Full class record declaration */
+
+typedef struct _MultiSinkClassRec {
+ ObjectClassPart object_class;
+ TextSinkClassPart text_sink_class;
+ MultiSinkClassPart multi_sink_class;
+} MultiSinkClassRec;
+
+extern MultiSinkClassRec multiSinkClassRec;
+
+/* New fields for the MultiSink object record */
+typedef struct {
+ /* public resources */
+ Boolean echo;
+ Boolean display_nonprinting;
+
+ /* private state */
+ GC normgc, invgc, xorgc;
+ Pixmap insertCursorOn;
+ XawTextInsertState laststate;
+ short cursor_x, cursor_y; /* Cursor Location. */
+ XFontSet fontset; /* font set to draw */
+} MultiSinkPart;
+
+/****************************************************************
+ *
+ * Full instance record declaration
+ *
+ ****************************************************************/
+
+typedef struct _MultiSinkRec {
+ ObjectPart object;
+ TextSinkPart text_sink;
+ MultiSinkPart multi_sink;
+} MultiSinkRec;
+
+
+/********************************************
+ *
+ * Semi-private functions
+ * for use by other Xaw modules only
+ *
+ *******************************************/
+
+extern void _XawMultiSinkPosToXY(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ XawTextPosition /* pos */,
+ Position * /* x */,
+ Position * /*y */
+#endif
+);
+
+#endif /* _XawMultiSinkP_h */
+
diff --git a/src/MultiSrc.c b/src/MultiSrc.c
new file mode 100644
index 0000000..05a6530
--- /dev/null
+++ b/src/MultiSrc.c
@@ -0,0 +1,1461 @@
+/* $XConsortium: MultiSrc.c,v 1.8 95/01/24 22:29:08 kaleb Exp $ */
+
+/*
+ * Copyright 1991 by OMRON Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, 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 OMRON not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OMRON makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OMRON 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
+ * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Chris Peterson MIT X Consortium
+ * Li Yuhong OMRON Corporation
+ * Frank Sheeran OMRON Corporation
+ *
+ * Much code taken from X11R3 String and Disk Sources.
+ */
+
+/*
+
+Copyright (c) 1991, 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.
+
+*/
+
+/*
+ * MultiSrc.c - MultiSrc object. (For use with the text widget).
+ *
+ */
+
+#include "Xaw3dP.h"
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xfuncs.h>
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/MultiSrcP.h>
+#include <X11/Xaw3d/XawImP.h>
+#include <X11/Xmu/Misc.h>
+#include <X11/Xmu/CharSet.h>
+#include "XawI18n.h"
+#include <X11/Xos.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+
+/****************************************************************
+ *
+ * Full class record constant
+ *
+ ****************************************************************/
+
+/* Private Data */
+
+static int magic_value = MAGIC_VALUE;
+
+#define offset(field) XtOffsetOf(MultiSrcRec, multi_src.field)
+
+static XtResource resources[] = {
+ {XtNstring, XtCString, XtRString, sizeof (XtPointer),
+ offset(string), XtRPointer, NULL},
+ {XtNtype, XtCType, XtRMultiType, sizeof (XawAsciiType),
+ offset(type), XtRImmediate, (XtPointer)XawAsciiString},
+ /* not used. */
+ {XtNdataCompression, XtCDataCompression, XtRBoolean, sizeof (Boolean),
+ offset(data_compression), XtRImmediate, (XtPointer) FALSE},
+ {XtNpieceSize, XtCPieceSize, XtRInt, sizeof (XawTextPosition),
+ offset(piece_size), XtRImmediate, (XtPointer) BUFSIZ},
+ {XtNcallback, XtCCallback, XtRCallback, sizeof(XtPointer),
+ offset(callback), XtRCallback, (XtPointer)NULL},
+ {XtNuseStringInPlace, XtCUseStringInPlace, XtRBoolean, sizeof (Boolean),
+ offset(use_string_in_place), XtRImmediate, (XtPointer) FALSE},
+ {XtNlength, XtCLength, XtRInt, sizeof (int),
+ offset(multi_length), XtRInt, (XtPointer) &magic_value},
+
+};
+#undef offset
+
+static XawTextPosition Scan(), Search(), ReadText();
+static int ReplaceText();
+static MultiPiece * FindPiece(), * AllocNewPiece();
+static FILE * InitStringOrFile();
+static void FreeAllPieces(), RemovePiece(), BreakPiece(), LoadPieces();
+static void RemoveOldStringOrFile(), CvtStringToMultiType();
+static void ClassInitialize(), Initialize(), Destroy(), GetValuesHook();
+static String StorePiecesInString();
+static Boolean SetValues(), WriteToFile();
+
+#define MyWStrncpy( t,s,wcnt ) (void) memmove( (t), (s), (wcnt)*sizeof(wchar_t))
+
+#ifndef MyWStrncpy
+static void (MyWStrncpy)();
+#endif
+
+extern char *tmpnam();
+#ifdef X_NOT_STDC_ENV
+extern int errno;
+#endif
+
+#ifdef X_NOT_POSIX
+#define Off_t long
+#define Size_t unsigned int
+#else
+#define Off_t off_t
+#define Size_t size_t
+#endif
+
+extern wchar_t* _XawTextMBToWC();
+extern char *_XawTextWCToMB();
+
+#define superclass (&textSrcClassRec)
+MultiSrcClassRec multiSrcClassRec = {
+ { /* object_class fields */
+ /* superclass */ (WidgetClass) superclass,
+ /* class_name */ "MultiSrc",
+ /* widget_size */ sizeof(MultiSrcRec),
+ /* class_initialize */ ClassInitialize,
+ /* class_part_initialize */ NULL,
+ /* class_inited */ FALSE,
+ /* initialize */ Initialize,
+ /* initialize_hook */ NULL,
+ /* pad */ NULL,
+ /* pad */ NULL,
+ /* pad */ 0,
+ /* resources */ resources,
+ /* num_resources */ XtNumber(resources),
+ /* xrm_class */ NULLQUARK,
+ /* pad */ FALSE,
+ /* pad */ FALSE,
+ /* pad */ FALSE,
+ /* pad */ FALSE,
+ /* destroy */ Destroy,
+ /* pad */ NULL,
+ /* pad */ NULL,
+ /* set_values */ SetValues,
+ /* set_values_hook */ NULL,
+ /* pad */ NULL,
+ /* get_values_hook */ GetValuesHook,
+ /* pad */ NULL,
+ /* version */ XtVersion,
+ /* callback_private */ NULL,
+ /* pad */ NULL,
+ /* pad */ NULL,
+ /* pad */ NULL,
+ /* extension */ NULL
+ },
+ { /* textSrc_class fields */
+ /* Read */ ReadText,
+ /* Replace */ ReplaceText,
+ /* Scan */ Scan,
+ /* Search */ Search,
+ /* SetSelection */ XtInheritSetSelection,
+ /* ConvertSelection */ XtInheritConvertSelection
+ },
+ { /* multiSrc_class fields */
+ /* Keep the compiler happy */ '\0'
+ }
+};
+
+WidgetClass multiSrcObjectClass = (WidgetClass)&multiSrcClassRec;
+
+/************************************************************
+ *
+ * Semi-Public Interfaces.
+ *
+ ************************************************************/
+
+/* Function Name: ClassInitialize
+ * Description: Class Initialize routine, called only once.
+ * Arguments: none.
+ * Returns: none.
+ */
+
+static void
+ClassInitialize()
+{
+ XawInitializeWidgetSet();
+ XtAddConverter( XtRString, XtRMultiType, CvtStringToMultiType,
+ NULL, (Cardinal) 0);
+}
+
+/* Function Name: Initialize
+ * Description: Initializes the simple menu widget
+ * Arguments: request - the widget requested by the argument list.
+ * new - the new widget with both resource and non
+ * resource values.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+Initialize(request, new, args, num_args)
+ Widget request, new;
+ ArgList args;
+ Cardinal* num_args;
+{
+ MultiSrcObject src = (MultiSrcObject) new;
+ FILE * file;
+
+/*
+ * Set correct flags (override resources) depending upon widget class.
+ */
+
+ src->multi_src.changes = FALSE;
+ src->multi_src.allocated_string = FALSE;
+
+ file = InitStringOrFile(src, src->multi_src.type == XawAsciiFile);
+ LoadPieces(src, file, NULL);
+
+ if (file != NULL) fclose(file);
+ src->text_src.text_format = XawFmtWide;
+
+}
+
+/* Function Name: ReadText
+ * Description: This function reads the source.
+ * Arguments: w - the MultiSource widget.
+ * pos - position of the text to retreive.
+ * RETURNED text - text block that will contain returned text.
+ * length - maximum number of characters to read.
+ * Returns: The number of characters read into the buffer.
+ */
+
+static XawTextPosition
+ReadText(w, pos, text, length)
+ Widget w;
+ XawTextPosition pos;
+ XawTextBlock* text;
+ int length;
+{
+ MultiSrcObject src = (MultiSrcObject) w;
+ XawTextPosition count, start;
+ MultiPiece * piece = FindPiece(src, pos, &start);
+
+ text->format = XawFmtWide;
+ text->firstPos = pos;
+ text->ptr = (char *)(piece->text + (pos - start));
+ count = piece->used - (pos - start);
+ text->length = (length > count) ? count : length;
+ return(pos + text->length);
+}
+
+/* Function Name: ReplaceText.
+ * Description: Replaces a block of text with new text.
+ * Arguments: w - the MultiSource widget.
+ * startPos, endPos - ends of text that will be removed.
+ * text - new text to be inserted into buffer at startPos.
+ * Returns: XawEditError or XawEditDone.
+ */
+
+/*ARGSUSED*/
+static int
+ReplaceText( w, startPos, endPos, u_text_p)
+ Widget w;
+ XawTextPosition startPos, endPos;
+ XawTextBlock* u_text_p;
+{
+ MultiSrcObject src = (MultiSrcObject) w;
+ MultiPiece *start_piece, *end_piece, *temp_piece;
+ XawTextPosition start_first, end_first;
+ int length, firstPos;
+ wchar_t *wptr;
+ Boolean local_artificial_block = False;
+ XawTextBlock text;
+
+ /* STEP 1: The user handed me a text block called `u_text' that may be
+ * in either FMTWIDE or FMT8BIT (ie MB.) Later code needs the block
+ * `text' to hold FMTWIDE. So, this copies `u_text' to `text', and if
+ * `u_text' was MB, I knock it up to WIDE. */
+
+ if ( u_text_p->length == 0 ) /* if so, the block contents never ref'd. */
+ text.length = 0;
+
+ else if ( u_text_p->format == XawFmtWide) {
+ local_artificial_block = False; /* ie, don't have to free it ourselves*/
+ text.firstPos = u_text_p->firstPos;
+ text.length = u_text_p->length;
+ text.ptr = u_text_p->ptr;
+ /* text.format is unneeded */
+
+ } else {
+ /* WARNING! u_text->firstPos and length are in units of CHAR, not CHARACTERS! */
+
+ local_artificial_block = True; /* ie, have to free it ourselves */
+ text.firstPos = 0;
+ text.length = u_text_p->length; /* _XawTextMBToWC converts this to wchar len. */
+
+ text.ptr = (char*)_XawTextMBToWC( XtDisplay(XtParent(w)),
+ &(u_text_p->ptr[u_text_p->firstPos]), &(text.length) );
+
+ /* I assert the following assignment is not needed - since Step 4
+ depends on length, it has no need of a terminating NULL. I think
+ the ASCII-version has the same needless NULL. */
+ /*((wchar_t*)text.ptr)[ text.length ] = NULL;*/
+ }
+
+
+ /* STEP 2: some initialization... */
+
+ if (src->text_src.edit_mode == XawtextRead)
+ return(XawEditError);
+
+ start_piece = FindPiece(src, startPos, &start_first);
+ end_piece = FindPiece(src, endPos, &end_first);
+
+
+ /* STEP 3: remove the empty pieces... */
+
+ if (start_piece != end_piece) {
+ temp_piece = start_piece->next;
+
+ /* If empty and not the only piece then remove it. */
+
+ if ( ((start_piece->used = startPos - start_first) == 0) &&
+ !((start_piece->next == NULL) && (start_piece->prev == NULL)) )
+ RemovePiece(src, start_piece);
+
+ while (temp_piece != end_piece) {
+ temp_piece = temp_piece->next;
+ RemovePiece(src, temp_piece->prev);
+ }
+ end_piece->used -= endPos - end_first;
+ if (end_piece->used != 0)
+ MyWStrncpy(end_piece->text, (end_piece->text + endPos - end_first),
+ (int) end_piece->used);
+ }
+ else { /* We are fully in one piece. */
+ if ( (start_piece->used -= endPos - startPos) == 0) {
+ if ( !((start_piece->next == NULL) && (start_piece->prev == NULL)) )
+ RemovePiece(src, start_piece);
+ }
+ else {
+ MyWStrncpy(start_piece->text + (startPos - start_first),
+ start_piece->text + (endPos - start_first),
+ (int) (start_piece->used - (startPos - start_first)) );
+ if ( src->multi_src.use_string_in_place &&
+ ((src->multi_src.length - (endPos - startPos)) <
+ (src->multi_src.piece_size - 1)) )
+ start_piece->text[src->multi_src.length - (endPos - startPos)] = (wchar_t)0;
+ }
+ }
+
+ src->multi_src.length += text.length -(endPos - startPos);
+ /*((TextWidget)src->object.parent)->text.lastPos = src->multi_src.length;*/
+
+
+
+ /* STEP 4: insert the new stuff */
+
+ if ( text.length != 0) {
+
+ start_piece = FindPiece(src, startPos, &start_first);
+
+ length = text.length;
+ firstPos = text.firstPos;
+
+ while (length > 0) {
+ wchar_t* ptr;
+ int fill;
+
+ if (src->multi_src.use_string_in_place) {
+ if (start_piece->used == (src->multi_src.piece_size - 1)) {
+ /*
+ * The string is used in place, then the string
+ * is not allowed to grow.
+ */
+ start_piece->used = src->multi_src.length =
+ src->multi_src.piece_size - 1;
+ /*((TextWidget)src->object.parent)->text.lastPos = src->multi_src.length;*/
+
+
+ start_piece->text[src->multi_src.length] = (wchar_t)0;
+ return(XawEditError);
+ }
+ }
+
+
+ if (start_piece->used == src->multi_src.piece_size) {
+ BreakPiece(src, start_piece);
+ start_piece = FindPiece(src, startPos, &start_first);
+ }
+
+ fill = Min((int)(src->multi_src.piece_size - start_piece->used), length);
+
+ ptr = start_piece->text + (startPos - start_first);
+ MyWStrncpy(ptr + fill, ptr,
+ (int) start_piece->used - (startPos - start_first));
+ wptr =(wchar_t *)text.ptr;
+ (void)wcsncpy(ptr, wptr + firstPos, fill);
+
+ startPos += fill;
+ firstPos += fill;
+ start_piece->used += fill;
+ length -= fill;
+ }
+ }
+
+ if ( local_artificial_block == True )
+
+ /* In other words, text is not the u_text that the user handed me but
+ one I made myself. I only care, because I need to free the string. */
+
+ XFree( text.ptr );
+
+ if (src->multi_src.use_string_in_place)
+ start_piece->text[start_piece->used] = (wchar_t)0;
+
+ src->multi_src.changes = TRUE;
+
+ XtCallCallbacks(w, XtNcallback, NULL);
+
+ return(XawEditDone);
+}
+
+/* Function Name: Scan
+ * Description: Scans the text source for the number and type
+ * of item specified.
+ * Arguments: w - the MultiSource widget.
+ * position - the position to start scanning.
+ * type - type of thing to scan for.
+ * dir - direction to scan.
+ * count - which occurance if this thing to search for.
+ * include - whether or not to include the character found in
+ * the position that is returned.
+ * Returns: the position of the item found.
+ *
+ * Note: While there are only 'n' characters in the file there are n+1
+ * possible cursor positions (one before the first character and
+ * one after the last character.
+ */
+
+static
+XawTextPosition
+Scan( w, position, type, dir, count, include )
+ Widget w;
+ XawTextPosition position;
+ XawTextScanType type;
+ XawTextScanDirection dir;
+ int count;
+ Boolean include;
+{
+ MultiSrcObject src = (MultiSrcObject) w;
+ int inc;
+ MultiPiece * piece;
+ XawTextPosition first, first_eol_position = 0;
+ wchar_t * ptr;
+
+ if (type == XawstAll) { /* Optimize this common case. */
+ if (dir == XawsdRight)
+ return(src->multi_src.length);
+ return(0); /* else. */
+ }
+
+
+ /* STEP 1: basic sanity checks */
+
+ if (position > src->multi_src.length)
+ position = src->multi_src.length;
+
+
+ if ( dir == XawsdRight ) {
+ if (position == src->multi_src.length)
+ return(src->multi_src.length);
+ inc = 1;
+ }
+ else {
+ if (position == 0)
+ return(0);
+ inc = -1;
+ position--;
+ }
+
+ piece = FindPiece(src, position, &first);
+
+ if ( piece->used == 0 ) return(0); /* i.e., buffer is empty. */
+
+ ptr = (position - first) + piece->text;
+
+ switch (type) {
+ case XawstEOL:
+ case XawstParagraph:
+ case XawstWhiteSpace:
+ for ( ; count > 0 ; count-- ) {
+ Boolean non_space = FALSE, first_eol = TRUE;
+ /* CONSTCOND */
+ while (TRUE) {
+ wchar_t c = *ptr;
+
+ ptr += inc;
+ position += inc;
+
+ if (type == XawstWhiteSpace) {
+ if (iswspace(c)) {
+ if (non_space)
+ break;
+ }
+ else
+ non_space = TRUE;
+ }
+ else if (type == XawstEOL) {
+ if (c == _Xaw_atowc(XawLF)) break;
+ }
+ else { /* XawstParagraph */
+ if (first_eol) {
+ if (c == _Xaw_atowc(XawLF)) {
+ first_eol_position = position;
+ first_eol = FALSE;
+ }
+ }
+ else
+ if ( c == _Xaw_atowc(XawLF))
+ break;
+ else if ( !iswspace(c) )
+ first_eol = TRUE;
+ }
+
+
+ if ( ptr < piece->text ) {
+ piece = piece->prev;
+ if (piece == NULL) /* Begining of text. */
+ return(0);
+ ptr = piece->text + piece->used - 1;
+ }
+ else if ( ptr >= (piece->text + piece->used) ) {
+ piece = piece->next;
+ if (piece == NULL) /* End of text. */
+ return(src->multi_src.length);
+ ptr = piece->text;
+ }
+ }
+ }
+ if (!include) {
+ if ( type == XawstParagraph)
+ position = first_eol_position;
+ position -= inc;
+ }
+ break;
+ case XawstPositions:
+ position += count * inc;
+ break;
+ case XawstAll: /* handled in special code above */
+ default:
+ break;
+ }
+
+ if ( dir == XawsdLeft )
+ position++;
+
+ if (position >= src->multi_src.length)
+ return(src->multi_src.length);
+ if (position < 0)
+ return(0);
+
+ return(position);
+}
+
+/* Function Name: Search
+ * Description: Searchs the text source for the text block passed
+ * Arguments: w - the MultiSource Widget.
+ * position - the position to start scanning.
+ * dir - direction to scan.
+ * text - the text block to search for.
+ * Returns: the position of the item found.
+ */
+
+static XawTextPosition
+Search(w, position, dir, text )
+ Widget w;
+ XawTextPosition position;
+ XawTextScanDirection dir;
+ XawTextBlock* text;
+{
+ MultiSrcObject src = (MultiSrcObject) w;
+ int inc, count = 0;
+ wchar_t * ptr;
+ wchar_t* wtarget;
+ int wtarget_len;
+ Display * d = XtDisplay(XtParent(w));
+ MultiPiece * piece;
+ wchar_t* buf;
+ XawTextPosition first;
+
+
+ /* STEP 1: First, a brief sanity check. */
+
+ if ( dir == XawsdRight )
+ inc = 1;
+ else {
+ inc = -1;
+ if (position == 0)
+ return(XawTextSearchError); /* scanning left from 0??? */
+ position--;
+ }
+
+
+ /* STEP 2: Ensure I have a local wide string.. */
+
+ /* Since this widget stores 32bit chars, I check here to see if
+ I'm being passed a string claiming to be 8bit chars (ie, MB text.)
+ If that is the case, naturally I convert to 32bit format. */
+
+ /*if the block was FMT8BIT, length will convert to REAL wchar count below */
+ wtarget_len = text->length;
+
+ if ( text->format == XawFmtWide )
+ wtarget = &( ((wchar_t*)text->ptr) [text->firstPos] );
+ else
+ {
+ /* The following converts wtarget_len from byte len to wchar count */
+ wtarget = _XawTextMBToWC( d, &text->ptr[ text->firstPos ], &wtarget_len );
+ }
+
+ /* OK, I can now assert that wtarget holds wide characters, wtarget_len
+ holds an accurate count of those characters, and that firstPos has been
+ effectively factored out of the following computations. */
+
+
+ /* STEP 3: SEARCH! */
+
+ buf = (wchar_t *)XtMalloc((unsigned)sizeof(wchar_t) * wtarget_len );
+ (void)wcsncpy(buf, wtarget, wtarget_len );
+ piece = FindPiece(src, position, &first);
+ ptr = (position - first) + piece->text;
+
+ /* CONSTCOND */
+ while (TRUE) {
+ if (*ptr == ((dir == XawsdRight) ? *(buf + count)
+ : *(buf + wtarget_len - count - 1)) ) {
+ if (count == (text->length - 1))
+ break;
+ else
+ count++;
+ }
+ else {
+ if (count != 0) {
+ position -=inc * count;
+ ptr -= inc * count;
+ }
+ count = 0;
+ }
+
+ ptr += inc;
+ position += inc;
+
+ while ( ptr < piece->text ) {
+ piece = piece->prev;
+ if (piece == NULL) { /* Begining of text. */
+ XtFree((char *)buf);
+ return(XawTextSearchError);
+ }
+ ptr = piece->text + piece->used - 1;
+ }
+
+ while ( ptr >= (piece->text + piece->used) ) {
+ piece = piece->next;
+ if (piece == NULL) { /* End of text. */
+ XtFree((char *)buf);
+ return(XawTextSearchError);
+ }
+ ptr = piece->text;
+ }
+ }
+
+ XtFree( (char *) buf );
+ if (dir == XawsdLeft)
+ return( position );
+ return( position - ( wtarget_len - 1 ) );
+}
+
+/* Function Name: SetValues
+ * Description: Sets the values for the MultiSource.
+ * Arguments: current - current state of the widget.
+ * request - what was requested.
+ * new - what the widget will become.
+ * Returns: True if redisplay is needed.
+ */
+
+/* ARGSUSED */
+static Boolean
+SetValues(current, request, new, args, num_args)
+ Widget current, request, new;
+ ArgList args;
+ Cardinal* num_args;
+{
+ MultiSrcObject src = (MultiSrcObject) new;
+ MultiSrcObject old_src = (MultiSrcObject) current;
+ XtAppContext app_con = XtWidgetToApplicationContext(new);
+ Boolean total_reset = FALSE, string_set = FALSE;
+ FILE * file;
+ int i;
+
+ if ( old_src->multi_src.use_string_in_place !=
+ src->multi_src.use_string_in_place ) {
+ XtAppWarning( app_con,
+ "MultiSrc: The XtNuseStringInPlace resources may not be changed.");
+ src->multi_src.use_string_in_place =
+ old_src->multi_src.use_string_in_place;
+ }
+
+ for (i = 0; i < *num_args ; i++ )
+ if (streq(args[i].name, XtNstring)) {
+ string_set = TRUE;
+ break;
+ }
+
+ if ( string_set || (old_src->multi_src.type != src->multi_src.type) ) {
+ RemoveOldStringOrFile(old_src, string_set);
+ file = InitStringOrFile(src, string_set);
+
+ /* Load pieces does this logic for us, but it shouldn't. Its messy.*/
+ /*if (old_src->multi_src.type == XawAsciiString)
+ LoadPieces(src, NULL, src->multi_src.string);
+ else*/
+ LoadPieces(src, file, NULL);
+ if (file != NULL) fclose(file);
+ XawTextSetSource( XtParent(new), new, 0); /* Tell text widget
+ what happened. */
+ total_reset = TRUE;
+ }
+
+ if ( old_src->multi_src.multi_length != src->multi_src.multi_length )
+ src->multi_src.piece_size = src->multi_src.multi_length;
+
+ if ( !total_reset && (old_src->multi_src.piece_size
+ != src->multi_src.piece_size) ) {
+ String mb_string = StorePiecesInString( old_src );
+
+ if ( mb_string != 0 ) {
+ FreeAllPieces( old_src );
+ LoadPieces( src, NULL, mb_string );
+ XtFree( mb_string );
+ } else {
+ /* If the buffer holds bad chars, don't touch it... */
+ XtAppWarningMsg( app_con,
+ "convertError", "multiSource", "XawError",
+ XtName( XtParent( (Widget) old_src ) ), NULL, NULL );
+ XtAppWarningMsg( app_con,
+ "convertError", "multiSource", "XawError",
+ "Non-character code(s) in buffer.", NULL, NULL );
+ }
+ }
+
+ return(FALSE);
+}
+
+/* Function Name: GetValuesHook
+ * Description: This is a get values hook routine that sets the
+ * values specific to the multi source.
+ * Arguments: w - the MultiSource Widget.
+ * args - the argument list.
+ * num_args - the number of args.
+ * Returns: none.
+ */
+
+static void
+GetValuesHook(w, args, num_args)
+ Widget w;
+ ArgList args;
+ Cardinal* num_args;
+{
+ MultiSrcObject src = (MultiSrcObject) w;
+ int i;
+
+ if (src->multi_src.type == XawAsciiString) {
+ for (i = 0; i < *num_args ; i++ )
+ if (streq(args[i].name, XtNstring)) {
+ if (src->multi_src.use_string_in_place) {
+ *((char **) args[i].value) = (char *)
+ src->multi_src.first_piece->text;
+ }
+ else {
+ if (_XawMultiSave(w)) /* If save sucessful. */
+ *((char **) args[i].value) = src->multi_src.string;
+ }
+ break;
+ }
+ }
+}
+
+/* Function Name: Destroy
+ * Description: Destroys an multi source (frees all data)
+ * Arguments: src - the Multi source Widget to free.
+ * Returns: none.
+ */
+
+static void
+Destroy (w)
+ Widget w;
+{
+ RemoveOldStringOrFile((MultiSrcObject) w, True);
+}
+
+/************************************************************
+ *
+ * Public routines
+ *
+ ************************************************************/
+
+/* Function Name: XawMultiSourceFreeString
+ * Description: Frees the string returned by a get values call
+ * on the string when the source is of type string.
+ * Arguments: w - the MultiSrc widget.
+ * Returns: none.
+ *
+ * The public interface is XawAsciiSourceFreeString!
+ */
+
+void
+#if NeedFunctionPrototypes
+_XawMultiSourceFreeString(
+ Widget w)
+#else
+_XawMultiSourceFreeString(w)
+ Widget w;
+#endif
+{
+ MultiSrcObject src = (MultiSrcObject) w;
+
+/*if (src->multi_src.allocated_string&& src->multi_src.type != XawAsciiFile) {*/
+ /* ASSERT: src->multi_src.allocated_string -> we MUST free .string! */
+ if ( src->multi_src.allocated_string ) {
+ XtFree(src->multi_src.string);
+ src->multi_src.allocated_string = FALSE;
+ src->multi_src.string = NULL;
+ }
+}
+
+/* Function Name: _XawMultiSave
+ * Description: Saves all the pieces into a file or string as required.
+ * Arguments: w - the multiSrc Widget.
+ * Returns: TRUE if the save was successful.
+ *
+ * The public interface is XawAsciiSave(w)!
+ */
+
+Boolean
+#if NeedFunctionPrototypes
+_XawMultiSave(
+ Widget w)
+#else
+_XawMultiSave(w)
+ Widget w;
+#endif
+{
+ MultiSrcObject src = (MultiSrcObject) w;
+ XtAppContext app_con = XtWidgetToApplicationContext(w);
+ char * mb_string;
+
+/*
+ * If using the string in place then there is no need to play games
+ * to get the internal info into a readable string.
+ */
+
+ if (src->multi_src.use_string_in_place)
+ return(TRUE);
+
+ if (src->multi_src.type == XawAsciiFile) {
+
+ if (!src->multi_src.changes) /* No changes to save. */
+ return(TRUE);
+
+ mb_string = StorePiecesInString( src );
+
+ if ( mb_string != 0 ) {
+ if ( WriteToFile( mb_string, src->multi_src.string ) == FALSE ) {
+ XtFree( mb_string );
+ return( FALSE );
+ }
+ XtFree( mb_string );
+ src->multi_src.changes = FALSE;
+ return( TRUE );
+ } else {
+ /* If the buffer holds bad chars, don't touch it... */
+ XtAppWarningMsg( app_con,
+ "convertError", "multiSource", "XawError",
+ "Due to illegal characters, file not saved.", NULL, NULL);
+ return( FALSE );
+ }
+ }
+ else {
+
+ /* THIS FUNCTIONALITY IS UNDOCUMENTED, probably UNNEEDED? The manual
+ says this routine's only function is to save files to disk. -Sheeran */
+
+ mb_string = StorePiecesInString( src );
+
+ if ( mb_string == 0 ) {
+ /* If the buffer holds bad chars, don't touch it... */
+ XtAppWarningMsg( app_con,
+ "convertError", "multiSource", "XawError",
+ XtName( XtParent( (Widget) src ) ), NULL, NULL);
+ return( FALSE );
+ }
+
+ /* assert: mb_string holds good characters so the buffer is fine */
+ if (src->multi_src.allocated_string == TRUE)
+ XtFree(src->multi_src.string);
+ else
+ src->multi_src.allocated_string = TRUE;
+
+ src->multi_src.string = mb_string;
+ }
+ src->multi_src.changes = FALSE;
+ return(TRUE);
+}
+
+/* Function Name: XawMultiSaveAsFile
+ * Description: Save the current buffer as a file.
+ * Arguments: w - the MultiSrc widget.
+ * name - name of the file to save this file into.
+ * Returns: True if the save was sucessful.
+ *
+ * The public interface is XawAsciiSaveAsFile!
+ */
+
+Boolean
+#if NeedFunctionPrototypes
+_XawMultiSaveAsFile(
+ Widget w,
+ _Xconst char* name)
+#else
+_XawMultiSaveAsFile(w, name)
+ Widget w;
+ String name;
+#endif
+{
+ MultiSrcObject src = (MultiSrcObject) w;
+ String mb_string;
+ Boolean ret;
+
+ mb_string = StorePiecesInString( src );
+
+ if ( mb_string != 0 ) {
+ ret = WriteToFile( mb_string, name );
+ XtFree( mb_string );
+ return( ret );
+ }
+
+ /* otherwise there was a conversion error. So print widget name too. */
+ XtAppWarningMsg( XtWidgetToApplicationContext(w),
+ "convertError", "multiSource", "XawError",
+ XtName( XtParent( (Widget) src ) ), NULL, NULL);
+ return( False );
+}
+
+/************************************************************
+ *
+ * Private Functions.
+ *
+ ************************************************************/
+
+static void
+RemoveOldStringOrFile(src, checkString)
+ MultiSrcObject src;
+ Boolean checkString;
+{
+ FreeAllPieces(src);
+
+ if (checkString && src->multi_src.allocated_string) {
+ XtFree(src->multi_src.string);
+ src->multi_src.allocated_string = False;
+ src->multi_src.string = NULL;
+ }
+}
+
+/* Function Name: WriteToFile
+ * Description: Write the string specified to the begining of the file
+ * specified.
+ * Arguments: string - string to write.
+ * name - the name of the file
+ * Returns: returns TRUE if sucessful, FALSE otherwise.
+ */
+
+static Boolean
+WriteToFile(string, name)
+ String string, name;
+{
+ int fd;
+
+ if ( ((fd = creat(name, 0666)) == -1 ) ||
+ (write(fd, string, sizeof(unsigned char) * strlen(string)) == -1) )
+ return(FALSE);
+
+ if ( close(fd) == -1 )
+ return(FALSE);
+
+ return(TRUE);
+}
+
+
+/* Function Name: StorePiecesInString
+ * Description: store the pieces in memory into a char string.
+ * Arguments: src - the multiSrc to gather data from
+ * Returns: char *mb_string. Caller must free.
+ * or 0: conversion error. Caller must panic!
+ */
+
+static String
+StorePiecesInString(src)
+ MultiSrcObject src;
+{
+ wchar_t* wc_string;
+ char *mb_string;
+ int char_count = src->multi_src.length;
+ XawTextPosition first;
+ MultiPiece * piece;
+
+ /* I believe the char_count + 1 and the NULL termination are unneeded! FS*/
+
+ wc_string = (wchar_t*) XtMalloc((unsigned)(char_count + 1) * sizeof(wchar_t));
+
+ for (first = 0, piece = src->multi_src.first_piece ; piece != NULL;
+ first += piece->used, piece = piece->next)
+ (void) wcsncpy( wc_string + first, piece->text, piece->used );
+
+ wc_string[ char_count ] = (wchar_t)0; /* NULL terminate this sucker. */
+
+
+ /* This will refill all pieces to capacity. */
+
+ if ( src->multi_src.data_compression ) {
+ FreeAllPieces( src );
+ LoadPieces( src, NULL, (char *)wc_string );
+ }
+
+ /* Lastly, convert it to a MB format and send it back. */
+
+ mb_string = _XawTextWCToMB( XtDisplayOfObject( (Widget)src ),
+ wc_string, &char_count );
+
+ /* NOTE THAT mb_string MAY BE ZERO IF THE CONVERSION FAILED. */
+ XtFree( (char*) wc_string );
+ return( mb_string );
+}
+
+
+/* Function Name: InitStringOrFile.
+ * Description: Initializes the string or file.
+ * Arguments: src - the MultiSource.
+ * Returns: none - May exit though.
+ */
+
+static FILE *
+InitStringOrFile(src, newString)
+ MultiSrcObject src;
+ Boolean newString;
+{
+ char * open_mode = NULL;
+ FILE * file;
+ char fileName[TMPSIZ];
+ Display *d = XtDisplayOfObject((Widget)src);
+
+ if (src->multi_src.type == XawAsciiString) {
+
+ if (src->multi_src.string == NULL)
+ src->multi_src.length = 0;
+
+ else if (! src->multi_src.use_string_in_place) {
+ int length;
+ String temp = XtNewString(src->multi_src.string);
+ if ( src->multi_src.allocated_string )
+ XtFree( src->multi_src.string );
+ src->multi_src.allocated_string = True;
+ src->multi_src.string = temp;
+
+ length = strlen(src->multi_src.string);
+
+ /* Wasteful, throwing away the WC string, but need side effect! */
+ (void) _XawTextMBToWC(d, src->multi_src.string, &length);
+ src->multi_src.length = (XawTextPosition) length;
+ } else {
+ src->multi_src.length = strlen(src->multi_src.string);
+ /* In case the length resource is incorrectly set */
+ if (src->multi_src.length > src->multi_src.multi_length)
+ src->multi_src.multi_length = src->multi_src.length;
+
+ if (src->multi_src.multi_length == MAGIC_VALUE)
+ src->multi_src.piece_size = src->multi_src.length;
+ else
+ src->multi_src.piece_size = src->multi_src.multi_length + 1;
+ }
+
+ /*((TextWidget)src->object.parent)->text.lastPos = src->multi_src.length;*/
+ return(NULL);
+ }
+
+/*
+ * type is XawAsciiFile.
+ */
+
+ src->multi_src.is_tempfile = FALSE;
+
+ switch (src->text_src.edit_mode) {
+ case XawtextRead:
+ if (src->multi_src.string == NULL)
+ XtErrorMsg("NoFile", "multiSourceCreate", "XawError",
+ "Creating a read only disk widget and no file specified.",
+ NULL, 0);
+ open_mode = "r";
+ break;
+ case XawtextAppend:
+ case XawtextEdit:
+ if (src->multi_src.string == NULL) {
+
+ if ( src->multi_src.allocated_string )
+ XtFree( src->multi_src.string );
+ src->multi_src.allocated_string = False;
+ src->multi_src.string = fileName;
+
+ (void) tmpnam(src->multi_src.string);
+ src->multi_src.is_tempfile = TRUE;
+ open_mode = "w";
+ } else
+ open_mode = "r+";
+ break;
+ default:
+ XtErrorMsg("badMode", "multiSourceCreate", "XawError",
+ "Bad editMode for multi source; must be Read, Append or Edit.",
+ NULL, NULL);
+ }
+
+ /* Allocate new memory for the temp filename, because it is held in
+ * a stack memory buffer. We must verify that all routines that set
+ * .string first check .allocated_string and free it - plumbing Sheeran.
+ */
+ if (newString || src->multi_src.is_tempfile) {
+ if ( src->multi_src.allocated_string )
+ src->multi_src.string = XtNewString(src->multi_src.string);
+ src->multi_src.allocated_string = TRUE;
+ }
+
+ if (!src->multi_src.is_tempfile) {
+ if ((file = fopen(src->multi_src.string, open_mode)) != 0) {
+ (void) fseek(file, (Off_t)0, 2);
+ src->multi_src.length = ftell (file);
+ return file;
+ } else {
+ String params[2];
+ Cardinal num_params = 2;
+
+ params[0] = src->multi_src.string;
+ params[1] = strerror(errno);
+ XtAppWarningMsg(XtWidgetToApplicationContext((Widget)src),
+ "openError", "multiSourceCreate", "XawWarning",
+ "Cannot open file %s; %s", params, &num_params);
+ }
+ }
+ src->multi_src.length = 0;
+ return((FILE *)NULL);
+#undef StrLen
+}
+
+/* LoadPieces: This routine takes either the MB contents of open file `file' or the
+MB contents of string or the MB contents of src->multi_src.string and places
+them in Pieces in WC format.
+
+CAUTION: You must have src->multi_src.length set to file length bytes
+when src->multi_src.type == XawAsciiFile. src->multi_src.length must be
+the length of the parameter string if string is non-NULL. */
+
+static void
+LoadPieces(src, file, string)
+ MultiSrcObject src;
+ FILE* file;
+ char* string;
+{
+ Display *d = XtDisplayOfObject((Widget)src);
+ wchar_t* local_str, *ptr;
+ MultiPiece* piece = NULL;
+ XawTextPosition left;
+ int bytes = sizeof(wchar_t);
+ char* temp_mb_holder = NULL;
+
+ /*
+ * This is tricky - the _XawTextMBtoWC converter uses its 3rd arg
+ * in as MB length, out as WC length. We want local_length to be
+ * WC count.
+ */
+ int local_length = src->multi_src.length;
+
+ if (string != NULL) {
+ /*
+ * ASSERT: IF our caller passed a non-null string, THEN
+ * src->multi_src.length is currently string's * byte count,
+ * AND string is in a MB format.
+ */
+ local_str = _XawTextMBToWC(d, (char *)string, &local_length);
+ src->multi_src.length = (XawTextPosition) local_length;
+ } else if (src->multi_src.type != XawAsciiFile) {
+ /*
+ * here, we are not changing the contents, just reloading,
+ * so don't change len...
+ */
+ local_length = src->multi_src.string ?
+ strlen( src->multi_src.string ) : 0;
+ local_str = _XawTextMBToWC( d, (char*)src->multi_src.string, &local_length );
+ } else {
+ if (src->multi_src.length != 0) {
+ temp_mb_holder =
+ XtMalloc((unsigned)(src->multi_src.length + 1) * sizeof(unsigned char));
+ fseek(file, (Off_t)0, 0);
+ src->multi_src.length = fread (temp_mb_holder,
+ (Size_t)sizeof(unsigned char),
+ (Size_t)src->multi_src.length, file);
+ if (src->multi_src.length <= 0)
+ XtAppErrorMsg( XtWidgetToApplicationContext ((Widget) src),
+ "readError", "multiSource", "XawError",
+ "fread returned error.", NULL, NULL);
+ local_length = src->multi_src.length;
+ local_str = _XawTextMBToWC(d, temp_mb_holder, &local_length);
+ src->multi_src.length = local_length;
+
+ if ( local_str == 0 ) {
+ String params[2];
+ Cardinal num_params;
+ static char err_text[] =
+ "<<< FILE CONTENTS NOT REPRESENTABLE IN THIS LOCALE >>>";
+
+ params[0] = XtName(XtParent((Widget)src));
+ params[1] = src->multi_src.string;
+ num_params = 2;
+
+ XtAppWarningMsg( XtWidgetToApplicationContext((Widget)src),
+ "readLocaleError", "multiSource", "XawError",
+ "%s: The file `%s' contains characters not representable in this locale.",
+ params, &num_params);
+ src->multi_src.length = sizeof err_text;
+ local_length = src->multi_src.length;
+ local_str = _XawTextMBToWC(d, err_text, &local_length);
+ src->multi_src.length = local_length;
+ }
+ } else { /*ASSERT that since following while loop looks at local_length
+ this isn't needed. Sheeran, Omron KK, 1993/07/15
+ temp_mb_holder[src->multi_src.length] = '\0';*/
+ local_str = (wchar_t*)temp_mb_holder;
+ }
+ }
+
+ if (src->multi_src.use_string_in_place) {
+ piece = AllocNewPiece(src, piece);
+ piece->used = Min(src->multi_src.length, src->multi_src.piece_size);
+ piece->text = (wchar_t*)src->multi_src.string;
+ return;
+ }
+
+ ptr = local_str;
+ left = local_length;
+
+ do {
+ piece = AllocNewPiece(src, piece);
+
+ piece->text = (wchar_t*)XtMalloc(src->multi_src.piece_size * bytes);
+ piece->used = Min(left, src->multi_src.piece_size);
+ if (piece->used != 0)
+ (void) wcsncpy(piece->text, ptr, piece->used);
+
+ left -= piece->used;
+ ptr += piece->used;
+ } while (left > 0);
+
+ if ( temp_mb_holder )
+ XtFree( (char*) temp_mb_holder );
+}
+
+
+/* Function Name: AllocNewPiece
+ * Description: Allocates a new piece of memory.
+ * Arguments: src - The MultiSrc Widget.
+ * prev - the piece just before this one, or NULL.
+ * Returns: the allocated piece.
+ */
+
+static MultiPiece *
+AllocNewPiece(src, prev)
+ MultiSrcObject src;
+ MultiPiece * prev;
+{
+ MultiPiece * piece = XtNew(MultiPiece);
+
+ if (prev == NULL) {
+ src->multi_src.first_piece = piece;
+ piece->next = NULL;
+ }
+ else {
+ if (prev->next != NULL)
+ (prev->next)->prev = piece;
+ piece->next = prev->next;
+ prev->next = piece;
+ }
+
+ piece->prev = prev;
+
+ return(piece);
+}
+
+/* Function Name: FreeAllPieces
+ * Description: Frees all the pieces
+ * Arguments: src - The MultiSrc Widget.
+ * Returns: none.
+ */
+
+static void
+FreeAllPieces(src)
+ MultiSrcObject src;
+{
+ MultiPiece * next, * first = src->multi_src.first_piece;
+
+ if (first->prev != NULL)
+ printf("Xaw MultiSrc Object: possible memory leak in FreeAllPieces().\n");
+
+ for ( ; first != NULL ; first = next ) {
+ next = first->next;
+ RemovePiece(src, first);
+ }
+}
+
+/* Function Name: RemovePiece
+ * Description: Removes a piece from the list.
+ * Arguments:
+ * piece - the piece to remove.
+ * Returns: none.
+ */
+
+static void
+RemovePiece(src, piece)
+ MultiSrcObject src;
+ MultiPiece* piece;
+{
+ if (piece->prev == NULL)
+ src->multi_src.first_piece = piece->next;
+ else
+ (piece->prev)->next = piece->next;
+
+ if (piece->next != NULL)
+ (piece->next)->prev = piece->prev;
+
+ if (!src->multi_src.use_string_in_place)
+ XtFree((char *)piece->text);
+
+ XtFree((char *)piece);
+}
+
+/* Function Name: FindPiece
+ * Description: Finds the piece containing the position indicated.
+ * Arguments: src - The MultiSrc Widget.
+ * position - the position that we are searching for.
+ * RETURNED first - the position of the first character in this piece.
+ * Returns: piece - the piece that contains this position.
+ */
+
+static MultiPiece *
+FindPiece(src, position, first)
+ MultiSrcObject src;
+ XawTextPosition position, *first;
+{
+ MultiPiece * old_piece = NULL, * piece = src->multi_src.first_piece;
+ XawTextPosition temp;
+
+ for ( temp = 0 ; piece != NULL ; temp += piece->used, piece = piece->next ) {
+ *first = temp;
+ old_piece = piece;
+
+ if ((temp + piece->used) > position)
+ return(piece);
+ }
+ return(old_piece); /* if we run off the end the return the last piece */
+}
+
+/* Function Name: BreakPiece
+ * Description: Breaks a full piece into two new pieces.
+ * Arguments: src - The MultiSrc Widget.
+ * piece - the piece to break.
+ * Returns: none.
+ */
+
+#define HALF_PIECE (src->multi_src.piece_size/2)
+
+static void
+BreakPiece(src, piece)
+ MultiSrcObject src;
+ MultiPiece* piece;
+{
+ MultiPiece * new = AllocNewPiece(src, piece);
+
+ new->text = (wchar_t*)XtMalloc(src->multi_src.piece_size * sizeof(wchar_t));
+ (void) wcsncpy(new->text, piece->text + HALF_PIECE,
+ src->multi_src.piece_size - HALF_PIECE);
+ piece->used = HALF_PIECE;
+ new->used = src->multi_src.piece_size - HALF_PIECE;
+}
+
+/* Convert string "XawAsciiString" and "XawAsciiFile" to quarks. */
+
+/* ARGSUSED */
+static void
+CvtStringToMultiType(args, num_args, fromVal, toVal)
+ XrmValuePtr args; /* unused */
+ Cardinal* num_args; /* unused */
+ XrmValuePtr fromVal;
+ XrmValuePtr toVal;
+{
+ static XawAsciiType type;
+ static XrmQuark XtQEstring = NULLQUARK;
+ static XrmQuark XtQEfile;
+ XrmQuark q;
+ char lowerName[40];
+
+ if (XtQEstring == NULLQUARK) {
+ XtQEstring = XrmPermStringToQuark(XtEstring);
+ XtQEfile = XrmPermStringToQuark(XtEfile);
+ }
+
+ if (strlen ((char*) fromVal->addr) < sizeof lowerName) {
+ XmuCopyISOLatin1Lowered(lowerName, (char *) fromVal->addr);
+ q = XrmStringToQuark(lowerName);
+
+ if (q == XtQEstring) type = XawAsciiString;
+ else if (q == XtQEfile) type = XawAsciiFile;
+ else {
+ toVal->size = 0;
+ toVal->addr = NULL;
+ return;
+ }
+ toVal->size = sizeof type;
+ toVal->addr = (XPointer) &type;
+ return;
+ }
+ toVal->size = 0;
+ toVal->addr = NULL;
+}
diff --git a/src/MultiSrc.h b/src/MultiSrc.h
new file mode 100644
index 0000000..be01857
--- /dev/null
+++ b/src/MultiSrc.h
@@ -0,0 +1,151 @@
+/* $XConsortium: MultiSrc.h,v 1.2 94/04/17 20:12:26 kaleb Exp $ */
+
+/*
+ * Copyright 1991 by OMRON Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, 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 OMRON not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OMRON makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OMRON 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
+ * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Li Yuhong OMRON Corporation
+ */
+
+/*
+
+Copyright (c) 1989, 1991, 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.
+
+*/
+
+/*
+ * This file was modified from AsciiSrc.h.
+ *
+ * By Li Yuhong, Sept. 18, 1990
+ */
+
+#ifndef _XawMultiSrc_h
+#define _XawMultiSrc_h
+
+#include <X11/Xaw3d/TextSrc.h>
+/*Xfuncproto.h included by Intrinsic.h*/
+
+/* Resources:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ callback Callback Callback (none)
+ dataCompression DataCompression Boolean True
+ length Length int (internal)
+ pieceSize PieceSize int BUFSIZ
+ string String String NULL
+ type Type XawAsciiType XawAsciiString
+ useStringInPlace UseStringInPlace Boolean False
+
+*/
+
+/* Class record constants */
+
+extern WidgetClass multiSrcObjectClass;
+
+typedef struct _MultiSrcClassRec *MultiSrcObjectClass;
+typedef struct _MultiSrcRec *MultiSrcObject;
+
+/*
+ * Just to make people's lives a bit easier.
+ */
+
+#define MultiSourceObjectClass MultiSrcObjectClass
+#define MultiSourceObject MultiSrcObject
+
+/*
+ * Resource Definitions.
+ */
+
+#define XtCDataCompression "DataCompression"
+#define XtCPieceSize "PieceSize"
+#define XtCType "Type"
+#define XtCUseStringInPlace "UseStringInPlace"
+
+#define XtNdataCompression "dataCompression"
+#define XtNpieceSize "pieceSize"
+#define XtNtype "type"
+#define XtNuseStringInPlace "useStringInPlace"
+
+#define XtRMultiType "MultiType"
+
+#define XtEstring "string"
+#define XtEfile "file"
+
+/************************************************************
+ *
+ * THESE ROUTINES ARE NOT PUBLIC: Source should call
+ *
+ * the AsciiSrc API which currently forwards requests here.
+ *
+ * future versions (like theres going to be an R7 Xaw!) may
+ *
+ * eliminate this file or at least these functions entirely.
+ *
+ ************************************************************/
+
+_XFUNCPROTOBEGIN
+
+
+extern void XawMultiSourceFreeString(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+extern Boolean _XawMultiSave(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+extern Boolean _XawMultiSaveAsFile(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ _Xconst char* /* name */
+#endif
+);
+
+
+_XFUNCPROTOEND
+
+#endif /* _XawMultiSrc_h - Don't add anything after this line. */
+
diff --git a/src/MultiSrcP.h b/src/MultiSrcP.h
new file mode 100644
index 0000000..6996361
--- /dev/null
+++ b/src/MultiSrcP.h
@@ -0,0 +1,194 @@
+/* $XConsortium: MultiSrcP.h,v 1.2 94/04/17 20:12:27 kaleb Exp $ */
+
+/*
+ * Copyright 1991 by OMRON Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, 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 OMRON not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OMRON make no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * OMRON DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OMRON 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
+ * TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Li Yuhong OMRON Corporation
+ */
+
+
+/***********************************************************
+
+Copyright (c) 1987, 1988, 1991, 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.
+
+******************************************************************/
+
+/*
+ * MultiSrcP.h - Private Header for Multi Text Source.
+ *
+ * This is the private header file for the Multi Text Source.
+ * It is intended to be used with the Text widget, the simplest way to use
+ * this text source is to use the MultiText Object.
+ *
+ * Date: June 29, 1989
+ *
+ * By: Chris D. Peterson
+ * MIT X Consortium
+ * kit@expo.lcs.mit.edu
+ */
+
+/*
+ * TextSrcP.h - Private definitions for MultiSrc object
+ *
+ */
+
+/*
+ * This file was changed from AsciiSrcP.h.
+ *
+ * By Li Yuhong, Sept. 18, 1990
+ */
+
+#ifndef _XawMultiSrcP_h
+#define _XawMultiSrcP_h
+
+#include <X11/Xaw3d/TextSrcP.h>
+#include <X11/Xaw3d/MultiSrc.h>
+
+/************************************************************
+ *
+ * Private declarations.
+ *
+ ************************************************************/
+
+#ifdef L_tmpnam
+#define TMPSIZ L_tmpnam
+#else
+#define TMPSIZ 32 /* bytes to allocate for tmpnam */
+#endif
+
+#define MAGIC_VALUE ((XawTextPosition) -1) /* Magic value. */
+
+#define streq(a, b) ( strcmp((a), (b)) == 0 )
+
+typedef struct _MultiPiece { /* Piece of the text file of BUFSIZ allocated
+ characters. */
+ wchar_t* text; /* The text in this buffer. */
+ XawTextPosition used; /* The number of characters of this buffer
+ that have been used. */
+ struct _MultiPiece *prev, *next; /* linked list pointers. */
+} MultiPiece;
+
+/************************************************************
+ *
+ * New fields for the MultiSrc object class record.
+ *
+ ************************************************************/
+
+typedef struct _MultiSrcClassPart { char foo; } MultiSrcClassPart;
+
+/* Full class record declaration */
+typedef struct _MultiSrcClassRec {
+ ObjectClassPart object_class;
+ TextSrcClassPart text_src_class;
+ MultiSrcClassPart multi_src_class;
+} MultiSrcClassRec;
+
+extern MultiSrcClassRec multiSrcClassRec;
+
+/* New fields for the MultiSrc object record */
+
+typedef struct _MultiSrcPart {
+
+ /* Resources. */
+
+ XIC ic; /* for X Input Method. */
+ XtPointer string; /* either the string, or the file name, depend-
+ ing upon the `type'. ALWAYS IN MB FORMAT. */
+ XawAsciiType type; /* either string or disk. */
+ XawTextPosition piece_size; /* Size of text buffer for each piece. */
+ Boolean data_compression; /* compress to minimum memory automatically
+ on save? */
+ XtCallbackList callback; /* A callback list to call when the source is
+ changed. */
+ Boolean use_string_in_place; /* Use the string passed in place. */
+ int multi_length; /* length field for multi string emulation. */
+
+/* Private data. */
+
+ Boolean is_tempfile; /* Is this a temporary file? */
+ Boolean changes; /* Has this file been edited? */
+ Boolean allocated_string; /* Have I allocated the
+ string in multi_src->string? */
+ XawTextPosition length; /* length of file - IN CHARACTERS, NOT BYTES. */
+ MultiPiece * first_piece; /* first piece of the text. */
+} MultiSrcPart;
+
+/****************************************************************
+ *
+ * Full instance record declaration
+ *
+ ****************************************************************/
+
+typedef struct _MultiSrcRec {
+ ObjectPart object;
+ TextSrcPart text_src;
+ MultiSrcPart multi_src;
+} MultiSrcRec;
+
+#if NeedFunctionPrototypes
+extern void _XawMultiSourceFreeString( Widget );
+#else
+extern void _XawMultiSourceFreeString();
+#endif
+
+#endif /* _XawMultiSrcP_h --- Don't add anything after this line. */
diff --git a/src/Paned.c b/src/Paned.c
new file mode 100644
index 0000000..babd492
--- /dev/null
+++ b/src/Paned.c
@@ -0,0 +1,1947 @@
+/* $XConsortium: Paned.c,v 1.27 94/04/17 20:12:28 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.
+
+******************************************************************/
+
+/*
+ * Paned.c - Paned Composite Widget.
+ *
+ * Updated and significantly modified from the Athena VPaned Widget.
+ *
+ * Date: March 1, 1989
+ *
+ * By: Chris D. Peterson
+ * MIT X Consortium
+ * kit@expo.lcs.mit.edu
+ */
+
+#include "Xaw3dP.h"
+#include <X11/IntrinsicP.h>
+#include <X11/cursorfont.h>
+#include <X11/StringDefs.h>
+#include <X11/Xmu/Misc.h>
+#include <X11/Xmu/Converters.h>
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/Grip.h>
+#include <X11/Xaw3d/PanedP.h>
+#include <ctype.h>
+
+/* I don't know why Paned.c calls _XawImCallVendorShellExtResize, but... */
+#ifdef XAW_INTERNATIONALIZATION
+#include <X11/Xaw3d/XawImP.h>
+#endif
+
+typedef enum {UpLeftPane = 'U', LowRightPane = 'L',
+ ThisBorderOnly = 'T', AnyPane = 'A' } Direction;
+
+#define NO_INDEX -100
+#define IS_GRIP NULL
+
+#define PaneInfo(w) ((Pane)(w)->core.constraints)
+#define HasGrip(w) (PaneInfo(w)->grip != NULL)
+#define IsPane(w) ((w)->core.widget_class != gripWidgetClass)
+#define PaneIndex(w) (PaneInfo(w)->position)
+#define IsVert(w) ( (w)->paned.orientation == XtorientVertical )
+
+#define ForAllPanes(pw, childP) \
+ for ( (childP) = (pw)->composite.children ; \
+ (childP) < (pw)->composite.children + (pw)->paned.num_panes ; \
+ (childP)++ )
+
+#define ForAllChildren(pw, childP) \
+ for ( (childP) = (pw)->composite.children ; \
+ (childP) < (pw)->composite.children + (pw)->composite.num_children ; \
+ (childP)++ )
+
+/*****************************************************************************
+ *
+ * Full instance record declaration
+ *
+ ****************************************************************************/
+
+static char defGripTranslations[] =
+ "<Btn1Down>: GripAction(Start, UpLeftPane) \n\
+ <Btn2Down>: GripAction(Start, ThisBorderOnly) \n\
+ <Btn3Down>: GripAction(Start, LowRightPane) \n\
+ <Btn1Motion>: GripAction(Move, UpLeft) \n\
+ <Btn2Motion>: GripAction(Move, ThisBorder) \n\
+ <Btn3Motion>: GripAction(Move, LowRight) \n\
+ Any<BtnUp>: GripAction(Commit)";
+
+#define offset(field) XtOffsetOf(PanedRec, paned.field)
+
+static XtResource resources[] = {
+ {XtNinternalBorderColor, XtCBorderColor, XtRPixel, sizeof(Pixel),
+ offset(internal_bp), XtRString,
+ (XtPointer) XtDefaultForeground},
+ {XtNinternalBorderWidth, XtCBorderWidth, XtRDimension, sizeof(Dimension),
+ offset(internal_bw), XtRImmediate, (XtPointer) 1},
+ {XtNgripIndent, XtCGripIndent, XtRPosition, sizeof(Position),
+ offset(grip_indent), XtRImmediate, (XtPointer) 10},
+ {XtNrefigureMode, XtCBoolean, XtRBoolean, sizeof(Boolean),
+ offset(refiguremode), XtRImmediate, (XtPointer) TRUE},
+ {XtNgripTranslations, XtCTranslations, XtRTranslationTable,
+ sizeof(XtTranslations),
+ offset(grip_translations), XtRString, (XtPointer)defGripTranslations},
+ {XtNorientation, XtCOrientation, XtROrientation, sizeof(XtOrientation),
+ offset(orientation), XtRImmediate, (XtPointer) XtorientVertical},
+
+ /* Cursors - both horiz and vertical have to work. */
+
+ {XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor),
+ offset(cursor), XtRImmediate, None},
+ {XtNgripCursor, XtCCursor, XtRCursor, sizeof(Cursor),
+ offset(grip_cursor), XtRImmediate, None},
+ {XtNverticalGripCursor, XtCCursor, XtRCursor, sizeof(Cursor),
+ offset(v_grip_cursor), XtRString, "sb_v_double_arrow"},
+ {XtNhorizontalGripCursor, XtCCursor, XtRCursor, sizeof(Cursor),
+ offset(h_grip_cursor), XtRString, "sb_h_double_arrow"},
+
+ {XtNbetweenCursor, XtCCursor, XtRCursor, sizeof(Cursor),
+ offset(adjust_this_cursor), XtRString, None},
+ {XtNverticalBetweenCursor, XtCCursor, XtRCursor, sizeof(Cursor),
+ offset(v_adjust_this_cursor), XtRString, "sb_left_arrow"},
+ {XtNhorizontalBetweenCursor, XtCCursor, XtRCursor, sizeof(Cursor),
+ offset(h_adjust_this_cursor), XtRString, "sb_up_arrow"},
+
+ {XtNupperCursor, XtCCursor, XtRCursor, sizeof(Cursor),
+ offset(adjust_upper_cursor), XtRString, "sb_up_arrow"},
+ {XtNlowerCursor, XtCCursor, XtRCursor, sizeof(Cursor),
+ offset(adjust_lower_cursor), XtRString, "sb_down_arrow"},
+ {XtNleftCursor, XtCCursor, XtRCursor, sizeof(Cursor),
+ offset(adjust_left_cursor), XtRString, "sb_left_arrow"},
+ {XtNrightCursor, XtCCursor, XtRCursor, sizeof(Cursor),
+ offset(adjust_right_cursor), XtRString, "sb_right_arrow"},
+};
+
+#undef offset
+
+#define offset(field) XtOffsetOf(PanedConstraintsRec, paned.field)
+
+static XtResource subresources[] = {
+ {XtNallowResize, XtCBoolean, XtRBoolean, sizeof(Boolean),
+ offset(allow_resize), XtRImmediate, (XtPointer) FALSE},
+ {XtNposition, XtCPosition, XtRInt, sizeof(int),
+ offset(position), XtRImmediate, (XtPointer) 0},
+ {XtNmin, XtCMin, XtRDimension, sizeof(Dimension),
+ offset(min), XtRImmediate, (XtPointer) PANED_GRIP_SIZE},
+ {XtNmax, XtCMax, XtRDimension, sizeof(Dimension),
+ offset(max), XtRImmediate, (XtPointer) ~0},
+ {XtNpreferredPaneSize, XtCPreferredPaneSize, XtRDimension,
+ sizeof(Dimension), offset(preferred_size),
+ XtRImmediate, (XtPointer) PANED_ASK_CHILD},
+ {XtNresizeToPreferred, XtCBoolean, XtRBoolean, sizeof(Boolean),
+ offset(resize_to_pref), XtRImmediate, (XtPointer) FALSE},
+ {XtNskipAdjust, XtCBoolean, XtRBoolean, sizeof(Boolean),
+ offset(skip_adjust), XtRImmediate, (XtPointer) FALSE},
+ {XtNshowGrip, XtCShowGrip, XtRBoolean, sizeof(Boolean),
+ offset(show_grip), XtRImmediate, (XtPointer) TRUE},
+};
+
+#undef offset
+
+static void ClassInitialize(), Initialize();
+static void Realize(), Resize();
+static void Redisplay();
+static void GetGCs(), ReleaseGCs();
+static void RefigureLocationsAndCommit();
+static Boolean SetValues();
+static XtGeometryResult GeometryManager();
+static void ChangeManaged();
+static void InsertChild();
+static void DeleteChild();
+static Boolean PaneSetValues();
+static Dimension PaneSize(), GetRequestInfo();
+static Boolean SatisfiesRule1(), SatisfiesRule2(), SatisfiesRule3();
+
+static void PushPaneStack();
+static void GetPaneStack();
+static Boolean PopPaneStack();
+static void ClearPaneStack();
+
+#define SuperClass ((ConstraintWidgetClass)&constraintClassRec)
+
+PanedClassRec panedClassRec = {
+ {
+/* core class fields */
+ /* superclass */ (WidgetClass) SuperClass,
+ /* class name */ "Paned",
+ /* size */ sizeof(PanedRec),
+ /* class_initialize */ ClassInitialize,
+ /* class_part init */ NULL,
+ /* class_inited */ FALSE,
+ /* initialize */ Initialize,
+ /* initialize_hook */ NULL,
+ /* realize */ Realize,
+ /* actions */ NULL,
+ /* num_actions */ 0,
+ /* resources */ resources,
+ /* resource_count */ XtNumber(resources),
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ TRUE,
+ /* compress_exposure */ TRUE,
+ /* compress_enterleave*/ TRUE,
+ /* visible_interest */ FALSE,
+ /* destroy */ ReleaseGCs,
+ /* 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 */ XtInheritQueryGeometry,
+ /* display_accelerator*/ XtInheritDisplayAccelerator,
+ /* extension */ NULL
+ }, {
+/* composite class fields */
+ /* geometry_manager */ GeometryManager,
+ /* change_managed */ ChangeManaged,
+ /* insert_child */ InsertChild,
+ /* delete_child */ DeleteChild,
+ /* extension */ NULL
+ }, {
+/* constraint class fields */
+ /* subresources */ subresources,
+ /* subresource_count */ XtNumber(subresources),
+ /* constraint_size */ sizeof(PanedConstraintsRec),
+ /* initialize */ NULL,
+ /* destroy */ NULL,
+ /* set_values */ PaneSetValues,
+ /* extension */ NULL
+ }
+};
+
+WidgetClass panedWidgetClass = (WidgetClass) &panedClassRec;
+
+/* For compatibility. */
+WidgetClass vPanedWidgetClass = (WidgetClass) &panedClassRec;
+
+/***********************************************************
+ *
+ * Private Functions.
+ *
+ ************************************************************/
+
+/* Function Name: AdjustPanedSize
+ * Description: Adjusts the size of the pane.
+ * Arguments: pw - the paned widget to adjust.
+ * off_size - the new off_size to use.
+ * result_ret - result of query ** RETURNED **
+ * on_size_ret - the new on_size ** RETURNED **
+ * off_size_ret - the new off_size ** RETURNED **
+ * Returns: the amount of change in size.
+ */
+
+static void
+AdjustPanedSize(pw, off_size, result_ret, on_size_ret, off_size_ret)
+PanedWidget pw;
+Dimension off_size;
+XtGeometryResult * result_ret;
+Dimension * on_size_ret, * off_size_ret;
+{
+ Dimension old_size = PaneSize( (Widget) pw, IsVert(pw));
+ Dimension newsize = 0;
+ Widget * childP;
+ XtWidgetGeometry request, reply;
+ request.request_mode = CWWidth | CWHeight;
+
+ ForAllPanes(pw, childP) {
+ int size = Max(PaneInfo(*childP)->size, (int)PaneInfo(*childP)->min);
+ AssignMin(size, (int) PaneInfo(*childP)->max);
+ newsize += size + pw->paned.internal_bw;
+ }
+ newsize -= pw->paned.internal_bw;
+
+ if (newsize < 1) newsize = 1;
+
+ if ( IsVert(pw) ) {
+ request.width = off_size;
+ request.height = newsize;
+ }
+ else {
+ request.width = newsize;
+ request.height = off_size;
+ }
+
+ if (result_ret != NULL) {
+ request.request_mode |= XtCWQueryOnly;
+
+ *result_ret = XtMakeGeometryRequest( (Widget) pw, &request, &reply );
+#ifdef XAW_INTERNATIONALIZATION
+ _XawImCallVendorShellExtResize( (Widget) pw );
+#endif
+
+ if ( (newsize == old_size) || (*result_ret == XtGeometryNo) ) {
+ *on_size_ret = old_size;
+ *off_size_ret = off_size;
+ return;
+ }
+ if (*result_ret != XtGeometryAlmost) {
+ *on_size_ret = GetRequestInfo( &request, IsVert(pw) );
+ *off_size_ret = GetRequestInfo( &request, !IsVert(pw) );
+ return;
+ }
+ *on_size_ret = GetRequestInfo( &reply, IsVert(pw) );
+ *off_size_ret = GetRequestInfo( &reply, !IsVert(pw) );
+ return;
+ }
+
+ if (newsize == old_size) return;
+
+ if (XtMakeGeometryRequest( (Widget) pw,
+ &request, &reply) == XtGeometryAlmost)
+ XtMakeGeometryRequest( (Widget) pw, &reply, &request);
+}
+
+/* Function Name: PaneSize
+ * Description: returns the width or height of the pane depending
+ * upon the orientation we are using.
+ * Arguments: w - and widget.
+ * vertical - TRUE if this is vertically oriented pane.
+ * Returns: the size requested
+ *
+ * vertical - return height
+ * !vertical - return width
+ */
+
+static Dimension
+PaneSize(w, vertical)
+Widget w;
+Boolean vertical;
+{
+ if (vertical) return (w->core.height);
+ return (w->core.width);
+}
+
+/* Function Name: GetRequestInfo
+ * Description: returns request information.
+ * Arguments: geo_struct - a geometry struct to get information out of.
+ * vert - TRUE if this is a vertical paned widget.
+ * Returns: the request information.
+ */
+
+static Dimension
+GetRequestInfo(geo_struct, vert)
+XtWidgetGeometry * geo_struct;
+Boolean vert;
+{
+ if ( vert ) return ( (Dimension) geo_struct->height);
+ return ( (Dimension) geo_struct->width);
+}
+
+/* Function Name: ChoosePaneToResize.
+ * Description: This function chooses a pane to resize.
+ * They are chosen using the following rules:
+ *
+ * 1) size < max && size > min
+ * 2) skip adjust == FALSE
+ * 3) widget not its prefered height &&
+ * this change will bring it closer &&
+ * The user has not resized this pane.
+ *
+ * If no widgets are found that fits all the rules then
+ * rule #3 is broken.
+ * If there are still no widgets found than
+ * rule #2 is broken.
+ * Rule #1 is never broken.
+ * If no widgets are found then NULL is returned.
+ *
+ * Arguments: pw - the paned widget.
+ * paneindex - the index of the current pane.
+ * dir - direction to search first.
+ * shrink - TRUE if we need to shrink a pane, FALSE otherwise.
+ * Returns: pane to resize or NULL.
+ */
+
+static Pane
+ChoosePaneToResize(pw, paneindex, dir, shrink)
+PanedWidget pw;
+int paneindex;
+Direction dir;
+Boolean shrink;
+{
+ Widget *childP;
+ int rules = 3;
+ Direction _dir = dir;
+ int _index = paneindex;
+
+ if ( (paneindex == NO_INDEX) || (dir == AnyPane) ) { /* Use defaults. */
+ _dir = LowRightPane; /* Go up. - really. */
+ _index = pw->paned.num_panes - 1; /* Start the last pane, and work
+ backwards. */
+ }
+ childP = pw->composite.children + _index;
+
+ /* CONSTCOND */
+ while(TRUE) {
+ Pane pane = PaneInfo(*childP);
+
+ if ( (rules < 3 || SatisfiesRule3(pane, shrink)) &&
+ (rules < 2 || SatisfiesRule2(pane)) &&
+ (SatisfiesRule1(pane, shrink)) &&
+ ((paneindex != PaneIndex(*childP)) || (dir == AnyPane)) )
+ return(pane);
+
+/*
+ * This is counter-intuitive, but if we are resizing the pane
+ * above the grip we want to choose a pane below the grip to lose,
+ * and visa-versa.
+ */
+
+ if (_dir == LowRightPane) --childP; else ++childP;
+
+/*
+ * If we have come to and edge then reduce the rule set, and try again.
+ * If we are reduced the rules to none, then return NULL.
+ */
+
+ if ( (childP - pw->composite.children < 0) ||
+ (childP - pw->composite.children >= pw->paned.num_panes) ) {
+ if (--rules < 1) /* less strict rules. */
+ return(NULL);
+ childP = pw->composite.children + _index;
+ }
+ }
+}
+
+/* Function Name: StatisfiesRule1
+ * Description: check for to see if this pane satisfies rule 1.
+ * Arguments: pane - the pane to check.
+ * shrink -TRUE if we want to shrink this pane, FALSE otherwise
+ * Returns: TRUE if the rule is satisfied.
+ */
+
+static Boolean
+SatisfiesRule1(pane, shrink)
+Pane pane;
+Boolean shrink;
+{
+ return( (shrink && (pane->size != pane->min)) ||
+ (!shrink && (pane->size != pane->max)) );
+}
+
+/* Function Name: StatisfiesRule2
+ * Description: check for to see if this pane satisfies rule 2.
+ * Arguments: pane - the pane to check.
+ * Returns: TRUE if the rule is satisfied.
+ */
+
+static Boolean
+SatisfiesRule2(pane)
+Pane pane;
+{
+ return(!pane->skip_adjust || pane->paned_adjusted_me);
+}
+
+/* Function Name: StatisfiesRule3
+ * Description: check for to see if this pane satisfies rule 3.
+ * Arguments: pane - the pane to check.
+ * shrink -TRUE if we want to shrink this pane, FALSE otherwise
+ * Returns: TRUE if the rule is satisfied.
+ */
+
+static Boolean
+SatisfiesRule3(pane, shrink)
+Pane pane;
+Boolean shrink;
+{
+ return ( pane->paned_adjusted_me &&
+ ( (shrink && ((int)pane->wp_size <= pane->size)) ||
+ (!shrink && ((int)pane->wp_size >= pane->size))) );
+}
+
+/* Function Name: LoopAndRefigureChildren.
+ * Description: if we are resizing either the UpleftPane or LowRight Pane
+ * loop through all the children to see if any will allow us
+ * to resize them.
+ * Arguments: pw - the paned widget.
+ * paneindex - the number of the pane border we are moving.
+ * dir - the pane to move (either UpLeftPane or LowRightPane).
+ * sizeused - current amount of space used.
+ * THIS VALUE IS USED AND RETURNED.
+ * Returns: none.
+ */
+
+static void
+LoopAndRefigureChildren(pw, paneindex, dir, sizeused)
+PanedWidget pw;
+int paneindex, *sizeused;
+Direction dir;
+{
+ int pane_size = (int) PaneSize( (Widget) pw, IsVert(pw));
+ Boolean shrink = (*sizeused > pane_size);
+
+ if (dir == LowRightPane) paneindex++;
+
+ while (*sizeused != pane_size) { /* While all panes do not fit properly. */
+/*
+ * Choose a pane to resize.
+ * First look on the Pane Stack, and then go hunting for another one.
+ * If we fail to find a pane to resize then give up.
+ */
+ Pane pane;
+ int start_size;
+ Dimension old;
+ Boolean rule3_ok = FALSE, from_stack = TRUE;
+
+ GetPaneStack(pw, shrink, &pane, &start_size);
+ if (pane == NULL) {
+ pane = ChoosePaneToResize(pw, paneindex, dir, shrink);
+ if (pane == NULL)
+ return; /* no one to resize, give up. */
+
+ rule3_ok = SatisfiesRule3(pane, shrink);
+ from_stack = FALSE;
+ PushPaneStack(pw, pane);
+ }
+
+
+/*
+ * Try to resize this pane so that all panes will fit, take min and max
+ * into account.
+ */
+ old = pane->size;
+ pane->size += pane_size - *sizeused;
+
+ if (from_stack) {
+ if (shrink) {
+ AssignMax(pane->size, start_size);
+ } /* don't remove these braces. */
+ else
+ AssignMin(pane->size, start_size);
+
+ if (pane->size == start_size) (void) PopPaneStack(pw);
+ }
+ else if (rule3_ok) {
+ if (shrink) {
+ AssignMax(pane->size, (int) pane->wp_size);
+ } /* don't remove these braces. */
+ else
+ AssignMin(pane->size, (int) pane->wp_size);
+ }
+
+ pane->paned_adjusted_me = (pane->size != pane->wp_size);
+ AssignMax(pane->size, (int) pane->min);
+ AssignMin(pane->size, (int) pane->max);
+ *sizeused += (pane->size - old);
+ }
+}
+
+/* Function Name: RefigureLocations
+ * Description: refigures all locations of children.
+ * Arguments: pw - the paned widget.
+ * paneindex - child to start refiguring at.
+ * dir - direction to move from child.
+ * Returns: none.
+ *
+ * There are special arguments to paneindex and dir, they are:
+ * paneindex - NO_INDEX.
+ * dir - AnyPane.
+ *
+ * If either of these is true then all panes may be resized and
+ * the choosing of panes procedes in reverse order starting with the
+ * last child.
+ */
+
+static void
+RefigureLocations(pw, paneindex, dir)
+PanedWidget pw;
+int paneindex;
+Direction dir;
+{
+ Widget *childP;
+ int pane_size = (int) PaneSize( (Widget) pw, IsVert(pw) );
+ int sizeused = 0;
+ Position loc = 0;
+
+ if (pw->paned.num_panes == 0 || !pw->paned.refiguremode) return;
+
+/*
+ * Get an initial estimate of the size we will use.
+ */
+
+ ForAllPanes(pw, childP) {
+ Pane pane = PaneInfo(*childP);
+ AssignMax(pane->size, (int) pane->min);
+ AssignMin(pane->size, (int) pane->max);
+ sizeused += (int) pane->size + (int) pw->paned.internal_bw;
+ }
+ sizeused -= (int) pw->paned.internal_bw;
+
+ if ( (dir != ThisBorderOnly) && (sizeused != pane_size) )
+ LoopAndRefigureChildren(pw, paneindex, dir, &sizeused);
+
+/*
+ * If we still are not the right size, then tell the pane that
+ * wanted to resize that it can't.
+ */
+
+
+ if ( (paneindex != NO_INDEX) && (dir != AnyPane) ) {
+ Pane pane = PaneInfo(*(pw->composite.children + paneindex));
+ Dimension old = pane->size;
+
+ pane->size += pane_size - sizeused;
+ AssignMax(pane->size, (int) pane->min);
+ AssignMin(pane->size, (int) pane->max);
+ sizeused += pane->size - old;
+ }
+
+/*
+ * It is possible that the panes will not fit inside the vpaned widget, but
+ * we have tried out best.
+ *
+ * Assign each pane a location.
+ */
+
+ ForAllPanes(pw, childP) {
+ PaneInfo(*childP)->delta = loc;
+ loc += PaneInfo(*childP)->size + pw->paned.internal_bw;
+ }
+}
+
+/* Function Name: CommitNewLocations
+ * Description: Commits all of the previously figured locations.
+ * Arguments: pw - the paned widget.
+ * Returns: none.
+ */
+
+static void
+CommitNewLocations(pw)
+PanedWidget pw;
+{
+ Widget *childP;
+ XWindowChanges changes;
+
+ changes.stack_mode = Above;
+
+ ForAllPanes(pw, childP) {
+ Pane pane = PaneInfo(*childP);
+ Widget grip = pane->grip; /* may be NULL. */
+
+ if (IsVert(pw)) {
+ XtMoveWidget(*childP, (Position) 0, pane->delta);
+ XtResizeWidget(*childP, pw->core.width, (Dimension) pane->size,
+ (Dimension) 0);
+
+ if (HasGrip(*childP)) { /* Move and Display the Grip */
+ changes.x = pw->core.width - pw->paned.grip_indent -
+ grip->core.width - grip->core.border_width*2;
+ changes.y = (*childP)->core.y + (*childP)->core.height -
+ grip->core.height/2 - grip->core.border_width +
+ pw->paned.internal_bw/2;
+ }
+ }
+ else {
+ XtMoveWidget(*childP, pane->delta, (Position) 0);
+ XtResizeWidget(*childP, (Dimension) pane->size, pw->core.height,
+ (Dimension) 0);
+
+
+ if (HasGrip(*childP)) { /* Move and Display the Grip */
+ changes.x = (*childP)->core.x + (*childP)->core.width -
+ grip->core.width/2 - grip->core.border_width +
+ pw->paned.internal_bw/2;
+ changes.y = pw->core.height - pw->paned.grip_indent -
+ grip->core.height - grip->core.border_width*2;
+ }
+ }
+
+/*
+ * This should match XtMoveWidget, except that we're also insuring the
+ * grip is Raised in the same request.
+ */
+
+ if (HasGrip(*childP)) {
+ grip->core.x = changes.x;
+ grip->core.y = changes.y;
+
+ if (XtIsRealized(pane->grip))
+ XConfigureWindow( XtDisplay(pane->grip), XtWindow(pane->grip),
+ CWX | CWY | CWStackMode, &changes );
+ }
+ }
+ ClearPaneStack(pw);
+}
+
+/* Function Name: RefigureLocationsAndCommit
+ * Description: Refigures all locations in a paned widget and
+ * commits them immediately.
+ * Arguments: pw - the paned widget.
+ * Returns: none
+ *
+ * This function does nothing if any of the following are true.
+ * o refiguremode is false.
+ * o The widget is unrealized.
+ * o There are no panes is the paned widget.
+ *
+ * NOTE: This is the resize Procedure for the Paned widget.
+ */
+
+static void
+RefigureLocationsAndCommit(w)
+Widget w;
+{
+ PanedWidget pw = (PanedWidget) w;
+ if (pw->paned.refiguremode && XtIsRealized( (Widget) pw) &&
+ pw->paned.num_panes > 0 ) {
+ RefigureLocations(pw, NO_INDEX, AnyPane);
+ CommitNewLocations(pw);
+ }
+}
+
+/* Function Name: _DrawRect
+ * Description: Draws a rectangle in the proper orientation.
+ * Arguments: pw - the paned widget.
+ * gc - gc to used for the draw.
+ * on_olc, off_loc - location of upper left corner of rect.
+ * on_size, off_size - size of rectangle.
+ * Returns: none
+ */
+
+static void
+_DrawRect(pw, gc, on_loc, off_loc, on_size, off_size)
+PanedWidget pw;
+GC gc;
+int on_loc, off_loc;
+unsigned int on_size, off_size;
+{
+ if (IsVert(pw))
+ XFillRectangle(XtDisplay(pw), XtWindow(pw), gc,
+ off_loc, on_loc, off_size, on_size);
+ else
+ XFillRectangle(XtDisplay(pw), XtWindow(pw), gc,
+ on_loc, off_loc, on_size, off_size);
+}
+
+/* Function Name: _DrawInternalBorders
+ * Description: Draws the internal borders into the paned widget.
+ * Arguments: pw - the paned widget.
+ * gc - the GC to use to draw the borders.
+ * Returns: none.
+ */
+
+static void
+_DrawInternalBorders(pw, gc)
+PanedWidget pw;
+GC gc;
+{
+ Widget *childP;
+ int on_loc, off_loc;
+ unsigned int on_size, off_size;
+
+/*
+ * This is an optimization. Do not paint the internal borders if
+ * they are the same color as the background.
+ */
+
+ if (pw->core.background_pixel == pw->paned.internal_bp)
+ return;
+
+ off_loc = 0;
+ off_size = (unsigned int) PaneSize( (Widget) pw, !IsVert(pw) );
+ on_size = (unsigned int) pw->paned.internal_bw;
+
+ ForAllPanes(pw, childP) {
+ on_loc = IsVert(pw) ? (*childP)->core.y : (*childP)->core.x;
+ on_loc -= (int) on_size;
+
+ _DrawRect( pw, gc, on_loc, off_loc, on_size, off_size);
+ }
+}
+
+/*
+ * This allows good reuse of code, as well as descriptive function names.
+ */
+
+#define DrawInternalBorders(pw) _DrawInternalBorders((pw), (pw)->paned.normgc);
+#define EraseInternalBorders(pw) _DrawInternalBorders((pw), (pw)->paned.invgc);
+
+/* Function Name: _DrawTrackLines
+ * Description: Draws the lines that animate the pane borders when the
+ * grips are moved.
+ * Arguments: pw - the Paned widget.
+ * erase - if True then just erase track lines, else
+ * draw them in.
+ * Returns: none.
+ */
+
+static void
+_DrawTrackLines(pw, erase)
+PanedWidget pw;
+Boolean erase;
+{
+ Widget *childP;
+ Pane pane;
+ int on_loc, off_loc;
+ unsigned int on_size, off_size;
+
+ off_loc = 0;
+ off_size = PaneSize( (Widget) pw, !IsVert(pw));
+
+ ForAllPanes(pw, childP) {
+ pane = PaneInfo(*childP);
+ if ( erase || (pane->olddelta != pane->delta) ) {
+ on_size = pw->paned.internal_bw;
+ if (!erase) {
+ on_loc = PaneInfo(*childP)->olddelta - (int) on_size;
+
+ _DrawRect( pw, pw->paned.flipgc,
+ on_loc, off_loc, on_size, off_size);
+ }
+
+ on_loc = PaneInfo(*childP)->delta - (int) on_size;
+
+ _DrawRect(pw, pw->paned.flipgc,
+ on_loc, off_loc, on_size, off_size);
+
+ pane->olddelta = pane->delta;
+ }
+ }
+}
+
+/*
+ * This allows good reuse of code, as well as descriptive function names.
+ */
+
+#define DrawTrackLines(pw) _DrawTrackLines((pw), FALSE);
+#define EraseTrackLines(pw) _DrawTrackLines((pw), TRUE);
+
+/* Function Name: GetEventLocation
+ * Description: Converts and event to an x and y location.
+ * Arguments: pw - the paned widget.
+ * event - a pointer to an event.
+ * Returns: if this is a vertical pane then (y) else (x).
+ */
+
+static int
+GetEventLocation(pw, event)
+PanedWidget pw;
+XEvent *event;
+{
+ int x, y;
+
+ switch (event->xany.type) {
+ case ButtonPress:
+ case ButtonRelease:
+ x = event->xbutton.x_root;
+ y = event->xbutton.y_root;
+ break;
+ case KeyPress:
+ case KeyRelease:
+ x = event->xkey.x_root;
+ y = event->xkey.y_root;
+ break;
+ case MotionNotify:
+ x = event->xmotion.x_root;
+ y = event->xmotion.y_root;
+ break;
+ default:
+ x = pw->paned.start_loc;
+ y = pw->paned.start_loc;
+ }
+ if (IsVert(pw))
+ return(y);
+ return(x);
+}
+
+/* Function Name: StartGripAdjustment
+ * Description: Starts the grip adjustment procedure.
+ * Arguments: pw - the paned widget.
+ * grip - the grip widget selected.
+ * dir - the direction that we are to be moving.
+ * Returns: none.
+ */
+
+static void
+StartGripAdjustment(pw, grip, dir)
+PanedWidget pw;
+Widget grip;
+Direction dir;
+{
+ Widget *childP;
+ Cursor cursor;
+
+ pw->paned.whichadd = pw->paned.whichsub = (Widget) NULL;
+
+ if (dir == ThisBorderOnly || dir == UpLeftPane)
+ pw->paned.whichadd = pw->composite.children[PaneIndex(grip)];
+ if (dir == ThisBorderOnly || dir == LowRightPane)
+ pw->paned.whichsub = pw->composite.children[PaneIndex(grip) + 1];
+
+/*
+ * Change the cursor.
+ */
+
+ if (XtIsRealized(grip)) {
+ if ( IsVert(pw) ) {
+ if (dir == UpLeftPane)
+ cursor = pw->paned.adjust_upper_cursor;
+ else if (dir == LowRightPane)
+ cursor = pw->paned.adjust_lower_cursor;
+ else {
+ if ( pw->paned.adjust_this_cursor == None)
+ cursor = pw->paned.v_adjust_this_cursor;
+ else
+ cursor = pw->paned.adjust_this_cursor;
+ }
+ }
+ else {
+ if (dir == UpLeftPane)
+ cursor = pw->paned.adjust_left_cursor;
+ else if (dir == LowRightPane)
+ cursor = pw->paned.adjust_right_cursor;
+ else {
+ if (pw->paned.adjust_this_cursor == None)
+ cursor = pw->paned.h_adjust_this_cursor;
+ else
+ cursor = pw->paned.adjust_this_cursor;
+ }
+ }
+
+ XDefineCursor(XtDisplay(grip), XtWindow(grip), cursor);
+ }
+
+ EraseInternalBorders(pw);
+ ForAllPanes(pw, childP)
+ PaneInfo(*childP)->olddelta = -99;
+}
+
+/* Function Name: MoveGripAdjustment
+ * Description: This routine moves all panes around when a grip is moved.
+ * Arguments: pw - the paned widget.
+ * grip - the grip that we are moving.
+ * dir - the direction the pane we are interested is w.r.t the
+ * grip.
+ * loc - location of pointer in proper direction.
+ * Returns: none.
+ */
+
+static void
+MoveGripAdjustment(pw, grip, dir, loc)
+PanedWidget pw;
+Widget grip;
+Direction dir;
+int loc;
+{
+ int diff, add_size = 0, sub_size = 0;
+
+ diff = loc - pw->paned.start_loc;
+
+ if (pw->paned.whichadd)
+ add_size = PaneSize(pw->paned.whichadd, IsVert(pw) ) + diff;
+
+ if (pw->paned.whichsub)
+ sub_size = PaneSize(pw->paned.whichsub, IsVert(pw) ) - diff;
+
+/*
+ * If moving this border only then do not allow either of the borders
+ * to go beyond the min or max size allowed.
+ */
+
+ if ( (dir == ThisBorderOnly) ) {
+ int old_add_size = add_size, old_sub_size;
+
+ AssignMax(add_size, (int) PaneInfo(pw->paned.whichadd)->min);
+ AssignMin(add_size, (int) PaneInfo(pw->paned.whichadd)->max);
+ if (add_size != old_add_size)
+ sub_size += old_add_size - add_size;
+
+ old_sub_size = sub_size;
+ AssignMax(sub_size, (int) PaneInfo(pw->paned.whichsub)->min);
+ AssignMin(sub_size, (int) PaneInfo(pw->paned.whichsub)->max);
+ if (sub_size != old_sub_size) return; /* Abort to current sizes. */
+ }
+
+ if (add_size != 0)
+ PaneInfo(pw->paned.whichadd)->size = add_size;
+ if (sub_size != 0)
+ PaneInfo(pw->paned.whichsub)->size = sub_size;
+ RefigureLocations(pw, PaneIndex(grip), dir);
+ DrawTrackLines(pw);
+}
+
+/* Function Name: CommitGripAdjustment
+ * Description: Commits the grip adjustment.
+ * Arguments: pw - the paned widget.
+ * Returns: none
+ */
+
+static void
+CommitGripAdjustment(pw)
+PanedWidget pw;
+{
+ EraseTrackLines(pw);
+ CommitNewLocations(pw);
+ DrawInternalBorders(pw);
+
+/*
+ * Since the user selected this size then use it as the preferred size.
+ */
+
+ if (pw->paned.whichadd) {
+ Pane pane = PaneInfo(pw->paned.whichadd);
+ pane->wp_size = pane->size;
+ }
+ if (pw->paned.whichsub) {
+ Pane pane = PaneInfo(pw->paned.whichsub);
+ pane->wp_size = pane->size;
+ }
+}
+
+/* Function Name: HandleGrip
+ * Description: Handles the grip manipulations.
+ * Arguments: grip - the grip widget that has been moved.
+ * junk - ** NOT USED **
+ * call_data - data passed to us from the grip widget.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+HandleGrip(grip, junk, callData)
+Widget grip;
+XtPointer junk, callData;
+{
+ XawGripCallData call_data = (XawGripCallData)callData;
+ PanedWidget pw = (PanedWidget) XtParent(grip);
+ int loc;
+ char action_type;
+ Cursor cursor;
+ Direction direction = 0;
+ Arg arglist[1];
+
+ action_type = *call_data->params[0];
+
+ if (call_data->num_params == 0 ||
+ (action_type == 'C' && call_data->num_params != 1) ||
+ (action_type != 'C' && call_data->num_params != 2))
+ XtError( "Paned GripAction has been passed incorrect parameters." );
+
+ if (islower(action_type)) action_type = toupper(action_type);
+
+ loc = GetEventLocation(pw, (XEvent *) (call_data->event));
+
+ if (action_type != 'C') {
+ if ( isupper(*call_data->params[1]) )
+ direction = (Direction) *call_data->params[1];
+ else
+ direction = (Direction) toupper(*call_data->params[1]);
+ }
+
+ switch (action_type) {
+ case 'S': /* Start adjustment */
+ pw->paned.resize_children_to_pref = FALSE;
+ StartGripAdjustment(pw, grip, direction);
+ pw->paned.start_loc = loc;
+ break;
+
+ case 'M':
+ MoveGripAdjustment(pw, grip, direction, loc);
+ break;
+
+ case 'C':
+ XtSetArg(arglist[0], XtNcursor, &cursor);
+ XtGetValues(grip, arglist, (Cardinal) 1);
+ XDefineCursor(XtDisplay(grip), XtWindow(grip), cursor);
+ CommitGripAdjustment(pw);
+ break;
+
+ default:
+ XtError( "Paned GripAction(); 1st parameter invalid" );
+ }
+}
+
+/* Function Name: ResortChildren
+ * Description: Resorts the children so that all managed children
+ * are first.
+ * Arguments: pw - the paned widget.
+ * Returns: none.
+ */
+
+static void
+ResortChildren(pw)
+PanedWidget pw;
+{
+ Widget * unmanagedP, * childP;
+
+ unmanagedP = NULL;
+ ForAllChildren(pw, childP) {
+ if (!IsPane(*childP) || !XtIsManaged(*childP)) {
+ /*
+ * We only keep track of the first unmanaged pane.
+ */
+ if (unmanagedP == NULL)
+ unmanagedP = childP;
+ }
+ else { /* must be a managed pane */
+ /*
+ * If an earlier widget was not a managed pane, then swap
+ */
+ if (unmanagedP != NULL) {
+ Widget child = *unmanagedP;
+ *unmanagedP = *childP;
+ *childP = child;
+ childP = unmanagedP; /* easiest to just back-track */
+ unmanagedP = NULL; /* in case there is another managed */
+ }
+ }
+ }
+}
+
+/* Function Name: ManageAndUnmanageGrips
+ * Description: This function manages and unmanages the grips so that
+ * the managed state of each grip matches that of its pane.
+ * Arguments: pw - the paned widget.
+ * Returns: none.
+ */
+
+static void
+ManageAndUnmanageGrips(pw)
+PanedWidget pw;
+{
+ WidgetList managed_grips, unmanaged_grips;
+ Widget *managedP, *unmanagedP, *childP;
+ Cardinal alloc_size;
+
+ alloc_size = (Cardinal) sizeof(Widget) * pw->composite.num_children / 2;
+ managedP = managed_grips = (WidgetList) XtMalloc(alloc_size);
+ unmanagedP = unmanaged_grips = (WidgetList) XtMalloc(alloc_size);
+
+ ForAllChildren(pw, childP)
+ if (IsPane(*childP) && HasGrip(*childP))
+ if ( XtIsManaged(*childP) )
+ *managedP++ = PaneInfo(*childP)->grip;
+ else
+ *unmanagedP++ = PaneInfo(*childP)->grip;
+
+ if (managedP != managed_grips) {
+ *unmanagedP++ = *--managedP; /* Last grip is never managed */
+ XtManageChildren( managed_grips, (Cardinal)(managedP - managed_grips) );
+ }
+
+ if (unmanagedP != unmanaged_grips)
+ XtUnmanageChildren( unmanaged_grips,
+ (Cardinal)(unmanagedP - unmanaged_grips) );
+
+ XtFree((char *)managed_grips);
+ XtFree((char *)unmanaged_grips);
+}
+
+/* Function Name: CreateGrip
+ * Description: Creates a grip widget.
+ * Arguments: child - the child that wants a grip to be created for it.
+ * Returns: none.
+ */
+
+static void
+CreateGrip(child)
+Widget child;
+{
+ PanedWidget pw = (PanedWidget) XtParent(child);
+ Arg arglist[2];
+ Cardinal num_args = 0;
+ Cursor cursor;
+
+ XtSetArg(arglist[num_args], XtNtranslations, pw->paned.grip_translations);
+ num_args++;
+ if ( (cursor = pw->paned.grip_cursor) == None )
+ if (IsVert(pw))
+ cursor = pw->paned.v_grip_cursor;
+ else
+ cursor = pw->paned.h_grip_cursor;
+
+ XtSetArg(arglist[num_args], XtNcursor, cursor);
+ num_args++;
+ PaneInfo(child)->grip = XtCreateWidget("grip", gripWidgetClass, (Widget)pw,
+ arglist, num_args);
+
+ XtAddCallback(PaneInfo(child)->grip, XtNcallback,
+ HandleGrip, (XtPointer) child);
+}
+
+/* Function Name: GetGCs
+ * Description: Gets new GC's.
+ * Arguments: w - the paned widget.
+ * Returns: none.
+ */
+
+static void
+GetGCs(w)
+Widget w;
+{
+ PanedWidget pw = (PanedWidget) w;
+ XtGCMask valuemask;
+ XGCValues values;
+
+/*
+ * Draw pane borders in internal border color.
+ */
+
+ values.foreground = pw->paned.internal_bp;
+ valuemask = GCForeground;
+ pw->paned.normgc = XtGetGC(w, valuemask, &values);
+
+/*
+ * Erase pane borders with background color.
+ */
+
+ values.foreground = pw->core.background_pixel;
+ valuemask = GCForeground;
+ pw->paned.invgc = XtGetGC(w, valuemask, &values);
+
+/*
+ * Draw Track lines (animate pane borders) in internal border color ^ bg color.
+ */
+
+ values.function = GXinvert;
+ values.plane_mask = pw->paned.internal_bp ^ pw->core.background_pixel;
+ values.subwindow_mode = IncludeInferiors;
+ valuemask = GCPlaneMask | GCFunction | GCSubwindowMode;
+ pw->paned.flipgc = XtGetGC(w, valuemask, &values);
+}
+
+/* Function Name: SetChildrenPrefSizes.
+ * Description: Sets the preferred sizes of the children.
+ * Arguments: pw - the paned widget.
+ * Returns: none.
+ */
+
+static void
+SetChildrenPrefSizes(pw, off_size)
+PanedWidget pw;
+Dimension off_size;
+{
+ Widget * childP;
+ Boolean vert = IsVert(pw);
+ XtWidgetGeometry request, reply;
+
+ ForAllPanes(pw, childP)
+ if ( pw->paned.resize_children_to_pref ||
+ (PaneInfo(*childP)->size == 0) ||
+ (PaneInfo(*childP)->resize_to_pref) ) {
+
+ if (PaneInfo(*childP)->preferred_size != PANED_ASK_CHILD)
+ PaneInfo(*childP)->wp_size=PaneInfo(*childP)->preferred_size;
+ else {
+ if( vert ) {
+ request.request_mode = CWWidth;
+ request.width = off_size;
+ }
+ else {
+ request.request_mode = CWHeight;
+ request.height = off_size;
+ }
+
+ if ((XtQueryGeometry( *childP, &request, &reply )
+ == XtGeometryAlmost) &&
+ (reply.request_mode = (vert ? CWHeight : CWWidth)))
+ PaneInfo(*childP)->wp_size = GetRequestInfo(&reply, vert);
+ else
+ PaneInfo(*childP)->wp_size = PaneSize(*childP, vert);
+ }
+
+ PaneInfo(*childP)->size = PaneInfo(*childP)->wp_size;
+ }
+}
+
+/* Function Name: ChangeAllGripCursors
+ * Description: Changes all the grip cursors.
+ * Arguments: pw - the paned widget.
+ * Returns: none
+ */
+
+static void
+ChangeAllGripCursors(pw)
+PanedWidget pw;
+{
+ Widget * childP;
+
+ ForAllPanes(pw, childP) {
+ Arg arglist[1];
+ Cursor cursor;
+
+ if ( (cursor = pw->paned.grip_cursor) == None )
+ if ( IsVert(pw) )
+ cursor = pw->paned.v_grip_cursor;
+ else
+ cursor = pw->paned.h_grip_cursor;
+
+ if (HasGrip (*childP)) {
+ XtSetArg(arglist[0], XtNcursor, cursor);
+ XtSetValues(PaneInfo(*childP)->grip, arglist, (Cardinal) 1);
+ }
+ }
+}
+
+/************************************************************
+ *
+ * Stack Manipulation routines (Private).
+ *
+ ************************************************************/
+
+/* Function Name: PushPaneStack
+ * Description: Pushes a value onto the pane stack.
+ * Arguments: pw - the paned widget.
+ * pane - the pane that we are pushing.
+ * Returns: none.
+ */
+
+static void
+PushPaneStack(pw, pane)
+PanedWidget pw;
+Pane pane;
+{
+ PaneStack * stack = (PaneStack *) XtMalloc(sizeof(PaneStack));
+
+ stack->next = pw->paned.stack;
+ stack->pane = pane;
+ stack->start_size = pane->size;
+
+ pw->paned.stack = stack;
+}
+
+/* Function Name: GetPaneStack
+ * Description: Gets the top value from the pane stack.
+ * Arguments: pw - the paned widget.
+ * shrink - TRUE if we want to shrink this pane,
+ * FALSE otherwise.
+ * ** RETURNED ** pane - the pane that we are popping.
+ * ** RETURNED ** start_size - the size that this pane started at.
+ * Returns: none.
+ */
+
+static void
+GetPaneStack(pw, shrink, pane, start_size)
+PanedWidget pw;
+Boolean shrink;
+Pane * pane;
+int * start_size;
+{
+ if (pw->paned.stack == NULL) {
+ *pane = NULL;
+ return;
+ }
+
+ *pane = pw->paned.stack->pane;
+ *start_size = pw->paned.stack->start_size;
+
+ if (shrink != ((*pane)->size > *start_size)) *pane = NULL;
+}
+
+/* Function Name: PopPaneStack
+ * Description: Pops the top item off the pane stack.
+ * Arguments: pw - the paned widget.
+ * Returns: TRUE if this is not the last element on the stack.
+ */
+
+static Boolean
+PopPaneStack(pw)
+PanedWidget pw;
+{
+ PaneStack * stack = pw->paned.stack;
+
+ if (stack == NULL) return(FALSE);
+
+ pw->paned.stack = stack->next;
+ XtFree((char*)stack);
+
+ if (pw->paned.stack == NULL) return(FALSE);
+ return(TRUE);
+}
+
+/* Function Name: ClearPaneStack
+ * Description: removes all entries from the pane stack.
+ * Arguments: pw - the paned widget.
+ * Returns: none
+ */
+
+static void
+ClearPaneStack(pw)
+PanedWidget pw;
+{
+ while(PopPaneStack(pw));
+}
+
+/************************************************************
+ *
+ * Semi-public routines.
+ *
+ ************************************************************/
+
+/* Function Name: ClassInitialize
+ * Description: The Paned widgets class initialization proc.
+ * Arguments: none.
+ * Returns: none.
+ */
+
+static void
+ClassInitialize()
+{
+ XawInitializeWidgetSet();
+ XtAddConverter( XtRString, XtROrientation, XmuCvtStringToOrientation,
+ (XtConvertArgList)NULL, (Cardinal)0 );
+}
+
+/* The Geometry Manager only allows changes after Realize if
+ * allow_resize is True in the constraints record.
+ *
+ * For vertically paned widgets:
+ *
+ * It only allows height changes, but offers the requested height
+ * as a compromise if both width and height changes were requested.
+ *
+ * For horizontal widgets the converse is true.
+ * As all good Geometry Managers should, we will return No if the
+ * request will have no effect; i.e. when the requestor is already
+ * of the desired geometry.
+ */
+
+static XtGeometryResult GeometryManager(w, request, reply)
+Widget w;
+XtWidgetGeometry *request, *reply;
+{
+ PanedWidget pw = (PanedWidget) XtParent(w);
+ XtGeometryMask mask = request->request_mode;
+ Dimension old_size, old_wpsize, old_paned_size;
+ Pane pane = PaneInfo(w);
+ Boolean vert = IsVert(pw);
+ Dimension on_size, off_size;
+ XtGeometryResult result;
+ Boolean almost = FALSE;
+
+/*
+ * If any of the following is true, disallow the geometry change.
+ *
+ * o The paned widget is realized and allow_resize is false for the pane.
+ * o The child did not ask to change the on_size.
+ * o The request is not a width or height request.
+ * o The requested size is the same as the current size.
+ */
+
+ if ( (XtIsRealized((Widget)pw) && !pane->allow_resize) ||
+ !(mask & ((vert) ? CWHeight : CWWidth)) ||
+ (mask & ~(CWWidth | CWHeight)) ||
+ (GetRequestInfo(request, vert) == PaneSize(w, vert)) ) {
+ return XtGeometryNo;
+ }
+
+ old_paned_size = PaneSize( (Widget) pw, vert);
+ old_wpsize = pane->wp_size;
+ old_size = pane->size;
+
+ pane->wp_size = pane->size = GetRequestInfo(request, vert);
+
+ AdjustPanedSize(pw, PaneSize((Widget) pw, !vert), &result, &on_size,
+ &off_size);
+
+/*
+ * Fool the Refigure Locations proc to thinking that we are
+ * a different on_size;
+ */
+
+ if (result != XtGeometryNo)
+ if (vert)
+ pw->core.height = on_size;
+ else
+ pw->core.width = on_size;
+
+ RefigureLocations(pw, PaneIndex(w), AnyPane);
+
+/*
+ * Set up reply struct and reset core on_size.
+ */
+
+ if (vert) {
+ pw->core.height = old_paned_size;
+ reply->height = pane->size;
+ reply->width = off_size;
+ }
+ else {
+ pw->core.width = old_paned_size;
+ reply->height = off_size;
+ reply->width = pane->size;
+ }
+
+/*
+ * IF either of the following is true.
+ *
+ * o There was a "off_size" request and the new "off_size" is different
+ * from that requested.
+ * o There was no "off_size" request and the new "off_size" is different
+ *
+ * o The "on_size" we will allow is different from that requested.
+ *
+ * THEN: set almost
+ */
+
+ if ( !((vert ? CWWidth : CWHeight) & mask))
+ if (vert)
+ request->width = w->core.width;
+ else
+ request->height = w->core.height;
+
+ almost = GetRequestInfo(request, !vert) != GetRequestInfo(reply, !vert);
+ almost |= (GetRequestInfo(request, vert) != GetRequestInfo(reply, vert));
+
+ if ( (mask & XtCWQueryOnly) || almost ) {
+ pane->wp_size = old_wpsize;
+ pane->size = old_size;
+ RefigureLocations(pw, PaneIndex(w), AnyPane);
+ reply->request_mode = CWWidth | CWHeight;
+ if (almost) return XtGeometryAlmost;
+ }
+ else {
+ AdjustPanedSize(pw, PaneSize((Widget) pw, !vert),
+ (XtGeometryResult *)NULL,
+ (Dimension *)NULL, (Dimension *)NULL);
+ CommitNewLocations( pw ); /* layout already refigured. */
+ }
+ return XtGeometryDone;
+}
+
+/* ARGSUSED */
+static void Initialize(request, new, args, num_args)
+Widget request, new;
+ArgList args;
+Cardinal *num_args;
+{
+ PanedWidget pw = (PanedWidget)new;
+
+ GetGCs( (Widget) pw);
+
+ pw->paned.recursively_called = False;
+ pw->paned.stack = NULL;
+ pw->paned.resize_children_to_pref = TRUE;
+ pw->paned.num_panes = 0;
+}
+
+static void
+Realize(w, valueMask, attributes)
+Widget w;
+Mask *valueMask;
+XSetWindowAttributes *attributes;
+{
+ PanedWidget pw = (PanedWidget) w;
+ Widget * childP;
+
+ if ((attributes->cursor = (pw)->paned.cursor) != None)
+ *valueMask |= CWCursor;
+
+ (*SuperClass->core_class.realize) (w, valueMask, attributes);
+
+/*
+ * Before we commit the new locations we need to realize all the panes and
+ * their grips.
+ */
+
+ ForAllPanes(pw, childP) {
+ XtRealizeWidget( *childP );
+ if (HasGrip (*childP))
+ XtRealizeWidget( PaneInfo(*childP)->grip );
+ }
+
+ RefigureLocationsAndCommit(w);
+ pw->paned.resize_children_to_pref = FALSE;
+} /* Realize */
+
+static void
+ReleaseGCs(w)
+Widget w;
+{
+ PanedWidget pw = (PanedWidget)w;
+
+ XtReleaseGC( w, pw->paned.normgc );
+ XtReleaseGC( w, pw->paned.invgc );
+ XtReleaseGC( w, pw->paned.flipgc );
+}
+
+static void InsertChild(w)
+Widget w;
+{
+ Pane pane = PaneInfo(w);
+
+ /* insert the child widget in the composite children list with the */
+ /* superclass insert_child routine. */
+ (*SuperClass->composite_class.insert_child)(w);
+
+ if (!IsPane(w)) return;
+
+ /* ||| Panes will be added in the order they are created, temporarily */
+
+ if ( pane->show_grip == TRUE ) {
+ CreateGrip(w);
+ if (pane->min == PANED_GRIP_SIZE)
+ pane->min = PaneSize(pane->grip, IsVert((PanedWidget) XtParent(w)));
+ }
+ else {
+ if (pane->min == PANED_GRIP_SIZE)
+ pane->min = 1;
+ pane->grip = NULL;
+ }
+
+ pane->size = 0;
+ pane->paned_adjusted_me = FALSE;
+
+} /* InsertChild */
+
+static void DeleteChild(w)
+Widget w;
+{
+ /* remove the subwidget info and destroy the grip */
+
+ if ( IsPane(w) && HasGrip(w) ) XtDestroyWidget(PaneInfo(w)->grip);
+
+ /* delete the child widget in the composite children list with the */
+ /* superclass delete_child routine. */
+ (*SuperClass->composite_class.delete_child) (w);
+
+} /* DeleteChild */
+
+static void ChangeManaged(w)
+ Widget w;
+{
+ PanedWidget pw = (PanedWidget)w;
+ Boolean vert = IsVert(pw);
+ Dimension size;
+ Widget *childP;
+
+ if (pw->paned.recursively_called++) return;
+
+/*
+ * If the size is zero then set it to the size of the widest or tallest pane.
+ */
+
+ if ( (size = PaneSize( (Widget) pw, !vert )) == 0) {
+ size = 1;
+ ForAllChildren(pw, childP)
+ if ( XtIsManaged(*childP) && (PaneSize( *childP, !vert ) > size) )
+ size = PaneSize( *childP, !vert );
+ }
+
+ ManageAndUnmanageGrips(pw);
+ pw->paned.recursively_called = False;
+ ResortChildren(pw);
+
+ pw->paned.num_panes = 0;
+ ForAllChildren(pw, childP)
+ if ( IsPane(*childP) )
+ if ( XtIsManaged(*childP) ) {
+ Pane pane = PaneInfo(*childP);
+ if (HasGrip(*childP))
+ PaneInfo(pane->grip)->position = pw->paned.num_panes;
+ pane->position = pw->paned.num_panes; /*TEMPORY -CDP 3/89 */
+ pw->paned.num_panes++;
+ }
+ else
+ break; /* This list is already sorted. */
+
+ SetChildrenPrefSizes( (PanedWidget) w, size);
+
+/*
+ * ForAllPanes can now be used.
+ */
+
+ if ( PaneSize((Widget) pw, vert) == 0 )
+ AdjustPanedSize(pw, size, (XtGeometryResult *)NULL,
+ (Dimension *)NULL, (Dimension *)NULL);
+
+ if (XtIsRealized( (Widget) pw))
+ RefigureLocationsAndCommit( (Widget) pw);
+
+} /* ChangeManaged */
+
+/* Function Name: Resize
+ * Description: The paned widget's resize proc.
+ * Arguments: w - the paned widget.
+ * Returns: none.
+ */
+
+static void
+Resize(w)
+Widget w;
+{
+ SetChildrenPrefSizes( (PanedWidget) w,
+ PaneSize(w, !IsVert((PanedWidget) w)) );
+ RefigureLocationsAndCommit(w);
+}
+
+/* ARGSUSED */
+static void
+Redisplay(w, event, region)
+Widget w;
+XEvent * event; /* unused. */
+Region region; /* unused. */
+{
+ DrawInternalBorders( (PanedWidget) w);
+}
+
+/* ARGSUSED */
+static Boolean
+SetValues(old, request, new, args, num_args)
+Widget old, request, new;
+ArgList args;
+Cardinal *num_args;
+{
+ PanedWidget old_pw = (PanedWidget) old;
+ PanedWidget new_pw = (PanedWidget) new;
+ Boolean redisplay = FALSE;
+
+ if ( (old_pw->paned.cursor != new_pw->paned.cursor) && XtIsRealized(new))
+ XDefineCursor(XtDisplay(new), XtWindow(new), new_pw->paned.cursor);
+
+ if ( (old_pw->paned.internal_bp != new_pw->paned.internal_bp) ||
+ (old_pw->core.background_pixel != new_pw->core.background_pixel) ) {
+ ReleaseGCs(old);
+ GetGCs(new);
+ redisplay = TRUE;
+ }
+
+ if ( (old_pw->paned.grip_cursor != new_pw->paned.grip_cursor) ||
+ (old_pw->paned.v_grip_cursor != new_pw->paned.v_grip_cursor) ||
+ (old_pw->paned.h_grip_cursor != new_pw->paned.h_grip_cursor) ) {
+ ChangeAllGripCursors(new_pw);
+ }
+
+ if ( IsVert(old_pw) != IsVert(new_pw)) {
+/*
+ * We are fooling the paned widget into thinking that is needs to
+ * fully refigure everything, which is what we want.
+ */
+ if (IsVert(new_pw))
+ new_pw->core.width = 0;
+ else
+ new_pw->core.height = 0;
+
+ new_pw->paned.resize_children_to_pref = TRUE;
+ ChangeManaged(new); /* Seems weird, but does the right thing. */
+ new_pw->paned.resize_children_to_pref = FALSE;
+ if (new_pw->paned.grip_cursor == None)
+ ChangeAllGripCursors(new_pw);
+ return(TRUE);
+ }
+
+ if (old_pw->paned.internal_bw != new_pw->paned.internal_bw) {
+ AdjustPanedSize( new_pw, PaneSize(new, !IsVert(old_pw)),
+ (XtGeometryResult *)NULL,
+ (Dimension *)NULL, (Dimension *)NULL);
+ RefigureLocationsAndCommit(new);
+ return(TRUE); /* We have done a full configuration, return.*/
+ }
+
+ if ( (old_pw->paned.grip_indent != new_pw->paned.grip_indent) &&
+ (XtIsRealized(new)) ) {
+ CommitNewLocations(new_pw);
+ redisplay = TRUE;
+ }
+
+ return (redisplay);
+} /* SetValues */
+
+
+/* ARGSUSED */
+static Boolean
+PaneSetValues(old, request, new, args, num_args)
+Widget old, request, new;
+ArgList args;
+Cardinal *num_args;
+{
+ Pane old_pane = PaneInfo(old);
+ Pane new_pane = PaneInfo(new);
+ Boolean redisplay = FALSE;
+
+ /* Check for new min and max. */
+
+ if (old_pane->min != new_pane->min || old_pane->max != new_pane->max)
+ XawPanedSetMinMax(new, (int)new_pane->min, (int)new_pane->max);
+
+ /* Check for change in XtNshowGrip. */
+
+ if (old_pane->show_grip != new_pane->show_grip)
+ if (new_pane->show_grip == TRUE) {
+ CreateGrip(new);
+ if (XtIsRealized(XtParent(new))) {
+ if (XtIsManaged(new)) /* if paned is unrealized this will
+ happen automatically at realize time.*/
+ XtManageChild(PaneInfo(new)->grip); /* manage the grip. */
+ XtRealizeWidget(PaneInfo(new)->grip); /* realize the grip. */
+ CommitNewLocations( (PanedWidget) XtParent(new) );
+ }
+ }
+ else if ( HasGrip(old) ) {
+ XtDestroyWidget( old_pane->grip );
+ new_pane->grip = NULL;
+ redisplay = TRUE;
+ }
+
+ /* ||| need to look at position changes */
+
+ return(redisplay);
+}
+
+/************************************************************
+ *
+ * Public routines.
+ *
+ ************************************************************/
+
+/* Function Name: XawPanedSetMinMax
+ * Description: Sets the min and max size for a pane.
+ * Arguments: widget - the widget that is a child of the Paned widget.
+ * min, max - the new min and max size for the pane.
+ * Returns: none.
+ */
+
+void
+#if NeedFunctionPrototypes
+XawPanedSetMinMax(Widget widget, int min, int max)
+#else
+XawPanedSetMinMax(widget, min, max)
+Widget widget;
+int min, max;
+#endif
+{
+ Pane pane = PaneInfo(widget);
+
+ pane->min = min;
+ pane->max = max;
+ RefigureLocationsAndCommit( widget->core.parent );
+}
+
+/* Function Name: XawPanedGetMinMax
+ * Description: Gets the min and max size for a pane.
+ * Arguments: widget - the widget that is a child of the Paned widget.
+ ** RETURNED ** min, max - the current min and max size for the pane.
+ * Returns: none.
+ */
+
+void
+#if NeedFunctionPrototypes
+XawPanedGetMinMax(Widget widget, int *min, int *max)
+#else
+XawPanedGetMinMax(widget, min, max)
+Widget widget;
+int *min, *max;
+#endif
+{
+ Pane pane = PaneInfo(widget);
+
+ *min = pane->min;
+ *max = pane->max;
+}
+
+/* Function Name: XawPanedSetRefigureMode
+ * Description: Allows a flag to be set the will inhibit
+ * the paned widgets relayout routine.
+ * Arguments: w - the paned widget.
+ * mode - if FALSE then inhibit refigure.
+ * Returns: none.
+ */
+
+void
+#if NeedFunctionPrototypes
+XawPanedSetRefigureMode(Widget w,
+#if NeedWidePrototypes
+ int mode)
+#else
+ Boolean mode)
+#endif
+#else
+XawPanedSetRefigureMode(w, mode)
+Widget w;
+Boolean mode;
+#endif
+{
+ ((PanedWidget) w)->paned.refiguremode = mode;
+ RefigureLocationsAndCommit( w );
+}
+
+/* Function Name: XawPanedGetNumSub
+ * Description: Returns the number of panes in the paned widget.
+ * Arguments: w - the paned widget.
+ * Returns: the number of panes in the paned widget.
+ */
+
+int
+#if NeedFunctionPrototypes
+XawPanedGetNumSub(Widget w)
+#else
+XawPanedGetNumSub(w)
+Widget w;
+#endif
+{
+ return ((PanedWidget)w)->paned.num_panes;
+}
+
+/* Function Name: XawPanedAllowResize
+ * Description: Allows a flag to be set that determines if the paned
+ * widget will allow geometry requests from this child
+ * Arguments: widget - a child of the paned widget.
+ * Returns: none.
+ */
+
+void
+#if NeedFunctionPrototypes
+XawPanedAllowResize(Widget widget,
+#if NeedWidePrototypes
+ int allow_resize)
+#else
+ Boolean allow_resize)
+#endif
+#else
+XawPanedAllowResize(widget, allow_resize)
+Widget widget;
+Boolean allow_resize;
+#endif
+{
+ PaneInfo(widget)->allow_resize = allow_resize;
+}
diff --git a/src/Paned.h b/src/Paned.h
new file mode 100644
index 0000000..6b37346
--- /dev/null
+++ b/src/Paned.h
@@ -0,0 +1,256 @@
+/*
+* $XConsortium: Paned.h,v 1.15 94/04/17 20:12:29 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.
+
+******************************************************************/
+
+/*
+ * Paned.h - Paned Composite Widget's public header file.
+ *
+ * Updated and significantly modifided from the Athena VPaned Widget.
+ *
+ * Date: March 1, 1989
+ *
+ * By: Chris D. Peterson
+ * MIT X Consortium
+ * kit@expo.lcs.mit.edu
+ */
+
+#ifndef _XawPaned_h
+#define _XawPaned_h
+
+#include <X11/Constraint.h>
+#include <X11/Xmu/Converters.h>
+
+/****************************************************************
+ *
+ * Vertical Paned Widget (SubClass of CompositeClass)
+ *
+ ****************************************************************/
+
+/* RESOURCES:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ background Background Pixel XtDefaultBackground
+ betweenCursor Cursor Cursor **
+ border BorderColor Pixel XtDefaultForeground
+ borderWidth BorderWidth Dimension 1
+ cursor Cursor Cursor None
+ destroyCallback Callback Pointer NULL
+ height Height Dimension 0
+ gripIndent GripIndent Position 16
+ gripCursor Cursor Cursor **
+ horizontalGripCursol Cursor Cursor sb_h_double_arrow
+ horizontalBetweencursor Cursor Cursor sb_up_arrow
+ internalBorderColor BorderColor Pixel XtDefaultForeground
+ internalBorderWidth BorderWidth Position 1
+ leftCursor Cursor Cursor sb_left_arrow
+ lowerCursor Cursor Cursor sb_down_arrow
+ mappedWhenManaged MappedWhenManaged Boolean True
+ orientation Orientation XtOrientation XtorientVertical
+ refigureMode Boolean Boolean On
+ rightCursor Cursor Cursor sb_right_arrow
+ sensitive Sensitive Boolean True
+ upperCursor Cursor Cursor sb_up_arrow
+ verticalBetweenCursor Cursor Cursor sb_left_arrow
+ verticalGripCursor Cursor Cursor sb_v_double_arrow
+ width Width Dimension 0
+ x Position Position 0
+ y Position Position 0
+
+** These resources now are set to the vertical or horizontal cursor
+ depending upon orientation, by default. If a value is specified here
+ then that cursor will be used reguardless of orientation.
+
+
+CONSTRAINT RESOURCES:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ allowResize Boolean Boolean False
+ max Max Dimension unlimited
+ min Min Dimension Grip Size
+ preferredPaneSize PerferredPaneSize Dimension PANED_ASK_CHILD
+ resizeToPreferred Boolean Boolean False
+ showGrip ShowGrip Boolean True
+ skipAdjust Boolean Boolean False
+
+*/
+
+#define PANED_ASK_CHILD 0
+#define PANED_GRIP_SIZE 0
+
+/* New Fields */
+#define XtNallowResize "allowResize"
+#define XtNbetweenCursor "betweenCursor"
+#define XtNverticalBetweenCursor "verticalBetweenCursor"
+#define XtNhorizontalBetweenCursor "horizontalBetweenCursor"
+#define XtNgripCursor "gripCursor"
+#define XtNgripIndent "gripIndent"
+#define XtNhorizontalGripCursor "horizontalGripCursor"
+#define XtNinternalBorderColor "internalBorderColor"
+#define XtNinternalBorderWidth "internalBorderWidth"
+#define XtNleftCursor "leftCursor"
+#define XtNlowerCursor "lowerCursor"
+#define XtNrefigureMode "refigureMode"
+#define XtNposition "position"
+#define XtNmin "min"
+#define XtNmax "max"
+#define XtNpreferredPaneSize "preferredPaneSize"
+#define XtNresizeToPreferred "resizeToPreferred"
+#define XtNrightCursor "rightCursor"
+#define XtNshowGrip "showGrip"
+#define XtNskipAdjust "skipAdjust"
+#define XtNupperCursor "upperCursor"
+#define XtNverticalGripCursor "verticalGripCursor"
+
+#define XtCGripIndent "GripIndent"
+#define XtCMin "Min"
+#define XtCMax "Max"
+#define XtCPreferredPaneSize "PreferredPaneSize"
+#define XtCShowGrip "ShowGrip"
+
+/* Class record constant */
+extern WidgetClass panedWidgetClass;
+
+typedef struct _PanedClassRec *PanedWidgetClass;
+typedef struct _PanedRec *PanedWidget;
+
+/************************************************************
+ *
+ * Public Procedures
+ *
+ ************************************************************/
+
+_XFUNCPROTOBEGIN
+
+/* Function Name: XawPanedSetMinMax
+ * Description: Sets the min and max size for a pane.
+ * Arguments: widget - the widget that is a child of the Paned widget.
+ * min, max - the new min and max size for the pane.
+ * Returns: none.
+ */
+
+extern void XawPanedSetMinMax(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ int /* min */,
+ int /* max */
+#endif
+);
+
+/* Function Name: XawPanedGetMinMax
+ * Description: Gets the min and max size for a pane.
+ * Arguments: widget - the widget that is a child of the Paned widget.
+ ** RETURNED ** min, max - the current min and max size for the pane.
+ * Returns: none.
+ */
+
+extern void XawPanedGetMinMax(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ int * /* min_return */,
+ int * /* max_return */
+#endif
+);
+
+/* Function Name: XawPanedSetRefigureMode
+ * Description: Allows a flag to be set the will inhibit
+ * the paned widgets relayout routine.
+ * Arguments: w - the paned widget.
+ * mode - if FALSE then inhibit refigure.
+ * Returns: none.
+ */
+
+extern void XawPanedSetRefigureMode(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+#if NeedWidePrototypes
+ /* Boolean */ int /* mode */
+#else
+ Boolean /* mode */
+#endif
+#endif
+);
+
+/* Function Name: XawPanedGetNumSub
+ * Description: Returns the number of panes in the paned widget.
+ * Arguments: w - the paned widget.
+ * Returns: the number of panes in the paned widget.
+ */
+
+extern int XawPanedGetNumSub(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+/* Function Name: XawPanedAllowResize
+ * Description: Allows a flag to be set that determines if the paned
+ * widget will allow geometry requests from this child
+ * Arguments: widget - a child of the paned widget.
+ * Returns: none.
+ */
+
+extern void XawPanedAllowResize(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+#if NeedWidePrototypes
+ /* Boolean */ int /* allow_resize */
+#else
+ Boolean /* allow_resize */
+#endif
+#endif
+);
+
+_XFUNCPROTOEND
+
+#endif /* _XawPaned_h */
diff --git a/src/PanedP.h b/src/PanedP.h
new file mode 100644
index 0000000..57c410b
--- /dev/null
+++ b/src/PanedP.h
@@ -0,0 +1,193 @@
+/***********************************************************
+
+ $XConsortium: PanedP.h,v 1.6 94/04/17 20:12:30 gildea Exp $
+
+
+Copyright (c) 1987, 1988 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.
+
+******************************************************************/
+
+/*
+ * PanedP.h - Paned Composite Widget's private header file.
+ *
+ * Updated and significantly modified from the Athena VPaned Widget.
+ *
+ * Date: March 1, 1989
+ *
+ * By: Chris D. Peterson
+ * MIT X Consortium
+ * kit@expo.lcs.mit.edu
+ */
+
+#ifndef _XawPanedP_h
+#define _XawPanedP_h
+
+#include <X11/Xaw3d/Paned.h>
+
+/*********************************************************************
+ *
+ * Paned Widget Private Data
+ *
+ *********************************************************************/
+
+/* New fields for the Paned widget class record */
+
+typedef struct _PanedClassPart {
+ int foo; /* keep compiler happy. */
+} PanedClassPart;
+
+/* Full Class record declaration */
+typedef struct _PanedClassRec {
+ CoreClassPart core_class;
+ CompositeClassPart composite_class;
+ ConstraintClassPart constraint_class;
+ PanedClassPart paned_class;
+} PanedClassRec;
+
+extern PanedClassRec panedClassRec;
+
+/* Paned constraint record */
+typedef struct _PanedConstraintsPart {
+ /* Resources. */
+ Dimension min; /* Minimum height */
+ Dimension max; /* Maximum height */
+ Boolean allow_resize; /* TRUE iff child resize requests are ok */
+ Boolean show_grip; /* TRUE iff child will have grip below it,
+ when it is not the bottom pane. */
+ Boolean skip_adjust; /* TRUE iff child's height should not be */
+ /* changed without explicit user action. */
+ int position; /* position location in Paned (relative to
+ other children) ** NIY ** */
+ Dimension preferred_size; /* The Preferred size of the pane.
+ Iff this is zero then ask child for size.*/
+ Boolean resize_to_pref; /* resize this pane to its preferred size
+ on a resize or change managed after
+ realize. */
+
+ /* Private state. */
+ Position delta; /* Desired Location */
+ Position olddelta; /* The last value of dy. */
+ Boolean paned_adjusted_me; /* Has the vpaned adjusted this widget w/o
+ user interaction to make things fit? */
+ Dimension wp_size; /* widget's preferred size */
+ int size; /* the size the widget will actually get. */
+ Widget grip; /* The grip for this child */
+
+} PanedConstraintsPart, *Pane;
+
+typedef struct _PanedConstraintsRec {
+ PanedConstraintsPart paned;
+} PanedConstraintsRec, *PanedConstraints;
+
+/*
+ * The Pane Stack Structure.
+ */
+
+typedef struct _PaneStack {
+ struct _PaneStack * next; /* The next element on the stack. */
+ Pane pane; /* The pane in this element on the stack. */
+ int start_size; /* The size of this element when it was pushed
+ onto the stack. */
+} PaneStack;
+
+/* New Fields for the Paned widget record */
+typedef struct {
+ /* resources */
+ Position grip_indent; /* Location of grips (offset
+ from right margin) */
+ Boolean refiguremode; /* Whether to refigure changes
+ right now */
+ XtTranslations grip_translations; /* grip translation table */
+ Pixel internal_bp; /* color of internal borders. */
+ Dimension internal_bw; /* internal border width. */
+ XtOrientation orientation; /* Orientation of paned widget. */
+
+ Cursor cursor; /* Cursor for paned window */
+ Cursor grip_cursor; /* inactive grip cursor */
+ Cursor v_grip_cursor; /* inactive vert grip cursor */
+ Cursor h_grip_cursor; /* inactive horiz grip cursor */
+ Cursor adjust_this_cursor; /* active grip cursor: T */
+ Cursor v_adjust_this_cursor; /* active vert grip cursor: T */
+ Cursor h_adjust_this_cursor; /* active horiz grip cursor: T */
+
+ /* vertical. */
+ Cursor adjust_upper_cursor; /* active grip cursor: U */
+ Cursor adjust_lower_cursor; /* active grip cursor: D */
+
+ /* horizontal. */
+ Cursor adjust_left_cursor; /* active grip cursor: U */
+ Cursor adjust_right_cursor; /* active grip cursor: D */
+
+ /* private */
+ Boolean recursively_called; /* for ChangeManaged */
+ Boolean resize_children_to_pref; /* override constrain resources
+ and resize all children to
+ preferred size. */
+ int start_loc; /* mouse origin when adjusting */
+ Widget whichadd; /* Which pane to add changes to */
+ Widget whichsub; /* Which pane to sub changes from */
+ GC normgc; /* GC to use when drawing borders */
+ GC invgc; /* GC to use when erasing borders */
+ GC flipgc; /* GC to use when animating
+ borders */
+ int num_panes; /* count of managed panes */
+ PaneStack * stack; /* The pane stack for this widget.*/
+} PanedPart;
+
+/**************************************************************************
+ *
+ * Full instance record declaration
+ *
+ **************************************************************************/
+
+typedef struct _PanedRec {
+ CorePart core;
+ CompositePart composite;
+ ConstraintPart constraint;
+ PanedPart paned;
+} PanedRec;
+
+#endif /* _XawPanedP_h */
+/* DON'T ADD STUFF AFTER THIS #endif */
diff --git a/src/Panner.c b/src/Panner.c
new file mode 100644
index 0000000..2d2f482
--- /dev/null
+++ b/src/Panner.c
@@ -0,0 +1,975 @@
+/*
+ * $XConsortium: Panner.c,v 1.52 95/01/10 14:31:26 kaleb Exp $
+ *
+Copyright (c) 1989, 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.
+ *
+ * Author: Jim Fulton, MIT X Consortium
+ */
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h> /* for XtN and XtC defines */
+#include <X11/Xmu/CharSet.h> /* for XmuCompareISOLatin1() */
+#include <X11/Xaw3d/XawInit.h> /* for XawInitializeWidgetSet */
+#include <X11/Xaw3d/PannerP.h> /* us */
+#include <X11/Xos.h>
+#include <X11/Xmu/Misc.h> /* for Min */
+#include <X11/Xmu/Drawing.h>
+#include <ctype.h> /* for isascii() etc. */
+#include <math.h> /* for atof() */
+
+extern Bool XmuDistinguishablePixels(); /* not defined in any Xmu headers */
+
+#if defined(ISC) && __STDC__ && !defined(ISC30)
+extern double atof(char *);
+#endif
+
+
+#if XtVersion >= 11006
+static char defaultTranslations[] =
+ "<Btn1Down>: start() \n\
+ <Btn1Motion>: move() \n\
+ <Btn1Up>: notify() stop() \n\
+ <Btn2Down>: abort() \n\
+ :<Key>KP_Enter: set(rubberband,toggle) \n\
+ <Key>space: page(+1p,+1p) \n\
+ <Key>Delete: page(-1p,-1p) \n\
+ :<Key>KP_Delete: page(-1p,-1p) \n\
+ <Key>BackSpace: page(-1p,-1p) \n\
+ <Key>Left: page(-.5p,+0) \n\
+ :<Key>KP_Left: page(-.5p,+0) \n\
+ <Key>Right: page(+.5p,+0) \n\
+ :<Key>KP_Right: page(+.5p,+0) \n\
+ <Key>Up: page(+0,-.5p) \n\
+ :<Key>KP_Up: page(+0,-.5p) \n\
+ <Key>Down: page(+0,+.5p) \n\
+ :<Key>KP_Down: page(+0,+.5p) \n\
+ <Key>Home: page(0,0) \n\
+ :<Key>KP_Home: page(0,0)";
+#else
+static char defaultTranslations[] =
+ "<Btn1Down>: start() \n\
+ <Btn1Motion>: move() \n\
+ <Btn1Up>: notify() stop() \n\
+ <Btn2Down>: abort() \n\
+ <Key>KP_Enter: set(rubberband,toggle) \n\
+ <Key>space: page(+1p,+1p) \n\
+ <Key>Delete: page(-1p,-1p) \n\
+ <Key>BackSpace: page(-1p,-1p) \n\
+ <Key>Left: page(-.5p,+0) \n\
+ <Key>Right: page(+.5p,+0) \n\
+ <Key>Up: page(+0,-.5p) \n\
+ <Key>Down: page(+0,+.5p) \n\
+ <Key>Home: page(0,0)";
+#endif
+
+
+static void ActionStart(), ActionStop(), ActionAbort(), ActionMove();
+static void ActionPage(), ActionNotify(), ActionSet();
+
+static XtActionsRec actions[] = {
+ { "start", ActionStart }, /* start tmp graphics */
+ { "stop", ActionStop }, /* stop tmp graphics */
+ { "abort", ActionAbort }, /* punt */
+ { "move", ActionMove }, /* move tmp graphics on Motion event */
+ { "page", ActionPage }, /* page around usually from keyboard */
+ { "notify", ActionNotify }, /* callback new position */
+ { "set", ActionSet }, /* set various parameters */
+};
+
+
+/*
+ * resources for the panner
+ */
+static XtResource resources[] = {
+#define poff(field) XtOffsetOf(PannerRec, panner.field)
+ { XtNallowOff, XtCAllowOff, XtRBoolean, sizeof(Boolean),
+ poff(allow_off), XtRImmediate, (XtPointer) FALSE },
+ { XtNresize, XtCResize, XtRBoolean, sizeof(Boolean),
+ poff(resize_to_pref), XtRImmediate, (XtPointer) TRUE },
+ { XtNreportCallback, XtCReportCallback, XtRCallback, sizeof(XtPointer),
+ poff(report_callbacks), XtRCallback, (XtPointer) NULL },
+ { XtNdefaultScale, XtCDefaultScale, XtRDimension, sizeof(Dimension),
+ poff(default_scale), XtRImmediate, (XtPointer) PANNER_DEFAULT_SCALE },
+ { XtNrubberBand, XtCRubberBand, XtRBoolean, sizeof(Boolean),
+ poff(rubber_band), XtRImmediate, (XtPointer) FALSE },
+ { XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
+ poff(foreground), XtRString, (XtPointer) XtDefaultBackground },
+ { XtNinternalSpace, XtCInternalSpace, XtRDimension, sizeof(Dimension),
+ poff(internal_border), XtRImmediate, (XtPointer) 4 },
+ { XtNlineWidth, XtCLineWidth, XtRDimension, sizeof(Dimension),
+ poff(line_width), XtRImmediate, (XtPointer) 0 },
+ { XtNcanvasWidth, XtCCanvasWidth, XtRDimension, sizeof(Dimension),
+ poff(canvas_width), XtRImmediate, (XtPointer) 0 },
+ { XtNcanvasHeight, XtCCanvasHeight, XtRDimension, sizeof(Dimension),
+ poff(canvas_height), XtRImmediate, (XtPointer) 0 },
+ { XtNsliderX, XtCSliderX, XtRPosition, sizeof(Position),
+ poff(slider_x), XtRImmediate, (XtPointer) 0 },
+ { XtNsliderY, XtCSliderY, XtRPosition, sizeof(Position),
+ poff(slider_y), XtRImmediate, (XtPointer) 0 },
+ { XtNsliderWidth, XtCSliderWidth, XtRDimension, sizeof(Dimension),
+ poff(slider_width), XtRImmediate, (XtPointer) 0 },
+ { XtNsliderHeight, XtCSliderHeight, XtRDimension, sizeof(Dimension),
+ poff(slider_height), XtRImmediate, (XtPointer) 0 },
+ { XtNshadowColor, XtCShadowColor, XtRPixel, sizeof(Pixel),
+ poff(shadow_color), XtRString, (XtPointer) XtDefaultForeground },
+ { XtNshadowThickness, XtCShadowThickness, XtRDimension, sizeof(Dimension),
+ poff(shadow_thickness), XtRImmediate, (XtPointer) 2 },
+ { XtNbackgroundStipple, XtCBackgroundStipple, XtRString, sizeof(String),
+ poff(stipple_name), XtRImmediate, (XtPointer) NULL },
+#undef poff
+};
+
+
+/*
+ * widget class methods used below
+ */
+static void Initialize(); /* create gc's */
+static void Realize(); /* create window */
+static void Destroy(); /* clean up widget */
+static void Resize(); /* need to rescale ourselves */
+static void Redisplay(); /* draw ourselves */
+static Boolean SetValues(); /* set all of the resources */
+static void SetValuesAlmost(); /* deal with failed setval geom req */
+static XtGeometryResult QueryGeometry(); /* say how big we would like to be */
+
+PannerClassRec pannerClassRec = {
+ { /* core fields */
+ /* superclass */ (WidgetClass) &simpleClassRec,
+ /* class_name */ "Panner",
+ /* widget_size */ sizeof(PannerRec),
+ /* class_initialize */ XawInitializeWidgetSet,
+ /* class_part_initialize */ NULL,
+ /* class_inited */ FALSE,
+ /* initialize */ Initialize,
+ /* initialize_hook */ NULL,
+ /* realize */ Realize,
+ /* actions */ actions,
+ /* num_actions */ XtNumber(actions),
+ /* 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 */ SetValuesAlmost,
+ /* get_values_hook */ NULL,
+ /* accept_focus */ NULL,
+ /* version */ XtVersion,
+ /* callback_private */ NULL,
+ /* tm_table */ defaultTranslations,
+ /* query_geometry */ QueryGeometry,
+ /* display_accelerator */ XtInheritDisplayAccelerator,
+ /* extension */ NULL
+ },
+ { /* simple fields */
+ /* change_sensitive */ XtInheritChangeSensitive
+ },
+ { /* panner fields */
+ /* ignore */ 0
+ }
+};
+
+WidgetClass pannerWidgetClass = (WidgetClass) &pannerClassRec;
+
+
+/*****************************************************************************
+ * *
+ * panner utility routines *
+ * *
+ *****************************************************************************/
+
+static void reset_shadow_gc (pw) /* used when resources change */
+ PannerWidget pw;
+{
+ XtGCMask valuemask = GCForeground;
+ XGCValues values;
+ unsigned long pixels[3];
+
+ if (pw->panner.shadow_gc) XtReleaseGC ((Widget) pw, pw->panner.shadow_gc);
+
+ pixels[0] = pw->panner.foreground;
+ pixels[1] = pw->core.background_pixel;
+ pixels[2] = pw->panner.shadow_color;
+ if (!pw->panner.stipple_name &&
+ !XmuDistinguishablePixels (XtDisplay (pw), pw->core.colormap,
+ pixels, 3) &&
+ XmuDistinguishablePixels (XtDisplay (pw), pw->core.colormap,
+ pixels, 2))
+ {
+ valuemask = GCTile | GCFillStyle;
+ values.fill_style = FillTiled;
+ values.tile = XmuCreateStippledPixmap(XtScreen((Widget)pw),
+ pw->panner.foreground,
+ pw->core.background_pixel,
+ pw->core.depth);
+ }
+ else
+ {
+ if (!pw->panner.line_width &&
+ !XmuDistinguishablePixels (XtDisplay (pw), pw->core.colormap,
+ pixels, 2))
+ pw->panner.line_width = 1;
+ valuemask = GCForeground;
+ values.foreground = pw->panner.shadow_color;
+ }
+ if (pw->panner.line_width > 0) {
+ values.line_width = pw->panner.line_width;
+ valuemask |= GCLineWidth;
+ }
+
+ pw->panner.shadow_gc = XtGetGC ((Widget) pw, valuemask, &values);
+}
+
+static void reset_slider_gc (pw) /* used when resources change */
+ PannerWidget pw;
+{
+ XtGCMask valuemask = GCForeground;
+ XGCValues values;
+
+ if (pw->panner.slider_gc) XtReleaseGC ((Widget) pw, pw->panner.slider_gc);
+
+ values.foreground = pw->panner.foreground;
+
+ pw->panner.slider_gc = XtGetGC ((Widget) pw, valuemask, &values);
+}
+
+static void reset_xor_gc (pw) /* used when resources change */
+ PannerWidget pw;
+{
+ if (pw->panner.xor_gc) XtReleaseGC ((Widget) pw, pw->panner.xor_gc);
+
+ if (pw->panner.rubber_band) {
+ XtGCMask valuemask = (GCForeground | GCFunction);
+ XGCValues values;
+ Pixel tmp;
+
+ tmp = ((pw->panner.foreground == pw->core.background_pixel) ?
+ pw->panner.shadow_color : pw->panner.foreground);
+ values.foreground = tmp ^ pw->core.background_pixel;
+ values.function = GXxor;
+ if (pw->panner.line_width > 0) {
+ valuemask |= GCLineWidth;
+ values.line_width = pw->panner.line_width;
+ }
+ pw->panner.xor_gc = XtGetGC ((Widget) pw, valuemask, &values);
+ } else {
+ pw->panner.xor_gc = NULL;
+ }
+}
+
+
+static void check_knob (pw, knob)
+ PannerWidget pw;
+ Boolean knob;
+{
+ Position pad = pw->panner.internal_border * 2;
+ Position maxx = (((Position) pw->core.width) - pad -
+ ((Position) pw->panner.knob_width));
+ Position maxy = (((Position) pw->core.height) - pad -
+ ((Position) pw->panner.knob_height));
+ Position *x = (knob ? &pw->panner.knob_x : &pw->panner.tmp.x);
+ Position *y = (knob ? &pw->panner.knob_y : &pw->panner.tmp.y);
+
+ /*
+ * note that positions are already normalized (i.e. internal_border
+ * has been subtracted out)
+ */
+ if (*x < 0) *x = 0;
+ if (*x > maxx) *x = maxx;
+
+ if (*y < 0) *y = 0;
+ if (*y > maxy) *y = maxy;
+
+ if (knob) {
+ pw->panner.slider_x = (Position) (((double) pw->panner.knob_x) /
+ pw->panner.haspect + 0.5);
+ pw->panner.slider_y = (Position) (((double) pw->panner.knob_y) /
+ pw->panner.vaspect + 0.5);
+ pw->panner.last_x = pw->panner.last_y = PANNER_OUTOFRANGE;
+ }
+}
+
+
+static void move_shadow (pw)
+ PannerWidget pw;
+{
+ if (pw->panner.shadow_thickness > 0) {
+ int lw = pw->panner.shadow_thickness + pw->panner.line_width * 2;
+ int pad = pw->panner.internal_border;
+
+ if ((int)pw->panner.knob_height > lw && (int)pw->panner.knob_width > lw) {
+ XRectangle *r = pw->panner.shadow_rects;
+ r->x = (short) (pw->panner.knob_x + pad + pw->panner.knob_width);
+ r->y = (short) (pw->panner.knob_y + pad + lw);
+ r->width = pw->panner.shadow_thickness;
+ r->height = (unsigned short) (pw->panner.knob_height - lw);
+ r++;
+ r->x = (short) (pw->panner.knob_x + pad + lw);
+ r->y = (short) (pw->panner.knob_y + pad + pw->panner.knob_height);
+ r->width = (unsigned short) (pw->panner.knob_width - lw +
+ pw->panner.shadow_thickness);
+ r->height = pw->panner.shadow_thickness;
+ pw->panner.shadow_valid = TRUE;
+ return;
+ }
+ }
+ pw->panner.shadow_valid = FALSE;
+}
+
+static void scale_knob (pw, location, size) /* set knob size and/or loc */
+ PannerWidget pw;
+ Boolean location, size;
+{
+ if (location) {
+ pw->panner.knob_x = (Position) PANNER_HSCALE (pw, pw->panner.slider_x);
+ pw->panner.knob_y = (Position) PANNER_VSCALE (pw, pw->panner.slider_y);
+ }
+ if (size) {
+ Dimension width, height;
+
+ if (pw->panner.slider_width < 1) {
+ pw->panner.slider_width = pw->panner.canvas_width;
+ }
+ if (pw->panner.slider_height < 1) {
+ pw->panner.slider_height = pw->panner.canvas_height;
+ }
+ width = Min (pw->panner.slider_width, pw->panner.canvas_width);
+ height = Min (pw->panner.slider_height, pw->panner.canvas_height);
+
+ pw->panner.knob_width = (Dimension) PANNER_HSCALE (pw, width);
+ pw->panner.knob_height = (Dimension) PANNER_VSCALE (pw, height);
+ }
+ if (!pw->panner.allow_off) check_knob (pw, TRUE);
+ move_shadow (pw);
+}
+
+static void rescale (pw)
+ PannerWidget pw;
+{
+ int hpad = pw->panner.internal_border * 2;
+ int vpad = hpad;
+
+ if (pw->panner.canvas_width < 1)
+ pw->panner.canvas_width = pw->core.width;
+ if (pw->panner.canvas_height < 1)
+ pw->panner.canvas_height = pw->core.height;
+
+ if ((int)pw->core.width <= hpad) hpad = 0;
+ if ((int)pw->core.height <= vpad) vpad = 0;
+
+ pw->panner.haspect = ((double) pw->core.width - hpad) /
+ (double) pw->panner.canvas_width;
+ pw->panner.vaspect = ((double) pw->core.height - vpad) /
+ (double) pw->panner.canvas_height;
+ scale_knob (pw, TRUE, TRUE);
+}
+
+
+static void get_default_size (pw, wp, hp)
+ PannerWidget pw;
+ Dimension *wp, *hp;
+{
+ Dimension pad = pw->panner.internal_border * 2;
+ *wp = PANNER_DSCALE (pw, pw->panner.canvas_width) + pad;
+ *hp = PANNER_DSCALE (pw, pw->panner.canvas_height) + pad;
+}
+
+static Boolean get_event_xy (pw, event, x, y)
+ PannerWidget pw;
+ XEvent *event;
+ int *x, *y;
+{
+ int pad = pw->panner.internal_border;
+
+ switch (event->type) {
+ case ButtonPress:
+ case ButtonRelease:
+ *x = event->xbutton.x - pad;
+ *y = event->xbutton.y - pad;
+ return TRUE;
+
+ case KeyPress:
+ case KeyRelease:
+ *x = event->xkey.x - pad;
+ *y = event->xkey.y - pad;
+ return TRUE;
+
+ case EnterNotify:
+ case LeaveNotify:
+ *x = event->xcrossing.x - pad;
+ *y = event->xcrossing.y - pad;
+ return TRUE;
+
+ case MotionNotify:
+ *x = event->xmotion.x - pad;
+ *y = event->xmotion.y - pad;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static int parse_page_string (s, pagesize, canvassize, relative)
+ char *s;
+ int pagesize, canvassize;
+ Boolean *relative;
+{
+ char *cp;
+ double val = 1.0;
+ Boolean rel = FALSE;
+
+ /*
+ * syntax: spaces [+-] number spaces [pc\0] spaces
+ */
+
+ for (; isascii(*s) && isspace(*s); s++) ; /* skip white space */
+
+ if (*s == '+' || *s == '-') { /* deal with signs */
+ rel = TRUE;
+ if (*s == '-') val = -1.0;
+ s++;
+ }
+ if (!*s) { /* if null then return nothing */
+ *relative = TRUE;
+ return 0;
+ }
+
+ /* skip over numbers */
+ for (cp = s; isascii(*s) && (isdigit(*s) || *s == '.'); s++) ;
+ val *= atof (cp);
+
+ /* skip blanks */
+ for (; isascii(*s) && isspace(*s); s++) ;
+
+ if (*s) { /* if units */
+ switch (s[0]) {
+ case 'p': case 'P':
+ val *= (double) pagesize;
+ break;
+
+ case 'c': case 'C':
+ val *= (double) canvassize;
+ break;
+ }
+ }
+ *relative = rel;
+ return ((int) val);
+}
+
+
+#define DRAW_TMP(pw) \
+{ \
+ XDrawRectangle (XtDisplay(pw), XtWindow(pw), \
+ pw->panner.xor_gc, \
+ (int) (pw->panner.tmp.x + pw->panner.internal_border), \
+ (int) (pw->panner.tmp.y + pw->panner.internal_border), \
+ (unsigned int) (pw->panner.knob_width - 1), \
+ (unsigned int) (pw->panner.knob_height - 1)); \
+ pw->panner.tmp.showing = !pw->panner.tmp.showing; \
+}
+
+#define UNDRAW_TMP(pw) \
+{ \
+ if (pw->panner.tmp.showing) DRAW_TMP(pw); \
+}
+
+#define BACKGROUND_STIPPLE(pw) \
+ XmuLocatePixmapFile (pw->core.screen, pw->panner.stipple_name, \
+ pw->panner.shadow_color, pw->core.background_pixel, \
+ pw->core.depth, NULL, 0, NULL, NULL, NULL, NULL)
+
+#define PIXMAP_OKAY(pm) ((pm) != None && (pm) != XtUnspecifiedPixmap)
+
+
+/*****************************************************************************
+ * *
+ * panner class methods *
+ * *
+ *****************************************************************************/
+
+
+/*ARGSUSED*/
+static void Initialize (greq, gnew, args, num_args)
+ Widget greq, gnew;
+ ArgList args;
+ Cardinal *num_args;
+{
+ PannerWidget req = (PannerWidget) greq, new = (PannerWidget) gnew;
+ Dimension defwidth, defheight;
+
+ if (req->panner.canvas_width < 1) new->panner.canvas_width = 1;
+ if (req->panner.canvas_height < 1) new->panner.canvas_height = 1;
+ if (req->panner.default_scale < 1)
+ new->panner.default_scale = PANNER_DEFAULT_SCALE;
+
+ get_default_size (req, &defwidth, &defheight);
+ if (req->core.width < 1) new->core.width = defwidth;
+ if (req->core.height < 1) new->core.height = defheight;
+
+ new->panner.shadow_gc = NULL;
+ reset_shadow_gc (new); /* shadowColor */
+ new->panner.slider_gc = NULL;
+ reset_slider_gc (new); /* foreground */
+ new->panner.xor_gc = NULL;
+ reset_xor_gc (new); /* foreground ^ background */
+
+ rescale (new); /* does a position check */
+ new->panner.shadow_valid = FALSE;
+ new->panner.tmp.doing = FALSE;
+ new->panner.tmp.showing = FALSE;
+}
+
+
+static void Realize (gw, valuemaskp, attr)
+ Widget gw;
+ XtValueMask *valuemaskp;
+ XSetWindowAttributes *attr;
+{
+ PannerWidget pw = (PannerWidget) gw;
+ Pixmap pm = XtUnspecifiedPixmap;
+ Boolean gotpm = FALSE;
+
+ if (pw->core.background_pixmap == XtUnspecifiedPixmap) {
+ if (pw->panner.stipple_name) pm = BACKGROUND_STIPPLE (pw);
+
+ if (PIXMAP_OKAY(pm)) {
+ attr->background_pixmap = pm;
+ *valuemaskp |= CWBackPixmap;
+ *valuemaskp &= ~CWBackPixel;
+ gotpm = TRUE;
+ }
+ }
+ (*pannerWidgetClass->core_class.superclass->core_class.realize)
+ (gw, valuemaskp, attr);
+
+ if (gotpm) XFreePixmap (XtDisplay(gw), pm);
+}
+
+
+static void Destroy (gw)
+ Widget gw;
+{
+ PannerWidget pw = (PannerWidget) gw;
+
+ XtReleaseGC (gw, pw->panner.shadow_gc);
+ XtReleaseGC (gw, pw->panner.slider_gc);
+ XtReleaseGC (gw, pw->panner.xor_gc);
+}
+
+
+static void Resize (gw)
+ Widget gw;
+{
+ rescale ((PannerWidget) gw);
+}
+
+
+/* ARGSUSED */
+static void Redisplay (gw, event, region)
+ Widget gw;
+ XEvent *event;
+ Region region;
+{
+ PannerWidget pw = (PannerWidget) gw;
+ Display *dpy = XtDisplay(gw);
+ Window w = XtWindow(gw);
+ int pad = pw->panner.internal_border;
+ Dimension lw = pw->panner.line_width;
+ Dimension extra = pw->panner.shadow_thickness + lw * 2;
+ int kx = pw->panner.knob_x + pad, ky = pw->panner.knob_y + pad;
+
+ pw->panner.tmp.showing = FALSE;
+ XClearArea (XtDisplay(pw), XtWindow(pw),
+ (int) pw->panner.last_x - ((int) lw) + pad,
+ (int) pw->panner.last_y - ((int) lw) + pad,
+ (unsigned int) (pw->panner.knob_width + extra),
+ (unsigned int) (pw->panner.knob_height + extra),
+ False);
+ pw->panner.last_x = pw->panner.knob_x;
+ pw->panner.last_y = pw->panner.knob_y;
+
+ XFillRectangle (dpy, w, pw->panner.slider_gc, kx, ky,
+ pw->panner.knob_width - 1, pw->panner.knob_height - 1);
+
+ if (lw)
+ {
+ XDrawRectangle (dpy, w, pw->panner.shadow_gc, kx, ky,
+ (unsigned int) (pw->panner.knob_width - 1),
+ (unsigned int) (pw->panner.knob_height - 1));
+ }
+
+ if (pw->panner.shadow_valid) {
+ XFillRectangles (dpy, w, pw->panner.shadow_gc,
+ pw->panner.shadow_rects, 2);
+ }
+ if (pw->panner.tmp.doing && pw->panner.rubber_band) DRAW_TMP (pw);
+}
+
+
+/* ARGSUSED */
+static Boolean SetValues (gcur, greq, gnew, args, num_args)
+ Widget gcur, greq, gnew;
+ ArgList args;
+ Cardinal *num_args;
+{
+ PannerWidget cur = (PannerWidget) gcur;
+ PannerWidget new = (PannerWidget) gnew;
+ Boolean redisplay = FALSE;
+
+ if (cur->panner.foreground != new->panner.foreground) {
+ reset_slider_gc (new);
+ if (cur->panner.foreground != cur->core.background_pixel)
+ reset_xor_gc (new);
+ redisplay = TRUE;
+ } else if (cur->panner.line_width != new->panner.line_width ||
+ cur->core.background_pixel != new->core.background_pixel) {
+ reset_xor_gc (new);
+ redisplay = TRUE;
+ }
+ if (cur->panner.shadow_color != new->panner.shadow_color) {
+ reset_shadow_gc (new);
+ if (cur->panner.foreground == cur->core.background_pixel)
+ reset_xor_gc (new);
+ redisplay = TRUE;
+ }
+ if (cur->panner.shadow_thickness != new->panner.shadow_thickness) {
+ move_shadow (new);
+ redisplay = TRUE;
+ }
+ if (cur->panner.rubber_band != new->panner.rubber_band) {
+ reset_xor_gc (new);
+ if (new->panner.tmp.doing) redisplay = TRUE;
+ }
+
+ if ((cur->panner.stipple_name != new->panner.stipple_name ||
+ cur->panner.shadow_color != new->panner.shadow_color ||
+ cur->core.background_pixel != new->core.background_pixel) &&
+ XtIsRealized(gnew)) {
+ Pixmap pm = (new->panner.stipple_name ? BACKGROUND_STIPPLE (new)
+ : XtUnspecifiedPixmap);
+
+ if (PIXMAP_OKAY(pm)) {
+ XSetWindowBackgroundPixmap (XtDisplay (new), XtWindow(new), pm);
+ XFreePixmap (XtDisplay (new), pm);
+ } else {
+ XSetWindowBackground (XtDisplay (new), XtWindow(new),
+ new->core.background_pixel);
+ }
+ redisplay = TRUE;
+ }
+
+ if (new->panner.resize_to_pref &&
+ (cur->panner.canvas_width != new->panner.canvas_width ||
+ cur->panner.canvas_height != new->panner.canvas_height ||
+ cur->panner.resize_to_pref != new->panner.resize_to_pref)) {
+ get_default_size (new, &new->core.width, &new->core.height);
+ redisplay = TRUE;
+ } else if (cur->panner.canvas_width != new->panner.canvas_width ||
+ cur->panner.canvas_height != new->panner.canvas_height ||
+ cur->panner.internal_border != new->panner.internal_border) {
+ rescale (new); /* does a scale_knob as well */
+ redisplay = TRUE;
+ } else {
+ Boolean loc = (cur->panner.slider_x != new->panner.slider_x ||
+ cur->panner.slider_y != new->panner.slider_y);
+ Boolean siz = (cur->panner.slider_width != new->panner.slider_width ||
+ cur->panner.slider_height != new->panner.slider_height);
+ if (loc || siz ||
+ (cur->panner.allow_off != new->panner.allow_off &&
+ new->panner.allow_off)) {
+ scale_knob (new, loc, siz);
+ redisplay = TRUE;
+ }
+ }
+
+ return redisplay;
+}
+
+static void SetValuesAlmost (gold, gnew, req, reply)
+ Widget gold, gnew;
+ XtWidgetGeometry *req, *reply;
+{
+ if (reply->request_mode == 0) { /* got turned down, so cope */
+ Resize (gnew);
+ }
+ (*pannerWidgetClass->core_class.superclass->core_class.set_values_almost)
+ (gold, gnew, req, reply);
+}
+
+static XtGeometryResult QueryGeometry (gw, intended, pref)
+ Widget gw;
+ XtWidgetGeometry *intended, *pref;
+{
+ PannerWidget pw = (PannerWidget) gw;
+
+ pref->request_mode = (CWWidth | CWHeight);
+ get_default_size (pw, &pref->width, &pref->height);
+
+ if (((intended->request_mode & (CWWidth | CWHeight)) ==
+ (CWWidth | CWHeight)) &&
+ intended->width == pref->width &&
+ intended->height == pref->height)
+ return XtGeometryYes;
+ else if (pref->width == pw->core.width && pref->height == pw->core.height)
+ return XtGeometryNo;
+ else
+ return XtGeometryAlmost;
+}
+
+
+/*****************************************************************************
+ * *
+ * panner action procs *
+ * *
+ *****************************************************************************/
+
+/* ARGSUSED */
+static void ActionStart (gw, event, params, num_params)
+ Widget gw;
+ XEvent *event;
+ String *params; /* unused */
+ Cardinal *num_params; /* unused */
+{
+ PannerWidget pw = (PannerWidget) gw;
+ int x, y;
+
+ if (!get_event_xy (pw, event, &x, &y)) {
+ XBell (XtDisplay(gw), 0); /* should do error message */
+ return;
+ }
+
+ pw->panner.tmp.doing = TRUE;
+ pw->panner.tmp.startx = pw->panner.knob_x;
+ pw->panner.tmp.starty = pw->panner.knob_y;
+ pw->panner.tmp.dx = (((Position) x) - pw->panner.knob_x);
+ pw->panner.tmp.dy = (((Position) y) - pw->panner.knob_y);
+ pw->panner.tmp.x = pw->panner.knob_x;
+ pw->panner.tmp.y = pw->panner.knob_y;
+ if (pw->panner.rubber_band) DRAW_TMP (pw);
+}
+
+/* ARGSUSED */
+static void ActionStop (gw, event, params, num_params)
+ Widget gw;
+ XEvent *event;
+ String *params; /* unused */
+ Cardinal *num_params; /* unused */
+{
+ PannerWidget pw = (PannerWidget) gw;
+ int x, y;
+
+ if (get_event_xy (pw, event, &x, &y)) {
+ pw->panner.tmp.x = ((Position) x) - pw->panner.tmp.dx;
+ pw->panner.tmp.y = ((Position) y) - pw->panner.tmp.dy;
+ if (!pw->panner.allow_off) check_knob (pw, FALSE);
+ }
+ if (pw->panner.rubber_band) UNDRAW_TMP (pw);
+ pw->panner.tmp.doing = FALSE;
+}
+
+/* ARGSUSED */
+static void ActionAbort (gw, event, params, num_params)
+ Widget gw;
+ XEvent *event;
+ String *params; /* unused */
+ Cardinal *num_params; /* unused */
+{
+ PannerWidget pw = (PannerWidget) gw;
+
+ if (!pw->panner.tmp.doing) return;
+
+ if (pw->panner.rubber_band) UNDRAW_TMP (pw);
+
+ if (!pw->panner.rubber_band) { /* restore old position */
+ pw->panner.tmp.x = pw->panner.tmp.startx;
+ pw->panner.tmp.y = pw->panner.tmp.starty;
+ ActionNotify (gw, event, params, num_params);
+ }
+ pw->panner.tmp.doing = FALSE;
+}
+
+
+/* ARGSUSED */
+static void ActionMove (gw, event, params, num_params)
+ Widget gw;
+ XEvent *event; /* must be a motion event */
+ String *params; /* unused */
+ Cardinal *num_params; /* unused */
+{
+ PannerWidget pw = (PannerWidget) gw;
+ int x, y;
+
+ if (!pw->panner.tmp.doing) return;
+
+ if (!get_event_xy (pw, event, &x, &y)) {
+ XBell (XtDisplay(gw), 0); /* should do error message */
+ return;
+ }
+
+ if (pw->panner.rubber_band) UNDRAW_TMP (pw);
+ pw->panner.tmp.x = ((Position) x) - pw->panner.tmp.dx;
+ pw->panner.tmp.y = ((Position) y) - pw->panner.tmp.dy;
+
+ if (!pw->panner.rubber_band) {
+ ActionNotify (gw, event, params, num_params); /* does a check */
+ } else {
+ if (!pw->panner.allow_off) check_knob (pw, FALSE);
+ DRAW_TMP (pw);
+ }
+}
+
+
+/* ARGSUSED */
+static void ActionPage (gw, event, params, num_params)
+ Widget gw;
+ XEvent *event; /* unused */
+ String *params;
+ Cardinal *num_params; /* unused */
+{
+ PannerWidget pw = (PannerWidget) gw;
+ Cardinal zero = 0;
+ Boolean isin = pw->panner.tmp.doing;
+ int x, y;
+ Boolean relx, rely;
+ int pad = pw->panner.internal_border * 2;
+
+ if (*num_params != 2) {
+ XBell (XtDisplay(gw), 0);
+ return;
+ }
+
+ x = parse_page_string (params[0], (int) pw->panner.knob_width,
+ ((int) pw->core.width) - pad, &relx);
+ y = parse_page_string (params[1], (int) pw->panner.knob_height,
+ ((int) pw->core.height) - pad, &rely);
+
+ if (relx) x += pw->panner.knob_x;
+ if (rely) y += pw->panner.knob_y;
+
+ if (isin) { /* if in, then use move */
+ XEvent ev;
+ ev.xbutton.type = ButtonPress;
+ ev.xbutton.x = x;
+ ev.xbutton.y = y;
+ ActionMove (gw, &ev, (String *) NULL, &zero);
+ } else { /* else just do it */
+ pw->panner.tmp.doing = TRUE;
+ pw->panner.tmp.x = x;
+ pw->panner.tmp.y = y;
+ ActionNotify (gw, event, (String *) NULL, &zero);
+ pw->panner.tmp.doing = FALSE;
+ }
+}
+
+
+/* ARGSUSED */
+static void ActionNotify (gw, event, params, num_params)
+ Widget gw;
+ XEvent *event; /* unused */
+ String *params; /* unused */
+ Cardinal *num_params; /* unused */
+{
+ PannerWidget pw = (PannerWidget) gw;
+
+ if (!pw->panner.tmp.doing) return;
+
+ if (!pw->panner.allow_off) check_knob (pw, FALSE);
+ pw->panner.knob_x = pw->panner.tmp.x;
+ pw->panner.knob_y = pw->panner.tmp.y;
+ move_shadow (pw);
+
+ pw->panner.slider_x = (Position) (((double) pw->panner.knob_x) /
+ pw->panner.haspect + 0.5);
+ pw->panner.slider_y = (Position) (((double) pw->panner.knob_y) /
+ pw->panner.vaspect + 0.5);
+ if (!pw->panner.allow_off) {
+ Position tmp;
+
+ if (pw->panner.slider_x >
+ (tmp = (((Position) pw->panner.canvas_width) -
+ ((Position) pw->panner.slider_width))))
+ pw->panner.slider_x = tmp;
+ if (pw->panner.slider_x < 0) pw->panner.slider_x = 0;
+ if (pw->panner.slider_y >
+ (tmp = (((Position) pw->panner.canvas_height) -
+ ((Position) pw->panner.slider_height))))
+ pw->panner.slider_y = tmp;
+ if (pw->panner.slider_y < 0) pw->panner.slider_y = 0;
+ }
+
+ if (pw->panner.last_x != pw->panner.knob_x ||
+ pw->panner.last_y != pw->panner.knob_y) {
+ XawPannerReport rep;
+
+ Redisplay (gw, (XEvent*) NULL, (Region) NULL);
+ rep.changed = (XawPRSliderX | XawPRSliderY);
+ rep.slider_x = pw->panner.slider_x;
+ rep.slider_y = pw->panner.slider_y;
+ rep.slider_width = pw->panner.slider_width;
+ rep.slider_height = pw->panner.slider_height;
+ rep.canvas_width = pw->panner.canvas_width;
+ rep.canvas_height = pw->panner.canvas_height;
+ XtCallCallbackList (gw, pw->panner.report_callbacks, (XtPointer) &rep);
+ }
+}
+
+/* ARGSUSED */
+static void ActionSet (gw, event, params, num_params)
+ Widget gw;
+ XEvent *event; /* unused */
+ String *params;
+ Cardinal *num_params;
+{
+ PannerWidget pw = (PannerWidget) gw;
+ Boolean rb;
+
+ if (*num_params < 2 ||
+ XmuCompareISOLatin1 (params[0], "rubberband") != 0) {
+ XBell (XtDisplay(gw), 0);
+ return;
+ }
+
+ if (XmuCompareISOLatin1 (params[1], "on") == 0) {
+ rb = TRUE;
+ } else if (XmuCompareISOLatin1 (params[1], "off") == 0) {
+ rb = FALSE;
+ } else if (XmuCompareISOLatin1 (params[1], "toggle") == 0) {
+ rb = !pw->panner.rubber_band;
+ } else {
+ XBell (XtDisplay(gw), 0);
+ return;
+ }
+
+ if (rb != pw->panner.rubber_band) {
+ Arg args[1];
+ XtSetArg (args[0], XtNrubberBand, rb);
+ XtSetValues (gw, args, (Cardinal) 1);
+ }
+}
diff --git a/src/Panner.h b/src/Panner.h
new file mode 100644
index 0000000..ed0cdfe
--- /dev/null
+++ b/src/Panner.h
@@ -0,0 +1,108 @@
+/*
+ * $XConsortium: Panner.h,v 1.22 94/04/17 20:12:32 rws Exp $
+ *
+Copyright (c) 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: Jim Fulton, MIT X Consortium
+ */
+
+#ifndef _XawPanner_h
+#define _XawPanner_h
+
+#include <X11/Xaw3d/Reports.h>
+
+/*****************************************************************************
+ *
+ * Panner Widget (subclass of Simple)
+ *
+ * This widget is used to represent navigation in a 2d coordinate system.
+ *
+ * Parameters:
+ *
+ * Name Class Type Default
+ * ---- ----- ---- -------
+ *
+ * allowOff AllowOff Boolean FALSE
+ * background Background Pixel XtDefaultBackground
+ * backgroundStipple BackgroundStipple String NULL
+ * canvasWidth CanvasWidth Dimension 0
+ * canvasHeight CanvasHeight Dimension 0
+ * defaultScale DefaultScale Dimension 8 percent
+ * foreground Foreground Pixel XtDefaultBackground
+ * internalSpace InternalSpace Dimension 4
+ * lineWidth LineWidth Dimension 0
+ * reportCallback ReportCallback XtCallbackList NULL
+ * resize Resize Boolean TRUE
+ * rubberBand RubberBand Boolean FALSE
+ * shadowColor ShadowColor Pixel XtDefaultForeground
+ * shadowThickness ShadowThickness Dimension 2
+ * sliderX SliderX Position 0
+ * sliderY SliderY Position 0
+ * sliderWidth SliderWidth Dimension 0
+ * sliderHeight SliderHeight Dimension 0
+ *
+ *****************************************************************************/
+
+ /* new instance and class names */
+#ifndef _XtStringDefs_h_
+#define XtNresize "resize"
+#define XtCResize "Resize"
+#endif
+
+#define XtNallowOff "allowOff"
+#define XtCAllowOff "AllowOff"
+#define XtNbackgroundStipple "backgroundStipple"
+#define XtCBackgroundStipple "BackgroundStipple"
+#define XtNdefaultScale "defaultScale"
+#define XtCDefaultScale "DefaultScale"
+#define XtNcanvasWidth "canvasWidth"
+#define XtCCanvasWidth "CanvasWidth"
+#define XtNcanvasHeight "canvasHeight"
+#define XtCCanvasHeight "CanvasHeight"
+#define XtNinternalSpace "internalSpace"
+#define XtCInternalSpace "InternalSpace"
+#define XtNlineWidth "lineWidth"
+#define XtCLineWidth "LineWidth"
+#define XtNrubberBand "rubberBand"
+#define XtCRubberBand "RubberBand"
+#define XtNshadowThickness "shadowThickness"
+#define XtCShadowThickness "ShadowThickness"
+#define XtNshadowColor "shadowColor"
+#define XtCShadowColor "ShadowColor"
+#define XtNsliderX "sliderX"
+#define XtCSliderX "SliderX"
+#define XtNsliderY "sliderY"
+#define XtCSliderY "SliderY"
+#define XtNsliderWidth "sliderWidth"
+#define XtCSliderWidth "SliderWidth"
+#define XtNsliderHeight "sliderHeight"
+#define XtCSliderHeight "SliderHeight"
+
+ /* external declarations */
+extern WidgetClass pannerWidgetClass;
+
+typedef struct _PannerClassRec *PannerWidgetClass;
+typedef struct _PannerRec *PannerWidget;
+
+#endif /* _XawPanner_h */
diff --git a/src/PannerP.h b/src/PannerP.h
new file mode 100644
index 0000000..2662929
--- /dev/null
+++ b/src/PannerP.h
@@ -0,0 +1,104 @@
+/*
+ * $XConsortium: PannerP.h,v 1.19 94/04/17 20:12:33 jim Exp $
+ *
+Copyright (c) 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: Jim Fulton, MIT X Consortium
+ */
+
+#ifndef _XawPannerP_h
+#define _XawPannerP_h
+
+#include <X11/Xaw3d/Panner.h>
+#include <X11/Xaw3d/SimpleP.h> /* parent */
+
+typedef struct { /* new fields in widget class */
+ int dummy;
+} PannerClassPart;
+
+typedef struct _PannerClassRec { /* Panner widget class */
+ CoreClassPart core_class;
+ SimpleClassPart simple_class;
+ PannerClassPart panner_class;
+} PannerClassRec;
+
+typedef struct { /* new fields in widget */
+ /* resources... */
+ XtCallbackList report_callbacks; /* callback/Callback */
+ Boolean allow_off; /* allowOff/AllowOff */
+ Boolean resize_to_pref; /* resizeToPreferred/Boolean */
+ Pixel foreground; /* foreground/Foreground */
+ Pixel shadow_color; /* shadowColor/ShadowColor */
+ Dimension shadow_thickness; /* shadowThickness/ShadowThickness */
+ Dimension default_scale; /* defaultScale/DefaultScale */
+ Dimension line_width; /* lineWidth/LineWidth */
+ Dimension canvas_width; /* canvasWidth/CanvasWidth */
+ Dimension canvas_height; /* canvasHeight/CanvasHeight */
+ Position slider_x; /* sliderX/SliderX */
+ Position slider_y; /* sliderY/SliderY */
+ Dimension slider_width; /* sliderWidth/SliderWidth */
+ Dimension slider_height; /* sliderHeight/SliderHeight */
+ Dimension internal_border; /* internalBorderWidth/BorderWidth */
+ String stipple_name; /* backgroundStipple/BackgroundStipple */
+ /* private data... */
+ GC slider_gc; /* background of slider */
+ GC shadow_gc; /* edge of slider and shadow */
+ GC xor_gc; /* for doing XOR tmp graphics */
+ double haspect, vaspect; /* aspect ratio of core to canvas */
+ Boolean rubber_band; /* true = rubber band, false = move */
+ struct {
+ Boolean doing; /* tmp graphics in progress */
+ Boolean showing; /* true if tmp graphics displayed */
+ Position startx, starty; /* initial position of slider */
+ Position dx, dy; /* offset loc for tmp graphics */
+ Position x, y; /* location for tmp graphics */
+ } tmp;
+ Position knob_x, knob_y; /* real upper left of knob in canvas */
+ Dimension knob_width, knob_height; /* real size of knob in canvas */
+ Boolean shadow_valid; /* true if rects are valid */
+ XRectangle shadow_rects[2]; /* location of shadows */
+ Position last_x, last_y; /* previous location of knob */
+} PannerPart;
+
+typedef struct _PannerRec {
+ CorePart core;
+ SimplePart simple;
+ PannerPart panner;
+} PannerRec;
+
+#define PANNER_HSCALE(pw,val) ((pw)->panner.haspect * ((double) (val)))
+#define PANNER_VSCALE(pw,val) ((pw)->panner.vaspect * ((double) (val)))
+
+#define PANNER_DSCALE(pw,val) (Dimension) \
+ ((((unsigned long) (val)) * (unsigned long) pw->panner.default_scale) / 100L)
+#define PANNER_DEFAULT_SCALE 8 /* percent */
+
+#define PANNER_OUTOFRANGE -30000
+
+/*
+ * external declarations
+ */
+extern PannerClassRec pannerClassRec;
+
+#endif /* _XawPannerP_h */
diff --git a/src/Porthole.c b/src/Porthole.c
new file mode 100644
index 0000000..56ea9a8
--- /dev/null
+++ b/src/Porthole.c
@@ -0,0 +1,366 @@
+/*
+ * $XConsortium: Porthole.c,v 1.16 94/04/17 20:12:34 kaleb Exp $
+ *
+Copyright (c) 1990, 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.
+ *
+ * Author: Jim Fulton, MIT X Consortium
+ *
+ * This widget is a trivial clipping widget. It is typically used with a
+ * panner or scrollbar to navigate.
+ */
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h> /* get XtN and XtC defines */
+#include <X11/Xaw3d/XawInit.h> /* get Xaw initialize stuff */
+#include <X11/Xaw3d/PortholeP.h> /* get porthole structs */
+#include <X11/Xmu/Misc.h> /* for MAX */
+
+
+/*
+ * resources for the porthole
+ */
+static XtResource resources[] = {
+#define poff(field) XtOffsetOf(PortholeRec, porthole.field)
+ { XtNreportCallback, XtCReportCallback, XtRCallback, sizeof(XtPointer),
+ poff(report_callbacks), XtRCallback, (XtPointer) NULL },
+#undef poff
+};
+
+
+/*
+ * widget class methods used below
+ */
+static void Realize(); /* set gravity and upcall */
+static void Resize(); /* report new size */
+static XtGeometryResult GeometryManager(); /* deal with child requests */
+static void ChangeManaged(); /* somebody added a new widget */
+static XtGeometryResult QueryGeometry(); /* say how big would like to be */
+
+PortholeClassRec portholeClassRec = {
+ { /* core fields */
+ /* superclass */ (WidgetClass) &compositeClassRec,
+ /* class_name */ "Porthole",
+ /* widget_size */ sizeof(PortholeRec),
+ /* class_initialize */ XawInitializeWidgetSet,
+ /* class_part_initialize */ NULL,
+ /* class_inited */ FALSE,
+ /* initialize */ NULL,
+ /* initialize_hook */ NULL,
+ /* realize */ Realize,
+ /* 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 */ NULL,
+ /* resize */ Resize,
+ /* expose */ NULL,
+ /* set_values */ NULL,
+ /* 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
+ },
+ { /* composite fields */
+ /* geometry_manager */ GeometryManager,
+ /* change_managed */ ChangeManaged,
+ /* insert_child */ XtInheritInsertChild,
+ /* delete_child */ XtInheritDeleteChild,
+ /* extension */ NULL
+ },
+ { /* porthole fields */
+ /* ignore */ 0
+ }
+};
+
+WidgetClass portholeWidgetClass = (WidgetClass) &portholeClassRec;
+
+
+/*****************************************************************************
+ * *
+ * utility routines *
+ * *
+ *****************************************************************************/
+
+static Widget find_child (pw)
+ PortholeWidget pw;
+{
+ Widget *children;
+ int i;
+
+ /*
+ * Find the managed child on which we should operate. Ignore multiple
+ * managed children.
+ */
+ for (i = 0, children = pw->composite.children;
+ i < pw->composite.num_children; i++, children++) {
+ if (XtIsManaged(*children)) return *children;
+ }
+
+ return (Widget) NULL;
+}
+
+static void SendReport (pw, changed)
+ PortholeWidget pw;
+ unsigned int changed;
+{
+ Widget child = find_child (pw);
+
+ if (pw->porthole.report_callbacks && child) {
+ XawPannerReport prep;
+
+ prep.changed = changed;
+ prep.slider_x = -child->core.x; /* porthole is "inner" */
+ prep.slider_y = -child->core.y; /* child is outer since it is larger */
+ prep.slider_width = pw->core.width;
+ prep.slider_height = pw->core.height;
+ prep.canvas_width = child->core.width;
+ prep.canvas_height = child->core.height;
+ XtCallCallbackList ((Widget)pw, pw->porthole.report_callbacks,
+ (XtPointer) &prep);
+ }
+}
+
+
+static void layout_child (pw, child, geomp, xp, yp, widthp, heightp)
+ PortholeWidget pw;
+ Widget child;
+ XtWidgetGeometry *geomp;
+ Position *xp, *yp;
+ Dimension *widthp, *heightp;
+{
+ Position minx, miny;
+
+ *xp = child->core.x; /* default to current values */
+ *yp = child->core.y;
+ *widthp = child->core.width;
+ *heightp = child->core.height;
+ if (geomp) { /* mix in any requested changes */
+ if (geomp->request_mode & CWX) *xp = geomp->x;
+ if (geomp->request_mode & CWY) *yp = geomp->y;
+ if (geomp->request_mode & CWWidth) *widthp = geomp->width;
+ if (geomp->request_mode & CWHeight) *heightp = geomp->height;
+ }
+
+ /*
+ * Make sure that the child is at least as large as the porthole; there
+ * is no maximum size.
+ */
+ if (*widthp < pw->core.width) *widthp = pw->core.width;
+ if (*heightp < pw->core.height) *heightp = pw->core.height;
+
+ /*
+ * Make sure that the child is still on the screen. Note that this must
+ * be done *after* the size computation so that we know where to put it.
+ */
+ minx = ((Position) pw->core.width) - ((Position) *widthp);
+ miny = ((Position) pw->core.height) - ((Position) *heightp);
+
+ if (*xp < minx) *xp = minx; /* keep at lower right corner */
+ if (*yp < miny) *yp = miny;
+
+ if (*xp > 0) *xp = 0; /* keep at upper left corner */
+ if (*yp > 0) *yp = 0;
+}
+
+
+
+/*****************************************************************************
+ * *
+ * Porthole Widget Class Methods *
+ * *
+ *****************************************************************************/
+
+
+static void Realize (gw, valueMask, attributes)
+ Widget gw;
+ Mask *valueMask;
+ XSetWindowAttributes *attributes;
+{
+ attributes->bit_gravity = NorthWestGravity;
+ *valueMask |= CWBitGravity;
+
+ if (gw->core.width < 1) gw->core.width = 1;
+ if (gw->core.height < 1) gw->core.height = 1;
+ (*portholeWidgetClass->core_class.superclass->core_class.realize)
+ (gw, valueMask, attributes);
+}
+
+
+static void Resize (gw)
+ Widget gw;
+{
+ PortholeWidget pw = (PortholeWidget) gw;
+ Widget child = find_child (pw);
+
+ /*
+ * If we have a child, we need to make sure that it is at least as big
+ * as we are and in the right place.
+ */
+ if (child) {
+ Position x, y;
+ Dimension width, height;
+
+ layout_child (pw, child, (XtWidgetGeometry *)NULL,
+ &x, &y, &width, &height);
+ XtConfigureWidget (child, x, y, width, height, (Dimension) 0);
+ }
+
+ SendReport (pw, (unsigned int) (XawPRCanvasWidth | XawPRCanvasHeight));
+}
+
+
+static XtGeometryResult QueryGeometry (gw, intended, preferred)
+ Widget gw;
+ XtWidgetGeometry *intended, *preferred;
+{
+ PortholeWidget pw = (PortholeWidget) gw;
+ Widget child = find_child (pw);
+
+ if (child) {
+#define SIZEONLY (CWWidth | CWHeight)
+ preferred->request_mode = SIZEONLY;
+ preferred->width = child->core.width;
+ preferred->height = child->core.height;
+
+ if (((intended->request_mode & SIZEONLY) == SIZEONLY) &&
+ intended->width == preferred->width &&
+ intended->height == preferred->height)
+ return XtGeometryYes;
+ else if (preferred->width == pw->core.width &&
+ preferred->height == pw->core.height)
+ return XtGeometryNo;
+ else
+ return XtGeometryAlmost;
+#undef SIZEONLY
+ }
+ return XtGeometryNo;
+}
+
+
+static XtGeometryResult GeometryManager (w, req, reply)
+ Widget w;
+ XtWidgetGeometry *req, *reply;
+{
+ PortholeWidget pw = (PortholeWidget) w->core.parent;
+ Widget child = find_child (pw);
+ Boolean okay = TRUE;
+
+ if (child != w) return XtGeometryNo; /* unknown child */
+
+ *reply = *req; /* assume we'll grant everything */
+
+ if ((req->request_mode & CWBorderWidth) && req->border_width != 0) {
+ reply->border_width = 0; /* require border width of 0 */
+ okay = FALSE;
+ }
+
+ layout_child (pw, child, req, &reply->x, &reply->y,
+ &reply->width, &reply->height);
+
+ if ((req->request_mode & CWX) && req->x != reply->x) okay = FALSE;
+ if ((req->request_mode & CWY) && req->x != reply->x) okay = FALSE;
+ if ((req->request_mode & CWWidth) && req->width != reply->width)
+ okay = FALSE;
+ if ((req->request_mode & CWHeight) && req->height != reply->height)
+ okay = FALSE;
+
+
+ /*
+ * If we failed on anything, simply return without touching widget
+ */
+ if (!okay) return XtGeometryAlmost;
+
+ /*
+ * If not just doing a query, update widget and send report. Note that
+ * we will often set fields that weren't requested because we want to keep
+ * the child visible.
+ */
+ if (!(req->request_mode & XtCWQueryOnly)) {
+ unsigned int changed = 0;
+
+ if (child->core.x != reply->x) {
+ changed |= XawPRSliderX;
+ child->core.x = reply->x;
+ }
+ if (child->core.y != reply->y) {
+ changed |= XawPRSliderY;
+ child->core.y = reply->y;
+ }
+ if (child->core.width != reply->width) {
+ changed |= XawPRSliderWidth;
+ child->core.width = reply->width;
+ }
+ if (child->core.height != reply->height) {
+ changed |= XawPRSliderHeight;
+ child->core.height = reply->height;
+ }
+ if (changed) SendReport (pw, changed);
+ }
+
+ return XtGeometryYes; /* success! */
+}
+
+
+static void ChangeManaged (gw)
+ Widget gw;
+{
+ PortholeWidget pw = (PortholeWidget) gw;
+ Widget child = find_child (pw); /* ignore extra children */
+
+ if (child) {
+ if (!XtIsRealized (gw)) {
+ XtWidgetGeometry geom, retgeom;
+
+ geom.request_mode = 0;
+ if (pw->core.width == 0) {
+ geom.width = child->core.width;
+ geom.request_mode |= CWWidth;
+ }
+ if (pw->core.height == 0) {
+ geom.height = child->core.height;
+ geom.request_mode |= CWHeight;
+ }
+ if (geom.request_mode &&
+ XtMakeGeometryRequest (gw, &geom, &retgeom) == XtGeometryAlmost) {
+ (void) XtMakeGeometryRequest (gw, &retgeom, (XtWidgetGeometry *)NULL);
+ }
+ }
+
+ XtResizeWidget (child, Max (child->core.width, pw->core.width),
+ Max (child->core.height, pw->core.height), 0);
+
+ SendReport (pw, (unsigned int) XawPRAll);
+ }
+}
diff --git a/src/Porthole.h b/src/Porthole.h
new file mode 100644
index 0000000..18cac79
--- /dev/null
+++ b/src/Porthole.h
@@ -0,0 +1,64 @@
+/*
+ * $XConsortium: Porthole.h,v 1.2 94/04/17 20:12:35 jim Exp $
+ *
+Copyright (c) 1990 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: Jim Fulton, MIT X Consortium
+ */
+
+#ifndef _XawPorthole_h
+#define _XawPorthole_h
+
+#include <X11/Xaw3d/Reports.h>
+
+/*****************************************************************************
+ *
+ * Porthole Widget (subclass of Composite)
+ *
+ * This widget is similar to a viewport without scrollbars. Child movement
+ * is done by external panners or scrollbars.
+ *
+ * Parameters:
+ *
+ * Name Class Type Default
+ * ---- ----- ---- -------
+ *
+ * background Background Pixel XtDefaultBackground
+ * border BorderColor Pixel XtDefaultForeground
+ * borderWidth BorderWidth Dimension 1
+ * height Height Dimension 0
+ * reportCallback ReportCallback Pointer NULL
+ * width Width Dimension 0
+ * x Position Position 0
+ * y Position Position 0
+ *
+ *****************************************************************************/
+
+ /* external declarations */
+
+extern WidgetClass portholeWidgetClass;
+typedef struct _PortholeClassRec *PortholeWidgetClass;
+typedef struct _PortholeRec *PortholeWidget;
+
+#endif /* _XawPorthole_h */
diff --git a/src/PortholeP.h b/src/PortholeP.h
new file mode 100644
index 0000000..2c1d586
--- /dev/null
+++ b/src/PortholeP.h
@@ -0,0 +1,65 @@
+/*
+ * $XConsortium: PortholeP.h,v 1.3 94/04/17 20:12:36 kaleb Exp $
+ *
+Copyright (c) 1990, 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.
+ *
+ * Author: Jim Fulton, MIT X Consortium
+ */
+
+#ifndef _XawPortholeP_h
+#define _XawPortholeP_h
+
+#include <X11/Xaw3d/Porthole.h>
+
+typedef struct { /* new fields in widget class */
+ int dummy;
+} PortholeClassPart;
+
+typedef struct _PortholeClassRec { /* Porthole widget class */
+ CoreClassPart core_class;
+ CompositeClassPart composite_class;
+ PortholeClassPart porthole_class;
+} PortholeClassRec;
+
+
+typedef struct { /* new fields in widget */
+ /* resources... */
+ XtCallbackList report_callbacks; /* callback/Callback */
+ /* private data... */
+} PortholePart;
+
+typedef struct _PortholeRec {
+ CorePart core;
+ CompositePart composite;
+ PortholePart porthole;
+} PortholeRec;
+
+
+/*
+ * external declarations
+ */
+extern PortholeClassRec portholeClassRec;
+
+
+#endif /* _XawPortholeP_h */
diff --git a/src/README.XAW3D b/src/README.XAW3D
new file mode 100644
index 0000000..f77be1b
--- /dev/null
+++ b/src/README.XAW3D
@@ -0,0 +1,544 @@
+
+ The Three-D Athena Toolkit (Xaw3d)
+ ----------------------------------
+
+ This is Release 1.5E of the Xaw3d toolkit (dated March 8, 2003), an
+ update that fixes some bugs, and adds many features. There were no
+ public releases of 1.5A through 1.5D.
+
+ I am not Kaleb Keithley. Kaleb has moved on, and no longer supports
+ Xaw3d; it's my baby now. This distribution is not a fork - it is the
+ latest update of the One True Xaw3d.
+
+ While not as insistant as Kaleb was, I do suggest you include this
+ file, as is, with any product that includes Xaw3d, in whole or in
+ part, in any form. This file is the authoritative documentation for
+ Xaw3d.
+
+ If you discover bugs not already known, do not contact Kaleb; he's had
+ no part in this effort. Feel free to contact me; I'll try to respond
+ in kind. If you're new to the Athena toolkit, understand that it is
+ highly configurable, and some resources will interact (or not) with
+ undesirable results. Some of these are bugs, but many are just the
+ nature of the beast.
+
+ D. J. Hawkey Jr.
+ _________________________________________________________________
+
+ Usage:
+ ------
+
+ This release of Xaw3d is based on X.Org's X11R6.3 Athena toolkit, with
+ bits and pieces thrown in from other sources. It is intended to be a
+ general-purpose replacement for the Athena (Xaw) toolkit.
+
+ In general, you should be able to link almost any Athena-based
+ application to this Xaw3d Athena toolkit, for a three-dimensional
+ appearance on most of the widgets. On systems with shared libraries,
+ you might be able replace your shared libXaw.* with libXaw3d.* to
+ obtain the appearance without even relinking, but the odds of this
+ working is slim, and not recommended.
+
+ Applications written for Xaw3d might have to test the library for a
+ particular feature (see the "Xaw3d build options" section below). To
+ accomodate this, a private header is installed which reflects the
+ library's capabilities. Xaw3dP.h contains four definitions that may be
+ used for this purpose. For example:
+
+ #define XAW_INTERNATIONALIZATION
+ #define XAW_MULTIPLANE_PIXMAPS
+ #define XAW_GRAY_BLKWHT_STIPPLES
+ #undef XAW_ARROW_SCROLLBARS
+
+ Xaw3dP.h need not be included by the application source, as the public
+ headers that reference any 3D features include this header. The
+ default configuration is set up to match the capabilities of X.Org's
+ Xaw toolkit.
+
+ The use of most shadow resources should be intuitive enough, and may
+ be set or read conventionally (e.g., resource files, editres,
+ programatically, etc.). The userData resource may be used to "hang"
+ application-specific data on a widget, but this is accessable to
+ programs only. Other resources and less-than-obvious features are
+ documented throughout this file.
+
+ The default resource values present a not-as-pretty-as-it-could-be
+ appearance, due to stippled shadows (as opposed to allocated colors)
+ in order to conserve colormap space, and by allowing non-rectangular
+ pushbuttons, which are not shadowed. To specify otherwise, set these
+ resources:
+
+ *beNiceToColormap: False
+ *shapeStyle: Rectangle
+
+ You might also want to remove the borders from some widgets:
+
+ *Text.borderWidth: 0
+ *SimpleMenu.borderWidth: 0
+ *Paned.internalBorderWidth: 0
+
+ To revert to reverse-video highlighting in menus:
+
+ *SmeBSB.shadowWidth: 0
+
+ Note that shadows "grow outward" in the SimpleMenu and Text widgets,
+ increasing these widgets' sizes, "grow inward" in the Viewport and
+ Scrollbar widgets, decreasing the size of the clip widget and thumb,
+ respectively, and "grow inward" in the Label (and superclasses of) and
+ SmeBSB widgets, encroaching on their label parts. Fat shadows will
+ probably mean some futzing with size or margin resources for a proper
+ appearance.
+ _________________________________________________________________
+
+ Xaw3d build requirements:
+ -------------------------
+
+ Many header files have changed since Release 1.5. This means that any
+ installed Xaw3d headers must be removed before building this
+ distribution, to see that these source files include these header
+ files. Renaming the directory that the existing headers live in is
+ sufficient.
+
+ Xaw3d build options:
+ --------------------
+
+ Like Xaw, the default Xaw3d does not accomodate multi-plane pixmaps.
+ However, at the top of this distribution's Imakefile are the lines:
+
+ XCOMM For color pixmaps, define MULTIPLANE_PIXMAPS:
+ #undef MULTIPLANE_PIXMAPS
+
+ If you want color pixmaps, and have Arnaud Le Hors's XPM library
+ installed, change the "#undef" to "#define". You may then specify
+ either XPM or XBM files for any Xaw3d bitmap resource, whether by
+ resource files, with editres, programmatically, etc.. And yes, the
+ transparency of XPM files is honored.
+
+ Note that this enables the use of structures and functions in the XPM
+ library; the XPM library include file (xpm.h) must be available when
+ building Xaw3d, and the XPM library must then be linked to any and all
+ applications that use Xaw3d. This makes Xaw3d dependant on the XPM
+ library, so think twice about it.
+
+ The default stippled shadows used when the beNiceToColormap resource
+ is True work well enough, except for widgets that have black or white
+ backgrounds. So, at the top of this distribution's Imakefile, are the
+ lines:
+
+ XCOMM For grayed stipple shadows, define GRAY_BLKWHT_STIPPLES:
+ #define GRAY_BLKWHT_STIPPLES
+
+ This makes Xaw3d allocate a gray colorcell, and use it in stippled
+ shadows when 1) widgets have black or white backgrounds and 2) the
+ beNiceToColormap resource is True and 3) the display allows it. This
+ option was disabled in previous Xaw3d releases.
+
+ The default Xaw3d does not use arrow scrollbars. At the top of this
+ distribution's Imakefile are the lines:
+
+ XCOMM For scrollbars with arrows, define ARROW_SCROLLBARS:
+ #undef ARROW_SCROLLBARS
+
+ If you want arrow-style scrollbars, change the "#undef" to "#define".
+ Note that the Scrollbar widget's translations and actions will change
+ accordingly.
+
+ Building Xaw3d within an X11 source tree:
+ -----------------------------------------
+
+ This distribution expects a configured X11R6.[1-6] source tree (by
+ "configured", I mean that the imake infrastructure has been built).
+ You can use the source from X.Org, XFree86, or the X Project Team.
+
+ Change to the directory containing /xc, and issue these commands:
+
+ # gunzip -c Xaw3d-1.5E.tar.gz | tar -xpf -
+ # cd xc/lib/Xaw3d
+ # ../../config/imake/imake -I../../config/cf \
+ -DTOPDIR=../.. -DCURDIR=lib/Xaw3d
+ # make includes; make depend; make; make install
+
+ The Imakefile uses the Xaw symbols in /xc/config/cf, so if you have
+ debug, shared, profile, etc. libraries specified for Xaw, Xaw3d will
+ have them as well.
+
+ Building Xaw3d without an X11 source tree:
+ ------------------------------------------
+
+ Near the top of this distribution's Imakefile are the lines:
+
+ XCOMM When building outside an X11 source tree:
+ XCOMM EXTRA_INCLUDES = -I.
+
+ Uncomment the second line by deleting the "XCOMM ". Then, while still
+ in /xc/lib/Xaw3d, issue these commands:
+
+ # mkdir X11; cd X11; ln -fs .. Xaw3d; cd ..
+ # xmkmf; make depend; make; make install
+
+ If this works for you, great. If not, well, happy hacking.
+
+ Building Xaw3d under X11R5:
+ ---------------------------
+
+ I don't know that Xaw3d will build within an X11R5 source tree, so try
+ the "Building Xaw3d without an X11 source tree" instructions. If the
+ "make" command results in nothing being built, find these lines about
+ half-way into this distribution's Imakefile:
+
+ XCOMM At least one X11R5 distribution needs this:
+ XCOMM #include "Imakefrag.X11R5"
+
+ Uncomment the second line by deleting the "XCOMM ", and re-issue the
+ "xmkmf; make depend; make; make install" commands. This line will
+ insert the quoted file into the Makefile, and is for when the imake
+ configuration files don't create the appropriate rules.
+
+ Xaw3d and Internationalization:
+ -------------------------------
+
+ The Imakefile depends on a conventional system-wide definition for
+ including or omitting I18n support (i.e., "XawI18nDefines"). If the
+ Imakefile erroneously disables support for I18n (see the generated
+ Xaw3dP.h file), I can only suggest searching your imake configuration
+ files for a definition that enables support for "wide characters" (try
+ `egrep 'WCHAR|WCTYPE|XMBTOWC|ISW_FUNCS' *`), and then, about half-way
+ into this distribution's Imakefile, find these lines:
+
+ #ifdef XawI18nDefines
+ #define INTERNATIONALIZATION
+ HEADERS = $(BASE_HDRS) $(I18N_HDRS)
+ SRCS = $(BASE_SRCS) $(I18N_SRCS)
+ OBJS = $(BASE_OBJS) $(I18N_OBJS)
+ ...
+
+ Change the label in the first line to the label of the definition you
+ found. If no suitable definition is found, and I18n really is
+ supported, it's likely implemented in such a way that Xaw3d probably
+ won't include I18n support without some hacking at the Imakefile or
+ Makefile.
+ _________________________________________________________________
+
+ New in 1.5A:
+ ------------
+
+ The SimpleMenu widget now supports scrolling through entries too
+ numerous to fit on the screen, with a new resource supporting a scroll
+ jump value. The record variable is simple_menu.jump_val, resourced as
+ XtNjumpScroll, and classed as XtCJumpScroll. Adapted from an early
+ neXtaw toolkit.
+
+ Added 3D support to the SimpleMenu, Text, and Viewport widgets.
+
+ Four minor changes in ThreeD.c and SmeThreeD.c to have the widgets use
+ the app's colormap, rather than the screen's default, for those apps
+ that create their own.
+
+ Added the deletion of laygram.h to the Imakefile.
+
+ Created Xaw3dP.c, for functions shared by other modules that have no
+ other appropriate home.
+
+ A new directory containing sample resource files for a few apps. See
+ the README.AD file in that directory.
+
+ New in 1.5B:
+ ------------
+
+ Made Imakefile a bit more friendly to build options. Makefile now
+ defines the build options in Xaw3dP.h during the build.
+
+ Added to the key translation tables in Panner.c and TextTr.c, and some
+ rules to Imakefile, to make this distribution X11R5 compliant. Tested
+ on exactly one X11R5 system; your mileage may vary.
+
+ Made internationalization support conditional, for systems lacking or
+ broken. Tested on exactly two systems, one with and one without; your
+ mileage may vary.
+
+ New in 1.5C:
+ ------------
+
+ Enabled multi-plane pixmap support with a new Xt resource type
+ converter. The "Xaw3d build options" section has more information.
+
+ Added private Pixmap resources to the Label and SmeBSB widgets for
+ stippled copies of the public Pixmap resources (record variables
+ label.stippled, label.right_stippled, sme_bsb.left_stippled, and
+ sme_bsb.right_stippled, respectively). Insensitive pixmaps are now
+ rendered properly.
+
+ New in 1.5D:
+ ------------
+
+ Added two resources to the SimpleMenu widget for setting margins. The
+ SmeBSB widgets have a tighter relationship with their parent and
+ siblings; menus and their entries now respond properly to changes in
+ themselves or their parent. See the section "The SimpleMenu widget and
+ margins" below for a detailed explanation.
+
+ New in 1.5E:
+ ------------
+
+ Enabled a new resource in the ThreeD widget to specify one of five
+ shadow types. The record variable is threeD.relief (the record part is
+ transparent), resourced as XtNRelief and classed as XtCRelief. It
+ accepts as values XtReliefNone, XtReliefRaised, XtReliefSunken,
+ XtReliefRidge, and XtReliefGroove. Note that the Text, SimpleMenu,
+ Scrollbar, and Viewport widgets ignore this resource, and display only
+ raised or sunken shadows. Built on the unfinished work of an early
+ neXtaw toolkit.
+
+ Added support for sub-menus in the SimpleMenu widget. Inspired by the
+ xfig application, adapted from XFree86's X11R6.6 "Xaw7" toolkit, and
+ made better than both. See the section "The SimpleMenu widget and
+ sub-menus" below for usage.
+
+ Added a resource to the SmeBSB widget to specify an underlined
+ character in the label. The record variable is sme_bsb.underline,
+ resourced as XtNunderline, and classed as XtCUnderline. It accepts an
+ integer as an index to the character; a value less than zero or
+ greater than or equal to the label length inhibits underlining.
+ Adapted from a recent distribution of the xfig application.
+
+ Made the SmeThreeD widget sensitive to the GRAY_BLKWHT_STIPPLES build
+ option (see the "Xaw3d build options" section for what this is and
+ does).
+
+ Added support for "tooltips". Inspired by the xfig application and
+ adapted from XFree86's X11R6.6 "Xaw7" toolkit. See the section "The
+ Tip widget" below for usage.
+
+ Fixed some geometry and positioning bugs in the Label widget. It's
+ internalHeight and internalWidth resources are now used to enforce a
+ minimum size when it's resize resource is True. The Label (and
+ superclasses of) widget now resizes properly to changes in label parts
+ and internal margins (subject to any constraints placed on the
+ widgets, of course).
+
+ Swapped the top and bottom colors in the stippled pixmap shadows.
+
+ Fixed a shadow drawing bug in the Command widget, when the shape is
+ changed.
+
+ Fixed the shadow state bug in the SmeBSB widget.
+
+ Dropped support for Linux shared a.out libraries.
+ _________________________________________________________________
+
+ Bugs and deficiencies:
+ ----------------------
+
+ You may not be be able to replace shared libXaw.* libraries with
+ libXaw3d.* libraries on systems with SVR3-style shared libraries.
+
+ The lexer in the Layout widget doesn't work well when a program that
+ uses the Layout widget is linked with GNU's malloc(). This is a
+ problem on older releases of Linux, where the libc malloc() is is GNU
+ malloc(). It's also a problem on older releases of FreeBSD if
+ "ExtraLibraries -lgnumalloc" is specified in imake's FreeBSD.cf
+ configuration file (this may be a problem on other BSDs too, but I
+ don't know this as fact). The solution under FreeBSD is to delete the
+ "ExtraLibraries" line(s) in the vendor.cf configuration file, or edit
+ the Makefile to not link with "-lgnumalloc". I don't have a solution
+ for older Linux distributions, nor do I have the time (or inclination)
+ to figure one out. If you discover a fix, you're more than welcome to
+ send it in.
+
+ The samples in Layout.h are wrong and don't work. Example programs
+ written by Keith Packard that use the Layout widget are available at
+ ftp://ftp.x.org/R5contrib/.
+
+ If an application subclasses Athena's Simple or Sme classes, or
+ subclasses thereof, there is a high probability that Xaw3d isn't
+ source compatible. Sorry, I have no plans (or ideas) on how to fix
+ this.
+
+ Xaw3d pixel allocation may not behave well when beNiceToColormap is
+ False and the colormap (default or application) is full.
+
+ Non-rectangular Command widgets are not rendered with shadows.
+
+ All geometry management routines should fully account for shadow
+ widths, but some don't, and it can show.
+
+ A few bugs and ambiguities in the Athena toolkit from which this
+ distribution is derived have been resolved. While trying to be true to
+ Athena documentation, these changes may make Xaw3d behave oddly for
+ some applications. Nothing that can't be fixed by tweaking the
+ appropriate resources, I'll wager.
+
+ A comment that appears in the xterm source:
+ -------------------------------------------
+
+ *
+ * ...There be serious and nasty dragons here.
+ *
+
+ xterm is, well, xterm. The auto-scroll with arrow-style scrollbars
+ won't work in xterm because it relies on timeouts. xterm, perhaps for
+ speed, circumvents XtAppNextEvent() by using XNextEvent() to get its X
+ events, with the unfortunate side effect of completely ignoring "other
+ sources", like timeouts. At this time there is no patch to fix the
+ X11R6 xterm, but there is a patch for the X11R5 xterm at
+ ftp://ftp.x.org/contrib/widgets/Xaw3d/R5/; it shouldn't be too hard to
+ integrate it into the X11R6 sources.
+ _________________________________________________________________
+
+ The SimpleMenu widget and margins:
+ ----------------------------------
+
+ Two resources have been added to the SimpleMenu widget for margin
+ management. The record variables are simple_menu.left_whitespace and
+ simple_menu.right_whitespace, resourced as XtNleftWhitespace and
+ XtNrightWhitespace, and classed as - yup - XtCLeftWhitespace and
+ XtCRightWhitespace. They can be also be referenced together by the
+ class XtCHorizontalWhitespace.
+
+ To illustrate, the leftMargin resource can be different values in each
+ SmeBSB widget, and SimpleMenu will oblige. If a pixmap wider than the
+ margin is specified in any SmeBSB widget, the result is less than
+ desirable (refer to ORA X, Vol 5 Sec 6, SmeBSB.*Bitmap and
+ SmeBSB.*Margin). Set the leftWhitespace resource in the parent
+ SimpleMenu widget, and SimpleMenu will set all children SmeBSB
+ leftMargins to that value. Specify a pixmap of any width for any
+ SmeBSB child, and SimpleMenu will separate the elements (menu edge,
+ pixmap, and text) of all SmeBSB children with that minimum distance as
+ it vertically aligns their text elements.
+
+ The SimpleMenu widget now resizes not only to the above, but also to
+ changes in these SmeBSB traits: Labels and fonts, pixmaps, and
+ margins.
+
+ Implementation notes: The SimpleMenu *Whitespace resources override
+ and replace the values of SmeBSB *Margin resources. To nullify this
+ behavior, a *Whitespace resource must first be set to zero, and the
+ corresponding *Margin resources then set appropriately. The *Margin
+ resources remain unchanged in and of themselves; they behave just as
+ always when the *Whitespace resources are not used.
+
+ The SimpleMenu widget and sub-menus:
+ ------------------------------------
+
+ Resources have been added to the SimpleMenu and SmeBSB widgets to
+ support sub-menus. The record variables are simple_menu.sub_menu and
+ simple_menu.state (neither are public), and sme_bsb.menu_name, which
+ is resourced as XtNmenuName, and classed as XtCMenuName. It's the
+ latter resource that is used by an application, and by default it is
+ NULL; menus behave as they always have. When this resource is set to a
+ menu name, the parent SimpleMenu widget will use the SmeBSB widget as
+ the entry point to a child SimpleMenu widget, managing it's visibility
+ and location. No constraints are placed on focus or the pointer.
+ Consider this code fragment:
+
+ /* create a menu button */
+ opsbutton = XtCreateManagedWidget("ops", menuButtonWidgetClass,
+ parent, NULL, 0);
+
+ /* create a menu for the button */
+ opsmenu = XtCreatePopupShell("opsMenu", simpleMenuWidgetClass,
+ opsbutton, NULL, 0);
+ XtSetArg(args[0], XtNmenuName, "fileMenu");
+ XtSetArg(args[1], XtNrightBitmap, rightArrow);
+ filebutton = XtCreateManagedWidget("file", smeBSBObjectClass,
+ opsmenu, args, 2);
+ XtSetArg(args[0], XtNmenuName, "pageMenu");
+ XtSetArg(args[1], XtNrightBitmap, rightArrow);
+ pagebutton = XtCreateManagedWidget("page", smeBSBObjectClass,
+ opsmenu, args, 2);
+ quitbutton = XtCreateManagedWidget("quit", smeBSBObjectClass,
+ opsmenu, NULL, 0);
+
+ /* create a sub-menu for the first menu item */
+ filemenu = XtCreatePopupShell("fileMenu", simpleMenuWidgetClass,
+ opsmenu, NULL, 0);
+ openbutton = XtCreateManagedWidget("open", smeBSBObjectClass,
+ filemenu, NULL, 0);
+ printbutton = XtCreateManagedWidget("print", smeBSBObjectClass,
+ filemenu, NULL, 0);
+
+ /* create a sub-menu for the second menu item */
+ pagemenu = XtCreatePopupShell("pageMenu", simpleMenuWidgetClass,
+ opsmenu, NULL, 0);
+ prevbutton = XtCreateManagedWidget("prev", smeBSBObjectClass,
+ pagemenu, NULL, 0);
+ nextbutton = XtCreateManagedWidget("next", smeBSBObjectClass,
+ pagemenu, NULL, 0);
+
+ The SimpleMenu widget named "opsMenu" will inherit the SimpleMenu
+ widgets named "fileMenu" and "pageMenu" as children sub-menus. It will
+ position the first sub-menu next to the SmeBSB widget named "file",
+ and the second next to the SmeBSB widget named "page". A sub-menu will
+ be mapped (or unmapped) when the pointer enters (or leaves) the
+ superior SmeBSB widget. Note that a sub-menu's parent must be the
+ superior SimpleMenu widget, not the superior SmeBSB widget. The other
+ resources of SmeBSB widgets are unaffected by the menuName resource.
+
+ The Tip widget:
+ ---------------
+
+ This Tip widget is not compatable with XFree86's "Xaw7" Tip widget. I
+ couldn't grok how it links the specified widgets to a Tip widget, nor
+ how their labels are set. Perhaps it's all done with an "Xaw7"
+ DisplayList, I don't know. So, this XawTipEnable() function requires a
+ second parameter, to set the label:
+
+ /* create a menu button */
+ opsbutton = XtCreateManagedWidget("ops", menuButtonWidgetClass,
+ parent, NULL, 0);
+
+ /* add a tooltip */
+ XawTipEnable(opsbutton, "Application functions");
+
+ ...
+
+ /* for some reason, disable the tooltip */
+ XawTipDisable(opsbutton);
+
+ The XawTipEnable() function creates a Tip widget (one per screen, as
+ required), and links the specified widget and label to the correct Tip
+ widget. Nothing else is required of the application; Tip widgets
+ manage themselves. The XawTipDisable() function removes the timeout
+ and event handler, and unmaps the Tip window if necessary, but does
+ not destroy the widget or its linked list.
+
+ Note that the labels of Tip widgets are set individually, but the
+ font, colors, margins, etc., can only be set globally, for all Tip
+ widget instances. For example, a resource file might contain:
+
+ *Tip.font: 7x13bold
+ *Tip.background: yellow
+ *Tip.foreground: blue
+ *Tip.borderColor: blue
+
+ Note also that the *Margin resources of XFree86's "Xaw7" Tip widget
+ are not in this Tip widget; they have been reduced to internalHeight
+ and internalWidth resources, like those of the Label widget.
+ _________________________________________________________________
+
+ Authors and contributors, in alphabetical order:
+ ------------------------------------------------
+
+ Uri Blumenthal <uri@watson.ibm.com>
+ Dimitrios P. Bouras <dbouras@hol.gr>
+ David Flanagan <david@ora.com>
+ D. J. Hawkey Jr. <hawkeyd@visi.com>, current maintainer
+ Achille Hui <eillihca@drizzle.stanford.edu>
+ Kaleb S. Keithley <kaleb@keithley.org>, developed and maintained Xaw3d
+ Alfredo Kojima
+ Gustaf Neumann <neumann@mohegan.wi-inf.uni-essen.de>
+ Keith Packard <keithp@ncd.com>
+ Mark Rawling <mwr@mel.dit.csiro.au>
+ Heiko Schroeder <heiko@pool.informatik.rwth-aachen.de>
+ Mike Schulze <mike@cs.curtin.edu.au>
+ Brian V. Smith <bvsmith@lbl.gov>
+ Malcolm Strickland <chuck-strickland@orl.mmc.com>
+ Frank Terhaar-Yonkers <fty@bizarre.trpnc.epa.gov>
+ Tim Theisen <tim@cs.wisc.edu>
+ Mitch Trachtenberg <mitch@mta.com>
+ Jerry Whelan <guru@stasi.bradley.edu>
+ Robert Withrow <witr@rwwa.com>
+ Jamie Zawinski <jwz@netscape.com>
+
+ And, of course, all the people at X.Org and XFree86.
+
diff --git a/src/Repeater.c b/src/Repeater.c
new file mode 100644
index 0000000..1467f63
--- /dev/null
+++ b/src/Repeater.c
@@ -0,0 +1,278 @@
+/*
+ * $XConsortium: Repeater.c,v 1.11 94/04/17 20:12:37 kaleb Exp $
+ *
+Copyright (c) 1990, 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.
+ *
+ * Author: Jim Fulton, MIT X Consortium
+ *
+ * This widget is used for press-and-hold style buttons.
+ */
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h> /* for XtN and XtC defines */
+#include <X11/Xaw3d/XawInit.h> /* for XawInitializeWidgetSet() */
+#include <X11/Xaw3d/RepeaterP.h> /* us */
+
+static void tic(); /* clock timeout */
+
+#define DO_CALLBACK(rw) \
+ XtCallCallbackList ((Widget) rw, rw->command.callbacks, (XtPointer)NULL)
+
+
+#define ADD_TIMEOUT(rw,delay) \
+ XtAppAddTimeOut (XtWidgetToApplicationContext ((Widget) rw), \
+ (unsigned long) delay, tic, (XtPointer) rw)
+
+#define CLEAR_TIMEOUT(rw) \
+ if ((rw)->repeater.timer) { \
+ XtRemoveTimeOut ((rw)->repeater.timer); \
+ (rw)->repeater.timer = 0; \
+ }
+
+
+/*
+ * Translations to give user interface of press-notify...-release_or_leave
+ */
+static char defaultTranslations[] =
+ "<EnterWindow>: highlight() \n\
+ <LeaveWindow>: unhighlight() \n\
+ <Btn1Down>: set() start() \n\
+ <Btn1Up>: stop() unset() ";
+
+
+/*
+ * Actions added by this widget
+ */
+static void ActionStart(), ActionStop();
+
+static XtActionsRec actions[] = {
+ { "start", ActionStart }, /* trigger timers */
+ { "stop", ActionStop }, /* clear timers */
+};
+
+
+/*
+ * New resources added by this widget
+ */
+static XtResource resources[] = {
+#define off(field) XtOffsetOf(RepeaterRec, repeater.field)
+ { XtNdecay, XtCDecay, XtRInt, sizeof (int),
+ off(decay), XtRImmediate, (XtPointer) REP_DEF_DECAY },
+ { XtNinitialDelay, XtCDelay, XtRInt, sizeof (int),
+ off(initial_delay), XtRImmediate, (XtPointer) REP_DEF_INITIAL_DELAY },
+ { XtNminimumDelay, XtCMinimumDelay, XtRInt, sizeof (int),
+ off(minimum_delay), XtRImmediate, (XtPointer) REP_DEF_MINIMUM_DELAY },
+ { XtNrepeatDelay, XtCDelay, XtRInt, sizeof (int),
+ off(repeat_delay), XtRImmediate, (XtPointer) REP_DEF_REPEAT_DELAY },
+ { XtNflash, XtCBoolean, XtRBoolean, sizeof (Boolean),
+ off(flash), XtRImmediate, (XtPointer) FALSE },
+ { XtNstartCallback, XtCStartCallback, XtRCallback, sizeof (XtPointer),
+ off(start_callbacks), XtRImmediate, (XtPointer) NULL },
+ { XtNstopCallback, XtCStopCallback, XtRCallback, sizeof (XtPointer),
+ off(stop_callbacks), XtRImmediate, (XtPointer) NULL },
+#undef off
+};
+
+
+/*
+ * Class Methods
+ */
+
+static void Initialize(); /* setup private data */
+static void Destroy(); /* clear timers */
+static Boolean SetValues(); /* set resources */
+
+RepeaterClassRec repeaterClassRec = {
+ { /* core fields */
+ /* superclass */ (WidgetClass) &commandClassRec,
+ /* class_name */ "Repeater",
+ /* widget_size */ sizeof(RepeaterRec),
+ /* class_initialize */ XawInitializeWidgetSet,
+ /* class_part_initialize */ NULL,
+ /* class_inited */ FALSE,
+ /* initialize */ Initialize,
+ /* initialize_hook */ NULL,
+ /* realize */ XtInheritRealize,
+ /* actions */ actions,
+ /* num_actions */ XtNumber(actions),
+ /* resources */ resources,
+ /* num_resources */ XtNumber(resources),
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ TRUE,
+ /* compress_exposure */ TRUE,
+ /* compress_enterleave */ TRUE,
+ /* visible_interest */ FALSE,
+ /* destroy */ Destroy,
+ /* resize */ XtInheritResize,
+ /* expose */ XtInheritExpose,
+ /* 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 */ defaultTranslations,
+ /* query_geometry */ XtInheritQueryGeometry,
+ /* display_accelerator */ XtInheritDisplayAccelerator,
+ /* extension */ NULL
+ },
+ { /* simple fields */
+ /* change_sensitive */ XtInheritChangeSensitive
+ },
+ { /* threeD fields */
+ /* shadowdraw */ XtInheritXaw3dShadowDraw
+ },
+ { /* label fields */
+ /* ignore */ 0
+ },
+ { /* command fields */
+ /* ignore */ 0
+ },
+ { /* repeater fields */
+ /* ignore */ 0
+ }
+};
+
+WidgetClass repeaterWidgetClass = (WidgetClass) &repeaterClassRec;
+
+
+/*****************************************************************************
+ * *
+ * repeater utility routines *
+ * *
+ *****************************************************************************/
+
+/* ARGSUSED */
+static void tic (client_data, id)
+ XtPointer client_data;
+ XtIntervalId *id;
+{
+ RepeaterWidget rw = (RepeaterWidget) client_data;
+
+ rw->repeater.timer = 0; /* timer is removed */
+ if (rw->repeater.flash) {
+ XtExposeProc expose;
+ expose = repeaterWidgetClass->core_class.superclass->core_class.expose;
+ XClearWindow (XtDisplay((Widget) rw), XtWindow((Widget) rw));
+ rw->command.set = FALSE;
+ (*expose) ((Widget) rw, (XEvent *) NULL, (Region) NULL);
+ XClearWindow (XtDisplay((Widget) rw), XtWindow((Widget) rw));
+ rw->command.set = TRUE;
+ (*expose) ((Widget) rw, (XEvent *) NULL, (Region) NULL);
+ }
+ DO_CALLBACK (rw);
+
+ rw->repeater.timer = ADD_TIMEOUT (rw, rw->repeater.next_delay);
+
+ /* decrement delay time, but clamp */
+ if (rw->repeater.decay) {
+ rw->repeater.next_delay -= rw->repeater.decay;
+ if (rw->repeater.next_delay < rw->repeater.minimum_delay)
+ rw->repeater.next_delay = rw->repeater.minimum_delay;
+ }
+}
+
+
+/*****************************************************************************
+ * *
+ * repeater class methods *
+ * *
+ *****************************************************************************/
+
+/* ARGSUSED */
+static void Initialize (greq, gnew, args, num_args)
+ Widget greq, gnew;
+ ArgList args;
+ Cardinal *num_args;
+{
+ RepeaterWidget new = (RepeaterWidget) gnew;
+
+ if (new->repeater.minimum_delay < 0) new->repeater.minimum_delay = 0;
+ new->repeater.timer = (XtIntervalId) 0;
+}
+
+static void Destroy (gw)
+ Widget gw;
+{
+ CLEAR_TIMEOUT ((RepeaterWidget) gw);
+}
+
+/* ARGSUSED */
+static Boolean SetValues (gcur, greq, gnew, args, num_args)
+ Widget gcur, greq, gnew;
+ ArgList args;
+ Cardinal *num_args;
+{
+ RepeaterWidget cur = (RepeaterWidget) gcur;
+ RepeaterWidget new = (RepeaterWidget) gnew;
+ Boolean redisplay = FALSE;
+
+ if (cur->repeater.minimum_delay != new->repeater.minimum_delay) {
+ if (new->repeater.next_delay < new->repeater.minimum_delay)
+ new->repeater.next_delay = new->repeater.minimum_delay;
+ }
+
+ return redisplay;
+}
+
+/*****************************************************************************
+ * *
+ * repeater action procs *
+ * *
+ *****************************************************************************/
+
+/* ARGSUSED */
+static void ActionStart (gw, event, params, num_params)
+ Widget gw;
+ XEvent *event;
+ String *params; /* unused */
+ Cardinal *num_params; /* unused */
+{
+ RepeaterWidget rw = (RepeaterWidget) gw;
+
+ CLEAR_TIMEOUT (rw);
+ if (rw->repeater.start_callbacks)
+ XtCallCallbackList (gw, rw->repeater.start_callbacks, (XtPointer)NULL);
+
+ DO_CALLBACK (rw);
+ rw->repeater.timer = ADD_TIMEOUT (rw, rw->repeater.initial_delay);
+ rw->repeater.next_delay = rw->repeater.repeat_delay;
+}
+
+
+/* ARGSUSED */
+static void ActionStop (gw, event, params, num_params)
+ Widget gw;
+ XEvent *event;
+ String *params; /* unused */
+ Cardinal *num_params; /* unused */
+{
+ RepeaterWidget rw = (RepeaterWidget) gw;
+
+ CLEAR_TIMEOUT ((RepeaterWidget) gw);
+ if (rw->repeater.stop_callbacks)
+ XtCallCallbackList (gw, rw->repeater.stop_callbacks, (XtPointer)NULL);
+}
+
diff --git a/src/Repeater.h b/src/Repeater.h
new file mode 100644
index 0000000..efc07cb
--- /dev/null
+++ b/src/Repeater.h
@@ -0,0 +1,77 @@
+/*
+ * $XConsortium: Repeater.h,v 1.4 94/04/17 20:12:38 jim Exp $
+ *
+Copyright (c) 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: Jim Fulton, MIT X Consortium
+ */
+
+#ifndef _XawRepeater_h
+#define _XawRepeater_h
+
+#include <X11/Xaw3d/Command.h>
+
+/*****************************************************************************
+ *
+ * Repeater Widget (subclass of Command)
+ *
+ * This widget is a push button that repeatedly fires when held down.
+ *
+ * Parameters:
+ *
+ * Name Class Type Default
+ * ---- ----- ---- -------
+ *
+ * decay Decay int 5 milliseconds
+ * flash Boolean Boolean FALSE
+ * initialDelay Delay int 200 milliseconds
+ * minimumDelay MinimumDelay int 10 milliseconds
+ * repeatDelay Delay int 50 milliseconds
+ * startCallback StartCallback XtCallbackList NULL
+ * stopCallback StopCallback XtCallbackList NULL
+ *
+ *****************************************************************************/
+
+ /* new instance and class names */
+#define XtNdecay "decay"
+#define XtCDecay "Decay"
+#define XtNinitialDelay "initialDelay"
+#define XtCDelay "Delay"
+#define XtNminimumDelay "minimumDelay"
+#define XtCMinimumDelay "MinimumDelay"
+#define XtNrepeatDelay "repeatDelay"
+#define XtNflash "flash"
+#define XtNstartCallback "startCallback"
+#define XtCStartCallback "StartCallback"
+#define XtNstopCallback "stopCallback"
+#define XtCStopCallback "StopCallback"
+
+
+ /* external declarations */
+extern WidgetClass repeaterWidgetClass;
+
+typedef struct _RepeaterClassRec *RepeaterWidgetClass;
+typedef struct _RepeaterRec *RepeaterWidget;
+
+#endif /* _XawRepeater_h */
diff --git a/src/RepeaterP.h b/src/RepeaterP.h
new file mode 100644
index 0000000..4cd0e75
--- /dev/null
+++ b/src/RepeaterP.h
@@ -0,0 +1,82 @@
+/*
+ * $XConsortium: RepeaterP.h,v 1.4 94/04/17 20:12:39 jim Exp $
+ *
+Copyright (c) 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: Jim Fulton, MIT X Consortium
+ */
+
+#ifndef _XawRepeaterP_h
+#define _XawRepeaterP_h
+
+#include <X11/Xaw3d/CommandP.h>
+#include <X11/Xaw3d/Repeater.h>
+
+typedef struct { /* new fields in widget class */
+ int dummy;
+} RepeaterClassPart;
+
+typedef struct _RepeaterClassRec { /* Repeater widget class */
+ CoreClassPart core_class;
+ SimpleClassPart simple_class;
+ ThreeDClassPart threeD_class;
+ LabelClassPart label_class;
+ CommandClassPart command_class;
+ RepeaterClassPart repeater_class;
+} RepeaterClassRec;
+
+typedef struct { /* new fields in widget */
+ /* resources... */
+ int initial_delay; /* initialDelay/Delay */
+ int repeat_delay; /* repeatDelay/Delay */
+ int minimum_delay; /* minimumDelay/MinimumDelay */
+ int decay; /* decay to minimum delay */
+ Boolean flash; /* flash/Boolean */
+ XtCallbackList start_callbacks; /* startCallback/StartCallback */
+ XtCallbackList stop_callbacks; /* stopCallback/StopCallback */
+ /* private data... */
+ int next_delay; /* next amount for timer */
+ XtIntervalId timer; /* timer that will fire */
+} RepeaterPart;
+
+typedef struct _RepeaterRec {
+ CorePart core;
+ SimplePart simple;
+ ThreeDPart threeD;
+ LabelPart label;
+ CommandPart command;
+ RepeaterPart repeater;
+} RepeaterRec;
+
+#define REP_DEF_DECAY 5 /* milliseconds */
+#define REP_DEF_INITIAL_DELAY 200 /* milliseconds */
+#define REP_DEF_MINIMUM_DELAY 10 /* milliseconds */
+#define REP_DEF_REPEAT_DELAY 50 /* milliseconds */
+
+/*
+ * external declarations
+ */
+extern RepeaterClassRec repeaterClassRec;
+
+#endif /* _XawRepeaterP_h */
diff --git a/src/Reports.h b/src/Reports.h
new file mode 100644
index 0000000..0b193c9
--- /dev/null
+++ b/src/Reports.h
@@ -0,0 +1,55 @@
+/*
+ * $XConsortium: Reports.h,v 1.4 94/04/17 20:12:39 jim Exp $
+ *
+Copyright (c) 1990 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.
+ */
+
+#ifndef _Xaw_Reports_h
+#define _Xaw_Reports_h
+
+/*
+ * XawPannerReport - this structure is used by the reportCallback of the
+ * Panner, Porthole, Viewport, and Scrollbar widgets to report its position.
+ * All fields must be filled in, although the changed field may be used as
+ * a hint as to which fields have been altered since the last report.
+ */
+typedef struct {
+ unsigned int changed; /* mask, see below */
+ Position slider_x, slider_y; /* location of slider within outer */
+ Dimension slider_width, slider_height; /* size of slider */
+ Dimension canvas_width, canvas_height; /* size of canvas */
+} XawPannerReport;
+
+#define XawPRSliderX (1 << 0)
+#define XawPRSliderY (1 << 1)
+#define XawPRSliderWidth (1 << 2)
+#define XawPRSliderHeight (1 << 3)
+#define XawPRCanvasWidth (1 << 4)
+#define XawPRCanvasHeight (1 << 5)
+#define XawPRAll (63) /* union of above */
+
+#define XtNreportCallback "reportCallback"
+#define XtCReportCallback "reportCallback"
+
+#endif /* _Xaw_Reports_h */
diff --git a/src/Scrollbar.c b/src/Scrollbar.c
new file mode 100644
index 0000000..c105688
--- /dev/null
+++ b/src/Scrollbar.c
@@ -0,0 +1,1169 @@
+
+/* MODIFIED ATHENA SCROLLBAR (USING ARROWHEADS AT ENDS OF TRAVEL) */
+/* Modifications Copyright 1992 by Mitch Trachtenberg */
+/* Rights, permissions, and disclaimer of warranty are as in the */
+/* DEC and MIT notice below. */
+/* $XConsortium: Scrollbar.c,v 1.70 91/10/16 21:39:40 eswu 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.
+
+******************************************************************/
+
+/* ScrollBar.c */
+/* created by weissman, Mon Jul 7 13:20:03 1986 */
+/* converted by swick, Thu Aug 27 1987 */
+
+#include "Xaw3dP.h"
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/ScrollbarP.h>
+
+#include <X11/Xmu/Drawing.h>
+
+/* Private definitions. */
+
+#ifdef XAW_ARROW_SCROLLBARS
+static char defaultTranslations[] =
+ "<Btn1Down>: NotifyScroll()\n\
+ <Btn2Down>: MoveThumb() NotifyThumb() \n\
+ <Btn3Down>: NotifyScroll()\n\
+ <Btn1Motion>: HandleThumb() \n\
+ <Btn3Motion>: HandleThumb() \n\
+ <Btn2Motion>: MoveThumb() NotifyThumb() \n\
+ <BtnUp>: EndScroll()";
+#else
+static char defaultTranslations[] =
+ "<Btn1Down>: StartScroll(Forward) \n\
+ <Btn2Down>: StartScroll(Continuous) MoveThumb() NotifyThumb() \n\
+ <Btn3Down>: StartScroll(Backward) \n\
+ <Btn2Motion>: MoveThumb() NotifyThumb() \n\
+ <BtnUp>: NotifyScroll(Proportional) EndScroll()";
+#ifdef bogusScrollKeys
+ /* examples */
+ "<KeyPress>f: StartScroll(Forward) NotifyScroll(FullLength) EndScroll()"
+ "<KeyPress>b: StartScroll(Backward) NotifyScroll(FullLength) EndScroll()"
+#endif
+#endif
+
+static float floatZero = 0.0;
+
+#define Offset(field) XtOffsetOf(ScrollbarRec, field)
+
+static XtResource resources[] = {
+#ifdef XAW_ARROW_SCROLLBARS
+/* {XtNscrollCursor, XtCCursor, XtRCursor, sizeof(Cursor),
+ Offset(scrollbar.cursor), XtRString, "crosshair"},*/
+#else
+ {XtNscrollVCursor, XtCCursor, XtRCursor, sizeof(Cursor),
+ Offset(scrollbar.verCursor), XtRString, "sb_v_double_arrow"},
+ {XtNscrollHCursor, XtCCursor, XtRCursor, sizeof(Cursor),
+ Offset(scrollbar.horCursor), XtRString, "sb_h_double_arrow"},
+ {XtNscrollUCursor, XtCCursor, XtRCursor, sizeof(Cursor),
+ Offset(scrollbar.upCursor), XtRString, "sb_up_arrow"},
+ {XtNscrollDCursor, XtCCursor, XtRCursor, sizeof(Cursor),
+ Offset(scrollbar.downCursor), XtRString, "sb_down_arrow"},
+ {XtNscrollLCursor, XtCCursor, XtRCursor, sizeof(Cursor),
+ Offset(scrollbar.leftCursor), XtRString, "sb_left_arrow"},
+ {XtNscrollRCursor, XtCCursor, XtRCursor, sizeof(Cursor),
+ Offset(scrollbar.rightCursor), XtRString, "sb_right_arrow"},
+#endif
+ {XtNlength, XtCLength, XtRDimension, sizeof(Dimension),
+ Offset(scrollbar.length), XtRImmediate, (XtPointer) 1},
+ {XtNthickness, XtCThickness, XtRDimension, sizeof(Dimension),
+ Offset(scrollbar.thickness), XtRImmediate, (XtPointer) 14},
+ {XtNorientation, XtCOrientation, XtROrientation, sizeof(XtOrientation),
+ Offset(scrollbar.orientation), XtRImmediate, (XtPointer) XtorientVertical},
+ {XtNscrollProc, XtCCallback, XtRCallback, sizeof(XtPointer),
+ Offset(scrollbar.scrollProc), XtRCallback, NULL},
+ {XtNthumbProc, XtCCallback, XtRCallback, sizeof(XtPointer),
+ Offset(scrollbar.thumbProc), XtRCallback, NULL},
+ {XtNjumpProc, XtCCallback, XtRCallback, sizeof(XtPointer),
+ Offset(scrollbar.jumpProc), XtRCallback, NULL},
+ {XtNthumb, XtCThumb, XtRBitmap, sizeof(Pixmap),
+ Offset(scrollbar.thumb), XtRImmediate, (XtPointer) XtUnspecifiedPixmap},
+ {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
+ Offset(scrollbar.foreground), XtRString, XtDefaultForeground},
+ {XtNshown, XtCShown, XtRFloat, sizeof(float),
+ Offset(scrollbar.shown), XtRFloat, (XtPointer)&floatZero},
+ {XtNtopOfThumb, XtCTopOfThumb, XtRFloat, sizeof(float),
+ Offset(scrollbar.top), XtRFloat, (XtPointer)&floatZero},
+ {XtNpickTop, XtCPickTop, XtRBoolean, sizeof(Boolean),
+ Offset(scrollbar.pick_top), XtRBoolean, (XtPointer) False},
+ {XtNminimumThumb, XtCMinimumThumb, XtRDimension, sizeof(Dimension),
+ Offset(scrollbar.min_thumb), XtRImmediate, (XtPointer) 7}
+};
+#undef Offset
+
+static void ClassInitialize();
+static void Initialize();
+static void Destroy();
+static void Realize();
+static void Resize();
+static void Redisplay();
+static Boolean SetValues();
+
+#ifdef XAW_ARROW_SCROLLBARS
+static void HandleThumb();
+#else
+static void StartScroll();
+#endif
+static void MoveThumb();
+static void NotifyThumb();
+static void NotifyScroll();
+static void EndScroll();
+
+static XtActionsRec actions[] = {
+#ifdef XAW_ARROW_SCROLLBARS
+ {"HandleThumb", HandleThumb},
+#else
+ {"StartScroll", StartScroll},
+#endif
+ {"MoveThumb", MoveThumb},
+ {"NotifyThumb", NotifyThumb},
+ {"NotifyScroll", NotifyScroll},
+ {"EndScroll", EndScroll}
+};
+
+
+ScrollbarClassRec scrollbarClassRec = {
+ { /* core fields */
+ /* superclass */ (WidgetClass) &threeDClassRec,
+ /* class_name */ "Scrollbar",
+ /* size */ sizeof(ScrollbarRec),
+ /* class_initialize */ ClassInitialize,
+ /* class_part_init */ NULL,
+ /* class_inited */ FALSE,
+ /* initialize */ Initialize,
+ /* initialize_hook */ NULL,
+ /* realize */ Realize,
+ /* actions */ actions,
+ /* num_actions */ XtNumber(actions),
+ /* 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 */ defaultTranslations,
+ /* query_geometry */ XtInheritQueryGeometry,
+ /* display_accelerator*/ XtInheritDisplayAccelerator,
+ /* extension */ NULL
+ },
+ { /* simple fields */
+ /* change_sensitive */ XtInheritChangeSensitive
+ },
+ { /* threeD fields */
+ /* shadowdraw */ XtInheritXaw3dShadowDraw /*,*/
+ /* shadowboxdraw */ /*XtInheritXaw3dShadowBoxDraw*/
+ },
+ { /* scrollbar fields */
+ /* ignore */ 0
+ }
+
+};
+
+WidgetClass scrollbarWidgetClass = (WidgetClass)&scrollbarClassRec;
+
+#define NoButton -1
+#define PICKLENGTH(widget, x, y) \
+ ((widget->scrollbar.orientation == XtorientHorizontal) ? x : y)
+#define MIN(x,y) ((x) < (y) ? (x) : (y))
+#define MAX(x,y) ((x) > (y) ? (x) : (y))
+
+static void ClassInitialize()
+{
+ XawInitializeWidgetSet();
+ XtAddConverter( XtRString, XtROrientation, XmuCvtStringToOrientation,
+ (XtConvertArgList)NULL, (Cardinal)0 );
+}
+
+#ifdef XAW_ARROW_SCROLLBARS
+/* CHECKIT #define MARGIN(sbw) (sbw)->scrollbar.thickness + (sbw)->threeD.shadow_width */
+#define MARGIN(sbw) (sbw)->scrollbar.thickness
+#else
+#define MARGIN(sbw) (sbw)->threeD.shadow_width
+#endif
+
+/*
+ The original Xaw Scrollbar's FillArea *really* relied on the fact that the
+ server was going to clip at the window boundaries; so the logic was really
+ rather sloppy. To avoid drawing over the shadows and the arrows requires
+ some extra care... Hope I didn't make any mistakes.
+*/
+static void FillArea (sbw, top, bottom, fill)
+ ScrollbarWidget sbw;
+ Position top, bottom;
+ int fill;
+{
+ int tlen = bottom - top; /* length of thumb in pixels */
+ int sw, margin, floor;
+ int lx, ly, lw, lh;
+
+ if (bottom <= 0 || bottom <= top)
+ return;
+ if ((sw = sbw->threeD.shadow_width) < 0)
+ sw = 0;
+ margin = MARGIN (sbw);
+ floor = sbw->scrollbar.length - margin;
+
+ if (sbw->scrollbar.orientation == XtorientHorizontal) {
+ lx = ((top < margin) ? margin : top);
+ ly = sw;
+ lw = ((bottom > floor) ? floor - top : tlen);
+/* CHECKIT lw = (((top + tlen) > floor) ? floor - top : tlen); */
+ lh = sbw->core.height - 2 * sw;
+ } else {
+ lx = sw;
+ ly = ((top < margin) ? margin : top);
+ lw = sbw->core.width - 2 * sw;
+/* CHECKIT lh = (((top + tlen) > floor) ? floor - top : tlen); */
+ lh = ((bottom > floor) ? floor - top : tlen);
+ }
+ if (lh <= 0 || lw <= 0) return;
+ if (fill) {
+ XFillRectangle(XtDisplay((Widget) sbw), XtWindow((Widget) sbw),
+ sbw->scrollbar.gc,
+ lx, ly, (unsigned int) lw, (unsigned int) lh);
+ } else {
+ XClearArea (XtDisplay((Widget) sbw), XtWindow((Widget) sbw),
+ lx, ly, (unsigned int) lw, (unsigned int) lh,
+ FALSE);
+ }
+}
+
+/* Paint the thumb in the area specified by sbw->top and
+ sbw->shown. The old area is erased. The painting and
+ erasing is done cleverly so that no flickering will occur. */
+
+static void PaintThumb (sbw, event)
+ ScrollbarWidget sbw;
+ XEvent *event;
+{
+ Dimension s = sbw->threeD.shadow_width;
+ Position oldtop = sbw->scrollbar.topLoc;
+ Position oldbot = oldtop + sbw->scrollbar.shownLength;
+ Dimension margin = MARGIN (sbw);
+ Dimension tzl = sbw->scrollbar.length - margin - margin;
+ Position newtop, newbot;
+ Position floor = sbw->scrollbar.length - margin;
+
+ newtop = margin + (int)(tzl * sbw->scrollbar.top);
+ newbot = newtop + (int)(tzl * sbw->scrollbar.shown);
+ if (sbw->scrollbar.shown < 1.) newbot++;
+ if (newbot < newtop + (int)sbw->scrollbar.min_thumb +
+ 2 * (int)sbw->threeD.shadow_width)
+ newbot = newtop + sbw->scrollbar.min_thumb +
+ 2 * sbw->threeD.shadow_width;
+ if ( newbot >= floor ) {
+ newtop = floor-(newbot-newtop)+1;
+ newbot = floor;
+ }
+
+ sbw->scrollbar.topLoc = newtop;
+ sbw->scrollbar.shownLength = newbot - newtop;
+ if (XtIsRealized ((Widget) sbw)) {
+ /* 3D thumb wanted ?
+ */
+ if (s)
+ {
+ if (newtop < oldtop) FillArea(sbw, oldtop, oldtop + s, 0);
+ if (newtop > oldtop) FillArea(sbw, oldtop, MIN(newtop, oldbot), 0);
+ if (newbot < oldbot) FillArea(sbw, MAX(newbot, oldtop), oldbot, 0);
+ if (newbot > oldbot) FillArea(sbw, oldbot - s, oldbot, 0);
+
+ if (sbw->scrollbar.orientation == XtorientHorizontal)
+ {
+ _ShadowSurroundedBox((Widget)sbw, (ThreeDWidget)sbw,
+ newtop, s, newbot, sbw->core.height - s,
+ sbw->threeD.relief, TRUE);
+ }
+ else
+ {
+ _ShadowSurroundedBox((Widget)sbw, (ThreeDWidget)sbw,
+ s, newtop, sbw->core.width - s, newbot,
+ sbw->threeD.relief, TRUE);
+ }
+ }
+ else
+ {
+ /*
+ Note to Mitch: FillArea is (now) correctly implemented to
+ not draw over shadows or the arrows. Therefore setting clipmasks
+ doesn't seem to be necessary. Correct me if I'm wrong!
+ */
+ if (newtop < oldtop) FillArea(sbw, newtop, MIN(newbot, oldtop), 1);
+ if (newtop > oldtop) FillArea(sbw, oldtop, MIN(newtop, oldbot), 0);
+ if (newbot < oldbot) FillArea(sbw, MAX(newbot, oldtop), oldbot, 0);
+ if (newbot > oldbot) FillArea(sbw, MAX(newtop, oldbot), newbot, 1);
+ }
+ }
+}
+
+#ifdef XAW_ARROW_SCROLLBARS
+static void PaintArrows (sbw)
+ ScrollbarWidget sbw;
+{
+ XPoint pt[20];
+ Dimension s = sbw->threeD.shadow_width;
+ Dimension t = sbw->scrollbar.thickness;
+ Dimension l = sbw->scrollbar.length;
+ Dimension tms = t - s, lms = l - s;
+ Dimension tm1 = t - 1;
+ Dimension lmt = l - t;
+ Dimension lp1 = lmt + 1;
+ Dimension sm1 = s - 1;
+ Dimension t2 = t / 2;
+ Dimension sa30 = (Dimension)(1.732 * s ); /* cotangent of 30 deg */
+ Display *dpy = XtDisplay (sbw);
+ Window win = XtWindow (sbw);
+ GC top = sbw->threeD.top_shadow_GC;
+ GC bot = sbw->threeD.bot_shadow_GC;
+
+
+ if (XtIsRealized ((Widget) sbw)) {
+ /* 3D arrows?
+ */
+ if (s) {
+ /* upper/right arrow */
+ pt[0].x = sm1; pt[0].y = tm1;
+ pt[1].x = t2; pt[1].y = sm1;
+ pt[2].x = t2; pt[2].y = s + sa30;
+ pt[3].x = sm1 + sa30; pt[3].y = tms - 1;
+
+ pt[4].x = sm1; pt[4].y = tm1;
+ pt[5].x = tms; pt[5].y = tm1;
+ pt[6].x = t2; pt[6].y = sm1;
+ pt[7].x = t2; pt[7].y = s + sa30;
+ pt[8].x = tms - sa30; pt[8].y = tms - 1;
+ pt[9].x = sm1 + sa30; pt[9].y = tms - 1;
+
+ /* lower/left arrow */
+ pt[10].x = tms; pt[10].y = lp1;
+ pt[11].x = s; pt[11].y = lp1;
+ pt[12].x = t2; pt[12].y = lms;
+ pt[13].x = t2; pt[13].y = lms - sa30;
+ pt[14].x = s + sa30; pt[14].y = lmt + s + 1;
+ pt[15].x = tms - sa30; pt[15].y = lmt + s + 1;
+
+ pt[16].x = tms; pt[16].y = lp1;
+ pt[17].x = t2; pt[17].y = lms;
+ pt[18].x = t2; pt[18].y = lms - sa30;
+ pt[19].x = tms - sa30; pt[19].y = lmt + s + 1;
+
+ /* horizontal arrows require that x and y coordinates be swapped */
+ if (sbw->scrollbar.orientation == XtorientHorizontal) {
+ int n;
+ int swap;
+ for (n = 0; n < 20; n++) {
+ swap = pt[n].x;
+ pt[n].x = pt[n].y;
+ pt[n].y = swap;
+ }
+ }
+ XFillPolygon (dpy, win, top, pt, 4, Complex, CoordModeOrigin);
+ XFillPolygon (dpy, win, bot, pt + 4, 6, Complex, CoordModeOrigin);
+ XFillPolygon (dpy, win, top, pt + 10, 6, Complex, CoordModeOrigin);
+ XFillPolygon (dpy, win, bot, pt + 16, 4, Complex, CoordModeOrigin);
+
+ } else {
+ pt[0].x = 0; pt[0].y = tm1;
+ pt[1].x = t; pt[1].y = tm1;
+ pt[2].x = t2; pt[2].y = 0;
+
+ pt[3].x = 0; pt[3].y = lp1;
+ pt[4].x = t; pt[4].y = lp1;
+ pt[5].x = t2; pt[5].y = l;
+
+ /* horizontal arrows require that x and y coordinates be swapped */
+ if (sbw->scrollbar.orientation == XtorientHorizontal) {
+ int n;
+ int swap;
+ for (n = 0; n < 6; n++) {
+ swap = pt[n].x;
+ pt[n].x = pt[n].y;
+ pt[n].y = swap;
+ }
+ }
+ /* draw the up/left arrow */
+ XFillPolygon (dpy, win, sbw->scrollbar.gc,
+ pt, 3,
+ Convex, CoordModeOrigin);
+ /* draw the down/right arrow */
+ XFillPolygon (dpy, win, sbw->scrollbar.gc,
+ pt+3, 3,
+ Convex, CoordModeOrigin);
+ }
+ }
+}
+#endif
+
+/* Function Name: Destroy
+ * Description: Called as the scrollbar is going away...
+ * Arguments: w - the scrollbar.
+ * Returns: nonw
+ */
+static void Destroy (w)
+ Widget w;
+{
+ ScrollbarWidget sbw = (ScrollbarWidget) w;
+#ifdef XAW_ARROW_SCROLLBARS
+ if(sbw->scrollbar.timer_id != (XtIntervalId) 0)
+ XtRemoveTimeOut (sbw->scrollbar.timer_id);
+#endif
+ XtReleaseGC (w, sbw->scrollbar.gc);
+}
+
+/* Function Name: CreateGC
+ * Description: Creates the GC.
+ * Arguments: w - the scrollbar widget.
+ * Returns: none.
+ */
+
+static void CreateGC (w)
+ Widget w;
+{
+ ScrollbarWidget sbw = (ScrollbarWidget) w;
+ XGCValues gcValues;
+ XtGCMask mask;
+ unsigned int depth = 1;
+
+ if (sbw->scrollbar.thumb == XtUnspecifiedPixmap) {
+ sbw->scrollbar.thumb = XmuCreateStippledPixmap (XtScreen(w),
+ (Pixel) 1, (Pixel) 0, depth);
+ } else if (sbw->scrollbar.thumb != None) {
+ Window root;
+ int x, y;
+ unsigned int width, height, bw;
+ if (XGetGeometry (XtDisplay(w), sbw->scrollbar.thumb, &root, &x, &y,
+ &width, &height, &bw, &depth) == 0) {
+ XtAppError (XtWidgetToApplicationContext (w),
+ "Scrollbar Widget: Could not get geometry of thumb pixmap.");
+ }
+ }
+
+ gcValues.foreground = sbw->scrollbar.foreground;
+ gcValues.background = sbw->core.background_pixel;
+ mask = GCForeground | GCBackground;
+
+ if (sbw->scrollbar.thumb != None) {
+ if (depth == 1) {
+ gcValues.fill_style = FillOpaqueStippled;
+ gcValues.stipple = sbw->scrollbar.thumb;
+ mask |= GCFillStyle | GCStipple;
+ }
+ else {
+ gcValues.fill_style = FillTiled;
+ gcValues.tile = sbw->scrollbar.thumb;
+ mask |= GCFillStyle | GCTile;
+ }
+ }
+ /* the creation should be non-caching, because */
+ /* we now set and clear clip masks on the gc returned */
+ sbw->scrollbar.gc = XtGetGC (w, mask, &gcValues);
+}
+
+static void SetDimensions (sbw)
+ ScrollbarWidget sbw;
+{
+ if (sbw->scrollbar.orientation == XtorientVertical) {
+ sbw->scrollbar.length = sbw->core.height;
+ sbw->scrollbar.thickness = sbw->core.width;
+ } else {
+ sbw->scrollbar.length = sbw->core.width;
+ sbw->scrollbar.thickness = sbw->core.height;
+ }
+}
+
+/* ARGSUSED */
+static void Initialize( request, new, args, num_args )
+ Widget request; /* what the client asked for */
+ Widget new; /* what we're going to give him */
+ ArgList args;
+ Cardinal *num_args;
+{
+ ScrollbarWidget sbw = (ScrollbarWidget) new;
+
+ CreateGC (new);
+
+ if (sbw->core.width == 0)
+ sbw->core.width = (sbw->scrollbar.orientation == XtorientVertical)
+ ? sbw->scrollbar.thickness : sbw->scrollbar.length;
+
+ if (sbw->core.height == 0)
+ sbw->core.height = (sbw->scrollbar.orientation == XtorientHorizontal)
+ ? sbw->scrollbar.thickness : sbw->scrollbar.length;
+
+ SetDimensions (sbw);
+#ifdef XAW_ARROW_SCROLLBARS
+ sbw->scrollbar.scroll_mode = 0;
+ sbw->scrollbar.timer_id = (XtIntervalId)0;
+#else
+ sbw->scrollbar.direction = 0;
+#endif
+ sbw->scrollbar.topLoc = 0;
+ sbw->scrollbar.shownLength = sbw->scrollbar.min_thumb;
+}
+
+static void Realize (w, valueMask, attributes)
+ Widget w;
+ Mask *valueMask;
+ XSetWindowAttributes *attributes;
+{
+ ScrollbarWidget sbw = (ScrollbarWidget) w;
+#ifdef XAW_ARROW_SCROLLBARS
+ if(sbw->simple.cursor_name == NULL)
+ XtVaSetValues(w, XtNcursorName, "crosshair", NULL);
+ /* dont set the cursor of the window to anything */
+ *valueMask &= ~CWCursor;
+#else
+ sbw->scrollbar.inactiveCursor =
+ (sbw->scrollbar.orientation == XtorientVertical)
+ ? sbw->scrollbar.verCursor
+ : sbw->scrollbar.horCursor;
+
+ XtVaSetValues (w, XtNcursor, sbw->scrollbar.inactiveCursor, NULL);
+#endif
+ /*
+ * The Simple widget actually stuffs the value in the valuemask.
+ */
+
+ (*scrollbarWidgetClass->core_class.superclass->core_class.realize)
+ (w, valueMask, attributes);
+}
+
+/* ARGSUSED */
+static Boolean SetValues (current, request, desired, args, num_args)
+ Widget current, /* what I am */
+ request, /* what he wants me to be */
+ desired; /* what I will become */
+ ArgList args;
+ Cardinal *num_args;
+{
+ ScrollbarWidget sbw = (ScrollbarWidget) current;
+ ScrollbarWidget dsbw = (ScrollbarWidget) desired;
+ Boolean redraw = FALSE;
+
+/*
+ * If these values are outside the acceptable range ignore them...
+ */
+
+ if (dsbw->scrollbar.top < 0.0 || dsbw->scrollbar.top > 1.0)
+ dsbw->scrollbar.top = sbw->scrollbar.top;
+
+ if (dsbw->scrollbar.shown < 0.0 || dsbw->scrollbar.shown > 1.0)
+ dsbw->scrollbar.shown = sbw->scrollbar.shown;
+
+/*
+ * Change colors and stuff...
+ */
+ if (XtIsRealized (desired)) {
+ if (sbw->scrollbar.foreground != dsbw->scrollbar.foreground ||
+ sbw->core.background_pixel != dsbw->core.background_pixel ||
+ sbw->scrollbar.thumb != dsbw->scrollbar.thumb) {
+ XtReleaseGC (desired, sbw->scrollbar.gc);
+ CreateGC (desired);
+ redraw = TRUE;
+ }
+ if (sbw->scrollbar.top != dsbw->scrollbar.top ||
+ sbw->scrollbar.shown != dsbw->scrollbar.shown)
+ redraw = TRUE;
+ }
+ return redraw;
+}
+
+static void Resize (w)
+ Widget w;
+{
+ /* ForgetGravity has taken care of background, but thumb may
+ * have to move as a result of the new size. */
+ SetDimensions ((ScrollbarWidget) w);
+ Redisplay (w, (XEvent*) NULL, (Region)NULL);
+}
+
+
+/* ARGSUSED */
+static void Redisplay (w, event, region)
+ Widget w;
+ XEvent *event;
+ Region region;
+{
+ ScrollbarWidget sbw = (ScrollbarWidget) w;
+ ScrollbarWidgetClass swclass = (ScrollbarWidgetClass) XtClass (w);
+ int x, y;
+ unsigned int width, height;
+
+ (*swclass->threeD_class.shadowdraw) (w, event, region, sbw->threeD.relief, FALSE);
+
+ if (sbw->scrollbar.orientation == XtorientHorizontal) {
+ x = sbw->scrollbar.topLoc;
+ y = 1;
+ width = sbw->scrollbar.shownLength;
+ height = sbw->core.height - 2;
+ } else {
+ x = 1;
+ y = sbw->scrollbar.topLoc;
+ width = sbw->core.width - 2;
+ height = sbw->scrollbar.shownLength;
+ }
+ if (region == NULL ||
+ XRectInRegion (region, x, y, width, height) != RectangleOut) {
+ /* Forces entire thumb to be painted. */
+ sbw->scrollbar.topLoc = -(sbw->scrollbar.length + 1);
+ PaintThumb (sbw, event);
+ }
+#ifdef XAW_ARROW_SCROLLBARS
+ /* we'd like to be region aware here!!!! */
+ PaintArrows (sbw);
+#endif
+
+}
+
+
+static Boolean CompareEvents (oldEvent, newEvent)
+ XEvent *oldEvent, *newEvent;
+{
+#define Check(field) if (newEvent->field != oldEvent->field) return False;
+
+ Check(xany.display);
+ Check(xany.type);
+ Check(xany.window);
+
+ switch (newEvent->type) {
+ case MotionNotify:
+ Check(xmotion.state);
+ break;
+ case ButtonPress:
+ case ButtonRelease:
+ Check(xbutton.state);
+ Check(xbutton.button);
+ break;
+ case KeyPress:
+ case KeyRelease:
+ Check(xkey.state);
+ Check(xkey.keycode);
+ break;
+ case EnterNotify:
+ case LeaveNotify:
+ Check(xcrossing.mode);
+ Check(xcrossing.detail);
+ Check(xcrossing.state);
+ break;
+ }
+#undef Check
+
+ return True;
+}
+
+struct EventData {
+ XEvent *oldEvent;
+ int count;
+};
+
+static Bool PeekNotifyEvent (dpy, event, args)
+ Display *dpy;
+ XEvent *event;
+ char *args;
+{
+ struct EventData *eventData = (struct EventData*)args;
+
+ return ((++eventData->count == QLength(dpy)) /* since PeekIf blocks */
+ || CompareEvents(event, eventData->oldEvent));
+}
+
+
+static Boolean LookAhead (w, event)
+ Widget w;
+ XEvent *event;
+{
+ XEvent newEvent;
+ struct EventData eventData;
+
+ if (QLength (XtDisplay (w)) == 0) return False;
+
+ eventData.count = 0;
+ eventData.oldEvent = event;
+
+ XPeekIfEvent (XtDisplay (w), &newEvent, PeekNotifyEvent, (char*)&eventData);
+
+ return CompareEvents (event, &newEvent);
+}
+
+
+static void ExtractPosition (event, x, y)
+ XEvent *event;
+ Position *x, *y; /* RETURN */
+{
+ switch( event->type ) {
+ case MotionNotify:
+ *x = event->xmotion.x;
+ *y = event->xmotion.y;
+ break;
+ case ButtonPress:
+ case ButtonRelease:
+ *x = event->xbutton.x;
+ *y = event->xbutton.y;
+ break;
+ case KeyPress:
+ case KeyRelease:
+ *x = event->xkey.x;
+ *y = event->xkey.y;
+ break;
+ case EnterNotify:
+ case LeaveNotify:
+ *x = event->xcrossing.x;
+ *y = event->xcrossing.y;
+ break;
+ default:
+ *x = 0; *y = 0;
+ }
+}
+
+#ifdef XAW_ARROW_SCROLLBARS
+/* ARGSUSED */
+static void HandleThumb (w, event, params, num_params)
+ Widget w;
+ XEvent *event;
+ String *params; /* unused */
+ Cardinal *num_params; /* unused */
+{
+ Position x,y;
+ ScrollbarWidget sbw = (ScrollbarWidget) w;
+
+ ExtractPosition( event, &x, &y );
+ /* if the motion event puts the pointer in thumb, call Move and Notify */
+ /* also call Move and Notify if we're already in continuous scroll mode */
+ if (sbw->scrollbar.scroll_mode == 2 ||
+ (PICKLENGTH (sbw,x,y) >= sbw->scrollbar.topLoc &&
+ PICKLENGTH (sbw,x,y) <= sbw->scrollbar.topLoc + sbw->scrollbar.shownLength)){
+ XtCallActionProc(w, "MoveThumb", event, params, *num_params);
+ XtCallActionProc(w, "NotifyThumb", event, params, *num_params);
+ }
+}
+
+static void RepeatNotify (client_data, idp)
+ XtPointer client_data;
+ XtIntervalId *idp;
+{
+#define A_FEW_PIXELS 5
+ ScrollbarWidget sbw = (ScrollbarWidget) client_data;
+ int call_data;
+ if (sbw->scrollbar.scroll_mode != 1 && sbw->scrollbar.scroll_mode != 3) {
+ sbw->scrollbar.timer_id = (XtIntervalId) 0;
+ return;
+ }
+ call_data = MAX (A_FEW_PIXELS, sbw->scrollbar.length / 20);
+ if (sbw->scrollbar.scroll_mode == 1)
+ call_data = -call_data;
+ XtCallCallbacks((Widget)sbw, XtNscrollProc, (XtPointer) call_data);
+ sbw->scrollbar.timer_id =
+ XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)sbw),
+ (unsigned long) 150,
+ RepeatNotify,
+ client_data);
+}
+
+#else /* XAW_ARROW_SCROLLBARS */
+/* ARGSUSED */
+static void StartScroll (w, event, params, num_params )
+ Widget w;
+ XEvent *event;
+ String *params; /* direction: Back|Forward|Smooth */
+ Cardinal *num_params; /* we only support 1 */
+{
+ ScrollbarWidget sbw = (ScrollbarWidget) w;
+ Cursor cursor;
+ char direction;
+
+ if (sbw->scrollbar.direction != 0) return; /* if we're already scrolling */
+ if (*num_params > 0)
+ direction = *params[0];
+ else
+ direction = 'C';
+
+ sbw->scrollbar.direction = direction;
+
+ switch (direction) {
+ case 'B':
+ case 'b':
+ cursor = (sbw->scrollbar.orientation == XtorientVertical)
+ ? sbw->scrollbar.downCursor
+ : sbw->scrollbar.rightCursor;
+ break;
+ case 'F':
+ case 'f':
+ cursor = (sbw->scrollbar.orientation == XtorientVertical)
+ ? sbw->scrollbar.upCursor
+ : sbw->scrollbar.leftCursor;
+ break;
+ case 'C':
+ case 'c':
+ cursor = (sbw->scrollbar.orientation == XtorientVertical)
+ ? sbw->scrollbar.rightCursor
+ : sbw->scrollbar.upCursor;
+ break;
+ default:
+ return; /* invalid invocation */
+ }
+ XtVaSetValues (w, XtNcursor, cursor, NULL);
+ XFlush (XtDisplay (w));
+}
+#endif /* XAW_ARROW_SCROLLBARS */
+
+/*
+ * Make sure the first number is within the range specified by the other
+ * two numbers.
+ */
+
+#ifndef XAW_ARROW_SCROLLBARS
+static int InRange(num, small, big)
+ int num, small, big;
+{
+ return (num < small) ? small : ((num > big) ? big : num);
+}
+#endif
+
+/*
+ * Same as above, but for floating numbers.
+ */
+
+static float FloatInRange(num, small, big)
+ float num, small, big;
+{
+ return (num < small) ? small : ((num > big) ? big : num);
+}
+
+
+#ifdef XAW_ARROW_SCROLLBARS
+static void NotifyScroll (w, event, params, num_params)
+ Widget w;
+ XEvent *event;
+ String *params;
+ Cardinal *num_params;
+{
+ ScrollbarWidget sbw = (ScrollbarWidget) w;
+ int call_data;
+ Position x, y;
+
+ if (sbw->scrollbar.scroll_mode == 2 /* if scroll continuous */
+ || LookAhead (w, event))
+ return;
+
+ ExtractPosition (event, &x, &y);
+
+ if (PICKLENGTH (sbw,x,y) < sbw->scrollbar.thickness) {
+ /* handle first arrow zone */
+ call_data = -MAX (A_FEW_PIXELS, sbw->scrollbar.length / 20);
+ XtCallCallbacks (w, XtNscrollProc, (XtPointer)(call_data));
+ /* establish autoscroll */
+ sbw->scrollbar.timer_id =
+ XtAppAddTimeOut (XtWidgetToApplicationContext (w),
+ (unsigned long) 300, RepeatNotify, (XtPointer)w);
+ sbw->scrollbar.scroll_mode = 1;
+ } else if (PICKLENGTH (sbw,x,y) > sbw->scrollbar.length - sbw->scrollbar.thickness) {
+ /* handle last arrow zone */
+ call_data = MAX (A_FEW_PIXELS, sbw->scrollbar.length / 20);
+ XtCallCallbacks (w, XtNscrollProc, (XtPointer)(call_data));
+ /* establish autoscroll */
+ sbw->scrollbar.timer_id =
+ XtAppAddTimeOut (XtWidgetToApplicationContext (w),
+ (unsigned long) 300, RepeatNotify, (XtPointer)w);
+ sbw->scrollbar.scroll_mode = 3;
+ } else if (PICKLENGTH (sbw, x, y) < sbw->scrollbar.topLoc) {
+ /* handle zone "above" the thumb */
+ call_data = - sbw->scrollbar.length;
+ XtCallCallbacks (w, XtNscrollProc, (XtPointer)(call_data));
+ } else if (PICKLENGTH (sbw, x, y) > sbw->scrollbar.topLoc + sbw->scrollbar.shownLength) {
+ /* handle zone "below" the thumb */
+ call_data = sbw->scrollbar.length;
+ XtCallCallbacks (w, XtNscrollProc, (XtPointer)(call_data));
+ } else
+ {
+ /* handle the thumb in the motion notify action */
+ }
+ return;
+}
+#else /* XAW_ARROW_SCROLLBARS */
+static void NotifyScroll (w, event, params, num_params)
+ Widget w;
+ XEvent *event;
+ String *params; /* style: Proportional|FullLength */
+ Cardinal *num_params; /* we only support 1 */
+{
+ ScrollbarWidget sbw = (ScrollbarWidget) w;
+ int call_data;
+ char style;
+ Position x, y;
+
+ if (sbw->scrollbar.direction == 0) return; /* if no StartScroll */
+ if (LookAhead (w, event)) return;
+ if (*num_params > 0)
+ style = *params[0];
+ else
+ style = 'P';
+
+ switch (style) {
+ case 'P': /* Proportional */
+ case 'p':
+ ExtractPosition (event, &x, &y);
+ call_data =
+ InRange (PICKLENGTH (sbw, x, y), 0, (int) sbw->scrollbar.length);
+ break;
+
+ case 'F': /* FullLength */
+ case 'f':
+ call_data = sbw->scrollbar.length;
+ break;
+ }
+ switch (sbw->scrollbar.direction) {
+ case 'B':
+ case 'b':
+ call_data = -call_data;
+ /* fall through */
+
+ case 'F':
+ case 'f':
+ XtCallCallbacks (w, XtNscrollProc, (XtPointer)call_data);
+ break;
+
+ case 'C':
+ case 'c':
+ /* NotifyThumb has already called the thumbProc(s) */
+ break;
+ }
+}
+#endif /* XAW_ARROW_SCROLLBARS */
+
+/* ARGSUSED */
+static void EndScroll(w, event, params, num_params )
+ Widget w;
+ XEvent *event; /* unused */
+ String *params; /* unused */
+ Cardinal *num_params; /* unused */
+{
+ ScrollbarWidget sbw = (ScrollbarWidget) w;
+
+#ifdef XAW_ARROW_SCROLLBARS
+ sbw->scrollbar.scroll_mode = 0;
+ /* no need to remove any autoscroll timeout; it will no-op */
+ /* because the scroll_mode is 0 */
+ /* but be sure to remove timeout in destroy proc */
+#else
+ XtVaSetValues (w, XtNcursor, sbw->scrollbar.inactiveCursor, NULL);
+ XFlush (XtDisplay (w));
+ sbw->scrollbar.direction = 0;
+#endif
+}
+
+static float FractionLoc (sbw, x, y)
+ ScrollbarWidget sbw;
+ int x, y;
+{
+ float result;
+ int margin;
+ float height, width;
+
+ margin = MARGIN (sbw);
+ x -= margin;
+ y -= margin;
+ height = sbw->core.height - 2 * margin;
+ width = sbw->core.width - 2 * margin;
+ result = PICKLENGTH (sbw, x / width, y / height);
+ return FloatInRange(result, 0.0, 1.0);
+}
+
+
+static void MoveThumb (w, event, params, num_params)
+ Widget w;
+ XEvent *event;
+ String *params; /* unused */
+ Cardinal *num_params; /* unused */
+{
+ ScrollbarWidget sbw = (ScrollbarWidget) w;
+ Position x, y;
+ float loc, t, s;
+
+#ifndef XAW_ARROW_SCROLLBARS
+ if (sbw->scrollbar.direction == 0) return; /* if no StartScroll */
+#endif
+
+ if (LookAhead (w, event)) return;
+
+ if (!event->xmotion.same_screen) return;
+
+ ExtractPosition (event, &x, &y);
+ loc = FractionLoc (sbw, x, y);
+ t = sbw->scrollbar.top;
+ s = sbw->scrollbar.shown;
+#ifdef XAW_ARROW_SCROLLBARS
+ if (sbw->scrollbar.scroll_mode != 2 )
+ /* initialize picked position */
+ sbw->scrollbar.picked = (FloatInRange( loc, t, t + s ) - t);
+#else
+ sbw->scrollbar.picked = 0.5 * s;
+#endif
+ if (sbw->scrollbar.pick_top)
+ sbw->scrollbar.top = loc;
+ else {
+ sbw->scrollbar.top = loc - sbw->scrollbar.picked;
+ if (sbw->scrollbar.top < 0.0) sbw->scrollbar.top = 0.0;
+ }
+
+#if 0
+ /* this breaks many text-line scrolls */
+ if (sbw->scrollbar.top + sbw->scrollbar.shown > 1.0)
+ sbw->scrollbar.top = 1.0 - sbw->scrollbar.shown;
+#endif
+#ifdef XAW_ARROW_SCROLLBARS
+ sbw->scrollbar.scroll_mode = 2; /* indicate continuous scroll */
+#endif
+ PaintThumb (sbw, event);
+ XFlush (XtDisplay (w)); /* re-draw it before Notifying */
+}
+
+
+/* ARGSUSED */
+static void NotifyThumb (w, event, params, num_params )
+ Widget w;
+ XEvent *event;
+ String *params; /* unused */
+ Cardinal *num_params; /* unused */
+{
+ register ScrollbarWidget sbw = (ScrollbarWidget) w;
+ float top = sbw->scrollbar.top;
+
+#ifndef XAW_ARROW_SCROLLBARS
+ if (sbw->scrollbar.direction == 0) return; /* if no StartScroll */
+#endif
+
+ if (LookAhead (w, event)) return;
+
+ /* thumbProc is not pretty, but is necessary for backwards
+ compatibility on those architectures for which it work{s,ed};
+ the intent is to pass a (truncated) float by value. */
+/* #ifdef XAW_ARROW_SCROLLBARS */
+ /* This corrects for rounding errors: If the thumb is moved to the end of
+ the scrollable area sometimes the last line/column is not displayed.
+ This can happen when the integer number of the top line or leftmost
+ column to be be displayed is calculated from the float value
+ sbw->scrollbar.top. The numerical error of this rounding problem is
+ very small. We therefore add a small value which then forces the
+ next line/column (the correct one) to be used. Since we can expect
+ that the resolution of display screens will not be higher then
+ 10000 text lines/columns we add 1/10000 to the top position. The
+ intermediate variable `top' is used to avoid erroneous summing up
+ corrections (can this happen at all?). If the arrows are not displayed
+ there is no problem since in this case there is always a constant
+ integer number of pixels the thumb must be moved in order to scroll
+ to the next line/column. */
+ /* Removed the dependancy on scrollbar arrows. Xterm as distributed in
+ X11R6.6 by The XFree86 Project wants this correction, with or without
+ the arrows. */
+ top += 0.0001;
+/* #endif */
+ XtCallCallbacks (w, XtNthumbProc, *(XtPointer*)&top);
+ XtCallCallbacks (w, XtNjumpProc, (XtPointer)&top);
+}
+
+
+
+/************************************************************
+ *
+ * Public routines.
+ *
+ ************************************************************/
+
+/* Set the scroll bar to the given location. */
+
+#if NeedFunctionPrototypes
+void XawScrollbarSetThumb (Widget w,
+#if NeedWidePrototypes
+ double top, double shown)
+#else
+ float top, float shown)
+#endif
+#else
+void XawScrollbarSetThumb (w, top, shown)
+ Widget w;
+ float top, shown;
+#endif
+{
+ ScrollbarWidget sbw = (ScrollbarWidget) w;
+
+#ifdef WIERD
+ fprintf(stderr,"< XawScrollbarSetThumb w=%p, top=%f, shown=%f\n",
+ w,top,shown);
+#endif
+
+#ifdef XAW_ARROW_SCROLLBARS
+ if (sbw->scrollbar.scroll_mode == (char) 2) return; /* if still thumbing */
+#else
+ if (sbw->scrollbar.direction == 'c') return; /* if still thumbing */
+#endif
+
+ sbw->scrollbar.top = (top > 1.0) ? 1.0 :
+ (top >= 0.0) ? top : sbw->scrollbar.top;
+
+ sbw->scrollbar.shown = (shown > 1.0) ? 1.0 :
+ (shown >= 0.0) ? shown : sbw->scrollbar.shown;
+
+ PaintThumb (sbw, NULL);
+}
+
diff --git a/src/Scrollbar.h b/src/Scrollbar.h
new file mode 100644
index 0000000..2821018
--- /dev/null
+++ b/src/Scrollbar.h
@@ -0,0 +1,146 @@
+/* $XConsortium: Scrollbar.h,v 1.7 91/07/26 21:59:31 converse Exp $ */
+
+/***********************************************************
+
+Copyright (c) 1987, 1988 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.
+
+******************************************************************/
+
+#ifndef _Scrollbar_h
+#define _Scrollbar_h
+
+/****************************************************************
+ *
+ * Scrollbar Widget
+ *
+ ****************************************************************/
+
+#include <X11/Xmu/Converters.h>
+#include <X11/Xfuncproto.h>
+
+/* Scrollbar resources:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ accelerators Accelerators AcceleratorTable NULL
+ ancestorSensitive AncestorSensitive Boolean True
+ background Background Pixel XtDefaultBackground
+ backgroundPixmap Pixmap Pixmap XtUnspecifiedPixmap
+ borderColor BorderColor Pixel XtDefaultForeground
+ borderPixmap Pixmap Pixmap XtUnspecifiedPixmap
+ borderWidth BorderWidth Dimension 1
+ colormap Colormap Colormap parent's colormap
+ cursor Cursor Cursor None
+ cursorName Cursor String NULL
+ depth Depth int parent's depth
+ destroyCallback Callback XtCallbackList NULL
+ foreground Foreground Pixel XtDefaultForeground
+ height Height Dimension length or thickness
+ insensitiveBorder Insensitive Pixmap GreyPixmap
+ jumpProc Callback XtCallbackList NULL
+ length Length Dimension 1
+ mappedWhenManaged MappedWhenManaged Boolean True
+ minimumThumb MinimumThumb Dimension 7
+ orientation Orientation XtOrientation XtorientVertical
+ pointerColor Foreground Pixel XtDefaultForeground
+ pointerColorBackground Background Pixel XtDefaultBackground
+ screen Screen Screen parent's screen
+ scrollDCursor Cursor Cursor XC_sb_down_arrow
+ scrollHCursor Cursor Cursor XC_sb_h_double_arrow
+ scrollLCursor Cursor Cursor XC_sb_left_arrow
+ scrollProc Callback XtCallbackList NULL
+ scrollRCursor Cursor Cursor XC_sb_right_arrow
+ scrollUCursor Cursor Cursor XC_sb_up_arrow
+ scrollVCursor Cursor Cursor XC_sb_v_double_arrow
+ sensitive Sensitive Boolean True
+ shown Shown Float 0.0
+ thickness Thickness Dimension 14
+ thumb Thumb Bitmap GreyPixmap
+ thumbProc Callback XtCallbackList NULL
+ topOfThumb TopOfThumb Float 0.0
+ pickTop PickTop Boolean False
+ translations Translations TranslationTable see source or doc
+ width Width Dimension thickness or length
+ x Position Position 0
+ y Position Position 0
+
+*/
+
+/*
+ * Most things we need are in StringDefs.h
+ */
+
+#define XtCMinimumThumb "MinimumThumb"
+#define XtCShown "Shown"
+#define XtCTopOfThumb "TopOfThumb"
+#define XtCPickTop "PickTop"
+
+#define XtNminimumThumb "minimumThumb"
+#define XtNtopOfThumb "topOfThumb"
+#define XtNpickTop "pickTop"
+
+typedef struct _ScrollbarRec *ScrollbarWidget;
+typedef struct _ScrollbarClassRec *ScrollbarWidgetClass;
+
+extern WidgetClass scrollbarWidgetClass;
+
+_XFUNCPROTOBEGIN
+
+extern void XawScrollbarSetThumb(
+#if NeedFunctionPrototypes
+ Widget /* scrollbar */,
+#if NeedWidePrototypes
+ /* float */ double /* top */,
+ /* float */ double /* shown */
+#else
+ float /* top */,
+ float /* shown */
+#endif
+#endif
+);
+
+_XFUNCPROTOEND
+
+#endif /* _Scrollbar_h */
diff --git a/src/ScrollbarP.h b/src/ScrollbarP.h
new file mode 100644
index 0000000..d4c8b72
--- /dev/null
+++ b/src/ScrollbarP.h
@@ -0,0 +1,122 @@
+/* MODIFIED ATHENA SCROLLBAR (USING ARROWHEADS AT ENDS OF TRAVEL) */
+/* Modifications Copyright 1992 by Mitch Trachtenberg */
+/* Rights, permissions, and disclaimer of warranty are as in the */
+/* DEC and MIT notice below. See usage warning in .c file. */
+
+/*
+ * $XConsortium: ScrollbarP.h,v 1.2 90/04/11 17:33:53 jim Exp $
+ */
+
+/***********************************************************
+
+Copyright (c) 1987, 1988 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.
+
+******************************************************************/
+
+#ifndef _ScrollbarP_h
+#define _ScrollbarP_h
+
+#include "Xaw3dP.h"
+#include <X11/Xaw3d/Scrollbar.h>
+#include <X11/Xaw3d/ThreeDP.h>
+
+typedef struct {
+ /* public */
+ Pixel foreground; /* thumb foreground color */
+ XtOrientation orientation; /* horizontal or vertical */
+ XtCallbackList scrollProc; /* proportional scroll */
+ XtCallbackList thumbProc; /* jump (to position) scroll */
+ XtCallbackList jumpProc; /* same as thumbProc but pass data by ref */
+ Pixmap thumb; /* thumb color */
+#ifndef XAW_ARROW_SCROLLBARS
+ Cursor upCursor; /* scroll up cursor */
+ Cursor downCursor; /* scroll down cursor */
+ Cursor leftCursor; /* scroll left cursor */
+ Cursor rightCursor; /* scroll right cursor */
+ Cursor verCursor; /* scroll vertical cursor */
+ Cursor horCursor; /* scroll horizontal cursor */
+#endif
+ float top; /* What percent is above the win's top */
+ float shown; /* What percent is shown in the win */
+ Dimension length; /* either height or width */
+ Dimension thickness; /* either width or height */
+ Dimension min_thumb; /* minium size for the thumb. */
+ float picked; /* How much of the thumb is picked *
+ * when scrolling starts */
+
+ /* private */
+#ifdef XAW_ARROW_SCROLLBARS
+ XtIntervalId timer_id; /* autorepeat timer; remove on destruction */
+ char scroll_mode; /* 0:none 1:up/back 2:track 3:down/forward */
+#else
+ Cursor inactiveCursor; /* the normal cursor for scrollbar */
+ char direction; /* a scroll has started; which direction */
+#endif
+ GC gc; /* a (shared) gc */
+ Position topLoc; /* Pixel that corresponds to top */
+ Dimension shownLength; /* Num pixels corresponding to shown */
+ Boolean pick_top; /* pick thumb at top or anywhere*/
+
+} ScrollbarPart;
+
+typedef struct _ScrollbarRec {
+ CorePart core;
+ SimplePart simple;
+ ThreeDPart threeD;
+ ScrollbarPart scrollbar;
+} ScrollbarRec;
+
+typedef struct {int empty;} ScrollbarClassPart;
+
+typedef struct _ScrollbarClassRec {
+ CoreClassPart core_class;
+ SimpleClassPart simple_class;
+ ThreeDClassPart threeD_class;
+ ScrollbarClassPart scrollbar_class;
+} ScrollbarClassRec;
+
+extern ScrollbarClassRec scrollbarClassRec;
+
+#endif /* _ScrollbarP_h */
diff --git a/src/Simple.c b/src/Simple.c
new file mode 100644
index 0000000..29cbbc8
--- /dev/null
+++ b/src/Simple.c
@@ -0,0 +1,299 @@
+/* $XConsortium: Simple.c,v 1.36 94/04/17 20:12:43 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.
+
+******************************************************************/
+
+#include "Xaw3dP.h"
+#include <stdio.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/SimpleP.h>
+#include <X11/Xmu/Drawing.h>
+
+#define offset(field) XtOffsetOf(SimpleRec, simple.field)
+
+static XtResource resources[] = {
+ {XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor),
+ offset(cursor), XtRImmediate, (XtPointer) None},
+ {XtNinsensitiveBorder, XtCInsensitive, XtRPixmap, sizeof(Pixmap),
+ offset(insensitive_border), XtRImmediate, (XtPointer) NULL},
+ {XtNpointerColor, XtCForeground, XtRPixel, sizeof(Pixel),
+ offset(pointer_fg), XtRString, XtDefaultForeground},
+ {XtNpointerColorBackground, XtCBackground, XtRPixel, sizeof(Pixel),
+ offset(pointer_bg), XtRString, XtDefaultBackground},
+ {XtNcursorName, XtCCursor, XtRString, sizeof(String),
+ offset(cursor_name), XtRString, NULL},
+#ifdef XAW_INTERNATIONALIZATION
+ {XtNinternational, XtCInternational, XtRBoolean, sizeof(Boolean),
+ offset(international), XtRImmediate, (XtPointer) FALSE},
+#endif
+#undef offset
+};
+
+static void ClassPartInitialize(), ClassInitialize(),Realize(),ConvertCursor();
+static Boolean SetValues(), ChangeSensitive();
+
+SimpleClassRec simpleClassRec = {
+ { /* core fields */
+ /* superclass */ (WidgetClass) &widgetClassRec,
+ /* class_name */ "Simple",
+ /* widget_size */ sizeof(SimpleRec),
+ /* class_initialize */ ClassInitialize,
+ /* class_part_initialize */ ClassPartInitialize,
+ /* class_inited */ FALSE,
+ /* initialize */ NULL,
+ /* initialize_hook */ NULL,
+ /* realize */ Realize,
+ /* 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 */ NULL,
+ /* resize */ NULL,
+ /* expose */ NULL,
+ /* 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 */ XtInheritQueryGeometry,
+ /* display_accelerator */ XtInheritDisplayAccelerator,
+ /* extension */ NULL
+ },
+ { /* simple fields */
+ /* change_sensitive */ ChangeSensitive
+ }
+};
+
+WidgetClass simpleWidgetClass = (WidgetClass)&simpleClassRec;
+
+static void ClassInitialize()
+{
+ static XtConvertArgRec convertArg[] = {
+ {XtWidgetBaseOffset, (XtPointer) XtOffsetOf(WidgetRec, core.screen),
+ sizeof(Screen *)},
+ {XtResourceString, (XtPointer) XtNpointerColor, sizeof(Pixel)},
+ {XtResourceString, (XtPointer) XtNpointerColorBackground,
+ sizeof(Pixel)},
+ {XtWidgetBaseOffset, (XtPointer) XtOffsetOf(WidgetRec, core.colormap),
+ sizeof(Colormap)}
+ };
+
+ XawInitializeWidgetSet();
+ XtSetTypeConverter( XtRString, XtRColorCursor, XmuCvtStringToColorCursor,
+ convertArg, XtNumber(convertArg),
+ XtCacheByDisplay, (XtDestructor)NULL);
+}
+
+static void ClassPartInitialize(class)
+ WidgetClass class;
+{
+ SimpleWidgetClass c = (SimpleWidgetClass) class;
+ SimpleWidgetClass super = (SimpleWidgetClass)
+ c->core_class.superclass;
+
+ if (c->simple_class.change_sensitive == NULL) {
+ char buf[BUFSIZ];
+
+ (void) sprintf(buf,
+ "%s Widget: The Simple Widget class method 'change_sensitive' is undefined.\nA function must be defined or inherited.",
+ c->core_class.class_name);
+ XtWarning(buf);
+ c->simple_class.change_sensitive = ChangeSensitive;
+ }
+
+ if (c->simple_class.change_sensitive == XtInheritChangeSensitive)
+ c->simple_class.change_sensitive = super->simple_class.change_sensitive;
+}
+
+static void Realize(w, valueMask, attributes)
+ Widget w;
+ Mask *valueMask;
+ XSetWindowAttributes *attributes;
+{
+ Pixmap border_pixmap = 0;
+ if (!XtIsSensitive(w)) {
+ /* change border to gray; have to remember the old one,
+ * so XtDestroyWidget deletes the proper one */
+ if (((SimpleWidget)w)->simple.insensitive_border == None)
+ ((SimpleWidget)w)->simple.insensitive_border =
+ XmuCreateStippledPixmap(XtScreen(w),
+ w->core.border_pixel,
+ w->core.background_pixel,
+ w->core.depth);
+ border_pixmap = w->core.border_pixmap;
+ attributes->border_pixmap =
+ w->core.border_pixmap = ((SimpleWidget)w)->simple.insensitive_border;
+
+ *valueMask |= CWBorderPixmap;
+ *valueMask &= ~CWBorderPixel;
+ }
+
+ ConvertCursor(w);
+
+ if ((attributes->cursor = ((SimpleWidget)w)->simple.cursor) != None)
+ *valueMask |= CWCursor;
+
+ XtCreateWindow( w, (unsigned int)InputOutput, (Visual *)CopyFromParent,
+ *valueMask, attributes );
+
+ if (!XtIsSensitive(w))
+ w->core.border_pixmap = border_pixmap;
+}
+
+/* Function Name: ConvertCursor
+ * Description: Converts a name to a new cursor.
+ * Arguments: w - the simple widget.
+ * Returns: none.
+ */
+
+static void
+ConvertCursor(w)
+Widget w;
+{
+ SimpleWidget simple = (SimpleWidget) w;
+ XrmValue from, to;
+ Cursor cursor;
+
+ if (simple->simple.cursor_name == NULL)
+ return;
+
+ from.addr = (XPointer) simple->simple.cursor_name;
+ from.size = strlen((char *) from.addr) + 1;
+
+ to.size = sizeof(Cursor);
+ to.addr = (XPointer) &cursor;
+
+ if (XtConvertAndStore(w, XtRString, &from, XtRColorCursor, &to)) {
+ if ( cursor != None)
+ simple->simple.cursor = cursor;
+ }
+ else {
+ XtAppErrorMsg(XtWidgetToApplicationContext(w),
+ "convertFailed","ConvertCursor","XawError",
+ "Simple: ConvertCursor failed.",
+ (String *)NULL, (Cardinal *)NULL);
+ }
+}
+
+
+/* ARGSUSED */
+static Boolean SetValues(current, request, new, args, num_args)
+ Widget current, request, new;
+ ArgList args;
+ Cardinal *num_args;
+{
+ SimpleWidget s_old = (SimpleWidget) current;
+ SimpleWidget s_new = (SimpleWidget) new;
+ Boolean new_cursor = FALSE;
+
+ /* this disables user changes after creation*/
+#ifdef XAW_INTERNATIONALIZATION
+ s_new->simple.international = s_old->simple.international;
+#endif
+
+ if ( XtIsSensitive(current) != XtIsSensitive(new) )
+ (*((SimpleWidgetClass)XtClass(new))->
+ simple_class.change_sensitive) ( new );
+
+ if (s_old->simple.cursor != s_new->simple.cursor) {
+ new_cursor = TRUE;
+ }
+
+/*
+ * We are not handling the string cursor_name correctly here.
+ */
+
+ if ( (s_old->simple.pointer_fg != s_new->simple.pointer_fg) ||
+ (s_old->simple.pointer_bg != s_new->simple.pointer_bg) ||
+ (s_old->simple.cursor_name != s_new->simple.cursor_name) ) {
+ ConvertCursor(new);
+ new_cursor = TRUE;
+ }
+
+ if (new_cursor && XtIsRealized(new))
+ XDefineCursor(XtDisplay(new), XtWindow(new), s_new->simple.cursor);
+
+ return False;
+}
+
+
+static Boolean ChangeSensitive(w)
+ Widget w;
+{
+ if (XtIsRealized(w)) {
+ if (XtIsSensitive(w))
+ if (w->core.border_pixmap != XtUnspecifiedPixmap)
+ XSetWindowBorderPixmap( XtDisplay(w), XtWindow(w),
+ w->core.border_pixmap );
+ else
+ XSetWindowBorder( XtDisplay(w), XtWindow(w),
+ w->core.border_pixel );
+ else {
+ if (((SimpleWidget)w)->simple.insensitive_border == None)
+ ((SimpleWidget)w)->simple.insensitive_border =
+ XmuCreateStippledPixmap(XtScreen(w),
+ w->core.border_pixel,
+ w->core.background_pixel,
+ w->core.depth);
+ XSetWindowBorderPixmap( XtDisplay(w), XtWindow(w),
+ ((SimpleWidget)w)->
+ simple.insensitive_border );
+ }
+ }
+ return False;
+}
diff --git a/src/Simple.h b/src/Simple.h
new file mode 100644
index 0000000..7be83b1
--- /dev/null
+++ b/src/Simple.h
@@ -0,0 +1,105 @@
+/* $XConsortium: Simple.h,v 1.14 94/04/17 20:12:44 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.
+
+******************************************************************/
+
+#ifndef _Simple_h
+#define _Simple_h
+
+#include "Xaw3dP.h"
+#include <X11/Xmu/Converters.h>
+
+/****************************************************************
+ *
+ * Simple widgets
+ *
+ ****************************************************************/
+
+/* Resources:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ background Background Pixel XtDefaultBackground
+ border BorderColor Pixel XtDefaultForeground
+ borderWidth BorderWidth Dimension 1
+ cursor Cursor Cursor None
+ cursorName Cursor String NULL
+ destroyCallback Callback Pointer NULL
+ height Height Dimension 0
+ insensitiveBorder Insensitive Pixmap Gray
+ mappedWhenManaged MappedWhenManaged Boolean True
+ pointerColor Foreground Pixel XtDefaultForeground
+ pointerColorBackground Background Pixel XtDefaultBackground
+ sensitive Sensitive Boolean True
+ width Width Dimension 0
+ x Position Position 0
+ y Position Position 0
+
+*/
+
+#define XtNcursor "cursor"
+#define XtNcursorName "cursorName"
+#define XtNinsensitiveBorder "insensitiveBorder"
+
+#define XtCInsensitive "Insensitive"
+
+#ifdef XAW_INTERNATIONALIZATION
+#ifndef XtCInternational
+#define XtCInternational "International"
+#endif
+#ifndef XtNinternational
+#define XtNinternational "international"
+#endif
+#endif
+
+typedef struct _SimpleClassRec *SimpleWidgetClass;
+typedef struct _SimpleRec *SimpleWidget;
+
+extern WidgetClass simpleWidgetClass;
+
+#endif /* _Simple_h */
diff --git a/src/SimpleMenP.h b/src/SimpleMenP.h
new file mode 100644
index 0000000..4ecb187
--- /dev/null
+++ b/src/SimpleMenP.h
@@ -0,0 +1,113 @@
+/*
+ * $XConsortium: SimpleMenP.h,v 1.14 94/04/17 20:12:44 kaleb Exp $
+ *
+Copyright (c) 1989, 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.
+ *
+ */
+
+/*
+ * SimpleMenuP.h - Private Header file for SimpleMenu widget.
+ *
+ * Date: April 3, 1989
+ *
+ * By: Chris D. Peterson
+ * MIT X Consortium
+ * kit@expo.lcs.mit.edu
+ */
+
+#ifndef _SimpleMenuP_h
+#define _SimpleMenuP_h
+
+#include <X11/Xaw3d/SimpleMenu.h>
+#include <X11/Xaw3d/SmeP.h>
+#include <X11/ShellP.h>
+
+typedef struct {
+ XtPointer extension; /* For future needs. */
+} SimpleMenuClassPart;
+
+typedef struct _SimpleMenuClassRec {
+ CoreClassPart core_class;
+ CompositeClassPart composite_class;
+ ShellClassPart shell_class;
+ OverrideShellClassPart override_shell_class;
+ SimpleMenuClassPart simpleMenu_class;
+} SimpleMenuClassRec;
+
+extern SimpleMenuClassRec simpleMenuClassRec;
+
+typedef struct _SimpleMenuPart {
+
+ /* resources */
+
+ String label_string; /* The string for the label or NULL. */
+ SmeObject label; /* If label_string is non-NULL then this is
+ the label widget. */
+ WidgetClass label_class; /* Widget Class of the menu label object. */
+
+ Dimension top_margin; /* Top and bottom margins. */
+ Dimension bottom_margin;
+ Dimension left_whitespace; /* Space between BSB elements */
+ Dimension right_whitespace;
+ Dimension row_height; /* height of each row (menu entry) */
+
+ Cursor cursor; /* The menu's cursor. */
+ SmeObject popup_entry; /* The entry to position the cursor on for
+ when using XawPositionSimpleMenu. */
+ Boolean menu_on_screen; /* Force the menus to be fully on the screen.*/
+ int backing_store; /* What type of backing store to use. */
+
+ /* private state */
+
+ Boolean recursive_set_values; /* contain a possible infinite loop. */
+
+ Boolean menu_width; /* If true then force width to remain
+ core.width */
+ Boolean menu_height; /* Just like menu_width, but for height. */
+
+ SmeObject entry_set; /* The entry that is currently set or
+ highlighted. */
+
+ Widget threeD; /* 3d drawing stuff */
+
+ SmeObject *first_entry; /* the first entry */
+ SmeObject *current_first; /* the first entry displayed */
+ Dimension last_y;
+ int first_y; /* Dimension doesn't do negatives! */
+ int jump_val; /* number of entries to scroll by */
+ Boolean too_tall; /* menu doesn't fit on screen */
+ Boolean didnt_fit; /* if some entry didn't fit in the menu */
+ Widget sub_menu; /* submenu of active SmeBSB object */
+ unsigned char state;
+} SimpleMenuPart;
+
+typedef struct _SimpleMenuRec {
+ CorePart core;
+ CompositePart composite;
+ ShellPart shell;
+ OverrideShellPart override;
+ SimpleMenuPart simple_menu;
+} SimpleMenuRec;
+
+#endif /* _SimpleMenuP_h */
diff --git a/src/SimpleMenu.c b/src/SimpleMenu.c
new file mode 100644
index 0000000..87a3170
--- /dev/null
+++ b/src/SimpleMenu.c
@@ -0,0 +1,1673 @@
+/* $XConsortium: SimpleMenu.c,v 1.44 94/04/17 20:12:45 kaleb Exp $ */
+
+/*
+Copyright (c) 1989, 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.
+ */
+
+/*
+ * SimpleMenu.c - Source code file for SimpleMenu widget.
+ *
+ * Date: April 3, 1989
+ *
+ * By: Chris D. Peterson
+ * MIT X Consortium
+ * kit@expo.lcs.mit.edu
+ */
+
+#include <stdio.h>
+#include <limits.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+
+#include "Xaw3dP.h"
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/SimpleMenP.h>
+#include <X11/Xaw3d/SmeBSBP.h>
+#include <X11/Xaw3d/SmeLine.h>
+#include <X11/Xaw3d/Cardinals.h>
+#include <X11/Xaw3d/ThreeDP.h>
+
+#include <X11/Xmu/Initer.h>
+#include <X11/Xmu/CharSet.h>
+
+#define streq(a, b) ( strcmp((a), (b)) == 0 )
+
+#define offset(field) XtOffsetOf(SimpleMenuRec, simple_menu.field)
+
+static XtResource resources[] = {
+
+/*
+ * Label Resources.
+ */
+
+ {XtNlabel, XtCLabel, XtRString, sizeof(String),
+ offset(label_string), XtRString, NULL},
+ {XtNlabelClass, XtCLabelClass, XtRPointer, sizeof(WidgetClass),
+ offset(label_class), XtRImmediate, (XtPointer) NULL},
+
+/*
+ * Layout Resources.
+ */
+
+ {XtNrowHeight, XtCRowHeight, XtRDimension, sizeof(Dimension),
+ offset(row_height), XtRImmediate, (XtPointer) 0},
+ {XtNtopMargin, XtCVerticalMargins, XtRDimension, sizeof(Dimension),
+ offset(top_margin), XtRImmediate, (XtPointer) 0},
+ {XtNbottomMargin, XtCVerticalMargins, XtRDimension, sizeof(Dimension),
+ offset(bottom_margin), XtRImmediate, (XtPointer) 0},
+ {XtNleftWhitespace, XtCHorizontalWhitespace, XtRDimension, sizeof(Dimension),
+ offset(left_whitespace), XtRImmediate, (XtPointer) 0},
+ {XtNrightWhitespace, XtCHorizontalWhitespace, XtRDimension, sizeof(Dimension),
+ offset(right_whitespace), XtRImmediate, (XtPointer) 0},
+
+/*
+ * Misc. Resources
+ */
+
+ { XtNallowShellResize, XtCAllowShellResize, XtRBoolean, sizeof(Boolean),
+ XtOffsetOf(SimpleMenuRec, shell.allow_shell_resize),
+ XtRImmediate, (XtPointer) TRUE },
+ {XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor),
+ offset(cursor), XtRImmediate, (XtPointer) None},
+ {XtNmenuOnScreen, XtCMenuOnScreen, XtRBoolean, sizeof(Boolean),
+ offset(menu_on_screen), XtRImmediate, (XtPointer) TRUE},
+ {XtNpopupOnEntry, XtCPopupOnEntry, XtRWidget, sizeof(Widget),
+ offset(popup_entry), XtRWidget, NULL},
+ {XtNbackingStore, XtCBackingStore, XtRBackingStore, sizeof (int),
+ offset(backing_store),
+ XtRImmediate, (XtPointer) (Always + WhenMapped + NotUseful)},
+ {XtNjumpScroll, XtCJumpScroll, XtRInt, sizeof(int),
+ offset(jump_val), XtRImmediate, (XtPointer)1},
+};
+#undef offset
+
+static char defaultTranslations[] =
+ "<EnterWindow>: highlight() \n\
+ <LeaveWindow>: unhighlight() \n\
+ <BtnMotion>: highlight() \n\
+ <BtnUp>: notify() unhighlight() popdown()";
+
+/*
+ * Semi Public function definitions.
+ */
+
+static void Redisplay(), Realize(), Resize(), ChangeManaged();
+static void Initialize(), ClassInitialize(), ClassPartInitialize();
+static Boolean SetValues(), SetValuesHook();
+static XtGeometryResult GeometryManager();
+static void PopupCB(), PopupSubMenu(), PopdownSubMenu();
+
+/*
+ * Action Routine Definitions
+ */
+
+static void Highlight(), Unhighlight(), Notify(), PositionMenuAction();
+static void Popdown();
+
+/*
+ * Private Function Definitions.
+ */
+
+static void MakeSetValuesRequest(), CreateLabel(), Layout();
+static void AddPositionAction(), PositionMenu(), ChangeCursorOnGrab();
+static void SetMarginWidths();
+static Dimension GetMenuWidth(), GetMenuHeight();
+static Widget FindMenu();
+static SmeObject GetEventEntry();
+static void MoveMenu();
+
+static XtActionsRec actionsList[] =
+{
+ {"notify", Notify},
+ {"highlight", Highlight},
+ {"unhighlight", Unhighlight},
+ {"popdown", Popdown}
+};
+
+static CompositeClassExtensionRec extension_rec = {
+ /* next_extension */ NULL,
+ /* record_type */ NULLQUARK,
+ /* version */ XtCompositeExtensionVersion,
+ /* record_size */ sizeof(CompositeClassExtensionRec),
+ /* accepts_objects */ TRUE,
+};
+
+#define superclass (&overrideShellClassRec)
+
+SimpleMenuClassRec simpleMenuClassRec = {
+ {
+ /* superclass */ (WidgetClass) superclass,
+ /* class_name */ "SimpleMenu",
+ /* size */ sizeof(SimpleMenuRec),
+ /* class_initialize */ ClassInitialize,
+ /* class_part_initialize*/ ClassPartInitialize,
+ /* Class init'ed */ FALSE,
+ /* initialize */ Initialize,
+ /* initialize_hook */ NULL,
+ /* realize */ Realize,
+ /* actions */ actionsList,
+ /* num_actions */ XtNumber(actionsList),
+ /* resources */ resources,
+ /* resource_count */ XtNumber(resources),
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ TRUE,
+ /* compress_exposure */ TRUE,
+ /* compress_enterleave*/ TRUE,
+ /* visible_interest */ FALSE,
+ /* destroy */ NULL,
+ /* resize */ Resize,
+ /* expose */ Redisplay,
+ /* set_values */ SetValues,
+ /* set_values_hook */ SetValuesHook,
+ /* set_values_almost */ XtInheritSetValuesAlmost,
+ /* get_values_hook */ NULL,
+ /* accept_focus */ NULL,
+ /* intrinsics version */ XtVersion,
+ /* callback offsets */ NULL,
+ /* tm_table */ defaultTranslations,
+ /* query_geometry */ NULL,
+ /* display_accelerator*/ NULL,
+ /* extension */ NULL
+ },{
+ /* geometry_manager */ GeometryManager,
+ /* change_managed */ ChangeManaged,
+ /* insert_child */ XtInheritInsertChild,
+ /* delete_child */ XtInheritDeleteChild,
+ /* extension */ NULL
+ },{
+ /* Shell extension */ NULL
+ },{
+ /* Override extension */ NULL
+ },{
+ /* Simple Menu extension*/ NULL
+ }
+};
+
+WidgetClass simpleMenuWidgetClass = (WidgetClass)&simpleMenuClassRec;
+
+#define SMW_ARROW_SIZE 8
+#define SMW_UNMAPPING 0x01
+#define SMW_POPLEFT 0x02
+
+#define ForAllChildren(smw, childP) \
+ for ((childP) = (SmeObject *) (smw)->composite.children; \
+ (childP) < (SmeObject *) ((smw)->composite.children + \
+ (smw)->composite.num_children); \
+ (childP)++)
+
+/************************************************************
+ *
+ * Semi-Public Functions.
+ *
+ ************************************************************/
+
+/* Function Name: ClassInitialize
+ * Description: Class Initialize routine, called only once.
+ * Arguments: none.
+ * Returns: none.
+ */
+
+static void
+ClassInitialize()
+{
+ XawInitializeWidgetSet();
+ XtAddConverter( XtRString, XtRBackingStore, XmuCvtStringToBackingStore,
+ (XtConvertArgList)NULL, (Cardinal)0 );
+ XmuAddInitializer( AddPositionAction, NULL);
+}
+
+/* Function Name: ClassInitialize
+ * Description: Class Part Initialize routine, called for every
+ * subclass. Makes sure that the subclasses pick up
+ * the extension record.
+ * Arguments: wc - the widget class of the subclass.
+ * Returns: none.
+ */
+
+static void
+ClassPartInitialize(wc)
+WidgetClass wc;
+{
+ SimpleMenuWidgetClass smwc = (SimpleMenuWidgetClass) wc;
+
+/*
+ * Make sure that our subclass gets the extension rec too.
+ */
+
+ extension_rec.next_extension = smwc->composite_class.extension;
+ smwc->composite_class.extension = (XtPointer) &extension_rec;
+}
+
+/* Function Name: Initialize
+ * Description: Initializes the simple menu widget
+ * Arguments: request - the widget requested by the argument list.
+ * new - the new widget with both resource and non
+ * resource values.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+Initialize(request, new, args, num_args)
+Widget request, new;
+ArgList args;
+Cardinal *num_args;
+{
+ SimpleMenuWidget smw = (SimpleMenuWidget) new;
+
+ XmuCallInitializers(XtWidgetToApplicationContext(new));
+
+ smw->simple_menu.label = NULL;
+ smw->simple_menu.entry_set = NULL;
+ smw->simple_menu.recursive_set_values = FALSE;
+ smw->simple_menu.first_entry = NULL;
+ smw->simple_menu.current_first = NULL;
+ smw->simple_menu.first_y = 0;
+ smw->simple_menu.too_tall = FALSE;
+ smw->simple_menu.sub_menu = NULL;
+ smw->simple_menu.state = 0;
+
+ XtAddCallback(new, XtNpopupCallback, PopupCB, NULL);
+
+ if (smw->simple_menu.label_class == NULL)
+ smw->simple_menu.label_class = smeBSBObjectClass;
+
+ if (smw->simple_menu.label_string != NULL)
+ CreateLabel(new);
+
+ /* GetMenuHeight() needs this */
+ smw->simple_menu.threeD = XtVaCreateWidget("threeD", threeDWidgetClass,
+ new,
+ XtNx, 0, XtNy, 0, XtNwidth, /* dummy */ 10, XtNheight, /* dummy */ 10,
+ NULL);
+
+ smw->simple_menu.menu_width = TRUE;
+
+ if (smw->core.width == 0) {
+ smw->simple_menu.menu_width = FALSE;
+ smw->core.width = GetMenuWidth(new, (Widget)NULL);
+ }
+
+ smw->simple_menu.menu_height = TRUE;
+
+ if (smw->core.height == 0) {
+ smw->simple_menu.menu_height = FALSE;
+ smw->core.height = GetMenuHeight(new);
+ }
+
+ /* add a popup_callback routine for changing the cursor */
+ XtAddCallback(new, XtNpopupCallback, ChangeCursorOnGrab, (XtPointer)NULL);
+}
+
+/* Function Name: Redisplay
+ * Description: Redisplays the contents of the widget.
+ * Arguments: w - the simple menu widget.
+ * event - the X event that caused this redisplay.
+ * region - the region the needs to be repainted.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+Redisplay(w, event, region)
+Widget w;
+XEvent * event;
+Region region;
+{
+ SimpleMenuWidget smw = (SimpleMenuWidget)w;
+ SmeObject *entry;
+ SmeObjectClass class;
+ ThreeDWidget tdw = (ThreeDWidget)smw->simple_menu.threeD;
+ RectObjPart old_pos;
+ int y, max_y, new_y, dy, s = tdw->threeD.shadow_width;
+ Boolean can_paint;
+ XPoint point[3];
+
+ if (region == NULL)
+ XClearWindow(XtDisplay(w), XtWindow(w));
+
+ if (XtIsRealized((Widget)smw))
+ _ShadowSurroundedBox((Widget)smw, tdw,
+ 0, 0, smw->core.width, smw->core.height,
+ tdw->threeD.relief, True);
+
+ smw->simple_menu.didnt_fit = False;
+ y = 0;
+ max_y = HeightOfScreen(XtScreen(w)) - s;
+ new_y = -(*(SmeObject *)(smw)->composite.children)->rectangle.y;
+ can_paint = False;
+
+ /* check and paint each of the entries - including the label */
+ ForAllChildren(smw, entry)
+ {
+ if (!XtIsManaged((Widget)*entry)) continue;
+
+ if (smw->simple_menu.first_entry == NULL)
+ {
+ smw->simple_menu.first_entry = entry;
+ smw->simple_menu.current_first = entry;
+ }
+
+ if (smw->simple_menu.too_tall)
+ {
+ dy = 0;
+
+ if (entry == (smw->simple_menu.current_first))
+ {
+ new_y = (*entry)->rectangle.y - 1;
+
+ if (smw->simple_menu.current_first != smw->simple_menu.first_entry)
+ {
+ point[0].x = (*entry)->rectangle.width / 2;
+ point[0].y = s + 1;
+ point[1].x = (*entry)->rectangle.width / 2 - SMW_ARROW_SIZE / 2;
+ point[1].y = s + SMW_ARROW_SIZE;
+ point[2].x = (*entry)->rectangle.width / 2 + SMW_ARROW_SIZE / 2;
+ point[2].y = s + SMW_ARROW_SIZE;
+ XFillPolygon(XtDisplay(w), smw->core.window,
+ tdw->threeD.bot_shadow_GC, point, 3, Convex,
+ CoordModeOrigin);
+
+ new_y -= SMW_ARROW_SIZE;
+ dy = SMW_ARROW_SIZE;
+ }
+
+ smw->simple_menu.first_y = new_y;
+ can_paint = True;
+ }
+ else if (!can_paint)
+ continue;
+
+ old_pos = (*entry)->rectangle;
+ (*entry)->rectangle.y -= new_y;
+
+ if ((*entry)->rectangle.y + (*entry)->rectangle.height + dy > max_y)
+ {
+ smw->simple_menu.last_y = (*entry)->rectangle.y;
+ point[0].x = (*entry)->rectangle.width / 2;
+ point[0].y = max_y - 1;
+ point[1].x = (*entry)->rectangle.width / 2 - SMW_ARROW_SIZE / 2;
+ point[1].y = max_y - SMW_ARROW_SIZE;
+ point[2].x = (*entry)->rectangle.width / 2 + SMW_ARROW_SIZE / 2;
+ point[2].y = max_y - SMW_ARROW_SIZE;
+ XFillPolygon(XtDisplay(w), smw->core.window,
+ tdw->threeD.bot_shadow_GC, point, 3, Convex,
+ CoordModeOrigin);
+
+ smw->simple_menu.didnt_fit = True;
+ (*entry)->rectangle = old_pos;
+ break;
+ }
+ }
+
+ /*
+ if (region != NULL)
+ switch (XRectInRegion(region,
+ (int)(*entry)->rectangle.x, (int)(*entry)->rectangle.y,
+ (unsigned int)(*entry)->rectangle.width,
+ (unsigned int)(*entry)->rectangle.height))
+ {
+ case RectangleIn:
+ case RectanglePart:
+ break;
+ default:
+ continue;
+ }
+ */
+
+ class = (SmeObjectClass)(*entry)->object.widget_class;
+
+ if (class->rect_class.expose != NULL)
+ (class->rect_class.expose)((Widget)*entry, NULL, NULL);
+
+ if (smw->simple_menu.too_tall) (*entry)->rectangle = old_pos;
+
+ y += (*entry)->rectangle.height;
+ }
+}
+
+/* Function Name: Realize
+ * Description: Realizes the widget.
+ * Arguments: w - the simple menu widget.
+ * mask - value mask for the window to create.
+ * attrs - attributes for the window to create.
+ * Returns: none
+ */
+
+static void
+Realize(w, mask, attrs)
+Widget w;
+XtValueMask * mask;
+XSetWindowAttributes * attrs;
+{
+ SimpleMenuWidget smw = (SimpleMenuWidget) w;
+
+ attrs->cursor = smw->simple_menu.cursor;
+ *mask |= CWCursor;
+ if ((smw->simple_menu.backing_store == Always) ||
+ (smw->simple_menu.backing_store == NotUseful) ||
+ (smw->simple_menu.backing_store == WhenMapped) ) {
+ *mask |= CWBackingStore;
+ attrs->backing_store = smw->simple_menu.backing_store;
+ }
+ else
+ *mask &= ~CWBackingStore;
+
+ /* check if the menu is too big */
+ if (smw->core.height >= HeightOfScreen(XtScreen(w))) {
+ smw->simple_menu.too_tall = TRUE;
+ smw->core.height = HeightOfScreen(XtScreen(w));
+ }
+
+ (*superclass->core_class.realize) (w, mask, attrs);
+}
+
+/* Function Name: Resize
+ * Description: Handle the menu being resized.
+ * Arguments: w - the simple menu widget or any of its object children.
+ * Returns: none.
+ */
+
+static void
+Resize(w)
+Widget w;
+{
+ /*
+ * The sole purpose of this function is to force an initial
+ * layout by handling a call from some child widget. Ick.
+ */
+
+ if (XtIsSubclass(w, smeBSBObjectClass))
+ {
+ Widget parent = XtParent(w);
+
+ if (!XtIsRealized(parent))
+ XtRealizeWidget(parent);
+
+ Layout(w, (Dimension *)NULL, (Dimension *)NULL);
+ }
+}
+
+/* Function Name: SetValues
+ * Description: Relayout the menu when one of the resources is changed.
+ * Arguments: current - current state of the widget.
+ * request - what was requested.
+ * new - what the widget will become.
+ * Returns: none
+ */
+
+/* ARGSUSED */
+static Boolean
+SetValues(current, request, new, args, num_args)
+Widget current, request, new;
+ArgList args;
+Cardinal *num_args;
+{
+ SimpleMenuWidget smw_old = (SimpleMenuWidget) current;
+ SimpleMenuWidget smw_new = (SimpleMenuWidget) new;
+ Boolean ret_val = FALSE, layout = FALSE;
+
+ if (!XtIsRealized(current)) return(FALSE);
+
+ if (!smw_new->simple_menu.recursive_set_values) {
+ if (smw_new->core.width != smw_old->core.width) {
+ smw_new->simple_menu.menu_width = (smw_new->core.width != 0);
+ layout = TRUE;
+ }
+ if (smw_new->core.height != smw_old->core.height) {
+ smw_new->simple_menu.menu_height = (smw_new->core.height != 0);
+ layout = TRUE;
+ }
+ }
+
+ if (smw_old->simple_menu.cursor != smw_new->simple_menu.cursor)
+ XDefineCursor(XtDisplay(new),
+ XtWindow(new), smw_new->simple_menu.cursor);
+
+ if (smw_old->simple_menu.label_string !=smw_new->simple_menu.label_string)
+ if (smw_new->simple_menu.label_string == NULL) /* Destroy. */
+ XtDestroyWidget((Widget) smw_old->simple_menu.label);
+ else if (smw_old->simple_menu.label_string == NULL) /* Create. */
+ CreateLabel(new);
+ else { /* Change. */
+ Arg arglist[1];
+
+ XtSetArg(arglist[0], XtNlabel, smw_new->simple_menu.label_string);
+ XtSetValues((Widget) smw_new->simple_menu.label, arglist, ONE);
+ }
+
+ if (smw_old->simple_menu.label_class != smw_new->simple_menu.label_class)
+ XtAppWarning(XtWidgetToApplicationContext(new),
+ "No Dynamic class change of the SimpleMenu Label.");
+
+ if ((smw_old->simple_menu.top_margin != smw_new->simple_menu.top_margin) ||
+ (smw_old->simple_menu.bottom_margin !=
+ smw_new->simple_menu.bottom_margin) /* filler................. */ ) {
+ layout = TRUE;
+ ret_val = TRUE;
+ }
+
+ if (smw_old->simple_menu.left_whitespace != smw_new->simple_menu.left_whitespace) {
+ layout = TRUE;
+ ret_val = TRUE;
+ }
+
+ if (smw_old->simple_menu.right_whitespace != smw_new->simple_menu.right_whitespace) {
+ layout = TRUE;
+ ret_val = TRUE;
+ }
+
+ if (layout)
+ Layout(new, (Dimension *)NULL, (Dimension *)NULL);
+
+ return(ret_val);
+}
+
+/* Function Name: SetValuesHook
+ * Description: To handle a special case, this is passed the
+ * actual arguments.
+ * Arguments: w - the menu widget.
+ * arglist - the argument list passed to XtSetValues.
+ * num_args - the number of args.
+ * Returns: none
+ */
+
+/*
+ * If the user actually passed a width and height to the widget
+ * then this MUST be used, rather than our newly calculated width and
+ * height.
+ */
+
+static Boolean
+SetValuesHook(w, arglist, num_args)
+Widget w;
+ArgList arglist;
+Cardinal *num_args;
+{
+ Cardinal i;
+ Dimension width, height;
+
+ width = w->core.width;
+ height = w->core.height;
+
+ for ( i = 0 ; i < *num_args ; i++) {
+ if ( streq(arglist[i].name, XtNwidth) )
+ width = (Dimension) arglist[i].value;
+ if ( streq(arglist[i].name, XtNheight) )
+ height = (Dimension) arglist[i].value;
+ }
+
+ if ((width != w->core.width) || (height != w->core.height))
+ MakeSetValuesRequest(w, width, height);
+ return(FALSE);
+}
+
+/************************************************************
+ *
+ * Geometry Management routines.
+ *
+ ************************************************************/
+
+/* Function Name: GeometryManager
+ * Description: This is the SimpleMenu Widget's Geometry Manager.
+ * Arguments: w - the Menu Entry making the request.
+ * request - requested new geometry.
+ * reply - the allowed geometry.
+ * Returns: XtGeometry{Yes, No, Almost}.
+ */
+
+static XtGeometryResult
+GeometryManager(w, request, reply)
+Widget w;
+XtWidgetGeometry * request, * reply;
+{
+ SimpleMenuWidget smw = (SimpleMenuWidget) XtParent(w);
+ SmeObject entry = (SmeObject) w;
+ XtGeometryMask mode = request->request_mode;
+ XtGeometryResult answer;
+ Dimension old_height, old_width;
+
+ if ( !(mode & CWWidth) && !(mode & CWHeight) )
+ return(XtGeometryNo);
+
+ reply->width = request->width;
+ reply->height = request->height;
+
+ old_width = entry->rectangle.width;
+ old_height = entry->rectangle.height;
+
+ Layout(w, &(reply->width), &(reply->height) );
+
+/*
+ * Since we are an override shell and have no parent there is no one to
+ * ask to see if this geom change is okay, so I am just going to assume
+ * we can do whatever we want. If you subclass be very careful with this
+ * assumption, it could bite you.
+ *
+ * Chris D. Peterson - Sept. 1989.
+ */
+
+ if ( (reply->width == request->width) &&
+ (reply->height == request->height) ) {
+
+ if ( mode & XtCWQueryOnly ) {
+ entry->rectangle.width = old_width;
+ entry->rectangle.height = old_height;
+ }
+ else {
+ /* Actually perform the layout */
+ Layout(( Widget) smw, (Dimension *)NULL, (Dimension *)NULL);
+ }
+ answer = XtGeometryDone;
+ }
+ else {
+ entry->rectangle.width = old_width;
+ entry->rectangle.height = old_height;
+
+ if ( ((reply->width == request->width) && !(mode & CWHeight)) ||
+ ((reply->height == request->height) && !(mode & CWWidth)) ||
+ ((reply->width == request->width) &&
+ (reply->height == request->height)) )
+ answer = XtGeometryNo;
+ else {
+ answer = XtGeometryAlmost;
+ reply->request_mode = 0;
+ if (reply->width != request->width)
+ reply->request_mode |= CWWidth;
+ if (reply->height != request->height)
+ reply->request_mode |= CWHeight;
+ }
+ }
+ return(answer);
+}
+
+/* Function Name: ChangeManaged
+ * Description: called whenever a new child is managed.
+ * Arguments: w - the simple menu widget.
+ * Returns: none.
+ */
+
+static void
+ChangeManaged(w)
+Widget w;
+{
+ Layout(w, (Dimension *)NULL, (Dimension *)NULL);
+}
+
+/************************************************************
+ *
+ * Global Action Routines.
+ *
+ * These actions routines will be added to the application's
+ * global action list.
+ *
+ ************************************************************/
+
+/* Function Name: PositionMenuAction
+ * Description: Positions the simple menu widget.
+ * Arguments: w - a widget (no the simple menu widget.)
+ * event - the event that caused this action.
+ * params, num_params - parameters passed to the routine.
+ * we expect the name of the menu here.
+ * Returns: none
+ */
+
+/* ARGSUSED */
+static void
+PositionMenuAction(w, event, params, num_params)
+Widget w;
+XEvent * event;
+String * params;
+Cardinal * num_params;
+{
+ Widget menu;
+ XPoint loc;
+
+ if (*num_params != 1) {
+ char error_buf[BUFSIZ];
+ (void) sprintf(error_buf, "%s %s",
+ "Xaw - SimpleMenuWidget: position menu action expects only one",
+ "parameter which is the name of the menu.");
+ XtAppWarning(XtWidgetToApplicationContext(w), error_buf);
+ return;
+ }
+
+ if ( (menu = FindMenu(w, params[0])) == NULL) {
+ char error_buf[BUFSIZ];
+ (void) sprintf(error_buf, "%s '%s'",
+ "Xaw - SimpleMenuWidget: could not find menu named: ", params[0]);
+ XtAppWarning(XtWidgetToApplicationContext(w), error_buf);
+ return;
+ }
+
+ switch (event->type) {
+ case ButtonPress:
+ case ButtonRelease:
+ loc.x = event->xbutton.x_root;
+ loc.y = event->xbutton.y_root;
+ PositionMenu(menu, &loc);
+ break;
+ case EnterNotify:
+ case LeaveNotify:
+ loc.x = event->xcrossing.x_root;
+ loc.y = event->xcrossing.y_root;
+ PositionMenu(menu, &loc);
+ break;
+ case MotionNotify:
+ loc.x = event->xmotion.x_root;
+ loc.y = event->xmotion.y_root;
+ PositionMenu(menu, &loc);
+ break;
+ default:
+ PositionMenu(menu, (XPoint *)NULL);
+ break;
+ }
+}
+
+/************************************************************
+ *
+ * Widget Action Routines.
+ *
+ ************************************************************/
+
+/* Function Name: Unhighlight
+ * Description: Unhighlights current entry.
+ * Arguments: w - the simple menu widget.
+ * event - the event that caused this action.
+ * params, num_params - ** NOT USED **
+ * Returns: none
+ */
+
+/* ARGSUSED */
+static void
+Unhighlight(w, event, params, num_params)
+Widget w;
+XEvent * event;
+String * params;
+Cardinal * num_params;
+{
+ SimpleMenuWidget smw = (SimpleMenuWidget) w;
+ SimpleMenuWidget sub = (SimpleMenuWidget) smw->simple_menu.sub_menu;
+ SmeObject entry = smw->simple_menu.entry_set;
+ SmeObjectClass class;
+ int old_pos;
+
+ if (entry == NULL || entry == GetEventEntry(w, event)) {
+ smw->simple_menu.entry_set = NULL;
+ PopdownSubMenu(smw);
+ return;
+ }
+
+ if (event->xcrossing.y < 0 || event->xcrossing.y >= (int)smw->core.height)
+ PopdownSubMenu(smw);
+ else if (sub &&
+ ((event->xcrossing.x < 0 &&
+ !(sub->simple_menu.state & SMW_POPLEFT)) ||
+ (event->xcrossing.x >= (int)smw->core.width &&
+ (sub->simple_menu.state & SMW_POPLEFT))))
+ PopdownSubMenu(smw);
+
+ smw->simple_menu.entry_set = NULL;
+ class = (SmeObjectClass) entry->object.widget_class;
+
+ /* backup, then restore, original entry position */
+ old_pos = entry->rectangle.y;
+ entry->rectangle.y -= smw->simple_menu.first_y;
+
+ (class->sme_class.unhighlight) ((Widget) entry);
+
+ entry->rectangle.y = old_pos;
+}
+
+/* Function Name: Highlight
+ * Description: Highlights current entry.
+ * Arguments: w - the simple menu widget.
+ * event - the event that caused this action.
+ * params, num_params - ** NOT USED **
+ * Returns: none
+ */
+
+/* ARGSUSED */
+static void
+Highlight(w, event, params, num_params)
+Widget w;
+XEvent * event;
+String * params;
+Cardinal * num_params;
+{
+ SimpleMenuWidget smw = (SimpleMenuWidget) w;
+ SmeObject entry;
+ SmeObjectClass class;
+ int old_pos;
+
+ if (!XtIsSensitive(w)) return;
+
+ entry = GetEventEntry(w, event);
+ if (entry == smw->simple_menu.entry_set)
+ return;
+
+ PopdownSubMenu(smw);
+ Unhighlight(w, event, params, num_params);
+
+ if (entry == NULL)
+ return;
+ if (!XtIsSensitive((Widget) entry)) {
+ smw->simple_menu.entry_set = NULL;
+ return;
+ }
+
+ if (!(smw->simple_menu.state & SMW_UNMAPPING)) {
+ smw->simple_menu.entry_set = entry;
+ class = (SmeObjectClass) entry->object.widget_class;
+
+ /* backup, then restore, original entry position */
+ old_pos = entry->rectangle.y;
+ entry->rectangle.y -= smw->simple_menu.first_y;
+
+ (class->sme_class.highlight) ((Widget) entry);
+ if (XtIsSubclass((Widget)entry, smeBSBObjectClass))
+ PopupSubMenu(smw);
+
+ entry->rectangle.y = old_pos;
+ }
+}
+
+/* Function Name: Notify
+ * Description: Notify user of current entry.
+ * Arguments: w - the simple menu widget.
+ * event - the event that caused this action.
+ * params, num_params - ** NOT USED **
+ * Returns: none
+ */
+
+/* ARGSUSED */
+static void
+Notify(w, event, params, num_params)
+Widget w;
+XEvent * event;
+String * params;
+Cardinal * num_params;
+{
+ SimpleMenuWidget smw = (SimpleMenuWidget) w;
+ SmeObject entry = smw->simple_menu.entry_set;
+ SmeObjectClass class;
+
+ if ( (entry == NULL) || !XtIsSensitive((Widget) entry ) ) return;
+
+ class = (SmeObjectClass) entry->object.widget_class;
+ (class->sme_class.notify)( (Widget) entry );
+}
+
+/************************************************************
+ *
+ * Public Functions.
+ *
+ ************************************************************/
+
+/* Function Name: XawSimpleMenuAddGlobalActions
+ * Description: adds the global actions to the simple menu widget.
+ * Arguments: app_con - the appcontext.
+ * Returns: none.
+ */
+
+void
+#if NeedFunctionPrototypes
+XawSimpleMenuAddGlobalActions(XtAppContext app_con)
+#else
+XawSimpleMenuAddGlobalActions(app_con)
+XtAppContext app_con;
+#endif
+{
+ XtInitializeWidgetClass(simpleMenuWidgetClass);
+ XmuCallInitializers( app_con );
+}
+
+
+/* Function Name: XawSimpleMenuGetActiveEntry
+ * Description: Gets the currently active (set) entry.
+ * Arguments: w - the smw widget.
+ * Returns: the currently set entry or NULL if none is set.
+ */
+
+Widget
+#if NeedFunctionPrototypes
+XawSimpleMenuGetActiveEntry(Widget w)
+#else
+XawSimpleMenuGetActiveEntry(w)
+Widget w;
+#endif
+{
+ SimpleMenuWidget smw = (SimpleMenuWidget) w;
+
+ return( (Widget) smw->simple_menu.entry_set);
+}
+
+/* Function Name: XawSimpleMenuClearActiveEntry
+ * Description: Unsets the currently active (set) entry.
+ * Arguments: w - the smw widget.
+ * Returns: none.
+ */
+
+void
+#if NeedFunctionPrototypes
+XawSimpleMenuClearActiveEntry(Widget w)
+#else
+XawSimpleMenuClearActiveEntry(w)
+Widget w;
+#endif
+{
+ SimpleMenuWidget smw = (SimpleMenuWidget) w;
+
+ smw->simple_menu.entry_set = NULL;
+}
+
+/************************************************************
+ *
+ * Private Functions.
+ *
+ ************************************************************/
+
+/* Function Name: CreateLabel
+ * Description: Creates a the menu label.
+ * Arguments: w - the smw widget.
+ * Returns: none.
+ *
+ * Creates the label object and makes sure it is the first child in
+ * in the list.
+ */
+
+static void
+CreateLabel(w)
+Widget w;
+{
+ SimpleMenuWidget smw = (SimpleMenuWidget) w;
+ Widget * child, * next_child;
+ int i;
+ Arg args[2];
+
+ if ( (smw->simple_menu.label_string == NULL) ||
+ (smw->simple_menu.label != NULL) ) {
+ char error_buf[BUFSIZ];
+
+ (void) sprintf(error_buf, "Xaw Simple Menu Widget: %s or %s, %s",
+ "label string is NULL", "label already exists",
+ "no label is being created.");
+ XtAppWarning(XtWidgetToApplicationContext(w), error_buf);
+ return;
+ }
+
+ XtSetArg(args[0], XtNlabel, smw->simple_menu.label_string);
+ XtSetArg(args[1], XtNjustify, XtJustifyCenter);
+ smw->simple_menu.label = (SmeObject)
+ XtCreateManagedWidget("menuLabel",
+ smw->simple_menu.label_class, w,
+ args, TWO);
+
+ next_child = NULL;
+ for (child = smw->composite.children + smw->composite.num_children,
+ i = smw->composite.num_children ; i > 0 ; i--, child--) {
+ if (next_child != NULL)
+ *next_child = *child;
+ next_child = child;
+ }
+ *child = (Widget) smw->simple_menu.label;
+}
+
+/* Function Name: Layout
+ * Description: lays the menu entries out all nice and neat.
+ * Arguments: w - See below (+++)
+ * width_ret, height_ret - The returned width and
+ * height values.
+ * Returns: none.
+ *
+ * if width == NULL || height == NULL then it assumes the you do not care
+ * about the return values, and just want a relayout.
+ *
+ * if this is not the case then it will set width_ret and height_ret
+ * to be width and height that the child would get if it were layed out
+ * at this time.
+ *
+ * +++ "w" can be the simple menu widget or any of its object children.
+ */
+
+static void
+Layout(w, width_ret, height_ret)
+Widget w;
+Dimension *width_ret, *height_ret;
+{
+ SmeObject current_entry, *entry;
+ SimpleMenuWidget smw;
+ ThreeDWidget tdw;
+ Dimension width, height;
+ Boolean do_layout = (height_ret == NULL || width_ret == NULL);
+ Boolean allow_change_size;
+ height = 0;
+
+ if (XtIsSubclass(w, simpleMenuWidgetClass))
+ {
+ smw = (SimpleMenuWidget)w;
+ current_entry = NULL;
+ }
+ else
+ {
+ smw = (SimpleMenuWidget)XtParent(w);
+ current_entry = (SmeObject)w;
+ }
+ tdw = (ThreeDWidget)smw->simple_menu.threeD;
+
+ do_layout |= (current_entry != NULL);
+ allow_change_size =
+ (!XtIsRealized((Widget)smw) || smw->shell.allow_shell_resize);
+
+ if (smw->simple_menu.menu_height)
+ height = smw->core.height;
+ else if (do_layout)
+ {
+ height = smw->simple_menu.top_margin + tdw->threeD.shadow_width;
+
+ ForAllChildren(smw, entry)
+ {
+ if (!XtIsManaged((Widget)*entry)) continue;
+
+ if (smw->simple_menu.row_height != 0 &&
+ *entry != smw->simple_menu.label)
+ (*entry)->rectangle.height = smw->simple_menu.row_height;
+
+ (*entry)->rectangle.y = height;
+ (*entry)->rectangle.x = 0;
+ height += (*entry)->rectangle.height;
+ }
+
+ height += smw->simple_menu.bottom_margin + tdw->threeD.shadow_width;
+ }
+ else if (smw->simple_menu.row_height != 0 &&
+ current_entry != smw->simple_menu.label)
+ {
+ height = smw->simple_menu.row_height * smw->composite.num_children;
+ height += tdw->threeD.shadow_width * 2;
+ }
+
+ if (smw->simple_menu.menu_width)
+ width = smw->core.width;
+ else if (allow_change_size)
+ {
+ SetMarginWidths((Widget)smw);
+
+ width = GetMenuWidth((Widget)smw, (Widget)NULL);
+ }
+ else
+ width = smw->core.width;
+
+ if (do_layout)
+ {
+ ForAllChildren(smw, entry)
+ if (XtIsManaged((Widget)*entry))
+ (*entry)->rectangle.width = width;
+
+ if (allow_change_size)
+ MakeSetValuesRequest((Widget) smw, width, height);
+ }
+ else
+ {
+ *width_ret = width;
+ if (height != 0) *height_ret = height;
+ }
+}
+
+/* Function Name: AddPositionAction
+ * Description: Adds the XawPositionSimpleMenu action to the global
+ * action list for this appcon.
+ * Arguments: app_con - the application context for this app.
+ * data - NOT USED.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+AddPositionAction(app_con, data)
+XtAppContext app_con;
+XPointer data;
+{
+ static XtActionsRec pos_action[] = {
+ { "XawPositionSimpleMenu", PositionMenuAction },
+ };
+
+ XtAppAddActions(app_con, pos_action, XtNumber(pos_action));
+}
+
+/* Function Name: FindMenu
+ * Description: Find the menu give a name and reference widget.
+ * Arguments: widget - reference widget.
+ * name - the menu widget's name.
+ * Returns: the menu widget or NULL.
+ */
+
+static Widget
+FindMenu(widget, name)
+Widget widget;
+String name;
+{
+ Widget w, menu;
+
+ for ( w = widget ; w != NULL ; w = XtParent(w) )
+ if ( (menu = XtNameToWidget(w, name)) != NULL )
+ return(menu);
+ return(NULL);
+}
+
+/* Function Name: PositionMenu
+ * Description: Places the menu
+ * Arguments: w - the simple menu widget.
+ * location - a pointer the the position or NULL.
+ * Returns: none.
+ */
+
+static void
+PositionMenu(w, location)
+Widget w;
+XPoint * location;
+{
+ SimpleMenuWidget smw = (SimpleMenuWidget) w;
+ SmeObject entry;
+ XPoint t_point;
+
+ if (location == NULL) {
+ Window junk1, junk2;
+ int root_x, root_y, junkX, junkY;
+ unsigned int junkM;
+
+ location = &t_point;
+ if (XQueryPointer(XtDisplay(w), XtWindow(w), &junk1, &junk2,
+ &root_x, &root_y, &junkX, &junkY, &junkM) == FALSE) {
+ char error_buf[BUFSIZ];
+ (void) sprintf(error_buf, "%s %s", "Xaw Simple Menu Widget:",
+ "Could not find location of mouse pointer");
+ XtAppWarning(XtWidgetToApplicationContext(w), error_buf);
+ return;
+ }
+ location->x = (short) root_x;
+ location->y = (short) root_y;
+ }
+
+ /*
+ * The width will not be correct unless it is realized.
+ */
+
+ XtRealizeWidget(w);
+
+ location->x -= (Position) w->core.width/2;
+
+ if (smw->simple_menu.popup_entry == NULL)
+ entry = smw->simple_menu.label;
+ else
+ entry = smw->simple_menu.popup_entry;
+
+ if (entry != NULL)
+ location->y -= entry->rectangle.y + entry->rectangle.height/2;
+
+ MoveMenu(w, (Position) location->x, (Position) location->y);
+}
+
+/* Function Name: MoveMenu
+ * Description: Actually moves the menu, may force it to
+ * to be fully visable if menu_on_screen is TRUE.
+ * Arguments: w - the simple menu widget.
+ * x, y - the current location of the widget.
+ * Returns: none
+ */
+
+static void
+MoveMenu(w, x, y)
+Widget w;
+Position x, y;
+{
+ SimpleMenuWidget smw = (SimpleMenuWidget) w;
+ Arg arglist[2];
+
+ if (smw->simple_menu.menu_on_screen) {
+ int width = w->core.width + 2 * w->core.border_width;
+ int height = w->core.height + 2 * w->core.border_width;
+
+ if (x >= 0) {
+ int scr_width = WidthOfScreen(XtScreen(w));
+ if (x + width > scr_width)
+ x = scr_width - width;
+ }
+ if (x < 0)
+ x = 0;
+
+ if (y >= 0) {
+ int scr_height = HeightOfScreen(XtScreen(w));
+ if (y + height > scr_height)
+ y = scr_height - height;
+ }
+ if (y < 0)
+ y = 0;
+ }
+
+ XtSetArg(arglist[0], XtNx, x);
+ XtSetArg(arglist[1], XtNy, y);
+ XtSetValues(w, arglist, TWO);
+}
+
+/* Function Name: ChangeCursorOnGrab
+ * Description: Changes the cursor on the active grab to the one
+ * specified in out resource list.
+ * Arguments: w - the widget.
+ * junk, garbage - ** NOT USED **.
+ * Returns: None.
+ */
+
+/* ARGSUSED */
+static void
+ChangeCursorOnGrab(w, junk, garbage)
+Widget w;
+XtPointer junk, garbage;
+{
+ SimpleMenuWidget smw = (SimpleMenuWidget) w;
+
+ /*
+ * The event mask here is what is currently in the MIT implementation.
+ * There really needs to be a way to get the value of the mask out
+ * of the toolkit (CDP 5/26/89).
+ */
+
+ XChangeActivePointerGrab(XtDisplay(w), ButtonPressMask|ButtonReleaseMask,
+ smw->simple_menu.cursor,
+ XtLastTimestampProcessed(XtDisplay(w)));
+}
+
+/* Function Name: MakeSetValuesRequest
+ * Description: Makes a (possibly recursive) call to SetValues,
+ * I take great pains to not go into an infinite loop.
+ * Arguments: w - the simple menu widget.
+ * width, height - the size of the ask for.
+ * Returns: none
+ */
+
+static void
+MakeSetValuesRequest(w, width, height)
+Widget w;
+Dimension width, height;
+{
+ SimpleMenuWidget smw = (SimpleMenuWidget) w;
+
+ if ( !smw->simple_menu.recursive_set_values ) {
+ if ( (smw->core.width != width) || (smw->core.height != height) ) {
+ Arg arglist[2];
+
+ smw->simple_menu.recursive_set_values = TRUE;
+ XtSetArg(arglist[0], XtNwidth, width);
+ XtSetArg(arglist[1], XtNheight, height);
+ XtSetValues(w, arglist, TWO);
+ }
+ else if (XtIsRealized( (Widget) smw))
+ Redisplay((Widget) smw, (XEvent *) NULL, (Region) NULL);
+ }
+ smw->simple_menu.recursive_set_values = FALSE;
+}
+
+/*
+ * Function Name: SetMarginWidths()
+ * Description: Set new margin values for all menu children.
+ * Arguments: w - the simple menu widget
+ * w_ent - the current menu entry
+ */
+static void
+SetMarginWidths(w)
+Widget w;
+{
+ SimpleMenuWidget smw = (SimpleMenuWidget)w;
+ SmeObject *entry;
+ SmeBSBObject bsb_entry;
+ Dimension l_mrgn, l_bmw, r_mrgn, r_bmw;
+
+ if (smw->simple_menu.left_whitespace || smw->simple_menu.right_whitespace)
+ {
+ /* determine the widest bitmaps */
+ l_bmw = r_bmw = (Dimension)0;
+ ForAllChildren(smw, entry)
+ {
+ if (!XtIsManaged((Widget)*entry)) continue;
+ if (*entry == smw->simple_menu.label) continue;
+ if (XtIsSubclass((Widget)*entry, smeLineObjectClass))
+ continue;
+
+ bsb_entry = (SmeBSBObject)&((*entry)->object);
+ if (bsb_entry->sme_bsb.left_bitmap_width > l_bmw)
+ l_bmw = bsb_entry->sme_bsb.left_bitmap_width;
+ if (bsb_entry->sme_bsb.right_bitmap_width > r_bmw)
+ r_bmw = bsb_entry->sme_bsb.right_bitmap_width;
+ }
+
+ /* set the margin values */
+ if (smw->simple_menu.left_whitespace)
+ l_mrgn = l_bmw +
+ (smw->simple_menu.left_whitespace * ((l_bmw) ? 2 : 1));
+ if (smw->simple_menu.right_whitespace)
+ r_mrgn = r_bmw +
+ (smw->simple_menu.right_whitespace * ((r_bmw) ? 2 : 1));
+
+ /* make all the margins uniform */
+ ForAllChildren(smw, entry)
+ {
+ if (!XtIsManaged((Widget)*entry)) continue;
+ if (*entry == smw->simple_menu.label) continue;
+ if (XtIsSubclass((Widget)*entry, smeLineObjectClass))
+ continue;
+
+ bsb_entry = (SmeBSBObject)&((*entry)->object);
+ if (smw->simple_menu.left_whitespace)
+ bsb_entry->sme_bsb.left_margin = l_mrgn;
+ if (smw->simple_menu.right_whitespace)
+ bsb_entry->sme_bsb.right_margin = r_mrgn;
+ }
+ }
+}
+
+/* Function Name: GetMenuWidth
+ * Description: Sets the width to the widest entry in pixels.
+ * Arguments: w - the simple menu widget.
+ * w_ent - the current menu entry.
+ * Returns: width of menu.
+ */
+
+static Dimension
+GetMenuWidth(w, w_ent)
+Widget w, w_ent;
+{
+ SmeObject cur_entry = (SmeObject) w_ent;
+ SimpleMenuWidget smw = (SimpleMenuWidget) w;
+ Dimension width, widest = (Dimension) 0;
+ SmeObject * entry;
+
+ if ( smw->simple_menu.menu_width )
+ return(smw->core.width);
+
+ ForAllChildren(smw, entry) {
+ XtWidgetGeometry preferred;
+
+ if (!XtIsManaged( (Widget) *entry)) continue;
+
+ if (*entry != cur_entry) {
+ XtQueryGeometry((Widget) *entry, (XtWidgetGeometry *)NULL, &preferred);
+
+ if (preferred.request_mode & CWWidth)
+ width = preferred.width;
+ else
+ width = (*entry)->rectangle.width;
+ }
+ else
+ width = (*entry)->rectangle.width;
+
+ if ( width > widest )
+ widest = width;
+ }
+
+ return(widest);
+}
+
+/* Function Name: GetMenuHeight
+ * Description: Sets the height to all the entries in pixels.
+ * Arguments: w - the simple menu widget.
+ * Returns: height of menu.
+ */
+
+static Dimension
+GetMenuHeight(w)
+Widget w;
+{
+ SimpleMenuWidget smw = (SimpleMenuWidget) w;
+ ThreeDWidget tdw = (ThreeDWidget) smw->simple_menu.threeD;
+ SmeObject * entry;
+ Dimension height;
+
+ if (smw->simple_menu.menu_height)
+ return(smw->core.height);
+
+ height = smw->simple_menu.top_margin + smw->simple_menu.bottom_margin;
+ height += tdw->threeD.shadow_width * 2;
+
+ if (smw->simple_menu.row_height == 0) {
+ ForAllChildren(smw, entry)
+ if (XtIsManaged ((Widget) *entry))
+ height += (*entry)->rectangle.height;
+ } else
+ height += smw->simple_menu.row_height * smw->composite.num_children;
+
+ return(height);
+}
+
+/* Function Name: GetEventEntry
+ * Description: Gets an entry given an event that has X and Y coords.
+ * Arguments: w - the simple menu widget.
+ * event - the event.
+ * Returns: the entry that this point is in.
+ */
+
+static SmeObject
+GetEventEntry(w, event)
+Widget w;
+XEvent * event;
+{
+ Position x_loc = 0, y_loc = 0;
+ SimpleMenuWidget smw = (SimpleMenuWidget)w;
+ SmeObject *entry;
+ static XPoint last_pos;
+ XPoint pos;
+ int s = ((ThreeDWidget)smw->simple_menu.threeD)->threeD.shadow_width;
+
+ switch (event->type) {
+ case MotionNotify:
+ x_loc = event->xmotion.x;
+ y_loc = event->xmotion.y;
+ pos.y = event->xmotion.y_root;
+ break;
+ case EnterNotify:
+ case LeaveNotify:
+ x_loc = event->xcrossing.x;
+ y_loc = event->xcrossing.y;
+ pos.y = event->xcrossing.y_root;
+ break;
+ case ButtonPress:
+ case ButtonRelease:
+ x_loc = event->xbutton.x;
+ y_loc = event->xbutton.y;
+ pos.y = event->xbutton.y_root;
+ break;
+ default:
+ XtAppError(XtWidgetToApplicationContext(w),
+ "Unknown event type in GetEventEntry().");
+ break;
+ }
+
+ if (x_loc < 0 || x_loc >= (int)smw->core.width)
+ return NULL;
+ else if (smw->simple_menu.too_tall) {
+ if (pos.y >= smw->simple_menu.last_y && smw->simple_menu.didnt_fit) {
+ if (last_pos.y && pos.y < last_pos.y) {
+ last_pos.y = pos.y;
+ return NULL;
+ }
+ smw->simple_menu.current_first += smw->simple_menu.jump_val;
+ Redisplay(w, (XEvent *)NULL, (Region)NULL);
+ last_pos.y = pos.y;
+ return NULL;
+ } else if (pos.y <= s + SMW_ARROW_SIZE &&
+ smw->simple_menu.first_entry != smw->simple_menu.current_first)
+ {
+ if (pos.y && (!last_pos.y || pos.y > last_pos.y)) {
+ last_pos.y = pos.y;
+ return NULL;
+ }
+ smw->simple_menu.current_first -= smw->simple_menu.jump_val;
+ Redisplay(w, (XEvent *)NULL, (Region)NULL);
+ last_pos.y = pos.y;
+ return NULL;
+ }
+ else
+ last_pos.y = 0;
+ } else if (y_loc < 0 || y_loc >= (int)smw->core.height)
+ return NULL;
+
+ ForAllChildren(smw, entry) {
+ int tmp_y;
+
+ if (!XtIsManaged((Widget)*entry)) continue;
+
+ tmp_y = (*entry)->rectangle.y - smw->simple_menu.first_y;
+ if (tmp_y < y_loc && tmp_y + (int)(*entry)->rectangle.height > y_loc) {
+ if (*entry == smw->simple_menu.label)
+ return NULL; /* cannot select the label */
+ else
+ return *entry;
+ }
+ }
+
+ return NULL;
+}
+
+/*ARGSUSED*/
+static void
+PopupCB(w, client_data, call_data)
+Widget w;
+XtPointer client_data, call_data;
+{
+ SimpleMenuWidget smw = (SimpleMenuWidget)w;
+
+ smw->simple_menu.state &= ~SMW_UNMAPPING;
+}
+
+static void
+PopupSubMenu(smw)
+SimpleMenuWidget smw;
+{
+ Widget menu;
+ SmeBSBObject entry = (SmeBSBObject)smw->simple_menu.entry_set;
+ Position menu_x, menu_y;
+ Bool popleft;
+ Arg args[2];
+
+ if (entry->sme_bsb.menu_name == NULL)
+ return;
+
+ if ((menu = FindMenu((Widget)smw, entry->sme_bsb.menu_name)) == NULL)
+ return;
+
+ smw->simple_menu.sub_menu = menu;
+
+ if (!XtIsRealized(menu))
+ XtRealizeWidget(menu);
+
+ popleft = (smw->simple_menu.state & SMW_POPLEFT) != 0;
+
+ if (popleft)
+ XtTranslateCoords((Widget)smw, -(int)XtWidth(menu),
+ XtY(entry) - XtBorderWidth(menu), &menu_x, &menu_y);
+ else
+ XtTranslateCoords((Widget)smw, XtWidth(smw), XtY(entry)
+ - XtBorderWidth(menu), &menu_x, &menu_y);
+
+ if (!popleft && menu_x >= 0) {
+ int scr_width = WidthOfScreen(XtScreen(menu));
+
+ if (menu_x + XtWidth(menu) > scr_width) {
+ menu_x -= XtWidth(menu) + XtWidth(smw);
+ popleft = True;
+ }
+ }
+ else if (popleft && menu_x < 0) {
+ menu_x = 0;
+ popleft = False;
+ }
+
+ if (menu_y >= 0) {
+ ThreeDWidget tdw =
+ (ThreeDWidget)((SimpleMenuWidget)menu)->simple_menu.threeD;
+ int scr_height = HeightOfScreen(XtScreen(menu));
+
+ if (menu_y + XtHeight(menu) > scr_height)
+ menu_y = scr_height - XtHeight(menu) - XtBorderWidth(menu);
+
+ menu_y -= tdw->threeD.shadow_width;
+ }
+ if (menu_y < 0)
+ menu_y = 0;
+
+ XtSetArg(args[0], XtNx, menu_x);
+ XtSetArg(args[1], XtNy, menu_y);
+ XtSetValues(menu, args, TWO);
+
+ if (popleft)
+ ((SimpleMenuWidget)menu)->simple_menu.state |= SMW_POPLEFT;
+ else
+ ((SimpleMenuWidget)menu)->simple_menu.state &= ~SMW_POPLEFT;
+
+ XtPopup(menu, XtGrabNone);
+}
+
+static void
+Popdown(w, event, params, num_params)
+Widget w;
+XEvent *event;
+String *params;
+Cardinal *num_params;
+{
+ SimpleMenuWidget smw = (SimpleMenuWidget)w;
+
+ while (XtParent(w) &&
+ XtIsSubclass(XtParent(w), simpleMenuWidgetClass)) {
+ if (((SimpleMenuWidget)XtParent(w))->simple_menu.sub_menu == (Widget)w)
+ {
+ w = XtParent(w);
+ smw = (SimpleMenuWidget)w;
+ smw->simple_menu.entry_set = NULL;
+ }
+ else
+ break;
+ }
+
+ smw->simple_menu.state |= SMW_UNMAPPING;
+ PopdownSubMenu(smw);
+
+ XtCallActionProc(w, "XtMenuPopdown", event, params, *num_params);
+}
+
+static void
+PopdownSubMenu(smw)
+SimpleMenuWidget smw;
+{
+ SimpleMenuWidget menu = (SimpleMenuWidget)smw->simple_menu.sub_menu;
+
+ if (!menu) return;
+
+ menu->simple_menu.state &= ~SMW_POPLEFT;
+ menu->simple_menu.state |= SMW_UNMAPPING;
+ PopdownSubMenu(menu);
+
+ XtPopdown((Widget)menu);
+
+ smw->simple_menu.sub_menu = NULL;
+}
+
diff --git a/src/SimpleMenu.h b/src/SimpleMenu.h
new file mode 100644
index 0000000..9e4c45c
--- /dev/null
+++ b/src/SimpleMenu.h
@@ -0,0 +1,159 @@
+/*
+ * $XConsortium: SimpleMenu.h,v 1.22 94/04/17 20:12:47 kaleb Exp $
+ *
+Copyright (c) 1989, 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.
+ *
+ * Author: Chris D. Peterson, MIT X Consortium
+ */
+
+/*
+ * SimpleMenu.h - Public Header file for SimpleMenu widget.
+ *
+ * This is the public header file for the Athena SimpleMenu widget.
+ * It is intended to provide one pane pulldown and popup menus within
+ * the framework of the X Toolkit. As the name implies it is a first and
+ * by no means complete implementation of menu code. It does not attempt to
+ * fill the needs of all applications, but does allow a resource oriented
+ * interface to menus.
+ *
+ * Date: April 3, 1989
+ *
+ * By: Chris D. Peterson
+ * MIT X Consortium
+ * kit@expo.lcs.mit.edu
+ */
+
+#ifndef _SimpleMenu_h
+#define _SimpleMenu_h
+
+#include <X11/Shell.h>
+#include <X11/Xmu/Converters.h>
+
+/****************************************************************
+ *
+ * SimpleMenu widget
+ *
+ ****************************************************************/
+
+/* SimpleMenu Resources:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ background Background Pixel XtDefaultBackground
+ backgroundPixmap BackgroundPixmap Pixmap None
+ borderColor BorderColor Pixel XtDefaultForeground
+ borderPixmap BorderPixmap Pixmap None
+ borderWidth BorderWidth Dimension 1
+ bottomMargin VerticalMargins Dimension VerticalSpace
+ columnWidth ColumnWidth Dimension Width of widest text
+ cursor Cursor Cursor None
+ destroyCallback Callback Pointer NULL
+ height Height Dimension 0
+ label Label String NULL (No label)
+ labelClass LabelClass Pointer smeBSBObjectClass
+ mappedWhenManaged MappedWhenManaged Boolean True
+ rowHeight RowHeight Dimension Height of Font
+ sensitive Sensitive Boolean True
+ topMargin VerticalMargins Dimension VerticalSpace
+ width Width Dimension 0
+ x Position Position 0n
+ y Position Position 0
+
+*/
+
+typedef struct _SimpleMenuClassRec* SimpleMenuWidgetClass;
+typedef struct _SimpleMenuRec* SimpleMenuWidget;
+
+extern WidgetClass simpleMenuWidgetClass;
+
+#define XtNcursor "cursor"
+#define XtNbottomMargin "bottomMargin"
+#define XtNcolumnWidth "columnWidth"
+#define XtNlabelClass "labelClass"
+#define XtNmenuOnScreen "menuOnScreen"
+#define XtNpopupOnEntry "popupOnEntry"
+#define XtNrowHeight "rowHeight"
+#define XtNtopMargin "topMargin"
+#define XtNjumpScroll "jumpScroll"
+#define XtNleftWhitespace "leftWhitespace"
+#define XtNrightWhitespace "rightWhitespace"
+
+#define XtCColumnWidth "ColumnWidth"
+#define XtCLabelClass "LabelClass"
+#define XtCMenuOnScreen "MenuOnScreen"
+#define XtCPopupOnEntry "PopupOnEntry"
+#define XtCRowHeight "RowHeight"
+#define XtCVerticalMargins "VerticalMargins"
+#define XtCJumpScroll "JumpScroll"
+#define XtCLeftWhitespace "LeftWhitespace"
+#define XtCRightWhitespace "RightWhitespace"
+#define XtCHorizontalWhitespace "HorizontalWhitespace"
+
+/************************************************************
+ *
+ * Public Functions.
+ *
+ ************************************************************/
+
+_XFUNCPROTOBEGIN
+
+/* Function Name: XawSimpleMenuAddGlobalActions
+ * Description: adds the global actions to the simple menu widget.
+ * Arguments: app_con - the appcontext.
+ * Returns: none.
+ */
+
+extern void XawSimpleMenuAddGlobalActions(
+#if NeedFunctionPrototypes
+ XtAppContext /* app_con */
+#endif
+);
+
+/* Function Name: XawSimpleMenuGetActiveEntry
+ * Description: Gets the currently active (set) entry.
+ * Arguments: w - the smw widget.
+ * Returns: the currently set entry or NULL if none is set.
+ */
+
+extern Widget XawSimpleMenuGetActiveEntry(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+/* Function Name: XawSimpleMenuClearActiveEntry
+ * Description: Unsets the currently active (set) entry.
+ * Arguments: w - the smw widget.
+ * Returns: none.
+ */
+
+extern void XawSimpleMenuClearActiveEntry(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+_XFUNCPROTOEND
+
+#endif /* _SimpleMenu_h */
diff --git a/src/SimpleP.h b/src/SimpleP.h
new file mode 100644
index 0000000..ce7d744
--- /dev/null
+++ b/src/SimpleP.h
@@ -0,0 +1,89 @@
+/***********************************************************
+
+ $XConsortium: SimpleP.h,v 1.12 94/04/17 20:12:47 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.
+
+******************************************************************/
+
+#ifndef _SimpleP_h
+#define _SimpleP_h
+
+#include "Xaw3dP.h"
+#include <X11/Xaw3d/Simple.h>
+
+typedef struct {
+ Boolean (*change_sensitive)(/* widget */);
+} SimpleClassPart;
+
+#define XtInheritChangeSensitive ((Boolean (*)())_XtInherit)
+
+typedef struct _SimpleClassRec {
+ CoreClassPart core_class;
+ SimpleClassPart simple_class;
+} SimpleClassRec;
+
+extern SimpleClassRec simpleClassRec;
+
+typedef struct {
+ /* resources */
+ Cursor cursor;
+ Pixmap insensitive_border;
+ String cursor_name; /* cursor specified by name. */
+
+ Pixel pointer_fg, pointer_bg; /* Pointer colors. */
+#ifdef XAW_INTERNATIONALIZATION
+ Boolean international;
+#endif
+ /* private state */
+} SimplePart;
+
+typedef struct _SimpleRec {
+ CorePart core;
+ SimplePart simple;
+} SimpleRec;
+
+#endif /* _SimpleP_h */
diff --git a/src/Sme.c b/src/Sme.c
new file mode 100644
index 0000000..f3b34dd
--- /dev/null
+++ b/src/Sme.c
@@ -0,0 +1,246 @@
+/* $XConsortium: Sme.c,v 1.12 94/04/17 20:12:48 kaleb Exp $ */
+
+/*
+Copyright (c) 1989, 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.
+ */
+
+/*
+ * Sme.c - Source code for the generic menu entry
+ *
+ * Date: September 26, 1989
+ *
+ * By: Chris D. Peterson
+ * MIT X Consortium
+ * kit@expo.lcs.mit.edu
+ */
+
+#include "Xaw3dP.h"
+#include <stdio.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/SmeP.h>
+#include <X11/Xaw3d/Cardinals.h>
+
+#define offset(field) XtOffsetOf(SmeRec, sme.field)
+static XtResource resources[] = {
+ {XtNcallback, XtCCallback, XtRCallback, sizeof(XtPointer),
+ offset(callbacks), XtRCallback, (XtPointer)NULL},
+#ifdef XAW_INTERNATIONALIZATION
+ {XtNinternational, XtCInternational, XtRBoolean, sizeof(Boolean),
+ offset(international), XtRImmediate, (XtPointer) FALSE},
+#endif
+};
+#undef offset
+
+/*
+ * Semi Public function definitions.
+ */
+
+static void Unhighlight(), Highlight(), Notify(), ClassPartInitialize();
+static void Initialize();
+static XtGeometryResult QueryGeometry();
+
+#define SUPERCLASS (&rectObjClassRec)
+
+SmeClassRec smeClassRec = {
+ {
+ /* superclass */ (WidgetClass) SUPERCLASS,
+ /* class_name */ "Sme",
+ /* size */ sizeof(SmeRec),
+ /* class_initialize */ XawInitializeWidgetSet,
+ /* class_part_initialize*/ ClassPartInitialize,
+ /* Class init'ed */ FALSE,
+ /* initialize */ Initialize,
+ /* initialize_hook */ NULL,
+ /* realize */ NULL,
+ /* actions */ NULL,
+ /* num_actions */ ZERO,
+ /* resources */ resources,
+ /* resource_count */ XtNumber(resources),
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ FALSE,
+ /* compress_exposure */ FALSE,
+ /* compress_enterleave*/ FALSE,
+ /* visible_interest */ FALSE,
+ /* destroy */ NULL,
+ /* resize */ NULL,
+ /* expose */ NULL,
+ /* set_values */ NULL,
+ /* set_values_hook */ NULL,
+ /* set_values_almost */ XtInheritSetValuesAlmost,
+ /* get_values_hook */ NULL,
+ /* accept_focus */ NULL,
+ /* intrinsics version */ XtVersion,
+ /* callback offsets */ NULL,
+ /* tm_table */ NULL,
+ /* query_geometry */ QueryGeometry,
+ /* display_accelerator*/ NULL,
+ /* extension */ NULL
+ },{
+ /* Simple Menu Entry Fields */
+
+ /* highlight */ Highlight,
+ /* unhighlight */ Unhighlight,
+ /* notify */ Notify,
+ /* extension */ NULL
+ }
+};
+
+WidgetClass smeObjectClass = (WidgetClass) &smeClassRec;
+
+/************************************************************
+ *
+ * Semi-Public Functions.
+ *
+ ************************************************************/
+
+/* Function Name: ClassPartInitialize
+ * Description: handles inheritance of class functions.
+ * Arguments: class - the widget classs of this widget.
+ * Returns: none.
+ */
+
+static void
+ClassPartInitialize(class)
+WidgetClass class;
+{
+ SmeObjectClass m_ent, superC;
+
+ m_ent = (SmeObjectClass) class;
+ superC = (SmeObjectClass) m_ent->rect_class.superclass;
+
+/*
+ * We don't need to check for null super since we'll get to TextSink
+ * eventually.
+ */
+
+ if (m_ent->sme_class.highlight == XtInheritHighlight)
+ m_ent->sme_class.highlight = superC->sme_class.highlight;
+
+ if (m_ent->sme_class.unhighlight == XtInheritUnhighlight)
+ m_ent->sme_class.unhighlight = superC->sme_class.unhighlight;
+
+ if (m_ent->sme_class.notify == XtInheritNotify)
+ m_ent->sme_class.notify = superC->sme_class.notify;
+}
+
+/* Function Name: Initialize
+ * Description: Initializes the simple menu widget
+ * Arguments: request - the widget requested by the argument list.
+ * new - the new widget with both resource and non
+ * resource values.
+ * Returns: none.
+ *
+ * MENU ENTRIES CANNOT HAVE BORDERS.
+ */
+
+/* ARGSUSED */
+static void
+Initialize(request, new, args, num_args)
+Widget request, new;
+ArgList args;
+Cardinal *num_args;
+{
+ SmeObject entry = (SmeObject) new;
+
+ entry->rectangle.border_width = 0;
+}
+
+/* Function Name: Highlight
+ * Description: The default highlight proceedure for menu entries.
+ * Arguments: w - the menu entry.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+Highlight(w)
+Widget w;
+{
+/* This space intentionally left blank. */
+}
+
+/* Function Name: Unhighlight
+ * Description: The default unhighlight proceedure for menu entries.
+ * Arguments: w - the menu entry.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+Unhighlight(w)
+Widget w;
+{
+/* This space intentionally left blank. */
+}
+
+/* Function Name: Notify
+ * Description: calls the callback proceedures for this entry.
+ * Arguments: w - the menu entry.
+ * Returns: none.
+ */
+
+static void
+Notify(w)
+Widget w;
+{
+ XtCallCallbacks(w, XtNcallback, (XtPointer)NULL);
+}
+
+/* Function Name: QueryGeometry.
+ * Description: Returns the preferred geometry for this widget.
+ * Arguments: w - the menu entry object.
+ * itended, return - the intended and return geometry info.
+ * Returns: A Geometry Result.
+ *
+ * See the Intrinsics manual for details on what this function is for.
+ *
+ * I just return the height and a width of 1.
+ */
+
+static XtGeometryResult
+QueryGeometry(w, intended, return_val)
+Widget w;
+XtWidgetGeometry *intended, *return_val;
+{
+ SmeObject entry = (SmeObject) w;
+ Dimension width;
+ XtGeometryResult ret_val = XtGeometryYes;
+ XtGeometryMask mode = intended->request_mode;
+
+ width = 1; /* we can be really small. */
+
+ if ( ((mode & CWWidth) && (intended->width != width)) ||
+ !(mode & CWWidth) ) {
+ return_val->request_mode |= CWWidth;
+ return_val->width = width;
+ mode = return_val->request_mode;
+
+ if ( (mode & CWWidth) && (width == entry->rectangle.width) )
+ return(XtGeometryNo);
+ return(XtGeometryAlmost);
+ }
+ return(ret_val);
+}
diff --git a/src/Sme.h b/src/Sme.h
new file mode 100644
index 0000000..709b105
--- /dev/null
+++ b/src/Sme.h
@@ -0,0 +1,81 @@
+/*
+ * $XConsortium: Sme.h,v 1.6 94/04/17 20:12:48 kaleb Exp $
+ *
+Copyright (c) 1989, 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.
+ */
+
+/*
+ * Sme.h - Public Header file for Sme object.
+ *
+ * This is the public header file for the Athena Sme object.
+ * It is intended to be used with the simple menu widget.
+ *
+ * Date: April 3, 1989
+ *
+ * By: Chris D. Peterson
+ * MIT X Consortium
+ * kit@expo.lcs.mit.edu
+ */
+
+#ifndef _Sme_h
+#define _Sme_h
+
+#include "Xaw3dP.h"
+#include <X11/RectObj.h>
+
+/****************************************************************
+ *
+ * Sme Object
+ *
+ ****************************************************************/
+
+/* Simple Menu Entry Resources:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ callback Callback Pointer NULL
+ destroyCallback Callback Pointer NULL
+ height Height Dimension 0
+ sensitive Sensitive Boolean True
+ width Width Dimension 0
+ x Position Position 0n
+ y Position Position 0
+
+*/
+
+#ifdef XAW_INTERNATIONALIZATION
+#ifndef XtCInternational
+#define XtCInternational "International"
+#endif
+#ifndef XtNinternational
+#define XtNinternational "international"
+#endif
+#endif
+
+typedef struct _SmeClassRec* SmeObjectClass;
+typedef struct _SmeRec* SmeObject;
+
+extern WidgetClass smeObjectClass;
+
+#endif /* _Sme_h */
diff --git a/src/SmeBSB.c b/src/SmeBSB.c
new file mode 100644
index 0000000..63bdc49
--- /dev/null
+++ b/src/SmeBSB.c
@@ -0,0 +1,877 @@
+/* $XConsortium: SmeBSB.c,v 1.19 94/04/17 20:12:49 kaleb Exp $ */
+
+/*
+Copyright (c) 1989, 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.
+ */
+
+/*
+ * Portions Copyright (c) 2003 Brian V. Smith
+ * Rights, permissions, and disclaimer per the above X Consortium license.
+ */
+
+/*
+ * SmeBSB.c - Source code file for BSB Menu Entry object.
+ *
+ * Date: September 26, 1989
+ *
+ * By: Chris D. Peterson
+ * MIT X Consortium
+ * kit@expo.lcs.mit.edu
+ */
+
+#include "Xaw3dP.h"
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xos.h>
+#include <X11/Xmu/Drawing.h>
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/ThreeDP.h>
+#include <X11/Xaw3d/SimpleMenP.h>
+#include <X11/Xaw3d/SmeBSBP.h>
+#include <X11/Xaw3d/Cardinals.h>
+#include <stdio.h>
+
+/* needed for abs() */
+#ifndef X_NOT_STDC_ENV
+#include <stdlib.h>
+#else
+extern int abs();
+#endif
+
+#define offset(field) XtOffsetOf(SmeBSBRec, sme_bsb.field)
+
+static XtResource resources[] = {
+ {XtNlabel, XtCLabel, XtRString, sizeof(String),
+ offset(label), XtRString, NULL},
+ {XtNvertSpace, XtCVertSpace, XtRInt, sizeof(int),
+ offset(vert_space), XtRImmediate, (XtPointer) 25},
+ {XtNleftBitmap, XtCLeftBitmap, XtRBitmap, sizeof(Pixmap),
+ offset(left_bitmap), XtRImmediate, (XtPointer)None},
+ {XtNjustify, XtCJustify, XtRJustify, sizeof(XtJustify),
+ offset(justify), XtRImmediate, (XtPointer) XtJustifyLeft},
+ {XtNrightBitmap, XtCRightBitmap, XtRBitmap, sizeof(Pixmap),
+ offset(right_bitmap), XtRImmediate, (XtPointer)None},
+ {XtNleftMargin, XtCHorizontalMargins, XtRDimension, sizeof(Dimension),
+ offset(left_margin), XtRImmediate, (XtPointer) 4},
+ {XtNrightMargin, XtCHorizontalMargins, XtRDimension, sizeof(Dimension),
+ offset(right_margin), XtRImmediate, (XtPointer) 4},
+ {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
+ offset(foreground), XtRString, XtDefaultForeground},
+ {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
+ offset(font), XtRString, XtDefaultFont},
+#ifdef XAW_INTERNATIONALIZATION
+ {XtNfontSet, XtCFontSet, XtRFontSet, sizeof(XFontSet ),
+ offset(fontset),XtRString, XtDefaultFontSet},
+#endif
+ {XtNmenuName, XtCMenuName, XtRString, sizeof(String),
+ offset(menu_name), XtRImmediate, (XtPointer) NULL},
+ {XtNunderline, XtCIndex, XtRInt, sizeof(int),
+ offset(underline), XtRImmediate, (XtPointer) -1},
+};
+#undef offset
+
+/*
+ * Semi Public function definitions.
+ */
+
+static void Redisplay(), Destroy(), Initialize();
+static void Highlight(), Unhighlight();
+static void ClassInitialize();
+static Boolean SetValues();
+static XtGeometryResult QueryGeometry();
+
+/*
+ * Private Function Definitions.
+ */
+
+static void GetDefaultSize(), DrawBitmaps(), GetBitmapInfo();
+static void CreateGCs(), DestroyGCs(), FlipColors();
+
+#define superclass (&smeThreeDClassRec)
+SmeBSBClassRec smeBSBClassRec = {
+ {
+ /* superclass */ (WidgetClass) superclass,
+ /* class_name */ "SmeBSB",
+ /* size */ sizeof(SmeBSBRec),
+ /* class_initializer */ ClassInitialize,
+ /* class_part_initialize*/ NULL,
+ /* Class init'ed */ FALSE,
+ /* initialize */ Initialize,
+ /* initialize_hook */ NULL,
+ /* realize */ NULL,
+ /* actions */ NULL,
+ /* num_actions */ ZERO,
+ /* resources */ resources,
+ /* resource_count */ XtNumber(resources),
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ FALSE,
+ /* compress_exposure */ FALSE,
+ /* compress_enterleave*/ FALSE,
+ /* visible_interest */ FALSE,
+ /* destroy */ Destroy,
+ /* resize */ NULL,
+ /* expose */ Redisplay,
+ /* set_values */ SetValues,
+ /* set_values_hook */ NULL,
+ /* set_values_almost */ XtInheritSetValuesAlmost,
+ /* get_values_hook */ NULL,
+ /* accept_focus */ NULL,
+ /* intrinsics version */ XtVersion,
+ /* callback offsets */ NULL,
+ /* tm_table */ NULL,
+ /* query_geometry */ QueryGeometry,
+ /* display_accelerator*/ NULL,
+ /* extension */ NULL
+ },{
+ /* SimpleMenuClass Fields */
+ /* highlight */ Highlight,
+ /* unhighlight */ Unhighlight,
+ /* notify */ XtInheritNotify,
+ /* extension */ NULL
+ }, {
+ /* ThreeDClass Fields */
+ /* shadowdraw */ XtInheritXawSme3dShadowDraw
+ }, {
+ /* BSBClass Fields */
+ /* extension */ NULL
+ }
+};
+
+WidgetClass smeBSBObjectClass = (WidgetClass) &smeBSBClassRec;
+
+/************************************************************
+ *
+ * Semi-Public Functions.
+ *
+ ************************************************************/
+
+/* Function Name: ClassInitialize
+ * Description: Initializes the SmeBSBObject.
+ * Arguments: none.
+ * Returns: none.
+ */
+
+static void
+ClassInitialize()
+{
+ XawInitializeWidgetSet();
+ XtAddConverter( XtRString, XtRJustify, XmuCvtStringToJustify,
+ (XtConvertArgList)NULL, (Cardinal)0 );
+}
+
+/* Function Name: Initialize
+ * Description: Initializes the simple menu widget
+ * Arguments: request - the widget requested by the argument list.
+ * new - the new widget with both resource and non
+ * resource values.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+Initialize(request, new, args, num_args)
+Widget request, new;
+ArgList args;
+Cardinal *num_args;
+{
+ SmeBSBObject entry = (SmeBSBObject) new;
+
+ if (entry->sme_bsb.label == NULL)
+ entry->sme_bsb.label = XtName(new);
+ else
+ entry->sme_bsb.label = XtNewString( entry->sme_bsb.label );
+
+ CreateGCs(new);
+
+ GetBitmapInfo(new, TRUE); /* Left Bitmap Info */
+ GetBitmapInfo(new, FALSE); /* Right Bitmap Info */
+
+ entry->sme_bsb.left_stippled = entry->sme_bsb.right_stippled = None;
+
+ GetDefaultSize(new, &(entry->rectangle.width), &(entry->rectangle.height));
+}
+
+/* Function Name: Destroy
+ * Description: Called at destroy time, cleans up.
+ * Arguments: w - the simple menu widget.
+ * Returns: none.
+ */
+
+static void
+Destroy(w)
+Widget w;
+{
+ SmeBSBObject entry = (SmeBSBObject) w;
+
+ DestroyGCs(w);
+#ifdef XAW_MULTIPLANE_PIXMAPS
+ if (entry->sme_bsb.left_stippled != None)
+ XFreePixmap(XtDisplayOfObject(w), entry->sme_bsb.left_stippled);
+ if (entry->sme_bsb.right_stippled != None)
+ XFreePixmap(XtDisplayOfObject(w), entry->sme_bsb.right_stippled);
+#endif
+ if (entry->sme_bsb.label != XtName(w))
+ XtFree(entry->sme_bsb.label);
+}
+
+/* Function Name: Redisplay
+ * Description: Redisplays the contents of the widget.
+ * Arguments: w - the simple menu widget.
+ * event - the X event that caused this redisplay.
+ * region - the region the needs to be repainted.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+Redisplay(w, event, region)
+Widget w;
+XEvent * event;
+Region region;
+{
+ GC gc;
+ SmeBSBObject entry = (SmeBSBObject) w;
+ Dimension s = entry->sme_threeD.shadow_width;
+ int font_ascent = 0, font_descent = 0, y_loc;
+#ifdef XAW_INTERNATIONALIZATION
+ int fontset_ascent = 0, fontset_descent = 0;
+ XFontSetExtents *ext = XExtentsOfFontSet(entry->sme_bsb.fontset);
+#endif
+
+ entry->sme_bsb.set_values_area_cleared = FALSE;
+#ifdef XAW_INTERNATIONALIZATION
+ if ( entry->sme.international == True ) {
+ fontset_ascent = abs(ext->max_ink_extent.y);
+ fontset_descent = ext->max_ink_extent.height - fontset_ascent;
+ }
+ else
+#endif
+ { /*else, compute size from font like R5*/
+ font_ascent = entry->sme_bsb.font->max_bounds.ascent;
+ font_descent = entry->sme_bsb.font->max_bounds.descent;
+ }
+ y_loc = entry->rectangle.y;
+
+ if (XtIsSensitive(w) && XtIsSensitive( XtParent(w) ) ) {
+ if ( w == XawSimpleMenuGetActiveEntry(XtParent(w)) ) {
+ XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w),
+ entry->sme_bsb.norm_gc, s, y_loc + s,
+ (unsigned int) entry->rectangle.width - 2 * s,
+ (unsigned int) entry->rectangle.height - 2 * s);
+ gc = entry->sme_bsb.rev_gc;
+ }
+ else
+ gc = entry->sme_bsb.norm_gc;
+ }
+ else
+ gc = entry->sme_bsb.norm_gray_gc;
+
+ if (entry->sme_bsb.label != NULL) {
+ int x_loc = entry->sme_bsb.left_margin;
+ int len = strlen(entry->sme_bsb.label);
+ int width, t_width;
+ char * label = entry->sme_bsb.label;
+
+ switch(entry->sme_bsb.justify) {
+ case XtJustifyCenter:
+#ifdef XAW_INTERNATIONALIZATION
+ if ( entry->sme.international == True )
+ t_width = XmbTextEscapement(entry->sme_bsb.fontset,label,len);
+ else
+#endif
+ t_width = XTextWidth(entry->sme_bsb.font, label, len);
+
+ width = entry->rectangle.width -
+ (entry->sme_bsb.left_margin +
+ entry->sme_bsb.right_margin);
+ x_loc += (width - t_width)/2;
+ break;
+ case XtJustifyRight:
+#ifdef XAW_INTERNATIONALIZATION
+ if ( entry->sme.international == True )
+ t_width = XmbTextEscapement(entry->sme_bsb.fontset,label,len);
+ else
+#endif
+ t_width = XTextWidth(entry->sme_bsb.font, label, len);
+
+ x_loc = entry->rectangle.width -
+ (entry->sme_bsb.right_margin + t_width);
+ break;
+ case XtJustifyLeft:
+ default:
+ break;
+ }
+
+ /* this will center the text in the gadget top-to-bottom */
+
+#ifdef XAW_INTERNATIONALIZATION
+ if ( entry->sme.international==True ) {
+ y_loc += ((int)entry->rectangle.height -
+ (fontset_ascent + fontset_descent)) / 2 + fontset_ascent;
+
+ XmbDrawString(XtDisplayOfObject(w), XtWindowOfObject(w),
+ entry->sme_bsb.fontset, gc, x_loc + s, y_loc, label, len);
+ }
+ else
+#endif
+ {
+ y_loc += ((int)entry->rectangle.height -
+ (font_ascent + font_descent)) / 2 + font_ascent;
+
+ XDrawString(XtDisplayOfObject(w), XtWindowOfObject(w), gc,
+ x_loc + s, y_loc, label, len);
+ }
+
+ if (entry->sme_bsb.underline >= 0 && entry->sme_bsb.underline < len) {
+ int ul = entry->sme_bsb.underline;
+ int ul_x1_loc = x_loc + s;
+ int ul_wid;
+
+ if (ul != 0)
+ ul_x1_loc += XTextWidth(entry->sme_bsb.font, label, ul);
+ ul_wid = XTextWidth(entry->sme_bsb.font, &label[ul], 1) - 2;
+ XDrawLine(XtDisplayOfObject(w), XtWindowOfObject(w), gc,
+ ul_x1_loc, y_loc + 1, ul_x1_loc + ul_wid, y_loc + 1);
+ }
+ }
+
+ DrawBitmaps(w, gc);
+}
+
+
+/* Function Name: SetValues
+ * Description: Relayout the menu when one of the resources is changed.
+ * Arguments: current - current state of the widget.
+ * request - what was requested.
+ * new - what the widget will become.
+ * Returns: none
+ */
+
+/* ARGSUSED */
+static Boolean
+SetValues(current, request, new, args, num_args)
+Widget current, request, new;
+ArgList args;
+Cardinal *num_args;
+{
+ Widget parent = XtParent(new);
+ SmeBSBObject entry = (SmeBSBObject) new;
+ SmeBSBObject old_entry = (SmeBSBObject) current;
+ Boolean ret_val = FALSE;
+
+ if (old_entry->sme_bsb.label != entry->sme_bsb.label) {
+ if (old_entry->sme_bsb.label != XtName( new ) )
+ XtFree( (char *) old_entry->sme_bsb.label );
+
+ if (entry->sme_bsb.label != XtName(new) )
+ entry->sme_bsb.label = XtNewString( entry->sme_bsb.label );
+
+ ret_val = TRUE;
+ }
+
+ if (entry->sme_bsb.underline != old_entry->sme_bsb.underline)
+ ret_val = TRUE;
+
+ if (entry->rectangle.sensitive != old_entry->rectangle.sensitive)
+ ret_val = TRUE;
+
+#ifdef XAW_INTERNATIONALIZATION
+ if ( ( (old_entry->sme_bsb.font != entry->sme_bsb.font) &&
+ (old_entry->sme.international == False ) ) ||
+ (old_entry->sme_bsb.foreground != entry->sme_bsb.foreground) ) {
+#else
+ if ( (old_entry->sme_bsb.font != entry->sme_bsb.font) ||
+ (old_entry->sme_bsb.foreground != entry->sme_bsb.foreground) ) {
+#endif
+ DestroyGCs(current);
+ CreateGCs(new);
+
+ ret_val = TRUE;
+ }
+
+ if (entry->sme_bsb.left_bitmap != old_entry->sme_bsb.left_bitmap)
+ {
+ GetBitmapInfo(new, TRUE);
+
+#ifdef XAW_MULTIPLANE_PIXMAPS
+ entry->sme_bsb.left_stippled = None;
+ if (old_entry->sme_bsb.left_stippled != None)
+ XFreePixmap(XtDisplayOfObject(current),
+ old_entry->sme_bsb.left_stippled);
+#endif
+
+ ret_val = TRUE;
+ }
+
+ if (entry->sme_bsb.left_margin != old_entry->sme_bsb.left_margin)
+ ret_val = TRUE;
+
+ if (entry->sme_bsb.right_bitmap != old_entry->sme_bsb.right_bitmap)
+ {
+ GetBitmapInfo(new, FALSE);
+
+#ifdef XAW_MULTIPLANE_PIXMAPS
+ entry->sme_bsb.right_stippled = None;
+ if (old_entry->sme_bsb.right_stippled != None)
+ XFreePixmap(XtDisplayOfObject(current),
+ old_entry->sme_bsb.right_stippled);
+#endif
+
+ ret_val = TRUE;
+ }
+
+ if (entry->sme_bsb.right_margin != old_entry->sme_bsb.right_margin)
+ ret_val = TRUE;
+
+#ifdef XAW_INTERNATIONALIZATION
+ if ( ( old_entry->sme_bsb.fontset != entry->sme_bsb.fontset) &&
+ (old_entry->sme.international == True ) )
+ /* don't change the GCs - the fontset is not in them */
+ ret_val = TRUE;
+#endif
+
+ if (ret_val) {
+ GetDefaultSize(new,
+ &(entry->rectangle.width), &(entry->rectangle.height));
+ entry->sme_bsb.set_values_area_cleared = TRUE;
+
+ (parent->core.widget_class->core_class.resize)(new);
+ }
+
+ return(ret_val);
+}
+
+/* Function Name: QueryGeometry.
+ * Description: Returns the preferred geometry for this widget.
+ * Arguments: w - the menu entry object.
+ * itended, return_val - the intended and return geometry info.
+ * Returns: A Geometry Result.
+ *
+ * See the Intrinsics manual for details on what this function is for.
+ *
+ * I just return the height and width of the label plus the margins.
+ */
+
+static XtGeometryResult
+QueryGeometry(w, intended, return_val)
+Widget w;
+XtWidgetGeometry *intended, *return_val;
+{
+ SmeBSBObject entry = (SmeBSBObject) w;
+ Dimension width, height, h;
+ XtGeometryResult ret_val = XtGeometryYes;
+ XtGeometryMask mode = intended->request_mode;
+
+ GetDefaultSize(w, &width, &height );
+
+ if ( ((mode & CWWidth) && (intended->width != width)) ||
+ !(mode & CWWidth) ) {
+ return_val->request_mode |= CWWidth;
+ return_val->width = width;
+ ret_val = XtGeometryAlmost;
+ }
+
+ if ( ((mode & CWHeight) && (intended->height != height)) ||
+ !(mode & CWHeight) ) {
+ return_val->request_mode |= CWHeight;
+ return_val->height = height;
+ ret_val = XtGeometryAlmost;
+ }
+
+ if (ret_val == XtGeometryAlmost) {
+ mode = return_val->request_mode;
+
+ if ( ((mode & CWWidth) && (width == entry->rectangle.width)) &&
+ ((mode & CWHeight) && (height == entry->rectangle.height)) )
+ return(XtGeometryNo);
+ }
+
+ entry->rectangle.width = width;
+ entry->rectangle.height = height;
+
+ return(ret_val);
+}
+
+/*
+ * FlipColors() used to be called directly, but it's blind
+ * state toggling caused re-unhighlighting problems.
+ */
+
+static void
+Highlight(w)
+Widget w;
+{
+ SmeBSBObject entry = (SmeBSBObject) w;
+
+ entry->sme_threeD.shadowed = True;
+ FlipColors(w);
+}
+
+static void
+Unhighlight(w)
+Widget w;
+{
+ SmeBSBObject entry = (SmeBSBObject) w;
+
+ entry->sme_threeD.shadowed = False;
+ FlipColors(w);
+}
+
+/************************************************************
+ *
+ * Private Functions.
+ *
+ ************************************************************/
+
+/* Function Name: GetDefaultSize
+ * Description: Calculates the Default (preferred) size of
+ * this menu entry.
+ * Arguments: w - the menu entry widget.
+ * width, height - default sizes (RETURNED).
+ * Returns: none.
+ */
+
+static void
+GetDefaultSize(w, width, height)
+Widget w;
+Dimension * width, * height;
+{
+ SmeBSBObject entry = (SmeBSBObject) w;
+ Dimension h;
+
+#ifdef XAW_INTERNATIONALIZATION
+ if ( entry->sme.international == True ) {
+ XFontSetExtents *ext = XExtentsOfFontSet(entry->sme_bsb.fontset);
+
+ if (entry->sme_bsb.label == NULL)
+ *width = 0;
+ else
+ *width = XmbTextEscapement(entry->sme_bsb.fontset, entry->sme_bsb.label,
+ strlen(entry->sme_bsb.label));
+
+ *height = ext->max_ink_extent.height;
+ }
+ else
+#endif
+ {
+ if (entry->sme_bsb.label == NULL)
+ *width = 0;
+ else
+ *width = XTextWidth(entry->sme_bsb.font, entry->sme_bsb.label,
+ strlen(entry->sme_bsb.label));
+
+ *height = (entry->sme_bsb.font->max_bounds.ascent +
+ entry->sme_bsb.font->max_bounds.descent);
+ }
+
+ *width += entry->sme_bsb.left_margin + entry->sme_bsb.right_margin;
+ *width += (2 * entry->sme_threeD.shadow_width);
+
+ h = (entry->sme_bsb.left_bitmap_height > entry->sme_bsb.right_bitmap_height)
+ ? entry->sme_bsb.left_bitmap_height : entry->sme_bsb.right_bitmap_height;
+ if (h > *height) *height = h;
+ *height = ((int)*height * (100 + entry->sme_bsb.vert_space)) / 100;
+ *height += (2 * entry->sme_threeD.shadow_width);
+}
+
+/* Function Name: DrawBitmaps
+ * Description: Draws left and right bitmaps.
+ * Arguments: w - the simple menu widget.
+ * gc - graphics context to use for drawing.
+ * Returns: none
+ */
+
+static void
+DrawBitmaps(w, gc)
+Widget w;
+GC gc;
+{
+#ifdef XAW_MULTIPLANE_PIXMAPS
+ Widget parent = XtParent(w);
+#endif
+ int x_loc, y_loc;
+ SmeBSBObject entry = (SmeBSBObject) w;
+ Pixmap pm;
+
+ if ( (entry->sme_bsb.left_bitmap == None) &&
+ (entry->sme_bsb.right_bitmap == None) ) return;
+
+/*
+ * Draw Left Bitmap.
+ */
+
+ if (entry->sme_bsb.left_bitmap != None) {
+ x_loc = entry->sme_threeD.shadow_width +
+ (int)(entry->sme_bsb.left_margin -
+ entry->sme_bsb.left_bitmap_width) / 2;
+
+ y_loc = entry->rectangle.y + (int)(entry->rectangle.height -
+ entry->sme_bsb.left_bitmap_height) / 2;
+
+ pm = entry->sme_bsb.left_bitmap;
+#ifdef XAW_MULTIPLANE_PIXMAPS
+ if (!XtIsSensitive(w)) {
+ if (entry->sme_bsb.left_stippled == None)
+ entry->sme_bsb.left_stippled = stipplePixmap(w,
+ entry->sme_bsb.left_bitmap,
+ parent->core.colormap,
+ parent->core.background_pixel,
+ entry->sme_bsb.left_depth);
+ if (entry->sme_bsb.left_stippled != None)
+ pm = entry->sme_bsb.left_stippled;
+ }
+#endif
+
+ if (entry->sme_bsb.left_depth == 1)
+ XCopyPlane(XtDisplayOfObject(w), pm,
+ XtWindowOfObject(w), gc, 0, 0,
+ entry->sme_bsb.left_bitmap_width,
+ entry->sme_bsb.left_bitmap_height, x_loc, y_loc, 1);
+ else
+ XCopyArea (XtDisplayOfObject(w), pm,
+ XtWindowOfObject(w), gc, 0, 0,
+ entry->sme_bsb.left_bitmap_width,
+ entry->sme_bsb.left_bitmap_height, x_loc, y_loc);
+ }
+
+/*
+ * Draw Right Bitmap.
+ */
+
+ if (entry->sme_bsb.right_bitmap != None) {
+ x_loc = entry->rectangle.width - entry->sme_threeD.shadow_width -
+ (int)(entry->sme_bsb.right_margin +
+ entry->sme_bsb.right_bitmap_width) / 2;
+
+ y_loc = entry->rectangle.y + (int)(entry->rectangle.height -
+ entry->sme_bsb.right_bitmap_height) / 2;
+
+ pm = entry->sme_bsb.right_bitmap;
+#ifdef XAW_MULTIPLANE_PIXMAPS
+ if (!XtIsSensitive(w)) {
+ if (entry->sme_bsb.right_stippled == None)
+ entry->sme_bsb.right_stippled = stipplePixmap(w,
+ entry->sme_bsb.right_bitmap,
+ parent->core.colormap,
+ parent->core.background_pixel,
+ entry->sme_bsb.right_depth);
+ if (entry->sme_bsb.right_stippled != None)
+ pm = entry->sme_bsb.right_stippled;
+ }
+#endif
+
+ if (entry->sme_bsb.right_depth == 1)
+ XCopyPlane(XtDisplayOfObject(w), pm,
+ XtWindowOfObject(w), gc, 0, 0,
+ entry->sme_bsb.right_bitmap_width,
+ entry->sme_bsb.right_bitmap_height, x_loc, y_loc, 1);
+ else
+ XCopyArea (XtDisplayOfObject(w), pm,
+ XtWindowOfObject(w), gc, 0, 0,
+ entry->sme_bsb.right_bitmap_width,
+ entry->sme_bsb.right_bitmap_height, x_loc, y_loc);
+ }
+}
+
+/* Function Name: GetBitmapInfo
+ * Description: Gets the bitmap information from either of the bitmaps.
+ * Arguments: w - the bsb menu entry widget.
+ * is_left - TRUE if we are testing left bitmap,
+ * FALSE if we are testing the right bitmap.
+ * Returns: none
+ */
+
+static void
+GetBitmapInfo(w, is_left)
+Widget w;
+Boolean is_left;
+{
+ SmeBSBObject entry = (SmeBSBObject) w;
+ Window root;
+ int x, y;
+ unsigned int width, height, bw;
+ char buf[BUFSIZ];
+
+ if (is_left) {
+ width = height = 0;
+
+ if (entry->sme_bsb.left_bitmap != None) {
+ if (!XGetGeometry(XtDisplayOfObject(w),
+ entry->sme_bsb.left_bitmap, &root, &x, &y,
+ &width, &height, &bw, &entry->sme_bsb.left_depth)) {
+ (void) sprintf(buf, "Xaw SmeBSB Object: %s %s \"%s\".",
+ "Could not get Left Bitmap",
+ "geometry information for menu entry",
+ XtName(w));
+ XtAppError(XtWidgetToApplicationContext(w), buf);
+ }
+#ifdef NEVER
+ if (entry->sme_bsb.left_depth != 1) {
+ (void) sprintf(buf, "Xaw SmeBSB Object: %s \"%s\" %s.",
+ "Left Bitmap of entry", XtName(w),
+ "is not one bit deep");
+ XtAppError(XtWidgetToApplicationContext(w), buf);
+ }
+#endif
+ }
+
+ entry->sme_bsb.left_bitmap_width = (Dimension) width;
+ entry->sme_bsb.left_bitmap_height = (Dimension) height;
+ } else {
+ width = height = 0;
+
+ if (entry->sme_bsb.right_bitmap != None) {
+ if (!XGetGeometry(XtDisplayOfObject(w),
+ entry->sme_bsb.right_bitmap, &root, &x, &y,
+ &width, &height, &bw, &entry->sme_bsb.right_depth)) {
+ (void) sprintf(buf, "Xaw SmeBSB Object: %s %s \"%s\".",
+ "Could not get Right Bitmap",
+ "geometry information for menu entry",
+ XtName(w));
+ XtAppError(XtWidgetToApplicationContext(w), buf);
+ }
+#ifdef NEVER
+ if (entry->sme_bsb.right_depth != 1) {
+ (void) sprintf(buf, "Xaw SmeBSB Object: %s \"%s\" %s.",
+ "Right Bitmap of entry", XtName(w),
+ "is not one bit deep");
+ XtAppError(XtWidgetToApplicationContext(w), buf);
+ }
+#endif
+ }
+
+ entry->sme_bsb.right_bitmap_width = (Dimension) width;
+ entry->sme_bsb.right_bitmap_height = (Dimension) height;
+ }
+}
+
+/* Function Name: CreateGCs
+ * Description: Creates all gc's for the simple menu widget.
+ * Arguments: w - the simple menu widget.
+ * Returns: none.
+ */
+
+static void
+CreateGCs(w)
+Widget w;
+{
+ SmeBSBObject entry = (SmeBSBObject) w;
+ XGCValues values;
+ XtGCMask mask;
+#ifdef XAW_INTERNATIONALIZATION
+ XtGCMask mask_i18n;
+#endif
+
+ values.foreground = XtParent(w)->core.background_pixel;
+ values.background = entry->sme_bsb.foreground;
+ values.font = entry->sme_bsb.font->fid;
+ values.graphics_exposures = FALSE;
+ mask = GCForeground | GCBackground | GCGraphicsExposures | GCFont;
+#ifdef XAW_INTERNATIONALIZATION
+ mask_i18n = GCForeground | GCBackground | GCGraphicsExposures;
+ if ( entry->sme.international == True )
+ entry->sme_bsb.rev_gc = XtAllocateGC(w, 0, mask_i18n, &values, GCFont, 0 );
+ else
+#endif
+ entry->sme_bsb.rev_gc = XtGetGC(w, mask, &values);
+
+ values.foreground = entry->sme_bsb.foreground;
+ values.background = XtParent(w)->core.background_pixel;
+#ifdef XAW_INTERNATIONALIZATION
+ if ( entry->sme.international == True )
+ entry->sme_bsb.norm_gc = XtAllocateGC(w, 0, mask_i18n, &values, GCFont, 0 );
+ else
+#endif
+ entry->sme_bsb.norm_gc = XtGetGC(w, mask, &values);
+
+ values.fill_style = FillTiled;
+ values.tile = XmuCreateStippledPixmap(XtScreenOfObject(w),
+ entry->sme_bsb.foreground,
+ XtParent(w)->core.background_pixel,
+ XtParent(w)->core.depth);
+ values.graphics_exposures = FALSE;
+ mask |= GCTile | GCFillStyle;
+#ifdef XAW_INTERNATIONALIZATION
+ if ( entry->sme.international == True )
+ entry->sme_bsb.norm_gray_gc = XtAllocateGC(w, 0, mask_i18n, &values, GCFont, 0 );
+ else
+#endif
+ entry->sme_bsb.norm_gray_gc = XtGetGC(w, mask, &values);
+
+ values.foreground ^= values.background;
+ values.background = 0;
+ values.function = GXxor;
+ mask = GCForeground | GCBackground | GCGraphicsExposures | GCFunction;
+ entry->sme_bsb.invert_gc = XtGetGC(w, mask, &values);
+}
+
+/* Function Name: DestroyGCs
+ * Description: Removes all gc's for the simple menu widget.
+ * Arguments: w - the simple menu widget.
+ * Returns: none.
+ */
+
+static void
+DestroyGCs(w)
+Widget w;
+{
+ SmeBSBObject entry = (SmeBSBObject) w;
+
+ XtReleaseGC(w, entry->sme_bsb.norm_gc);
+ XtReleaseGC(w, entry->sme_bsb.norm_gray_gc);
+ XtReleaseGC(w, entry->sme_bsb.rev_gc);
+ XtReleaseGC(w, entry->sme_bsb.invert_gc);
+}
+
+/* Function Name: FlipColors
+ * Description: Invert the colors of the current entry.
+ * Arguments: w - the bsb menu entry widget.
+ * Returns: none.
+ */
+
+static void
+FlipColors(w)
+Widget w;
+{
+ SmeBSBObject entry = (SmeBSBObject) w;
+ SmeBSBObjectClass oclass = (SmeBSBObjectClass) XtClass (w);
+ SimpleMenuWidget smw = (SimpleMenuWidget) XtParent (w);
+ ThreeDWidget tdw = (ThreeDWidget) smw->simple_menu.threeD;
+ Dimension s = tdw->threeD.shadow_width;
+
+ if (entry->sme_bsb.set_values_area_cleared) {
+ entry->sme_threeD.shadowed = False;
+ return;
+ }
+
+ if (entry->sme_threeD.shadow_width > 0) {
+ (*oclass->sme_threeD_class.shadowdraw) (w);
+ } else
+ XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w),
+ entry->sme_bsb.invert_gc,
+ s, (int) entry->rectangle.y,
+ (unsigned int) entry->rectangle.width - 2 * s,
+ (unsigned int) entry->rectangle.height);
+}
+
diff --git a/src/SmeBSB.h b/src/SmeBSB.h
new file mode 100644
index 0000000..47ad6e0
--- /dev/null
+++ b/src/SmeBSB.h
@@ -0,0 +1,111 @@
+/*
+ * $XConsortium: SmeBSB.h,v 1.7 94/04/17 20:12:49 kaleb Exp $
+ *
+Copyright (c) 1989, 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.
+ */
+
+/*
+ * SmeBSB.h - Public Header file for SmeBSB object.
+ *
+ * This is the public header file for the Athena BSB Sme object.
+ * It is intended to be used with the simple menu widget. This object
+ * provides bitmap - string - bitmap style entries.
+ *
+ * Date: April 3, 1989
+ *
+ * By: Chris D. Peterson
+ * MIT X Consortium
+ * kit@expo.lcs.mit.edu
+ */
+
+#ifndef _SmeBSB_h
+#define _SmeBSB_h
+
+#include <X11/Xmu/Converters.h>
+
+#include "Xaw3dP.h"
+#include <X11/Xaw3d/Sme.h>
+
+/****************************************************************
+ *
+ * SmeBSB object
+ *
+ ****************************************************************/
+
+/* BSB Menu Entry Resources:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ callback Callback Callback NULL
+ destroyCallback Callback Pointer NULL
+ font Font XFontStruct * XtDefaultFont
+ foreground Foreground Pixel XtDefaultForeground
+ height Height Dimension 0
+ label Label String Name of entry
+ leftBitmap LeftBitmap Pixmap None
+ leftMargin HorizontalMargins Dimension 4
+ menuName MenuName String NULL
+ rightBitmap RightBitmap Pixmap None
+ rightMargin HorizontalMargins Dimension 4
+ sensitive Sensitive Boolean True
+ underline Underline int -1
+ vertSpace VertSpace int 25
+ width Width Dimension 0
+ x Position Position 0n
+ y Position Position 0
+
+*/
+
+typedef struct _SmeBSBClassRec *SmeBSBObjectClass;
+typedef struct _SmeBSBRec *SmeBSBObject;
+
+extern WidgetClass smeBSBObjectClass;
+
+#define XtNleftBitmap "leftBitmap"
+#define XtNleftMargin "leftMargin"
+#define XtNleftWhitespace "leftWhitespace"
+#define XtNrightBitmap "rightBitmap"
+#define XtNrightMargin "rightMargin"
+#define XtNrightWhitespace "rightWhitespace"
+#define XtNvertSpace "vertSpace"
+#define XtNmenuName "menuName"
+#define XtNunderline "underline"
+
+#ifdef XAW_INTERNATIONALIZATION
+#ifndef XtNfontSet
+#define XtNfontSet "fontSet"
+#endif
+#ifndef XtCFontSet
+#define XtCFontSet "FontSet"
+#endif
+#endif
+
+#define XtCLeftBitmap "LeftBitmap"
+#define XtCRightBitmap "RightBitmap"
+#define XtCHorizontalMargins "HorizontalMargins"
+#define XtCVertSpace "VertSpace"
+#define XtCMenuName "MenuName"
+#define XtCUnderline "Underline"
+
+#endif /* _SmeBSB_h */
diff --git a/src/SmeBSBP.h b/src/SmeBSBP.h
new file mode 100644
index 0000000..6ef1c4b
--- /dev/null
+++ b/src/SmeBSBP.h
@@ -0,0 +1,120 @@
+/*
+ * $XConsortium: SmeBSBP.h,v 1.8 94/04/17 21:44:11 rws Exp $
+ *
+Copyright (c) 1989, 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.
+ *
+ * Author: Chris D. Peterson, MIT X Consortium
+ */
+
+/*
+ * SmeP.h - Private definitions for Sme object
+ *
+ */
+
+#ifndef _XawSmeBSBP_h
+#define _XawSmeBSBP_h
+
+/***********************************************************************
+ *
+ * Sme Object Private Data
+ *
+ ***********************************************************************/
+
+#include "Xaw3dP.h"
+#include <X11/Xaw3d/SmeThreeDP.h>
+#include <X11/Xaw3d/SmeBSB.h>
+
+/************************************************************
+ *
+ * New fields for the Sme Object class record.
+ *
+ ************************************************************/
+
+typedef struct _SmeBSBClassPart {
+ XtPointer extension;
+} SmeBSBClassPart;
+
+/* Full class record declaration */
+typedef struct _SmeBSBClassRec {
+ RectObjClassPart rect_class;
+ SmeClassPart sme_class;
+ SmeThreeDClassPart sme_threeD_class;
+ SmeBSBClassPart sme_bsb_class;
+} SmeBSBClassRec;
+
+extern SmeBSBClassRec smeBSBClassRec;
+
+/* New fields for the Sme Object record */
+typedef struct {
+ /* resources */
+ String label; /* The entry label. */
+ int vert_space; /* extra vert space to leave, as a percentage
+ of the font height of the label. */
+ Pixmap left_bitmap, right_bitmap; /* pixmaps to show. */
+ Dimension left_margin, right_margin; /* left and right margins. */
+ Pixel foreground; /* foreground color. */
+ XFontStruct * font; /* The font to show label in. */
+#ifdef XAW_INTERNATIONALIZATION
+ XFontSet fontset; /* or fontset */
+#endif
+ XtJustify justify; /* Justification for the label. */
+ int underline; /* index of letter to underline in label. */
+
+ /* private resources. */
+ Boolean set_values_area_cleared; /* Remember if we need to unhighlight. */
+ GC norm_gc; /* noral color gc. */
+ GC rev_gc; /* reverse color gc. */
+ GC norm_gray_gc; /* Normal color (grayed out) gc. */
+ GC invert_gc; /* gc for flipping colors. */
+ Pixmap left_stippled, right_stippled; /* insensitive pixmaps */
+ Dimension left_bitmap_width; /* size and depth of each pixmap. */
+ Dimension left_bitmap_height;
+ Dimension right_bitmap_width;
+ Dimension right_bitmap_height;
+ unsigned int left_depth;
+ unsigned int right_depth;
+ String menu_name; /* name of nested sub-menu or NULL */
+} SmeBSBPart;
+
+/****************************************************************
+ *
+ * Full instance record declaration
+ *
+ ****************************************************************/
+
+typedef struct _SmeBSBRec {
+ ObjectPart object;
+ RectObjPart rectangle;
+ SmePart sme;
+ SmeThreeDPart sme_threeD;
+ SmeBSBPart sme_bsb;
+} SmeBSBRec;
+
+/************************************************************
+ *
+ * Private declarations.
+ *
+ ************************************************************/
+
+#endif /* _XawSmeBSBP_h */
diff --git a/src/SmeLine.c b/src/SmeLine.c
new file mode 100644
index 0000000..27aa65b
--- /dev/null
+++ b/src/SmeLine.c
@@ -0,0 +1,294 @@
+/* $XConsortium: SmeLine.c,v 1.15 94/04/17 20:12:51 eswu Exp $ */
+
+/*
+Copyright (c) 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: Chris D. Peterson, MIT X Consortium
+ */
+
+/*
+ * Sme.c - Source code for the generic menu entry
+ *
+ * Date: September 26, 1989
+ *
+ * By: Chris D. Peterson
+ * MIT X Consortium
+ * kit@expo.lcs.mit.edu
+ */
+
+#include <stdio.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/ThreeDP.h>
+#include <X11/Xaw3d/SimpleMenP.h>
+#include <X11/Xaw3d/SmeLineP.h>
+#include <X11/Xaw3d/Cardinals.h>
+
+#define offset(field) XtOffsetOf(SmeLineRec, sme_line.field)
+static XtResource resources[] = {
+ {XtNlineWidth, XtCLineWidth, XtRDimension, sizeof(Dimension),
+ offset(line_width), XtRImmediate, (XtPointer) 1},
+ {XtNstipple, XtCStipple, XtRBitmap, sizeof(Pixmap),
+ offset(stipple), XtRImmediate, (XtPointer) XtUnspecifiedPixmap},
+ {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
+ offset(foreground), XtRString, XtDefaultForeground},
+};
+#undef offset
+
+/*
+ * Function definitions.
+ */
+
+static void Redisplay(), Initialize();
+static void DestroyGC(), CreateGC();
+static Boolean SetValues();
+static XtGeometryResult QueryGeometry();
+
+
+#define SUPERCLASS (&smeClassRec)
+
+SmeLineClassRec smeLineClassRec = {
+ {
+ /* superclass */ (WidgetClass) SUPERCLASS,
+ /* class_name */ "SmeLine",
+ /* size */ sizeof(SmeLineRec),
+ /* class_initialize */ XawInitializeWidgetSet,
+ /* class_part_initialize*/ NULL,
+ /* Class init'ed */ FALSE,
+ /* initialize */ Initialize,
+ /* initialize_hook */ NULL,
+ /* realize */ NULL,
+ /* actions */ NULL,
+ /* num_actions */ ZERO,
+ /* resources */ resources,
+ /* resource_count */ XtNumber(resources),
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ FALSE,
+ /* compress_exposure */ FALSE,
+ /* compress_enterleave*/ FALSE,
+ /* visible_interest */ FALSE,
+ /* destroy */ DestroyGC,
+ /* resize */ NULL,
+ /* expose */ Redisplay,
+ /* set_values */ SetValues,
+ /* set_values_hook */ NULL,
+ /* set_values_almost */ XtInheritSetValuesAlmost,
+ /* get_values_hook */ NULL,
+ /* accept_focus */ NULL,
+ /* intrinsics version */ XtVersion,
+ /* callback offsets */ NULL,
+ /* tm_table */ NULL,
+ /* query_geometry */ QueryGeometry,
+ /* display_accelerator*/ NULL,
+ /* extension */ NULL
+ },{
+ /* Menu Entry Fields */
+
+ /* highlight */ XtInheritHighlight,
+ /* unhighlight */ XtInheritUnhighlight,
+ /* notify */ XtInheritNotify,
+ /* extension */ NULL
+ },{
+ /* Line Menu Entry Fields */
+ /* extension */ NULL
+ }
+};
+
+WidgetClass smeLineObjectClass = (WidgetClass) &smeLineClassRec;
+
+/************************************************************
+ *
+ * Semi-Public Functions.
+ *
+ ************************************************************/
+
+/* Function Name: Initialize
+ * Description: Initializes the simple menu widget
+ * Arguments: request - the widget requested by the argument list.
+ * new - the new widget with both resource and non
+ * resource values.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+Initialize(request, new, args, num_args)
+Widget request, new;
+ArgList args;
+Cardinal *num_args;
+{
+ SmeLineObject entry = (SmeLineObject) new;
+
+ if (entry->rectangle.height == 0)
+ entry->rectangle.height = entry->sme_line.line_width;
+
+ CreateGC(new);
+}
+
+/* Function Name: CreateGC
+ * Description: Creates the GC for the line entry widget.
+ * Arguments: w - the Line entry widget.
+ * Returns: none
+ *
+ * We can only share the GC if there is no stipple, because
+ * we need to change the stipple origin when drawing.
+ */
+
+static void
+CreateGC(w)
+Widget w;
+{
+ SmeLineObject entry = (SmeLineObject) w;
+ XGCValues values;
+ XtGCMask mask = GCForeground | GCGraphicsExposures | GCLineWidth ;
+
+ values.foreground = entry->sme_line.foreground;
+ values.graphics_exposures = FALSE;
+ values.line_width = entry->sme_line.line_width;
+
+ if (entry->sme_line.stipple != XtUnspecifiedPixmap) {
+ values.stipple = entry->sme_line.stipple;
+ values.fill_style = FillStippled;
+ mask |= GCStipple | GCFillStyle;
+
+ entry->sme_line.gc = XCreateGC(XtDisplayOfObject(w),
+ RootWindowOfScreen(XtScreenOfObject(w)),
+ mask, &values);
+ }
+ else
+ entry->sme_line.gc = XtGetGC(w, mask, &values);
+}
+
+/* Function Name: DestroyGC
+ * Description: Destroys the GC when we are done with it.
+ * Arguments: w - the Line entry widget.
+ * Returns: none
+ */
+
+static void
+DestroyGC(w)
+Widget w;
+{
+ SmeLineObject entry = (SmeLineObject) w;
+
+ if (entry->sme_line.stipple != XtUnspecifiedPixmap)
+ XFreeGC(XtDisplayOfObject(w), entry->sme_line.gc);
+ else
+ XtReleaseGC(w, entry->sme_line.gc);
+}
+
+/* Function Name: Redisplay
+ * Description: Paints the Line
+ * Arguments: w - the menu entry.
+ * event, region - NOT USED.
+ * Returns: none
+ */
+
+/*ARGSUSED*/
+static void
+Redisplay(w, event, region)
+Widget w;
+XEvent * event;
+Region region;
+{
+ SmeLineObject entry = (SmeLineObject) w;
+ SimpleMenuWidget smw = (SimpleMenuWidget) XtParent (w);
+ ThreeDWidget tdw = (ThreeDWidget) smw->simple_menu.threeD;
+ Dimension s = tdw->threeD.shadow_width;
+ int y = entry->rectangle.y +
+ (int)(entry->rectangle.height - entry->sme_line.line_width) / 2;
+
+ if (entry->sme_line.stipple != XtUnspecifiedPixmap)
+ XSetTSOrigin(XtDisplayOfObject(w), entry->sme_line.gc, 0, y);
+
+ XFillRectangle(XtDisplayOfObject(w), XtWindowOfObject(w),
+ entry->sme_line.gc,
+ s, y, (unsigned int) entry->rectangle.width - 2 * s,
+ (unsigned int) entry->sme_line.line_width );
+}
+
+/* Function Name: SetValues
+ * Description: Relayout the menu when one of the resources is changed.
+ * Arguments: current - current state of the widget.
+ * request - what was requested.
+ * new - what the widget will become.
+ * Returns: none
+ */
+
+/* ARGSUSED */
+static Boolean
+SetValues(current, request, new, args, num_args)
+Widget current, request, new;
+ArgList args;
+Cardinal *num_args;
+{
+ SmeLineObject entry = (SmeLineObject) new;
+ SmeLineObject old_entry = (SmeLineObject) current;
+
+ if ( (entry->sme_line.line_width != old_entry->sme_line.line_width) &&
+ (entry->sme_line.stipple != old_entry->sme_line.stipple) ) {
+ DestroyGC(current);
+ CreateGC(new);
+ return(TRUE);
+ }
+ return(FALSE);
+}
+
+/* Function Name: QueryGeometry.
+ * Description: Returns the preferred geometry for this widget.
+ * Arguments: w - the menu entry object.
+ * itended, return - the intended and return geometry info.
+ * Returns: A Geometry Result.
+ *
+ * See the Intrinsics manual for details on what this function is for.
+ *
+ * I just return the height and a width of 1.
+ */
+
+static XtGeometryResult
+QueryGeometry(w, intended, return_val)
+Widget w;
+XtWidgetGeometry *intended, *return_val;
+{
+ SmeObject entry = (SmeObject) w;
+ Dimension width;
+ XtGeometryResult ret_val = XtGeometryYes;
+ XtGeometryMask mode = intended->request_mode;
+
+ width = 1; /* we can be really small. */
+
+ if ( ((mode & CWWidth) && (intended->width != width)) ||
+ !(mode & CWWidth) ) {
+ return_val->request_mode |= CWWidth;
+ return_val->width = width;
+ mode = return_val->request_mode;
+
+ if ( (mode & CWWidth) && (width == entry->rectangle.width) )
+ return(XtGeometryNo);
+ return(XtGeometryAlmost);
+ }
+ return(ret_val);
+}
diff --git a/src/SmeLine.h b/src/SmeLine.h
new file mode 100644
index 0000000..42b969e
--- /dev/null
+++ b/src/SmeLine.h
@@ -0,0 +1,79 @@
+/*
+ * $XConsortium: SmeLine.h,v 1.4 94/04/17 20:12:53 kit Exp $
+ *
+Copyright (c) 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.
+ *
+ */
+
+/*
+ * SmeLine.h - Public Header file for SmeLine object.
+ *
+ * This is the public header file for the Athena SmeLine object.
+ * It is intended to be used with the simple menu widget.
+ *
+ * Date: April 3, 1989
+ *
+ * By: Chris D. Peterson
+ * MIT X Consortium
+ * kit@expo.lcs.mit.edu
+ */
+
+#ifndef _SmeLine_h
+#define _SmeLine_h
+
+#include <X11/Xaw3d/Sme.h>
+#include <X11/Xmu/Converters.h>
+
+/****************************************************************
+ *
+ * SmeLine Object
+ *
+ ****************************************************************/
+
+/* Menu Entry Resources:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ callback Callback Pointer NULL
+ destroyCallback Callback Pointer NULL
+ height Height Dimension 0
+ sensitive Sensitive Boolean True
+ width Width Dimension 0
+ x Position Position 0n
+ y Position Position 0
+
+*/
+
+#define XtCLineWidth "LineWidth"
+#define XtCStipple "Stipple"
+
+#define XtNlineWidth "lineWidth"
+#define XtNstipple "stipple"
+
+typedef struct _SmeLineClassRec* SmeLineObjectClass;
+typedef struct _SmeLineRec* SmeLineObject;
+
+extern WidgetClass smeLineObjectClass;
+
+#endif /* _SmeLine_h */
diff --git a/src/SmeLineP.h b/src/SmeLineP.h
new file mode 100644
index 0000000..c6b612d
--- /dev/null
+++ b/src/SmeLineP.h
@@ -0,0 +1,97 @@
+/*
+ * $XConsortium: SmeLineP.h,v 1.4 94/04/17 20:12:54 kit Exp $
+ *
+Copyright (c) 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: Chris D. Peterson, MIT X Consortium
+ */
+
+/*
+ * SmeLineP.h - Private definitions for SmeLine widget
+ *
+ */
+
+#ifndef _XawSmeLineP_h
+#define _XawSmeLineP_h
+
+/***********************************************************************
+ *
+ * SmeLine Widget Private Data
+ *
+ ***********************************************************************/
+
+#include <X11/Xaw3d/SmeP.h>
+#include <X11/Xaw3d/SmeLine.h>
+
+/************************************************************
+ *
+ * New fields for the SmeLine widget class record.
+ *
+ ************************************************************/
+
+typedef struct _SmeLineClassPart {
+ XtPointer extension;
+} SmeLineClassPart;
+
+/* Full class record declaration */
+typedef struct _SmeLineClassRec {
+ RectObjClassPart rect_class;
+ SmeClassPart sme_class;
+ SmeLineClassPart sme_line_class;
+} SmeLineClassRec;
+
+extern SmeLineClassRec smeLineClassRec;
+
+/* New fields for the SmeLine widget record */
+typedef struct {
+ /* resources */
+ Pixel foreground; /* Foreground color. */
+ Pixmap stipple; /* Line Stipple. */
+ Dimension line_width; /* Width of the line. */
+
+ /* private data. */
+
+ GC gc; /* Graphics context for drawing line. */
+} SmeLinePart;
+
+/****************************************************************
+ *
+ * Full instance record declaration
+ *
+ ****************************************************************/
+
+typedef struct _SmeLineRec {
+ ObjectPart object;
+ RectObjPart rectangle;
+ SmePart sme;
+ SmeLinePart sme_line;
+} SmeLineRec;
+
+/************************************************************
+ *
+ * Private declarations.
+ *
+ ************************************************************/
+
+#endif /* _XawSmeLineP_h */
diff --git a/src/SmeP.h b/src/SmeP.h
new file mode 100644
index 0000000..9501771
--- /dev/null
+++ b/src/SmeP.h
@@ -0,0 +1,107 @@
+/*
+ * $XConsortium: SmeP.h,v 1.6 94/04/17 20:12:54 kaleb Exp $
+ *
+Copyright (c) 1989, 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.
+ */
+
+/*
+ * SmeP.h - Private Header file for Sme object.
+ *
+ * This is the private header file for the Athena Sme object.
+ * This object is intended to be used with the simple menu widget.
+ *
+ * Date: April 3, 1989
+ *
+ * By: Chris D. Peterson
+ * MIT X Consortium
+ * kit@expo.lcs.mit.edu
+ */
+
+#ifndef _XawSmeP_h
+#define _XawSmeP_h
+
+/***********************************************************************
+ *
+ * Sme Widget Private Data
+ *
+ ***********************************************************************/
+
+#include "Xaw3dP.h"
+#include <X11/Xaw3d/Sme.h>
+
+/************************************************************
+ *
+ * New fields for the Sme widget class record.
+ *
+ ************************************************************/
+
+typedef struct _SmeClassPart {
+ void (*highlight)();
+ void (*unhighlight)();
+ void (*notify)();
+ XtPointer extension;
+} SmeClassPart;
+
+/* Full class record declaration */
+typedef struct _SmeClassRec {
+ RectObjClassPart rect_class;
+ SmeClassPart sme_class;
+} SmeClassRec;
+
+extern SmeClassRec smeClassRec;
+
+/* New fields for the Sme widget record */
+typedef struct {
+ /* resources */
+ XtCallbackList callbacks; /* The callback list */
+#ifdef XAW_INTERNATIONALIZATION
+ Boolean international;
+#endif
+} SmePart;
+
+/****************************************************************
+ *
+ * Full instance record declaration
+ *
+ ****************************************************************/
+
+typedef struct _SmeRec {
+ ObjectPart object;
+ RectObjPart rectangle;
+ SmePart sme;
+} SmeRec;
+
+/************************************************************
+ *
+ * Private declarations.
+ *
+ ************************************************************/
+
+typedef void (*_XawEntryVoidFunc)();
+
+#define XtInheritHighlight ((_XawEntryVoidFunc) _XtInherit)
+#define XtInheritUnhighlight XtInheritHighlight
+#define XtInheritNotify XtInheritHighlight
+
+#endif /* _XawSmeP_h */
diff --git a/src/SmeThreeD.c b/src/SmeThreeD.c
new file mode 100644
index 0000000..a01023c
--- /dev/null
+++ b/src/SmeThreeD.c
@@ -0,0 +1,596 @@
+/*
+* $KK: SmeThreeD.c,v 0.3 92/11/04 xx:xx:xx keithley Exp $
+*/
+
+/***********************************************************
+Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+Copyright 1992, 1993 by Kaleb Keithley
+
+ 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 names of Digital, MIT, or Kaleb
+Keithley 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.
+
+******************************************************************/
+
+#include "Xaw3dP.h"
+#include <X11/Xlib.h>
+#include <X11/StringDefs.h>
+#include <X11/IntrinsicP.h>
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/ThreeDP.h>
+#include <X11/Xaw3d/SimpleMenP.h>
+#include <X11/Xaw3d/SmeThreeDP.h>
+#include <X11/Xosdefs.h>
+
+/* Initialization of defaults */
+
+#define XtNtopShadowPixmap "topShadowPixmap"
+#define XtCTopShadowPixmap "TopShadowPixmap"
+#define XtNbottomShadowPixmap "bottomShadowPixmap"
+#define XtCBottomShadowPixmap "BottomShadowPixmap"
+#define XtNshadowed "shadowed"
+#define XtCShadowed "Shadowed"
+
+#define offset(field) XtOffsetOf(SmeThreeDRec, field)
+
+static XtResource resources[] = {
+ {XtNshadowWidth, XtCShadowWidth, XtRDimension, sizeof(Dimension),
+ offset(sme_threeD.shadow_width), XtRImmediate, (XtPointer) 2},
+ {XtNtopShadowPixel, XtCTopShadowPixel, XtRPixel, sizeof(Pixel),
+ offset(sme_threeD.top_shadow_pixel), XtRString, XtDefaultForeground},
+ {XtNbottomShadowPixel, XtCBottomShadowPixel, XtRPixel, sizeof(Pixel),
+ offset(sme_threeD.bot_shadow_pixel), XtRString, XtDefaultForeground},
+ {XtNtopShadowPixmap, XtCTopShadowPixmap, XtRPixmap, sizeof(Pixmap),
+ offset(sme_threeD.top_shadow_pxmap), XtRImmediate, (XtPointer) NULL},
+ {XtNbottomShadowPixmap, XtCBottomShadowPixmap, XtRPixmap, sizeof(Pixmap),
+ offset(sme_threeD.bot_shadow_pxmap), XtRImmediate, (XtPointer) NULL},
+ {XtNtopShadowContrast, XtCTopShadowContrast, XtRInt, sizeof(int),
+ offset(sme_threeD.top_shadow_contrast), XtRImmediate, (XtPointer) 20},
+ {XtNbottomShadowContrast, XtCBottomShadowContrast, XtRInt, sizeof(int),
+ offset(sme_threeD.bot_shadow_contrast), XtRImmediate, (XtPointer) 40},
+ {XtNuserData, XtCUserData, XtRPointer, sizeof(XtPointer),
+ offset(sme_threeD.user_data), XtRPointer, (XtPointer) NULL},
+ {XtNbeNiceToColormap, XtCBeNiceToColormap, XtRBoolean, sizeof(Boolean),
+ offset(sme_threeD.be_nice_to_cmap), XtRImmediate, (XtPointer) True},
+ {XtNshadowed, XtCShadowed, XtRBoolean, sizeof(Boolean),
+ offset(sme_threeD.shadowed), XtRImmediate, (XtPointer) False},
+ {XtNborderWidth, XtCBorderWidth, XtRDimension, sizeof(Dimension),
+ XtOffsetOf(RectObjRec,rectangle.border_width), XtRImmediate,
+ (XtPointer)0}
+};
+
+#undef offset
+
+static void Initialize(), Destroy();
+static void ClassPartInitialize(), _XawSme3dDrawShadows();
+static Boolean SetValues();
+
+SmeThreeDClassRec smeThreeDClassRec = {
+ { /* core fields */
+ /* superclass */ (WidgetClass) &smeClassRec,
+ /* class_name */ "SmeThreeD",
+ /* widget_size */ sizeof(SmeThreeDRec),
+ /* class_initialize */ NULL,
+ /* class_part_initialize */ ClassPartInitialize,
+ /* class_inited */ FALSE,
+ /* initialize */ Initialize,
+ /* initialize_hook */ NULL,
+ /* realize */ NULL,
+ /* actions */ NULL,
+ /* num_actions */ 0,
+ /* resources */ resources,
+ /* resource_count */ XtNumber(resources),
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ TRUE,
+ /* compress_exposure */ TRUE,
+ /* compress_enterleave */ TRUE,
+ /* visible_interest */ FALSE,
+ /* destroy */ Destroy,
+ /* resize */ XtInheritResize,
+ /* expose */ NULL,
+ /* set_values */ SetValues,
+ /* set_values_hook */ NULL,
+ /* set_values_almost */ XtInheritSetValuesAlmost,
+ /* get_values_hook */ NULL,
+ /* accept_focus */ NULL,
+ /* version */ XtVersion,
+ /* callback_private */ NULL,
+ /* tm_table */ NULL,
+ /* query_geometry */ XtInheritQueryGeometry,
+ /* display_accelerator */ NULL,
+ /* extension */ NULL
+ },
+ { /* Menu Entry fields */
+ /* highlight */ XtInheritHighlight,
+ /* unhighlight */ XtInheritUnhighlight,
+ /* notify */ XtInheritNotify,
+ /* extension */ NULL
+ },
+ { /* threeD fields */
+ /* shadow draw */ _XawSme3dDrawShadows
+ }
+};
+
+WidgetClass smeThreeDObjectClass = (WidgetClass) &smeThreeDClassRec;
+
+/****************************************************************
+ *
+ * Private Procedures
+ *
+ ****************************************************************/
+
+
+#define shadowpm_width 8
+#define shadowpm_height 8
+static char shadowpm_bits[] = {
+ 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55};
+
+static char mtshadowpm_bits[] = {
+ 0x92, 0x24, 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
+
+static char mbshadowpm_bits[] = {
+ 0x6d, 0xdb, 0xb6, 0x6d, 0xdb, 0xb6, 0x6d, 0xdb};
+
+/* ARGSUSED */
+static void AllocTopShadowGC (w)
+ Widget w;
+{
+ SmeThreeDObject tdo = (SmeThreeDObject) w;
+ Screen *scn = XtScreenOfObject (w);
+ XtGCMask valuemask;
+ XGCValues myXGCV;
+
+ if (tdo->sme_threeD.be_nice_to_cmap || DefaultDepthOfScreen (scn) == 1) {
+ valuemask = GCTile | GCFillStyle;
+ myXGCV.tile = tdo->sme_threeD.top_shadow_pxmap;
+ myXGCV.fill_style = FillTiled;
+ } else {
+ valuemask = GCForeground;
+ myXGCV.foreground = tdo->sme_threeD.top_shadow_pixel;
+ }
+ tdo->sme_threeD.top_shadow_GC = XtGetGC(w, valuemask, &myXGCV);
+}
+
+/* ARGSUSED */
+static void AllocBotShadowGC (w)
+ Widget w;
+{
+ SmeThreeDObject tdo = (SmeThreeDObject) w;
+ Screen *scn = XtScreenOfObject (w);
+ XtGCMask valuemask;
+ XGCValues myXGCV;
+
+ if (tdo->sme_threeD.be_nice_to_cmap || DefaultDepthOfScreen (scn) == 1) {
+ valuemask = GCTile | GCFillStyle;
+ myXGCV.tile = tdo->sme_threeD.bot_shadow_pxmap;
+ myXGCV.fill_style = FillTiled;
+ } else {
+ valuemask = GCForeground;
+ myXGCV.foreground = tdo->sme_threeD.bot_shadow_pixel;
+ }
+ tdo->sme_threeD.bot_shadow_GC = XtGetGC(w, valuemask, &myXGCV);
+}
+
+/* ARGSUSED */
+static void AllocEraseGC (w)
+ Widget w;
+{
+ Widget parent = XtParent (w);
+ SmeThreeDObject tdo = (SmeThreeDObject) w;
+ XtGCMask valuemask;
+ XGCValues myXGCV;
+
+ valuemask = GCForeground;
+ myXGCV.foreground = parent->core.background_pixel;
+ tdo->sme_threeD.erase_GC = XtGetGC(w, valuemask, &myXGCV);
+}
+
+/* ARGSUSED */
+static void AllocTopShadowPixmap (new)
+ Widget new;
+{
+ SmeThreeDObject tdo = (SmeThreeDObject) new;
+ Widget parent = XtParent (new);
+ Display *dpy = XtDisplayOfObject (new);
+ Screen *scn = XtScreenOfObject (new);
+ unsigned long top_fg_pixel = 0, top_bg_pixel = 0;
+ char *pm_data;
+ Boolean create_pixmap = FALSE;
+
+ /*
+ * I know, we're going to create two pixmaps for each and every
+ * shadow'd widget. Yeuck. I'm semi-relying on server side
+ * pixmap cacheing.
+ */
+
+ if (DefaultDepthOfScreen (scn) == 1) {
+ top_fg_pixel = BlackPixelOfScreen (scn);
+ top_bg_pixel = WhitePixelOfScreen (scn);
+ pm_data = mtshadowpm_bits;
+ create_pixmap = TRUE;
+ } else if (tdo->sme_threeD.be_nice_to_cmap) {
+ if (parent->core.background_pixel == WhitePixelOfScreen (scn)) {
+ top_fg_pixel = WhitePixelOfScreen (scn);
+ top_bg_pixel = grayPixel( BlackPixelOfScreen (scn), dpy, scn);
+ } else if (parent->core.background_pixel == BlackPixelOfScreen (scn)) {
+ top_fg_pixel = grayPixel( BlackPixelOfScreen (scn), dpy, scn);
+ top_bg_pixel = WhitePixelOfScreen (scn);
+ } else {
+ top_fg_pixel = parent->core.background_pixel;
+ top_bg_pixel = WhitePixelOfScreen (scn);
+ }
+#ifndef XAW_GRAY_BLKWHT_STIPPLES
+ if (parent->core.background_pixel == WhitePixelOfScreen (scn) ||
+ parent->core.background_pixel == BlackPixelOfScreen (scn)) {
+ pm_data = mtshadowpm_bits;
+ } else
+#endif
+ pm_data = shadowpm_bits;
+
+ create_pixmap = TRUE;
+ }
+
+ if (create_pixmap)
+ tdo->sme_threeD.top_shadow_pxmap = XCreatePixmapFromBitmapData (dpy,
+ RootWindowOfScreen (scn),
+ pm_data,
+ shadowpm_width,
+ shadowpm_height,
+ top_fg_pixel,
+ top_bg_pixel,
+ DefaultDepthOfScreen (scn));
+}
+
+/* ARGSUSED */
+static void AllocBotShadowPixmap (new)
+ Widget new;
+{
+ SmeThreeDObject tdo = (SmeThreeDObject) new;
+ Widget parent = XtParent (new);
+ Display *dpy = XtDisplayOfObject (new);
+ Screen *scn = XtScreenOfObject (new);
+ unsigned long bot_fg_pixel = 0, bot_bg_pixel = 0;
+ char *pm_data;
+ Boolean create_pixmap = FALSE;
+
+ if (DefaultDepthOfScreen (scn) == 1) {
+ bot_fg_pixel = BlackPixelOfScreen (scn);
+ bot_bg_pixel = WhitePixelOfScreen (scn);
+ pm_data = mbshadowpm_bits;
+ create_pixmap = TRUE;
+ } else if (tdo->sme_threeD.be_nice_to_cmap) {
+ if (parent->core.background_pixel == WhitePixelOfScreen (scn)) {
+ bot_fg_pixel = grayPixel( WhitePixelOfScreen (scn), dpy, scn);
+ bot_bg_pixel = BlackPixelOfScreen (scn);
+ } else if (parent->core.background_pixel == BlackPixelOfScreen (scn)) {
+ bot_fg_pixel = BlackPixelOfScreen (scn);
+ bot_bg_pixel = grayPixel( BlackPixelOfScreen (scn), dpy, scn);
+ } else {
+ bot_fg_pixel = parent->core.background_pixel;
+ bot_bg_pixel = BlackPixelOfScreen (scn);
+ }
+#ifndef XAW_GRAY_BLKWHT_STIPPLES
+ if (parent->core.background_pixel == WhitePixelOfScreen (scn) ||
+ parent->core.background_pixel == BlackPixelOfScreen (scn)) {
+ pm_data = mbshadowpm_bits;
+ } else
+#endif
+ pm_data = shadowpm_bits;
+
+ create_pixmap = TRUE;
+ }
+
+ if (create_pixmap)
+ tdo->sme_threeD.bot_shadow_pxmap = XCreatePixmapFromBitmapData (dpy,
+ RootWindowOfScreen (scn),
+ pm_data,
+ shadowpm_width,
+ shadowpm_height,
+ bot_fg_pixel,
+ bot_bg_pixel,
+ DefaultDepthOfScreen (scn));
+}
+
+/* ARGSUSED */
+void XawSme3dComputeTopShadowRGB (new, xcol_out)
+ Widget new;
+ XColor *xcol_out;
+{
+ if (XtIsSubclass (new, smeThreeDObjectClass)) {
+ SmeThreeDObject tdo = (SmeThreeDObject) new;
+ Widget w = XtParent (new);
+ XColor get_c;
+ double contrast;
+ Display *dpy = XtDisplayOfObject (new);
+ Screen *scn = XtScreenOfObject (new);
+ Colormap cmap = w->core.colormap;
+
+ get_c.pixel = w->core.background_pixel;
+ if (get_c.pixel == WhitePixelOfScreen (scn) ||
+ get_c.pixel == BlackPixelOfScreen (scn)) {
+ contrast = (100 - tdo->sme_threeD.top_shadow_contrast) / 100.0;
+ xcol_out->red = contrast * 65535.0;
+ xcol_out->green = contrast * 65535.0;
+ xcol_out->blue = contrast * 65535.0;
+ } else {
+ contrast = 1.0 + tdo->sme_threeD.top_shadow_contrast / 100.0;
+ XQueryColor (dpy, cmap, &get_c);
+#define MIN(x,y) (unsigned short) (x < y) ? x : y
+ xcol_out->red = MIN (65535, (int) (contrast * (double) get_c.red));
+ xcol_out->green = MIN (65535, (int) (contrast * (double) get_c.green));
+ xcol_out->blue = MIN (65535, (int) (contrast * (double) get_c.blue));
+#undef MIN
+ }
+ } else
+ xcol_out->red = xcol_out->green = xcol_out->blue = 0;
+}
+
+/* ARGSUSED */
+static void AllocTopShadowPixel (new)
+ Widget new;
+{
+ XColor set_c;
+ SmeThreeDObject tdo = (SmeThreeDObject) new;
+ Widget w = XtParent (new);
+ Display *dpy = XtDisplayOfObject (new);
+ Colormap cmap = w->core.colormap;
+
+ XawSme3dComputeTopShadowRGB (new, &set_c);
+ (void) XAllocColor (dpy, cmap, &set_c);
+ tdo->sme_threeD.top_shadow_pixel = set_c.pixel;
+}
+
+
+/* ARGSUSED */
+void XawSme3dComputeBottomShadowRGB (new, xcol_out)
+ Widget new;
+ XColor *xcol_out;
+{
+ if (XtIsSubclass (new, smeThreeDObjectClass)) {
+ SmeThreeDObject tdo = (SmeThreeDObject) new;
+ Widget w = XtParent (new);
+ XColor get_c;
+ double contrast;
+ Display *dpy = XtDisplayOfObject (new);
+ Screen *scn = XtScreenOfObject (new);
+ Colormap cmap = w->core.colormap;
+
+ get_c.pixel = w->core.background_pixel;
+ if (get_c.pixel == WhitePixelOfScreen (scn) ||
+ get_c.pixel == BlackPixelOfScreen (scn)) {
+ contrast = tdo->sme_threeD.bot_shadow_contrast / 100.0;
+ xcol_out->red = contrast * 65535.0;
+ xcol_out->green = contrast * 65535.0;
+ xcol_out->blue = contrast * 65535.0;
+ } else {
+ XQueryColor (dpy, cmap, &get_c);
+ contrast = (100 - tdo->sme_threeD.bot_shadow_contrast) / 100.0;
+ xcol_out->red = contrast * get_c.red;
+ xcol_out->green = contrast * get_c.green;
+ xcol_out->blue = contrast * get_c.blue;
+ }
+ } else
+ xcol_out->red = xcol_out->green = xcol_out->blue = 0;
+}
+
+/* ARGSUSED */
+static void AllocBotShadowPixel (new)
+ Widget new;
+{
+ XColor set_c;
+ SmeThreeDObject tdo = (SmeThreeDObject) new;
+ Widget w = XtParent (new);
+ Display *dpy = XtDisplayOfObject (new);
+ Colormap cmap = w->core.colormap;
+
+ XawSme3dComputeBottomShadowRGB (new, &set_c);
+ (void) XAllocColor (dpy, cmap, &set_c);
+ tdo->sme_threeD.bot_shadow_pixel = set_c.pixel;
+}
+
+
+/* ARGSUSED */
+static void ClassPartInitialize (wc)
+ WidgetClass wc;
+{
+ SmeThreeDClassRec *tdwc = (SmeThreeDClassRec *) wc;
+ SmeThreeDClassRec *super =
+ (SmeThreeDClassRec *) tdwc->rect_class.superclass;
+
+ if (tdwc->sme_threeD_class.shadowdraw == XtInheritXawSme3dShadowDraw)
+ tdwc->sme_threeD_class.shadowdraw = super->sme_threeD_class.shadowdraw;
+}
+
+/* ARGSUSED */
+static void Initialize (request, new, args, num_args)
+ Widget request, new;
+ ArgList args;
+ Cardinal *num_args;
+{
+ SmeThreeDObject w = (SmeThreeDObject) new;
+ Screen *scr = XtScreenOfObject (new);
+
+ if (w->sme_threeD.be_nice_to_cmap || DefaultDepthOfScreen (scr) == 1) {
+ AllocTopShadowPixmap (new);
+ AllocBotShadowPixmap (new);
+ } else {
+ if (w->sme_threeD.top_shadow_pixel == w->sme_threeD.bot_shadow_pixel) {
+ AllocTopShadowPixel (new);
+ AllocBotShadowPixel (new);
+ }
+ w->sme_threeD.top_shadow_pxmap = w->sme_threeD.bot_shadow_pxmap = 0;
+ }
+ AllocTopShadowGC (new);
+ AllocBotShadowGC (new);
+ AllocEraseGC (new);
+}
+
+static void Destroy (gw)
+ Widget gw;
+{
+ SmeThreeDObject w = (SmeThreeDObject) gw;
+ XtReleaseGC (gw, w->sme_threeD.top_shadow_GC);
+ XtReleaseGC (gw, w->sme_threeD.bot_shadow_GC);
+ XtReleaseGC (gw, w->sme_threeD.erase_GC);
+ if (w->sme_threeD.top_shadow_pxmap)
+ XFreePixmap (XtDisplayOfObject (gw), w->sme_threeD.top_shadow_pxmap);
+ if (w->sme_threeD.bot_shadow_pxmap)
+ XFreePixmap (XtDisplayOfObject (gw), w->sme_threeD.bot_shadow_pxmap);
+}
+
+/* ARGSUSED */
+static Boolean SetValues (gcurrent, grequest, gnew, args, num_args)
+ Widget gcurrent, grequest, gnew;
+ ArgList args;
+ Cardinal *num_args;
+{
+ SmeThreeDObject current = (SmeThreeDObject) gcurrent;
+ SmeThreeDObject new = (SmeThreeDObject) gnew;
+ Boolean redisplay = FALSE;
+ Boolean alloc_top_pixel = FALSE;
+ Boolean alloc_bot_pixel = FALSE;
+ Boolean alloc_top_pixmap = FALSE;
+ Boolean alloc_bot_pixmap = FALSE;
+
+#if 0
+ (*threeDWidgetClass->core_class.superclass->core_class.set_values)
+ (gcurrent, grequest, gnew, NULL, 0);
+#endif
+ if (new->sme_threeD.shadow_width != current->sme_threeD.shadow_width)
+ redisplay = TRUE;
+ if (new->sme_threeD.be_nice_to_cmap != current->sme_threeD.be_nice_to_cmap) {
+ if (new->sme_threeD.be_nice_to_cmap) {
+ alloc_top_pixmap = TRUE;
+ alloc_bot_pixmap = TRUE;
+ } else {
+ alloc_top_pixel = TRUE;
+ alloc_bot_pixel = TRUE;
+ }
+ redisplay = TRUE;
+ }
+ if (!new->sme_threeD.be_nice_to_cmap &&
+ new->sme_threeD.top_shadow_contrast != current->sme_threeD.top_shadow_contrast)
+ alloc_top_pixel = TRUE;
+ if (!new->sme_threeD.be_nice_to_cmap &&
+ new->sme_threeD.bot_shadow_contrast != current->sme_threeD.bot_shadow_contrast)
+ alloc_bot_pixel = TRUE;
+ if (alloc_top_pixel)
+ AllocTopShadowPixel (gnew);
+ if (alloc_bot_pixel)
+ AllocBotShadowPixel (gnew);
+ if (alloc_top_pixmap)
+ AllocTopShadowPixmap (gnew);
+ if (alloc_bot_pixmap)
+ AllocBotShadowPixmap (gnew);
+ if (!new->sme_threeD.be_nice_to_cmap &&
+ new->sme_threeD.top_shadow_pixel != current->sme_threeD.top_shadow_pixel)
+ alloc_top_pixel = TRUE;
+ if (!new->sme_threeD.be_nice_to_cmap &&
+ new->sme_threeD.bot_shadow_pixel != current->sme_threeD.bot_shadow_pixel)
+ alloc_bot_pixel = TRUE;
+ if (new->sme_threeD.be_nice_to_cmap) {
+ if (alloc_top_pixmap) {
+ XtReleaseGC (gcurrent, current->sme_threeD.top_shadow_GC);
+ AllocTopShadowGC (gnew);
+ redisplay = True;
+ }
+ if (alloc_bot_pixmap) {
+ XtReleaseGC (gcurrent, current->sme_threeD.bot_shadow_GC);
+ AllocBotShadowGC (gnew);
+ redisplay = True;
+ }
+ } else {
+ if (alloc_top_pixel) {
+ if (new->sme_threeD.top_shadow_pxmap) {
+ XFreePixmap (XtDisplayOfObject (gnew), new->sme_threeD.top_shadow_pxmap);
+ new->sme_threeD.top_shadow_pxmap = (Pixmap) NULL;
+ }
+ XtReleaseGC (gcurrent, current->sme_threeD.top_shadow_GC);
+ AllocTopShadowGC (gnew);
+ redisplay = True;
+ }
+ if (alloc_bot_pixel) {
+ if (new->sme_threeD.bot_shadow_pxmap) {
+ XFreePixmap (XtDisplayOfObject (gnew), new->sme_threeD.bot_shadow_pxmap);
+ new->sme_threeD.bot_shadow_pxmap = (Pixmap) NULL;
+ }
+ XtReleaseGC (gcurrent, current->sme_threeD.bot_shadow_GC);
+ AllocBotShadowGC (gnew);
+ redisplay = True;
+ }
+ }
+ return (redisplay);
+}
+
+/* ARGSUSED */
+static void
+_XawSme3dDrawShadows(gw)
+ Widget gw;
+{
+ SmeThreeDObject tdo = (SmeThreeDObject) gw;
+ SimpleMenuWidget smw = (SimpleMenuWidget) XtParent(gw);
+ ThreeDWidget tdw = (ThreeDWidget) smw->simple_menu.threeD;
+ Dimension s = tdo->sme_threeD.shadow_width;
+ Dimension ps = tdw->threeD.shadow_width;
+ XPoint pt[6];
+
+ /*
+ * draw the shadows using the core part width and height,
+ * and the threeD part shadow_width.
+ *
+ * no point to do anything if the shadow_width is 0 or the
+ * widget has not been realized.
+ */
+ if (s > 0 && XtIsRealized(gw))
+ {
+ Dimension h = tdo->rectangle.height;
+ Dimension w = tdo->rectangle.width - ps;
+ Dimension x = tdo->rectangle.x + ps;
+ Dimension y = tdo->rectangle.y;
+ Display *dpy = XtDisplayOfObject(gw);
+ Window win = XtWindowOfObject(gw);
+ GC top, bot;
+
+ if (tdo->sme_threeD.shadowed)
+ {
+ top = tdo->sme_threeD.top_shadow_GC;
+ bot = tdo->sme_threeD.bot_shadow_GC;
+ }
+ else
+ top = bot = tdo->sme_threeD.erase_GC;
+
+ /* top-left shadow */
+ pt[0].x = x; pt[0].y = y + h;
+ pt[1].x = x; pt[1].y = y;
+ pt[2].x = w; pt[2].y = y;
+ pt[3].x = w - s; pt[3].y = y + s;
+ pt[4].x = ps + s; pt[4].y = y + s;
+ pt[5].x = ps + s; pt[5].y = y + h - s;
+ XFillPolygon(dpy, win, top, pt, 6, Complex, CoordModeOrigin);
+
+ /* bottom-right shadow */
+/* pt[0].x = x; pt[0].y = y + h; */
+ pt[1].x = w; pt[1].y = y + h;
+/* pt[2].x = w; pt[2].y = y; */
+/* pt[3].x = w - s; pt[3].y = y + s; */
+ pt[4].x = w - s; pt[4].y = y + h - s;
+/* pt[5].x = ps + s; pt[5].y = y + h - s; */
+ XFillPolygon(dpy, win, bot, pt, 6, Complex, CoordModeOrigin);
+ }
+}
+
diff --git a/src/SmeThreeD.h b/src/SmeThreeD.h
new file mode 100644
index 0000000..b4d458f
--- /dev/null
+++ b/src/SmeThreeD.h
@@ -0,0 +1,96 @@
+/*
+* $KK: SmeThreeD.h,v 0.3 92/11/04 xx:xx:xx keithley Exp $
+*/
+
+/***********************************************************
+Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+Copyright 1992 by Kaleb Keithley
+
+ 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 names of Digital, MIT, or Kaleb
+Keithley 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.
+
+******************************************************************/
+
+#ifndef _XawSmeThreeD_h
+#define _XawSmeThreeD_h
+
+/***********************************************************************
+ *
+ * ThreeD Widget
+ *
+ ***********************************************************************/
+
+#include <X11/Xmu/Converters.h>
+#include <X11/Xaw3d/Sme.h>
+
+/* Parameters:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ shadowWidth ShadowWidth Dimension 2
+ topShadowPixel TopShadowPixel Pixel dynamic
+ bottomShadowPixel BottomShadowPixel Pixel dynamic
+ topShadowContrast TopShadowContrast Int 20
+ bottomShadowContrast BottomShadowContrast Int 40
+ userData UserData XtPointer NULL
+ beNiceToColormap BeNiceToColormap Boolean False
+
+*/
+
+#define XtNshadowWidth "shadowWidth"
+#define XtCShadowWidth "ShadowWidth"
+#define XtNtopShadowPixel "topShadowPixel"
+#define XtCTopShadowPixel "TopShadowPixel"
+#define XtNbottomShadowPixel "bottomShadowPixel"
+#define XtCBottomShadowPixel "BottomShadowPixel"
+#define XtNtopShadowContrast "topShadowContrast"
+#define XtCTopShadowContrast "TopShadowContrast"
+#define XtNbottomShadowContrast "bottomShadowContrast"
+#define XtCBottomShadowContrast "BottomShadowContrast"
+#define XtNbeNiceToColormap "beNiceToColormap"
+#define XtCBeNiceToColormap "BeNiceToColormap"
+#define XtNbeNiceToColourmap "beNiceToColormap"
+#define XtCBeNiceToColourmap "BeNiceToColormap"
+#define XtNuserData "userData"
+#define XtCUserData "UserData"
+
+typedef struct _SmeThreeDClassRec *SmeThreeDObjectClass;
+typedef struct _SmeThreeDRec *SmeThreeDObject;
+
+extern WidgetClass smeThreeDWidgetClass;
+
+_XFUNCPROTOBEGIN
+
+extern void XawSme3dComputeTopShadowRGB (
+#if NeedFunctionPrototypes
+ Widget /* new */,
+ XColor* /* xcol_out */
+#endif
+);
+
+extern void XawSme3dComputeBottomShadowRGB (
+#if NeedFunctionPrototypes
+ Widget /* new */,
+ XColor* /* xcol_out */
+#endif
+);
+
+_XFUNCPROTOEND
+
+#endif /* _XawSmeThreeD_h */
diff --git a/src/SmeThreeDP.h b/src/SmeThreeDP.h
new file mode 100644
index 0000000..a07dd40
--- /dev/null
+++ b/src/SmeThreeDP.h
@@ -0,0 +1,82 @@
+/*
+* $KK: SmeThreeDP.h,v 0.3 92/11/04 xx:xx:xx keithley Exp $
+*/
+
+/***********************************************************
+Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+Copyright 1992 by Kaleb Keithley
+
+ 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 names of Digital, MIT, or Kaleb
+Keithley 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.
+
+******************************************************************/
+
+#ifndef _XawSmeThreeDP_h
+#define _XawSmeThreeDP_h
+
+#include <X11/Xaw3d/SmeThreeD.h>
+#include <X11/Xaw3d/SmeP.h>
+
+typedef struct {
+ Dimension shadow_width;
+ Pixel top_shadow_pixel;
+ Pixel bot_shadow_pixel;
+ Pixmap top_shadow_pxmap;
+ Pixmap bot_shadow_pxmap;
+ int top_shadow_contrast;
+ int bot_shadow_contrast;
+ GC top_shadow_GC;
+ GC bot_shadow_GC;
+ GC erase_GC;
+ XtPointer user_data;
+ Boolean be_nice_to_cmap;
+ Boolean shadowed;
+ } SmeThreeDPart;
+
+/* Full instance record declaration */
+typedef struct _SmeThreeDRec {
+ ObjectPart object;
+ RectObjPart rectangle;
+ SmePart sme;
+ SmeThreeDPart sme_threeD;
+ } SmeThreeDRec;
+
+typedef void (*XawSme3dShadowDrawProc)(
+#if NeedFunctionPrototypes
+ Widget
+#endif
+);
+
+typedef struct {
+ XawSme3dShadowDrawProc shadowdraw;
+ } SmeThreeDClassPart;
+
+/* Full class record declaration. */
+typedef struct _SmeThreeDClassRec {
+ RectObjClassPart rect_class;
+ SmeClassPart sme_class;
+ SmeThreeDClassPart sme_threeD_class;
+ } SmeThreeDClassRec;
+
+/* Class pointer. */
+extern SmeThreeDClassRec smeThreeDClassRec;
+
+#define XtInheritXawSme3dShadowDraw ((XawSme3dShadowDrawProc) _XtInherit)
+
+#endif /* _XawSmeThreeDP_h */
diff --git a/src/StripCharP.h b/src/StripCharP.h
new file mode 100644
index 0000000..feb91e7
--- /dev/null
+++ b/src/StripCharP.h
@@ -0,0 +1,109 @@
+/*
+* $XConsortium: StripCharP.h,v 1.5 94/04/17 20:12:55 converse Exp $
+*/
+
+
+/***********************************************************
+
+Copyright (c) 1987, 1988 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.
+
+******************************************************************/
+
+#ifndef _XawStripChartP_h
+#define _XawStripChartP_h
+
+#include <X11/Xaw3d/StripChart.h>
+#include <X11/Xaw3d/ThreeDP.h>
+
+#define NO_GCS 0
+#define FOREGROUND 1 << 0
+#define HIGHLIGHT 1 << 1
+#define ALL_GCS (FOREGROUND | HIGHLIGHT)
+
+/* New fields for the stripChart widget instance record */
+
+typedef struct {
+ Pixel fgpixel; /* color index for graph */
+ Pixel hipixel; /* color index for lines */
+ GC fgGC; /* graphics context for fgpixel */
+ GC hiGC; /* graphics context for hipixel */
+
+ /* start of graph stuff */
+
+ int update; /* update frequence */
+ int scale; /* scale factor */
+ int min_scale; /* smallest scale factor */
+ int interval; /* data point interval */
+ XPoint * points ; /* Poly point for repairing graph lines. */
+ double max_value; /* Max Value in window */
+ double valuedata[2048];/* record of data points */
+ XtIntervalId interval_id;
+ XtCallbackList get_value; /* proc to call to fetch load pt */
+ int jump_val; /* Amount to jump on each scroll. */
+} StripChartPart;
+
+/* Full instance record declaration */
+typedef struct _StripChartRec {
+ CorePart core;
+ SimplePart simple;
+ ThreeDPart threeD;
+ StripChartPart strip_chart;
+} StripChartRec;
+
+/* New fields for the StripChart widget class record */
+typedef struct {int dummy;} StripChartClassPart;
+
+/* Full class record declaration. */
+typedef struct _StripChartClassRec {
+ CoreClassPart core_class;
+ SimpleClassPart simple_class;
+ ThreeDClassPart threeD_class;
+ StripChartClassPart strip_chart_class;
+} StripChartClassRec;
+
+/* Class pointer. */
+extern StripChartClassRec stripChartClassRec;
+
+#endif /* _XawStripChartP_h */
diff --git a/src/StripChart.c b/src/StripChart.c
new file mode 100644
index 0000000..5344f97
--- /dev/null
+++ b/src/StripChart.c
@@ -0,0 +1,556 @@
+/* $XConsortium: StripChart.c,v 1.25 94/04/17 20:12:56 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.
+
+******************************************************************/
+
+#include <stdio.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/StripCharP.h>
+#include <X11/Xfuncs.h>
+
+#define MS_PER_SEC 1000
+
+/* Private Data */
+
+#define offset(field) XtOffsetOf(StripChartRec, field)
+
+static XtResource resources[] = {
+ {XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension),
+ offset(core.width), XtRImmediate, (XtPointer) 120},
+ {XtNheight, XtCHeight, XtRDimension, sizeof(Dimension),
+ offset(core.height), XtRImmediate, (XtPointer) 120},
+ {XtNupdate, XtCInterval, XtRInt, sizeof(int),
+ offset(strip_chart.update), XtRImmediate, (XtPointer) 10},
+ {XtNminScale, XtCScale, XtRInt, sizeof(int),
+ offset(strip_chart.min_scale), XtRImmediate, (XtPointer) 1},
+ {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
+ offset(strip_chart.fgpixel), XtRString, XtDefaultForeground},
+ {XtNhighlight, XtCForeground, XtRPixel, sizeof(Pixel),
+ offset(strip_chart.hipixel), XtRString, XtDefaultForeground},
+ {XtNgetValue, XtCCallback, XtRCallback, sizeof(XtPointer),
+ offset(strip_chart.get_value), XtRImmediate, (XtPointer) NULL},
+ {XtNjumpScroll, XtCJumpScroll, XtRInt, sizeof(int),
+ offset(strip_chart.jump_val), XtRImmediate, (XtPointer) DEFAULT_JUMP},
+};
+
+#undef offset
+
+static void Initialize(), Destroy(), Redisplay(), MoveChart(), SetPoints();
+static Boolean SetValues();
+static int repaint_window();
+
+StripChartClassRec stripChartClassRec = {
+ { /* core fields */
+ /* superclass */ (WidgetClass) &threeDClassRec,
+ /* class_name */ "StripChart",
+ /* size */ sizeof(StripChartRec),
+ /* class_initialize */ XawInitializeWidgetSet,
+ /* 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 */ XtExposeCompressMultiple |
+ XtExposeGraphicsExposeMerged,
+ /* compress_enterleave */ TRUE,
+ /* visible_interest */ FALSE,
+ /* destroy */ Destroy,
+ /* resize */ SetPoints,
+ /* expose */ Redisplay,
+ /* set_values */ SetValues,
+ /* set_values_hook */ NULL,
+ /* set_values_almost */ NULL,
+ /* get_values_hook */ NULL,
+ /* accept_focus */ NULL,
+ /* version */ XtVersion,
+ /* callback_private */ NULL,
+ /* tm_table */ NULL,
+ /* query_geometry */ XtInheritQueryGeometry,
+ /* display_accelerator */ XtInheritDisplayAccelerator,
+ /* extension */ NULL
+ },
+ { /* Simple class fields */
+ /* change_sensitive */ XtInheritChangeSensitive
+ },
+ { /* ThreeD fields */
+ /* shadowdraw */ XtInheritXaw3dShadowDraw
+ },
+ { /* Stripchart fields */
+ /* ignore */ 0
+ }
+};
+
+WidgetClass stripChartWidgetClass = (WidgetClass) &stripChartClassRec;
+
+/****************************************************************
+ *
+ * Private Procedures
+ *
+ ****************************************************************/
+
+static void draw_it();
+
+/* Function Name: CreateGC
+ * Description: Creates the GC's
+ * Arguments: w - the strip chart widget.
+ * which - which GC's to create.
+ * Returns: none
+ */
+
+static void
+CreateGC(w, which)
+StripChartWidget w;
+unsigned int which;
+{
+ XGCValues myXGCV;
+
+ if (which & FOREGROUND) {
+ myXGCV.foreground = w->strip_chart.fgpixel;
+ w->strip_chart.fgGC = XtGetGC((Widget) w, GCForeground, &myXGCV);
+ }
+
+ if (which & HIGHLIGHT) {
+ myXGCV.foreground = w->strip_chart.hipixel;
+ w->strip_chart.hiGC = XtGetGC((Widget) w, GCForeground, &myXGCV);
+ }
+}
+
+/* Function Name: DestroyGC
+ * Description: Destroys the GC's
+ * Arguments: w - the strip chart widget.
+ * which - which GC's to destroy.
+ * Returns: none
+ */
+
+static void
+DestroyGC(w, which)
+StripChartWidget w;
+unsigned int which;
+{
+ if (which & FOREGROUND)
+ XtReleaseGC((Widget) w, w->strip_chart.fgGC);
+
+ if (which & HIGHLIGHT)
+ XtReleaseGC((Widget) w, w->strip_chart.hiGC);
+}
+
+/* ARGSUSED */
+static void Initialize (greq, gnew, args, num_args)
+ Widget greq, gnew;
+ ArgList args;
+ Cardinal *num_args;
+{
+ StripChartWidget w = (StripChartWidget)gnew;
+
+ if (w->strip_chart.update > 0)
+ w->strip_chart.interval_id =
+ XtAppAddTimeOut( XtWidgetToApplicationContext(gnew),
+ (unsigned long) w->strip_chart.update * MS_PER_SEC,
+ draw_it, (XtPointer) gnew);
+ CreateGC(w, (unsigned int) ALL_GCS);
+
+ w->strip_chart.scale = w->strip_chart.min_scale;
+ w->strip_chart.interval = 0;
+ w->strip_chart.max_value = 0.0;
+ w->strip_chart.points = NULL;
+ SetPoints((Widget)w);
+}
+
+static void Destroy (gw)
+ Widget gw;
+{
+ StripChartWidget w = (StripChartWidget)gw;
+
+ if (w->strip_chart.update > 0)
+ XtRemoveTimeOut (w->strip_chart.interval_id);
+ if (w->strip_chart.points)
+ XtFree((char *) w->strip_chart.points);
+ DestroyGC(w, (unsigned int) ALL_GCS);
+}
+
+/*
+ * NOTE: This function really needs to recieve graphics exposure
+ * events, but since this is not easily supported until R4 I am
+ * going to hold off until then.
+ */
+
+/* ARGSUSED */
+static void Redisplay(gw, event, region)
+ Widget gw;
+ XEvent *event;
+ Region region;
+{
+
+ StripChartWidget w = (StripChartWidget)gw;
+ StripChartWidgetClass swclass = (StripChartWidgetClass) XtClass (gw);
+ Dimension x, width, s = w->threeD.shadow_width;
+
+ (*swclass->threeD_class.shadowdraw) (gw, event, region, w->threeD.relief, FALSE);
+
+ if (event->type == GraphicsExpose) {
+ x = event->xgraphicsexpose.x;
+ width = event->xgraphicsexpose.width;
+ } else {
+ x = event->xexpose.x;
+ width = event->xexpose.width;
+ }
+ if (x > s) x -= s; /* respect shadow width, but don't become negative */
+ else x = 0;
+ if (x + width > w->core.width - 2 * s) /* ditto for right boundary */
+ width = w->core.width - 2 * s - x;
+
+ (void) repaint_window (gw, x, width);
+}
+
+/* ARGSUSED */
+static void
+draw_it(client_data, id)
+XtPointer client_data;
+XtIntervalId *id; /* unused */
+{
+ StripChartWidget w = (StripChartWidget)client_data;
+ StripChartWidgetClass swclass = (StripChartWidgetClass) XtClass ((Widget) w);
+ Dimension s = w->threeD.shadow_width;
+ double value;
+
+ if (w->strip_chart.update > 0)
+ w->strip_chart.interval_id =
+ XtAppAddTimeOut(XtWidgetToApplicationContext( (Widget) w),
+ (unsigned long) w->strip_chart.update * MS_PER_SEC,
+ draw_it, client_data);
+
+ if (w->strip_chart.interval >= (int)( w->core.width - 2 * s))
+ MoveChart( (StripChartWidget) w, TRUE);
+
+ /* Get the value, stash the point and draw corresponding line. */
+
+ if (w->strip_chart.get_value == NULL)
+ return;
+
+ XtCallCallbacks( (Widget)w, XtNgetValue, (XtPointer)&value );
+
+ /*
+ * Keep w->strip_chart.max_value up to date, and if this data
+ * point is off the graph, change the scale to make it fit.
+ */
+
+ if (value > w->strip_chart.max_value) {
+ w->strip_chart.max_value = value;
+ if (XtIsRealized((Widget)w) &&
+ w->strip_chart.max_value > w->strip_chart.scale) {
+ XClearWindow(XtDisplay ((Widget) w), XtWindow ((Widget) w));
+ w->strip_chart.interval = repaint_window((Widget)w, 0, (int) w->core.width - 2 * s);
+ (*swclass->threeD_class.shadowdraw) ((Widget) w,
+ (XEvent *)0, (Region)0,
+ w->threeD.relief, FALSE);
+ }
+ }
+
+ w->strip_chart.valuedata[w->strip_chart.interval] = value;
+ if (XtIsRealized((Widget)w)) {
+ int y = (int) (( w->core.height - 2 * s)
+ - (int)(( w->core.height - 2 * s) * value) / w->strip_chart.scale);
+
+ XFillRectangle(XtDisplay((Widget) w), XtWindow((Widget) w), w->strip_chart.fgGC,
+ w->strip_chart.interval + s,
+ y + s, (unsigned int) 1,
+ (w->core.height - 2 * s) - y);
+ /*
+ * Fill in the graph lines we just painted over.
+ */
+
+ if (w->strip_chart.points != NULL) {
+ w->strip_chart.points[0].x = w->strip_chart.interval + s;
+ XDrawPoints(XtDisplay(w), XtWindow(w), w->strip_chart.hiGC,
+ w->strip_chart.points, w->strip_chart.scale,
+ CoordModePrevious);
+ }
+
+ XFlush(XtDisplay(w)); /* Flush output buffers */
+ }
+ w->strip_chart.interval++; /* Next point */
+} /* draw_it */
+
+/* Blts data according to current size, then redraws the stripChart window.
+ * Next represents the number of valid points in data. Returns the (possibly)
+ * adjusted value of next. If next is 0, this routine draws an empty window
+ * (scale - 1 lines for graph). If next is less than the current window width,
+ * the returned value is identical to the initial value of next and data is
+ * unchanged. Otherwise keeps half a window's worth of data. If data is
+ * changed, then w->strip_chart.max_value is updated to reflect the
+ * largest data point.
+ */
+
+static int
+repaint_window(gw, left, width)
+Widget gw;
+int left, width;
+{
+ StripChartWidget w = (StripChartWidget) gw;
+ Dimension s = w->threeD.shadow_width;
+ StripChartWidgetClass swclass = (StripChartWidgetClass) XtClass ((Widget) w);
+ int i, j;
+ int next = w->strip_chart.interval;
+ int scale = w->strip_chart.scale;
+ int scalewidth = 0;
+
+ /* Compute the minimum scale required to graph the data, but don't go
+ lower than min_scale. */
+ if (w->strip_chart.interval != 0 || scale <= (int)w->strip_chart.max_value)
+ scale = ((int) (w->strip_chart.max_value)) + 1;
+ if (scale < w->strip_chart.min_scale)
+ scale = w->strip_chart.min_scale;
+
+ if (scale != w->strip_chart.scale) {
+ w->strip_chart.scale = scale;
+ left = 0;
+ width = next; /* check this */
+ scalewidth = w->core.width - 2 * s;
+
+ SetPoints(gw);
+
+ if (XtIsRealized (gw)) {
+ XClearWindow (XtDisplay (gw), XtWindow (gw));
+ (*swclass->threeD_class.shadowdraw) (gw, (XEvent *)0, (Region)0, w->threeD.relief, FALSE);
+ }
+
+ }
+
+ if (XtIsRealized(gw)) {
+ Display *dpy = XtDisplay(gw);
+ Window win = XtWindow(gw);
+
+ width += left - 1;
+ if (!scalewidth) scalewidth = width;
+
+ if (next < (++width - s)) width = next + s;
+
+ /* Draw data point lines. */
+ for (i = left; i < width; i++) {
+ int y = (int) (( w->core.height - 2 * s) -
+ (int)(( w->core.height - 2 * s) * w->strip_chart.valuedata[i]) /
+ w->strip_chart.scale);
+
+ XFillRectangle(dpy, win, w->strip_chart.fgGC,
+ i + s, y + s, (unsigned int) 1,
+ (unsigned int) (w->core.height - 2 * s - y ));
+ }
+
+ /* Draw graph reference lines */
+ for (i = 1; i < w->strip_chart.scale; i++) {
+ j = i * ((w->core.height - 2 * s) / w->strip_chart.scale);
+ XDrawLine(dpy, win, w->strip_chart.hiGC,
+ left + s, j + s, scalewidth + s, j + s);
+ }
+ }
+ return(next);
+}
+
+/* Function Name: MoveChart
+ * Description: moves the chart over when it would run off the end.
+ * Arguments: w - the load widget.
+ * blit - blit the bits? (TRUE/FALSE).
+ * Returns: none.
+ */
+
+static void
+MoveChart(w, blit)
+StripChartWidget w;
+Boolean blit;
+{
+ Dimension s = w->threeD.shadow_width;
+ double old_max;
+ int left, i, j;
+ int next = w->strip_chart.interval;
+
+ if (!XtIsRealized((Widget) w)) return;
+
+ if (w->strip_chart.jump_val < 0) w->strip_chart.jump_val = DEFAULT_JUMP;
+ if (w->strip_chart.jump_val == DEFAULT_JUMP)
+ j = ( w->core.width - 2 * s) / 2; /* Half the window width. */
+ else {
+ j = ( w->core.width - 2 * s) - w->strip_chart.jump_val;
+ if (j < 0) j = 0;
+ }
+
+ (void) memmove((char *)(w->strip_chart.valuedata),
+ (char *)(w->strip_chart.valuedata + next - j),
+ j * sizeof(double));
+ next = w->strip_chart.interval = j;
+
+ /*
+ * Since we just lost some data, recompute the
+ * w->strip_chart.max_value.
+ */
+
+ old_max = w->strip_chart.max_value;
+ w->strip_chart.max_value = 0.0;
+ for (i = 0; i < next; i++) {
+ if (w->strip_chart.valuedata[i] > w->strip_chart.max_value)
+ w->strip_chart.max_value = w->strip_chart.valuedata[i];
+ }
+
+ if (!blit) return; /* we are done... */
+
+ if ( ((int) old_max) != ( (int) w->strip_chart.max_value) ) {
+ XClearWindow(XtDisplay(w), XtWindow(w));
+ repaint_window((Widget)w, 0, w->core.width - 2 * s);
+ return;
+ }
+
+ XCopyArea(XtDisplay((Widget)w), XtWindow((Widget)w), XtWindow((Widget)w),
+ w->strip_chart.hiGC,
+ (int) ((w->strip_chart.jump_val == DEFAULT_JUMP) ?
+ (j + s) : (w->strip_chart.jump_val + s)), s,
+ (unsigned int) j, (unsigned int) ( w->core.height - 2 * s),
+ s, s);
+
+ XClearArea(XtDisplay((Widget)w), XtWindow((Widget)w),
+ (int) j + s, s,
+ (unsigned int) ((w->strip_chart.jump_val == DEFAULT_JUMP) ?
+ j : w->strip_chart.jump_val),
+ (unsigned int) ( w->core.height - 2 * s),
+ FALSE);
+
+ /* Draw graph reference lines */
+ left = j;
+ for (i = 1; i < w->strip_chart.scale; i++) {
+ j = i * ((w->core.height - 2 * s) / w->strip_chart.scale);
+ XDrawLine(XtDisplay((Widget) w), XtWindow( (Widget) w),
+ w->strip_chart.hiGC,
+ left, j + s, ((int)w->core.width - s - 1), j + s);
+ }
+ return;
+}
+
+/* ARGSUSED */
+static Boolean SetValues (current, request, new, args, num_args)
+ Widget current, request, new;
+ ArgList args;
+ Cardinal *num_args;
+{
+ StripChartWidget old = (StripChartWidget)current;
+ StripChartWidget w = (StripChartWidget)new;
+ Boolean ret_val = FALSE;
+ unsigned int new_gc = NO_GCS;
+
+ if (w->strip_chart.update != old->strip_chart.update) {
+ if (old->strip_chart.update > 0)
+ XtRemoveTimeOut (old->strip_chart.interval_id);
+ if (w->strip_chart.update > 0)
+ w->strip_chart.interval_id =
+ XtAppAddTimeOut(XtWidgetToApplicationContext(new),
+ (unsigned long) w->strip_chart.update * MS_PER_SEC,
+ draw_it, (XtPointer)w);
+ }
+
+ if ( w->strip_chart.min_scale > (int) ((w->strip_chart.max_value) + 1) )
+ ret_val = TRUE;
+
+ if ( w->strip_chart.fgpixel != old->strip_chart.fgpixel ) {
+ new_gc |= FOREGROUND;
+ ret_val = True;
+ }
+
+ if ( w->strip_chart.hipixel != old->strip_chart.hipixel ) {
+ new_gc |= HIGHLIGHT;
+ ret_val = True;
+ }
+
+ DestroyGC(old, new_gc);
+ CreateGC(w, new_gc);
+
+ return( ret_val );
+}
+
+/* Function Name: SetPoints
+ * Description: Sets up the polypoint that will be used to draw in
+ * the graph lines.
+ * Arguments: w - the StripChart widget.
+ * Returns: none.
+ */
+
+#define HEIGHT ( (unsigned int) w->core.height)
+
+static void
+SetPoints(widget)
+Widget widget;
+{
+ StripChartWidget w = (StripChartWidget) widget;
+ Dimension s = w->threeD.shadow_width;
+ XPoint * points;
+ Cardinal size;
+ int i;
+
+ if (w->strip_chart.scale <= 1) { /* no scale lines. */
+ XtFree ((char *) w->strip_chart.points);
+ w->strip_chart.points = NULL;
+ return;
+ }
+
+ size = sizeof(XPoint) * (w->strip_chart.scale - 1);
+
+ points = (XPoint *) XtRealloc( (XtPointer) w->strip_chart.points, size);
+ w->strip_chart.points = points;
+
+ /* Draw graph reference lines into clip mask */
+
+ for (i = 1; i < w->strip_chart.scale; i++) {
+ points[i - 1].x = 0;
+ points[i - 1].y = ( short)(((double)w->core.height - 2.0 * (double) s) / (double) w->strip_chart.scale );
+ }
+ points[0].y += (short)s;
+}
diff --git a/src/StripChart.h b/src/StripChart.h
new file mode 100644
index 0000000..93052d0
--- /dev/null
+++ b/src/StripChart.h
@@ -0,0 +1,118 @@
+/* $XConsortium: StripChart.h,v 1.6 94/04/17 20:12:57 converse Exp $ */
+
+/***********************************************************
+
+Copyright (c) 1987, 1988 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.
+
+******************************************************************/
+
+#ifndef _XawStripChart_h
+#define _XawStripChart_h
+
+/***********************************************************************
+ *
+ * StripChart Widget
+ *
+ ***********************************************************************/
+
+/* StripChart resources:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ accelerators Accelerators AcceleratorTable NULL
+ ancestorSensitive AncestorSensitive Boolean True
+ background Background Pixel XtDefaultBackground
+ backgroundPixmap Pixmap Pixmap XtUnspecifiedPixmap
+ borderColor BorderColor Pixel XtDefaultForeground
+ borderPixmap Pixmap Pixmap XtUnspecifiedPixmap
+ borderWidth BorderWidth Dimension 1
+ colormap Colormap Colormap parent's colormap
+ cursor Cursor Cursor None
+ cursorName Cursor String NULL
+ depth Depth int parent's depth
+ destroyCallback Callback XtCallbackList NULL
+ foreground Foreground Pixel XtDefaultForeground
+ getValue Callback XtCallbackList NULL
+ height Height Dimension 120
+ highlight Foreground Pixel XtDefaultForeground
+ insensitiveBorder Insensitive Pixmap GreyPixmap
+ jumpScroll JumpScroll int 1/2 width
+ mappedWhenManaged MappedWhenManaged Boolean True
+ minScale Scale int 1
+ pointerColor Foreground Pixel XtDefaultForeground
+ pointerColorBackground Background Pixel XtDefaultBackground
+ screen Screen Screen parent's screen
+ sensitive Sensitive Boolean True
+ translations Translations TranslationTable NULL
+ update Interval int 10 (seconds)
+ width Width Dimension 120
+ x Position Position 0
+ y Position Position 0
+
+*/
+
+#define DEFAULT_JUMP -1
+
+#ifndef _XtStringDefs_h_
+#define XtNhighlight "highlight"
+#define XtNupdate "update"
+#endif
+
+#define XtCJumpScroll "JumpScroll"
+#define XtCScale "Scale"
+
+#define XtNgetValue "getValue"
+#define XtNjumpScroll "jumpScroll"
+#define XtNminScale "minScale"
+#define XtNscale "scale"
+#define XtNvmunix "vmunix"
+
+typedef struct _StripChartRec *StripChartWidget;
+typedef struct _StripChartClassRec *StripChartWidgetClass;
+
+extern WidgetClass stripChartWidgetClass;
+
+#endif /* _XawStripChart_h */
+/* DON'T ADD STUFF AFTER THIS #endif */
diff --git a/src/Template.c b/src/Template.c
new file mode 100644
index 0000000..33063aa
--- /dev/null
+++ b/src/Template.c
@@ -0,0 +1,94 @@
+/* $XConsortium: Template.c,v 1.5 94/04/17 20:12:58 converse Exp $ */
+
+/*
+
+Copyright (c) 1987 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.
+
+*/
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include "TemplateP.h"
+
+static XtResource resources[] = {
+#define offset(field) XtOffsetOf(TemplateRec, template.field)
+ /* {name, class, type, size, offset, default_type, default_addr}, */
+ { XtNtemplateResource, XtCTemplateResource, XtRTemplateResource,
+ sizeof(char*), offset(resource), XtRString, (XtPointer) "default" },
+#undef offset
+};
+
+static void TemplateAction(/* Widget, XEvent*, String*, Cardinal* */);
+
+static XtActionsRec actions[] =
+{
+ /* {name, procedure}, */
+ {"template", TemplateAction},
+};
+
+static char translations[] =
+"<Key>: template() \n\
+";
+
+TemplateClassRec templateClassRec = {
+ { /* core fields */
+ /* superclass */ (WidgetClass) &widgetClassRec,
+ /* class_name */ "Template",
+ /* widget_size */ sizeof(TemplateRec),
+ /* class_initialize */ NULL,
+ /* class_part_initialize */ NULL,
+ /* class_inited */ FALSE,
+ /* initialize */ NULL,
+ /* initialize_hook */ NULL,
+ /* realize */ XtInheritRealize,
+ /* actions */ actions,
+ /* num_actions */ XtNumber(actions),
+ /* resources */ resources,
+ /* num_resources */ XtNumber(resources),
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ TRUE,
+ /* compress_exposure */ TRUE,
+ /* compress_enterleave */ TRUE,
+ /* visible_interest */ FALSE,
+ /* destroy */ NULL,
+ /* resize */ NULL,
+ /* expose */ NULL,
+ /* set_values */ NULL,
+ /* set_values_hook */ NULL,
+ /* set_values_almost */ XtInheritSetValuesAlmost,
+ /* get_values_hook */ NULL,
+ /* accept_focus */ NULL,
+ /* version */ XtVersion,
+ /* callback_private */ NULL,
+ /* tm_table */ translations,
+ /* query_geometry */ XtInheritQueryGeometry,
+ /* display_accelerator */ XtInheritDisplayAccelerator,
+ /* extension */ NULL
+ },
+ { /* template fields */
+ /* empty */ 0
+ }
+};
+
+WidgetClass templateWidgetClass = (WidgetClass)&templateClassRec;
diff --git a/src/Template.h b/src/Template.h
new file mode 100644
index 0000000..dbb6b14
--- /dev/null
+++ b/src/Template.h
@@ -0,0 +1,71 @@
+/* $XConsortium: Template.h,v 1.6 94/04/17 20:12:59 converse Exp $ */
+
+/*
+
+Copyright (c) 1987 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.
+
+*/
+
+#ifndef _Template_h
+#define _Template_h
+
+/****************************************************************
+ *
+ * Template widget
+ *
+ ****************************************************************/
+
+/* Resources:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ background Background Pixel XtDefaultBackground
+ border BorderColor Pixel XtDefaultForeground
+ borderWidth BorderWidth Dimension 1
+ destroyCallback Callback Pointer NULL
+ height Height Dimension 0
+ mappedWhenManaged MappedWhenManaged Boolean True
+ sensitive Sensitive Boolean True
+ width Width Dimension 0
+ x Position Position 0
+ y Position Position 0
+
+*/
+
+/* define any special resource names here that are not in <X11/StringDefs.h> */
+
+#define XtNtemplateResource "templateResource"
+
+#define XtCTemplateResource "TemplateResource"
+
+/* declare specific TemplateWidget class and instance datatypes */
+
+typedef struct _TemplateClassRec* TemplateWidgetClass;
+typedef struct _TemplateRec* TemplateWidget;
+
+/* declare the class constant */
+
+extern WidgetClass templateWidgetClass;
+
+#endif /* _Template_h */
diff --git a/src/TemplateP.h b/src/TemplateP.h
new file mode 100644
index 0000000..d20175e
--- /dev/null
+++ b/src/TemplateP.h
@@ -0,0 +1,64 @@
+/* $XConsortium: TemplateP.h,v 1.7 94/04/17 20:13:00 rws Exp $ */
+
+/*
+
+Copyright (c) 1987 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.
+
+*/
+
+
+#ifndef _TemplateP_h
+#define _TemplateP_h
+
+#include <X11/Xaw3d/Template.h>
+/* include superclass private header file */
+#include <X11/CoreP.h>
+
+/* define unique representation types not found in <X11/StringDefs.h> */
+
+#define XtRTemplateResource "TemplateResource"
+
+typedef struct {
+ int empty;
+} TemplateClassPart;
+
+typedef struct _TemplateClassRec {
+ CoreClassPart core_class;
+ TemplateClassPart template_class;
+} TemplateClassRec;
+
+extern TemplateClassRec templateClassRec;
+
+typedef struct {
+ /* resources */
+ char* resource;
+ /* private state */
+} TemplatePart;
+
+typedef struct _TemplateRec {
+ CorePart core;
+ TemplatePart template;
+} TemplateRec;
+
+#endif /* _TemplateP_h */
diff --git a/src/Text.c b/src/Text.c
new file mode 100644
index 0000000..4b47bbd
--- /dev/null
+++ b/src/Text.c
@@ -0,0 +1,3600 @@
+/* $XConsortium: Text.c,v 1.197 95/06/14 15:07:27 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.
+
+******************************************************************/
+
+#include "Xaw3dP.h"
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Shell.h>
+#include <X11/Xatom.h>
+#include <X11/Xutil.h>
+#ifdef XAW_INTERNATIONALIZATION
+#include "XawI18n.h"
+#endif
+#include <stdio.h>
+#include <X11/Xmu/Atoms.h>
+#include <X11/Xmu/CharSet.h>
+#include <X11/Xmu/Converters.h>
+#include <X11/Xmu/StdSel.h>
+#include <X11/Xmu/Misc.h>
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/Cardinals.h>
+#include <X11/Xaw3d/Scrollbar.h>
+#include <X11/Xaw3d/TextP.h>
+#ifdef XAW_INTERNATIONALIZATION
+#include <X11/Xaw3d/MultiSinkP.h>
+#include <X11/Xaw3d/XawImP.h>
+#endif
+#include <X11/Xaw3d/ThreeDP.h>
+#include <X11/Xfuncs.h>
+#include <ctype.h> /* for isprint() */
+
+#ifndef MAX_LEN_CT
+#define MAX_LEN_CT 6 /* for sequence: ESC $ ( A \xx \xx */
+#endif
+
+unsigned long FMT8BIT = 0L;
+unsigned long XawFmt8Bit = 0L;
+#ifdef XAW_INTERNATIONALIZATION
+unsigned long XawFmtWide = 0L;
+#endif
+
+#define SinkClearToBG XawTextSinkClearToBackground
+
+#define SrcScan XawTextSourceScan
+#define SrcRead XawTextSourceRead
+#define SrcReplace XawTextSourceReplace
+#define SrcSearch XawTextSourceSearch
+#define SrcCvtSel XawTextSourceConvertSelection
+#define SrcSetSelection XawTextSourceSetSelection
+
+#define BIGNUM ((Dimension)32023)
+#define MULTI_CLICK_TIME 500L
+
+/*
+ * Compute a the maximum length of a cut buffer that we can pass at any
+ * time. The 64 allows for the overhead of the Change Property request.
+ */
+
+#define MAX_CUT_LEN(dpy) (XMaxRequestSize(dpy) - 64)
+
+#define IsValidLine(ctx, num) ( ((num) == 0) || \
+ ((ctx)->text.lt.info[(num)].position != 0) )
+
+/*
+ * Defined in Text.c
+ */
+static void UnrealizeScrollbars();
+static void VScroll(), VJump(), HScroll(), HJump(), ClearWindow();
+static void DisplayTextWindow(), ModifySelection(), PushCopyQueue();
+static void UpdateTextInLine(), UpdateTextInRectangle(), PopCopyQueue();
+static void FlushUpdate();
+static Boolean LineAndXYForPosition(), TranslateExposeRegion();
+static XawTextPosition FindGoodPosition(), _BuildLineTable();
+
+void _XawTextAlterSelection(), _XawTextExecuteUpdate();
+void _XawTextSetScrollBars(), _XawTextPrepareToUpdate();
+
+/****************************************************************
+ *
+ * Full class record constant
+ *
+ ****************************************************************/
+
+static XawTextSelectType defaultSelectTypes[] = {
+ XawselectPosition, XawselectWord, XawselectLine, XawselectParagraph,
+ XawselectAll, XawselectNull,
+};
+
+static XPointer defaultSelectTypesPtr = (XPointer)defaultSelectTypes;
+extern char *_XawDefaultTextTranslations1, *_XawDefaultTextTranslations2,
+ *_XawDefaultTextTranslations3, *_XawDefaultTextTranslations4;
+static Dimension defWidth = 100;
+static Dimension defHeight = DEFAULT_TEXT_HEIGHT;
+
+#define offset(field) XtOffsetOf(TextRec, field)
+static XtResource resources[] = {
+ {XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension),
+ offset(core.width), XtRDimension, (XtPointer)&defWidth},
+ {XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor),
+ offset(simple.cursor), XtRString, "xterm"},
+ {XtNheight, XtCHeight, XtRDimension, sizeof(Dimension),
+ offset(core.height), XtRDimension, (XtPointer)&defHeight},
+ {XtNdisplayPosition, XtCTextPosition, XtRInt, sizeof(XawTextPosition),
+ offset(text.lt.top), XtRImmediate, (XtPointer)0},
+ {XtNinsertPosition, XtCTextPosition, XtRInt, sizeof(XawTextPosition),
+ offset(text.insertPos), XtRImmediate,(XtPointer)0},
+ {XtNleftMargin, XtCMargin, XtRPosition, sizeof (Position),
+ offset(text.r_margin.left), XtRImmediate, (XtPointer)2},
+ {XtNrightMargin, XtCMargin, XtRPosition, sizeof (Position),
+ offset(text.r_margin.right), XtRImmediate, (XtPointer)4},
+ {XtNtopMargin, XtCMargin, XtRPosition, sizeof (Position),
+ offset(text.r_margin.top), XtRImmediate, (XtPointer)2},
+ {XtNbottomMargin, XtCMargin, XtRPosition, sizeof (Position),
+ offset(text.r_margin.bottom), XtRImmediate, (XtPointer)2},
+ {XtNselectTypes, XtCSelectTypes, XtRPointer,
+ sizeof(XawTextSelectType*), offset(text.sarray),
+ XtRPointer, (XtPointer)&defaultSelectTypesPtr},
+ {XtNtextSource, XtCTextSource, XtRWidget, sizeof (Widget),
+ offset(text.source), XtRImmediate, NULL},
+ {XtNtextSink, XtCTextSink, XtRWidget, sizeof (Widget),
+ offset(text.sink), XtRImmediate, NULL},
+ {XtNdisplayCaret, XtCOutput, XtRBoolean, sizeof(Boolean),
+ offset(text.display_caret), XtRImmediate, (XtPointer)True},
+ {XtNscrollVertical, XtCScroll, XtRScrollMode, sizeof(XawTextScrollMode),
+ offset(text.scroll_vert), XtRImmediate, (XtPointer) XawtextScrollNever},
+ {XtNscrollHorizontal, XtCScroll, XtRScrollMode, sizeof(XawTextScrollMode),
+ offset(text.scroll_horiz), XtRImmediate, (XtPointer) XawtextScrollNever},
+ {XtNwrap, XtCWrap, XtRWrapMode, sizeof(XawTextWrapMode),
+ offset(text.wrap), XtRImmediate, (XtPointer) XawtextWrapNever},
+ {XtNresize, XtCResize, XtRResizeMode, sizeof(XawTextResizeMode),
+ offset(text.resize), XtRImmediate, (XtPointer) XawtextResizeNever},
+ {XtNautoFill, XtCAutoFill, XtRBoolean, sizeof(Boolean),
+ offset(text.auto_fill), XtRImmediate, (XtPointer) FALSE},
+ {XtNunrealizeCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
+ offset(text.unrealize_callbacks), XtRCallback, (XtPointer) NULL}
+};
+#undef offset
+
+/* ARGSUSED */
+static void
+CvtStringToScrollMode(args, num_args, fromVal, toVal)
+XrmValuePtr args; /* unused */
+Cardinal *num_args; /* unused */
+XrmValuePtr fromVal;
+XrmValuePtr toVal;
+{
+ static XawTextScrollMode scrollMode;
+ static XrmQuark QScrollNever, QScrollAlways, QScrollWhenNeeded;
+ XrmQuark q;
+ char lowerName[40];
+ static Boolean inited = FALSE;
+
+ if ( !inited ) {
+ QScrollNever = XrmPermStringToQuark(XtEtextScrollNever);
+ QScrollWhenNeeded = XrmPermStringToQuark(XtEtextScrollWhenNeeded);
+ QScrollAlways = XrmPermStringToQuark(XtEtextScrollAlways);
+ inited = TRUE;
+ }
+
+ if (strlen ((char*) fromVal->addr) < sizeof lowerName) {
+ XmuCopyISOLatin1Lowered (lowerName, (char *)fromVal->addr);
+ q = XrmStringToQuark(lowerName);
+
+ if (q == QScrollNever) scrollMode = XawtextScrollNever;
+ else if (q == QScrollWhenNeeded) scrollMode = XawtextScrollWhenNeeded;
+ else if (q == QScrollAlways) scrollMode = XawtextScrollAlways;
+ else {
+ toVal->size = 0;
+ toVal->addr = NULL;
+ return;
+ }
+ toVal->size = sizeof scrollMode;
+ toVal->addr = (XPointer) &scrollMode;
+ return;
+ }
+ toVal->size = 0;
+ toVal->addr = NULL;
+}
+
+/* ARGSUSED */
+static void
+CvtStringToWrapMode(args, num_args, fromVal, toVal)
+XrmValuePtr args; /* unused */
+Cardinal *num_args; /* unused */
+XrmValuePtr fromVal;
+XrmValuePtr toVal;
+{
+ static XawTextWrapMode wrapMode;
+ static XrmQuark QWrapNever, QWrapLine, QWrapWord;
+ XrmQuark q;
+ char lowerName[BUFSIZ];
+ static Boolean inited = FALSE;
+
+ if ( !inited ) {
+ QWrapNever = XrmPermStringToQuark(XtEtextWrapNever);
+ QWrapLine = XrmPermStringToQuark(XtEtextWrapLine);
+ QWrapWord = XrmPermStringToQuark(XtEtextWrapWord);
+ inited = TRUE;
+ }
+
+ if (strlen ((char*) fromVal->addr) < sizeof lowerName) {
+ XmuCopyISOLatin1Lowered (lowerName, (char *)fromVal->addr);
+ q = XrmStringToQuark(lowerName);
+
+ if (q == QWrapNever) wrapMode = XawtextWrapNever;
+ else if (q == QWrapLine) wrapMode = XawtextWrapLine;
+ else if (q == QWrapWord) wrapMode = XawtextWrapWord;
+ else {
+ toVal->size = 0;
+ toVal->addr = NULL;
+ return;
+ }
+ toVal->size = sizeof wrapMode;
+ toVal->addr = (XPointer) &wrapMode;
+ return;
+ }
+ toVal->size = 0;
+ toVal->addr = NULL;
+}
+
+/* ARGSUSED */
+static void
+CvtStringToResizeMode(args, num_args, fromVal, toVal)
+XrmValuePtr args; /* unused */
+Cardinal *num_args; /* unused */
+XrmValuePtr fromVal;
+XrmValuePtr toVal;
+{
+ static XawTextResizeMode resizeMode;
+ static XrmQuark QResizeNever, QResizeWidth, QResizeHeight, QResizeBoth;
+ XrmQuark q;
+ char lowerName[40];
+ static Boolean inited = FALSE;
+
+ if ( !inited ) {
+ QResizeNever = XrmPermStringToQuark(XtEtextResizeNever);
+ QResizeWidth = XrmPermStringToQuark(XtEtextResizeWidth);
+ QResizeHeight = XrmPermStringToQuark(XtEtextResizeHeight);
+ QResizeBoth = XrmPermStringToQuark(XtEtextResizeBoth);
+ inited = TRUE;
+ }
+
+ if (strlen ((char*) fromVal->addr) < sizeof lowerName) {
+ XmuCopyISOLatin1Lowered (lowerName, (char *)fromVal->addr);
+ q = XrmStringToQuark(lowerName);
+
+ if (q == QResizeNever) resizeMode = XawtextResizeNever;
+ else if (q == QResizeWidth) resizeMode = XawtextResizeWidth;
+ else if (q == QResizeHeight) resizeMode = XawtextResizeHeight;
+ else if (q == QResizeBoth) resizeMode = XawtextResizeBoth;
+ else {
+ toVal->size = 0;
+ toVal->addr = NULL;
+ return;
+ }
+ toVal->size = sizeof resizeMode;
+ toVal->addr = (XPointer) &resizeMode;
+ return;
+ }
+ toVal->size = 0;
+ toVal->addr = NULL;
+}
+
+static void
+ClassInitialize()
+{
+ int len1 = strlen (_XawDefaultTextTranslations1);
+ int len2 = strlen (_XawDefaultTextTranslations2);
+ int len3 = strlen (_XawDefaultTextTranslations3);
+ int len4 = strlen (_XawDefaultTextTranslations4);
+ char *buf = XtMalloc ((unsigned)(len1 + len2 + len3 + len4 + 1));
+ char *cp = buf;
+
+ if (!XawFmt8Bit)
+ FMT8BIT = XawFmt8Bit = XrmPermStringToQuark("FMT8BIT");
+#ifdef XAW_INTERNATIONALIZATION
+ if (!XawFmtWide)
+ XawFmtWide = XrmPermStringToQuark("FMTWIDE");
+#endif
+
+ XawInitializeWidgetSet();
+
+/*
+ * Set the number of actions.
+ */
+
+ textClassRec.core_class.num_actions = _XawTextActionsTableCount;
+
+ (void) strcpy( cp, _XawDefaultTextTranslations1); cp += len1;
+ (void) strcpy( cp, _XawDefaultTextTranslations2); cp += len2;
+ (void) strcpy( cp, _XawDefaultTextTranslations3); cp += len3;
+ (void) strcpy( cp, _XawDefaultTextTranslations4);
+ textWidgetClass->core_class.tm_table = buf;
+
+ XtAddConverter(XtRString, XtRScrollMode, CvtStringToScrollMode,
+ (XtConvertArgList)NULL, (Cardinal)0 );
+ XtAddConverter(XtRString, XtRWrapMode, CvtStringToWrapMode,
+ (XtConvertArgList)NULL, (Cardinal)0 );
+ XtAddConverter(XtRString, XtRResizeMode, CvtStringToResizeMode,
+ (XtConvertArgList)NULL, (Cardinal)0 );
+}
+
+/* Function Name: PositionHScrollBar.
+ * Description: Positions the Horizontal scrollbar.
+ * Arguments: ctx - the text widget.
+ * Returns: none
+ */
+
+static void
+PositionHScrollBar(ctx)
+TextWidget ctx;
+{
+ Widget vbar = ctx->text.vbar, hbar = ctx->text.hbar;
+ Position top, left = 0;
+ int s = ((ThreeDWidget)ctx->text.threeD)->threeD.shadow_width;
+
+ if (ctx->text.hbar == NULL) return;
+
+ if (vbar != NULL)
+ left += (Position) (vbar->core.width + vbar->core.border_width);
+
+ XtResizeWidget( hbar, ctx->core.width - left - s, hbar->core.height,
+ hbar->core.border_width );
+
+ left = s / 2 - (Position) hbar->core.border_width;
+ if (left < 0) left = 0;
+ if (vbar != NULL)
+ left += (Position) (vbar->core.width + vbar->core.border_width);
+
+ top = ctx->core.height - (hbar->core.height + hbar->core.border_width + s / 2);
+
+ XtMoveWidget( hbar, left, top);
+}
+
+/* Function Name: PositionVScrollBar.
+ * Description: Positions the Vertical scrollbar.
+ * Arguments: ctx - the text widget.
+ * Returns: none.
+ */
+
+static void
+PositionVScrollBar(ctx)
+TextWidget ctx;
+{
+ Widget vbar = ctx->text.vbar;
+ Position pos;
+ Dimension bw;
+ int s = ((ThreeDWidget)ctx->text.threeD)->threeD.shadow_width;
+
+ if (vbar == NULL) return;
+ bw = vbar->core.border_width;
+
+ XtResizeWidget( vbar, vbar->core.width, ctx->core.height - s, bw);
+ pos = s / 2 - (Position)bw;
+ if (pos < 0) pos = 0;
+
+ XtMoveWidget( vbar, pos, pos);
+}
+
+static void
+CreateVScrollBar(ctx)
+TextWidget ctx;
+{
+ Widget vbar;
+
+ if (ctx->text.vbar != NULL) return;
+
+ ctx->text.vbar = vbar =
+ XtCreateWidget("vScrollbar", scrollbarWidgetClass, (Widget)ctx,
+ (ArgList) NULL, ZERO);
+ XtAddCallback( vbar, XtNscrollProc, VScroll, (XtPointer)ctx );
+ XtAddCallback( vbar, XtNjumpProc, VJump, (XtPointer)ctx );
+ if (ctx->text.hbar == NULL)
+ XtAddCallback((Widget) ctx, XtNunrealizeCallback, UnrealizeScrollbars,
+ (XtPointer) NULL);
+
+ ctx->text.r_margin.left += vbar->core.width + vbar->core.border_width;
+ ctx->text.margin.left = ctx->text.r_margin.left;
+
+ PositionVScrollBar(ctx);
+ PositionHScrollBar(ctx); /* May modify location of Horiz. Bar. */
+
+ if (XtIsRealized((Widget)ctx)) {
+ XtRealizeWidget(vbar);
+ XtMapWidget(vbar);
+ }
+}
+
+/* Function Name: DestroyVScrollBar
+ * Description: Removes a vertical ScrollBar.
+ * Arguments: ctx - the parent text widget.
+ * Returns: none.
+ */
+
+static void
+DestroyVScrollBar(ctx)
+TextWidget ctx;
+{
+ Widget vbar = ctx->text.vbar;
+
+ if (vbar == NULL) return;
+
+ ctx->text.r_margin.left -= vbar->core.width + vbar->core.border_width;
+ ctx->text.margin.left = ctx->text.r_margin.left;
+ if (ctx->text.hbar == NULL)
+ XtRemoveCallback((Widget) ctx, XtNunrealizeCallback, UnrealizeScrollbars,
+ (XtPointer) NULL);
+ XtDestroyWidget(vbar);
+ ctx->text.vbar = NULL;
+ PositionHScrollBar(ctx);
+}
+
+static void
+CreateHScrollBar(ctx)
+TextWidget ctx;
+{
+ Arg args[1];
+ Widget hbar;
+
+ if (ctx->text.hbar != NULL) return;
+
+ XtSetArg(args[0], XtNorientation, XtorientHorizontal);
+ ctx->text.hbar = hbar =
+ XtCreateWidget("hScrollbar", scrollbarWidgetClass, (Widget)ctx, args, ONE);
+ XtAddCallback( hbar, XtNscrollProc, HScroll, (XtPointer)ctx );
+ XtAddCallback( hbar, XtNjumpProc, HJump, (XtPointer)ctx );
+ if (ctx->text.vbar == NULL)
+ XtAddCallback((Widget) ctx, XtNunrealizeCallback, UnrealizeScrollbars,
+ (XtPointer) NULL);
+
+/**/
+ ctx->text.r_margin.bottom += hbar->core.height + hbar->core.border_width;
+ ctx->text.margin.bottom = ctx->text.r_margin.bottom;
+/**/
+ PositionHScrollBar(ctx);
+ if (XtIsRealized((Widget)ctx)) {
+ XtRealizeWidget(hbar);
+ XtMapWidget(hbar);
+ }
+}
+
+/* Function Name: DestroyHScrollBar
+ * Description: Removes a horizontal ScrollBar.
+ * Arguments: ctx - the parent text widget.
+ * Returns: none.
+ */
+
+static void
+DestroyHScrollBar(ctx)
+TextWidget ctx;
+{
+ Widget hbar = ctx->text.hbar;
+
+ if (hbar == NULL) return;
+
+/**/
+ ctx->text.r_margin.bottom -= hbar->core.height + hbar->core.border_width;
+ ctx->text.margin.bottom = ctx->text.r_margin.bottom;
+/**/
+ if (ctx->text.vbar == NULL)
+ XtRemoveCallback((Widget) ctx, XtNunrealizeCallback, UnrealizeScrollbars,
+ (XtPointer) NULL);
+ XtDestroyWidget(hbar);
+ ctx->text.hbar = NULL;
+}
+
+/* ARGSUSED */
+static void
+Initialize(request, new, args, num_args)
+Widget request, new;
+ArgList args; /* unused */
+Cardinal *num_args; /* unused */
+{
+ TextWidget ctx = (TextWidget) new;
+ char error_buf[BUFSIZ];
+ int s;
+
+ ctx->text.threeD = XtVaCreateWidget("threeD", threeDWidgetClass, new,
+ XtNx, 0, XtNy, 0,
+ XtNwidth, 10, XtNheight, 10, /* dummy */
+ NULL);
+
+ s = ((ThreeDWidget)ctx->text.threeD)->threeD.shadow_width;
+
+ ctx->text.r_margin.left += s;
+ ctx->text.r_margin.right += s;
+ ctx->text.r_margin.top += s;
+ ctx->text.r_margin.bottom += s - 1;
+
+ ctx->text.lt.lines = 0;
+ ctx->text.lt.info = NULL;
+ (void) bzero((char *) &(ctx->text.origSel), sizeof(XawTextSelection));
+ (void) bzero((char *) &(ctx->text.s), sizeof(XawTextSelection));
+ ctx->text.s.type = XawselectPosition;
+ ctx->text.salt = NULL;
+ ctx->text.hbar = ctx->text.vbar = (Widget) NULL;
+ ctx->text.lasttime = 0; /* ||| correct? */
+ ctx->text.time = 0; /* ||| correct? */
+ ctx->text.showposition = TRUE;
+ ctx->text.lastPos = (ctx->text.source != NULL) ? GETLASTPOS : 0;
+ ctx->text.file_insert = NULL;
+ ctx->text.search = NULL;
+ ctx->text.updateFrom = (XawTextPosition *) XtMalloc((unsigned) ONE);
+ ctx->text.updateTo = (XawTextPosition *) XtMalloc((unsigned) ONE);
+ ctx->text.numranges = ctx->text.maxranges = 0;
+ ctx->text.gc = DefaultGCOfScreen(XtScreen(ctx));
+ ctx->text.hasfocus = FALSE;
+ ctx->text.margin = ctx->text.r_margin; /* Strucure copy. */
+ ctx->text.update_disabled = FALSE;
+ ctx->text.old_insert = -1;
+ ctx->text.mult = 1;
+ ctx->text.single_char = FALSE;
+ ctx->text.copy_area_offsets = NULL;
+ ctx->text.salt2 = NULL;
+
+ if (ctx->core.height == DEFAULT_TEXT_HEIGHT) {
+ ctx->core.height = VMargins(ctx);
+ if (ctx->text.sink != NULL)
+ ctx->core.height += XawTextSinkMaxHeight(ctx->text.sink, 1);
+ }
+
+ if (ctx->text.scroll_vert != XawtextScrollNever)
+ if ( (ctx->text.resize == XawtextResizeHeight) ||
+ (ctx->text.resize == XawtextResizeBoth) ) {
+ (void) sprintf(error_buf, "Xaw Text Widget %s:\n %s %s.", ctx->core.name,
+ "Vertical scrolling not allowed with height resize.\n",
+ "Vertical scrolling has been DEACTIVATED.");
+ XtAppWarning(XtWidgetToApplicationContext(new), error_buf);
+ ctx->text.scroll_vert = XawtextScrollNever;
+ }
+ else if (ctx->text.scroll_vert == XawtextScrollAlways)
+ CreateVScrollBar(ctx);
+
+ if (ctx->text.scroll_horiz != XawtextScrollNever)
+ if (ctx->text.wrap != XawtextWrapNever) {
+ (void) sprintf(error_buf, "Xaw Text Widget %s:\n %s %s.", ctx->core.name,
+ "Horizontal scrolling not allowed with wrapping active.\n",
+ "Horizontal scrolling has been DEACTIVATED.");
+ XtAppWarning(XtWidgetToApplicationContext(new), error_buf);
+ ctx->text.scroll_horiz = XawtextScrollNever;
+ }
+ else if ( (ctx->text.resize == XawtextResizeWidth) ||
+ (ctx->text.resize == XawtextResizeBoth) ) {
+ (void) sprintf(error_buf, "Xaw Text Widget %s:\n %s %s.", ctx->core.name,
+ "Horizontal scrolling not allowed with width resize.\n",
+ "Horizontal scrolling has been DEACTIVATED.");
+ XtAppWarning(XtWidgetToApplicationContext(new), error_buf);
+ ctx->text.scroll_horiz = XawtextScrollNever;
+ }
+ else if (ctx->text.scroll_horiz == XawtextScrollAlways)
+ CreateHScrollBar(ctx);
+}
+
+static void
+Realize( w, valueMask, attributes )
+Widget w;
+Mask *valueMask;
+XSetWindowAttributes *attributes;
+{
+ TextWidget ctx = (TextWidget)w;
+ void _XawTextCheckResize();
+
+ (*textClassRec.core_class.superclass->core_class.realize)
+ (w, valueMask, attributes);
+
+ if (ctx->text.hbar != NULL) { /* Put up Hbar -- Must be first. */
+ XtRealizeWidget(ctx->text.hbar);
+ XtMapWidget(ctx->text.hbar);
+ }
+
+ if (ctx->text.vbar != NULL) { /* Put up Vbar. */
+ XtRealizeWidget(ctx->text.vbar);
+ XtMapWidget(ctx->text.vbar);
+ }
+
+ _XawTextBuildLineTable(ctx, ctx->text.lt.top, TRUE);
+ _XawTextSetScrollBars(ctx);
+ _XawTextCheckResize(ctx);
+}
+
+/*ARGSUSED*/
+static void UnrealizeScrollbars(widget, client, call)
+Widget widget; /* Text widget */
+XtPointer client; /* unused */
+XtPointer call; /* unused */
+{
+ TextWidget ctx = (TextWidget) widget;
+
+ if (ctx->text.hbar)
+ XtUnrealizeWidget(ctx->text.hbar);
+ if (ctx->text.vbar)
+ XtUnrealizeWidget(ctx->text.vbar);
+}
+
+/* Utility routines for support of Text */
+
+static void
+_CreateCutBuffers(d)
+Display *d;
+{
+ static struct _DisplayRec {
+ struct _DisplayRec *next;
+ Display *dpy;
+ } *dpy_list = NULL;
+ struct _DisplayRec *dpy_ptr;
+
+ for (dpy_ptr = dpy_list; dpy_ptr != NULL; dpy_ptr = dpy_ptr->next)
+ if (dpy_ptr->dpy == d) return;
+
+ dpy_ptr = XtNew(struct _DisplayRec);
+ dpy_ptr->next = dpy_list;
+ dpy_ptr->dpy = d;
+ dpy_list = dpy_ptr;
+
+#define Create(buffer) \
+ XChangeProperty(d, RootWindow(d, 0), buffer, XA_STRING, 8, \
+ PropModeAppend, NULL, 0 );
+
+ Create( XA_CUT_BUFFER0 );
+ Create( XA_CUT_BUFFER1 );
+ Create( XA_CUT_BUFFER2 );
+ Create( XA_CUT_BUFFER3 );
+ Create( XA_CUT_BUFFER4 );
+ Create( XA_CUT_BUFFER5 );
+ Create( XA_CUT_BUFFER6 );
+ Create( XA_CUT_BUFFER7 );
+
+#undef Create
+}
+
+/*
+ * Procedure to manage insert cursor visibility for editable text. It uses
+ * the value of ctx->insertPos and an implicit argument. In the event that
+ * position is immediately preceded by an eol graphic, then the insert cursor
+ * is displayed at the beginning of the next line.
+*/
+static void
+InsertCursor (w, state)
+Widget w;
+XawTextInsertState state;
+{
+ TextWidget ctx = (TextWidget)w;
+ Position x, y;
+ int line;
+
+ if (ctx->text.lt.lines < 1) return;
+
+ if ( LineAndXYForPosition(ctx, ctx->text.insertPos, &line, &x, &y) ) {
+ if (line < ctx->text.lt.lines)
+ y += (ctx->text.lt.info[line + 1].y - ctx->text.lt.info[line].y) + 1;
+ else
+ y += (ctx->text.lt.info[line].y - ctx->text.lt.info[line - 1].y) + 1;
+
+ if (ctx->text.display_caret)
+ XawTextSinkInsertCursor(ctx->text.sink, x, y, state);
+ }
+ ctx->text.ev_x = x;
+ ctx->text.ev_y = y;
+
+ /* Keep Input Method up to speed */
+
+#ifdef XAW_INTERNATIONALIZATION
+ if ( ctx->simple.international ) {
+ Arg list[1];
+
+ XtSetArg (list[0], XtNinsertPosition, ctx->text.insertPos);
+ _XawImSetValues (w, list, 1);
+ }
+#endif
+}
+
+/*
+ * Procedure to register a span of text that is no longer valid on the display
+ * It is used to avoid a number of small, and potentially overlapping, screen
+ * updates.
+*/
+
+void
+_XawTextNeedsUpdating(ctx, left, right)
+TextWidget ctx;
+XawTextPosition left, right;
+{
+ int i;
+ if (left < right) {
+ for (i = 0; i < ctx->text.numranges; i++) {
+ if (left <= ctx->text.updateTo[i] && right >= ctx->text.updateFrom[i]) {
+ ctx->text.updateFrom[i] = Min(left, ctx->text.updateFrom[i]);
+ ctx->text.updateTo[i] = Max(right, ctx->text.updateTo[i]);
+ return;
+ }
+ }
+ ctx->text.numranges++;
+ if (ctx->text.numranges > ctx->text.maxranges) {
+ ctx->text.maxranges = ctx->text.numranges;
+ i = ctx->text.maxranges * sizeof(XawTextPosition);
+ ctx->text.updateFrom = (XawTextPosition *)
+ XtRealloc((char *)ctx->text.updateFrom, (unsigned) i);
+ ctx->text.updateTo = (XawTextPosition *)
+ XtRealloc((char *)ctx->text.updateTo, (unsigned) i);
+ }
+ ctx->text.updateFrom[ctx->text.numranges - 1] = left;
+ ctx->text.updateTo[ctx->text.numranges - 1] = right;
+ }
+}
+
+/*
+ * Procedure to read a span of text in Ascii form. This is purely a hack and
+ * we probably need to add a function to sources to provide this functionality.
+ * [note: this is really a private procedure but is used in multiple modules].
+ */
+
+char *
+_XawTextGetText(ctx, left, right)
+TextWidget ctx;
+XawTextPosition left, right;
+{
+ char *result, *tempResult;
+ XawTextBlock text;
+ int bytes;
+
+ if (_XawTextFormat(ctx) == XawFmt8Bit)
+ bytes = sizeof(unsigned char);
+#ifdef XAW_INTERNATIONALIZATION
+ else if (_XawTextFormat(ctx) == XawFmtWide)
+ bytes = sizeof(wchar_t);
+#endif
+ else /* if there is another fomat, add here */
+ bytes = 1;
+
+ /* leave space for ZERO */
+ tempResult=result=XtMalloc( (unsigned)(((Cardinal)(right-left))+ONE )* bytes);
+ while (left < right) {
+ left = SrcRead(ctx->text.source, left, &text, (int)(right - left));
+ if (!text.length)
+ break;
+ memmove(tempResult, text.ptr, text.length * bytes);
+ tempResult += text.length * bytes;
+ }
+
+ if (bytes == sizeof(wchar_t))
+ *((wchar_t*)tempResult) = (wchar_t)0;
+ else
+ *tempResult = '\0';
+ return(result);
+}
+
+/* Like _XawTextGetText, but enforces ICCCM STRING type encoding. This
+routine is currently used to put just the ASCII chars in the selection into a
+cut buffer. */
+
+char *
+_XawTextGetSTRING(ctx, left, right)
+TextWidget ctx;
+XawTextPosition left, right;
+{
+ unsigned char *s;
+ unsigned char c;
+ long i, j, n;
+ wchar_t *ws, wc;
+
+ /* allow ESC in accordance with ICCCM */
+#ifdef XAW_INTERNATIONALIZATION
+ if (_XawTextFormat(ctx) == XawFmtWide) {
+ MultiSinkObject sink = (MultiSinkObject) ctx->text.sink;
+ ws = (wchar_t *)_XawTextGetText(ctx, left, right);
+ n = wcslen(ws);
+ for (j = 0, i = 0; j < n; j++) {
+ wc = ws[j];
+ if (XwcTextEscapement (sink->multi_sink.fontset, &wc, 1) ||
+ (wc == _Xaw_atowc(XawTAB)) || (wc == _Xaw_atowc(XawLF)) || (wc == _Xaw_atowc(XawESC)))
+ ws[i++] = wc;
+ }
+ ws[i] = (wchar_t)0;
+ return (char *)ws;
+ } else
+#endif
+ {
+ s = (unsigned char *)_XawTextGetText(ctx, left, right);
+ /* only HT and NL control chars are allowed, strip out others */
+ n = strlen((char *)s);
+ i = 0;
+ for (j = 0; j < n; j++) {
+ c = s[j];
+ if (((c >= 0x20) && c <= 0x7f) ||
+ (c >= 0xa0) || (c == XawTAB) || (c == XawLF) || (c == XawESC)) {
+ s[i] = c;
+ i++;
+ }
+ }
+ s[i] = 0;
+ return (char *)s;
+ }
+#undef ESC
+
+}
+
+/*
+ * This routine maps an x and y position in a window that is displaying text
+ * into the corresponding position in the source.
+ *
+ * NOTE: it is illegal to call this routine unless there is a valid line table!
+ */
+
+/*** figure out what line it is on ***/
+
+static XawTextPosition
+PositionForXY (ctx, x, y)
+TextWidget ctx;
+Position x,y;
+{
+ int fromx, line, width, height;
+ XawTextPosition position;
+
+ if (ctx->text.lt.lines == 0) return 0;
+
+ for (line = 0; line < ctx->text.lt.lines - 1; line++) {
+ if (y <= ctx->text.lt.info[line + 1].y)
+ break;
+ }
+ position = ctx->text.lt.info[line].position;
+ if (position >= ctx->text.lastPos)
+ return(ctx->text.lastPos);
+ fromx = (int) ctx->text.margin.left;
+ XawTextSinkFindPosition( ctx->text.sink, position, fromx, x - fromx,
+ FALSE, &position, &width, &height);
+ if (position > ctx->text.lastPos) return(ctx->text.lastPos);
+ if (position >= ctx->text.lt.info[line + 1].position)
+ position = SrcScan(ctx->text.source, ctx->text.lt.info[line + 1].position,
+ XawstPositions, XawsdLeft, 1, TRUE);
+ return(position);
+}
+
+/*
+ * This routine maps a source position in to the corresponding line number
+ * of the text that is displayed in the window.
+ *
+ * NOTE: It is illegal to call this routine unless there is a valid line table!
+ */
+
+static int
+LineForPosition (ctx, position)
+TextWidget ctx;
+XawTextPosition position;
+{
+ int line;
+
+ for (line = 0; line < ctx->text.lt.lines; line++)
+ if (position < ctx->text.lt.info[line + 1].position)
+ break;
+ return(line);
+}
+
+/*
+ * This routine maps a source position into the corresponding line number
+ * and the x, y coordinates of the text that is displayed in the window.
+ *
+ * NOTE: It is illegal to call this routine unless there is a valid line table!
+ */
+
+static Boolean
+LineAndXYForPosition (ctx, pos, line, x, y)
+TextWidget ctx;
+XawTextPosition pos;
+int *line;
+Position *x, *y;
+{
+ XawTextPosition linePos, endPos;
+ Boolean visible;
+ int realW, realH;
+
+ *line = 0;
+ *x = ctx->text.margin.left;
+ *y = ctx->text.margin.top;
+ if ((visible = IsPositionVisible(ctx, pos))) {
+ *line = LineForPosition(ctx, pos);
+ *y = ctx->text.lt.info[*line].y;
+ *x = ctx->text.margin.left;
+ linePos = ctx->text.lt.info[*line].position;
+ XawTextSinkFindDistance( ctx->text.sink, linePos,
+ *x, pos, &realW, &endPos, &realH);
+ *x += realW;
+ }
+ return(visible);
+}
+
+/*
+ * This routine builds a line table. It does this by starting at the
+ * specified position and measuring text to determine the staring position
+ * of each line to be displayed. It also determines and saves in the
+ * linetable all the required metrics for displaying a given line (e.g.
+ * x offset, y offset, line length, etc.).
+ */
+
+void
+#if NeedFunctionPrototypes
+_XawTextBuildLineTable (
+ TextWidget ctx,
+ XawTextPosition position,
+ _XtBoolean force_rebuild)
+#else
+_XawTextBuildLineTable (ctx, position, force_rebuild)
+ TextWidget ctx;
+ XawTextPosition position;
+ Boolean force_rebuild;
+#endif
+{
+ Dimension height = 0;
+ int lines = 0;
+ Cardinal size;
+
+ if ((int)ctx->core.height > VMargins(ctx)) {
+ height = ctx->core.height - VMargins(ctx);
+ lines = XawTextSinkMaxLines(ctx->text.sink, height);
+ }
+ size = sizeof(XawTextLineTableEntry) * (lines + 1);
+
+ if ( (lines != ctx->text.lt.lines) || (ctx->text.lt.info == NULL) ) {
+ ctx->text.lt.info = (XawTextLineTableEntry *) XtRealloc((char *) ctx->text.
+ lt.info, size);
+ ctx->text.lt.lines = lines;
+ force_rebuild = TRUE;
+ }
+
+ if ( force_rebuild || (position != ctx->text.lt.top) ) {
+ (void) bzero((char *) ctx->text.lt.info, size);
+ (void) _BuildLineTable(ctx, ctx->text.lt.top = position, zeroPosition, 0);
+ }
+}
+
+/*
+ * This assumes that the line table does not change size.
+ */
+
+static XawTextPosition
+_BuildLineTable(ctx, position, min_pos, line)
+TextWidget ctx;
+XawTextPosition position, min_pos;
+int line;
+{
+ XawTextLineTableEntry * lt = ctx->text.lt.info + line;
+ XawTextPosition endPos;
+ Position y;
+ int count, width, realW, realH;
+ Widget src = ctx->text.source;
+
+ if ( ((ctx->text.resize == XawtextResizeWidth) ||
+ (ctx->text.resize == XawtextResizeBoth) ) ||
+ (ctx->text.wrap == XawtextWrapNever) )
+ width = BIGNUM;
+ else
+ width = Max(0, ((int)ctx->core.width - (int)HMargins(ctx)));
+
+ y = ( (line == 0) ? ctx->text.margin.top : lt->y );
+
+ /* CONSTCOND */
+ while ( TRUE ) {
+ lt->y = y;
+ lt->position = position;
+
+ XawTextSinkFindPosition( ctx->text.sink, position, ctx->text.margin.left,
+ width, ctx->text.wrap == XawtextWrapWord,
+ &endPos, &realW, &realH);
+ lt->textWidth = realW;
+ y += realH;
+
+ if (ctx->text.wrap == XawtextWrapNever)
+ endPos = SrcScan(src, position, XawstEOL, XawsdRight, 1, TRUE);
+
+ if ( endPos == ctx->text.lastPos) { /* We have reached the end. */
+ if(SrcScan(src, position, XawstEOL, XawsdRight, 1, FALSE) == endPos)
+ break;
+ }
+
+ ++lt;
+ ++line;
+ if ( (line > ctx->text.lt.lines) ||
+ ((lt->position == (position = endPos)) && (position > min_pos)) )
+ return(position);
+ }
+
+/*
+ * If we are at the end of the buffer put two special lines in the table.
+ *
+ * a) Both have position > text.lastPos and lt->textWidth = 0.
+ * b) The first has a real height, and the second has a height that
+ * is the rest of the screen.
+ *
+ * I could fill in the rest of the table with valid heights and a large
+ * lastPos, but this method keeps the number of fill regions down to a
+ * minimum.
+ *
+ * One valid entry is needed at the end of the table so that the cursor
+ * does not jump off the bottom of the window.
+ */
+
+ for ( count = 0; count < 2 ; count++)
+ if (line++ < ctx->text.lt.lines) { /* make sure not to run of the end. */
+ (++lt)->y = (count == 0) ? y : ctx->core.height
+ - 2 * ((ThreeDWidget)ctx->text.threeD)->threeD.shadow_width;
+ lt->textWidth = 0;
+ lt->position = ctx->text.lastPos + 100;
+ }
+
+ if (line < ctx->text.lt.lines) /* Clear out rest of table. */
+ (void) bzero( (char *) (lt + 1),
+ (ctx->text.lt.lines - line) * sizeof(XawTextLineTableEntry) );
+
+ ctx->text.lt.info[ctx->text.lt.lines].position = lt->position;
+
+ return(endPos);
+}
+
+/* Function Name: GetWidestLine
+ * Description: Returns the width (in pixels) of the widest line that
+ * is currently visable.
+ * Arguments: ctx - the text widget.
+ * Returns: the width of the widest line.
+ *
+ * NOTE: This function requires a valid line table.
+ */
+
+static Dimension
+GetWidestLine(ctx)
+TextWidget ctx;
+{
+ int i;
+ Dimension widest;
+ XawTextLineTablePtr lt = &(ctx->text.lt);
+
+ for (i = 0, widest = 1 ; i < lt->lines ; i++)
+ if (widest < lt->info[i].textWidth)
+ widest = lt->info[i].textWidth;
+
+ return(widest);
+}
+
+static void
+CheckVBarScrolling(ctx)
+TextWidget ctx;
+{
+ float first, last;
+ Boolean temp = (ctx->text.vbar == NULL);
+
+ if (ctx->text.scroll_vert == XawtextScrollNever) return;
+
+ if ( (ctx->text.lastPos > 0) && (ctx->text.lt.lines > 0)) {
+ first = ctx->text.lt.top;
+ first /= (float) ctx->text.lastPos;
+ last = ctx->text.lt.info[ctx->text.lt.lines].position;
+ if ( ctx->text.lt.info[ctx->text.lt.lines].position < ctx->text.lastPos )
+ last /= (float) ctx->text.lastPos;
+ else
+ last = 1.0;
+
+ if (ctx->text.scroll_vert == XawtextScrollWhenNeeded) {
+ int line;
+ XawTextPosition last_pos;
+ Position y = ctx->core.height - ctx->text.margin.bottom;
+
+ if (ctx->text.hbar != NULL)
+ y -= (ctx->text.hbar->core.height +
+ 2 * ctx->text.hbar->core.border_width);
+
+ last_pos = PositionForXY(ctx, (Position) ctx->core.width, y);
+ line = LineForPosition(ctx, last_pos);
+
+ if ( (y < ctx->text.lt.info[line + 1].y) || ((last - first) < 1.0) )
+ CreateVScrollBar(ctx);
+ else
+ DestroyVScrollBar(ctx);
+ }
+
+ if (ctx->text.vbar != NULL)
+ XawScrollbarSetThumb(ctx->text.vbar, first, last - first);
+
+ if ( (ctx->text.vbar == NULL) != temp) {
+ _XawTextNeedsUpdating(ctx, zeroPosition, ctx->text.lastPos);
+ if (ctx->text.vbar == NULL)
+ _XawTextBuildLineTable (ctx, zeroPosition, FALSE);
+ }
+ }
+ else if (ctx->text.vbar != NULL)
+ if (ctx->text.scroll_vert == XawtextScrollWhenNeeded)
+ DestroyVScrollBar(ctx);
+ else if (ctx->text.scroll_vert == XawtextScrollAlways)
+ XawScrollbarSetThumb(ctx->text.vbar, 0.0, 1.0);
+}
+
+/*
+ * This routine is used by Text to notify an associated scrollbar of the
+ * correct metrics (position and shown fraction) for the text being currently
+ * displayed in the window.
+ */
+
+void
+_XawTextSetScrollBars(ctx)
+TextWidget ctx;
+{
+ float first, last, widest;
+ Boolean temp = (ctx->text.hbar == NULL);
+ Boolean vtemp = (ctx->text.vbar == NULL);
+ int s = ((ThreeDWidget)ctx->text.threeD)->threeD.shadow_width;
+
+ CheckVBarScrolling(ctx);
+
+ if (ctx->text.scroll_horiz == XawtextScrollNever) return;
+
+ if (ctx->text.vbar != NULL)
+ widest = (int)(ctx->core.width - ctx->text.vbar->core.width -
+ 2 * s - ctx->text.vbar->core.border_width);
+ else
+ widest = ctx->core.width - 2 * s;
+ widest /= (last = GetWidestLine(ctx));
+ if (ctx->text.scroll_horiz == XawtextScrollWhenNeeded)
+ if (widest < 1.0)
+ CreateHScrollBar(ctx);
+ else
+ DestroyHScrollBar(ctx);
+
+ if ( (ctx->text.hbar == NULL) != temp ) {
+ _XawTextBuildLineTable (ctx, ctx->text.lt.top, TRUE);
+ CheckVBarScrolling(ctx); /* Recheck need for vbar, now that we added
+ or removed the hbar.*/
+ }
+
+ if (ctx->text.hbar != NULL) {
+ first = ctx->text.r_margin.left - ctx->text.margin.left;
+ first /= last;
+ XawScrollbarSetThumb(ctx->text.hbar, first, widest);
+ }
+
+ if (((ctx->text.hbar == NULL) && (ctx->text.margin.left !=
+ ctx->text.r_margin.left)) ||
+ (ctx->text.vbar == NULL) != vtemp)
+ {
+ ctx->text.margin.left = ctx->text.r_margin.left;
+ _XawTextNeedsUpdating(ctx, zeroPosition, ctx->text.lastPos);
+ FlushUpdate(ctx);
+ }
+}
+
+/*
+ * The routine will scroll the displayed text by lines. If the arg is
+ * positive, move up; otherwise, move down. [note: this is really a private
+ * procedure but is used in multiple modules].
+ */
+
+void
+_XawTextVScroll(ctx, n)
+TextWidget ctx;
+int n;
+{
+ XawTextPosition top, target;
+ int y;
+ Arg list[1];
+ XawTextLineTable * lt = &(ctx->text.lt);
+ int s = ((ThreeDWidget)ctx->text.threeD)->threeD.shadow_width;
+
+ if (abs(n) > ctx->text.lt.lines)
+ n = (n > 0) ? ctx->text.lt.lines : -ctx->text.lt.lines;
+
+ if (n == 0) return;
+
+ if (n > 0) {
+ if ( IsValidLine(ctx, n) )
+ top = Min(lt->info[n].position, ctx->text.lastPos);
+ else
+ top = ctx->text.lastPos;
+
+ y = IsValidLine(ctx, n) ? lt->info[n].y : ctx->core.height - 2 * s;
+ _XawTextBuildLineTable(ctx, top, FALSE);
+ if (top >= ctx->text.lastPos)
+ DisplayTextWindow( (Widget) ctx);
+ else {
+ XCopyArea(XtDisplay(ctx), XtWindow(ctx), XtWindow(ctx), ctx->text.gc,
+ s, y, (int)ctx->core.width - 2 * s, (int)ctx->core.height - y - s,
+ s, ctx->text.margin.top);
+
+ PushCopyQueue(ctx, 0, (int) -y);
+ SinkClearToBG(ctx->text.sink,
+ (Position) s,
+ (Position) (ctx->text.margin.top + ctx->core.height - y - s),
+ (Dimension) ctx->core.width - 2 * s,
+ (Dimension) ctx->core.height - 2 * s);
+
+ if (n < lt->lines) n++; /* update descenders at bottom */
+ _XawTextNeedsUpdating(ctx, lt->info[lt->lines - n].position,
+ ctx->text.lastPos);
+ _XawTextSetScrollBars(ctx);
+ }
+ }
+ else {
+ XawTextPosition updateTo;
+ unsigned int height, clear_height;
+
+ n = -n;
+ target = lt->top;
+ top = SrcScan(ctx->text.source, target, XawstEOL,
+ XawsdLeft, n+1, FALSE);
+
+ _XawTextBuildLineTable(ctx, top, FALSE);
+ y = IsValidLine(ctx, n) ? lt->info[n].y : ctx->core.height - 2 * s;
+ updateTo = IsValidLine(ctx, n) ? lt->info[n].position : ctx->text.lastPos;
+ if (IsValidLine(ctx, lt->lines - n))
+ height = lt->info[lt->lines-n].y - ctx->text.margin.top;
+ else if (ctx->core.height - HMargins(ctx))
+ height = ctx->core.height - HMargins(ctx);
+ else
+ height = 0;
+ if (y > (int) ctx->text.margin.top)
+ clear_height = y - ctx->text.margin.top;
+ else
+ clear_height = 0;
+
+ if ( updateTo == target ) {
+ XCopyArea(XtDisplay(ctx), XtWindow(ctx), XtWindow(ctx), ctx->text.gc,
+ s, ctx->text.margin.top, (int) ctx->core.width - 2 * s,
+ height, s, y);
+ PushCopyQueue(ctx, 0, (int) y);
+ SinkClearToBG(ctx->text.sink, (Position) s, ctx->text.margin.top,
+ (Dimension) ctx->core.width - 2 * s, (Dimension) clear_height);
+
+ _XawTextNeedsUpdating(ctx, lt->info[0].position, updateTo);
+ _XawTextSetScrollBars(ctx);
+ }
+ else if (lt->top != target)
+ DisplayTextWindow((Widget)ctx);
+ }
+ XtSetArg (list[0], XtNinsertPosition, ctx->text.lt.top+ctx->text.lt.lines);
+#ifdef XAW_INTERNATIONALIZATION
+ _XawImSetValues ((Widget) ctx, list, 1);
+#endif
+
+ _ShadowSurroundedBox((Widget)ctx, (ThreeDWidget)ctx->text.threeD,
+ 0, 0, ctx->core.width, ctx->core.height,
+ ((ThreeDWidget)ctx->text.threeD)->threeD.relief, False);
+}
+
+/*ARGSUSED*/
+static void
+HScroll(w, closure, callData)
+Widget w;
+XtPointer closure; /* TextWidget */
+XtPointer callData; /* #pixels */
+{
+ TextWidget ctx = (TextWidget) closure;
+ Widget tw = (Widget) ctx;
+ Position old_left, pixels = (Position)(int) callData;
+ XRectangle rect, t_rect;
+ int s = ((ThreeDWidget)ctx->text.threeD)->threeD.shadow_width;
+
+ _XawTextPrepareToUpdate(ctx);
+
+ old_left = ctx->text.margin.left;
+ ctx->text.margin.left -= pixels;
+ if (ctx->text.margin.left > ctx->text.r_margin.left) {
+ ctx->text.margin.left = ctx->text.r_margin.left;
+ pixels = old_left - ctx->text.margin.left;
+ }
+
+ if (pixels > 0) {
+ rect.width = (unsigned short) pixels + ctx->text.margin.right;
+ rect.x = (short) ctx->core.width - (short) rect.width;
+ rect.y = (short) ctx->text.margin.top;
+ rect.height = (unsigned short) ctx->core.height - rect.y - 2 * s;
+
+ XCopyArea(XtDisplay(tw), XtWindow(tw), XtWindow(tw), ctx->text.gc,
+ pixels + s, (int) rect.y,
+ (unsigned int) rect.x, (unsigned int) ctx->core.height - 2 * s,
+ s, (int) rect.y);
+
+ PushCopyQueue(ctx, (int) -pixels, 0);
+ }
+ else if (pixels < 0) {
+ rect.x = s;
+
+ if (ctx->text.vbar != NULL)
+ rect.x += (short) (ctx->text.vbar->core.width +
+ ctx->text.vbar->core.border_width);
+
+ rect.width = (Position) - pixels;
+ rect.y = ctx->text.margin.top;
+ rect.height = ctx->core.height - rect.y - 2 * s;
+
+ XCopyArea(XtDisplay(tw), XtWindow(tw), XtWindow(tw), ctx->text.gc,
+ (int) rect.x, (int) rect.y,
+ (unsigned int) ctx->core.width - rect.width - 2 * s,
+ (unsigned int) rect.height,
+ (int) rect.x + rect.width, (int) rect.y);
+
+ PushCopyQueue(ctx, (int) rect.width, 0);
+
+/*
+ * Redraw the line overflow marks.
+ */
+
+ t_rect.x = ctx->core.width - ctx->text.margin.right - s;
+ t_rect.width = ctx->text.margin.right;
+ t_rect.y = rect.y;
+ t_rect.height = rect.height - 2 * s;
+
+ SinkClearToBG(ctx->text.sink, (Position) t_rect.x, (Position) t_rect.y,
+ (Dimension) t_rect.width, (Dimension) t_rect.height);
+
+ UpdateTextInRectangle(ctx, &t_rect);
+ }
+
+/*
+ * Put in the text that just became visible.
+ */
+
+ if ( pixels != 0 ) {
+ SinkClearToBG(ctx->text.sink, (Position) rect.x, (Position) rect.y,
+ (Dimension) rect.width, (Dimension) rect.height);
+
+ UpdateTextInRectangle(ctx, &rect);
+ }
+ _XawTextExecuteUpdate(ctx);
+ _XawTextSetScrollBars(ctx);
+}
+
+/*ARGSUSED*/
+static void
+HJump(w, closure, callData)
+Widget w;
+XtPointer closure, callData; /* closure = TextWidget, callData = percent. */
+{
+ TextWidget ctx = (TextWidget) closure;
+ float * percent = (float *) callData;
+ Position new_left, old_left = ctx->text.margin.left;
+
+ long move; /*difference of Positions can be bigger than Position; lint err */
+
+ new_left = ctx->text.r_margin.left;
+ new_left -= (Position) (*percent * GetWidestLine(ctx));
+ move = old_left - new_left;
+
+ if (abs(move) < (int)ctx->core.width) {
+ HScroll(w, (XtPointer) ctx, (XtPointer) move);
+ return;
+ }
+ _XawTextPrepareToUpdate(ctx);
+ ctx->text.margin.left = new_left;
+ if (XtIsRealized((Widget) ctx)) DisplayTextWindow((Widget) ctx);
+ _XawTextExecuteUpdate(ctx);
+}
+
+/* Function Name: UpdateTextInLine
+ * Description: Updates some text in a given line.
+ * Arguments: ctx - the text widget.
+ * line - the line number (in the line table) of this line.
+ * left, right - left and right pixel offsets of the
+ * area to update.
+ * Returns: none.
+ */
+
+static void
+UpdateTextInLine(ctx, line, left, right)
+TextWidget ctx;
+int line;
+Position left, right;
+{
+ XawTextPosition pos1, pos2;
+ int width, height, local_left, local_width;
+ XawTextLineTableEntry * lt = ctx->text.lt.info + line;
+
+ if ( ((int)(lt->textWidth + ctx->text.margin.left) < left) ||
+ ( ctx->text.margin.left > right ) )
+ return; /* no need to update. */
+
+ local_width = left - ctx->text.margin.left;
+ XawTextSinkFindPosition(ctx->text.sink, lt->position,
+ (int) ctx->text.margin.left,
+ local_width, FALSE, &pos1, &width, &height);
+
+ if (right >= (Position) lt->textWidth - ctx->text.margin.left)
+ if ( (IsValidLine(ctx, line + 1)) &&
+ (ctx->text.lt.info[line + 1].position <= ctx->text.lastPos) )
+ pos2 = SrcScan( ctx->text.source, (lt + 1)->position, XawstPositions,
+ XawsdLeft, 1, TRUE);
+ else
+ pos2 = GETLASTPOS;
+ else {
+ XawTextPosition t_pos;
+
+ local_left = ctx->text.margin.left + width;
+ local_width = right - local_left;
+ XawTextSinkFindPosition(ctx->text.sink, pos1, local_left,
+ local_width, FALSE, &pos2, &width, &height);
+
+ t_pos = SrcScan( ctx->text.source, pos2,
+ XawstPositions, XawsdRight, 1, TRUE);
+ if (t_pos < (lt + 1)->position)
+ pos2 = t_pos;
+ }
+
+ _XawTextNeedsUpdating(ctx, pos1, pos2);
+}
+
+/*
+ * The routine will scroll the displayed text by pixels. If the calldata is
+ * positive, move up; otherwise, move down.
+ */
+
+/*ARGSUSED*/
+static void
+VScroll(w, closure, callData)
+Widget w;
+XtPointer closure; /* TextWidget */
+XtPointer callData; /* #pixels */
+{
+ TextWidget ctx = (TextWidget)closure;
+ int height, nlines, lines = (int) callData;
+
+ height = ctx->core.height - VMargins(ctx);
+ if (height < 1)
+ height = 1;
+ nlines = (int) (lines * (int) ctx->text.lt.lines) / height;
+#ifdef XAW_ARROW_SCROLLBARS
+ if (nlines == 0 && lines != 0)
+ nlines = lines > 0 ? 1 : -1;
+#endif
+ _XawTextPrepareToUpdate(ctx);
+ _XawTextVScroll(ctx, nlines);
+ _XawTextExecuteUpdate(ctx);
+}
+
+/*
+ * The routine "thumbs" the displayed text. Thumbing means reposition the
+ * displayed view of the source to a new position determined by a fraction
+ * of the way from beginning to end. Ideally, this should be determined by
+ * the number of displayable lines in the source. This routine does it as a
+ * fraction of the first position and last position and then normalizes to
+ * the start of the line containing the position.
+ *
+ * BUG/deficiency: The normalize to line portion of this routine will
+ * cause thumbing to always position to the start of the source.
+ */
+
+/*ARGSUSED*/
+static void
+VJump(w, closure, callData)
+Widget w;
+XtPointer closure, callData; /* closuer = TextWidget, callData = percent. */
+{
+ float * percent = (float *) callData;
+ TextWidget ctx = (TextWidget)closure;
+ XawTextPosition position, old_top, old_bot;
+ XawTextLineTable * lt = &(ctx->text.lt);
+
+ _XawTextPrepareToUpdate(ctx);
+ old_top = lt->top;
+ if ( (lt->lines > 0) && (IsValidLine(ctx, lt->lines - 1)) )
+ old_bot = lt->info[lt->lines - 1].position;
+ else
+ old_bot = ctx->text.lastPos;
+
+ position = (long) (*percent * (float) ctx->text.lastPos);
+ position= SrcScan(ctx->text.source, position, XawstEOL, XawsdLeft, 1, FALSE);
+ if ( (position >= old_top) && (position <= old_bot) ) {
+ int line = 0;
+ for (;(line < lt->lines) && (position > lt->info[line].position) ; line++);
+ _XawTextVScroll(ctx, line);
+ }
+ else {
+ XawTextPosition new_bot;
+ _XawTextBuildLineTable(ctx, position, FALSE);
+ new_bot = IsValidLine(ctx, lt->lines-1) ? lt->info[lt->lines-1].position
+ : ctx->text.lastPos;
+
+ if ((old_top >= lt->top) && (old_top <= new_bot)) {
+ int line = 0;
+ for (;(line < lt->lines) && (old_top > lt->info[line].position); line++);
+ _XawTextBuildLineTable(ctx, old_top, FALSE);
+ _XawTextVScroll(ctx, -line);
+ }
+ else
+ DisplayTextWindow( (Widget) ctx);
+ }
+ _XawTextExecuteUpdate(ctx);
+}
+
+static Boolean
+MatchSelection(selection, s)
+Atom selection;
+XawTextSelection *s;
+{
+ Atom *match;
+ int count;
+
+ for (count = 0, match = s->selections; count < s->atom_count; match++, count++)
+ if (*match == selection)
+ return True;
+ return False;
+}
+
+static Boolean
+ConvertSelection(w, selection, target, type, value, length, format)
+Widget w;
+Atom *selection, *target, *type;
+XtPointer *value;
+unsigned long *length;
+int *format;
+{
+ Display* d = XtDisplay(w);
+ TextWidget ctx = (TextWidget)w;
+ Widget src = ctx->text.source;
+ XawTextEditType edit_mode;
+ Arg args[1];
+
+ XawTextSelectionSalt *salt = NULL;
+ XawTextSelection *s;
+
+ if (*target == XA_TARGETS(d)) {
+ Atom* targetP, * std_targets;
+ unsigned long std_length;
+
+ if ( SrcCvtSel(src, selection, target, type, value, length, format) )
+ return True;
+
+ XmuConvertStandardSelection(w, ctx->text.time, selection,
+ target, type, (XPointer*)&std_targets,
+ &std_length, format);
+
+ *value = XtMalloc((unsigned) sizeof(Atom)*(std_length + 7));
+ targetP = *(Atom**)value;
+ *length = std_length + 6;
+ *targetP++ = XA_STRING;
+ *targetP++ = XA_TEXT(d);
+ *targetP++ = XA_COMPOUND_TEXT(d);
+ *targetP++ = XA_LENGTH(d);
+ *targetP++ = XA_LIST_LENGTH(d);
+ *targetP++ = XA_CHARACTER_POSITION(d);
+
+ XtSetArg(args[0], XtNeditType,&edit_mode);
+ XtGetValues(src, args, ONE);
+
+ if (edit_mode == XawtextEdit) {
+ *targetP++ = XA_DELETE(d);
+ (*length)++;
+ }
+ (void) memmove((char*)targetP, (char*)std_targets, sizeof(Atom)*std_length);
+ XtFree((char*)std_targets);
+ *type = XA_ATOM;
+ *format = 32;
+ return True;
+ }
+
+ if ( SrcCvtSel(src, selection, target, type, value, length, format) )
+ return True;
+
+ if (MatchSelection (*selection, &ctx->text.s))
+ s = &ctx->text.s;
+ else
+ {
+ for (salt = ctx->text.salt; salt; salt = salt->next)
+ if (MatchSelection (*selection, &salt->s))
+ break;
+ if (!salt)
+ return False;
+ s = &salt->s;
+ }
+ if (*target == XA_STRING ||
+ *target == XA_TEXT(d) ||
+ *target == XA_COMPOUND_TEXT(d)) {
+ if (*target == XA_TEXT(d)) {
+#ifdef XAW_INTERNATIONALIZATION
+ if (_XawTextFormat(ctx) == XawFmtWide)
+ *type = XA_COMPOUND_TEXT(d);
+ else
+#endif
+ *type = XA_STRING;
+ } else {
+ *type = *target;
+ }
+ /*
+ * If salt is True, the salt->contents stores CT string,
+ * its length is measured in bytes.
+ * Refer to _XawTextSaltAwaySelection().
+ *
+ * by Li Yuhong, Mar. 20, 1991.
+ */
+ if (!salt) {
+ *value = _XawTextGetSTRING(ctx, s->left, s->right);
+#ifdef XAW_INTERNATIONALIZATION
+ if (_XawTextFormat(ctx) == XawFmtWide) {
+ XTextProperty textprop;
+ if (XwcTextListToTextProperty(d, (wchar_t **)value, 1,
+ XCompoundTextStyle, &textprop)
+ < Success) {
+ XtFree(*value);
+ return False;
+ }
+ XtFree(*value);
+ *value = (XtPointer)textprop.value;
+ *length = textprop.nitems;
+ } else
+#endif
+ {
+ *length = strlen(*value);
+ }
+ } else {
+ *value = XtMalloc((salt->length + 1) * sizeof(unsigned char));
+ strcpy (*value, salt->contents);
+ *length = salt->length;
+ }
+#ifdef XAW_INTERNATIONALIZATION
+ if (_XawTextFormat(ctx) == XawFmtWide && *type == XA_STRING) {
+ XTextProperty textprop;
+ wchar_t **wlist;
+ int count;
+ textprop.encoding = XA_COMPOUND_TEXT(d);
+ textprop.value = (unsigned char *)*value;
+ textprop.nitems = strlen(*value);
+ textprop.format = 8;
+ if (XwcTextPropertyToTextList(d, &textprop, (wchar_t ***)&wlist, &count)
+ < Success) {
+ XtFree(*value);
+ return False;
+ }
+ XtFree(*value);
+ if (XwcTextListToTextProperty( d, (wchar_t **)wlist, 1,
+ XStringStyle, &textprop) < Success) {
+ XwcFreeStringList( (wchar_t**) wlist );
+ return False;
+ }
+ *value = (XtPointer) textprop.value;
+ *length = textprop.nitems;
+ XwcFreeStringList( (wchar_t**) wlist );
+ }
+#endif
+ *format = 8;
+ return True;
+ }
+
+ if ( (*target == XA_LIST_LENGTH(d)) || (*target == XA_LENGTH(d)) ) {
+ long * temp;
+
+ temp = (long *) XtMalloc( (unsigned) sizeof(long) );
+ if (*target == XA_LIST_LENGTH(d))
+ *temp = 1L;
+ else /* *target == XA_LENGTH(d) */
+ *temp = (long) (s->right - s->left);
+
+ *value = (XPointer) temp;
+ *type = XA_INTEGER;
+ *length = 1L;
+ *format = 32;
+ return True;
+ }
+
+ if (*target == XA_CHARACTER_POSITION(d)) {
+ long * temp;
+
+ temp = (long *) XtMalloc( (unsigned)( 2 * sizeof(long) ) );
+ temp[0] = (long) (s->left + 1);
+ temp[1] = s->right;
+ *value = (XPointer) temp;
+ *type = XA_SPAN(d);
+ *length = 2L;
+ *format = 32;
+ return True;
+ }
+
+ if (*target == XA_DELETE(d)) {
+ void _XawTextZapSelection(); /* From TextAction.c */
+
+ if (!salt)
+ _XawTextZapSelection( ctx, (XEvent *) NULL, TRUE);
+ *value = NULL;
+ *type = XA_NULL(d);
+ *length = 0;
+ *format = 32;
+ return True;
+ }
+
+ if (XmuConvertStandardSelection(w, ctx->text.time, selection, target, type,
+ (XPointer *)value, length, format))
+ return True;
+
+ /* else */
+ return False;
+}
+
+/* Function Name: GetCutBuffferNumber
+ * Description: Returns the number of the cut buffer.
+ * Arguments: atom - the atom to check.
+ * Returns: the number of the cut buffer representing this atom or
+ * NOT_A_CUT_BUFFER.
+ */
+
+#define NOT_A_CUT_BUFFER -1
+
+static int
+GetCutBufferNumber(atom)
+Atom atom;
+{
+ if (atom == XA_CUT_BUFFER0) return(0);
+ if (atom == XA_CUT_BUFFER1) return(1);
+ if (atom == XA_CUT_BUFFER2) return(2);
+ if (atom == XA_CUT_BUFFER3) return(3);
+ if (atom == XA_CUT_BUFFER4) return(4);
+ if (atom == XA_CUT_BUFFER5) return(5);
+ if (atom == XA_CUT_BUFFER6) return(6);
+ if (atom == XA_CUT_BUFFER7) return(7);
+ return(NOT_A_CUT_BUFFER);
+}
+
+static void
+LoseSelection(w, selection)
+Widget w;
+Atom *selection;
+{
+ TextWidget ctx = (TextWidget) w;
+ Atom* atomP;
+ int i;
+ XawTextSelectionSalt *salt, *prevSalt, *nextSalt;
+
+ _XawTextPrepareToUpdate(ctx);
+
+ atomP = ctx->text.s.selections;
+ for (i = 0 ; i < ctx->text.s.atom_count; i++, atomP++)
+ if ( (*selection == *atomP) ||
+ (GetCutBufferNumber(*atomP) != NOT_A_CUT_BUFFER) )/* is a cut buffer */
+ *atomP = (Atom)0;
+
+ while (ctx->text.s.atom_count &&
+ ctx->text.s.selections[ctx->text.s.atom_count-1] == 0)
+ ctx->text.s.atom_count--;
+
+/*
+ * Must walk the selection list in opposite order from UnsetSelection.
+ */
+
+ atomP = ctx->text.s.selections;
+ for (i = 0 ; i < ctx->text.s.atom_count; i++, atomP++)
+ if (*atomP == (Atom)0) {
+ *atomP = ctx->text.s.selections[--ctx->text.s.atom_count];
+ while (ctx->text.s.atom_count &&
+ ctx->text.s.selections[ctx->text.s.atom_count-1] == 0)
+ ctx->text.s.atom_count--;
+ }
+
+ if (ctx->text.s.atom_count == 0)
+ ModifySelection(ctx, ctx->text.insertPos, ctx->text.insertPos);
+
+ if (ctx->text.old_insert >= 0) /* Update in progress. */
+ _XawTextExecuteUpdate(ctx);
+
+ prevSalt = 0;
+ for (salt = ctx->text.salt; salt; salt = nextSalt)
+ {
+ atomP = salt->s.selections;
+ nextSalt = salt->next;
+ for (i = 0 ; i < salt->s.atom_count; i++, atomP++)
+ if (*selection == *atomP)
+ *atomP = (Atom)0;
+
+ while (salt->s.atom_count &&
+ salt->s.selections[salt->s.atom_count-1] == 0)
+ {
+ salt->s.atom_count--;
+ }
+
+ /*
+ * Must walk the selection list in opposite order from UnsetSelection.
+ */
+
+ atomP = salt->s.selections;
+ for (i = 0 ; i < salt->s.atom_count; i++, atomP++)
+ if (*atomP == (Atom)0)
+ {
+ *atomP = salt->s.selections[--salt->s.atom_count];
+ while (salt->s.atom_count &&
+ salt->s.selections[salt->s.atom_count-1] == 0)
+ salt->s.atom_count--;
+ }
+ if (salt->s.atom_count == 0)
+ {
+ XtFree ((char *) salt->s.selections);
+ XtFree (salt->contents);
+ if (prevSalt)
+ prevSalt->next = nextSalt;
+ else
+ ctx->text.salt = nextSalt;
+ XtFree ((char *) salt);
+ }
+ else
+ prevSalt = salt;
+ }
+}
+
+void
+_XawTextSaltAwaySelection (ctx, selections, num_atoms)
+TextWidget ctx;
+Atom* selections;
+int num_atoms;
+{
+ XawTextSelectionSalt *salt;
+ int i, j;
+
+ for (i = 0; i < num_atoms; i++)
+ LoseSelection ((Widget) ctx, selections + i);
+ if (num_atoms == 0)
+ return;
+ salt = (XawTextSelectionSalt *)
+ XtMalloc( (unsigned) sizeof(XawTextSelectionSalt) );
+ if (!salt)
+ return;
+ salt->s.selections = (Atom *)
+ XtMalloc( (unsigned) ( num_atoms * sizeof (Atom) ) );
+ if (!salt->s.selections)
+ {
+ XtFree ((char *) salt);
+ return;
+ }
+ salt->s.left = ctx->text.s.left;
+ salt->s.right = ctx->text.s.right;
+ salt->s.type = ctx->text.s.type;
+ salt->contents = _XawTextGetSTRING(ctx, ctx->text.s.left, ctx->text.s.right);
+#ifdef XAW_INTERNATIONALIZATION
+ if (_XawTextFormat(ctx) == XawFmtWide) {
+ XTextProperty textprop;
+ if (XwcTextListToTextProperty(XtDisplay((Widget)ctx),
+ (wchar_t**)(&(salt->contents)), 1, XCompoundTextStyle,
+ &textprop) < Success) {
+ XtFree(salt->contents);
+ salt->length = 0;
+ return;
+ }
+ XtFree(salt->contents);
+ salt->contents = (char *)textprop.value;
+ salt->length = textprop.nitems;
+ } else
+#endif
+ salt->length = strlen (salt->contents);
+ salt->next = ctx->text.salt;
+ ctx->text.salt = salt;
+ j = 0;
+ for (i = 0; i < num_atoms; i++)
+ {
+ if (GetCutBufferNumber (selections[i]) == NOT_A_CUT_BUFFER)
+ {
+ salt->s.selections[j++] = selections[i];
+ XtOwnSelection ((Widget) ctx, selections[i], ctx->text.time,
+ ConvertSelection, LoseSelection, (XtSelectionDoneProc)NULL);
+ }
+ }
+ salt->s.atom_count = j;
+}
+
+static void
+_SetSelection(ctx, left, right, selections, count)
+TextWidget ctx;
+XawTextPosition left, right;
+Atom *selections;
+Cardinal count;
+{
+ XawTextPosition pos;
+
+ if (left < ctx->text.s.left) {
+ pos = Min(right, ctx->text.s.left);
+ _XawTextNeedsUpdating(ctx, left, pos);
+ }
+ if (left > ctx->text.s.left) {
+ pos = Min(left, ctx->text.s.right);
+ _XawTextNeedsUpdating(ctx, ctx->text.s.left, pos);
+ }
+ if (right < ctx->text.s.right) {
+ pos = Max(right, ctx->text.s.left);
+ _XawTextNeedsUpdating(ctx, pos, ctx->text.s.right);
+ }
+ if (right > ctx->text.s.right) {
+ pos = Max(left, ctx->text.s.right);
+ _XawTextNeedsUpdating(ctx, pos, right);
+ }
+
+ ctx->text.s.left = left;
+ ctx->text.s.right = right;
+
+ SrcSetSelection(ctx->text.source, left, right,
+ (count == 0) ? None : selections[0]);
+
+ if (left < right) {
+ Widget w = (Widget) ctx;
+ int buffer;
+
+ while (count) {
+ Atom selection = selections[--count];
+
+ if ((buffer = GetCutBufferNumber(selection)) != NOT_A_CUT_BUFFER) {
+
+ unsigned char *ptr, *tptr;
+ unsigned int amount, max_len = MAX_CUT_LEN(XtDisplay(w));
+ unsigned long len;
+
+ tptr= ptr= (unsigned char *) _XawTextGetSTRING(ctx, ctx->text.s.left,
+ ctx->text.s.right);
+#ifdef XAW_INTERNATIONALIZATION
+ if (_XawTextFormat(ctx) == XawFmtWide) {
+ /*
+ * Only XA_STRING(Latin 1) is allowed in CUT_BUFFER,
+ * so we get it from wchar string, then free the wchar string.
+ */
+ XTextProperty textprop;
+ if (XwcTextListToTextProperty(XtDisplay(w), (wchar_t**)&ptr, 1,
+ XStringStyle, &textprop) < Success) {
+ XtFree((char *)ptr);
+ return;
+ }
+ XtFree((char *)ptr);
+ tptr = ptr = textprop.value;
+ }
+#endif
+ if (buffer == 0) {
+ _CreateCutBuffers(XtDisplay(w));
+ XRotateBuffers(XtDisplay(w), 1);
+ }
+ amount = Min ( (len = strlen((char *)ptr)), max_len);
+ XChangeProperty(XtDisplay(w), RootWindow(XtDisplay(w), 0), selection,
+ XA_STRING, 8, PropModeReplace, ptr, amount);
+
+ while (len > max_len) {
+ len -= max_len;
+ tptr += max_len;
+ amount = Min (len, max_len);
+ XChangeProperty(XtDisplay(w), RootWindow(XtDisplay(w), 0),
+ selection, XA_STRING, 8, PropModeAppend,
+ tptr, amount);
+ }
+ XtFree ((char *)ptr);
+ }
+ else /* This is a real selection */
+ XtOwnSelection(w, selection, ctx->text.time, ConvertSelection,
+ LoseSelection, (XtSelectionDoneProc)NULL);
+ }
+ }
+ else
+ XawTextUnsetSelection((Widget)ctx);
+}
+
+/*
+ * This internal routine deletes the text from pos1 to pos2 in a source and
+ * then inserts, at pos1, the text that was passed. As a side effect it
+ * "invalidates" that portion of the displayed text (if any).
+ *
+ * NOTE: It is illegal to call this routine unless there is a valid line table!
+ */
+
+int
+_XawTextReplace (ctx, pos1, pos2, text)
+TextWidget ctx;
+XawTextPosition pos1, pos2;
+XawTextBlock *text;
+{
+ int i, line1, delta, error;
+ XawTextPosition updateFrom, updateTo;
+ Widget src = ctx->text.source;
+ XawTextEditType edit_mode;
+ Arg args[1];
+ Boolean tmp = ctx->text.update_disabled;
+
+ ctx->text.update_disabled = True; /* No redisplay during replacement. */
+
+/*
+ * The insertPos may not always be set to the right spot in XawtextAppend
+ */
+
+ XtSetArg(args[0], XtNeditType, &edit_mode);
+ XtGetValues(src, args, ONE);
+
+ if ((pos1 == ctx->text.insertPos) && (edit_mode == XawtextAppend)) {
+ ctx->text.insertPos = ctx->text.lastPos;
+ pos2 = SrcScan(src, ctx->text.insertPos, XawstPositions, XawsdRight,
+ (int)(ctx->text.insertPos - pos1), (Boolean)TRUE);
+ pos1 = ctx->text.insertPos;
+ if ( (pos1 == pos2) && (text->length == 0) ) {
+ ctx->text.update_disabled = FALSE; /* rearm redisplay. */
+ return( XawEditError );
+ }
+ }
+
+ updateFrom = SrcScan(src, pos1, XawstWhiteSpace, XawsdLeft, 1, FALSE);
+ updateFrom = Max(updateFrom, ctx->text.lt.top);
+
+ line1 = LineForPosition(ctx, updateFrom);
+ if ( (error = SrcReplace(src, pos1, pos2, text)) != 0) {
+ ctx->text.update_disabled = tmp; /* restore redisplay */
+ return(error);
+ }
+
+ XawTextUnsetSelection((Widget)ctx);
+
+ ctx->text.lastPos = GETLASTPOS;
+ if (ctx->text.lt.top >= ctx->text.lastPos) {
+ _XawTextBuildLineTable(ctx, ctx->text.lastPos, FALSE);
+ ClearWindow( (Widget) ctx);
+ ctx->text.update_disabled = tmp; /* restore redisplay */
+ return(0); /* Things are fine. */
+ }
+
+ ctx->text.single_char = (text->length <= 1 && pos2 - pos1 <= 1);
+
+ delta = text->length - (pos2 - pos1);
+
+ if (delta < ctx->text.lastPos) {
+ for (pos2 += delta, i = 0; i < ctx->text.numranges; i++) {
+ if (ctx->text.updateFrom[i] > pos1)
+ ctx->text.updateFrom[i] += delta;
+ if (ctx->text.updateTo[i] >= pos1)
+ ctx->text.updateTo[i] += delta;
+ }
+ }
+
+ /*
+ * fixup all current line table entries to reflect edit.
+ * %%% it is not legal to do arithmetic on positions.
+ * using Scan would be more proper.
+ */
+ if (delta != 0) {
+ XawTextLineTableEntry *lineP;
+ i = LineForPosition(ctx, pos1) + 1;
+ for (lineP = ctx->text.lt.info + i; i <= ctx->text.lt.lines; i++, lineP++)
+ lineP->position += delta;
+ }
+
+ /*
+ * Now process the line table and fixup in case edits caused
+ * changes in line breaks. If we are breaking on word boundaries,
+ * this code checks for moving words to and from lines.
+ */
+
+ if (IsPositionVisible(ctx, updateFrom)) {
+ updateTo = _BuildLineTable(ctx,
+ ctx->text.lt.info[line1].position, pos1, line1);
+ _XawTextNeedsUpdating(ctx, updateFrom, updateTo);
+ }
+
+ ctx->text.update_disabled = tmp; /* restore redisplay */
+ return(0); /* Things are fine. */
+}
+
+/*
+ * This routine will display text between two arbitrary source positions.
+ * In the event that this span contains highlighted text for the selection,
+ * only that portion will be displayed highlighted.
+ *
+ * NOTE: it is illegal to call this routine unless there
+ * is a valid line table!
+ */
+
+static void
+DisplayText(w, pos1, pos2)
+Widget w;
+XawTextPosition pos1, pos2;
+{
+ TextWidget ctx = (TextWidget)w;
+ Position x, y;
+ int height, line, i, lastPos = ctx->text.lastPos;
+ XawTextPosition startPos, endPos;
+ Boolean clear_eol, done_painting;
+ Dimension s = ((ThreeDWidget)ctx->text.threeD)->threeD.shadow_width;
+
+ pos1 = (pos1 < ctx->text.lt.top) ? ctx->text.lt.top : pos1;
+ pos2 = FindGoodPosition(ctx, pos2);
+ if ( (pos1 >= pos2) || !LineAndXYForPosition(ctx, pos1, &line, &x, &y) )
+ return; /* line not visible, or pos1 >= pos2. */
+
+ for ( startPos = pos1, i = line; IsValidLine(ctx, i) &&
+ (i < ctx->text.lt.lines) ; i++) {
+
+
+ if ( (endPos = ctx->text.lt.info[i + 1].position) > pos2 ) {
+ clear_eol = ((endPos = pos2) >= lastPos);
+ done_painting = (!clear_eol || ctx->text.single_char);
+ }
+ else {
+ clear_eol = TRUE;
+ done_painting = FALSE;
+ }
+
+ height = ctx->text.lt.info[i + 1].y - ctx->text.lt.info[i].y - s + 1;
+
+ if ( (endPos > startPos) ) {
+
+ /* note to self: _ShadowSurroundedBox() hacks are in here */
+
+ if ( (x == (Position) ctx->text.margin.left) && (x > 0) )
+ {
+ SinkClearToBG (ctx->text.sink,
+ (Position) s, y,
+ (Dimension) ctx->text.margin.left, (Dimension)height);
+ _ShadowSurroundedBox((Widget)ctx, (ThreeDWidget)ctx->text.threeD,
+ 0, 0, ctx->core.width, ctx->core.height,
+ ((ThreeDWidget)ctx->text.threeD)->threeD.relief,
+ False);
+ }
+
+ if ( (startPos >= ctx->text.s.right) || (endPos <= ctx->text.s.left) )
+ XawTextSinkDisplayText(ctx->text.sink, x, y, startPos, endPos, FALSE);
+ else if ((startPos >= ctx->text.s.left) && (endPos <= ctx->text.s.right))
+ XawTextSinkDisplayText(ctx->text.sink, x, y, startPos, endPos, TRUE);
+ else {
+ DisplayText(w, startPos, ctx->text.s.left);
+ DisplayText(w, Max(startPos, ctx->text.s.left),
+ Min(endPos, ctx->text.s.right));
+ DisplayText(w, ctx->text.s.right, endPos);
+ }
+ }
+ startPos = endPos;
+ if (clear_eol) {
+ Position myx = ctx->text.lt.info[i].textWidth + ctx->text.margin.left;
+
+ SinkClearToBG(ctx->text.sink,
+ (Position) myx,
+ (Position) y, w->core.width - myx/* - 2 * s*/,
+ (Dimension) height);
+ _ShadowSurroundedBox((Widget)ctx, (ThreeDWidget)ctx->text.threeD,
+ 0, 0, ctx->core.width, ctx->core.height,
+ ((ThreeDWidget)ctx->text.threeD)->threeD.relief,
+ False);
+
+ /*
+ * We only get here if single character is true, and we need
+ * to clear to the end of the screen. We know that since there
+ * was only one character deleted that this is the same
+ * as clearing an extra line, so we do this, and are done.
+ *
+ * This a performance hack, and a pretty gross one, but it works.
+ *
+ * Chris Peterson 11/13/89.
+ */
+
+ if (done_painting) {
+ y += height;
+ SinkClearToBG(ctx->text.sink,
+ (Position) ctx->text.margin.left, (Position) y,
+ w->core.width - ctx->text.margin.left/* - 2 * s*/,
+ (Dimension) Min(height, ctx->core.height - 2 * s - y));
+ _ShadowSurroundedBox((Widget)ctx, (ThreeDWidget)ctx->text.threeD,
+ 0, 0, ctx->core.width, ctx->core.height,
+ ((ThreeDWidget)ctx->text.threeD)->threeD.relief,
+ False);
+
+ break; /* set single_char to FALSE and return. */
+ }
+ }
+
+ x = (Position) ctx->text.margin.left;
+ y = ctx->text.lt.info[i + 1].y;
+ if ( done_painting
+ || (y >= (int)(ctx->core.height - ctx->text.margin.bottom)) )
+ break;
+ }
+ ctx->text.single_char = FALSE;
+}
+
+/*
+ * This routine implements multi-click selection in a hardwired manner.
+ * It supports multi-click entity cycling (char, word, line, file) and mouse
+ * motion adjustment of the selected entitie (i.e. select a word then, with
+ * button still down, adjust wich word you really meant by moving the mouse).
+ * [NOTE: This routine is to be replaced by a set of procedures that
+ * will allows clients to implements a wide class of draw through and
+ * multi-click selection user interfaces.]
+ */
+
+static void
+DoSelection (ctx, pos, time, motion)
+TextWidget ctx;
+XawTextPosition pos;
+Time time;
+Boolean motion;
+{
+ XawTextPosition newLeft, newRight;
+ XawTextSelectType newType, *sarray;
+ Widget src = ctx->text.source;
+
+ if (motion)
+ newType = ctx->text.s.type;
+ else {
+ if ( (abs((long) time - (long) ctx->text.lasttime) < MULTI_CLICK_TIME) &&
+ ((pos >= ctx->text.s.left) && (pos <= ctx->text.s.right))) {
+ sarray = ctx->text.sarray;
+ for (;*sarray != XawselectNull && *sarray != ctx->text.s.type; sarray++);
+
+ if (*sarray == XawselectNull)
+ newType = *(ctx->text.sarray);
+ else {
+ newType = *(sarray + 1);
+ if (newType == XawselectNull)
+ newType = *(ctx->text.sarray);
+ }
+ }
+ else /* single-click event */
+ newType = *(ctx->text.sarray);
+
+ ctx->text.lasttime = time;
+ }
+ switch (newType) {
+ case XawselectPosition:
+ newLeft = newRight = pos;
+ break;
+ case XawselectChar:
+ newLeft = pos;
+ newRight = SrcScan(src, pos, XawstPositions, XawsdRight, 1, FALSE);
+ break;
+ case XawselectWord:
+ case XawselectParagraph:
+ {
+ XawTextScanType stype;
+
+ if (newType == XawselectWord)
+ stype = XawstWhiteSpace;
+ else
+ stype = XawstParagraph;
+
+ /*
+ * Somewhat complicated, but basically I treat the space between
+ * two objects as another object. The object that I am currently
+ * in then becomes the end of the selection.
+ *
+ * Chris Peterson - 4/19/90.
+ */
+
+ newRight = SrcScan(ctx->text.source, pos, stype, XawsdRight, 1, FALSE);
+ newRight =SrcScan(ctx->text.source, newRight,stype,XawsdLeft,1, FALSE);
+
+ if (pos != newRight)
+ newLeft = SrcScan(ctx->text.source, pos, stype, XawsdLeft, 1, FALSE);
+ else
+ newLeft = pos;
+
+ newLeft =SrcScan(ctx->text.source, newLeft, stype, XawsdRight,1,FALSE);
+
+ if (newLeft > newRight) {
+ XawTextPosition temp = newLeft;
+ newLeft = newRight;
+ newRight = temp;
+ }
+ }
+ break;
+ case XawselectLine:
+ newLeft = SrcScan(src, pos, XawstEOL, XawsdLeft, 1, FALSE);
+ newRight = SrcScan(src, pos, XawstEOL, XawsdRight, 1, FALSE);
+ break;
+ case XawselectAll:
+ newLeft = SrcScan(src, pos, XawstAll, XawsdLeft, 1, FALSE);
+ newRight = SrcScan(src, pos, XawstAll, XawsdRight, 1, FALSE);
+ break;
+ default:
+ XtAppWarning(XtWidgetToApplicationContext((Widget) ctx),
+ "Text Widget: empty selection array.");
+ return;
+ }
+
+ if ( (newLeft != ctx->text.s.left) || (newRight != ctx->text.s.right)
+ || (newType != ctx->text.s.type)) {
+ ModifySelection(ctx, newLeft, newRight);
+ if (pos - ctx->text.s.left < ctx->text.s.right - pos)
+ ctx->text.insertPos = newLeft;
+ else
+ ctx->text.insertPos = newRight;
+ ctx->text.s.type = newType;
+ }
+ if (!motion) { /* setup so we can freely mix select extend calls*/
+ ctx->text.origSel.type = ctx->text.s.type;
+ ctx->text.origSel.left = ctx->text.s.left;
+ ctx->text.origSel.right = ctx->text.s.right;
+
+ if (pos >= ctx->text.s.left + ((ctx->text.s.right - ctx->text.s.left) / 2))
+ ctx->text.extendDir = XawsdRight;
+ else
+ ctx->text.extendDir = XawsdLeft;
+ }
+}
+
+/*
+ * This routine implements extension of the currently selected text in
+ * the "current" mode (i.e. char word, line, etc.). It worries about
+ * extending from either end of the selection and handles the case when you
+ * cross through the "center" of the current selection (e.g. switch which
+ * end you are extending!).
+ */
+
+static void
+ExtendSelection (ctx, pos, motion)
+TextWidget ctx;
+XawTextPosition pos;
+Boolean motion;
+{
+ XawTextScanDirection dir;
+
+ if (!motion) { /* setup for extending selection */
+ if (ctx->text.s.left == ctx->text.s.right) /* no current selection. */
+ ctx->text.s.left = ctx->text.s.right = ctx->text.insertPos;
+ else {
+ ctx->text.origSel.left = ctx->text.s.left;
+ ctx->text.origSel.right = ctx->text.s.right;
+ }
+
+ ctx->text.origSel.type = ctx->text.s.type;
+
+ if (pos >= ctx->text.s.left + ((ctx->text.s.right - ctx->text.s.left) / 2))
+ ctx->text.extendDir = XawsdRight;
+ else
+ ctx->text.extendDir = XawsdLeft;
+ }
+ else /* check for change in extend direction */
+ if ((ctx->text.extendDir == XawsdRight && pos <= ctx->text.origSel.left) ||
+ (ctx->text.extendDir == XawsdLeft && pos >= ctx->text.origSel.right)) {
+ ctx->text.extendDir = (ctx->text.extendDir == XawsdRight) ?
+ XawsdLeft : XawsdRight;
+ ModifySelection(ctx, ctx->text.origSel.left, ctx->text.origSel.right);
+ }
+
+ dir = ctx->text.extendDir;
+ switch (ctx->text.s.type) {
+ case XawselectWord:
+ case XawselectParagraph:
+ {
+ XawTextPosition left_pos, right_pos;
+ XawTextScanType stype;
+
+ if (ctx->text.s.type == XawselectWord)
+ stype = XawstWhiteSpace;
+ else
+ stype = XawstParagraph;
+
+ /*
+ * Somewhat complicated, but basically I treat the space between
+ * two objects as another object. The object that I am currently
+ * in then becomes the end of the selection.
+ *
+ * Chris Peterson - 4/19/90.
+ */
+
+ right_pos = SrcScan(ctx->text.source, pos, stype, XawsdRight, 1, FALSE);
+ right_pos =SrcScan(ctx->text.source, right_pos,stype,XawsdLeft,1, FALSE);
+
+ if (pos != right_pos)
+ left_pos = SrcScan(ctx->text.source, pos, stype, XawsdLeft, 1, FALSE);
+ else
+ left_pos = pos;
+
+ left_pos =SrcScan(ctx->text.source, left_pos, stype, XawsdRight,1,FALSE);
+
+ if (dir == XawsdLeft)
+ pos = Min(left_pos, right_pos);
+ else /* dir == XawsdRight */
+ pos = Max(left_pos, right_pos);
+ }
+ break;
+ case XawselectLine:
+ pos = SrcScan(ctx->text.source, pos, XawstEOL, dir, 1, dir == XawsdRight);
+ break;
+ case XawselectAll:
+ pos = ctx->text.insertPos;
+ case XawselectPosition: /* fall through. */
+ default:
+ break;
+ }
+
+ if (dir == XawsdRight)
+ ModifySelection(ctx, ctx->text.s.left, pos);
+ else
+ ModifySelection(ctx, pos, ctx->text.s.right);
+
+ ctx->text.insertPos = pos;
+}
+
+/*
+ * Clear the window to background color.
+ */
+
+static void
+ClearWindow (w)
+Widget w;
+{
+ TextWidget ctx = (TextWidget) w;
+ int s = ((ThreeDWidget)ctx->text.threeD)->threeD.shadow_width;
+
+ if (XtIsRealized(w))
+ {
+ SinkClearToBG(ctx->text.sink,
+ (Position) s, (Position) s,
+ w->core.width - 2 * s, w->core.height - 2 * s);
+ /* note to self: _ShadowSurroundedBox() hack might be needed here */
+ }
+}
+
+/* Function Name: _XawTextClearAndCenterDisplay
+ * Description: Redraws the display with the cursor in insert point
+ * centered vertically.
+ * Arguments: ctx - the text widget.
+ * Returns: none.
+ */
+
+void
+_XawTextClearAndCenterDisplay(ctx)
+TextWidget ctx;
+{
+ int insert_line = LineForPosition(ctx, ctx->text.insertPos);
+ int scroll_by = insert_line - ctx->text.lt.lines/2;
+
+ _XawTextVScroll(ctx, scroll_by);
+ DisplayTextWindow( (Widget) ctx);
+}
+
+/*
+ * Internal redisplay entire window.
+ * Legal to call only if widget is realized.
+ */
+
+static void
+DisplayTextWindow (w)
+Widget w;
+{
+ TextWidget ctx = (TextWidget) w;
+ ClearWindow(w);
+ _XawTextBuildLineTable(ctx, ctx->text.lt.top, FALSE);
+ _XawTextNeedsUpdating(ctx, zeroPosition, ctx->text.lastPos);
+ _XawTextSetScrollBars(ctx);
+}
+
+/*
+ * This routine checks to see if the window should be resized (grown or
+ * shrunk) when text to be painted overflows to the right or
+ * the bottom of the window. It is used by the keyboard input routine.
+ */
+
+void
+_XawTextCheckResize(ctx)
+TextWidget ctx;
+{
+ Widget w = (Widget) ctx;
+ int line = 0, old_height;
+ XtWidgetGeometry rbox, return_geom;
+
+ if ( (ctx->text.resize == XawtextResizeWidth) ||
+ (ctx->text.resize == XawtextResizeBoth) ) {
+ XawTextLineTableEntry *lt;
+ rbox.width = 0;
+ for (lt = ctx->text.lt.info;
+ IsValidLine(ctx, line) && (line < ctx->text.lt.lines);
+ line++, lt++) {
+ if ((int)(lt->textWidth + ctx->text.margin.left) > (int)rbox.width)
+ rbox.width = lt->textWidth + ctx->text.margin.left;
+ }
+
+ rbox.width += ctx->text.margin.right;
+ if (rbox.width > ctx->core.width) { /* Only get wider. */
+ rbox.request_mode = CWWidth;
+ if (XtMakeGeometryRequest(w, &rbox, &return_geom) == XtGeometryAlmost)
+ (void) XtMakeGeometryRequest(w, &return_geom, (XtWidgetGeometry*) NULL);
+ }
+ }
+
+ if ( !((ctx->text.resize == XawtextResizeHeight) ||
+ (ctx->text.resize == XawtextResizeBoth)) )
+ return;
+
+ if (IsPositionVisible(ctx, ctx->text.lastPos))
+ line = LineForPosition(ctx, ctx->text.lastPos);
+ else
+ line = ctx->text.lt.lines;
+
+ if ( (line + 1) == ctx->text.lt.lines ) return;
+
+ old_height = ctx->core.height;
+ rbox.request_mode = CWHeight;
+ rbox.height = XawTextSinkMaxHeight(ctx->text.sink, line + 1) + VMargins(ctx);
+
+ if ((int)rbox.height < old_height) return; /* It will only get taller. */
+
+ if (XtMakeGeometryRequest(w, &rbox, &return_geom) == XtGeometryAlmost)
+ if (XtMakeGeometryRequest(w, &return_geom, (XtWidgetGeometry*)NULL) != XtGeometryYes)
+ return;
+
+ _XawTextBuildLineTable(ctx, ctx->text.lt.top, TRUE);
+}
+
+/*
+ * Converts (params, num_params) to a list of atoms & caches the
+ * list in the TextWidget instance.
+ */
+
+Atom*
+_XawTextSelectionList(ctx, list, nelems)
+TextWidget ctx;
+String *list;
+Cardinal nelems;
+{
+ Atom * sel = ctx->text.s.selections;
+ Display *dpy = XtDisplay((Widget) ctx);
+ int n;
+
+ if (nelems > ctx->text.s.array_size) {
+ sel = (Atom *) XtRealloc((char *) sel, sizeof(Atom) * nelems);
+ ctx->text.s.array_size = nelems;
+ ctx->text.s.selections = sel;
+ }
+ for (n=nelems; --n >= 0; sel++, list++)
+ *sel = XInternAtom(dpy, *list, False);
+
+ ctx->text.s.atom_count = nelems;
+ return ctx->text.s.selections;
+}
+
+/* Function Name: SetSelection
+ * Description: Sets the current selection.
+ * Arguments: ctx - the text widget.
+ * defaultSel - the default selection.
+ * l, r - the left and right ends of the selection.
+ * list, nelems - the selection list (as strings).
+ * Returns: none.
+ *
+ * NOTE: if (ctx->text.s.left >= ctx->text.s.right) then the selection
+ * is unset.
+ */
+
+void
+_XawTextSetSelection(ctx, l, r, list, nelems)
+TextWidget ctx;
+XawTextPosition l, r;
+String *list;
+Cardinal nelems;
+{
+ if (nelems == 1 && !strcmp (list[0], "none"))
+ return;
+ if (nelems == 0) {
+ String defaultSel = "PRIMARY";
+ list = &defaultSel;
+ nelems = 1;
+ }
+ _SetSelection(ctx, l, r, _XawTextSelectionList(ctx, list, nelems), nelems);
+}
+
+
+/* Function Name: ModifySelection
+ * Description: Modifies the current selection.
+ * Arguments: ctx - the text widget.
+ * left, right - the left and right ends of the selection.
+ * Returns: none.
+ *
+ * NOTE: if (ctx->text.s.left >= ctx->text.s.right) then the selection
+ * is unset.
+ */
+
+static void
+ModifySelection(ctx, left, right)
+TextWidget ctx;
+XawTextPosition left, right;
+{
+ if (left == right)
+ ctx->text.insertPos = left;
+ _SetSelection( ctx, left, right, (Atom*) NULL, ZERO );
+}
+
+/*
+ * This routine is used to perform various selection functions. The goal is
+ * to be able to specify all the more popular forms of draw-through and
+ * multi-click selection user interfaces from the outside.
+ */
+
+void
+_XawTextAlterSelection (ctx, mode, action, params, num_params)
+TextWidget ctx;
+XawTextSelectionMode mode; /* {XawsmTextSelect, XawsmTextExtend} */
+XawTextSelectionAction action; /* {XawactionStart,
+ XawactionAdjust, XawactionEnd} */
+String *params;
+Cardinal *num_params;
+{
+ XawTextPosition position;
+ Boolean flag;
+
+/*
+ * This flag is used by TextPop.c:DoReplace() to determine if the selection
+ * is okay to use, or if it has been modified.
+ */
+
+ if (ctx->text.search != NULL)
+ ctx->text.search->selection_changed = TRUE;
+
+ position = PositionForXY (ctx, (int) ctx->text.ev_x, (int) ctx->text.ev_y);
+
+ flag = (action != XawactionStart);
+ if (mode == XawsmTextSelect)
+ DoSelection (ctx, position, ctx->text.time, flag);
+ else /* mode == XawsmTextExtend */
+ ExtendSelection (ctx, position, flag);
+
+ if (action == XawactionEnd)
+ _XawTextSetSelection(ctx, ctx->text.s.left, ctx->text.s.right,
+ params, *num_params);
+}
+
+/* Function Name: RectanglesOverlap
+ * Description: Returns TRUE if two rectangles overlap.
+ * Arguments: rect1, rect2 - the two rectangles to check.
+ * Returns: TRUE iff these rectangles overlap.
+ */
+
+static Boolean
+RectanglesOverlap(rect1, rect2)
+XRectangle *rect1, *rect2;
+{
+ return ( (rect1->x < rect2->x + (short) rect2->width) &&
+ (rect2->x < rect1->x + (short) rect1->width) &&
+ (rect1->y < rect2->y + (short) rect2->height) &&
+ (rect2->y < rect1->y + (short) rect1->height) );
+}
+
+/* Function Name: UpdateTextInRectangle.
+ * Description: Updates the text in a rectangle.
+ * Arguments: ctx - the text widget.
+ * rect - the rectangle to update.
+ * Returns: none.
+ */
+
+static void
+UpdateTextInRectangle(ctx, rect)
+TextWidget ctx;
+XRectangle * rect;
+{
+ XawTextLineTableEntry *info = ctx->text.lt.info;
+ int line, x = rect->x, y = rect->y;
+ int right = rect->width + x, bottom = rect->height + y;
+
+ for (line = 0;( (line < ctx->text.lt.lines) &&
+ IsValidLine(ctx, line) && (info->y < bottom)); line++, info++)
+ if ( (info + 1)->y >= y )
+ UpdateTextInLine(ctx, line, x, right);
+}
+
+/*
+ * This routine processes all "expose region" XEvents. In general, its job
+ * is to the best job at minimal re-paint of the text, displayed in the
+ * window, that it can.
+ */
+
+/* ARGSUSED */
+static void
+ProcessExposeRegion(w, event, region)
+Widget w;
+XEvent *event;
+Region region; /* Unused. */
+{
+ TextWidget ctx = (TextWidget) w;
+ XRectangle expose, cursor;
+ Boolean need_to_draw;
+
+ if (event->type == Expose) {
+ expose.x = event->xexpose.x;
+ expose.y = event->xexpose.y;
+ expose.width = event->xexpose.width;
+ expose.height = event->xexpose.height;
+ }
+ else if (event->type == GraphicsExpose) {
+ expose.x = event->xgraphicsexpose.x;
+ expose.y = event->xgraphicsexpose.y;
+ expose.width = event->xgraphicsexpose.width;
+ expose.height = event->xgraphicsexpose.height;
+ }
+ else { /* No Expose */
+ PopCopyQueue(ctx);
+ return; /* no more processing necessary. */
+ }
+
+ need_to_draw = TranslateExposeRegion(ctx, &expose);
+ if ((event->type == GraphicsExpose) && (event->xgraphicsexpose.count == 0))
+ PopCopyQueue(ctx);
+
+ if (!need_to_draw)
+ return; /* don't draw if we don't need to. */
+
+ _XawTextPrepareToUpdate(ctx);
+ UpdateTextInRectangle(ctx, &expose);
+ XawTextSinkGetCursorBounds(ctx->text.sink, &cursor);
+ if (RectanglesOverlap(&cursor, &expose)) {
+ SinkClearToBG(ctx->text.sink, (Position) cursor.x, (Position) cursor.y,
+ (Dimension) cursor.width, (Dimension) cursor.height);
+ UpdateTextInRectangle(ctx, &cursor);
+ }
+ _XawTextExecuteUpdate(ctx);
+
+ _ShadowSurroundedBox((Widget)ctx, (ThreeDWidget)ctx->text.threeD,
+ 0, 0, ctx->core.width, ctx->core.height,
+ ((ThreeDWidget)ctx->text.threeD)->threeD.relief, False);
+}
+
+/*
+ * This routine does all setup required to syncronize batched screen updates
+ */
+
+void
+_XawTextPrepareToUpdate(ctx)
+TextWidget ctx;
+{
+ if (ctx->text.old_insert < 0) {
+ InsertCursor((Widget)ctx, XawisOff);
+ ctx->text.numranges = 0;
+ ctx->text.showposition = FALSE;
+ ctx->text.old_insert = ctx->text.insertPos;
+ }
+}
+
+/*
+ * This is a private utility routine used by _XawTextExecuteUpdate. It
+ * processes all the outstanding update requests and merges update
+ * ranges where possible.
+ */
+
+static
+void FlushUpdate(ctx)
+TextWidget ctx;
+{
+ int i, w;
+ XawTextPosition updateFrom, updateTo;
+ if (!XtIsRealized((Widget)ctx)) {
+ ctx->text.numranges = 0;
+ return;
+ }
+ while (ctx->text.numranges > 0) {
+ updateFrom = ctx->text.updateFrom[0];
+ w = 0;
+ for (i = 1 ; i < ctx->text.numranges ; i++) {
+ if (ctx->text.updateFrom[i] < updateFrom) {
+ updateFrom = ctx->text.updateFrom[i];
+ w = i;
+ }
+ }
+ updateTo = ctx->text.updateTo[w];
+ ctx->text.numranges--;
+ ctx->text.updateFrom[w] = ctx->text.updateFrom[ctx->text.numranges];
+ ctx->text.updateTo[w] = ctx->text.updateTo[ctx->text.numranges];
+ for (i = ctx->text.numranges - 1 ; i >= 0 ; i--) {
+ while (ctx->text.updateFrom[i] <= updateTo && i < ctx->text.numranges) {
+ updateTo = ctx->text.updateTo[i];
+ ctx->text.numranges--;
+ ctx->text.updateFrom[i] = ctx->text.updateFrom[ctx->text.numranges];
+ ctx->text.updateTo[i] = ctx->text.updateTo[ctx->text.numranges];
+ }
+ }
+ DisplayText((Widget)ctx, updateFrom, updateTo);
+ }
+}
+
+/*
+ * This is a private utility routine used by _XawTextExecuteUpdate. This
+ * routine worries about edits causing new data or the insertion point becoming
+ * invisible (off the screen, or under the horiz. scrollbar). Currently
+ * it always makes it visible by scrolling. It probably needs
+ * generalization to allow more options.
+ */
+
+void
+_XawTextShowPosition(ctx)
+TextWidget ctx;
+{
+ int x, y, lines, number;
+ Boolean no_scroll;
+ XawTextPosition max_pos, top, first;
+
+ if ( (!XtIsRealized((Widget)ctx)) || (ctx->text.lt.lines <= 0) )
+ return;
+
+/*
+ * Find out the bottom the visable window, and make sure that the
+ * cursor does not go past the end of this space.
+ *
+ * This makes sure that the cursor does not go past the end of the
+ * visable window.
+ */
+
+ x = ctx->core.width;
+ y = ctx->core.height - ctx->text.margin.bottom;
+ if (ctx->text.hbar != NULL)
+ y -= ctx->text.hbar->core.height + 2 * ctx->text.hbar->core.border_width;
+
+ max_pos = PositionForXY (ctx, x, y);
+ lines = LineForPosition(ctx, max_pos) + 1; /* number of visable lines. */
+
+ if ( (ctx->text.insertPos >= ctx->text.lt.top) &&
+ (ctx->text.insertPos < max_pos))
+ return;
+
+ first = ctx->text.lt.top;
+ no_scroll = FALSE;
+
+ if (ctx->text.insertPos < first) { /* We need to scroll down. */
+ top = SrcScan(ctx->text.source, ctx->text.insertPos,
+ XawstEOL, XawsdLeft, 1, FALSE);
+
+ /* count the number of lines we have to scroll */
+
+ number = 0;
+ while (first > top) {
+ first = SrcScan(ctx->text.source, first,
+ XawstEOL, XawsdLeft, 1, TRUE);
+
+ if ( - number > lines )
+ break;
+
+ number--;
+ }
+
+ if (first <= top) { /* If we found the proper number
+ of lines. */
+
+ /* Back up to just before the last CR. */
+
+ first = SrcScan(ctx->text.source, first,
+ XawstPositions, XawsdRight, 1, TRUE);
+
+ /* Check to make sure the cursor is visable. */
+
+ if (first <= top)
+ number++;
+
+ lines = number;
+ }
+ else
+ no_scroll = TRUE;
+ }
+ else { /* We need to Scroll up */
+ top = SrcScan(ctx->text.source, ctx->text.insertPos,
+ XawstEOL, XawsdLeft, lines, FALSE);
+
+ if (top < max_pos)
+ lines = LineForPosition(ctx, top);
+ else
+ no_scroll = TRUE;
+ }
+
+ if (no_scroll) {
+ _XawTextBuildLineTable(ctx, top, FALSE);
+ DisplayTextWindow((Widget)ctx);
+ }
+ else
+ _XawTextVScroll(ctx, lines);
+
+ _XawTextSetScrollBars(ctx);
+}
+
+/*
+ * This routine causes all batched screen updates to be performed
+ */
+
+void
+_XawTextExecuteUpdate(ctx)
+TextWidget ctx;
+{
+ if ( ctx->text.update_disabled || (ctx->text.old_insert < 0) )
+ return;
+
+ if((ctx->text.old_insert != ctx->text.insertPos) || (ctx->text.showposition))
+ _XawTextShowPosition(ctx);
+ FlushUpdate(ctx);
+ InsertCursor((Widget)ctx, XawisOn);
+ ctx->text.old_insert = -1;
+}
+
+
+static void
+TextDestroy(w)
+Widget w;
+{
+ TextWidget ctx = (TextWidget)w;
+
+ DestroyHScrollBar(ctx);
+ DestroyVScrollBar(ctx);
+
+ XtFree((char *)ctx->text.s.selections);
+ XtFree((char *)ctx->text.lt.info);
+ XtFree((char *)ctx->text.search);
+ XtFree((char *)ctx->text.updateFrom);
+ XtFree((char *)ctx->text.updateTo);
+}
+
+/*
+ * by the time we are managed (and get this far) we had better
+ * have both a source and a sink
+ */
+
+static void
+Resize(w)
+Widget w;
+{
+ TextWidget ctx = (TextWidget) w;
+
+ PositionVScrollBar(ctx);
+ PositionHScrollBar(ctx);
+
+ _XawTextBuildLineTable(ctx, ctx->text.lt.top, TRUE);
+ _XawTextSetScrollBars(ctx);
+}
+
+/*
+ * This routine allow the application program to Set attributes.
+ */
+
+/*ARGSUSED*/
+static Boolean
+SetValues(current, request, new, args, num_args)
+Widget current, request, new;
+ArgList args;
+Cardinal *num_args;
+{
+ TextWidget oldtw = (TextWidget) current;
+ TextWidget newtw = (TextWidget) new;
+ Boolean redisplay = FALSE;
+ Boolean display_caret = newtw->text.display_caret;
+
+
+ newtw->text.display_caret = oldtw->text.display_caret;
+ _XawTextPrepareToUpdate(newtw);
+ newtw->text.display_caret = display_caret;
+
+ if (oldtw->text.r_margin.left != newtw->text.r_margin.left) {
+ newtw->text.margin.left = newtw->text.r_margin.left;
+ if (newtw->text.vbar != NULL)
+ newtw->text.margin.left += newtw->text.vbar->core.width +
+ newtw->text.vbar->core.border_width;
+ redisplay = TRUE;
+ }
+
+ if (oldtw->text.scroll_vert != newtw->text.scroll_vert) {
+ if (newtw->text.scroll_vert == XawtextScrollNever)
+ DestroyVScrollBar(newtw);
+ else if (newtw->text.scroll_vert == XawtextScrollAlways)
+ CreateVScrollBar(newtw);
+ redisplay = TRUE;
+ }
+
+ if (oldtw->text.r_margin.bottom != newtw->text.r_margin.bottom) {
+ newtw->text.margin.bottom = newtw->text.r_margin.bottom;
+ if (newtw->text.hbar != NULL)
+ newtw->text.margin.bottom += newtw->text.hbar->core.height +
+ newtw->text.hbar->core.border_width;
+ redisplay = TRUE;
+ }
+
+ if (oldtw->text.scroll_horiz != newtw->text.scroll_horiz) {
+ if (newtw->text.scroll_horiz == XawtextScrollNever)
+ DestroyHScrollBar(newtw);
+ else if (newtw->text.scroll_horiz == XawtextScrollAlways)
+ CreateHScrollBar(newtw);
+ redisplay = TRUE;
+ }
+
+ if ( oldtw->text.source != newtw->text.source )
+ XawTextSetSource( (Widget) newtw, newtw->text.source, newtw->text.lt.top);
+
+ newtw->text.redisplay_needed = False;
+ XtSetValues( (Widget)newtw->text.source, args, *num_args );
+ XtSetValues( (Widget)newtw->text.sink, args, *num_args );
+
+ if ( oldtw->text.wrap != newtw->text.wrap ||
+ oldtw->text.lt.top != newtw->text.lt.top ||
+ oldtw->text.r_margin.right != newtw->text.r_margin.right ||
+ oldtw->text.r_margin.top != newtw->text.r_margin.top ||
+ oldtw->text.sink != newtw->text.sink ||
+ newtw->text.redisplay_needed )
+ {
+ _XawTextBuildLineTable(newtw, newtw->text.lt.top, TRUE);
+ redisplay = TRUE;
+ }
+
+ if (oldtw->text.insertPos != newtw->text.insertPos) {
+ newtw->text.showposition = TRUE;
+ redisplay = TRUE;
+ }
+
+ _XawTextExecuteUpdate(newtw);
+ if (redisplay)
+ _XawTextSetScrollBars(newtw);
+
+ return redisplay;
+}
+
+/* invoked by the Simple widget's SetValues */
+static Boolean ChangeSensitive(w)
+ Widget w; /* the new widget */
+{
+ Arg args[1];
+ TextWidget tw = (TextWidget) w;
+
+ (*(&simpleClassRec)->simple_class.change_sensitive)(w);
+
+ XtSetArg(args[0], XtNancestorSensitive,
+ (tw->core.ancestor_sensitive && tw->core.sensitive));
+ if (tw->text.vbar)
+ XtSetValues(tw->text.vbar, args, ONE);
+ if (tw->text.hbar)
+ XtSetValues(tw->text.hbar, args, ONE);
+ return False;
+}
+
+/* Function Name: GetValuesHook
+ * Description: This is a get values hook routine that gets the
+ * values in the text source and sink.
+ * Arguments: w - the Text Widget.
+ * args - the argument list.
+ * num_args - the number of args.
+ * Returns: none.
+ */
+
+static void
+GetValuesHook(w, args, num_args)
+Widget w;
+ArgList args;
+Cardinal * num_args;
+{
+ XtGetValues( ((TextWidget) w)->text.source, args, *num_args );
+ XtGetValues( ((TextWidget) w)->text.sink, args, *num_args );
+}
+
+/* Function Name: FindGoodPosition
+ * Description: Returns a valid position given any postition
+ * Arguments: pos - any position.
+ * Returns: a position between (0 and lastPos);
+ */
+
+static XawTextPosition
+FindGoodPosition(ctx, pos)
+TextWidget ctx;
+XawTextPosition pos;
+{
+ if (pos < 0) return(0);
+ return ( ((pos > ctx->text.lastPos) ? ctx->text.lastPos : pos) );
+}
+
+/************************************************************
+ *
+ * Routines for handling the copy area expose queue.
+ *
+ ************************************************************/
+
+/* Function Name: PushCopyQueue
+ * Description: Pushes a value onto the copy queue.
+ * Arguments: ctx - the text widget.
+ * h, v - amount of offset in the horiz and vert directions.
+ * Returns: none
+ */
+
+static void
+PushCopyQueue(ctx, h, v)
+TextWidget ctx;
+int h, v;
+{
+ struct text_move * offsets = XtNew(struct text_move);
+
+ offsets->h = h;
+ offsets->v = v;
+ offsets->next = NULL;
+
+ if (ctx->text.copy_area_offsets == NULL)
+ ctx->text.copy_area_offsets = offsets;
+ else {
+ struct text_move * end = ctx->text.copy_area_offsets;
+ for ( ; end->next != NULL; end = end->next) {}
+ end->next = offsets;
+ }
+}
+
+/* Function Name: PopCopyQueue
+ * Description: Pops the top value off of the copy queue.
+ * Arguments: ctx - the text widget.
+ * Returns: none.
+ */
+
+static void
+PopCopyQueue(ctx)
+TextWidget ctx;
+{
+ struct text_move * offsets = ctx->text.copy_area_offsets;
+
+ if (offsets == NULL)
+ (void) printf( "Xaw Text widget %s: empty copy queue\n",
+ XtName( (Widget) ctx ) );
+ else {
+ ctx->text.copy_area_offsets = offsets->next;
+ XtFree((char *) offsets); /* free what you allocate. */
+ }
+}
+
+/* Function Name: TranslateExposeRegion
+ * Description: Translates the expose that came into
+ * the cordinates that now exist in the Text widget.
+ * Arguments: ctx - the text widget.
+ * expose - a Rectangle, who's region currently
+ * contains the expose event location.
+ * this region will be returned containing
+ * the new rectangle.
+ * Returns: True if there is drawing that needs to be done.
+ */
+
+static Boolean
+TranslateExposeRegion(ctx, expose)
+TextWidget ctx;
+XRectangle * expose;
+{
+ struct text_move * offsets = ctx->text.copy_area_offsets;
+ int value;
+ int x, y, width, height;
+
+ /*
+ * Skip over the first one, this has already been taken into account.
+ */
+
+ if (!offsets || !(offsets = offsets->next))
+ return(TRUE);
+
+ x = expose->x;
+ y = expose->y;
+ width = expose->width;
+ height = expose->height;
+
+ while (offsets) {
+ x += offsets->h;
+ y += offsets->v;
+ offsets = offsets->next;
+ }
+
+ /*
+ * remove that area of the region that is now outside the window.
+ */
+
+ if (y < 0) {
+ height += y;
+ y = 0;
+ }
+
+ value = y + height - ctx->core.height;
+ if (value > 0)
+ height -= value;
+
+ if (height <= 0)
+ return(FALSE); /* no need to draw outside the window. */
+
+ /*
+ * and now in the horiz direction...
+ */
+
+ if (x < 0) {
+ width += x;
+ x = 0;
+ }
+
+ value = x + width - ctx->core.width;
+ if (value > 0)
+ width -= value;
+
+ if (width <= 0)
+ return(FALSE); /* no need to draw outside the window. */
+
+ expose->x = x;
+ expose->y = y;
+ expose->width = width;
+ expose->height = height;
+ return(TRUE);
+}
+
+/* Li wrote this so the IM can find a given text position's screen position. */
+
+void
+#if NeedFunctionPrototypes
+_XawTextPosToXY(
+ Widget w,
+ XawTextPosition pos,
+ Position* x,
+ Position* y )
+#else
+_XawTextPosToXY( w, pos, x, y )
+ Widget w;
+ XawTextPosition pos;
+ Position *x, *y;
+#endif
+{
+ int line;
+ LineAndXYForPosition( (TextWidget)w, pos, &line, x, y );
+}
+
+/*******************************************************************
+The following routines provide procedural interfaces to Text window state
+setting and getting. They need to be redone so than the args code can use
+them. I suggest we create a complete set that takes the context as an
+argument and then have the public version lookup the context and call the
+internal one. The major value of this set is that they have actual application
+clients and therefore the functionality provided is required for any future
+version of Text.
+********************************************************************/
+
+void
+#if NeedFunctionPrototypes
+XawTextDisplay (Widget w)
+#else
+XawTextDisplay (w)
+Widget w;
+#endif
+{
+ if (!XtIsRealized(w)) return;
+
+ _XawTextPrepareToUpdate( (TextWidget) w);
+ DisplayTextWindow(w);
+ _XawTextExecuteUpdate( (TextWidget) w);
+}
+
+void
+#if NeedFunctionPrototypes
+XawTextSetSelectionArray(Widget w, XawTextSelectType *sarray)
+#else
+XawTextSetSelectionArray(w, sarray)
+Widget w;
+XawTextSelectType *sarray;
+#endif
+{
+ ((TextWidget)w)->text.sarray = sarray;
+}
+
+void
+#if NeedFunctionPrototypes
+XawTextGetSelectionPos(Widget w, XawTextPosition *left, XawTextPosition *right)
+#else
+XawTextGetSelectionPos(w, left, right)
+Widget w;
+XawTextPosition* left,* right;
+#endif
+{
+ *left = ((TextWidget) w)->text.s.left;
+ *right = ((TextWidget) w)->text.s.right;
+}
+
+
+void
+#if NeedFunctionPrototypes
+XawTextSetSource(Widget w, Widget source, XawTextPosition startPos)
+#else
+XawTextSetSource(w, source, startPos)
+Widget w, source;
+XawTextPosition startPos;
+#endif
+{
+ TextWidget ctx = (TextWidget) w;
+
+ ctx->text.source = source;
+ ctx->text.lt.top = startPos;
+ ctx->text.s.left = ctx->text.s.right = 0;
+ ctx->text.insertPos = startPos;
+ ctx->text.lastPos = GETLASTPOS;
+
+ _XawTextBuildLineTable(ctx, ctx->text.lt.top, TRUE);
+ XawTextDisplay(w);
+}
+
+/*
+ * This public routine deletes the text from startPos to endPos in a source and
+ * then inserts, at startPos, the text that was passed. As a side effect it
+ * "invalidates" that portion of the displayed text (if any), so that things
+ * will be repainted properly.
+ */
+
+int
+#if NeedFunctionPrototypes
+XawTextReplace(Widget w, XawTextPosition startPos, XawTextPosition endPos,
+ XawTextBlock *text)
+#else
+XawTextReplace(w, startPos, endPos, text)
+Widget w;
+XawTextPosition startPos, endPos;
+XawTextBlock *text;
+#endif
+{
+ TextWidget ctx = (TextWidget) w;
+ int result;
+
+ _XawTextPrepareToUpdate(ctx);
+ endPos = FindGoodPosition(ctx, endPos);
+ startPos = FindGoodPosition(ctx, startPos);
+ if ((result = _XawTextReplace(ctx, startPos, endPos, text)) == XawEditDone) {
+ int delta = text->length - (endPos - startPos);
+ if (ctx->text.insertPos >= (endPos + delta)) {
+ XawTextScanDirection sd = (delta < 0) ? XawsdLeft : XawsdRight;
+ ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.insertPos,
+ XawstPositions, sd, abs(delta), TRUE);
+ }
+ }
+
+ _XawTextCheckResize(ctx);
+ _XawTextExecuteUpdate(ctx);
+ _XawTextSetScrollBars(ctx);
+
+ return result;
+}
+
+XawTextPosition
+#if NeedFunctionPrototypes
+XawTextTopPosition(Widget w)
+#else
+XawTextTopPosition(w)
+Widget w;
+#endif
+{
+ return( ((TextWidget) w)->text.lt.top );
+}
+
+void
+#if NeedFunctionPrototypes
+XawTextSetInsertionPoint(Widget w, XawTextPosition position)
+#else
+XawTextSetInsertionPoint(w, position)
+Widget w;
+XawTextPosition position;
+#endif
+{
+ TextWidget ctx = (TextWidget) w;
+
+ _XawTextPrepareToUpdate(ctx);
+ ctx->text.insertPos = FindGoodPosition(ctx, position);
+ ctx->text.showposition = TRUE;
+
+ _XawTextExecuteUpdate(ctx);
+}
+
+XawTextPosition
+#if NeedFunctionPrototypes
+XawTextGetInsertionPoint(Widget w)
+#else
+XawTextGetInsertionPoint(w)
+Widget w;
+#endif
+{
+ return( ((TextWidget) w)->text.insertPos);
+}
+
+/*
+ * NOTE: Must walk the selection list in opposite order from LoseSelection.
+ */
+
+void
+#if NeedFunctionPrototypes
+XawTextUnsetSelection(Widget w)
+#else
+XawTextUnsetSelection(w)
+Widget w;
+#endif
+{
+ TextWidget ctx = (TextWidget)w;
+
+ while (ctx->text.s.atom_count != 0) {
+ Atom sel = ctx->text.s.selections[ctx->text.s.atom_count - 1];
+ if ( sel != (Atom) 0 ) {
+/*
+ * As selections are lost the atom_count will decrement.
+ */
+ if (GetCutBufferNumber(sel) == NOT_A_CUT_BUFFER)
+ XtDisownSelection(w, sel, ctx->text.time);
+ LoseSelection(w, &sel); /* In case this is a cut buffer, or
+ XtDisownSelection failed to call us. */
+ }
+ }
+}
+
+void
+#if NeedFunctionPrototypes
+XawTextSetSelection (Widget w, XawTextPosition left, XawTextPosition right)
+#else
+XawTextSetSelection (w, left, right)
+Widget w;
+XawTextPosition left, right;
+#endif
+{
+ TextWidget ctx = (TextWidget) w;
+
+ _XawTextPrepareToUpdate(ctx);
+ _XawTextSetSelection(ctx, FindGoodPosition(ctx, left),
+ FindGoodPosition(ctx, right), (String*)NULL, ZERO);
+ _XawTextExecuteUpdate(ctx);
+}
+
+void
+#if NeedFunctionPrototypes
+XawTextInvalidate(Widget w, XawTextPosition from, XawTextPosition to)
+#else
+XawTextInvalidate(w, from, to)
+Widget w;
+XawTextPosition from,to;
+#endif
+{
+ TextWidget ctx = (TextWidget) w;
+
+ from = FindGoodPosition(ctx, from);
+ to = FindGoodPosition(ctx, to);
+ ctx->text.lastPos = GETLASTPOS;
+ _XawTextPrepareToUpdate(ctx);
+ _XawTextNeedsUpdating(ctx, from, to);
+ _XawTextBuildLineTable(ctx, ctx->text.lt.top, TRUE);
+ _XawTextExecuteUpdate(ctx);
+}
+
+/*ARGSUSED*/
+void
+#if NeedFunctionPrototypes
+XawTextDisableRedisplay(Widget w)
+#else
+XawTextDisableRedisplay(w)
+Widget w;
+#endif
+{
+ ((TextWidget) w)->text.update_disabled = True;
+ _XawTextPrepareToUpdate( (TextWidget) w);
+}
+
+void
+#if NeedFunctionPrototypes
+XawTextEnableRedisplay(Widget w)
+#else
+XawTextEnableRedisplay(w)
+Widget w;
+#endif
+{
+ TextWidget ctx = (TextWidget)w;
+ XawTextPosition lastPos;
+
+ if (!ctx->text.update_disabled) return;
+
+ ctx->text.update_disabled = False;
+ lastPos = ctx->text.lastPos = GETLASTPOS;
+ ctx->text.lt.top = FindGoodPosition(ctx, ctx->text.lt.top);
+ ctx->text.insertPos = FindGoodPosition(ctx, ctx->text.insertPos);
+ if ( (ctx->text.s.left > lastPos) || (ctx->text.s.right > lastPos) )
+ ctx->text.s.left = ctx->text.s.right = 0;
+
+ _XawTextBuildLineTable(ctx, ctx->text.lt.top, TRUE);
+ if (XtIsRealized(w))
+ DisplayTextWindow(w);
+ _XawTextExecuteUpdate(ctx);
+}
+
+Widget
+#if NeedFunctionPrototypes
+XawTextGetSource(Widget w)
+#else
+XawTextGetSource(w)
+Widget w;
+#endif
+{
+ return ((TextWidget)w)->text.source;
+}
+
+void
+#if NeedFunctionPrototypes
+XawTextDisplayCaret (Widget w,
+#if NeedWidePrototypes
+ /* Boolean */ int display_caret)
+#else
+ Boolean display_caret)
+#endif
+#else
+XawTextDisplayCaret (w, display_caret)
+Widget w;
+Boolean display_caret;
+#endif
+{
+ TextWidget ctx = (TextWidget) w;
+
+ if (ctx->text.display_caret == display_caret) return;
+
+ if (XtIsRealized(w)) {
+ _XawTextPrepareToUpdate(ctx);
+ ctx->text.display_caret = display_caret;
+ _XawTextExecuteUpdate(ctx);
+ }
+ else
+ ctx->text.display_caret = display_caret;
+}
+
+/* Function Name: XawTextSearch(w, dir, text).
+ * Description: searches for the given text block.
+ * Arguments: w - The text widget.
+ * dir - The direction to search.
+ * text - The text block containing info about the string
+ * to search for.
+ * Returns: The position of the text found, or XawTextSearchError on
+ * an error.
+ */
+
+XawTextPosition
+#if NeedFunctionPrototypes
+XawTextSearch(Widget w,
+#if NeedWidePrototypes
+ /* XawTextScanDirection */ int dir,
+#else
+ XawTextScanDirection dir,
+#endif
+ XawTextBlock *text)
+#else
+XawTextSearch(w, dir, text)
+Widget w;
+XawTextScanDirection dir;
+XawTextBlock * text;
+#endif
+{
+ TextWidget ctx = (TextWidget) w;
+
+ return(SrcSearch(ctx->text.source, ctx->text.insertPos, dir, text));
+}
+
+TextClassRec textClassRec = {
+ { /* core fields */
+ /* superclass */ (WidgetClass) &simpleClassRec,
+ /* class_name */ "Text",
+ /* widget_size */ sizeof(TextRec),
+ /* class_initialize */ ClassInitialize,
+ /* class_part_init */ NULL,
+ /* class_inited */ FALSE,
+ /* initialize */ Initialize,
+ /* initialize_hook */ NULL,
+ /* realize */ Realize,
+ /* actions */ _XawTextActionsTable,
+ /* num_actions */ 0, /* Set in ClassInitialize. */
+ /* resources */ resources,
+ /* num_ resource */ XtNumber(resources),
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ TRUE,
+ /* compress_exposure*/ XtExposeGraphicsExpose | XtExposeNoExpose,
+ /* compress_enterleave*/ TRUE,
+ /* visible_interest */ FALSE,
+ /* destroy */ TextDestroy,
+ /* resize */ Resize,
+ /* expose */ ProcessExposeRegion,
+ /* set_values */ SetValues,
+ /* set_values_hook */ NULL,
+ /* set_values_almost*/ XtInheritSetValuesAlmost,
+ /* get_values_hook */ GetValuesHook,
+ /* accept_focus */ NULL,
+ /* version */ XtVersion,
+ /* callback_private */ NULL,
+ /* tm_table */ NULL, /* set in ClassInitialize */
+ /* query_geometry */ XtInheritQueryGeometry,
+ /* display_accelerator*/ XtInheritDisplayAccelerator,
+ /* extension */ NULL
+ },
+ { /* Simple fields */
+ /* change_sensitive */ ChangeSensitive
+ },
+ { /* text fields */
+ /* empty */ 0
+ }
+};
+
+WidgetClass textWidgetClass = (WidgetClass)&textClassRec;
diff --git a/src/Text.h b/src/Text.h
new file mode 100644
index 0000000..9157927
--- /dev/null
+++ b/src/Text.h
@@ -0,0 +1,310 @@
+/* $XConsortium: Text.h,v 1.45 94/04/17 20:13:05 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.
+
+******************************************************************/
+
+#ifndef _XawText_h
+#define _XawText_h
+
+#include <X11/Xaw3d/Simple.h>
+
+/*
+ Text widget
+
+ Class: textWidgetClass
+ Class Name: Text
+ Superclass: Simple
+
+ Resources added by the Text widget:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ autoFill AutoFill Boolean False
+ bottomMargin Margin Position 2
+ displayPosition TextPosition XawTextPosition 0
+ insertPosition TextPosition XawTextPosition 0
+ leftMargin Margin Position 2
+ resize Resize XawTextResizeMode XawTextResizeNever
+ rightMargin Margin Position 4
+ scrollHorizontal Scroll XawTextScrollMode XawtextScrollNever
+ scrollVertical Scroll XawTextScrollMode XawtextScrollNever
+ selectTypes SelectTypes Pointer see documentation
+ textSink TextSink Widget NULL
+ textSource TextSource Widget NULL
+ topMargin Margin Position 2
+ unrealizeCallback Callback Callback NULL
+ wrap Wrap XawTextWrapMode XawTextWrapNever
+
+*/
+
+typedef long XawTextPosition;
+
+typedef enum { XawtextScrollNever,
+ XawtextScrollWhenNeeded, XawtextScrollAlways} XawTextScrollMode;
+
+typedef enum { XawtextWrapNever,
+ XawtextWrapLine, XawtextWrapWord} XawTextWrapMode;
+
+typedef enum { XawtextResizeNever, XawtextResizeWidth,
+ XawtextResizeHeight, XawtextResizeBoth} XawTextResizeMode;
+
+typedef enum {XawsdLeft, XawsdRight} XawTextScanDirection;
+typedef enum {XawtextRead, XawtextAppend, XawtextEdit} XawTextEditType;
+typedef enum {XawselectNull, XawselectPosition, XawselectChar, XawselectWord,
+ XawselectLine, XawselectParagraph, XawselectAll} XawTextSelectType;
+
+typedef struct {
+ int firstPos;
+ int length;
+ char *ptr;
+ unsigned long format;
+ } XawTextBlock, *XawTextBlockPtr;
+
+#include <X11/Xaw3d/TextSink.h>
+#include <X11/Xaw3d/TextSrc.h>
+
+#define XtEtextScrollNever "never"
+#define XtEtextScrollWhenNeeded "whenneeded"
+#define XtEtextScrollAlways "always"
+
+#define XtEtextWrapNever "never"
+#define XtEtextWrapLine "line"
+#define XtEtextWrapWord "word"
+
+#define XtEtextResizeNever "never"
+#define XtEtextResizeWidth "width"
+#define XtEtextResizeHeight "height"
+#define XtEtextResizeBoth "both"
+
+#define XtNautoFill "autoFill"
+#define XtNbottomMargin "bottomMargin"
+#define XtNdialogHOffset "dialogHOffset"
+#define XtNdialogVOffset "dialogVOffset"
+#define XtNdisplayCaret "displayCaret"
+#define XtNdisplayPosition "displayPosition"
+#define XtNleftMargin "leftMargin"
+#define XtNrightMargin "rightMargin"
+#define XtNscrollVertical "scrollVertical"
+#define XtNscrollHorizontal "scrollHorizontal"
+#define XtNselectTypes "selectTypes"
+#define XtNtopMargin "topMargin"
+#define XtNwrap "wrap"
+
+#define XtCAutoFill "AutoFill"
+#define XtCScroll "Scroll"
+#define XtCSelectTypes "SelectTypes"
+#define XtCWrap "Wrap"
+
+#ifndef _XtStringDefs_h_
+#define XtNinsertPosition "insertPosition"
+#define XtNresize "resize"
+#define XtNselection "selection"
+#define XtCResize "Resize"
+#endif
+
+/* Return Error code for XawTextSearch */
+
+#define XawTextSearchError (-12345L)
+
+/* Return codes from XawTextReplace */
+
+#define XawReplaceError -1
+#define XawEditDone 0
+#define XawEditError 1
+#define XawPositionError 2
+
+extern unsigned long FMT8BIT;
+extern unsigned long XawFmt8Bit;
+extern unsigned long XawFmtWide;
+
+/* Class record constants */
+
+extern WidgetClass textWidgetClass;
+
+typedef struct _TextClassRec *TextWidgetClass;
+typedef struct _TextRec *TextWidget;
+
+_XFUNCPROTOBEGIN
+
+extern XrmQuark _XawTextFormat(
+#if NeedFunctionPrototypes
+ TextWidget /* tw */
+#endif
+);
+
+extern void XawTextDisplay(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+extern void XawTextEnableRedisplay(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+extern void XawTextDisableRedisplay(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+extern void XawTextSetSelectionArray(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ XawTextSelectType* /* sarray */
+#endif
+);
+
+extern void XawTextGetSelectionPos(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ XawTextPosition* /* begin_return */,
+ XawTextPosition* /* end_return */
+#endif
+);
+
+extern void XawTextSetSource(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ Widget /* source */,
+ XawTextPosition /* position */
+#endif
+);
+
+extern int XawTextReplace(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ XawTextPosition /* start */,
+ XawTextPosition /* end */,
+ XawTextBlock* /* text */
+#endif
+);
+
+extern XawTextPosition XawTextTopPosition(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+extern void XawTextSetInsertionPoint(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ XawTextPosition /* position */
+#endif
+);
+
+extern XawTextPosition XawTextGetInsertionPoint(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+extern void XawTextUnsetSelection(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+extern void XawTextSetSelection(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ XawTextPosition /* left */,
+ XawTextPosition /* right */
+#endif
+);
+
+extern void XawTextInvalidate(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ XawTextPosition /* from */,
+ XawTextPosition /* to */
+#endif
+);
+
+extern Widget XawTextGetSource(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+extern XawTextPosition XawTextSearch(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+#if NeedWidePrototypes
+ /* XawTextScanDirection */ int /* dir */,
+#else
+ XawTextScanDirection /* dir */,
+#endif
+ XawTextBlock* /* text */
+#endif
+);
+
+extern void XawTextDisplayCaret(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+#if NeedWidePrototypes
+ /* Boolean */ int /* visible */
+#else
+ Boolean /* visible */
+#endif
+#endif
+);
+
+_XFUNCPROTOEND
+
+/*
+ * For R3 compatability only.
+ */
+
+#include <X11/Xaw3d/AsciiSrc.h>
+#include <X11/Xaw3d/AsciiSink.h>
+
+#endif /* _XawText_h */
+/* DON'T ADD STUFF AFTER THIS #endif */
diff --git a/src/TextAction.c b/src/TextAction.c
new file mode 100644
index 0000000..65b8539
--- /dev/null
+++ b/src/TextAction.c
@@ -0,0 +1,2327 @@
+/* $XConsortium: TextAction.c,v 1.53 95/06/14 15:07:27 kaleb Exp $ */
+
+/*
+
+Copyright (c) 1989, 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.
+
+*/
+
+#include "Xaw3dP.h"
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/Xmu/Misc.h>
+#include <X11/Xmu/StdSel.h> /* for XmuConvertStandardSelection */
+#include <X11/Xmu/Atoms.h> /* for XA_COMPOUND_TEXT */
+#include <X11/Xaw3d/TextP.h>
+#ifdef XAW_INTERNATIONALIZATION
+#include <X11/Xaw3d/MultiSrcP.h>
+#include <X11/Xaw3d/XawImP.h>
+#endif
+#include <X11/Xfuncs.h>
+#ifdef XAW_INTERNATIONALIZATION
+#include "XawI18n.h"
+#endif
+#include <stdio.h>
+#include <ctype.h>
+
+#define SrcScan XawTextSourceScan
+#define FindDist XawTextSinkFindDistance
+#define FindPos XawTextSinkFindPosition
+
+#define XawTextActionMaxHexChars 100
+
+/*
+ * These are defined in TextPop.c
+ */
+
+void _XawTextInsertFileAction(), _XawTextInsertFile(), _XawTextSearch();
+void _XawTextSearch(), _XawTextDoSearchAction(), _XawTextDoReplaceAction();
+void _XawTextSetField(), _XawTextPopdownSearchAction();
+
+/*
+ * These are defined in Text.c
+ */
+
+char * _XawTextGetText();
+void _XawTextAlterSelection(), _XawTextVScroll();
+void _XawTextSetSelection(), _XawTextCheckResize(), _XawTextExecuteUpdate();
+void _XawTextSetScrollBars(), _XawTextClearAndCenterDisplay();
+Atom * _XawTextSelectionList();
+void _XawTextPrepareToUpdate();
+int _XawTextReplace();
+
+static void ParameterError(w, param)
+ Widget w;
+ String param;
+{
+ String params[2];
+ Cardinal num_params = 2;
+ params[0] = XtName(w);
+ params[1] = param;
+
+ XtAppWarningMsg( XtWidgetToApplicationContext(w),
+ "parameterError", "textAction", "XawError",
+ "Widget: %s Parameter: %s",
+ params, &num_params);
+ XBell( XtDisplay( w ), 50 );
+}
+
+static void
+StartAction(ctx, event)
+TextWidget ctx;
+XEvent *event;
+{
+ _XawTextPrepareToUpdate(ctx);
+ if (event != NULL) {
+ switch (event->type) {
+ case ButtonPress:
+ case ButtonRelease:
+ ctx->text.time = event->xbutton.time;
+ break;
+ case KeyPress:
+ case KeyRelease:
+ ctx->text.time = event->xkey.time;
+ break;
+ case MotionNotify:
+ ctx->text.time = event->xmotion.time;
+ break;
+ case EnterNotify:
+ case LeaveNotify:
+ ctx->text.time = event->xcrossing.time;
+ }
+ }
+}
+
+static void
+NotePosition(ctx, event)
+TextWidget ctx;
+XEvent* event;
+{
+ switch (event->type) {
+ case ButtonPress:
+ case ButtonRelease:
+ ctx->text.ev_x = event->xbutton.x;
+ ctx->text.ev_y = event->xbutton.y;
+ break;
+ case KeyPress:
+ case KeyRelease:
+ {
+ XRectangle cursor;
+ XawTextSinkGetCursorBounds(ctx->text.sink, &cursor);
+ ctx->text.ev_x = cursor.x + cursor.width / 2;;
+ ctx->text.ev_y = cursor.y + cursor.height / 2;;
+ }
+ break;
+ case MotionNotify:
+ ctx->text.ev_x = event->xmotion.x;
+ ctx->text.ev_y = event->xmotion.y;
+ break;
+ case EnterNotify:
+ case LeaveNotify:
+ ctx->text.ev_x = event->xcrossing.x;
+ ctx->text.ev_y = event->xcrossing.y;
+ }
+}
+
+static void
+EndAction(ctx)
+TextWidget ctx;
+{
+ _XawTextCheckResize(ctx);
+ _XawTextExecuteUpdate(ctx);
+ ctx->text.mult = 1;
+}
+
+
+struct _SelectionList {
+ String* params;
+ Cardinal count;
+ Time time;
+ Boolean CT_asked; /* flag if asked XA_COMPOUND_TEXT */
+ Atom selection; /* selection atom when asking XA_COMPOUND_TEXT */
+};
+
+static int ProbablyMB(s)
+ char* s;
+{
+ int escapes = 0;
+ int has_hi_bit = False;
+
+ /* if it has more than one ESC char, I assume it is COMPOUND_TEXT.
+ If it has at least one hi bit set character, I pretend it is multibyte. */
+
+ while ( (wchar_t)(*s) != (wchar_t)0 ) {
+ if ( *s & 128 )
+ has_hi_bit = True;
+ if ( *s++ == '\033' )
+ escapes++;
+ if ( escapes >= 2 )
+ return( 0 );
+ }
+ return( has_hi_bit );
+}
+static void GetSelection();
+
+/* ARGSUSED */
+static void
+_SelectionReceived(w, client_data, selection, type, value, length, format)
+Widget w;
+XtPointer client_data;
+Atom *selection, *type;
+XtPointer value;
+unsigned long *length;
+int* format;
+{
+ TextWidget ctx = (TextWidget)w;
+ XawTextBlock text;
+
+ if (*type == 0 /*XT_CONVERT_FAIL*/ || *length == 0) {
+ struct _SelectionList* list = (struct _SelectionList*)client_data;
+ if (list != NULL) {
+ if (list->CT_asked) {
+
+ /* If we just asked for a XA_COMPOUND_TEXT and got a null
+ response, we'll ask again, this time for an XA_STRING. */
+
+ list->CT_asked = False;
+ XtGetSelectionValue(w, list->selection, XA_STRING, _SelectionReceived,
+ (XtPointer)list, list->time);
+ } else {
+ GetSelection(w, list->time, list->params, list->count);
+ XtFree(client_data);
+ }
+ }
+ return;
+ }
+
+ /* Many programs, especially old terminal emulators, give us multibyte text
+but tell us it is COMPOUND_TEXT :( The following routine checks to see if the
+string is a legal multibyte string in our locale using a spooky heuristic :O
+and if it is we can only assume the sending client is using the same locale as
+we are, and convert it. I also warn the user that the other client is evil. */
+
+ StartAction( ctx, (XEvent*) NULL );
+#ifdef XAW_INTERNATIONALIZATION
+ if (_XawTextFormat(ctx) == XawFmtWide) {
+ XTextProperty textprop;
+ Display *d = XtDisplay((Widget)ctx);
+ wchar_t **wlist;
+ int count;
+ int try_CT = 1;
+
+ /* IS THE SELECTION IN MULTIBYTE FORMAT? */
+
+ if ( ProbablyMB( (char *) value ) ) {
+ char * list[1];
+ list[0] = (char *) value;
+ if ( XmbTextListToTextProperty( d, (char**) list, 1,
+ XCompoundTextStyle, &textprop ) == Success )
+ try_CT = 0;
+ }
+
+ /* OR IN COMPOUND TEXT FORMAT? */
+
+ if ( try_CT ) {
+ textprop.encoding = XA_COMPOUND_TEXT(d);
+ textprop.value = (unsigned char *)value;
+ textprop.nitems = strlen(value);
+ textprop.format = 8;
+ }
+
+ if ( XwcTextPropertyToTextList( d, &textprop, (wchar_t***) &wlist, &count )
+ != Success) {
+ XwcFreeStringList( (wchar_t**) wlist );
+
+ /* Notify the user on strerr and in the insertion :) */
+ textprop.value = (unsigned char *) " >> ILLEGAL SELECTION << ";
+ count = 1;
+ fprintf( stderr, "Xaw Text Widget: An attempt was made to insert an illegal selection.\n" );
+
+ if ( XwcTextPropertyToTextList( d, &textprop, (wchar_t***) &wlist, &count )
+ != Success) return;
+ }
+
+ XFree(value);
+ value = (XPointer)wlist[0];
+
+ *length = wcslen(wlist[0]);
+ XtFree((XtPointer)wlist);
+ text.format = XawFmtWide;
+ } else
+#endif
+ text.format = XawFmt8Bit;
+ text.ptr = (char*)value;
+ text.firstPos = 0;
+ text.length = *length;
+ if (_XawTextReplace(ctx, ctx->text.insertPos, ctx->text.insertPos, &text)) {
+ XBell(XtDisplay(ctx), 0);
+ return;
+ }
+ ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.insertPos,
+ XawstPositions, XawsdRight, text.length, TRUE);
+
+ _XawTextSetScrollBars(ctx);
+ EndAction(ctx);
+ XtFree(client_data);
+ XFree(value); /* the selection value should be freed with XFree */
+}
+
+static void
+GetSelection(w, time, params, num_params)
+Widget w;
+Time time;
+String* params; /* selections in precedence order */
+Cardinal num_params;
+{
+ Atom selection;
+ int buffer;
+
+ selection = XInternAtom(XtDisplay(w), *params, False);
+
+ switch (selection) {
+ case XA_CUT_BUFFER0: buffer = 0; break;
+ case XA_CUT_BUFFER1: buffer = 1; break;
+ case XA_CUT_BUFFER2: buffer = 2; break;
+ case XA_CUT_BUFFER3: buffer = 3; break;
+ case XA_CUT_BUFFER4: buffer = 4; break;
+ case XA_CUT_BUFFER5: buffer = 5; break;
+ case XA_CUT_BUFFER6: buffer = 6; break;
+ case XA_CUT_BUFFER7: buffer = 7; break;
+ default: buffer = -1;
+ }
+ if (buffer >= 0) {
+ int nbytes;
+ unsigned long length;
+ int fmt8 = 8;
+ Atom type = XA_STRING;
+ char *line = XFetchBuffer(XtDisplay(w), &nbytes, buffer);
+ if ((length = nbytes))
+ _SelectionReceived(w, (XtPointer) NULL, &selection, &type, (XPointer)line,
+ &length, &fmt8);
+ else if (num_params > 1)
+ GetSelection(w, time, params+1, num_params-1);
+ } else {
+ struct _SelectionList* list;
+ if (--num_params) {
+ list = XtNew(struct _SelectionList);
+ list->params = params + 1;
+ list->count = num_params;
+ list->time = time;
+ list->CT_asked = True;
+ list->selection = selection;
+ } else list = NULL;
+ XtGetSelectionValue(w, selection, XA_COMPOUND_TEXT(XtDisplay(w)),
+ _SelectionReceived, (XtPointer)list, time);
+ }
+}
+
+static void
+InsertSelection(w, event, params, num_params)
+Widget w;
+XEvent* event;
+String* params; /* precedence list of selections to try */
+Cardinal* num_params;
+{
+ StartAction((TextWidget)w, event); /* Get Time. */
+ GetSelection(w, ((TextWidget)w)->text.time, params, *num_params);
+ EndAction((TextWidget)w);
+}
+
+/************************************************************
+ *
+ * Routines for Moving Around.
+ *
+ ************************************************************/
+
+static void
+Move(ctx, event, dir, type, include)
+TextWidget ctx;
+XEvent* event;
+XawTextScanDirection dir;
+XawTextScanType type;
+Boolean include;
+{
+ StartAction(ctx, event);
+ ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.insertPos,
+ type, dir, ctx->text.mult, include);
+ EndAction(ctx);
+}
+
+/*ARGSUSED*/
+static void
+MoveForwardChar(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ Move((TextWidget) w, event, XawsdRight, XawstPositions, TRUE);
+}
+
+/*ARGSUSED*/
+static void
+MoveBackwardChar(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ Move((TextWidget) w, event, XawsdLeft, XawstPositions, TRUE);
+}
+
+/*ARGSUSED*/
+static void
+MoveForwardWord(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ Move((TextWidget) w, event, XawsdRight, XawstWhiteSpace, FALSE);
+}
+
+/*ARGSUSED*/
+static void
+MoveBackwardWord(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ Move((TextWidget) w, event, XawsdLeft, XawstWhiteSpace, FALSE);
+}
+
+/*ARGSUSED*/
+static void MoveForwardParagraph(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ Move((TextWidget) w, event, XawsdRight, XawstParagraph, FALSE);
+}
+
+/*ARGSUSED*/
+static void MoveBackwardParagraph(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ Move((TextWidget) w, event, XawsdLeft, XawstParagraph, FALSE);
+}
+
+/*ARGSUSED*/
+static void
+MoveToLineEnd(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ Move((TextWidget) w, event, XawsdRight, XawstEOL, FALSE);
+}
+
+/*ARGSUSED*/
+static void
+MoveToLineStart(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ Move((TextWidget) w, event, XawsdLeft, XawstEOL, FALSE);
+}
+
+
+static void
+MoveLine(ctx, event, dir)
+TextWidget ctx;
+XEvent* event;
+XawTextScanDirection dir;
+{
+ XawTextPosition new, next_line, junk;
+ int from_left, garbage;
+
+ StartAction(ctx, event);
+
+ if (dir == XawsdLeft)
+ ctx->text.mult++;
+
+ new = SrcScan(ctx->text.source, ctx->text.insertPos,
+ XawstEOL, XawsdLeft, 1, FALSE);
+
+ FindDist(ctx->text.sink, new, ctx->text.margin.left, ctx->text.insertPos,
+ &from_left, &junk, &garbage);
+
+ new = SrcScan(ctx->text.source, ctx->text.insertPos, XawstEOL, dir,
+ ctx->text.mult, (dir == XawsdRight));
+
+ next_line = SrcScan(ctx->text.source, new, XawstEOL, XawsdRight, 1, FALSE);
+
+ FindPos(ctx->text.sink, new, ctx->text.margin.left, from_left, FALSE,
+ &(ctx->text.insertPos), &garbage, &garbage);
+
+ if (ctx->text.insertPos > next_line)
+ ctx->text.insertPos = next_line;
+
+ EndAction(ctx);
+}
+
+/*ARGSUSED*/
+static void
+MoveNextLine(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ MoveLine( (TextWidget) w, event, XawsdRight);
+}
+
+/*ARGSUSED*/
+static void
+MovePreviousLine(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ MoveLine( (TextWidget) w, event, XawsdLeft);
+}
+
+/*ARGSUSED*/
+static void
+MoveBeginningOfFile(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ Move((TextWidget) w, event, XawsdLeft, XawstAll, TRUE);
+}
+
+/*ARGSUSED*/
+static void
+MoveEndOfFile(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ Move((TextWidget) w, event, XawsdRight, XawstAll, TRUE);
+}
+
+static void
+Scroll(ctx, event, dir)
+TextWidget ctx;
+XEvent* event;
+XawTextScanDirection dir;
+{
+ StartAction(ctx, event);
+
+ if (dir == XawsdLeft)
+ _XawTextVScroll(ctx, ctx->text.mult);
+ else
+ _XawTextVScroll(ctx, -ctx->text.mult);
+
+ EndAction(ctx);
+}
+
+/*ARGSUSED*/
+static void
+ScrollOneLineUp(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ Scroll( (TextWidget) w, event, XawsdLeft);
+}
+
+/*ARGSUSED*/
+static void
+ScrollOneLineDown(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ Scroll( (TextWidget) w, event, XawsdRight);
+}
+
+static void
+MovePage(ctx, event, dir)
+TextWidget ctx;
+XEvent* event;
+XawTextScanDirection dir;
+{
+ int scroll_val = Max(1, ctx->text.lt.lines - 2);
+
+ if (dir == XawsdLeft)
+ scroll_val = -scroll_val;
+
+ StartAction(ctx, event);
+ _XawTextVScroll(ctx, scroll_val);
+ ctx->text.insertPos = ctx->text.lt.top;
+ EndAction(ctx);
+}
+
+/*ARGSUSED*/
+static void
+MoveNextPage(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ MovePage((TextWidget) w, event, XawsdRight);
+}
+
+/*ARGSUSED*/
+static void
+MovePreviousPage(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ MovePage((TextWidget) w, event, XawsdLeft);
+}
+
+/************************************************************
+ *
+ * Delete Routines.
+ *
+ ************************************************************/
+
+static Boolean
+MatchSelection(selection, s)
+ Atom selection;
+ XawTextSelection* s;
+{
+ Atom *match;
+ int count;
+
+ for (count = 0, match = s->selections; count < s->atom_count; match++, count++)
+ if (*match == selection)
+ return True;
+ return False;
+}
+
+#define SrcCvtSel XawTextSourceConvertSelection
+
+static Boolean
+ConvertSelection(w, selection, target, type, value, length, format)
+ Widget w;
+ Atom *selection, *target, *type;
+ XtPointer* value;
+ unsigned long* length;
+ int* format;
+{
+ Display* d = XtDisplay(w);
+ TextWidget ctx = (TextWidget)w;
+ Widget src = ctx->text.source;
+ XawTextEditType edit_mode;
+ Arg args[1];
+ XawTextSelectionSalt *salt = NULL;
+ XawTextSelection *s;
+
+ if (*target == XA_TARGETS(d)) {
+ Atom* targetP, * std_targets;
+ unsigned long std_length;
+
+ if ( SrcCvtSel(src, selection, target, type, value, length, format) )
+ return True;
+
+ XmuConvertStandardSelection(w, ctx->text.time, selection,
+ target, type, (XPointer*)&std_targets,
+ &std_length, format);
+
+ *value = XtMalloc((unsigned) sizeof(Atom)*(std_length + 7));
+ targetP = *(Atom**)value;
+
+ *length = std_length + 6;
+ *targetP++ = XA_STRING;
+ *targetP++ = XA_TEXT(d);
+ *targetP++ = XA_COMPOUND_TEXT(d);
+ *targetP++ = XA_LENGTH(d);
+ *targetP++ = XA_LIST_LENGTH(d);
+ *targetP++ = XA_CHARACTER_POSITION(d);
+
+ XtSetArg(args[0], XtNeditType,&edit_mode);
+ XtGetValues(src, args, 1);
+
+ if (edit_mode == XawtextEdit) {
+ *targetP++ = XA_DELETE(d);
+ (*length)++;
+ }
+ memcpy((char*)targetP, (char*)std_targets, sizeof(Atom)*std_length);
+ XtFree((char*)std_targets);
+ *type = XA_ATOM;
+ *format = 32;
+ return True;
+ }
+
+ if ( SrcCvtSel(src, selection, target, type, value, length, format) )
+ return True;
+
+ for (salt = ctx->text.salt2; salt; salt = salt->next)
+ if (MatchSelection (*selection, &salt->s))
+ break;
+ if (!salt)
+ return False;
+ s = &salt->s;
+ if (*target == XA_STRING ||
+ *target == XA_TEXT(d) ||
+ *target == XA_COMPOUND_TEXT(d)) {
+ if (*target == XA_TEXT(d)) {
+#ifdef XAW_INTERNATIONALIZATION
+ if (_XawTextFormat(ctx) == XawFmtWide)
+ *type = XA_COMPOUND_TEXT(d);
+ else
+#endif
+ *type = XA_STRING;
+ } else {
+ *type = *target;
+ }
+ /*
+ * If salt is True, the salt->contents stores CT string,
+ * its length is measured in bytes.
+ * Refer to _XawTextSaltAwaySelection().
+ *
+ * by Li Yuhong, Mar. 20, 1991.
+ */
+ if (!salt) {
+ *value = (char *)_XawTextGetSTRING(ctx, s->left, s->right);
+#ifdef XAW_INTERNATIONALIZATION
+ if (_XawTextFormat(ctx) == XawFmtWide) {
+ XTextProperty textprop;
+ if (XwcTextListToTextProperty(d, (wchar_t**)value, 1,
+ XCompoundTextStyle, &textprop)
+ < Success) {
+ XtFree(*value);
+ return False;
+ }
+ XtFree(*value);
+ *value = (XtPointer)textprop.value;
+ *length = textprop.nitems;
+ } else
+#endif
+ {
+ *length = strlen(*value);
+ }
+ } else {
+ *value = XtMalloc((salt->length + 1) * sizeof(unsigned char));
+ strcpy (*value, salt->contents);
+ *length = salt->length;
+ }
+#ifdef XAW_INTERNATIONALIZATION
+ if (_XawTextFormat(ctx) == XawFmtWide && *type == XA_STRING) {
+ XTextProperty textprop;
+ wchar_t** wlist;
+ int count;
+ textprop.encoding = XA_COMPOUND_TEXT(d);
+ textprop.value = (unsigned char *)*value;
+ textprop.nitems = strlen(*value);
+ textprop.format = 8;
+ if (XwcTextPropertyToTextList(d, &textprop, (wchar_t***)&wlist, &count)
+ < Success) {
+ XtFree(*value);
+ return False;
+ }
+ XtFree(*value);
+ if (XwcTextListToTextProperty(d, (wchar_t**)wlist, 1,
+ XStringStyle, &textprop) < Success) {
+ XwcFreeStringList( (wchar_t**) wlist );
+ return False;
+ }
+ *value = (XtPointer)textprop.value;
+ *length = textprop.nitems;
+ XwcFreeStringList( (wchar_t**) wlist );
+ }
+#endif
+ *format = 8;
+ return True;
+ }
+
+ if ( (*target == XA_LIST_LENGTH(d)) || (*target == XA_LENGTH(d)) ) {
+ long * temp;
+
+ temp = (long *) XtMalloc(sizeof(long));
+ if (*target == XA_LIST_LENGTH(d))
+ *temp = 1L;
+ else /* *target == XA_LENGTH(d) */
+ *temp = (long) (s->right - s->left);
+
+ *value = (XPointer) temp;
+ *type = XA_INTEGER;
+ *length = 1L;
+ *format = 32;
+ return True;
+ }
+
+ if (*target == XA_CHARACTER_POSITION(d)) {
+ long * temp;
+
+ temp = (long *) XtMalloc(2 * sizeof(long));
+ temp[0] = (long) (s->left + 1);
+ temp[1] = s->right;
+ *value = (XPointer) temp;
+ *type = XA_SPAN(d);
+ *length = 2L;
+ *format = 32;
+ return True;
+ }
+
+ if (*target == XA_DELETE(d)) {
+ void _XawTextZapSelection(); /* From TextAction.c */
+
+ if (!salt)
+ _XawTextZapSelection( ctx, (XEvent *) NULL, TRUE);
+ *value = NULL;
+ *type = XA_NULL(d);
+ *length = 0;
+ *format = 32;
+ return True;
+ }
+
+ if (XmuConvertStandardSelection(w, ctx->text.time, selection, target, type,
+ (XPointer *)value, length, format))
+ return True;
+
+ /* else */
+ return False;
+}
+
+static void
+LoseSelection(w, selection)
+ Widget w;
+ Atom* selection;
+{
+ TextWidget ctx = (TextWidget) w;
+ Atom* atomP;
+ int i;
+ XawTextSelectionSalt *salt, *prevSalt, *nextSalt;
+
+ prevSalt = 0;
+ for (salt = ctx->text.salt2; salt; salt = nextSalt)
+ {
+ atomP = salt->s.selections;
+ nextSalt = salt->next;
+ for (i = 0 ; i < salt->s.atom_count; i++, atomP++)
+ if (*selection == *atomP)
+ *atomP = (Atom)0;
+
+ while (salt->s.atom_count &&
+ salt->s.selections[salt->s.atom_count-1] == 0)
+ {
+ salt->s.atom_count--;
+ }
+
+ /*
+ * Must walk the selection list in opposite order from UnsetSelection.
+ */
+
+ atomP = salt->s.selections;
+ for (i = 0 ; i < salt->s.atom_count; i++, atomP++)
+ if (*atomP == (Atom)0)
+ {
+ *atomP = salt->s.selections[--salt->s.atom_count];
+ while (salt->s.atom_count &&
+ salt->s.selections[salt->s.atom_count-1] == 0)
+ salt->s.atom_count--;
+ }
+ if (salt->s.atom_count == 0)
+ {
+ XtFree ((char *) salt->s.selections);
+
+ /* WARNING: the next line frees memory not allocated in Xaw. */
+ /* Could be a serious bug. Someone look into it. */
+ XtFree (salt->contents);
+ if (prevSalt)
+ prevSalt->next = nextSalt;
+ else
+ ctx->text.salt2 = nextSalt;
+ XtFree ((char *) salt);
+ }
+ else
+ prevSalt = salt;
+ }
+}
+
+static void
+_DeleteOrKill(ctx, from, to, kill)
+TextWidget ctx;
+XawTextPosition from, to;
+Boolean kill;
+{
+ XawTextBlock text;
+
+ if (kill && from < to) {
+ XawTextSelectionSalt *salt;
+ Atom selection = XInternAtom(XtDisplay(ctx), "SECONDARY", False);
+
+ LoseSelection ((Widget) ctx, &selection);
+ salt = (XawTextSelectionSalt *) XtMalloc (sizeof (XawTextSelectionSalt));
+ if (!salt)
+ return;
+ salt->s.selections = (Atom *) XtMalloc (sizeof (Atom));
+ if (!salt->s.selections)
+ {
+ XtFree ((char *) salt);
+ return;
+ }
+ salt->s.left = from;
+ salt->s.right = to;
+ salt->contents = (char *)_XawTextGetSTRING(ctx, from, to);
+#ifdef XAW_INTERNATIONALIZATION
+ if (_XawTextFormat(ctx) == XawFmtWide) {
+ XTextProperty textprop;
+ if (XwcTextListToTextProperty(XtDisplay((Widget)ctx),
+ (wchar_t**)(&(salt->contents)), 1, XCompoundTextStyle,
+ &textprop) < Success) {
+ XtFree(salt->contents);
+ salt->length = 0;
+ return;
+ }
+ XtFree(salt->contents);
+ salt->contents = (char *)textprop.value;
+ salt->length = textprop.nitems;
+ } else
+#endif
+ salt->length = strlen (salt->contents);
+ salt->next = ctx->text.salt2;
+ ctx->text.salt2 = salt;
+ salt->s.selections[0] = selection;
+ XtOwnSelection ((Widget) ctx, selection, ctx->text.time,
+ ConvertSelection, LoseSelection, NULL);
+ salt->s.atom_count = 1;
+/*
+ XStoreBuffer(XtDisplay(ctx), ptr, strlen(ptr), 1);
+ XtFree(ptr);
+*/
+ }
+ text.length = 0;
+ text.firstPos = 0;
+
+ text.format = _XawTextFormat(ctx);
+ text.ptr = ""; /* These two lines needed to make legal TextBlock */
+
+ if (_XawTextReplace(ctx, from, to, &text)) {
+ XBell(XtDisplay(ctx), 50);
+ return;
+ }
+ ctx->text.insertPos = from;
+ ctx->text.showposition = TRUE;
+}
+
+static void
+DeleteOrKill(ctx, event, dir, type, include, kill)
+TextWidget ctx;
+XEvent* event;
+XawTextScanDirection dir;
+XawTextScanType type;
+Boolean include, kill;
+{
+ XawTextPosition from, to;
+
+ StartAction(ctx, event);
+ to = SrcScan(ctx->text.source, ctx->text.insertPos,
+ type, dir, ctx->text.mult, include);
+
+/*
+ * If no movement actually happened, then bump the count and try again.
+ * This causes the character position at the very beginning and end of
+ * a boundary to act correctly.
+ */
+
+ if (to == ctx->text.insertPos)
+ to = SrcScan(ctx->text.source, ctx->text.insertPos,
+ type, dir, ctx->text.mult + 1, include);
+
+ if (dir == XawsdLeft) {
+ from = to;
+ to = ctx->text.insertPos;
+ }
+ else
+ from = ctx->text.insertPos;
+
+ _DeleteOrKill(ctx, from, to, kill);
+ _XawTextSetScrollBars(ctx);
+ EndAction(ctx);
+}
+
+/*ARGSUSED*/
+static void
+DeleteForwardChar(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ DeleteOrKill((TextWidget) w, event, XawsdRight, XawstPositions, TRUE, FALSE);
+}
+
+/*ARGSUSED*/
+static void
+DeleteBackwardChar(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ DeleteOrKill((TextWidget) w, event, XawsdLeft, XawstPositions, TRUE, FALSE);
+}
+
+/*ARGSUSED*/
+static void
+DeleteForwardWord(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ DeleteOrKill((TextWidget) w, event,
+ XawsdRight, XawstWhiteSpace, FALSE, FALSE);
+}
+
+/*ARGSUSED*/
+static void
+DeleteBackwardWord(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ DeleteOrKill((TextWidget) w, event,
+ XawsdLeft, XawstWhiteSpace, FALSE, FALSE);
+}
+
+/*ARGSUSED*/
+static void
+KillForwardWord(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ DeleteOrKill((TextWidget) w, event,
+ XawsdRight, XawstWhiteSpace, FALSE, TRUE);
+}
+
+/*ARGSUSED*/
+static void
+KillBackwardWord(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ DeleteOrKill((TextWidget) w, event,
+ XawsdLeft, XawstWhiteSpace, FALSE, TRUE);
+}
+
+/*ARGSUSED*/
+static void
+KillToEndOfLine(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ TextWidget ctx = (TextWidget) w;
+ XawTextPosition end_of_line;
+
+ StartAction(ctx, event);
+ end_of_line = SrcScan(ctx->text.source, ctx->text.insertPos, XawstEOL,
+ XawsdRight, ctx->text.mult, FALSE);
+ if (end_of_line == ctx->text.insertPos)
+ end_of_line = SrcScan(ctx->text.source, ctx->text.insertPos, XawstEOL,
+ XawsdRight, ctx->text.mult, TRUE);
+
+ _DeleteOrKill(ctx, ctx->text.insertPos, end_of_line, TRUE);
+ _XawTextSetScrollBars(ctx);
+ EndAction(ctx);
+}
+
+/*ARGSUSED*/
+static void
+KillToEndOfParagraph(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ DeleteOrKill((TextWidget) w, event, XawsdRight, XawstParagraph, FALSE, TRUE);
+}
+
+void
+_XawTextZapSelection(ctx, event, kill)
+TextWidget ctx;
+XEvent* event;
+Boolean kill;
+{
+ StartAction(ctx, event);
+ _DeleteOrKill(ctx, ctx->text.s.left, ctx->text.s.right, kill);
+ _XawTextSetScrollBars(ctx);
+ EndAction(ctx);
+}
+
+/*ARGSUSED*/
+static void
+KillCurrentSelection(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ _XawTextZapSelection( (TextWidget) w, event, TRUE);
+}
+
+/*ARGSUSED*/
+static void
+DeleteCurrentSelection(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ _XawTextZapSelection( (TextWidget) w, event, FALSE);
+}
+
+/************************************************************
+ *
+ * Insertion Routines.
+ *
+ ************************************************************/
+
+static int
+InsertNewLineAndBackupInternal(ctx)
+TextWidget ctx;
+{
+ int count, error = XawEditDone;
+ XawTextBlock text;
+
+ text.format = _XawTextFormat(ctx);
+ text.length = ctx->text.mult;
+ text.firstPos = 0;
+
+#ifdef XAW_INTERNATIONALIZATION
+ if ( text.format == XawFmtWide ) {
+ wchar_t* wptr;
+ text.ptr = XtMalloc(sizeof(wchar_t) * ctx->text.mult);
+ wptr = (wchar_t *)text.ptr;
+ for (count = 0; count < ctx->text.mult; count++ )
+ wptr[count] = _Xaw_atowc(XawLF);
+ }
+ else
+#endif
+ {
+ text.ptr = XtMalloc(sizeof(char) * ctx->text.mult);
+ for (count = 0; count < ctx->text.mult; count++ )
+ text.ptr[count] = XawLF;
+ }
+
+ if (_XawTextReplace(ctx, ctx->text.insertPos, ctx->text.insertPos, &text)) {
+ XBell( XtDisplay(ctx), 50);
+ error = XawEditError;
+ }
+ else
+ ctx->text.showposition = TRUE;
+
+ XtFree( text.ptr );
+ return( error );
+}
+
+/*ARGSUSED*/
+static void
+InsertNewLineAndBackup(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ StartAction( (TextWidget) w, event );
+ (void) InsertNewLineAndBackupInternal( (TextWidget) w );
+ _XawTextSetScrollBars( (TextWidget) w);
+ EndAction( (TextWidget) w );
+}
+
+static int
+LocalInsertNewLine(ctx, event)
+ TextWidget ctx;
+ XEvent* event;
+{
+ StartAction(ctx, event);
+ if (InsertNewLineAndBackupInternal(ctx) == XawEditError)
+ return(XawEditError);
+ ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.insertPos,
+ XawstPositions, XawsdRight, ctx->text.mult, TRUE);
+ _XawTextSetScrollBars(ctx);
+ EndAction(ctx);
+ return(XawEditDone);
+}
+
+/*ARGSUSED*/
+static void
+InsertNewLine(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ (void) LocalInsertNewLine( (TextWidget) w, event);
+}
+
+/*ARGSUSED*/
+static void
+InsertNewLineAndIndent(w, event, p, n)
+Widget w;
+XEvent *event;
+String *p;
+Cardinal *n;
+{
+ XawTextBlock text;
+ XawTextPosition pos1;
+ int length;
+ TextWidget ctx = (TextWidget) w;
+ String line_to_ip;
+
+ StartAction(ctx, event);
+ pos1 = SrcScan(ctx->text.source, ctx->text.insertPos,
+ XawstEOL, XawsdLeft, 1, FALSE);
+
+ line_to_ip = _XawTextGetText(ctx, pos1, ctx->text.insertPos);
+
+ text.format = _XawTextFormat(ctx);
+ text.firstPos = 0;
+
+#ifdef XAW_INTERNATIONALIZATION
+ if ( text.format == XawFmtWide ) {
+ wchar_t* ptr;
+ text.ptr = XtMalloc( ( 2 + wcslen((wchar_t*)line_to_ip) ) * sizeof(wchar_t) );
+
+ ptr = (wchar_t*)text.ptr;
+ ptr[0] = _Xaw_atowc( XawLF );
+ wcscpy( (wchar_t*) ++ptr, (wchar_t*) line_to_ip );
+
+ length = wcslen((wchar_t*)text.ptr);
+ while ( length && ( iswspace(*ptr) || ( *ptr == _Xaw_atowc(XawTAB) ) ) )
+ ptr++, length--;
+ *ptr = (wchar_t)0;
+ text.length = wcslen((wchar_t*)text.ptr);
+
+ } else
+#endif
+ {
+ char *ptr;
+ length = strlen(line_to_ip);
+ /* The current line + \0 and LF will be copied to this
+ buffer. Before my fix, only length + 1 bytes were
+ allocated, causing on machine with non-wasteful
+ malloc implementation segmentation violations by
+ overwriting the bypte after the allocated area
+
+ -gustaf neumann
+ */
+ text.ptr = XtMalloc( ( 2 + length ) * sizeof( char ) );
+
+ ptr = text.ptr;
+ ptr[0] = XawLF;
+ strcpy( ++ptr, line_to_ip );
+
+ length++;
+ while ( length && ( isspace(*ptr) || ( *ptr == XawTAB ) ) )
+ ptr++, length--;
+ *ptr = '\0';
+ text.length = strlen(text.ptr);
+ }
+ XtFree( line_to_ip );
+
+ if (_XawTextReplace(ctx,ctx->text.insertPos, ctx->text.insertPos, &text)) {
+ XBell(XtDisplay(ctx), 50);
+ XtFree(text.ptr);
+ EndAction(ctx);
+ return;
+ }
+ XtFree(text.ptr);
+ ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.insertPos,
+ XawstPositions, XawsdRight, text.length, TRUE);
+ _XawTextSetScrollBars(ctx);
+ EndAction(ctx);
+}
+
+/************************************************************
+ *
+ * Selection Routines.
+ *
+ *************************************************************/
+
+static void
+SelectWord(w, event, params, num_params)
+Widget w;
+XEvent* event;
+String* params;
+Cardinal* num_params;
+{
+ TextWidget ctx = (TextWidget) w;
+ XawTextPosition l, r;
+
+ StartAction(ctx, event);
+ l = SrcScan(ctx->text.source, ctx->text.insertPos,
+ XawstWhiteSpace, XawsdLeft, 1, FALSE);
+ r = SrcScan(ctx->text.source, l, XawstWhiteSpace, XawsdRight, 1, FALSE);
+ _XawTextSetSelection(ctx, l, r, params, *num_params);
+ EndAction(ctx);
+}
+
+static void
+SelectAll(w, event, params, num_params)
+Widget w;
+XEvent* event;
+String* params;
+Cardinal* num_params;
+{
+ TextWidget ctx = (TextWidget) w;
+
+ StartAction(ctx, event);
+ _XawTextSetSelection(ctx,zeroPosition,ctx->text.lastPos,params,*num_params);
+ EndAction(ctx);
+}
+
+static void
+ModifySelection(ctx, event, mode, action, params, num_params)
+TextWidget ctx;
+XEvent* event;
+XawTextSelectionMode mode;
+XawTextSelectionAction action;
+String* params; /* unused */
+Cardinal* num_params; /* unused */
+{
+ StartAction(ctx, event);
+ NotePosition(ctx, event);
+ _XawTextAlterSelection(ctx, mode, action, params, num_params);
+ EndAction(ctx);
+}
+
+/* ARGSUSED */
+static void
+SelectStart(w, event, params, num_params)
+Widget w;
+XEvent* event;
+String* params; /* unused */
+Cardinal* num_params; /* unused */
+{
+ ModifySelection((TextWidget) w, event,
+ XawsmTextSelect, XawactionStart, params, num_params);
+}
+
+/* ARGSUSED */
+static void
+SelectAdjust(w, event, params, num_params)
+Widget w;
+XEvent* event;
+String* params; /* unused */
+Cardinal* num_params; /* unused */
+{
+ ModifySelection((TextWidget) w, event,
+ XawsmTextSelect, XawactionAdjust, params, num_params);
+}
+
+static void
+SelectEnd(w, event, params, num_params)
+Widget w;
+XEvent* event;
+String* params;
+Cardinal* num_params;
+{
+ ModifySelection((TextWidget) w, event,
+ XawsmTextSelect, XawactionEnd, params, num_params);
+}
+
+/* ARGSUSED */
+static void
+ExtendStart(w, event, params, num_params)
+Widget w;
+XEvent* event;
+String* params; /* unused */
+Cardinal* num_params; /* unused */
+{
+ ModifySelection((TextWidget) w, event,
+ XawsmTextExtend, XawactionStart, params, num_params);
+}
+
+/* ARGSUSED */
+static void
+ExtendAdjust(w, event, params, num_params)
+Widget w;
+XEvent* event;
+String* params; /* unused */
+Cardinal* num_params; /* unused */
+{
+ ModifySelection((TextWidget) w, event,
+ XawsmTextExtend, XawactionAdjust, params, num_params);
+}
+
+static void
+ExtendEnd(w, event, params, num_params)
+Widget w;
+XEvent* event;
+String* params;
+Cardinal* num_params;
+{
+ ModifySelection((TextWidget) w, event,
+ XawsmTextExtend, XawactionEnd, params, num_params);
+}
+
+static void
+SelectSave(w, event, params, num_params)
+Widget w;
+XEvent* event;
+String* params;
+Cardinal* num_params;
+{
+ int num_atoms;
+ Atom* sel;
+ Display* dpy = XtDisplay(w);
+ Atom selections[256];
+
+ StartAction( (TextWidget) w, event );
+ num_atoms = *num_params;
+ if (num_atoms > 256)
+ num_atoms = 256;
+ for (sel=selections; --num_atoms >= 0; sel++, params++)
+ *sel = XInternAtom(dpy, *params, False);
+ num_atoms = *num_params;
+ _XawTextSaltAwaySelection( (TextWidget) w, selections, num_atoms );
+ EndAction( (TextWidget) w );
+}
+
+/************************************************************
+ *
+ * Misc. Routines.
+ *
+ ************************************************************/
+
+/* ARGSUSED */
+static void
+RedrawDisplay(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ StartAction( (TextWidget) w, event);
+ _XawTextClearAndCenterDisplay((TextWidget) w);
+ EndAction( (TextWidget) w);
+}
+
+/*ARGSUSED*/
+static void
+TextFocusIn (w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ TextWidget ctx = (TextWidget) w;
+
+ /* Let the input method know focus has arrived. */
+#ifdef XAW_INTERNATIONALIZATION
+ _XawImSetFocusValues (w, NULL, 0);
+#endif
+ if ( event->xfocus.detail == NotifyPointer ) return;
+
+ ctx->text.hasfocus = TRUE;
+}
+
+/*ARGSUSED*/
+static void
+TextFocusOut(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ TextWidget ctx = (TextWidget) w;
+
+ /* Let the input method know focus has left.*/
+#ifdef XAW_INTERNATIONALIZATION
+ _XawImUnsetFocus(w);
+#endif
+ if ( event->xfocus.detail == NotifyPointer ) return;
+ ctx->text.hasfocus = FALSE;
+}
+
+/*ARGSUSED*/
+static void
+TextEnterWindow( w, event, params, num_params )
+ Widget w;
+ XEvent* event;
+ String* params;
+ Cardinal* num_params;
+{
+ TextWidget ctx = (TextWidget) w;
+
+#ifdef XAW_INTERNATIONALIZATION
+ if ((event->xcrossing.detail != NotifyInferior) && event->xcrossing.focus &&
+ !ctx->text.hasfocus) {
+ _XawImSetFocusValues(w, NULL, 0);
+ }
+#endif
+}
+
+/*ARGSUSED*/
+static void
+TextLeaveWindow( w, event, params, num_params )
+ Widget w;
+ XEvent* event;
+ String* params;
+ Cardinal* num_params;
+{
+ TextWidget ctx = (TextWidget) w;
+
+#ifdef XAW_INTERNATIONALIZATION
+ if ((event->xcrossing.detail != NotifyInferior) && event->xcrossing.focus &&
+ !ctx->text.hasfocus) {
+ _XawImUnsetFocus(w);
+ }
+#endif
+}
+
+static XComposeStatus compose_status = {NULL, 0};
+
+/* Function Name: AutoFill
+ * Description: Breaks the line at the previous word boundry when
+ * called inside InsertChar.
+ * Arguments: ctx - The text widget.
+ * Returns: none
+ */
+
+static void
+AutoFill(ctx)
+TextWidget ctx;
+{
+ int width, height, x, line_num, max_width;
+ XawTextPosition ret_pos;
+ XawTextBlock text;
+
+ if ( !((ctx->text.auto_fill) && (ctx->text.mult == 1)) )
+ return;
+
+ for ( line_num = 0; line_num < ctx->text.lt.lines ; line_num++)
+ if ( ctx->text.lt.info[line_num].position >= ctx->text.insertPos )
+ break;
+ line_num--; /* backup a line. */
+
+ max_width = Max(0, (int)(ctx->core.width - HMargins(ctx)));
+
+ x = ctx->text.margin.left;
+ XawTextSinkFindPosition( ctx->text.sink,ctx->text.lt.info[line_num].position,
+ x, max_width, TRUE, &ret_pos, &width, &height);
+
+ if ( ret_pos >= ctx->text.insertPos )
+ return;
+
+ text.format = XawFmt8Bit;
+#ifdef XAW_INTERNATIONALIZATION
+ if (_XawTextFormat(ctx) == XawFmtWide) {
+ text.format = XawFmtWide;
+ text.ptr = (char *)XtMalloc(sizeof(wchar_t) * 2);
+ ((wchar_t*)text.ptr)[0] = _Xaw_atowc(XawLF);
+ ((wchar_t*)text.ptr)[1] = 0;
+ } else
+#endif
+ text.ptr = "\n";
+ text.length = 1;
+ text.firstPos = 0;
+
+ if (_XawTextReplace(ctx, ret_pos - 1, ret_pos, &text))
+ XBell(XtDisplay((Widget) ctx), 0); /* Unable to edit, complain. */
+}
+
+/*ARGSUSED*/
+static void
+InsertChar(w, event, p, n)
+Widget w;
+XEvent* event;
+String* p;
+Cardinal* n;
+{
+ TextWidget ctx = (TextWidget) w;
+ char *ptr, strbuf[BUFSIZ];
+ int count, error;
+ KeySym keysym;
+ XawTextBlock text;
+
+#ifdef XAW_INTERNATIONALIZATION
+ if (XtIsSubclass (ctx->text.source, (WidgetClass) multiSrcObjectClass))
+ text.length = _XawImWcLookupString (w, &event->xkey,
+ (wchar_t*) strbuf, BUFSIZ, &keysym, (Status*) &compose_status);
+ else
+#endif
+ text.length = XLookupString ((XKeyEvent*)event, strbuf, BUFSIZ, &keysym, &compose_status);
+
+ if (text.length == 0)
+ return;
+
+ text.format = _XawTextFormat( ctx );
+#ifdef XAW_INTERNATIONALIZATION
+ if ( text.format == XawFmtWide ) {
+ text.ptr = ptr = XtMalloc(sizeof(wchar_t) * text.length * ctx->text.mult );
+ for (count = 0; count < ctx->text.mult; count++ ) {
+ memcpy((char*) ptr, (char *)strbuf, sizeof(wchar_t) * text.length );
+ ptr += sizeof(wchar_t) * text.length;
+ }
+
+ } else
+#endif
+ { /* == XawFmt8Bit */
+ text.ptr = ptr = XtMalloc( sizeof(char) * text.length * ctx->text.mult );
+ for ( count = 0; count < ctx->text.mult; count++ ) {
+ strncpy( ptr, strbuf, text.length );
+ ptr += text.length;
+ }
+ }
+
+ text.length = text.length * ctx->text.mult;
+ text.firstPos = 0;
+
+ StartAction(ctx, event);
+
+ error = _XawTextReplace(ctx, ctx->text.insertPos,ctx->text.insertPos, &text);
+
+ if (error == XawEditDone) {
+ ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.insertPos,
+ XawstPositions, XawsdRight, text.length, TRUE);
+ AutoFill(ctx);
+ }
+ else
+ XBell(XtDisplay(ctx), 50);
+
+ XtFree(text.ptr);
+ _XawTextSetScrollBars(ctx);
+ EndAction(ctx);
+}
+
+
+/* IfHexConvertHexElseReturnParam() - called by InsertString
+ *
+ * i18n requires the ability to specify multiple characters in a hexa-
+ * decimal string at once. Since Insert was already too long, I made
+ * this a seperate routine.
+ *
+ * A legal hex string in MBNF: '0' 'x' ( HEX-DIGIT HEX-DIGIT )+ '\0'
+ *
+ * WHEN: the passed param is a legal hex string
+ * RETURNS: a pointer to that converted, null terminated hex string;
+ * len_return holds the character count of conversion result
+ *
+ * WHEN: the passed param is not a legal hex string:
+ * RETURNS: the parameter passed;
+ * len_return holds the char count of param.
+ *
+ * NOTE: In neither case will there be strings to free. */
+
+static char*
+IfHexConvertHexElseReturnParam(param, len_return)
+ char* param;
+ int* len_return;
+{
+ char *p; /* steps through param char by char */
+ char c; /* holds the character pointed to by p */
+
+ int ind; /* steps through hexval buffer char by char */
+ static char hexval[ XawTextActionMaxHexChars ];
+ Boolean first_digit;
+
+ /* reject if it doesn't begin with 0x and at least one more character. */
+
+ if ( ( param[0] != '0' ) || ( param[1] != 'x' ) || ( param[2] == '\0' ) ) {
+ *len_return = strlen( param );
+ return( param );
+ }
+
+ /* Skip the 0x; go character by character shifting and adding. */
+
+ first_digit = True;
+ ind = 0;
+ hexval[ ind ] = '\0';
+
+ for ( p = param+2; ( c = *p ); p++ ) {
+ hexval[ ind ] *= 16;
+ if (c >= '0' && c <= '9')
+ hexval[ ind ] += c - '0';
+ else if (c >= 'a' && c <= 'f')
+ hexval[ ind ] += c - 'a' + 10;
+ else if (c >= 'A' && c <= 'F')
+ hexval[ ind ] += c - 'A' + 10;
+ else break;
+
+ /* If we didn't break in preceding line, it was a good hex char. */
+
+ if ( first_digit )
+ first_digit = False;
+ else {
+ first_digit = True;
+ if ( ++ind < XawTextActionMaxHexChars )
+ hexval[ ind ] = '\0';
+ else {
+ *len_return = strlen( param );
+ return( param );
+ }
+ }
+ }
+
+ /* We quit the above loop becasue we hit a non hex. If that char is \0... */
+
+ if ( ( c == '\0' ) && first_digit ) {
+ *len_return = strlen( hexval );
+ return( hexval ); /* ...it was a legal hex string, so return it.*/
+ }
+
+ /* Else, there were non-hex chars or odd digit count, so... */
+
+ *len_return = strlen( param );
+ return( param ); /* ...return the verbatim string. */
+}
+
+
+/* InsertString() - action
+ *
+ * Mostly rewritten for R6 i18n.
+ *
+ * Each parameter, in turn, will be insert at the inputPos
+ * and the inputPos advances to the insertion's end.
+ *
+ * The exception is that parameters composed of the two
+ * characters 0x, followed only by an even number of
+ * hexadecimal digits will be converted to characters. */
+
+/*ARGSUSED*/
+static void
+InsertString(w, event, params, num_params)
+Widget w;
+XEvent* event;
+String* params;
+Cardinal* num_params;
+{
+ TextWidget ctx = (TextWidget) w;
+ XtAppContext app_con = XtWidgetToApplicationContext(w);
+ XawTextBlock text;
+ int i;
+
+ text.firstPos = 0;
+ text.format = _XawTextFormat( ctx );
+
+ StartAction(ctx, event);
+ for ( i = *num_params; i; i--, params++ ) { /* DO FOR EACH PARAMETER */
+
+ text.ptr = IfHexConvertHexElseReturnParam( *params, &text.length );
+
+ if ( text.length == 0 ) continue;
+
+#ifdef XAW_INTERNATIONALIZATION
+ if ( _XawTextFormat( ctx ) == XawFmtWide ) { /* convert to WC */
+
+ int temp_len;
+ text.ptr = (char*) _XawTextMBToWC( XtDisplay(w), text.ptr,
+ &text.length );
+
+ if ( text.ptr == NULL ) { /* conversion error */
+ XtAppWarningMsg( app_con,
+ "insertString", "textAction", "XawError",
+ "insert-string()'s parameter contents not legal in this locale.",
+ NULL, NULL );
+ ParameterError( w, *params );
+ continue;
+ }
+
+ /* Double check that the new input is legal: try to convert to MB. */
+
+ temp_len = text.length; /* _XawTextWCToMB's 3rd arg is in_out */
+ if ( _XawTextWCToMB( XtDisplay(w), (wchar_t*)text.ptr, &temp_len ) == NULL ) {
+ XtAppWarningMsg( app_con,
+ "insertString", "textAction", "XawError",
+ "insert-string()'s parameter contents not legal in this locale.",
+ NULL, NULL );
+ ParameterError( w, *params );
+ continue;
+ }
+ } /* convert to WC */
+#endif
+
+ if ( _XawTextReplace( ctx, ctx->text.insertPos,
+ ctx->text.insertPos, &text ) ) {
+ XBell( XtDisplay( ctx ), 50 );
+ EndAction( ctx );
+ return;
+ }
+
+ /* Advance insertPos to the end of the string we just inserted. */
+ ctx->text.insertPos = SrcScan( ctx->text.source, ctx->text.insertPos,
+ XawstPositions, XawsdRight, text.length, TRUE );
+
+ } /* DO FOR EACH PARAMETER */
+
+ EndAction( ctx );
+}
+
+
+/* DisplayCaret() - action
+ *
+ * The parameter list should contain one boolean value. If the
+ * argument is true, the cursor will be displayed. If false, not.
+ *
+ * The exception is that EnterNotify and LeaveNotify events may
+ * have a second argument, "always". If they do not, the cursor
+ * is only affected if the focus member of the event is true. */
+
+static void
+DisplayCaret(w, event, params, num_params)
+Widget w;
+XEvent* event; /* CrossingNotify special-cased */
+String* params; /* Off, False, No, On, True, Yes, etc. */
+Cardinal* num_params; /* 0, 1 or 2 */
+{
+ TextWidget ctx = (TextWidget)w;
+ Boolean display_caret = True;
+
+ if ( ( event->type == EnterNotify || event->type == LeaveNotify ) &&
+ ( ( *num_params >= 2 ) && ( strcmp( params[1], "always" ) == 0 ) ) &&
+ ( !event->xcrossing.focus ) )
+ return;
+
+ if (*num_params > 0) { /* default arg is "True" */
+ XrmValue from, to;
+ from.size = strlen(from.addr = params[0]);
+ XtConvert( w, XtRString, &from, XtRBoolean, &to );
+
+ if ( to.addr != NULL )
+ display_caret = *(Boolean*)to.addr;
+ if ( ctx->text.display_caret == display_caret )
+ return;
+ }
+ StartAction(ctx, event);
+ ctx->text.display_caret = display_caret;
+ EndAction(ctx);
+}
+
+
+/* Multiply() - action
+ *
+ * The parameter list may contain either a number or the string 'Reset'.
+ *
+ * A number will multiply the current multiplication factor by that number.
+ * Many of the text widget actions will will perform n actions, where n is
+ * the multiplication factor.
+ *
+ * The string reset will reset the mutiplication factor to 1. */
+
+/* ARGSUSED */
+static void
+Multiply(w, event, params, num_params)
+Widget w;
+XEvent* event;
+String* params;
+Cardinal* num_params;
+{
+ TextWidget ctx = (TextWidget) w;
+ int mult;
+
+ if (*num_params != 1) {
+ XtAppError( XtWidgetToApplicationContext( w ),
+ "Xaw Text Widget: multiply() takes exactly one argument.");
+ XBell( XtDisplay( w ), 0 );
+ return;
+ }
+
+ if ( ( params[0][0] == 'r' ) || ( params[0][0] == 'R' ) ) {
+ XBell( XtDisplay( w ), 0 );
+ ctx->text.mult = 1;
+ return;
+ }
+
+ if ( ( mult = atoi( params[0] ) ) == 0 ) {
+ char buf[ BUFSIZ ];
+ sprintf(buf, "%s %s", "Xaw Text Widget: multiply() argument",
+ "must be a number greater than zero, or 'Reset'." );
+ XtAppError( XtWidgetToApplicationContext( w ), buf );
+ XBell( XtDisplay( w ), 50 );
+ return;
+ }
+
+ ctx->text.mult *= mult;
+}
+
+
+/* StripOutOldCRs() - called from FormRegion
+ *
+ * removes CRs in widget ctx, from from to to.
+ *
+ * RETURNS: the new ending location (we may add some characters),
+ * or XawReplaceError if the widget can't be written to. */
+
+static XawTextPosition
+StripOutOldCRs(ctx, from, to)
+TextWidget ctx;
+XawTextPosition from, to;
+{
+ XawTextPosition startPos, endPos, eop_begin, eop_end, temp;
+ Widget src = ctx->text.source;
+ XawTextBlock text;
+ char *buf;
+ static wchar_t wc_two_spaces[ 3 ];
+
+ /* Initialize our TextBlock with two spaces. */
+
+ text.firstPos = 0;
+ text.format = _XawTextFormat(ctx);
+ if ( text.format == XawFmt8Bit )
+ text.ptr= " ";
+#ifdef XAW_INTERNATIONALIZATION
+ else {
+ wc_two_spaces[0] = _Xaw_atowc(XawSP);
+ wc_two_spaces[1] = _Xaw_atowc(XawSP);
+ wc_two_spaces[2] = 0;
+ text.ptr = (char*) wc_two_spaces;
+ }
+#endif
+
+ /* Strip out CR's. */
+
+ eop_begin = eop_end = startPos = endPos = from;
+ /* CONSTCOND */
+ while (TRUE) {
+ endPos=SrcScan(src, startPos, XawstEOL, XawsdRight, 1, FALSE);
+
+ temp = SrcScan(src, endPos, XawstWhiteSpace, XawsdLeft, 1, FALSE);
+ temp = SrcScan(src, temp, XawstWhiteSpace, XawsdRight,1, FALSE);
+
+ if (temp > startPos)
+ endPos = temp;
+
+ if (endPos >= to)
+ break;
+
+ if (endPos >= eop_begin) {
+ startPos = eop_end;
+ eop_begin=SrcScan(src, startPos, XawstParagraph, XawsdRight, 1,FALSE);
+ eop_end = SrcScan(src, startPos, XawstParagraph, XawsdRight, 1, TRUE);
+ }
+ else {
+ XawTextPosition periodPos, next_word;
+ int i, len;
+
+ periodPos= SrcScan(src, endPos, XawstPositions, XawsdLeft, 1, TRUE);
+ next_word = SrcScan(src, endPos, XawstWhiteSpace, XawsdRight, 1, FALSE);
+
+ len = next_word - periodPos;
+
+ text.length = 1;
+ buf = _XawTextGetText(ctx, periodPos, next_word);
+#ifdef XAW_INTERNATIONALIZATION
+ if (text.format == XawFmtWide) {
+ if ( (periodPos < endPos) && (((wchar_t*)buf)[0] == _Xaw_atowc('.')))
+ text.length++;
+ } else
+#endif
+ if ( (periodPos < endPos) && (buf[0] == '.') )
+ text.length++; /* Put in two spaces. */
+
+ /*
+ * Remove all extra spaces.
+ */
+
+ for (i = 1 ; i < len; i++)
+#ifdef XAW_INTERNATIONALIZATION
+ if (text.format == XawFmtWide) {
+ if ( !iswspace(((wchar_t*)buf)[i]) || ((periodPos + i) >= to) ) {
+ break;
+ }
+ } else
+#endif
+ if ( !isspace(buf[i]) || ((periodPos + i) >= to) ) {
+ break;
+ }
+
+ XtFree(buf);
+
+ to -= (i - text.length - 1);
+ startPos = SrcScan(src, periodPos, XawstPositions, XawsdRight, i, TRUE);
+ if (_XawTextReplace(ctx, endPos, startPos, &text) != XawEditDone)
+ return XawReplaceError;
+ startPos -= i - text.length;
+ }
+ }
+ return(to);
+}
+
+
+/* InsertNewCRs() - called from FormRegion
+ *
+ * inserts new CRs for FormRegion, thus for FormParagraph action */
+
+static void
+InsertNewCRs(ctx, from, to)
+TextWidget ctx;
+XawTextPosition from, to;
+{
+ XawTextPosition startPos, endPos, space, eol;
+ XawTextBlock text;
+ int i, width, height, len;
+ char * buf;
+ static wchar_t wide_CR[ 2 ];
+
+ text.firstPos = 0;
+ text.length = 1;
+ text.format = _XawTextFormat( ctx );
+
+ if ( text.format == XawFmt8Bit )
+ text.ptr = "\n";
+#ifdef XAW_INTERNATIONALIZATION
+ else {
+ wide_CR[0] = _Xaw_atowc(XawLF);
+ wide_CR[1] = 0;
+ text.ptr = (char*) wide_CR;
+ }
+#endif
+
+ startPos = from;
+ /* CONSTCOND */
+ while (TRUE) {
+ XawTextSinkFindPosition( ctx->text.sink, startPos,
+ (int) ctx->text.margin.left,
+ (int) (ctx->core.width - HMargins(ctx)),
+ TRUE, &eol, &width, &height);
+ if (eol >= to)
+ break;
+
+ eol = SrcScan(ctx->text.source, eol, XawstPositions, XawsdLeft, 1, TRUE);
+ space= SrcScan(ctx->text.source, eol, XawstWhiteSpace,XawsdRight,1, TRUE);
+
+ startPos = endPos = eol;
+ if (eol == space)
+ return;
+
+ len = (int) (space - eol);
+ buf = _XawTextGetText(ctx, eol, space);
+ for ( i = 0 ; i < len ; i++)
+#ifdef XAW_INTERNATIONALIZATION
+ if (text.format == XawFmtWide) {
+ if (!iswspace(((wchar_t*)buf)[i]))
+ break;
+ } else
+#endif
+ if (!isspace(buf[i]))
+ break;
+
+ to -= (i - 1);
+ endPos = SrcScan(ctx->text.source, endPos,
+ XawstPositions, XawsdRight, i, TRUE);
+ XtFree(buf);
+
+ if (_XawTextReplace(ctx, startPos, endPos, &text))
+ return;
+
+ startPos = SrcScan(ctx->text.source, startPos,
+ XawstPositions, XawsdRight, 1, TRUE);
+ }
+}
+
+
+/* FormRegion() - called by FormParagraph
+ *
+ * oversees the work of paragraph-forming a region
+ *
+ * RETURNS: XawEditDone if successful, or XawReplaceError. */
+
+static int
+FormRegion(ctx, from, to)
+TextWidget ctx;
+XawTextPosition from, to;
+{
+ if ( from >= to ) return XawEditDone;
+
+ if ( ( to = StripOutOldCRs( ctx, from, to ) ) == XawReplaceError )
+ return XawReplaceError;
+
+ /* insure that the insertion point is within legal bounds */
+ if ( ctx->text.insertPos > SrcScan( ctx->text.source, 0,
+ XawstAll, XawsdRight, 1, TRUE ) )
+ ctx->text.insertPos = to;
+
+ InsertNewCRs(ctx, from, to);
+ _XawTextBuildLineTable(ctx, ctx->text.lt.top, TRUE);
+ return XawEditDone;
+}
+
+
+/* FormParagraph() - action
+ *
+ * removes and reinserts CRs to maximize line length without clipping */
+
+/* ARGSUSED */
+static void
+FormParagraph(w, event, params, num_params)
+Widget w;
+XEvent* event;
+String* params;
+Cardinal* num_params;
+{
+ TextWidget ctx = (TextWidget) w;
+ XawTextPosition from, to;
+
+ StartAction(ctx, event);
+
+ from = SrcScan( ctx->text.source, ctx->text.insertPos,
+ XawstParagraph, XawsdLeft, 1, FALSE );
+ to = SrcScan( ctx->text.source, from,
+ XawstParagraph, XawsdRight, 1, FALSE );
+
+ if ( FormRegion( ctx, from, to ) == XawReplaceError )
+ XBell( XtDisplay( w ), 0 );
+ _XawTextSetScrollBars( ctx );
+ EndAction( ctx );
+}
+
+
+/* TransposeCharacters() - action
+ *
+ * Swaps the character to the left of the mark
+ * with the character to the right of the mark. */
+
+/* ARGSUSED */
+static void
+TransposeCharacters(w, event, params, num_params)
+Widget w;
+XEvent* event;
+String* params;
+Cardinal* num_params;
+{
+ TextWidget ctx = (TextWidget) w;
+ XawTextPosition start, end;
+ XawTextBlock text;
+ char* buf;
+ int i;
+
+ StartAction(ctx, event);
+
+ /* Get bounds. */
+
+ start = SrcScan( ctx->text.source, ctx->text.insertPos, XawstPositions,
+ XawsdLeft, 1, TRUE );
+ end = SrcScan( ctx->text.source, ctx->text.insertPos, XawstPositions,
+ XawsdRight, ctx->text.mult, TRUE );
+
+ /* Make sure we aren't at the very beginning or end of the buffer. */
+
+ if ( ( start == ctx->text.insertPos ) || ( end == ctx->text.insertPos ) ) {
+ XBell( XtDisplay( w ), 0 ); /* complain. */
+ EndAction( ctx );
+ return;
+ }
+
+ ctx->text.insertPos = end;
+
+ text.firstPos = 0;
+ text.format = _XawTextFormat(ctx);
+
+ /* Retrieve text and swap the characters. */
+
+#ifdef XAW_INTERNATIONALIZATION
+ if ( text.format == XawFmtWide) {
+ wchar_t wc;
+ wchar_t* wbuf;
+
+ wbuf = (wchar_t*) _XawTextGetText(ctx, start, end);
+ text.length = wcslen( wbuf );
+ wc = wbuf[ 0 ];
+ for ( i = 1; i < text.length; i++ )
+ wbuf[ i-1 ] = wbuf[ i ];
+ wbuf[ i-1 ] = wc;
+ buf = (char*) wbuf; /* so that it gets assigned and freed */
+
+ } else
+#endif
+ { /* thus text.format == XawFmt8Bit */
+ char c;
+ buf = _XawTextGetText( ctx, start, end );
+ text.length = strlen( buf );
+ c = buf[ 0 ];
+ for ( i = 1; i < text.length; i++ )
+ buf[ i-1 ] = buf[ i ];
+ buf[ i-1 ] = c;
+ }
+
+ text.ptr = buf;
+
+ /* Store new text in source. */
+
+ if (_XawTextReplace (ctx, start, end, &text)) /* Unable to edit, complain. */
+ XBell(XtDisplay(w), 0);
+ XtFree((char *) buf);
+ EndAction(ctx);
+}
+
+
+/* NoOp() - action
+ * This action performs no action, and allows the user or
+ * application programmer to unbind a translation.
+ *
+ * Note: If the parameter list contains the string "RingBell" then
+ * this action will ring the bell.
+ */
+
+/*ARGSUSED*/
+static void
+NoOp(w, event, params, num_params)
+Widget w;
+XEvent* event;
+String* params;
+Cardinal* num_params;
+{
+ if (*num_params != 1)
+ return;
+
+ switch(params[0][0]) {
+ case 'R':
+ case 'r':
+ XBell(XtDisplay(w), 0);
+ default: /* Fall Through */
+ break;
+ }
+}
+
+/* Reconnect() - action
+ * This reconnects to the input method. The user will typically call
+ * this action if/when connection has been severed, or when the app
+ * was started up before an IM was started up.
+ */
+
+#ifdef XAW_INTERNATIONALIZATION
+/*ARGSUSED*/
+static void
+Reconnect( w, event, params, num_params )
+ Widget w;
+ XEvent* event;
+ String* params;
+ Cardinal* num_params;
+{
+ _XawImReconnect( w );
+}
+#endif
+
+
+XtActionsRec _XawTextActionsTable[] = {
+
+/* motion bindings */
+
+ {"forward-character", MoveForwardChar},
+ {"backward-character", MoveBackwardChar},
+ {"forward-word", MoveForwardWord},
+ {"backward-word", MoveBackwardWord},
+ {"forward-paragraph", MoveForwardParagraph},
+ {"backward-paragraph", MoveBackwardParagraph},
+ {"beginning-of-line", MoveToLineStart},
+ {"end-of-line", MoveToLineEnd},
+ {"next-line", MoveNextLine},
+ {"previous-line", MovePreviousLine},
+ {"next-page", MoveNextPage},
+ {"previous-page", MovePreviousPage},
+ {"beginning-of-file", MoveBeginningOfFile},
+ {"end-of-file", MoveEndOfFile},
+ {"scroll-one-line-up", ScrollOneLineUp},
+ {"scroll-one-line-down", ScrollOneLineDown},
+
+/* delete bindings */
+
+ {"delete-next-character", DeleteForwardChar},
+ {"delete-previous-character", DeleteBackwardChar},
+ {"delete-next-word", DeleteForwardWord},
+ {"delete-previous-word", DeleteBackwardWord},
+ {"delete-selection", DeleteCurrentSelection},
+
+/* kill bindings */
+
+ {"kill-word", KillForwardWord},
+ {"backward-kill-word", KillBackwardWord},
+ {"kill-selection", KillCurrentSelection},
+ {"kill-to-end-of-line", KillToEndOfLine},
+ {"kill-to-end-of-paragraph", KillToEndOfParagraph},
+
+/* new line stuff */
+
+ {"newline-and-indent", InsertNewLineAndIndent},
+ {"newline-and-backup", InsertNewLineAndBackup},
+ {"newline", InsertNewLine},
+
+/* Selection stuff */
+
+ {"select-word", SelectWord},
+ {"select-all", SelectAll},
+ {"select-start", SelectStart},
+ {"select-adjust", SelectAdjust},
+ {"select-end", SelectEnd},
+ {"select-save", SelectSave},
+ {"extend-start", ExtendStart},
+ {"extend-adjust", ExtendAdjust},
+ {"extend-end", ExtendEnd},
+ {"insert-selection", InsertSelection},
+
+/* Miscellaneous */
+
+ {"redraw-display", RedrawDisplay},
+ {"insert-file", _XawTextInsertFile},
+ {"search", _XawTextSearch},
+ {"insert-char", InsertChar},
+ {"insert-string", InsertString},
+ {"focus-in", TextFocusIn},
+ {"focus-out", TextFocusOut},
+ {"enter-window", TextEnterWindow},
+ {"leave-window", TextLeaveWindow},
+ {"display-caret", DisplayCaret},
+ {"multiply", Multiply},
+ {"form-paragraph", FormParagraph},
+ {"transpose-characters", TransposeCharacters},
+ {"no-op", NoOp},
+
+/* Action to bind special translations for text Dialogs. */
+
+ {"InsertFileAction", _XawTextInsertFileAction},
+ {"DoSearchAction", _XawTextDoSearchAction},
+ {"DoReplaceAction", _XawTextDoReplaceAction},
+ {"SetField", _XawTextSetField},
+ {"PopdownSearchAction", _XawTextPopdownSearchAction},
+
+/* Reconnect to Input Method */
+#ifdef XAW_INTERNATIONALIZATION
+ {"reconnect-im", Reconnect} /* Li Yuhong, Omron KK, 1991 */
+#endif
+};
+
+Cardinal _XawTextActionsTableCount = XtNumber(_XawTextActionsTable);
diff --git a/src/TextP.h b/src/TextP.h
new file mode 100644
index 0000000..9121314
--- /dev/null
+++ b/src/TextP.h
@@ -0,0 +1,290 @@
+/*
+* $XConsortium: TextP.h,v 1.54 95/06/14 15:07:27 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.
+
+******************************************************************/
+
+#ifndef _XawTextP_h
+#define _XawTextP_h
+
+#include <X11/Xaw3d/Text.h>
+#include <X11/Xaw3d/SimpleP.h>
+
+/****************************************************************
+ *
+ * Text widget private
+ *
+ ****************************************************************/
+#define MAXCUT 30000 /* Maximum number of characters that can be cut. */
+
+#define GETLASTPOS XawTextSourceScan(ctx->text.source, 0, \
+ XawstAll, XawsdRight, 1, TRUE)
+
+#define zeroPosition ((XawTextPosition) 0)
+
+extern XtActionsRec _XawTextActionsTable[];
+extern Cardinal _XawTextActionsTableCount;
+
+#define XawLF 0x0a
+#define XawCR 0x0d
+#define XawTAB 0x09
+#define XawBS 0x08
+#define XawSP 0x20
+#define XawDEL 0x7f
+#define XawESC 0x1b
+#define XawBSLASH '\\'
+
+/* constants that subclasses may want to know */
+#define DEFAULT_TEXT_HEIGHT ((Dimension)~0)
+
+/* displayable text management data structures */
+
+typedef struct {
+ XawTextPosition position;
+ Position y;
+ Dimension textWidth;
+} XawTextLineTableEntry, *XawTextLineTableEntryPtr;
+
+typedef struct {
+ XawTextPosition left, right;
+ XawTextSelectType type;
+ Atom* selections;
+ int atom_count;
+ int array_size;
+} XawTextSelection;
+
+typedef struct _XawTextSelectionSalt {
+ struct _XawTextSelectionSalt *next;
+ XawTextSelection s;
+ /*
+ * The element "contents" stores the CT string which is gotten in the
+ * function _XawTextSaltAwaySelection().
+ */
+ char *contents;
+ int length;
+} XawTextSelectionSalt;
+
+/* Line Tables are n+1 long - last position displayed is in last lt entry */
+typedef struct {
+ XawTextPosition top; /* Top of the displayed text. */
+ int lines; /* How many lines in this table. */
+ XawTextLineTableEntry *info; /* A dynamic array, one entry per line */
+} XawTextLineTable, *XawTextLineTablePtr;
+
+
+typedef struct _XawTextMargin {
+ Position left, right, top, bottom;
+} XawTextMargin;
+
+#define VMargins(ctx) ( (ctx)->text.margin.top + (ctx)->text.margin.bottom )
+#define HMargins(ctx) ( (ctx)->text.margin.left + (ctx)->text.margin.right )
+
+#define IsPositionVisible(ctx, pos) \
+ (pos >= ctx->text.lt.info[0].position && \
+ pos < ctx->text.lt.info[ctx->text.lt.lines].position)
+
+/*
+ * Search & Replace data structure.
+ */
+
+struct SearchAndReplace {
+ Boolean selection_changed; /* flag so that the selection cannot be
+ changed out from underneath query-replace.*/
+ Widget search_popup; /* The poppup widget that allows searches.*/
+ Widget label1; /* The label widgets for the search window. */
+ Widget label2;
+ Widget left_toggle; /* The left search toggle radioGroup. */
+ Widget right_toggle; /* The right search toggle radioGroup. */
+ Widget rep_label; /* The Replace label string. */
+ Widget rep_text; /* The Replace text field. */
+ Widget search_text; /* The Search text field. */
+ Widget rep_one; /* The Replace one button. */
+ Widget rep_all; /* The Replace all button. */
+};
+
+/* Private Text Definitions */
+
+typedef int (*ActionProc)();
+
+/* New fields for the Text widget class record */
+
+typedef struct {int empty;} TextClassPart;
+
+struct text_move {
+ int h, v;
+ struct text_move * next;
+};
+
+/* Full class record declaration */
+typedef struct _TextClassRec {
+ CoreClassPart core_class;
+ SimpleClassPart simple_class;
+ TextClassPart text_class;
+} TextClassRec;
+
+extern TextClassRec textClassRec;
+
+/* New fields for the Text widget record */
+typedef struct _TextPart {
+ /* resources */
+
+ Widget source, sink;
+ XawTextPosition insertPos;
+ XawTextSelection s;
+ XawTextSelectType *sarray; /* Array to cycle for selections. */
+ XawTextSelectionSalt *salt; /* salted away selections */
+ int options; /* wordbreak, scroll, etc. */
+ int dialog_horiz_offset; /* position for popup dialog */
+ int dialog_vert_offset; /* position for popup dialog */
+ Boolean display_caret; /* insertion pt visible iff T */
+ Boolean auto_fill; /* Auto fill mode? */
+ XawTextScrollMode scroll_vert, scroll_horiz; /*what type of scrollbars.*/
+ XawTextWrapMode wrap; /* The type of wrapping. */
+ XawTextResizeMode resize; /* what to resize */
+ XawTextMargin r_margin; /* The real margins. */
+ XtCallbackList unrealize_callbacks; /* used for scrollbars */
+
+ /* private state */
+
+ XawTextMargin margin; /* The current margins. */
+ XawTextLineTable lt;
+ XawTextScanDirection extendDir;
+ XawTextSelection origSel; /* the selection being modified */
+ Time lasttime; /* timestamp of last processed action */
+ Time time; /* time of last key or button action */
+ Position ev_x, ev_y; /* x, y coords for key or button action */
+ Widget vbar, hbar; /* The scroll bars (none = NULL). */
+ struct SearchAndReplace * search;/* Search and replace structure. */
+ Widget file_insert; /* The file insert popup widget. */
+ XawTextPosition *updateFrom; /* Array of start positions for update. */
+ XawTextPosition *updateTo; /* Array of end positions for update. */
+ int numranges; /* How many update ranges there are. */
+ int maxranges; /* How many ranges we have space for */
+ XawTextPosition lastPos; /* Last position of source. */
+ GC gc;
+ Boolean showposition; /* True if we need to show the position. */
+ Boolean hasfocus; /* TRUE if we currently have input focus.*/
+ Boolean update_disabled; /* TRUE if display updating turned off */
+ Boolean single_char; /* Single character replaced. */
+ XawTextPosition old_insert; /* Last insertPos for batched updates */
+ short mult; /* Multiplier. */
+ struct text_move * copy_area_offsets; /* Text offset area (linked list) */
+ Widget threeD; /* shadow drawing */
+
+ /* private state, shared w/Source and Sink */
+ Boolean redisplay_needed; /* in SetValues */
+ XawTextSelectionSalt *salt2; /* salted away selections */
+} TextPart;
+
+/*************************************************************
+ *
+ * Resource types private to Text widget.
+ *
+ *************************************************************/
+
+#define XtRScrollMode "ScrollMode"
+#define XtRWrapMode "WrapMode"
+#define XtRResizeMode "ResizeMode"
+
+/****************************************************************
+ *
+ * Full instance record declaration
+ *
+ ****************************************************************/
+
+typedef struct _TextRec {
+ CorePart core;
+ SimplePart simple;
+ TextPart text;
+} TextRec;
+
+/********************************************
+ *
+ * Semi-private functions
+ * for use by other Xaw modules only
+ *
+ *******************************************/
+
+extern void _XawTextBuildLineTable (
+#if NeedFunctionPrototypes
+ TextWidget /*ctx*/,
+ XawTextPosition /*top pos*/,
+ _XtBoolean /* force_rebuild */
+#endif
+);
+
+extern char* _XawTextGetSTRING(
+#if NeedFunctionPrototypes
+ TextWidget /*ctx*/,
+ XawTextPosition /*left*/,
+ XawTextPosition /*right*/
+#endif
+);
+
+extern void _XawTextSaltAwaySelection(
+#if NeedFunctionPrototypes
+ TextWidget /*ctx*/,
+ Atom* /*selections*/,
+ int /*num_atoms*/
+#endif
+);
+
+extern void _XawTextPosToXY(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ XawTextPosition /* pos */,
+ Position * /* x */,
+ Position * /*y */
+#endif
+);
+
+#endif /* _XawTextP_h */
+
+
diff --git a/src/TextPop.c b/src/TextPop.c
new file mode 100644
index 0000000..260b4dc
--- /dev/null
+++ b/src/TextPop.c
@@ -0,0 +1,1434 @@
+/* $XConsortium: TextPop.c,v 1.31 94/04/17 20:13:10 kaleb Exp $ */
+
+/*
+
+Copyright (c) 1989, 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.
+
+*/
+
+/************************************************************
+ *
+ * This file is broken up into three sections one dealing with
+ * each of the three popups created here:
+ *
+ * FileInsert, Search, and Replace.
+ *
+ * There is also a section at the end for utility functions
+ * used by all more than one of these dialogs.
+ *
+ * The following functions are the only non-static ones defined
+ * in this module. They are located at the begining of the
+ * section that contains this dialog box that uses them.
+ *
+ * void _XawTextInsertFileAction(w, event, params, num_params);
+ * void _XawTextDoSearchAction(w, event, params, num_params);
+ * void _XawTextDoReplaceAction(w, event, params, num_params);
+ * void _XawTextInsertFile(w, event, params, num_params);
+ *
+ *************************************************************/
+
+#include "Xaw3dP.h"
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Shell.h>
+#include <X11/Xaw3d/TextP.h>
+#include <X11/Xaw3d/AsciiText.h>
+#include <X11/Xaw3d/Cardinals.h>
+#include <X11/Xaw3d/Command.h>
+#include <X11/Xaw3d/Form.h>
+#include <X11/Xaw3d/Toggle.h>
+#include <X11/Xmu/CharSet.h>
+#ifdef XAW_INTERNATIONALIZATION
+#include "XawI18n.h"
+#endif
+#include <stdio.h>
+#include <X11/Xos.h> /* for O_RDONLY */
+#include <errno.h>
+
+#ifdef X_NOT_STDC_ENV
+extern int errno;
+#endif
+
+#define INSERT_FILE ("Enter Filename:")
+
+#define SEARCH_LABEL_1 ("Use <Tab> to change fields.")
+#define SEARCH_LABEL_2 ("Use ^q<Tab> for <Tab>.")
+#define DISMISS_NAME ("cancel")
+#define DISMISS_NAME_LEN 6
+#define FORM_NAME ("form")
+#define LABEL_NAME ("label")
+#define TEXT_NAME ("text")
+
+#define R_OFFSET 1
+
+static void CenterWidgetOnPoint(), PopdownSearch(), DoInsert(), _SetField();
+static void InitializeSearchWidget(), SetResource(), SetSearchLabels();
+static void DoReplaceOne(), DoReplaceAll();
+static Widget CreateDialog(), GetShell();
+static void SetWMProtocolTranslations();
+static Boolean DoSearch(), SetResourceByName(), Replace();
+static String GetString();
+
+static String GetStringRaw();
+
+static void AddInsertFileChildren();
+static Boolean InsertFileNamed();
+static void AddSearchChildren();
+
+static char radio_trans_string[] =
+ "<Btn1Down>,<Btn1Up>: set() notify()";
+
+static char search_text_trans[] =
+ "~Shift<Key>Return: DoSearchAction(Popdown) \n\
+ Shift<Key>Return: DoSearchAction() SetField(Replace) \n\
+ Ctrl<Key>q,<Key>Tab: insert-char() \n\
+ Ctrl<Key>c: PopdownSearchAction() \n\
+ <Btn1Down>: select-start() SetField(Search) \n\
+ <Key>Tab: DoSearchAction() SetField(Replace)";
+
+static char rep_text_trans[] =
+ "~Shift<Key>Return: DoReplaceAction(Popdown) \n\
+ Shift<Key>Return: SetField(Search) \n\
+ Ctrl<Key>q,<Key>Tab: insert-char() \n\
+ Ctrl<Key>c: PopdownSearchAction() \n\
+ <Btn1Down>: select-start() DoSearchAction() SetField(Replace)\n\
+ <Key>Tab: SetField(Search)";
+
+/************************************************************
+ *
+ * This section of the file contains all the functions that
+ * the file insert dialog box uses.
+ *
+ ************************************************************/
+
+/* Function Name: _XawTextInsertFileAction
+ * Description: Action routine that can be bound to dialog box's
+ * Text Widget that will insert a file into the main
+ * Text Widget.
+ * Arguments: (Standard Action Routine args)
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+void
+_XawTextInsertFileAction(w, event, params, num_params)
+Widget w;
+XEvent *event;
+String * params;
+Cardinal * num_params;
+{
+ DoInsert(w, (XtPointer) XtParent(XtParent(XtParent(w))), (XtPointer)NULL);
+}
+
+/* Function Name: _XawTextInsertFile
+ * Description: Action routine that can be bound to the text widget
+ * it will popup the insert file dialog box.
+ * Arguments: w - the text widget.
+ * event - X Event (used to get x and y location).
+ * params, num_params - the parameter list.
+ * Returns: none.
+ *
+ * NOTE:
+ *
+ * The parameter list may contain one entry.
+ *
+ * Entry: This entry is optional and contains the value of the default
+ * file to insert.
+ */
+
+void
+_XawTextInsertFile(w, event, params, num_params)
+Widget w;
+XEvent *event;
+String * params;
+Cardinal * num_params;
+{
+ TextWidget ctx = (TextWidget)w;
+ char * ptr;
+ XawTextEditType edit_mode;
+ Arg args[1];
+
+ XtSetArg(args[0], XtNeditType,&edit_mode);
+ XtGetValues(ctx->text.source, args, ONE);
+
+ if (edit_mode != XawtextEdit) {
+ XBell(XtDisplay(w), 0);
+ return;
+ }
+
+ if (*num_params == 0)
+ ptr = "";
+ else
+ ptr = params[0];
+
+ if (!ctx->text.file_insert) {
+ ctx->text.file_insert = CreateDialog(w, ptr, "insertFile",
+ AddInsertFileChildren);
+ XtRealizeWidget(ctx->text.file_insert);
+ SetWMProtocolTranslations(ctx->text.file_insert);
+ }
+
+ CenterWidgetOnPoint(ctx->text.file_insert, event);
+ XtPopup(ctx->text.file_insert, XtGrabNone);
+}
+
+/* Function Name: PopdownFileInsert
+ * Description: Pops down the file insert button.
+ * Arguments: w - the widget that caused this action.
+ * closure - a pointer to the main text widget that
+ * popped up this dialog.
+ * call_data - *** NOT USED ***.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+PopdownFileInsert(w, closure, call_data)
+Widget w; /* The Dialog Button Pressed. */
+XtPointer closure; /* Text Widget. */
+XtPointer call_data; /* unused */
+{
+ TextWidget ctx = (TextWidget) closure;
+
+ XtPopdown( ctx->text.file_insert );
+ (void) SetResourceByName( ctx->text.file_insert, LABEL_NAME,
+ XtNlabel, (XtArgVal) INSERT_FILE);
+}
+
+/* Function Name: DoInsert
+ * Description: Actually insert the file named in the text widget
+ * of the file dialog.
+ * Arguments: w - the widget that activated this callback.
+ * closure - a pointer to the text widget to insert the
+ * file into.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+DoInsert(w, closure, call_data)
+Widget w; /* The Dialog Button Pressed. */
+XtPointer closure; /* Text Widget */
+XtPointer call_data; /* unused */
+{
+ TextWidget ctx = (TextWidget) closure;
+ char buf[BUFSIZ], msg[BUFSIZ];
+ Widget temp_widget;
+
+ (void) sprintf(buf, "%s.%s", FORM_NAME, TEXT_NAME);
+ if ( (temp_widget = XtNameToWidget(ctx->text.file_insert, buf)) == NULL ) {
+ (void) strcpy(msg,
+ "*** Error: Could not get text widget from file insert popup");
+ }
+ else
+ if (InsertFileNamed( (Widget) ctx, GetString( temp_widget ))) {
+ PopdownFileInsert(w, closure, call_data);
+ return;
+ }
+ else
+ (void) sprintf( msg, "*** Error: %s ***", strerror(errno));
+
+ (void)SetResourceByName(ctx->text.file_insert,
+ LABEL_NAME, XtNlabel, (XtArgVal) msg);
+ XBell(XtDisplay(w), 0);
+}
+
+/* Function Name: InsertFileNamed
+ * Description: Inserts a file into the text widget.
+ * Arguments: tw - The text widget to insert this file into.
+ * str - name of the file to insert.
+ * Returns: TRUE if the insert was sucessful, FALSE otherwise.
+ */
+
+
+static Boolean
+InsertFileNamed(tw, str)
+Widget tw;
+char *str;
+{
+ FILE *file;
+ XawTextBlock text;
+ XawTextPosition pos;
+
+ if ( (str == NULL) || (strlen(str) == 0) ||
+ ((file = fopen(str, "r")) == NULL))
+ return(FALSE);
+
+ pos = XawTextGetInsertionPoint(tw);
+
+ fseek(file, 0L, 2);
+
+
+ text.firstPos = 0;
+ text.length = (ftell(file))/sizeof(unsigned char);
+ text.ptr = XtMalloc((text.length + 1) * sizeof(unsigned char));
+ text.format = XawFmt8Bit;
+
+ fseek(file, 0L, 0);
+ if (fread(text.ptr, sizeof(unsigned char), text.length, file) != text.length)
+ XtErrorMsg("readError", "insertFileNamed", "XawError",
+ "fread returned error.", NULL, NULL);
+
+ /* DELETE if (text.format == XawFmtWide) {
+ wchar_t* _XawTextMBToWC();
+ wchar_t* wstr;
+ wstr = _XawTextMBToWC(XtDisplay(tw), text.ptr, &(text.length));
+ wstr[text.length] = NULL;
+ XtFree(text.ptr);
+ text.ptr = (char *)wstr;
+ } else {
+ (text.ptr)[text.length] = '\0';
+ }*/
+
+ if (XawTextReplace(tw, pos, pos, &text) != XawEditDone) {
+ XtFree(text.ptr);
+ fclose(file);
+ return(FALSE);
+ }
+ pos += text.length;
+ XtFree(text.ptr);
+ fclose(file);
+ XawTextSetInsertionPoint(tw, pos);
+ return(TRUE);
+}
+
+
+/* Function Name: AddInsertFileChildren
+ * Description: Adds all children to the InsertFile dialog widget.
+ * Arguments: form - the form widget for the insert dialog widget.
+ * ptr - a pointer to the initial string for the Text Widget.
+ * tw - the main text widget.
+ * Returns: none
+ */
+
+static void
+AddInsertFileChildren(form, ptr, tw)
+Widget form, tw;
+char * ptr;
+{
+ Arg args[10];
+ Cardinal num_args;
+ Widget label, text, cancel, insert;
+ XtTranslations trans;
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNlabel, INSERT_FILE);num_args++;
+ XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNresizable, TRUE ); num_args++;
+ XtSetArg(args[num_args], XtNborderWidth, 0 ); num_args++;
+ label = XtCreateManagedWidget (LABEL_NAME, labelWidgetClass, form,
+ args, num_args);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNfromVert, label); num_args++;
+ XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNright, XtChainRight); num_args++;
+ XtSetArg(args[num_args], XtNeditType, XawtextEdit); num_args++;
+ XtSetArg(args[num_args], XtNresizable, TRUE); num_args++;
+ XtSetArg(args[num_args], XtNresize, XawtextResizeWidth); num_args++;
+ XtSetArg(args[num_args], XtNstring, ptr); num_args++;
+ text = XtCreateManagedWidget(TEXT_NAME, asciiTextWidgetClass, form,
+ args, num_args);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNlabel, "Insert File"); num_args++;
+ XtSetArg(args[num_args], XtNfromVert, text); num_args++;
+ XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
+ insert = XtCreateManagedWidget("insert", commandWidgetClass, form,
+ args, num_args);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNlabel, "Cancel"); num_args++;
+ XtSetArg(args[num_args], XtNfromVert, text); num_args++;
+ XtSetArg(args[num_args], XtNfromHoriz, insert); num_args++;
+ XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
+ cancel = XtCreateManagedWidget(DISMISS_NAME, commandWidgetClass, form,
+ args, num_args);
+
+ XtAddCallback(cancel, XtNcallback, PopdownFileInsert, (XtPointer) tw);
+ XtAddCallback(insert, XtNcallback, DoInsert, (XtPointer) tw);
+
+ XtSetKeyboardFocus(form, text);
+
+/*
+ * Bind <CR> to insert file.
+ */
+
+ trans = XtParseTranslationTable("<Key>Return: InsertFileAction()");
+ XtOverrideTranslations(text, trans);
+
+}
+
+/************************************************************
+ *
+ * This section of the file contains all the functions that
+ * the search dialog box uses.
+ *
+ ************************************************************/
+
+/* Function Name: _XawTextDoSearchAction
+ * Description: Action routine that can be bound to dialog box's
+ * Text Widget that will search for a string in the main
+ * Text Widget.
+ * Arguments: (Standard Action Routine args)
+ * Returns: none.
+ *
+ * Note:
+ *
+ * If the search was sucessful and the argument popdown is passed to
+ * this action routine then the widget will automatically popdown the
+ * search widget.
+ */
+
+/* ARGSUSED */
+void
+_XawTextDoSearchAction(w, event, params, num_params)
+Widget w;
+XEvent *event;
+String * params;
+Cardinal * num_params;
+{
+ TextWidget tw = (TextWidget) XtParent(XtParent(XtParent(w)));
+ Boolean popdown = FALSE;
+
+ if ( (*num_params == 1) &&
+ ((params[0][0] == 'p') || (params[0][0] == 'P')) )
+ popdown = TRUE;
+
+ if (DoSearch(tw->text.search) && popdown)
+ PopdownSearch(w, (XtPointer) tw->text.search, (XtPointer)NULL);
+}
+
+/* Function Name: _XawTextPopdownSearchAction
+ * Description: Action routine that can be bound to dialog box's
+ * Text Widget that will popdown the search widget.
+ * Arguments: (Standard Action Routine args)
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+void
+_XawTextPopdownSearchAction(w, event, params, num_params)
+Widget w;
+XEvent *event;
+String * params;
+Cardinal * num_params;
+{
+ TextWidget tw = (TextWidget) XtParent(XtParent(XtParent(w)));
+
+ PopdownSearch(w, (XtPointer) tw->text.search, (XtPointer)NULL);
+}
+
+/* Function Name: PopdownSeach
+ * Description: Pops down the search widget and resets it.
+ * Arguments: w - *** NOT USED ***.
+ * closure - a pointer to the search structure.
+ * call_data - *** NOT USED ***.
+ * Returns: none
+ */
+
+/* ARGSUSED */
+static void
+PopdownSearch(w, closure, call_data)
+Widget w;
+XtPointer closure;
+XtPointer call_data;
+{
+ struct SearchAndReplace * search = (struct SearchAndReplace *) closure;
+
+ XtPopdown( search->search_popup );
+ SetSearchLabels(search, SEARCH_LABEL_1, SEARCH_LABEL_2, FALSE);
+}
+
+/* Function Name: SearchButton
+ * Description: Performs a search when the button is clicked.
+ * Arguments: w - *** NOT USED **.
+ * closure - a pointer to the search info.
+ * call_data - *** NOT USED ***.
+ * Returns:
+ */
+
+/* ARGSUSED */
+static void
+SearchButton(w, closure, call_data)
+Widget w;
+XtPointer closure;
+XtPointer call_data;
+{
+ (void) DoSearch( (struct SearchAndReplace *) closure );
+}
+
+/* Function Name: _XawTextSearch
+ * Description: Action routine that can be bound to the text widget
+ * it will popup the search dialog box.
+ * Arguments: w - the text widget.
+ * event - X Event (used to get x and y location).
+ * params, num_params - the parameter list.
+ * Returns: none.
+ *
+ * NOTE:
+ *
+ * The parameter list contains one or two entries that may be the following.
+ *
+ * First Entry: The first entry is the direction to search by default.
+ * This arguement must be specified and may have a value of
+ * "left" or "right".
+ *
+ * Second Entry: This entry is optional and contains the value of the default
+ * string to search for.
+ */
+
+#define SEARCH_HEADER ("Text Widget - Search():")
+
+void
+_XawTextSearch(w, event, params, num_params)
+Widget w;
+XEvent *event;
+String * params;
+Cardinal * num_params;
+{
+ TextWidget ctx = (TextWidget)w;
+ XawTextScanDirection dir;
+ char * ptr, buf[BUFSIZ];
+ XawTextEditType edit_mode;
+ Arg args[1];
+
+#ifdef notdef
+ if (ctx->text.source->Search == NULL) {
+ XBell(XtDisplay(w), 0);
+ return;
+ }
+#endif
+
+ if ( (*num_params < 1) || (*num_params > 2) ) {
+ (void) sprintf(buf, "%s %s\n%s", SEARCH_HEADER,
+ "This action must have only",
+ "one or two parameters");
+ XtAppWarning(XtWidgetToApplicationContext(w), buf);
+ return;
+ }
+
+ if (*num_params == 2 )
+ ptr = params[1];
+ else
+#ifdef XAW_INTERNATIONALIZATION
+ if (_XawTextFormat(ctx) == XawFmtWide) {
+ /*This just does the equivalent of ptr = ""L, a waste because params[1] isnt W aligned.*/
+ ptr = (char *)XtMalloc(sizeof(wchar_t));
+ *((wchar_t*)ptr) = (wchar_t)0;
+ } else
+#endif
+ ptr = "";
+
+ switch(params[0][0]) {
+ case 'b': /* Left. */
+ case 'B':
+ dir = XawsdLeft;
+ break;
+ case 'f': /* Right. */
+ case 'F':
+ dir = XawsdRight;
+ break;
+ default:
+ (void) sprintf(buf, "%s %s\n%s", SEARCH_HEADER,
+ "The first parameter must be",
+ "Either 'backward' or 'forward'");
+ XtAppWarning(XtWidgetToApplicationContext(w), buf);
+ return;
+ }
+
+ if (ctx->text.search== NULL) {
+ ctx->text.search = XtNew(struct SearchAndReplace);
+ ctx->text.search->search_popup = CreateDialog(w, ptr, "search",
+ AddSearchChildren);
+ XtRealizeWidget(ctx->text.search->search_popup);
+ SetWMProtocolTranslations(ctx->text.search->search_popup);
+ }
+ else if (*num_params > 1) {
+ XtVaSetValues(ctx->text.search->search_text, XtNstring, ptr, NULL);
+ }
+
+ XtSetArg(args[0], XtNeditType,&edit_mode);
+ XtGetValues(ctx->text.source, args, ONE);
+
+ InitializeSearchWidget(ctx->text.search, dir, (edit_mode == XawtextEdit));
+
+ CenterWidgetOnPoint(ctx->text.search->search_popup, event);
+ XtPopup(ctx->text.search->search_popup, XtGrabNone);
+}
+
+/* Function Name: InitializeSearchWidget
+ * Description: This function initializes the search widget and
+ * is called each time the search widget is poped up.
+ * Arguments: search - the search widget structure.
+ * dir - direction to search.
+ * replace_active - state of the sensitivity for the
+ * replace button.
+ * Returns: none.
+ */
+
+static void
+InitializeSearchWidget(search, dir, replace_active)
+struct SearchAndReplace * search;
+XawTextScanDirection dir;
+Boolean replace_active;
+{
+ SetResource(search->rep_one, XtNsensitive, (XtArgVal) replace_active);
+ SetResource(search->rep_all, XtNsensitive, (XtArgVal) replace_active);
+ SetResource(search->rep_label, XtNsensitive, (XtArgVal) replace_active);
+ SetResource(search->rep_text, XtNsensitive, (XtArgVal) replace_active);
+
+ switch (dir) {
+ case XawsdLeft:
+ SetResource(search->left_toggle, XtNstate, (XtArgVal) TRUE);
+ break;
+ case XawsdRight:
+ SetResource(search->right_toggle, XtNstate, (XtArgVal) TRUE);
+ break;
+ default:
+ break;
+ }
+}
+
+/* Function Name: AddSearchChildren
+ * Description: Adds all children to the Search Dialog Widget.
+ * Arguments: form - the form widget for the search widget.
+ * ptr - a pointer to the initial string for the Text Widget.
+ * tw - the main text widget.
+ * Returns: none.
+ */
+
+static void
+AddSearchChildren(form, ptr, tw)
+Widget form, tw;
+char * ptr;
+{
+ Arg args[10];
+ Cardinal num_args;
+ Widget cancel, search_button, s_label, s_text, r_text;
+ XtTranslations trans;
+ struct SearchAndReplace * search = ((TextWidget) tw)->text.search;
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNresizable, TRUE ); num_args++;
+ XtSetArg(args[num_args], XtNborderWidth, 0 ); num_args++;
+ search->label1 = XtCreateManagedWidget("label1", labelWidgetClass, form,
+ args, num_args);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNfromVert, search->label1); num_args++;
+ XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNresizable, TRUE ); num_args++;
+ XtSetArg(args[num_args], XtNborderWidth, 0 ); num_args++;
+ search->label2 = XtCreateManagedWidget("label2", labelWidgetClass, form,
+ args, num_args);
+
+/*
+ * We need to add R_OFFSET to the radio_data, because the value zero (0)
+ * has special meaning.
+ */
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNlabel, "Backward"); num_args++;
+ XtSetArg(args[num_args], XtNfromVert, search->label2); num_args++;
+ XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNradioData, (XPointer) XawsdLeft + R_OFFSET);
+ num_args++;
+ search->left_toggle = XtCreateManagedWidget("backwards", toggleWidgetClass,
+ form, args, num_args);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNlabel, "Forward"); num_args++;
+ XtSetArg(args[num_args], XtNfromVert, search->label2); num_args++;
+ XtSetArg(args[num_args], XtNfromHoriz, search->left_toggle); num_args++;
+ XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNradioGroup, search->left_toggle); num_args++;
+ XtSetArg(args[num_args], XtNradioData, (XPointer) XawsdRight + R_OFFSET);
+ num_args++;
+ search->right_toggle = XtCreateManagedWidget("forwards", toggleWidgetClass,
+ form, args, num_args);
+
+ {
+ XtTranslations radio_translations;
+
+ radio_translations = XtParseTranslationTable(radio_trans_string);
+ XtOverrideTranslations(search->left_toggle, radio_translations);
+ XtOverrideTranslations(search->right_toggle, radio_translations);
+ }
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNfromVert, search->left_toggle); num_args++;
+ XtSetArg(args[num_args], XtNlabel, "Search for: ");num_args++;
+ XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNborderWidth, 0 ); num_args++;
+ s_label = XtCreateManagedWidget("searchLabel", labelWidgetClass, form,
+ args, num_args);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNfromVert, search->left_toggle); num_args++;
+ XtSetArg(args[num_args], XtNfromHoriz, s_label); num_args++;
+ XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNright, XtChainRight); num_args++;
+ XtSetArg(args[num_args], XtNeditType, XawtextEdit); num_args++;
+ XtSetArg(args[num_args], XtNresizable, TRUE); num_args++;
+ XtSetArg(args[num_args], XtNresize, XawtextResizeWidth); num_args++;
+ XtSetArg(args[num_args], XtNstring, ptr); num_args++;
+ s_text = XtCreateManagedWidget("searchText", asciiTextWidgetClass, form,
+ args, num_args);
+ search->search_text = s_text;
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNfromVert, s_text); num_args++;
+ XtSetArg(args[num_args], XtNlabel, "Replace with:");num_args++;
+ XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNborderWidth, 0 ); num_args++;
+ search->rep_label = XtCreateManagedWidget("replaceLabel", labelWidgetClass,
+ form, args, num_args);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNfromHoriz, s_label); num_args++;
+ XtSetArg(args[num_args], XtNfromVert, s_text); num_args++;
+ XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNright, XtChainRight); num_args++;
+ XtSetArg(args[num_args], XtNeditType, XawtextEdit); num_args++;
+ XtSetArg(args[num_args], XtNresizable, TRUE); num_args++;
+ XtSetArg(args[num_args], XtNresize, XawtextResizeWidth); num_args++;
+ XtSetArg(args[num_args], XtNstring, ""); num_args++;
+ r_text = XtCreateManagedWidget("replaceText", asciiTextWidgetClass,
+ form, args, num_args);
+ search->rep_text = r_text;
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNlabel, "Search"); num_args++;
+ XtSetArg(args[num_args], XtNfromVert, r_text); num_args++;
+ XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
+ search_button = XtCreateManagedWidget("search", commandWidgetClass, form,
+ args, num_args);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNlabel, "Replace"); num_args++;
+ XtSetArg(args[num_args], XtNfromVert, r_text); num_args++;
+ XtSetArg(args[num_args], XtNfromHoriz, search_button); num_args++;
+ XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
+ search->rep_one = XtCreateManagedWidget("replaceOne", commandWidgetClass,
+ form, args, num_args);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNlabel, "Replace All"); num_args++;
+ XtSetArg(args[num_args], XtNfromVert, r_text); num_args++;
+ XtSetArg(args[num_args], XtNfromHoriz, search->rep_one); num_args++;
+ XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
+ search->rep_all = XtCreateManagedWidget("replaceAll", commandWidgetClass,
+ form, args, num_args);
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNlabel, "Cancel"); num_args++;
+ XtSetArg(args[num_args], XtNfromVert, r_text); num_args++;
+ XtSetArg(args[num_args], XtNfromHoriz, search->rep_all); num_args++;
+ XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
+ XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
+ cancel = XtCreateManagedWidget(DISMISS_NAME, commandWidgetClass, form,
+ args, num_args);
+
+ XtAddCallback(search_button, XtNcallback, SearchButton, (XtPointer) search);
+ XtAddCallback(search->rep_one, XtNcallback, DoReplaceOne, (XtPointer) search);
+ XtAddCallback(search->rep_all, XtNcallback, DoReplaceAll, (XtPointer) search);
+ XtAddCallback(cancel, XtNcallback, PopdownSearch, (XtPointer) search);
+
+/*
+ * Initialize the text entry fields.
+ */
+
+ {
+ Pixel color;
+ num_args = 0;
+ XtSetArg(args[num_args], XtNbackground, &color); num_args++;
+ XtGetValues(search->rep_text, args, num_args);
+ num_args = 0;
+ XtSetArg(args[num_args], XtNborderColor, color); num_args++;
+ XtSetValues(search->rep_text, args, num_args);
+ XtSetKeyboardFocus(form, search->search_text);
+ }
+
+ SetSearchLabels(search, SEARCH_LABEL_1, SEARCH_LABEL_2, FALSE);
+
+/*
+ * Bind Extra translations.
+ */
+
+ trans = XtParseTranslationTable(search_text_trans);
+ XtOverrideTranslations(search->search_text, trans);
+
+ trans = XtParseTranslationTable(rep_text_trans);
+ XtOverrideTranslations(search->rep_text, trans);
+}
+
+/* Function Name: DoSearch
+ * Description: Performs a search.
+ * Arguments: search - the serach structure.
+ * Returns: TRUE if sucessful.
+ */
+
+/* ARGSUSED */
+static Boolean
+DoSearch(search)
+struct SearchAndReplace * search;
+{
+ char msg[BUFSIZ];
+ Widget tw = XtParent(search->search_popup);
+ XawTextPosition pos;
+ XawTextScanDirection dir;
+ XawTextBlock text;
+
+ TextWidget ctx = (TextWidget)tw;
+
+ text.ptr = GetStringRaw(search->search_text);
+ text.format = _XawTextFormat(ctx);
+#ifdef XAW_INTERNATIONALIZATION
+ if (text.format == XawFmtWide)
+ text.length = wcslen((wchar_t*)text.ptr);
+ else
+#endif
+ text.length = strlen(text.ptr);
+ text.firstPos = 0;
+
+ dir = (XawTextScanDirection)(int) ((XPointer)XawToggleGetCurrent(search->left_toggle) -
+ R_OFFSET);
+
+ pos = XawTextSearch( tw, dir, &text);
+
+
+ /* The Raw string in find.ptr may be WC I can't use here, so I re - call
+ GetString to get a tame version. */
+
+ if (pos == XawTextSearchError)
+ (void) sprintf( msg, "Could not find string ``%s''.", GetString( search->search_text ) );
+ else {
+ if (dir == XawsdRight)
+ XawTextSetInsertionPoint( tw, pos + text.length);
+ else
+ XawTextSetInsertionPoint( tw, pos);
+
+ XawTextSetSelection( tw, pos, pos + text.length);
+ search->selection_changed = FALSE; /* selection is good. */
+ return(TRUE);
+ }
+
+ XawTextUnsetSelection(tw);
+ SetSearchLabels(search, msg, "", TRUE);
+ return(FALSE);
+}
+
+/************************************************************
+ *
+ * This section of the file contains all the functions that
+ * the replace dialog box uses.
+ *
+ ************************************************************/
+
+/* Function Name: _XawTextDoReplaceAction
+ * Description: Action routine that can be bound to dialog box's
+ * Text Widget that will replace a string in the main
+ * Text Widget.
+ * Arguments: (Standard Action Routine args)
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+void
+_XawTextDoReplaceAction(w, event, params, num_params)
+Widget w;
+XEvent *event;
+String * params;
+Cardinal * num_params;
+{
+ TextWidget ctx = (TextWidget) XtParent(XtParent(XtParent(w)));
+ Boolean popdown = FALSE;
+
+ if ( (*num_params == 1) &&
+ ((params[0][0] == 'p') || (params[0][0] == 'P')) )
+ popdown = TRUE;
+
+ if (Replace( ctx->text.search, TRUE, popdown) && popdown)
+ PopdownSearch(w, (XtPointer) ctx->text.search, (XtPointer)NULL);
+}
+
+/* Function Name: DoReplaceOne
+ * Description: Replaces the first instance of the string
+ * in the search dialog's text widget
+ * with the one in the replace dialog's text widget.
+ * Arguments: w - *** Not Used ***.
+ * closure - a pointer to the search structure.
+ * call_data - *** Not Used ***.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+DoReplaceOne(w, closure, call_data)
+Widget w; /* The Button Pressed. */
+XtPointer closure; /* Text Widget. */
+XtPointer call_data; /* unused */
+{
+ Replace( (struct SearchAndReplace *) closure, TRUE, FALSE);
+}
+
+/* Function Name: DoReplaceOne
+ * Description: Replaces every instance of the string
+ * in the search dialog's text widget
+ * with the one in the replace dialog's text widget.
+ * Arguments: w - *** Not Used ***.
+ * closure - a pointer to the search structure.
+ * call_data - *** Not Used ***.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+DoReplaceAll(w, closure, call_data)
+Widget w; /* The Button Pressed. */
+XtPointer closure; /* Text Widget. */
+XtPointer call_data; /* unused */
+{
+ Replace( (struct SearchAndReplace *) closure, FALSE, FALSE);
+}
+
+/* Function Name: Replace
+ * Description: This is the function that does the real work of
+ * replacing strings in the main text widget.
+ * Arguments: tw - the Text Widget to replce the string in.
+ * once_only - If TRUE then only replace the first one found.
+ * other replace all of them.
+ * show_current - If true then leave the selection on the
+ * string that was just replaced, otherwise
+ * move it onto the next one.
+ * Returns: none.
+ */
+
+static Boolean
+Replace(search, once_only, show_current)
+struct SearchAndReplace * search;
+Boolean once_only, show_current;
+{
+ XawTextPosition pos, new_pos, end_pos;
+ XawTextScanDirection dir;
+ XawTextBlock find, replace;
+ Widget tw = XtParent(search->search_popup);
+ int count = 0;
+
+ TextWidget ctx = (TextWidget)tw;
+
+ find.ptr = GetStringRaw( search->search_text);
+ find.format = _XawTextFormat(ctx);
+#ifdef XAW_INTERNATIONALIZATION
+ if (find.format == XawFmtWide)
+ find.length = wcslen((wchar_t*)find.ptr);
+ else
+#endif
+ find.length = strlen(find.ptr);
+ find.firstPos = 0;
+
+ replace.ptr = GetStringRaw(search->rep_text);
+ replace.firstPos = 0;
+ replace.format = _XawTextFormat(ctx);
+#ifdef XAW_INTERNATIONALIZATION
+ if (replace.format == XawFmtWide)
+ replace.length = wcslen((wchar_t*)replace.ptr);
+ else
+#endif
+ replace.length = strlen(replace.ptr);
+
+ dir = (XawTextScanDirection)(int) ((XPointer)XawToggleGetCurrent(search->left_toggle) -
+ R_OFFSET);
+ /* CONSTCOND */
+ while (TRUE) {
+ if (count != 0) {
+ new_pos = XawTextSearch( tw, dir, &find);
+
+ if ( (new_pos == XawTextSearchError) ) {
+ if (count == 0) {
+ char msg[BUFSIZ];
+
+ /* The Raw string in find.ptr may be WC I can't use here,
+ so I call GetString to get a tame version.*/
+
+ (void) sprintf( msg, "%s %s %s", "*** Error: Could not find string ``",
+ GetString( search->search_text ), "''. ***");
+ SetSearchLabels(search, msg, "", TRUE);
+ return(FALSE);
+ }
+ else
+ break;
+ }
+ pos = new_pos;
+ end_pos = pos + find.length;
+ }
+ else {
+ XawTextGetSelectionPos(tw, &pos, &end_pos);
+
+ if (search->selection_changed) {
+ SetSearchLabels(search, "Selection has been modified, aborting.",
+ "", TRUE);
+ return(FALSE);
+ }
+ if (pos == end_pos)
+ return(FALSE);
+ }
+
+ if (XawTextReplace(tw, pos, end_pos, &replace) != XawEditDone) {
+ char msg[BUFSIZ];
+
+ (void) sprintf( msg, "'%s' with '%s'. ***", find.ptr, replace.ptr);
+ SetSearchLabels(search, "*** Error while replacing", msg, TRUE);
+ return(FALSE);
+ }
+
+ if (dir == XawsdRight)
+ XawTextSetInsertionPoint( tw, pos + replace.length);
+ else
+ XawTextSetInsertionPoint( tw, pos);
+
+ if (once_only)
+ if (show_current)
+ break;
+ else {
+ DoSearch(search);
+ return(TRUE);
+ }
+ count++;
+ }
+
+ if (replace.length == 0)
+ XawTextUnsetSelection(tw);
+ else
+ XawTextSetSelection( tw, pos, pos + replace.length);
+
+ return(TRUE);
+}
+
+/* Function Name: SetSearchLabels
+ * Description: Sets both the search labels, and also rings the bell
+ * Arguments: search - the search structure.
+ * msg1, msg2 - message to put in each search label.
+ * bell - if TRUE then ring bell.
+ * Returns: none.
+ */
+
+static void
+SetSearchLabels(search, msg1, msg2, bell)
+struct SearchAndReplace * search;
+String msg1, msg2;
+Boolean bell;
+{
+ (void) SetResource( search->label1, XtNlabel, (XtArgVal) msg1);
+ (void) SetResource( search->label2, XtNlabel, (XtArgVal) msg2);
+ if (bell)
+ XBell(XtDisplay(search->search_popup), 0);
+}
+
+/************************************************************
+ *
+ * This section of the file contains utility routines used by
+ * other functions in this file.
+ *
+ ************************************************************/
+
+
+/* Function Name: _XawTextSetField
+ * Description: Action routine that can be bound to dialog box's
+ * Text Widget that will send input to the field specified.
+ * Arguments: (Standard Action Routine args)
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+void
+_XawTextSetField(w, event, params, num_params)
+Widget w;
+XEvent *event;
+String * params;
+Cardinal * num_params;
+{
+ struct SearchAndReplace * search;
+ Widget new, old;
+
+ search = ((TextWidget) XtParent(XtParent(XtParent(w))))->text.search;
+
+ if (*num_params != 1) {
+ SetSearchLabels(search, "*** Error: SetField Action must have",
+ "exactly one argument. ***", TRUE);
+ return;
+ }
+ switch (params[0][0]) {
+ case 's':
+ case 'S':
+ new = search->search_text;
+ old = search->rep_text;
+ break;
+ case 'r':
+ case 'R':
+ old = search->search_text;
+ new = search->rep_text;
+ break;
+ default:
+ SetSearchLabels(search, "*** Error: SetField Action's first Argument must",
+ "be either 'Search' or 'Replace'. ***", TRUE);
+ return;
+ }
+ _SetField(new, old);
+}
+
+/* Function Name: SetField
+ * Description: Sets the current text field.
+ * Arguments: new, old - new and old text fields.
+ * Returns: none
+ */
+
+static void
+_SetField(new, old)
+Widget new, old;
+{
+ Arg args[2];
+ Pixel new_border, old_border, old_bg;
+
+ if (!XtIsSensitive(new)) {
+ XBell(XtDisplay(old), 0); /* Don't set field to an inactive Widget. */
+ return;
+ }
+
+ XtSetKeyboardFocus(XtParent(new), new);
+
+ XtSetArg(args[0], XtNborderColor, &old_border);
+ XtSetArg(args[1], XtNbackground, &old_bg);
+ XtGetValues(new, args, TWO);
+
+ XtSetArg(args[0], XtNborderColor, &new_border);
+ XtGetValues(old, args, ONE);
+
+ if (old_border != old_bg) /* Colors are already correct, return. */
+ return;
+
+ SetResource(old, XtNborderColor, (XtArgVal) old_border);
+ SetResource(new, XtNborderColor, (XtArgVal) new_border);
+}
+
+/* Function Name: SetResourceByName
+ * Description: Sets a resource in any of the dialog children given
+ * name of the child and the shell widget of the dialog.
+ * Arguments: shell - shell widget of the popup.
+ * name - name of the child.
+ * res_name - name of the resource.
+ * value - the value of the resource.
+ * Returns: TRUE if sucessful.
+ */
+
+static Boolean
+SetResourceByName(shell, name, res_name, value)
+Widget shell;
+char * name, * res_name;
+XtArgVal value;
+{
+ Widget temp_widget;
+ char buf[BUFSIZ];
+
+ (void) sprintf(buf, "%s.%s", FORM_NAME, name);
+
+ if ( (temp_widget = XtNameToWidget(shell, buf)) != NULL) {
+ SetResource(temp_widget, res_name, value);
+ return(TRUE);
+ }
+ return(FALSE);
+}
+
+/* Function Name: SetResource
+ * Description: Sets a resource in a widget
+ * Arguments: w - the widget.
+ * res_name - name of the resource.
+ * value - the value of the resource.
+ * Returns: none.
+ */
+
+static void
+SetResource(w, res_name, value)
+Widget w;
+char * res_name;
+XtArgVal value;
+{
+ Arg args[1];
+
+ XtSetArg(args[0], res_name, value);
+ XtSetValues( w, args, ONE );
+}
+
+/* Function Name: GetString{Raw}
+ * Description: Gets the value for the string in the popup.
+ * Arguments: text - the text widget whose string we will get.
+ *
+ * GetString returns the string as a MB.
+ * GetStringRaw returns the exact buffer contents suitable for a search.
+ *
+ */
+
+static String
+GetString(text)
+Widget text;
+{
+ String string;
+ Arg args[1];
+
+ XtSetArg( args[0], XtNstring, &string );
+ XtGetValues( text, args, ONE );
+ return(string);
+}
+
+static String
+GetStringRaw(tw)
+Widget tw;
+{
+ TextWidget ctx = (TextWidget)tw;
+ XawTextPosition last;
+ char *_XawTextGetText();
+
+ last = XawTextSourceScan(ctx->text.source, 0, XawstAll, XawsdRight,
+ ctx->text.mult, TRUE);
+ return (_XawTextGetText(ctx, 0, last));
+}
+
+/* Function Name: CenterWidgetOnPoint.
+ * Description: Centers a shell widget on a point relative to
+ * the root window.
+ * Arguments: w - the shell widget.
+ * event - event containing the location of the point
+ * Returns: none.
+ *
+ * NOTE: The widget is not allowed to go off the screen.
+ */
+
+static void
+CenterWidgetOnPoint(w, event)
+Widget w;
+XEvent *event;
+{
+ Arg args[3];
+ Cardinal num_args;
+ Dimension width, height, b_width;
+ Position x = 0, y = 0, max_x, max_y;
+
+ if (event != NULL) {
+ switch (event->type) {
+ case ButtonPress:
+ case ButtonRelease:
+ x = event->xbutton.x_root;
+ y = event->xbutton.y_root;
+ break;
+ case KeyPress:
+ case KeyRelease:
+ x = event->xkey.x_root;
+ y = event->xkey.y_root;
+ break;
+ default:
+ return;
+ }
+ }
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNwidth, &width); num_args++;
+ XtSetArg(args[num_args], XtNheight, &height); num_args++;
+ XtSetArg(args[num_args], XtNborderWidth, &b_width); num_args++;
+ XtGetValues(w, args, num_args);
+
+ width += 2 * b_width;
+ height += 2 * b_width;
+
+ x -= ( (Position) width/2 );
+ if (x < 0) x = 0;
+ if ( x > (max_x = (Position) (XtScreen(w)->width - width)) ) x = max_x;
+
+ y -= ( (Position) height/2 );
+ if (y < 0) y = 0;
+ if ( y > (max_y = (Position) (XtScreen(w)->height - height)) ) y = max_y;
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNx, x); num_args++;
+ XtSetArg(args[num_args], XtNy, y); num_args++;
+ XtSetValues(w, args, num_args);
+}
+
+/* Function Name: CreateDialog
+ * Description: Actually creates a dialog.
+ * Arguments: parent - the parent of the dialog - the main text widget.
+ * ptr - initial_string for the dialog.
+ * name - name of the dialog.
+ * func - function to create the children of the dialog.
+ * Returns: the popup shell of the dialog.
+ *
+ * NOTE:
+ *
+ * The function argument is passed the following arguements.
+ *
+ * form - the from widget that is the dialog.
+ * ptr - the initial string for the dialog's text widget.
+ * parent - the parent of the dialog - the main text widget.
+ */
+
+static Widget
+CreateDialog(parent, ptr, name, func)
+Widget parent;
+String ptr, name;
+void (*func)();
+{
+ Widget popup, form;
+ Arg args[5];
+ Cardinal num_args;
+
+ num_args = 0;
+ XtSetArg(args[num_args], XtNiconName, name); num_args++;
+ XtSetArg(args[num_args], XtNgeometry, NULL); num_args++;
+ XtSetArg(args[num_args], XtNallowShellResize, TRUE); num_args++;
+ XtSetArg(args[num_args], XtNtransientFor, GetShell(parent)); num_args++;
+ popup = XtCreatePopupShell(name, transientShellWidgetClass,
+ parent, args, num_args);
+
+ form = XtCreateManagedWidget(FORM_NAME, formWidgetClass, popup,
+ (ArgList)NULL, ZERO);
+ XtManageChild (form);
+
+ (*func) (form, ptr, parent);
+ return(popup);
+}
+
+ /* Function Name: GetShell
+ * Description: Walks up the widget hierarchy to find the
+ * nearest shell widget.
+ * Arguments: w - the widget whose parent shell should be returned.
+ * Returns: The shell widget among the ancestors of w that is the
+ * fewest levels up in the widget hierarchy.
+ */
+
+static Widget
+GetShell(w)
+Widget w;
+{
+ while ((w != NULL) && !XtIsShell(w))
+ w = XtParent(w);
+
+ return (w);
+}
+
+static Boolean InParams(str, p, n)
+ String str;
+ String *p;
+ Cardinal n;
+{
+ int i;
+ for (i=0; i < n; p++, i++)
+ if (! XmuCompareISOLatin1(*p, str)) return True;
+ return False;
+}
+
+static char *WM_DELETE_WINDOW = "WM_DELETE_WINDOW";
+
+static void WMProtocols(w, event, params, num_params)
+ Widget w; /* popup shell */
+ XEvent *event;
+ String *params;
+ Cardinal *num_params;
+{
+ Atom wm_delete_window;
+ Atom wm_protocols;
+
+ wm_delete_window = XInternAtom(XtDisplay(w), WM_DELETE_WINDOW, True);
+ wm_protocols = XInternAtom(XtDisplay(w), "WM_PROTOCOLS", True);
+
+ /* Respond to a recognized WM protocol request iff
+ * event type is ClientMessage and no parameters are passed, or
+ * event type is ClientMessage and event data is matched to parameters, or
+ * event type isn't ClientMessage and parameters make a request.
+ */
+#define DO_DELETE_WINDOW InParams(WM_DELETE_WINDOW, params, *num_params)
+
+ if ((event->type == ClientMessage &&
+ event->xclient.message_type == wm_protocols &&
+ event->xclient.data.l[0] == wm_delete_window &&
+ (*num_params == 0 || DO_DELETE_WINDOW))
+ ||
+ (event->type != ClientMessage && DO_DELETE_WINDOW)) {
+
+#undef DO_DELETE_WINDOW
+
+ Widget cancel;
+ char descendant[DISMISS_NAME_LEN + 2];
+ (void) sprintf(descendant, "*%s", DISMISS_NAME);
+ cancel = XtNameToWidget(w, descendant);
+ if (cancel) XtCallCallbacks(cancel, XtNcallback, (XtPointer)NULL);
+ }
+}
+
+static void SetWMProtocolTranslations(w)
+ Widget w; /* realized popup shell */
+{
+ int i;
+ XtAppContext app_context;
+ Atom wm_delete_window;
+ static XtTranslations compiled_table; /* initially 0 */
+ static XtAppContext *app_context_list; /* initially 0 */
+ static Cardinal list_size; /* initially 0 */
+
+ app_context = XtWidgetToApplicationContext(w);
+
+ /* parse translation table once */
+ if (! compiled_table) compiled_table = XtParseTranslationTable
+ ("<Message>WM_PROTOCOLS: XawWMProtocols()\n");
+
+ /* add actions once per application context */
+ for (i=0; i < list_size && app_context_list[i] != app_context; i++) ;
+ if (i == list_size) {
+ XtActionsRec actions[1];
+ actions[0].string = "XawWMProtocols";
+ actions[0].proc = WMProtocols;
+ list_size++;
+ app_context_list = (XtAppContext *) XtRealloc
+ ((char *)app_context_list, list_size * sizeof(XtAppContext));
+ XtAppAddActions(app_context, actions, 1);
+ app_context_list[i] = app_context;
+ }
+
+ /* establish communication between the window manager and each shell */
+ XtAugmentTranslations(w, compiled_table);
+ wm_delete_window = XInternAtom(XtDisplay(w), WM_DELETE_WINDOW, False);
+ (void) XSetWMProtocols(XtDisplay(w), XtWindow(w), &wm_delete_window, 1);
+}
diff --git a/src/TextSink.c b/src/TextSink.c
new file mode 100644
index 0000000..7c7e2a9
--- /dev/null
+++ b/src/TextSink.c
@@ -0,0 +1,779 @@
+/* $XConsortium: TextSink.c,v 1.19 94/04/17 20:13:11 kaleb Exp $ */
+/*
+
+Copyright (c) 1989, 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.
+
+*/
+
+/*
+ * Author: Chris Peterson, MIT X Consortium.
+ *
+ * Much code taken from X11R3 AsciiSink.
+ */
+
+/*
+ * TextSink.c - TextSink object. (For use with the text widget).
+ *
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/TextSinkP.h>
+#include <X11/Xaw3d/TextP.h>
+
+/****************************************************************
+ *
+ * Full class record constant
+ *
+ ****************************************************************/
+
+static void ClassPartInitialize(), Initialize(), Destroy();
+static Boolean SetValues();
+
+static int MaxHeight(), MaxLines();
+static void DisplayText(), InsertCursor(), ClearToBackground(), FindPosition();
+static void FindDistance(), Resolve(), SetTabs(), GetCursorBounds();
+
+#define offset(field) XtOffsetOf(TextSinkRec, text_sink.field)
+static XtResource resources[] = {
+ {XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel),
+ offset(foreground), XtRString, XtDefaultForeground},
+ {XtNbackground, XtCBackground, XtRPixel, sizeof (Pixel),
+ offset(background), XtRString, XtDefaultBackground},
+};
+#undef offset
+
+#define SuperClass (&objectClassRec)
+TextSinkClassRec textSinkClassRec = {
+ {
+/* core_class fields */
+ /* superclass */ (WidgetClass) SuperClass,
+ /* class_name */ "TextSink",
+ /* widget_size */ sizeof(TextSinkRec),
+ /* class_initialize */ XawInitializeWidgetSet,
+ /* class_part_initialize */ ClassPartInitialize,
+ /* class_inited */ FALSE,
+ /* initialize */ Initialize,
+ /* initialize_hook */ NULL,
+ /* obj1 */ NULL,
+ /* obj2 */ NULL,
+ /* obj3 */ 0,
+ /* resources */ resources,
+ /* num_resources */ XtNumber(resources),
+ /* xrm_class */ NULLQUARK,
+ /* obj4 */ FALSE,
+ /* obj5 */ FALSE,
+ /* obj6 */ FALSE,
+ /* obj7 */ FALSE,
+ /* destroy */ Destroy,
+ /* obj8 */ NULL,
+ /* obj9 */ NULL,
+ /* set_values */ SetValues,
+ /* set_values_hook */ NULL,
+ /* obj10 */ NULL,
+ /* get_values_hook */ NULL,
+ /* obj11 */ NULL,
+ /* version */ XtVersion,
+ /* callback_private */ NULL,
+ /* obj12 */ NULL,
+ /* obj13 */ NULL,
+ /* obj14 */ NULL,
+ /* extension */ NULL
+ },
+/* textSink_class fields */
+ {
+ /* DisplayText */ DisplayText,
+ /* InsertCursor */ InsertCursor,
+ /* ClearToBackground */ ClearToBackground,
+ /* FindPosition */ FindPosition,
+ /* FindDistance */ FindDistance,
+ /* Resolve */ Resolve,
+ /* MaxLines */ MaxLines,
+ /* MaxHeight */ MaxHeight,
+ /* SetTabs */ SetTabs,
+ /* GetCursorBounds */ GetCursorBounds,
+ }
+};
+
+WidgetClass textSinkObjectClass = (WidgetClass)&textSinkClassRec;
+
+static void
+ClassPartInitialize(wc)
+WidgetClass wc;
+{
+ TextSinkObjectClass t_src, superC;
+
+ t_src = (TextSinkObjectClass) wc;
+ superC = (TextSinkObjectClass) t_src->object_class.superclass;
+
+/*
+ * We don't need to check for null super since we'll get to TextSink
+ * eventually.
+ */
+
+ if (t_src->text_sink_class.DisplayText == XtInheritDisplayText)
+ t_src->text_sink_class.DisplayText = superC->text_sink_class.DisplayText;
+
+ if (t_src->text_sink_class.InsertCursor == XtInheritInsertCursor)
+ t_src->text_sink_class.InsertCursor =
+ superC->text_sink_class.InsertCursor;
+
+ if (t_src->text_sink_class.ClearToBackground== XtInheritClearToBackground)
+ t_src->text_sink_class.ClearToBackground =
+ superC->text_sink_class.ClearToBackground;
+
+ if (t_src->text_sink_class.FindPosition == XtInheritFindPosition)
+ t_src->text_sink_class.FindPosition =
+ superC->text_sink_class.FindPosition;
+
+ if (t_src->text_sink_class.FindDistance == XtInheritFindDistance)
+ t_src->text_sink_class.FindDistance =
+ superC->text_sink_class.FindDistance;
+
+ if (t_src->text_sink_class.Resolve == XtInheritResolve)
+ t_src->text_sink_class.Resolve = superC->text_sink_class.Resolve;
+
+ if (t_src->text_sink_class.MaxLines == XtInheritMaxLines)
+ t_src->text_sink_class.MaxLines = superC->text_sink_class.MaxLines;
+
+ if (t_src->text_sink_class.MaxHeight == XtInheritMaxHeight)
+ t_src->text_sink_class.MaxHeight = superC->text_sink_class.MaxHeight;
+
+ if (t_src->text_sink_class.SetTabs == XtInheritSetTabs)
+ t_src->text_sink_class.SetTabs = superC->text_sink_class.SetTabs;
+
+ if (t_src->text_sink_class.GetCursorBounds == XtInheritGetCursorBounds)
+ t_src->text_sink_class.GetCursorBounds =
+ superC->text_sink_class.GetCursorBounds;
+}
+
+/* Function Name: Initialize
+ * Description: Initializes the TextSink Object.
+ * Arguments: request, new - the requested and new values for the object
+ * instance.
+ * Returns: none.
+ *
+ */
+
+/* ARGSUSED */
+static void
+Initialize(request, new, args, num_args)
+Widget request, new;
+ArgList args;
+Cardinal *num_args;
+{
+ TextSinkObject sink = (TextSinkObject) new;
+
+ sink->text_sink.tab_count = 0; /* Initialize the tab stops. */
+ sink->text_sink.tabs = NULL;
+ sink->text_sink.char_tabs = NULL;
+}
+
+/* Function Name: Destroy
+ * Description: This function cleans up when the object is
+ * destroyed.
+ * Arguments: w - the TextSink Object.
+ * Returns: none.
+ */
+
+static void
+Destroy(w)
+Widget w;
+{
+ TextSinkObject sink = (TextSinkObject) w;
+
+ XtFree((char *) sink->text_sink.tabs);
+ XtFree((char *) sink->text_sink.char_tabs);
+}
+
+/* Function Name: SetValues
+ * Description: Sets the values for the TextSink
+ * Arguments: current - current state of the object.
+ * request - what was requested.
+ * new - what the object will become.
+ * Returns: True if redisplay is needed.
+ */
+
+/* ARGSUSED */
+static Boolean
+SetValues(current, request, new, args, num_args)
+Widget current, request, new;
+ArgList args;
+Cardinal *num_args;
+{
+ TextSinkObject w = (TextSinkObject) new;
+ TextSinkObject old_w = (TextSinkObject) current;
+
+ if (w->text_sink.foreground != old_w->text_sink.foreground)
+ ((TextWidget)XtParent(new))->text.redisplay_needed = True;
+
+ return FALSE;
+}
+
+/************************************************************
+ *
+ * Class specific methods.
+ *
+ ************************************************************/
+
+/* Function Name: DisplayText
+ * Description: Stub function that in subclasses will display text.
+ * Arguments: w - the TextSink Object.
+ * x, y - location to start drawing text.
+ * pos1, pos2 - location of starting and ending points
+ * in the text buffer.
+ * highlight - hightlight this text?
+ * Returns: none.
+ *
+ * This function doesn't actually display anything, it is only a place
+ * holder.
+ */
+
+/* ARGSUSED */
+static void
+DisplayText(w, x, y, pos1, pos2, highlight)
+Widget w;
+Position x, y;
+Boolean highlight;
+XawTextPosition pos1, pos2;
+{
+ return;
+}
+
+/* Function Name: InsertCursor
+ * Description: Places the InsertCursor.
+ * Arguments: w - the TextSink Object.
+ * x, y - location for the cursor.
+ * staye - whether to turn the cursor on, or off.
+ * Returns: none.
+ *
+ * This function doesn't actually display anything, it is only a place
+ * holder.
+ */
+
+/* ARGSUSED */
+static void
+InsertCursor(w, x, y, state)
+Widget w;
+Position x, y;
+XawTextInsertState state;
+{
+ return;
+}
+
+/* Function Name: ClearToBackground
+ * Description: Clears a region of the sink to the background color.
+ * Arguments: w - the TextSink Object.
+ * x, y - location of area to clear.
+ * width, height - size of area to clear
+ * Returns: void.
+ *
+ */
+
+/* ARGSUSED */
+static void
+ClearToBackground (w, x, y, width, height)
+Widget w;
+Position x, y;
+Dimension width, height;
+{
+/*
+ * Don't clear in height or width are zero.
+ * XClearArea() has special semantic for these values.
+ */
+
+ if ( (height == 0) || (width == 0) ) return;
+ XClearArea(XtDisplayOfObject(w), XtWindowOfObject(w),
+ x, y, width, height, False);
+}
+
+/* Function Name: FindPosition
+ * Description: Finds a position in the text.
+ * Arguments: w - the TextSink Object.
+ * fromPos - reference position.
+ * fromX - reference location.
+ * width, - width of section to paint text.
+ * stopAtWordBreak - returned position is a word break?
+ * resPos - Position to return. *** RETURNED ***
+ * resWidth - Width actually used. *** RETURNED ***
+ * resHeight - Height actually used. *** RETURNED ***
+ * Returns: none (see above).
+ */
+
+/* ARGSUSED */
+static void
+FindPosition(w, fromPos, fromx, width, stopAtWordBreak,
+ resPos, resWidth, resHeight)
+Widget w;
+XawTextPosition fromPos;
+int fromx, width;
+Boolean stopAtWordBreak;
+XawTextPosition *resPos;
+int *resWidth, *resHeight;
+{
+ *resPos = fromPos;
+ *resHeight = *resWidth = 0;
+}
+
+/* Function Name: FindDistance
+ * Description: Find the Pixel Distance between two text Positions.
+ * Arguments: w - the TextSink Object.
+ * fromPos - starting Position.
+ * fromX - x location of starting Position.
+ * toPos - end Position.
+ * resWidth - Distance between fromPos and toPos.
+ * resPos - Acutal toPos used.
+ * resHeight - Height required by this text.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+FindDistance (w, fromPos, fromx, toPos, resWidth, resPos, resHeight)
+Widget w;
+XawTextPosition fromPos;
+int fromx;
+XawTextPosition toPos;
+int *resWidth;
+XawTextPosition *resPos;
+int *resHeight;
+{
+ *resWidth = *resHeight = 0;
+ *resPos = fromPos;
+}
+
+/* Function Name: Resolve
+ * Description: Resloves a location to a position.
+ * Arguments: w - the TextSink Object.
+ * pos - a reference Position.
+ * fromx - a reference Location.
+ * width - width to move.
+ * resPos - the resulting position.
+ * Returns: none
+ */
+
+/* ARGSUSED */
+static void
+Resolve (w, pos, fromx, width, resPos)
+Widget w;
+XawTextPosition pos;
+int fromx, width;
+XawTextPosition *resPos;
+{
+ *resPos = pos;
+}
+
+/* Function Name: MaxLines
+ * Description: Finds the Maximum number of lines that will fit in
+ * a given height.
+ * Arguments: w - the TextSink Object.
+ * height - height to fit lines into.
+ * Returns: the number of lines that will fit.
+ */
+
+/* ARGSUSED */
+static int
+MaxLines(w, height)
+Widget w;
+Dimension height;
+{
+ /*
+ * The fontset has gone down to descent Sink Widget, so
+ * the functions such MaxLines, SetTabs... are bound to the descent.
+ *
+ * by Li Yuhong, Jan. 15, 1991
+ */
+ return 0;
+}
+
+/* Function Name: MaxHeight
+ * Description: Finds the Minium height that will contain a given number
+ * lines.
+ * Arguments: w - the TextSink Object.
+ * lines - the number of lines.
+ * Returns: the height.
+ */
+
+/* ARGSUSED */
+static int
+MaxHeight(w, lines)
+Widget w;
+int lines;
+{
+ return 0;
+}
+
+/* Function Name: SetTabs
+ * Description: Sets the Tab stops.
+ * Arguments: w - the TextSink Object.
+ * tab_count - the number of tabs in the list.
+ * tabs - the text positions of the tabs.
+ * Returns: none
+ */
+
+/*ARGSUSED*/
+static void
+SetTabs(w, tab_count, tabs)
+Widget w;
+int tab_count;
+short *tabs;
+{
+ return;
+}
+
+/* Function Name: GetCursorBounds
+ * Description: Finds the bounding box for the insert curor (caret).
+ * Arguments: w - the TextSinkObject.
+ * rect - an X rectance containing the cursor bounds.
+ * Returns: none (fills in rect).
+ */
+
+/* ARGSUSED */
+static void
+GetCursorBounds(w, rect)
+Widget w;
+XRectangle * rect;
+{
+ rect->x = rect->y = rect->width = rect->height = 0;
+}
+/************************************************************
+ *
+ * Public Functions.
+ *
+ ************************************************************/
+
+
+/* Function Name: XawTextSinkDisplayText
+ * Description: Stub function that in subclasses will display text.
+ * Arguments: w - the TextSink Object.
+ * x, y - location to start drawing text.
+ * pos1, pos2 - location of starting and ending points
+ * in the text buffer.
+ * highlight - hightlight this text?
+ * Returns: none.
+ *
+ * This function doesn't actually display anything, it is only a place
+ * holder.
+ */
+
+/* ARGSUSED */
+void
+#if NeedFunctionPrototypes
+XawTextSinkDisplayText(Widget w,
+#if NeedWidePrototypes
+ /* Position */ int x, /* Position */ int y,
+#else
+ Position x, Position y,
+#endif
+ XawTextPosition pos1, XawTextPosition pos2,
+#if NeedWidePrototypes
+ /* Boolean */ int highlight)
+#else
+ Boolean highlight)
+#endif
+#else
+XawTextSinkDisplayText(w, x, y, pos1, pos2, highlight)
+Widget w;
+Position x, y;
+Boolean highlight;
+XawTextPosition pos1, pos2;
+#endif
+{
+ TextSinkObjectClass class = (TextSinkObjectClass) w->core.widget_class;
+
+ (*class->text_sink_class.DisplayText)(w, x, y, pos1, pos2, highlight);
+}
+
+/* Function Name: XawTextSinkInsertCursor
+ * Description: Places the InsertCursor.
+ * Arguments: w - the TextSink Object.
+ * x, y - location for the cursor.
+ * staye - whether to turn the cursor on, or off.
+ * Returns: none.
+ *
+ * This function doesn't actually display anything, it is only a place
+ * holder.
+ */
+
+/* ARGSUSED */
+void
+#if NeedFunctionPrototypes
+XawTextSinkInsertCursor(Widget w,
+#if NeedWidePrototypes
+ int x, int y, int state)
+#else
+ Position x, Position y, XawTextInsertState state)
+#endif
+#else
+XawTextSinkInsertCursor(w, x, y, state)
+Widget w;
+Position x, y;
+XawTextInsertState state;
+#endif
+{
+ TextSinkObjectClass class = (TextSinkObjectClass) w->core.widget_class;
+
+ (*class->text_sink_class.InsertCursor)(w, x, y, state);
+}
+
+
+/* Function Name: XawTextSinkClearToBackground
+ * Description: Clears a region of the sink to the background color.
+ * Arguments: w - the TextSink Object.
+ * x, y - location of area to clear.
+ * width, height - size of area to clear
+ * Returns: void.
+ *
+ * This function doesn't actually display anything, it is only a place
+ * holder.
+ */
+
+/* ARGSUSED */
+void
+#if NeedFunctionPrototypes
+XawTextSinkClearToBackground (Widget w,
+#if NeedWidePrototypes
+ int x, int y, int width, int height)
+#else
+ Position x, Position y,
+ Dimension width, Dimension height)
+#endif
+#else
+XawTextSinkClearToBackground (w, x, y, width, height)
+Widget w;
+Position x, y;
+Dimension width, height;
+#endif
+{
+ TextSinkObjectClass class = (TextSinkObjectClass) w->core.widget_class;
+
+ (*class->text_sink_class.ClearToBackground)(w, x, y, width, height);
+}
+
+/* Function Name: XawTextSinkFindPosition
+ * Description: Finds a position in the text.
+ * Arguments: w - the TextSink Object.
+ * fromPos - reference position.
+ * fromX - reference location.
+ * width, - width of section to paint text.
+ * stopAtWordBreak - returned position is a word break?
+ * resPos - Position to return. *** RETURNED ***
+ * resWidth - Width actually used. *** RETURNED ***
+ * resHeight - Height actually used. *** RETURNED ***
+ * Returns: none (see above).
+ */
+
+/* ARGSUSED */
+void
+#if NeedFunctionPrototypes
+XawTextSinkFindPosition(Widget w, XawTextPosition fromPos, int fromx,
+ int width,
+#if NeedWidePrototypes
+ /* Boolean */ int stopAtWordBreak,
+#else
+ Boolean stopAtWordBreak,
+#endif
+ XawTextPosition *resPos, int *resWidth, int *resHeight)
+#else
+XawTextSinkFindPosition(w, fromPos, fromx, width, stopAtWordBreak,
+ resPos, resWidth, resHeight)
+Widget w;
+XawTextPosition fromPos;
+int fromx, width;
+Boolean stopAtWordBreak;
+XawTextPosition *resPos;
+int *resWidth, *resHeight;
+#endif
+{
+ TextSinkObjectClass class = (TextSinkObjectClass) w->core.widget_class;
+
+ (*class->text_sink_class.FindPosition)(w, fromPos, fromx, width,
+ stopAtWordBreak,
+ resPos, resWidth, resHeight);
+}
+
+/* Function Name: XawTextSinkFindDistance
+ * Description: Find the Pixel Distance between two text Positions.
+ * Arguments: w - the TextSink Object.
+ * fromPos - starting Position.
+ * fromX - x location of starting Position.
+ * toPos - end Position.
+ * resWidth - Distance between fromPos and toPos.
+ * resPos - Acutal toPos used.
+ * resHeight - Height required by this text.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+void
+#if NeedFunctionPrototypes
+XawTextSinkFindDistance (Widget w, XawTextPosition fromPos, int fromx,
+ XawTextPosition toPos, int *resWidth,
+ XawTextPosition *resPos, int *resHeight)
+#else
+XawTextSinkFindDistance (w, fromPos, fromx, toPos, resWidth, resPos, resHeight)
+Widget w;
+XawTextPosition fromPos, toPos, *resPos;
+int fromx, *resWidth, *resHeight;
+#endif
+{
+ TextSinkObjectClass class = (TextSinkObjectClass) w->core.widget_class;
+
+ (*class->text_sink_class.FindDistance)(w, fromPos, fromx, toPos,
+ resWidth, resPos, resHeight);
+}
+
+/* Function Name: XawTextSinkResolve
+ * Description: Resloves a location to a position.
+ * Arguments: w - the TextSink Object.
+ * pos - a reference Position.
+ * fromx - a reference Location.
+ * width - width to move.
+ * resPos - the resulting position.
+ * Returns: none
+ */
+
+/* ARGSUSED */
+void
+#if NeedFunctionPrototypes
+XawTextSinkResolve(Widget w, XawTextPosition pos, int fromx, int width,
+ XawTextPosition *resPos)
+#else
+XawTextSinkResolve(w, pos, fromx, width, resPos)
+Widget w;
+XawTextPosition pos;
+int fromx, width;
+XawTextPosition *resPos;
+#endif
+{
+ TextSinkObjectClass class = (TextSinkObjectClass) w->core.widget_class;
+
+ (*class->text_sink_class.Resolve)(w, pos, fromx, width, resPos);
+}
+
+/* Function Name: XawTextSinkMaxLines
+ * Description: Finds the Maximum number of lines that will fit in
+ * a given height.
+ * Arguments: w - the TextSink Object.
+ * height - height to fit lines into.
+ * Returns: the number of lines that will fit.
+ */
+
+/* ARGSUSED */
+int
+#if NeedFunctionPrototypes
+XawTextSinkMaxLines(Widget w,
+#if NeedWidePrototypes
+ /* Dimension */ int height)
+#else
+ Dimension height)
+#endif
+#else
+XawTextSinkMaxLines(w, height)
+Widget w;
+Dimension height;
+#endif
+{
+ TextSinkObjectClass class = (TextSinkObjectClass) w->core.widget_class;
+
+ return((*class->text_sink_class.MaxLines)(w, height));
+}
+
+/* Function Name: XawTextSinkMaxHeight
+ * Description: Finds the Minimum height that will contain a given number
+ * lines.
+ * Arguments: w - the TextSink Object.
+ * lines - the number of lines.
+ * Returns: the height.
+ */
+
+/* ARGSUSED */
+int
+#if NeedFunctionPrototypes
+XawTextSinkMaxHeight(Widget w, int lines)
+#else
+XawTextSinkMaxHeight(w, lines)
+Widget w;
+int lines;
+#endif
+{
+ TextSinkObjectClass class = (TextSinkObjectClass) w->core.widget_class;
+
+ return((*class->text_sink_class.MaxHeight)(w, lines));
+}
+
+/* Function Name: XawTextSinkSetTabs
+ * Description: Sets the Tab stops.
+ * Arguments: w - the TextSink Object.
+ * tab_count - the number of tabs in the list.
+ * tabs - the text positions of the tabs.
+ * Returns: none
+ */
+
+void
+#if NeedFunctionPrototypes
+XawTextSinkSetTabs(Widget w, int tab_count, int *tabs)
+#else
+XawTextSinkSetTabs(w, tab_count, tabs)
+Widget w;
+int tab_count, *tabs;
+#endif
+{
+ if (tab_count > 0) {
+ TextSinkObjectClass class = (TextSinkObjectClass) w->core.widget_class;
+ short *char_tabs = (short*)XtMalloc( (unsigned)tab_count*sizeof(short) );
+ short *tab;
+ int i;
+
+ for (i = tab_count, tab = char_tabs; i; i--) *tab++ = (short)*tabs++;
+
+ (*class->text_sink_class.SetTabs)(w, tab_count, char_tabs);
+ XtFree((char *)char_tabs);
+ }
+}
+
+/* Function Name: XawTextSinkGetCursorBounds
+ * Description: Finds the bounding box for the insert curor (caret).
+ * Arguments: w - the TextSinkObject.
+ * rect - an X rectance containing the cursor bounds.
+ * Returns: none (fills in rect).
+ */
+
+/* ARGSUSED */
+void
+#if NeedFunctionPrototypes
+XawTextSinkGetCursorBounds(Widget w, XRectangle *rect)
+#else
+XawTextSinkGetCursorBounds(w, rect)
+Widget w;
+XRectangle * rect;
+#endif
+{
+ TextSinkObjectClass class = (TextSinkObjectClass) w->core.widget_class;
+
+ (*class->text_sink_class.GetCursorBounds)(w, rect);
+}
diff --git a/src/TextSink.h b/src/TextSink.h
new file mode 100644
index 0000000..957938b
--- /dev/null
+++ b/src/TextSink.h
@@ -0,0 +1,317 @@
+/*
+ * $XConsortium: TextSink.h,v 1.10 94/04/17 20:13: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.
+
+******************************************************************/
+
+#ifndef _XawTextSink_h
+#define _XawTextSink_h
+
+#include <X11/Xaw3d/Text.h>
+
+/***********************************************************************
+ *
+ * TextSink Object
+ *
+ ***********************************************************************/
+
+/* Resources:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ foreground Foreground Pixel XtDefaultForeground
+ background Background Pixel XtDefaultBackground
+
+*/
+
+/* Class record constants */
+
+extern WidgetClass textSinkObjectClass;
+
+typedef struct _TextSinkClassRec *TextSinkObjectClass;
+typedef struct _TextSinkRec *TextSinkObject;
+
+typedef enum {XawisOn, XawisOff} XawTextInsertState;
+
+/************************************************************
+ *
+ * Public Functions.
+ *
+ ************************************************************/
+
+_XFUNCPROTOBEGIN
+
+/* Function Name: XawTextSinkDisplayText
+ * Description: Stub function that in subclasses will display text.
+ * Arguments: w - the TextSink Object.
+ * x, y - location to start drawing text.
+ * pos1, pos2 - location of starting and ending points
+ * in the text buffer.
+ * highlight - hightlight this text?
+ * Returns: none.
+ *
+ * This function doesn't actually display anything, it is only a place
+ * holder.
+ */
+
+extern void XawTextSinkDisplayText(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+#if NeedWidePrototypes
+ /* Position */ int /* x */,
+ /* Position */ int /* y */,
+#else
+ Position /* x */,
+ Position /* y */,
+#endif
+ XawTextPosition /* pos1 */,
+ XawTextPosition /* pos2 */,
+#if NeedWidePrototypes
+ /* Boolean */ int /* highlight */
+#else
+ Boolean /* highlight */
+#endif
+#endif
+);
+
+/* Function Name: XawTextSinkInsertCursor
+ * Description: Places the InsertCursor.
+ * Arguments: w - the TextSink Object.
+ * x, y - location for the cursor.
+ * staye - whether to turn the cursor on, or off.
+ * Returns: none.
+ *
+ * This function doesn't actually display anything, it is only a place
+ * holder.
+ */
+
+extern void XawTextSinkInsertCursor(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+#if NeedWidePrototypes
+ /* Position */ int /* x */,
+ /* Position */ int /* y */,
+ /* XawTextInsertState */ int /* state */
+#else
+ Position /* x */,
+ Position /* y */,
+ XawTextInsertState /* state */
+#endif
+#endif
+);
+
+/* Function Name: XawTextSinkClearToBackground
+ * Description: Clears a region of the sink to the background color.
+ * Arguments: w - the TextSink Object.
+ * x, y - location of area to clear.
+ * width, height - size of area to clear
+ * Returns: void.
+ *
+ * This function doesn't actually display anything, it is only a place
+ * holder.
+ */
+
+extern void XawTextSinkClearToBackground(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+#if NeedWidePrototypes
+ /* Position */ int /* x */,
+ /* Position */ int /* y */,
+ /* Dimension */ int /* width */,
+ /* Dimension */ int /* height */
+#else
+ Position /* x */,
+ Position /* y */,
+ Dimension /* width */,
+ Dimension /* height */
+#endif
+#endif
+);
+
+/* Function Name: XawTextSinkFindPosition
+ * Description: Finds a position in the text.
+ * Arguments: w - the TextSink Object.
+ * fromPos - reference position.
+ * fromX - reference location.
+ * width, - width of section to paint text.
+ * stopAtWordBreak - returned position is a word break?
+ * resPos - Position to return. *** RETURNED ***
+ * resWidth - Width actually used. *** RETURNED ***
+ * resHeight - Height actually used. *** RETURNED ***
+ * Returns: none (see above).
+ */
+
+extern void XawTextSinkFindPosition(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ XawTextPosition /* fromPos */,
+ int /* fromX */,
+ int /* width */,
+#if NeedWidePrototypes
+ /* Boolean */ int /* stopAtWordBreak */,
+#else
+ Boolean /* stopAtWordBreak */,
+#endif
+ XawTextPosition* /* pos_return */,
+ int* /* width_return */,
+ int* /* height_return */
+#endif
+);
+
+/* Function Name: XawTextSinkFindDistance
+ * Description: Find the Pixel Distance between two text Positions.
+ * Arguments: w - the TextSink Object.
+ * fromPos - starting Position.
+ * fromX - x location of starting Position.
+ * toPos - end Position.
+ * resWidth - Distance between fromPos and toPos.
+ * resPos - Acutal toPos used.
+ * resHeight - Height required by this text.
+ * Returns: none.
+ */
+
+extern void XawTextSinkFindDistance (
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ XawTextPosition /* fromPos */,
+ int /* fromX */,
+ XawTextPosition /* toPos */,
+ int* /* width_return */,
+ XawTextPosition* /* pos_return */,
+ int* /* height_return */
+#endif
+);
+
+/* Function Name: XawTextSinkResolve
+ * Description: Resloves a location to a position.
+ * Arguments: w - the TextSink Object.
+ * pos - a reference Position.
+ * fromx - a reference Location.
+ * width - width to move.
+ * resPos - the resulting position.
+ * Returns: none
+ */
+
+extern void XawTextSinkResolve(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ XawTextPosition /* fromPos */,
+ int /* fromX */,
+ int /* width */,
+ XawTextPosition* /* pos_return */
+#endif
+);
+
+/* Function Name: XawTextSinkMaxLines
+ * Description: Finds the Maximum number of lines that will fit in
+ * a given height.
+ * Arguments: w - the TextSink Object.
+ * height - height to fit lines into.
+ * Returns: the number of lines that will fit.
+ */
+
+extern int XawTextSinkMaxLines(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+#if NeedWidePrototypes
+ /* Dimension */ int /* height */
+#else
+ Dimension /* height */
+#endif
+#endif
+);
+
+/* Function Name: XawTextSinkMaxHeight
+ * Description: Finds the Minium height that will contain a given number
+ * lines.
+ * Arguments: w - the TextSink Object.
+ * lines - the number of lines.
+ * Returns: the height.
+ */
+
+extern int XawTextSinkMaxHeight(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ int /* lines */
+#endif
+);
+
+/* Function Name: XawTextSinkSetTabs
+ * Description: Sets the Tab stops.
+ * Arguments: w - the TextSink Object.
+ * tab_count - the number of tabs in the list.
+ * tabs - the text positions of the tabs.
+ * Returns: none
+ */
+
+extern void XawTextSinkSetTabs(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ int /* tab_count */,
+ int* /* tabs */
+#endif
+);
+
+/* Function Name: XawTextSinkGetCursorBounds
+ * Description: Finds the bounding box for the insert curor (caret).
+ * Arguments: w - the TextSinkObject.
+ * rect - an X rectance containing the cursor bounds.
+ * Returns: none (fills in rect).
+ */
+
+extern void XawTextSinkGetCursorBounds(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ XRectangle* /* rect_return */
+#endif
+);
+
+_XFUNCPROTOEND
+
+#endif /* _XawTextSrc_h */
diff --git a/src/TextSinkP.h b/src/TextSinkP.h
new file mode 100644
index 0000000..e45bf75
--- /dev/null
+++ b/src/TextSinkP.h
@@ -0,0 +1,143 @@
+/*
+* $XConsortium: TextSinkP.h,v 1.6 94/04/17 20:13:13 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.
+
+******************************************************************/
+
+/*
+ * TextSinkP.h - Private definitions for TextSink object
+ *
+ */
+
+#ifndef _XawTextSinkP_h
+#define _XawTextSinkP_h
+
+/***********************************************************************
+ *
+ * TextSink Object Private Data
+ *
+ ***********************************************************************/
+
+#include <X11/Xaw3d/TextSink.h>
+#include <X11/Xaw3d/TextP.h> /* This source works with the Text widget. */
+#include <X11/Xaw3d/TextSrcP.h> /* This source works with the Text Source. */
+
+/************************************************************
+ *
+ * New fields for the TextSink object class record.
+ *
+ ************************************************************/
+
+typedef struct _TextSinkClassPart {
+ void (*DisplayText)();
+ void (*InsertCursor)();
+ void (*ClearToBackground)();
+ void (*FindPosition)();
+ void (*FindDistance)();
+ void (*Resolve)();
+ int (*MaxLines)();
+ int (*MaxHeight)();
+ void (*SetTabs)();
+ void (*GetCursorBounds)();
+} TextSinkClassPart;
+
+/* Full class record declaration */
+typedef struct _TextSinkClassRec {
+ ObjectClassPart object_class;
+ TextSinkClassPart text_sink_class;
+} TextSinkClassRec;
+
+extern TextSinkClassRec textSinkClassRec;
+
+/* New fields for the TextSink object record */
+typedef struct {
+ /* resources */
+ Pixel foreground; /* Foreground color. */
+ Pixel background; /* Background color. */
+
+ /* private state. */
+ Position *tabs; /* The tab stops as pixel values. */
+ short *char_tabs; /* The tabs stops as character values. */
+ int tab_count; /* number of items in tabs */
+
+} TextSinkPart;
+
+/****************************************************************
+ *
+ * Full instance record declaration
+ *
+ ****************************************************************/
+
+typedef struct _TextSinkRec {
+ ObjectPart object;
+ TextSinkPart text_sink;
+} TextSinkRec;
+
+/************************************************************
+ *
+ * Private declarations.
+ *
+ ************************************************************/
+
+typedef int (*_XawSinkIntFunc)();
+typedef void (*_XawSinkVoidFunc)();
+
+#define XtInheritDisplayText ((_XawSinkVoidFunc) _XtInherit)
+#define XtInheritInsertCursor ((_XawSinkVoidFunc) _XtInherit)
+#define XtInheritClearToBackground ((_XawSinkVoidFunc) _XtInherit)
+#define XtInheritFindPosition ((_XawSinkVoidFunc) _XtInherit)
+#define XtInheritFindDistance ((_XawSinkVoidFunc) _XtInherit)
+#define XtInheritResolve ((_XawSinkVoidFunc) _XtInherit)
+#define XtInheritMaxLines ((_XawSinkIntFunc) _XtInherit)
+#define XtInheritMaxHeight ((_XawSinkIntFunc) _XtInherit)
+#define XtInheritSetTabs ((_XawSinkVoidFunc) _XtInherit)
+#define XtInheritGetCursorBounds ((_XawSinkVoidFunc) _XtInherit)
+
+#endif /* _XawTextSinkP_h */
diff --git a/src/TextSrc.c b/src/TextSrc.c
new file mode 100644
index 0000000..d954954
--- /dev/null
+++ b/src/TextSrc.c
@@ -0,0 +1,676 @@
+/* $XConsortium: TextSrc.c,v 1.15 94/04/17 20:13:14 kaleb Exp $ */
+/*
+
+Copyright (c) 1989, 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.
+
+*/
+
+/*
+ * Author: Chris Peterson, MIT X Consortium.
+ * Much code taken from X11R3 String and Disk Sources.
+ */
+
+/*
+ * TextSrc.c - TextSrc object. (For use with the text widget).
+ *
+ */
+
+#include "Xaw3dP.h"
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xutil.h>
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/TextSrcP.h>
+#include <X11/Xmu/Atoms.h>
+#include <X11/Xmu/CharSet.h>
+#ifdef XAW_INTERNATIONALIZATION
+#include "XawI18n.h"
+#endif
+#include <stdio.h>
+#include <ctype.h>
+
+/****************************************************************
+ *
+ * Full class record constant
+ *
+ ****************************************************************/
+
+/* Private Data */
+
+#define offset(field) XtOffsetOf(TextSrcRec, textSrc.field)
+static XtResource resources[] = {
+ {XtNeditType, XtCEditType, XtREditMode, sizeof(XawTextEditType),
+ offset(edit_mode), XtRString, "read"},
+};
+
+static void ClassInitialize(), ClassPartInitialize(), SetSelection();
+static void CvtStringToEditMode();
+static Boolean ConvertSelection();
+static XawTextPosition Search(), Scan(), Read();
+static int Replace();
+
+#define SuperClass (&objectClassRec)
+TextSrcClassRec textSrcClassRec = {
+ {
+/* core_class fields */
+ /* superclass */ (WidgetClass) SuperClass,
+ /* class_name */ "TextSrc",
+ /* widget_size */ sizeof(TextSrcRec),
+ /* class_initialize */ ClassInitialize,
+ /* class_part_initialize */ ClassPartInitialize,
+ /* class_inited */ FALSE,
+ /* initialize */ NULL,
+ /* initialize_hook */ NULL,
+ /* realize */ NULL,
+ /* actions */ NULL,
+ /* num_actions */ 0,
+ /* resources */ resources,
+ /* num_resources */ XtNumber(resources),
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ FALSE,
+ /* compress_exposure */ FALSE,
+ /* compress_enterleave */ FALSE,
+ /* visible_interest */ FALSE,
+ /* destroy */ NULL,
+ /* resize */ NULL,
+ /* expose */ NULL,
+ /* set_values */ NULL,
+ /* set_values_hook */ NULL,
+ /* set_values_almost */ NULL,
+ /* get_values_hook */ NULL,
+ /* accept_focus */ NULL,
+ /* version */ XtVersion,
+ /* callback_private */ NULL,
+ /* tm_table */ NULL,
+ /* query_geometry */ NULL,
+ /* display_accelerator */ NULL,
+ /* extension */ NULL,
+ },
+/* textSrc_class fields */
+ {
+ /* Read */ Read,
+ /* Replace */ Replace,
+ /* Scan */ Scan,
+ /* Search */ Search,
+ /* SetSelection */ SetSelection,
+ /* ConvertSelection */ ConvertSelection
+ }
+};
+
+WidgetClass textSrcObjectClass = (WidgetClass)&textSrcClassRec;
+
+static void
+ClassInitialize ()
+{
+ XawInitializeWidgetSet ();
+ XtAddConverter(XtRString, XtREditMode, CvtStringToEditMode, NULL, 0);
+}
+
+
+static void
+ClassPartInitialize(wc)
+WidgetClass wc;
+{
+ TextSrcObjectClass t_src, superC;
+
+ t_src = (TextSrcObjectClass) wc;
+ superC = (TextSrcObjectClass) t_src->object_class.superclass;
+
+/*
+ * We don't need to check for null super since we'll get to TextSrc
+ * eventually.
+ */
+ if (t_src->textSrc_class.Read == XtInheritRead)
+ t_src->textSrc_class.Read = superC->textSrc_class.Read;
+
+ if (t_src->textSrc_class.Replace == XtInheritReplace)
+ t_src->textSrc_class.Replace = superC->textSrc_class.Replace;
+
+ if (t_src->textSrc_class.Scan == XtInheritScan)
+ t_src->textSrc_class.Scan = superC->textSrc_class.Scan;
+
+ if (t_src->textSrc_class.Search == XtInheritSearch)
+ t_src->textSrc_class.Search = superC->textSrc_class.Search;
+
+ if (t_src->textSrc_class.SetSelection == XtInheritSetSelection)
+ t_src->textSrc_class.SetSelection = superC->textSrc_class.SetSelection;
+
+ if (t_src->textSrc_class.ConvertSelection == XtInheritConvertSelection)
+ t_src->textSrc_class.ConvertSelection =
+ superC->textSrc_class.ConvertSelection;
+}
+
+/************************************************************
+ *
+ * Class specific methods.
+ *
+ ************************************************************/
+
+/* Function Name: Read
+ * Description: This function reads the source.
+ * Arguments: w - the TextSrc Object.
+ * pos - position of the text to retreive.
+ * RETURNED text - text block that will contain returned text.
+ * length - maximum number of characters to read.
+ * Returns: The number of characters read into the buffer.
+ */
+
+/* ARGSUSED */
+static XawTextPosition
+Read(w, pos, text, length)
+Widget w;
+XawTextPosition pos;
+XawTextBlock *text;
+int length;
+{
+ XtAppError(XtWidgetToApplicationContext(w),
+ "TextSrc Object: No read function is defined.");
+
+ return( (XawTextPosition) 0 ); /* for gcc -Wall and lint */
+}
+
+/* Function Name: Replace.
+ * Description: Replaces a block of text with new text.
+ * Arguments: src - the Text Source Object.
+ * startPos, endPos - ends of text that will be removed.
+ * text - new text to be inserted into buffer at startPos.
+ * Returns: XawEditError.
+ */
+
+/*ARGSUSED*/
+static int
+Replace (w, startPos, endPos, text)
+Widget w;
+XawTextPosition startPos, endPos;
+XawTextBlock *text;
+{
+ return(XawEditError);
+}
+
+/* Function Name: Scan
+ * Description: Scans the text source for the number and type
+ * of item specified.
+ * Arguments: w - the TextSrc Object.
+ * position - the position to start scanning.
+ * type - type of thing to scan for.
+ * dir - direction to scan.
+ * count - which occurance if this thing to search for.
+ * include - whether or not to include the character found in
+ * the position that is returned.
+ * Returns: EXITS WITH AN ERROR MESSAGE.
+ *
+ */
+
+/* ARGSUSED */
+static
+XawTextPosition
+Scan (w, position, type, dir, count, include)
+Widget w;
+XawTextPosition position;
+XawTextScanType type;
+XawTextScanDirection dir;
+int count;
+Boolean include;
+{
+ XtAppError(XtWidgetToApplicationContext(w),
+ "TextSrc Object: No SCAN function is defined.");
+
+ return( (XawTextPosition) 0 ); /* for gcc -Wall and lint */
+}
+
+/* Function Name: Search
+ * Description: Searchs the text source for the text block passed
+ * Arguments: w - the TextSource Object.
+ * position - the position to start scanning.
+ * dir - direction to scan.
+ * text - the text block to search for.
+ * Returns: XawTextSearchError.
+ */
+
+/* ARGSUSED */
+static XawTextPosition
+Search(w, position, dir, text)
+Widget w;
+XawTextPosition position;
+XawTextScanDirection dir;
+XawTextBlock * text;
+{
+ return(XawTextSearchError);
+}
+
+/* Function Name: ConvertSelection
+ * Description: Dummy selection converter.
+ * Arguments: w - the TextSrc object.
+ * selection - the current selection atom.
+ * target - the current target atom.
+ * type - the type to conver the selection to.
+ * RETURNED value, length - the return value that has been converted.
+ * RETURNED format - the format of the returned value.
+ * Returns: TRUE if the selection has been converted.
+ *
+ */
+
+/* ARGSUSED */
+static Boolean
+ConvertSelection(w, selection, target, type, value, length, format)
+Widget w;
+Atom * selection, * target, * type;
+XtPointer * value;
+unsigned long * length;
+int * format;
+{
+ return(FALSE);
+}
+
+/* Function Name: SetSelection
+ * Description: allows special setting of the selection.
+ * Arguments: w - the TextSrc object.
+ * left, right - bounds of the selection.
+ * selection - the selection atom.
+ * Returns: none
+ */
+
+/* ARGSUSED */
+static void
+SetSelection(w, left, right, selection)
+Widget w;
+XawTextPosition left, right;
+Atom selection;
+{
+ /* This space intentionally left blank. */
+}
+
+
+/* ARGSUSED */
+static void
+CvtStringToEditMode(args, num_args, fromVal, toVal)
+XrmValuePtr args; /* unused */
+Cardinal *num_args; /* unused */
+XrmValuePtr fromVal;
+XrmValuePtr toVal;
+{
+ static XawTextEditType editType;
+ static XrmQuark QRead, QAppend, QEdit;
+ XrmQuark q;
+ char lowerName[40];
+ static Boolean inited = FALSE;
+
+ if ( !inited ) {
+ QRead = XrmPermStringToQuark(XtEtextRead);
+ QAppend = XrmPermStringToQuark(XtEtextAppend);
+ QEdit = XrmPermStringToQuark(XtEtextEdit);
+ inited = TRUE;
+ }
+
+ if (strlen ((char*) fromVal->addr) < sizeof lowerName) {
+ XmuCopyISOLatin1Lowered (lowerName, (char *)fromVal->addr);
+ q = XrmStringToQuark(lowerName);
+
+ if (q == QRead) editType = XawtextRead;
+ else if (q == QAppend) editType = XawtextAppend;
+ else if (q == QEdit) editType = XawtextEdit;
+ else {
+ toVal->size = 0;
+ toVal->addr = NULL;
+ return;
+ }
+ toVal->size = sizeof editType;
+ toVal->addr = (XPointer) &editType;
+ return;
+ }
+ toVal->size = 0;
+ toVal->addr = NULL;
+}
+
+
+
+/************************************************************
+ *
+ * Public Functions.
+ *
+ ************************************************************/
+
+/* Function Name: XawTextSourceRead
+ * Description: This function reads the source.
+ * Arguments: w - the TextSrc Object.
+ * pos - position of the text to retreive.
+ * RETURNED text - text block that will contain returned text.
+ * length - maximum number of characters to read.
+ * Returns: The number of characters read into the buffer.
+ */
+
+XawTextPosition
+#if NeedFunctionPrototypes
+XawTextSourceRead(Widget w, XawTextPosition pos, XawTextBlock *text,
+ int length)
+#else
+XawTextSourceRead(w, pos, text, length)
+Widget w;
+XawTextPosition pos;
+XawTextBlock *text;
+int length;
+#endif
+{
+ TextSrcObjectClass class = (TextSrcObjectClass) w->core.widget_class;
+
+ if ( !XtIsSubclass( w, textSrcObjectClass ) )
+ XtErrorMsg("bad argument", "textSource", "XawError",
+ "XawTextSourceRead's 1st parameter must be subclass of asciiSrc.",
+ NULL, NULL);
+
+ return((*class->textSrc_class.Read)(w, pos, text, length));
+}
+
+/* Function Name: XawTextSourceReplace.
+ * Description: Replaces a block of text with new text.
+ * Arguments: src - the Text Source Object.
+ * startPos, endPos - ends of text that will be removed.
+ * text - new text to be inserted into buffer at startPos.
+ * Returns: XawEditError or XawEditDone.
+ */
+
+/*ARGSUSED*/
+int
+#if NeedFunctionPrototypes
+XawTextSourceReplace (Widget w, XawTextPosition startPos,
+ XawTextPosition endPos, XawTextBlock *text)
+#else
+XawTextSourceReplace (w, startPos, endPos, text)
+Widget w;
+XawTextPosition startPos, endPos;
+XawTextBlock *text;
+#endif
+{
+ TextSrcObjectClass class = (TextSrcObjectClass) w->core.widget_class;
+
+ if ( !XtIsSubclass( w, textSrcObjectClass ) )
+ XtErrorMsg("bad argument", "textSource", "XawError",
+ "XawTextSourceReplace's 1st parameter must be subclass of asciiSrc.",
+ NULL, NULL);
+
+ return((*class->textSrc_class.Replace)(w, startPos, endPos, text));
+}
+
+/* Function Name: XawTextSourceScan
+ * Description: Scans the text source for the number and type
+ * of item specified.
+ * Arguments: w - the TextSrc Object.
+ * position - the position to start scanning.
+ * type - type of thing to scan for.
+ * dir - direction to scan.
+ * count - which occurance if this thing to search for.
+ * include - whether or not to include the character found in
+ * the position that is returned.
+ * Returns: The position of the text.
+ *
+ */
+
+XawTextPosition
+#if NeedFunctionPrototypes
+XawTextSourceScan(Widget w, XawTextPosition position,
+#if NeedWidePrototypes
+ int type, int dir,
+#else
+ XawTextScanType type, XawTextScanDirection dir,
+#endif
+ int count,
+#if NeedWidePrototypes
+ int include)
+#else
+ Boolean include)
+#endif
+#else
+XawTextSourceScan(w, position, type, dir, count, include)
+Widget w;
+XawTextPosition position;
+XawTextScanType type;
+XawTextScanDirection dir;
+int count;
+Boolean include;
+#endif
+{
+ TextSrcObjectClass class = (TextSrcObjectClass) w->core.widget_class;
+
+ if ( !XtIsSubclass( w, textSrcObjectClass ) )
+ XtErrorMsg("bad argument", "textSource", "XawError",
+ "XawTextSourceScan's 1st parameter must be subclass of asciiSrc.",
+ NULL, NULL);
+
+ return((*class->textSrc_class.Scan)(w, position, type, dir, count, include));
+}
+
+/* Function Name: XawTextSourceSearch
+ * Description: Searchs the text source for the text block passed
+ * Arguments: w - the TextSource Object.
+ * position - the position to start scanning.
+ * dir - direction to scan.
+ * text - the text block to search for.
+ * Returns: The position of the text we are searching for or
+ * XawTextSearchError.
+ */
+
+XawTextPosition
+#if NeedFunctionPrototypes
+XawTextSourceSearch(Widget w, XawTextPosition position,
+#if NeedWidePrototypes
+ int dir,
+#else
+ XawTextScanDirection dir,
+#endif
+ XawTextBlock *text)
+#else
+XawTextSourceSearch(w, position, dir, text)
+Widget w;
+XawTextPosition position;
+XawTextScanDirection dir;
+XawTextBlock * text;
+#endif
+{
+ TextSrcObjectClass class = (TextSrcObjectClass) w->core.widget_class;
+
+ if ( !XtIsSubclass( w, textSrcObjectClass ) )
+ XtErrorMsg("bad argument", "textSource", "XawError",
+ "XawTextSourceSearch's 1st parameter must be subclass of asciiSrc.",
+ NULL, NULL);
+
+ return((*class->textSrc_class.Search)(w, position, dir, text));
+}
+
+/* Function Name: XawTextSourceConvertSelection
+ * Description: Dummy selection converter.
+ * Arguments: w - the TextSrc object.
+ * selection - the current selection atom.
+ * target - the current target atom.
+ * type - the type to conver the selection to.
+ * RETURNED value, length - the return value that has been converted.
+ * RETURNED format - the format of the returned value.
+ * Returns: TRUE if the selection has been converted.
+ *
+ */
+
+Boolean
+#if NeedFunctionPrototypes
+XawTextSourceConvertSelection(Widget w, Atom *selection, Atom *target,
+ Atom *type, XtPointer *value,
+ unsigned long *length, int *format)
+#else
+XawTextSourceConvertSelection(w, selection,
+ target, type, value, length, format)
+Widget w;
+Atom * selection, * target, * type;
+XtPointer * value;
+unsigned long * length;
+int * format;
+#endif
+{
+ TextSrcObjectClass class = (TextSrcObjectClass) w->core.widget_class;
+
+ if ( !XtIsSubclass( w, textSrcObjectClass ) )
+ XtErrorMsg("bad argument", "textSource", "XawError",
+ "XawTextSourceConvertSelectionXawTextSourceConvertSelection's 1st parameter must be subclass of asciiSrc.",
+ NULL, NULL);
+
+ return((*class->textSrc_class.ConvertSelection)(w, selection, target, type,
+ value, length, format));
+}
+
+/* Function Name: XawTextSourceSetSelection
+ * Description: allows special setting of the selection.
+ * Arguments: w - the TextSrc object.
+ * left, right - bounds of the selection.
+ * selection - the selection atom.
+ * Returns: none
+ */
+
+void
+#if NeedFunctionPrototypes
+XawTextSourceSetSelection(Widget w, XawTextPosition left,
+ XawTextPosition right, Atom selection)
+#else
+XawTextSourceSetSelection(w, left, right, selection)
+Widget w;
+XawTextPosition left, right;
+Atom selection;
+#endif
+{
+ TextSrcObjectClass class = (TextSrcObjectClass) w->core.widget_class;
+
+ if ( !XtIsSubclass( w, textSrcObjectClass ) )
+ XtErrorMsg("bad argument", "textSource", "XawError",
+ "'s 1st parameter must be subclass of asciiSrc.",
+ NULL, NULL);
+
+ (*class->textSrc_class.SetSelection)(w, left, right, selection);
+}
+
+/********************************************************************
+ *
+ * External Functions for Multi Text.
+ *
+ ********************************************************************/
+
+/*
+ * TextFormat():
+ * returns the format of text: FMT8BIT or FMTWIDE.
+ *
+ */
+XrmQuark
+#if NeedFunctionPrototypes
+_XawTextFormat(TextWidget tw)
+#else
+_XawTextFormat(tw)
+ TextWidget tw;
+#endif
+{
+ return (((TextSrcObject)(tw->text.source))->textSrc.text_format);
+}
+
+
+#ifdef XAW_INTERNATIONALIZATION
+/* _XawTextWCToMB():
+ * convert the wchar string to external encoding.
+ * The caller is responsible for freeing both the source and ret string.
+ *
+ * wstr - source wchar string.
+ * len_in_out - lengh of string.
+ * As In, length of source wchar string, measured in wchar.
+ * As Out, length of returned string.
+ */
+
+
+char *
+_XawTextWCToMB( d, wstr, len_in_out )
+ Display* d;
+ wchar_t* wstr;
+ int* len_in_out;
+
+{
+ XTextProperty textprop;
+ if (XwcTextListToTextProperty(d, (wchar_t**)&wstr, 1,
+ XTextStyle, &textprop) < Success) {
+ XtWarningMsg("convertError", "textSource", "XawError",
+ "Non-character code(s) in buffer.", NULL, NULL);
+ *len_in_out = 0;
+ return( NULL );
+ }
+ *len_in_out = textprop.nitems;
+ return((char *)textprop.value);
+}
+
+
+/* _XawTextMBToWC():
+ * convert the string to internal processing codeset WC.
+ * The caller is responsible for freeing both the source and ret string.
+ *
+ * str - source string.
+ * len_in_out - lengh of string.
+ * As In, it is length of source string.
+ * As Out, it is length of returned string, measured in wchar.
+ */
+
+wchar_t* _XawTextMBToWC( d, str, len_in_out )
+Display *d;
+char *str;
+int *len_in_out;
+{
+ if (*len_in_out == 0) {
+ return(NULL);
+ } else {
+ XTextProperty textprop;
+ char *buf;
+ wchar_t **wlist, *wstr;
+ int count;
+ buf = XtMalloc(*len_in_out + 1);
+ if (!buf) {
+ XtErrorMsg("convertError", "multiSourceCreate", "XawError",
+ "No Memory", NULL, NULL);
+ *len_in_out = 0;
+ return (NULL); /* The above function doesn't really return. */
+ }
+ strncpy(buf, str, *len_in_out);
+ *(buf + *len_in_out) = '\0';
+ if (XmbTextListToTextProperty(d, &buf, 1, XTextStyle, &textprop)
+ != Success) {
+ XtWarningMsg("convertError", "textSource", "XawError",
+ "No Memory, or Locale not supported.", NULL, NULL);
+ XtFree(buf);
+ *len_in_out = 0;
+ return (NULL);
+ }
+ XtFree(buf);
+ if (XwcTextPropertyToTextList(d, &textprop,
+ (wchar_t***)&wlist, &count) != Success) {
+ XtWarningMsg("convertError", "multiSourceCreate", "XawError",
+ "Non-character code(s) in source.", NULL, NULL);
+ *len_in_out = 0;
+ return (NULL);
+ }
+ wstr = wlist[0];
+ *len_in_out = wcslen(wstr);
+ XFree((char**)wlist); /* this is evil */
+ return(wstr);
+ }
+}
+#endif
+
diff --git a/src/TextSrc.h b/src/TextSrc.h
new file mode 100644
index 0000000..edd3153
--- /dev/null
+++ b/src/TextSrc.h
@@ -0,0 +1,237 @@
+/*
+ * $XConsortium: TextSrc.h,v 1.11 94/04/17 20:13:15 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.
+
+******************************************************************/
+
+#ifndef _XawTextSrc_h
+#define _XawTextSrc_h
+
+/***********************************************************************
+ *
+ * TextSrc Object
+ *
+ ***********************************************************************/
+
+#include <X11/Xaw3d/Text.h>
+
+/* Resources:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ editType EditType XawTextEditType XawtextRead
+
+*/
+
+/* Class record constants */
+
+extern WidgetClass textSrcObjectClass;
+
+typedef struct _TextSrcClassRec *TextSrcObjectClass;
+typedef struct _TextSrcRec *TextSrcObject;
+
+typedef enum {XawstPositions, XawstWhiteSpace, XawstEOL, XawstParagraph,
+ XawstAll} XawTextScanType;
+typedef enum {Normal, Selected }highlightType;
+typedef enum {XawsmTextSelect, XawsmTextExtend} XawTextSelectionMode;
+typedef enum {XawactionStart, XawactionAdjust, XawactionEnd}
+ XawTextSelectionAction;
+
+/*
+ * Error Conditions:
+ */
+
+#define XawTextReadError -1
+#define XawTextScanError -1
+
+/************************************************************
+ *
+ * Public Functions.
+ *
+ ************************************************************/
+
+_XFUNCPROTOBEGIN
+
+/* Function Name: XawTextSourceRead
+ * Description: This function reads the source.
+ * Arguments: w - the TextSrc Object.
+ * pos - position of the text to retreive.
+ * RETURNED text - text block that will contain returned text.
+ * length - maximum number of characters to read.
+ * Returns: The number of characters read into the buffer.
+ */
+
+extern XawTextPosition XawTextSourceRead(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ XawTextPosition /* pos */,
+ XawTextBlock* /* text_return */,
+ int /* length */
+#endif
+);
+
+/* Function Name: XawTextSourceReplace.
+ * Description: Replaces a block of text with new text.
+ * Arguments: src - the Text Source Object.
+ * startPos, endPos - ends of text that will be removed.
+ * text - new text to be inserted into buffer at startPos.
+ * Returns: XawEditError or XawEditDone.
+ */
+
+extern int XawTextSourceReplace (
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ XawTextPosition /* start */,
+ XawTextPosition /* end */,
+ XawTextBlock* /* text */
+#endif
+);
+
+/* Function Name: XawTextSourceScan
+ * Description: Scans the text source for the number and type
+ * of item specified.
+ * Arguments: w - the TextSrc Object.
+ * position - the position to start scanning.
+ * type - type of thing to scan for.
+ * dir - direction to scan.
+ * count - which occurance if this thing to search for.
+ * include - whether or not to include the character found in
+ * the position that is returned.
+ * Returns: The position of the text.
+ *
+ */
+
+extern XawTextPosition XawTextSourceScan(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ XawTextPosition /* position */,
+#if NeedWidePrototypes
+ /* XawTextScanType */ int /* type */,
+ /* XawTextScanDirection */ int /* dir */,
+#else
+ XawTextScanType /* type */,
+ XawTextScanDirection /* dir */,
+#endif
+ int /* count */,
+#if NeedWidePrototypes
+ /* Boolean */ int /* include */
+#else
+ Boolean /* include */
+#endif
+#endif
+);
+
+/* Function Name: XawTextSourceSearch
+ * Description: Searchs the text source for the text block passed
+ * Arguments: w - the TextSource Object.
+ * position - the position to start scanning.
+ * dir - direction to scan.
+ * text - the text block to search for.
+ * Returns: The position of the text we are searching for or
+ * XawTextSearchError.
+ */
+
+extern XawTextPosition XawTextSourceSearch(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ XawTextPosition /* position */,
+#if NeedWidePrototypes
+ /* XawTextScanDirection */ int /* dir */,
+#else
+ XawTextScanDirection /* dir */,
+#endif
+ XawTextBlock* /* text */
+#endif
+);
+
+/* Function Name: XawTextSourceConvertSelection
+ * Description: Dummy selection converter.
+ * Arguments: w - the TextSrc object.
+ * selection - the current selection atom.
+ * target - the current target atom.
+ * type - the type to conver the selection to.
+ * RETURNED value, length - the return value that has been converted.
+ * RETURNED format - the format of the returned value.
+ * Returns: TRUE if the selection has been converted.
+ *
+ */
+
+extern Boolean XawTextSourceConvertSelection(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ Atom* /* selection */,
+ Atom* /* target */,
+ Atom* /* type */,
+ XtPointer* /* value_return */,
+ unsigned long* /* length_return */,
+ int* /* format_return */
+#endif
+);
+
+/* Function Name: XawTextSourceSetSelection
+ * Description: allows special setting of the selection.
+ * Arguments: w - the TextSrc object.
+ * left, right - bounds of the selection.
+ * selection - the selection atom.
+ * Returns: none
+ */
+
+extern void XawTextSourceSetSelection(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ XawTextPosition /* start */,
+ XawTextPosition /* end */,
+ Atom /* selection */
+#endif
+);
+
+_XFUNCPROTOEND
+
+#endif /* _XawTextSrc_h */
+/* DON'T ADD STUFF AFTER THIS #endif */
diff --git a/src/TextSrcP.h b/src/TextSrcP.h
new file mode 100644
index 0000000..c7e0db7
--- /dev/null
+++ b/src/TextSrcP.h
@@ -0,0 +1,164 @@
+/*
+* $XConsortium: TextSrcP.h,v 1.20 94/04/17 20:13:15 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.
+
+******************************************************************/
+
+/*
+ * TextSrcP.h - Private definitions for TextSrc object
+ *
+ */
+
+#ifndef _XawTextSrcP_h
+#define _XawTextSrcP_h
+
+/***********************************************************************
+ *
+ * TextSrc Object Private Data
+ *
+ ***********************************************************************/
+
+#include <X11/Xaw3d/TextSrc.h>
+#include <X11/Xaw3d/TextP.h> /* This source works with the Text widget. */
+
+/************************************************************
+ *
+ * New fields for the TextSrc object class record.
+ *
+ ************************************************************/
+
+typedef struct {
+ XtPointer next_extension;
+ XrmQuark record_type;
+ long version;
+ Cardinal record_size;
+ int (*Input)();
+} TextSrcExtRec, *TextSrcExt;
+
+typedef struct _TextSrcClassPart {
+ XawTextPosition (*Read)();
+ int (*Replace)();
+ XawTextPosition (*Scan)();
+ XawTextPosition (*Search)();
+ void (*SetSelection)();
+ Boolean (*ConvertSelection)();
+} TextSrcClassPart;
+
+/* Full class record declaration */
+typedef struct _TextSrcClassRec {
+ ObjectClassPart object_class;
+ TextSrcClassPart textSrc_class;
+} TextSrcClassRec;
+
+extern TextSrcClassRec textSrcClassRec;
+
+/* New fields for the TextSrc object record */
+typedef struct {
+ /* resources */
+ XawTextEditType edit_mode;
+ XrmQuark text_format; /* 2 formats: FMT8BIT for Ascii */
+ /* FMTWIDE for ISO 10646 */
+} TextSrcPart;
+
+/****************************************************************
+ *
+ * Full instance record declaration
+ *
+ ****************************************************************/
+
+typedef struct _TextSrcRec {
+ ObjectPart object;
+ TextSrcPart textSrc;
+} TextSrcRec;
+
+/******************************************************************
+ *
+ * Semiprivate declarations of functions used in other modules
+ *
+ ******************************************************************/
+
+char* _XawTextWCToMB(
+#if NeedFunctionPrototypes
+ Display* /* d */,
+ wchar_t* /* wstr */,
+ int* /* len_in_out */
+#endif
+);
+
+wchar_t* _XawTextMBToWC(
+#if NeedFunctionPrototypes
+ Display* /* d */,
+ char* /* str */,
+ int* /* len_in_out */
+#endif
+);
+
+/************************************************************
+ *
+ * Private declarations.
+ *
+ ************************************************************/
+
+typedef Boolean (*_XawBooleanFunc)();
+typedef int (*_XawIntFunc)();
+typedef XawTextPosition (*_XawTextPositionFunc)();
+typedef void (*_XawTextVoidFunc)();
+
+#define XtInheritInput ((_XawTextPositionFunc) _XtInherit)
+#define XtInheritRead ((_XawTextPositionFunc) _XtInherit)
+#define XtInheritReplace ((_XawIntFunc) _XtInherit)
+#define XtInheritScan ((_XawTextPositionFunc) _XtInherit)
+#define XtInheritSearch ((_XawTextPositionFunc) _XtInherit)
+#define XtInheritSetSelection ((_XawTextVoidFunc) _XtInherit)
+#define XtInheritConvertSelection ((_XawBooleanFunc) _XtInherit)
+#define XtTextSrcExtVersion 1
+#define XtTextSrcExtTypeString "XT_TEXTSRC_EXT"
+
+#endif /* _XawTextSrcP_h */
diff --git a/src/TextTr.c b/src/TextTr.c
new file mode 100644
index 0000000..a3cd8a9
--- /dev/null
+++ b/src/TextTr.c
@@ -0,0 +1,147 @@
+/* $XConsortium: TextTr.c,v 1.20 95/06/14 15:07:27 kaleb Exp $ */
+
+/*
+
+Copyright (c) 1991, 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.
+
+*/
+
+/* INTERNATIONALIZATION:
+
+The OMRON R5 contrib added the following action to the old TextTr:
+
+ Ctrl<Key>backslash: reconnect-im()
+
+This is needed when the im is killed or otherwise becomes unreachable.
+This keystroke is evil (inconvenient, hard-to-remember, not obvious)
+so I am adding one more translation:
+
+ <Key>Kanji: reconnect-im()
+
+The Japanese user typically hits their Kanji key when they want to do
+input. This merely makes sure the input is connected.
+*/
+
+char *_XawDefaultTextTranslations1 =
+"\
+Ctrl<Key>A: beginning-of-line() \n\
+Ctrl<Key>B: backward-character() \n\
+Ctrl<Key>C: insert-selection(CUT_BUFFER0) \n\
+Ctrl<Key>D: delete-next-character() \n\
+Ctrl<Key>E: end-of-line() \n\
+Ctrl<Key>F: forward-character() \n\
+Ctrl<Key>G: multiply(Reset) \n\
+Ctrl<Key>H: delete-previous-character() \n\
+Ctrl<Key>J: newline-and-indent() \n\
+Ctrl<Key>K: kill-to-end-of-line() \n\
+Ctrl<Key>L: redraw-display() \n\
+Ctrl<Key>M: newline() \n\
+Ctrl<Key>N: next-line() \n\
+Ctrl<Key>O: newline-and-backup() \n\
+Ctrl<Key>P: previous-line() \n\
+Ctrl<Key>R: search(backward) \n\
+Ctrl<Key>S: search(forward) \n\
+Ctrl<Key>T: transpose-characters() \n\
+Ctrl<Key>U: multiply(4) \n\
+Ctrl<Key>V: next-page() \n\
+Ctrl<Key>W: kill-selection() \n\
+Ctrl<Key>Y: insert-selection(SECONDARY) \n\
+Ctrl<Key>Z: scroll-one-line-up() \n\
+", *_XawDefaultTextTranslations2 = "\
+Meta<Key>B: backward-word() \n\
+Meta<Key>F: forward-word() \n\
+Meta<Key>I: insert-file() \n\
+Meta<Key>K: kill-to-end-of-paragraph() \n\
+Meta<Key>Q: form-paragraph() \n\
+Meta<Key>V: previous-page() \n\
+Meta<Key>Y: insert-selection(PRIMARY, CUT_BUFFER0) \n\
+Meta<Key>Z: scroll-one-line-down() \n\
+:Meta<Key>d: delete-next-word() \n\
+:Meta<Key>D: kill-word() \n\
+:Meta<Key>h: delete-previous-word() \n\
+:Meta<Key>H: backward-kill-word() \n\
+:Meta<Key>\\<: beginning-of-file() \n\
+:Meta<Key>\\>: end-of-file() \n\
+:Meta<Key>]: forward-paragraph() \n\
+:Meta<Key>[: backward-paragraph() \n\
+~Shift Meta<Key>Delete: delete-previous-word() \n\
+ Shift Meta<Key>Delete: backward-kill-word() \n\
+~Shift Meta<Key>BackSpace: delete-previous-word() \n\
+ Shift Meta<Key>BackSpace: backward-kill-word() \n\
+",
+#if XtVersion >= 11006
+*_XawDefaultTextTranslations3 = "\
+<Key>Home: beginning-of-file() \n\
+:<Key>KP_Home: beginning-of-file() \n\
+<Key>End: end-of-file() \n\
+:<Key>KP_End: end-of-file() \n\
+<Key>Next: next-page() \n\
+:<Key>KP_Next: next-page() \n\
+<Key>Prior: previous-page() \n\
+:<Key>KP_Prior: previous-page() \n\
+<Key>Right: forward-character() \n\
+:<Key>KP_Right: forward-character() \n\
+<Key>Left: backward-character() \n\
+:<Key>KP_Left: backward-character() \n\
+<Key>Down: next-line() \n\
+:<Key>KP_Down: next-line() \n\
+<Key>Up: previous-line() \n\
+:<Key>KP_Up: previous-line() \n\
+<Key>Delete: delete-previous-character() \n\
+:<Key>KP_Delete: delete-previous-character() \n\
+<Key>BackSpace: delete-previous-character() \n\
+<Key>Linefeed: newline-and-indent() \n\
+<Key>Return: newline() \n\
+:<Key>KP_Enter: newline() \n\
+Ctrl<Key>backslash: reconnect-im() \n\
+<Key>Kanji: reconnect-im()\n\
+<Key>: insert-char() \n\
+",
+#else
+*_XawDefaultTextTranslations3 = "\
+<Key>Right: forward-character() \n\
+<Key>Left: backward-character() \n\
+<Key>Down: next-line() \n\
+<Key>Up: previous-line() \n\
+<Key>Delete: delete-previous-character() \n\
+<Key>BackSpace: delete-previous-character() \n\
+<Key>Linefeed: newline-and-indent() \n\
+<Key>Return: newline() \n\
+<Key>KP_Enter: newline() \n\
+<Key>: insert-char() \n\
+",
+#endif
+*_XawDefaultTextTranslations4 = "\
+<EnterWindow>: enter-window() \n\
+<LeaveWindow>: leave-window() \n\
+<FocusIn>: focus-in() \n\
+<FocusOut>: focus-out() \n\
+<Btn1Down>: select-start() \n\
+<Btn1Motion>: extend-adjust() \n\
+<Btn1Up>: extend-end(PRIMARY, CUT_BUFFER0) \n\
+<Btn2Down>: insert-selection(PRIMARY, CUT_BUFFER0) \n\
+<Btn3Down>: extend-start() \n\
+<Btn3Motion>: extend-adjust() \n\
+<Btn3Up>: extend-end(PRIMARY, CUT_BUFFER0) \
+";
diff --git a/src/ThreeD.c b/src/ThreeD.c
new file mode 100644
index 0000000..8166a7c
--- /dev/null
+++ b/src/ThreeD.c
@@ -0,0 +1,839 @@
+/*
+* $KK: ThreeD.c,v 0.3 92/11/04 xx:xx:xx keithley Exp $
+*/
+
+/***********************************************************
+Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+Copyright 1992 by Kaleb Keithley
+
+ 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 names of Digital, MIT, or Kaleb
+Keithley 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.
+
+******************************************************************/
+
+/*
+ * Portions Copyright (c) 2003 David J. Hawkey Jr.
+ * Rights, permissions, and disclaimer per the above DEC/MIT license.
+ */
+
+#include "Xaw3dP.h"
+#include <X11/Xlib.h>
+#include <X11/StringDefs.h>
+#include <X11/IntrinsicP.h>
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/ThreeDP.h>
+#include <X11/Xosdefs.h>
+
+/* Initialization of defaults */
+
+#define XtNtopShadowPixmap "topShadowPixmap"
+#define XtCTopShadowPixmap "TopShadowPixmap"
+#define XtNbottomShadowPixmap "bottomShadowPixmap"
+#define XtCBottomShadowPixmap "BottomShadowPixmap"
+
+static char defRelief[] = "Raised";
+
+#define offset(field) XtOffsetOf(ThreeDRec, field)
+
+static XtResource resources[] = {
+ {XtNshadowWidth, XtCShadowWidth, XtRDimension, sizeof(Dimension),
+ offset(threeD.shadow_width), XtRImmediate, (XtPointer) 2},
+ {XtNtopShadowPixel, XtCTopShadowPixel, XtRPixel, sizeof(Pixel),
+ offset(threeD.top_shadow_pixel), XtRString, XtDefaultForeground},
+ {XtNbottomShadowPixel, XtCBottomShadowPixel, XtRPixel, sizeof(Pixel),
+ offset(threeD.bot_shadow_pixel), XtRString, XtDefaultForeground},
+ {XtNtopShadowPixmap, XtCTopShadowPixmap, XtRPixmap, sizeof(Pixmap),
+ offset(threeD.top_shadow_pxmap), XtRImmediate, (XtPointer) NULL},
+ {XtNbottomShadowPixmap, XtCBottomShadowPixmap, XtRPixmap, sizeof(Pixmap),
+ offset(threeD.bot_shadow_pxmap), XtRImmediate, (XtPointer) NULL},
+ {XtNtopShadowContrast, XtCTopShadowContrast, XtRInt, sizeof(int),
+ offset(threeD.top_shadow_contrast), XtRImmediate, (XtPointer) 20},
+ {XtNbottomShadowContrast, XtCBottomShadowContrast, XtRInt, sizeof(int),
+ offset(threeD.bot_shadow_contrast), XtRImmediate, (XtPointer) 40},
+ {XtNuserData, XtCUserData, XtRPointer, sizeof(XtPointer),
+ offset(threeD.user_data), XtRPointer, (XtPointer) NULL},
+ {XtNbeNiceToColormap, XtCBeNiceToColormap, XtRBoolean, sizeof(Boolean),
+ offset(threeD.be_nice_to_cmap), XtRImmediate, (XtPointer) True},
+ {XtNborderWidth, XtCBorderWidth, XtRDimension, sizeof(Dimension),
+ XtOffsetOf(RectObjRec,rectangle.border_width), XtRImmediate,
+ (XtPointer)0},
+ {XtNrelief, XtCRelief, XtRRelief, sizeof(XtRelief),
+ offset(threeD.relief), XtRString, (XtPointer) defRelief}
+};
+
+#undef offset
+
+static void ClassInitialize(), ClassPartInitialize(), Initialize(), Destroy();
+static void Redisplay(), Realize(), _Xaw3dDrawShadows();
+static Boolean SetValues();
+
+ThreeDClassRec threeDClassRec = {
+ { /* core fields */
+ /* superclass */ (WidgetClass) &simpleClassRec,
+ /* class_name */ "ThreeD",
+ /* widget_size */ sizeof(ThreeDRec),
+ /* class_initialize */ ClassInitialize,
+ /* class_part_initialize */ ClassPartInitialize,
+ /* class_inited */ FALSE,
+ /* initialize */ Initialize,
+ /* initialize_hook */ NULL,
+ /* realize */ Realize,
+ /* actions */ NULL,
+ /* num_actions */ 0,
+ /* resources */ resources,
+ /* resource_count */ XtNumber(resources),
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ TRUE,
+ /* compress_exposure */ TRUE,
+ /* compress_enterleave */ TRUE,
+ /* visible_interest */ FALSE,
+ /* destroy */ Destroy,
+ /* resize */ XtInheritResize,
+ /* expose */ 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 */ XtInheritQueryGeometry,
+ /* display_accelerator */ XtInheritDisplayAccelerator,
+ /* extension */ NULL
+ },
+ { /* simple fields */
+ /* change_sensitive */ XtInheritChangeSensitive
+ },
+ { /* threeD fields */
+ /* shadow draw */ _Xaw3dDrawShadows
+ }
+};
+
+WidgetClass threeDWidgetClass = (WidgetClass) &threeDClassRec;
+
+/****************************************************************
+ *
+ * Private Procedures
+ *
+ ****************************************************************/
+
+#define mbshadowpm_size 3
+static char mbshadowpm_bits[] = {0x05, 0x03, 0x06};
+
+#define mtshadowpm_size 3
+static char mtshadowpm_bits[] = {0x02, 0x04, 0x01};
+
+#define shadowpm_size 2
+static char shadowpm_bits[] = {0x02, 0x01};
+
+/* ARGSUSED */
+static void AllocTopShadowGC (w)
+ Widget w;
+{
+ ThreeDWidget tdw = (ThreeDWidget) w;
+ Screen *scn = XtScreen (w);
+ XtGCMask valuemask;
+ XGCValues myXGCV;
+
+ if (tdw->threeD.be_nice_to_cmap || DefaultDepthOfScreen (scn) == 1) {
+ valuemask = GCTile | GCFillStyle;
+ myXGCV.tile = tdw->threeD.top_shadow_pxmap;
+ myXGCV.fill_style = FillTiled;
+ } else {
+ valuemask = GCForeground;
+ myXGCV.foreground = tdw->threeD.top_shadow_pixel;
+ }
+ tdw->threeD.top_shadow_GC = XtGetGC(w, valuemask, &myXGCV);
+}
+
+/* ARGSUSED */
+static void AllocBotShadowGC (w)
+ Widget w;
+{
+ ThreeDWidget tdw = (ThreeDWidget) w;
+ Screen *scn = XtScreen (w);
+ XtGCMask valuemask;
+ XGCValues myXGCV;
+
+ if (tdw->threeD.be_nice_to_cmap || DefaultDepthOfScreen (scn) == 1) {
+ valuemask = GCTile | GCFillStyle;
+ myXGCV.tile = tdw->threeD.bot_shadow_pxmap;
+ myXGCV.fill_style = FillTiled;
+ } else {
+ valuemask = GCForeground;
+ myXGCV.foreground = tdw->threeD.bot_shadow_pixel;
+ }
+ tdw->threeD.bot_shadow_GC = XtGetGC(w, valuemask, &myXGCV);
+}
+
+/* ARGSUSED */
+static void AllocTopShadowPixmap (new)
+ Widget new;
+{
+ ThreeDWidget tdw = (ThreeDWidget) new;
+ Display *dpy = XtDisplay (new);
+ Screen *scn = XtScreen (new);
+ unsigned long top_fg_pixel = 0, top_bg_pixel = 0;
+ char *pm_data = NULL;
+ Boolean create_pixmap = FALSE;
+ unsigned int pm_size;
+
+ /*
+ * I know, we're going to create two pixmaps for each and every
+ * shadow'd widget. Yeuck. I'm semi-relying on server side
+ * pixmap cacheing.
+ */
+
+ if (DefaultDepthOfScreen (scn) == 1) {
+ top_fg_pixel = BlackPixelOfScreen (scn);
+ top_bg_pixel = WhitePixelOfScreen (scn);
+ pm_data = mtshadowpm_bits;
+ pm_size = mtshadowpm_size;
+ create_pixmap = TRUE;
+ } else if (tdw->threeD.be_nice_to_cmap) {
+ if (tdw->core.background_pixel == WhitePixelOfScreen (scn)) {
+ top_fg_pixel = WhitePixelOfScreen (scn);
+ top_bg_pixel = grayPixel( BlackPixelOfScreen (scn), dpy, scn);
+ } else if (tdw->core.background_pixel == BlackPixelOfScreen (scn)) {
+ top_fg_pixel = grayPixel( BlackPixelOfScreen (scn), dpy, scn);
+ top_bg_pixel = WhitePixelOfScreen (scn);
+ } else {
+ top_fg_pixel = tdw->core.background_pixel;
+ top_bg_pixel = WhitePixelOfScreen (scn);
+ }
+#ifndef XAW_GRAY_BLKWHT_STIPPLES
+ if (tdw->core.background_pixel == WhitePixelOfScreen (scn) ||
+ tdw->core.background_pixel == BlackPixelOfScreen (scn)) {
+ pm_data = mtshadowpm_bits;
+ pm_size = mtshadowpm_size;
+ } else
+#endif
+ {
+ pm_data = shadowpm_bits;
+ pm_size = shadowpm_size;
+ }
+
+ create_pixmap = TRUE;
+ } else {
+ pm_size = 0; /* keep gcc happy */
+ }
+
+ if (create_pixmap)
+ tdw->threeD.top_shadow_pxmap = XCreatePixmapFromBitmapData (dpy,
+ RootWindowOfScreen (scn),
+ pm_data,
+ pm_size,
+ pm_size,
+ top_fg_pixel,
+ top_bg_pixel,
+ DefaultDepthOfScreen (scn));
+}
+
+/* ARGSUSED */
+static void AllocBotShadowPixmap (new)
+ Widget new;
+{
+ ThreeDWidget tdw = (ThreeDWidget) new;
+ Display *dpy = XtDisplay (new);
+ Screen *scn = XtScreen (new);
+ unsigned long bot_fg_pixel = 0, bot_bg_pixel = 0;
+ char *pm_data = NULL;
+ Boolean create_pixmap = FALSE;
+ unsigned int pm_size;
+
+ if (DefaultDepthOfScreen (scn) == 1) {
+ bot_fg_pixel = BlackPixelOfScreen (scn);
+ bot_bg_pixel = WhitePixelOfScreen (scn);
+ pm_data = mbshadowpm_bits;
+ pm_size = mbshadowpm_size;
+ create_pixmap = TRUE;
+ } else if (tdw->threeD.be_nice_to_cmap) {
+ if (tdw->core.background_pixel == WhitePixelOfScreen (scn)) {
+ bot_fg_pixel = grayPixel( WhitePixelOfScreen (scn), dpy, scn);
+ bot_bg_pixel = BlackPixelOfScreen (scn);
+ } else if (tdw->core.background_pixel == BlackPixelOfScreen (scn)) {
+ bot_fg_pixel = BlackPixelOfScreen (scn);
+ bot_bg_pixel = grayPixel( BlackPixelOfScreen (scn), dpy, scn);
+ } else {
+ bot_fg_pixel = tdw->core.background_pixel;
+ bot_bg_pixel = BlackPixelOfScreen (scn);
+ }
+#ifndef XAW_GRAY_BLKWHT_STIPPLES
+ if (tdw->core.background_pixel == WhitePixelOfScreen (scn) ||
+ tdw->core.background_pixel == BlackPixelOfScreen (scn)) {
+ pm_data = mbshadowpm_bits;
+ pm_size = mbshadowpm_size;
+ } else
+#endif
+ {
+ pm_data = shadowpm_bits;
+ pm_size = shadowpm_size;
+ }
+ create_pixmap = TRUE;
+ } else {
+ pm_size = 0; /* keep gcc happy */
+ }
+
+ if (create_pixmap)
+ tdw->threeD.bot_shadow_pxmap = XCreatePixmapFromBitmapData (dpy,
+ RootWindowOfScreen (scn),
+ pm_data,
+ pm_size,
+ pm_size,
+ bot_fg_pixel,
+ bot_bg_pixel,
+ DefaultDepthOfScreen (scn));
+}
+
+/* ARGSUSED */
+void Xaw3dComputeTopShadowRGB (new, xcol_out)
+ Widget new;
+ XColor *xcol_out;
+{
+ if (XtIsSubclass (new, threeDWidgetClass)) {
+ ThreeDWidget tdw = (ThreeDWidget) new;
+ XColor get_c;
+ double contrast;
+ Display *dpy = XtDisplay (new);
+ Screen *scn = XtScreen (new);
+ Colormap cmap = new->core.colormap;
+
+ get_c.pixel = tdw->core.background_pixel;
+ if (get_c.pixel == WhitePixelOfScreen (scn) ||
+ get_c.pixel == BlackPixelOfScreen (scn)) {
+ contrast = (100 - tdw->threeD.top_shadow_contrast) / 100.0;
+ xcol_out->red = contrast * 65535.0;
+ xcol_out->green = contrast * 65535.0;
+ xcol_out->blue = contrast * 65535.0;
+ } else {
+ contrast = 1.0 + tdw->threeD.top_shadow_contrast / 100.0;
+ XQueryColor (dpy, cmap, &get_c);
+#define MIN(x,y) (unsigned short) (x < y) ? x : y
+ xcol_out->red = MIN (65535, (int) (contrast * (double) get_c.red));
+ xcol_out->green = MIN (65535, (int) (contrast * (double) get_c.green));
+ xcol_out->blue = MIN (65535, (int) (contrast * (double) get_c.blue));
+#undef MIN
+ }
+ } else
+ xcol_out->red = xcol_out->green = xcol_out->blue = 0;
+}
+
+/* ARGSUSED */
+static void AllocTopShadowPixel (new)
+ Widget new;
+{
+ XColor set_c;
+ ThreeDWidget tdw = (ThreeDWidget) new;
+ Display *dpy = XtDisplay (new);
+ Screen *scn = XtScreen (new);
+ Colormap cmap = new->core.colormap;
+
+ Xaw3dComputeTopShadowRGB (new, &set_c);
+ (void) XAllocColor (dpy, cmap, &set_c);
+ tdw->threeD.top_shadow_pixel = set_c.pixel;
+}
+
+/* ARGSUSED */
+void Xaw3dComputeBottomShadowRGB (new, xcol_out)
+ Widget new;
+ XColor *xcol_out;
+{
+ if (XtIsSubclass (new, threeDWidgetClass)) {
+ ThreeDWidget tdw = (ThreeDWidget) new;
+ XColor get_c;
+ double contrast;
+ Display *dpy = XtDisplay (new);
+ Screen *scn = XtScreen (new);
+ Colormap cmap = new->core.colormap;
+
+ get_c.pixel = tdw->core.background_pixel;
+ if (get_c.pixel == WhitePixelOfScreen (scn) ||
+ get_c.pixel == BlackPixelOfScreen (scn)) {
+ contrast = tdw->threeD.bot_shadow_contrast / 100.0;
+ xcol_out->red = contrast * 65535.0;
+ xcol_out->green = contrast * 65535.0;
+ xcol_out->blue = contrast * 65535.0;
+ } else {
+ XQueryColor (dpy, cmap, &get_c);
+ contrast = (100 - tdw->threeD.bot_shadow_contrast) / 100.0;
+ xcol_out->red = contrast * get_c.red;
+ xcol_out->green = contrast * get_c.green;
+ xcol_out->blue = contrast * get_c.blue;
+ }
+ } else
+ xcol_out->red = xcol_out->green = xcol_out->blue = 0;
+}
+
+/* ARGSUSED */
+static void AllocBotShadowPixel (new)
+ Widget new;
+{
+ XColor set_c;
+ ThreeDWidget tdw = (ThreeDWidget) new;
+ Display *dpy = XtDisplay (new);
+ Screen *scn = XtScreen (new);
+ Colormap cmap = new->core.colormap;
+
+ Xaw3dComputeBottomShadowRGB (new, &set_c);
+ (void) XAllocColor (dpy, cmap, &set_c);
+ tdw->threeD.bot_shadow_pixel = set_c.pixel;
+}
+
+
+static XrmQuark XtQReliefNone, XtQReliefRaised, XtQReliefSunken,
+ XtQReliefRidge, XtQReliefGroove;
+
+#define done(address, type) { \
+ toVal->size = sizeof(type); \
+ toVal->addr = (XPointer) address; \
+ return; \
+ }
+
+/* ARGSUSED */
+static void _CvtStringToRelief(args, num_args, fromVal, toVal)
+ XrmValuePtr args; /* unused */
+ Cardinal *num_args; /* unused */
+ XrmValuePtr fromVal;
+ XrmValuePtr toVal;
+{
+ static XtRelief relief;
+ XrmQuark q;
+ char lowerName[1000];
+
+ XmuCopyISOLatin1Lowered (lowerName, (char*)fromVal->addr);
+ q = XrmStringToQuark(lowerName);
+ if (q == XtQReliefNone) {
+ relief = XtReliefNone;
+ done(&relief, XtRelief);
+ }
+ if (q == XtQReliefRaised) {
+ relief = XtReliefRaised;
+ done(&relief, XtRelief);
+ }
+ if (q == XtQReliefSunken) {
+ relief = XtReliefSunken;
+ done(&relief, XtRelief);
+ }
+ if (q == XtQReliefRidge) {
+ relief = XtReliefRidge;
+ done(&relief, XtRelief);
+ }
+ if (q == XtQReliefGroove) {
+ relief = XtReliefGroove;
+ done(&relief, XtRelief);
+ }
+ XtStringConversionWarning(fromVal->addr, "relief");
+ toVal->addr = NULL;
+ toVal->size = 0;
+}
+
+static void ClassInitialize()
+{
+ XawInitializeWidgetSet();
+ XtQReliefNone = XrmPermStringToQuark("none");
+ XtQReliefRaised = XrmPermStringToQuark("raised");
+ XtQReliefSunken = XrmPermStringToQuark("sunken");
+ XtQReliefRidge = XrmPermStringToQuark("ridge");
+ XtQReliefGroove = XrmPermStringToQuark("groove");
+
+ XtAddConverter( XtRString, XtRRelief, _CvtStringToRelief,
+ (XtConvertArgList)NULL, 0 );
+}
+
+
+/* ARGSUSED */
+static void ClassPartInitialize (wc)
+ WidgetClass wc;
+
+{
+ ThreeDClassRec *tdwc = (ThreeDClassRec*) wc;
+ ThreeDClassRec *super = (ThreeDClassRec*) tdwc->core_class.superclass;
+
+ if (tdwc->threeD_class.shadowdraw == XtInheritXaw3dShadowDraw)
+ tdwc->threeD_class.shadowdraw = super->threeD_class.shadowdraw;
+}
+
+
+/* ARGSUSED */
+static void Initialize (request, new, args, num_args)
+ Widget request, new;
+ ArgList args;
+ Cardinal *num_args;
+{
+ ThreeDWidget tdw = (ThreeDWidget) new;
+ Screen *scr = XtScreen (new);
+
+ if (tdw->threeD.be_nice_to_cmap || DefaultDepthOfScreen (scr) == 1) {
+ AllocTopShadowPixmap (new);
+ AllocBotShadowPixmap (new);
+ } else {
+ if (tdw->threeD.top_shadow_pixel == tdw->threeD.bot_shadow_pixel) {
+ /*
+ Eeek. We're probably going to XQueryColor() twice
+ for each widget. Necessary because you can set the
+ top and bottom shadows independent of each other in
+ SetValues. Some cacheing would certainly help...
+ */
+ AllocTopShadowPixel (new);
+ AllocBotShadowPixel (new);
+ }
+ tdw->threeD.top_shadow_pxmap = tdw->threeD.bot_shadow_pxmap = (Pixmap) 0;
+ }
+ AllocTopShadowGC (new);
+ AllocBotShadowGC (new);
+}
+
+static void Realize (gw, valueMask, attrs)
+ Widget gw;
+ XtValueMask *valueMask;
+ XSetWindowAttributes *attrs;
+{
+ /*
+ * This is necessary because Simple doesn't have a realize method
+ * XtInheritRealize in the ThreeD class record doesn't work. This
+ * daisychains through Simple to the Core class realize method
+ */
+ (*threeDWidgetClass->core_class.superclass->core_class.realize)
+ (gw, valueMask, attrs);
+}
+
+static void Destroy (w)
+ Widget w;
+{
+ ThreeDWidget tdw = (ThreeDWidget) w;
+ XtReleaseGC (w, tdw->threeD.top_shadow_GC);
+ XtReleaseGC (w, tdw->threeD.bot_shadow_GC);
+ if (tdw->threeD.top_shadow_pxmap)
+ XFreePixmap (XtDisplay (w), tdw->threeD.top_shadow_pxmap);
+ if (tdw->threeD.bot_shadow_pxmap)
+ XFreePixmap (XtDisplay (w), tdw->threeD.bot_shadow_pxmap);
+}
+
+/* ARGSUSED */
+static void Redisplay (w, event, region)
+ Widget w;
+ XEvent *event; /* unused */
+ Region region; /* unused */
+{
+ ThreeDWidget tdw = (ThreeDWidget) w;
+
+ _Xaw3dDrawShadows (w, event, region, tdw->threeD.relief, True);
+}
+
+/* ARGSUSED */
+static Boolean SetValues (gcurrent, grequest, gnew, args, num_args)
+ Widget gcurrent, grequest, gnew;
+ ArgList args;
+ Cardinal *num_args;
+{
+ ThreeDWidget current = (ThreeDWidget) gcurrent;
+ ThreeDWidget new = (ThreeDWidget) gnew;
+ Boolean redisplay = FALSE;
+ Boolean alloc_top_pixel = FALSE;
+ Boolean alloc_bot_pixel = FALSE;
+ Boolean alloc_top_pxmap = FALSE;
+ Boolean alloc_bot_pxmap = FALSE;
+
+ (*threeDWidgetClass->core_class.superclass->core_class.set_values)
+ (gcurrent, grequest, gnew, NULL, 0);
+ if (new->threeD.relief != current->threeD.relief)
+ redisplay = TRUE;
+ if (new->threeD.shadow_width != current->threeD.shadow_width)
+ redisplay = TRUE;
+ if (new->threeD.be_nice_to_cmap != current->threeD.be_nice_to_cmap) {
+ if (new->threeD.be_nice_to_cmap) {
+ alloc_top_pxmap = TRUE;
+ alloc_bot_pxmap = TRUE;
+ } else {
+ alloc_top_pixel = TRUE;
+ alloc_bot_pixel = TRUE;
+ }
+ redisplay = TRUE;
+ }
+ if (!new->threeD.be_nice_to_cmap &&
+ new->threeD.top_shadow_contrast != current->threeD.top_shadow_contrast)
+ alloc_top_pixel = TRUE;
+ if (!new->threeD.be_nice_to_cmap &&
+ new->threeD.bot_shadow_contrast != current->threeD.bot_shadow_contrast)
+ alloc_bot_pixel = TRUE;
+ if (alloc_top_pixel)
+ AllocTopShadowPixel (gnew);
+ if (alloc_bot_pixel)
+ AllocBotShadowPixel (gnew);
+ if (alloc_top_pxmap)
+ AllocTopShadowPixmap (gnew);
+ if (alloc_bot_pxmap)
+ AllocBotShadowPixmap (gnew);
+ if (!new->threeD.be_nice_to_cmap &&
+ new->threeD.top_shadow_pixel != current->threeD.top_shadow_pixel)
+ alloc_top_pixel = TRUE;
+ if (!new->threeD.be_nice_to_cmap &&
+ new->threeD.bot_shadow_pixel != current->threeD.bot_shadow_pixel)
+ alloc_bot_pixel = TRUE;
+ if (new->threeD.be_nice_to_cmap) {
+ if (alloc_top_pxmap) {
+ XtReleaseGC (gcurrent, current->threeD.top_shadow_GC);
+ AllocTopShadowGC (gnew);
+ redisplay = True;
+ }
+ if (alloc_bot_pxmap) {
+ XtReleaseGC (gcurrent, current->threeD.bot_shadow_GC);
+ AllocBotShadowGC (gnew);
+ redisplay = True;
+ }
+ } else {
+ if (alloc_top_pixel) {
+ if (new->threeD.top_shadow_pxmap) {
+ XFreePixmap (XtDisplay (gnew), new->threeD.top_shadow_pxmap);
+ new->threeD.top_shadow_pxmap = (Pixmap) NULL;
+ }
+ XtReleaseGC (gcurrent, current->threeD.top_shadow_GC);
+ AllocTopShadowGC (gnew);
+ redisplay = True;
+ }
+ if (alloc_bot_pixel) {
+ if (new->threeD.bot_shadow_pxmap) {
+ XFreePixmap (XtDisplay (gnew), new->threeD.bot_shadow_pxmap);
+ new->threeD.bot_shadow_pxmap = (Pixmap) NULL;
+ }
+ XtReleaseGC (gcurrent, current->threeD.bot_shadow_GC);
+ AllocBotShadowGC (gnew);
+ redisplay = True;
+ }
+ }
+ return (redisplay);
+}
+
+/* ARGSUSED */
+static void
+_Xaw3dDrawShadows (gw, event, region, relief, out)
+ Widget gw;
+ XEvent *event;
+ Region region;
+ XtRelief relief;
+ Boolean out;
+{
+ XPoint pt[6];
+ ThreeDWidget tdw = (ThreeDWidget) gw;
+ Dimension s = tdw->threeD.shadow_width;
+
+ /*
+ * Draw the shadows using the core part width and height,
+ * and the threeD part relief and shadow_width.
+ * No point to do anything if the shadow_width is 0 or the
+ * widget has not been realized.
+ */
+ if ((s > 0) && XtIsRealized (gw)) {
+ Dimension h = tdw->core.height;
+ Dimension w = tdw->core.width;
+ Dimension hms = h - s;
+ Dimension wms = w - s;
+ Display *dpy = XtDisplay (gw);
+ Window win = XtWindow (gw);
+ GC realtop = tdw->threeD.top_shadow_GC;
+ GC realbot = tdw->threeD.bot_shadow_GC;
+ GC top, bot;
+
+ if (out) {
+ top = tdw->threeD.top_shadow_GC;
+ bot = tdw->threeD.bot_shadow_GC;
+ } else {
+ top = tdw->threeD.bot_shadow_GC;
+ bot = tdw->threeD.top_shadow_GC;
+ }
+
+ if (relief == XtReliefRaised || relief == XtReliefSunken) {
+ /* top-left shadow */
+ if ((region == NULL) ||
+ (XRectInRegion (region, 0, 0, w, s) != RectangleOut) ||
+ (XRectInRegion (region, 0, 0, s, h) != RectangleOut)) {
+ pt[0].x = 0; pt[0].y = h;
+ pt[1].x = pt[1].y = 0;
+ pt[2].x = w; pt[2].y = 0;
+ pt[3].x = wms; pt[3].y = s;
+ pt[4].x = pt[4].y = s;
+ pt[5].x = s; pt[5].y = hms;
+ XFillPolygon (dpy, win,
+ (relief == XtReliefRaised) ? top : bot,
+ pt, 6, Complex, CoordModeOrigin);
+ }
+
+ /* bottom-right shadow */
+ if ((region == NULL) ||
+ (XRectInRegion (region, 0, hms, w, s) != RectangleOut) ||
+ (XRectInRegion (region, wms, 0, s, h) != RectangleOut)) {
+ pt[0].x = 0; pt[0].y = h;
+ pt[1].x = w; pt[1].y = h;
+ pt[2].x = w; pt[2].y = 0;
+ pt[3].x = wms; pt[3].y = s;
+ pt[4].x = wms; pt[4].y = hms;
+ pt[5].x = s; pt[5].y = hms;
+ XFillPolygon (dpy, win,
+ (relief == XtReliefRaised) ? bot : top,
+ pt, 6, Complex, CoordModeOrigin);
+ }
+ } else if (relief == XtReliefRidge || relief == XtReliefGroove) {
+ /* split the shadow width */
+ s /= 2; hms = h - s; wms = w - s;
+
+ /* outer top-left shadow */
+ if ((region == NULL) ||
+ (XRectInRegion (region, 0, 0, w, s) != RectangleOut) ||
+ (XRectInRegion (region, 0, 0, s, h) != RectangleOut)) {
+ pt[0].x = 0; pt[0].y = h;
+ pt[1].x = pt[1].y = 0;
+ pt[2].x = w; pt[2].y = 0;
+ pt[3].x = wms; pt[3].y = s;
+ pt[4].x = pt[4].y = s;
+ pt[5].x = s; pt[5].y = hms;
+ XFillPolygon (dpy, win,
+ (relief == XtReliefRidge) ? realtop : realbot,
+ pt, 6, Complex, CoordModeOrigin);
+ }
+
+ /* outer bottom-right shadow */
+ if ((region == NULL) ||
+ (XRectInRegion (region, 0, hms, w, s) != RectangleOut) ||
+ (XRectInRegion (region, wms, 0, s, h) != RectangleOut)) {
+ pt[0].x = 0; pt[0].y = h;
+ pt[1].x = w; pt[1].y = h;
+ pt[2].x = w; pt[2].y = 0;
+ pt[3].x = wms; pt[3].y = s;
+ pt[4].x = wms; pt[4].y = hms;
+ pt[5].x = s; pt[5].y = hms;
+ XFillPolygon (dpy, win,
+ (relief == XtReliefRidge) ? realbot : realtop,
+ pt, 6, Complex, CoordModeOrigin);
+ }
+
+ /* inner top-left shadow */
+ if ((region == NULL) ||
+ (XRectInRegion (region, 0, 0, w, s) != RectangleOut) ||
+ (XRectInRegion (region, 0, 0, s, h) != RectangleOut)) {
+ pt[0].x = s; pt[0].y = h;
+ pt[1].x = pt[1].y = s;
+ pt[2].x = w; pt[2].y = s;
+ pt[3].x = wms; pt[3].y = s * 2;
+ pt[4].x = pt[4].y = s * 2;
+ pt[5].x = s * 2; pt[5].y = hms;
+ XFillPolygon (dpy, win,
+ (relief == XtReliefRidge) ? bot: top,
+ pt, 6, Complex, CoordModeOrigin);
+ }
+
+ /* inner bottom-right shadow */
+ if ((region == NULL) ||
+ (XRectInRegion (region, 0, hms, w, s) != RectangleOut) ||
+ (XRectInRegion (region, wms, 0, s, h) != RectangleOut)) {
+ pt[0].x = s; pt[0].y = hms;
+ pt[1].x = wms; pt[1].y = hms;
+ pt[2].x = wms; pt[2].y = s;
+ pt[3].x = wms - s; pt[3].y = s * 2;
+ pt[4].x = wms - s; pt[4].y = hms - s;
+ pt[5].x = s * 2; pt[5].y = hms - s;
+ XFillPolygon (dpy, win,
+ (relief == XtReliefRidge) ? top : bot,
+ pt, 6, Complex, CoordModeOrigin);
+ }
+ }
+ }
+}
+
+/*
+ * _ShadowSurroundedBox() is somewhat redundant with _Xaw3dDrawShadows(),
+ * but has a more explicit interface, and ignores threeD part relief.
+ */
+
+/* ARGSUSED */
+void
+_ShadowSurroundedBox(gw, tdw, x0, y0, x1, y1, relief, out)
+Widget gw;
+ThreeDWidget tdw;
+Position x0, y0, x1, y1;
+XtRelief relief; /* unused */
+Boolean out;
+{
+ XPoint pt[6];
+ Dimension s = tdw->threeD.shadow_width;
+
+ /*
+ * Draw the shadows using the core part width and height,
+ * and the threeD part shadow_width.
+ * No point to do anything if the shadow_width is 0 or the
+ * widget has not been realized.
+ */
+ if ((s > 0) && XtIsRealized(gw))
+ {
+ Dimension h = y1 - y0;
+ Dimension w = x1 - x0;
+ Dimension wms = w - s;
+ Dimension hms = h - s;
+ Dimension sm = (s > 1 ? s / 2 : 1);
+ Dimension wmsm = w - sm;
+ Dimension hmsm = h - sm;
+ Display *dpy = XtDisplay(gw);
+ Window win = XtWindow(gw);
+ GC top, bot;
+
+ if (out)
+ {
+ top = tdw->threeD.top_shadow_GC;
+ bot = tdw->threeD.bot_shadow_GC;
+ }
+ else
+ {
+ top = tdw->threeD.bot_shadow_GC;
+ bot = tdw->threeD.top_shadow_GC;
+ }
+
+ /* top-left shadow */
+ pt[0].x = x0; pt[0].y = y0 + h;
+ pt[1].x = x0; pt[1].y = y0;
+ pt[2].x = x0 + w; pt[2].y = y0;
+ pt[3].x = x0 + wmsm; pt[3].y = y0 + sm - 1;
+ pt[4].x = x0 + sm; pt[4].y = y0 + sm;
+ pt[5].x = x0 + sm - 1; pt[5].y = y0 + hmsm;
+ XFillPolygon(dpy, win, top, pt, 6, Complex, CoordModeOrigin);
+ if (s > 1)
+ {
+ pt[0].x = x0 + s - 1; pt[0].y = y0 + hms;
+ pt[1].x = x0 + s; pt[1].y = y0 + s;
+ pt[2].x = x0 + wms; pt[2].y = y0 + s - 1;
+ XFillPolygon(dpy, win, top, pt, 6, Complex, CoordModeOrigin);
+ }
+
+ /* bottom-right shadow */
+ pt[0].x = x0; pt[0].y = y0 + h;
+ pt[1].x = x0 + w; pt[1].y = y0 + h;
+ pt[2].x = x0 + w; pt[2].y = y0;
+ pt[3].x = x0 + wmsm; pt[3].y = y0 + sm - 1;
+ pt[4].x = x0 + wmsm; pt[4].y = y0 + hmsm;
+ pt[5].x = x0 + sm - 1; pt[5].y = y0 + hmsm;
+ XFillPolygon(dpy, win, bot, pt, 6, Complex, CoordModeOrigin);
+ if (s > 1)
+ {
+ pt[0].x = x0 + s - 1; pt[0].y = y0 + hms;
+ pt[1].x = x0 + wms; pt[1].y = y0 + hms;
+ pt[2].x = x0 + wms; pt[2].y = y0 + s - 1;
+ XFillPolygon(dpy, win, bot, pt, 6, Complex, CoordModeOrigin);
+ }
+ }
+}
+
diff --git a/src/ThreeD.h b/src/ThreeD.h
new file mode 100644
index 0000000..d7cf8e2
--- /dev/null
+++ b/src/ThreeD.h
@@ -0,0 +1,119 @@
+/*
+* $KK: ThreeD.h,v 0.3 92/11/04 xx:xx:xx keithley Exp $
+*/
+
+/***********************************************************
+Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+Copyright 1992 by Kaleb Keithley
+
+ 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 names of Digital, MIT, or Kaleb
+Keithley 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.
+
+******************************************************************/
+
+#ifndef _XawThreeD_h
+#define _XawThreeD_h
+
+/***********************************************************************
+ *
+ * ThreeD Widget
+ *
+ ***********************************************************************/
+
+#include <X11/Xmu/Converters.h>
+
+/* Parameters:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ shadowWidth ShadowWidth Dimension 2
+ topShadowPixel TopShadowPixel Pixel dynamic
+ bottomShadowPixel BottomShadowPixel Pixel dynamic
+ topShadowContrast TopShadowContrast Int 20
+ bottomShadowContrast BottomShadowContrast Int 40
+ userData UserData XtPointer NULL
+ beNiceToColormap BeNiceToColormap Boolean False
+ relief Relief XtRelief XtReliefRaised
+
+*/
+
+#define XtNshadowWidth "shadowWidth"
+#define XtCShadowWidth "ShadowWidth"
+#define XtNtopShadowPixel "topShadowPixel"
+#define XtCTopShadowPixel "TopShadowPixel"
+#define XtNbottomShadowPixel "bottomShadowPixel"
+#define XtCBottomShadowPixel "BottomShadowPixel"
+#define XtNtopShadowContrast "topShadowContrast"
+#define XtCTopShadowContrast "TopShadowContrast"
+#define XtNbottomShadowContrast "bottomShadowContrast"
+#define XtCBottomShadowContrast "BottomShadowContrast"
+#define XtNbeNiceToColormap "beNiceToColormap"
+#define XtCBeNiceToColormap "BeNiceToColormap"
+#define XtNbeNiceToColourmap "beNiceToColormap"
+#define XtCBeNiceToColourmap "BeNiceToColormap"
+#define XtNuserData "userData"
+#define XtCUserData "UserData"
+#define XtNrelief "relief"
+#define XtCRelief "Relief"
+
+typedef enum {
+ XtReliefNone,
+ XtReliefRaised,
+ XtReliefSunken,
+ XtReliefRidge,
+ XtReliefGroove
+} XtRelief;
+
+typedef struct _ThreeDRec *ThreeDWidget;
+typedef struct _ThreeDClassRec *ThreeDWidgetClass;
+
+extern WidgetClass threeDWidgetClass;
+
+_XFUNCPROTOBEGIN
+
+extern void Xaw3dComputeTopShadowRGB (
+#if NeedFunctionPrototypes
+ Widget /* new */,
+ XColor* /* xcol_out */
+#endif
+);
+
+extern void Xaw3dComputeBottomShadowRGB (
+#if NeedFunctionPrototypes
+ Widget /* new */,
+ XColor* /* xcol_out */
+#endif
+);
+
+extern void _ShadowSurroundedBox (
+#if NeedFunctionPrototypes
+ Widget,
+ ThreeDWidget,
+ Position,
+ Position,
+ Position,
+ Position,
+ XtRelief,
+ Boolean
+#endif
+);
+
+_XFUNCPROTOEND
+
+#endif /* _XawThreeD_h */
diff --git a/src/ThreeDP.h b/src/ThreeDP.h
new file mode 100644
index 0000000..44ccb97
--- /dev/null
+++ b/src/ThreeDP.h
@@ -0,0 +1,77 @@
+/*
+* $KK: ThreeDP.h,v 0.3 92/11/04 xx:xx:xx keithley Exp $
+*/
+
+/***********************************************************
+Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+Copyright 1992 by Kaleb Keithley
+
+ 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 names of Digital, MIT, or Kaleb
+Keithley 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.
+
+******************************************************************/
+
+#ifndef _ThreeDP_h
+#define _ThreeDP_h
+
+#include <X11/Xaw3d/ThreeD.h>
+#include <X11/Xaw3d/SimpleP.h>
+
+#define XtRRelief "Relief"
+
+typedef struct {
+ Dimension shadow_width;
+ Pixel top_shadow_pixel;
+ Pixel bot_shadow_pixel;
+ Pixmap top_shadow_pxmap;
+ Pixmap bot_shadow_pxmap;
+ int top_shadow_contrast;
+ int bot_shadow_contrast;
+ GC top_shadow_GC;
+ GC bot_shadow_GC;
+ XtPointer user_data;
+ Boolean be_nice_to_cmap;
+ XtRelief relief;
+ } ThreeDPart;
+
+/* Full instance record declaration */
+typedef struct _ThreeDRec {
+ CorePart core;
+ SimplePart simple;
+ ThreeDPart threeD;
+ } ThreeDRec;
+
+typedef struct {
+ void (*shadowdraw)();
+ } ThreeDClassPart;
+
+#define XtInheritXaw3dShadowDraw ((void (*)())_XtInherit)
+
+/* Full class record declaration. */
+typedef struct _ThreeDClassRec {
+ CoreClassPart core_class;
+ SimpleClassPart simple_class;
+ ThreeDClassPart threeD_class;
+ } ThreeDClassRec;
+
+/* Class pointer. */
+extern ThreeDClassRec threeDClassRec;
+
+
+#endif /* _ThreeDP_h */
diff --git a/src/Tip.c b/src/Tip.c
new file mode 100644
index 0000000..888eeac
--- /dev/null
+++ b/src/Tip.c
@@ -0,0 +1,718 @@
+/*
+ * Copyright (c) 1999 by The XFree86 Project, Inc.
+ *
+ * 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 XFREE86 PROJECT 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 XFree86 Project 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
+ * XFree86 Project.
+ *
+ * Author: Paulo César Pereira de Andrade
+ */
+
+/*
+ * Portions Copyright (c) 2003 David J. Hawkey Jr.
+ * Rights, permissions, and disclaimer per the above XFree86 license.
+ */
+
+/* $XFree86: xc/lib/Xaw/Tip.c,v 1.5 2000/05/18 16:29:53 dawes Exp $ */
+
+#include "Xaw3dP.h"
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xos.h>
+#include <X11/Xmu/Converters.h>
+#include <X11/Xaw3d/TipP.h>
+#include <X11/Xaw3d/XawInit.h>
+
+#define TIP_EVENT_MASK (ButtonPressMask | \
+ ButtonReleaseMask | \
+ PointerMotionMask | \
+ ButtonMotionMask | \
+ KeyPressMask | \
+ KeyReleaseMask | \
+ EnterWindowMask | \
+ LeaveWindowMask)
+
+/*
+ * Types
+ */
+typedef struct _WidgetInfo {
+ Widget widget;
+ String label;
+ struct _WidgetInfo *next;
+} WidgetInfo;
+
+typedef struct _XawTipInfo {
+ Screen *screen;
+ TipWidget tip;
+ Bool mapped;
+ WidgetInfo *widgets;
+ struct _XawTipInfo *next;
+} XawTipInfo;
+
+typedef struct {
+ XawTipInfo *info;
+ WidgetInfo *winfo;
+} TimeoutInfo;
+
+/*
+ * Class Methods
+ */
+static void XawTipClassInitialize();
+static void XawTipInitialize();
+static void XawTipDestroy();
+static void XawTipExpose();
+static void XawTipRealize();
+static Boolean XawTipSetValues();
+
+/*
+ * Prototypes
+ */
+static void TipEventHandler();
+static void TipShellEventHandler();
+static WidgetInfo *CreateWidgetInfo();
+static WidgetInfo *FindWidgetInfo();
+static XawTipInfo *CreateTipInfo();
+static XawTipInfo *FindTipInfo();
+static void ResetTip();
+static void TipTimeoutCallback();
+static void TipLayout();
+static void TipPosition();
+
+/*
+ * Initialization
+ */
+#define offset(field) XtOffsetOf(TipRec, tip.field)
+static XtResource resources[] = {
+ {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
+ offset(foreground), XtRString, XtDefaultForeground},
+ {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct*),
+ offset(font), XtRString, XtDefaultFont},
+#ifdef XAW_INTERNATIONALIZATION
+ {XtNfontSet, XtCFontSet, XtRFontSet, sizeof(XFontSet),
+ offset(fontset), XtRString, XtDefaultFontSet},
+#endif
+ {XtNlabel, XtCLabel, XtRString, sizeof(String),
+ offset(label), XtRString, NULL},
+ {XtNencoding, XtCEncoding, XtRUnsignedChar, sizeof(unsigned char),
+ offset(encoding), XtRImmediate, (XtPointer)XawTextEncoding8bit},
+ {XtNinternalHeight, XtCHeight, XtRDimension, sizeof(Dimension),
+ offset(internal_height), XtRImmediate, (XtPointer)2},
+ {XtNinternalWidth, XtCWidth, XtRDimension, sizeof(Dimension),
+ offset(internal_width), XtRImmediate, (XtPointer)2},
+ {XtNbackingStore, XtCBackingStore, XtRBackingStore, sizeof(int),
+ offset(backing_store), XtRImmediate,
+ (XtPointer)(Always + WhenMapped + NotUseful)},
+ {XtNtimeout, XtCTimeout, XtRInt, sizeof(int),
+ offset(timeout), XtRImmediate, (XtPointer)500},
+};
+#undef offset
+
+TipClassRec tipClassRec = {
+ /* core */
+ {
+ (WidgetClass)&widgetClassRec, /* superclass */
+ "Tip", /* class_name */
+ sizeof(TipRec), /* widget_size */
+ XawTipClassInitialize, /* class_initialize */
+ NULL, /* class_part_initialize */
+ False, /* class_inited */
+ XawTipInitialize, /* initialize */
+ NULL, /* initialize_hook */
+ XawTipRealize, /* realize */
+ NULL, /* actions */
+ 0, /* num_actions */
+ resources, /* resources */
+ XtNumber(resources), /* num_resources */
+ NULLQUARK, /* xrm_class */
+ True, /* compress_motion */
+ True, /* compress_exposure */
+ True, /* compress_enterleave */
+ False, /* visible_interest */
+ XawTipDestroy, /* destroy */
+ NULL, /* resize */
+ XawTipExpose, /* expose */
+ XawTipSetValues, /* set_values */
+ NULL, /* set_values_hook */
+ XtInheritSetValuesAlmost, /* set_values_almost */
+ NULL, /* get_values_hook */
+ NULL, /* accept_focus */
+ XtVersion, /* version */
+ NULL, /* callback_private */
+ NULL, /* tm_table */
+ XtInheritQueryGeometry, /* query_geometry */
+ XtInheritDisplayAccelerator, /* display_accelerator */
+ NULL, /* extension */
+ },
+ /* tip */
+ {
+ NULL, /* extension */
+ },
+};
+
+WidgetClass tipWidgetClass = (WidgetClass)&tipClassRec;
+
+static XawTipInfo *TipInfoList = NULL;
+static TimeoutInfo TimeoutData;
+
+/*
+ * Implementation
+ */
+
+/*
+ * XmuCvtBackingStoreToString() from XFree86's distribution, because
+ * X.Org's distribution doesn't have it.
+ */
+
+/*ARGSUSED*/
+static Boolean
+XawCvtBackingStoreToString(dpy, args, num_args, fromVal, toVal, data)
+Display *dpy;
+XrmValuePtr args;
+Cardinal *num_args;
+XrmValuePtr fromVal, toVal;
+XtPointer *data;
+{
+ static String buffer;
+ Cardinal size;
+
+ switch (*(int *)fromVal->addr)
+ {
+ case NotUseful:
+ buffer = XtEnotUseful;
+ break;
+ case WhenMapped:
+ buffer = XtEwhenMapped;
+ break;
+ case Always:
+ buffer = XtEalways;
+ break;
+ case (Always + WhenMapped + NotUseful):
+ buffer = XtEdefault;
+ break;
+ default:
+ XtWarning("Cannot convert BackingStore to String");
+ toVal->addr = NULL;
+ toVal->size = 0;
+ return (False);
+ }
+
+ size = strlen(buffer) + 1;
+ if (toVal->addr != NULL)
+ {
+ if (toVal->size < size)
+ {
+ toVal->size = size;
+ return (False);
+ }
+ strcpy((char *)toVal->addr, buffer);
+ }
+ else
+ toVal->addr = (XPointer)buffer;
+ toVal->size = sizeof(String);
+
+ return (True);
+}
+
+static void
+XawTipClassInitialize()
+{
+ XawInitializeWidgetSet();
+ XtAddConverter(XtRString, XtRBackingStore, XmuCvtStringToBackingStore,
+ NULL, 0);
+ XtSetTypeConverter(XtRBackingStore, XtRString, XawCvtBackingStoreToString,
+ NULL, 0, XtCacheNone, NULL);
+}
+
+/*ARGSUSED*/
+static void
+XawTipInitialize(req, w, args, num_args)
+Widget req, w;
+ArgList args;
+Cardinal *num_args;
+{
+ TipWidget tip = (TipWidget)w;
+ XGCValues values;
+
+ tip->tip.timer = 0;
+
+ values.foreground = tip->tip.foreground;
+ values.background = tip->core.background_pixel;
+ values.font = tip->tip.font->fid;
+ values.graphics_exposures = False;
+
+ tip->tip.gc = XtAllocateGC(w, 0, GCForeground | GCBackground | GCFont |
+ GCGraphicsExposures, &values, GCFont, 0);
+}
+
+static void
+XawTipDestroy(w)
+Widget w;
+{
+ XawTipInfo *info = FindTipInfo(w);
+ WidgetInfo *winfo;
+ TipWidget tip = (TipWidget)w;
+
+ if (tip->tip.timer)
+ XtRemoveTimeOut(tip->tip.timer);
+
+ XtReleaseGC(w, tip->tip.gc);
+
+ XtRemoveEventHandler(XtParent(w), KeyPressMask, False,
+ TipShellEventHandler, (XtPointer)NULL);
+
+ while (info->widgets) {
+ winfo = info->widgets->next;
+ XtFree((char *)info->widgets->label);
+ XtFree((char *)info->widgets);
+ info->widgets = winfo;
+ }
+
+ if (info == TipInfoList)
+ TipInfoList = TipInfoList->next;
+ else {
+ XawTipInfo *p = TipInfoList;
+
+ while (p && p->next != info)
+ p = p->next;
+ if (p)
+ p->next = info->next;
+ }
+
+ XtFree((char *)info);
+}
+
+static void
+XawTipRealize(w, mask, attr)
+Widget w;
+Mask *mask;
+XSetWindowAttributes *attr;
+{
+ TipWidget tip = (TipWidget)w;
+
+ if (tip->tip.backing_store == Always ||
+ tip->tip.backing_store == NotUseful ||
+ tip->tip.backing_store == WhenMapped) {
+ *mask |= CWBackingStore;
+ attr->backing_store = tip->tip.backing_store;
+ }
+ else
+ *mask &= ~CWBackingStore;
+ *mask |= CWOverrideRedirect;
+ attr->override_redirect = True;
+
+ XtWindow(w) = XCreateWindow(DisplayOfScreen(XtScreen(w)),
+ RootWindowOfScreen(XtScreen(w)),
+ XtX(w), XtY(w),
+ XtWidth(w) ? XtWidth(w) : 1,
+ XtHeight(w) ? XtHeight(w) : 1,
+ XtBorderWidth(w),
+ DefaultDepthOfScreen(XtScreen(w)),
+ InputOutput, CopyFromParent, *mask, attr);
+}
+
+static void
+XawTipExpose(w, event, region)
+Widget w;
+XEvent *event;
+Region region;
+{
+ TipWidget tip = (TipWidget)w;
+ GC gc = tip->tip.gc;
+ char *nl, *label = tip->tip.label;
+ Position y = tip->tip.internal_height + tip->tip.font->max_bounds.ascent;
+ int len;
+
+#ifdef XAW_INTERNATIONALIZATION
+ if (tip->tip.international == True) {
+ Position ksy = tip->tip.internal_height;
+ XFontSetExtents *ext = XExtentsOfFontSet(tip->tip.fontset);
+
+ ksy += abs(ext->max_ink_extent.y);
+
+ while ((nl = index(label, '\n')) != NULL) {
+ XmbDrawString(XtDisplay(w), XtWindow(w), tip->tip.fontset,
+ gc, tip->tip.internal_width, ksy, label,
+ (int)(nl - label));
+ ksy += ext->max_ink_extent.height;
+ label = nl + 1;
+ }
+ len = strlen(label);
+ if (len)
+ XmbDrawString(XtDisplay(w), XtWindow(w), tip->tip.fontset, gc,
+ tip->tip.internal_width, ksy, label, len);
+ }
+ else
+#endif
+ {
+ while ((nl = index(label, '\n')) != NULL) {
+ if (tip->tip.encoding)
+ XDrawString16(XtDisplay(w), XtWindow(w), gc,
+ tip->tip.internal_width, y,
+ (XChar2b*)label, (int)(nl - label) >> 1);
+ else
+ XDrawString(XtDisplay(w), XtWindow(w), gc,
+ tip->tip.internal_width, y,
+ label, (int)(nl - label));
+ y += tip->tip.font->max_bounds.ascent +
+ tip->tip.font->max_bounds.descent;
+ label = nl + 1;
+ }
+ len = strlen(label);
+ if (len) {
+ if (tip->tip.encoding)
+ XDrawString16(XtDisplay(w), XtWindow(w), gc,
+ tip->tip.internal_width, y,
+ (XChar2b*)label, len >> 1);
+ else
+ XDrawString(XtDisplay(w), XtWindow(w), gc,
+ tip->tip.internal_width, y, label, len);
+ }
+ }
+}
+
+/*ARGSUSED*/
+static Boolean
+XawTipSetValues(current, request, cnew, args, num_args)
+Widget current, request, cnew;
+ArgList args;
+Cardinal *num_args;
+{
+ TipWidget curtip = (TipWidget)current;
+ TipWidget newtip = (TipWidget)cnew;
+ Boolean redisplay = False;
+
+ if (curtip->tip.font->fid != newtip->tip.font->fid ||
+ curtip->tip.foreground != newtip->tip.foreground) {
+ XGCValues values;
+
+ values.foreground = newtip->tip.foreground;
+ values.background = newtip->core.background_pixel;
+ values.font = newtip->tip.font->fid;
+ values.graphics_exposures = False;
+ XtReleaseGC(cnew, curtip->tip.gc);
+ newtip->tip.gc = XtAllocateGC(cnew, 0, GCForeground | GCBackground |
+ GCFont | GCGraphicsExposures, &values,
+ GCFont, 0);
+ redisplay = True;
+ }
+
+ return (redisplay);
+}
+
+static void
+TipLayout(info)
+XawTipInfo *info;
+{
+ XFontStruct *fs = info->tip->tip.font;
+ int width = 0, height;
+ char *nl, *label = info->tip->tip.label;
+
+#ifdef XAW_INTERNATIONALIZATION
+ if (info->tip->tip.international == True) {
+ XFontSet fset = info->tip->tip.fontset;
+ XFontSetExtents *ext = XExtentsOfFontSet(fset);
+
+ height = ext->max_ink_extent.height;
+ if ((nl = index(label, '\n')) != NULL) {
+ /*CONSTCOND*/
+ while (True) {
+ int w = XmbTextEscapement(fset, label, (int)(nl - label));
+
+ if (w > width)
+ width = w;
+ if (*nl == '\0')
+ break;
+ label = nl + 1;
+ if (*label)
+ height += ext->max_ink_extent.height;
+ if ((nl = index(label, '\n')) == NULL)
+ nl = index(label, '\0');
+ }
+ }
+ else
+ width = XmbTextEscapement(fset, label, strlen(label));
+ }
+ else
+#endif
+ {
+ height = fs->max_bounds.ascent + fs->max_bounds.descent;
+ if ((nl = index(label, '\n')) != NULL) {
+ /*CONSTCOND*/
+ while (True) {
+ int w = info->tip->tip.encoding ?
+ XTextWidth16(fs, (XChar2b*)label,
+ (int)(nl - label) >> 1) :
+ XTextWidth(fs, label, (int)(nl - label));
+
+ if (w > width)
+ width = w;
+ if (*nl == '\0')
+ break;
+ label = nl + 1;
+ if (*label)
+ height += fs->max_bounds.ascent + fs->max_bounds.descent;
+ if ((nl = index(label, '\n')) == NULL)
+ nl = index(label, '\0');
+ }
+ }
+ else
+ width = info->tip->tip.encoding ?
+ XTextWidth16(fs, (XChar2b*)label, strlen(label) >> 1) :
+ XTextWidth(fs, label, strlen(label));
+ }
+ XtWidth(info->tip) = width + info->tip->tip.internal_width * 2;
+ XtHeight(info->tip) = height + info->tip->tip.internal_height * 2;
+}
+
+#define DEFAULT_TIP_OFFSET 12
+
+static void
+TipPosition(info)
+XawTipInfo *info;
+{
+ Window r, c;
+ int rx, ry, wx, wy;
+ unsigned mask;
+ Position x, y;
+ int bw2 = XtBorderWidth(info->tip) * 2;
+ int scr_width = WidthOfScreen(XtScreen(info->tip));
+ int scr_height = HeightOfScreen(XtScreen(info->tip));
+ int win_width = XtWidth(info->tip) + bw2;
+ int win_height = XtHeight(info->tip) + bw2;
+
+ XQueryPointer(XtDisplay((Widget)info->tip), XtWindow((Widget)info->tip),
+ &r, &c, &rx, &ry, &wx, &wy, &mask);
+ x = rx + DEFAULT_TIP_OFFSET;
+ y = ry + DEFAULT_TIP_OFFSET;
+
+ if (x + win_width > scr_width)
+ x = scr_width - win_width;
+ if (x < 0)
+ x = 0;
+
+ if (y + win_height > scr_height)
+ y -= win_height + (DEFAULT_TIP_OFFSET << 1);
+ if (y < 0)
+ y = 0;
+
+ XMoveResizeWindow(XtDisplay(info->tip), XtWindow(info->tip),
+ (int)(XtX(info->tip) = x), (int)(XtY(info->tip) = y),
+ (unsigned)XtWidth(info->tip),
+ (unsigned)XtHeight(info->tip));
+}
+
+static WidgetInfo *
+CreateWidgetInfo(w)
+Widget w;
+{
+ WidgetInfo *winfo = XtNew(WidgetInfo);
+
+ winfo->widget = w;
+ winfo->label = NULL;
+ winfo->next = NULL;
+
+ return (winfo);
+}
+
+static WidgetInfo *
+FindWidgetInfo(info, w)
+XawTipInfo *info;
+Widget w;
+{
+ WidgetInfo *winfo, *wlist = info->widgets;
+
+ if (wlist == NULL)
+ return (info->widgets = CreateWidgetInfo(w));
+
+ for (winfo = wlist; wlist; winfo = wlist, wlist = wlist->next)
+ if (wlist->widget == w)
+ return (wlist);
+
+ return (winfo->next = CreateWidgetInfo(w));
+}
+
+static XawTipInfo *
+CreateTipInfo(w)
+Widget w;
+{
+ XawTipInfo *info = XtNew(XawTipInfo);
+ Widget shell = w;
+
+ while (XtParent(shell))
+ shell = XtParent(shell);
+
+ info->tip = (TipWidget)XtCreateWidget("tip", tipWidgetClass,
+ shell, NULL, 0);
+ XtRealizeWidget((Widget)info->tip);
+ info->screen = XtScreen(w);
+ info->mapped = False;
+ info->widgets = NULL;
+ info->next = NULL;
+ XtAddEventHandler(shell, KeyPressMask, False, TipShellEventHandler,
+ (XtPointer)NULL);
+
+ return (info);
+}
+
+static XawTipInfo *
+FindTipInfo(w)
+Widget w;
+{
+ XawTipInfo *info, *list = TipInfoList;
+ Screen *screen;
+
+ if (list == NULL)
+ return (TipInfoList = CreateTipInfo(w));
+
+ screen = XtScreen(w);
+ for (info = list; list; info = list, list = list->next)
+ if (list->screen == screen)
+ return (list);
+
+ return (info->next = CreateTipInfo(w));
+}
+
+static void
+ResetTip(info, winfo, add_timeout)
+XawTipInfo *info;
+WidgetInfo *winfo;
+Bool add_timeout;
+{
+ if (info->tip->tip.timer) {
+ XtRemoveTimeOut(info->tip->tip.timer);
+ info->tip->tip.timer = 0;
+ }
+ if (info->mapped) {
+ XtRemoveGrab(XtParent((Widget)info->tip));
+ XUnmapWindow(XtDisplay((Widget)info->tip), XtWindow((Widget)info->tip));
+ info->mapped = False;
+ }
+ if (add_timeout) {
+ TimeoutData.info = info;
+ TimeoutData.winfo = winfo;
+ info->tip->tip.timer =
+ XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)info->tip),
+ info->tip->tip.timeout, TipTimeoutCallback,
+ (XtPointer)&TimeoutData);
+ }
+}
+
+static void
+TipTimeoutCallback(closure, id)
+XtPointer closure;
+XtIntervalId *id;
+{
+ TimeoutInfo *cinfo = (TimeoutInfo *)closure;
+ XawTipInfo *info = cinfo->info;
+ WidgetInfo *winfo = cinfo->winfo;
+ Arg args[2];
+
+ info->tip->tip.label = winfo->label;
+ info->tip->tip.encoding = 0;
+ XtSetArg(args[0], XtNencoding, &info->tip->tip.encoding);
+#ifdef XAW_INTERNATIONALIZATION
+ info->tip->tip.international = False;
+ XtSetArg(args[1], XtNinternational, &info->tip->tip.international);
+#endif
+ XtGetValues(winfo->widget, args, 2);
+
+ TipLayout(info);
+ TipPosition(info);
+ XMapRaised(XtDisplay((Widget)info->tip), XtWindow((Widget)info->tip));
+ XtAddGrab(XtParent((Widget)info->tip), True, True);
+ info->mapped = True;
+}
+
+/*ARGSUSED*/
+static void
+TipShellEventHandler(w, client_data, event, continue_to_dispatch)
+Widget w;
+XtPointer client_data;
+XEvent *event;
+Boolean *continue_to_dispatch;
+{
+ XawTipInfo *info = FindTipInfo(w);
+
+ ResetTip(info, FindWidgetInfo(info, w), False);
+}
+
+/*ARGSUSED*/
+static void
+TipEventHandler(w, client_data, event, continue_to_dispatch)
+Widget w;
+XtPointer client_data;
+XEvent *event;
+Boolean *continue_to_dispatch;
+{
+ XawTipInfo *info = FindTipInfo(w);
+ Boolean add_timeout;
+
+ switch (event->type) {
+ case EnterNotify:
+ add_timeout = True;
+ break;
+ case MotionNotify:
+ /* If any button is pressed, timer is 0 */
+ if (info->mapped)
+ return;
+ add_timeout = info->tip->tip.timer != 0;
+ break;
+ default:
+ add_timeout = False;
+ break;
+ }
+ ResetTip(info, FindWidgetInfo(info, w), add_timeout);
+}
+
+/*
+ * Public routines
+ */
+void
+XawTipEnable(w, label)
+Widget w;
+String label;
+{
+ if (XtIsWidget(w) && label && *label) {
+ XawTipInfo *info = FindTipInfo(w);
+ WidgetInfo *winfo = FindWidgetInfo(info, w);
+
+ if (winfo->label)
+ XtFree((char *)winfo->label);
+ winfo->label = XtNewString(label);
+
+ XtAddEventHandler(w, TIP_EVENT_MASK, False, TipEventHandler,
+ (XtPointer)NULL);
+ }
+}
+
+void
+XawTipDisable(w)
+Widget w;
+{
+ if (XtIsWidget(w)) {
+ XawTipInfo *info = FindTipInfo(w);
+
+ XtRemoveEventHandler(w, TIP_EVENT_MASK, False, TipEventHandler,
+ (XtPointer)NULL);
+ ResetTip(info, FindWidgetInfo(info, w), False);
+ }
+}
diff --git a/src/Tip.h b/src/Tip.h
new file mode 100644
index 0000000..f576fd7
--- /dev/null
+++ b/src/Tip.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 1999 by The XFree86 Project, Inc.
+ *
+ * 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 XFREE86 PROJECT 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 XFree86 Project 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
+ * XFree86 Project.
+ *
+ * Author: Paulo César Pereira de Andrade
+ */
+
+/* $XFree86: xc/lib/Xaw/Tip.h,v 1.1 1999/06/27 14:07:35 dawes Exp $ */
+
+#ifndef _XawTip_h
+#define _XawTip_h
+
+/*
+ * Tip Widget
+ */
+
+#include "Xaw3dP.h"
+#include <X11/Xaw3d/Simple.h>
+
+/* Resources:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ background Background Pixel XtDefaultBackground
+ backgroundPixmap BackgroundPixmap Pixmap XtUnspecifiedPixmap
+ border BorderColor Pixel XtDefaultForeground
+ borderWidth BorderWidth Dimension 1
+ destroyCallback Callback XtCallbackList NULL
+ font Font XFontStruct* XtDefaultFont
+ foreground Foreground Pixel XtDefaultForeground
+ height Height Dimension text height
+ internalHeight Height Dimension 2
+ internalWidth Width Dimension 2
+ label Label String NULL
+ timeout Timeout Int 500
+ width Width Dimension text width
+ x Position Position 0
+ y Position Position 0
+
+*/
+
+typedef struct _TipClassRec *TipWidgetClass;
+typedef struct _TipRec *TipWidget;
+
+extern WidgetClass tipWidgetClass;
+
+#define XawTextEncoding8bit 0
+#define XawTextEncodingChar2b 1
+
+#define XtNencoding "encoding"
+#define XtNtimeout "timeout"
+#define XtNtip "tip"
+
+#ifdef XAW_INTERNATIONALIZATION
+#ifndef XtNfontSet
+#define XtNfontSet "fontSet"
+#endif
+#ifndef XtCFontSet
+#define XtCFontSet "FontSet"
+#endif
+#endif
+
+#define XtCEncoding "Encoding"
+#define XtCTimeout "Timeout"
+#define XtCTip "Tip"
+
+#ifndef _XtStringDefs_h_
+#define XtNforeground "foreground"
+#define XtNlabel "label"
+#define XtNfont "font"
+#define XtNinternalWidth "internalWidth"
+#define XtNinternalHeight "internalHeight"
+#endif
+
+/*
+ * Public Functions
+ */
+
+/*
+ * Function:
+ * XawTipEnable
+ *
+ * Parameters:
+ * Widget - widget for tooltip
+ * String - tooltip label
+ *
+ * Description:
+ * Enables the tip event handler for this widget.
+ */
+void XawTipEnable(
+#if NeedFunctionPrototypes
+ Widget,
+ String
+#endif
+);
+
+/*
+ * Function:
+ * XawTipDisable
+ *
+ * Parameters:
+ * Widget - widget for tooltip
+ *
+ * Description:
+ * Disables the tip event handler for this widget.
+ */
+void XawTipDisable(
+#if NeedFunctionPrototypes
+ Widget
+#endif
+);
+
+#endif /* _XawTip_h */
diff --git a/src/TipP.h b/src/TipP.h
new file mode 100644
index 0000000..a4430d7
--- /dev/null
+++ b/src/TipP.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 1999 by The XFree86 Project, Inc.
+ *
+ * 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 XFREE86 PROJECT 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 XFree86 Project 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
+ * XFree86 Project.
+ *
+ * Author: Paulo César Pereira de Andrade
+ */
+
+/* $XFree86: xc/lib/Xaw/TipP.h,v 1.1 1999/06/27 14:07:35 dawes Exp $ */
+
+#ifndef _XawTipP_h
+#define _XawTipP_h
+
+#include "Xaw3dP.h"
+#include <X11/Xaw3d/Tip.h>
+
+typedef struct {
+ XtPointer extension;
+} TipClassPart;
+
+typedef struct _TipClassRec {
+ CoreClassPart core_class;
+ TipClassPart tip_class;
+} TipClassRec;
+
+extern TipClassRec tipClassRec;
+
+typedef struct _TipPart {
+ /* resources */
+ Pixel foreground;
+ XFontStruct *font;
+#ifdef XAW_INTERNATIONALIZATION
+ XFontSet fontset;
+#endif
+ Dimension internal_width;
+ Dimension internal_height;
+ String label;
+ int backing_store;
+ int timeout;
+
+ /* private */
+ GC gc;
+ XtIntervalId timer;
+#ifdef XAW_INTERNATIONALIZATION
+ Boolean international;
+#endif
+ unsigned char encoding;
+} TipPart;
+
+typedef struct _TipRec {
+ CorePart core;
+ TipPart tip;
+} TipRec;
+
+#endif /* _XawTipP_h */
diff --git a/src/Toggle.c b/src/Toggle.c
new file mode 100644
index 0000000..66902c4
--- /dev/null
+++ b/src/Toggle.c
@@ -0,0 +1,619 @@
+/* $XConsortium: Toggle.c,v 1.28 94/04/17 20:13:17 kaleb Exp $ */
+
+/*
+
+Copyright (c) 1989, 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.
+
+ */
+
+/*
+ * Toggle.c - Toggle button widget
+ *
+ * Author: Chris D. Peterson
+ * MIT X Consortium
+ * kit@expo.lcs.mit.edu
+ *
+ * Date: January 12, 1989
+ *
+ */
+
+#include <stdio.h>
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xmu/Converters.h>
+#include <X11/Xmu/Misc.h>
+#include <X11/Xaw3d/ToggleP.h>
+
+/****************************************************************
+ *
+ * Full class record constant
+ *
+ ****************************************************************/
+
+/* Private Data */
+
+/*
+ * The order of toggle and notify are important, as the state has
+ * to be set when we call the notify proc.
+ */
+
+static char defaultTranslations[] =
+ "<EnterWindow>: highlight(Always) \n\
+ <LeaveWindow>: unhighlight() \n\
+ <Btn1Down>,<Btn1Up>: toggle() notify()";
+
+#define offset(field) XtOffsetOf(ToggleRec, field)
+
+static XtResource resources[] = {
+ {XtNstate, XtCState, XtRBoolean, sizeof(Boolean),
+ offset(command.set), XtRString, "off"},
+ {XtNradioGroup, XtCWidget, XtRWidget, sizeof(Widget),
+ offset(toggle.widget), XtRWidget, (XtPointer) NULL },
+ {XtNradioData, XtCRadioData, XtRPointer, sizeof(XtPointer),
+ offset(toggle.radio_data), XtRPointer, (XtPointer) NULL },
+};
+
+#undef offset
+
+
+static void Toggle(), Initialize(), Notify(), ToggleSet();
+static void ToggleDestroy(), ClassInit();
+static Boolean SetValues();
+
+/* Functions for handling the Radio Group. */
+
+static RadioGroup * GetRadioGroup();
+static void CreateRadioGroup(), AddToRadioGroup(), TurnOffRadioSiblings();
+static void RemoveFromRadioGroup();
+
+static XtActionsRec actionsList[] =
+{
+ {"toggle", Toggle},
+ {"notify", Notify},
+ {"set", ToggleSet},
+};
+
+#define SuperClass ((CommandWidgetClass)&commandClassRec)
+
+ToggleClassRec toggleClassRec = {
+ {
+ (WidgetClass) SuperClass, /* superclass */
+ "Toggle", /* class_name */
+ sizeof(ToggleRec), /* size */
+ ClassInit, /* class_initialize */
+ NULL, /* class_part_initialize */
+ FALSE, /* class_inited */
+ Initialize, /* initialize */
+ NULL, /* initialize_hook */
+ XtInheritRealize, /* realize */
+ actionsList, /* actions */
+ XtNumber(actionsList), /* num_actions */
+ resources, /* resources */
+ XtNumber(resources), /* resource_count */
+ NULLQUARK, /* xrm_class */
+ FALSE, /* compress_motion */
+ TRUE, /* compress_exposure */
+ TRUE, /* compress_enterleave */
+ FALSE, /* visible_interest */
+ NULL, /* destroy */
+ XtInheritResize, /* resize */
+ XtInheritExpose, /* expose */
+ SetValues, /* set_values */
+ NULL, /* set_values_hook */
+ XtInheritSetValuesAlmost, /* set_values_almost */
+ NULL, /* get_values_hook */
+ NULL, /* accept_focus */
+ XtVersion, /* version */
+ NULL, /* callback_private */
+ defaultTranslations, /* tm_table */
+ XtInheritQueryGeometry, /* query_geometry */
+ XtInheritDisplayAccelerator, /* display_accelerator */
+ NULL /* extension */
+ }, /* CoreClass fields initialization */
+ {
+ XtInheritChangeSensitive /* change_sensitive */
+ }, /* SimpleClass fields initialization */
+ {
+ XtInheritXaw3dShadowDraw /* shadowdraw */
+ }, /* ThreeDClass fields initialization */
+ {
+ 0 /* field not used */
+ }, /* LabelClass fields initialization */
+ {
+ 0 /* field not used */
+ }, /* CommandClass fields initialization */
+ {
+ NULL, /* Set Procedure. */
+ NULL, /* Unset Procedure. */
+ NULL /* extension. */
+ } /* ToggleClass fields initialization */
+};
+
+ /* for public consumption */
+WidgetClass toggleWidgetClass = (WidgetClass) &toggleClassRec;
+
+/****************************************************************
+ *
+ * Private Procedures
+ *
+ ****************************************************************/
+
+static void
+ClassInit()
+{
+ XtActionList actions;
+ Cardinal num_actions;
+ Cardinal i;
+ ToggleWidgetClass class = (ToggleWidgetClass) toggleWidgetClass;
+ static XtConvertArgRec parentCvtArgs[] = {
+ {XtBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.parent),
+ sizeof(Widget)}
+ };
+
+ XawInitializeWidgetSet();
+ XtSetTypeConverter(XtRString, XtRWidget, XmuNewCvtStringToWidget,
+ parentCvtArgs, XtNumber(parentCvtArgs), XtCacheNone,
+ (XtDestructor)NULL);
+/*
+ * Find the set and unset actions in the command widget's action table.
+ */
+
+ XtGetActionList(commandWidgetClass, &actions, &num_actions);
+
+ for (i = 0 ; i < num_actions ; i++) {
+ if (streq(actions[i].string, "set"))
+ class->toggle_class.Set = actions[i].proc;
+ if (streq(actions[i].string, "unset"))
+ class->toggle_class.Unset = actions[i].proc;
+
+ if ( (class->toggle_class.Set != NULL) &&
+ (class->toggle_class.Unset != NULL) ) {
+ XtFree((char *) actions);
+ return;
+ }
+ }
+
+/* We should never get here. */
+ XtError("Aborting, due to errors resolving bindings in the Toggle widget.");
+}
+
+/*ARGSUSED*/
+static void Initialize(request, new, args, num_args)
+ Widget request, new;
+ ArgList args;
+ Cardinal *num_args;
+{
+ ToggleWidget tw = (ToggleWidget) new;
+ ToggleWidget tw_req = (ToggleWidget) request;
+
+ tw->toggle.radio_group = NULL;
+
+ if (tw->toggle.radio_data == NULL)
+ tw->toggle.radio_data = (XtPointer) new->core.name;
+
+ if (tw->toggle.widget != NULL) {
+ if ( GetRadioGroup(tw->toggle.widget) == NULL)
+ CreateRadioGroup(new, tw->toggle.widget);
+ else
+ AddToRadioGroup( GetRadioGroup(tw->toggle.widget), new);
+ }
+ XtAddCallback(new, XtNdestroyCallback, ToggleDestroy, (XtPointer)NULL);
+
+/*
+ * Command widget assumes that the widget is unset, so we only
+ * have to handle the case where it needs to be set.
+ *
+ * If this widget is in a radio group then it may cause another
+ * widget to be unset, thus calling the notify proceedure.
+ *
+ * I want to set the toggle if the user set the state to "On" in
+ * the resource group, reguardless of what my ancestors did.
+ */
+
+ if (tw_req->command.set)
+ ToggleSet(new, (XEvent *)NULL, (String *)NULL, (Cardinal *)0);
+}
+
+/************************************************************
+ *
+ * Action Procedures
+ *
+ ************************************************************/
+
+/* ARGSUSED */
+static void
+ToggleSet(w,event,params,num_params)
+Widget w;
+XEvent *event;
+String *params; /* unused */
+Cardinal *num_params; /* unused */
+{
+ ToggleWidgetClass class = (ToggleWidgetClass) w->core.widget_class;
+
+ TurnOffRadioSiblings(w);
+ class->toggle_class.Set(w, event, NULL, 0);
+}
+
+/* ARGSUSED */
+static void
+Toggle(w,event,params,num_params)
+Widget w;
+XEvent *event;
+String *params; /* unused */
+Cardinal *num_params; /* unused */
+{
+ ToggleWidget tw = (ToggleWidget)w;
+ ToggleWidgetClass class = (ToggleWidgetClass) w->core.widget_class;
+
+ if (tw->command.set)
+ class->toggle_class.Unset(w, event, NULL, 0);
+ else
+ ToggleSet(w, event, params, num_params);
+}
+
+/* ARGSUSED */
+static void Notify(w,event,params,num_params)
+Widget w;
+XEvent *event;
+String *params; /* unused */
+Cardinal *num_params; /* unused */
+{
+ ToggleWidget tw = (ToggleWidget) w;
+ long antilint = tw->command.set;
+
+ XtCallCallbacks( w, XtNcallback, (XtPointer) antilint );
+}
+
+/************************************************************
+ *
+ * Set specified arguments into widget
+ *
+ ***********************************************************/
+
+/* ARGSUSED */
+static Boolean
+SetValues (current, request, new, args, num_args)
+Widget current, request, new;
+ArgList args;
+Cardinal *num_args;
+{
+ ToggleWidget oldtw = (ToggleWidget) current;
+ ToggleWidget tw = (ToggleWidget) new;
+ ToggleWidget rtw = (ToggleWidget) request;
+
+ if (oldtw->toggle.widget != tw->toggle.widget)
+ XawToggleChangeRadioGroup(new, tw->toggle.widget);
+
+ if (!tw->core.sensitive && oldtw->core.sensitive && rtw->command.set)
+ tw->command.set = True;
+
+ if (oldtw->command.set != tw->command.set) {
+ tw->command.set = oldtw->command.set;
+ Toggle(new, (XEvent *)NULL, (String *)NULL, (Cardinal *)0);
+ }
+ return(FALSE);
+}
+
+/* Function Name: ToggleDestroy
+ * Description: Destroy Callback for toggle widget.
+ * Arguments: w - the toggle widget that is being destroyed.
+ * junk, grabage - not used.
+ * Returns: none.
+ */
+
+/* ARGSUSED */
+static void
+ToggleDestroy(w, junk, garbage)
+Widget w;
+XtPointer junk, garbage;
+{
+ RemoveFromRadioGroup(w);
+}
+
+/************************************************************
+ *
+ * Below are all the private procedures that handle
+ * radio toggle buttons.
+ *
+ ************************************************************/
+
+/* Function Name: GetRadioGroup
+ * Description: Gets the radio group associated with a give toggle
+ * widget.
+ * Arguments: w - the toggle widget who's radio group we are getting.
+ * Returns: the radio group associated with this toggle group.
+ */
+
+static RadioGroup *
+GetRadioGroup(w)
+Widget w;
+{
+ ToggleWidget tw = (ToggleWidget) w;
+
+ if (tw == NULL) return(NULL);
+ return( tw->toggle.radio_group );
+}
+
+/* Function Name: CreateRadioGroup
+ * Description: Creates a radio group. give two widgets.
+ * Arguments: w1, w2 - the toggle widgets to add to the radio group.
+ * Returns: none.
+ *
+ * NOTE: A pointer to the group is added to each widget's radio_group
+ * field.
+ */
+
+static void
+CreateRadioGroup(w1, w2)
+Widget w1, w2;
+{
+ char error_buf[BUFSIZ];
+ ToggleWidget tw1 = (ToggleWidget) w1;
+ ToggleWidget tw2 = (ToggleWidget) w2;
+
+ if ( (tw1->toggle.radio_group != NULL) || (tw2->toggle.radio_group != NULL) ) {
+ (void) sprintf(error_buf, "%s %s", "Toggle Widget Error - Attempting",
+ "to create a new toggle group, when one already exists.");
+ XtWarning(error_buf);
+ }
+
+ AddToRadioGroup( (RadioGroup *)NULL, w1 );
+ AddToRadioGroup( GetRadioGroup(w1), w2 );
+}
+
+/* Function Name: AddToRadioGroup
+ * Description: Adds a toggle to the radio group.
+ * Arguments: group - any element of the radio group the we are adding to.
+ * w - the new toggle widget to add to the group.
+ * Returns: none.
+ */
+
+static void
+AddToRadioGroup(group, w)
+RadioGroup * group;
+Widget w;
+{
+ ToggleWidget tw = (ToggleWidget) w;
+ RadioGroup * local;
+
+ local = (RadioGroup *) XtMalloc( sizeof(RadioGroup) );
+ local->widget = w;
+ tw->toggle.radio_group = local;
+
+ if (group == NULL) { /* Creating new group. */
+ group = local;
+ group->next = NULL;
+ group->prev = NULL;
+ return;
+ }
+ local->prev = group; /* Adding to previous group. */
+ if ((local->next = group->next) != NULL)
+ local->next->prev = local;
+ group->next = local;
+}
+
+/* Function Name: TurnOffRadioSiblings
+ * Description: Deactivates all radio siblings.
+ * Arguments: widget - a toggle widget.
+ * Returns: none.
+ */
+
+static void
+TurnOffRadioSiblings(w)
+Widget w;
+{
+ RadioGroup * group;
+ ToggleWidgetClass class = (ToggleWidgetClass) w->core.widget_class;
+
+ if ( (group = GetRadioGroup(w)) == NULL) /* Punt if there is no group */
+ return;
+
+ /* Go to the top of the group. */
+
+ for ( ; group->prev != NULL ; group = group->prev );
+
+ while ( group != NULL ) {
+ ToggleWidget local_tog = (ToggleWidget) group->widget;
+ if ( local_tog->command.set ) {
+ class->toggle_class.Unset(group->widget, NULL, NULL, 0);
+ Notify( group->widget, (XEvent *)NULL, (String *)NULL, (Cardinal *)0);
+ }
+ group = group->next;
+ }
+}
+
+/* Function Name: RemoveFromRadioGroup
+ * Description: Removes a toggle from a RadioGroup.
+ * Arguments: w - the toggle widget to remove.
+ * Returns: none.
+ */
+
+static void
+RemoveFromRadioGroup(w)
+Widget w;
+{
+ RadioGroup * group = GetRadioGroup(w);
+ if (group != NULL) {
+ if (group->prev != NULL)
+ (group->prev)->next = group->next;
+ if (group->next != NULL)
+ (group->next)->prev = group->prev;
+ XtFree((char *) group);
+ }
+}
+
+/************************************************************
+ *
+ * Public Routines
+ *
+ ************************************************************/
+
+/* Function Name: XawToggleChangeRadioGroup
+ * Description: Allows a toggle widget to change radio groups.
+ * Arguments: w - The toggle widget to change groups.
+ * radio_group - any widget in the new group.
+ * Returns: none.
+ */
+
+void
+#if NeedFunctionPrototypes
+XawToggleChangeRadioGroup(Widget w, Widget radio_group)
+#else
+XawToggleChangeRadioGroup(w, radio_group)
+Widget w, radio_group;
+#endif
+{
+ ToggleWidget tw = (ToggleWidget) w;
+ RadioGroup * group;
+
+ RemoveFromRadioGroup(w);
+
+/*
+ * If the toggle that we are about to add is set then we will
+ * unset all toggles in the new radio group.
+ */
+
+ if ( tw->command.set && radio_group != NULL )
+ XawToggleUnsetCurrent(radio_group);
+
+ if (radio_group != NULL)
+ if ((group = GetRadioGroup(radio_group)) == NULL)
+ CreateRadioGroup(w, radio_group);
+ else AddToRadioGroup(group, w);
+}
+
+/* Function Name: XawToggleGetCurrent
+ * Description: Returns the RadioData associated with the toggle
+ * widget that is currently active in a toggle group.
+ * Arguments: w - any toggle widget in the toggle group.
+ * Returns: The XtNradioData associated with the toggle widget.
+ */
+
+XtPointer
+#if NeedFunctionPrototypes
+XawToggleGetCurrent(Widget w)
+#else
+XawToggleGetCurrent(w)
+Widget w;
+#endif
+{
+ RadioGroup * group;
+
+ if ( (group = GetRadioGroup(w)) == NULL) return(NULL);
+ for ( ; group->prev != NULL ; group = group->prev);
+
+ while ( group != NULL ) {
+ ToggleWidget local_tog = (ToggleWidget) group->widget;
+ if ( local_tog->command.set )
+ return( local_tog->toggle.radio_data );
+ group = group->next;
+ }
+ return(NULL);
+}
+
+/* Function Name: XawToggleSetCurrent
+ * Description: Sets the Toggle widget associated with the
+ * radio_data specified.
+ * Arguments: radio_group - any toggle widget in the toggle group.
+ * radio_data - radio data of the toggle widget to set.
+ * Returns: none.
+ */
+
+void
+#if NeedFunctionPrototypes
+XawToggleSetCurrent(Widget radio_group, XtPointer radio_data)
+#else
+XawToggleSetCurrent(radio_group, radio_data)
+Widget radio_group;
+XtPointer radio_data;
+#endif
+{
+ RadioGroup * group;
+ ToggleWidget local_tog;
+
+/* Special case of no radio group. */
+
+ if ( (group = GetRadioGroup(radio_group)) == NULL) {
+ local_tog = (ToggleWidget) radio_group;
+ if ( (local_tog->toggle.radio_data == radio_data) )
+ if (!local_tog->command.set) {
+ ToggleSet((Widget) local_tog, (XEvent *)NULL, (String *)NULL, (Cardinal *)0);
+ Notify((Widget) local_tog, (XEvent *)NULL, (String *)NULL, (Cardinal *)0);
+ }
+ return;
+ }
+
+/*
+ * find top of radio_roup
+ */
+
+ for ( ; group->prev != NULL ; group = group->prev);
+
+/*
+ * search for matching radio data.
+ */
+
+ while ( group != NULL ) {
+ local_tog = (ToggleWidget) group->widget;
+ if ( (local_tog->toggle.radio_data == radio_data) ) {
+ if (!local_tog->command.set) { /* if not already set. */
+ ToggleSet((Widget) local_tog, (XEvent *)NULL, (String *)NULL, (Cardinal *)0);
+ Notify((Widget) local_tog, (XEvent *)NULL, (String *)NULL, (Cardinal *)0);
+ }
+ return; /* found it, done */
+ }
+ group = group->next;
+ }
+}
+
+/* Function Name: XawToggleUnsetCurrent
+ * Description: Unsets all Toggles in the radio_group specified.
+ * Arguments: radio_group - any toggle widget in the toggle group.
+ * Returns: none.
+ */
+
+void
+#if NeedFunctionPrototypes
+XawToggleUnsetCurrent(Widget radio_group)
+#else
+XawToggleUnsetCurrent(radio_group)
+Widget radio_group;
+#endif
+{
+ ToggleWidgetClass class;
+ ToggleWidget local_tog = (ToggleWidget) radio_group;
+
+ /* Special Case no radio group. */
+
+ if (local_tog->command.set) {
+ class = (ToggleWidgetClass) local_tog->core.widget_class;
+ class->toggle_class.Unset(radio_group, NULL, NULL, 0);
+ Notify(radio_group, (XEvent *)NULL, (String *)NULL, (Cardinal *)0);
+ }
+ if ( GetRadioGroup(radio_group) == NULL) return;
+ TurnOffRadioSiblings(radio_group);
+}
+
diff --git a/src/Toggle.h b/src/Toggle.h
new file mode 100644
index 0000000..7083139
--- /dev/null
+++ b/src/Toggle.h
@@ -0,0 +1,177 @@
+/*
+ * $XConsortium: Toggle.h,v 1.16 94/04/17 20:13:19 kaleb Exp $
+ *
+Copyright (c) 1989, 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.
+ */
+
+/*
+ * ToggleP.h - Private definitions for Toggle widget
+ *
+ * Author: Chris D. Peterson
+ * MIT X Consortium
+ * kit@expo.lcs.mit.edu
+ *
+ * Date: January 12, 1989
+ */
+
+#ifndef _XawToggle_h
+#define _XawToggle_h
+
+/***********************************************************************
+ *
+ * Toggle Widget
+ *
+ ***********************************************************************/
+
+#include <X11/Xaw3d/Command.h>
+
+/* Resources:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ radioGroup RadioGroup Widget NULL +
+ radioData RadioData Pointer (XPointer) Widget ++
+ state State Boolean Off
+
+ background Background Pixel XtDefaultBackground
+ bitmap Pixmap Pixmap None
+ border BorderColor Pixel XtDefaultForeground
+ borderWidth BorderWidth Dimension 1
+ callback Callback Pointer NULL
+ cursor Cursor Cursor None
+ destroyCallback Callback Pointer NULL
+ font Font XFontStructx* XtDefaultFont
+ foreground Foreground Pixel XtDefaultForeground
+ height Height Dimension text height
+ highlightThickness Thickness Dimension 2
+ insensitiveBorder Insensitive Pixmap Gray
+ internalHeight Height Dimension 2
+ internalWidth Width Dimension 4
+ justify Justify XtJustify XtJustifyCenter
+ label Label String NULL
+ mappedWhenManaged MappedWhenManaged Boolean True
+ resize Resize Boolean True
+ sensitive Sensitive Boolean True
+ width Width Dimension text width
+ x Position Position 0
+ y Position Position 0
+
++ To use the toggle as a radio toggle button, set this resource to point to
+ any other widget in the radio group.
+
+++ This is the data returned from a call to XtToggleGetCurrent, by default
+ this is set to the name of toggle widget.
+
+*/
+
+/*
+ * These should be in StringDefs.h but aren't so we will define
+ * them here if they are needed.
+ */
+
+
+#define XtCWidget "Widget"
+#define XtCState "State"
+#define XtCRadioGroup "RadioGroup"
+#define XtCRadioData "RadioData"
+
+#ifndef _XtStringDefs_h_
+#define XtRWidget "Widget"
+#endif
+
+#define XtNstate "state"
+#define XtNradioGroup "radioGroup"
+#define XtNradioData "radioData"
+
+extern WidgetClass toggleWidgetClass;
+
+typedef struct _ToggleClassRec *ToggleWidgetClass;
+typedef struct _ToggleRec *ToggleWidget;
+
+
+/************************************************************
+ *
+ * Public Functions
+ *
+ ************************************************************/
+
+_XFUNCPROTOBEGIN
+
+/* Function Name: XawToggleChangeRadioGroup
+ * Description: Allows a toggle widget to change radio lists.
+ * Arguments: w - The toggle widget to change lists.
+ * radio_group - any widget in the new list.
+ * Returns: none.
+ */
+
+extern void XawToggleChangeRadioGroup(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ Widget /* radio_group */
+#endif
+);
+
+/* Function Name: XawToggleGetCurrent
+ * Description: Returns the RadioData associated with the toggle
+ * widget that is currently active in a toggle list.
+ * Arguments: radio_group - any toggle widget in the toggle list.
+ * Returns: The XtNradioData associated with the toggle widget.
+ */
+
+extern XtPointer XawToggleGetCurrent(
+#if NeedFunctionPrototypes
+ Widget /* radio_group */
+#endif
+);
+
+/* Function Name: XawToggleSetCurrent
+ * Description: Sets the Toggle widget associated with the
+ * radio_data specified.
+ * Arguments: radio_group - any toggle widget in the toggle list.
+ * radio_data - radio data of the toggle widget to set.
+ * Returns: none.
+ */
+
+extern void XawToggleSetCurrent(
+#if NeedFunctionPrototypes
+ Widget /* radio_group */,
+ XtPointer /* radio_data */
+#endif
+);
+
+/* Function Name: XawToggleUnsetCurrent
+ * Description: Unsets all Toggles in the radio_group specified.
+ * Arguments: radio_group - any toggle widget in the toggle list.
+ * Returns: none.
+ */
+
+extern void XawToggleUnsetCurrent(
+#if NeedFunctionPrototypes
+ Widget /* radio_group */
+#endif
+);
+
+_XFUNCPROTOEND
+
+#endif /* _XawToggle_h */
diff --git a/src/ToggleP.h b/src/ToggleP.h
new file mode 100644
index 0000000..0155ae4
--- /dev/null
+++ b/src/ToggleP.h
@@ -0,0 +1,113 @@
+/* $XConsortium: ToggleP.h,v 1.9 94/04/17 20:13:19 converse Exp $ */
+
+/*
+
+Copyright (c) 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.
+
+*/
+
+/*
+ * ToggleP.h - Private definitions for Toggle widget
+ *
+ * Author: Chris D. Peterson
+ * MIT X Consortium
+ * kit@expo.lcs.mit.edu
+ *
+ * Date: January 12, 1989
+ *
+ */
+
+#ifndef _XawToggleP_h
+#define _XawToggleP_h
+
+#include <X11/Xaw3d/Toggle.h>
+#include <X11/Xaw3d/CommandP.h>
+
+/***********************************************************************
+ *
+ * Toggle Widget Private Data
+ *
+ ***********************************************************************/
+
+#define streq(a, b) ( strcmp((a), (b)) == 0 )
+
+typedef struct _RadioGroup {
+ struct _RadioGroup *prev, *next; /* Pointers to other elements in group. */
+ Widget widget; /* Widget corrosponding to this element. */
+} RadioGroup;
+
+/************************************
+ *
+ * Class structure
+ *
+ ***********************************/
+
+ /* New fields for the Toggle widget class record */
+typedef struct _ToggleClass {
+ XtActionProc Set;
+ XtActionProc Unset;
+ XtPointer extension;
+} ToggleClassPart;
+
+ /* Full class record declaration */
+typedef struct _ToggleClassRec {
+ CoreClassPart core_class;
+ SimpleClassPart simple_class;
+ ThreeDClassPart threeD_class;
+ LabelClassPart label_class;
+ CommandClassPart command_class;
+ ToggleClassPart toggle_class;
+} ToggleClassRec;
+
+extern ToggleClassRec toggleClassRec;
+
+/***************************************
+ *
+ * Instance (widget) structure
+ *
+ **************************************/
+
+ /* New fields for the Toggle widget record */
+typedef struct {
+ /* resources */
+ Widget widget;
+ XtPointer radio_data;
+
+ /* private data */
+ RadioGroup * radio_group;
+} TogglePart;
+
+ /* Full widget declaration */
+typedef struct _ToggleRec {
+ CorePart core;
+ SimplePart simple;
+ ThreeDPart threeD;
+ LabelPart label;
+ CommandPart command;
+ TogglePart toggle;
+} ToggleRec;
+
+#endif /* _XawToggleP_h */
+
+
diff --git a/src/Tree.c b/src/Tree.c
new file mode 100644
index 0000000..94b8d70
--- /dev/null
+++ b/src/Tree.c
@@ -0,0 +1,1008 @@
+/*
+ * $XConsortium: Tree.c,v 1.45 94/04/17 20:13:20 kaleb Exp $
+ *
+
+Copyright (c) 1990, 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 1989 Prentice Hall
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation.
+ *
+ * Prentice Hall and the authors disclaim all warranties with regard
+ * to this software, including all implied warranties of merchantability and
+ * fitness. In no event shall Prentice Hall or the authors be liable
+ * for any special, indirect or cosequential 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.
+ *
+ * Authors: Jim Fulton, MIT X Consortium,
+ * based on a version by Douglas Young, Prentice Hall
+ *
+ * This widget is based on the Tree widget described on pages 397-419 of
+ * Douglas Young's book "The X Window System, Programming and Applications
+ * with Xt OSF/Motif Edition." The layout code has been rewritten to use
+ * additional blank space to make the structure of the graph easier to see
+ * as well as to support vertical trees.
+ */
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xaw3d/Cardinals.h>
+#include <X11/Xaw3d/TreeP.h>
+
+#define IsHorizontal(tw) ((tw)->tree.gravity == WestGravity || \
+ (tw)->tree.gravity == EastGravity)
+
+
+ /* widget class method */
+static void ClassInitialize();
+static void Initialize();
+static void ConstraintInitialize();
+static void ConstraintDestroy();
+static Boolean ConstraintSetValues();
+static void Destroy();
+static Boolean SetValues();
+static XtGeometryResult GeometryManager();
+static void ChangeManaged();
+static void Redisplay();
+static XtGeometryResult QueryGeometry();
+
+ /* utility routines */
+static void insert_node();
+static void delete_node();
+static void layout_tree();
+
+
+/*
+ * resources of the tree itself
+ */
+static XtResource resources[] = {
+ { XtNautoReconfigure, XtCAutoReconfigure, XtRBoolean, sizeof (Boolean),
+ XtOffsetOf(TreeRec, tree.auto_reconfigure), XtRImmediate,
+ (XtPointer) FALSE },
+ { XtNhSpace, XtCHSpace, XtRDimension, sizeof (Dimension),
+ XtOffsetOf(TreeRec, tree.hpad), XtRImmediate, (XtPointer) 0 },
+ { XtNvSpace, XtCVSpace, XtRDimension, sizeof (Dimension),
+ XtOffsetOf(TreeRec, tree.vpad), XtRImmediate, (XtPointer) 0 },
+ { XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel),
+ XtOffsetOf(TreeRec, tree.foreground), XtRString,
+ XtDefaultForeground},
+ { XtNlineWidth, XtCLineWidth, XtRDimension, sizeof (Dimension),
+ XtOffsetOf(TreeRec, tree.line_width), XtRImmediate, (XtPointer) 0 },
+ { XtNgravity, XtCGravity, XtRGravity, sizeof (XtGravity),
+ XtOffsetOf(TreeRec, tree.gravity), XtRImmediate,
+ (XtPointer) WestGravity },
+};
+
+
+/*
+ * resources that are attached to all children of the tree
+ */
+static XtResource treeConstraintResources[] = {
+ { XtNtreeParent, XtCTreeParent, XtRWidget, sizeof (Widget),
+ XtOffsetOf(TreeConstraintsRec, tree.parent), XtRImmediate, NULL },
+ { XtNtreeGC, XtCTreeGC, XtRGC, sizeof(GC),
+ XtOffsetOf(TreeConstraintsRec, tree.gc), XtRImmediate, NULL },
+};
+
+
+TreeClassRec treeClassRec = {
+ {
+ /* core_class fields */
+ (WidgetClass) &constraintClassRec, /* superclass */
+ "Tree", /* class_name */
+ sizeof(TreeRec), /* widget_size */
+ ClassInitialize, /* class_init */
+ NULL, /* class_part_init */
+ FALSE, /* class_inited */
+ Initialize, /* initialize */
+ NULL, /* initialize_hook */
+ XtInheritRealize, /* realize */
+ NULL, /* actions */
+ 0, /* num_actions */
+ resources, /* resources */
+ XtNumber(resources), /* num_resources */
+ NULLQUARK, /* xrm_class */
+ TRUE, /* compress_motion */
+ TRUE, /* compress_exposure */
+ TRUE, /* compress_enterleave*/
+ TRUE, /* visible_interest */
+ Destroy, /* destroy */
+ NULL, /* resize */
+ Redisplay, /* expose */
+ SetValues, /* set_values */
+ NULL, /* set_values_hook */
+ XtInheritSetValuesAlmost, /* set_values_almost */
+ NULL, /* get_values_hook */
+ NULL, /* accept_focus */
+ XtVersion, /* version */
+ NULL, /* callback_private */
+ NULL, /* tm_table */
+ QueryGeometry, /* query_geometry */
+ NULL, /* display_accelerator*/
+ NULL, /* extension */
+ },
+ {
+ /* composite_class fields */
+ GeometryManager, /* geometry_manager */
+ ChangeManaged, /* change_managed */
+ XtInheritInsertChild, /* insert_child */
+ XtInheritDeleteChild, /* delete_child */
+ NULL, /* extension */
+ },
+ {
+ /* constraint_class fields */
+ treeConstraintResources, /* subresources */
+ XtNumber(treeConstraintResources), /* subresource_count */
+ sizeof(TreeConstraintsRec), /* constraint_size */
+ ConstraintInitialize, /* initialize */
+ ConstraintDestroy, /* destroy */
+ ConstraintSetValues, /* set_values */
+ NULL, /* extension */
+ },
+ {
+ /* Tree class fields */
+ 0, /* ignore */
+ }
+};
+
+WidgetClass treeWidgetClass = (WidgetClass) &treeClassRec;
+
+
+/*****************************************************************************
+ * *
+ * tree utility routines *
+ * *
+ *****************************************************************************/
+
+static void initialize_dimensions (listp, sizep, n)
+ Dimension **listp;
+ int *sizep;
+ int n;
+{
+ int i;
+ Dimension *l;
+
+ if (!*listp) {
+ *listp = (Dimension *) XtCalloc ((unsigned int) n,
+ (unsigned int) sizeof(Dimension));
+ *sizep = ((*listp) ? n : 0);
+ return;
+ }
+ if (n > *sizep) {
+ *listp = (Dimension *) XtRealloc((char *) *listp,
+ (unsigned int) (n*sizeof(Dimension)));
+ if (!*listp) {
+ *sizep = 0;
+ return;
+ }
+ for (i = *sizep, l = (*listp) + i; i < n; i++, l++) *l = 0;
+ *sizep = n;
+ }
+ return;
+}
+
+static GC get_tree_gc (w)
+ TreeWidget w;
+{
+ XtGCMask valuemask = GCBackground | GCForeground;
+ XGCValues values;
+
+ values.background = w->core.background_pixel;
+ values.foreground = w->tree.foreground;
+ if (w->tree.line_width != 0) {
+ valuemask |= GCLineWidth;
+ values.line_width = w->tree.line_width;
+ }
+
+ return XtGetGC ((Widget) w, valuemask, &values);
+}
+
+static void insert_node (parent, node)
+ Widget parent, node;
+{
+ TreeConstraints pc;
+ TreeConstraints nc = TREE_CONSTRAINT(node);
+ int nindex;
+
+ nc->tree.parent = parent;
+
+ if (parent == NULL) return;
+
+ /*
+ * If there isn't more room in the children array,
+ * allocate additional space.
+ */
+ pc = TREE_CONSTRAINT(parent);
+ nindex = pc->tree.n_children;
+
+ if (pc->tree.n_children == pc->tree.max_children) {
+ pc->tree.max_children += (pc->tree.max_children / 2) + 2;
+ pc->tree.children = (WidgetList) XtRealloc ((char *)pc->tree.children,
+ (unsigned int)
+ ((pc->tree.max_children) *
+ sizeof(Widget)));
+ }
+
+ /*
+ * Add the sub_node in the next available slot and
+ * increment the counter.
+ */
+ pc->tree.children[nindex] = node;
+ pc->tree.n_children++;
+}
+
+static void delete_node (parent, node)
+ Widget parent, node;
+{
+ TreeConstraints pc;
+ int pos, i;
+
+ /*
+ * Make sure the parent exists.
+ */
+ if (!parent) return;
+
+ pc = TREE_CONSTRAINT(parent);
+
+ /*
+ * Find the sub_node on its parent's list.
+ */
+ for (pos = 0; pos < pc->tree.n_children; pos++)
+ if (pc->tree.children[pos] == node) break;
+
+ if (pos == pc->tree.n_children) return;
+
+ /*
+ * Decrement the number of children
+ */
+ pc->tree.n_children--;
+
+ /*
+ * Fill in the gap left by the sub_node.
+ * Zero the last slot for good luck.
+ */
+ for (i = pos; i < pc->tree.n_children; i++)
+ pc->tree.children[i] = pc->tree.children[i+1];
+
+ pc->tree.children[pc->tree.n_children]=0;
+}
+
+static void check_gravity (tw, grav)
+ TreeWidget tw;
+ XtGravity grav;
+{
+ switch (tw->tree.gravity) {
+ case WestGravity: case NorthGravity: case EastGravity: case SouthGravity:
+ break;
+ default:
+ tw->tree.gravity = grav;
+ break;
+ }
+}
+
+
+/*****************************************************************************
+ * *
+ * tree class methods *
+ * *
+ *****************************************************************************/
+
+static void ClassInitialize ()
+{
+ XawInitializeWidgetSet();
+ XtAddConverter (XtRString, XtRGravity, XmuCvtStringToGravity,
+ (XtConvertArgList) NULL, (Cardinal) 0);
+}
+
+
+/*ARGSUSED*/
+static void Initialize (grequest, gnew, args, num_args)
+ Widget grequest, gnew;
+ ArgList args;
+ Cardinal *num_args;
+{
+ TreeWidget request = (TreeWidget) grequest, new = (TreeWidget) gnew;
+ Arg arglist[2];
+
+ /*
+ * Make sure the widget's width and height are
+ * greater than zero.
+ */
+ if (request->core.width <= 0) new->core.width = 5;
+ if (request->core.height <= 0) new->core.height = 5;
+
+ /*
+ * Set the padding according to the orientation
+ */
+ if (request->tree.hpad == 0 && request->tree.vpad == 0) {
+ if (IsHorizontal (request)) {
+ new->tree.hpad = TREE_HORIZONTAL_DEFAULT_SPACING;
+ new->tree.vpad = TREE_VERTICAL_DEFAULT_SPACING;
+ } else {
+ new->tree.hpad = TREE_VERTICAL_DEFAULT_SPACING;
+ new->tree.vpad = TREE_HORIZONTAL_DEFAULT_SPACING;
+ }
+ }
+
+ /*
+ * Create a graphics context for the connecting lines.
+ */
+ new->tree.gc = get_tree_gc (new);
+
+ /*
+ * Create the hidden root widget.
+ */
+ new->tree.tree_root = (Widget) NULL;
+ XtSetArg(arglist[0], XtNwidth, 1);
+ XtSetArg(arglist[1], XtNheight, 1);
+ new->tree.tree_root = XtCreateWidget ("root", widgetClass, gnew,
+ arglist,TWO);
+
+ /*
+ * Allocate the array used to hold the widest values per depth
+ */
+ new->tree.largest = NULL;
+ new->tree.n_largest = 0;
+ initialize_dimensions (&new->tree.largest, &new->tree.n_largest,
+ TREE_INITIAL_DEPTH);
+
+ /*
+ * make sure that our gravity is one of the acceptable values
+ */
+ check_gravity (new, WestGravity);
+}
+
+
+/* ARGSUSED */
+static void ConstraintInitialize (request, new, args, num_args)
+ Widget request, new;
+ ArgList args;
+ Cardinal *num_args;
+{
+ TreeConstraints tc = TREE_CONSTRAINT(new);
+ TreeWidget tw = (TreeWidget) new->core.parent;
+
+ /*
+ * Initialize the widget to have no sub-nodes.
+ */
+ tc->tree.n_children = 0;
+ tc->tree.max_children = 0;
+ tc->tree.children = (Widget *) NULL;
+ tc->tree.x = tc->tree.y = 0;
+ tc->tree.bbsubwidth = 0;
+ tc->tree.bbsubheight = 0;
+
+
+ /*
+ * If this widget has a super-node, add it to that
+ * widget' sub-nodes list. Otherwise make it a sub-node of
+ * the tree_root widget.
+ */
+ if (tc->tree.parent)
+ insert_node (tc->tree.parent, new);
+ else if (tw->tree.tree_root)
+ insert_node (tw->tree.tree_root, new);
+}
+
+
+/* ARGSUSED */
+static Boolean SetValues (gcurrent, grequest, gnew, args, num_args)
+ Widget gcurrent, grequest, gnew;
+ ArgList args;
+ Cardinal *num_args;
+{
+ TreeWidget current = (TreeWidget) gcurrent, new = (TreeWidget) gnew;
+ Boolean redraw = FALSE;
+
+ /*
+ * If the foreground color has changed, redo the GC's
+ * and indicate a redraw.
+ */
+ if (new->tree.foreground != current->tree.foreground ||
+ new->core.background_pixel != current->core.background_pixel ||
+ new->tree.line_width != current->tree.line_width) {
+ XtReleaseGC (gnew, new->tree.gc);
+ new->tree.gc = get_tree_gc (new);
+ redraw = TRUE;
+ }
+
+ /*
+ * If the minimum spacing has changed, recalculate the
+ * tree layout. layout_tree() does a redraw, so we don't
+ * need SetValues to do another one.
+ */
+ if (new->tree.gravity != current->tree.gravity) {
+ check_gravity (new, current->tree.gravity);
+ }
+
+ if (IsHorizontal(new) != IsHorizontal(current)) {
+ if (new->tree.vpad == current->tree.vpad &&
+ new->tree.hpad == current->tree.hpad) {
+ new->tree.vpad = current->tree.hpad;
+ new->tree.hpad = current->tree.vpad;
+ }
+ }
+
+ if (new->tree.vpad != current->tree.vpad ||
+ new->tree.hpad != current->tree.hpad ||
+ new->tree.gravity != current->tree.gravity) {
+ layout_tree (new, TRUE);
+ redraw = FALSE;
+ }
+ return redraw;
+}
+
+
+/* ARGSUSED */
+static Boolean ConstraintSetValues (current, request, new, args, num_args)
+ Widget current, request, new;
+ ArgList args;
+ Cardinal *num_args;
+{
+ TreeConstraints newc = TREE_CONSTRAINT(new);
+ TreeConstraints curc = TREE_CONSTRAINT(current);
+ TreeWidget tw = (TreeWidget) new->core.parent;
+
+ /*
+ * If the parent field has changed, remove the widget
+ * from the old widget's children list and add it to the
+ * new one.
+ */
+ if (curc->tree.parent != newc->tree.parent){
+ if (curc->tree.parent)
+ delete_node (curc->tree.parent, new);
+ if (newc->tree.parent)
+ insert_node(newc->tree.parent, new);
+
+ /*
+ * If the Tree widget has been realized,
+ * compute new layout.
+ */
+ if (XtIsRealized((Widget)tw))
+ layout_tree (tw, FALSE);
+ }
+ return False;
+}
+
+
+static void ConstraintDestroy (w)
+ Widget w;
+{
+ TreeConstraints tc = TREE_CONSTRAINT(w);
+ TreeWidget tw = (TreeWidget) XtParent(w);
+ int i;
+
+ /*
+ * Remove the widget from its parent's sub-nodes list and
+ * make all this widget's sub-nodes sub-nodes of the parent.
+ */
+
+ if (tw->tree.tree_root == w) {
+ if (tc->tree.n_children > 0)
+ tw->tree.tree_root = tc->tree.children[0];
+ else
+ tw->tree.tree_root = NULL;
+ }
+
+ delete_node (tc->tree.parent, (Widget) w);
+ for (i = 0; i< tc->tree.n_children; i++)
+ insert_node (tc->tree.parent, tc->tree.children[i]);
+
+ layout_tree ((TreeWidget) (w->core.parent), FALSE);
+}
+
+/* ARGSUSED */
+static XtGeometryResult GeometryManager (w, request, reply)
+ Widget w;
+ XtWidgetGeometry *request;
+ XtWidgetGeometry *reply;
+{
+
+ TreeWidget tw = (TreeWidget) w->core.parent;
+
+ /*
+ * No position changes allowed!.
+ */
+ if ((request->request_mode & CWX && request->x!=w->core.x)
+ ||(request->request_mode & CWY && request->y!=w->core.y))
+ return (XtGeometryNo);
+
+ /*
+ * Allow all resize requests.
+ */
+
+ if (request->request_mode & CWWidth)
+ w->core.width = request->width;
+ if (request->request_mode & CWHeight)
+ w->core.height = request->height;
+ if (request->request_mode & CWBorderWidth)
+ w->core.border_width = request->border_width;
+
+ if (tw->tree.auto_reconfigure) layout_tree (tw, FALSE);
+ return (XtGeometryYes);
+}
+
+static void ChangeManaged (gw)
+ Widget gw;
+{
+ layout_tree ((TreeWidget) gw, FALSE);
+}
+
+
+static void Destroy (gw)
+ Widget gw;
+{
+ TreeWidget w = (TreeWidget) gw;
+
+ XtReleaseGC (gw, w->tree.gc);
+ if (w->tree.largest) XtFree ((char *) w->tree.largest);
+}
+
+
+/* ARGSUSED */
+static void Redisplay (gw, event, region)
+ Widget gw;
+ XEvent *event;
+ Region region;
+{
+ TreeWidget tw = (TreeWidget) gw;
+
+ /*
+ * If the Tree widget is visible, visit each managed child.
+ */
+ if (tw->core.visible) {
+ int i, j;
+ Display *dpy = XtDisplay (tw);
+ Window w = XtWindow (tw);
+
+ for (i = 0; i < tw->composite.num_children; i++) {
+ Widget child = tw->composite.children[i];
+ TreeConstraints tc = TREE_CONSTRAINT(child);
+
+ /*
+ * Don't draw lines from the fake tree_root.
+ */
+ if (child != tw->tree.tree_root && tc->tree.n_children) {
+ int srcx = child->core.x + child->core.border_width;
+ int srcy = child->core.y + child->core.border_width;
+
+ switch (tw->tree.gravity) {
+ case WestGravity:
+ srcx += child->core.width + child->core.border_width;
+ /* fall through */
+ case EastGravity:
+ srcy += child->core.height / 2;
+ break;
+
+ case NorthGravity:
+ srcy += child->core.height + child->core.border_width;
+ /* fall through */
+ case SouthGravity:
+ srcx += child->core.width / 2;
+ break;
+ }
+
+ for (j = 0; j < tc->tree.n_children; j++) {
+ Widget k = tc->tree.children[j];
+ GC gc = (tc->tree.gc ? tc->tree.gc : tw->tree.gc);
+
+ switch (tw->tree.gravity) {
+ case WestGravity:
+ /*
+ * right center to left center
+ */
+ XDrawLine (dpy, w, gc, srcx, srcy,
+ (int) k->core.x,
+ (k->core.y + ((int) k->core.border_width) +
+ ((int) k->core.height) / 2));
+ break;
+
+ case NorthGravity:
+ /*
+ * bottom center to top center
+ */
+ XDrawLine (dpy, w, gc, srcx, srcy,
+ (k->core.x + ((int) k->core.border_width) +
+ ((int) k->core.width) / 2),
+ (int) k->core.y);
+ break;
+
+ case EastGravity:
+ /*
+ * left center to right center
+ */
+ XDrawLine (dpy, w, gc, srcx, srcy,
+ (k->core.x +
+ (((int) k->core.border_width) << 1) +
+ (int) k->core.width),
+ (k->core.y + ((int) k->core.border_width) +
+ ((int) k->core.height) / 2));
+ break;
+
+ case SouthGravity:
+ /*
+ * top center to bottom center
+ */
+ XDrawLine (dpy, w, gc, srcx, srcy,
+ (k->core.x + ((int) k->core.border_width) +
+ ((int) k->core.width) / 2),
+ (k->core.y +
+ (((int) k->core.border_width) << 1) +
+ (int) k->core.height));
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+static XtGeometryResult QueryGeometry (w, intended, preferred)
+ Widget w;
+ XtWidgetGeometry *intended, *preferred;
+{
+ TreeWidget tw = (TreeWidget) w;
+
+ preferred->request_mode = (CWWidth | CWHeight);
+ preferred->width = tw->tree.maxwidth;
+ preferred->height = tw->tree.maxheight;
+
+ 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;
+}
+
+
+/*****************************************************************************
+ * *
+ * tree layout algorithm *
+ * *
+ * Each node in the tree is "shrink-wrapped" with a minimal bounding *
+ * rectangle, laid next to its siblings (with a small about of padding in *
+ * between) and then wrapped with their parent. Parents are centered about *
+ * their children (or vice versa if the parent is larger than the children). *
+ * *
+ *****************************************************************************/
+
+static void compute_bounding_box_subtree (tree, w, depth)
+ TreeWidget tree;
+ Widget w;
+ int depth;
+{
+ TreeConstraints tc = TREE_CONSTRAINT(w); /* info attached to all kids */
+ int i;
+ Bool horiz = IsHorizontal (tree);
+ Dimension newwidth, newheight;
+ Dimension bw2 = w->core.border_width * 2;
+
+ /*
+ * Set the max-size per level.
+ */
+ if (depth >= tree->tree.n_largest) {
+ initialize_dimensions (&tree->tree.largest,
+ &tree->tree.n_largest, depth + 1);
+ }
+ newwidth = ((horiz ? w->core.width : w->core.height) + bw2);
+ if (tree->tree.largest[depth] < newwidth)
+ tree->tree.largest[depth] = newwidth;
+
+
+ /*
+ * initialize
+ */
+ tc->tree.bbwidth = w->core.width + bw2;
+ tc->tree.bbheight = w->core.height + bw2;
+
+ if (tc->tree.n_children == 0) return;
+
+ /*
+ * Figure the size of the opposite dimension (vertical if tree is
+ * horizontal, else vice versa). The other dimension will be set
+ * in the second pass once we know the maximum dimensions.
+ */
+ newwidth = 0;
+ newheight = 0;
+ for (i = 0; i < tc->tree.n_children; i++) {
+ Widget child = tc->tree.children[i];
+ TreeConstraints cc = TREE_CONSTRAINT(child);
+
+ compute_bounding_box_subtree (tree, child, depth + 1);
+
+ if (horiz) {
+ if (newwidth < cc->tree.bbwidth) newwidth = cc->tree.bbwidth;
+ newheight += tree->tree.vpad + cc->tree.bbheight;
+ } else {
+ if (newheight < cc->tree.bbheight) newheight = cc->tree.bbheight;
+ newwidth += tree->tree.hpad + cc->tree.bbwidth;
+ }
+ }
+
+
+ tc->tree.bbsubwidth = newwidth;
+ tc->tree.bbsubheight = newheight;
+
+ /*
+ * Now fit parent onto side (or top) of bounding box and correct for
+ * extra padding. Be careful of unsigned arithmetic.
+ */
+ if (horiz) {
+ tc->tree.bbwidth += tree->tree.hpad + newwidth;
+ newheight -= tree->tree.vpad;
+ if (newheight > tc->tree.bbheight) tc->tree.bbheight = newheight;
+ } else {
+ tc->tree.bbheight += tree->tree.vpad + newheight;
+ newwidth -= tree->tree.hpad;
+ if (newwidth > tc->tree.bbwidth) tc->tree.bbwidth = newwidth;
+ }
+}
+
+
+static void set_positions (tw, w, level)
+ TreeWidget tw;
+ Widget w;
+ int level;
+{
+ int i;
+
+ if (w) {
+ TreeConstraints tc = TREE_CONSTRAINT(w);
+
+ if (level > 0) {
+ /*
+ * mirror if necessary
+ */
+ switch (tw->tree.gravity) {
+ case EastGravity:
+ tc->tree.x = (((Position) tw->tree.maxwidth) -
+ ((Position) w->core.width) - tc->tree.x);
+ break;
+
+ case SouthGravity:
+ tc->tree.y = (((Position) tw->tree.maxheight) -
+ ((Position) w->core.height) - tc->tree.y);
+ break;
+ }
+
+ /*
+ * Move the widget into position.
+ */
+ XtMoveWidget (w, tc->tree.x, tc->tree.y);
+ }
+
+ /*
+ * Set the positions of all children.
+ */
+ for (i = 0; i < tc->tree.n_children; i++)
+ set_positions (tw, tc->tree.children[i], level + 1);
+ }
+}
+
+
+static void arrange_subtree (tree, w, depth, x, y)
+ TreeWidget tree;
+ Widget w;
+ int depth;
+ Position x, y;
+{
+ TreeConstraints tc = TREE_CONSTRAINT(w); /* info attached to all kids */
+ TreeConstraints firstcc, lastcc;
+ int i;
+ int newx, newy;
+ Bool horiz = IsHorizontal (tree);
+ Widget child = NULL;
+ Dimension tmp;
+ Dimension bw2 = w->core.border_width * 2;
+ Bool relayout = True;
+
+
+ /*
+ * If no children, then just lay out where requested.
+ */
+ tc->tree.x = x;
+ tc->tree.y = y;
+
+ if (horiz) {
+ int myh = (w->core.height + bw2);
+
+ if (myh > (int)tc->tree.bbsubheight) {
+ y += (myh - (int)tc->tree.bbsubheight) / 2;
+ relayout = False;
+ }
+ } else {
+ int myw = (w->core.width + bw2);
+
+ if (myw > (int)tc->tree.bbsubwidth) {
+ x += (myw - (int)tc->tree.bbsubwidth) / 2;
+ relayout = False;
+ }
+ }
+
+ if ((tmp = ((Dimension) x) + tc->tree.bbwidth) > tree->tree.maxwidth)
+ tree->tree.maxwidth = tmp;
+ if ((tmp = ((Dimension) y) + tc->tree.bbheight) > tree->tree.maxheight)
+ tree->tree.maxheight = tmp;
+
+ if (tc->tree.n_children == 0) return;
+
+
+ /*
+ * Have children, so walk down tree laying out children, then laying
+ * out parents.
+ */
+ if (horiz) {
+ newx = x + tree->tree.largest[depth];
+ if (depth > 0) newx += tree->tree.hpad;
+ newy = y;
+ } else {
+ newx = x;
+ newy = y + tree->tree.largest[depth];
+ if (depth > 0) newy += tree->tree.vpad;
+ }
+
+ for (i = 0; i < tc->tree.n_children; i++) {
+ TreeConstraints cc;
+
+ child = tc->tree.children[i]; /* last value is used outside loop */
+ cc = TREE_CONSTRAINT(child);
+
+ arrange_subtree (tree, child, depth + 1, newx, newy);
+ if (horiz) {
+ newy += tree->tree.vpad + cc->tree.bbheight;
+ } else {
+ newx += tree->tree.hpad + cc->tree.bbwidth;
+ }
+ }
+
+ /*
+ * now layout parent between first and last children
+ */
+ if (relayout) {
+ Position adjusted;
+ firstcc = TREE_CONSTRAINT (tc->tree.children[0]);
+ lastcc = TREE_CONSTRAINT (child);
+
+ /* Adjustments are disallowed if they result in a position above
+ * or to the left of the originally requested position, because
+ * this could collide with the position of the previous sibling.
+ */
+ if (horiz) {
+ tc->tree.x = x;
+ adjusted = firstcc->tree.y +
+ ((lastcc->tree.y + (Position) child->core.height +
+ (Position) child->core.border_width * 2 -
+ firstcc->tree.y - (Position) w->core.height -
+ (Position) w->core.border_width * 2 + 1) / 2);
+ if (adjusted > tc->tree.y) tc->tree.y = adjusted;
+ } else {
+ adjusted = firstcc->tree.x +
+ ((lastcc->tree.x + (Position) child->core.width +
+ (Position) child->core.border_width * 2 -
+ firstcc->tree.x - (Position) w->core.width -
+ (Position) w->core.border_width * 2 + 1) / 2);
+ if (adjusted > tc->tree.x) tc->tree.x = adjusted;
+ tc->tree.y = y;
+ }
+ }
+}
+
+static void set_tree_size (tw, insetvalues, width, height)
+ TreeWidget tw;
+ Boolean insetvalues;
+ Dimension width, height;
+{
+ if (insetvalues) {
+ tw->core.width = width;
+ tw->core.height = height;
+ } else {
+ Dimension replyWidth = 0, replyHeight = 0;
+ XtGeometryResult result = XtMakeResizeRequest ((Widget) tw,
+ width, height,
+ &replyWidth,
+ &replyHeight);
+ /*
+ * Accept any compromise.
+ */
+ if (result == XtGeometryAlmost)
+ XtMakeResizeRequest ((Widget) tw, replyWidth, replyHeight,
+ (Dimension *) NULL, (Dimension *) NULL);
+ }
+ return;
+}
+
+static void layout_tree (tw, insetvalues)
+ TreeWidget tw;
+ Boolean insetvalues;
+{
+ int i;
+ Dimension *dp;
+
+ /*
+ * Do a depth-first search computing the width and height of the bounding
+ * box for the tree at that position (and below). Then, walk again using
+ * this information to layout the children at each level.
+ */
+
+ if (tw->tree.tree_root == NULL)
+ return;
+
+ tw->tree.maxwidth = tw->tree.maxheight = 0;
+ for (i = 0, dp = tw->tree.largest; i < tw->tree.n_largest; i++, dp++)
+ *dp = 0;
+ initialize_dimensions (&tw->tree.largest, &tw->tree.n_largest,
+ tw->tree.n_largest);
+ compute_bounding_box_subtree (tw, tw->tree.tree_root, 0);
+
+ /*
+ * Second pass to do final layout. Each child's bounding box is stacked
+ * on top of (if horizontal, else next to) on top of its siblings. The
+ * parent is centered between the first and last children.
+ */
+ arrange_subtree (tw, tw->tree.tree_root, 0, 0, 0);
+
+ /*
+ * Move each widget into place.
+ */
+ set_tree_size (tw, insetvalues, tw->tree.maxwidth, tw->tree.maxheight);
+ set_positions (tw, tw->tree.tree_root, 0);
+
+ /*
+ * And redisplay.
+ */
+ if (XtIsRealized ((Widget) tw)) {
+ XClearArea (XtDisplay(tw), XtWindow((Widget)tw), 0, 0, 0, 0, True);
+ }
+}
+
+
+
+/*****************************************************************************
+ * *
+ * Public Routines *
+ * *
+ *****************************************************************************/
+
+void
+#if NeedFunctionPrototypes
+XawTreeForceLayout (Widget tree)
+#else
+XawTreeForceLayout (tree)
+ Widget tree;
+#endif
+{
+ layout_tree ((TreeWidget) tree, FALSE);
+}
+
diff --git a/src/Tree.h b/src/Tree.h
new file mode 100644
index 0000000..fde1117
--- /dev/null
+++ b/src/Tree.h
@@ -0,0 +1,125 @@
+/*
+ * $XConsortium: Tree.h,v 1.13 94/04/17 20:13:22 kaleb Exp $
+ *
+
+Copyright (c) 1990, 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 1989 Prentice Hall
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation.
+ *
+ * Prentice Hall and the authors disclaim all warranties with regard
+ * to this software, including all implied warranties of merchantability and
+ * fitness. In no event shall Prentice Hall or the authors be liable
+ * for any special, indirect or cosequential 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.
+ *
+ * Authors: Jim Fulton, MIT X Consortium,
+ * based on a version by Douglas Young, Prentice Hall
+ *
+ * This widget is based on the Tree widget described on pages 397-419 of
+ * Douglas Young's book "The X Window System, Programming and Applications
+ * with Xt OSF/Motif Edition." The layout code has been rewritten to use
+ * additional blank space to make the structure of the graph easier to see
+ * as well as to support vertical trees.
+ */
+
+
+#ifndef _XawTree_h
+#define _XawTree_h
+
+#include <X11/Xmu/Converters.h>
+
+/******************************************************************************
+ *
+ * Tree Widget (subclass of ConstraintClass)
+ *
+ ******************************************************************************
+ *
+ * Parameters:
+ *
+ * Name Class Type Default
+ * ---- ----- ---- -------
+ *
+ * autoReconfigure AutoReconfigure Boolean FALSE
+ * background Background Pixel XtDefaultBackground
+ * foreground Foreground Pixel XtDefaultForeground
+ * gravity Gravity XtGravity West
+ * hSpace HSpace Dimension 20
+ * lineWidth LineWidth Dimension 0
+ * vSpace VSpace Dimension 6
+ *
+ *
+ * Constraint Resources attached to children:
+ *
+ * treeGC TreeGC GC NULL
+ * treeParent TreeParent Widget NULL
+ *
+ *
+ *****************************************************************************/
+
+ /* new instance field names */
+#ifndef _XtStringDefs_h_
+#define XtNhSpace "hSpace"
+#define XtNvSpace "vSpace"
+#define XtCHSpace "HSpace"
+#define XtCVSpace "VSpace"
+#endif
+
+#define XtNautoReconfigure "autoReconfigure"
+#define XtNlineWidth "lineWidth"
+#define XtNtreeGC "treeGC"
+#define XtNtreeParent "treeParent"
+#define XtNgravity "gravity"
+
+ /* new class field names */
+#define XtCAutoReconfigure "AutoReconfigure"
+#define XtCLineWidth "LineWidth"
+#define XtCTreeGC "TreeGC"
+#define XtCTreeParent "TreeParent"
+#define XtCGravity "Gravity"
+
+#define XtRGC "GC"
+ /* external declarations */
+extern WidgetClass treeWidgetClass;
+
+typedef struct _TreeClassRec *TreeWidgetClass;
+typedef struct _TreeRec *TreeWidget;
+
+_XFUNCPROTOBEGIN
+
+extern void XawTreeForceLayout (
+#if NeedFunctionPrototypes
+ Widget /* tree */
+#endif
+);
+
+_XFUNCPROTOEND
+
+#endif /* _XawTree_h */
diff --git a/src/TreeP.h b/src/TreeP.h
new file mode 100644
index 0000000..9905138
--- /dev/null
+++ b/src/TreeP.h
@@ -0,0 +1,132 @@
+/*
+ * $XConsortium: TreeP.h,v 1.14 94/04/17 20:13:24 jim Exp $
+ *
+
+Copyright (c) 1990 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 1989 Prentice Hall
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies and that both the copyright notice
+ * and this permission notice appear in supporting documentation.
+ *
+ * Prentice Hall and the authors disclaim all warranties with regard
+ * to this software, including all implied warranties of merchantability and
+ * fitness. In no event shall Prentice Hall or the authors be liable
+ * for any special, indirect or cosequential 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.
+ *
+ * Authors: Jim Fulton, MIT X Consortium,
+ * based on a version by Douglas Young, Prentice Hall
+ *
+ * This widget is based on the Tree widget described on pages 397-419 of
+ * Douglas Young's book "The X Window System, Programming and Applications
+ * with Xt OSF/Motif Edition." The layout code has been rewritten to use
+ * additional blank space to make the structure of the graph easier to see
+ * as well as to support vertical trees.
+ */
+
+
+#ifndef _XawTreeP_h
+#define _XawTreeP_h
+
+#include <X11/Xaw3d/Tree.h>
+
+typedef struct _TreeClassPart {
+ int ignore;
+} TreeClassPart;
+
+typedef struct _TreeClassRec {
+ CoreClassPart core_class;
+ CompositeClassPart composite_class;
+ ConstraintClassPart constraint_class;
+ TreeClassPart tree_class;
+} TreeClassRec;
+
+extern TreeClassRec treeClassRec;
+
+typedef struct {
+ /* fields available through resources */
+ Dimension hpad; /* hSpace/HSpace */
+ Dimension vpad; /* vSpace/VSpace */
+ Dimension line_width; /* lineWidth/LineWidth */
+ Pixel foreground; /* foreground/Foreground */
+ XtGravity gravity; /* gravity/Gravity */
+ Boolean auto_reconfigure; /* autoReconfigure/AutoReconfigure */
+ /* private fields */
+ GC gc; /* used to draw lines */
+ Widget tree_root; /* hidden root off all children */
+ Dimension *largest; /* list of largest per depth */
+ int n_largest; /* number of elements in largest */
+ Dimension maxwidth, maxheight; /* for shrink wrapping */
+} TreePart;
+
+
+typedef struct _TreeRec {
+ CorePart core;
+ CompositePart composite;
+ ConstraintPart constraint;
+ TreePart tree;
+} TreeRec;
+
+
+/*
+ * structure attached to all children
+ */
+typedef struct _TreeConstraintsPart {
+ /* resources */
+ Widget parent; /* treeParent/TreeParent */
+ GC gc; /* treeGC/TreeGC */
+ /* private data */
+ Widget *children;
+ int n_children;
+ int max_children;
+ Dimension bbsubwidth, bbsubheight; /* bounding box of sub tree */
+ Dimension bbwidth, bbheight; /* bounding box including node */
+ Position x, y;
+} TreeConstraintsPart;
+
+typedef struct _TreeConstraintsRec {
+ TreeConstraintsPart tree;
+} TreeConstraintsRec, *TreeConstraints;
+
+
+/*
+ * useful macros
+ */
+
+#define TREE_CONSTRAINT(w) \
+ ((TreeConstraints)((w)->core.constraints))
+
+#define TREE_INITIAL_DEPTH 10 /* for allocating largest array */
+#define TREE_HORIZONTAL_DEFAULT_SPACING 20
+#define TREE_VERTICAL_DEFAULT_SPACING 6
+
+#endif /* _XawTreeP_h */
+
+
+
diff --git a/src/Vendor.c b/src/Vendor.c
new file mode 100644
index 0000000..4fa43db
--- /dev/null
+++ b/src/Vendor.c
@@ -0,0 +1,604 @@
+/* $XConsortium: Vendor.c,v 1.27 94/04/17 20:13:25 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.
+
+******************************************************************/
+
+/*
+ * Portions Copyright (c) 1996 Alfredo Kojima
+ * Rights, permissions, and disclaimer per the above X Consortium license.
+ */
+
+/*
+ * This is a copy of Xt/Vendor.c with an additional ClassInitialize
+ * procedure to register Xmu resource type converters, and all the
+ * monkey business associated with input methods...
+ *
+ */
+
+/* Make sure all wm properties can make it out of the resource manager */
+
+#include "Xaw3dP.h"
+#include <stdio.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/ShellP.h>
+#include <X11/VendorP.h>
+#include <X11/Xmu/Converters.h>
+#include <X11/Xmu/Atoms.h>
+#include <X11/Xmu/Editres.h>
+#ifdef XAW_INTERNATIONALIZATION
+#include <X11/Xmu/ExtAgent.h>
+#endif
+#ifdef XAW_MULTIPLANE_PIXMAPS
+#include <X11/xpm.h>
+#include <X11/Xmu/Drawing.h>
+#endif
+
+/* The following two headers are for the input method. */
+#ifdef XAW_INTERNATIONALIZATION
+#include <X11/Xaw3d/VendorEP.h>
+#include <X11/Xaw3d/XawImP.h>
+#endif
+
+
+static XtResource resources[] = {
+ {XtNinput, XtCInput, XtRBool, sizeof(Bool),
+ XtOffsetOf(VendorShellRec, wm.wm_hints.input),
+ XtRImmediate, (XtPointer)True}
+};
+
+/***************************************************************************
+ *
+ * Vendor shell class record
+ *
+ ***************************************************************************/
+
+static void XawVendorShellClassInitialize();
+static void XawVendorShellInitialize();
+static Boolean XawVendorShellSetValues();
+static void Realize(), ChangeManaged();
+static XtGeometryResult GeometryManager();
+#ifdef XAW_INTERNATIONALIZATION
+static void XawVendorShellClassPartInit();
+void XawVendorShellExtResize();
+#endif
+
+#ifdef XAW_INTERNATIONALIZATION
+static CompositeClassExtensionRec vendorCompositeExt = {
+ /* next_extension */ NULL,
+ /* record_type */ NULLQUARK,
+ /* version */ XtCompositeExtensionVersion,
+ /* record_size */ sizeof (CompositeClassExtensionRec),
+ /* accepts_objects */ TRUE,
+ /* allows_change_managed_set */ FALSE
+};
+#endif
+
+#define SuperClass (&wmShellClassRec)
+externaldef(vendorshellclassrec) VendorShellClassRec vendorShellClassRec = {
+ {
+ /* superclass */ (WidgetClass)SuperClass,
+ /* class_name */ "VendorShell",
+ /* size */ sizeof(VendorShellRec),
+ /* class_initialize */ XawVendorShellClassInitialize,
+#ifdef XAW_INTERNATIONALIZATION
+ /* class_part_init */ XawVendorShellClassPartInit,
+#else
+ /* class_part_init */ NULL,
+#endif
+ /* Class init'ed ? */ FALSE,
+ /* initialize */ XawVendorShellInitialize,
+ /* initialize_hook */ NULL,
+ /* realize */ Realize,
+ /* actions */ NULL,
+ /* num_actions */ 0,
+ /* resources */ resources,
+ /* resource_count */ XtNumber(resources),
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ FALSE,
+ /* compress_exposure */ TRUE,
+ /* compress_enterleave*/ FALSE,
+ /* visible_interest */ FALSE,
+ /* destroy */ NULL,
+#ifdef XAW_INTERNATIONALIZATION
+ /* resize */ XawVendorShellExtResize,
+#else
+ /* resize */ XtInheritResize,
+#endif
+ /* expose */ NULL,
+ /* set_values */ XawVendorShellSetValues,
+ /* set_values_hook */ NULL,
+ /* set_values_almost */ XtInheritSetValuesAlmost,
+ /* get_values_hook */ NULL,
+ /* accept_focus */ NULL,
+ /* intrinsics version */ XtVersion,
+ /* callback offsets */ NULL,
+ /* tm_table */ NULL,
+ /* query_geometry */ NULL,
+ /* display_accelerator*/ NULL,
+ /* extension */ NULL
+ },{
+ /* geometry_manager */ GeometryManager,
+ /* change_managed */ ChangeManaged,
+ /* insert_child */ XtInheritInsertChild,
+ /* delete_child */ XtInheritDeleteChild,
+#ifdef XAW_INTERNATIONALIZATION
+ /* extension */ (XtPointer) &vendorCompositeExt
+#else
+ /* extension */ NULL
+#endif
+ },{
+ /* extension */ NULL
+ },{
+ /* extension */ NULL
+ },{
+ /* extension */ NULL
+ }
+};
+
+externaldef(vendorshellwidgetclass) WidgetClass vendorShellWidgetClass =
+ (WidgetClass) (&vendorShellClassRec);
+
+
+#ifdef XAW_INTERNATIONALIZATION
+/***************************************************************************
+ *
+ * The following section is for the Vendor shell Extension class record
+ *
+ ***************************************************************************/
+
+static XtResource ext_resources[] = {
+ {XtNinputMethod, XtCInputMethod, XtRString, sizeof(String),
+ XtOffsetOf(XawVendorShellExtRec, vendor_ext.im.input_method),
+ XtRString, (XtPointer)NULL},
+ {XtNpreeditType, XtCPreeditType, XtRString, sizeof(String),
+ XtOffsetOf(XawVendorShellExtRec, vendor_ext.im.preedit_type),
+ XtRString, (XtPointer)"OverTheSpot,OffTheSpot,Root"},
+ {XtNopenIm, XtCOpenIm, XtRBoolean, sizeof(Boolean),
+ XtOffsetOf(XawVendorShellExtRec, vendor_ext.im.open_im),
+ XtRImmediate, (XtPointer)TRUE},
+ {XtNsharedIc, XtCSharedIc, XtRBoolean, sizeof(Boolean),
+ XtOffsetOf(XawVendorShellExtRec, vendor_ext.ic.shared_ic),
+ XtRImmediate, (XtPointer)FALSE}
+};
+
+static void XawVendorShellExtClassInitialize();
+static void XawVendorShellExtInitialize();
+static void XawVendorShellExtDestroy();
+static Boolean XawVendorShellExtSetValues();
+
+externaldef(vendorshellextclassrec) XawVendorShellExtClassRec
+ xawvendorShellExtClassRec = {
+ {
+ /* superclass */ (WidgetClass)&objectClassRec,
+ /* class_name */ "VendorShellExt",
+ /* size */ sizeof(XawVendorShellExtRec),
+ /* class_initialize */ XawVendorShellExtClassInitialize,
+ /* class_part_initialize*/ NULL,
+ /* Class init'ed ? */ FALSE,
+ /* initialize */ XawVendorShellExtInitialize,
+ /* initialize_hook */ NULL,
+ /* pad */ NULL,
+ /* pad */ NULL,
+ /* pad */ 0,
+ /* resources */ ext_resources,
+ /* resource_count */ XtNumber(ext_resources),
+ /* xrm_class */ NULLQUARK,
+ /* pad */ FALSE,
+ /* pad */ FALSE,
+ /* pad */ FALSE,
+ /* pad */ FALSE,
+ /* destroy */ XawVendorShellExtDestroy,
+ /* pad */ NULL,
+ /* pad */ NULL,
+ /* set_values */ XawVendorShellExtSetValues,
+ /* set_values_hook */ NULL,
+ /* pad */ NULL,
+ /* get_values_hook */ NULL,
+ /* pad */ NULL,
+ /* version */ XtVersion,
+ /* callback_offsets */ NULL,
+ /* pad */ NULL,
+ /* pad */ NULL,
+ /* pad */ NULL,
+ /* extension */ NULL
+ },{
+ /* extension */ NULL
+ }
+};
+
+externaldef(xawvendorshellwidgetclass) WidgetClass
+ xawvendorShellExtWidgetClass = (WidgetClass) (&xawvendorShellExtClassRec);
+#endif
+
+
+/*ARGSUSED*/
+static Boolean
+XawCvtCompoundTextToString(dpy, args, num_args, fromVal, toVal, cvt_data)
+Display *dpy;
+XrmValuePtr args;
+Cardinal *num_args;
+XrmValue *fromVal;
+XrmValue *toVal;
+XtPointer *cvt_data;
+{
+ XTextProperty prop;
+ char **list;
+ int count;
+ static char *mbs = NULL;
+ int len;
+
+ prop.value = (unsigned char *)fromVal->addr;
+ prop.encoding = XA_COMPOUND_TEXT(dpy);
+ prop.format = 8;
+ prop.nitems = fromVal->size;
+
+ if(XmbTextPropertyToTextList(dpy, &prop, &list, &count) < Success) {
+ XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
+ "converter", "XmbTextPropertyToTextList", "XawError",
+ "conversion from CT to MB failed.", NULL, 0);
+ return False;
+ }
+ len = strlen(*list);
+ toVal->size = len;
+ mbs = XtRealloc(mbs, len + 1); /* keep buffer because no one call free :( */
+ strcpy(mbs, *list);
+ XFreeStringList(list);
+ toVal->addr = (XtPointer)mbs;
+ return True;
+}
+
+#ifdef XAW_MULTIPLANE_PIXMAPS
+#define DONE(type, address) \
+ {to->size = sizeof(type); to->addr = (XPointer)address;}
+
+/* ARGSUSED */
+static Boolean
+_XawCvtStringToPixmap(dpy, args, nargs, from, to, data)
+Display *dpy;
+XrmValuePtr args;
+Cardinal *nargs;
+XrmValuePtr from, to;
+XtPointer *data;
+{
+ static Pixmap pixmap;
+ Window win;
+ XpmAttributes attr;
+ XpmColorSymbol colors[1];
+
+ if (*nargs != 3)
+ XtAppErrorMsg(XtDisplayToApplicationContext(dpy),
+ "_XawCvtStringToPixmap", "wrongParameters", "XtToolkitError",
+ "_XawCvtStringToPixmap needs screen, colormap, and background_pixel",
+ (String *) NULL, (Cardinal *) NULL);
+
+ if (strcmp(from->addr, "None") == 0)
+ {
+ pixmap = None;
+ DONE(Pixmap, &pixmap);
+ return (True);
+ }
+ if (strcmp(from->addr, "ParentRelative") == 0)
+ {
+ pixmap = ParentRelative;
+ DONE(Pixmap, &pixmap);
+ return (True);
+ }
+
+ win = RootWindowOfScreen(*((Screen **) args[0].addr));
+
+ attr.colormap = *((Colormap *) args[1].addr);
+ attr.closeness = 32768; /* might help on 8-bpp displays? */
+ attr.valuemask = XpmColormap | XpmCloseness;
+
+ colors[0].name = NULL;
+ colors[0].value = "none";
+ colors[0].pixel = *((Pixel *) args[2].addr);
+ attr.colorsymbols = colors;
+ attr.numsymbols = 1;
+ attr.valuemask |= XpmColorSymbols;
+
+ if (XpmReadFileToPixmap(dpy, win, (String) from->addr,
+ &pixmap, NULL, &attr) != XpmSuccess)
+ {
+ if ((pixmap = XmuLocateBitmapFile(*((Screen **) args[0].addr),
+ (char *)from->addr, NULL, 0, NULL, NULL, NULL, NULL)) == None)
+ {
+ XtDisplayStringConversionWarning(dpy, (String) from->addr,
+ XtRPixmap);
+ return (False);
+ }
+ }
+
+ if (to->addr == NULL)
+ to->addr = (XtPointer) & pixmap;
+ else
+ {
+ if (to->size < sizeof(Pixmap))
+ {
+ to->size = sizeof(Pixmap);
+ XtDisplayStringConversionWarning(dpy, (String) from->addr,
+ XtRPixmap);
+ return (False);
+ }
+
+ *((Pixmap *) to->addr) = pixmap;
+ }
+ to->size = sizeof(Pixmap);
+ return (True);
+}
+#endif
+
+static void XawVendorShellClassInitialize()
+{
+ static XtConvertArgRec screenConvertArg[] = {
+ {XtWidgetBaseOffset, (XtPointer) XtOffsetOf(WidgetRec, core.screen),
+ sizeof(Screen *)}
+ };
+#ifdef XAW_MULTIPLANE_PIXMAPS
+ static XtConvertArgRec _XawCvtStrToPix[] = {
+ {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.screen),
+ sizeof(Screen *)},
+ {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.colormap),
+ sizeof(Colormap)},
+ {XtWidgetBaseOffset,
+ (XtPointer)XtOffsetOf(WidgetRec, core.background_pixel),
+ sizeof(Pixel)}
+ };
+#endif
+
+ XtAddConverter(XtRString, XtRCursor, XmuCvtStringToCursor,
+ screenConvertArg, XtNumber(screenConvertArg));
+
+#ifdef XAW_MULTIPLANE_PIXMAPS
+ XtSetTypeConverter(XtRString, XtRBitmap,
+ (XtTypeConverter)_XawCvtStringToPixmap,
+ _XawCvtStrToPix, XtNumber(_XawCvtStrToPix),
+ XtCacheByDisplay, (XtDestructor)NULL);
+#else
+ XtAddConverter(XtRString, XtRBitmap, XmuCvtStringToBitmap,
+ screenConvertArg, XtNumber(screenConvertArg));
+#endif
+
+ XtSetTypeConverter("CompoundText", XtRString, XawCvtCompoundTextToString,
+ NULL, 0, XtCacheNone, NULL);
+}
+
+#ifdef XAW_INTERNATIONALIZATION
+static void XawVendorShellClassPartInit(class)
+ WidgetClass class;
+{
+ CompositeClassExtension ext;
+ VendorShellWidgetClass vsclass = (VendorShellWidgetClass) class;
+
+ if ((ext = (CompositeClassExtension)
+ XtGetClassExtension (class,
+ XtOffsetOf(CompositeClassRec,
+ composite_class.extension),
+ NULLQUARK, 1L, (Cardinal) 0)) == NULL) {
+ ext = (CompositeClassExtension) XtNew (CompositeClassExtensionRec);
+ if (ext != NULL) {
+ ext->next_extension = vsclass->composite_class.extension;
+ ext->record_type = NULLQUARK;
+ ext->version = XtCompositeExtensionVersion;
+ ext->record_size = sizeof (CompositeClassExtensionRec);
+ ext->accepts_objects = TRUE;
+ ext->allows_change_managed_set = FALSE;
+ vsclass->composite_class.extension = (XtPointer) ext;
+ }
+ }
+}
+#endif
+
+#ifdef __osf__
+/* stupid OSF/1 shared libraries have the wrong semantics */
+/* symbols do not get resolved external to the shared library */
+void _XawFixupVendorShell()
+{
+ transientShellWidgetClass->core_class.superclass =
+ (WidgetClass) &vendorShellClassRec;
+ topLevelShellWidgetClass->core_class.superclass =
+ (WidgetClass) &vendorShellClassRec;
+}
+#endif
+
+/* ARGSUSED */
+static void XawVendorShellInitialize(req, new, args, num_args)
+ Widget req, new;
+ ArgList args;
+ Cardinal *num_args;
+{
+ XtAddEventHandler(new, (EventMask) 0, TRUE, _XEditResCheckMessages, NULL);
+#ifdef XAW_INTERNATIONALIZATION
+ XtAddEventHandler(new, (EventMask) 0, TRUE, XmuRegisterExternalAgent, NULL);
+ XtCreateWidget("shellext", xawvendorShellExtWidgetClass,
+ new, args, *num_args);
+#endif
+}
+
+/* ARGSUSED */
+static Boolean XawVendorShellSetValues(old, ref, new)
+ Widget old, ref, new;
+{
+ return FALSE;
+}
+
+static void Realize(wid, vmask, attr)
+ Widget wid;
+ Mask *vmask;
+ XSetWindowAttributes *attr;
+{
+ WidgetClass super = wmShellWidgetClass;
+
+ /* Make my superclass do all the dirty work */
+
+ (*super->core_class.realize) (wid, vmask, attr);
+#ifdef XAW_INTERNATIONALIZATION
+ _XawImRealize(wid);
+#endif
+}
+
+
+#ifdef XAW_INTERNATIONALIZATION
+static void XawVendorShellExtClassInitialize()
+{
+}
+
+/* ARGSUSED */
+static void XawVendorShellExtInitialize(req, new)
+ Widget req, new;
+{
+ _XawImInitialize(new->core.parent, new);
+}
+
+/* ARGSUSED */
+static void XawVendorShellExtDestroy( w )
+ Widget w;
+{
+ _XawImDestroy( w->core.parent, w );
+}
+
+/* ARGSUSED */
+static Boolean XawVendorShellExtSetValues(old, ref, new)
+ Widget old, ref, new;
+{
+ return FALSE;
+}
+
+void XawVendorShellExtResize( w )
+ Widget w;
+{
+ ShellWidget sw = (ShellWidget) w;
+ Widget childwid;
+ int i;
+ int core_height;
+
+ _XawImResizeVendorShell( w );
+ core_height = _XawImGetShellHeight( w );
+ for( i = 0; i < sw->composite.num_children; i++ ) {
+ if( XtIsManaged( sw->composite.children[ i ] ) ) {
+ childwid = sw->composite.children[ i ];
+ XtResizeWidget( childwid, sw->core.width, core_height,
+ childwid->core.border_width );
+ }
+ }
+}
+#endif
+
+/*ARGSUSED*/
+static XtGeometryResult GeometryManager( wid, request, reply )
+ Widget wid;
+ XtWidgetGeometry *request;
+ XtWidgetGeometry *reply;
+{
+ ShellWidget shell = (ShellWidget)(wid->core.parent);
+ XtWidgetGeometry my_request;
+
+ if(shell->shell.allow_shell_resize == FALSE && XtIsRealized(wid))
+ return(XtGeometryNo);
+
+ if (request->request_mode & (CWX | CWY))
+ return(XtGeometryNo);
+
+ /* %%% worry about XtCWQueryOnly */
+ my_request.request_mode = 0;
+ if (request->request_mode & CWWidth) {
+ my_request.width = request->width;
+ my_request.request_mode |= CWWidth;
+ }
+ if (request->request_mode & CWHeight) {
+ my_request.height = request->height
+#ifdef XAW_INTERNATIONALIZATION
+ + _XawImGetImAreaHeight( wid )
+#endif
+ ;
+ my_request.request_mode |= CWHeight;
+ }
+ if (request->request_mode & CWBorderWidth) {
+ my_request.border_width = request->border_width;
+ my_request.request_mode |= CWBorderWidth;
+ }
+ if (XtMakeGeometryRequest((Widget)shell, &my_request, NULL)
+ == XtGeometryYes) {
+ /* assert: if (request->request_mode & CWWidth) then
+ * shell->core.width == request->width
+ * assert: if (request->request_mode & CWHeight) then
+ * shell->core.height == request->height
+ *
+ * so, whatever the WM sized us to (if the Shell requested
+ * only one of the two) is now the correct child size
+ */
+
+ wid->core.width = shell->core.width;
+ wid->core.height = shell->core.height;
+ if (request->request_mode & CWBorderWidth) {
+ wid->core.x = wid->core.y = -request->border_width;
+ }
+#ifdef XAW_INTERNATIONALIZATION
+ _XawImCallVendorShellExtResize(wid);
+#endif
+ return XtGeometryYes;
+ } else return XtGeometryNo;
+}
+
+static void ChangeManaged(wid)
+ Widget wid;
+{
+ ShellWidget w = (ShellWidget) wid;
+ Widget* childP;
+ int i;
+
+ (*SuperClass->composite_class.change_managed)(wid);
+ for (i = w->composite.num_children, childP = w->composite.children;
+ i; i--, childP++) {
+ if (XtIsManaged(*childP)) {
+ XtSetKeyboardFocus(wid, *childP);
+ break;
+ }
+ }
+}
diff --git a/src/VendorEP.h b/src/VendorEP.h
new file mode 100644
index 0000000..9da02d9
--- /dev/null
+++ b/src/VendorEP.h
@@ -0,0 +1,81 @@
+/* $XConsortium: VendorEP.h,v 1.2 94/04/17 20:13:25 kaleb Exp $ */
+
+/*
+ * Copyright 1991 by OMRON Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, 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 OMRON not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. OMRON makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * OMRON 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 TORTUOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Author: Seiji Kuwari OMRON Corporation
+ * kuwa@omron.co.jp
+ * kuwa%omron.co.jp@uunet.uu.net
+ */
+
+/*
+
+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.
+
+*/
+
+#ifndef _VendorEP_h
+#define _VendorEP_h
+
+#include <X11/Xaw3d/XawImP.h>
+
+typedef struct {
+ XtPointer extension;
+} XawVendorShellExtClassPart;
+
+typedef struct _VendorShellExtClassRec {
+ ObjectClassPart object_class;
+ XawVendorShellExtClassPart vendor_shell_ext_class;
+} XawVendorShellExtClassRec;
+
+typedef struct {
+ Widget parent;
+ XawImPart im;
+ XawIcPart ic;
+} XawVendorShellExtPart;
+
+typedef struct XawVendorShellExtRec {
+ ObjectPart object;
+ XawVendorShellExtPart vendor_ext;
+} XawVendorShellExtRec, *XawVendorShellExtWidget;
+
+#endif /* _VendorEP_h */
diff --git a/src/Viewport.c b/src/Viewport.c
new file mode 100644
index 0000000..b257cd3
--- /dev/null
+++ b/src/Viewport.c
@@ -0,0 +1,1200 @@
+/* $XConsortium: Viewport.c,v 1.71 94/04/17 20:13:26 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.
+
+******************************************************************/
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+
+#include <X11/Xaw3d/XawInit.h>
+#include <X11/Xmu/Misc.h>
+#include <X11/Xaw3d/Scrollbar.h>
+#include <X11/Xaw3d/ViewportP.h>
+
+static void ScrollUpDownProc(), ThumbProc();
+static Boolean GetGeometry();
+
+static void ComputeWithForceBars();
+
+#define offset(field) XtOffsetOf(ViewportRec, viewport.field)
+static XtResource resources[] = {
+ {XtNforceBars, XtCBoolean, XtRBoolean, sizeof(Boolean),
+ offset(forcebars), XtRImmediate, (XtPointer)False},
+ {XtNallowHoriz, XtCBoolean, XtRBoolean, sizeof(Boolean),
+ offset(allowhoriz), XtRImmediate, (XtPointer)False},
+ {XtNallowVert, XtCBoolean, XtRBoolean, sizeof(Boolean),
+ offset(allowvert), XtRImmediate, (XtPointer)False},
+ {XtNuseBottom, XtCBoolean, XtRBoolean, sizeof(Boolean),
+ offset(usebottom), XtRImmediate, (XtPointer)False},
+ {XtNuseRight, XtCBoolean, XtRBoolean, sizeof(Boolean),
+ offset(useright), XtRImmediate, (XtPointer)False},
+ {XtNreportCallback, XtCReportCallback, XtRCallback, sizeof(XtPointer),
+ offset(report_callbacks), XtRImmediate, (XtPointer) NULL},
+};
+#undef offset
+
+static void Initialize(), ConstraintInitialize(),
+ Realize(), Resize(), ChangeManaged();
+static Boolean SetValues(), Layout();
+static XtGeometryResult GeometryManager(), PreferredGeometry();
+
+#define superclass (&formClassRec)
+ViewportClassRec viewportClassRec = {
+ { /* core_class fields */
+ /* superclass */ (WidgetClass) superclass,
+ /* class_name */ "Viewport",
+ /* widget_size */ sizeof(ViewportRec),
+ /* class_initialize */ XawInitializeWidgetSet,
+ /* class_part_init */ NULL,
+ /* class_inited */ FALSE,
+ /* initialize */ Initialize,
+ /* initialize_hook */ NULL,
+ /* realize */ Realize,
+ /* 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 */ NULL,
+ /* resize */ Resize,
+ /* expose */ XtInheritExpose,
+ /* 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 */ PreferredGeometry,
+ /* display_accelerator*/ XtInheritDisplayAccelerator,
+ /* extension */ NULL
+ },
+ { /* composite_class fields */
+ /* geometry_manager */ GeometryManager,
+ /* change_managed */ ChangeManaged,
+ /* insert_child */ XtInheritInsertChild,
+ /* delete_child */ XtInheritDeleteChild,
+ /* extension */ NULL
+ },
+ { /* constraint_class fields */
+ /* subresourses */ NULL,
+ /* subresource_count */ 0,
+ /* constraint_size */ sizeof(ViewportConstraintsRec),
+ /* initialize */ ConstraintInitialize,
+ /* destroy */ NULL,
+ /* set_values */ NULL,
+ /* extension */ NULL
+ },
+ { /* form_class fields */
+ /* layout */ Layout
+ },
+ { /* viewport_class fields */
+ /* empty */ 0
+ }
+};
+
+
+WidgetClass viewportWidgetClass = (WidgetClass)&viewportClassRec;
+
+static Widget CreateScrollbar(w, horizontal)
+ ViewportWidget w;
+ Boolean horizontal;
+{
+ Widget clip = w->viewport.clip;
+ ViewportConstraints constraints =
+ (ViewportConstraints)clip->core.constraints;
+ static Arg barArgs[] = {
+ {XtNorientation, (XtArgVal) 0},
+ {XtNlength, (XtArgVal) 0},
+ {XtNleft, (XtArgVal) 0},
+ {XtNright, (XtArgVal) 0},
+ {XtNtop, (XtArgVal) 0},
+ {XtNbottom, (XtArgVal) 0},
+ {XtNmappedWhenManaged, (XtArgVal) False},
+ };
+ Widget bar;
+
+ XtSetArg(barArgs[0], XtNorientation,
+ horizontal ? XtorientHorizontal : XtorientVertical );
+ XtSetArg(barArgs[1], XtNlength,
+ horizontal ? clip->core.width : clip->core.height);
+ XtSetArg(barArgs[2], XtNleft,
+ (!horizontal && w->viewport.useright) ? XtChainRight : XtChainLeft);
+ XtSetArg(barArgs[3], XtNright,
+ (!horizontal && !w->viewport.useright) ? XtChainLeft : XtChainRight);
+ XtSetArg(barArgs[4], XtNtop,
+ (horizontal && w->viewport.usebottom) ? XtChainBottom : XtChainTop);
+ XtSetArg(barArgs[5], XtNbottom,
+ (horizontal && !w->viewport.usebottom) ? XtChainTop : XtChainBottom);
+
+ bar = XtCreateWidget((horizontal ? "horizontal" : "vertical"),
+ scrollbarWidgetClass, (Widget)w,
+ barArgs, XtNumber(barArgs) );
+ XtAddCallback( bar, XtNscrollProc, ScrollUpDownProc, (XtPointer)w );
+ XtAddCallback( bar, XtNjumpProc, ThumbProc, (XtPointer)w );
+
+ if (horizontal) {
+ w->viewport.horiz_bar = bar;
+ constraints->form.vert_base = bar;
+ }
+ else {
+ w->viewport.vert_bar = bar;
+ constraints->form.horiz_base = bar;
+ }
+
+ XtManageChild( bar );
+
+ return bar;
+}
+
+/* ARGSUSED */
+static void Initialize(request, new, args, num_args)
+ Widget request, new;
+ ArgList args;
+ Cardinal *num_args;
+{
+ ViewportWidget w = (ViewportWidget)new;
+ static Arg clip_args[8];
+ static Arg threeD_args[8];
+ Cardinal arg_cnt;
+ Widget h_bar, v_bar;
+ Dimension clip_height, clip_width;
+ Dimension pad = 0, sw = 0;
+
+ w->form.default_spacing = 0; /* Reset the default spacing to 0 pixels. */
+
+
+/*
+ * Initialize all widget pointers to NULL.
+ */
+
+ w->viewport.child = (Widget) NULL;
+ w->viewport.horiz_bar = w->viewport.vert_bar = (Widget)NULL;
+
+/*
+ * Create 3D Widget.
+ */
+
+ arg_cnt = 0;
+ XtSetArg(threeD_args[arg_cnt], XtNleft, XtChainLeft); arg_cnt++;
+ XtSetArg(threeD_args[arg_cnt], XtNright, XtChainRight); arg_cnt++;
+ XtSetArg(threeD_args[arg_cnt], XtNtop, XtChainTop); arg_cnt++;
+ XtSetArg(threeD_args[arg_cnt], XtNbottom, XtChainBottom); arg_cnt++;
+ XtSetArg(threeD_args[arg_cnt], XtNwidth, w->core.width); arg_cnt++;
+ XtSetArg(threeD_args[arg_cnt], XtNheight, w->core.height); arg_cnt++;
+ XtSetArg(threeD_args[arg_cnt], XtNrelief, XtReliefSunken); arg_cnt++;
+ w->viewport.threeD =
+ (ThreeDWidget)XtCreateManagedWidget("threeD", threeDWidgetClass, new,
+ threeD_args, arg_cnt);
+ XtVaGetValues((Widget)(w->viewport.threeD), XtNshadowWidth, &sw, NULL);
+ if (sw)
+ {
+ pad = 2;
+
+ arg_cnt = 0;
+ XtSetArg(threeD_args[arg_cnt], XtNborderWidth, 0); arg_cnt++;
+ XtSetValues((Widget)w, threeD_args, arg_cnt);
+ }
+
+/*
+ * Create Clip Widget.
+ */
+
+ arg_cnt = 0;
+ XtSetArg(clip_args[arg_cnt], XtNbackgroundPixmap, None); arg_cnt++;
+ XtSetArg(clip_args[arg_cnt], XtNborderWidth, 0); arg_cnt++;
+ XtSetArg(clip_args[arg_cnt], XtNleft, XtChainLeft); arg_cnt++;
+ XtSetArg(clip_args[arg_cnt], XtNright, XtChainRight); arg_cnt++;
+ XtSetArg(clip_args[arg_cnt], XtNtop, XtChainTop); arg_cnt++;
+ XtSetArg(clip_args[arg_cnt], XtNbottom, XtChainBottom); arg_cnt++;
+ XtSetArg(clip_args[arg_cnt], XtNwidth, w->core.width - 2 * sw); arg_cnt++;
+ XtSetArg(clip_args[arg_cnt], XtNheight, w->core.height - 2 * sw); arg_cnt++;
+
+ w->viewport.clip = XtCreateManagedWidget("clip", widgetClass, new,
+ clip_args, arg_cnt);
+
+ if (!w->viewport.forcebars)
+ return; /* If we are not forcing the bars then we are done. */
+
+ if (w->viewport.allowhoriz)
+ (void) CreateScrollbar(w, True);
+ if (w->viewport.allowvert)
+ (void) CreateScrollbar(w, False);
+
+ h_bar = w->viewport.horiz_bar;
+ v_bar = w->viewport.vert_bar;
+
+/*
+ * Set the clip widget to the correct height.
+ */
+
+ clip_width = w->core.width - 2 * sw;
+ clip_height = w->core.height - 2 * sw;
+
+ if ( (h_bar != NULL) &&
+ ((int)w->core.width >
+ (int)(h_bar->core.width + h_bar->core.border_width + pad)) )
+ clip_width -= h_bar->core.width + h_bar->core.border_width + pad;
+
+ if ( (v_bar != NULL) &&
+ ((int)w->core.height >
+ (int)(v_bar->core.height + v_bar->core.border_width + pad)) )
+ clip_height -= v_bar->core.height + v_bar->core.border_width + pad;
+
+ arg_cnt = 0;
+ XtSetArg(clip_args[arg_cnt], XtNwidth, clip_width); arg_cnt++;
+ XtSetArg(clip_args[arg_cnt], XtNheight, clip_height); arg_cnt++;
+ XtSetValues(w->viewport.clip, clip_args, arg_cnt);
+}
+
+/* ARGSUSED */
+static void ConstraintInitialize(request, new, args, num_args)
+ Widget request, new;
+ ArgList args;
+ Cardinal *num_args;
+{
+ ((ViewportConstraints)new->core.constraints)->viewport.reparented = False;
+}
+
+static void Realize(widget, value_mask, attributes)
+ Widget widget;
+ XtValueMask *value_mask;
+ XSetWindowAttributes *attributes;
+{
+ ViewportWidget w = (ViewportWidget)widget;
+ Widget child = w->viewport.child;
+ Widget clip = w->viewport.clip;
+ Widget threeD = (Widget)w->viewport.threeD;
+
+ *value_mask |= CWBitGravity;
+ attributes->bit_gravity = NorthWestGravity;
+ (*superclass->core_class.realize)(widget, value_mask, attributes);
+
+ (*w->core.widget_class->core_class.resize)(widget); /* turn on bars */
+
+ if (child != (Widget)NULL) {
+ XtMoveWidget( child, (Position)0, (Position)0 );
+ XtRealizeWidget( clip );
+ XtRealizeWidget( child );
+ XtRealizeWidget( threeD );
+ XLowerWindow( XtDisplay(threeD), XtWindow(threeD) );
+ XReparentWindow( XtDisplay(w), XtWindow(child), XtWindow(clip),
+ (Position)0, (Position)0 );
+ XtMapWidget( child );
+ }
+}
+
+/* ARGSUSED */
+static Boolean SetValues(current, request, new, args, num_args)
+ Widget current, request, new;
+ ArgList args;
+ Cardinal *num_args;
+{
+ ViewportWidget w = (ViewportWidget)new;
+ ViewportWidget cw = (ViewportWidget)current;
+
+ if ( (w->viewport.forcebars != cw->viewport.forcebars) ||
+ (w->viewport.allowvert != cw->viewport.allowvert) ||
+ (w->viewport.allowhoriz != cw->viewport.allowhoriz) ||
+ (w->viewport.useright != cw->viewport.useright) ||
+ (w->viewport.usebottom != cw->viewport.usebottom) )
+ {
+ (*w->core.widget_class->core_class.resize)(new); /* Recompute layout.*/
+ }
+
+ return False;
+}
+
+
+static void ChangeManaged(widget)
+ Widget widget;
+{
+ ViewportWidget w = (ViewportWidget)widget;
+ int num_children = w->composite.num_children;
+ Widget child, *childP;
+ int i;
+
+ child = (Widget)NULL;
+ for (childP=w->composite.children, i=0; i < num_children; childP++, i++) {
+ if (XtIsManaged(*childP)
+ && *childP != w->viewport.clip
+ && *childP != w->viewport.horiz_bar
+ && *childP != w->viewport.vert_bar
+ && *childP != (Widget)w->viewport.threeD)
+ {
+ child = *childP;
+ break;
+ }
+ }
+
+ if (child != w->viewport.child) {
+ w->viewport.child = child;
+ if (child != (Widget)NULL) {
+ XtResizeWidget( child, child->core.width,
+ child->core.height, (Dimension)0 );
+ if (XtIsRealized(widget)) {
+ ViewportConstraints constraints =
+ (ViewportConstraints)child->core.constraints;
+ if (!XtIsRealized(child)) {
+ Window window = XtWindow(w);
+ XtMoveWidget( child, (Position)0, (Position)0 );
+#ifdef notdef
+ /* this is dirty, but it saves the following code: */
+ XtRealizeWidget( child );
+ XReparentWindow( XtDisplay(w), XtWindow(child),
+ XtWindow(w->viewport.clip),
+ (Position)0, (Position)0 );
+ if (child->core.mapped_when_managed)
+ XtMapWidget( child );
+#else
+ w->core.window = XtWindow(w->viewport.clip);
+ XtRealizeWidget( child );
+ w->core.window = window;
+#endif /* notdef */
+ constraints->viewport.reparented = True;
+ }
+ else if (!constraints->viewport.reparented) {
+ XReparentWindow( XtDisplay(w), XtWindow(child),
+ XtWindow(w->viewport.clip),
+ (Position)0, (Position)0 );
+ constraints->viewport.reparented = True;
+ if (child->core.mapped_when_managed)
+ XtMapWidget( child );
+ }
+ }
+ GetGeometry( widget, child->core.width, child->core.height );
+ (*((ViewportWidgetClass)w->core.widget_class)->form_class.layout)
+ ( (FormWidget)w, w->core.width, w->core.height );
+ /* %%% do we need to hide this child from Form? */
+ }
+ }
+
+#ifdef notdef
+ (*superclass->composite_class.change_managed)( widget );
+#endif
+}
+
+
+static void SetBar(w, top, length, total)
+ Widget w;
+ Position top;
+ Dimension length, total;
+{
+ XawScrollbarSetThumb(w, (float)top/(float)total,
+ (float)length/(float)total);
+}
+
+static void RedrawThumbs(w)
+ ViewportWidget w;
+{
+ Widget child = w->viewport.child;
+ Widget clip = w->viewport.clip;
+
+ if (w->viewport.horiz_bar != (Widget)NULL)
+ SetBar( w->viewport.horiz_bar, -(child->core.x),
+ clip->core.width, child->core.width );
+
+ if (w->viewport.vert_bar != (Widget)NULL)
+ SetBar( w->viewport.vert_bar, -(child->core.y),
+ clip->core.height, child->core.height );
+}
+
+
+
+static void SendReport (w, changed)
+ ViewportWidget w;
+ unsigned int changed;
+{
+ XawPannerReport rep;
+
+ if (w->viewport.report_callbacks) {
+ Widget child = w->viewport.child;
+ Widget clip = w->viewport.clip;
+
+ rep.changed = changed;
+ rep.slider_x = -child->core.x; /* child is canvas */
+ rep.slider_y = -child->core.y; /* clip is slider */
+ rep.slider_width = clip->core.width;
+ rep.slider_height = clip->core.height;
+ rep.canvas_width = child->core.width;
+ rep.canvas_height = child->core.height;
+ XtCallCallbackList ((Widget) w, w->viewport.report_callbacks,
+ (XtPointer) &rep);
+ }
+}
+
+
+static void MoveChild(w, x, y)
+ ViewportWidget w;
+ Position x, y;
+{
+ Widget child = w->viewport.child;
+ Widget clip = w->viewport.clip;
+
+ /* make sure we never move past right/bottom borders */
+ if (-x + (int)clip->core.width > (int)child->core.width)
+ x = -(child->core.width - clip->core.width);
+
+ if (-y + (int)clip->core.height > (int)child->core.height)
+ y = -(child->core.height - clip->core.height);
+
+ /* make sure we never move past left/top borders */
+ if (x >= 0) x = 0;
+ if (y >= 0) y = 0;
+
+ XtMoveWidget(child, x, y);
+ SendReport (w, (XawPRSliderX | XawPRSliderY));
+
+ RedrawThumbs(w);
+}
+
+
+static void ComputeLayout(widget, query, destroy_scrollbars)
+ Widget widget; /* Viewport */
+ Boolean query; /* query child's preferred geom? */
+ Boolean destroy_scrollbars; /* destroy un-needed scrollbars? */
+{
+ ViewportWidget w = (ViewportWidget)widget;
+ Widget child = w->viewport.child;
+ Widget clip = w->viewport.clip;
+ Widget threeD = (Widget)w->viewport.threeD;
+ ViewportConstraints constraints
+ = (ViewportConstraints)clip->core.constraints;
+ Boolean needshoriz, needsvert;
+ int clip_width, clip_height;
+ int bar_width, bar_height;
+ XtWidgetGeometry intended;
+ Dimension pad = 0, sw = 0;
+
+ /*
+ * I've made two optimizations here. The first does away with the
+ * loop, and the second defers setting the child dimensions to the
+ * clip if smaller until after adjusting for possible scrollbars.
+ * If you find that these go too far, define the identifiers here
+ * as required. -- djhjr
+ */
+#define NEED_LAYOUT_LOOP
+#undef PREP_CHILD_TO_CLIP
+
+ if (child == (Widget) NULL) return;
+
+ XtVaGetValues(threeD, XtNshadowWidth, &sw, NULL);
+ if (sw) pad = 2;
+
+ clip_width = w->core.width - 2 * sw;
+ clip_height = w->core.height - 2 * sw;
+ intended.request_mode = CWBorderWidth;
+ intended.border_width = 0;
+
+ if (w->viewport.forcebars) {
+ needsvert = w->viewport.allowvert;
+ needshoriz = w->viewport.allowhoriz;
+ ComputeWithForceBars(widget, query, &intended,
+ &clip_width, &clip_height);
+ }
+ else {
+#ifdef NEED_LAYOUT_LOOP
+ Dimension prev_width, prev_height;
+ XtGeometryMask prev_mode;
+#endif
+ XtWidgetGeometry preferred;
+
+ needshoriz = needsvert = False;
+
+ /*
+ * intended.{width,height} caches the eventual child dimensions,
+ * but we don't set the mode bits until after we decide that the
+ * child's preferences are not acceptable.
+ */
+
+ if (!w->viewport.allowhoriz)
+ intended.request_mode |= CWWidth;
+
+#ifdef PREP_CHILD_TO_CLIP
+ if ((int)child->core.width < clip_width)
+ intended.width = clip_width;
+ else
+#endif
+ intended.width = child->core.width;
+
+ if (!w->viewport.allowvert)
+ intended.request_mode |= CWHeight;
+
+#ifdef PREP_CHILD_TO_CLIP
+ if ((int)child->core.height < clip_height)
+ intended.height = clip_height;
+ else
+#endif
+ intended.height = child->core.height;
+
+ if (!query) {
+ preferred.width = child->core.width;
+ preferred.height = child->core.height;
+ }
+
+#ifdef NEED_LAYOUT_LOOP
+ do { /* while intended != prev */
+#endif
+ if (query) {
+ (void) XtQueryGeometry( child, &intended, &preferred );
+ if ( !(preferred.request_mode & CWWidth) )
+ preferred.width = intended.width;
+ if ( !(preferred.request_mode & CWHeight) )
+ preferred.height = intended.height;
+ }
+
+#ifdef NEED_LAYOUT_LOOP
+ prev_width = intended.width;
+ prev_height = intended.height;
+ prev_mode = intended.request_mode;
+#endif
+
+ /*
+ * Note that having once decided to turn on either bar
+ * we'll not change our mind until we're next resized,
+ * thus avoiding potential oscillations.
+ */
+
+#define CheckHoriz() \
+ if (w->viewport.allowhoriz && \
+ (int)preferred.width > clip_width + 2 * sw) { \
+ if (!needshoriz) { \
+ Widget bar = w->viewport.horiz_bar; \
+ needshoriz = True; \
+ if (bar == (Widget)NULL) \
+ bar = CreateScrollbar(w, True); \
+ clip_height -= bar->core.height + \
+ bar->core.border_width + pad; \
+ if (clip_height < 1) clip_height = 1; \
+ } \
+ intended.width = preferred.width; \
+ }
+/* enddef */
+ CheckHoriz();
+ if (w->viewport.allowvert &&
+ (int)preferred.height > clip_height + 2 * sw) {
+ if (!needsvert) {
+ Widget bar = w->viewport.vert_bar;
+ needsvert = True;
+ if (bar == (Widget)NULL)
+ bar = CreateScrollbar(w, False);
+ clip_width -= bar->core.width +
+ bar->core.border_width + pad;
+ if (clip_width < 1) clip_width = 1;
+ if (!needshoriz) CheckHoriz();
+ }
+ intended.height = preferred.height;
+ }
+
+#ifdef PREP_CHILD_TO_CLIP
+ if (!w->viewport.allowhoriz ||
+ (int)preferred.width < clip_width) {
+ intended.width = clip_width;
+ intended.request_mode |= CWWidth;
+ }
+ if (!w->viewport.allowvert ||
+ (int)preferred.height < clip_height) {
+ intended.height = clip_height;
+ intended.request_mode |= CWHeight;
+ }
+#endif
+#ifdef NEED_LAYOUT_LOOP
+ } while ( intended.request_mode != prev_mode ||
+ (intended.request_mode & CWWidth &&
+ intended.width != prev_width) ||
+ (intended.request_mode & CWHeight &&
+ intended.height != prev_height) );
+#endif
+
+#ifndef PREP_CHILD_TO_CLIP
+ if (!w->viewport.allowhoriz ||
+ (int)preferred.width < clip_width) {
+ intended.width = clip_width;
+ intended.request_mode |= CWWidth;
+ }
+ if (!w->viewport.allowvert ||
+ (int)preferred.height < clip_height) {
+ intended.height = clip_height;
+ intended.request_mode |= CWHeight;
+ }
+#endif
+ }
+
+ bar_width = bar_height = 0;
+ if (needsvert)
+ bar_width = w->viewport.vert_bar->core.width +
+ w->viewport.vert_bar->core.border_width + pad;
+ if (needshoriz)
+ bar_height = w->viewport.horiz_bar->core.height +
+ w->viewport.horiz_bar->core.border_width + pad;
+
+ if (XtIsRealized(threeD))
+ XLowerWindow( XtDisplay(threeD), XtWindow(threeD) );
+
+ XtMoveWidget( threeD,
+ (Position)(!needsvert ? 0 :
+ (w->viewport.useright ? 0 : bar_width)),
+ (Position)(!needshoriz ? 0 :
+ (w->viewport.usebottom ? 0 : bar_height)) );
+ XtResizeWidget( threeD, (Dimension)(w->core.width - bar_width),
+ (Dimension)(w->core.height - bar_height), (Dimension)0 );
+
+ if (XtIsRealized(clip))
+ XRaiseWindow( XtDisplay(clip), XtWindow(clip) );
+
+ XtMoveWidget( clip,
+ (Position)(!needsvert ? sw :
+ (w->viewport.useright ? sw : bar_width + sw)),
+ (Position)(!needshoriz ? sw :
+ (w->viewport.usebottom ? sw : bar_height + sw)) );
+ XtResizeWidget( clip, (Dimension)clip_width, (Dimension)clip_height,
+ (Dimension)0 );
+
+ if (w->viewport.horiz_bar != (Widget)NULL) {
+ Widget bar = w->viewport.horiz_bar;
+ if (!needshoriz) {
+ constraints->form.vert_base = (Widget)NULL;
+ if (destroy_scrollbars) {
+ XtDestroyWidget( bar );
+ w->viewport.horiz_bar = (Widget)NULL;
+ }
+ }
+ else {
+ int bw = bar->core.border_width;
+ XtResizeWidget( bar,
+ (Dimension)(clip_width + 2 * sw), bar->core.height,
+ (Dimension)bw );
+ XtMoveWidget( bar,
+ (Position)((needsvert && !w->viewport.useright)
+ ? w->viewport.vert_bar->core.width + pad
+ : -bw),
+ (Position)(w->viewport.usebottom
+ ? w->core.height - bar->core.height - bw
+ : -bw) );
+ XtSetMappedWhenManaged( bar, True );
+ }
+ }
+
+ if (w->viewport.vert_bar != (Widget)NULL) {
+ Widget bar = w->viewport.vert_bar;
+ if (!needsvert) {
+ constraints->form.horiz_base = (Widget)NULL;
+ if (destroy_scrollbars) {
+ XtDestroyWidget( bar );
+ w->viewport.vert_bar = (Widget)NULL;
+ }
+ }
+ else {
+ int bw = bar->core.border_width;
+ XtResizeWidget( bar,
+ bar->core.width, (Dimension)(clip_height + 2 * sw),
+ (Dimension)bw );
+ XtMoveWidget( bar,
+ (Position)(w->viewport.useright
+ ? w->core.width - bar->core.width - bw
+ : -bw),
+ (Position)((needshoriz && !w->viewport.usebottom)
+ ? w->viewport.horiz_bar->core.height + pad
+ : -bw) );
+ XtSetMappedWhenManaged( bar, True );
+ }
+ }
+
+ if (child != (Widget)NULL) {
+ XtResizeWidget( child, (Dimension)intended.width,
+ (Dimension)intended.height, (Dimension)0 );
+ MoveChild(w,
+ needshoriz ? child->core.x : 0,
+ needsvert ? child->core.y : 0);
+ }
+
+ SendReport (w, XawPRAll);
+}
+
+/* Function Name: ComputeWithForceBars
+ * Description: Computes the layout give forcebars is set.
+ * Arguments: widget - the viewport widget.
+ * query - whether or not to query the child.
+ * intended - the cache of the childs height is
+ * stored here ( USED AND RETURNED ).
+ * clip_width, clip_height - size of clip window.
+ * (USED AND RETURNED ).
+ * Returns: none.
+ */
+
+static void
+ComputeWithForceBars(widget, query, intended, clip_width, clip_height)
+Widget widget;
+Boolean query;
+XtWidgetGeometry * intended;
+int *clip_width, *clip_height;
+{
+ ViewportWidget w = (ViewportWidget)widget;
+ Widget child = w->viewport.child;
+ XtWidgetGeometry preferred;
+ Dimension pad = 0, sw = 0;
+
+/*
+ * If forcebars then needs = allows = has.
+ * Thus if needsvert is set it MUST have a scrollbar.
+ */
+
+ XtVaGetValues((Widget)(w->viewport.threeD), XtNshadowWidth, &sw, NULL);
+ if (sw) pad = 2;
+
+ if (w->viewport.allowvert) {
+ if (w->viewport.vert_bar == NULL)
+ w->viewport.vert_bar = CreateScrollbar(w, False);
+
+ *clip_width -= w->viewport.vert_bar->core.width +
+ w->viewport.vert_bar->core.border_width + pad;
+ }
+
+ if (w->viewport.allowhoriz) {
+ if (w->viewport.horiz_bar == NULL)
+ w->viewport.horiz_bar = CreateScrollbar(w, True);
+
+ *clip_height -= w->viewport.horiz_bar->core.height +
+ w->viewport.horiz_bar->core.border_width + pad;
+ }
+
+ AssignMax( *clip_width, 1 );
+ AssignMax( *clip_height, 1 );
+
+ if (!w->viewport.allowvert) {
+ intended->height = *clip_height;
+ intended->request_mode |= CWHeight;
+ }
+ if (!w->viewport.allowhoriz) {
+ intended->width = *clip_width;
+ intended->request_mode |= CWWidth;
+ }
+
+ if ( query ) {
+ if ( (w->viewport.allowvert || w->viewport.allowhoriz) ) {
+ XtQueryGeometry( child, intended, &preferred );
+
+ if ( !(intended->request_mode & CWWidth) )
+ if ( preferred.request_mode & CWWidth )
+ intended->width = preferred.width;
+ else
+ intended->width = child->core.width;
+
+ if ( !(intended->request_mode & CWHeight) )
+ if ( preferred.request_mode & CWHeight )
+ intended->height = preferred.height;
+ else
+ intended->height = child->core.height;
+ }
+ }
+ else {
+ if (w->viewport.allowvert)
+ intended->height = child->core.height;
+ if (w->viewport.allowhoriz)
+ intended->width = child->core.width;
+ }
+
+ if (*clip_width > (int)intended->width)
+ intended->width = *clip_width;
+ if (*clip_height > (int)intended->height)
+ intended->height = *clip_height;
+}
+
+static void Resize(widget)
+ Widget widget;
+{
+ ComputeLayout( widget, /*query=*/True, /*destroy=*/True );
+}
+
+
+/* ARGSUSED */
+static Boolean Layout(w, width, height)
+ FormWidget w;
+ Dimension width, height;
+{
+ ComputeLayout( (Widget)w, /*query=*/True, /*destroy=*/True );
+ w->form.preferred_width = w->core.width;
+ w->form.preferred_height = w->core.height;
+ return False;
+}
+
+
+static void ScrollUpDownProc(widget, closure, call_data)
+ Widget widget;
+ XtPointer closure;
+ XtPointer call_data;
+{
+ ViewportWidget w = (ViewportWidget)closure;
+ Widget child = w->viewport.child;
+ int pix = (int)call_data;
+ Position x, y;
+
+ if (child == NULL) return; /* no child to scroll. */
+
+ x = child->core.x - ((widget == w->viewport.horiz_bar) ? pix : 0);
+ y = child->core.y - ((widget == w->viewport.vert_bar) ? pix : 0);
+ MoveChild(w, x, y);
+}
+
+
+/* ARGSUSED */
+static void ThumbProc(widget, closure, call_data)
+ Widget widget;
+ XtPointer closure;
+ XtPointer call_data;
+{
+ ViewportWidget w = (ViewportWidget)closure;
+ Widget child = w->viewport.child;
+ float *percent = (float *) call_data;
+ Position x, y;
+
+ if (child == NULL) return; /* no child to scroll. */
+
+ if (widget == w->viewport.horiz_bar)
+#ifdef macII /* bug in the macII A/UX 1.0 cc */
+ x = (int)(-*percent * child->core.width);
+#else /* else not macII */
+ x = -(int)(*percent * child->core.width);
+#endif /* macII */
+ else
+ x = child->core.x;
+
+ if (widget == w->viewport.vert_bar)
+#ifdef macII /* bug in the macII A/UX 1.0 cc */
+ y = (int)(-*percent * child->core.height);
+#else /* else not macII */
+ y = -(int)(*percent * child->core.height);
+#endif /* macII */
+ else
+ y = child->core.y;
+
+ MoveChild(w, x, y);
+}
+
+static XtGeometryResult
+TestSmaller(w, request, reply_return)
+ ViewportWidget w; XtWidgetGeometry *request, *reply_return;
+{
+ if (request->width < w->core.width || request->height < w->core.height)
+ return XtMakeGeometryRequest((Widget)w, request, reply_return);
+ else
+ return XtGeometryYes;
+}
+
+static XtGeometryResult
+GeometryRequestPlusScrollbar(w, horizontal, request, reply_return)
+ Boolean horizontal;
+ ViewportWidget w;
+ XtWidgetGeometry *request, *reply_return;
+{
+ Widget bar;
+ XtWidgetGeometry plusScrollbars;
+ Dimension pad = 0, sw = 0;
+
+ XtVaGetValues((Widget)(w->viewport.threeD), XtNshadowWidth, &sw, NULL);
+ if (sw) pad = 2;
+
+ plusScrollbars = *request;
+ if ((bar = w->viewport.horiz_bar) == (Widget)NULL)
+ bar = CreateScrollbar(w, horizontal);
+ request->width += bar->core.width + pad;
+ request->height += bar->core.height + pad;
+ XtDestroyWidget(bar);
+ return XtMakeGeometryRequest((Widget) w, &plusScrollbars, reply_return);
+ }
+
+#define WidthChange() (request->width != w->core.width)
+#define HeightChange() (request->height != w->core.height)
+
+static XtGeometryResult
+QueryGeometry(w, request, reply_return)
+ ViewportWidget w; XtWidgetGeometry *request, *reply_return;
+{
+ if (w->viewport.allowhoriz && w->viewport.allowvert)
+ return TestSmaller(w, request, reply_return);
+
+ else if (w->viewport.allowhoriz && !w->viewport.allowvert) {
+ if (WidthChange() && !HeightChange())
+ return TestSmaller(w, request, reply_return);
+ else if (!WidthChange() && HeightChange())
+ return XtMakeGeometryRequest((Widget) w, request, reply_return);
+ else if (WidthChange() && HeightChange()) /* hard part */
+ return GeometryRequestPlusScrollbar(w, True, request, reply_return);
+ else /* !WidthChange() && !HeightChange() */
+ return XtGeometryYes;
+ }
+ else if (!w->viewport.allowhoriz && w->viewport.allowvert) {
+ if (!WidthChange() && HeightChange())
+ return TestSmaller(w, request, reply_return);
+ else if (WidthChange() && !HeightChange())
+ return XtMakeGeometryRequest((Widget)w, request, reply_return);
+ else if (WidthChange() && HeightChange()) /* hard part */
+ return GeometryRequestPlusScrollbar(w, False, request, reply_return);
+ else /* !WidthChange() && !HeightChange() */
+ return XtGeometryYes;
+ }
+ else /* (!w->viewport.allowhoriz && !w->viewport.allowvert) */
+ return XtMakeGeometryRequest((Widget) w, request, reply_return);
+}
+
+#undef WidthChange
+#undef HeightChange
+
+static XtGeometryResult GeometryManager(child, request, reply)
+ Widget child;
+ XtWidgetGeometry *request, *reply;
+{
+ ViewportWidget w = (ViewportWidget)child->core.parent;
+ Boolean rWidth = (Boolean)(request->request_mode & CWWidth);
+ Boolean rHeight = (Boolean)(request->request_mode & CWHeight);
+ XtWidgetGeometry allowed;
+ XtGeometryResult result;
+ Boolean reconfigured;
+ Boolean child_changed_size;
+ Dimension height_remaining;
+ Dimension pad = 0, sw = 0;
+
+ if (request->request_mode & XtCWQueryOnly)
+ return QueryGeometry(w, request, reply);
+
+ if (child != w->viewport.child
+ || request->request_mode & ~(CWWidth | CWHeight
+ | CWBorderWidth)
+ || ((request->request_mode & CWBorderWidth)
+ && request->border_width > 0))
+ return XtGeometryNo;
+
+ XtVaGetValues((Widget)(w->viewport.threeD), XtNshadowWidth, &sw, NULL);
+ if (sw) pad = 2;
+
+ allowed = *request;
+
+ reconfigured = GetGeometry( (Widget)w,
+ (rWidth ? request->width : w->core.width),
+ (rHeight ? request->height : w->core.height)
+ );
+
+ child_changed_size = ((rWidth && child->core.width != request->width) ||
+ (rHeight && child->core.height != request->height));
+
+ height_remaining = w->core.height;
+ if (rWidth && w->core.width != request->width) {
+ if (w->viewport.allowhoriz && request->width > w->core.width) {
+ /* horizontal scrollbar will be needed so possibly reduce height */
+ Widget bar;
+ if ((bar = w->viewport.horiz_bar) == (Widget)NULL)
+ bar = CreateScrollbar( w, True );
+ height_remaining -= bar->core.height +
+ bar->core.border_width + pad;
+ reconfigured = True;
+ }
+ else {
+ allowed.width = w->core.width;
+ }
+ }
+ if (rHeight && height_remaining != request->height) {
+ if (w->viewport.allowvert && request->height > height_remaining) {
+ /* vertical scrollbar will be needed, so possibly reduce width */
+ if (!w->viewport.allowhoriz || request->width < w->core.width) {
+ Widget bar;
+ if ((bar = w->viewport.vert_bar) == (Widget)NULL)
+ bar = CreateScrollbar( w, False );
+ if (!rWidth) {
+ allowed.width = w->core.width;
+ allowed.request_mode |= CWWidth;
+ }
+ if ( (int)allowed.width >
+ (int)(bar->core.width + bar->core.border_width + pad) )
+ allowed.width -= bar->core.width +
+ bar->core.border_width + pad;
+ else
+ allowed.width = 1;
+ reconfigured = True;
+ }
+ }
+ else {
+ allowed.height = height_remaining;
+ }
+ }
+
+ if (allowed.width != request->width || allowed.height != request->height) {
+ *reply = allowed;
+ result = XtGeometryAlmost;
+ }
+ else {
+ if (rWidth) child->core.width = request->width;
+ if (rHeight) child->core.height = request->height;
+ result = XtGeometryYes;
+ }
+
+ if (reconfigured || child_changed_size)
+ ComputeLayout( (Widget)w,
+ /*query=*/ False,
+ /*destroy=*/ (result == XtGeometryYes) ? True : False );
+
+ return result;
+ }
+
+
+static Boolean GetGeometry(w, width, height)
+ Widget w;
+ Dimension width, height;
+{
+ XtWidgetGeometry geometry, return_geom;
+ XtGeometryResult result;
+
+ if (width == w->core.width && height == w->core.height)
+ return False;
+
+ geometry.request_mode = CWWidth | CWHeight;
+ geometry.width = width;
+ geometry.height = height;
+
+ if (XtIsRealized(w)) {
+ if (((ViewportWidget)w)->viewport.allowhoriz && width > w->core.width)
+ geometry.width = w->core.width;
+ if (((ViewportWidget)w)->viewport.allowvert && height > w->core.height)
+ geometry.height = w->core.height;
+ } else {
+ /* This is the Realize call; we'll inherit a w&h iff none currently */
+ if (w->core.width != 0) {
+ if (w->core.height != 0) return False;
+ geometry.width = w->core.width;
+ }
+ if (w->core.height != 0) geometry.height = w->core.height;
+ }
+
+ result = XtMakeGeometryRequest(w, &geometry, &return_geom);
+ if (result == XtGeometryAlmost)
+ result = XtMakeGeometryRequest(w, &return_geom, (XtWidgetGeometry *)NULL);
+
+ return (result == XtGeometryYes);
+}
+
+static XtGeometryResult PreferredGeometry(w, constraints, reply)
+ Widget w;
+ XtWidgetGeometry *constraints, *reply;
+{
+ if (((ViewportWidget)w)->viewport.child != NULL)
+ return XtQueryGeometry( ((ViewportWidget)w)->viewport.child,
+ constraints, reply );
+ else
+ return XtGeometryYes;
+}
+
+
+void
+#if NeedFunctionPrototypes
+XawViewportSetLocation (Widget gw,
+#if NeedWidePrototypes
+ double xoff, double yoff)
+#else
+ float xoff, float yoff)
+#endif
+#else
+XawViewportSetLocation (gw, xoff, yoff)
+ Widget gw;
+ float xoff,yoff;
+#endif
+{
+ ViewportWidget w = (ViewportWidget) gw;
+ Widget child = w->viewport.child;
+ Position x, y;
+
+ if (xoff > 1.0) /* scroll to right */
+ x = child->core.width;
+ else if (xoff < 0.0) /* if the offset is < 0.0 nothing */
+ x = child->core.x;
+ else
+ x = (Position) (((float) child->core.width) * xoff);
+
+ if (yoff > 1.0)
+ y = child->core.height;
+ else if (yoff < 0.0)
+ y = child->core.y;
+ else
+ y = (Position) (((float) child->core.height) * yoff);
+
+ MoveChild (w, -x, -y);
+}
+
+void
+#if NeedFunctionPrototypes
+XawViewportSetCoordinates (Widget gw,
+#if NeedWidePrototypes
+ int x, int y)
+#else
+ Position x, Position y)
+#endif
+#else
+XawViewportSetCoordinates (gw, x, y)
+ Widget gw;
+ Position x, y;
+#endif
+{
+ ViewportWidget w = (ViewportWidget) gw;
+ Widget child = w->viewport.child;
+
+ if (x > (int)child->core.width)
+ x = child->core.width;
+ else if (x < 0)
+ x = child->core.x;
+
+ if (y > (int)child->core.height)
+ y = child->core.height;
+ else if (y < 0)
+ y = child->core.y;
+
+ MoveChild (w, -x, -y);
+}
+
diff --git a/src/Viewport.h b/src/Viewport.h
new file mode 100644
index 0000000..499905e
--- /dev/null
+++ b/src/Viewport.h
@@ -0,0 +1,124 @@
+/* $XConsortium: Viewport.h,v 1.23 94/04/17 20:13:27 kaleb Exp $ */
+
+/************************************************************
+
+Copyright (c) 1987, 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 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.
+
+********************************************************/
+
+#ifndef _XawViewport_h
+#define _XawViewport_h
+
+#include <X11/Xaw3d/Form.h>
+#include <X11/Xaw3d/Reports.h>
+
+/* Resources:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ allowHoriz Boolean Boolean False
+ allowVert Boolean Boolean False
+ background Background Pixel XtDefaultBackground
+ border BorderColor Pixel XtDefaultForeground
+ borderWidth BorderWidth Dimension 1
+ destroyCallback Callback Pointer NULL
+ foreceBars Boolean Boolean False
+ height Height Dimension 0
+ mappedWhenManaged MappedWhenManaged Boolean True
+ reportCallback ReportCallback Pointer NULL
+ sensitive Sensitive Boolean True
+ useBottom Boolean Boolean False
+ useRight Boolean Boolean False
+ width Width Dimension 0
+ x Position Position 0
+ y Position Position 0
+
+*/
+
+/* fields added to Form */
+#ifndef _XtStringDefs_h_
+#define XtNforceBars "forceBars"
+#define XtNallowHoriz "allowHoriz"
+#define XtNallowVert "allowVert"
+#define XtNuseBottom "useBottom"
+#define XtNuseRight "useRight"
+#endif
+
+extern WidgetClass viewportWidgetClass;
+
+typedef struct _ViewportClassRec *ViewportWidgetClass;
+typedef struct _ViewportRec *ViewportWidget;
+
+_XFUNCPROTOBEGIN
+
+extern void XawViewportSetLocation (
+#if NeedFunctionPrototypes
+ Widget /* gw */,
+#if NeedWidePrototypes
+ /* float */ double /* xoff */,
+ /* float */ double /* yoff */
+#else
+ float /* xoff */,
+ float /* yoff */
+#endif
+#endif
+);
+
+extern void XawViewportSetCoordinates (
+#if NeedFunctionPrototypes
+ Widget /* gw */,
+#if NeedWidePrototypes
+ /* Position */ int /* x */,
+ /* Position */ int /* y */
+#else
+ Position /* x */,
+ Position /* y */
+#endif
+#endif
+);
+
+_XFUNCPROTOEND
+
+#endif /* _XawViewport_h */
diff --git a/src/ViewportP.h b/src/ViewportP.h
new file mode 100644
index 0000000..20e279b
--- /dev/null
+++ b/src/ViewportP.h
@@ -0,0 +1,108 @@
+/*
+ * $XConsortium: ViewportP.h,v 1.14 94/04/17 20:13:28 jim Exp $
+ * Private declarations for ViewportWidgetClass
+ */
+
+/************************************************************
+
+Copyright (c) 1987 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 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.
+
+********************************************************/
+
+#ifndef _ViewportP_h
+#define _ViewportP_h
+
+#include <X11/Xaw3d/Viewport.h>
+#include <X11/Xaw3d/FormP.h>
+#include <X11/Xaw3d/ThreeDP.h>
+
+typedef struct {int empty;} ViewportClassPart;
+
+typedef struct _ViewportClassRec {
+ CoreClassPart core_class;
+ CompositeClassPart composite_class;
+ ConstraintClassPart constraint_class;
+ FormClassPart form_class;
+ ViewportClassPart viewport_class;
+} ViewportClassRec;
+
+extern ViewportClassRec viewportClassRec;
+
+typedef struct _ViewportPart {
+ /* resources */
+ Boolean forcebars; /* Whether we should always display */
+ /* the selected scrollbars. */
+ Boolean allowhoriz; /* Whether we allow horizontal scrollbars. */
+ Boolean allowvert; /* Whether we allow vertical scrollbars. */
+ Boolean usebottom; /* True iff horiz bars appear at bottom. */
+ Boolean useright; /* True iff vert bars appear at right. */
+ XtCallbackList report_callbacks; /* when size/position changes */
+ /* private state */
+ Widget clip, child; /* The clipping and (scrolled) child widgets */
+ Widget horiz_bar, vert_bar;/* What scrollbars we currently have. */
+ ThreeDWidget threeD;
+} ViewportPart;
+
+typedef struct _ViewportRec {
+ CorePart core;
+ CompositePart composite;
+ ConstraintPart constraint;
+ FormPart form;
+ ViewportPart viewport;
+} ViewportRec;
+
+typedef struct {
+ /* resources */
+
+ /* private state */
+ Boolean reparented; /* True if child has been re-parented */
+} ViewportConstraintsPart;
+
+typedef struct _ViewportConstraintsRec {
+ FormConstraintsPart form;
+ ViewportConstraintsPart viewport;
+} ViewportConstraintsRec, *ViewportConstraints;
+
+#endif /* _ViewportP_h */
diff --git a/src/Xaw3dP.c b/src/Xaw3dP.c
new file mode 100644
index 0000000..b3b26f7
--- /dev/null
+++ b/src/Xaw3dP.c
@@ -0,0 +1,212 @@
+/*
+ * Xaw3dP.c
+ *
+ * Global functions that don't really belong anywhere else.
+ */
+
+/*********************************************************************
+Copyright (C) 1992 Kaleb Keithley
+Copyright (C) 2000, 2003 David J. Hawkey Jr.
+
+ 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 names of the copyright holders
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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.
+*********************************************************************/
+
+#include "Xaw3dP.h"
+#ifdef XAW_MULTIPLANE_PIXMAPS
+#include <stdio.h>
+#include <X11/xpm.h>
+#endif
+
+#ifdef XAW_GRAY_BLKWHT_STIPPLES
+/* ARGSUSED */
+unsigned long
+grayPixel(p, dpy, scn)
+unsigned long p; /* unused */
+Display *dpy;
+Screen *scn;
+{
+ static XColor Gray =
+ {
+ 0, /* pixel */
+ 0, 0, 0, /* red, green, blue */
+ 0, /* flags */
+ 0 /* pad */
+ };
+
+ if (!Gray.pixel)
+ {
+ XColor exact;
+
+ (void)XAllocNamedColor(dpy, DefaultColormapOfScreen(scn),
+ "gray", &Gray, &exact); /* Blindflug */
+ }
+
+ return Gray.pixel;
+}
+#endif
+
+#ifdef XAW_MULTIPLANE_PIXMAPS
+#define IS_EVEN(x) (((x) % 2) == 0)
+#define IS_ODD(x) (((x) % 2) == 1)
+
+/* ARGSUSED */
+Pixmap
+stipplePixmap(w, pm, cm, bg, d)
+Widget w;
+Pixmap pm;
+Colormap cm;
+Pixel bg;
+unsigned int d;
+{
+ static Pixmap pixmap;
+ Display *dpy;
+ XpmImage image;
+ XpmAttributes attr;
+ XpmColor *src_table, *dst_table;
+ int i, j, index = -1;
+
+ if (pm == None)
+ return (None);
+ if (XtIsRealized(w) == False)
+ return (None);
+
+ dpy = XtDisplayOfObject(w);
+
+ attr.colormap = cm;
+ attr.closeness = 32768; /* might help on 8-bpp displays? */
+ attr.valuemask = XpmColormap | XpmCloseness;
+
+ if (XpmCreateXpmImageFromPixmap(dpy, pm, None,
+ &image, &attr) != XpmSuccess)
+ return (None);
+ if (image.height == 0 || image.width == 0)
+ {
+ XpmFreeXpmImage(&image);
+ return (None);
+ }
+
+ if (d > 1)
+ {
+ XColor x_color;
+ XpmColor *dst_color;
+ char dst_rgb[14];
+
+ /*
+ * Multi-plane (XPM) pixmap. Don't bother scanning the color table
+ * for the background color, it might not be there. Copy the color
+ * table, add an entry for the background color, and set the index
+ * to that.
+ */
+
+ x_color.pixel = bg;
+ XQueryColor(dpy, cm, &x_color);
+ sprintf(dst_rgb, "#%04X%04X%04X",
+ x_color.red, x_color.green, x_color.blue);
+
+ dst_table = (XpmColor *) XtCalloc(sizeof(XpmColor),
+ image.ncolors + 1);
+ memcpy(dst_table, image.colorTable, image.ncolors * sizeof(XpmColor));
+
+ dst_color = &dst_table[image.ncolors];
+ switch (w->core.depth)
+ {
+ case 1:
+ dst_color->m_color = dst_rgb;
+ break;
+ case 4:
+ dst_color->g4_color = dst_rgb;
+ break;
+ case 6:
+ dst_color->g_color = dst_rgb;
+ break;
+ case 8:
+ default:
+ dst_color->c_color = dst_rgb;
+ break;
+ }
+ dst_color->string = "\x01"; /* ! */
+
+ src_table = image.colorTable;
+ image.colorTable = dst_table;
+
+ index = image.ncolors++;
+ }
+ else
+ {
+ XpmColor *src_color;
+ char *src_rgb;
+
+ /*
+ * Single-plane (XBM) pixmap. Set the index to the white color.
+ */
+
+ for (i = 0, src_color = image.colorTable; i < image.ncolors;
+ i++, src_color++)
+ {
+ switch (w->core.depth)
+ {
+ case 1:
+ src_rgb = src_color->m_color;
+ break;
+ case 4:
+ src_rgb = src_color->g4_color;
+ break;
+ case 6:
+ src_rgb = src_color->g_color;
+ break;
+ case 8:
+ default:
+ src_rgb = src_color->c_color;
+ break;
+ }
+ if (strcmp(src_rgb, "#000000000000") == 0)
+ {
+ index = i;
+ break;
+ }
+ }
+
+ if (index == -1)
+ {
+ XpmFreeXpmImage(&image);
+ return (None);
+ }
+ }
+
+ for (i = 0; i < image.height; i++)
+ for (j = 0; j < image.width; j++)
+ if ((IS_ODD(i) && IS_EVEN(j)) || (IS_EVEN(i) && IS_ODD(j)))
+ image.data[(i * image.width) + j] = index;
+
+ attr.depth = d;
+ attr.valuemask |= XpmDepth;
+
+ i = XpmCreatePixmapFromXpmImage(dpy, pm, &image, &pixmap, NULL, &attr);
+
+ if (d > 1)
+ {
+ XtFree((void *)image.colorTable); /* dst_table */
+ image.colorTable = src_table;
+ image.ncolors--;
+ }
+ XpmFreeXpmImage(&image);
+
+ return ((i == XpmSuccess) ? pixmap : None);
+}
+#endif
diff --git a/src/Xaw3dP.h.sed b/src/Xaw3dP.h.sed
new file mode 100644
index 0000000..391bde3
--- /dev/null
+++ b/src/Xaw3dP.h.sed
@@ -0,0 +1,83 @@
+/*
+ * Xaw3dP.h
+ *
+ * Global definitions and declarations. Not for public consumption.
+ */
+
+/*********************************************************************
+Copyright (C) 1992 Kaleb Keithley
+Copyright (C) 2000, 2003 David J. Hawkey Jr.
+
+ 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 names of the copyright holders
+not be used in advertising or publicity pertaining to distribution
+of the software without specific, written prior permission.
+
+THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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.
+*********************************************************************/
+
+#ifndef _Xaw3dP_h
+#define _Xaw3dP_h
+
+#include <X11/IntrinsicP.h>
+
+/* These are set during the build to reflect capability and options. */
+/* I18n support */
+/* XPM support */
+/* gray stipples */
+/* arrow scrollbars */
+
+#ifndef XtX
+#define XtX(w) (((RectObj)w)->rectangle.x)
+#endif
+#ifndef XtY
+#define XtY(w) (((RectObj)w)->rectangle.y)
+#endif
+#ifndef XtWidth
+#define XtWidth(w) (((RectObj)w)->rectangle.width)
+#endif
+#ifndef XtHeight
+#define XtHeight(w) (((RectObj)w)->rectangle.height)
+#endif
+#ifndef XtBorderWidth
+#define XtBorderWidth(w) (((RectObj)w)->rectangle.border_width)
+#endif
+
+#ifdef XAW_GRAY_BLKWHT_STIPPLES
+extern unsigned long
+grayPixel(
+#if NeedFunctionPrototypes
+ unsigned long,
+ Display *,
+ Screen *
+#endif
+);
+#else
+#define grayPixel(p, dpy, scn) (p)
+#endif
+
+#ifdef XAW_MULTIPLANE_PIXMAPS
+extern Pixmap
+stipplePixmap(
+#if NeedFunctionPrototypes
+ Widget,
+ Pixmap,
+ Colormap,
+ Pixel,
+ unsigned int
+#endif
+);
+#endif
+
+#endif /* _Xaw3dP_h */
diff --git a/src/XawI18n.c b/src/XawI18n.c
new file mode 100644
index 0000000..c911057
--- /dev/null
+++ b/src/XawI18n.c
@@ -0,0 +1,88 @@
+/* $XConsortium: XawI18n.c,v 1.6 94/04/17 20:13:28 kaleb Exp $ */
+
+/* Copyright 1991 NCR Corporation - Dayton, Ohio, USA */
+
+/*
+ * Copyright 1990, 1991 by OMRON Corporation, NTT Software Corporation,
+ * and Nippon Telegraph and Telephone Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, 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 names of OMRON, NTT Software, and NTT
+ * not be used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. OMRON, NTT Software,
+ * and NTT make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * OMRON, NTT SOFTWARE, AND NTT, DISCLAIM ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL OMRON, NTT SOFTWARE, OR NTT 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.
+ *
+ * Author: Li Yuhong OMRON Corporation
+ */
+
+/*
+
+Copyright (c) 1991, 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.
+
+*/
+
+#include <X11/IntrinsicP.h>
+#include "XawI18n.h"
+
+#if NeedFunctionPrototypes
+wchar_t _Xaw_atowc(
+ unsigned char c)
+#else
+wchar_t _Xaw_atowc(c)
+ unsigned char c;
+#endif
+{
+ wchar_t wc;
+ char str[2];
+
+ str[0] = c;
+ str[1] = '\0';
+
+ mbtowc(&wc, str, 1);
+ return wc;
+}
+
+#ifdef NCR
+int _Xaw_iswspace(wchar_t w)
+{
+ int ret = 0;
+ wchar_t s = _Xaw_atowc(' ');
+ if (s == w)
+ ret = 1;
+ return ret;
+}
+#endif
diff --git a/src/XawI18n.h b/src/XawI18n.h
new file mode 100644
index 0000000..1b0ee5d
--- /dev/null
+++ b/src/XawI18n.h
@@ -0,0 +1,78 @@
+/* $XConsortium: XawI18n.h,v 1.12 95/01/25 00:48:44 kaleb Exp $ */
+
+/************************************************************
+
+Copyright (c) 1993, 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.
+
+********************************************************/
+
+#ifdef HAS_WCTYPE_H
+#include <wctype.h>
+#include <widec.h>
+#define wcslen(c) wslen(c)
+#define wcscpy(d,s) wscpy(d,s)
+#define wcsncpy(d,s,l) wsncpy(d,s,l)
+#endif
+
+#ifdef HAS_WCHAR_H
+#include <wchar.h>
+#endif
+
+#ifdef AIXV3
+#include <ctype.h>
+#endif
+
+#ifdef NCR
+#define iswspace(c) _Xaw_iswspace(c)
+extern int _Xaw_iswspace(wchar_t);
+#endif
+
+#ifdef sony
+#ifndef SVR4
+#include <jctype.h>
+#define iswspace(c) jisspace(c)
+#endif
+#endif
+
+#ifdef USE_XWCHAR_STRING
+#define wcslen(c) _Xwcslen(c)
+#define wcscpy(d,s) _Xwcscpy(d,s)
+#define wcsncpy(d,s,l) _Xwcsncpy(d,s,l)
+#ifdef USE_XMBTOWC
+#define mbtowc(wc,s,l) _Xmbtowc(wc,s,l)
+#endif
+#endif
+
+extern wchar_t _Xaw_atowc (
+#if NeedFunctionPrototypes
+ unsigned char c
+#endif
+);
+
+#ifndef HAS_ISW_FUNCS
+#include <ctype.h>
+#ifndef iswspace
+#define iswspace(c) (isascii(c) && isspace(toascii(c)))
+#endif
+#endif
diff --git a/src/XawIm.c b/src/XawIm.c
new file mode 100644
index 0000000..ead7166
--- /dev/null
+++ b/src/XawIm.c
@@ -0,0 +1,1716 @@
+/* $XConsortium: XawIm.c,v 1.6 95/01/20 16:17:21 kaleb Exp $ */
+
+/*
+ * Copyright 1991 by OMRON Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, 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 OMRON not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. OMRON makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * OMRON 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 TORTUOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Author: Seiji Kuwari OMRON Corporation
+ * kuwa@omron.co.jp
+ * kuwa%omron.co.jp@uunet.uu.net
+ */
+
+
+/*
+
+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.
+
+*/
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xos.h>
+#include <X11/Xfuncs.h>
+#include <X11/ShellP.h>
+#include <X11/Xaw3d/TextP.h>
+#include <X11/Xaw3d/MultiSrc.h>
+#include <X11/Xaw3d/MultiSinkP.h>
+#include <X11/Xaw3d/XawImP.h>
+#include <X11/Xaw3d/VendorEP.h>
+#include "XawI18n.h"
+#include <ctype.h>
+
+#if NeedVarargsPrototypes
+# include <stdarg.h>
+# define Va_start(a,b) va_start(a,b)
+#else
+# include <varargs.h>
+# define Va_start(a,b) va_start(a)
+#endif
+
+#define maxAscentOfFontSet(fontset) \
+ ( - (XExtentsOfFontSet((fontset)))->max_logical_extent.y)
+
+#define maxHeightOfFontSet(fontset) \
+ ((XExtentsOfFontSet((fontset)))->max_logical_extent.height)
+
+#define maxDescentOfFontSet(fontset) \
+ (maxHeightOfFontSet(fontset) - maxAscentOfFontSet(fontset))
+
+#define Offset(field) (XtOffsetOf(XawIcTablePart, field))
+
+/*****************************************************
+ *
+ * Forward reference prototypes
+ *
+ *****************************************************/
+
+static XawIcTableList CurrentSharedIcTable(
+#if NeedFunctionPrototypes
+ XawVendorShellExtPart* /* ve */
+#endif
+);
+
+static void DestroyIC(
+#if NeedFunctionPrototypes
+ Widget /* w */,
+ XawVendorShellExtPart* /* ve */
+#endif
+);
+
+static XtResource resources[] =
+{
+ {
+ XtNfontSet, XtCFontSet, XtRFontSet, sizeof(XFontSet),
+ Offset (font_set), XtRString, XtDefaultFontSet
+ },
+ {
+ XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
+ Offset (foreground), XtRString, (XtPointer)"XtDefaultForeground"
+ },
+ {
+ XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel),
+ Offset (background), XtRString, (XtPointer)"XtDefaultBackground"
+ },
+ {
+ XtNbackgroundPixmap, XtCPixmap, XtRPixmap, sizeof(Pixmap),
+ Offset (bg_pixmap), XtRImmediate, (XtPointer) XtUnspecifiedPixmap
+ },
+ {
+ XtNinsertPosition, XtCTextPosition, XtRInt, sizeof (XawTextPosition),
+ Offset (cursor_position), XtRImmediate, (XtPointer) 0
+ }
+};
+#undef Offset
+
+
+static void SetVaArg( arg, value )
+ XPointer *arg, value;
+{
+ *arg = value;
+}
+
+static VendorShellWidget SearchVendorShell( w )
+ Widget w;
+{
+ while(w && !XtIsShell(w)) w = XtParent(w);
+ if (w && XtIsVendorShell(w)) return((VendorShellWidget)w);
+ return(NULL);
+}
+
+static XContext extContext = (XContext)NULL;
+
+static XawVendorShellExtPart *SetExtPart( w, vew )
+ VendorShellWidget w;
+ XawVendorShellExtWidget vew;
+{
+ contextDataRec *contextData;
+
+ if (extContext == (XContext)NULL) extContext = XUniqueContext();
+
+ contextData = XtNew(contextDataRec);
+ contextData->parent = (Widget)w;
+ contextData->ve = (Widget)vew;
+ if (XSaveContext(XtDisplay(w), (Window)w, extContext, (char *)contextData)) {
+ return(NULL);
+ }
+ return(&(vew->vendor_ext));
+}
+
+static XawVendorShellExtPart *GetExtPart( w )
+ VendorShellWidget w;
+{
+ contextDataRec *contextData;
+ XawVendorShellExtWidget vew;
+
+ if (XFindContext(XtDisplay(w), (Window)w, extContext,
+ (XPointer*)&contextData)) {
+ return(NULL);
+ }
+ vew = (XawVendorShellExtWidget)contextData->ve;
+ return(&(vew->vendor_ext));
+}
+
+static Boolean IsSharedIC( ve )
+ XawVendorShellExtPart * ve;
+{
+ return( ve->ic.shared_ic );
+}
+
+static XawIcTableList GetIcTableShared( w, ve )
+ Widget w;
+ XawVendorShellExtPart * ve;
+{
+ XawIcTableList p;
+
+ for (p = ve->ic.ic_table; p; p = p->next) {
+ if (p->widget == w) {
+ if (IsSharedIC(ve)) {
+ return(ve->ic.shared_ic_table);
+ } else {
+ return(p);
+ }
+ }
+ }
+ return(NULL);
+}
+
+static XawIcTableList GetIcTable( w, ve )
+ Widget w;
+ XawVendorShellExtPart * ve;
+{
+ XawIcTableList p;
+
+ for (p = ve->ic.ic_table; p; p = p->next) {
+ if (p->widget == w) {
+ return(p);
+ }
+ }
+ return(NULL);
+}
+
+static XIMStyle GetInputStyleOfIC( ve )
+ XawVendorShellExtPart * ve;
+{
+
+ if (!ve) return((XIMStyle)0);
+ return(ve->ic.input_style);
+}
+
+static void ConfigureCB( w, closure, event )
+ Widget w;
+ XtPointer closure;
+ XEvent * event;
+{
+ XawIcTableList p;
+ XawVendorShellExtPart *ve;
+ VendorShellWidget vw;
+ XVaNestedList pe_attr;
+ XRectangle pe_area;
+ XawTextMargin *margin;
+
+ if (event->type != ConfigureNotify) return;
+
+ if ((vw = SearchVendorShell(w)) == NULL) return;
+
+ if ((ve = GetExtPart(vw))) {
+ if (IsSharedIC(ve)) return;
+ if ((ve->im.xim == NULL) ||
+ ((p = GetIcTableShared(w, ve)) == NULL) ||
+ (p->xic == NULL) || !(p->input_style & XIMPreeditPosition)) return;
+ pe_area.x = 0;
+ pe_area.y = 0;
+ pe_area.width = w->core.width;
+ pe_area.height = w->core.height;
+ margin = &(((TextWidget)w)->text.margin);
+ pe_area.x += margin->left;
+ pe_area.y += margin->top;
+ pe_area.width -= (margin->left + margin->right - 1);
+ pe_area.height -= (margin->top + margin->bottom - 1);
+
+ pe_attr = XVaCreateNestedList(0, XNArea, &pe_area, NULL);
+ XSetICValues(p->xic, XNPreeditAttributes, pe_attr, NULL);
+ XtFree(pe_attr);
+ }
+}
+
+static XContext errContext = (XContext)NULL;
+
+static Widget SetErrCnxt( w, xim )
+ Widget w;
+ XIM xim;
+{
+ contextErrDataRec *contextErrData;
+
+ if (errContext == (XContext)NULL) errContext = XUniqueContext();
+
+ contextErrData = XtNew(contextErrDataRec);
+ contextErrData->widget = w;
+ contextErrData->xim = xim;
+ if (XSaveContext(XtDisplay(w), (Window)xim, errContext,
+ (char *)contextErrData)) {
+ return(NULL);
+ }
+ return(contextErrData->widget);
+}
+
+static void CloseIM( ve )
+ XawVendorShellExtPart * ve;
+{
+ if (ve->im.xim)
+ XCloseIM(ve->im.xim);
+}
+
+static Dimension SetVendorShellHeight( ve, height )
+ XawVendorShellExtPart* ve;
+ Dimension height;
+{
+ Arg args[2];
+ Cardinal i = 0;
+
+ if (ve->im.area_height < height || height == 0) {
+ XtSetArg(args[i], XtNheight,
+ (ve->parent->core.height + height - ve->im.area_height));
+ ve->im.area_height = height;
+ XtSetValues(ve->parent, args, 1);
+ }
+ return(ve->im.area_height);
+}
+
+static void DestroyAllIM( ve )
+ XawVendorShellExtPart * ve;
+{
+ XawIcTableList p;
+ contextErrDataRec *contextErrData;
+
+ /*
+ * Destory all ICs
+ */
+ if (IsSharedIC(ve)) {
+ if ((p = ve->ic.shared_ic_table) && p->xic) {
+ DestroyIC(p->widget, ve);
+ p->xic = NULL;
+ p->ic_focused = FALSE;
+ }
+ } else {
+ for (p = ve->ic.ic_table; p; p = p->next) {
+ if (p->xic == NULL) continue;
+ DestroyIC(p->widget, ve);
+ p->xic = NULL;
+ p->ic_focused = FALSE;
+ }
+ }
+ if (!ve->im.xim) return;
+ /*
+ * Close Input Method
+ */
+ CloseIM(ve);
+ if (!XFindContext(XDisplayOfIM(ve->im.xim), (Window)ve->im.xim, errContext,
+ (XPointer*)&contextErrData)) {
+ if (contextErrData) XtFree((char *)contextErrData);
+ }
+ XDeleteContext(XDisplayOfIM(ve->im.xim), (Window)ve->im.xim, errContext);
+ ve->im.xim = NULL;
+
+ /*
+ * resize vendor shell to core size
+ */
+ (void) SetVendorShellHeight(ve, 0);
+ /*
+ XawVendorShellExtResize(vw);
+ */
+ return;
+}
+
+static void FreeAllDataOfVendorShell(ve, vw)
+ XawVendorShellExtPart * ve;
+ VendorShellWidget vw;
+{
+ XawIcTableList p, next;
+ contextErrDataRec *contextErrData;
+
+ if (!XFindContext(XtDisplay(vw), (Window)vw, extContext,
+ (XPointer*)&contextErrData)) {
+ if (contextErrData) XtFree((char *)contextErrData);
+ }
+ XDeleteContext(XtDisplay(vw), (Window)vw, extContext);
+ if (ve->ic.shared_ic_table)
+ XtFree((char *)ve->ic.shared_ic_table);
+ if (ve->im.resources) XtFree((char *)ve->im.resources);
+ for (p = ve->ic.ic_table; p; p = next) {
+ next = p->next;
+ XtFree((char *)p);
+ }
+}
+
+static void VendorShellDestroyed( w, cl_data, ca_data )
+ Widget w;
+ XtPointer cl_data, ca_data;
+{
+ XawVendorShellExtPart *ve;
+
+ if ( ( ve = GetExtPart( (VendorShellWidget) w ) ) == NULL ) return;
+ DestroyAllIM( ve );
+ FreeAllDataOfVendorShell( ve, (VendorShellWidget) w );
+ return;
+}
+
+/*
+ * Attempt to open an input method
+ */
+
+static void OpenIM(ve)
+ XawVendorShellExtPart * ve;
+{
+ int i;
+ char *p, *s, *ns, *end, *pbuf, buf[32];
+ XIM xim = NULL;
+ XIMStyles *xim_styles;
+ XIMStyle input_style = 0;
+ Boolean found;
+
+ if (ve->im.open_im == False) return;
+ ve->im.xim = NULL;
+ if (ve->im.input_method == NULL) {
+ if ((p = XSetLocaleModifiers("@im=none")) != NULL && *p)
+ xim = XOpenIM(XtDisplay(ve->parent), NULL, NULL, NULL);
+ } else {
+ /* no fragment can be longer than the whole string */
+ int len = strlen (ve->im.input_method) + 5;
+
+ if (len < sizeof buf) pbuf = buf;
+ else pbuf = XtMalloc (len);
+
+ if (pbuf == NULL) return;
+
+ for(ns=s=ve->im.input_method; ns && *s;) {
+ /* skip any leading blanks */
+ while (*s && isspace(*s)) s++;
+ if (!*s) break;
+ if ((ns = end = strchr(s, ',')) == NULL)
+ end = s + strlen(s);
+ /* strip any trailing blanks */
+ while (isspace(*end)) end--;
+
+ strcpy (pbuf, "@im=");
+ strncat (pbuf, s, end - s);
+ pbuf[end - s + 4] = '\0';
+
+ if ((p = XSetLocaleModifiers(pbuf)) != NULL && *p
+ && (xim = XOpenIM(XtDisplay(ve->parent), NULL, NULL, NULL)) != NULL)
+ break;
+
+ s = ns + 1;
+ }
+
+ if (pbuf != buf) XtFree (pbuf);
+ }
+ if (xim == NULL) {
+ if ((p = XSetLocaleModifiers("")) != NULL) {
+ xim = XOpenIM(XtDisplay(ve->parent), NULL, NULL, NULL);
+ }
+ }
+ if (xim == NULL) {
+ XtAppWarning(XtWidgetToApplicationContext(ve->parent),
+ "Input Method Open Failed");
+ return;
+ }
+ if (XGetIMValues(xim, XNQueryInputStyle, &xim_styles, NULL)
+ || !xim_styles) {
+ XtAppWarning(XtWidgetToApplicationContext(ve->parent),
+ "input method doesn't support any style");
+ XCloseIM(xim);
+ return;
+ }
+ found = False;
+ for(ns = s = ve->im.preedit_type; s && !found;) {
+ while (*s && isspace(*s)) s++;
+ if (!*s) break;
+ if ((ns = end = strchr(s, ',')) == NULL)
+ end = s + strlen(s);
+ while (isspace(*end)) end--;
+
+ if (!strncmp(s, "OverTheSpot", end - s)) {
+ input_style = (XIMPreeditPosition | XIMStatusArea);
+ } else if (!strncmp(s, "OffTheSpot", end - s)) {
+ input_style = (XIMPreeditArea | XIMStatusArea);
+ } else if (!strncmp(s, "Root", end - s)) {
+ input_style = (XIMPreeditNothing | XIMStatusNothing);
+ }
+ for (i = 0; (unsigned short)i < xim_styles->count_styles; i++)
+ if (input_style == xim_styles->supported_styles[i]) {
+ ve->ic.input_style = input_style;
+ SetErrCnxt(ve->parent, xim);
+ ve->im.xim = xim;
+ found = True;
+ break;
+ }
+
+ s = ns + 1;
+ }
+ XFree(xim_styles);
+
+ if (!found) {
+ XCloseIM(xim);
+ XtAppWarning(XtWidgetToApplicationContext(ve->parent),
+ "input method doesn't support my input style");
+ }
+}
+
+static Boolean ResizeVendorShell_Core(vw, ve, p)
+ VendorShellWidget vw;
+ XawVendorShellExtPart * ve;
+ XawIcTableList p;
+{
+ XVaNestedList pe_attr, st_attr;
+ XRectangle pe_area, st_area;
+ XRectangle *get_pe_area = NULL, *get_st_area = NULL;
+
+ st_area.width = 0;
+ if (p->input_style & XIMStatusArea) {
+ st_attr = XVaCreateNestedList(0, XNArea, &get_st_area, NULL);
+ XGetICValues(p->xic, XNStatusAttributes, st_attr, NULL);
+ XFree(st_attr);
+ if (p->xic == NULL) {
+ return(FALSE);
+ }
+ st_area.x = 0;
+ st_area.y = vw->core.height - ve->im.area_height;
+ st_area.width = get_st_area->width;
+ st_area.height = get_st_area->height;
+ XFree(get_st_area);
+ st_attr = XVaCreateNestedList(0, XNArea, &st_area, NULL);
+ XSetICValues(p->xic, XNStatusAttributes, st_attr, NULL);
+ XFree(st_attr);
+ if (p->xic == NULL) {
+ return(FALSE);
+ }
+ }
+ if (p->input_style & XIMPreeditArea) {
+ pe_attr = XVaCreateNestedList(0, XNArea, &get_pe_area, NULL);
+ XGetICValues(p->xic, XNPreeditAttributes, pe_attr, NULL);
+ XFree(pe_attr);
+ if (p->xic == NULL) {
+ return(FALSE);
+ }
+ pe_area.x = st_area.width;
+ pe_area.y = vw->core.height - ve->im.area_height;
+ pe_area.width = vw->core.width;
+ pe_area.height = get_pe_area->height;
+ if (p->input_style & XIMStatusArea) {
+ pe_area.width -= st_area.width;
+ }
+ XFree(get_pe_area);
+ pe_attr = XVaCreateNestedList(0, XNArea, &pe_area, NULL);
+ XSetICValues(p->xic, XNPreeditAttributes, pe_attr, NULL);
+ XFree(pe_attr);
+ }
+ return(TRUE);
+}
+
+static void ResizeVendorShell(vw, ve)
+ VendorShellWidget vw;
+ XawVendorShellExtPart * ve;
+{
+ XawIcTableList p;
+
+ if (IsSharedIC(ve)) {
+ p = ve->ic.shared_ic_table;
+ if (p->xic == NULL) return;
+ ResizeVendorShell_Core(vw, ve, p);
+ return;
+ }
+ for (p = ve->ic.ic_table; p; p = p->next) {
+ if (p->xic == NULL) continue;
+ if (ResizeVendorShell_Core(vw, ve, p) == FALSE) return;
+ }
+}
+
+static XawIcTableList CreateIcTable( w, ve )
+ Widget w;
+ XawVendorShellExtPart * ve;
+{
+ XawIcTableList table;
+
+ table = (XawIcTableList) XtMalloc(sizeof(XawIcTablePart));
+ if (table == NULL) return(NULL);
+ table->widget = w;
+ table->xic = NULL;
+ table->flg = table->prev_flg = 0;
+ table->font_set = NULL;
+ table->foreground = table->background = 0xffffffff;
+ table->bg_pixmap = 0;
+ table->cursor_position = 0xffff;
+ table->line_spacing = 0;
+ table->ic_focused = FALSE;
+ table->openic_error = FALSE;
+ return(table);
+}
+
+static Boolean RegisterToVendorShell( w, ve )
+ Widget w;
+ XawVendorShellExtPart * ve;
+{
+ XawIcTableList table;
+
+ if ((table = CreateIcTable(w, ve)) == NULL) return(FALSE);
+ table->next = ve->ic.ic_table;
+ ve->ic.ic_table = table;
+ return(TRUE);
+}
+
+static void UnregisterFromVendorShell(w, ve)
+ Widget w;
+ XawVendorShellExtPart * ve;
+{
+ XawIcTableList *prev, p;
+
+ for (prev = &ve->ic.ic_table; (p = *prev); prev = &p->next) {
+ if (p->widget == w) {
+ *prev = p->next;
+ XtFree((char *)p);
+ break;
+ }
+ }
+ return;
+}
+
+static void SetICValuesShared(w, ve, p, check)
+ Widget w;
+ XawVendorShellExtPart * ve;
+ XawIcTableList p;
+ Boolean check;
+{
+ XawIcTableList pp;
+
+ if ((pp = GetIcTable(w, ve)) == NULL) return;
+ if (check == TRUE && CurrentSharedIcTable(ve) != pp) return;
+
+ if (pp->prev_flg & CICursorP && p->cursor_position != pp->cursor_position) {
+ p->cursor_position = pp->cursor_position;
+ p->flg |= CICursorP;
+ }
+ if (pp->prev_flg & CIFontSet && p->font_set != pp->font_set) {
+ p->font_set = pp->font_set;
+ p->flg |= (CIFontSet|CICursorP);
+ }
+ if (pp->prev_flg & CIFg && p->foreground != pp->foreground) {
+ p->foreground = pp->foreground;
+ p->flg |= CIFg;
+ }
+ if (pp->prev_flg & CIBg && p->background != pp->background) {
+ p->background = pp->background;
+ p->flg |= CIBg;
+ }
+ if (pp->prev_flg & CIBgPixmap && p->bg_pixmap != pp->bg_pixmap) {
+ p->bg_pixmap = pp->bg_pixmap;
+ p->flg |= CIBgPixmap;
+ }
+ if (pp->prev_flg & CILineS && p->line_spacing != pp->line_spacing) {
+ p->line_spacing = pp->line_spacing;
+ p->flg |= CILineS;
+ }
+}
+
+static Boolean IsCreatedIC(w, ve)
+ Widget w;
+ XawVendorShellExtPart * ve;
+{
+ XawIcTableList p;
+
+ if (ve->im.xim == NULL) return(FALSE);
+ if ((p = GetIcTableShared(w, ve)) == NULL) return(FALSE);
+ if (p->xic == NULL) return(FALSE);
+ return(TRUE);
+}
+
+static void SizeNegotiation(p, width, height)
+ XawIcTableList p;
+ Dimension width, height;
+{
+ XRectangle pe_area, st_area;
+ XVaNestedList pe_attr = NULL, st_attr = NULL;
+ int ic_cnt = 0, pe_cnt = 0, st_cnt = 0;
+ XRectangle *pe_area_needed = NULL, *st_area_needed = NULL;
+ XPointer ic_a[5];
+
+ if (p->input_style & XIMPreeditArea) {
+ pe_attr = XVaCreateNestedList(0, XNAreaNeeded, &pe_area_needed, NULL);
+ SetVaArg( &ic_a[ic_cnt], (XPointer) XNPreeditAttributes); ic_cnt++;
+ SetVaArg( &ic_a[ic_cnt], (XPointer) pe_attr); ic_cnt++;
+ }
+ if (p->input_style & XIMStatusArea) {
+ st_attr = XVaCreateNestedList(0, XNAreaNeeded, &st_area_needed, NULL);
+ SetVaArg( &ic_a[ic_cnt], (XPointer) XNStatusAttributes); ic_cnt++;
+ SetVaArg( &ic_a[ic_cnt], (XPointer) st_attr); ic_cnt++;
+ }
+ SetVaArg( &ic_a[ic_cnt], (XPointer) NULL);
+
+ if (ic_cnt > 0) {
+ XGetICValues(p->xic, ic_a[0], ic_a[1], ic_a[2], ic_a[3], ic_a[4]);
+ if (pe_attr) XFree(pe_attr);
+ if (st_attr) XFree(st_attr);
+ if (p->xic == NULL) {
+ p->openic_error = True;
+ return;
+ }
+ pe_attr = st_attr = NULL;
+ ic_cnt = pe_cnt = st_cnt = 0;
+ if (p->input_style & XIMStatusArea) {
+ st_area.height = st_area_needed->height;
+ st_area.x = 0;
+ st_area.y = height - st_area.height;
+ if (p->input_style & XIMPreeditArea) {
+ st_area.width = st_area_needed->width;
+ } else {
+ st_area.width = width;
+ }
+
+ XFree(st_area_needed);
+ st_attr = XVaCreateNestedList(0, XNArea, &st_area, NULL);
+ SetVaArg( &ic_a[ic_cnt], (XPointer) XNStatusAttributes); ic_cnt++;
+ SetVaArg( &ic_a[ic_cnt], (XPointer) st_attr); ic_cnt++;
+ }
+ if (p->input_style & XIMPreeditArea) {
+ if (p->input_style & XIMStatusArea) {
+ pe_area.x = st_area.width;
+ pe_area.width = width - st_area.width;
+ } else {
+ pe_area.x = 0;
+ pe_area.width = width;
+ }
+ pe_area.height = pe_area_needed->height;
+ XFree(pe_area_needed);
+ pe_area.y = height - pe_area.height;
+ pe_attr = XVaCreateNestedList(0, XNArea, &pe_area, NULL);
+ SetVaArg( &ic_a[ic_cnt], (XPointer) XNPreeditAttributes); ic_cnt++;
+ SetVaArg( &ic_a[ic_cnt], (XPointer) pe_attr); ic_cnt++;
+ }
+ SetVaArg( &ic_a[ic_cnt], (XPointer) NULL);
+ XSetICValues(p->xic, ic_a[0], ic_a[1], ic_a[2], ic_a[3], ic_a[4]);
+ if (pe_attr) XFree(pe_attr);
+ if (st_attr) XFree(st_attr);
+ if (p->xic == NULL) {
+ p->openic_error = True;
+ return;
+ }
+ }
+}
+
+static void CreateIC( w, ve )
+ Widget w;
+ XawVendorShellExtPart* ve;
+{
+ XawIcTableList p;
+ XPoint position;
+ XRectangle pe_area, st_area;
+ XVaNestedList pe_attr = NULL, st_attr = NULL;
+ XPointer ic_a[20], pe_a[20], st_a[20];
+ Dimension height = 0;
+ int ic_cnt = 0, pe_cnt = 0, st_cnt = 0;
+ XawTextMargin *margin;
+
+ if (!XtIsRealized(w)) return;
+ if (((ve->im.xim == NULL) || (p = GetIcTableShared(w, ve)) == NULL) ||
+ p->xic || (p->openic_error != FALSE)) return;
+
+ p->input_style = GetInputStyleOfIC(ve);
+
+ if (IsSharedIC(ve)) SetICValuesShared(w, ve, p, FALSE);
+ XFlush(XtDisplay(w));
+
+ if (p->input_style & (XIMPreeditArea|XIMPreeditPosition|XIMStatusArea)) {
+ if (p->flg & CIFontSet) {
+ SetVaArg( &pe_a[pe_cnt], (XPointer) XNFontSet); pe_cnt++;
+ SetVaArg( &pe_a[pe_cnt], (XPointer) p->font_set); pe_cnt++;
+ SetVaArg( &st_a[st_cnt], (XPointer) XNFontSet); st_cnt++;
+ SetVaArg( &st_a[st_cnt], (XPointer) p->font_set); st_cnt++;
+ height = maxAscentOfFontSet(p->font_set)
+ + maxDescentOfFontSet(p->font_set);
+ height = SetVendorShellHeight(ve, height);
+ }
+ if (p->flg & CIFg) {
+ SetVaArg( &pe_a[pe_cnt], (XPointer) XNForeground); pe_cnt++;
+ SetVaArg( &pe_a[pe_cnt], (XPointer) p->foreground); pe_cnt++;
+ SetVaArg( &st_a[st_cnt], (XPointer) XNForeground); st_cnt++;
+ SetVaArg( &st_a[st_cnt], (XPointer) p->foreground); st_cnt++;
+ }
+ if (p->flg & CIBg) {
+ SetVaArg( &pe_a[pe_cnt], (XPointer) XNBackground); pe_cnt++;
+ SetVaArg( &pe_a[pe_cnt], (XPointer) p->background); pe_cnt++;
+ SetVaArg( &st_a[st_cnt], (XPointer) XNBackground); st_cnt++;
+ SetVaArg( &st_a[st_cnt], (XPointer) p->background); st_cnt++;
+ }
+ if (p->flg & CIBgPixmap) {
+ SetVaArg( &pe_a[pe_cnt], (XPointer) XNBackgroundPixmap); pe_cnt++;
+ SetVaArg( &pe_a[pe_cnt], (XPointer) p->bg_pixmap); pe_cnt++;
+ SetVaArg( &st_a[st_cnt], (XPointer) XNBackgroundPixmap); st_cnt++;
+ SetVaArg( &st_a[st_cnt], (XPointer) p->bg_pixmap); st_cnt++;
+ }
+ if (p->flg & CILineS) {
+ SetVaArg( &pe_a[pe_cnt], (XPointer) XNLineSpace); pe_cnt++;
+ SetVaArg( &pe_a[pe_cnt], (XPointer) p->line_spacing); pe_cnt++;
+ SetVaArg( &st_a[st_cnt], (XPointer) XNLineSpace); st_cnt++;
+ SetVaArg( &st_a[st_cnt], (XPointer) p->line_spacing); st_cnt++;
+ }
+ }
+ if (p->input_style & XIMPreeditArea) {
+ pe_area.x = 0;
+ pe_area.y = ve->parent->core.height - height;
+ pe_area.width = ve->parent->core.width;
+ pe_area.height = height;
+ SetVaArg( &pe_a[pe_cnt], (XPointer) XNArea); pe_cnt++;
+ SetVaArg( &pe_a[pe_cnt], (XPointer) &pe_area); pe_cnt++;
+ }
+ if (p->input_style & XIMPreeditPosition) {
+ pe_area.x = 0;
+ pe_area.y = 0;
+ pe_area.width = w->core.width;
+ pe_area.height = w->core.height;
+ margin = &(((TextWidget)w)->text.margin);
+ pe_area.x += margin->left;
+ pe_area.y += margin->top;
+ pe_area.width -= (margin->left + margin->right - 1);
+ pe_area.height -= (margin->top + margin->bottom - 1);
+ SetVaArg( &pe_a[pe_cnt], (XPointer) XNArea); pe_cnt++;
+ SetVaArg( &pe_a[pe_cnt], (XPointer) &pe_area); pe_cnt++;
+ if (p->flg & CICursorP) {
+ _XawMultiSinkPosToXY(w, p->cursor_position, &position.x, &position.y);
+ } else {
+ position.x = position.y = 0;
+ }
+ SetVaArg( &pe_a[pe_cnt], (XPointer) XNSpotLocation); pe_cnt++;
+ SetVaArg( &pe_a[pe_cnt], (XPointer) &position); pe_cnt++;
+ }
+ if (p->input_style & XIMStatusArea) {
+ st_area.x = 0;
+ st_area.y = ve->parent->core.height - height;
+ st_area.width = ve->parent->core.width;
+ st_area.height = height;
+ SetVaArg( &st_a[st_cnt], (XPointer) XNArea); st_cnt++;
+ SetVaArg( &st_a[st_cnt], (XPointer) &st_area); st_cnt++;
+ }
+
+ SetVaArg( &ic_a[ic_cnt], (XPointer) XNInputStyle); ic_cnt++;
+ SetVaArg( &ic_a[ic_cnt], (XPointer) p->input_style); ic_cnt++;
+ SetVaArg( &ic_a[ic_cnt], (XPointer) XNClientWindow); ic_cnt++;
+ SetVaArg( &ic_a[ic_cnt], (XPointer) XtWindow(ve->parent)); ic_cnt++;
+ SetVaArg( &ic_a[ic_cnt], (XPointer) XNFocusWindow); ic_cnt++;
+ SetVaArg( &ic_a[ic_cnt], (XPointer) XtWindow(w)); ic_cnt++;
+
+ if (pe_cnt > 0) {
+ SetVaArg( &pe_a[pe_cnt], (XPointer) NULL);
+ pe_attr = XVaCreateNestedList(0, pe_a[0], pe_a[1], pe_a[2], pe_a[3],
+ pe_a[4], pe_a[5], pe_a[6], pe_a[7], pe_a[8],
+ pe_a[9], pe_a[10], pe_a[11], pe_a[12],
+ pe_a[13], pe_a[14], pe_a[15], pe_a[16],
+ pe_a[17], pe_a[18], pe_a[19]);
+ SetVaArg( &ic_a[ic_cnt], (XPointer) XNPreeditAttributes); ic_cnt++;
+ SetVaArg( &ic_a[ic_cnt], (XPointer) pe_attr); ic_cnt++;
+ }
+
+ if (st_cnt > 0) {
+ SetVaArg( &st_a[st_cnt], (XPointer) NULL);
+ st_attr = XVaCreateNestedList(0, st_a[0], st_a[1], st_a[2], st_a[3],
+ st_a[4], st_a[5], st_a[6], st_a[7], st_a[8],
+ st_a[9], st_a[10], st_a[11], st_a[12],
+ st_a[13], st_a[14], st_a[15], st_a[16],
+ st_a[17], st_a[18], st_a[19]);
+ SetVaArg( &ic_a[ic_cnt], (XPointer) XNStatusAttributes); ic_cnt++;
+ SetVaArg( &ic_a[ic_cnt], (XPointer) st_attr); ic_cnt++;
+ }
+ SetVaArg( &ic_a[ic_cnt], (XPointer) NULL);
+
+ p->xic = XCreateIC(ve->im.xim, ic_a[0], ic_a[1], ic_a[2], ic_a[3],
+ ic_a[4], ic_a[5], ic_a[6], ic_a[7], ic_a[8], ic_a[9],
+ ic_a[10], ic_a[11], ic_a[12], ic_a[13], ic_a[14],
+ ic_a[15], ic_a[16], ic_a[17], ic_a[18], ic_a[19]);
+ if (pe_attr) XtFree(pe_attr);
+ if (st_attr) XtFree(st_attr);
+
+ if (p->xic == NULL) {
+ p->openic_error = True;
+ return;
+ }
+
+ SizeNegotiation(p, ve->parent->core.width, ve->parent->core.height);
+
+ p->flg &= ~(CIFontSet | CIFg | CIBg | CIBgPixmap | CICursorP | CILineS);
+
+ if (!IsSharedIC(ve)) {
+ if (p->input_style & XIMPreeditPosition) {
+ XtAddEventHandler(w, (EventMask)StructureNotifyMask, FALSE,
+ (XtEventHandler)ConfigureCB, (Opaque)NULL);
+ }
+ }
+}
+
+static void SetICValues( w, ve, focus )
+ Widget w;
+ XawVendorShellExtPart *ve;
+ Boolean focus;
+{
+ XawIcTableList p;
+ XPoint position;
+ XRectangle pe_area;
+ XVaNestedList pe_attr = NULL, st_attr = NULL;
+ XPointer ic_a[20], pe_a[20], st_a[20];
+ int ic_cnt = 0, pe_cnt = 0, st_cnt = 0;
+ XawTextMargin *margin;
+ int height;
+
+ if ((ve->im.xim == NULL) || ((p = GetIcTableShared(w, ve)) == NULL) ||
+ (p->xic == NULL)) return;
+
+ if (IsSharedIC(ve)) SetICValuesShared(w, ve, p, TRUE);
+ XFlush(XtDisplay(w));
+ if (focus == FALSE &&
+ !(p->flg & (CIFontSet | CIFg | CIBg |
+ CIBgPixmap | CICursorP | CILineS))) return;
+#ifdef SPOT
+ if ((p->input_style & XIMPreeditPosition)
+ && ((!IsSharedIC(ve) && ((p->flg & ~CIICFocus) == CICursorP))
+ || (IsSharedIC(ve) && p->flg == CICursorP))) {
+ _XawMultiSinkPosToXY(w, p->cursor_position, &position.x, &position.y);
+ _XipChangeSpot(p->xic, position.x, position.y);
+ p->flg &= ~CICursorP;
+ return;
+ }
+#endif
+
+ if (p->input_style & (XIMPreeditArea|XIMPreeditPosition|XIMStatusArea)) {
+ if (p->flg & CIFontSet) {
+ SetVaArg( &pe_a[pe_cnt], (XPointer) XNFontSet); pe_cnt++;
+ SetVaArg( &pe_a[pe_cnt], (XPointer) p->font_set); pe_cnt++;
+ SetVaArg( &st_a[st_cnt], (XPointer) XNFontSet); st_cnt++;
+ SetVaArg( &st_a[st_cnt], (XPointer) p->font_set); st_cnt++;
+ height = maxAscentOfFontSet(p->font_set)
+ + maxDescentOfFontSet(p->font_set);
+ height = SetVendorShellHeight(ve, height);
+ }
+ if (p->flg & CIFg) {
+ SetVaArg( &pe_a[pe_cnt], (XPointer) XNForeground); pe_cnt++;
+ SetVaArg( &pe_a[pe_cnt], (XPointer) p->foreground); pe_cnt++;
+ SetVaArg( &st_a[st_cnt], (XPointer) XNForeground); st_cnt++;
+ SetVaArg( &st_a[st_cnt], (XPointer) p->foreground); st_cnt++;
+ }
+ if (p->flg & CIBg) {
+ SetVaArg( &pe_a[pe_cnt], (XPointer) XNBackground); pe_cnt++;
+ SetVaArg( &pe_a[pe_cnt], (XPointer) p->background); pe_cnt++;
+ SetVaArg( &st_a[st_cnt], (XPointer) XNBackground); st_cnt++;
+ SetVaArg( &st_a[st_cnt], (XPointer) p->background); st_cnt++;
+ }
+ if (p->flg & CIBgPixmap) {
+ SetVaArg( &pe_a[pe_cnt], (XPointer) XNBackgroundPixmap); pe_cnt++;
+ SetVaArg( &pe_a[pe_cnt], (XPointer) p->bg_pixmap); pe_cnt++;
+ SetVaArg( &st_a[st_cnt], (XPointer) XNBackgroundPixmap); st_cnt++;
+ SetVaArg( &st_a[st_cnt], (XPointer) p->bg_pixmap); st_cnt++;
+ }
+ if (p->flg & CILineS) {
+ SetVaArg( &pe_a[pe_cnt], (XPointer) XNLineSpace); pe_cnt++;
+ SetVaArg( &pe_a[pe_cnt], (XPointer) p->line_spacing); pe_cnt++;
+ SetVaArg( &st_a[st_cnt], (XPointer) XNLineSpace); st_cnt++;
+ SetVaArg( &st_a[st_cnt], (XPointer) p->line_spacing); st_cnt++;
+ }
+ }
+ if (p->input_style & XIMPreeditPosition) {
+ if (p->flg & CICursorP) {
+ _XawMultiSinkPosToXY(w, p->cursor_position, &position.x, &position.y);
+ SetVaArg( &pe_a[pe_cnt], (XPointer) XNSpotLocation); pe_cnt++;
+ SetVaArg( &pe_a[pe_cnt], (XPointer) &position); pe_cnt++;
+ }
+ }
+ if (IsSharedIC(ve)) {
+ if (p->input_style & XIMPreeditPosition) {
+ pe_area.x = 0;
+ pe_area.y = 0;
+ pe_area.width = w->core.width;
+ pe_area.height = w->core.height;
+ margin = &(((TextWidget)w)->text.margin);
+ pe_area.x += margin->left;
+ pe_area.y += margin->top;
+ pe_area.width -= (margin->left + margin->right - 1);
+ pe_area.height -= (margin->top + margin->bottom - 1);
+ SetVaArg( &pe_a[pe_cnt], (XPointer) XNArea); pe_cnt++;
+ SetVaArg( &pe_a[pe_cnt], (XPointer) &pe_area); pe_cnt++;
+ }
+ }
+
+ if (pe_cnt > 0) {
+ SetVaArg( &pe_a[pe_cnt], (XPointer) NULL);
+ pe_attr = XVaCreateNestedList(0, pe_a[0], pe_a[1], pe_a[2], pe_a[3],
+ pe_a[4], pe_a[5], pe_a[6], pe_a[7],
+ pe_a[8], pe_a[9], pe_a[10], pe_a[11],
+ pe_a[12], pe_a[13], pe_a[14], pe_a[15],
+ pe_a[16], pe_a[17], pe_a[18], pe_a[19]);
+ SetVaArg( &ic_a[ic_cnt], (XPointer) XNPreeditAttributes); ic_cnt++;
+ SetVaArg( &ic_a[ic_cnt], (XPointer) pe_attr); ic_cnt++;
+ }
+ if (st_cnt > 0) {
+ SetVaArg( &st_a[st_cnt], (XPointer) NULL);
+ st_attr = XVaCreateNestedList(0, st_a[0], st_a[1], st_a[2], st_a[3],
+ st_a[4], st_a[5], st_a[6], st_a[7],
+ st_a[8], st_a[9], st_a[10], st_a[11],
+ st_a[12], st_a[13], st_a[14], st_a[15],
+ st_a[16], st_a[17], st_a[18], st_a[19]);
+ SetVaArg( &ic_a[ic_cnt], (XPointer) XNStatusAttributes); ic_cnt++;
+ SetVaArg( &ic_a[ic_cnt], (XPointer) st_attr); ic_cnt++;
+ }
+ if (focus == TRUE) {
+ SetVaArg( &ic_a[ic_cnt], (XPointer) XNFocusWindow); ic_cnt++;
+ SetVaArg( &ic_a[ic_cnt], (XPointer) XtWindow(w)); ic_cnt++;
+ }
+ if (ic_cnt > 0) {
+ SetVaArg( &ic_a[ic_cnt], (XPointer) NULL);
+ XSetICValues(p->xic, ic_a[0], ic_a[1], ic_a[2], ic_a[3], ic_a[4],
+ ic_a[5], ic_a[6], ic_a[7], ic_a[8], ic_a[9], ic_a[10],
+ ic_a[11], ic_a[12], ic_a[13], ic_a[14], ic_a[15],
+ ic_a[16], ic_a[17], ic_a[18], ic_a[19]);
+ if (pe_attr) XtFree(pe_attr);
+ if (st_attr) XtFree(st_attr);
+ }
+
+ if (IsSharedIC(ve) && p->flg & CIFontSet)
+ SizeNegotiation(p, ve->parent->core.width, ve->parent->core.height);
+
+ p->flg &= ~(CIFontSet | CIFg | CIBg | CIBgPixmap | CICursorP | CILineS);
+}
+
+static void SharedICChangeFocusWindow(w, ve, p)
+ Widget w;
+ XawVendorShellExtPart *ve;
+ XawIcTableList p;
+{
+ XawIcTableList pp;
+
+ if (w == NULL) {
+ ve->ic.current_ic_table = NULL;
+ return;
+ }
+ if ((pp = GetIcTable(w, ve)) == NULL) return;
+ ve->ic.current_ic_table = pp;
+ SetICValues(w, ve, TRUE);
+}
+
+static XawIcTableList CurrentSharedIcTable( ve )
+ XawVendorShellExtPart * ve;
+{
+ return(ve->ic.current_ic_table);
+}
+
+static void SetICFocus(w, ve)
+ Widget w;
+ XawVendorShellExtPart * ve;
+{
+ XawIcTableList p, pp;
+
+ if ((ve->im.xim == NULL) || ((p = GetIcTableShared(w, ve)) == NULL) ||
+ (p->xic == NULL)) return;
+
+ if (IsSharedIC(ve)) {
+ pp = CurrentSharedIcTable(ve);
+ if (pp == NULL || pp->widget != w) {
+ SharedICChangeFocusWindow(w, ve, p);
+ }
+ }
+ if (p->flg & CIICFocus && p->ic_focused == FALSE) {
+ p->ic_focused = TRUE;
+ XSetICFocus(p->xic);
+ }
+ p->flg &= ~CIICFocus;
+}
+
+static void UnsetICFocus(w, ve)
+ Widget w;
+ XawVendorShellExtPart * ve;
+{
+ XawIcTableList p, pp;
+
+ if ((ve->im.xim == NULL) || ((p = GetIcTableShared(w, ve)) == NULL) ||
+ (p->xic == NULL)) return;
+
+ if (IsSharedIC(ve) && (pp = CurrentSharedIcTable(ve))) {
+ if (pp->widget != w) {
+ return;
+ }
+ SharedICChangeFocusWindow(NULL, ve, p);
+ }
+ if (p->ic_focused == TRUE) {
+ XUnsetICFocus(p->xic);
+ p->ic_focused = FALSE;
+ }
+}
+
+static void SetValues( w, ve, args, num_args )
+ Widget w;
+ XawVendorShellExtPart * ve;
+ ArgList args;
+ Cardinal num_args;
+{
+ ArgList arg;
+
+ XrmName argName;
+ XrmResourceList xrmres;
+ int i;
+ XawIcTablePart *p, save_tbl;
+
+ if ((p = GetIcTable(w, ve)) == NULL) return;
+
+ memcpy(&save_tbl, p, sizeof(XawIcTablePart));
+
+ for (arg = args ; num_args != 0; num_args--, arg++) {
+ argName = XrmStringToName(arg->name);
+ for (xrmres = (XrmResourceList)ve->im.resources, i = 0;
+ i < ve->im.num_resources; i++, xrmres++) {
+ if (argName == xrmres->xrm_name) {
+ _XtCopyFromArg(arg->value,
+ (char *)p - xrmres->xrm_offset - 1,
+ xrmres->xrm_size);
+ break;
+ }
+ }
+ }
+ if (p->font_set != save_tbl.font_set) {
+ p->flg |= CIFontSet;
+ }
+ if (p->foreground != save_tbl.foreground) {
+ p->flg |= CIFg;
+ }
+ if (p->background !=save_tbl.background) {
+ p->flg |= CIBg;
+ }
+ if (p->bg_pixmap != save_tbl.bg_pixmap) {
+ p->flg |= CIBgPixmap;
+ }
+ if (p->cursor_position != save_tbl.cursor_position) {
+ p->flg |= CICursorP;
+ }
+ if (p->line_spacing != save_tbl.line_spacing) {
+ p->flg |= CILineS;
+ }
+ p->prev_flg |= p->flg;
+}
+
+static void SetFocus( w, ve )
+ Widget w;
+ XawVendorShellExtPart *ve;
+{
+ XawIcTableList p;
+ if ((p = GetIcTableShared(w, ve)) == NULL) return;
+
+ if ( p->ic_focused == FALSE || IsSharedIC(ve)) {
+ p->flg |= CIICFocus;
+ }
+ p->prev_flg |= p->flg;
+}
+
+static void DestroyIC(w, ve)
+ Widget w;
+ XawVendorShellExtPart *ve;
+{
+ XawIcTableList p;
+
+ if ((ve->im.xim == NULL) || ((p = GetIcTableShared(w, ve)) == NULL) ||
+ (p->xic == NULL)) return;
+ if (IsSharedIC(ve)) {
+ if (GetIcTable(w, ve) == ve->ic.current_ic_table) {
+ UnsetICFocus(w, ve);
+ }
+ return;
+ }
+ XDestroyIC(p->xic);
+ if (!IsSharedIC(ve)) {
+ if (p->input_style & XIMPreeditPosition) {
+ XtRemoveEventHandler(w, (EventMask)StructureNotifyMask, FALSE,
+ (XtEventHandler)ConfigureCB, (Opaque)NULL);
+ }
+ }
+}
+
+static void SetFocusValues( inwidg, args, num_args, focus )
+ Widget inwidg;
+ ArgList args;
+ Cardinal num_args;
+ Boolean focus;
+{
+ XawVendorShellExtPart *ve;
+ VendorShellWidget vw;
+
+ if ((vw = SearchVendorShell(inwidg)) == NULL) return;
+ if ((ve = GetExtPart(vw))) {
+ if (num_args > 0) SetValues(inwidg, ve, args, num_args);
+ if (focus) SetFocus(inwidg, ve);
+ if (XtIsRealized((Widget)vw) && ve->im.xim) {
+ if (IsCreatedIC(inwidg, ve)) {
+ SetICValues(inwidg, ve, FALSE);
+ if (focus) SetICFocus(inwidg, ve);
+ } else {
+ CreateIC(inwidg, ve);
+ SetICFocus(inwidg, ve);
+ }
+ }
+ }
+}
+
+static void UnsetFocus( inwidg )
+ Widget inwidg;
+{
+ XawVendorShellExtPart *ve;
+ VendorShellWidget vw;
+ XawIcTableList p;
+
+ if ((vw = SearchVendorShell(inwidg)) == NULL) return;
+ if ((ve = GetExtPart(vw))) {
+ if ((p = GetIcTableShared(inwidg, ve)) == NULL) return;
+ if (p->flg & CIICFocus) {
+ p->flg &= ~CIICFocus;
+ }
+ p->prev_flg &= ~CIICFocus;
+ if (ve->im.xim && XtIsRealized((Widget)vw) && p->xic) {
+ UnsetICFocus(inwidg, ve);
+ }
+ }
+}
+
+static Boolean IsRegistered( w, ve )
+ Widget w;
+ XawVendorShellExtPart* ve;
+{
+ XawIcTableList p;
+
+ for (p = ve->ic.ic_table; p; p = p->next)
+ {
+ if (p->widget == w) return(TRUE);
+ }
+ return(FALSE);
+}
+
+static void Register(inwidg, ve)
+ Widget inwidg;
+ XawVendorShellExtPart* ve;
+{
+ if (ve->im.xim == NULL)
+ {
+ OpenIM(ve);
+ }
+
+ if (IsRegistered(inwidg, ve)) return;
+
+ if (RegisterToVendorShell(inwidg, ve) == FALSE) return;
+
+ if (ve->im.xim == NULL) return;
+
+ if (XtIsRealized(ve->parent))
+ {
+ CreateIC(inwidg, ve);
+ SetICFocus(inwidg, ve);
+ }
+}
+
+static Boolean NoRegistered(ve)
+ XawVendorShellExtPart* ve;
+{
+ if (ve->ic.ic_table == NULL) return(TRUE);
+ return(FALSE);
+}
+
+static void Unregister(inwidg, ve)
+ Widget inwidg;
+ XawVendorShellExtPart* ve;
+{
+ if (!IsRegistered(inwidg, ve)) return;
+
+ DestroyIC(inwidg, ve);
+
+ UnregisterFromVendorShell(inwidg, ve);
+
+ if (NoRegistered(ve))
+ {
+ CloseIM(ve);
+ ve->im.xim = NULL;
+ /*
+ * resize vendor shell to core size
+ */
+ (void) SetVendorShellHeight(ve, 0);
+ }
+}
+
+static void AllCreateIC( ve )
+ XawVendorShellExtPart* ve;
+{
+ XawIcTableList p;
+
+ if (ve->im.xim == NULL) return;
+ if (IsSharedIC(ve) && ve->ic.ic_table[0].widget) {
+ p = ve->ic.shared_ic_table;
+ if (p->xic == NULL)
+ CreateIC(ve->ic.ic_table[0].widget, ve);
+ SetICFocus(ve->ic.ic_table[0].widget, ve);
+ return;
+ }
+ for (p = ve->ic.ic_table; p; p = p->next) {
+ if (p->xic == NULL)
+ CreateIC(p->widget, ve);
+ }
+ for (p = ve->ic.ic_table; p; p = p->next) {
+ SetICFocus(p->widget, ve);
+ }
+}
+
+
+static void Reconnect(ve)
+ XawVendorShellExtPart* ve;
+{
+ XawIcTableList p;
+
+ ve->im.open_im = True;
+ if (ve->im.xim == NULL) {
+ OpenIM(ve);
+ }
+ if (ve->im.xim == NULL) return;
+
+ if (IsSharedIC(ve)) {
+ p = ve->ic.shared_ic_table;
+ p->flg = p->prev_flg;
+ p->openic_error = FALSE;
+ } else {
+ for (p = ve->ic.ic_table; p; p = p->next) {
+ p->flg = p->prev_flg;
+ p->openic_error = FALSE;
+ }
+ }
+ AllCreateIC(ve);
+}
+
+
+static void CompileResourceList( res, num_res )
+ XtResourceList res;
+ unsigned int num_res;
+{
+ unsigned int count;
+
+#define xrmres ((XrmResourceList) res)
+ for (count = 0; count < num_res; res++, count++) {
+ xrmres->xrm_name = XrmPermStringToQuark(res->resource_name);
+ xrmres->xrm_class = XrmPermStringToQuark(res->resource_class);
+ xrmres->xrm_type = XrmPermStringToQuark(res->resource_type);
+ xrmres->xrm_offset = -res->resource_offset - 1;
+ xrmres->xrm_default_type = XrmPermStringToQuark(res->default_type);
+ }
+#undef xrmres
+}
+
+static Boolean Initialize( vw, ve )
+ VendorShellWidget vw;
+ XawVendorShellExtPart* ve;
+{
+ int i;
+
+ if (!XtIsVendorShell((Widget)vw)) return(FALSE);
+ ve->parent = (Widget)vw;
+ ve->im.xim = NULL;
+ ve->im.area_height = 0;
+ ve->im.resources = (XrmResourceList)XtMalloc(sizeof(resources));
+ if (ve->im.resources == NULL) return(FALSE);
+ memcpy((char *)ve->im.resources, (char *)resources, sizeof(resources));
+ ve->im.num_resources = XtNumber(resources);
+ CompileResourceList( (XtResourceList) ve->im.resources,
+ ve->im.num_resources );
+ if ((ve->ic.shared_ic_table = CreateIcTable( (Widget)vw, ve)) == NULL)
+ return(FALSE);
+ ve->ic.current_ic_table = NULL;
+ ve->ic.ic_table = NULL;
+ return(TRUE);
+}
+
+
+/* Destroy()
+ *
+ * This frees all (most?) of the resources malloced by XawIm.
+ * It is called by _XawImDestroy, which is called by Vendor.c's
+ * VendorExt's Destroy method. Sheeran, Omron KK, 93/08/05 */
+
+static void Destroy( w, ve )
+ Widget w;
+ XawVendorShellExtPart* ve;
+{
+ contextDataRec *contextData;
+ contextErrDataRec *contextErrData;
+
+ if (!XtIsVendorShell( w ) )
+ return;
+ XtFree( (char*) ve->im.resources );
+
+ if (extContext != (XContext)NULL &&
+ !XFindContext (XtDisplay (w), (Window)w,
+ extContext, (XPointer*)&contextData))
+ XtFree( (char*) contextData );
+
+ if (errContext != (XContext)NULL &&
+ !XFindContext (XDisplayOfIM( ve->im.xim ), (Window) ve->im.xim,
+ errContext, (XPointer*) &contextErrData))
+ XtFree( (char*) contextErrData );
+}
+
+/*********************************************
+ *
+ * SEMI-PRIVATE FUNCTIONS
+ * For use by other Xaw modules
+ *
+ ********************************************/
+
+void
+#if NeedFunctionPrototypes
+_XawImResizeVendorShell(
+ Widget w )
+#else
+_XawImResizeVendorShell( w )
+ Widget w;
+#endif
+{
+ XawVendorShellExtPart *ve;
+
+ if ( ( ve = GetExtPart( (VendorShellWidget) w ) ) && ve->im.xim ) {
+ ResizeVendorShell( (VendorShellWidget) w, ve );
+ }
+}
+
+
+Dimension
+#if NeedFunctionPrototypes
+_XawImGetShellHeight(
+ Widget w )
+#else
+_XawImGetShellHeight( w )
+ Widget w;
+#endif
+{
+ XawVendorShellExtPart *ve;
+
+ if (!XtIsVendorShell( w ) ) return( w->core.height );
+ if ((ve = GetExtPart( (VendorShellWidget) w ))) {
+ return( w->core.height - ve->im.area_height );
+ }
+ return( w->core.height );
+}
+
+void
+#if NeedFunctionPrototypes
+_XawImRealize(
+ Widget w )
+#else
+_XawImRealize( w )
+ Widget w;
+#endif
+{
+ XawVendorShellExtPart *ve;
+ extern void XawVendorShellExtResize();
+
+ if ( !XtIsRealized( w ) || !XtIsVendorShell( w ) ) return;
+ if ((ve = GetExtPart( (VendorShellWidget) w ))) {
+ XtAddEventHandler( w, (EventMask)StructureNotifyMask, FALSE,
+ XawVendorShellExtResize, (XtPointer)NULL );
+ AllCreateIC(ve);
+ }
+}
+
+void
+#if NeedFunctionPrototypes
+_XawImInitialize(
+ Widget w,
+ Widget ext )
+#else
+_XawImInitialize( w, ext )
+ Widget w, ext;
+#endif
+{
+ XawVendorShellExtPart *ve;
+
+ if ( !XtIsVendorShell( w ) ) return;
+ if ((ve = SetExtPart( (VendorShellWidget) w, (XawVendorShellExtWidget)ext)) ) {
+ if ( Initialize( (VendorShellWidget) w, ve ) == FALSE ) return;
+ XtAddCallback( w, XtNdestroyCallback, VendorShellDestroyed,
+ (XtPointer) NULL );
+ }
+}
+
+void
+#if NeedFunctionPrototypes
+_XawImReconnect(
+ Widget inwidg )
+#else
+_XawImReconnect( inwidg )
+ Widget inwidg;
+#endif
+{
+ XawVendorShellExtPart *ve;
+ VendorShellWidget vw;
+
+ if ((vw = SearchVendorShell(inwidg)) == NULL) return;
+ if ((ve = GetExtPart(vw))) {
+ Reconnect(ve);
+ }
+}
+
+void
+#if NeedFunctionPrototypes
+_XawImRegister(
+ Widget inwidg)
+#else
+_XawImRegister(inwidg)
+ Widget inwidg;
+#endif
+{
+ XawVendorShellExtPart *ve;
+ VendorShellWidget vw;
+
+ if ((vw = SearchVendorShell(inwidg)) == NULL) return;
+ if ((ve = GetExtPart(vw))) {
+ Register(inwidg, ve);
+ }
+}
+
+void
+#if NeedFunctionPrototypes
+_XawImUnregister(
+ Widget inwidg)
+#else
+_XawImUnregister(inwidg)
+ Widget inwidg;
+#endif
+{
+ XawVendorShellExtPart *ve;
+ VendorShellWidget vw;
+
+ if ((vw = SearchVendorShell(inwidg)) == NULL) return;
+ if ((ve = GetExtPart(vw))) {
+ Unregister(inwidg, ve);
+ }
+}
+
+void
+#if NeedFunctionPrototypes
+_XawImSetValues(
+ Widget inwidg,
+ ArgList args,
+ Cardinal num_args )
+#else
+_XawImSetValues( inwidg, args, num_args )
+ Widget inwidg;
+ ArgList args;
+ Cardinal num_args;
+#endif
+{
+ SetFocusValues( inwidg, args, num_args, FALSE );
+}
+
+void
+#if NeedVarargsPrototypes
+_XawImVASetValues( Widget inwidg, ... )
+#else
+_XawImVASetValues( inwidg, va_alist )
+ Widget inwidg;
+ va_dcl
+#endif
+{
+ va_list var;
+ ArgList args = NULL;
+ Cardinal num_args;
+ int total_count, typed_count;
+
+ Va_start( var, inwidg );
+ _XtCountVaList( var, &total_count, &typed_count );
+ va_end( var );
+
+ Va_start( var, inwidg );
+
+ _XtVaToArgList( inwidg, var, total_count, &args, &num_args );
+ _XawImSetValues( inwidg, args, num_args );
+ if ( args != NULL ) {
+ XtFree( (XtPointer) args );
+ }
+ va_end( var );
+}
+
+void
+#if NeedFunctionPrototypes
+_XawImSetFocusValues(
+ Widget inwidg,
+ ArgList args,
+ Cardinal num_args)
+#else
+_XawImSetFocusValues(inwidg, args, num_args)
+ Widget inwidg;
+ ArgList args;
+ Cardinal num_args;
+#endif
+{
+ SetFocusValues(inwidg, args, num_args, TRUE);
+}
+
+void
+#if NeedVarargsPrototypes
+_XawImVASetFocusValues(Widget inwidg, ...)
+#else
+_XawImVASetFocusValues(inwidg, va_alist)
+ Widget inwidg;
+ va_dcl
+#endif
+{
+ va_list var;
+ ArgList args = NULL;
+ Cardinal num_args;
+ int total_count, typed_count;
+
+ Va_start(var, inwidg);
+ _XtCountVaList(var, &total_count, &typed_count);
+ va_end(var);
+
+ Va_start(var,inwidg);
+
+ _XtVaToArgList(inwidg, var, total_count, &args, &num_args);
+ _XawImSetFocusValues(inwidg, args, num_args);
+ if (args != NULL) {
+ XtFree((XtPointer)args);
+ }
+ va_end(var);
+}
+
+void
+#if NeedFunctionPrototypes
+_XawImUnsetFocus(
+ Widget inwidg)
+#else
+_XawImUnsetFocus(inwidg)
+ Widget inwidg;
+#endif
+{
+ UnsetFocus(inwidg);
+}
+
+int
+#if NeedFunctionPrototypes
+_XawImWcLookupString(
+ Widget inwidg,
+ XKeyPressedEvent *event,
+ wchar_t* buffer_return,
+ int bytes_buffer,
+ KeySym *keysym_return,
+ Status *status_return)
+#else
+_XawImWcLookupString( inwidg, event, buffer_return, bytes_buffer,
+ keysym_return, status_return)
+ Widget inwidg;
+ XKeyPressedEvent* event;
+ wchar_t* buffer_return;
+ int bytes_buffer;
+ KeySym* keysym_return;
+ Status* status_return;
+#endif
+{
+ XawVendorShellExtPart* ve;
+ VendorShellWidget vw;
+ XawIcTableList p;
+ int i, ret;
+ char tmp_buf[64], *tmp_p;
+ wchar_t* buf_p;
+
+ if ((vw = SearchVendorShell(inwidg)) && (ve = GetExtPart(vw)) &&
+ ve->im.xim && (p = GetIcTableShared(inwidg, ve)) && p->xic) {
+ return(XwcLookupString(p->xic, event, buffer_return, bytes_buffer,
+ keysym_return, status_return));
+ }
+ ret = XLookupString( event, tmp_buf, 64, keysym_return,
+ (XComposeStatus*) status_return );
+ for ( i = 0, tmp_p = tmp_buf, buf_p = buffer_return; i < ret; i++ ) {
+ *buf_p++ = _Xaw_atowc(*tmp_p++);
+ }
+ return( ret );
+}
+
+int
+#if NeedFunctionPrototypes
+_XawImGetImAreaHeight(
+ Widget w)
+#else
+_XawImGetImAreaHeight( w )
+ Widget w;
+#endif
+{
+ XawVendorShellExtPart *ve;
+ VendorShellWidget vw;
+
+ if ((vw = SearchVendorShell(w)) && (ve = GetExtPart(vw))) {
+ return(ve->im.area_height);
+ }
+ return(0);
+}
+
+void
+#if NeedFunctionPrototypes
+_XawImCallVendorShellExtResize(
+ Widget w)
+#else
+_XawImCallVendorShellExtResize( w )
+ Widget w;
+#endif
+{
+ XawVendorShellExtPart *ve;
+ VendorShellWidget vw;
+ extern void XawVendorShellExtResize();
+
+ if ((vw = SearchVendorShell(w)) && (ve = GetExtPart(vw))) {
+ XawVendorShellExtResize(vw);
+ }
+}
+
+
+/* _XawImDestroy()
+ *
+ * This should be called by the VendorExt from its
+ * core Destroy method. Sheeran, Omron KK 93/08/05 */
+
+void
+#if NeedFunctionPrototypes
+_XawImDestroy(
+ Widget w,
+ Widget ext )
+#else
+_XawImDestroy( w, ext )
+ Widget w;
+ Widget ext;
+#endif
+{
+ XawVendorShellExtPart *ve;
+
+ if ( !XtIsVendorShell( w ) ) return;
+ if ((ve = GetExtPart( (VendorShellWidget) w )))
+ Destroy( w, ve );
+}
diff --git a/src/XawImP.h b/src/XawImP.h
new file mode 100644
index 0000000..4c398ff
--- /dev/null
+++ b/src/XawImP.h
@@ -0,0 +1,240 @@
+/* $XConsortium: XawImP.h,v 1.4 95/06/06 20:50:30 kaleb Exp $ */
+
+/*
+ * Copyright 1991 by OMRON Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, 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 OMRON not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. OMRON makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * OMRON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * OMRON 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 TORTUOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ * Author: Seiji Kuwari OMRON Corporation
+ * kuwa@omron.co.jp
+ * kuwa%omron.co.jp@uunet.uu.net
+ */
+
+/*
+
+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.
+
+*/
+
+#ifndef _XawImP_h
+#define _XawImP_h
+
+#define XtNinputMethod "inputMethod"
+#define XtCInputMethod "InputMethod"
+#define XtNpreeditType "preeditType"
+#define XtCPreeditType "PreeditType"
+#define XtNopenIm "openIm"
+#define XtCOpenIm "OpenIm"
+#define XtNsharedIc "sharedIc"
+#define XtCSharedIc "SharedIc"
+
+#include <X11/Xaw3d/Text.h>
+
+#define CIICFocus (1 << 0)
+#define CIFontSet (1 << 1)
+#define CIFg (1 << 2)
+#define CIBg (1 << 3)
+#define CIBgPixmap (1 << 4)
+#define CICursorP (1 << 5)
+#define CILineS (1 << 6)
+
+typedef struct _XawImPart
+{
+ XIM xim;
+ XrmResourceList resources;
+ Cardinal num_resources;
+ Boolean open_im;
+ Boolean initialized;
+ Dimension area_height;
+ String input_method;
+ String preedit_type;
+} XawImPart;
+
+typedef struct _XawIcTablePart
+{
+ Widget widget;
+ XIC xic;
+ XIMStyle input_style;
+ unsigned long flg;
+ unsigned long prev_flg;
+ Boolean ic_focused;
+ XFontSet font_set;
+ Pixel foreground;
+ Pixel background;
+ Pixmap bg_pixmap;
+ XawTextPosition cursor_position;
+ unsigned long line_spacing;
+ Boolean openic_error;
+ struct _XawIcTablePart *next;
+} XawIcTablePart, *XawIcTableList;
+
+typedef struct _XawIcPart
+{
+ XIMStyle input_style;
+ Boolean shared_ic;
+ XawIcTableList shared_ic_table;
+ XawIcTableList current_ic_table;
+ XawIcTableList ic_table;
+} XawIcPart;
+
+typedef struct _contextDataRec
+{
+ Widget parent;
+ Widget ve;
+} contextDataRec;
+
+typedef struct _contextErrDataRec
+{
+ Widget widget;
+ XIM xim;
+} contextErrDataRec;
+
+void _XawImResizeVendorShell(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+Dimension _XawImGetShellHeight(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+void _XawImRealize(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+void _XawImInitialize(
+#if NeedFunctionPrototypes
+ Widget, /* w */
+ Widget /* ext */
+#endif
+);
+
+void _XawImReconnect(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+void _XawImRegister(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+void _XawImUnregister(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+void _XawImSetValues(
+#if NeedFunctionPrototypes
+ Widget, /* w */
+ ArgList, /* args */
+ Cardinal /* num_args */
+#endif
+);
+
+/* DON'T USE THIS FUNCTION -- it's going away in the next release */
+void _XawImVASetValues(
+#if NeedVarargsPrototypes
+ Widget, /* w */
+ ...
+#endif
+);
+
+void _XawImSetFocusValues(
+#if NeedFunctionPrototypes
+ Widget, /* w */
+ ArgList, /* args */
+ Cardinal /* num_args */
+#endif
+);
+
+/* DON'T USE THIS FUNCTION -- it's going away in the next release */
+void _XawImVASetFocusValues(
+#if NeedVarargsPrototypes
+ Widget, /* w */
+ ...
+#endif
+);
+
+void _XawImUnsetFocus(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+int _XawImWcLookupString(
+#if NeedFunctionPrototypes
+ Widget, /* w */
+ XKeyPressedEvent*, /* event */
+ wchar_t*, /* buffer_return */
+ int, /* bytes_buffer */
+ KeySym*, /* keysym_return */
+ Status* /* status return */
+#endif
+);
+
+int _XawImGetImAreaHeight(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+void _XawImCallVendorShellExtResize(
+#if NeedFunctionPrototypes
+ Widget /* w */
+#endif
+);
+
+void _XawImDestroy(
+#if NeedFunctionPrototypes
+ Widget, /* w */
+ Widget /* ext */
+#endif
+);
+
+#endif /* _XawImP_h */
diff --git a/src/XawInit.c b/src/XawInit.c
new file mode 100644
index 0000000..b2bd482
--- /dev/null
+++ b/src/XawInit.c
@@ -0,0 +1,49 @@
+/*
+ * $XConsortium: XawInit.c,v 1.3 94/04/17 20:13:32 jim Exp $
+ *
+Copyright (c) 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.
+ *
+ *
+ * XawInitializeWidgetSet
+ *
+ * This routine forces a reference to vendor shell so that the one in this
+ * widget is installed. Any other cross-widget set initialization should be
+ * done here as well. All Athena widgets should include "XawInit.h" and
+ * call this routine from their ClassInitialize procs (this routine may be
+ * used as the class init proc).
+ */
+
+#include <X11/Intrinsic.h>
+#include <X11/Vendor.h>
+#include <X11/Xaw3d/XawInit.h>
+
+void XawInitializeWidgetSet ()
+{
+ static int firsttime = 1;
+
+ if (firsttime) {
+ firsttime = 0;
+ XtInitializeWidgetClass (vendorShellWidgetClass);
+ }
+}
diff --git a/src/XawInit.h b/src/XawInit.h
new file mode 100644
index 0000000..5d19f88
--- /dev/null
+++ b/src/XawInit.h
@@ -0,0 +1,31 @@
+/* $XConsortium: XawInit.h,v 1.6 94/04/17 20:13:33 kaleb Exp $
+ *
+Copyright (c) 1989, 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.
+ */
+
+_XFUNCPROTOBEGIN
+
+extern void XawInitializeWidgetSet(); /* called from ClassInit procs */
+
+_XFUNCPROTOEND
diff --git a/src/laygram.y b/src/laygram.y
new file mode 100644
index 0000000..c209b64
--- /dev/null
+++ b/src/laygram.y
@@ -0,0 +1,263 @@
+%{
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+#include <stdio.h>
+#include <X11/IntrinsicP.h>
+#include <X11/cursorfont.h>
+#include <X11/StringDefs.h>
+
+#include <X11/Xmu/Misc.h>
+#include <X11/Xmu/Converters.h>
+#include "LayoutP.h"
+
+static LayoutPtr *dest;
+
+%}
+
+%union {
+ int ival;
+ XrmQuark qval;
+ BoxPtr bval;
+ BoxParamsPtr pval;
+ GlueRec gval;
+ LayoutDirection lval;
+ ExprPtr eval;
+ Operator oval;
+}
+
+%type <bval> box boxes compositebox
+%type <pval> bothparams oneparams
+%type <gval> glue opStretch opShrink
+%type <lval> orientation
+%type <eval> signedExpr simpleExpr expr
+
+%token OC CC OA CA OP CP
+%token <qval> NAME
+%token <ival> NUMBER
+%token <ival> INFINITY
+%token VERTICAL HORIZONTAL
+
+%token EQUAL DOLLAR
+
+%left <oval> PLUS MINUS
+%left <oval> TIMES DIVIDE PERCENTOF
+%right <oval> PERCENT
+%nonassoc WIDTH HEIGHT
+%right <oval> UMINUS UPLUS
+
+%%
+layout : compositebox
+ { *dest = $1; }
+ ;
+box : NAME bothparams
+ {
+ BoxPtr box = New(LBoxRec);
+ box->nextSibling = 0;
+ box->type = WidgetBox;
+ box->params = *$2;
+ Dispose ($2);
+ box->u.widget.quark = $1;
+ $$ = box;
+ }
+ | signedExpr oneparams
+ {
+ BoxPtr box = New(LBoxRec);
+ box->nextSibling = 0;
+ box->type = GlueBox;
+ box->params = *$2;
+ Dispose ($2);
+ box->u.glue.expr = $1;
+ $$ = box;
+ }
+ | NAME EQUAL signedExpr
+ {
+ BoxPtr box = New(LBoxRec);
+ box->nextSibling = 0;
+ box->type = VariableBox;
+ box->u.variable.quark = $1;
+ box->u.variable.expr = $3;
+ $$ = box;
+ }
+ | compositebox
+ {
+ $$ = $1;
+ }
+ ;
+compositebox : orientation OC boxes CC
+ {
+ BoxPtr box = New(LBoxRec);
+ BoxPtr child;
+
+ box->nextSibling = 0;
+ box->parent = 0;
+ box->type = BoxBox;
+ box->u.box.dir = $1;
+ box->u.box.firstChild = $3;
+ for (child = $3; child; child = child->nextSibling)
+ {
+ if (child->type == GlueBox)
+ {
+ child->params.stretch[!$1].expr = 0;
+ child->params.shrink[!$1].expr = 0;
+ child->params.stretch[!$1].order = 100000;
+ child->params.shrink[!$1].order = 100000;
+ child->params.stretch[!$1].value = 1;
+ child->params.shrink[!$1].value = 1;
+ }
+ child->parent = box;
+ }
+ $$ = box;
+ }
+ ;
+boxes : box boxes
+ {
+ $1->nextSibling = $2;
+ $$ = $1;
+ }
+ | box
+ { $$ = $1; }
+ ;
+bothparams : OA opStretch opShrink TIMES opStretch opShrink CA
+ {
+ BoxParamsPtr p = New(BoxParamsRec);
+
+ p->stretch[LayoutHorizontal] = $2;
+ p->shrink[LayoutHorizontal] = $3;
+ p->stretch[LayoutVertical] = $5;
+ p->shrink[LayoutVertical] = $6;
+ $$ = p;
+ }
+ |
+ {
+ BoxParamsPtr p = New(BoxParamsRec);
+
+ ZeroGlue (p->stretch[LayoutHorizontal]);
+ ZeroGlue (p->shrink[LayoutHorizontal]);
+ ZeroGlue (p->stretch[LayoutVertical]);
+ ZeroGlue (p->shrink[LayoutVertical]);
+ $$ = p;
+ }
+ ;
+oneparams : OA opStretch opShrink CA
+ {
+ BoxParamsPtr p = New(BoxParamsRec);
+
+ p->stretch[LayoutHorizontal] = $2;
+ p->shrink[LayoutHorizontal] = $3;
+ p->stretch[LayoutVertical] = $2;
+ p->shrink[LayoutVertical] = $3;
+ $$ = p;
+ }
+ |
+ {
+ BoxParamsPtr p = New(BoxParamsRec);
+
+ ZeroGlue (p->stretch[LayoutHorizontal]);
+ ZeroGlue (p->shrink[LayoutHorizontal]);
+ ZeroGlue (p->stretch[LayoutVertical]);
+ ZeroGlue (p->shrink[LayoutVertical]);
+ $$ = p;
+ }
+ ;
+opStretch : PLUS glue
+ { $$ = $2; }
+ |
+ { ZeroGlue ($$); }
+ ;
+opShrink : MINUS glue
+ { $$ = $2; }
+ |
+ { ZeroGlue ($$); }
+ ;
+glue : simpleExpr INFINITY
+ { $$.order = $2; $$.expr = $1; }
+ | simpleExpr
+ { $$.order = 0; $$.expr = $1; }
+ | INFINITY
+ { $$.order = $1; $$.expr = 0; $$.value = 1; }
+ ;
+signedExpr : MINUS simpleExpr %prec UMINUS
+ {
+ $$ = New(ExprRec);
+ $$->type = Unary;
+ $$->u.unary.op = $1;
+ $$->u.unary.down = $2;
+ }
+ | PLUS simpleExpr %prec UPLUS
+ { $$ = $2; }
+ | simpleExpr
+ ;
+simpleExpr : WIDTH NAME
+ { $$ = New(ExprRec);
+ $$->type = Width;
+ $$->u.width = $2;
+ }
+ | HEIGHT NAME
+ { $$ = New(ExprRec);
+ $$->type = Height;
+ $$->u.height = $2;
+ }
+ | OP expr CP
+ { $$ = $2; }
+ | simpleExpr PERCENT
+ {
+ $$ = New(ExprRec);
+ $$->type = Unary;
+ $$->u.unary.op = $2;
+ $$->u.unary.down = $1;
+ }
+ | NUMBER
+ { $$ = New(ExprRec);
+ $$->type = Constant;
+ $$->u.constant = $1;
+ }
+ | DOLLAR NAME
+ { $$ = New(ExprRec);
+ $$->type = Variable;
+ $$->u.variable = $2;
+ }
+ ;
+expr : expr PLUS expr
+ { binary: ;
+ $$ = New(ExprRec);
+ $$->type = Binary;
+ $$->u.binary.op = $2;
+ $$->u.binary.left = $1;
+ $$->u.binary.right = $3;
+ }
+ | expr MINUS expr
+ { goto binary; }
+ | expr TIMES expr
+ { goto binary; }
+ | expr DIVIDE expr
+ { goto binary; }
+ | expr PERCENTOF expr
+ { goto binary; }
+ | MINUS expr %prec UMINUS
+ { unary: ;
+ $$ = New(ExprRec);
+ $$->type = Unary;
+ $$->u.unary.op = $1;
+ $$->u.unary.down = $2;
+ }
+ | PLUS expr %prec UPLUS
+ { $$ = $2; }
+ | simpleExpr
+ ;
+orientation : VERTICAL
+ { $$ = LayoutVertical; }
+ | HORIZONTAL
+ { $$ = LayoutHorizontal; }
+ ;
+%%
+
+int yywrap ()
+{
+ return 1;
+}
+
+void yysetdest (c)
+ LayoutPtr *c;
+{
+ dest = c;
+}
diff --git a/src/laylex.l b/src/laylex.l
new file mode 100644
index 0000000..7de4f2d
--- /dev/null
+++ b/src/laylex.l
@@ -0,0 +1,127 @@
+
+%{
+#ifndef FLEX_SCANNER
+#undef input
+#undef unput
+#endif
+
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+
+#include "LayoutP.h"
+#include "laygram.h"
+static char *yysourcebase, *yysource;
+
+#ifndef FLEX_SCANNER
+#define input() (*yysource++)
+#define unput(c) (--yysource)
+#else
+#include <string.h>
+static void my_yyinput(char *buf, int *result, int max_size);
+#define YY_INPUT(buf, res, max) my_yyinput(buf, &(res), max)
+#endif
+
+#ifdef __STDC__
+static int count ();
+#endif
+%}
+%%
+vertical return VERTICAL;
+horizontal return HORIZONTAL;
+"{" return OC;
+"}" return CC;
+"(" return OP;
+")" return CP;
+"<" return OA;
+">" return CA;
+infinity { yylval.ival = 1; return INFINITY; }
+inff* { yylval.ival = count(yytext, 'f'); return INFINITY; }
+[0-9][0-9]* { yylval.ival = atoi(yytext); return NUMBER; }
+"=" { return EQUAL; }
+"$" { return DOLLAR; }
+"+" { yylval.oval = Plus; return PLUS; }
+"-" { yylval.oval = Minus; return MINUS; }
+"*" { yylval.oval = Times; return TIMES; }
+"/" { yylval.oval = Divide; return DIVIDE; }
+"%" { yylval.oval = Percent; return PERCENT; }
+%[ \t\n]*of { yylval.oval = Percent; return PERCENTOF; }
+width return WIDTH;
+height return HEIGHT;
+\\[a-zA-Z_][a-zA-Z0-9_]* {
+#ifdef FLEX_SCANNER
+ yytext[yyleng] = '\0';
+#else
+ yytext[yyleng-1] = '\0';
+#endif
+ yylval.qval = XrmStringToQuark (yytext+1);
+ return NAME;
+ }
+
+[a-zA-Z_][a-zA-Z0-9_]* {
+#ifdef FLEX_SCANNER
+ yytext[yyleng] = '\0';
+#else
+ yytext[yyleng-1] = '\0';
+#endif
+ yylval.qval = XrmStringToQuark (yytext);
+ return NAME;
+ }
+" " ;
+"\t" ;
+"\n" ;
+. fprintf (stderr, "ignoring %c\n", *yytext);
+%%
+
+static int
+count (s, c)
+ char *s;
+ char c;
+{
+ int i = 0;
+ while (*s)
+ if (*s++ == c)
+ i++;
+ return i;
+}
+
+yysetsource(s)
+ char *s;
+{
+ yysourcebase = yysource = s;
+}
+
+yyerror(s)
+ char *s;
+{
+ char *t;
+
+ fprintf (stderr, "%s\n", s);
+ t = yysource - 50;
+ if (t < yysourcebase)
+ t = yysourcebase;
+ while (*t && t < yysource + 50) {
+ if (t == yysource)
+ putc ('@', stderr);
+ putc (*t++, stderr);
+ }
+ if (t == yysource)
+ putc ('@', stderr);
+ if (!*t)
+ fprintf (stderr, "<EOF>");
+ fprintf (stderr, "\n");
+}
+
+#ifdef FLEX_SCANNER
+static void
+my_yyinput(buf, result, max_size)
+ char *buf; int *result; int max_size;
+{
+ int size = max_size < strlen(yysource) ? max_size : strlen(yysource);
+
+ strncpy(buf, yysource, size);
+ yysource += size;
+ *result = size;
+}
+#endif
diff --git a/src/sharedlib.c b/src/sharedlib.c
new file mode 100644
index 0000000..486cf0a
--- /dev/null
+++ b/src/sharedlib.c
@@ -0,0 +1,192 @@
+/* $XConsortium: sharedlib.c,v 1.6 94/04/17 20:13:34 kaleb Exp $ */
+/*
+
+Copyright (c) 1991, 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.
+
+*/
+
+#if defined(SUNSHLIB) && !defined(SHAREDCODE)
+
+#include <X11/Xaw3d/Xaw3dP.h>
+#include <X11/IntrinsicP.h>
+#include <X11/Xaw3d/AsciiSinkP.h>
+#include <X11/Xaw3d/AsciiSrcP.h>
+#include <X11/Xaw3d/AsciiTextP.h>
+#ifdef XAW_INTERNATIONALIZATION
+#include <X11/Xaw3d/MultiSinkP.h>
+#include <X11/Xaw3d/MultiSrcP.h>
+#endif
+#include <X11/Xaw3d/BoxP.h>
+#include <X11/Xaw3d/CommandP.h>
+#include <X11/Xaw3d/DialogP.h>
+#include <X11/Xaw3d/FormP.h>
+#include <X11/Xaw3d/GripP.h>
+#include <X11/Xaw3d/LabelP.h>
+#include <X11/Xaw3d/ListP.h>
+#include <X11/Xaw3d/MenuButtoP.h>
+#include <X11/Xaw3d/PanedP.h>
+#include <X11/Xaw3d/PannerP.h>
+#include <X11/Xaw3d/PortholeP.h>
+#include <X11/Xaw3d/RepeaterP.h>
+#include <X11/Xaw3d/ScrollbarP.h>
+#include <X11/Xaw3d/SimpleP.h>
+#include <X11/Xaw3d/SimpleMenP.h>
+#include <X11/Xaw3d/SmeP.h>
+#include <X11/Xaw3d/SmeThreeDP.h>
+#include <X11/Xaw3d/SmeBSBP.h>
+#include <X11/Xaw3d/SmeLineP.h>
+#include <X11/Xaw3d/StripCharP.h>
+#include <X11/Xaw3d/TextP.h>
+#include <X11/Xaw3d/TextSinkP.h>
+#include <X11/Xaw3d/TextSrcP.h>
+#include <X11/Xaw3d/ThreeDP.h>
+#include <X11/Xaw3d/TipP.h>
+#include <X11/Xaw3d/ToggleP.h>
+#include <X11/Xaw3d/TreeP.h>
+#include <X11/VendorP.h>
+#include <X11/Xaw3d/ViewportP.h>
+
+extern AsciiSinkClassRec asciiSinkClassRec;
+WidgetClass asciiSinkObjectClass = (WidgetClass)&asciiSinkClassRec;
+
+extern AsciiSrcClassRec asciiSrcClassRec;
+WidgetClass asciiSrcObjectClass = (WidgetClass)&asciiSrcClassRec;
+
+extern AsciiTextClassRec asciiTextClassRec;
+WidgetClass asciiTextWidgetClass = (WidgetClass)&asciiTextClassRec;
+
+#ifdef ASCII_STRING
+extern AsciiStringClassRec asciiStringClassRec;
+WidgetClass asciiStringWidgetClass = (WidgetClass)&asciiStringClassRec;
+#endif
+
+#ifdef ASCII_DISK
+extern AsciiDiskClassRec asciiDiskClassRec;
+WidgetClass asciiDiskWidgetClass = (WidgetClass)&asciiDiskClassRec;
+#endif
+
+#ifdef XAW_INTERNATIONALIZATION
+extern MultiSinkClassRec multiSinkClassRec;
+WidgetClass multiSinkObjectClass = (WidgetClass)&multiSinkClassRec;
+#endif
+
+#ifdef XAW_INTERNATIONALIZATION
+extern MultiSrcClassRec multiSrcClassRec;
+WidgetClass multiSrcObjectClass = (WidgetClass)&multiSrcClassRec;
+#endif
+
+extern BoxClassRec boxClassRec;
+WidgetClass boxWidgetClass = (WidgetClass)&boxClassRec;
+
+extern CommandClassRec commandClassRec;
+WidgetClass commandWidgetClass = (WidgetClass) &commandClassRec;
+
+extern DialogClassRec dialogClassRec;
+WidgetClass dialogWidgetClass = (WidgetClass)&dialogClassRec;
+
+extern FormClassRec formClassRec;
+WidgetClass formWidgetClass = (WidgetClass)&formClassRec;
+
+extern GripClassRec gripClassRec;
+WidgetClass gripWidgetClass = (WidgetClass) &gripClassRec;
+
+extern LabelClassRec labelClassRec;
+WidgetClass labelWidgetClass = (WidgetClass)&labelClassRec;
+
+extern ListClassRec listClassRec;
+WidgetClass listWidgetClass = (WidgetClass)&listClassRec;
+
+extern MenuButtonClassRec menuButtonClassRec;
+WidgetClass menuButtonWidgetClass = (WidgetClass) &menuButtonClassRec;
+
+extern PanedClassRec panedClassRec;
+WidgetClass panedWidgetClass = (WidgetClass) &panedClassRec;
+WidgetClass vPanedWidgetClass = (WidgetClass) &panedClassRec;
+
+extern PannerClassRec pannerClassRec;
+WidgetClass pannerWidgetClass = (WidgetClass) &pannerClassRec;
+
+extern PortholeClassRec portholeClassRec;
+WidgetClass portholeWidgetClass = (WidgetClass) &portholeClassRec;
+
+extern RepeaterClassRec repeaterClassRec;
+WidgetClass repeaterWidgetClass = (WidgetClass) &repeaterClassRec;
+
+extern ScrollbarClassRec scrollbarClassRec;
+WidgetClass scrollbarWidgetClass = (WidgetClass)&scrollbarClassRec;
+
+extern SimpleClassRec simpleClassRec;
+WidgetClass simpleWidgetClass = (WidgetClass)&simpleClassRec;
+
+extern SimpleMenuClassRec simpleMenuClassRec;
+WidgetClass simpleMenuWidgetClass = (WidgetClass)&simpleMenuClassRec;
+
+extern SmeClassRec smeClassRec;
+WidgetClass smeObjectClass = (WidgetClass) &smeClassRec;
+
+extern smeThreeDClassRec smeThreeDClassRec;
+WidgetClass smeThreeDObjectClass = (WidgetClass) &smeThreeDClassRec;
+
+WidgetClass smeBSBObjectClass = (WidgetClass) &smeBSBClassRec;
+
+extern SmeLineClassRec smeLineClassRec;
+WidgetClass smeLineObjectClass = (WidgetClass) &smeLineClassRec;
+
+extern StripChartClassRec stripChartClassRec;
+WidgetClass stripChartWidgetClass = (WidgetClass) &stripChartClassRec;
+
+extern TextClassRec textClassRec;
+WidgetClass textWidgetClass = (WidgetClass)&textClassRec;
+
+unsigned long FMT8BIT = 0L;
+unsigned long XawFmt8Bit = 0L;
+#ifdef XAW_INTERNATIONALIZATION
+unsigned long XawFmtWide = 0L;
+#endif
+
+extern TextSinkClassRec textSinkClassRec;
+WidgetClass textSinkObjectClass = (WidgetClass)&textSinkClassRec;
+
+extern TextSrcClassRec textSrcClassRec;
+WidgetClass textSrcObjectClass = (WidgetClass)&textSrcClassRec;
+
+extern ThreeDClassRec threeDClassRec;
+WidgetClass threeDClass = (WidgetClass)&threeDClassRec;
+
+extern TipClassRec tipClassRec;
+WidgetClass tipWidgetClass = (WidgetClass)&tipClassRec;
+
+extern ToggleClassRec toggleClassRec;
+WidgetClass toggleWidgetClass = (WidgetClass) &toggleClassRec;
+
+extern TreeClassRec treeClassRec;
+WidgetClass treeWidgetClass = (WidgetClass) &treeClassRec;
+
+extern VendorShellClassRec vendorShellClassRec;
+WidgetClass vendorShellWidgetClass = (WidgetClass) &vendorShellClassRec;
+
+extern ViewportClassRec viewportClassRec;
+WidgetClass viewportWidgetClass = (WidgetClass)&viewportClassRec;
+
+#endif /* SUNSHLIB */