1 #if (!defined(lint) && !defined(SABER))
2 static char Xrcsid
[] = "$XConsortium: TextAction.c,v 1.23 89/12/10 11:30:43 rws Exp $";
3 #endif /* lint && SABER */
5 /***********************************************************
6 Copyright 1989 by the Massachusetts Institute of Technology,
7 Cambridge, Massachusetts.
11 Permission to use, copy, modify, and distribute this software and its
12 documentation for any purpose and without fee is hereby granted,
13 provided that the above copyright notice appear in all copies and that
14 both that copyright notice and this permission notice appear in
15 supporting documentation, and that the names of Digital or MIT not be
16 used in advertising or publicity pertaining to distribution of the
17 software without specific, written prior permission.
19 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
20 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
21 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
22 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
23 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
24 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
27 ******************************************************************/
30 * NOTE: There are some ASCII Dependancies on '\n' and '\0' that I
31 * am not too thrilled with. There is also the implicit assumption
32 * that the individual characters will fit inside a "char".
33 * It would be nice if we could generalize this a but more. If
34 * anyone out there comes up with an implementation of this stuff
35 * that has no dependency on ASCII, please send the code back to us.
42 #include <stdlib.h> /* For atoi() */
44 #include <X11/Xlib.h> /* For XFetchBuffer() */
45 #include <X11/Xatom.h>
46 #include <X11/IntrinsicP.h>
47 #include <X11/StringDefs.h>
49 #include <X11/Xmu/Atoms.h>
50 #include <X11/Xmu/Misc.h>
52 #include <./Xaw3_1TextP.h>
54 #define SrcScan XawTextSourceScan
55 #define FindDist XawTextSinkFindDistance
56 #define FindPos XawTextSinkFindPosition
59 * These are defined in TextPop.c
62 void _XawTextInsertFileAction(), _XawTextInsertFile(), _XawTextSearch();
63 void _XawTextSearch(), _XawTextDoSearchAction(), _XawTextDoReplaceAction();
64 void _XawTextSetField(), _XawTextPopdownSearchAction();
67 * These are defined in Text.c
70 char * _XawTextGetText();
71 void _XawTextBuildLineTable(), _XawTextAlterSelection(), _XawTextVScroll();
72 void _XawTextSetSelection(), _XawTextCheckResize(), _XawTextExecuteUpdate();
73 void _XawTextSetScrollBars(), _XawTextClearAndCenterDisplay();
74 Atom
*_XawTextSelectionList();
75 void _XawTextPrepareToUpdate(TextWidget ctx
);
76 int _XawTextReplace(TextWidget ctx
,
77 XawTextPosition pos1
, XawTextPosition pos2
,
81 StartAction(ctx
, event
)
85 _XawTextPrepareToUpdate(ctx
);
87 switch (event
->type
) {
90 ctx
->text
.time
= event
->xbutton
.time
;
91 ctx
->text
.ev_x
= event
->xbutton
.x
;
92 ctx
->text
.ev_y
= event
->xbutton
.y
;
96 ctx
->text
.time
= event
->xkey
.time
;
97 ctx
->text
.ev_x
= event
->xkey
.x
;
98 ctx
->text
.ev_y
= event
->xkey
.y
;
101 ctx
->text
.time
= event
->xmotion
.time
;
102 ctx
->text
.ev_x
= event
->xmotion
.x
;
103 ctx
->text
.ev_y
= event
->xmotion
.y
;
107 ctx
->text
.time
= event
->xcrossing
.time
;
108 ctx
->text
.ev_x
= event
->xcrossing
.x
;
109 ctx
->text
.ev_y
= event
->xcrossing
.y
;
118 _XawTextCheckResize(ctx
);
119 _XawTextExecuteUpdate(ctx
);
127 * These functions are superceeded by insert-selection.
131 StuffFromBuffer(ctx
, buffer
)
136 text
.ptr
= XFetchBuffer(XtDisplay(ctx
), &(text
.length
), buffer
);
138 if (_XawTextReplace(ctx
, ctx
->text
.insertPos
, ctx
->text
.insertPos
, &text
)) {
139 XBell(XtDisplay(ctx
), 0);
142 ctx
->text
.insertPos
= SrcScan(ctx
->text
.source
, ctx
->text
.insertPos
,
143 XawstPositions
, XawsdRight
, text
.length
, TRUE
);
152 StartAction(ctx
, event
);
153 StuffFromBuffer(ctx
, 1);
162 StartAction(ctx
, event
);
163 StuffFromBuffer(ctx
, 0);
169 struct _SelectionList
{
175 static void GetSelection();
179 _SelectionReceived(w
, client_data
, selection
, type
, value
, length
, format
)
182 Atom
*selection
, *type
;
184 unsigned long *length
;
187 TextWidget ctx
= (TextWidget
)w
;
190 if (*type
== 0 /*XT_CONVERT_FAIL*/ || *length
== 0) {
191 struct _SelectionList
* list
= (struct _SelectionList
*)client_data
;
193 GetSelection(w
, list
->time
, list
->params
, list
->count
);
199 StartAction(ctx
, (XEvent
*)NULL
);
200 text
.ptr
= (char*)value
;
202 text
.length
= *length
;
203 text
.format
= FMT8BIT
;
204 if (_XawTextReplace(ctx
, ctx
->text
.insertPos
, ctx
->text
.insertPos
, &text
)) {
205 XBell(XtDisplay(ctx
), 0);
208 ctx
->text
.insertPos
= SrcScan(ctx
->text
.source
, ctx
->text
.insertPos
,
209 XawstPositions
, XawsdRight
, text
.length
, TRUE
);
212 _XawTextSetScrollBars(ctx
);
218 GetSelection(w
, time
, params
, num_params
)
221 String
*params
; /* selections in precedence order */
227 XmuInternStrings(XtDisplay(w
), params
, (Cardinal
)1, &selection
);
229 case XA_CUT_BUFFER0
: buffer
= 0; break;
230 case XA_CUT_BUFFER1
: buffer
= 1; break;
231 case XA_CUT_BUFFER2
: buffer
= 2; break;
232 case XA_CUT_BUFFER3
: buffer
= 3; break;
233 case XA_CUT_BUFFER4
: buffer
= 4; break;
234 case XA_CUT_BUFFER5
: buffer
= 5; break;
235 case XA_CUT_BUFFER6
: buffer
= 6; break;
236 case XA_CUT_BUFFER7
: buffer
= 7; break;
237 default: buffer
= -1;
241 unsigned long length
;
243 Atom type
= XA_STRING
;
244 char *line
= XFetchBuffer(XtDisplay(w
), &nbytes
, buffer
);
246 _SelectionReceived(w
, (caddr_t
)NULL
, &selection
, &type
, (caddr_t
)line
,
248 else if (num_params
> 1)
249 GetSelection(w
, time
, params
+1, num_params
-1);
251 struct _SelectionList
* list
;
253 list
= XtNew(struct _SelectionList
);
254 list
->params
= params
+ 1;
255 list
->count
= num_params
;
258 XtGetSelectionValue(w
, selection
, XA_STRING
,
259 (XtSelectionCallbackProc
)_SelectionReceived
,
260 (caddr_t
)list
, time
);
265 InsertSelection(w
, event
, params
, num_params
)
268 String
*params
; /* precedence list of selections to try */
269 Cardinal
*num_params
;
271 StartAction((TextWidget
)w
, event
); /* Get Time. */
272 GetSelection(w
, ((TextWidget
)w
)->text
.time
, params
, *num_params
);
273 EndAction((TextWidget
)w
);
276 /************************************************************
278 * Routines for Moving Around.
280 ************************************************************/
283 Move(ctx
, event
, dir
, type
, include
)
286 XawTextScanDirection dir
;
287 XawTextScanType type
;
290 StartAction(ctx
, event
);
291 ctx
->text
.insertPos
= SrcScan(ctx
->text
.source
, ctx
->text
.insertPos
,
292 type
, dir
, ctx
->text
.mult
, include
);
297 MoveForwardChar(w
, event
)
301 Move((TextWidget
) w
, event
, XawsdRight
, XawstPositions
, TRUE
);
305 MoveBackwardChar(w
, event
)
309 Move((TextWidget
) w
, event
, XawsdLeft
, XawstPositions
, TRUE
);
313 MoveForwardWord(w
, event
)
317 Move((TextWidget
) w
, event
, XawsdRight
, XawstWhiteSpace
, FALSE
);
321 MoveBackwardWord(w
, event
)
325 Move((TextWidget
) w
, event
, XawsdLeft
, XawstWhiteSpace
, FALSE
);
328 static void MoveForwardParagraph(w
, event
)
332 Move((TextWidget
) w
, event
, XawsdRight
, XawstParagraph
, FALSE
);
335 static void MoveBackwardParagraph(w
, event
)
339 Move((TextWidget
) w
, event
, XawsdLeft
, XawstParagraph
, FALSE
);
343 MoveToLineEnd(w
, event
)
347 Move((TextWidget
) w
, event
, XawsdRight
, XawstEOL
, FALSE
);
351 MoveToLineStart(w
, event
)
355 Move((TextWidget
) w
, event
, XawsdLeft
, XawstEOL
, FALSE
);
360 MoveLine(ctx
, event
, dir
)
363 XawTextScanDirection dir
;
365 XawTextPosition
new, next_line
, junk
;
366 int from_left
, garbage
;
368 StartAction(ctx
, event
);
370 if (dir
== XawsdLeft
)
373 new = SrcScan(ctx
->text
.source
, ctx
->text
.insertPos
,
374 XawstEOL
, XawsdLeft
, 1, FALSE
);
376 FindDist(ctx
->text
.sink
, new, ctx
->text
.margin
.left
, ctx
->text
.insertPos
,
377 &from_left
, &junk
, &garbage
);
379 new = SrcScan(ctx
->text
.source
, ctx
->text
.insertPos
, XawstEOL
, dir
,
380 ctx
->text
.mult
, (dir
== XawsdRight
));
382 next_line
= SrcScan(ctx
->text
.source
, new, XawstEOL
, XawsdRight
, 1, FALSE
);
384 FindPos(ctx
->text
.sink
, new, ctx
->text
.margin
.left
, from_left
, FALSE
,
385 &(ctx
->text
.insertPos
), &garbage
, &garbage
);
387 if (ctx
->text
.insertPos
> next_line
)
388 ctx
->text
.insertPos
= next_line
;
394 MoveNextLine(w
, event
)
398 MoveLine( (TextWidget
) w
, event
, XawsdRight
);
402 MovePreviousLine(w
, event
)
406 MoveLine( (TextWidget
) w
, event
, XawsdLeft
);
410 MoveBeginningOfFile(w
, event
)
414 Move((TextWidget
) w
, event
, XawsdLeft
, XawstAll
, TRUE
);
418 MoveEndOfFile(w
, event
)
422 Move((TextWidget
) w
, event
, XawsdRight
, XawstAll
, TRUE
);
426 Scroll(ctx
, event
, dir
)
429 XawTextScanDirection dir
;
431 StartAction(ctx
, event
);
433 if (dir
== XawsdLeft
)
434 _XawTextVScroll(ctx
, ctx
->text
.mult
);
436 _XawTextVScroll(ctx
, -ctx
->text
.mult
);
442 ScrollOneLineUp(w
, event
)
446 Scroll( (TextWidget
) w
, event
, XawsdLeft
);
450 ScrollOneLineDown(w
, event
)
454 Scroll( (TextWidget
) w
, event
, XawsdRight
);
458 MovePage(ctx
, event
, dir
)
461 XawTextScanDirection dir
;
463 int scroll_val
= Max(1, ctx
->text
.lt
.lines
- 2);
465 if (dir
== XawsdLeft
)
466 scroll_val
= -scroll_val
;
468 StartAction(ctx
, event
);
469 _XawTextVScroll(ctx
, scroll_val
);
470 ctx
->text
.insertPos
= ctx
->text
.lt
.top
;
475 MoveNextPage(w
, event
)
479 MovePage((TextWidget
) w
, event
, XawsdRight
);
483 MovePreviousPage(w
, event
)
487 MovePage((TextWidget
) w
, event
, XawsdLeft
);
490 /************************************************************
494 ************************************************************/
497 _DeleteOrKill(ctx
, from
, to
, kill
)
499 XawTextPosition from
, to
;
505 if (kill
&& from
< to
) {
506 ptr
= _XawTextGetText(ctx
, from
, to
);
507 XStoreBuffer(XtDisplay(ctx
), ptr
, strlen(ptr
), 1);
512 if (_XawTextReplace(ctx
, from
, to
, &text
)) {
513 XBell(XtDisplay(ctx
), 50);
516 ctx
->text
.insertPos
= from
;
517 ctx
->text
.showposition
= TRUE
;
521 DeleteOrKill(ctx
, event
, dir
, type
, include
, kill
)
524 XawTextScanDirection dir
;
525 XawTextScanType type
;
526 Boolean include
, kill
;
528 XawTextPosition from
, to
;
530 StartAction(ctx
, event
);
531 to
= SrcScan(ctx
->text
.source
, ctx
->text
.insertPos
,
532 type
, dir
, ctx
->text
.mult
, include
);
534 if (dir
== XawsdLeft
) {
536 to
= ctx
->text
.insertPos
;
539 from
= ctx
->text
.insertPos
;
541 _DeleteOrKill(ctx
, from
, to
, kill
);
542 _XawTextSetScrollBars(ctx
);
547 DeleteForwardChar(w
, event
)
551 DeleteOrKill((TextWidget
) w
, event
, XawsdRight
, XawstPositions
, TRUE
, FALSE
);
555 DeleteBackwardChar(w
, event
)
559 DeleteOrKill((TextWidget
) w
, event
, XawsdLeft
, XawstPositions
, TRUE
, FALSE
);
563 DeleteForwardWord(w
, event
)
567 DeleteOrKill((TextWidget
) w
, event
,
568 XawsdRight
, XawstWhiteSpace
, FALSE
, FALSE
);
572 DeleteBackwardWord(w
, event
)
576 DeleteOrKill((TextWidget
) w
, event
,
577 XawsdLeft
, XawstWhiteSpace
, FALSE
, FALSE
);
581 KillForwardWord(w
, event
)
585 DeleteOrKill((TextWidget
) w
, event
,
586 XawsdRight
, XawstWhiteSpace
, FALSE
, TRUE
);
590 KillBackwardWord(w
, event
)
594 DeleteOrKill((TextWidget
) w
, event
,
595 XawsdLeft
, XawstWhiteSpace
, FALSE
, TRUE
);
599 KillToEndOfLine(w
, event
)
603 TextWidget ctx
= (TextWidget
) w
;
604 XawTextPosition end_of_line
;
606 StartAction(ctx
, event
);
607 end_of_line
= SrcScan(ctx
->text
.source
, ctx
->text
.insertPos
, XawstEOL
,
608 XawsdRight
, ctx
->text
.mult
, FALSE
);
609 if (end_of_line
== ctx
->text
.insertPos
)
610 end_of_line
= SrcScan(ctx
->text
.source
, ctx
->text
.insertPos
, XawstEOL
,
611 XawsdRight
, ctx
->text
.mult
, TRUE
);
613 _DeleteOrKill(ctx
, ctx
->text
.insertPos
, end_of_line
, TRUE
);
615 _XawTextSetScrollBars(ctx
);
619 KillToEndOfParagraph(w
, event
)
623 DeleteOrKill((TextWidget
) w
, event
, XawsdRight
, XawstParagraph
, FALSE
, TRUE
);
627 _XawTextZapSelection(ctx
, event
, kill
)
632 StartAction(ctx
, event
);
633 _DeleteOrKill(ctx
, ctx
->text
.s
.left
, ctx
->text
.s
.right
, kill
);
635 _XawTextSetScrollBars(ctx
);
639 KillCurrentSelection(w
, event
)
643 _XawTextZapSelection( (TextWidget
) w
, event
, TRUE
);
647 DeleteCurrentSelection(w
, event
)
651 _XawTextZapSelection( (TextWidget
) w
, event
, FALSE
);
654 /************************************************************
656 * Insertion Routines.
658 ************************************************************/
661 InsertNewLineAndBackupInternal(ctx
)
664 int count
, error
= XawEditDone
;
668 ptr
= buf
= XtMalloc(sizeof(char) * ctx
->text
.mult
);
669 for (count
= 0; count
< ctx
->text
.mult
; count
++, ptr
++)
672 text
.length
= ctx
->text
.mult
;
675 text
.format
= FMT8BIT
;
677 if (_XawTextReplace(ctx
, ctx
->text
.insertPos
, ctx
->text
.insertPos
, &text
)) {
678 XBell( XtDisplay(ctx
), 50);
679 error
= XawEditError
;
682 ctx
->text
.showposition
= TRUE
;
689 InsertNewLineAndBackup(w
, event
)
693 StartAction( (TextWidget
) w
, event
);
694 (void) InsertNewLineAndBackupInternal( (TextWidget
) w
);
695 EndAction( (TextWidget
) w
);
696 _XawTextSetScrollBars( (TextWidget
) w
);
700 LocalInsertNewLine(ctx
, event
)
704 StartAction(ctx
, event
);
705 if (InsertNewLineAndBackupInternal(ctx
) == XawEditError
)
706 return(XawEditError
);
707 ctx
->text
.insertPos
= SrcScan(ctx
->text
.source
, ctx
->text
.insertPos
,
708 XawstPositions
, XawsdRight
, ctx
->text
.mult
, TRUE
);
710 _XawTextSetScrollBars(ctx
);
715 InsertNewLine(w
, event
)
719 (void) LocalInsertNewLine( (TextWidget
) w
, event
);
723 InsertNewLineAndIndent(w
, event
)
728 XawTextPosition pos1
, pos2
;
729 TextWidget ctx
= (TextWidget
) w
;
731 StartAction(ctx
, event
);
732 pos1
= SrcScan(ctx
->text
.source
, ctx
->text
.insertPos
,
733 XawstEOL
, XawsdLeft
, 1, FALSE
);
734 pos2
= SrcScan(ctx
->text
.source
, pos1
, XawstEOL
, XawsdLeft
, 1, TRUE
);
735 pos2
= SrcScan(ctx
->text
.source
, pos2
, XawstWhiteSpace
, XawsdRight
, 1, TRUE
);
736 text
.ptr
= _XawTextGetText(ctx
, pos1
, pos2
);
737 text
.length
= strlen(text
.ptr
);
738 if (LocalInsertNewLine(ctx
, event
)) return;
740 if (_XawTextReplace(ctx
,ctx
->text
.insertPos
, ctx
->text
.insertPos
, &text
)) {
741 XBell(XtDisplay(ctx
), 50);
745 ctx
->text
.insertPos
= SrcScan(ctx
->text
.source
, ctx
->text
.insertPos
,
746 XawstPositions
, XawsdRight
, text
.length
, TRUE
);
749 _XawTextSetScrollBars(ctx
);
752 /************************************************************
754 * Selection Routines.
756 *************************************************************/
759 SelectWord(w
, event
, params
, num_params
)
763 Cardinal
*num_params
;
765 TextWidget ctx
= (TextWidget
) w
;
766 XawTextPosition l
, r
;
768 StartAction(ctx
, event
);
769 l
= SrcScan(ctx
->text
.source
, ctx
->text
.insertPos
,
770 XawstWhiteSpace
, XawsdLeft
, 1, FALSE
);
771 r
= SrcScan(ctx
->text
.source
, l
, XawstWhiteSpace
, XawsdRight
, 1, FALSE
);
772 _XawTextSetSelection(ctx
, l
, r
, params
, *num_params
);
777 SelectAll(w
, event
, params
, num_params
)
781 Cardinal
*num_params
;
783 TextWidget ctx
= (TextWidget
) w
;
785 StartAction(ctx
, event
);
786 _XawTextSetSelection(ctx
,zeroPosition
,ctx
->text
.lastPos
,params
,*num_params
);
791 ModifySelection(ctx
, event
, mode
, action
, params
, num_params
)
794 XawTextSelectionMode mode
;
795 XawTextSelectionAction action
;
796 String
*params
; /* unused */
797 Cardinal
*num_params
; /* unused */
799 StartAction(ctx
, event
);
800 _XawTextAlterSelection(ctx
, mode
, action
, params
, num_params
);
806 SelectStart(w
, event
, params
, num_params
)
809 String
*params
; /* unused */
810 Cardinal
*num_params
; /* unused */
812 ModifySelection((TextWidget
) w
, event
,
813 XawsmTextSelect
, XawactionStart
, params
, num_params
);
818 SelectAdjust(w
, event
, params
, num_params
)
821 String
*params
; /* unused */
822 Cardinal
*num_params
; /* unused */
824 ModifySelection((TextWidget
) w
, event
,
825 XawsmTextSelect
, XawactionAdjust
, params
, num_params
);
829 SelectEnd(w
, event
, params
, num_params
)
833 Cardinal
*num_params
;
835 ModifySelection((TextWidget
) w
, event
,
836 XawsmTextSelect
, XawactionEnd
, params
, num_params
);
841 ExtendStart(w
, event
, params
, num_params
)
844 String
*params
; /* unused */
845 Cardinal
*num_params
; /* unused */
847 ModifySelection((TextWidget
) w
, event
,
848 XawsmTextExtend
, XawactionStart
, params
, num_params
);
853 ExtendAdjust(w
, event
, params
, num_params
)
856 String
*params
; /* unused */
857 Cardinal
*num_params
; /* unused */
859 ModifySelection((TextWidget
) w
, event
,
860 XawsmTextExtend
, XawactionAdjust
, params
, num_params
);
864 ExtendEnd(w
, event
, params
, num_params
)
868 Cardinal
*num_params
;
870 ModifySelection((TextWidget
) w
, event
,
871 XawsmTextExtend
, XawactionEnd
, params
, num_params
);
874 /************************************************************
878 ************************************************************/
882 RedrawDisplay(w
, event
)
886 StartAction( (TextWidget
) w
, event
);
887 _XawTextClearAndCenterDisplay((TextWidget
) w
);
888 EndAction( (TextWidget
) w
);
893 TextFocusIn (w
, event
)
897 TextWidget ctx
= (TextWidget
) w
;
899 ctx
->text
.hasfocus
= TRUE
;
904 TextFocusOut(w
, event
)
908 TextWidget ctx
= (TextWidget
) w
;
910 ctx
->text
.hasfocus
= FALSE
;
913 static XComposeStatus compose_status
= {NULL
, 0};
915 /* Function Name: AutoFill
916 * Description: Breaks the line at the previous word boundry when
917 * called inside InsertChar.
918 * Arguments: ctx - The text widget.
926 int width
, height
, x
, line_num
, max_width
;
927 XawTextPosition ret_pos
;
930 if ( !((ctx
->text
.auto_fill
) && (ctx
->text
.mult
== 1)) )
933 for ( line_num
= 0; line_num
< ctx
->text
.lt
.lines
; line_num
++)
934 if ( ctx
->text
.lt
.info
[line_num
].position
>= ctx
->text
.insertPos
)
936 line_num
--; /* backup a line. */
938 max_width
= Max(0, ctx
->core
.width
- HMargins(ctx
));
940 x
= ctx
->text
.margin
.left
;
941 XawTextSinkFindPosition( ctx
->text
.sink
,ctx
->text
.lt
.info
[line_num
].position
,
942 x
, max_width
, TRUE
, &ret_pos
, &width
, &height
);
944 if ( ret_pos
>= ctx
->text
.insertPos
)
950 text
.format
= FMT8BIT
;
952 _XawTextReplace(ctx
, ret_pos
- 1, ret_pos
, &text
);
960 TextWidget ctx
= (TextWidget
) w
;
961 char *ptr
, strbuf
[BUFSIZ
];
966 if ( (text
.length
= XLookupString (&event
->xkey
, strbuf
, BUFSIZ
,
967 &keysym
, &compose_status
)) == 0) {
971 text
.ptr
= ptr
= XtMalloc(sizeof(char) * text
.length
* ctx
->text
.mult
);
972 for (count
= 0 ; count
< ctx
->text
.mult
; count
++) {
973 strncpy(ptr
, strbuf
, text
.length
);
977 text
.length
= text
.length
* ctx
->text
.mult
;
979 text
.format
= FMT8BIT
;
981 StartAction(ctx
, event
);
983 error
= _XawTextReplace(ctx
, ctx
->text
.insertPos
,ctx
->text
.insertPos
, &text
);
985 if (error
== XawEditDone
) {
986 ctx
->text
.insertPos
=
987 SrcScan(ctx
->text
.source
, ctx
->text
.insertPos
,
988 XawstPositions
, XawsdRight
, text
.length
, TRUE
);
992 XBell(XtDisplay(ctx
), 50);
996 _XawTextSetScrollBars(ctx
);
1001 InsertString(w
, event
, params
, num_params
)
1005 Cardinal
*num_params
;
1007 TextWidget ctx
= (TextWidget
) w
;
1012 StartAction(ctx
, event
);
1013 for (i
= *num_params
; i
; i
--, params
++) {
1014 unsigned char hexval
;
1015 if ((*params
)[0] == '0' && (*params
)[1] == 'x' && (*params
)[2] != '\0') {
1018 for (p
= *params
+2; (c
= *p
); p
++) {
1020 if (c
>= '0' && c
<= '9')
1022 else if (c
>= 'a' && c
<= 'f')
1023 hexval
+= c
- 'a' + 10;
1024 else if (c
>= 'A' && c
<= 'F')
1025 hexval
+= c
- 'A' + 10;
1029 text
.ptr
= (char*)&hexval
;
1031 } else text
.length
= strlen(text
.ptr
= *params
);
1032 } else text
.length
= strlen(text
.ptr
= *params
);
1033 if (text
.length
== 0) continue;
1034 if (_XawTextReplace(ctx
, ctx
->text
.insertPos
,
1035 ctx
->text
.insertPos
, &text
)) {
1036 XBell(XtDisplay(ctx
), 50);
1040 ctx
->text
.insertPos
=
1041 SrcScan(ctx
->text
.source
, ctx
->text
.insertPos
,
1042 XawstPositions
, XawsdRight
, text
.length
, TRUE
);
1048 DisplayCaret(w
, event
, params
, num_params
)
1050 XEvent
*event
; /* CrossingNotify special-cased */
1051 String
*params
; /* Off, False, No, On, True, Yes, etc. */
1052 Cardinal
*num_params
; /* 0, 1 or 2 */
1054 TextWidget ctx
= (TextWidget
)w
;
1055 Boolean display_caret
= True
;
1057 if (event
->type
== EnterNotify
|| event
->type
== LeaveNotify
) {
1058 /* for Crossing events, the default case is to check the focus
1059 * field and only change the caret when focus==True. A second
1060 * argument of "always" will cause the focus field to be ignored.
1062 Boolean check_focus
= True
;
1063 if (*num_params
== 2 && strcmp(params
[1], "always") == 0)
1064 check_focus
= False
;
1065 if (check_focus
&& !event
->xcrossing
.focus
) return;
1068 if (*num_params
> 0) { /* default arg is "True" */
1070 from
.size
= strlen(from
.addr
= params
[0]);
1071 XtConvert(w
, XtRString
, &from
, XtRBoolean
, &to
);
1072 if (to
.addr
!= NULL
) display_caret
= *(Boolean
*)to
.addr
;
1073 if (ctx
->text
.display_caret
== display_caret
) return;
1075 StartAction(ctx
, event
);
1076 ctx
->text
.display_caret
= display_caret
;
1080 /* Function Name: Multiply
1081 * Description: Multiplies the current action by the number passed.
1082 * Arguments: w - the text widget.
1083 * event - ** NOT USED **.
1084 * params, num_params - The parameter list, see below.
1089 * The parameter list may contain either a number or the string 'Reset'.
1091 * A number will multiply the current multiplication factor by that number.
1092 * Many of the text widget actions will will perform n actions, where n is
1093 * the multiplication factor.
1095 * The string reset will reset the mutiplication factor to 1.
1101 Multiply(w
, event
, params
, num_params
)
1105 Cardinal
* num_params
;
1107 TextWidget ctx
= (TextWidget
) w
;
1110 if (*num_params
!= 1) {
1111 XtAppError(XtWidgetToApplicationContext(w
),
1112 "The multiply action takes exactly one argument.");
1113 XBell(XtDisplay(w
), 0);
1117 if ( (params
[0][0] == 'r') || (params
[0][0] == 'R') ) {
1118 XBell(XtDisplay(w
), 0);
1123 if ( (mult
= atoi(params
[0])) == 0 ) {
1125 sprintf(buf
, "%s %s", "Text Widget: The multiply action's argument",
1126 "must be a number greater than zero, or 'Reset'.");
1127 XtAppError(XtWidgetToApplicationContext(w
), buf
);
1128 XBell(XtDisplay(w
), 0);
1132 ctx
->text
.mult
*= mult
;
1135 /* Function Name: StripOutOldCRs
1136 * Description: strips out the old carrige returns.
1137 * Arguments: ctx - the text widget.
1138 * from - starting point.
1139 * to - the ending point
1140 * Returns: the new ending location (we may add some caracters).
1143 static XawTextPosition
1144 StripOutOldCRs(ctx
, from
, to
)
1146 XawTextPosition from
, to
;
1148 XawTextPosition startPos
, endPos
, eop_begin
, eop_end
, temp
;
1149 Widget src
= ctx
->text
.source
;
1155 text
.format
= FMT8BIT
;
1161 eop_begin
= eop_end
= startPos
= endPos
= from
;
1163 endPos
=SrcScan(src
, startPos
, XawstEOL
, XawsdRight
, 1, FALSE
);
1165 temp
=SrcScan(src
, endPos
, XawstWhiteSpace
, XawsdLeft
, 1, FALSE
);
1166 temp
=SrcScan(src
, temp
, XawstWhiteSpace
, XawsdRight
, 1, FALSE
);
1167 if (temp
> startPos
)
1173 if (endPos
>= eop_begin
) {
1175 eop_begin
= SrcScan(src
, startPos
, XawstParagraph
, XawsdRight
, 1, FALSE
);
1176 eop_end
= SrcScan(src
, startPos
, XawstParagraph
, XawsdRight
, 1, TRUE
);
1179 XawTextPosition periodPos
, next_word
;
1182 periodPos
= SrcScan(src
, endPos
, XawstPositions
, XawsdLeft
, 1, TRUE
);
1183 next_word
= SrcScan(src
, endPos
, XawstWhiteSpace
, XawsdRight
, 1, FALSE
);
1185 len
= next_word
- periodPos
;
1188 buf
= _XawTextGetText(ctx
, periodPos
, next_word
);
1189 if ( (periodPos
< endPos
) && (buf
[0] == '.') )
1190 text
.length
++; /* Put in two spaces. */
1193 * Remove all extra spaces.
1196 for (i
= 1 ; i
< len
; i
++)
1197 if ( !isspace(buf
[i
]) || ((periodPos
+ i
) >= to
) ) {
1203 to
-= (i
- text
.length
- 1);
1204 startPos
= SrcScan(src
, periodPos
, XawstPositions
, XawsdRight
, i
, TRUE
);
1205 _XawTextReplace(ctx
, endPos
, startPos
, &text
);
1206 startPos
-= i
- text
.length
;
1212 /* Function Name: InsertNewCRs
1213 * Description: Inserts the new Carrige Returns.
1214 * Arguments: ctx - the text widget.
1215 * from, to - the ends of the region.
1220 InsertNewCRs(ctx
, from
, to
)
1222 XawTextPosition from
, to
;
1224 XawTextPosition startPos
, endPos
, space
, eol
;
1226 int i
, width
, height
, len
;
1232 text
.format
= FMT8BIT
;
1236 XawTextSinkFindPosition( ctx
->text
.sink
, startPos
,
1237 (int) ctx
->text
.margin
.left
,
1238 (int) (ctx
->core
.width
- HMargins(ctx
)),
1239 TRUE
, &eol
, &width
, &height
);
1243 eol
= SrcScan(ctx
->text
.source
, eol
, XawstPositions
, XawsdLeft
, 1, TRUE
);
1244 space
= SrcScan(ctx
->text
.source
, eol
, XawstWhiteSpace
, XawsdRight
, 1,TRUE
);
1246 startPos
= endPos
= eol
;
1250 len
= (int) (space
- eol
);
1251 buf
= _XawTextGetText(ctx
, eol
, space
);
1252 for ( i
= 0 ; i
< len
; i
++)
1253 if (!isspace(buf
[i
]))
1257 endPos
= SrcScan(ctx
->text
.source
, endPos
,
1258 XawstPositions
, XawsdRight
, i
, TRUE
);
1261 _XawTextReplace(ctx
, startPos
, endPos
, &text
);
1262 startPos
= SrcScan(ctx
->text
.source
, startPos
,
1263 XawstPositions
, XawsdRight
, 1, TRUE
);
1267 /* Function Name: FormRegion
1268 * Description: Forms up the region specified.
1269 * Arguments: ctx - the text widget.
1270 * from, to - the ends of the region.
1275 FormRegion(ctx
, from
, to
)
1277 XawTextPosition from
, to
;
1279 if (from
>= to
) return;
1281 to
= StripOutOldCRs(ctx
, from
, to
);
1282 InsertNewCRs(ctx
, from
, to
);
1283 _XawTextBuildLineTable(ctx
, ctx
->text
.lt
.top
, TRUE
);
1286 /* Function Name: FromParagraph.
1287 * Description: reforms up the current paragraph.
1288 * Arguments: w - the text widget.
1289 * event - the X event.
1290 * params, num_params *** NOT USED ***.
1296 FormParagraph(w
, event
, params
, num_params
)
1300 Cardinal
* num_params
;
1302 TextWidget ctx
= (TextWidget
) w
;
1303 XawTextPosition from
, to
;
1305 StartAction(ctx
, event
);
1307 from
= SrcScan(ctx
->text
.source
, ctx
->text
.insertPos
,
1308 XawstParagraph
, XawsdLeft
, 1, FALSE
);
1309 to
= SrcScan(ctx
->text
.source
, from
,
1310 XawstParagraph
, XawsdRight
, 1, FALSE
);
1312 FormRegion(ctx
, from
, to
);
1314 _XawTextSetScrollBars(ctx
);
1317 /* Function Name: TransposeCharacters
1318 * Description: Swaps the character to the left of the mark with
1319 * the character to the right of the mark.
1320 * Arguments: w - the text widget.
1321 * event - the event that cause this action.
1322 * params, num_params *** NOT USED ***.
1328 TransposeCharacters(w
, event
, params
, num_params
)
1332 Cardinal
* num_params
;
1334 TextWidget ctx
= (TextWidget
) w
;
1335 XawTextPosition start
, end
;
1337 unsigned char * buf
, c
;
1340 StartAction(ctx
, event
);
1346 start
= SrcScan(ctx
->text
.source
, ctx
->text
.insertPos
, XawstPositions
,
1347 XawsdLeft
, 1, TRUE
);
1348 end
= SrcScan(ctx
->text
.source
, ctx
->text
.insertPos
, XawstPositions
,
1349 XawsdRight
, ctx
->text
.mult
, TRUE
);
1351 if ( (start
== ctx
->text
.insertPos
) || (end
== ctx
->text
.insertPos
) )
1352 XBell(XtDisplay(w
), 0); /* complain. */
1354 ctx
->text
.insertPos
= end
;
1357 * Retrieve text and swap the characters.
1360 buf
= (unsigned char *) _XawTextGetText(ctx
, start
, end
);
1361 text
.length
= strlen((const char *)buf
);
1363 text
.format
= FMT8BIT
;
1366 for (i
= 1 ; i
< text
.length
; i
++)
1367 buf
[i
- 1] = buf
[i
];
1371 * Store new text is source.
1374 text
.ptr
= (char *) buf
;
1375 _XawTextReplace (ctx
, start
, end
, &text
);
1377 XtFree((caddr_t
)buf
);
1382 /* Function Name: NoOp
1383 * Description: This action performs no action, and allows
1384 * the user or application programmer to unbind a
1386 * Arguments: w - the text widget.
1387 * event - *** UNUSED ***.
1388 * parms and num_params - the action parameters.
1391 * Note: If the parameter list contains the string "RingBell" then
1392 * this action will ring the bell.
1396 NoOp(w
, event
, params
, num_params
)
1400 Cardinal
*num_params
;
1402 if (*num_params
!= 1)
1405 switch(params
[0][0]) {
1408 XBell(XtDisplay(w
), 0);
1409 default: /* Fall Through */
1416 XtActionsRec textActionsTable
[] = {
1417 /* motion bindings */
1418 {"forward-character", (XtActionProc
)MoveForwardChar
},
1419 {"backward-character", (XtActionProc
)MoveBackwardChar
},
1420 {"forward-word", (XtActionProc
)MoveForwardWord
},
1421 {"backward-word", (XtActionProc
)MoveBackwardWord
},
1422 {"forward-paragraph", (XtActionProc
)MoveForwardParagraph
},
1423 {"backward-paragraph", (XtActionProc
)MoveBackwardParagraph
},
1424 {"beginning-of-line", (XtActionProc
)MoveToLineStart
},
1425 {"end-of-line", (XtActionProc
)MoveToLineEnd
},
1426 {"next-line", (XtActionProc
)MoveNextLine
},
1427 {"previous-line", (XtActionProc
)MovePreviousLine
},
1428 {"next-page", (XtActionProc
)MoveNextPage
},
1429 {"previous-page", (XtActionProc
)MovePreviousPage
},
1430 {"beginning-of-file", (XtActionProc
)MoveBeginningOfFile
},
1431 {"end-of-file", (XtActionProc
)MoveEndOfFile
},
1432 {"scroll-one-line-up", (XtActionProc
)ScrollOneLineUp
},
1433 {"scroll-one-line-down", (XtActionProc
)ScrollOneLineDown
},
1434 /* delete bindings */
1435 {"delete-next-character", (XtActionProc
)DeleteForwardChar
},
1436 {"delete-previous-character", (XtActionProc
)DeleteBackwardChar
},
1437 {"delete-next-word", (XtActionProc
)DeleteForwardWord
},
1438 {"delete-previous-word", (XtActionProc
)DeleteBackwardWord
},
1439 {"delete-selection", (XtActionProc
)DeleteCurrentSelection
},
1441 {"kill-word", (XtActionProc
)KillForwardWord
},
1442 {"backward-kill-word", (XtActionProc
)KillBackwardWord
},
1443 {"kill-selection", (XtActionProc
)KillCurrentSelection
},
1444 {"kill-to-end-of-line", (XtActionProc
)KillToEndOfLine
},
1445 {"kill-to-end-of-paragraph", (XtActionProc
)KillToEndOfParagraph
},
1447 /* unkill bindings */
1448 {"unkill", (XtActionProc
)UnKill
},
1449 {"stuff", (XtActionProc
)Stuff
},
1451 /* new line stuff */
1452 {"newline-and-indent", (XtActionProc
)InsertNewLineAndIndent
},
1453 {"newline-and-backup", (XtActionProc
)InsertNewLineAndBackup
},
1454 {"newline", (XtActionProc
)InsertNewLine
},
1455 /* Selection stuff */
1456 {"select-word", (XtActionProc
)SelectWord
},
1457 {"select-all", (XtActionProc
)SelectAll
},
1458 {"select-start", (XtActionProc
)SelectStart
},
1459 {"select-adjust", (XtActionProc
)SelectAdjust
},
1460 {"select-end", (XtActionProc
)SelectEnd
},
1461 {"extend-start", (XtActionProc
)ExtendStart
},
1462 {"extend-adjust", (XtActionProc
)ExtendAdjust
},
1463 {"extend-end", (XtActionProc
)ExtendEnd
},
1464 {"insert-selection", (XtActionProc
)InsertSelection
},
1466 {"redraw-display", (XtActionProc
)RedrawDisplay
},
1467 {"insert-file", (XtActionProc
)_XawTextInsertFile
},
1468 {"search", (XtActionProc
)_XawTextSearch
},
1469 {"insert-char", (XtActionProc
)InsertChar
},
1470 {"insert-string", (XtActionProc
)InsertString
},
1471 {"focus-in", (XtActionProc
)TextFocusIn
},
1472 {"focus-out", (XtActionProc
)TextFocusOut
},
1473 {"display-caret", (XtActionProc
)DisplayCaret
},
1474 {"multiply", (XtActionProc
)Multiply
},
1475 {"form-paragraph", (XtActionProc
)FormParagraph
},
1476 {"transpose-characters", (XtActionProc
)TransposeCharacters
},
1477 {"no-op", (XtActionProc
)NoOp
},
1478 /* Action to bind special translations for text Dialogs. */
1479 {"InsertFileAction", (XtActionProc
)_XawTextInsertFileAction
},
1480 {"DoSearchAction", (XtActionProc
)_XawTextDoSearchAction
},
1481 {"DoReplaceAction", (XtActionProc
)_XawTextDoReplaceAction
},
1482 {"SetField", (XtActionProc
)_XawTextSetField
},
1483 {"PopdownSearchAction", (XtActionProc
)_XawTextPopdownSearchAction
},
1486 Cardinal textActionsTableCount
= XtNumber(textActionsTable
);