Path: utzoo!censor!geac!torsqnt!news-server.csri.toronto.edu!cs.utexas.edu!tut.cis.ohio-state.edu!ucbvax!bloom-beacon!LARRY.MCRCIM.MCGILL.EDU!mouse From: mouse@LARRY.MCRCIM.MCGILL.EDU Newsgroups: comp.windows.x Subject: Re: How Do You Monitor Events For More Than 1 Display? Message-ID: <9012041241.AA01920@Larry.McRCIM.McGill.EDU> Date: 4 Dec 90 12:41:23 GMT Sender: daemon@athena.mit.edu (Mr Background) Organization: The Internet Lines: 109 > I am writing this program which is supposed to wait for KeyPress > events from more than 1 display, however, after thinking about it for > a long long time, I don't really know how to do it. Please enlighten > me. It's system-dependent. I don't know enough about toolkits to say for sure, but I would hope that most/all toolkits would provide some way of doing this. On BSD UNIX (or other Unices which have been BSDified enough to have select()), the canonical way of doing this is to gobble up all events that are available on the connections, then select() waiting for something to arrive. > To be more concrete, here's what I will do if I only have 1 display: > for (;;) { > XNextEvent(display, &event); > } Well, you also need to do something with the event; just reading it isn't going to be very useful. I have a program that speaks to multiple displays. Here is its event loop, with irrelevant code stripped out. (The real function is about twice as big as what you see here; it does input from another file descriptor, and timeouts, in this loop as well.) (DISP_INFO is a typedef referring to my structure containing all the interesting information about each connection. disps is a global pointer to a linked list of these structures.) #define EACH_DISP(var) var=disps;var;var=var->link run() { XEvent e; DISP_INFO *d; int selrv; int wantflush; int wantupd; fd_set fds; int selcnt; int mustcontinue; struct timeval *tvp; for (EACH_DISP(d)) d->xfd = XConnectionNumber(d->disp); wantflush = 1; wantupd = 0; while (1) { mustcontinue = 0; for (EACH_DISP(d)) { if (XQLength(d->disp) > 0) { do { XNextEvent(d->disp,&e); handle_event(&e); } while (XQLength(d->disp) > 0); wantupd = 1; mustcontinue = 1; } } if (mustcontinue) continue; FD_ZERO(&fds); for (EACH_DISP(d)) FD_SET(d->xfd,&fds); if (wantflush || wantupd) { static struct timeval ztv; ztv.tv_sec = 0; ztv.tv_usec = 0; tvp = &ztv; } else { tvp = 0; } selrv = select(FD_SETSIZE,&fds,(fd_set *)0,(fd_set *)0,tvp); if (selrv < 0) { if (errno == EINTR) continue; perror("select"); utexit(1); } if (selrv == 0) { if (wantupd) { update_display(); wantflush = 1; wantupd = 0; } if (wantflush) { for (EACH_DISP(d)) XFlush(d->disp); if (debugging) fflush(stdout); wantflush = 0; } continue; } for (EACH_DISP(d)) { if (FD_ISSET(d->xfd,&fds)) { int bpend; ioctl(d->xfd,FIONREAD,&bpend); if (bpend == 0) /* socket EOF */ { utexit(0); } XEventsQueued(d->disp,QueuedAfterReading); } } } } der Mouse old: mcgill-vision!mouse new: mouse@larry.mcrcim.mcgill.edu