[comp.windows.x] Text Widget Bug

rgcote@mit-vax.LCS.MIT.EDU (Rob Cote) (01/21/89)

Thanks to Ralph Swick and Chris Peterson for their responses to my question
about the Athena text widget. Both admitted that the behavior I have noticed
is probably a bug. Below is a description of the problem and an example
program which demonstrates the bug for anyone interested. Hopefully, it didn't
get mangled in being sent.

					-Rob

------------------8<------------Cut Here------------->8---------------------

Suppose I have an editable text widget that is, say, 2 lines long. The
scrollOnOverflow option for the widget is (by default) off. I am receiving
lines of text via a file descriptor. As I receive each line, I place it
into the text widget by means of XtTextReplace. While waiting for text to
arrive, I sit in a loop servicing X events. Once I have received 2 lines
of text, I would like any additional text to be properly stuffed into
the text widget via the XtTextReplace routine, but I would not like the
text on the screen to scroll up, making room for line 3, say, on the
screen. I want the text to be in the widget so that a person can page
through it, but I want the first 2 lines to be showing (no matter how
much text was received) until the user indicates otherwise. Currently,
the text widget will scroll up what is shown on the screen as each new 
line is inserted. 

Enclosed is an example program which exhibits the behavior I am talking
about. The program creates a small (height-wise) text widget and inserts
six lines of text into the widget. Because the widget cannot accommodate
six lines of text, the first few lines of text inserted get scrolled off
the screen. The behavior I would like is for the first few lines of text
to remain on the screen (regardless of text inserted) until the user 
scrolls. [This behavior is dependent on the font size you use, but it 
should work.]

I compiled the following program with the command line:

	cc -g myprogram.c -lXaw -lXmu -lXt -lX11 -o myprogram


-----------------8<--------Cut Here for Program-------->8---------------------

/* This program demonstrates a bug in the Athena text widget. Even though
   the scrollOnOverflow option is turned off, the widget scrolls when text
   is added that will not fit in what is shown on the screen. */

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

/* The toplevel and text widgets */
Widget TestProgram, MyTextWidget;

/* This string will house the text widget text */
#define TEXT_SIZE	1024
char *internal_text[TEXT_SIZE];

#define MAXARGS	20
Arg arg[MAXARGS];
int argn;

/* I don't really care about options for this demo */
static XrmOptionDescRec options[1];

/*****************************************************************************/

main(argc, argv)

     int argc;
     char *argv[];

{
  /* First create the toplevel widget */
  TestProgram = XtInitialize("main", "Test", options, 0, &argc, argv);

  /* Zero out the internal text string that will be passed to the text widget*/
  internal_text[0] = '\0';

  /* Give the text widget a rather small height so we know we will overflow
     by inserting many lines of text. Also turn off *all* options by setting
     the XtNtextOptions to 0. */
  argn = 0;
  XtSetArg(arg[argn], XtNheight, 40); ++argn;
  XtSetArg(arg[argn], XtNwidth, 500); ++argn;
  XtSetArg(arg[argn], XtNeditType, XttextEdit); ++argn;
  XtSetArg(arg[argn], XtNstring, internal_text); ++argn;
  XtSetArg(arg[argn], XtNlength, TEXT_SIZE); ++argn;
  XtSetArg(arg[argn], XtNtextOptions, 0);
  MyTextWidget = XtCreateManagedWidget("MyTextWidget", asciiStringWidgetClass, 
				     TestProgram, arg, argn);

  /* Realize the toplevel widget and then go fill the text widget with text */
  XtRealizeWidget(TestProgram);
  FillWidgetWithText(MyTextWidget);
}

/*****************************************************************************/

#define MAXLINES	6

/* These are the lines of text we are going to use to fill the text widget */
static char *lines[MAXLINES] = {
  "This is the first line of text to fill the widget with.\n",
  "This is the second line of text to fill the widget with.\n",
  "This is the third line of text to fill the widget with.\n",
  "This is the fourth line of text to fill the widget with.\n",
  "This is the fifth line of text to fill the widget with.\n",
  "This is the sixth line of text to fill the widget with.\n"};


FillWidgetWithText(MyTextWidget)

     Widget MyTextWidget;

{
  XtTextPosition startPos = 0, endPos = 0;
  XtTextBlock textblock;
  int i;
  XEvent event;

  /* For each line of text ... */
  for (i = 0; i < MAXLINES; ++i) {

    /* ... insert into the text widget. This is a fairly standard way of 
       inserting text into a widget */
    textblock.firstPos = 0;
    textblock.length = strlen(lines[i]);
    textblock.ptr = lines[i];
    endPos = startPos + strlen(lines[i]);
    XtTextReplace(MyTextWidget, startPos, endPos, &textblock);
    startPos += strlen(lines[i]) + 1;

    /* Service X events here so we will see a change on the screen. This 
	  is more or less the same thing that XtMainLoop does, except this
       loop will end when there are no events pending. */
    while (XtPending()) {
      XtNextEvent(&event);
      XtDispatchEvent(&event);
    }
    /* Sleep here so we can see each line as it is being added. */
    sleep(2);
  }

  /* All done. Now exit the program. */
  exit(0);
}

-- 
and none of this of course will stand when I stand before the man on that great
day of the great divide when all the kings and queens will have their closets
emptied and the bones them bones them dry bones will not fail dead men will 
tell tales and you can laugh I can laugh we can laugh but its not funny -the 77s