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
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 #include <X11/IntrinsicP.h>
00064 #include <X11/StringDefs.h>
00065 #include <X11/Xfuncs.h>
00066 #include <X11/Xaw3d/XawInit.h>
00067 #include <X11/Xaw3d/MultiSrcP.h>
00068 #include <X11/Xaw3d/XawImP.h>
00069 #include <X11/Xmu/Misc.h>
00070 #include <X11/Xmu/CharSet.h>
00071 #include "XawI18n.h"
00072 #include <X11/Xos.h>
00073 #include <stdio.h>
00074 #include <ctype.h>
00075 #include <errno.h>
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 static int magic_value = MAGIC_VALUE;
00086
00087 #define offset(field) XtOffsetOf(MultiSrcRec, multi_src.field)
00088
00089 static XtResource resources[] = {
00090 {XtNstring, XtCString, XtRString, sizeof (XtPointer),
00091 offset(string), XtRPointer, NULL},
00092 {XtNtype, XtCType, XtRMultiType, sizeof (XawAsciiType),
00093 offset(type), XtRImmediate, (XtPointer)XawAsciiString},
00094
00095 {XtNdataCompression, XtCDataCompression, XtRBoolean, sizeof (Boolean),
00096 offset(data_compression), XtRImmediate, (XtPointer) FALSE},
00097 {XtNpieceSize, XtCPieceSize, XtRInt, sizeof (XawTextPosition),
00098 offset(piece_size), XtRImmediate, (XtPointer) BUFSIZ},
00099 {XtNcallback, XtCCallback, XtRCallback, sizeof(XtPointer),
00100 offset(callback), XtRCallback, (XtPointer)NULL},
00101 {XtNuseStringInPlace, XtCUseStringInPlace, XtRBoolean, sizeof (Boolean),
00102 offset(use_string_in_place), XtRImmediate, (XtPointer) FALSE},
00103 {XtNlength, XtCLength, XtRInt, sizeof (int),
00104 offset(multi_length), XtRInt, (XtPointer) &magic_value},
00105
00106 };
00107 #undef offset
00108
00109 static XawTextPosition Scan(), Search(), ReadText();
00110 static int ReplaceText();
00111 static MultiPiece * FindPiece(), * AllocNewPiece();
00112 static FILE * InitStringOrFile();
00113 static void FreeAllPieces(), RemovePiece(), BreakPiece(), LoadPieces();
00114 static void RemoveOldStringOrFile(), CvtStringToMultiType();
00115 static void ClassInitialize(), Initialize(), Destroy(), GetValuesHook();
00116 static String StorePiecesInString();
00117 static Boolean SetValues(), WriteToFile();
00118
00119 #define MyWStrncpy( t,s,wcnt ) (void) memmove( (t), (s), (wcnt)*sizeof(wchar_t))
00120
00121 #ifndef MyWStrncpy
00122 static void (MyWStrncpy)();
00123 #endif
00124
00125 extern char *tmpnam();
00126 #ifdef X_NOT_STDC_ENV
00127 extern int errno;
00128 #endif
00129
00130 #ifdef X_NOT_POSIX
00131 #define Off_t long
00132 #define Size_t unsigned int
00133 #else
00134 #define Off_t off_t
00135 #define Size_t size_t
00136 #endif
00137
00138 extern wchar_t* _XawTextMBToWC();
00139 extern char *_XawTextWCToMB();
00140
00141 #define superclass (&textSrcClassRec)
00142 MultiSrcClassRec multiSrcClassRec = {
00143 {
00144 (WidgetClass) superclass,
00145 "MultiSrc",
00146 sizeof(MultiSrcRec),
00147 ClassInitialize,
00148 NULL,
00149 FALSE,
00150 Initialize,
00151 NULL,
00152 NULL,
00153 NULL,
00154 0,
00155 resources,
00156 XtNumber(resources),
00157 NULLQUARK,
00158 FALSE,
00159 FALSE,
00160 FALSE,
00161 FALSE,
00162 Destroy,
00163 NULL,
00164 NULL,
00165 SetValues,
00166 NULL,
00167 NULL,
00168 GetValuesHook,
00169 NULL,
00170 XtVersion,
00171 NULL,
00172 NULL,
00173 NULL,
00174 NULL,
00175 NULL
00176 },
00177 {
00178 ReadText,
00179 ReplaceText,
00180 Scan,
00181 Search,
00182 XtInheritSetSelection,
00183 XtInheritConvertSelection
00184 },
00185 {
00186 '\0'
00187 }
00188 };
00189
00190 WidgetClass multiSrcObjectClass = (WidgetClass)&multiSrcClassRec;
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 static void
00205 ClassInitialize()
00206 {
00207 XawInitializeWidgetSet();
00208 XtAddConverter( XtRString, XtRMultiType, CvtStringToMultiType,
00209 NULL, (Cardinal) 0);
00210 }
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 static void
00222 Initialize(request, new, args, num_args)
00223 Widget request, new;
00224 ArgList args;
00225 Cardinal* num_args;
00226 {
00227 MultiSrcObject src = (MultiSrcObject) new;
00228 FILE * file;
00229
00230
00231
00232
00233
00234 src->multi_src.changes = FALSE;
00235 src->multi_src.allocated_string = FALSE;
00236
00237 file = InitStringOrFile(src, src->multi_src.type == XawAsciiFile);
00238 LoadPieces(src, file, NULL);
00239
00240 if (file != NULL) fclose(file);
00241 src->text_src.text_format = XawFmtWide;
00242
00243 }
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 static XawTextPosition
00255 ReadText(w, pos, text, length)
00256 Widget w;
00257 XawTextPosition pos;
00258 XawTextBlock* text;
00259 int length;
00260 {
00261 MultiSrcObject src = (MultiSrcObject) w;
00262 XawTextPosition count, start;
00263 MultiPiece * piece = FindPiece(src, pos, &start);
00264
00265 text->format = XawFmtWide;
00266 text->firstPos = pos;
00267 text->ptr = (char *)(piece->text + (pos - start));
00268 count = piece->used - (pos - start);
00269 text->length = (length > count) ? count : length;
00270 return(pos + text->length);
00271 }
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 static int
00283 ReplaceText( w, startPos, endPos, u_text_p)
00284 Widget w;
00285 XawTextPosition startPos, endPos;
00286 XawTextBlock* u_text_p;
00287 {
00288 MultiSrcObject src = (MultiSrcObject) w;
00289 MultiPiece *start_piece, *end_piece, *temp_piece;
00290 XawTextPosition start_first, end_first;
00291 int length, firstPos;
00292 wchar_t *wptr;
00293 Boolean local_artificial_block = False;
00294 XawTextBlock text;
00295
00296
00297
00298
00299
00300
00301 if ( u_text_p->length == 0 )
00302 text.length = 0;
00303
00304 else if ( u_text_p->format == XawFmtWide) {
00305 local_artificial_block = False;
00306 text.firstPos = u_text_p->firstPos;
00307 text.length = u_text_p->length;
00308 text.ptr = u_text_p->ptr;
00309
00310
00311 } else {
00312
00313
00314 local_artificial_block = True;
00315 text.firstPos = 0;
00316 text.length = u_text_p->length;
00317
00318 text.ptr = (char*)_XawTextMBToWC( XtDisplay(XtParent(w)),
00319 &(u_text_p->ptr[u_text_p->firstPos]), &(text.length) );
00320
00321
00322
00323
00324
00325 }
00326
00327
00328
00329
00330 if (src->text_src.edit_mode == XawtextRead)
00331 return(XawEditError);
00332
00333 start_piece = FindPiece(src, startPos, &start_first);
00334 end_piece = FindPiece(src, endPos, &end_first);
00335
00336
00337
00338
00339 if (start_piece != end_piece) {
00340 temp_piece = start_piece->next;
00341
00342
00343
00344 if ( ((start_piece->used = startPos - start_first) == 0) &&
00345 !((start_piece->next == NULL) && (start_piece->prev == NULL)) )
00346 RemovePiece(src, start_piece);
00347
00348 while (temp_piece != end_piece) {
00349 temp_piece = temp_piece->next;
00350 RemovePiece(src, temp_piece->prev);
00351 }
00352 end_piece->used -= endPos - end_first;
00353 if (end_piece->used != 0)
00354 MyWStrncpy(end_piece->text, (end_piece->text + endPos - end_first),
00355 (int) end_piece->used);
00356 }
00357 else {
00358 if ( (start_piece->used -= endPos - startPos) == 0) {
00359 if ( !((start_piece->next == NULL) && (start_piece->prev == NULL)) )
00360 RemovePiece(src, start_piece);
00361 }
00362 else {
00363 MyWStrncpy(start_piece->text + (startPos - start_first),
00364 start_piece->text + (endPos - start_first),
00365 (int) (start_piece->used - (startPos - start_first)) );
00366 if ( src->multi_src.use_string_in_place &&
00367 ((src->multi_src.length - (endPos - startPos)) <
00368 (src->multi_src.piece_size - 1)) )
00369 start_piece->text[src->multi_src.length - (endPos - startPos)] = (wchar_t)0;
00370 }
00371 }
00372
00373 src->multi_src.length += text.length -(endPos - startPos);
00374
00375
00376
00377
00378
00379
00380 if ( text.length != 0) {
00381
00382 start_piece = FindPiece(src, startPos, &start_first);
00383
00384 length = text.length;
00385 firstPos = text.firstPos;
00386
00387 while (length > 0) {
00388 wchar_t* ptr;
00389 int fill;
00390
00391 if (src->multi_src.use_string_in_place) {
00392 if (start_piece->used == (src->multi_src.piece_size - 1)) {
00393
00394
00395
00396
00397 start_piece->used = src->multi_src.length =
00398 src->multi_src.piece_size - 1;
00399
00400
00401
00402 start_piece->text[src->multi_src.length] = (wchar_t)0;
00403 return(XawEditError);
00404 }
00405 }
00406
00407
00408 if (start_piece->used == src->multi_src.piece_size) {
00409 BreakPiece(src, start_piece);
00410 start_piece = FindPiece(src, startPos, &start_first);
00411 }
00412
00413 fill = Min((int)(src->multi_src.piece_size - start_piece->used), length);
00414
00415 ptr = start_piece->text + (startPos - start_first);
00416 MyWStrncpy(ptr + fill, ptr,
00417 (int) start_piece->used - (startPos - start_first));
00418 wptr =(wchar_t *)text.ptr;
00419 (void)wcsncpy(ptr, wptr + firstPos, fill);
00420
00421 startPos += fill;
00422 firstPos += fill;
00423 start_piece->used += fill;
00424 length -= fill;
00425 }
00426 }
00427
00428 if ( local_artificial_block == True )
00429
00430
00431
00432
00433 XFree( text.ptr );
00434
00435 if (src->multi_src.use_string_in_place)
00436 start_piece->text[start_piece->used] = (wchar_t)0;
00437
00438 src->multi_src.changes = TRUE;
00439
00440 XtCallCallbacks(w, XtNcallback, NULL);
00441
00442 return(XawEditDone);
00443 }
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462 static
00463 XawTextPosition
00464 Scan( w, position, type, dir, count, include )
00465 Widget w;
00466 XawTextPosition position;
00467 XawTextScanType type;
00468 XawTextScanDirection dir;
00469 int count;
00470 Boolean include;
00471 {
00472 MultiSrcObject src = (MultiSrcObject) w;
00473 int inc;
00474 MultiPiece * piece;
00475 XawTextPosition first, first_eol_position = 0;
00476 wchar_t * ptr;
00477
00478 if (type == XawstAll) {
00479 if (dir == XawsdRight)
00480 return(src->multi_src.length);
00481 return(0);
00482 }
00483
00484
00485
00486
00487 if (position > src->multi_src.length)
00488 position = src->multi_src.length;
00489
00490
00491 if ( dir == XawsdRight ) {
00492 if (position == src->multi_src.length)
00493 return(src->multi_src.length);
00494 inc = 1;
00495 }
00496 else {
00497 if (position == 0)
00498 return(0);
00499 inc = -1;
00500 position--;
00501 }
00502
00503 piece = FindPiece(src, position, &first);
00504
00505 if ( piece->used == 0 ) return(0);
00506
00507 ptr = (position - first) + piece->text;
00508
00509 switch (type) {
00510 case XawstEOL:
00511 case XawstParagraph:
00512 case XawstWhiteSpace:
00513 for ( ; count > 0 ; count-- ) {
00514 Boolean non_space = FALSE, first_eol = TRUE;
00515
00516 while (TRUE) {
00517 wchar_t c = *ptr;
00518
00519 ptr += inc;
00520 position += inc;
00521
00522 if (type == XawstWhiteSpace) {
00523 if (iswspace(c)) {
00524 if (non_space)
00525 break;
00526 }
00527 else
00528 non_space = TRUE;
00529 }
00530 else if (type == XawstEOL) {
00531 if (c == _Xaw_atowc(XawLF)) break;
00532 }
00533 else {
00534 if (first_eol) {
00535 if (c == _Xaw_atowc(XawLF)) {
00536 first_eol_position = position;
00537 first_eol = FALSE;
00538 }
00539 }
00540 else
00541 if ( c == _Xaw_atowc(XawLF))
00542 break;
00543 else if ( !iswspace(c) )
00544 first_eol = TRUE;
00545 }
00546
00547
00548 if ( ptr < piece->text ) {
00549 piece = piece->prev;
00550 if (piece == NULL)
00551 return(0);
00552 ptr = piece->text + piece->used - 1;
00553 }
00554 else if ( ptr >= (piece->text + piece->used) ) {
00555 piece = piece->next;
00556 if (piece == NULL)
00557 return(src->multi_src.length);
00558 ptr = piece->text;
00559 }
00560 }
00561 }
00562 if (!include) {
00563 if ( type == XawstParagraph)
00564 position = first_eol_position;
00565 position -= inc;
00566 }
00567 break;
00568 case XawstPositions:
00569 position += count * inc;
00570 break;
00571 case XawstAll:
00572 default:
00573 break;
00574 }
00575
00576 if ( dir == XawsdLeft )
00577 position++;
00578
00579 if (position >= src->multi_src.length)
00580 return(src->multi_src.length);
00581 if (position < 0)
00582 return(0);
00583
00584 return(position);
00585 }
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596 static XawTextPosition
00597 Search(w, position, dir, text )
00598 Widget w;
00599 XawTextPosition position;
00600 XawTextScanDirection dir;
00601 XawTextBlock* text;
00602 {
00603 MultiSrcObject src = (MultiSrcObject) w;
00604 int inc, count = 0;
00605 wchar_t * ptr;
00606 wchar_t* wtarget;
00607 int wtarget_len;
00608 Display * d = XtDisplay(XtParent(w));
00609 MultiPiece * piece;
00610 wchar_t* buf;
00611 XawTextPosition first;
00612
00613
00614
00615
00616 if ( dir == XawsdRight )
00617 inc = 1;
00618 else {
00619 inc = -1;
00620 if (position == 0)
00621 return(XawTextSearchError);
00622 position--;
00623 }
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633 wtarget_len = text->length;
00634
00635 if ( text->format == XawFmtWide )
00636 wtarget = &( ((wchar_t*)text->ptr) [text->firstPos] );
00637 else
00638 {
00639
00640 wtarget = _XawTextMBToWC( d, &text->ptr[ text->firstPos ], &wtarget_len );
00641 }
00642
00643
00644
00645
00646
00647
00648
00649
00650 buf = (wchar_t *)XtMalloc((unsigned)sizeof(wchar_t) * wtarget_len );
00651 (void)wcsncpy(buf, wtarget, wtarget_len );
00652 piece = FindPiece(src, position, &first);
00653 ptr = (position - first) + piece->text;
00654
00655
00656 while (TRUE) {
00657 if (*ptr == ((dir == XawsdRight) ? *(buf + count)
00658 : *(buf + wtarget_len - count - 1)) ) {
00659 if (count == (text->length - 1))
00660 break;
00661 else
00662 count++;
00663 }
00664 else {
00665 if (count != 0) {
00666 position -=inc * count;
00667 ptr -= inc * count;
00668 }
00669 count = 0;
00670 }
00671
00672 ptr += inc;
00673 position += inc;
00674
00675 while ( ptr < piece->text ) {
00676 piece = piece->prev;
00677 if (piece == NULL) {
00678 XtFree((char *)buf);
00679 return(XawTextSearchError);
00680 }
00681 ptr = piece->text + piece->used - 1;
00682 }
00683
00684 while ( ptr >= (piece->text + piece->used) ) {
00685 piece = piece->next;
00686 if (piece == NULL) {
00687 XtFree((char *)buf);
00688 return(XawTextSearchError);
00689 }
00690 ptr = piece->text;
00691 }
00692 }
00693
00694 XtFree( (char *) buf );
00695 if (dir == XawsdLeft)
00696 return( position );
00697 return( position - ( wtarget_len - 1 ) );
00698 }
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709 static Boolean
00710 SetValues(current, request, new, args, num_args)
00711 Widget current, request, new;
00712 ArgList args;
00713 Cardinal* num_args;
00714 {
00715 MultiSrcObject src = (MultiSrcObject) new;
00716 MultiSrcObject old_src = (MultiSrcObject) current;
00717 XtAppContext app_con = XtWidgetToApplicationContext(new);
00718 Boolean total_reset = FALSE, string_set = FALSE;
00719 FILE * file;
00720 int i;
00721
00722 if ( old_src->multi_src.use_string_in_place !=
00723 src->multi_src.use_string_in_place ) {
00724 XtAppWarning( app_con,
00725 "MultiSrc: The XtNuseStringInPlace resources may not be changed.");
00726 src->multi_src.use_string_in_place =
00727 old_src->multi_src.use_string_in_place;
00728 }
00729
00730 for (i = 0; i < *num_args ; i++ )
00731 if (streq(args[i].name, XtNstring)) {
00732 string_set = TRUE;
00733 break;
00734 }
00735
00736 if ( string_set || (old_src->multi_src.type != src->multi_src.type) ) {
00737 RemoveOldStringOrFile(old_src, string_set);
00738 file = InitStringOrFile(src, string_set);
00739
00740
00741
00742
00743
00744 LoadPieces(src, file, NULL);
00745 if (file != NULL) fclose(file);
00746 XawTextSetSource( XtParent(new), new, 0);
00747
00748 total_reset = TRUE;
00749 }
00750
00751 if ( old_src->multi_src.multi_length != src->multi_src.multi_length )
00752 src->multi_src.piece_size = src->multi_src.multi_length;
00753
00754 if ( !total_reset && (old_src->multi_src.piece_size
00755 != src->multi_src.piece_size) ) {
00756 String mb_string = StorePiecesInString( old_src );
00757
00758 if ( mb_string != 0 ) {
00759 FreeAllPieces( old_src );
00760 LoadPieces( src, NULL, mb_string );
00761 XtFree( mb_string );
00762 } else {
00763
00764 XtAppWarningMsg( app_con,
00765 "convertError", "multiSource", "XawError",
00766 XtName( XtParent( (Widget) old_src ) ), NULL, NULL );
00767 XtAppWarningMsg( app_con,
00768 "convertError", "multiSource", "XawError",
00769 "Non-character code(s) in buffer.", NULL, NULL );
00770 }
00771 }
00772
00773 return(FALSE);
00774 }
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785 static void
00786 GetValuesHook(w, args, num_args)
00787 Widget w;
00788 ArgList args;
00789 Cardinal* num_args;
00790 {
00791 MultiSrcObject src = (MultiSrcObject) w;
00792 int i;
00793
00794 if (src->multi_src.type == XawAsciiString) {
00795 for (i = 0; i < *num_args ; i++ )
00796 if (streq(args[i].name, XtNstring)) {
00797 if (src->multi_src.use_string_in_place) {
00798 *((char **) args[i].value) = (char *)
00799 src->multi_src.first_piece->text;
00800 }
00801 else {
00802 if (_XawMultiSave(w))
00803 *((char **) args[i].value) = src->multi_src.string;
00804 }
00805 break;
00806 }
00807 }
00808 }
00809
00810
00811
00812
00813
00814
00815
00816 static void
00817 Destroy (w)
00818 Widget w;
00819 {
00820 RemoveOldStringOrFile((MultiSrcObject) w, True);
00821 }
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838 void
00839 #if NeedFunctionPrototypes
00840 _XawMultiSourceFreeString(
00841 Widget w)
00842 #else
00843 _XawMultiSourceFreeString(w)
00844 Widget w;
00845 #endif
00846 {
00847 MultiSrcObject src = (MultiSrcObject) w;
00848
00849
00850
00851 if ( src->multi_src.allocated_string ) {
00852 XtFree(src->multi_src.string);
00853 src->multi_src.allocated_string = FALSE;
00854 src->multi_src.string = NULL;
00855 }
00856 }
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866 Boolean
00867 #if NeedFunctionPrototypes
00868 _XawMultiSave(
00869 Widget w)
00870 #else
00871 _XawMultiSave(w)
00872 Widget w;
00873 #endif
00874 {
00875 MultiSrcObject src = (MultiSrcObject) w;
00876 XtAppContext app_con = XtWidgetToApplicationContext(w);
00877 char * mb_string;
00878
00879
00880
00881
00882
00883
00884 if (src->multi_src.use_string_in_place)
00885 return(TRUE);
00886
00887 if (src->multi_src.type == XawAsciiFile) {
00888
00889 if (!src->multi_src.changes)
00890 return(TRUE);
00891
00892 mb_string = StorePiecesInString( src );
00893
00894 if ( mb_string != 0 ) {
00895 if ( WriteToFile( mb_string, src->multi_src.string ) == FALSE ) {
00896 XtFree( mb_string );
00897 return( FALSE );
00898 }
00899 XtFree( mb_string );
00900 src->multi_src.changes = FALSE;
00901 return( TRUE );
00902 } else {
00903
00904 XtAppWarningMsg( app_con,
00905 "convertError", "multiSource", "XawError",
00906 "Due to illegal characters, file not saved.", NULL, NULL);
00907 return( FALSE );
00908 }
00909 }
00910 else {
00911
00912
00913
00914
00915 mb_string = StorePiecesInString( src );
00916
00917 if ( mb_string == 0 ) {
00918
00919 XtAppWarningMsg( app_con,
00920 "convertError", "multiSource", "XawError",
00921 XtName( XtParent( (Widget) src ) ), NULL, NULL);
00922 return( FALSE );
00923 }
00924
00925
00926 if (src->multi_src.allocated_string == TRUE)
00927 XtFree(src->multi_src.string);
00928 else
00929 src->multi_src.allocated_string = TRUE;
00930
00931 src->multi_src.string = mb_string;
00932 }
00933 src->multi_src.changes = FALSE;
00934 return(TRUE);
00935 }
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946 Boolean
00947 #if NeedFunctionPrototypes
00948 _XawMultiSaveAsFile(
00949 Widget w,
00950 _Xconst char* name)
00951 #else
00952 _XawMultiSaveAsFile(w, name)
00953 Widget w;
00954 String name;
00955 #endif
00956 {
00957 MultiSrcObject src = (MultiSrcObject) w;
00958 String mb_string;
00959 Boolean ret;
00960
00961 mb_string = StorePiecesInString( src );
00962
00963 if ( mb_string != 0 ) {
00964 ret = WriteToFile( mb_string, name );
00965 XtFree( mb_string );
00966 return( ret );
00967 }
00968
00969
00970 XtAppWarningMsg( XtWidgetToApplicationContext(w),
00971 "convertError", "multiSource", "XawError",
00972 XtName( XtParent( (Widget) src ) ), NULL, NULL);
00973 return( False );
00974 }
00975
00976
00977
00978
00979
00980
00981
00982 static void
00983 RemoveOldStringOrFile(src, checkString)
00984 MultiSrcObject src;
00985 Boolean checkString;
00986 {
00987 FreeAllPieces(src);
00988
00989 if (checkString && src->multi_src.allocated_string) {
00990 XtFree(src->multi_src.string);
00991 src->multi_src.allocated_string = False;
00992 src->multi_src.string = NULL;
00993 }
00994 }
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004 static Boolean
01005 WriteToFile(string, name)
01006 String string, name;
01007 {
01008 int fd;
01009
01010 if ( ((fd = creat(name, 0666)) == -1 ) ||
01011 (write(fd, string, sizeof(unsigned char) * strlen(string)) == -1) )
01012 return(FALSE);
01013
01014 if ( close(fd) == -1 )
01015 return(FALSE);
01016
01017 return(TRUE);
01018 }
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028 static String
01029 StorePiecesInString(src)
01030 MultiSrcObject src;
01031 {
01032 wchar_t* wc_string;
01033 char *mb_string;
01034 int char_count = src->multi_src.length;
01035 XawTextPosition first;
01036 MultiPiece * piece;
01037
01038
01039
01040 wc_string = (wchar_t*) XtMalloc((unsigned)(char_count + 1) * sizeof(wchar_t));
01041
01042 for (first = 0, piece = src->multi_src.first_piece ; piece != NULL;
01043 first += piece->used, piece = piece->next)
01044 (void) wcsncpy( wc_string + first, piece->text, piece->used );
01045
01046 wc_string[ char_count ] = (wchar_t)0;
01047
01048
01049
01050
01051 if ( src->multi_src.data_compression ) {
01052 FreeAllPieces( src );
01053 LoadPieces( src, NULL, (char *)wc_string );
01054 }
01055
01056
01057
01058 mb_string = _XawTextWCToMB( XtDisplayOfObject( (Widget)src ),
01059 wc_string, &char_count );
01060
01061
01062 XtFree( (char*) wc_string );
01063 return( mb_string );
01064 }
01065
01066
01067
01068
01069
01070
01071
01072
01073 static FILE *
01074 InitStringOrFile(src, newString)
01075 MultiSrcObject src;
01076 Boolean newString;
01077 {
01078 char * open_mode = NULL;
01079 FILE * file;
01080 char fileName[TMPSIZ];
01081 Display *d = XtDisplayOfObject((Widget)src);
01082
01083 if (src->multi_src.type == XawAsciiString) {
01084
01085 if (src->multi_src.string == NULL)
01086 src->multi_src.length = 0;
01087
01088 else if (! src->multi_src.use_string_in_place) {
01089 int length;
01090 String temp = XtNewString(src->multi_src.string);
01091 if ( src->multi_src.allocated_string )
01092 XtFree( src->multi_src.string );
01093 src->multi_src.allocated_string = True;
01094 src->multi_src.string = temp;
01095
01096 length = strlen(src->multi_src.string);
01097
01098
01099 (void) _XawTextMBToWC(d, src->multi_src.string, &length);
01100 src->multi_src.length = (XawTextPosition) length;
01101 } else {
01102 src->multi_src.length = strlen(src->multi_src.string);
01103
01104 if (src->multi_src.length > src->multi_src.multi_length)
01105 src->multi_src.multi_length = src->multi_src.length;
01106
01107 if (src->multi_src.multi_length == MAGIC_VALUE)
01108 src->multi_src.piece_size = src->multi_src.length;
01109 else
01110 src->multi_src.piece_size = src->multi_src.multi_length + 1;
01111 }
01112
01113
01114 return(NULL);
01115 }
01116
01117
01118
01119
01120
01121 src->multi_src.is_tempfile = FALSE;
01122
01123 switch (src->text_src.edit_mode) {
01124 case XawtextRead:
01125 if (src->multi_src.string == NULL)
01126 XtErrorMsg("NoFile", "multiSourceCreate", "XawError",
01127 "Creating a read only disk widget and no file specified.",
01128 NULL, 0);
01129 open_mode = "r";
01130 break;
01131 case XawtextAppend:
01132 case XawtextEdit:
01133 if (src->multi_src.string == NULL) {
01134
01135 if ( src->multi_src.allocated_string )
01136 XtFree( src->multi_src.string );
01137 src->multi_src.allocated_string = False;
01138 src->multi_src.string = fileName;
01139
01140 (void) tmpnam(src->multi_src.string);
01141 src->multi_src.is_tempfile = TRUE;
01142 open_mode = "w";
01143 } else
01144 open_mode = "r+";
01145 break;
01146 default:
01147 XtErrorMsg("badMode", "multiSourceCreate", "XawError",
01148 "Bad editMode for multi source; must be Read, Append or Edit.",
01149 NULL, NULL);
01150 }
01151
01152
01153
01154
01155
01156 if (newString || src->multi_src.is_tempfile) {
01157 if ( src->multi_src.allocated_string )
01158 src->multi_src.string = XtNewString(src->multi_src.string);
01159 src->multi_src.allocated_string = TRUE;
01160 }
01161
01162 if (!src->multi_src.is_tempfile) {
01163 if ((file = fopen(src->multi_src.string, open_mode)) != 0) {
01164 (void) fseek(file, (Off_t)0, 2);
01165 src->multi_src.length = ftell (file);
01166 return file;
01167 } else {
01168 String params[2];
01169 Cardinal num_params = 2;
01170
01171 params[0] = src->multi_src.string;
01172 params[1] = strerror(errno);
01173 XtAppWarningMsg(XtWidgetToApplicationContext((Widget)src),
01174 "openError", "multiSourceCreate", "XawWarning",
01175 "Cannot open file %s; %s", params, &num_params);
01176 }
01177 }
01178 src->multi_src.length = 0;
01179 return((FILE *)NULL);
01180 #undef StrLen
01181 }
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191 static void
01192 LoadPieces(src, file, string)
01193 MultiSrcObject src;
01194 FILE* file;
01195 char* string;
01196 {
01197 Display *d = XtDisplayOfObject((Widget)src);
01198 wchar_t* local_str, *ptr;
01199 MultiPiece* piece = NULL;
01200 XawTextPosition left;
01201 int bytes = sizeof(wchar_t);
01202 char* temp_mb_holder = NULL;
01203
01204
01205
01206
01207
01208
01209 int local_length = src->multi_src.length;
01210
01211 if (string != NULL) {
01212
01213
01214
01215
01216
01217 local_str = _XawTextMBToWC(d, (char *)string, &local_length);
01218 src->multi_src.length = (XawTextPosition) local_length;
01219 } else if (src->multi_src.type != XawAsciiFile) {
01220
01221
01222
01223
01224 local_length = src->multi_src.string ?
01225 strlen( src->multi_src.string ) : 0;
01226 local_str = _XawTextMBToWC( d, (char*)src->multi_src.string, &local_length );
01227 } else {
01228 if (src->multi_src.length != 0) {
01229 temp_mb_holder =
01230 XtMalloc((unsigned)(src->multi_src.length + 1) * sizeof(unsigned char));
01231 fseek(file, (Off_t)0, 0);
01232 src->multi_src.length = fread (temp_mb_holder,
01233 (Size_t)sizeof(unsigned char),
01234 (Size_t)src->multi_src.length, file);
01235 if (src->multi_src.length <= 0)
01236 XtAppErrorMsg( XtWidgetToApplicationContext ((Widget) src),
01237 "readError", "multiSource", "XawError",
01238 "fread returned error.", NULL, NULL);
01239 local_length = src->multi_src.length;
01240 local_str = _XawTextMBToWC(d, temp_mb_holder, &local_length);
01241 src->multi_src.length = local_length;
01242
01243 if ( local_str == 0 ) {
01244 String params[2];
01245 Cardinal num_params;
01246 static char err_text[] =
01247 "<<< FILE CONTENTS NOT REPRESENTABLE IN THIS LOCALE >>>";
01248
01249 params[0] = XtName(XtParent((Widget)src));
01250 params[1] = src->multi_src.string;
01251 num_params = 2;
01252
01253 XtAppWarningMsg( XtWidgetToApplicationContext((Widget)src),
01254 "readLocaleError", "multiSource", "XawError",
01255 "%s: The file `%s' contains characters not representable in this locale.",
01256 params, &num_params);
01257 src->multi_src.length = sizeof err_text;
01258 local_length = src->multi_src.length;
01259 local_str = _XawTextMBToWC(d, err_text, &local_length);
01260 src->multi_src.length = local_length;
01261 }
01262 } else {
01263
01264
01265 local_str = (wchar_t*)temp_mb_holder;
01266 }
01267 }
01268
01269 if (src->multi_src.use_string_in_place) {
01270 piece = AllocNewPiece(src, piece);
01271 piece->used = Min(src->multi_src.length, src->multi_src.piece_size);
01272 piece->text = (wchar_t*)src->multi_src.string;
01273 return;
01274 }
01275
01276 ptr = local_str;
01277 left = local_length;
01278
01279 do {
01280 piece = AllocNewPiece(src, piece);
01281
01282 piece->text = (wchar_t*)XtMalloc(src->multi_src.piece_size * bytes);
01283 piece->used = Min(left, src->multi_src.piece_size);
01284 if (piece->used != 0)
01285 (void) wcsncpy(piece->text, ptr, piece->used);
01286
01287 left -= piece->used;
01288 ptr += piece->used;
01289 } while (left > 0);
01290
01291 if ( temp_mb_holder )
01292 XtFree( (char*) temp_mb_holder );
01293 }
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303 static MultiPiece *
01304 AllocNewPiece(src, prev)
01305 MultiSrcObject src;
01306 MultiPiece * prev;
01307 {
01308 MultiPiece * piece = XtNew(MultiPiece);
01309
01310 if (prev == NULL) {
01311 src->multi_src.first_piece = piece;
01312 piece->next = NULL;
01313 }
01314 else {
01315 if (prev->next != NULL)
01316 (prev->next)->prev = piece;
01317 piece->next = prev->next;
01318 prev->next = piece;
01319 }
01320
01321 piece->prev = prev;
01322
01323 return(piece);
01324 }
01325
01326
01327
01328
01329
01330
01331
01332 static void
01333 FreeAllPieces(src)
01334 MultiSrcObject src;
01335 {
01336 MultiPiece * next, * first = src->multi_src.first_piece;
01337
01338 if (first->prev != NULL)
01339 printf("Xaw MultiSrc Object: possible memory leak in FreeAllPieces().\n");
01340
01341 for ( ; first != NULL ; first = next ) {
01342 next = first->next;
01343 RemovePiece(src, first);
01344 }
01345 }
01346
01347
01348
01349
01350
01351
01352
01353
01354 static void
01355 RemovePiece(src, piece)
01356 MultiSrcObject src;
01357 MultiPiece* piece;
01358 {
01359 if (piece->prev == NULL)
01360 src->multi_src.first_piece = piece->next;
01361 else
01362 (piece->prev)->next = piece->next;
01363
01364 if (piece->next != NULL)
01365 (piece->next)->prev = piece->prev;
01366
01367 if (!src->multi_src.use_string_in_place)
01368 XtFree((char *)piece->text);
01369
01370 XtFree((char *)piece);
01371 }
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381 static MultiPiece *
01382 FindPiece(src, position, first)
01383 MultiSrcObject src;
01384 XawTextPosition position, *first;
01385 {
01386 MultiPiece * old_piece = NULL, * piece = src->multi_src.first_piece;
01387 XawTextPosition temp;
01388
01389 for ( temp = 0 ; piece != NULL ; temp += piece->used, piece = piece->next ) {
01390 *first = temp;
01391 old_piece = piece;
01392
01393 if ((temp + piece->used) > position)
01394 return(piece);
01395 }
01396 return(old_piece);
01397 }
01398
01399
01400
01401
01402
01403
01404
01405
01406 #define HALF_PIECE (src->multi_src.piece_size/2)
01407
01408 static void
01409 BreakPiece(src, piece)
01410 MultiSrcObject src;
01411 MultiPiece* piece;
01412 {
01413 MultiPiece * new = AllocNewPiece(src, piece);
01414
01415 new->text = (wchar_t*)XtMalloc(src->multi_src.piece_size * sizeof(wchar_t));
01416 (void) wcsncpy(new->text, piece->text + HALF_PIECE,
01417 src->multi_src.piece_size - HALF_PIECE);
01418 piece->used = HALF_PIECE;
01419 new->used = src->multi_src.piece_size - HALF_PIECE;
01420 }
01421
01422
01423
01424
01425 static void
01426 CvtStringToMultiType(args, num_args, fromVal, toVal)
01427 XrmValuePtr args;
01428 Cardinal* num_args;
01429 XrmValuePtr fromVal;
01430 XrmValuePtr toVal;
01431 {
01432 static XawAsciiType type;
01433 static XrmQuark XtQEstring = NULLQUARK;
01434 static XrmQuark XtQEfile;
01435 XrmQuark q;
01436 char lowerName[40];
01437
01438 if (XtQEstring == NULLQUARK) {
01439 XtQEstring = XrmPermStringToQuark(XtEstring);
01440 XtQEfile = XrmPermStringToQuark(XtEfile);
01441 }
01442
01443 if (strlen ((char*) fromVal->addr) < sizeof lowerName) {
01444 XmuCopyISOLatin1Lowered(lowerName, (char *) fromVal->addr);
01445 q = XrmStringToQuark(lowerName);
01446
01447 if (q == XtQEstring) type = XawAsciiString;
01448 else if (q == XtQEfile) type = XawAsciiFile;
01449 else {
01450 toVal->size = 0;
01451 toVal->addr = NULL;
01452 return;
01453 }
01454 toVal->size = sizeof type;
01455 toVal->addr = (XPointer) &type;
01456 return;
01457 }
01458 toVal->size = 0;
01459 toVal->addr = NULL;
01460 }