1 #if ( !defined(lint) && !defined(SABER) )
2 static char Xrcsid
[] = "$XConsortium: AsciiSrc.c,v 1.28 90/01/10 14:25:21 kit Exp $";
6 * Copyright 1989 Massachusetts Institute of Technology
8 * Permission to use, copy, modify, distribute, and sell this software and its
9 * documentation for any purpose is hereby granted without fee, provided that
10 * the above copyright notice appear in all copies and that both that
11 * copyright notice and this permission notice appear in supporting
12 * documentation, and that the name of M.I.T. not be used in advertising or
13 * publicity pertaining to distribution of the software without specific,
14 * written prior permission. M.I.T. makes no representations about the
15 * suitability of this software for any purpose. It is provided "as is"
16 * without express or implied warranty.
18 * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
20 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
22 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
23 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 * Author: Chris Peterson, MIT X Consortium.
27 * Much code taken from X11R3 String and Disk Sources.
31 * AsciiSrc.c - AsciiSrc object. (For use with the text widget).
37 #include <X11/IntrinsicP.h>
38 #include <X11/StringDefs.h>
40 #include <./Xaw3_1XawInit.h>
41 #include <./Xaw3_1AsciiSrcP.h>
42 #include <X11/Xmu/Misc.h>
43 #include <X11/Xmu/CharSet.h>
46 #include <./Xaw3_1AsciiText.h> /* for Widget Classes. */
49 #include <./Xaw3_1AsciiText.h> /* for Widget Classes. */
51 /****************************************************************
53 * Full class record constant
55 ****************************************************************/
59 static int magic_value
= MAGIC_VALUE
;
61 #define offset(field) XtOffset(AsciiSrcObject, ascii_src.field)
63 static XtResource resources
[] = {
64 {XtNstring
, XtCString
, XtRString
, sizeof (char *),
65 offset(string
), XtRString
, NULL
},
66 {XtNtype
, XtCType
, XtRAsciiType
, sizeof (XawAsciiType
),
67 offset(type
), XtRImmediate
, (XtPointer
)XawAsciiString
},
68 {XtNdataCompression
, XtCDataCompression
, XtRBoolean
, sizeof (Boolean
),
69 offset(data_compression
), XtRImmediate
, (XtPointer
) TRUE
},
70 {XtNpieceSize
, XtCPieceSize
, XtRInt
, sizeof (XawTextPosition
),
71 offset(piece_size
), XtRImmediate
, (XtPointer
) BUFSIZ
},
72 {XtNcallback
, XtCCallback
, XtRCallback
, sizeof(XtPointer
),
73 offset(callback
), XtRCallback
, (XtPointer
)NULL
},
74 {XtNuseStringInPlace
, XtCUseStringInPlace
, XtRBoolean
, sizeof (Boolean
),
75 offset(use_string_in_place
), XtRImmediate
, (XtPointer
) FALSE
},
76 {XtNlength
, XtCLength
, XtRInt
, sizeof (int),
77 offset(ascii_length
), XtRInt
, (XtPointer
) &magic_value
},
80 {XtNfile
, XtCFile
, XtRString
, sizeof (String
),
81 offset(filename
), XtRString
, NULL
},
82 #endif /* ASCII_DISK */
85 static XawTextPosition
Scan(), Search(), ReadText();
86 static int ReplaceText();
87 static Piece
* FindPiece(), * AllocNewPiece();
88 static FILE * InitStringOrFile();
89 static void FreeAllPieces(), RemovePiece(), BreakPiece(), LoadPieces();
90 static void RemoveOldStringOrFile(), CvtStringToAsciiType();
91 static void ClassInitialize(), Initialize(), Destroy(), GetValuesHook();
92 static String
MyStrncpy(), StorePiecesInString();
93 static Boolean
SetValues(), WriteToFile();
94 extern char *tmpnam();
98 extern int errno
, sys_nerr
;
99 extern char* sys_errlist
[];
101 #define superclass (&textSrcClassRec)
102 AsciiSrcClassRec asciiSrcClassRec
= {
104 /* core_class fields */
105 /* superclass */ (WidgetClass
) superclass
,
106 /* class_name */ "AsciiSrc",
107 /* widget_size */ sizeof(AsciiSrcRec
),
108 /* class_initialize */ ClassInitialize
,
109 /* class_part_initialize */ NULL
,
110 /* class_inited */ FALSE
,
111 /* initialize */ Initialize
,
112 /* initialize_hook */ NULL
,
116 /* resources */ resources
,
117 /* num_resources */ XtNumber(resources
),
118 /* xrm_class */ NULLQUARK
,
119 /* compress_motion */ FALSE
,
120 /* compress_exposure */ FALSE
,
121 /* compress_enterleave */ FALSE
,
122 /* visible_interest */ FALSE
,
123 /* destroy */ Destroy
,
126 /* set_values */ SetValues
,
127 /* set_values_hook */ NULL
,
128 /* set_values_almost */ NULL
,
129 /* get_values_hook */ GetValuesHook
,
130 /* accept_focus */ NULL
,
131 /* version */ XtVersion
,
132 /* callback_private */ NULL
,
134 /* query_geometry */ NULL
,
135 /* display_accelerator */ NULL
,
138 /* textSrc_class fields */
141 /* Replace */ ReplaceText
,
144 /* SetSelection */ XtInheritSetSelection
,
145 /* ConvertSelection */ XtInheritConvertSelection
147 /* asciiSrc_class fields */
149 /* Keep the compiler happy */ NULL
153 WidgetClass asciiSrcObjectClass
= (WidgetClass
)&asciiSrcClassRec
;
155 /************************************************************
157 * Semi-Public Interfaces.
159 ************************************************************/
161 /* Function Name: ClassInitialize
162 * Description: Class Initialize routine, called only once.
170 XawInitializeWidgetSet();
171 XtAddConverter( XtRString
, XtRAsciiType
, CvtStringToAsciiType
,
175 /* Function Name: Initialize
176 * Description: Initializes the simple menu widget
177 * Arguments: request - the widget requested by the argument list.
178 * new - the new widget with both resource and non
185 Initialize(request
, new)
188 AsciiSrcObject src
= (AsciiSrcObject
) new;
192 * Set correct flags (override resources) depending upon widget class.
196 if (XtIsSubclass(XtParent(new), asciiDiskWidgetClass
)) {
197 src
->ascii_src
.type
= XawAsciiFile
;
198 src
->ascii_src
.string
= src
->ascii_src
.filename
;
203 if (XtIsSubclass(XtParent(new), asciiStringWidgetClass
)) {
204 src
->ascii_src
.use_string_in_place
= TRUE
;
205 src
->ascii_src
.type
= XawAsciiString
;
209 src
->ascii_src
.changes
= FALSE
;
210 src
->ascii_src
.allocated_string
= FALSE
;
212 file
= InitStringOrFile(src
);
213 LoadPieces(src
, file
, NULL
);
215 if (file
!= NULL
) fclose(file
);
217 if ( src
->ascii_src
.type
== XawAsciiString
)
218 src
->ascii_src
.string
= NULL
;
221 /* Function Name: ReadText
222 * Description: This function reads the source.
223 * Arguments: w - the AsciiSource widget.
224 * pos - position of the text to retreive.
225 * RETURNED text - text block that will contain returned text.
226 * length - maximum number of characters to read.
227 * Returns: The number of characters read into the buffer.
230 static XawTextPosition
231 ReadText(w
, pos
, text
, length
)
237 AsciiSrcObject src
= (AsciiSrcObject
) w
;
238 XawTextPosition count
, start
;
239 Piece
* piece
= FindPiece(src
, pos
, &start
);
241 text
->firstPos
= pos
;
242 text
->ptr
= piece
->text
+ (pos
- start
);
243 count
= piece
->used
- (pos
- start
);
244 text
->length
= (length
> count
) ? count
: length
;
245 return(pos
+ text
->length
);
248 /* Function Name: ReplaceText.
249 * Description: Replaces a block of text with new text.
250 * Arguments: w - the AsciiSource widget.
251 * startPos, endPos - ends of text that will be removed.
252 * text - new text to be inserted into buffer at startPos.
253 * Returns: XawEditError or XawEditDone.
258 ReplaceText (w
, startPos
, endPos
, text
)
260 XawTextPosition startPos
, endPos
;
263 AsciiSrcObject src
= (AsciiSrcObject
) w
;
264 Piece
*start_piece
, *end_piece
, *temp_piece
;
265 XawTextPosition start_first
, end_first
;
266 int length
, firstPos
;
269 * Editing a read only source is not allowed.
272 if (src
->text_src
.edit_mode
== XawtextRead
)
273 return(XawEditError
);
275 start_piece
= FindPiece(src
, startPos
, &start_first
);
276 end_piece
= FindPiece(src
, endPos
, &end_first
);
278 src
->ascii_src
.changes
= TRUE
; /* We have changed the buffer. */
280 XtCallCallbacks(w
, XtNcallback
, NULL
);
286 if (start_piece
!= end_piece
) {
287 temp_piece
= start_piece
->next
;
290 * If empty and not the only piece then remove it.
293 if ( ((start_piece
->used
= startPos
- start_first
) == 0) &&
294 !((start_piece
->next
== NULL
) && (start_piece
->prev
== NULL
)) )
295 RemovePiece(src
, start_piece
);
297 while (temp_piece
!= end_piece
) {
298 temp_piece
= temp_piece
->next
;
299 RemovePiece(src
, temp_piece
->prev
);
301 end_piece
->used
-= endPos
- end_first
;
302 if (end_piece
->used
!= 0)
303 MyStrncpy(end_piece
->text
, (end_piece
->text
+ endPos
- end_first
),
304 (int) end_piece
->used
);
306 else { /* We are fully in one piece. */
307 if ( (start_piece
->used
-= endPos
- startPos
) == 0) {
308 if ( !((start_piece
->next
== NULL
) && (start_piece
->prev
== NULL
)) )
309 RemovePiece(src
, start_piece
);
312 MyStrncpy(start_piece
->text
+ (startPos
- start_first
),
313 start_piece
->text
+ (endPos
- start_first
),
314 (int) (start_piece
->used
- (startPos
- start_first
)) );
315 if ( src
->ascii_src
.use_string_in_place
&&
316 ((src
->ascii_src
.length
- (endPos
- startPos
)) <
317 (src
->ascii_src
.piece_size
- 1)) )
318 start_piece
->text
[src
->ascii_src
.length
- (endPos
- startPos
)] = '\0';
322 src
->ascii_src
.length
+= -(endPos
- startPos
) + text
->length
;
324 if ( text
->length
!= 0) {
327 * Put in the New Stuff.
330 start_piece
= FindPiece(src
, startPos
, &start_first
);
332 length
= text
->length
;
333 firstPos
= text
->firstPos
;
339 if (src
->ascii_src
.use_string_in_place
) {
340 if (start_piece
->used
== (src
->ascii_src
.piece_size
- 1)) {
342 * If we are in ascii string emulation mode. Then the
343 * string is not allowed to grow.
345 start_piece
->used
= src
->ascii_src
.length
=
346 src
->ascii_src
.piece_size
- 1;
347 start_piece
->text
[src
->ascii_src
.length
] = '\0';
348 return(XawEditError
);
353 if (start_piece
->used
== src
->ascii_src
.piece_size
) {
354 BreakPiece(src
, start_piece
);
355 start_piece
= FindPiece(src
, startPos
, &start_first
);
358 fill
= Min((int)(src
->ascii_src
.piece_size
- start_piece
->used
), length
);
360 ptr
= start_piece
->text
+ (startPos
- start_first
);
361 MyStrncpy(ptr
+ fill
, ptr
,
362 (int) start_piece
->used
- (startPos
- start_first
));
363 strncpy(ptr
, text
->ptr
+ firstPos
, fill
);
367 start_piece
->used
+= fill
;
372 if (src
->ascii_src
.use_string_in_place
)
373 start_piece
->text
[start_piece
->used
] = '\0';
378 /* Function Name: Scan
379 * Description: Scans the text source for the number and type
381 * Arguments: w - the AsciiSource widget.
382 * position - the position to start scanning.
383 * type - type of thing to scan for.
384 * dir - direction to scan.
385 * count - which occurance if this thing to search for.
386 * include - whether or not to include the character found in
387 * the position that is returned.
388 * Returns: the position of the item found.
390 * Note: While there are only 'n' characters in the file there are n+1
391 * possible cursor positions (one before the first character and
392 * one after the last character.
397 Scan (w
, position
, type
, dir
, count
, include
)
399 XawTextPosition position
;
400 XawTextScanType type
;
401 XawTextScanDirection dir
;
405 AsciiSrcObject src
= (AsciiSrcObject
) w
;
408 XawTextPosition first
, first_eol_position
;
411 if (type
== XawstAll
) { /* Optomize this common case. */
412 if (dir
== XawsdRight
)
413 return(src
->ascii_src
.length
);
414 return(0); /* else. */
417 if (position
> src
->ascii_src
.length
)
418 position
= src
->ascii_src
.length
;
420 if ( dir
== XawsdRight
) {
421 if (position
== src
->ascii_src
.length
)
423 * Scanning right from src->ascii_src.length???
425 return(src
->ascii_src
.length
);
430 return(0); /* Scanning left from 0??? */
435 piece
= FindPiece(src
, position
, &first
);
438 * If the buffer is empty then return 0.
441 if ( piece
->used
== 0 ) return(0);
443 ptr
= (position
- first
) + piece
->text
;
448 case XawstWhiteSpace
:
449 for ( ; count
> 0 ; count
-- ) {
450 Boolean non_space
= FALSE
, first_eol
= TRUE
;
452 register unsigned char c
= *ptr
;
457 if (type
== XawstWhiteSpace
) {
465 else if (type
== XawstEOL
) {
466 if (c
== '\n') break;
468 else { /* XawstParagraph */
471 first_eol_position
= position
;
478 else if ( !isspace(c
) )
483 if ( ptr
< piece
->text
) {
485 if (piece
== NULL
) /* Begining of text. */
487 ptr
= piece
->text
+ piece
->used
- 1;
489 else if ( ptr
>= (piece
->text
+ piece
->used
) ) {
491 if (piece
== NULL
) /* End of text. */
492 return(src
->ascii_src
.length
);
498 if ( type
== XawstParagraph
)
499 position
= first_eol_position
;
504 position
+= count
* inc
;
506 /* case XawstAll: ---- handled in special code above */
509 if ( dir
== XawsdLeft
)
512 if (position
>= src
->ascii_src
.length
)
513 return(src
->ascii_src
.length
);
520 /* Function Name: Search
521 * Description: Searchs the text source for the text block passed
522 * Arguments: w - the AsciiSource Widget.
523 * position - the position to start scanning.
524 * dir - direction to scan.
525 * text - the text block to search for.
526 * Returns: the position of the item found.
529 static XawTextPosition
530 Search(w
, position
, dir
, text
)
532 XawTextPosition position
;
533 XawTextScanDirection dir
;
536 AsciiSrcObject src
= (AsciiSrcObject
) w
;
537 register int inc
, count
= 0;
541 XawTextPosition first
;
543 if ( dir
== XawsdRight
)
548 return(XawTextSearchError
); /* scanning left from 0??? */
552 buf
= XtMalloc(sizeof(unsigned char) * text
->length
);
553 strncpy(buf
, (text
->ptr
+ text
->firstPos
), text
->length
);
554 piece
= FindPiece(src
, position
, &first
);
555 ptr
= (position
- first
) + piece
->text
;
558 if (*ptr
== ((dir
== XawsdRight
) ? *(buf
+ count
)
559 : *(buf
+ text
->length
- count
- 1)) ) {
560 if (count
== (text
->length
- 1))
567 position
-=inc
* count
;
576 while ( ptr
< piece
->text
) {
578 if (piece
== NULL
) { /* Begining of text. */
580 return(XawTextSearchError
);
582 ptr
= piece
->text
+ piece
->used
- 1;
585 while ( ptr
>= (piece
->text
+ piece
->used
) ) {
587 if (piece
== NULL
) { /* End of text. */
589 return(XawTextSearchError
);
596 if (dir
== XawsdLeft
)
598 return(position
- (text
->length
- 1));
601 /* Function Name: SetValues
602 * Description: Sets the values for the AsciiSource.
603 * Arguments: current - current state of the widget.
604 * request - what was requested.
605 * new - what the widget will become.
606 * Returns: True if redisplay is needed.
611 SetValues(current
, request
, new)
612 Widget current
, request
, new;
614 AsciiSrcObject src
= (AsciiSrcObject
) new;
615 AsciiSrcObject old_src
= (AsciiSrcObject
) current
;
616 Boolean total_reset
= FALSE
;
619 if ( old_src
->ascii_src
.use_string_in_place
!=
620 src
->ascii_src
.use_string_in_place
) {
621 XtAppWarning( XtWidgetToApplicationContext(new),
622 "AsciiSrc: The XtNuseStrinInPlace resources may not be changed.");
623 src
->ascii_src
.use_string_in_place
=
624 old_src
->ascii_src
.use_string_in_place
;
627 if ( (old_src
->ascii_src
.string
!= src
->ascii_src
.string
) ||
628 (old_src
->ascii_src
.type
!= src
->ascii_src
.type
) ) {
629 if (old_src
->ascii_src
.string
== src
->ascii_src
.string
) {
630 /* Fool it into not freeing the string */
631 src
->ascii_src
.allocated_string
= FALSE
;
632 RemoveOldStringOrFile(old_src
); /* remove old info. */
633 src
->ascii_src
.allocated_string
= TRUE
;
636 RemoveOldStringOrFile(old_src
); /* remove old info. */
637 src
->ascii_src
.allocated_string
= FALSE
;
640 file
= InitStringOrFile(src
); /* Init new info. */
641 LoadPieces(src
, file
, NULL
); /* load new info into internal buffers. */
642 if (file
!= NULL
) fclose(file
);
643 XawTextSetSource( XtParent(new), new, 0); /* Tell text widget
645 if ( src
->ascii_src
.type
== XawAsciiString
)
646 src
->ascii_src
.string
= NULL
;
651 if ( old_src
->ascii_src
.ascii_length
!= src
->ascii_src
.ascii_length
)
652 src
->ascii_src
.piece_size
= src
->ascii_src
.ascii_length
;
655 (old_src
->ascii_src
.piece_size
!= src
->ascii_src
.piece_size
) ) {
656 String string
= StorePiecesInString(old_src
);
657 FreeAllPieces(old_src
);
658 LoadPieces(src
, NULL
, string
);
665 /* Function Name: GetValuesHook
666 * Description: This is a get values hook routine that sets the
667 * values specific to the ascii source.
668 * Arguments: w - the AsciiSource Widget.
669 * args - the argument list.
670 * num_args - the number of args.
675 GetValuesHook(w
, args
, num_args
)
680 AsciiSrcObject src
= (AsciiSrcObject
) w
;
683 if (src
->ascii_src
.use_string_in_place
)
686 if (src
->ascii_src
.type
== XawAsciiString
) {
687 for (i
= 0; i
< *num_args
; i
++ )
688 if (streq(args
[i
].name
, XtNstring
)) {
689 if (XawAsciiSave(w
)) /* If save sucessful. */
690 *((char **) args
[i
].value
) = src
->ascii_src
.string
;
696 /* Function Name: Destroy
697 * Description: Destroys an ascii source (frees all data)
698 * Arguments: src - the Ascii source Widget to free.
706 RemoveOldStringOrFile((AsciiSrcObject
) w
);
709 /************************************************************
713 ************************************************************/
715 /* Function Name: XawAsciiSourceFreeString
716 * Description: Frees the string returned by a get values call
717 * on the string when the source is of type string.
718 * Arguments: w - the AsciiSrc widget.
723 XawAsciiSourceFreeString(w
)
726 AsciiSrcObject src
= (AsciiSrcObject
) w
;
728 if (src
->ascii_src
.allocated_string
) {
729 src
->ascii_src
.allocated_string
= FALSE
;
730 XtFree(src
->ascii_src
.string
);
734 /* Function Name: XawAsciiSave
735 * Description: Saves all the pieces into a file or string as required.
736 * Arguments: w - the asciiSrc Widget.
737 * Returns: TRUE if the save was successful.
744 AsciiSrcObject src
= (AsciiSrcObject
) w
;
747 * If using the string in place then there is no need to play games
748 * to get the internal info into a readable string.
751 if (src
->ascii_src
.use_string_in_place
)
754 if (src
->ascii_src
.type
== XawAsciiFile
) {
757 if (!src
->ascii_src
.changes
) /* No changes to save. */
760 string
= StorePiecesInString(src
);
762 if (WriteToFile(src
, string
, src
->ascii_src
.string
) == FALSE
) {
768 else { /* This is a string widget. */
769 if (src
->ascii_src
.allocated_string
== TRUE
)
770 XtFree(src
->ascii_src
.string
);
772 src
->ascii_src
.allocated_string
= TRUE
;
774 src
->ascii_src
.string
= StorePiecesInString(src
);
776 src
->ascii_src
.changes
= FALSE
;
780 /* Function Name: XawAsciiSaveAsFile
781 * Description: Save the current buffer as a file.
782 * Arguments: w - the AsciiSrc widget.
783 * name - name of the file to save this file into.
784 * Returns: True if the save was sucessful.
788 XawAsciiSaveAsFile(w
, name
)
792 AsciiSrcObject src
= (AsciiSrcObject
) w
;
796 string
= StorePiecesInString(src
);
798 ret
= WriteToFile(src
, string
, name
);
803 /* Function Name: XawAsciiSourceChanged
804 * Description: Returns true if the source has changed since last saved.
805 * Arguments: w - the ascii source widget.
806 * Returns: a Boolean (see description).
810 XawAsciiSourceChanged(w
)
813 return( ((AsciiSrcObject
) w
)->ascii_src
.changes
);
816 /************************************************************
820 ************************************************************/
823 RemoveOldStringOrFile(src
)
828 if (src
->ascii_src
.allocated_string
)
829 XtFree(src
->ascii_src
.string
);
832 /* Function Name: WriteToFile
833 * Description: Write the string specified to the begining of the file
835 * Arguments: w - the widget. (for error messages only)
836 * string - string to write.
837 * name - the name of the file
838 * file - file to write it to.
839 * Returns: returns TRUE if sucessful, FALSE otherwise.
843 WriteToFile(src
, string
, name
)
847 unsigned char buf
[BUFSIZ
];
850 if ( ((fd
= creat(name
, 0666)) == -1 ) ||
851 (write(fd
, string
, sizeof(unsigned char) * strlen(string
)) == -1) ) {
852 sprintf((char *)buf
, "Error, while attempting to write to the file %s.", name
);
853 XtAppWarning(XtWidgetToApplicationContext((Widget
) src
), (const char *)buf
);
857 if ( close(fd
) == -1 ) {
858 sprintf((char *)buf
, "Error, while attempting to close the file %s.", name
);
859 XtAppWarning(XtWidgetToApplicationContext((Widget
) src
), (const char *)buf
);
865 /* Function Name: StorePiecesInString
866 * Description: store the pieces in memory into a standard ascii string.
867 * Arguments: data - the ascii pointer data.
872 StorePiecesInString(src
)
876 XawTextPosition first
;
879 string
= XtMalloc(sizeof(unsigned char) * src
->ascii_src
.length
+ 1);
881 for (first
= 0, piece
= src
->ascii_src
.first_piece
; piece
!= NULL
;
882 first
+= piece
->used
, piece
= piece
->next
)
883 strncpy(string
+ first
, piece
->text
, piece
->used
);
885 string
[src
->ascii_src
.length
] = '\0'; /* NULL terminate this sucker. */
888 * This will refill all pieces to capacity.
891 if (src
->ascii_src
.data_compression
) {
893 LoadPieces(src
, NULL
, string
);
899 /* Function Name: InitStringOrFile.
900 * Description: Initializes the string or file.
901 * Arguments: src - the AsciiSource.
902 * Returns: none - May exit though.
906 InitStringOrFile(src
)
912 if (src
->ascii_src
.type
== XawAsciiString
) {
913 if (src
->ascii_src
.string
== NULL
)
914 src
->ascii_src
.length
= 0;
916 src
->ascii_src
.length
= strlen(src
->ascii_src
.string
);
918 if (src
->ascii_src
.use_string_in_place
) {
919 if (src
->ascii_src
.ascii_length
== MAGIC_VALUE
)
920 src
->ascii_src
.piece_size
= src
->ascii_src
.length
;
922 src
->ascii_src
.piece_size
= src
->ascii_src
.ascii_length
+ 1;
929 * type is XawAsciiFile.
932 src
->ascii_src
.is_tempfile
= FALSE
;
934 switch (src
->text_src
.edit_mode
) {
936 if (src
->ascii_src
.string
== NULL
)
937 XtErrorMsg("NoFile", "asciiSourceCreate", "XawError",
938 "Creating a read only disk widget and no file specified.",
944 if (src
->ascii_src
.string
== NULL
) {
945 src
->ascii_src
.string
= tmpnam (XtMalloc((unsigned)TMPSIZ
));
946 src
->ascii_src
.is_tempfile
= TRUE
;
949 if (!src
->ascii_src
.allocated_string
) {
950 src
->ascii_src
.allocated_string
= TRUE
;
951 src
->ascii_src
.string
= XtNewString(src
->ascii_src
.string
);
958 XtErrorMsg("badMode", "asciiSourceCreate", "XawError",
959 "Bad editMode for ascii source; must be Read, Append or Edit.",
963 if (!src
->ascii_src
.is_tempfile
) {
964 if ((file
= fopen(src
->ascii_src
.string
, open_mode
)) == 0) {
966 Cardinal num_params
= 2;
968 params
[0] = src
->ascii_src
.string
;
969 if (errno
<= sys_nerr
)
970 params
[1] = sys_errlist
[errno
];
973 sprintf(msg
, "errno=%.4d", errno
);
976 XtErrorMsg("openError", "asciiSourceCreate", "XawError",
977 "Cannot open source file %s; %s", params
, &num_params
);
979 (void) fseek(file
, 0L, 2);
980 src
->ascii_src
.length
= ftell (file
);
983 src
->ascii_src
.length
= 0;
991 LoadPieces(src
, file
, string
)
996 char *local_str
, *ptr
;
997 register Piece
* piece
= NULL
;
998 XawTextPosition left
;
1000 if (string
== NULL
) {
1001 if (src
->ascii_src
.type
== XawAsciiFile
) {
1002 local_str
= XtMalloc((src
->ascii_src
.length
+ 1) *sizeof(unsigned char));
1003 if (src
->ascii_src
.length
!= 0) {
1005 if ( fread(local_str
, sizeof(unsigned char),
1006 src
->ascii_src
.length
, file
) != src
->ascii_src
.length
)
1007 XtErrorMsg("readError", "asciiSourceCreate", "XawError",
1008 "fread returned error.", NULL
, NULL
);
1010 local_str
[src
->ascii_src
.length
] = '\0';
1013 local_str
= src
->ascii_src
.string
;
1019 * If we are using teh string in place then set the other fields as follows:
1021 * piece_size = length;
1022 * piece->used = src->ascii_src.length;
1025 if (src
->ascii_src
.use_string_in_place
) {
1026 piece
= AllocNewPiece(src
, piece
);
1027 piece
->used
= Min(src
->ascii_src
.length
, src
->ascii_src
.piece_size
);
1028 piece
->text
= src
->ascii_src
.string
;
1033 left
= src
->ascii_src
.length
;
1036 piece
= AllocNewPiece(src
, piece
);
1038 piece
->text
= XtMalloc(src
->ascii_src
.piece_size
* sizeof(unsigned char));
1039 piece
->used
= Min(left
, src
->ascii_src
.piece_size
);
1040 if (piece
->used
!= 0)
1041 strncpy(piece
->text
, ptr
, piece
->used
);
1043 left
-= piece
->used
;
1047 if ( (src
->ascii_src
.type
== XawAsciiFile
) && (string
== NULL
) )
1051 /* Function Name: AllocNewPiece
1052 * Description: Allocates a new piece of memory.
1053 * Arguments: src - The AsciiSrc Widget.
1054 * prev - the piece just before this one, or NULL.
1055 * Returns: the allocated piece.
1059 AllocNewPiece(src
, prev
)
1063 Piece
* piece
= XtNew(Piece
);
1066 src
->ascii_src
.first_piece
= piece
;
1070 if (prev
->next
!= NULL
)
1071 (prev
->next
)->prev
= piece
;
1072 piece
->next
= prev
->next
;
1081 /* Function Name: FreeAllPieces
1082 * Description: Frees all the pieces
1083 * Arguments: src - The AsciiSrc Widget.
1091 Piece
* next
, * first
= src
->ascii_src
.first_piece
;
1093 if (first
->prev
!= NULL
)
1094 printf("Programmer Botch in FreeAllPieces, there may be a memory leak.\n");
1096 for ( ; first
!= NULL
; first
= next
) {
1098 RemovePiece(src
, first
);
1102 /* Function Name: RemovePiece
1103 * Description: Removes a piece from the list.
1105 * piece - the piece to remove.
1110 RemovePiece(src
, piece
)
1114 if (piece
->prev
== NULL
)
1115 src
->ascii_src
.first_piece
= piece
->next
;
1117 (piece
->prev
)->next
= piece
->next
;
1119 if (piece
->next
!= NULL
)
1120 (piece
->next
)->prev
= piece
->prev
;
1122 if (src
->ascii_src
.allocated_string
)
1123 XtFree(piece
->text
);
1125 XtFree((char *)piece
);
1128 /* Function Name: FindPiece
1129 * Description: Finds the piece containing the position indicated.
1130 * Arguments: src - The AsciiSrc Widget.
1131 * position - the position that we are searching for.
1132 * RETURNED first - the position of the first character in this piece.
1133 * Returns: piece - the piece that contains this position.
1137 FindPiece(src
, position
, first
)
1139 XawTextPosition position
, *first
;
1141 Piece
* old_piece
, * piece
= src
->ascii_src
.first_piece
;
1142 XawTextPosition temp
;
1144 for ( temp
= 0 ; piece
!= NULL
; temp
+= piece
->used
, piece
= piece
->next
) {
1148 if ((temp
+ piece
->used
) > position
)
1151 return(old_piece
); /* if we run off the end the return the last piece */
1154 /* Function Name: MyStrncpy
1155 * Description: Just like string copy, but slower and will always
1156 * work on overlapping strings.
1157 * Arguments: (same as strncpy) - s1, s2 - strings to copy (2->1).
1158 * n - the number of chars to copy.
1163 MyStrncpy(s1
, s2
, n
)
1167 char * temp
= XtMalloc(sizeof(unsigned char) * n
);
1169 strncpy(temp
, s2
, n
); /* Saber has a bug that causes it to generate*/
1170 strncpy(s1
, temp
, n
); /* a bogus warning message here (CDP 6/32/89)*/
1175 /* Function Name: BreakPiece
1176 * Description: Breaks a full piece into two new pieces.
1177 * Arguments: src - The AsciiSrc Widget.
1178 * piece - the piece to break.
1182 #define HALF_PIECE (src->ascii_src.piece_size/2)
1185 BreakPiece(src
, piece
)
1189 Piece
* new = AllocNewPiece(src
, piece
);
1191 new->text
= XtMalloc(src
->ascii_src
.piece_size
* sizeof(unsigned char));
1192 strncpy(new->text
, piece
->text
+ HALF_PIECE
,
1193 src
->ascii_src
.piece_size
- HALF_PIECE
);
1194 piece
->used
= HALF_PIECE
;
1195 new->used
= src
->ascii_src
.piece_size
- HALF_PIECE
;
1200 CvtStringToAsciiType(args
, num_args
, fromVal
, toVal
)
1201 XrmValuePtr
*args
; /* unused */
1202 Cardinal
*num_args
; /* unused */
1203 XrmValuePtr fromVal
;
1206 static XawAsciiType type
;
1207 static XrmQuark XtQEstring
;
1208 static XrmQuark XtQEfile
;
1209 static int haveQuarks
= FALSE
;
1211 char lowerName
[BUFSIZ
];
1214 XtQEstring
= XrmStringToQuark(XtEstring
);
1215 XtQEfile
= XrmStringToQuark(XtEfile
);
1219 XmuCopyISOLatin1Lowered(lowerName
, (char *) fromVal
->addr
);
1220 q
= XrmStringToQuark(lowerName
);
1222 if (q
== XtQEstring
) type
= XawAsciiString
;
1223 if (q
== XtQEfile
) type
= XawAsciiFile
;
1225 (*toVal
).size
= sizeof(XawAsciiType
);
1226 (*toVal
).addr
= (caddr_t
) &type
;
1230 #if (defined(ASCII_STRING) || defined(ASCII_DISK))
1231 # include <./Xaw3_1Cardinals.h>
1235 /************************************************************
1237 * Compatability functions.
1239 ************************************************************/
1241 /* Function Name: AsciiStringSourceCreate
1242 * Description: Creates a string source.
1243 * Arguments: parent - the widget that will own this source.
1244 * args, num_args - the argument list.
1245 * Returns: a pointer to the new text source.
1249 XawStringSourceCreate(parent
, args
, num_args
)
1258 XtSetArg(temp
[0], XtNtype
, XawAsciiString
);
1259 XtSetArg(temp
[1], XtNuseStringInPlace
, TRUE
);
1260 ascii_args
= XtMergeArgLists(temp
, TWO
, args
, num_args
);
1262 src
= XtCreateWidget("genericAsciiString", asciiSrcObjectClass
, parent
,
1263 ascii_args
, num_args
+ TWO
);
1264 XtFree((char *)ascii_args
);
1269 * This is hacked up to try to emulate old functionality, it
1270 * may not work, as I have not old code to test it on.
1272 * Chris D. Peterson 8/31/89.
1276 XawTextSetLastPos (w
, lastPos
)
1278 XawTextPosition lastPos
;
1280 AsciiSrcObject src
= (AsciiSrcObject
) XawTextGetSource(w
);
1282 src
->ascii_src
.piece_size
= lastPos
;
1284 #endif /* ASCII_STRING */
1287 /* Function Name: AsciiDiskSourceCreate
1288 * Description: Creates a disk source.
1289 * Arguments: parent - the widget that will own this source.
1290 * args, num_args - the argument list.
1291 * Returns: a pointer to the new text source.
1295 XawDiskSourceCreate(parent
, args
, num_args
)
1305 XtSetArg(temp
[0], XtNtype
, XawAsciiFile
);
1307 for (i
= 0; i
< num_args
; i
++)
1308 if (streq(args
[i
].name
, XtNfile
) || streq(args
[i
].name
, XtCFile
))
1309 args
[i
].name
= XtNstring
;
1311 ascii_args
= XtMergeArgLists(temp
, ONE
, args
, num_args
);
1312 src
= XtCreateWidget("genericAsciiDisk", asciiSrcObjectClass
, parent
,
1313 ascii_args
, num_args
+ ONE
);
1314 XtFree((char *)ascii_args
);
1317 #endif /* ASCII_DISK */