TextSrc.c revision 7a84e134
17a84e134Smrg/* $Xorg: TextSrc.c,v 1.5 2001/02/09 02:03:47 xorgcvs Exp $ */ 27a84e134Smrg/* 37a84e134Smrg 47a84e134SmrgCopyright 1989, 1994, 1998 The Open Group 57a84e134Smrg 67a84e134SmrgPermission to use, copy, modify, distribute, and sell this software and its 77a84e134Smrgdocumentation for any purpose is hereby granted without fee, provided that 87a84e134Smrgthe above copyright notice appear in all copies and that both that 97a84e134Smrgcopyright notice and this permission notice appear in supporting 107a84e134Smrgdocumentation. 117a84e134Smrg 127a84e134SmrgThe above copyright notice and this permission notice shall be included in 137a84e134Smrgall copies or substantial portions of the Software. 147a84e134Smrg 157a84e134SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 167a84e134SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 177a84e134SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 187a84e134SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 197a84e134SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 207a84e134SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 217a84e134Smrg 227a84e134SmrgExcept as contained in this notice, the name of The Open Group shall not be 237a84e134Smrgused in advertising or otherwise to promote the sale, use or other dealings 247a84e134Smrgin this Software without prior written authorization from The Open Group. 257a84e134Smrg 267a84e134Smrg*/ 277a84e134Smrg 287a84e134Smrg/* $XFree86: xc/lib/Xaw/TextSrc.c,v 1.33 2002/09/08 02:29:47 paulo Exp $ */ 297a84e134Smrg 307a84e134Smrg/* 317a84e134Smrg * Author: Chris Peterson, MIT X Consortium. 327a84e134Smrg * Much code taken from X11R3 String and Disk Sources. 337a84e134Smrg */ 347a84e134Smrg 357a84e134Smrg#ifdef HAVE_CONFIG_H 367a84e134Smrg#include <config.h> 377a84e134Smrg#endif 387a84e134Smrg#include <stdio.h> 397a84e134Smrg#include <ctype.h> 407a84e134Smrg#include <X11/IntrinsicP.h> 417a84e134Smrg#include <X11/StringDefs.h> 427a84e134Smrg#include <X11/Xfuncs.h> 437a84e134Smrg#include <X11/Xutil.h> 447a84e134Smrg#include <X11/Xmu/Atoms.h> 457a84e134Smrg#include <X11/Xmu/CharSet.h> 467a84e134Smrg#include <X11/Xaw/TextSrcP.h> 477a84e134Smrg#include <X11/Xaw/XawInit.h> 487a84e134Smrg#include "XawI18n.h" 497a84e134Smrg#include "Private.h" 507a84e134Smrg 517a84e134Smrg#ifndef OLDXAW 527a84e134Smrg#define UNDO_DEPTH 16384 537a84e134Smrg 547a84e134Smrg#define ANCHORS_DIST 4096 /* default distance between anchors */ 557a84e134Smrg 567a84e134Smrg/* 577a84e134Smrg * Types 587a84e134Smrg */ 597a84e134Smrgtypedef struct { 607a84e134Smrg XawTextPosition position; 617a84e134Smrg char *buffer; 627a84e134Smrg unsigned length; 637a84e134Smrg unsigned refcount; 647a84e134Smrg unsigned long format; 657a84e134Smrg} XawTextUndoBuffer; 667a84e134Smrg 677a84e134Smrgtypedef struct _XawTextUndoList XawTextUndoList; 687a84e134Smrgstruct _XawTextUndoList { 697a84e134Smrg XawTextUndoBuffer *left, *right; 707a84e134Smrg XawTextUndoList *undo, *redo; 717a84e134Smrg}; 727a84e134Smrg 737a84e134Smrgstruct _XawTextUndo { 747a84e134Smrg XawTextUndoBuffer **undo; 757a84e134Smrg unsigned num_undo; 767a84e134Smrg XawTextUndoList *list, *pointer, *end_mark, *head; 777a84e134Smrg unsigned num_list; 787a84e134Smrg XawTextScanDirection dir; 797a84e134Smrg XawTextUndoBuffer *l_save, *r_save; 807a84e134Smrg XawTextUndoList *u_save; 817a84e134Smrg XawTextUndoBuffer *l_no_change, *r_no_change; 827a84e134Smrg int merge; 837a84e134Smrg int erase; /* there are two types of erases */ 847a84e134Smrg}; 857a84e134Smrg#endif /* OLDXAW */ 867a84e134Smrg 877a84e134Smrg/* 887a84e134Smrg * Class Methods 897a84e134Smrg */ 907a84e134Smrgstatic Boolean ConvertSelection(Widget, Atom*, Atom*, Atom*, XtPointer*, 917a84e134Smrg unsigned long*, int*); 927a84e134Smrgstatic XawTextPosition Read(Widget, XawTextPosition, XawTextBlock*, int); 937a84e134Smrgstatic int Replace(Widget, XawTextPosition, XawTextPosition, XawTextBlock*); 947a84e134Smrgstatic XawTextPosition Scan(Widget, XawTextPosition, XawTextScanType, 957a84e134Smrg XawTextScanDirection, int, Bool); 967a84e134Smrgstatic XawTextPosition Search(Widget, XawTextPosition, XawTextScanDirection, 977a84e134Smrg XawTextBlock*); 987a84e134Smrgstatic void SetSelection(Widget, XawTextPosition, XawTextPosition, Atom); 997a84e134Smrgstatic void XawTextSrcClassInitialize(void); 1007a84e134Smrgstatic void XawTextSrcClassPartInitialize(WidgetClass); 1017a84e134Smrgstatic void XawTextSrcInitialize(Widget, Widget, ArgList, Cardinal*); 1027a84e134Smrgstatic void XawTextSrcDestroy(Widget); 1037a84e134Smrgstatic Boolean XawTextSrcSetValues(Widget, Widget, Widget, ArgList, Cardinal*); 1047a84e134Smrg/* 1057a84e134Smrg * Prototypes 1067a84e134Smrg */ 1077a84e134Smrgstatic void CvtStringToEditMode(XrmValuePtr, Cardinal*, 1087a84e134Smrg XrmValuePtr, XrmValuePtr); 1097a84e134Smrgstatic Boolean CvtEditModeToString(Display*, XrmValuePtr, Cardinal*, 1107a84e134Smrg XrmValuePtr, XrmValuePtr, XtPointer*); 1117a84e134Smrg#ifndef OLDXAW 1127a84e134Smrgstatic void FreeUndoBuffer(XawTextUndo*); 1137a84e134Smrgstatic void UndoGC(XawTextUndo*); 1147a84e134Smrgstatic void TellSourceChanged(TextSrcObject, XawTextPosition, XawTextPosition, 1157a84e134Smrg XawTextBlock*, int); 1167a84e134SmrgBool _XawTextSrcUndo(TextSrcObject, XawTextPosition*); 1177a84e134SmrgBool _XawTextSrcToggleUndo(TextSrcObject); 1187a84e134SmrgXawTextAnchor *_XawTextSourceFindAnchor(Widget, XawTextPosition); 1197a84e134Smrg 1207a84e134Smrg/* 1217a84e134Smrg * External 1227a84e134Smrg */ 1237a84e134Smrgvoid _XawSourceAddText(Widget, Widget); 1247a84e134Smrgvoid _XawSourceRemoveText(Widget, Widget, Bool); 1257a84e134SmrgBool _XawTextSourceNewLineAtEOF(Widget); 1267a84e134Smrgvoid _XawSourceSetUndoErase(TextSrcObject, int); 1277a84e134Smrgvoid _XawSourceSetUndoMerge(TextSrcObject, Bool); 1287a84e134Smrg#endif /* OLDXAW */ 1297a84e134Smrg 1307a84e134Smrg/* 1317a84e134Smrg * Defined in Text.c 1327a84e134Smrg */ 1337a84e134Smrgchar *_XawTextGetText(TextWidget, XawTextPosition, XawTextPosition); 1347a84e134Smrgvoid _XawTextSourceChanged(Widget, XawTextPosition, XawTextPosition, 1357a84e134Smrg XawTextBlock*, int); 1367a84e134Smrg 1377a84e134Smrg/* 1387a84e134Smrg * Initialization 1397a84e134Smrg */ 1407a84e134Smrg#define offset(field) XtOffsetOf(TextSrcRec, textSrc.field) 1417a84e134Smrgstatic XtResource resources[] = { 1427a84e134Smrg { 1437a84e134Smrg XtNeditType, 1447a84e134Smrg XtCEditType, 1457a84e134Smrg XtREditMode, 1467a84e134Smrg sizeof(XawTextEditType), 1477a84e134Smrg offset(edit_mode), 1487a84e134Smrg XtRString, 1497a84e134Smrg "read" 1507a84e134Smrg }, 1517a84e134Smrg#ifndef OLDXAW 1527a84e134Smrg { 1537a84e134Smrg XtNcallback, 1547a84e134Smrg XtCCallback, 1557a84e134Smrg XtRCallback, 1567a84e134Smrg sizeof(XtPointer), 1577a84e134Smrg offset(callback), 1587a84e134Smrg XtRCallback, 1597a84e134Smrg NULL 1607a84e134Smrg }, 1617a84e134Smrg { 1627a84e134Smrg XtNsourceChanged, 1637a84e134Smrg XtCChanged, 1647a84e134Smrg XtRBoolean, 1657a84e134Smrg sizeof(Boolean), 1667a84e134Smrg offset(changed), 1677a84e134Smrg XtRImmediate, 1687a84e134Smrg (XtPointer)False 1697a84e134Smrg }, 1707a84e134Smrg { 1717a84e134Smrg XtNenableUndo, 1727a84e134Smrg XtCUndo, 1737a84e134Smrg XtRBoolean, 1747a84e134Smrg sizeof(Boolean), 1757a84e134Smrg offset(enable_undo), 1767a84e134Smrg XtRImmediate, 1777a84e134Smrg (XtPointer)False 1787a84e134Smrg }, 1797a84e134Smrg { 1807a84e134Smrg XtNpropertyCallback, 1817a84e134Smrg XtCCallback, 1827a84e134Smrg XtRCallback, 1837a84e134Smrg sizeof(XtPointer), 1847a84e134Smrg offset(property_callback), 1857a84e134Smrg XtRCallback, 1867a84e134Smrg NULL 1877a84e134Smrg }, 1887a84e134Smrg#endif /* OLDXAW */ 1897a84e134Smrg}; 1907a84e134Smrg#undef offset 1917a84e134Smrg 1927a84e134Smrg#define Superclass (&objectClassRec) 1937a84e134SmrgTextSrcClassRec textSrcClassRec = { 1947a84e134Smrg /* object */ 1957a84e134Smrg { 1967a84e134Smrg (WidgetClass)Superclass, /* superclass */ 1977a84e134Smrg "TextSrc", /* class_name */ 1987a84e134Smrg sizeof(TextSrcRec), /* widget_size */ 1997a84e134Smrg XawTextSrcClassInitialize, /* class_initialize */ 2007a84e134Smrg XawTextSrcClassPartInitialize, /* class_part_initialize */ 2017a84e134Smrg False, /* class_inited */ 2027a84e134Smrg XawTextSrcInitialize, /* initialize */ 2037a84e134Smrg NULL, /* initialize_hook */ 2047a84e134Smrg NULL, /* realize */ 2057a84e134Smrg NULL, /* actions */ 2067a84e134Smrg 0, /* num_actions */ 2077a84e134Smrg resources, /* resources */ 2087a84e134Smrg XtNumber(resources), /* num_resources */ 2097a84e134Smrg NULLQUARK, /* xrm_class */ 2107a84e134Smrg False, /* compress_motion */ 2117a84e134Smrg False, /* compress_exposure */ 2127a84e134Smrg False, /* compress_enterleave */ 2137a84e134Smrg False, /* visible_interest */ 2147a84e134Smrg XawTextSrcDestroy, /* destroy */ 2157a84e134Smrg NULL, /* resize */ 2167a84e134Smrg NULL, /* expose */ 2177a84e134Smrg XawTextSrcSetValues, /* set_values */ 2187a84e134Smrg NULL, /* set_values_hook */ 2197a84e134Smrg NULL, /* set_values_almost */ 2207a84e134Smrg NULL, /* get_values_hook */ 2217a84e134Smrg NULL, /* accept_focus */ 2227a84e134Smrg XtVersion, /* version */ 2237a84e134Smrg NULL, /* callback_private */ 2247a84e134Smrg NULL, /* tm_table */ 2257a84e134Smrg NULL, /* query_geometry */ 2267a84e134Smrg NULL, /* display_accelerator */ 2277a84e134Smrg NULL, /* extension */ 2287a84e134Smrg }, 2297a84e134Smrg /* text_src */ 2307a84e134Smrg { 2317a84e134Smrg Read, /* Read */ 2327a84e134Smrg Replace, /* Replace */ 2337a84e134Smrg Scan, /* Scan */ 2347a84e134Smrg Search, /* Search */ 2357a84e134Smrg SetSelection, /* SetSelection */ 2367a84e134Smrg ConvertSelection, /* ConvertSelection */ 2377a84e134Smrg }, 2387a84e134Smrg}; 2397a84e134Smrg 2407a84e134SmrgWidgetClass textSrcObjectClass = (WidgetClass)&textSrcClassRec; 2417a84e134Smrg 2427a84e134Smrgstatic XrmQuark QRead, QAppend, QEdit; 2437a84e134Smrg#ifndef OLDXAW 2447a84e134Smrgstatic char *SrcNL = "\n"; 2457a84e134Smrgstatic wchar_t SrcWNL[2]; 2467a84e134Smrg#endif 2477a84e134Smrg 2487a84e134Smrg/* 2497a84e134Smrg * Implementation 2507a84e134Smrg */ 2517a84e134Smrgstatic void 2527a84e134SmrgXawTextSrcClassInitialize(void) 2537a84e134Smrg{ 2547a84e134Smrg XawInitializeWidgetSet(); 2557a84e134Smrg 2567a84e134Smrg#ifndef OLDXAW 2577a84e134Smrg SrcWNL[0] = _Xaw_atowc(XawLF); 2587a84e134Smrg SrcWNL[1] = 0; 2597a84e134Smrg#endif 2607a84e134Smrg QRead = XrmPermStringToQuark(XtEtextRead); 2617a84e134Smrg QAppend = XrmPermStringToQuark(XtEtextAppend); 2627a84e134Smrg QEdit = XrmPermStringToQuark(XtEtextEdit); 2637a84e134Smrg XtAddConverter(XtRString, XtREditMode, CvtStringToEditMode, NULL, 0); 2647a84e134Smrg XtSetTypeConverter(XtREditMode, XtRString, CvtEditModeToString, NULL, 0, 2657a84e134Smrg XtCacheNone, NULL); 2667a84e134Smrg} 2677a84e134Smrg 2687a84e134Smrgstatic void 2697a84e134SmrgXawTextSrcClassPartInitialize(WidgetClass wc) 2707a84e134Smrg{ 2717a84e134Smrg TextSrcObjectClass t_src, superC; 2727a84e134Smrg 2737a84e134Smrg t_src = (TextSrcObjectClass)wc; 2747a84e134Smrg superC = (TextSrcObjectClass)t_src->object_class.superclass; 2757a84e134Smrg 2767a84e134Smrg /* 2777a84e134Smrg * We don't need to check for null super since we'll get to TextSrc 2787a84e134Smrg * eventually 2797a84e134Smrg */ 2807a84e134Smrg if (t_src->textSrc_class.Read == XtInheritRead) 2817a84e134Smrg t_src->textSrc_class.Read = superC->textSrc_class.Read; 2827a84e134Smrg 2837a84e134Smrg if (t_src->textSrc_class.Replace == XtInheritReplace) 2847a84e134Smrg t_src->textSrc_class.Replace = superC->textSrc_class.Replace; 2857a84e134Smrg 2867a84e134Smrg if (t_src->textSrc_class.Scan == XtInheritScan) 2877a84e134Smrg t_src->textSrc_class.Scan = superC->textSrc_class.Scan; 2887a84e134Smrg 2897a84e134Smrg if (t_src->textSrc_class.Search == XtInheritSearch) 2907a84e134Smrg t_src->textSrc_class.Search = superC->textSrc_class.Search; 2917a84e134Smrg 2927a84e134Smrg if (t_src->textSrc_class.SetSelection == XtInheritSetSelection) 2937a84e134Smrg t_src->textSrc_class.SetSelection = superC->textSrc_class.SetSelection; 2947a84e134Smrg 2957a84e134Smrg if (t_src->textSrc_class.ConvertSelection == XtInheritConvertSelection) 2967a84e134Smrg t_src->textSrc_class.ConvertSelection = 2977a84e134Smrg superC->textSrc_class.ConvertSelection; 2987a84e134Smrg} 2997a84e134Smrg 3007a84e134Smrg/*ARGSUSED*/ 3017a84e134Smrgstatic void 3027a84e134SmrgXawTextSrcInitialize(Widget request, Widget cnew, 3037a84e134Smrg ArgList args, Cardinal *num_args) 3047a84e134Smrg{ 3057a84e134Smrg#ifndef OLDXAW 3067a84e134Smrg TextSrcObject src = (TextSrcObject)cnew; 3077a84e134Smrg 3087a84e134Smrg if (src->textSrc.enable_undo) { 3097a84e134Smrg src->textSrc.undo = (XawTextUndo*)XtCalloc(1, sizeof(XawTextUndo)); 3107a84e134Smrg src->textSrc.undo->dir = XawsdLeft; 3117a84e134Smrg } 3127a84e134Smrg else 3137a84e134Smrg src->textSrc.undo = NULL; 3147a84e134Smrg src->textSrc.undo_state = False; 3157a84e134Smrg if (XtIsSubclass(XtParent(cnew), textWidgetClass)) { 3167a84e134Smrg src->textSrc.text = (WidgetList)XtMalloc(sizeof(Widget*)); 3177a84e134Smrg src->textSrc.text[0] = XtParent(cnew); 3187a84e134Smrg src->textSrc.num_text = 1; 3197a84e134Smrg } 3207a84e134Smrg else { 3217a84e134Smrg src->textSrc.text = NULL; 3227a84e134Smrg src->textSrc.num_text = 0; 3237a84e134Smrg } 3247a84e134Smrg 3257a84e134Smrg src->textSrc.anchors = NULL; 3267a84e134Smrg src->textSrc.num_anchors = 0; 3277a84e134Smrg (void)XawTextSourceAddAnchor(cnew, 0); 3287a84e134Smrg#endif /* OLDXAW */ 3297a84e134Smrg} 3307a84e134Smrg 3317a84e134Smrgstatic void 3327a84e134SmrgXawTextSrcDestroy(Widget w) 3337a84e134Smrg{ 3347a84e134Smrg#ifndef OLDXAW 3357a84e134Smrg TextSrcObject src = (TextSrcObject)w; 3367a84e134Smrg 3377a84e134Smrg if (src->textSrc.enable_undo) { 3387a84e134Smrg FreeUndoBuffer(src->textSrc.undo); 3397a84e134Smrg XtFree((char*)src->textSrc.undo); 3407a84e134Smrg } 3417a84e134Smrg XtFree((char*)src->textSrc.text); 3427a84e134Smrg 3437a84e134Smrg if (src->textSrc.num_anchors) { 3447a84e134Smrg XawTextEntity *entity, *enext; 3457a84e134Smrg int i; 3467a84e134Smrg 3477a84e134Smrg for (i = 0; i < src->textSrc.num_anchors; i++) { 3487a84e134Smrg entity = src->textSrc.anchors[i]->entities; 3497a84e134Smrg while (entity) { 3507a84e134Smrg enext = entity->next; 3517a84e134Smrg XtFree((XtPointer)entity); 3527a84e134Smrg entity = enext; 3537a84e134Smrg } 3547a84e134Smrg XtFree((XtPointer)src->textSrc.anchors[i]); 3557a84e134Smrg } 3567a84e134Smrg XtFree((XtPointer)src->textSrc.anchors); 3577a84e134Smrg } 3587a84e134Smrg#endif /* OLDXAW */ 3597a84e134Smrg} 3607a84e134Smrg 3617a84e134Smrg/*ARGSUSED*/ 3627a84e134Smrgstatic Boolean 3637a84e134SmrgXawTextSrcSetValues(Widget current, Widget request, Widget cnew, 3647a84e134Smrg ArgList args, Cardinal *num_args) 3657a84e134Smrg{ 3667a84e134Smrg#ifndef OLDXAW 3677a84e134Smrg TextSrcObject oldtw = (TextSrcObject)current; 3687a84e134Smrg TextSrcObject newtw = (TextSrcObject)cnew; 3697a84e134Smrg 3707a84e134Smrg if (oldtw->textSrc.enable_undo != newtw->textSrc.enable_undo) { 3717a84e134Smrg if (newtw->textSrc.enable_undo) { 3727a84e134Smrg newtw->textSrc.undo = (XawTextUndo*) 3737a84e134Smrg XtCalloc(1, sizeof(XawTextUndo)); 3747a84e134Smrg newtw->textSrc.undo->dir = XawsdLeft; 3757a84e134Smrg } 3767a84e134Smrg else { 3777a84e134Smrg FreeUndoBuffer(newtw->textSrc.undo); 3787a84e134Smrg XtFree((char*)newtw->textSrc.undo); 3797a84e134Smrg newtw->textSrc.undo = NULL; 3807a84e134Smrg } 3817a84e134Smrg } 3827a84e134Smrg if (oldtw->textSrc.changed != newtw->textSrc.changed) { 3837a84e134Smrg if (newtw->textSrc.enable_undo) { 3847a84e134Smrg if (newtw->textSrc.undo->list) { 3857a84e134Smrg newtw->textSrc.undo->l_no_change = 3867a84e134Smrg newtw->textSrc.undo->list->left; 3877a84e134Smrg newtw->textSrc.undo->r_no_change = 3887a84e134Smrg newtw->textSrc.undo->list->right; 3897a84e134Smrg } 3907a84e134Smrg else 3917a84e134Smrg newtw->textSrc.undo->l_no_change = 3927a84e134Smrg newtw->textSrc.undo->r_no_change = NULL; 3937a84e134Smrg } 3947a84e134Smrg } 3957a84e134Smrg#endif /* OLDXAW */ 3967a84e134Smrg return (False); 3977a84e134Smrg} 3987a84e134Smrg 3997a84e134Smrg/* 4007a84e134Smrg * Function: 4017a84e134Smrg * Read 4027a84e134Smrg * 4037a84e134Smrg * Parameters: 4047a84e134Smrg * w - TextSrc Object 4057a84e134Smrg * pos - position of the text to retreive 4067a84e134Smrg * text - text block that will contain returned text 4077a84e134Smrg * length - maximum number of characters to read 4087a84e134Smrg * 4097a84e134Smrg * Description: 4107a84e134Smrg * This function reads the source. 4117a84e134Smrg * 4127a84e134Smrg * Returns: 4137a84e134Smrg * The character position following the retrieved text. 4147a84e134Smrg */ 4157a84e134Smrg/*ARGSUSED*/ 4167a84e134Smrgstatic XawTextPosition 4177a84e134SmrgRead(Widget w, XawTextPosition pos, XawTextBlock *text, int length) 4187a84e134Smrg{ 4197a84e134Smrg return ((XawTextPosition)0); 4207a84e134Smrg} 4217a84e134Smrg 4227a84e134Smrg/* 4237a84e134Smrg * Function: 4247a84e134Smrg * Replace 4257a84e134Smrg * 4267a84e134Smrg * Parameters: 4277a84e134Smrg * src - Text Source Object 4287a84e134Smrg * startPos - ends of text that will be removed 4297a84e134Smrg * endPos - "" 4307a84e134Smrg * text - new text to be inserted into buffer at startPos 4317a84e134Smrg * 4327a84e134Smrg * Description: 4337a84e134Smrg * Replaces a block of text with new text. 4347a84e134Smrg */ 4357a84e134Smrg/*ARGSUSED*/ 4367a84e134Smrgstatic int 4377a84e134SmrgReplace(Widget w, XawTextPosition startPos, XawTextPosition endPos, 4387a84e134Smrg XawTextBlock *text) 4397a84e134Smrg{ 4407a84e134Smrg return (XawEditError); 4417a84e134Smrg} 4427a84e134Smrg 4437a84e134Smrg/* 4447a84e134Smrg * Function: 4457a84e134Smrg * Scan 4467a84e134Smrg * 4477a84e134Smrg * Parameters: 4487a84e134Smrg * w - TextSrc Object 4497a84e134Smrg * position - position to start scanning 4507a84e134Smrg * type - type of thing to scan for 4517a84e134Smrg * dir - direction to scan 4527a84e134Smrg * count - which occurance if this thing to search for 4537a84e134Smrg * include - whether or not to include the character found in 4547a84e134Smrg * the position that is returned 4557a84e134Smrg * 4567a84e134Smrg * Description: 4577a84e134Smrg * Scans the text source for the number and type of item specified. 4587a84e134Smrg */ 4597a84e134Smrg/*ARGSUSED*/ 4607a84e134Smrgstatic XawTextPosition 4617a84e134SmrgScan(Widget w, XawTextPosition position, XawTextScanType type, 4627a84e134Smrg XawTextScanDirection dir, int count, Bool include) 4637a84e134Smrg{ 4647a84e134Smrg return ((XawTextPosition)0); 4657a84e134Smrg} 4667a84e134Smrg 4677a84e134Smrg/* 4687a84e134Smrg * Function: 4697a84e134Smrg * Search 4707a84e134Smrg * 4717a84e134Smrg * Parameters: 4727a84e134Smrg * w - TextSource Object 4737a84e134Smrg * position - position to start searching 4747a84e134Smrg * dir - direction to search 4757a84e134Smrg * text - the text block to search for 4767a84e134Smrg * 4777a84e134Smrg * Description: 4787a84e134Smrg * Searchs the text source for the text block passed 4797a84e134Smrg */ 4807a84e134Smrg/*ARGSUSED*/ 4817a84e134Smrgstatic XawTextPosition 4827a84e134SmrgSearch(Widget w, XawTextPosition position, XawTextScanDirection dir, 4837a84e134Smrg XawTextBlock *text) 4847a84e134Smrg{ 4857a84e134Smrg return (XawTextSearchError); 4867a84e134Smrg} 4877a84e134Smrg 4887a84e134Smrg/*ARGSUSED*/ 4897a84e134Smrgstatic Boolean 4907a84e134SmrgConvertSelection(Widget w, Atom *selection, Atom *target, Atom *type, 4917a84e134Smrg XtPointer *value, unsigned long *length, int *format) 4927a84e134Smrg{ 4937a84e134Smrg return (False); 4947a84e134Smrg} 4957a84e134Smrg 4967a84e134Smrg/*ARGSUSED*/ 4977a84e134Smrgstatic void 4987a84e134SmrgSetSelection(Widget w, XawTextPosition left, XawTextPosition right, 4997a84e134Smrg Atom selection) 5007a84e134Smrg{ 5017a84e134Smrg} 5027a84e134Smrg 5037a84e134Smrg/*ARGSUSED*/ 5047a84e134Smrgstatic void 5057a84e134SmrgCvtStringToEditMode(XrmValuePtr args, Cardinal *num_args, 5067a84e134Smrg XrmValuePtr fromVal, XrmValuePtr toVal) 5077a84e134Smrg{ 5087a84e134Smrg static XawTextEditType editType; 5097a84e134Smrg XrmQuark q; 5107a84e134Smrg char name[7]; 5117a84e134Smrg 5127a84e134Smrg XmuNCopyISOLatin1Lowered(name, (char *)fromVal->addr, sizeof(name)); 5137a84e134Smrg q = XrmStringToQuark(name); 5147a84e134Smrg 5157a84e134Smrg if (q == QRead) 5167a84e134Smrg editType = XawtextRead; 5177a84e134Smrg else if (q == QAppend) 5187a84e134Smrg editType = XawtextAppend; 5197a84e134Smrg else if (q == QEdit) 5207a84e134Smrg editType = XawtextEdit; 5217a84e134Smrg else { 5227a84e134Smrg toVal->size = 0; 5237a84e134Smrg toVal->addr = NULL; 5247a84e134Smrg XtStringConversionWarning((char *)fromVal->addr, XtREditMode); 5257a84e134Smrg } 5267a84e134Smrg toVal->size = sizeof(XawTextEditType); 5277a84e134Smrg toVal->addr = (XPointer)&editType; 5287a84e134Smrg} 5297a84e134Smrg 5307a84e134Smrg/*ARGSUSED*/ 5317a84e134Smrgstatic Boolean 5327a84e134SmrgCvtEditModeToString(Display *dpy, XrmValuePtr args, Cardinal *num_args, 5337a84e134Smrg XrmValuePtr fromVal, XrmValuePtr toVal, 5347a84e134Smrg XtPointer *data) 5357a84e134Smrg{ 5367a84e134Smrg static String buffer; 5377a84e134Smrg Cardinal size; 5387a84e134Smrg 5397a84e134Smrg switch (*(XawTextEditType *)fromVal->addr) { 5407a84e134Smrg case XawtextAppend: 5417a84e134Smrg case XawtextRead: 5427a84e134Smrg buffer = XtEtextRead; 5437a84e134Smrg break; 5447a84e134Smrg buffer = XtEtextAppend; 5457a84e134Smrg break; 5467a84e134Smrg case XawtextEdit: 5477a84e134Smrg buffer = XtEtextEdit; 5487a84e134Smrg break; 5497a84e134Smrg default: 5507a84e134Smrg XawTypeToStringWarning(dpy, XtREditMode); 5517a84e134Smrg toVal->addr = NULL; 5527a84e134Smrg toVal->size = 0; 5537a84e134Smrg return (False); 5547a84e134Smrg } 5557a84e134Smrg 5567a84e134Smrg size = strlen(buffer) + 1; 5577a84e134Smrg if (toVal->addr != NULL) { 5587a84e134Smrg if (toVal->size < size) { 5597a84e134Smrg toVal->size = size; 5607a84e134Smrg return (False); 5617a84e134Smrg } 5627a84e134Smrg strcpy((char *)toVal->addr, buffer); 5637a84e134Smrg } 5647a84e134Smrg else 5657a84e134Smrg toVal->addr = (XPointer)buffer; 5667a84e134Smrg toVal->size = sizeof(String); 5677a84e134Smrg 5687a84e134Smrg return (True); 5697a84e134Smrg} 5707a84e134Smrg 5717a84e134Smrg#ifndef OLDXAW 5727a84e134SmrgBool 5737a84e134Smrg_XawTextSourceNewLineAtEOF(Widget w) 5747a84e134Smrg{ 5757a84e134Smrg TextSrcObject src = (TextSrcObject)w; 5767a84e134Smrg XawTextBlock text; 5777a84e134Smrg 5787a84e134Smrg text.firstPos = 0; 5797a84e134Smrg if ((text.format = src->textSrc.text_format) == XawFmt8Bit) 5807a84e134Smrg text.ptr = SrcNL; 5817a84e134Smrg else 5827a84e134Smrg text.ptr = (char*)SrcWNL; 5837a84e134Smrg text.length = 1; 5847a84e134Smrg 5857a84e134Smrg return (XawTextSourceSearch(w, XawTextSourceScan(w, 0, XawstAll, 5867a84e134Smrg XawsdRight, 1, True) - 1, 5877a84e134Smrg XawsdRight, &text) != XawTextSearchError); 5887a84e134Smrg} 5897a84e134Smrg 5907a84e134Smrgvoid 5917a84e134Smrg_XawSourceAddText(Widget source, Widget text) 5927a84e134Smrg{ 5937a84e134Smrg TextSrcObject src = (TextSrcObject)source; 5947a84e134Smrg Bool found = False; 5957a84e134Smrg Cardinal i; 5967a84e134Smrg 5977a84e134Smrg for (i = 0; i < src->textSrc.num_text; i++) 5987a84e134Smrg if (src->textSrc.text[i] == text) { 5997a84e134Smrg found = True; 6007a84e134Smrg break; 6017a84e134Smrg } 6027a84e134Smrg 6037a84e134Smrg if (!found) { 6047a84e134Smrg src->textSrc.text = (WidgetList) 6057a84e134Smrg XtRealloc((char*)src->textSrc.text, 6067a84e134Smrg sizeof(Widget) * (src->textSrc.num_text + 1)); 6077a84e134Smrg src->textSrc.text[src->textSrc.num_text++] = text; 6087a84e134Smrg } 6097a84e134Smrg} 6107a84e134Smrg 6117a84e134Smrgvoid 6127a84e134Smrg_XawSourceRemoveText(Widget source, Widget text, Bool destroy) 6137a84e134Smrg{ 6147a84e134Smrg TextSrcObject src = (TextSrcObject)source; 6157a84e134Smrg Bool found = False; 6167a84e134Smrg Cardinal i; 6177a84e134Smrg 6187a84e134Smrg if (src == NULL) 6197a84e134Smrg return; 6207a84e134Smrg 6217a84e134Smrg for (i = 0; i < src->textSrc.num_text; i++) 6227a84e134Smrg if (src->textSrc.text[i] == text) { 6237a84e134Smrg found = True; 6247a84e134Smrg break; 6257a84e134Smrg } 6267a84e134Smrg 6277a84e134Smrg if (found) { 6287a84e134Smrg if (--src->textSrc.num_text == 0) { 6297a84e134Smrg if (destroy) { 6307a84e134Smrg XtDestroyWidget(source); 6317a84e134Smrg return; 6327a84e134Smrg } 6337a84e134Smrg else { 6347a84e134Smrg XtFree((char*)src->textSrc.text); 6357a84e134Smrg src->textSrc.text = NULL; /* for realloc "magic" */ 6367a84e134Smrg } 6377a84e134Smrg } 6387a84e134Smrg else if (i < src->textSrc.num_text) 6397a84e134Smrg memmove(&src->textSrc.text[i], &src->textSrc.text[i + 1], 6407a84e134Smrg sizeof(Widget) * (src->textSrc.num_text - i)); 6417a84e134Smrg } 6427a84e134Smrg} 6437a84e134Smrg#endif /* OLDXAW */ 6447a84e134Smrg 6457a84e134Smrg/* 6467a84e134Smrg * Function: 6477a84e134Smrg * XawTextSourceRead 6487a84e134Smrg * 6497a84e134Smrg * Parameters: 6507a84e134Smrg * w - TextSrc Object 6517a84e134Smrg * pos - position of the text to retrieve 6527a84e134Smrg * text - text block that will contain returned text (return) 6537a84e134Smrg * length - maximum number of characters to read 6547a84e134Smrg * 6557a84e134Smrg * Description: 6567a84e134Smrg * This function reads the source. 6577a84e134Smrg * 6587a84e134Smrg * Returns: 6597a84e134Smrg * The number of characters read into the buffer 6607a84e134Smrg */ 6617a84e134SmrgXawTextPosition 6627a84e134SmrgXawTextSourceRead(Widget w, XawTextPosition pos, XawTextBlock *text, 6637a84e134Smrg int length) 6647a84e134Smrg{ 6657a84e134Smrg TextSrcObjectClass cclass = (TextSrcObjectClass)w->core.widget_class; 6667a84e134Smrg 6677a84e134Smrg return ((*cclass->textSrc_class.Read)(w, pos, text, length)); 6687a84e134Smrg} 6697a84e134Smrg 6707a84e134Smrg#ifndef OLDXAW 6717a84e134Smrgstatic void 6727a84e134SmrgTellSourceChanged(TextSrcObject src, XawTextPosition left, 6737a84e134Smrg XawTextPosition right, XawTextBlock *block, int lines) 6747a84e134Smrg{ 6757a84e134Smrg Cardinal i; 6767a84e134Smrg 6777a84e134Smrg for (i = 0; i < src->textSrc.num_text; i++) 6787a84e134Smrg _XawTextSourceChanged(src->textSrc.text[i], left, right, block, lines); 6797a84e134Smrg} 6807a84e134Smrg 6817a84e134Smrg/* 6827a84e134Smrg * This function is required because there is no way to diferentiate 6837a84e134Smrg * if the first erase was generated by a backward-kill-char and the 6847a84e134Smrg * second by a forward-kill-char (or vice-versa) from XawTextSourceReplace. 6857a84e134Smrg * It is only possible to diferentiate after the second character is 6867a84e134Smrg * killed, but then, it is too late. 6877a84e134Smrg */ 6887a84e134Smrgvoid 6897a84e134Smrg_XawSourceSetUndoErase(TextSrcObject src, int value) 6907a84e134Smrg{ 6917a84e134Smrg if (src && src->textSrc.enable_undo) 6927a84e134Smrg src->textSrc.undo->erase = value; 6937a84e134Smrg} 6947a84e134Smrg 6957a84e134Smrg/* 6967a84e134Smrg * To diferentiate insert-char's separeted by cursor movements. 6977a84e134Smrg */ 6987a84e134Smrgvoid 6997a84e134Smrg_XawSourceSetUndoMerge(TextSrcObject src, Bool state) 7007a84e134Smrg{ 7017a84e134Smrg if (src && src->textSrc.enable_undo) 7027a84e134Smrg src->textSrc.undo->merge += state ? 1 : -1; 7037a84e134Smrg} 7047a84e134Smrg#endif /* OLDXAW */ 7057a84e134Smrg 7067a84e134Smrg/* 7077a84e134Smrg * Public Functions 7087a84e134Smrg */ 7097a84e134Smrg/* 7107a84e134Smrg * Function: 7117a84e134Smrg * XawTextSourceReplace 7127a84e134Smrg * 7137a84e134Smrg * Parameters: 7147a84e134Smrg * src - Text Source Object 7157a84e134Smrg * startPos - ends of text that will be removed 7167a84e134Smrg * endPos - "" 7177a84e134Smrg * text - new text to be inserted into buffer at startPos 7187a84e134Smrg * 7197a84e134Smrg * Description: 7207a84e134Smrg * Replaces a block of text with new text. 7217a84e134Smrg * 7227a84e134Smrg * Returns: 7237a84e134Smrg * XawEditError or XawEditDone. 7247a84e134Smrg */ 7257a84e134Smrg/*ARGSUSED*/ 7267a84e134Smrgint 7277a84e134SmrgXawTextSourceReplace(Widget w, XawTextPosition left, 7287a84e134Smrg XawTextPosition right, XawTextBlock *block) 7297a84e134Smrg{ 7307a84e134Smrg TextSrcObjectClass cclass = (TextSrcObjectClass)w->core.widget_class; 7317a84e134Smrg#ifndef OLDXAW 7327a84e134Smrg TextSrcObject src = (TextSrcObject)w; 7337a84e134Smrg XawTextUndoBuffer *l_state, *r_state; 7347a84e134Smrg XawTextUndoList *undo; 7357a84e134Smrg Bool enable_undo; 7367a84e134Smrg XawTextPosition start, end; 7377a84e134Smrg int i, error, lines = 0; 7387a84e134Smrg 7397a84e134Smrg if (src->textSrc.edit_mode == XawtextRead) 7407a84e134Smrg return (XawEditError); 7417a84e134Smrg 7427a84e134Smrg enable_undo = src->textSrc.enable_undo && src->textSrc.undo_state == False; 7437a84e134Smrg if (enable_undo) { 7447a84e134Smrg unsigned size, total; 7457a84e134Smrg 7467a84e134Smrg if (src->textSrc.undo->l_save) { 7477a84e134Smrg l_state = src->textSrc.undo->l_save; 7487a84e134Smrg src->textSrc.undo->l_save = NULL; 7497a84e134Smrg } 7507a84e134Smrg else 7517a84e134Smrg l_state = XtNew(XawTextUndoBuffer); 7527a84e134Smrg l_state->refcount = 1; 7537a84e134Smrg l_state->position = left; 7547a84e134Smrg if (left < right) { 7557a84e134Smrg Widget ctx = NULL; 7567a84e134Smrg 7577a84e134Smrg for (i = 0; i < src->textSrc.num_text; i++) 7587a84e134Smrg if (XtIsSubclass(src->textSrc.text[i], textWidgetClass)) { 7597a84e134Smrg ctx = src->textSrc.text[i]; 7607a84e134Smrg break; 7617a84e134Smrg } 7627a84e134Smrg l_state->buffer = _XawTextGetText((TextWidget)ctx, left, right); 7637a84e134Smrg l_state->length = right - left; 7647a84e134Smrg } 7657a84e134Smrg else { 7667a84e134Smrg l_state->length = 0; 7677a84e134Smrg l_state->buffer = NULL; 7687a84e134Smrg } 7697a84e134Smrg l_state->format = src->textSrc.text_format; 7707a84e134Smrg if (l_state->length == 1) { 7717a84e134Smrg if (l_state->format == XawFmtWide && 7727a84e134Smrg *(wchar_t*)l_state->buffer == *SrcWNL) { 7737a84e134Smrg XtFree(l_state->buffer); 7747a84e134Smrg l_state->buffer = (char*)SrcWNL; 7757a84e134Smrg } 7767a84e134Smrg else if (*l_state->buffer == '\n') { 7777a84e134Smrg XtFree(l_state->buffer); 7787a84e134Smrg l_state->buffer = SrcNL; 7797a84e134Smrg } 7807a84e134Smrg } 7817a84e134Smrg 7827a84e134Smrg if (src->textSrc.undo->r_save) { 7837a84e134Smrg r_state = src->textSrc.undo->r_save; 7847a84e134Smrg src->textSrc.undo->r_save = NULL; 7857a84e134Smrg } 7867a84e134Smrg else 7877a84e134Smrg r_state = XtNew(XawTextUndoBuffer); 7887a84e134Smrg r_state->refcount = 1; 7897a84e134Smrg r_state->position = left; 7907a84e134Smrg r_state->format = block->format; 7917a84e134Smrg size = block->format == XawFmtWide ? sizeof(wchar_t) : sizeof(char); 7927a84e134Smrg total = size * block->length; 7937a84e134Smrg r_state->length = block->length; 7947a84e134Smrg r_state->buffer = NULL; 7957a84e134Smrg if (total == size) { 7967a84e134Smrg if (r_state->format == XawFmtWide && 7977a84e134Smrg *(wchar_t*)block->ptr == *SrcWNL) 7987a84e134Smrg r_state->buffer = (char*)SrcWNL; 7997a84e134Smrg else if (*block->ptr == '\n') 8007a84e134Smrg r_state->buffer = SrcNL; 8017a84e134Smrg } 8027a84e134Smrg if (total && !r_state->buffer) { 8037a84e134Smrg r_state->buffer = XtMalloc(total); 8047a84e134Smrg memcpy(r_state->buffer, block->ptr, total); 8057a84e134Smrg } 8067a84e134Smrg 8077a84e134Smrg if (src->textSrc.undo->u_save) { 8087a84e134Smrg undo = src->textSrc.undo->u_save; 8097a84e134Smrg src->textSrc.undo->u_save = NULL; 8107a84e134Smrg } 8117a84e134Smrg else 8127a84e134Smrg undo = XtNew(XawTextUndoList); 8137a84e134Smrg undo->left = l_state; 8147a84e134Smrg undo->right = r_state; 8157a84e134Smrg undo->undo = src->textSrc.undo->list; 8167a84e134Smrg undo->redo = NULL; 8177a84e134Smrg } 8187a84e134Smrg else { 8197a84e134Smrg undo = NULL; 8207a84e134Smrg l_state = r_state = NULL; 8217a84e134Smrg } 8227a84e134Smrg 8237a84e134Smrg#define LARGE_VALUE 262144 /* 256 K */ 8247a84e134Smrg /* optimization, to avoid long delays recalculating the line number 8257a84e134Smrg * when editing huge files 8267a84e134Smrg */ 8277a84e134Smrg if (left > LARGE_VALUE) { 8287a84e134Smrg start = XawTextSourceScan(w, left, XawstEOL, XawsdLeft, 2, False); 8297a84e134Smrg for (i = 0; i < src->textSrc.num_text; i++) { 8307a84e134Smrg TextWidget tw = (TextWidget)src->textSrc.text[i]; 8317a84e134Smrg 8327a84e134Smrg if (left <= tw->text.lt.top && 8337a84e134Smrg left + block->length - (right - left) > tw->text.lt.top) 8347a84e134Smrg _XawTextBuildLineTable(tw, start, False); 8357a84e134Smrg } 8367a84e134Smrg } 8377a84e134Smrg#undef LARGE_VALUE 8387a84e134Smrg 8397a84e134Smrg start = left; 8407a84e134Smrg end = right; 8417a84e134Smrg while (start < end) { 8427a84e134Smrg start = XawTextSourceScan(w, start, XawstEOL, XawsdRight, 1, True); 8437a84e134Smrg if (start <= end) { 8447a84e134Smrg --lines; 8457a84e134Smrg if (start == XawTextSourceScan(w, 0, XawstAll, XawsdRight, 1, True)) { 8467a84e134Smrg lines += !_XawTextSourceNewLineAtEOF(w); 8477a84e134Smrg break; 8487a84e134Smrg } 8497a84e134Smrg } 8507a84e134Smrg } 8517a84e134Smrg#else 8527a84e134Smrg int error; 8537a84e134Smrg#endif /* OLDXAW */ 8547a84e134Smrg 8557a84e134Smrg error = (*cclass->textSrc_class.Replace)(w, left, right, block); 8567a84e134Smrg 8577a84e134Smrg#ifndef OLDXAW 8587a84e134Smrg if (error != XawEditDone) { 8597a84e134Smrg if (enable_undo) { 8607a84e134Smrg if (l_state->buffer) { 8617a84e134Smrg if (l_state->buffer != SrcNL && l_state->buffer != (char*)SrcWNL) 8627a84e134Smrg XtFree(l_state->buffer); 8637a84e134Smrg l_state->buffer = NULL; 8647a84e134Smrg } 8657a84e134Smrg src->textSrc.undo->l_save = l_state; 8667a84e134Smrg if (r_state->buffer) { 8677a84e134Smrg if (r_state->buffer != SrcNL && r_state->buffer != (char*)SrcWNL) 8687a84e134Smrg XtFree(r_state->buffer); 8697a84e134Smrg r_state->buffer = NULL; 8707a84e134Smrg } 8717a84e134Smrg src->textSrc.undo->r_save = r_state; 8727a84e134Smrg 8737a84e134Smrg src->textSrc.undo->u_save = undo; 8747a84e134Smrg } 8757a84e134Smrg } 8767a84e134Smrg else if (enable_undo) { 8777a84e134Smrg XawTextUndoList *list = src->textSrc.undo->list; 8787a84e134Smrg XawTextUndoBuffer *unl, *lnl; 8797a84e134Smrg int erase = undo->right->length == 0 && undo->left->length == 1 && list 8807a84e134Smrg && list->right->length == 0; 8817a84e134Smrg 8827a84e134Smrg if (erase) { 8837a84e134Smrg erase = list->left->position - 1 == undo->left->position ? -1 : 8847a84e134Smrg list->left->position == undo->left->position ? 1 : 0; 8857a84e134Smrg if (src->textSrc.undo->erase && erase != src->textSrc.undo->erase) 8867a84e134Smrg erase = 0; 8877a84e134Smrg else 8887a84e134Smrg src->textSrc.undo->erase = erase; 8897a84e134Smrg } 8907a84e134Smrg 8917a84e134Smrg if (erase) { 8927a84e134Smrg unl = l_state; 8937a84e134Smrg lnl = list->left; 8947a84e134Smrg } 8957a84e134Smrg else { 8967a84e134Smrg unl = r_state; 8977a84e134Smrg lnl = list ? list->right : NULL; 8987a84e134Smrg } 8997a84e134Smrg 9007a84e134Smrg /* Try to merge the undo buffers */ 9017a84e134Smrg if (src->textSrc.undo->merge > 0 && ((erase || 9027a84e134Smrg (list && ((list->left->length == 0 && undo->left->length == 0) || 9037a84e134Smrg (list->left->length == list->right->length && 9047a84e134Smrg undo->left->length == 1)) && 9057a84e134Smrg undo->right->length == 1 && 9067a84e134Smrg list->right->position + list->right->length 9077a84e134Smrg == undo->right->position)) 9087a84e134Smrg && src->textSrc.undo->pointer == list 9097a84e134Smrg && unl->format == list->right->format 9107a84e134Smrg && ((unl->format == XawFmt8Bit && unl->buffer[0] != XawLF) || 9117a84e134Smrg (unl->format == XawFmtWide && 9127a84e134Smrg *(wchar_t*)(unl->buffer) != _Xaw_atowc(XawLF))) 9137a84e134Smrg && ((lnl->format == XawFmt8Bit && lnl->buffer[0] != XawLF) || 9147a84e134Smrg (lnl->format == XawFmtWide && 9157a84e134Smrg *(wchar_t*)(lnl->buffer) != _Xaw_atowc(XawLF))))) { 9167a84e134Smrg unsigned size = lnl->format == XawFmtWide ? 9177a84e134Smrg sizeof(wchar_t) : sizeof(char); 9187a84e134Smrg 9197a84e134Smrg if (!erase) { 9207a84e134Smrg list->right->buffer = XtRealloc(list->right->buffer, 9217a84e134Smrg (list->right->length + 1) * size); 9227a84e134Smrg memcpy(list->right->buffer + list->right->length * size, 9237a84e134Smrg undo->right->buffer, size); 9247a84e134Smrg ++list->right->length; 9257a84e134Smrg XtFree(r_state->buffer); 9267a84e134Smrg } 9277a84e134Smrg else if (erase < 0) { 9287a84e134Smrg --list->left->position; 9297a84e134Smrg --list->right->position; 9307a84e134Smrg } 9317a84e134Smrg 9327a84e134Smrg src->textSrc.undo->l_save = l_state; 9337a84e134Smrg src->textSrc.undo->r_save = r_state; 9347a84e134Smrg src->textSrc.undo->u_save = undo; 9357a84e134Smrg 9367a84e134Smrg if (list->left->length) { 9377a84e134Smrg list->left->buffer = XtRealloc(list->left->buffer, 9387a84e134Smrg (list->left->length + 1) * size); 9397a84e134Smrg if (erase >= 0) 9407a84e134Smrg memcpy(list->left->buffer + list->left->length * size, 9417a84e134Smrg undo->left->buffer, size); 9427a84e134Smrg else { 9437a84e134Smrg /* use memmove, since strings overlap */ 9447a84e134Smrg memmove(list->left->buffer + size, list->left->buffer, 9457a84e134Smrg list->left->length * size); 9467a84e134Smrg memcpy(list->left->buffer, undo->left->buffer, size); 9477a84e134Smrg } 9487a84e134Smrg ++list->left->length; 9497a84e134Smrg if (l_state->buffer != SrcNL && l_state->buffer != (char*)SrcWNL) 9507a84e134Smrg XtFree(l_state->buffer); 9517a84e134Smrg } 9527a84e134Smrg 9537a84e134Smrg if (src->textSrc.undo->num_list >= UNDO_DEPTH) 9547a84e134Smrg UndoGC(src->textSrc.undo); 9557a84e134Smrg } 9567a84e134Smrg else { 9577a84e134Smrg src->textSrc.undo->undo = (XawTextUndoBuffer**) 9587a84e134Smrg XtRealloc((char*)src->textSrc.undo->undo, 9597a84e134Smrg (2 + src->textSrc.undo->num_undo) 9607a84e134Smrg * sizeof(XawTextUndoBuffer)); 9617a84e134Smrg src->textSrc.undo->undo[src->textSrc.undo->num_undo++] = l_state; 9627a84e134Smrg src->textSrc.undo->undo[src->textSrc.undo->num_undo++] = r_state; 9637a84e134Smrg 9647a84e134Smrg if (src->textSrc.undo->list) 9657a84e134Smrg src->textSrc.undo->list->redo = undo; 9667a84e134Smrg else 9677a84e134Smrg src->textSrc.undo->head = undo; 9687a84e134Smrg 9697a84e134Smrg src->textSrc.undo->merge = l_state->length <= 1 && 9707a84e134Smrg r_state->length <= 1; 9717a84e134Smrg 9727a84e134Smrg src->textSrc.undo->list = src->textSrc.undo->pointer = 9737a84e134Smrg src->textSrc.undo->end_mark = undo; 9747a84e134Smrg 9757a84e134Smrg if (++src->textSrc.undo->num_list >= UNDO_DEPTH) 9767a84e134Smrg UndoGC(src->textSrc.undo); 9777a84e134Smrg } 9787a84e134Smrg src->textSrc.undo->dir = XawsdLeft; 9797a84e134Smrg if (!src->textSrc.changed) { 9807a84e134Smrg src->textSrc.undo->l_no_change = src->textSrc.undo->list->right; 9817a84e134Smrg src->textSrc.undo->r_no_change = src->textSrc.undo->list->left; 9827a84e134Smrg src->textSrc.changed = True; 9837a84e134Smrg } 9847a84e134Smrg } 9857a84e134Smrg else if (!src->textSrc.enable_undo) 9867a84e134Smrg src->textSrc.changed = True; 9877a84e134Smrg 9887a84e134Smrg if (error == XawEditDone) { 9897a84e134Smrg XawTextPropertyInfo info; 9907a84e134Smrg XawTextAnchor *anchor; 9917a84e134Smrg 9927a84e134Smrg /* find anchor and index */ 9937a84e134Smrg /* XXX index (i) could be returned by XawTextSourceFindAnchor 9947a84e134Smrg * or similar function, to speed up */ 9957a84e134Smrg if ((anchor = XawTextSourceFindAnchor(w, left))) { 9967a84e134Smrg XawTextEntity *eprev, *entity, *enext; 9977a84e134Smrg XawTextPosition offset = 0, diff = block->length - (right - left); 9987a84e134Smrg 9997a84e134Smrg for (i = 0; i < src->textSrc.num_anchors; i++) 10007a84e134Smrg if (src->textSrc.anchors[i] == anchor) 10017a84e134Smrg break; 10027a84e134Smrg if (anchor->cache && anchor->position + anchor->cache->offset + 10037a84e134Smrg anchor->cache->length <= left) 10047a84e134Smrg eprev = entity = anchor->cache; 10057a84e134Smrg else 10067a84e134Smrg eprev = entity = anchor->entities; 10077a84e134Smrg while (entity) { 10087a84e134Smrg offset = anchor->position + entity->offset; 10097a84e134Smrg 10107a84e134Smrg if (offset > left) 10117a84e134Smrg break; 10127a84e134Smrg if (offset + entity->length > left) 10137a84e134Smrg break; 10147a84e134Smrg 10157a84e134Smrg eprev = entity; 10167a84e134Smrg entity = entity->next; 10177a84e134Smrg } 10187a84e134Smrg 10197a84e134Smrg /* try to do the right thing here (and most likely correct), but 10207a84e134Smrg * other code needs to check what was done */ 10217a84e134Smrg 10227a84e134Smrg /* adjust entity length */ 10237a84e134Smrg if (entity && offset <= left) { 10247a84e134Smrg if (offset + entity->length < right) 10257a84e134Smrg entity->length = left - offset + block->length; 10267a84e134Smrg else 10277a84e134Smrg entity->length += diff; 10287a84e134Smrg 10297a84e134Smrg if (entity->length == 0) { 10307a84e134Smrg enext = entity->next; 10317a84e134Smrg eprev->next = enext; 10327a84e134Smrg anchor->cache = NULL; 10337a84e134Smrg XtFree((XtPointer)entity); 10347a84e134Smrg if (entity == anchor->entities) { 10357a84e134Smrg if ((anchor->entities = enext) == NULL) { 10367a84e134Smrg eprev = NULL; 10377a84e134Smrg anchor = XawTextSourceRemoveAnchor(w, anchor); 10387a84e134Smrg entity = anchor ? anchor->entities : NULL; 10397a84e134Smrg } 10407a84e134Smrg else 10417a84e134Smrg eprev = entity = enext; 10427a84e134Smrg } 10437a84e134Smrg else 10447a84e134Smrg entity = enext; 10457a84e134Smrg } 10467a84e134Smrg else { 10477a84e134Smrg eprev = entity; 10487a84e134Smrg entity = entity->next; 10497a84e134Smrg } 10507a84e134Smrg } 10517a84e134Smrg 10527a84e134Smrg while (anchor) { 10537a84e134Smrg while (entity) { 10547a84e134Smrg offset = anchor->position + entity->offset + entity->length; 10557a84e134Smrg 10567a84e134Smrg if (offset > right) { 10577a84e134Smrg entity->length = XawMin(entity->length, offset - right); 10587a84e134Smrg goto exit_anchor_loop; 10597a84e134Smrg } 10607a84e134Smrg 10617a84e134Smrg enext = entity->next; 10627a84e134Smrg if (eprev) 10637a84e134Smrg eprev->next = enext; 10647a84e134Smrg XtFree((XtPointer)entity); 10657a84e134Smrg anchor->cache = NULL; 10667a84e134Smrg if (entity == anchor->entities) { 10677a84e134Smrg eprev = NULL; 10687a84e134Smrg if ((anchor->entities = enext) == NULL) { 10697a84e134Smrg if (i == 0) 10707a84e134Smrg ++i; 10717a84e134Smrg else if (i < --src->textSrc.num_anchors) { 10727a84e134Smrg memmove(&src->textSrc.anchors[i], 10737a84e134Smrg &src->textSrc.anchors[i + 1], 10747a84e134Smrg (src->textSrc.num_anchors - i) * 10757a84e134Smrg sizeof(XawTextAnchor*)); 10767a84e134Smrg XtFree((XtPointer)anchor); 10777a84e134Smrg } 10787a84e134Smrg if (i >= src->textSrc.num_anchors) { 10797a84e134Smrg anchor = NULL; 10807a84e134Smrg entity = NULL; 10817a84e134Smrg break; 10827a84e134Smrg } 10837a84e134Smrg anchor = src->textSrc.anchors[i]; 10847a84e134Smrg entity = anchor->entities; 10857a84e134Smrg continue; 10867a84e134Smrg } 10877a84e134Smrg } 10887a84e134Smrg entity = enext; 10897a84e134Smrg } 10907a84e134Smrg if (i + 1 < src->textSrc.num_anchors) { 10917a84e134Smrg anchor = src->textSrc.anchors[++i]; 10927a84e134Smrg entity = anchor->entities; 10937a84e134Smrg eprev = NULL; 10947a84e134Smrg } 10957a84e134Smrg else 10967a84e134Smrg break; 10977a84e134Smrg eprev = NULL; 10987a84e134Smrg } 10997a84e134Smrg 11007a84e134Smrgexit_anchor_loop: 11017a84e134Smrg if (anchor) { 11027a84e134Smrg XawTextAnchor *aprev; 11037a84e134Smrg 11047a84e134Smrg if (anchor->position >= XawMax(right, left + block->length)) 11057a84e134Smrg anchor->position += diff; 11067a84e134Smrg else if (anchor->position > left && 11077a84e134Smrg (aprev = XawTextSourcePrevAnchor(w, anchor))) { 11087a84e134Smrg XawTextPosition tmp = anchor->position - aprev->position; 11097a84e134Smrg 11107a84e134Smrg if (diff) { 11117a84e134Smrg while (entity) { 11127a84e134Smrg entity->offset += diff; 11137a84e134Smrg entity = entity->next; 11147a84e134Smrg } 11157a84e134Smrg } 11167a84e134Smrg entity = anchor->entities; 11177a84e134Smrg while (entity) { 11187a84e134Smrg entity->offset += tmp; 11197a84e134Smrg entity = entity->next; 11207a84e134Smrg } 11217a84e134Smrg if ((entity = aprev->entities) == NULL) 11227a84e134Smrg aprev->entities = anchor->entities; 11237a84e134Smrg else { 11247a84e134Smrg while (entity->next) 11257a84e134Smrg entity = entity->next; 11267a84e134Smrg entity->next = anchor->entities; 11277a84e134Smrg } 11287a84e134Smrg anchor->entities = NULL; 11297a84e134Smrg (void)XawTextSourceRemoveAnchor(w, anchor); 11307a84e134Smrg --i; 11317a84e134Smrg } 11327a84e134Smrg else if (diff) { 11337a84e134Smrg while (entity) { 11347a84e134Smrg entity->offset += diff; 11357a84e134Smrg entity = entity->next; 11367a84e134Smrg } 11377a84e134Smrg } 11387a84e134Smrg } 11397a84e134Smrg 11407a84e134Smrg if (diff) { 11417a84e134Smrg for (++i; i < src->textSrc.num_anchors; i++) 11427a84e134Smrg src->textSrc.anchors[i]->position += diff; 11437a84e134Smrg } 11447a84e134Smrg } 11457a84e134Smrg 11467a84e134Smrg start = left; 11477a84e134Smrg end = start + block->length; 11487a84e134Smrg while (start < end) { 11497a84e134Smrg start = XawTextSourceScan(w, start, XawstEOL, XawsdRight, 1, True); 11507a84e134Smrg if (start <= end) { 11517a84e134Smrg ++lines; 11527a84e134Smrg if (start == XawTextSourceScan(w, 0, XawstAll, XawsdRight, 1, True)) { 11537a84e134Smrg lines -= !_XawTextSourceNewLineAtEOF(w); 11547a84e134Smrg break; 11557a84e134Smrg } 11567a84e134Smrg } 11577a84e134Smrg } 11587a84e134Smrg 11597a84e134Smrg info.left = left; 11607a84e134Smrg info.right = right; 11617a84e134Smrg info.block = block; 11627a84e134Smrg XtCallCallbacks(w, XtNpropertyCallback, &info); 11637a84e134Smrg 11647a84e134Smrg TellSourceChanged(src, left, right, block, lines); 11657a84e134Smrg /* Call callbacks, we have changed the buffer */ 11667a84e134Smrg XtCallCallbacks(w, XtNcallback, 11677a84e134Smrg (XtPointer)((long)src->textSrc.changed)); 11687a84e134Smrg } 11697a84e134Smrg 11707a84e134Smrg#endif /* OLDXAW */ 11717a84e134Smrg return (error); 11727a84e134Smrg} 11737a84e134Smrg 11747a84e134Smrg#ifndef OLDXAW 11757a84e134SmrgBool 11767a84e134Smrg_XawTextSrcUndo(TextSrcObject src, XawTextPosition *insert_pos) 11777a84e134Smrg{ 11787a84e134Smrg static wchar_t wnull = 0; 11797a84e134Smrg XawTextBlock block; 11807a84e134Smrg XawTextUndoList *list, *nlist; 11817a84e134Smrg XawTextUndoBuffer *l_state, *r_state; 11827a84e134Smrg Boolean changed = src->textSrc.changed; 11837a84e134Smrg 11847a84e134Smrg if (!src->textSrc.enable_undo || !src->textSrc.undo->num_undo) 11857a84e134Smrg return (False); 11867a84e134Smrg 11877a84e134Smrg list = src->textSrc.undo->pointer; 11887a84e134Smrg 11897a84e134Smrg if (src->textSrc.undo->dir == XawsdLeft) { 11907a84e134Smrg l_state = list->right; 11917a84e134Smrg r_state = list->left; 11927a84e134Smrg } 11937a84e134Smrg else { 11947a84e134Smrg l_state = list->left; 11957a84e134Smrg r_state = list->right; 11967a84e134Smrg } 11977a84e134Smrg 11987a84e134Smrg if (src->textSrc.undo->l_no_change == l_state 11997a84e134Smrg && src->textSrc.undo->r_no_change == r_state) 12007a84e134Smrg src->textSrc.changed = False; 12017a84e134Smrg else 12027a84e134Smrg src->textSrc.changed = True; 12037a84e134Smrg 12047a84e134Smrg block.firstPos = 0; 12057a84e134Smrg block.length = r_state->length; 12067a84e134Smrg block.ptr = r_state->buffer ? r_state->buffer : (char*)&wnull; 12077a84e134Smrg block.format = r_state->format; 12087a84e134Smrg 12097a84e134Smrg src->textSrc.undo_state = True; 12107a84e134Smrg if (XawTextSourceReplace((Widget)src, l_state->position, l_state->position 12117a84e134Smrg + l_state->length, &block) != XawEditDone) { 12127a84e134Smrg src->textSrc.undo_state = False; 12137a84e134Smrg src->textSrc.changed = changed; 12147a84e134Smrg return (False); 12157a84e134Smrg } 12167a84e134Smrg src->textSrc.undo_state = False; 12177a84e134Smrg 12187a84e134Smrg ++l_state->refcount; 12197a84e134Smrg ++r_state->refcount; 12207a84e134Smrg nlist = XtNew(XawTextUndoList); 12217a84e134Smrg nlist->left = l_state; 12227a84e134Smrg nlist->right = r_state; 12237a84e134Smrg nlist->undo = src->textSrc.undo->list; 12247a84e134Smrg nlist->redo = NULL; 12257a84e134Smrg 12267a84e134Smrg if (list == src->textSrc.undo->list) 12277a84e134Smrg src->textSrc.undo->end_mark = nlist; 12287a84e134Smrg 12297a84e134Smrg if (src->textSrc.undo->dir == XawsdLeft) { 12307a84e134Smrg if (list->undo == NULL) 12317a84e134Smrg src->textSrc.undo->dir = XawsdRight; 12327a84e134Smrg else 12337a84e134Smrg list = list->undo; 12347a84e134Smrg } 12357a84e134Smrg else { 12367a84e134Smrg if (list->redo == NULL || list->redo == src->textSrc.undo->end_mark) 12377a84e134Smrg src->textSrc.undo->dir = XawsdLeft; 12387a84e134Smrg else 12397a84e134Smrg list = list->redo; 12407a84e134Smrg } 12417a84e134Smrg *insert_pos = r_state->position + r_state->length; 12427a84e134Smrg src->textSrc.undo->pointer = list; 12437a84e134Smrg src->textSrc.undo->list->redo = nlist; 12447a84e134Smrg src->textSrc.undo->list = nlist; 12457a84e134Smrg src->textSrc.undo->merge = src->textSrc.undo->erase = 0; 12467a84e134Smrg 12477a84e134Smrg if (++src->textSrc.undo->num_list >= UNDO_DEPTH) 12487a84e134Smrg UndoGC(src->textSrc.undo); 12497a84e134Smrg 12507a84e134Smrg return (True); 12517a84e134Smrg} 12527a84e134Smrg 12537a84e134SmrgBool 12547a84e134Smrg_XawTextSrcToggleUndo(TextSrcObject src) 12557a84e134Smrg{ 12567a84e134Smrg if (!src->textSrc.enable_undo || !src->textSrc.undo->num_undo) 12577a84e134Smrg return (False); 12587a84e134Smrg 12597a84e134Smrg if (src->textSrc.undo->pointer != src->textSrc.undo->list) { 12607a84e134Smrg if (src->textSrc.undo->dir == XawsdLeft) { 12617a84e134Smrg if (src->textSrc.undo->pointer->redo 12627a84e134Smrg && (src->textSrc.undo->pointer->redo 12637a84e134Smrg != src->textSrc.undo->end_mark)) { 12647a84e134Smrg src->textSrc.undo->pointer = src->textSrc.undo->pointer->redo; 12657a84e134Smrg src->textSrc.undo->dir = XawsdRight; 12667a84e134Smrg } 12677a84e134Smrg } 12687a84e134Smrg else { 12697a84e134Smrg if (src->textSrc.undo->pointer->undo 12707a84e134Smrg && (src->textSrc.undo->pointer != src->textSrc.undo->head)) { 12717a84e134Smrg src->textSrc.undo->pointer = src->textSrc.undo->pointer->undo; 12727a84e134Smrg src->textSrc.undo->dir = XawsdLeft; 12737a84e134Smrg } 12747a84e134Smrg } 12757a84e134Smrg } 12767a84e134Smrg 12777a84e134Smrg return (True); 12787a84e134Smrg} 12797a84e134Smrg 12807a84e134Smrgstatic void 12817a84e134SmrgFreeUndoBuffer(XawTextUndo *undo) 12827a84e134Smrg{ 12837a84e134Smrg unsigned i; 12847a84e134Smrg XawTextUndoList *head, *del; 12857a84e134Smrg 12867a84e134Smrg for (i = 0; i < undo->num_undo; i++) { 12877a84e134Smrg if (undo->undo[i]->buffer && undo->undo[i]->buffer != SrcNL && 12887a84e134Smrg undo->undo[i]->buffer != (char*)SrcWNL) 12897a84e134Smrg XtFree(undo->undo[i]->buffer); 12907a84e134Smrg XtFree((char*)undo->undo[i]); 12917a84e134Smrg } 12927a84e134Smrg XtFree((char*)undo->undo); 12937a84e134Smrg head = undo->head; 12947a84e134Smrg 12957a84e134Smrg del = head; 12967a84e134Smrg while (head) { 12977a84e134Smrg head = head->redo; 12987a84e134Smrg XtFree((char*)del); 12997a84e134Smrg del = head; 13007a84e134Smrg } 13017a84e134Smrg 13027a84e134Smrg if (undo->l_save) { 13037a84e134Smrg XtFree((char*)undo->l_save); 13047a84e134Smrg undo->l_save = NULL; 13057a84e134Smrg } 13067a84e134Smrg if (undo->r_save) { 13077a84e134Smrg XtFree((char*)undo->r_save); 13087a84e134Smrg undo->r_save = NULL; 13097a84e134Smrg } 13107a84e134Smrg if (undo->u_save) { 13117a84e134Smrg XtFree((char*)undo->u_save); 13127a84e134Smrg undo->u_save = NULL; 13137a84e134Smrg } 13147a84e134Smrg 13157a84e134Smrg undo->list = undo->pointer = undo->head = undo->end_mark = NULL; 13167a84e134Smrg undo->l_no_change = undo->r_no_change = NULL; 13177a84e134Smrg undo->undo = NULL; 13187a84e134Smrg undo->dir = XawsdLeft; 13197a84e134Smrg undo->num_undo = undo->num_list = undo->erase = undo->merge = 0; 13207a84e134Smrg} 13217a84e134Smrg 13227a84e134Smrgstatic void 13237a84e134SmrgUndoGC(XawTextUndo *undo) 13247a84e134Smrg{ 13257a84e134Smrg unsigned i; 13267a84e134Smrg XawTextUndoList *head = undo->head, *redo = head->redo; 13277a84e134Smrg 13287a84e134Smrg if (head == undo->pointer || head == undo->end_mark 13297a84e134Smrg || undo->l_no_change == NULL 13307a84e134Smrg || head->left == undo->l_no_change || head->right == undo->l_no_change) 13317a84e134Smrg return; 13327a84e134Smrg 13337a84e134Smrg undo->head = redo; 13347a84e134Smrg redo->undo = NULL; 13357a84e134Smrg 13367a84e134Smrg --head->left->refcount; 13377a84e134Smrg if (--head->right->refcount == 0) { 13387a84e134Smrg for (i = 0; i < undo->num_undo; i+= 2) 13397a84e134Smrg if (head->left == undo->undo[i] || head->left == undo->undo[i+1]) { 13407a84e134Smrg if (head->left == undo->undo[i+1]) { 13417a84e134Smrg XawTextUndoBuffer *tmp = redo->left; 13427a84e134Smrg 13437a84e134Smrg redo->left = redo->right; 13447a84e134Smrg redo->right = tmp; 13457a84e134Smrg } 13467a84e134Smrg if (head->left->buffer && head->left->buffer != SrcNL && 13477a84e134Smrg head->left->buffer != (char*)SrcWNL) 13487a84e134Smrg XtFree(head->left->buffer); 13497a84e134Smrg XtFree((char*)head->left); 13507a84e134Smrg if (head->right->buffer && head->right->buffer != SrcNL && 13517a84e134Smrg head->right->buffer != (char*)SrcWNL) 13527a84e134Smrg XtFree(head->right->buffer); 13537a84e134Smrg XtFree((char*)head->right); 13547a84e134Smrg 13557a84e134Smrg undo->num_undo -= 2; 13567a84e134Smrg memmove(&undo->undo[i], &undo->undo[i + 2], 13577a84e134Smrg (undo->num_undo - i) * sizeof(XawTextUndoBuffer*)); 13587a84e134Smrg break; 13597a84e134Smrg } 13607a84e134Smrg } 13617a84e134Smrg XtFree((char*)head); 13627a84e134Smrg --undo->num_list; 13637a84e134Smrg} 13647a84e134Smrg#endif /* OLDXAW */ 13657a84e134Smrg 13667a84e134Smrg/* 13677a84e134Smrg * Function: 13687a84e134Smrg * XawTextSourceScan 13697a84e134Smrg * 13707a84e134Smrg * Parameters: 13717a84e134Smrg * w - TextSrc Object 13727a84e134Smrg * position - position to start scanning 13737a84e134Smrg * type - type of thing to scan for 13747a84e134Smrg * dir - direction to scan 13757a84e134Smrg * count - which occurance if this thing to search for 13767a84e134Smrg * include - whether or not to include the character found in 13777a84e134Smrg * the position that is returned. 13787a84e134Smrg * 13797a84e134Smrg * Description: 13807a84e134Smrg * Scans the text source for the number and type of item specified. 13817a84e134Smrg * 13827a84e134Smrg * Returns: 13837a84e134Smrg * The position of the text 13847a84e134Smrg */ 13857a84e134SmrgXawTextPosition 13867a84e134SmrgXawTextSourceScan(Widget w, XawTextPosition position, 13877a84e134Smrg#if NeedWidePrototypes 13887a84e134Smrg int type, int dir, int count, int include 13897a84e134Smrg#else 13907a84e134Smrg XawTextScanType type, XawTextScanDirection dir, 13917a84e134Smrg int count, Boolean include 13927a84e134Smrg#endif 13937a84e134Smrg) 13947a84e134Smrg{ 13957a84e134Smrg TextSrcObjectClass cclass = (TextSrcObjectClass)w->core.widget_class; 13967a84e134Smrg 13977a84e134Smrg return ((*cclass->textSrc_class.Scan) 13987a84e134Smrg (w, position, type, dir, count, include)); 13997a84e134Smrg} 14007a84e134Smrg 14017a84e134Smrg/* 14027a84e134Smrg * Function: 14037a84e134Smrg * XawTextSourceSearch 14047a84e134Smrg * 14057a84e134Smrg * Parameters: 14067a84e134Smrg * w - TextSource Object 14077a84e134Smrg * position - position to start scanning 14087a84e134Smrg * dir - direction to scan 14097a84e134Smrg * text - the text block to search for. 14107a84e134Smrg * 14117a84e134Smrg * Returns: 14127a84e134Smrg * The position of the text we are searching for or XawTextSearchError. 14137a84e134Smrg * 14147a84e134Smrg * Description: 14157a84e134Smrg * Searchs the text source for the text block passed 14167a84e134Smrg */ 14177a84e134SmrgXawTextPosition 14187a84e134SmrgXawTextSourceSearch(Widget w, XawTextPosition position, 14197a84e134Smrg#if NeedWidePrototypes 14207a84e134Smrg int dir, 14217a84e134Smrg#else 14227a84e134Smrg XawTextScanDirection dir, 14237a84e134Smrg#endif 14247a84e134Smrg XawTextBlock *text) 14257a84e134Smrg{ 14267a84e134Smrg TextSrcObjectClass cclass = (TextSrcObjectClass)w->core.widget_class; 14277a84e134Smrg 14287a84e134Smrg return ((*cclass->textSrc_class.Search)(w, position, dir, text)); 14297a84e134Smrg} 14307a84e134Smrg 14317a84e134Smrg/* 14327a84e134Smrg * Function: 14337a84e134Smrg * XawTextSourceConvertSelection 14347a84e134Smrg * 14357a84e134Smrg * Parameters: 14367a84e134Smrg * w - TextSrc object 14377a84e134Smrg * selection - current selection atom 14387a84e134Smrg * target - current target atom 14397a84e134Smrg * type - type to conver the selection to 14407a84e134Smrg * value - return value that has been converted 14417a84e134Smrg * length - "" 14427a84e134Smrg * format - format of the returned value 14437a84e134Smrg * 14447a84e134Smrg * Returns: 14457a84e134Smrg * True if the selection has been converted 14467a84e134Smrg */ 14477a84e134SmrgBoolean 14487a84e134SmrgXawTextSourceConvertSelection(Widget w, Atom *selection, Atom *target, 14497a84e134Smrg Atom *type, XtPointer *value, 14507a84e134Smrg unsigned long *length, int *format) 14517a84e134Smrg{ 14527a84e134Smrg TextSrcObjectClass cclass = (TextSrcObjectClass)w->core.widget_class; 14537a84e134Smrg 14547a84e134Smrg return((*cclass->textSrc_class.ConvertSelection) 14557a84e134Smrg (w, selection, target, type, value, length, format)); 14567a84e134Smrg} 14577a84e134Smrg 14587a84e134Smrg/* 14597a84e134Smrg * Function: 14607a84e134Smrg * XawTextSourceSetSelection 14617a84e134Smrg * 14627a84e134Smrg * Parameters: 14637a84e134Smrg * w - TextSrc object 14647a84e134Smrg * left - bounds of the selection 14657a84e134Smrg * rigth - "" 14667a84e134Smrg * selection - selection atom 14677a84e134Smrg * 14687a84e134Smrg * Description: 14697a84e134Smrg * Allows special setting of the selection. 14707a84e134Smrg */ 14717a84e134Smrgvoid 14727a84e134SmrgXawTextSourceSetSelection(Widget w, XawTextPosition left, 14737a84e134Smrg XawTextPosition right, Atom selection) 14747a84e134Smrg{ 14757a84e134Smrg TextSrcObjectClass cclass = (TextSrcObjectClass)w->core.widget_class; 14767a84e134Smrg 14777a84e134Smrg (*cclass->textSrc_class.SetSelection)(w, left, right, selection); 14787a84e134Smrg} 14797a84e134Smrg 14807a84e134Smrg/* 14817a84e134Smrg * External Functions for Multi Text 14827a84e134Smrg */ 14837a84e134Smrg/* 14847a84e134Smrg * TextFormat(): 14857a84e134Smrg * returns the format of text: FMT8BIT or FMTWIDE 14867a84e134Smrg */ 14877a84e134SmrgXrmQuark 14887a84e134Smrg_XawTextFormat(TextWidget tw) 14897a84e134Smrg{ 14907a84e134Smrg return (((TextSrcObject)(tw->text.source))->textSrc.text_format); 14917a84e134Smrg} 14927a84e134Smrg 14937a84e134Smrg/* _XawTextWCToMB(): 14947a84e134Smrg * Convert the wchar string to external encoding 14957a84e134Smrg * The caller is responsible for freeing both the source and ret string 14967a84e134Smrg * 14977a84e134Smrg * wstr - source wchar string 14987a84e134Smrg * len_in_out - lengh of string. 14997a84e134Smrg * As In, length of source wchar string, measured in wchar 15007a84e134Smrg * As Out, length of returned string 15017a84e134Smrg */ 15027a84e134Smrgchar * 15037a84e134Smrg_XawTextWCToMB(Display *d, wchar_t *wstr, int *len_in_out) 15047a84e134Smrg{ 15057a84e134Smrg XTextProperty textprop; 15067a84e134Smrg 15077a84e134Smrg if (XwcTextListToTextProperty(d, (wchar_t**)&wstr, 1, 15087a84e134Smrg XTextStyle, &textprop) < Success) { 15097a84e134Smrg XtWarningMsg("convertError", "textSource", "XawError", 15107a84e134Smrg "Non-character code(s) in buffer.", NULL, NULL); 15117a84e134Smrg *len_in_out = 0; 15127a84e134Smrg return (NULL); 15137a84e134Smrg } 15147a84e134Smrg *len_in_out = textprop.nitems; 15157a84e134Smrg 15167a84e134Smrg return ((char *)textprop.value); 15177a84e134Smrg} 15187a84e134Smrg 15197a84e134Smrg/* _XawTextMBToWC(): 15207a84e134Smrg * Convert the string to internal processing codeset WC. 15217a84e134Smrg * The caller is responsible for freeing both the source and ret string. 15227a84e134Smrg * 15237a84e134Smrg * str - source string 15247a84e134Smrg * len_in_out - lengh of string 15257a84e134Smrg * As In, it is length of source string 15267a84e134Smrg * As Out, it is length of returned string, measured in wchar 15277a84e134Smrg */ 15287a84e134Smrgwchar_t * 15297a84e134Smrg_XawTextMBToWC(Display *d, char *str, int *len_in_out) 15307a84e134Smrg{ 15317a84e134Smrg XTextProperty textprop; 15327a84e134Smrg char *buf; 15337a84e134Smrg wchar_t **wlist, *wstr; 15347a84e134Smrg int count; 15357a84e134Smrg 15367a84e134Smrg if (*len_in_out == 0) 15377a84e134Smrg return (NULL); 15387a84e134Smrg 15397a84e134Smrg buf = XtMalloc(*len_in_out + 1); 15407a84e134Smrg 15417a84e134Smrg strncpy(buf, str, *len_in_out); 15427a84e134Smrg *(buf + *len_in_out) = '\0'; 15437a84e134Smrg if (XmbTextListToTextProperty(d, &buf, 1, XTextStyle, &textprop) != Success) { 15447a84e134Smrg XtWarningMsg("convertError", "textSource", "XawError", 15457a84e134Smrg "No Memory, or Locale not supported.", NULL, NULL); 15467a84e134Smrg XtFree(buf); 15477a84e134Smrg *len_in_out = 0; 15487a84e134Smrg return (NULL); 15497a84e134Smrg } 15507a84e134Smrg 15517a84e134Smrg XtFree(buf); 15527a84e134Smrg if (XwcTextPropertyToTextList(d, &textprop, 15537a84e134Smrg (wchar_t***)&wlist, &count) != Success) { 15547a84e134Smrg XtWarningMsg("convertError", "multiSourceCreate", "XawError", 15557a84e134Smrg "Non-character code(s) in source.", NULL, NULL); 15567a84e134Smrg *len_in_out = 0; 15577a84e134Smrg return (NULL); 15587a84e134Smrg } 15597a84e134Smrg wstr = wlist[0]; 15607a84e134Smrg *len_in_out = wcslen(wstr); 15617a84e134Smrg XtFree((XtPointer)wlist); 15627a84e134Smrg 15637a84e134Smrg return (wstr); 15647a84e134Smrg} 15657a84e134Smrg 15667a84e134Smrg#ifndef OLDXAW 15677a84e134Smrgstatic int 15687a84e134Smrgqcmp_anchors(_Xconst void *left, _Xconst void *right) 15697a84e134Smrg{ 15707a84e134Smrg return ((*(XawTextAnchor**)left)->position - 15717a84e134Smrg (*(XawTextAnchor**)right)->position); 15727a84e134Smrg} 15737a84e134Smrg 15747a84e134SmrgXawTextAnchor * 15757a84e134SmrgXawTextSourceAddAnchor(Widget w, XawTextPosition position) 15767a84e134Smrg{ 15777a84e134Smrg TextSrcObject src = (TextSrcObject)w; 15787a84e134Smrg XawTextAnchor *anchor, *panchor; 15797a84e134Smrg 15807a84e134Smrg if ((panchor = XawTextSourceFindAnchor(w, position)) != NULL) { 15817a84e134Smrg XawTextEntity *pentity, *entity; 15827a84e134Smrg 15837a84e134Smrg if (position - panchor->position < ANCHORS_DIST) 15847a84e134Smrg return (panchor); 15857a84e134Smrg 15867a84e134Smrg if (panchor->cache && panchor->position + panchor->cache->offset + 15877a84e134Smrg panchor->cache->length < position) 15887a84e134Smrg pentity = entity = panchor->cache; 15897a84e134Smrg else 15907a84e134Smrg pentity = entity = panchor->entities; 15917a84e134Smrg 15927a84e134Smrg while (entity && panchor->position + entity->offset + 15937a84e134Smrg entity->length < position) { 15947a84e134Smrg pentity = entity; 15957a84e134Smrg entity = entity->next; 15967a84e134Smrg } 15977a84e134Smrg if (entity) { 15987a84e134Smrg XawTextPosition diff; 15997a84e134Smrg 16007a84e134Smrg if (panchor->position + entity->offset < position) 16017a84e134Smrg position = panchor->position + entity->offset; 16027a84e134Smrg 16037a84e134Smrg if (position == panchor->position) 16047a84e134Smrg return (panchor); 16057a84e134Smrg 16067a84e134Smrg anchor = XtNew(XawTextAnchor); 16077a84e134Smrg diff = position - panchor->position; 16087a84e134Smrg 16097a84e134Smrg panchor->cache = NULL; 16107a84e134Smrg anchor->entities = entity; 16117a84e134Smrg if (pentity != entity) 16127a84e134Smrg pentity->next = NULL; 16137a84e134Smrg else 16147a84e134Smrg panchor->entities = NULL; 16157a84e134Smrg while (entity) { 16167a84e134Smrg entity->offset -= diff; 16177a84e134Smrg entity = entity->next; 16187a84e134Smrg } 16197a84e134Smrg } 16207a84e134Smrg else { 16217a84e134Smrg anchor = XtNew(XawTextAnchor); 16227a84e134Smrg anchor->entities = NULL; 16237a84e134Smrg } 16247a84e134Smrg } 16257a84e134Smrg else { 16267a84e134Smrg anchor = XtNew(XawTextAnchor); 16277a84e134Smrg anchor->entities = NULL; 16287a84e134Smrg } 16297a84e134Smrg 16307a84e134Smrg anchor->position = position; 16317a84e134Smrg anchor->cache = NULL; 16327a84e134Smrg 16337a84e134Smrg src->textSrc.anchors = (XawTextAnchor**) 16347a84e134Smrg XtRealloc((XtPointer)src->textSrc.anchors, sizeof(XawTextAnchor*) * 16357a84e134Smrg (src->textSrc.num_anchors + 1)); 16367a84e134Smrg src->textSrc.anchors[src->textSrc.num_anchors++] = anchor; 16377a84e134Smrg qsort((void*)src->textSrc.anchors, src->textSrc.num_anchors, 16387a84e134Smrg sizeof(XawTextAnchor*), qcmp_anchors); 16397a84e134Smrg 16407a84e134Smrg return (anchor); 16417a84e134Smrg} 16427a84e134Smrg 16437a84e134SmrgXawTextAnchor * 16447a84e134SmrgXawTextSourceFindAnchor(Widget w, XawTextPosition position) 16457a84e134Smrg{ 16467a84e134Smrg TextSrcObject src = (TextSrcObject)w; 16477a84e134Smrg int i = 0, left, right, nmemb = src->textSrc.num_anchors; 16487a84e134Smrg XawTextAnchor *anchor, **anchors = src->textSrc.anchors; 16497a84e134Smrg 16507a84e134Smrg left = 0; 16517a84e134Smrg right = nmemb - 1; 16527a84e134Smrg while (left <= right) { 16537a84e134Smrg anchor = anchors[i = (left + right) >> 1]; 16547a84e134Smrg if (anchor->position == position) 16557a84e134Smrg return (anchor); 16567a84e134Smrg else if (position < anchor->position) 16577a84e134Smrg right = i - 1; 16587a84e134Smrg else 16597a84e134Smrg left = i + 1; 16607a84e134Smrg } 16617a84e134Smrg 16627a84e134Smrg if (nmemb) 16637a84e134Smrg return (right < 0 ? anchors[0] : anchors[right]); 16647a84e134Smrg 16657a84e134Smrg return (NULL); 16667a84e134Smrg} 16677a84e134Smrg 16687a84e134SmrgBool 16697a84e134SmrgXawTextSourceAnchorAndEntity(Widget w, XawTextPosition position, 16707a84e134Smrg XawTextAnchor **anchor_return, 16717a84e134Smrg XawTextEntity **entity_return) 16727a84e134Smrg{ 16737a84e134Smrg XawTextAnchor *anchor = XawTextSourceFindAnchor(w, position); 16747a84e134Smrg XawTextEntity *pentity, *entity; 16757a84e134Smrg XawTextPosition offset; 16767a84e134Smrg Bool next_anchor = True, retval = False; 16777a84e134Smrg 16787a84e134Smrg if (anchor->cache && anchor->position + anchor->cache->offset + 16797a84e134Smrg anchor->cache->length <= position) 16807a84e134Smrg pentity = entity = anchor->cache; 16817a84e134Smrg else 16827a84e134Smrg pentity = entity = anchor->entities; 16837a84e134Smrg while (entity) { 16847a84e134Smrg offset = anchor->position + entity->offset; 16857a84e134Smrg 16867a84e134Smrg if (offset > position) { 16877a84e134Smrg retval = next_anchor = False; 16887a84e134Smrg break; 16897a84e134Smrg } 16907a84e134Smrg if (offset + entity->length > position) { 16917a84e134Smrg retval = True; 16927a84e134Smrg next_anchor = False; 16937a84e134Smrg break; 16947a84e134Smrg } 16957a84e134Smrg pentity = entity; 16967a84e134Smrg entity = entity->next; 16977a84e134Smrg } 16987a84e134Smrg 16997a84e134Smrg if (next_anchor) { 17007a84e134Smrg *anchor_return = anchor = XawTextSourceNextAnchor(w, anchor); 17017a84e134Smrg *entity_return = anchor ? anchor->entities : NULL; 17027a84e134Smrg } 17037a84e134Smrg else { 17047a84e134Smrg *anchor_return = anchor; 17057a84e134Smrg *entity_return = retval ? entity : pentity; 17067a84e134Smrg } 17077a84e134Smrg 17087a84e134Smrg if (*anchor_return) 17097a84e134Smrg (*anchor_return)->cache = *entity_return; 17107a84e134Smrg 17117a84e134Smrg return (retval); 17127a84e134Smrg} 17137a84e134Smrg 17147a84e134SmrgXawTextAnchor * 17157a84e134SmrgXawTextSourceNextAnchor(Widget w, XawTextAnchor *anchor) 17167a84e134Smrg{ 17177a84e134Smrg int i; 17187a84e134Smrg TextSrcObject src = (TextSrcObject)w; 17197a84e134Smrg 17207a84e134Smrg for (i = 0; i < src->textSrc.num_anchors - 1; i++) 17217a84e134Smrg if (src->textSrc.anchors[i] == anchor) 17227a84e134Smrg return (src->textSrc.anchors[i + 1]); 17237a84e134Smrg 17247a84e134Smrg return (NULL); 17257a84e134Smrg} 17267a84e134Smrg 17277a84e134SmrgXawTextAnchor * 17287a84e134SmrgXawTextSourcePrevAnchor(Widget w, XawTextAnchor *anchor) 17297a84e134Smrg{ 17307a84e134Smrg int i; 17317a84e134Smrg TextSrcObject src = (TextSrcObject)w; 17327a84e134Smrg 17337a84e134Smrg for (i = src->textSrc.num_anchors - 1; i > 0; i--) 17347a84e134Smrg if (src->textSrc.anchors[i] == anchor) 17357a84e134Smrg return (src->textSrc.anchors[i - 1]); 17367a84e134Smrg 17377a84e134Smrg return (NULL); 17387a84e134Smrg} 17397a84e134Smrg 17407a84e134SmrgXawTextAnchor * 17417a84e134SmrgXawTextSourceRemoveAnchor(Widget w, XawTextAnchor *anchor) 17427a84e134Smrg{ 17437a84e134Smrg int i; 17447a84e134Smrg TextSrcObject src = (TextSrcObject)w; 17457a84e134Smrg 17467a84e134Smrg for (i = 0; i < src->textSrc.num_anchors; i++) 17477a84e134Smrg if (src->textSrc.anchors[i] == anchor) 17487a84e134Smrg break; 17497a84e134Smrg 17507a84e134Smrg if (i == 0) 17517a84e134Smrg return (src->textSrc.num_anchors > 1 ? src->textSrc.anchors[1] : NULL); 17527a84e134Smrg 17537a84e134Smrg if (i < src->textSrc.num_anchors) { 17547a84e134Smrg XtFree((XtPointer)anchor); 17557a84e134Smrg if (i < --src->textSrc.num_anchors) { 17567a84e134Smrg memmove(&src->textSrc.anchors[i], 17577a84e134Smrg &src->textSrc.anchors[i + 1], 17587a84e134Smrg (src->textSrc.num_anchors - i) * 17597a84e134Smrg sizeof(XawTextAnchor*)); 17607a84e134Smrg 17617a84e134Smrg return (src->textSrc.anchors[i]); 17627a84e134Smrg } 17637a84e134Smrg } 17647a84e134Smrg 17657a84e134Smrg return (NULL); 17667a84e134Smrg} 17677a84e134Smrg 17687a84e134SmrgXawTextEntity * 17697a84e134SmrgXawTextSourceAddEntity(Widget w, int type, int flags, XtPointer data, 17707a84e134Smrg XawTextPosition position, Cardinal length, 17717a84e134Smrg XrmQuark property) 17727a84e134Smrg{ 17737a84e134Smrg XawTextAnchor *next, *anchor = _XawTextSourceFindAnchor(w, position); 17747a84e134Smrg XawTextEntity *entity, *eprev; 17757a84e134Smrg 17767a84e134Smrg /* There is no support for zero length entities for now */ 17777a84e134Smrg if (length == 0) 17787a84e134Smrg return (NULL); 17797a84e134Smrg 17807a84e134Smrg if (anchor->cache && anchor->position + anchor->cache->offset + 17817a84e134Smrg anchor->cache->length <= position) 17827a84e134Smrg eprev = entity = anchor->cache; 17837a84e134Smrg else 17847a84e134Smrg eprev = entity = anchor->entities; 17857a84e134Smrg 17867a84e134Smrg while (entity && anchor->position + entity->offset + entity->length <= 17877a84e134Smrg position) { 17887a84e134Smrg eprev = entity; 17897a84e134Smrg entity = entity->next; 17907a84e134Smrg } 17917a84e134Smrg if (entity && anchor->position + entity->offset < position + length) { 17927a84e134Smrg fprintf(stderr, "Cannot (yet) add more than one entity to same region.\n"); 17937a84e134Smrg return (NULL); 17947a84e134Smrg } 17957a84e134Smrg 17967a84e134Smrg next = XawTextSourceFindAnchor(w, position + length); 17977a84e134Smrg if (next && next != anchor) { 17987a84e134Smrg if ((entity = next->entities) != NULL) { 17997a84e134Smrg if (next->position + entity->offset < position + length) { 18007a84e134Smrg fprintf(stderr, "Cannot (yet) add more than one entity to same region.\n"); 18017a84e134Smrg return (NULL); 18027a84e134Smrg } 18037a84e134Smrg } 18047a84e134Smrg if (position + length > next->position) { 18057a84e134Smrg XawTextPosition diff = position + length - next->position; 18067a84e134Smrg 18077a84e134Smrg next->position += diff; 18087a84e134Smrg entity = next->entities; 18097a84e134Smrg while (entity) { 18107a84e134Smrg entity->offset -= diff; 18117a84e134Smrg entity = entity->next; 18127a84e134Smrg } 18137a84e134Smrg entity = anchor->entities; 18147a84e134Smrg while (entity && entity->offset < 0) 18157a84e134Smrg entity = entity->next; 18167a84e134Smrg if (entity && entity->offset < 0) { 18177a84e134Smrg if (eprev) 18187a84e134Smrg eprev->next = next->entities; 18197a84e134Smrg else 18207a84e134Smrg anchor->entities = next->entities; 18217a84e134Smrg if ((next->entities = entity->next) == NULL) 18227a84e134Smrg (void)XawTextSourceRemoveAnchor(w, next); 18237a84e134Smrg entity->next = NULL; 18247a84e134Smrg 18257a84e134Smrg return (XawTextSourceAddEntity(w, type, flags, data, position, 18267a84e134Smrg length, property)); 18277a84e134Smrg } 18287a84e134Smrg } 18297a84e134Smrg } 18307a84e134Smrg 18317a84e134Smrg /* Automatically join sequential entities if possible */ 18327a84e134Smrg if (eprev && 18337a84e134Smrg anchor->position + eprev->offset + eprev->length == position && 18347a84e134Smrg eprev->property == property && eprev->type == type && 18357a84e134Smrg eprev->flags == flags && eprev->data == data) { 18367a84e134Smrg eprev->length += length; 18377a84e134Smrg return (eprev); 18387a84e134Smrg } 18397a84e134Smrg 18407a84e134Smrg entity = XtNew(XawTextEntity); 18417a84e134Smrg entity->type = type; 18427a84e134Smrg entity->flags = flags; 18437a84e134Smrg entity->data = data; 18447a84e134Smrg entity->offset = position - anchor->position; 18457a84e134Smrg entity->length = length; 18467a84e134Smrg entity->property = property; 18477a84e134Smrg 18487a84e134Smrg if (eprev == NULL) { 18497a84e134Smrg anchor->entities = entity; 18507a84e134Smrg entity->next = NULL; 18517a84e134Smrg anchor->cache = NULL; 18527a84e134Smrg } 18537a84e134Smrg else if (eprev->offset > entity->offset) { 18547a84e134Smrg anchor->cache = NULL; 18557a84e134Smrg anchor->entities = entity; 18567a84e134Smrg entity->next = eprev; 18577a84e134Smrg } 18587a84e134Smrg else { 18597a84e134Smrg anchor->cache = eprev; 18607a84e134Smrg entity->next = eprev->next; 18617a84e134Smrg eprev->next = entity; 18627a84e134Smrg } 18637a84e134Smrg 18647a84e134Smrg return (entity); 18657a84e134Smrg} 18667a84e134Smrg 18677a84e134Smrgvoid 18687a84e134SmrgXawTextSourceClearEntities(Widget w, XawTextPosition left, XawTextPosition right) 18697a84e134Smrg{ 18707a84e134Smrg XawTextAnchor *anchor = XawTextSourceFindAnchor(w, left); 18717a84e134Smrg XawTextEntity *entity, *eprev, *enext; 18727a84e134Smrg XawTextPosition offset; 18737a84e134Smrg int length; 18747a84e134Smrg 18757a84e134Smrg while (anchor && anchor->entities == NULL) 18767a84e134Smrg anchor = XawTextSourceRemoveAnchor(w, anchor); 18777a84e134Smrg 18787a84e134Smrg if (anchor == NULL || left >= right) 18797a84e134Smrg return; 18807a84e134Smrg 18817a84e134Smrg if (anchor->cache && anchor->position + anchor->cache->offset + 18827a84e134Smrg anchor->cache->length < left) 18837a84e134Smrg eprev = entity = anchor->cache; 18847a84e134Smrg else 18857a84e134Smrg eprev = entity = anchor->entities; 18867a84e134Smrg 18877a84e134Smrg /* find first entity before left position */ 18887a84e134Smrg while (anchor->position + entity->offset + entity->length < left) { 18897a84e134Smrg eprev = entity; 18907a84e134Smrg if ((entity = entity->next) == NULL) { 18917a84e134Smrg if ((anchor = XawTextSourceNextAnchor(w, anchor)) == NULL) 18927a84e134Smrg return; 18937a84e134Smrg if ((eprev = entity = anchor->entities) == NULL) { 18947a84e134Smrg fprintf(stderr, "Bad anchor found!\n"); 18957a84e134Smrg return; 18967a84e134Smrg } 18977a84e134Smrg } 18987a84e134Smrg } 18997a84e134Smrg 19007a84e134Smrg offset = anchor->position + entity->offset; 19017a84e134Smrg if (offset <= left) { 19027a84e134Smrg length = XawMin(entity->length, left - offset); 19037a84e134Smrg 19047a84e134Smrg if (length <= 0) { 19057a84e134Smrg enext = entity->next; 19067a84e134Smrg eprev->next = enext; 19077a84e134Smrg XtFree((XtPointer)entity); 19087a84e134Smrg anchor->cache = NULL; 19097a84e134Smrg if (entity == anchor->entities) { 19107a84e134Smrg eprev = NULL; 19117a84e134Smrg if ((anchor->entities = enext) == NULL) { 19127a84e134Smrg if ((anchor = XawTextSourceRemoveAnchor(w, anchor)) == NULL) 19137a84e134Smrg return; 19147a84e134Smrg entity = anchor->entities; 19157a84e134Smrg } 19167a84e134Smrg else 19177a84e134Smrg entity = enext; 19187a84e134Smrg } 19197a84e134Smrg else 19207a84e134Smrg entity = enext; 19217a84e134Smrg } 19227a84e134Smrg else { 19237a84e134Smrg entity->length = length; 19247a84e134Smrg eprev = entity; 19257a84e134Smrg entity = entity->next; 19267a84e134Smrg } 19277a84e134Smrg } 19287a84e134Smrg 19297a84e134Smrg /* clean everything until right position is reached */ 19307a84e134Smrg while (anchor) { 19317a84e134Smrg while (entity) { 19327a84e134Smrg offset = anchor->position + entity->offset + entity->length; 19337a84e134Smrg 19347a84e134Smrg if (offset > right) { 19357a84e134Smrg anchor->cache = NULL; 19367a84e134Smrg entity->offset = XawMax(entity->offset, right - anchor->position); 19377a84e134Smrg entity->length = XawMin(entity->length, offset - right); 19387a84e134Smrg return; 19397a84e134Smrg } 19407a84e134Smrg 19417a84e134Smrg enext = entity->next; 19427a84e134Smrg if (eprev) 19437a84e134Smrg eprev->next = enext; 19447a84e134Smrg XtFree((XtPointer)entity); 19457a84e134Smrg if (entity == anchor->entities) { 19467a84e134Smrg eprev = anchor->cache = NULL; 19477a84e134Smrg if ((anchor->entities = enext) == NULL) { 19487a84e134Smrg if ((anchor = XawTextSourceRemoveAnchor(w, anchor)) == NULL) 19497a84e134Smrg return; 19507a84e134Smrg entity = anchor->entities; 19517a84e134Smrg continue; 19527a84e134Smrg } 19537a84e134Smrg } 19547a84e134Smrg entity = enext; 19557a84e134Smrg } 19567a84e134Smrg if (anchor) 19577a84e134Smrg anchor->cache = NULL; 19587a84e134Smrg if ((anchor = XawTextSourceNextAnchor(w, anchor)) != NULL) 19597a84e134Smrg entity = anchor->entities; 19607a84e134Smrg eprev = NULL; 19617a84e134Smrg } 19627a84e134Smrg} 19637a84e134Smrg 19647a84e134Smrg/* checks the anchors up to position, and create an appropriate anchor 19657a84e134Smrg * at position, if required. 19667a84e134Smrg */ 19677a84e134SmrgXawTextAnchor * 19687a84e134Smrg_XawTextSourceFindAnchor(Widget w, XawTextPosition position) 19697a84e134Smrg{ 19707a84e134Smrg XawTextAnchor *anchor; 19717a84e134Smrg 19727a84e134Smrg anchor = XawTextSourceFindAnchor(w, position); 19737a84e134Smrg 19747a84e134Smrg position -= position % ANCHORS_DIST; 19757a84e134Smrg 19767a84e134Smrg if (position - anchor->position >= ANCHORS_DIST) 19777a84e134Smrg return (XawTextSourceAddAnchor(w, position)); 19787a84e134Smrg 19797a84e134Smrg return (anchor); 19807a84e134Smrg} 19817a84e134Smrg#endif 1982