1 /*************************************<+>*************************************
2  *****************************************************************************
3  **
4  **   File:        TextEdit.c
5  **
6  **   Project:     X Widgets
7  **
8  **   Description: Code for TextEdit widget
9  **
10  *****************************************************************************
11  **
12  **   Copyright (c) 1988 by Hewlett-Packard Company
13  **   Copyright (c) 1987, 1988 by Digital Equipment Corporation, Maynard,
14  **             Massachusetts, and the Massachusetts Institute of Technology,
15  **             Cambridge, Massachusetts
16  **
17  **   Permission to use, copy, modify, and distribute this software
18  **   and its documentation for any purpose and without fee is hereby
19  **   granted, provided that the above copyright notice appear in all
20  **   copies and that both that copyright notice and this permission
21  **   notice appear in supporting documentation, and that the names of
22  **   Hewlett-Packard, Digital or  M.I.T.  not be used in advertising or
23  **   publicity pertaining to distribution of the software without
24  **   written prior permission.
25  **
26  **   DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
27  **   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
28  **   DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
29  **   ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
30  **   WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
31  **   ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
32  **   SOFTWARE.
33  **
34  *****************************************************************************
35  *************************************<+>*************************************/
36 
37 #include <stdio.h>
38 #ifdef SYSV
39 #include <fcntl.h>
40 #include <string.h>
41 #else
42 #include <strings.h>
43 #endif	/* SYSV */
44 #include <X11/Xos.h>
45 
46 #include <X11/Xlib.h>
47 #include <X11/cursorfont.h>
48 #include <X11/IntrinsicP.h>
49 #include <X11/StringDefs.h>
50 #include <Xw/Xw.h>
51 #include <Xw/XwP.h>
52 
53 #include <Xw/TextEdit.h>
54 #include <Xw/TextEditP.h>
55 #include <X11/Xutil.h>  /* This include depends on something above it */
56 
57 #define BufMax 1000
58 #define abs(x)	(((x) < 0) ? (-(x)) : (x))
59 #define min(x,y)	((x) < (y) ? (x) : (y))
60 #define max(x,y)	((x) > (y) ? (x) : (y))
61 #define GETLASTPOS(ctx)  ((*(ctx->text.source->getLastPos)) (ctx->text.source))
62 
63 #define BUTTONMASK 0x143d
64 
65 #define zeroPosition ((XwTextPosition) 0)
66 
67 /******************************************************************************
68 *
69 *  Resources for TextEdit
70 *
71 ******************************************************************************/
72 
73 static XtResource resources[] = {
74 /* Resources from other classes with new defaults */
75   {XtNheight,
76      XtCHeight,
77      XtRDimension,
78      sizeof(Dimension),
79      XtOffset(XwTextEditWidget, core.height),
80      XtRString,
81      "200"},
82   {XtNwidth,
83      XtCWidth,
84      XtRDimension,
85      sizeof(Dimension),
86      XtOffset(XwTextEditWidget, core.width),
87      XtRString,
88      "200"},
89 /* New resources for TextEdit */
90   {XtNdisplayPosition,
91      XtCTextPosition,
92      XtRInt,
93      sizeof (XwTextPosition),
94      XtOffset(XwTextEditWidget, text.lt.top),
95      XtRString, "0"},
96   {XtNinsertPosition,
97      XtCTextPosition,
98      XtRInt,
99      sizeof(XwTextPosition),
100      XtOffset(XwTextEditWidget, text.insertPos),
101      XtRString,
102      "0"},
103   {XtNleftMargin,
104      XtCMargin,
105      XtRDimension,
106      sizeof (Dimension),
107      XtOffset(XwTextEditWidget, text.leftmargin),
108      XtRString,
109      "2"},
110   {XtNrightMargin,
111      XtCMargin,
112      XtRDimension,
113      sizeof (Dimension),
114      XtOffset(XwTextEditWidget, text.rightmargin),
115      XtRString,
116      "2"},
117   {XtNtopMargin,
118      XtCMargin,
119      XtRDimension,
120      sizeof (Dimension),
121      XtOffset(XwTextEditWidget, text.topmargin),
122      XtRString,
123      "2"},
124   {XtNbottomMargin,
125      XtCMargin,
126      XtRDimension,
127      sizeof (Dimension),
128      XtOffset(XwTextEditWidget, text.bottommargin),
129      XtRString,
130      "2"},
131   {XtNsourceType,
132      XtCSourceType,
133      XtRSourceType,
134      sizeof(XwSourceType),
135      XtOffset(XwTextEditWidget, text.srctype),
136      XtRString,
137      "stringsrc"},
138   {XtNtextSource,
139      XtCTextSource,
140      XtRPointer,
141      sizeof (caddr_t),
142      XtOffset(XwTextEditWidget, text.source),
143      XtRPointer,
144      NULL},
145   {XtNselection,
146      XtCSelection,
147      XtRPointer,
148      sizeof(caddr_t),
149      XtOffset(XwTextEditWidget, text.s),
150      XtRPointer,
151      NULL},
152   {XtNmotionVerification,
153      XtCCallback,
154      XtRCallback,
155      sizeof(XtCallbackProc),
156      XtOffset(XwTextEditWidget, text.motion_verification),
157      XtRCallback,
158      (caddr_t) NULL},
159   {XtNmodifyVerification,
160      XtCCallback,
161      XtRCallback,
162      sizeof(XtCallbackProc),
163      XtOffset(XwTextEditWidget, text.modify_verification),
164      XtRCallback,
165      (caddr_t) NULL},
166   {XtNleaveVerification,
167      XtCCallback,
168      XtRCallback,
169      sizeof(XtCallbackProc),
170      XtOffset(XwTextEditWidget, text.leave_verification),
171      XtRCallback,
172      (caddr_t) NULL},
173   {XtNexecute,
174      XtCCallback,
175      XtRCallback,
176      sizeof(XtCallbackProc),
177      XtOffset(XwTextEditWidget, text.execute),
178      XtRCallback,
179      (caddr_t) NULL},
180   {XtNwrap,
181      XtCWrap,
182      XtRWrap,
183      sizeof (XwWrap),
184      XtOffset (XwTextEditWidget, text.wrap_mode),
185      XtRString,
186      "softwrap"},
187   {XtNwrapForm,
188      XtCWrapForm,
189      XtRWrapForm,
190      sizeof (XwWrapForm),
191      XtOffset (XwTextEditWidget, text.wrap_form),
192      XtRString,
193      "sourceform"},
194   {XtNwrapBreak,
195      XtCWrapBreak,
196      XtRWrapBreak,
197      sizeof (XwWrapBreak),
198      XtOffset (XwTextEditWidget, text.wrap_break),
199      XtRString,
200      "wrapwhitespace"},
201   {XtNscroll,
202      XtCScroll,
203      XtRScroll,
204      sizeof (XwScroll),
205      XtOffset (XwTextEditWidget, text.scroll_mode),
206      XtRString,
207      "autoscrolloff"},
208   {XtNgrow,
209      XtCGrow,
210      XtRGrow,
211      sizeof (XwGrow),
212      XtOffset (XwTextEditWidget, text.grow_mode),
213      XtRString,
214      "growoff"},
215 };
216 
217 
218 /******************************************************************************
219 *
220 *  Forward declarations of functions to put into the class record
221 *
222 ******************************************************************************/
223 static void Initialize();
224 static void Realize();
225 static void TextDestroy();
226 static void Resize();
227 static void ProcessExposeRegion();
228 static Boolean SetValues();
229 static unsigned char* _XwTextCopySubString();
230 
231 /******************************************************************************
232 *
233 *  Forward declarations of action functions to put into the action table
234 *
235 ******************************************************************************/
236 static void TraverseUp();
237 static void TraverseDown();
238 static void TraverseLeft();
239 static void TraverseRight();
240 static void TraverseNext();
241 static void TraversePrev();
242 static void TraverseHome();
243 static void TraverseNextTop();
244 static void Enter();
245 static void Leave();
246 static void Execute();
247 static void RedrawDisplay();
248 static void InsertChar();
249 static void TextFocusIn();
250 static void TextFocusOut();
251 static void MoveForwardChar();
252 static void MoveBackwardChar();
253 static void MoveForwardWord();
254 static void MoveBackwardWord();
255 static void MoveForwardParagraph();
256 static void MoveBackwardParagraph();
257 static void MoveToLineStart();
258 static void MoveToLineEnd();
259 static void MoveNextLine();
260 static void MovePreviousLine();
261 static void MoveNextPage();
262 static void MovePreviousPage();
263 static void MoveBeginningOfFile();
264 static void MoveEndOfFile();
265 static void ScrollOneLineUp();
266 static void ScrollOneLineDown();
267 static void DeleteForwardChar();
268 static void DeleteBackwardChar();
269 static void DeleteBackwardNormal();
270 static void DeleteForwardWord();
271 static void DeleteBackwardWord();
272 static void DeleteCurrentSelection();
273 static void KillForwardWord();
274 static void KillBackwardWord();
275 static void KillCurrentSelection();
276 static void KillToEndOfLine();
277 static void KillToEndOfParagraph();
278 static void UnKill();
279 static void Stuff();
280 static void InsertNewLineAndIndent();
281 static void InsertNewLineAndBackup();
282 static XwEditResult InsertNewLine();
283 static void SelectWord();
284 static void SelectAll();
285 static void SelectStart();
286 static void SelectAdjust();
287 static void SelectEnd();
288 static void ExtendStart();
289 static void ExtendAdjust();
290 static void ExtendEnd();
291 
292 /******************************************************************************
293 *
294 * TextEdit Actions Table
295 *
296 ******************************************************************************/
297 XtActionsRec texteditActionsTable [] = {
298 /* motion bindings */
299   {"forward-character", 	MoveForwardChar},
300   {"backward-character", 	MoveBackwardChar},
301   {"forward-word", 		MoveForwardWord},
302   {"backward-word", 		MoveBackwardWord},
303   {"forward-paragraph", 	MoveForwardParagraph},
304   {"backward-paragraph", 	MoveBackwardParagraph},
305   {"beginning-of-line", 	MoveToLineStart},
306   {"end-of-line", 		MoveToLineEnd},
307   {"next-line", 		MoveNextLine},
308   {"previous-line", 		MovePreviousLine},
309   {"next-page", 		MoveNextPage},
310   {"previous-page", 		MovePreviousPage},
311   {"beginning-of-file", 	MoveBeginningOfFile},
312   {"end-of-file", 		MoveEndOfFile},
313   {"scroll-one-line-up", 	ScrollOneLineUp},
314   {"scroll-one-line-down", 	ScrollOneLineDown},
315 /* delete bindings */
316   {"delete-next-character", 	DeleteForwardChar},
317   {"delete-previous-character", DeleteBackwardNormal},
318   {"delete-next-word", 		DeleteForwardWord},
319   {"delete-previous-word", 	DeleteBackwardWord},
320   {"delete-selection", 		DeleteCurrentSelection},
321 /* kill bindings */
322   {"kill-word", 		KillForwardWord},
323   {"backward-kill-word", 	KillBackwardWord},
324   {"kill-selection", 		KillCurrentSelection},
325   {"kill-to-end-of-line", 	KillToEndOfLine},
326   {"kill-to-end-of-paragraph", 	KillToEndOfParagraph},
327 /* unkill bindings */
328   {"unkill", 			UnKill},
329   {"stuff", 			Stuff},
330 /* new line stuff */
331   {"newline-and-indent", 	InsertNewLineAndIndent},
332   {"newline-and-backup", 	InsertNewLineAndBackup},
333   {"newline", 			(XtActionProc)InsertNewLine},
334 /* Selection stuff */
335   {"select-word", 		SelectWord},
336   {"select-all", 		SelectAll},
337   {"select-start", 		SelectStart},
338   {"select-adjust", 		SelectAdjust},
339   {"select-end", 		SelectEnd},
340   {"extend-start", 		ExtendStart},
341   {"extend-adjust", 		ExtendAdjust},
342   {"extend-end", 		ExtendEnd},
343 /* Miscellaneous */
344   {"redraw-display", 		RedrawDisplay},
345   {"insert-char", 		InsertChar},
346   {"focus-in", 	 	        TextFocusIn},
347   {"focus-out", 		TextFocusOut},
348 /* traversal direction functions */
349   {"traverse-left", 		TraverseLeft},
350   {"traverse-right", 		TraverseRight},
351   {"traverse-next", 		TraverseNext},
352   {"traverse-prev", 		TraversePrev},
353   {"traverse-up", 		TraverseUp},
354   {"traverse-down", 		TraverseDown},
355   {"traverse-home", 		TraverseHome},
356   {"traverse-next-top",		TraverseNextTop},
357 /* highlighting */
358   {"enter",			Enter},
359   {"leave",			Leave},
360   {"execute",                   Execute},
361   {NULL,NULL}
362 };
363 
364 /****************************************************************************
365 *
366 * TextEdit Default Event Translations
367 *
368 ****************************************************************************/
369 char defaultTextEditTranslations[] =
370        "Ctrl<Key>F:	forward-character()\n\
371 	Ctrl<Key>Right:	traverse-right()\n\
372 	<Key>Right:	forward-character()\n\
373 	Ctrl<Key>B:	backward-character()\n\
374 	Ctrl<Key>Left:	traverse-left()\n\
375 	<Key>Left: 	backward-character()\n\
376 	Meta<Key>F:	forward-word()\n\
377 	Meta<Key>B:	backward-word()\n\
378 	Meta<Key>]:	forward-paragraph()\n\
379 	Ctrl<Key>[:	backward-paragraph()\n\
380 	Ctrl<Key>A:	beginning-of-line()\n\
381 	Ctrl<Key>E:	end-of-line()\n\
382 	Ctrl<Key>N:	next-line()\n\
383 	Ctrl<Key>Down:	traverse-down()\n\
384 	<Key>Down: 	next-line()\n\
385 	Ctrl<Key>P:	previous-line()\n\
386 	Ctrl<Key>Up:	traverse-up()\n\
387 	<Key>Up:	previous-line()\n\
388 	Ctrl<Key>V:	next-page()\n\
389 	Ctrl<Key>Next:	traverse-next()\n\
390 	<Key>Next:	next-page()\n\
391 	Meta<Key>V:	previous-page()\n\
392 	Ctrl<Key>Prior:	traverse-prev()\n\
393 	<Key>Prior:	previous-page()\n\
394 	Meta<Key>\\<:	beginning-of-file()\n\
395 	Meta<Key>\\>:	end-of-file()\n\
396 	Ctrl<Key>Home:	traverse-home()\n\
397 	Shift<Key>Home:	end-of-file()\n\
398 	<Key>Home:	beginning-of-file()\n\
399 	Ctrl<Key>Z:	scroll-one-line-up()\n\
400 	Meta<Key>Z:	scroll-one-line-down()\n\
401 	Ctrl<Key>D:	delete-next-character()\n\
402 	<Key>Delete:	delete-previous-character()\n\
403 	<Key>BackSpace:	delete-previous-character()\n\
404 	Ctrl<Key>H:	delete-previous-character()\n\
405 	Meta<Key>D:	delete-next-word()\n\
406 	Meta<Key>H:	delete-previous-word()\n\
407 	Shift Meta<Key>D:	kill-word()\n\
408 	Shift Meta<Key>H:	backward-kill-word()\n\
409 	Ctrl<Key>W:	kill-selection()\n\
410 	Ctrl<Key>K:	kill-to-end-of-line()\n\
411 	Meta<Key>K:	kill-to-end-of-paragraph()\n\
412 	Ctrl<Key>Y:	unkill()\n\
413 	Meta<Key>Y:	stuff()\n\
414 	Ctrl<Key>J:	newline-and-indent()\n\
415 	Ctrl<Key>O:	newline-and-backup()\n\
416 	Ctrl<Key>M:	newline()\n\
417 	<Key>Return:	newline()\n\
418       <Key>Linefeed:  newline-and-indent()\n\
419 	Ctrl<Key>L:	redraw-display()\n\
420 	<FocusIn>:	focus-in()\n\
421 	<FocusOut>:	focus-out()\n\
422 	<Btn1Down>:	select-start()\n\
423 	Button1<PtrMoved>:	extend-adjust()\n\
424 	<Btn1Up>:	extend-end()\n\
425 	<Btn2Down>:	stuff()\n\
426 	<Btn3Down>:	extend-start()\n\
427 	Button3<PtrMoved>:	extend-adjust()\n\
428 	<Btn3Up>:	extend-end()\n\
429 	<Key>Execute:	execute()\n\
430 	<Key>:	insert-char()\n\
431 	Shift<Key>:	insert-char()\n\
432 	<EnterWindow>:	enter()\n\
433 	<LeaveWindow>:	leave()";
434 
435 
436 /* Utility routines for support of TextEdit */
437 #include "sub.c"
438 
439 /******************************************************************************
440 *
441 * Functions to support selection
442 *
443 ******************************************************************************/
444 /*--------------------------------------------------------------------------+*/
_XtTextSetNewSelection(ctx,left,right)445 static void _XtTextSetNewSelection(ctx, left, right)
446 /*--------------------------------------------------------------------------+*/
447   XwTextEditWidget ctx;
448   XwTextPosition left, right;
449 {
450     XwTextPosition pos;
451 
452     if (left < ctx->text.s.left) {
453 	pos = min(right, ctx->text.s.left);
454 	_XtTextNeedsUpdating(ctx, left, pos);
455     }
456     if (left > ctx->text.s.left) {
457 	pos = min(left, ctx->text.s.right);
458 	_XtTextNeedsUpdating(ctx, ctx->text.s.left, pos);
459     }
460     if (right < ctx->text.s.right) {
461 	pos = max(right, ctx->text.s.left);
462 	_XtTextNeedsUpdating(ctx, pos, ctx->text.s.right);
463     }
464     if (right > ctx->text.s.right) {
465 	pos = max(left, ctx->text.s.right);
466 	_XtTextNeedsUpdating(ctx, pos, right);
467     }
468 
469     ctx->text.s.left = left;
470     ctx->text.s.right = right;
471 }
472 
473 
474 /*
475  * This routine implements multi-click selection in a hardwired manner.
476  * It supports multi-click entity cycling (char, word, line, file) and mouse
477  * motion adjustment of the selected entitie (i.e. select a word then, with
478  * button still down, adjust wich word you really meant by moving the mouse).
479  * [NOTE: This routine is to be replaced by a set of procedures that
480  * will allows clients to implements a wide class of draw through and
481  * multi-click selection user interfaces.]
482 */
483 /*--------------------------------------------------------------------------+*/
DoSelection(ctx,position,time,motion)484 static void DoSelection (ctx, position, time, motion)
485 /*--------------------------------------------------------------------------+*/
486   XwTextEditWidget ctx;
487   XwTextPosition position;
488   Time time;
489   Boolean motion;
490 {
491     int     delta;
492     XwTextPosition newLeft, newRight;
493     XwSelectType newType;
494     XwSelectType *sarray;
495 
496     delta = (time < ctx->text.lasttime) ?
497 	ctx->text.lasttime - time : time - ctx->text.lasttime;
498     if (motion)
499 	newType = ctx->text.s.type;
500     else {/* multi-click event */
501 	if ((delta < 500) && ((position >= ctx->text.s.left)
502 		    && (position <= ctx->text.s.right))) {
503 	  sarray = ctx->text.sarray;
504 	  for (sarray = ctx->text.sarray;
505 	       *sarray != XwselectNull && *sarray != ctx->text.s.type;
506 	       sarray++) ;
507 	  if (*sarray != XwselectNull) sarray++;
508 	  if (*sarray == XwselectNull) sarray = ctx->text.sarray;
509 	  newType = *sarray;
510 	} else {			/* single-click event */
511 	    newType = *(ctx->text.sarray);
512 	}
513         ctx->text.lasttime = time;
514     }
515     switch (newType) {
516 	case XwselectPosition:
517             newLeft = newRight = position;
518 	    break;
519 	case XwselectChar:
520             newLeft = position;
521             newRight = (*(ctx->text.source->scan))(
522                     ctx->text.source, position, position, XwsdRight, 1, FALSE);
523 	    break;
524 	case XwselectWord:
525 	    newLeft = (*(ctx->text.source->scan))
526 	      (ctx->text.source, position, XwstWhiteSpace, XwsdLeft, 1, FALSE);
527 	    newRight = (*(ctx->text.source->scan))
528 	      (ctx->text.source, position, XwstWhiteSpace, XwsdRight, 1, FALSE);
529 	    break;
530 	case XwselectLine:
531 	case XwselectParagraph:  /* need "para" scan mode to implement pargraph */
532  	    newLeft = (*(ctx->text.source->scan))(
533 		    ctx->text.source, position, XwstEOL, XwsdLeft, 1, FALSE);
534 	    newRight = (*(ctx->text.source->scan))(
535 		    ctx->text.source, position, XwstEOL, XwsdRight, 1, FALSE);
536 	    break;
537 	case XwselectAll:
538 	    newLeft = (*(ctx->text.source->scan))(
539 		    ctx->text.source, position, XwstLast, XwsdLeft, 1, FALSE);
540 	    newRight = (*(ctx->text.source->scan))(
541 		    ctx->text.source, position, XwstLast, XwsdRight, 1, FALSE);
542 	    break;
543 	default:
544 	    break;
545     }
546     if ((newLeft != ctx->text.s.left) || (newRight != ctx->text.s.right)
547 	    || (newType != ctx->text.s.type)) {
548 	_XtTextSetNewSelection(ctx, newLeft, newRight);
549 	ctx->text.s.type = newType;
550 	if (position - ctx->text.s.left < ctx->text.s.right - position)
551 	    ctx->text.insertPos = newLeft;
552 	else
553 	    ctx->text.insertPos = newRight;
554     }
555     if (!motion) { /* setup so we can freely mix select extend calls*/
556 	ctx->text.origSel.type = ctx->text.s.type;
557 	ctx->text.origSel.left = ctx->text.s.left;
558 	ctx->text.origSel.right = ctx->text.s.right;
559 	if (position >= ctx->text.s.left +
560 	    ((ctx->text.s.right - ctx->text.s.left) / 2))
561 	    ctx->text.extendDir = XwsdRight;
562 	else
563 	    ctx->text.extendDir = XwsdLeft;
564     }
565 }
566 
567 /*
568  * This routine implements extension of the currently selected text in
569  * the "current" mode (i.e. char word, line, etc.). It worries about
570  * extending from either end of the selection and handles the case when you
571  * cross through the "center" of the current selection (e.g. switch which
572  * end you are extending!).
573  * [NOTE: This routine will be replaced by a set of procedures that
574  * will allows clients to implements a wide class of draw through and
575  * multi-click selection user interfaces.]
576 */
577 /*--------------------------------------------------------------------------+*/
ExtendSelection(ctx,position,motion)578 static void ExtendSelection (ctx, position, motion)
579 /*--------------------------------------------------------------------------+*/
580   XwTextEditWidget ctx;
581   XwTextPosition position;
582   Boolean motion;
583 {
584     XwTextPosition newLeft, newRight;
585 
586 
587     if (!motion) {		/* setup for extending selection */
588 	ctx->text.origSel.type = ctx->text.s.type;
589 	ctx->text.origSel.left = ctx->text.s.left;
590 	ctx->text.origSel.right = ctx->text.s.right;
591 	if (position >= ctx->text.s.left +
592 	    ((ctx->text.s.right - ctx->text.s.left) / 2))
593 	    ctx->text.extendDir = XwsdRight;
594 	else
595 	    ctx->text.extendDir = XwsdLeft;
596     }
597     else /* check for change in extend direction */
598 	if ((ctx->text.extendDir == XwsdRight &&
599 	     position < ctx->text.origSel.left) ||
600 	    (ctx->text.extendDir == XwsdLeft &&
601 	     position > ctx->text.origSel.right)) {
602 	  ctx->text.extendDir =
603 	    (ctx->text.extendDir == XwsdRight)? XwsdLeft : XwsdRight;
604 	  _XtTextSetNewSelection(ctx, ctx->text.origSel.left,
605 				 ctx->text.origSel.right);
606 	}
607     newLeft = ctx->text.s.left;
608     newRight = ctx->text.s.right;
609     switch (ctx->text.s.type) {
610 	case XwselectPosition:
611 	    if (ctx->text.extendDir == XwsdRight)
612 		newRight = position;
613 	    else
614 		newLeft = position;
615 	    break;
616 	case XwselectWord:
617 	    if (ctx->text.extendDir == XwsdRight)
618 	      newRight = position = (*(ctx->text.source->scan))
619 	      (ctx->text.source, position, XwstWhiteSpace, XwsdRight, 1, FALSE);
620 	    else
621 	      newLeft = position = (*(ctx->text.source->scan))
622 	      (ctx->text.source, position, XwstWhiteSpace, XwsdLeft, 1, FALSE);
623             break;
624         case XwselectLine:
625 	case XwselectParagraph: /* need "para" scan mode to implement pargraph */
626 	    if (ctx->text.extendDir == XwsdRight)
627 		newRight = position = (*(ctx->text.source->scan))
628 		      (ctx->text.source, position, XwstEOL, XwsdRight, 1, TRUE);
629 	    else
630 		newLeft = position = (*(ctx->text.source->scan))
631 		       (ctx->text.source, position, XwstEOL, XwsdLeft, 1, FALSE);
632 	    break;
633 	case XwselectAll:
634 	    position = ctx->text.insertPos;
635 	    break;
636 	default:
637 	    break;
638     }
639     _XtTextSetNewSelection(ctx, newLeft, newRight);
640     ctx->text.insertPos = position;
641 }
642 
643 
644 /*
645  * This routine is used to perform various selection functions. The goal is
646  * to be able to specify all the more popular forms of draw-through and
647  * multi-click selection user interfaces from the outside.
648  */
649 /*--------------------------------------------------------------------------+*/
AlterSelection(ctx,mode,action)650 static void AlterSelection (ctx, mode, action)
651 /*--------------------------------------------------------------------------+*/
652     XwTextEditWidget     ctx;
653     XwSelectionMode      mode;   /* {XwsmTextSelect, XwsmTextExtend}	  */
654     XwSelectionAction action; /* {XwactionStart, XwactionAdjust, XwactionEnd} */
655 {
656     XwTextPosition position;
657     unsigned char   *ptr;
658 
659     position = PositionForXY (ctx, (int) ctx->text.ev_x, (int) ctx->text.ev_y);
660     if (action == XwactionStart) {
661 	switch (mode) {
662 	case XwsmTextSelect:
663 	    DoSelection (ctx, position, ctx->text.time, FALSE);
664 	    break;
665 	case XwsmTextExtend:
666             ExtendSelection (ctx, position, FALSE);
667             break;
668         }
669     }
670     else {
671         switch (mode) {
672         case XwsmTextSelect:
673             DoSelection (ctx, position, ctx->text.time, TRUE);
674             break;
675         case XwsmTextExtend:
676             ExtendSelection (ctx, position, TRUE);
677             break;
678         }
679     }
680     if (action == XwactionEnd && ctx->text.s.left < ctx->text.s.right) {
681         ptr = _XwTextCopySubString (ctx, ctx->text.s.left, ctx->text.s.right);
682         XStoreBuffer (XtDisplay(ctx), ptr, min (XwStrlen (ptr), MAXCUT), 0);
683         XtFree (ptr);
684     }
685 }
686 
687 /******************************************************************************
688 *
689 * TextEdit Class Methods
690 *
691 ******************************************************************************/
692 
693 /*****************************************************************************
694 * This method deletes the text from startPos to endPos in a source and
695 * then inserts, at startPos, the text that was passed. As a side effect it
696 * "invalidates" that portion of the displayed text (if any), so that things
697 * will be repainted properly.
698 ******************************************************************************/
699 
700 /*--------------------------------------------------------------------------+*/
_XwTextSubString(ctx,left,right,target,size,used)701 static int _XwTextSubString(ctx, left, right, target, size, used)
702 /*--------------------------------------------------------------------------+*/
703   XwTextEditWidget ctx;
704   XwTextPosition left, right;
705   unsigned char  *target;       /* Memory to copy into */
706   int            size,          /* Size of memory */
707                  *used;         /* Memory used by copy */
708 {
709     unsigned char   *tempResult;
710     int             length, n;
711     XwTextBlock     text;
712     XwTextPosition  end, nend;
713 
714     end = (*(ctx->text.source->read))(ctx->text.source, left, &text,
715 				      right - left);
716     n = length = min(text.length,size);
717     strncpy(target, text.ptr, n);
718     while (n && (end < right) && (length < size)) {
719         nend = (*(ctx->text.source->read))(ctx->text.source, end, &text,
720 					   right - end);
721 	n = text.length;
722 	if (length + n > size) n = size - length;
723 	tempResult = target + length;
724         strncpy(tempResult, text.ptr, n);
725 	length += n;
726         end = nend;
727     }
728     *used = length;
729     return length; /* return the number of positions transfered to target */
730 }
731 
732 /*--------------------------------------------------------------------------+*/
_XwTextCopySubString(ctx,left,right)733 static unsigned char *_XwTextCopySubString(ctx, left, right)
734 /*--------------------------------------------------------------------------+*/
735   XwTextEditWidget ctx;
736   XwTextPosition left, right;
737 {
738     unsigned char *result;
739     int length, resultLength;
740     int   dummy;
741 
742     resultLength = right - left + 10;	/* Bogus? %%% */
743     result = (unsigned char *)XtMalloc((unsigned) resultLength);
744 
745     length = _XwTextSubString(ctx, left, right, result, resultLength, &dummy);
746 
747     result[length] = 0;
748     return result;
749 }
750 
751 /*--------------------------------------------------------------------------+*/
_XwTextCopySelection(ctx)752 static unsigned char *_XwTextCopySelection(ctx)
753 /*--------------------------------------------------------------------------+*/
754   XwTextEditWidget ctx;
755 {
756    return( _XwTextCopySubString(ctx, ctx->text.s.left, ctx->text.s.right));
757 }
758 
759 /*--------------------------------------------------------------------------+*/
_XwTextSetSelection(w,left,right)760 static void _XwTextSetSelection(w, left, right)
761 /*--------------------------------------------------------------------------+*/
762   Widget w;
763   Position left, right;
764 {
765    XwTextEditWidget ctx = (XwTextEditWidget) w;
766 
767   _XtTextPrepareToUpdate(ctx);
768   _XtTextSetNewSelection(ctx, (XwTextPosition)left, (XwTextPosition)right);
769   _XtTextExecuteUpdate(ctx);
770 }
771 
772 /*--------------------------------------------------------------------------+*/
_XwTextUnsetSelection(w)773 static void _XwTextUnsetSelection(w)
774 /*--------------------------------------------------------------------------+*/
775     Widget	    w;
776 {
777     XwTextEditWidget ctx = (XwTextEditWidget) w;
778 
779     _XtTextPrepareToUpdate(ctx);
780     _XtTextSetNewSelection(ctx, zeroPosition, zeroPosition);
781     _XtTextExecuteUpdate(ctx);
782 }
783 
784 /*--------------------------------------------------------------------------+*/
_XwTextReplace(w,startPos,endPos,text,verify)785 static XwEditResult _XwTextReplace(w, startPos, endPos, text, verify)
786 /*--------------------------------------------------------------------------+*/
787     Widget	    w;
788     XwTextPosition  startPos, endPos;
789     XwTextBlock     *text;
790     Boolean         verify;
791 {
792     XwTextEditWidget ctx = (XwTextEditWidget) w;
793     XwEditResult result;
794 
795     _XtTextPrepareToUpdate(ctx);
796     result = ReplaceText(ctx, startPos, endPos, text, verify);
797     _XtTextExecuteUpdate(ctx);
798     return result;
799 }
800 
801 /*--------------------------------------------------------------------------+*/
_XwTextRedraw(w)802 static void _XwTextRedraw (w)
803 /*--------------------------------------------------------------------------+*/
804    Widget w;
805 {
806    XwTextEditWidget ctx = (XwTextEditWidget) w;
807 
808    _XtTextPrepareToUpdate(ctx);
809    ForceBuildLineTable(ctx);
810    DisplayAllText(ctx);
811    _XtTextExecuteUpdate(ctx);
812    if (ctx->primitive.highlighted)
813       _XwHighlightBorder(ctx);
814 }
815 
816 
817 /******************************************************************************
818 *
819 * Utilities
820 *
821 ******************************************************************************/
822 /*--------------------------------------------------------------------------+*/
_XwSetCursorPos(ctx,newposition)823 static XwEditResult _XwSetCursorPos(ctx, newposition)
824 /*--------------------------------------------------------------------------+*/
825   XwTextEditWidget  ctx;
826   XwTextPosition  newposition;
827 {
828   XwTextVerifyCD  cbdata;
829 
830   cbdata.operation = motionVerify;
831   cbdata.doit = TRUE;
832   cbdata.currInsert = ctx->text.insertPos;
833   cbdata.newInsert = newposition;
834 
835   XtCallCallbacks((Widget)ctx, XtNmotionVerification, &cbdata);
836 
837   if (!cbdata.doit) return XweditReject;
838 
839   ctx->text.insertPos = cbdata.newInsert;
840 
841   return XweditDone;
842 }
843 
844 /*--------------------------------------------------------------------------+*/
StartAction(ctx,event)845 static void StartAction(ctx, event)
846 /*--------------------------------------------------------------------------+*/
847    XwTextEditWidget ctx;
848    XEvent *event;
849 {
850     _XtTextPrepareToUpdate(ctx);
851     if (event) {
852       ctx->text.time = event->xbutton.time;
853       ctx->text.ev_x = event->xbutton.x;
854       ctx->text.ev_y = event->xbutton.y;
855     }
856 }
857 
858 /*--------------------------------------------------------------------------+*/
EndAction(ctx)859 static void EndAction(ctx)
860 /*--------------------------------------------------------------------------+*/
861    XwTextEditWidget ctx;
862 {
863     CheckResizeOrOverflow(ctx);
864     _XtTextExecuteUpdate(ctx);
865 }
866 
867 /*--------------------------------------------------------------------------+*/
DeleteOrKill(ctx,from,to,kill)868 static void DeleteOrKill(ctx, from, to, kill)
869 /*--------------------------------------------------------------------------+*/
870     XwTextEditWidget	   ctx;
871     XwTextPosition from, to;
872     Boolean	   kill;
873 {
874     XwTextBlock text;
875     unsigned char *ptr;
876     XwEditResult result;
877 
878     if (kill && from < to)
879       ptr = _XwTextCopySubString(ctx, from, to);
880 
881     text.length = 0;
882 
883     if (result = ReplaceText(ctx, from, to, &text, TRUE)) {
884       if (result != XweditReject)
885 	XBell(XtDisplay(ctx), 50);
886       if (kill && from < to)
887 	XtFree(ptr);
888       return;
889     }
890 
891     if (kill && from < to) {
892       XStoreBuffer(XtDisplay(ctx), ptr, XwStrlen(ptr), 1);
893       XtFree(ptr);
894     }
895     _XwSetCursorPos(ctx, from);
896     ctx->text.showposition = TRUE;
897 
898     from = ctx->text.insertPos;
899     _XtTextSetNewSelection(ctx, from, from);
900 }
901 
902 
903 /*--------------------------------------------------------------------------+*/
StuffFromBuffer(ctx,buffer)904 static void StuffFromBuffer(ctx, buffer)
905 /*--------------------------------------------------------------------------+*/
906   XwTextEditWidget ctx;
907   int buffer;
908 {
909     extern char *XFetchBuffer();
910     XwTextBlock text;
911     XwEditResult result;
912     XwTextPosition nextcursorpos;
913 
914     text.ptr =
915       (unsigned char*)XFetchBuffer(XtDisplay(ctx), &(text.length), buffer);
916     if (result =
917 	ReplaceText(ctx, ctx->text.insertPos, ctx->text.insertPos,
918 		    &text, TRUE)) {
919 	if (result != XweditReject)
920 	  XBell(XtDisplay(ctx), 50);
921 	XtFree(text.ptr);
922 	return;
923     }
924     nextcursorpos = (*(ctx->text.source->scan))
925       (ctx->text.source, ctx->text.insertPos, XwstPositions, XwsdRight,
926        text.length, TRUE);
927     _XwSetCursorPos(ctx, nextcursorpos);
928     nextcursorpos = ctx->text.insertPos;
929     _XtTextSetNewSelection(ctx, nextcursorpos, nextcursorpos);
930     XtFree(text.ptr);
931 }
932 
933 /*--------------------------------------------------------------------------+*/
NextPosition(ctx,position,kind,direction)934 static XwTextPosition NextPosition(ctx, position, kind, direction)
935 /*--------------------------------------------------------------------------+*/
936     XwTextEditWidget ctx;
937     XwTextPosition   position;
938     XwScanType       kind;
939     XwScanDirection  direction;
940 {
941     XwTextPosition pos;
942 
943      pos = (*(ctx->text.source->scan))(
944 	    ctx->text.source, position, kind, direction, 1, FALSE);
945      if (pos == ctx->text.insertPos)
946          pos = (*(ctx->text.source->scan))(
947             ctx->text.source, position, kind, direction, 2, FALSE);
948      return pos;
949 }
950 
951 /*--------------------------------------------------------------------------+*/
InsertNewLineAndBackupInternal(ctx)952 static XwEditResult InsertNewLineAndBackupInternal(ctx)
953 /*--------------------------------------------------------------------------+*/
954   XwTextEditWidget ctx;
955 {
956     XwTextBlock text;
957     XwEditResult result;
958 
959     text.length = 1;
960     text.ptr = (unsigned char*)"\n";
961     text.firstPos = 0;
962     if (result =
963 	ReplaceText(ctx, ctx->text.insertPos, ctx->text.insertPos,
964 		    &text, TRUE)) {
965 	if (result != XweditReject)
966 	  XBell( XtDisplay(ctx), 50);
967 	return(result);
968     }
969     _XtTextSetNewSelection(ctx, (XwTextPosition) 0, (XwTextPosition) 0);
970     ctx->text.showposition = TRUE;
971     return(result);
972 }
973 /* Insert a file of the given name into the text.  Returns 0 if file found,
974    -1 if not. */
975 
976 /* Unadvertized function */
977 /*--------------------------------------------------------------------------+*/
XwTextInsertFile(ctx,str)978 int XwTextInsertFile(ctx, str)
979 /*--------------------------------------------------------------------------+*/
980   XwTextEditWidget ctx;
981   unsigned char *str;
982 {
983     int fid;
984     XwTextBlock text;
985     unsigned char    buf[1000];
986     XwTextPosition position;
987 
988     if (str == NULL || XwStrlen(str) == 0) return -1;
989     fid = open(str, O_RDONLY);
990     if (fid <= 0) return -1;
991     _XtTextPrepareToUpdate(ctx);
992     position = ctx->text.insertPos;
993     while ((text.length = read(fid, buf, 512)) > 0) {
994 	text.ptr = buf;
995 	ReplaceText(ctx, position, position, &text, TRUE);
996 	position = (*(ctx->text.source->scan))(ctx->text.source, position,
997 		XwstPositions, XwsdRight, text.length, TRUE);
998     }
999     close(fid);
1000     ctx->text.insertPos = position;
1001     _XtTextExecuteUpdate(ctx);
1002     return 0;
1003 }
1004 
1005 /******************************************************************************
1006 *
1007 *  Action Table Functions
1008 *
1009 ******************************************************************************/
1010 /*--------------------------------------------------------------------------+*/
VerifyLeave(ctx,event)1011 static Boolean VerifyLeave(ctx,event)
1012 /*--------------------------------------------------------------------------+*/
1013   XwTextEditWidget  ctx;
1014   XEvent            *event;
1015 {
1016   XwTextVerifyCD  cbdata;
1017 
1018   StartAction(ctx, event);
1019   cbdata.operation = leaveVerify;
1020   cbdata.doit = TRUE;
1021   cbdata.currInsert = ctx->text.insertPos;
1022   cbdata.newInsert = ctx->text.insertPos;
1023   cbdata.startPos = ctx->text.insertPos;
1024   cbdata.endPos = ctx->text.insertPos;
1025   cbdata.text = NULL;
1026   cbdata.xevent = event;
1027   XtCallCallbacks((Widget)ctx, XtNleaveVerification, &cbdata);
1028   ctx->text.insertPos = cbdata.newInsert;
1029   EndAction(ctx);
1030   return( cbdata.doit );
1031 }
1032 
1033 /*--------------------------------------------------------------------------+*/
TraverseUp(ctx,event)1034 static void TraverseUp(ctx, event)
1035 /*--------------------------------------------------------------------------+*/
1036   XwTextEditWidget ctx;
1037   XEvent           *event;
1038 {
1039   /* Allow the verification routine to control the traversal */
1040   if (VerifyLeave(ctx, event))
1041     _XwTraverseUp((Widget)ctx, event);
1042 }
1043 
1044 /*--------------------------------------------------------------------------+*/
TraverseDown(ctx,event)1045 static void TraverseDown(ctx, event)
1046 /*--------------------------------------------------------------------------+*/
1047   XwTextEditWidget ctx;
1048   XEvent           *event;
1049 {
1050   /* Allow the verification routine to control the traversal */
1051   if (VerifyLeave(ctx, event))
1052     _XwTraverseDown((Widget)ctx, event);
1053 }
1054 
1055 /*--------------------------------------------------------------------------+*/
TraversePrev(ctx,event)1056 static void TraversePrev(ctx, event)
1057 /*--------------------------------------------------------------------------+*/
1058   XwTextEditWidget ctx;
1059   XEvent           *event;
1060 {
1061   /* Allow the verification routine to control the traversal */
1062   if (VerifyLeave(ctx, event))
1063     _XwTraversePrev((Widget)ctx, event);
1064 }
1065 
1066 /*--------------------------------------------------------------------------+*/
TraverseNext(ctx,event)1067 static void TraverseNext(ctx, event)
1068 /*--------------------------------------------------------------------------+*/
1069   XwTextEditWidget ctx;
1070   XEvent           *event;
1071 {
1072   /* Allow the verification routine to control the traversal */
1073   if (VerifyLeave(ctx, event))
1074     _XwTraverseNext((Widget)ctx, event);
1075 }
1076 
1077 /*--------------------------------------------------------------------------+*/
TraverseLeft(ctx,event)1078 static void TraverseLeft(ctx, event)
1079 /*--------------------------------------------------------------------------+*/
1080   XwTextEditWidget ctx;
1081   XEvent           *event;
1082 {
1083   /* Allow the verification routine to control the traversal */
1084   if (VerifyLeave(ctx, event))
1085     _XwTraverseLeft((Widget)ctx, event);
1086 }
1087 
1088 /*--------------------------------------------------------------------------+*/
TraverseRight(ctx,event)1089 static void TraverseRight(ctx, event)
1090 /*--------------------------------------------------------------------------+*/
1091   XwTextEditWidget ctx;
1092   XEvent           *event;
1093 {
1094   /* Allow the verification routine to control the traversal */
1095   if (VerifyLeave(ctx, event))
1096     _XwTraverseRight((Widget)ctx, event);
1097 }
1098 
1099 /*--------------------------------------------------------------------------+*/
TraverseHome(ctx,event)1100 static void TraverseHome(ctx, event)
1101 /*--------------------------------------------------------------------------+*/
1102   XwTextEditWidget ctx;
1103   XEvent           *event;
1104 {
1105   /* Allow the verification routine to control the traversal */
1106   if (VerifyLeave(ctx, event))
1107     _XwTraverseHome((Widget)ctx, event);
1108 }
1109 
1110 /*--------------------------------------------------------------------------+*/
TraverseNextTop(ctx,event)1111 static void TraverseNextTop(ctx, event)
1112 /*--------------------------------------------------------------------------+*/
1113   XwTextEditWidget ctx;
1114   XEvent           *event;
1115 {
1116   /* Allow the verification routine to control the traversal */
1117   if (VerifyLeave(ctx, event))
1118     _XwTraverseNextTop((Widget)ctx, event);
1119 }
1120 
1121 /*--------------------------------------------------------------------------+*/
Enter(ctx,event)1122 static void Enter(ctx, event)
1123 /*--------------------------------------------------------------------------+*/
1124   XwTextEditWidget ctx;
1125   XEvent           *event;
1126 {
1127   _XwPrimitiveEnter((Widget)ctx, event);
1128 }
1129 
1130 /*--------------------------------------------------------------------------+*/
Leave(ctx,event)1131 static void Leave(ctx, event)
1132 /*--------------------------------------------------------------------------+*/
1133   XwTextEditWidget ctx;
1134   XEvent           *event;
1135 {
1136   /* If traversal is on, then the leave verification callback is called
1137      in the focus out event handler */
1138   if (ctx->primitive.traversal_type != XwHIGHLIGHT_TRAVERSAL)
1139     VerifyLeave(ctx, event);
1140 
1141   _XwPrimitiveLeave((Widget)ctx, event);
1142 }
1143 
1144 /*--------------------------------------------------------------------------+*/
TextFocusIn(ctx,event)1145 static void TextFocusIn (ctx, event)
1146 /*--------------------------------------------------------------------------+*/
1147   XwTextEditWidget ctx;
1148    XEvent *event;
1149 {
1150   _XwPrimitiveFocusIn((XwPrimitiveWidget)ctx, event);
1151   ctx->text.hasfocus = TRUE;
1152 }
1153 
1154 /*--------------------------------------------------------------------------+*/
TextFocusOut(ctx,event)1155 static void TextFocusOut(ctx, event)
1156 /*--------------------------------------------------------------------------+*/
1157   XwTextEditWidget ctx;
1158   XEvent *event;
1159 {
1160   /* If traversal is on, then the leave verification callback is called in
1161      the traversal event handler */
1162   if (ctx->primitive.traversal_type != XwHIGHLIGHT_TRAVERSAL)
1163       VerifyLeave(ctx, event);
1164 
1165   _XwPrimitiveFocusOut((XwPrimitiveWidget)ctx, event);
1166   ctx->text.hasfocus = FALSE;
1167 }
1168 
1169 /* Kill and Stuff */
1170 /*--------------------------------------------------------------------------+*/
UnKill(ctx,event)1171 static void UnKill(ctx, event)
1172 /*--------------------------------------------------------------------------+*/
1173   XwTextEditWidget ctx;
1174    XEvent *event;
1175 {
1176    StartAction(ctx, event);
1177     StuffFromBuffer(ctx, 1);
1178    EndAction(ctx);
1179 }
1180 
1181 /*--------------------------------------------------------------------------+*/
Stuff(ctx,event)1182 static void Stuff(ctx, event)
1183 /*--------------------------------------------------------------------------+*/
1184   XwTextEditWidget ctx;
1185    XEvent *event;
1186 {
1187    StartAction(ctx, event);
1188     StuffFromBuffer(ctx, 0);
1189    EndAction(ctx);
1190 }
1191 
1192 /* routines for moving around */
1193 
1194 /*--------------------------------------------------------------------------+*/
MoveForwardChar(ctx,event)1195 static void MoveForwardChar(ctx, event)
1196 /*--------------------------------------------------------------------------+*/
1197    XwTextEditWidget ctx;
1198    XEvent *event;
1199 {
1200   StartAction(ctx, event);
1201   _XwSetCursorPos(ctx, (*(ctx->text.source->scan))
1202        (ctx->text.source, ctx->text.insertPos, XwstPositions, XwsdRight, 1,
1203 	TRUE)
1204 		  );
1205   EndAction(ctx);
1206 }
1207 
1208 /*--------------------------------------------------------------------------+*/
MoveBackwardChar(ctx,event)1209 static void MoveBackwardChar(ctx, event)
1210 /*--------------------------------------------------------------------------+*/
1211    XwTextEditWidget ctx;
1212    XEvent *event;
1213 {
1214   StartAction(ctx, event);
1215   _XwSetCursorPos(ctx, (*(ctx->text.source->scan))
1216        (ctx->text.source, ctx->text.insertPos, XwstPositions, XwsdLeft, 1, TRUE)
1217 		  );
1218   EndAction(ctx);
1219 }
1220 
1221 /*--------------------------------------------------------------------------+*/
MoveForwardWord(ctx,event)1222 static void MoveForwardWord(ctx, event)
1223 /*--------------------------------------------------------------------------+*/
1224    XwTextEditWidget ctx;
1225    XEvent *event;
1226 {
1227   StartAction(ctx, event);
1228   _XwSetCursorPos(ctx,
1229 	  NextPosition(ctx, ctx->text.insertPos, XwstWhiteSpace, XwsdRight)
1230 		  );
1231   EndAction(ctx);
1232 }
1233 
1234 /*--------------------------------------------------------------------------+*/
MoveBackwardWord(ctx,event)1235 static void MoveBackwardWord(ctx, event)
1236 /*--------------------------------------------------------------------------+*/
1237    XwTextEditWidget ctx;
1238    XEvent *event;
1239 {
1240   StartAction(ctx, event);
1241   _XwSetCursorPos(ctx,
1242          NextPosition(ctx, ctx->text.insertPos, XwstWhiteSpace, XwsdLeft)
1243 		  );
1244   EndAction(ctx);
1245 }
1246 
1247 /*--------------------------------------------------------------------------+*/
MoveBackwardParagraph(ctx,event)1248 static void MoveBackwardParagraph(ctx, event)
1249 /*--------------------------------------------------------------------------+*/
1250    XwTextEditWidget ctx;
1251    XEvent *event;
1252 {
1253   StartAction(ctx, event);
1254   _XwSetCursorPos(ctx,
1255          NextPosition(ctx, ctx->text.insertPos, XwstEOL, XwsdLeft)
1256 		  );
1257   EndAction(ctx);
1258 }
1259 
1260 /*--------------------------------------------------------------------------+*/
MoveForwardParagraph(ctx,event)1261 static void MoveForwardParagraph(ctx, event)
1262 /*--------------------------------------------------------------------------+*/
1263    XwTextEditWidget ctx;
1264    XEvent *event;
1265 {
1266   StartAction(ctx, event);
1267   _XwSetCursorPos(ctx,
1268          NextPosition(ctx, ctx->text.insertPos, XwstEOL, XwsdRight)
1269 		  );
1270    EndAction(ctx);
1271 }
1272 
1273 /*--------------------------------------------------------------------------+*/
MoveToLineStart(ctx,event)1274 static void MoveToLineStart(ctx, event)
1275 /*--------------------------------------------------------------------------+*/
1276      XwTextEditWidget ctx;
1277      XEvent *event;
1278 {
1279   int line;
1280   StartAction(ctx, event);
1281   _XtTextShowPosition(ctx);
1282   line = LineForPosition(ctx, ctx->text.insertPos);
1283   _XwSetCursorPos(ctx, ctx->text.lt.info[line].position);
1284   EndAction(ctx);
1285 }
1286 
1287 /*--------------------------------------------------------------------------+*/
MoveToLineEnd(ctx,event)1288 static void MoveToLineEnd(ctx, event)
1289 /*--------------------------------------------------------------------------+*/
1290   XwTextEditWidget ctx;
1291   XEvent *event;
1292 {
1293   int line;
1294   XwTextPosition next, lastpos = GETLASTPOS(ctx);
1295   StartAction(ctx, event);
1296   _XtTextShowPosition(ctx);
1297   line = LineForPosition(ctx, ctx->text.insertPos);
1298   next = ctx->text.lt.info[line+1].position;
1299   if (next > lastpos)
1300     next = lastpos;
1301   else
1302     next = (*(ctx->text.source->scan))
1303       (ctx->text.source, next, XwstPositions, XwsdLeft, 1, TRUE);
1304   if (next <= ctx->text.lt.info[line].drawPos)
1305     next = ctx->text.lt.info[line].drawPos + 1 ;
1306   _XwSetCursorPos(ctx, next);
1307   EndAction(ctx);
1308 }
1309 
1310 
1311 /*--------------------------------------------------------------------------+*/
MoveNextLine(ctx,event)1312 static void MoveNextLine(ctx, event)
1313 /*--------------------------------------------------------------------------+*/
1314   XwTextEditWidget ctx;
1315   XEvent *event;
1316 {
1317   int     width, width2, height, line;
1318   XwTextPosition position, maxp, lastpos = GETLASTPOS(ctx);
1319   XwTextSink *sink = ctx->text.sink ;
1320 
1321   StartAction(ctx, event);
1322   _XtTextShowPosition(ctx); /* Needed if cursor goes off screen ??? */
1323   line = LineForPosition(ctx, ctx->text.insertPos);
1324 
1325   if (ctx->text.lt.info[line+1].position != (lastpos + 1)) {
1326     if ((line == ctx->text.lt.lines - 1) && (line > 0)) {
1327       _XtTextScroll(ctx, 1);
1328       line = LineForPosition(ctx, ctx->text.insertPos);
1329     }
1330     if (sink->LineLastPosition == ctx->text.insertPos)
1331       width = sink->LineLastWidth;
1332     else
1333       (*(ctx->text.sink->findDistance))
1334 	(ctx, ctx->text.lt.info[line].position, ctx->text.lt.info[line].x,
1335 	  ctx->text.insertPos, &width, &position, &height);
1336     line++;
1337     if (ctx->text.lt.info[line].position > lastpos) {
1338       position = lastpos;
1339     }
1340     else {
1341       (*(ctx->text.sink->findPosition))(ctx,
1342 					ctx->text.lt.info[line].position, ctx->text.lt.info[line].x,
1343 					width, FALSE, &position, &width2, &height);
1344       maxp = (*(ctx->text.source->scan))(ctx->text.source,
1345 					 ctx->text.lt.info[line+1].position,
1346 					 XwstPositions, XwsdLeft, 1, TRUE);
1347       if (position > maxp)
1348 	position = maxp;
1349     }
1350     if (_XwSetCursorPos(ctx, position) == XweditDone) {
1351       sink->LineLastWidth = width;
1352       sink->LineLastPosition = position;
1353     }
1354   }
1355   EndAction(ctx);
1356 }
1357 
1358 /*--------------------------------------------------------------------------+*/
MovePreviousLine(ctx,event)1359 static void MovePreviousLine(ctx, event)
1360 /*--------------------------------------------------------------------------+*/
1361   XwTextEditWidget ctx;
1362   XEvent *event;
1363 {
1364   int     width, width2, height, line;
1365   XwTextPosition position, maxp;
1366   XwTextSink *sink = ctx->text.sink ;
1367 
1368   StartAction(ctx, event);
1369   _XtTextShowPosition(ctx);
1370   line = LineForPosition(ctx, ctx->text.insertPos);
1371   if (line == 0) {
1372     _XtTextScroll(ctx, -1);
1373     line = LineForPosition(ctx, ctx->text.insertPos);
1374   }
1375   if (line > 0) {
1376     if (sink->LineLastPosition == ctx->text.insertPos)
1377       width = sink->LineLastWidth;
1378     else
1379       (*(ctx->text.sink->findDistance))(ctx,
1380 		    ctx->text.lt.info[line].position,
1381 		    ctx->text.lt.info[line].x,
1382 		    ctx->text.insertPos, &width, &position, &height);
1383     line--;
1384     (*(ctx->text.sink->findPosition))(ctx,
1385 		ctx->text.lt.info[line].position, ctx->text.lt.info[line].x,
1386 		width, FALSE, &position, &width2, &height);
1387     maxp = (*(ctx->text.source->scan))(ctx->text.source,
1388 		ctx->text.lt.info[line+1].position,
1389 		XwstPositions, XwsdLeft, 1, TRUE);
1390     if (position > maxp)
1391 	    position = maxp;
1392     if (_XwSetCursorPos(ctx, position) == XweditDone) {
1393       sink->LineLastWidth = width;
1394       sink->LineLastPosition = position;
1395     }
1396   }
1397   EndAction(ctx);
1398 }
1399 
1400 /*--------------------------------------------------------------------------+*/
MoveBeginningOfFile(ctx,event)1401 static void MoveBeginningOfFile(ctx, event)
1402 /*--------------------------------------------------------------------------+*/
1403   XwTextEditWidget ctx;
1404   XEvent *event;
1405 {
1406   StartAction(ctx, event);
1407   _XwSetCursorPos(ctx, (*(ctx->text.source->scan))
1408 	   (ctx->text.source, ctx->text.insertPos, XwstLast, XwsdLeft, 1, TRUE)
1409 		  );
1410   EndAction(ctx);
1411 }
1412 
1413 /*--------------------------------------------------------------------------+*/
MoveEndOfFile(ctx,event)1414 static void MoveEndOfFile(ctx, event)
1415 /*--------------------------------------------------------------------------+*/
1416   XwTextEditWidget ctx;
1417   XEvent *event;
1418 {
1419   StartAction(ctx, event);
1420   _XwSetCursorPos(ctx, (*(ctx->text.source->scan))
1421 	 (ctx->text.source, ctx->text.insertPos, XwstLast,  XwsdRight, 1, TRUE)
1422 		  );
1423   EndAction(ctx);
1424 }
1425 
1426 /*--------------------------------------------------------------------------+*/
ScrollOneLineUp(ctx,event)1427 static void ScrollOneLineUp(ctx, event)
1428 /*--------------------------------------------------------------------------+*/
1429   XwTextEditWidget ctx;
1430   XEvent *event;
1431 {
1432   StartAction(ctx, event);
1433   _XtTextScroll(ctx, 1);
1434   EndAction(ctx);
1435 }
1436 
1437 /*--------------------------------------------------------------------------+*/
ScrollOneLineDown(ctx,event)1438 static void ScrollOneLineDown(ctx, event)
1439 /*--------------------------------------------------------------------------+*/
1440   XwTextEditWidget ctx;
1441   XEvent *event;
1442 {
1443   StartAction(ctx, event);
1444   _XtTextScroll(ctx, -1);
1445   EndAction(ctx);
1446 }
1447 
1448 /*--------------------------------------------------------------------------+*/
MoveNextPage(ctx,event)1449 static void MoveNextPage(ctx, event)
1450 /*--------------------------------------------------------------------------+*/
1451   XwTextEditWidget ctx;
1452   XEvent *event;
1453 {
1454   XwLineTablePtr  lt = &(ctx->text.lt) ;
1455   int cur_line;
1456   XwTextPosition line_offset, new_pos, lastpos = GETLASTPOS(ctx);
1457 
1458   StartAction(ctx, event);
1459   if (lt->info[(lt->lines)].position != (lastpos + 1)) {
1460     cur_line = LineForPosition(ctx, ctx->text.insertPos);
1461     line_offset = (ctx->text.insertPos - lt->info[cur_line].position);
1462     _XtTextScroll(ctx, max(1, lt->lines - 2));
1463     if (lt->info[cur_line].position > lastpos)
1464       cur_line = LineForPosition(ctx, lastpos);
1465     new_pos = (lt->info[cur_line].position + line_offset);
1466     new_pos = min(new_pos, lt->info[cur_line].drawPos);
1467     _XwSetCursorPos(ctx, new_pos);
1468   }
1469   EndAction(ctx);
1470 }
1471 
1472 /*--------------------------------------------------------------------------+*/
MovePreviousPage(ctx,event)1473 static void MovePreviousPage(ctx, event)
1474 /*--------------------------------------------------------------------------+*/
1475   XwTextEditWidget ctx;
1476   XEvent *event;
1477 { XwLineTablePtr  lt = &(ctx->text.lt) ;
1478   int cur_line = LineForPosition(ctx, ctx->text.insertPos);
1479   XwTextPosition line_offset =
1480                   (ctx->text.insertPos - lt->info[cur_line].position);
1481   XwTextPosition new_pos;
1482   StartAction(ctx, event);
1483   _XtTextScroll(ctx, -max(1, lt->lines - 2));
1484   new_pos = (lt->info[cur_line].position + line_offset);
1485   _XwSetCursorPos(ctx, min(new_pos, lt->info[cur_line].drawPos));
1486   EndAction(ctx);
1487 }
1488 
1489 /* delete routines */
1490 
1491 /*--------------------------------------------------------------------------+*/
DeleteForwardChar(ctx,event)1492 static void DeleteForwardChar(ctx, event)
1493 /*--------------------------------------------------------------------------+*/
1494   XwTextEditWidget ctx;
1495   XEvent *event;
1496 {
1497   XwTextPosition next;
1498 
1499   StartAction(ctx, event);
1500   next = (*(ctx->text.source->scan))(
1501             ctx->text.source, ctx->text.insertPos, XwstPositions,
1502 	    XwsdRight, 1, TRUE);
1503   DeleteOrKill(ctx, ctx->text.insertPos, next, FALSE);
1504   EndAction(ctx);
1505 }
1506 
1507 /*--------------------------------------------------------------------------+*/
DeleteBackwardNormal(ctx,event)1508 static void DeleteBackwardNormal(ctx, event)
1509 /*--------------------------------------------------------------------------+*/
1510   XwTextEditWidget ctx;
1511   XEvent *event;
1512 {
1513   /* If there's a selection, delete it, otherwise, delete the character */
1514 
1515   if (ctx->text.s.left != ctx->text.s.right)
1516      DeleteCurrentSelection(ctx, event);
1517   else
1518      DeleteBackwardChar(ctx, event);
1519 }
1520 
1521 /*--------------------------------------------------------------------------+*/
DeleteBackwardChar(ctx,event)1522 static void DeleteBackwardChar(ctx, event)
1523 /*--------------------------------------------------------------------------+*/
1524   XwTextEditWidget ctx;
1525   XEvent *event;
1526 {
1527   XwTextPosition next;
1528 
1529   StartAction(ctx, event);
1530   next = (*(ctx->text.source->scan))(
1531          ctx->text.source, ctx->text.insertPos, XwstPositions,
1532 	 XwsdLeft, 1, TRUE);
1533   DeleteOrKill(ctx, next, ctx->text.insertPos, FALSE);
1534   EndAction(ctx);
1535 }
1536 
1537 /*--------------------------------------------------------------------------+*/
DeleteForwardWord(ctx,event)1538 static void DeleteForwardWord(ctx, event)
1539 /*--------------------------------------------------------------------------+*/
1540   XwTextEditWidget ctx;
1541   XEvent *event;
1542 {
1543   XwTextPosition next;
1544 
1545   StartAction(ctx, event);
1546   next = NextPosition(ctx, ctx->text.insertPos, XwstWhiteSpace, XwsdRight);
1547   DeleteOrKill(ctx, ctx->text.insertPos, next, FALSE);
1548   EndAction(ctx);
1549 }
1550 
1551 /*--------------------------------------------------------------------------+*/
DeleteBackwardWord(ctx,event)1552 static void DeleteBackwardWord(ctx, event)
1553 /*--------------------------------------------------------------------------+*/
1554   XwTextEditWidget ctx;
1555   XEvent *event;
1556 {
1557   XwTextPosition next;
1558 
1559   StartAction(ctx, event);
1560   next = NextPosition(ctx, ctx->text.insertPos, XwstWhiteSpace, XwsdLeft);
1561   DeleteOrKill(ctx, next, ctx->text.insertPos, FALSE);
1562   EndAction(ctx);
1563 }
1564 
1565 /*--------------------------------------------------------------------------+*/
KillForwardWord(ctx,event)1566 static void KillForwardWord(ctx, event)
1567 /*--------------------------------------------------------------------------+*/
1568   XwTextEditWidget ctx;
1569   XEvent *event;
1570 {
1571   XwTextPosition next;
1572 
1573   StartAction(ctx, event);
1574   next = NextPosition(ctx, ctx->text.insertPos, XwstWhiteSpace, XwsdRight);
1575   DeleteOrKill(ctx, ctx->text.insertPos, next, TRUE);
1576   EndAction(ctx);
1577 }
1578 
1579 /*--------------------------------------------------------------------------+*/
KillBackwardWord(ctx,event)1580 static void KillBackwardWord(ctx, event)
1581 /*--------------------------------------------------------------------------+*/
1582   XwTextEditWidget ctx;
1583   XEvent *event;
1584 {
1585   XwTextPosition next;
1586 
1587   StartAction(ctx, event);
1588   next = NextPosition(ctx, ctx->text.insertPos, XwstWhiteSpace, XwsdLeft);
1589   DeleteOrKill(ctx, next, ctx->text.insertPos, TRUE);
1590   EndAction(ctx);
1591 }
1592 
1593 /*--------------------------------------------------------------------------+*/
KillCurrentSelection(ctx,event)1594 static void KillCurrentSelection(ctx, event)
1595 /*--------------------------------------------------------------------------+*/
1596   XwTextEditWidget ctx;
1597   XEvent *event;
1598 {
1599   StartAction(ctx, event);
1600   DeleteOrKill(ctx, ctx->text.s.left, ctx->text.s.right, TRUE);
1601   EndAction(ctx);
1602 }
1603 
1604 /*--------------------------------------------------------------------------+*/
DeleteCurrentSelection(ctx,event)1605 static void DeleteCurrentSelection(ctx, event)
1606 /*--------------------------------------------------------------------------+*/
1607   XwTextEditWidget ctx;
1608   XEvent *event;
1609 {
1610   StartAction(ctx, event);
1611   DeleteOrKill(ctx, ctx->text.s.left, ctx->text.s.right, FALSE);
1612   EndAction(ctx);
1613 }
1614 
1615 /*--------------------------------------------------------------------------+*/
KillToEndOfLine(ctx,event)1616 static void KillToEndOfLine(ctx, event)
1617 /*--------------------------------------------------------------------------+*/
1618   XwTextEditWidget ctx;
1619   XEvent *event;
1620 {
1621   int     line;
1622   XwTextPosition last, next, lastpos = GETLASTPOS(ctx);
1623   StartAction(ctx, event);
1624   _XtTextShowPosition(ctx);
1625   line = LineForPosition(ctx, ctx->text.insertPos);
1626   last = ctx->text.lt.info[line + 1].position;
1627   next = (*(ctx->text.source->scan))(ctx->text.source, ctx->text.insertPos,
1628        XwstEOL, XwsdRight, 1, FALSE);
1629   if (last > lastpos)
1630     last = lastpos;
1631   if (last > next && ctx->text.insertPos < next)
1632     last = next;
1633   DeleteOrKill(ctx, ctx->text.insertPos, last, TRUE);
1634   EndAction(ctx);
1635 }
1636 
1637 /*--------------------------------------------------------------------------+*/
KillToEndOfParagraph(ctx,event)1638 static void KillToEndOfParagraph(ctx, event)
1639 /*--------------------------------------------------------------------------+*/
1640   XwTextEditWidget ctx;
1641   XEvent *event;
1642 {
1643   XwTextPosition next;
1644 
1645   StartAction(ctx, event);
1646   next = (*(ctx->text.source->scan))(ctx->text.source, ctx->text.insertPos,
1647 				       XwstEOL, XwsdRight, 1, FALSE);
1648   if (next == ctx->text.insertPos)
1649     next = (*(ctx->text.source->scan))(ctx->text.source, next, XwstEOL,
1650 					   XwsdRight, 1, TRUE);
1651   DeleteOrKill(ctx, ctx->text.insertPos, next, TRUE);
1652   EndAction(ctx);
1653 }
1654 
1655 /*--------------------------------------------------------------------------+*/
InsertNewLineAndBackup(ctx,event)1656 static void InsertNewLineAndBackup(ctx, event)
1657 /*--------------------------------------------------------------------------+*/
1658   XwTextEditWidget ctx;
1659   XEvent *event;
1660 {
1661   StartAction(ctx, event);
1662   InsertNewLineAndBackupInternal(ctx);
1663   EndAction(ctx);
1664 }
1665 
1666 /*--------------------------------------------------------------------------+*/
InsertNewLine(ctx,event)1667 static XwEditResult InsertNewLine(ctx, event)
1668 /*--------------------------------------------------------------------------+*/
1669   XwTextEditWidget ctx;
1670   XEvent *event;
1671 {
1672   XwTextPosition next;
1673   XwEditResult result;
1674 
1675   StartAction(ctx, event);
1676   if (InsertNewLineAndBackupInternal(ctx)) {
1677     EndAction(ctx);
1678     return(XweditError);
1679   }
1680   next = (*(ctx->text.source->scan))(ctx->text.source, ctx->text.insertPos,
1681 	    XwstPositions, XwsdRight, 1, TRUE);
1682   result = _XwSetCursorPos(ctx, next);
1683   EndAction(ctx);
1684   return(result);
1685 }
1686 
1687 /*--------------------------------------------------------------------------+*/
InsertNewLineAndIndent(ctx,event)1688 static void InsertNewLineAndIndent(ctx, event)
1689 /*--------------------------------------------------------------------------+*/
1690   XwTextEditWidget ctx;
1691   XEvent *event;
1692 {
1693   XwTextBlock text;
1694   XwTextPosition pos1, pos2;
1695   XwEditResult result;
1696 
1697   StartAction(ctx, event);
1698   pos1 = (*(ctx->text.source->scan))(ctx->text.source, ctx->text.insertPos,
1699 				     XwstEOL, XwsdLeft, 1, FALSE);
1700   pos2 = (*(ctx->text.source->scan))(ctx->text.source, pos1, XwstEOL,
1701 				     XwsdLeft, 1, TRUE);
1702   pos2 = (*(ctx->text.source->scan))(ctx->text.source, pos2, XwstWhiteSpace,
1703 				     XwsdRight, 1, TRUE);
1704   text.ptr = _XwTextCopySubString(ctx, pos1, pos2);
1705   text.length = XwStrlen(text.ptr);
1706   if (InsertNewLine(ctx, event)) return;
1707   if (result =
1708 	ReplaceText(ctx, ctx->text.insertPos, ctx->text.insertPos,
1709 		    &text, TRUE)) {
1710     if (result != XweditReject)
1711       XBell(XtDisplay(ctx), 50);
1712     XtFree(text.ptr);
1713     EndAction(ctx);
1714     return;
1715   }
1716   _XwSetCursorPos(ctx, (*(ctx->text.source->scan))
1717                         (ctx->text.source, ctx->text.insertPos, XwstPositions,
1718 			 XwsdRight, text.length, TRUE));
1719   XtFree(text.ptr);
1720   EndAction(ctx);
1721 }
1722 
1723 /*--------------------------------------------------------------------------+*/
NewSelection(ctx,l,r)1724 static void NewSelection(ctx, l, r)
1725 /*--------------------------------------------------------------------------+*/
1726   XwTextEditWidget ctx;
1727   XwTextPosition l, r;
1728 {
1729   unsigned char   *ptr;
1730   _XtTextSetNewSelection(ctx, l, r);
1731   if (l < r) {
1732     ptr = _XwTextCopySubString(ctx, l, r);
1733     XStoreBuffer(XtDisplay(ctx), ptr, min(XwStrlen(ptr), MAXCUT), 0);
1734     XtFree(ptr);
1735   }
1736 }
1737 
1738 /*--------------------------------------------------------------------------+*/
SelectWord(ctx,event)1739 static void SelectWord(ctx, event)
1740 /*--------------------------------------------------------------------------+*/
1741   XwTextEditWidget ctx;
1742   XEvent *event;
1743 {
1744   XwTextPosition l, r;
1745   StartAction(ctx, event);
1746   l = (*(ctx->text.source->scan))(ctx->text.source, ctx->text.insertPos,
1747 				  XwstWhiteSpace, XwsdLeft, 1, FALSE);
1748   r = (*(ctx->text.source->scan))(ctx->text.source, l, XwstWhiteSpace,
1749 				  XwsdRight, 1, FALSE);
1750   NewSelection(ctx, l, r);
1751   EndAction(ctx);
1752 }
1753 
1754 /*--------------------------------------------------------------------------+*/
SelectAll(ctx,event)1755 static void SelectAll(ctx, event)
1756 /*--------------------------------------------------------------------------+*/
1757   XwTextEditWidget ctx;
1758   XEvent *event;
1759 {
1760   StartAction(ctx, event);
1761   NewSelection(ctx, (XwTextPosition) 0, GETLASTPOS(ctx));
1762   EndAction(ctx);
1763 }
1764 
1765 /*--------------------------------------------------------------------------+*/
SelectStart(ctx,event)1766 static void SelectStart(ctx, event)
1767 /*--------------------------------------------------------------------------+*/
1768   XwTextEditWidget ctx;
1769   XEvent *event;
1770 {
1771   StartAction(ctx, event);
1772   AlterSelection(ctx, XwsmTextSelect, XwactionStart);
1773   EndAction(ctx);
1774 }
1775 
1776 /*--------------------------------------------------------------------------+*/
SelectAdjust(ctx,event)1777 static void SelectAdjust(ctx, event)
1778 /*--------------------------------------------------------------------------+*/
1779   XwTextEditWidget ctx;
1780   XEvent *event;
1781 {
1782   StartAction(ctx, event);
1783   AlterSelection(ctx, XwsmTextSelect, XwactionAdjust);
1784   EndAction(ctx);
1785 }
1786 
1787 /*--------------------------------------------------------------------------+*/
SelectEnd(ctx,event)1788 static void SelectEnd(ctx, event)
1789 /*--------------------------------------------------------------------------+*/
1790   XwTextEditWidget ctx;
1791   XEvent *event;
1792 {
1793   StartAction(ctx, event);
1794   AlterSelection(ctx, XwsmTextSelect, XwactionEnd);
1795   EndAction(ctx);
1796 }
1797 
1798 /*--------------------------------------------------------------------------+*/
ExtendStart(ctx,event)1799 static void ExtendStart(ctx, event)
1800 /*--------------------------------------------------------------------------+*/
1801   XwTextEditWidget ctx;
1802   XEvent *event;
1803 {
1804   StartAction(ctx, event);
1805   AlterSelection(ctx, XwsmTextExtend, XwactionStart);
1806   EndAction(ctx);
1807 }
1808 
1809 /*--------------------------------------------------------------------------+*/
ExtendAdjust(ctx,event)1810 static void ExtendAdjust(ctx, event)
1811 /*--------------------------------------------------------------------------+*/
1812   XwTextEditWidget ctx;
1813   XEvent *event;
1814 {
1815   StartAction(ctx, event);
1816   AlterSelection(ctx, XwsmTextExtend, XwactionAdjust);
1817   EndAction(ctx);
1818 }
1819 
1820 /*--------------------------------------------------------------------------+*/
ExtendEnd(ctx,event)1821 static void ExtendEnd(ctx, event)
1822 /*--------------------------------------------------------------------------+*/
1823   XwTextEditWidget ctx;
1824   XEvent *event;
1825 {
1826   StartAction(ctx, event);
1827   AlterSelection(ctx, XwsmTextExtend, XwactionEnd);
1828   EndAction(ctx);
1829 }
1830 
1831 /*--------------------------------------------------------------------------+*/
RedrawDisplay(ctx,event)1832 static void RedrawDisplay(ctx, event)
1833 /*--------------------------------------------------------------------------+*/
1834   XwTextEditWidget ctx;
1835   XEvent *event;
1836 {
1837   StartAction(ctx, event);
1838   ForceBuildLineTable(ctx);
1839   DisplayAllText(ctx);
1840   ClearWindow(ctx);
1841   EndAction(ctx);
1842 /* This seems like the wrong place for this */
1843   if (ctx->primitive.highlighted)
1844      _XwHighlightBorder(ctx);
1845 }
1846 
1847 #define STRBUFSIZE 100
1848 static XComposeStatus compose_status = {NULL, 0};
1849 
1850 /*--------------------------------------------------------------------------+*/
InsertChar(ctx,event)1851 static void InsertChar(ctx, event)
1852 /*--------------------------------------------------------------------------+*/
1853   XwTextEditWidget ctx;
1854   XEvent *event;
1855 {
1856   unsigned char strbuf[STRBUFSIZE];
1857   KeySym keysym;
1858   XwEditResult result;
1859   XwTextBlock text;
1860 
1861   text.length = XLookupString ((XKeyEvent *)event, strbuf, STRBUFSIZE,
1862 			       &keysym, &compose_status);
1863   if (text.length==0) return;
1864   StartAction(ctx, event);
1865   text.ptr = &strbuf[0];;
1866   text.firstPos = 0;
1867   if (result =
1868       ReplaceText(ctx, ctx->text.insertPos, ctx->text.insertPos,
1869 		  &text, TRUE)) {
1870     if (result != XweditReject)
1871       XBell(XtDisplay(ctx), 50);
1872     EndAction(ctx);
1873     return;
1874   }
1875   _XwSetCursorPos(ctx,
1876 	(*(ctx->text.source->scan))(ctx->text.source, ctx->text.insertPos,
1877 			           XwstPositions, XwsdRight, text.length, TRUE));
1878   _XtTextSetNewSelection(ctx, ctx->text.insertPos, ctx->text.insertPos);
1879 
1880   EndAction(ctx);
1881 }
1882 
1883 /*--------------------------------------------------------------------------+*/
Execute(ctx,event)1884 static void Execute(ctx, event)
1885 /*--------------------------------------------------------------------------+*/
1886      XwTextEditWidget ctx;
1887      XEvent           *event;
1888 {
1889 
1890   XtCallCallbacks((Widget)ctx, XtNexecute, NULL);
1891 
1892 }
1893 
1894 /*************************************************************************
1895 *
1896 * Class Record Support Functions
1897 *
1898 *************************************************************************/
1899 
1900 /******************************************************************************
1901 *
1902 *  Class Record Functions
1903 *
1904 ******************************************************************************/
1905 
1906 /*--------------------------------------------------------------------------+*/
ClassInitialize()1907 static void ClassInitialize()
1908 /*--------------------------------------------------------------------------+*/
1909 {
1910 
1911 
1912 } /* ClassInitialize */
1913 
1914 
1915 
1916 /******************************************************************************
1917 *
1918 *  External functions (Methods???) on the class
1919 *
1920 ******************************************************************************/
1921 
1922 /*--------------------------------------------------------------------------+*/
XwTextClearBuffer(w)1923 void XwTextClearBuffer(w)
1924 /*--------------------------------------------------------------------------+*/
1925     XwTextEditWidget w;
1926 {
1927   _XtTextPrepareToUpdate(w);
1928   (*(w->text.source->setLastPos))(w->text.source, (XwTextPosition)0);
1929   w->text.insertPos = 0;
1930   ForceBuildLineTable(w);
1931   DisplayAllText(w);
1932   _XtTextExecuteUpdate(w);
1933 }
1934 
1935 /*--------------------------------------------------------------------------+*/
XwTextCopyBuffer(w)1936 unsigned char *XwTextCopyBuffer(w)
1937 /*--------------------------------------------------------------------------+*/
1938    XwTextEditWidget w;
1939 {
1940 
1941   return (*((XwTextEditClassRec *)(w->core.widget_class))->textedit_class.copy_substring)
1942            ((XwTextEditWidget)w, 0, GETLASTPOS(w));
1943 
1944 }
1945 
1946 /*--------------------------------------------------------------------------+*/
XwTextCopySelection(w)1947 unsigned char *XwTextCopySelection(w)
1948 /*--------------------------------------------------------------------------+*/
1949    XwTextEditWidget w;
1950 {
1951   return (*((XwTextEditClassRec *)(w->core.widget_class))->textedit_class.copy_selection)
1952     ((XwTextEditWidget)w);
1953 }
1954 
1955 /*--------------------------------------------------------------------------+*/
XwTextReadSubString(w,startpos,endpos,target,targetsize,targetused)1956 int XwTextReadSubString( w, startpos, endpos, target, targetsize, targetused )
1957 /*--------------------------------------------------------------------------+*/
1958   XwTextEditWidget  w;
1959   XwTextPosition    startpos, endpos;
1960   unsigned char     *target;
1961   int               targetsize,
1962                     *targetused;
1963 {
1964   return( _XwTextSubString(w, startpos, endpos, target, targetsize, targetused) );
1965 
1966 }
1967 
1968 /*--------------------------------------------------------------------------+*/
XwTextUnsetSelection(w)1969 void XwTextUnsetSelection(w)
1970 /*--------------------------------------------------------------------------+*/
1971     XwTextEditWidget w;
1972 {
1973  (*((XwTextEditClassRec *)(w->core.widget_class))->textedit_class.unset_selection)
1974              ((Widget)w);
1975 }
1976 
1977 /*--------------------------------------------------------------------------+*/
XwTextSetSelection(w,left,right)1978 void XwTextSetSelection(w, left, right)
1979 /*--------------------------------------------------------------------------+*/
1980   XwTextEditWidget  w;
1981   XwTextPosition    left, right;
1982 {
1983   (*((XwTextEditClassRec *)(w->core.widget_class))->textedit_class.set_selection)
1984     ((Widget)w, left, right);
1985 }
1986 
1987 /*--------------------------------------------------------------------------+*/
XwTextReplace(w,startPos,endPos,string)1988 XwEditResult XwTextReplace(w, startPos, endPos, string)
1989 /*--------------------------------------------------------------------------+*/
1990     XwTextEditWidget w;
1991     XwTextPosition   startPos, endPos;
1992     unsigned char    *string;
1993 {
1994   XwTextBlock blk;
1995 
1996   blk.ptr = string;
1997   blk.length = XwStrlen(string);
1998   blk.firstPos = (XwTextPosition)0;
1999 
2000   return (*((XwTextEditClassRec *)(w->core.widget_class))->textedit_class.replace_text)
2001     (w, startPos, endPos, &blk, FALSE);
2002 }
2003 
2004 /*--------------------------------------------------------------------------+*/
XwTextRedraw(w)2005 void XwTextRedraw(w)
2006 /*--------------------------------------------------------------------------+*/
2007     XwTextEditWidget w;
2008 {
2009   (*((XwTextEditClassRec *)(w->core.widget_class))->textedit_class.redraw_text)
2010      ((Widget)w);
2011 }
2012 
2013 /*--------------------------------------------------------------------------+*/
XwTextResize(w)2014 void XwTextResize(w)
2015 /*--------------------------------------------------------------------------+*/
2016     XwTextEditWidget w;
2017 {
2018     _XtTextPrepareToUpdate(w);
2019     CheckResizeOrOverflow(w);
2020     _XtTextExecuteUpdate(w);
2021 }
2022 
2023 /*--------------------------------------------------------------------------+*/
XwTextUpdate(w,status)2024 void XwTextUpdate( w, status )
2025 /*--------------------------------------------------------------------------+*/
2026     XwTextEditWidget w;
2027     Boolean status;
2028 {
2029    w->text.update_flag = status;
2030    if (status) {
2031      _XtTextExecuteUpdate(w);
2032    }
2033    else {
2034      w->text.numranges = 0;
2035      w->text.showposition = FALSE;
2036      w->text.oldinsert = w->text.insertPos;
2037      if ( XtIsRealized((Widget)w) ) InsertCursor(w, XwisOff);
2038    }
2039 }
2040 
2041 
2042 /*--------------------------------------------------------------------------+*/
XwTextInsert(w,string)2043 void XwTextInsert(w, string)
2044 /*--------------------------------------------------------------------------+*/
2045      XwTextEditWidget w;
2046      unsigned char *string;
2047 {
2048      XwTextBlock blk;
2049 
2050      blk.ptr = string;
2051      blk.length = XwStrlen(string);
2052      blk.firstPos = (XwTextPosition) 0;
2053 
2054     _XtTextPrepareToUpdate(w);
2055     if (ReplaceText(w, w->text.insertPos,
2056 		    w->text.insertPos, &blk, FALSE) == XweditDone) {
2057       w->text.showposition = TRUE;
2058       w->text.insertPos = w->text.insertPos + blk.length;
2059     }
2060     _XtTextExecuteUpdate(w);
2061 
2062 }
2063 
2064 /*--------------------------------------------------------------------------+*/
XwTextGetLastPos(w)2065 XwTextPosition XwTextGetLastPos (w)
2066 /*--------------------------------------------------------------------------+*/
2067     XwTextEditWidget w;
2068 {
2069     return( GETLASTPOS(w) );
2070 }
2071 
2072 /*--------------------------------------------------------------------------+*/
XwTextGetSelectionPos(w,left,right)2073 void XwTextGetSelectionPos(w, left, right)
2074 /*--------------------------------------------------------------------------+*/
2075      XwTextEditWidget w;
2076      XwTextPosition *left, *right;
2077 {
2078 
2079   *left = w->text.s.left;
2080   *right = w->text.s.right;
2081 }
2082 
2083 /*--------------------------------------------------------------------------+*/
XwTextSetInsertPos(w,position)2084 void XwTextSetInsertPos(w, position)
2085 /*--------------------------------------------------------------------------+*/
2086      XwTextEditWidget w;
2087      XwTextPosition position;
2088 {
2089 
2090   _XtTextPrepareToUpdate(w);
2091   w->text.insertPos = position;
2092   w->text.showposition = TRUE;
2093   _XtTextExecuteUpdate(w);
2094 }
2095 
2096 /*--------------------------------------------------------------------------+*/
XwTextGetInsertPos(w)2097 XwTextPosition XwTextGetInsertPos(w)
2098 /*--------------------------------------------------------------------------+*/
2099      XwTextEditWidget w;
2100 {
2101 
2102   return( w->text.insertPos );
2103 
2104 }
2105 
2106 /*--------------------------------------------------------------------------+*/
XwTextSetSource(w,source,startpos)2107 void XwTextSetSource(w, source, startpos)
2108 /*--------------------------------------------------------------------------+*/
2109      XwTextEditWidget w;
2110      XwTextSourcePtr source;
2111      XwTextPosition startpos;
2112 {
2113 
2114   w->text.source = source;
2115   w->text.lt.top = startpos;
2116   w->text.s.left = w->text.s.right = 0;
2117   w->text.insertPos = startpos;
2118 
2119   ForceBuildLineTable(w);
2120   if (XtIsRealized((Widget)w)) {
2121     _XtTextPrepareToUpdate(w);
2122     DisplayAllText(w);
2123     _XtTextExecuteUpdate(w);
2124   }
2125 }
2126 /* Not advertised. Don't think it is necessary */
2127 /*--------------------------------------------------------------------------+*/
XwTextCopySubString(w,left,right)2128 unsigned char *XwTextCopySubString(w, left, right)
2129 /*--------------------------------------------------------------------------+*/
2130   XwTextEditWidget w;
2131   XwTextPosition left, right;
2132 {
2133   return (*((XwTextEditClassRec *)(w->core.widget_class))->textedit_class.copy_substring)
2134     ((XwTextEditWidget)w, left, right);
2135 }
2136 
2137 /*--------------------------------------------------------------------------+*/
XwTextInvalidate(w,from,to)2138 void XwTextInvalidate(w, from, to)
2139 /*--------------------------------------------------------------------------+*/
2140     XwTextEditWidget     w;
2141     XwTextPosition       from,to;
2142 {
2143         _XtTextPrepareToUpdate(w);
2144         _XtTextNeedsUpdating(w, from, to);
2145         ForceBuildLineTable(w);
2146         _XtTextExecuteUpdate(w);
2147 }
2148 
2149 /*--------------------------------------------------------------------------+*/
XwTextTopPosition(w)2150 XwTextPosition XwTextTopPosition(w)
2151 /*--------------------------------------------------------------------------+*/
2152     XwTextEditWidget  w;
2153 {
2154      return w->text.lt.top;
2155 }
2156 
2157 /*****************************************************************************
2158 *  Class Functions
2159 *****************************************************************************/
2160 
2161 /*--------------------------------------------------------------------------+*/
Initialize(request,new)2162 static void Initialize(request, new)
2163 /*--------------------------------------------------------------------------+*/
2164  Widget request, new;
2165 {
2166     XwTextEditWidget ctx = (XwTextEditWidget)new;
2167     XwTextEditPart *text = &(ctx->text);
2168 
2169     text->lt.lines = 0;
2170     text->lt.info = NULL;
2171     text->s.left = text->s.right = 0;
2172     text->s.type = XwselectPosition;
2173     text->sarray[0] = XwselectPosition;
2174     text->sarray[1] = XwselectWord;
2175     text->sarray[2] = XwselectLine;
2176     text->sarray[3] = XwselectParagraph;
2177     text->sarray[4] = XwselectAll;
2178     text->sarray[5] = XwselectNull;
2179     text->lasttime = 0; /* ||| correct? */
2180     text->time = 0; /* ||| correct? */
2181 
2182     text->oldinsert = -1 ;
2183     text->update_flag = FALSE;
2184     text->showposition = TRUE;
2185     text->updateFrom = (XwTextPosition *) XtMalloc(sizeof(XwTextPosition));
2186     text->updateTo = (XwTextPosition *) XtMalloc(sizeof(XwTextPosition));
2187     text->numranges = text->maxranges = 0;
2188     text->gc = DefaultGCOfScreen(XtScreen(ctx));
2189     text->hasfocus = FALSE;
2190     text->scroll_state = text->scroll_mode ;
2191     text->grow_state = text->grow_mode ;
2192     text->prevW = ctx->core.width ;
2193     text->prevH = ctx->core.height ;
2194     if (text->grow_mode & XwGrowHorizontal)
2195       {	text->wrap_mode = XwWrapOff ;
2196       } ;
2197     if (text->wrap_mode == XwWrapOff)
2198       { text->wrap_form = XwSourceForm ;
2199 	text->wrap_break = XwWrapAny ;
2200       } ;
2201 
2202 #ifdef GLSDEBUG
2203     fprintf (stderr, "%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %x\n"
2204 	     , "  wrap mode", text->wrap_mode
2205 	     , "  wrap form", text->wrap_form
2206 	     , " wrap break", text->wrap_break
2207 	     , "scroll mode", text->scroll_mode
2208 	     , "  grow mode", text->grow_mode
2209 	     , "    options", text->options
2210 	     ) ;
2211 #endif
2212 }
2213 
2214 /*--------------------------------------------------------------------------+*/
InitializeHook(widget,args,num_args)2215 static void InitializeHook(widget, args, num_args)
2216 /*--------------------------------------------------------------------------+*/
2217    Widget widget;
2218    ArgList args;
2219    Cardinal *num_args;
2220 { XwTextEditWidget ctx = (XwTextEditWidget)widget;
2221   register XwTextEditPart *text = &(ctx->text);
2222 
2223   text->sink = XwAsciiSinkCreate(widget, args, *num_args);
2224 
2225   if (text->srctype == XwstringSrc)
2226     text->source = XwStringSourceCreate(widget, args, *num_args);
2227   else if (text->srctype != XwprogDefinedSrc)
2228     {XtWarning("XwSourceType not recognized. Using XwstringSrc.");
2229      text->source = XwStringSourceCreate(widget, args, *num_args);
2230    };
2231 
2232   ForceBuildLineTable((XwTextEditWidget)widget);
2233   if (text->lt.lines > 1)
2234     { text->scroll_state &= ~XwAutoScrollHorizontal ;
2235     }
2236 }
2237 
2238 /*--------------------------------------------------------------------------+*/
TextDestroy(ctx)2239 static void TextDestroy(ctx)
2240 /*--------------------------------------------------------------------------+*/
2241      XwTextEditWidget ctx;
2242 {
2243   (*(ctx->text.source->destroy))(ctx->text.source);
2244   (*(ctx->text.sink->destroy))(ctx->text.sink);
2245   XtFree((char *)ctx->text.updateFrom);
2246   XtFree((char *)ctx->text.updateTo);
2247   XtRemoveAllCallbacks((Widget)ctx, XtNmotionVerification);
2248   XtRemoveAllCallbacks((Widget)ctx, XtNmodifyVerification);
2249   XtRemoveAllCallbacks((Widget)ctx, XtNleaveVerification);
2250 }
2251 
2252 
2253 /*--------------------------------------------------------------------------+*/
Resize(w)2254 static void Resize(w)
2255 /*--------------------------------------------------------------------------+*/
2256     Widget          w;
2257 {
2258     XwTextEditWidget ctx = (XwTextEditWidget) w;
2259     XwTextEditPart   *tp ;
2260     Dimension width, height ;
2261     Boolean          realized = XtIsRealized(w);
2262 
2263     tp = &(ctx->text) ;
2264     width = ctx->core.width ;
2265     if ((width < tp->prevW)  && (tp->grow_mode & XwGrowHorizontal))
2266       tp->grow_state |= XwGrowHorizontal ;
2267     height = ctx->core.height ;
2268     if ((height < tp->prevH)  && (tp->grow_mode & XwGrowVertical))
2269       tp->grow_state |= XwGrowVertical ;
2270 
2271     if (realized) _XtTextPrepareToUpdate(ctx);
2272     ForceBuildLineTable(ctx);
2273 
2274     if (tp->lt.lines > 1)
2275       { tp->scroll_state &= ~XwAutoScrollHorizontal ;
2276       }
2277     else
2278       { tp->scroll_state |=  tp->scroll_mode & XwAutoScrollHorizontal ;
2279       }
2280 
2281     if (realized)
2282     {
2283 	DisplayAllText(ctx);
2284         ClearWindow(ctx);
2285     }
2286 
2287     if (realized) _XtTextExecuteUpdate(ctx);
2288 }
2289 
2290 /*--------------------------------------------------------------------------+*/
SetValues(current,request,new)2291 static Boolean SetValues(current, request, new)
2292 /*--------------------------------------------------------------------------+*/
2293 Widget current, request, new;
2294 {
2295     XwTextEditWidget oldtw = (XwTextEditWidget) current;
2296     XwTextEditWidget newtw = (XwTextEditWidget) new;
2297     Boolean    redisplay = FALSE;
2298     XwTextEditPart *oldtext = &(oldtw->text);
2299     XwTextEditPart *newtext = &(newtw->text);
2300     Boolean realized = XtIsRealized(current);
2301 
2302     if (realized) _XtTextPrepareToUpdate(oldtw);
2303 
2304     if (oldtext->source != newtext->source) {
2305 	ForceBuildLineTable(oldtw);
2306 	if ((oldtext->s.left == newtext->s.left) &&
2307 	    (oldtext->s.right == newtext->s.right)) {
2308 	  newtext->s.left = (XwTextPosition) 0;
2309 	  newtext->s.right = (XwTextPosition) 0;
2310 	}
2311 	redisplay = TRUE;
2312     }
2313 
2314     if (oldtext->sink != newtext->sink)
2315 	redisplay = TRUE;
2316 
2317     if (oldtext->insertPos != newtext->insertPos)
2318 	oldtext->showposition = TRUE;
2319 
2320     if (oldtext->lt.top != newtext->lt.top)
2321 	redisplay = TRUE;
2322 
2323     if ((oldtext->leftmargin != newtext->leftmargin) ||
2324 	(oldtext->topmargin != newtext->topmargin) ||
2325 	(oldtext->rightmargin != newtext->rightmargin) ||
2326 	(oldtext->bottommargin != newtext->bottommargin))
2327 	redisplay = TRUE;
2328 
2329     if ((oldtext->s.left != newtext->s.left) ||
2330 	(oldtext->s.right != newtext->s.right)) {
2331       if (newtext->s.left > newtext->s.right) {
2332 	XwTextPosition temp = newtext->s.right;
2333 	newtext->s.right = newtext->s.left;
2334 	newtext->s.left = temp;
2335 	redisplay = TRUE;
2336       }
2337     }
2338 
2339 
2340     /* ||| This may be the best way to do this, as some optimizations
2341      *     can occur here that may be harder if we let XtSetValues
2342      *     call our expose proc.
2343      */
2344 
2345     if (redisplay && realized)
2346 	DisplayAllText(newtw);
2347 
2348     if (realized) _XtTextExecuteUpdate(newtw);
2349 
2350     return ( FALSE );
2351 }
2352 
2353 /*--------------------------------------------------------------------------+*/
SetValuesHook(widget,args,num_args)2354 static Boolean SetValuesHook(widget, args, num_args)
2355 /*--------------------------------------------------------------------------+*/
2356   Widget widget;
2357   ArgList args;
2358   Cardinal *num_args;
2359 {
2360   XwTextEditWidget ctx = (XwTextEditWidget)widget;
2361   XwTextSource *source = ctx->text.source;
2362   XwTextSink   *sink   = ctx->text.sink;
2363   Boolean realized = XtIsRealized(widget);
2364 
2365   if (realized) _XtTextPrepareToUpdate(ctx);
2366 
2367   /* This is ugly, but need to know if user set initial_string */
2368   ((StringSourcePtr)(source->data))->initial_string = NULL;
2369 
2370   XtSetSubvalues(source->data, source->resources,
2371 		 source->resource_num, args, *num_args);
2372   XtSetSubvalues(sink->data, sink->resources,
2373 		 sink->resource_num, args, *num_args);
2374 
2375   (*(source->check_data))(source);
2376 
2377   ForceBuildLineTable(ctx);
2378   if (realized) {
2379     DisplayAllText(ctx);
2380     _XtTextExecuteUpdate(ctx);
2381   }
2382 
2383   return( FALSE );
2384 }
2385 
2386 /*--------------------------------------------------------------------------+*/
GetValuesHook(widget,args,num_args)2387 static void GetValuesHook(widget, args, num_args)
2388 /*--------------------------------------------------------------------------+*/
2389   Widget widget;
2390   ArgList args;
2391   Cardinal *num_args;
2392 {
2393   XwTextSource *source = ((XwTextEditWidget)widget)->text.source;
2394   XwTextSink *sink = ((XwTextEditWidget)widget)->text.sink;
2395   int i = 0;
2396 
2397   /* This is ugly, but have to get internal buffer to initial_string storage */
2398   while (i < *num_args) {
2399     if (strcmp(args[i].name, XtNstring) == 0) {
2400       ((StringSourcePtr)(source->data))->initial_string =
2401 	XwTextCopyBuffer((XwTextEditWidget)widget);
2402       break;
2403     };
2404     i++;
2405   };
2406 
2407   XtGetSubvalues(source->data, source->resources, source->resource_num,
2408 			 args, *num_args);
2409   XtGetSubvalues(sink->data, sink->resources, sink->resource_num,
2410 			 args, *num_args);
2411 }
2412 
2413 /*--------------------------------------------------------------------------+*/
Realize(w,valueMask,attributes)2414 static void Realize( w, valueMask, attributes )
2415 /*--------------------------------------------------------------------------+*/
2416    Widget w;
2417    Mask *valueMask;
2418    XSetWindowAttributes *attributes;
2419 {
2420    XwTextEditWidget ctx = (XwTextEditWidget)w;
2421 
2422    *valueMask |= CWBitGravity;
2423    attributes->bit_gravity = NorthWestGravity;
2424 
2425    XtCreateWindow( w, InputOutput, (Visual *)CopyFromParent,
2426 		   *valueMask, attributes);
2427    if (XtIsRealized(w)) {
2428      XDefineCursor( w->core.screen->display, w->core.window,
2429 		   XCreateFontCursor( w->core.screen->display, XC_left_ptr));
2430      ctx->text.update_flag = TRUE;
2431    }
2432    else {
2433      XtWarning("Unable to realize TextEdit");
2434    }
2435    _XwRegisterName(w);
2436 }
2437 
2438 
2439 /*****************************************************************************
2440 *
2441 *  Text Edit Class Record
2442 *
2443 *****************************************************************************/
2444 XwTextEditClassRec XwtexteditClassRec = {
2445   {
2446     /* core fields */
2447     /* superclass       */      (WidgetClass) &XwprimitiveClassRec,
2448     /* class_name       */      "XwTextEdit",
2449     /* widget_size      */      sizeof(XwTextEditRec),
2450     /* class_initialize */      ClassInitialize,
2451     /* class_part_init  */      NULL,
2452     /* class_inited     */      FALSE,
2453     /* initialize       */      (XtInitProc)Initialize,
2454     /* initialize_hook  */      InitializeHook,
2455     /* realize          */      Realize,
2456     /* actions          */      texteditActionsTable,
2457     /* num_actions      */      XtNumber(texteditActionsTable),
2458     /* resources        */      resources,
2459     /* num_ resource    */      XtNumber(resources),
2460     /* xrm_class        */      NULLQUARK,
2461     /* compress_motion  */      TRUE,
2462     /* compress_exposure*/      FALSE,
2463     /* compress_enterleave*/    TRUE,
2464     /* visible_interest */      FALSE,
2465     /* destroy          */      (XtWidgetProc)TextDestroy,
2466     /* resize           */      Resize,
2467     /* expose           */      (XtExposeProc)ProcessExposeRegion,
2468     /* set_values       */      (XtSetValuesFunc)SetValues,
2469     /* set_values_hook  */      SetValuesHook,
2470     /* set_values_almost*/      XtInheritSetValuesAlmost,
2471     /* get_values_hook  */      GetValuesHook,
2472     /* accept_focus     */      NULL,
2473     /* version          */      XtVersion,
2474     /* callback_private */      NULL,
2475     /* tm_table         */      defaultTextEditTranslations,
2476     /* query_geometry   */      NULL,
2477     /* display_accelerator	*/	XtInheritDisplayAccelerator,
2478     /* extension		*/	NULL
2479   },
2480   {
2481     /* XwPrimitive fields */
2482 
2483     (XtWidgetProc)   NULL,
2484     (XtWidgetProc)   NULL,
2485     (XwEventProc)    NULL,
2486     (XwEventProc)    NULL,
2487     (XwEventProc)    NULL,
2488     (XtTranslations) NULL
2489   },
2490   {
2491     /* XwTextEdit fields */
2492     /* copy_substring    */     _XwTextCopySubString,
2493     /* copy_selection    */	_XwTextCopySelection,
2494     /* unset_selection   */     _XwTextUnsetSelection,
2495     /* set_selection     */     (XwSetSProc)_XwTextSetSelection,
2496     /* replace_text      */	_XwTextReplace,
2497     /* redraw_text       */	_XwTextRedraw,
2498   }
2499 };
2500 
2501 WidgetClass XwtexteditWidgetClass = (WidgetClass)&XwtexteditClassRec;
2502 WidgetClass XwtextEditWidgetClass = (WidgetClass)&XwtexteditClassRec;
2503 
2504