[comp.windows.x] Athena asciiStringWidget questions

ted@MBUNIX.MITRE.ORG (Ted Ede) (09/26/89)

Time for a few more questions on text widgets.  First, boatloads of
thanks to Brian Smith of Lawrence Berkeley Laboratory for identifying
my last problem as a known bug in R3 and providing the patch.

I'm using the Athena Widgets to create a multi-window talk utility.  I
open a display on each server, and create a form widget to contain a
label and text widget for each talker.  I'd like prevent a user from
typing into just any text widget (ie talking in some else's window).

Two options I can think of:

1) force all input from the form widget into a particular text widget
using XtSetKeyboardFocus(form_widget,particular_text_widget) after I
create the managed widget but before I realize it.  This doesn't seem
to work under awm.  Is it a one shot deal or am I doing something
dumb?

2) Identifying input focus to all text widgets with a callback, and
calling XtCallAcceptFocus if the widget is the appropriate widget.  I
haven't tried this because the asciiStringWidget doesn't have a
callback for input focus.  Is there another way to get this event?
Also, XtCallAcceptFocus is not in my libXt.  Is this a common error or
were our libraries built incorrectly?


Now, for a more mundane question: How do I allow more text to be saved
in an asciiStringWidget?  I've read the section on sincs and sources,
and it doesn't paint the clearest picture to me.  Should I just
allocate a big bunch of memory and create my own string source?  Also,
I'd like the widget to just forget about text further back than N
characters, instead of beeping at me.  A sliding text window of sorts.
Is that possible?  (As an aside, DEC's S TEXT WIDGET allows for a
string 2^31 - 1 characters long.  How do they do that?)

Inquiring minds want to know.  

Thanks,
Ted

|Ted Ede -- ted@mbunix.mitre.org -- The MITRE Corporation -- Burlington Road|
| linus!mbunix!ted -- Bedford MA, 01730 -- Mail Stop B090 -- (617) 271-7465 |
|                   - this line intentionally left blank -                  |
+---------------------------------------------------------------------------+

kit@EXPO.LCS.MIT.EDU (Chris D. Peterson) (10/27/89)

> I'd like prevent a user from
> typing into just any text widget (ie talking in some else's window).

Smash all the editing translations for the text widget that is to be read only
(Use *Text.Translations: #replace ...).  Also use SetKeyboard focus so that all
editing commands go to the other text widget.  The function
XtSetKeyboardFocus(form, edit_text) should do the trick.

> Now, for a more mundane question: How do I allow more text to be saved 
> in an asciiStringWidget...Should I just allocate a big bunch of memory and
> create my own string source?  

In R3 this is about it, don't forget to pass the allocacted size of the buffer
to the text widget at XtNlength.

> Also, I'd like the widget to just forget about
> text further back than N characters, instead of beeping at me.  A sliding text
> window of sorts.  Is that possible?  (As an aside, DEC's S TEXT WIDGET allows
> for a string 2^31 - 1 characters long.  How do they do that?)

You can do this, but you will have to do the work, when you get close you will
have to delete the first N characters of the buffer, and add in the new N
characters at the end of the buffer, use XtTextReplace(). 


						Chris D. Peterson     
						MIT X Consortium 

Net:	 kit@expo.lcs.mit.edu
Phone:   (617) 253 - 9608	
Address: MIT - Room NE43-213

jkh@meepmeep.pcs.com (Jordan K. Hubbard) (10/28/89)

This brings up a question I have about the asciiStringWidget, perhaps
Chris can help me too. I have an application (the Info browsing widget, for
the curious) that uses an ascii string widget to display a section of
text from a large allocated chunk of memory. The text widget's "window"
into this chunk of memory (and often the chunk of memory itself) changes
frequently. This is what I did:

     XtTextSource oldSource, newSource;

..

     oldSource = XtTextGetSource(widget);

     i = 0;
     XtSetArg(args[i], XtNlength, .. new length ..);			i++;
     XtSetArg(args[i], XtNstring, .. new start ptr in buffer ..);	i++;
     XtSetArg(args[i], XtNtextOptions, (wordBreak | scrollVertical));	i++;
     newSource = XtStringSourceCreate(widget, args, i);
     XtTextSetSource(widget, newSource, 0);
     XtStringSourceDestroy(oldSource);

Note that I don't know whether the setting of the textOptions is useless
or not. The documentation is quite vague on the question of which resources
are destined for the source, and for the sink. Anyway, the long and short
of this is that it doesn't work. The starting position in the text widget
is set correctly, but the length doesn't seem to have any effect. In
fact, everything from the new starting position (represented by a pointer
into the buffer) to the END OF THE BUFFER is displayed! This is a real
mystery, since I have no idea how the text widget knows how large the
entire buffer is. I suspect that it runs into a large contiguous
section of nulls or something and gives up. It also may be that the
old Source length is maintained somehow (which usually is the length
of the entire buffer the first time around). In order to get this to work
properly, I had to do the following after creating the new source:

	...
     XtTextDisableRedisplay(widget);
     XtTextSetSource(widget, newSource, 0);
     XtStringSourceDestroy(oldSource);
     XtTextSetLastPos(widget, .. new length ..);
     XtTextEnableRedisplay(widget);


Any clues?

				Jordan
---
--
			PCS Computer Systeme GmbH, Munich, West Germany
	UUCP:		pyramid!pcsbst!jkh jkh@meepmeep.pcs.com
	EUNET:		unido!pcsbst!jkh
	ARPA:		jkh@violet.berkeley.edu or hubbard@decwrl.dec.com

bjaspan@athena.mit.edu (Barr3y Jaspan) (10/29/89)

I have written a function that takes a text widget and a string and
appends the string to the widget, deleting text from the beginning if
necessary.  I wrote it a little while ago and haven't used it lately,
so it might have undergone bit rot, but it worked when I used it.  (It
does some less-than-brilliant things in case of error.. you probably
will want to fix that.)

Barr3y Jaspan, bjaspan@athena.mit.edu
MIT Project Athena

----- snip snip -----

/* 
 * AppendString.c -- appends a string to the end of a text widget.  It
 * assumes the widget is in the proper state to accept input in this manner
 * (ie: it does no error checking.)
 *
 * Written by Barry Jaspan (bjaspan@ATHENA.MIT.EDU)
 */

#include <stdio.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/AsciiText.h>

void AppendString(w, value, maxlen)
    Widget w;
    caddr_t value;
    int maxlen;
{
    XtTextBlock text;
    static XtTextPosition last=0;
    unsigned long	length;
    int retval;

    length = (unsigned long) strlen((char *) value);
    if (length == 0) {
	 printf("Length of %s = %ld\n",(char *) value, length);
	XBell( XtDisplay(w), 0 );
	return; }

    /* If this text puts us over the buffer len, just delete enough */
    /* text from the front to compensate.  Not an ideal algorithm. */
    if ((last+length)>maxlen) {
	 text.ptr = "";
	 text.firstPos = 0;
	 text.length = 0;
	 text.format = FMT8BIT;
	 XtTextReplace(w,(XtTextPosition)0,(XtTextPosition)length,&text);
	 last -= length;
	 XtTextSetInsertionPoint(w, (XtTextPosition) last);
         XtTextSetLastPos(w, (XtTextPosition) last); }

    text.ptr = (char *) value;
    text.firstPos = 0;
    text.length = length;
    text.format = FMT8BIT;

    if ((retval=XtTextReplace(w, last, last, &text))!=0) {
	 XBell(XtDisplay(w), 0);
	 printf("TextReplace returned %d\n",retval); }
    else {
	XtTextSetInsertionPoint(w, last + text.length);
	last += (XtTextPosition) length;
   }
}

Barry Jaspan
Project Athena ``Watchmaker''
SIPB (Student Information Processing Board) Member
OLC Volunteer

kit@EXPO.LCS.MIT.EDU (Chris D. Peterson) (11/28/89)

> This brings up a question I have about the asciiStringWidget, perhaps
> Chris can help me too. I have an application (the Info browsing widget, for
> the curious) that uses an ascii string widget to display a section of
> text from a large allocated chunk of memory. The text widget's "window"
> into this chunk of memory (and often the chunk of memory itself) changes
> frequently. This is what I did:

>      XtTextSource oldSource, newSource;

>     oldSource = XtTextGetSource(widget);

>     i = 0;
>     XtSetArg(args[i], XtNlength, .. new length ..);			i++;
>     XtSetArg(args[i], XtNstring, .. new start ptr in buffer ..);	i++;
>     XtSetArg(args[i], XtNtextOptions, (wordBreak | scrollVertical));	i++;
>     newSource = XtStringSourceCreate(widget, args, i);
>     XtTextSetSource(widget, newSource, 0);
>     XtStringSourceDestroy(oldSource);

> Note that I don't know whether the setting of the textOptions is useless
> or not.

Setting the options is useless.  The docs will be better in R4, promise.

> Anyway, the long and short
> of this is that it doesn't work. The starting position in the text widget
> is set correctly, but the length doesn't seem to have any effect.

If I understand you correctly the problem appears to be that you are
misinterpreting the function of the length resource.  This resource specifies
the length of the buffer that the text widget will use, in place, to contain
the string.  The text that is displayed is a normal NULL terminated Latin1
string.  The end of the displayed string is determined by using strlen(). 
The length is used to keep the Text widget from overwriting the end of the
buffer when the Text widget is in edit mode.  

> Any clues?

>				Jordan

I hope that clears things up a bit.


						Chris D. Peterson     
						MIT X Consortium 

Net:	 kit@expo.lcs.mit.edu
Phone:   (617) 253 - 9608	
Address: MIT - Room NE43-213

simon@bear.UUCP (Simon Leinen) (11/29/89)

In article <8911272047.AA05542@expo.lcs.mit.edu> kit@EXPO.LCS.MIT.EDU (Chris D. Peterson) writes:

   [ in reply to another message (????): ]

   > I have an application (the Info browsing widget, for the curious)
   > that uses an ascii string widget to display a section of text
   > from a large allocated chunk of memory. The text widget's
   > "window" into this chunk of memory (and often the chunk of memory
   > itself) changes frequently. This is what I did:

   > ...

   ... you are misinterpreting the function of the length resource ...

In programming my version of the Info browsing widget, I ran into the
same problem, of course.  The solution that worked for me is setting
the buffer limit explicitly using ``XtTextSetLastPos'', like

	XtTextSetLastPos (w->info.text_buffer, w->info.node->length);

Unfortunately, I can't seem to find the original message, So I don't
know whom I am replying to.  I would like to contact its poster (via
EMail) if he likes, because we are seemingly implementing the same
kind of widget, and I am sure I'm doing many things in a wrong way.
-- 
Simon Leinen.