rust/cargo-c: update to 0.10.7+cargo-0.84.0
[oi-userland.git] / components / x11 / libXaw4 / src / Xaw3_1TextAction.c
blob0bbf9f45ab211b0bbc28f49f73fd36e2f6035c18
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.
9 All Rights Reserved
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
25 SOFTWARE.
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.
37 * Chris D. Peterson
38 * MIT X Consortium
41 #include <stdio.h>
42 #include <stdlib.h> /* For atoi() */
43 #include <ctype.h>
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,
78 XawTextBlock *text);
80 static void
81 StartAction(ctx, event)
82 TextWidget ctx;
83 XEvent *event;
85 _XawTextPrepareToUpdate(ctx);
86 if (event != NULL) {
87 switch (event->type) {
88 case ButtonPress:
89 case ButtonRelease:
90 ctx->text.time = event->xbutton.time;
91 ctx->text.ev_x = event->xbutton.x;
92 ctx->text.ev_y = event->xbutton.y;
93 break;
94 case KeyPress:
95 case KeyRelease:
96 ctx->text.time = event->xkey.time;
97 ctx->text.ev_x = event->xkey.x;
98 ctx->text.ev_y = event->xkey.y;
99 break;
100 case MotionNotify:
101 ctx->text.time = event->xmotion.time;
102 ctx->text.ev_x = event->xmotion.x;
103 ctx->text.ev_y = event->xmotion.y;
104 break;
105 case EnterNotify:
106 case LeaveNotify:
107 ctx->text.time = event->xcrossing.time;
108 ctx->text.ev_x = event->xcrossing.x;
109 ctx->text.ev_y = event->xcrossing.y;
114 static void
115 EndAction(ctx)
116 TextWidget ctx;
118 _XawTextCheckResize(ctx);
119 _XawTextExecuteUpdate(ctx);
120 ctx->text.mult = 1;
124 #ifdef XAW_BC
127 * These functions are superceeded by insert-selection.
130 static void
131 StuffFromBuffer(ctx, buffer)
132 TextWidget ctx;
133 int buffer;
135 XawTextBlock text;
136 text.ptr = XFetchBuffer(XtDisplay(ctx), &(text.length), buffer);
137 text.firstPos = 0;
138 if (_XawTextReplace(ctx, ctx->text.insertPos, ctx->text.insertPos, &text)) {
139 XBell(XtDisplay(ctx), 0);
140 return;
142 ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.insertPos,
143 XawstPositions, XawsdRight, text.length, TRUE);
144 XtFree(text.ptr);
147 static void
148 UnKill(ctx, event)
149 TextWidget ctx;
150 XEvent *event;
152 StartAction(ctx, event);
153 StuffFromBuffer(ctx, 1);
154 EndAction(ctx);
157 static void
158 Stuff(ctx, event)
159 TextWidget ctx;
160 XEvent *event;
162 StartAction(ctx, event);
163 StuffFromBuffer(ctx, 0);
164 EndAction(ctx);
167 #endif /* XAW_BC */
169 struct _SelectionList {
170 String *params;
171 Cardinal count;
172 Time time;
175 static void GetSelection();
177 /* ARGSUSED */
178 static void
179 _SelectionReceived(w, client_data, selection, type, value, length, format)
180 Widget w;
181 caddr_t client_data;
182 Atom *selection, *type;
183 caddr_t value;
184 unsigned long *length;
185 int *format;
187 TextWidget ctx = (TextWidget)w;
188 XawTextBlock text;
190 if (*type == 0 /*XT_CONVERT_FAIL*/ || *length == 0) {
191 struct _SelectionList* list = (struct _SelectionList*)client_data;
192 if (list != NULL) {
193 GetSelection(w, list->time, list->params, list->count);
194 XtFree(client_data);
196 return;
199 StartAction(ctx, (XEvent *)NULL);
200 text.ptr = (char*)value;
201 text.firstPos = 0;
202 text.length = *length;
203 text.format = FMT8BIT;
204 if (_XawTextReplace(ctx, ctx->text.insertPos, ctx->text.insertPos, &text)) {
205 XBell(XtDisplay(ctx), 0);
206 return;
208 ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.insertPos,
209 XawstPositions, XawsdRight, text.length, TRUE);
211 EndAction(ctx);
212 _XawTextSetScrollBars(ctx);
213 XtFree(client_data);
214 XtFree(value);
217 static void
218 GetSelection(w, time, params, num_params)
219 Widget w;
220 Time time;
221 String *params; /* selections in precedence order */
222 Cardinal num_params;
224 Atom selection;
225 int buffer;
227 XmuInternStrings(XtDisplay(w), params, (Cardinal)1, &selection);
228 switch (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;
239 if (buffer >= 0) {
240 int nbytes;
241 unsigned long length;
242 int fmt8 = 8;
243 Atom type = XA_STRING;
244 char *line = XFetchBuffer(XtDisplay(w), &nbytes, buffer);
245 if (length = nbytes)
246 _SelectionReceived(w, (caddr_t)NULL, &selection, &type, (caddr_t)line,
247 &length, &fmt8);
248 else if (num_params > 1)
249 GetSelection(w, time, params+1, num_params-1);
250 } else {
251 struct _SelectionList* list;
252 if (--num_params) {
253 list = XtNew(struct _SelectionList);
254 list->params = params + 1;
255 list->count = num_params;
256 list->time = time;
257 } else list = NULL;
258 XtGetSelectionValue(w, selection, XA_STRING,
259 (XtSelectionCallbackProc)_SelectionReceived,
260 (caddr_t)list, time);
264 static void
265 InsertSelection(w, event, params, num_params)
266 Widget w;
267 XEvent *event;
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 ************************************************************/
282 static void
283 Move(ctx, event, dir, type, include)
284 TextWidget ctx;
285 XEvent *event;
286 XawTextScanDirection dir;
287 XawTextScanType type;
288 Boolean include;
290 StartAction(ctx, event);
291 ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.insertPos,
292 type, dir, ctx->text.mult, include);
293 EndAction(ctx);
296 static void
297 MoveForwardChar(w, event)
298 Widget w;
299 XEvent *event;
301 Move((TextWidget) w, event, XawsdRight, XawstPositions, TRUE);
304 static void
305 MoveBackwardChar(w, event)
306 Widget w;
307 XEvent *event;
309 Move((TextWidget) w, event, XawsdLeft, XawstPositions, TRUE);
312 static void
313 MoveForwardWord(w, event)
314 Widget w;
315 XEvent *event;
317 Move((TextWidget) w, event, XawsdRight, XawstWhiteSpace, FALSE);
320 static void
321 MoveBackwardWord(w, event)
322 Widget w;
323 XEvent *event;
325 Move((TextWidget) w, event, XawsdLeft, XawstWhiteSpace, FALSE);
328 static void MoveForwardParagraph(w, event)
329 Widget w;
330 XEvent *event;
332 Move((TextWidget) w, event, XawsdRight, XawstParagraph, FALSE);
335 static void MoveBackwardParagraph(w, event)
336 Widget w;
337 XEvent *event;
339 Move((TextWidget) w, event, XawsdLeft, XawstParagraph, FALSE);
342 static void
343 MoveToLineEnd(w, event)
344 Widget w;
345 XEvent *event;
347 Move((TextWidget) w, event, XawsdRight, XawstEOL, FALSE);
350 static void
351 MoveToLineStart(w, event)
352 Widget w;
353 XEvent *event;
355 Move((TextWidget) w, event, XawsdLeft, XawstEOL, FALSE);
359 static void
360 MoveLine(ctx, event, dir)
361 TextWidget ctx;
362 XEvent *event;
363 XawTextScanDirection dir;
365 XawTextPosition new, next_line, junk;
366 int from_left, garbage;
368 StartAction(ctx, event);
370 if (dir == XawsdLeft)
371 ctx->text.mult++;
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;
390 EndAction(ctx);
393 static void
394 MoveNextLine(w, event)
395 Widget w;
396 XEvent *event;
398 MoveLine( (TextWidget) w, event, XawsdRight);
401 static void
402 MovePreviousLine(w, event)
403 Widget w;
404 XEvent *event;
406 MoveLine( (TextWidget) w, event, XawsdLeft);
409 static void
410 MoveBeginningOfFile(w, event)
411 Widget w;
412 XEvent *event;
414 Move((TextWidget) w, event, XawsdLeft, XawstAll, TRUE);
417 static void
418 MoveEndOfFile(w, event)
419 Widget w;
420 XEvent *event;
422 Move((TextWidget) w, event, XawsdRight, XawstAll, TRUE);
425 static void
426 Scroll(ctx, event, dir)
427 TextWidget ctx;
428 XEvent *event;
429 XawTextScanDirection dir;
431 StartAction(ctx, event);
433 if (dir == XawsdLeft)
434 _XawTextVScroll(ctx, ctx->text.mult);
435 else
436 _XawTextVScroll(ctx, -ctx->text.mult);
438 EndAction(ctx);
441 static void
442 ScrollOneLineUp(w, event)
443 Widget w;
444 XEvent *event;
446 Scroll( (TextWidget) w, event, XawsdLeft);
449 static void
450 ScrollOneLineDown(w, event)
451 Widget w;
452 XEvent *event;
454 Scroll( (TextWidget) w, event, XawsdRight);
457 static void
458 MovePage(ctx, event, dir)
459 TextWidget ctx;
460 XEvent *event;
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;
471 EndAction(ctx);
474 static void
475 MoveNextPage(w, event)
476 Widget w;
477 XEvent *event;
479 MovePage((TextWidget) w, event, XawsdRight);
482 static void
483 MovePreviousPage(w, event)
484 Widget w;
485 XEvent *event;
487 MovePage((TextWidget) w, event, XawsdLeft);
490 /************************************************************
492 * Delete Routines.
494 ************************************************************/
496 static void
497 _DeleteOrKill(ctx, from, to, kill)
498 TextWidget ctx;
499 XawTextPosition from, to;
500 Boolean kill;
502 XawTextBlock text;
503 char *ptr;
505 if (kill && from < to) {
506 ptr = _XawTextGetText(ctx, from, to);
507 XStoreBuffer(XtDisplay(ctx), ptr, strlen(ptr), 1);
508 XtFree(ptr);
510 text.length = 0;
511 text.firstPos = 0;
512 if (_XawTextReplace(ctx, from, to, &text)) {
513 XBell(XtDisplay(ctx), 50);
514 return;
516 ctx->text.insertPos = from;
517 ctx->text.showposition = TRUE;
520 static void
521 DeleteOrKill(ctx, event, dir, type, include, kill)
522 TextWidget ctx;
523 XEvent *event;
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) {
535 from = to;
536 to = ctx->text.insertPos;
538 else
539 from = ctx->text.insertPos;
541 _DeleteOrKill(ctx, from, to, kill);
542 _XawTextSetScrollBars(ctx);
543 EndAction(ctx);
546 static void
547 DeleteForwardChar(w, event)
548 Widget w;
549 XEvent *event;
551 DeleteOrKill((TextWidget) w, event, XawsdRight, XawstPositions, TRUE, FALSE);
554 static void
555 DeleteBackwardChar(w, event)
556 Widget w;
557 XEvent *event;
559 DeleteOrKill((TextWidget) w, event, XawsdLeft, XawstPositions, TRUE, FALSE);
562 static void
563 DeleteForwardWord(w, event)
564 Widget w;
565 XEvent *event;
567 DeleteOrKill((TextWidget) w, event,
568 XawsdRight, XawstWhiteSpace, FALSE, FALSE);
571 static void
572 DeleteBackwardWord(w, event)
573 Widget w;
574 XEvent *event;
576 DeleteOrKill((TextWidget) w, event,
577 XawsdLeft, XawstWhiteSpace, FALSE, FALSE);
580 static void
581 KillForwardWord(w, event)
582 Widget w;
583 XEvent *event;
585 DeleteOrKill((TextWidget) w, event,
586 XawsdRight, XawstWhiteSpace, FALSE, TRUE);
589 static void
590 KillBackwardWord(w, event)
591 TextWidget w;
592 XEvent *event;
594 DeleteOrKill((TextWidget) w, event,
595 XawsdLeft, XawstWhiteSpace, FALSE, TRUE);
598 static void
599 KillToEndOfLine(w, event)
600 Widget w;
601 XEvent *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);
614 EndAction(ctx);
615 _XawTextSetScrollBars(ctx);
618 static void
619 KillToEndOfParagraph(w, event)
620 Widget w;
621 XEvent *event;
623 DeleteOrKill((TextWidget) w, event, XawsdRight, XawstParagraph, FALSE, TRUE);
626 void
627 _XawTextZapSelection(ctx, event, kill)
628 TextWidget ctx;
629 XEvent *event;
630 Boolean kill;
632 StartAction(ctx, event);
633 _DeleteOrKill(ctx, ctx->text.s.left, ctx->text.s.right, kill);
634 EndAction(ctx);
635 _XawTextSetScrollBars(ctx);
638 static void
639 KillCurrentSelection(w, event)
640 Widget w;
641 XEvent *event;
643 _XawTextZapSelection( (TextWidget) w, event, TRUE);
646 static void
647 DeleteCurrentSelection(w, event)
648 Widget w;
649 XEvent *event;
651 _XawTextZapSelection( (TextWidget) w, event, FALSE);
654 /************************************************************
656 * Insertion Routines.
658 ************************************************************/
660 static int
661 InsertNewLineAndBackupInternal(ctx)
662 TextWidget ctx;
664 int count, error = XawEditDone;
665 XawTextBlock text;
666 char *buf, *ptr;
668 ptr = buf = XtMalloc(sizeof(char) * ctx->text.mult);
669 for (count = 0; count < ctx->text.mult; count++, ptr++)
670 ptr[0] = '\n';
672 text.length = ctx->text.mult;
673 text.ptr = buf;
674 text.firstPos = 0;
675 text.format = FMT8BIT;
677 if (_XawTextReplace(ctx, ctx->text.insertPos, ctx->text.insertPos, &text)) {
678 XBell( XtDisplay(ctx), 50);
679 error = XawEditError;
681 else
682 ctx->text.showposition = TRUE;
684 XtFree(buf);
685 return(error);
688 static void
689 InsertNewLineAndBackup(w, event)
690 Widget w;
691 XEvent *event;
693 StartAction( (TextWidget) w, event );
694 (void) InsertNewLineAndBackupInternal( (TextWidget) w );
695 EndAction( (TextWidget) w );
696 _XawTextSetScrollBars( (TextWidget) w);
699 static int
700 LocalInsertNewLine(ctx, event)
701 TextWidget ctx;
702 XEvent *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);
709 EndAction(ctx);
710 _XawTextSetScrollBars(ctx);
711 return(XawEditDone);
714 static void
715 InsertNewLine(w, event)
716 Widget w;
717 XEvent *event;
719 (void) LocalInsertNewLine( (TextWidget) w, event);
722 static void
723 InsertNewLineAndIndent(w, event)
724 Widget w;
725 XEvent *event;
727 XawTextBlock text;
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;
739 text.firstPos = 0;
740 if (_XawTextReplace(ctx,ctx->text.insertPos, ctx->text.insertPos, &text)) {
741 XBell(XtDisplay(ctx), 50);
742 EndAction(ctx);
743 return;
745 ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.insertPos,
746 XawstPositions, XawsdRight, text.length, TRUE);
747 XtFree(text.ptr);
748 EndAction(ctx);
749 _XawTextSetScrollBars(ctx);
752 /************************************************************
754 * Selection Routines.
756 *************************************************************/
758 static void
759 SelectWord(w, event, params, num_params)
760 Widget w;
761 XEvent *event;
762 String *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);
773 EndAction(ctx);
776 static void
777 SelectAll(w, event, params, num_params)
778 Widget w;
779 XEvent *event;
780 String *params;
781 Cardinal *num_params;
783 TextWidget ctx = (TextWidget) w;
785 StartAction(ctx, event);
786 _XawTextSetSelection(ctx,zeroPosition,ctx->text.lastPos,params,*num_params);
787 EndAction(ctx);
790 static void
791 ModifySelection(ctx, event, mode, action, params, num_params)
792 TextWidget ctx;
793 XEvent *event;
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);
801 EndAction(ctx);
804 /* ARGSUSED */
805 static void
806 SelectStart(w, event, params, num_params)
807 Widget w;
808 XEvent *event;
809 String *params; /* unused */
810 Cardinal *num_params; /* unused */
812 ModifySelection((TextWidget) w, event,
813 XawsmTextSelect, XawactionStart, params, num_params);
816 /* ARGSUSED */
817 static void
818 SelectAdjust(w, event, params, num_params)
819 Widget w;
820 XEvent *event;
821 String *params; /* unused */
822 Cardinal *num_params; /* unused */
824 ModifySelection((TextWidget) w, event,
825 XawsmTextSelect, XawactionAdjust, params, num_params);
828 static void
829 SelectEnd(w, event, params, num_params)
830 Widget w;
831 XEvent *event;
832 String *params;
833 Cardinal *num_params;
835 ModifySelection((TextWidget) w, event,
836 XawsmTextSelect, XawactionEnd, params, num_params);
839 /* ARGSUSED */
840 static void
841 ExtendStart(w, event, params, num_params)
842 Widget w;
843 XEvent *event;
844 String *params; /* unused */
845 Cardinal *num_params; /* unused */
847 ModifySelection((TextWidget) w, event,
848 XawsmTextExtend, XawactionStart, params, num_params);
851 /* ARGSUSED */
852 static void
853 ExtendAdjust(w, event, params, num_params)
854 Widget w;
855 XEvent *event;
856 String *params; /* unused */
857 Cardinal *num_params; /* unused */
859 ModifySelection((TextWidget) w, event,
860 XawsmTextExtend, XawactionAdjust, params, num_params);
863 static void
864 ExtendEnd(w, event, params, num_params)
865 TextWidget w;
866 XEvent *event;
867 String *params;
868 Cardinal *num_params;
870 ModifySelection((TextWidget) w, event,
871 XawsmTextExtend, XawactionEnd, params, num_params);
874 /************************************************************
876 * Misc. Routines.
878 ************************************************************/
880 /* ARGSUSED */
881 static void
882 RedrawDisplay(w, event)
883 Widget w;
884 XEvent *event;
886 StartAction( (TextWidget) w, event);
887 _XawTextClearAndCenterDisplay((TextWidget) w);
888 EndAction( (TextWidget) w);
891 /*ARGSUSED*/
892 static void
893 TextFocusIn (w, event)
894 TextWidget w;
895 XEvent *event;
897 TextWidget ctx = (TextWidget) w;
899 ctx->text.hasfocus = TRUE;
902 /*ARGSUSED*/
903 static void
904 TextFocusOut(w, event)
905 TextWidget w;
906 XEvent *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.
919 * Returns: none
922 static void
923 AutoFill(ctx)
924 TextWidget ctx;
926 int width, height, x, line_num, max_width;
927 XawTextPosition ret_pos;
928 XawTextBlock text;
930 if ( !((ctx->text.auto_fill) && (ctx->text.mult == 1)) )
931 return;
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 )
935 break;
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 )
945 return;
947 text.ptr = "\n";
948 text.length = 1;
949 text.firstPos = 0;
950 text.format = FMT8BIT;
952 _XawTextReplace(ctx, ret_pos - 1, ret_pos, &text);
955 static void
956 InsertChar(w, event)
957 Widget w;
958 XEvent *event;
960 TextWidget ctx = (TextWidget) w;
961 char *ptr, strbuf[BUFSIZ];
962 int count, error;
963 KeySym keysym;
964 XawTextBlock text;
966 if ( (text.length = XLookupString (&event->xkey, strbuf, BUFSIZ,
967 &keysym, &compose_status)) == 0) {
968 return;
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);
974 ptr += text.length;
977 text.length = text.length * ctx->text.mult;
978 text.firstPos = 0;
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);
989 AutoFill(ctx);
991 else
992 XBell(XtDisplay(ctx), 50);
994 XtFree(text.ptr);
995 EndAction(ctx);
996 _XawTextSetScrollBars(ctx);
999 /*ARGSUSED*/
1000 static void
1001 InsertString(w, event, params, num_params)
1002 Widget w;
1003 XEvent *event;
1004 String *params;
1005 Cardinal *num_params;
1007 TextWidget ctx = (TextWidget) w;
1008 XawTextBlock text;
1009 int i;
1011 text.firstPos = 0;
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') {
1016 char c, *p;
1017 hexval = 0;
1018 for (p = *params+2; (c = *p); p++) {
1019 hexval *= 16;
1020 if (c >= '0' && c <= '9')
1021 hexval += c - '0';
1022 else if (c >= 'a' && c <= 'f')
1023 hexval += c - 'a' + 10;
1024 else if (c >= 'A' && c <= 'F')
1025 hexval += c - 'A' + 10;
1026 else break;
1028 if (c == '\0') {
1029 text.ptr = (char*)&hexval;
1030 text.length = 1;
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);
1037 EndAction(ctx);
1038 return;
1040 ctx->text.insertPos =
1041 SrcScan(ctx->text.source, ctx->text.insertPos,
1042 XawstPositions, XawsdRight, text.length, TRUE);
1044 EndAction(ctx);
1047 static void
1048 DisplayCaret(w, event, params, num_params)
1049 Widget w;
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" */
1069 XrmValue from, to;
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;
1077 EndAction(ctx);
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.
1085 * Returns: none.
1087 * Parameter list;
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.
1099 /* ARGSUSED */
1100 static void
1101 Multiply(w, event, params, num_params)
1102 Widget w;
1103 XEvent *event;
1104 String * params;
1105 Cardinal * num_params;
1107 TextWidget ctx = (TextWidget) w;
1108 int mult;
1110 if (*num_params != 1) {
1111 XtAppError(XtWidgetToApplicationContext(w),
1112 "The multiply action takes exactly one argument.");
1113 XBell(XtDisplay(w), 0);
1114 return;
1117 if ( (params[0][0] == 'r') || (params[0][0] == 'R') ) {
1118 XBell(XtDisplay(w), 0);
1119 ctx->text.mult = 1;
1120 return;
1123 if ( (mult = atoi(params[0])) == 0 ) {
1124 char buf[BUFSIZ];
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);
1129 return;
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)
1145 TextWidget ctx;
1146 XawTextPosition from, to;
1148 XawTextPosition startPos, endPos, eop_begin, eop_end, temp;
1149 Widget src = ctx->text.source;
1150 XawTextBlock text;
1151 char *buf;
1153 text.ptr= " ";
1154 text.firstPos = 0;
1155 text.format = FMT8BIT;
1158 * Strip out CR's.
1161 eop_begin = eop_end = startPos = endPos = from;
1162 while (TRUE) {
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)
1168 endPos = temp;
1170 if (endPos >= to)
1171 break;
1173 if (endPos >= eop_begin) {
1174 startPos = eop_end;
1175 eop_begin = SrcScan(src, startPos, XawstParagraph, XawsdRight, 1, FALSE);
1176 eop_end = SrcScan(src, startPos, XawstParagraph, XawsdRight, 1, TRUE);
1178 else {
1179 XawTextPosition periodPos, next_word;
1180 int i, len;
1182 periodPos= SrcScan(src, endPos, XawstPositions, XawsdLeft, 1, TRUE);
1183 next_word = SrcScan(src, endPos, XawstWhiteSpace, XawsdRight, 1, FALSE);
1185 len = next_word - periodPos;
1187 text.length = 1;
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) ) {
1198 break;
1201 XtFree(buf);
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;
1209 return(to);
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.
1216 * Returns: none
1219 static void
1220 InsertNewCRs(ctx, from, to)
1221 TextWidget ctx;
1222 XawTextPosition from, to;
1224 XawTextPosition startPos, endPos, space, eol;
1225 XawTextBlock text;
1226 int i, width, height, len;
1227 char * buf;
1229 text.ptr = "\n";
1230 text.length = 1;
1231 text.firstPos = 0;
1232 text.format = FMT8BIT;
1234 startPos = from;
1235 while (TRUE) {
1236 XawTextSinkFindPosition( ctx->text.sink, startPos,
1237 (int) ctx->text.margin.left,
1238 (int) (ctx->core.width - HMargins(ctx)),
1239 TRUE, &eol, &width, &height);
1240 if (eol >= to)
1241 break;
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;
1247 if (eol == space)
1248 return;
1250 len = (int) (space - eol);
1251 buf = _XawTextGetText(ctx, eol, space);
1252 for ( i = 0 ; i < len ; i++)
1253 if (!isspace(buf[i]))
1254 break;
1256 to -= (i - 1);
1257 endPos = SrcScan(ctx->text.source, endPos,
1258 XawstPositions, XawsdRight, i, TRUE);
1259 XtFree(buf);
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.
1271 * Returns: none.
1274 static void
1275 FormRegion(ctx, from, to)
1276 TextWidget ctx;
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 ***.
1291 * Returns: none
1294 /* ARGSUSED */
1295 static void
1296 FormParagraph(w, event, params, num_params)
1297 Widget w;
1298 XEvent *event;
1299 String * 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);
1313 EndAction(ctx);
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 ***.
1323 * Returns: none.
1326 /* ARGSUSED */
1327 static void
1328 TransposeCharacters(w, event, params, num_params)
1329 Widget w;
1330 XEvent *event;
1331 String * params;
1332 Cardinal * num_params;
1334 TextWidget ctx = (TextWidget) w;
1335 XawTextPosition start, end;
1336 XawTextBlock text;
1337 unsigned char * buf, c;
1338 int i;
1340 StartAction(ctx, event);
1343 * Get bounds.
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. */
1353 else {
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);
1362 text.firstPos = 0;
1363 text.format = FMT8BIT;
1365 c = buf[0];
1366 for (i = 1 ; i < text.length ; i++)
1367 buf[i - 1] = buf[i];
1368 buf[i - 1] = c;
1371 * Store new text is source.
1374 text.ptr = (char *) buf;
1375 _XawTextReplace (ctx, start, end, &text);
1377 XtFree((caddr_t)buf);
1379 EndAction(ctx);
1382 /* Function Name: NoOp
1383 * Description: This action performs no action, and allows
1384 * the user or application programmer to unbind a
1385 * translation.
1386 * Arguments: w - the text widget.
1387 * event - *** UNUSED ***.
1388 * parms and num_params - the action parameters.
1389 * Returns: none.
1391 * Note: If the parameter list contains the string "RingBell" then
1392 * this action will ring the bell.
1395 static void
1396 NoOp(w, event, params, num_params)
1397 Widget w;
1398 XEvent *event;
1399 String *params;
1400 Cardinal *num_params;
1402 if (*num_params != 1)
1403 return;
1405 switch(params[0][0]) {
1406 case 'R':
1407 case 'r':
1408 XBell(XtDisplay(w), 0);
1409 default: /* Fall Through */
1410 break;
1414 /* Action Table */
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},
1440 /* kill bindings */
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},
1446 #ifdef XAW_BC
1447 /* unkill bindings */
1448 {"unkill", (XtActionProc)UnKill},
1449 {"stuff", (XtActionProc)Stuff},
1450 #endif /* XAW_BC */
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},
1465 /* Miscellaneous */
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);