1 /* $XConsortium: AsciiSrc.c,v 1.66 95/01/16 20:10:20 kaleb Exp $ */
5 Copyright (c) 1989, 1994 X Consortium
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 Except as contained in this notice, the name of the X Consortium shall not be
25 used in advertising or otherwise to promote the sale, use or other dealings
26 in this Software without prior written authorization from the X Consortium.
31 * AsciiSrc.c - AsciiSrc object. (For use with the text widget).
35 #include <X11/IntrinsicP.h>
39 #include <X11/StringDefs.h>
41 #ifndef X_NOT_STDC_ENV
44 #include <X11/Xfuncs.h>
46 #include "AsciiSrcP.h"
47 #include <X11/Xmu/Misc.h>
48 #include <X11/Xmu/CharSet.h>
49 #include "MultiSrcP.h"
52 #if (defined(ASCII_STRING) || defined(ASCII_DISK))
53 # include "AsciiText.h" /* for Widget Classes. */
57 /****************************************************************
59 * Full class record constant
61 ****************************************************************/
65 static int magic_value
= MAGIC_VALUE
;
67 #define offset(field) XtOffsetOf(AsciiSrcRec, ascii_src.field)
69 static XtResource resources
[] = {
70 {XtNstring
, XtCString
, XtRString
, sizeof (char *),
71 offset(string
), XtRString
, NULL
},
72 {XtNtype
, XtCType
, XtRAsciiType
, sizeof (XawAsciiType
),
73 offset(type
), XtRImmediate
, (XtPointer
)XawAsciiString
},
74 {XtNdataCompression
, XtCDataCompression
, XtRBoolean
, sizeof (Boolean
),
75 offset(data_compression
), XtRImmediate
, (XtPointer
) TRUE
},
76 {XtNpieceSize
, XtCPieceSize
, XtRInt
, sizeof (XawTextPosition
),
77 offset(piece_size
), XtRImmediate
, (XtPointer
) BUFSIZ
},
78 {XtNcallback
, XtCCallback
, XtRCallback
, sizeof(XtPointer
),
79 offset(callback
), XtRCallback
, (XtPointer
)NULL
},
80 {XtNuseStringInPlace
, XtCUseStringInPlace
, XtRBoolean
, sizeof (Boolean
),
81 offset(use_string_in_place
), XtRImmediate
, (XtPointer
) FALSE
},
82 {XtNlength
, XtCLength
, XtRInt
, sizeof (int),
83 offset(ascii_length
), XtRInt
, (XtPointer
) &magic_value
},
86 {XtNfile
, XtCFile
, XtRString
, sizeof (String
),
87 offset(filename
), XtRString
, NULL
},
88 #endif /* ASCII_DISK */
92 static XawTextPosition
Scan(), Search(), ReadText();
93 static int ReplaceText();
94 static Piece
* FindPiece(), * AllocNewPiece();
95 static FILE * InitStringOrFile();
96 static void FreeAllPieces(), RemovePiece(), BreakPiece(), LoadPieces();
97 static void RemoveOldStringOrFile(), CvtStringToAsciiType();
98 static void ClassInitialize(), Initialize(), Destroy(), GetValuesHook();
99 static String
MyStrncpy(), StorePiecesInString();
100 static Boolean
SetValues(), WriteToFile();
101 #ifdef X_NOT_STDC_ENV
107 #define Size_t unsigned int
110 #define Size_t size_t
113 #define superclass (&textSrcClassRec)
114 AsciiSrcClassRec asciiSrcClassRec
= {
116 /* core_class fields */
117 /* superclass */ (WidgetClass
) superclass
,
118 /* class_name */ "AsciiSrc",
119 /* widget_size */ sizeof(AsciiSrcRec
),
120 /* class_initialize */ ClassInitialize
,
121 /* class_part_initialize */ NULL
,
122 /* class_inited */ FALSE
,
123 /* initialize */ Initialize
,
124 /* initialize_hook */ NULL
,
128 /* resources */ resources
,
129 /* num_resources */ XtNumber(resources
),
130 /* xrm_class */ NULLQUARK
,
131 /* compress_motion */ FALSE
,
132 /* compress_exposure */ FALSE
,
133 /* compress_enterleave */ FALSE
,
134 /* visible_interest */ FALSE
,
135 /* destroy */ Destroy
,
138 /* set_values */ SetValues
,
139 /* set_values_hook */ NULL
,
140 /* set_values_almost */ NULL
,
141 /* get_values_hook */ GetValuesHook
,
142 /* accept_focus */ NULL
,
143 /* version */ XtVersion
,
144 /* callback_private */ NULL
,
146 /* query_geometry */ NULL
,
147 /* display_accelerator */ NULL
,
150 /* textSrc_class fields */
153 /* Replace */ ReplaceText
,
156 /* SetSelection */ XtInheritSetSelection
,
157 /* ConvertSelection */ XtInheritConvertSelection
159 /* asciiSrc_class fields */
161 /* Keep the compiler happy */ '\0'
165 WidgetClass asciiSrcObjectClass
= (WidgetClass
)&asciiSrcClassRec
;
167 /************************************************************
169 * Semi-Public Interfaces.
171 ************************************************************/
173 /* Function Name: ClassInitialize
174 * Description: Class Initialize routine, called only once.
182 XawInitializeWidgetSet();
183 XtAddConverter( XtRString
, XtRAsciiType
, CvtStringToAsciiType
,
187 /* Function Name: Initialize
188 * Description: Initializes the simple menu widget
189 * Arguments: request - the widget requested by the argument list.
190 * new - the new widget with both resource and non
197 Initialize(request
, new, args
, num_args
)
202 AsciiSrcObject src
= (AsciiSrcObject
) new;
206 * Set correct flags (override resources) depending upon widget class.
209 src
->text_src
.text_format
= XawFmt8Bit
; /* data format. */
212 if (XtIsSubclass(XtParent(new), asciiDiskWidgetClass
)) {
213 src
->ascii_src
.type
= XawAsciiFile
;
214 src
->ascii_src
.string
= src
->ascii_src
.filename
;
219 if (XtIsSubclass(XtParent(new), asciiStringWidgetClass
)) {
220 src
->ascii_src
.use_string_in_place
= TRUE
;
221 src
->ascii_src
.type
= XawAsciiString
;
225 src
->ascii_src
.changes
= FALSE
;
226 src
->ascii_src
.allocated_string
= FALSE
;
228 file
= InitStringOrFile(src
, src
->ascii_src
.type
== XawAsciiFile
);
229 LoadPieces(src
, file
, NULL
);
231 if (file
!= NULL
) fclose(file
);
234 /* Function Name: ReadText
235 * Description: This function reads the source.
236 * Arguments: w - the AsciiSource widget.
237 * pos - position of the text to retreive.
238 * RETURNED text - text block that will contain returned text.
239 * length - maximum number of characters to read.
240 * Returns: The number of characters read into the buffer.
243 static XawTextPosition
244 ReadText(w
, pos
, text
, length
)
250 AsciiSrcObject src
= (AsciiSrcObject
) w
;
251 XawTextPosition count
, start
;
252 Piece
* piece
= FindPiece(src
, pos
, &start
);
254 text
->firstPos
= pos
;
255 text
->ptr
= piece
->text
+ (pos
- start
);
256 count
= piece
->used
- (pos
- start
);
257 text
->length
= (length
> (int)count
) ? count
: length
;
258 return(pos
+ text
->length
);
261 /* Function Name: ReplaceText.
262 * Description: Replaces a block of text with new text.
263 * Arguments: w - the AsciiSource widget.
264 * startPos, endPos - ends of text that will be removed.
265 * text - new text to be inserted into buffer at startPos.
266 * Returns: XawEditError or XawEditDone.
271 ReplaceText (w
, startPos
, endPos
, text
)
273 XawTextPosition startPos
, endPos
;
276 AsciiSrcObject src
= (AsciiSrcObject
) w
;
277 Piece
*start_piece
, *end_piece
, *temp_piece
;
278 XawTextPosition start_first
, end_first
;
279 int length
, firstPos
;
282 * Editing a read only source is not allowed.
285 if (src
->text_src
.edit_mode
== XawtextRead
)
286 return(XawEditError
);
288 start_piece
= FindPiece(src
, startPos
, &start_first
);
289 end_piece
= FindPiece(src
, endPos
, &end_first
);
291 src
->ascii_src
.changes
= TRUE
; /* We have changed the buffer. */
297 if (start_piece
!= end_piece
) {
298 temp_piece
= start_piece
->next
;
301 * If empty and not the only piece then remove it.
304 if ( ((start_piece
->used
= startPos
- start_first
) == 0) &&
305 !((start_piece
->next
== NULL
) && (start_piece
->prev
== NULL
)) )
306 RemovePiece(src
, start_piece
);
308 while (temp_piece
!= end_piece
) {
309 temp_piece
= temp_piece
->next
;
310 RemovePiece(src
, temp_piece
->prev
);
312 end_piece
->used
-= endPos
- end_first
;
313 if (end_piece
->used
!= 0)
314 MyStrncpy(end_piece
->text
, (end_piece
->text
+ endPos
- end_first
),
315 (int) end_piece
->used
);
317 else { /* We are fully in one piece. */
318 if ( (start_piece
->used
-= endPos
- startPos
) == 0) {
319 if ( !((start_piece
->next
== NULL
) && (start_piece
->prev
== NULL
)) )
320 RemovePiece(src
, start_piece
);
323 MyStrncpy(start_piece
->text
+ (startPos
- start_first
),
324 start_piece
->text
+ (endPos
- start_first
),
325 (int) (start_piece
->used
- (startPos
- start_first
)) );
326 if ( src
->ascii_src
.use_string_in_place
&&
327 ((src
->ascii_src
.length
- (endPos
- startPos
)) <
328 (src
->ascii_src
.piece_size
- 1)) )
329 start_piece
->text
[src
->ascii_src
.length
- (endPos
- startPos
)] = '\0';
333 src
->ascii_src
.length
+= -(endPos
- startPos
) + text
->length
;
335 if ( text
->length
!= 0) {
338 * Put in the New Stuff.
341 start_piece
= FindPiece(src
, startPos
, &start_first
);
343 length
= text
->length
;
344 firstPos
= text
->firstPos
;
350 if (src
->ascii_src
.use_string_in_place
) {
351 if (start_piece
->used
== (src
->ascii_src
.piece_size
- 1)) {
353 * If we are in ascii string emulation mode. Then the
354 * string is not allowed to grow.
356 start_piece
->used
= src
->ascii_src
.length
=
357 src
->ascii_src
.piece_size
- 1;
358 start_piece
->text
[src
->ascii_src
.length
] = '\0';
359 return(XawEditError
);
364 if (start_piece
->used
== src
->ascii_src
.piece_size
) {
365 BreakPiece(src
, start_piece
);
366 start_piece
= FindPiece(src
, startPos
, &start_first
);
369 fill
= Min((int)(src
->ascii_src
.piece_size
- start_piece
->used
), length
);
371 ptr
= start_piece
->text
+ (startPos
- start_first
);
372 MyStrncpy(ptr
+ fill
, ptr
,
373 (int) start_piece
->used
- (startPos
- start_first
));
374 strncpy(ptr
, text
->ptr
+ firstPos
, fill
);
378 start_piece
->used
+= fill
;
383 if (src
->ascii_src
.use_string_in_place
)
384 start_piece
->text
[start_piece
->used
] = '\0';
386 XtCallCallbacks(w
, XtNcallback
, NULL
); /* Call callbacks, we have changed
392 /* Function Name: Scan
393 * Description: Scans the text source for the number and type
395 * Arguments: w - the AsciiSource widget.
396 * position - the position to start scanning.
397 * type - type of thing to scan for.
398 * dir - direction to scan.
399 * count - which occurance if this thing to search for.
400 * include - whether or not to include the character found in
401 * the position that is returned.
402 * Returns: the position of the item found.
404 * Note: While there are only 'n' characters in the file there are n+1
405 * possible cursor positions (one before the first character and
406 * one after the last character.
411 Scan (w
, position
, type
, dir
, count
, include
)
413 XawTextPosition position
;
414 XawTextScanType type
;
415 XawTextScanDirection dir
;
419 AsciiSrcObject src
= (AsciiSrcObject
) w
;
422 XawTextPosition first
, first_eol_position
;
425 if (type
== XawstAll
) { /* Optomize this common case. */
426 if (dir
== XawsdRight
)
427 return(src
->ascii_src
.length
);
428 return(0); /* else. */
431 if (position
> src
->ascii_src
.length
)
432 position
= src
->ascii_src
.length
;
434 if ( dir
== XawsdRight
) {
435 if (position
== src
->ascii_src
.length
)
437 * Scanning right from src->ascii_src.length???
439 return(src
->ascii_src
.length
);
444 return(0); /* Scanning left from 0??? */
449 piece
= FindPiece(src
, position
, &first
);
452 * If the buffer is empty then return 0.
455 if ( piece
->used
== 0 ) return(0);
457 ptr
= (position
- first
) + piece
->text
;
462 case XawstWhiteSpace
:
463 for ( ; count
> 0 ; count
-- ) {
464 Boolean non_space
= FALSE
, first_eol
= TRUE
;
467 unsigned char c
= *ptr
;
472 if (type
== XawstWhiteSpace
) {
480 else if (type
== XawstEOL
) {
481 if (c
== '\n') break;
483 else { /* XawstParagraph */
486 first_eol_position
= position
;
493 else if ( !isspace(c
) )
498 if ( ptr
< piece
->text
) {
500 if (piece
== NULL
) /* Begining of text. */
502 ptr
= piece
->text
+ piece
->used
- 1;
504 else if ( ptr
>= (piece
->text
+ piece
->used
) ) {
506 if (piece
== NULL
) /* End of text. */
507 return(src
->ascii_src
.length
);
513 if ( type
== XawstParagraph
)
514 position
= first_eol_position
;
519 position
+= count
* inc
;
521 /* case XawstAll: ---- handled in special code above */
524 if ( dir
== XawsdLeft
)
527 if (position
>= src
->ascii_src
.length
)
528 return(src
->ascii_src
.length
);
535 /* Function Name: Search
536 * Description: Searchs the text source for the text block passed
537 * Arguments: w - the AsciiSource Widget.
538 * position - the position to start scanning.
539 * dir - direction to scan.
540 * text - the text block to search for.
541 * Returns: the position of the item found.
544 static XawTextPosition
545 Search(w
, position
, dir
, text
)
547 XawTextPosition position
;
548 XawTextScanDirection dir
;
551 AsciiSrcObject src
= (AsciiSrcObject
) w
;
556 XawTextPosition first
;
558 if ( dir
== XawsdRight
)
563 return(XawTextSearchError
); /* scanning left from 0??? */
567 buf
= XtMalloc((unsigned)sizeof(unsigned char) * text
->length
);
568 strncpy(buf
, (text
->ptr
+ text
->firstPos
), text
->length
);
569 piece
= FindPiece(src
, position
, &first
);
570 ptr
= (position
- first
) + piece
->text
;
574 if (*ptr
== ((dir
== XawsdRight
) ? *(buf
+ count
)
575 : *(buf
+ text
->length
- count
- 1)) ) {
576 if (count
== (text
->length
- 1))
583 position
-=inc
* count
;
592 while ( ptr
< piece
->text
) {
594 if (piece
== NULL
) { /* Begining of text. */
596 return(XawTextSearchError
);
598 ptr
= piece
->text
+ piece
->used
- 1;
601 while ( ptr
>= (piece
->text
+ piece
->used
) ) {
603 if (piece
== NULL
) { /* End of text. */
605 return(XawTextSearchError
);
612 if (dir
== XawsdLeft
)
614 return(position
- (text
->length
- 1));
617 /* Function Name: SetValues
618 * Description: Sets the values for the AsciiSource.
619 * Arguments: current - current state of the widget.
620 * request - what was requested.
621 * new - what the widget will become.
622 * Returns: True if redisplay is needed.
627 SetValues(current
, request
, new, args
, num_args
)
628 Widget current
, request
, new;
632 AsciiSrcObject src
= (AsciiSrcObject
) new;
633 AsciiSrcObject old_src
= (AsciiSrcObject
) current
;
634 Boolean total_reset
= FALSE
, string_set
= FALSE
;
638 if ( old_src
->ascii_src
.use_string_in_place
!=
639 src
->ascii_src
.use_string_in_place
) {
640 XtAppWarning( XtWidgetToApplicationContext(new),
641 "AsciiSrc: The XtNuseStringInPlace resource may not be changed.");
642 src
->ascii_src
.use_string_in_place
=
643 old_src
->ascii_src
.use_string_in_place
;
646 for (i
= 0; i
< *num_args
; i
++ )
647 if (streq(args
[i
].name
, XtNstring
)) {
652 if ( string_set
|| (old_src
->ascii_src
.type
!= src
->ascii_src
.type
) ) {
653 RemoveOldStringOrFile(old_src
, string_set
); /* remove old info. */
654 file
= InitStringOrFile(src
, string_set
); /* Init new info. */
655 LoadPieces(src
, file
, NULL
); /* load new info into internal buffers. */
656 if (file
!= NULL
) fclose(file
);
657 XawTextSetSource( XtParent(new), new, 0); /* Tell text widget
662 if ( old_src
->ascii_src
.ascii_length
!= src
->ascii_src
.ascii_length
)
663 src
->ascii_src
.piece_size
= src
->ascii_src
.ascii_length
;
666 (old_src
->ascii_src
.piece_size
!= src
->ascii_src
.piece_size
) ) {
667 String string
= StorePiecesInString(old_src
);
668 FreeAllPieces(old_src
);
669 LoadPieces(src
, NULL
, string
);
676 /* Function Name: GetValuesHook
677 * Description: This is a get values hook routine that sets the
678 * values specific to the ascii source.
679 * Arguments: w - the AsciiSource Widget.
680 * args - the argument list.
681 * num_args - the number of args.
686 GetValuesHook(w
, args
, num_args
)
691 AsciiSrcObject src
= (AsciiSrcObject
) w
;
694 if (src
->ascii_src
.type
== XawAsciiString
) {
695 for (i
= 0; i
< *num_args
; i
++ )
696 if (streq(args
[i
].name
, XtNstring
)) {
697 if (src
->ascii_src
.use_string_in_place
) {
698 *((char **) args
[i
].value
) = src
->ascii_src
.first_piece
->text
;
701 if (XawAsciiSave(w
)) /* If save sucessful. */
702 *((char **) args
[i
].value
) = src
->ascii_src
.string
;
709 /* Function Name: Destroy
710 * Description: Destroys an ascii source (frees all data)
711 * Arguments: src - the Ascii source Widget to free.
719 RemoveOldStringOrFile((AsciiSrcObject
) w
, True
);
722 /************************************************************
726 ************************************************************/
728 /* Function Name: XawAsciiSourceFreeString
729 * Description: Frees the string returned by a get values call
730 * on the string when the source is of type string.
731 * Arguments: w - the AsciiSrc widget.
736 #if NeedFunctionPrototypes
737 XawAsciiSourceFreeString(Widget w
)
739 XawAsciiSourceFreeString(w
)
743 AsciiSrcObject src
= (AsciiSrcObject
) w
;
745 /* If the src is really a multi, call the multi routine.*/
747 if ( XtIsSubclass( w
, multiSrcObjectClass
) ) {
748 _XawMultiSourceFreeString( w
);
752 else if ( !XtIsSubclass( w
, asciiSrcObjectClass
) ) {
753 XtErrorMsg("bad argument", "asciiSource", "XawError",
754 "XawAsciiSourceFreeString's parameter must be an asciiSrc or multiSrc.",
758 if (src
->ascii_src
.allocated_string
&& src
->ascii_src
.type
!= XawAsciiFile
) {
759 src
->ascii_src
.allocated_string
= FALSE
;
760 XtFree(src
->ascii_src
.string
);
761 src
->ascii_src
.string
= NULL
;
765 /* Function Name: XawAsciiSave
766 * Description: Saves all the pieces into a file or string as required.
767 * Arguments: w - the asciiSrc Widget.
768 * Returns: TRUE if the save was successful.
771 #if NeedFunctionPrototypes
772 XawAsciiSave(Widget w
)
778 AsciiSrcObject src
= (AsciiSrcObject
) w
;
780 /* If the src is really a multi, call the multi save. */
782 if ( XtIsSubclass( w
, multiSrcObjectClass
) )
783 return( _XawMultiSave( w
) );
785 else if ( !XtIsSubclass( w
, asciiSrcObjectClass
) ) {
786 XtErrorMsg("bad argument", "asciiSource", "XawError",
787 "XawAsciiSave's parameter must be an asciiSrc or multiSrc.",
792 * If using the string in place then there is no need to play games
793 * to get the internal info into a readable string.
796 if (src
->ascii_src
.use_string_in_place
)
799 if (src
->ascii_src
.type
== XawAsciiFile
) {
802 if (!src
->ascii_src
.changes
) /* No changes to save. */
805 string
= StorePiecesInString(src
);
807 if (WriteToFile(string
, src
->ascii_src
.string
) == FALSE
) {
814 if (src
->ascii_src
.allocated_string
== TRUE
)
815 XtFree(src
->ascii_src
.string
);
817 src
->ascii_src
.allocated_string
= TRUE
;
819 src
->ascii_src
.string
= StorePiecesInString(src
);
821 src
->ascii_src
.changes
= FALSE
;
825 /* Function Name: XawAsciiSaveAsFile
826 * Description: Save the current buffer as a file.
827 * Arguments: w - the AsciiSrc widget.
828 * name - name of the file to save this file into.
829 * Returns: True if the save was sucessful.
832 #if NeedFunctionPrototypes
833 XawAsciiSaveAsFile(Widget w
, _Xconst
char* name
)
835 XawAsciiSaveAsFile(w
, name
)
840 AsciiSrcObject src
= (AsciiSrcObject
) w
;
844 /* If the src is really a multi, call the multi save. - */
846 if ( XtIsSubclass( w
, multiSrcObjectClass
) )
847 return( _XawMultiSaveAsFile( w
, name
) );
849 else if ( !XtIsSubclass( w
, asciiSrcObjectClass
) ) {
850 XtErrorMsg("bad argument", "asciiSource", "XawError",
851 "XawAsciiSaveAsFile's 1st parameter must be an asciiSrc or multiSrc.",
855 string
= StorePiecesInString(src
);
857 ret
= WriteToFile(string
, name
);
862 /* Function Name: XawAsciiSourceChanged
863 * Description: Returns true if the source has changed since last saved.
864 * Arguments: w - the ascii source widget.
865 * Returns: a Boolean (see description).
869 #if NeedFunctionPrototypes
870 XawAsciiSourceChanged(Widget w
)
872 XawAsciiSourceChanged(w
)
876 if ( XtIsSubclass( w
, multiSrcObjectClass
) )
877 return( ( (MultiSrcObject
) w
)->multi_src
.changes
);
879 if ( XtIsSubclass( w
, asciiSrcObjectClass
) )
880 return( ( (AsciiSrcObject
) w
)->ascii_src
.changes
);
882 XtErrorMsg("bad argument", "asciiSource", "XawError",
883 "XawAsciiSourceChanged parameter must be an asciiSrc or multiSrc.",
886 return( True
); /* for gcc -Wall */
889 /************************************************************
893 ************************************************************/
896 RemoveOldStringOrFile(src
, checkString
)
902 if (checkString
&& src
->ascii_src
.allocated_string
) {
903 XtFree(src
->ascii_src
.string
);
904 src
->ascii_src
.allocated_string
= False
;
905 src
->ascii_src
.string
= NULL
;
909 /* Function Name: WriteToFile
910 * Description: Write the string specified to the begining of the file
912 * Arguments: string - string to write.
913 * name - the name of the file
914 * Returns: returns TRUE if sucessful, FALSE otherwise.
918 WriteToFile(string
, name
)
923 if ( ((fd
= creat(name
, 0666)) == -1 ) ||
924 (write(fd
, string
, sizeof(unsigned char) * strlen(string
)) == -1) )
927 if ( close(fd
) == -1 )
933 /* Function Name: StorePiecesInString
934 * Description: store the pieces in memory into a standard ascii string.
935 * Arguments: data - the ascii pointer data.
940 StorePiecesInString(src
)
944 XawTextPosition first
;
947 string
= XtMalloc((unsigned) sizeof(unsigned char) *
948 src
->ascii_src
.length
+ 1);
950 for (first
= 0, piece
= src
->ascii_src
.first_piece
; piece
!= NULL
;
951 first
+= piece
->used
, piece
= piece
->next
)
952 strncpy(string
+ first
, piece
->text
, piece
->used
);
954 string
[src
->ascii_src
.length
] = '\0'; /* NULL terminate this sucker. */
957 * This will refill all pieces to capacity.
960 if (src
->ascii_src
.data_compression
) {
962 LoadPieces(src
, NULL
, string
);
968 /* Function Name: InitStringOrFile.
969 * Description: Initializes the string or file.
970 * Arguments: src - the AsciiSource.
971 * Returns: none - May exit though.
975 InitStringOrFile(src
, newString
)
981 char fileName
[TMPSIZ
];
983 if (src
->ascii_src
.type
== XawAsciiString
) {
985 if (src
->ascii_src
.string
== NULL
)
986 src
->ascii_src
.length
= 0;
988 else if (! src
->ascii_src
.use_string_in_place
) {
989 src
->ascii_src
.string
= XtNewString(src
->ascii_src
.string
);
990 src
->ascii_src
.allocated_string
= True
;
991 src
->ascii_src
.length
= strlen(src
->ascii_src
.string
);
994 if (src
->ascii_src
.use_string_in_place
) {
995 src
->ascii_src
.length
= strlen(src
->ascii_src
.string
);
996 /* In case the length resource is incorrectly set */
997 if (src
->ascii_src
.length
> (long)src
->ascii_src
.ascii_length
)
998 src
->ascii_src
.ascii_length
= src
->ascii_src
.length
;
1000 if (src
->ascii_src
.ascii_length
== MAGIC_VALUE
)
1001 src
->ascii_src
.piece_size
= src
->ascii_src
.length
;
1003 src
->ascii_src
.piece_size
= src
->ascii_src
.ascii_length
+ 1;
1010 * type is XawAsciiFile.
1013 src
->ascii_src
.is_tempfile
= FALSE
;
1015 switch (src
->text_src
.edit_mode
) {
1017 if (src
->ascii_src
.string
== NULL
)
1018 XtErrorMsg("NoFile", "asciiSourceCreate", "XawError",
1019 "Creating a read only disk widget and no file specified.",
1025 if (src
->ascii_src
.string
== NULL
) {
1026 src
->ascii_src
.string
= fileName
;
1027 (void) tmpnam(src
->ascii_src
.string
);
1028 src
->ascii_src
.is_tempfile
= TRUE
;
1034 XtErrorMsg("badMode", "asciiSourceCreate", "XawError",
1035 "Bad editMode for ascii source; must be Read, Append or Edit.",
1039 /* Allocate new memory for the temp filename, because it is held in
1040 * a stack variable, not static memory. This widget does not need
1041 * to keep the private state field is_tempfile -- it is only accessed
1042 * in this routine, and its former setting is unused.
1044 if (newString
|| src
->ascii_src
.is_tempfile
) {
1045 src
->ascii_src
.string
= XtNewString(src
->ascii_src
.string
);
1046 src
->ascii_src
.allocated_string
= TRUE
;
1049 if (!src
->ascii_src
.is_tempfile
) {
1050 if ((file
= fopen(src
->ascii_src
.string
, open_mode
)) != 0) {
1051 (void) fseek(file
, (Off_t
)0, 2);
1052 src
->ascii_src
.length
= (XawTextPosition
) ftell(file
);
1056 Cardinal num_params
= 2;
1058 params
[0] = src
->ascii_src
.string
;
1059 params
[1] = strerror(errno
);
1060 XtAppWarningMsg(XtWidgetToApplicationContext((Widget
)src
),
1061 "openError", "asciiSourceCreate", "XawWarning",
1062 "Cannot open file %s; %s", params
, &num_params
);
1065 src
->ascii_src
.length
= 0;
1066 return((FILE *)NULL
);
1070 LoadPieces(src
, file
, string
)
1075 char *local_str
, *ptr
;
1076 Piece
* piece
= NULL
;
1077 XawTextPosition left
;
1079 if (string
== NULL
) {
1080 if (src
->ascii_src
.type
== XawAsciiFile
) {
1081 local_str
= XtMalloc((unsigned) (src
->ascii_src
.length
+ 1)
1082 * sizeof(unsigned char));
1083 if (src
->ascii_src
.length
!= 0) {
1084 fseek(file
, (Off_t
)0, 0);
1085 src
->ascii_src
.length
= fread(local_str
, (Size_t
)sizeof(unsigned char),
1086 (Size_t
)src
->ascii_src
.length
, file
);
1087 if (src
->ascii_src
.length
<= 0)
1088 XtErrorMsg("readError", "asciiSourceCreate", "XawError",
1089 "fread returned error.", NULL
, NULL
);
1091 local_str
[src
->ascii_src
.length
] = '\0';
1094 local_str
= src
->ascii_src
.string
;
1099 if (src
->ascii_src
.use_string_in_place
) {
1100 piece
= AllocNewPiece(src
, piece
);
1101 piece
->used
= Min(src
->ascii_src
.length
, src
->ascii_src
.piece_size
);
1102 piece
->text
= src
->ascii_src
.string
;
1107 left
= src
->ascii_src
.length
;
1110 piece
= AllocNewPiece(src
, piece
);
1112 piece
->text
= XtMalloc((unsigned)src
->ascii_src
.piece_size
1113 * sizeof(unsigned char));
1114 piece
->used
= Min(left
, src
->ascii_src
.piece_size
);
1115 if (piece
->used
!= 0)
1116 strncpy(piece
->text
, ptr
, piece
->used
);
1118 left
-= piece
->used
;
1122 if ( (src
->ascii_src
.type
== XawAsciiFile
) && (string
== NULL
) )
1126 /* Function Name: AllocNewPiece
1127 * Description: Allocates a new piece of memory.
1128 * Arguments: src - The AsciiSrc Widget.
1129 * prev - the piece just before this one, or NULL.
1130 * Returns: the allocated piece.
1134 AllocNewPiece(src
, prev
)
1138 Piece
* piece
= XtNew(Piece
);
1141 src
->ascii_src
.first_piece
= piece
;
1145 if (prev
->next
!= NULL
)
1146 (prev
->next
)->prev
= piece
;
1147 piece
->next
= prev
->next
;
1156 /* Function Name: FreeAllPieces
1157 * Description: Frees all the pieces
1158 * Arguments: src - The AsciiSrc Widget.
1166 Piece
* next
, * first
= src
->ascii_src
.first_piece
;
1168 if (first
->prev
!= NULL
)
1169 (void) printf("Xaw AsciiSrc Object: possible memory leak in FreeAllPieces().\n");
1171 for ( ; first
!= NULL
; first
= next
) {
1173 RemovePiece(src
, first
);
1177 /* Function Name: RemovePiece
1178 * Description: Removes a piece from the list.
1180 * piece - the piece to remove.
1185 RemovePiece(src
, piece
)
1189 if (piece
->prev
== NULL
)
1190 src
->ascii_src
.first_piece
= piece
->next
;
1192 (piece
->prev
)->next
= piece
->next
;
1194 if (piece
->next
!= NULL
)
1195 (piece
->next
)->prev
= piece
->prev
;
1197 if (!src
->ascii_src
.use_string_in_place
)
1198 XtFree(piece
->text
);
1200 XtFree((char *)piece
);
1203 /* Function Name: FindPiece
1204 * Description: Finds the piece containing the position indicated.
1205 * Arguments: src - The AsciiSrc Widget.
1206 * position - the position that we are searching for.
1207 * RETURNED first - the position of the first character in this piece.
1208 * Returns: piece - the piece that contains this position.
1212 FindPiece(src
, position
, first
)
1214 XawTextPosition position
, *first
;
1216 Piece
* old_piece
, * piece
= src
->ascii_src
.first_piece
;
1217 XawTextPosition temp
;
1219 for ( temp
= 0 ; piece
!= NULL
; temp
+= piece
->used
, piece
= piece
->next
) {
1223 if ((temp
+ piece
->used
) > position
)
1226 return(old_piece
); /* if we run off the end the return the last piece */
1229 /* Function Name: MyStrncpy
1230 * Description: Just like string copy, but slower and will always
1231 * work on overlapping strings.
1232 * Arguments: (same as strncpy) - s1, s2 - strings to copy (2->1).
1233 * n - the number of chars to copy.
1238 MyStrncpy(s1
, s2
, n
)
1245 if (n
== 0) return s1
;
1247 if (n
< sizeof buf
) temp
= buf
;
1248 else temp
= XtMalloc((unsigned)sizeof(unsigned char) * n
);
1250 strncpy(temp
, s2
, n
); /* Saber has a bug that causes it to generate*/
1251 strncpy(s1
, temp
, n
); /* a bogus warning message here (CDP 6/32/89)*/
1252 if (temp
!= buf
) XtFree(temp
);
1256 /* Function Name: BreakPiece
1257 * Description: Breaks a full piece into two new pieces.
1258 * Arguments: src - The AsciiSrc Widget.
1259 * piece - the piece to break.
1263 #define HALF_PIECE (src->ascii_src.piece_size/2)
1266 BreakPiece(src
, piece
)
1270 Piece
* new = AllocNewPiece(src
, piece
);
1272 new->text
= XtMalloc(src
->ascii_src
.piece_size
* sizeof(unsigned char));
1273 strncpy(new->text
, piece
->text
+ HALF_PIECE
,
1274 src
->ascii_src
.piece_size
- HALF_PIECE
);
1275 piece
->used
= HALF_PIECE
;
1276 new->used
= src
->ascii_src
.piece_size
- HALF_PIECE
;
1281 CvtStringToAsciiType(args
, num_args
, fromVal
, toVal
)
1282 XrmValuePtr args
; /* unused */
1283 Cardinal
*num_args
; /* unused */
1284 XrmValuePtr fromVal
;
1287 static XawAsciiType type
;
1288 static XrmQuark XtQEstring
= NULLQUARK
;
1289 static XrmQuark XtQEfile
;
1293 if (XtQEstring
== NULLQUARK
) {
1294 XtQEstring
= XrmPermStringToQuark(XtEstring
);
1295 XtQEfile
= XrmPermStringToQuark(XtEfile
);
1298 if (strlen ((char*)fromVal
->addr
) < sizeof lowerName
) {
1299 XmuCopyISOLatin1Lowered(lowerName
, (char *) fromVal
->addr
);
1300 q
= XrmStringToQuark(lowerName
);
1302 if (q
== XtQEstring
) type
= XawAsciiString
;
1303 else if (q
== XtQEfile
) type
= XawAsciiFile
;
1309 toVal
->size
= sizeof type
;
1310 toVal
->addr
= (XPointer
) &type
;
1317 #if (defined(ASCII_STRING) || defined(ASCII_DISK))
1318 # include <X11/Xaw/Cardinals.h>
1322 /************************************************************
1324 * Compatability functions.
1326 ************************************************************/
1328 /* Function Name: AsciiStringSourceCreate
1329 * Description: Creates a string source.
1330 * Arguments: parent - the widget that will own this source.
1331 * args, num_args - the argument list.
1332 * Returns: a pointer to the new text source.
1336 XawStringSourceCreate(parent
, args
, num_args
)
1345 XtSetArg(temp
[0], XtNtype
, XawAsciiString
);
1346 XtSetArg(temp
[1], XtNuseStringInPlace
, TRUE
);
1347 ascii_args
= XtMergeArgLists(temp
, TWO
, args
, num_args
);
1349 src
= XtCreateWidget("genericAsciiString", asciiSrcObjectClass
, parent
,
1350 ascii_args
, num_args
+ TWO
);
1351 XtFree((char *)ascii_args
);
1356 * This is hacked up to try to emulate old functionality, it
1357 * may not work, as I have not old code to test it on.
1359 * Chris D. Peterson 8/31/89.
1363 XawTextSetLastPos (w
, lastPos
)
1365 XawTextPosition lastPos
;
1367 AsciiSrcObject src
= (AsciiSrcObject
) XawTextGetSource(w
);
1369 src
->ascii_src
.piece_size
= lastPos
;
1371 #endif /* ASCII_STRING */
1374 /* Function Name: AsciiDiskSourceCreate
1375 * Description: Creates a disk source.
1376 * Arguments: parent - the widget that will own this source.
1377 * args, num_args - the argument list.
1378 * Returns: a pointer to the new text source.
1382 XawDiskSourceCreate(parent
, args
, num_args
)
1392 XtSetArg(temp
[0], XtNtype
, XawAsciiFile
);
1393 ascii_args
= XtMergeArgLists(temp
, ONE
, args
, num_args
);
1396 for (i
= 0; i
< num_args
; i
++)
1397 if (streq(ascii_args
[i
].name
, XtNfile
) ||
1398 streq(ascii_args
[i
].name
, XtCFile
))
1399 ascii_args
[i
].name
= XtNstring
;
1401 src
= XtCreateWidget("genericAsciiDisk", asciiSrcObjectClass
, parent
,
1402 ascii_args
, num_args
);
1403 XtFree((char *)ascii_args
);
1406 #endif /* ASCII_DISK */