1830 lines
48 KiB
C
1830 lines
48 KiB
C
/* $Xorg: TextSink.c,v 1.4 2001/02/09 02:03:46 xorgcvs Exp $ */
|
|
/*
|
|
|
|
Copyright 1989, 1994, 1998 The Open Group
|
|
|
|
Permission to use, copy, modify, distribute, and sell this software and its
|
|
documentation for any purpose is hereby granted without fee, provided that
|
|
the above copyright notice appear in all copies and that both that
|
|
copyright notice and this permission notice appear in supporting
|
|
documentation.
|
|
|
|
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
|
|
OPEN GROUP 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 Open Group 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 Open Group.
|
|
|
|
*/
|
|
/* $XFree86: xc/lib/Xaw/TextSink.c,v 1.21 2002/06/03 21:39:24 paulo Exp $ */
|
|
|
|
/*
|
|
* Author: Chris Peterson, MIT X Consortium.
|
|
*
|
|
* Much code taken from X11R3 AsciiSink.
|
|
*/
|
|
|
|
/*
|
|
* TextSink.c - TextSink object. (For use with the text widget).
|
|
*
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <ctype.h>
|
|
#include <X11/IntrinsicP.h>
|
|
#include <X11/StringDefs.h>
|
|
#include <X11/Xaw/TextP.h>
|
|
#include <X11/Xaw/TextSinkP.h>
|
|
#include <X11/Xaw/XawInit.h>
|
|
#include "Private.h"
|
|
|
|
/*
|
|
* Prototypes
|
|
*/
|
|
static void XawTextSinkClassPartInitialize(WidgetClass);
|
|
static void XawTextSinkInitialize(Widget, Widget, ArgList, Cardinal*);
|
|
static void XawTextSinkDestroy(Widget);
|
|
static Boolean XawTextSinkSetValues(Widget, Widget, Widget,
|
|
ArgList, Cardinal*);
|
|
|
|
static int MaxLines(Widget, unsigned int);
|
|
static int MaxHeight(Widget, int);
|
|
static void DisplayText(Widget, int, int, XawTextPosition, XawTextPosition,
|
|
Bool);
|
|
static void InsertCursor(Widget, int, int, XawTextInsertState);
|
|
static void ClearToBackground(Widget, int, int, unsigned int, unsigned int);
|
|
static void FindPosition(Widget, XawTextPosition, int, int, Bool,
|
|
XawTextPosition*, int*, int*);
|
|
static void FindDistance(Widget, XawTextPosition, int, XawTextPosition, int*,
|
|
XawTextPosition*, int*);
|
|
static void Resolve(Widget, XawTextPosition, int, int, XawTextPosition*);
|
|
static void SetTabs(Widget, int, short*);
|
|
static void GetCursorBounds(Widget, XRectangle*);
|
|
|
|
#ifndef OLDXAW
|
|
static Boolean CvtStringToPropertyList(Display*, XrmValue*, Cardinal*,
|
|
XrmValue*, XrmValue*, XtPointer*);
|
|
static Boolean CvtPropertyListToString(Display*, XrmValue*, Cardinal*,
|
|
XrmValue*, XrmValue*, XtPointer*);
|
|
static Bool BeginPaint(Widget);
|
|
static Bool EndPaint(Widget);
|
|
static void SetXlfdDefaults(Display*, XawTextProperty*);
|
|
#endif
|
|
|
|
/*
|
|
* External
|
|
*/
|
|
void _XawTextSinkClearToBackground(Widget, int, int, unsigned, unsigned);
|
|
void _XawTextSinkDisplayText(Widget, int, int, XawTextPosition, XawTextPosition,
|
|
Bool);
|
|
|
|
/*
|
|
* Initialization
|
|
*/
|
|
#define offset(field) XtOffsetOf(TextSinkRec, text_sink.field)
|
|
static XtResource resources[] = {
|
|
{
|
|
XtNforeground,
|
|
XtCForeground,
|
|
XtRPixel,
|
|
sizeof(Pixel),
|
|
offset(foreground),
|
|
XtRString,
|
|
XtDefaultForeground
|
|
},
|
|
{
|
|
XtNbackground,
|
|
XtCBackground,
|
|
XtRPixel,
|
|
sizeof(Pixel),
|
|
offset(background),
|
|
XtRString,
|
|
XtDefaultBackground
|
|
},
|
|
#ifndef OLDXAW
|
|
{
|
|
XtNcursorColor,
|
|
XtCColor,
|
|
XtRPixel,
|
|
sizeof(Pixel),
|
|
offset(cursor_color),
|
|
XtRString,
|
|
XtDefaultForeground
|
|
},
|
|
{
|
|
XawNtextProperties,
|
|
XawCTextProperties,
|
|
XawRTextProperties,
|
|
sizeof(XawTextPropertyList*),
|
|
offset(properties),
|
|
XtRImmediate,
|
|
NULL
|
|
},
|
|
#endif
|
|
};
|
|
#undef offset
|
|
|
|
#ifndef OLDXAW
|
|
static TextSinkExtRec extension_rec = {
|
|
NULL, /* next_extension */
|
|
NULLQUARK, /* record_type */
|
|
1, /* version */
|
|
sizeof(TextSinkExtRec), /* record_size */
|
|
BeginPaint,
|
|
NULL,
|
|
NULL,
|
|
EndPaint
|
|
};
|
|
|
|
static XrmQuark Qdefault;
|
|
#endif
|
|
|
|
#define Superclass (&objectClassRec)
|
|
TextSinkClassRec textSinkClassRec = {
|
|
/* object */
|
|
{
|
|
(WidgetClass)Superclass, /* superclass */
|
|
"TextSink", /* class_name */
|
|
sizeof(TextSinkRec), /* widget_size */
|
|
XawInitializeWidgetSet, /* class_initialize */
|
|
XawTextSinkClassPartInitialize, /* class_part_initialize */
|
|
False, /* class_inited */
|
|
XawTextSinkInitialize, /* initialize */
|
|
NULL, /* initialize_hook */
|
|
NULL, /* obj1 */
|
|
NULL, /* obj2 */
|
|
0, /* obj3 */
|
|
resources, /* resources */
|
|
XtNumber(resources), /* num_resources */
|
|
NULLQUARK, /* xrm_class */
|
|
False, /* obj4 */
|
|
False, /* obj5 */
|
|
False, /* obj6 */
|
|
False, /* obj7 */
|
|
XawTextSinkDestroy, /* destroy */
|
|
NULL, /* obj8 */
|
|
NULL, /* obj9 */
|
|
XawTextSinkSetValues, /* set_values */
|
|
NULL, /* set_values_hook */
|
|
NULL, /* obj10 */
|
|
NULL, /* get_values_hook */
|
|
NULL, /* obj11 */
|
|
XtVersion, /* version */
|
|
NULL, /* callback_private */
|
|
NULL, /* obj12 */
|
|
NULL, /* obj13 */
|
|
NULL, /* obj14 */
|
|
NULL, /* extension */
|
|
},
|
|
/* text_sink */
|
|
{
|
|
DisplayText, /* DisplayText */
|
|
InsertCursor, /* InsertCursor */
|
|
ClearToBackground, /* ClearToBackground */
|
|
FindPosition, /* FindPosition */
|
|
FindDistance, /* FindDistance */
|
|
Resolve, /* Resolve */
|
|
MaxLines, /* MaxLines */
|
|
MaxHeight, /* MaxHeight */
|
|
SetTabs, /* SetTabs */
|
|
GetCursorBounds, /* GetCursorBounds */
|
|
},
|
|
};
|
|
|
|
WidgetClass textSinkObjectClass = (WidgetClass)&textSinkClassRec;
|
|
|
|
/*
|
|
* Implementation
|
|
*/
|
|
static void
|
|
XawTextSinkClassPartInitialize(WidgetClass wc)
|
|
{
|
|
TextSinkObjectClass t_src, superC;
|
|
#ifndef OLDXAW
|
|
static XtConvertArgRec CvtArgs[] = {
|
|
{XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.self),
|
|
sizeof(Widget)},
|
|
};
|
|
#endif
|
|
|
|
t_src = (TextSinkObjectClass) wc;
|
|
superC = (TextSinkObjectClass) t_src->object_class.superclass;
|
|
|
|
#ifndef OLDXAW
|
|
extension_rec.record_type = XrmPermStringToQuark("TextSink");
|
|
extension_rec.next_extension = (XtPointer)t_src->text_sink_class.extension;
|
|
t_src->text_sink_class.extension = &extension_rec;
|
|
|
|
Qdefault = XrmPermStringToQuark("default");
|
|
#endif
|
|
|
|
/*
|
|
* We don't need to check for null super since we'll get to TextSink
|
|
* eventually.
|
|
*/
|
|
if (t_src->text_sink_class.DisplayText == XtInheritDisplayText)
|
|
t_src->text_sink_class.DisplayText =
|
|
superC->text_sink_class.DisplayText;
|
|
|
|
if (t_src->text_sink_class.InsertCursor == XtInheritInsertCursor)
|
|
t_src->text_sink_class.InsertCursor =
|
|
superC->text_sink_class.InsertCursor;
|
|
|
|
if (t_src->text_sink_class.ClearToBackground== XtInheritClearToBackground)
|
|
t_src->text_sink_class.ClearToBackground =
|
|
superC->text_sink_class.ClearToBackground;
|
|
|
|
if (t_src->text_sink_class.FindPosition == XtInheritFindPosition)
|
|
t_src->text_sink_class.FindPosition =
|
|
superC->text_sink_class.FindPosition;
|
|
|
|
if (t_src->text_sink_class.FindDistance == XtInheritFindDistance)
|
|
t_src->text_sink_class.FindDistance =
|
|
superC->text_sink_class.FindDistance;
|
|
|
|
if (t_src->text_sink_class.Resolve == XtInheritResolve)
|
|
t_src->text_sink_class.Resolve =
|
|
superC->text_sink_class.Resolve;
|
|
|
|
if (t_src->text_sink_class.MaxLines == XtInheritMaxLines)
|
|
t_src->text_sink_class.MaxLines =
|
|
superC->text_sink_class.MaxLines;
|
|
|
|
if (t_src->text_sink_class.MaxHeight == XtInheritMaxHeight)
|
|
t_src->text_sink_class.MaxHeight =
|
|
superC->text_sink_class.MaxHeight;
|
|
|
|
if (t_src->text_sink_class.SetTabs == XtInheritSetTabs)
|
|
t_src->text_sink_class.SetTabs =
|
|
superC->text_sink_class.SetTabs;
|
|
|
|
if (t_src->text_sink_class.GetCursorBounds == XtInheritGetCursorBounds)
|
|
t_src->text_sink_class.GetCursorBounds =
|
|
superC->text_sink_class.GetCursorBounds;
|
|
|
|
#ifndef OLDXAW
|
|
XtSetTypeConverter(XtRString, XawRTextProperties, CvtStringToPropertyList,
|
|
&CvtArgs[0], XtNumber(CvtArgs), XtCacheNone, NULL);
|
|
XtSetTypeConverter(XawRTextProperties, XtRString, CvtPropertyListToString,
|
|
NULL, 0, XtCacheNone, NULL);
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* Function:
|
|
* XawTextSinkInitialize
|
|
*
|
|
* Parameters:
|
|
* request - requested and new values for the object instance
|
|
* cnew - ""
|
|
*
|
|
* Description:
|
|
* Initializes the TextSink Object.
|
|
*/
|
|
/*ARGSUSED*/
|
|
static void
|
|
XawTextSinkInitialize(Widget request, Widget cnew,
|
|
ArgList args, Cardinal *num_args)
|
|
{
|
|
TextSinkObject sink = (TextSinkObject)cnew;
|
|
|
|
sink->text_sink.tab_count = 0; /* Initialize the tab stops. */
|
|
sink->text_sink.tabs = NULL;
|
|
sink->text_sink.char_tabs = NULL;
|
|
#ifndef OLDXAW
|
|
sink->text_sink.paint = NULL;
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* Function:
|
|
* XawTextSinkDestroy
|
|
*
|
|
* Parameters:
|
|
* w - TextSink Object
|
|
*
|
|
* Description:
|
|
* This function cleans up when the object is destroyed.
|
|
*/
|
|
static void
|
|
XawTextSinkDestroy(Widget w)
|
|
{
|
|
TextSinkObject sink = (TextSinkObject) w;
|
|
|
|
XtFree((char *)sink->text_sink.tabs);
|
|
XtFree((char *)sink->text_sink.char_tabs);
|
|
}
|
|
|
|
/*
|
|
* Function:
|
|
* XawTextSinkSetValues
|
|
*
|
|
* Parameters:
|
|
* current - current state of the object
|
|
* request - what was requested
|
|
* cnew - what the object will become
|
|
*
|
|
* Description:
|
|
* Sets the values for the TextSink.
|
|
*
|
|
* Returns:
|
|
* True if redisplay is needed
|
|
*/
|
|
/*ARGSUSED*/
|
|
static Boolean
|
|
XawTextSinkSetValues(Widget current, Widget request, Widget cnew,
|
|
ArgList args, Cardinal *num_args)
|
|
{
|
|
TextSinkObject w = (TextSinkObject)cnew;
|
|
TextSinkObject old_w = (TextSinkObject)current;
|
|
|
|
if (w->text_sink.foreground != old_w->text_sink.foreground)
|
|
((TextWidget)XtParent(cnew))->text.redisplay_needed = True;
|
|
|
|
return (False);
|
|
}
|
|
|
|
/*
|
|
* Function:
|
|
* DisplayText
|
|
*
|
|
* Parameters:
|
|
* w - TextSink Object
|
|
* x - location to start drawing text
|
|
* y - ""
|
|
* pos1 - location of starting and ending points in the text buffer
|
|
* pos2 - ""
|
|
* highlight - hightlight this text?
|
|
*
|
|
* Description:
|
|
* Stub function that in subclasses will display text.
|
|
*/
|
|
/*ARGSUSED*/
|
|
static void
|
|
DisplayText(Widget w, int x, int y,
|
|
XawTextPosition pos1, XawTextPosition pos2, Bool highlight)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* Function:
|
|
* InsertCursor
|
|
*
|
|
* Parameters:
|
|
* w - TextSink Object
|
|
* x - location for the cursor
|
|
* y - ""
|
|
* state - whether to turn the cursor on, or off
|
|
*
|
|
* Description:
|
|
* Places the InsertCursor.
|
|
*/
|
|
/*ARGSUSED*/
|
|
static void
|
|
InsertCursor(Widget w, int x, int y, XawTextInsertState state)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* Function:
|
|
* ClearToBackground
|
|
*
|
|
* Parameters:
|
|
* w - TextSink Object
|
|
* x - location of area to clear
|
|
* y - ""
|
|
* width - size of area to clear
|
|
* height - ""
|
|
*
|
|
* Description:
|
|
* Clears a region of the sink to the background color.
|
|
*/
|
|
/*ARGSUSED*/
|
|
static void
|
|
ClearToBackground(Widget w, int x, int y,
|
|
unsigned int width, unsigned int height)
|
|
{
|
|
/*
|
|
* Don't clear in height or width are zero
|
|
* XClearArea() has special semantic for these values
|
|
*/
|
|
TextWidget xaw = (TextWidget)XtParent(w);
|
|
Position x1, y1, x2, y2;
|
|
|
|
x1 = XawMax(x, xaw->text.r_margin.left);
|
|
y1 = XawMax(y, xaw->text.r_margin.top);
|
|
x2 = XawMin(x + (int)width, (int)XtWidth(xaw) - xaw->text.r_margin.right);
|
|
y2 = XawMin(y + (int)height, (int)XtHeight(xaw) - xaw->text.r_margin.bottom);
|
|
|
|
x = x1;
|
|
y = y1;
|
|
width = XawMax(0, x2 - x1);
|
|
height = XawMax(0, y2 - y1);
|
|
|
|
if (height != 0 && width != 0)
|
|
XClearArea(XtDisplayOfObject(w), XtWindowOfObject(w),
|
|
x, y, width, height, False);
|
|
}
|
|
|
|
/*
|
|
* Function:
|
|
* FindPosition
|
|
*
|
|
* Parameters:
|
|
* w - TextSink Object
|
|
* fromPos - reference position
|
|
* fromX - reference location
|
|
* width - width of section to paint text
|
|
* stopAtWordBreak - returned position is a word break?
|
|
* resPos - position found (return)
|
|
* resWidth - Width actually used (return)
|
|
* resHeight - Height actually used (return)
|
|
*
|
|
* Description:
|
|
* Finds a position in the text.
|
|
*/
|
|
/*ARGSUSED*/
|
|
static void
|
|
FindPosition(Widget w, XawTextPosition fromPos, int fromx, int width,
|
|
Bool stopAtWordBreak, XawTextPosition *resPos,
|
|
int *resWidth, int *resHeight)
|
|
{
|
|
*resPos = fromPos;
|
|
*resHeight = *resWidth = 0;
|
|
}
|
|
|
|
/*
|
|
* Function:
|
|
* FindDistance
|
|
*
|
|
* Parameters:
|
|
* w - TextSink Object
|
|
* fromPos - starting Position
|
|
* fromX - x location of starting Position
|
|
* toPos - end Position
|
|
* resWidth - Distance between fromPos and toPos
|
|
* resPos - Acutal toPos used
|
|
* resHeight - Height required by this text
|
|
*
|
|
* Description:
|
|
* Find the Pixel Distance between two text Positions.
|
|
*/
|
|
/*ARGSUSED*/
|
|
static void
|
|
FindDistance(Widget w, XawTextPosition fromPos, int fromx,
|
|
XawTextPosition toPos, int *resWidth,
|
|
XawTextPosition *resPos, int *resHeight)
|
|
{
|
|
*resWidth = *resHeight = 0;
|
|
*resPos = fromPos;
|
|
}
|
|
|
|
/*
|
|
* Function:
|
|
* Resolve
|
|
*
|
|
* Parameters:
|
|
* w - TextSink Object
|
|
* pos - reference Position
|
|
* fromx - reference Location
|
|
* width - width to move
|
|
* resPos - resulting position
|
|
*
|
|
* Description:
|
|
* Resloves a location to a position.
|
|
*/
|
|
/*ARGSUSED*/
|
|
static void
|
|
Resolve(Widget w, XawTextPosition pos, int fromx, int width,
|
|
XawTextPosition *resPos)
|
|
{
|
|
*resPos = pos;
|
|
}
|
|
|
|
/*
|
|
* Function:
|
|
* MaxLines
|
|
*
|
|
* Parameters:
|
|
* w - TextSink Object
|
|
* height - height to fit lines into
|
|
*
|
|
* Description:
|
|
* Finds the Maximum number of lines that will fit in a given height.
|
|
*
|
|
* Returns:
|
|
* Number of lines that will fit
|
|
*/
|
|
/*ARGSUSED*/
|
|
static int
|
|
MaxLines(Widget w, unsigned int height)
|
|
{
|
|
/*
|
|
* The fontset has gone down to descent Sink Widget, so
|
|
* the functions such MaxLines, SetTabs... are bound to the descent.
|
|
*
|
|
* by Li Yuhong, Jan. 15, 1991
|
|
*/
|
|
return (0);
|
|
}
|
|
|
|
/*
|
|
* Function:
|
|
* MaxHeight
|
|
*
|
|
* Parameters:
|
|
* w - TextSink Object
|
|
* lines - number of lines
|
|
*
|
|
* Description:
|
|
* Finds the Minium height that will contain a given number lines.
|
|
*
|
|
* Returns:
|
|
* the height
|
|
*/
|
|
/*ARGSUSED*/
|
|
static int
|
|
MaxHeight(Widget w, int lines)
|
|
{
|
|
return (0);
|
|
}
|
|
|
|
/*
|
|
* Function:
|
|
* SetTabs
|
|
*
|
|
* Parameters:
|
|
* w - TextSink Object
|
|
* tab_count - the number of tabs in the list
|
|
* tabs - text positions of the tabs
|
|
* Description:
|
|
* Sets the Tab stops.
|
|
*/
|
|
/*ARGSUSED*/
|
|
static void
|
|
SetTabs(Widget w, int tab_count, short *tabs)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* Function:
|
|
* GetCursorBounds
|
|
*
|
|
* Parameters:
|
|
* w - TextSinkObject.
|
|
* rect - X rectangle containing the cursor bounds
|
|
*
|
|
* Description:
|
|
* Finds the bounding box for the insert cursor (caret)
|
|
*/
|
|
/*ARGSUSED*/
|
|
static void
|
|
GetCursorBounds(Widget w, XRectangle *rect)
|
|
{
|
|
rect->x = rect->y = rect->width = rect->height = 0;
|
|
}
|
|
|
|
/*
|
|
* Public Functions
|
|
*/
|
|
/*
|
|
* Function:
|
|
* XawTextSinkDisplayText
|
|
*
|
|
* Parameters:
|
|
* w - TextSink Object
|
|
* x - location to start drawing text
|
|
* y - ""
|
|
* pos1 - location of starting and ending points in the text buffer
|
|
* pos2 - ""
|
|
* highlight - hightlight this text?
|
|
*/
|
|
/*ARGSUSED*/
|
|
void
|
|
XawTextSinkDisplayText(Widget w,
|
|
#if NeedWidePrototypes
|
|
int x, int y,
|
|
#else
|
|
Position x, Position y,
|
|
#endif
|
|
XawTextPosition pos1, XawTextPosition pos2,
|
|
#if NeedWidePrototypes
|
|
int highlight
|
|
#else
|
|
Boolean highlight
|
|
#endif
|
|
)
|
|
{
|
|
_XawTextSinkDisplayText(w, x, y, pos1, pos2, highlight);
|
|
}
|
|
|
|
void
|
|
_XawTextSinkDisplayText(Widget w, int x, int y,
|
|
XawTextPosition pos1, XawTextPosition pos2,
|
|
Bool highlight)
|
|
{
|
|
TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class;
|
|
|
|
(*cclass->text_sink_class.DisplayText)(w, x, y, pos1, pos2, highlight);
|
|
}
|
|
|
|
/*
|
|
* Function:
|
|
* XawTextSinkInsertCursor
|
|
*
|
|
* Parameters:
|
|
* w - TextSink Object
|
|
* x - location for the cursor
|
|
* y - ""
|
|
* state - whether to turn the cursor on, or off
|
|
*
|
|
* Description:
|
|
* Places the InsertCursor.
|
|
*/
|
|
/*ARGSUSED*/
|
|
void
|
|
#if NeedWidePrototypes
|
|
XawTextSinkInsertCursor(Widget w, int x, int y, int state)
|
|
#else
|
|
XawTextSinkInsertCursor(Widget w, Position x, Position y, XawTextInsertState state)
|
|
#endif
|
|
{
|
|
TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class;
|
|
|
|
(*cclass->text_sink_class.InsertCursor)(w, x, y, state);
|
|
}
|
|
|
|
/*
|
|
* Function:
|
|
* XawTextSinkClearToBackground
|
|
*
|
|
* Parameters:
|
|
* w - TextSink Object
|
|
* x - location of area to clear
|
|
* y - ""
|
|
* width - size of area to clear
|
|
* height - ""
|
|
*
|
|
* Description:
|
|
* Clears a region of the sink to the background color.
|
|
*/
|
|
/*ARGSUSED*/
|
|
void
|
|
XawTextSinkClearToBackground(Widget w,
|
|
#if NeedWidePrototypes
|
|
int x, int y,
|
|
unsigned int width, unsigned int height
|
|
#else
|
|
Position x, Position y,
|
|
Dimension width, Dimension height
|
|
#endif
|
|
)
|
|
{
|
|
_XawTextSinkClearToBackground(w, x, y, width, height);
|
|
}
|
|
|
|
void
|
|
_XawTextSinkClearToBackground(Widget w,
|
|
int x, int y,
|
|
unsigned int width, unsigned int height)
|
|
{
|
|
TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class;
|
|
|
|
(*cclass->text_sink_class.ClearToBackground)(w, x, y, width, height);
|
|
}
|
|
|
|
/*
|
|
* Function:
|
|
* XawTextSinkFindPosition
|
|
*
|
|
* Parameters:
|
|
* w - TextSink Object
|
|
* fromPos - reference position
|
|
* fromX - reference location
|
|
* width - width of section to paint text
|
|
* stopAtWordBreak - returned position is a word break?
|
|
* resPos - position found (return)
|
|
* resWidth - Width actually used (return)
|
|
* resHeight - Height actually used (return)
|
|
*
|
|
* Description:
|
|
* Finds a position in the text.
|
|
*/
|
|
/*ARGSUSED*/
|
|
void
|
|
XawTextSinkFindPosition(Widget w, XawTextPosition fromPos, int fromx, int width,
|
|
#if NeedWidePrototypes
|
|
int stopAtWordBreak,
|
|
#else
|
|
Boolean stopAtWordBreak,
|
|
#endif
|
|
XawTextPosition *resPos, int *resWidth, int *resHeight)
|
|
{
|
|
TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class;
|
|
|
|
(*cclass->text_sink_class.FindPosition)(w, fromPos, fromx, width,
|
|
stopAtWordBreak,
|
|
resPos, resWidth, resHeight);
|
|
}
|
|
|
|
/*
|
|
* Function:
|
|
* XawTextSinkFindDistance
|
|
*
|
|
* Parameters:
|
|
* w - TextSink Object
|
|
* fromPos - starting Position
|
|
* fromX - x location of starting Position
|
|
* toPos - end Position
|
|
* resWidth - Distance between fromPos and toPos
|
|
* resPos - Acutal toPos used
|
|
* resHeight - Height required by this text
|
|
*
|
|
* Description:
|
|
* Find the Pixel Distance between two text Positions.
|
|
*/
|
|
/*ARGSUSED*/
|
|
void
|
|
XawTextSinkFindDistance(Widget w, XawTextPosition fromPos, int fromx,
|
|
XawTextPosition toPos, int *resWidth,
|
|
XawTextPosition *resPos, int *resHeight)
|
|
{
|
|
TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class;
|
|
|
|
(*cclass->text_sink_class.FindDistance)(w, fromPos, fromx, toPos,
|
|
resWidth, resPos, resHeight);
|
|
}
|
|
|
|
/*
|
|
* Function:
|
|
* XawTextSinkResolve
|
|
*
|
|
* Parameters:
|
|
* w - TextSink Object
|
|
* pos - reference Position
|
|
* fromx - reference Location
|
|
* width - width to move
|
|
* resPos - resulting position
|
|
*
|
|
* Description:
|
|
* Resloves a location to a position.
|
|
*/
|
|
/*ARGSUSED*/
|
|
void
|
|
XawTextSinkResolve(Widget w, XawTextPosition pos, int fromx, int width,
|
|
XawTextPosition *resPos)
|
|
{
|
|
TextSinkObjectClass cclass = (TextSinkObjectClass) w->core.widget_class;
|
|
|
|
(*cclass->text_sink_class.Resolve)(w, pos, fromx, width, resPos);
|
|
}
|
|
|
|
/*
|
|
* Function:
|
|
* XawTextSinkMaxLines
|
|
*
|
|
* Parameters:
|
|
* w - TextSink Object
|
|
* height - height to fit lines into
|
|
*
|
|
* Description:
|
|
* Finds the Maximum number of lines that will fit in a given height.
|
|
*
|
|
* Returns:
|
|
* Number of lines that will fit
|
|
*/
|
|
/*ARGSUSED*/
|
|
int
|
|
#if NeedWidePrototypes
|
|
XawTextSinkMaxLines(Widget w, unsigned int height)
|
|
#else
|
|
XawTextSinkMaxLines(Widget w, Dimension height)
|
|
#endif
|
|
{
|
|
TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class;
|
|
|
|
return((*cclass->text_sink_class.MaxLines)(w, height));
|
|
}
|
|
|
|
/*
|
|
* Function:
|
|
* XawTextSinkMaxHeight
|
|
*
|
|
* Parameters:
|
|
* w - TextSink Object
|
|
* lines - number of lines
|
|
*
|
|
* Description:
|
|
* Finds the Minium height that will contain a given number lines.
|
|
*
|
|
* Returns:
|
|
* the height
|
|
*/
|
|
/*ARGSUSED*/
|
|
int
|
|
XawTextSinkMaxHeight(Widget w, int lines)
|
|
{
|
|
TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class;
|
|
|
|
return((*cclass->text_sink_class.MaxHeight)(w, lines));
|
|
}
|
|
|
|
/*
|
|
* Function:
|
|
* XawTextSinkSetTabs
|
|
*
|
|
* Parameters:
|
|
* w - TextSink Object
|
|
* tab_count - the number of tabs in the list
|
|
* tabs - text positions of the tabs
|
|
* Description:
|
|
* Sets the Tab stops.
|
|
*/
|
|
void
|
|
XawTextSinkSetTabs(Widget w, int tab_count, int *tabs)
|
|
{
|
|
if (tab_count > 0) {
|
|
TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class;
|
|
short *char_tabs = (short*)XtMalloc((unsigned)tab_count * sizeof(short));
|
|
short *tab, len = 0;
|
|
int i;
|
|
|
|
for (i = tab_count, tab = char_tabs; i; i--) {
|
|
if ((short)*tabs > len)
|
|
*tab++ = (len = (short)*tabs++);
|
|
else {
|
|
tabs++;
|
|
--tab_count;
|
|
}
|
|
}
|
|
|
|
if (tab_count > 0)
|
|
(*cclass->text_sink_class.SetTabs)(w, tab_count, char_tabs);
|
|
XtFree((char *)char_tabs);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Function:
|
|
* XawTextSinkGetCursorBounds
|
|
*
|
|
* Parameters:
|
|
* w - TextSinkObject
|
|
* rect - X rectance containing the cursor bounds
|
|
*
|
|
* Description:
|
|
* Finds the bounding box for the insert cursor (caret).
|
|
*/
|
|
/*ARGSUSED*/
|
|
void
|
|
XawTextSinkGetCursorBounds(Widget w, XRectangle *rect)
|
|
{
|
|
TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class;
|
|
|
|
(*cclass->text_sink_class.GetCursorBounds)(w, rect);
|
|
}
|
|
|
|
#ifndef OLDXAW
|
|
Bool
|
|
XawTextSinkBeginPaint(Widget w)
|
|
{
|
|
TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class;
|
|
|
|
if (cclass->text_sink_class.extension->BeginPaint == NULL ||
|
|
cclass->text_sink_class.extension->PreparePaint == NULL ||
|
|
cclass->text_sink_class.extension->DoPaint == NULL ||
|
|
cclass->text_sink_class.extension->EndPaint == NULL)
|
|
return (False);
|
|
|
|
return ((*cclass->text_sink_class.extension->BeginPaint)(w));
|
|
}
|
|
|
|
static Bool
|
|
BeginPaint(Widget w)
|
|
{
|
|
TextSinkObject sink = (TextSinkObject)w;
|
|
|
|
if (sink->text_sink.paint != NULL)
|
|
return (False);
|
|
|
|
sink->text_sink.paint = XtNew(XawTextPaintList);
|
|
sink->text_sink.paint->clip = XmuCreateArea();
|
|
sink->text_sink.paint->hightabs = NULL;
|
|
sink->text_sink.paint->paint = NULL;
|
|
sink->text_sink.paint->bearings = NULL;
|
|
|
|
return (True);
|
|
}
|
|
|
|
void
|
|
XawTextSinkPreparePaint(Widget w, int y, int line, XawTextPosition from,
|
|
XawTextPosition to, Bool highlight)
|
|
{
|
|
TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class;
|
|
|
|
(*cclass->text_sink_class.extension->PreparePaint)
|
|
(w, y, line, from, to, highlight);
|
|
}
|
|
|
|
#if 0
|
|
/*ARGSUSED*/
|
|
static void
|
|
PreparePaint(Widget w, int y, int line, XawTextPosition from, XawTextPosition to,
|
|
Bool highlight)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
void
|
|
XawTextSinkDoPaint(Widget w)
|
|
{
|
|
TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class;
|
|
|
|
(*cclass->text_sink_class.extension->DoPaint)(w);
|
|
}
|
|
|
|
#if 0
|
|
/*ARGSUSED*/
|
|
static void
|
|
DoPaint(Widget w)
|
|
{
|
|
}
|
|
#endif
|
|
|
|
Bool
|
|
XawTextSinkEndPaint(Widget w)
|
|
{
|
|
TextSinkObjectClass cclass = (TextSinkObjectClass)w->core.widget_class;
|
|
|
|
return ((*cclass->text_sink_class.extension->EndPaint)(w));
|
|
}
|
|
|
|
static Bool
|
|
EndPaint(Widget w)
|
|
{
|
|
TextSinkObject sink = (TextSinkObject)w;
|
|
XawTextPaintStruct *paint, *next;
|
|
|
|
if (sink->text_sink.paint == NULL)
|
|
return (False);
|
|
|
|
XmuDestroyArea(sink->text_sink.paint->clip);
|
|
if (sink->text_sink.paint->hightabs)
|
|
XmuDestroyArea(sink->text_sink.paint->hightabs);
|
|
paint = sink->text_sink.paint->paint;
|
|
while (paint) {
|
|
next = paint->next;
|
|
if (paint->text)
|
|
XtFree((XtPointer)paint->text);
|
|
if (paint->backtabs)
|
|
XmuDestroyArea(paint->backtabs);
|
|
XtFree((XtPointer)paint);
|
|
paint = next;
|
|
}
|
|
|
|
paint = sink->text_sink.paint->bearings;
|
|
while (paint) {
|
|
next = paint->next;
|
|
if (paint->text)
|
|
XtFree((XtPointer)paint->text);
|
|
XtFree((XtPointer)paint);
|
|
paint = next;
|
|
}
|
|
|
|
XtFree((XtPointer)sink->text_sink.paint);
|
|
sink->text_sink.paint = NULL;
|
|
return (True);
|
|
}
|
|
|
|
static XawTextPropertyList **prop_lists;
|
|
static Cardinal num_prop_lists;
|
|
|
|
static int
|
|
bcmp_qident(_Xconst void *left, _Xconst void *right)
|
|
{
|
|
return ((long)left - (*(XawTextProperty**)right)->identifier);
|
|
}
|
|
|
|
static int
|
|
qcmp_qident(_Xconst void *left, _Xconst void *right)
|
|
{
|
|
return ((*(XawTextProperty**)left)->identifier -
|
|
(*(XawTextProperty**)right)->identifier);
|
|
}
|
|
|
|
static void
|
|
SetXlfdDefaults(Display *display, XawTextProperty *property)
|
|
{
|
|
Atom atom = XInternAtom(display, "FONT", True);
|
|
unsigned long value;
|
|
char *str;
|
|
|
|
if (XGetFontProperty(property->font, atom, &value)) {
|
|
char *xlfd = XGetAtomName(display, value);
|
|
|
|
if (xlfd) {
|
|
char *sep = xlfd + 1;
|
|
char *name = sep;
|
|
|
|
property->xlfd = XrmStringToQuark(xlfd);
|
|
|
|
sep = strchr(sep, '-'); *sep++ = '\0';
|
|
property->foundry = XrmStringToQuark(name);
|
|
name = sep;
|
|
|
|
sep = strchr(sep, '-'); *sep++ = '\0';
|
|
property->family = XrmStringToQuark(name);
|
|
name = sep;
|
|
|
|
sep = strchr(sep, '-'); *sep++ = '\0';
|
|
property->weight = XrmStringToQuark(name);
|
|
name = sep;
|
|
|
|
sep = strchr(sep, '-'); *sep++ = '\0';
|
|
property->slant = XrmStringToQuark(name);
|
|
name = sep;
|
|
|
|
sep = strchr(sep, '-'); *sep++ = '\0';
|
|
property->setwidth = XrmStringToQuark(name);
|
|
name = sep;
|
|
|
|
sep = strchr(sep, '-'); *sep++ = '\0';
|
|
property->addstyle = XrmStringToQuark(name);
|
|
name = sep;
|
|
|
|
sep = strchr(sep, '-'); *sep++ = '\0';
|
|
property->pixel_size = XrmStringToQuark(name);
|
|
name = sep;
|
|
|
|
sep = strchr(sep, '-'); *sep++ = '\0';
|
|
property->point_size = XrmStringToQuark(name);
|
|
name = sep;
|
|
|
|
sep = strchr(sep, '-'); *sep++ = '\0';
|
|
property->res_x = XrmStringToQuark(name);
|
|
name = sep;
|
|
|
|
sep = strchr(sep, '-'); *sep++ = '\0';
|
|
property->res_y = XrmStringToQuark(name);
|
|
name = sep;
|
|
|
|
sep = strchr(sep, '-'); *sep++ = '\0';
|
|
property->spacing = XrmStringToQuark(name);
|
|
name = sep;
|
|
|
|
sep = strchr(sep, '-'); *sep++ = '\0';
|
|
property->avgwidth = XrmStringToQuark(name);
|
|
name = sep;
|
|
|
|
sep = strchr(sep, '-'); *sep++ = '\0';
|
|
property->registry = XrmStringToQuark(name);
|
|
name = sep;
|
|
|
|
property->encoding = XrmStringToQuark(name);
|
|
|
|
XFree(xlfd);
|
|
}
|
|
}
|
|
|
|
atom = XInternAtom(display, "UNDERLINE_THICKNESS", True);
|
|
if (XGetFontProperty(property->font, atom, &value) &&
|
|
(str = XGetAtomName(display, value)) != NULL) {
|
|
property->underline_thickness = atoi(str);
|
|
XFree(str);
|
|
}
|
|
else {
|
|
/* XLFD says:
|
|
* CapStemWidth = average width of the stems of capitals
|
|
* if (UNDERLINE_THICKNESS undefined) then
|
|
* UNDERLINE_THICKNESS = CapStemWidth
|
|
*
|
|
* How do I know the value of CapStemWidth??
|
|
*/
|
|
if (property->pixel_size != NULLQUARK) {
|
|
property->underline_thickness =
|
|
atoi(XrmQuarkToString(property->pixel_size)) / 10;
|
|
property->underline_thickness =
|
|
XawMax(1, property->underline_thickness);
|
|
}
|
|
else
|
|
property->underline_thickness = 1;
|
|
}
|
|
|
|
atom = XInternAtom(display, "UNDERLINE_POSITION", True);
|
|
if (XGetFontProperty(property->font, atom, &value) &&
|
|
(str = XGetAtomName(display, value)) != NULL) {
|
|
property->underline_position = atoi(str);
|
|
XFree(str);
|
|
}
|
|
else
|
|
/* XLFD says:
|
|
* if (UNDERLINE_POSITION undefined) then
|
|
* UNDERLINE_POSITION = ROUND((maximum_descent) / 2)
|
|
*/
|
|
property->underline_position =
|
|
property->font->max_bounds.descent >> 1;
|
|
|
|
/* I am assuming xlfd does not consider that lines are
|
|
* centered in the path */
|
|
property->underline_position += property->underline_thickness >> 1;
|
|
|
|
}
|
|
|
|
static void
|
|
DestroyTextPropertyList(XawTextPropertyList *list)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < list->num_properties; i++) {
|
|
if (list->properties[i]->font)
|
|
XFreeFont(DisplayOfScreen(list->screen), list->properties[i]->font);
|
|
XtFree((char*)list->properties[i]);
|
|
}
|
|
if (list->properties)
|
|
XtFree((char*)list->properties);
|
|
XtFree((char*)list);
|
|
}
|
|
|
|
static XawTextProperty *
|
|
_XawTextSinkGetProperty(XawTextPropertyList *list, XrmQuark property)
|
|
{
|
|
if (property != NULLQUARK && list && list->properties) {
|
|
XawTextProperty **ptr = (XawTextProperty**)
|
|
bsearch((void*)(long)property,
|
|
list->properties, list->num_properties,
|
|
sizeof(XawTextProperty*), bcmp_qident);
|
|
|
|
if (ptr)
|
|
return (*ptr);
|
|
}
|
|
|
|
return (NULL);
|
|
}
|
|
|
|
XawTextProperty *
|
|
XawTextSinkGetProperty(Widget w, XrmQuark property)
|
|
{
|
|
TextSinkObject sink = (TextSinkObject)w;
|
|
XawTextPropertyList *list = sink->text_sink.properties;
|
|
|
|
return (_XawTextSinkGetProperty(list, property));
|
|
}
|
|
|
|
XawTextProperty *
|
|
XawTextSinkCopyProperty(Widget w, XrmQuark property)
|
|
{
|
|
XawTextProperty *cur, *ret;
|
|
|
|
if ((cur = XawTextSinkGetProperty(w, property)) == NULL)
|
|
cur = XawTextSinkGetProperty(w, Qdefault);
|
|
ret = (XawTextProperty*)XtCalloc(1, sizeof(XawTextProperty));
|
|
if (cur)
|
|
memcpy(ret, cur, sizeof(XawTextProperty));
|
|
ret->identifier = NULLQUARK;
|
|
ret->mask &= ~XAW_TPROP_FONT;
|
|
|
|
return (ret);
|
|
}
|
|
|
|
static XawTextProperty *
|
|
_XawTextSinkAddProperty(XawTextPropertyList *list, XawTextProperty *property,
|
|
Bool replace)
|
|
{
|
|
XawTextProperty *result;
|
|
XColor color;
|
|
char identifier[1024];
|
|
char foreground[16];
|
|
char background[16];
|
|
char *foundry, *family, *weight, *slant, *setwidth, *addstyle, *pixel_size,
|
|
*point_size, *res_x, *res_y, *spacing, *avgwidth, *registry, *encoding;
|
|
char *xlfd;
|
|
static char *asterisk = "*", *null = "";
|
|
XrmQuark quark;
|
|
|
|
if (list == NULL || property == NULL)
|
|
return (NULL);
|
|
|
|
if (property->mask & XAW_TPROP_FOREGROUND) {
|
|
color.pixel = property->foreground;
|
|
XQueryColor(DisplayOfScreen(list->screen), list->colormap, &color);
|
|
XmuSnprintf(foreground, sizeof(foreground), "%04x%04x%04x",
|
|
color.red, color.green, color.blue);
|
|
}
|
|
else
|
|
strcpy(foreground, asterisk);
|
|
if (property->mask & XAW_TPROP_BACKGROUND) {
|
|
color.pixel = property->background;
|
|
XQueryColor(DisplayOfScreen(list->screen), list->colormap, &color);
|
|
XmuSnprintf(background, sizeof(background), "%04x%04x%04x",
|
|
color.red, color.green, color.blue);
|
|
}
|
|
else
|
|
strcpy(background, asterisk);
|
|
|
|
if (property->xlfd_mask & XAW_TPROP_FOUNDRY)
|
|
foundry = XrmQuarkToString(property->foundry);
|
|
else
|
|
foundry = asterisk;
|
|
|
|
/* use default, or what was requested */
|
|
if (property->family != NULLQUARK)
|
|
family = XrmQuarkToString(property->family);
|
|
else
|
|
family = asterisk;
|
|
if (property->weight != NULLQUARK)
|
|
weight = XrmQuarkToString(property->weight);
|
|
else
|
|
weight = asterisk;
|
|
if (property->slant != NULLQUARK) {
|
|
slant = XrmQuarkToString(property->slant);
|
|
if (toupper(*slant) != 'R')
|
|
slant = asterisk; /* X defaults to italics, so, don't
|
|
care in resolving between `I' and `O' */
|
|
}
|
|
else
|
|
slant = asterisk;
|
|
|
|
if (property->xlfd_mask & XAW_TPROP_SETWIDTH)
|
|
setwidth = XrmQuarkToString(property->setwidth);
|
|
else
|
|
setwidth = asterisk;
|
|
if (property->xlfd_mask & XAW_TPROP_ADDSTYLE)
|
|
addstyle = XrmQuarkToString(property->addstyle);
|
|
else
|
|
addstyle = null;
|
|
|
|
/* use default, or what was requested */
|
|
if (!(property->mask & XAW_TPROP_POINTSIZE) &&
|
|
property->pixel_size != NULLQUARK)
|
|
pixel_size = XrmQuarkToString(property->pixel_size);
|
|
else
|
|
pixel_size = asterisk;
|
|
|
|
if (property->xlfd_mask & XAW_TPROP_POINTSIZE)
|
|
point_size = XrmQuarkToString(property->point_size);
|
|
else
|
|
point_size = asterisk;
|
|
if (property->xlfd_mask & XAW_TPROP_RESX)
|
|
res_x = XrmQuarkToString(property->res_x);
|
|
else
|
|
res_x = asterisk;
|
|
if (property->xlfd_mask & XAW_TPROP_RESY)
|
|
res_y = XrmQuarkToString(property->res_y);
|
|
else
|
|
res_y = asterisk;
|
|
if (property->xlfd_mask & XAW_TPROP_SPACING)
|
|
spacing = XrmQuarkToString(property->spacing);
|
|
else
|
|
spacing = asterisk;
|
|
if (property->xlfd_mask & XAW_TPROP_AVGWIDTH)
|
|
avgwidth = XrmQuarkToString(property->avgwidth);
|
|
else
|
|
avgwidth = asterisk;
|
|
|
|
/* use default, or what that was requested */
|
|
if (property->registry != NULLQUARK)
|
|
registry = XrmQuarkToString(property->registry);
|
|
else
|
|
registry = asterisk;
|
|
if (property->encoding != NULLQUARK)
|
|
encoding = XrmQuarkToString(property->encoding);
|
|
else
|
|
encoding = asterisk;
|
|
|
|
if (replace) {
|
|
result = XtNew(XawTextProperty);
|
|
memcpy(result, property, sizeof(XawTextProperty));
|
|
}
|
|
else
|
|
result = property;
|
|
|
|
/* XXX should do the best to load a suitable font here */
|
|
if (!(result->mask & XAW_TPROP_FONT)) {
|
|
XmuSnprintf(identifier, sizeof(identifier),
|
|
"-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s",
|
|
foundry, family, weight, slant, setwidth, addstyle, pixel_size,
|
|
point_size, res_x, res_y, spacing, avgwidth, registry, encoding);
|
|
if ((result->font = XLoadQueryFont(DisplayOfScreen(list->screen),
|
|
identifier)) != NULL) {
|
|
result->mask |= XAW_TPROP_FONT;
|
|
SetXlfdDefaults(DisplayOfScreen(list->screen), result);
|
|
}
|
|
else
|
|
result->mask &= ~XAW_TPROP_FONT;
|
|
}
|
|
|
|
if (result->font)
|
|
xlfd = XrmQuarkToString(result->xlfd);
|
|
else
|
|
xlfd = null;
|
|
|
|
XmuSnprintf(identifier, sizeof(identifier), "%08lx%08lx%s%s%d%d%d%d%s",
|
|
property->mask, property->xlfd_mask,
|
|
foreground, background,
|
|
(result->mask & XAW_TPROP_UNDERLINE) != 0,
|
|
(result->mask & XAW_TPROP_OVERSTRIKE) != 0,
|
|
(result->mask & XAW_TPROP_SUBSCRIPT) != 0,
|
|
(result->mask & XAW_TPROP_SUPERSCRIPT) != 0,
|
|
xlfd);
|
|
|
|
quark = XrmStringToQuark(identifier);
|
|
if (result->identifier == NULLQUARK)
|
|
result->identifier = quark;
|
|
result->code = quark;
|
|
|
|
if ((property = _XawTextSinkGetProperty(list, result->identifier)) != NULL) {
|
|
if (result->font)
|
|
XFreeFont(DisplayOfScreen(list->screen), result->font);
|
|
if (replace)
|
|
XtFree((XtPointer)result);
|
|
|
|
return (property);
|
|
}
|
|
|
|
list->properties = (XawTextProperty**)
|
|
XtRealloc((XtPointer)list->properties, sizeof(XawTextProperty*) *
|
|
(list->num_properties + 1));
|
|
list->properties[list->num_properties++] = result;
|
|
qsort((void*)list->properties, list->num_properties,
|
|
sizeof(XawTextProperty*), qcmp_qident);
|
|
|
|
return (result);
|
|
}
|
|
|
|
XawTextProperty *
|
|
XawTextSinkAddProperty(Widget w, XawTextProperty *property)
|
|
{
|
|
TextSinkObject sink = (TextSinkObject)w;
|
|
XawTextPropertyList *list = sink->text_sink.properties;
|
|
|
|
return (_XawTextSinkAddProperty(list, property, True));
|
|
}
|
|
|
|
XawTextProperty *
|
|
XawTextSinkCombineProperty(Widget w,
|
|
XawTextProperty *property, XawTextProperty *combine,
|
|
Bool override)
|
|
{
|
|
if (property == NULL || combine == NULL)
|
|
return (property);
|
|
|
|
if ((override || !(property->mask & XAW_TPROP_FOREGROUND)) &&
|
|
(combine->mask & XAW_TPROP_FOREGROUND)) {
|
|
property->mask |= XAW_TPROP_FOREGROUND;
|
|
property->foreground = combine->foreground;
|
|
}
|
|
if ((override || !(property->mask & XAW_TPROP_BACKGROUND)) &&
|
|
(combine->mask & XAW_TPROP_BACKGROUND)) {
|
|
property->mask |= XAW_TPROP_BACKGROUND;
|
|
property->background = combine->background;
|
|
}
|
|
if ((override || !(property->mask & XAW_TPROP_FPIXMAP)) &&
|
|
(combine->mask & XAW_TPROP_FPIXMAP)) {
|
|
property->mask |= XAW_TPROP_FPIXMAP;
|
|
property->foreground_pixmap = combine->foreground_pixmap;
|
|
}
|
|
if ((override || !(property->mask & XAW_TPROP_BPIXMAP)) &&
|
|
(combine->mask & XAW_TPROP_BPIXMAP)) {
|
|
property->mask |= XAW_TPROP_BPIXMAP;
|
|
property->background_pixmap = combine->background_pixmap;
|
|
}
|
|
if (combine->mask & XAW_TPROP_UNDERLINE)
|
|
property->mask |= XAW_TPROP_UNDERLINE;
|
|
if (combine->mask & XAW_TPROP_OVERSTRIKE)
|
|
property->mask |= XAW_TPROP_OVERSTRIKE;
|
|
if ((override || !(property->mask & XAW_TPROP_SUPERSCRIPT)) &&
|
|
(combine->mask & XAW_TPROP_SUBSCRIPT))
|
|
property->mask |= XAW_TPROP_SUBSCRIPT;
|
|
if ((property->mask & XAW_TPROP_SUBSCRIPT) &&
|
|
(combine->mask & XAW_TPROP_SUPERSCRIPT))
|
|
property->mask |= XAW_TPROP_SUPERSCRIPT;
|
|
if ((override || !(property->xlfd_mask & XAW_TPROP_FOUNDRY)) &&
|
|
(combine->xlfd_mask & XAW_TPROP_FOUNDRY)) {
|
|
property->xlfd_mask |= XAW_TPROP_FOUNDRY;
|
|
property->foundry = combine->foundry;
|
|
}
|
|
if ((override || !(property->xlfd_mask & XAW_TPROP_FAMILY)) &&
|
|
(combine->xlfd_mask & XAW_TPROP_FAMILY)) {
|
|
property->xlfd_mask |= XAW_TPROP_FAMILY;
|
|
property->family = combine->family;
|
|
}
|
|
if ((override || !(property->xlfd_mask & XAW_TPROP_WEIGHT)) &&
|
|
(combine->xlfd_mask & XAW_TPROP_WEIGHT)) {
|
|
property->xlfd_mask |= XAW_TPROP_WEIGHT;
|
|
property->weight = combine->weight;
|
|
}
|
|
if ((override || !(property->xlfd_mask & XAW_TPROP_SLANT)) &&
|
|
(combine->xlfd_mask & XAW_TPROP_SLANT)) {
|
|
property->xlfd_mask |= XAW_TPROP_SLANT;
|
|
property->slant = combine->slant;
|
|
}
|
|
if ((override || !(property->xlfd_mask & XAW_TPROP_SETWIDTH)) &&
|
|
(combine->xlfd_mask & XAW_TPROP_SETWIDTH)) {
|
|
property->xlfd_mask |= XAW_TPROP_SETWIDTH;
|
|
property->setwidth = combine->setwidth;
|
|
}
|
|
if ((override || !(property->xlfd_mask & XAW_TPROP_ADDSTYLE)) &&
|
|
(combine->xlfd_mask & XAW_TPROP_ADDSTYLE)) {
|
|
property->xlfd_mask |= XAW_TPROP_ADDSTYLE;
|
|
property->addstyle = combine->addstyle;
|
|
}
|
|
if ((override || !(property->xlfd_mask & XAW_TPROP_PIXELSIZE)) &&
|
|
(combine->xlfd_mask & XAW_TPROP_PIXELSIZE)) {
|
|
property->xlfd_mask |= XAW_TPROP_PIXELSIZE;
|
|
property->pixel_size = combine->pixel_size;
|
|
}
|
|
if ((override || !(property->xlfd_mask & XAW_TPROP_POINTSIZE)) &&
|
|
(combine->xlfd_mask & XAW_TPROP_POINTSIZE)) {
|
|
property->xlfd_mask |= XAW_TPROP_POINTSIZE;
|
|
property->point_size = combine->point_size;
|
|
}
|
|
if ((override || !(property->xlfd_mask & XAW_TPROP_RESX)) &&
|
|
(combine->xlfd_mask & XAW_TPROP_RESX)) {
|
|
property->xlfd_mask |= XAW_TPROP_RESX;
|
|
property->res_x = combine->res_x;
|
|
}
|
|
if ((override || !(property->xlfd_mask & XAW_TPROP_RESY)) &&
|
|
(combine->xlfd_mask & XAW_TPROP_RESY)) {
|
|
property->xlfd_mask |= XAW_TPROP_RESY;
|
|
property->res_y = combine->res_y;
|
|
}
|
|
if ((override || !(property->xlfd_mask & XAW_TPROP_SPACING)) &&
|
|
(combine->xlfd_mask & XAW_TPROP_SPACING)) {
|
|
property->xlfd_mask |= XAW_TPROP_SPACING;
|
|
property->spacing = combine->spacing;
|
|
}
|
|
if ((override || !(property->xlfd_mask & XAW_TPROP_AVGWIDTH)) &&
|
|
(combine->xlfd_mask & XAW_TPROP_AVGWIDTH)) {
|
|
property->xlfd_mask |= XAW_TPROP_AVGWIDTH;
|
|
property->avgwidth = combine->avgwidth;
|
|
}
|
|
if ((override || !(property->xlfd_mask & XAW_TPROP_REGISTRY)) &&
|
|
(combine->xlfd_mask & XAW_TPROP_REGISTRY)) {
|
|
property->xlfd_mask |= XAW_TPROP_REGISTRY;
|
|
property->registry = combine->registry;
|
|
}
|
|
if ((override || !(property->xlfd_mask & XAW_TPROP_ENCODING)) &&
|
|
(combine->xlfd_mask & XAW_TPROP_ENCODING)) {
|
|
property->xlfd_mask |= XAW_TPROP_ENCODING;
|
|
property->encoding = combine->encoding;
|
|
}
|
|
|
|
return (property);
|
|
}
|
|
|
|
/*
|
|
* The default property must be defined first, if the code is willing to
|
|
* combine properties.
|
|
*/
|
|
XawTextPropertyList *
|
|
XawTextSinkConvertPropertyList(String name, String spec, Screen *screen,
|
|
Colormap colormap, int depth)
|
|
{
|
|
XrmQuark qname = XrmStringToQuark(name);
|
|
XawTextPropertyList **ptr = NULL;
|
|
XawTextPropertyList *propl, *prev = NULL;
|
|
XawTextProperty *def_prop = NULL;
|
|
String str, tok, tmp;
|
|
char buffer[BUFSIZ];
|
|
|
|
if (prop_lists) ptr = (XawTextPropertyList**)
|
|
bsearch((void*)(long)qname, prop_lists, num_prop_lists,
|
|
sizeof(XawTextPropertyList*), bcmp_qident);
|
|
if (ptr) {
|
|
propl = *ptr;
|
|
while (propl) {
|
|
prev = propl;
|
|
if (propl->screen == screen &&
|
|
propl->colormap == colormap &&
|
|
propl->depth == depth)
|
|
return (propl);
|
|
propl = propl->next;
|
|
}
|
|
}
|
|
|
|
propl = XtNew(XawTextPropertyList);
|
|
propl->identifier = qname;
|
|
propl->screen = screen;
|
|
propl->colormap = colormap;
|
|
propl->depth = depth;
|
|
propl->next = NULL;
|
|
|
|
if (prev)
|
|
prev->next = propl;
|
|
|
|
propl->properties = NULL;
|
|
propl->num_properties = 0;
|
|
|
|
str = XtNewString(spec);
|
|
for (tok = str; tok; tok = tmp) {
|
|
XawTextProperty *prop;
|
|
XawParams *params;
|
|
XrmQuark ident;
|
|
XawArgVal *argval;
|
|
XColor color, exact;
|
|
|
|
if (def_prop == NULL && propl->num_properties)
|
|
def_prop = _XawTextSinkGetProperty(propl, Qdefault);
|
|
tmp = strchr(tok, ',');
|
|
if (tmp) {
|
|
*tmp = '\0';
|
|
if (*++tmp == '\0')
|
|
tmp = NULL;
|
|
}
|
|
params = XawParseParamsString(tok);
|
|
ident = XrmStringToQuark(params->name);
|
|
if (ident == NULLQUARK) {
|
|
XmuSnprintf(buffer, sizeof(buffer),
|
|
"Bad text property name \"%s\".", params->name);
|
|
XtAppWarning(XtDisplayToApplicationContext
|
|
(DisplayOfScreen(screen)), buffer);
|
|
DestroyTextPropertyList(propl);
|
|
if (prev)
|
|
prev->next = NULL;
|
|
XawFreeParamsStruct(params);
|
|
return (NULL);
|
|
}
|
|
else if (_XawTextSinkGetProperty(propl, ident) != NULL) {
|
|
XawFreeParamsStruct(params);
|
|
continue;
|
|
}
|
|
|
|
prop = (XawTextProperty*)XtCalloc(1, sizeof(XawTextProperty));
|
|
prop->identifier = ident;
|
|
|
|
if ((argval = XawFindArgVal(params, "font")) != NULL &&
|
|
argval->value) {
|
|
|
|
if ((prop->font = XLoadQueryFont(DisplayOfScreen(screen),
|
|
argval->value)) == NULL) {
|
|
XmuSnprintf(buffer, sizeof(buffer),
|
|
"Cannot load font \"%s\".", argval->value);
|
|
XtAppWarning(XtDisplayToApplicationContext
|
|
(DisplayOfScreen(screen)), buffer);
|
|
DestroyTextPropertyList(propl);
|
|
if (prev)
|
|
prev->next = NULL;
|
|
XawFreeParamsStruct(params);
|
|
return (NULL);
|
|
}
|
|
prop->mask |= XAW_TPROP_FONT;
|
|
SetXlfdDefaults(DisplayOfScreen(screen), prop);
|
|
}
|
|
/* fontset processing here */
|
|
|
|
if ((argval = XawFindArgVal(params, "foreground")) != NULL &&
|
|
argval->value) {
|
|
if (!XAllocNamedColor(DisplayOfScreen(screen), colormap,
|
|
argval->value, &color, &exact)) {
|
|
XmuSnprintf(buffer, sizeof(buffer),
|
|
"Cannot allocate color \"%s\".", argval->value);
|
|
XtAppWarning(XtDisplayToApplicationContext
|
|
(DisplayOfScreen(screen)), buffer);
|
|
DestroyTextPropertyList(propl);
|
|
if (prev)
|
|
prev->next = NULL;
|
|
XawFreeParamsStruct(params);
|
|
return (NULL);
|
|
}
|
|
prop->foreground = color.pixel;
|
|
prop->mask |= XAW_TPROP_FOREGROUND;
|
|
}
|
|
if ((argval = XawFindArgVal(params, "background")) != NULL &&
|
|
argval->value) {
|
|
if (!XAllocNamedColor(DisplayOfScreen(screen), colormap,
|
|
argval->value, &color, &exact)) {
|
|
XmuSnprintf(buffer, sizeof(buffer),
|
|
"Cannot allocate color \"%s\".", argval->value);
|
|
XtAppWarning(XtDisplayToApplicationContext
|
|
(DisplayOfScreen(screen)), buffer);
|
|
DestroyTextPropertyList(propl);
|
|
if (prev)
|
|
prev->next = NULL;
|
|
XawFreeParamsStruct(params);
|
|
return (NULL);
|
|
}
|
|
prop->background = color.pixel;
|
|
prop->mask |= XAW_TPROP_BACKGROUND;
|
|
}
|
|
/* foreground_pixmap and background_pixmap processing here */
|
|
|
|
if (XawFindArgVal(params, "underline"))
|
|
prop->mask |= XAW_TPROP_UNDERLINE;
|
|
if (XawFindArgVal(params, "overstrike"))
|
|
prop->mask |= XAW_TPROP_OVERSTRIKE;
|
|
|
|
if (XawFindArgVal(params, "subscript"))
|
|
prop->mask |= XAW_TPROP_SUBSCRIPT;
|
|
else if (XawFindArgVal(params, "superscript"))
|
|
prop->mask |= XAW_TPROP_SUPERSCRIPT;
|
|
|
|
/* xlfd */
|
|
if ((argval = XawFindArgVal(params, "foundry")) != NULL &&
|
|
argval->value) {
|
|
prop->xlfd_mask |= XAW_TPROP_FOUNDRY;
|
|
prop->foundry = XrmStringToQuark(argval->value);
|
|
}
|
|
if ((argval = XawFindArgVal(params, "family")) != NULL &&
|
|
argval->value) {
|
|
prop->xlfd_mask |= XAW_TPROP_FAMILY;
|
|
prop->family = XrmStringToQuark(argval->value);
|
|
}
|
|
if ((argval = XawFindArgVal(params, "weight")) != NULL &&
|
|
argval->value) {
|
|
prop->xlfd_mask |= XAW_TPROP_WEIGHT;
|
|
prop->weight = XrmStringToQuark(argval->value);
|
|
}
|
|
if ((argval = XawFindArgVal(params, "slant")) != NULL &&
|
|
argval->value) {
|
|
prop->xlfd_mask |= XAW_TPROP_SLANT;
|
|
prop->slant = XrmStringToQuark(argval->value);
|
|
}
|
|
if ((argval = XawFindArgVal(params, "setwidth")) != NULL &&
|
|
argval->value) {
|
|
prop->xlfd_mask |= XAW_TPROP_SETWIDTH;
|
|
prop->setwidth = XrmStringToQuark(argval->value);
|
|
}
|
|
if ((argval = XawFindArgVal(params, "addstyle")) != NULL &&
|
|
argval->value) {
|
|
prop->xlfd_mask |= XAW_TPROP_ADDSTYLE;
|
|
prop->addstyle = XrmStringToQuark(argval->value);
|
|
}
|
|
if ((argval = XawFindArgVal(params, "pixelsize")) != NULL &&
|
|
argval->value) {
|
|
prop->xlfd_mask |= XAW_TPROP_PIXELSIZE;
|
|
prop->pixel_size = XrmStringToQuark(argval->value);
|
|
}
|
|
if ((argval = XawFindArgVal(params, "pointsize")) != NULL &&
|
|
argval->value) {
|
|
prop->xlfd_mask |= XAW_TPROP_POINTSIZE;
|
|
prop->point_size = XrmStringToQuark(argval->value);
|
|
}
|
|
if ((argval = XawFindArgVal(params, "resx")) != NULL &&
|
|
argval->value) {
|
|
prop->xlfd_mask |= XAW_TPROP_RESX;
|
|
prop->res_x = XrmStringToQuark(argval->value);
|
|
}
|
|
if ((argval = XawFindArgVal(params, "resy")) != NULL &&
|
|
argval->value) {
|
|
prop->xlfd_mask |= XAW_TPROP_RESY;
|
|
prop->res_y = XrmStringToQuark(argval->value);
|
|
}
|
|
if ((argval = XawFindArgVal(params, "spacing")) != NULL &&
|
|
argval->value) {
|
|
prop->xlfd_mask |= XAW_TPROP_SPACING;
|
|
prop->spacing = XrmStringToQuark(argval->value);
|
|
}
|
|
if ((argval = XawFindArgVal(params, "avgwidth")) != NULL &&
|
|
argval->value) {
|
|
prop->xlfd_mask |= XAW_TPROP_AVGWIDTH;
|
|
prop->avgwidth = XrmStringToQuark(argval->value);
|
|
}
|
|
if ((argval = XawFindArgVal(params, "registry")) != NULL &&
|
|
argval->value) {
|
|
prop->xlfd_mask |= XAW_TPROP_REGISTRY;
|
|
prop->registry = XrmStringToQuark(argval->value);
|
|
}
|
|
if ((argval = XawFindArgVal(params, "encoding")) != NULL &&
|
|
argval->value) {
|
|
prop->xlfd_mask |= XAW_TPROP_ENCODING;
|
|
prop->encoding = XrmStringToQuark(argval->value);
|
|
}
|
|
|
|
if (def_prop)
|
|
(void)XawTextSinkCombineProperty(NULL, prop, def_prop, False);
|
|
(void)_XawTextSinkAddProperty(propl, prop, False);
|
|
|
|
XawFreeParamsStruct(params);
|
|
}
|
|
|
|
prop_lists = (XawTextPropertyList**)
|
|
XtRealloc((XtPointer)prop_lists, sizeof(XawTextPropertyList*) *
|
|
(num_prop_lists + 1));
|
|
prop_lists[num_prop_lists++] = propl;
|
|
qsort((void*)prop_lists, num_prop_lists, sizeof(XawTextPropertyList*),
|
|
qcmp_qident);
|
|
|
|
XtFree(str);
|
|
|
|
return (propl);
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
static Boolean
|
|
CvtStringToPropertyList(Display *dpy, XrmValue *args, Cardinal *num_args,
|
|
XrmValue *fromVal, XrmValue *toVal,
|
|
XtPointer *converter_data)
|
|
{
|
|
XawTextPropertyList *propl = NULL;
|
|
String name;
|
|
Widget w;
|
|
|
|
if (*num_args != 1) {
|
|
XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
|
|
"wrongParameters", "cvtStringToTextProperties",
|
|
"ToolkitError",
|
|
"String to textProperties conversion needs widget argument",
|
|
NULL, NULL);
|
|
return (False);
|
|
}
|
|
|
|
w = *(Widget*)args[0].addr;
|
|
while (w && !XtIsWidget(w))
|
|
w = XtParent(w);
|
|
|
|
name = (String)(fromVal[0].addr);
|
|
|
|
if (w) {
|
|
XawTextPropertyList **ptr = NULL;
|
|
if (prop_lists) ptr = (XawTextPropertyList**)
|
|
bsearch((void*)(long)XrmStringToQuark(name),
|
|
prop_lists, num_prop_lists,
|
|
sizeof(XawTextPropertyList*), bcmp_qident);
|
|
|
|
if (ptr) {
|
|
Screen *screen = w->core.screen;
|
|
Colormap colormap = w->core.colormap;
|
|
int depth = w->core.depth;
|
|
|
|
propl = *ptr;
|
|
while (propl) {
|
|
if (propl->screen == screen &&
|
|
propl->colormap == colormap &&
|
|
propl->depth == depth)
|
|
break;
|
|
propl = propl->next;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!propl) {
|
|
XtDisplayStringConversionWarning(dpy, (String)fromVal->addr,
|
|
XawRTextProperties);
|
|
toVal->addr = NULL;
|
|
toVal->size = sizeof(XawTextPropertyList*);
|
|
return (False);
|
|
}
|
|
|
|
if (toVal->addr != NULL) {
|
|
if (toVal->size < sizeof(XawTextPropertyList*)) {
|
|
toVal->size = sizeof(XawTextPropertyList*);
|
|
return (False);
|
|
}
|
|
*(XawTextPropertyList**)(toVal->addr) = propl;
|
|
}
|
|
else {
|
|
static XawTextPropertyList *static_val;
|
|
|
|
static_val = propl;
|
|
toVal->addr = (XPointer)&static_val;
|
|
}
|
|
toVal->size = sizeof(XawTextProperty*);
|
|
|
|
return (True);
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
static Boolean
|
|
CvtPropertyListToString(Display *dpy, XrmValue *args, Cardinal *num_args,
|
|
XrmValue *fromVal, XrmValue *toVal,
|
|
XtPointer *converter_data)
|
|
{
|
|
static char *buffer;
|
|
Cardinal size;
|
|
XawTextPropertyList *propl;
|
|
|
|
propl = *(XawTextPropertyList**)fromVal[0].addr;
|
|
|
|
buffer = XrmQuarkToString(propl->identifier);
|
|
size = strlen(buffer) + 1;
|
|
|
|
if (toVal->addr != NULL) {
|
|
if (toVal->size < size) {
|
|
toVal->size = size;
|
|
return (False);
|
|
}
|
|
strcpy((char *)toVal->addr, buffer);
|
|
}
|
|
else
|
|
toVal->addr = buffer;
|
|
toVal->size = size;
|
|
|
|
return (True);
|
|
}
|
|
#endif
|