1 /*************************************<+>*************************************
2 *****************************************************************************
8 ** Description: Code for TextEdit widget
10 *****************************************************************************
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
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.
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
34 *****************************************************************************
35 *************************************<+>*************************************/
47 #include <X11/cursorfont.h>
48 #include <X11/IntrinsicP.h>
49 #include <X11/StringDefs.h>
53 #include <Xw/TextEdit.h>
54 #include <Xw/TextEditP.h>
55 #include <X11/Xutil.h> /* This include depends on something above it */
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))
63 #define BUTTONMASK 0x143d
65 #define zeroPosition ((XwTextPosition) 0)
67 /******************************************************************************
69 * Resources for TextEdit
71 ******************************************************************************/
73 static XtResource resources
[] = {
74 /* Resources from other classes with new defaults */
79 XtOffset(XwTextEditWidget
, core
.height
),
86 XtOffset(XwTextEditWidget
, core
.width
),
89 /* New resources for TextEdit */
93 sizeof (XwTextPosition
),
94 XtOffset(XwTextEditWidget
, text
.lt
.top
),
99 sizeof(XwTextPosition
),
100 XtOffset(XwTextEditWidget
, text
.insertPos
),
107 XtOffset(XwTextEditWidget
, text
.leftmargin
),
114 XtOffset(XwTextEditWidget
, text
.rightmargin
),
121 XtOffset(XwTextEditWidget
, text
.topmargin
),
128 XtOffset(XwTextEditWidget
, text
.bottommargin
),
134 sizeof(XwSourceType
),
135 XtOffset(XwTextEditWidget
, text
.srctype
),
142 XtOffset(XwTextEditWidget
, text
.source
),
149 XtOffset(XwTextEditWidget
, text
.s
),
152 {XtNmotionVerification
,
155 sizeof(XtCallbackProc
),
156 XtOffset(XwTextEditWidget
, text
.motion_verification
),
159 {XtNmodifyVerification
,
162 sizeof(XtCallbackProc
),
163 XtOffset(XwTextEditWidget
, text
.modify_verification
),
166 {XtNleaveVerification
,
169 sizeof(XtCallbackProc
),
170 XtOffset(XwTextEditWidget
, text
.leave_verification
),
176 sizeof(XtCallbackProc
),
177 XtOffset(XwTextEditWidget
, text
.execute
),
184 XtOffset (XwTextEditWidget
, text
.wrap_mode
),
191 XtOffset (XwTextEditWidget
, text
.wrap_form
),
197 sizeof (XwWrapBreak
),
198 XtOffset (XwTextEditWidget
, text
.wrap_break
),
205 XtOffset (XwTextEditWidget
, text
.scroll_mode
),
212 XtOffset (XwTextEditWidget
, text
.grow_mode
),
218 /******************************************************************************
220 * Forward declarations of functions to put into the class record
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();
231 /******************************************************************************
233 * Forward declarations of action functions to put into the action table
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();
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();
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();
292 /******************************************************************************
294 * TextEdit Actions Table
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
},
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 */
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
},
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
},
360 {"execute", Execute
},
364 /****************************************************************************
366 * TextEdit Default Event Translations
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()";
436 /* Utility routines for support of TextEdit */
439 /******************************************************************************
441 * Functions to support selection
443 ******************************************************************************/
444 /*--------------------------------------------------------------------------+*/
445 static void _XtTextSetNewSelection(ctx
, left
, right
)
446 /*--------------------------------------------------------------------------+*/
447 XwTextEditWidget ctx
;
448 XwTextPosition left
, right
;
452 if (left
< ctx
->text
.s
.left
) {
453 pos
= min(right
, ctx
->text
.s
.left
);
454 _XtTextNeedsUpdating(ctx
, left
, pos
);
456 if (left
> ctx
->text
.s
.left
) {
457 pos
= min(left
, ctx
->text
.s
.right
);
458 _XtTextNeedsUpdating(ctx
, ctx
->text
.s
.left
, pos
);
460 if (right
< ctx
->text
.s
.right
) {
461 pos
= max(right
, ctx
->text
.s
.left
);
462 _XtTextNeedsUpdating(ctx
, pos
, ctx
->text
.s
.right
);
464 if (right
> ctx
->text
.s
.right
) {
465 pos
= max(left
, ctx
->text
.s
.right
);
466 _XtTextNeedsUpdating(ctx
, pos
, right
);
469 ctx
->text
.s
.left
= left
;
470 ctx
->text
.s
.right
= right
;
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.]
483 /*--------------------------------------------------------------------------+*/
484 static void DoSelection (ctx
, position
, time
, motion
)
485 /*--------------------------------------------------------------------------+*/
486 XwTextEditWidget ctx
;
487 XwTextPosition position
;
492 XwTextPosition newLeft
, newRight
;
493 XwSelectType newType
;
494 XwSelectType
*sarray
;
496 delta
= (time
< ctx
->text
.lasttime
) ?
497 ctx
->text
.lasttime
- time
: time
- ctx
->text
.lasttime
;
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
;
507 if (*sarray
!= XwselectNull
) sarray
++;
508 if (*sarray
== XwselectNull
) sarray
= ctx
->text
.sarray
;
510 } else { /* single-click event */
511 newType
= *(ctx
->text
.sarray
);
513 ctx
->text
.lasttime
= time
;
516 case XwselectPosition
:
517 newLeft
= newRight
= position
;
521 newRight
= (*(ctx
->text
.source
->scan
))(
522 ctx
->text
.source
, position
, position
, XwsdRight
, 1, FALSE
);
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
);
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
);
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
);
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
;
553 ctx
->text
.insertPos
= newRight
;
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
;
563 ctx
->text
.extendDir
= XwsdLeft
;
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.]
577 /*--------------------------------------------------------------------------+*/
578 static void ExtendSelection (ctx
, position
, motion
)
579 /*--------------------------------------------------------------------------+*/
580 XwTextEditWidget ctx
;
581 XwTextPosition position
;
584 XwTextPosition newLeft
, newRight
;
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
;
595 ctx
->text
.extendDir
= XwsdLeft
;
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
);
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
)
617 if (ctx
->text
.extendDir
== XwsdRight
)
618 newRight
= position
= (*(ctx
->text
.source
->scan
))
619 (ctx
->text
.source
, position
, XwstWhiteSpace
, XwsdRight
, 1, FALSE
);
621 newLeft
= position
= (*(ctx
->text
.source
->scan
))
622 (ctx
->text
.source
, position
, XwstWhiteSpace
, XwsdLeft
, 1, FALSE
);
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
);
630 newLeft
= position
= (*(ctx
->text
.source
->scan
))
631 (ctx
->text
.source
, position
, XwstEOL
, XwsdLeft
, 1, FALSE
);
634 position
= ctx
->text
.insertPos
;
639 _XtTextSetNewSelection(ctx
, newLeft
, newRight
);
640 ctx
->text
.insertPos
= position
;
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.
649 /*--------------------------------------------------------------------------+*/
650 static void AlterSelection (ctx
, mode
, action
)
651 /*--------------------------------------------------------------------------+*/
652 XwTextEditWidget ctx
;
653 XwSelectionMode mode
; /* {XwsmTextSelect, XwsmTextExtend} */
654 XwSelectionAction action
; /* {XwactionStart, XwactionAdjust, XwactionEnd} */
656 XwTextPosition position
;
659 position
= PositionForXY (ctx
, (int) ctx
->text
.ev_x
, (int) ctx
->text
.ev_y
);
660 if (action
== XwactionStart
) {
663 DoSelection (ctx
, position
, ctx
->text
.time
, FALSE
);
666 ExtendSelection (ctx
, position
, FALSE
);
673 DoSelection (ctx
, position
, ctx
->text
.time
, TRUE
);
676 ExtendSelection (ctx
, position
, TRUE
);
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);
687 /******************************************************************************
689 * TextEdit Class Methods
691 ******************************************************************************/
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 ******************************************************************************/
700 /*--------------------------------------------------------------------------+*/
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 */
709 unsigned char *tempResult
;
712 XwTextPosition end
, nend
;
714 end
= (*(ctx
->text
.source
->read
))(ctx
->text
.source
, left
, &text
,
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
,
722 if (length
+ n
> size
) n
= size
- length
;
723 tempResult
= target
+ length
;
724 strncpy(tempResult
, text
.ptr
, n
);
729 return length
; /* return the number of positions transfered to target */
732 /*--------------------------------------------------------------------------+*/
733 static unsigned char *_XwTextCopySubString(ctx
, left
, right
)
734 /*--------------------------------------------------------------------------+*/
735 XwTextEditWidget ctx
;
736 XwTextPosition left
, right
;
738 unsigned char *result
;
739 int length
, resultLength
;
742 resultLength
= right
- left
+ 10; /* Bogus? %%% */
743 result
= (unsigned char *)XtMalloc((unsigned) resultLength
);
745 length
= _XwTextSubString(ctx
, left
, right
, result
, resultLength
, &dummy
);
751 /*--------------------------------------------------------------------------+*/
752 static unsigned char *_XwTextCopySelection(ctx
)
753 /*--------------------------------------------------------------------------+*/
754 XwTextEditWidget ctx
;
756 return( _XwTextCopySubString(ctx
, ctx
->text
.s
.left
, ctx
->text
.s
.right
));
759 /*--------------------------------------------------------------------------+*/
760 static void _XwTextSetSelection(w
, left
, right
)
761 /*--------------------------------------------------------------------------+*/
763 Position left
, right
;
765 XwTextEditWidget ctx
= (XwTextEditWidget
) w
;
767 _XtTextPrepareToUpdate(ctx
);
768 _XtTextSetNewSelection(ctx
, (XwTextPosition
)left
, (XwTextPosition
)right
);
769 _XtTextExecuteUpdate(ctx
);
772 /*--------------------------------------------------------------------------+*/
773 static void _XwTextUnsetSelection(w
)
774 /*--------------------------------------------------------------------------+*/
777 XwTextEditWidget ctx
= (XwTextEditWidget
) w
;
779 _XtTextPrepareToUpdate(ctx
);
780 _XtTextSetNewSelection(ctx
, zeroPosition
, zeroPosition
);
781 _XtTextExecuteUpdate(ctx
);
784 /*--------------------------------------------------------------------------+*/
785 static XwEditResult
_XwTextReplace(w
, startPos
, endPos
, text
, verify
)
786 /*--------------------------------------------------------------------------+*/
788 XwTextPosition startPos
, endPos
;
792 XwTextEditWidget ctx
= (XwTextEditWidget
) w
;
795 _XtTextPrepareToUpdate(ctx
);
796 result
= ReplaceText(ctx
, startPos
, endPos
, text
, verify
);
797 _XtTextExecuteUpdate(ctx
);
801 /*--------------------------------------------------------------------------+*/
802 static void _XwTextRedraw (w
)
803 /*--------------------------------------------------------------------------+*/
806 XwTextEditWidget ctx
= (XwTextEditWidget
) w
;
808 _XtTextPrepareToUpdate(ctx
);
809 ForceBuildLineTable(ctx
);
811 _XtTextExecuteUpdate(ctx
);
812 if (ctx
->primitive
.highlighted
)
813 _XwHighlightBorder(ctx
);
817 /******************************************************************************
821 ******************************************************************************/
822 /*--------------------------------------------------------------------------+*/
823 static XwEditResult
_XwSetCursorPos(ctx
, newposition
)
824 /*--------------------------------------------------------------------------+*/
825 XwTextEditWidget ctx
;
826 XwTextPosition newposition
;
828 XwTextVerifyCD cbdata
;
830 cbdata
.operation
= motionVerify
;
832 cbdata
.currInsert
= ctx
->text
.insertPos
;
833 cbdata
.newInsert
= newposition
;
835 XtCallCallbacks((Widget
)ctx
, XtNmotionVerification
, &cbdata
);
837 if (!cbdata
.doit
) return XweditReject
;
839 ctx
->text
.insertPos
= cbdata
.newInsert
;
844 /*--------------------------------------------------------------------------+*/
845 static void StartAction(ctx
, event
)
846 /*--------------------------------------------------------------------------+*/
847 XwTextEditWidget ctx
;
850 _XtTextPrepareToUpdate(ctx
);
852 ctx
->text
.time
= event
->xbutton
.time
;
853 ctx
->text
.ev_x
= event
->xbutton
.x
;
854 ctx
->text
.ev_y
= event
->xbutton
.y
;
858 /*--------------------------------------------------------------------------+*/
859 static void EndAction(ctx
)
860 /*--------------------------------------------------------------------------+*/
861 XwTextEditWidget ctx
;
863 CheckResizeOrOverflow(ctx
);
864 _XtTextExecuteUpdate(ctx
);
867 /*--------------------------------------------------------------------------+*/
868 static void DeleteOrKill(ctx
, from
, to
, kill
)
869 /*--------------------------------------------------------------------------+*/
870 XwTextEditWidget ctx
;
871 XwTextPosition from
, to
;
878 if (kill
&& from
< to
)
879 ptr
= _XwTextCopySubString(ctx
, from
, to
);
883 if (result
= ReplaceText(ctx
, from
, to
, &text
, TRUE
)) {
884 if (result
!= XweditReject
)
885 XBell(XtDisplay(ctx
), 50);
886 if (kill
&& from
< to
)
891 if (kill
&& from
< to
) {
892 XStoreBuffer(XtDisplay(ctx
), ptr
, XwStrlen(ptr
), 1);
895 _XwSetCursorPos(ctx
, from
);
896 ctx
->text
.showposition
= TRUE
;
898 from
= ctx
->text
.insertPos
;
899 _XtTextSetNewSelection(ctx
, from
, from
);
903 /*--------------------------------------------------------------------------+*/
904 static void StuffFromBuffer(ctx
, buffer
)
905 /*--------------------------------------------------------------------------+*/
906 XwTextEditWidget ctx
;
909 extern char *XFetchBuffer();
912 XwTextPosition nextcursorpos
;
915 (unsigned char*)XFetchBuffer(XtDisplay(ctx
), &(text
.length
), buffer
);
917 ReplaceText(ctx
, ctx
->text
.insertPos
, ctx
->text
.insertPos
,
919 if (result
!= XweditReject
)
920 XBell(XtDisplay(ctx
), 50);
924 nextcursorpos
= (*(ctx
->text
.source
->scan
))
925 (ctx
->text
.source
, ctx
->text
.insertPos
, XwstPositions
, XwsdRight
,
927 _XwSetCursorPos(ctx
, nextcursorpos
);
928 nextcursorpos
= ctx
->text
.insertPos
;
929 _XtTextSetNewSelection(ctx
, nextcursorpos
, nextcursorpos
);
933 /*--------------------------------------------------------------------------+*/
934 static XwTextPosition
NextPosition(ctx
, position
, kind
, direction
)
935 /*--------------------------------------------------------------------------+*/
936 XwTextEditWidget ctx
;
937 XwTextPosition position
;
939 XwScanDirection direction
;
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
);
951 /*--------------------------------------------------------------------------+*/
952 static XwEditResult
InsertNewLineAndBackupInternal(ctx
)
953 /*--------------------------------------------------------------------------+*/
954 XwTextEditWidget ctx
;
960 text
.ptr
= (unsigned char*)"\n";
963 ReplaceText(ctx
, ctx
->text
.insertPos
, ctx
->text
.insertPos
,
965 if (result
!= XweditReject
)
966 XBell( XtDisplay(ctx
), 50);
969 _XtTextSetNewSelection(ctx
, (XwTextPosition
) 0, (XwTextPosition
) 0);
970 ctx
->text
.showposition
= TRUE
;
973 /* Insert a file of the given name into the text. Returns 0 if file found,
976 /* Unadvertized function */
977 /*--------------------------------------------------------------------------+*/
978 int XwTextInsertFile(ctx
, str
)
979 /*--------------------------------------------------------------------------+*/
980 XwTextEditWidget ctx
;
985 unsigned char buf
[1000];
986 XwTextPosition position
;
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) {
995 ReplaceText(ctx
, position
, position
, &text
, TRUE
);
996 position
= (*(ctx
->text
.source
->scan
))(ctx
->text
.source
, position
,
997 XwstPositions
, XwsdRight
, text
.length
, TRUE
);
1000 ctx
->text
.insertPos
= position
;
1001 _XtTextExecuteUpdate(ctx
);
1005 /******************************************************************************
1007 * Action Table Functions
1009 ******************************************************************************/
1010 /*--------------------------------------------------------------------------+*/
1011 static Boolean
VerifyLeave(ctx
,event
)
1012 /*--------------------------------------------------------------------------+*/
1013 XwTextEditWidget ctx
;
1016 XwTextVerifyCD cbdata
;
1018 StartAction(ctx
, event
);
1019 cbdata
.operation
= leaveVerify
;
1021 cbdata
.currInsert
= ctx
->text
.insertPos
;
1022 cbdata
.newInsert
= ctx
->text
.insertPos
;
1023 cbdata
.startPos
= ctx
->text
.insertPos
;
1024 cbdata
.endPos
= ctx
->text
.insertPos
;
1026 cbdata
.xevent
= event
;
1027 XtCallCallbacks((Widget
)ctx
, XtNleaveVerification
, &cbdata
);
1028 ctx
->text
.insertPos
= cbdata
.newInsert
;
1030 return( cbdata
.doit
);
1033 /*--------------------------------------------------------------------------+*/
1034 static void TraverseUp(ctx
, event
)
1035 /*--------------------------------------------------------------------------+*/
1036 XwTextEditWidget ctx
;
1039 /* Allow the verification routine to control the traversal */
1040 if (VerifyLeave(ctx
, event
))
1041 _XwTraverseUp((Widget
)ctx
, event
);
1044 /*--------------------------------------------------------------------------+*/
1045 static void TraverseDown(ctx
, event
)
1046 /*--------------------------------------------------------------------------+*/
1047 XwTextEditWidget ctx
;
1050 /* Allow the verification routine to control the traversal */
1051 if (VerifyLeave(ctx
, event
))
1052 _XwTraverseDown((Widget
)ctx
, event
);
1055 /*--------------------------------------------------------------------------+*/
1056 static void TraversePrev(ctx
, event
)
1057 /*--------------------------------------------------------------------------+*/
1058 XwTextEditWidget ctx
;
1061 /* Allow the verification routine to control the traversal */
1062 if (VerifyLeave(ctx
, event
))
1063 _XwTraversePrev((Widget
)ctx
, event
);
1066 /*--------------------------------------------------------------------------+*/
1067 static void TraverseNext(ctx
, event
)
1068 /*--------------------------------------------------------------------------+*/
1069 XwTextEditWidget ctx
;
1072 /* Allow the verification routine to control the traversal */
1073 if (VerifyLeave(ctx
, event
))
1074 _XwTraverseNext((Widget
)ctx
, event
);
1077 /*--------------------------------------------------------------------------+*/
1078 static void TraverseLeft(ctx
, event
)
1079 /*--------------------------------------------------------------------------+*/
1080 XwTextEditWidget ctx
;
1083 /* Allow the verification routine to control the traversal */
1084 if (VerifyLeave(ctx
, event
))
1085 _XwTraverseLeft((Widget
)ctx
, event
);
1088 /*--------------------------------------------------------------------------+*/
1089 static void TraverseRight(ctx
, event
)
1090 /*--------------------------------------------------------------------------+*/
1091 XwTextEditWidget ctx
;
1094 /* Allow the verification routine to control the traversal */
1095 if (VerifyLeave(ctx
, event
))
1096 _XwTraverseRight((Widget
)ctx
, event
);
1099 /*--------------------------------------------------------------------------+*/
1100 static void TraverseHome(ctx
, event
)
1101 /*--------------------------------------------------------------------------+*/
1102 XwTextEditWidget ctx
;
1105 /* Allow the verification routine to control the traversal */
1106 if (VerifyLeave(ctx
, event
))
1107 _XwTraverseHome((Widget
)ctx
, event
);
1110 /*--------------------------------------------------------------------------+*/
1111 static void TraverseNextTop(ctx
, event
)
1112 /*--------------------------------------------------------------------------+*/
1113 XwTextEditWidget ctx
;
1116 /* Allow the verification routine to control the traversal */
1117 if (VerifyLeave(ctx
, event
))
1118 _XwTraverseNextTop((Widget
)ctx
, event
);
1121 /*--------------------------------------------------------------------------+*/
1122 static void Enter(ctx
, event
)
1123 /*--------------------------------------------------------------------------+*/
1124 XwTextEditWidget ctx
;
1127 _XwPrimitiveEnter((Widget
)ctx
, event
);
1130 /*--------------------------------------------------------------------------+*/
1131 static void Leave(ctx
, event
)
1132 /*--------------------------------------------------------------------------+*/
1133 XwTextEditWidget ctx
;
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
);
1141 _XwPrimitiveLeave((Widget
)ctx
, event
);
1144 /*--------------------------------------------------------------------------+*/
1145 static void TextFocusIn (ctx
, event
)
1146 /*--------------------------------------------------------------------------+*/
1147 XwTextEditWidget ctx
;
1150 _XwPrimitiveFocusIn((XwPrimitiveWidget
)ctx
, event
);
1151 ctx
->text
.hasfocus
= TRUE
;
1154 /*--------------------------------------------------------------------------+*/
1155 static void TextFocusOut(ctx
, event
)
1156 /*--------------------------------------------------------------------------+*/
1157 XwTextEditWidget ctx
;
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
);
1165 _XwPrimitiveFocusOut((XwPrimitiveWidget
)ctx
, event
);
1166 ctx
->text
.hasfocus
= FALSE
;
1169 /* Kill and Stuff */
1170 /*--------------------------------------------------------------------------+*/
1171 static void UnKill(ctx
, event
)
1172 /*--------------------------------------------------------------------------+*/
1173 XwTextEditWidget ctx
;
1176 StartAction(ctx
, event
);
1177 StuffFromBuffer(ctx
, 1);
1181 /*--------------------------------------------------------------------------+*/
1182 static void Stuff(ctx
, event
)
1183 /*--------------------------------------------------------------------------+*/
1184 XwTextEditWidget ctx
;
1187 StartAction(ctx
, event
);
1188 StuffFromBuffer(ctx
, 0);
1192 /* routines for moving around */
1194 /*--------------------------------------------------------------------------+*/
1195 static void MoveForwardChar(ctx
, event
)
1196 /*--------------------------------------------------------------------------+*/
1197 XwTextEditWidget ctx
;
1200 StartAction(ctx
, event
);
1201 _XwSetCursorPos(ctx
, (*(ctx
->text
.source
->scan
))
1202 (ctx
->text
.source
, ctx
->text
.insertPos
, XwstPositions
, XwsdRight
, 1,
1208 /*--------------------------------------------------------------------------+*/
1209 static void MoveBackwardChar(ctx
, event
)
1210 /*--------------------------------------------------------------------------+*/
1211 XwTextEditWidget ctx
;
1214 StartAction(ctx
, event
);
1215 _XwSetCursorPos(ctx
, (*(ctx
->text
.source
->scan
))
1216 (ctx
->text
.source
, ctx
->text
.insertPos
, XwstPositions
, XwsdLeft
, 1, TRUE
)
1221 /*--------------------------------------------------------------------------+*/
1222 static void MoveForwardWord(ctx
, event
)
1223 /*--------------------------------------------------------------------------+*/
1224 XwTextEditWidget ctx
;
1227 StartAction(ctx
, event
);
1228 _XwSetCursorPos(ctx
,
1229 NextPosition(ctx
, ctx
->text
.insertPos
, XwstWhiteSpace
, XwsdRight
)
1234 /*--------------------------------------------------------------------------+*/
1235 static void MoveBackwardWord(ctx
, event
)
1236 /*--------------------------------------------------------------------------+*/
1237 XwTextEditWidget ctx
;
1240 StartAction(ctx
, event
);
1241 _XwSetCursorPos(ctx
,
1242 NextPosition(ctx
, ctx
->text
.insertPos
, XwstWhiteSpace
, XwsdLeft
)
1247 /*--------------------------------------------------------------------------+*/
1248 static void MoveBackwardParagraph(ctx
, event
)
1249 /*--------------------------------------------------------------------------+*/
1250 XwTextEditWidget ctx
;
1253 StartAction(ctx
, event
);
1254 _XwSetCursorPos(ctx
,
1255 NextPosition(ctx
, ctx
->text
.insertPos
, XwstEOL
, XwsdLeft
)
1260 /*--------------------------------------------------------------------------+*/
1261 static void MoveForwardParagraph(ctx
, event
)
1262 /*--------------------------------------------------------------------------+*/
1263 XwTextEditWidget ctx
;
1266 StartAction(ctx
, event
);
1267 _XwSetCursorPos(ctx
,
1268 NextPosition(ctx
, ctx
->text
.insertPos
, XwstEOL
, XwsdRight
)
1273 /*--------------------------------------------------------------------------+*/
1274 static void MoveToLineStart(ctx
, event
)
1275 /*--------------------------------------------------------------------------+*/
1276 XwTextEditWidget ctx
;
1280 StartAction(ctx
, event
);
1281 _XtTextShowPosition(ctx
);
1282 line
= LineForPosition(ctx
, ctx
->text
.insertPos
);
1283 _XwSetCursorPos(ctx
, ctx
->text
.lt
.info
[line
].position
);
1287 /*--------------------------------------------------------------------------+*/
1288 static void MoveToLineEnd(ctx
, event
)
1289 /*--------------------------------------------------------------------------+*/
1290 XwTextEditWidget ctx
;
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
;
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
);
1311 /*--------------------------------------------------------------------------+*/
1312 static void MoveNextLine(ctx
, event
)
1313 /*--------------------------------------------------------------------------+*/
1314 XwTextEditWidget ctx
;
1317 int width
, width2
, height
, line
;
1318 XwTextPosition position
, maxp
, lastpos
= GETLASTPOS(ctx
);
1319 XwTextSink
*sink
= ctx
->text
.sink
;
1321 StartAction(ctx
, event
);
1322 _XtTextShowPosition(ctx
); /* Needed if cursor goes off screen ??? */
1323 line
= LineForPosition(ctx
, ctx
->text
.insertPos
);
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
);
1330 if (sink
->LineLastPosition
== ctx
->text
.insertPos
)
1331 width
= sink
->LineLastWidth
;
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
);
1337 if (ctx
->text
.lt
.info
[line
].position
> lastpos
) {
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
)
1350 if (_XwSetCursorPos(ctx
, position
) == XweditDone
) {
1351 sink
->LineLastWidth
= width
;
1352 sink
->LineLastPosition
= position
;
1358 /*--------------------------------------------------------------------------+*/
1359 static void MovePreviousLine(ctx
, event
)
1360 /*--------------------------------------------------------------------------+*/
1361 XwTextEditWidget ctx
;
1364 int width
, width2
, height
, line
;
1365 XwTextPosition position
, maxp
;
1366 XwTextSink
*sink
= ctx
->text
.sink
;
1368 StartAction(ctx
, event
);
1369 _XtTextShowPosition(ctx
);
1370 line
= LineForPosition(ctx
, ctx
->text
.insertPos
);
1372 _XtTextScroll(ctx
, -1);
1373 line
= LineForPosition(ctx
, ctx
->text
.insertPos
);
1376 if (sink
->LineLastPosition
== ctx
->text
.insertPos
)
1377 width
= sink
->LineLastWidth
;
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
);
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
)
1392 if (_XwSetCursorPos(ctx
, position
) == XweditDone
) {
1393 sink
->LineLastWidth
= width
;
1394 sink
->LineLastPosition
= position
;
1400 /*--------------------------------------------------------------------------+*/
1401 static void MoveBeginningOfFile(ctx
, event
)
1402 /*--------------------------------------------------------------------------+*/
1403 XwTextEditWidget ctx
;
1406 StartAction(ctx
, event
);
1407 _XwSetCursorPos(ctx
, (*(ctx
->text
.source
->scan
))
1408 (ctx
->text
.source
, ctx
->text
.insertPos
, XwstLast
, XwsdLeft
, 1, TRUE
)
1413 /*--------------------------------------------------------------------------+*/
1414 static void MoveEndOfFile(ctx
, event
)
1415 /*--------------------------------------------------------------------------+*/
1416 XwTextEditWidget ctx
;
1419 StartAction(ctx
, event
);
1420 _XwSetCursorPos(ctx
, (*(ctx
->text
.source
->scan
))
1421 (ctx
->text
.source
, ctx
->text
.insertPos
, XwstLast
, XwsdRight
, 1, TRUE
)
1426 /*--------------------------------------------------------------------------+*/
1427 static void ScrollOneLineUp(ctx
, event
)
1428 /*--------------------------------------------------------------------------+*/
1429 XwTextEditWidget ctx
;
1432 StartAction(ctx
, event
);
1433 _XtTextScroll(ctx
, 1);
1437 /*--------------------------------------------------------------------------+*/
1438 static void ScrollOneLineDown(ctx
, event
)
1439 /*--------------------------------------------------------------------------+*/
1440 XwTextEditWidget ctx
;
1443 StartAction(ctx
, event
);
1444 _XtTextScroll(ctx
, -1);
1448 /*--------------------------------------------------------------------------+*/
1449 static void MoveNextPage(ctx
, event
)
1450 /*--------------------------------------------------------------------------+*/
1451 XwTextEditWidget ctx
;
1454 XwLineTablePtr lt
= &(ctx
->text
.lt
) ;
1456 XwTextPosition line_offset
, new_pos
, lastpos
= GETLASTPOS(ctx
);
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
);
1472 /*--------------------------------------------------------------------------+*/
1473 static void MovePreviousPage(ctx
, event
)
1474 /*--------------------------------------------------------------------------+*/
1475 XwTextEditWidget ctx
;
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
));
1489 /* delete routines */
1491 /*--------------------------------------------------------------------------+*/
1492 static void DeleteForwardChar(ctx
, event
)
1493 /*--------------------------------------------------------------------------+*/
1494 XwTextEditWidget ctx
;
1497 XwTextPosition next
;
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
);
1507 /*--------------------------------------------------------------------------+*/
1508 static void DeleteBackwardNormal(ctx
, event
)
1509 /*--------------------------------------------------------------------------+*/
1510 XwTextEditWidget ctx
;
1513 /* If there's a selection, delete it, otherwise, delete the character */
1515 if (ctx
->text
.s
.left
!= ctx
->text
.s
.right
)
1516 DeleteCurrentSelection(ctx
, event
);
1518 DeleteBackwardChar(ctx
, event
);
1521 /*--------------------------------------------------------------------------+*/
1522 static void DeleteBackwardChar(ctx
, event
)
1523 /*--------------------------------------------------------------------------+*/
1524 XwTextEditWidget ctx
;
1527 XwTextPosition next
;
1529 StartAction(ctx
, event
);
1530 next
= (*(ctx
->text
.source
->scan
))(
1531 ctx
->text
.source
, ctx
->text
.insertPos
, XwstPositions
,
1533 DeleteOrKill(ctx
, next
, ctx
->text
.insertPos
, FALSE
);
1537 /*--------------------------------------------------------------------------+*/
1538 static void DeleteForwardWord(ctx
, event
)
1539 /*--------------------------------------------------------------------------+*/
1540 XwTextEditWidget ctx
;
1543 XwTextPosition next
;
1545 StartAction(ctx
, event
);
1546 next
= NextPosition(ctx
, ctx
->text
.insertPos
, XwstWhiteSpace
, XwsdRight
);
1547 DeleteOrKill(ctx
, ctx
->text
.insertPos
, next
, FALSE
);
1551 /*--------------------------------------------------------------------------+*/
1552 static void DeleteBackwardWord(ctx
, event
)
1553 /*--------------------------------------------------------------------------+*/
1554 XwTextEditWidget ctx
;
1557 XwTextPosition next
;
1559 StartAction(ctx
, event
);
1560 next
= NextPosition(ctx
, ctx
->text
.insertPos
, XwstWhiteSpace
, XwsdLeft
);
1561 DeleteOrKill(ctx
, next
, ctx
->text
.insertPos
, FALSE
);
1565 /*--------------------------------------------------------------------------+*/
1566 static void KillForwardWord(ctx
, event
)
1567 /*--------------------------------------------------------------------------+*/
1568 XwTextEditWidget ctx
;
1571 XwTextPosition next
;
1573 StartAction(ctx
, event
);
1574 next
= NextPosition(ctx
, ctx
->text
.insertPos
, XwstWhiteSpace
, XwsdRight
);
1575 DeleteOrKill(ctx
, ctx
->text
.insertPos
, next
, TRUE
);
1579 /*--------------------------------------------------------------------------+*/
1580 static void KillBackwardWord(ctx
, event
)
1581 /*--------------------------------------------------------------------------+*/
1582 XwTextEditWidget ctx
;
1585 XwTextPosition next
;
1587 StartAction(ctx
, event
);
1588 next
= NextPosition(ctx
, ctx
->text
.insertPos
, XwstWhiteSpace
, XwsdLeft
);
1589 DeleteOrKill(ctx
, next
, ctx
->text
.insertPos
, TRUE
);
1593 /*--------------------------------------------------------------------------+*/
1594 static void KillCurrentSelection(ctx
, event
)
1595 /*--------------------------------------------------------------------------+*/
1596 XwTextEditWidget ctx
;
1599 StartAction(ctx
, event
);
1600 DeleteOrKill(ctx
, ctx
->text
.s
.left
, ctx
->text
.s
.right
, TRUE
);
1604 /*--------------------------------------------------------------------------+*/
1605 static void DeleteCurrentSelection(ctx
, event
)
1606 /*--------------------------------------------------------------------------+*/
1607 XwTextEditWidget ctx
;
1610 StartAction(ctx
, event
);
1611 DeleteOrKill(ctx
, ctx
->text
.s
.left
, ctx
->text
.s
.right
, FALSE
);
1615 /*--------------------------------------------------------------------------+*/
1616 static void KillToEndOfLine(ctx
, event
)
1617 /*--------------------------------------------------------------------------+*/
1618 XwTextEditWidget ctx
;
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
);
1631 if (last
> next
&& ctx
->text
.insertPos
< next
)
1633 DeleteOrKill(ctx
, ctx
->text
.insertPos
, last
, TRUE
);
1637 /*--------------------------------------------------------------------------+*/
1638 static void KillToEndOfParagraph(ctx
, event
)
1639 /*--------------------------------------------------------------------------+*/
1640 XwTextEditWidget ctx
;
1643 XwTextPosition next
;
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
);
1655 /*--------------------------------------------------------------------------+*/
1656 static void InsertNewLineAndBackup(ctx
, event
)
1657 /*--------------------------------------------------------------------------+*/
1658 XwTextEditWidget ctx
;
1661 StartAction(ctx
, event
);
1662 InsertNewLineAndBackupInternal(ctx
);
1666 /*--------------------------------------------------------------------------+*/
1667 static XwEditResult
InsertNewLine(ctx
, event
)
1668 /*--------------------------------------------------------------------------+*/
1669 XwTextEditWidget ctx
;
1672 XwTextPosition next
;
1673 XwEditResult result
;
1675 StartAction(ctx
, event
);
1676 if (InsertNewLineAndBackupInternal(ctx
)) {
1678 return(XweditError
);
1680 next
= (*(ctx
->text
.source
->scan
))(ctx
->text
.source
, ctx
->text
.insertPos
,
1681 XwstPositions
, XwsdRight
, 1, TRUE
);
1682 result
= _XwSetCursorPos(ctx
, next
);
1687 /*--------------------------------------------------------------------------+*/
1688 static void InsertNewLineAndIndent(ctx
, event
)
1689 /*--------------------------------------------------------------------------+*/
1690 XwTextEditWidget ctx
;
1694 XwTextPosition pos1
, pos2
;
1695 XwEditResult result
;
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
,
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;
1708 ReplaceText(ctx
, ctx
->text
.insertPos
, ctx
->text
.insertPos
,
1710 if (result
!= XweditReject
)
1711 XBell(XtDisplay(ctx
), 50);
1716 _XwSetCursorPos(ctx
, (*(ctx
->text
.source
->scan
))
1717 (ctx
->text
.source
, ctx
->text
.insertPos
, XwstPositions
,
1718 XwsdRight
, text
.length
, TRUE
));
1723 /*--------------------------------------------------------------------------+*/
1724 static void NewSelection(ctx
, l
, r
)
1725 /*--------------------------------------------------------------------------+*/
1726 XwTextEditWidget ctx
;
1727 XwTextPosition l
, r
;
1730 _XtTextSetNewSelection(ctx
, l
, r
);
1732 ptr
= _XwTextCopySubString(ctx
, l
, r
);
1733 XStoreBuffer(XtDisplay(ctx
), ptr
, min(XwStrlen(ptr
), MAXCUT
), 0);
1738 /*--------------------------------------------------------------------------+*/
1739 static void SelectWord(ctx
, event
)
1740 /*--------------------------------------------------------------------------+*/
1741 XwTextEditWidget ctx
;
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
);
1754 /*--------------------------------------------------------------------------+*/
1755 static void SelectAll(ctx
, event
)
1756 /*--------------------------------------------------------------------------+*/
1757 XwTextEditWidget ctx
;
1760 StartAction(ctx
, event
);
1761 NewSelection(ctx
, (XwTextPosition
) 0, GETLASTPOS(ctx
));
1765 /*--------------------------------------------------------------------------+*/
1766 static void SelectStart(ctx
, event
)
1767 /*--------------------------------------------------------------------------+*/
1768 XwTextEditWidget ctx
;
1771 StartAction(ctx
, event
);
1772 AlterSelection(ctx
, XwsmTextSelect
, XwactionStart
);
1776 /*--------------------------------------------------------------------------+*/
1777 static void SelectAdjust(ctx
, event
)
1778 /*--------------------------------------------------------------------------+*/
1779 XwTextEditWidget ctx
;
1782 StartAction(ctx
, event
);
1783 AlterSelection(ctx
, XwsmTextSelect
, XwactionAdjust
);
1787 /*--------------------------------------------------------------------------+*/
1788 static void SelectEnd(ctx
, event
)
1789 /*--------------------------------------------------------------------------+*/
1790 XwTextEditWidget ctx
;
1793 StartAction(ctx
, event
);
1794 AlterSelection(ctx
, XwsmTextSelect
, XwactionEnd
);
1798 /*--------------------------------------------------------------------------+*/
1799 static void ExtendStart(ctx
, event
)
1800 /*--------------------------------------------------------------------------+*/
1801 XwTextEditWidget ctx
;
1804 StartAction(ctx
, event
);
1805 AlterSelection(ctx
, XwsmTextExtend
, XwactionStart
);
1809 /*--------------------------------------------------------------------------+*/
1810 static void ExtendAdjust(ctx
, event
)
1811 /*--------------------------------------------------------------------------+*/
1812 XwTextEditWidget ctx
;
1815 StartAction(ctx
, event
);
1816 AlterSelection(ctx
, XwsmTextExtend
, XwactionAdjust
);
1820 /*--------------------------------------------------------------------------+*/
1821 static void ExtendEnd(ctx
, event
)
1822 /*--------------------------------------------------------------------------+*/
1823 XwTextEditWidget ctx
;
1826 StartAction(ctx
, event
);
1827 AlterSelection(ctx
, XwsmTextExtend
, XwactionEnd
);
1831 /*--------------------------------------------------------------------------+*/
1832 static void RedrawDisplay(ctx
, event
)
1833 /*--------------------------------------------------------------------------+*/
1834 XwTextEditWidget ctx
;
1837 StartAction(ctx
, event
);
1838 ForceBuildLineTable(ctx
);
1839 DisplayAllText(ctx
);
1842 /* This seems like the wrong place for this */
1843 if (ctx
->primitive
.highlighted
)
1844 _XwHighlightBorder(ctx
);
1847 #define STRBUFSIZE 100
1848 static XComposeStatus compose_status
= {NULL
, 0};
1850 /*--------------------------------------------------------------------------+*/
1851 static void InsertChar(ctx
, event
)
1852 /*--------------------------------------------------------------------------+*/
1853 XwTextEditWidget ctx
;
1856 unsigned char strbuf
[STRBUFSIZE
];
1858 XwEditResult result
;
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];;
1868 ReplaceText(ctx
, ctx
->text
.insertPos
, ctx
->text
.insertPos
,
1870 if (result
!= XweditReject
)
1871 XBell(XtDisplay(ctx
), 50);
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
);
1883 /*--------------------------------------------------------------------------+*/
1884 static void Execute(ctx
, event
)
1885 /*--------------------------------------------------------------------------+*/
1886 XwTextEditWidget ctx
;
1890 XtCallCallbacks((Widget
)ctx
, XtNexecute
, NULL
);
1894 /*************************************************************************
1896 * Class Record Support Functions
1898 *************************************************************************/
1900 /******************************************************************************
1902 * Class Record Functions
1904 ******************************************************************************/
1906 /*--------------------------------------------------------------------------+*/
1907 static void ClassInitialize()
1908 /*--------------------------------------------------------------------------+*/
1912 } /* ClassInitialize */
1916 /******************************************************************************
1918 * External functions (Methods???) on the class
1920 ******************************************************************************/
1922 /*--------------------------------------------------------------------------+*/
1923 void XwTextClearBuffer(w
)
1924 /*--------------------------------------------------------------------------+*/
1927 _XtTextPrepareToUpdate(w
);
1928 (*(w
->text
.source
->setLastPos
))(w
->text
.source
, (XwTextPosition
)0);
1929 w
->text
.insertPos
= 0;
1930 ForceBuildLineTable(w
);
1932 _XtTextExecuteUpdate(w
);
1935 /*--------------------------------------------------------------------------+*/
1936 unsigned char *XwTextCopyBuffer(w
)
1937 /*--------------------------------------------------------------------------+*/
1941 return (*((XwTextEditClassRec
*)(w
->core
.widget_class
))->textedit_class
.copy_substring
)
1942 ((XwTextEditWidget
)w
, 0, GETLASTPOS(w
));
1946 /*--------------------------------------------------------------------------+*/
1947 unsigned char *XwTextCopySelection(w
)
1948 /*--------------------------------------------------------------------------+*/
1951 return (*((XwTextEditClassRec
*)(w
->core
.widget_class
))->textedit_class
.copy_selection
)
1952 ((XwTextEditWidget
)w
);
1955 /*--------------------------------------------------------------------------+*/
1956 int XwTextReadSubString( w
, startpos
, endpos
, target
, targetsize
, targetused
)
1957 /*--------------------------------------------------------------------------+*/
1959 XwTextPosition startpos
, endpos
;
1960 unsigned char *target
;
1964 return( _XwTextSubString(w
, startpos
, endpos
, target
, targetsize
, targetused
) );
1968 /*--------------------------------------------------------------------------+*/
1969 void XwTextUnsetSelection(w
)
1970 /*--------------------------------------------------------------------------+*/
1973 (*((XwTextEditClassRec
*)(w
->core
.widget_class
))->textedit_class
.unset_selection
)
1977 /*--------------------------------------------------------------------------+*/
1978 void XwTextSetSelection(w
, left
, right
)
1979 /*--------------------------------------------------------------------------+*/
1981 XwTextPosition left
, right
;
1983 (*((XwTextEditClassRec
*)(w
->core
.widget_class
))->textedit_class
.set_selection
)
1984 ((Widget
)w
, left
, right
);
1987 /*--------------------------------------------------------------------------+*/
1988 XwEditResult
XwTextReplace(w
, startPos
, endPos
, string
)
1989 /*--------------------------------------------------------------------------+*/
1991 XwTextPosition startPos
, endPos
;
1992 unsigned char *string
;
1997 blk
.length
= XwStrlen(string
);
1998 blk
.firstPos
= (XwTextPosition
)0;
2000 return (*((XwTextEditClassRec
*)(w
->core
.widget_class
))->textedit_class
.replace_text
)
2001 (w
, startPos
, endPos
, &blk
, FALSE
);
2004 /*--------------------------------------------------------------------------+*/
2005 void XwTextRedraw(w
)
2006 /*--------------------------------------------------------------------------+*/
2009 (*((XwTextEditClassRec
*)(w
->core
.widget_class
))->textedit_class
.redraw_text
)
2013 /*--------------------------------------------------------------------------+*/
2014 void XwTextResize(w
)
2015 /*--------------------------------------------------------------------------+*/
2018 _XtTextPrepareToUpdate(w
);
2019 CheckResizeOrOverflow(w
);
2020 _XtTextExecuteUpdate(w
);
2023 /*--------------------------------------------------------------------------+*/
2024 void XwTextUpdate( w
, status
)
2025 /*--------------------------------------------------------------------------+*/
2029 w
->text
.update_flag
= status
;
2031 _XtTextExecuteUpdate(w
);
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
);
2042 /*--------------------------------------------------------------------------+*/
2043 void XwTextInsert(w
, string
)
2044 /*--------------------------------------------------------------------------+*/
2046 unsigned char *string
;
2051 blk
.length
= XwStrlen(string
);
2052 blk
.firstPos
= (XwTextPosition
) 0;
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
;
2060 _XtTextExecuteUpdate(w
);
2064 /*--------------------------------------------------------------------------+*/
2065 XwTextPosition
XwTextGetLastPos (w
)
2066 /*--------------------------------------------------------------------------+*/
2069 return( GETLASTPOS(w
) );
2072 /*--------------------------------------------------------------------------+*/
2073 void XwTextGetSelectionPos(w
, left
, right
)
2074 /*--------------------------------------------------------------------------+*/
2076 XwTextPosition
*left
, *right
;
2079 *left
= w
->text
.s
.left
;
2080 *right
= w
->text
.s
.right
;
2083 /*--------------------------------------------------------------------------+*/
2084 void XwTextSetInsertPos(w
, position
)
2085 /*--------------------------------------------------------------------------+*/
2087 XwTextPosition position
;
2090 _XtTextPrepareToUpdate(w
);
2091 w
->text
.insertPos
= position
;
2092 w
->text
.showposition
= TRUE
;
2093 _XtTextExecuteUpdate(w
);
2096 /*--------------------------------------------------------------------------+*/
2097 XwTextPosition
XwTextGetInsertPos(w
)
2098 /*--------------------------------------------------------------------------+*/
2102 return( w
->text
.insertPos
);
2106 /*--------------------------------------------------------------------------+*/
2107 void XwTextSetSource(w
, source
, startpos
)
2108 /*--------------------------------------------------------------------------+*/
2110 XwTextSourcePtr source
;
2111 XwTextPosition startpos
;
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
;
2119 ForceBuildLineTable(w
);
2120 if (XtIsRealized((Widget
)w
)) {
2121 _XtTextPrepareToUpdate(w
);
2123 _XtTextExecuteUpdate(w
);
2126 /* Not advertised. Don't think it is necessary */
2127 /*--------------------------------------------------------------------------+*/
2128 unsigned char *XwTextCopySubString(w
, left
, right
)
2129 /*--------------------------------------------------------------------------+*/
2131 XwTextPosition left
, right
;
2133 return (*((XwTextEditClassRec
*)(w
->core
.widget_class
))->textedit_class
.copy_substring
)
2134 ((XwTextEditWidget
)w
, left
, right
);
2137 /*--------------------------------------------------------------------------+*/
2138 void XwTextInvalidate(w
, from
, to
)
2139 /*--------------------------------------------------------------------------+*/
2141 XwTextPosition from
,to
;
2143 _XtTextPrepareToUpdate(w
);
2144 _XtTextNeedsUpdating(w
, from
, to
);
2145 ForceBuildLineTable(w
);
2146 _XtTextExecuteUpdate(w
);
2149 /*--------------------------------------------------------------------------+*/
2150 XwTextPosition
XwTextTopPosition(w
)
2151 /*--------------------------------------------------------------------------+*/
2154 return w
->text
.lt
.top
;
2157 /*****************************************************************************
2159 *****************************************************************************/
2161 /*--------------------------------------------------------------------------+*/
2162 static void Initialize(request
, new)
2163 /*--------------------------------------------------------------------------+*/
2164 Widget request
, new;
2166 XwTextEditWidget ctx
= (XwTextEditWidget
)new;
2167 XwTextEditPart
*text
= &(ctx
->text
);
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? */
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
;
2197 if (text
->wrap_mode
== XwWrapOff
)
2198 { text
->wrap_form
= XwSourceForm
;
2199 text
->wrap_break
= XwWrapAny
;
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
2214 /*--------------------------------------------------------------------------+*/
2215 static void InitializeHook(widget
, args
, num_args
)
2216 /*--------------------------------------------------------------------------+*/
2220 { XwTextEditWidget ctx
= (XwTextEditWidget
)widget
;
2221 register XwTextEditPart
*text
= &(ctx
->text
);
2223 text
->sink
= XwAsciiSinkCreate(widget
, args
, *num_args
);
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
);
2232 ForceBuildLineTable((XwTextEditWidget
)widget
);
2233 if (text
->lt
.lines
> 1)
2234 { text
->scroll_state
&= ~XwAutoScrollHorizontal
;
2238 /*--------------------------------------------------------------------------+*/
2239 static void TextDestroy(ctx
)
2240 /*--------------------------------------------------------------------------+*/
2241 XwTextEditWidget ctx
;
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
);
2253 /*--------------------------------------------------------------------------+*/
2254 static void Resize(w
)
2255 /*--------------------------------------------------------------------------+*/
2258 XwTextEditWidget ctx
= (XwTextEditWidget
) w
;
2259 XwTextEditPart
*tp
;
2260 Dimension width
, height
;
2261 Boolean realized
= XtIsRealized(w
);
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
;
2271 if (realized
) _XtTextPrepareToUpdate(ctx
);
2272 ForceBuildLineTable(ctx
);
2274 if (tp
->lt
.lines
> 1)
2275 { tp
->scroll_state
&= ~XwAutoScrollHorizontal
;
2278 { tp
->scroll_state
|= tp
->scroll_mode
& XwAutoScrollHorizontal
;
2283 DisplayAllText(ctx
);
2287 if (realized
) _XtTextExecuteUpdate(ctx
);
2290 /*--------------------------------------------------------------------------+*/
2291 static Boolean
SetValues(current
, request
, new)
2292 /*--------------------------------------------------------------------------+*/
2293 Widget current
, request
, new;
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
);
2302 if (realized
) _XtTextPrepareToUpdate(oldtw
);
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;
2314 if (oldtext
->sink
!= newtext
->sink
)
2317 if (oldtext
->insertPos
!= newtext
->insertPos
)
2318 oldtext
->showposition
= TRUE
;
2320 if (oldtext
->lt
.top
!= newtext
->lt
.top
)
2323 if ((oldtext
->leftmargin
!= newtext
->leftmargin
) ||
2324 (oldtext
->topmargin
!= newtext
->topmargin
) ||
2325 (oldtext
->rightmargin
!= newtext
->rightmargin
) ||
2326 (oldtext
->bottommargin
!= newtext
->bottommargin
))
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
;
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.
2345 if (redisplay
&& realized
)
2346 DisplayAllText(newtw
);
2348 if (realized
) _XtTextExecuteUpdate(newtw
);
2353 /*--------------------------------------------------------------------------+*/
2354 static Boolean
SetValuesHook(widget
, args
, num_args
)
2355 /*--------------------------------------------------------------------------+*/
2360 XwTextEditWidget ctx
= (XwTextEditWidget
)widget
;
2361 XwTextSource
*source
= ctx
->text
.source
;
2362 XwTextSink
*sink
= ctx
->text
.sink
;
2363 Boolean realized
= XtIsRealized(widget
);
2365 if (realized
) _XtTextPrepareToUpdate(ctx
);
2367 /* This is ugly, but need to know if user set initial_string */
2368 ((StringSourcePtr
)(source
->data
))->initial_string
= NULL
;
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
);
2375 (*(source
->check_data
))(source
);
2377 ForceBuildLineTable(ctx
);
2379 DisplayAllText(ctx
);
2380 _XtTextExecuteUpdate(ctx
);
2386 /*--------------------------------------------------------------------------+*/
2387 static void GetValuesHook(widget
, args
, num_args
)
2388 /*--------------------------------------------------------------------------+*/
2393 XwTextSource
*source
= ((XwTextEditWidget
)widget
)->text
.source
;
2394 XwTextSink
*sink
= ((XwTextEditWidget
)widget
)->text
.sink
;
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
);
2407 XtGetSubvalues(source
->data
, source
->resources
, source
->resource_num
,
2409 XtGetSubvalues(sink
->data
, sink
->resources
, sink
->resource_num
,
2413 /*--------------------------------------------------------------------------+*/
2414 static void Realize( w
, valueMask
, attributes
)
2415 /*--------------------------------------------------------------------------+*/
2418 XSetWindowAttributes
*attributes
;
2420 XwTextEditWidget ctx
= (XwTextEditWidget
)w
;
2422 *valueMask
|= CWBitGravity
;
2423 attributes
->bit_gravity
= NorthWestGravity
;
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
;
2433 XtWarning("Unable to realize TextEdit");
2439 /*****************************************************************************
2441 * Text Edit Class Record
2443 *****************************************************************************/
2444 XwTextEditClassRec XwtexteditClassRec
= {
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
2481 /* XwPrimitive fields */
2483 (XtWidgetProc
) NULL
,
2484 (XtWidgetProc
) NULL
,
2488 (XtTranslations
) NULL
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
,
2501 WidgetClass XwtexteditWidgetClass
= (WidgetClass
)&XwtexteditClassRec
;
2502 WidgetClass XwtextEditWidgetClass
= (WidgetClass
)&XwtexteditClassRec
;