aboutsummaryrefslogtreecommitdiff
path: root/libXaw/src/TextSrc.c
diff options
context:
space:
mode:
Diffstat (limited to 'libXaw/src/TextSrc.c')
-rw-r--r--libXaw/src/TextSrc.c4019
1 files changed, 2008 insertions, 2011 deletions
diff --git a/libXaw/src/TextSrc.c b/libXaw/src/TextSrc.c
index 10e819cda..bc055aaca 100644
--- a/libXaw/src/TextSrc.c
+++ b/libXaw/src/TextSrc.c
@@ -1,2011 +1,2008 @@
-/* $Xorg: TextSrc.c,v 1.5 2001/02/09 02:03:47 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/TextSrc.c,v 1.33 2002/09/08 02:29:47 paulo Exp $ */
-
-/*
- * Author: Chris Peterson, MIT X Consortium.
- * Much code taken from X11R3 String and Disk Sources.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdio.h>
-#include <ctype.h>
-#include <X11/IntrinsicP.h>
-#include <X11/StringDefs.h>
-#include <X11/Xfuncs.h>
-#include <X11/Xutil.h>
-#include <X11/Xmu/Atoms.h>
-#include <X11/Xmu/CharSet.h>
-#include <X11/Xaw/TextSrcP.h>
-#include <X11/Xaw/XawInit.h>
-#include "XawI18n.h"
-#include "Private.h"
-
-#ifndef OLDXAW
-#define UNDO_DEPTH 16384
-
-#define ANCHORS_DIST 4096 /* default distance between anchors */
-
-/*
- * Types
- */
-typedef struct {
- XawTextPosition position;
- char *buffer;
- unsigned length;
- unsigned refcount;
- unsigned long format;
-} XawTextUndoBuffer;
-
-typedef struct _XawTextUndoList XawTextUndoList;
-struct _XawTextUndoList {
- XawTextUndoBuffer *left, *right;
- XawTextUndoList *undo, *redo;
-};
-
-struct _XawTextUndo {
- XawTextUndoBuffer **undo;
- unsigned num_undo;
- XawTextUndoList *list, *pointer, *end_mark, *head;
- unsigned num_list;
- XawTextScanDirection dir;
- XawTextUndoBuffer *l_save, *r_save;
- XawTextUndoList *u_save;
- XawTextUndoBuffer *l_no_change, *r_no_change;
- int merge;
- int erase; /* there are two types of erases */
-};
-#endif /* OLDXAW */
-
-/*
- * Class Methods
- */
-static Boolean ConvertSelection(Widget, Atom*, Atom*, Atom*, XtPointer*,
- unsigned long*, int*);
-static XawTextPosition Read(Widget, XawTextPosition, XawTextBlock*, int);
-static int Replace(Widget, XawTextPosition, XawTextPosition, XawTextBlock*);
-static XawTextPosition Scan(Widget, XawTextPosition, XawTextScanType,
- XawTextScanDirection, int, Bool);
-static XawTextPosition Search(Widget, XawTextPosition, XawTextScanDirection,
- XawTextBlock*);
-static void SetSelection(Widget, XawTextPosition, XawTextPosition, Atom);
-static void XawTextSrcClassInitialize(void);
-static void XawTextSrcClassPartInitialize(WidgetClass);
-static void XawTextSrcInitialize(Widget, Widget, ArgList, Cardinal*);
-static void XawTextSrcDestroy(Widget);
-static Boolean XawTextSrcSetValues(Widget, Widget, Widget, ArgList, Cardinal*);
-/*
- * Prototypes
- */
-static void CvtStringToEditMode(XrmValuePtr, Cardinal*,
- XrmValuePtr, XrmValuePtr);
-static Boolean CvtEditModeToString(Display*, XrmValuePtr, Cardinal*,
- XrmValuePtr, XrmValuePtr, XtPointer*);
-#ifndef OLDXAW
-static void FreeUndoBuffer(XawTextUndo*);
-static void UndoGC(XawTextUndo*);
-static void TellSourceChanged(TextSrcObject, XawTextPosition, XawTextPosition,
- XawTextBlock*, int);
-Bool _XawTextSrcUndo(TextSrcObject, XawTextPosition*);
-Bool _XawTextSrcToggleUndo(TextSrcObject);
-XawTextAnchor *_XawTextSourceFindAnchor(Widget, XawTextPosition);
-
-/*
- * External
- */
-void _XawSourceAddText(Widget, Widget);
-void _XawSourceRemoveText(Widget, Widget, Bool);
-Bool _XawTextSourceNewLineAtEOF(Widget);
-void _XawSourceSetUndoErase(TextSrcObject, int);
-void _XawSourceSetUndoMerge(TextSrcObject, Bool);
-#endif /* OLDXAW */
-
-/*
- * Defined in Text.c
- */
-char *_XawTextGetText(TextWidget, XawTextPosition, XawTextPosition);
-void _XawTextSourceChanged(Widget, XawTextPosition, XawTextPosition,
- XawTextBlock*, int);
-
-/*
- * Initialization
- */
-#define offset(field) XtOffsetOf(TextSrcRec, textSrc.field)
-static XtResource resources[] = {
- {
- XtNeditType,
- XtCEditType,
- XtREditMode,
- sizeof(XawTextEditType),
- offset(edit_mode),
- XtRString,
- "read"
- },
-#ifndef OLDXAW
- {
- XtNcallback,
- XtCCallback,
- XtRCallback,
- sizeof(XtPointer),
- offset(callback),
- XtRCallback,
- NULL
- },
- {
- XtNsourceChanged,
- XtCChanged,
- XtRBoolean,
- sizeof(Boolean),
- offset(changed),
- XtRImmediate,
- (XtPointer)False
- },
- {
- XtNenableUndo,
- XtCUndo,
- XtRBoolean,
- sizeof(Boolean),
- offset(enable_undo),
- XtRImmediate,
- (XtPointer)False
- },
- {
- XtNpropertyCallback,
- XtCCallback,
- XtRCallback,
- sizeof(XtPointer),
- offset(property_callback),
- XtRCallback,
- NULL
- },
-#endif /* OLDXAW */
-};
-#undef offset
-
-#define Superclass (&objectClassRec)
-TextSrcClassRec textSrcClassRec = {
- /* object */
- {
- (WidgetClass)Superclass, /* superclass */
- "TextSrc", /* class_name */
- sizeof(TextSrcRec), /* widget_size */
- XawTextSrcClassInitialize, /* class_initialize */
- XawTextSrcClassPartInitialize, /* class_part_initialize */
- False, /* class_inited */
- XawTextSrcInitialize, /* initialize */
- NULL, /* initialize_hook */
- NULL, /* realize */
- NULL, /* actions */
- 0, /* num_actions */
- resources, /* resources */
- XtNumber(resources), /* num_resources */
- NULLQUARK, /* xrm_class */
- False, /* compress_motion */
- False, /* compress_exposure */
- False, /* compress_enterleave */
- False, /* visible_interest */
- XawTextSrcDestroy, /* destroy */
- NULL, /* resize */
- NULL, /* expose */
- XawTextSrcSetValues, /* set_values */
- NULL, /* set_values_hook */
- NULL, /* set_values_almost */
- NULL, /* get_values_hook */
- NULL, /* accept_focus */
- XtVersion, /* version */
- NULL, /* callback_private */
- NULL, /* tm_table */
- NULL, /* query_geometry */
- NULL, /* display_accelerator */
- NULL, /* extension */
- },
- /* text_src */
- {
- Read, /* Read */
- Replace, /* Replace */
- Scan, /* Scan */
- Search, /* Search */
- SetSelection, /* SetSelection */
- ConvertSelection, /* ConvertSelection */
- },
-};
-
-WidgetClass textSrcObjectClass = (WidgetClass)&textSrcClassRec;
-
-static XrmQuark QRead, QAppend, QEdit;
-#ifndef OLDXAW
-static char *SrcNL = "\n";
-static wchar_t SrcWNL[2];
-#endif
-
-/*
- * Implementation
- */
-static void
-XawTextSrcClassInitialize(void)
-{
- XawInitializeWidgetSet();
-
-#ifndef OLDXAW
- SrcWNL[0] = _Xaw_atowc(XawLF);
- SrcWNL[1] = 0;
-#endif
- QRead = XrmPermStringToQuark(XtEtextRead);
- QAppend = XrmPermStringToQuark(XtEtextAppend);
- QEdit = XrmPermStringToQuark(XtEtextEdit);
- XtAddConverter(XtRString, XtREditMode, CvtStringToEditMode, NULL, 0);
- XtSetTypeConverter(XtREditMode, XtRString, CvtEditModeToString, NULL, 0,
- XtCacheNone, NULL);
-}
-
-static void
-XawTextSrcClassPartInitialize(WidgetClass wc)
-{
- TextSrcObjectClass t_src, superC;
-
- t_src = (TextSrcObjectClass)wc;
- superC = (TextSrcObjectClass)t_src->object_class.superclass;
-
- /*
- * We don't need to check for null super since we'll get to TextSrc
- * eventually
- */
- if (t_src->textSrc_class.Read == XtInheritRead)
- t_src->textSrc_class.Read = superC->textSrc_class.Read;
-
- if (t_src->textSrc_class.Replace == XtInheritReplace)
- t_src->textSrc_class.Replace = superC->textSrc_class.Replace;
-
- if (t_src->textSrc_class.Scan == XtInheritScan)
- t_src->textSrc_class.Scan = superC->textSrc_class.Scan;
-
- if (t_src->textSrc_class.Search == XtInheritSearch)
- t_src->textSrc_class.Search = superC->textSrc_class.Search;
-
- if (t_src->textSrc_class.SetSelection == XtInheritSetSelection)
- t_src->textSrc_class.SetSelection = superC->textSrc_class.SetSelection;
-
- if (t_src->textSrc_class.ConvertSelection == XtInheritConvertSelection)
- t_src->textSrc_class.ConvertSelection =
- superC->textSrc_class.ConvertSelection;
-}
-
-/*ARGSUSED*/
-static void
-XawTextSrcInitialize(Widget request, Widget cnew,
- ArgList args, Cardinal *num_args)
-{
-#ifndef OLDXAW
- TextSrcObject src = (TextSrcObject)cnew;
-
- if (src->textSrc.enable_undo) {
- src->textSrc.undo = (XawTextUndo*)XtCalloc(1, sizeof(XawTextUndo));
- src->textSrc.undo->dir = XawsdLeft;
- }
- else
- src->textSrc.undo = NULL;
- src->textSrc.undo_state = False;
- if (XtIsSubclass(XtParent(cnew), textWidgetClass)) {
- src->textSrc.text = (WidgetList)XtMalloc(sizeof(Widget*));
- src->textSrc.text[0] = XtParent(cnew);
- src->textSrc.num_text = 1;
- }
- else {
- src->textSrc.text = NULL;
- src->textSrc.num_text = 0;
- }
-
- src->textSrc.anchors = NULL;
- src->textSrc.num_anchors = 0;
- (void)XawTextSourceAddAnchor(cnew, 0);
-#endif /* OLDXAW */
-}
-
-static void
-XawTextSrcDestroy(Widget w)
-{
-#ifndef OLDXAW
- TextSrcObject src = (TextSrcObject)w;
-
- if (src->textSrc.enable_undo) {
- FreeUndoBuffer(src->textSrc.undo);
- XtFree((char*)src->textSrc.undo);
- }
- XtFree((char*)src->textSrc.text);
-
- if (src->textSrc.num_anchors) {
- XawTextEntity *entity, *enext;
- int i;
-
- for (i = 0; i < src->textSrc.num_anchors; i++) {
- entity = src->textSrc.anchors[i]->entities;
- while (entity) {
- enext = entity->next;
- XtFree((XtPointer)entity);
- entity = enext;
- }
- XtFree((XtPointer)src->textSrc.anchors[i]);
- }
- XtFree((XtPointer)src->textSrc.anchors);
- }
-#endif /* OLDXAW */
-}
-
-/*ARGSUSED*/
-static Boolean
-XawTextSrcSetValues(Widget current, Widget request, Widget cnew,
- ArgList args, Cardinal *num_args)
-{
-#ifndef OLDXAW
- TextSrcObject oldtw = (TextSrcObject)current;
- TextSrcObject newtw = (TextSrcObject)cnew;
-
- if (oldtw->textSrc.enable_undo != newtw->textSrc.enable_undo) {
- if (newtw->textSrc.enable_undo) {
- newtw->textSrc.undo = (XawTextUndo*)
- XtCalloc(1, sizeof(XawTextUndo));
- newtw->textSrc.undo->dir = XawsdLeft;
- }
- else {
- FreeUndoBuffer(newtw->textSrc.undo);
- XtFree((char*)newtw->textSrc.undo);
- newtw->textSrc.undo = NULL;
- }
- }
- if (oldtw->textSrc.changed != newtw->textSrc.changed) {
- if (newtw->textSrc.enable_undo) {
- if (newtw->textSrc.undo->list) {
- newtw->textSrc.undo->l_no_change =
- newtw->textSrc.undo->list->left;
- newtw->textSrc.undo->r_no_change =
- newtw->textSrc.undo->list->right;
- }
- else
- newtw->textSrc.undo->l_no_change =
- newtw->textSrc.undo->r_no_change = NULL;
- }
- }
-#endif /* OLDXAW */
- return (False);
-}
-
-/*
- * Function:
- * Read
- *
- * Parameters:
- * w - TextSrc Object
- * pos - position of the text to retreive
- * text - text block that will contain returned text
- * length - maximum number of characters to read
- *
- * Description:
- * This function reads the source.
- *
- * Returns:
- * The character position following the retrieved text.
- */
-/*ARGSUSED*/
-static XawTextPosition
-Read(Widget w, XawTextPosition pos, XawTextBlock *text, int length)
-{
- return ((XawTextPosition)0);
-}
-
-/*
- * Function:
- * Replace
- *
- * Parameters:
- * src - Text Source Object
- * startPos - ends of text that will be removed
- * endPos - ""
- * text - new text to be inserted into buffer at startPos
- *
- * Description:
- * Replaces a block of text with new text.
- */
-/*ARGSUSED*/
-static int
-Replace(Widget w, XawTextPosition startPos, XawTextPosition endPos,
- XawTextBlock *text)
-{
- return (XawEditError);
-}
-
-/*
- * Function:
- * Scan
- *
- * Parameters:
- * w - TextSrc Object
- * position - position to start scanning
- * type - type of thing to scan for
- * dir - direction to scan
- * count - which occurance if this thing to search for
- * include - whether or not to include the character found in
- * the position that is returned
- *
- * Description:
- * Scans the text source for the number and type of item specified.
- */
-/*ARGSUSED*/
-static XawTextPosition
-Scan(Widget w, XawTextPosition position, XawTextScanType type,
- XawTextScanDirection dir, int count, Bool include)
-{
- return ((XawTextPosition)0);
-}
-
-/*
- * Function:
- * Search
- *
- * Parameters:
- * w - TextSource Object
- * position - position to start searching
- * dir - direction to search
- * text - the text block to search for
- *
- * Description:
- * Searchs the text source for the text block passed
- */
-/*ARGSUSED*/
-static XawTextPosition
-Search(Widget w, XawTextPosition position, XawTextScanDirection dir,
- XawTextBlock *text)
-{
- return (XawTextSearchError);
-}
-
-/*ARGSUSED*/
-static Boolean
-ConvertSelection(Widget w, Atom *selection, Atom *target, Atom *type,
- XtPointer *value, unsigned long *length, int *format)
-{
- return (False);
-}
-
-/*ARGSUSED*/
-static void
-SetSelection(Widget w, XawTextPosition left, XawTextPosition right,
- Atom selection)
-{
-}
-
-/*ARGSUSED*/
-static void
-CvtStringToEditMode(XrmValuePtr args, Cardinal *num_args,
- XrmValuePtr fromVal, XrmValuePtr toVal)
-{
- static XawTextEditType editType;
- XrmQuark q;
- char name[7];
-
- XmuNCopyISOLatin1Lowered(name, (char *)fromVal->addr, sizeof(name));
- q = XrmStringToQuark(name);
-
- if (q == QRead)
- editType = XawtextRead;
- else if (q == QAppend)
- editType = XawtextAppend;
- else if (q == QEdit)
- editType = XawtextEdit;
- else {
- toVal->size = 0;
- toVal->addr = NULL;
- XtStringConversionWarning((char *)fromVal->addr, XtREditMode);
- }
- toVal->size = sizeof(XawTextEditType);
- toVal->addr = (XPointer)&editType;
-}
-
-/*ARGSUSED*/
-static Boolean
-CvtEditModeToString(Display *dpy, XrmValuePtr args, Cardinal *num_args,
- XrmValuePtr fromVal, XrmValuePtr toVal,
- XtPointer *data)
-{
- static String buffer;
- Cardinal size;
-
- switch (*(XawTextEditType *)fromVal->addr) {
- case XawtextAppend:
- case XawtextRead:
- buffer = XtEtextRead;
- break;
- buffer = XtEtextAppend;
- break;
- case XawtextEdit:
- buffer = XtEtextEdit;
- break;
- default:
- XawTypeToStringWarning(dpy, XtREditMode);
- toVal->addr = NULL;
- toVal->size = 0;
- return (False);
- }
-
- size = strlen(buffer) + 1;
- if (toVal->addr != NULL) {
- if (toVal->size < size) {
- toVal->size = size;
- return (False);
- }
- strcpy((char *)toVal->addr, buffer);
- }
- else
- toVal->addr = (XPointer)buffer;
- toVal->size = sizeof(String);
-
- return (True);
-}
-
-#ifndef OLDXAW
-Bool
-_XawTextSourceNewLineAtEOF(Widget w)
-{
- TextSrcObject src = (TextSrcObject)w;
- XawTextBlock text;
-
- text.firstPos = 0;
- if ((text.format = src->textSrc.text_format) == XawFmt8Bit)
- text.ptr = SrcNL;
- else
- text.ptr = (char*)SrcWNL;
- text.length = 1;
-
- return (XawTextSourceSearch(w, XawTextSourceScan(w, 0, XawstAll,
- XawsdRight, 1, True) - 1,
- XawsdRight, &text) != XawTextSearchError);
-}
-
-void
-_XawSourceAddText(Widget source, Widget text)
-{
- TextSrcObject src = (TextSrcObject)source;
- Bool found = False;
- Cardinal i;
-
- for (i = 0; i < src->textSrc.num_text; i++)
- if (src->textSrc.text[i] == text) {
- found = True;
- break;
- }
-
- if (!found) {
- src->textSrc.text = (WidgetList)
- XtRealloc((char*)src->textSrc.text,
- sizeof(Widget) * (src->textSrc.num_text + 1));
- src->textSrc.text[src->textSrc.num_text++] = text;
- }
-}
-
-void
-_XawSourceRemoveText(Widget source, Widget text, Bool destroy)
-{
- TextSrcObject src = (TextSrcObject)source;
- Bool found = False;
- Cardinal i;
-
- if (src == NULL)
- return;
-
- for (i = 0; i < src->textSrc.num_text; i++)
- if (src->textSrc.text[i] == text) {
- found = True;
- break;
- }
-
- if (found) {
- if (--src->textSrc.num_text == 0) {
- if (destroy) {
- XtDestroyWidget(source);
- return;
- }
- else {
- XtFree((char*)src->textSrc.text);
- src->textSrc.text = NULL; /* for realloc "magic" */
- }
- }
- else if (i < src->textSrc.num_text)
- memmove(&src->textSrc.text[i], &src->textSrc.text[i + 1],
- sizeof(Widget) * (src->textSrc.num_text - i));
- }
-}
-#endif /* OLDXAW */
-
-/*
- * Function:
- * XawTextSourceRead
- *
- * Parameters:
- * w - TextSrc Object
- * pos - position of the text to retrieve
- * text - text block that will contain returned text (return)
- * length - maximum number of characters to read
- *
- * Description:
- * This function reads the source.
- *
- * Returns:
- * The number of characters read into the buffer
- */
-XawTextPosition
-XawTextSourceRead(Widget w, XawTextPosition pos, XawTextBlock *text,
- int length)
-{
- TextSrcObjectClass cclass = (TextSrcObjectClass)w->core.widget_class;
-
- return ((*cclass->textSrc_class.Read)(w, pos, text, length));
-}
-
-#ifndef OLDXAW
-static void
-TellSourceChanged(TextSrcObject src, XawTextPosition left,
- XawTextPosition right, XawTextBlock *block, int lines)
-{
- Cardinal i;
-
- for (i = 0; i < src->textSrc.num_text; i++)
- _XawTextSourceChanged(src->textSrc.text[i], left, right, block, lines);
-}
-
-/*
- * This function is required because there is no way to diferentiate
- * if the first erase was generated by a backward-kill-char and the
- * second by a forward-kill-char (or vice-versa) from XawTextSourceReplace.
- * It is only possible to diferentiate after the second character is
- * killed, but then, it is too late.
- */
-void
-_XawSourceSetUndoErase(TextSrcObject src, int value)
-{
- if (src && src->textSrc.enable_undo)
- src->textSrc.undo->erase = value;
-}
-
-/*
- * To diferentiate insert-char's separeted by cursor movements.
- */
-void
-_XawSourceSetUndoMerge(TextSrcObject src, Bool state)
-{
- if (src && src->textSrc.enable_undo)
- src->textSrc.undo->merge += state ? 1 : -1;
-}
-#endif /* OLDXAW */
-
-/*
- * Public Functions
- */
-/*
- * Function:
- * XawTextSourceReplace
- *
- * Parameters:
- * src - Text Source Object
- * startPos - ends of text that will be removed
- * endPos - ""
- * text - new text to be inserted into buffer at startPos
- *
- * Description:
- * Replaces a block of text with new text.
- *
- * Returns:
- * XawEditError or XawEditDone.
- */
-/*ARGSUSED*/
-int
-XawTextSourceReplace(Widget w, XawTextPosition left,
- XawTextPosition right, XawTextBlock *block)
-{
- TextSrcObjectClass cclass = (TextSrcObjectClass)w->core.widget_class;
-#ifndef OLDXAW
- TextSrcObject src = (TextSrcObject)w;
- XawTextUndoBuffer *l_state, *r_state;
- XawTextUndoList *undo;
- Bool enable_undo;
- XawTextPosition start, end;
- int i, error, lines = 0;
-
- if (src->textSrc.edit_mode == XawtextRead)
- return (XawEditError);
-
- enable_undo = src->textSrc.enable_undo && src->textSrc.undo_state == False;
- if (enable_undo) {
- unsigned size, total;
-
- if (src->textSrc.undo->l_save) {
- l_state = src->textSrc.undo->l_save;
- src->textSrc.undo->l_save = NULL;
- }
- else
- l_state = XtNew(XawTextUndoBuffer);
- l_state->refcount = 1;
- l_state->position = left;
- if (left < right) {
- Widget ctx = NULL;
-
- for (i = 0; i < src->textSrc.num_text; i++)
- if (XtIsSubclass(src->textSrc.text[i], textWidgetClass)) {
- ctx = src->textSrc.text[i];
- break;
- }
- l_state->buffer = _XawTextGetText((TextWidget)ctx, left, right);
- l_state->length = right - left;
- }
- else {
- l_state->length = 0;
- l_state->buffer = NULL;
- }
- l_state->format = src->textSrc.text_format;
- if (l_state->length == 1) {
- if (l_state->format == XawFmtWide &&
- *(wchar_t*)l_state->buffer == *SrcWNL) {
- XtFree(l_state->buffer);
- l_state->buffer = (char*)SrcWNL;
- }
- else if (*l_state->buffer == '\n') {
- XtFree(l_state->buffer);
- l_state->buffer = SrcNL;
- }
- }
-
- if (src->textSrc.undo->r_save) {
- r_state = src->textSrc.undo->r_save;
- src->textSrc.undo->r_save = NULL;
- }
- else
- r_state = XtNew(XawTextUndoBuffer);
- r_state->refcount = 1;
- r_state->position = left;
- r_state->format = block->format;
- size = block->format == XawFmtWide ? sizeof(wchar_t) : sizeof(char);
- total = size * block->length;
- r_state->length = block->length;
- r_state->buffer = NULL;
- if (total == size) {
- if (r_state->format == XawFmtWide &&
- *(wchar_t*)block->ptr == *SrcWNL)
- r_state->buffer = (char*)SrcWNL;
- else if (*block->ptr == '\n')
- r_state->buffer = SrcNL;
- }
- if (total && !r_state->buffer) {
- r_state->buffer = XtMalloc(total);
- memcpy(r_state->buffer, block->ptr, total);
- }
-
- if (src->textSrc.undo->u_save) {
- undo = src->textSrc.undo->u_save;
- src->textSrc.undo->u_save = NULL;
- }
- else
- undo = XtNew(XawTextUndoList);
- undo->left = l_state;
- undo->right = r_state;
- undo->undo = src->textSrc.undo->list;
- undo->redo = NULL;
- }
- else {
- undo = NULL;
- l_state = r_state = NULL;
- }
-
-#define LARGE_VALUE 262144 /* 256 K */
- /* optimization, to avoid long delays recalculating the line number
- * when editing huge files
- */
- if (left > LARGE_VALUE) {
- start = XawTextSourceScan(w, left, XawstEOL, XawsdLeft, 2, False);
- for (i = 0; i < src->textSrc.num_text; i++) {
- TextWidget tw = (TextWidget)src->textSrc.text[i];
-
- if (left <= tw->text.lt.top &&
- left + block->length - (right - left) > tw->text.lt.top)
- _XawTextBuildLineTable(tw, start, False);
- }
- }
-#undef LARGE_VALUE
-
- start = left;
- end = right;
- while (start < end) {
- start = XawTextSourceScan(w, start, XawstEOL, XawsdRight, 1, True);
- if (start <= end) {
- --lines;
- if (start == XawTextSourceScan(w, 0, XawstAll, XawsdRight, 1, True)) {
- lines += !_XawTextSourceNewLineAtEOF(w);
- break;
- }
- }
- }
-#else
- int error;
-#endif /* OLDXAW */
-
- error = (*cclass->textSrc_class.Replace)(w, left, right, block);
-
-#ifndef OLDXAW
- if (error != XawEditDone) {
- if (enable_undo) {
- if (l_state->buffer) {
- if (l_state->buffer != SrcNL && l_state->buffer != (char*)SrcWNL)
- XtFree(l_state->buffer);
- l_state->buffer = NULL;
- }
- src->textSrc.undo->l_save = l_state;
- if (r_state->buffer) {
- if (r_state->buffer != SrcNL && r_state->buffer != (char*)SrcWNL)
- XtFree(r_state->buffer);
- r_state->buffer = NULL;
- }
- src->textSrc.undo->r_save = r_state;
-
- src->textSrc.undo->u_save = undo;
- }
- }
- else if (enable_undo) {
- XawTextUndoList *list = src->textSrc.undo->list;
- XawTextUndoBuffer *unl, *lnl;
- int erase = undo->right->length == 0 && undo->left->length == 1 && list
- && list->right->length == 0;
-
- if (erase) {
- erase = list->left->position - 1 == undo->left->position ? -1 :
- list->left->position == undo->left->position ? 1 : 0;
- if (src->textSrc.undo->erase && erase != src->textSrc.undo->erase)
- erase = 0;
- else
- src->textSrc.undo->erase = erase;
- }
-
- if (erase) {
- unl = l_state;
- lnl = list->left;
- }
- else {
- unl = r_state;
- lnl = list ? list->right : NULL;
- }
-
- /* Try to merge the undo buffers */
- if (src->textSrc.undo->merge > 0 && ((erase ||
- (list && ((list->left->length == 0 && undo->left->length == 0) ||
- (list->left->length == list->right->length &&
- undo->left->length == 1)) &&
- undo->right->length == 1 &&
- list->right->position + list->right->length
- == undo->right->position))
- && src->textSrc.undo->pointer == list
- && unl->format == list->right->format
- && ((unl->format == XawFmt8Bit && unl->buffer[0] != XawLF) ||
- (unl->format == XawFmtWide &&
- *(wchar_t*)(unl->buffer) != _Xaw_atowc(XawLF)))
- && ((lnl->format == XawFmt8Bit && lnl->buffer[0] != XawLF) ||
- (lnl->format == XawFmtWide &&
- *(wchar_t*)(lnl->buffer) != _Xaw_atowc(XawLF))))) {
- unsigned size = lnl->format == XawFmtWide ?
- sizeof(wchar_t) : sizeof(char);
-
- if (!erase) {
- list->right->buffer = XtRealloc(list->right->buffer,
- (list->right->length + 1) * size);
- memcpy(list->right->buffer + list->right->length * size,
- undo->right->buffer, size);
- ++list->right->length;
- XtFree(r_state->buffer);
- }
- else if (erase < 0) {
- --list->left->position;
- --list->right->position;
- }
-
- src->textSrc.undo->l_save = l_state;
- src->textSrc.undo->r_save = r_state;
- src->textSrc.undo->u_save = undo;
-
- if (list->left->length) {
- list->left->buffer = XtRealloc(list->left->buffer,
- (list->left->length + 1) * size);
- if (erase >= 0)
- memcpy(list->left->buffer + list->left->length * size,
- undo->left->buffer, size);
- else {
- /* use memmove, since strings overlap */
- memmove(list->left->buffer + size, list->left->buffer,
- list->left->length * size);
- memcpy(list->left->buffer, undo->left->buffer, size);
- }
- ++list->left->length;
- if (l_state->buffer != SrcNL && l_state->buffer != (char*)SrcWNL)
- XtFree(l_state->buffer);
- }
-
- if (src->textSrc.undo->num_list >= UNDO_DEPTH)
- UndoGC(src->textSrc.undo);
- }
- else {
- src->textSrc.undo->undo = (XawTextUndoBuffer**)
- XtRealloc((char*)src->textSrc.undo->undo,
- (2 + src->textSrc.undo->num_undo)
- * sizeof(XawTextUndoBuffer));
- src->textSrc.undo->undo[src->textSrc.undo->num_undo++] = l_state;
- src->textSrc.undo->undo[src->textSrc.undo->num_undo++] = r_state;
-
- if (src->textSrc.undo->list)
- src->textSrc.undo->list->redo = undo;
- else
- src->textSrc.undo->head = undo;
-
- src->textSrc.undo->merge = l_state->length <= 1 &&
- r_state->length <= 1;
-
- src->textSrc.undo->list = src->textSrc.undo->pointer =
- src->textSrc.undo->end_mark = undo;
-
- if (++src->textSrc.undo->num_list >= UNDO_DEPTH)
- UndoGC(src->textSrc.undo);
- }
- src->textSrc.undo->dir = XawsdLeft;
- if (!src->textSrc.changed) {
- src->textSrc.undo->l_no_change = src->textSrc.undo->list->right;
- src->textSrc.undo->r_no_change = src->textSrc.undo->list->left;
- src->textSrc.changed = True;
- }
- }
- else if (!src->textSrc.enable_undo)
- src->textSrc.changed = True;
-
- if (error == XawEditDone) {
- XawTextPropertyInfo info;
- XawTextAnchor *anchor;
-
- /* find anchor and index */
- /* XXX index (i) could be returned by XawTextSourceFindAnchor
- * or similar function, to speed up */
- if ((anchor = XawTextSourceFindAnchor(w, left))) {
- XawTextEntity *eprev, *entity, *enext;
- XawTextPosition offset = 0, diff = block->length - (right - left);
-
- for (i = 0; i < src->textSrc.num_anchors; i++)
- if (src->textSrc.anchors[i] == anchor)
- break;
- if (anchor->cache && anchor->position + anchor->cache->offset +
- anchor->cache->length <= left)
- eprev = entity = anchor->cache;
- else
- eprev = entity = anchor->entities;
- while (entity) {
- offset = anchor->position + entity->offset;
-
- if (offset > left)
- break;
- if (offset + entity->length > left)
- break;
-
- eprev = entity;
- entity = entity->next;
- }
-
- /* try to do the right thing here (and most likely correct), but
- * other code needs to check what was done */
-
- /* adjust entity length */
- if (entity && offset <= left) {
- if (offset + entity->length < right)
- entity->length = left - offset + block->length;
- else
- entity->length += diff;
-
- if (entity->length == 0) {
- enext = entity->next;
- eprev->next = enext;
- anchor->cache = NULL;
- XtFree((XtPointer)entity);
- if (entity == anchor->entities) {
- if ((anchor->entities = enext) == NULL) {
- eprev = NULL;
- anchor = XawTextSourceRemoveAnchor(w, anchor);
- entity = anchor ? anchor->entities : NULL;
- }
- else
- eprev = entity = enext;
- }
- else
- entity = enext;
- }
- else {
- eprev = entity;
- entity = entity->next;
- }
- }
-
- while (anchor) {
- while (entity) {
- offset = anchor->position + entity->offset + entity->length;
-
- if (offset > right) {
- entity->length = XawMin(entity->length, offset - right);
- goto exit_anchor_loop;
- }
-
- enext = entity->next;
- if (eprev)
- eprev->next = enext;
- XtFree((XtPointer)entity);
- anchor->cache = NULL;
- if (entity == anchor->entities) {
- eprev = NULL;
- if ((anchor->entities = enext) == NULL) {
- if (i == 0)
- ++i;
- else if (i < --src->textSrc.num_anchors) {
- memmove(&src->textSrc.anchors[i],
- &src->textSrc.anchors[i + 1],
- (src->textSrc.num_anchors - i) *
- sizeof(XawTextAnchor*));
- XtFree((XtPointer)anchor);
- }
- if (i >= src->textSrc.num_anchors) {
- anchor = NULL;
- entity = NULL;
- break;
- }
- anchor = src->textSrc.anchors[i];
- entity = anchor->entities;
- continue;
- }
- }
- entity = enext;
- }
- if (i + 1 < src->textSrc.num_anchors) {
- anchor = src->textSrc.anchors[++i];
- entity = anchor->entities;
- eprev = NULL;
- }
- else {
- anchor = NULL;
- break;
- }
- eprev = NULL;
- }
-
-exit_anchor_loop:
- if (anchor) {
- XawTextAnchor *aprev;
-
- if (anchor->position >= XawMax(right, left + block->length))
- anchor->position += diff;
- else if (anchor->position > left &&
- (aprev = XawTextSourcePrevAnchor(w, anchor))) {
- XawTextPosition tmp = anchor->position - aprev->position;
-
- if (diff) {
- while (entity) {
- entity->offset += diff;
- entity = entity->next;
- }
- }
- entity = anchor->entities;
- while (entity) {
- entity->offset += tmp;
- entity = entity->next;
- }
- if ((entity = aprev->entities) == NULL)
- aprev->entities = anchor->entities;
- else {
- while (entity->next)
- entity = entity->next;
- entity->next = anchor->entities;
- }
- anchor->entities = NULL;
- (void)XawTextSourceRemoveAnchor(w, anchor);
- --i;
- }
- else if (diff) {
- while (entity) {
- entity->offset += diff;
- entity = entity->next;
- }
- }
- }
-
- if (diff) {
- /* The first anchor is never removed, and should
- * have position 0.
- * i should be -1 if attempted to removed the first
- * anchor, what can be caused when removing a chunk
- * of text of the first entity.
- * */
- if (++i == 0) {
- anchor = src->textSrc.anchors[0];
- eprev = entity = anchor->entities;
- while (entity) {
- enext = entity->next;
- if (entity->offset + entity->length <= -diff)
- XtFree((XtPointer)entity);
- else
- break;
- entity = enext;
- }
- if (eprev != entity) {
- anchor->cache = NULL;
- if ((anchor->entities = entity) != NULL) {
- if ((entity->offset += diff) < 0) {
- entity->length += entity->offset;
- entity->offset = 0;
- }
- }
- }
- ++i;
- }
- for (; i < src->textSrc.num_anchors; i++)
- src->textSrc.anchors[i]->position += diff;
- }
- }
-
- start = left;
- end = start + block->length;
- while (start < end) {
- start = XawTextSourceScan(w, start, XawstEOL, XawsdRight, 1, True);
- if (start <= end) {
- ++lines;
- if (start == XawTextSourceScan(w, 0, XawstAll, XawsdRight, 1, True)) {
- lines -= !_XawTextSourceNewLineAtEOF(w);
- break;
- }
- }
- }
-
- info.left = left;
- info.right = right;
- info.block = block;
- XtCallCallbacks(w, XtNpropertyCallback, &info);
-
- TellSourceChanged(src, left, right, block, lines);
- /* Call callbacks, we have changed the buffer */
- XtCallCallbacks(w, XtNcallback,
- (XtPointer)((long)src->textSrc.changed));
- }
-
-#endif /* OLDXAW */
- return (error);
-}
-
-#ifndef OLDXAW
-Bool
-_XawTextSrcUndo(TextSrcObject src, XawTextPosition *insert_pos)
-{
- static wchar_t wnull = 0;
- XawTextBlock block;
- XawTextUndoList *list, *nlist;
- XawTextUndoBuffer *l_state, *r_state;
- Boolean changed = src->textSrc.changed;
-
- if (!src->textSrc.enable_undo || !src->textSrc.undo->num_undo)
- return (False);
-
- list = src->textSrc.undo->pointer;
-
- if (src->textSrc.undo->dir == XawsdLeft) {
- l_state = list->right;
- r_state = list->left;
- }
- else {
- l_state = list->left;
- r_state = list->right;
- }
-
- if (src->textSrc.undo->l_no_change == l_state
- && src->textSrc.undo->r_no_change == r_state)
- src->textSrc.changed = False;
- else
- src->textSrc.changed = True;
-
- block.firstPos = 0;
- block.length = r_state->length;
- block.ptr = r_state->buffer ? r_state->buffer : (char*)&wnull;
- block.format = r_state->format;
-
- src->textSrc.undo_state = True;
- if (XawTextSourceReplace((Widget)src, l_state->position, l_state->position
- + l_state->length, &block) != XawEditDone) {
- src->textSrc.undo_state = False;
- src->textSrc.changed = changed;
- return (False);
- }
- src->textSrc.undo_state = False;
-
- ++l_state->refcount;
- ++r_state->refcount;
- nlist = XtNew(XawTextUndoList);
- nlist->left = l_state;
- nlist->right = r_state;
- nlist->undo = src->textSrc.undo->list;
- nlist->redo = NULL;
-
- if (list == src->textSrc.undo->list)
- src->textSrc.undo->end_mark = nlist;
-
- if (src->textSrc.undo->dir == XawsdLeft) {
- if (list->undo == NULL)
- src->textSrc.undo->dir = XawsdRight;
- else
- list = list->undo;
- }
- else {
- if (list->redo == NULL || list->redo == src->textSrc.undo->end_mark)
- src->textSrc.undo->dir = XawsdLeft;
- else
- list = list->redo;
- }
- *insert_pos = r_state->position + r_state->length;
- src->textSrc.undo->pointer = list;
- src->textSrc.undo->list->redo = nlist;
- src->textSrc.undo->list = nlist;
- src->textSrc.undo->merge = src->textSrc.undo->erase = 0;
-
- if (++src->textSrc.undo->num_list >= UNDO_DEPTH)
- UndoGC(src->textSrc.undo);
-
- return (True);
-}
-
-Bool
-_XawTextSrcToggleUndo(TextSrcObject src)
-{
- if (!src->textSrc.enable_undo || !src->textSrc.undo->num_undo)
- return (False);
-
- if (src->textSrc.undo->pointer != src->textSrc.undo->list) {
- if (src->textSrc.undo->dir == XawsdLeft) {
- if (src->textSrc.undo->pointer->redo
- && (src->textSrc.undo->pointer->redo
- != src->textSrc.undo->end_mark)) {
- src->textSrc.undo->pointer = src->textSrc.undo->pointer->redo;
- src->textSrc.undo->dir = XawsdRight;
- }
- }
- else {
- if (src->textSrc.undo->pointer->undo
- && (src->textSrc.undo->pointer != src->textSrc.undo->head)) {
- src->textSrc.undo->pointer = src->textSrc.undo->pointer->undo;
- src->textSrc.undo->dir = XawsdLeft;
- }
- }
- }
-
- return (True);
-}
-
-static void
-FreeUndoBuffer(XawTextUndo *undo)
-{
- unsigned i;
- XawTextUndoList *head, *del;
-
- for (i = 0; i < undo->num_undo; i++) {
- if (undo->undo[i]->buffer && undo->undo[i]->buffer != SrcNL &&
- undo->undo[i]->buffer != (char*)SrcWNL)
- XtFree(undo->undo[i]->buffer);
- XtFree((char*)undo->undo[i]);
- }
- XtFree((char*)undo->undo);
- head = undo->head;
-
- del = head;
- while (head) {
- head = head->redo;
- XtFree((char*)del);
- del = head;
- }
-
- if (undo->l_save) {
- XtFree((char*)undo->l_save);
- undo->l_save = NULL;
- }
- if (undo->r_save) {
- XtFree((char*)undo->r_save);
- undo->r_save = NULL;
- }
- if (undo->u_save) {
- XtFree((char*)undo->u_save);
- undo->u_save = NULL;
- }
-
- undo->list = undo->pointer = undo->head = undo->end_mark = NULL;
- undo->l_no_change = undo->r_no_change = NULL;
- undo->undo = NULL;
- undo->dir = XawsdLeft;
- undo->num_undo = undo->num_list = undo->erase = undo->merge = 0;
-}
-
-static void
-UndoGC(XawTextUndo *undo)
-{
- unsigned i;
- XawTextUndoList *head = undo->head, *redo = head->redo;
-
- if (head == undo->pointer || head == undo->end_mark
- || undo->l_no_change == NULL
- || head->left == undo->l_no_change || head->right == undo->l_no_change)
- return;
-
- undo->head = redo;
- redo->undo = NULL;
-
- --head->left->refcount;
- if (--head->right->refcount == 0) {
- for (i = 0; i < undo->num_undo; i+= 2)
- if (head->left == undo->undo[i] || head->left == undo->undo[i+1]) {
- if (head->left == undo->undo[i+1]) {
- XawTextUndoBuffer *tmp = redo->left;
-
- redo->left = redo->right;
- redo->right = tmp;
- }
- if (head->left->buffer && head->left->buffer != SrcNL &&
- head->left->buffer != (char*)SrcWNL)
- XtFree(head->left->buffer);
- XtFree((char*)head->left);
- if (head->right->buffer && head->right->buffer != SrcNL &&
- head->right->buffer != (char*)SrcWNL)
- XtFree(head->right->buffer);
- XtFree((char*)head->right);
-
- undo->num_undo -= 2;
- memmove(&undo->undo[i], &undo->undo[i + 2],
- (undo->num_undo - i) * sizeof(XawTextUndoBuffer*));
- break;
- }
- }
- XtFree((char*)head);
- --undo->num_list;
-}
-#endif /* OLDXAW */
-
-/*
- * Function:
- * XawTextSourceScan
- *
- * Parameters:
- * w - TextSrc Object
- * position - position to start scanning
- * type - type of thing to scan for
- * dir - direction to scan
- * count - which occurance if this thing to search for
- * include - whether or not to include the character found in
- * the position that is returned.
- *
- * Description:
- * Scans the text source for the number and type of item specified.
- *
- * Returns:
- * The position of the text
- */
-XawTextPosition
-XawTextSourceScan(Widget w, XawTextPosition position,
-#if NeedWidePrototypes
- int type, int dir, int count, int include
-#else
- XawTextScanType type, XawTextScanDirection dir,
- int count, Boolean include
-#endif
-)
-{
- TextSrcObjectClass cclass = (TextSrcObjectClass)w->core.widget_class;
-
- return ((*cclass->textSrc_class.Scan)
- (w, position, type, dir, count, include));
-}
-
-/*
- * Function:
- * XawTextSourceSearch
- *
- * Parameters:
- * w - TextSource Object
- * position - position to start scanning
- * dir - direction to scan
- * text - the text block to search for.
- *
- * Returns:
- * The position of the text we are searching for or XawTextSearchError.
- *
- * Description:
- * Searchs the text source for the text block passed
- */
-XawTextPosition
-XawTextSourceSearch(Widget w, XawTextPosition position,
-#if NeedWidePrototypes
- int dir,
-#else
- XawTextScanDirection dir,
-#endif
- XawTextBlock *text)
-{
- TextSrcObjectClass cclass = (TextSrcObjectClass)w->core.widget_class;
-
- return ((*cclass->textSrc_class.Search)(w, position, dir, text));
-}
-
-/*
- * Function:
- * XawTextSourceConvertSelection
- *
- * Parameters:
- * w - TextSrc object
- * selection - current selection atom
- * target - current target atom
- * type - type to conver the selection to
- * value - return value that has been converted
- * length - ""
- * format - format of the returned value
- *
- * Returns:
- * True if the selection has been converted
- */
-Boolean
-XawTextSourceConvertSelection(Widget w, Atom *selection, Atom *target,
- Atom *type, XtPointer *value,
- unsigned long *length, int *format)
-{
- TextSrcObjectClass cclass = (TextSrcObjectClass)w->core.widget_class;
-
- return((*cclass->textSrc_class.ConvertSelection)
- (w, selection, target, type, value, length, format));
-}
-
-/*
- * Function:
- * XawTextSourceSetSelection
- *
- * Parameters:
- * w - TextSrc object
- * left - bounds of the selection
- * rigth - ""
- * selection - selection atom
- *
- * Description:
- * Allows special setting of the selection.
- */
-void
-XawTextSourceSetSelection(Widget w, XawTextPosition left,
- XawTextPosition right, Atom selection)
-{
- TextSrcObjectClass cclass = (TextSrcObjectClass)w->core.widget_class;
-
- (*cclass->textSrc_class.SetSelection)(w, left, right, selection);
-}
-
-/*
- * External Functions for Multi Text
- */
-/*
- * TextFormat():
- * returns the format of text: FMT8BIT or FMTWIDE
- */
-XrmQuark
-_XawTextFormat(TextWidget tw)
-{
- return (((TextSrcObject)(tw->text.source))->textSrc.text_format);
-}
-
-/* _XawTextWCToMB():
- * Convert the wchar string to external encoding
- * The caller is responsible for freeing both the source and ret string
- *
- * wstr - source wchar string
- * len_in_out - lengh of string.
- * As In, length of source wchar string, measured in wchar
- * As Out, length of returned string
- */
-char *
-_XawTextWCToMB(Display *d, wchar_t *wstr, int *len_in_out)
-{
- XTextProperty textprop;
-
- if (XwcTextListToTextProperty(d, (wchar_t**)&wstr, 1,
- XTextStyle, &textprop) < Success) {
- XtWarningMsg("convertError", "textSource", "XawError",
- "Non-character code(s) in buffer.", NULL, NULL);
- *len_in_out = 0;
- return (NULL);
- }
- *len_in_out = textprop.nitems;
-
- return ((char *)textprop.value);
-}
-
-/* _XawTextMBToWC():
- * Convert the string to internal processing codeset WC.
- * The caller is responsible for freeing both the source and ret string.
- *
- * str - source string
- * len_in_out - lengh of string
- * As In, it is length of source string
- * As Out, it is length of returned string, measured in wchar
- */
-wchar_t *
-_XawTextMBToWC(Display *d, char *str, int *len_in_out)
-{
- XTextProperty textprop;
- char *buf;
- wchar_t **wlist, *wstr;
- int count;
-
- if (*len_in_out == 0)
- return (NULL);
-
- buf = XtMalloc(*len_in_out + 1);
-
- strncpy(buf, str, *len_in_out);
- *(buf + *len_in_out) = '\0';
- if (XmbTextListToTextProperty(d, &buf, 1, XTextStyle, &textprop) != Success) {
- XtWarningMsg("convertError", "textSource", "XawError",
- "No Memory, or Locale not supported.", NULL, NULL);
- XtFree(buf);
- *len_in_out = 0;
- return (NULL);
- }
-
- XtFree(buf);
- if (XwcTextPropertyToTextList(d, &textprop,
- (wchar_t***)&wlist, &count) != Success) {
- XtWarningMsg("convertError", "multiSourceCreate", "XawError",
- "Non-character code(s) in source.", NULL, NULL);
- *len_in_out = 0;
- return (NULL);
- }
- wstr = wlist[0];
- *len_in_out = wcslen(wstr);
- XtFree((XtPointer)wlist);
-
- return (wstr);
-}
-
-#ifndef OLDXAW
-static int
-qcmp_anchors(_Xconst void *left, _Xconst void *right)
-{
- return ((*(XawTextAnchor**)left)->position -
- (*(XawTextAnchor**)right)->position);
-}
-
-XawTextAnchor *
-XawTextSourceAddAnchor(Widget w, XawTextPosition position)
-{
- TextSrcObject src = (TextSrcObject)w;
- XawTextAnchor *anchor, *panchor;
-
- if ((panchor = XawTextSourceFindAnchor(w, position)) != NULL) {
- XawTextEntity *pentity, *entity;
-
- if (position - panchor->position < ANCHORS_DIST)
- return (panchor);
-
- if (panchor->cache && panchor->position + panchor->cache->offset +
- panchor->cache->length < position)
- pentity = entity = panchor->cache;
- else
- pentity = entity = panchor->entities;
-
- while (entity && panchor->position + entity->offset +
- entity->length < position) {
- pentity = entity;
- entity = entity->next;
- }
- if (entity) {
- XawTextPosition diff;
-
- if (panchor->position + entity->offset < position)
- position = panchor->position + entity->offset;
-
- if (position == panchor->position)
- return (panchor);
-
- anchor = XtNew(XawTextAnchor);
- diff = position - panchor->position;
-
- panchor->cache = NULL;
- anchor->entities = entity;
- if (pentity != entity)
- pentity->next = NULL;
- else
- panchor->entities = NULL;
- while (entity) {
- entity->offset -= diff;
- entity = entity->next;
- }
- }
- else {
- anchor = XtNew(XawTextAnchor);
- anchor->entities = NULL;
- }
- }
- else {
- anchor = XtNew(XawTextAnchor);
- anchor->entities = NULL;
- }
-
- anchor->position = position;
- anchor->cache = NULL;
-
- src->textSrc.anchors = (XawTextAnchor**)
- XtRealloc((XtPointer)src->textSrc.anchors, sizeof(XawTextAnchor*) *
- (src->textSrc.num_anchors + 1));
- src->textSrc.anchors[src->textSrc.num_anchors++] = anchor;
- qsort((void*)src->textSrc.anchors, src->textSrc.num_anchors,
- sizeof(XawTextAnchor*), qcmp_anchors);
-
- return (anchor);
-}
-
-XawTextAnchor *
-XawTextSourceFindAnchor(Widget w, XawTextPosition position)
-{
- TextSrcObject src = (TextSrcObject)w;
- int i = 0, left, right, nmemb = src->textSrc.num_anchors;
- XawTextAnchor *anchor, **anchors = src->textSrc.anchors;
-
- left = 0;
- right = nmemb - 1;
- while (left <= right) {
- anchor = anchors[i = (left + right) >> 1];
- if (anchor->position == position)
- return (anchor);
- else if (position < anchor->position)
- right = i - 1;
- else
- left = i + 1;
- }
-
- if (nmemb)
- return (right < 0 ? anchors[0] : anchors[right]);
-
- return (NULL);
-}
-
-Bool
-XawTextSourceAnchorAndEntity(Widget w, XawTextPosition position,
- XawTextAnchor **anchor_return,
- XawTextEntity **entity_return)
-{
- XawTextAnchor *anchor = XawTextSourceFindAnchor(w, position);
- XawTextEntity *pentity, *entity;
- XawTextPosition offset;
- Bool next_anchor = True, retval = False;
-
- if (anchor->cache && anchor->position + anchor->cache->offset +
- anchor->cache->length <= position)
- pentity = entity = anchor->cache;
- else
- pentity = entity = anchor->entities;
- while (entity) {
- offset = anchor->position + entity->offset;
-
- if (offset > position) {
- retval = next_anchor = False;
- break;
- }
- if (offset + entity->length > position) {
- retval = True;
- next_anchor = False;
- break;
- }
- pentity = entity;
- entity = entity->next;
- }
-
- if (next_anchor) {
- *anchor_return = anchor = XawTextSourceNextAnchor(w, anchor);
- *entity_return = anchor ? anchor->entities : NULL;
- }
- else {
- *anchor_return = anchor;
- *entity_return = retval ? entity : pentity;
- }
-
- if (*anchor_return)
- (*anchor_return)->cache = *entity_return;
-
- return (retval);
-}
-
-XawTextAnchor *
-XawTextSourceNextAnchor(Widget w, XawTextAnchor *anchor)
-{
- int i;
- TextSrcObject src = (TextSrcObject)w;
-
- for (i = 0; i < src->textSrc.num_anchors - 1; i++)
- if (src->textSrc.anchors[i] == anchor)
- return (src->textSrc.anchors[i + 1]);
-
- return (NULL);
-}
-
-XawTextAnchor *
-XawTextSourcePrevAnchor(Widget w, XawTextAnchor *anchor)
-{
- int i;
- TextSrcObject src = (TextSrcObject)w;
-
- for (i = src->textSrc.num_anchors - 1; i > 0; i--)
- if (src->textSrc.anchors[i] == anchor)
- return (src->textSrc.anchors[i - 1]);
-
- return (NULL);
-}
-
-XawTextAnchor *
-XawTextSourceRemoveAnchor(Widget w, XawTextAnchor *anchor)
-{
- int i;
- TextSrcObject src = (TextSrcObject)w;
-
- for (i = 0; i < src->textSrc.num_anchors; i++)
- if (src->textSrc.anchors[i] == anchor)
- break;
-
- if (i == 0)
- return (src->textSrc.num_anchors > 1 ? src->textSrc.anchors[1] : NULL);
-
- if (i < src->textSrc.num_anchors) {
- XtFree((XtPointer)anchor);
- if (i < --src->textSrc.num_anchors) {
- memmove(&src->textSrc.anchors[i],
- &src->textSrc.anchors[i + 1],
- (src->textSrc.num_anchors - i) *
- sizeof(XawTextAnchor*));
-
- return (src->textSrc.anchors[i]);
- }
- }
-
- return (NULL);
-}
-
-XawTextEntity *
-XawTextSourceAddEntity(Widget w, int type, int flags, XtPointer data,
- XawTextPosition position, Cardinal length,
- XrmQuark property)
-{
- XawTextAnchor *next, *anchor = _XawTextSourceFindAnchor(w, position);
- XawTextEntity *entity, *eprev;
-
- /* There is no support for zero length entities for now */
- if (length == 0)
- return (NULL);
-
- if (anchor->cache && anchor->position + anchor->cache->offset +
- anchor->cache->length <= position)
- eprev = entity = anchor->cache;
- else
- eprev = entity = anchor->entities;
-
- while (entity && anchor->position + entity->offset + entity->length <=
- position) {
- eprev = entity;
- entity = entity->next;
- }
- if (entity && anchor->position + entity->offset < position + length) {
- fprintf(stderr, "Cannot (yet) add more than one entity to same region.\n");
- return (NULL);
- }
-
- next = XawTextSourceFindAnchor(w, position + length);
- if (next && next != anchor) {
- if ((entity = next->entities) != NULL) {
- if (next->position + entity->offset < position + length) {
- fprintf(stderr, "Cannot (yet) add more than one entity to same region.\n");
- return (NULL);
- }
- }
- if (position + length > next->position) {
- XawTextPosition diff = position + length - next->position;
-
- next->position += diff;
- entity = next->entities;
- while (entity) {
- entity->offset -= diff;
- entity = entity->next;
- }
- entity = anchor->entities;
- while (entity && entity->offset < 0)
- entity = entity->next;
- if (entity && entity->offset < 0) {
- if (eprev)
- eprev->next = next->entities;
- else
- anchor->entities = next->entities;
- if ((next->entities = entity->next) == NULL)
- (void)XawTextSourceRemoveAnchor(w, next);
- entity->next = NULL;
-
- return (XawTextSourceAddEntity(w, type, flags, data, position,
- length, property));
- }
- }
- }
-
- /* Automatically join sequential entities if possible */
- if (eprev &&
- anchor->position + eprev->offset + eprev->length == position &&
- eprev->property == property && eprev->type == type &&
- eprev->flags == flags && eprev->data == data) {
- eprev->length += length;
- return (eprev);
- }
-
- entity = XtNew(XawTextEntity);
- entity->type = type;
- entity->flags = flags;
- entity->data = data;
- entity->offset = position - anchor->position;
- entity->length = length;
- entity->property = property;
-
- if (eprev == NULL) {
- anchor->entities = entity;
- entity->next = NULL;
- anchor->cache = NULL;
- }
- else if (eprev->offset > entity->offset) {
- anchor->cache = NULL;
- anchor->entities = entity;
- entity->next = eprev;
- }
- else {
- anchor->cache = eprev;
- entity->next = eprev->next;
- eprev->next = entity;
- }
-
- return (entity);
-}
-
-void
-XawTextSourceClearEntities(Widget w, XawTextPosition left, XawTextPosition right)
-{
- XawTextAnchor *anchor = XawTextSourceFindAnchor(w, left);
- XawTextEntity *entity, *eprev, *enext;
- XawTextPosition offset;
- int length;
-
- while (anchor && anchor->entities == NULL)
- anchor = XawTextSourceRemoveAnchor(w, anchor);
-
- if (anchor == NULL || left >= right)
- return;
-
- if (anchor->cache && anchor->position + anchor->cache->offset +
- anchor->cache->length < left)
- eprev = entity = anchor->cache;
- else
- eprev = entity = anchor->entities;
-
- /* find first entity before left position */
- while (anchor->position + entity->offset + entity->length < left) {
- eprev = entity;
- if ((entity = entity->next) == NULL) {
- if ((anchor = XawTextSourceNextAnchor(w, anchor)) == NULL)
- return;
- if ((eprev = entity = anchor->entities) == NULL) {
- fprintf(stderr, "Bad anchor found!\n");
- return;
- }
- }
- }
-
- offset = anchor->position + entity->offset;
- if (offset <= left) {
- length = XawMin(entity->length, left - offset);
-
- if (length <= 0) {
- enext = entity->next;
- eprev->next = enext;
- XtFree((XtPointer)entity);
- anchor->cache = NULL;
- if (entity == anchor->entities) {
- eprev = NULL;
- if ((anchor->entities = enext) == NULL) {
- if ((anchor = XawTextSourceRemoveAnchor(w, anchor)) == NULL)
- return;
- entity = anchor->entities;
- }
- else
- entity = enext;
- }
- else
- entity = enext;
- }
- else {
- entity->length = length;
- eprev = entity;
- entity = entity->next;
- }
- }
-
- /* clean everything until right position is reached */
- while (anchor) {
- while (entity) {
- offset = anchor->position + entity->offset + entity->length;
-
- if (offset > right) {
- anchor->cache = NULL;
- entity->offset = XawMax(entity->offset, right - anchor->position);
- entity->length = XawMin(entity->length, offset - right);
- return;
- }
-
- enext = entity->next;
- if (eprev)
- eprev->next = enext;
- XtFree((XtPointer)entity);
- if (entity == anchor->entities) {
- eprev = anchor->cache = NULL;
- if ((anchor->entities = enext) == NULL) {
- if ((anchor = XawTextSourceRemoveAnchor(w, anchor)) == NULL)
- return;
- entity = anchor->entities;
- continue;
- }
- }
- entity = enext;
- }
- if (anchor)
- anchor->cache = NULL;
- if ((anchor = XawTextSourceNextAnchor(w, anchor)) != NULL)
- entity = anchor->entities;
- eprev = NULL;
- }
-}
-
-/* checks the anchors up to position, and create an appropriate anchor
- * at position, if required.
- */
-XawTextAnchor *
-_XawTextSourceFindAnchor(Widget w, XawTextPosition position)
-{
- XawTextAnchor *anchor;
-
- anchor = XawTextSourceFindAnchor(w, position);
-
- position -= position % ANCHORS_DIST;
-
- if (position - anchor->position >= ANCHORS_DIST)
- return (XawTextSourceAddAnchor(w, position));
-
- return (anchor);
-}
-#endif
+/*
+
+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.
+
+*/
+
+/*
+ * Author: Chris Peterson, MIT X Consortium.
+ * Much code taken from X11R3 String and Disk Sources.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <ctype.h>
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xfuncs.h>
+#include <X11/Xutil.h>
+#include <X11/Xmu/Atoms.h>
+#include <X11/Xmu/CharSet.h>
+#include <X11/Xaw/TextSrcP.h>
+#include <X11/Xaw/XawInit.h>
+#include "XawI18n.h"
+#include "Private.h"
+
+#ifndef OLDXAW
+#define UNDO_DEPTH 16384
+
+#define ANCHORS_DIST 4096 /* default distance between anchors */
+
+/*
+ * Types
+ */
+typedef struct {
+ XawTextPosition position;
+ char *buffer;
+ unsigned length;
+ unsigned refcount;
+ unsigned long format;
+} XawTextUndoBuffer;
+
+typedef struct _XawTextUndoList XawTextUndoList;
+struct _XawTextUndoList {
+ XawTextUndoBuffer *left, *right;
+ XawTextUndoList *undo, *redo;
+};
+
+struct _XawTextUndo {
+ XawTextUndoBuffer **undo;
+ unsigned num_undo;
+ XawTextUndoList *list, *pointer, *end_mark, *head;
+ unsigned num_list;
+ XawTextScanDirection dir;
+ XawTextUndoBuffer *l_save, *r_save;
+ XawTextUndoList *u_save;
+ XawTextUndoBuffer *l_no_change, *r_no_change;
+ int merge;
+ int erase; /* there are two types of erases */
+};
+#endif /* OLDXAW */
+
+/*
+ * Class Methods
+ */
+static Boolean ConvertSelection(Widget, Atom*, Atom*, Atom*, XtPointer*,
+ unsigned long*, int*);
+static XawTextPosition Read(Widget, XawTextPosition, XawTextBlock*, int);
+static int Replace(Widget, XawTextPosition, XawTextPosition, XawTextBlock*);
+static XawTextPosition Scan(Widget, XawTextPosition, XawTextScanType,
+ XawTextScanDirection, int, Bool);
+static XawTextPosition Search(Widget, XawTextPosition, XawTextScanDirection,
+ XawTextBlock*);
+static void SetSelection(Widget, XawTextPosition, XawTextPosition, Atom);
+static void XawTextSrcClassInitialize(void);
+static void XawTextSrcClassPartInitialize(WidgetClass);
+static void XawTextSrcInitialize(Widget, Widget, ArgList, Cardinal*);
+static void XawTextSrcDestroy(Widget);
+static Boolean XawTextSrcSetValues(Widget, Widget, Widget, ArgList, Cardinal*);
+/*
+ * Prototypes
+ */
+static void CvtStringToEditMode(XrmValuePtr, Cardinal*,
+ XrmValuePtr, XrmValuePtr);
+static Boolean CvtEditModeToString(Display*, XrmValuePtr, Cardinal*,
+ XrmValuePtr, XrmValuePtr, XtPointer*);
+#ifndef OLDXAW
+static void FreeUndoBuffer(XawTextUndo*);
+static void UndoGC(XawTextUndo*);
+static void TellSourceChanged(TextSrcObject, XawTextPosition, XawTextPosition,
+ XawTextBlock*, int);
+Bool _XawTextSrcUndo(TextSrcObject, XawTextPosition*);
+Bool _XawTextSrcToggleUndo(TextSrcObject);
+XawTextAnchor *_XawTextSourceFindAnchor(Widget, XawTextPosition);
+
+/*
+ * External
+ */
+void _XawSourceAddText(Widget, Widget);
+void _XawSourceRemoveText(Widget, Widget, Bool);
+Bool _XawTextSourceNewLineAtEOF(Widget);
+void _XawSourceSetUndoErase(TextSrcObject, int);
+void _XawSourceSetUndoMerge(TextSrcObject, Bool);
+#endif /* OLDXAW */
+
+/*
+ * Defined in Text.c
+ */
+char *_XawTextGetText(TextWidget, XawTextPosition, XawTextPosition);
+void _XawTextSourceChanged(Widget, XawTextPosition, XawTextPosition,
+ XawTextBlock*, int);
+
+/*
+ * Initialization
+ */
+#define offset(field) XtOffsetOf(TextSrcRec, textSrc.field)
+static XtResource resources[] = {
+ {
+ XtNeditType,
+ XtCEditType,
+ XtREditMode,
+ sizeof(XawTextEditType),
+ offset(edit_mode),
+ XtRString,
+ "read"
+ },
+#ifndef OLDXAW
+ {
+ XtNcallback,
+ XtCCallback,
+ XtRCallback,
+ sizeof(XtPointer),
+ offset(callback),
+ XtRCallback,
+ NULL
+ },
+ {
+ XtNsourceChanged,
+ XtCChanged,
+ XtRBoolean,
+ sizeof(Boolean),
+ offset(changed),
+ XtRImmediate,
+ (XtPointer)False
+ },
+ {
+ XtNenableUndo,
+ XtCUndo,
+ XtRBoolean,
+ sizeof(Boolean),
+ offset(enable_undo),
+ XtRImmediate,
+ (XtPointer)False
+ },
+ {
+ XtNpropertyCallback,
+ XtCCallback,
+ XtRCallback,
+ sizeof(XtPointer),
+ offset(property_callback),
+ XtRCallback,
+ NULL
+ },
+#endif /* OLDXAW */
+};
+#undef offset
+
+#define Superclass (&objectClassRec)
+TextSrcClassRec textSrcClassRec = {
+ /* object */
+ {
+ (WidgetClass)Superclass, /* superclass */
+ "TextSrc", /* class_name */
+ sizeof(TextSrcRec), /* widget_size */
+ XawTextSrcClassInitialize, /* class_initialize */
+ XawTextSrcClassPartInitialize, /* class_part_initialize */
+ False, /* class_inited */
+ XawTextSrcInitialize, /* initialize */
+ NULL, /* initialize_hook */
+ NULL, /* realize */
+ NULL, /* actions */
+ 0, /* num_actions */
+ resources, /* resources */
+ XtNumber(resources), /* num_resources */
+ NULLQUARK, /* xrm_class */
+ False, /* compress_motion */
+ False, /* compress_exposure */
+ False, /* compress_enterleave */
+ False, /* visible_interest */
+ XawTextSrcDestroy, /* destroy */
+ NULL, /* resize */
+ NULL, /* expose */
+ XawTextSrcSetValues, /* set_values */
+ NULL, /* set_values_hook */
+ NULL, /* set_values_almost */
+ NULL, /* get_values_hook */
+ NULL, /* accept_focus */
+ XtVersion, /* version */
+ NULL, /* callback_private */
+ NULL, /* tm_table */
+ NULL, /* query_geometry */
+ NULL, /* display_accelerator */
+ NULL, /* extension */
+ },
+ /* text_src */
+ {
+ Read, /* Read */
+ Replace, /* Replace */
+ Scan, /* Scan */
+ Search, /* Search */
+ SetSelection, /* SetSelection */
+ ConvertSelection, /* ConvertSelection */
+ },
+};
+
+WidgetClass textSrcObjectClass = (WidgetClass)&textSrcClassRec;
+
+static XrmQuark QRead, QAppend, QEdit;
+#ifndef OLDXAW
+static char *SrcNL = "\n";
+static wchar_t SrcWNL[2];
+#endif
+
+/*
+ * Implementation
+ */
+static void
+XawTextSrcClassInitialize(void)
+{
+ XawInitializeWidgetSet();
+
+#ifndef OLDXAW
+ SrcWNL[0] = _Xaw_atowc(XawLF);
+ SrcWNL[1] = 0;
+#endif
+ QRead = XrmPermStringToQuark(XtEtextRead);
+ QAppend = XrmPermStringToQuark(XtEtextAppend);
+ QEdit = XrmPermStringToQuark(XtEtextEdit);
+ XtAddConverter(XtRString, XtREditMode, CvtStringToEditMode, NULL, 0);
+ XtSetTypeConverter(XtREditMode, XtRString, CvtEditModeToString, NULL, 0,
+ XtCacheNone, NULL);
+}
+
+static void
+XawTextSrcClassPartInitialize(WidgetClass wc)
+{
+ TextSrcObjectClass t_src, superC;
+
+ t_src = (TextSrcObjectClass)wc;
+ superC = (TextSrcObjectClass)t_src->object_class.superclass;
+
+ /*
+ * We don't need to check for null super since we'll get to TextSrc
+ * eventually
+ */
+ if (t_src->textSrc_class.Read == XtInheritRead)
+ t_src->textSrc_class.Read = superC->textSrc_class.Read;
+
+ if (t_src->textSrc_class.Replace == XtInheritReplace)
+ t_src->textSrc_class.Replace = superC->textSrc_class.Replace;
+
+ if (t_src->textSrc_class.Scan == XtInheritScan)
+ t_src->textSrc_class.Scan = superC->textSrc_class.Scan;
+
+ if (t_src->textSrc_class.Search == XtInheritSearch)
+ t_src->textSrc_class.Search = superC->textSrc_class.Search;
+
+ if (t_src->textSrc_class.SetSelection == XtInheritSetSelection)
+ t_src->textSrc_class.SetSelection = superC->textSrc_class.SetSelection;
+
+ if (t_src->textSrc_class.ConvertSelection == XtInheritConvertSelection)
+ t_src->textSrc_class.ConvertSelection =
+ superC->textSrc_class.ConvertSelection;
+}
+
+/*ARGSUSED*/
+static void
+XawTextSrcInitialize(Widget request, Widget cnew,
+ ArgList args, Cardinal *num_args)
+{
+#ifndef OLDXAW
+ TextSrcObject src = (TextSrcObject)cnew;
+
+ if (src->textSrc.enable_undo) {
+ src->textSrc.undo = (XawTextUndo*)XtCalloc(1, sizeof(XawTextUndo));
+ src->textSrc.undo->dir = XawsdLeft;
+ }
+ else
+ src->textSrc.undo = NULL;
+ src->textSrc.undo_state = False;
+ if (XtIsSubclass(XtParent(cnew), textWidgetClass)) {
+ src->textSrc.text = (WidgetList)XtMalloc(sizeof(Widget*));
+ src->textSrc.text[0] = XtParent(cnew);
+ src->textSrc.num_text = 1;
+ }
+ else {
+ src->textSrc.text = NULL;
+ src->textSrc.num_text = 0;
+ }
+
+ src->textSrc.anchors = NULL;
+ src->textSrc.num_anchors = 0;
+ (void)XawTextSourceAddAnchor(cnew, 0);
+#endif /* OLDXAW */
+}
+
+static void
+XawTextSrcDestroy(Widget w)
+{
+#ifndef OLDXAW
+ TextSrcObject src = (TextSrcObject)w;
+
+ if (src->textSrc.enable_undo) {
+ FreeUndoBuffer(src->textSrc.undo);
+ XtFree((char*)src->textSrc.undo);
+ }
+ XtFree((char*)src->textSrc.text);
+
+ if (src->textSrc.num_anchors) {
+ XawTextEntity *entity, *enext;
+ int i;
+
+ for (i = 0; i < src->textSrc.num_anchors; i++) {
+ entity = src->textSrc.anchors[i]->entities;
+ while (entity) {
+ enext = entity->next;
+ XtFree((XtPointer)entity);
+ entity = enext;
+ }
+ XtFree((XtPointer)src->textSrc.anchors[i]);
+ }
+ XtFree((XtPointer)src->textSrc.anchors);
+ }
+#endif /* OLDXAW */
+}
+
+/*ARGSUSED*/
+static Boolean
+XawTextSrcSetValues(Widget current, Widget request, Widget cnew,
+ ArgList args, Cardinal *num_args)
+{
+#ifndef OLDXAW
+ TextSrcObject oldtw = (TextSrcObject)current;
+ TextSrcObject newtw = (TextSrcObject)cnew;
+
+ if (oldtw->textSrc.enable_undo != newtw->textSrc.enable_undo) {
+ if (newtw->textSrc.enable_undo) {
+ newtw->textSrc.undo = (XawTextUndo*)
+ XtCalloc(1, sizeof(XawTextUndo));
+ newtw->textSrc.undo->dir = XawsdLeft;
+ }
+ else {
+ FreeUndoBuffer(newtw->textSrc.undo);
+ XtFree((char*)newtw->textSrc.undo);
+ newtw->textSrc.undo = NULL;
+ }
+ }
+ if (oldtw->textSrc.changed != newtw->textSrc.changed) {
+ if (newtw->textSrc.enable_undo) {
+ if (newtw->textSrc.undo->list) {
+ newtw->textSrc.undo->l_no_change =
+ newtw->textSrc.undo->list->left;
+ newtw->textSrc.undo->r_no_change =
+ newtw->textSrc.undo->list->right;
+ }
+ else
+ newtw->textSrc.undo->l_no_change =
+ newtw->textSrc.undo->r_no_change = NULL;
+ }
+ }
+#endif /* OLDXAW */
+ return (False);
+}
+
+/*
+ * Function:
+ * Read
+ *
+ * Parameters:
+ * w - TextSrc Object
+ * pos - position of the text to retreive
+ * text - text block that will contain returned text
+ * length - maximum number of characters to read
+ *
+ * Description:
+ * This function reads the source.
+ *
+ * Returns:
+ * The character position following the retrieved text.
+ */
+/*ARGSUSED*/
+static XawTextPosition
+Read(Widget w, XawTextPosition pos, XawTextBlock *text, int length)
+{
+ return ((XawTextPosition)0);
+}
+
+/*
+ * Function:
+ * Replace
+ *
+ * Parameters:
+ * src - Text Source Object
+ * startPos - ends of text that will be removed
+ * endPos - ""
+ * text - new text to be inserted into buffer at startPos
+ *
+ * Description:
+ * Replaces a block of text with new text.
+ */
+/*ARGSUSED*/
+static int
+Replace(Widget w, XawTextPosition startPos, XawTextPosition endPos,
+ XawTextBlock *text)
+{
+ return (XawEditError);
+}
+
+/*
+ * Function:
+ * Scan
+ *
+ * Parameters:
+ * w - TextSrc Object
+ * position - position to start scanning
+ * type - type of thing to scan for
+ * dir - direction to scan
+ * count - which occurance if this thing to search for
+ * include - whether or not to include the character found in
+ * the position that is returned
+ *
+ * Description:
+ * Scans the text source for the number and type of item specified.
+ */
+/*ARGSUSED*/
+static XawTextPosition
+Scan(Widget w, XawTextPosition position, XawTextScanType type,
+ XawTextScanDirection dir, int count, Bool include)
+{
+ return ((XawTextPosition)0);
+}
+
+/*
+ * Function:
+ * Search
+ *
+ * Parameters:
+ * w - TextSource Object
+ * position - position to start searching
+ * dir - direction to search
+ * text - the text block to search for
+ *
+ * Description:
+ * Searchs the text source for the text block passed
+ */
+/*ARGSUSED*/
+static XawTextPosition
+Search(Widget w, XawTextPosition position, XawTextScanDirection dir,
+ XawTextBlock *text)
+{
+ return (XawTextSearchError);
+}
+
+/*ARGSUSED*/
+static Boolean
+ConvertSelection(Widget w, Atom *selection, Atom *target, Atom *type,
+ XtPointer *value, unsigned long *length, int *format)
+{
+ return (False);
+}
+
+/*ARGSUSED*/
+static void
+SetSelection(Widget w, XawTextPosition left, XawTextPosition right,
+ Atom selection)
+{
+}
+
+/*ARGSUSED*/
+static void
+CvtStringToEditMode(XrmValuePtr args, Cardinal *num_args,
+ XrmValuePtr fromVal, XrmValuePtr toVal)
+{
+ static XawTextEditType editType;
+ XrmQuark q;
+ char name[7];
+
+ XmuNCopyISOLatin1Lowered(name, (char *)fromVal->addr, sizeof(name));
+ q = XrmStringToQuark(name);
+
+ if (q == QRead)
+ editType = XawtextRead;
+ else if (q == QAppend)
+ editType = XawtextAppend;
+ else if (q == QEdit)
+ editType = XawtextEdit;
+ else {
+ toVal->size = 0;
+ toVal->addr = NULL;
+ XtStringConversionWarning((char *)fromVal->addr, XtREditMode);
+ }
+ toVal->size = sizeof(XawTextEditType);
+ toVal->addr = (XPointer)&editType;
+}
+
+/*ARGSUSED*/
+static Boolean
+CvtEditModeToString(Display *dpy, XrmValuePtr args, Cardinal *num_args,
+ XrmValuePtr fromVal, XrmValuePtr toVal,
+ XtPointer *data)
+{
+ static String buffer;
+ Cardinal size;
+
+ switch (*(XawTextEditType *)fromVal->addr) {
+ case XawtextRead:
+ buffer = XtEtextRead;
+ break;
+ case XawtextAppend:
+ buffer = XtEtextAppend;
+ break;
+ case XawtextEdit:
+ buffer = XtEtextEdit;
+ break;
+ default:
+ XawTypeToStringWarning(dpy, XtREditMode);
+ toVal->addr = NULL;
+ toVal->size = 0;
+ return (False);
+ }
+
+ size = strlen(buffer) + 1;
+ if (toVal->addr != NULL) {
+ if (toVal->size < size) {
+ toVal->size = size;
+ return (False);
+ }
+ strcpy((char *)toVal->addr, buffer);
+ }
+ else
+ toVal->addr = (XPointer)buffer;
+ toVal->size = sizeof(String);
+
+ return (True);
+}
+
+#ifndef OLDXAW
+Bool
+_XawTextSourceNewLineAtEOF(Widget w)
+{
+ TextSrcObject src = (TextSrcObject)w;
+ XawTextBlock text;
+
+ text.firstPos = 0;
+ if ((text.format = src->textSrc.text_format) == XawFmt8Bit)
+ text.ptr = SrcNL;
+ else
+ text.ptr = (char*)SrcWNL;
+ text.length = 1;
+
+ return (XawTextSourceSearch(w, XawTextSourceScan(w, 0, XawstAll,
+ XawsdRight, 1, True) - 1,
+ XawsdRight, &text) != XawTextSearchError);
+}
+
+void
+_XawSourceAddText(Widget source, Widget text)
+{
+ TextSrcObject src = (TextSrcObject)source;
+ Bool found = False;
+ Cardinal i;
+
+ for (i = 0; i < src->textSrc.num_text; i++)
+ if (src->textSrc.text[i] == text) {
+ found = True;
+ break;
+ }
+
+ if (!found) {
+ src->textSrc.text = (WidgetList)
+ XtRealloc((char*)src->textSrc.text,
+ sizeof(Widget) * (src->textSrc.num_text + 1));
+ src->textSrc.text[src->textSrc.num_text++] = text;
+ }
+}
+
+void
+_XawSourceRemoveText(Widget source, Widget text, Bool destroy)
+{
+ TextSrcObject src = (TextSrcObject)source;
+ Bool found = False;
+ Cardinal i;
+
+ if (src == NULL)
+ return;
+
+ for (i = 0; i < src->textSrc.num_text; i++)
+ if (src->textSrc.text[i] == text) {
+ found = True;
+ break;
+ }
+
+ if (found) {
+ if (--src->textSrc.num_text == 0) {
+ if (destroy) {
+ XtDestroyWidget(source);
+ return;
+ }
+ else {
+ XtFree((char*)src->textSrc.text);
+ src->textSrc.text = NULL; /* for realloc "magic" */
+ }
+ }
+ else if (i < src->textSrc.num_text)
+ memmove(&src->textSrc.text[i], &src->textSrc.text[i + 1],
+ sizeof(Widget) * (src->textSrc.num_text - i));
+ }
+}
+#endif /* OLDXAW */
+
+/*
+ * Function:
+ * XawTextSourceRead
+ *
+ * Parameters:
+ * w - TextSrc Object
+ * pos - position of the text to retrieve
+ * text - text block that will contain returned text (return)
+ * length - maximum number of characters to read
+ *
+ * Description:
+ * This function reads the source.
+ *
+ * Returns:
+ * The number of characters read into the buffer
+ */
+XawTextPosition
+XawTextSourceRead(Widget w, XawTextPosition pos, XawTextBlock *text,
+ int length)
+{
+ TextSrcObjectClass cclass = (TextSrcObjectClass)w->core.widget_class;
+
+ return ((*cclass->textSrc_class.Read)(w, pos, text, length));
+}
+
+#ifndef OLDXAW
+static void
+TellSourceChanged(TextSrcObject src, XawTextPosition left,
+ XawTextPosition right, XawTextBlock *block, int lines)
+{
+ Cardinal i;
+
+ for (i = 0; i < src->textSrc.num_text; i++)
+ _XawTextSourceChanged(src->textSrc.text[i], left, right, block, lines);
+}
+
+/*
+ * This function is required because there is no way to diferentiate
+ * if the first erase was generated by a backward-kill-char and the
+ * second by a forward-kill-char (or vice-versa) from XawTextSourceReplace.
+ * It is only possible to diferentiate after the second character is
+ * killed, but then, it is too late.
+ */
+void
+_XawSourceSetUndoErase(TextSrcObject src, int value)
+{
+ if (src && src->textSrc.enable_undo)
+ src->textSrc.undo->erase = value;
+}
+
+/*
+ * To diferentiate insert-char's separeted by cursor movements.
+ */
+void
+_XawSourceSetUndoMerge(TextSrcObject src, Bool state)
+{
+ if (src && src->textSrc.enable_undo)
+ src->textSrc.undo->merge += state ? 1 : -1;
+}
+#endif /* OLDXAW */
+
+/*
+ * Public Functions
+ */
+/*
+ * Function:
+ * XawTextSourceReplace
+ *
+ * Parameters:
+ * src - Text Source Object
+ * startPos - ends of text that will be removed
+ * endPos - ""
+ * text - new text to be inserted into buffer at startPos
+ *
+ * Description:
+ * Replaces a block of text with new text.
+ *
+ * Returns:
+ * XawEditError or XawEditDone.
+ */
+/*ARGSUSED*/
+int
+XawTextSourceReplace(Widget w, XawTextPosition left,
+ XawTextPosition right, XawTextBlock *block)
+{
+ TextSrcObjectClass cclass = (TextSrcObjectClass)w->core.widget_class;
+#ifndef OLDXAW
+ TextSrcObject src = (TextSrcObject)w;
+ XawTextUndoBuffer *l_state, *r_state;
+ XawTextUndoList *undo;
+ Bool enable_undo;
+ XawTextPosition start, end;
+ int i, error, lines = 0;
+
+ if (src->textSrc.edit_mode == XawtextRead)
+ return (XawEditError);
+
+ enable_undo = src->textSrc.enable_undo && src->textSrc.undo_state == False;
+ if (enable_undo) {
+ unsigned size, total;
+
+ if (src->textSrc.undo->l_save) {
+ l_state = src->textSrc.undo->l_save;
+ src->textSrc.undo->l_save = NULL;
+ }
+ else
+ l_state = XtNew(XawTextUndoBuffer);
+ l_state->refcount = 1;
+ l_state->position = left;
+ if (left < right) {
+ Widget ctx = NULL;
+
+ for (i = 0; i < src->textSrc.num_text; i++)
+ if (XtIsSubclass(src->textSrc.text[i], textWidgetClass)) {
+ ctx = src->textSrc.text[i];
+ break;
+ }
+ l_state->buffer = _XawTextGetText((TextWidget)ctx, left, right);
+ l_state->length = right - left;
+ }
+ else {
+ l_state->length = 0;
+ l_state->buffer = NULL;
+ }
+ l_state->format = src->textSrc.text_format;
+ if (l_state->length == 1) {
+ if (l_state->format == XawFmtWide &&
+ *(wchar_t*)l_state->buffer == *SrcWNL) {
+ XtFree(l_state->buffer);
+ l_state->buffer = (char*)SrcWNL;
+ }
+ else if (*l_state->buffer == '\n') {
+ XtFree(l_state->buffer);
+ l_state->buffer = SrcNL;
+ }
+ }
+
+ if (src->textSrc.undo->r_save) {
+ r_state = src->textSrc.undo->r_save;
+ src->textSrc.undo->r_save = NULL;
+ }
+ else
+ r_state = XtNew(XawTextUndoBuffer);
+ r_state->refcount = 1;
+ r_state->position = left;
+ r_state->format = block->format;
+ size = block->format == XawFmtWide ? sizeof(wchar_t) : sizeof(char);
+ total = size * block->length;
+ r_state->length = block->length;
+ r_state->buffer = NULL;
+ if (total == size) {
+ if (r_state->format == XawFmtWide &&
+ *(wchar_t*)block->ptr == *SrcWNL)
+ r_state->buffer = (char*)SrcWNL;
+ else if (*block->ptr == '\n')
+ r_state->buffer = SrcNL;
+ }
+ if (total && !r_state->buffer) {
+ r_state->buffer = XtMalloc(total);
+ memcpy(r_state->buffer, block->ptr, total);
+ }
+
+ if (src->textSrc.undo->u_save) {
+ undo = src->textSrc.undo->u_save;
+ src->textSrc.undo->u_save = NULL;
+ }
+ else
+ undo = XtNew(XawTextUndoList);
+ undo->left = l_state;
+ undo->right = r_state;
+ undo->undo = src->textSrc.undo->list;
+ undo->redo = NULL;
+ }
+ else {
+ undo = NULL;
+ l_state = r_state = NULL;
+ }
+
+#define LARGE_VALUE 262144 /* 256 K */
+ /* optimization, to avoid long delays recalculating the line number
+ * when editing huge files
+ */
+ if (left > LARGE_VALUE) {
+ start = XawTextSourceScan(w, left, XawstEOL, XawsdLeft, 2, False);
+ for (i = 0; i < src->textSrc.num_text; i++) {
+ TextWidget tw = (TextWidget)src->textSrc.text[i];
+
+ if (left <= tw->text.lt.top &&
+ left + block->length - (right - left) > tw->text.lt.top)
+ _XawTextBuildLineTable(tw, start, False);
+ }
+ }
+#undef LARGE_VALUE
+
+ start = left;
+ end = right;
+ while (start < end) {
+ start = XawTextSourceScan(w, start, XawstEOL, XawsdRight, 1, True);
+ if (start <= end) {
+ --lines;
+ if (start == XawTextSourceScan(w, 0, XawstAll, XawsdRight, 1, True)) {
+ lines += !_XawTextSourceNewLineAtEOF(w);
+ break;
+ }
+ }
+ }
+#else
+ int error;
+#endif /* OLDXAW */
+
+ error = (*cclass->textSrc_class.Replace)(w, left, right, block);
+
+#ifndef OLDXAW
+ if (error != XawEditDone) {
+ if (enable_undo) {
+ if (l_state->buffer) {
+ if (l_state->buffer != SrcNL && l_state->buffer != (char*)SrcWNL)
+ XtFree(l_state->buffer);
+ l_state->buffer = NULL;
+ }
+ src->textSrc.undo->l_save = l_state;
+ if (r_state->buffer) {
+ if (r_state->buffer != SrcNL && r_state->buffer != (char*)SrcWNL)
+ XtFree(r_state->buffer);
+ r_state->buffer = NULL;
+ }
+ src->textSrc.undo->r_save = r_state;
+
+ src->textSrc.undo->u_save = undo;
+ }
+ }
+ else if (enable_undo) {
+ XawTextUndoList *list = src->textSrc.undo->list;
+ XawTextUndoBuffer *unl, *lnl;
+ int erase = undo->right->length == 0 && undo->left->length == 1 && list
+ && list->right->length == 0;
+
+ if (erase) {
+ erase = list->left->position - 1 == undo->left->position ? -1 :
+ list->left->position == undo->left->position ? 1 : 0;
+ if (src->textSrc.undo->erase && erase != src->textSrc.undo->erase)
+ erase = 0;
+ else
+ src->textSrc.undo->erase = erase;
+ }
+
+ if (erase) {
+ unl = l_state;
+ lnl = list->left;
+ }
+ else {
+ unl = r_state;
+ lnl = list ? list->right : NULL;
+ }
+
+ /* Try to merge the undo buffers */
+ if (src->textSrc.undo->merge > 0 && ((erase ||
+ (list && ((list->left->length == 0 && undo->left->length == 0) ||
+ (list->left->length == list->right->length &&
+ undo->left->length == 1)) &&
+ undo->right->length == 1 &&
+ list->right->position + list->right->length
+ == undo->right->position))
+ && src->textSrc.undo->pointer == list
+ && unl->format == list->right->format
+ && ((unl->format == XawFmt8Bit && unl->buffer[0] != XawLF) ||
+ (unl->format == XawFmtWide &&
+ *(wchar_t*)(unl->buffer) != _Xaw_atowc(XawLF)))
+ && ((lnl->format == XawFmt8Bit && lnl->buffer[0] != XawLF) ||
+ (lnl->format == XawFmtWide &&
+ *(wchar_t*)(lnl->buffer) != _Xaw_atowc(XawLF))))) {
+ unsigned size = lnl->format == XawFmtWide ?
+ sizeof(wchar_t) : sizeof(char);
+
+ if (!erase) {
+ list->right->buffer = XtRealloc(list->right->buffer,
+ (list->right->length + 1) * size);
+ memcpy(list->right->buffer + list->right->length * size,
+ undo->right->buffer, size);
+ ++list->right->length;
+ XtFree(r_state->buffer);
+ }
+ else if (erase < 0) {
+ --list->left->position;
+ --list->right->position;
+ }
+
+ src->textSrc.undo->l_save = l_state;
+ src->textSrc.undo->r_save = r_state;
+ src->textSrc.undo->u_save = undo;
+
+ if (list->left->length) {
+ list->left->buffer = XtRealloc(list->left->buffer,
+ (list->left->length + 1) * size);
+ if (erase >= 0)
+ memcpy(list->left->buffer + list->left->length * size,
+ undo->left->buffer, size);
+ else {
+ /* use memmove, since strings overlap */
+ memmove(list->left->buffer + size, list->left->buffer,
+ list->left->length * size);
+ memcpy(list->left->buffer, undo->left->buffer, size);
+ }
+ ++list->left->length;
+ if (l_state->buffer != SrcNL && l_state->buffer != (char*)SrcWNL)
+ XtFree(l_state->buffer);
+ }
+
+ if (src->textSrc.undo->num_list >= UNDO_DEPTH)
+ UndoGC(src->textSrc.undo);
+ }
+ else {
+ src->textSrc.undo->undo = (XawTextUndoBuffer**)
+ XtRealloc((char*)src->textSrc.undo->undo,
+ (2 + src->textSrc.undo->num_undo)
+ * sizeof(XawTextUndoBuffer));
+ src->textSrc.undo->undo[src->textSrc.undo->num_undo++] = l_state;
+ src->textSrc.undo->undo[src->textSrc.undo->num_undo++] = r_state;
+
+ if (src->textSrc.undo->list)
+ src->textSrc.undo->list->redo = undo;
+ else
+ src->textSrc.undo->head = undo;
+
+ src->textSrc.undo->merge = l_state->length <= 1 &&
+ r_state->length <= 1;
+
+ src->textSrc.undo->list = src->textSrc.undo->pointer =
+ src->textSrc.undo->end_mark = undo;
+
+ if (++src->textSrc.undo->num_list >= UNDO_DEPTH)
+ UndoGC(src->textSrc.undo);
+ }
+ src->textSrc.undo->dir = XawsdLeft;
+ if (!src->textSrc.changed) {
+ src->textSrc.undo->l_no_change = src->textSrc.undo->list->right;
+ src->textSrc.undo->r_no_change = src->textSrc.undo->list->left;
+ src->textSrc.changed = True;
+ }
+ }
+ else if (!src->textSrc.enable_undo)
+ src->textSrc.changed = True;
+
+ if (error == XawEditDone) {
+ XawTextPropertyInfo info;
+ XawTextAnchor *anchor;
+
+ /* find anchor and index */
+ /* XXX index (i) could be returned by XawTextSourceFindAnchor
+ * or similar function, to speed up */
+ if ((anchor = XawTextSourceFindAnchor(w, left))) {
+ XawTextEntity *eprev, *entity, *enext;
+ XawTextPosition offset = 0, diff = block->length - (right - left);
+
+ for (i = 0; i < src->textSrc.num_anchors; i++)
+ if (src->textSrc.anchors[i] == anchor)
+ break;
+ if (anchor->cache && anchor->position + anchor->cache->offset +
+ anchor->cache->length <= left)
+ eprev = entity = anchor->cache;
+ else
+ eprev = entity = anchor->entities;
+ while (entity) {
+ offset = anchor->position + entity->offset;
+
+ if (offset > left)
+ break;
+ if (offset + entity->length > left)
+ break;
+
+ eprev = entity;
+ entity = entity->next;
+ }
+
+ /* try to do the right thing here (and most likely correct), but
+ * other code needs to check what was done */
+
+ /* adjust entity length */
+ if (entity && offset <= left) {
+ if (offset + entity->length < right)
+ entity->length = left - offset + block->length;
+ else
+ entity->length += diff;
+
+ if (entity->length == 0) {
+ enext = entity->next;
+ eprev->next = enext;
+ anchor->cache = NULL;
+ XtFree((XtPointer)entity);
+ if (entity == anchor->entities) {
+ if ((anchor->entities = enext) == NULL) {
+ eprev = NULL;
+ anchor = XawTextSourceRemoveAnchor(w, anchor);
+ entity = anchor ? anchor->entities : NULL;
+ }
+ else
+ eprev = entity = enext;
+ }
+ else
+ entity = enext;
+ }
+ else {
+ eprev = entity;
+ entity = entity->next;
+ }
+ }
+
+ while (anchor) {
+ while (entity) {
+ offset = anchor->position + entity->offset + entity->length;
+
+ if (offset > right) {
+ entity->length = XawMin(entity->length, offset - right);
+ goto exit_anchor_loop;
+ }
+
+ enext = entity->next;
+ if (eprev)
+ eprev->next = enext;
+ XtFree((XtPointer)entity);
+ anchor->cache = NULL;
+ if (entity == anchor->entities) {
+ eprev = NULL;
+ if ((anchor->entities = enext) == NULL) {
+ if (i == 0)
+ ++i;
+ else if (i < --src->textSrc.num_anchors) {
+ memmove(&src->textSrc.anchors[i],
+ &src->textSrc.anchors[i + 1],
+ (src->textSrc.num_anchors - i) *
+ sizeof(XawTextAnchor*));
+ XtFree((XtPointer)anchor);
+ }
+ if (i >= src->textSrc.num_anchors) {
+ anchor = NULL;
+ entity = NULL;
+ break;
+ }
+ anchor = src->textSrc.anchors[i];
+ entity = anchor->entities;
+ continue;
+ }
+ }
+ entity = enext;
+ }
+ if (i + 1 < src->textSrc.num_anchors) {
+ anchor = src->textSrc.anchors[++i];
+ entity = anchor->entities;
+ eprev = NULL;
+ }
+ else {
+ anchor = NULL;
+ break;
+ }
+ eprev = NULL;
+ }
+
+exit_anchor_loop:
+ if (anchor) {
+ XawTextAnchor *aprev;
+
+ if (anchor->position >= XawMax(right, left + block->length))
+ anchor->position += diff;
+ else if (anchor->position > left &&
+ (aprev = XawTextSourcePrevAnchor(w, anchor))) {
+ XawTextPosition tmp = anchor->position - aprev->position;
+
+ if (diff) {
+ while (entity) {
+ entity->offset += diff;
+ entity = entity->next;
+ }
+ }
+ entity = anchor->entities;
+ while (entity) {
+ entity->offset += tmp;
+ entity = entity->next;
+ }
+ if ((entity = aprev->entities) == NULL)
+ aprev->entities = anchor->entities;
+ else {
+ while (entity->next)
+ entity = entity->next;
+ entity->next = anchor->entities;
+ }
+ anchor->entities = NULL;
+ (void)XawTextSourceRemoveAnchor(w, anchor);
+ --i;
+ }
+ else if (diff) {
+ while (entity) {
+ entity->offset += diff;
+ entity = entity->next;
+ }
+ }
+ }
+
+ if (diff) {
+ /* The first anchor is never removed, and should
+ * have position 0.
+ * i should be -1 if attempted to removed the first
+ * anchor, what can be caused when removing a chunk
+ * of text of the first entity.
+ * */
+ if (++i == 0) {
+ anchor = src->textSrc.anchors[0];
+ eprev = entity = anchor->entities;
+ while (entity) {
+ enext = entity->next;
+ if (entity->offset + entity->length <= -diff)
+ XtFree((XtPointer)entity);
+ else
+ break;
+ entity = enext;
+ }
+ if (eprev != entity) {
+ anchor->cache = NULL;
+ if ((anchor->entities = entity) != NULL) {
+ if ((entity->offset += diff) < 0) {
+ entity->length += entity->offset;
+ entity->offset = 0;
+ }
+ }
+ }
+ ++i;
+ }
+ for (; i < src->textSrc.num_anchors; i++)
+ src->textSrc.anchors[i]->position += diff;
+ }
+ }
+
+ start = left;
+ end = start + block->length;
+ while (start < end) {
+ start = XawTextSourceScan(w, start, XawstEOL, XawsdRight, 1, True);
+ if (start <= end) {
+ ++lines;
+ if (start == XawTextSourceScan(w, 0, XawstAll, XawsdRight, 1, True)) {
+ lines -= !_XawTextSourceNewLineAtEOF(w);
+ break;
+ }
+ }
+ }
+
+ info.left = left;
+ info.right = right;
+ info.block = block;
+ XtCallCallbacks(w, XtNpropertyCallback, &info);
+
+ TellSourceChanged(src, left, right, block, lines);
+ /* Call callbacks, we have changed the buffer */
+ XtCallCallbacks(w, XtNcallback,
+ (XtPointer)((long)src->textSrc.changed));
+ }
+
+#endif /* OLDXAW */
+ return (error);
+}
+
+#ifndef OLDXAW
+Bool
+_XawTextSrcUndo(TextSrcObject src, XawTextPosition *insert_pos)
+{
+ static wchar_t wnull = 0;
+ XawTextBlock block;
+ XawTextUndoList *list, *nlist;
+ XawTextUndoBuffer *l_state, *r_state;
+ Boolean changed = src->textSrc.changed;
+
+ if (!src->textSrc.enable_undo || !src->textSrc.undo->num_undo)
+ return (False);
+
+ list = src->textSrc.undo->pointer;
+
+ if (src->textSrc.undo->dir == XawsdLeft) {
+ l_state = list->right;
+ r_state = list->left;
+ }
+ else {
+ l_state = list->left;
+ r_state = list->right;
+ }
+
+ if (src->textSrc.undo->l_no_change == l_state
+ && src->textSrc.undo->r_no_change == r_state)
+ src->textSrc.changed = False;
+ else
+ src->textSrc.changed = True;
+
+ block.firstPos = 0;
+ block.length = r_state->length;
+ block.ptr = r_state->buffer ? r_state->buffer : (char*)&wnull;
+ block.format = r_state->format;
+
+ src->textSrc.undo_state = True;
+ if (XawTextSourceReplace((Widget)src, l_state->position, l_state->position
+ + l_state->length, &block) != XawEditDone) {
+ src->textSrc.undo_state = False;
+ src->textSrc.changed = changed;
+ return (False);
+ }
+ src->textSrc.undo_state = False;
+
+ ++l_state->refcount;
+ ++r_state->refcount;
+ nlist = XtNew(XawTextUndoList);
+ nlist->left = l_state;
+ nlist->right = r_state;
+ nlist->undo = src->textSrc.undo->list;
+ nlist->redo = NULL;
+
+ if (list == src->textSrc.undo->list)
+ src->textSrc.undo->end_mark = nlist;
+
+ if (src->textSrc.undo->dir == XawsdLeft) {
+ if (list->undo == NULL)
+ src->textSrc.undo->dir = XawsdRight;
+ else
+ list = list->undo;
+ }
+ else {
+ if (list->redo == NULL || list->redo == src->textSrc.undo->end_mark)
+ src->textSrc.undo->dir = XawsdLeft;
+ else
+ list = list->redo;
+ }
+ *insert_pos = r_state->position + r_state->length;
+ src->textSrc.undo->pointer = list;
+ src->textSrc.undo->list->redo = nlist;
+ src->textSrc.undo->list = nlist;
+ src->textSrc.undo->merge = src->textSrc.undo->erase = 0;
+
+ if (++src->textSrc.undo->num_list >= UNDO_DEPTH)
+ UndoGC(src->textSrc.undo);
+
+ return (True);
+}
+
+Bool
+_XawTextSrcToggleUndo(TextSrcObject src)
+{
+ if (!src->textSrc.enable_undo || !src->textSrc.undo->num_undo)
+ return (False);
+
+ if (src->textSrc.undo->pointer != src->textSrc.undo->list) {
+ if (src->textSrc.undo->dir == XawsdLeft) {
+ if (src->textSrc.undo->pointer->redo
+ && (src->textSrc.undo->pointer->redo
+ != src->textSrc.undo->end_mark)) {
+ src->textSrc.undo->pointer = src->textSrc.undo->pointer->redo;
+ src->textSrc.undo->dir = XawsdRight;
+ }
+ }
+ else {
+ if (src->textSrc.undo->pointer->undo
+ && (src->textSrc.undo->pointer != src->textSrc.undo->head)) {
+ src->textSrc.undo->pointer = src->textSrc.undo->pointer->undo;
+ src->textSrc.undo->dir = XawsdLeft;
+ }
+ }
+ }
+
+ return (True);
+}
+
+static void
+FreeUndoBuffer(XawTextUndo *undo)
+{
+ unsigned i;
+ XawTextUndoList *head, *del;
+
+ for (i = 0; i < undo->num_undo; i++) {
+ if (undo->undo[i]->buffer && undo->undo[i]->buffer != SrcNL &&
+ undo->undo[i]->buffer != (char*)SrcWNL)
+ XtFree(undo->undo[i]->buffer);
+ XtFree((char*)undo->undo[i]);
+ }
+ XtFree((char*)undo->undo);
+ head = undo->head;
+
+ del = head;
+ while (head) {
+ head = head->redo;
+ XtFree((char*)del);
+ del = head;
+ }
+
+ if (undo->l_save) {
+ XtFree((char*)undo->l_save);
+ undo->l_save = NULL;
+ }
+ if (undo->r_save) {
+ XtFree((char*)undo->r_save);
+ undo->r_save = NULL;
+ }
+ if (undo->u_save) {
+ XtFree((char*)undo->u_save);
+ undo->u_save = NULL;
+ }
+
+ undo->list = undo->pointer = undo->head = undo->end_mark = NULL;
+ undo->l_no_change = undo->r_no_change = NULL;
+ undo->undo = NULL;
+ undo->dir = XawsdLeft;
+ undo->num_undo = undo->num_list = undo->erase = undo->merge = 0;
+}
+
+static void
+UndoGC(XawTextUndo *undo)
+{
+ unsigned i;
+ XawTextUndoList *head = undo->head, *redo = head->redo;
+
+ if (head == undo->pointer || head == undo->end_mark
+ || undo->l_no_change == NULL
+ || head->left == undo->l_no_change || head->right == undo->l_no_change)
+ return;
+
+ undo->head = redo;
+ redo->undo = NULL;
+
+ --head->left->refcount;
+ if (--head->right->refcount == 0) {
+ for (i = 0; i < undo->num_undo; i+= 2)
+ if (head->left == undo->undo[i] || head->left == undo->undo[i+1]) {
+ if (head->left == undo->undo[i+1]) {
+ XawTextUndoBuffer *tmp = redo->left;
+
+ redo->left = redo->right;
+ redo->right = tmp;
+ }
+ if (head->left->buffer && head->left->buffer != SrcNL &&
+ head->left->buffer != (char*)SrcWNL)
+ XtFree(head->left->buffer);
+ XtFree((char*)head->left);
+ if (head->right->buffer && head->right->buffer != SrcNL &&
+ head->right->buffer != (char*)SrcWNL)
+ XtFree(head->right->buffer);
+ XtFree((char*)head->right);
+
+ undo->num_undo -= 2;
+ memmove(&undo->undo[i], &undo->undo[i + 2],
+ (undo->num_undo - i) * sizeof(XawTextUndoBuffer*));
+ break;
+ }
+ }
+ XtFree((char*)head);
+ --undo->num_list;
+}
+#endif /* OLDXAW */
+
+/*
+ * Function:
+ * XawTextSourceScan
+ *
+ * Parameters:
+ * w - TextSrc Object
+ * position - position to start scanning
+ * type - type of thing to scan for
+ * dir - direction to scan
+ * count - which occurance if this thing to search for
+ * include - whether or not to include the character found in
+ * the position that is returned.
+ *
+ * Description:
+ * Scans the text source for the number and type of item specified.
+ *
+ * Returns:
+ * The position of the text
+ */
+XawTextPosition
+XawTextSourceScan(Widget w, XawTextPosition position,
+#if NeedWidePrototypes
+ int type, int dir, int count, int include
+#else
+ XawTextScanType type, XawTextScanDirection dir,
+ int count, Boolean include
+#endif
+)
+{
+ TextSrcObjectClass cclass = (TextSrcObjectClass)w->core.widget_class;
+
+ return ((*cclass->textSrc_class.Scan)
+ (w, position, type, dir, count, include));
+}
+
+/*
+ * Function:
+ * XawTextSourceSearch
+ *
+ * Parameters:
+ * w - TextSource Object
+ * position - position to start scanning
+ * dir - direction to scan
+ * text - the text block to search for.
+ *
+ * Returns:
+ * The position of the text we are searching for or XawTextSearchError.
+ *
+ * Description:
+ * Searchs the text source for the text block passed
+ */
+XawTextPosition
+XawTextSourceSearch(Widget w, XawTextPosition position,
+#if NeedWidePrototypes
+ int dir,
+#else
+ XawTextScanDirection dir,
+#endif
+ XawTextBlock *text)
+{
+ TextSrcObjectClass cclass = (TextSrcObjectClass)w->core.widget_class;
+
+ return ((*cclass->textSrc_class.Search)(w, position, dir, text));
+}
+
+/*
+ * Function:
+ * XawTextSourceConvertSelection
+ *
+ * Parameters:
+ * w - TextSrc object
+ * selection - current selection atom
+ * target - current target atom
+ * type - type to conver the selection to
+ * value - return value that has been converted
+ * length - ""
+ * format - format of the returned value
+ *
+ * Returns:
+ * True if the selection has been converted
+ */
+Boolean
+XawTextSourceConvertSelection(Widget w, Atom *selection, Atom *target,
+ Atom *type, XtPointer *value,
+ unsigned long *length, int *format)
+{
+ TextSrcObjectClass cclass = (TextSrcObjectClass)w->core.widget_class;
+
+ return((*cclass->textSrc_class.ConvertSelection)
+ (w, selection, target, type, value, length, format));
+}
+
+/*
+ * Function:
+ * XawTextSourceSetSelection
+ *
+ * Parameters:
+ * w - TextSrc object
+ * left - bounds of the selection
+ * rigth - ""
+ * selection - selection atom
+ *
+ * Description:
+ * Allows special setting of the selection.
+ */
+void
+XawTextSourceSetSelection(Widget w, XawTextPosition left,
+ XawTextPosition right, Atom selection)
+{
+ TextSrcObjectClass cclass = (TextSrcObjectClass)w->core.widget_class;
+
+ (*cclass->textSrc_class.SetSelection)(w, left, right, selection);
+}
+
+/*
+ * External Functions for Multi Text
+ */
+/*
+ * TextFormat():
+ * returns the format of text: FMT8BIT or FMTWIDE
+ */
+XrmQuark
+_XawTextFormat(TextWidget tw)
+{
+ return (((TextSrcObject)(tw->text.source))->textSrc.text_format);
+}
+
+/* _XawTextWCToMB():
+ * Convert the wchar string to external encoding
+ * The caller is responsible for freeing both the source and ret string
+ *
+ * wstr - source wchar string
+ * len_in_out - lengh of string.
+ * As In, length of source wchar string, measured in wchar
+ * As Out, length of returned string
+ */
+char *
+_XawTextWCToMB(Display *d, wchar_t *wstr, int *len_in_out)
+{
+ XTextProperty textprop;
+
+ if (XwcTextListToTextProperty(d, (wchar_t**)&wstr, 1,
+ XTextStyle, &textprop) < Success) {
+ XtWarningMsg("convertError", "textSource", "XawError",
+ "Non-character code(s) in buffer.", NULL, NULL);
+ *len_in_out = 0;
+ return (NULL);
+ }
+ *len_in_out = textprop.nitems;
+
+ return ((char *)textprop.value);
+}
+
+/* _XawTextMBToWC():
+ * Convert the string to internal processing codeset WC.
+ * The caller is responsible for freeing both the source and ret string.
+ *
+ * str - source string
+ * len_in_out - lengh of string
+ * As In, it is length of source string
+ * As Out, it is length of returned string, measured in wchar
+ */
+wchar_t *
+_XawTextMBToWC(Display *d, char *str, int *len_in_out)
+{
+ XTextProperty textprop;
+ char *buf;
+ wchar_t **wlist, *wstr;
+ int count;
+
+ if (*len_in_out == 0)
+ return (NULL);
+
+ buf = XtMalloc(*len_in_out + 1);
+
+ strncpy(buf, str, *len_in_out);
+ *(buf + *len_in_out) = '\0';
+ if (XmbTextListToTextProperty(d, &buf, 1, XTextStyle, &textprop) != Success) {
+ XtWarningMsg("convertError", "textSource", "XawError",
+ "No Memory, or Locale not supported.", NULL, NULL);
+ XtFree(buf);
+ *len_in_out = 0;
+ return (NULL);
+ }
+
+ XtFree(buf);
+ if (XwcTextPropertyToTextList(d, &textprop,
+ (wchar_t***)&wlist, &count) != Success) {
+ XtWarningMsg("convertError", "multiSourceCreate", "XawError",
+ "Non-character code(s) in source.", NULL, NULL);
+ *len_in_out = 0;
+ return (NULL);
+ }
+ wstr = wlist[0];
+ *len_in_out = wcslen(wstr);
+ XtFree((XtPointer)wlist);
+
+ return (wstr);
+}
+
+#ifndef OLDXAW
+static int
+qcmp_anchors(_Xconst void *left, _Xconst void *right)
+{
+ return ((*(XawTextAnchor**)left)->position -
+ (*(XawTextAnchor**)right)->position);
+}
+
+XawTextAnchor *
+XawTextSourceAddAnchor(Widget w, XawTextPosition position)
+{
+ TextSrcObject src = (TextSrcObject)w;
+ XawTextAnchor *anchor, *panchor;
+
+ if ((panchor = XawTextSourceFindAnchor(w, position)) != NULL) {
+ XawTextEntity *pentity, *entity;
+
+ if (position - panchor->position < ANCHORS_DIST)
+ return (panchor);
+
+ if (panchor->cache && panchor->position + panchor->cache->offset +
+ panchor->cache->length < position)
+ pentity = entity = panchor->cache;
+ else
+ pentity = entity = panchor->entities;
+
+ while (entity && panchor->position + entity->offset +
+ entity->length < position) {
+ pentity = entity;
+ entity = entity->next;
+ }
+ if (entity) {
+ XawTextPosition diff;
+
+ if (panchor->position + entity->offset < position)
+ position = panchor->position + entity->offset;
+
+ if (position == panchor->position)
+ return (panchor);
+
+ anchor = XtNew(XawTextAnchor);
+ diff = position - panchor->position;
+
+ panchor->cache = NULL;
+ anchor->entities = entity;
+ if (pentity != entity)
+ pentity->next = NULL;
+ else
+ panchor->entities = NULL;
+ while (entity) {
+ entity->offset -= diff;
+ entity = entity->next;
+ }
+ }
+ else {
+ anchor = XtNew(XawTextAnchor);
+ anchor->entities = NULL;
+ }
+ }
+ else {
+ anchor = XtNew(XawTextAnchor);
+ anchor->entities = NULL;
+ }
+
+ anchor->position = position;
+ anchor->cache = NULL;
+
+ src->textSrc.anchors = (XawTextAnchor**)
+ XtRealloc((XtPointer)src->textSrc.anchors, sizeof(XawTextAnchor*) *
+ (src->textSrc.num_anchors + 1));
+ src->textSrc.anchors[src->textSrc.num_anchors++] = anchor;
+ qsort((void*)src->textSrc.anchors, src->textSrc.num_anchors,
+ sizeof(XawTextAnchor*), qcmp_anchors);
+
+ return (anchor);
+}
+
+XawTextAnchor *
+XawTextSourceFindAnchor(Widget w, XawTextPosition position)
+{
+ TextSrcObject src = (TextSrcObject)w;
+ int i = 0, left, right, nmemb = src->textSrc.num_anchors;
+ XawTextAnchor *anchor, **anchors = src->textSrc.anchors;
+
+ left = 0;
+ right = nmemb - 1;
+ while (left <= right) {
+ anchor = anchors[i = (left + right) >> 1];
+ if (anchor->position == position)
+ return (anchor);
+ else if (position < anchor->position)
+ right = i - 1;
+ else
+ left = i + 1;
+ }
+
+ if (nmemb)
+ return (right < 0 ? anchors[0] : anchors[right]);
+
+ return (NULL);
+}
+
+Bool
+XawTextSourceAnchorAndEntity(Widget w, XawTextPosition position,
+ XawTextAnchor **anchor_return,
+ XawTextEntity **entity_return)
+{
+ XawTextAnchor *anchor = XawTextSourceFindAnchor(w, position);
+ XawTextEntity *pentity, *entity;
+ XawTextPosition offset;
+ Bool next_anchor = True, retval = False;
+
+ if (anchor->cache && anchor->position + anchor->cache->offset +
+ anchor->cache->length <= position)
+ pentity = entity = anchor->cache;
+ else
+ pentity = entity = anchor->entities;
+ while (entity) {
+ offset = anchor->position + entity->offset;
+
+ if (offset > position) {
+ retval = next_anchor = False;
+ break;
+ }
+ if (offset + entity->length > position) {
+ retval = True;
+ next_anchor = False;
+ break;
+ }
+ pentity = entity;
+ entity = entity->next;
+ }
+
+ if (next_anchor) {
+ *anchor_return = anchor = XawTextSourceNextAnchor(w, anchor);
+ *entity_return = anchor ? anchor->entities : NULL;
+ }
+ else {
+ *anchor_return = anchor;
+ *entity_return = retval ? entity : pentity;
+ }
+
+ if (*anchor_return)
+ (*anchor_return)->cache = *entity_return;
+
+ return (retval);
+}
+
+XawTextAnchor *
+XawTextSourceNextAnchor(Widget w, XawTextAnchor *anchor)
+{
+ int i;
+ TextSrcObject src = (TextSrcObject)w;
+
+ for (i = 0; i < src->textSrc.num_anchors - 1; i++)
+ if (src->textSrc.anchors[i] == anchor)
+ return (src->textSrc.anchors[i + 1]);
+
+ return (NULL);
+}
+
+XawTextAnchor *
+XawTextSourcePrevAnchor(Widget w, XawTextAnchor *anchor)
+{
+ int i;
+ TextSrcObject src = (TextSrcObject)w;
+
+ for (i = src->textSrc.num_anchors - 1; i > 0; i--)
+ if (src->textSrc.anchors[i] == anchor)
+ return (src->textSrc.anchors[i - 1]);
+
+ return (NULL);
+}
+
+XawTextAnchor *
+XawTextSourceRemoveAnchor(Widget w, XawTextAnchor *anchor)
+{
+ int i;
+ TextSrcObject src = (TextSrcObject)w;
+
+ for (i = 0; i < src->textSrc.num_anchors; i++)
+ if (src->textSrc.anchors[i] == anchor)
+ break;
+
+ if (i == 0)
+ return (src->textSrc.num_anchors > 1 ? src->textSrc.anchors[1] : NULL);
+
+ if (i < src->textSrc.num_anchors) {
+ XtFree((XtPointer)anchor);
+ if (i < --src->textSrc.num_anchors) {
+ memmove(&src->textSrc.anchors[i],
+ &src->textSrc.anchors[i + 1],
+ (src->textSrc.num_anchors - i) *
+ sizeof(XawTextAnchor*));
+
+ return (src->textSrc.anchors[i]);
+ }
+ }
+
+ return (NULL);
+}
+
+XawTextEntity *
+XawTextSourceAddEntity(Widget w, int type, int flags, XtPointer data,
+ XawTextPosition position, Cardinal length,
+ XrmQuark property)
+{
+ XawTextAnchor *next, *anchor = _XawTextSourceFindAnchor(w, position);
+ XawTextEntity *entity, *eprev;
+
+ /* There is no support for zero length entities for now */
+ if (length == 0)
+ return (NULL);
+
+ if (anchor->cache && anchor->position + anchor->cache->offset +
+ anchor->cache->length <= position)
+ eprev = entity = anchor->cache;
+ else
+ eprev = entity = anchor->entities;
+
+ while (entity && anchor->position + entity->offset + entity->length <=
+ position) {
+ eprev = entity;
+ entity = entity->next;
+ }
+ if (entity && anchor->position + entity->offset < position + length) {
+ fprintf(stderr, "Cannot (yet) add more than one entity to same region.\n");
+ return (NULL);
+ }
+
+ next = XawTextSourceFindAnchor(w, position + length);
+ if (next && next != anchor) {
+ if ((entity = next->entities) != NULL) {
+ if (next->position + entity->offset < position + length) {
+ fprintf(stderr, "Cannot (yet) add more than one entity to same region.\n");
+ return (NULL);
+ }
+ }
+ if (position + length > next->position) {
+ XawTextPosition diff = position + length - next->position;
+
+ next->position += diff;
+ entity = next->entities;
+ while (entity) {
+ entity->offset -= diff;
+ entity = entity->next;
+ }
+ entity = anchor->entities;
+ while (entity && entity->offset < 0)
+ entity = entity->next;
+ if (entity && entity->offset < 0) {
+ if (eprev)
+ eprev->next = next->entities;
+ else
+ anchor->entities = next->entities;
+ if ((next->entities = entity->next) == NULL)
+ (void)XawTextSourceRemoveAnchor(w, next);
+ entity->next = NULL;
+
+ return (XawTextSourceAddEntity(w, type, flags, data, position,
+ length, property));
+ }
+ }
+ }
+
+ /* Automatically join sequential entities if possible */
+ if (eprev &&
+ anchor->position + eprev->offset + eprev->length == position &&
+ eprev->property == property && eprev->type == type &&
+ eprev->flags == flags && eprev->data == data) {
+ eprev->length += length;
+ return (eprev);
+ }
+
+ entity = XtNew(XawTextEntity);
+ entity->type = type;
+ entity->flags = flags;
+ entity->data = data;
+ entity->offset = position - anchor->position;
+ entity->length = length;
+ entity->property = property;
+
+ if (eprev == NULL) {
+ anchor->entities = entity;
+ entity->next = NULL;
+ anchor->cache = NULL;
+ }
+ else if (eprev->offset > entity->offset) {
+ anchor->cache = NULL;
+ anchor->entities = entity;
+ entity->next = eprev;
+ }
+ else {
+ anchor->cache = eprev;
+ entity->next = eprev->next;
+ eprev->next = entity;
+ }
+
+ return (entity);
+}
+
+void
+XawTextSourceClearEntities(Widget w, XawTextPosition left, XawTextPosition right)
+{
+ XawTextAnchor *anchor = XawTextSourceFindAnchor(w, left);
+ XawTextEntity *entity, *eprev, *enext;
+ XawTextPosition offset;
+ int length;
+
+ while (anchor && anchor->entities == NULL)
+ anchor = XawTextSourceRemoveAnchor(w, anchor);
+
+ if (anchor == NULL || left >= right)
+ return;
+
+ if (anchor->cache && anchor->position + anchor->cache->offset +
+ anchor->cache->length < left)
+ eprev = entity = anchor->cache;
+ else
+ eprev = entity = anchor->entities;
+
+ /* find first entity before left position */
+ while (anchor->position + entity->offset + entity->length < left) {
+ eprev = entity;
+ if ((entity = entity->next) == NULL) {
+ if ((anchor = XawTextSourceNextAnchor(w, anchor)) == NULL)
+ return;
+ if ((eprev = entity = anchor->entities) == NULL) {
+ fprintf(stderr, "Bad anchor found!\n");
+ return;
+ }
+ }
+ }
+
+ offset = anchor->position + entity->offset;
+ if (offset <= left) {
+ length = XawMin(entity->length, left - offset);
+
+ if (length <= 0) {
+ enext = entity->next;
+ eprev->next = enext;
+ XtFree((XtPointer)entity);
+ anchor->cache = NULL;
+ if (entity == anchor->entities) {
+ eprev = NULL;
+ if ((anchor->entities = enext) == NULL) {
+ if ((anchor = XawTextSourceRemoveAnchor(w, anchor)) == NULL)
+ return;
+ entity = anchor->entities;
+ }
+ else
+ entity = enext;
+ }
+ else
+ entity = enext;
+ }
+ else {
+ entity->length = length;
+ eprev = entity;
+ entity = entity->next;
+ }
+ }
+
+ /* clean everything until right position is reached */
+ while (anchor) {
+ while (entity) {
+ offset = anchor->position + entity->offset + entity->length;
+
+ if (offset > right) {
+ anchor->cache = NULL;
+ entity->offset = XawMax(entity->offset, right - anchor->position);
+ entity->length = XawMin(entity->length, offset - right);
+ return;
+ }
+
+ enext = entity->next;
+ if (eprev)
+ eprev->next = enext;
+ XtFree((XtPointer)entity);
+ if (entity == anchor->entities) {
+ eprev = anchor->cache = NULL;
+ if ((anchor->entities = enext) == NULL) {
+ if ((anchor = XawTextSourceRemoveAnchor(w, anchor)) == NULL)
+ return;
+ entity = anchor->entities;
+ continue;
+ }
+ }
+ entity = enext;
+ }
+ if (anchor)
+ anchor->cache = NULL;
+ if ((anchor = XawTextSourceNextAnchor(w, anchor)) != NULL)
+ entity = anchor->entities;
+ eprev = NULL;
+ }
+}
+
+/* checks the anchors up to position, and create an appropriate anchor
+ * at position, if required.
+ */
+XawTextAnchor *
+_XawTextSourceFindAnchor(Widget w, XawTextPosition position)
+{
+ XawTextAnchor *anchor;
+
+ anchor = XawTextSourceFindAnchor(w, position);
+
+ position -= position % ANCHORS_DIST;
+
+ if (position - anchor->position >= ANCHORS_DIST)
+ return (XawTextSourceAddAnchor(w, position));
+
+ return (anchor);
+}
+#endif