[comp.windows.open-look] OLIT --- Problems outside the event loop

ali@boulder.Colorado.EDU (Ali Baharami) (01/09/91)

  I've run into a problem while writing a program using
OLIT that I hope someone can help me with. The environment is
Open Windows 2.0 on a Sparcstation 1+ under SunOS 4.1. Unlike most
applications, my program is unable to live in the event loop,
which is how I came up against this:

Suppose I create and realize the following hierarchy:

        (top level shell) --> (Bulletin Board) --> (Static Text)

Later, while outside the event loop, if I try to destroy the static
text widget and create a new one with the same parent, I get an X
protocol error and the program quits. (I realize that I could just
change the label with the XtNstring resource, but that wouldn't
demonstrate the problem I'm having.) If I write a conventionally
structured program which lives in the event loop and the static
text widget is killed inside a callback, there is no problem.
                        
To demonstrate this, I wrote the following program.
(Sorry about the length --- it was difficult to boil it down.) It uses
select() to wait on input from the keyboard or the X Server. On input
from the server, it simply dispatches any pending events. The first
time input arrives from stdin, the static text widget is killed and a
new one put in its place. The second time input arrives from stdin, the
program exits:

    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/time.h>
    #include <X11/Intrinsic.h>
    #include <Xol/OpenLook.h>
    #include <X11/StringDefs.h>
    #include <Xol/BulletinBo.h>
    #include <Xol/StaticText.h>
      
    
    int main(argc, argv)
         int argc;
         char *argv[];
    {
      Arg arg;
      Widget top;                   /* Top Level shell widget */
      Widget base;                  /* Bboard widget to hold label */
      Widget label;                 /* The label */
      char buf[1024];               /* Gets input from stdin */
      int stdin_input;              /* # of lines input from stdin */
    
      Display *display;
      XEvent event;
    
      /* For select(2) */
      int select_width;
      int x_fd;
      int stdin_fd;
      fd_set readfds;
    
    
      top = OlInitialize(NULL, "test", NULL, 0, &argc, argv);
      display = XtDisplay(top);
    
      base = XtCreateManagedWidget("base", bulletinBoardWidgetClass,
                                   top, &arg, 0);
    
      XtSetArg(arg, XtNstring, "Hello");
      label = XtCreateManagedWidget("label", staticTextWidgetClass,
                                    base, &arg, 1);
      XtRealizeWidget(top);
        
      x_fd = XConnectionNumber(display);
      stdin_fd = fileno(stdin);
      select_width = x_fd + 1;
      stdin_input = 0;              /* # of lines seen on stdin */
      XSync(display, False);        /* Get the ball rolling */
    
      for (;;) {
    
        FD_ZERO(&readfds);
        FD_SET(stdin_fd, &readfds);   /* stdin */
        FD_SET(x_fd, &readfds);       /* X server */
        if (select(select_width, &readfds, (fd_set *) 0, (fd_set *) 0,
                   (struct timeval *) 0) == -1) {
          (void) fprintf(stderr, "Unable to call select.\n");
          exit(1);
        }
    
        if (FD_ISSET(x_fd, &readfds)) {   /* X events have arrived. */
          while (XtPending()) {     /* Handle any waiting events */
            XtNextEvent(&event);
            XtDispatchEvent(&event);
          }
        } else {                    /* Input on stdin */
          if (gets(buf) == NULL) exit(0);   /* Read stdin */
          if (!stdin_input++) {             /* First input? change label */
            XtDestroyWidget(label);
            XtSetArg(arg, XtNstring, "Goodbye");
            label = XtCreateManagedWidget("label", staticTextWidgetClass,
                                          base, &arg, 1);
            XSync(display, False);   /* Flush the changes... */
          } else {                  /* Not first input? Quit. */
            break;                  /* for(;;) */
          }
        }
    
      }                             /* for(;;) */
      return(0);
    }

Compile it with:

        cc -I$OPENWINHOME/include -o test test.c \
                      -L$OPENWINHOME/lib -lXol -lXt -lX11

Run it. It puts up a little window with the text "Hello".
If you press return while in the window you ran test from,
it should delete the label widget and add a new one to
the bulletin board widget with the text "Goodbye", but instead:

        X Error:  BadValue
          Request Major code 12 ()
          Request Minor code 0
          ResourceID 0x0
          Error Serial #82
          Current Serial #82

I was able to do this using Motif, which makes me suspicious of the OLIT
version of the Intrinsics, but I realize that it is far more likely
that I am simply making some sort of basic mistake. Any help, information,
pointers to documentation I should read, etc. will be most appreciated.
(I already have (1) The O'Reilly books, (2) The OLIT documentation
from Sun, (3) "An OPEN LOOK at Unix" by John David Miller, so I think
I've got the basic documentation covered.)

Thanks for anything you can tell me.
-----------------------------------------------------------------------------
Ali Bahrami
Research Systems, Inc, Boulder CO., (303) 786-9900
ali@boulder.colorado.edu   <- Ignore the reply address at the top. Use this.
-----------------------------------------------------------------------------