tsource.c revision d859ff80
1c9e2be55Smrg/* $XConsortium: tsource.c,v 2.24 91/10/21 14:32:36 eswu Exp $ */
2c9e2be55Smrg
3c9e2be55Smrg/*
4c9e2be55Smrg *			  COPYRIGHT 1987
5c9e2be55Smrg *		   DIGITAL EQUIPMENT CORPORATION
6c9e2be55Smrg *		       MAYNARD, MASSACHUSETTS
7c9e2be55Smrg *			ALL RIGHTS RESERVED.
8c9e2be55Smrg *
9c9e2be55Smrg * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND
10c9e2be55Smrg * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
11c9e2be55Smrg * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR
12c9e2be55Smrg * ANY PURPOSE.  IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
13c9e2be55Smrg *
14c9e2be55Smrg * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT RIGHTS,
15c9e2be55Smrg * APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN ADDITION TO THAT
16c9e2be55Smrg * SET FORTH ABOVE.
17c9e2be55Smrg *
18c9e2be55Smrg *
19c9e2be55Smrg * Permission to use, copy, modify, and distribute this software and its
20c9e2be55Smrg * documentation for any purpose and without fee is hereby granted, provided
21c9e2be55Smrg * that the above copyright notice appear in all copies and that both that
22c9e2be55Smrg * copyright notice and this permission notice appear in supporting documentation,
23c9e2be55Smrg * and that the name of Digital Equipment Corporation not be used in advertising
24c9e2be55Smrg * or publicity pertaining to distribution of the software without specific,
25c9e2be55Smrg * written prior permission.
26c9e2be55Smrg */
27c9e2be55Smrg/* $XFree86: xc/programs/xmh/tsource.c,v 1.3 2002/04/05 21:06:29 dickey Exp $ */
28c9e2be55Smrg
29c9e2be55Smrg/* File: tsource.c -- the code for a toc source */
30c9e2be55Smrg
31c9e2be55Smrg#include "xmh.h"
32c9e2be55Smrg#include "tocintrnl.h"
33c9e2be55Smrg#include <X11/Xatom.h>
34c9e2be55Smrg#include "tsourceP.h"
35c9e2be55Smrg
36c9e2be55Smrg/****************************************************************
37c9e2be55Smrg *
38c9e2be55Smrg * Full class record constant
39c9e2be55Smrg *
40c9e2be55Smrg ****************************************************************/
41c9e2be55Smrg
42c9e2be55Smrg/* Private Data */
43c9e2be55Smrg
44c9e2be55Smrg#define Offset(field) XtOffsetOf(TocSourceRec, toc_source.field)
45c9e2be55Smrg
46c9e2be55Smrgstatic XtResource resources[] = {
47d859ff80Smrg    {XtNtoc, XtCToc, XtRPointer, sizeof(caddr_t),
48c9e2be55Smrg       Offset(toc), XtRPointer, NULL},
49c9e2be55Smrg};
50c9e2be55Smrg
51c9e2be55Smrg#undef Offset
52c9e2be55Smrg
53c9e2be55Smrgstatic void Initialize(Widget, Widget, ArgList, Cardinal *num_args);
54c9e2be55Smrgstatic XawTextPosition Read(Widget, XawTextPosition, XawTextBlock *, int);
55c9e2be55Smrgstatic XawTextPosition Scan(Widget, XawTextPosition, XawTextScanType, XawTextScanDirection, int, Bool);
56c9e2be55Smrgstatic XawTextPosition Search(Widget, XawTextPosition, XawTextScanDirection, XawTextBlock *);
57c9e2be55Smrgstatic int Replace(Widget, XawTextPosition, XawTextPosition, XawTextBlock *);
58c9e2be55Smrg
59c9e2be55Smrg#define SuperClass		(&textSrcClassRec)
60c9e2be55SmrgTocSourceClassRec tocSourceClassRec = {
61c9e2be55Smrg  {
62d859ff80Smrg/* core_class fields */
63c9e2be55Smrg    /* superclass	  	*/	(WidgetClass) SuperClass,
64c9e2be55Smrg    /* class_name	  	*/	"TocSrc",
65c9e2be55Smrg    /* widget_size	  	*/	sizeof(TocSourceRec),
66c9e2be55Smrg    /* class_initialize   	*/	NULL,
67c9e2be55Smrg    /* class_part_initialize	*/	NULL,
68c9e2be55Smrg    /* class_inited       	*/	FALSE,
69c9e2be55Smrg    /* initialize	  	*/	Initialize,
70c9e2be55Smrg    /* initialize_hook		*/	NULL,
71c9e2be55Smrg    /* realize		  	*/	NULL,
72c9e2be55Smrg    /* actions		  	*/	NULL,
73c9e2be55Smrg    /* num_actions	  	*/	0,
74c9e2be55Smrg    /* resources	  	*/	resources,
75c9e2be55Smrg    /* num_resources	  	*/	XtNumber(resources),
76c9e2be55Smrg    /* xrm_class	  	*/	NULLQUARK,
77c9e2be55Smrg    /* compress_motion	  	*/	FALSE,
78c9e2be55Smrg    /* compress_exposure  	*/	FALSE,
79c9e2be55Smrg    /* compress_enterleave	*/	FALSE,
80c9e2be55Smrg    /* visible_interest	  	*/	FALSE,
81c9e2be55Smrg    /* destroy		  	*/	NULL,
82c9e2be55Smrg    /* resize		  	*/	NULL,
83c9e2be55Smrg    /* expose		  	*/	NULL,
84c9e2be55Smrg    /* set_values	  	*/	NULL,
85c9e2be55Smrg    /* set_values_hook		*/	NULL,
86c9e2be55Smrg    /* set_values_almost	*/	NULL,
87c9e2be55Smrg    /* get_values_hook		*/	NULL,
88c9e2be55Smrg    /* accept_focus	 	*/	NULL,
89c9e2be55Smrg    /* version			*/	XtVersion,
90c9e2be55Smrg    /* callback_private   	*/	NULL,
91c9e2be55Smrg    /* tm_table		   	*/	NULL,
92c9e2be55Smrg    /* query_geometry		*/	NULL,
93c9e2be55Smrg    /* display_accelerator	*/	NULL,
94c9e2be55Smrg    /* extension		*/	NULL
95c9e2be55Smrg  },
96c9e2be55Smrg/* textSrc_class fields */
97c9e2be55Smrg  {
98c9e2be55Smrg    /* Read                     */      Read,
99c9e2be55Smrg    /* Replace                  */      Replace,
100c9e2be55Smrg    /* Scan                     */      Scan,
101c9e2be55Smrg    /* Search                   */      Search,
102c9e2be55Smrg    /* SetSelection             */      XtInheritSetSelection,
103c9e2be55Smrg    /* ConvertSelection         */      XtInheritConvertSelection
104c9e2be55Smrg  },
105c9e2be55Smrg/* toc_source_class fields */
106c9e2be55Smrg  {
107c9e2be55Smrg    /* keeping the compiler happy */	0
108c9e2be55Smrg  }
109c9e2be55Smrg};
110c9e2be55Smrg
111c9e2be55SmrgWidgetClass tocSourceWidgetClass = (WidgetClass)&tocSourceClassRec;
112c9e2be55Smrg
113c9e2be55Smrg/************************************************************
114c9e2be55Smrg *
115c9e2be55Smrg * Class specific methods.
116c9e2be55Smrg *
117c9e2be55Smrg ************************************************************/
118c9e2be55Smrg
119c9e2be55SmrgMsg MsgFromPosition(
120c9e2be55Smrg    Toc toc,
121c9e2be55Smrg    XawTextPosition position,
122c9e2be55Smrg    XawTextScanDirection dir)
123c9e2be55Smrg{
124c9e2be55Smrg    Msg msg;
125c9e2be55Smrg    int     h, l, m;
126c9e2be55Smrg    if (position > toc->lastPos) position = toc->lastPos;
127c9e2be55Smrg    if (dir == XawsdLeft) position--;
128c9e2be55Smrg    l = 0;
129c9e2be55Smrg    h = toc->nummsgs - 1;
130c9e2be55Smrg    while (l < h - 1) {
131c9e2be55Smrg	m = (l + h) / 2;
132c9e2be55Smrg	if (toc->msgs[m]->position > position)
133c9e2be55Smrg	    h = m;
134c9e2be55Smrg	else
135c9e2be55Smrg	    l = m;
136c9e2be55Smrg    }
137c9e2be55Smrg    msg = toc->msgs[h];
138c9e2be55Smrg    if (msg->position > position)
139c9e2be55Smrg	msg = toc->msgs[h = l];
140c9e2be55Smrg    while (!msg->visible)
141c9e2be55Smrg	msg = toc->msgs[h++];
142c9e2be55Smrg    if (position < msg->position || position > msg->position + msg->length)
143c9e2be55Smrg	Punt("Error in MsgFromPosition!");
144c9e2be55Smrg    return msg;
145c9e2be55Smrg}
146c9e2be55Smrg
147c9e2be55Smrg
148c9e2be55Smrgstatic XawTextPosition
149c9e2be55SmrgCoerceToLegalPosition(Toc toc, XawTextPosition position)
150c9e2be55Smrg{
151c9e2be55Smrg    return (position < 0) ? 0 :
152c9e2be55Smrg		 ((position > toc->lastPos) ? toc->lastPos : position);
153c9e2be55Smrg}
154c9e2be55Smrg
155c9e2be55Smrgstatic XawTextPosition
156c9e2be55SmrgRead(
157c9e2be55Smrg    Widget w,
158c9e2be55Smrg    XawTextPosition position,
159c9e2be55Smrg    XawTextBlock *block,
160c9e2be55Smrg    int length)
161c9e2be55Smrg{
162c9e2be55Smrg    TocSourceWidget source = (TocSourceWidget) w;
163c9e2be55Smrg    Toc toc = source->toc_source.toc;
164c9e2be55Smrg    Msg msg;
165c9e2be55Smrg    int count;
166c9e2be55Smrg
167c9e2be55Smrg    if (position < toc->lastPos) {
168c9e2be55Smrg        block->firstPos = position;
169c9e2be55Smrg	msg = MsgFromPosition(toc, position, XawsdRight);
170c9e2be55Smrg	block->ptr = msg->buf + (position - msg->position);
171c9e2be55Smrg	count = msg->length - (position - msg->position);
172c9e2be55Smrg	block->length = (count < length) ? count : length;
173c9e2be55Smrg	position += block->length;
174c9e2be55Smrg    }
175c9e2be55Smrg    else {
176c9e2be55Smrg        block->firstPos = 0;
177c9e2be55Smrg	block->length = 0;
178c9e2be55Smrg	block->ptr = "";
179c9e2be55Smrg    }
180c9e2be55Smrg    block->format = FMT8BIT;
181c9e2be55Smrg    return position;
182c9e2be55Smrg}
183c9e2be55Smrg
184c9e2be55Smrg/* Right now, we can only replace a piece with another piece of the same size,
185c9e2be55Smrg   and it can't cross between lines. */
186c9e2be55Smrg
187d859ff80Smrgstatic int
188c9e2be55SmrgReplace(
189c9e2be55Smrg    Widget w,
190c9e2be55Smrg    XawTextPosition startPos,
191c9e2be55Smrg    XawTextPosition endPos,
192c9e2be55Smrg    XawTextBlock *block)
193c9e2be55Smrg{
194c9e2be55Smrg    TocSourceWidget source = (TocSourceWidget) w;
195c9e2be55Smrg    Toc toc = source->toc_source.toc;
196c9e2be55Smrg    Msg msg;
197c9e2be55Smrg    int i;
198c9e2be55Smrg
199c9e2be55Smrg    if (block->length != endPos - startPos)
200c9e2be55Smrg	return XawEditError;
201c9e2be55Smrg    msg = MsgFromPosition(toc, startPos, XawsdRight);
202c9e2be55Smrg    for (i = 0; i < block->length; i++)
203c9e2be55Smrg	msg->buf[startPos - msg->position + i] = block->ptr[i];
204c9e2be55Smrg/*    for (i=0 ; i<toc->numwidgets ; i++)
205c9e2be55Smrg	XawTextInvalidate(toc->widgets[i], startPos, endPos);
206c9e2be55Smrg*
207d859ff80Smrg* CDP 9/1/89
208c9e2be55Smrg*/
209c9e2be55Smrg    return XawEditDone;
210c9e2be55Smrg}
211c9e2be55Smrg
212c9e2be55Smrg
213c9e2be55Smrg#define Look(ti, c)\
214c9e2be55Smrg{									\
215c9e2be55Smrg    if ((dir == XawsdLeft && ti <= 0) ||				\
216c9e2be55Smrg	    (dir == XawsdRight && ti >= toc->lastPos))		\
217c9e2be55Smrg	c = 0;								\
218c9e2be55Smrg    else {								\
219c9e2be55Smrg	if (ti + doff < msg->position ||				\
220c9e2be55Smrg		ti + doff >= msg->position + msg->length)		\
221c9e2be55Smrg	    msg = MsgFromPosition(toc, ti, dir);			\
222c9e2be55Smrg	c = msg->buf[ti + doff - msg->position];			\
223c9e2be55Smrg    }									\
224c9e2be55Smrg}
225c9e2be55Smrg
226c9e2be55Smrg
227c9e2be55Smrg
228d859ff80Smrgstatic XawTextPosition
229c9e2be55SmrgScan(
230c9e2be55Smrg    Widget w,
231c9e2be55Smrg    XawTextPosition position,
232c9e2be55Smrg    XawTextScanType sType,
233c9e2be55Smrg    XawTextScanDirection dir,
234c9e2be55Smrg    int count,
235c9e2be55Smrg    Bool include)
236c9e2be55Smrg{
237c9e2be55Smrg    TocSourceWidget source = (TocSourceWidget) w;
238c9e2be55Smrg    Toc toc = source->toc_source.toc;
239c9e2be55Smrg    XawTextPosition textindex;
240c9e2be55Smrg    Msg msg;
241c9e2be55Smrg    char    c;
242c9e2be55Smrg    int     ddir, doff, i, whiteSpace = 0;
243c9e2be55Smrg    ddir = (dir == XawsdRight) ? 1 : -1;
244c9e2be55Smrg    doff = (dir == XawsdRight) ? 0 : -1;
245c9e2be55Smrg
246c9e2be55Smrg    if (toc->lastPos == 0) return 0;
247c9e2be55Smrg    textindex = position;
248c9e2be55Smrg    if (textindex + doff < 0) return 0;
249c9e2be55Smrg    if (dir == XawsdRight && textindex >= toc->lastPos) return toc->lastPos;
250c9e2be55Smrg    msg = MsgFromPosition(toc, textindex, dir);
251c9e2be55Smrg    switch (sType) {
252c9e2be55Smrg	case XawstPositions:
253c9e2be55Smrg	    if (!include && count > 0)
254c9e2be55Smrg		count--;
255c9e2be55Smrg	    textindex = CoerceToLegalPosition(toc, textindex + count * ddir);
256c9e2be55Smrg	    break;
257c9e2be55Smrg	case XawstWhiteSpace:
258c9e2be55Smrg	    for (i = 0; i < count; i++) {
259c9e2be55Smrg		whiteSpace = -1;
260c9e2be55Smrg		while (textindex >= 0 && textindex <= toc->lastPos) {
261c9e2be55Smrg		    Look(textindex, c);
262c9e2be55Smrg		    if ((c == ' ') || (c == '\t') || (c == '\n')) {
263c9e2be55Smrg			if (whiteSpace < 0) whiteSpace = textindex;
264c9e2be55Smrg		    } else if (whiteSpace >= 0)
265c9e2be55Smrg			break;
266c9e2be55Smrg		    textindex += ddir;
267c9e2be55Smrg		}
268c9e2be55Smrg	    }
269c9e2be55Smrg	    if (!include) {
270c9e2be55Smrg		if (whiteSpace < 0 && dir == XawsdRight)
271c9e2be55Smrg		    whiteSpace = toc->lastPos;
272c9e2be55Smrg		textindex = whiteSpace;
273c9e2be55Smrg	    }
274c9e2be55Smrg	    textindex = CoerceToLegalPosition(toc, textindex);
275c9e2be55Smrg	    break;
276c9e2be55Smrg	case XawstEOL:
277c9e2be55Smrg	case XawstParagraph:
278c9e2be55Smrg	    for (i = 0; i < count; i++) {
279c9e2be55Smrg		while (textindex >= 0 && textindex <= toc->lastPos) {
280c9e2be55Smrg		    Look(textindex, c);
281c9e2be55Smrg		    if (c == '\n')
282c9e2be55Smrg			break;
283c9e2be55Smrg		    textindex += ddir;
284c9e2be55Smrg		}
285c9e2be55Smrg		if (i < count - 1)
286c9e2be55Smrg		    textindex += ddir;
287c9e2be55Smrg	    }
288c9e2be55Smrg	    if (include)
289c9e2be55Smrg		textindex += ddir;
290c9e2be55Smrg	    textindex = CoerceToLegalPosition(toc, textindex);
291c9e2be55Smrg	    break;
292c9e2be55Smrg	case XawstAll:
293c9e2be55Smrg	    if (dir == XawsdLeft)
294c9e2be55Smrg		textindex = 0;
295c9e2be55Smrg	    else
296c9e2be55Smrg		textindex = toc->lastPos;
297c9e2be55Smrg	    break;
298c9e2be55Smrg	default:
299c9e2be55Smrg	    break;
300c9e2be55Smrg    }
301c9e2be55Smrg    return textindex;
302c9e2be55Smrg}
303c9e2be55Smrg
304c9e2be55Smrg/*ARGSUSED*/
305c9e2be55Smrgstatic XawTextPosition Search(
306c9e2be55Smrg    Widget			w,
307c9e2be55Smrg    XawTextPosition		position,
308c9e2be55Smrg    XawTextScanDirection	direction,
309c9e2be55Smrg    XawTextBlock		*block)
310c9e2be55Smrg{
311c9e2be55Smrg    /* TocSourceWidget source = (TocSourceWidget) w;
312c9e2be55Smrg     * Toc toc = source->toc_source.toc;
313c9e2be55Smrg     * not implemented
314c9e2be55Smrg     */
315c9e2be55Smrg    return XawTextSearchError;
316c9e2be55Smrg}
317c9e2be55Smrg
318c9e2be55Smrg/* Public definitions. */
319c9e2be55Smrg
320c9e2be55Smrg/* ARGSUSED*/
321c9e2be55Smrgstatic void Initialize(
322c9e2be55Smrg    Widget request,
323c9e2be55Smrg    Widget new,
324c9e2be55Smrg    ArgList args,
325c9e2be55Smrg    Cardinal *num_args)
326c9e2be55Smrg{
327c9e2be55Smrg    Toc toc;
328c9e2be55Smrg    TocSourceWidget source = (TocSourceWidget) new;
329c9e2be55Smrg
330c9e2be55Smrg    source->text_source.edit_mode = XawtextRead; /* force read only. */
331c9e2be55Smrg
332c9e2be55Smrg    toc = source->toc_source.toc;
333c9e2be55Smrg
334c9e2be55Smrg    toc->hasselection = FALSE;
335c9e2be55Smrg    toc->left = toc->right = 0;
336c9e2be55Smrg}
337c9e2be55Smrg
338c9e2be55Smrgvoid
339c9e2be55SmrgTSourceInvalid(Toc toc, XawTextPosition position, int length)
340c9e2be55Smrg{
341d859ff80Smrg  XawTextInvalidate(XtParent(toc->source), position,
342c9e2be55Smrg		    (XawTextPosition) position+length-1);
343c9e2be55Smrg}
344