00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <X11/IntrinsicP.h>
00030 #include <X11/StringDefs.h>
00031 #include <X11/Xutil.h>
00032 #include <X11/Xatom.h>
00033 #include <X11/Xmu/Misc.h>
00034 #include <X11/Xmu/StdSel.h>
00035 #include <X11/Xmu/Atoms.h>
00036 #include <X11/Xaw3d/TextP.h>
00037 #include <X11/Xaw3d/MultiSrcP.h>
00038 #include <X11/Xaw3d/XawImP.h>
00039 #include <X11/Xfuncs.h>
00040 #include "XawI18n.h"
00041 #include <stdio.h>
00042 #include <ctype.h>
00043
00044 #define SrcScan XawTextSourceScan
00045 #define FindDist XawTextSinkFindDistance
00046 #define FindPos XawTextSinkFindPosition
00047
00048 #define XawTextActionMaxHexChars 100
00049
00050
00051
00052
00053
00054 void _XawTextInsertFileAction(), _XawTextInsertFile(), _XawTextSearch();
00055 void _XawTextSearch(), _XawTextDoSearchAction(), _XawTextDoReplaceAction();
00056 void _XawTextSetField(), _XawTextPopdownSearchAction();
00057
00058
00059
00060
00061
00062 char * _XawTextGetText();
00063 void _XawTextAlterSelection(), _XawTextVScroll();
00064 void _XawTextSetSelection(), _XawTextCheckResize(), _XawTextExecuteUpdate();
00065 void _XawTextSetScrollBars(), _XawTextClearAndCenterDisplay();
00066 Atom * _XawTextSelectionList();
00067 void _XawTextPrepareToUpdate();
00068 int _XawTextReplace();
00069
00070 static void ParameterError(w, param)
00071 Widget w;
00072 String param;
00073 {
00074 String params[2];
00075 Cardinal num_params = 2;
00076 params[0] = XtName(w);
00077 params[1] = param;
00078
00079 XtAppWarningMsg( XtWidgetToApplicationContext(w),
00080 "parameterError", "textAction", "XawError",
00081 "Widget: %s Parameter: %s",
00082 params, &num_params);
00083 XBell( XtDisplay( w ), 50 );
00084 }
00085
00086 static void
00087 StartAction(ctx, event)
00088 TextWidget ctx;
00089 XEvent *event;
00090 {
00091 _XawTextPrepareToUpdate(ctx);
00092 if (event != NULL) {
00093 switch (event->type) {
00094 case ButtonPress:
00095 case ButtonRelease:
00096 ctx->text.time = event->xbutton.time;
00097 break;
00098 case KeyPress:
00099 case KeyRelease:
00100 ctx->text.time = event->xkey.time;
00101 break;
00102 case MotionNotify:
00103 ctx->text.time = event->xmotion.time;
00104 break;
00105 case EnterNotify:
00106 case LeaveNotify:
00107 ctx->text.time = event->xcrossing.time;
00108 }
00109 }
00110 }
00111
00112 static void
00113 NotePosition(ctx, event)
00114 TextWidget ctx;
00115 XEvent* event;
00116 {
00117 switch (event->type) {
00118 case ButtonPress:
00119 case ButtonRelease:
00120 ctx->text.ev_x = event->xbutton.x;
00121 ctx->text.ev_y = event->xbutton.y;
00122 break;
00123 case KeyPress:
00124 case KeyRelease:
00125 {
00126 XRectangle cursor;
00127 XawTextSinkGetCursorBounds(ctx->text.sink, &cursor);
00128 ctx->text.ev_x = cursor.x + cursor.width / 2;;
00129 ctx->text.ev_y = cursor.y + cursor.height / 2;;
00130 }
00131 break;
00132 case MotionNotify:
00133 ctx->text.ev_x = event->xmotion.x;
00134 ctx->text.ev_y = event->xmotion.y;
00135 break;
00136 case EnterNotify:
00137 case LeaveNotify:
00138 ctx->text.ev_x = event->xcrossing.x;
00139 ctx->text.ev_y = event->xcrossing.y;
00140 }
00141 }
00142
00143 static void
00144 EndAction(ctx)
00145 TextWidget ctx;
00146 {
00147 _XawTextCheckResize(ctx);
00148 _XawTextExecuteUpdate(ctx);
00149 ctx->text.mult = 1;
00150 }
00151
00152
00153 struct _SelectionList {
00154 String* params;
00155 Cardinal count;
00156 Time time;
00157 Boolean CT_asked;
00158 Atom selection;
00159 };
00160
00161 static int ProbablyMB(s)
00162 char* s;
00163 {
00164 int escapes = 0;
00165 int has_hi_bit = False;
00166
00167
00168
00169
00170 while ( (wchar_t)(*s) != (wchar_t)0 ) {
00171 if ( *s & 128 )
00172 has_hi_bit = True;
00173 if ( *s++ == '\033' )
00174 escapes++;
00175 if ( escapes >= 2 )
00176 return( 0 );
00177 }
00178 return( has_hi_bit );
00179 }
00180 static void GetSelection();
00181
00182
00183 static void
00184 _SelectionReceived(w, client_data, selection, type, value, length, format)
00185 Widget w;
00186 XtPointer client_data;
00187 Atom *selection, *type;
00188 XtPointer value;
00189 unsigned long *length;
00190 int* format;
00191 {
00192 TextWidget ctx = (TextWidget)w;
00193 XawTextBlock text;
00194
00195 if (*type == 0 || *length == 0) {
00196 struct _SelectionList* list = (struct _SelectionList*)client_data;
00197 if (list != NULL) {
00198 if (list->CT_asked) {
00199
00200
00201
00202
00203 list->CT_asked = False;
00204 XtGetSelectionValue(w, list->selection, XA_STRING, _SelectionReceived,
00205 (XtPointer)list, list->time);
00206 } else {
00207 GetSelection(w, list->time, list->params, list->count);
00208 XtFree(client_data);
00209 }
00210 }
00211 return;
00212 }
00213
00214
00215
00216
00217
00218
00219
00220 StartAction( ctx, (XEvent*) NULL );
00221 if (_XawTextFormat(ctx) == XawFmtWide) {
00222 XTextProperty textprop;
00223 Display *d = XtDisplay((Widget)ctx);
00224 wchar_t **wlist;
00225 int count;
00226 int try_CT = 1;
00227
00228
00229
00230 if ( ProbablyMB( (char *) value ) ) {
00231 char * list[1];
00232 list[0] = (char *) value;
00233 if ( XmbTextListToTextProperty( d, (char**) list, 1,
00234 XCompoundTextStyle, &textprop ) == Success )
00235 try_CT = 0;
00236 }
00237
00238
00239
00240 if ( try_CT ) {
00241 textprop.encoding = XA_COMPOUND_TEXT(d);
00242 textprop.value = (unsigned char *)value;
00243 textprop.nitems = strlen(value);
00244 textprop.format = 8;
00245 }
00246
00247 if ( XwcTextPropertyToTextList( d, &textprop, (wchar_t***) &wlist, &count )
00248 != Success) {
00249 XwcFreeStringList( (wchar_t**) wlist );
00250
00251
00252 textprop.value = (unsigned char *) " >> ILLEGAL SELECTION << ";
00253 count = 1;
00254 fprintf( stderr, "Xaw Text Widget: An attempt was made to insert an illegal selection.\n" );
00255
00256 if ( XwcTextPropertyToTextList( d, &textprop, (wchar_t***) &wlist, &count )
00257 != Success) return;
00258 }
00259
00260 XFree(value);
00261 value = (XPointer)wlist[0];
00262
00263 *length = wcslen(wlist[0]);
00264 XtFree((XtPointer)wlist);
00265 text.format = XawFmtWide;
00266 } else
00267 text.format = XawFmt8Bit;
00268 text.ptr = (char*)value;
00269 text.firstPos = 0;
00270 text.length = *length;
00271 if (_XawTextReplace(ctx, ctx->text.insertPos, ctx->text.insertPos, &text)) {
00272 XBell(XtDisplay(ctx), 0);
00273 return;
00274 }
00275 ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.insertPos,
00276 XawstPositions, XawsdRight, text.length, TRUE);
00277
00278 _XawTextSetScrollBars(ctx);
00279 EndAction(ctx);
00280 XtFree(client_data);
00281 XFree(value);
00282 }
00283
00284 static void
00285 GetSelection(w, time, params, num_params)
00286 Widget w;
00287 Time time;
00288 String* params;
00289 Cardinal num_params;
00290 {
00291 Atom selection;
00292 int buffer;
00293
00294 selection = XInternAtom(XtDisplay(w), *params, False);
00295
00296 switch (selection) {
00297 case XA_CUT_BUFFER0: buffer = 0; break;
00298 case XA_CUT_BUFFER1: buffer = 1; break;
00299 case XA_CUT_BUFFER2: buffer = 2; break;
00300 case XA_CUT_BUFFER3: buffer = 3; break;
00301 case XA_CUT_BUFFER4: buffer = 4; break;
00302 case XA_CUT_BUFFER5: buffer = 5; break;
00303 case XA_CUT_BUFFER6: buffer = 6; break;
00304 case XA_CUT_BUFFER7: buffer = 7; break;
00305 default: buffer = -1;
00306 }
00307 if (buffer >= 0) {
00308 int nbytes;
00309 unsigned long length;
00310 int fmt8 = 8;
00311 Atom type = XA_STRING;
00312 char *line = XFetchBuffer(XtDisplay(w), &nbytes, buffer);
00313 if ((length = nbytes))
00314 _SelectionReceived(w, (XtPointer) NULL, &selection, &type, (XPointer)line,
00315 &length, &fmt8);
00316 else if (num_params > 1)
00317 GetSelection(w, time, params+1, num_params-1);
00318 } else {
00319 struct _SelectionList* list;
00320 if (--num_params) {
00321 list = XtNew(struct _SelectionList);
00322 list->params = params + 1;
00323 list->count = num_params;
00324 list->time = time;
00325 list->CT_asked = True;
00326 list->selection = selection;
00327 } else list = NULL;
00328 XtGetSelectionValue(w, selection, XA_COMPOUND_TEXT(XtDisplay(w)),
00329 _SelectionReceived, (XtPointer)list, time);
00330 }
00331 }
00332
00333 static void
00334 InsertSelection(w, event, params, num_params)
00335 Widget w;
00336 XEvent* event;
00337 String* params;
00338 Cardinal* num_params;
00339 {
00340 StartAction((TextWidget)w, event);
00341 GetSelection(w, ((TextWidget)w)->text.time, params, *num_params);
00342 EndAction((TextWidget)w);
00343 }
00344
00345
00346
00347
00348
00349
00350
00351 static void
00352 Move(ctx, event, dir, type, include)
00353 TextWidget ctx;
00354 XEvent* event;
00355 XawTextScanDirection dir;
00356 XawTextScanType type;
00357 Boolean include;
00358 {
00359 StartAction(ctx, event);
00360 ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.insertPos,
00361 type, dir, ctx->text.mult, include);
00362 EndAction(ctx);
00363 }
00364
00365
00366 static void
00367 MoveForwardChar(w, event, p, n)
00368 Widget w;
00369 XEvent* event;
00370 String* p;
00371 Cardinal* n;
00372 {
00373 Move((TextWidget) w, event, XawsdRight, XawstPositions, TRUE);
00374 }
00375
00376
00377 static void
00378 MoveBackwardChar(w, event, p, n)
00379 Widget w;
00380 XEvent* event;
00381 String* p;
00382 Cardinal* n;
00383 {
00384 Move((TextWidget) w, event, XawsdLeft, XawstPositions, TRUE);
00385 }
00386
00387
00388 static void
00389 MoveForwardWord(w, event, p, n)
00390 Widget w;
00391 XEvent* event;
00392 String* p;
00393 Cardinal* n;
00394 {
00395 Move((TextWidget) w, event, XawsdRight, XawstWhiteSpace, FALSE);
00396 }
00397
00398
00399 static void
00400 MoveBackwardWord(w, event, p, n)
00401 Widget w;
00402 XEvent* event;
00403 String* p;
00404 Cardinal* n;
00405 {
00406 Move((TextWidget) w, event, XawsdLeft, XawstWhiteSpace, FALSE);
00407 }
00408
00409
00410 static void MoveForwardParagraph(w, event, p, n)
00411 Widget w;
00412 XEvent* event;
00413 String* p;
00414 Cardinal* n;
00415 {
00416 Move((TextWidget) w, event, XawsdRight, XawstParagraph, FALSE);
00417 }
00418
00419
00420 static void MoveBackwardParagraph(w, event, p, n)
00421 Widget w;
00422 XEvent* event;
00423 String* p;
00424 Cardinal* n;
00425 {
00426 Move((TextWidget) w, event, XawsdLeft, XawstParagraph, FALSE);
00427 }
00428
00429
00430 static void
00431 MoveToLineEnd(w, event, p, n)
00432 Widget w;
00433 XEvent* event;
00434 String* p;
00435 Cardinal* n;
00436 {
00437 Move((TextWidget) w, event, XawsdRight, XawstEOL, FALSE);
00438 }
00439
00440
00441 static void
00442 MoveToLineStart(w, event, p, n)
00443 Widget w;
00444 XEvent* event;
00445 String* p;
00446 Cardinal* n;
00447 {
00448 Move((TextWidget) w, event, XawsdLeft, XawstEOL, FALSE);
00449 }
00450
00451
00452 static void
00453 MoveLine(ctx, event, dir)
00454 TextWidget ctx;
00455 XEvent* event;
00456 XawTextScanDirection dir;
00457 {
00458 XawTextPosition new, next_line, junk;
00459 int from_left, garbage;
00460
00461 StartAction(ctx, event);
00462
00463 if (dir == XawsdLeft)
00464 ctx->text.mult++;
00465
00466 new = SrcScan(ctx->text.source, ctx->text.insertPos,
00467 XawstEOL, XawsdLeft, 1, FALSE);
00468
00469 FindDist(ctx->text.sink, new, ctx->text.margin.left, ctx->text.insertPos,
00470 &from_left, &junk, &garbage);
00471
00472 new = SrcScan(ctx->text.source, ctx->text.insertPos, XawstEOL, dir,
00473 ctx->text.mult, (dir == XawsdRight));
00474
00475 next_line = SrcScan(ctx->text.source, new, XawstEOL, XawsdRight, 1, FALSE);
00476
00477 FindPos(ctx->text.sink, new, ctx->text.margin.left, from_left, FALSE,
00478 &(ctx->text.insertPos), &garbage, &garbage);
00479
00480 if (ctx->text.insertPos > next_line)
00481 ctx->text.insertPos = next_line;
00482
00483 EndAction(ctx);
00484 }
00485
00486
00487 static void
00488 MoveNextLine(w, event, p, n)
00489 Widget w;
00490 XEvent* event;
00491 String* p;
00492 Cardinal* n;
00493 {
00494 MoveLine( (TextWidget) w, event, XawsdRight);
00495 }
00496
00497
00498 static void
00499 MovePreviousLine(w, event, p, n)
00500 Widget w;
00501 XEvent* event;
00502 String* p;
00503 Cardinal* n;
00504 {
00505 MoveLine( (TextWidget) w, event, XawsdLeft);
00506 }
00507
00508
00509 static void
00510 MoveBeginningOfFile(w, event, p, n)
00511 Widget w;
00512 XEvent* event;
00513 String* p;
00514 Cardinal* n;
00515 {
00516 Move((TextWidget) w, event, XawsdLeft, XawstAll, TRUE);
00517 }
00518
00519
00520 static void
00521 MoveEndOfFile(w, event, p, n)
00522 Widget w;
00523 XEvent* event;
00524 String* p;
00525 Cardinal* n;
00526 {
00527 Move((TextWidget) w, event, XawsdRight, XawstAll, TRUE);
00528 }
00529
00530 static void
00531 Scroll(ctx, event, dir)
00532 TextWidget ctx;
00533 XEvent* event;
00534 XawTextScanDirection dir;
00535 {
00536 StartAction(ctx, event);
00537
00538 if (dir == XawsdLeft)
00539 _XawTextVScroll(ctx, ctx->text.mult);
00540 else
00541 _XawTextVScroll(ctx, -ctx->text.mult);
00542
00543 EndAction(ctx);
00544 }
00545
00546
00547 static void
00548 ScrollOneLineUp(w, event, p, n)
00549 Widget w;
00550 XEvent* event;
00551 String* p;
00552 Cardinal* n;
00553 {
00554 Scroll( (TextWidget) w, event, XawsdLeft);
00555 }
00556
00557
00558 static void
00559 ScrollOneLineDown(w, event, p, n)
00560 Widget w;
00561 XEvent* event;
00562 String* p;
00563 Cardinal* n;
00564 {
00565 Scroll( (TextWidget) w, event, XawsdRight);
00566 }
00567
00568 static void
00569 MovePage(ctx, event, dir)
00570 TextWidget ctx;
00571 XEvent* event;
00572 XawTextScanDirection dir;
00573 {
00574 int scroll_val = Max(1, ctx->text.lt.lines - 2);
00575
00576 if (dir == XawsdLeft)
00577 scroll_val = -scroll_val;
00578
00579 StartAction(ctx, event);
00580 _XawTextVScroll(ctx, scroll_val);
00581 ctx->text.insertPos = ctx->text.lt.top;
00582 EndAction(ctx);
00583 }
00584
00585
00586 static void
00587 MoveNextPage(w, event, p, n)
00588 Widget w;
00589 XEvent* event;
00590 String* p;
00591 Cardinal* n;
00592 {
00593 MovePage((TextWidget) w, event, XawsdRight);
00594 }
00595
00596
00597 static void
00598 MovePreviousPage(w, event, p, n)
00599 Widget w;
00600 XEvent* event;
00601 String* p;
00602 Cardinal* n;
00603 {
00604 MovePage((TextWidget) w, event, XawsdLeft);
00605 }
00606
00607
00608
00609
00610
00611
00612
00613 static Boolean
00614 MatchSelection(selection, s)
00615 Atom selection;
00616 XawTextSelection* s;
00617 {
00618 Atom *match;
00619 int count;
00620
00621 for (count = 0, match = s->selections; count < s->atom_count; match++, count++)
00622 if (*match == selection)
00623 return True;
00624 return False;
00625 }
00626
00627 #define SrcCvtSel XawTextSourceConvertSelection
00628
00629 static Boolean
00630 ConvertSelection(w, selection, target, type, value, length, format)
00631 Widget w;
00632 Atom *selection, *target, *type;
00633 XtPointer* value;
00634 unsigned long* length;
00635 int* format;
00636 {
00637 Display* d = XtDisplay(w);
00638 TextWidget ctx = (TextWidget)w;
00639 Widget src = ctx->text.source;
00640 XawTextEditType edit_mode;
00641 Arg args[1];
00642 XawTextSelectionSalt *salt = NULL;
00643 XawTextSelection *s;
00644
00645 if (*target == XA_TARGETS(d)) {
00646 Atom* targetP, * std_targets;
00647 unsigned long std_length;
00648
00649 if ( SrcCvtSel(src, selection, target, type, value, length, format) )
00650 return True;
00651
00652 XmuConvertStandardSelection(w, ctx->text.time, selection,
00653 target, type, (XPointer*)&std_targets,
00654 &std_length, format);
00655
00656 *value = XtMalloc((unsigned) sizeof(Atom)*(std_length + 7));
00657 targetP = *(Atom**)value;
00658
00659 *length = std_length + 6;
00660 *targetP++ = XA_STRING;
00661 *targetP++ = XA_TEXT(d);
00662 *targetP++ = XA_COMPOUND_TEXT(d);
00663 *targetP++ = XA_LENGTH(d);
00664 *targetP++ = XA_LIST_LENGTH(d);
00665 *targetP++ = XA_CHARACTER_POSITION(d);
00666
00667 XtSetArg(args[0], XtNeditType,&edit_mode);
00668 XtGetValues(src, args, 1);
00669
00670 if (edit_mode == XawtextEdit) {
00671 *targetP++ = XA_DELETE(d);
00672 (*length)++;
00673 }
00674 memcpy((char*)targetP, (char*)std_targets, sizeof(Atom)*std_length);
00675 XtFree((char*)std_targets);
00676 *type = XA_ATOM;
00677 *format = 32;
00678 return True;
00679 }
00680
00681 if ( SrcCvtSel(src, selection, target, type, value, length, format) )
00682 return True;
00683
00684 for (salt = ctx->text.salt2; salt; salt = salt->next)
00685 if (MatchSelection (*selection, &salt->s))
00686 break;
00687 if (!salt)
00688 return False;
00689 s = &salt->s;
00690 if (*target == XA_STRING ||
00691 *target == XA_TEXT(d) ||
00692 *target == XA_COMPOUND_TEXT(d)) {
00693 if (*target == XA_TEXT(d)) {
00694 if (_XawTextFormat(ctx) == XawFmtWide)
00695 *type = XA_COMPOUND_TEXT(d);
00696 else
00697 *type = XA_STRING;
00698 } else {
00699 *type = *target;
00700 }
00701
00702
00703
00704
00705
00706
00707
00708 if (!salt) {
00709 *value = (char *)_XawTextGetSTRING(ctx, s->left, s->right);
00710 if (_XawTextFormat(ctx) == XawFmtWide) {
00711 XTextProperty textprop;
00712 if (XwcTextListToTextProperty(d, (wchar_t**)value, 1,
00713 XCompoundTextStyle, &textprop)
00714 < Success) {
00715 XtFree(*value);
00716 return False;
00717 }
00718 XtFree(*value);
00719 *value = (XtPointer)textprop.value;
00720 *length = textprop.nitems;
00721 } else {
00722 *length = strlen(*value);
00723 }
00724 } else {
00725 *value = XtMalloc((salt->length + 1) * sizeof(unsigned char));
00726 strcpy (*value, salt->contents);
00727 *length = salt->length;
00728 }
00729 if (_XawTextFormat(ctx) == XawFmtWide && *type == XA_STRING) {
00730 XTextProperty textprop;
00731 wchar_t** wlist;
00732 int count;
00733 textprop.encoding = XA_COMPOUND_TEXT(d);
00734 textprop.value = (unsigned char *)*value;
00735 textprop.nitems = strlen(*value);
00736 textprop.format = 8;
00737 if (XwcTextPropertyToTextList(d, &textprop, (wchar_t***)&wlist, &count)
00738 < Success) {
00739 XtFree(*value);
00740 return False;
00741 }
00742 XtFree(*value);
00743 if (XwcTextListToTextProperty(d, (wchar_t**)wlist, 1,
00744 XStringStyle, &textprop) < Success) {
00745 XwcFreeStringList( (wchar_t**) wlist );
00746 return False;
00747 }
00748 *value = (XtPointer)textprop.value;
00749 *length = textprop.nitems;
00750 XwcFreeStringList( (wchar_t**) wlist );
00751 }
00752 *format = 8;
00753 return True;
00754 }
00755
00756 if ( (*target == XA_LIST_LENGTH(d)) || (*target == XA_LENGTH(d)) ) {
00757 long * temp;
00758
00759 temp = (long *) XtMalloc(sizeof(long));
00760 if (*target == XA_LIST_LENGTH(d))
00761 *temp = 1L;
00762 else
00763 *temp = (long) (s->right - s->left);
00764
00765 *value = (XPointer) temp;
00766 *type = XA_INTEGER;
00767 *length = 1L;
00768 *format = 32;
00769 return True;
00770 }
00771
00772 if (*target == XA_CHARACTER_POSITION(d)) {
00773 long * temp;
00774
00775 temp = (long *) XtMalloc(2 * sizeof(long));
00776 temp[0] = (long) (s->left + 1);
00777 temp[1] = s->right;
00778 *value = (XPointer) temp;
00779 *type = XA_SPAN(d);
00780 *length = 2L;
00781 *format = 32;
00782 return True;
00783 }
00784
00785 if (*target == XA_DELETE(d)) {
00786 void _XawTextZapSelection();
00787
00788 if (!salt)
00789 _XawTextZapSelection( ctx, (XEvent *) NULL, TRUE);
00790 *value = NULL;
00791 *type = XA_NULL(d);
00792 *length = 0;
00793 *format = 32;
00794 return True;
00795 }
00796
00797 if (XmuConvertStandardSelection(w, ctx->text.time, selection, target, type,
00798 (XPointer *)value, length, format))
00799 return True;
00800
00801
00802 return False;
00803 }
00804
00805 static void
00806 LoseSelection(w, selection)
00807 Widget w;
00808 Atom* selection;
00809 {
00810 TextWidget ctx = (TextWidget) w;
00811 Atom* atomP;
00812 int i;
00813 XawTextSelectionSalt *salt, *prevSalt, *nextSalt;
00814
00815 prevSalt = 0;
00816 for (salt = ctx->text.salt2; salt; salt = nextSalt)
00817 {
00818 atomP = salt->s.selections;
00819 nextSalt = salt->next;
00820 for (i = 0 ; i < salt->s.atom_count; i++, atomP++)
00821 if (*selection == *atomP)
00822 *atomP = (Atom)0;
00823
00824 while (salt->s.atom_count &&
00825 salt->s.selections[salt->s.atom_count-1] == 0)
00826 {
00827 salt->s.atom_count--;
00828 }
00829
00830
00831
00832
00833
00834 atomP = salt->s.selections;
00835 for (i = 0 ; i < salt->s.atom_count; i++, atomP++)
00836 if (*atomP == (Atom)0)
00837 {
00838 *atomP = salt->s.selections[--salt->s.atom_count];
00839 while (salt->s.atom_count &&
00840 salt->s.selections[salt->s.atom_count-1] == 0)
00841 salt->s.atom_count--;
00842 }
00843 if (salt->s.atom_count == 0)
00844 {
00845 XtFree ((char *) salt->s.selections);
00846
00847
00848
00849 XtFree (salt->contents);
00850 if (prevSalt)
00851 prevSalt->next = nextSalt;
00852 else
00853 ctx->text.salt2 = nextSalt;
00854 XtFree ((char *) salt);
00855 }
00856 else
00857 prevSalt = salt;
00858 }
00859 }
00860
00861 static void
00862 _DeleteOrKill(ctx, from, to, kill)
00863 TextWidget ctx;
00864 XawTextPosition from, to;
00865 Boolean kill;
00866 {
00867 XawTextBlock text;
00868
00869 if (kill && from < to) {
00870 XawTextSelectionSalt *salt;
00871 Atom selection = XInternAtom(XtDisplay(ctx), "SECONDARY", False);
00872
00873 LoseSelection ((Widget) ctx, &selection);
00874 salt = (XawTextSelectionSalt *) XtMalloc (sizeof (XawTextSelectionSalt));
00875 if (!salt)
00876 return;
00877 salt->s.selections = (Atom *) XtMalloc (sizeof (Atom));
00878 if (!salt->s.selections)
00879 {
00880 XtFree ((char *) salt);
00881 return;
00882 }
00883 salt->s.left = from;
00884 salt->s.right = to;
00885 salt->contents = (char *)_XawTextGetSTRING(ctx, from, to);
00886 if (_XawTextFormat(ctx) == XawFmtWide) {
00887 XTextProperty textprop;
00888 if (XwcTextListToTextProperty(XtDisplay((Widget)ctx),
00889 (wchar_t**)(&(salt->contents)), 1, XCompoundTextStyle,
00890 &textprop) < Success) {
00891 XtFree(salt->contents);
00892 salt->length = 0;
00893 return;
00894 }
00895 XtFree(salt->contents);
00896 salt->contents = (char *)textprop.value;
00897 salt->length = textprop.nitems;
00898 } else
00899 salt->length = strlen (salt->contents);
00900 salt->next = ctx->text.salt2;
00901 ctx->text.salt2 = salt;
00902 salt->s.selections[0] = selection;
00903 XtOwnSelection ((Widget) ctx, selection, ctx->text.time,
00904 ConvertSelection, LoseSelection, NULL);
00905 salt->s.atom_count = 1;
00906
00907
00908
00909
00910 }
00911 text.length = 0;
00912 text.firstPos = 0;
00913
00914 text.format = _XawTextFormat(ctx);
00915 text.ptr = "";
00916
00917 if (_XawTextReplace(ctx, from, to, &text)) {
00918 XBell(XtDisplay(ctx), 50);
00919 return;
00920 }
00921 ctx->text.insertPos = from;
00922 ctx->text.showposition = TRUE;
00923 }
00924
00925 static void
00926 DeleteOrKill(ctx, event, dir, type, include, kill)
00927 TextWidget ctx;
00928 XEvent* event;
00929 XawTextScanDirection dir;
00930 XawTextScanType type;
00931 Boolean include, kill;
00932 {
00933 XawTextPosition from, to;
00934
00935 StartAction(ctx, event);
00936 to = SrcScan(ctx->text.source, ctx->text.insertPos,
00937 type, dir, ctx->text.mult, include);
00938
00939
00940
00941
00942
00943
00944
00945 if (to == ctx->text.insertPos)
00946 to = SrcScan(ctx->text.source, ctx->text.insertPos,
00947 type, dir, ctx->text.mult + 1, include);
00948
00949 if (dir == XawsdLeft) {
00950 from = to;
00951 to = ctx->text.insertPos;
00952 }
00953 else
00954 from = ctx->text.insertPos;
00955
00956 _DeleteOrKill(ctx, from, to, kill);
00957 _XawTextSetScrollBars(ctx);
00958 EndAction(ctx);
00959 }
00960
00961
00962 static void
00963 DeleteForwardChar(w, event, p, n)
00964 Widget w;
00965 XEvent* event;
00966 String* p;
00967 Cardinal* n;
00968 {
00969 DeleteOrKill((TextWidget) w, event, XawsdRight, XawstPositions, TRUE, FALSE);
00970 }
00971
00972
00973 static void
00974 DeleteBackwardChar(w, event, p, n)
00975 Widget w;
00976 XEvent* event;
00977 String* p;
00978 Cardinal* n;
00979 {
00980 DeleteOrKill((TextWidget) w, event, XawsdLeft, XawstPositions, TRUE, FALSE);
00981 }
00982
00983
00984 static void
00985 DeleteForwardWord(w, event, p, n)
00986 Widget w;
00987 XEvent* event;
00988 String* p;
00989 Cardinal* n;
00990 {
00991 DeleteOrKill((TextWidget) w, event,
00992 XawsdRight, XawstWhiteSpace, FALSE, FALSE);
00993 }
00994
00995
00996 static void
00997 DeleteBackwardWord(w, event, p, n)
00998 Widget w;
00999 XEvent* event;
01000 String* p;
01001 Cardinal* n;
01002 {
01003 DeleteOrKill((TextWidget) w, event,
01004 XawsdLeft, XawstWhiteSpace, FALSE, FALSE);
01005 }
01006
01007
01008 static void
01009 KillForwardWord(w, event, p, n)
01010 Widget w;
01011 XEvent* event;
01012 String* p;
01013 Cardinal* n;
01014 {
01015 DeleteOrKill((TextWidget) w, event,
01016 XawsdRight, XawstWhiteSpace, FALSE, TRUE);
01017 }
01018
01019
01020 static void
01021 KillBackwardWord(w, event, p, n)
01022 Widget w;
01023 XEvent* event;
01024 String* p;
01025 Cardinal* n;
01026 {
01027 DeleteOrKill((TextWidget) w, event,
01028 XawsdLeft, XawstWhiteSpace, FALSE, TRUE);
01029 }
01030
01031
01032 static void
01033 KillToEndOfLine(w, event, p, n)
01034 Widget w;
01035 XEvent* event;
01036 String* p;
01037 Cardinal* n;
01038 {
01039 TextWidget ctx = (TextWidget) w;
01040 XawTextPosition end_of_line;
01041
01042 StartAction(ctx, event);
01043 end_of_line = SrcScan(ctx->text.source, ctx->text.insertPos, XawstEOL,
01044 XawsdRight, ctx->text.mult, FALSE);
01045 if (end_of_line == ctx->text.insertPos)
01046 end_of_line = SrcScan(ctx->text.source, ctx->text.insertPos, XawstEOL,
01047 XawsdRight, ctx->text.mult, TRUE);
01048
01049 _DeleteOrKill(ctx, ctx->text.insertPos, end_of_line, TRUE);
01050 _XawTextSetScrollBars(ctx);
01051 EndAction(ctx);
01052 }
01053
01054
01055 static void
01056 KillToEndOfParagraph(w, event, p, n)
01057 Widget w;
01058 XEvent* event;
01059 String* p;
01060 Cardinal* n;
01061 {
01062 DeleteOrKill((TextWidget) w, event, XawsdRight, XawstParagraph, FALSE, TRUE);
01063 }
01064
01065 void
01066 _XawTextZapSelection(ctx, event, kill)
01067 TextWidget ctx;
01068 XEvent* event;
01069 Boolean kill;
01070 {
01071 StartAction(ctx, event);
01072 _DeleteOrKill(ctx, ctx->text.s.left, ctx->text.s.right, kill);
01073 _XawTextSetScrollBars(ctx);
01074 EndAction(ctx);
01075 }
01076
01077
01078 static void
01079 KillCurrentSelection(w, event, p, n)
01080 Widget w;
01081 XEvent* event;
01082 String* p;
01083 Cardinal* n;
01084 {
01085 _XawTextZapSelection( (TextWidget) w, event, TRUE);
01086 }
01087
01088
01089 static void
01090 DeleteCurrentSelection(w, event, p, n)
01091 Widget w;
01092 XEvent* event;
01093 String* p;
01094 Cardinal* n;
01095 {
01096 _XawTextZapSelection( (TextWidget) w, event, FALSE);
01097 }
01098
01099
01100
01101
01102
01103
01104
01105 static int
01106 InsertNewLineAndBackupInternal(ctx)
01107 TextWidget ctx;
01108 {
01109 int count, error = XawEditDone;
01110 XawTextBlock text;
01111
01112 text.format = _XawTextFormat(ctx);
01113 text.length = ctx->text.mult;
01114 text.firstPos = 0;
01115
01116 if ( text.format == XawFmtWide ) {
01117 wchar_t* wptr;
01118 text.ptr = XtMalloc(sizeof(wchar_t) * ctx->text.mult);
01119 wptr = (wchar_t *)text.ptr;
01120 for (count = 0; count < ctx->text.mult; count++ )
01121 wptr[count] = _Xaw_atowc(XawLF);
01122 }
01123 else {
01124 text.ptr = XtMalloc(sizeof(char) * ctx->text.mult);
01125 for (count = 0; count < ctx->text.mult; count++ )
01126 text.ptr[count] = XawLF;
01127 }
01128
01129 if (_XawTextReplace(ctx, ctx->text.insertPos, ctx->text.insertPos, &text)) {
01130 XBell( XtDisplay(ctx), 50);
01131 error = XawEditError;
01132 }
01133 else
01134 ctx->text.showposition = TRUE;
01135
01136 XtFree( text.ptr );
01137 return( error );
01138 }
01139
01140
01141 static void
01142 InsertNewLineAndBackup(w, event, p, n)
01143 Widget w;
01144 XEvent* event;
01145 String* p;
01146 Cardinal* n;
01147 {
01148 StartAction( (TextWidget) w, event );
01149 (void) InsertNewLineAndBackupInternal( (TextWidget) w );
01150 _XawTextSetScrollBars( (TextWidget) w);
01151 EndAction( (TextWidget) w );
01152 }
01153
01154 static int
01155 LocalInsertNewLine(ctx, event)
01156 TextWidget ctx;
01157 XEvent* event;
01158 {
01159 StartAction(ctx, event);
01160 if (InsertNewLineAndBackupInternal(ctx) == XawEditError)
01161 return(XawEditError);
01162 ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.insertPos,
01163 XawstPositions, XawsdRight, ctx->text.mult, TRUE);
01164 _XawTextSetScrollBars(ctx);
01165 EndAction(ctx);
01166 return(XawEditDone);
01167 }
01168
01169
01170 static void
01171 InsertNewLine(w, event, p, n)
01172 Widget w;
01173 XEvent* event;
01174 String* p;
01175 Cardinal* n;
01176 {
01177 (void) LocalInsertNewLine( (TextWidget) w, event);
01178 }
01179
01180
01181 static void
01182 InsertNewLineAndIndent(w, event, p, n)
01183 Widget w;
01184 XEvent *event;
01185 String *p;
01186 Cardinal *n;
01187 {
01188 XawTextBlock text;
01189 XawTextPosition pos1;
01190 int length;
01191 TextWidget ctx = (TextWidget) w;
01192 String line_to_ip;
01193
01194 StartAction(ctx, event);
01195 pos1 = SrcScan(ctx->text.source, ctx->text.insertPos,
01196 XawstEOL, XawsdLeft, 1, FALSE);
01197
01198 line_to_ip = _XawTextGetText(ctx, pos1, ctx->text.insertPos);
01199
01200 text.format = _XawTextFormat(ctx);
01201 text.firstPos = 0;
01202
01203 if ( text.format == XawFmtWide ) {
01204 wchar_t* ptr;
01205 text.ptr = XtMalloc( ( 2 + wcslen((wchar_t*)line_to_ip) ) * sizeof(wchar_t) );
01206
01207 ptr = (wchar_t*)text.ptr;
01208 ptr[0] = _Xaw_atowc( XawLF );
01209 wcscpy( (wchar_t*) ++ptr, (wchar_t*) line_to_ip );
01210
01211 length = wcslen((wchar_t*)text.ptr);
01212 while ( length && ( iswspace(*ptr) || ( *ptr == _Xaw_atowc(XawTAB) ) ) )
01213 ptr++, length--;
01214 *ptr = (wchar_t)0;
01215 text.length = wcslen((wchar_t*)text.ptr);
01216
01217 } else {
01218 char *ptr;
01219 length = strlen(line_to_ip);
01220
01221
01222
01223
01224
01225
01226
01227
01228 text.ptr = XtMalloc( ( 2 + length ) * sizeof( char ) );
01229
01230 ptr = text.ptr;
01231 ptr[0] = XawLF;
01232 strcpy( ++ptr, line_to_ip );
01233
01234 length++;
01235 while ( length && ( isspace(*ptr) || ( *ptr == XawTAB ) ) )
01236 ptr++, length--;
01237 *ptr = '\0';
01238 text.length = strlen(text.ptr);
01239 }
01240 XtFree( line_to_ip );
01241
01242 if (_XawTextReplace(ctx,ctx->text.insertPos, ctx->text.insertPos, &text)) {
01243 XBell(XtDisplay(ctx), 50);
01244 XtFree(text.ptr);
01245 EndAction(ctx);
01246 return;
01247 }
01248 XtFree(text.ptr);
01249 ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.insertPos,
01250 XawstPositions, XawsdRight, text.length, TRUE);
01251 _XawTextSetScrollBars(ctx);
01252 EndAction(ctx);
01253 }
01254
01255
01256
01257
01258
01259
01260
01261 static void
01262 SelectWord(w, event, params, num_params)
01263 Widget w;
01264 XEvent* event;
01265 String* params;
01266 Cardinal* num_params;
01267 {
01268 TextWidget ctx = (TextWidget) w;
01269 XawTextPosition l, r;
01270
01271 StartAction(ctx, event);
01272 l = SrcScan(ctx->text.source, ctx->text.insertPos,
01273 XawstWhiteSpace, XawsdLeft, 1, FALSE);
01274 r = SrcScan(ctx->text.source, l, XawstWhiteSpace, XawsdRight, 1, FALSE);
01275 _XawTextSetSelection(ctx, l, r, params, *num_params);
01276 EndAction(ctx);
01277 }
01278
01279 static void
01280 SelectAll(w, event, params, num_params)
01281 Widget w;
01282 XEvent* event;
01283 String* params;
01284 Cardinal* num_params;
01285 {
01286 TextWidget ctx = (TextWidget) w;
01287
01288 StartAction(ctx, event);
01289 _XawTextSetSelection(ctx,zeroPosition,ctx->text.lastPos,params,*num_params);
01290 EndAction(ctx);
01291 }
01292
01293 static void
01294 ModifySelection(ctx, event, mode, action, params, num_params)
01295 TextWidget ctx;
01296 XEvent* event;
01297 XawTextSelectionMode mode;
01298 XawTextSelectionAction action;
01299 String* params;
01300 Cardinal* num_params;
01301 {
01302 StartAction(ctx, event);
01303 NotePosition(ctx, event);
01304 _XawTextAlterSelection(ctx, mode, action, params, num_params);
01305 EndAction(ctx);
01306 }
01307
01308
01309 static void
01310 SelectStart(w, event, params, num_params)
01311 Widget w;
01312 XEvent* event;
01313 String* params;
01314 Cardinal* num_params;
01315 {
01316 ModifySelection((TextWidget) w, event,
01317 XawsmTextSelect, XawactionStart, params, num_params);
01318 }
01319
01320
01321 static void
01322 SelectAdjust(w, event, params, num_params)
01323 Widget w;
01324 XEvent* event;
01325 String* params;
01326 Cardinal* num_params;
01327 {
01328 ModifySelection((TextWidget) w, event,
01329 XawsmTextSelect, XawactionAdjust, params, num_params);
01330 }
01331
01332 static void
01333 SelectEnd(w, event, params, num_params)
01334 Widget w;
01335 XEvent* event;
01336 String* params;
01337 Cardinal* num_params;
01338 {
01339 ModifySelection((TextWidget) w, event,
01340 XawsmTextSelect, XawactionEnd, params, num_params);
01341 }
01342
01343
01344 static void
01345 ExtendStart(w, event, params, num_params)
01346 Widget w;
01347 XEvent* event;
01348 String* params;
01349 Cardinal* num_params;
01350 {
01351 ModifySelection((TextWidget) w, event,
01352 XawsmTextExtend, XawactionStart, params, num_params);
01353 }
01354
01355
01356 static void
01357 ExtendAdjust(w, event, params, num_params)
01358 Widget w;
01359 XEvent* event;
01360 String* params;
01361 Cardinal* num_params;
01362 {
01363 ModifySelection((TextWidget) w, event,
01364 XawsmTextExtend, XawactionAdjust, params, num_params);
01365 }
01366
01367 static void
01368 ExtendEnd(w, event, params, num_params)
01369 Widget w;
01370 XEvent* event;
01371 String* params;
01372 Cardinal* num_params;
01373 {
01374 ModifySelection((TextWidget) w, event,
01375 XawsmTextExtend, XawactionEnd, params, num_params);
01376 }
01377
01378 static void
01379 SelectSave(w, event, params, num_params)
01380 Widget w;
01381 XEvent* event;
01382 String* params;
01383 Cardinal* num_params;
01384 {
01385 int num_atoms;
01386 Atom* sel;
01387 Display* dpy = XtDisplay(w);
01388 Atom selections[256];
01389
01390 StartAction( (TextWidget) w, event );
01391 num_atoms = *num_params;
01392 if (num_atoms > 256)
01393 num_atoms = 256;
01394 for (sel=selections; --num_atoms >= 0; sel++, params++)
01395 *sel = XInternAtom(dpy, *params, False);
01396 num_atoms = *num_params;
01397 _XawTextSaltAwaySelection( (TextWidget) w, selections, num_atoms );
01398 EndAction( (TextWidget) w );
01399 }
01400
01401
01402
01403
01404
01405
01406
01407
01408 static void
01409 RedrawDisplay(w, event, p, n)
01410 Widget w;
01411 XEvent* event;
01412 String* p;
01413 Cardinal* n;
01414 {
01415 StartAction( (TextWidget) w, event);
01416 _XawTextClearAndCenterDisplay((TextWidget) w);
01417 EndAction( (TextWidget) w);
01418 }
01419
01420
01421 static void
01422 TextFocusIn (w, event, p, n)
01423 Widget w;
01424 XEvent* event;
01425 String* p;
01426 Cardinal* n;
01427 {
01428 TextWidget ctx = (TextWidget) w;
01429
01430
01431 _XawImSetFocusValues (w, NULL, 0);
01432 if ( event->xfocus.detail == NotifyPointer ) return;
01433
01434 ctx->text.hasfocus = TRUE;
01435 }
01436
01437
01438 static void
01439 TextFocusOut(w, event, p, n)
01440 Widget w;
01441 XEvent* event;
01442 String* p;
01443 Cardinal* n;
01444 {
01445 TextWidget ctx = (TextWidget) w;
01446
01447
01448 _XawImUnsetFocus(w);
01449 if ( event->xfocus.detail == NotifyPointer ) return;
01450 ctx->text.hasfocus = FALSE;
01451 }
01452
01453
01454 static void
01455 TextEnterWindow( w, event, params, num_params )
01456 Widget w;
01457 XEvent* event;
01458 String* params;
01459 Cardinal* num_params;
01460 {
01461 TextWidget ctx = (TextWidget) w;
01462
01463 if ((event->xcrossing.detail != NotifyInferior) && event->xcrossing.focus &&
01464 !ctx->text.hasfocus) {
01465 _XawImSetFocusValues(w, NULL, 0);
01466 }
01467 }
01468
01469
01470 static void
01471 TextLeaveWindow( w, event, params, num_params )
01472 Widget w;
01473 XEvent* event;
01474 String* params;
01475 Cardinal* num_params;
01476 {
01477 TextWidget ctx = (TextWidget) w;
01478
01479 if ((event->xcrossing.detail != NotifyInferior) && event->xcrossing.focus &&
01480 !ctx->text.hasfocus) {
01481 _XawImUnsetFocus(w);
01482 }
01483 }
01484
01485 static XComposeStatus compose_status = {NULL, 0};
01486
01487
01488
01489
01490
01491
01492
01493
01494 static void
01495 AutoFill(ctx)
01496 TextWidget ctx;
01497 {
01498 int width, height, x, line_num, max_width;
01499 XawTextPosition ret_pos;
01500 XawTextBlock text;
01501
01502 if ( !((ctx->text.auto_fill) && (ctx->text.mult == 1)) )
01503 return;
01504
01505 for ( line_num = 0; line_num < ctx->text.lt.lines ; line_num++)
01506 if ( ctx->text.lt.info[line_num].position >= ctx->text.insertPos )
01507 break;
01508 line_num--;
01509
01510 max_width = Max(0, (int)(ctx->core.width - HMargins(ctx)));
01511
01512 x = ctx->text.margin.left;
01513 XawTextSinkFindPosition( ctx->text.sink,ctx->text.lt.info[line_num].position,
01514 x, max_width, TRUE, &ret_pos, &width, &height);
01515
01516 if ( ret_pos >= ctx->text.insertPos )
01517 return;
01518
01519 text.format = XawFmt8Bit;
01520 if (_XawTextFormat(ctx) == XawFmtWide) {
01521 text.format = XawFmtWide;
01522 text.ptr = (char *)XtMalloc(sizeof(wchar_t) * 2);
01523 ((wchar_t*)text.ptr)[0] = _Xaw_atowc(XawLF);
01524 ((wchar_t*)text.ptr)[1] = 0;
01525 } else
01526 text.ptr = "\n";
01527 text.length = 1;
01528 text.firstPos = 0;
01529
01530 if (_XawTextReplace(ctx, ret_pos - 1, ret_pos, &text))
01531 XBell(XtDisplay((Widget) ctx), 0);
01532 }
01533
01534
01535 static void
01536 InsertChar(w, event, p, n)
01537 Widget w;
01538 XEvent* event;
01539 String* p;
01540 Cardinal* n;
01541 {
01542 TextWidget ctx = (TextWidget) w;
01543 char *ptr, strbuf[BUFSIZ];
01544 int count, error;
01545 KeySym keysym;
01546 XawTextBlock text;
01547
01548 if (XtIsSubclass (ctx->text.source, (WidgetClass) multiSrcObjectClass))
01549 text.length = _XawImWcLookupString (w, &event->xkey,
01550 (wchar_t*) strbuf, BUFSIZ, &keysym, (Status*) &compose_status);
01551 else
01552 text.length = XLookupString ((XKeyEvent*)event, strbuf, BUFSIZ, &keysym, &compose_status);
01553
01554 if (text.length == 0)
01555 return;
01556
01557 text.format = _XawTextFormat( ctx );
01558 if ( text.format == XawFmtWide ) {
01559 text.ptr = ptr = XtMalloc(sizeof(wchar_t) * text.length * ctx->text.mult );
01560 for (count = 0; count < ctx->text.mult; count++ ) {
01561 memcpy((char*) ptr, (char *)strbuf, sizeof(wchar_t) * text.length );
01562 ptr += sizeof(wchar_t) * text.length;
01563 }
01564
01565 } else {
01566 text.ptr = ptr = XtMalloc( sizeof(char) * text.length * ctx->text.mult );
01567 for ( count = 0; count < ctx->text.mult; count++ ) {
01568 strncpy( ptr, strbuf, text.length );
01569 ptr += text.length;
01570 }
01571 }
01572
01573 text.length = text.length * ctx->text.mult;
01574 text.firstPos = 0;
01575
01576 StartAction(ctx, event);
01577
01578 error = _XawTextReplace(ctx, ctx->text.insertPos,ctx->text.insertPos, &text);
01579
01580 if (error == XawEditDone) {
01581 ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.insertPos,
01582 XawstPositions, XawsdRight, text.length, TRUE);
01583 AutoFill(ctx);
01584 }
01585 else
01586 XBell(XtDisplay(ctx), 50);
01587
01588 XtFree(text.ptr);
01589 _XawTextSetScrollBars(ctx);
01590 EndAction(ctx);
01591 }
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612 static char*
01613 IfHexConvertHexElseReturnParam(param, len_return)
01614 char* param;
01615 int* len_return;
01616 {
01617 char *p;
01618 char c;
01619
01620 int ind;
01621 static char hexval[ XawTextActionMaxHexChars ];
01622 Boolean first_digit;
01623
01624
01625
01626 if ( ( param[0] != '0' ) || ( param[1] != 'x' ) || ( param[2] == '\0' ) ) {
01627 *len_return = strlen( param );
01628 return( param );
01629 }
01630
01631
01632
01633 first_digit = True;
01634 ind = 0;
01635 hexval[ ind ] = '\0';
01636
01637 for ( p = param+2; ( c = *p ); p++ ) {
01638 hexval[ ind ] *= 16;
01639 if (c >= '0' && c <= '9')
01640 hexval[ ind ] += c - '0';
01641 else if (c >= 'a' && c <= 'f')
01642 hexval[ ind ] += c - 'a' + 10;
01643 else if (c >= 'A' && c <= 'F')
01644 hexval[ ind ] += c - 'A' + 10;
01645 else break;
01646
01647
01648
01649 if ( first_digit )
01650 first_digit = False;
01651 else {
01652 first_digit = True;
01653 if ( ++ind < XawTextActionMaxHexChars )
01654 hexval[ ind ] = '\0';
01655 else {
01656 *len_return = strlen( param );
01657 return( param );
01658 }
01659 }
01660 }
01661
01662
01663
01664 if ( ( c == '\0' ) && first_digit ) {
01665 *len_return = strlen( hexval );
01666 return( hexval );
01667 }
01668
01669
01670
01671 *len_return = strlen( param );
01672 return( param );
01673 }
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688 static void
01689 InsertString(w, event, params, num_params)
01690 Widget w;
01691 XEvent* event;
01692 String* params;
01693 Cardinal* num_params;
01694 {
01695 TextWidget ctx = (TextWidget) w;
01696 XtAppContext app_con = XtWidgetToApplicationContext(w);
01697 XawTextBlock text;
01698 int i;
01699
01700 text.firstPos = 0;
01701 text.format = _XawTextFormat( ctx );
01702
01703 StartAction(ctx, event);
01704 for ( i = *num_params; i; i--, params++ ) {
01705
01706 text.ptr = IfHexConvertHexElseReturnParam( *params, &text.length );
01707
01708 if ( text.length == 0 ) continue;
01709
01710 if ( _XawTextFormat( ctx ) == XawFmtWide ) {
01711
01712 int temp_len;
01713 text.ptr = (char*) _XawTextMBToWC( XtDisplay(w), text.ptr,
01714 &text.length );
01715
01716 if ( text.ptr == NULL ) {
01717 XtAppWarningMsg( app_con,
01718 "insertString", "textAction", "XawError",
01719 "insert-string()'s parameter contents not legal in this locale.",
01720 NULL, NULL );
01721 ParameterError( w, *params );
01722 continue;
01723 }
01724
01725
01726
01727 temp_len = text.length;
01728 if ( _XawTextWCToMB( XtDisplay(w), (wchar_t*)text.ptr, &temp_len ) == NULL ) {
01729 XtAppWarningMsg( app_con,
01730 "insertString", "textAction", "XawError",
01731 "insert-string()'s parameter contents not legal in this locale.",
01732 NULL, NULL );
01733 ParameterError( w, *params );
01734 continue;
01735 }
01736 }
01737
01738 if ( _XawTextReplace( ctx, ctx->text.insertPos,
01739 ctx->text.insertPos, &text ) ) {
01740 XBell( XtDisplay( ctx ), 50 );
01741 EndAction( ctx );
01742 return;
01743 }
01744
01745
01746 ctx->text.insertPos = SrcScan( ctx->text.source, ctx->text.insertPos,
01747 XawstPositions, XawsdRight, text.length, TRUE );
01748
01749 }
01750
01751 EndAction( ctx );
01752 }
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764 static void
01765 DisplayCaret(w, event, params, num_params)
01766 Widget w;
01767 XEvent* event;
01768 String* params;
01769 Cardinal* num_params;
01770 {
01771 TextWidget ctx = (TextWidget)w;
01772 Boolean display_caret = True;
01773
01774 if ( ( event->type == EnterNotify || event->type == LeaveNotify ) &&
01775 ( ( *num_params >= 2 ) && ( strcmp( params[1], "always" ) == 0 ) ) &&
01776 ( !event->xcrossing.focus ) )
01777 return;
01778
01779 if (*num_params > 0) {
01780 XrmValue from, to;
01781 from.size = strlen(from.addr = params[0]);
01782 XtConvert( w, XtRString, &from, XtRBoolean, &to );
01783
01784 if ( to.addr != NULL )
01785 display_caret = *(Boolean*)to.addr;
01786 if ( ctx->text.display_caret == display_caret )
01787 return;
01788 }
01789 StartAction(ctx, event);
01790 ctx->text.display_caret = display_caret;
01791 EndAction(ctx);
01792 }
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806 static void
01807 Multiply(w, event, params, num_params)
01808 Widget w;
01809 XEvent* event;
01810 String* params;
01811 Cardinal* num_params;
01812 {
01813 TextWidget ctx = (TextWidget) w;
01814 int mult;
01815
01816 if (*num_params != 1) {
01817 XtAppError( XtWidgetToApplicationContext( w ),
01818 "Xaw Text Widget: multiply() takes exactly one argument.");
01819 XBell( XtDisplay( w ), 0 );
01820 return;
01821 }
01822
01823 if ( ( params[0][0] == 'r' ) || ( params[0][0] == 'R' ) ) {
01824 XBell( XtDisplay( w ), 0 );
01825 ctx->text.mult = 1;
01826 return;
01827 }
01828
01829 if ( ( mult = atoi( params[0] ) ) == 0 ) {
01830 char buf[ BUFSIZ ];
01831 sprintf(buf, "%s %s", "Xaw Text Widget: multiply() argument",
01832 "must be a number greater than zero, or 'Reset'." );
01833 XtAppError( XtWidgetToApplicationContext( w ), buf );
01834 XBell( XtDisplay( w ), 50 );
01835 return;
01836 }
01837
01838 ctx->text.mult *= mult;
01839 }
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849 static XawTextPosition
01850 StripOutOldCRs(ctx, from, to)
01851 TextWidget ctx;
01852 XawTextPosition from, to;
01853 {
01854 XawTextPosition startPos, endPos, eop_begin, eop_end, temp;
01855 Widget src = ctx->text.source;
01856 XawTextBlock text;
01857 char *buf;
01858 static wchar_t wc_two_spaces[ 3 ];
01859
01860
01861
01862 text.firstPos = 0;
01863 text.format = _XawTextFormat(ctx);
01864 if ( text.format == XawFmt8Bit )
01865 text.ptr= " ";
01866 else {
01867 wc_two_spaces[0] = _Xaw_atowc(XawSP);
01868 wc_two_spaces[1] = _Xaw_atowc(XawSP);
01869 wc_two_spaces[2] = 0;
01870 text.ptr = (char*) wc_two_spaces;
01871 }
01872
01873
01874
01875 eop_begin = eop_end = startPos = endPos = from;
01876
01877 while (TRUE) {
01878 endPos=SrcScan(src, startPos, XawstEOL, XawsdRight, 1, FALSE);
01879
01880 temp = SrcScan(src, endPos, XawstWhiteSpace, XawsdLeft, 1, FALSE);
01881 temp = SrcScan(src, temp, XawstWhiteSpace, XawsdRight,1, FALSE);
01882
01883 if (temp > startPos)
01884 endPos = temp;
01885
01886 if (endPos >= to)
01887 break;
01888
01889 if (endPos >= eop_begin) {
01890 startPos = eop_end;
01891 eop_begin=SrcScan(src, startPos, XawstParagraph, XawsdRight, 1,FALSE);
01892 eop_end = SrcScan(src, startPos, XawstParagraph, XawsdRight, 1, TRUE);
01893 }
01894 else {
01895 XawTextPosition periodPos, next_word;
01896 int i, len;
01897
01898 periodPos= SrcScan(src, endPos, XawstPositions, XawsdLeft, 1, TRUE);
01899 next_word = SrcScan(src, endPos, XawstWhiteSpace, XawsdRight, 1, FALSE);
01900
01901 len = next_word - periodPos;
01902
01903 text.length = 1;
01904 buf = _XawTextGetText(ctx, periodPos, next_word);
01905 if (text.format == XawFmtWide) {
01906 if ( (periodPos < endPos) && (((wchar_t*)buf)[0] == _Xaw_atowc('.')))
01907 text.length++;
01908 } else
01909 if ( (periodPos < endPos) && (buf[0] == '.') )
01910 text.length++;
01911
01912
01913
01914
01915
01916 for (i = 1 ; i < len; i++)
01917 if (text.format == XawFmtWide) {
01918 if ( !iswspace(((wchar_t*)buf)[i]) || ((periodPos + i) >= to) ) {
01919 break;
01920 }
01921 } else
01922 if ( !isspace(buf[i]) || ((periodPos + i) >= to) ) {
01923 break;
01924 }
01925
01926 XtFree(buf);
01927
01928 to -= (i - text.length - 1);
01929 startPos = SrcScan(src, periodPos, XawstPositions, XawsdRight, i, TRUE);
01930 if (_XawTextReplace(ctx, endPos, startPos, &text) != XawEditDone)
01931 return XawReplaceError;
01932 startPos -= i - text.length;
01933 }
01934 }
01935 return(to);
01936 }
01937
01938
01939
01940
01941
01942
01943 static void
01944 InsertNewCRs(ctx, from, to)
01945 TextWidget ctx;
01946 XawTextPosition from, to;
01947 {
01948 XawTextPosition startPos, endPos, space, eol;
01949 XawTextBlock text;
01950 int i, width, height, len;
01951 char * buf;
01952 static wchar_t wide_CR[ 2 ];
01953
01954 text.firstPos = 0;
01955 text.length = 1;
01956 text.format = _XawTextFormat( ctx );
01957
01958 if ( text.format == XawFmt8Bit )
01959 text.ptr = "\n";
01960 else {
01961 wide_CR[0] = _Xaw_atowc(XawLF);
01962 wide_CR[1] = 0;
01963 text.ptr = (char*) wide_CR;
01964 }
01965
01966 startPos = from;
01967
01968 while (TRUE) {
01969 XawTextSinkFindPosition( ctx->text.sink, startPos,
01970 (int) ctx->text.margin.left,
01971 (int) (ctx->core.width - HMargins(ctx)),
01972 TRUE, &eol, &width, &height);
01973 if (eol >= to)
01974 break;
01975
01976 eol = SrcScan(ctx->text.source, eol, XawstPositions, XawsdLeft, 1, TRUE);
01977 space= SrcScan(ctx->text.source, eol, XawstWhiteSpace,XawsdRight,1, TRUE);
01978
01979 startPos = endPos = eol;
01980 if (eol == space)
01981 return;
01982
01983 len = (int) (space - eol);
01984 buf = _XawTextGetText(ctx, eol, space);
01985 for ( i = 0 ; i < len ; i++)
01986 if (text.format == XawFmtWide) {
01987 if (!iswspace(((wchar_t*)buf)[i]))
01988 break;
01989 } else
01990 if (!isspace(buf[i]))
01991 break;
01992
01993 to -= (i - 1);
01994 endPos = SrcScan(ctx->text.source, endPos,
01995 XawstPositions, XawsdRight, i, TRUE);
01996 XtFree(buf);
01997
01998 if (_XawTextReplace(ctx, startPos, endPos, &text))
01999 return;
02000
02001 startPos = SrcScan(ctx->text.source, startPos,
02002 XawstPositions, XawsdRight, 1, TRUE);
02003 }
02004 }
02005
02006
02007
02008
02009
02010
02011
02012
02013 static int
02014 FormRegion(ctx, from, to)
02015 TextWidget ctx;
02016 XawTextPosition from, to;
02017 {
02018 if ( from >= to ) return XawEditDone;
02019
02020 if ( ( to = StripOutOldCRs( ctx, from, to ) ) == XawReplaceError )
02021 return XawReplaceError;
02022
02023
02024 if ( ctx->text.insertPos > SrcScan( ctx->text.source, 0,
02025 XawstAll, XawsdRight, 1, TRUE ) )
02026 ctx->text.insertPos = to;
02027
02028 InsertNewCRs(ctx, from, to);
02029 _XawTextBuildLineTable(ctx, ctx->text.lt.top, TRUE);
02030 return XawEditDone;
02031 }
02032
02033
02034
02035
02036
02037
02038
02039 static void
02040 FormParagraph(w, event, params, num_params)
02041 Widget w;
02042 XEvent* event;
02043 String* params;
02044 Cardinal* num_params;
02045 {
02046 TextWidget ctx = (TextWidget) w;
02047 XawTextPosition from, to;
02048
02049 StartAction(ctx, event);
02050
02051 from = SrcScan( ctx->text.source, ctx->text.insertPos,
02052 XawstParagraph, XawsdLeft, 1, FALSE );
02053 to = SrcScan( ctx->text.source, from,
02054 XawstParagraph, XawsdRight, 1, FALSE );
02055
02056 if ( FormRegion( ctx, from, to ) == XawReplaceError )
02057 XBell( XtDisplay( w ), 0 );
02058 _XawTextSetScrollBars( ctx );
02059 EndAction( ctx );
02060 }
02061
02062
02063
02064
02065
02066
02067
02068
02069 static void
02070 TransposeCharacters(w, event, params, num_params)
02071 Widget w;
02072 XEvent* event;
02073 String* params;
02074 Cardinal* num_params;
02075 {
02076 TextWidget ctx = (TextWidget) w;
02077 XawTextPosition start, end;
02078 XawTextBlock text;
02079 char* buf;
02080 int i;
02081
02082 StartAction(ctx, event);
02083
02084
02085
02086 start = SrcScan( ctx->text.source, ctx->text.insertPos, XawstPositions,
02087 XawsdLeft, 1, TRUE );
02088 end = SrcScan( ctx->text.source, ctx->text.insertPos, XawstPositions,
02089 XawsdRight, ctx->text.mult, TRUE );
02090
02091
02092
02093 if ( ( start == ctx->text.insertPos ) || ( end == ctx->text.insertPos ) ) {
02094 XBell( XtDisplay( w ), 0 );
02095 EndAction( ctx );
02096 return;
02097 }
02098
02099 ctx->text.insertPos = end;
02100
02101 text.firstPos = 0;
02102 text.format = _XawTextFormat(ctx);
02103
02104
02105
02106 if ( text.format == XawFmtWide) {
02107 wchar_t wc;
02108 wchar_t* wbuf;
02109
02110 wbuf = (wchar_t*) _XawTextGetText(ctx, start, end);
02111 text.length = wcslen( wbuf );
02112 wc = wbuf[ 0 ];
02113 for ( i = 1; i < text.length; i++ )
02114 wbuf[ i-1 ] = wbuf[ i ];
02115 wbuf[ i-1 ] = wc;
02116 buf = (char*) wbuf;
02117
02118 } else {
02119 char c;
02120 buf = _XawTextGetText( ctx, start, end );
02121 text.length = strlen( buf );
02122 c = buf[ 0 ];
02123 for ( i = 1; i < text.length; i++ )
02124 buf[ i-1 ] = buf[ i ];
02125 buf[ i-1 ] = c;
02126 }
02127
02128 text.ptr = buf;
02129
02130
02131
02132 if (_XawTextReplace (ctx, start, end, &text))
02133 XBell(XtDisplay(w), 0);
02134 XtFree((char *) buf);
02135 EndAction(ctx);
02136 }
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148 static void
02149 NoOp(w, event, params, num_params)
02150 Widget w;
02151 XEvent* event;
02152 String* params;
02153 Cardinal* num_params;
02154 {
02155 if (*num_params != 1)
02156 return;
02157
02158 switch(params[0][0]) {
02159 case 'R':
02160 case 'r':
02161 XBell(XtDisplay(w), 0);
02162 default:
02163 break;
02164 }
02165 }
02166
02167
02168
02169
02170
02171
02172
02173
02174 static void
02175 Reconnect( w, event, params, num_params )
02176 Widget w;
02177 XEvent* event;
02178 String* params;
02179 Cardinal* num_params;
02180 {
02181 _XawImReconnect( w );
02182 }
02183
02184
02185 XtActionsRec _XawTextActionsTable[] = {
02186
02187
02188
02189 {"forward-character", MoveForwardChar},
02190 {"backward-character", MoveBackwardChar},
02191 {"forward-word", MoveForwardWord},
02192 {"backward-word", MoveBackwardWord},
02193 {"forward-paragraph", MoveForwardParagraph},
02194 {"backward-paragraph", MoveBackwardParagraph},
02195 {"beginning-of-line", MoveToLineStart},
02196 {"end-of-line", MoveToLineEnd},
02197 {"next-line", MoveNextLine},
02198 {"previous-line", MovePreviousLine},
02199 {"next-page", MoveNextPage},
02200 {"previous-page", MovePreviousPage},
02201 {"beginning-of-file", MoveBeginningOfFile},
02202 {"end-of-file", MoveEndOfFile},
02203 {"scroll-one-line-up", ScrollOneLineUp},
02204 {"scroll-one-line-down", ScrollOneLineDown},
02205
02206
02207
02208 {"delete-next-character", DeleteForwardChar},
02209 {"delete-previous-character", DeleteBackwardChar},
02210 {"delete-next-word", DeleteForwardWord},
02211 {"delete-previous-word", DeleteBackwardWord},
02212 {"delete-selection", DeleteCurrentSelection},
02213
02214
02215
02216 {"kill-word", KillForwardWord},
02217 {"backward-kill-word", KillBackwardWord},
02218 {"kill-selection", KillCurrentSelection},
02219 {"kill-to-end-of-line", KillToEndOfLine},
02220 {"kill-to-end-of-paragraph", KillToEndOfParagraph},
02221
02222
02223
02224 {"newline-and-indent", InsertNewLineAndIndent},
02225 {"newline-and-backup", InsertNewLineAndBackup},
02226 {"newline", InsertNewLine},
02227
02228
02229
02230 {"select-word", SelectWord},
02231 {"select-all", SelectAll},
02232 {"select-start", SelectStart},
02233 {"select-adjust", SelectAdjust},
02234 {"select-end", SelectEnd},
02235 {"select-save", SelectSave},
02236 {"extend-start", ExtendStart},
02237 {"extend-adjust", ExtendAdjust},
02238 {"extend-end", ExtendEnd},
02239 {"insert-selection", InsertSelection},
02240
02241
02242
02243 {"redraw-display", RedrawDisplay},
02244 {"insert-file", _XawTextInsertFile},
02245 {"search", _XawTextSearch},
02246 {"insert-char", InsertChar},
02247 {"insert-string", InsertString},
02248 {"focus-in", TextFocusIn},
02249 {"focus-out", TextFocusOut},
02250 {"enter-window", TextEnterWindow},
02251 {"leave-window", TextLeaveWindow},
02252 {"display-caret", DisplayCaret},
02253 {"multiply", Multiply},
02254 {"form-paragraph", FormParagraph},
02255 {"transpose-characters", TransposeCharacters},
02256 {"no-op", NoOp},
02257
02258
02259
02260 {"InsertFileAction", _XawTextInsertFileAction},
02261 {"DoSearchAction", _XawTextDoSearchAction},
02262 {"DoReplaceAction", _XawTextDoReplaceAction},
02263 {"SetField", _XawTextSetField},
02264 {"PopdownSearchAction", _XawTextPopdownSearchAction},
02265
02266
02267 {"reconnect-im", Reconnect}
02268 };
02269
02270 Cardinal _XawTextActionsTableCount = XtNumber(_XawTextActionsTable);