reading input from a stream in xview

Laurence R. Brothers quasar at ctt.bellcore.com
Thu Nov 30 09:34:02 AEST 1989


After some struggle, I've finally managed to do it reliably.

The obvious way to do this is to use "implicit dispatching", a mechanism
more or less the same in sunview and xview that allows you to replace
xv_main_loop() with your own code, on the understanding that event
dispatching will only occur when you are hung in a blocking read.

Another obvious possibility is using "explicit dispatching", a similar
mechanism under which event dispatching will only occur when you call
notify_dispatch() -- obviously for this you should use nonblocking reads
or the program will hang when there is no input.

Unfortunately, neither of these currently works the way I needed.

Implicit dispatching does in fact function, but unfortunately, due to what
is SOP in X, things you display or render in response to input do not
necessarily get shown immediately -- instead they are buffered, a natural
consequence of the distributed X client and server. The result of this is
that what you think has been displayed has not been.  With more and more
input and no user events (input events flush the buffer), eventually the
buffer overflows, or some other internal error dumps core.

Explicit dispatching (at least a la sunview) fails entirely and hangs the
interface.

A search of the xview manual revealed the existence of the following calls
(of course, not properly indexed):

xv_set(xv_default_server,SERVER_SYNC,1,0);
xv_set(xv_default_server,SERVER_SYNC_AND_PROCESS_EVENTS,1,0);
XSync((Display*)xv_default_server,0);
XFlush((Display*)xv_default_server,0);

Apparently, any one of the above should at least have the effect of
flushing the X buffer, and thus fixing the above problem with implicit
dispatching. Actually, the first two completely wedge the program.  The
last two, which are Xlib calls, have the effect of a programmatic call to
exit() -- ie, the program immediately terminates with no error message.

So no joy with either special dispatching mechanism. Finally, after much
travail, I discovered another mechanism in the sunview (not xview) manual:

notify_set_input_func(base_frame,input_read_proc,input_fd);

What this does is tells the notifier that whenever input is available for
immediate read on the file descriptor input_fd, post an input event that
calls input_read_proc (your i/o routine). This first of all lets you go
back to using xv_main_loop(), and secondly fixes the X buffering problem,
as input events immediately automagically stimulate flushing the X
protocol buffer. Your read function is also guaranteed not to block since
an event is only posted when there is data present on the input fd
already. If the input_fd is some kind of stream, like a pipe for example
(my case), then the data coming in is reliable and buffered correctly, so
you don't have to fiddle about writing complicated i/o routines, but can
simply read whatever is there to be read.

notify_set_input_func() is of course undocumented in the xview manual,
but supported by the xview include files and library archives.

	    Laurence R. Brothers (quasar at ctt.bellcore.com)



More information about the Comp.sys.sun mailing list