open-src/lib/libXaw4/sun-src/Xaw3_1TextAction.c
changeset 749 d7a0cca9c876
equal deleted inserted replaced
748:15434e185476 749:d7a0cca9c876
       
     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 */
       
     4 
       
     5 /***********************************************************
       
     6 Copyright 1989 by the Massachusetts Institute of Technology,
       
     7 Cambridge, Massachusetts.
       
     8 
       
     9                         All Rights Reserved
       
    10 
       
    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.  
       
    18 
       
    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.
       
    26 
       
    27 ******************************************************************/
       
    28 
       
    29 /*
       
    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.
       
    36  *
       
    37  *						Chris D. Peterson     
       
    38  *						MIT X Consortium 
       
    39  */
       
    40 
       
    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>
       
    48 
       
    49 #include <X11/Xmu/Atoms.h>
       
    50 #include <X11/Xmu/Misc.h>
       
    51 
       
    52 #include <./Xaw3_1TextP.h>
       
    53 
       
    54 #define SrcScan                XawTextSourceScan
       
    55 #define FindDist               XawTextSinkFindDistance
       
    56 #define FindPos                XawTextSinkFindPosition
       
    57 
       
    58 /*
       
    59  * These are defined in TextPop.c
       
    60  */
       
    61 
       
    62 void _XawTextInsertFileAction(), _XawTextInsertFile(), _XawTextSearch();
       
    63 void _XawTextSearch(), _XawTextDoSearchAction(), _XawTextDoReplaceAction();
       
    64 void _XawTextSetField(), _XawTextPopdownSearchAction();
       
    65 
       
    66 /*
       
    67  * These are defined in Text.c
       
    68  */
       
    69 
       
    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);
       
    79 
       
    80 static void
       
    81 StartAction(ctx, event)
       
    82 TextWidget ctx;
       
    83 XEvent *event;
       
    84 {
       
    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;
       
   110     }
       
   111   }
       
   112 }
       
   113 
       
   114 static void
       
   115 EndAction(ctx)
       
   116 TextWidget ctx;
       
   117 {
       
   118   _XawTextCheckResize(ctx);
       
   119   _XawTextExecuteUpdate(ctx);
       
   120   ctx->text.mult = 1;
       
   121 }
       
   122 
       
   123 
       
   124 #ifdef XAW_BC
       
   125 
       
   126 /*
       
   127  * These functions are superceeded by insert-selection.
       
   128  */
       
   129 
       
   130 static void
       
   131 StuffFromBuffer(ctx, buffer)
       
   132 TextWidget ctx;
       
   133 int buffer;
       
   134 {
       
   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;
       
   141   }
       
   142   ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.insertPos,
       
   143 				XawstPositions, XawsdRight, text.length, TRUE);
       
   144   XtFree(text.ptr);
       
   145 }
       
   146 
       
   147 static void 
       
   148 UnKill(ctx, event)
       
   149 TextWidget ctx;
       
   150 XEvent *event;
       
   151 {
       
   152   StartAction(ctx, event);
       
   153   StuffFromBuffer(ctx, 1);
       
   154   EndAction(ctx);
       
   155 }
       
   156 
       
   157 static void
       
   158 Stuff(ctx, event)
       
   159 TextWidget ctx;
       
   160 XEvent *event;
       
   161 {
       
   162   StartAction(ctx, event);
       
   163   StuffFromBuffer(ctx, 0);
       
   164   EndAction(ctx);
       
   165 }
       
   166 
       
   167 #endif	/* XAW_BC */
       
   168 
       
   169 struct _SelectionList {
       
   170     String *params;
       
   171     Cardinal count;
       
   172     Time time;
       
   173 };
       
   174 
       
   175 static void GetSelection();
       
   176 
       
   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;
       
   186 {
       
   187   TextWidget ctx = (TextWidget)w;
       
   188   XawTextBlock text;
       
   189   
       
   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);
       
   195     }
       
   196     return;
       
   197   }
       
   198   
       
   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;
       
   207   }
       
   208   ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.insertPos, 
       
   209 				XawstPositions, XawsdRight, text.length, TRUE);
       
   210 
       
   211   EndAction(ctx);
       
   212   _XawTextSetScrollBars(ctx);
       
   213   XtFree(client_data);
       
   214   XtFree(value);
       
   215 }
       
   216 
       
   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;
       
   223 {
       
   224     Atom selection;
       
   225     int buffer;
       
   226 
       
   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;
       
   238     }
       
   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);
       
   261     }
       
   262 }
       
   263 
       
   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;
       
   270 {
       
   271   StartAction((TextWidget)w, event); /* Get Time. */
       
   272   GetSelection(w, ((TextWidget)w)->text.time, params, *num_params);
       
   273   EndAction((TextWidget)w);
       
   274 }
       
   275 
       
   276 /************************************************************
       
   277  *
       
   278  * Routines for Moving Around.
       
   279  *
       
   280  ************************************************************/
       
   281 
       
   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;
       
   289 {
       
   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);
       
   294 }
       
   295 
       
   296 static void 
       
   297 MoveForwardChar(w, event)
       
   298 Widget w;
       
   299 XEvent *event;
       
   300 {
       
   301    Move((TextWidget) w, event, XawsdRight, XawstPositions, TRUE);
       
   302 }
       
   303 
       
   304 static void 
       
   305 MoveBackwardChar(w, event)
       
   306 Widget w;
       
   307 XEvent *event;
       
   308 {
       
   309   Move((TextWidget) w, event, XawsdLeft, XawstPositions, TRUE);
       
   310 }
       
   311 
       
   312 static void 
       
   313 MoveForwardWord(w, event)
       
   314 Widget w;
       
   315 XEvent *event;
       
   316 {
       
   317   Move((TextWidget) w, event, XawsdRight, XawstWhiteSpace, FALSE);
       
   318 }
       
   319 
       
   320 static void 
       
   321 MoveBackwardWord(w, event)
       
   322 Widget w;
       
   323 XEvent *event;
       
   324 {
       
   325   Move((TextWidget) w, event, XawsdLeft, XawstWhiteSpace, FALSE);
       
   326 }
       
   327 
       
   328 static void MoveForwardParagraph(w, event)
       
   329 Widget w;
       
   330 XEvent *event;
       
   331 {
       
   332   Move((TextWidget) w, event, XawsdRight, XawstParagraph, FALSE);
       
   333 }
       
   334 
       
   335 static void MoveBackwardParagraph(w, event)
       
   336 Widget w;
       
   337 XEvent *event;
       
   338 {
       
   339   Move((TextWidget) w, event, XawsdLeft, XawstParagraph, FALSE);
       
   340 }
       
   341 
       
   342 static void 
       
   343 MoveToLineEnd(w, event)
       
   344 Widget w;
       
   345 XEvent *event;
       
   346 {
       
   347   Move((TextWidget) w, event, XawsdRight, XawstEOL, FALSE);
       
   348 }
       
   349 
       
   350 static void 
       
   351 MoveToLineStart(w, event)
       
   352 Widget w;
       
   353 XEvent *event;
       
   354 {
       
   355   Move((TextWidget) w, event, XawsdLeft, XawstEOL, FALSE);
       
   356 }
       
   357 
       
   358 
       
   359 static void
       
   360 MoveLine(ctx, event, dir)
       
   361 TextWidget ctx;
       
   362 XEvent *event;
       
   363 XawTextScanDirection dir;
       
   364 {
       
   365   XawTextPosition new, next_line, junk;
       
   366   int from_left, garbage;
       
   367 
       
   368   StartAction(ctx, event);
       
   369 
       
   370   if (dir == XawsdLeft)
       
   371     ctx->text.mult++;
       
   372 
       
   373   new = SrcScan(ctx->text.source, ctx->text.insertPos,
       
   374 		XawstEOL, XawsdLeft, 1, FALSE);
       
   375 
       
   376   FindDist(ctx->text.sink, new, ctx->text.margin.left, ctx->text.insertPos,
       
   377 	   &from_left, &junk, &garbage);
       
   378 
       
   379   new = SrcScan(ctx->text.source, ctx->text.insertPos, XawstEOL, dir,
       
   380 		ctx->text.mult, (dir == XawsdRight));
       
   381 
       
   382   next_line = SrcScan(ctx->text.source, new, XawstEOL, XawsdRight, 1, FALSE);
       
   383 
       
   384   FindPos(ctx->text.sink, new, ctx->text.margin.left, from_left, FALSE,
       
   385 	  &(ctx->text.insertPos), &garbage, &garbage);
       
   386   
       
   387   if (ctx->text.insertPos > next_line)
       
   388     ctx->text.insertPos = next_line;
       
   389 
       
   390   EndAction(ctx);
       
   391 }
       
   392 
       
   393 static void 
       
   394 MoveNextLine(w, event)
       
   395 Widget w;
       
   396 XEvent *event;
       
   397 {
       
   398   MoveLine( (TextWidget) w, event, XawsdRight);
       
   399 }
       
   400 
       
   401 static void 
       
   402 MovePreviousLine(w, event)
       
   403 Widget w;
       
   404 XEvent *event;
       
   405 {
       
   406   MoveLine( (TextWidget) w, event, XawsdLeft);
       
   407 }
       
   408 
       
   409 static void
       
   410 MoveBeginningOfFile(w, event)
       
   411 Widget w;
       
   412 XEvent *event;
       
   413 {
       
   414   Move((TextWidget) w, event, XawsdLeft, XawstAll, TRUE);
       
   415 }
       
   416 
       
   417 static void 
       
   418 MoveEndOfFile(w, event)
       
   419 Widget w;
       
   420 XEvent *event;
       
   421 {
       
   422   Move((TextWidget) w, event, XawsdRight, XawstAll, TRUE);
       
   423 }
       
   424 
       
   425 static void 
       
   426 Scroll(ctx, event, dir)
       
   427 TextWidget ctx;
       
   428 XEvent *event;
       
   429 XawTextScanDirection dir;
       
   430 {
       
   431   StartAction(ctx, event);
       
   432 
       
   433   if (dir == XawsdLeft)
       
   434     _XawTextVScroll(ctx, ctx->text.mult);
       
   435   else
       
   436     _XawTextVScroll(ctx, -ctx->text.mult);
       
   437 
       
   438   EndAction(ctx);
       
   439 }
       
   440 
       
   441 static void 
       
   442 ScrollOneLineUp(w, event)
       
   443 Widget w;
       
   444 XEvent *event;
       
   445 {
       
   446   Scroll( (TextWidget) w, event, XawsdLeft);
       
   447 }
       
   448 
       
   449 static void 
       
   450 ScrollOneLineDown(w, event)
       
   451 Widget w;
       
   452 XEvent *event;
       
   453 {
       
   454   Scroll( (TextWidget) w, event, XawsdRight);
       
   455 }
       
   456 
       
   457 static void 
       
   458 MovePage(ctx, event, dir)
       
   459 TextWidget ctx;
       
   460 XEvent *event;
       
   461 XawTextScanDirection dir;
       
   462 {
       
   463   int scroll_val = Max(1, ctx->text.lt.lines - 2);
       
   464 
       
   465   if (dir == XawsdLeft)
       
   466     scroll_val = -scroll_val;
       
   467 
       
   468   StartAction(ctx, event);
       
   469   _XawTextVScroll(ctx, scroll_val);
       
   470   ctx->text.insertPos = ctx->text.lt.top;
       
   471   EndAction(ctx);
       
   472 }
       
   473 
       
   474 static void 
       
   475 MoveNextPage(w, event)
       
   476 Widget w;
       
   477 XEvent *event;
       
   478 {
       
   479   MovePage((TextWidget) w, event, XawsdRight);
       
   480 }
       
   481 
       
   482 static void 
       
   483 MovePreviousPage(w, event)
       
   484 Widget w;
       
   485 XEvent *event;
       
   486 {
       
   487   MovePage((TextWidget) w, event, XawsdLeft);
       
   488 }
       
   489 
       
   490 /************************************************************
       
   491  *
       
   492  * Delete Routines.
       
   493  *
       
   494  ************************************************************/
       
   495 
       
   496 static void 
       
   497 _DeleteOrKill(ctx, from, to, kill)
       
   498 TextWidget ctx;
       
   499 XawTextPosition from, to;
       
   500 Boolean	kill;
       
   501 {
       
   502   XawTextBlock text;
       
   503   char *ptr;
       
   504   
       
   505   if (kill && from < to) {
       
   506     ptr = _XawTextGetText(ctx, from, to);
       
   507     XStoreBuffer(XtDisplay(ctx), ptr, strlen(ptr), 1);
       
   508     XtFree(ptr);
       
   509   }
       
   510   text.length = 0;
       
   511   text.firstPos = 0;
       
   512   if (_XawTextReplace(ctx, from, to, &text)) {
       
   513     XBell(XtDisplay(ctx), 50);
       
   514     return;
       
   515   }
       
   516   ctx->text.insertPos = from;
       
   517   ctx->text.showposition = TRUE; 
       
   518 }
       
   519 
       
   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;
       
   527 {
       
   528   XawTextPosition from, to;
       
   529   
       
   530   StartAction(ctx, event);
       
   531   to = SrcScan(ctx->text.source, ctx->text.insertPos,
       
   532 	       type, dir, ctx->text.mult, include);
       
   533   
       
   534   if (dir == XawsdLeft) {
       
   535     from = to;
       
   536     to = ctx->text.insertPos;
       
   537   }
       
   538   else 
       
   539     from = ctx->text.insertPos;
       
   540 
       
   541   _DeleteOrKill(ctx, from, to, kill);
       
   542   _XawTextSetScrollBars(ctx);
       
   543   EndAction(ctx);
       
   544 }
       
   545 
       
   546 static void 
       
   547 DeleteForwardChar(w, event)
       
   548 Widget w;
       
   549 XEvent *event;
       
   550 {
       
   551   DeleteOrKill((TextWidget) w, event, XawsdRight, XawstPositions, TRUE, FALSE);
       
   552 }
       
   553 
       
   554 static void
       
   555 DeleteBackwardChar(w, event)
       
   556 Widget w;
       
   557 XEvent *event;
       
   558 {
       
   559   DeleteOrKill((TextWidget) w, event, XawsdLeft, XawstPositions, TRUE, FALSE);
       
   560 }
       
   561 
       
   562 static void 
       
   563 DeleteForwardWord(w, event)
       
   564 Widget w;
       
   565 XEvent *event;
       
   566 {
       
   567   DeleteOrKill((TextWidget) w, event,
       
   568 	       XawsdRight, XawstWhiteSpace, FALSE, FALSE);
       
   569 }
       
   570 
       
   571 static void 
       
   572 DeleteBackwardWord(w, event)
       
   573 Widget w;
       
   574 XEvent *event;
       
   575 {
       
   576   DeleteOrKill((TextWidget) w, event,
       
   577 	       XawsdLeft, XawstWhiteSpace, FALSE, FALSE);
       
   578 }
       
   579 
       
   580 static void 
       
   581 KillForwardWord(w, event)
       
   582 Widget w;
       
   583 XEvent *event;
       
   584 {
       
   585   DeleteOrKill((TextWidget) w, event, 
       
   586 	       XawsdRight, XawstWhiteSpace, FALSE, TRUE);
       
   587 }
       
   588 
       
   589 static void 
       
   590 KillBackwardWord(w, event)
       
   591 TextWidget w;
       
   592 XEvent *event;
       
   593 {
       
   594   DeleteOrKill((TextWidget) w, event,
       
   595 	       XawsdLeft, XawstWhiteSpace, FALSE, TRUE);
       
   596 }
       
   597 
       
   598 static void
       
   599 KillToEndOfLine(w, event)
       
   600 Widget w;
       
   601 XEvent *event;
       
   602 {
       
   603   TextWidget ctx = (TextWidget) w;
       
   604   XawTextPosition end_of_line;
       
   605 
       
   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);
       
   612 
       
   613   _DeleteOrKill(ctx, ctx->text.insertPos, end_of_line, TRUE);
       
   614   EndAction(ctx);
       
   615   _XawTextSetScrollBars(ctx);
       
   616 }
       
   617 
       
   618 static void 
       
   619 KillToEndOfParagraph(w, event)
       
   620 Widget w;
       
   621 XEvent *event;
       
   622 {
       
   623   DeleteOrKill((TextWidget) w, event, XawsdRight, XawstParagraph, FALSE, TRUE);
       
   624 }
       
   625 
       
   626 void 
       
   627 _XawTextZapSelection(ctx, event, kill)
       
   628 TextWidget ctx;
       
   629 XEvent *event;
       
   630 Boolean kill;
       
   631 {
       
   632    StartAction(ctx, event);
       
   633    _DeleteOrKill(ctx, ctx->text.s.left, ctx->text.s.right, kill);
       
   634    EndAction(ctx);
       
   635   _XawTextSetScrollBars(ctx);
       
   636 }
       
   637 
       
   638 static void 
       
   639 KillCurrentSelection(w, event)
       
   640 Widget w;
       
   641 XEvent *event;
       
   642 {
       
   643   _XawTextZapSelection( (TextWidget) w, event, TRUE);
       
   644 }
       
   645 
       
   646 static void 
       
   647 DeleteCurrentSelection(w, event)
       
   648 Widget w;
       
   649 XEvent *event;
       
   650 {
       
   651   _XawTextZapSelection( (TextWidget) w, event, FALSE);
       
   652 }
       
   653 
       
   654 /************************************************************
       
   655  *
       
   656  * Insertion Routines.
       
   657  *
       
   658  ************************************************************/
       
   659 
       
   660 static int 
       
   661 InsertNewLineAndBackupInternal(ctx)
       
   662 TextWidget ctx;
       
   663 {
       
   664   int count, error = XawEditDone;
       
   665   XawTextBlock text;
       
   666   char *buf, *ptr;
       
   667 
       
   668   ptr = buf = XtMalloc(sizeof(char) * ctx->text.mult);
       
   669   for (count = 0; count < ctx->text.mult; count++, ptr++)
       
   670     ptr[0] = '\n';
       
   671 
       
   672   text.length = ctx->text.mult;
       
   673   text.ptr = buf;
       
   674   text.firstPos = 0;
       
   675   text.format = FMT8BIT;
       
   676 
       
   677   if (_XawTextReplace(ctx, ctx->text.insertPos, ctx->text.insertPos, &text)) {
       
   678     XBell( XtDisplay(ctx), 50);
       
   679     error = XawEditError;
       
   680   }
       
   681   else 
       
   682     ctx->text.showposition = TRUE;
       
   683 
       
   684   XtFree(buf);
       
   685   return(error);
       
   686 }
       
   687 
       
   688 static void 
       
   689 InsertNewLineAndBackup(w, event)
       
   690 Widget w;
       
   691 XEvent *event;
       
   692 {
       
   693   StartAction( (TextWidget) w, event );
       
   694   (void) InsertNewLineAndBackupInternal( (TextWidget) w );
       
   695   EndAction( (TextWidget) w );
       
   696   _XawTextSetScrollBars( (TextWidget) w);
       
   697 }
       
   698 
       
   699 static int
       
   700 LocalInsertNewLine(ctx, event)
       
   701 TextWidget ctx;
       
   702 XEvent *event;
       
   703 {
       
   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);
       
   712 }
       
   713 
       
   714 static void
       
   715 InsertNewLine(w, event)
       
   716 Widget w;
       
   717 XEvent *event;
       
   718 {
       
   719   (void) LocalInsertNewLine( (TextWidget) w, event);
       
   720 }
       
   721 
       
   722 static void 
       
   723 InsertNewLineAndIndent(w, event)
       
   724 Widget w;
       
   725 XEvent *event;
       
   726 {
       
   727   XawTextBlock text;
       
   728   XawTextPosition pos1, pos2;
       
   729   TextWidget ctx = (TextWidget) w;
       
   730 
       
   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;
       
   744   }
       
   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);
       
   750 }
       
   751 
       
   752 /************************************************************
       
   753  *
       
   754  * Selection Routines.
       
   755  *
       
   756  *************************************************************/
       
   757 
       
   758 static void 
       
   759 SelectWord(w, event, params, num_params)
       
   760 Widget w;
       
   761 XEvent *event;
       
   762 String *params;
       
   763 Cardinal *num_params;
       
   764 {
       
   765   TextWidget ctx = (TextWidget) w;
       
   766   XawTextPosition l, r;
       
   767 
       
   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);
       
   774 }
       
   775 
       
   776 static void 
       
   777 SelectAll(w, event, params, num_params)
       
   778 Widget w;
       
   779 XEvent *event;
       
   780 String *params;
       
   781 Cardinal *num_params;
       
   782 {
       
   783   TextWidget ctx = (TextWidget) w;
       
   784 
       
   785   StartAction(ctx, event);
       
   786   _XawTextSetSelection(ctx,zeroPosition,ctx->text.lastPos,params,*num_params);
       
   787   EndAction(ctx);
       
   788 }
       
   789 
       
   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 */
       
   798 {
       
   799   StartAction(ctx, event);
       
   800   _XawTextAlterSelection(ctx, mode, action, params, num_params);
       
   801   EndAction(ctx);
       
   802 }
       
   803 		
       
   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 */
       
   811 {
       
   812   ModifySelection((TextWidget) w, event, 
       
   813 		  XawsmTextSelect, XawactionStart, params, num_params);
       
   814 }
       
   815 
       
   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 */
       
   823 {
       
   824   ModifySelection((TextWidget) w, event, 
       
   825 		  XawsmTextSelect, XawactionAdjust, params, num_params);
       
   826 }
       
   827 
       
   828 static void 
       
   829 SelectEnd(w, event, params, num_params)
       
   830 Widget w;
       
   831 XEvent *event;
       
   832 String *params;
       
   833 Cardinal *num_params;
       
   834 {
       
   835   ModifySelection((TextWidget) w, event, 
       
   836 		  XawsmTextSelect, XawactionEnd, params, num_params);
       
   837 }
       
   838 
       
   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 */
       
   846 {
       
   847   ModifySelection((TextWidget) w, event, 
       
   848 		  XawsmTextExtend, XawactionStart, params, num_params);
       
   849 }
       
   850 
       
   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 */
       
   858 {
       
   859   ModifySelection((TextWidget) w, event, 
       
   860 		  XawsmTextExtend, XawactionAdjust, params, num_params);
       
   861 }
       
   862 
       
   863 static void 
       
   864 ExtendEnd(w, event, params, num_params)
       
   865 TextWidget w;
       
   866 XEvent *event;
       
   867 String *params;
       
   868 Cardinal *num_params;
       
   869 {
       
   870   ModifySelection((TextWidget) w, event, 
       
   871 		  XawsmTextExtend, XawactionEnd, params, num_params);
       
   872 }
       
   873 
       
   874 /************************************************************
       
   875  *
       
   876  * Misc. Routines.
       
   877  *
       
   878  ************************************************************/
       
   879 
       
   880 /* ARGSUSED */
       
   881 static void 
       
   882 RedrawDisplay(w, event)
       
   883 Widget w;
       
   884 XEvent *event;
       
   885 {
       
   886   StartAction( (TextWidget) w, event);
       
   887   _XawTextClearAndCenterDisplay((TextWidget) w);
       
   888   EndAction( (TextWidget) w);
       
   889 }
       
   890 
       
   891 /*ARGSUSED*/
       
   892 static void
       
   893 TextFocusIn (w, event)
       
   894 TextWidget w;
       
   895 XEvent *event;
       
   896 {
       
   897   TextWidget ctx = (TextWidget) w;
       
   898 
       
   899   ctx->text.hasfocus = TRUE; 
       
   900 }
       
   901 
       
   902 /*ARGSUSED*/
       
   903 static void
       
   904 TextFocusOut(w, event)
       
   905 TextWidget w;
       
   906 XEvent *event;
       
   907 {
       
   908   TextWidget ctx = (TextWidget) w;
       
   909 
       
   910   ctx->text.hasfocus = FALSE;
       
   911 }
       
   912 
       
   913 static XComposeStatus compose_status = {NULL, 0};
       
   914 
       
   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
       
   920  */
       
   921 
       
   922 static void
       
   923 AutoFill(ctx)
       
   924 TextWidget ctx;
       
   925 {
       
   926   int width, height, x, line_num, max_width;
       
   927   XawTextPosition ret_pos;
       
   928   XawTextBlock text;
       
   929 
       
   930   if ( !((ctx->text.auto_fill) && (ctx->text.mult == 1)) )
       
   931     return;
       
   932 
       
   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. */
       
   937 
       
   938   max_width = Max(0, ctx->core.width - HMargins(ctx));
       
   939 
       
   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);
       
   943   
       
   944   if ( ret_pos >= ctx->text.insertPos )
       
   945     return;
       
   946   
       
   947   text.ptr = "\n";
       
   948   text.length = 1;
       
   949   text.firstPos = 0;
       
   950   text.format = FMT8BIT;
       
   951 
       
   952   _XawTextReplace(ctx, ret_pos - 1, ret_pos, &text);
       
   953 }
       
   954 
       
   955 static void
       
   956 InsertChar(w, event)
       
   957 Widget w;
       
   958 XEvent *event;
       
   959 {
       
   960   TextWidget ctx = (TextWidget) w;
       
   961   char *ptr, strbuf[BUFSIZ];
       
   962   int count, error;
       
   963   KeySym keysym;
       
   964   XawTextBlock text;
       
   965 
       
   966   if ( (text.length = XLookupString (&event->xkey, strbuf, BUFSIZ,
       
   967 			       &keysym, &compose_status)) == 0) {
       
   968     return;
       
   969   }
       
   970   
       
   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;
       
   975   }
       
   976 
       
   977   text.length = text.length * ctx->text.mult;
       
   978   text.firstPos = 0;
       
   979   text.format = FMT8BIT;
       
   980   
       
   981   StartAction(ctx, event);
       
   982   
       
   983   error = _XawTextReplace(ctx, ctx->text.insertPos,ctx->text.insertPos, &text);
       
   984 
       
   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);
       
   990   }
       
   991   else 
       
   992     XBell(XtDisplay(ctx), 50);
       
   993 
       
   994   XtFree(text.ptr);
       
   995   EndAction(ctx);
       
   996   _XawTextSetScrollBars(ctx);
       
   997 }
       
   998 
       
   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;
       
  1006 {
       
  1007   TextWidget ctx = (TextWidget) w;
       
  1008   XawTextBlock text;
       
  1009   int	   i;
       
  1010 
       
  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;
       
  1027       }
       
  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;
       
  1039     }
       
  1040     ctx->text.insertPos =
       
  1041       SrcScan(ctx->text.source, ctx->text.insertPos,
       
  1042 	      XawstPositions, XawsdRight, text.length, TRUE);
       
  1043   }
       
  1044   EndAction(ctx);
       
  1045 }
       
  1046 
       
  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 */
       
  1053 {
       
  1054   TextWidget ctx = (TextWidget)w;
       
  1055   Boolean display_caret = True;
       
  1056 
       
  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.
       
  1061      */
       
  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;
       
  1066   }
       
  1067 
       
  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;
       
  1074   }
       
  1075   StartAction(ctx, event);
       
  1076   ctx->text.display_caret = display_caret;
       
  1077   EndAction(ctx);
       
  1078 }
       
  1079 
       
  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.
       
  1086  *
       
  1087  * Parameter list;
       
  1088  *  
       
  1089  * The parameter list may contain either a number or the string 'Reset'.
       
  1090  * 
       
  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.
       
  1094  *
       
  1095  * The string reset will reset the mutiplication factor to 1.
       
  1096  * 
       
  1097  */
       
  1098 
       
  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;
       
  1106 {
       
  1107   TextWidget ctx = (TextWidget) w;
       
  1108   int mult;
       
  1109 
       
  1110   if (*num_params != 1) {
       
  1111     XtAppError(XtWidgetToApplicationContext(w), 
       
  1112 	       "The multiply action takes exactly one argument.");
       
  1113     XBell(XtDisplay(w), 0);
       
  1114     return;
       
  1115   }
       
  1116 
       
  1117   if ( (params[0][0] == 'r') || (params[0][0] == 'R') ) {
       
  1118     XBell(XtDisplay(w), 0);
       
  1119     ctx->text.mult = 1;
       
  1120     return;
       
  1121   }
       
  1122 
       
  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;
       
  1130   }
       
  1131 
       
  1132   ctx->text.mult *= mult;
       
  1133 }
       
  1134 
       
  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).
       
  1141  */
       
  1142 
       
  1143 static XawTextPosition
       
  1144 StripOutOldCRs(ctx, from, to)
       
  1145 TextWidget ctx;
       
  1146 XawTextPosition from, to;
       
  1147 {
       
  1148   XawTextPosition startPos, endPos, eop_begin, eop_end, temp;
       
  1149   Widget src = ctx->text.source;
       
  1150   XawTextBlock text;
       
  1151   char *buf;
       
  1152 
       
  1153   text.ptr= "  ";
       
  1154   text.firstPos = 0;
       
  1155   text.format = FMT8BIT;
       
  1156    
       
  1157 /*
       
  1158  * Strip out CR's. 
       
  1159  */
       
  1160 
       
  1161   eop_begin = eop_end = startPos = endPos = from;
       
  1162   while (TRUE) {
       
  1163     endPos=SrcScan(src, startPos, XawstEOL, XawsdRight, 1, FALSE);
       
  1164 
       
  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;
       
  1169 
       
  1170     if (endPos >= to)
       
  1171       break;
       
  1172 
       
  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);
       
  1177     }
       
  1178     else {
       
  1179       XawTextPosition periodPos, next_word;
       
  1180       int i, len;
       
  1181 
       
  1182       periodPos= SrcScan(src, endPos, XawstPositions, XawsdLeft, 1, TRUE);
       
  1183       next_word = SrcScan(src, endPos, XawstWhiteSpace, XawsdRight, 1, FALSE);
       
  1184 
       
  1185       len = next_word - periodPos;
       
  1186 
       
  1187       text.length = 1;
       
  1188       buf = _XawTextGetText(ctx, periodPos, next_word);
       
  1189       if ( (periodPos < endPos) && (buf[0] == '.') )
       
  1190 	  text.length++;	/* Put in two spaces. */
       
  1191 
       
  1192       /*
       
  1193        * Remove all extra spaces. 
       
  1194        */
       
  1195 
       
  1196       for (i = 1 ; i < len; i++) 
       
  1197 	  if ( !isspace(buf[i]) || ((periodPos + i) >= to) ) {
       
  1198 	      break;
       
  1199 	  }
       
  1200       
       
  1201       XtFree(buf);
       
  1202 
       
  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;
       
  1207     }
       
  1208   }
       
  1209   return(to);
       
  1210 }
       
  1211 
       
  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
       
  1217  */
       
  1218 
       
  1219 static void
       
  1220 InsertNewCRs(ctx, from, to)
       
  1221 TextWidget ctx;
       
  1222 XawTextPosition from, to;
       
  1223 {
       
  1224   XawTextPosition startPos, endPos, space, eol;
       
  1225   XawTextBlock text;
       
  1226   int i, width, height, len;
       
  1227   char * buf;
       
  1228 
       
  1229   text.ptr = "\n";
       
  1230   text.length = 1;
       
  1231   text.firstPos = 0;
       
  1232   text.format = FMT8BIT;
       
  1233 
       
  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;
       
  1242 
       
  1243     eol = SrcScan(ctx->text.source, eol, XawstPositions, XawsdLeft, 1, TRUE);
       
  1244     space= SrcScan(ctx->text.source, eol, XawstWhiteSpace, XawsdRight, 1,TRUE);
       
  1245     
       
  1246     startPos = endPos = eol;
       
  1247     if (eol == space) 
       
  1248       return;
       
  1249 
       
  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;
       
  1255 
       
  1256     to -= (i - 1);
       
  1257     endPos = SrcScan(ctx->text.source, endPos,
       
  1258 		     XawstPositions, XawsdRight, i, TRUE);
       
  1259     XtFree(buf);
       
  1260     
       
  1261     _XawTextReplace(ctx, startPos, endPos, &text);
       
  1262     startPos = SrcScan(ctx->text.source, startPos,
       
  1263 		       XawstPositions, XawsdRight, 1, TRUE);
       
  1264   }
       
  1265 }  
       
  1266   
       
  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.
       
  1272  */
       
  1273 
       
  1274 static void
       
  1275 FormRegion(ctx, from, to)
       
  1276 TextWidget ctx;
       
  1277 XawTextPosition from, to;
       
  1278 {
       
  1279   if (from >= to) return;
       
  1280 
       
  1281   to = StripOutOldCRs(ctx, from, to);
       
  1282   InsertNewCRs(ctx, from, to);
       
  1283   _XawTextBuildLineTable(ctx, ctx->text.lt.top, TRUE);
       
  1284 }
       
  1285 
       
  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
       
  1292  */
       
  1293 
       
  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;
       
  1301 {
       
  1302   TextWidget ctx = (TextWidget) w;
       
  1303   XawTextPosition from, to;
       
  1304 
       
  1305   StartAction(ctx, event);
       
  1306 
       
  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);
       
  1311 
       
  1312   FormRegion(ctx, from, to);
       
  1313   EndAction(ctx);
       
  1314   _XawTextSetScrollBars(ctx);
       
  1315 }
       
  1316 
       
  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.
       
  1324  */
       
  1325 	     
       
  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;
       
  1333 {
       
  1334   TextWidget ctx = (TextWidget) w;
       
  1335   XawTextPosition start, end;
       
  1336   XawTextBlock text;
       
  1337   unsigned char * buf, c;
       
  1338   int i;
       
  1339 
       
  1340   StartAction(ctx, event);
       
  1341 
       
  1342 /*
       
  1343  * Get bounds. 
       
  1344  */
       
  1345 
       
  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);
       
  1350 
       
  1351   if ( (start == ctx->text.insertPos) || (end == ctx->text.insertPos) ) 
       
  1352     XBell(XtDisplay(w), 0);	/* complain. */
       
  1353   else {
       
  1354     ctx->text.insertPos = end;
       
  1355 
       
  1356     /*
       
  1357      * Retrieve text and swap the characters. 
       
  1358      */
       
  1359     
       
  1360     buf = (unsigned char *) _XawTextGetText(ctx, start, end);
       
  1361     text.length = strlen((const char *)buf);
       
  1362     text.firstPos = 0;
       
  1363     text.format = FMT8BIT;
       
  1364     
       
  1365     c = buf[0];
       
  1366     for (i = 1 ; i < text.length ; i++)
       
  1367       buf[i - 1] = buf[i];
       
  1368     buf[i - 1] = c;
       
  1369     
       
  1370     /* 
       
  1371      * Store new text is source.
       
  1372      */
       
  1373     
       
  1374     text.ptr = (char *) buf;
       
  1375     _XawTextReplace (ctx, start, end, &text);
       
  1376     
       
  1377     XtFree((caddr_t)buf);
       
  1378   }
       
  1379   EndAction(ctx);
       
  1380 }
       
  1381 
       
  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.
       
  1390  *
       
  1391  * Note: If the parameter list contains the string "RingBell" then
       
  1392  *       this action will ring the bell.
       
  1393  */
       
  1394 
       
  1395 static void
       
  1396 NoOp(w, event, params, num_params)
       
  1397 Widget w;
       
  1398 XEvent *event;
       
  1399 String *params;
       
  1400 Cardinal *num_params;
       
  1401 {
       
  1402     if (*num_params != 1)
       
  1403 	return;
       
  1404 
       
  1405     switch(params[0][0]) {
       
  1406     case 'R':
       
  1407     case 'r':
       
  1408 	XBell(XtDisplay(w), 0);
       
  1409     default:			/* Fall Through */
       
  1410 	break;
       
  1411     }
       
  1412 }
       
  1413 	
       
  1414 /* Action Table */
       
  1415 
       
  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},
       
  1484 };
       
  1485 
       
  1486 Cardinal textActionsTableCount = XtNumber(textActionsTable);