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
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #include <X11/IntrinsicP.h>
00052 #include <X11/StringDefs.h>
00053 #include <X11/Shell.h>
00054 #include <X11/Xatom.h>
00055 #include <X11/Xutil.h>
00056 #include "XawI18n.h"
00057 #include <stdio.h>
00058
00059 #include <X11/Xmu/Atoms.h>
00060 #include <X11/Xmu/CharSet.h>
00061 #include <X11/Xmu/Converters.h>
00062 #include <X11/Xmu/StdSel.h>
00063 #include <X11/Xmu/Misc.h>
00064
00065 #include <X11/Xaw3d/XawInit.h>
00066 #include <X11/Xaw3d/Cardinals.h>
00067 #include <X11/Xaw3d/Scrollbar.h>
00068 #include <X11/Xaw3d/TextP.h>
00069 #include <X11/Xaw3d/MultiSinkP.h>
00070 #include <X11/Xaw3d/XawImP.h>
00071
00072 #include <X11/Xfuncs.h>
00073 #include <ctype.h>
00074
00075 #ifndef MAX_LEN_CT
00076 #define MAX_LEN_CT 6
00077 #endif
00078
00079 unsigned long FMT8BIT = 0L;
00080 unsigned long XawFmt8Bit = 0L;
00081 unsigned long XawFmtWide = 0L;
00082
00083 #define SinkClearToBG XawTextSinkClearToBackground
00084
00085 #define SrcScan XawTextSourceScan
00086 #define SrcRead XawTextSourceRead
00087 #define SrcReplace XawTextSourceReplace
00088 #define SrcSearch XawTextSourceSearch
00089 #define SrcCvtSel XawTextSourceConvertSelection
00090 #define SrcSetSelection XawTextSourceSetSelection
00091
00092 #define BIGNUM ((Dimension)32023)
00093 #define MULTI_CLICK_TIME 500L
00094
00095
00096
00097
00098
00099
00100 #define MAX_CUT_LEN(dpy) (XMaxRequestSize(dpy) - 64)
00101
00102 #define IsValidLine(ctx, num) ( ((num) == 0) || \
00103 ((ctx)->text.lt.info[(num)].position != 0) )
00104
00105
00106
00107
00108 static void UnrealizeScrollbars();
00109 static void VScroll(), VJump(), HScroll(), HJump(), ClearWindow();
00110 static void DisplayTextWindow(), ModifySelection(), PushCopyQueue();
00111 static void UpdateTextInLine(), UpdateTextInRectangle(), PopCopyQueue();
00112 static void FlushUpdate();
00113 static Boolean LineAndXYForPosition(), TranslateExposeRegion();
00114 static XawTextPosition FindGoodPosition(), _BuildLineTable();
00115
00116 void _XawTextAlterSelection(), _XawTextExecuteUpdate();
00117 void _XawTextSetScrollBars(), _XawTextPrepareToUpdate();
00118
00119
00120
00121
00122
00123
00124
00125 static XawTextSelectType defaultSelectTypes[] = {
00126 XawselectPosition, XawselectWord, XawselectLine, XawselectParagraph,
00127 XawselectAll, XawselectNull,
00128 };
00129
00130 static XPointer defaultSelectTypesPtr = (XPointer)defaultSelectTypes;
00131 extern char *_XawDefaultTextTranslations1, *_XawDefaultTextTranslations2,
00132 *_XawDefaultTextTranslations3, *_XawDefaultTextTranslations4;
00133 static Dimension defWidth = 100;
00134 static Dimension defHeight = DEFAULT_TEXT_HEIGHT;
00135
00136 #define offset(field) XtOffsetOf(TextRec, field)
00137 static XtResource resources[] = {
00138 {XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension),
00139 offset(core.width), XtRDimension, (XtPointer)&defWidth},
00140 {XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor),
00141 offset(simple.cursor), XtRString, "xterm"},
00142 {XtNheight, XtCHeight, XtRDimension, sizeof(Dimension),
00143 offset(core.height), XtRDimension, (XtPointer)&defHeight},
00144 {XtNdisplayPosition, XtCTextPosition, XtRInt, sizeof(XawTextPosition),
00145 offset(text.lt.top), XtRImmediate, (XtPointer)0},
00146 {XtNinsertPosition, XtCTextPosition, XtRInt, sizeof(XawTextPosition),
00147 offset(text.insertPos), XtRImmediate,(XtPointer)0},
00148 {XtNleftMargin, XtCMargin, XtRPosition, sizeof (Position),
00149 offset(text.r_margin.left), XtRImmediate, (XtPointer)2},
00150 {XtNrightMargin, XtCMargin, XtRPosition, sizeof (Position),
00151 offset(text.r_margin.right), XtRImmediate, (XtPointer)4},
00152 {XtNtopMargin, XtCMargin, XtRPosition, sizeof (Position),
00153 offset(text.r_margin.top), XtRImmediate, (XtPointer)2},
00154 {XtNbottomMargin, XtCMargin, XtRPosition, sizeof (Position),
00155 offset(text.r_margin.bottom), XtRImmediate, (XtPointer)2},
00156 {XtNselectTypes, XtCSelectTypes, XtRPointer,
00157 sizeof(XawTextSelectType*), offset(text.sarray),
00158 XtRPointer, (XtPointer)&defaultSelectTypesPtr},
00159 {XtNtextSource, XtCTextSource, XtRWidget, sizeof (Widget),
00160 offset(text.source), XtRImmediate, NULL},
00161 {XtNtextSink, XtCTextSink, XtRWidget, sizeof (Widget),
00162 offset(text.sink), XtRImmediate, NULL},
00163 {XtNdisplayCaret, XtCOutput, XtRBoolean, sizeof(Boolean),
00164 offset(text.display_caret), XtRImmediate, (XtPointer)True},
00165 {XtNscrollVertical, XtCScroll, XtRScrollMode, sizeof(XawTextScrollMode),
00166 offset(text.scroll_vert), XtRImmediate, (XtPointer) XawtextScrollNever},
00167 {XtNscrollHorizontal, XtCScroll, XtRScrollMode, sizeof(XawTextScrollMode),
00168 offset(text.scroll_horiz), XtRImmediate, (XtPointer) XawtextScrollNever},
00169 {XtNwrap, XtCWrap, XtRWrapMode, sizeof(XawTextWrapMode),
00170 offset(text.wrap), XtRImmediate, (XtPointer) XawtextWrapNever},
00171 {XtNresize, XtCResize, XtRResizeMode, sizeof(XawTextResizeMode),
00172 offset(text.resize), XtRImmediate, (XtPointer) XawtextResizeNever},
00173 {XtNautoFill, XtCAutoFill, XtRBoolean, sizeof(Boolean),
00174 offset(text.auto_fill), XtRImmediate, (XtPointer) FALSE},
00175 {XtNunrealizeCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
00176 offset(text.unrealize_callbacks), XtRCallback, (XtPointer) NULL}
00177 };
00178 #undef offset
00179
00180
00181 static void
00182 CvtStringToScrollMode(args, num_args, fromVal, toVal)
00183 XrmValuePtr args;
00184 Cardinal *num_args;
00185 XrmValuePtr fromVal;
00186 XrmValuePtr toVal;
00187 {
00188 static XawTextScrollMode scrollMode;
00189 static XrmQuark QScrollNever, QScrollAlways, QScrollWhenNeeded;
00190 XrmQuark q;
00191 char lowerName[40];
00192 static Boolean inited = FALSE;
00193
00194 if ( !inited ) {
00195 QScrollNever = XrmPermStringToQuark(XtEtextScrollNever);
00196 QScrollWhenNeeded = XrmPermStringToQuark(XtEtextScrollWhenNeeded);
00197 QScrollAlways = XrmPermStringToQuark(XtEtextScrollAlways);
00198 inited = TRUE;
00199 }
00200
00201 if (strlen ((char*) fromVal->addr) < sizeof lowerName) {
00202 XmuCopyISOLatin1Lowered (lowerName, (char *)fromVal->addr);
00203 q = XrmStringToQuark(lowerName);
00204
00205 if (q == QScrollNever) scrollMode = XawtextScrollNever;
00206 else if (q == QScrollWhenNeeded) scrollMode = XawtextScrollWhenNeeded;
00207 else if (q == QScrollAlways) scrollMode = XawtextScrollAlways;
00208 else {
00209 toVal->size = 0;
00210 toVal->addr = NULL;
00211 return;
00212 }
00213 toVal->size = sizeof scrollMode;
00214 toVal->addr = (XPointer) &scrollMode;
00215 return;
00216 }
00217 toVal->size = 0;
00218 toVal->addr = NULL;
00219 }
00220
00221
00222 static void
00223 CvtStringToWrapMode(args, num_args, fromVal, toVal)
00224 XrmValuePtr args;
00225 Cardinal *num_args;
00226 XrmValuePtr fromVal;
00227 XrmValuePtr toVal;
00228 {
00229 static XawTextWrapMode wrapMode;
00230 static XrmQuark QWrapNever, QWrapLine, QWrapWord;
00231 XrmQuark q;
00232 char lowerName[BUFSIZ];
00233 static Boolean inited = FALSE;
00234
00235 if ( !inited ) {
00236 QWrapNever = XrmPermStringToQuark(XtEtextWrapNever);
00237 QWrapLine = XrmPermStringToQuark(XtEtextWrapLine);
00238 QWrapWord = XrmPermStringToQuark(XtEtextWrapWord);
00239 inited = TRUE;
00240 }
00241
00242 if (strlen ((char*) fromVal->addr) < sizeof lowerName) {
00243 XmuCopyISOLatin1Lowered (lowerName, (char *)fromVal->addr);
00244 q = XrmStringToQuark(lowerName);
00245
00246 if (q == QWrapNever) wrapMode = XawtextWrapNever;
00247 else if (q == QWrapLine) wrapMode = XawtextWrapLine;
00248 else if (q == QWrapWord) wrapMode = XawtextWrapWord;
00249 else {
00250 toVal->size = 0;
00251 toVal->addr = NULL;
00252 return;
00253 }
00254 toVal->size = sizeof wrapMode;
00255 toVal->addr = (XPointer) &wrapMode;
00256 return;
00257 }
00258 toVal->size = 0;
00259 toVal->addr = NULL;
00260 }
00261
00262
00263 static void
00264 CvtStringToResizeMode(args, num_args, fromVal, toVal)
00265 XrmValuePtr args;
00266 Cardinal *num_args;
00267 XrmValuePtr fromVal;
00268 XrmValuePtr toVal;
00269 {
00270 static XawTextResizeMode resizeMode;
00271 static XrmQuark QResizeNever, QResizeWidth, QResizeHeight, QResizeBoth;
00272 XrmQuark q;
00273 char lowerName[40];
00274 static Boolean inited = FALSE;
00275
00276 if ( !inited ) {
00277 QResizeNever = XrmPermStringToQuark(XtEtextResizeNever);
00278 QResizeWidth = XrmPermStringToQuark(XtEtextResizeWidth);
00279 QResizeHeight = XrmPermStringToQuark(XtEtextResizeHeight);
00280 QResizeBoth = XrmPermStringToQuark(XtEtextResizeBoth);
00281 inited = TRUE;
00282 }
00283
00284 if (strlen ((char*) fromVal->addr) < sizeof lowerName) {
00285 XmuCopyISOLatin1Lowered (lowerName, (char *)fromVal->addr);
00286 q = XrmStringToQuark(lowerName);
00287
00288 if (q == QResizeNever) resizeMode = XawtextResizeNever;
00289 else if (q == QResizeWidth) resizeMode = XawtextResizeWidth;
00290 else if (q == QResizeHeight) resizeMode = XawtextResizeHeight;
00291 else if (q == QResizeBoth) resizeMode = XawtextResizeBoth;
00292 else {
00293 toVal->size = 0;
00294 toVal->addr = NULL;
00295 return;
00296 }
00297 toVal->size = sizeof resizeMode;
00298 toVal->addr = (XPointer) &resizeMode;
00299 return;
00300 }
00301 toVal->size = 0;
00302 toVal->addr = NULL;
00303 }
00304
00305 static void
00306 ClassInitialize()
00307 {
00308 int len1 = strlen (_XawDefaultTextTranslations1);
00309 int len2 = strlen (_XawDefaultTextTranslations2);
00310 int len3 = strlen (_XawDefaultTextTranslations3);
00311 int len4 = strlen (_XawDefaultTextTranslations4);
00312 char *buf = XtMalloc ((unsigned)(len1 + len2 + len3 + len4 + 1));
00313 char *cp = buf;
00314
00315 if (!XawFmt8Bit)
00316 FMT8BIT = XawFmt8Bit = XrmPermStringToQuark("FMT8BIT");
00317 if (!XawFmtWide)
00318 XawFmtWide = XrmPermStringToQuark("FMTWIDE");
00319
00320 XawInitializeWidgetSet();
00321
00322
00323
00324
00325
00326 textClassRec.core_class.num_actions = _XawTextActionsTableCount;
00327
00328 (void) strcpy( cp, _XawDefaultTextTranslations1); cp += len1;
00329 (void) strcpy( cp, _XawDefaultTextTranslations2); cp += len2;
00330 (void) strcpy( cp, _XawDefaultTextTranslations3); cp += len3;
00331 (void) strcpy( cp, _XawDefaultTextTranslations4);
00332 textWidgetClass->core_class.tm_table = buf;
00333
00334 XtAddConverter(XtRString, XtRScrollMode, CvtStringToScrollMode,
00335 (XtConvertArgList)NULL, (Cardinal)0 );
00336 XtAddConverter(XtRString, XtRWrapMode, CvtStringToWrapMode,
00337 (XtConvertArgList)NULL, (Cardinal)0 );
00338 XtAddConverter(XtRString, XtRResizeMode, CvtStringToResizeMode,
00339 (XtConvertArgList)NULL, (Cardinal)0 );
00340 }
00341
00342
00343
00344
00345
00346
00347
00348 static void
00349 PositionHScrollBar(ctx)
00350 TextWidget ctx;
00351 {
00352 Widget vbar = ctx->text.vbar, hbar = ctx->text.hbar;
00353 Position top, left = 0;
00354
00355 if (ctx->text.hbar == NULL) return;
00356
00357 if (vbar != NULL)
00358 left += (Position) (vbar->core.width + vbar->core.border_width);
00359
00360 XtResizeWidget( hbar, ctx->core.width - left, hbar->core.height,
00361 hbar->core.border_width );
00362
00363 left -= (Position) hbar->core.border_width;
00364
00365 top = ctx->core.height - ( hbar->core.height + hbar->core.border_width);
00366 XtMoveWidget( hbar, left, top);
00367 }
00368
00369
00370
00371
00372
00373
00374
00375 static void
00376 PositionVScrollBar(ctx)
00377 TextWidget ctx;
00378 {
00379 Widget vbar = ctx->text.vbar;
00380 Dimension bw;
00381
00382 if (vbar == NULL) return;
00383 bw = vbar->core.border_width;
00384
00385 XtResizeWidget( vbar, vbar->core.width, ctx->core.height, bw);
00386 XtMoveWidget( vbar, -(Position)bw, -(Position)bw );
00387 }
00388
00389 static void
00390 CreateVScrollBar(ctx)
00391 TextWidget ctx;
00392 {
00393 Widget vbar;
00394
00395 if (ctx->text.vbar != NULL) return;
00396
00397 ctx->text.vbar = vbar =
00398 XtCreateWidget("vScrollbar", scrollbarWidgetClass, (Widget)ctx,
00399 (ArgList) NULL, ZERO);
00400 XtAddCallback( vbar, XtNscrollProc, VScroll, (XtPointer)ctx );
00401 XtAddCallback( vbar, XtNjumpProc, VJump, (XtPointer)ctx );
00402 if (ctx->text.hbar == NULL)
00403 XtAddCallback((Widget) ctx, XtNunrealizeCallback, UnrealizeScrollbars,
00404 (XtPointer) NULL);
00405
00406 ctx->text.r_margin.left += vbar->core.width + vbar->core.border_width;
00407 ctx->text.margin.left = ctx->text.r_margin.left;
00408
00409 PositionVScrollBar(ctx);
00410 PositionHScrollBar(ctx);
00411
00412 if (XtIsRealized((Widget)ctx)) {
00413 XtRealizeWidget(vbar);
00414 XtMapWidget(vbar);
00415 }
00416 }
00417
00418
00419
00420
00421
00422
00423
00424 static void
00425 DestroyVScrollBar(ctx)
00426 TextWidget ctx;
00427 {
00428 Widget vbar = ctx->text.vbar;
00429
00430 if (vbar == NULL) return;
00431
00432 ctx->text.r_margin.left -= vbar->core.width + vbar->core.border_width;
00433 ctx->text.margin.left = ctx->text.r_margin.left;
00434 if (ctx->text.hbar == NULL)
00435 XtRemoveCallback((Widget) ctx, XtNunrealizeCallback, UnrealizeScrollbars,
00436 (XtPointer) NULL);
00437 XtDestroyWidget(vbar);
00438 ctx->text.vbar = NULL;
00439 PositionHScrollBar(ctx);
00440 }
00441
00442 static void
00443 CreateHScrollBar(ctx)
00444 TextWidget ctx;
00445 {
00446 Arg args[1];
00447 Widget hbar;
00448
00449 if (ctx->text.hbar != NULL) return;
00450
00451 XtSetArg(args[0], XtNorientation, XtorientHorizontal);
00452 ctx->text.hbar = hbar =
00453 XtCreateWidget("hScrollbar", scrollbarWidgetClass, (Widget)ctx, args, ONE);
00454 XtAddCallback( hbar, XtNscrollProc, HScroll, (XtPointer)ctx );
00455 XtAddCallback( hbar, XtNjumpProc, HJump, (XtPointer)ctx );
00456 if (ctx->text.vbar == NULL)
00457 XtAddCallback((Widget) ctx, XtNunrealizeCallback, UnrealizeScrollbars,
00458 (XtPointer) NULL);
00459
00460 PositionHScrollBar(ctx);
00461 if (XtIsRealized((Widget)ctx)) {
00462 XtRealizeWidget(hbar);
00463 XtMapWidget(hbar);
00464 }
00465 }
00466
00467
00468
00469
00470
00471
00472
00473 static void
00474 DestroyHScrollBar(ctx)
00475 TextWidget ctx;
00476 {
00477 Widget hbar = ctx->text.hbar;
00478
00479 if (hbar == NULL) return;
00480
00481
00482
00483
00484
00485 if (ctx->text.vbar == NULL)
00486 XtRemoveCallback((Widget) ctx, XtNunrealizeCallback, UnrealizeScrollbars,
00487 (XtPointer) NULL);
00488 XtDestroyWidget(hbar);
00489 ctx->text.hbar = NULL;
00490 }
00491
00492
00493 static void
00494 Initialize(request, new, args, num_args)
00495 Widget request, new;
00496 ArgList args;
00497 Cardinal *num_args;
00498 {
00499 TextWidget ctx = (TextWidget) new;
00500 char error_buf[BUFSIZ];
00501
00502 ctx->text.lt.lines = 0;
00503 ctx->text.lt.info = NULL;
00504 (void) bzero((char *) &(ctx->text.origSel), sizeof(XawTextSelection));
00505 (void) bzero((char *) &(ctx->text.s), sizeof(XawTextSelection));
00506 ctx->text.s.type = XawselectPosition;
00507 ctx->text.salt = NULL;
00508 ctx->text.hbar = ctx->text.vbar = (Widget) NULL;
00509 ctx->text.lasttime = 0;
00510 ctx->text.time = 0;
00511 ctx->text.showposition = TRUE;
00512 ctx->text.lastPos = (ctx->text.source != NULL) ? GETLASTPOS : 0;
00513 ctx->text.file_insert = NULL;
00514 ctx->text.search = NULL;
00515 ctx->text.updateFrom = (XawTextPosition *) XtMalloc((unsigned) ONE);
00516 ctx->text.updateTo = (XawTextPosition *) XtMalloc((unsigned) ONE);
00517 ctx->text.numranges = ctx->text.maxranges = 0;
00518 ctx->text.gc = DefaultGCOfScreen(XtScreen(ctx));
00519 ctx->text.hasfocus = FALSE;
00520 ctx->text.margin = ctx->text.r_margin;
00521 ctx->text.update_disabled = FALSE;
00522 ctx->text.old_insert = -1;
00523 ctx->text.mult = 1;
00524 ctx->text.single_char = FALSE;
00525 ctx->text.copy_area_offsets = NULL;
00526 ctx->text.salt2 = NULL;
00527
00528 if (ctx->core.height == DEFAULT_TEXT_HEIGHT) {
00529 ctx->core.height = VMargins(ctx);
00530 if (ctx->text.sink != NULL)
00531 ctx->core.height += XawTextSinkMaxHeight(ctx->text.sink, 1);
00532 }
00533
00534 if (ctx->text.scroll_vert != XawtextScrollNever)
00535 if ( (ctx->text.resize == XawtextResizeHeight) ||
00536 (ctx->text.resize == XawtextResizeBoth) ) {
00537 (void) sprintf(error_buf, "Xaw Text Widget %s:\n %s %s.", ctx->core.name,
00538 "Vertical scrolling not allowed with height resize.\n",
00539 "Vertical scrolling has been DEACTIVATED.");
00540 XtAppWarning(XtWidgetToApplicationContext(new), error_buf);
00541 ctx->text.scroll_vert = XawtextScrollNever;
00542 }
00543 else if (ctx->text.scroll_vert == XawtextScrollAlways)
00544 CreateVScrollBar(ctx);
00545
00546 if (ctx->text.scroll_horiz != XawtextScrollNever)
00547 if (ctx->text.wrap != XawtextWrapNever) {
00548 (void) sprintf(error_buf, "Xaw Text Widget %s:\n %s %s.", ctx->core.name,
00549 "Horizontal scrolling not allowed with wrapping active.\n",
00550 "Horizontal scrolling has been DEACTIVATED.");
00551 XtAppWarning(XtWidgetToApplicationContext(new), error_buf);
00552 ctx->text.scroll_horiz = XawtextScrollNever;
00553 }
00554 else if ( (ctx->text.resize == XawtextResizeWidth) ||
00555 (ctx->text.resize == XawtextResizeBoth) ) {
00556 (void) sprintf(error_buf, "Xaw Text Widget %s:\n %s %s.", ctx->core.name,
00557 "Horizontal scrolling not allowed with width resize.\n",
00558 "Horizontal scrolling has been DEACTIVATED.");
00559 XtAppWarning(XtWidgetToApplicationContext(new), error_buf);
00560 ctx->text.scroll_horiz = XawtextScrollNever;
00561 }
00562 else if (ctx->text.scroll_horiz == XawtextScrollAlways)
00563 CreateHScrollBar(ctx);
00564 }
00565
00566 static void
00567 Realize( w, valueMask, attributes )
00568 Widget w;
00569 Mask *valueMask;
00570 XSetWindowAttributes *attributes;
00571 {
00572 TextWidget ctx = (TextWidget)w;
00573 void _XawTextCheckResize();
00574
00575 (*textClassRec.core_class.superclass->core_class.realize)
00576 (w, valueMask, attributes);
00577
00578 if (ctx->text.hbar != NULL) {
00579 XtRealizeWidget(ctx->text.hbar);
00580 XtMapWidget(ctx->text.hbar);
00581 }
00582
00583 if (ctx->text.vbar != NULL) {
00584 XtRealizeWidget(ctx->text.vbar);
00585 XtMapWidget(ctx->text.vbar);
00586 }
00587
00588 _XawTextBuildLineTable(ctx, ctx->text.lt.top, TRUE);
00589 _XawTextSetScrollBars(ctx);
00590 _XawTextCheckResize(ctx);
00591 }
00592
00593
00594 static void UnrealizeScrollbars(widget, client, call)
00595 Widget widget;
00596 XtPointer client;
00597 XtPointer call;
00598 {
00599 TextWidget ctx = (TextWidget) widget;
00600
00601 if (ctx->text.hbar)
00602 XtUnrealizeWidget(ctx->text.hbar);
00603 if (ctx->text.vbar)
00604 XtUnrealizeWidget(ctx->text.vbar);
00605 }
00606
00607
00608
00609 static void
00610 _CreateCutBuffers(d)
00611 Display *d;
00612 {
00613 static struct _DisplayRec {
00614 struct _DisplayRec *next;
00615 Display *dpy;
00616 } *dpy_list = NULL;
00617 struct _DisplayRec *dpy_ptr;
00618
00619 for (dpy_ptr = dpy_list; dpy_ptr != NULL; dpy_ptr = dpy_ptr->next)
00620 if (dpy_ptr->dpy == d) return;
00621
00622 dpy_ptr = XtNew(struct _DisplayRec);
00623 dpy_ptr->next = dpy_list;
00624 dpy_ptr->dpy = d;
00625 dpy_list = dpy_ptr;
00626
00627 #define Create(buffer) \
00628 XChangeProperty(d, RootWindow(d, 0), buffer, XA_STRING, 8, \
00629 PropModeAppend, NULL, 0 );
00630
00631 Create( XA_CUT_BUFFER0 );
00632 Create( XA_CUT_BUFFER1 );
00633 Create( XA_CUT_BUFFER2 );
00634 Create( XA_CUT_BUFFER3 );
00635 Create( XA_CUT_BUFFER4 );
00636 Create( XA_CUT_BUFFER5 );
00637 Create( XA_CUT_BUFFER6 );
00638 Create( XA_CUT_BUFFER7 );
00639
00640 #undef Create
00641 }
00642
00643
00644
00645
00646
00647
00648
00649 static void
00650 InsertCursor (w, state)
00651 Widget w;
00652 XawTextInsertState state;
00653 {
00654 TextWidget ctx = (TextWidget)w;
00655 Position x, y;
00656 int line;
00657
00658 if (ctx->text.lt.lines < 1) return;
00659
00660 if ( LineAndXYForPosition(ctx, ctx->text.insertPos, &line, &x, &y) ) {
00661 if (line < ctx->text.lt.lines)
00662 y += (ctx->text.lt.info[line + 1].y - ctx->text.lt.info[line].y) + 1;
00663 else
00664 y += (ctx->text.lt.info[line].y - ctx->text.lt.info[line - 1].y) + 1;
00665
00666 if (ctx->text.display_caret)
00667 XawTextSinkInsertCursor(ctx->text.sink, x, y, state);
00668 }
00669 ctx->text.ev_x = x;
00670 ctx->text.ev_y = y;
00671
00672
00673
00674 if ( ctx->simple.international ) {
00675 Arg list[1];
00676
00677 XtSetArg (list[0], XtNinsertPosition, ctx->text.insertPos);
00678 _XawImSetValues (w, list, 1);
00679 }
00680 }
00681
00682
00683
00684
00685
00686
00687
00688 void
00689 _XawTextNeedsUpdating(ctx, left, right)
00690 TextWidget ctx;
00691 XawTextPosition left, right;
00692 {
00693 int i;
00694 if (left < right) {
00695 for (i = 0; i < ctx->text.numranges; i++) {
00696 if (left <= ctx->text.updateTo[i] && right >= ctx->text.updateFrom[i]) {
00697 ctx->text.updateFrom[i] = Min(left, ctx->text.updateFrom[i]);
00698 ctx->text.updateTo[i] = Max(right, ctx->text.updateTo[i]);
00699 return;
00700 }
00701 }
00702 ctx->text.numranges++;
00703 if (ctx->text.numranges > ctx->text.maxranges) {
00704 ctx->text.maxranges = ctx->text.numranges;
00705 i = ctx->text.maxranges * sizeof(XawTextPosition);
00706 ctx->text.updateFrom = (XawTextPosition *)
00707 XtRealloc((char *)ctx->text.updateFrom, (unsigned) i);
00708 ctx->text.updateTo = (XawTextPosition *)
00709 XtRealloc((char *)ctx->text.updateTo, (unsigned) i);
00710 }
00711 ctx->text.updateFrom[ctx->text.numranges - 1] = left;
00712 ctx->text.updateTo[ctx->text.numranges - 1] = right;
00713 }
00714 }
00715
00716
00717
00718
00719
00720
00721
00722 char *
00723 _XawTextGetText(ctx, left, right)
00724 TextWidget ctx;
00725 XawTextPosition left, right;
00726 {
00727 char *result, *tempResult;
00728 XawTextBlock text;
00729 int bytes;
00730
00731 if (_XawTextFormat(ctx) == XawFmt8Bit)
00732 bytes = sizeof(unsigned char);
00733 else if (_XawTextFormat(ctx) == XawFmtWide)
00734 bytes = sizeof(wchar_t);
00735 else
00736 bytes = 1;
00737
00738
00739 tempResult=result=XtMalloc( (unsigned)(((Cardinal)(right-left))+ONE )* bytes);
00740 while (left < right) {
00741 left = SrcRead(ctx->text.source, left, &text, (int)(right - left));
00742 if (!text.length)
00743 break;
00744 memmove(tempResult, text.ptr, text.length * bytes);
00745 tempResult += text.length * bytes;
00746 }
00747
00748 if (bytes == sizeof(wchar_t))
00749 *((wchar_t*)tempResult) = (wchar_t)0;
00750 else
00751 *tempResult = '\0';
00752 return(result);
00753 }
00754
00755
00756
00757
00758
00759 char *
00760 _XawTextGetSTRING(ctx, left, right)
00761 TextWidget ctx;
00762 XawTextPosition left, right;
00763 {
00764 unsigned char *s;
00765 unsigned char c;
00766 long i, j, n;
00767 wchar_t *ws, wc;
00768
00769
00770 if (_XawTextFormat(ctx) == XawFmtWide) {
00771 MultiSinkObject sink = (MultiSinkObject) ctx->text.sink;
00772 ws = (wchar_t *)_XawTextGetText(ctx, left, right);
00773 n = wcslen(ws);
00774 for (j = 0, i = 0; j < n; j++) {
00775 wc = ws[j];
00776 if (XwcTextEscapement (sink->multi_sink.fontset, &wc, 1) ||
00777 (wc == _Xaw_atowc(XawTAB)) || (wc == _Xaw_atowc(XawLF)) || (wc == _Xaw_atowc(XawESC)))
00778 ws[i++] = wc;
00779 }
00780 ws[i] = (wchar_t)0;
00781 return (char *)ws;
00782 } else {
00783 s = (unsigned char *)_XawTextGetText(ctx, left, right);
00784
00785 n = strlen((char *)s);
00786 i = 0;
00787 for (j = 0; j < n; j++) {
00788 c = s[j];
00789 if (((c >= 0x20) && c <= 0x7f) ||
00790 (c >= 0xa0) || (c == XawTAB) || (c == XawLF) || (c == XawESC)) {
00791 s[i] = c;
00792 i++;
00793 }
00794 }
00795 s[i] = 0;
00796 return (char *)s;
00797 }
00798 #undef ESC
00799
00800 }
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811 static XawTextPosition
00812 PositionForXY (ctx, x, y)
00813 TextWidget ctx;
00814 Position x,y;
00815 {
00816 int fromx, line, width, height;
00817 XawTextPosition position;
00818
00819 if (ctx->text.lt.lines == 0) return 0;
00820
00821 for (line = 0; line < ctx->text.lt.lines - 1; line++) {
00822 if (y <= ctx->text.lt.info[line + 1].y)
00823 break;
00824 }
00825 position = ctx->text.lt.info[line].position;
00826 if (position >= ctx->text.lastPos)
00827 return(ctx->text.lastPos);
00828 fromx = (int) ctx->text.margin.left;
00829 XawTextSinkFindPosition( ctx->text.sink, position, fromx, x - fromx,
00830 FALSE, &position, &width, &height);
00831 if (position > ctx->text.lastPos) return(ctx->text.lastPos);
00832 if (position >= ctx->text.lt.info[line + 1].position)
00833 position = SrcScan(ctx->text.source, ctx->text.lt.info[line + 1].position,
00834 XawstPositions, XawsdLeft, 1, TRUE);
00835 return(position);
00836 }
00837
00838
00839
00840
00841
00842
00843
00844
00845 static int
00846 LineForPosition (ctx, position)
00847 TextWidget ctx;
00848 XawTextPosition position;
00849 {
00850 int line;
00851
00852 for (line = 0; line < ctx->text.lt.lines; line++)
00853 if (position < ctx->text.lt.info[line + 1].position)
00854 break;
00855 return(line);
00856 }
00857
00858
00859
00860
00861
00862
00863
00864
00865 static Boolean
00866 LineAndXYForPosition (ctx, pos, line, x, y)
00867 TextWidget ctx;
00868 XawTextPosition pos;
00869 int *line;
00870 Position *x, *y;
00871 {
00872 XawTextPosition linePos, endPos;
00873 Boolean visible;
00874 int realW, realH;
00875
00876 *line = 0;
00877 *x = ctx->text.margin.left;
00878 *y = ctx->text.margin.top;
00879 if ((visible = IsPositionVisible(ctx, pos))) {
00880 *line = LineForPosition(ctx, pos);
00881 *y = ctx->text.lt.info[*line].y;
00882 *x = ctx->text.margin.left;
00883 linePos = ctx->text.lt.info[*line].position;
00884 XawTextSinkFindDistance( ctx->text.sink, linePos,
00885 *x, pos, &realW, &endPos, &realH);
00886 *x += realW;
00887 }
00888 return(visible);
00889 }
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899 void
00900 #if NeedFunctionPrototypes
00901 _XawTextBuildLineTable (
00902 TextWidget ctx,
00903 XawTextPosition position,
00904 _XtBoolean force_rebuild)
00905 #else
00906 _XawTextBuildLineTable (ctx, position, force_rebuild)
00907 TextWidget ctx;
00908 XawTextPosition position;
00909 Boolean force_rebuild;
00910 #endif
00911 {
00912 Dimension height = 0;
00913 int lines = 0;
00914 Cardinal size;
00915
00916 if ((int)ctx->core.height > VMargins(ctx)) {
00917 height = ctx->core.height - VMargins(ctx);
00918 lines = XawTextSinkMaxLines(ctx->text.sink, height);
00919 }
00920 size = sizeof(XawTextLineTableEntry) * (lines + 1);
00921
00922 if ( (lines != ctx->text.lt.lines) || (ctx->text.lt.info == NULL) ) {
00923 ctx->text.lt.info = (XawTextLineTableEntry *) XtRealloc((char *) ctx->text.
00924 lt.info, size);
00925 ctx->text.lt.lines = lines;
00926 force_rebuild = TRUE;
00927 }
00928
00929 if ( force_rebuild || (position != ctx->text.lt.top) ) {
00930 (void) bzero((char *) ctx->text.lt.info, size);
00931 (void) _BuildLineTable(ctx, ctx->text.lt.top = position, zeroPosition, 0);
00932 }
00933 }
00934
00935
00936
00937
00938
00939 static XawTextPosition
00940 _BuildLineTable(ctx, position, min_pos, line)
00941 TextWidget ctx;
00942 XawTextPosition position, min_pos;
00943 int line;
00944 {
00945 XawTextLineTableEntry * lt = ctx->text.lt.info + line;
00946 XawTextPosition endPos;
00947 Position y;
00948 int count, width, realW, realH;
00949 Widget src = ctx->text.source;
00950
00951 if ( ((ctx->text.resize == XawtextResizeWidth) ||
00952 (ctx->text.resize == XawtextResizeBoth) ) ||
00953 (ctx->text.wrap == XawtextWrapNever) )
00954 width = BIGNUM;
00955 else
00956 width = Max(0, ((int)ctx->core.width - (int)HMargins(ctx)));
00957
00958 y = ( (line == 0) ? ctx->text.margin.top : lt->y );
00959
00960
00961 while ( TRUE ) {
00962 lt->y = y;
00963 lt->position = position;
00964
00965 XawTextSinkFindPosition( ctx->text.sink, position, ctx->text.margin.left,
00966 width, ctx->text.wrap == XawtextWrapWord,
00967 &endPos, &realW, &realH);
00968 lt->textWidth = realW;
00969 y += realH;
00970
00971 if (ctx->text.wrap == XawtextWrapNever)
00972 endPos = SrcScan(src, position, XawstEOL, XawsdRight, 1, TRUE);
00973
00974 if ( endPos == ctx->text.lastPos) {
00975 if(SrcScan(src, position, XawstEOL, XawsdRight, 1, FALSE) == endPos)
00976 break;
00977 }
00978
00979 ++lt;
00980 ++line;
00981 if ( (line > ctx->text.lt.lines) ||
00982 ((lt->position == (position = endPos)) && (position > min_pos)) )
00983 return(position);
00984 }
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001 for ( count = 0; count < 2 ; count++)
01002 if (line++ < ctx->text.lt.lines) {
01003 (++lt)->y = (count == 0) ? y : ctx->core.height;
01004 lt->textWidth = 0;
01005 lt->position = ctx->text.lastPos + 100;
01006 }
01007
01008 if (line < ctx->text.lt.lines)
01009 (void) bzero( (char *) (lt + 1),
01010 (ctx->text.lt.lines - line) * sizeof(XawTextLineTableEntry) );
01011
01012 ctx->text.lt.info[ctx->text.lt.lines].position = lt->position;
01013
01014 return(endPos);
01015 }
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026 static Dimension
01027 GetWidestLine(ctx)
01028 TextWidget ctx;
01029 {
01030 int i;
01031 Dimension widest;
01032 XawTextLineTablePtr lt = &(ctx->text.lt);
01033
01034 for (i = 0, widest = 1 ; i < lt->lines ; i++)
01035 if (widest < lt->info[i].textWidth)
01036 widest = lt->info[i].textWidth;
01037
01038 return(widest);
01039 }
01040
01041 static void
01042 CheckVBarScrolling(ctx)
01043 TextWidget ctx;
01044 {
01045 float first, last;
01046 Boolean temp = (ctx->text.vbar == NULL);
01047
01048 if (ctx->text.scroll_vert == XawtextScrollNever) return;
01049
01050 if ( (ctx->text.lastPos > 0) && (ctx->text.lt.lines > 0)) {
01051 first = ctx->text.lt.top;
01052 first /= (float) ctx->text.lastPos;
01053 last = ctx->text.lt.info[ctx->text.lt.lines].position;
01054 if ( ctx->text.lt.info[ctx->text.lt.lines].position < ctx->text.lastPos )
01055 last /= (float) ctx->text.lastPos;
01056 else
01057 last = 1.0;
01058
01059 if (ctx->text.scroll_vert == XawtextScrollWhenNeeded) {
01060 int line;
01061 XawTextPosition last_pos;
01062 Position y = ctx->core.height - ctx->text.margin.bottom;
01063
01064 if (ctx->text.hbar != NULL)
01065 y -= (ctx->text.hbar->core.height +
01066 2 * ctx->text.hbar->core.border_width);
01067
01068 last_pos = PositionForXY(ctx, (Position) ctx->core.width, y);
01069 line = LineForPosition(ctx, last_pos);
01070
01071 if ( (y < ctx->text.lt.info[line + 1].y) || ((last - first) < 1.0) )
01072 CreateVScrollBar(ctx);
01073 else
01074 DestroyVScrollBar(ctx);
01075 }
01076
01077 if (ctx->text.vbar != NULL)
01078 XawScrollbarSetThumb(ctx->text.vbar, first, last - first);
01079
01080 if ( (ctx->text.vbar == NULL) != temp) {
01081 _XawTextNeedsUpdating(ctx, zeroPosition, ctx->text.lastPos);
01082 if (ctx->text.vbar == NULL)
01083 _XawTextBuildLineTable (ctx, zeroPosition, FALSE);
01084 }
01085 }
01086 else if (ctx->text.vbar != NULL)
01087 if (ctx->text.scroll_vert == XawtextScrollWhenNeeded)
01088 DestroyVScrollBar(ctx);
01089 else if (ctx->text.scroll_vert == XawtextScrollAlways)
01090 XawScrollbarSetThumb(ctx->text.vbar, 0.0, 1.0);
01091 }
01092
01093
01094
01095
01096
01097
01098
01099 void
01100 _XawTextSetScrollBars(ctx)
01101 TextWidget ctx;
01102 {
01103 float first, last, widest;
01104 Boolean temp = (ctx->text.hbar == NULL);
01105 Boolean vtemp = (ctx->text.vbar == NULL);
01106
01107 CheckVBarScrolling(ctx);
01108
01109 if (ctx->text.scroll_horiz == XawtextScrollNever) return;
01110
01111 if (ctx->text.vbar != NULL)
01112 widest = (int)(ctx->core.width - ctx->text.vbar->core.width -
01113 ctx->text.vbar->core.border_width);
01114 else
01115 widest = ctx->core.width;
01116 widest /= (last = GetWidestLine(ctx));
01117 if (ctx->text.scroll_horiz == XawtextScrollWhenNeeded)
01118 if (widest < 1.0)
01119 CreateHScrollBar(ctx);
01120 else
01121 DestroyHScrollBar(ctx);
01122
01123 if ( (ctx->text.hbar == NULL) != temp ) {
01124 _XawTextBuildLineTable (ctx, ctx->text.lt.top, TRUE);
01125 CheckVBarScrolling(ctx);
01126
01127 }
01128
01129 if (ctx->text.hbar != NULL) {
01130 first = ctx->text.r_margin.left - ctx->text.margin.left;
01131 first /= last;
01132 XawScrollbarSetThumb(ctx->text.hbar, first, widest);
01133 }
01134
01135 if (((ctx->text.hbar == NULL) && (ctx->text.margin.left !=
01136 ctx->text.r_margin.left)) ||
01137 (ctx->text.vbar == NULL) != vtemp)
01138 {
01139 ctx->text.margin.left = ctx->text.r_margin.left;
01140 _XawTextNeedsUpdating(ctx, zeroPosition, ctx->text.lastPos);
01141 FlushUpdate(ctx);
01142 }
01143 }
01144
01145
01146
01147
01148
01149
01150
01151 void
01152 _XawTextVScroll(ctx, n)
01153 TextWidget ctx;
01154 int n;
01155 {
01156 XawTextPosition top, target;
01157 int y;
01158 Arg list[1];
01159 XawTextLineTable * lt = &(ctx->text.lt);
01160
01161 if (abs(n) > ctx->text.lt.lines)
01162 n = (n > 0) ? ctx->text.lt.lines : -ctx->text.lt.lines;
01163
01164 if (n == 0) return;
01165
01166 if (n > 0) {
01167 if ( IsValidLine(ctx, n) )
01168 top = Min(lt->info[n].position, ctx->text.lastPos);
01169 else
01170 top = ctx->text.lastPos;
01171
01172 y = IsValidLine(ctx, n) ? lt->info[n].y : ctx->core.height;
01173 _XawTextBuildLineTable(ctx, top, FALSE);
01174 if (top >= ctx->text.lastPos)
01175 DisplayTextWindow( (Widget) ctx);
01176 else {
01177 XCopyArea(XtDisplay(ctx), XtWindow(ctx), XtWindow(ctx), ctx->text.gc,
01178 0, y, (int)ctx->core.width, (int)ctx->core.height - y,
01179 0, ctx->text.margin.top);
01180
01181 PushCopyQueue(ctx, 0, (int) -y);
01182 SinkClearToBG(ctx->text.sink,
01183 (Position) 0,
01184 (Position) (ctx->text.margin.top + ctx->core.height - y),
01185 (Dimension) ctx->core.width, (Dimension) ctx->core.height);
01186
01187 if (n < lt->lines) n++;
01188 _XawTextNeedsUpdating(ctx, lt->info[lt->lines - n].position,
01189 ctx->text.lastPos);
01190 _XawTextSetScrollBars(ctx);
01191 }
01192 }
01193 else {
01194 XawTextPosition updateTo;
01195 unsigned int height, clear_height;
01196
01197 n = -n;
01198 target = lt->top;
01199 top = SrcScan(ctx->text.source, target, XawstEOL,
01200 XawsdLeft, n+1, FALSE);
01201
01202 _XawTextBuildLineTable(ctx, top, FALSE);
01203 y = IsValidLine(ctx, n) ? lt->info[n].y : ctx->core.height;
01204 updateTo = IsValidLine(ctx, n) ? lt->info[n].position : ctx->text.lastPos;
01205 if (IsValidLine(ctx, lt->lines - n))
01206 height = lt->info[lt->lines-n].y - ctx->text.margin.top;
01207 else if (ctx->core.height - HMargins(ctx))
01208 height = ctx->core.height - HMargins(ctx);
01209 else
01210 height = 0;
01211 if (y > (int) ctx->text.margin.top)
01212 clear_height = y - ctx->text.margin.top;
01213 else
01214 clear_height = 0;
01215
01216 if ( updateTo == target ) {
01217 XCopyArea(XtDisplay(ctx), XtWindow(ctx), XtWindow(ctx), ctx->text.gc,
01218 0, ctx->text.margin.top, (int) ctx->core.width, height, 0, y);
01219 PushCopyQueue(ctx, 0, (int) y);
01220 SinkClearToBG(ctx->text.sink, (Position) 0, ctx->text.margin.top,
01221 (Dimension) ctx->core.width, (Dimension) clear_height);
01222
01223 _XawTextNeedsUpdating(ctx, lt->info[0].position, updateTo);
01224 _XawTextSetScrollBars(ctx);
01225 }
01226 else if (lt->top != target)
01227 DisplayTextWindow((Widget)ctx);
01228 }
01229 XtSetArg (list[0], XtNinsertPosition, ctx->text.lt.top+ctx->text.lt.lines);
01230 _XawImSetValues ((Widget) ctx, list, 1);
01231 }
01232
01233
01234 static void
01235 HScroll(w, closure, callData)
01236 Widget w;
01237 XtPointer closure;
01238 XtPointer callData;
01239 {
01240 TextWidget ctx = (TextWidget) closure;
01241 Widget tw = (Widget) ctx;
01242 Position old_left, pixels = (Position)(int) callData;
01243 XRectangle rect, t_rect;
01244
01245 _XawTextPrepareToUpdate(ctx);
01246
01247 old_left = ctx->text.margin.left;
01248 ctx->text.margin.left -= pixels;
01249 if (ctx->text.margin.left > ctx->text.r_margin.left) {
01250 ctx->text.margin.left = ctx->text.r_margin.left;
01251 pixels = old_left - ctx->text.margin.left;
01252 }
01253
01254 if (pixels > 0) {
01255 rect.width = (unsigned short) pixels + ctx->text.margin.right;
01256 rect.x = (short) ctx->core.width - (short) rect.width;
01257 rect.y = (short) ctx->text.margin.top;
01258 rect.height = (unsigned short) ctx->core.height - rect.y;
01259
01260 XCopyArea(XtDisplay(tw), XtWindow(tw), XtWindow(tw), ctx->text.gc,
01261 pixels, (int) rect.y,
01262 (unsigned int) rect.x, (unsigned int) ctx->core.height,
01263 0, (int) rect.y);
01264
01265 PushCopyQueue(ctx, (int) -pixels, 0);
01266 }
01267 else if (pixels < 0) {
01268 rect.x = 0;
01269
01270 if (ctx->text.vbar != NULL)
01271 rect.x += (short) (ctx->text.vbar->core.width +
01272 ctx->text.vbar->core.border_width);
01273
01274 rect.width = (Position) - pixels;
01275 rect.y = ctx->text.margin.top;
01276 rect.height = ctx->core.height - rect.y;
01277
01278 XCopyArea(XtDisplay(tw), XtWindow(tw), XtWindow(tw), ctx->text.gc,
01279 (int) rect.x, (int) rect.y,
01280 (unsigned int) ctx->core.width - rect.width,
01281 (unsigned int) rect.height,
01282 (int) rect.x + rect.width, (int) rect.y);
01283
01284 PushCopyQueue(ctx, (int) rect.width, 0);
01285
01286
01287
01288
01289
01290 t_rect.x = ctx->core.width - ctx->text.margin.right;
01291 t_rect.width = ctx->text.margin.right;
01292 t_rect.y = rect.y;
01293 t_rect.height = rect.height;
01294
01295 SinkClearToBG(ctx->text.sink, (Position) t_rect.x, (Position) t_rect.y,
01296 (Dimension) t_rect.width, (Dimension) t_rect.height);
01297
01298 UpdateTextInRectangle(ctx, &t_rect);
01299 }
01300
01301
01302
01303
01304
01305 if ( pixels != 0 ) {
01306 SinkClearToBG(ctx->text.sink, (Position) rect.x, (Position) rect.y,
01307 (Dimension) rect.width, (Dimension) rect.height);
01308
01309 UpdateTextInRectangle(ctx, &rect);
01310 }
01311 _XawTextExecuteUpdate(ctx);
01312 _XawTextSetScrollBars(ctx);
01313 }
01314
01315
01316 static void
01317 HJump(w, closure, callData)
01318 Widget w;
01319 XtPointer closure, callData;
01320 {
01321 TextWidget ctx = (TextWidget) closure;
01322 float * percent = (float *) callData;
01323 Position new_left, old_left = ctx->text.margin.left;
01324
01325 long move;
01326
01327 new_left = ctx->text.r_margin.left;
01328 new_left -= (Position) (*percent * GetWidestLine(ctx));
01329 move = old_left - new_left;
01330
01331 if (abs(move) < (int)ctx->core.width) {
01332 HScroll(w, (XtPointer) ctx, (XtPointer) move);
01333 return;
01334 }
01335 _XawTextPrepareToUpdate(ctx);
01336 ctx->text.margin.left = new_left;
01337 if (XtIsRealized((Widget) ctx)) DisplayTextWindow((Widget) ctx);
01338 _XawTextExecuteUpdate(ctx);
01339 }
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350 static void
01351 UpdateTextInLine(ctx, line, left, right)
01352 TextWidget ctx;
01353 int line;
01354 Position left, right;
01355 {
01356 XawTextPosition pos1, pos2;
01357 int width, height, local_left, local_width;
01358 XawTextLineTableEntry * lt = ctx->text.lt.info + line;
01359
01360 if ( ((int)(lt->textWidth + ctx->text.margin.left) < left) ||
01361 ( ctx->text.margin.left > right ) )
01362 return;
01363
01364 local_width = left - ctx->text.margin.left;
01365 XawTextSinkFindPosition(ctx->text.sink, lt->position,
01366 (int) ctx->text.margin.left,
01367 local_width, FALSE, &pos1, &width, &height);
01368
01369 if (right >= (Position) lt->textWidth - ctx->text.margin.left)
01370 if ( (IsValidLine(ctx, line + 1)) &&
01371 (ctx->text.lt.info[line + 1].position <= ctx->text.lastPos) )
01372 pos2 = SrcScan( ctx->text.source, (lt + 1)->position, XawstPositions,
01373 XawsdLeft, 1, TRUE);
01374 else
01375 pos2 = GETLASTPOS;
01376 else {
01377 XawTextPosition t_pos;
01378
01379 local_left = ctx->text.margin.left + width;
01380 local_width = right - local_left;
01381 XawTextSinkFindPosition(ctx->text.sink, pos1, local_left,
01382 local_width, FALSE, &pos2, &width, &height);
01383
01384 t_pos = SrcScan( ctx->text.source, pos2,
01385 XawstPositions, XawsdRight, 1, TRUE);
01386 if (t_pos < (lt + 1)->position)
01387 pos2 = t_pos;
01388 }
01389
01390 _XawTextNeedsUpdating(ctx, pos1, pos2);
01391 }
01392
01393
01394
01395
01396
01397
01398
01399 static void
01400 VScroll(w, closure, callData)
01401 Widget w;
01402 XtPointer closure;
01403 XtPointer callData;
01404 {
01405 TextWidget ctx = (TextWidget)closure;
01406 int height, nlines, lines = (int) callData;
01407
01408 height = ctx->core.height - VMargins(ctx);
01409 if (height < 1)
01410 height = 1;
01411 nlines = (int) (lines * (int) ctx->text.lt.lines) / height;
01412 #ifdef ARROW_SCROLLBAR
01413 if (nlines == 0 && lines != 0)
01414 nlines = lines > 0 ? 1 : -1;
01415 #endif
01416 _XawTextPrepareToUpdate(ctx);
01417 _XawTextVScroll(ctx, nlines);
01418 _XawTextExecuteUpdate(ctx);
01419 }
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434 static void
01435 VJump(w, closure, callData)
01436 Widget w;
01437 XtPointer closure, callData;
01438 {
01439 float * percent = (float *) callData;
01440 TextWidget ctx = (TextWidget)closure;
01441 XawTextPosition position, old_top, old_bot;
01442 XawTextLineTable * lt = &(ctx->text.lt);
01443
01444 _XawTextPrepareToUpdate(ctx);
01445 old_top = lt->top;
01446 if ( (lt->lines > 0) && (IsValidLine(ctx, lt->lines - 1)) )
01447 old_bot = lt->info[lt->lines - 1].position;
01448 else
01449 old_bot = ctx->text.lastPos;
01450
01451 position = (long) (*percent * (float) ctx->text.lastPos);
01452 position= SrcScan(ctx->text.source, position, XawstEOL, XawsdLeft, 1, FALSE);
01453 if ( (position >= old_top) && (position <= old_bot) ) {
01454 int line = 0;
01455 for (;(line < lt->lines) && (position > lt->info[line].position) ; line++);
01456 _XawTextVScroll(ctx, line);
01457 }
01458 else {
01459 XawTextPosition new_bot;
01460 _XawTextBuildLineTable(ctx, position, FALSE);
01461 new_bot = IsValidLine(ctx, lt->lines-1) ? lt->info[lt->lines-1].position
01462 : ctx->text.lastPos;
01463
01464 if ((old_top >= lt->top) && (old_top <= new_bot)) {
01465 int line = 0;
01466 for (;(line < lt->lines) && (old_top > lt->info[line].position); line++);
01467 _XawTextBuildLineTable(ctx, old_top, FALSE);
01468 _XawTextVScroll(ctx, -line);
01469 }
01470 else
01471 DisplayTextWindow( (Widget) ctx);
01472 }
01473 _XawTextExecuteUpdate(ctx);
01474 }
01475
01476 static Boolean
01477 MatchSelection(selection, s)
01478 Atom selection;
01479 XawTextSelection *s;
01480 {
01481 Atom *match;
01482 int count;
01483
01484 for (count = 0, match = s->selections; count < s->atom_count; match++, count++)
01485 if (*match == selection)
01486 return True;
01487 return False;
01488 }
01489
01490 static Boolean
01491 ConvertSelection(w, selection, target, type, value, length, format)
01492 Widget w;
01493 Atom *selection, *target, *type;
01494 XtPointer *value;
01495 unsigned long *length;
01496 int *format;
01497 {
01498 Display* d = XtDisplay(w);
01499 TextWidget ctx = (TextWidget)w;
01500 Widget src = ctx->text.source;
01501 XawTextEditType edit_mode;
01502 Arg args[1];
01503
01504 XawTextSelectionSalt *salt = NULL;
01505 XawTextSelection *s;
01506
01507 if (*target == XA_TARGETS(d)) {
01508 Atom* targetP, * std_targets;
01509 unsigned long std_length;
01510
01511 if ( SrcCvtSel(src, selection, target, type, value, length, format) )
01512 return True;
01513
01514 XmuConvertStandardSelection(w, ctx->text.time, selection,
01515 target, type, (XPointer*)&std_targets,
01516 &std_length, format);
01517
01518 *value = XtMalloc((unsigned) sizeof(Atom)*(std_length + 7));
01519 targetP = *(Atom**)value;
01520 *length = std_length + 6;
01521 *targetP++ = XA_STRING;
01522 *targetP++ = XA_TEXT(d);
01523 *targetP++ = XA_COMPOUND_TEXT(d);
01524 *targetP++ = XA_LENGTH(d);
01525 *targetP++ = XA_LIST_LENGTH(d);
01526 *targetP++ = XA_CHARACTER_POSITION(d);
01527
01528 XtSetArg(args[0], XtNeditType,&edit_mode);
01529 XtGetValues(src, args, ONE);
01530
01531 if (edit_mode == XawtextEdit) {
01532 *targetP++ = XA_DELETE(d);
01533 (*length)++;
01534 }
01535 (void) memmove((char*)targetP, (char*)std_targets, sizeof(Atom)*std_length);
01536 XtFree((char*)std_targets);
01537 *type = XA_ATOM;
01538 *format = 32;
01539 return True;
01540 }
01541
01542 if ( SrcCvtSel(src, selection, target, type, value, length, format) )
01543 return True;
01544
01545 if (MatchSelection (*selection, &ctx->text.s))
01546 s = &ctx->text.s;
01547 else
01548 {
01549 for (salt = ctx->text.salt; salt; salt = salt->next)
01550 if (MatchSelection (*selection, &salt->s))
01551 break;
01552 if (!salt)
01553 return False;
01554 s = &salt->s;
01555 }
01556 if (*target == XA_STRING ||
01557 *target == XA_TEXT(d) ||
01558 *target == XA_COMPOUND_TEXT(d)) {
01559 if (*target == XA_TEXT(d)) {
01560 if (_XawTextFormat(ctx) == XawFmtWide)
01561 *type = XA_COMPOUND_TEXT(d);
01562 else
01563 *type = XA_STRING;
01564 } else {
01565 *type = *target;
01566 }
01567
01568
01569
01570
01571
01572
01573
01574 if (!salt) {
01575 *value = _XawTextGetSTRING(ctx, s->left, s->right);
01576 if (_XawTextFormat(ctx) == XawFmtWide) {
01577 XTextProperty textprop;
01578 if (XwcTextListToTextProperty(d, (wchar_t **)value, 1,
01579 XCompoundTextStyle, &textprop)
01580 < Success) {
01581 XtFree(*value);
01582 return False;
01583 }
01584 XtFree(*value);
01585 *value = (XtPointer)textprop.value;
01586 *length = textprop.nitems;
01587 } else {
01588 *length = strlen(*value);
01589 }
01590 } else {
01591 *value = XtMalloc((salt->length + 1) * sizeof(unsigned char));
01592 strcpy (*value, salt->contents);
01593 *length = salt->length;
01594 }
01595 if (_XawTextFormat(ctx) == XawFmtWide && *type == XA_STRING) {
01596 XTextProperty textprop;
01597 wchar_t **wlist;
01598 int count;
01599 textprop.encoding = XA_COMPOUND_TEXT(d);
01600 textprop.value = (unsigned char *)*value;
01601 textprop.nitems = strlen(*value);
01602 textprop.format = 8;
01603 if (XwcTextPropertyToTextList(d, &textprop, (wchar_t ***)&wlist, &count)
01604 < Success) {
01605 XtFree(*value);
01606 return False;
01607 }
01608 XtFree(*value);
01609 if (XwcTextListToTextProperty( d, (wchar_t **)wlist, 1,
01610 XStringStyle, &textprop) < Success) {
01611 XwcFreeStringList( (wchar_t**) wlist );
01612 return False;
01613 }
01614 *value = (XtPointer) textprop.value;
01615 *length = textprop.nitems;
01616 XwcFreeStringList( (wchar_t**) wlist );
01617 }
01618 *format = 8;
01619 return True;
01620 }
01621
01622 if ( (*target == XA_LIST_LENGTH(d)) || (*target == XA_LENGTH(d)) ) {
01623 long * temp;
01624
01625 temp = (long *) XtMalloc( (unsigned) sizeof(long) );
01626 if (*target == XA_LIST_LENGTH(d))
01627 *temp = 1L;
01628 else
01629 *temp = (long) (s->right - s->left);
01630
01631 *value = (XPointer) temp;
01632 *type = XA_INTEGER;
01633 *length = 1L;
01634 *format = 32;
01635 return True;
01636 }
01637
01638 if (*target == XA_CHARACTER_POSITION(d)) {
01639 long * temp;
01640
01641 temp = (long *) XtMalloc( (unsigned)( 2 * sizeof(long) ) );
01642 temp[0] = (long) (s->left + 1);
01643 temp[1] = s->right;
01644 *value = (XPointer) temp;
01645 *type = XA_SPAN(d);
01646 *length = 2L;
01647 *format = 32;
01648 return True;
01649 }
01650
01651 if (*target == XA_DELETE(d)) {
01652 void _XawTextZapSelection();
01653
01654 if (!salt)
01655 _XawTextZapSelection( ctx, (XEvent *) NULL, TRUE);
01656 *value = NULL;
01657 *type = XA_NULL(d);
01658 *length = 0;
01659 *format = 32;
01660 return True;
01661 }
01662
01663 if (XmuConvertStandardSelection(w, ctx->text.time, selection, target, type,
01664 (XPointer *)value, length, format))
01665 return True;
01666
01667
01668 return False;
01669 }
01670
01671
01672
01673
01674
01675
01676
01677
01678 #define NOT_A_CUT_BUFFER -1
01679
01680 static int
01681 GetCutBufferNumber(atom)
01682 Atom atom;
01683 {
01684 if (atom == XA_CUT_BUFFER0) return(0);
01685 if (atom == XA_CUT_BUFFER1) return(1);
01686 if (atom == XA_CUT_BUFFER2) return(2);
01687 if (atom == XA_CUT_BUFFER3) return(3);
01688 if (atom == XA_CUT_BUFFER4) return(4);
01689 if (atom == XA_CUT_BUFFER5) return(5);
01690 if (atom == XA_CUT_BUFFER6) return(6);
01691 if (atom == XA_CUT_BUFFER7) return(7);
01692 return(NOT_A_CUT_BUFFER);
01693 }
01694
01695 static void
01696 LoseSelection(w, selection)
01697 Widget w;
01698 Atom *selection;
01699 {
01700 TextWidget ctx = (TextWidget) w;
01701 Atom* atomP;
01702 int i;
01703 XawTextSelectionSalt *salt, *prevSalt, *nextSalt;
01704
01705 _XawTextPrepareToUpdate(ctx);
01706
01707 atomP = ctx->text.s.selections;
01708 for (i = 0 ; i < ctx->text.s.atom_count; i++, atomP++)
01709 if ( (*selection == *atomP) ||
01710 (GetCutBufferNumber(*atomP) != NOT_A_CUT_BUFFER) )
01711 *atomP = (Atom)0;
01712
01713 while (ctx->text.s.atom_count &&
01714 ctx->text.s.selections[ctx->text.s.atom_count-1] == 0)
01715 ctx->text.s.atom_count--;
01716
01717
01718
01719
01720
01721 atomP = ctx->text.s.selections;
01722 for (i = 0 ; i < ctx->text.s.atom_count; i++, atomP++)
01723 if (*atomP == (Atom)0) {
01724 *atomP = ctx->text.s.selections[--ctx->text.s.atom_count];
01725 while (ctx->text.s.atom_count &&
01726 ctx->text.s.selections[ctx->text.s.atom_count-1] == 0)
01727 ctx->text.s.atom_count--;
01728 }
01729
01730 if (ctx->text.s.atom_count == 0)
01731 ModifySelection(ctx, ctx->text.insertPos, ctx->text.insertPos);
01732
01733 if (ctx->text.old_insert >= 0)
01734 _XawTextExecuteUpdate(ctx);
01735
01736 prevSalt = 0;
01737 for (salt = ctx->text.salt; salt; salt = nextSalt)
01738 {
01739 atomP = salt->s.selections;
01740 nextSalt = salt->next;
01741 for (i = 0 ; i < salt->s.atom_count; i++, atomP++)
01742 if (*selection == *atomP)
01743 *atomP = (Atom)0;
01744
01745 while (salt->s.atom_count &&
01746 salt->s.selections[salt->s.atom_count-1] == 0)
01747 {
01748 salt->s.atom_count--;
01749 }
01750
01751
01752
01753
01754
01755 atomP = salt->s.selections;
01756 for (i = 0 ; i < salt->s.atom_count; i++, atomP++)
01757 if (*atomP == (Atom)0)
01758 {
01759 *atomP = salt->s.selections[--salt->s.atom_count];
01760 while (salt->s.atom_count &&
01761 salt->s.selections[salt->s.atom_count-1] == 0)
01762 salt->s.atom_count--;
01763 }
01764 if (salt->s.atom_count == 0)
01765 {
01766 XtFree ((char *) salt->s.selections);
01767 XtFree (salt->contents);
01768 if (prevSalt)
01769 prevSalt->next = nextSalt;
01770 else
01771 ctx->text.salt = nextSalt;
01772 XtFree ((char *) salt);
01773 }
01774 else
01775 prevSalt = salt;
01776 }
01777 }
01778
01779 void
01780 _XawTextSaltAwaySelection (ctx, selections, num_atoms)
01781 TextWidget ctx;
01782 Atom* selections;
01783 int num_atoms;
01784 {
01785 XawTextSelectionSalt *salt;
01786 int i, j;
01787
01788 for (i = 0; i < num_atoms; i++)
01789 LoseSelection ((Widget) ctx, selections + i);
01790 if (num_atoms == 0)
01791 return;
01792 salt = (XawTextSelectionSalt *)
01793 XtMalloc( (unsigned) sizeof(XawTextSelectionSalt) );
01794 if (!salt)
01795 return;
01796 salt->s.selections = (Atom *)
01797 XtMalloc( (unsigned) ( num_atoms * sizeof (Atom) ) );
01798 if (!salt->s.selections)
01799 {
01800 XtFree ((char *) salt);
01801 return;
01802 }
01803 salt->s.left = ctx->text.s.left;
01804 salt->s.right = ctx->text.s.right;
01805 salt->s.type = ctx->text.s.type;
01806 salt->contents = _XawTextGetSTRING(ctx, ctx->text.s.left, ctx->text.s.right);
01807 if (_XawTextFormat(ctx) == XawFmtWide) {
01808 XTextProperty textprop;
01809 if (XwcTextListToTextProperty(XtDisplay((Widget)ctx),
01810 (wchar_t**)(&(salt->contents)), 1, XCompoundTextStyle,
01811 &textprop) < Success) {
01812 XtFree(salt->contents);
01813 salt->length = 0;
01814 return;
01815 }
01816 XtFree(salt->contents);
01817 salt->contents = (char *)textprop.value;
01818 salt->length = textprop.nitems;
01819 } else
01820 salt->length = strlen (salt->contents);
01821 salt->next = ctx->text.salt;
01822 ctx->text.salt = salt;
01823 j = 0;
01824 for (i = 0; i < num_atoms; i++)
01825 {
01826 if (GetCutBufferNumber (selections[i]) == NOT_A_CUT_BUFFER)
01827 {
01828 salt->s.selections[j++] = selections[i];
01829 XtOwnSelection ((Widget) ctx, selections[i], ctx->text.time,
01830 ConvertSelection, LoseSelection, (XtSelectionDoneProc)NULL);
01831 }
01832 }
01833 salt->s.atom_count = j;
01834 }
01835
01836 static void
01837 _SetSelection(ctx, left, right, selections, count)
01838 TextWidget ctx;
01839 XawTextPosition left, right;
01840 Atom *selections;
01841 Cardinal count;
01842 {
01843 XawTextPosition pos;
01844
01845 if (left < ctx->text.s.left) {
01846 pos = Min(right, ctx->text.s.left);
01847 _XawTextNeedsUpdating(ctx, left, pos);
01848 }
01849 if (left > ctx->text.s.left) {
01850 pos = Min(left, ctx->text.s.right);
01851 _XawTextNeedsUpdating(ctx, ctx->text.s.left, pos);
01852 }
01853 if (right < ctx->text.s.right) {
01854 pos = Max(right, ctx->text.s.left);
01855 _XawTextNeedsUpdating(ctx, pos, ctx->text.s.right);
01856 }
01857 if (right > ctx->text.s.right) {
01858 pos = Max(left, ctx->text.s.right);
01859 _XawTextNeedsUpdating(ctx, pos, right);
01860 }
01861
01862 ctx->text.s.left = left;
01863 ctx->text.s.right = right;
01864
01865 SrcSetSelection(ctx->text.source, left, right,
01866 (count == 0) ? None : selections[0]);
01867
01868 if (left < right) {
01869 Widget w = (Widget) ctx;
01870 int buffer;
01871
01872 while (count) {
01873 Atom selection = selections[--count];
01874
01875 if ((buffer = GetCutBufferNumber(selection)) != NOT_A_CUT_BUFFER) {
01876
01877 unsigned char *ptr, *tptr;
01878 unsigned int amount, max_len = MAX_CUT_LEN(XtDisplay(w));
01879 unsigned long len;
01880
01881 tptr= ptr= (unsigned char *) _XawTextGetSTRING(ctx, ctx->text.s.left,
01882 ctx->text.s.right);
01883 if (_XawTextFormat(ctx) == XawFmtWide) {
01884
01885
01886
01887
01888 XTextProperty textprop;
01889 if (XwcTextListToTextProperty(XtDisplay(w), (wchar_t**)&ptr, 1,
01890 XStringStyle, &textprop) < Success) {
01891 XtFree((char *)ptr);
01892 return;
01893 }
01894 XtFree((char *)ptr);
01895 tptr = ptr = textprop.value;
01896 }
01897 if (buffer == 0) {
01898 _CreateCutBuffers(XtDisplay(w));
01899 XRotateBuffers(XtDisplay(w), 1);
01900 }
01901 amount = Min ( (len = strlen((char *)ptr)), max_len);
01902 XChangeProperty(XtDisplay(w), RootWindow(XtDisplay(w), 0), selection,
01903 XA_STRING, 8, PropModeReplace, ptr, amount);
01904
01905 while (len > max_len) {
01906 len -= max_len;
01907 tptr += max_len;
01908 amount = Min (len, max_len);
01909 XChangeProperty(XtDisplay(w), RootWindow(XtDisplay(w), 0),
01910 selection, XA_STRING, 8, PropModeAppend,
01911 tptr, amount);
01912 }
01913 XtFree ((char *)ptr);
01914 }
01915 else
01916 XtOwnSelection(w, selection, ctx->text.time, ConvertSelection,
01917 LoseSelection, (XtSelectionDoneProc)NULL);
01918 }
01919 }
01920 else
01921 XawTextUnsetSelection((Widget)ctx);
01922 }
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932 int
01933 _XawTextReplace (ctx, pos1, pos2, text)
01934 TextWidget ctx;
01935 XawTextPosition pos1, pos2;
01936 XawTextBlock *text;
01937 {
01938 int i, line1, delta, error;
01939 XawTextPosition updateFrom, updateTo;
01940 Widget src = ctx->text.source;
01941 XawTextEditType edit_mode;
01942 Arg args[1];
01943 Boolean tmp = ctx->text.update_disabled;
01944
01945 ctx->text.update_disabled = True;
01946
01947
01948
01949
01950
01951 XtSetArg(args[0], XtNeditType, &edit_mode);
01952 XtGetValues(src, args, ONE);
01953
01954 if ((pos1 == ctx->text.insertPos) && (edit_mode == XawtextAppend)) {
01955 ctx->text.insertPos = ctx->text.lastPos;
01956 pos2 = SrcScan(src, ctx->text.insertPos, XawstPositions, XawsdRight,
01957 (int)(ctx->text.insertPos - pos1), (Boolean)TRUE);
01958 pos1 = ctx->text.insertPos;
01959 if ( (pos1 == pos2) && (text->length == 0) ) {
01960 ctx->text.update_disabled = FALSE;
01961 return( XawEditError );
01962 }
01963 }
01964
01965 updateFrom = SrcScan(src, pos1, XawstWhiteSpace, XawsdLeft, 1, FALSE);
01966 updateFrom = Max(updateFrom, ctx->text.lt.top);
01967
01968 line1 = LineForPosition(ctx, updateFrom);
01969 if ( (error = SrcReplace(src, pos1, pos2, text)) != 0) {
01970 ctx->text.update_disabled = tmp;
01971 return(error);
01972 }
01973
01974 XawTextUnsetSelection((Widget)ctx);
01975
01976 ctx->text.lastPos = GETLASTPOS;
01977 if (ctx->text.lt.top >= ctx->text.lastPos) {
01978 _XawTextBuildLineTable(ctx, ctx->text.lastPos, FALSE);
01979 ClearWindow( (Widget) ctx);
01980 ctx->text.update_disabled = tmp;
01981 return(0);
01982 }
01983
01984 ctx->text.single_char = (text->length <= 1 && pos2 - pos1 <= 1);
01985
01986 delta = text->length - (pos2 - pos1);
01987
01988 if (delta < ctx->text.lastPos) {
01989 for (pos2 += delta, i = 0; i < ctx->text.numranges; i++) {
01990 if (ctx->text.updateFrom[i] > pos1)
01991 ctx->text.updateFrom[i] += delta;
01992 if (ctx->text.updateTo[i] >= pos1)
01993 ctx->text.updateTo[i] += delta;
01994 }
01995 }
01996
01997
01998
01999
02000
02001
02002 if (delta != 0) {
02003 XawTextLineTableEntry *lineP;
02004 i = LineForPosition(ctx, pos1) + 1;
02005 for (lineP = ctx->text.lt.info + i; i <= ctx->text.lt.lines; i++, lineP++)
02006 lineP->position += delta;
02007 }
02008
02009
02010
02011
02012
02013
02014
02015 if (IsPositionVisible(ctx, updateFrom)) {
02016 updateTo = _BuildLineTable(ctx,
02017 ctx->text.lt.info[line1].position, pos1, line1);
02018 _XawTextNeedsUpdating(ctx, updateFrom, updateTo);
02019 }
02020
02021 ctx->text.update_disabled = tmp;
02022 return(0);
02023 }
02024
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034 static void
02035 DisplayText(w, pos1, pos2)
02036 Widget w;
02037 XawTextPosition pos1, pos2;
02038 {
02039 TextWidget ctx = (TextWidget)w;
02040 Position x, y;
02041 int height, line, i, lastPos = ctx->text.lastPos;
02042 XawTextPosition startPos, endPos;
02043 Boolean clear_eol, done_painting;
02044
02045 pos1 = (pos1 < ctx->text.lt.top) ? ctx->text.lt.top : pos1;
02046 pos2 = FindGoodPosition(ctx, pos2);
02047 if ( (pos1 >= pos2) || !LineAndXYForPosition(ctx, pos1, &line, &x, &y) )
02048 return;
02049
02050 for ( startPos = pos1, i = line; IsValidLine(ctx, i) &&
02051 (i < ctx->text.lt.lines) ; i++) {
02052
02053
02054 if ( (endPos = ctx->text.lt.info[i + 1].position) > pos2 ) {
02055 clear_eol = ((endPos = pos2) >= lastPos);
02056 done_painting = (!clear_eol || ctx->text.single_char);
02057 }
02058 else {
02059 clear_eol = TRUE;
02060 done_painting = FALSE;
02061 }
02062
02063 height = ctx->text.lt.info[i + 1].y - ctx->text.lt.info[i].y;
02064
02065 if ( (endPos > startPos) ) {
02066 if ( (x == (Position) ctx->text.margin.left) && (x > 0) )
02067 SinkClearToBG (ctx->text.sink,
02068 (Position) 0, y,
02069 (Dimension) ctx->text.margin.left, (Dimension)height);
02070
02071 if ( (startPos >= ctx->text.s.right) || (endPos <= ctx->text.s.left) )
02072 XawTextSinkDisplayText(ctx->text.sink, x, y, startPos, endPos, FALSE);
02073 else if ((startPos >= ctx->text.s.left) && (endPos <= ctx->text.s.right))
02074 XawTextSinkDisplayText(ctx->text.sink, x, y, startPos, endPos, TRUE);
02075 else {
02076 DisplayText(w, startPos, ctx->text.s.left);
02077 DisplayText(w, Max(startPos, ctx->text.s.left),
02078 Min(endPos, ctx->text.s.right));
02079 DisplayText(w, ctx->text.s.right, endPos);
02080 }
02081 }
02082 startPos = endPos;
02083 if (clear_eol) {
02084 SinkClearToBG(ctx->text.sink,
02085 (Position) (ctx->text.lt.info[i].textWidth +
02086 ctx->text.margin.left),
02087 (Position) y, w->core.width, (Dimension) height);
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100 if (done_painting) {
02101 y += height;
02102 SinkClearToBG(ctx->text.sink,
02103 (Position) ctx->text.margin.left, (Position) y,
02104 w->core.width, (Dimension) height);
02105
02106 break;
02107 }
02108 }
02109
02110 x = (Position) ctx->text.margin.left;
02111 y = ctx->text.lt.info[i + 1].y;
02112 if ( done_painting
02113 || (y >= (int)(ctx->core.height - ctx->text.margin.bottom)) )
02114 break;
02115 }
02116 ctx->text.single_char = FALSE;
02117 }
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129 static void
02130 DoSelection (ctx, pos, time, motion)
02131 TextWidget ctx;
02132 XawTextPosition pos;
02133 Time time;
02134 Boolean motion;
02135 {
02136 XawTextPosition newLeft, newRight;
02137 XawTextSelectType newType, *sarray;
02138 Widget src = ctx->text.source;
02139
02140 if (motion)
02141 newType = ctx->text.s.type;
02142 else {
02143 if ( (abs((long) time - (long) ctx->text.lasttime) < MULTI_CLICK_TIME) &&
02144 ((pos >= ctx->text.s.left) && (pos <= ctx->text.s.right))) {
02145 sarray = ctx->text.sarray;
02146 for (;*sarray != XawselectNull && *sarray != ctx->text.s.type; sarray++);
02147
02148 if (*sarray == XawselectNull)
02149 newType = *(ctx->text.sarray);
02150 else {
02151 newType = *(sarray + 1);
02152 if (newType == XawselectNull)
02153 newType = *(ctx->text.sarray);
02154 }
02155 }
02156 else
02157 newType = *(ctx->text.sarray);
02158
02159 ctx->text.lasttime = time;
02160 }
02161 switch (newType) {
02162 case XawselectPosition:
02163 newLeft = newRight = pos;
02164 break;
02165 case XawselectChar:
02166 newLeft = pos;
02167 newRight = SrcScan(src, pos, XawstPositions, XawsdRight, 1, FALSE);
02168 break;
02169 case XawselectWord:
02170 case XawselectParagraph:
02171 {
02172 XawTextScanType stype;
02173
02174 if (newType == XawselectWord)
02175 stype = XawstWhiteSpace;
02176 else
02177 stype = XawstParagraph;
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187 newRight = SrcScan(ctx->text.source, pos, stype, XawsdRight, 1, FALSE);
02188 newRight =SrcScan(ctx->text.source, newRight,stype,XawsdLeft,1, FALSE);
02189
02190 if (pos != newRight)
02191 newLeft = SrcScan(ctx->text.source, pos, stype, XawsdLeft, 1, FALSE);
02192 else
02193 newLeft = pos;
02194
02195 newLeft =SrcScan(ctx->text.source, newLeft, stype, XawsdRight,1,FALSE);
02196
02197 if (newLeft > newRight) {
02198 XawTextPosition temp = newLeft;
02199 newLeft = newRight;
02200 newRight = temp;
02201 }
02202 }
02203 break;
02204 case XawselectLine:
02205 newLeft = SrcScan(src, pos, XawstEOL, XawsdLeft, 1, FALSE);
02206 newRight = SrcScan(src, pos, XawstEOL, XawsdRight, 1, FALSE);
02207 break;
02208 case XawselectAll:
02209 newLeft = SrcScan(src, pos, XawstAll, XawsdLeft, 1, FALSE);
02210 newRight = SrcScan(src, pos, XawstAll, XawsdRight, 1, FALSE);
02211 break;
02212 default:
02213 XtAppWarning(XtWidgetToApplicationContext((Widget) ctx),
02214 "Text Widget: empty selection array.");
02215 return;
02216 }
02217
02218 if ( (newLeft != ctx->text.s.left) || (newRight != ctx->text.s.right)
02219 || (newType != ctx->text.s.type)) {
02220 ModifySelection(ctx, newLeft, newRight);
02221 if (pos - ctx->text.s.left < ctx->text.s.right - pos)
02222 ctx->text.insertPos = newLeft;
02223 else
02224 ctx->text.insertPos = newRight;
02225 ctx->text.s.type = newType;
02226 }
02227 if (!motion) {
02228 ctx->text.origSel.type = ctx->text.s.type;
02229 ctx->text.origSel.left = ctx->text.s.left;
02230 ctx->text.origSel.right = ctx->text.s.right;
02231
02232 if (pos >= ctx->text.s.left + ((ctx->text.s.right - ctx->text.s.left) / 2))
02233 ctx->text.extendDir = XawsdRight;
02234 else
02235 ctx->text.extendDir = XawsdLeft;
02236 }
02237 }
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247 static void
02248 ExtendSelection (ctx, pos, motion)
02249 TextWidget ctx;
02250 XawTextPosition pos;
02251 Boolean motion;
02252 {
02253 XawTextScanDirection dir;
02254
02255 if (!motion) {
02256 if (ctx->text.s.left == ctx->text.s.right)
02257 ctx->text.s.left = ctx->text.s.right = ctx->text.insertPos;
02258 else {
02259 ctx->text.origSel.left = ctx->text.s.left;
02260 ctx->text.origSel.right = ctx->text.s.right;
02261 }
02262
02263 ctx->text.origSel.type = ctx->text.s.type;
02264
02265 if (pos >= ctx->text.s.left + ((ctx->text.s.right - ctx->text.s.left) / 2))
02266 ctx->text.extendDir = XawsdRight;
02267 else
02268 ctx->text.extendDir = XawsdLeft;
02269 }
02270 else
02271 if ((ctx->text.extendDir == XawsdRight && pos <= ctx->text.origSel.left) ||
02272 (ctx->text.extendDir == XawsdLeft && pos >= ctx->text.origSel.right)) {
02273 ctx->text.extendDir = (ctx->text.extendDir == XawsdRight) ?
02274 XawsdLeft : XawsdRight;
02275 ModifySelection(ctx, ctx->text.origSel.left, ctx->text.origSel.right);
02276 }
02277
02278 dir = ctx->text.extendDir;
02279 switch (ctx->text.s.type) {
02280 case XawselectWord:
02281 case XawselectParagraph:
02282 {
02283 XawTextPosition left_pos, right_pos;
02284 XawTextScanType stype;
02285
02286 if (ctx->text.s.type == XawselectWord)
02287 stype = XawstWhiteSpace;
02288 else
02289 stype = XawstParagraph;
02290
02291
02292
02293
02294
02295
02296
02297
02298
02299 right_pos = SrcScan(ctx->text.source, pos, stype, XawsdRight, 1, FALSE);
02300 right_pos =SrcScan(ctx->text.source, right_pos,stype,XawsdLeft,1, FALSE);
02301
02302 if (pos != right_pos)
02303 left_pos = SrcScan(ctx->text.source, pos, stype, XawsdLeft, 1, FALSE);
02304 else
02305 left_pos = pos;
02306
02307 left_pos =SrcScan(ctx->text.source, left_pos, stype, XawsdRight,1,FALSE);
02308
02309 if (dir == XawsdLeft)
02310 pos = Min(left_pos, right_pos);
02311 else
02312 pos = Max(left_pos, right_pos);
02313 }
02314 break;
02315 case XawselectLine:
02316 pos = SrcScan(ctx->text.source, pos, XawstEOL, dir, 1, dir == XawsdRight);
02317 break;
02318 case XawselectAll:
02319 pos = ctx->text.insertPos;
02320 case XawselectPosition:
02321 default:
02322 break;
02323 }
02324
02325 if (dir == XawsdRight)
02326 ModifySelection(ctx, ctx->text.s.left, pos);
02327 else
02328 ModifySelection(ctx, pos, ctx->text.s.right);
02329
02330 ctx->text.insertPos = pos;
02331 }
02332
02333
02334
02335
02336
02337 static void
02338 ClearWindow (w)
02339 Widget w;
02340 {
02341 TextWidget ctx = (TextWidget) w;
02342
02343 if (XtIsRealized(w))
02344 SinkClearToBG(ctx->text.sink,
02345 (Position) 0, (Position) 0,
02346 w->core.width, w->core.height);
02347 }
02348
02349
02350
02351
02352
02353
02354
02355
02356 void
02357 _XawTextClearAndCenterDisplay(ctx)
02358 TextWidget ctx;
02359 {
02360 int insert_line = LineForPosition(ctx, ctx->text.insertPos);
02361 int scroll_by = insert_line - ctx->text.lt.lines/2;
02362
02363 _XawTextVScroll(ctx, scroll_by);
02364 DisplayTextWindow( (Widget) ctx);
02365 }
02366
02367
02368
02369
02370
02371
02372 static void
02373 DisplayTextWindow (w)
02374 Widget w;
02375 {
02376 TextWidget ctx = (TextWidget) w;
02377 ClearWindow(w);
02378 _XawTextBuildLineTable(ctx, ctx->text.lt.top, FALSE);
02379 _XawTextNeedsUpdating(ctx, zeroPosition, ctx->text.lastPos);
02380 _XawTextSetScrollBars(ctx);
02381 }
02382
02383
02384
02385
02386
02387
02388
02389 void
02390 _XawTextCheckResize(ctx)
02391 TextWidget ctx;
02392 {
02393 Widget w = (Widget) ctx;
02394 int line = 0, old_height;
02395 XtWidgetGeometry rbox, return_geom;
02396
02397 if ( (ctx->text.resize == XawtextResizeWidth) ||
02398 (ctx->text.resize == XawtextResizeBoth) ) {
02399 XawTextLineTableEntry *lt;
02400 rbox.width = 0;
02401 for (lt = ctx->text.lt.info;
02402 IsValidLine(ctx, line) && (line < ctx->text.lt.lines);
02403 line++, lt++) {
02404 if ((int)(lt->textWidth + ctx->text.margin.left) > (int)rbox.width)
02405 rbox.width = lt->textWidth + ctx->text.margin.left;
02406 }
02407
02408 rbox.width += ctx->text.margin.right;
02409 if (rbox.width > ctx->core.width) {
02410 rbox.request_mode = CWWidth;
02411 if (XtMakeGeometryRequest(w, &rbox, &return_geom) == XtGeometryAlmost)
02412 (void) XtMakeGeometryRequest(w, &return_geom, (XtWidgetGeometry*) NULL);
02413 }
02414 }
02415
02416 if ( !((ctx->text.resize == XawtextResizeHeight) ||
02417 (ctx->text.resize == XawtextResizeBoth)) )
02418 return;
02419
02420 if (IsPositionVisible(ctx, ctx->text.lastPos))
02421 line = LineForPosition(ctx, ctx->text.lastPos);
02422 else
02423 line = ctx->text.lt.lines;
02424
02425 if ( (line + 1) == ctx->text.lt.lines ) return;
02426
02427 old_height = ctx->core.height;
02428 rbox.request_mode = CWHeight;
02429 rbox.height = XawTextSinkMaxHeight(ctx->text.sink, line + 1) + VMargins(ctx);
02430
02431 if ((int)rbox.height < old_height) return;
02432
02433 if (XtMakeGeometryRequest(w, &rbox, &return_geom) == XtGeometryAlmost)
02434 if (XtMakeGeometryRequest(w, &return_geom, (XtWidgetGeometry*)NULL) != XtGeometryYes)
02435 return;
02436
02437 _XawTextBuildLineTable(ctx, ctx->text.lt.top, TRUE);
02438 }
02439
02440
02441
02442
02443
02444
02445 Atom*
02446 _XawTextSelectionList(ctx, list, nelems)
02447 TextWidget ctx;
02448 String *list;
02449 Cardinal nelems;
02450 {
02451 Atom * sel = ctx->text.s.selections;
02452 Display *dpy = XtDisplay((Widget) ctx);
02453 int n;
02454
02455 if (nelems > ctx->text.s.array_size) {
02456 sel = (Atom *) XtRealloc((char *) sel, sizeof(Atom) * nelems);
02457 ctx->text.s.array_size = nelems;
02458 ctx->text.s.selections = sel;
02459 }
02460 for (n=nelems; --n >= 0; sel++, list++)
02461 *sel = XInternAtom(dpy, *list, False);
02462
02463 ctx->text.s.atom_count = nelems;
02464 return ctx->text.s.selections;
02465 }
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479 void
02480 _XawTextSetSelection(ctx, l, r, list, nelems)
02481 TextWidget ctx;
02482 XawTextPosition l, r;
02483 String *list;
02484 Cardinal nelems;
02485 {
02486 if (nelems == 1 && !strcmp (list[0], "none"))
02487 return;
02488 if (nelems == 0) {
02489 String defaultSel = "PRIMARY";
02490 list = &defaultSel;
02491 nelems = 1;
02492 }
02493 _SetSelection(ctx, l, r, _XawTextSelectionList(ctx, list, nelems), nelems);
02494 }
02495
02496
02497
02498
02499
02500
02501
02502
02503
02504
02505
02506
02507 static void
02508 ModifySelection(ctx, left, right)
02509 TextWidget ctx;
02510 XawTextPosition left, right;
02511 {
02512 if (left == right)
02513 ctx->text.insertPos = left;
02514 _SetSelection( ctx, left, right, (Atom*) NULL, ZERO );
02515 }
02516
02517
02518
02519
02520
02521
02522
02523 void
02524 _XawTextAlterSelection (ctx, mode, action, params, num_params)
02525 TextWidget ctx;
02526 XawTextSelectionMode mode;
02527 XawTextSelectionAction action;
02528
02529 String *params;
02530 Cardinal *num_params;
02531 {
02532 XawTextPosition position;
02533 Boolean flag;
02534
02535
02536
02537
02538
02539
02540 if (ctx->text.search != NULL)
02541 ctx->text.search->selection_changed = TRUE;
02542
02543 position = PositionForXY (ctx, (int) ctx->text.ev_x, (int) ctx->text.ev_y);
02544
02545 flag = (action != XawactionStart);
02546 if (mode == XawsmTextSelect)
02547 DoSelection (ctx, position, ctx->text.time, flag);
02548 else
02549 ExtendSelection (ctx, position, flag);
02550
02551 if (action == XawactionEnd)
02552 _XawTextSetSelection(ctx, ctx->text.s.left, ctx->text.s.right,
02553 params, *num_params);
02554 }
02555
02556
02557
02558
02559
02560
02561
02562 static Boolean
02563 RectanglesOverlap(rect1, rect2)
02564 XRectangle *rect1, *rect2;
02565 {
02566 return ( (rect1->x < rect2->x + (short) rect2->width) &&
02567 (rect2->x < rect1->x + (short) rect1->width) &&
02568 (rect1->y < rect2->y + (short) rect2->height) &&
02569 (rect2->y < rect1->y + (short) rect1->height) );
02570 }
02571
02572
02573
02574
02575
02576
02577
02578
02579 static void
02580 UpdateTextInRectangle(ctx, rect)
02581 TextWidget ctx;
02582 XRectangle * rect;
02583 {
02584 XawTextLineTableEntry *info = ctx->text.lt.info;
02585 int line, x = rect->x, y = rect->y;
02586 int right = rect->width + x, bottom = rect->height + y;
02587
02588 for (line = 0;( (line < ctx->text.lt.lines) &&
02589 IsValidLine(ctx, line) && (info->y < bottom)); line++, info++)
02590 if ( (info + 1)->y >= y )
02591 UpdateTextInLine(ctx, line, x, right);
02592 }
02593
02594
02595
02596
02597
02598
02599
02600
02601 static void
02602 ProcessExposeRegion(w, event, region)
02603 Widget w;
02604 XEvent *event;
02605 Region region;
02606 {
02607 TextWidget ctx = (TextWidget) w;
02608 XRectangle expose, cursor;
02609 Boolean need_to_draw;
02610
02611 if (event->type == Expose) {
02612 expose.x = event->xexpose.x;
02613 expose.y = event->xexpose.y;
02614 expose.width = event->xexpose.width;
02615 expose.height = event->xexpose.height;
02616 }
02617 else if (event->type == GraphicsExpose) {
02618 expose.x = event->xgraphicsexpose.x;
02619 expose.y = event->xgraphicsexpose.y;
02620 expose.width = event->xgraphicsexpose.width;
02621 expose.height = event->xgraphicsexpose.height;
02622 }
02623 else {
02624 PopCopyQueue(ctx);
02625 return;
02626 }
02627
02628 need_to_draw = TranslateExposeRegion(ctx, &expose);
02629 if ((event->type == GraphicsExpose) && (event->xgraphicsexpose.count == 0))
02630 PopCopyQueue(ctx);
02631
02632 if (!need_to_draw)
02633 return;
02634
02635 _XawTextPrepareToUpdate(ctx);
02636 UpdateTextInRectangle(ctx, &expose);
02637 XawTextSinkGetCursorBounds(ctx->text.sink, &cursor);
02638 if (RectanglesOverlap(&cursor, &expose)) {
02639 SinkClearToBG(ctx->text.sink, (Position) cursor.x, (Position) cursor.y,
02640 (Dimension) cursor.width, (Dimension) cursor.height);
02641 UpdateTextInRectangle(ctx, &cursor);
02642 }
02643 _XawTextExecuteUpdate(ctx);
02644 }
02645
02646
02647
02648
02649
02650 void
02651 _XawTextPrepareToUpdate(ctx)
02652 TextWidget ctx;
02653 {
02654 if (ctx->text.old_insert < 0) {
02655 InsertCursor((Widget)ctx, XawisOff);
02656 ctx->text.numranges = 0;
02657 ctx->text.showposition = FALSE;
02658 ctx->text.old_insert = ctx->text.insertPos;
02659 }
02660 }
02661
02662
02663
02664
02665
02666
02667
02668 static
02669 void FlushUpdate(ctx)
02670 TextWidget ctx;
02671 {
02672 int i, w;
02673 XawTextPosition updateFrom, updateTo;
02674 if (!XtIsRealized((Widget)ctx)) {
02675 ctx->text.numranges = 0;
02676 return;
02677 }
02678 while (ctx->text.numranges > 0) {
02679 updateFrom = ctx->text.updateFrom[0];
02680 w = 0;
02681 for (i = 1 ; i < ctx->text.numranges ; i++) {
02682 if (ctx->text.updateFrom[i] < updateFrom) {
02683 updateFrom = ctx->text.updateFrom[i];
02684 w = i;
02685 }
02686 }
02687 updateTo = ctx->text.updateTo[w];
02688 ctx->text.numranges--;
02689 ctx->text.updateFrom[w] = ctx->text.updateFrom[ctx->text.numranges];
02690 ctx->text.updateTo[w] = ctx->text.updateTo[ctx->text.numranges];
02691 for (i = ctx->text.numranges - 1 ; i >= 0 ; i--) {
02692 while (ctx->text.updateFrom[i] <= updateTo && i < ctx->text.numranges) {
02693 updateTo = ctx->text.updateTo[i];
02694 ctx->text.numranges--;
02695 ctx->text.updateFrom[i] = ctx->text.updateFrom[ctx->text.numranges];
02696 ctx->text.updateTo[i] = ctx->text.updateTo[ctx->text.numranges];
02697 }
02698 }
02699 DisplayText((Widget)ctx, updateFrom, updateTo);
02700 }
02701 }
02702
02703
02704
02705
02706
02707
02708
02709
02710
02711 void
02712 _XawTextShowPosition(ctx)
02713 TextWidget ctx;
02714 {
02715 int x, y, lines, number;
02716 Boolean no_scroll;
02717 XawTextPosition max_pos, top, first;
02718
02719 if ( (!XtIsRealized((Widget)ctx)) || (ctx->text.lt.lines <= 0) )
02720 return;
02721
02722
02723
02724
02725
02726
02727
02728
02729
02730 x = ctx->core.width;
02731 y = ctx->core.height - ctx->text.margin.bottom;
02732 if (ctx->text.hbar != NULL)
02733 y -= ctx->text.hbar->core.height + 2 * ctx->text.hbar->core.border_width;
02734
02735 max_pos = PositionForXY (ctx, x, y);
02736 lines = LineForPosition(ctx, max_pos) + 1;
02737
02738 if ( (ctx->text.insertPos >= ctx->text.lt.top) &&
02739 (ctx->text.insertPos < max_pos))
02740 return;
02741
02742 first = ctx->text.lt.top;
02743 no_scroll = FALSE;
02744
02745 if (ctx->text.insertPos < first) {
02746 top = SrcScan(ctx->text.source, ctx->text.insertPos,
02747 XawstEOL, XawsdLeft, 1, FALSE);
02748
02749
02750
02751 number = 0;
02752 while (first > top) {
02753 first = SrcScan(ctx->text.source, first,
02754 XawstEOL, XawsdLeft, 1, TRUE);
02755
02756 if ( - number > lines )
02757 break;
02758
02759 number--;
02760 }
02761
02762 if (first <= top) {
02763
02764
02765
02766
02767 first = SrcScan(ctx->text.source, first,
02768 XawstPositions, XawsdRight, 1, TRUE);
02769
02770
02771
02772 if (first <= top)
02773 number++;
02774
02775 lines = number;
02776 }
02777 else
02778 no_scroll = TRUE;
02779 }
02780 else {
02781 top = SrcScan(ctx->text.source, ctx->text.insertPos,
02782 XawstEOL, XawsdLeft, lines, FALSE);
02783
02784 if (top < max_pos)
02785 lines = LineForPosition(ctx, top);
02786 else
02787 no_scroll = TRUE;
02788 }
02789
02790 if (no_scroll) {
02791 _XawTextBuildLineTable(ctx, top, FALSE);
02792 DisplayTextWindow((Widget)ctx);
02793 }
02794 else
02795 _XawTextVScroll(ctx, lines);
02796
02797 _XawTextSetScrollBars(ctx);
02798 }
02799
02800
02801
02802
02803
02804 void
02805 _XawTextExecuteUpdate(ctx)
02806 TextWidget ctx;
02807 {
02808 if ( ctx->text.update_disabled || (ctx->text.old_insert < 0) )
02809 return;
02810
02811 if((ctx->text.old_insert != ctx->text.insertPos) || (ctx->text.showposition))
02812 _XawTextShowPosition(ctx);
02813 FlushUpdate(ctx);
02814 InsertCursor((Widget)ctx, XawisOn);
02815 ctx->text.old_insert = -1;
02816 }
02817
02818
02819 static void
02820 TextDestroy(w)
02821 Widget w;
02822 {
02823 TextWidget ctx = (TextWidget)w;
02824
02825 DestroyHScrollBar(ctx);
02826 DestroyVScrollBar(ctx);
02827
02828 XtFree((char *)ctx->text.s.selections);
02829 XtFree((char *)ctx->text.lt.info);
02830 XtFree((char *)ctx->text.search);
02831 XtFree((char *)ctx->text.updateFrom);
02832 XtFree((char *)ctx->text.updateTo);
02833 }
02834
02835
02836
02837
02838
02839
02840 static void
02841 Resize(w)
02842 Widget w;
02843 {
02844 TextWidget ctx = (TextWidget) w;
02845
02846 PositionVScrollBar(ctx);
02847 PositionHScrollBar(ctx);
02848
02849 _XawTextBuildLineTable(ctx, ctx->text.lt.top, TRUE);
02850 _XawTextSetScrollBars(ctx);
02851 }
02852
02853
02854
02855
02856
02857
02858 static Boolean
02859 SetValues(current, request, new, args, num_args)
02860 Widget current, request, new;
02861 ArgList args;
02862 Cardinal *num_args;
02863 {
02864 TextWidget oldtw = (TextWidget) current;
02865 TextWidget newtw = (TextWidget) new;
02866 Boolean redisplay = FALSE;
02867 Boolean display_caret = newtw->text.display_caret;
02868
02869
02870 newtw->text.display_caret = oldtw->text.display_caret;
02871 _XawTextPrepareToUpdate(newtw);
02872 newtw->text.display_caret = display_caret;
02873
02874 if (oldtw->text.r_margin.left != newtw->text.r_margin.left) {
02875 newtw->text.margin.left = newtw->text.r_margin.left;
02876 if (newtw->text.vbar != NULL)
02877 newtw->text.margin.left += newtw->text.vbar->core.width +
02878 newtw->text.vbar->core.border_width;
02879 redisplay = TRUE;
02880 }
02881
02882 if (oldtw->text.scroll_vert != newtw->text.scroll_vert) {
02883 if (newtw->text.scroll_vert == XawtextScrollNever)
02884 DestroyVScrollBar(newtw);
02885 else if (newtw->text.scroll_vert == XawtextScrollAlways)
02886 CreateVScrollBar(newtw);
02887 redisplay = TRUE;
02888 }
02889
02890 if (oldtw->text.r_margin.bottom != newtw->text.r_margin.bottom) {
02891 newtw->text.margin.bottom = newtw->text.r_margin.bottom;
02892 if (newtw->text.hbar != NULL)
02893 newtw->text.margin.bottom += newtw->text.hbar->core.height +
02894 newtw->text.hbar->core.border_width;
02895 redisplay = TRUE;
02896 }
02897
02898 if (oldtw->text.scroll_horiz != newtw->text.scroll_horiz) {
02899 if (newtw->text.scroll_horiz == XawtextScrollNever)
02900 DestroyHScrollBar(newtw);
02901 else if (newtw->text.scroll_horiz == XawtextScrollAlways)
02902 CreateHScrollBar(newtw);
02903 redisplay = TRUE;
02904 }
02905
02906 if ( oldtw->text.source != newtw->text.source )
02907 XawTextSetSource( (Widget) newtw, newtw->text.source, newtw->text.lt.top);
02908
02909 newtw->text.redisplay_needed = False;
02910 XtSetValues( (Widget)newtw->text.source, args, *num_args );
02911 XtSetValues( (Widget)newtw->text.sink, args, *num_args );
02912
02913 if ( oldtw->text.wrap != newtw->text.wrap ||
02914 oldtw->text.lt.top != newtw->text.lt.top ||
02915 oldtw->text.r_margin.right != newtw->text.r_margin.right ||
02916 oldtw->text.r_margin.top != newtw->text.r_margin.top ||
02917 oldtw->text.sink != newtw->text.sink ||
02918 newtw->text.redisplay_needed )
02919 {
02920 _XawTextBuildLineTable(newtw, newtw->text.lt.top, TRUE);
02921 redisplay = TRUE;
02922 }
02923
02924 if (oldtw->text.insertPos != newtw->text.insertPos) {
02925 newtw->text.showposition = TRUE;
02926 redisplay = TRUE;
02927 }
02928
02929 _XawTextExecuteUpdate(newtw);
02930 if (redisplay)
02931 _XawTextSetScrollBars(newtw);
02932
02933 return redisplay;
02934 }
02935
02936
02937 static Boolean ChangeSensitive(w)
02938 Widget w;
02939 {
02940 Arg args[1];
02941 TextWidget tw = (TextWidget) w;
02942
02943 (*(&simpleClassRec)->simple_class.change_sensitive)(w);
02944
02945 XtSetArg(args[0], XtNancestorSensitive,
02946 (tw->core.ancestor_sensitive && tw->core.sensitive));
02947 if (tw->text.vbar)
02948 XtSetValues(tw->text.vbar, args, ONE);
02949 if (tw->text.hbar)
02950 XtSetValues(tw->text.hbar, args, ONE);
02951 return False;
02952 }
02953
02954
02955
02956
02957
02958
02959
02960
02961
02962
02963 static void
02964 GetValuesHook(w, args, num_args)
02965 Widget w;
02966 ArgList args;
02967 Cardinal * num_args;
02968 {
02969 XtGetValues( ((TextWidget) w)->text.source, args, *num_args );
02970 XtGetValues( ((TextWidget) w)->text.sink, args, *num_args );
02971 }
02972
02973
02974
02975
02976
02977
02978
02979 static XawTextPosition
02980 FindGoodPosition(ctx, pos)
02981 TextWidget ctx;
02982 XawTextPosition pos;
02983 {
02984 if (pos < 0) return(0);
02985 return ( ((pos > ctx->text.lastPos) ? ctx->text.lastPos : pos) );
02986 }
02987
02988
02989
02990
02991
02992
02993
02994
02995
02996
02997
02998
02999
03000
03001 static void
03002 PushCopyQueue(ctx, h, v)
03003 TextWidget ctx;
03004 int h, v;
03005 {
03006 struct text_move * offsets = XtNew(struct text_move);
03007
03008 offsets->h = h;
03009 offsets->v = v;
03010 offsets->next = NULL;
03011
03012 if (ctx->text.copy_area_offsets == NULL)
03013 ctx->text.copy_area_offsets = offsets;
03014 else {
03015 struct text_move * end = ctx->text.copy_area_offsets;
03016 for ( ; end->next != NULL; end = end->next) {}
03017 end->next = offsets;
03018 }
03019 }
03020
03021
03022
03023
03024
03025
03026
03027 static void
03028 PopCopyQueue(ctx)
03029 TextWidget ctx;
03030 {
03031 struct text_move * offsets = ctx->text.copy_area_offsets;
03032
03033 if (offsets == NULL)
03034 (void) printf( "Xaw Text widget %s: empty copy queue\n",
03035 XtName( (Widget) ctx ) );
03036 else {
03037 ctx->text.copy_area_offsets = offsets->next;
03038 XtFree((char *) offsets);
03039 }
03040 }
03041
03042
03043
03044
03045
03046
03047
03048
03049
03050
03051
03052
03053 static Boolean
03054 TranslateExposeRegion(ctx, expose)
03055 TextWidget ctx;
03056 XRectangle * expose;
03057 {
03058 struct text_move * offsets = ctx->text.copy_area_offsets;
03059 int value;
03060 int x, y, width, height;
03061
03062
03063
03064
03065
03066 if (!offsets || !(offsets = offsets->next))
03067 return(TRUE);
03068
03069 x = expose->x;
03070 y = expose->y;
03071 width = expose->width;
03072 height = expose->height;
03073
03074 while (offsets) {
03075 x += offsets->h;
03076 y += offsets->v;
03077 offsets = offsets->next;
03078 }
03079
03080
03081
03082
03083
03084 if (y < 0) {
03085 height += y;
03086 y = 0;
03087 }
03088
03089 value = y + height - ctx->core.height;
03090 if (value > 0)
03091 height -= value;
03092
03093 if (height <= 0)
03094 return(FALSE);
03095
03096
03097
03098
03099
03100 if (x < 0) {
03101 width += x;
03102 x = 0;
03103 }
03104
03105 value = x + width - ctx->core.width;
03106 if (value > 0)
03107 width -= value;
03108
03109 if (width <= 0)
03110 return(FALSE);
03111
03112 expose->x = x;
03113 expose->y = y;
03114 expose->width = width;
03115 expose->height = height;
03116 return(TRUE);
03117 }
03118
03119
03120
03121 void
03122 #if NeedFunctionPrototypes
03123 _XawTextPosToXY(
03124 Widget w,
03125 XawTextPosition pos,
03126 Position* x,
03127 Position* y )
03128 #else
03129 _XawTextPosToXY( w, pos, x, y )
03130 Widget w;
03131 XawTextPosition pos;
03132 Position *x, *y;
03133 #endif
03134 {
03135 int line;
03136 LineAndXYForPosition( (TextWidget)w, pos, &line, x, y );
03137 }
03138
03139
03140
03141
03142
03143
03144
03145
03146
03147
03148
03149 void
03150 #if NeedFunctionPrototypes
03151 XawTextDisplay (Widget w)
03152 #else
03153 XawTextDisplay (w)
03154 Widget w;
03155 #endif
03156 {
03157 if (!XtIsRealized(w)) return;
03158
03159 _XawTextPrepareToUpdate( (TextWidget) w);
03160 DisplayTextWindow(w);
03161 _XawTextExecuteUpdate( (TextWidget) w);
03162 }
03163
03164 void
03165 #if NeedFunctionPrototypes
03166 XawTextSetSelectionArray(Widget w, XawTextSelectType *sarray)
03167 #else
03168 XawTextSetSelectionArray(w, sarray)
03169 Widget w;
03170 XawTextSelectType *sarray;
03171 #endif
03172 {
03173 ((TextWidget)w)->text.sarray = sarray;
03174 }
03175
03176 void
03177 #if NeedFunctionPrototypes
03178 XawTextGetSelectionPos(Widget w, XawTextPosition *left, XawTextPosition *right)
03179 #else
03180 XawTextGetSelectionPos(w, left, right)
03181 Widget w;
03182 XawTextPosition* left,* right;
03183 #endif
03184 {
03185 *left = ((TextWidget) w)->text.s.left;
03186 *right = ((TextWidget) w)->text.s.right;
03187 }
03188
03189
03190 void
03191 #if NeedFunctionPrototypes
03192 XawTextSetSource(Widget w, Widget source, XawTextPosition startPos)
03193 #else
03194 XawTextSetSource(w, source, startPos)
03195 Widget w, source;
03196 XawTextPosition startPos;
03197 #endif
03198 {
03199 TextWidget ctx = (TextWidget) w;
03200
03201 ctx->text.source = source;
03202 ctx->text.lt.top = startPos;
03203 ctx->text.s.left = ctx->text.s.right = 0;
03204 ctx->text.insertPos = startPos;
03205 ctx->text.lastPos = GETLASTPOS;
03206
03207 _XawTextBuildLineTable(ctx, ctx->text.lt.top, TRUE);
03208 XawTextDisplay(w);
03209 }
03210
03211
03212
03213
03214
03215
03216
03217
03218 int
03219 #if NeedFunctionPrototypes
03220 XawTextReplace(Widget w, XawTextPosition startPos, XawTextPosition endPos,
03221 XawTextBlock *text)
03222 #else
03223 XawTextReplace(w, startPos, endPos, text)
03224 Widget w;
03225 XawTextPosition startPos, endPos;
03226 XawTextBlock *text;
03227 #endif
03228 {
03229 TextWidget ctx = (TextWidget) w;
03230 int result;
03231
03232 _XawTextPrepareToUpdate(ctx);
03233 endPos = FindGoodPosition(ctx, endPos);
03234 startPos = FindGoodPosition(ctx, startPos);
03235 if ((result = _XawTextReplace(ctx, startPos, endPos, text)) == XawEditDone) {
03236 int delta = text->length - (endPos - startPos);
03237 if (ctx->text.insertPos >= (endPos + delta)) {
03238 XawTextScanDirection sd = (delta < 0) ? XawsdLeft : XawsdRight;
03239 ctx->text.insertPos = SrcScan(ctx->text.source, ctx->text.insertPos,
03240 XawstPositions, sd, abs(delta), TRUE);
03241 }
03242 }
03243
03244 _XawTextCheckResize(ctx);
03245 _XawTextExecuteUpdate(ctx);
03246 _XawTextSetScrollBars(ctx);
03247
03248 return result;
03249 }
03250
03251 XawTextPosition
03252 #if NeedFunctionPrototypes
03253 XawTextTopPosition(Widget w)
03254 #else
03255 XawTextTopPosition(w)
03256 Widget w;
03257 #endif
03258 {
03259 return( ((TextWidget) w)->text.lt.top );
03260 }
03261
03262 void
03263 #if NeedFunctionPrototypes
03264 XawTextSetInsertionPoint(Widget w, XawTextPosition position)
03265 #else
03266 XawTextSetInsertionPoint(w, position)
03267 Widget w;
03268 XawTextPosition position;
03269 #endif
03270 {
03271 TextWidget ctx = (TextWidget) w;
03272
03273 _XawTextPrepareToUpdate(ctx);
03274 ctx->text.insertPos = FindGoodPosition(ctx, position);
03275 ctx->text.showposition = TRUE;
03276
03277 _XawTextExecuteUpdate(ctx);
03278 }
03279
03280 XawTextPosition
03281 #if NeedFunctionPrototypes
03282 XawTextGetInsertionPoint(Widget w)
03283 #else
03284 XawTextGetInsertionPoint(w)
03285 Widget w;
03286 #endif
03287 {
03288 return( ((TextWidget) w)->text.insertPos);
03289 }
03290
03291
03292
03293
03294
03295 void
03296 #if NeedFunctionPrototypes
03297 XawTextUnsetSelection(Widget w)
03298 #else
03299 XawTextUnsetSelection(w)
03300 Widget w;
03301 #endif
03302 {
03303 TextWidget ctx = (TextWidget)w;
03304
03305 while (ctx->text.s.atom_count != 0) {
03306 Atom sel = ctx->text.s.selections[ctx->text.s.atom_count - 1];
03307 if ( sel != (Atom) 0 ) {
03308
03309
03310
03311 if (GetCutBufferNumber(sel) == NOT_A_CUT_BUFFER)
03312 XtDisownSelection(w, sel, ctx->text.time);
03313 LoseSelection(w, &sel);
03314
03315 }
03316 }
03317 }
03318
03319 void
03320 #if NeedFunctionPrototypes
03321 XawTextSetSelection (Widget w, XawTextPosition left, XawTextPosition right)
03322 #else
03323 XawTextSetSelection (w, left, right)
03324 Widget w;
03325 XawTextPosition left, right;
03326 #endif
03327 {
03328 TextWidget ctx = (TextWidget) w;
03329
03330 _XawTextPrepareToUpdate(ctx);
03331 _XawTextSetSelection(ctx, FindGoodPosition(ctx, left),
03332 FindGoodPosition(ctx, right), (String*)NULL, ZERO);
03333 _XawTextExecuteUpdate(ctx);
03334 }
03335
03336 void
03337 #if NeedFunctionPrototypes
03338 XawTextInvalidate(Widget w, XawTextPosition from, XawTextPosition to)
03339 #else
03340 XawTextInvalidate(w, from, to)
03341 Widget w;
03342 XawTextPosition from,to;
03343 #endif
03344 {
03345 TextWidget ctx = (TextWidget) w;
03346
03347 from = FindGoodPosition(ctx, from);
03348 to = FindGoodPosition(ctx, to);
03349 ctx->text.lastPos = GETLASTPOS;
03350 _XawTextPrepareToUpdate(ctx);
03351 _XawTextNeedsUpdating(ctx, from, to);
03352 _XawTextBuildLineTable(ctx, ctx->text.lt.top, TRUE);
03353 _XawTextExecuteUpdate(ctx);
03354 }
03355
03356
03357 void
03358 #if NeedFunctionPrototypes
03359 XawTextDisableRedisplay(Widget w)
03360 #else
03361 XawTextDisableRedisplay(w)
03362 Widget w;
03363 #endif
03364 {
03365 ((TextWidget) w)->text.update_disabled = True;
03366 _XawTextPrepareToUpdate( (TextWidget) w);
03367 }
03368
03369 void
03370 #if NeedFunctionPrototypes
03371 XawTextEnableRedisplay(Widget w)
03372 #else
03373 XawTextEnableRedisplay(w)
03374 Widget w;
03375 #endif
03376 {
03377 TextWidget ctx = (TextWidget)w;
03378 XawTextPosition lastPos;
03379
03380 if (!ctx->text.update_disabled) return;
03381
03382 ctx->text.update_disabled = False;
03383 lastPos = ctx->text.lastPos = GETLASTPOS;
03384 ctx->text.lt.top = FindGoodPosition(ctx, ctx->text.lt.top);
03385 ctx->text.insertPos = FindGoodPosition(ctx, ctx->text.insertPos);
03386 if ( (ctx->text.s.left > lastPos) || (ctx->text.s.right > lastPos) )
03387 ctx->text.s.left = ctx->text.s.right = 0;
03388
03389 _XawTextBuildLineTable(ctx, ctx->text.lt.top, TRUE);
03390 if (XtIsRealized(w))
03391 DisplayTextWindow(w);
03392 _XawTextExecuteUpdate(ctx);
03393 }
03394
03395 Widget
03396 #if NeedFunctionPrototypes
03397 XawTextGetSource(Widget w)
03398 #else
03399 XawTextGetSource(w)
03400 Widget w;
03401 #endif
03402 {
03403 return ((TextWidget)w)->text.source;
03404 }
03405
03406 void
03407 #if NeedFunctionPrototypes
03408 XawTextDisplayCaret (Widget w,
03409 #if NeedWidePrototypes
03410 int display_caret)
03411 #else
03412 Boolean display_caret)
03413 #endif
03414 #else
03415 XawTextDisplayCaret (w, display_caret)
03416 Widget w;
03417 Boolean display_caret;
03418 #endif
03419 {
03420 TextWidget ctx = (TextWidget) w;
03421
03422 if (ctx->text.display_caret == display_caret) return;
03423
03424 if (XtIsRealized(w)) {
03425 _XawTextPrepareToUpdate(ctx);
03426 ctx->text.display_caret = display_caret;
03427 _XawTextExecuteUpdate(ctx);
03428 }
03429 else
03430 ctx->text.display_caret = display_caret;
03431 }
03432
03433
03434
03435
03436
03437
03438
03439
03440
03441
03442
03443 XawTextPosition
03444 #if NeedFunctionPrototypes
03445 XawTextSearch(Widget w,
03446 #if NeedWidePrototypes
03447 int dir,
03448 #else
03449 XawTextScanDirection dir,
03450 #endif
03451 XawTextBlock *text)
03452 #else
03453 XawTextSearch(w, dir, text)
03454 Widget w;
03455 XawTextScanDirection dir;
03456 XawTextBlock * text;
03457 #endif
03458 {
03459 TextWidget ctx = (TextWidget) w;
03460
03461 return(SrcSearch(ctx->text.source, ctx->text.insertPos, dir, text));
03462 }
03463
03464 TextClassRec textClassRec = {
03465 {
03466 (WidgetClass) &simpleClassRec,
03467 "Text",
03468 sizeof(TextRec),
03469 ClassInitialize,
03470 NULL,
03471 FALSE,
03472 Initialize,
03473 NULL,
03474 Realize,
03475 _XawTextActionsTable,
03476 0,
03477 resources,
03478 XtNumber(resources),
03479 NULLQUARK,
03480 TRUE,
03481 XtExposeGraphicsExpose | XtExposeNoExpose,
03482 TRUE,
03483 FALSE,
03484 TextDestroy,
03485 Resize,
03486 ProcessExposeRegion,
03487 SetValues,
03488 NULL,
03489 XtInheritSetValuesAlmost,
03490 GetValuesHook,
03491 NULL,
03492 XtVersion,
03493 NULL,
03494 NULL,
03495 XtInheritQueryGeometry,
03496 XtInheritDisplayAccelerator,
03497 NULL
03498 },
03499 {
03500 ChangeSensitive
03501 },
03502 {
03503 0
03504 }
03505 };
03506
03507 WidgetClass textWidgetClass = (WidgetClass)&textClassRec;