summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:48 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:48 +0000
commit81ad93fde745d556aaa3880deabf3674bb3db49e (patch)
tree24120e85c169c58dedc31dfb61df4e533b058b99
parentb6e0280a57c4dfa572770241a42fe6a476109516 (diff)
Initial revisionXORG-STABLE
-rw-r--r--include/X11/Xaw/Tip.h120
-rw-r--r--include/X11/Xaw/TipP.h77
-rw-r--r--man/Xaw.man586
-rw-r--r--old-doc/Changelog1370
-rw-r--r--src/Actions.c1132
-rw-r--r--src/Converters.c698
-rw-r--r--src/DisplayList.c2250
-rw-r--r--src/OS.c60
-rw-r--r--src/Pixmap.c984
-rw-r--r--src/Private.h154
-rw-r--r--src/Tip.c631
11 files changed, 8062 insertions, 0 deletions
diff --git a/include/X11/Xaw/Tip.h b/include/X11/Xaw/Tip.h
new file mode 100644
index 0000000..5fb56f5
--- /dev/null
+++ b/include/X11/Xaw/Tip.h
@@ -0,0 +1,120 @@
+/*
+ * 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 <X11/Xaw/Simple.h>
+
+/* Resources:
+
+ Name Class RepType Default Value
+ ---- ----- ------- -------------
+ background Background Pixel XtDefaultBackground
+ backgroundPixmap BackgroundPixmap Pixmap XtUnspecifiedPixmap
+ border BorderColor Pixel XtDefaultForeground
+ borderWidth BorderWidth Dimension 1
+ bottomMargin VerticalMargins Dimension 2
+ destroyCallback Callback XtCallbackList NULL
+ displayList DisplayList XawDisplayList* NULL
+ font Font XFontStruct* XtDefaultFont
+ foreground Foreground Pixel XtDefaultForeground
+ height Height Dimension text height
+ leftMargin HorizontalMargins Dimension 6
+ rightMargin HorizontalMargins Dimension 6
+ timeout Timeout Int 500
+ topMargin VerticalMargins Dimension 2
+ 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 XtNbottomMargin "bottomMargin"
+#define XawNdisplayList "displayList"
+#define XtNencoding "encoding"
+#define XtNleftMargin "leftMargin"
+#define XtNrightMargin "rightMargin"
+#define XtNtimeout "timeout"
+#define XtNtopMargin "topMargin"
+#define XtNtip "tip"
+
+#define XawCDisplayList "DisplayList"
+#define XtCHorizontalMargins "HorizontalMargins"
+#define XtCTimeout "Timeout"
+#define XtCVerticalMargins "VerticalMargins"
+#define XtCTip "Tip"
+
+#define XawRDisplayList "XawDisplayList"
+
+/*
+ * Public Functions
+ */
+/*
+ * Function:
+ * XawTipEnable
+ *
+ * Parameters:
+ * w - widget
+ *
+ * Description:
+ * Enables the tip event handler for this widget.
+ */
+void XawTipEnable
+(
+ Widget w
+ );
+
+/*
+ * Function:
+ * XawTipEnable
+ *
+ * Parameters:
+ * w - widget
+ *
+ * Description:
+ * Disables the tip event handler for this widget.
+ */
+void XawTipDisable
+(
+ Widget w
+ );
+
+#endif /* _XawTip_h */
diff --git a/include/X11/Xaw/TipP.h b/include/X11/Xaw/TipP.h
new file mode 100644
index 0000000..0c1abc6
--- /dev/null
+++ b/include/X11/Xaw/TipP.h
@@ -0,0 +1,77 @@
+/*
+ * 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 <X11/Xaw/Tip.h>
+#include <X11/CoreP.h>
+#include <X11/Xaw/XawInit.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;
+ XFontSet fontset;
+ Dimension top_margin;
+ Dimension bottom_margin;
+ Dimension left_margin;
+ Dimension right_margin;
+ int backing_store;
+ int timeout;
+ XawDisplayList *display_list;
+
+ /* private */
+ GC gc;
+ XtIntervalId timer;
+ String label;
+ Boolean international;
+ unsigned char encoding;
+ XtPointer pad[4];
+} TipPart;
+
+typedef struct _TipRec {
+ CorePart core;
+ TipPart tip;
+} TipRec;
+
+#endif /* _XawTipP_h */
diff --git a/man/Xaw.man b/man/Xaw.man
new file mode 100644
index 0000000..6d179d3
--- /dev/null
+++ b/man/Xaw.man
@@ -0,0 +1,586 @@
+.\"
+.\" 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/Xaw.man,v 1.7 2001/11/04 21:16:39 paulo Exp $
+.\"
+.de TQ
+.br
+.ns
+.TP \\$1
+..
+.TH Xaw 3 __vendorversion__
+.SH NAME
+ Xaw \- X Athena Widgets
+.SH DESCRIPTION
+.B Xaw
+is a widget set based on the X Toolkit Intrinsics (Xt) Library. This
+manual page describes the additions and modifications to the Xaw library
+made by XFree86 (Xaw7), as well as some of the common interfaces between
+its version and the previous X Consortium release (Xaw6).
+.SH ACTIONS
+All of the \fIXaw\fR widgets now have the additional translations
+.B call-proc, declare, get-values
+and \fBset-values\fP. The syntax for these actions is:
+.PP
+.I action-name \fP(\fIboolean-expression\fP, \fIarguments\fP)
+.PP
+\fBAction-name\fP is one of \fIcall-proc\fP, \fIdeclare\fP,
+\fIget-values\fP or \fIset-values\fP.
+.PP
+\fBBoolean-expression\fP is composed with the operators \fI|\fR (or), \fI&\fR
+(and), \fI^\fR (xor), and \fI~\fR (not). The operands can be a variable name,
+which starts with a \fI$\fR; a resource name without the bindings \fI.\fP
+or \fI*\fP; or a constant name, including \fImine\fP (event->xany.window
+== XtWindow(widget)), \fIfaked\fP (event->xany.send_event != 0), \fItrue\fP (1)
+and \fIfalse\fP (0).
+.PP
+\fBArguments\fP are self-explanatory; when starting with a \fI$\fP they name
+a variable, otherise, they indicate a resource name.
+.TP 8
+.B call-proc \fP(\fIboolean-expression\fP, \fIprocedure-name\fP)
+This action allows the evaluation of a boolean expression in the first
+parameter before calling a action procedure. The procedure is only called
+if the expression evaluates as true. Example:
+.br
+.I call-proc("$inside & $pressed", notify)
+.TP 8
+.B declare \fP(\fIboolean-expression\fP, \fIvariable\fP, \fIvalue\fP, ...)
+This action is used to create new variables or change their values. Any
+number of variable-value tuples may be specified. Example:
+.br
+.I declare(1, $pressed, 1)
+.TP 8
+.B get-values \fP(\fIboolean-expression\fP, \fIvariable\fP, \fIvalue\fP, ...)
+This action reads a widget resource value into a variable. Any number of
+variable-value tuples may be specified. Example:
+.br
+.I get-values(1, $fg, foreground, $bg, background)
+.TP 8
+.B set-values \fP(\fIboolean-expression\fP, \fIvariable\fP, \fIvalue\fP, ...)
+This action sets a widget resource to the given value, which may be a
+variable. Any number of variable-value tuples may be specified. Example:
+.br
+.I set-values(1, foreground, $bg, background, $fg)
+.PP
+Here is a sample translation to make a label widget behave like a button:
+.PP
+.nf
+<Map>: get-values(1, $fg, foreground, $bg, background)\\n\\
+<Btn1Down>: set-values(1, foreground, yellow, background, gray30)\\n\\
+<Btn1Up>: set-values(1, foreground, $fg, background, $bg)
+.fi
+.SH DISPLAY LISTS
+All of the \fBXaw\fP widgets have now the additional resource
+\fIdisplayList\fP. This resource allows drawing the widget decorations
+using commands embedded in a resource string. The displayList resource has
+the syntax:
+.PP
+\fI[class-name:]function-name arguments[[{;\\n}]...]\fP
+.PP
+\fBClass-name\fP is any registered set of functions to draw in the widget.
+Currently the only existing class is \fIxlib\fP, which provides access to
+the Xlib drawing primitives.
+.PP
+\fBFunction-name\fP is the drawing or configuration function to be called,
+described bellow.
+.PP
+\fBArguments\fP may be anything suitable to the displayList function being
+called. When the function requires a coordinate, the syntax is
+\fI{+-}<integer>\fP or \fI<integer>/<integer>\fP. Examples:
+.nf
+ +0,+0 top, left
+ -0,-0 bottom, right
+ -+10,-+10 bottom+10, right+10
+ +0,1/2 left, vertical-center
+.fi
+.TP 8
+.B arc-mode \fPmode
+Sets the arc mode. Accepted \fImode\fPs are "pieslice" and "chord", which
+set the arc to ArcPieSlice or ArcChord, respectively. Example:
+.br
+.I arc-mode chord
+.TP 8
+.B bg \fPcolor-spec
+.TQ
+.B background \fPcolor-spec
+Sets the background color. \fIcolor-spec\fP must a valid color
+specification. Example:
+.br
+.I background red
+.TP 8
+.B cap-style \fPstyle
+Sets the cap style. Accepted \fIstyle\fPs are "notlast", "butt", "round",
+and "projecting", which set the cap style to CapNotLast, CapBut, CapRound
+or CapProjecting, respectively. Example:
+.br
+.I cap-style round
+.TP 8
+.B clip-mask \fPpixmap-spec
+Sets the pixmap for the clip mask. Requires a pixmap parameter, as
+described in the \fBPIXMAPS\fP section below. Example:
+.br
+.I clip-mask xlogo11
+.TP 8
+.B clip-origin \fPx,y
+Sets the clip x and y origin. Requires two arguments, the x and y
+coordinates. Example:
+.br
+.I clip-origin 10,10
+.TP 8
+.B clip-rects \fPx1,y1,x2,y2 [...,xn,yn]
+.TQ
+.B clip-rectangles \fPx1,y1,x2,y2 [...,xn,yn]
+Sets a list of rectangles to the clip mask. The number of arguments must
+be a multiple of four. The arguments are coordinates. The parser
+calculates the width and height of the rectangles. Example:
+.br
+.I clip-rects 0,0,10,20, 20,10,30,30
+.TP 8
+.B coord-mode \fPmode
+Changes the coord mode for \fIfill-polygon\fP, \fIdraw-lines\fP, and
+\fIdraw-points\fP. Accepted parameters are "modeorigin" and "previous",
+that sets the coord mode to CoordModeOrigin or CoordModePrevious,
+respectively. Example:
+.br
+.I coord-mode previous
+.TP 8
+.B copy-area \fP{pixmap-spec|.},dstx,dsty[,x2,y2,srcx,srcy]
+Calls XCopyArea. The character \fI.\fP means copy the window contents;
+pixmap-spec is as defined in the \fBPIXMAPS\fP section below. \fIX2\fP and
+\fIy2\fP are the coordinates of the end copy, not the width and height; if
+not defined, the parser calculates them. \fIsrc_x\fP and \fIsrc_y\fP
+default to zero. Example:
+.br
+.I copy-area Term,10,10
+.TP 8
+.B copy-plane \fP{pixmap-spec|.},dstx,dsty[,x2,y2,srcx,srcy,plane]
+Calls XCopyPlane. The character \fI.\fP means copy the window contents;
+pixmap-spec is as defined in the \fBPIXMAPS\fP section below. \fIX2\fP and
+\fIy2\fP are the coordinates of the end copy, not the width and height; if
+not defined, the parser calculates them. \fIsrc_x\fP and \fIsrc_y\fP
+default to zero. \fIPlane\fP defaults to one. Example:
+.br
+.I copy-plane star,10,10
+.TP 8
+.B dashes \fPi1[...,in]
+Sets the dashes for line drawing. Accepts up to 127 arguments. Example:
+.br
+.I dashes 3,7 9,10
+.TP 8
+.B draw-arc \fPx1,y1,x2,y2[,start-angle,end-angle]
+Draws an arc. The four first arguments are the rectangle enclosing the
+arc. The two remaining arguments, if specified, are the start and end
+angle, in degrees. Example:
+.br
+.I draw-arc +0,+0,-1,-1,0,90
+.TP 8
+.B draw-rect \fPx1,y1,x2,y2
+.TQ
+.B draw-rectangle \fPx1,y1,x2,y2
+Draws a rectangle. Requires four arguments, which are the start and end
+coordinate pairs. Example:
+.br
+.I draw-rect +1,+1,-5,-5
+.TP 8
+.B draw-string \fPx,y,"string"
+Draws a text string. Requires three arguments, a x coordinate, a y
+coordinate, and a string. Strings that have white space can be quoted with
+the \fI"\fP character; the backslash character \fI\\\fP can also be used,
+but it will be necessary escape it twice. Example:
+.br
+\fI draw-string 10,10, "Hello world!"\fP
+.TP 8
+.B exposures \fPboolean
+Sets graphics exposures in the GC. Allowed parameters are a integer or the
+strings "true", "false", "on" and "off". Example:
+.br
+.I exposures true
+.TP 8
+.B fill-arc \fPx1,y1,x2,y2[,start-angle,end-angle]
+Like \fIdraw-arc\fP, but fills the contents of the arc with the currently
+selected foreground. Example:
+.br
+.I fill-arc +0,+0,-1,-1,0,180
+.TP 8
+.B fill-poly \fPx1,y1 [...,xn,yn]
+.TQ
+.B fill-polygon \fPx1,y1 [...,xn,yn]
+Like \fIdraw-lines\fP, but fills the enclosed polygon and joins the first
+and last point, if they are not at the same position. Example:
+.br
+.I fill-poly +0,+10, +10,+20, +30,+0
+.TP
+.B fill-rect \fPx1,y1,x2,y2
+.TQ
+.B fill-rectangle \fPx1,y1,x2,y2
+Like \fIdraw-rect\fP, but fills the contents of the rectangle with the
+selected foreground color. Example:
+.br
+.I fill-rect +10,+10,-20,-20
+.TP 8
+.B fill-rule \fPrule
+Sets the fill rule. Accepted parameters are "evenodd" and "winding", which
+set the fill rule to EvenOddRule or WindingRule, respectively. Example:
+.br
+.I
+fill-rule winding
+.TP 8
+.B fill-style \fPstyle
+Sets the fill style. Allowed parameters are "solid", "tiled", "stippled" and
+"opaquestippled", which set the fill style to FillSolid, FillTiled,
+FillStippled or FillOpaqueStippled, respectively. Example:
+.br
+.I fill-style tiled
+.TP 8
+.B font \fPfont-spec
+Sets the font for text functions. Example:
+.br
+.I font -*-*-*-R-*-*-*-120-*-*-*-*-ISO8859-1
+.TP 8
+.B fg \fPcolor-spec
+.TQ
+.B foreground \fPcolor-spec
+Like \fIbackground\fP, but sets the current foreground color. Example:
+.br
+.I foreground blue
+.TP 8
+.B mask
+This command is useful when you want to draw only in the region that really
+needs to be repainted. Requires no arguments.
+.TP 8
+.B function \fPfunction-spec
+Sets the specific GC function. Allowed parameters are "set", "clear", "and",
+"andreverse", "copy", "andinverted", "noop", "xor", "or", "nor", "equiv",
+"invert", "orreverse", "copyinverted" and "nand", which set the function to
+GXset, GXclear, GXand, GXandReverse, GXcopy, GXandInverted, GXnoop, GXxor,
+GXor, GXnor, GXequiv, GXinvert, GXorReverse, GXcopyInverted or GXnand,
+respectively. Example:
+.br
+.I function xor
+.TP 8
+.B join-style \fPstyle
+Sets the join style. Allowed parameters are "miter", "round" and "bevel",
+which set the join style to JoinMiter, JoinRound and JoinBevel,
+respectively. Example:
+.br
+.I join-style round
+.TP 8
+.B image \fP{pixmap-spec},xs,ys,[xe,ye]
+This function is implemented as a way to quickly compose complex
+decorations in widgets. \fIPixmap-spec\fP is as defined in the
+\fBPIXMAPS\fP section below. \fIxs\fP and \fIys\fP are the coodinates from
+where to start copying the pixmap; \fIxe\fP and \fIye\fP are optional (they
+default to xs + pixmap.width and ys + pixmap.height, respectively). If the
+pixmap has a mask, the copy is masked accordingly. Example:
+.br
+.I image pixmap.xpm,0,0,20,20
+.TP 8
+.B line \fPx1,y1,x2,y2
+.TQ
+.B draw-line \fPx1,y1,x2,y2
+Draws a line with the current foreground color. Requires four arguments,
+the starting and ending coordinate pairs. Example:
+.br
+.I line +0,+0, -1,-1
+.TP 8
+.B line-width \fPinteger
+Selects a line width for drawing. Example:
+.br
+.I line-width 2
+.TP 8
+.B line-style \fPstyle
+Sets the line style. Accepted parameters are "solid", "onoffdash" and
+"doubledash", which set the line style to LineSolid, LineOnOffDash or
+LineDoubleDash, respectively. Example:
+.br
+.I line-style onoffdash
+.TP 8
+.B lines \fPx1,y1,x2,y2 [...,xn,yn]
+.TQ
+.B draw-lines \fPx1,y1,x2,y2 [...,xn,yn]
+Draws a list of lines. Any number of argument pairs may be supplied.
+Example:
+.br
+.I lines +0,-1, -1,-1, -1,+0
+.TP 8
+.B paint-string \fPx,y,"string"
+Identical to draw-string, but also uses the background color. Example:
+.br
+\fI paint-string 10,20, "Sample text"\fP
+.TP 8
+.B point \fPx,y
+.TQ
+.B draw-point \fPx,y
+Draws a point. Requires two arguments, a coordinate pair. Example:
+.br
+.I point +10,+10
+.TP 8
+.B plane-mask \fPinteger
+Sets the plane mask. Requires an integer parameter. Example:
+.br
+.I plane-mask -1
+.TP 8
+.B points \fPx1,y1 [...,xn,yn]
+.TQ
+.B draw-points \fPx1,y1 [...,xn,yn]
+Draws a list of points at the specified coordinates. Example:
+.br
+.I points +1,+2, +1,+4, +1,+6
+.TP 8
+.B segments \fPx1,y1,x2,y2 [...,xn,yn]
+.TQ
+.B draw-segments \fPx1,y1,x2,y2 [...,xn,yn]
+Draws a list of segment lines. The number of parameters must be multiple
+of 4. Example:
+.br
+.I segments +1,+2,+1,-3, +2,-2,-3,-2
+.TP 8
+.B shape-mode \fPmode
+Sets the shape mode used in \fIfill-polygon\fP. Accepted parameters are
+"complex", "convex" or "nonconvex", which set the shape mode to Complex,
+Convex or Nonconvex, accordingly. Example:
+.br
+.I shape-mode convex
+.TP 8
+.B stipple \fPpixmap-spec
+Sets the pixmap for a stipple. Requires a pixmap parameter, as described
+in the \fBPIXMAPS\fP section below. Example:
+.br
+.I stipple plaid
+.TP 8
+.B subwindow-mode \fPmode
+Sets the subwindow mode in the GC. Accepted parameters are
+"includeinferiors" and "clipbychildren", which set the subwindow mode to
+IncludeInferiors or ClipByChildren, respectively. Example:
+.br
+.I subwindow-mode includeinferiors
+.TP 8
+.B tile \fPpixmap-spec
+Sets the pixmap for a tile. Requires a pixmap parameter, as described
+in the \fBPIXMAPS\fP section below. Example:
+.br
+.I tile xlogo11?foreground=red&background=gray80
+.TP 8
+.B ts-origin \fPx,y
+Sets the tile stipple x and y origin. Requires two arguments, a x and y
+coordinate. Example:
+.br
+.I ts-origin 10,10
+.TP 8
+.B umask
+Disables the GC mask, if it has been set with the command \fImask\fP.
+Requires no arguments.
+.PP
+Example for drawing a shadow effect in a widget:
+.nf
+foreground gray30;\\
+draw-lines +1,-1,-1,-1,-1,+1;\\
+foreground gray85;\\
+draw-lines -1,+0,+0,+0,+0,-1
+.fi
+.SH PIXMAPS
+A String to Pixmap converter has been added to \fBXaw\fP. This converter
+is meant to be extended, and has enough abstraction to allow loading
+several image formats. It uses a format that resembles a \fIURL\fP, with
+the syntax:
+.PP
+.I [type:]name[?arg=val[{&}...]]
+.PP
+\fBType\fP can be one of \fIbitmap\fP, \fIgradient\fP or \fIxpm\fP.
+.PP
+\fBName\fP may be a file name, or, in the case of type \fIgradient\fP, may be
+either \fIvertical\fP or \fIhorizontal\fP.
+.PP
+\fBArg=val\fP is a list of arguments to the converter. An argument list is
+preceded by a question mark, and multiple arguments are separated by
+ampersands. The most common arguments are \fIforeground\fP and
+\fIbackground\fP. Gradients also support the arguments \fIstart\fP and
+\fIend\fP (colors with which to start and end the gradient); the
+\fPsteps\fP argument, to allow using less colors; and the \fIdimension\fP
+argument to specify the size of the gradient. The \fIxpm\fP converter
+understands the \fIcloseness\fP argument, which aids in using fewer colors
+(useful if you have a limited colormap).
+.SH TEXT WIDGET
+Most of the changes to this version of the Xaw library were done in the
+TextWidget, TextSrcObject, TextSinkObject and related files.
+.PP
+A couple of highly visible changes in the Text widget are due to many bugs
+in the Xaw6 implementation involving scrollbars and auto-resizing.
+Scrollbars being added or removed caused several problems in keeping the
+text cursor visible, and in Xaw6 it was very easy to have a widget thinking
+the cursor was visible, when it was not. Also, permitting automatic
+resizing of the widget to a larger geometry created other problems, making
+it difficult to have a consistent layout in the application, and, if the
+window manager did not interfere, windows larger than the screen could
+result. Therefore, some functionality involving scrollbars and
+auto-resizing has been disabled; see the section on new and modified
+Text widget resources below.
+.PP
+The Text widget's default key bindings were originally based on the Emacs
+text editor. In this release, even more operations familiar to Emacs users
+have been added. New text actions include:
+.TP 8
+.B indent
+Indents text blocks. Not bound by default. The Text widget also does not
+attempt to perform auto-indentation of its source object by default.
+.TP 8
+.B keyboard-reset
+Resets the keyboard state. Reverts the action multiplier to 1, and if undo
+is enabled, toggles between undo and redo. Bound by default to
+\fIControl<Key>G\fP.
+.TP 8
+.B kill-ring-yank
+In this version of Xaw, text killed in any text field is kept in memory,
+allowing cut and paste operations internally to the program between text
+fields. Bound by default to \fIMeta<Key>Y\fP.
+.TP 8
+.B numeric
+Listed here only for purposes of documentation. Called by default when one
+of the characters \fI1, 2, 3, 4, 5, 6, 7, 8, 9, 0,\fP or \fI-\fP is typed,
+allowing composition of the multiplication number of text actions.
+.TP 8
+.B set-keyboard-focus
+Sets the input focus of the top level widget to the text field. Not
+enabled by default, but bound to the \fI<Btn1Down>\fP event.
+.TP 8
+.B toggle-overwrite
+Toggles overwrite mode. In overwrite mode, any text inserted in a text
+field will replace existing text. Bound by default to \fI<Key>Insert\fP.
+.TP 8
+.B undo
+Sets the \fIenableUndo\fP resource of the textSrcObject. Not enabled by
+default, but bound to \fIControl<Key>_\fP.
+.PP
+New and modified Text widget resources include:
+.TP 8
+.B justify (\fPClass\fB Justify)
+Sets the text justification. Can be one of \fIleft, right, center\fP, or
+\fIfull\fP. Only enabled when the \fIautoFill\fP resource is set, and the
+resources \fIleftColumn\fP and \fIrightColumn\fP are correctly set.
+.TP 8
+.B leftColumn (\fPClass\fB Column)
+Specifies the left column at which to break text. Text lines started with
+an alphanumeric character will automatically start at this column.
+.TP 8
+.B positionCallback (\fPClass\fB Callback)
+Allows installation of a callback to be called every time the cursor is
+moved, and/or the file changes its size. The callback is called with a
+pointer to a structure containing the following data:
+.nf
+typedef struct {
+ int line_number;
+ int column_number;
+ XawTextPosition insert_position;
+ XawTextPosition last_position;
+ Boolean overwrite_mode;
+} XawTextPositionInfo;
+.fi
+This callback is intended to help programmers write text editors based
+on the Xaw widget set.
+.TP 8
+.B resize (\fPClass\fB Resize)
+No longer supported, but recognized for backward compatibility with
+resource specifications written for the Xaw6 Text widget.
+.TP 8
+.B rightColumn (\fPClass\fB Column)
+Specifies the right column at which to break text. Text lines started with
+an alphanumeric character will automatically end at this column.
+.TP 8
+.B scrollHorizontal (\fPClass\fB Scroll)
+.TQ
+.B scrollVertical (\fPClass\fB Scroll)
+These resources control the placement of scrollbars on the left and bottom
+edges of the Text widget. They accept the values \fIXawtextScrollAlways\fP
+and \fIXawtextScrollNever\fP. A converter is registerd for this resource
+that will convert the following strings: \fIalways\fP and \fInever\fP. The
+value \fIXawtextScrollWhenNeeded\fP (and \fIwhenNeeded\fP, recognized by
+the converter), is accepted for backwards compatibilty with resource
+specifications written for the Xaw6 Text widget, but ignored (effectively
+treated as \fIXawtextScrollNever\fP).
+.SH TEXT SOURCE OBJECT
+The textSrcObject allows display of its contents to more than one window,
+and also stores undo information. The new resources for the textSrcObject
+are:
+.TP 8
+.B callback (\fPClass\fB Callback)
+Previous versions of Xaw had this resource in subclasses of the TextSource
+object. This was changed to make it possible to tell the callback the
+state of the text when undo is enabled.
+.TP 8
+.B enableUndo (\fPClass\fB Undo)
+A boolean resource that enables or disables the undo function. The default
+value is False.
+.TP 8
+.B sourceChanged (\fPClass\fB Changed)
+Like the callback resource, this resource was previously in subclasses of
+the TextSource object. It is now in the textSrcObject to control the
+changed/unchanged state when undo is enabled.
+.SH TEXT SINK OBJECT
+The textSinkObject subclasses asciiSinkObject and multiSinkObject have been
+changed slightly to use a new cursor shape (no longer a caret at the
+baseline) that indicates the input focus of the text widget, and allow
+specification of the cursor color. The new resource is:
+.TP 8
+.B cursorColor (\fPClass\fB Color)
+Sets the cursor color of the text. This color is also used to draw
+selected text.
+.SH SIMPLE MENU WIDGET
+The simpleMenuWidget algorithm to lay out menu entries has been changed to
+enable multiple columns when a single column does not fit on the screen.
+It was also modified to enable submenus.
+.SH SME BSB OBJECT
+A new resource has been added to the smeBSBObject to allow binding submenus
+to it. The new resource is:
+.TP 8
+.B menuName (\fPClass\fB MenuName)
+Specifies the name of the popup widget to be popped up when the pointer is
+over the menu entry, or NULL. Note that the named menu must be a child of
+the popup parent of the smeBSBObject.
+.SH RESTRICTIONS
+.B Xaw
+is actively being developed. Programs intending to be fully compatible
+with future releases of the Xaw library should use only the public
+interfaces. While widget subclassification is not a bad thing, and
+sometimes an encouraged programming practice, programs that access private
+data structures may have problems with newer releases in the current stage
+of
+.I Xaw
+development. Efforts are being made to avoid such problems and to guarantee
+that newer releases will be source and binary compatible.
+.SH AUTHORS
+The original X Consortium version of the Athena Widget Set and its
+documentation were the work of many people, including Chris D. Peterson,
+Ralph Swick, Mark Ackerman, Donna Converse, Jim Fulton, Loretta
+Guarino-Reid, Charles Haynes, Rich Hyde, Mary Larson, Joel McCormack, Ron
+Newman, Jeanne Rich, Terry Weissman, Mike Gancarz, Phil Karlton, Kathleen
+Langone, Ram Rao, Smokey Wallace, Al Mento, and Jean Diaz.
+.PP
+XFree86's additions and modifications to \fIXaw\fR were written by Paulo
+C\('esar Pereira de Andrade.
+.SH SEE ALSO
+.I Athena Widget Set - C Language Interface
diff --git a/old-doc/Changelog b/old-doc/Changelog
new file mode 100644
index 0000000..5a1d674
--- /dev/null
+++ b/old-doc/Changelog
@@ -0,0 +1,1370 @@
+Patch 1 (#1655) 15 April 1998
+
+ Description of the actions system:
+--------------------------------------------------------------------
+ All the actions have the syntax:
+
+action-name(boolean-expression, args)
+
+ Where:
+action-name:
+ Any string with a translation binding in the binary for the widget.
+
+boolean-expression:
+ [{~}]variable-name|resource-name|constant-name[{&|^}[[{~}]variable-name|resource-name|constant-name]]...
+
+variable-name:
+ Any string starting with a '$' character (actually it's not possible
+ to mask this character; I'll fix it). Variables are actually created
+ with the translations 'declare' and 'get-values'. Example:
+ get-values(1, $x, x)
+ declare(1, $armed, true)
+
+resource-name:
+ Any resource name of the widget. Note that it requires a <TYPE> to
+ string converter in the code (I added some on the patches), since
+ all variables values are stored in a 'String' format. Example:
+ borderWidth
+ height
+ font
+ background
+
+constant-name:
+ Especial values. They aren't normally contants, but a special state
+ not triggered with resources or variables (They have the highest
+ precedence, so, to allow these strings as resource names I'll need
+ to allow some sort of escape sequences). Examples:
+ mine # event->xany.window == XtWindow(widget)
+ faked # event->xany.send_event != 0
+ true # you know
+ false # " "
+
+args:
+ Special strings values interpreted by the translation binding.
+
+The operators (currently) understood are:
+ ~ - NOT
+ & - AND
+ | - OR
+ ^ - XOR
+ ( - RP
+ ) - LP
+ The final result value is and'ed with 1.
+
+Sample translation to make a label widget behave like a button:
+<Map>:\
+ get-values(1, $fg, foreground, $bg, background)\n\
+<Btn1Down>:\
+ set-values(1, foreground, yellow, background, gray30)\n\
+<Btn1Up>:\
+ set-values(1, foreground, $fg, background, $bg)\n
+
+
+ Description of the displayList system:
+--------------------------------------------------------------------
+ The display list has the syntax:
+
+[class-name:]function-name args[{;|\n}]...
+
+ Where:
+class-name:
+ Any registered set of functions. The code registers the class 'xlib',
+ and if the class name is not specified, this class is assumed.
+
+function-name:
+ A string binding to the correct function to be called.
+
+args:
+ A set of converted and shareable arguments, to the function. The
+ positioning/sizing arguments currently implemented have the syntax:
+{+-}<integer> or <integer>/<integer>. Examples:
+ +0,+0 top, left
+ -0,-0 bottom, right
+ -+10,-+10 bottom+10, right+10
+ +0,1/2 left, vcenter
+
+ All displayLists are shared by:
+ widget->core.screen
+ widget->core.colormap
+ widget->core.depth
+ I have added only partial code for handling non-windowed widgets (gadgets).
+I'll fix it.
+
+ Example for drawing two lines crossing the widget:
+foreground black;\
+line +0,+0,-0,-0;\
+line +0,-0,-0,+0
+
+
+
+Patch 2 (#1660) 19 April 1998
+
+ + More functions for displayList's
+ + Fixes for simpleMenuWidget, xfontsel should work very better now. Try
+ this with the newer patches to verify the changes:
+ xfontsel -xrm '*XFontSel*SimpleMenu*font:
+-*-helvetica-medium-r-*-*-16-*-*-*-*-*-*-1'
+ + Small bug fix to boxWidget, viewres should work better now. Try this
+ to verify the changes:
+ viewres -xrm '*Viewres*Box.borderWidth: 1'
+ + Small bug fix to panedWidget, when pressing in a gripWidget but not
+ moving the pointer, or releasing at the same coordinates.
+
+Patch 3 (#1673) 25 April 1998
+
+ + Changes in layout code for the Form widget. To see the changes, run xcalc
+ and resize it several times (try giving it a very small size and the
+ restore the size). The new code uses a 'known' reference size/position
+ to avoid integer rounding problems.
+ + A optimization for the Form widget. Now it unmaps itself before resizing
+ the child widgets. This way the layout process is very faster.
+ + The List widget will try to fit in a 32767x32767 window size. It checks
+ if the width or height will become bigger than 32767 and if will, changes
+ the number of columns. This fixes xman (at least for me, that have several
+ entries in the section 3 of the manpages).
+ + New functions to displayList's and fixes to some bad bugs (I'm yet working
+ on that file).
+ + Change in the Scrollbar functionality. It was redrawing the thumb when
+ triggering the MoveThumb action. This is bad because several programs
+ choose to recalculate the thumb position with XawScrollbarSetThumb, causing
+ screen flickering. Now it redraws the thumb when triggering the NotifyThumb
+ action. To verify the changes, run xfm or xman and try to scroll past the
+ end of a window; it will keep erasing and redrawing the thumb.
+ + Other change in the Scrollbar is that it will only draw in the rectangle:
+ 1, 1, core.width - 1, core.height - 1. It is better when creatting a 3d
+ effect with displayList's.
+
+
+Patch 4 (#1678) 3 May 1998
+
+Included the patches for the recent problems with libXaw.
+Several 'gratuitous' small changes, to compile cleanly with gcc -Wall.
+Some bug fixes for DisplayList.c.
+Colored pixmaps support. I'm building a abstraction layer for the colored
+ pixmaps, so that it should be easy to support more pixmap formats
+ (actually, only X bitmaps).
+
+
+Patch 5 (#1686) 11 May 1998
+
+ + Patch to libXmu, so that the StringToCursor converter will understand the
+ string 'None', that means not to use a cursor. This is useful when
+ overriding resource settings, and the user wants to use the parent window
+ cursor, or the root window cursor. Any unrecognized name will generate
+ a 'None' cursor, but then with a warning message.
+ + SimpleWidget was modified to allow setting the cursor to none, when it
+ was a valid cursor.
+ + Modification in the Actions.c,
+ from:
+ typedef struct _XawActionVar {
+ XrmQuark qname;
+ String value;
+ } XawActionVar;
+ to:
+ typedef struct _XawActionVar {
+ XrmQuark qname;
+ XrmQuark qvalue;
+ } XawActionVar;
+ This does not cause any problems, since the exported interface remains
+ the same. This is required to avoid to much copies of the same string.
+ + Values of action variables can start with '$'.
+ + If a resource name clashes with a special constant name when evaluating
+ a boolean expression (in the translations code), it's enough
+ start the resource name with '\\' (it can always be used, but is
+ only useful if there is a name clash :).
+ + The only code that loads data files actually is the pixmap code. To avoid
+ security problems, the code only loads files that are group readable,
+ regular file, non suid and non sgid.
+ + If the code to load a pixmap does not find a match, and the pixmap name
+ has a extension, try without the extension.
+ + Function 'line-with' added to displayList code.
+ + Added DisplayListToString and PixmapToString converters.
+ + Bug fixes in the pixmap name interpretation.
+
+
+Patch 6 (#1701) 24 May 1998
+
+ Xaw
+ ------
+ + Allows setting the resources label_x and label_y inherited from labelWidget.
+ This is useful for moving the contents of a button when it is pressed
+ ( I included a simple test for it )
+ + Added OS/2 patchs
+ + The buffer overflow problems were resolved in a different way. I added
+ a function XmuSnprintf, that is used by Xaw and Xmu.
+ + Correction of a problem in SimpleMenu, when it tries to optimize the
+ space used by the menu.
+
+ Xmu
+ -----
+ + Function XmuNCopyISOLatin1Lowered, defined in <X11/Xmu/CharSet.h>
+ + Function XmuSnprintf, defined in <X11/Xmu/SysUtil.h>
+ + All ocurrences of sprintf were replaced by XmuSnprintf and all ocurrences
+ of XmuCopyISOLatin1Lowered were replaced by XmuNCopyISOLation1Lowered.
+
+
+Patch 7 (#1738) 21 June 1998
+
+ + Corrected problem with the Command widget, when it was made insensitive
+ without calling the 'reset' action.
+ + Rework of the SimpleMenu code for optimizing the space used. Now it
+ really works as intended.
+ + Fixed portability problems with my previous patches.
+ + Corrected problem pointed by 'grano@cs.Helsinki.FI'. He have followed up
+ a bug report to the devel mailing list. While the problem exist, his
+ patch was not complete, so I did a rework of the AsciiSrc.c:Scan() and
+ MultiSrc.c:Scan() functions.
+ + I added clipping code to the {Ascii,Multi}Sink widgets, to allow use of
+ displayList's as decoration. The best solution I found to avoid too much
+ server requests, and keep full binary compatability was to use the resize
+ method of these widgets, to tell them to the parent widget have changed
+ it's size.
+ + Now the TextWidget has a xterm/emacs like cursor. And it is possible to
+ especify a cursor color.
+ + Fixed several problems caused by code assuming a line of text will be
+ shown as one line in the TextWidget. This is not always true when
+ it uses XawtextWrapLine or XawTextWrapWord, the most common problem was
+ the cursor becomming invisible, after calling the function
+ Text.c:_XawTextShowPosition() that is called to make sure it is visible ;)
+ + Added code that it will not forget the cursor distance from the left of
+ the window while moving the cursor one line up or down.
+ + Ansification of the text code (not yet complete). Private routines now
+ uses prototypes and wide parameters. External routines were kept
+ as before (but with prototypes not masked by NeedFunctionPrototypes),
+ to avoid binary compatability problems. The bigger problem I found in the
+ ansification was a function with 6 parameters being called with only 5.
+ + Several routines were rewritten, sometimes from scratch.
+ + The cursor navigation of the TextWidget was completely reviewed. It
+ should be very familiar to Emacs users. The most Emacs like behaviour is
+ when the cursor in move one line up or down and becomes invisible; the
+ text will be scrolled so that the line with the cursor will be centered
+ in the screen. Also, when doing page up, the cursor will be positioned
+ in the bottom-left, instead of allways in the top-left.
+
+Patch 8 (#1752) 27 June 1998
+
+ + There was a problem with the previous patch regarding to portability.
+ The problem was strcasecmp. I was planning to provide the funcionality
+ in libXmu, and forgot when creating the previous patch :(. There is
+ already a strcasecmp equivalent in libXmu, that is
+ Lower.c:XmuCompareISOLatin1(), so I used that function.
+ + The previous patch was working correctly for viewing text, but there were
+ some cases the text window could end not displaying correctly the text.
+ This problem was fixed.
+ + Now, the only real need of scrollbars is when doing long jumps on the
+ text, because the cursor will be always visible since this new patch
+ does horizontal scrolling automatically.
+
+
+Patch 9 (#1755) 28 June 1998
+
+ + Removed all my RCS idents in the files.
+ + Declared functions as static in the prototype and in the definition
+ (this basically reverts a previous patch, but should help when applying
+ the patches sequentially).
+ + Changed the code in Pixmap.c to use strtok instead of strsep, that is
+ not portable.
+ + Corrected problem with previous patch that would cause trouble when
+ a text widget had more than 32K bytes, and would also cause offset
+ mismatches if a program access private structures (AsciiSinkP.h).
+
+
+#1776 6 July 1998
+
+Corrected problem when moving the cursor over a non-printing character,
+ i.e. ^Q ^X
+Does not allow anymore scrolling of the text width Ctrl+Z if the text has
+ only one line, or only one line of text.
+Several changes in the TextWidget. I did not gratuitously break binary
+ compatability. Source compatability is only granted to programs that
+ do not access private structures. This is required because there are
+ several changes in the behaviour of the TextWidget, and if a program
+ becomes non compilable, it is because it will not work properly with
+ the changes in the text widget (please read bellow for a explanation)
+Better cursor navigation when moving line-up or line-down over a tab:
+ cursor
+ |
+ v
+ spaces | |#| | | |text
+ tab | |text
+ Move one line down:
+ before:
+ tab |# |text
+ now:
+ tab | |#ext
+There were several problems in the Text.c:_XawTextReplace(), when deleting
+ a character and the cursor (shoud be) moved to the previous line. This
+ problem was corrected.
+The text code was doing too much redrawing! When typping text, it would
+ redraw all the current line at each character typped, and also redraw the
+ entire window till the bottom. Now it only redraws the minimum necessary
+ (and makes a minimum of requests for the Xserver, when clearing areas),
+ most of these problems were related to Text.c:_XawTextReplace() (rewritten
+ from scratch), Text.c:_BuildLineTable() (mostly rewritten) and
+ Text.c:DisplayText() (mostly rewritten).
+Now, when selecting text, with: button1-down, button1-move, the window will
+ be scrolled automatically, if the mouse is moved to the top or bottom of
+ the text window, making it easier to extend selections.
+Added a set-keyboard-focus translation to the text code, and in the
+ default translation, it is called when pressing the left mouse button over
+ a text widget (so that the mouse does not need to be over the text window
+ when typping)
+
+These are the changes to Xaw that made it not fully source compatable (I'm
+open to comments, to make it source compatable, but as I said above, if
+a program does not compile anymore, it is because it is not granted it will
+work properly):
+scrollMode set to WhenNeeded is not supported anymore. I spent several
+ hours fighting side-effects caused when a scrollbar is created or destroyed
+ 'on demand', and have (after tired of long debug sessions) choosed that
+ it is not required (it saves a lot of potencial unespected conditions
+ being found by a user). I changed the 'type' of the scroll mode to Boolean,
+ so, to have a scrollbar, is enough to say: *Text.scrollVertical: True.
+ Since the type now is Boolean, Xt will print warning messages when the
+ scroll is set to 'Always', 'Never' or 'WhenNeeded'
+automatic resize is nonsense since the text does automatic horizontal
+ scrolling. IMHO, to be useful, automatic resize should also shrink the
+ text window when needed, anyway, it's not required anymore
+
+Comments:
+auto-fill mode does not work properly (never did)
+wrap-mode set to line may not work properly
+wrap-mode set to word does not work properly always (never did)
+the multiply should be setable to a variable value; the default value
+ is 4, i.e. Ctrl+U <text+action>
+I will work on the itens listed above, and I'm also planning:
+one level undo, for text actions
+C style indentation and 'jumping' the cursor to show matching '(', '['
+ and '{'
+other things that I don't remember now :)
+
+
+-- XMU --
+Moved the code clipping code I have put in Text.c in my previous patch to
+ Xmu/Clip.c. There was a bug in the code I have put in Text.c (this is what
+ I get by cutting and pasting code under a #if 0 :(), but it was corrected.
+ The code in the new file 'Clip.c' is very useful for creating clipiing lists
+ and thus, avoiding too much server requests, or code for the same
+ functionality (poorly) repeteated in several places around the libary. This
+ code is now heavily used by the TextWidget.
+
+
+-- XEDIT --
+Removed a XDefineCursor in xedit.c:main(). There are several ways to specify
+ a cursor for a program (most times inherited from the wm decoration window),
+ so, it is better to let the user choose one.
+Before starting the main loop, now xedit sets the keyboard focus to the
+ text window if a file was loaded, or to the prompt for a file name if
+ none was especified in the command line (do not use the new xedit without
+ the new Xaw library, or you will not be able to change the keyboard focus).
+Updated the Scrollbar configurations in Xedit.ad
+
+
+#1788 12 July 1998
+
+-- TextWidget --
+ + Corrected problem whem moving the cursor over a non-printing character
+ + Now, does not allow scroll with ^Z when there is only one line of text
+ + Automatic resize was removed, it is not required with automatic horizontal
+ scroll, but I will look for programs that rely on it; the only program
+ affected (that I know) is xmh, because it popups dialogs of a small size,
+ and expects that the text widget (with a warning message) do a geometry
+ request.
+ + Scroll mode set to "WhenNeeded" was removed. It generates several unespected
+ conditions when editing text, and the new feature of automatic scrolling
+ the text widget while typping is more useful.
+ + Removed a leak in TextAction.c:AutoFill(), generated by the code
+ text.ptr = (char *)XtMalloc(sizeof(wchar_t) * 2);
+ that memory was never released, but the fix was simple, since the amount
+ of memory requested is fixed.
+ + Several optimizations in the redisplay of the text.
+ + Now, wrap mode set to word or line is expected to work, while typping text.
+ + AutoFill will only break lines in word boundaries now.
+ + Added a set-keyboard-focus action to TextAction.c, so that when pressing
+ the left button over a text widget, it will receive the keyboard focus.
+ This behaviour is the default, but can be disabled, with something like:
+ *Text.translations: #override\n<Btn1Down>: select-start()\n
+ in your .Xdefaults.
+ + Corrected several cases that would left the text widget showing incorrect
+ data. All the problems should have been fixed, but in case you find one,
+ a quick fix is:
+ *Text.backgroundPixmap: black?foreground=<some-color>
+ because it does not try to optimize the redrawing when using a background
+ pixmap, and thus, avoid several possible problems.
+
+
+-- XAW --
+ + I had added a XawStackAlloc definition to "Private.h", to avoid a XtMalloc
+ request for every character typped in TextAction.c:InsertChar(), but
+ when syncing with 3.9Aj, saw that the file "XawAlloc.h" is no longer
+ required. Please, remove XawAlloc.h from 3.9Aj.
+
+
+-- XMU --
+ + Added the file Clip.c, with clipping code, that, now is being used by
+ the text widget, but can be used by other widgets.
+
+-- xedit --
+ + Removed a XDefineCursor from xedit.c:main()
+ + I have added a XtSetKeyboardFocus in xedit.c:main(), but comented it
+ because it would make xedit unusable with previous versions of Xaw,
+ or with the Xaw replacements (Xaw3d, Xaw95 ...)
+
+Comments:
+ I wrote a lot of code to work properly with italic fonts in the text widget,
+that code made the cursor do not erase portions of the text while moving the
+it, but it was failing at some places that would need that the TextWidget,
+and not only the {Ascii,Multi}SinkObject had access to the fonts, so I
+choosed to left it to the future (and keep the sources simple, by now).
+The text widget is useable with italic fonts, but fonts with:
+ f->per_char[<char> - f->min_char_or_byte2].rbearing
+ > f->per_char[<char> - f->min_char_or_byte2].width
+or
+ f->per_char[<char> - f->min_char_or_byte2].lbearing < 0
+will not allways be displayed correctly.
+
+ I haved also added a xedit configuration file to this mail.
+
+
+#1842 27 July 1998
+
+Fixed problem with the default macro for type conversion, where it was
+ possible to the code tell the wrong size of a string, since it was
+ returning the string size with 'strlen' but making the copy with strcpy.
+Complete ansification of Xaw (and Xmu).
+Corrected some problems caused due to an alteration in the text code, to
+ make the cursor always visible when the wrap mode is 'line' or 'word'.
+Text.c:VJump() was made a bit smarter and a problem that would cause it
+ to jump incorrectly was also corrected so that now the jumping should be
+ very smooth.
+Corrected problem that would cause a coredump due to the
+ Text.c:_XawTextReplace() deferencing a NULL pointer. Now ctx->text.lt.info
+ is initialized when the text widget is created, solving this problem.
+All the variables with name 'new' and 'class' where renamed to 'cnew' and
+ 'cclass'. This allows even building Xaw with 'gcc -x c++'.
+Variables shadowing other variables or functions where also renamed.
+Static functions were changed to use wide parameters, where applicable.
+(Almost) every time a StringTo<Type> converter is installed in the class
+ initialization of a widget, the code also installs a <Type>ToString converter
+ since now editres seens to work better.
+Complete reestilization of the indentation. See the files Template*.{c,h}.
+Corrected problem with the 'virtual' function Layout of the Form widget. That
+ function requires 4 parameters, but the Viewport widget (a Form subclass) was
+ calling that function with only 3 parameters; the ansification flagred that
+ error.
+TextTr.c was modified to have only one string. I believe that that weird
+ thing was due to the inheritance of compatability with some very old and
+ probably buggy ld.
+Xaw is expected to be binary compatable with R6.3; there are some
+ preprocessor macros that keeps binary compatability, and unless the gains
+ of breaking binary compatability show worth enough (and people think) it
+ is good that code would be made default, otherwise it will be forgotten.
+I have also added a XFree86 copyright notice to Text.c, since there is
+ a very large amount of work in that file (and it is not yet ready).
+---------------------
+
+-------- Xmu --------
+Complete ansification of Xmu.
+Rework of EditresCom.c to allow editres working correctly. It was also
+ added a new feature, that allows editres finding some extra child widgets,
+ i.e. widgets that aren't a child of a subclass of composite and aren't in
+ the popup list. This modification is not enough, since it does not find
+ child widgets that don't a XtRWidget resource in the parent widget.
+Rework of ShapeWidg.c, so that it will give the correct feeling to the
+ ellipse shape, and inversion of the oval, if shape is oval and
+ height > width. To see these changes, run a program with:
+ <prog> -xrm '*shapeStyle: ellipse'
+ and/or
+ <prog> -xrm '*shapeStyle: oval'
+Revision of DrRndRect.c to make the widget looks 'more correct' when using:
+ <prog> -xrm '*shapeStyle: roundedRectangle'
+---------------------
+
+------ editres ------
+Added small patch to bug in handler.c so that editres will correctly now.
+---------------------
+
+------- xedit -------
+Changed the resources file, to avoid a problem when resizing xedit to a
+ very small size and than restoring it's size. Probably the culprit is the
+ Paned widget, but the new resource file is at least a good workaround for
+ the problem.
+The resource file was also modified so that the default xedit size will
+ give a 80x25 rows/columns when using the default font.
+---------------------
+
+-------- xgc --------
+Small patch to clear correctly the status text window, when pressing the
+ 'Clear window' button. Note that this patch showed a bug in
+ Xaw/{Ascii,Multi}Src.c; only apply this patch with the latest Xaw, or
+ be sure that Xaw/{Ascii,Multi}Src.c:*SetValues() has something like:
+ if (old_src->ascii_src.ascii_length != src->ascii_src.ascii_length)
+ src->ascii_src.piece_size = src->ascii_src.ascii_length + 1;
+ instead of:
+ if (old_src->ascii_src.ascii_length != src->ascii_src.ascii_length)
+ src->ascii_src.piece_size = src->ascii_src.ascii_length;
+ or it will enter a infinite XtMalloc(0) loop :(
+also fixed a possible buffer overflow while searching the source of the
+ bug described above.
+---------------------
+
+#1945, 31 Aug 1998
+
+-- XAW --
+ + Corrected bug in Viewport.c:ComputeLayout(), that would put the scrollbar
+ in the incorrect position, if w->viewport.useright == True
+ + Corrected bug in Converters.c:_XawCvtCARD32ToString(), so that now it
+ will correctly format the converted value.
+ + Corrected problem in {Ascii,Multi}Src.c:Search(), that would cause a
+ incorrect offset to be returned, if the searched text (or a substring of
+ it) were in a 'Piece' boundary.
+ + Some small patches to other sections of the code, to reduce the number
+ of warnings generated by gcc, when using more restrictive warning options.
+
+-- XMU --
+ + Corrected a problem in Atoms.c:GetAtomName(), to return a NULL pointer,
+ instead of a const if the given atom is 0.
+ + Corrected a typo in Xmu.h
+ + Several 'ansification' patches, to get function definitions and avoid
+ unecessary definitions.
+
+
+#2028, 2033, 7 Oct 1998
+
+-- Xaw --
+Added a delete translation to the text widget, that deletes the current
+ selection if any, else the backwards char.
+Corrected bug that would not update correctly the screen if page-up or
+ page-down was pressed while there was an selection.
+Added a ^Q<any-char> translation to the text widget, to be able to insert
+ any char in the text.
+Changed TextAction.c:Move() to set ctx->text.showposition, so that even
+ if the cursor did not change the position, it will become visible.
+Corrected problem with the 'form-paragraph' translation, so that the
+ text will be always correclty shown.
+Modified the automatic scrolling of the text to one line at a time, to
+ make it easier to see what is being selected.
+Added a 'hack' to be able to type ^U<any-numeric-sequence> to be able
+ set the multiply of the text widget. Since it is a hack (besides seens
+ to work very well) it can be disabled with -DNO_NUMERIC_HACK
+Corrected a nasty bug in Text.c:CvtStringToScrollMode(); XtConvertAndStore
+ can't be called from a type converter!
+added UNDO/REDO to the text widget. Please try it, I think it is very nice.
+ Undo is enabled by the new resource 'enableUndo', and, by default is
+ triggered with 'Ctrl+_'.
+
+-- editres --
+Resubmitting a patch to editres/handler.c, to make editres work properly.
+
+-- xedit --
+NOTE that with this patch, xedit probably will not work with Xaw3d, neXtaw...
+ this surelly can be fixed, or in the xedit side or the *Xaw* side, but
+ the patch seens to be necessary.
+Changed the defaults file to be more user friendly and previsible.
+ Added some 'Emacs like' binding translations.
+Added file completion in the filename prompt. This is a very nice
+ feature, but I'm not sure if the code is portable to all the XFree86
+ supported platforms (surely it will not work 'as is' with OS/2).
+
+
+#2083 18 Oct 1998
+
+-- XAW --
+Changed the functions {Ascii,Multi}Sink.c:CharWidth and PaintText, to
+ improve speed, and avoid too much recalculations. On normal files, it
+ becames about 5:1 faster, but can go up to 20:1 when editting files with
+ very large lines. Besides this speed improvement, I believe it can
+ surely be made faster (based on comparition with some popular X editors).
+Changed the way the AsciiSink prints characters with value bigger than
+ 126 decimal. Now it prints DEL as ^?, and the other characters as \XXX
+ where 'X' is an octal digit. The MultiSink widget was unchanged in this
+ respect, i.e. when calling xedit with something like:
+ xedit -xrm '*international: true'
+Converted all calls to strncpy, in AsciiSrc.c to memcpy, so that the (ascii)
+ text widget will work properly with data containing nulls.
+Added a experimental 'Xaw Scan Type' XawstAlphaNumeric, that shoud make
+ edition of C (or any other language) easier in xedit (i.e. the text widget).
+ It can be tested with Ctrl-Left and Ctrl-Right, by now.
+Changed the TextWidget to handle text lines that would result in more than
+ 32767 pixels. Besides the text widget is not meant to be used in the
+ edition of binary files, this change allows it.
+Changed Text.c:TextScroll() to be smarter when calculating the offset of
+ the line table on scroll up.
+Added a nice feature, to show the matching '(', '[' or '{', when a ')',
+ ']' or '}' is typped.
+Changed TextAction.c:FormParagraph() to generate only one undo/redo step.
+
+-- xedit --
+Changed the defaults file to enable backups and made the backup suffix
+ the character '~'.
+Replaced all instances of sprintf by XmuSnprintf.
+Changed xedit to set the label when saving a file also, to reflect what
+ is being edited correctly.
+Corrected a bug in the new action 'file-completion', to replace correctly
+ the home directory, and keep correctly whatever was after the '~'. This
+ isn't the correct place to this code (xedit/commands.c), since there are
+ several other file name prompt windows in Xaw, but since it is required
+ another window to show the possible matches, I'll study a better way to
+ implement it.
+Added a 'hints' feature to xedit. Instead of a 'dead'
+ "Use Control-S and Control-R to Search." label, now it allows the label
+ string being changed at user settable intervals.
+
+
+#2205 10 Nov 1998
+
+-- xaw --
+ + Fixed some 16 bit overflows in AsciiSink.c and some cases where it would draw
+ past the end of the text window (a no-op), the overflows were not a
+ problem, but could left the text window with incorrect data.
+ + Moved the undo/redo code to TextSrc.c, and some code/data from
+ {Ascii,Multi}Src.c to TextSrc.c. The callback now is called when the
+ source is changed, or becames unchanged due to an undo/redo. Also
+ changed the Scan procedure to be a bit faster.
+ + The asciiTextWidget will now accept a source or sink object being set at
+ creation time.
+ + Fixed the 'struct XawDisplayList' being redefined when compiling Xaw under
+ SunOS.
+ + Several changes to the SimpleMenuWidget to make the geometry management
+ work correctly when adding/removing/changing menu entries at run-time.
+ + Added a 'kill-ring' feature to the TextWidget. The behaviour is identical
+ to Emacs. Pressing C-K repeteadely will merge the lines being killed, so
+ that a C-Y latter will paste all the killed lines.
+ + Added the enough glue code (and as backwards compatible as possible) to
+ allow the *src object be shared between several TextWidgets. My initial idea
+ was to make the TextWidget be able to have more than one source, but, to
+ be backwards compatible, I did the reverse (the source can have more than
+ one TextWidget).
+ + Fixed a automatic wrap bug (TextWidget) that could eat non white space
+ characters (my previous patch to this problem was completely wrong).
+
+-- xedit --
+ + Added a split-window feature to xedit. To keep xedit simple, it only allows
+ two windows at the same time: or subdivides in the vertical or horizontal.
+ + Added more some key-bindings, that should do the same as Emacs.
+
+#2291 5 Dec 1998
+
+-- Xaw (only changes to the 'text' code) --
+ + Changed the default 'piece size' from BUFSIZ to the value returned by
+ the getpagesize() function (or keep BUFSIZ if that value is smaller).
+ + Added a case sensitive option to the search popup. This is a 'hack' by
+ now, but should not cause trouble to anybody.
+ + Fixed a bug inserted when changing the code for the search, the only side
+ effect I saw was that the jumping cursor to show the matching '(', '[' or '{'
+ stopped working in my last patch.
+ + Moved back my change to the function XawTextSetSource. The 'correct' function
+ is _XawTextSetSource. This is only to make sure old code should compile
+ cleanly.
+ + Added line and column number calculation code (and a callback to tell when
+ that information changed) to the TextWidget. This was not an easy task,
+ because I tried to optimize as much as possible the code, and do relative
+ calculations, instead of scanning the entire file to count the number of
+ lines (there are several special cases, when removing/inserting text).
+ + Added the selection type XawselectAlphaNumeric. This adds one step in
+ the sequence word-line-all when doing multiclick in the text.
+ + Fixed some bugs in the 'kill ring' feature added in the last patch. Now
+ it is expected to never fail.
+ + Corrected the indentation of TextP.h, and changed more some fields. The
+ internal data of the TextWidget changed a lot, so it is not expected that
+ program code read directly the private data, at the price of requiring the
+ correct library version.
+ + Fixed a small bug in the undo code, that would 'think' the file was unchanged
+ in the incorrect position in the undo buffer.
+ + Changed the default key bindings for delete/kill word functions to use the
+ alpha numeric versions (this is better for coding, and more compatible with
+ other text editors).
+
+-- xedit --
+ + Changed the labelWindow, to show the current line number (but it is also
+ possible to show the current column number, offset or file size).
+ + Fixed bug when saving the *scratch* buffer with a new name.
+ + The 'changedBitmap' is now correctly displayed on all the windows showing a
+ changed file.
+ + Small changes to the xedit man page.
+
+
+
+#2371 8 Jan 1999
+
+--- Xaw ---
+ + More some changes to AsciiSrc.c:Scan(). This improves a bit the speed when
+ scanning text.
+ + Added sanity checking for AsciiSrc.c:Search(), to avoid the risk of
+ deferecing a null pointer (or reading memory out of the text piece) if the
+ searched text happens to be larger than a "piece size".
+ + Fixed bug when trying to optimize line number calculation, due to a typo,
+ while meaning XawTextWrapNever I wrote XawTextWrapLine.
+ + Fixed a problem shown by xclipboard, when setting the "string" resource
+ of the text source, the sink object was keeping the insertPosition in the
+ old text contents, and then, when showing the cursor, it was incorrectly
+ 'erasing' the old cursor position.
+ + Fixed problem in XawTextReplace, that would not update correctly all the
+ TextWidget's sharing the same source.
+ + Added a kill ring list to the text code. This works like the emacs feature,
+ but, unlike emacs, it is not required to press C-Y before M-Y, to start
+ looping through the kill ring list. To use it, just press M-Y repeteadly,
+ and all the text that was killed will be inserted, one at a time, so that
+ you can choose one. Note that the text inserted from the kill ring list
+ will also enter in the undo list.
+ + Changed the Move{Backward,Forward}Paragraph actions to make the cursor always
+ stop in a blank line. This makes only one step moving from a paragragh to
+ another, instead of two.
+ + Added code to check for overflows in the C-U<number> sequence.
+ + Changed the FormParagraph action to keep the cursor at the correct position.
+ + Changed the default translations in TextTr.c to get a more emacs like
+ behaviour with the kill ring list.
+
+--- xedit ---
+ + Added a few more resource settings to the Xedit-sample file.
+ + Added some sanity checkings when trying to save a file. This avoids the
+ case of saving a file with the name of a directory (but moving the directoy
+ to other name before). A possible case is: have a directory named 'dir',
+ saves a file as 'dir', but before saving, renames the directory as 'dir~'.
+ + Allows saving a file that xedit thinks is not changed (the file may have
+ changed on the disk, but the user really wants to rewrite it).
+ + Corrected several bugs in the FileCompletion action, and added a new
+ feature, that is to complete the partial names, when there is a '/' or '.'
+ after the cursor position.
+
+
+#2479 19 Feb 1999
+
+-- Xaw --
+ + Fixed bug in the line numbering code, when removing lines before the
+ top position.
+ + Changed code to form regions to always show the cursor after formatting the
+ text.
+
+-- xedit --
+ + Added code to keep the file mode, after saving. This is useful when editting
+ scripts, so that the executable flag will not be lost after edition.
+
+
+#2544 12 Mar 1999
+
+-- Xaw --
+ Mostly changes to add support to latin-* languages in the text code, when not
+ using the international resource.
+Actions.c:
+ + Corrected some bugs in the boolean expression parser. The old version would
+ not parse correclty parenthized expressions, and was giving equal precedence
+ to AND, OR and XOR (what is incorrect).
+AsciiSink.c:
+ + Changed to display characters in the range 0x32-0x7e and 0xa0-0xff literally.
+ The other characters are represented as control-codes, as before. This is
+ better for edition of Latin-* text files.
+AsciiText.c:
+ + Changed the code, so that even if the *international resource is not set,
+ _XawImRegister and _XawImUnregister are called for the text widget. This is
+ useful for latin-* locales, that use one byte wide characters, and makes Xaw
+ more compatable with modern toolkits, like qt and gtk.
+List.c:
+ + Added code to work correctly with a background pixmap.
+ + Added a smarter code for list window size calculation, that is used if the
+ number of columns is especified to be zero (automatic).
+MultiSink.c:
+ + Fixed a core-dump problem caused when passing a null pointer to
+ XwcTextEscapement.
+Text.c:
+ + Removed the resource adjustScrollbars. This resource was not used, and its
+ funcionality was not finished, and by now, it is not required.
+TextAction.c:
+ + Does not call XLookpupString in InsertChar any more, but the new function
+ _XawLookupString (in XawIm.c) to work correclty with composed characters.
+XawIm.c:
+ + Added the private function _XawLookupString, that just calls XmbLookupString,
+ or in case of any initialization error, XLookupString.
+
+-- xedit --
+ The most important change is the addition of a new functionality, that allows
+ the user to navigate the file system, in a 'ls -a' like list widget, if
+ the file is not a directory it is loaded for edition, else, the list widget
+ is rebuilt with the contents of the selected directory. To test it, just
+ type: C-X d, or tab when 'finding a file'. To exit the dirwindow without
+ loading a file, type C-G or Escape.
+Xedit-sample:
+ + Added more some resource entries, to use the new 'emacs dired like' feature.
+Xedit.ad:
+ + Same as for Xedit-sample, but more important resource settings.
+commands.c:
+ + The code now checks if the filename is a directory and calls the dirwindow
+ code in that case, when trying to open a file.
+ + Changed the function IsDir from static to global, to use it from xedit.c.
+ + Most of the code for the filesystem navigation window was added to this file.
+util.c:
+ + Fixed a bug that was causing core dump due to passing garbage to XtGetValues
+ as the widget address.
+ + Added the code for managing the dirwindow and its relationship with the
+ text windows to this file.
+xedit.c:
+ + Added the code for creation the dirwindow to this file.
+
+
+#2638 2 Apr 1999
+-- Xaw --
+ + Added xpm pixmaps support to the library. This time, it is required to
+ compile Xaw with -DUSE_XPM.
+ + If the xpm image has a mask, the widget will be automatically reshaped
+ to the pixmap mask.
+ + Changed the kill_ring code in TextAction.c to always end in a text block
+ of zero length, this way, it is easier to know when one traversed the
+ entire kill ring (it may be interesting to forget the undo sequences
+ while traversing the kill ring list).
+
+-- xedit --
+ + Changed the Xedit.ad file to avoid overriding a translation that would
+ make the search window do not respond to WM_DELETE_WINODW messages.
+ + Fixed a core dump condition in the new code for listing files and
+ directories, due to deferencing a null pointer.
+
+
+#2662 10 Apr 1999
+-- Xaw --
+ + Corrected the problems gererated in my last patch. I was compiling with
+ -DUSE_XPM defined, and did'nt realize that the patch would not compile
+ without it. Just ifdef'ed again the code to avoid warnings or dead code.
+
+-- xedit --
+ + Added a ispell interface to xedit. Sorry for not documenting enough about it
+ the man page, but here is a small explanation of the new funcionality:
+ Replace: Replace's the selected word.
+ All (right side of Replace button): Replaces all occurrences of the selected
+ word.
+ Undo: When this button is sensitive, allow undoing the last replace,
+ this is useful when doing a incorrect "Replace All" action.
+ Ignore: Ignore this word, and continues spell checking.
+ All (right side of Ignore button): Ignore any further ocurrences of the
+ selected word.
+ Add: Add's the selected word to the user's private dictionary.
+ Suspend: Go back to text edition, but does not kill the ispell process,
+ This is useful if you have a really big dictionary or slow
+ machine. I believe it is mostly useful to keep in memory
+ the words selected to be ignored, but that you don't want to
+ add to your private dictionary.
+ Close: Kill the ispell process, and go back to text edition.
+ Automatically saves the user's private dictionary.
+ When pressing the Add button, the word in the "Mispelled word:" field is
+ added to the user private dictionary (normally ~/.ispell_*). When pressing
+ the Replace button, the text in the "Replace with:" field is used.
+ If no word is selected in the "Suggestions:" field, this mean that the
+ selected word was not found in the ispell dictionary.
+
+
+#2716 24 Apr 1999
+-- Xaw --
+ + Minor changes to AsciiSrc.c to try to get more speed in the FindPiece
+ function. Xedit may become very slow when editing files bigger than 1M,
+ and I'm studing ways to get more speed in the Scan and FindPiece functions.
+ The FindPosition function in *Sink.c also can consume a lot of cpu time,
+ and may need some rework.
+ + Added submenus support to the SimpleMenuWidget. This is something essencial
+ to a widget toolkit. Just plugged in the code of a menu widget I wrote some
+ time ago. Xedit uses submenus now. To use it, set the resource menuName
+ of a SmeBSBObject to the name of the submenu.
+ + Added code for text justification to the TextWidget. To use the justification,
+ set the resources autoFill, leftColumn and rightColumn. If autoFill is set,
+ and leftColumn is smaller than rightColumn, an alternate code will be
+ used in the form-paragrpah action, normally triggered with M-Q. The values
+ for justification can be left, right, center and full.
+ + Added a overwrite mode to the TextWidget. The default translation is to
+ press the Insert key, that will toggle the overwrite mode.
+ + Made the TextWidget understand negative values for the multiply. This is
+ like the emacs feature, to indent text to the left. To set a negative value
+ to the multiply, just start the numeric sequence with a '-'. Like C-U -1.
+ + The code for justification added several new functions to TextAction.c.
+ Functions to tabify, untabify, get block boundaries, verify if a line
+ is completely blank, and strip excess of spaces.
+ + Added a indent action to the TextWidget. The default translation, only
+ used by xedit, is C-X Tab, did this way, to make it fully compatable with
+ emacs, but other translations can be used. The multiply value is used to
+ calculate the amount of spaces to move to the left or right.
+ + Corrected a very hard to find (and reproduce) bug in the undo code, that
+ would easily cause core dumps. The problem would happen when starting
+ editing exactly in the moment the redo automatically reverts to undo.
+ + Added translations for toggling the overwriting mode with the Insert key,
+ and to paste the selection with S-Insert.
+
+-- xedit --
+ + Corrected all the known bugs in the ispell code (including a memory leak).
+ And added a compile time limit of 16 levels of undo, for all the actions,
+ that include Add, Ignore and Replace. 16 levels is more than enough, but
+ more than this can be done with the undo action, but then, only to revert
+ replaced text, to remove added words that the undo code forgot, it is
+ required to edit the personal dictionary file. The code now also understands
+ root/affix combinations, that ispell normally returns when using the
+ -m option. The ispell code should now also work when using the international
+ resource of the edit window.
+ + Added a new file, called options.c, that holds the code for the editMenu,
+ to enabling setting the wrap, autoFill, justify, leftColumn, rightColumn,
+ verticalScroll and horizontalScroll resources of the current edit window.
+
+
+#2746 1 May 1999
+-- Xaw --
+ + Reverted most of the #if NeedWidePrototypes definitions, only two
+ functions were kept, to not break some of the new features, but these
+ functions aren't called by any program: XawTextSinkDisplayText and
+ XawTextSinkClearToBackground.
+ + Rewrite of the functions *Sink.c:FindPosition() and FindDistance() to
+ try to get more speed.
+ + Reworked the function Text.c:_BuildLineTable, to correct some strange
+ code, and to avoid unecessary recalculations.
+ + Made negative values of the multiply work for all the actions, not only
+ for negative indentations. This makes the TextWidget behaviour more
+ compatable with emacs.
+ + Optimization of the new code for text justification, to avoid a call to
+ malloc on every char typped, when undo is enabled.
+ + Reorganized the offsets of the fields of the TextWidget, trying to make
+ xxgdb work again with the new Xaw code, but, unfortunately, the SimpleWidget
+ (a subclass of the TextWidget) have growed by 4 bytes (a XawDisplayList*)
+ added at the end of the structure, and xxgdb incorrectly reads the text.sink
+ field. Old xxgdb binaries dont work with the current code.
+ + Removed several XtIsSubclass checks in TextSrc.c. While those checks could
+ be useful for debugging, the functions are called so frequently that it is
+ a big waste of time for running programs.
+
+-- xedit --
+ + Added/Changed some translations to work correctly when CapsLock and/or NumLock
+ are pressed.
+ + Fixed some bugs in the ispell code. The biggest bug was that it was not
+ correctly saving the Add'ed words in the user dictionary when pressing the
+ Close button.
+
+
+#2764 8 May 1999
+-- Xaw --
+ + Create two new private functions, to replace internally the public interfaces.
+ These two functions are XawTextSinkClearToBackground and
+ XawTextSinkDisplayText. These two functions use wide prototypes, and
+ are required to support text lines that are represented by more than
+ 32767 pixels. This was done to make sure that the public interfaces remain
+ 100% backwards compatible.
+ + Fixed the deferencing of a null pointer when the source object of a text
+ widget is not initialized. I noticed this problem when recompiling xcolorsel.
+ + Added a new type converter to Converters.c, that is Short -> String.
+ + Added a new compile time option, called NO_BIN_COMPAT_HACK. If defined,
+ it will break some programs that access private data. It only works with
+ programs that access private data structures, but don't subclassify any
+ widget. It fixed old binaries of chimera1, the Offix editor and xxgdb.
+ There is no way to fix old binaries of chimera2, xcolorsel and xmh, these
+ programs need to be recompiled. I would like to know of other programs that
+ became broken, to try to fix them with the NO_BIN_COMPAT_HACK option.
+ + Fixed some compile warnings, with shadowed, uninitialized and unused
+ variables.
+ + Fixed a inifite loop problem that could happen when the text widget window
+ was resized to a very small width.
+ + Reverted some of the text widget translations, to avoid conflicts when
+ setting the input focus and programs that do so.
+
+-- xedit --
+ + Fixed a problem in the file-completion code, that would insert the partial
+ match in the incorrect position, if the cursor was not at the end of the
+ string.
+ + Changed ispell.c to use only one hash for ignored and added words. Also
+ changed the IspellSend function to not call itself recursively, what is
+ a big problem when spell checking big files that are correct or have too
+ few errors.
+
+-- editres --
+ + Changed Editres.ad in several places, to try to avoid resource setting
+ problems. Most of them were changed to address more directly the resource,
+ and avoid confusion. Also, added some new resource settings to configure
+ the code I added to widgets.c.
+ + Changed widgets.c to make sure the resource setting dialog is allways
+ entirely in the screen, and if it does not fit, scrollbars will be created.
+
+
+#2793 15 May 1999
+-- Xaw --
+ + Changed AsciiSrc.c:LoadPieces to load the file incrementally, instead of
+ allocating a big buffer.
+ + Added several new functions to DisplayList.c. Almost all gc and painting
+ related functions were mapped to displayList functions. There are
+ several optimizations that can yet be done to the displayList code, and
+ I'm working on it. That code is clearly not finished yet, but is stable.
+ Also, changed some functions to be more exigent with it's parameters,
+ because it is better to receive a warning message than see the program
+ core dumping. The functions are documented in Xaw.man.
+ + Corrected a problem in the SimpleMenu code, to make the sub menus popup
+ more 'visually' correct, when popping up in the left side.
+ + Added a optimization in Text.c, to avoid unnecessarily recalculating
+ the line and column number when scrolling text. A big speed up should
+ be seen when scrolling large files.
+ + Modified all code that expected TAB_SIZE to be equal to 8, to read the
+ TextSink resources, and work properly with whatever value the program
+ had set to the tab stops.
+ + Fixed a very bad bug in the form-paragraph function. It was very hard
+ to find because I was looking at the wrong places. If the text was
+ allready formatted, or did not need formatting, the code was not
+ reenabling undo, making the undo/redo behaviour imprevisible.
+
+-- xedit --
+ + Added Xedit-color.ad file, to show some of the new features of Xaw.
+ Tried to keep it simple, but since it uses gradients, maybe it should
+ better be called Xedit-TrueColor. The better way to see the functionality
+ of this file is (if you don't have it already) add to your .Xdefaults:
+#ifdef COLOR
+*customization: -color
+#endif
+ and make sure xrdb parses it.
+ + Changed a bit Xedit.ad, to work properly when Caps Lock is pressed.
+ + Several changes to ispell.c. It should run very faster now, because
+ the code keeps information about words already ignored or correct
+ in the xedit side, instead of asking ispell every time. Added also
+ a terseMode resource, and made the interface ask for user interaction
+ allways ispell does not say the word is completely correct; the
+ terseMode resource makes ispell itself decide what words are correct
+ or not.
+
+-- editres --
+ + Small patch to Edit-col.ad, to use a default text cursor color of 'Azure'
+ in text fields, instead of the default 'black'.
+
+
+#2811 22 May 1999
+-- Xaw --
+ + Removed the 'NO_NUMERIC_HACK' preprocessor definition, and renamed the
+ 'doing_numeric_hack' field of the text widget to 'numeric'.
+ + Changed the code to always create the horizontal scrollbar, if requested.
+ + Small changes to TextPop.c, to automatically scroll horizontally the
+ text window when the text found in a search/replace action is not visible.
+ + Added a optimization when editting large files, to rebuild the line table
+ if the region containing the text being added/replaced overlaps the lt.top
+ field of the text widget.
+ + Changed the undo code to also merge text typed when overwrite mode is
+ active. The new behaviour is not like emacs (that generates a undo step
+ for every character), but uses less memory, making only one undo/redo step.
+
+-- xedit --
+ + Added a new file, hook.c that is intended to be used for the addition of
+ some new features to xedit, like auto indentation of program files. The
+ first feature added is the 'autoReplace' resource, described in the xedit
+ man page.
+ + Corrected a bug in ispell.c, that would make the code alocate lots of
+ memory unnecessarily, due to an uninitialized variable. Thanks to David
+ Dawes that found the bug. The bug was not in 3.9Pn, but the solution in
+ the later release was not completely correct.
+
+
+#2834 29 May 1999
+-- Xaw --
+ + Added a ChangeSensitive function to Command.c, to avoid it creating an
+ incorrect insensitive border if the button is set. This is a side effect of
+ the function XawCommandToggle I added some time ago. The solution for the
+ problem is not very elegant, since it copies almost verbatim the code from
+ Simple.c, but it works as expected.
+ + Moved some calls to _XawTextSetLineAndColumnNumber in Text.c to other places,
+ to make sure it is safe to change the text when the positionCallback is
+ called (like what is done by the new xedit file hook.c).
+ + Another optimization was added to the undo/redo code. Now it also merge
+ erases, needing yet less memory for undo, and this way, generating less
+ undo/redo steps.
+ + Removed the default translation to call the toggle-overwrite action from
+ TextTr.c. Only the xedit edit windows calls this translation now, instead of
+ every text widget.
+
+-- xedit --
+ + Changed the auto replace feature to be a bit more easier to use. The new
+ behaviour is almost identical, but if the user types some text, and it is
+ auto replaced, only one undo step is enough to correct it. Example:
+ 1) user types 'nto.'
+ 2) text is auto replaced by 'not.'
+ 3) user call undo action
+ 4) text is converted to 'nto.'
+ It should be a very infrequent problem, but makes the xedit behaviour
+ identical to a "well known text editor", from where this feature was borrowed.
+ + Added a 'Check' button to the ispell interface. This button allows
+ checking the word in the text field. This feature was borrowed from the spell
+ checking interface of the Netscape html editor.
+ + The ispell checking interface now also asks for user interaction if there are
+ two identical words togheter.
+ + Added a status bar to the ispell interface, to give feedback to the user
+ about what is happening.
+ + Added some new resources, to let easier customization of the ispell status
+ bar strings. The new resources are documented in xedit.man.
+
+#2849 5 Jun 1999
+-- Xaw --
+ + Add a OLDXAW define, to enable building a binary compatible version with
+ 6.1, and changes to the Imakefile, to try to keep the changes only in Xaw.
+ I hope it can be removed in the future.
+ + Add a XawVendor define, with the value "XFree86". If this is not a good
+ idea, please correct it an let me know.
+ + Add a XawVersion define. The value for the new xaw is 7000L, and for the
+ compatible one is 6700L (same comments as for the XawVendor define).
+ + Bug fixes to the undo/redo code, and code to merge erases generated by
+ ^H and ^D. Also, if the cursor is moved, it stops merging the text typped
+ in the undo buffer.
+ + Bug fixes to the Form widget geometry management code, to work correctly
+ when child widgets are removed or added at run time.
+ + Xaw now links with XPM by default, and the config files where changed to
+ enable newly compiled programs to do so.
+ + Added 16 pad bytes to every widget, to try to avoid binary compatability
+ problems in the future.
+ + Added a displayList resource to the Tree Widget.
+ + Added the functions XawTextGetSink and XawTextLastPosition, to enable a
+ public way to get the <TextWidget>->text.sink and <TextWidget>->text.lastPos,
+ since these are the most commonly private fields the programs access in
+ the text widget.
+ + Added the actions 'capitalize-word', 'donwcase-word' and 'upcase-word' to
+ TextAction.c. The bindings are the same as of Emacs (and the way it works).
+ + Corrected some problems with negative values of the <TextWidget>->text.mult.
+
+-- xedit --
+ + Correct possible problem in the file hook.c, when interpreting the auto
+ replace list, that is, it was not checking the buffer size when finding
+ the '\' character.
+ + Updates for the configuration files.
+ + Added a 'Look' button the the ispell interface, that will by default run
+ "/usr/bin/bin/egrep -i '^<VALUE OF TEXT FIELD>.*$' /usr/share/dict/words"
+ and put up to 256 returned words in the ispell list. The behavior is
+ almost identical to the one in the terminal interface of ispell.
+ + The ispell interface works correctly with aspell now.
+ + Added some resources and a popup to enable changing the dictionaries in
+ run time.
+ + Added a toggle button to the ispell interface to allow changing the terse
+ mode in run-time.
+ + Added a 'Uncap' button, to allow adding an uncapitalized word to the
+ private dictionary, and enough code to do the capitalization checks inside
+ of xedit (to enable undo actions).
+ + Added a "text mode" and a "html mode". The html mode is not yet completely
+ finished. It must work correctly with some html specific things like
+ converting internally "&aacute;" to "á" and so on. I'm planning also, at
+ least a nroff mode too.
+ + The wordChars resource is set by dictionary now.
+ To set the word chars for the br dictionary, write something like:
+ *ispell*options.dictionaries.br.wordChars: <VALUE>
+ or
+ *ispell*br.wordChars: <VALUE>
+ or simply
+ *ispell*wordChars: <VALUE>
+ + The skipLines resource is set only for the text mode now.
+ To set it, write something like:
+ *ispell*options.formats.text.skipLines: <VALUE>
+ or
+ *ispell*options*text.skipLines: <VALUE>
+ or simply
+ *ispell*skipLines: <VALUE>
+
+
+#2877 12 Jun 1999
+-- Xaw --
+ + Note: The compatible old version of Xaw is not fully compatible. There
+ a few things that are not equal to the standard old Xaw. These are:
+ + The cursor code in the *Sink.c files is not identical, and the
+ field insertCursorOn (type Pixmap) was replaced by the field
+ cursor_position (type XawTextPosition).
+ + There are some changes in TextP.h, that include changes to the fields:
+ options -> left_margin
+ unrealize_callbacks -> pad1
+ updateFrom -> update
+ updateTo -> pad2
+ numranges -> pad3
+ maxranges -> from_left
+ copy_area_offsets -> pad4
+ + The text window does not increase its size when text is typed past
+ the end of the window, instead of it, it is automatically scrolled
+ horizontally, but this may not be enough to every usage of this
+ feature; xmh uses that code to make the text widget auto resize
+ warning popup widgets. I dont know what is better in this case,
+ if re-enabling the auto resize code of changing xmh to use label
+ widgets in the warning popups.
+ It is very unlikely that exists code that will have problems with these
+ changes in the fields of the TextWidget and the *SinkObject, but if any
+ code that has trouble with it exists, I will promptly make the required
+ changes to correct it (at least for the compatible version of Xaw).
+ + Several optimizations for the code to redisplay the text window in the
+ TextWidget. Including fixes for bugs in the XawTextScroll function, and
+ making it really works. Previous versions of the library have made this
+ function ineffective, because it was always redrawing everything when
+ the text window was scrolled. The optimizations should be more noticeable
+ when running some application that uses the TextWidget (like xedit) on
+ slow hardware, or over slow connections.
+ + Corrections for the FormWidget geometry management code, to work correctly
+ in the old version of Xaw, and some bug fixes for the new Xaw. Also added
+ 8 pad bytes to the FormConstraintsPart structure, to have space for extra
+ information on possible future optimizations for the FormWidget geometry
+ management code.
+ + Some fixes for the OLDXAW define in the SimpleMenuWidget code, that was
+ not hiding some of the new fields introduced in the new Xaw code.
+ + Some corrections for the code handling the necessity of having scrollbars
+ in the text widget, and bug fixes for cases where the scrollbars were not
+ being updated when the text window contents were changed.
+ + Re-enabled code to also process GraphicsExpose events in the text code. It
+ became required due to the optimizations in the text redisplay code.
+ + Several fixes in TextAction.c, for symbols that were not being included
+ in the compatible version of the library, and for symbols that were being
+ included with no need.
+ + Fixes for the form-paragraph action, in the old Xaw code.
+
+-- xedit --
+ + Some bug fixes for the ispell undo code, to avoid deferencing a NULL pointer
+ in the function IspellCheckUndo.
+ + Added code to handle correctly &<VALUE>; in ispell.c, when using the html
+ mode.
+ + Fixed some compile time warnings, and updated the code for setting the
+ scrollbars in options.c.
+
+
+#2899 19 Jun 1999
+-- Xaw --
+ + Changed all the 'char pad[<number>]' to 'XtPointer pad[<number>/4]' to
+ make sure 64 bit machines will not have binary compatibility problems before
+ the 32 bit ones.
+ + Added a new static function 'WritePiecesToFile' to AsciiSrc.c, to avoid
+ allocation of temporary memory. This is useful when editing very large
+ files (I have some people using xedit on text files that can have up to
+ 80,000 lines).
+ + Added more some optimizations to AsciiSrc.c:Scan, to try to get the maximum
+ speed of this function.
+ + Added a new function to the displayList's, called 'image', that will tile
+ pixmaps on the widget. It is documented in Xaw.man.
+ + Several widget classes did not have a 'extension' field. I added it to them.
+ The first usage of this field that I'm planning is to extend the *Src and
+ *Sink objects to handle formatted text, and add text properties, like
+ foreground, background, font and so on.
+ + Fixed a bug in MultiSrc.c, that was crashing Xaw after the first character
+ was typed, or if text was removed.
+ + Some minor changes to SimpleMenu.c, to work properly with very large menus.
+ + Fixed some bugs that were caused by my previous optimizations of the text
+ redisplay code.
+ + Bug fixes and optimizations to TextPop.c, there were some cases that the
+ function XawTextDisableRediplay was being called, but XawTextEnableRedisplay
+ was not being called later because of a error condition (the error
+ conditions were only warnings).
++ Updates to Xaw.man.
+
+-- xedit --
+ + Fixed a memory leak when freeing list widget strings. The code was not
+ releasing the memory of the string at offset 0, in the list.
+ + Changed the way the ispell undo code handles the terse mode, to not need
+ to make the toggle button insensitive.
+ + Updated xedit.man.
+
+
+#2932 26 Jun 1999
+-- Xaw --
+ + Added a new tip resource to the SimpleWidget. This may also be seen as
+ a test of the binary compatibility issues. Besides of being a new feature,
+ it cannot cause problems with old binaries, because the code is only
+ called if the tip resource is set to any SimpleWidget subclass. If the
+ tip resource is set or reset, the SimpleWidget code will call one of the
+ two new functions XawTipEnable or XawTipDisable.
+ + Added 3 new files: Tip.c, Tip.h and TipP.h. These files are used only
+ by the new Xaw.
+ + Updates to Xaw.man, including a problem with accented characters on SunOS.
+
+-- xedit --
+ + Added resource configurations to show the new tip code in Xaw.
+ + Some fixes to ispell.c, to make it more previsible/user-friendly.
+ + Fixes xedit.man to avoid problems with accented characters.
+
+
+#2964 3 Jul 1999
+-- Xaw --
+ + Fix for problem found in the search/replace dialog when using splitted
+ windows in xedit.
+ + Added initialization for the display_list field of the Tree widget.
+
+-- xedit --
+ + Fixed some problems in the undo code of ispell interface.
+
+
+#2999 10 Jul 1999
+-- Xaw --
+ + Added code to check the return value of XAllocColor and XAllocNamedColor in
+ Pixmap.c.
+ + Reverted back some code, and did a carefull review of the code in TextPop.c
+ to avoid the possibility of calling XawTextDisableRedisplay, and not calling
+ XawTextEnableRedisplay later (due to errors or end of file reached).
+ + Added code to TextSrc.c, to use two static variables, that represent a new
+ line in 8 bits and wchar_t, to avoid allocating memory in the undo buffers
+ to store only a new line.
+ + Small change in the behavior of the Tip widget, to not unmap the tip window
+ when the cursor is moved.
+
+-- Xmu --
+ + Fixed a bug and a typo in the XmuToupper macro.
+
+-- xedit --
+ + Small update to the Xedit-sample file.
+ + Fixed a bug in the ispell code that checks for repeated words.
+
+
+#3122 14 Aug 1999
+-- Xaw --
+ + Mixed fonts and colors can be used in the text widget (currently only
+ in the Ascii*Object).
+ + Added the XawTextAnchor, XawTextEntity, XawTextProperty, XawTextPropertyList,
+ XawTextPaintStruct, XawTextPaintList and XawTextPropertyInfo structures to
+ Xaw, to be used in the new text code.
+ + Added the functions XawTextSourceAddAnchor, XawTextSourceNextAnchor,
+ XawTextSourcePrevAnchor, XawTextSourceRemoveAnchor and
+ XawTextSinkConvertPropertyList, that probably should not be used outside of
+ Xaw.
+ + Added the functions XawTextSourceFindAnchor, XawTextSourceAnchorAndEntity,
+ XawTextSourceAddEntity, XawTextSourceClearEntities and XawTextSinkGetProperty
+ that are probably the ones that should be most used in programs.
+ + Italic fonts should be always displayed correctly.
+ + The text widget cursor is now displayed with a gc with the Xor function, to
+ avoid unnecessary computation/redrawing.
+ + Most changes were done in the {Ascii,Text}{Src,Sink}Object, but the text
+ widget was also a bit modified for things like automatically changing the
+ number of lines in the line table when needed.
+
+-- Xmu --
+ + Fixed bug in Clip.c, that could cause a SEGV.
+
+-- xedit --
+ + Added the file c-mode.c, to interface with the new Xaw text code, and show
+ what can be done when interfacing that new code.
+ + Added the necessary code to util.c and options.c to let the user select
+ if he or she wants to use the color/font syntax highlight in the C/C++ mode.
+
+
+# 26 Aug 1999
+
+--Xaw--
+ + Added initial support for two new XawTextEntity attributes, that enable
+ hidden text and replaced text. This initial support was the minimum
+ required to get the new html mode in xedit working. A lot of code does
+ math with text positions, and became broken with the addition of these
+ two attributes. Since only code that knows about these two attributes
+ should use it, it is only a question to fix the remaining code in
+ Xaw/xedit.
+ + Bug fixes to AsciiSink.c:PreparePaint to work correctly with tabs and
+ the two new entity attributes.
+ + Disabled the translation "c<Key>q,<Key>Tab" of the search/replace popup.
+ This action is already done by the translation "<Ctrl>Q,<Key>" that I added
+ to TextTr.c. Disabling that translation has the advantage that now it
+ is possible to replace ^Ms by nothing.
+ + Added some new functions to TextSink.c. The functions XawTextSinkCopyProperty,
+ XawTextSinkAddProperty and XawTextSinkCombineProperty are candidates to being
+ public in the future, but, there is a problem when using
+ XawTextSinkCombineProperty, that requires the AsciiSinkObject having the
+ correct XawTextPropertyList, what can generate a "chicken and egg" like
+ problem (I did some hacks in xedit to have the first html-mode version
+ working).
+ + Added several new flags to the XawTextProperty attributes, and a new field,
+ called xlfd_mask.
+ + Some bug fixes to XawTextSourceReplace and to the code to manage the
+ XawTextAnchor e XawTextEntity structures. The form-paragraph, called with
+ M-Q does several consecutive text changes, and was very useful to find bugs.
+ + The flag XAW_TENTF_REPLACE is a hack for XawTextSourceAddEntity currently.
+ The function XawTextSourceAddEntity will probably change its parameters
+ to receive a structure pointer, or a pointer parameter.
+
+--xedit--
+ + Fixed some bugs in c-mode.c. Again, this patch fixes all the bugs I have
+ found.
+ + Added the html-mode.c file to xedit. The html-mode is in its initial steps.
+ It is not usable yet, but should not core-dump or leak memory (unless you
+ try to edit the file, then, I cannot say what will happen). The html mode
+ should be used only to see a rendered version of the file, but, there are
+ several markups not implemented. To be usable, it must yet understand at
+ least <ul>, <ol>, <li>, <dl>, <dd>, <hr> and the table tags.
+
+
+
+$XFree86: xc/lib/Xaw/Changelog,v 3.32 1999/08/28 09:00:26 dawes Exp $
diff --git a/src/Actions.c b/src/Actions.c
new file mode 100644
index 0000000..8e51063
--- /dev/null
+++ b/src/Actions.c
@@ -0,0 +1,1132 @@
+/*
+ * Copyright (c) 1998 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.
+ */
+
+/* $XFree86: xc/lib/Xaw/Actions.c,v 3.16 2001/10/30 04:56:38 paulo Exp $ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <X11/Xmd.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/CoreP.h>
+#include <X11/Constraint.h>
+#include <X11/Xmu/CharSet.h>
+#include <X11/Xmu/SysUtil.h>
+#include <X11/Xfuncs.h>
+#include "Private.h"
+
+#ifndef OLDXAW
+
+/*
+ * Definitions
+ */
+#define ERROR -2
+#define END -1
+#define BOOLEAN 0
+#define AND '&'
+#define OR '|'
+#define XOR '^'
+#define NOT '~'
+#define LP '('
+#define RP ')'
+
+/*
+ * Types
+ */
+/* boolean expressions */
+typedef struct _XawEvalInfo {
+ Widget widget;
+ XawActionResList *rlist;
+ XawActionVarList *vlist;
+ XawParseBooleanProc parse_proc;
+ XEvent *event;
+ char *cp, *lp;
+ int token;
+ Bool value;
+} XawEvalInfo;
+
+/* resources */
+typedef struct _XawActionRes {
+ XrmQuark qname;
+ XrmQuark qtype;
+ Cardinal size;
+} XawActionRes;
+
+struct _XawActionResList {
+ WidgetClass widget_class;
+ XawActionRes **resources;
+ Cardinal num_common_resources;
+ Cardinal num_constraint_resources;
+};
+
+/* variables */
+typedef struct _XawActionVar {
+ XrmQuark qname;
+ XrmQuark qvalue;
+} XawActionVar;
+
+struct _XawActionVarList {
+ Widget widget;
+ Cardinal num_variables;
+ XawActionVar **variables;
+};
+
+/*
+ * Private methods
+ */
+/* expressions */
+static int get_token(XawEvalInfo*);
+static Bool expr(XawEvalInfo*);
+static Bool and(XawEvalInfo*);
+static Bool prim(XawEvalInfo*);
+
+/* resources */
+static String XawConvertActionRes(XawActionResList*, Widget w, String);
+
+static String _XawEscapeActionVarValue(String);
+static String _XawUnescapeActionVarValue(String);
+static XawActionResList *_XawCreateActionResList(WidgetClass);
+static XawActionResList *_XawFindActionResList(WidgetClass);
+static void _XawBindActionResList(XawActionResList*);
+static XawActionRes *_XawFindActionRes(XawActionResList*, Widget, String);
+static int qcmp_action_resource_list(_Xconst void*, _Xconst void*);
+static int bcmp_action_resource_list(_Xconst void*, _Xconst void*);
+static int qcmp_action_resource(_Xconst void*, _Xconst void*);
+static int bcmp_action_resource(_Xconst void*, _Xconst void*);
+
+/* variables */
+static String XawConvertActionVar(XawActionVarList*, String);
+static void XawDeclareActionVar(XawActionVarList*, String, String);
+
+static XawActionVarList *_XawCreateActionVarList(Widget);
+static XawActionVarList *_XawFindActionVarList(Widget);
+static XawActionVar *_XawCreateActionVar(XawActionVarList*, String);
+static XawActionVar *_XawFindActionVar(XawActionVarList*, String);
+static void _XawDestroyActionVarList(Widget, XtPointer, XtPointer);
+
+/*
+ * Initialization
+ */
+/* resources */
+static XawActionResList **resource_list;
+static Cardinal num_resource_list;
+
+/* variables */
+static XawActionVarList **variable_list;
+static Cardinal num_variable_list;
+
+/*
+ * Implementation
+ */
+/*
+ * Start of Boolean Expression Evaluation Implementation Code
+ */
+Bool
+XawParseBoolean(Widget w, String param, XEvent *event, Bool *succed)
+{
+ char *tmp = param;
+ int value;
+
+ if (!param)
+ return (False);
+
+ value = (int)strtod(param, &tmp);
+ if (*tmp == '\0')
+ return (value);
+
+ if (XmuCompareISOLatin1(param, "true") == 0
+ || XmuCompareISOLatin1(param, "yes") == 0
+ || XmuCompareISOLatin1(param, "on") == 0
+ || XmuCompareISOLatin1(param, "in") == 0
+ || XmuCompareISOLatin1(param, "up") == 0)
+ return (True);
+ else if (XmuCompareISOLatin1(param, "false") == 0
+ || XmuCompareISOLatin1(param, "no") == 0
+ || XmuCompareISOLatin1(param, "off") == 0
+ || XmuCompareISOLatin1(param, "out") == 0
+ || XmuCompareISOLatin1(param, "down") == 0)
+ ;
+ else if (XmuCompareISOLatin1(param, "my") == 0
+ || XmuCompareISOLatin1(param, "mine") == 0)
+ return (event->xany.window == XtWindow(w));
+ else if (XmuCompareISOLatin1(param, "faked") == 0)
+ return (event->xany.send_event != 0);
+ else
+ *succed = False;
+
+ return (False);
+}
+
+Bool
+XawBooleanExpression(Widget w, String param, XEvent *event)
+{
+ XawEvalInfo info;
+ Bool retval;
+
+ if (!param)
+ return (False);
+
+ info.widget = w;
+
+ info.rlist = XawGetActionResList(XtClass(w));
+ info.vlist = XawGetActionVarList(w);
+
+ /*
+ * Verify widget class, in case we will allow the parse proc procedure
+ * as a widget class element, or if we allow overriding the default
+ * parse boolean proc.
+ */
+ info.parse_proc = XawParseBoolean;
+
+ info.event = event;
+ info.cp = info.lp = param;
+
+#ifdef DIAGNOSTIC
+ fprintf(stderr, "(*) Parsing expression \"%s\"\n", param);
+#endif
+
+ (void)get_token(&info);
+ if (info.token == ERROR)
+ return (False);
+ retval = expr(&info);
+
+ return (info.token != ERROR ? retval : False);
+}
+
+static int
+get_token(XawEvalInfo *info)
+{
+ int ch;
+ char *p, name[256];
+
+ info->lp = info->cp;
+
+ /*COSTCOND*/
+ while (1) /* eat white spaces */
+ {
+ ch = *info->cp++;
+ if (isspace(ch))
+ continue;
+ break;
+ }
+
+ switch (ch)
+ {
+ case AND: case OR: case XOR: case NOT: case LP: case RP:
+ return (info->token = ch);
+ }
+
+ /* It's a symbol name, resolve it. */
+ if (ch == XAW_PRIV_VAR_PREFIX || isalnum(ch) || ch == '_' || ch == '\\')
+ {
+ Bool succed = True;
+
+ p = info->cp - 1;
+
+ while ((ch = *info->cp) && (isalnum(ch) || ch == '_'))
+ ++info->cp;
+
+ strncpy(name, p, XawMin((int)sizeof(name) - 1,
+ (unsigned)(info->cp - p)));
+ name[XawMin((int)sizeof(name) -1, info->cp - p)] = '\0';
+
+ if (name[0] == XAW_PRIV_VAR_PREFIX)
+ {
+ String value = XawConvertActionVar(info->vlist, name);
+
+ info->value = info->parse_proc(info->widget, value, info->event,
+ &succed) & 1;
+ }
+ else
+ {
+ info->value = info->parse_proc(info->widget, name, info->event,
+ &succed) & 1;
+ if (!succed)
+ {
+ String value =
+ XawConvertActionRes(info->rlist, info->widget,
+ name[0] == '\\' ? &name[1] : name);
+ /* '\\' may have been used to escape a resource name.
+ */
+
+ succed = True;
+ info->value = info->parse_proc(info->widget, value, info->event,
+ &succed) & 1;
+ if (!succed)
+ {
+ /* not a numeric value or boolean string */
+ info->value = True;
+ succed = True;
+ }
+ }
+ }
+ if (succed)
+ return (info->token = BOOLEAN);
+ }
+ else if (ch == '\0')
+ return (info->token = END);
+
+ {
+ char msg[256];
+
+ XmuSnprintf(msg, sizeof(msg),
+ "evaluate(): bad token \"%c\" at \"%s\"", ch, info->cp - 1);
+
+ XtAppWarning(XtWidgetToApplicationContext(info->widget), msg);
+ }
+
+ return (info->token = ERROR);
+}
+
+static Bool
+expr(XawEvalInfo *info)
+{
+ Bool left = and(info);
+
+ for (;;)
+ switch (info->token)
+ {
+ case OR:
+ (void)get_token(info);
+ left |= and(info);
+ break;
+ case XOR:
+ (void)get_token(info);
+ left ^= and(info);
+ break;
+ default:
+ return (left);
+ }
+ /* NOTREACHED */
+}
+
+static Bool
+and(XawEvalInfo *info)
+{
+ Bool left = prim(info);
+
+ for (;;)
+ switch (info->token)
+ {
+ case AND:
+ (void)get_token(info);
+ left &= prim(info);
+ break;
+ default:
+ return (left);
+ }
+ /* NOTREACHED */
+}
+
+static Bool
+prim(XawEvalInfo *info)
+{
+ Bool e;
+
+ switch (info->token)
+ {
+ case BOOLEAN:
+ e = info->value;
+ (void)get_token(info);
+ return (e);
+ case NOT:
+ (void)get_token(info);
+ return (!prim(info));
+ case LP:
+ (void)get_token(info);
+ e = expr(info);
+ if (info->token != RP)
+ {
+ char msg[256];
+
+ info->token = ERROR;
+ XmuSnprintf(msg, sizeof(msg),
+ "evaluate(): expecting ), at \"%s\"", info->lp);
+ XtAppWarning(XtWidgetToApplicationContext(info->widget), msg);
+ return (False);
+ }
+ (void)get_token(info);
+ return (e);
+ case END:
+ return (True);
+ default:
+ {
+ char msg[256];
+
+ info->token = ERROR;
+ XmuSnprintf(msg, sizeof(msg),
+ "evaluate(): sintax error, at \"%s\"", info->lp);
+ XtAppWarning(XtWidgetToApplicationContext(info->widget), msg);
+ } return (False);
+ }
+ /* NOTREACHED */
+}
+
+/*
+ * Start of Resources Implementation Code
+ */
+void
+XawSetValuesAction(Widget w, XEvent *event,
+ String *params, Cardinal *num_params)
+{
+ Arg *arglist;
+ Cardinal num_args, count;
+ XawActionResList *rlist;
+ XawActionVarList *vlist;
+ XawActionRes *resource;
+ XrmValue from, to;
+ String value;
+ char c_1;
+ short c_2;
+ int c_4;
+#ifdef LONG64
+ long c_8;
+#endif
+
+ if (!(*num_params & 1))
+ {
+ XawPrintActionErrorMsg("set-values", w, params, num_params);
+ return;
+ }
+
+ if (!XawBooleanExpression(w, params[0], event))
+ return;
+
+ rlist = XawGetActionResList(XtClass(w));
+ vlist = XawGetActionVarList(w);
+
+ num_args = 0;
+ arglist = (Arg *)XtMalloc(sizeof(Arg) * ((*num_params) >> 1));
+
+ for (count = 1; count < *num_params; count += 2)
+ {
+ if ((resource = _XawFindActionRes(rlist, w, params[count])) == NULL)
+ {
+ char msg[256];
+
+ XmuSnprintf(msg, sizeof(msg),
+ "set-values(): bad resource name \"%s\"",
+ params[count]);
+ XtAppWarning(XtWidgetToApplicationContext(w), msg);
+ continue;
+ }
+ value = XawConvertActionVar(vlist, params[count + 1]);
+ from.size = strlen(value) + 1;
+ from.addr = value;
+ to.size = resource->size;
+ switch (to.size)
+ {
+ case 1: to.addr = (XPointer)&c_1; break;
+ case 2: to.addr = (XPointer)&c_2; break;
+ case 4: to.addr = (XPointer)&c_4; break;
+#ifdef LONG64
+ case 8: to.addr = (XPointer)&c_8; break;
+#endif
+ default:
+ {
+ char msg[256];
+
+ XmuSnprintf(msg, sizeof(msg),
+ "set-values(): bad resource size for \"%s\"",
+ params[count]);
+ XtAppWarning(XtWidgetToApplicationContext(w), msg);
+ } continue;
+ }
+
+ if (strcmp(XtRString, XrmQuarkToString(resource->qtype)) == 0)
+#ifdef LONG64
+ c_8 = (long)from.addr;
+#else
+ c_4 = (int)from.addr;
+#endif
+ else if (!XtConvertAndStore(w, XtRString, &from,
+ XrmQuarkToString(resource->qtype), &to))
+ continue;
+
+ switch (to.size)
+ {
+ case 1:
+ XtSetArg(arglist[num_args], XrmQuarkToString(resource->qname), c_1);
+ break;
+ case 2:
+ XtSetArg(arglist[num_args], XrmQuarkToString(resource->qname), c_2);
+ break;
+ case 4:
+ XtSetArg(arglist[num_args], XrmQuarkToString(resource->qname), c_4);
+ break;
+#ifdef LONG64
+ case 8:
+ XtSetArg(arglist[num_args], XrmQuarkToString(resource->qname), c_8);
+ break;
+#endif
+ }
+ ++num_args;
+ }
+
+ XtSetValues(w, arglist, num_args);
+ XtFree((char *)arglist);
+}
+
+void
+XawGetValuesAction(Widget w, XEvent *event,
+ String *params, Cardinal *num_params)
+{
+ XawActionResList *rlist;
+ XawActionVarList *vlist;
+ String value;
+ Cardinal count;
+
+ if (!(*num_params & 1))
+ {
+ XawPrintActionErrorMsg("get-values", w, params, num_params);
+ return;
+ }
+ if (!XawBooleanExpression(w, params[0], event))
+ return;
+
+ rlist = XawGetActionResList(XtClass(w));
+ vlist = XawGetActionVarList(w);
+
+ for (count = 1; count < *num_params; count += 2)
+ {
+ if ((value = XawConvertActionRes(rlist, w, params[count + 1])) == NULL)
+ continue;
+ XawDeclareActionVar(vlist, params[count], value);
+ }
+}
+
+void
+XawDeclareAction(Widget w, XEvent *event,
+ String *params, Cardinal *num_params)
+{
+ XawActionVarList *vlist;
+ Cardinal count;
+
+ if (!(*num_params & 1))
+ {
+ XawPrintActionErrorMsg("declare", w, params, num_params);
+ return;
+ }
+ if (!XawBooleanExpression(w, params[0], event))
+ return;
+
+ vlist = XawGetActionVarList(w);
+
+ for (count = 1; count < *num_params; count += 2)
+ XawDeclareActionVar(vlist, params[count], params[count + 1]);
+}
+
+void
+XawCallProcAction(Widget w, XEvent *event,
+ String *params, Cardinal *num_params)
+{
+ String *args;
+ Cardinal num_args;
+
+ if (*num_params < 2)
+ {
+ XawPrintActionErrorMsg("call-proc", w, params, num_params);
+ return;
+ }
+
+ if (*num_params && !XawBooleanExpression(w, params[0], event))
+ return;
+
+ if (*num_params > 2)
+ {
+ args = &params[2];
+ num_args = *num_params - 2;
+ }
+ else
+ {
+ args = NULL;
+ num_args = 0;
+ }
+
+ XtCallActionProc(w, params[1], event, args, num_args);
+}
+
+static String
+XawConvertActionRes(XawActionResList *list, Widget w, String name)
+{
+ XawActionRes *resource;
+ XrmValue from, to;
+ Arg arg;
+ char c_1;
+ short c_2;
+ int c_4;
+#ifdef LONG64
+ long c_8;
+#endif
+
+ if ((resource = _XawFindActionRes(list, w, name)) == NULL)
+ {
+ char msg[256];
+
+ XmuSnprintf(msg, sizeof(msg),
+ "convert(): bad resource name \"%s\"", name);
+ XtAppWarning(XtWidgetToApplicationContext(w), msg);
+ return (NULL);
+ }
+
+ from.size = resource->size;
+ switch (from.size)
+ {
+ case 1:
+ XtSetArg(arg, XrmQuarkToString(resource->qname),
+ from.addr = (XPointer)&c_1);
+ break;
+ case 2:
+ XtSetArg(arg, XrmQuarkToString(resource->qname),
+ from.addr = (XPointer)&c_2);
+ break;
+ case 4:
+ XtSetArg(arg, XrmQuarkToString(resource->qname),
+ from.addr = (XPointer)&c_4);
+ break;
+#ifdef LONG64
+ case 8:
+ XtSetArg(arg, XrmQuarkToString(resource->qname),
+ from.addr = (XPointer)&c_8);
+ break;
+#endif
+ default:
+ {
+ char msg[256];
+
+ XmuSnprintf(msg, sizeof(msg),
+ "convert(): bad resource size for \"%s\"", name);
+ XtAppWarning(XtWidgetToApplicationContext(w), name);
+ } return (NULL);
+ }
+
+ XtGetValues(w, &arg, 1);
+ to.size = sizeof(String);
+ to.addr = NULL;
+
+ if (strcmp(XtRString, XrmQuarkToString(resource->qtype)) == 0)
+ to.addr = *(char **)from.addr;
+ else if (!XtConvertAndStore(w, XrmQuarkToString(resource->qtype),
+ &from, XtRString, &to))
+ return (NULL);
+
+ return ((String)to.addr);
+}
+
+void
+XawPrintActionErrorMsg(String action_name, Widget w,
+ String *params, Cardinal *num_params)
+{
+ char msg[1024];
+ unsigned int size, idx;
+
+ size = XmuSnprintf(msg, sizeof(msg), "%s(): bad number of parameters.\n\t(",
+ action_name, action_name);
+
+ idx = 0;
+ while (idx < *num_params - 1 && size < sizeof(msg))
+ size += XmuSnprintf(&msg[size], sizeof(msg) - size, "%s, ",
+ params[idx++]);
+ if (*num_params)
+ XmuSnprintf(&msg[size], sizeof(msg) - size, "%s)", params[idx]);
+ else
+ XmuSnprintf(&msg[size], sizeof(msg) - size, ")");
+ XtAppWarning(XtWidgetToApplicationContext(w), msg);
+}
+
+XawActionResList *
+XawGetActionResList(WidgetClass wc)
+{
+ XawActionResList *list;
+
+ list = _XawFindActionResList(wc);
+
+ if (!list)
+ list = _XawCreateActionResList(wc);
+
+ return (list);
+}
+
+static int
+qcmp_action_resource_list(register _Xconst void *left,
+ register _Xconst void *right)
+{
+ return ((char *)((*(XawActionResList **)left)->widget_class) -
+ (char *)((*(XawActionResList **)right)->widget_class));
+}
+
+static XawActionResList *
+_XawCreateActionResList(WidgetClass wc)
+{
+ XawActionResList *list;
+
+ list = (XawActionResList *)XtMalloc(sizeof(XawActionResList));
+ list->widget_class = wc;
+ list->num_common_resources = list->num_constraint_resources = 0;
+ list->resources = NULL;
+
+ if (!resource_list)
+ {
+ num_resource_list = 1;
+ resource_list = (XawActionResList **)XtMalloc(sizeof(XawActionResList*));
+ resource_list[0] = list;
+ }
+ else
+ {
+ ++num_resource_list;
+ resource_list = (XawActionResList **)XtRealloc((char *)resource_list,
+ sizeof(XawActionResList*)
+ * num_resource_list);
+ resource_list[num_resource_list - 1] = list;
+ qsort(resource_list, num_resource_list, sizeof(XawActionResList*),
+ qcmp_action_resource_list);
+ }
+
+ _XawBindActionResList(list);
+
+ return (list);
+}
+
+static int
+bcmp_action_resource_list(register _Xconst void *wc,
+ register _Xconst void *list)
+{
+ return ((char *)wc - (char *)((*(XawActionResList **)list)->widget_class));
+}
+
+static XawActionResList *
+_XawFindActionResList(WidgetClass wc)
+{
+ XawActionResList **list;
+
+ if (!resource_list)
+ return (NULL);
+
+ list = (XawActionResList **)bsearch(wc, resource_list,
+ num_resource_list,
+ sizeof(XawActionResList*),
+ bcmp_action_resource_list);
+
+ return (list ? *list : NULL);
+}
+
+static int
+qcmp_action_resource(register _Xconst void *left,
+ register _Xconst void *right)
+{
+ return (strcmp(XrmQuarkToString((*(XawActionRes **)left)->qname),
+ XrmQuarkToString((*(XawActionRes **)right)->qname)));
+}
+
+static void
+_XawBindActionResList(XawActionResList *list)
+{
+ XtResourceList xt_list, cons_list;
+ Cardinal i, num_xt, num_cons;
+
+#ifdef DIAGNOSTIC
+ fprintf(stderr, "(*) Creating resource list for class \'%s\'\n---------\n",
+ list->widget_class->core_class.class_name);
+#endif
+
+ XtGetResourceList(list->widget_class, &xt_list, &num_xt);
+ XtGetConstraintResourceList(list->widget_class, &cons_list, &num_cons);
+ list->num_common_resources = num_xt;
+ list->num_constraint_resources = num_cons;
+
+ list->resources = (XawActionRes **)
+ XtMalloc(sizeof(XawActionRes*) * (num_xt + num_cons));
+
+#ifdef DIAGNOSTIC
+ fprintf(stderr, "Common resources\n---\n");
+#endif
+
+ for (i = 0; i < num_xt; i++)
+ {
+ list->resources[i] = (XawActionRes *)XtMalloc(sizeof(XawActionRes));
+ list->resources[i]->qname =
+ XrmPermStringToQuark(xt_list[i].resource_name);
+ list->resources[i]->qtype =
+ XrmPermStringToQuark(xt_list[i].resource_type);
+ list->resources[i]->size = xt_list[i].resource_size;
+
+#ifdef DIAGNOSTIC
+ fprintf(stderr, "%-20s\t%-20s\t(%d)\n",
+ xt_list[i].resource_name,
+ xt_list[i].resource_type,
+ xt_list[i].resource_size);
+#endif
+ }
+
+#ifdef DIAGNOSTIC
+ fprintf(stderr, "---\nContraint resources\n---");
+#endif
+
+ for (; i < num_xt + num_cons; i++)
+ {
+ list->resources[i] = (XawActionRes *)XtMalloc(sizeof(XawActionRes));
+ list->resources[i]->qname =
+ XrmPermStringToQuark(cons_list[i - num_xt].resource_name);
+ list->resources[i]->qtype =
+ XrmPermStringToQuark(cons_list[i - num_xt].resource_type);
+ list->resources[i]->size = cons_list[i - num_xt].resource_size;
+
+#ifdef DIAGNOSTIC
+ fprintf(stderr, "%-20s\t%-20s\t(%d)\n",
+ cons_list[i - num_xt].resource_name,
+ cons_list[i - num_xt].resource_type,
+ cons_list[i - num_xt].resource_size);
+#endif
+ }
+
+#ifdef DIAGNOSTIC
+ fprintf(stderr, "---\n");
+#endif
+
+ XtFree((char *)xt_list);
+ if (cons_list)
+ XtFree((char *)cons_list);
+
+ qsort(list->resources, list->num_common_resources, sizeof(XawActionRes*),
+ qcmp_action_resource);
+ if (num_cons)
+ qsort(&list->resources[num_xt], list->num_constraint_resources,
+ sizeof(XawActionRes*), qcmp_action_resource);
+}
+
+static int
+bcmp_action_resource(register _Xconst void *string,
+ register _Xconst void *resource)
+{
+ return (strcmp((String)string,
+ XrmQuarkToString((*(XawActionRes **)resource)->qname)));
+}
+
+static XawActionRes *
+_XawFindActionRes(XawActionResList *list, Widget detail, String name)
+{
+ XawActionRes **res;
+
+ if (!list->resources)
+ return (NULL);
+
+ res = (XawActionRes **)bsearch(name, list->resources,
+ list->num_common_resources,
+ sizeof(XawActionRes*), bcmp_action_resource);
+
+ if (!res && XtParent(detail)
+ && XtIsSubclass(XtParent(detail), constraintWidgetClass))
+ {
+ XawActionResList *cons = XawGetActionResList(XtClass(XtParent(detail)));
+
+ if (cons)
+ res = (XawActionRes **)
+ bsearch(name, &cons->resources[cons->num_common_resources],
+ cons->num_constraint_resources,
+ sizeof(XawActionRes*), bcmp_action_resource);
+ }
+
+ return (res ? *res : NULL);
+}
+
+/*
+ * Start of Variables Implementation Code
+ */
+/* For speed, only does memory allocation when really required */
+static String
+_XawEscapeActionVarValue(String value)
+{
+ String escape;
+
+ if (value[0] == '$' || value[0] == '\\')
+ {
+ escape = XtMalloc(strlen(value) + 2);
+ escape[0] = '\\';
+ strcpy(escape + 1, value);
+ return (escape);
+ }
+ return (NULL);
+}
+
+/* For speed, only does memory allocation when really required */
+static String
+_XawUnescapeActionVarValue(String value)
+{
+ String unescape;
+
+ if (value[0] == '\\')
+ {
+ unescape = XtMalloc(strlen(value));
+ strcpy(unescape, value + 1);
+ return (unescape);
+ }
+ return (NULL);
+}
+
+static void
+XawDeclareActionVar(XawActionVarList *list, String name, String value)
+{
+ XawActionVar *variable;
+ String escape = NULL;
+
+ if (name[0] != XAW_PRIV_VAR_PREFIX)
+ {
+ char msg[256];
+
+ XmuSnprintf(msg, sizeof(msg), "declare(): variable name must begin with "
+ "\'%c\', at %s = %s", XAW_PRIV_VAR_PREFIX, name, value);
+ XtAppWarning(XtWidgetToApplicationContext(list->widget), msg);
+ return;
+ }
+ variable = _XawFindActionVar(list, name);
+ if (!variable)
+ variable = _XawCreateActionVar(list, name);
+ if (value)
+ escape = _XawEscapeActionVarValue(value);
+
+ if (variable->qvalue)
+ {
+ String val = escape ? escape : value;
+
+ if (strcmp(XrmQuarkToString(variable->qvalue), val) == 0)
+ {
+ if (escape)
+ XtFree(escape);
+ return;
+ }
+ }
+ variable->qvalue = (escape ? XrmStringToQuark(escape) :
+ (value ? XrmStringToQuark(value) : NULLQUARK));
+ if (escape)
+ XtFree(escape);
+}
+
+static String
+XawConvertActionVar(XawActionVarList *list, String name)
+{
+ XawActionVar *variable;
+ String unescape;
+ XrmQuark quark;
+
+ if (name[0] != XAW_PRIV_VAR_PREFIX)
+ return (name);
+
+ variable = _XawFindActionVar(list, name);
+ if (!variable || variable->qvalue == NULLQUARK)
+ return (name);
+ unescape = _XawUnescapeActionVarValue(XrmQuarkToString(variable->qvalue));
+ if (unescape)
+ {
+ quark = XrmStringToQuark(unescape);
+ XtFree(unescape);
+ }
+ else
+ quark = variable->qvalue;
+
+ return (XrmQuarkToString(quark));
+}
+
+XawActionVarList *
+XawGetActionVarList(Widget w)
+{
+ XawActionVarList *list;
+
+ list = _XawFindActionVarList(w);
+ if (!list)
+ list = _XawCreateActionVarList(w);
+
+ return (list);
+}
+
+static int
+qcmp_action_variable_list(register _Xconst void *left,
+ register _Xconst void *right)
+{
+ return ((char *)((*(XawActionVarList **)left)->widget) -
+ (char *)((*(XawActionVarList **)right)->widget));
+}
+
+static XawActionVarList *
+_XawCreateActionVarList(Widget w)
+{
+ XawActionVarList *list;
+
+#ifdef DIAGNOSTIC
+ fprintf(stderr, "(*) Creating action variable list for widget %s (%p)\n",
+ XtName(w), w);
+#endif
+
+ list = (XawActionVarList *)XtMalloc(sizeof(XawActionVarList));
+ list->widget = w;
+ list->num_variables = 0;
+ list->variables = NULL;
+
+ if (!variable_list)
+ {
+ num_variable_list = 1;
+ variable_list = (XawActionVarList **)XtMalloc(sizeof(XawActionVarList*));
+ variable_list[0] = list;
+ }
+ else
+ {
+ ++num_variable_list;
+ variable_list = (XawActionVarList **)
+ XtRealloc((char *)variable_list,
+ sizeof(XawActionVarList *) * num_variable_list);
+ variable_list[num_variable_list - 1] = list;
+ qsort(variable_list, num_variable_list, sizeof(XawActionVarList*),
+ qcmp_action_variable_list);
+ }
+
+ XtAddCallback(w, XtNdestroyCallback, _XawDestroyActionVarList,
+ (XtPointer)list);
+
+ return (list);
+}
+
+static int
+bcmp_action_variable_list(register _Xconst void *widget,
+ register _Xconst void *list)
+{
+ return ((char *)widget - (char *)((*(XawActionVarList **)list)->widget));
+}
+
+static XawActionVarList *
+_XawFindActionVarList(Widget w)
+{
+ XawActionVarList **list;
+
+ if (!num_variable_list)
+ return (NULL);
+
+ list = (XawActionVarList **)bsearch(w, variable_list, num_variable_list,
+ sizeof(XawActionVarList*),
+ bcmp_action_variable_list);
+
+ return (list ? *list : NULL);
+}
+
+static int
+qcmp_action_variable(register _Xconst void *left,
+ register _Xconst void *right)
+{
+ return (strcmp(XrmQuarkToString((*(XawActionVar **)left)->qname),
+ XrmQuarkToString((*(XawActionVar **)right)->qname)));
+}
+
+static XawActionVar *
+_XawCreateActionVar(XawActionVarList *list, String name)
+{
+ XawActionVar *variable;
+
+#ifdef DIAGNOSTIC
+ fprintf(stderr, "(*) Creating action variable '%s' for widget %s (%p)\n",
+ name, XtName(list->widget), list->widget);
+#endif
+
+ variable = (XawActionVar *)XtMalloc(sizeof(XawActionVar));
+ variable->qname = XrmStringToQuark(name);
+ variable->qvalue = NULLQUARK;
+
+ if (!list->variables)
+ {
+ list->num_variables = 1;
+ list->variables = (XawActionVar **)XtMalloc(sizeof(XawActionVar*));
+ list->variables[0] = variable;
+ }
+ else
+ {
+ ++list->num_variables;
+ list->variables = (XawActionVar **)XtRealloc((char *)list->variables,
+ sizeof(XawActionVar *) *
+ list->num_variables);
+ list->variables[list->num_variables - 1] = variable;
+ qsort(list->variables, list->num_variables, sizeof(XawActionVar*),
+ qcmp_action_variable);
+ }
+ return (variable);
+}
+
+static int
+bcmp_action_variable(register _Xconst void *string,
+ register _Xconst void *variable)
+{
+ return (strcmp((String)string,
+ XrmQuarkToString((*(XawActionVar **)variable)->qname)));
+}
+
+static XawActionVar *
+_XawFindActionVar(XawActionVarList *list, String name)
+{
+ XawActionVar **var;
+
+ if (!list->variables)
+ return (NULL);
+
+ var = (XawActionVar **)bsearch(name, list->variables, list->num_variables,
+ sizeof(XawActionVar*), bcmp_action_variable);
+
+ return (var ? *var : NULL);
+}
+
+/*ARGSUSED*/
+static void
+_XawDestroyActionVarList(Widget w, XtPointer client_data, XtPointer call_data)
+{
+ XawActionVarList *list = (XawActionVarList *)client_data;
+ Cardinal i;
+
+ for (i = 0; i < num_variable_list; i++)
+ if (variable_list[i] == list)
+ break;
+ if (i >= num_variable_list || list->widget != w
+ || variable_list[i]->widget != w)
+ {
+ XtWarning("destroy-variable-list(): Bad widget argument.");
+ return;
+ }
+ if (--num_variable_list > 0)
+ {
+ memmove(&variable_list[i], &variable_list[i + 1],
+ (num_variable_list - i) * sizeof(XawActionVarList *));
+ variable_list = (XawActionVarList **)
+ XtRealloc((char *)variable_list, sizeof(XawActionVarList *) *
+ num_variable_list);
+ }
+ else
+ {
+ XtFree((char *)variable_list);
+ variable_list = NULL;
+ }
+
+ XtFree((char *)list->variables);
+ XtFree((char *)list);
+}
+
+#endif /* OLDXAW */
diff --git a/src/Converters.c b/src/Converters.c
new file mode 100644
index 0000000..99ea5aa
--- /dev/null
+++ b/src/Converters.c
@@ -0,0 +1,698 @@
+/*
+ * Copyright (c) 1998 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.
+ */
+
+/* $XFree86: xc/lib/Xaw/Converters.c,v 3.14 1999/06/20 08:40:59 dawes Exp $ */
+
+#include <stdio.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xmu/CharSet.h>
+#include <X11/Xmu/SysUtil.h>
+#include <X11/Xaw/Simple.h>
+#include <X11/Xaw/XawInit.h>
+#include "Private.h"
+
+#ifndef OLDXAW
+
+/*
+ * Definitions
+ */
+#define done(type, value) \
+{ \
+ if (toVal->addr != NULL) \
+ { \
+ if (toVal->size < sizeof(type)) \
+ { \
+ toVal->size = sizeof(type); \
+ return (False); \
+ } \
+ *(type *)(toVal->addr) = (value); \
+ } \
+ else \
+ { \
+ static type static_val; \
+ \
+ static_val = (value); \
+ toVal->addr = (XPointer)&static_val; \
+ } \
+ toVal->size = sizeof(type); \
+ return (True); \
+}
+
+#define string_done(value) \
+{ \
+ if (toVal->addr != NULL) \
+ { \
+ if (toVal->size < size) \
+ { \
+ toVal->size = size; \
+ return (False); \
+ } \
+ strcpy((char *)toVal->addr, (value)); \
+ } \
+ else \
+ toVal->addr = (XPointer)(value); \
+ toVal->size = size; \
+ return (True); \
+}
+
+/*
+ * Prototypes
+ */
+static Boolean _XawCvtAtomToString(Display*, XrmValue*, Cardinal*,
+ XrmValue*, XrmValue*, XtPointer*);
+static Boolean _XawCvtBooleanToString(Display*, XrmValue*, Cardinal*,
+ XrmValue*, XrmValue*, XtPointer*);
+static Boolean _XawCvtBoolToString(Display*, XrmValue*, Cardinal*,
+ XrmValue*, XrmValue*, XtPointer*);
+static Boolean _XawCvtCARD32ToString(Display*, XrmValue*, Cardinal*,
+ XrmValue*, XrmValue*, XtPointer*);
+static Boolean _XawCvtCardinalToString(Display*, XrmValue*, Cardinal*,
+ XrmValue*, XrmValue*, XtPointer*);
+static Boolean _XawCvtDimensionToString(Display*, XrmValue*, Cardinal*,
+ XrmValue*, XrmValue*, XtPointer*);
+static Boolean _XawCvtDisplayListToString(Display*, XrmValue*, Cardinal*,
+ XrmValue*, XrmValue*, XtPointer*);
+static Boolean _XawCvtFontStructToString(Display*, XrmValue*, Cardinal*,
+ XrmValue*, XrmValue*, XtPointer*);
+static Boolean _XawCvtIntToString(Display*, XrmValue*, Cardinal*,
+ XrmValue*, XrmValue*, XtPointer*);
+static Boolean _XawCvtPixelToString(Display*, XrmValue*, Cardinal*,
+ XrmValue*, XrmValue*, XtPointer*);
+static Boolean _XawCvtPixmapToString(Display*, XrmValue*, Cardinal*,
+ XrmValue*, XrmValue*, XtPointer*);
+static Boolean _XawCvtShortToString(Display*, XrmValue*, Cardinal*,
+ XrmValue*, XrmValue*, XtPointer*);
+static Boolean _XawCvtPositionToString(Display*, XrmValue*, Cardinal*,
+ XrmValue*, XrmValue*, XtPointer*);
+static Boolean _XawCvtStringToDisplayList(Display*, XrmValue*, Cardinal*,
+ XrmValue*, XrmValue*, XtPointer*);
+static Boolean _XawCvtStringToPixmap(Display*, XrmValue*, Cardinal*,
+ XrmValue*, XrmValue*, XtPointer*);
+static Boolean _XawCvtUnsignedCharToString(Display*, XrmValue*, Cardinal*,
+ XrmValue*, XrmValue*, XtPointer*);
+static void TypeToStringNoArgsWarning(Display*, String);
+
+/*
+ * Initialization
+ */
+static XtConvertArgRec PixelArgs[] = {
+ {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.colormap),
+ sizeof(Colormap)},
+};
+
+static XtConvertArgRec DLArgs[] = {
+ {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.screen),
+ sizeof(Screen *)},
+ {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.colormap),
+ sizeof(Colormap)},
+ {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.depth),
+ sizeof(int)},
+};
+#endif /* OLDXAW */
+
+static String XtCToolkitError = "ToolkitError";
+static String XtNconversionError = "conversionError";
+
+#ifndef OLDXAW
+static String XtNwrongParameters = "wrongParameters";
+
+/*
+ * Implementation
+ */
+void
+XawInitializeDefaultConverters(void)
+{
+ static Boolean first_time = True;
+
+ if (first_time == False)
+ return;
+
+ first_time = False;
+
+ /* Replace with more apropriate converters */
+ XtSetTypeConverter(XtRCallback, XtRString, _XawCvtCARD32ToString,
+ NULL, 0, XtCacheNone, NULL);
+ XtSetTypeConverter(XtRColormap, XtRString, _XawCvtCARD32ToString,
+ NULL, 0, XtCacheNone, NULL);
+ XtSetTypeConverter(XtRFunction, XtRString, _XawCvtCARD32ToString,
+ NULL, 0, XtCacheNone, NULL);
+ XtSetTypeConverter(XtRPointer, XtRString, _XawCvtCARD32ToString,
+ NULL, 0, XtCacheNone, NULL);
+ XtSetTypeConverter(XtRScreen, XtRString, _XawCvtCARD32ToString,
+ NULL, 0, XtCacheNone, NULL);
+ XtSetTypeConverter(XtRStringArray, XtRString, _XawCvtCARD32ToString,
+ NULL, 0, XtCacheNone, NULL);
+ XtSetTypeConverter(XtRVisual, XtRString, _XawCvtCARD32ToString,
+ NULL, 0, XtCacheNone, NULL);
+ XtSetTypeConverter(XtRWidget, XtRString, _XawCvtCARD32ToString,
+ NULL, 0, XtCacheNone, NULL);
+ XtSetTypeConverter(XtRWidgetList, XtRString, _XawCvtCARD32ToString,
+ NULL, 0, XtCacheNone, NULL);
+ XtSetTypeConverter(XtRWindow, XtRString, _XawCvtCARD32ToString,
+ NULL, 0, XtCacheNone, NULL);
+
+ XtSetTypeConverter(XtRAtom, XtRString, _XawCvtAtomToString,
+ NULL, 0, XtCacheNone, NULL);
+ XtSetTypeConverter(XtRBool, XtRString, _XawCvtBoolToString,
+ NULL, 0, XtCacheNone, NULL);
+ XtSetTypeConverter(XtRBoolean, XtRString, _XawCvtBooleanToString,
+ NULL, 0, XtCacheNone, NULL);
+ XtSetTypeConverter(XtRCardinal, XtRString, _XawCvtCardinalToString,
+ NULL, 0, XtCacheNone, NULL);
+ XtSetTypeConverter(XtRDimension, XtRString, _XawCvtDimensionToString,
+ NULL, 0, XtCacheNone, NULL);
+ XtSetTypeConverter(XawRDisplayList, XtRString, _XawCvtDisplayListToString,
+ NULL, 0, XtCacheNone, NULL);
+ XtSetTypeConverter(XtRFontStruct, XtRString, _XawCvtFontStructToString,
+ NULL, 0, XtCacheNone, NULL);
+ XtSetTypeConverter(XtRInt, XtRString, _XawCvtIntToString,
+ NULL, 0, XtCacheNone, NULL);
+ XtSetTypeConverter(XtRPixel, XtRString, _XawCvtPixelToString,
+ &PixelArgs[0], XtNumber(PixelArgs), XtCacheNone, NULL);
+ XtSetTypeConverter(XtRPixmap, XtRString, _XawCvtPixmapToString,
+ &DLArgs[0], XtNumber(DLArgs), XtCacheNone, NULL);
+ XtSetTypeConverter(XtRPosition, XtRString, _XawCvtPositionToString,
+ NULL, 0, XtCacheNone, NULL);
+ XtSetTypeConverter(XtRShort, XtRString, _XawCvtShortToString,
+ NULL, 0, XtCacheNone, NULL);
+ XtSetTypeConverter(XtRString, XawRDisplayList, _XawCvtStringToDisplayList,
+ &DLArgs[0], XtNumber(DLArgs), XtCacheAll, NULL);
+ XtSetTypeConverter(XtRString, XtRPixmap, _XawCvtStringToPixmap,
+ &DLArgs[0], XtNumber(DLArgs), XtCacheAll, NULL);
+ XtSetTypeConverter(XtRUnsignedChar, XtRString, _XawCvtUnsignedCharToString,
+ NULL, 0, XtCacheNone, NULL);
+}
+#endif /* OLDXAW */
+
+void
+XawTypeToStringWarning(Display *dpy, String type)
+{
+ char fname[64];
+ String params[1];
+ Cardinal num_params;
+
+ XmuSnprintf(fname, sizeof(fname), "cvt%sToString", type);
+
+ params[0] = type;
+ num_params = 1;
+ XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
+ XtNconversionError, fname, XtCToolkitError,
+ "Cannot convert %s to String",
+ params, &num_params);
+}
+
+#ifndef OLDXAW
+static void
+TypeToStringNoArgsWarning(Display *dpy, String type)
+{
+ char fname[64];
+ String params[1];
+ Cardinal num_params;
+
+ XmuSnprintf(fname, sizeof(fname), "cvt%sToString", type);
+
+ params[0] = type;
+ num_params = 1;
+ XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
+ XtNconversionError, fname,
+ XtCToolkitError,
+ "%s to String conversion needs no extra arguments",
+ params, &num_params);
+}
+
+/*ARGSUSED*/
+static Boolean
+_XawCvtBooleanToString(Display *dpy, XrmValue *args, Cardinal *num_args,
+ XrmValue *fromVal, XrmValue *toVal,
+ XtPointer *converter_data)
+{
+ static char buffer[6];
+ Cardinal size;
+
+ if (*num_args != 0)
+ TypeToStringNoArgsWarning(dpy, XtRBoolean);
+
+ XmuSnprintf(buffer, sizeof(buffer), "%s",
+ *(Boolean *)fromVal->addr ? XtEtrue : XtEfalse);
+ size = strlen(buffer) + 1;
+
+ string_done(buffer);
+}
+
+/*ARGSUSED*/
+static Boolean
+_XawCvtBoolToString(Display *dpy, XrmValue *args, Cardinal *num_args,
+ XrmValue *fromVal, XrmValue *toVal,
+ XtPointer *converter_data)
+{
+ static char buffer[6];
+ Cardinal size;
+
+ if (*num_args != 0)
+ TypeToStringNoArgsWarning(dpy, XtRBool);
+
+ XmuSnprintf(buffer, sizeof(buffer), "%s",
+ *(Bool *)fromVal->addr ? XtEtrue : XtEfalse);
+ size = strlen(buffer) + 1;
+
+ string_done(buffer);
+}
+
+/*ARGSUSED*/
+static Boolean
+_XawCvtPositionToString(Display *dpy, XrmValue *args, Cardinal *num_args,
+ XrmValue *fromVal, XrmValue *toVal,
+ XtPointer *converter_data)
+{
+ static char buffer[7];
+ Cardinal size;
+
+ if (*num_args != 0)
+ TypeToStringNoArgsWarning(dpy, XtRPosition);
+
+ XmuSnprintf(buffer, sizeof(buffer), "%d", *(Position *)fromVal->addr);
+ size = strlen(buffer) + 1;
+
+ string_done(buffer);
+}
+
+/*ARGSUSED*/
+static Boolean
+_XawCvtShortToString(Display *dpy, XrmValue *args, Cardinal *num_args,
+ XrmValue *fromVal, XrmValue *toVal,
+ XtPointer *converter_data)
+{
+ static char buffer[7];
+ Cardinal size;
+
+ if (*num_args != 0)
+ TypeToStringNoArgsWarning(dpy, XtRShort);
+
+ XmuSnprintf(buffer, sizeof(buffer), "%d", *(short *)fromVal->addr);
+ size = strlen(buffer) + 1;
+
+ string_done(buffer);
+}
+
+/*ARGSUSED*/
+static Boolean
+_XawCvtDimensionToString(Display *dpy, XrmValue *args, Cardinal *num_args,
+ XrmValue *fromVal, XrmValue *toVal,
+ XtPointer *converter_data)
+{
+ static char buffer[6];
+ Cardinal size;
+
+ if (*num_args != 0)
+ TypeToStringNoArgsWarning(dpy, XtRDimension);
+
+ XmuSnprintf(buffer, sizeof(buffer), "%u", *(Dimension *)fromVal->addr);
+ size = strlen(buffer) + 1;
+
+ string_done(buffer);
+}
+
+/*ARGSUSED*/
+static Boolean
+_XawCvtCARD32ToString(Display *dpy, XrmValue *args, Cardinal *num_args,
+ XrmValue *fromVal, XrmValue *toVal,
+ XtPointer *converter_data)
+{
+ static char buffer[11];
+ Cardinal size;
+
+ if (*num_args != 0)
+ TypeToStringNoArgsWarning(dpy, "CARD32");
+
+ XmuSnprintf(buffer, sizeof(buffer), "0x%08hx", *(int *)fromVal->addr);
+ size = strlen(buffer) + 1;
+
+ string_done(buffer);
+}
+
+/*ARGSUSED*/
+static Boolean
+_XawCvtIntToString(Display *dpy, XrmValue *args, Cardinal *num_args,
+ XrmValue *fromVal, XrmValue *toVal,
+ XtPointer *converter_data)
+{
+ static char buffer[12];
+ Cardinal size;
+
+ if (*num_args != 0)
+ TypeToStringNoArgsWarning(dpy, XtRInt);
+
+ XmuSnprintf(buffer, sizeof(buffer), "%d", *(int *)fromVal->addr);
+ size = strlen(buffer) + 1;
+
+ string_done(buffer);
+}
+
+/*ARGSUSED*/
+static Boolean
+_XawCvtCardinalToString(Display *dpy, XrmValue *args, Cardinal *num_args,
+ XrmValue *fromVal, XrmValue *toVal,
+ XtPointer *converter_data)
+{
+ static char buffer[11];
+ Cardinal size;
+
+ if (*num_args != 0)
+ TypeToStringNoArgsWarning(dpy, XtRCardinal);
+
+ XmuSnprintf(buffer, sizeof(buffer), "%u", *(Cardinal *)fromVal->addr);
+ size = strlen(buffer) + 1;
+
+ string_done(buffer);
+}
+
+/*ARGSUSED*/
+static Boolean
+_XawCvtAtomToString(Display *dpy, XrmValue *args, Cardinal *num_args,
+ XrmValue *fromVal, XrmValue *toVal,
+ XtPointer *converter_data)
+{
+ static char *buffer = NULL;
+ static char *nullatom = "NULL";
+ Cardinal size;
+ Atom atom;
+
+ if (*num_args != 0)
+ TypeToStringNoArgsWarning(dpy, XtRAtom);
+
+ if (buffer && buffer != nullatom)
+ XFree(buffer);
+
+ atom = *(Atom *)fromVal[0].addr;
+ if (atom == 0)
+ buffer = nullatom;
+ else if ((buffer = XGetAtomName(dpy, *(Atom *)fromVal[0].addr)) == NULL)
+ {
+ XawTypeToStringWarning(dpy, XtRAtom);
+ toVal->addr = NULL;
+ toVal->size = sizeof(String);
+ return (False);
+ }
+
+ size = strlen(buffer) + 1;
+
+ string_done(buffer);
+}
+
+/*ARGSUSED*/
+static Boolean
+_XawCvtPixelToString(Display *dpy, XrmValue *args, Cardinal *num_args,
+ XrmValue *fromVal, XrmValue *toVal,
+ XtPointer *converter_data)
+{
+ static char buffer[19];
+ Cardinal size;
+ Colormap colormap;
+ XColor color;
+
+ if (*num_args != 1)
+ {
+ XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
+ XtNwrongParameters, "cvtPixelToString",
+ XtCToolkitError,
+ "Pixel to String conversion needs colormap argument",
+ NULL, NULL);
+ return (False);
+ }
+
+ colormap = *(Colormap *)args[0].addr;
+ color.pixel = *(Pixel *)fromVal->addr;
+
+ /* Note:
+ * If we know the visual type, we can calculate the xcolor
+ * without asking Xlib.
+ */
+ XQueryColor(dpy, colormap, &color);
+ XmuSnprintf(buffer, sizeof(buffer), "rgb:%04hx/%04hx/%04hx",
+ color.red, color.green, color.blue);
+ size = strlen(buffer) + 1;
+
+ string_done(buffer);
+}
+
+/*ARGSUSED*/
+static Boolean
+_XawCvtFontStructToString(Display *dpy, XrmValue *args, Cardinal *num_args,
+ XrmValue *fromVal, XrmValue *toVal,
+ XtPointer *converter_data)
+{
+ static char buffer[128];
+ Cardinal size;
+ Atom atom;
+ unsigned long value;
+
+ if (*num_args != 0)
+ TypeToStringNoArgsWarning(dpy, XtRFontStruct);
+
+ if ((atom = XInternAtom(dpy, "FONT", True)) == None)
+ return (False);
+
+ size = 0;
+
+ if (XGetFontProperty(*(XFontStruct **)fromVal->addr, atom, &value))
+ {
+ char *tmp = XGetAtomName(dpy, value);
+
+ if (tmp)
+ {
+ XmuSnprintf(buffer, sizeof(buffer), "%s", tmp);
+ size = strlen(tmp);
+ XFree(tmp);
+ }
+ }
+
+ if (size)
+ {
+ ++size;
+ string_done(buffer);
+ }
+
+ XawTypeToStringWarning(dpy, XtRFontStruct);
+
+ return (False);
+}
+
+/*ARGSUSED*/
+static Boolean
+_XawCvtUnsignedCharToString(Display *dpy, XrmValue *args, Cardinal *num_args,
+ XrmValue *fromVal, XrmValue *toVal,
+ XtPointer *converter_data)
+{
+ static char buffer[4];
+ Cardinal size;
+
+ if (*num_args != 0)
+ TypeToStringNoArgsWarning(dpy, XtRUnsignedChar);
+
+ XmuSnprintf(buffer, sizeof(buffer), "%u",
+ *(unsigned char *)fromVal->addr);
+ size = strlen(buffer) + 1;
+
+ string_done(buffer);
+}
+
+/*ARGSUSED*/
+static Boolean
+_XawCvtStringToDisplayList(Display *dpy, XrmValue *args, Cardinal *num_args,
+ XrmValue *fromVal, XrmValue *toVal,
+ XtPointer *converter_data)
+{
+ XawDisplayList *dlist;
+ Screen *screen;
+ Colormap colormap;
+ int depth;
+ String commands;
+
+ if (*num_args != 3)
+ {
+ XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
+ XtNwrongParameters, "cvtStringToDisplayList",
+ XtCToolkitError,
+ "String to DisplayList conversion needs screen, "
+ "colormap, and depth arguments",
+ NULL, NULL);
+ return (False);
+ }
+
+ screen = *(Screen **)args[0].addr;
+ colormap = *(Colormap *)args[1].addr;
+ depth = *(int *)args[2].addr;
+
+ commands = (String)(fromVal[0].addr);
+
+ dlist = XawCreateDisplayList(commands, screen, colormap, depth);
+
+ if (!dlist)
+ {
+ XtDisplayStringConversionWarning(dpy, (String)fromVal->addr,
+ XawRDisplayList);
+ toVal->addr = NULL;
+ toVal->size = sizeof(XawDisplayList*);
+ return (False);
+ }
+
+ done(XawDisplayList*, dlist);
+}
+
+/*ARGSUSED*/
+static Boolean
+_XawCvtDisplayListToString(Display *dpy, XrmValue *args, Cardinal *num_args,
+ XrmValue *fromVal, XrmValue *toVal,
+ XtPointer *converter_data)
+{
+ String buffer;
+ Cardinal size;
+
+ if (*num_args != 0)
+ TypeToStringNoArgsWarning(dpy, XawRDisplayList);
+
+ buffer = XawDisplayListString(*(XawDisplayList **)(fromVal[0].addr));
+ size = strlen(buffer) + 1;
+
+ string_done(buffer);
+}
+
+/*ARGSUSED*/
+static Boolean
+_XawCvtStringToPixmap(Display *dpy, XrmValue *args, Cardinal *num_args,
+ XrmValue *fromVal, XrmValue *toVal,
+ XtPointer *converter_data)
+{
+ XawPixmap *xaw_pixmap;
+ Pixmap pixmap;
+ Screen *screen;
+ Colormap colormap;
+ int depth;
+ String name;
+
+ if (*num_args != 3)
+ {
+ XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
+ XtNwrongParameters, "cvtStringToPixmap",
+ XtCToolkitError,
+ "String to Pixmap conversion needs screen, "
+ "colormap, and depth arguments",
+ NULL, NULL);
+ return (False);
+ }
+
+ screen = *(Screen **)args[0].addr;
+ colormap = *(Colormap *)args[1].addr;
+ depth = *(int *)args[2].addr;
+
+ name = (String)(fromVal[0].addr);
+
+ if (XmuCompareISOLatin1(name, "None") == 0)
+ pixmap = None;
+ else if (XmuCompareISOLatin1(name, "ParentRelative") == 0)
+ pixmap = ParentRelative;
+ else if (XmuCompareISOLatin1(name, "XtUnspecifiedPixmap") == 0)
+ pixmap = XtUnspecifiedPixmap;
+ else
+ {
+ xaw_pixmap = XawLoadPixmap(name, screen, colormap, depth);
+ if (!xaw_pixmap)
+ {
+ XtDisplayStringConversionWarning(dpy, (String)fromVal->addr,
+ XtRPixmap);
+ toVal->addr = (XtPointer)XtUnspecifiedPixmap;
+ toVal->size = sizeof(Pixmap);
+ return (False);
+ }
+ else
+ pixmap = xaw_pixmap->pixmap;
+ }
+
+ done(Pixmap, pixmap);
+}
+
+/*ARGSUSED*/
+static Boolean
+_XawCvtPixmapToString(Display *dpy, XrmValue *args, Cardinal *num_args,
+ XrmValue *fromVal, XrmValue *toVal,
+ XtPointer *converter_data)
+{
+ XawPixmap *xaw_pixmap;
+ Pixmap pixmap;
+ Screen *screen;
+ Colormap colormap;
+ int depth;
+ String buffer = NULL;
+ Cardinal size;
+
+ if (*num_args != 3)
+ {
+ XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
+ XtNwrongParameters, "cvtPixmapToString",
+ XtCToolkitError,
+ "Pixmap to String conversion needs screen, "
+ "colormap, and depth arguments",
+ NULL, NULL);
+ return (False);
+ }
+
+ screen = *(Screen **)args[0].addr;
+ colormap = *(Colormap *)args[1].addr;
+ depth = *(int *)args[2].addr;
+
+ pixmap = *(Pixmap *)(fromVal[0].addr);
+
+ switch (pixmap)
+ {
+ case None:
+ buffer = "None";
+ break;
+ case ParentRelative:
+ buffer = "ParentRelative";
+ break;
+ case XtUnspecifiedPixmap:
+ buffer = "XtUnspecifiedPixmap";
+ break;
+ default:
+ xaw_pixmap = XawPixmapFromXPixmap(pixmap, screen, colormap, depth);
+ if (xaw_pixmap)
+ buffer = xaw_pixmap->name;
+ break;
+ }
+
+ if (!buffer)
+ /* Bad Pixmap or Pixmap was not loaded by XawLoadPixmap() */
+ return (_XawCvtCARD32ToString(dpy, args, num_args, fromVal, toVal,
+ converter_data));
+
+ size = strlen(buffer) + 1;
+
+ string_done(buffer);
+}
+
+#endif /* OLDXAW */
diff --git a/src/DisplayList.c b/src/DisplayList.c
new file mode 100644
index 0000000..559095d
--- /dev/null
+++ b/src/DisplayList.c
@@ -0,0 +1,2250 @@
+/*
+ * Copyright (c) 1998 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/DisplayList.c,v 3.16 2000/09/26 15:56:54 tsi Exp $ */
+
+#include <ctype.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/CoreP.h>
+#include <X11/Xfuncs.h>
+#include <X11/Xmu/CharSet.h>
+#include <X11/Xmu/SysUtil.h>
+#include "Private.h"
+
+#ifndef OLDXAW
+
+/*
+ * Types
+ */
+typedef struct _XawDLProc XawDLProc;
+typedef struct _XawDLData XawDLData;
+typedef struct _XawDLInfo XawDLInfo;
+
+struct _XawDLProc {
+ XrmQuark qname;
+ String *params;
+ Cardinal num_params;
+ XawDisplayListProc proc;
+ XtPointer args;
+ XawDLData *data;
+};
+
+struct _XawDLData {
+ XawDLClass *dlclass;
+ XtPointer data;
+};
+
+struct _XawDLInfo {
+ String name;
+ XrmQuark qname;
+ XawDisplayListProc proc;
+};
+
+struct _XawDL {
+ XawDLProc **procs;
+ Cardinal num_procs;
+ XawDLData **data;
+ Cardinal num_data;
+ Screen *screen;
+ Colormap colormap;
+ int depth;
+ XrmQuark qrep; /* for cache lookup */
+};
+
+struct _XawDLClass {
+ String name;
+ XawDLInfo **infos;
+ Cardinal num_infos;
+ XawDLArgsInitProc args_init;
+ XawDLArgsDestructor args_destructor;
+ XawDLDataInitProc data_init;
+ XawDLDataDestructor data_destructor;
+};
+
+/*
+ * Private Methods
+ */
+static XawDLClass *_XawFindDLClass(String);
+static int qcmp_dlist_class(_Xconst void*, _Xconst void*);
+static int bcmp_dlist_class(_Xconst void*, _Xconst void*);
+static XawDLInfo *_XawFindDLInfo(XawDLClass*, String);
+static int qcmp_dlist_info(_Xconst void*, _Xconst void*);
+static int bcmp_dlist_info(_Xconst void*, _Xconst void*);
+static void *_Xaw_Xlib_ArgsInitProc(String, String*, Cardinal*,
+ Screen*, Colormap, int);
+static void _Xaw_Xlib_ArgsDestructor(Display*, String, XtPointer,
+ String*, Cardinal*);
+static void *_Xaw_Xlib_DataInitProc(String, Screen*, Colormap, int);
+static void _Xaw_Xlib_DataDestructor(Display*, String, XtPointer);
+
+/*
+ * Initialization
+ */
+static XawDLClass **classes;
+static Cardinal num_classes;
+static String xlib = "xlib";
+
+/*
+ * Implementation
+ */
+void
+XawRunDisplayList(Widget w, _XawDisplayList *list,
+ XEvent *event, Region region)
+{
+ XawDLProc *proc;
+ Cardinal i;
+
+ if (!XtIsRealized(w))
+ return;
+
+ for (i = 0; i < list->num_procs; i++)
+ {
+ proc = list->procs[i];
+ proc->proc(w, proc->args, proc->data->data, event, region);
+ }
+}
+
+#define DLERR -2
+#define DLEOF -1
+#define DLEND 1
+#define DLNAME 2
+#define DLARG 3
+static char *
+read_token(char *src, char *dst, Cardinal size, int *status)
+{
+ int ch;
+ Bool esc, quote;
+ Cardinal i;
+
+ i = 0;
+ esc = quote = False;
+
+ /*CONSTCOND*/
+ while (1)
+ {
+ ch = *src;
+ if (ch != '\n' && isspace(ch))
+ ++src;
+ else
+ break;
+ }
+
+ for (; i < size - 1; src++)
+ {
+ ch = *src;
+ if (ch == '"')
+ {
+ if (quote)
+ {
+ quote = False;
+ continue;
+ }
+ quote = True;
+ continue;
+ }
+ if (ch == '\\')
+ {
+ if (esc)
+ {
+ dst[i++] = ch;
+ esc = False;
+ continue;
+ }
+ esc = True;
+ continue;
+ }
+ if (ch == '\0')
+ {
+ *status = DLEOF;
+ dst[i] = '\0';
+ return (src);
+ }
+ else if (!esc)
+ {
+ if (!quote)
+ {
+ if (ch == ',')
+ {
+ *status = DLARG;
+ dst[i] = '\0';
+ return (++src);
+ }
+ else if (ch == ' ' || ch == '\t')
+ {
+ *status = DLNAME;
+ dst[i] = '\0';
+ return (++src);
+ }
+ else if (ch == ';' || ch == '\n')
+ {
+ *status = DLEND;
+ dst[i] = '\0';
+ return (++src);
+ }
+ }
+ }
+ else
+ esc = False;
+ dst[i++] = ch;
+ }
+
+ *status = DLERR;
+ dst[i] = '\0';
+
+ return (src);
+}
+
+_XawDisplayList *XawCreateDisplayList(String string, Screen *screen,
+ Colormap colormap, int depth)
+{
+ _XawDisplayList *dlist;
+ XawDLClass *lc, *xlibc;
+ XawDLData *data;
+ XawDLInfo *info;
+ XawDLProc *proc;
+ char cname[64], fname[64], aname[1024];
+ Cardinal i;
+ char *cp, *fp, *lp;
+ int status;
+
+ xlibc = XawGetDisplayListClass(xlib);
+ if (!xlibc)
+ {
+ XawDisplayListInitialize();
+ xlibc = XawGetDisplayListClass(xlib);
+ }
+
+ dlist = (_XawDisplayList *)XtMalloc(sizeof(_XawDisplayList));
+ dlist->procs = NULL;
+ dlist->num_procs = 0;
+ dlist->data = NULL;
+ dlist->num_data = 0;
+ dlist->screen = screen;
+ dlist->colormap = colormap;
+ dlist->depth = depth;
+ dlist->qrep = NULLQUARK;
+ if (!string || !string[0])
+ return (dlist);
+
+ cp = string;
+
+ status = 0;
+ while (status != DLEOF)
+ {
+ lp = cp;
+ cp = read_token(cp, fname, sizeof(fname), &status);
+
+ if (status != DLNAME && status != DLEND && status != DLEOF)
+ {
+ char msg[256];
+
+ XmuSnprintf(msg, sizeof(msg),
+ "Error parsing displayList at \"%s\"", lp);
+ XtAppWarning(XtDisplayToApplicationContext(DisplayOfScreen(screen)),
+ msg);
+ XawDestroyDisplayList(dlist);
+ return (NULL);
+ }
+ fp = fname;
+ /*CONSTCOND*/
+ while (1)
+ {
+ fp = strchr(fp, ':');
+ if (!fp || (fp == cp || fp[-1] != '\\'))
+ break;
+ ++fp;
+ }
+ if (fp)
+ {
+ XmuSnprintf(cname, fp - fname + 1, fname);
+ memmove(fname, fp + 1, strlen(fp));
+ lc = cname[0] ? XawGetDisplayListClass(cname) : xlibc;
+ if (!lc)
+ {
+ char msg[256];
+
+ XmuSnprintf(msg, sizeof(msg),
+ "Cannot find displayList class \"%s\"", cname);
+ XtAppWarning(XtDisplayToApplicationContext
+ (DisplayOfScreen(screen)), msg);
+ XawDestroyDisplayList(dlist);
+ return (NULL);
+ }
+ }
+ else
+ lc = xlibc;
+
+ if (status == DLEOF && !fname[0])
+ break;
+
+ if ((info = _XawFindDLInfo(lc, fname)) == NULL)
+ {
+ char msg[256];
+
+ XmuSnprintf(msg, sizeof(msg),
+ "Cannot find displayList procedure \"%s\"", fname);
+ XtAppWarning(XtDisplayToApplicationContext(DisplayOfScreen(screen)),
+ msg);
+ XawDestroyDisplayList(dlist);
+ return (NULL);
+ }
+
+ proc = (XawDLProc *)XtMalloc(sizeof(XawDLProc));
+ proc->qname = info->qname;
+ proc->params = NULL;
+ proc->num_params = 0;
+ proc->proc = info->proc;
+ proc->args = NULL;
+ proc->data = NULL;
+
+ if (!dlist->procs)
+ {
+ dlist->num_procs = 1;
+ dlist->procs = (XawDLProc**)XtMalloc(sizeof(XawDLProc*));
+ }
+ else
+ {
+ ++dlist->num_procs;
+ dlist->procs = (XawDLProc**)
+ XtRealloc((char *)dlist->procs, sizeof(XawDLProc*) *
+ dlist->num_procs);
+ }
+ dlist->procs[dlist->num_procs - 1] = proc;
+
+ while (status != DLEND && status != DLEOF)
+ {
+ lp = cp;
+ cp = read_token(cp, aname, sizeof(aname), &status);
+
+ if (status != DLARG && status != DLEND && status != DLEOF)
+ {
+ char msg[256];
+
+ XmuSnprintf(msg, sizeof(msg),
+ "Error parsing displayList at \"%s\"", lp);
+ XtAppWarning(XtDisplayToApplicationContext
+ (DisplayOfScreen(screen)), msg);
+ XawDestroyDisplayList(dlist);
+ return (NULL);
+ }
+
+ if (!proc->num_params)
+ {
+ proc->num_params = 1;
+ proc->params = (String *)XtMalloc(sizeof(String));
+ }
+ else
+ {
+ ++proc->num_params;
+ proc->params = (String *)XtRealloc((char *)proc->params,
+ sizeof(String) *
+ proc->num_params);
+ }
+ proc->params[proc->num_params - 1] = XtNewString(aname);
+ }
+
+ /* verify if data is already created for lc */
+ data = NULL;
+ for (i = 0; i < dlist->num_data; i++)
+ if (dlist->data[i]->dlclass == lc)
+ {
+ data = dlist->data[i];
+ break;
+ }
+
+ if (!data)
+ {
+ data = (XawDLData *)XtMalloc(sizeof(XawDLData));
+ data->dlclass = lc;
+ if (lc->data_init)
+ data->data = lc->data_init(lc->name, screen, colormap, depth);
+ else
+ data->data = NULL;
+
+ if (!dlist->data)
+ {
+ dlist->num_data = 1;
+ dlist->data = (XawDLData **)XtMalloc(sizeof(XawDLData*));
+ }
+ else
+ {
+ ++dlist->num_data;
+ dlist->data = (XawDLData **)
+ XtRealloc((char *)dlist->data, sizeof(XawDLData*) *
+ dlist->num_data);
+ }
+ dlist->data[dlist->num_data - 1] = data;
+ }
+
+ if (lc->args_init)
+ {
+ proc->args = lc->args_init(fname, proc->params, &proc->num_params,
+ screen, colormap, depth);
+ if (proc->args == XAWDL_CONVERT_ERROR)
+ {
+ char msg[256];
+
+ proc->args = NULL;
+ XmuSnprintf(msg, sizeof(msg),
+ "Cannot convert arguments to displayList function \"%s\"", fname);
+ XtAppWarning(XtDisplayToApplicationContext
+ (DisplayOfScreen(screen)), msg);
+ XawDestroyDisplayList(dlist);
+ return (NULL);
+ }
+ }
+ else
+ proc->args = NULL;
+
+ proc->data = data;
+ }
+
+ dlist->qrep = XrmStringToQuark(string);
+ return (dlist);
+}
+
+String
+XawDisplayListString(_XawDisplayList *dlist)
+{
+ if (!dlist || dlist->qrep == NULLQUARK)
+ return ("");
+ return (XrmQuarkToString(dlist->qrep));
+}
+
+void
+XawDestroyDisplayList(_XawDisplayList *dlist)
+{
+ Cardinal i, j;
+ XawDLProc *proc;
+ XawDLData *data;
+
+ if (!dlist)
+ return;
+
+ for (i = 0; i < dlist->num_procs; i++)
+ {
+ proc = dlist->procs[i];
+ data = proc->data;
+
+ if (data)
+ {
+ if (data->dlclass->args_destructor)
+ data->dlclass->args_destructor(DisplayOfScreen(dlist->screen),
+ XrmQuarkToString(proc->qname),
+ proc->args,
+ proc->params, &proc->num_params);
+ if (data->data)
+ {
+ if (data->dlclass->data_destructor)
+ {
+ data->dlclass
+ ->data_destructor(DisplayOfScreen(dlist->screen),
+ data->dlclass->name, data->data);
+ data->data = NULL;
+ }
+ }
+ }
+
+ for (j = 0; j < proc->num_params; j++)
+ XtFree(proc->params[j]);
+ if (proc->num_params)
+ XtFree((char *)proc->params);
+ XtFree((char *)proc);
+ }
+
+ if (dlist->num_procs)
+ XtFree((char *)dlist->procs);
+
+ XtFree((char *)dlist);
+}
+
+/**********************************************************************
+ * If you want to implement your own class of procedures, look at
+ * the code bellow.
+ **********************************************************************/
+/* Start of Implementation of class "xlib" */
+typedef struct _XawXlibData {
+ GC gc;
+ unsigned long mask;
+ XGCValues values;
+ int shape;
+ int mode;
+ char *dashes;
+ /* these fields can be used for optimization, to
+ * avoid unnecessary coordinates recalculation.
+ */
+ Position x, y;
+ Dimension width, height;
+} XawXlibData;
+
+typedef struct _XawDLPosition {
+ Position pos;
+ short denom;
+ Boolean high;
+} XawDLPosition;
+
+typedef struct _XawDLPositionPtr {
+ XawDLPosition *pos;
+ Cardinal num_pos;
+} XawDLPositionPtr;
+
+typedef struct _XawDLArcArgs {
+ XawDLPosition pos[4];
+ int angle1;
+ int angle2;
+} XawDLArcArgs;
+
+typedef struct _XawDLStringArgs {
+ XawDLPosition pos[2];
+ char *string;
+ int length;
+} XawDLStringArgs;
+
+typedef struct _XawDLCopyArgs {
+ XawPixmap *pixmap;
+ XawDLPosition pos[6];
+ int plane;
+} XawDLCopyArgs;
+
+typedef struct _XawDLImageArgs {
+ XawPixmap *pixmap;
+ XawDLPosition pos[4];
+ int depth;
+} XawDLImageArgs;
+
+#define X_ARG(x) (Position)(((x).denom != 0) ? \
+ ((float)XtWidth(w) * ((float)(x).pos / (float)(x).denom)) : \
+ ((x).high ? XtWidth(w) - (x).pos : (x).pos))
+#define Y_ARG(x) (Position)(((x).denom != 0) ? \
+ ((float)XtHeight(w) * ((float)(x).pos / (float)(x).denom)): \
+ ((x).high ? XtHeight(w) - (x).pos : (x).pos))
+#define DRECT 0
+#define FRECT 1
+#define LINE 2
+#define GCFG 3
+#define GCBG 4
+#define FPOLY 5
+#define DARC 6
+#define FARC 7
+#define DLINES 8
+#define MASK 9
+#define UMASK 10
+#define LWIDTH 11
+#define POINT 12
+#define POINTS 13
+#define SEGMENTS 14
+#define ARCMODE 15
+#define COORDMODE 16
+#define SHAPEMODE 17
+#define LINESTYLE 18
+#define CAPSTYLE 19
+#define JOINSTYLE 20
+#define FILLSTYLE 21
+#define FILLRULE 22
+#define TILE 23
+#define STIPPLE 24
+#define TSORIGIN 25
+#define FUNCTION 26
+#define PLANEMASK 27
+#define DSTRING 28
+#define PSTRING 29
+#define FONT 30
+#define DASHES 31
+#define SUBWMODE 32
+#define EXPOSURES 33
+#define CLIPORIGIN 34
+#define CLIPMASK 35
+#define CLIPRECTS 36
+#define COPYAREA 37
+#define COPYPLANE 38
+#define IMAGE 39
+
+static void
+Dl1Point(Widget w, XtPointer args, XtPointer data, int id)
+{
+ XawDLPosition *pos = (XawDLPosition *)args;
+ XawXlibData *xdata = (XawXlibData *)data;
+ Display *display;
+ Window window;
+ Position x, y;
+
+ x = X_ARG(pos[0]);
+ y = Y_ARG(pos[1]);
+
+ if (!XtIsWidget(w))
+ {
+ Position xpad, ypad;
+
+ xpad = XtX(w) + XtBorderWidth(w);
+ ypad = XtY(w) + XtBorderWidth(w);
+ x += xpad;
+ x += xpad;
+ display = XtDisplayOfObject(w);
+ window = XtWindowOfObject(w);
+ }
+ else
+ {
+ display = XtDisplay(w);
+ window = XtWindow(w);
+ }
+
+ if (id == POINT)
+ XDrawPoint(display, window, xdata->gc, x, y);
+ else if (id == TSORIGIN)
+ {
+ xdata->values.ts_x_origin = x;
+ xdata->values.ts_y_origin = y;
+ xdata->mask |= GCTileStipXOrigin | GCTileStipYOrigin;
+ XSetTSOrigin(display, xdata->gc, x, y);
+ }
+ else if (id == CLIPORIGIN)
+ {
+ xdata->values.clip_x_origin = x;
+ xdata->values.clip_y_origin = y;
+ xdata->mask |= GCClipXOrigin | GCClipYOrigin;
+ XSetClipOrigin(display, xdata->gc, x, y);
+ }
+}
+
+static void
+Dl2Points(Widget w, XtPointer args, XtPointer data, int id)
+{
+ XawDLPosition *pos = (XawDLPosition *)args;
+ XawXlibData *xdata = (XawXlibData *)data;
+ Display *display;
+ Window window;
+ Position x1, y1, x2, y2;
+
+ x1 = X_ARG(pos[0]);
+ y1 = Y_ARG(pos[1]);
+ x2 = X_ARG(pos[2]);
+ y2 = Y_ARG(pos[3]);
+
+ if (!XtIsWidget(w))
+ {
+ Position xpad, ypad;
+
+ xpad = XtX(w) + XtBorderWidth(w);
+ ypad = XtY(w) + XtBorderWidth(w);
+ x1 += xpad; y1 += ypad;
+ x2 += xpad; y2 += ypad;
+ display = XtDisplayOfObject(w);
+ window = XtWindowOfObject(w);
+ }
+ else
+ {
+ display = XtDisplay(w);
+ window = XtWindow(w);
+ }
+
+ if (id == DRECT)
+ XDrawRectangle(display, window, xdata->gc, x1, y1, x2 - x1, y2 - y1);
+ else if (id == FRECT)
+ XFillRectangle(display, window, xdata->gc, x1, y1, x2 - x1, y2 - y1);
+ else if (id == LINE)
+ XDrawLine(display, window, xdata->gc, x1, y1, x2, y2);
+}
+
+/* ARGSUSED */
+static void
+DlLine(Widget w, XtPointer args, XtPointer data, XEvent *event, Region region)
+{
+ Dl2Points(w, args, data, LINE);
+}
+
+/* ARGSUSED */
+static void
+DlDrawRectangle(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ Dl2Points(w, args, data, DRECT);
+}
+
+/* ARGSUSED */
+static void
+DlFillRectangle(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ Dl2Points(w, args, data, FRECT);
+}
+
+static void
+DlXPoints(Widget w, XtPointer args, XtPointer data, int id)
+{
+ XawDLPositionPtr *pos_ptr = (XawDLPositionPtr *)args;
+ XawXlibData *xdata = (XawXlibData *)data;
+ XawDLPosition *pos;
+ XPoint points_buf[16];
+ XPoint *points;
+ Display *display;
+ Window window;
+ Cardinal num_points, i, j;
+
+ num_points = pos_ptr->num_pos>>1;
+ points = (XPoint *)XawStackAlloc(sizeof(XPoint) * num_points, points_buf);
+
+ for (i = j = 0; i < num_points; i++, j = i << 1)
+ {
+ pos = &pos_ptr->pos[j];
+ points[i].x = X_ARG(pos[0]);
+ points[i].y = Y_ARG(pos[1]);
+ }
+
+ if (!XtIsWidget(w))
+ {
+ Position xpad, ypad;
+
+ xpad = XtX(w) + XtBorderWidth(w);
+ ypad = XtY(w) + XtBorderWidth(w);
+ if (xdata->mode != CoordModePrevious)
+ {
+ for (i = 0; i < num_points; i++)
+ {
+ points[i].x += xpad;
+ points[i].y += ypad;
+ }
+ }
+ else
+ {
+ points[0].x += xpad;
+ points[0].y += ypad;
+ }
+ display = XtDisplayOfObject(w);
+ window = XtWindowOfObject(w);
+ }
+ else
+ {
+ display = XtDisplay(w);
+ window = XtWindow(w);
+ }
+
+ if (id == FPOLY)
+ XFillPolygon(display, window, xdata->gc, points, num_points,
+ xdata->shape, xdata->mode);
+ else if (id == DLINES)
+ XDrawLines(display, window, xdata->gc, points, num_points, xdata->mode);
+ else if (id == POINTS)
+ XDrawPoints(display, window, xdata->gc, points, num_points, xdata->mode);
+
+ XawStackFree(points, points_buf);
+}
+
+/* ARGSUSED */
+static void
+DlFillPolygon(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ DlXPoints(w, args, data, FPOLY);
+}
+
+/* ARGSUSED */
+static void
+DlDrawLines(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ DlXPoints(w, args, data, DLINES);
+}
+
+/* ARGSUSED */
+static void
+DlDrawPoints(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ DlXPoints(w, args, data, POINTS);
+}
+
+/* ARGSUSED */
+static void
+DlForeground(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ XawXlibData *xdata = (XawXlibData *)data;
+ Pixel foreground = (Pixel)args;
+
+ if (xdata->values.foreground != foreground)
+ {
+ xdata->mask |= GCForeground;
+ xdata->values.foreground = foreground;
+ XSetForeground(XtDisplayOfObject(w), xdata->gc, foreground);
+ }
+}
+
+/* ARGSUSED */
+static void
+DlBackground(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ XawXlibData *xdata = (XawXlibData *)data;
+ Pixel background = (Pixel)args;
+
+ if (xdata->values.background != background)
+ {
+ xdata->mask |= GCBackground;
+ xdata->values.background = background;
+ XSetBackground(XtDisplayOfObject(w), xdata->gc, background);
+ }
+}
+
+static void
+DlArc(Widget w, XtPointer args, XtPointer data, Bool fill)
+{
+ XawXlibData *xdata = (XawXlibData *)data;
+ XawDLArcArgs *arc = (XawDLArcArgs *)args;
+ Position x1, y1, x2, y2;
+ Display *display;
+ Window window;
+
+ x1 = X_ARG(arc->pos[0]);
+ y1 = Y_ARG(arc->pos[1]);
+ x2 = X_ARG(arc->pos[2]);
+ y2 = Y_ARG(arc->pos[3]);
+
+ if (!XtIsWidget(w))
+ {
+ Position xpad, ypad;
+
+ xpad = XtX(w) + XtBorderWidth(w);
+ ypad = XtY(w) + XtBorderWidth(w);
+ x1 += xpad;
+ y1 += ypad;
+ x2 += xpad;
+ y2 += ypad;
+ display = XtDisplayOfObject(w);
+ window = XtWindowOfObject(w);
+ }
+ else
+ {
+ display = XtDisplay(w);
+ window = XtWindow(w);
+ }
+
+ if (fill)
+ XFillArc(display, window, xdata->gc, x1, y1, x2 - x1, y2 - y1,
+ arc->angle1, arc->angle2);
+ else
+ XDrawArc(display, window, xdata->gc, x1, y1, x2 - x1, y2 - y1,
+ arc->angle1, arc->angle2);
+}
+
+/* ARGSUSED */
+static void
+DlDrawArc(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ DlArc(w, args, data, False);
+}
+
+/* ARGSUSED */
+static void
+DlFillArc(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ DlArc(w, args, data, True);
+}
+
+/*ARGSUSED*/
+static void
+DlMask(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ XawXlibData *xdata = (XawXlibData *)data;
+ Display *display = XtDisplayOfObject(w);
+
+ if (region)
+ XSetRegion(display, xdata->gc, region);
+ else if (event)
+ {
+ XRectangle rect;
+
+ rect.x = event->xexpose.x;
+ rect.y = event->xexpose.y;
+ rect.width = event->xexpose.width;
+ rect.height = event->xexpose.height;
+ XSetClipRectangles(display, xdata->gc, 0, 0, &rect, 1, Unsorted);
+ }
+}
+
+/* ARGSUSED */
+static void
+DlUmask(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ XawXlibData *xdata = (XawXlibData *)data;
+
+ XSetClipMask(XtDisplayOfObject(w), xdata->gc, None);
+}
+
+/* ARGSUSED */
+static void
+DlLineWidth(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ XawXlibData *xdata = (XawXlibData *)data;
+ unsigned line_width = (unsigned long)args;
+
+ if (xdata->values.line_width != line_width)
+ {
+ xdata->mask |= GCLineWidth;
+ xdata->values.line_width = line_width;
+ XChangeGC(XtDisplayOfObject(w), xdata->gc, GCLineWidth, &xdata->values);
+ }
+}
+
+/* ARGSUSED */
+static void
+DlDrawPoint(Widget w, XtPointer args, XtPointer data, XEvent *event, Region region)
+{
+ Dl1Point(w, args, data, POINT);
+}
+
+/* ARGSUSED */
+static void
+DlDrawSegments(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ XawDLPositionPtr *pos_ptr = (XawDLPositionPtr *)args;
+ XawXlibData *xdata = (XawXlibData *)data;
+ XawDLPosition *pos;
+ XSegment *segments;
+ XSegment segments_buf[8];
+ Display *display;
+ Window window;
+ Cardinal num_segments, i, j;
+
+ num_segments = pos_ptr->num_pos>>2;
+ segments = (XSegment *)XawStackAlloc(sizeof(XSegment) * num_segments, segments_buf);
+
+ for (i = j = 0; i < num_segments; i++, j = i << 2)
+ {
+ pos = &pos_ptr->pos[j];
+ segments[i].x1 = X_ARG(pos[0]);
+ segments[i].y1 = Y_ARG(pos[1]);
+ segments[i].x2 = X_ARG(pos[2]);
+ segments[i].y2 = Y_ARG(pos[3]);
+ }
+
+ if (!XtIsWidget(w))
+ {
+ Position xpad, ypad;
+
+ xpad = XtX(w) + XtBorderWidth(w);
+ ypad = XtY(w) + XtBorderWidth(w);
+ for (i = 0; i < num_segments; i++)
+ {
+ segments[i].x1 += xpad;
+ segments[i].y1 += ypad;
+ segments[i].x2 += xpad;
+ segments[i].y2 += ypad;
+ }
+ display = XtDisplayOfObject(w);
+ window = XtWindowOfObject(w);
+ }
+ else
+ {
+ display = XtDisplay(w);
+ window = XtWindow(w);
+ }
+
+ XDrawSegments(display, window, xdata->gc, segments, num_segments);
+
+ XawStackFree(segments, segments_buf);
+}
+
+/* ARGSUSED */
+static void
+DlArcMode(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ XawXlibData *xdata = (XawXlibData *)data;
+ int arc_mode = (long)args;
+
+ if (xdata->values.arc_mode != arc_mode)
+ {
+ xdata->mask |= GCArcMode;
+ xdata->values.arc_mode = arc_mode;
+ XSetArcMode(XtDisplayOfObject(w), xdata->gc, arc_mode);
+ }
+}
+
+/* ARGSUSED */
+static void
+DlCoordMode(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ XawXlibData *xdata = (XawXlibData *)data;
+ int mode = (long)args;
+
+ xdata->mode = mode;
+}
+
+/* ARGSUSED */
+static void
+DlShapeMode(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ XawXlibData *xdata = (XawXlibData *)data;
+ int shape = (long)args;
+
+ xdata->shape = shape;
+}
+
+/* ARGSUSED */
+static void
+DlLineStyle(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ XawXlibData *xdata = (XawXlibData *)data;
+ int line_style = (long)args;
+
+ if (xdata->values.line_style != line_style)
+ {
+ xdata->mask |= GCLineStyle;
+ xdata->values.line_style = line_style;
+ XChangeGC(XtDisplayOfObject(w), xdata->gc, GCLineStyle, &xdata->values);
+ }
+}
+
+/* ARGSUSED */
+static void
+DlCapStyle(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ XawXlibData *xdata = (XawXlibData *)data;
+ int cap_style = (long)args;
+
+ if (xdata->values.cap_style != cap_style)
+ {
+ xdata->mask |= GCCapStyle;
+ xdata->values.cap_style = cap_style;
+ XChangeGC(XtDisplayOfObject(w), xdata->gc, GCCapStyle, &xdata->values);
+ }
+}
+
+/* ARGSUSED */
+static void
+DlJoinStyle(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ XawXlibData *xdata = (XawXlibData *)data;
+ int join_style = (long)args;
+
+ if (xdata->values.join_style != join_style)
+ {
+ xdata->mask |= GCJoinStyle;
+ xdata->values.join_style = join_style;
+ XChangeGC(XtDisplayOfObject(w), xdata->gc, GCJoinStyle, &xdata->values);
+ }
+}
+
+/* ARGSUSED */
+static void
+DlFillStyle(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ XawXlibData *xdata = (XawXlibData *)data;
+ int fill_style = (long)args;
+
+ if (xdata->values.fill_style != fill_style)
+ {
+ xdata->mask |= GCFillStyle;
+ xdata->values.fill_style = fill_style;
+ XSetFillStyle(XtDisplayOfObject(w), xdata->gc, fill_style);
+ }
+}
+
+/* ARGSUSED */
+static void
+DlFillRule(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ XawXlibData *xdata = (XawXlibData *)data;
+ int fill_rule = (long)args;
+
+ if (xdata->values.fill_rule != fill_rule)
+ {
+ xdata->mask |= GCFillRule;
+ xdata->values.fill_rule = fill_rule;
+ XSetFillRule(XtDisplayOfObject(w), xdata->gc, fill_rule);
+ }
+}
+
+/* ARGSUSED */
+static void
+DlTile(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ XawXlibData *xdata = (XawXlibData *)data;
+ XawPixmap *pixmap = (XawPixmap *)args;
+
+ if (pixmap && xdata->values.tile != pixmap->pixmap)
+ {
+ xdata->mask |= GCTile;
+ xdata->values.tile = pixmap->pixmap;
+ XSetTile(XtDisplayOfObject(w), xdata->gc, xdata->values.tile);
+ }
+}
+
+/* ARGSUSED */
+static void
+DlStipple(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ XawXlibData *xdata = (XawXlibData *)data;
+ XawPixmap *pixmap = (XawPixmap *)args;
+
+ if (pixmap && xdata->values.stipple != pixmap->pixmap)
+ {
+ xdata->mask |= GCStipple;
+ xdata->values.stipple = pixmap->pixmap;
+ XSetStipple(XtDisplayOfObject(w), xdata->gc, xdata->values.stipple);
+ }
+}
+
+/* ARGSUSED */
+static void
+DlTSOrigin(Widget w, XtPointer args, XtPointer data, XEvent *event, Region region)
+{
+ Dl1Point(w, args, data, TSORIGIN);
+}
+
+/* ARGSUSED */
+static void
+DlFunction(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ XawXlibData *xdata = (XawXlibData *)data;
+ int function = (long)args;
+
+ if (function != xdata->values.function)
+ {
+ xdata->mask |= GCFunction;
+ xdata->values.function = function;
+ XSetFunction(XtDisplayOfObject(w), xdata->gc, function);
+ }
+}
+
+/* ARGSUSED */
+static void
+DlPlaneMask(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ XawXlibData *xdata = (XawXlibData *)data;
+ unsigned long plane_mask = (unsigned long)args;
+
+ if (xdata->values.plane_mask != plane_mask)
+ {
+ xdata->mask |= GCPlaneMask;
+ xdata->values.plane_mask = plane_mask;
+ XSetPlaneMask(XtDisplayOfObject(w), xdata->gc, plane_mask);
+ }
+}
+
+static void
+DlString(Widget w, XtPointer args, XtPointer data, Bool image)
+{
+ XawDLStringArgs *string = (XawDLStringArgs *)args;
+ XawXlibData *xdata = (XawXlibData *)data;
+ Display *display;
+ Window window;
+ Position x, y;
+
+ x = X_ARG(string->pos[0]);
+ y = Y_ARG(string->pos[1]);
+
+ if (!XtIsWidget(w))
+ {
+ Position xpad, ypad;
+
+ xpad = XtX(w) + XtBorderWidth(w);
+ ypad = XtY(w) + XtBorderWidth(w);
+ x += xpad;
+ x += xpad;
+ display = XtDisplayOfObject(w);
+ window = XtWindowOfObject(w);
+ }
+ else
+ {
+ display = XtDisplay(w);
+ window = XtWindow(w);
+ }
+
+ if (image)
+ XDrawImageString(display, window, xdata->gc, x, y, string->string, string->length);
+ else
+ XDrawString(display, window, xdata->gc, x, y, string->string, string->length);
+}
+
+/* ARGSUSED */
+static void
+DlDrawString(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ DlString(w, args, data, False);
+}
+
+/* ARGSUSED */
+static void
+DlPaintString(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ DlString(w, args, data, True);
+}
+
+/* ARGSUSED */
+static void
+DlFont(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ XawXlibData *xdata = (XawXlibData *)data;
+ Font font = (Font)args;
+
+ if (xdata->values.font != font)
+ {
+ xdata->mask |= GCFont;
+ xdata->values.font = font;
+ XSetFont(XtDisplayOfObject(w), xdata->gc, font);
+ }
+}
+
+/* ARGSUSED */
+static void
+DlDashes(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ XawXlibData *xdata = (XawXlibData *)data;
+ char *dashes = args;
+
+ if (xdata->dashes != dashes)
+ {
+ xdata->mask |= GCDashOffset | GCDashList;
+ xdata->dashes = dashes;
+ XSetDashes(XtDisplayOfObject(w), xdata->gc, 0, dashes + 1, *dashes);
+ }
+}
+
+/* ARGSUSED */
+static void
+DlSubwindowMode(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ XawXlibData *xdata = (XawXlibData *)data;
+ int subwindow_mode = (long)args;
+
+ if (xdata->values.subwindow_mode != subwindow_mode)
+ {
+ xdata->mask |= GCSubwindowMode;
+ xdata->values.subwindow_mode = subwindow_mode;
+ XSetSubwindowMode(XtDisplayOfObject(w), xdata->gc, subwindow_mode);
+ }
+}
+
+/* ARGSUSED */
+static void
+DlExposures(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ XawXlibData *xdata = (XawXlibData *)data;
+ Bool graphics_exposures = (Bool)(long)args;
+
+ if (xdata->values.graphics_exposures != graphics_exposures)
+ {
+ xdata->mask |= GCGraphicsExposures;
+ xdata->values.graphics_exposures = graphics_exposures;
+ XSetGraphicsExposures(XtDisplayOfObject(w), xdata->gc, graphics_exposures);
+ }
+}
+
+/* ARGSUSED */
+static void
+DlClipOrigin(Widget w, XtPointer args, XtPointer data, XEvent *event, Region region)
+{
+ Dl1Point(w, args, data, CLIPORIGIN);
+}
+
+/* ARGSUSED */
+static void
+DlClipMask(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ XawXlibData *xdata = (XawXlibData *)data;
+ XawPixmap *pixmap = (XawPixmap *)args;
+ Pixmap clip_mask;
+
+ if (pixmap)
+ clip_mask = pixmap->mask ? pixmap->mask : pixmap->pixmap;
+ else
+ clip_mask = None;
+
+ if (xdata->values.clip_mask != clip_mask)
+ {
+ xdata->mask |= GCClipMask;
+ XSetClipMask(XtDisplayOfObject(w), xdata->gc, clip_mask);
+ }
+}
+
+/* ARGSUSED */
+static void
+DlClipRectangles(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ XawDLPositionPtr *pos_ptr = (XawDLPositionPtr *)args;
+ XawXlibData *xdata = (XawXlibData *)data;
+ XawDLPosition *pos;
+ XRectangle *rects;
+ XRectangle rects_buf[8];
+ Position x1, y1, x2, y2;
+ Cardinal num_rects, i, j;
+
+ num_rects = pos_ptr->num_pos>>2;
+ rects = (XRectangle *)XawStackAlloc(sizeof(XRectangle) * num_rects, rects_buf);
+
+ for (i = j = 0; i < num_rects; i++, j = i << 2)
+ {
+ pos = &pos_ptr->pos[j];
+ x1 = X_ARG(pos[0]);
+ y1 = Y_ARG(pos[1]);
+ x2 = X_ARG(pos[2]);
+ y2 = Y_ARG(pos[3]);
+ rects[i].x = XawMin(x1, x2);
+ rects[i].y = XawMin(y1, y2);
+ rects[i].width = XawMax(x1, x2) - rects[i].x;
+ rects[i].height = XawMax(y1, y2) - rects[i].y;
+ }
+
+ if (!XtIsWidget(w))
+ {
+ Position xpad, ypad;
+
+ xpad = XtX(w) + XtBorderWidth(w);
+ ypad = XtY(w) + XtBorderWidth(w);
+ for (i = 0; i < num_rects; i++)
+ {
+ rects[i].x += xpad;
+ rects[i].y += ypad;
+ }
+ }
+
+ XSetClipRectangles(XtDisplayOfObject(w), xdata->gc, 0, 0, rects, num_rects, Unsorted);
+
+ XawStackFree(rects, rects_buf);
+}
+
+static void
+DlCopy(Widget w, XtPointer args, XtPointer data, Bool plane)
+{
+ XawDLCopyArgs *copy = (XawDLCopyArgs *)args;
+ XawXlibData *xdata = (XawXlibData *)data;
+ int src_x, src_y, dst_x, dst_y, width, height, tmp1, tmp2;
+
+ tmp1 = X_ARG(copy->pos[0]);
+ tmp2 = X_ARG(copy->pos[2]);
+ dst_x = XawMin(tmp1, tmp2);
+ width = XawMax(tmp1, tmp2) - dst_x;
+
+ tmp1 = Y_ARG(copy->pos[1]);
+ tmp2 = Y_ARG(copy->pos[3]);
+ dst_y = XawMin(tmp1, tmp2);
+ height = XawMax(tmp1, tmp2) - dst_y;
+
+ src_x = X_ARG(copy->pos[4]);
+ src_y = Y_ARG(copy->pos[5]);
+
+ if (width <= 0)
+ {
+ if (copy->pixmap)
+ width = copy->pixmap->width;
+ else
+ {
+ if ((width = XtWidth(w) - src_x) < 0)
+ width = 0;
+ }
+ }
+ if (height <= 0)
+ {
+ if (copy->pixmap)
+ height = copy->pixmap->height;
+ else
+ {
+ if ((height = XtHeight(w) - src_y) < 0)
+ height = 0;
+ }
+ }
+
+ if (!XtIsWidget(w))
+ {
+ Position xpad, ypad;
+
+ xpad = XtX(w) + XtBorderWidth(w);
+ ypad = XtY(w) + XtBorderWidth(w);
+ src_x += xpad;
+ src_y += ypad;
+ dst_x += xpad;
+ dst_y += ypad;
+ }
+
+ if (plane)
+ XCopyPlane(XtDisplayOfObject(w), XtWindowOfObject(w),
+ copy->pixmap ? copy->pixmap->pixmap : XtWindowOfObject(w),
+ xdata->gc, src_x, src_y, width, height, dst_x, dst_y,
+ copy->plane ? copy->plane : 1);
+ else
+ XCopyArea(XtDisplayOfObject(w),
+ copy->pixmap ? copy->pixmap->pixmap : XtWindowOfObject(w),
+ XtWindowOfObject(w), xdata->gc, src_x, src_y, width, height, dst_x, dst_y);
+}
+
+/* ARGSUSED */
+static void
+DlCopyArea(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ DlCopy(w, args, data, False);
+}
+
+/* ARGSUSED */
+static void
+DlCopyPlane(Widget w, XtPointer args, XtPointer data,
+ XEvent *event, Region region)
+{
+ DlCopy(w, args, data, True);
+}
+
+/*ARGSUSED*/
+/* Note:
+ * This function is destructive if you set the ts_x_origin, ts_y_origin,
+ * and/or clip-mask. It is meant to be the only function used in a display
+ * list. If you need to use other functions (and those values), be sure to
+ * set them after calling this function.
+ */
+static void
+DlImage(Widget w, XtPointer args, XtPointer data, XEvent *event, Region region)
+{
+ XawDLImageArgs *image = (XawDLImageArgs *)args;
+ XawXlibData *xdata = (XawXlibData *)data;
+ int x, y, xs, ys, xe, ye, width, height;
+ Display *display;
+ Window window;
+
+ width = image->pixmap->width;
+ height = image->pixmap->height;
+ xs = X_ARG(image->pos[0]);
+ ys = Y_ARG(image->pos[1]);
+ xe = X_ARG(image->pos[2]);
+ ye = Y_ARG(image->pos[3]);
+
+ if (xe <= 0)
+ xe = xs + width;
+ if (ye <= 0)
+ ye = ys + height;
+
+ if (!XtIsWidget(w))
+ {
+ Position xpad, ypad;
+
+ xpad = XtX(w) + XtBorderWidth(w);
+ ypad = XtY(w) + XtBorderWidth(w);
+ xe += xpad;
+ ye += ypad;
+ xe += xpad;
+ ye += ypad;
+ display = XtDisplayOfObject(w);
+ window = XtWindowOfObject(w);
+ }
+ else
+ {
+ display = XtDisplay(w);
+ window = XtWindow(w);
+ }
+
+ for (y = ys; y < ye; y += height)
+ for (x = xs; x < xe; x += width)
+ {
+ XSetClipOrigin(display, xdata->gc, x, y);
+ if (image->pixmap->mask)
+ XSetClipMask(display, xdata->gc, image->pixmap->mask);
+ if (image->depth == 1)
+ XCopyPlane(display, image->pixmap->pixmap, window, xdata->gc,
+ 0, 0, XawMin(width, xe - x), XawMin(height, ye - y),
+ x, y, 1L);
+ else
+ XCopyArea(display, image->pixmap->pixmap, window, xdata->gc, 0, 0,
+ XawMin(width, xe - x), XawMin(height, ye - y), x, y);
+ }
+
+ XSetClipMask(display, xdata->gc, None);
+}
+
+typedef struct _Dl_init Dl_init;
+struct _Dl_init {
+ String name;
+ XawDisplayListProc proc;
+ Cardinal id;
+};
+
+static Dl_init dl_init[] =
+{
+ {"arc-mode", DlArcMode, ARCMODE},
+ {"background", DlBackground, GCBG},
+ {"bg", DlBackground, GCBG},
+ {"cap-style", DlCapStyle, CAPSTYLE},
+ {"clip-mask", DlClipMask, CLIPMASK},
+ {"clip-origin", DlClipOrigin, CLIPORIGIN},
+ {"clip-rectangles", DlClipRectangles, CLIPRECTS},
+ {"clip-rects", DlClipRectangles, CLIPRECTS},
+ {"coord-mode", DlCoordMode, COORDMODE},
+ {"copy-area", DlCopyArea, COPYAREA},
+ {"copy-plane", DlCopyPlane, COPYPLANE},
+ {"dashes", DlDashes, DASHES},
+ {"draw-arc", DlDrawArc, DARC},
+ {"draw-line", DlLine, LINE},
+ {"draw-lines", DlDrawLines, DLINES},
+ {"draw-point", DlDrawPoint, POINT},
+ {"draw-points", DlDrawPoints, POINTS},
+ {"draw-rect", DlDrawRectangle, DRECT},
+ {"draw-rectangle", DlDrawRectangle, DRECT},
+ {"draw-segments", DlDrawSegments, SEGMENTS},
+ {"draw-string", DlDrawString, DSTRING},
+ {"exposures", DlExposures, EXPOSURES},
+ {"fg", DlForeground, GCFG},
+ {"fill-arc", DlFillArc, FARC},
+ {"fill-poly", DlFillPolygon, FPOLY},
+ {"fill-polygon", DlFillPolygon, FPOLY},
+ {"fill-rect", DlFillRectangle, FRECT},
+ {"fill-rectangle", DlFillRectangle, FRECT},
+ {"fill-rule", DlFillRule, FILLRULE},
+ {"fill-style", DlFillStyle, FILLSTYLE},
+ {"font", DlFont, FONT},
+ {"foreground", DlForeground, GCFG},
+ {"function", DlFunction, FUNCTION},
+ {"image", DlImage, IMAGE},
+ {"join-style", DlJoinStyle, JOINSTYLE},
+ {"line", DlLine, LINE},
+ {"line-style", DlLineStyle, LINESTYLE},
+ {"line-width", DlLineWidth, LWIDTH},
+ {"lines", DlDrawLines, DLINES},
+ {"mask", DlMask, MASK},
+ {"paint-string", DlPaintString, PSTRING},
+ {"plane-mask", DlPlaneMask, PLANEMASK},
+ {"point", DlDrawPoint, POINT},
+ {"points", DlDrawPoints, POINTS},
+ {"segments", DlDrawSegments, SEGMENTS},
+ {"shape-mode", DlShapeMode, SHAPEMODE},
+ {"stipple", DlStipple, STIPPLE},
+ {"subwindow-mode", DlSubwindowMode, SUBWMODE},
+ {"tile", DlTile, TILE},
+ {"ts-origin", DlTSOrigin, TSORIGIN},
+ {"umask", DlUmask, UMASK},
+};
+
+void
+XawDisplayListInitialize(void)
+{
+ static Bool first_time = True;
+ XawDLClass *lc;
+ Cardinal i;
+
+ if (first_time == False)
+ return;
+
+ first_time = False;
+
+ lc = XawCreateDisplayListClass(xlib,
+ _Xaw_Xlib_ArgsInitProc,
+ _Xaw_Xlib_ArgsDestructor,
+ _Xaw_Xlib_DataInitProc,
+ _Xaw_Xlib_DataDestructor);
+ for (i = 0; i < sizeof(dl_init) / sizeof(dl_init[0]); i++)
+ (void)XawDeclareDisplayListProc(lc, dl_init[i].name, dl_init[i].proc);
+}
+
+static int
+bcmp_cvt_proc(register _Xconst void *string,
+ register _Xconst void *dlinfo)
+{
+ return (strcmp((String)string, ((Dl_init*)dlinfo)->name));
+}
+
+static long
+read_int(char *cp, char **cpp)
+{
+ long value = 0, sign = 1;
+
+ if (*cp == '-')
+ {
+ sign = -1;
+ ++cp;
+ }
+ else if (*cp == '+')
+ ++cp;
+ value = 0;
+ while (*cp >= '0' && *cp <= '9')
+ {
+ value = value * 10 + *cp - '0';
+ ++cp;
+ }
+ if (cpp)
+ *cpp = cp;
+ return (value * sign);
+}
+
+static void
+read_position(char *arg, XawDLPosition *pos)
+{
+ int ch;
+ char *str = arg;
+
+ ch = *str;
+ if (ch == '-' || ch == '+')
+ {
+ ++str;
+ if (ch == '-')
+ pos->high = True;
+ pos->pos = read_int(str, NULL);
+ }
+ else if (isdigit(ch))
+ {
+ pos->pos = read_int(str, &str);
+ ch = *str++;
+ if (ch == '/')
+ pos->denom = read_int(str, NULL);
+ }
+}
+
+/* ARGSUSED */
+static void *
+_Xaw_Xlib_ArgsInitProc(String proc_name, String *params, Cardinal *num_params,
+ Screen *screen, Colormap colormap, int depth)
+{
+ Cardinal id, i;
+ Dl_init *init;
+ void *retval = XAWDL_CONVERT_ERROR;
+
+ init = (Dl_init *)bsearch(proc_name, dl_init,
+ sizeof(dl_init) / sizeof(dl_init[0]),
+ sizeof(dl_init[0]),
+ bcmp_cvt_proc);
+
+ id = init->id;
+
+ switch (id)
+ {
+ case LINE:
+ case DRECT:
+ case FRECT:
+ if (*num_params == 4)
+ {
+ XawDLPosition *pos = (XawDLPosition *)XtCalloc(1, sizeof(XawDLPosition) * 4);
+
+ for (i = 0; i < 4; i++)
+ read_position(params[i], &pos[i]);
+ retval = (void *)pos;
+ }
+ break;
+ case POINT:
+ case TSORIGIN:
+ case CLIPORIGIN:
+ if (*num_params == 2)
+ {
+ XawDLPosition *pos = (XawDLPosition *)XtCalloc(1, sizeof(XawDLPosition) * 2);
+
+ read_position(params[0], &pos[0]);
+ read_position(params[1], &pos[1]);
+ retval = (void *)pos;
+ }
+ break;
+ case DLINES:
+ case FPOLY:
+ case POINTS:
+ if (*num_params >= 4 && !(*num_params & 1))
+ {
+ XawDLPositionPtr *pos = XtNew(XawDLPositionPtr);
+
+ pos->pos = (XawDLPosition *)XtCalloc(1, sizeof(XawDLPosition) *
+ *num_params);
+ pos->num_pos = *num_params;
+ for (i = 0; i < *num_params; i++)
+ read_position(params[i], &pos->pos[i]);
+ retval = (void *)pos;
+ }
+ break;
+ case SEGMENTS:
+ case CLIPRECTS:
+ if (*num_params >= 4 && !(*num_params % 4))
+ {
+ XawDLPositionPtr *pos = XtNew(XawDLPositionPtr);
+
+ pos->pos = (XawDLPosition *)XtCalloc(1, sizeof(XawDLPosition) *
+ *num_params);
+ pos->num_pos = *num_params;
+ for (i = 0; i < *num_params; i++)
+ read_position(params[i], &pos->pos[i]);
+ retval = (void *)pos;
+ }
+ break;
+ case DARC:
+ case FARC:
+ if (*num_params >= 4 && *num_params <= 6)
+ {
+ XawDLArcArgs *args = (XawDLArcArgs *)XtCalloc(1, sizeof(XawDLArcArgs));
+
+ args->angle1 = 0;
+ args->angle2 = 360;
+ for (i = 0; i < 4; i++)
+ read_position(params[i], &args->pos[i]);
+ if (*num_params > 4)
+ args->angle1 = read_int(params[4], NULL);
+ if (*num_params > 5)
+ args->angle2 = read_int(params[5], NULL);
+ args->angle1 *= 64;
+ args->angle2 *= 64;
+ retval = (void *)args;
+ }
+ break;
+ case GCFG:
+ case GCBG:
+ {
+ XColor xcolor;
+
+ if (*num_params == 1 &&
+ XAllocNamedColor(DisplayOfScreen(screen), colormap,
+ params[0], &xcolor, &xcolor))
+ retval = (void *)xcolor.pixel;
+ } break;
+ case MASK:
+ case UMASK:
+ if (*num_params == 0)
+ retval = NULL;
+ break;
+ case LWIDTH:
+ if (*num_params == 1)
+ retval = (void *)read_int(params[0], NULL);
+ break;
+ case ARCMODE:
+ if (*num_params == 1)
+ {
+ if (XmuCompareISOLatin1(params[0], "pieslice") == 0)
+ retval = (void *)ArcPieSlice;
+ else if (XmuCompareISOLatin1(params[0], "chord") == 0)
+ retval = (void *)ArcChord;
+ }
+ break;
+ case COORDMODE:
+ if (*num_params == 1)
+ {
+ if (XmuCompareISOLatin1(params[0], "origin") == 0)
+ retval = (void *)CoordModeOrigin;
+ else if (XmuCompareISOLatin1(params[0], "previous") == 0)
+ retval = (void *)CoordModePrevious;
+ }
+ break;
+ case SHAPEMODE:
+ if (*num_params == 1)
+ {
+ if (XmuCompareISOLatin1(params[0], "complex") == 0)
+ retval = (void *)Complex;
+ else if (XmuCompareISOLatin1(params[0], "convex") == 0)
+ retval = (void *)Convex;
+ else if (XmuCompareISOLatin1(params[0], "nonconvex") == 0)
+ retval = (void *)Nonconvex;
+ }
+ break;
+ case LINESTYLE:
+ if (*num_params == 1)
+ {
+ if (XmuCompareISOLatin1(params[0], "solid") == 0)
+ retval = (void *)LineSolid;
+ else if (XmuCompareISOLatin1(params[0], "onoffdash") == 0)
+ retval = (void *)LineOnOffDash;
+ else if (XmuCompareISOLatin1(params[0], "doubledash") == 0)
+ retval = (void *)LineDoubleDash;
+ }
+ break;
+ case CAPSTYLE:
+ if (*num_params == 1)
+ {
+ if (XmuCompareISOLatin1(params[0], "notlast") == 0)
+ retval = (void *)CapNotLast;
+ else if (XmuCompareISOLatin1(params[0], "butt") == 0)
+ retval = (void *)CapButt;
+ else if (XmuCompareISOLatin1(params[0], "round") == 0)
+ retval = (void *)CapRound;
+ else if (XmuCompareISOLatin1(params[0], "projecting") == 0)
+ retval = (void *)CapProjecting;
+ }
+ break;
+ case JOINSTYLE:
+ if (*num_params == 1)
+ {
+ if (XmuCompareISOLatin1(params[0], "miter") == 0)
+ retval = (void *)JoinMiter;
+ else if (XmuCompareISOLatin1(params[0], "round") == 0)
+ retval = (void *)JoinRound;
+ else if (XmuCompareISOLatin1(params[0], "bevel") == 0)
+ retval = (void *)JoinBevel;
+ }
+ break;
+ case FILLSTYLE:
+ if (*num_params == 1)
+ {
+ if (*num_params && XmuCompareISOLatin1(params[0], "solid") == 0)
+ retval = (void *)FillSolid;
+ else if (*num_params && XmuCompareISOLatin1(params[0], "tiled") == 0)
+ retval = (void *)FillTiled;
+ else if (*num_params && XmuCompareISOLatin1(params[0], "stippled") == 0)
+ retval = (void *)FillStippled;
+ else if (*num_params && XmuCompareISOLatin1(params[0], "opaquestippled") == 0)
+ retval = (void *)FillOpaqueStippled;
+ }
+ break;
+ case FILLRULE:
+ if (*num_params == 1)
+ {
+ if (XmuCompareISOLatin1(params[0], "evenodd") == 0)
+ retval = (void *)EvenOddRule;
+ else if (XmuCompareISOLatin1(params[0], "winding") == 0)
+ retval = (void *)WindingRule;
+ }
+ break;
+ case TILE:
+ if (*num_params == 1)
+ retval = (void *)XawLoadPixmap(params[0], screen, colormap, depth);
+ if (retval == NULL)
+ {
+ XtDisplayStringConversionWarning(DisplayOfScreen(screen), (String)params[0],
+ XtRPixmap);
+ retval = XAWDL_CONVERT_ERROR;
+ }
+ break;
+ case STIPPLE:
+ if (*num_params == 1)
+ retval = (void *)XawLoadPixmap(params[0], screen, colormap, 1);
+ if (retval == NULL)
+ {
+ XtDisplayStringConversionWarning(DisplayOfScreen(screen), (String)params[0],
+ XtRBitmap);
+ retval = XAWDL_CONVERT_ERROR;
+ }
+ break;
+ case FUNCTION:
+ if (*num_params == 1)
+ {
+ if (XmuCompareISOLatin1(params[0], "set") == 0)
+ retval = (void *)GXset;
+ else if (XmuCompareISOLatin1(params[0], "clear") == 0)
+ retval = (void *)GXclear;
+ else if (XmuCompareISOLatin1(params[0], "and") == 0)
+ retval = (void *)GXand;
+ else if (XmuCompareISOLatin1(params[0], "andreverse") == 0)
+ retval = (void *)GXandReverse;
+ else if (XmuCompareISOLatin1(params[0], "copy") == 0)
+ retval = (void *)GXcopy;
+ else if (XmuCompareISOLatin1(params[0], "andinverted") == 0)
+ retval = (void *)GXandInverted;
+ else if (XmuCompareISOLatin1(params[0], "noop") == 0)
+ retval = (void *)GXnoop;
+ else if (XmuCompareISOLatin1(params[0], "xor") == 0)
+ retval = (void *)GXxor;
+ else if (XmuCompareISOLatin1(params[0], "or") == 0)
+ retval = (void *)GXor;
+ else if (XmuCompareISOLatin1(params[0], "nor") == 0)
+ retval = (void *)GXnor;
+ else if (XmuCompareISOLatin1(params[0], "equiv") == 0)
+ retval = (void *)GXequiv;
+ else if (XmuCompareISOLatin1(params[0], "invert") == 0)
+ retval = (void *)GXinvert;
+ else if (XmuCompareISOLatin1(params[0], "orreverse") == 0)
+ retval = (void *)GXorReverse;
+ else if (XmuCompareISOLatin1(params[0], "copyinverted") == 0)
+ retval = (void *)GXcopyInverted;
+ else if (XmuCompareISOLatin1(params[0], "nand") == 0)
+ retval = (void *)GXnand;
+ }
+ break;
+ case PLANEMASK:
+ if (*num_params == 1)
+ retval = (void *)read_int(params[0], NULL);
+ break;
+ case DSTRING:
+ case PSTRING:
+ if (*num_params == 3)
+ {
+ XawDLStringArgs *string = (XawDLStringArgs *)
+ XtCalloc(1, sizeof(XawDLStringArgs));
+
+ read_position(params[0], &string->pos[0]);
+ read_position(params[1], &string->pos[1]);
+ string->string = XtNewString(params[2]);
+ string->length = strlen(string->string);
+ retval = string;
+ }
+ break;
+ case FONT:
+ if (*num_params == 1)
+ retval = (void *)XLoadFont(DisplayOfScreen(screen), params[0]);
+ break;
+ case DASHES:
+ if (*num_params && *num_params < 127)
+ {
+ char *dashes;
+
+ dashes = XtMalloc(*num_params + 1);
+
+ for (i = 0; i < *num_params; i++)
+ dashes[i + 1] = read_int(params[i], NULL);
+ *dashes = *num_params;
+ retval = dashes;
+ }
+ break;
+ case SUBWMODE:
+ if (*num_params == 1)
+ {
+ if (XmuCompareISOLatin1(params[0], "clipbychildren") == 0)
+ retval = (void *)ClipByChildren;
+ else if (XmuCompareISOLatin1(params[0], "includeinferiors") == 0)
+ retval = (void *)IncludeInferiors;
+ }
+ break;
+ case EXPOSURES:
+ if (*num_params == 1)
+ {
+ if (isdigit(params[0][0]) || params[0][0] == '+' || params[0][0] == '-')
+ retval = (void *)read_int(params[0], NULL);
+ else if (XmuCompareISOLatin1(params[0], "true") == 0 ||
+ XmuCompareISOLatin1(params[0], "on") == 0)
+ retval = (void *)True;
+ else if (XmuCompareISOLatin1(params[0], "false") == 0 ||
+ XmuCompareISOLatin1(params[0], "off") == 0)
+ retval = (void *)False;
+ }
+ break;
+ case CLIPMASK:
+ if (*num_params == 1)
+ retval = (void *)XawLoadPixmap(params[0], screen, colormap, 1);
+ if (retval == NULL)
+ {
+ retval = XAWDL_CONVERT_ERROR;
+ XtDisplayStringConversionWarning(DisplayOfScreen(screen), (String)params[0],
+ XtRPixmap);
+ }
+ break;
+ case COPYAREA:
+ case COPYPLANE:
+ if (*num_params > 2 && *num_params <= 7 + (id == COPYPLANE))
+ {
+ XawDLCopyArgs *args = (XawDLCopyArgs *)
+ XtCalloc(1, sizeof(XawDLCopyArgs));
+
+ retval = args;
+ if (params[0][0] == '\0' || strcmp(params[0], ".") == 0)
+ args->pixmap = NULL;
+ else
+ {
+ args->pixmap = XawLoadPixmap(params[0], screen, colormap, id == COPYPLANE ? 1 : depth);
+ if (args->pixmap == NULL)
+ {
+ XtDisplayStringConversionWarning(DisplayOfScreen(screen), (String)params[0],
+ XtRBitmap);
+ retval = XAWDL_CONVERT_ERROR;
+ XtFree((char *)args);
+ }
+ }
+ if (retval != XAWDL_CONVERT_ERROR)
+ {
+ for (i = 1; i < *num_params && i < 7; i++)
+ read_position(params[i], &args->pos[i - 1]);
+ if (*num_params > 7)
+ args->plane = read_int(params[7], NULL);
+ }
+ }
+ break;
+ case IMAGE:
+ if (*num_params > 2 && *num_params <= 7)
+ {
+ XawDLImageArgs *args = (XawDLImageArgs *)
+ XtCalloc(1, sizeof(XawDLImageArgs));
+
+ retval = args;
+ args->pixmap = XawLoadPixmap(params[0], screen, colormap, depth);
+ if (args->pixmap == NULL)
+ {
+ XtDisplayStringConversionWarning(DisplayOfScreen(screen),
+ (String)params[0], XtRPixmap);
+ retval = XAWDL_CONVERT_ERROR;
+ XtFree((char *)args);
+ }
+ else
+ {
+ args->depth = depth;
+ for (i = 1; i < *num_params && i < 5; i++)
+ read_position(params[i], &args->pos[i - 1]);
+ }
+ }
+ break;
+ }
+
+ return (retval);
+}
+
+/* ARGSUSED */
+static void *
+_Xaw_Xlib_DataInitProc(String class_name,
+ Screen *screen, Colormap colormap, int depth)
+{
+ XawXlibData *data;
+ Window tmp_win;
+
+ data = (XawXlibData *)XtMalloc(sizeof(XawXlibData));
+
+ tmp_win = XCreateWindow(DisplayOfScreen(screen),
+ RootWindowOfScreen(screen),
+ 0, 0, 1, 1, 1, depth,
+ InputOutput, CopyFromParent, 0, NULL);
+ data->mask = 0;
+ data->gc = XCreateGC(DisplayOfScreen(screen), tmp_win, 0, &data->values);
+ XDestroyWindow(DisplayOfScreen(screen), tmp_win);
+ data->shape = Complex;
+ data->mode = CoordModeOrigin;
+ data->dashes = NULL;
+
+ return ((void *)data);
+}
+
+/* ARGSUSED */
+static void
+_Xaw_Xlib_ArgsDestructor(Display *display, String proc_name, XtPointer args,
+ String *params, Cardinal *num_params)
+{
+ Cardinal id;
+ Dl_init *init;
+
+ init = (Dl_init *)bsearch(proc_name, dl_init,
+ sizeof(dl_init) / sizeof(dl_init[0]),
+ sizeof(dl_init[0]),
+ bcmp_cvt_proc);
+
+ id = init->id;
+
+ switch (id)
+ {
+ case LINE:
+ case DRECT:
+ case FRECT:
+ case DARC:
+ case FARC:
+ case POINT:
+ case TSORIGIN:
+ case DASHES:
+ case CLIPORIGIN:
+ case COPYAREA:
+ case COPYPLANE:
+ case IMAGE:
+ XtFree(args);
+ break;
+ case DSTRING:
+ case PSTRING:
+ {
+ XawDLStringArgs *string = (XawDLStringArgs *)args;
+ XtFree(string->string);
+ XtFree(args);
+ } break;
+ case DLINES:
+ case FPOLY:
+ case POINTS:
+ case SEGMENTS:
+ case CLIPRECTS:
+ {
+ XawDLPositionPtr *ptr = (XawDLPositionPtr *)args;
+
+ XtFree((char *)ptr->pos);
+ XtFree(args);
+ } break;
+ }
+}
+
+/* ARGSUSED */
+static void
+_Xaw_Xlib_DataDestructor(Display *display, String class_name, XtPointer data)
+{
+ if (data)
+ {
+ XawXlibData *xdata = (XawXlibData *)data;
+
+ XFreeGC(display, xdata->gc);
+ if (xdata->dashes)
+ XtFree(xdata->dashes);
+ XtFree((char *)data);
+ }
+}
+
+/* Start of DLInfo Management Functions */
+static int
+qcmp_dlist_info(register _Xconst void *left, register _Xconst void *right)
+{
+ return (strcmp((*(XawDLInfo **)left)->name, (*(XawDLInfo **)right)->name));
+}
+
+Bool XawDeclareDisplayListProc(XawDLClass *lc, String name,
+ XawDisplayListProc proc)
+{
+ XawDLInfo *info;
+
+ if (!lc || !proc || !name || name[0] == '\0')
+ return (False);
+
+ if ((info = _XawFindDLInfo(lc, name)) != NULL)
+ /* Since the data structures to the displayList classes are(should be)
+ * opaque, it is not a good idea to allow overriding a displayList
+ * procedure; it's better to choose another name or class name!
+ */
+ return (False);
+
+ info = (XawDLInfo *)XtMalloc(sizeof(XawDLInfo));
+ info->name = XtNewString(name);
+ info->qname = XrmStringToQuark(info->name);
+ info->proc = proc;
+
+ if (!lc->num_infos)
+ {
+ lc->num_infos = 1;
+ lc->infos = (XawDLInfo **)XtMalloc(sizeof(XawDLInfo*));
+ }
+ else
+ {
+ ++lc->num_infos;
+ lc->infos = (XawDLInfo **)
+ XtRealloc((char *)lc->infos, sizeof(XawDLInfo*) * lc->num_infos);
+ }
+ lc->infos[lc->num_infos - 1] = info;
+
+ if (lc->num_infos > 1)
+ qsort(lc->infos, lc->num_infos, sizeof(XawDLInfo*), qcmp_dlist_info);
+
+ return (True);
+}
+
+static int
+bcmp_dlist_info(register _Xconst void *string,
+ register _Xconst void *dlinfo)
+{
+ return (strcmp((String)string, (*(XawDLClass **)dlinfo)->name));
+}
+
+static XawDLInfo *
+_XawFindDLInfo(XawDLClass *lc, String name)
+{
+ XawDLInfo **info;
+
+ if (!lc->infos)
+ return (NULL);
+
+ info = (XawDLInfo **)bsearch(name, lc->infos, lc->num_infos,
+ sizeof(XawDLInfo*), bcmp_dlist_info);
+
+ return (info ? *info : NULL);
+}
+
+/* Start of DLClass Management Functions */
+XawDLClass *
+XawGetDisplayListClass(String name)
+{
+ return (_XawFindDLClass(name));
+}
+
+static int
+qcmp_dlist_class(register _Xconst void *left, register _Xconst void *right)
+{
+ return (strcmp((*(XawDLClass **)left)->name, (*(XawDLClass **)right)->name));
+}
+
+XawDLClass *
+XawCreateDisplayListClass(String name,
+ XawDLArgsInitProc args_init,
+ XawDLArgsDestructor args_destructor,
+ XawDLDataInitProc data_init,
+ XawDLDataDestructor data_destructor)
+{
+ XawDLClass *lc;
+
+ if (!name || name[0] == '\0')
+ return (NULL);
+
+ lc = (XawDLClass *)XtMalloc(sizeof(XawDLClass));
+ lc->name = XtNewString(name);
+ lc->infos = NULL;
+ lc->num_infos = 0;
+ lc->args_init = args_init;
+ lc->args_destructor = args_destructor;
+ lc->data_init = data_init;
+ lc->data_destructor = data_destructor;
+
+ if (!classes)
+ {
+ num_classes = 1;
+ classes = (XawDLClass **)XtMalloc(sizeof(XawDLClass));
+ }
+ else
+ {
+ ++num_classes;
+ classes = (XawDLClass **)XtRealloc((char *)classes,
+ sizeof(XawDLClass) * num_classes);
+ }
+ classes[num_classes - 1] = lc;
+
+ if (num_classes > 1)
+ qsort(&classes[0], num_classes, sizeof(XawDLClass*), qcmp_dlist_class);
+
+ return (lc);
+}
+
+static int
+bcmp_dlist_class(register _Xconst void *string,
+ register _Xconst void *dlist)
+{
+ return (strcmp((String)string, (*(XawDLClass **)dlist)->name));
+}
+
+static XawDLClass *
+_XawFindDLClass(String name)
+{
+ XawDLClass **lc;
+
+ if (!classes)
+ return (NULL);
+
+ lc = (XawDLClass **)bsearch(name, &classes[0], num_classes,
+ sizeof(XawDLClass*), bcmp_dlist_class);
+
+ return (lc ? *lc : NULL);
+}
+
+#endif /* OLDXAW */
diff --git a/src/OS.c b/src/OS.c
new file mode 100644
index 0000000..e91f36d
--- /dev/null
+++ b/src/OS.c
@@ -0,0 +1,60 @@
+/* $XFree86: xc/lib/Xaw/OS.c,v 1.2 1998/12/06 11:24:32 dawes Exp $ */
+
+/* Some OS-dependent utility code */
+
+#include <X11/Xosdefs.h>
+#include <X11/IntrinsicP.h>
+#include "Private.h"
+
+#ifndef X_NOT_POSIX
+#include <unistd.h> /* for sysconf(), and getpagesize() */
+#endif
+
+#if defined(linux)
+#include <asm/page.h> /* for PAGE_SIZE */
+#define HAS_GETPAGESIZE
+#define HAS_SC_PAGESIZE /* _SC_PAGESIZE may be an enum for Linux */
+#endif
+
+#if defined(CSRG_BASED)
+#define HAS_GETPAGESIZE
+#endif
+
+#if defined(sun)
+#define HAS_GETPAGESIZE
+#endif
+
+int
+_XawGetPageSize()
+{
+ static int pagesize = -1;
+
+ if (pagesize != -1)
+ return pagesize;
+
+ /* Try each supported method in the preferred order */
+
+#if defined(_SC_PAGESIZE) || defined(HAS_SC_PAGESIZE)
+ pagesize = sysconf(_SC_PAGESIZE);
+#endif
+
+#ifdef _SC_PAGE_SIZE
+ if (pagesize == -1)
+ pagesize = sysconf(_SC_PAGE_SIZE);
+#endif
+
+#ifdef HAS_GETPAGESIZE
+ if (pagesize == -1)
+ pagesize = getpagesize();
+#endif
+
+#ifdef PAGE_SIZE
+ if (pagesize == -1)
+ pagesize = PAGE_SIZE;
+#endif
+
+ if (pagesize == -1)
+ pagesize = 0;
+
+ return pagesize;
+}
diff --git a/src/Pixmap.c b/src/Pixmap.c
new file mode 100644
index 0000000..feb0fc2
--- /dev/null
+++ b/src/Pixmap.c
@@ -0,0 +1,984 @@
+/*
+ * Copyright (c) 1998 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.
+ */
+
+/* $XFree86: xc/lib/Xaw/Pixmap.c,v 3.17 2002/05/18 02:05:39 paulo Exp $ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <X11/IntrinsicP.h>
+#include <X11/Xmu/CharSet.h>
+#include <X11/Xfuncs.h>
+#include <X11/extensions/shape.h>
+#include <X11/xpm.h>
+#include "Private.h"
+
+#ifndef OLDXAW
+
+/*
+ * Types
+ */
+typedef struct _XawCache {
+ long value;
+ XtPointer *elems;
+ unsigned int num_elems;
+} XawCache;
+
+typedef struct _XawPixmapLoaderInfo {
+ XawPixmapLoader loader;
+ String type;
+ String ext;
+} XawPixmapLoaderInfo;
+
+/*
+ * Private Methods
+ */
+static Bool BitmapLoader(XawParams*, Screen*, Colormap, int,
+ Pixmap*, Pixmap*, Dimension*, Dimension*);
+static Bool GradientLoader(XawParams*, Screen*, Colormap, int,
+ Pixmap*, Pixmap*, Dimension*, Dimension*);
+static Bool XPixmapLoader(XawParams*, Screen*, Colormap, int,
+ Pixmap*, Pixmap*, Dimension*, Dimension*);
+static XawPixmap *_XawFindPixmap(String, Screen*, Colormap, int);
+static void _XawCachePixmap(XawPixmap*, Screen*, Colormap, int);
+static int _XawFindPixmapLoaderIndex(String, String);
+static int qcmp_long(register _Xconst void*, register _Xconst void *);
+static int bcmp_long(register _Xconst void*, register _Xconst void *);
+static int qcmp_string(register _Xconst void*, register _Xconst void *);
+static int bcmp_string(register _Xconst void*, register _Xconst void *);
+static void GetResourcePixmapPath(Display*);
+
+/*
+ * Initialization
+ */
+static XawCache xaw_pixmaps;
+static XawCache x_pixmaps; /* for fast reverse search */
+static XawPixmapLoaderInfo **loader_info;
+static Cardinal num_loader_info;
+
+/*
+ * Implementation
+ */
+Bool
+XawPixmapsInitialize(void)
+{
+ static Boolean first_time = True;
+
+ if (!first_time)
+ return (False);
+
+ (void)XawAddPixmapLoader(NULL, NULL, BitmapLoader);
+ (void)XawAddPixmapLoader("bitmap", NULL, BitmapLoader);
+ (void)XawAddPixmapLoader("gradient", NULL, GradientLoader);
+ (void)XawAddPixmapLoader("xpm", "xpm", XPixmapLoader);
+
+ return (True);
+}
+
+XawParams *
+XawParseParamsString(String name)
+{
+ XawParams *xaw_params;
+ char *tok, *str, *type = NULL, *ext = NULL, *params = NULL;
+
+ if (!name)
+ return (NULL);
+
+ xaw_params = (XawParams *)XtMalloc(sizeof(XawParams));
+
+ str = XtNewString(name);
+
+ /* Find type */
+ tok = str;
+ while (tok = strchr(tok, ':'), tok)
+ {
+ if (tok == str || tok[-1] != '\\')
+ break;
+ memmove(&tok[-1], tok, strlen(tok) + 1);
+ }
+ if (tok)
+ {
+ *tok = '\0';
+ if (strchr(str, '?'))
+ {
+ *tok = ':';
+ }
+ else
+ {
+ ++tok;
+ type = XtNewString(str);
+ memmove(str, tok, strlen(tok) + 1);
+ }
+ }
+
+ /* Find params */
+ tok = str;
+ while (tok = strchr(tok, '?'), tok)
+ {
+ if (tok == str || tok[-1] != '\\')
+ params = tok;
+ if (tok != str && tok[-1] == '\\')
+ memmove(&tok[-1], tok, strlen(tok) + 1);
+ else
+ break;
+ }
+ if (params)
+ {
+ *params = '\0';
+ ++params;
+ }
+
+ /* Find ext */
+ tok = str;
+ while (tok = strchr(tok, '.'), tok)
+ {
+ if (tok == str || tok[-1] != '\\')
+ ext = tok;
+ if (tok != str && tok[-1] == '\\')
+ memmove(&tok[-1], tok, strlen(tok) + 1);
+ else
+ break;
+ }
+ if (ext)
+ {
+ ++ext;
+ if (strchr(ext, '/'))
+ ext = NULL;
+ }
+
+ xaw_params->name = XtNewString(str);
+ xaw_params->type = type;
+ xaw_params->ext = ext ? XtNewString(ext) : ext;
+ xaw_params->args = NULL;
+ xaw_params->num_args = 0;
+
+ /* Parse params */
+ if (params)
+ {
+ char *arg, *val;
+ XawArgVal *xaw_arg;
+
+ for (tok = strtok(params, "&"); tok; tok = strtok(NULL, "&"))
+ {
+ val = strchr(tok, '=');
+ if (val)
+ {
+ *val = '\0';
+ ++val;
+ if (*val != '\0')
+ val = XtNewString(val);
+ else
+ val = NULL;
+ }
+ arg = XtNewString(tok);
+ xaw_arg = (XawArgVal *)XtMalloc(sizeof(XawArgVal));
+ xaw_arg->name = arg;
+ xaw_arg->value = val;
+ if (!xaw_params->num_args)
+ {
+ xaw_params->num_args = 1;
+ xaw_params->args = (XawArgVal **)
+ XtMalloc(sizeof(XawArgVal*));
+ }
+ else
+ {
+ ++xaw_params->num_args;
+ xaw_params->args = (XawArgVal **)
+ XtRealloc((char *)xaw_params->args,
+ sizeof(XawArgVal*) * xaw_params->num_args);
+ }
+ xaw_params->args[xaw_params->num_args - 1] = xaw_arg;
+ }
+ }
+
+ if (xaw_params->num_args > 1)
+ qsort(xaw_params->args, xaw_params->num_args, sizeof(XtPointer),
+ qcmp_string);
+
+ XtFree(str);
+
+ return (xaw_params);
+}
+
+void
+XawFreeParamsStruct(XawParams *params)
+{
+ unsigned int i;
+
+ if (!params)
+ return;
+
+ for (i = 0; i < params->num_args; i++)
+ {
+ XtFree(params->args[i]->name);
+ if (params->args[i]->value)
+ XtFree(params->args[i]->value);
+ XtFree((char *)params->args[i]);
+ }
+
+ if (params->args)
+ XtFree((char *)params->args);
+ XtFree((char *)params);
+}
+
+XawArgVal *
+XawFindArgVal(XawParams *params, String name)
+{
+ XawArgVal **arg_val;
+
+ if (!params->args)
+ return (NULL);
+
+ arg_val = (XawArgVal **)bsearch((void *)name, params->args,
+ params->num_args, sizeof(XtPointer*),
+ bcmp_string);
+ if (!arg_val)
+ return (NULL);
+
+ return (*arg_val);
+}
+
+XawPixmap *
+XawLoadPixmap(String name, Screen *screen, Colormap colormap, int depth)
+{
+ int idx;
+ Bool success;
+ XawPixmap *xaw_pixmap;
+ Pixmap pixmap, mask;
+ Dimension width, height;
+ XawParams *xaw_params;
+
+ if (!name)
+ return (False);
+
+ xaw_pixmap = _XawFindPixmap(name, screen, colormap, depth);
+
+ if (xaw_pixmap)
+ return (xaw_pixmap);
+
+ if ((xaw_params = XawParseParamsString(name)) == NULL)
+ return (NULL);
+
+ idx = _XawFindPixmapLoaderIndex(xaw_params->type, xaw_params->ext);
+ if (idx < 0)
+ return (NULL);
+
+#ifdef DIAGNOSTIC
+ fprintf(stderr, "(*) Loading pixmap \"%s\": ", name);
+#endif
+
+ success = loader_info[idx]->loader(xaw_params, screen, colormap, depth,
+ &pixmap, &mask, &width, &height);
+ if (success)
+ {
+ xaw_pixmap = (XawPixmap *)XtMalloc(sizeof(XawPixmap));
+ xaw_pixmap->name = XtNewString(name);
+ xaw_pixmap->pixmap = pixmap;
+ xaw_pixmap->mask = mask;
+ xaw_pixmap->width = width;
+ xaw_pixmap->height = height;
+ _XawCachePixmap(xaw_pixmap, screen, colormap, depth);
+ }
+
+ XawFreeParamsStruct(xaw_params);
+
+#ifdef DIAGNOSTIC
+ fprintf(stderr, "%s", success ? "success\n" : "failed\n");
+#endif
+
+ return (success ? xaw_pixmap : NULL);
+}
+
+Bool
+XawAddPixmapLoader(String type, String ext, XawPixmapLoader loader)
+{
+ XawPixmapLoaderInfo *info;
+ int i;
+
+ if (!loader)
+ return (False);
+
+ i = _XawFindPixmapLoaderIndex(type, ext);
+
+ if (i >= 0)
+ {
+ loader_info[i]->loader = loader;
+ if (loader_info[i]->type)
+ XtFree(loader_info[i]->type);
+ if (loader_info[i]->ext)
+ XtFree(loader_info[i]->ext);
+ loader_info[i]->type = type ? XtNewString(type) : NULL;
+ loader_info[i]->ext = ext ? XtNewString(ext) : NULL;
+ return (True);
+ }
+
+ if ((info = (XawPixmapLoaderInfo *)XtMalloc(sizeof(XawPixmapLoaderInfo)))
+ == NULL)
+ return (False);
+
+ info->loader = loader;
+ info->type = type ? XtNewString(type) : NULL;
+ info->ext = ext ? XtNewString(ext) : NULL;
+
+ if (!loader_info)
+ {
+ num_loader_info = 1;
+ loader_info = (XawPixmapLoaderInfo**)
+ XtMalloc(sizeof(XawPixmapLoaderInfo*));
+ }
+ else
+ {
+ ++num_loader_info;
+ loader_info = (XawPixmapLoaderInfo**)
+ XtRealloc((char *)loader_info,
+ sizeof(XawPixmapLoaderInfo) * num_loader_info);
+ }
+ loader_info[num_loader_info - 1] = info;
+
+ return (True);
+}
+
+static int
+_XawFindPixmapLoaderIndex(String type, String ext)
+{
+ Cardinal i;
+
+ if (!loader_info)
+ return (-1);
+
+ for (i = 0; i < num_loader_info; i++)
+ if ((type && loader_info[i]->type && strcmp(type, loader_info[i]->type) == 0)
+ || (ext && loader_info[i]->ext && strcmp(ext, loader_info[i]->ext) == 0))
+ return ((int)i);
+
+ if (!type)
+ return (0); /* try a bitmap */
+
+ return (-1);
+}
+
+static int
+qcmp_x_cache(register _Xconst void *left, register _Xconst void *right)
+{
+ return ((int)((*(XawPixmap **)left)->pixmap) -
+ (int)((*(XawPixmap **)right)->pixmap));
+}
+
+static int
+bcmp_x_cache(register _Xconst void *pixmap, register _Xconst void *xaw)
+{
+ return (int)((long)pixmap - (long)((*(XawPixmap **)xaw)->pixmap));
+}
+
+static int
+qcmp_long(register _Xconst void *left, register _Xconst void *right)
+{
+ return ((long)((*(XawCache **)left)->value) -
+ (long)((*(XawCache **)right)->value));
+}
+
+static int
+qcmp_string(register _Xconst void *left, register _Xconst void *right)
+{
+ return (strcmp((String)((*(XawCache **)left)->value),
+ (String)((*(XawCache **)right)->value)));
+}
+
+static int
+bcmp_long(register _Xconst void *value, register _Xconst void *cache)
+{
+ return ((long)value - (long)((*(XawCache **)cache)->value));
+}
+
+static int
+bcmp_string(register _Xconst void *string,
+ register _Xconst void *cache)
+{
+ return (strcmp((String)string, (String)((*(XawCache **)cache)->value)));
+}
+
+#define FIND_ALL 0
+#define FIND_SCREEN 1
+#define FIND_COLORMAP 2
+#define FIND_DEPTH 3
+static XawCache *
+_XawFindCache(XawCache *xaw,
+ Screen *screen, Colormap colormap, int depth, int flags)
+{
+ XawCache **cache;
+
+ if (!xaw->num_elems)
+ return (NULL);
+
+ /* Screen */
+ cache = (XawCache **)bsearch(screen, xaw->elems,
+ xaw->num_elems, sizeof(XtPointer),
+ bcmp_long);
+ if (!cache || !(*cache)->num_elems)
+ return (NULL);
+ if (flags == FIND_SCREEN)
+ return (*cache);
+
+ /* Colormap */
+ cache = (XawCache **)bsearch((void *)colormap, (*cache)->elems,
+ (*cache)->num_elems, sizeof(XtPointer),
+ bcmp_long);
+ if (!cache || !(*cache)->num_elems)
+ return (NULL);
+ if (flags == FIND_COLORMAP)
+ return (*cache);
+
+ /* Depth */
+ cache = (XawCache **)bsearch((void *)(long)depth, (*cache)->elems,
+ (*cache)->num_elems, sizeof(XtPointer),
+ bcmp_long);
+
+ if (!cache || !(*cache)->num_elems)
+ return (NULL);
+ return (*cache);
+}
+
+static XawCache *
+_XawGetCache(XawCache *xaw, Screen *screen, Colormap colormap, int depth)
+{
+ XawCache *s_cache, *c_cache, *d_cache, *cache, *pcache;
+
+ cache = _XawFindCache(xaw, screen, colormap, depth, FIND_ALL);
+
+ if (!cache)
+ {
+ s_cache = _XawFindCache(xaw,
+ screen, colormap, depth, FIND_SCREEN);
+ if (!s_cache)
+ {
+ pcache = (XawCache *)XtMalloc(sizeof(XawCache));
+ if (!xaw->num_elems)
+ {
+ xaw->num_elems = 1;
+ xaw->elems = (XtPointer*)XtMalloc(sizeof(XtPointer));
+ }
+ else
+ {
+ ++xaw->num_elems;
+ xaw->elems = (XtPointer*)
+ XtRealloc((char *)xaw->elems,
+ sizeof(XtPointer) * xaw->num_elems);
+ }
+ pcache->value = (long)screen;
+ pcache->elems = NULL;
+ pcache->num_elems = 0;
+ xaw->elems[xaw->num_elems - 1] = (XtPointer)pcache;
+ s_cache = (XawCache *)xaw->elems[xaw->num_elems - 1];
+ if (xaw->num_elems > 1)
+ qsort(xaw->elems, xaw->num_elems, sizeof(XtPointer), qcmp_long);
+ }
+
+ c_cache = _XawFindCache(xaw,
+ screen, colormap, depth, FIND_COLORMAP);
+ if (!c_cache)
+ {
+ pcache = (XawCache *)XtMalloc(sizeof(XawCache));
+ if (!s_cache->num_elems)
+ {
+ s_cache->num_elems = 1;
+ s_cache->elems = (XtPointer*)XtMalloc(sizeof(XtPointer));
+ }
+ else
+ {
+ ++s_cache->num_elems;
+ s_cache->elems = (XtPointer*)
+ XtRealloc((char *)s_cache->elems,
+ sizeof(XtPointer) * s_cache->num_elems);
+ }
+ pcache->value = (long)colormap;
+ pcache->elems = NULL;
+ pcache->num_elems = 0;
+ s_cache->elems[s_cache->num_elems - 1] = (XtPointer)pcache;
+ c_cache = (XawCache *)s_cache->elems[s_cache->num_elems - 1];
+ if (s_cache->num_elems > 1)
+ qsort(s_cache->elems, s_cache->num_elems,
+ sizeof(XtPointer), qcmp_long);
+ }
+
+ d_cache = _XawFindCache(xaw,
+ screen, colormap, depth, FIND_DEPTH);
+ if (!d_cache)
+ {
+ pcache = (XawCache *)XtMalloc(sizeof(XawCache));
+ if (!c_cache->num_elems)
+ {
+ c_cache->num_elems = 1;
+ c_cache->elems = (XtPointer*)XtMalloc(sizeof(XtPointer));
+ }
+ else
+ {
+ ++c_cache->num_elems;
+ c_cache->elems = (XtPointer*)
+ XtRealloc((char *)c_cache->elems,
+ sizeof(XtPointer) * c_cache->num_elems);
+ }
+ pcache->value = (long)depth;
+ pcache->elems = NULL;
+ pcache->num_elems = 0;
+ c_cache->elems[c_cache->num_elems - 1] = (XtPointer)pcache;
+ d_cache = (XawCache *)c_cache->elems[c_cache->num_elems - 1];
+ if (c_cache->num_elems > 1)
+ qsort(c_cache->elems, c_cache->num_elems,
+ sizeof(XtPointer), qcmp_long);
+ }
+
+ cache = d_cache;
+ }
+
+ return (cache);
+}
+
+static XawPixmap *
+_XawFindPixmap(String name, Screen *screen, Colormap colormap, int depth)
+{
+ XawCache *cache;
+ XawPixmap **pixmap;
+
+ cache = _XawFindCache(&xaw_pixmaps, screen, colormap, depth, FIND_ALL);
+
+ if (!cache)
+ return (NULL);
+
+ /* Name */
+ pixmap = (XawPixmap **)bsearch((void *)name, cache->elems,
+ cache->num_elems, sizeof(XtPointer),
+ bcmp_string);
+ if (!pixmap)
+ return (NULL);
+
+ return (*pixmap);
+}
+
+XawPixmap *
+XawPixmapFromXPixmap(Pixmap pixmap,
+ Screen *screen, Colormap colormap, int depth)
+{
+ XawCache *cache;
+ XawPixmap **x_pixmap;
+
+ cache = _XawFindCache(&x_pixmaps, screen, colormap, depth, FIND_ALL);
+
+ if (!cache)
+ return (NULL);
+
+ /* Pixmap */
+ x_pixmap = (XawPixmap **)bsearch((void *)pixmap, cache->elems,
+ cache->num_elems, sizeof(XtPointer),
+ bcmp_x_cache);
+ if (!x_pixmap)
+ return (NULL);
+
+ return (*x_pixmap);
+}
+
+static void
+_XawCachePixmap(XawPixmap *pixmap,
+ Screen *screen, Colormap colormap, int depth)
+{
+ XawCache *xaw_cache, *x_cache;
+
+ xaw_cache = _XawGetCache(&xaw_pixmaps, screen, colormap, depth);
+ x_cache = _XawGetCache(&x_pixmaps, screen, colormap, depth);
+
+ if (!xaw_cache->num_elems)
+ {
+ xaw_cache->num_elems = 1;
+ xaw_cache->elems = (XtPointer*)XtMalloc(sizeof(XtPointer));
+ }
+ else
+ {
+ ++xaw_cache->num_elems;
+ xaw_cache->elems = (XtPointer*)XtRealloc((char *)xaw_cache->elems,
+ sizeof(XtPointer) *
+ xaw_cache->num_elems);
+ }
+
+ xaw_cache->elems[xaw_cache->num_elems - 1] = (XtPointer)pixmap;
+ if (xaw_cache->num_elems > 1)
+ qsort(xaw_cache->elems, xaw_cache->num_elems,
+ sizeof(XtPointer), qcmp_string);
+
+
+ if (!x_cache->num_elems)
+ {
+ x_cache->num_elems = 1;
+ x_cache->elems = (XtPointer*)XtMalloc(sizeof(XtPointer));
+ }
+ else
+ {
+ ++x_cache->num_elems;
+ x_cache->elems = (XtPointer*)XtRealloc((char *)x_cache->elems,
+ sizeof(XtPointer) *
+ x_cache->num_elems);
+ }
+
+ x_cache->elems[x_cache->num_elems - 1] = (XtPointer)pixmap;
+ if (x_cache->num_elems > 1)
+ qsort(x_cache->elems, x_cache->num_elems, sizeof(XtPointer), qcmp_x_cache);
+}
+
+#ifndef PROJECT_ROOT
+#define PROJECT_ROOT "/usr/X11R6"
+#endif
+
+static char *pixmap_path = NULL;
+
+static void
+GetResourcePixmapPath(Display *display)
+{
+ XrmName xrm_name[2];
+ XrmClass xrm_class[2];
+ XrmRepresentation rep_type;
+ XrmValue value;
+ static char *default_path =
+ "%H/%T/%N:%P/include/X11/%T/%N:/usr/X11R6/include/X11/%T/%N:/usr/include/X11/%T/%N:%N";
+
+ xrm_name[0] = XrmPermStringToQuark("pixmapFilePath");
+ xrm_name[1] = NULLQUARK;
+ xrm_class[0] = XrmPermStringToQuark("PixmapFilePath");
+ xrm_class[1] = NULLQUARK;
+ if (!XrmGetDatabase(display))
+ (void) XGetDefault(display, "", "");
+ if (XrmQGetResource(XrmGetDatabase(display), xrm_name, xrm_class,
+ &rep_type, &value) &&
+ rep_type == XrmPermStringToQuark("String")) {
+ int length = 0;
+ char *tok, *buffer = XtNewString(value.addr);
+
+ for (tok = strtok(buffer, ":"); tok; tok = strtok(NULL, ":")) {
+ int toklen = strlen(tok);
+
+ if (toklen) {
+ pixmap_path = XtRealloc(pixmap_path, length + toklen + 5);
+ strcpy(pixmap_path + length, tok);
+ if (length)
+ pixmap_path[length++] = ':';
+ sprintf(pixmap_path + length, "%s/%%N", tok);
+ length += strlen(tok) + 3;
+ }
+ }
+ pixmap_path = XtRealloc(pixmap_path, length + strlen(default_path) + 2);
+ if (length)
+ pixmap_path[length++] = ':';
+ strcpy(pixmap_path + length, default_path);
+ }
+ else
+ pixmap_path = default_path;
+}
+
+static Bool
+BitmapLoader(XawParams *params, Screen *screen, Colormap colormap, int depth,
+ Pixmap *pixmap_return, Pixmap *mask_return,
+ Dimension *width_return, Dimension *height_return)
+{
+ Pixel fg, bg;
+ XColor color, exact;
+ Pixmap pixmap;
+ unsigned int width, height;
+ unsigned char *data = NULL;
+ int hotX, hotY;
+ XawArgVal *argval;
+ Bool retval = False;
+ static SubstitutionRec sub[] = {
+ {'H', NULL},
+ {'N', NULL},
+ {'T', "bitmaps"},
+ {'P', PROJECT_ROOT},
+ };
+ char *filename;
+
+ fg = BlackPixelOfScreen(screen);
+ bg = WhitePixelOfScreen(screen);
+
+ if ((argval = XawFindArgVal(params, "foreground")) != NULL
+ && argval->value)
+ {
+ if (XAllocNamedColor(DisplayOfScreen(screen), colormap, argval->value,
+ &color, &exact))
+ fg = color.pixel;
+ else
+ return (False);
+ }
+ if ((argval = XawFindArgVal(params, "background")) != NULL
+ && argval->value)
+ {
+ if (XAllocNamedColor(DisplayOfScreen(screen), colormap, argval->value,
+ &color, &exact))
+ bg = color.pixel;
+ else
+ return (False);
+ }
+
+ if (params->name[0] != '/' && params->name[0] != '.')
+ {
+ if (!sub[0].substitution)
+ sub[0].substitution = getenv("HOME");
+ sub[1].substitution = params->name;
+ if (pixmap_path == NULL)
+ GetResourcePixmapPath(DisplayOfScreen(screen));
+ filename = XtFindFile(pixmap_path, sub, XtNumber(sub), NULL);
+ if (!filename)
+ return (FALSE);
+ }
+ else
+ filename = params->name;
+
+ if (XReadBitmapFileData(filename, &width, &height, &data,
+ &hotX, &hotY) == BitmapSuccess)
+ {
+ pixmap = XCreatePixmapFromBitmapData(DisplayOfScreen(screen),
+ RootWindowOfScreen(screen),
+ (char *)data,
+ width, height, fg, bg, depth);
+ if (data)
+ XFree(data);
+ *pixmap_return = pixmap;
+ *mask_return = None;
+ *width_return = width;
+ *height_return = height;
+
+ retval = True;
+ }
+
+ if (filename != params->name)
+ XtFree(filename);
+
+ return (retval);
+}
+
+#define VERTICAL 1
+#define HORIZONTAL 2
+static Bool
+GradientLoader(XawParams *params, Screen *screen, Colormap colormap, int depth,
+ Pixmap *pixmap_return, Pixmap *mask_return,
+ Dimension *width_return, Dimension *height_return)
+{
+ double ired, igreen, iblue, red, green, blue;
+ XColor start, end, color;
+ XGCValues values;
+ GC gc;
+ double i, inc, x, y, xend, yend;
+ Pixmap pixmap;
+ XawArgVal *argval;
+ int orientation, dimension, steps;
+ char *value;
+
+ if (XmuCompareISOLatin1(params->name, "vertical") == 0)
+ orientation = VERTICAL;
+ else if (XmuCompareISOLatin1(params->name, "horizontal") == 0)
+ orientation = HORIZONTAL;
+ else
+ return (False);
+
+ if ((argval = XawFindArgVal(params, "dimension")) != NULL
+ && argval->value)
+ {
+ dimension = atoi(argval->value);
+ if (dimension <= 0)
+ return (False);
+ }
+ else
+ dimension = 50;
+
+ if ((argval = XawFindArgVal(params, "steps")) != NULL
+ && argval->value)
+ {
+ steps = atoi(argval->value);
+ if (steps <= 0)
+ return (False);
+ }
+ else
+ steps = dimension;
+
+ steps = XawMin(steps, dimension);
+
+ value = NULL;
+ if ((argval = XawFindArgVal(params, "start")) != NULL)
+ value = argval->value;
+ if (value && !XAllocNamedColor(DisplayOfScreen(screen), colormap, value,
+ &start, &color))
+ return (False);
+ else if (!value)
+ {
+ start.pixel = WhitePixelOfScreen(screen);
+ XQueryColor(DisplayOfScreen(screen), colormap, &start);
+ }
+ value = NULL;
+ if ((argval = XawFindArgVal(params, "end")) != NULL)
+ value = argval->value;
+ if (value && !XAllocNamedColor(DisplayOfScreen(screen), colormap, value,
+ &end, &color))
+ return (False);
+ else if (!value)
+ {
+ end.pixel = BlackPixelOfScreen(screen);
+ XQueryColor(DisplayOfScreen(screen), colormap, &end);
+ }
+
+ if ((pixmap = XCreatePixmap(DisplayOfScreen(screen),
+ RootWindowOfScreen(screen),
+ orientation == VERTICAL ? 1 : dimension,
+ orientation == VERTICAL ? dimension : 1, depth))
+ == 0)
+ return (False);
+
+ ired = (double)(end.red - start.red) / (double)steps;
+ igreen = (double)(end.green - start.green) / (double)steps;
+ iblue = (double)(end.blue - start.blue) / (double)steps;
+
+ red = color.red = start.red;
+ green = color.green = start.green;
+ blue = color.blue = start.blue;
+
+ inc = (double)dimension / (double)steps;
+
+ gc = XCreateGC(DisplayOfScreen(screen), pixmap, 0, &values);
+
+ x = y = 0.0;
+ if (orientation == VERTICAL)
+ {
+ xend = 1;
+ yend = 0;
+ }
+ else
+ {
+ xend = 0;
+ yend = 1;
+ }
+
+ color.flags = DoRed | DoGreen | DoBlue;
+
+ XSetForeground(DisplayOfScreen(screen), gc, start.pixel);
+ for (i = 0.0; i < dimension; i += inc)
+ {
+ if ((int)color.red != (int)red || (int)color.green != (int)green
+ || (int)color.blue != (int)blue)
+ {
+ XFillRectangle(DisplayOfScreen(screen), pixmap, gc, (int)x, (int)y,
+ (unsigned int)xend, (unsigned int)yend);
+ color.red = (unsigned short)red;
+ color.green = (unsigned short)green;
+ color.blue = (unsigned short)blue;
+ if (!XAllocColor(DisplayOfScreen(screen), colormap, &color))
+ {
+ XFreePixmap(DisplayOfScreen(screen), pixmap);
+ return (False);
+ }
+ XSetForeground(DisplayOfScreen(screen), gc, color.pixel);
+ if (orientation == VERTICAL)
+ y = yend;
+ else
+ x = xend;
+ }
+ red += ired;
+ green += igreen;
+ blue += iblue;
+ if (orientation == VERTICAL)
+ yend += inc;
+ else
+ xend += inc;
+ }
+ XFillRectangle(DisplayOfScreen(screen), pixmap, gc, (int)x, (int)y,
+ (unsigned int)xend, (unsigned int)yend);
+
+ *pixmap_return = pixmap;
+ *mask_return = None;
+ *width_return = orientation == VERTICAL ? 1 : dimension;
+ *height_return = orientation == VERTICAL ? dimension : 1;
+
+ XFreeGC(DisplayOfScreen(screen), gc);
+
+ return (True);
+}
+
+static Bool
+XPixmapLoader(XawParams *params, Screen *screen, Colormap colormap, int depth,
+ Pixmap *pixmap_return, Pixmap *mask_return,
+ Dimension *width_return, Dimension *height_return)
+{
+ XpmAttributes xpm_attributes;
+ XawArgVal *argval;
+ unsigned int closeness = 4000;
+ static SubstitutionRec sub[] = {
+ {'H', NULL},
+ {'N', NULL},
+ {'T', "pixmaps"},
+ {'P', PROJECT_ROOT},
+ };
+ char *filename;
+
+ if ((argval = XawFindArgVal(params, "closeness")) != NULL
+ && argval->value)
+ closeness = atoi(argval->value);
+
+ if (params->name[0] != '/' && params->name[0] != '.')
+ {
+ if (!sub[0].substitution)
+ sub[0].substitution = getenv("HOME");
+ sub[1].substitution = params->name;
+ if (pixmap_path == NULL)
+ GetResourcePixmapPath(DisplayOfScreen(screen));
+ filename = XtFindFile(pixmap_path, sub, XtNumber(sub), NULL);
+ if (!filename)
+ return (False);
+ }
+ else
+ filename = params->name;
+
+ xpm_attributes.colormap = colormap;
+ xpm_attributes.closeness = closeness;
+ xpm_attributes.valuemask = XpmSize | XpmColormap | XpmCloseness;
+ if (XpmReadFileToPixmap(DisplayOfScreen(screen),
+ RootWindowOfScreen(screen), filename, pixmap_return,
+ mask_return, &xpm_attributes) == XpmSuccess)
+ {
+ *width_return = xpm_attributes.width;
+ *height_return = xpm_attributes.height;
+
+ return (True);
+ }
+
+ return (False);
+}
+
+void
+XawReshapeWidget(Widget w, XawPixmap *pixmap)
+{
+ if (!pixmap || pixmap->mask == None)
+ XShapeCombineMask(XtDisplay(w), XtWindow(w), ShapeBounding, 0, 0,
+ None, ShapeSet);
+ else
+ XShapeCombineMask(XtDisplay(w), XtWindow(w), ShapeBounding, 0, 0,
+ pixmap->mask, ShapeSet);
+}
+
+#endif /* OLDXAW */
diff --git a/src/Private.h b/src/Private.h
new file mode 100644
index 0000000..5bdf73c
--- /dev/null
+++ b/src/Private.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 1998 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.
+ */
+
+/* $XFree86: xc/lib/Xaw/Private.h,v 3.10 1999/06/06 08:48:07 dawes Exp $ */
+
+#ifndef _XawPrivate_h
+#define _XawPrivate_h
+
+#define XawMax(a, b) ((a) > (b) ? (a) : (b))
+#define XawMin(a, b) ((a) < (b) ? (a) : (b))
+#define XawAbs(a) ((a) < 0 ? -(a) : (a))
+
+#define XawStackAlloc(size, stk_buffer) \
+((size) <= sizeof(stk_buffer) \
+ ? (XtPointer)(stk_buffer) \
+ : XtMalloc((unsigned)(size)))
+
+#define XawStackFree(pointer, stk_buffer) \
+do { \
+ if ((pointer) != (XtPointer)(stk_buffer)) \
+ XtFree((char *)pointer); \
+} while (0)
+
+#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
+
+#ifndef OLDXAW
+#define XAW_PRIV_VAR_PREFIX '$'
+
+typedef Bool (*XawParseBooleanProc)(Widget, String, XEvent*, Bool*);
+
+typedef struct _XawActionVarList XawActionVarList;
+typedef struct _XawActionResList XawActionResList;
+
+/* Boolean expressions */
+Bool XawParseBoolean(Widget, String, XEvent*, Bool*);
+Bool XawBooleanExpression(Widget, String, XEvent*);
+
+/* actions */
+void XawPrintActionErrorMsg(String, Widget, String*, Cardinal*);
+XawActionResList *XawGetActionResList(WidgetClass);
+XawActionVarList *XawGetActionVarList(Widget);
+
+void XawSetValuesAction(Widget, XEvent*, String*, Cardinal*);
+void XawGetValuesAction(Widget, XEvent*, String*, Cardinal*);
+void XawDeclareAction(Widget, XEvent*, String*, Cardinal*);
+void XawCallProcAction(Widget, XEvent*, String*, Cardinal*);
+
+/* display lists */
+#define XAWDL_CONVERT_ERROR (XtPointer)-1
+typedef struct _XawDL _XawDisplayList;
+typedef struct _XawDLClass XawDLClass, XawDisplayListClass;
+
+typedef void (*XawDisplayListProc)(Widget, XtPointer, XtPointer,
+ XEvent*, Region);
+typedef void *(*XawDLArgsInitProc)(String, String*, Cardinal*,
+ Screen*, Colormap, int);
+typedef void *(*XawDLDataInitProc)(String,
+ Screen*, Colormap, int);
+typedef void (*XawDLArgsDestructor)(Display*, String, XtPointer,
+ String*, Cardinal*);
+typedef void (*XawDLDataDestructor)(Display*, String, XtPointer);
+
+void XawRunDisplayList(Widget, _XawDisplayList*, XEvent*, Region);
+void XawDisplayListInitialize(void);
+
+_XawDisplayList *XawCreateDisplayList(String, Screen*, Colormap, int);
+void XawDestroyDisplayList(_XawDisplayList*);
+String XawDisplayListString(_XawDisplayList*);
+XawDLClass *XawGetDisplayListClass(String);
+XawDLClass *XawCreateDisplayListClass(String,
+ XawDLArgsInitProc, XawDLArgsDestructor,
+ XawDLDataInitProc, XawDLDataDestructor);
+Bool XawDeclareDisplayListProc(XawDLClass*, String, XawDisplayListProc);
+
+/* pixmaps */
+typedef struct _XawArgVal {
+ String name;
+ String value;
+} XawArgVal;
+
+typedef struct _XawParams {
+ String name;
+ String type;
+ String ext;
+ XawArgVal **args;
+ Cardinal num_args;
+} XawParams;
+
+typedef struct _XawPixmap {
+ String name;
+ Pixmap pixmap;
+ Pixmap mask;
+ Dimension width;
+ Dimension height;
+} XawPixmap;
+
+typedef Bool (*XawPixmapLoader)(XawParams*, Screen*, Colormap, int,
+ Pixmap*, Pixmap*,
+ Dimension*, Dimension*);
+Bool XawPixmapsInitialize(void);
+Bool XawAddPixmapLoader(String, String, XawPixmapLoader);
+XawPixmap *XawLoadPixmap(String, Screen*, Colormap, int);
+XawPixmap *XawPixmapFromXPixmap(Pixmap, Screen*, Colormap, int);
+XawParams *XawParseParamsString(String name);
+void XawFreeParamsStruct(XawParams *params);
+XawArgVal *XawFindArgVal(XawParams *params, String name);
+void XawReshapeWidget(Widget, XawPixmap*);
+#endif /* OLDXAW */
+
+/* misc */
+void XawTypeToStringWarning(Display*, String);
+
+/* OS.c */
+int _XawGetPageSize(void);
+
+#endif /* _XawPrivate_h */
diff --git a/src/Tip.c b/src/Tip.c
new file mode 100644
index 0000000..761492a
--- /dev/null
+++ b/src/Tip.c
@@ -0,0 +1,631 @@
+/*
+ * 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.c,v 1.5 2000/05/18 16:29:53 dawes Exp $ */
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xos.h>
+#include <X11/Xaw/TipP.h>
+#include <X11/Xaw/XawInit.h>
+#include <X11/Xmu/Converters.h>
+#include "Private.h"
+
+#define TIP_EVENT_MASK (ButtonPressMask | \
+ ButtonReleaseMask | \
+ PointerMotionMask | \
+ ButtonMotionMask | \
+ KeyPressMask | \
+ KeyReleaseMask | \
+ EnterWindowMask | \
+ LeaveWindowMask)
+
+/*
+ * Types
+ */
+typedef struct _XawTipInfo {
+ Screen *screen;
+ TipWidget tip;
+ Widget widget;
+ Bool mapped;
+ struct _XawTipInfo *next;
+} XawTipInfo;
+
+/*
+ * Class Methods
+ */
+static void XawTipClassInitialize(void);
+static void XawTipInitialize(Widget, Widget, ArgList, Cardinal*);
+static void XawTipDestroy(Widget);
+static void XawTipExpose(Widget, XEvent*, Region);
+static void XawTipRealize(Widget, Mask*, XSetWindowAttributes*);
+static Boolean XawTipSetValues(Widget, Widget, Widget, ArgList, Cardinal*);
+
+/*
+ * Prototypes
+ */
+static void TipEventHandler(Widget, XtPointer, XEvent*, Boolean*);
+static void TipShellEventHandler(Widget, XtPointer, XEvent*, Boolean*);
+static XawTipInfo *CreateTipInfo(Widget);
+static XawTipInfo *FindTipInfo(Widget);
+static void ResetTip(XawTipInfo*, Bool);
+static void TipTimeoutCallback(XtPointer, XtIntervalId*);
+static void TipLayout(XawTipInfo*);
+static void TipPosition(XawTipInfo*);
+
+/*
+ * 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
+ },
+ {
+ XtNfontSet,
+ XtCFontSet,
+ XtRFontSet,
+ sizeof(XFontSet),
+ offset(fontset),
+ XtRString,
+ XtDefaultFontSet
+ },
+ {
+ XtNtopMargin,
+ XtCVerticalMargins,
+ XtRDimension,
+ sizeof(Dimension),
+ offset(top_margin),
+ XtRImmediate,
+ (XtPointer)2
+ },
+ {
+ XtNbottomMargin,
+ XtCVerticalMargins,
+ XtRDimension,
+ sizeof(Dimension),
+ offset(bottom_margin),
+ XtRImmediate,
+ (XtPointer)2
+ },
+ {
+ XtNleftMargin,
+ XtCHorizontalMargins,
+ XtRDimension,
+ sizeof(Dimension),
+ offset(left_margin),
+ XtRImmediate,
+ (XtPointer)6
+ },
+ {
+ XtNrightMargin,
+ XtCHorizontalMargins,
+ XtRDimension,
+ sizeof(Dimension),
+ offset(right_margin),
+ XtRImmediate,
+ (XtPointer)6
+ },
+ {
+ XtNbackingStore,
+ XtCBackingStore,
+ XtRBackingStore,
+ sizeof(int),
+ offset(backing_store),
+ XtRImmediate,
+ (XtPointer)(Always + WhenMapped + NotUseful)
+ },
+ {
+ XtNtimeout,
+ XtCTimeout,
+ XtRInt,
+ sizeof(int),
+ offset(timeout),
+ XtRImmediate,
+ (XtPointer)500
+ },
+ {
+ XawNdisplayList,
+ XawCDisplayList,
+ XawRDisplayList,
+ sizeof(XawDisplayList*),
+ offset(display_list),
+ XtRImmediate,
+ NULL
+ },
+};
+#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 *first_tip;
+
+/*
+ * Implementation
+ */
+static void
+XawTipClassInitialize(void)
+{
+ XawInitializeWidgetSet();
+ XtAddConverter(XtRString, XtRBackingStore, XmuCvtStringToBackingStore,
+ NULL, 0);
+ XtSetTypeConverter(XtRBackingStore, XtRString, XmuCvtBackingStoreToString,
+ NULL, 0, XtCacheNone, NULL);
+}
+
+/*ARGSUSED*/
+static void
+XawTipInitialize(Widget req, Widget 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(Widget w)
+{
+ XawTipInfo *info = FindTipInfo(w);
+ 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);
+ if (info == first_tip)
+ first_tip = first_tip->next;
+ else {
+ XawTipInfo *p = first_tip;
+
+ while (p && p->next != info)
+ p = p->next;
+ if (p)
+ p->next = info->next;
+ }
+ XtFree((char*)info);
+}
+
+static void
+XawTipRealize(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(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.top_margin + tip->tip.font->max_bounds.ascent;
+ int len;
+
+ if (tip->tip.display_list)
+ XawRunDisplayList(w, tip->tip.display_list, event, region);
+
+ if (tip->tip.international == True) {
+ Position ksy = tip->tip.top_margin;
+ XFontSetExtents *ext = XExtentsOfFontSet(tip->tip.fontset);
+
+ ksy += XawAbs(ext->max_ink_extent.y);
+
+ while ((nl = index(label, '\n')) != NULL) {
+ XmbDrawString(XtDisplay(w), XtWindow(w), tip->tip.fontset,
+ gc, tip->tip.left_margin, 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.left_margin, ksy, label, len);
+ }
+ else {
+ while ((nl = index(label, '\n')) != NULL) {
+ if (tip->tip.encoding)
+ XDrawString16(XtDisplay(w), XtWindow(w), gc,
+ tip->tip.left_margin, y,
+ (XChar2b*)label, (int)(nl - label) >> 1);
+ else
+ XDrawString(XtDisplay(w), XtWindow(w), gc,
+ tip->tip.left_margin, 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.left_margin, y, (XChar2b*)label, len >> 1);
+ else
+ XDrawString(XtDisplay(w), XtWindow(w), gc,
+ tip->tip.left_margin, y, label, len);
+ }
+ }
+}
+
+/*ARGSUSED*/
+static Boolean
+XawTipSetValues(Widget current, Widget request, Widget 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;
+ }
+ if (curtip->tip.display_list != newtip->tip.display_list)
+ redisplay = True;
+
+ return (redisplay);
+}
+
+static void
+TipLayout(XawTipInfo *info)
+{
+ XFontStruct *fs = info->tip->tip.font;
+ int width = 0, height;
+ char *nl, *label = info->tip->tip.label;
+
+ 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 {
+ 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.left_margin +
+ info->tip->tip.right_margin;
+ XtHeight(info->tip) = height + info->tip->tip.top_margin +
+ info->tip->tip.bottom_margin;
+}
+
+#define DEFAULT_TIP_Y_OFFSET 12
+static void
+TipPosition(XawTipInfo *info)
+{
+ Window r, c;
+ int rx, ry, wx, wy;
+ unsigned mask;
+ Position x, y;
+
+ XQueryPointer(XtDisplay((Widget)info->tip), XtWindow((Widget)info->tip),
+ &r, &c, &rx, &ry, &wx, &wy, &mask);
+ x = rx - (XtWidth(info->tip) >> 1);
+ y = ry + DEFAULT_TIP_Y_OFFSET;
+
+ if (x >= 0) {
+ int scr_width = WidthOfScreen(XtScreen(info->tip));
+
+ if (x + XtWidth(info->tip) + XtBorderWidth(info->tip) > scr_width)
+ x = scr_width - XtWidth(info->tip) - XtBorderWidth(info->tip);
+ }
+ if (x < 0)
+ x = 0;
+ if (y >= 0) {
+ int scr_height = HeightOfScreen(XtScreen(info->tip));
+
+ if (y + XtHeight(info->tip) + XtBorderWidth(info->tip) > scr_height)
+ y -= XtHeight(info->tip) + XtBorderWidth(info->tip) +
+ (DEFAULT_TIP_Y_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 XawTipInfo *
+CreateTipInfo(Widget w)
+{
+ XawTipInfo *info = XtNew(XawTipInfo);
+ Widget shell = w;
+
+ info->screen = XtScreen(w);
+
+ while (XtParent(shell))
+ shell = XtParent(shell);
+
+ info->tip = (TipWidget)XtCreateWidget("tip", tipWidgetClass, shell, NULL, 0);
+ XtRealizeWidget((Widget)info->tip);
+ info->widget = NULL;
+ info->mapped = False;
+ info->next = NULL;
+ XtAddEventHandler(shell, KeyPressMask, False, TipShellEventHandler,
+ (XtPointer)NULL);
+
+ return (info);
+}
+
+static XawTipInfo *
+FindTipInfo(Widget w)
+{
+ XawTipInfo *ptip, *tip = first_tip;
+ Screen *screen = XtScreenOfObject(w);
+
+ if (tip == NULL)
+ return (first_tip = tip = CreateTipInfo(w));
+
+ for (ptip = tip; tip; ptip = tip, tip = tip->next)
+ if (tip->screen == screen)
+ return (tip);
+
+ return (ptip->next = CreateTipInfo(w));
+}
+
+static void
+ResetTip(XawTipInfo *info, 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) {
+ info->tip->tip.timer =
+ XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)info->tip),
+ info->tip->tip.timeout, TipTimeoutCallback,
+ (XtPointer)info);
+ }
+}
+
+static void
+TipTimeoutCallback(XtPointer closure, XtIntervalId *id)
+{
+ XawTipInfo *info = (XawTipInfo*)closure;
+ Arg args[3];
+
+ info->tip->tip.label = NULL;
+ info->tip->tip.international = False;
+ info->tip->tip.encoding = 0;
+ XtSetArg(args[0], XtNtip, &info->tip->tip.label);
+ XtSetArg(args[1], XtNinternational, &info->tip->tip.international);
+ XtSetArg(args[2], XtNencoding, &info->tip->tip.encoding);
+ XtGetValues(info->widget, args, 3);
+
+ if (info->tip->tip.label) {
+ 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(Widget w, XtPointer client_data, XEvent *event,
+ Boolean *continue_to_dispatch)
+{
+ ResetTip(FindTipInfo(w), False);
+}
+
+/*ARGSUSED*/
+static void
+TipEventHandler(Widget w, XtPointer client_data, XEvent *event,
+ Boolean *continue_to_dispatch)
+{
+ XawTipInfo *info = FindTipInfo(w);
+ Boolean add_timeout;
+
+ if (info->widget != w) {
+ ResetTip(info, False);
+ info->widget = w;
+ }
+
+ 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, add_timeout);
+}
+
+/*
+ * Public routines
+ */
+void
+XawTipEnable(Widget w)
+{
+ XtAddEventHandler(w, TIP_EVENT_MASK, False, TipEventHandler,
+ (XtPointer)NULL);
+}
+
+void
+XawTipDisable(Widget w)
+{
+ XawTipInfo *info = FindTipInfo(w);
+
+ XtRemoveEventHandler(w, TIP_EVENT_MASK, False, TipEventHandler,
+ (XtPointer)NULL);
+ if (info->widget == w)
+ ResetTip(info, False);
+}