1883 lines
44 KiB
C
1883 lines
44 KiB
C
|
/*
|
||
|
|
||
|
Copyright 1989, 1994, 1998 The Open Group
|
||
|
|
||
|
Permission to use, copy, modify, distribute, and sell this software and its
|
||
|
documentation for any purpose is hereby granted without fee, provided that
|
||
|
the above copyright notice appear in all copies and that both that
|
||
|
copyright notice and this permission notice appear in supporting
|
||
|
documentation.
|
||
|
|
||
|
The above copyright notice and this permission notice shall be included in
|
||
|
all copies or substantial portions of the Software.
|
||
|
|
||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
|
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||
|
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
|
||
|
Except as contained in this notice, the name of The Open Group shall not be
|
||
|
used in advertising or otherwise to promote the sale, use or other dealings
|
||
|
in this Software without prior written authorization from The Open Group.
|
||
|
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* AsciiSrc.c - AsciiSrc object. (For use with the text widget).
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#ifdef HAVE_CONFIG_H
|
||
|
#include <config.h>
|
||
|
#endif
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <ctype.h>
|
||
|
#include <errno.h>
|
||
|
#include <X11/IntrinsicP.h>
|
||
|
#include <X11/StringDefs.h>
|
||
|
#include <X11/Xos.h>
|
||
|
#include <X11/Xfuncs.h>
|
||
|
#include <X11/Xmu/CharSet.h>
|
||
|
#include <X11/Xmu/Misc.h>
|
||
|
#include <X11/Xaw/XawInit.h>
|
||
|
#include <X11/Xaw/AsciiSrcP.h>
|
||
|
#include <X11/Xaw/MultiSrcP.h>
|
||
|
#ifndef OLDXAW
|
||
|
#include <X11/Xaw/TextSinkP.h>
|
||
|
#include <X11/Xaw/AsciiSinkP.h>
|
||
|
#endif
|
||
|
#include "Private.h"
|
||
|
|
||
|
#include <sys/types.h>
|
||
|
#include <sys/stat.h>
|
||
|
#include <fcntl.h>
|
||
|
|
||
|
#if (defined(ASCII_STRING) || defined(ASCII_DISK))
|
||
|
#include <X11/Xaw/AsciiText.h> /* for Widget Classes */
|
||
|
#endif
|
||
|
|
||
|
#define MAGIC_VALUE ((XawTextPosition)-1)
|
||
|
#define streq(a, b) (strcmp((a), (b)) == 0)
|
||
|
|
||
|
/*
|
||
|
* Class Methods
|
||
|
*/
|
||
|
static void XawAsciiSrcClassInitialize(void);
|
||
|
static void XawAsciiSrcDestroy(Widget);
|
||
|
static void XawAsciiSrcGetValuesHook(Widget, ArgList, Cardinal*);
|
||
|
static void XawAsciiSrcInitialize(Widget, Widget, ArgList, Cardinal*);
|
||
|
static Boolean XawAsciiSrcSetValues(Widget, Widget, Widget,
|
||
|
ArgList, Cardinal*);
|
||
|
static XawTextPosition ReadText(Widget, XawTextPosition, XawTextBlock*, int);
|
||
|
static int ReplaceText(Widget, XawTextPosition, XawTextPosition,
|
||
|
XawTextBlock*);
|
||
|
static XawTextPosition Scan(Widget, XawTextPosition, XawTextScanType,
|
||
|
XawTextScanDirection, int, Bool);
|
||
|
static XawTextPosition Search(Widget, XawTextPosition, XawTextScanDirection,
|
||
|
XawTextBlock*);
|
||
|
|
||
|
/*
|
||
|
* Prototypes
|
||
|
*/
|
||
|
static Piece *AllocNewPiece(AsciiSrcObject, Piece*);
|
||
|
static void BreakPiece(AsciiSrcObject, Piece*);
|
||
|
static Boolean CvtAsciiTypeToString(Display*, XrmValuePtr, Cardinal*,
|
||
|
XrmValuePtr, XrmValuePtr, XtPointer*);
|
||
|
static void CvtStringToAsciiType(XrmValuePtr, Cardinal*,
|
||
|
XrmValuePtr, XrmValuePtr);
|
||
|
static Piece *FindPiece(AsciiSrcObject, XawTextPosition, XawTextPosition*);
|
||
|
static void FreeAllPieces(AsciiSrcObject);
|
||
|
static FILE *InitStringOrFile(AsciiSrcObject, Bool);
|
||
|
static void LoadPieces(AsciiSrcObject, FILE*, char*);
|
||
|
static void RemoveOldStringOrFile(AsciiSrcObject, Bool);
|
||
|
static void RemovePiece(AsciiSrcObject, Piece*);
|
||
|
static char * StorePiecesInString(AsciiSrcObject);
|
||
|
static Bool WriteToFile(String, String, unsigned);
|
||
|
static Bool WritePiecesToFile(AsciiSrcObject, String);
|
||
|
static void GetDefaultPieceSize(Widget, int, XrmValue*);
|
||
|
|
||
|
/*
|
||
|
* More Prototypes
|
||
|
*/
|
||
|
#ifdef ASCII_DISK
|
||
|
Widget XawAsciiDiskSourceCreate(Widget, ArgList, Cardinal);
|
||
|
#endif
|
||
|
#ifdef ASCII_STRING
|
||
|
Widget XawStringSourceCreate(Widget, ArgList, Cardinal);
|
||
|
void XawTextSetLastPos(Widget, XawTextPosition);
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* Initialization
|
||
|
*/
|
||
|
#define offset(field) XtOffsetOf(AsciiSrcRec, ascii_src.field)
|
||
|
static XtResource resources[] = {
|
||
|
{
|
||
|
XtNstring,
|
||
|
XtCString,
|
||
|
XtRString,
|
||
|
sizeof(char*),
|
||
|
offset(string),
|
||
|
XtRString,
|
||
|
NULL
|
||
|
},
|
||
|
{
|
||
|
XtNtype,
|
||
|
XtCType,
|
||
|
XtRAsciiType,
|
||
|
sizeof(XawAsciiType),
|
||
|
offset(type),
|
||
|
XtRImmediate,
|
||
|
(XtPointer)XawAsciiString
|
||
|
},
|
||
|
{
|
||
|
XtNdataCompression,
|
||
|
XtCDataCompression,
|
||
|
XtRBoolean,
|
||
|
sizeof(Boolean),
|
||
|
offset(data_compression),
|
||
|
XtRImmediate,
|
||
|
(XtPointer)True
|
||
|
},
|
||
|
{
|
||
|
XtNpieceSize,
|
||
|
XtCPieceSize,
|
||
|
XtRInt,
|
||
|
sizeof(XawTextPosition),
|
||
|
offset(piece_size),
|
||
|
XtRCallProc,
|
||
|
(XtPointer)GetDefaultPieceSize
|
||
|
},
|
||
|
#ifdef OLDXAW
|
||
|
{
|
||
|
XtNcallback,
|
||
|
XtCCallback,
|
||
|
XtRCallback,
|
||
|
sizeof(XtPointer),
|
||
|
offset(callback),
|
||
|
XtRCallback,
|
||
|
(XtPointer)NULL
|
||
|
},
|
||
|
#endif
|
||
|
{
|
||
|
XtNuseStringInPlace,
|
||
|
XtCUseStringInPlace,
|
||
|
XtRBoolean,
|
||
|
sizeof(Boolean),
|
||
|
offset(use_string_in_place),
|
||
|
XtRImmediate,
|
||
|
(XtPointer)False
|
||
|
},
|
||
|
{
|
||
|
XtNlength,
|
||
|
XtCLength,
|
||
|
XtRInt,
|
||
|
sizeof(int),
|
||
|
offset(ascii_length),
|
||
|
XtRImmediate,
|
||
|
(XtPointer)MAGIC_VALUE
|
||
|
},
|
||
|
#ifdef ASCII_DISK
|
||
|
{
|
||
|
XtNfile,
|
||
|
XtCFile,
|
||
|
XtRString,
|
||
|
sizeof(String),
|
||
|
offset(filename),
|
||
|
XtRString,
|
||
|
NULL
|
||
|
},
|
||
|
#endif /* ASCII_DISK */
|
||
|
};
|
||
|
#undef offset
|
||
|
|
||
|
|
||
|
#define Superclass (&textSrcClassRec)
|
||
|
AsciiSrcClassRec asciiSrcClassRec = {
|
||
|
/* object */
|
||
|
{
|
||
|
(WidgetClass)Superclass, /* superclass */
|
||
|
"AsciiSrc", /* class_name */
|
||
|
sizeof(AsciiSrcRec), /* widget_size */
|
||
|
XawAsciiSrcClassInitialize, /* class_initialize */
|
||
|
NULL, /* class_part_initialize */
|
||
|
False, /* class_inited */
|
||
|
XawAsciiSrcInitialize, /* initialize */
|
||
|
NULL, /* initialize_hook */
|
||
|
NULL, /* realize */
|
||
|
NULL, /* actions */
|
||
|
0, /* num_actions */
|
||
|
resources, /* resources */
|
||
|
XtNumber(resources), /* num_resources */
|
||
|
NULLQUARK, /* xrm_class */
|
||
|
False, /* compress_motion */
|
||
|
False, /* compress_exposure */
|
||
|
False, /* compress_enterleave */
|
||
|
False, /* visible_interest */
|
||
|
XawAsciiSrcDestroy, /* destroy */
|
||
|
NULL, /* resize */
|
||
|
NULL, /* expose */
|
||
|
XawAsciiSrcSetValues, /* set_values */
|
||
|
NULL, /* set_values_hook */
|
||
|
NULL, /* set_values_almost */
|
||
|
XawAsciiSrcGetValuesHook, /* get_values_hook */
|
||
|
NULL, /* accept_focus */
|
||
|
XtVersion, /* version */
|
||
|
NULL, /* callback_private */
|
||
|
NULL, /* tm_table */
|
||
|
NULL, /* query_geometry */
|
||
|
NULL, /* display_accelerator */
|
||
|
NULL, /* extension */
|
||
|
},
|
||
|
/* text_src */
|
||
|
{
|
||
|
ReadText, /* Read */
|
||
|
ReplaceText, /* Replace */
|
||
|
Scan, /* Scan */
|
||
|
Search, /* Search */
|
||
|
XtInheritSetSelection, /* SetSelection */
|
||
|
XtInheritConvertSelection, /* ConvertSelection */
|
||
|
},
|
||
|
/* ascii_src */
|
||
|
{
|
||
|
NULL, /* extension */
|
||
|
},
|
||
|
};
|
||
|
|
||
|
WidgetClass asciiSrcObjectClass = (WidgetClass)&asciiSrcClassRec;
|
||
|
|
||
|
static XrmQuark Qstring, Qfile;
|
||
|
|
||
|
/*
|
||
|
* Implementation
|
||
|
*/
|
||
|
/*
|
||
|
* Function:
|
||
|
* XawAsciiSrcClassInitialize()
|
||
|
*
|
||
|
* Description:
|
||
|
* Initializes the asciiSrcObjectClass and install the converters for
|
||
|
* AsciiType <-> String.
|
||
|
*/
|
||
|
static void
|
||
|
XawAsciiSrcClassInitialize(void)
|
||
|
{
|
||
|
XawInitializeWidgetSet();
|
||
|
Qstring = XrmPermStringToQuark(XtEstring);
|
||
|
Qfile = XrmPermStringToQuark(XtEfile);
|
||
|
XtAddConverter(XtRString, XtRAsciiType, CvtStringToAsciiType, NULL, 0);
|
||
|
XtSetTypeConverter(XtRAsciiType, XtRString, CvtAsciiTypeToString,
|
||
|
NULL, 0, XtCacheNone, NULL);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function:
|
||
|
* XawAsciiSrcInitialize
|
||
|
*
|
||
|
* Parameters:
|
||
|
* request - widget requested by the argument list
|
||
|
* cnew - new widget with both resource and non resource values
|
||
|
* args - (unused)
|
||
|
* num_args - (unused)
|
||
|
*
|
||
|
* Description:
|
||
|
* Initializes the ascii src object.
|
||
|
*/
|
||
|
/*ARGSUSED*/
|
||
|
static void
|
||
|
XawAsciiSrcInitialize(Widget request _X_UNUSED, Widget cnew,
|
||
|
ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED)
|
||
|
{
|
||
|
AsciiSrcObject src = (AsciiSrcObject)cnew;
|
||
|
FILE *file;
|
||
|
|
||
|
/*
|
||
|
* Set correct flags (override resources) depending upon widget class
|
||
|
*/
|
||
|
src->text_src.text_format = (XrmQuark)XawFmt8Bit;
|
||
|
|
||
|
#ifdef ASCII_DISK
|
||
|
if (XtIsSubclass(XtParent(cnew), asciiDiskWidgetClass)) {
|
||
|
src->ascii_src.type = XawAsciiFile;
|
||
|
src->ascii_src.string = src->ascii_src.filename;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#ifdef ASCII_STRING
|
||
|
if (XtIsSubclass(XtParent(cnew), asciiStringWidgetClass)) {
|
||
|
src->ascii_src.use_string_in_place = True;
|
||
|
src->ascii_src.type = XawAsciiString;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#ifdef OLDXAW
|
||
|
src->ascii_src.changes = False;
|
||
|
#else
|
||
|
src->text_src.changed = False;
|
||
|
#endif
|
||
|
src->ascii_src.allocated_string = False;
|
||
|
|
||
|
if (src->ascii_src.use_string_in_place && src->ascii_src.string == NULL)
|
||
|
src->ascii_src.use_string_in_place = False;
|
||
|
|
||
|
file = InitStringOrFile(src, src->ascii_src.type == XawAsciiFile);
|
||
|
LoadPieces(src, file, NULL);
|
||
|
|
||
|
if (file != NULL)
|
||
|
fclose(file);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function:
|
||
|
* ReadText
|
||
|
*
|
||
|
* Parameters:
|
||
|
* w - AsciiSource widget
|
||
|
* pos - position of the text to retrieve.
|
||
|
* text - text block that will contain returned text
|
||
|
* length - maximum number of characters to read
|
||
|
*
|
||
|
* Description:
|
||
|
* This function reads the source.
|
||
|
*
|
||
|
* Returns:
|
||
|
* The character position following the retrieved text.
|
||
|
*/
|
||
|
static XawTextPosition
|
||
|
ReadText(Widget w, XawTextPosition pos, XawTextBlock *text, int length)
|
||
|
{
|
||
|
AsciiSrcObject src = (AsciiSrcObject)w;
|
||
|
XawTextPosition count, start;
|
||
|
Piece *piece;
|
||
|
#ifndef OLDXAW
|
||
|
XawTextAnchor *anchor;
|
||
|
XawTextEntity *entity;
|
||
|
XawTextPosition offset, end = pos + length;
|
||
|
Bool state;
|
||
|
|
||
|
end = XawMin(end, src->ascii_src.length);
|
||
|
while ((state = XawTextSourceAnchorAndEntity(w, pos, &anchor, &entity)) &&
|
||
|
(entity->flags & XAW_TENTF_HIDE))
|
||
|
pos = anchor->position + entity->offset + entity->length;
|
||
|
if (state == False ||
|
||
|
!(entity->flags & XAW_TENTF_REPLACE)) {
|
||
|
while (entity) {
|
||
|
offset = anchor->position + entity->offset;
|
||
|
if (offset >= end)
|
||
|
break;
|
||
|
if (offset > pos &&
|
||
|
(entity->flags & (XAW_TENTF_HIDE | XAW_TENTF_REPLACE))) {
|
||
|
end = XawMin(end, offset);
|
||
|
break;
|
||
|
}
|
||
|
if ((entity = entity->next) == NULL &&
|
||
|
(anchor = XawTextSourceNextAnchor(w, anchor)) != NULL)
|
||
|
entity = anchor->entities;
|
||
|
}
|
||
|
}
|
||
|
else if (state && (entity->flags & XAW_TENTF_REPLACE) && pos < end) {
|
||
|
XawTextBlock *block = (XawTextBlock*)entity->data;
|
||
|
|
||
|
offset = anchor->position + entity->offset;
|
||
|
end = XawMin(end, offset + block->length);
|
||
|
if ((length = (int)(end - pos)) < 0)
|
||
|
length = 0;
|
||
|
text->length = length;
|
||
|
text->format = XawFmt8Bit;
|
||
|
if (length == 0) {
|
||
|
text->firstPos = (int)(end = (offset + entity->length));
|
||
|
text->ptr = "";
|
||
|
}
|
||
|
else {
|
||
|
text->firstPos = (int)pos;
|
||
|
text->ptr = block->ptr + (pos - offset);
|
||
|
if (pos + length < offset + block->length)
|
||
|
end = pos + length; /* there is data left to be read */
|
||
|
else
|
||
|
end = offset + entity->length;
|
||
|
}
|
||
|
|
||
|
return (end);
|
||
|
}
|
||
|
|
||
|
if ((length = (int)(end - pos)) < 0)
|
||
|
length = 0;
|
||
|
#endif
|
||
|
|
||
|
piece = FindPiece(src, pos, &start);
|
||
|
text->firstPos = (int)pos;
|
||
|
text->ptr = piece->text + (pos - start);
|
||
|
count = piece->used - (pos - start);
|
||
|
text->length = (Max(0, (length > count) ? count : length));
|
||
|
text->format = XawFmt8Bit;
|
||
|
|
||
|
return (pos + text->length);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function:
|
||
|
* ReplaceText
|
||
|
*
|
||
|
* Parameters:
|
||
|
* w - AsciiSource object
|
||
|
* startPos - ends of text that will be replaced
|
||
|
* endPos - ""
|
||
|
* text - new text to be inserted into buffer at startPos
|
||
|
*
|
||
|
* Description:
|
||
|
* Replaces a block of text with new text.
|
||
|
*
|
||
|
* Returns:
|
||
|
* XawEditDone on success, XawEditError otherwise
|
||
|
*/
|
||
|
/*ARGSUSED*/
|
||
|
static int
|
||
|
ReplaceText(Widget w, XawTextPosition startPos, XawTextPosition endPos,
|
||
|
XawTextBlock *text)
|
||
|
{
|
||
|
AsciiSrcObject src = (AsciiSrcObject)w;
|
||
|
Piece *start_piece, *end_piece, *temp_piece;
|
||
|
XawTextPosition start_first, end_first;
|
||
|
int length, firstPos;
|
||
|
|
||
|
/*
|
||
|
* Editing a read only source is not allowed
|
||
|
*/
|
||
|
if (src->text_src.edit_mode == XawtextRead)
|
||
|
return (XawEditError);
|
||
|
|
||
|
start_piece = FindPiece(src, startPos, &start_first);
|
||
|
end_piece = FindPiece(src, endPos, &end_first);
|
||
|
|
||
|
#ifndef OLDXAW
|
||
|
/*
|
||
|
* This is a big hack, but I can't think about a clever way to know
|
||
|
* if the character being moved forward has a negative lbearing.
|
||
|
*
|
||
|
*/
|
||
|
if (start_piece->used) {
|
||
|
int i;
|
||
|
|
||
|
for (i = 0; i < src->text_src.num_text; i++) {
|
||
|
int line;
|
||
|
TextWidget ctx = (TextWidget)src->text_src.text[i];
|
||
|
|
||
|
for (line = 0; line < ctx->text.lt.lines; line++)
|
||
|
if (startPos < ctx->text.lt.info[line + 1].position)
|
||
|
break;
|
||
|
if (i < ctx->text.lt.lines &&
|
||
|
startPos > ctx->text.lt.info[i].position) {
|
||
|
AsciiSinkObject sink = (AsciiSinkObject)ctx->text.sink;
|
||
|
XawTextAnchor *anchor;
|
||
|
XawTextEntity *entity;
|
||
|
XawTextProperty *property;
|
||
|
XFontStruct *font;
|
||
|
|
||
|
if (XawTextSourceAnchorAndEntity(w, startPos, &anchor, &entity) &&
|
||
|
(property = XawTextSinkGetProperty(ctx->text.sink,
|
||
|
entity->property)) != NULL &&
|
||
|
(property->mask & XAW_TPROP_FONT))
|
||
|
font = property->font;
|
||
|
else
|
||
|
font = sink->ascii_sink.font;
|
||
|
|
||
|
if (font->min_bounds.lbearing < 0) {
|
||
|
int lbearing = font->min_bounds.lbearing;
|
||
|
unsigned char c = *(unsigned char*)
|
||
|
(start_piece->text + (startPos - start_first));
|
||
|
|
||
|
if (c == '\t' || c == '\n')
|
||
|
c = ' ';
|
||
|
else if ((c & 0177) < XawSP || c == 0177) {
|
||
|
if (sink->ascii_sink.display_nonprinting)
|
||
|
c = (unsigned char)(c > 0177 ? '\\' : c + '^');
|
||
|
else
|
||
|
c = ' ';
|
||
|
}
|
||
|
if (font->per_char &&
|
||
|
(c >= font->min_char_or_byte2 && c <= font->max_char_or_byte2))
|
||
|
lbearing = font->per_char[c - font->min_char_or_byte2].lbearing;
|
||
|
if (lbearing < 0)
|
||
|
_XawTextNeedsUpdating(ctx, startPos - 1, startPos);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* Remove Old Stuff
|
||
|
*/
|
||
|
if (start_piece != end_piece) {
|
||
|
temp_piece = start_piece->next;
|
||
|
|
||
|
/*
|
||
|
* If empty and not the only piece then remove it.
|
||
|
*/
|
||
|
if (((start_piece->used = startPos - start_first) == 0)
|
||
|
&& !(start_piece->next == NULL && start_piece->prev == NULL))
|
||
|
RemovePiece(src, start_piece);
|
||
|
|
||
|
while (temp_piece != end_piece) {
|
||
|
temp_piece = temp_piece->next;
|
||
|
RemovePiece(src, temp_piece->prev);
|
||
|
}
|
||
|
|
||
|
end_piece->used -= endPos - end_first;
|
||
|
if (end_piece->used != 0)
|
||
|
memmove(end_piece->text, end_piece->text + endPos - end_first,
|
||
|
(unsigned)end_piece->used);
|
||
|
}
|
||
|
else { /* We are fully in one piece */
|
||
|
if ((start_piece->used -= endPos - startPos) == 0) {
|
||
|
if (!(start_piece->next == NULL && start_piece->prev == NULL))
|
||
|
RemovePiece(src, start_piece);
|
||
|
}
|
||
|
else {
|
||
|
memmove(start_piece->text + (startPos - start_first),
|
||
|
start_piece->text + (endPos - start_first),
|
||
|
(unsigned)(start_piece->used - (startPos - start_first)));
|
||
|
if (src->ascii_src.use_string_in_place
|
||
|
&& src->ascii_src.length - (endPos - startPos)
|
||
|
< src->ascii_src.piece_size - 1)
|
||
|
start_piece->text[src->ascii_src.length - (endPos - startPos)] =
|
||
|
'\0';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
src->ascii_src.length += -(endPos - startPos) + text->length;
|
||
|
|
||
|
if ( text->length != 0) {
|
||
|
/*
|
||
|
* Put in the New Stuff
|
||
|
*/
|
||
|
start_piece = FindPiece(src, startPos, &start_first);
|
||
|
|
||
|
length = text->length;
|
||
|
firstPos = text->firstPos;
|
||
|
|
||
|
while (length > 0) {
|
||
|
char *ptr;
|
||
|
int fill;
|
||
|
|
||
|
if (src->ascii_src.use_string_in_place) {
|
||
|
if (start_piece->used == src->ascii_src.piece_size - 1) {
|
||
|
/*
|
||
|
* If we are in ascii string emulation mode. Then the
|
||
|
* string is not allowed to grow
|
||
|
*/
|
||
|
start_piece->used = src->ascii_src.length =
|
||
|
src->ascii_src.piece_size - 1;
|
||
|
start_piece->text[src->ascii_src.length] = '\0';
|
||
|
return (XawEditError);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (start_piece->used == src->ascii_src.piece_size) {
|
||
|
BreakPiece(src, start_piece);
|
||
|
start_piece = FindPiece(src, startPos, &start_first);
|
||
|
}
|
||
|
|
||
|
fill = Min((int)(src->ascii_src.piece_size - start_piece->used),
|
||
|
length);
|
||
|
|
||
|
ptr = start_piece->text + (startPos - start_first);
|
||
|
memmove(ptr + fill, ptr,
|
||
|
(unsigned)(start_piece->used - (startPos - start_first)));
|
||
|
memcpy(ptr, text->ptr + firstPos, (unsigned)fill);
|
||
|
|
||
|
startPos += fill;
|
||
|
firstPos += fill;
|
||
|
start_piece->used += fill;
|
||
|
length -= fill;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (src->ascii_src.use_string_in_place)
|
||
|
start_piece->text[start_piece->used] = '\0';
|
||
|
|
||
|
#ifdef OLDXAW
|
||
|
src->ascii_src.changes = True;
|
||
|
XtCallCallbacks(w, XtNcallback, NULL);
|
||
|
#endif
|
||
|
|
||
|
return (XawEditDone);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function:
|
||
|
* Scan
|
||
|
*
|
||
|
* Parameters:
|
||
|
* w - AsciiSource object
|
||
|
* position - position to start scanning
|
||
|
* type - type of thing to scan for
|
||
|
* dir - direction to scan
|
||
|
* count - which occurrence if this thing to search for.
|
||
|
* include - whether or not to include the character found in
|
||
|
* the position that is returned
|
||
|
*
|
||
|
* Description:
|
||
|
* Scans the text source for the number and type of item specified.
|
||
|
*
|
||
|
* Returns:
|
||
|
* The position of the item found
|
||
|
*
|
||
|
* Note:
|
||
|
* While there are only 'n' characters in the file there are n+1
|
||
|
* possible cursor positions (one before the first character and
|
||
|
* one after the last character
|
||
|
*/
|
||
|
static XawTextPosition
|
||
|
Scan(Widget w, register XawTextPosition position, XawTextScanType type,
|
||
|
XawTextScanDirection dir, int count, Bool include)
|
||
|
{
|
||
|
AsciiSrcObject src = (AsciiSrcObject)w;
|
||
|
Piece *piece;
|
||
|
XawTextPosition first, first_eol_position = 0;
|
||
|
register char *ptr, *lim;
|
||
|
register int cnt = count;
|
||
|
register unsigned char c;
|
||
|
|
||
|
if (dir == XawsdLeft) {
|
||
|
if (position <= 0)
|
||
|
return (0);
|
||
|
--position;
|
||
|
}
|
||
|
else if (position >= src->ascii_src.length)
|
||
|
return (src->ascii_src.length);
|
||
|
|
||
|
piece = FindPiece(src, position, &first);
|
||
|
if (piece->used == 0)
|
||
|
return (0);
|
||
|
|
||
|
ptr = (position - first) + piece->text;
|
||
|
|
||
|
if (dir == XawsdRight) {
|
||
|
lim = piece->text + piece->used;
|
||
|
switch (type) {
|
||
|
case XawstEOL:
|
||
|
case XawstParagraph:
|
||
|
case XawstWhiteSpace:
|
||
|
case XawstAlphaNumeric:
|
||
|
for (; cnt > 0; cnt--) {
|
||
|
Bool non_space = False, first_eol = True;
|
||
|
|
||
|
/*CONSTCOND*/
|
||
|
while (True) {
|
||
|
if (ptr >= lim) {
|
||
|
piece = piece->next;
|
||
|
if (piece == NULL) /* End of text */
|
||
|
return (src->ascii_src.length);
|
||
|
ptr = piece->text;
|
||
|
lim = piece->text + piece->used;
|
||
|
}
|
||
|
|
||
|
c = (unsigned char)*ptr++;
|
||
|
++position;
|
||
|
|
||
|
if (type == XawstEOL) {
|
||
|
if (c == '\n')
|
||
|
break;
|
||
|
}
|
||
|
else if (type == XawstAlphaNumeric) {
|
||
|
if (!isalnum(c)) {
|
||
|
if (non_space)
|
||
|
break;
|
||
|
}
|
||
|
else
|
||
|
non_space = True;
|
||
|
}
|
||
|
else if (type == XawstWhiteSpace) {
|
||
|
if (isspace(c)) {
|
||
|
if (non_space)
|
||
|
break;
|
||
|
}
|
||
|
else
|
||
|
non_space = True;
|
||
|
}
|
||
|
else { /* XawstParagraph */
|
||
|
if (first_eol) {
|
||
|
if (c == '\n') {
|
||
|
first_eol_position = position;
|
||
|
first_eol = False;
|
||
|
}
|
||
|
}
|
||
|
else if (c == '\n')
|
||
|
break;
|
||
|
else if (!isspace(c))
|
||
|
first_eol = True;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case XawstPositions:
|
||
|
position += count;
|
||
|
return (position < src->ascii_src.length ?
|
||
|
position : src->ascii_src.length);
|
||
|
case XawstAll:
|
||
|
return (src->ascii_src.length);
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
if (!include) {
|
||
|
if (type == XawstParagraph)
|
||
|
position = first_eol_position;
|
||
|
if (count)
|
||
|
--position;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
lim = piece->text;
|
||
|
switch (type) {
|
||
|
case XawstEOL:
|
||
|
case XawstParagraph:
|
||
|
case XawstWhiteSpace:
|
||
|
case XawstAlphaNumeric:
|
||
|
for (; cnt > 0; cnt--) {
|
||
|
Bool non_space = False, first_eol = True;
|
||
|
|
||
|
/*CONSTCOND*/
|
||
|
while (True) {
|
||
|
if (ptr < lim) {
|
||
|
piece = piece->prev;
|
||
|
if (piece == NULL) /* Beginning of text */
|
||
|
return (0);
|
||
|
ptr = piece->text + piece->used - 1;
|
||
|
lim = piece->text;
|
||
|
}
|
||
|
|
||
|
c = (unsigned char)*ptr--;
|
||
|
--position;
|
||
|
|
||
|
if (type == XawstEOL) {
|
||
|
if (c == '\n')
|
||
|
break;
|
||
|
}
|
||
|
else if (type == XawstAlphaNumeric) {
|
||
|
if (!isalnum(c)) {
|
||
|
if (non_space)
|
||
|
break;
|
||
|
}
|
||
|
else
|
||
|
non_space = True;
|
||
|
}
|
||
|
else if (type == XawstWhiteSpace) {
|
||
|
if (isspace(c)) {
|
||
|
if (non_space)
|
||
|
break;
|
||
|
}
|
||
|
else
|
||
|
non_space = True;
|
||
|
}
|
||
|
else { /* XawstParagraph */
|
||
|
if (first_eol) {
|
||
|
if (c == '\n') {
|
||
|
first_eol_position = position;
|
||
|
first_eol = False;
|
||
|
}
|
||
|
}
|
||
|
else if (c == '\n')
|
||
|
break;
|
||
|
else if (!isspace(c))
|
||
|
first_eol = True;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case XawstPositions:
|
||
|
position -= count - 1;
|
||
|
return (position > 0 ? position : 0);
|
||
|
case XawstAll:
|
||
|
return (0);
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
if (!include) {
|
||
|
if (type == XawstParagraph)
|
||
|
position = first_eol_position;
|
||
|
if (count)
|
||
|
++position;
|
||
|
}
|
||
|
position++;
|
||
|
}
|
||
|
|
||
|
return (position);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function:
|
||
|
* Search
|
||
|
*
|
||
|
* Parameters:
|
||
|
* w - AsciiSource object
|
||
|
* position - the position to start scanning
|
||
|
* dir - direction to scan
|
||
|
* text - text block to search for
|
||
|
*
|
||
|
* Description:
|
||
|
* Searches the text source for the text block passed.
|
||
|
*
|
||
|
* Returns:
|
||
|
* The position of the item found
|
||
|
*/
|
||
|
static XawTextPosition
|
||
|
Search(Widget w, register XawTextPosition position, XawTextScanDirection dir,
|
||
|
XawTextBlock *text)
|
||
|
{
|
||
|
AsciiSrcObject src = (AsciiSrcObject)w;
|
||
|
register int count = 0;
|
||
|
register char *ptr, c;
|
||
|
char *str;
|
||
|
Piece *piece;
|
||
|
char *buf;
|
||
|
XawTextPosition first;
|
||
|
int cnt, case_sensitive;
|
||
|
|
||
|
if (dir == XawsdLeft) {
|
||
|
if (position == 0)
|
||
|
return (XawTextSearchError);
|
||
|
position--;
|
||
|
}
|
||
|
|
||
|
buf = XtMalloc((unsigned)sizeof(unsigned char) * (unsigned)text->length);
|
||
|
memcpy(buf, text->ptr, (unsigned)text->length);
|
||
|
piece = FindPiece(src, position, &first);
|
||
|
ptr = (position - first) + piece->text;
|
||
|
case_sensitive = text->firstPos;
|
||
|
|
||
|
if (dir == XawsdRight) {
|
||
|
str = buf;
|
||
|
c = *str;
|
||
|
/*CONSTCOND*/
|
||
|
while (1) {
|
||
|
if (*ptr++ == c
|
||
|
|| (case_sensitive && isalpha((unsigned char)c) && isalpha((unsigned char)ptr[-1])
|
||
|
&& toupper((unsigned char)c) == toupper((unsigned char)ptr[-1]))) {
|
||
|
if (++count == text->length)
|
||
|
break;
|
||
|
c = *++str;
|
||
|
}
|
||
|
else if (count) {
|
||
|
ptr -= count;
|
||
|
str -= count;
|
||
|
position -= count;
|
||
|
count = 0;
|
||
|
c = *str;
|
||
|
|
||
|
if (ptr < piece->text) {
|
||
|
do {
|
||
|
cnt = (int)(piece->text - ptr);
|
||
|
piece = piece->prev;
|
||
|
if (piece == NULL) {
|
||
|
XtFree(buf);
|
||
|
return (XawTextSearchError);
|
||
|
}
|
||
|
ptr = piece->text + piece->used - cnt;
|
||
|
} while (ptr < piece->text);
|
||
|
}
|
||
|
}
|
||
|
position++;
|
||
|
if (ptr >= (piece->text + piece->used)) {
|
||
|
do {
|
||
|
cnt = (int)(ptr - (piece->text + piece->used));
|
||
|
piece = piece->next;
|
||
|
if (piece == NULL) {
|
||
|
XtFree(buf);
|
||
|
return (XawTextSearchError);
|
||
|
}
|
||
|
ptr = piece->text + cnt;
|
||
|
} while (ptr >= (piece->text + piece->used));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
position -= text->length - 1;
|
||
|
}
|
||
|
else {
|
||
|
str = buf + text->length - 1;
|
||
|
c = *str;
|
||
|
/*CONSTCOND*/
|
||
|
while (1) {
|
||
|
if (*ptr-- == c
|
||
|
|| (case_sensitive && isalpha((unsigned char)c) && isalpha((unsigned char)ptr[1])
|
||
|
&& toupper((unsigned char)c) == toupper((unsigned char)ptr[1]))) {
|
||
|
if (++count == text->length)
|
||
|
break;
|
||
|
c = *--str;
|
||
|
}
|
||
|
else if (count) {
|
||
|
ptr += count;
|
||
|
str += count;
|
||
|
position += count;
|
||
|
count = 0;
|
||
|
c = *str;
|
||
|
|
||
|
if (ptr >= (piece->text + piece->used)) {
|
||
|
do {
|
||
|
cnt = (int)(ptr - (piece->text + piece->used));
|
||
|
piece = piece->next;
|
||
|
if (piece == NULL) {
|
||
|
XtFree(buf);
|
||
|
return (XawTextSearchError);
|
||
|
}
|
||
|
ptr = piece->text + cnt;
|
||
|
} while (ptr >= (piece->text + piece->used));
|
||
|
}
|
||
|
}
|
||
|
position--;
|
||
|
if (ptr < piece->text) {
|
||
|
do {
|
||
|
cnt = (int)(piece->text - ptr);
|
||
|
piece = piece->prev;
|
||
|
if (piece == NULL) {
|
||
|
XtFree(buf);
|
||
|
return (XawTextSearchError);
|
||
|
}
|
||
|
ptr = piece->text + piece->used - cnt;
|
||
|
} while (ptr < piece->text);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
XtFree(buf);
|
||
|
|
||
|
return (position);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function:
|
||
|
* XawAsciiSrcSetValues
|
||
|
*
|
||
|
* Parameters:
|
||
|
* current - current state of the widget
|
||
|
* request - what was requested
|
||
|
* cnew - what the widget will become
|
||
|
* args - representation of changed resources
|
||
|
* num_args - number of resources that have changed
|
||
|
*
|
||
|
* Description:
|
||
|
* Sets the values for the AsciiSource.
|
||
|
*
|
||
|
* Returns:
|
||
|
* True if redisplay is needed
|
||
|
*/
|
||
|
static Boolean
|
||
|
XawAsciiSrcSetValues(Widget current, Widget request _X_UNUSED, Widget cnew,
|
||
|
ArgList args, Cardinal *num_args)
|
||
|
{
|
||
|
AsciiSrcObject src = (AsciiSrcObject)cnew;
|
||
|
AsciiSrcObject old_src = (AsciiSrcObject)current;
|
||
|
Bool total_reset = False, string_set = False;
|
||
|
FILE *file;
|
||
|
unsigned int i;
|
||
|
|
||
|
if (old_src->ascii_src.use_string_in_place
|
||
|
!= src->ascii_src.use_string_in_place) {
|
||
|
XtAppWarning(XtWidgetToApplicationContext(cnew),
|
||
|
"AsciiSrc: The XtNuseStringInPlace resource may "
|
||
|
"not be changed.");
|
||
|
src->ascii_src.use_string_in_place =
|
||
|
old_src->ascii_src.use_string_in_place;
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < *num_args ; i++)
|
||
|
if (streq(args[i].name, XtNstring)) {
|
||
|
string_set = True;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (string_set || (old_src->ascii_src.type != src->ascii_src.type)) {
|
||
|
RemoveOldStringOrFile(old_src, string_set); /* remove old info */
|
||
|
file = InitStringOrFile(src, string_set); /* Init new info */
|
||
|
LoadPieces(src, file, NULL); /* load new info into internal buffers */
|
||
|
if (file != NULL)
|
||
|
fclose(file);
|
||
|
#ifndef OLDXAW
|
||
|
for (i = 0; i < src->text_src.num_text; i++)
|
||
|
/* Tell text widget what happened */
|
||
|
XawTextSetSource(src->text_src.text[i], cnew, 0);
|
||
|
#else
|
||
|
XawTextSetSource(XtParent(cnew), cnew, 0);
|
||
|
#endif
|
||
|
total_reset = True;
|
||
|
}
|
||
|
|
||
|
if (old_src->ascii_src.ascii_length != src->ascii_src.ascii_length)
|
||
|
src->ascii_src.piece_size = src->ascii_src.ascii_length + 1;
|
||
|
|
||
|
if (!total_reset &&
|
||
|
old_src->ascii_src.piece_size != src->ascii_src.piece_size) {
|
||
|
char * string = StorePiecesInString(old_src);
|
||
|
|
||
|
FreeAllPieces(old_src);
|
||
|
LoadPieces(src, NULL, string);
|
||
|
XtFree(string);
|
||
|
}
|
||
|
|
||
|
return (False);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function:
|
||
|
* XawAsciiSrcGetValuesHook
|
||
|
*
|
||
|
* Parameters:
|
||
|
* w - AsciiSource Widget
|
||
|
* args - argument list
|
||
|
* num_args - number of args
|
||
|
*
|
||
|
* Description:
|
||
|
* This is a get values hook routine that sets the
|
||
|
* values specific to the ascii source.
|
||
|
*/
|
||
|
static void
|
||
|
XawAsciiSrcGetValuesHook(Widget w, ArgList args, Cardinal *num_args)
|
||
|
{
|
||
|
AsciiSrcObject src = (AsciiSrcObject)w;
|
||
|
unsigned int i;
|
||
|
|
||
|
if (src->ascii_src.type == XawAsciiString) {
|
||
|
for (i = 0; i < *num_args ; i++)
|
||
|
if (streq(args[i].name, XtNstring)) {
|
||
|
if (src->ascii_src.use_string_in_place)
|
||
|
*((char **)args[i].value) = src->ascii_src.first_piece->text;
|
||
|
else if (XawAsciiSave(w)) /* If save successful */
|
||
|
*((char **)args[i].value) = src->ascii_src.string;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function:
|
||
|
* XawAsciiSrcDestroy
|
||
|
*
|
||
|
* Parameters:
|
||
|
* src - Ascii source object to free
|
||
|
*
|
||
|
* Description:
|
||
|
* Destroys an ascii source (frees all data)
|
||
|
*/
|
||
|
static void
|
||
|
XawAsciiSrcDestroy(Widget w)
|
||
|
{
|
||
|
RemoveOldStringOrFile((AsciiSrcObject) w, True);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Public routines
|
||
|
*/
|
||
|
/*
|
||
|
* Function:
|
||
|
* XawAsciiSourceFreeString
|
||
|
*
|
||
|
* Parameters:
|
||
|
* w - AsciiSrc widget
|
||
|
*
|
||
|
* Description:
|
||
|
* Frees the string returned by a get values call
|
||
|
* on the string when the source is of type string.
|
||
|
*/
|
||
|
void
|
||
|
XawAsciiSourceFreeString(Widget w)
|
||
|
{
|
||
|
AsciiSrcObject src = (AsciiSrcObject)w;
|
||
|
|
||
|
/* If the src is really a multi, call the multi routine */
|
||
|
if (XtIsSubclass(w, multiSrcObjectClass)) {
|
||
|
_XawMultiSourceFreeString(w);
|
||
|
return;
|
||
|
}
|
||
|
else if (!XtIsSubclass(w, asciiSrcObjectClass)) {
|
||
|
XtErrorMsg("bad argument", "asciiSource", "XawError",
|
||
|
"XawAsciiSourceFreeString's parameter must be "
|
||
|
"an asciiSrc or multiSrc.",
|
||
|
NULL, NULL);
|
||
|
}
|
||
|
|
||
|
if (src->ascii_src.allocated_string && src->ascii_src.type != XawAsciiFile) {
|
||
|
src->ascii_src.allocated_string = False;
|
||
|
XtFree(src->ascii_src.string);
|
||
|
src->ascii_src.string = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function:
|
||
|
* XawAsciiSave
|
||
|
*
|
||
|
* Parameters:
|
||
|
* w - asciiSrc Widget
|
||
|
*
|
||
|
* Description:
|
||
|
* Saves all the pieces into a file or string as required.
|
||
|
*
|
||
|
* Returns:
|
||
|
* True if the save was successful
|
||
|
*/
|
||
|
Bool
|
||
|
XawAsciiSave(Widget w)
|
||
|
{
|
||
|
AsciiSrcObject src = (AsciiSrcObject)w;
|
||
|
|
||
|
/* If the src is really a multi, call the multi save */
|
||
|
if (XtIsSubclass(w, multiSrcObjectClass ))
|
||
|
return (_XawMultiSave(w));
|
||
|
|
||
|
else if (!XtIsSubclass(w, asciiSrcObjectClass))
|
||
|
XtErrorMsg("bad argument", "asciiSource", "XawError",
|
||
|
"XawAsciiSave's parameter must be an asciiSrc or multiSrc.",
|
||
|
NULL, NULL);
|
||
|
|
||
|
/*
|
||
|
* If using the string in place then there is no need to play games
|
||
|
* to get the internal info into a readable string.
|
||
|
*/
|
||
|
if (src->ascii_src.use_string_in_place)
|
||
|
return (True);
|
||
|
|
||
|
if (src->ascii_src.type == XawAsciiFile) {
|
||
|
#ifdef OLDXAW
|
||
|
if (!src->ascii_src.changes)
|
||
|
#else
|
||
|
if (!src->text_src.changed) /* No changes to save */
|
||
|
#endif
|
||
|
return (True);
|
||
|
|
||
|
if (WritePiecesToFile(src, src->ascii_src.string) == False)
|
||
|
return (False);
|
||
|
}
|
||
|
else {
|
||
|
if (src->ascii_src.allocated_string == True)
|
||
|
XtFree(src->ascii_src.string);
|
||
|
else
|
||
|
src->ascii_src.allocated_string = True;
|
||
|
|
||
|
src->ascii_src.string = StorePiecesInString(src);
|
||
|
}
|
||
|
#ifdef OLDXAW
|
||
|
src->ascii_src.changes = False;
|
||
|
#else
|
||
|
src->text_src.changed = False;
|
||
|
#endif
|
||
|
|
||
|
return (True);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function:
|
||
|
* XawAsciiSaveAsFile
|
||
|
*
|
||
|
* Arguments:
|
||
|
* w - AsciiSrc widget
|
||
|
* name - name of the file to save this file into
|
||
|
*
|
||
|
* Description:
|
||
|
* Save the current buffer as a file.
|
||
|
*
|
||
|
* Returns:
|
||
|
* True if the save was successful
|
||
|
*/
|
||
|
Bool
|
||
|
XawAsciiSaveAsFile(Widget w, _Xconst char *name)
|
||
|
{
|
||
|
AsciiSrcObject src = (AsciiSrcObject)w;
|
||
|
Bool ret;
|
||
|
|
||
|
/* If the src is really a multi, call the multi save */
|
||
|
|
||
|
if (XtIsSubclass( w, multiSrcObjectClass))
|
||
|
return (_XawMultiSaveAsFile(w, name));
|
||
|
|
||
|
else if (!XtIsSubclass(w, asciiSrcObjectClass))
|
||
|
XtErrorMsg("bad argument", "asciiSource", "XawError",
|
||
|
"XawAsciiSaveAsFile's 1st parameter must be an "
|
||
|
"asciiSrc or multiSrc.",
|
||
|
NULL, NULL);
|
||
|
|
||
|
if (src->ascii_src.type == XawAsciiFile)
|
||
|
ret = WritePiecesToFile(src, (String)name);
|
||
|
else {
|
||
|
char * string = StorePiecesInString(src);
|
||
|
|
||
|
ret = WriteToFile(string, (String)name, (unsigned)src->ascii_src.length);
|
||
|
XtFree(string);
|
||
|
}
|
||
|
|
||
|
return (ret);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function:
|
||
|
* XawAsciiSourceChanged
|
||
|
*
|
||
|
* Parameters:
|
||
|
* w - ascii source widget
|
||
|
*
|
||
|
* Description:
|
||
|
* Returns true if the source has changed since last saved.
|
||
|
*
|
||
|
* Returns:
|
||
|
* A Boolean (see description).
|
||
|
*/
|
||
|
Bool
|
||
|
XawAsciiSourceChanged(Widget w)
|
||
|
{
|
||
|
#ifdef OLDXAW
|
||
|
if (XtIsSubclass(w, multiSrcObjectClass))
|
||
|
return (((MultiSrcObject)w)->multi_src.changes);
|
||
|
|
||
|
if (XtIsSubclass(w, asciiSrcObjectClass))
|
||
|
return (((AsciiSrcObject)w)->ascii_src.changes);
|
||
|
#else
|
||
|
if (XtIsSubclass(w, textSrcObjectClass))
|
||
|
return (((TextSrcObject)w)->textSrc.changed);
|
||
|
#endif
|
||
|
XtErrorMsg("bad argument", "asciiSource", "XawError",
|
||
|
"XawAsciiSourceChanged parameter must be an "
|
||
|
"asciiSrc or multiSrc.",
|
||
|
NULL, NULL);
|
||
|
|
||
|
return (True);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Private Functions
|
||
|
*/
|
||
|
static void
|
||
|
RemoveOldStringOrFile(AsciiSrcObject src, Bool checkString)
|
||
|
{
|
||
|
FreeAllPieces(src);
|
||
|
|
||
|
if (checkString && src->ascii_src.allocated_string) {
|
||
|
XtFree(src->ascii_src.string);
|
||
|
src->ascii_src.allocated_string = False;
|
||
|
src->ascii_src.string = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function:
|
||
|
* WriteToFile
|
||
|
*
|
||
|
* Parameters:
|
||
|
* string - string to write
|
||
|
* name - the name of the file
|
||
|
*
|
||
|
* Description:
|
||
|
* Write the string specified to the beginning of the file specified.
|
||
|
*
|
||
|
* Returns:
|
||
|
* returns True if successful, False otherwise
|
||
|
*/
|
||
|
static Bool
|
||
|
WriteToFile(String string, String name, unsigned length)
|
||
|
{
|
||
|
int fd;
|
||
|
|
||
|
if ((fd = creat(name, 0666)) == -1)
|
||
|
return (False);
|
||
|
|
||
|
if (write(fd, string, length) == -1) {
|
||
|
close(fd);
|
||
|
return (False);
|
||
|
}
|
||
|
|
||
|
if (close(fd) == -1)
|
||
|
return (False);
|
||
|
|
||
|
return (True);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function:
|
||
|
* WritePiecesToFile
|
||
|
*
|
||
|
* Parameters:
|
||
|
* src - ascii source object
|
||
|
* name - name of the file
|
||
|
*
|
||
|
* Description:
|
||
|
* Almost identical to WriteToFile, but only works for ascii src objects
|
||
|
* of type XawAsciiFile. This function avoids allocating temporary memory,
|
||
|
* what can be useful when editing very large files.
|
||
|
*
|
||
|
* Returns:
|
||
|
* returns True if successful, False otherwise
|
||
|
*/
|
||
|
static Bool
|
||
|
WritePiecesToFile(AsciiSrcObject src, String name)
|
||
|
{
|
||
|
Piece *piece;
|
||
|
int fd;
|
||
|
|
||
|
if (src->ascii_src.data_compression) {
|
||
|
Piece *tmp;
|
||
|
|
||
|
piece = src->ascii_src.first_piece;
|
||
|
while (piece) {
|
||
|
int bytes = (int)(src->ascii_src.piece_size - piece->used);
|
||
|
|
||
|
if (bytes > 0 && (tmp = piece->next) != NULL) {
|
||
|
bytes = (XawMin(bytes, tmp->used));
|
||
|
memcpy(piece->text + piece->used, tmp->text, (size_t)bytes);
|
||
|
memmove(tmp->text, tmp->text + bytes, (size_t)(tmp->used - bytes));
|
||
|
piece->used += bytes;
|
||
|
if ((tmp->used -= bytes) == 0) {
|
||
|
RemovePiece(src, tmp);
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
piece = piece->next;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ((fd = creat(name, 0666)) == -1)
|
||
|
return (False);
|
||
|
|
||
|
for (piece = src->ascii_src.first_piece; piece; piece = piece->next)
|
||
|
if (write(fd, piece->text, (size_t)piece->used) == -1) {
|
||
|
close(fd);
|
||
|
return (False);
|
||
|
}
|
||
|
|
||
|
if (close(fd) == -1)
|
||
|
return (False);
|
||
|
|
||
|
return (True);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function:
|
||
|
* StorePiecesInString
|
||
|
*
|
||
|
* Parameters:
|
||
|
* data - ascii pointer data
|
||
|
*
|
||
|
* Description:
|
||
|
* Store the pieces in memory into a standard ascii string.
|
||
|
*/
|
||
|
static char *
|
||
|
StorePiecesInString(AsciiSrcObject src)
|
||
|
{
|
||
|
char * string;
|
||
|
XawTextPosition first;
|
||
|
Piece *piece;
|
||
|
|
||
|
string = XtMalloc((unsigned)(src->ascii_src.length + 1));
|
||
|
|
||
|
for (first = 0, piece = src->ascii_src.first_piece ; piece != NULL;
|
||
|
first += piece->used, piece = piece->next)
|
||
|
memcpy(string + first, piece->text, (unsigned)piece->used);
|
||
|
|
||
|
string[src->ascii_src.length] = '\0';
|
||
|
|
||
|
/*
|
||
|
* This will refill all pieces to capacity
|
||
|
*/
|
||
|
if (src->ascii_src.data_compression) {
|
||
|
FreeAllPieces(src);
|
||
|
LoadPieces(src, NULL, string);
|
||
|
}
|
||
|
|
||
|
return (string);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function:
|
||
|
* InitStringOrFile
|
||
|
*
|
||
|
* Parameters:
|
||
|
* src - AsciiSource
|
||
|
*
|
||
|
* Description:
|
||
|
* Initializes the string or file.
|
||
|
*/
|
||
|
static FILE *
|
||
|
InitStringOrFile(AsciiSrcObject src, Bool newString)
|
||
|
{
|
||
|
mode_t open_mode = 0;
|
||
|
const char *fdopen_mode = NULL;
|
||
|
int fd;
|
||
|
FILE *file;
|
||
|
|
||
|
if (src->ascii_src.type == XawAsciiString) {
|
||
|
if (src->ascii_src.string == NULL)
|
||
|
src->ascii_src.length = 0;
|
||
|
|
||
|
else if (!src->ascii_src.use_string_in_place) {
|
||
|
src->ascii_src.string = XtNewString(src->ascii_src.string);
|
||
|
src->ascii_src.allocated_string = True;
|
||
|
src->ascii_src.length = (XawTextPosition)strlen(src->ascii_src.string);
|
||
|
}
|
||
|
|
||
|
if (src->ascii_src.use_string_in_place) {
|
||
|
if (src->ascii_src.string != NULL)
|
||
|
src->ascii_src.length = (XawTextPosition)strlen(src->ascii_src.string);
|
||
|
/* In case the length resource is incorrectly set */
|
||
|
if (src->ascii_src.length > src->ascii_src.ascii_length)
|
||
|
src->ascii_src.ascii_length = (int)src->ascii_src.length;
|
||
|
|
||
|
if (src->ascii_src.ascii_length == MAGIC_VALUE)
|
||
|
src->ascii_src.piece_size = src->ascii_src.length;
|
||
|
else
|
||
|
src->ascii_src.piece_size = src->ascii_src.ascii_length + 1;
|
||
|
}
|
||
|
|
||
|
return (NULL);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* type is XawAsciiFile
|
||
|
*/
|
||
|
src->ascii_src.is_tempfile = False;
|
||
|
|
||
|
switch (src->text_src.edit_mode) {
|
||
|
case XawtextRead:
|
||
|
if (src->ascii_src.string == NULL)
|
||
|
XtErrorMsg("NoFile", "asciiSourceCreate", "XawError",
|
||
|
"Creating a read only disk widget and no file specified.",
|
||
|
NULL, NULL);
|
||
|
open_mode = O_RDONLY;
|
||
|
fdopen_mode = "r";
|
||
|
break;
|
||
|
case XawtextAppend:
|
||
|
case XawtextEdit:
|
||
|
if (src->ascii_src.string == NULL) {
|
||
|
src->ascii_src.string = "*ascii-src*";
|
||
|
src->ascii_src.is_tempfile = True;
|
||
|
}
|
||
|
else {
|
||
|
/* O_NOFOLLOW is a FreeBSD & Linux extension */
|
||
|
#ifdef O_NOFOLLOW
|
||
|
open_mode = O_RDWR | O_NOFOLLOW;
|
||
|
#else
|
||
|
open_mode = O_RDWR; /* unsafe; subject to race conditions */
|
||
|
#endif /* O_NOFOLLOW */
|
||
|
fdopen_mode = "r+";
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
XtErrorMsg("badMode", "asciiSourceCreate", "XawError",
|
||
|
"Bad editMode for ascii source; must be Read, "
|
||
|
"Append or Edit.",
|
||
|
NULL, NULL);
|
||
|
}
|
||
|
|
||
|
/* If is_tempfile, allocate a private copy of the text
|
||
|
* Unlikely to be changed, just to set allocated_string */
|
||
|
if (newString || src->ascii_src.is_tempfile) {
|
||
|
src->ascii_src.string = XtNewString(src->ascii_src.string);
|
||
|
src->ascii_src.allocated_string = True;
|
||
|
}
|
||
|
|
||
|
if (!src->ascii_src.is_tempfile) {
|
||
|
if ((fd = open(src->ascii_src.string, (int)open_mode, 0666)) != -1) {
|
||
|
if ((file = fdopen(fd, fdopen_mode))) {
|
||
|
(void)fseek(file, 0, SEEK_END);
|
||
|
src->ascii_src.length = (XawTextPosition)ftell(file);
|
||
|
return (file);
|
||
|
}
|
||
|
else
|
||
|
close(fd);
|
||
|
}
|
||
|
{
|
||
|
String params[2];
|
||
|
Cardinal num_params = 2;
|
||
|
|
||
|
params[0] = src->ascii_src.string;
|
||
|
params[1] = strerror(errno);
|
||
|
XtAppWarningMsg(XtWidgetToApplicationContext((Widget)src),
|
||
|
"openError", "asciiSourceCreate", "XawWarning",
|
||
|
"Cannot open file %s; %s", params, &num_params);
|
||
|
}
|
||
|
}
|
||
|
src->ascii_src.length = 0;
|
||
|
return (NULL);
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
LoadPieces(AsciiSrcObject src, FILE *file, char *string)
|
||
|
{
|
||
|
char *ptr;
|
||
|
Piece *piece = NULL;
|
||
|
XawTextPosition left;
|
||
|
|
||
|
if (string == NULL) {
|
||
|
if (src->ascii_src.type == XawAsciiFile) {
|
||
|
if (src->ascii_src.length != 0) {
|
||
|
int len;
|
||
|
|
||
|
left = 0;
|
||
|
fseek(file, 0, SEEK_SET);
|
||
|
while (left < src->ascii_src.length) {
|
||
|
ptr = XtMalloc((unsigned)src->ascii_src.piece_size);
|
||
|
if ((len = (int)fread(ptr, sizeof(unsigned char),
|
||
|
(size_t)src->ascii_src.piece_size, file)) < 0)
|
||
|
XtErrorMsg("readError", "asciiSourceCreate", "XawError",
|
||
|
"fread returned error.", NULL, NULL);
|
||
|
piece = AllocNewPiece(src, piece);
|
||
|
piece->text = ptr;
|
||
|
piece->used = XawMin(len, src->ascii_src.piece_size);
|
||
|
left += piece->used;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
piece = AllocNewPiece(src, NULL);
|
||
|
piece->text = XtMalloc((unsigned)src->ascii_src.piece_size);
|
||
|
piece->used = 0;
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
else
|
||
|
string = src->ascii_src.string;
|
||
|
}
|
||
|
|
||
|
if (src->ascii_src.use_string_in_place) {
|
||
|
piece = AllocNewPiece(src, piece);
|
||
|
piece->used = XawMin(src->ascii_src.length, src->ascii_src.piece_size);
|
||
|
piece->text = src->ascii_src.string;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
ptr = string;
|
||
|
left = src->ascii_src.length;
|
||
|
do {
|
||
|
piece = AllocNewPiece(src, piece);
|
||
|
|
||
|
piece->text = XtMalloc((unsigned)src->ascii_src.piece_size);
|
||
|
piece->used = XawMin(left, src->ascii_src.piece_size);
|
||
|
if (piece->used != 0)
|
||
|
memcpy(piece->text, ptr, (unsigned)piece->used);
|
||
|
|
||
|
left -= piece->used;
|
||
|
ptr += piece->used;
|
||
|
} while (left > 0);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function:
|
||
|
* AllocNewPiece
|
||
|
*
|
||
|
* Parameters:
|
||
|
* src - AsciiSrc Widget
|
||
|
* prev - piece just before this one, or NULL
|
||
|
*
|
||
|
* Description:
|
||
|
* Allocates a new piece of memory.
|
||
|
*
|
||
|
* Returns:
|
||
|
* The allocated piece
|
||
|
*/
|
||
|
static Piece *
|
||
|
AllocNewPiece(AsciiSrcObject src, Piece *prev)
|
||
|
{
|
||
|
Piece *piece = XtNew(Piece);
|
||
|
|
||
|
if (prev == NULL) {
|
||
|
src->ascii_src.first_piece = piece;
|
||
|
piece->next = NULL;
|
||
|
}
|
||
|
else {
|
||
|
if (prev->next != NULL)
|
||
|
(prev->next)->prev = piece;
|
||
|
piece->next = prev->next;
|
||
|
prev->next = piece;
|
||
|
}
|
||
|
|
||
|
piece->prev = prev;
|
||
|
|
||
|
return (piece);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function:
|
||
|
* FreeAllPieces
|
||
|
*
|
||
|
* Parameters:
|
||
|
* src - AsciiSrc Widget
|
||
|
*
|
||
|
* Description:
|
||
|
* Frees all the pieces.
|
||
|
*/
|
||
|
static void
|
||
|
FreeAllPieces(AsciiSrcObject src)
|
||
|
{
|
||
|
Piece *next, * first = src->ascii_src.first_piece;
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
if (first->prev != NULL)
|
||
|
printf("Xaw AsciiSrc Object: possible memory leak in FreeAllPieces().\n");
|
||
|
#endif
|
||
|
|
||
|
for (; first != NULL ; first = next) {
|
||
|
next = first->next;
|
||
|
RemovePiece(src, first);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function:
|
||
|
* RemovePiece
|
||
|
*
|
||
|
* Parameters:
|
||
|
* piece - piece to remove
|
||
|
*
|
||
|
* Description:
|
||
|
* Removes a piece from the list.
|
||
|
*/
|
||
|
static void
|
||
|
RemovePiece(AsciiSrcObject src, Piece *piece)
|
||
|
{
|
||
|
if (piece->prev == NULL)
|
||
|
src->ascii_src.first_piece = piece->next;
|
||
|
else
|
||
|
piece->prev->next = piece->next;
|
||
|
|
||
|
if (piece->next != NULL)
|
||
|
piece->next->prev = piece->prev;
|
||
|
|
||
|
if (!src->ascii_src.use_string_in_place)
|
||
|
XtFree(piece->text);
|
||
|
|
||
|
XtFree((char *)piece);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function:
|
||
|
* FindPiece
|
||
|
*
|
||
|
* Parameters:
|
||
|
* src - AsciiSrc Widget
|
||
|
* position - position that we are searching for
|
||
|
* first - position of the first character in this piece (return)
|
||
|
*
|
||
|
* Description:
|
||
|
* Finds the piece containing the position indicated.
|
||
|
*
|
||
|
* Returns:
|
||
|
* the piece that contains this position
|
||
|
*/
|
||
|
static Piece *
|
||
|
FindPiece(AsciiSrcObject src, XawTextPosition position, XawTextPosition *first)
|
||
|
{
|
||
|
Piece *old_piece, *piece;
|
||
|
XawTextPosition temp;
|
||
|
|
||
|
for (old_piece = NULL, piece = src->ascii_src.first_piece, temp = 0;
|
||
|
piece; old_piece = piece, piece = piece->next)
|
||
|
if ((temp += piece->used) > position) {
|
||
|
*first = temp - piece->used;
|
||
|
return (piece);
|
||
|
}
|
||
|
|
||
|
*first = temp - (old_piece ? old_piece->used : 0);
|
||
|
|
||
|
return (old_piece); /* if we run off the end the return the last piece */
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Function:
|
||
|
* BreakPiece
|
||
|
*
|
||
|
* Parameters:
|
||
|
* src - AsciiSrc Widget
|
||
|
* piece - piece to break
|
||
|
*
|
||
|
* Description:
|
||
|
* Breaks a full piece into two new pieces.
|
||
|
*/
|
||
|
#define HALF_PIECE (src->ascii_src.piece_size >> 1)
|
||
|
static void
|
||
|
BreakPiece(AsciiSrcObject src, Piece *piece)
|
||
|
{
|
||
|
Piece *cnew = AllocNewPiece(src, piece);
|
||
|
|
||
|
cnew->text = XtMalloc((unsigned)src->ascii_src.piece_size);
|
||
|
memcpy(cnew->text, piece->text + HALF_PIECE,
|
||
|
(unsigned)(src->ascii_src.piece_size - HALF_PIECE));
|
||
|
piece->used = HALF_PIECE;
|
||
|
cnew->used = src->ascii_src.piece_size - HALF_PIECE;
|
||
|
}
|
||
|
|
||
|
/*ARGSUSED*/
|
||
|
static void
|
||
|
CvtStringToAsciiType(XrmValuePtr args _X_UNUSED, Cardinal *num_args _X_UNUSED,
|
||
|
XrmValuePtr fromVal, XrmValuePtr toVal)
|
||
|
{
|
||
|
static XawAsciiType type;
|
||
|
XrmQuark q;
|
||
|
char name[7];
|
||
|
|
||
|
XmuNCopyISOLatin1Lowered(name, (char *)fromVal->addr, sizeof(name));
|
||
|
q = XrmStringToQuark(name);
|
||
|
|
||
|
if (q == Qstring)
|
||
|
type = XawAsciiString;
|
||
|
else if (q == Qfile)
|
||
|
type = XawAsciiFile;
|
||
|
else {
|
||
|
toVal->size = 0;
|
||
|
toVal->addr = NULL;
|
||
|
XtStringConversionWarning((char *)fromVal->addr, XtRAsciiType);
|
||
|
}
|
||
|
|
||
|
toVal->size = sizeof(XawAsciiType);
|
||
|
toVal->addr = (XPointer)&type;
|
||
|
}
|
||
|
|
||
|
/*ARGSUSED*/
|
||
|
static Boolean
|
||
|
CvtAsciiTypeToString(Display *dpy, XrmValuePtr args _X_UNUSED, Cardinal *num_args _X_UNUSED,
|
||
|
XrmValuePtr fromVal, XrmValuePtr toVal,
|
||
|
XtPointer *data _X_UNUSED)
|
||
|
{
|
||
|
static String buffer;
|
||
|
Cardinal size;
|
||
|
|
||
|
switch (*(XawAsciiType *)fromVal->addr) {
|
||
|
case XawAsciiFile:
|
||
|
buffer = XtEfile;
|
||
|
break;
|
||
|
case XawAsciiString:
|
||
|
buffer = XtEstring;
|
||
|
break;
|
||
|
default:
|
||
|
XawTypeToStringWarning(dpy, XtRAsciiType);
|
||
|
toVal->addr = NULL;
|
||
|
toVal->size = 0;
|
||
|
return (False);
|
||
|
}
|
||
|
|
||
|
size = (Cardinal)(strlen(buffer) + 1);
|
||
|
if (toVal->addr != NULL) {
|
||
|
if (toVal->size < size) {
|
||
|
toVal->size = size;
|
||
|
return (False);
|
||
|
}
|
||
|
strcpy((char *)toVal->addr, buffer);
|
||
|
}
|
||
|
else
|
||
|
toVal->addr = (XPointer)buffer;
|
||
|
toVal->size = sizeof(String);
|
||
|
|
||
|
return (True);
|
||
|
}
|
||
|
|
||
|
/*ARGSUSED*/
|
||
|
static void
|
||
|
GetDefaultPieceSize(Widget w _X_UNUSED, int offset _X_UNUSED, XrmValue *value)
|
||
|
{
|
||
|
static XPointer pagesize;
|
||
|
|
||
|
if (pagesize == NULL) {
|
||
|
pagesize = (XPointer)((long)_XawGetPageSize());
|
||
|
if (pagesize < (XPointer)BUFSIZ)
|
||
|
pagesize = (XPointer)BUFSIZ;
|
||
|
}
|
||
|
|
||
|
value->addr = (XPointer)&pagesize;
|
||
|
}
|
||
|
|
||
|
#if (defined(ASCII_STRING) || defined(ASCII_DISK))
|
||
|
# include <X11/Xaw/Cardinals.h>
|
||
|
#endif
|
||
|
|
||
|
#ifdef ASCII_STRING
|
||
|
/*
|
||
|
* Compatibility functions.
|
||
|
*/
|
||
|
/*
|
||
|
* Function:
|
||
|
* AsciiStringSourceCreate
|
||
|
*
|
||
|
* Parameters:
|
||
|
* parent - widget that will own this source
|
||
|
* args - the argument list
|
||
|
* num_args - ""
|
||
|
*
|
||
|
* Description:
|
||
|
* Creates a string source.
|
||
|
*
|
||
|
* Returns:
|
||
|
* A pointer to the new text source.
|
||
|
*/
|
||
|
Widget
|
||
|
XawStringSourceCreate(Widget parent, ArgList args, Cardinal num_args)
|
||
|
{
|
||
|
XawTextSource src;
|
||
|
ArgList ascii_args;
|
||
|
Arg temp[2];
|
||
|
|
||
|
XtSetArg(temp[0], XtNtype, XawAsciiString);
|
||
|
XtSetArg(temp[1], XtNuseStringInPlace, True);
|
||
|
ascii_args = XtMergeArgLists(temp, TWO, args, num_args);
|
||
|
|
||
|
src = XtCreateWidget("genericAsciiString", asciiSrcObjectClass, parent,
|
||
|
ascii_args, num_args + TWO);
|
||
|
XtFree((char *)ascii_args);
|
||
|
|
||
|
return (src);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* This is hacked up to try to emulate old functionality, it
|
||
|
* may not work, as I have not old code to test it on.
|
||
|
*
|
||
|
* Chris D. Peterson 8/31/89.
|
||
|
*/
|
||
|
void
|
||
|
XawTextSetLastPos(Widget w, XawTextPosition lastPos)
|
||
|
{
|
||
|
AsciiSrcObject src = (AsciiSrcObject)XawTextGetSource(w);
|
||
|
|
||
|
src->ascii_src.piece_size = lastPos;
|
||
|
}
|
||
|
#endif /* ASCII_STRING */
|
||
|
|
||
|
#ifdef ASCII_DISK
|
||
|
/*
|
||
|
* Function:
|
||
|
* AsciiDiskSourceCreate
|
||
|
*
|
||
|
* Parameters:
|
||
|
* parent - widget that will own this source
|
||
|
* args - argument list
|
||
|
* num_args - ""
|
||
|
*
|
||
|
* Description:
|
||
|
* Creates a disk source.
|
||
|
*
|
||
|
* Returns:
|
||
|
* A pointer to the new text source
|
||
|
*/
|
||
|
Widget
|
||
|
XawDiskSourceCreate(Widget parent, ArgList args, Cardinal num_args)
|
||
|
{
|
||
|
XawTextSource src;
|
||
|
ArgList ascii_args;
|
||
|
Arg temp[1];
|
||
|
int i;
|
||
|
|
||
|
XtSetArg(temp[0], XtNtype, XawAsciiFile);
|
||
|
ascii_args = XtMergeArgLists(temp, ONE, args, num_args);
|
||
|
num_args++;
|
||
|
|
||
|
for (i = 0; i < num_args; i++)
|
||
|
if (streq(ascii_args[i].name, XtNfile)
|
||
|
|| streq(ascii_args[i].name, XtCFile))
|
||
|
ascii_args[i].name = XtNstring;
|
||
|
|
||
|
src = XtCreateWidget("genericAsciiDisk", asciiSrcObjectClass, parent,
|
||
|
ascii_args, num_args);
|
||
|
XtFree((char *)ascii_args);
|
||
|
|
||
|
return (src);
|
||
|
}
|
||
|
#endif /* ASCII_DISK */
|