logan@crystel.UUCP (Mark) (01/16/91)
I am trying to write a program, using Xlib right now, which receives input from several sockets and displays them on the screen. (I am using a SPARCstation SLC with SunOS 4.1 and OpenWindows.) The only way I can think of doing this is polling, which I am unhappy with for performance reasons. I call XCheckMaskEvent() to check for an event, and then I call select() on the socket file descriptors with a timeout of 1 second. I would rather use something like select() to check for input from the XEvent list at the same time as the sockets. Can anyone think of a way to do this? Thanks in advance, Mark Logan uunet!lcc!turnkey!crystel!logan
tbecker@sirius.informatik.uni-kl.de (Thomas Becker) (01/18/91)
In comp.windows.x you write: >I am trying to write a program, using Xlib right now, which receives >input from several sockets and displays them on the screen. I have had the same problem some time ago (using Xlib only). In fact X events are nothing else but messages coming in through a socket. By the macro socket = ConnectionNumber(display) you get the socket connection id to the X server, which you can use as any other socket for setting up masks required in select(). However, I had some slight trouble with this: calling select() for the FIRST time, select() told me that an X event is ready to be received, but XNextEvent() couldn't find any. I have solved the problem by looking for the first X event with XPpending() or some other non-blocking function, and then using select() only. So your program should roughly look like that: x_socket = (1 << ConnectionNumber(display)); sockwet_mask |= x_socket; if (XPending(display)) { /* handle event */ } do { i = select(..., &socket_mask, ...); if (socket_mask & x_socket) { XNextEvent(display, &event); /* handle event */ } else { /* ... */ } } Hope that helps. Thomas Becker -- Thomas Becker +---------+ acoustic: Computer Science Department | /"""\ | +49 631 205 3295 University of Kaiserslautern | { O~O } | electronic: P.O.Box 3049 | \ U / | tbecker@informatik.uni-kl.de
dvb@emisle.uucp (David Van Beveren) (01/19/91)
In article <tbecker.664209752@sirius> tbecker@sirius.informatik.uni-kl.de (Thomas Becker) writes: . . >I have had the same problem some time ago (using Xlib only). >In fact X events are nothing else but messages coming in through a socket. . . . Is this true? That seems like a implementation-dependant thing. In fact, I know that ISC X rev 1.2 can run without the ISC TCP/IP package. They have a (dummy?) libinet.a that you link, that comes with the X package. When you get TCP/IP (if), then you get a "real" libinet.a. I have always assumed that you cannot depend on the Xprotocol messages being delivered over a socket. What about machines that support AT&T TLI only? I am very interested in this. I have an X application that uses a XtWorkProcess in the background of the event loop to do a select on an open socket. The following code is from an application I inherited at one time, and this (an event loop trying to monitor other sockets besides the 'x socket' does not work (does not compile if I remember correcty) in the Interactive configuration that does not include TCP/IP. But, when you add that package, it works fine. If someone at Interactive could clear this up I would appreciate it. In any case, if your application needs to be portable, I would not assume that X is implemented on top of some BSD socket transport mechanism. when you add the TCP/IP package, it runs fine. #include "common.h" #include <sys/socket.h> mainloop (dpy, tcpsock) Display *dpy; int tcpsock; { fd_set fdmask; XEvent event; struct timeval timeout; int displayFD; int ret; /* get file descriptor of TCP stream connection to server */ displayFD = XConnectionNumber (dpy); while (1) { allock(); /* * Look for events. Try to arrange that X events have priority over * network traffic. See if there's an X event pending. If so, check * for a net event, too; if not, select on both the network and the X * connection. If that doesn't time out, but there's no X event * pending, try again, just selecting on the X connection. If that * times out, let the network event get processed. * * Can't just select on the two fds, because there may be X events * pending in the queue that have already been read. * * This may look baroque, but we've seen some instances where X server * latency seems to let the network events take priority over server * events, leading to sluggish keyboard response and lots of local * death. */ FD_ZERO (&fdmask); tcp_setfds (&fdmask); /* enable all client fds */ if (! XPending (dpy)) { /* nothing on the X connection */ FD_SET (displayFD, &fdmask); while ((ret = select (32, &fdmask, NULL, NULL, (struct timeval *)0)) == -1) if (errno != EINTR) perror("select error on events(1)"); if (ret == 0) { continue; } } /* *** */ else { timeout.tv_sec = 0; timeout.tv_usec = 0; while ((ret = select (32, &fdmask, NULL, NULL, &timeout)) == -1) if (errno != EINTR) perror("select error on events(2)"); } /* handle X events */ if (XPending (dpy)) { XNextEvent (dpy, &event); HandleEvent (dpy, &event); } /* handle TCP listener and clients */ tcp_service_fds (&fdmask); } /*NOTREACHED*/ } dvb David Van Beveren INTERNET: emisle!dvb@ism.isc.com EIS ltd. Professional Software Services UUCP: ..uunet!emisle!dvb voice: (818) 587-1247