From: juando@cnm.us.es
Subject: Re: Socket Events? (IV3.1)
X-Unparsable-Date: Wed,  9 Sep 1992  5: 25:54 UTC+0100
Organization: Internet-USENET Gateway at Stanford University
Date: Wed, 9 Sep 1992 03:31:06 GMT

>X-Envelope-to: interviews@interviews.stanford.edu

>Date: 8 Sep 92 23:58:22 GMT
>From: howard@coredump.hrl (Mike Howard)
>Subject: Socket Events? (IV3.1)
>
>I have an image viewer similar to the TIFFviewer in IV3.1,
>and would like to have an outside application tell it to
>change images.  What is the best way to do this?
>* create a socket with an event handler?
>* use the RPC class?
>* create an X event?
>I'm very new to IV, so please be gentle...
>
>Mike Howard, Hughes Research Labs, Malibu
>

Some time ago I made a simple example for other InterView's user regarding a
similar question. The application reads data through a pipe and flips a Deck
according to the data received. The data read are numbers from 1 to 7 and
the Deck shows a week day. As I have seen an earlier request for simple
examples I'm posting the example in shar format.

To build unshar and type

%ivmkmf
%make depend
%make

It will create a couple of executables in the same directory. One is pipedemo
and the other is daynums. Pipedemo invokes daynums through popen() call and
then reads and displays the data.

Hope it helps,

Juan
-- 
Juan D. Martin                     Centro Nacional de Microelectronica
<juando@cnm.us.es>                                   Edificio C.I.C.A.
Phone: 34-5-4623811                             Av/ Reina Mercedes s/n
Fax:   34-5-4624506                               41012-SEVILLA, SPAIN

---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is a shell archive (produced by shar 3.50)
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
#
# made 09/09/1992 03:18 UTC by juando@cnmus
# Source directory /mnt/electron/juando/iv/pipedemo
#
# existing files will NOT be overwritten unless -c is specified
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#    256 -rw-r----- Imakefile
#    173 -rw-r----- daynums.c
#   3709 -rw-r----- main.c
#
# ============= Imakefile ==============
if test -f 'Imakefile' -a X"$1" != X"-c"; then
	echo 'x - skipping Imakefile (File already exists)'
else
echo 'x - extracting Imakefile (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'Imakefile' &&
XXCOMM
XXCOMM pipedemo - Read from a pipe and display the data.
XXCOMM
X
AOUT=pipedemo
APP_CCFLAGS = $(DEBUG_CCFLAGS)
X
Use_libInterViews()
ComplexProgramTarget(pipedemo)
X
MakeObjectFromSrc(main)
X
all:: daynums
X
daynums : daynums.c
X	$(CCDRIVER) -o $@ daynums.c
SHAR_EOF
chmod 0640 Imakefile ||
echo 'restore of Imakefile failed'
Wc_c="`wc -c < 'Imakefile'`"
test 256 -eq "$Wc_c" ||
	echo 'Imakefile: original size 256, current size' "$Wc_c"
fi
# ============= daynums.c ==============
if test -f 'daynums.c' -a X"$1" != X"-c"; then
	echo 'x - skipping daynums.c (File already exists)'
else
echo 'x - extracting daynums.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'daynums.c' &&
#include <stdio.h>
#include <osfcn.h>
X
int cnt = 1;
X
main()
{
X    for(;;)
X    {
X	printf("%d\n", cnt);
X	fflush(stdout);
X	cnt++;
X	if(cnt > 7)
X	    cnt = 1;
X	sleep(1);
X    }
}
SHAR_EOF
chmod 0640 daynums.c ||
echo 'restore of daynums.c failed'
Wc_c="`wc -c < 'daynums.c'`"
test 173 -eq "$Wc_c" ||
	echo 'daynums.c: original size 173, current size' "$Wc_c"
fi
# ============= main.c ==============
if test -f 'main.c' -a X"$1" != X"-c"; then
	echo 'x - skipping main.c (File already exists)'
else
echo 'x - extracting main.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'main.c' &&
#include <Dispatch/dispatcher.h>
#include <Dispatch/iocallback.h>
#include <InterViews/action.h>
#include <InterViews/session.h>
#include <InterViews/layout.h>
#include <InterViews/deck.h>
#include <InterViews/patch.h>
#include <InterViews/window.h>
#include <IV-look/kit.h>
#include <stdio.h>
X
class App
{
public:
X    App();
X    ~App();
X
X    void run(int, char **);
X    int input(int);
X    void quit();
X
private:
X    IOHandler *_input;
X    Window *_win;
X    WidgetKit *_kit;
X    LayoutKit *_layout;
X    Deck *_deck;
X    Patch  *_patch;
X    Glyph *_body;
X    FILE *_pipe;
};
X
// We need this in order to build IOHandlers and Actions from App
// member functions.
X
declareIOCallback(App)
declareActionCallback(App)
implementIOCallback(App)
implementActionCallback(App)
X
X
main(int argc, char **argv)
{
X    App *a = new App();
X    a->run(argc, argv);
X    delete a;
X    return 0;
}
X
App::App()
{
}
X
void App::run(int argc, char** argv)
{
X    // Get the dispatcher. It will be shared by App and Session.
X    Dispatcher &dp = Dispatcher::instance();
X
X    Session *session = new Session("Pipe Demo", argc, argv, nil, nil);
X    _kit = WidgetKit::instance();
X    _layout = LayoutKit::instance();
X    WidgetKit &kit = *_kit;
X    LayoutKit &layout = *_layout;
X
X    Glyph *hspace = layout.hglue(18.0, fil, 16.0);
X    Glyph *vspace = layout.vglue(18.0, fil, 16.0);
X
X    // Build the Deck.
X    _deck = layout.deck();
X    _deck->append(kit.label("Bad input"));
X    _deck->append(kit.label("Monday"));
X    _deck->append(kit.label("Tuesday"));
X    _deck->append(kit.label("Wednesday"));
X    _deck->append(kit.label("Thursday"));
X    _deck->append(kit.label("Friday"));
X    _deck->append(kit.label("Saturday"));
X    _deck->append(kit.label("Sunday"));
X    _deck->flip_to(1);
X
X    // Now for the Patch.
X    _patch = new Patch(_deck);
X
X    // This builds an IOHandler that calls App::input() when there is input.
X    _input = new IOCallback(App)(this, &App::input);
X
X    // This builds an Action that calls app::quit()
X    Action *a_quit = new ActionCallback(App)(this, &App::quit);
X
X    // Place things.
X    _body = kit.outset_frame(
X	layout.hbox(
X	    hspace,
X	    layout.vbox(
X		vspace,
X		layout.hbox(
X		    hspace,
X		    kit.push_button("Quit", a_quit),
X		    hspace
X		),
X		vspace,
X		_patch,
X		vspace
X	    ),
X	    hspace
X	)
X    );
X    _win = new ApplicationWindow(_body);
X
X    // Start the second program.
X    _pipe = popen("daynums", "r");
X    if(!_pipe)
X    {
X	fprintf(stderr, "Popen failed\n");
X	exit(1);
X    }
X
X    //Tell the Dispatcher to call the IOHandler when there is
X    // something to read.
X    dp.link(fileno(_pipe), Dispatcher::ReadMask, _input);
X
X    session->run_window(_win);
}
X
App::~App()
{
X    // Clean things.
X    Dispatcher &dp = Dispatcher::instance();
X    if(_pipe)
X    {
X	dp.unlink(fileno(_pipe));
X	pclose(_pipe);
X    }
X    delete _input;
X    delete _kit;
X    delete _layout;
}
X
// This method is called when there is input pending. Note that the
// argument is ignored. We can do that beacause this handler is linked
// to one descriptor only. We would need the argument if we were listening
// to more than one descriptor through the same handler. In that case the
// argument would tell which descriptor we have to use.
int App::input(int)
{
X    int day = 0;
X    fscanf(_pipe, "%d", &day);
X    if(day < 1 || day > 7)
X	day = 0;
X
X    _deck->flip_to(day);
X    _patch->redraw();
X
X    // We return 0 to indicate that we have read everything for now, but
X    // See the man page for details about other return values.
X    return 0;
}
X
void App::quit()
{
X    // Delete the window and quit.
X    // Cleaning is done in App::~App(), but you can move it here.
X    delete _win;
X    _kit->quit()->execute();
}
SHAR_EOF
chmod 0640 main.c ||
echo 'restore of main.c failed'
Wc_c="`wc -c < 'main.c'`"
test 3709 -eq "$Wc_c" ||
	echo 'main.c: original size 3709, current size' "$Wc_c"
fi
exit 0

Newsgroups: comp.windows.interviews