Hi again,
There's a separate issue that came up when I was looking at this XmText
crashing problem.
When I first tracked down the crashing problem, I was trying to display a
file with Windows line endings (\r\n) in my text widget, and the crash
occurred when a string containing the \r character was passed to
FontTextWidth (and then on to _XmTextNextX). However, later I found that
I also encountered the crash when displaying what should be perfectly
normal text, where the only special characters were newlines. I have a
number of multiline XmText widgets in my app that display text containing
newlines, but the crash didn't occur in all of them.
By running the app under gdb, I learned that FontTextWidth is usually only
called for individual lines of text in a multiline XmText widget, and so
_XmTextNextX ordinarily doesn't need to deal with text containing
newlines. That makes sense - the only carriage-control character that's
treated specially in _XmTextNextX is the tab char; it's not written to
give an accurate result for text containing newlines and carriage returns.
Apparently what happens is that multiline text is first broken into
individual lines, which are recorded in the TextLine array. Sometimes,
however, FontTextWidth seems to get called *before* the text is broken
into lines, so that the entire contents of the text widget ends up being
treated as a single line, getting passed into _XmTextNextX.
In the case I observed, I had a widget which was handled like this (the
widget displays a growing output file from a running calculation)
n = 0;
XtSetArg(args[n], XmNeditable, FALSE); n++;
XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
XtSetArg(args[n], XmNtopWidget, textPanel.widget); n++;
XtSetArg(args[n], XmNtopOffset, 5); n++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
w = XmCreateScrolledText(workArea, "mainjobText", args, n);
then, later,
XmTextSetString(w,"");
then, in another function,
XmTextSetInsertionPosition(w,XmTextGetLastPosition(w));
then later the first text was being added with
XmTextPosition end_of_text;
char *new_text;
[...]
end_of_text = XmTextGetLastPosition(w);
XmTextInsert(w, end_of_text, new_text);
This caused a crash when new_text contained newline characters, with the
following stack trace (this is from notes I made):
0: _XmTextNextX
1: FontTextWidth
2: MakePositionVisible
3: XmTextShowPosition
4: _XmTextSetCursorPosition
5: Replace
6: XmTextInsert
So, XmTextShowPosition was called before the new text had been broken into
lines, and the entire block of new text was treated as though it was the
first and only line of text in the widget. This caused a crash. After I'd
made the patch in _XmTextNextX to avoid the crash, I saw that on the next
call to FontTextWidth after the one shown above, the text had been parsed
into lines and so strings containing newlines were no longer being given
to FontTextWidth. When I changed my code so that the first text added to
the widget was added with XmTextSetString, rather than with XmTextInsert,
then this problem no longer arose.
So, it looks like the code for the Replace function has a problem: it
should make sure the text is broken into lines before calling
XmTextShowPosition. I haven't tried to track this down further, to see if
there's a safe and easy fix for this, but it's definitely a bug. Under
ordinary circumstances FontTextWidth should never be called with a string
that contains newlines.
Anyway, I hope this is of interest to someone. It's been fun digging into
the Lesstif code a little.
Cheers,
TomP
-------------------------------------------------------------------------
Tom Pollard [EMAIL PROTECTED]
Schrodinger, Inc. 201-433-2014 x102
-------------------------------------------------------------------------