Bug Summary

File:Text.c
Location:line 1713, column 2
Description:Value stored to 'y1' is never read

Annotated Source Code

1/***********************************************************
2
3Copyright 1987, 1988, 1994, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25
26Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
27
28 All Rights Reserved
29
30Permission to use, copy, modify, and distribute this software and its
31documentation for any purpose and without fee is hereby granted,
32provided that the above copyright notice appear in all copies and that
33both that copyright notice and this permission notice appear in
34supporting documentation, and that the name of Digital not be
35used in advertising or publicity pertaining to distribution of the
36software without specific, written prior permission.
37
38DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
39ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
40DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
41ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
42WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
43ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
44SOFTWARE.
45
46******************************************************************/
47
48/*
49 * Copyright (c) 1998 by The XFree86 Project, Inc.
50 *
51 * Permission is hereby granted, free of charge, to any person obtaining a
52 * copy of this software and associated documentation files (the "Software"),
53 * to deal in the Software without restriction, including without limitation
54 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
55 * and/or sell copies of the Software, and to permit persons to whom the
56 * Software is furnished to do so, subject to the following conditions:
57 *
58 * The above copyright notice and this permission notice shall be included in
59 * all copies or substantial portions of the Software.
60 *
61 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
62 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
63 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
64 * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
65 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
66 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
67 * SOFTWARE.
68 *
69 * Except as contained in this notice, the name of the XFree86 Project shall
70 * not be used in advertising or otherwise to promote the sale, use or other
71 * dealings in this Software without prior written authorization from the
72 * XFree86 Project.
73 */
74
75#ifdef HAVE_CONFIG_H1
76#include <config.h>
77#endif
78#include <stdio.h>
79#include <X11/IntrinsicP.h>
80#include <X11/StringDefs.h>
81#include <X11/Shell.h>
82#include <X11/Xatom.h>
83#include <X11/Xfuncs.h>
84#include <X11/Xutil.h>
85#include <X11/Xmu/Misc.h>
86#include <X11/Xmu/Xmu.h>
87#include <X11/Xaw/Cardinals.h>
88#include <X11/Xaw/MultiSinkP.h>
89#include <X11/Xaw/TextP.h>
90#include <X11/Xaw/TextSrcP.h>
91#include <X11/Xaw/TextSinkP.h>
92#include <X11/Xaw/Scrollbar.h>
93#include <X11/Xaw/XawImP.h>
94#include <X11/Xaw/XawInit.h>
95#include "Private.h"
96#include "XawI18n.h"
97
98#ifndef MAX_LEN_CT6
99#define MAX_LEN_CT6 6 /* for sequence: ESC $ ( A \xx \xx */
100#endif
101
102unsigned long FMT8BIT = 0L;
103unsigned long XawFmt8Bit = 0L;
104unsigned long XawFmtWide = 0L;
105
106#define SinkClearToBG_XawTextSinkClearToBackground _XawTextSinkClearToBackground
107
108#define SrcScanXawTextSourceScan XawTextSourceScan
109#define SrcReadXawTextSourceRead XawTextSourceRead
110#define SrcReplaceXawTextSourceReplace XawTextSourceReplace
111#define SrcSearchXawTextSourceSearch XawTextSourceSearch
112#define SrcCvtSelXawTextSourceConvertSelection XawTextSourceConvertSelection
113#define SrcSetSelectionXawTextSourceSetSelection XawTextSourceSetSelection
114
115#define MULTI_CLICK_TIME500L 500L
116
117#define SRC_CHANGE_NONE0 0
118#define SRC_CHANGE_AFTER1 1
119#define SRC_CHANGE_BEFORE2 2
120#define SRC_CHANGE_OVERLAP3 3
121
122#define Superclass(&simpleClassRec) (&simpleClassRec)
123
124/*
125 * Compute a the maximum length of a cut buffer that we can pass at any
126 * time. The 64 allows for the overhead of the Change Property request.
127 */
128#define MAX_CUT_LEN(dpy)(XMaxRequestSize(dpy) - 64) (XMaxRequestSize(dpy) - 64)
129
130#define ClearWindow(ctx)_XawTextNeedsUpdating((ctx), (ctx)->text.lt.top, (ctx)->
text.lt.info[ctx->text.lt.lines].position)
\
131 _XawTextNeedsUpdating((ctx), \
132 (ctx)->text.lt.top, \
133 (ctx)->text.lt.info[ctx->text.lt.lines].position)
134
135/*
136 * Class Methods
137 */
138static void XawTextClassInitialize(void);
139static void XawTextInitialize(Widget, Widget, ArgList, Cardinal*);
140static void XawTextRealize(Widget, XtValueMask*, XSetWindowAttributes*);
141static void XawTextDestroy(Widget);
142static void XawTextResize(Widget);
143static void XawTextExpose(Widget, XEvent*, Region);
144static Boolean XawTextSetValues(Widget, Widget, Widget, ArgList, Cardinal*);
145static void XawTextGetValuesHook(Widget, ArgList, Cardinal*);
146static Boolint XawTextChangeSensitive(Widget);
147
148/*
149 * Prototypes
150 */
151static XawTextPosition _BuildLineTable(TextWidget, XawTextPosition, int);
152static void _CreateCutBuffers(Display*);
153static Boolean TextConvertSelection(Widget, Atom*, Atom*, Atom*, XtPointer*,
154 unsigned long*, int*);
155static int CountLines(TextWidget, XawTextPosition, XawTextPosition);
156static void CreateHScrollBar(TextWidget);
157static void CreateVScrollBar(TextWidget);
158static void CvtStringToScrollMode(XrmValuePtr, Cardinal*,
159 XrmValuePtr, XrmValuePtr);
160static Boolean CvtScrollModeToString(Display*, XrmValue*, Cardinal*,
161 XrmValue*, XrmValue*, XtPointer*);
162static void CvtStringToWrapMode(XrmValuePtr, Cardinal*,
163 XrmValuePtr, XrmValuePtr);
164static Boolean CvtWrapModeToString(Display*, XrmValue*, Cardinal*,
165 XrmValue*, XrmValue*, XtPointer*);
166static Boolean CvtStringToJustifyMode(Display*, XrmValue*, Cardinal*,
167 XrmValue*, XrmValue*, XtPointer*);
168static Boolean CvtJustifyModeToString(Display*, XrmValue*, Cardinal*,
169 XrmValue*, XrmValue*, XtPointer*);
170static void DestroyHScrollBar(TextWidget);
171static void DestroyVScrollBar(TextWidget);
172#ifndef OLDXAW1
173static void DisplayText(Widget, XawTextPosition, XawTextPosition);
174#endif
175static void OldDisplayText(Widget, XawTextPosition, XawTextPosition);
176static void DisplayTextWindow(Widget);
177static void DoCopyArea(TextWidget, int, int, unsigned int, unsigned int,
178 int, int);
179static void DoSelection(TextWidget, XawTextPosition, Time, Boolint);
180static void ExtendSelection(TextWidget, XawTextPosition, Boolint);
181static XawTextPosition FindGoodPosition(TextWidget, XawTextPosition);
182static void FlushUpdate(TextWidget);
183static int GetCutBufferNumber(Atom);
184static int GetMaxTextWidth(TextWidget);
185static unsigned int GetWidestLine(TextWidget);
186static void HScroll(Widget, XtPointer, XtPointer);
187static void HJump(Widget, XtPointer, XtPointer);
188static void InsertCursor(Widget, XawTextInsertState);
189static Boolint LineAndXYForPosition(TextWidget, XawTextPosition, int*,
190 int*, int*);
191static int LineForPosition(TextWidget, XawTextPosition);
192static void TextLoseSelection(Widget, Atom*);
193static Boolint MatchSelection(Atom, XawTextSelection*);
194static void ModifySelection(TextWidget, XawTextPosition, XawTextPosition);
195static XawTextPosition PositionForXY(TextWidget, int, int);
196static void PositionHScrollBar(TextWidget);
197static void PositionVScrollBar(TextWidget);
198#ifndef OLDXAW1
199static int ResolveColumnNumber(TextWidget);
200static int ResolveLineNumber(TextWidget);
201#endif
202static void _SetSelection(TextWidget, XawTextPosition, XawTextPosition,
203 Atom*, Cardinal);
204static void TextSinkResize(Widget);
205static void UpdateTextInRectangle(TextWidget, XRectangle*);
206static void UpdateTextInLine(TextWidget, int, int, int);
207static void VScroll(Widget, XtPointer, XtPointer);
208static void VJump(Widget, XtPointer, XtPointer);
209
210/*
211 * External
212 */
213void _XawTextAlterSelection(TextWidget,
214 XawTextSelectionMode, XawTextSelectionAction,
215 String*, Cardinal*);
216void _XawTextCheckResize(TextWidget);
217void _XawTextClearAndCenterDisplay(TextWidget);
218void _XawTextExecuteUpdate(TextWidget);
219char *_XawTextGetText(TextWidget, XawTextPosition, XawTextPosition);
220void _XawTextPrepareToUpdate(TextWidget);
221int _XawTextReplace(TextWidget, XawTextPosition, XawTextPosition,
222 XawTextBlock*);
223Atom *_XawTextSelectionList(TextWidget, String*, Cardinal);
224void _XawTextSetScrollBars(TextWidget);
225void _XawTextSetSelection(TextWidget, XawTextPosition, XawTextPosition,
226 String*, Cardinal);
227void _XawTextVScroll(TextWidget, int);
228void XawTextScroll(TextWidget, int, int);
229void _XawTextSetSource(Widget, Widget, XawTextPosition, XawTextPosition);
230#ifndef OLDXAW1
231void _XawTextSetLineAndColumnNumber(TextWidget, Boolint);
232#endif
233void _XawTextSourceChanged(Widget, XawTextPosition, XawTextPosition,
234 XawTextBlock*, int);
235
236/* Not used by other modules, but were extern on previous versions
237 * of the library
238 */
239void _XawTextShowPosition(TextWidget);
240
241/*
242 * From TextAction.c
243 */
244extern void _XawTextZapSelection(TextWidget, XEvent*, Boolint);
245
246/*
247 * From TextSrc.c
248 */
249void _XawSourceAddText(Widget, Widget);
250void _XawSourceRemoveText(Widget, Widget, Boolint);
251Boolint _XawTextSourceNewLineAtEOF(Widget);
252
253/*
254 * From TextSink.c
255 */
256void _XawTextSinkClearToBackground(Widget, int, int, unsigned, unsigned);
257void _XawTextSinkDisplayText(Widget, int, int, XawTextPosition, XawTextPosition,
258 Boolint);
259
260/****************************************************************
261 *
262 * Full class record constant
263 *
264 ****************************************************************/
265/*
266 * From TextTr.c
267 */
268static XawTextSelectType defaultSelectTypes[] = {
269 XawselectPosition, XawselectAlphaNumeric, XawselectWord, XawselectLine,
270 XawselectParagraph, XawselectAll, XawselectNull,
271};
272
273static XPointer defaultSelectTypesPtr = (XPointer)defaultSelectTypes;
274static Dimension defWidth = 100;
275static Dimension defHeight = DEFAULT_TEXT_HEIGHT((Dimension)~0);
276
277#define offset(field) XtOffsetOf(TextRec, field)__builtin_offsetof(TextRec, field)
278static XtResource resources[] = {
279 {
280 XtNwidth((char*)&XtStrings[872]),
281 XtCWidth((char*)&XtStrings[1510]),
282 XtRDimension((char*)&XtStrings[1618]),
283 sizeof(Dimension),
284 offset(core.width),
285 XtRDimension((char*)&XtStrings[1618]),
286 (XtPointer)&defWidth
287 },
288 {
289 XtNcursor"cursor",
290 XtCCursor((char*)&XtStrings[976]),
291 XtRCursor((char*)&XtStrings[1611]),
292 sizeof(Cursor),
293 offset(simple.cursor),
294 XtRString((char*)&XtStrings[1797]),
295 "xterm"
296 },
297 {
298 XtNheight((char*)&XtStrings[234]),
299 XtCHeight((char*)&XtStrings[1051]),
300 XtRDimension((char*)&XtStrings[1618]),
301 sizeof(Dimension),
302 offset(core.height),
303 XtRDimension((char*)&XtStrings[1618]),
304 (XtPointer)&defHeight
305 },
306 {
307 XtNdisplayPosition"displayPosition",
308 XtCTextPosition((char*)&XtStrings[1435]),
309 XtRInt((char*)&XtStrings[1718]),
310 sizeof(XawTextPosition),
311 offset(text.lt.top),
312 XtRImmediate((char*)&XtStrings[1695]),
313 (XtPointer)0
314 },
315 {
316 XtNinsertPosition((char*)&XtStrings[326]),
317 XtCTextPosition((char*)&XtStrings[1435]),
318 XtRInt((char*)&XtStrings[1718]),
319 sizeof(XawTextPosition),
320 offset(text.insertPos),
321 XtRImmediate((char*)&XtStrings[1695]),
322 (XtPointer)0
323 },
324 {
325 XtNleftMargin"leftMargin",
326 XtCMargin((char*)&XtStrings[1182]),
327 XtRPosition((char*)&XtStrings[1775]),
328 sizeof(Position),
329 offset(text.r_margin.left),
330 XtRImmediate((char*)&XtStrings[1695]),
331 (XtPointer)2
332 },
333 {
334 XtNrightMargin"rightMargin",
335 XtCMargin((char*)&XtStrings[1182]),
336 XtRPosition((char*)&XtStrings[1775]),
337 sizeof(Position),
338 offset(text.r_margin.right),
339 XtRImmediate((char*)&XtStrings[1695]),
340 (XtPointer)4
341 },
342 {
343 XtNtopMargin"topMargin",
344 XtCMargin((char*)&XtStrings[1182]),
345 XtRPosition((char*)&XtStrings[1775]),
346 sizeof(Position),
347 offset(text.r_margin.top),
348 XtRImmediate((char*)&XtStrings[1695]),
349 (XtPointer)2
350 },
351 {
352 XtNbottomMargin"bottomMargin",
353 XtCMargin((char*)&XtStrings[1182]),
354 XtRPosition((char*)&XtStrings[1775]),
355 sizeof(Position),
356 offset(text.r_margin.bottom),
357 XtRImmediate((char*)&XtStrings[1695]),
358 (XtPointer)2
359 },
360 {
361 XtNselectTypes"selectTypes",
362 XtCSelectTypes"SelectTypes",
363 XtRPointer((char*)&XtStrings[1767]),
364 sizeof(XawTextSelectType*),
365 offset(text.sarray),
366 XtRPointer((char*)&XtStrings[1767]),
367 (XtPointer)&defaultSelectTypesPtr
368 },
369 {
370 XtNtextSource((char*)&XtStrings[761]),
371 XtCTextSource((char*)&XtStrings[1457]),
372 XtRWidget((char*)&XtStrings[1865]),
373 sizeof(Widget),
374 offset(text.source),
375 XtRImmediate((char*)&XtStrings[1695]),
376 NULL((void*)0)
377 },
378 {
379 XtNtextSink((char*)&XtStrings[752]),
380 XtCTextSink((char*)&XtStrings[1448]),
381 XtRWidget((char*)&XtStrings[1865]),
382 sizeof(Widget),
383 offset(text.sink),
384 XtRImmediate((char*)&XtStrings[1695]),
385 NULL((void*)0)
386 },
387 {
388 XtNdisplayCaret"displayCaret",
389 XtCOutput"Output",
390 XtRBoolean((char*)&XtStrings[1561]),
391 sizeof(Boolean),
392 offset(text.display_caret),
393 XtRImmediate((char*)&XtStrings[1695]),
394 (XtPointer)True1
395 },
396 {
397 XtNscrollVertical"scrollVertical",
398 XtCScroll"Scroll",
399 XtRScrollMode"ScrollMode",
400 sizeof(XawTextScrollMode),
401 offset(text.scroll_vert),
402 XtRImmediate((char*)&XtStrings[1695]),
403 (XtPointer)False0
404 },
405 {
406 XtNscrollHorizontal"scrollHorizontal",
407 XtCScroll"Scroll",
408 XtRScrollMode"ScrollMode",
409 sizeof(XawTextScrollMode),
410 offset(text.scroll_horiz),
411 XtRImmediate((char*)&XtStrings[1695]),
412 (XtPointer)False0
413 },
414 {
415 XtNwrap"wrap",
416 XtCWrap"Wrap",
417 XtRWrapMode"WrapMode",
418 sizeof(XawTextWrapMode),
419 offset(text.wrap),
420 XtRImmediate((char*)&XtStrings[1695]),
421 (XtPointer)XawtextWrapNever
422 },
423 {
424 XtNautoFill"autoFill",
425 XtCAutoFill"AutoFill",
426 XtRBoolean((char*)&XtStrings[1561]),
427 sizeof(Boolean),
428 offset(text.auto_fill),
429 XtRImmediate((char*)&XtStrings[1695]),
430 (XtPointer)False0
431 },
432#ifndef OLDXAW1
433 {
434 XtNpositionCallback"positionCallback",
435 XtCCallback((char*)&XtStrings[952]),
436 XtRCallback((char*)&XtStrings[1569]),
437 sizeof(XtPointer),
438 offset(text.position_callbacks),
439 XtRCallback((char*)&XtStrings[1569]),
440 NULL((void*)0)
441 },
442 {
443 XtNleftColumn"leftColumn",
444 XtCColumn"Column",
445 XtRShort((char*)&XtStrings[1791]),
446 sizeof(short),
447 offset(text.left_column),
448 XtRImmediate((char*)&XtStrings[1695]),
449 (XtPointer)0
450 },
451 {
452 XtNrightColumn"rightColumn",
453 XtCColumn"Column",
454 XtRShort((char*)&XtStrings[1791]),
455 sizeof(short),
456 offset(text.right_column),
457 XtRImmediate((char*)&XtStrings[1695]),
458 (XtPointer)0
459 },
460 {
461 XtNjustifyMode((char*)&XtStrings[379]),
462 XtCJustifyMode((char*)&XtStrings[1122]),
463 XtRJustifyMode"JustifyMode",
464 sizeof(XawTextJustifyMode),
465 offset(text.justify),
466 XtRImmediate((char*)&XtStrings[1695]),
467 (XtPointer)XawjustifyLeft
468 },
469#endif /* OLDXAW */
470};
471#undef offset
472
473#define done(address, type) \
474 { toVal->size = sizeof(type); toVal->addr = (XPointer)address; }
475
476static XrmQuark QWrapNever, QWrapLine, QWrapWord;
477#ifndef notdef
478static XrmQuark QScrollNever, QScrollWhenNeeded, QScrollAlways;
479#endif
480static XrmQuark QJustifyLeft, QJustifyRight, QJustifyCenter, QJustifyFull;
481
482/*ARGSUSED*/
483static void
484CvtStringToScrollMode(XrmValuePtr args, Cardinal *num_args,
485 XrmValuePtr fromVal, XrmValuePtr toVal)
486{
487 static XawTextScrollMode scrollMode = XawtextScrollNever;
488 XrmQuark q;
489 char name[32];
490
491 XmuNCopyISOLatin1Lowered(name, (char *)fromVal->addr, sizeof(name));
492 q = XrmStringToQuark(name);
493
494 if (q == QScrollNever || q == QScrollWhenNeeded)
495 scrollMode = XawtextScrollNever;
496 else if (q == QScrollAlways)
497 scrollMode = XawtextScrollAlways;
498 else if (strcmp(name, "true") == 0 || strcmp(name, "1") == 0)
499 scrollMode = XawtextScrollAlways;
500 else if (strcmp(name, "false") == 0 || strcmp(name, "0") == 0)
501 scrollMode = XawtextScrollNever;
502 else
503 XtStringConversionWarning((char *)fromVal->addr, XtRScrollMode"ScrollMode");
504
505 done(&scrollMode, XawTextScrollMode);
506}
507
508/*ARGSUSED*/
509static Boolean
510CvtScrollModeToString(Display *dpy, XrmValue *args, Cardinal *num_args,
511 XrmValue *fromVal, XrmValue *toVal, XtPointer *data)
512{
513 static char *buffer;
514 Cardinal size;
515
516 switch (*(XawTextScrollMode *)fromVal->addr) {
517 case XawtextScrollNever:
518 case XawtextScrollWhenNeeded:
519 buffer = XtEtextScrollNever"never";
520 break;
521 case XawtextScrollAlways:
522 buffer = XtEtextScrollAlways"always";
523 break;
524 default:
525 XawTypeToStringWarning(dpy, XtRScrollMode"ScrollMode");
526 toVal->addr = NULL((void*)0);
527 toVal->size = 0;
528 return (False0);
529 }
530 size = strlen(buffer) + 1;
531 if (toVal->addr != NULL((void*)0)) {
532 if (toVal->size < size) {
533 toVal->size = size;
534 return (False0);
535 }
536 strcpy((char *)toVal->addr, buffer);
537 }
538 else
539 toVal->addr = (XPointer)buffer;
540 toVal->size = sizeof(String);
541
542 return (True1);
543}
544
545/*ARGSUSED*/
546static void
547CvtStringToWrapMode(XrmValuePtr args, Cardinal *num_args,
548 XrmValuePtr fromVal, XrmValuePtr toVal)
549{
550 static XawTextWrapMode wrapMode = XawtextWrapNever;
551 XrmQuark q;
552 char lowerName[6];
553
554 XmuNCopyISOLatin1Lowered(lowerName, (char *)fromVal->addr,
555 sizeof(lowerName));
556 q = XrmStringToQuark(lowerName);
557
558 if (q == QWrapNever)
559 wrapMode = XawtextWrapNever;
560 else if (q == QWrapLine)
561 wrapMode = XawtextWrapLine;
562 else if (q == QWrapWord)
563 wrapMode = XawtextWrapWord;
564 else
565 XtStringConversionWarning((char *)fromVal->addr, XtRWrapMode"WrapMode");
566
567 done(&wrapMode, XawTextWrapMode);
568}
569
570/*ARGSUSED*/
571static Boolean
572CvtWrapModeToString(Display *dpy, XrmValue *args, Cardinal *num_args,
573 XrmValue *fromVal, XrmValue *toVal, XtPointer *data)
574{
575 static char *buffer;
576 Cardinal size;
577
578 switch (*(XawTextWrapMode *)fromVal->addr) {
579 case XawtextWrapNever:
580 buffer = XtEtextWrapNever"never";
581 break;
582 case XawtextWrapLine:
583 buffer = XtEtextWrapLine"line";
584 break;
585 case XawtextWrapWord:
586 buffer = XtEtextWrapWord"word";
587 break;
588 default:
589 XawTypeToStringWarning(dpy, XtRWrapMode"WrapMode");
590 toVal->addr = NULL((void*)0);
591 toVal->size = 0;
592 return (False0);
593 }
594 size = strlen(buffer) + 1;
595 if (toVal->addr != NULL((void*)0)) {
596 if (toVal->size < size) {
597 toVal->size = size;
598 return (False0);
599 }
600 strcpy((char *)toVal->addr, buffer);
601 }
602 else
603 toVal->addr = (XPointer)buffer;
604 toVal->size = sizeof(String);
605
606 return (True1);
607}
608
609/*ARGSUSED*/
610static Boolean
611CvtStringToJustifyMode(Display *dpy, XrmValue *args, Cardinal *num_args,
612 XrmValue *fromVal, XrmValue *toVal, XtPointer *data)
613{
614 XawTextJustifyMode justify;
615 XrmQuark q;
616 char lowerName[8];
617
618 XmuNCopyISOLatin1Lowered(lowerName, (char *)fromVal->addr,
619 sizeof(lowerName));
620 q = XrmStringToQuark(lowerName);
621
622 if (q == QJustifyLeft)
623 justify = XawjustifyLeft;
624 else if (q == QJustifyRight)
625 justify = XawjustifyRight;
626 else if (q == QJustifyCenter)
627 justify = XawjustifyCenter;
628 else if(q == QJustifyFull)
629 justify = XawjustifyFull;
630 else {
631 XtStringConversionWarning((char *)fromVal->addr, XtRJustifyMode"JustifyMode");
632 return (False0);
633 }
634
635 toVal->size = sizeof(XawTextJustifyMode);
636 *(XawTextJustifyMode *)(toVal->addr) = justify;
637
638 return (True1);
639}
640
641
642/*ARGSUSED*/
643static Boolean
644CvtJustifyModeToString(Display *dpy, XrmValue *args, Cardinal *num_args,
645 XrmValue *fromVal, XrmValue *toVal, XtPointer *data)
646{
647 static char *buffer;
648 Cardinal size;
649
650 switch (*(XawTextJustifyMode *)fromVal->addr) {
651 case XawjustifyLeft:
652 buffer = XtEtextJustifyLeft"left";
653 break;
654 case XawjustifyRight:
655 buffer = XtEtextJustifyRight"right";
656 break;
657 case XawjustifyCenter:
658 buffer = XtEtextJustifyCenter"center";
659 break;
660 case XawjustifyFull:
661 buffer = XtEtextJustifyFull"full";
662 break;
663 default:
664 XawTypeToStringWarning(dpy, XtRJustifyMode"JustifyMode");
665 toVal->addr = NULL((void*)0);
666 toVal->size = 0;
667 return (False0);
668 }
669 size = strlen(buffer) + 1;
670 if (toVal->addr != NULL((void*)0)) {
671 if (toVal->size < size) {
672 toVal->size = size;
673 return (False0);
674 }
675 strcpy((char *)toVal->addr, buffer);
676 }
677 else
678 toVal->addr = (XPointer)buffer;
679 toVal->size = sizeof(String);
680
681 return (True1);
682}
683
684#undef done
685
686static void
687XawTextClassInitialize(void)
688{
689 if (!XawFmt8Bit)
690 FMT8BIT = XawFmt8Bit = XrmPermStringToQuark("FMT8BIT");
691 if (!XawFmtWide)
692 XawFmtWide = XrmPermStringToQuark("FMTWIDE");
693
694 XawInitializeWidgetSet();
695
696 textClassRec.core_class.num_actions = _XawTextActionsTableCount;
697
698 QWrapNever = XrmPermStringToQuark(XtEtextWrapNever"never");
699 QWrapLine = XrmPermStringToQuark(XtEtextWrapLine"line");
700 QWrapWord = XrmPermStringToQuark(XtEtextWrapWord"word");
701 XtAddConverter(XtRString((char*)&XtStrings[1797]), XtRWrapMode"WrapMode", CvtStringToWrapMode, NULL((void*)0), 0);
702 XtSetTypeConverter(XtRWrapMode"WrapMode", XtRString((char*)&XtStrings[1797]), CvtWrapModeToString,
703 NULL((void*)0), 0, XtCacheNone0x001, NULL((void*)0));
704 QScrollNever = XrmPermStringToQuark(XtEtextScrollNever"never");
705 QScrollWhenNeeded = XrmPermStringToQuark(XtEtextScrollWhenNeeded"whenneeded");
706 QScrollAlways = XrmPermStringToQuark(XtEtextScrollAlways"always");
707 XtAddConverter(XtRString((char*)&XtStrings[1797]), XtRScrollMode"ScrollMode", CvtStringToScrollMode,
708 NULL((void*)0), 0);
709 XtSetTypeConverter(XtRScrollMode"ScrollMode", XtRString((char*)&XtStrings[1797]), CvtScrollModeToString,
710 NULL((void*)0), 0, XtCacheNone0x001, NULL((void*)0));
711 QJustifyLeft = XrmPermStringToQuark(XtEtextJustifyLeft"left");
712 QJustifyRight = XrmPermStringToQuark(XtEtextJustifyRight"right");
713 QJustifyCenter = XrmPermStringToQuark(XtEtextJustifyCenter"center");
714 QJustifyFull = XrmPermStringToQuark(XtEtextJustifyFull"full");
715 XtSetTypeConverter(XtRString((char*)&XtStrings[1797]), XtRJustifyMode"JustifyMode", CvtStringToJustifyMode,
716 NULL((void*)0), 0, XtCacheNone0x001, NULL((void*)0));
717 XtSetTypeConverter(XtRJustifyMode"JustifyMode", XtRString((char*)&XtStrings[1797]), CvtJustifyModeToString,
718 NULL((void*)0), 0, XtCacheNone0x001, NULL((void*)0));
719}
720
721/*
722 * Function:
723 * PositionHScrollBar
724 *
725 * Parameters:
726 * ctx - text widget
727 *
728 * Description:
729 * Positions the Horizontal scrollbar.
730 */
731static void
732PositionHScrollBar(TextWidget ctx)
733{
734 Widget hbar = ctx->text.hbar, vbar = ctx->text.vbar;
735 Position x, y;
736 Dimension width, height;
737
738 if (ctx->text.hbar == NULL((void*)0))
739 return;
740
741 if (vbar != NULL((void*)0))
742 x = XtWidth(vbar)(((RectObj)vbar)->rectangle.width);
743 else
744 x = -XtBorderWidth(hbar)(((RectObj)hbar)->rectangle.border_width);
745 y = XtHeight(ctx)(((RectObj)ctx)->rectangle.height) - XtHeight(hbar)(((RectObj)hbar)->rectangle.height) - XtBorderWidth(hbar)(((RectObj)hbar)->rectangle.border_width);
746 if (vbar != NULL((void*)0)) {
747 width = XtWidth(ctx)(((RectObj)ctx)->rectangle.width) - XtWidth(vbar)(((RectObj)vbar)->rectangle.width) - XtBorderWidth(vbar)(((RectObj)vbar)->rectangle.border_width);
748 if (width > XtWidth(ctx)(((RectObj)ctx)->rectangle.width))
749 width = XtWidth(ctx)(((RectObj)ctx)->rectangle.width);
750 }
751 else
752 width = XtWidth(ctx)(((RectObj)ctx)->rectangle.width);
753 height = XtHeight(hbar)(((RectObj)hbar)->rectangle.height);
754
755 XtConfigureWidget(hbar, x, y, width, height, XtBorderWidth(hbar)(((RectObj)hbar)->rectangle.border_width));
756}
757
758/*
759 * Function:
760 * PositionVScrollBar
761 *
762 * Parameters:
763 * ctx - text widget
764 *
765 * Description:
766 * Positions the Vertical scrollbar.
767 */
768static void
769PositionVScrollBar(TextWidget ctx)
770{
771 Widget vbar = ctx->text.vbar;
772 Position x, y;
773 Dimension width, height;
774
775 if (vbar == NULL((void*)0))
776 return;
777
778 x = y = -XtBorderWidth(vbar)(((RectObj)vbar)->rectangle.border_width);
779 height = XtHeight(ctx)(((RectObj)ctx)->rectangle.height);
780 width = XtWidth(vbar)(((RectObj)vbar)->rectangle.width);
781
782 XtConfigureWidget(vbar, x, y, width, height, XtBorderWidth(vbar)(((RectObj)vbar)->rectangle.border_width));
783}
784
785static void
786CreateVScrollBar(TextWidget ctx)
787{
788 Widget vbar;
789
790 if (ctx->text.vbar != NULL((void*)0))
791 return;
792
793 ctx->text.vbar = vbar =
794 XtCreateWidget("vScrollbar", scrollbarWidgetClass, (Widget)ctx, NULL((void*)0), 0);
795 XtAddCallback(vbar, XtNscrollProc((char*)&XtStrings[591]), VScroll, (XtPointer)ctx);
796 XtAddCallback(vbar, XtNjumpProc((char*)&XtStrings[370]), VJump, (XtPointer)ctx);
797
798 ctx->text.r_margin.left += XtWidth(vbar)(((RectObj)vbar)->rectangle.width) + XtBorderWidth(vbar)(((RectObj)vbar)->rectangle.border_width);
799 ctx->text.left_margin = ctx->text.margin.left = ctx->text.r_margin.left;
800
801 PositionVScrollBar(ctx);
802 PositionHScrollBar(ctx);
803 TextSinkResize(ctx->text.sink);
804
805 if (XtIsRealized((Widget)ctx)(XtWindowOfObject((Widget)ctx) != 0L)) {
806 XtRealizeWidget(vbar);
807 XtMapWidget(vbar)XMapWindow((((vbar)->core.screen)->display), ((vbar)->
core.window))
;
808 }
809 XtSetKeyboardFocus(vbar, (Widget)ctx);
810}
811
812/*
813 * Function:
814 * DestroyVScrollBar
815 *
816 * Parameters:
817 * ctx - parent text widget
818 *
819 * Description:
820 * Removes vertical ScrollBar.
821 */
822static void
823DestroyVScrollBar(TextWidget ctx)
824{
825 Widget vbar = ctx->text.vbar;
826
827 if (vbar == NULL((void*)0))
828 return;
829
830 ctx->text.r_margin.left -= XtWidth(vbar)(((RectObj)vbar)->rectangle.width) + XtBorderWidth(vbar)(((RectObj)vbar)->rectangle.border_width);
831 ctx->text.left_margin = ctx->text.margin.left = ctx->text.r_margin.left;
832
833 XtDestroyWidget(vbar);
834 ctx->text.vbar = NULL((void*)0);
835 if (!ctx->core.being_destroyed) {
836 PositionHScrollBar(ctx);
837 TextSinkResize(ctx->text.sink);
838 }
839}
840
841static void
842CreateHScrollBar(TextWidget ctx)
843{
844 Arg args[1];
845 Widget hbar;
846 int bottom;
847
848 if (ctx->text.hbar != NULL((void*)0))
849 return;
850
851 XtSetArg(args[0], XtNorientation, XtorientHorizontal)((void)( (args[0]).name = (((char*)&XtStrings[505])), (args
[0]).value = (XtArgVal)(XtorientHorizontal) ))
;
852 ctx->text.hbar = hbar =
853 XtCreateWidget("hScrollbar", scrollbarWidgetClass, (Widget)ctx, args, 1);
854 XtAddCallback(hbar, XtNscrollProc((char*)&XtStrings[591]), HScroll, (XtPointer)ctx);
855 XtAddCallback(hbar, XtNjumpProc((char*)&XtStrings[370]), HJump, (XtPointer)ctx);
856
857 bottom = ctx->text.r_margin.bottom + XtHeight(hbar)(((RectObj)hbar)->rectangle.height) + XtBorderWidth(hbar)(((RectObj)hbar)->rectangle.border_width);
858
859 ctx->text.margin.bottom = ctx->text.r_margin.bottom = bottom;
860
861 PositionHScrollBar(ctx);
862 TextSinkResize(ctx->text.sink);
863
864 if (XtIsRealized((Widget)ctx)(XtWindowOfObject((Widget)ctx) != 0L)) {
865 XtRealizeWidget(hbar);
866 XtMapWidget(hbar)XMapWindow((((hbar)->core.screen)->display), ((hbar)->
core.window))
;
867 }
868 XtSetKeyboardFocus(hbar, (Widget)ctx);
869}
870
871/*
872 * Function:
873 * DestroyHScrollBar
874 *
875 * Parameters:
876 * ctx - parent text widget
877 *
878 * Description:
879 * Removes horizontal ScrollBar.
880 */
881static void
882DestroyHScrollBar(TextWidget ctx)
883{
884 Widget hbar = ctx->text.hbar;
885
886 if (hbar == NULL((void*)0))
887 return;
888
889 ctx->text.r_margin.bottom -= XtHeight(hbar)(((RectObj)hbar)->rectangle.height) + XtBorderWidth(hbar)(((RectObj)hbar)->rectangle.border_width);
890 ctx->text.margin.bottom = ctx->text.r_margin.bottom;
891
892 XtDestroyWidget(hbar);
893 ctx->text.hbar = NULL((void*)0);
894 if (!ctx->core.being_destroyed)
895 TextSinkResize(ctx->text.sink);
896}
897
898/*ARGSUSED*/
899static void
900XawTextInitialize(Widget request, Widget cnew,
901 ArgList args, Cardinal *num_args)
902{
903 TextWidget ctx = (TextWidget)cnew;
904
905 ctx->text.lt.lines = 0;
906 ctx->text.lt.info = (XawTextLineTableEntry *)
907 XtCalloc(1, sizeof(XawTextLineTableEntry));
908#ifndef OLDXAW1
909 ctx->text.lt.base_line = 1;
910#endif
911 (void)bzero(&ctx->text.origSel, sizeof(XawTextSelection))memset(&ctx->text.origSel,0,sizeof(XawTextSelection));
912 (void)bzero(&ctx->text.s, sizeof(XawTextSelection))memset(&ctx->text.s,0,sizeof(XawTextSelection));
913 ctx->text.s.type = XawselectPosition;
914 ctx->text.salt = NULL((void*)0);
915 ctx->text.hbar = ctx->text.vbar = NULL((void*)0);
916 ctx->text.lasttime = 0;
917 ctx->text.time = 0;
918 ctx->text.showposition = True1;
919 ctx->text.lastPos = ctx->text.source != NULL((void*)0) ?
920 XawTextGetLastPosition(ctx)XawTextSourceScan((ctx)->text.source, 0, XawstAll, XawsdRight
, 1, 1)
: 0;
921 ctx->text.file_insert = NULL((void*)0);
922 ctx->text.search = NULL((void*)0);
923 ctx->text.update = XmuNewScanline(0, 0, 0);
924 ctx->text.gc = XtGetGC(cnew, 0, 0);
925 ctx->text.hasfocus = False0;
926 ctx->text.margin = ctx->text.r_margin; /* Strucure copy */
927 ctx->text.left_margin = ctx->text.r_margin.left;
928 ctx->text.update_disabled = False0;
929 ctx->text.clear_to_eol = True1;
930 ctx->text.old_insert = -1;
931 ctx->text.mult = 1;
932 ctx->text.salt2 = NULL((void*)0);
933 ctx->text.from_left = -1;
934
935#ifndef OLDXAW1
936 ctx->text.numeric = False0;
937 ctx->text.selection_state = False0;
938 ctx->text.kill_ring = 0;
939
940 ctx->text.line_number = -1;
941 ctx->text.column_number = -1;
942 ctx->text.source_changed = SRC_CHANGE_NONE0;
943
944 ctx->text.kill_ring_ptr = NULL((void*)0);
945 ctx->text.overwrite = False0;
946#endif
947
948 if (XtHeight(ctx)(((RectObj)ctx)->rectangle.height) == DEFAULT_TEXT_HEIGHT((Dimension)~0)) {
949 XtHeight(ctx)(((RectObj)ctx)->rectangle.height) = VMargins(ctx)((ctx)->text.margin.top + (ctx)->text.margin.bottom);
950 if (ctx->text.sink != NULL((void*)0))
951 XtHeight(ctx)(((RectObj)ctx)->rectangle.height) += XawTextSinkMaxHeight(ctx->text.sink, 1);
952 }
953
954 if (ctx->text.scroll_vert == XawtextScrollAlways)
955 CreateVScrollBar(ctx);
956 if (ctx->text.scroll_horiz == XawtextScrollAlways)
957 CreateHScrollBar(ctx);
958
959#ifndef OLDXAW1
960 if (ctx->text.left_column < 0)
961 ctx->text.left_column = 0;
962 if (ctx->text.right_column < 0)
963 ctx->text.right_column = 0;
964#endif
965}
966
967static void
968XawTextRealize(Widget w, XtValueMask *mask, XSetWindowAttributes *attr)
969{
970 TextWidget ctx = (TextWidget)w;
971
972 (*textClassRec.core_class.superclass->core_class.realize)(w, mask, attr);
973
974 if (ctx->text.hbar != NULL((void*)0)) {
975 XtRealizeWidget(ctx->text.hbar);
976 XtMapWidget(ctx->text.hbar)XMapWindow((((ctx->text.hbar)->core.screen)->display
), ((ctx->text.hbar)->core.window))
;
977 }
978
979 if (ctx->text.vbar != NULL((void*)0)) {
980 XtRealizeWidget(ctx->text.vbar);
981 XtMapWidget(ctx->text.vbar)XMapWindow((((ctx->text.vbar)->core.screen)->display
), ((ctx->text.vbar)->core.window))
;
982 }
983
984 _XawTextBuildLineTable(ctx, ctx->text.lt.top, True1);
985
986#ifndef OLDXAW1
987 _XawTextSetLineAndColumnNumber(ctx, True1);
988#endif
989}
990
991/* Utility routines for support of Text */
992static void
993_CreateCutBuffers(Display *d)
994{
995 static struct _DisplayRec {
996 struct _DisplayRec *next;
997 Display *dpy;
998 } *dpy_list = NULL((void*)0);
999 struct _DisplayRec *dpy_ptr;
1000
1001 for (dpy_ptr = dpy_list; dpy_ptr != NULL((void*)0); dpy_ptr = dpy_ptr->next)
1002 if (dpy_ptr->dpy == d)
1003 return;
1004
1005 dpy_ptr = XtNew(struct _DisplayRec)((struct _DisplayRec *) XtMalloc((unsigned) sizeof(struct _DisplayRec
)))
;
1006 dpy_ptr->next = dpy_list;
1007 dpy_ptr->dpy = d;
1008 dpy_list = dpy_ptr;
1009
1010#define Create(buffer) \
1011 XChangeProperty(d, RootWindow(d, 0)((&((_XPrivDisplay)d)->screens[0])->root), buffer, XA_STRING((Atom) 31), 8, \
1012 PropModeAppend2, NULL((void*)0), 0);
1013
1014 Create(XA_CUT_BUFFER0((Atom) 9));
1015 Create(XA_CUT_BUFFER1((Atom) 10));
1016 Create(XA_CUT_BUFFER2((Atom) 11));
1017 Create(XA_CUT_BUFFER3((Atom) 12));
1018 Create(XA_CUT_BUFFER4((Atom) 13));
1019 Create(XA_CUT_BUFFER5((Atom) 14));
1020 Create(XA_CUT_BUFFER6((Atom) 15));
1021 Create(XA_CUT_BUFFER7((Atom) 16));
1022
1023#undef Create
1024}
1025
1026/*
1027 * Procedure to manage insert cursor visibility for editable text. It uses
1028 * the value of ctx->insertPos and an implicit argument. In the event that
1029 * position is immediately preceded by an eol graphic, then the insert cursor
1030 * is displayed at the beginning of the next line.
1031 */
1032static void
1033InsertCursor(Widget w, XawTextInsertState state)
1034{
1035 TextWidget ctx = (TextWidget)w;
1036 int x, y;
1037 int line;
1038
1039 if (ctx->text.lt.lines < 1)
1040 return;
1041
1042 if (ctx->text.display_caret &&
1043 LineAndXYForPosition(ctx, ctx->text.insertPos, &line, &x, &y)) {
1044 if (line < ctx->text.lt.lines)
1045 y += (ctx->text.lt.info[line + 1].y - ctx->text.lt.info[line].y) + 1;
1046 else
1047 y += (ctx->text.lt.info[line].y - ctx->text.lt.info[line - 1].y) + 1;
1048
1049 XawTextSinkInsertCursor(ctx->text.sink, x, y, state);
1050 }
1051
1052 /* Keep Input Method up to speed */
1053 if (ctx->simple.international) {
1054 Arg list[1];
1055
1056 XtSetArg(list[0], XtNinsertPosition, ctx->text.insertPos)((void)( (list[0]).name = (((char*)&XtStrings[326])), (list
[0]).value = (XtArgVal)(ctx->text.insertPos) ))
;
1057 _XawImSetValues(w, list, 1);
1058 }
1059}
1060
1061/*
1062 * Procedure to register a span of text that is no longer valid on the display
1063 * It is used to avoid a number of small, and potentially overlapping, screen
1064 * updates.
1065*/
1066void
1067_XawTextNeedsUpdating(TextWidget ctx,
1068 XawTextPosition left, XawTextPosition right)
1069{
1070 XmuSegment segment;
1071
1072 if (left >= right)
1073 return;
1074
1075 segment.x1 = (int)left;
1076 segment.x2 = (int)right;
1077 (void)XmuScanlineOrSegment(ctx->text.update, &segment);
1078}
1079
1080/*
1081 * Procedure to read a span of text in Ascii form. This is purely a hack and
1082 * we probably need to add a function to sources to provide this functionality.
1083 * [note: this is really a private procedure but is used in multiple modules].
1084 */
1085char *
1086_XawTextGetText(TextWidget ctx, XawTextPosition left, XawTextPosition right)
1087{
1088 char *result, *tempResult;
1089 XawTextBlock text;
1090 int bytes;
1091
1092 if (XawTextFormat(ctx, XawFmt8Bit)((unsigned long)_XawTextFormat(ctx) == (XawFmt8Bit)))
1093 bytes = sizeof(unsigned char);
1094 else if (XawTextFormat(ctx, XawFmtWide)((unsigned long)_XawTextFormat(ctx) == (XawFmtWide)))
1095 bytes = sizeof(wchar_t);
1096 else /* if there is another fomat, add here */
1097 bytes = 1;
1098
1099 /* leave space for ZERO */
1100 tempResult = result = XtMalloc((unsigned)(right - left + ONE((Cardinal)1)) * bytes);
1101
1102 while (left < right) {
1103 left = SrcReadXawTextSourceRead(ctx->text.source, left, &text, (int)(right - left));
1104 if (!text.length)
1105 break;
1106 memmove(tempResult, text.ptr, (unsigned)(text.length * bytes));
1107 tempResult += text.length * bytes;
1108 }
1109
1110 if (bytes == sizeof(wchar_t))
1111 *((wchar_t*)tempResult) = (wchar_t)0;
1112 else
1113 *tempResult = '\0';
1114
1115 return (result);
1116}
1117
1118/* Like _XawTextGetText, but enforces ICCCM STRING type encoding. This
1119 * routine is currently used to put just the ASCII chars in the selection
1120 * into a cut buffer.
1121 */
1122char *
1123_XawTextGetSTRING(TextWidget ctx, XawTextPosition left, XawTextPosition right)
1124{
1125 unsigned char *s;
1126 unsigned char c;
1127 long i, j, n;
1128 wchar_t *ws, wc;
1129
1130 /* allow ESC in accordance with ICCCM */
1131 if (XawTextFormat(ctx, XawFmtWide)((unsigned long)_XawTextFormat(ctx) == (XawFmtWide))) {
1132 MultiSinkObject sink = (MultiSinkObject)ctx->text.sink;
1133 ws = (wchar_t *)_XawTextGetText(ctx, left, right);
1134 n = wcslen(ws);
1135 for (j = 0, i = 0; j < n; j++) {
1136 wc = ws[j];
1137 if (XwcTextEscapement (sink->multi_sink.fontset, &wc, 1)
1138 || (wc == _Xaw_atowc(XawTAB0x09)) || (wc == _Xaw_atowc(XawLF0x0a))
1139 || (wc == _Xaw_atowc(XawESC0x1b)))
1140 ws[i++] = wc;
1141 }
1142 ws[i] = (wchar_t)0;
1143 return ((char *)ws);
1144 }
1145 else {
1146 s = (unsigned char *)_XawTextGetText(ctx, left, right);
1147 /* only HT and NL control chars are allowed, strip out others */
1148 n = strlen((char *)s);
1149 i = 0;
1150 for (j = 0; j < n; j++) {
1151 c = s[j];
1152 if (((c >= 0x20) && c <= 0x7f)
1153 ||(c >= 0xa0) || (c == XawTAB0x09) || (c == XawLF0x0a)
1154 || (c == XawESC0x1b)) {
1155 s[i] = c;
1156 i++;
1157 }
1158 }
1159 s[i] = 0;
1160
1161 return ((char *)s);
1162 }
1163}
1164
1165/*
1166 * This routine maps an x and y position in a window that is displaying text
1167 * into the corresponding position in the source.
1168 */
1169static XawTextPosition
1170PositionForXY(TextWidget ctx, int x, int y)
1171{
1172 int fromx, line, width, height;
1173 XawTextPosition position;
1174
1175 if (ctx->text.lt.lines == 0)
1176 return (0);
1177
1178 for (line = 0; line < ctx->text.lt.lines - 1; line++) {
1179 if (y <= ctx->text.lt.info[line + 1].y)
1180 break;
1181 }
1182 position = ctx->text.lt.info[line].position;
1183 if (position >= ctx->text.lastPos)
1184 return (ctx->text.lastPos);
1185 fromx = ctx->text.left_margin;
1186 XawTextSinkFindPosition(ctx->text.sink, position, fromx, x - fromx,
1187 False0, &position, &width, &height);
1188
1189 if (position > ctx->text.lastPos)
1190 return (ctx->text.lastPos);
1191
1192 if (position >= ctx->text.lt.info[line + 1].position)
1193 position = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.lt.info[line + 1].position,
1194 XawstPositions, XawsdLeft, 1, True1);
1195
1196 return (position);
1197}
1198
1199/*
1200 * This routine maps a source position in to the corresponding line number
1201 * of the text that is displayed in the window.
1202 */
1203static int
1204LineForPosition(TextWidget ctx, XawTextPosition position)
1205{
1206 int line;
1207
1208 for (line = 0; line < ctx->text.lt.lines; line++)
1209 if (position < ctx->text.lt.info[line + 1].position)
1210 break;
1211
1212 return (line);
1213}
1214
1215/*
1216 * This routine maps a source position into the corresponding line number
1217 * and the x, y coordinates of the text that is displayed in the window.
1218 */
1219static Boolint
1220LineAndXYForPosition(TextWidget ctx, XawTextPosition pos,
1221 int *line, int *x, int *y)
1222{
1223 XawTextPosition linePos, endPos;
1224 Boolean visible;
1225 int realW, realH;
1226
1227 *line = 0;
1228 *x = ctx->text.left_margin;
1229 *y = ctx->text.margin.top + 1;
1230 if ((visible = IsPositionVisible(ctx, pos)(pos >= ctx->text.lt.info[0].position && pos <
ctx->text.lt.info[ctx->text.lt.lines].position)
) != False0) {
1231 *line = LineForPosition(ctx, pos);
1232 *y = ctx->text.lt.info[*line].y;
1233 linePos = ctx->text.lt.info[*line].position;
1234 XawTextSinkFindDistance(ctx->text.sink, linePos,
1235 *x, pos, &realW, &endPos, &realH);
1236 *x += realW;
1237 }
1238
1239 return (visible);
1240}
1241
1242/*
1243 * This routine builds a line table. It does this by starting at the
1244 * specified position and measuring text to determine the staring position
1245 * of each line to be displayed. It also determines and saves in the
1246 * linetable all the required metrics for displaying a given line (e.g.
1247 * x offset, y offset, line length, etc.).
1248 */
1249void
1250_XawTextBuildLineTable(TextWidget ctx, XawTextPosition position,
1251 _XtBooleanBoolean force_rebuild)
1252{
1253 Dimension height = 0;
1254 int lines = 0;
1255 Cardinal size;
1256
1257 if ((int)XtHeight(ctx)(((RectObj)ctx)->rectangle.height) > VMargins(ctx)((ctx)->text.margin.top + (ctx)->text.margin.bottom)) {
1258 height = XtHeight(ctx)(((RectObj)ctx)->rectangle.height) - VMargins(ctx)((ctx)->text.margin.top + (ctx)->text.margin.bottom);
1259 lines = XawTextSinkMaxLines(ctx->text.sink, height);
1260 }
1261 size = sizeof(XawTextLineTableEntry) * (lines + 1);
1262
1263 if (lines != ctx->text.lt.lines || ctx->text.lt.info == NULL((void*)0)) {
1264 ctx->text.lt.info = (XawTextLineTableEntry *)
1265 XtRealloc((char *)ctx->text.lt.info, size);
1266 ctx->text.lt.lines = lines;
1267 force_rebuild = True1;
1268 }
1269
1270 if (force_rebuild) {
1271 (void)bzero((char *)ctx->text.lt.info, size)memset((char *)ctx->text.lt.info,0,size);
1272 /* force a text update in the first text line if it is visible */
1273 ctx->text.lt.info[0].position = (XawTextPosition)-1;
1274 }
1275 if (position != ctx->text.lt.info[0].position) {
1276 (void)_BuildLineTable(ctx, position, 0);
1277 ctx->text.clear_to_eol = True1;
1278 }
1279}
1280
1281/*
1282 * We may need to resize the line table here, since there maybe lines with
1283 * different fonts (that can be shorter or taller than the default one)
1284 */
1285static XawTextPosition
1286_BuildLineTable(TextWidget ctx, XawTextPosition position, int line)
1287{
1288 XawTextLineTableEntry *lt = ctx->text.lt.info + line;
1289 XawTextPosition end, update_from = -1;
1290 Position y;
1291 int wwidth, width, height;
1292#ifndef OLDXAW1
1293 Widget src = ctx->text.source;
1294#endif
1295 int max_y = (int)XtHeight(ctx)(((RectObj)ctx)->rectangle.height) - (int)ctx->text.margin.bottom;
1296
1297 if (ctx->text.wrap == XawtextWrapNever)
1298 wwidth = 0x7fffffff;
1299 else
1300 wwidth = GetMaxTextWidth(ctx);
1301
1302 /* XXX y may change, due to font size changes. See later */
1303 y = line == 0 ? ctx->text.margin.top : lt->y;
1304
1305#ifndef OLDXAW1
1306 if (ctx->text.lt.base_line < 0) {
1307 if (line == 0)
1308 ctx->text.lt.top = position;
1309 }
1310 else if (line == 0) {
1311 XawTextPosition pos = ctx->text.lt.top;
1312 int base_line = ctx->text.lt.base_line;
1313
1314 if (position == 0)
1315 base_line = 1;
1316 else if (ctx->text.lt.base_line == 0 ||
1317 ctx->text.source_changed == SRC_CHANGE_OVERLAP3) {
1318 pos = 0;
1319 base_line = 1;
1320
1321 while (pos < position) {
1322 pos = SrcScanXawTextSourceScan(src, pos, XawstEOL, XawsdRight, 1, True1);
1323 if (pos <= position) {
1324 ++base_line;
1325 if (pos == ctx->text.lastPos) {
1326 base_line -= !_XawTextSourceNewLineAtEOF(src);
1327 break;
1328 }
1329 }
1330 }
1331 }
1332 else if (ctx->text.wrap == XawtextWrapNever
1333 && IsPositionVisible(ctx, position)(position >= ctx->text.lt.info[0].position && position
< ctx->text.lt.info[ctx->text.lt.lines].position)
)
1334 base_line += LineForPosition(ctx, position);
1335 else if (pos < position) {
1336 while (pos < position) {
1337 pos = SrcScanXawTextSourceScan(src, pos, XawstEOL, XawsdRight, 1, True1);
1338 if (pos <= position) {
1339 ++base_line;
1340 if (pos == ctx->text.lastPos) {
1341 base_line -= !_XawTextSourceNewLineAtEOF(src);
1342 break;
1343 }
1344 }
1345 }
1346 }
1347 else if (pos > position) {
1348 while (pos > position) {
1349 pos = SrcScanXawTextSourceScan(src, pos, XawstEOL, XawsdLeft, 1, False0);
1350 if (--pos >= position)
1351 --base_line;
1352 }
1353 }
1354
1355 ctx->text.lt.top = position;
1356 ctx->text.lt.base_line = base_line;
1357 }
1358#else
1359 if (line == 0)
1360 ctx->text.lt.top = position;
1361#endif
1362
1363 /* CONSTCOND */
1364 while (True1) {
1365 XawTextSinkFindPosition(ctx->text.sink, position, ctx->text.left_margin,
1366 wwidth, ctx->text.wrap == XawtextWrapWord,
1367 &end, &width, &height);
1368
1369 if (lt->position != position) {
1370 _XawTextNeedsUpdating(ctx, position,
1371 end <= position ? position + 1 : end);
1372 ctx->text.clear_to_eol = True1;
1373 lt->position = position;
1374 }
1375 if (lt->y != y) {
1376 if (update_from < 0)
1377 update_from = line == 0 ?
1378 ctx->text.lt.info[0].position :
1379 ctx->text.lt.info[line - 1].position;
1380 lt->y = y;
1381 ctx->text.clear_to_eol = True1;
1382 }
1383 if (lt->textWidth != width) {
1384 if (lt->textWidth > width)
1385 ctx->text.clear_to_eol = True1;
1386 lt->textWidth = width;
1387 }
1388 y += height;
1389
1390 if (end > ctx->text.lastPos) {
1391 position = end;
1392 ctx->text.clear_to_eol = True1;
1393 _XawTextNeedsUpdating(ctx, end, end + ctx->text.lt.lines - line);
1394 while (line++ < ctx->text.lt.lines) {
1395 if (line > 1 && y > max_y) {
1396 ctx->text.lt.lines = line - 1;
1397 break;
1398 }
1399 ++lt;
1400 if (lt->y != y) {
1401 if (update_from < 0)
1402 update_from = line < 2 ?
1403 ctx->text.lt.info[0].position :
1404 ctx->text.lt.info[line - 2].position;
1405 lt->y = y;
1406 }
1407 lt->position = ++position;
1408 lt->textWidth = 0;
1409 y += height;
1410 }
1411 if (update_from >= 0)
1412 _XawTextNeedsUpdating(ctx, update_from,
1413 ctx->text.lt.info[ctx->text.lt.lines].position);
1414 _XawTextSetScrollBars(ctx);
1415
1416 return (ctx->text.lastPos);
1417 }
1418
1419 if (line && y > max_y)
1420 /* will return in the next loop */
1421 ctx->text.lt.lines = line;
1422
1423 if (++line > ctx->text.lt.lines && y < max_y) {
1424 /* grow the line table */
1425 ctx->text.lt.info = (XawTextLineTableEntry *)
1426 XtRealloc((char *)ctx->text.lt.info,
1427 sizeof(XawTextLineTableEntry) * (line + 1));
1428 lt = ctx->text.lt.info + line;
1429 bzero(lt, sizeof(XawTextLineTableEntry))memset(lt,0,sizeof(XawTextLineTableEntry));
1430 ++ctx->text.lt.lines;
1431 }
1432 else
1433 ++lt;
1434 if (position == end)
1435 ++position;
1436 else
1437 position = end;
1438
1439 if (line > ctx->text.lt.lines) {
1440 if (update_from >= 0)
1441 _XawTextNeedsUpdating(ctx, update_from,
1442 ctx->text.lt.info[ctx->text.lt.lines].position);
1443 _XawTextSetScrollBars(ctx);
1444
1445 return (position);
1446 }
1447 }
1448 /*NOTREACHED*/
1449}
1450
1451/*
1452 * Function:
1453 * GetWidestLine
1454 *
1455 * Parameters:
1456 * ctx - text widget
1457 *
1458 * Description:
1459 * Returns the width (in pixels) of the widest line that
1460 * is currently visable.
1461 *
1462 * Returns:
1463 * The width of the widest line
1464 */
1465static unsigned int
1466GetWidestLine(TextWidget ctx)
1467{
1468 int i;
1469 unsigned int widest;
1470 XawTextLineTablePtr lt = &(ctx->text.lt);
1471
1472 for (i = 0, widest = 0; i < lt->lines; i++)
1473 if (widest < lt->info[i].textWidth)
1474 widest = lt->info[i].textWidth;
1475
1476 return (widest);
1477}
1478
1479/*
1480 * This routine is used by Text to notify an associated scrollbar of the
1481 * correct metrics (position and shown fraction) for the text being currently
1482 * displayed in the window.
1483 */
1484void
1485_XawTextSetScrollBars(TextWidget ctx)
1486{
1487 float first, last, denom, widest;
1488
1489 if (ctx->text.scroll_vert == XawtextScrollAlways) {
1490 if (ctx->text.lastPos == 0)
1491 first = 0.0;
1492 else
1493 first = ctx->text.lt.top / (float)ctx->text.lastPos;
1494
1495 if (ctx->text.lt.info[ctx->text.lt.lines].position < ctx->text.lastPos)
1496 last = ctx->text.lt.info[ctx->text.lt.lines].position /
1497 (float)ctx->text.lastPos;
1498 else
1499 last = 1.0;
1500
1501 XawScrollbarSetThumb(ctx->text.vbar, first, last - first);
1502 }
1503
1504 if (ctx->text.scroll_horiz == XawtextScrollAlways) {
1505 denom = GetWidestLine(ctx);
1506 if (denom <= 0)
1507 denom = (int)XtWidth(ctx)(((RectObj)ctx)->rectangle.width) - RHMargins(ctx)((ctx)->text.r_margin.left + (ctx)->text.r_margin.right
)
;
1508 if (denom <= 0)
1509 denom = 1;
1510 widest = ((int)XtWidth(ctx)(((RectObj)ctx)->rectangle.width) - RHMargins(ctx)((ctx)->text.r_margin.left + (ctx)->text.r_margin.right
)
) / denom;
1511 first = ctx->text.r_margin.left - ctx->text.left_margin;
1512 first /= denom;
1513
1514 XawScrollbarSetThumb(ctx->text.hbar, first, widest);
1515 }
1516}
1517
1518static void
1519DoCopyArea(TextWidget ctx, int src_x, int src_y,
1520 unsigned int width, unsigned int height, int dst_x, int dst_y)
1521{
1522 int x1, y1, x2, y2;
1523
1524 x1 = ctx->text.r_margin.left;
1525 y1 = ctx->text.r_margin.top;
1526 x2 = XtWidth(ctx)(((RectObj)ctx)->rectangle.width) - ctx->text.r_margin.right;
1527 y2 = XtHeight(ctx)(((RectObj)ctx)->rectangle.height) - ctx->text.r_margin.bottom;
1528
1529 if (x1 >= x2 || y1 >= y2)
1530 return;
1531
1532 src_x = XawMax(x1, XawMin(src_x, x2))((x1) > (((src_x) < (x2) ? (src_x) : (x2))) ? (x1) : ((
(src_x) < (x2) ? (src_x) : (x2))))
;
1533 src_y = XawMax(y1, XawMin(src_y, y2))((y1) > (((src_y) < (y2) ? (src_y) : (y2))) ? (y1) : ((
(src_y) < (y2) ? (src_y) : (y2))))
;
1534 dst_x = XawMax(x1, XawMin(dst_x, x2))((x1) > (((dst_x) < (x2) ? (dst_x) : (x2))) ? (x1) : ((
(dst_x) < (x2) ? (dst_x) : (x2))))
;
1535 dst_y = XawMax(y1, XawMin(dst_y, y2))((y1) > (((dst_y) < (y2) ? (dst_y) : (y2))) ? (y1) : ((
(dst_y) < (y2) ? (dst_y) : (y2))))
;
1536 width = XawMax(0, XawMin(x2 - dst_x, (int)width))((0) > (((x2 - dst_x) < ((int)width) ? (x2 - dst_x) : (
(int)width))) ? (0) : (((x2 - dst_x) < ((int)width) ? (x2 -
dst_x) : ((int)width))))
;
1537 height = XawMax(0, XawMin(y2 - dst_y, (int)height))((0) > (((y2 - dst_y) < ((int)height) ? (y2 - dst_y) : (
(int)height))) ? (0) : (((y2 - dst_y) < ((int)height) ? (y2
- dst_y) : ((int)height))))
;
1538
1539 XCopyArea(XtDisplay(ctx)(((ctx)->core.screen)->display), XtWindow(ctx)((ctx)->core.window), XtWindow(ctx)((ctx)->core.window), ctx->text.gc,
1540 src_x, src_y, width, height, dst_x, dst_y);
1541}
1542
1543/*
1544 * Function:
1545 * XawTextScroll
1546 *
1547 * Parameters:
1548 * ctx - text widget
1549 * vlines - number of lines to scroll vertically
1550 * hpixels - number of pixels to scroll horizontally
1551 *
1552 * Description:
1553 * Generic function for scrolling the text window.
1554 * Allows vertical and horizontal scroll at the same time.
1555 */
1556void
1557XawTextScroll(TextWidget ctx, int vlines, int hpixels)
1558{
1559 XawTextPosition top, tmp, update_from, update_to;
1560 XawTextLineTable *lt;
1561 Arg arglist[1];
1562 int y0, y1, y2, count, dim, wwidth, lines = ctx->text.lt.lines;
1563 int vwidth, vheight; /* visible width and height */
1564 Boolint scroll;
1565
1566 vwidth = (int)XtWidth(ctx)(((RectObj)ctx)->rectangle.width) - RHMargins(ctx)((ctx)->text.r_margin.left + (ctx)->text.r_margin.right
)
;
1567 vheight = (int)XtHeight(ctx)(((RectObj)ctx)->rectangle.height) - RVMargins(ctx)((ctx)->text.r_margin.top + (ctx)->text.r_margin.bottom
)
;
1568 lt = &ctx->text.lt;
1569
1570 if (!lt || vwidth <= 0 || vheight <= 0)
1571 return;
1572
1573 if ((scroll = ctx->core.background_pixmap == XtUnspecifiedPixmap((Pixmap)2)) == True1) {
1574 dim = lt->info[1].y - lt->info[0].y;
1575 for (count = 1; count < lt->lines - 1; count++)
1576 if (lt->info[count + 1].y - lt->info[count].y != dim) {
1577 scroll = False0;
1578 break;
1579 }
1580 }
1581
1582 wwidth = GetMaxTextWidth(ctx);
1583
1584 /*
1585 * Do the horizontall scrolling
1586 */
1587 if (hpixels < 0 && ctx->text.left_margin - hpixels > ctx->text.r_margin.left)
1588 hpixels = ctx->text.left_margin - ctx->text.r_margin.left;
1589 ctx->text.left_margin -= hpixels;
1590
1591 update_from = lt->top; /* remember the old value */
1592 /*
1593 * Checks the requested number of lines and calculates the top
1594 * of the line table
1595 */
1596 if (vlines < 0) { /* VScroll Up */
1597 if (IsPositionVisible(ctx, 0)(0 >= ctx->text.lt.info[0].position && 0 < ctx
->text.lt.info[ctx->text.lt.lines].position)
)
1598 vlines = 0;
1599 else if (ctx->text.wrap != XawtextWrapNever) {
1600 XawTextPosition end;
1601 int n_lines = 0;
1602
1603 count = -vlines;
1604 end = lt->top;
1605 while (n_lines < count) {
1606 top = SrcScanXawTextSourceScan(ctx->text.source, end, XawstEOL,
1607 XawsdLeft, 2, False0);
1608 n_lines += CountLines(ctx, top, end);
1609 end = top;
1610 }
1611
1612 while (count++ < n_lines) {
1613 tmp = top;
1614 XawTextSinkFindPosition(ctx->text.sink, top,
1615 ctx->text.left_margin,
1616 wwidth,ctx->text.wrap == XawtextWrapWord,
1617 &top, &dim, &dim);
1618 if (tmp == top)
1619 ++top;
1620 }
1621 }
1622 else
1623 top = SrcScanXawTextSourceScan(ctx->text.source, lt->top, XawstEOL,
1624 XawsdLeft, -vlines + 1, False0);
1625 if (-vlines >= ctx->text.lt.lines)
1626 scroll = False0;
1627 }
1628 else if (vlines > 0) { /* VScroll Down */
1629 if (LineForPosition(ctx, ctx->text.lastPos) == 0)
1630 vlines = 0;
1631 if (vlines < lt->lines)
1632 top = XawMin(lt->info[vlines].position, ctx->text.lastPos)((lt->info[vlines].position) < (ctx->text.lastPos) ?
(lt->info[vlines].position) : (ctx->text.lastPos))
;
1633 else if (ctx->text.wrap == XawtextWrapNever)
1634 top = SrcScanXawTextSourceScan(ctx->text.source,
1635 SrcScanXawTextSourceScan(ctx->text.source, lt->top,
1636 XawstEOL, XawsdRight, vlines,
1637 True1),
1638 XawstEOL, XawsdLeft, 1, False0);
1639 else {
1640 top = lt->top;
1641 count = 0;
1642 while (count++ < vlines) {
1643 tmp = top;
1644 XawTextSinkFindPosition(ctx->text.sink, top,
1645 ctx->text.left_margin,
1646 wwidth, ctx->text.wrap == XawtextWrapWord,
1647 &top, &dim, &dim);
1648 if (tmp == top)
1649 ++top;
1650 }
1651 }
1652 if (vlines >= ctx->text.lt.lines
1653 || lt->info[vlines].position >= ctx->text.lastPos)
1654 scroll = False0;
1655 }
1656
1657 if (!vlines) {
1658 if (hpixels) {
1659 ClearWindow(ctx)_XawTextNeedsUpdating((ctx), (ctx)->text.lt.top, (ctx)->
text.lt.info[ctx->text.lt.lines].position)
;
1660 ctx->text.clear_to_eol = True1;
1661 }
1662 _XawTextSetScrollBars(ctx);
1663 return;
1664 }
1665
1666 /* Flushes any pending updates. Normally, there may be a call to
1667 * XawTextUnsetSelection not yet updated.
1668 */
1669 if (!hpixels && scroll) {
1670 ctx->text.clear_to_eol = True1;
1671 FlushUpdate(ctx);
1672 }
1673
1674 /*
1675 * Rebuild the line table, doing the vertical scroll
1676 */
1677 (void)_BuildLineTable(ctx, top, 0);
1678 lt = &ctx->text.lt;
1679 if (scroll) {
1680 for (count = 0; count < lt->lines - 1; count++)
1681 if (lt->info[count + 1].y - lt->info[count].y != dim) {
1682 scroll = False0;
1683 break;
1684 }
1685 }
1686
1687 XtSetArg(arglist[0], XtNinsertPosition, lt->top + lt->lines)((void)( (arglist[0]).name = (((char*)&XtStrings[326])), (
arglist[0]).value = (XtArgVal)(lt->top + lt->lines) ))
;
1688 _XawImSetValues((Widget)ctx, arglist, 1);
1689
1690 if (hpixels || !scroll || lines != lt->lines)
1691 return;
1692
1693 /* _BuildLineTable updates everything if the top position changes.
1694 * It is not required here.
1695 */
1696 (void)XmuScanlineXor(ctx->text.update, ctx->text.update);
1697 if (vlines < 0 && IsPositionVisible(ctx, 0)(0 >= ctx->text.lt.info[0].position && 0 < ctx
->text.lt.info[ctx->text.lt.lines].position)
)
1698 vlines = -LineForPosition(ctx, update_from);
1699
1700 y0 = ctx->text.r_margin.top;
1701 if (vlines < 0) {
1702 update_from = lt->top;
1703 update_to = lt->info[-vlines + 1].position - 1;
1704 y1 = lt->info[lt->lines + vlines].y;
1705 y2 = lt->info[-vlines].y;
1706 DoCopyArea(ctx, ctx->text.r_margin.left, y0, vwidth,
1707 y1 - y0,
1708 ctx->text.r_margin.left, y2);
1709 }
1710 else {
1711 update_from = lt->info[lt->lines - vlines].position;
1712 update_to = lt->info[lt->lines].position;
1713 y1 = lt->info[lt->lines - vlines].y;
Value stored to 'y1' is never read
1714 y2 = lt->info[vlines].y;
1715 DoCopyArea(ctx, ctx->text.r_margin.left, y2,
1716 vwidth, lt->info[lt->lines].y - y2,
1717 ctx->text.r_margin.left, y0);
1718 }
1719 _XawTextNeedsUpdating(ctx, update_from, update_to);
1720 ctx->text.clear_to_eol = True1;
1721}
1722
1723/*
1724 * The routine will scroll the displayed text by lines. If the arg is
1725 * positive, move up; otherwise, move down. [note: this is really a private
1726 * procedure but is used in multiple modules].
1727 */
1728void
1729_XawTextVScroll(TextWidget ctx, int n)
1730{
1731 XawTextScroll(ctx, n, 0);
1732}
1733
1734/*ARGSUSED*/
1735static void
1736HScroll(Widget w, XtPointer closure, XtPointer callData)
1737{
1738 TextWidget ctx = (TextWidget)closure;
1739 long pixels = (long)callData;
1740
1741 if (pixels > 0) {
1742 long max;
1743
1744 max = (int)GetWidestLine(ctx) + ctx->text.left_margin -
1745 ctx->text.r_margin.left;
1746 max = XawMax(0, max)((0) > (max) ? (0) : (max));
1747 pixels = XawMin(pixels, max)((pixels) < (max) ? (pixels) : (max));
1748 }
1749
1750 if (pixels) {
1751 _XawTextPrepareToUpdate(ctx);
1752 XawTextScroll(ctx, 0, pixels);
1753 _XawTextExecuteUpdate(ctx);
1754 }
1755}
1756
1757/*ARGSUSED*/
1758static void
1759HJump(Widget w, XtPointer closure, XtPointer callData)
1760{
1761 TextWidget ctx = (TextWidget)closure;
1762 float percent = *(float *)callData;
1763 long pixels;
1764
1765 pixels = ctx->text.left_margin -
1766 (ctx->text.r_margin.left - (int)(percent * GetWidestLine(ctx)));
1767
1768 HScroll(w, (XtPointer)ctx, (XtPointer)pixels);
1769}
1770
1771/*
1772 * Function:
1773 * UpdateTextInLine
1774 *
1775 * Parameters:
1776 * ctx - text widget
1777 * line - line to update
1778 * x1 - left pixel
1779 * x2 - right pixel
1780 *
1781 * Description:
1782 * Updates the text in the given line and pixel interval
1783 */
1784static void
1785UpdateTextInLine(TextWidget ctx, int line, int x1, int x2)
1786{
1787 XawTextLineTableEntry *lt = ctx->text.lt.info + line;
1788 XawTextPosition left, right;
1789 int from_x, width, height;
1790
1791 if (lt->position >= ctx->text.lastPos
1792 || ctx->text.left_margin > x2
1793 || (int)lt->textWidth + ctx->text.left_margin < x1) {
1794 /* Mark line to be cleared */
1795 if (ctx->text.clear_to_eol)
1796 _XawTextNeedsUpdating(ctx, lt->position, lt->position + 1);
1797 return;
1798 }
1799
1800 from_x = ctx->text.left_margin;
1801 XawTextSinkFindPosition(ctx->text.sink, lt->position,
1802 from_x, x1 - from_x,
1803 False0, &left, &width, &height);
1804 if (line == ctx->text.lt.lines)
1805 right = -1;
1806 else if (x2 >= lt->textWidth - from_x)
1807 right = lt[1].position - 1;
1808 else {
1809 from_x += width;
1810 XawTextSinkFindPosition(ctx->text.sink, left,
1811 from_x, x2 - from_x,
1812 False0, &right, &width, &height);
1813 }
1814
1815 if ((right < 0) || (right + 1 <= lt[1].position))
1816 ++right;
1817
1818 /* Mark text interval to be repainted */
1819 _XawTextNeedsUpdating(ctx, left, right);
1820}
1821
1822/*
1823 * The routine will scroll the displayed text by pixels. If the calldata is
1824 * positive, move up; otherwise, move down.
1825 */
1826/*ARGSUSED*/
1827static void
1828VScroll(Widget w, XtPointer closure, XtPointer callData)
1829{
1830 TextWidget ctx = (TextWidget)closure;
1831 long height, lines = (long)callData;
1832
1833 height = XtHeight(ctx)(((RectObj)ctx)->rectangle.height) - VMargins(ctx)((ctx)->text.margin.top + (ctx)->text.margin.bottom);
1834 if (height < 1)
1835 height = 1;
1836 lines = (lines * ctx->text.lt.lines) / height;
1837 _XawTextPrepareToUpdate(ctx);
1838 XawTextScroll(ctx, lines, 0);
1839 _XawTextExecuteUpdate(ctx);
1840}
1841
1842/*ARGSUSED*/
1843static void
1844VJump(Widget w, XtPointer closure, XtPointer callData)
1845{
1846 float percent = *(float *)callData;
1847 TextWidget ctx = (TextWidget)closure;
1848 XawTextPosition top, last, position, tmp;
1849 XawTextLineTable *lt = &(ctx->text.lt);
1850 int dim, vlines = 0, wwidth = GetMaxTextWidth(ctx);
1851 Boolint scroll = True1;
1852
1853 position = percent * ctx->text.lastPos;
1854 top = lt->top;
1855
1856 if (!lt->lines || (position >= lt->top && position < lt->info[1].position)) {
1857 _XawTextSetScrollBars(ctx);
1858 return;
1859 }
1860
1861#ifndef OLDXAW1
1862 ctx->text.lt.base_line = -1;
1863#endif
1864
1865 if (position > lt->top) { /* VScroll Up */
1866 if (position > lt->top && position < lt->info[lt->lines].position)
1867 vlines = LineForPosition(ctx, position);
1868 else {
1869 scroll = False0;
1870 top = SrcScanXawTextSourceScan(ctx->text.source, position, XawstEOL,
1871 XawsdLeft, 1, False0);
1872 if (ctx->text.wrap != XawtextWrapNever) {
1873 last = top;
1874 while (last < position) {
1875 tmp = last;
1876 XawTextSinkFindPosition(ctx->text.sink, last,
1877 ctx->text.left_margin, wwidth,
1878 ctx->text.wrap == XawtextWrapWord,
1879 &last, &dim, &dim);
1880 if (last == tmp)
1881 ++last;
1882 if (last < position)
1883 top = last;
1884 }
1885 }
1886 }
1887 }
1888 else { /* VScroll Down */
1889 /*
1890 * Calculates the number of lines
1891 */
1892 while (top > position) {
1893 last = top;
1894 top = SrcScanXawTextSourceScan(ctx->text.source, top, XawstEOL,
1895 XawsdLeft, 2, False0);
1896 vlines -= CountLines(ctx, top, last);
1897 if (-vlines >= ctx->text.lt.lines) {
1898 scroll = False0;
1899 top = SrcScanXawTextSourceScan(ctx->text.source, position, XawstEOL,
1900 XawsdLeft, 1, False0);
1901 break;
1902 }
1903 }
1904 /*
1905 * Normalize
1906 */
1907 if (ctx->text.wrap != XawtextWrapNever) {
1908 last = top;
1909 while (last < position) {
1910 tmp = last;
1911 XawTextSinkFindPosition(ctx->text.sink, last,
1912 ctx->text.left_margin,
1913 wwidth,
1914 ctx->text.wrap == XawtextWrapWord,
1915 &last, &dim, &dim);
1916 if (last == tmp)
1917 ++last;
1918 if (last < position)
1919 top = last;
1920 ++vlines;
1921 }
1922 }
1923 }
1924
1925 if (vlines || !scroll) {
1926 _XawTextPrepareToUpdate(ctx);
1927 if (scroll)
1928 XawTextScroll(ctx, vlines, 0);
1929 else
1930 _BuildLineTable(ctx, top, 0);
1931 _XawTextExecuteUpdate(ctx);
1932 }
1933}
1934
1935static Boolint
1936MatchSelection(Atom selection, XawTextSelection *s)
1937{
1938 Atom *match;
1939 int count;
1940
1941 for (count = 0, match = s->selections; count < s->atom_count;
1942 match++, count++)
1943 if (*match == selection)
1944 return (True1);
1945
1946 return (False0);
1947}
1948
1949static Boolean
1950TextConvertSelection(Widget w, Atom *selection, Atom *target, Atom *type,
1951 XtPointer *value, unsigned long *length, int *format)
1952{
1953 Display *d = XtDisplay(w)(((w)->core.screen)->display);
1954 TextWidget ctx = (TextWidget)w;
1955 Widget src = ctx->text.source;
1956 XawTextEditType edit_mode;
1957 Arg args[1];
1958 XawTextSelectionSalt *salt = NULL((void*)0);
1959 XawTextSelection *s;
1960
1961 if (*target == XA_TARGETS(d)XmuInternAtom(d, _XA_TARGETS)) {
1962 Atom *targetP, *std_targets;
1963 unsigned long std_length;
1964
1965 if (SrcCvtSelXawTextSourceConvertSelection(src, selection, target, type, value, length, format))
1966 return (True1);
1967
1968 XtSetArg(args[0], XtNeditType, &edit_mode)((void)( (args[0]).name = (((char*)&XtStrings[185])), (args
[0]).value = (XtArgVal)(&edit_mode) ))
;
1969 XtGetValues(src, args, ONE((Cardinal)1));
1970
1971 XmuConvertStandardSelection(w, ctx->text.time, selection,
1972 target, type, (XPointer*)&std_targets,
1973 &std_length, format);
1974
1975 *length = 7 + (edit_mode == XawtextEdit) + std_length;
1976 *value = XtMalloc((unsigned)sizeof(Atom)*(*length));
1977 targetP = *(Atom**)value;
1978 *targetP++ = XA_STRING((Atom) 31);
1979 *targetP++ = XA_TEXT(d)XmuInternAtom(d, _XA_TEXT);
1980 *targetP++ = XA_UTF8_STRING(d)XmuInternAtom(d, _XA_UTF8_STRING);
1981 *targetP++ = XA_COMPOUND_TEXT(d)XmuInternAtom(d, _XA_COMPOUND_TEXT);
1982 *targetP++ = XA_LENGTH(d)XmuInternAtom(d, _XA_LENGTH);
1983 *targetP++ = XA_LIST_LENGTH(d)XmuInternAtom(d, _XA_LIST_LENGTH);
1984 *targetP++ = XA_CHARACTER_POSITION(d)XmuInternAtom(d, _XA_CHARACTER_POSITION);
1985 if (edit_mode == XawtextEdit) {
1986 *targetP++ = XA_DELETE(d)XmuInternAtom(d, _XA_DELETE);
1987 }
1988 (void)memmove((char*)targetP, (char*)std_targets,
1989 sizeof(Atom) * std_length);
1990 XtFree((char*)std_targets);
1991 *type = XA_ATOM((Atom) 4);
1992 *format = 32;
1993 return (True1);
1994 }
1995
1996 if (SrcCvtSelXawTextSourceConvertSelection(src, selection, target, type, value, length, format))
1997 return (True1);
1998
1999 if (MatchSelection(*selection, &ctx->text.s))
2000 s = &ctx->text.s;
2001 else {
2002 for (salt = ctx->text.salt; salt; salt = salt->next)
2003 if (MatchSelection(*selection, &salt->s))
2004 break;
2005 if (!salt)
2006 return (False0);
2007 s = &salt->s;
2008 }
2009 if (*target == XA_STRING((Atom) 31)
2010 || *target == XA_TEXT(d)XmuInternAtom(d, _XA_TEXT)
2011 || *target == XA_UTF8_STRING(d)XmuInternAtom(d, _XA_UTF8_STRING)
2012 || *target == XA_COMPOUND_TEXT(d)XmuInternAtom(d, _XA_COMPOUND_TEXT)) {
2013 if (*target == XA_TEXT(d)XmuInternAtom(d, _XA_TEXT)) {
2014 if (XawTextFormat(ctx, XawFmtWide)((unsigned long)_XawTextFormat(ctx) == (XawFmtWide)))
2015 *type = XA_COMPOUND_TEXT(d)XmuInternAtom(d, _XA_COMPOUND_TEXT);
2016 else
2017 *type = XA_STRING((Atom) 31);
2018 }
2019 else
2020 *type = *target;
2021 /*
2022 * If salt is True, the salt->contents stores CT string,
2023 * its length is measured in bytes.
2024 * Refer to _XawTextSaltAwaySelection().
2025 *
2026 * by Li Yuhong, Mar. 20, 1991.
2027 */
2028 if (!salt) {
2029 *value = _XawTextGetSTRING(ctx, s->left, s->right);
2030 if (XawTextFormat(ctx, XawFmtWide)((unsigned long)_XawTextFormat(ctx) == (XawFmtWide))) {
2031 XTextProperty textprop;
2032 if (XwcTextListToTextProperty(d, (wchar_t **)value, 1,
2033 XCompoundTextStyle, &textprop)
2034 < Success0) {
2035 XtFree((char *)*value);
2036 return (False0);
2037 }
2038 XtFree((char *)*value);
2039 *value = (XtPointer)textprop.value;
2040 *length = textprop.nitems;
2041 }
2042 else
2043 *length = strlen((char *)*value);
2044 }
2045 else {
2046 *value = XtMalloc((salt->length + 1) * sizeof(unsigned char));
2047 strcpy ((char *)*value, salt->contents);
2048 *length = salt->length;
2049 }
2050 /* Got *value,*length, now in COMPOUND_TEXT format. */
2051 if (XawTextFormat(ctx, XawFmtWide)((unsigned long)_XawTextFormat(ctx) == (XawFmtWide)) && *type == XA_STRING((Atom) 31)) {
2052 XTextProperty textprop;
2053 wchar_t **wlist;
2054 int count;
2055
2056 textprop.encoding = XA_COMPOUND_TEXT(d)XmuInternAtom(d, _XA_COMPOUND_TEXT);
2057 textprop.value = (unsigned char *)*value;
2058 textprop.nitems = strlen(*value);
2059 textprop.format = 8;
2060 if (XwcTextPropertyToTextList(d, &textprop, &wlist, &count)
2061 < Success0
2062 || count < 1) {
2063 XtFree((char *)*value);
2064 return (False0);
2065 }
2066 XtFree((char *)*value);
2067 if (XwcTextListToTextProperty(d, wlist, 1, XStringStyle, &textprop)
2068 < Success0) {
2069 XwcFreeStringList((wchar_t**) wlist);
2070 return (False0);
2071 }
2072 *value = (XtPointer)textprop.value;
2073 *length = textprop.nitems;
2074 XwcFreeStringList(wlist);
2075 } else if (*type == XA_UTF8_STRING(d)XmuInternAtom(d, _XA_UTF8_STRING)) {
2076 XTextProperty textprop;
2077 char **list;
2078 int count;
2079
2080 textprop.encoding = XA_COMPOUND_TEXT(d)XmuInternAtom(d, _XA_COMPOUND_TEXT);
2081 textprop.value = (unsigned char *)*value;
2082 textprop.nitems = strlen(*value);
2083 textprop.format = 8;
2084 if (Xutf8TextPropertyToTextList(d, &textprop, &list, &count)
2085 < Success0
2086 || count < 1) {
2087 XtFree((char *)*value);
2088 return (False0);
2089 }
2090 XtFree((char *)*value);
2091 *value = *list;
2092 *length = strlen(*list);
2093 XFree(list);
2094 }
2095 *format = 8;
2096 return (True1);
2097 }
2098
2099 if ((*target == XA_LIST_LENGTH(d)XmuInternAtom(d, _XA_LIST_LENGTH)) || (*target == XA_LENGTH(d)XmuInternAtom(d, _XA_LENGTH))) {
2100 long * temp;
2101
2102 temp = (long *)XtMalloc((unsigned)sizeof(long));
2103 if (*target == XA_LIST_LENGTH(d)XmuInternAtom(d, _XA_LIST_LENGTH))
2104 *temp = 1L;
2105 else /* *target == XA_LENGTH(d) */
2106 *temp = (long) (s->right - s->left);
2107
2108 *value = (XPointer)temp;
2109 *type = XA_INTEGER((Atom) 19);
2110 *length = 1L;
2111 *format = 32;
2112 return (True1);
2113 }
2114
2115 if (*target == XA_CHARACTER_POSITION(d)XmuInternAtom(d, _XA_CHARACTER_POSITION)) {
2116 long * temp;
2117
2118 temp = (long *)XtMalloc((unsigned)(2 * sizeof(long)));
2119 temp[0] = (long)(s->left + 1);
2120 temp[1] = s->right;
2121 *value = (XPointer)temp;
2122 *type = XA_SPAN(d)XmuInternAtom(d, _XA_SPAN);
2123 *length = 2L;
2124 *format = 32;
2125 return (True1);
2126 }
2127
2128 if (*target == XA_DELETE(d)XmuInternAtom(d, _XA_DELETE)) {
2129 if (!salt)
2130 _XawTextZapSelection(ctx, NULL((void*)0), True1);
2131 *value = NULL((void*)0);
2132 *type = XA_NULL(d)XmuInternAtom(d, _XA_NULL);
2133 *length = 0;
2134 *format = 32;
2135 return (True1);
2136 }
2137
2138 if (XmuConvertStandardSelection(w, ctx->text.time, selection, target, type,
2139 (XPointer *)value, length, format))
2140 return (True1);
2141
2142 /* else */
2143 return (False0);
2144}
2145
2146/*
2147 * Function:
2148 * GetCutBuffferNumber
2149 *
2150 * Parameters:
2151 * atom - atom to check
2152 *
2153 * Description:
2154 * Returns the number of the cut buffer.
2155 *
2156 * Returns:
2157 * The number of the cut buffer representing this atom or NOT_A_CUT_BUFFER
2158 */
2159#define NOT_A_CUT_BUFFER-1 -1
2160static int
2161GetCutBufferNumber(Atom atom)
2162{
2163 if (atom == XA_CUT_BUFFER0((Atom) 9)) return (0);
2164 if (atom == XA_CUT_BUFFER1((Atom) 10)) return (1);
2165 if (atom == XA_CUT_BUFFER2((Atom) 11)) return (2);
2166 if (atom == XA_CUT_BUFFER3((Atom) 12)) return (3);
2167 if (atom == XA_CUT_BUFFER4((Atom) 13)) return (4);
2168 if (atom == XA_CUT_BUFFER5((Atom) 14)) return (5);
2169 if (atom == XA_CUT_BUFFER6((Atom) 15)) return (6);
2170 if (atom == XA_CUT_BUFFER7((Atom) 16)) return (7);
2171 return (NOT_A_CUT_BUFFER-1);
2172}
2173
2174static void
2175TextLoseSelection(Widget w, Atom *selection)
2176{
2177 TextWidget ctx = (TextWidget)w;
2178 Atom *atomP;
2179 int i;
2180 XawTextSelectionSalt*salt, *prevSalt, *nextSalt;
2181
2182 atomP = ctx->text.s.selections;
2183 for (i = 0 ; i < ctx->text.s.atom_count; i++, atomP++)
2184 if ((*selection == *atomP)
2185 || (GetCutBufferNumber(*atomP) != NOT_A_CUT_BUFFER-1))
2186 *atomP = (Atom)0;
2187
2188 while (ctx->text.s.atom_count
2189 && ctx->text.s.selections[ctx->text.s.atom_count - 1] == 0)
2190 ctx->text.s.atom_count--;
2191
2192 /*
2193 * Must walk the selection list in opposite order from UnsetSelection
2194 */
2195 atomP = ctx->text.s.selections;
2196 for (i = 0 ; i < ctx->text.s.atom_count; i++, atomP++)
2197 if (*atomP == (Atom)0) {
2198 *atomP = ctx->text.s.selections[--ctx->text.s.atom_count];
2199 while (ctx->text.s.atom_count
2200 && ctx->text.s.selections[ctx->text.s.atom_count-1] == 0)
2201 ctx->text.s.atom_count--;
2202 }
2203
2204 if (ctx->text.s.atom_count == 0)
2205 ModifySelection(ctx, ctx->text.insertPos, ctx->text.insertPos);
2206
2207 prevSalt = 0;
2208 for (salt = ctx->text.salt; salt; salt = nextSalt) {
2209 atomP = salt->s.selections;
2210 nextSalt = salt->next;
2211 for (i = 0 ; i < salt->s.atom_count; i++, atomP++)
2212 if (*selection == *atomP)
2213 *atomP = (Atom)0;
2214
2215 while (salt->s.atom_count
2216 && salt->s.selections[salt->s.atom_count-1] == 0)
2217 salt->s.atom_count--;
2218
2219 /*
2220 * Must walk the selection list in opposite order from UnsetSelection
2221 */
2222 atomP = salt->s.selections;
2223 for (i = 0 ; i < salt->s.atom_count; i++, atomP++)
2224 if (*atomP == (Atom)0) {
2225 *atomP = salt->s.selections[--salt->s.atom_count];
2226 while (salt->s.atom_count
2227 && salt->s.selections[salt->s.atom_count-1] == 0)
2228 salt->s.atom_count--;
2229 }
2230
2231 if (salt->s.atom_count == 0) {
2232 XtFree ((char *) salt->s.selections);
2233 XtFree (salt->contents);
2234 if (prevSalt)
2235 prevSalt->next = nextSalt;
2236 else
2237 ctx->text.salt = nextSalt;
2238 XtFree((char *)salt);
2239 }
2240 else
2241 prevSalt = salt;
2242 }
2243}
2244
2245void
2246_XawTextSaltAwaySelection(TextWidget ctx, Atom *selections, int num_atoms)
2247{
2248 XawTextSelectionSalt *salt;
2249 int i, j;
2250
2251 for (i = 0; i < num_atoms; i++)
2252 TextLoseSelection((Widget)ctx, selections + i);
2253 if (num_atoms == 0)
2254 return;
2255 salt = (XawTextSelectionSalt *)
2256 XtMalloc((unsigned)sizeof(XawTextSelectionSalt));
2257 if (!salt)
2258 return;
2259 salt->s.selections = (Atom *)XtMalloc((unsigned)(num_atoms * sizeof(Atom)));
2260 if (!salt->s.selections) {
2261 XtFree((char *)salt);
2262 return;
2263 }
2264 salt->s.left = ctx->text.s.left;
2265 salt->s.right = ctx->text.s.right;
2266 salt->s.type = ctx->text.s.type;
2267 salt->contents = _XawTextGetSTRING(ctx, ctx->text.s.left, ctx->text.s.right);
2268 if (XawTextFormat(ctx, XawFmtWide)((unsigned long)_XawTextFormat(ctx) == (XawFmtWide))) {
2269 XTextProperty textprop;
2270 if (XwcTextListToTextProperty(XtDisplay((Widget)ctx)((((Widget)ctx)->core.screen)->display),
2271 (wchar_t**)(&(salt->contents)), 1,
2272 XCompoundTextStyle,
2273 &textprop) < Success0) {
2274 XtFree(salt->contents);
2275 salt->length = 0;
2276 return;
2277 }
2278 XtFree(salt->contents);
2279 salt->contents = (char *)textprop.value;
2280 salt->length = textprop.nitems;
2281 }
2282 else
2283 salt->length = strlen (salt->contents);
2284 salt->next = ctx->text.salt;
2285 ctx->text.salt = salt;
2286 j = 0;
2287 for (i = 0; i < num_atoms; i++) {
2288 if (GetCutBufferNumber (selections[i]) == NOT_A_CUT_BUFFER-1) {
2289 salt->s.selections[j++] = selections[i];
2290 XtOwnSelection((Widget)ctx, selections[i], ctx->text.time,
2291 TextConvertSelection, TextLoseSelection, NULL((void*)0));
2292 }
2293 }
2294 salt->s.atom_count = j;
2295}
2296
2297static void
2298_SetSelection(TextWidget ctx, XawTextPosition left, XawTextPosition right,
2299 Atom *selections, Cardinal count)
2300{
2301#ifndef OLDXAW1
2302 Cardinal i;
2303 XawTextPosition pos;
2304 TextSrcObject src = (TextSrcObject)ctx->text.source;
2305
2306 for (i = 0; i < src->textSrc.num_text; i++) {
2307 TextWidget tw = (TextWidget)src->textSrc.text[i];
2308 Boolint needs_updating = tw->text.old_insert < 0;
2309 Boolint showposition = tw->text.showposition;
2310
2311 if (needs_updating) {
2312 tw->text.showposition = False0;
2313 _XawTextPrepareToUpdate(tw);
2314 }
2315#else
2316 TextWidget tw = ctx;
2317 XawTextPosition pos;
2318#endif /* OLDXAW */
2319
2320 if (left < tw->text.s.left) {
2321 pos = Min(right, tw->text.s.left)(((right) < (tw->text.s.left)) ? (right) : (tw->text
.s.left))
;
2322 _XawTextNeedsUpdating(tw, left, pos);
2323 }
2324 if (left > tw->text.s.left) {
2325 pos = Min(left, tw->text.s.right)(((left) < (tw->text.s.right)) ? (left) : (tw->text.
s.right))
;
2326 _XawTextNeedsUpdating(tw, tw->text.s.left, pos);
2327 }
2328 if (right < tw->text.s.right) {
2329 pos = Max(right, tw->text.s.left)(((right) > (tw->text.s.left)) ? (right) : (tw->text
.s.left))
;
2330 _XawTextNeedsUpdating(tw, pos, tw->text.s.right);
2331 }
2332 if (right > tw->text.s.right) {
2333 pos = Max(left, tw->text.s.right)(((left) > (tw->text.s.right)) ? (left) : (tw->text.
s.right))
;
2334 _XawTextNeedsUpdating(tw, pos, right);
2335 }
2336
2337 tw->text.s.left = left;
2338 tw->text.s.right = right;
2339
2340#ifndef OLDXAW1
2341 if (needs_updating) {
2342 _XawTextExecuteUpdate(tw);
2343 tw->text.showposition = showposition;
2344 }
2345 }
2346#endif /* OLDXAW */
2347
2348 SrcSetSelectionXawTextSourceSetSelection(ctx->text.source, left, right,
2349 (count == 0) ? None0L : selections[0]);
2350
2351 if (left < right) {
2352 Widget w = (Widget)ctx;
2353 int buffer;
2354
2355 while (count) {
2356 Atom selection = selections[--count];
2357
2358 /*
2359 * If this is a cut buffer
2360 */
2361 if ((buffer = GetCutBufferNumber(selection)) != NOT_A_CUT_BUFFER-1) {
2362 unsigned char *ptr, *tptr;
2363 unsigned int amount, max_len = MAX_CUT_LEN(XtDisplay(w))(XMaxRequestSize((((w)->core.screen)->display)) - 64);
2364 unsigned long len;
2365
2366 tptr= ptr= (unsigned char *)_XawTextGetSTRING(ctx,
2367 ctx->text.s.left,
2368 ctx->text.s.right);
2369 if (XawTextFormat(ctx, XawFmtWide)((unsigned long)_XawTextFormat(ctx) == (XawFmtWide))) {
2370 /*
2371 * Only XA_STRING(Latin 1) is allowed in CUT_BUFFER,
2372 * so we get it from wchar string, then free the wchar string
2373 */
2374 XTextProperty textprop;
2375
2376 if (XwcTextListToTextProperty(XtDisplay(w)(((w)->core.screen)->display), (wchar_t**)&ptr,
2377 1, XStringStyle, &textprop)
2378 < Success0){
2379 XtFree((char *)ptr);
2380 return;
2381 }
2382 XtFree((char *)ptr);
2383 tptr = ptr = textprop.value;
2384 }
2385 if (buffer == 0) {
2386 _CreateCutBuffers(XtDisplay(w)(((w)->core.screen)->display));
2387 XRotateBuffers(XtDisplay(w)(((w)->core.screen)->display), 1);
2388 }
2389 amount = Min ((len = strlen((char *)ptr)), max_len)((((len = strlen((char *)ptr))) < (max_len)) ? ((len = strlen
((char *)ptr))) : (max_len))
;
2390 XChangeProperty(XtDisplay(w)(((w)->core.screen)->display), RootWindow(XtDisplay(w), 0)((&((_XPrivDisplay)(((w)->core.screen)->display))->
screens[0])->root)
,
2391 selection, XA_STRING((Atom) 31), 8, PropModeReplace0,
2392 ptr, amount);
2393
2394 while (len > max_len) {
2395 len -= max_len;
2396 tptr += max_len;
2397 amount = Min (len, max_len)(((len) < (max_len)) ? (len) : (max_len));
2398 XChangeProperty(XtDisplay(w)(((w)->core.screen)->display), RootWindow(XtDisplay(w), 0)((&((_XPrivDisplay)(((w)->core.screen)->display))->
screens[0])->root)
,
2399 selection, XA_STRING((Atom) 31), 8, PropModeAppend2,
2400 tptr, amount);
2401 }
2402 XtFree ((char *)ptr);
2403 }
2404 else /* This is a real selection */
2405 XtOwnSelection(w, selection, ctx->text.time, TextConvertSelection,
2406 TextLoseSelection, NULL((void*)0));
2407 }
2408 }
2409 else
2410 XawTextUnsetSelection((Widget)ctx);
2411}
2412
2413#ifndef OLDXAW1
2414void
2415_XawTextSetLineAndColumnNumber(TextWidget ctx, Boolint force)
2416{
2417 int line_number, column_number;
2418
2419 if (ctx->text.old_insert != ctx->text.insertPos &&
2420 ctx->text.lt.base_line < 0) {
2421 ctx->text.lt.base_line = 0;
2422 (void)_BuildLineTable(ctx, ctx->text.lt.top, 0);
2423 }
2424
2425 line_number = ResolveLineNumber(ctx);
2426 column_number = ResolveColumnNumber(ctx);
2427
2428 if (force || (ctx->text.column_number != column_number
2429 || ctx->text.line_number != line_number)) {
2430 XawTextPositionInfo info;
2431
2432 ctx->text.line_number = info.line_number = line_number;
2433 ctx->text.column_number = info.column_number = column_number;
2434 info.insert_position = ctx->text.insertPos;
2435 info.last_position = ctx->text.lastPos;
2436 info.overwrite_mode = ctx->text.overwrite;
2437
2438 XtCallCallbacks((Widget)ctx, XtNpositionCallback"positionCallback", (XtPointer)&info);
2439 }
2440}
2441
2442static int
2443ResolveColumnNumber(TextWidget ctx)
2444{
2445 Widget src = ctx->text.source;
2446 short column_number = 0;
2447 XawTextPosition position;
2448 XawTextBlock block;
2449 unsigned long format = _XawTextFormat(ctx);
2450 TextSinkObject sink = (TextSinkObject)ctx->text.sink;
2451 short *char_tabs = sink->text_sink.char_tabs;
2452 int tab_count = sink->text_sink.tab_count;
2453 int tab_index = 0, tab_column = 0, tab_base = 0;
2454
2455 if (ctx->text.lt.base_line < 1)
2456 return (ctx->text.column_number);
2457
2458 position = SrcScanXawTextSourceScan(src, ctx->text.insertPos, XawstEOL, XawsdLeft, 1, False0);
2459 XawTextSourceRead(src, position, &block, ctx->text.insertPos - position);
2460
2461 for (; position < ctx->text.insertPos; position++) {
2462 if (position - block.firstPos >= block.length)
2463 XawTextSourceRead(src, position, &block, ctx->text.insertPos - position);
2464 if ((format == XawFmt8Bit && block.ptr[position - block.firstPos] == '\t') ||
2465 (format == XawFmtWide && ((wchar_t*)block.ptr)[position - block.firstPos] == _Xaw_atowc(XawTAB0x09))) {
2466 while (tab_base + tab_column <= column_number) {
2467 if (tab_count) {
2468 for (; tab_index < tab_count; ++tab_index)
2469 if (tab_base + char_tabs[tab_index] > column_number) {
2470 tab_column = char_tabs[tab_index];
2471 break;
2472 }
2473 if (tab_index >= tab_count) {
2474 tab_base += char_tabs[tab_count - 1];
2475 tab_column = tab_index = 0;
2476 }
2477 }
2478 else
2479 tab_column += DEFAULT_TAB_SIZE8;
2480 }
2481 column_number = tab_base + tab_column;
2482 }
2483 else
2484 ++column_number;
2485 if (column_number >= 16384) {
2486 column_number = 16383;
2487 break;
2488 }
2489 }
2490
2491 return (column_number);
2492}
2493#endif /* OLDXAW */
2494
2495void
2496_XawTextSourceChanged(Widget w, XawTextPosition left, XawTextPosition right,
2497 XawTextBlock *block, int lines)
2498{
2499 TextWidget ctx = (TextWidget)w;
2500 Widget src = ctx->text.source;
2501 XawTextPosition update_from, update_to, top;
2502 Boolean update_disabled;
2503 int delta, line, line_from;
2504
2505 if (left < ctx->text.old_insert) {
2506 XawTextPosition old_insert = ctx->text.old_insert;
2507
2508 if (right < ctx->text.old_insert)
2509 old_insert -= right - left;
2510 else
2511 old_insert = left;
2512
2513 ctx->text.insertPos = old_insert + block->length;
2514 }
2515#ifndef OLDXAW1
2516 if (left <= ctx->text.lt.top) {
2517 if (left + block->length - (right - left) < ctx->text.lt.top) {
2518 ctx->text.source_changed = SRC_CHANGE_BEFORE2;
2519 ctx->text.lt.base_line += lines;
2520 }
2521 else
2522 ctx->text.source_changed = SRC_CHANGE_OVERLAP3;
2523 }
2524 else
2525 ctx->text.source_changed = SRC_CHANGE_AFTER1;
2526#endif
2527
2528 update_from = left;
2529 update_to = left + block->length;
2530 update_to = SrcScanXawTextSourceScan(src, update_to, XawstEOL, XawsdRight, 1, False0);
2531 delta = block->length - (right - left);
2532 if (delta < 0)
2533 ctx->text.clear_to_eol = True1;
2534 if (update_to == update_from)
2535 ++update_to;
2536 update_disabled = ctx->text.update_disabled;
2537 ctx->text.update_disabled = True1;
2538 ctx->text.lastPos = XawTextGetLastPosition(ctx)XawTextSourceScan((ctx)->text.source, 0, XawstAll, XawsdRight
, 1, 1)
;
2539 top = ctx->text.lt.info[0].position;
2540
2541 XawTextUnsetSelection((Widget)ctx);
2542
2543 if (delta) {
2544 int i;
2545 XmuSegment *seg;
2546
2547 for (seg = ctx->text.update->segment; seg; seg = seg->next) {
2548 if (seg->x1 > (int)left)
2549 break;
2550 else if (seg->x2 > (int)left) {
2551 seg->x2 += delta;
2552 seg = seg->next;
2553 break;
2554 }
2555 }
2556 for (; seg; seg = seg->next) {
2557 seg->x1 += delta;
2558 seg->x2 += delta;
2559 }
2560 XmuOptimizeScanline(ctx->text.update);
2561
2562 for (i = 0; i <= ctx->text.lt.lines; i++)
2563 if (ctx->text.lt.info[i].position > left)
2564 break;
2565 for (; i <= ctx->text.lt.lines; i++)
2566 ctx->text.lt.info[i].position += delta;
2567 }
2568
2569 if (top != ctx->text.lt.info[0].position) {
2570 line_from = line = 0;
2571 ctx->text.lt.top = top = SrcScanXawTextSourceScan(src, ctx->text.lt.info[0].position,
2572 XawstEOL, XawsdLeft, 1, False0);
2573 update_from = top;
2574 }
2575 else {
2576 line_from = line = LineForPosition(ctx, update_from + delta);
2577 top = ctx->text.lt.info[line].position;
2578 }
2579
2580 if (line > 0 && ctx->text.wrap == XawtextWrapWord) {
2581 --line;
2582 top = ctx->text.lt.info[line].position;
2583 }
2584
2585 (void)_BuildLineTable(ctx, top, line);
2586
2587 if (ctx->text.wrap == XawtextWrapWord) {
2588 if (line_from != LineForPosition(ctx, update_from)
2589 || line_from != LineForPosition(ctx, update_to)) {
2590 ctx->text.clear_to_eol = True1;
2591 update_from = SrcScanXawTextSourceScan(src, update_from,
2592 XawstWhiteSpace, XawsdLeft, 1, True1);
2593 if (update_to >= ctx->text.lastPos)
2594 /* this is not an error, it just tells _BuildLineTable to
2595 * clear to the bottom of the window. The value of update_to
2596 * should not be > ctx->text.lastPos.
2597 */
2598 ++update_to;
2599 }
2600 }
2601 else if (!ctx->text.clear_to_eol) {
2602 if (LineForPosition(ctx, update_from)
2603 != LineForPosition(ctx, update_to))
2604 ctx->text.clear_to_eol = True1;
2605 }
2606
2607 _XawTextNeedsUpdating(ctx, update_from, update_to);
2608 ctx->text.update_disabled = update_disabled;
2609}
2610
2611/*
2612 * Function:
2613 * _XawTextReplace
2614 *
2615 * Parameters:
2616 * ctx - text widget
2617 * left - left offset
2618 * right - right offset
2619 * block - text block
2620 *
2621 * Description:
2622 * Replaces the text between left and right by the text in block.
2623 * Does all the required calculations of offsets, and rebuild the
2624 * the line table, from the insertion point (or previous line, if
2625 * wrap mode is 'word').
2626 *
2627 * Returns:
2628 * XawEditDone - success
2629 * any other value - error code
2630 */
2631int
2632_XawTextReplace(TextWidget ctx, XawTextPosition left, XawTextPosition right,
2633 XawTextBlock *block)
2634{
2635 Arg args[1];
2636 Widget src;
2637 XawTextEditType edit_mode;
2638
2639 if (left == right && block->length == 0)
2640 return (XawEditDone0);
2641
2642 src = ctx->text.source;
2643 XtSetArg(args[0], XtNeditType, &edit_mode)((void)( (args[0]).name = (((char*)&XtStrings[185])), (args
[0]).value = (XtArgVal)(&edit_mode) ))
;
2644 XtGetValues(src, args, 1);
2645
2646 if (edit_mode == XawtextAppend) {
2647 if (block->length == 0)
2648 return (XawEditError1);
2649 ctx->text.insertPos = ctx->text.lastPos;
2650 }
2651
2652#ifndef OLDXAW1
2653 return (SrcReplaceXawTextSourceReplace(src, left, right, block));
2654#else
2655 if (SrcReplaceXawTextSourceReplace(src, left, right, block) == XawEditDone0) {
2656 _XawTextSourceChanged((Widget)ctx, left, right, block, 0);
2657
2658 return (XawEditDone0);
2659 }
2660
2661 return (XawEditError1);
2662#endif
2663}
2664
2665/*
2666 * This routine will display text between two arbitrary source positions.
2667 * In the event that this span contains highlighted text for the selection,
2668 * only that portion will be displayed highlighted.
2669 */
2670static void
2671OldDisplayText(Widget w, XawTextPosition left, XawTextPosition right)
2672{
2673 static XmuSegment segment;
2674 static XmuScanline next;
2675 static XmuScanline scanline = {0, &segment, &next};
2676 static XmuArea area = {&scanline};
2677
2678 TextWidget ctx = (TextWidget)w;
2679 int x, y, line;
2680 XawTextPosition start, end, last, final;
2681 XmuScanline *scan;
2682 XmuSegment *seg;
2683 XmuArea *clip = NULL((void*)0);
2684 Boolint cleol = ctx->text.clear_to_eol;
2685 Boolint has_selection = ctx->text.s.right > ctx->text.s.left;
2686
2687 left = left < ctx->text.lt.top ? ctx->text.lt.top : left;
2688
2689 if (left > right || !LineAndXYForPosition(ctx, left, &line, &x, &y))
2690 return;
2691
2692 last = XawTextGetLastPosition(ctx)XawTextSourceScan((ctx)->text.source, 0, XawstAll, XawsdRight
, 1, 1)
;
2693 segment.x2 = (int)XtWidth(ctx)(((RectObj)ctx)->rectangle.width) - ctx->text.r_margin.right;
2694
2695 if (cleol)
2696 clip = XmuCreateArea()XmuNewArea(0, 0, 0, 0);
2697
2698 for (start = left; start < right && line < ctx->text.lt.lines; line++) {
2699 if ((end = ctx->text.lt.info[line + 1].position) > right)
2700 end = right;
2701
2702 final = end;
2703 if (end > last)
2704 end = last;
2705
2706 if (end > start) {
2707 if (!has_selection
2708 || (start >= ctx->text.s.right || end <= ctx->text.s.left))
2709 _XawTextSinkDisplayText(ctx->text.sink, x, y, start, end, False0);
2710 else if (start >= ctx->text.s.left && end <= ctx->text.s.right)
2711 _XawTextSinkDisplayText(ctx->text.sink, x, y, start, end, True1);
2712 else {
2713 OldDisplayText(w, start, ctx->text.s.left);
2714 OldDisplayText(w, Max(start, ctx->text.s.left)(((start) > (ctx->text.s.left)) ? (start) : (ctx->text
.s.left))
,
2715 Min(end, ctx->text.s.right)(((end) < (ctx->text.s.right)) ? (end) : (ctx->text.
s.right))
);
2716 OldDisplayText(w, ctx->text.s.right, end);
2717 }
2718 }
2719
2720 x = ctx->text.left_margin;
2721 if (cleol) {
2722 segment.x1 = ctx->text.lt.info[line].textWidth + x;
2723 if (XmuValidSegment(&segment)((&segment)->x1 < (&segment)->x2)) {
2724 scanline.y = y;
2725 next.y = ctx->text.lt.info[line + 1].y;
2726 XmuAreaOr(clip, &area)XmuAreaOrXor((clip), (&area), 1);
2727 }
2728 }
2729
2730 start = final;
2731 y = ctx->text.lt.info[line + 1].y;
2732 }
2733
2734 if (cleol) {
2735 for (scan = clip->scanline; scan && scan->next; scan = scan->next)
2736 for (seg = scan->segment; seg; seg = seg->next)
2737 SinkClearToBG_XawTextSinkClearToBackground(ctx->text.sink,
2738 seg->x1, scan->y,
2739 seg->x2 - seg->x1, scan->next->y - scan->y);
2740 XmuDestroyArea(clip)do { XmuDestroyScanlineList((clip)->scanline); XtFree((char
*)(clip)); } while (0)
;
2741 }
2742}
2743
2744#ifndef OLDXAW1
2745/*ARGSUSED*/
2746static void
2747DisplayText(Widget w, XawTextPosition left, XawTextPosition right)
2748{
2749 static XmuSegment segment;
2750 static XmuScanline next;
2751 static XmuScanline scanline = {0, &segment, &next};
2752 static XmuArea area = {&scanline};
2753
2754 TextWidget ctx = (TextWidget)w;
2755 int y, line;
2756 XawTextPosition from, to, lastPos;
2757 Boolint cleol = ctx->text.clear_to_eol;
2758 Boolint has_selection = ctx->text.s.right > ctx->text.s.left;
2759 XawTextPaintList *paint_list;
2760
2761 left = left < ctx->text.lt.top ? ctx->text.lt.top : left;
2762
2763 if (left > right || !IsPositionVisible(ctx, left)(left >= ctx->text.lt.info[0].position && left <
ctx->text.lt.info[ctx->text.lt.lines].position)
)
2764 return;
2765
2766 line = LineForPosition(ctx, left);
2767 y = ctx->text.lt.info[line].y;
2768 segment.x2 = (int)XtWidth(ctx)(((RectObj)ctx)->rectangle.width) - ctx->text.r_margin.right;
2769 lastPos = XawTextGetLastPosition(ctx)XawTextSourceScan((ctx)->text.source, 0, XawstAll, XawsdRight
, 1, 1)
;
2770
2771 paint_list = ((TextSinkObject)ctx->text.sink)->text_sink.paint;
2772
2773 for (from = left; from < right && line < ctx->text.lt.lines; line++) {
2774 if ((to = ctx->text.lt.info[line + 1].position) > right)
2775 to = right;
2776
2777 if (to > lastPos)
2778 to = lastPos;
2779
2780 if (from < to) {
2781 if (!has_selection
2782 || (from >= ctx->text.s.right || to <= ctx->text.s.left))
2783 XawTextSinkPreparePaint(ctx->text.sink, y, line, from, to, False0);
2784 else if (from >= ctx->text.s.left && to <= ctx->text.s.right)
2785 XawTextSinkPreparePaint(ctx->text.sink, y, line, from, to, True1);
2786 else {
2787 XawTextSinkPreparePaint(ctx->text.sink, y, line, from,
2788 ctx->text.s.left, False0);
2789 XawTextSinkPreparePaint(ctx->text.sink, y, line,
2790 XawMax(from, ctx->text.s.left)((from) > (ctx->text.s.left) ? (from) : (ctx->text.s
.left))
,
2791 XawMin(to, ctx->text.s.right)((to) < (ctx->text.s.right) ? (to) : (ctx->text.s.right
))
, True1);
2792 XawTextSinkPreparePaint(ctx->text.sink, y, line,
2793 ctx->text.s.right, to, False0);
2794 }
2795 }
2796
2797 if (cleol) {
2798 segment.x1 = ctx->text.lt.info[line].textWidth + ctx->text.left_margin;
2799 if (XmuValidSegment(&segment)((&segment)->x1 < (&segment)->x2)) {
2800 scanline.y = y;
2801 next.y = ctx->text.lt.info[line + 1].y;
2802 XmuAreaOr(paint_list->clip, &area)XmuAreaOrXor((paint_list->clip), (&area), 1);
2803 }
2804 }
2805 y = ctx->text.lt.info[line + 1].y;
2806 from = to;
2807 }
2808
2809 /* clear to the bottom of the window */
2810 if (cleol && line >= ctx->text.lt.lines) {
2811 segment.x1 = ctx->text.left_margin;
2812 if (XmuValidSegment(&segment)((&segment)->x1 < (&segment)->x2)) {
2813 scanline.y = y;
2814 next.y = (int)XtHeight(ctx)(((RectObj)ctx)->rectangle.height) - (int)ctx->text.margin.bottom;
2815 XmuAreaOr(paint_list->clip, &area)XmuAreaOrXor((paint_list->clip), (&area), 1);
2816 }
2817 }
2818}
2819#endif
2820
2821/*
2822 * This routine implements multi-click selection in a hardwired manner.
2823 * It supports multi-click entity cycling (char, word, line, file) and mouse
2824 * motion adjustment of the selected entitie (i.e. select a word then, with
2825 * button still down, adjust wich word you really meant by moving the mouse).
2826 * [NOTE: This routine is to be replaced by a set of procedures that
2827 * will allows clients to implements a wide class of draw through and
2828 * multi-click selection user interfaces.]
2829 */
2830static void
2831DoSelection(TextWidget ctx, XawTextPosition pos, Time time, Boolint motion)
2832{
2833 XawTextPosition newLeft, newRight;
2834 XawTextSelectType newType, *sarray;
2835 Widget src = ctx->text.source;
2836
2837 if (motion)
2838 newType = ctx->text.s.type;
2839 else {
2840 if ((abs((long) time - (long) ctx->text.lasttime) < MULTI_CLICK_TIME500L)
2841 && (pos >= ctx->text.s.left && pos <= ctx->text.s.right)) {
2842 sarray = ctx->text.sarray;
2843 for (; *sarray != XawselectNull && *sarray != ctx->text.s.type;
2844 sarray++)
2845 ;
2846 if (*sarray == XawselectNull)
2847 newType = *(ctx->text.sarray);
2848 else {
2849 newType = *(sarray + 1);
2850 if (newType == XawselectNull)
2851 newType = *(ctx->text.sarray);
2852 }
2853 }
2854 else /* single-click event */
2855 newType = *(ctx->text.sarray);
2856
2857 ctx->text.lasttime = time;
2858 }
2859 switch (newType) {
2860 case XawselectPosition:
2861 newLeft = newRight = pos;
2862 break;
2863 case XawselectChar:
2864 newLeft = pos;
2865 newRight = SrcScanXawTextSourceScan(src, pos, XawstPositions, XawsdRight, 1, False0);
2866 break;
2867 case XawselectWord:
2868 case XawselectParagraph:
2869 case XawselectAlphaNumeric: {
2870 XawTextScanType stype;
2871
2872 if (newType == XawselectWord)
2873 stype = XawstWhiteSpace;
2874 else if (newType == XawselectParagraph)
2875 stype = XawstParagraph;
2876 else
2877 stype = XawstAlphaNumeric;
2878
2879 /*
2880 * Somewhat complicated, but basically I treat the space between
2881 * two objects as another object. The object that I am currently
2882 * in then becomes the end of the selection.
2883 *
2884 * Chris Peterson - 4/19/90.
2885 */
2886 newRight = SrcScanXawTextSourceScan(ctx->text.source, pos, stype,
2887 XawsdRight, 1, False0);
2888 newRight = SrcScanXawTextSourceScan(ctx->text.source, newRight, stype,
2889 XawsdLeft, 1, False0);
2890
2891 if (pos != newRight)
2892 newLeft = SrcScanXawTextSourceScan(ctx->text.source, pos, stype,
2893 XawsdLeft, 1, False0);
2894 else
2895 newLeft = pos;
2896
2897 newLeft =SrcScanXawTextSourceScan(ctx->text.source, newLeft, stype,
2898 XawsdRight, 1, False0);
2899
2900 if (newLeft > newRight) {
2901 XawTextPosition temp = newLeft;
2902 newLeft = newRight;
2903 newRight = temp;
2904 }
2905 } break;
2906 case XawselectLine:
2907 newLeft = SrcScanXawTextSourceScan(src, pos, XawstEOL, XawsdLeft, 1, False0);
2908 newRight = SrcScanXawTextSourceScan(src, pos, XawstEOL, XawsdRight, 1, False0);
2909 break;
2910 case XawselectAll:
2911 newLeft = SrcScanXawTextSourceScan(src, pos, XawstAll, XawsdLeft, 1, False0);
2912 newRight = SrcScanXawTextSourceScan(src, pos, XawstAll, XawsdRight, 1, False0);
2913 break;
2914 default:
2915 XtAppWarning(XtWidgetToApplicationContext((Widget) ctx),
2916 "Text Widget: empty selection array.");
2917 return;
2918 }
2919
2920 if (newLeft != ctx->text.s.left || newRight != ctx->text.s.right
2921 || newType != ctx->text.s.type) {
2922 ModifySelection(ctx, newLeft, newRight);
2923 if (pos - ctx->text.s.left < ctx->text.s.right - pos)
2924 ctx->text.insertPos = newLeft;
2925 else
2926 ctx->text.insertPos = newRight;
2927 ctx->text.s.type = newType;
2928 }
2929 if (!motion) { /* setup so we can freely mix select extend calls*/
2930 ctx->text.origSel.type = ctx->text.s.type;
2931 ctx->text.origSel.left = ctx->text.s.left;
2932 ctx->text.origSel.right = ctx->text.s.right;
2933
2934 if (pos >= ctx->text.s.left + (ctx->text.s.right - ctx->text.s.left) / 2)
2935 ctx->text.extendDir = XawsdRight;
2936 else
2937 ctx->text.extendDir = XawsdLeft;
2938 }
2939}
2940
2941/*
2942 * This routine implements extension of the currently selected text in
2943 * the "current" mode (i.e. char word, line, etc.). It worries about
2944 * extending from either end of the selection and handles the case when you
2945 * cross through the "center" of the current selection (e.g. switch which
2946 * end you are extending!).
2947 */
2948static void
2949ExtendSelection(TextWidget ctx, XawTextPosition pos, Boolint motion)
2950{
2951 XawTextScanDirection dir;
2952
2953 if (!motion) { /* setup for extending selection */
2954 if (ctx->text.s.left == ctx->text.s.right) /* no current selection. */
2955 ctx->text.s.left = ctx->text.s.right = ctx->text.insertPos;
2956 else {
2957 ctx->text.origSel.left = ctx->text.s.left;
2958 ctx->text.origSel.right = ctx->text.s.right;
2959 }
2960
2961 ctx->text.origSel.type = ctx->text.s.type;
2962
2963 if (pos >= ctx->text.s.left + (ctx->text.s.right - ctx->text.s.left) / 2)
2964 ctx->text.extendDir = XawsdRight;
2965 else
2966 ctx->text.extendDir = XawsdLeft;
2967 }
2968 else /* check for change in extend direction */
2969 if ((ctx->text.extendDir == XawsdRight &&
2970 pos <= ctx->text.origSel.left) ||
2971 (ctx->text.extendDir == XawsdLeft &&
2972 pos >= ctx->text.origSel.right)) {
2973 ctx->text.extendDir = (ctx->text.extendDir == XawsdRight) ?
2974 XawsdLeft : XawsdRight;
2975 ModifySelection(ctx, ctx->text.origSel.left, ctx->text.origSel.right);
2976 }
2977
2978 dir = ctx->text.extendDir;
2979 switch (ctx->text.s.type) {
2980 case XawselectWord:
2981 case XawselectParagraph:
2982 case XawselectAlphaNumeric: {
2983 XawTextPosition left_pos, right_pos;
2984 XawTextScanType stype;
2985
2986 if (ctx->text.s.type == XawselectWord)
2987 stype = XawstWhiteSpace;
2988 else if (ctx->text.s.type == XawselectParagraph)
2989 stype = XawstParagraph;
2990 else
2991 stype = XawstAlphaNumeric;
2992
2993 /*
2994 * Somewhat complicated, but basically I treat the space between
2995 * two objects as another object. The object that I am currently
2996 * in then becomes the end of the selection.
2997 *
2998 * Chris Peterson - 4/19/90.
2999 */
3000 right_pos = SrcScanXawTextSourceScan(ctx->text.source, pos, stype,
3001 XawsdRight, 1, False0);
3002 right_pos =SrcScanXawTextSourceScan(ctx->text.source, right_pos, stype,
3003 XawsdLeft, 1, False0);
3004
3005 if (pos != right_pos)
3006 left_pos = SrcScanXawTextSourceScan(ctx->text.source, pos, stype,
3007 XawsdLeft, 1, False0);
3008 else
3009 left_pos = pos;
3010
3011 left_pos =SrcScanXawTextSourceScan(ctx->text.source, left_pos, stype,
3012 XawsdRight, 1, False0);
3013
3014 if (dir == XawsdLeft)
3015 pos = Min(left_pos, right_pos)(((left_pos) < (right_pos)) ? (left_pos) : (right_pos));
3016 else /* dir == XawsdRight */
3017 pos = Max(left_pos, right_pos)(((left_pos) > (right_pos)) ? (left_pos) : (right_pos));
3018 } break;
3019 case XawselectLine:
3020 pos = SrcScanXawTextSourceScan(ctx->text.source, pos, XawstEOL,
3021 dir, 1, dir == XawsdRight);
3022 break;
3023 case XawselectAll:
3024 pos = ctx->text.insertPos;
3025 /*FALLTHROUGH*/
3026 case XawselectPosition:
3027 default:
3028 break;
3029 }
3030
3031 if (dir == XawsdRight)
3032 ModifySelection(ctx, ctx->text.s.left, pos);
3033 else
3034 ModifySelection(ctx, pos, ctx->text.s.right);
3035
3036 ctx->text.insertPos = pos;
3037}
3038
3039/*
3040 * Function:
3041 * _XawTextClearAndCenterDisplay
3042 *
3043 * Parameters:
3044 * ctx - text widget
3045 *
3046 * Description:
3047 * Redraws the display with the cursor in insert point
3048 * centered vertically.
3049 */
3050void
3051_XawTextClearAndCenterDisplay(TextWidget ctx)
3052{
3053 int left_margin = ctx->text.left_margin;
3054 Boolint visible = IsPositionVisible(ctx, ctx->text.insertPos)(ctx->text.insertPos >= ctx->text.lt.info[0].position
&& ctx->text.insertPos < ctx->text.lt.info[
ctx->text.lt.lines].position)
;
3055
3056 _XawTextShowPosition(ctx);
3057
3058 if (XtIsRealized((Widget)ctx)(XtWindowOfObject((Widget)ctx) != 0L) && visible &&
3059 left_margin == ctx->text.left_margin) {
3060 int insert_line = LineForPosition(ctx, ctx->text.insertPos);
3061 int scroll_by = insert_line - (ctx->text.lt.lines >> 1);
3062 Boolean clear_to_eol = ctx->text.clear_to_eol;
3063
3064 XawTextScroll(ctx, scroll_by, 0);
3065 SinkClearToBG_XawTextSinkClearToBackground(ctx->text.sink, 0, 0, XtWidth(ctx)(((RectObj)ctx)->rectangle.width), XtHeight(ctx)(((RectObj)ctx)->rectangle.height));
3066 ClearWindow(ctx)_XawTextNeedsUpdating((ctx), (ctx)->text.lt.top, (ctx)->
text.lt.info[ctx->text.lt.lines].position)
;
3067 clear_to_eol = ctx->text.clear_to_eol;
3068 ctx->text.clear_to_eol = False0;
3069 FlushUpdate(ctx);
3070 ctx->text.clear_to_eol = clear_to_eol;
3071 }
3072}
3073
3074/*
3075 * Internal redisplay entire window
3076 * Legal to call only if widget is realized
3077 */
3078static void
3079DisplayTextWindow(Widget w)
3080{
3081 TextWidget ctx = (TextWidget)w;
3082
3083 _XawTextBuildLineTable(ctx, ctx->text.lt.top, False0);
3084 ClearWindow(ctx)_XawTextNeedsUpdating((ctx), (ctx)->text.lt.top, (ctx)->
text.lt.info[ctx->text.lt.lines].position)
;
3085}
3086
3087static void
3088TextSinkResize(Widget w)
3089{
3090 if (w && XtClass(w)((w)->core.widget_class)->core_class.resize)
3091 XtClass(w)((w)->core.widget_class)->core_class.resize(w);
3092}
3093
3094/* ARGSUSED */
3095void
3096_XawTextCheckResize(TextWidget ctx)
3097{
3098 return;
3099}
3100
3101/*
3102 * Converts (params, num_params) to a list of atoms & caches the
3103 * list in the TextWidget instance.
3104 */
3105Atom *
3106_XawTextSelectionList(TextWidget ctx, String *list, Cardinal nelems)
3107{
3108 Atom *sel = ctx->text.s.selections;
3109 Display *dpy = XtDisplay((Widget)ctx)((((Widget)ctx)->core.screen)->display);
3110 int n;
3111
3112 if (nelems > (Cardinal)ctx->text.s.array_size) {
3113 sel = (Atom *)XtRealloc((char *)sel, sizeof(Atom) * nelems);
3114 ctx->text.s.array_size = nelems;
3115 ctx->text.s.selections = sel;
3116 }
3117 for (n = nelems; --n >= 0; sel++, list++)
3118 *sel = XInternAtom(dpy, *list, False0);
3119 ctx->text.s.atom_count = nelems;
3120
3121 return (ctx->text.s.selections);
3122}
3123
3124/*
3125 * Function:
3126 * SetSelection
3127 *
3128 * Parameters:
3129 * ctx - text widget
3130 * defaultSel - default selection
3131 * l - left and right ends of the selection
3132 * r - ""
3133 * list - the selection list (as strings).
3134 * nelems - ""
3135 *
3136 * Description:
3137 * Sets the current selection.
3138 *
3139 * Note:
3140 * if (ctx->text.s.left >= ctx->text.s.right) then the selection is unset
3141 */
3142void
3143_XawTextSetSelection(TextWidget ctx, XawTextPosition l, XawTextPosition r,
3144 String *list, Cardinal nelems)
3145{
3146 if (nelems == 1 && !strcmp (list[0], "none"))
3147 return;
3148 if (nelems == 0) {
3149 static String defaultSel = "PRIMARY";
3150 list = &defaultSel;
3151 nelems = 1;
3152 }
3153 _SetSelection(ctx, l, r, _XawTextSelectionList(ctx, list, nelems), nelems);
3154}
3155
3156/*
3157 * Function:
3158 * ModifySelection
3159 *
3160 * Parameters:
3161 * ctx - text widget
3162 * left - left and right ends of the selection
3163 * right - ""
3164 *
3165 * Description:
3166 * Modifies the current selection.
3167 *
3168 * Note:
3169 * if (ctx->text.s.left >= ctx->text.s.right) then the selection is unset
3170 */
3171static void
3172ModifySelection(TextWidget ctx, XawTextPosition left, XawTextPosition right)
3173{
3174 if (left == right)
3175 ctx->text.insertPos = left;
3176 _SetSelection(ctx, left, right, NULL((void*)0), 0);
3177}
3178
3179/*
3180 * This routine is used to perform various selection functions. The goal is
3181 * to be able to specify all the more popular forms of draw-through and
3182 * multi-click selection user interfaces from the outside.
3183 */
3184void
3185_XawTextAlterSelection(TextWidget ctx, XawTextSelectionMode mode,
3186 XawTextSelectionAction action, String *params,
3187 Cardinal *num_params)
3188{
3189 XawTextPosition position;
3190 Boolean flag;
3191
3192 /*
3193 * This flag is used by TextPop.c:DoReplace() to determine if the selection
3194 * is okay to use, or if it has been modified.
3195 */
3196 if (ctx->text.search != NULL((void*)0))
3197 ctx->text.search->selection_changed = True1;
3198
3199 position = PositionForXY(ctx, (int) ctx->text.ev_x, (int) ctx->text.ev_y);
3200
3201 flag = (action != XawactionStart);
3202 if (mode == XawsmTextSelect)
3203 DoSelection(ctx, position, ctx->text.time, flag);
3204 else /* mode == XawsmTextExtend */
3205 ExtendSelection (ctx, position, flag);
3206
3207 if (action == XawactionEnd)
3208 _XawTextSetSelection(ctx, ctx->text.s.left, ctx->text.s.right,
3209 params, *num_params);
3210}
3211
3212/*
3213 * Function:
3214 * UpdateTextInRectangle
3215 *
3216 * Parameters:
3217 * ctx - the text widget
3218 * rect - rectangle
3219 *
3220 * Description:
3221 * Updates the text in the given rectangle
3222 */
3223static void
3224UpdateTextInRectangle(TextWidget ctx, XRectangle *rect)
3225{
3226 XawTextLineTable *lt;
3227 int line, y1, y2, x2;
3228
3229 y1 = rect->y;
3230 y2 = y1 + rect->height;
3231 x2 = rect->x + rect->width;
3232
3233 for (line = 0, lt = &ctx->text.lt; line < lt->lines; line++)
3234 if (lt->info[line + 1].y > y1)
3235 break;
3236 for (; line <= lt->lines; line++) {
3237 if (lt->info[line].y > y2)
3238 break;
3239 UpdateTextInLine(ctx, line, rect->x, x2);
3240 }
3241}
3242
3243/*
3244 * This routine processes all "expose region" XEvents. In general, its job
3245 * is to the best job at minimal re-paint of the text, displayed in the
3246 * window, that it can.
3247 */
3248/* ARGSUSED */
3249static void
3250XawTextExpose(Widget w, XEvent *event, Region region)
3251{
3252 TextWidget ctx = (TextWidget)w;
3253 Boolean clear_to_eol;
3254 XRectangle expose;
3255
3256 if (event->type == Expose12) {
3257 expose.x = event->xexpose.x;
3258 expose.y = event->xexpose.y;
3259 expose.width = event->xexpose.width;
3260 expose.height = event->xexpose.height;
3261 }
3262 else if (event->type == GraphicsExpose13) {
3263 expose.x = event->xgraphicsexpose.x;
3264 expose.y = event->xgraphicsexpose.y;
3265 expose.width = event->xgraphicsexpose.width;
3266 expose.height = event->xgraphicsexpose.height;
3267 }
3268 else
3269 return;
3270
3271 _XawTextPrepareToUpdate(ctx);
3272
3273 if (Superclass(&simpleClassRec)->core_class.expose)
3274 (*Superclass(&simpleClassRec)->core_class.expose)(w, event, region);
3275
3276 clear_to_eol = ctx->text.clear_to_eol;
3277 ctx->text.clear_to_eol = False0;
3278
3279 UpdateTextInRectangle(ctx, &expose);
3280 XawTextSinkGetCursorBounds(ctx->text.sink, &expose);
3281 UpdateTextInRectangle(ctx, &expose);
3282 SinkClearToBG_XawTextSinkClearToBackground(ctx->text.sink, expose.x, expose.y,
3283 expose.width, expose.height);
3284 _XawTextExecuteUpdate(ctx);
3285 ctx->text.clear_to_eol = clear_to_eol;
3286}
3287
3288/*
3289 * This routine does all setup required to syncronize batched screen updates
3290 */
3291void
3292_XawTextPrepareToUpdate(TextWidget ctx)
3293{
3294 if (ctx->text.old_insert < 0) {
3295 InsertCursor((Widget)ctx, XawisOff);
3296 ctx->text.showposition = False0;
3297 ctx->text.old_insert = ctx->text.insertPos;
3298 ctx->text.clear_to_eol = False0;
3299#ifndef OLDXAW1
3300 ctx->text.source_changed = SRC_CHANGE_NONE0;
3301#endif
3302 }
3303}
3304
3305/*
3306 * This is a private utility routine used by _XawTextExecuteUpdate. It
3307 * processes all the outstanding update requests and merges update
3308 * ranges where possible.
3309 */
3310static void
3311FlushUpdate(TextWidget ctx)
3312{
3313 XmuSegment *seg;
3314 void (*display_text)(Widget, XawTextPosition, XawTextPosition);
3315
3316 if (XtIsRealized((Widget)ctx)(XtWindowOfObject((Widget)ctx) != 0L)) {
3317 ctx->text.s.right = XawMin(ctx->text.s.right, ctx->text.lastPos)((ctx->text.s.right) < (ctx->text.lastPos) ? (ctx->
text.s.right) : (ctx->text.lastPos))
;
3318 ctx->text.s.left = XawMin(ctx->text.s.left, ctx->text.s.right)((ctx->text.s.left) < (ctx->text.s.right) ? (ctx->
text.s.left) : (ctx->text.s.right))
;
3319
3320#ifndef OLDXAW1
3321 if (XawTextSinkBeginPaint(ctx->text.sink) == False0)
3322#endif
3323 display_text = OldDisplayText;
3324#ifndef OLDXAW1
3325 else
3326 display_text = DisplayText;
3327#endif
3328 for (seg = ctx->text.update->segment; seg; seg = seg->next)
3329 (*display_text)((Widget)ctx,
3330 (XawTextPosition)seg->x1,
3331 (XawTextPosition)seg->x2);
3332#ifndef OLDXAW1
3333 if (display_text != OldDisplayText) {
3334 XawTextSinkDoPaint(ctx->text.sink);
3335 XawTextSinkEndPaint(ctx->text.sink);
3336 }
3337#endif
3338 }
3339 (void)XmuScanlineXor(ctx->text.update, ctx->text.update);
3340}
3341
3342static int
3343CountLines(TextWidget ctx, XawTextPosition left, XawTextPosition right)
3344{
3345 if (ctx->text.wrap == XawtextWrapNever || left >= right)
3346 return (1);
3347 else {
3348 XawTextPosition tmp;
3349 int dim, lines = 0, wwidth = GetMaxTextWidth(ctx);
3350
3351 while (left < right) {
3352 tmp = left;
3353 XawTextSinkFindPosition(ctx->text.sink, left,
3354 ctx->text.left_margin,
3355 wwidth, ctx->text.wrap == XawtextWrapWord,
3356 &left, &dim, &dim);
3357 ++lines;
3358 if (tmp == left)
3359 ++left;
3360 }
3361
3362 return (lines);
3363 }
3364 /*NOTREACHED*/
3365}
3366
3367static int
3368GetMaxTextWidth(TextWidget ctx)
3369{
3370 XRectangle cursor;
3371 int width;
3372
3373 XawTextSinkGetCursorBounds(ctx->text.sink, &cursor);
3374 width = (int)XtWidth(ctx)(((RectObj)ctx)->rectangle.width) - RHMargins(ctx)((ctx)->text.r_margin.left + (ctx)->text.r_margin.right
)
- cursor.width;
3375
3376 return (XawMax(0, width)((0) > (width) ? (0) : (width)));
3377}
3378
3379/*
3380 * Function:
3381 * _XawTextShowPosition
3382 *
3383 * Parameters:
3384 * ctx - the text widget to show the position
3385 *
3386 * Description:
3387 * Makes sure the text cursor visible, scrolling the text window
3388 * if required.
3389 */
3390void
3391_XawTextShowPosition(TextWidget ctx)
3392{
3393 /*
3394 * Variable scroll is used to avoid scanning large files to calculate
3395 * line offsets
3396 */
3397 int hpixels, vlines;
3398 XawTextPosition first, last, top, tmp;
3399 Boolint visible, scroll;
3400
3401 if (!XtIsRealized((Widget)ctx)(XtWindowOfObject((Widget)ctx) != 0L))
3402 return;
3403
3404 /*
3405 * Checks if a horizontal scroll is required
3406 */
3407 if (ctx->text.wrap == XawtextWrapNever) {
3408 int x, vwidth, distance, dim;
3409 XRectangle rect;
3410
3411 vwidth = (int)XtWidth(ctx)(((RectObj)ctx)->rectangle.width) - RHMargins(ctx)((ctx)->text.r_margin.left + (ctx)->text.r_margin.right
)
;
3412 last = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.insertPos,
3413 XawstEOL, XawsdLeft, 1, False0);
3414 XawTextSinkFindDistance(ctx->text.sink, last,
3415 ctx->text.left_margin,
3416 ctx->text.insertPos,
3417 &distance, &first, &dim);
3418 XawTextSinkGetCursorBounds(ctx->text.sink, &rect);
3419 x = ctx->text.left_margin - ctx->text.r_margin.left;
3420
3421 if (x + distance + rect.width > vwidth)
3422 hpixels = x + distance + rect.width - vwidth + (vwidth >> 2);
3423 else if (x + distance < 0)
3424 hpixels = x + distance - (vwidth >> 2);
3425 else
3426 hpixels = 0;
3427 }
3428 else
3429 hpixels = 0;
3430
3431 visible = IsPositionVisible(ctx, ctx->text.insertPos)(ctx->text.insertPos >= ctx->text.lt.info[0].position
&& ctx->text.insertPos < ctx->text.lt.info[
ctx->text.lt.lines].position)
;
3432
3433 /*
3434 * If the cursor is already visible
3435 */
3436 if (!hpixels && visible)
3437 return;
3438
3439 scroll = ctx->core.background_pixmap == XtUnspecifiedPixmap((Pixmap)2) && !hpixels;
3440 vlines = 0;
3441 first = ctx->text.lt.top;
3442
3443 /*
3444 * Needs to scroll the text window
3445 */
3446 if (visible)
3447 top = ctx->text.lt.top;
3448 else {
3449 top = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.insertPos,
3450 XawstEOL, XawsdLeft, 1, False0);
3451
3452 /*
3453 * Finds the nearest left position from ctx->text.insertPos
3454 */
3455 if (ctx->text.wrap != XawtextWrapNever) {
3456 int dim, vwidth = GetMaxTextWidth(ctx);
3457
3458 last = top;
3459 /*CONSTCOND*/
3460 while (1) {
3461 tmp = last;
3462 XawTextSinkFindPosition(ctx->text.sink, last,
3463 ctx->text.left_margin, vwidth,
3464 ctx->text.wrap == XawtextWrapWord,
3465 &last, &dim, &dim);
3466 if (last == tmp)
3467 ++last;
3468 if (last <= ctx->text.insertPos)
3469 top = last;
3470 else
3471 break;
3472 }
3473 }
3474 }
3475
3476 if (scroll) {
3477 if (ctx->text.insertPos < first) { /* Scroll Down */
3478 while (first > top) {
3479 last = first;
3480 first = SrcScanXawTextSourceScan(ctx->text.source, first,
3481 XawstEOL, XawsdLeft, 2, False0);
3482 vlines -= CountLines(ctx, first, last);
3483 if (-vlines >= ctx->text.lt.lines) {
3484 scroll = False0;
3485 break;
3486 }
3487 }
3488 }
3489 else if (!visible) { /* Scroll Up */
3490 while (first < top) {
3491 last = first;
3492 first = SrcScanXawTextSourceScan(ctx->text.source, first,
3493 XawstEOL, XawsdRight, 1, True1);
3494 vlines += CountLines(ctx, last, first);
3495 if (vlines > ctx->text.lt.lines) {
3496 scroll = False0;
3497 break;
3498 }
3499 }
3500 }
3501 else
3502 scroll = False0;
3503 }
3504
3505 /*
3506 * If a portion of the text that will be scrolled is visible
3507 */
3508 if (scroll)
3509 XawTextScroll(ctx, vlines ? vlines - (ctx->text.lt.lines >> 1) : 0, 0);
3510 /*
3511 * Else redraw the entire text window
3512 */
3513 else {
3514 ctx->text.left_margin -= hpixels;
3515 if (ctx->text.left_margin > ctx->text.r_margin.left)
3516 ctx->text.left_margin = ctx->text.margin.left =
3517 ctx->text.r_margin.left;
3518
3519 if (!visible) {
3520 vlines = ctx->text.lt.lines >> 1;
3521 if (vlines)
3522 top = SrcScanXawTextSourceScan(ctx->text.source, ctx->text.insertPos,
3523 XawstEOL, XawsdLeft, vlines + 1, False0);
3524
3525 if (ctx->text.wrap != XawtextWrapNever) {
3526 int dim;
3527 int n_lines = CountLines(ctx, top, ctx->text.insertPos);
3528 int vwidth = GetMaxTextWidth(ctx);
3529
3530 while (n_lines-- > vlines) {
3531 tmp = top;
3532 XawTextSinkFindPosition(ctx->text.sink, top,
3533 ctx->text.left_margin,
3534 vwidth,
3535 ctx->text.wrap == XawtextWrapWord,
3536 &top, &dim, &dim);
3537 if (tmp == top)
3538 ++top;
3539 }
3540 }
3541 _XawTextBuildLineTable(ctx, top, True1);
3542 }
3543 else
3544 ClearWindow(ctx)_XawTextNeedsUpdating((ctx), (ctx)->text.lt.top, (ctx)->
text.lt.info[ctx->text.lt.lines].position)
;
3545 }
3546 ctx->text.clear_to_eol = True1;
3547}
3548
3549#ifndef OLDXAW1
3550static int
3551ResolveLineNumber(TextWidget ctx)
3552{
3553 int line_number = ctx->text.lt.base_line;
3554 XawTextPosition position = ctx->text.lt.top;
3555
3556 if (ctx->text.lt.base_line < 1)
3557 return (ctx->text.line_number);
3558
3559 if (ctx->text.wrap == XawtextWrapNever
3560 && IsPositionVisible(ctx, ctx->text.insertPos)(ctx->text.insertPos >= ctx->text.lt.info[0].position
&& ctx->text.insertPos < ctx->text.lt.info[
ctx->text.lt.lines].position)
)
3561 line_number += LineForPosition(ctx, ctx->text.insertPos);
3562 else if (position < ctx->text.insertPos) {
3563 while (position < ctx->text.insertPos) {
3564 position = SrcScanXawTextSourceScan(ctx->text.source, position,
3565 XawstEOL, XawsdRight, 1, True1);
3566 if (position <= ctx->text.insertPos) {
3567 ++line_number;
3568 if (position == ctx->text.lastPos) {
3569 line_number -= !_XawTextSourceNewLineAtEOF(ctx->text.source);
3570 break;
3571 }
3572 }
3573 }
3574 }
3575 else if (position > ctx->text.insertPos) {
3576 while (position > ctx->text.insertPos) {
3577 position = SrcScanXawTextSourceScan(ctx->text.source, position,
3578 XawstEOL, XawsdLeft, 1, False0);
3579 if (--position >= ctx->text.insertPos)
3580 --line_number;
3581 }
3582 }
3583
3584 return (line_number);
3585}
3586#endif
3587
3588/*
3589 * This routine causes all batched screen updates to be performed
3590 */
3591void
3592_XawTextExecuteUpdate(TextWidget ctx)
3593{
3594 if (ctx->text.update_disabled || ctx->text.old_insert < 0)
3595 return;
3596
3597 if(ctx->text.old_insert != ctx->text.insertPos || ctx->text.showposition)
3598 _XawTextShowPosition(ctx);
3599
3600 FlushUpdate(ctx);
3601 InsertCursor((Widget)ctx, XawisOn);
3602 ctx->text.old_insert = -1;
3603#ifndef OLDXAW1
3604 _XawTextSetLineAndColumnNumber(ctx, False0);
3605#endif
3606}
3607
3608static void
3609XawTextDestroy(Widget w)
3610{
3611 TextWidget ctx = (TextWidget)w;
3612
3613 DestroyHScrollBar(ctx);
3614 DestroyVScrollBar(ctx);
3615
3616 XtFree((char *)ctx->text.s.selections);
3617 XtFree((char *)ctx->text.lt.info);
3618 XtFree((char *)ctx->text.search);
3619 XmuDestroyScanline(ctx->text.update)do { XmuDestroySegmentList((ctx->text.update)->segment)
; XtFree((char*)(ctx->text.update)); } while (0)
;
3620 XtReleaseGC((Widget)ctx, ctx->text.gc);
3621}
3622
3623/*
3624 * by the time we are managed (and get this far) we had better
3625 * have both a source and a sink
3626 */
3627static void
3628XawTextResize(Widget w)
3629{
3630 TextWidget ctx = (TextWidget)w;
3631
3632 PositionVScrollBar(ctx);
3633 PositionHScrollBar(ctx);
3634 TextSinkResize(ctx->text.sink);
3635
3636 ctx->text.showposition = True1;
3637 _XawTextBuildLineTable(ctx, ctx->text.lt.top, True1);
3638}
3639
3640/*
3641 * This routine allow the application program to Set attributes.
3642 */
3643/*ARGSUSED*/
3644static Boolean
3645XawTextSetValues(Widget current, Widget request, Widget cnew,
3646 ArgList args, Cardinal *num_args)
3647{
3648 TextWidget oldtw = (TextWidget)current;
3649 TextWidget newtw = (TextWidget)cnew;
3650 Boolean redisplay = False0;
3651 Boolean display_caret = newtw->text.display_caret;
3652#ifndef OLDXAW1
3653 Boolean show_lc = False0;
3654#endif
3655
3656 newtw->text.display_caret = oldtw->text.display_caret;
3657 _XawTextPrepareToUpdate(newtw);
3658 newtw->text.display_caret = display_caret;
3659
3660 if (oldtw->text.r_margin.left != newtw->text.r_margin.left) {
3661 newtw->text.left_margin = newtw->text.margin.left =
3662 newtw->text.r_margin.left;
3663 if (newtw->text.vbar != NULL((void*)0)) {
3664 newtw->text.left_margin += XtWidth(newtw->text.vbar)(((RectObj)newtw->text.vbar)->rectangle.width) +
3665 XtBorderWidth(newtw->text.vbar)(((RectObj)newtw->text.vbar)->rectangle.border_width);
3666 }
3667 redisplay = True1;
3668 }
3669
3670 if (oldtw->text.scroll_vert != newtw->text.scroll_vert) {
3671 if (newtw->text.scroll_vert == XawtextScrollAlways)
3672 CreateVScrollBar(newtw);
3673 else
3674 DestroyVScrollBar(newtw);
3675
3676 redisplay = True1;
3677 }
3678
3679 if (oldtw->text.r_margin.bottom != newtw->text.r_margin.bottom) {
3680 newtw->text.margin.bottom = newtw->text.r_margin.bottom;
3681 if (newtw->text.hbar != NULL((void*)0))
3682 newtw->text.margin.bottom += newtw->text.hbar->core.height +
3683 newtw->text.hbar->core.border_width;
3684 redisplay = True1;
3685 }
3686
3687 if (oldtw->text.scroll_horiz != newtw->text.scroll_horiz) {
3688 if (newtw->text.scroll_horiz == XawtextScrollAlways)
3689 CreateHScrollBar(newtw);
3690 else
3691 DestroyHScrollBar(newtw);
3692
3693 redisplay = True1;
3694 }
3695
3696 if (oldtw->text.source != newtw->text.source) {
3697#ifndef OLDXAW1
3698 show_lc = True1;
3699 _XawSourceRemoveText(oldtw->text.source, cnew,
3700 oldtw->text.source &&
3701 XtParent(oldtw->text.source)((oldtw->text.source)->core.parent) == cnew);
3702 _XawSourceAddText(newtw->text.source, cnew);
3703#endif
3704 _XawTextSetSource((Widget)newtw, newtw->text.source, newtw->text.lt.top,
3705 newtw->text.insertPos);
3706 }
3707
3708 newtw->text.redisplay_needed = False0;
3709 XtSetValues((Widget)newtw->text.source, args, *num_args);
3710 XtSetValues((Widget)newtw->text.sink, args, *num_args);
3711
3712 if (oldtw->text.wrap != newtw->text.wrap
3713 || oldtw->text.lt.top != newtw->text.lt.top
3714 || oldtw->text.insertPos != newtw->text.insertPos
3715 || oldtw->text.r_margin.right != newtw->text.r_margin.right
3716 || oldtw->text.r_margin.top != newtw->text.r_margin.top
3717 || oldtw->text.sink != newtw->text.sink
3718 || newtw->text.redisplay_needed) {
3719 if (oldtw->text.wrap != newtw->text.wrap) {
3720 newtw->text.left_margin = newtw->text.margin.left =
3721 newtw->text.r_margin.left;
3722 if (oldtw->text.lt.top == newtw->text.lt.top)
3723 newtw->text.lt.top = SrcScanXawTextSourceScan(newtw->text.source, 0, XawstEOL,
3724 XawsdLeft, 1, False0);
3725 }
3726 newtw->text.showposition = True1;
3727#ifndef OLDXAW1
3728 show_lc = True1;
3729 newtw->text.source_changed = SRC_CHANGE_OVERLAP3;
3730#endif
3731 _XawTextBuildLineTable(newtw, newtw->text.lt.top, True1);
3732 redisplay = True1;
3733 }
3734
3735#ifndef OLDXAW1
3736 if (newtw->text.left_column < 0)
3737 newtw->text.left_column = 0;
3738 if (newtw->text.right_column < 0)
3739 newtw->text.right_column = 0;
3740#endif
3741
3742 _XawTextExecuteUpdate(newtw);
3743
3744#ifndef OLDXAW1
3745 if (show_lc)
3746 _XawTextSetLineAndColumnNumber(newtw, True1);
3747#endif
3748
3749 if (redisplay)
3750 _XawTextSetScrollBars(newtw);
3751
3752 return (redisplay);
3753}
3754
3755/* invoked by the Simple widget's SetValues */
3756static Boolint
3757XawTextChangeSensitive(Widget w)
3758{
3759 Arg args[1];
3760 TextWidget tw = (TextWidget)w;
3761
3762 (*(&simpleClassRec)->simple_class.change_sensitive)(w);
3763
3764 XtSetArg(args[0], XtNancestorSensitive,((void)( (args[0]).name = (((char*)&XtStrings[34])), (args
[0]).value = (XtArgVal)((tw->core.ancestor_sensitive &&
tw->core.sensitive)) ))
3765 (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)) ))
;
3766 if (tw->text.vbar)
3767 XtSetValues(tw->text.vbar, args, ONE((Cardinal)1));
3768 if (tw->text.hbar)
3769 XtSetValues(tw->text.hbar, args, ONE((Cardinal)1));
3770 return (False0);
3771}
3772
3773/*
3774 * Function:
3775 * XawTextGetValuesHook
3776 *
3777 * Parameters:
3778 * w - Text Widget
3779 * args - argument list
3780 * num_args - number of args
3781 *
3782 * Description:
3783 * This is a get values hook routine that gets the
3784 * values in the text source and sink.
3785 */
3786static void
3787XawTextGetValuesHook(Widget w, ArgList args, Cardinal *num_args)
3788{
3789 XtGetValues(((TextWidget)w)->text.source, args, *num_args);
3790 XtGetValues(((TextWidget)w)->text.sink, args, *num_args);
3791}
3792
3793/*
3794 * Function:
3795 * FindGoodPosition
3796 *
3797 * Parameters:
3798 * pos - any position
3799 *
3800 * Description:
3801 * Returns a valid position given any postition.
3802 *
3803 * Returns:
3804 * A position between (0 and lastPos)
3805 */
3806static XawTextPosition
3807FindGoodPosition(TextWidget ctx, XawTextPosition pos)
3808{
3809 if (pos < 0)
3810 return (0);
3811 return (((pos > ctx->text.lastPos) ? ctx->text.lastPos : pos));
3812}
3813
3814/* Li wrote this so the IM can find a given text position's screen position */
3815void
3816_XawTextPosToXY(Widget w, XawTextPosition pos, Position *x, Position *y)
3817{
3818 int line, ix, iy;
3819
3820 LineAndXYForPosition((TextWidget)w, pos, &line, &ix, &iy);
3821 *x = ix;
3822 *y = iy;
3823}
3824
3825/*******************************************************************
3826The following routines provide procedural interfaces to Text window state
3827setting and getting. They need to be redone so than the args code can use
3828them. I suggest we create a complete set that takes the context as an
3829argument and then have the public version lookup the context and call the
3830internal one. The major value of this set is that they have actual application
3831clients and therefore the functionality provided is required for any future
3832version of Text.
3833********************************************************************/
3834void
3835XawTextDisplay(Widget w)
3836{
3837 TextWidget ctx = (TextWidget)w;
3838
3839 if (!XtIsRealized(w)(XtWindowOfObject(w) != 0L))
3840 return;
3841
3842 _XawTextPrepareToUpdate(ctx);
3843 ctx->text.clear_to_eol = True1;
3844 DisplayTextWindow(w);
3845 _XawTextExecuteUpdate(ctx);
3846}
3847
3848void
3849XawTextSetSelectionArray(Widget w, XawTextSelectType *sarray)
3850{
3851 ((TextWidget)w)->text.sarray = sarray;
3852}
3853
3854void
3855XawTextGetSelectionPos(Widget w, XawTextPosition *left, XawTextPosition *right)
3856{
3857 *left = ((TextWidget)w)->text.s.left;
3858 *right = ((TextWidget)w)->text.s.right;
3859}
3860
3861void
3862_XawTextSetSource(Widget w, Widget source,
3863 XawTextPosition top, XawTextPosition startPos)
3864{
3865 TextWidget ctx = (TextWidget)w;
3866#ifndef OLDXAW1
3867 Boolint resolve = False0;
3868#endif
3869
3870#ifndef OLDXAW1
3871 if (source != ctx->text.source)
3872 _XawSourceRemoveText(ctx->text.source, w, ctx->text.source &&
3873 XtParent(ctx->text.source)((ctx->text.source)->core.parent) == w);
3874 _XawSourceAddText(source, w);
3875
3876 if (source != ctx->text.source || ctx->text.insertPos != startPos)
3877 resolve = True1;
3878
3879 ctx->text.source_changed = SRC_CHANGE_OVERLAP3;
3880#endif
3881 ctx->text.source = source;
3882 ctx->text.s.left = ctx->text.s.right = 0;
3883 ctx->text.lastPos = GETLASTPOSXawTextSourceScan((ctx)->text.source, 0, XawstAll, XawsdRight
, 1, 1)
;
3884 top = FindGoodPosition(ctx, top);
3885 startPos = FindGoodPosition(ctx, startPos);
3886 ctx->text.insertPos = ctx->text.old_insert = startPos;
3887 _XawTextPrepareToUpdate(ctx);
3888
3889 _XawTextBuildLineTable(ctx, top, True1);
3890
3891 _XawTextExecuteUpdate(ctx);
3892#ifndef OLDXAW1
3893 if (resolve)
3894 _XawTextSetLineAndColumnNumber(ctx, True1);
3895#endif
3896}
3897
3898void
3899XawTextSetSource(Widget w, Widget source, XawTextPosition top)
3900{
3901 _XawTextSetSource(w, source, top, top);
3902}
3903
3904/*
3905 * This public routine deletes the text from startPos to endPos in a source and
3906 * then inserts, at startPos, the text that was passed. As a side effect it
3907 * "invalidates" that portion of the displayed text (if any), so that things
3908 * will be repainted properly.
3909 */
3910int
3911XawTextReplace(Widget w, XawTextPosition startPos, XawTextPosition endPos,
3912 XawTextBlock *text)
3913{
3914 TextWidget ctx = (TextWidget)w;
3915 int result;
3916#ifndef OLDXAW1
3917 Cardinal i;
3918 TextSrcObject src = (TextSrcObject)ctx->text.source;
3919
3920 for (i = 0; i < src->textSrc.num_text; i++)
3921 _XawTextPrepareToUpdate((TextWidget)src->textSrc.text[i]);
3922#else
3923 _XawTextPrepareToUpdate(ctx);
3924#endif
3925
3926 endPos = FindGoodPosition(ctx, endPos);
3927 startPos = FindGoodPosition(ctx, startPos);
3928 result = _XawTextReplace(ctx, startPos, endPos, text);
3929
3930#ifndef OLDXAW1
3931 for (i = 0; i < src->textSrc.num_text; i++)
3932 _XawTextExecuteUpdate((TextWidget)src->textSrc.text[i]);
3933#else
3934 _XawTextExecuteUpdate(ctx);
3935#endif
3936
3937 return (result);
3938}
3939
3940XawTextPosition
3941XawTextTopPosition(Widget w)
3942{
3943 return (((TextWidget)w)->text.lt.top);
3944}
3945
3946XawTextPosition
3947XawTextLastPosition(Widget w)
3948{
3949 return (((TextWidget)w)->text.lastPos);
3950}
3951
3952void
3953XawTextSetInsertionPoint(Widget w, XawTextPosition position)
3954{
3955 TextWidget ctx = (TextWidget)w;
3956
3957 _XawTextPrepareToUpdate(ctx);
3958 ctx->text.insertPos = FindGoodPosition(ctx, position);
3959 ctx->text.showposition = True1;
3960 ctx->text.from_left = -1;
3961
3962 _XawTextExecuteUpdate(ctx);
3963#ifndef OLDXAW1
3964 _XawTextSetLineAndColumnNumber(ctx, False0);
3965#endif
3966}
3967
3968XawTextPosition
3969XawTextGetInsertionPoint(Widget w)
3970{
3971 return (((TextWidget)w)->text.insertPos);
3972}
3973
3974/*
3975 * Note: Must walk the selection list in opposite order from TextLoseSelection
3976 */
3977void
3978XawTextUnsetSelection(Widget w)
3979{
3980 TextWidget ctx = (TextWidget)w;
3981
3982 while (ctx->text.s.atom_count != 0) {
3983 Atom sel = ctx->text.s.selections[ctx->text.s.atom_count - 1];
3984
3985 if (sel != (Atom) 0) {
3986 /*
3987 * As selections are lost the atom_count will decrement
3988 */
3989 if (GetCutBufferNumber(sel) == NOT_A_CUT_BUFFER-1)
3990 XtDisownSelection(w, sel, ctx->text.time);
3991 TextLoseSelection(w, &sel); /* In case this is a cut buffer, or
3992 XtDisownSelection failed to call us */
3993 }
3994 }
3995}
3996
3997void
3998XawTextSetSelection(Widget w, XawTextPosition left, XawTextPosition right)
3999{
4000 TextWidget ctx = (TextWidget)w;
4001
4002 _XawTextPrepareToUpdate(ctx);
4003 _XawTextSetSelection(ctx, FindGoodPosition(ctx, left),
4004 FindGoodPosition(ctx, right), NULL((void*)0), 0);
4005 _XawTextExecuteUpdate(ctx);
4006}
4007
4008void
4009XawTextInvalidate(Widget w, XawTextPosition from, XawTextPosition to)
4010{
4011 TextWidget ctx = (TextWidget)w;
4012
4013 from = FindGoodPosition(ctx, from);
4014 to = FindGoodPosition(ctx, to);
4015 ctx->text.lastPos = GETLASTPOSXawTextSourceScan((ctx)->text.source, 0, XawstAll, XawsdRight
, 1, 1)
;
4016 _XawTextPrepareToUpdate(ctx);
4017 _XawTextNeedsUpdating(ctx, from, to);
4018 _XawTextExecuteUpdate(ctx);
4019}
4020
4021/*ARGSUSED*/
4022void
4023XawTextDisableRedisplay(Widget w)
4024{
4025 ((TextWidget)w)->text.update_disabled = True1;
4026 _XawTextPrepareToUpdate((TextWidget)w);
4027}
4028
4029void
4030XawTextEnableRedisplay(Widget w)
4031{
4032 TextWidget ctx = (TextWidget)w;
4033 XawTextPosition lastPos;
4034
4035 if (!ctx->text.update_disabled)
4036 return;
4037
4038 ctx->text.update_disabled = False0;
4039 lastPos = ctx->text.lastPos = GETLASTPOSXawTextSourceScan((ctx)->text.source, 0, XawstAll, XawsdRight
, 1, 1)
;
4040 ctx->text.lt.top = FindGoodPosition(ctx, ctx->text.lt.top);
4041 ctx->text.insertPos = FindGoodPosition(ctx, ctx->text.insertPos);
4042
4043 if (ctx->text.s.left > lastPos || ctx->text.s.right > lastPos)
4044 ctx->text.s.left = ctx->text.s.right = 0;
4045
4046 _XawTextExecuteUpdate(ctx);
4047}
4048
4049Widget
4050XawTextGetSource(Widget w)
4051{
4052 return (((TextWidget)w)->text.source);
4053}
4054
4055Widget
4056XawTextGetSink(Widget w)
4057{
4058 return (((TextWidget)w)->text.sink);
4059}
4060
4061void
4062XawTextDisplayCaret(Widget w,
4063#if NeedWidePrototypes0
4064 int display_caret
4065#else
4066 Boolean display_caret
4067#endif
4068)
4069{
4070 TextWidget ctx = (TextWidget)w;
4071
4072 if (XtIsRealized(w)(XtWindowOfObject(w) != 0L)) {
4073 _XawTextPrepareToUpdate(ctx);
4074 ctx->text.display_caret = display_caret;
4075 _XawTextExecuteUpdate(ctx);
4076 }
4077 else
4078 ctx->text.display_caret = display_caret;
4079}
4080
4081/*
4082 * Function:
4083 * XawTextSearch
4084 *
4085 * Parameters:
4086 * w - text widget
4087 * dir - direction to search
4088 * text - text block containing info about the string to search for
4089 *
4090 * Description:
4091 * Searches for the given text block.
4092 *
4093 * Returns:
4094 * The position of the text found, or XawTextSearchError on an error
4095 */
4096XawTextPosition
4097XawTextSearch(Widget w,
4098#if NeedWidePrototypes0
4099 int dir,
4100#else
4101 XawTextScanDirection dir,
4102#endif
4103 XawTextBlock *text)
4104{
4105 TextWidget ctx = (TextWidget)w;
4106
4107 return (SrcSearchXawTextSourceSearch(ctx->text.source, ctx->text.insertPos, dir, text));
4108}
4109
4110TextClassRec textClassRec = {
4111 /* core */
4112 {
4113 (WidgetClass)&simpleClassRec, /* superclass */
4114 "Text", /* class_name */
4115 sizeof(TextRec), /* widget_size */
4116 XawTextClassInitialize, /* class_initialize */
4117 NULL((void*)0), /* class_part_init */
4118 False0, /* class_inited */
4119 XawTextInitialize, /* initialize */
4120 NULL((void*)0), /* initialize_hook */
4121 XawTextRealize, /* realize */
4122 _XawTextActionsTable, /* actions */
4123 0, /* num_actions */
4124 resources, /* resources */
4125 XtNumber(resources)((Cardinal) (sizeof(resources) / sizeof(resources[0]))), /* num_resource */
4126 NULLQUARK((XrmQuark) 0), /* xrm_class */
4127 True1, /* compress_motion */
4128 XtExposeGraphicsExpose0x10 | /* compress_exposure */
4129 XtExposeNoExpose0x40,
4130 True1, /* compress_enterleave */
4131 False0, /* visible_interest */
4132 XawTextDestroy, /* destroy */
4133 XawTextResize, /* resize */
4134 XawTextExpose, /* expose */
4135 XawTextSetValues, /* set_values */
4136 NULL((void*)0), /* set_values_hook */
4137 XtInheritSetValuesAlmost((XtAlmostProc) _XtInherit), /* set_values_almost */
4138 XawTextGetValuesHook, /* get_values_hook */
4139 NULL((void*)0), /* accept_focus */
4140 XtVersion(11 * 1000 + 6), /* version */
4141 NULL((void*)0), /* callback_private */
4142 _XawDefaultTextTranslations, /* tm_table */
4143 XtInheritQueryGeometry((XtGeometryHandler) _XtInherit), /* query_geometry */
4144 XtInheritDisplayAccelerator((XtStringProc) _XtInherit), /* display_accelerator */
4145 NULL((void*)0), /* extension */
4146 },
4147 /* simple */
4148 {
4149 XawTextChangeSensitive, /* change_sensitive */
4150 },
4151 /* text */
4152 {
4153 NULL((void*)0), /* extension */
4154 }
4155};
4156
4157WidgetClass textWidgetClass = (WidgetClass)&textClassRec;