Bug Summary

File:Text.c
Location:line 2005, column 10
Description:Value stored to 'pos2' is never read

Annotated Source Code

1/***********************************************************
2
3Copyright (c) 1987, 1988, 1994 X Consortium
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of the X Consortium shall not be
23used in advertising or otherwise to promote the sale, use or other dealings
24in this Software without prior written authorization from the X Consortium.
25
26
27Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
28
29 All Rights Reserved
30
31Permission to use, copy, modify, and distribute this software and its
32documentation for any purpose and without fee is hereby granted,
33provided that the above copyright notice appear in all copies and that
34both that copyright notice and this permission notice appear in
35supporting documentation, and that the name of Digital not be
36used in advertising or publicity pertaining to distribution of the
37software without specific, written prior permission.
38
39DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
40ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
41DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
42ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
43WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
44ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
45SOFTWARE.
46
47******************************************************************/
48
49#ifdef HAVE_CONFIG_H1
50#include "config.h"
51#endif
52#include <X11/Xaw3d/Xaw3dP.h>
53#include <X11/IntrinsicP.h>
54#include <X11/StringDefs.h>
55#include <X11/Shell.h>
56#include <X11/Xatom.h>
57#include <X11/Xutil.h>
58#ifdef XAW_INTERNATIONALIZATION1
59#include "XawI18n.h"
60#endif
61#include <stdint.h>
62#include <stdio.h>
63#include <stdlib.h>
64#include <X11/Xmu/Atoms.h>
65#include <X11/Xmu/CharSet.h>
66#include <X11/Xmu/Converters.h>
67#include <X11/Xmu/StdSel.h>
68#include <X11/Xmu/Misc.h>
69#include <X11/Xaw3d/XawInit.h>
70#include <X11/Xaw3d/Cardinals.h>
71#include <X11/Xaw3d/Scrollbar.h>
72#include <X11/Xaw3d/TextP.h>
73#ifdef XAW_INTERNATIONALIZATION1
74#include <X11/Xaw3d/MultiSinkP.h>
75#include <X11/Xaw3d/XawImP.h>
76#endif
77#include <X11/Xaw3d/ThreeDP.h>
78#include <X11/Xfuncs.h>
79#include <ctype.h> /* for isprint() */
80
81#ifndef MAX_LEN_CT6
82#define MAX_LEN_CT6 6 /* for sequence: ESC $ ( A \xx \xx */
83#endif
84
85unsigned long FMT8BIT = 0L;
86unsigned long XawFmt8Bit = 0L;
87#ifdef XAW_INTERNATIONALIZATION1
88unsigned long XawFmtWide = 0L;
89#endif
90
91#define SinkClearToBGXawTextSinkClearToBackground XawTextSinkClearToBackground
92
93#define SrcScanXawTextSourceScan XawTextSourceScan
94#define SrcReadXawTextSourceRead XawTextSourceRead
95#define SrcReplaceXawTextSourceReplace XawTextSourceReplace
96#define SrcSearchXawTextSourceSearch XawTextSourceSearch
97#define SrcCvtSelXawTextSourceConvertSelection XawTextSourceConvertSelection
98#define SrcSetSelectionXawTextSourceSetSelection XawTextSourceSetSelection
99
100#define BIGNUM((Dimension)32023) ((Dimension)32023)
101#define MULTI_CLICK_TIME500L 500L
102
103/*
104 * Compute a the maximum length of a cut buffer that we can pass at any
105 * time. The 64 allows for the overhead of the Change Property request.
106 */
107
108#define MAX_CUT_LEN(dpy)(XMaxRequestSize(dpy) - 64) (XMaxRequestSize(dpy) - 64)
109
110#define IsValidLine(ctx, num)( ((num) == 0) || ((ctx)->text.lt.info[(num)].position != 0
) )
( ((num) == 0) || \
111 ((ctx)->text.lt.info[(num)].position != 0) )
112
113/*
114 * Defined in TextAction.c
115 */
116extern void _XawTextZapSelection(TextWidget, XEvent *, Boolean);
117
118
119/*
120 * Defined in Text.c
121 */
122static void UnrealizeScrollbars(Widget, XtPointer, XtPointer);
123static void VScroll(Widget, XtPointer, XtPointer);
124static void VJump(Widget, XtPointer, XtPointer);
125static void HScroll(Widget, XtPointer, XtPointer);
126static void HJump(Widget, XtPointer, XtPointer);
127static void ClearWindow(Widget);
128static void DisplayTextWindow(Widget);
129static void ModifySelection(TextWidget, XawTextPosition, XawTextPosition);
130static void PushCopyQueue(TextWidget, int, int);
131static void UpdateTextInLine(TextWidget, int, Position, Position);
132static void UpdateTextInRectangle(TextWidget, XRectangle *);
133static void PopCopyQueue(TextWidget);
134static void FlushUpdate(TextWidget);
135static Boolean LineAndXYForPosition(TextWidget, XawTextPosition, int *,
136 Position *, Position *);
137static Boolean TranslateExposeRegion(TextWidget, XRectangle *);
138static XawTextPosition FindGoodPosition(TextWidget, XawTextPosition);
139static XawTextPosition _BuildLineTable(TextWidget, XawTextPosition,
140 XawTextPosition, int);
141
142void _XawTextAlterSelection(TextWidget, XawTextSelectionMode,
143 XawTextSelectionAction, String *, Cardinal *);
144void _XawTextCheckResize(TextWidget);
145void _XawTextClearAndCenterDisplay(TextWidget);
146void _XawTextExecuteUpdate(TextWidget);
147char *_XawTextGetText(TextWidget, XawTextPosition, XawTextPosition);
148void _XawTextNeedsUpdating(TextWidget, XawTextPosition, XawTextPosition);
149Atom * _XawTextSelectionList(TextWidget, String *, Cardinal);
150void _XawTextSetScrollBars(TextWidget);
151void _XawTextSetSelection(TextWidget, XawTextPosition, XawTextPosition,
152 String *, Cardinal);
153void _XawTextShowPosition(TextWidget);
154void _XawTextPrepareToUpdate(TextWidget);
155int _XawTextReplace(TextWidget, XawTextPosition, XawTextPosition, XawTextBlock *);
156void _XawTextVScroll(TextWidget, int);
157
158/****************************************************************
159 *
160 * Full class record constant
161 *
162 ****************************************************************/
163
164static XawTextSelectType defaultSelectTypes[] = {
165 XawselectPosition, XawselectWord, XawselectLine, XawselectParagraph,
166 XawselectAll, XawselectNull,
167};
168
169static XPointer defaultSelectTypesPtr = (XPointer)defaultSelectTypes;
170extern char *_XawDefaultTextTranslations1, *_XawDefaultTextTranslations2,
171 *_XawDefaultTextTranslations3, *_XawDefaultTextTranslations4;
172static Dimension defWidth = 100;
173static Dimension defHeight = DEFAULT_TEXT_HEIGHT((Dimension)~0);
174
175#define offset(field) XtOffsetOf(TextRec, field)__builtin_offsetof(TextRec, field)
176static XtResource resources[] = {
177 {XtNwidth((char*)&XtStrings[872]), XtCWidth((char*)&XtStrings[1510]), XtRDimension((char*)&XtStrings[1618]), sizeof(Dimension),
178 offset(core.width), XtRDimension((char*)&XtStrings[1618]), (XtPointer)&defWidth},
179 {XtNcursor"cursor", XtCCursor((char*)&XtStrings[976]), XtRCursor((char*)&XtStrings[1611]), sizeof(Cursor),
180 offset(simple.cursor), XtRString((char*)&XtStrings[1797]), "xterm"},
181 {XtNheight((char*)&XtStrings[234]), XtCHeight((char*)&XtStrings[1051]), XtRDimension((char*)&XtStrings[1618]), sizeof(Dimension),
182 offset(core.height), XtRDimension((char*)&XtStrings[1618]), (XtPointer)&defHeight},
183 {XtNdisplayPosition"displayPosition", XtCTextPosition((char*)&XtStrings[1435]), XtRInt((char*)&XtStrings[1718]), sizeof(XawTextPosition),
184 offset(text.lt.top), XtRImmediate((char*)&XtStrings[1695]), (XtPointer)0},
185 {XtNinsertPosition((char*)&XtStrings[326]), XtCTextPosition((char*)&XtStrings[1435]), XtRInt((char*)&XtStrings[1718]), sizeof(XawTextPosition),
186 offset(text.insertPos), XtRImmediate((char*)&XtStrings[1695]),(XtPointer)0},
187 {XtNleftMargin"leftMargin", XtCMargin((char*)&XtStrings[1182]), XtRPosition((char*)&XtStrings[1775]), sizeof (Position),
188 offset(text.r_margin.left), XtRImmediate((char*)&XtStrings[1695]), (XtPointer)2},
189 {XtNrightMargin"rightMargin", XtCMargin((char*)&XtStrings[1182]), XtRPosition((char*)&XtStrings[1775]), sizeof (Position),
190 offset(text.r_margin.right), XtRImmediate((char*)&XtStrings[1695]), (XtPointer)4},
191 {XtNtopMargin"topMargin", XtCMargin((char*)&XtStrings[1182]), XtRPosition((char*)&XtStrings[1775]), sizeof (Position),
192 offset(text.r_margin.top), XtRImmediate((char*)&XtStrings[1695]), (XtPointer)2},
193 {XtNbottomMargin"bottomMargin", XtCMargin((char*)&XtStrings[1182]), XtRPosition((char*)&XtStrings[1775]), sizeof (Position),
194 offset(text.r_margin.bottom), XtRImmediate((char*)&XtStrings[1695]), (XtPointer)2},
195 {XtNselectTypes"selectTypes", XtCSelectTypes"SelectTypes", XtRPointer((char*)&XtStrings[1767]),
196 sizeof(XawTextSelectType*), offset(text.sarray),
197 XtRPointer((char*)&XtStrings[1767]), (XtPointer)&defaultSelectTypesPtr},
198 {XtNtextSource((char*)&XtStrings[761]), XtCTextSource((char*)&XtStrings[1457]), XtRWidget((char*)&XtStrings[1865]), sizeof (Widget),
199 offset(text.source), XtRImmediate((char*)&XtStrings[1695]), NULL((void*)0)},
200 {XtNtextSink((char*)&XtStrings[752]), XtCTextSink((char*)&XtStrings[1448]), XtRWidget((char*)&XtStrings[1865]), sizeof (Widget),
201 offset(text.sink), XtRImmediate((char*)&XtStrings[1695]), NULL((void*)0)},
202 {XtNdisplayCaret"displayCaret", XtCOutput"Output", XtRBoolean((char*)&XtStrings[1561]), sizeof(Boolean),
203 offset(text.display_caret), XtRImmediate((char*)&XtStrings[1695]), (XtPointer)True1},
204 {XtNscrollVertical"scrollVertical", XtCScroll"Scroll", XtRScrollMode"ScrollMode", sizeof(XawTextScrollMode),
205 offset(text.scroll_vert), XtRImmediate((char*)&XtStrings[1695]), (XtPointer) XawtextScrollNever},
206 {XtNscrollHorizontal"scrollHorizontal", XtCScroll"Scroll", XtRScrollMode"ScrollMode", sizeof(XawTextScrollMode),
207 offset(text.scroll_horiz), XtRImmediate((char*)&XtStrings[1695]), (XtPointer) XawtextScrollNever},
208 {XtNwrap"wrap", XtCWrap"Wrap", XtRWrapMode"WrapMode", sizeof(XawTextWrapMode),
209 offset(text.wrap), XtRImmediate((char*)&XtStrings[1695]), (XtPointer) XawtextWrapNever},
210 {XtNresize((char*)&XtStrings[564]), XtCResize((char*)&XtStrings[1253]), XtRResizeMode"ResizeMode", sizeof(XawTextResizeMode),
211 offset(text.resize), XtRImmediate((char*)&XtStrings[1695]), (XtPointer) XawtextResizeNever},
212 {XtNautoFill"autoFill", XtCAutoFill"AutoFill", XtRBoolean((char*)&XtStrings[1561]), sizeof(Boolean),
213 offset(text.auto_fill), XtRImmediate((char*)&XtStrings[1695]), (XtPointer) FALSE0},
214 {XtNunrealizeCallback((char*)&XtStrings[815]), XtCCallback((char*)&XtStrings[952]), XtRCallback((char*)&XtStrings[1569]), sizeof(XtPointer),
215 offset(text.unrealize_callbacks), XtRCallback((char*)&XtStrings[1569]), (XtPointer) NULL((void*)0)}
216};
217#undef offset
218
219/* ARGSUSED */
220static void
221CvtStringToScrollMode(XrmValuePtr args, Cardinal *num_args, XrmValuePtr fromVal,
222 XrmValuePtr toVal)
223{
224 static XawTextScrollMode scrollMode;
225 static XrmQuark QScrollNever, QScrollAlways, QScrollWhenNeeded;
226 XrmQuark q;
227 char lowerName[40];
228 static Boolean inited = FALSE0;
229
230 if ( !inited ) {
231 QScrollNever = XrmPermStringToQuark(XtEtextScrollNever"never");
232 QScrollWhenNeeded = XrmPermStringToQuark(XtEtextScrollWhenNeeded"whenneeded");
233 QScrollAlways = XrmPermStringToQuark(XtEtextScrollAlways"always");
234 inited = TRUE1;
235 }
236
237 if (strlen ((char*) fromVal->addr) < sizeof lowerName) {
238 XmuCopyISOLatin1Lowered (lowerName, (char *)fromVal->addr);
239 q = XrmStringToQuark(lowerName);
240
241 if (q == QScrollNever) scrollMode = XawtextScrollNever;
242 else if (q == QScrollWhenNeeded) scrollMode = XawtextScrollWhenNeeded;
243 else if (q == QScrollAlways) scrollMode = XawtextScrollAlways;
244 else {
245 toVal->size = 0;
246 toVal->addr = NULL((void*)0);
247 return;
248 }
249 toVal->size = sizeof scrollMode;
250 toVal->addr = (XPointer) &scrollMode;
251 return;
252 }
253 toVal->size = 0;
254 toVal->addr = NULL((void*)0);
255}
256
257/* ARGSUSED */
258static void
259CvtStringToWrapMode(XrmValuePtr args, Cardinal *num_args, XrmValuePtr fromVal,
260 XrmValuePtr toVal)
261{
262 static XawTextWrapMode wrapMode;
263 static XrmQuark QWrapNever, QWrapLine, QWrapWord;
264 XrmQuark q;
265 char lowerName[BUFSIZ1024];
266 static Boolean inited = FALSE0;
267
268 if ( !inited ) {
269 QWrapNever = XrmPermStringToQuark(XtEtextWrapNever"never");
270 QWrapLine = XrmPermStringToQuark(XtEtextWrapLine"line");
271 QWrapWord = XrmPermStringToQuark(XtEtextWrapWord"word");
272 inited = TRUE1;
273 }
274
275 if (strlen ((char*) fromVal->addr) < sizeof lowerName) {
276 XmuCopyISOLatin1Lowered (lowerName, (char *)fromVal->addr);
277 q = XrmStringToQuark(lowerName);
278
279 if (q == QWrapNever) wrapMode = XawtextWrapNever;
280 else if (q == QWrapLine) wrapMode = XawtextWrapLine;
281 else if (q == QWrapWord) wrapMode = XawtextWrapWord;
282 else {
283 toVal->size = 0;
284 toVal->addr = NULL((void*)0);
285 return;
286 }
287 toVal->size = sizeof wrapMode;
288 toVal->addr = (XPointer) &wrapMode;
289 return;
290 }
291 toVal->size = 0;
292 toVal->addr = NULL((void*)0);
293}
294
295/* ARGSUSED */
296static void
297CvtStringToResizeMode(XrmValuePtr args, Cardinal *num_args, XrmValuePtr fromVal,
298 XrmValuePtr toVal)
299{
300 static XawTextResizeMode resizeMode;
301 static XrmQuark QResizeNever, QResizeWidth, QResizeHeight, QResizeBoth;
302 XrmQuark q;
303 char lowerName[40];
304 static Boolean inited = FALSE0;
305
306 if ( !inited ) {
307 QResizeNever = XrmPermStringToQuark(XtEtextResizeNever"never");
308 QResizeWidth = XrmPermStringToQuark(XtEtextResizeWidth"width");
309 QResizeHeight = XrmPermStringToQuark(XtEtextResizeHeight"height");
310 QResizeBoth = XrmPermStringToQuark(XtEtextResizeBoth"both");
311 inited = TRUE1;
312 }
313
314 if (strlen ((char*) fromVal->addr) < sizeof lowerName) {
315 XmuCopyISOLatin1Lowered (lowerName, (char *)fromVal->addr);
316 q = XrmStringToQuark(lowerName);
317
318 if (q == QResizeNever) resizeMode = XawtextResizeNever;
319 else if (q == QResizeWidth) resizeMode = XawtextResizeWidth;
320 else if (q == QResizeHeight) resizeMode = XawtextResizeHeight;
321 else if (q == QResizeBoth) resizeMode = XawtextResizeBoth;
322 else {
323 toVal->size = 0;
324 toVal->addr = NULL((void*)0);
325 return;
326 }
327 toVal->size = sizeof resizeMode;
328 toVal->addr = (XPointer) &resizeMode;
329 return;
330 }
331 toVal->size = 0;
332 toVal->addr = NULL((void*)0);
333}
334
335static void
336ClassInitialize(void)
337{
338 int len1 = strlen (_XawDefaultTextTranslations1);
339 int len2 = strlen (_XawDefaultTextTranslations2);
340 int len3 = strlen (_XawDefaultTextTranslations3);
341 int len4 = strlen (_XawDefaultTextTranslations4);
342 char *buf = XtMalloc ((unsigned)(len1 + len2 + len3 + len4 + 1));
343 char *cp = buf;
344
345 if (!XawFmt8Bit)
346 FMT8BIT = XawFmt8Bit = XrmPermStringToQuark("FMT8BIT");
347#ifdef XAW_INTERNATIONALIZATION1
348 if (!XawFmtWide)
349 XawFmtWide = XrmPermStringToQuark("FMTWIDE");
350#endif
351
352 XawInitializeWidgetSet();
353
354/*
355 * Set the number of actions.
356 */
357
358 textClassRec.core_class.num_actions = _XawTextActionsTableCount;
359
360 (void) strcpy( cp, _XawDefaultTextTranslations1)__builtin___strcpy_chk (cp, _XawDefaultTextTranslations1, __builtin_object_size
(cp, 2 > 1 ? 1 : 0))
; cp += len1;
361 (void) strcpy( cp, _XawDefaultTextTranslations2)__builtin___strcpy_chk (cp, _XawDefaultTextTranslations2, __builtin_object_size
(cp, 2 > 1 ? 1 : 0))
; cp += len2;
362 (void) strcpy( cp, _XawDefaultTextTranslations3)__builtin___strcpy_chk (cp, _XawDefaultTextTranslations3, __builtin_object_size
(cp, 2 > 1 ? 1 : 0))
; cp += len3;
363 (void) strcpy( cp, _XawDefaultTextTranslations4)__builtin___strcpy_chk (cp, _XawDefaultTextTranslations4, __builtin_object_size
(cp, 2 > 1 ? 1 : 0))
;
364 textWidgetClass->core_class.tm_table = buf;
365
366 XtAddConverter(XtRString((char*)&XtStrings[1797]), XtRScrollMode"ScrollMode", CvtStringToScrollMode,
367 (XtConvertArgList)NULL((void*)0), (Cardinal)0 );
368 XtAddConverter(XtRString((char*)&XtStrings[1797]), XtRWrapMode"WrapMode", CvtStringToWrapMode,
369 (XtConvertArgList)NULL((void*)0), (Cardinal)0 );
370 XtAddConverter(XtRString((char*)&XtStrings[1797]), XtRResizeMode"ResizeMode", CvtStringToResizeMode,
371 (XtConvertArgList)NULL((void*)0), (Cardinal)0 );
372}
373
374/* Function Name: PositionHScrollBar.
375 * Description: Positions the Horizontal scrollbar.
376 * Arguments: ctx - the text widget.
377 * Returns: none
378 */
379
380static void
381PositionHScrollBar(TextWidget ctx)
382{
383 Widget vbar = ctx->text.vbar, hbar = ctx->text.hbar;
384 Position top, left = 0;
385 int s = ((ThreeDWidget)ctx->text.threeD)->threeD.shadow_width;
386
387 if (ctx->text.hbar == NULL((void*)0)) return;
388
389 if (vbar != NULL((void*)0))
390 left += (Position) (vbar->core.width + vbar->core.border_width);
391
392 XtResizeWidget( hbar, ctx->core.width - left - s, hbar->core.height,
393 hbar->core.border_width );
394
395 left = s / 2 - (Position) hbar->core.border_width;
396 if (left < 0) left = 0;
397 if (vbar != NULL((void*)0))
398 left += (Position) (vbar->core.width + vbar->core.border_width);
399
400 top = ctx->core.height - (hbar->core.height + hbar->core.border_width + s / 2);
401
402 XtMoveWidget( hbar, left, top);
403}
404
405/* Function Name: PositionVScrollBar.
406 * Description: Positions the Vertical scrollbar.
407 * Arguments: ctx - the text widget.
408 * Returns: none.
409 */
410
411static void
412PositionVScrollBar(TextWidget ctx)
413{
414 Widget vbar = ctx->text.vbar;
415 Position pos;
416 Dimension bw;
417 int s = ((ThreeDWidget)ctx->text.threeD)->threeD.shadow_width;
418
419 if (vbar == NULL((void*)0)) return;
420 bw = vbar->core.border_width;
421
422 XtResizeWidget( vbar, vbar->core.width, ctx->core.height - s, bw);
423 pos = s / 2 - (Position)bw;
424 if (pos < 0) pos = 0;
425
426 XtMoveWidget( vbar, pos, pos);
427}
428
429static void
430CreateVScrollBar(TextWidget ctx)
431{
432 Widget vbar;
433
434 if (ctx->text.vbar != NULL((void*)0)) return;
435
436 ctx->text.vbar = vbar =
437 XtCreateWidget("vScrollbar", scrollbarWidgetClass, (Widget)ctx,
438 (ArgList) NULL((void*)0), ZERO((Cardinal)0));
439 XtAddCallback( vbar, XtNscrollProc((char*)&XtStrings[591]), VScroll, (XtPointer)ctx );
440 XtAddCallback( vbar, XtNjumpProc((char*)&XtStrings[370]), VJump, (XtPointer)ctx );
441 if (ctx->text.hbar == NULL((void*)0))
442 XtAddCallback((Widget) ctx, XtNunrealizeCallback((char*)&XtStrings[815]), UnrealizeScrollbars,
443 (XtPointer) NULL((void*)0));
444
445 ctx->text.r_margin.left += vbar->core.width + vbar->core.border_width;
446 ctx->text.margin.left = ctx->text.r_margin.left;
447
448 PositionVScrollBar(ctx);
449 PositionHScrollBar(ctx); /* May modify location of Horiz. Bar. */
450
451 if (XtIsRealized((Widget)ctx)(XtWindowOfObject((Widget)ctx) != 0L)) {
452 XtRealizeWidget(vbar);
453 XtMapWidget(vbar)XMapWindow((((vbar)->core.screen)->display), ((vbar)->
core.window))
;
454 }
455}
456
457/* Function Name: DestroyVScrollBar
458 * Description: Removes a vertical ScrollBar.
459 * Arguments: ctx - the parent text widget.
460 * Returns: none.
461 */
462
463static void
464DestroyVScrollBar(TextWidget ctx)
465{
466 Widget vbar = ctx->text.vbar;
467
468 if (vbar == NULL((void*)0)) return;
469
470 ctx->text.r_margin.left -= vbar->core.width + vbar->core.border_width;
471 ctx->text.margin.left = ctx->text.r_margin.left;
472 if (ctx->text.hbar == NULL((void*)0))
473 XtRemoveCallback((Widget) ctx, XtNunrealizeCallback((char*)&XtStrings[815]), UnrealizeScrollbars,
474 (XtPointer) NULL((void*)0));
475 XtDestroyWidget(vbar);
476 ctx->text.vbar = NULL((void*)0);
477 PositionHScrollBar(ctx);
478}
479
480static void
481CreateHScrollBar(TextWidget ctx)
482{
483 Arg args[1];
484 Widget hbar;
485
486 if (ctx->text.hbar != NULL((void*)0)) return;
487
488 XtSetArg(args[0], XtNorientation, XtorientHorizontal)((void)( (args[0]).name = (((char*)&XtStrings[505])), (args
[0]).value = (XtArgVal)(XtorientHorizontal) ))
;
489 ctx->text.hbar = hbar =
490 XtCreateWidget("hScrollbar", scrollbarWidgetClass, (Widget)ctx, args, ONE((Cardinal)1));
491 XtAddCallback( hbar, XtNscrollProc((char*)&XtStrings[591]), HScroll, (XtPointer)ctx );
492 XtAddCallback( hbar, XtNjumpProc((char*)&XtStrings[370]), HJump, (XtPointer)ctx );
493 if (ctx->text.vbar == NULL((void*)0))
494 XtAddCallback((Widget) ctx, XtNunrealizeCallback((char*)&XtStrings[815]), UnrealizeScrollbars,
495 (XtPointer) NULL((void*)0));
496
497/**/
498 ctx->text.r_margin.bottom += hbar->core.height + hbar->core.border_width;
499 ctx->text.margin.bottom = ctx->text.r_margin.bottom;
500/**/
501 PositionHScrollBar(ctx);
502 if (XtIsRealized((Widget)ctx)(XtWindowOfObject((Widget)ctx) != 0L)) {
503 XtRealizeWidget(hbar);
504 XtMapWidget(hbar)XMapWindow((((hbar)->core.screen)->display), ((hbar)->
core.window))
;
505 }
506}
507
508/* Function Name: DestroyHScrollBar
509 * Description: Removes a horizontal ScrollBar.
510 * Arguments: ctx - the parent text widget.
511 * Returns: none.
512 */
513
514static void
515DestroyHScrollBar(TextWidget ctx)
516{
517 Widget hbar = ctx->text.hbar;
518
519 if (hbar == NULL((void*)0)) return;
520
521/**/
522 ctx->text.r_margin.bottom -= hbar->core.height + hbar->core.border_width;
523 ctx->text.margin.bottom = ctx->text.r_margin.bottom;
524/**/
525 if (ctx->text.vbar == NULL((void*)0))
526 XtRemoveCallback((Widget) ctx, XtNunrealizeCallback((char*)&XtStrings[815]), UnrealizeScrollbars,
527 (XtPointer) NULL((void*)0));
528 XtDestroyWidget(hbar);
529 ctx->text.hbar = NULL((void*)0);
530}
531
532/* ARGSUSED */
533static void
534Initialize(Widget request, Widget new, ArgList args, Cardinal *num_args)
535{
536 TextWidget ctx = (TextWidget) new;
537 char error_buf[BUFSIZ1024];
538 int s;
539
540 ctx->text.threeD = XtVaCreateWidget("threeD", threeDWidgetClass, new,
541 XtNx((char*)&XtStrings[885]), 0, XtNy((char*)&XtStrings[887]), 0,
542 XtNwidth((char*)&XtStrings[872]), 10, XtNheight((char*)&XtStrings[234]), 10, /* dummy */
543 NULL((void*)0));
544
545 s = ((ThreeDWidget)ctx->text.threeD)->threeD.shadow_width;
546
547 ctx->text.r_margin.left += s;
548 ctx->text.r_margin.right += s;
549 ctx->text.r_margin.top += s;
550 ctx->text.r_margin.bottom += s - 1;
551
552 ctx->text.lt.lines = 0;
553 ctx->text.lt.info = NULL((void*)0);
554 memset(&(ctx->text.origSel), 0, sizeof(XawTextSelection))__builtin___memset_chk (&(ctx->text.origSel), 0, sizeof
(XawTextSelection), __builtin_object_size (&(ctx->text
.origSel), 0))
;
555 memset(&(ctx->text.s), 0, sizeof(XawTextSelection))__builtin___memset_chk (&(ctx->text.s), 0, sizeof(XawTextSelection
), __builtin_object_size (&(ctx->text.s), 0))
;
556 ctx->text.s.type = XawselectPosition;
557 ctx->text.salt = NULL((void*)0);
558 ctx->text.hbar = ctx->text.vbar = (Widget) NULL((void*)0);
559 ctx->text.lasttime = 0; /* ||| correct? */
560 ctx->text.time = 0; /* ||| correct? */
561 ctx->text.showposition = TRUE1;
562 ctx->text.lastPos = (ctx->text.source != NULL((void*)0)) ? GETLASTPOSXawTextSourceScan(ctx->text.source, 0, XawstAll, XawsdRight
, 1, 1)
: 0;
563 ctx->text.file_insert = NULL((void*)0);
564 ctx->text.search = NULL((void*)0);
565 ctx->text.updateFrom = (XawTextPosition *) XtMalloc((unsigned) ONE((Cardinal)1));
566 ctx->text.updateTo = (XawTextPosition *) XtMalloc((unsigned) ONE((Cardinal)1));
567 ctx->text.numranges = ctx->text.maxranges = 0;
568 ctx->text.gc = DefaultGCOfScreen(XtScreen(ctx))((((ctx)->core.screen))->default_gc);
569 ctx->text.hasfocus = FALSE0;
570 ctx->text.margin = ctx->text.r_margin; /* Strucure copy. */
571 ctx->text.update_disabled = FALSE0;
572 ctx->text.old_insert = -1;
573 ctx->text.mult = 1;
574 ctx->text.single_char = FALSE0;
575 ctx->text.copy_area_offsets = NULL((void*)0);
576 ctx->text.salt2 = NULL((void*)0);
577
578 if (ctx->core.height == DEFAULT_TEXT_HEIGHT((Dimension)~0)) {
579 ctx->core.height = VMargins(ctx)( (ctx)->text.margin.top + (ctx)->text.margin.bottom );
580 if (ctx->text.sink != NULL((void*)0))
581 ctx->core.height += XawTextSinkMaxHeight(ctx->text.sink, 1);
582 }
583
584 if (ctx->text.scroll_vert != XawtextScrollNever) {
585 if ( (ctx->text.resize == XawtextResizeHeight) ||
586 (ctx->text.resize == XawtextResizeBoth) ) {
587 (void) sprintf(error_buf, "Xaw Text Widget %s:\n %s %s.", ctx->core.name,__builtin___sprintf_chk (error_buf, 0, __builtin_object_size (
error_buf, 2 > 1 ? 1 : 0), "Xaw Text Widget %s:\n %s %s.",
ctx->core.name, "Vertical scrolling not allowed with height resize.\n"
, "Vertical scrolling has been DEACTIVATED.")
588 "Vertical scrolling not allowed with height resize.\n",__builtin___sprintf_chk (error_buf, 0, __builtin_object_size (
error_buf, 2 > 1 ? 1 : 0), "Xaw Text Widget %s:\n %s %s.",
ctx->core.name, "Vertical scrolling not allowed with height resize.\n"
, "Vertical scrolling has been DEACTIVATED.")
589 "Vertical scrolling has been DEACTIVATED.")__builtin___sprintf_chk (error_buf, 0, __builtin_object_size (
error_buf, 2 > 1 ? 1 : 0), "Xaw Text Widget %s:\n %s %s.",
ctx->core.name, "Vertical scrolling not allowed with height resize.\n"
, "Vertical scrolling has been DEACTIVATED.")
;
590 XtAppWarning(XtWidgetToApplicationContext(new), error_buf);
591 ctx->text.scroll_vert = XawtextScrollNever;
592 }
593 else if (ctx->text.scroll_vert == XawtextScrollAlways)
594 CreateVScrollBar(ctx);
595 }
596
597 if (ctx->text.scroll_horiz != XawtextScrollNever) {
598 if (ctx->text.wrap != XawtextWrapNever) {
599 (void) sprintf(error_buf, "Xaw Text Widget %s:\n %s %s.", ctx->core.name,__builtin___sprintf_chk (error_buf, 0, __builtin_object_size (
error_buf, 2 > 1 ? 1 : 0), "Xaw Text Widget %s:\n %s %s.",
ctx->core.name, "Horizontal scrolling not allowed with wrapping active.\n"
, "Horizontal scrolling has been DEACTIVATED.")
600 "Horizontal scrolling not allowed with wrapping active.\n",__builtin___sprintf_chk (error_buf, 0, __builtin_object_size (
error_buf, 2 > 1 ? 1 : 0), "Xaw Text Widget %s:\n %s %s.",
ctx->core.name, "Horizontal scrolling not allowed with wrapping active.\n"
, "Horizontal scrolling has been DEACTIVATED.")
601 "Horizontal scrolling has been DEACTIVATED.")__builtin___sprintf_chk (error_buf, 0, __builtin_object_size (
error_buf, 2 > 1 ? 1 : 0), "Xaw Text Widget %s:\n %s %s.",
ctx->core.name, "Horizontal scrolling not allowed with wrapping active.\n"
, "Horizontal scrolling has been DEACTIVATED.")
;
602 XtAppWarning(XtWidgetToApplicationContext(new), error_buf);
603 ctx->text.scroll_horiz = XawtextScrollNever;
604 }
605 else if ( (ctx->text.resize == XawtextResizeWidth) ||
606 (ctx->text.resize == XawtextResizeBoth) ) {
607 (void) sprintf(error_buf, "Xaw Text Widget %s:\n %s %s.", ctx->core.name,__builtin___sprintf_chk (error_buf, 0, __builtin_object_size (
error_buf, 2 > 1 ? 1 : 0), "Xaw Text Widget %s:\n %s %s.",
ctx->core.name, "Horizontal scrolling not allowed with width resize.\n"
, "Horizontal scrolling has been DEACTIVATED.")
608 "Horizontal scrolling not allowed with width resize.\n",__builtin___sprintf_chk (error_buf, 0, __builtin_object_size (
error_buf, 2 > 1 ? 1 : 0), "Xaw Text Widget %s:\n %s %s.",
ctx->core.name, "Horizontal scrolling not allowed with width resize.\n"
, "Horizontal scrolling has been DEACTIVATED.")
609 "Horizontal scrolling has been DEACTIVATED.")__builtin___sprintf_chk (error_buf, 0, __builtin_object_size (
error_buf, 2 > 1 ? 1 : 0), "Xaw Text Widget %s:\n %s %s.",
ctx->core.name, "Horizontal scrolling not allowed with width resize.\n"
, "Horizontal scrolling has been DEACTIVATED.")
;
610 XtAppWarning(XtWidgetToApplicationContext(new), error_buf);
611 ctx->text.scroll_horiz = XawtextScrollNever;
612 }
613 else if (ctx->text.scroll_horiz == XawtextScrollAlways)
614 CreateHScrollBar(ctx);
615 }
616}
617
618static void
619Realize(Widget w, Mask *valueMask, XSetWindowAttributes *attributes)
620{
621 TextWidget ctx = (TextWidget)w;
622
623 (*textClassRec.core_class.superclass->core_class.realize)
624 (w, valueMask, attributes);
625
626 if (ctx->text.hbar != NULL((void*)0)) { /* Put up Hbar -- Must be first. */
627 XtRealizeWidget(ctx->text.hbar);
628 XtMapWidget(ctx->text.hbar)XMapWindow((((ctx->text.hbar)->core.screen)->display
), ((ctx->text.hbar)->core.window))
;
629 }
630
631 if (ctx->text.vbar != NULL((void*)0)) { /* Put up Vbar. */
632 XtRealizeWidget(ctx->text.vbar);
633 XtMapWidget(ctx->text.vbar)XMapWindow((((ctx->text.vbar)->core.screen)->display
), ((ctx->text.vbar)->core.window))
;
634 }
635
636 _XawTextBuildLineTable(ctx, ctx->text.lt.top, TRUE1);
637 _XawTextSetScrollBars(ctx);
638 _XawTextCheckResize(ctx);
639}
640
641/*ARGSUSED*/
642static void
643UnrealizeScrollbars(Widget widget, XtPointer client, XtPointer call)
644{
645 TextWidget ctx = (TextWidget) widget;
646
647 if (ctx->text.hbar)
648 XtUnrealizeWidget(ctx->text.hbar);
649 if (ctx->text.vbar)
650 XtUnrealizeWidget(ctx->text.vbar);
651}
652
653/* Utility routines for support of Text */
654
655static void
656_CreateCutBuffers(Display *d)
657{
658 static struct _DisplayRec {
659 struct _DisplayRec *next;
660 Display *dpy;
661 } *dpy_list = NULL((void*)0);
662 struct _DisplayRec *dpy_ptr;
663
664 for (dpy_ptr = dpy_list; dpy_ptr != NULL((void*)0); dpy_ptr = dpy_ptr->next)
665 if (dpy_ptr->dpy == d) return;
666
667 dpy_ptr = XtNew(struct _DisplayRec)((struct _DisplayRec *) XtMalloc((unsigned) sizeof(struct _DisplayRec
)))
;
668 dpy_ptr->next = dpy_list;
669 dpy_ptr->dpy = d;
670 dpy_list = dpy_ptr;
671
672#define Create(buffer) \
673 XChangeProperty(d, RootWindow(d, 0)((&((_XPrivDisplay)(d))->screens[0])->root), buffer, XA_STRING((Atom) 31), 8, \
674 PropModeAppend2, NULL((void*)0), 0 );
675
676 Create( XA_CUT_BUFFER0((Atom) 9) );
677 Create( XA_CUT_BUFFER1((Atom) 10) );
678 Create( XA_CUT_BUFFER2((Atom) 11) );
679 Create( XA_CUT_BUFFER3((Atom) 12) );
680 Create( XA_CUT_BUFFER4((Atom) 13) );
681 Create( XA_CUT_BUFFER5((Atom) 14) );
682 Create( XA_CUT_BUFFER6((Atom) 15) );
683 Create( XA_CUT_BUFFER7((Atom) 16) );
684
685#undef Create
686}
687
688/*
689 * Procedure to manage insert cursor visibility for editable text. It uses
690 * the value of ctx->insertPos and an implicit argument. In the event that
691 * position is immediately preceded by an eol graphic, then the insert cursor
692 * is displayed at the beginning of the next line.
693*/
694static void
695InsertCursor (Widget w, XawTextInsertState state)
696{
697 TextWidget ctx = (TextWidget)w;
698 Position x, y;
699 int line;
700
701 if (ctx->text.lt.lines < 1) return;
702
703 if ( LineAndXYForPosition(ctx, ctx->text.insertPos, &line, &x, &y) ) {
704 if (line < ctx->text.lt.lines)
705 y += (ctx->text.lt.info[line + 1].y - ctx->text.lt.info[line].y) + 1;
706 else
707 y += (ctx->text.lt.info[line].y - ctx->text.lt.info[line - 1].y) + 1;
708
709 if (ctx->text.display_caret)
710 XawTextSinkInsertCursor(ctx->text.sink, x, y, state);
711 }
712 ctx->text.ev_x = x;
713 ctx->text.ev_y = y;
714
715 /* Keep Input Method up to speed */
716
717#ifdef XAW_INTERNATIONALIZATION1
718 if ( ctx->simple.international ) {
719 Arg list[1];
720
721 XtSetArg (list[0], XtNinsertPosition, ctx->text.insertPos)((void)( (list[0]).name = (((char*)&XtStrings[326])), (list
[0]).value = (XtArgVal)(ctx->text.insertPos) ))
;
722 _XawImSetValues (w, list, 1);
723 }
724#endif
725}
726
727/*
728 * Procedure to register a span of text that is no longer valid on the display
729 * It is used to avoid a number of small, and potentially overlapping, screen
730 * updates.
731*/
732
733void
734_XawTextNeedsUpdating(TextWidget ctx, XawTextPosition left, XawTextPosition right)
735{
736 int i;
737 if (left < right) {
738 for (i = 0; i < ctx->text.numranges; i++) {
739 if (left <= ctx->text.updateTo[i] && right >= ctx->text.updateFrom[i]) {
740 ctx->text.updateFrom[i] = Min(left, ctx->text.updateFrom[i])(((left) < (ctx->text.updateFrom[i])) ? (left) : (ctx->
text.updateFrom[i]))
;
741 ctx->text.updateTo[i] = Max(right, ctx->text.updateTo[i])(((right) > (ctx->text.updateTo[i])) ? (right) : (ctx->
text.updateTo[i]))
;
742 return;
743 }
744 }
745 ctx->text.numranges++;
746 if (ctx->text.numranges > ctx->text.maxranges) {
747 ctx->text.maxranges = ctx->text.numranges;
748 i = ctx->text.maxranges * sizeof(XawTextPosition);
749 ctx->text.updateFrom = (XawTextPosition *)
750 XtRealloc((char *)ctx->text.updateFrom, (unsigned) i);
751 ctx->text.updateTo = (XawTextPosition *)
752 XtRealloc((char *)ctx->text.updateTo, (unsigned) i);
753 }
754 ctx->text.updateFrom[ctx->text.numranges - 1] = left;
755 ctx->text.updateTo[ctx->text.numranges - 1] = right;
756 }
757}
758
759/*
760 * Procedure to read a span of text in Ascii form. This is purely a hack and
761 * we probably need to add a function to sources to provide this functionality.
762 * [note: this is really a private procedure but is used in multiple modules].
763 */
764
765char *
766_XawTextGetText(TextWidget ctx, XawTextPosition left, XawTextPosition right)
767{
768 char *result, *tempResult;
769 XawTextBlock text;
770 int bytes;
771
772 if (_XawTextFormat(ctx) == XawFmt8Bit)
773 bytes = sizeof(unsigned char);
774#ifdef XAW_INTERNATIONALIZATION1
775 else if (_XawTextFormat(ctx) == XawFmtWide)
776 bytes = sizeof(wchar_t);
777#endif
778 else /* if there is another fomat, add here */
779 bytes = 1;
780
781 /* leave space for ZERO */
782 tempResult=result=XtMalloc( (unsigned)(((Cardinal)(right-left))+ONE((Cardinal)1) )* bytes);
783 while (left < right) {
784 left = SrcReadXawTextSourceRead(ctx->text.source, left, &text, (int)(right - left));
785 if (!text.length)
786 break;
787 memmove(tempResult, text.ptr, text.length * bytes)__builtin___memmove_chk (tempResult, text.ptr, text.length * bytes
, __builtin_object_size (tempResult, 0))
;
788 tempResult += text.length * bytes;
789 }
790
791 if (bytes == sizeof(wchar_t))
792 *((wchar_t*)tempResult) = (wchar_t)0;
793 else
794 *tempResult = '\0';
795 return(result);
796}
797
798/* Like _XawTextGetText, but enforces ICCCM STRING type encoding. This
799routine is currently used to put just the ASCII chars in the selection into a
800cut buffer. */
801
802char *
803_XawTextGetSTRING(TextWidget ctx, XawTextPosition left, XawTextPosition right)
804{
805 unsigned char *s;
806 unsigned char c;
807 long i, j, n;
808
809 /* allow ESC in accordance with ICCCM */
810#ifdef XAW_INTERNATIONALIZATION1
811 if (_XawTextFormat(ctx) == XawFmtWide) {
812 MultiSinkObject sink = (MultiSinkObject) ctx->text.sink;
813 wchar_t *ws, wc;
814 ws = (wchar_t *)_XawTextGetText(ctx, left, right);
815 n = wcslen(ws);
816 for (j = 0, i = 0; j < n; j++) {
817 wc = ws[j];
818 if (XwcTextEscapement (sink->multi_sink.fontset, &wc, 1) ||
819 (wc == _Xaw_atowc(XawTAB0x09)) || (wc == _Xaw_atowc(XawLF0x0a)) || (wc == _Xaw_atowc(XawESC0x1b)))
820 ws[i++] = wc;
821 }
822 ws[i] = (wchar_t)0;
823 return (char *)ws;
824 } else
825#endif
826 {
827 s = (unsigned char *)_XawTextGetText(ctx, left, right);
828 /* only HT and NL control chars are allowed, strip out others */
829 n = strlen((char *)s);
830 i = 0;
831 for (j = 0; j < n; j++) {
832 c = s[j];
833 if (((c >= 0x20) && c <= 0x7f) ||
834 (c >= 0xa0) || (c == XawTAB0x09) || (c == XawLF0x0a) || (c == XawESC0x1b)) {
835 s[i] = c;
836 i++;
837 }
838 }
839 s[i] = 0;
840 return (char *)s;
841 }
842#undef ESC
843
844}
845
846/*
847 * This routine maps an x and y position in a window that is displaying text
848 * into the corresponding position in the source.
849 *
850 * NOTE: it is illegal to call this routine unless there is a valid line table!
851 */
852
853/*** figure out what line it is on ***/
854
855static XawTextPosition
856PositionForXY (TextWidget ctx, Position x, Position y)
857{
858 int fromx, line, width, height;
859 XawTextPosition position;
860
861 if (ctx->text.lt.lines == 0) return 0;
862
863 for (line = 0; line < ctx->text.lt.lines - 1; line++) {
864 if (y <= ctx->text.lt.info[line + 1].y)
865 break;
866 }
867 position = ctx->text.lt.info[line].position;
868 if (position >= ctx->text.lastPos)
869 return(ctx->text.lastPos);
870 fromx = (int) ctx->text.margin.left;
871 XawTextSinkFindPosition( ctx->text.sink, position, fromx, x - fromx,
872 FALSE0, &position, &width, &height);
873 if (position > ctx->text.lastPos) return(ctx->text.lastPos);
874 if (position >= ctx->text.lt.info[line + 1].position)
875 position = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.lt.info[line + 1].position,
876 XawstPositions, XawsdLeft, 1, TRUE1);
877 return(position);
878}
879
880/*
881 * This routine maps a source position in to the corresponding line number
882 * of the text that is displayed in the window.
883 *
884 * NOTE: It is illegal to call this routine unless there is a valid line table!
885 */
886
887static int
888LineForPosition (TextWidget ctx, XawTextPosition position)
889{
890 int line;
891
892 for (line = 0; line < ctx->text.lt.lines; line++)
893 if (position < ctx->text.lt.info[line + 1].position)
894 break;
895 return(line);
896}
897
898/*
899 * This routine maps a source position into the corresponding line number
900 * and the x, y coordinates of the text that is displayed in the window.
901 *
902 * NOTE: It is illegal to call this routine unless there is a valid line table!
903 */
904
905static Boolean
906LineAndXYForPosition(TextWidget ctx, XawTextPosition pos, int *line,
907 Position *x, Position *y)
908{
909 XawTextPosition linePos, endPos;
910 Boolean visible;
911 int realW, realH;
912
913 *line = 0;
914 *x = ctx->text.margin.left;
915 *y = ctx->text.margin.top;
916 if ((visible = IsPositionVisible(ctx, pos)(pos >= ctx->text.lt.info[0].position && pos <
ctx->text.lt.info[ctx->text.lt.lines].position)
)) {
917 *line = LineForPosition(ctx, pos);
918 *y = ctx->text.lt.info[*line].y;
919 *x = ctx->text.margin.left;
920 linePos = ctx->text.lt.info[*line].position;
921 XawTextSinkFindDistance( ctx->text.sink, linePos,
922 *x, pos, &realW, &endPos, &realH);
923 *x += realW;
924 }
925 return(visible);
926}
927
928/*
929 * This routine builds a line table. It does this by starting at the
930 * specified position and measuring text to determine the staring position
931 * of each line to be displayed. It also determines and saves in the
932 * linetable all the required metrics for displaying a given line (e.g.
933 * x offset, y offset, line length, etc.).
934 */
935
936void
937_XawTextBuildLineTable (
938 TextWidget ctx,
939 XawTextPosition position,
940 _XtBooleanint force_rebuild)
941{
942 Dimension height = 0;
943 int lines = 0;
944 Cardinal size;
945
946 if ((int)ctx->core.height > VMargins(ctx)( (ctx)->text.margin.top + (ctx)->text.margin.bottom )) {
947 height = ctx->core.height - VMargins(ctx)( (ctx)->text.margin.top + (ctx)->text.margin.bottom );
948 lines = XawTextSinkMaxLines(ctx->text.sink, height);
949 }
950 size = sizeof(XawTextLineTableEntry) * (lines + 1);
951
952 if ( (lines != ctx->text.lt.lines) || (ctx->text.lt.info == NULL((void*)0)) ) {
953 ctx->text.lt.info = (XawTextLineTableEntry *) XtRealloc((char *) ctx->text.
954 lt.info, size);
955 ctx->text.lt.lines = lines;
956 force_rebuild = TRUE1;
957 }
958
959 if ( force_rebuild || (position != ctx->text.lt.top) ) {
960 memset(ctx->text.lt.info, 0, size)__builtin___memset_chk (ctx->text.lt.info, 0, size, __builtin_object_size
(ctx->text.lt.info, 0))
;
961 (void) _BuildLineTable(ctx, ctx->text.lt.top = position, zeroPosition((XawTextPosition) 0), 0);
962 }
963}
964
965/*
966 * This assumes that the line table does not change size.
967 */
968
969static XawTextPosition
970_BuildLineTable(TextWidget ctx, XawTextPosition position,
971 XawTextPosition min_pos, int line)
972{
973 XawTextLineTableEntry * lt = ctx->text.lt.info + line;
974 XawTextPosition endPos;
975 Position y;
976 int count, width, realW, realH;
977 Widget src = ctx->text.source;
978
979 if ( ((ctx->text.resize == XawtextResizeWidth) ||
980 (ctx->text.resize == XawtextResizeBoth) ) ||
981 (ctx->text.wrap == XawtextWrapNever) )
982 width = BIGNUM((Dimension)32023);
983 else
984 width = Max(0, ((int)ctx->core.width - (int)HMargins(ctx)))(((0) > (((int)ctx->core.width - (int)( (ctx)->text.
margin.left + (ctx)->text.margin.right )))) ? (0) : (((int
)ctx->core.width - (int)( (ctx)->text.margin.left + (ctx
)->text.margin.right ))))
;
985
986 y = ( (line == 0) ? ctx->text.margin.top : lt->y );
987
988 /* CONSTCOND */
989 while ( TRUE1 ) {
990 lt->y = y;
991 lt->position = position;
992
993 XawTextSinkFindPosition( ctx->text.sink, position, ctx->text.margin.left,
994 width, ctx->text.wrap == XawtextWrapWord,
995 &endPos, &realW, &realH);
996 lt->textWidth = realW;
997 y += realH;
998
999 if (ctx->text.wrap == XawtextWrapNever)
1000 endPos = SrcScanXawTextSourceScan(src, position, XawstEOL, XawsdRight, 1, TRUE1);
1001
1002 if ( endPos == ctx->text.lastPos) { /* We have reached the end. */
1003 if(SrcScanXawTextSourceScan(src, position, XawstEOL, XawsdRight, 1, FALSE0) == endPos)
1004 break;
1005 }
1006
1007 ++lt;
1008 ++line;
1009 if ( (line > ctx->text.lt.lines) ||
1010 ((lt->position == (position = endPos)) && (position > min_pos)) )
1011 return(position);
1012 }
1013
1014/*
1015 * If we are at the end of the buffer put two special lines in the table.
1016 *
1017 * a) Both have position > text.lastPos and lt->textWidth = 0.
1018 * b) The first has a real height, and the second has a height that
1019 * is the rest of the screen.
1020 *
1021 * I could fill in the rest of the table with valid heights and a large
1022 * lastPos, but this method keeps the number of fill regions down to a
1023 * minimum.
1024 *
1025 * One valid entry is needed at the end of the table so that the cursor
1026 * does not jump off the bottom of the window.
1027 */
1028
1029 for ( count = 0; count < 2 ; count++)
1030 if (line++ < ctx->text.lt.lines) { /* make sure not to run of the end. */
1031 (++lt)->y = (count == 0) ? y : ctx->core.height
1032 - 2 * ((ThreeDWidget)ctx->text.threeD)->threeD.shadow_width;
1033 lt->textWidth = 0;
1034 lt->position = ctx->text.lastPos + 100;
1035 }
1036
1037 if (line < ctx->text.lt.lines) /* Clear out rest of table. */
1038 memset((lt + 1), 0,__builtin___memset_chk ((lt + 1), 0, (ctx->text.lt.lines -
line) * sizeof(XawTextLineTableEntry), __builtin_object_size
((lt + 1), 0))
1039 (ctx->text.lt.lines - line) * sizeof(XawTextLineTableEntry) )__builtin___memset_chk ((lt + 1), 0, (ctx->text.lt.lines -
line) * sizeof(XawTextLineTableEntry), __builtin_object_size
((lt + 1), 0))
;
1040
1041 ctx->text.lt.info[ctx->text.lt.lines].position = lt->position;
1042
1043 return(endPos);
1044}
1045
1046/* Function Name: GetWidestLine
1047 * Description: Returns the width (in pixels) of the widest line that
1048 * is currently visable.
1049 * Arguments: ctx - the text widget.
1050 * Returns: the width of the widest line.
1051 *
1052 * NOTE: This function requires a valid line table.
1053 */
1054
1055static Dimension
1056GetWidestLine(TextWidget ctx)
1057{
1058 int i;
1059 Dimension widest;
1060 XawTextLineTablePtr lt = &(ctx->text.lt);
1061
1062 for (i = 0, widest = 1 ; i < lt->lines ; i++)
1063 if (widest < lt->info[i].textWidth)
1064 widest = lt->info[i].textWidth;
1065
1066 return(widest);
1067}
1068
1069static void
1070CheckVBarScrolling(TextWidget ctx)
1071{
1072 float first, last;
1073 Boolean temp = (ctx->text.vbar == NULL((void*)0));
1074
1075 if (ctx->text.scroll_vert == XawtextScrollNever) return;
1076
1077 if ( (ctx->text.lastPos > 0) && (ctx->text.lt.lines > 0)) {
1078 first = ctx->text.lt.top;
1079 first /= (float) ctx->text.lastPos;
1080 last = ctx->text.lt.info[ctx->text.lt.lines].position;
1081 if ( ctx->text.lt.info[ctx->text.lt.lines].position < ctx->text.lastPos )
1082 last /= (float) ctx->text.lastPos;
1083 else
1084 last = 1.0;
1085
1086 if (ctx->text.scroll_vert == XawtextScrollWhenNeeded) {
1087 int line;
1088 XawTextPosition last_pos;
1089 Position y = ctx->core.height - ctx->text.margin.bottom;
1090
1091 if (ctx->text.hbar != NULL((void*)0))
1092 y -= (ctx->text.hbar->core.height +
1093 2 * ctx->text.hbar->core.border_width);
1094
1095 last_pos = PositionForXY(ctx, (Position) ctx->core.width, y);
1096 line = LineForPosition(ctx, last_pos);
1097
1098 if ( (y < ctx->text.lt.info[line + 1].y) || ((last - first) < 1.0) )
1099 CreateVScrollBar(ctx);
1100 else
1101 DestroyVScrollBar(ctx);
1102 }
1103
1104 if (ctx->text.vbar != NULL((void*)0))
1105 XawScrollbarSetThumb(ctx->text.vbar, first, last - first);
1106
1107 if ( (ctx->text.vbar == NULL((void*)0)) != temp) {
1108 _XawTextNeedsUpdating(ctx, zeroPosition((XawTextPosition) 0), ctx->text.lastPos);
1109 if (ctx->text.vbar == NULL((void*)0))
1110 _XawTextBuildLineTable (ctx, zeroPosition((XawTextPosition) 0), FALSE0);
1111 }
1112 }
1113 else if (ctx->text.vbar != NULL((void*)0)) {
1114 if (ctx->text.scroll_vert == XawtextScrollWhenNeeded)
1115 DestroyVScrollBar(ctx);
1116 else if (ctx->text.scroll_vert == XawtextScrollAlways)
1117 XawScrollbarSetThumb(ctx->text.vbar, 0.0, 1.0);
1118 }
1119}
1120
1121/*
1122 * This routine is used by Text to notify an associated scrollbar of the
1123 * correct metrics (position and shown fraction) for the text being currently
1124 * displayed in the window.
1125 */
1126
1127void
1128_XawTextSetScrollBars(TextWidget ctx)
1129{
1130 float first, last, widest;
1131 Boolean temp = (ctx->text.hbar == NULL((void*)0));
1132 Boolean vtemp = (ctx->text.vbar == NULL((void*)0));
1133 int s = ((ThreeDWidget)ctx->text.threeD)->threeD.shadow_width;
1134
1135 CheckVBarScrolling(ctx);
1136
1137 if (ctx->text.scroll_horiz == XawtextScrollNever) return;
1138
1139 if (ctx->text.vbar != NULL((void*)0))
1140 widest = (int)(ctx->core.width - ctx->text.vbar->core.width -
1141 2 * s - ctx->text.vbar->core.border_width);
1142 else
1143 widest = ctx->core.width - 2 * s;
1144 widest /= (last = GetWidestLine(ctx));
1145 if (ctx->text.scroll_horiz == XawtextScrollWhenNeeded) {
1146 if (widest < 1.0)
1147 CreateHScrollBar(ctx);
1148 else
1149 DestroyHScrollBar(ctx);
1150 }
1151
1152 if ( (ctx->text.hbar == NULL((void*)0)) != temp ) {
1153 _XawTextBuildLineTable (ctx, ctx->text.lt.top, TRUE1);
1154 CheckVBarScrolling(ctx); /* Recheck need for vbar, now that we added
1155 or removed the hbar.*/
1156 }
1157
1158 if (ctx->text.hbar != NULL((void*)0)) {
1159 first = ctx->text.r_margin.left - ctx->text.margin.left;
1160 first /= last;
1161 XawScrollbarSetThumb(ctx->text.hbar, first, widest);
1162 }
1163
1164 if (((ctx->text.hbar == NULL((void*)0)) && (ctx->text.margin.left !=
1165 ctx->text.r_margin.left)) ||
1166 (ctx->text.vbar == NULL((void*)0)) != vtemp)
1167 {
1168 ctx->text.margin.left = ctx->text.r_margin.left;
1169 _XawTextNeedsUpdating(ctx, zeroPosition((XawTextPosition) 0), ctx->text.lastPos);
1170 FlushUpdate(ctx);
1171 }
1172}
1173
1174/*
1175 * The routine will scroll the displayed text by lines. If the arg is
1176 * positive, move up; otherwise, move down. [note: this is really a private
1177 * procedure but is used in multiple modules].
1178 */
1179
1180void
1181_XawTextVScroll(TextWidget ctx, int n)
1182{
1183 XawTextPosition top, target;
1184 int y;
1185 Arg list[1];
1186 XawTextLineTable * lt = &(ctx->text.lt);
1187 int s = ((ThreeDWidget)ctx->text.threeD)->threeD.shadow_width;
1188
1189 if (abs(n) > ctx->text.lt.lines)
1190 n = (n > 0) ? ctx->text.lt.lines : -ctx->text.lt.lines;
1191
1192 if (n == 0) return;
1193
1194 if (n > 0) {
1195 if ( IsValidLine(ctx, n)( ((n) == 0) || ((ctx)->text.lt.info[(n)].position != 0) ) )
1196 top = Min(lt->info[n].position, ctx->text.lastPos)(((lt->info[n].position) < (ctx->text.lastPos)) ? (lt
->info[n].position) : (ctx->text.lastPos))
;
1197 else
1198 top = ctx->text.lastPos;
1199
1200 y = IsValidLine(ctx, n)( ((n) == 0) || ((ctx)->text.lt.info[(n)].position != 0) ) ? lt->info[n].y : ctx->core.height - 2 * s;
1201 _XawTextBuildLineTable(ctx, top, FALSE0);
1202 if (top >= ctx->text.lastPos)
1203 DisplayTextWindow( (Widget) ctx);
1204 else {
1205 XCopyArea(XtDisplay(ctx)(((ctx)->core.screen)->display), XtWindow(ctx)((ctx)->core.window), XtWindow(ctx)((ctx)->core.window), ctx->text.gc,
1206 s, y, (int)ctx->core.width - 2 * s, (int)ctx->core.height - y - s,
1207 s, ctx->text.margin.top);
1208
1209 PushCopyQueue(ctx, 0, (int) -y);
1210 SinkClearToBGXawTextSinkClearToBackground(ctx->text.sink,
1211 (Position) s,
1212 (Position) (ctx->text.margin.top + ctx->core.height - y - s),
1213 (Dimension) ctx->core.width - 2 * s,
1214 (Dimension) ctx->core.height - 2 * s);
1215
1216 if (n < lt->lines) n++; /* update descenders at bottom */
1217 _XawTextNeedsUpdating(ctx, lt->info[lt->lines - n].position,
1218 ctx->text.lastPos);
1219 _XawTextSetScrollBars(ctx);
1220 }
1221 }
1222 else {
1223 XawTextPosition updateTo;
1224 unsigned int height, clear_height;
1225
1226 n = -n;
1227 target = lt->top;
1228 top = SrcScanXawTextSourceScan(ctx->text.source, target, XawstEOL,
1229 XawsdLeft, n+1, FALSE0);
1230
1231 _XawTextBuildLineTable(ctx, top, FALSE0);
1232 y = IsValidLine(ctx, n)( ((n) == 0) || ((ctx)->text.lt.info[(n)].position != 0) ) ? lt->info[n].y : ctx->core.height - 2 * s;
1233 updateTo = IsValidLine(ctx, n)( ((n) == 0) || ((ctx)->text.lt.info[(n)].position != 0) ) ? lt->info[n].position : ctx->text.lastPos;
1234 if (IsValidLine(ctx, lt->lines - n)( ((lt->lines - n) == 0) || ((ctx)->text.lt.info[(lt->
lines - n)].position != 0) )
)
1235 height = lt->info[lt->lines-n].y - ctx->text.margin.top;
1236 else if (ctx->core.height - HMargins(ctx)( (ctx)->text.margin.left + (ctx)->text.margin.right ))
1237 height = ctx->core.height - HMargins(ctx)( (ctx)->text.margin.left + (ctx)->text.margin.right );
1238 else
1239 height = 0;
1240 if (y > (int) ctx->text.margin.top)
1241 clear_height = y - ctx->text.margin.top;
1242 else
1243 clear_height = 0;
1244
1245 if ( updateTo == target ) {
1246 XCopyArea(XtDisplay(ctx)(((ctx)->core.screen)->display), XtWindow(ctx)((ctx)->core.window), XtWindow(ctx)((ctx)->core.window), ctx->text.gc,
1247 s, ctx->text.margin.top, (int) ctx->core.width - 2 * s,
1248 height, s, y);
1249 PushCopyQueue(ctx, 0, (int) y);
1250 SinkClearToBGXawTextSinkClearToBackground(ctx->text.sink, (Position) s, ctx->text.margin.top,
1251 (Dimension) ctx->core.width - 2 * s, (Dimension) clear_height);
1252
1253 _XawTextNeedsUpdating(ctx, lt->info[0].position, updateTo);
1254 _XawTextSetScrollBars(ctx);
1255 }
1256 else if (lt->top != target)
1257 DisplayTextWindow((Widget)ctx);
1258 }
1259 XtSetArg (list[0], XtNinsertPosition, ctx->text.lt.top+ctx->text.lt.lines)((void)( (list[0]).name = (((char*)&XtStrings[326])), (list
[0]).value = (XtArgVal)(ctx->text.lt.top+ctx->text.lt.lines
) ))
;
1260#ifdef XAW_INTERNATIONALIZATION1
1261 _XawImSetValues ((Widget) ctx, list, 1);
1262#endif
1263
1264 _ShadowSurroundedBox((Widget)ctx, (ThreeDWidget)ctx->text.threeD,
1265 0, 0, ctx->core.width, ctx->core.height,
1266 ((ThreeDWidget)ctx->text.threeD)->threeD.relief, False0);
1267}
1268
1269/*ARGSUSED*/
1270static void
1271HScroll(Widget w, XtPointer closure, XtPointer callData)
1272{
1273 TextWidget ctx = (TextWidget) closure;
1274 Widget tw = (Widget) ctx;
1275 Position old_left, pixels = (Position)(intptr_t) callData;
1276 XRectangle rect, t_rect;
1277 int s = ((ThreeDWidget)ctx->text.threeD)->threeD.shadow_width;
1278
1279 _XawTextPrepareToUpdate(ctx);
1280
1281 old_left = ctx->text.margin.left;
1282 ctx->text.margin.left -= pixels;
1283 if (ctx->text.margin.left > ctx->text.r_margin.left) {
1284 ctx->text.margin.left = ctx->text.r_margin.left;
1285 pixels = old_left - ctx->text.margin.left;
1286 }
1287
1288 if (pixels > 0) {
1289 rect.width = (unsigned short) pixels + ctx->text.margin.right;
1290 rect.x = (short) ctx->core.width - (short) rect.width;
1291 rect.y = (short) ctx->text.margin.top;
1292 rect.height = (unsigned short) ctx->core.height - rect.y - 2 * s;
1293
1294 XCopyArea(XtDisplay(tw)(((tw)->core.screen)->display), XtWindow(tw)((tw)->core.window), XtWindow(tw)((tw)->core.window), ctx->text.gc,
1295 pixels + s, (int) rect.y,
1296 (unsigned int) rect.x, (unsigned int) ctx->core.height - 2 * s,
1297 s, (int) rect.y);
1298
1299 PushCopyQueue(ctx, (int) -pixels, 0);
1300 }
1301 else if (pixels < 0) {
1302 rect.x = s;
1303
1304 if (ctx->text.vbar != NULL((void*)0))
1305 rect.x += (short) (ctx->text.vbar->core.width +
1306 ctx->text.vbar->core.border_width);
1307
1308 rect.width = (Position) - pixels;
1309 rect.y = ctx->text.margin.top;
1310 rect.height = ctx->core.height - rect.y - 2 * s;
1311
1312 XCopyArea(XtDisplay(tw)(((tw)->core.screen)->display), XtWindow(tw)((tw)->core.window), XtWindow(tw)((tw)->core.window), ctx->text.gc,
1313 (int) rect.x, (int) rect.y,
1314 (unsigned int) ctx->core.width - rect.width - 2 * s,
1315 (unsigned int) rect.height,
1316 (int) rect.x + rect.width, (int) rect.y);
1317
1318 PushCopyQueue(ctx, (int) rect.width, 0);
1319
1320/*
1321 * Redraw the line overflow marks.
1322 */
1323
1324 t_rect.x = ctx->core.width - ctx->text.margin.right - s;
1325 t_rect.width = ctx->text.margin.right;
1326 t_rect.y = rect.y;
1327 t_rect.height = rect.height - 2 * s;
1328
1329 SinkClearToBGXawTextSinkClearToBackground(ctx->text.sink, (Position) t_rect.x, (Position) t_rect.y,
1330 (Dimension) t_rect.width, (Dimension) t_rect.height);
1331
1332 UpdateTextInRectangle(ctx, &t_rect);
1333 }
1334
1335/*
1336 * Put in the text that just became visible.
1337 */
1338
1339 if ( pixels != 0 ) {
1340 SinkClearToBGXawTextSinkClearToBackground(ctx->text.sink, (Position) rect.x, (Position) rect.y,
1341 (Dimension) rect.width, (Dimension) rect.height);
1342
1343 UpdateTextInRectangle(ctx, &rect);
1344 }
1345 _XawTextExecuteUpdate(ctx);
1346 _XawTextSetScrollBars(ctx);
1347}
1348
1349/*ARGSUSED*/
1350static void
1351HJump(Widget w, XtPointer closure, XtPointer callData)
1352{
1353 TextWidget ctx = (TextWidget) closure;
1354 float * percent = (float *) callData;
1355 Position new_left, old_left = ctx->text.margin.left;
1356
1357 long move; /*difference of Positions can be bigger than Position; lint err */
1358
1359 new_left = ctx->text.r_margin.left;
1360 new_left -= (Position) (*percent * GetWidestLine(ctx));
1361 move = old_left - new_left;
1362
1363 if (abs(move) < (int)ctx->core.width) {
1364 HScroll(w, (XtPointer) ctx, (XtPointer) move);
1365 return;
1366 }
1367 _XawTextPrepareToUpdate(ctx);
1368 ctx->text.margin.left = new_left;
1369 if (XtIsRealized((Widget) ctx)(XtWindowOfObject((Widget) ctx) != 0L)) DisplayTextWindow((Widget) ctx);
1370 _XawTextExecuteUpdate(ctx);
1371}
1372
1373/* Function Name: UpdateTextInLine
1374 * Description: Updates some text in a given line.
1375 * Arguments: ctx - the text widget.
1376 * line - the line number (in the line table) of this line.
1377 * left, right - left and right pixel offsets of the
1378 * area to update.
1379 * Returns: none.
1380 */
1381
1382static void
1383UpdateTextInLine(TextWidget ctx, int line, Position left, Position right)
1384{
1385 XawTextPosition pos1, pos2;
1386 int width, height, local_left, local_width;
1387 XawTextLineTableEntry * lt = ctx->text.lt.info + line;
1388
1389 if ( ((int)(lt->textWidth + ctx->text.margin.left) < left) ||
1390 ( ctx->text.margin.left > right ) )
1391 return; /* no need to update. */
1392
1393 local_width = left - ctx->text.margin.left;
1394 XawTextSinkFindPosition(ctx->text.sink, lt->position,
1395 (int) ctx->text.margin.left,
1396 local_width, FALSE0, &pos1, &width, &height);
1397
1398 if (right >= (Position) lt->textWidth - ctx->text.margin.left)
1399 if ( (IsValidLine(ctx, line + 1)( ((line + 1) == 0) || ((ctx)->text.lt.info[(line + 1)].position
!= 0) )
) &&
1400 (ctx->text.lt.info[line + 1].position <= ctx->text.lastPos) )
1401 pos2 = SrcScanXawTextSourceScan( ctx->text.source, (lt + 1)->position, XawstPositions,
1402 XawsdLeft, 1, TRUE1);
1403 else
1404 pos2 = GETLASTPOSXawTextSourceScan(ctx->text.source, 0, XawstAll, XawsdRight
, 1, 1)
;
1405 else {
1406 XawTextPosition t_pos;
1407
1408 local_left = ctx->text.margin.left + width;
1409 local_width = right - local_left;
1410 XawTextSinkFindPosition(ctx->text.sink, pos1, local_left,
1411 local_width, FALSE0, &pos2, &width, &height);
1412
1413 t_pos = SrcScanXawTextSourceScan( ctx->text.source, pos2,
1414 XawstPositions, XawsdRight, 1, TRUE1);
1415 if (t_pos < (lt + 1)->position)
1416 pos2 = t_pos;
1417 }
1418
1419 _XawTextNeedsUpdating(ctx, pos1, pos2);
1420}
1421
1422/*
1423 * The routine will scroll the displayed text by pixels. If the calldata is
1424 * positive, move up; otherwise, move down.
1425 */
1426
1427/*ARGSUSED*/
1428static void
1429VScroll(Widget w, XtPointer closure, XtPointer callData)
1430{
1431 TextWidget ctx = (TextWidget)closure;
1432 int height, nlines, lines = (intptr_t) callData;
1433
1434 height = ctx->core.height - VMargins(ctx)( (ctx)->text.margin.top + (ctx)->text.margin.bottom );
1435 if (height < 1)
1436 height = 1;
1437 nlines = (int) (lines * (int) ctx->text.lt.lines) / height;
1438#ifdef XAW_ARROW_SCROLLBARS
1439 if (nlines == 0 && lines != 0)
1440 nlines = lines > 0 ? 1 : -1;
1441#endif
1442 _XawTextPrepareToUpdate(ctx);
1443 _XawTextVScroll(ctx, nlines);
1444 _XawTextExecuteUpdate(ctx);
1445}
1446
1447/*
1448 * The routine "thumbs" the displayed text. Thumbing means reposition the
1449 * displayed view of the source to a new position determined by a fraction
1450 * of the way from beginning to end. Ideally, this should be determined by
1451 * the number of displayable lines in the source. This routine does it as a
1452 * fraction of the first position and last position and then normalizes to
1453 * the start of the line containing the position.
1454 *
1455 * BUG/deficiency: The normalize to line portion of this routine will
1456 * cause thumbing to always position to the start of the source.
1457 */
1458
1459/*ARGSUSED*/
1460static void
1461VJump(Widget w, XtPointer closure, XtPointer callData)
1462{
1463 float * percent = (float *) callData;
1464 TextWidget ctx = (TextWidget)closure;
1465 XawTextPosition position, old_top, old_bot;
1466 XawTextLineTable * lt = &(ctx->text.lt);
1467
1468 _XawTextPrepareToUpdate(ctx);
1469 old_top = lt->top;
1470 if ( (lt->lines > 0) && (IsValidLine(ctx, lt->lines - 1)( ((lt->lines - 1) == 0) || ((ctx)->text.lt.info[(lt->
lines - 1)].position != 0) )
) )
1471 old_bot = lt->info[lt->lines - 1].position;
1472 else
1473 old_bot = ctx->text.lastPos;
1474
1475 position = (long) (*percent * (float) ctx->text.lastPos);
1476 position= SrcScanXawTextSourceScan(ctx->text.source, position, XawstEOL, XawsdLeft, 1, FALSE0);
1477 if ( (position >= old_top) && (position <= old_bot) ) {
1478 int line = 0;
1479 for (;(line < lt->lines) && (position > lt->info[line].position) ; line++);
1480 _XawTextVScroll(ctx, line);
1481 }
1482 else {
1483 XawTextPosition new_bot;
1484 _XawTextBuildLineTable(ctx, position, FALSE0);
1485 new_bot = IsValidLine(ctx, lt->lines-1)( ((lt->lines-1) == 0) || ((ctx)->text.lt.info[(lt->
lines-1)].position != 0) )
? lt->info[lt->lines-1].position
1486 : ctx->text.lastPos;
1487
1488 if ((old_top >= lt->top) && (old_top <= new_bot)) {
1489 int line = 0;
1490 for (;(line < lt->lines) && (old_top > lt->info[line].position); line++);
1491 _XawTextBuildLineTable(ctx, old_top, FALSE0);
1492 _XawTextVScroll(ctx, -line);
1493 }
1494 else
1495 DisplayTextWindow( (Widget) ctx);
1496 }
1497 _XawTextExecuteUpdate(ctx);
1498}
1499
1500static Boolean
1501MatchSelection(Atom selection, XawTextSelection *s)
1502{
1503 Atom *match;
1504 int count;
1505
1506 for (count = 0, match = s->selections; count < s->atom_count; match++, count++)
1507 if (*match == selection)
1508 return True1;
1509 return False0;
1510}
1511
1512static Boolean
1513ConvertSelection(Widget w, Atom *selection, Atom *target, Atom *type,
1514 XtPointer *value, unsigned long *length, int *format)
1515{
1516 Display* d = XtDisplay(w)(((w)->core.screen)->display);
1517 TextWidget ctx = (TextWidget)w;
1518 Widget src = ctx->text.source;
1519 XawTextEditType edit_mode;
1520 Arg args[1];
1521
1522 XawTextSelectionSalt *salt = NULL((void*)0);
1523 XawTextSelection *s;
1524
1525 if (*target == XA_TARGETS(d)XmuInternAtom(d, _XA_TARGETS)) {
1526 Atom* targetP, * std_targets;
1527 unsigned long std_length;
1528
1529 if ( SrcCvtSelXawTextSourceConvertSelection(src, selection, target, type, value, length, format) )
1530 return True1;
1531
1532 XmuConvertStandardSelection(w, ctx->text.time, selection,
1533 target, type, (XPointer*)&std_targets,
1534 &std_length, format);
1535
1536 *value = XtMalloc((unsigned) sizeof(Atom)*(std_length + 7));
1537 targetP = *(Atom**)value;
1538 *length = std_length + 6;
1539 *targetP++ = XA_STRING((Atom) 31);
1540 *targetP++ = XA_TEXT(d)XmuInternAtom(d, _XA_TEXT);
1541 *targetP++ = XA_COMPOUND_TEXT(d)XmuInternAtom(d, _XA_COMPOUND_TEXT);
1542 *targetP++ = XA_LENGTH(d)XmuInternAtom(d, _XA_LENGTH);
1543 *targetP++ = XA_LIST_LENGTH(d)XmuInternAtom(d, _XA_LIST_LENGTH);
1544 *targetP++ = XA_CHARACTER_POSITION(d)XmuInternAtom(d, _XA_CHARACTER_POSITION);
1545
1546 XtSetArg(args[0], XtNeditType,&edit_mode)((void)( (args[0]).name = (((char*)&XtStrings[185])), (args
[0]).value = (XtArgVal)(&edit_mode) ))
;
1547 XtGetValues(src, args, ONE((Cardinal)1));
1548
1549 if (edit_mode == XawtextEdit) {
1550 *targetP++ = XA_DELETE(d)XmuInternAtom(d, _XA_DELETE);
1551 (*length)++;
1552 }
1553 (void) memmove((char*)targetP, (char*)std_targets, sizeof(Atom)*std_length)__builtin___memmove_chk ((char*)targetP, (char*)std_targets, sizeof
(Atom)*std_length, __builtin_object_size ((char*)targetP, 0))
;
1554 XtFree((char*)std_targets);
1555 *type = XA_ATOM((Atom) 4);
1556 *format = 32;
1557 return True1;
1558 }
1559
1560 if ( SrcCvtSelXawTextSourceConvertSelection(src, selection, target, type, value, length, format) )
1561 return True1;
1562
1563 if (MatchSelection (*selection, &ctx->text.s))
1564 s = &ctx->text.s;
1565 else
1566 {
1567 for (salt = ctx->text.salt; salt; salt = salt->next)
1568 if (MatchSelection (*selection, &salt->s))
1569 break;
1570 if (!salt)
1571 return False0;
1572 s = &salt->s;
1573 }
1574 if (*target == XA_STRING((Atom) 31) ||
1575 *target == XA_TEXT(d)XmuInternAtom(d, _XA_TEXT) ||
1576 *target == XA_COMPOUND_TEXT(d)XmuInternAtom(d, _XA_COMPOUND_TEXT)) {
1577 if (*target == XA_TEXT(d)XmuInternAtom(d, _XA_TEXT)) {
1578#ifdef XAW_INTERNATIONALIZATION1
1579 if (_XawTextFormat(ctx) == XawFmtWide)
1580 *type = XA_COMPOUND_TEXT(d)XmuInternAtom(d, _XA_COMPOUND_TEXT);
1581 else
1582#endif
1583 *type = XA_STRING((Atom) 31);
1584 } else {
1585 *type = *target;
1586 }
1587 /*
1588 * If salt is True, the salt->contents stores CT string,
1589 * its length is measured in bytes.
1590 * Refer to _XawTextSaltAwaySelection().
1591 *
1592 * by Li Yuhong, Mar. 20, 1991.
1593 */
1594 if (!salt) {
1595 *value = _XawTextGetSTRING(ctx, s->left, s->right);
1596#ifdef XAW_INTERNATIONALIZATION1
1597 if (_XawTextFormat(ctx) == XawFmtWide) {
1598 XTextProperty textprop;
1599 if (XwcTextListToTextProperty(d, (wchar_t **)value, 1,
1600 XCompoundTextStyle, &textprop)
1601 < Success0) {
1602 XtFree(*value);
1603 return False0;
1604 }
1605 XtFree(*value);
1606 *value = (XtPointer)textprop.value;
1607 *length = textprop.nitems;
1608 } else
1609#endif
1610 {
1611 *length = strlen(*value);
1612 }
1613 } else {
1614 *value = XtMalloc((salt->length + 1) * sizeof(unsigned char));
1615 strcpy (*value, salt->contents)__builtin___strcpy_chk (*value, salt->contents, __builtin_object_size
(*value, 2 > 1 ? 1 : 0))
;
1616 *length = salt->length;
1617 }
1618#ifdef XAW_INTERNATIONALIZATION1
1619 if (_XawTextFormat(ctx) == XawFmtWide && *type == XA_STRING((Atom) 31)) {
1620 XTextProperty textprop;
1621 wchar_t **wlist;
1622 int count;
1623 textprop.encoding = XA_COMPOUND_TEXT(d)XmuInternAtom(d, _XA_COMPOUND_TEXT);
1624 textprop.value = (unsigned char *)*value;
1625 textprop.nitems = strlen(*value);
1626 textprop.format = 8;
1627 if (XwcTextPropertyToTextList(d, &textprop, (wchar_t ***)&wlist, &count)
1628 < Success0) {
1629 XtFree(*value);
1630 return False0;
1631 }
1632 XtFree(*value);
1633 if (XwcTextListToTextProperty( d, (wchar_t **)wlist, 1,
1634 XStringStyle, &textprop) < Success0) {
1635 XwcFreeStringList( (wchar_t**) wlist );
1636 return False0;
1637 }
1638 *value = (XtPointer) textprop.value;
1639 *length = textprop.nitems;
1640 XwcFreeStringList( (wchar_t**) wlist );
1641 }
1642#endif
1643 *format = 8;
1644 return True1;
1645 }
1646
1647 if ( (*target == XA_LIST_LENGTH(d)XmuInternAtom(d, _XA_LIST_LENGTH)) || (*target == XA_LENGTH(d)XmuInternAtom(d, _XA_LENGTH)) ) {
1648 long * temp;
1649
1650 temp = (long *) XtMalloc( (unsigned) sizeof(long) );
1651 if (*target == XA_LIST_LENGTH(d)XmuInternAtom(d, _XA_LIST_LENGTH))
1652 *temp = 1L;
1653 else /* *target == XA_LENGTH(d) */
1654 *temp = (long) (s->right - s->left);
1655
1656 *value = (XPointer) temp;
1657 *type = XA_INTEGER((Atom) 19);
1658 *length = 1L;
1659 *format = 32;
1660 return True1;
1661 }
1662
1663 if (*target == XA_CHARACTER_POSITION(d)XmuInternAtom(d, _XA_CHARACTER_POSITION)) {
1664 long * temp;
1665
1666 temp = (long *) XtMalloc( (unsigned)( 2 * sizeof(long) ) );
1667 temp[0] = (long) (s->left + 1);
1668 temp[1] = s->right;
1669 *value = (XPointer) temp;
1670 *type = XA_SPAN(d)XmuInternAtom(d, _XA_SPAN);
1671 *length = 2L;
1672 *format = 32;
1673 return True1;
1674 }
1675
1676 if (*target == XA_DELETE(d)XmuInternAtom(d, _XA_DELETE)) {
1677 if (!salt)
1678 _XawTextZapSelection( ctx, (XEvent *) NULL((void*)0), TRUE1);
1679 *value = NULL((void*)0);
1680 *type = XA_NULL(d)XmuInternAtom(d, _XA_NULL);
1681 *length = 0;
1682 *format = 32;
1683 return True1;
1684 }
1685
1686 if (XmuConvertStandardSelection(w, ctx->text.time, selection, target, type,
1687 (XPointer *)value, length, format))
1688 return True1;
1689
1690 /* else */
1691 return False0;
1692}
1693
1694/* Function Name: GetCutBuffferNumber
1695 * Description: Returns the number of the cut buffer.
1696 * Arguments: atom - the atom to check.
1697 * Returns: the number of the cut buffer representing this atom or
1698 * NOT_A_CUT_BUFFER.
1699 */
1700
1701#define NOT_A_CUT_BUFFER-1 -1
1702
1703static int
1704GetCutBufferNumber(Atom atom)
1705{
1706 if (atom == XA_CUT_BUFFER0((Atom) 9)) return(0);
1707 if (atom == XA_CUT_BUFFER1((Atom) 10)) return(1);
1708 if (atom == XA_CUT_BUFFER2((Atom) 11)) return(2);
1709 if (atom == XA_CUT_BUFFER3((Atom) 12)) return(3);
1710 if (atom == XA_CUT_BUFFER4((Atom) 13)) return(4);
1711 if (atom == XA_CUT_BUFFER5((Atom) 14)) return(5);
1712 if (atom == XA_CUT_BUFFER6((Atom) 15)) return(6);
1713 if (atom == XA_CUT_BUFFER7((Atom) 16)) return(7);
1714 return(NOT_A_CUT_BUFFER-1);
1715}
1716
1717static void
1718LoseSelection(Widget w, Atom *selection)
1719{
1720 TextWidget ctx = (TextWidget) w;
1721 Atom* atomP;
1722 int i;
1723 XawTextSelectionSalt *salt, *prevSalt, *nextSalt;
1724
1725 _XawTextPrepareToUpdate(ctx);
1726
1727 atomP = ctx->text.s.selections;
1728 for (i = 0 ; i < ctx->text.s.atom_count; i++, atomP++)
1729 if ( (*selection == *atomP) ||
1730 (GetCutBufferNumber(*atomP) != NOT_A_CUT_BUFFER-1) )/* is a cut buffer */
1731 *atomP = (Atom)0;
1732
1733 while (ctx->text.s.atom_count &&
1734 ctx->text.s.selections[ctx->text.s.atom_count-1] == 0)
1735 ctx->text.s.atom_count--;
1736
1737/*
1738 * Must walk the selection list in opposite order from UnsetSelection.
1739 */
1740
1741 atomP = ctx->text.s.selections;
1742 for (i = 0 ; i < ctx->text.s.atom_count; i++, atomP++)
1743 if (*atomP == (Atom)0) {
1744 *atomP = ctx->text.s.selections[--ctx->text.s.atom_count];
1745 while (ctx->text.s.atom_count &&
1746 ctx->text.s.selections[ctx->text.s.atom_count-1] == 0)
1747 ctx->text.s.atom_count--;
1748 }
1749
1750 if (ctx->text.s.atom_count == 0)
1751 ModifySelection(ctx, ctx->text.insertPos, ctx->text.insertPos);
1752
1753 if (ctx->text.old_insert >= 0) /* Update in progress. */
1754 _XawTextExecuteUpdate(ctx);
1755
1756 prevSalt = 0;
1757 for (salt = ctx->text.salt; salt; salt = nextSalt)
1758 {
1759 atomP = salt->s.selections;
1760 nextSalt = salt->next;
1761 for (i = 0 ; i < salt->s.atom_count; i++, atomP++)
1762 if (*selection == *atomP)
1763 *atomP = (Atom)0;
1764
1765 while (salt->s.atom_count &&
1766 salt->s.selections[salt->s.atom_count-1] == 0)
1767 {
1768 salt->s.atom_count--;
1769 }
1770
1771 /*
1772 * Must walk the selection list in opposite order from UnsetSelection.
1773 */
1774
1775 atomP = salt->s.selections;
1776 for (i = 0 ; i < salt->s.atom_count; i++, atomP++)
1777 if (*atomP == (Atom)0)
1778 {
1779 *atomP = salt->s.selections[--salt->s.atom_count];
1780 while (salt->s.atom_count &&
1781 salt->s.selections[salt->s.atom_count-1] == 0)
1782 salt->s.atom_count--;
1783 }
1784 if (salt->s.atom_count == 0)
1785 {
1786 XtFree ((char *) salt->s.selections);
1787 XtFree (salt->contents);
1788 if (prevSalt)
1789 prevSalt->next = nextSalt;
1790 else
1791 ctx->text.salt = nextSalt;
1792 XtFree ((char *) salt);
1793 }
1794 else
1795 prevSalt = salt;
1796 }
1797}
1798
1799void
1800_XawTextSaltAwaySelection(TextWidget ctx, Atom *selections, int num_atoms)
1801{
1802 XawTextSelectionSalt *salt;
1803 int i, j;
1804
1805 for (i = 0; i < num_atoms; i++)
1806 LoseSelection ((Widget) ctx, selections + i);
1807 if (num_atoms == 0)
1808 return;
1809 salt = (XawTextSelectionSalt *)
1810 XtMalloc( (unsigned) sizeof(XawTextSelectionSalt) );
1811 if (!salt)
1812 return;
1813 salt->s.selections = (Atom *)
1814 XtMalloc( (unsigned) ( num_atoms * sizeof (Atom) ) );
1815 if (!salt->s.selections)
1816 {
1817 XtFree ((char *) salt);
1818 return;
1819 }
1820 salt->s.left = ctx->text.s.left;
1821 salt->s.right = ctx->text.s.right;
1822 salt->s.type = ctx->text.s.type;
1823 salt->contents = _XawTextGetSTRING(ctx, ctx->text.s.left, ctx->text.s.right);
1824#ifdef XAW_INTERNATIONALIZATION1
1825 if (_XawTextFormat(ctx) == XawFmtWide) {
1826 XTextProperty textprop;
1827 if (XwcTextListToTextProperty(XtDisplay((Widget)ctx)((((Widget)ctx)->core.screen)->display),
1828 (wchar_t**)(&(salt->contents)), 1, XCompoundTextStyle,
1829 &textprop) < Success0) {
1830 XtFree(salt->contents);
1831 salt->length = 0;
1832 return;
1833 }
1834 XtFree(salt->contents);
1835 salt->contents = (char *)textprop.value;
1836 salt->length = textprop.nitems;
1837 } else
1838#endif
1839 salt->length = strlen (salt->contents);
1840 salt->next = ctx->text.salt;
1841 ctx->text.salt = salt;
1842 j = 0;
1843 for (i = 0; i < num_atoms; i++)
1844 {
1845 if (GetCutBufferNumber (selections[i]) == NOT_A_CUT_BUFFER-1)
1846 {
1847 salt->s.selections[j++] = selections[i];
1848 XtOwnSelection ((Widget) ctx, selections[i], ctx->text.time,
1849 ConvertSelection, LoseSelection, (XtSelectionDoneProc)NULL((void*)0));
1850 }
1851 }
1852 salt->s.atom_count = j;
1853}
1854
1855static void
1856_SetSelection(TextWidget ctx, XawTextPosition left, XawTextPosition right,
1857 Atom *selections, Cardinal count)
1858{
1859 XawTextPosition pos;
1860
1861 if (left < ctx->text.s.left) {
1862 pos = Min(right, ctx->text.s.left)(((right) < (ctx->text.s.left)) ? (right) : (ctx->text
.s.left))
;
1863 _XawTextNeedsUpdating(ctx, left, pos);
1864 }
1865 if (left > ctx->text.s.left) {
1866 pos = Min(left, ctx->text.s.right)(((left) < (ctx->text.s.right)) ? (left) : (ctx->text
.s.right))
;
1867 _XawTextNeedsUpdating(ctx, ctx->text.s.left, pos);
1868 }
1869 if (right < ctx->text.s.right) {
1870 pos = Max(right, ctx->text.s.left)(((right) > (ctx->text.s.left)) ? (right) : (ctx->text
.s.left))
;
1871 _XawTextNeedsUpdating(ctx, pos, ctx->text.s.right);
1872 }
1873 if (right > ctx->text.s.right) {
1874 pos = Max(left, ctx->text.s.right)(((left) > (ctx->text.s.right)) ? (left) : (ctx->text
.s.right))
;
1875 _XawTextNeedsUpdating(ctx, pos, right);
1876 }
1877
1878 ctx->text.s.left = left;
1879 ctx->text.s.right = right;
1880
1881 SrcSetSelectionXawTextSourceSetSelection(ctx->text.source, left, right,
1882 (count == 0) ? None0L : selections[0]);
1883
1884 if (left < right) {
1885 Widget w = (Widget) ctx;
1886 int buffer;
1887
1888 while (count) {
1889 Atom selection = selections[--count];
1890
1891 if ((buffer = GetCutBufferNumber(selection)) != NOT_A_CUT_BUFFER-1) {
1892
1893 unsigned char *ptr, *tptr;
1894 unsigned int amount, max_len = MAX_CUT_LEN(XtDisplay(w))(XMaxRequestSize((((w)->core.screen)->display)) - 64);
1895 unsigned long len;
1896
1897 tptr= ptr= (unsigned char *) _XawTextGetSTRING(ctx, ctx->text.s.left,
1898 ctx->text.s.right);
1899#ifdef XAW_INTERNATIONALIZATION1
1900 if (_XawTextFormat(ctx) == XawFmtWide) {
1901 /*
1902 * Only XA_STRING(Latin 1) is allowed in CUT_BUFFER,
1903 * so we get it from wchar string, then free the wchar string.
1904 */
1905 XTextProperty textprop;
1906 if (XwcTextListToTextProperty(XtDisplay(w)(((w)->core.screen)->display), (wchar_t**)&ptr, 1,
1907 XStringStyle, &textprop) < Success0) {
1908 XtFree((char *)ptr);
1909 return;
1910 }
1911 XtFree((char *)ptr);
1912 tptr = ptr = textprop.value;
1913 }
1914#endif
1915 if (buffer == 0) {
1916 _CreateCutBuffers(XtDisplay(w)(((w)->core.screen)->display));
1917 XRotateBuffers(XtDisplay(w)(((w)->core.screen)->display), 1);
1918 }
1919 amount = Min ( (len = strlen((char *)ptr)), max_len)((((len = strlen((char *)ptr))) < (max_len)) ? ((len = strlen
((char *)ptr))) : (max_len))
;
1920 XChangeProperty(XtDisplay(w)(((w)->core.screen)->display), RootWindow(XtDisplay(w), 0)((&((_XPrivDisplay)((((w)->core.screen)->display)))
->screens[0])->root)
, selection,
1921 XA_STRING((Atom) 31), 8, PropModeReplace0, ptr, amount);
1922
1923 while (len > max_len) {
1924 len -= max_len;
1925 tptr += max_len;
1926 amount = Min (len, max_len)(((len) < (max_len)) ? (len) : (max_len));
1927 XChangeProperty(XtDisplay(w)(((w)->core.screen)->display), RootWindow(XtDisplay(w), 0)((&((_XPrivDisplay)((((w)->core.screen)->display)))
->screens[0])->root)
,
1928 selection, XA_STRING((Atom) 31), 8, PropModeAppend2,
1929 tptr, amount);
1930 }
1931 XtFree ((char *)ptr);
1932 }
1933 else /* This is a real selection */
1934 XtOwnSelection(w, selection, ctx->text.time, ConvertSelection,
1935 LoseSelection, (XtSelectionDoneProc)NULL((void*)0));
1936 }
1937 }
1938 else
1939 XawTextUnsetSelection((Widget)ctx);
1940}
1941
1942/*
1943 * This internal routine deletes the text from pos1 to pos2 in a source and
1944 * then inserts, at pos1, the text that was passed. As a side effect it
1945 * "invalidates" that portion of the displayed text (if any).
1946 *
1947 * NOTE: It is illegal to call this routine unless there is a valid line table!
1948 */
1949
1950int
1951_XawTextReplace (TextWidget ctx, XawTextPosition pos1, XawTextPosition pos2,
1952 XawTextBlock *text)
1953{
1954 int i, line1, delta, error;
1955 XawTextPosition updateFrom, updateTo;
1956 Widget src = ctx->text.source;
1957 XawTextEditType edit_mode;
1958 Arg args[1];
1959 Boolean tmp = ctx->text.update_disabled;
1960
1961 ctx->text.update_disabled = True1; /* No redisplay during replacement. */
1962
1963/*
1964 * The insertPos may not always be set to the right spot in XawtextAppend
1965 */
1966
1967 XtSetArg(args[0], XtNeditType, &edit_mode)((void)( (args[0]).name = (((char*)&XtStrings[185])), (args
[0]).value = (XtArgVal)(&edit_mode) ))
;
1968 XtGetValues(src, args, ONE((Cardinal)1));
1969
1970 if ((pos1 == ctx->text.insertPos) && (edit_mode == XawtextAppend)) {
1971 ctx->text.insertPos = ctx->text.lastPos;
1972 pos2 = SrcScanXawTextSourceScan(src, ctx->text.insertPos, XawstPositions, XawsdRight,
1973 (int)(ctx->text.insertPos - pos1), (Boolean)TRUE1);
1974 pos1 = ctx->text.insertPos;
1975 if ( (pos1 == pos2) && (text->length == 0) ) {
1976 ctx->text.update_disabled = FALSE0; /* rearm redisplay. */
1977 return( XawEditError1 );
1978 }
1979 }
1980
1981 updateFrom = SrcScanXawTextSourceScan(src, pos1, XawstWhiteSpace, XawsdLeft, 1, FALSE0);
1982 updateFrom = Max(updateFrom, ctx->text.lt.top)(((updateFrom) > (ctx->text.lt.top)) ? (updateFrom) : (
ctx->text.lt.top))
;
1983
1984 line1 = LineForPosition(ctx, updateFrom);
1985 if ( (error = SrcReplaceXawTextSourceReplace(src, pos1, pos2, text)) != 0) {
1986 ctx->text.update_disabled = tmp; /* restore redisplay */
1987 return(error);
1988 }
1989
1990 XawTextUnsetSelection((Widget)ctx);
1991
1992 ctx->text.lastPos = GETLASTPOSXawTextSourceScan(ctx->text.source, 0, XawstAll, XawsdRight
, 1, 1)
;
1993 if (ctx->text.lt.top >= ctx->text.lastPos) {
1994 _XawTextBuildLineTable(ctx, ctx->text.lastPos, FALSE0);
1995 ClearWindow( (Widget) ctx);
1996 ctx->text.update_disabled = tmp; /* restore redisplay */
1997 return(0); /* Things are fine. */
1998 }
1999
2000 ctx->text.single_char = (text->length <= 1 && pos2 - pos1 <= 1);
2001
2002 delta = text->length - (pos2 - pos1);
2003
2004 if (delta < ctx->text.lastPos) {
2005 for (pos2 += delta, i = 0; i < ctx->text.numranges; i++) {
Value stored to 'pos2' is never read
2006 if (ctx->text.updateFrom[i] > pos1)
2007 ctx->text.updateFrom[i] += delta;
2008 if (ctx->text.updateTo[i] >= pos1)
2009 ctx->text.updateTo[i] += delta;
2010 }
2011 }
2012
2013 /*
2014 * fixup all current line table entries to reflect edit.
2015 * %%% it is not legal to do arithmetic on positions.
2016 * using Scan would be more proper.
2017 */
2018 if (delta != 0) {
2019 XawTextLineTableEntry *lineP;
2020 i = LineForPosition(ctx, pos1) + 1;
2021 for (lineP = ctx->text.lt.info + i; i <= ctx->text.lt.lines; i++, lineP++)
2022 lineP->position += delta;
2023 }
2024
2025 /*
2026 * Now process the line table and fixup in case edits caused
2027 * changes in line breaks. If we are breaking on word boundaries,
2028 * this code checks for moving words to and from lines.
2029 */
2030
2031 if (IsPositionVisible(ctx, updateFrom)(updateFrom >= ctx->text.lt.info[0].position &&
updateFrom < ctx->text.lt.info[ctx->text.lt.lines].
position)
) {
2032 updateTo = _BuildLineTable(ctx,
2033 ctx->text.lt.info[line1].position, pos1, line1);
2034 _XawTextNeedsUpdating(ctx, updateFrom, updateTo);
2035 }
2036
2037 ctx->text.update_disabled = tmp; /* restore redisplay */
2038 return(0); /* Things are fine. */
2039}
2040
2041/*
2042 * This routine will display text between two arbitrary source positions.
2043 * In the event that this span contains highlighted text for the selection,
2044 * only that portion will be displayed highlighted.
2045 *
2046 * NOTE: it is illegal to call this routine unless there
2047 * is a valid line table!
2048 */
2049
2050static void
2051DisplayText(Widget w, XawTextPosition pos1, XawTextPosition pos2)
2052{
2053 TextWidget ctx = (TextWidget)w;
2054 Position x, y;
2055 int height, line, i, lastPos = ctx->text.lastPos;
2056 XawTextPosition startPos, endPos;
2057 Boolean clear_eol, done_painting;
2058 Dimension s = ((ThreeDWidget)ctx->text.threeD)->threeD.shadow_width;
2059
2060 pos1 = (pos1 < ctx->text.lt.top) ? ctx->text.lt.top : pos1;
2061 pos2 = FindGoodPosition(ctx, pos2);
2062 if ( (pos1 >= pos2) || !LineAndXYForPosition(ctx, pos1, &line, &x, &y) )
2063 return; /* line not visible, or pos1 >= pos2. */
2064
2065 for ( startPos = pos1, i = line; IsValidLine(ctx, i)( ((i) == 0) || ((ctx)->text.lt.info[(i)].position != 0) ) &&
2066 (i < ctx->text.lt.lines) ; i++) {
2067
2068
2069 if ( (endPos = ctx->text.lt.info[i + 1].position) > pos2 ) {
2070 clear_eol = ((endPos = pos2) >= lastPos);
2071 done_painting = (!clear_eol || ctx->text.single_char);
2072 }
2073 else {
2074 clear_eol = TRUE1;
2075 done_painting = FALSE0;
2076 }
2077
2078 height = ctx->text.lt.info[i + 1].y - ctx->text.lt.info[i].y - s + 1;
2079
2080 if ( (endPos > startPos) ) {
2081
2082 /* note to self: _ShadowSurroundedBox() hacks are in here */
2083
2084 if ( (x == (Position) ctx->text.margin.left) && (x > 0) )
2085 {
2086 SinkClearToBGXawTextSinkClearToBackground (ctx->text.sink,
2087 (Position) s, y,
2088 (Dimension) ctx->text.margin.left, (Dimension)height);
2089 _ShadowSurroundedBox((Widget)ctx, (ThreeDWidget)ctx->text.threeD,
2090 0, 0, ctx->core.width, ctx->core.height,
2091 ((ThreeDWidget)ctx->text.threeD)->threeD.relief,
2092 False0);
2093 }
2094
2095 if ( (startPos >= ctx->text.s.right) || (endPos <= ctx->text.s.left) )
2096 XawTextSinkDisplayText(ctx->text.sink, x, y, startPos, endPos, FALSE0);
2097 else if ((startPos >= ctx->text.s.left) && (endPos <= ctx->text.s.right))
2098 XawTextSinkDisplayText(ctx->text.sink, x, y, startPos, endPos, TRUE1);
2099 else {
2100 DisplayText(w, startPos, ctx->text.s.left);
2101 DisplayText(w, Max(startPos, ctx->text.s.left)(((startPos) > (ctx->text.s.left)) ? (startPos) : (ctx->
text.s.left))
,
2102 Min(endPos, ctx->text.s.right)(((endPos) < (ctx->text.s.right)) ? (endPos) : (ctx->
text.s.right))
);
2103 DisplayText(w, ctx->text.s.right, endPos);
2104 }
2105 }
2106 startPos = endPos;
2107 if (clear_eol) {
2108 Position myx = ctx->text.lt.info[i].textWidth + ctx->text.margin.left;
2109
2110 SinkClearToBGXawTextSinkClearToBackground(ctx->text.sink,
2111 (Position) myx,
2112 (Position) y, w->core.width - myx/* - 2 * s*/,
2113 (Dimension) height);
2114 _ShadowSurroundedBox((Widget)ctx, (ThreeDWidget)ctx->text.threeD,
2115 0, 0, ctx->core.width, ctx->core.height,
2116 ((ThreeDWidget)ctx->text.threeD)->threeD.relief,
2117 False0);
2118
2119 /*
2120 * We only get here if single character is true, and we need
2121 * to clear to the end of the screen. We know that since there
2122 * was only one character deleted that this is the same
2123 * as clearing an extra line, so we do this, and are done.
2124 *
2125 * This a performance hack, and a pretty gross one, but it works.
2126 *
2127 * Chris Peterson 11/13/89.
2128 */
2129
2130 if (done_painting) {
2131 y += height;
2132 SinkClearToBGXawTextSinkClearToBackground(ctx->text.sink,
2133 (Position) ctx->text.margin.left, (Position) y,
2134 w->core.width - ctx->text.margin.left/* - 2 * s*/,
2135 (Dimension) Min(height, ctx->core.height - 2 * s - y)(((height) < (ctx->core.height - 2 * s - y)) ? (height)
: (ctx->core.height - 2 * s - y))
);
2136 _ShadowSurroundedBox((Widget)ctx, (ThreeDWidget)ctx->text.threeD,
2137 0, 0, ctx->core.width, ctx->core.height,
2138 ((ThreeDWidget)ctx->text.threeD)->threeD.relief,
2139 False0);
2140
2141 break; /* set single_char to FALSE and return. */
2142 }
2143 }
2144
2145 x = (Position) ctx->text.margin.left;
2146 y = ctx->text.lt.info[i + 1].y;
2147 if ( done_painting
2148 || (y >= (int)(ctx->core.height - ctx->text.margin.bottom)) )
2149 break;
2150 }
2151 ctx->text.single_char = FALSE0;
2152}
2153
2154/*
2155 * This routine implements multi-click selection in a hardwired manner.
2156 * It supports multi-click entity cycling (char, word, line, file) and mouse
2157 * motion adjustment of the selected entitie (i.e. select a word then, with
2158 * button still down, adjust wich word you really meant by moving the mouse).
2159 * [NOTE: This routine is to be replaced by a set of procedures that
2160 * will allows clients to implements a wide class of draw through and
2161 * multi-click selection user interfaces.]
2162 */
2163
2164static void
2165DoSelection (TextWidget ctx, XawTextPosition pos, Time time, Boolean motion)
2166{
2167 XawTextPosition newLeft, newRight;
2168 XawTextSelectType newType, *sarray;
2169 Widget src = ctx->text.source;
2170
2171 if (motion)
2172 newType = ctx->text.s.type;
2173 else {
2174 if ( (labs((long) time - (long) ctx->text.lasttime) < MULTI_CLICK_TIME500L) &&
2175 ((pos >= ctx->text.s.left) && (pos <= ctx->text.s.right))) {
2176 sarray = ctx->text.sarray;
2177 for (;*sarray != XawselectNull && *sarray != ctx->text.s.type; sarray++);
2178
2179 if (*sarray == XawselectNull)
2180 newType = *(ctx->text.sarray);
2181 else {
2182 newType = *(sarray + 1);
2183 if (newType == XawselectNull)
2184 newType = *(ctx->text.sarray);
2185 }
2186 }
2187 else /* single-click event */
2188 newType = *(ctx->text.sarray);
2189
2190 ctx->text.lasttime = time;
2191 }
2192 switch (newType) {
2193 case XawselectPosition:
2194 newLeft = newRight = pos;
2195 break;
2196 case XawselectChar:
2197 newLeft = pos;
2198 newRight = SrcScanXawTextSourceScan(src, pos, XawstPositions, XawsdRight, 1, FALSE0);
2199 break;
2200 case XawselectWord:
2201 case XawselectParagraph:
2202 {
2203 XawTextScanType stype;
2204
2205 if (newType == XawselectWord)
2206 stype = XawstWhiteSpace;
2207 else
2208 stype = XawstParagraph;
2209
2210 /*
2211 * Somewhat complicated, but basically I treat the space between
2212 * two objects as another object. The object that I am currently
2213 * in then becomes the end of the selection.
2214 *
2215 * Chris Peterson - 4/19/90.
2216 */
2217
2218 newRight = SrcScanXawTextSourceScan(ctx->text.source, pos, stype, XawsdRight, 1, FALSE0);
2219 newRight =SrcScanXawTextSourceScan(ctx->text.source, newRight,stype,XawsdLeft,1, FALSE0);
2220
2221 if (pos != newRight)
2222 newLeft = SrcScanXawTextSourceScan(ctx->text.source, pos, stype, XawsdLeft, 1, FALSE0);
2223 else
2224 newLeft = pos;
2225
2226 newLeft =SrcScanXawTextSourceScan(ctx->text.source, newLeft, stype, XawsdRight,1,FALSE0);
2227
2228 if (newLeft > newRight) {
2229 XawTextPosition temp = newLeft;
2230 newLeft = newRight;
2231 newRight = temp;
2232 }
2233 }
2234 break;
2235 case XawselectLine:
2236 newLeft = SrcScanXawTextSourceScan(src, pos, XawstEOL, XawsdLeft, 1, FALSE0);
2237 newRight = SrcScanXawTextSourceScan(src, pos, XawstEOL, XawsdRight, 1, FALSE0);
2238 break;
2239 case XawselectAll:
2240 newLeft = SrcScanXawTextSourceScan(src, pos, XawstAll, XawsdLeft, 1, FALSE0);
2241 newRight = SrcScanXawTextSourceScan(src, pos, XawstAll, XawsdRight, 1, FALSE0);
2242 break;
2243 default:
2244 XtAppWarning(XtWidgetToApplicationContext((Widget) ctx),
2245 "Text Widget: empty selection array.");
2246 return;
2247 }
2248
2249 if ( (newLeft != ctx->text.s.left) || (newRight != ctx->text.s.right)
2250 || (newType != ctx->text.s.type)) {
2251 ModifySelection(ctx, newLeft, newRight);
2252 if (pos - ctx->text.s.left < ctx->text.s.right - pos)
2253 ctx->text.insertPos = newLeft;
2254 else
2255 ctx->text.insertPos = newRight;
2256 ctx->text.s.type = newType;
2257 }
2258 if (!motion) { /* setup so we can freely mix select extend calls*/
2259 ctx->text.origSel.type = ctx->text.s.type;
2260 ctx->text.origSel.left = ctx->text.s.left;
2261 ctx->text.origSel.right = ctx->text.s.right;
2262
2263 if (pos >= ctx->text.s.left + ((ctx->text.s.right - ctx->text.s.left) / 2))
2264 ctx->text.extendDir = XawsdRight;
2265 else
2266 ctx->text.extendDir = XawsdLeft;
2267 }
2268}
2269
2270/*
2271 * This routine implements extension of the currently selected text in
2272 * the "current" mode (i.e. char word, line, etc.). It worries about
2273 * extending from either end of the selection and handles the case when you
2274 * cross through the "center" of the current selection (e.g. switch which
2275 * end you are extending!).
2276 */
2277
2278static void
2279ExtendSelection (TextWidget ctx, XawTextPosition pos, Boolean motion)
2280{
2281 XawTextScanDirection dir;
2282
2283 if (!motion) { /* setup for extending selection */
2284 if (ctx->text.s.left == ctx->text.s.right) /* no current selection. */
2285 ctx->text.s.left = ctx->text.s.right = ctx->text.insertPos;
2286 else {
2287 ctx->text.origSel.left = ctx->text.s.left;
2288 ctx->text.origSel.right = ctx->text.s.right;
2289 }
2290
2291 ctx->text.origSel.type = ctx->text.s.type;
2292
2293 if (pos >= ctx->text.s.left + ((ctx->text.s.right - ctx->text.s.left) / 2))
2294 ctx->text.extendDir = XawsdRight;
2295 else
2296 ctx->text.extendDir = XawsdLeft;
2297 }
2298 else /* check for change in extend direction */
2299 if ((ctx->text.extendDir == XawsdRight && pos <= ctx->text.origSel.left) ||
2300 (ctx->text.extendDir == XawsdLeft && pos >= ctx->text.origSel.right)) {
2301 ctx->text.extendDir = (ctx->text.extendDir == XawsdRight) ?
2302 XawsdLeft : XawsdRight;
2303 ModifySelection(ctx, ctx->text.origSel.left, ctx->text.origSel.right);
2304 }
2305
2306 dir = ctx->text.extendDir;
2307 switch (ctx->text.s.type) {
2308 case XawselectWord:
2309 case XawselectParagraph:
2310 {
2311 XawTextPosition left_pos, right_pos;
2312 XawTextScanType stype;
2313
2314 if (ctx->text.s.type == XawselectWord)
2315 stype = XawstWhiteSpace;
2316 else
2317 stype = XawstParagraph;
2318
2319 /*
2320 * Somewhat complicated, but basically I treat the space between
2321 * two objects as another object. The object that I am currently
2322 * in then becomes the end of the selection.
2323 *
2324 * Chris Peterson - 4/19/90.
2325 */
2326
2327 right_pos = SrcScanXawTextSourceScan(ctx->text.source, pos, stype, XawsdRight, 1, FALSE0);
2328 right_pos =SrcScanXawTextSourceScan(ctx->text.source, right_pos,stype,XawsdLeft,1, FALSE0);
2329
2330 if (pos != right_pos)
2331 left_pos = SrcScanXawTextSourceScan(ctx->text.source, pos, stype, XawsdLeft, 1, FALSE0);
2332 else
2333 left_pos = pos;
2334
2335 left_pos =SrcScanXawTextSourceScan(ctx->text.source, left_pos, stype, XawsdRight,1,FALSE0);
2336
2337 if (dir == XawsdLeft)
2338 pos = Min(left_pos, right_pos)(((left_pos) < (right_pos)) ? (left_pos) : (right_pos));
2339 else /* dir == XawsdRight */
2340 pos = Max(left_pos, right_pos)(((left_pos) > (right_pos)) ? (left_pos) : (right_pos));
2341 }
2342 break;
2343 case XawselectLine:
2344 pos = SrcScanXawTextSourceScan(ctx->text.source, pos, XawstEOL, dir, 1, dir == XawsdRight);
2345 break;
2346 case XawselectAll:
2347 pos = ctx->text.insertPos;
2348 case XawselectPosition: /* fall through. */
2349 default:
2350 break;
2351 }
2352
2353 if (dir == XawsdRight)
2354 ModifySelection(ctx, ctx->text.s.left, pos);
2355 else
2356 ModifySelection(ctx, pos, ctx->text.s.right);
2357
2358 ctx->text.insertPos = pos;
2359}
2360
2361/*
2362 * Clear the window to background color.
2363 */
2364
2365static void
2366ClearWindow (Widget w)
2367{
2368 TextWidget ctx = (TextWidget) w;
2369 int s = ((ThreeDWidget)ctx->text.threeD)->threeD.shadow_width;
2370
2371 if (XtIsRealized(w)(XtWindowOfObject(w) != 0L))
2372 {
2373 SinkClearToBGXawTextSinkClearToBackground(ctx->text.sink,
2374 (Position) s, (Position) s,
2375 w->core.width - 2 * s, w->core.height - 2 * s);
2376 /* note to self: _ShadowSurroundedBox() hack might be needed here */
2377 }
2378}
2379
2380/* Function Name: _XawTextClearAndCenterDisplay
2381 * Description: Redraws the display with the cursor in insert point
2382 * centered vertically.
2383 * Arguments: ctx - the text widget.
2384 * Returns: none.
2385 */
2386
2387void
2388_XawTextClearAndCenterDisplay(TextWidget ctx)
2389{
2390 int insert_line = LineForPosition(ctx, ctx->text.insertPos);
2391 int scroll_by = insert_line - ctx->text.lt.lines/2;
2392
2393 _XawTextVScroll(ctx, scroll_by);
2394 DisplayTextWindow( (Widget) ctx);
2395}
2396
2397/*
2398 * Internal redisplay entire window.
2399 * Legal to call only if widget is realized.
2400 */
2401
2402static void
2403DisplayTextWindow (Widget w)
2404{
2405 TextWidget ctx = (TextWidget) w;
2406 ClearWindow(w);
2407 _XawTextBuildLineTable(ctx, ctx->text.lt.top, FALSE0);
2408 _XawTextNeedsUpdating(ctx, zeroPosition((XawTextPosition) 0), ctx->text.lastPos);
2409 _XawTextSetScrollBars(ctx);
2410}
2411
2412/*
2413 * This routine checks to see if the window should be resized (grown or
2414 * shrunk) when text to be painted overflows to the right or
2415 * the bottom of the window. It is used by the keyboard input routine.
2416 */
2417
2418void
2419_XawTextCheckResize(TextWidget ctx)
2420{
2421 Widget w = (Widget) ctx;
2422 int line = 0, old_height;
2423 XtWidgetGeometry rbox, return_geom;
2424
2425 if ( (ctx->text.resize == XawtextResizeWidth) ||
2426 (ctx->text.resize == XawtextResizeBoth) ) {
2427 XawTextLineTableEntry *lt;
2428 rbox.width = 0;
2429 for (lt = ctx->text.lt.info;
2430 IsValidLine(ctx, line)( ((line) == 0) || ((ctx)->text.lt.info[(line)].position !=
0) )
&& (line < ctx->text.lt.lines);
2431 line++, lt++) {
2432 if ((int)(lt->textWidth + ctx->text.margin.left) > (int)rbox.width)
2433 rbox.width = lt->textWidth + ctx->text.margin.left;
2434 }
2435
2436 rbox.width += ctx->text.margin.right;
2437 if (rbox.width > ctx->core.width) { /* Only get wider. */
2438 rbox.request_mode = CWWidth(1<<2);
2439 if (XtMakeGeometryRequest(w, &rbox, &return_geom) == XtGeometryAlmost)
2440 (void) XtMakeGeometryRequest(w, &return_geom, (XtWidgetGeometry*) NULL((void*)0));
2441 }
2442 }
2443
2444 if ( !((ctx->text.resize == XawtextResizeHeight) ||
2445 (ctx->text.resize == XawtextResizeBoth)) )
2446 return;
2447
2448 if (IsPositionVisible(ctx, ctx->text.lastPos)(ctx->text.lastPos >= ctx->text.lt.info[0].position &&
ctx->text.lastPos < ctx->text.lt.info[ctx->text.
lt.lines].position)
)
2449 line = LineForPosition(ctx, ctx->text.lastPos);
2450 else
2451 line = ctx->text.lt.lines;
2452
2453 if ( (line + 1) == ctx->text.lt.lines ) return;
2454
2455 old_height = ctx->core.height;
2456 rbox.request_mode = CWHeight(1<<3);
2457 rbox.height = XawTextSinkMaxHeight(ctx->text.sink, line + 1) + VMargins(ctx)( (ctx)->text.margin.top + (ctx)->text.margin.bottom );
2458
2459 if ((int)rbox.height < old_height) return; /* It will only get taller. */
2460
2461 if (XtMakeGeometryRequest(w, &rbox, &return_geom) == XtGeometryAlmost)
2462 if (XtMakeGeometryRequest(w, &return_geom, (XtWidgetGeometry*)NULL((void*)0)) != XtGeometryYes)
2463 return;
2464
2465 _XawTextBuildLineTable(ctx, ctx->text.lt.top, TRUE1);
2466}
2467
2468/*
2469 * Converts (params, num_params) to a list of atoms & caches the
2470 * list in the TextWidget instance.
2471 */
2472
2473Atom*
2474_XawTextSelectionList(TextWidget ctx, String *list, Cardinal nelems)
2475{
2476 Atom * sel = ctx->text.s.selections;
2477 Display *dpy = XtDisplay((Widget) ctx)((((Widget) ctx)->core.screen)->display);
2478 int n;
2479
2480 if (nelems > ctx->text.s.array_size) {
2481 sel = (Atom *) XtRealloc((char *) sel, sizeof(Atom) * nelems);
2482 ctx->text.s.array_size = nelems;
2483 ctx->text.s.selections = sel;
2484 }
2485 for (n=nelems; --n >= 0; sel++, list++)
2486 *sel = XInternAtom(dpy, *list, False0);
2487
2488 ctx->text.s.atom_count = nelems;
2489 return ctx->text.s.selections;
2490}
2491
2492/* Function Name: SetSelection
2493 * Description: Sets the current selection.
2494 * Arguments: ctx - the text widget.
2495 * defaultSel - the default selection.
2496 * l, r - the left and right ends of the selection.
2497 * list, nelems - the selection list (as strings).
2498 * Returns: none.
2499 *
2500 * NOTE: if (ctx->text.s.left >= ctx->text.s.right) then the selection
2501 * is unset.
2502 */
2503
2504void
2505_XawTextSetSelection(TextWidget ctx, XawTextPosition l, XawTextPosition r,
2506 String *list, Cardinal nelems)
2507{
2508 if (nelems == 1 && !strcmp (list[0], "none"))
2509 return;
2510 if (nelems == 0) {
2511 String defaultSel = "PRIMARY";
2512 list = &defaultSel;
2513 nelems = 1;
2514 }
2515 _SetSelection(ctx, l, r, _XawTextSelectionList(ctx, list, nelems), nelems);
2516}
2517
2518
2519/* Function Name: ModifySelection
2520 * Description: Modifies the current selection.
2521 * Arguments: ctx - the text widget.
2522 * left, right - the left and right ends of the selection.
2523 * Returns: none.
2524 *
2525 * NOTE: if (ctx->text.s.left >= ctx->text.s.right) then the selection
2526 * is unset.
2527 */
2528
2529static void
2530ModifySelection(TextWidget ctx, XawTextPosition left, XawTextPosition right)
2531{
2532 if (left == right)
2533 ctx->text.insertPos = left;
2534 _SetSelection( ctx, left, right, (Atom*) NULL((void*)0), ZERO((Cardinal)0) );
2535}
2536
2537/*
2538 * This routine is used to perform various selection functions. The goal is
2539 * to be able to specify all the more popular forms of draw-through and
2540 * multi-click selection user interfaces from the outside.
2541 */
2542
2543void
2544_XawTextAlterSelection (TextWidget ctx, XawTextSelectionMode mode,
2545 XawTextSelectionAction action, String *params, Cardinal *num_params)
2546{
2547 XawTextPosition position;
2548 Boolean flag;
2549
2550/*
2551 * This flag is used by TextPop.c:DoReplace() to determine if the selection
2552 * is okay to use, or if it has been modified.
2553 */
2554
2555 if (ctx->text.search != NULL((void*)0))
2556 ctx->text.search->selection_changed = TRUE1;
2557
2558 position = PositionForXY (ctx, (int) ctx->text.ev_x, (int) ctx->text.ev_y);
2559
2560 flag = (action != XawactionStart);
2561 if (mode == XawsmTextSelect)
2562 DoSelection (ctx, position, ctx->text.time, flag);
2563 else /* mode == XawsmTextExtend */
2564 ExtendSelection (ctx, position, flag);
2565
2566 if (action == XawactionEnd)
2567 _XawTextSetSelection(ctx, ctx->text.s.left, ctx->text.s.right,
2568 params, *num_params);
2569}
2570
2571/* Function Name: RectanglesOverlap
2572 * Description: Returns TRUE if two rectangles overlap.
2573 * Arguments: rect1, rect2 - the two rectangles to check.
2574 * Returns: TRUE iff these rectangles overlap.
2575 */
2576
2577static Boolean
2578RectanglesOverlap(XRectangle *rect1, XRectangle *rect2)
2579{
2580 return ( (rect1->x < rect2->x + (short) rect2->width) &&
2581 (rect2->x < rect1->x + (short) rect1->width) &&
2582 (rect1->y < rect2->y + (short) rect2->height) &&
2583 (rect2->y < rect1->y + (short) rect1->height) );
2584}
2585
2586/* Function Name: UpdateTextInRectangle.
2587 * Description: Updates the text in a rectangle.
2588 * Arguments: ctx - the text widget.
2589 * rect - the rectangle to update.
2590 * Returns: none.
2591 */
2592
2593static void
2594UpdateTextInRectangle(TextWidget ctx, XRectangle * rect)
2595{
2596 XawTextLineTableEntry *info = ctx->text.lt.info;
2597 int line, x = rect->x, y = rect->y;
2598 int right = rect->width + x, bottom = rect->height + y;
2599
2600 for (line = 0;( (line < ctx->text.lt.lines) &&
2601 IsValidLine(ctx, line)( ((line) == 0) || ((ctx)->text.lt.info[(line)].position !=
0) )
&& (info->y < bottom)); line++, info++)
2602 if ( (info + 1)->y >= y )
2603 UpdateTextInLine(ctx, line, x, right);
2604}
2605
2606/*
2607 * This routine processes all "expose region" XEvents. In general, its job
2608 * is to the best job at minimal re-paint of the text, displayed in the
2609 * window, that it can.
2610 */
2611
2612/* ARGSUSED */
2613static void
2614ProcessExposeRegion(Widget w, XEvent *event, Region region)
2615{
2616 TextWidget ctx = (TextWidget) w;
2617 XRectangle expose, cursor;
2618 Boolean need_to_draw;
2619
2620 if (event->type == Expose12) {
2621 expose.x = event->xexpose.x;
2622 expose.y = event->xexpose.y;
2623 expose.width = event->xexpose.width;
2624 expose.height = event->xexpose.height;
2625 }
2626 else if (event->type == GraphicsExpose13) {
2627 expose.x = event->xgraphicsexpose.x;
2628 expose.y = event->xgraphicsexpose.y;
2629 expose.width = event->xgraphicsexpose.width;
2630 expose.height = event->xgraphicsexpose.height;
2631 }
2632 else { /* No Expose */
2633 PopCopyQueue(ctx);
2634 return; /* no more processing necessary. */
2635 }
2636
2637 need_to_draw = TranslateExposeRegion(ctx, &expose);
2638 if ((event->type == GraphicsExpose13) && (event->xgraphicsexpose.count == 0))
2639 PopCopyQueue(ctx);
2640
2641 if (!need_to_draw)
2642 return; /* don't draw if we don't need to. */
2643
2644 _XawTextPrepareToUpdate(ctx);
2645 UpdateTextInRectangle(ctx, &expose);
2646 XawTextSinkGetCursorBounds(ctx->text.sink, &cursor);
2647 if (RectanglesOverlap(&cursor, &expose)) {
2648 SinkClearToBGXawTextSinkClearToBackground(ctx->text.sink, (Position) cursor.x, (Position) cursor.y,
2649 (Dimension) cursor.width, (Dimension) cursor.height);
2650 UpdateTextInRectangle(ctx, &cursor);
2651 }
2652 _XawTextExecuteUpdate(ctx);
2653
2654 _ShadowSurroundedBox((Widget)ctx, (ThreeDWidget)ctx->text.threeD,
2655 0, 0, ctx->core.width, ctx->core.height,
2656 ((ThreeDWidget)ctx->text.threeD)->threeD.relief, False0);
2657}
2658
2659/*
2660 * This routine does all setup required to syncronize batched screen updates
2661 */
2662
2663void
2664_XawTextPrepareToUpdate(TextWidget ctx)
2665{
2666 if (ctx->text.old_insert < 0) {
2667 InsertCursor((Widget)ctx, XawisOff);
2668 ctx->text.numranges = 0;
2669 ctx->text.showposition = FALSE0;
2670 ctx->text.old_insert = ctx->text.insertPos;
2671 }
2672}
2673
2674/*
2675 * This is a private utility routine used by _XawTextExecuteUpdate. It
2676 * processes all the outstanding update requests and merges update
2677 * ranges where possible.
2678 */
2679
2680static
2681void FlushUpdate(TextWidget ctx)
2682{
2683 int i, w;
2684 XawTextPosition updateFrom, updateTo;
2685 if (!XtIsRealized((Widget)ctx)(XtWindowOfObject((Widget)ctx) != 0L)) {
2686 ctx->text.numranges = 0;
2687 return;
2688 }
2689 while (ctx->text.numranges > 0) {
2690 updateFrom = ctx->text.updateFrom[0];
2691 w = 0;
2692 for (i = 1 ; i < ctx->text.numranges ; i++) {
2693 if (ctx->text.updateFrom[i] < updateFrom) {
2694 updateFrom = ctx->text.updateFrom[i];
2695 w = i;
2696 }
2697 }
2698 updateTo = ctx->text.updateTo[w];
2699 ctx->text.numranges--;
2700 ctx->text.updateFrom[w] = ctx->text.updateFrom[ctx->text.numranges];
2701 ctx->text.updateTo[w] = ctx->text.updateTo[ctx->text.numranges];
2702 for (i = ctx->text.numranges - 1 ; i >= 0 ; i--) {
2703 while (ctx->text.updateFrom[i] <= updateTo && i < ctx->text.numranges) {
2704 updateTo = ctx->text.updateTo[i];
2705 ctx->text.numranges--;
2706 ctx->text.updateFrom[i] = ctx->text.updateFrom[ctx->text.numranges];
2707 ctx->text.updateTo[i] = ctx->text.updateTo[ctx->text.numranges];
2708 }
2709 }
2710 DisplayText((Widget)ctx, updateFrom, updateTo);
2711 }
2712}
2713
2714/*
2715 * This is a private utility routine used by _XawTextExecuteUpdate. This
2716 * routine worries about edits causing new data or the insertion point becoming
2717 * invisible (off the screen, or under the horiz. scrollbar). Currently
2718 * it always makes it visible by scrolling. It probably needs
2719 * generalization to allow more options.
2720 */
2721
2722void
2723_XawTextShowPosition(TextWidget ctx)
2724{
2725 int x, y, lines, number;
2726 Boolean no_scroll;
2727 XawTextPosition max_pos, top, first;
2728
2729 if ( (!XtIsRealized((Widget)ctx)(XtWindowOfObject((Widget)ctx) != 0L)) || (ctx->text.lt.lines <= 0) )
2730 return;
2731
2732/*
2733 * Find out the bottom the visable window, and make sure that the
2734 * cursor does not go past the end of this space.
2735 *
2736 * This makes sure that the cursor does not go past the end of the
2737 * visable window.
2738 */
2739
2740 x = ctx->core.width;
2741 y = ctx->core.height - ctx->text.margin.bottom;
2742 if (ctx->text.hbar != NULL((void*)0))
2743 y -= ctx->text.hbar->core.height + 2 * ctx->text.hbar->core.border_width;
2744
2745 max_pos = PositionForXY (ctx, x, y);
2746 lines = LineForPosition(ctx, max_pos) + 1; /* number of visable lines. */
2747
2748 if ( (ctx->text.insertPos >= ctx->text.lt.top) &&
2749 (ctx->text.insertPos < max_pos))
2750 return;
2751
2752 first = ctx->text.lt.top;
2753 no_scroll = FALSE0;
2754
2755 if (ctx->text.insertPos < first) { /* We need to scroll down. */
2756 top = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.insertPos,
2757 XawstEOL, XawsdLeft, 1, FALSE0);
2758
2759 /* count the number of lines we have to scroll */
2760
2761 number = 0;
2762 while (first > top) {
2763 first = SrcScanXawTextSourceScan(ctx->text.source, first,
2764 XawstEOL, XawsdLeft, 1, TRUE1);
2765
2766 if ( - number > lines )
2767 break;
2768
2769 number--;
2770 }
2771
2772 if (first <= top) { /* If we found the proper number
2773 of lines. */
2774
2775 /* Back up to just before the last CR. */
2776
2777 first = SrcScanXawTextSourceScan(ctx->text.source, first,
2778 XawstPositions, XawsdRight, 1, TRUE1);
2779
2780 /* Check to make sure the cursor is visable. */
2781
2782 if (first <= top)
2783 number++;
2784
2785 lines = number;
2786 }
2787 else
2788 no_scroll = TRUE1;
2789 }
2790 else { /* We need to Scroll up */
2791 top = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.insertPos,
2792 XawstEOL, XawsdLeft, lines, FALSE0);
2793
2794 if (top < max_pos)
2795 lines = LineForPosition(ctx, top);
2796 else
2797 no_scroll = TRUE1;
2798 }
2799
2800 if (no_scroll) {
2801 _XawTextBuildLineTable(ctx, top, FALSE0);
2802 DisplayTextWindow((Widget)ctx);
2803 }
2804 else
2805 _XawTextVScroll(ctx, lines);
2806
2807 _XawTextSetScrollBars(ctx);
2808}
2809
2810/*
2811 * This routine causes all batched screen updates to be performed
2812 */
2813
2814void
2815_XawTextExecuteUpdate(TextWidget ctx)
2816{
2817 if ( ctx->text.update_disabled || (ctx->text.old_insert < 0) )
2818 return;
2819
2820 if((ctx->text.old_insert != ctx->text.insertPos) || (ctx->text.showposition))
2821 _XawTextShowPosition(ctx);
2822 FlushUpdate(ctx);
2823 InsertCursor((Widget)ctx, XawisOn);
2824 ctx->text.old_insert = -1;
2825}
2826
2827
2828static void
2829TextDestroy(Widget w)
2830{
2831 TextWidget ctx = (TextWidget)w;
2832
2833 DestroyHScrollBar(ctx);
2834 DestroyVScrollBar(ctx);
2835
2836 XtFree((char *)ctx->text.s.selections);
2837 XtFree((char *)ctx->text.lt.info);
2838 XtFree((char *)ctx->text.search);
2839 XtFree((char *)ctx->text.updateFrom);
2840 XtFree((char *)ctx->text.updateTo);
2841}
2842
2843/*
2844 * by the time we are managed (and get this far) we had better
2845 * have both a source and a sink
2846 */
2847
2848static void
2849Resize(Widget w)
2850{
2851 TextWidget ctx = (TextWidget) w;
2852
2853 PositionVScrollBar(ctx);
2854 PositionHScrollBar(ctx);
2855
2856 _XawTextBuildLineTable(ctx, ctx->text.lt.top, TRUE1);
2857 _XawTextSetScrollBars(ctx);
2858}
2859
2860/*
2861 * This routine allow the application program to Set attributes.
2862 */
2863
2864/*ARGSUSED*/
2865static Boolean
2866SetValues(Widget current, Widget request, Widget new, ArgList args, Cardinal *num_args)
2867{
2868 TextWidget oldtw = (TextWidget) current;
2869 TextWidget newtw = (TextWidget) new;
2870 Boolean redisplay = FALSE0;
2871 Boolean display_caret = newtw->text.display_caret;
2872
2873
2874 newtw->text.display_caret = oldtw->text.display_caret;
2875 _XawTextPrepareToUpdate(newtw);
2876 newtw->text.display_caret = display_caret;
2877
2878 if (oldtw->text.r_margin.left != newtw->text.r_margin.left) {
2879 newtw->text.margin.left = newtw->text.r_margin.left;
2880 if (newtw->text.vbar != NULL((void*)0))
2881 newtw->text.margin.left += newtw->text.vbar->core.width +
2882 newtw->text.vbar->core.border_width;
2883 redisplay = TRUE1;
2884 }
2885
2886 if (oldtw->text.scroll_vert != newtw->text.scroll_vert) {
2887 if (newtw->text.scroll_vert == XawtextScrollNever)
2888 DestroyVScrollBar(newtw);
2889 else if (newtw->text.scroll_vert == XawtextScrollAlways)
2890 CreateVScrollBar(newtw);
2891 redisplay = TRUE1;
2892 }
2893
2894 if (oldtw->text.r_margin.bottom != newtw->text.r_margin.bottom) {
2895 newtw->text.margin.bottom = newtw->text.r_margin.bottom;
2896 if (newtw->text.hbar != NULL((void*)0))
2897 newtw->text.margin.bottom += newtw->text.hbar->core.height +
2898 newtw->text.hbar->core.border_width;
2899 redisplay = TRUE1;
2900 }
2901
2902 if (oldtw->text.scroll_horiz != newtw->text.scroll_horiz) {
2903 if (newtw->text.scroll_horiz == XawtextScrollNever)
2904 DestroyHScrollBar(newtw);
2905 else if (newtw->text.scroll_horiz == XawtextScrollAlways)
2906 CreateHScrollBar(newtw);
2907 redisplay = TRUE1;
2908 }
2909
2910 if ( oldtw->text.source != newtw->text.source )
2911 XawTextSetSource( (Widget) newtw, newtw->text.source, newtw->text.lt.top);
2912
2913 newtw->text.redisplay_needed = False0;
2914 XtSetValues( (Widget)newtw->text.source, args, *num_args );
2915 XtSetValues( (Widget)newtw->text.sink, args, *num_args );
2916
2917 if ( oldtw->text.wrap != newtw->text.wrap ||
2918 oldtw->text.lt.top != newtw->text.lt.top ||
2919 oldtw->text.r_margin.right != newtw->text.r_margin.right ||
2920 oldtw->text.r_margin.top != newtw->text.r_margin.top ||
2921 oldtw->text.sink != newtw->text.sink ||
2922 newtw->text.redisplay_needed )
2923 {
2924 _XawTextBuildLineTable(newtw, newtw->text.lt.top, TRUE1);
2925 redisplay = TRUE1;
2926 }
2927
2928 if (oldtw->text.insertPos != newtw->text.insertPos) {
2929 newtw->text.showposition = TRUE1;
2930 redisplay = TRUE1;
2931 }
2932
2933 _XawTextExecuteUpdate(newtw);
2934 if (redisplay)
2935 _XawTextSetScrollBars(newtw);
2936
2937 return redisplay;
2938}
2939
2940/* invoked by the Simple widget's SetValues */
2941static Boolean
2942ChangeSensitive(Widget w)
2943{
2944 Arg args[1];
2945 TextWidget tw = (TextWidget) w;
2946
2947 (*(&simpleClassRec)->simple_class.change_sensitive)(w);
2948
2949 XtSetArg(args[0], XtNancestorSensitive,((void)( (args[0]).name = (((char*)&XtStrings[34])), (args
[0]).value = (XtArgVal)((tw->core.ancestor_sensitive &&
tw->core.sensitive)) ))
2950 (tw->core.ancestor_sensitive && tw->core.sensitive))((void)( (args[0]).name = (((char*)&XtStrings[34])), (args
[0]).value = (XtArgVal)((tw->core.ancestor_sensitive &&
tw->core.sensitive)) ))
;
2951 if (tw->text.vbar)
2952 XtSetValues(tw->text.vbar, args, ONE((Cardinal)1));
2953 if (tw->text.hbar)
2954 XtSetValues(tw->text.hbar, args, ONE((Cardinal)1));
2955 return False0;
2956}
2957
2958/* Function Name: GetValuesHook
2959 * Description: This is a get values hook routine that gets the
2960 * values in the text source and sink.
2961 * Arguments: w - the Text Widget.
2962 * args - the argument list.
2963 * num_args - the number of args.
2964 * Returns: none.
2965 */
2966
2967static void
2968GetValuesHook(Widget w, ArgList args, Cardinal * num_args)
2969{
2970 XtGetValues( ((TextWidget) w)->text.source, args, *num_args );
2971 XtGetValues( ((TextWidget) w)->text.sink, args, *num_args );
2972}
2973
2974/* Function Name: FindGoodPosition
2975 * Description: Returns a valid position given any postition
2976 * Arguments: pos - any position.
2977 * Returns: a position between (0 and lastPos);
2978 */
2979
2980static XawTextPosition
2981FindGoodPosition(TextWidget ctx, XawTextPosition pos)
2982{
2983 if (pos < 0) return(0);
2984 return ( ((pos > ctx->text.lastPos) ? ctx->text.lastPos : pos) );
2985}
2986
2987/************************************************************
2988 *
2989 * Routines for handling the copy area expose queue.
2990 *
2991 ************************************************************/
2992
2993/* Function Name: PushCopyQueue
2994 * Description: Pushes a value onto the copy queue.
2995 * Arguments: ctx - the text widget.
2996 * h, v - amount of offset in the horiz and vert directions.
2997 * Returns: none
2998 */
2999
3000static void
3001PushCopyQueue(TextWidget ctx, int h, int v)
3002{
3003 struct text_move * offsets = XtNew(struct text_move)((struct text_move *) XtMalloc((unsigned) sizeof(struct text_move
)))
;
3004
3005 offsets->h = h;
3006 offsets->v = v;
3007 offsets->next = NULL((void*)0);
3008
3009 if (ctx->text.copy_area_offsets == NULL((void*)0))
3010 ctx->text.copy_area_offsets = offsets;
3011 else {
3012 struct text_move * end = ctx->text.copy_area_offsets;
3013 for ( ; end->next != NULL((void*)0); end = end->next) {}
3014 end->next = offsets;
3015 }
3016}
3017
3018/* Function Name: PopCopyQueue
3019 * Description: Pops the top value off of the copy queue.
3020 * Arguments: ctx - the text widget.
3021 * Returns: none.
3022 */
3023
3024static void
3025PopCopyQueue(TextWidget ctx)
3026{
3027 struct text_move * offsets = ctx->text.copy_area_offsets;
3028
3029 if (offsets == NULL((void*)0))
3030 (void) printf( "Xaw Text widget %s: empty copy queue\n",
3031 XtName( (Widget) ctx ) );
3032 else {
3033 ctx->text.copy_area_offsets = offsets->next;
3034 XtFree((char *) offsets); /* free what you allocate. */
3035 }
3036}
3037
3038/* Function Name: TranslateExposeRegion
3039 * Description: Translates the expose that came into
3040 * the cordinates that now exist in the Text widget.
3041 * Arguments: ctx - the text widget.
3042 * expose - a Rectangle, who's region currently
3043 * contains the expose event location.
3044 * this region will be returned containing
3045 * the new rectangle.
3046 * Returns: True if there is drawing that needs to be done.
3047 */
3048
3049static Boolean
3050TranslateExposeRegion(TextWidget ctx, XRectangle *expose)
3051{
3052 struct text_move * offsets = ctx->text.copy_area_offsets;
3053 int value;
3054 int x, y, width, height;
3055
3056 /*
3057 * Skip over the first one, this has already been taken into account.
3058 */
3059
3060 if (!offsets || !(offsets = offsets->next))
3061 return(TRUE1);
3062
3063 x = expose->x;
3064 y = expose->y;
3065 width = expose->width;
3066 height = expose->height;
3067
3068 while (offsets) {
3069 x += offsets->h;
3070 y += offsets->v;
3071 offsets = offsets->next;
3072 }
3073
3074 /*
3075 * remove that area of the region that is now outside the window.
3076 */
3077
3078 if (y < 0) {
3079 height += y;
3080 y = 0;
3081 }
3082
3083 value = y + height - ctx->core.height;
3084 if (value > 0)
3085 height -= value;
3086
3087 if (height <= 0)
3088 return(FALSE0); /* no need to draw outside the window. */
3089
3090 /*
3091 * and now in the horiz direction...
3092 */
3093
3094 if (x < 0) {
3095 width += x;
3096 x = 0;
3097 }
3098
3099 value = x + width - ctx->core.width;
3100 if (value > 0)
3101 width -= value;
3102
3103 if (width <= 0)
3104 return(FALSE0); /* no need to draw outside the window. */
3105
3106 expose->x = x;
3107 expose->y = y;
3108 expose->width = width;
3109 expose->height = height;
3110 return(TRUE1);
3111}
3112
3113/* Li wrote this so the IM can find a given text position's screen position. */
3114
3115void
3116_XawTextPosToXY(
3117 Widget w,
3118 XawTextPosition pos,
3119 Position* x,
3120 Position* y )
3121{
3122 int line;
3123 LineAndXYForPosition( (TextWidget)w, pos, &line, x, y );
3124}
3125
3126/*******************************************************************
3127The following routines provide procedural interfaces to Text window state
3128setting and getting. They need to be redone so than the args code can use
3129them. I suggest we create a complete set that takes the context as an
3130argument and then have the public version lookup the context and call the
3131internal one. The major value of this set is that they have actual application
3132clients and therefore the functionality provided is required for any future
3133version of Text.
3134********************************************************************/
3135
3136void
3137XawTextDisplay (Widget w)
3138{
3139 if (!XtIsRealized(w)(XtWindowOfObject(w) != 0L)) return;
3140
3141 _XawTextPrepareToUpdate( (TextWidget) w);
3142 DisplayTextWindow(w);
3143 _XawTextExecuteUpdate( (TextWidget) w);
3144}
3145
3146void
3147XawTextSetSelectionArray(Widget w, XawTextSelectType *sarray)
3148{
3149 ((TextWidget)w)->text.sarray = sarray;
3150}
3151
3152void
3153XawTextGetSelectionPos(Widget w, XawTextPosition *left, XawTextPosition *right)
3154{
3155 *left = ((TextWidget) w)->text.s.left;
3156 *right = ((TextWidget) w)->text.s.right;
3157}
3158
3159
3160void
3161XawTextSetSource(Widget w, Widget source, XawTextPosition startPos)
3162{
3163 TextWidget ctx = (TextWidget) w;
3164
3165 ctx->text.source = source;
3166 ctx->text.lt.top = startPos;
3167 ctx->text.s.left = ctx->text.s.right = 0;
3168 ctx->text.insertPos = startPos;
3169 ctx->text.lastPos = GETLASTPOSXawTextSourceScan(ctx->text.source, 0, XawstAll, XawsdRight
, 1, 1)
;
3170
3171 _XawTextBuildLineTable(ctx, ctx->text.lt.top, TRUE1);
3172 XawTextDisplay(w);
3173}
3174
3175/*
3176 * This public routine deletes the text from startPos to endPos in a source and
3177 * then inserts, at startPos, the text that was passed. As a side effect it
3178 * "invalidates" that portion of the displayed text (if any), so that things
3179 * will be repainted properly.
3180 */
3181
3182int
3183XawTextReplace(Widget w, XawTextPosition startPos, XawTextPosition endPos,
3184 XawTextBlock *text)
3185{
3186 TextWidget ctx = (TextWidget) w;
3187 int result;
3188
3189 _XawTextPrepareToUpdate(ctx);
3190 endPos = FindGoodPosition(ctx, endPos);
3191 startPos = FindGoodPosition(ctx, startPos);
3192 if ((result = _XawTextReplace(ctx, startPos, endPos, text)) == XawEditDone0) {
3193 int delta = text->length - (endPos - startPos);
3194 if (ctx->text.insertPos >= (endPos + delta)) {
3195 XawTextScanDirection sd = (delta < 0) ? XawsdLeft : XawsdRight;
3196 ctx->text.insertPos = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.insertPos,
3197 XawstPositions, sd, abs(delta), TRUE1);
3198 }
3199 }
3200
3201 _XawTextCheckResize(ctx);
3202 _XawTextExecuteUpdate(ctx);
3203 _XawTextSetScrollBars(ctx);
3204
3205 return result;
3206}
3207
3208XawTextPosition
3209XawTextTopPosition(Widget w)
3210{
3211 return( ((TextWidget) w)->text.lt.top );
3212}
3213
3214void
3215XawTextSetInsertionPoint(Widget w, XawTextPosition position)
3216{
3217 TextWidget ctx = (TextWidget) w;
3218
3219 _XawTextPrepareToUpdate(ctx);
3220 ctx->text.insertPos = FindGoodPosition(ctx, position);
3221 ctx->text.showposition = TRUE1;
3222
3223 _XawTextExecuteUpdate(ctx);
3224}
3225
3226XawTextPosition
3227XawTextGetInsertionPoint(Widget w)
3228{
3229 return( ((TextWidget) w)->text.insertPos);
3230}
3231
3232/*
3233 * NOTE: Must walk the selection list in opposite order from LoseSelection.
3234 */
3235
3236void
3237XawTextUnsetSelection(Widget w)
3238{
3239 TextWidget ctx = (TextWidget)w;
3240
3241 while (ctx->text.s.atom_count != 0) {
3242 Atom sel = ctx->text.s.selections[ctx->text.s.atom_count - 1];
3243 if ( sel != (Atom) 0 ) {
3244/*
3245 * As selections are lost the atom_count will decrement.
3246 */
3247 if (GetCutBufferNumber(sel) == NOT_A_CUT_BUFFER-1)
3248 XtDisownSelection(w, sel, ctx->text.time);
3249 LoseSelection(w, &sel); /* In case this is a cut buffer, or
3250 XtDisownSelection failed to call us. */
3251 }
3252 }
3253}
3254
3255void
3256XawTextSetSelection (Widget w, XawTextPosition left, XawTextPosition right)
3257{
3258 TextWidget ctx = (TextWidget) w;
3259
3260 _XawTextPrepareToUpdate(ctx);
3261 _XawTextSetSelection(ctx, FindGoodPosition(ctx, left),
3262 FindGoodPosition(ctx, right), (String*)NULL((void*)0), ZERO((Cardinal)0));
3263 _XawTextExecuteUpdate(ctx);
3264}
3265
3266void
3267XawTextInvalidate(Widget w, XawTextPosition from, XawTextPosition to)
3268{
3269 TextWidget ctx = (TextWidget) w;
3270
3271 from = FindGoodPosition(ctx, from);
3272 to = FindGoodPosition(ctx, to);
3273 ctx->text.lastPos = GETLASTPOSXawTextSourceScan(ctx->text.source, 0, XawstAll, XawsdRight
, 1, 1)
;
3274 _XawTextPrepareToUpdate(ctx);
3275 _XawTextNeedsUpdating(ctx, from, to);
3276 _XawTextBuildLineTable(ctx, ctx->text.lt.top, TRUE1);
3277 _XawTextExecuteUpdate(ctx);
3278}
3279
3280/*ARGSUSED*/
3281void
3282XawTextDisableRedisplay(Widget w)
3283{
3284 ((TextWidget) w)->text.update_disabled = True1;
3285 _XawTextPrepareToUpdate( (TextWidget) w);
3286}
3287
3288void
3289XawTextEnableRedisplay(Widget w)
3290{
3291 TextWidget ctx = (TextWidget)w;
3292 XawTextPosition lastPos;
3293
3294 if (!ctx->text.update_disabled) return;
3295
3296 ctx->text.update_disabled = False0;
3297 lastPos = ctx->text.lastPos = GETLASTPOSXawTextSourceScan(ctx->text.source, 0, XawstAll, XawsdRight
, 1, 1)
;
3298 ctx->text.lt.top = FindGoodPosition(ctx, ctx->text.lt.top);
3299 ctx->text.insertPos = FindGoodPosition(ctx, ctx->text.insertPos);
3300 if ( (ctx->text.s.left > lastPos) || (ctx->text.s.right > lastPos) )
3301 ctx->text.s.left = ctx->text.s.right = 0;
3302
3303 _XawTextBuildLineTable(ctx, ctx->text.lt.top, TRUE1);
3304 if (XtIsRealized(w)(XtWindowOfObject(w) != 0L))
3305 DisplayTextWindow(w);
3306 _XawTextExecuteUpdate(ctx);
3307}
3308
3309Widget
3310XawTextGetSource(Widget w)
3311{
3312 return ((TextWidget)w)->text.source;
3313}
3314
3315Widget
3316XawTextGetSink(Widget w)
3317{
3318 return (((TextWidget)w)->text.sink);
3319}
3320
3321void
3322XawTextDisplayCaret (Widget w,
3323#if NeedWidePrototypes1
3324 /* Boolean */ int display_caret)
3325#else
3326 Boolean display_caret)
3327#endif
3328{
3329 TextWidget ctx = (TextWidget) w;
3330
3331 if (ctx->text.display_caret == display_caret) return;
3332
3333 if (XtIsRealized(w)(XtWindowOfObject(w) != 0L)) {
3334 _XawTextPrepareToUpdate(ctx);
3335 ctx->text.display_caret = display_caret;
3336 _XawTextExecuteUpdate(ctx);
3337 }
3338 else
3339 ctx->text.display_caret = display_caret;
3340}
3341
3342/* Function Name: XawTextSearch(w, dir, text).
3343 * Description: searches for the given text block.
3344 * Arguments: w - The text widget.
3345 * dir - The direction to search.
3346 * text - The text block containing info about the string
3347 * to search for.
3348 * Returns: The position of the text found, or XawTextSearchError on
3349 * an error.
3350 */
3351
3352XawTextPosition
3353XawTextSearch(Widget w,
3354#if NeedWidePrototypes1
3355 /* XawTextScanDirection */ int dir,
3356#else
3357 XawTextScanDirection dir,
3358#endif
3359 XawTextBlock *text)
3360{
3361 TextWidget ctx = (TextWidget) w;
3362
3363 return(SrcSearchXawTextSourceSearch(ctx->text.source, ctx->text.insertPos, dir, text));
3364}
3365
3366TextClassRec textClassRec = {
3367 { /* core fields */
3368 /* superclass */ (WidgetClass) &simpleClassRec,
3369 /* class_name */ "Text",
3370 /* widget_size */ sizeof(TextRec),
3371 /* class_initialize */ ClassInitialize,
3372 /* class_part_init */ NULL((void*)0),
3373 /* class_inited */ FALSE0,
3374 /* initialize */ Initialize,
3375 /* initialize_hook */ NULL((void*)0),
3376 /* realize */ Realize,
3377 /* actions */ _XawTextActionsTable,
3378 /* num_actions */ 0, /* Set in ClassInitialize. */
3379 /* resources */ resources,
3380 /* num_ resource */ XtNumber(resources)((Cardinal) (sizeof(resources) / sizeof(resources[0]))),
3381 /* xrm_class */ NULLQUARK((XrmQuark) 0),
3382 /* compress_motion */ TRUE1,
3383 /* compress_exposure*/ XtExposeGraphicsExpose0x10 | XtExposeNoExpose0x40,
3384 /* compress_enterleave*/ TRUE1,
3385 /* visible_interest */ FALSE0,
3386 /* destroy */ TextDestroy,
3387 /* resize */ Resize,
3388 /* expose */ ProcessExposeRegion,
3389 /* set_values */ SetValues,
3390 /* set_values_hook */ NULL((void*)0),
3391 /* set_values_almost*/ XtInheritSetValuesAlmost((XtAlmostProc) _XtInherit),
3392 /* get_values_hook */ GetValuesHook,
3393 /* accept_focus */ NULL((void*)0),
3394 /* version */ XtVersion(11 * 1000 + 6),
3395 /* callback_private */ NULL((void*)0),
3396 /* tm_table */ NULL((void*)0), /* set in ClassInitialize */
3397 /* query_geometry */ XtInheritQueryGeometry((XtGeometryHandler) _XtInherit),
3398 /* display_accelerator*/ XtInheritDisplayAccelerator((XtStringProc) _XtInherit),
3399 /* extension */ NULL((void*)0)
3400 },
3401 { /* Simple fields */
3402 /* change_sensitive */ ChangeSensitive
3403 },
3404 { /* text fields */
3405 /* empty */ 0
3406 }
3407};
3408
3409WidgetClass textWidgetClass = (WidgetClass)&textClassRec;