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