1 /*************************************<+>*************************************
2 *****************************************************************************
8 ** Description: Code for TextEdit widget string source
10 *****************************************************************************
12 ** Copyright (c) 1988 by Hewlett-Packard Company
13 ** Copyright (c) 1987, 1988 by Digital Equipment Corporation, Maynard,
14 ** Massachusetts, and the Massachusetts Institute of Technology,
15 ** Cambridge, Massachusetts
17 ** Permission to use, copy, modify, and distribute this software
18 ** and its documentation for any purpose and without fee is hereby
19 ** granted, provided that the above copyright notice appear in all
20 ** copies and that both that copyright notice and this permission
21 ** notice appear in supporting documentation, and that the names of
22 ** Hewlett-Packard, Digital or M.I.T. not be used in advertising or
23 ** publicity pertaining to distribution of the software without
24 ** written prior permission.
26 ** DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
27 ** ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
28 ** DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
29 ** ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
30 ** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
31 ** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
34 *****************************************************************************
35 *************************************<+>*************************************/
37 #include <sys/types.h>
40 #include <X11/IntrinsicP.h>
41 #include <X11/StringDefs.h>
44 #include <Xw/TextEdit.h>
45 #include <Xw/TextEditP.h>
46 #include <Xw/SourceP.h>
48 /* Private StringSource Definitions */
51 #define DEFAULTBUFFERSIZE 512
54 #define Increment(data, position, direction)\
56 if (direction == XwsdLeft) {\
61 if (position < data->length)\
66 static long magic_value
= MAGICVALUE
;
68 static XtResource stringResources
[] = {
69 {XtNstring
, XtCString
, XtRString
, sizeof (char *),
70 XtOffset(StringSourcePtr
, initial_string
), XtRString
, NULL
},
71 {XtNmaximumSize
, XtCMaximumSize
, XtRLong
, sizeof (long),
72 XtOffset(StringSourcePtr
, max_size
), XtRLong
, (caddr_t
)&magic_value
},
73 {XtNeditType
, XtCEditType
, XtREditMode
, sizeof(XwEditType
),
74 XtOffset(StringSourcePtr
, editMode
), XtRString
, "edit"},
77 /*--------------------------------------------------------------------------+*/
78 static unsigned char Look(data
, position
, direction
)
79 /*--------------------------------------------------------------------------+*/
81 XwTextPosition position
;
82 XwScanDirection direction
;
84 /* Looking left at pos 0 or right at position data->length returns newline */
85 if (direction
== XwsdLeft
) {
89 return(data
->buffer
[position
-1]);
92 if (position
== data
->length
)
95 return(data
->buffer
[position
]);
99 /*--------------------------------------------------------------------------+*/
100 static int StringReadText (src
, pos
, text
, maxRead
)
101 /*--------------------------------------------------------------------------+*/
108 StringSourcePtr data
;
110 data
= (StringSourcePtr
) src
->data
;
111 text
->firstPos
= pos
;
112 text
->ptr
= data
->buffer
+ pos
;
113 charsLeft
= data
->length
- pos
;
114 text
->length
= (maxRead
> charsLeft
) ? charsLeft
: maxRead
;
115 return pos
+ text
->length
;
118 /*--------------------------------------------------------------------------+*/
119 static XwEditResult
StringReplaceText (src
, startPos
, endPos
, text
, delta
)
120 /*--------------------------------------------------------------------------+*/
122 XwTextPosition startPos
, endPos
;
126 StringSourcePtr data
;
129 data
= (StringSourcePtr
) src
->data
;
130 switch (data
->editMode
) {
132 if (startPos
!= endPos
|| endPos
!= data
->length
)
133 return (XweditPosError
);
136 return (XweditError
);
140 return (XweditError
);
142 length
= endPos
- startPos
;
143 *delta
= text
->length
- length
;
144 if ((data
->length
+ *delta
) > data
->buffer_size
) {
145 if (data
->max_size_flag
)
146 return (XweditError
);
148 while ((data
->length
+ *delta
) > data
->buffer_size
)
149 data
->buffer_size
+= DEFAULTBUFFERSIZE
;
150 data
->buffer
= (unsigned char *)
151 XtRealloc(data
->buffer
, data
->buffer_size
);
156 if (*delta
< 0) /* insert shorter than delete, text getting
158 for (i
= startPos
; i
< data
->length
+ *delta
; ++i
)
159 data
->buffer
[i
] = data
->buffer
[i
- *delta
];
161 if (*delta
> 0) { /* insert longer than delete, text getting
163 for (i
= data
->length
; i
> startPos
-1; --i
)
164 data
->buffer
[i
+ *delta
] = data
->buffer
[i
];
166 if (text
->length
!= 0) /* do insert */
167 for (i
= 0; i
< text
->length
; ++i
)
168 data
->buffer
[startPos
+ i
] = text
->ptr
[i
];
169 data
->length
= data
->length
+ *delta
;
170 data
->buffer
[data
->length
] = 0;
174 /*--------------------------------------------------------------------------+*/
175 static StringSetLastPos (src
, lastPos
)
176 /*--------------------------------------------------------------------------+*/
178 XwTextPosition lastPos
;
180 ((StringSourceData
*) (src
->data
))->length
= lastPos
;
183 /*--------------------------------------------------------------------------+*/
184 static XwTextPosition
StringGetLastPos (src
)
185 /*--------------------------------------------------------------------------+*/
188 return( ((StringSourceData
*) (src
->data
))->length
);
191 /*--------------------------------------------------------------------------+*/
192 static XwTextPosition
StringScan (src
, pos
, sType
, dir
, count
, include
)
193 /*--------------------------------------------------------------------------+*/
201 StringSourcePtr data
;
202 XwTextPosition position
;
205 int ddir
= (dir
== XwsdRight
) ? 1 : -1;
207 data
= (StringSourcePtr
) src
->data
;
211 if (!include
&& count
> 0)
213 for (i
= 0; i
< count
; i
++) {
214 Increment(data
, position
, dir
);
219 for (i
= 0; i
< count
; i
++) {
221 while (position
>= 0 && position
<= data
->length
) {
222 c
= Look(data
, position
, dir
);
223 if ((c
== ' ') || (c
== '\t') || (c
== '\n')){
224 if (whiteSpace
< 0) whiteSpace
= position
;
225 } else if (whiteSpace
>= 0)
231 if(whiteSpace
< 0 && dir
== XwsdRight
) whiteSpace
= data
->length
;
232 position
= whiteSpace
;
236 for (i
= 0; i
< count
; i
++) {
237 while (position
>= 0 && position
<= data
->length
) {
238 if (Look(data
, position
, dir
) == '\n')
240 if(((dir
== XwsdRight
) && (position
== data
->length
)) ||
241 (dir
== XwsdLeft
) && ((position
== 0)))
243 Increment(data
, position
, dir
);
246 Increment(data
, position
, dir
);
249 /* later!!!check for last char in file # eol */
250 Increment(data
, position
, dir
);
257 position
= data
->length
;
259 if (position
< 0) position
= 0;
260 if (position
> data
->length
) position
= data
->length
;
264 /*--------------------------------------------------------------------------+*/
265 static XwEditType
StringGetEditType(src
)
266 /*--------------------------------------------------------------------------+*/
269 StringSourcePtr data
;
270 data
= (StringSourcePtr
) src
->data
;
271 return(data
->editMode
);
274 /*--------------------------------------------------------------------------+*/
275 static Boolean
XwStringSourceCheckData(src
)
276 /*--------------------------------------------------------------------------+*/
278 { int initial_size
= 0;
279 StringSourcePtr data
= (StringSourcePtr
)src
->data
;
281 data
->max_size_flag
= (data
->max_size
!= MAGICVALUE
);
283 if (data
->initial_string
== NULL
) {
284 if (data
->max_size_flag
)
285 data
->buffer_size
= data
->max_size
;
287 data
->buffer_size
= DEFAULTBUFFERSIZE
;
288 if (!data
->buffer
) data
->length
= 0;
291 initial_size
= XwStrlen(data
->initial_string
);
292 if (data
->max_size_flag
) {
293 if (data
->max_size
< initial_size
) {
294 XtWarning("Initial string size larger than XtNmaximumSize");
295 data
->max_size
= initial_size
;
297 data
->buffer_size
= data
->max_size
;
301 (initial_size
< DEFAULTBUFFERSIZE
) ? DEFAULTBUFFERSIZE
:
302 ((initial_size
/ DEFAULTBUFFERSIZE
) + 1) * DEFAULTBUFFERSIZE
;
304 data
->length
= initial_size
;
307 if (data
->buffer
&& initial_size
)
309 (unsigned char *) XtRealloc(data
->buffer
, data
->buffer_size
);
310 else if (!data
->buffer
)
311 data
->buffer
= (unsigned char *) XtMalloc(data
->buffer_size
);
314 strcpy(data
->buffer
, data
->initial_string
);
315 data
->initial_string
= NULL
;
319 /***** Public routines *****/
321 /*--------------------------------------------------------------------------+*/
322 void XwStringSourceDestroy (src
)
323 /*--------------------------------------------------------------------------+*/
326 XtFree((char *) src
->data
);
327 XtFree((char *) src
);
330 /*--------------------------------------------------------------------------+*/
331 XwTextSource
*XwStringSourceCreate (w
, args
, argCount
)
332 /*--------------------------------------------------------------------------+*/
338 StringSourcePtr data
;
341 src
= XtNew(XwTextSource
);
342 src
->read
= StringReadText
;
343 src
->replace
= StringReplaceText
;
344 src
->setLastPos
= StringSetLastPos
;
345 src
->getLastPos
= StringGetLastPos
;
346 src
->scan
= StringScan
;
347 src
->editType
= StringGetEditType
;
348 src
->resources
= stringResources
;
349 src
->resource_num
= XtNumber(stringResources
);
350 src
->check_data
= XwStringSourceCheckData
;
351 src
->destroy
= XwStringSourceDestroy
;
352 data
= XtNew(StringSourceData
);
353 data
->editMode
= XwtextRead
;
355 data
->initial_string
= NULL
;
357 data
->buffer_size
= 0;
359 data
->max_size_flag
= 0;
360 src
->data
= (int *)data
;
362 /* Use the name given to the TextEdit widget this source will go with.
363 This could be a problem if we allow multiple views on one source */
365 XtGetSubresources (w
, data
, XtNstringSrc
, "StringSrc",
366 stringResources
, XtNumber(stringResources
), args
, argCount
);
368 src
->data
= (int *) (data
);
370 XwStringSourceCheckData(src
);