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(); }