wong@cathedral.cerc.wvu.wvnet.edu (Dennis Hiulum Wong) (10/24/90)
I have found a bug in the Tree widget from Young's book,
"The X Window System: Programming and Applications with Xt,
Motif Edition" (I got the source code from expo.lcs.mit.edu).
The Tree widget works fine for a binary tree, but has problem
with non-binary tree. The following is an example in which I
create a PushButton and a ScrolledWindow for displaying the
tree. When I click on the button, the program will destroy the
tree widget (if there is one there)and rebuild the tree. If I
keep on pressing the button, for the first few times it works
ok, but eventually it crashes on me.
Does anyone have a fix for it? Where can I report this bug?
Any comments are welcomed.
-- Dennis
wong@cerc.wvu.wvnet.edu
------- cut here -------------------------------------------
#include <stdio.h>
#include <X11/StringDefs.h>
#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
#include <Xm/PushBG.h>
#include <Xm/PushB.h>
#include <Xm/Form.h>
#include <Xm/ScrolledW.h>
#include "Tree.h"
/**********************************************************/
char *strtok();
Widget tree_node = NULL;
Widget sw;
static char *list = "a ( bb cc ( ee ( kk oo ) ff ) dd ( gg ) ) ";
char tree_str[300];
/**********************************************************/
button_handler (w, client_data, call_data)
Widget w;
caddr_t client_data;
caddr_t call_data;
{
if (tree_node != NULL) {
XtDestroyWidget (tree_node);
tree_node = NULL;
}
}
/**********************************************************/
button_handler2 (w, client_data, call_data)
Widget w;
caddr_t client_data;
caddr_t call_data;
{
Arg wargs[10];
int i;
static char *tok;
char *show_tree();
/*
* Create the tree widget.
*/
if (tree_node == NULL) {
i = 0;
XtSetArg(wargs[i], XmNborderWidth, 0); i++;
tree_node = XtCreateManagedWidget("tree", XstreeWidgetClass,
sw, wargs, i);
strcpy(tree_str, list);
tok = strtok(tree_str, " ");
/*
* Create the widgets representing the tree.
*/
show_tree(tree_node, NULL, 1, tok);
}
}
/**********************************************************/
print_name(w, client_data, call_data)
Widget w;
caddr_t client_data;
caddr_t call_data;
{
printf("level %d\n", (int)client_data);
}
/**********************************************************/
char *show_tree(parent, s_node, level, token)
Widget parent;
Widget s_node;
char *token;
int level;
{
Widget w;
Arg wargs[10];
int n = 0;
XmString str;
while (token != NULL) {
printf("token:%s|\n", token);
if (*token == '(') {
token = strtok(NULL, " ");
token = show_tree(parent, w, level + 1, token);
}
else if (*token == ')') {
token = strtok(NULL, " ");
return(token);
}
else {
str = XmStringCreate(token, XmSTRING_DEFAULT_CHARSET);
n = 0;
XtSetArg(wargs[n], XtNsuperNode, s_node); n++;
XtSetArg(wargs[n], XmNlabelString, str); n++;
w = XtCreateManagedWidget(token, xmPushButtonWidgetClass,
parent, wargs, n);
XtAddCallback(w, XmNactivateCallback, print_name, (caddr_t)level);
XmStringFree (str);
token = strtok(NULL, " ");
}
}
}
/**********************************************************/
main(argc, argv)
int argc;
char **argv;
{
Widget toplevel, win, w1;
int i, xargc;
char **xargv;
Arg wargs[10];
toplevel = XtInitialize(argv[0], "DisplayTree", NULL, 0,
&argc, argv);
i = 0;
XtSetArg(wargs[i], XmNwidth, 300); i++;
XtSetArg(wargs[i], XmNheight, 240); i++;
win = XtCreateManagedWidget ("Window", xmFormWidgetClass,
toplevel, (ArgList)wargs, i);
i = 0;
XtSetArg(wargs[i], XmNtopAttachment, XmATTACH_FORM); i++;
XtSetArg(wargs[i], XmNleftAttachment, XmATTACH_FORM); i++;
XtSetArg(wargs[i], XmNshadowThickness, 3); i++;
w1 = XtCreateManagedWidget ("Button", xmPushButtonGadgetClass,
win, (ArgList)wargs, i);
XtAddCallback (w1, XmNarmCallback, button_handler, 2);
XtAddCallback (w1, XmNactivateCallback, button_handler2, 2);
/*
* Put the tree in a scrolled window, to handle
* large trees.
*/
i = 0;
XtSetArg(wargs[i], XmNtopAttachment, XmATTACH_WIDGET); i++;
XtSetArg(wargs[i], XmNtopWidget, w1); i++;
XtSetArg(wargs[i], XmNleftAttachment, XmATTACH_FORM); i++;
XtSetArg(wargs[i], XmNrightAttachment, XmATTACH_FORM); i++;
XtSetArg(wargs[i], XmNbottomAttachment, XmATTACH_FORM); i++;
XtSetArg(wargs[i], XmNscrollingPolicy, XmAUTOMATIC); i++;
XtSetArg(wargs[i], XmNwidth, 300); i++;
XtSetArg(wargs[i], XmNheight, 100); i++;
XtSetArg(wargs[i], XmNborderWidth, 0); i++;
sw = XtCreateManagedWidget("swindow",
xmScrolledWindowWidgetClass, win, wargs, i);
XtRealizeWidget(toplevel);
XtMainLoop();
}