aboutsummaryrefslogtreecommitdiff
path: root/vendor/x11iraf/vximtool
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
commitfa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch)
treebdda434976bc09c864f2e4fa6f16ba1952b1e555 /vendor/x11iraf/vximtool
downloadiraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz
Initial commit
Diffstat (limited to 'vendor/x11iraf/vximtool')
-rw-r--r--vendor/x11iraf/vximtool/Imakefile45
-rw-r--r--vendor/x11iraf/vximtool/vximtool.c2147
-rw-r--r--vendor/x11iraf/vximtool/vximtool.man178
-rw-r--r--vendor/x11iraf/vximtool/vximtool.ps1569
-rw-r--r--vendor/x11iraf/vximtool/vximtool_non_cdl.c1728
5 files changed, 5667 insertions, 0 deletions
diff --git a/vendor/x11iraf/vximtool/Imakefile b/vendor/x11iraf/vximtool/Imakefile
new file mode 100644
index 00000000..5eb85b57
--- /dev/null
+++ b/vendor/x11iraf/vximtool/Imakefile
@@ -0,0 +1,45 @@
+# Imakefile for the Virtual XImtool display server.
+
+X11IRAFDIR = ../
+#include <../X11IRAF.tmpl>
+
+ CDEBUGFLAGS = -g
+
+ LOCAL_LDFLAGS = $(X11IRAF_LDFLAGS)
+ EXTRA_INCLUDES = $(X11IRAF_INCLUDES)
+ OBMLIBS =
+ MATHLIB = -lm
+ CDLLIB = -lcdl
+ XAWLIB =
+
+ SRCS = vximtool.c
+ OBJS = vximtool.o
+
+
+AllTarget(vximtool)
+
+vximtool: vximtool.o
+ $(RM) vximtool
+ $(CC) -o vximtool -DHAVE_CDL vximtool.o $(LDOPTIONS) $(CDLLIB) \
+ $(MATHLIB) $(EXTRA_LIBRARIES)
+
+vximtool.o:
+ $(CC) -c $(CFLAGS) -DHAVE_CDL vximtool.c
+
+clean::
+ $(RM) vximtool vximtool.o
+
+#if InstallManuals
+install::
+ MakeDir(X11irafManDir)
+ $(CP) vximtool.man X11irafManDir/vximtool.1
+#endif
+
+#if InstallBinaries
+install:: vximtool
+ -@if [ -d X11irafBinDir ]; then set +x; \
+ else (set -x; $(MKDIRHIER) X11irafBinDir); fi
+ $(CP) vximtool X11irafBinDir
+#endif
+
+DependTarget()
diff --git a/vendor/x11iraf/vximtool/vximtool.c b/vendor/x11iraf/vximtool/vximtool.c
new file mode 100644
index 00000000..42f919cd
--- /dev/null
+++ b/vendor/x11iraf/vximtool/vximtool.c
@@ -0,0 +1,2147 @@
+/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+ */
+
+#include <sys/times.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#if defined(AIX) || defined(AIXV3) || defined (AIXV4)
+#include <sys/select.h>
+#endif
+#include <netinet/in.h>
+#include <sys/un.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+#ifdef HAVE_CDL /* If we have the CDL we can build a proxy server. */
+#include "cdl.h"
+#endif
+
+
+/*
+ * VXIMTOOL.C -- Virtual image display server. This is a server process much
+ * like XIMTOOL, except that all the process does is respond to datastream
+ * requests to read and write to internal frame buffers maintained as arrays
+ * in memory. Multiple frame buffers and frame buffer configurations are
+ * supported. A log is kept to the stderr of all datastream requests. The
+ * process is terminated with an EOF on the stdin.
+ *
+ *
+ * To build: cc vximtool.c -o vximtool
+ * cc vximtool.c -o vximtool -lsocket # For Solaris systems
+ * cc -DANSI_FUNC vximtool.c # Use ANSI function prototypes
+ *
+ * Usage: vximtool -verbose >& spool # run server, log output
+ * vximtool -i # run interactively
+ * vximtool -noraster # don't store images in memory
+ * vximtool -i < cursor_file # take cursor input from file
+ *
+ * Options
+ *
+ * vximtool [-background] [-config <num>] [-fifo <pipe>] [-fifo_only] [-help]
+ * [-i] [-imtoolrc <file>] [-inet_only | -port_only] [-noraster]
+ * [-nframes <num>] [-port <num>] [-proxy] [-verbose] [-unix <name>]
+ * [-unix_only]
+ *
+ *
+ * Minimal match for command line options may be used. In interactive mode,
+ * cursor value strings may be typed in on the server stdin in response to
+ * cursor read requests from the client. Otherwise, a constant cursor value
+ * "1.0 1.0 101 q" is returned.
+ */
+
+
+/* Default values, size limiting values.
+ */
+#define MAX_FBCONFIG 128 /* max possible frame buf sizes */
+#ifndef HAVE_CDL
+#define MAX_FRAMES 16 /* max number of frames */
+#endif
+#define MAX_MAPPINGS 32 /* max number mappings/frame */
+#define MAX_CLIENTS 8 /* max display server clients */
+#define DEF_NFRAMES 1 /* save memory; only one frame */
+#define DEF_FRAME_WIDTH 512 /* 512 square frame */
+#define DEF_FRAME_HEIGHT 512 /* 512 square frame */
+
+#define SZ_LABEL 256 /* main frame label string */
+#define SZ_IMTITLE 128 /* image title string */
+#define SZ_FIFOBUF 4000 /* transfer size for FIFO i/o */
+#define SZ_FNAME 256
+#define SZ_LINE 256
+
+/* Magic numbers. */
+#define DEF_PORT 5137 /* default tcp/ip socket */
+#define DEF_NPORTS 1 /* default no. sockets to open */
+#define DEF_PROXY_PORT 5136 /* default proxy socket */
+#define I_DEVNAME "/dev/imt1o" /* pseudo device names */
+#define O_DEVNAME "/dev/imt1i" /* our IN is client's OUT */
+#define DEF_UNIXADDR "/tmp/.IMT%d" /* default unix socket */
+#define FBCONFIG_1 ".imtoolrc"
+#define FBCONFIG_2 "/usr/local/lib/imtoolrc"
+#define FBCONFIG_ENV1 "imtoolrc"
+#define FBCONFIG_ENV2 "IMTOOLRC"
+
+/* IIS definitions. */
+#define IO_TIMEOUT 30
+#define MAXCONN 5
+#define SZ_IOBUF 65536 /* max size data transfer */
+#define SZ_FIFOBUF 4000
+#define SZ_OLD_WCSBUF 320 /* old WCS text buffer size */
+#define SZ_WCSBUF 1024 /* WCS text buffer size */
+#define SZ_FNAME 256
+#define SZ_IMCURVAL 160
+
+#define IIS_VERSION 10 /* version 10 -> 1.0 */
+
+#define MEMORY 01 /* frame buffer i/o */
+#define LUT 02 /* lut i/o */
+#define FEEDBACK 05 /* used for frame clears */
+#define IMCURSOR 020 /* logical image cursor */
+#define WCS 021 /* used to set WCS */
+
+#define PACKED 0040000
+#define COMMAND 0100000
+#define IIS_READ 0100000
+#define IMC_SAMPLE 0040000
+#define IMT_FBCONFIG 077
+#define XYMASK 077777
+
+struct iism70 { /* DO NOT change the order of */
+ short tid; /* this structure. */
+ short thingct;
+ short subunit;
+ short checksum;
+ short x, y, z;
+ short t;
+};
+
+/* IIS data pixel values. */
+#define CMS_DATASTART 1
+#define CMS_DATAEND 200
+#define CMS_DATARANGE 200
+
+/* WCS definitions. */
+#define W_UNITARY 0
+#define W_LINEAR 1
+#define W_LOG 2
+#define W_DEFFORMAT " %7.2f %7.2f %7.1f%c"
+
+/* Rotation matrix defining world coordinate system (WCS) of a frame. */
+typedef struct {
+ int valid; /* has WCS been set? */
+ float a, b; /* x, y scale factors */
+ float c, d; /* x, y cross factors */
+ float tx, ty; /* x, y translation */
+ float z1, z2; /* greyscale range */
+ int zt; /* greyscale mapping */
+ char format[32]; /* wcs output format */
+ char imtitle[SZ_IMTITLE+1]; /* image title from WCS */
+} Ctran, *CtranPtr;
+
+/* Coordinate mappings on each frame buffer. */
+typedef struct {
+ int id; /* object id */
+ Ctran ctran; /* world coordinate system */
+ char ref[SZ_FNAME+1]; /* image reference from WCS */
+ int regid; /* region id */
+ char region[SZ_FNAME+1]; /* region name from WCS */
+ float sx, sy; /* source rect */
+ int snx, sny;
+ int dx, dy; /* destination rect */
+ int dnx, dny;
+} Mapping, *MappingPtr;
+
+/* The frame buffers. */
+typedef struct {
+ int frameno; /* frame number */
+ char *framebuf; /* frame buffer raster */
+ char label[SZ_LABEL+1]; /* frame label string */
+ Ctran ctran; /* world coordinate system */
+ char wcsbuf[SZ_WCSBUF]; /* wcs info string */
+ Mapping mapping[MAX_MAPPINGS]; /* coordinate mappings */
+ int nmaps; /* number of defined mappings */
+} FrameBuf, *FrameBufPtr;
+
+/* Possible frame buffer sizes. */
+typedef struct {
+ int nframes; /* number of frames */
+ int width; /* frame buffer width */
+ int height; /* frame buffer height */
+} FbConfig, *FbConfigPtr;
+
+/* Client I/O channel. */
+typedef struct {
+ void *vxim; /* backpointer to vxim descriptor */
+ int type; /* channel type */
+ int listen_fd; /* socket server fd */
+ int datain; /* input channel */
+ int dataout; /* output channel */
+ int keepalive; /* used to keep input fifo ready */
+ int connected; /* channel is connected to client */
+ int port; /* inet port number */
+ char path[SZ_FNAME+1]; /* for unix sockets */
+ int reference_frame; /* reference (cmd i/o) frame */
+ int version; /* flags capability of client */
+ FrameBufPtr rf_p; /* reference frame descriptor */
+} IoChan, *IoChanPtr;
+
+#define IO_FIFO 1
+#define IO_INET 2
+#define IO_UNIX 3
+
+
+/* Application runtime descriptor.
+ * --------------------------------
+ */
+typedef struct {
+ int def_config; /* default FB config */
+ int def_nframes; /* default number of frames */
+ char *imtoolrc; /* imtoolrc file name */
+ char *input_fifo; /* client's output */
+ char *output_fifo; /* client's input */
+ char *unixaddr; /* format for unix socket path */
+ int port; /* port for INET socket */
+ int nports; /* nports to open */
+
+ /* Internal state. */
+ int display_frame; /* currently displayed frame */
+ int fb_configno; /* current config number */
+ int nframes; /* current number of frame bufs */
+ int width, height; /* current width, height */
+ IoChan chan[MAX_CLIENTS]; /* client i/o descriptors */
+ FrameBufPtr df_p; /* display frame descriptor */
+ FrameBuf frames[MAX_FRAMES]; /* array of frame descriptors */
+ FbConfig fb_config[MAX_FBCONFIG]; /* fb config table */
+
+} VXimData, *VXimDataPtr;
+
+
+/* Initialize the structure with out starting values. These can be reset
+ * with command line options.
+ */
+VXimData server_data = {
+ 1, /* def_config */
+ DEF_NFRAMES, /* def_nframes */
+ FBCONFIG_2, /* def_imtoolrc */
+ O_DEVNAME, /* input_fifo */
+ I_DEVNAME, /* output_fifo */
+ DEF_UNIXADDR, /* unixaddr */
+ DEF_PORT, /* port */
+ DEF_NPORTS, /* nports */
+ 1, /* display_frame */
+ 1, /* fb_configno */
+ 2, /* nframes */
+ 512, 512 /* width, height */
+};
+
+/* Functions.
+ */
+#ifndef abs
+#define abs(a) (((a)<0)?(-(a)):(a))
+#endif
+#ifndef min
+#define min(a,b) ((a)<(b)?(a):(b))
+#endif
+#ifndef max
+#define max(a,b) ((a)<(b)?(b):(a))
+#endif
+
+#ifdef SOLARIS
+#define bzero(a,n) memset(a,0,n)
+#define bcopy(a,b,n) memmove(b,a,n)
+#endif
+
+#define SELWIDTH 32
+
+#ifdef HAVE_CDL
+static int proxy = 0;
+static int nclients = 0;
+CDLPtr cdl[MAX_CLIENTS];
+#endif
+static int keep_raster = 1;
+extern int errno;
+static int background = 0;
+static int objid = 0;
+static int verbose = 0;
+static int interactive = 0;
+static float cursor_x = 1.0, cursor_y = 1.0;
+static fd_set fds, allset;
+
+
+#ifdef ANSI_FUNC
+
+int main(int argc, char **argv);
+static int vx_iisopen(register VXimDataPtr vxim);
+static void vx_iisclose(register VXimDataPtr vxim);
+static IoChanPtr open_fifo(register VXimDataPtr vxim);
+static IoChanPtr open_inet(register VXimDataPtr vxim);
+static IoChanPtr open_unix(register VXimDataPtr vxim);
+static void vx_connectClient(IoChanPtr chan, int *source);
+static void vx_disconnectClient(register IoChanPtr chan);
+static IoChanPtr get_iochan(register VXimDataPtr vxim);
+static void vx_iisio(IoChanPtr chan, int *fd_addr, int source);
+static void set_fbconfig(IoChanPtr chan, int config, int frame);
+static int decode_frameno(register int z);
+static void bswap2(char *a, char *b, int nbytes);
+static void vx_retCursorVal(register int dataout, float sx, float sy,
+ int wcs, int key, char *strval);
+static CtranPtr wcs_update(register VXimDataPtr vxim, FrameBufPtr fr);
+static void vx_initialize(register VXimDataPtr vxim, int config,
+ int nframes, int reset);
+static void vx_initFrame(register VXimDataPtr vxim, int frame,
+ int nframes, FbConfigPtr config);
+static void vx_eraseFrame(register VXimDataPtr vxim, int frame);
+static void get_fbconfig(register VXimDataPtr vxim);
+static void Usage(void);
+static void printoption(char *st);
+static void add_mapping(register VXimDataPtr vxim, CtranPtr ctran,
+ char *wcsbuf, FrameBufPtr fr);
+#ifdef HAVE_CDL
+static void vx_flip(char *buffer, int nx, int ny);
+#endif
+static int iis_read (int fd, void *vptr, int nbytes);
+static int iis_write (int fd, void *vptr, int nbytes);
+
+#else
+
+static void vx_iisclose(), vx_connectClient(), vx_disconnectClient();
+static void vx_iisio(), set_fbconfig(), vx_retCursorVal();
+static void vx_initialize(), vx_initFrame(), vx_eraseFrame();
+static void get_fbconfig(), Usage(), printoption();
+static void add_mapping();
+#ifdef HAVE_CDL
+static void vx_flip();
+#endif
+static int vx_iisopen(), decode_frameno(), iis_read(), iis_write();
+static void bswap2();
+static IoChanPtr open_fifo(), open_inet(), open_unix(), get_iochan();
+static CtranPtr wcs_update();
+
+#endif
+
+
+/*
+ * VXIMTOOL -- Virtual display server process. This task is an image display
+ * server like XImtool, responding to datastream requests on fifo pipes,
+ * inet sockets, or unix sockets. Up to 16 frames are supported, frame
+ * buffers may be any of the defined frames in the imtoolrc file. Images
+ * are stored in memory, allowing readback by the client. Cursor input can
+ * come from stdin (or a redirected file) allowing the user to respond to
+ * client cursor requests. The task is terminated with an EOF on stdin.
+ */
+
+#ifdef ANSI_FUNC
+
+int
+main (int argc, char **argv)
+#else
+
+main (argc, argv)
+int argc;
+char **argv;
+#endif
+{
+ register VXimDataPtr vxim = &server_data;
+ register IoChanPtr chan;
+ register int i, nopen, n;
+ char buf[SZ_FNAME];
+ int fd;
+
+ /* Process the command line arguments. */
+ for (i=1; i < argc; i++) {
+
+#ifdef HAVE_CDL
+ /* Anything without a '-' is a client device to add to the proxy
+ * list. Format of the arg must be a valid IMTDEV string.
+ */
+ if (proxy && argv[i][0] != '-') {
+ if ((cdl[nclients++] = cdl_open (argv[i])) == (CDLPtr) NULL)
+ nclients--;
+ else if (verbose)
+ printf ("Connected to server on %s\n", argv[i]);
+ continue;
+ }
+#endif
+ if (strncmp (argv[i], "-background", 2) == 0) {
+ background = 1;
+ } else if (strncmp (argv[i], "-config", 2) == 0) {
+ vxim->def_config = atoi (argv[++i]);
+ } else if (strncmp (argv[i], "-fifo_only", 6) == 0) {
+ vxim->unixaddr = "none";
+ vxim->port = 0;
+ } else if (strncmp (argv[i], "-fifo", 5) == 0) {
+ vxim->input_fifo = (char *) calloc (SZ_FNAME, sizeof(char));
+ vxim->output_fifo = (char *) calloc (SZ_FNAME, sizeof(char));
+ sprintf (vxim->input_fifo, "%si", argv[++i]);
+ sprintf (vxim->output_fifo, "%so", argv[i]);
+ } else if (strncmp (argv[i], "-help", 2) == 0) {
+ Usage ();
+ exit (0);
+ } else if (strncmp (argv[i], "-imtoolrc", 3) == 0) {
+ vxim->imtoolrc = argv[++i];
+ } else if (strncmp (argv[i], "-inet_only", 3) == 0) {
+ vxim->input_fifo = "";
+ vxim->unixaddr = "none";
+ } else if (strcmp (argv[i], "-i") == 0) {
+ interactive++;
+ } else if (strncmp (argv[i], "-noraster", 3) == 0) {
+ keep_raster = 0;
+ } else if (strncmp (argv[i], "-nframes", 3) == 0) {
+ vxim->def_nframes = min (MAX_FRAMES, atoi (argv[++i]));
+ } else if (strncmp (argv[i], "-nports", 3) == 0) {
+ vxim->nports = atoi (argv[++i]);
+ } else if (strncmp (argv[i], "-port_only", 6) == 0) {
+ vxim->input_fifo = "";
+ vxim->unixaddr = "none";
+ } else if (strncmp (argv[i], "-port", 5) == 0) {
+ vxim->port = atoi (argv[++i]);
+#ifdef HAVE_CDL
+ } else if (strncmp (argv[i], "-proxy", 5) == 0) {
+ proxy = 1;
+ vxim->port = DEF_PROXY_PORT; /* re-assign port */
+ vxim->input_fifo = ""; /* shut off other connections */
+ vxim->unixaddr = "none";
+#endif
+ } else if (strncmp (argv[i], "-verbose", 2) == 0) {
+ verbose = 1;
+ } else if (strncmp (argv[i], "-unix_only", 6) == 0) {
+ vxim->input_fifo = "";
+ vxim->port = 0;
+ } else if (strncmp (argv[i], "-unix", 5) == 0) {
+ vxim->unixaddr = argv[++i];
+ }
+ }
+
+#ifdef HAVE_CDL
+ /* If we're acting as a proxy server, but can't connect to anything,
+ * exit. In this case it is required that the servers be running
+ * before starting the proxy program so we have a connection waiting.
+ */
+ if (!nclients && proxy) {
+ fprintf (stderr, "Error: No servers available for display.\007\n");
+ exit (-1);
+ }
+#endif
+
+ /* Initialize the frame buffers */
+ vx_initialize (vxim, vxim->def_config, vxim->def_nframes, 1);
+
+ /* Listen for a client connection and initialize the fdset. */
+ if (!(nopen = vx_iisopen (vxim))) {
+ fprintf (stderr, "Error: Cannot open client communications.\007\n");
+ exit (-1);
+ }
+ FD_ZERO (&allset);
+ for (i=0; i < nopen; i++) {
+ chan = &vxim->chan[i];
+ FD_SET (chan->datain, &allset);
+ }
+ if (!background || interactive)
+ FD_SET (fileno(stdin), &allset);
+
+ /* Sit in a loop waiting on input, processing the events. */
+ while (1) {
+ fds = allset; /* reset the FD set on each pass */
+
+ if ((n = select (SELWIDTH, &fds, NULL, NULL, NULL)) > 0) {
+
+ /* Loop over each of the open connections, checking for and
+ * processing input on any that are ready.
+ */
+ for (i=0; i < nopen; i++) {
+ chan = &vxim->chan[i];
+ fd = chan->datain;
+ if (FD_ISSET(fd, &fds)) {
+
+ /* Connect the client if not already connected. */
+ if (!chan->connected) {
+ if (verbose) {
+ if (chan->type == IO_UNIX)
+ fprintf (stderr,
+ "connecting client on %s\n",
+ chan->path);
+ else if (chan->type == IO_INET)
+ fprintf (stderr,
+ "connecting client on port %d\n",
+ vxim->port);
+ }
+ vx_connectClient (chan, &chan->datain);
+ }
+
+ /* Process any waiting input. */
+ vx_iisio (chan, &chan->datain, chan->type);
+ fflush (stdout); fflush (stderr);
+ }
+ }
+
+ /* Check the stdin for an EOF so we can quit gracefully. */
+ if (!background) {
+ if (FD_ISSET(fileno(stdin), &fds)) {
+ if ((n = read (fileno(stdin), buf, SZ_FNAME)) <= 0) {
+ /* Shut it down. */
+ vx_iisclose (vxim);
+ exit (0);
+ }
+ }
+ }
+
+ } else if (n < 0) {
+ fprintf (stderr, "Error: select error\007\n");
+ exit (-1);
+ }
+ }
+}
+
+
+
+/* VX_IISOPEN -- Initialize the IIS protocol module and ready the module to
+ * accept client connections and begin processing client requests. Clients
+ * may connect to the server using a fifo connection or an internet or
+ * UNIX domain socket connection. All three types of server ports are
+ * simultaneously ready to receive client connections.
+ */
+#ifdef ANSI_FUNC
+
+static int
+vx_iisopen (register VXimDataPtr vxim)
+#else
+
+static int
+vx_iisopen (vxim)
+register VXimDataPtr vxim;
+#endif
+{
+ int i, port, last_port = (vxim->port + vxim->nports - 1);
+ int nopen = 0;
+
+ if (open_unix (vxim))
+ nopen++;
+ if (open_fifo (vxim))
+ nopen++;
+
+ for (port=vxim->port; port > 0 && port <= last_port; port++) {
+ if (open_inet (vxim, port))
+ nopen++;
+ }
+
+ return (nopen);
+}
+
+
+/* VX_IISCLOSE -- Close down the IIS protocol module.
+ */
+#ifdef ANSI_FUNC
+
+static void
+vx_iisclose (register VXimDataPtr vxim)
+#else
+
+static void
+vx_iisclose (vxim)
+register VXimDataPtr vxim;
+#endif
+{
+ register IoChanPtr chan = NULL;
+ register FrameBufPtr fb;
+ register int i, j;
+
+ for (i=0; i < (sizeof(vxim->chan) / sizeof(vxim->chan[0])); i++) {
+ chan = &vxim->chan[i];
+
+ /* Free the in-memory frame buffer rasters. */
+ for (j=0; j < vxim->nframes; j++) {
+ fb = &vxim->frames[j];
+ if (keep_raster && fb->framebuf)
+ free (fb->framebuf);
+ }
+
+ /* Close the I/O channels. */
+ switch (chan->type) {
+ case IO_FIFO:
+ if (chan->keepalive >= 0)
+ close (chan->keepalive);
+ if (chan->datain >= 0)
+ close (chan->datain);
+ if (chan->dataout >= 0)
+ close (chan->dataout);
+ chan->type = 0;
+ if (verbose)
+ fprintf (stderr, "vximtool: closing fifo connection\n");
+ break;
+
+ case IO_INET:
+ close (chan->datain);
+ chan->type = 0;
+ if (verbose)
+ fprintf (stderr, "vximtool: closing inet socket\n");
+ break;
+
+ case IO_UNIX:
+ close (chan->datain);
+ unlink (chan->path);
+ chan->type = 0;
+ if (verbose)
+ fprintf (stderr, "vximtool: closing unix socket\n");
+ break;
+ }
+ }
+}
+
+
+/* OPEN_FIFO -- Open the server fifo port and make ready to accept client
+ * connections and begin processing client requests. There is no client
+ * yet at this stage.
+ */
+#ifdef ANSI_FUNC
+
+static IoChanPtr
+open_fifo (register VXimDataPtr vxim)
+#else
+
+static IoChanPtr
+open_fifo (vxim)
+register VXimDataPtr vxim;
+#endif
+{
+ register IoChanPtr chan;
+ int datain, dataout;
+ int keepalive;
+
+
+#if defined(__DARWIN__) || defined (__CYGWIN__)
+ /* On OS X and Cygwin we don't use fifos. */
+ xim->input_fifo = "none";
+ return (NULL);
+#endif
+
+ /* Setting the input fifo to "none" or the null string disables
+ * fifo support.
+ */
+ if (!vxim->input_fifo[0] || strcmp(vxim->input_fifo,"none")==0)
+ return (NULL);
+
+ datain = dataout = -1;
+
+ /* Open the output fifo (which is the client's input fifo). We have
+ * to open it ourselves first as a client to get around the fifo
+ * open-no-client error.
+ */
+ if ((datain = open (vxim->input_fifo, O_RDONLY|O_NDELAY)) != -1) {
+ if ((dataout = open (vxim->input_fifo, O_WRONLY|O_NDELAY)) != -1)
+ fcntl (dataout, F_SETFL, O_WRONLY);
+ else
+ goto done;
+ close (datain);
+ } else
+ goto done;
+
+ /* Open the input stream, a FIFO pseudodevice file used by
+ * applications to send us commands and data.
+ */
+ if ((datain = open (vxim->output_fifo, O_RDONLY|O_NDELAY)) == -1)
+ goto done;
+ else {
+ /* Clear O_NDELAY for reading. */
+ fcntl (datain, F_SETFL, O_RDONLY);
+
+ /* Open the client's output fifo as a pseudo-client to make it
+ * appear that a client is connected.
+ */
+ keepalive = open (vxim->output_fifo, O_WRONLY);
+ }
+done:
+ /* Allocate and fill in i/o channel descriptor. */
+ if (datain > 0 && dataout > 0 && (chan = get_iochan(vxim))) {
+ chan->vxim = (void *) vxim;
+ chan->type = IO_FIFO;
+ chan->datain = datain;
+ chan->dataout = dataout;
+ chan->keepalive = keepalive;
+ chan->connected = 1;
+ chan->reference_frame = 1;
+ chan->rf_p = &vxim->frames[0];
+ } else {
+ fprintf (stderr, "Warning: cannot open %s\n", vxim->output_fifo);
+ chan = NULL;
+ }
+
+ /* Register input callback. */
+ if (!chan) {
+ if (datain > 0)
+ close (datain);
+ if (dataout > 0)
+ close (dataout);
+ } else if (verbose) {
+ fprintf (stderr,
+ "vximtool: Open to accept input on fifo: %s\n",
+ vxim->input_fifo);
+ }
+
+ return (chan);
+}
+
+
+/* OPEN_INET -- Set up a port to be used for incoming client connections
+ * using internet domain sockets.
+ */
+#ifdef ANSI_FUNC
+
+static IoChanPtr
+open_inet (register VXimDataPtr vxim, int port)
+#else
+
+static IoChanPtr
+open_inet (vxim, port)
+register VXimDataPtr vxim;
+int port;
+#endif
+{
+ register int s = 0;
+ register IoChanPtr chan;
+ struct sockaddr_in sockaddr;
+
+ /* Setting the port to zero disables inet socket support. */
+ if (port <= 0)
+ return (NULL);
+
+ if ((s = socket (AF_INET, SOCK_STREAM, 0)) < 0)
+ goto err;
+
+ memset ((void *)&sockaddr, 0, sizeof(sockaddr));
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = htons((short)port);
+ sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ if (bind (s, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) < 0)
+ goto err;
+
+ if (listen (s, MAXCONN) < 0)
+ goto err;
+
+ /* Allocate and fill in i/o channel descriptor. */
+ if ((chan = get_iochan(vxim))) {
+ chan->vxim = (void *) vxim;
+ chan->type = IO_INET;
+ chan->port = port;
+ chan->datain = s;
+ chan->dataout = s;
+ chan->listen_fd = s;
+ chan->connected = 0;
+ chan->reference_frame = 1;
+ chan->rf_p = &vxim->frames[0];
+ if (verbose)
+ fprintf (stderr,
+ "vximtool: Open to accept input on inet: port %d\n", port);
+ return (chan);
+ }
+err:
+ fprintf (stderr, "vximtool: cannot open socket on port %d, errno=%d\n",
+ port, errno);
+ if (s)
+ close (s);
+ return (NULL);
+}
+
+
+/* OPEN_UNIX -- Set up a port to be used for incoming client connections
+ * using unix domain sockets.
+ */
+#ifdef ANSI_FUNC
+
+static IoChanPtr
+open_unix (register VXimDataPtr vxim)
+#else
+
+static IoChanPtr
+open_unix (vxim)
+register VXimDataPtr vxim;
+#endif
+{
+ register int s = 0;
+ register IoChanPtr chan;
+ struct sockaddr_un sockaddr;
+ char path[256];
+
+ /* Setting the addr to "none" or the null string disables unix
+ * socket support.
+ */
+ if (!vxim->unixaddr[0] || strcmp(vxim->unixaddr,"none")==0)
+ return (NULL);
+
+ /* Get path to be used for the unix domain socket. */
+ sprintf (path, vxim->unixaddr, getuid());
+ unlink (path);
+
+ if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
+ goto err;
+
+ memset ((void *)&sockaddr, 0, sizeof(sockaddr));
+ sockaddr.sun_family = AF_UNIX;
+ strcpy (sockaddr.sun_path, path);
+ if (bind (s, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) < 0)
+ goto err;
+
+ if (listen (s, MAXCONN) < 0)
+ goto err;
+
+ /* Allocate and fill in i/o channel descriptor. */
+ if ((chan = get_iochan(vxim))) {
+ chan->vxim = (void *) vxim;
+ chan->type = IO_UNIX;
+ chan->datain = s;
+ chan->dataout = s;
+ chan->listen_fd = s;
+ chan->connected = 0;
+ chan->reference_frame = 1;
+ chan->rf_p = &vxim->frames[0];
+ strncpy (chan->path, path, SZ_FNAME);
+ if (verbose)
+ fprintf (stderr,
+ "vximtool: Open to accept input on unix: %s\n", path);
+ return (chan);
+ }
+err:
+ fprintf (stderr, "vximtool: cannot open socket on port %s, errno=%d\n",
+ path, errno);
+ if (s)
+ close (s);
+ return (NULL);
+}
+
+
+/* VX_CONNECTCLIENT -- Called when a client has attempted a connection on
+ * a socket port. Accept the connection and set up a new i/o channel to
+ * communicate with the new client.
+ */
+#ifdef ANSI_FUNC
+
+static void
+vx_connectClient (IoChanPtr chan, int *source)
+#else
+
+static void
+vx_connectClient (chan, source)
+IoChanPtr chan;
+int *source;
+#endif
+{
+ register VXimDataPtr vxim = (VXimDataPtr) chan->vxim;
+ register int s;
+
+ /* Accept connection. */
+ if ((s = accept ((int)*source, (struct sockaddr *)0, (int *)0)) < 0)
+ return;
+/*
+ if (fcntl (s, F_SETFD, O_RDWR|O_NDELAY) < 0) {
+ close (s);
+ return;
+ }
+*/
+
+ /* Allocate and fill in i/o channel descriptor. */
+ FD_SET(s, &allset);
+ chan->datain = s;
+ chan->dataout = s;
+ chan->connected = 1;
+ chan->reference_frame = 1;
+ chan->rf_p = &vxim->frames[0];
+
+ switch (chan->type) {
+ case IO_INET:
+ if (verbose)
+ fprintf (stderr,
+ "connecting client on port %d\n", chan->port);
+ case IO_UNIX:
+ if (verbose && chan->type == IO_UNIX)
+ fprintf (stderr,
+ "connecting client on %s\n", chan->path);
+ }
+}
+
+
+/* VX_DISCONNECTCLIENT -- Called to close a client connection when EOF is
+ * seen on the input port. Close the connection and free the channel
+ * descriptor.
+ */
+#ifdef ANSI_FUNC
+
+static void
+vx_disconnectClient (register IoChanPtr chan)
+#else
+
+static void
+vx_disconnectClient (chan)
+register IoChanPtr chan;
+#endif
+{
+ switch (chan->type) {
+ case IO_INET:
+ if (verbose)
+ fprintf (stderr,
+ "disconnecting client on port %d\n", chan->port);
+ case IO_UNIX:
+ if (verbose && chan->type == IO_UNIX)
+ fprintf (stderr,
+ "disconnecting client on %s\n", chan->path);
+ FD_CLR(chan->datain, &allset);
+ close (chan->datain);
+ chan->datain = chan->dataout = chan->listen_fd;
+ chan->connected = 0;
+ break;
+ default:
+ break;
+ }
+}
+
+
+/* GET_IOCHAN --- Get an i/o channel descriptor.
+ */
+#ifdef ANSI_FUNC
+
+static IoChanPtr
+get_iochan (register VXimDataPtr vxim)
+#else
+
+static IoChanPtr
+get_iochan (vxim)
+register VXimDataPtr vxim;
+#endif
+{
+ register int i;
+
+ for (i=0; i < MAX_CLIENTS; i++)
+ if (!vxim->chan[i].type)
+ return (&vxim->chan[i]);
+
+ return (NULL);
+}
+
+
+/* VX_IISIO -- File i/o callback procedure, called when there is input
+ * pending on the data stream to the vximtool client.
+ */
+#ifdef ANSI_FUNC
+
+static void
+vx_iisio (IoChanPtr chan, int *fd_addr, int source)
+#else
+
+static void
+vx_iisio (chan, fd_addr, source)
+IoChanPtr chan;
+int *fd_addr;
+int source;
+#endif
+{
+ register VXimDataPtr vxim = (VXimDataPtr) chan->vxim;
+ register int sum, i;
+ register short *p;
+ int datain = *fd_addr;
+ int dataout = chan->dataout;
+ int ndatabytes, nbytes, n, ntrys=0;
+ struct iism70 iis;
+ char buf[SZ_FIFOBUF];
+ static int errmsg=0, bswap=0;
+
+
+ /* Get the IIS header. */
+ if ((n = iis_read (datain, (char *)&iis, sizeof(iis))) < sizeof(iis)) {
+ if (n != 0)
+ fprintf (stderr,
+ "vximtool: command input read error, n=%d of %d, errno=%d\n",
+ n, sizeof(iis), errno);
+ if (n <= 0)
+ vx_disconnectClient (chan);
+ return;
+ } else if (bswap)
+ bswap2 ((char *)&iis, (char *)&iis, sizeof(iis));
+
+ /* Verify the checksum. If it fails swap the bytes and try again.
+ */
+ for (;;) {
+ for (i=0, sum=0, p=(short *)&iis; i < 8; i++)
+ sum += *p++;
+ if ((sum & 0177777) == 0177777)
+ break;
+
+ if (ntrys++) {
+ if (!errmsg++) {
+ fprintf (stderr, "vximtool: bad data header checksum\n");
+ if (bswap)
+ bswap2 ((char *)&iis, (char *)&iis, sizeof(iis));
+ fprintf (stderr, "noswap:");
+ for (i=0, p=(short *)&iis; i < 8; i++)
+ fprintf (stderr, " %6o", p[i]);
+ fprintf (stderr, "\n");
+
+ bswap2 ((char *)&iis, (char *)&iis, sizeof(iis));
+ fprintf (stderr, " swap:");
+ for (i=0, p=(short *)&iis; i < 8; i++)
+ fprintf (stderr, " %6o", p[i]);
+ fprintf (stderr, "\n");
+ }
+ break;
+
+ } else {
+ bswap2 ((char *)&iis, (char *)&iis, sizeof(iis));
+ bswap = !bswap;
+ }
+ }
+
+ ndatabytes = -iis.thingct;
+ if (!(iis.tid & PACKED))
+ ndatabytes *= 2;
+
+ if (verbose) {
+ fprintf (stderr, "%s: ", (source == IO_FIFO ? "fifo" :
+ (source == IO_INET ? "inet" : "unix")));
+ fprintf (stderr,
+ "subunit=%03o tid=%06o nbytes=%6d x=%06o y=%06o z=%06o t=%06o\n",
+ iis.subunit & 077,
+ iis.tid,
+ ndatabytes,
+ iis.x & 0177777,
+ iis.y & 0177777,
+ iis.z & 0177777,
+ iis.t & 0177777);
+ fflush (stdout);
+ }
+
+
+ switch (iis.subunit & 077) {
+ case FEEDBACK:
+ /* The feedback unit is used only to clear a frame.
+ */
+ chan->reference_frame = decode_frameno (iis.z & 07777);
+ vx_eraseFrame (vxim, chan->reference_frame);
+#ifdef HAVE_CDL
+ if (proxy) {
+ for (i=0; i < nclients; i++)
+ cdl_clearFrame (cdl[i]);
+ }
+#endif
+ if (verbose)
+ fprintf (stderr, "erase frame %d - ref = %d\n",
+ decode_frameno(iis.z & 0177777), chan->reference_frame);
+ break;
+
+ case LUT:
+ /* Data mode writes to the frame lookup tables are not implemented.
+ * A command mode write to the LUT subunit is used to connect
+ * image memories up to the RGB channels, i.e., to select the frame
+ * to be displayed. We ignore any attempt to assign multiple
+ * frames to multiple color channels, and just do a simple frame
+ * select.
+ */
+ if (iis.subunit & COMMAND) {
+ int frame, z, n;
+ short x[14];
+
+ if (iis_read (datain, (char *)x, ndatabytes) == ndatabytes) {
+ if (bswap)
+ bswap2 ((char *)x, (char *)x, ndatabytes);
+
+ z = x[0];
+ if (!z) z = 1;
+ for (n=0; !(z & 1); z >>= 1)
+ n++;
+
+ frame = max (1, n + 1);
+ if (frame > vxim->nframes) {
+ if (frame <= MAX_FRAMES) {
+#ifdef HAVE_CDL
+ if (proxy) {
+ for (i=0; i < nclients; i++) {
+ cdl_setFBConfig (cdl[i], vxim->fb_configno);
+ cdl_setFrame (cdl[i], frame);
+ }
+ }
+#endif
+ set_fbconfig (chan, vxim->fb_configno, frame);
+ if (verbose)
+ fprintf (stderr, "set_fbconfig (%d, %d)\n",
+ vxim->fb_configno, frame);
+ } else {
+ fprintf (stderr, "imtool warning: ");
+ fprintf (stderr,
+ "attempt to display nonexistent frame %d\n",
+ frame);
+ return;
+ }
+ }
+
+ vxim->display_frame = frame;
+ if (verbose)
+ fprintf (stderr, "set_frame (%d)\n", frame);
+ return;
+ }
+ }
+
+ case MEMORY:
+ /* Load data into the frame buffer. Data is assumed to be byte
+ * packed.
+ */
+ if (iis.tid & IIS_READ) {
+ /* Read from the display.
+ */
+ register FrameBufPtr fb;
+ unsigned char *ip, iobuf[SZ_IOBUF];
+ int nbytes, nleft, n, x, y;
+ long starttime;
+
+ /* Get the frame to be read from. */
+ chan->reference_frame = decode_frameno (iis.z & 0177777);
+ fb = &vxim->frames[chan->reference_frame-1];
+
+ nbytes = ndatabytes;
+ x = iis.x & XYMASK;
+ y = iis.y & XYMASK;
+
+ if (x < 0 || x >= vxim->width || y < 0 || y >= vxim->height) {
+ fprintf (stderr,
+ "vximtool: attempted read out of bounds on framebuf\n");
+ fprintf (stderr,
+ "read %d bytes at [%d,%d]\n", nbytes, x, y);
+ memset ((void *)iobuf, 0, min(SZ_IOBUF,nbytes));
+ } else {
+ if (verbose)
+ fprintf (stderr, "read %d bytes at [%d,%d]\n",
+ nbytes, x, y);
+ if (keep_raster)
+ bcopy(&fb->framebuf[(y * vxim->width)+x], iobuf,nbytes);
+ else
+ bzero (iobuf, nbytes);
+#ifdef HAVE_CDL
+ if (proxy) {
+ unsigned char *pix = (unsigned char *)malloc(SZ_IOBUF);
+ cdl_readSubRaster (cdl[0], x,
+ (vxim->height-y-max(1, nbytes/vxim->width)),
+ min(vxim->width, nbytes),
+ max(1, nbytes/vxim->width),
+ &pix);
+ bcopy(pix, iobuf, nbytes);
+ vx_flip ((char *)iobuf, min(vxim->width, nbytes),
+ max(1, nbytes/vxim->width));
+ free ((char *)pix);
+ }
+#endif
+ }
+
+ /* Return the data from the frame buffer. */
+ starttime = time(0);
+ for (nleft=nbytes, ip=iobuf; nleft > 0; nleft -= n) {
+ n = (nleft < SZ_FIFOBUF) ? nleft : SZ_FIFOBUF;
+ if ((n = iis_write (dataout, ip, n)) <= 0) {
+ if (n < 0 || (time(0) - starttime > IO_TIMEOUT)) {
+ fprintf (stderr, "IMTOOL: timeout on write\n");
+ break;
+ }
+ } else
+ ip += n;
+ }
+
+ return;
+
+ } else {
+ /* Write to the display.
+ */
+ register FrameBufPtr fb;
+ unsigned char *op, iobuf[SZ_IOBUF];
+ int nbytes, nleft, n, x, y;
+ long starttime;
+
+ /* Get the frame to be written into (encoded with a bit for
+ * each frame, 01 is frame 1, 02 is frame 2, 04 is frame 3,
+ * and so on).
+ */
+ chan->reference_frame = decode_frameno (iis.z & 0177777);
+ fb = &vxim->frames[chan->reference_frame-1];
+
+ nbytes = ndatabytes;
+ x = iis.x & XYMASK;
+ y = iis.y & XYMASK;
+
+ /* Read the data into the frame buffer.
+ */
+ starttime = time(0);
+ for (nleft=nbytes, op=iobuf; nleft > 0; nleft -= n) {
+ n = (nleft < SZ_FIFOBUF) ? nleft : SZ_FIFOBUF;
+ if ((n = iis_read (datain, op, n)) <= 0) {
+ if (n < 0 || (time(0) - starttime > IO_TIMEOUT))
+ break;
+ } else
+ op += n;
+ }
+
+ if (x < 0 || x >= vxim->width || y < 0 || y >= vxim->height) {
+ fprintf (stderr,
+ "vximtool: attempted write out of bounds on framebuf\n");
+ fprintf (stderr,
+ "write %d bytes at [%d,%d]\n", nbytes, x, y);
+ bzero ((void *)iobuf, nbytes);
+ } else {
+ if (verbose)
+ fprintf (stderr, "write %d bytes at x=%d, y=%d\n",
+ nbytes, x, y);
+ if (keep_raster)
+ bcopy(iobuf, &fb->framebuf[(y * vxim->width)+x],nbytes);
+#ifdef HAVE_CDL
+ if (proxy) {
+ vx_flip ((char *)iobuf, min(vxim->width, nbytes),
+ max(1, nbytes/vxim->width));
+ for (i=0; i < nclients; i++)
+ cdl_writeSubRaster (cdl[i], x,
+ (vxim->height-y-max(1, nbytes/vxim->width)),
+ min(vxim->width, nbytes),
+ max(1, nbytes/vxim->width),
+ iobuf);
+ }
+#endif
+ }
+
+ return;
+ }
+ break;
+
+ case WCS:
+ /* Read or write the WCS for a frame. The frame number to
+ * which the WCS applies is passed in Z and the frame buffer
+ * configuration in T. The client changes the frame buffer
+ * configuration in a WCS set. The WCS text follows the header
+ * as byte packed ASCII data.
+ */
+ if (iis.tid & IIS_READ) {
+ /* Return the WCS for the referenced frame.
+ */
+ char emsg[SZ_FNAME];
+ char *text;
+ int frame;
+
+ if ((iis.y & 0177777)) {
+ /* This is a check by the client on our capabilities.
+ * Return with a version number which can be used by the
+ * client. However we write back using the old WCS
+ * buffer size for compatability.
+ */
+ sprintf (text=emsg, "version=%d", IIS_VERSION);
+ chan->version = IIS_VERSION;
+
+ iis_write (dataout, text, SZ_OLD_WCSBUF);
+ if (verbose)
+ fprintf (stderr, "version query wcs: %s\n",text);
+
+ } else {
+ frame = decode_frameno (iis.z & 0177777);
+ chan->reference_frame = frame;
+
+ if (chan->rf_p->frameno <= 0)
+ strcpy (text=emsg, "[NOSUCHFRAME]\n");
+ else
+ text = chan->rf_p->wcsbuf;
+
+ if ((iis.x & 0177777))
+ iis_write (dataout, text, SZ_WCSBUF);
+ else
+ iis_write (dataout, text, SZ_OLD_WCSBUF);
+
+ if (verbose) {
+ fprintf (stderr, "query wcs:\n");
+ write (2, text, SZ_WCSBUF);
+ }
+ }
+
+ } else {
+ /* Set the WCS for the referenced frame.
+ */
+ register CtranPtr ct;
+ int fb_config, frame, new_wcs = 0;
+
+ frame = decode_frameno (iis.z & 0177777);
+ fb_config = (iis.t & 0777) + 1;
+ new_wcs = (iis.t & 0777);
+
+ /* See if we need to change the frame buffer configuration,
+ * or allocate a new frame.
+ */
+ if (fb_config != vxim->fb_configno) {
+ set_fbconfig (chan, fb_config, frame);
+#ifdef HAVE_CDL
+ if (proxy) {
+ for (i=0; i < nclients; i++) {
+ cdl_setFBConfig (cdl[i], fb_config);
+ cdl_setFrame (cdl[i], frame);
+ }
+ }
+#endif
+ } else if (frame > vxim->nframes && frame < MAX_FRAMES) {
+ set_fbconfig (chan, vxim->fb_configno, frame);
+#ifdef HAVE_CDL
+ if (proxy) {
+ for (i=0; i < nclients; i++) {
+ cdl_setFBConfig (cdl[i], vxim->fb_configno);
+ cdl_setFrame (cdl[i], frame);
+ }
+ }
+#endif
+ }
+
+ /* Read in and set up the WCS. */
+ chan->reference_frame = frame;
+ memset ((char *)buf, 0, SZ_WCSBUF);
+ if (iis_read (datain, buf, ndatabytes) == ndatabytes)
+ strncpy (chan->rf_p->wcsbuf, buf,
+ (new_wcs ? SZ_WCSBUF : SZ_OLD_WCSBUF));
+
+ if (verbose) {
+ fprintf (stderr, "set wcs: nbytes=%d\n", ndatabytes);
+ write (2, buf, ndatabytes);
+ }
+
+ strcpy (chan->rf_p->ctran.format, W_DEFFORMAT);
+ chan->rf_p->ctran.imtitle[0] = '\0';
+ chan->rf_p->ctran.valid = 0;
+ ct = wcs_update (vxim, chan->rf_p);
+
+#ifdef HAVE_CDL
+ if (proxy) {
+ for (i=0; i < nclients; i++)
+ cdl_setWCS (cdl[i], " ", ct->imtitle,
+ ct->a, ct->b, ct->c, ct->d,
+ ct->tx, ct->ty, ct->z1, ct->z2, ct->zt);
+ }
+#endif
+
+ /* Add the mapping information. */
+ add_mapping (vxim, ct, chan->rf_p->wcsbuf,
+ &vxim->frames[chan->reference_frame-1]);
+ }
+ return;
+
+ case IMCURSOR:
+ /* Read or write the logical image cursor. This is an extension
+ * added to provide a high level cursor read facility; this is
+ * not the same as a low level access to the IIS cursor subunit.
+ * Cursor reads may be either nonblocking (immediate) or blocking,
+ * using the keyboard or mouse to terminate the read, and
+ * coordinates may be returned in either image (world) or frame
+ * buffer pixel coordinates.
+ */
+ if (iis.tid & IIS_READ) {
+ /* Read the logical image cursor. In the case of a blocking
+ * read all we do is initiate a cursor read; completion occurs
+ * when the user hits a key or button.
+ */
+ float sx, sy;
+
+ if (verbose)
+ fprintf (stderr, "read cursor position\n");
+ if (iis.tid & IMC_SAMPLE) {
+ /* Sample the cursor position and return the cursor value
+ * on the output datastream encoded in a fixed size
+ * ascii buffer.
+ */
+ int wcs = iis.z;
+
+ sx = cursor_x;
+ sy = cursor_y;
+#ifdef HAVE_CDL
+ if (proxy) {
+ char key = ' ';
+ char curval[SZ_IMCURVAL], keystr[20];
+
+ cdl_readCursor (cdl[0], 1, &sx, &sy, &key);
+
+ /* Encode the cursor value. */
+ if (key == EOF)
+ sprintf (curval, "EOF\n");
+ else {
+ if (isprint (key) && !isspace(key)) {
+ keystr[0] = key;
+ keystr[1] = '\0';
+ } else
+ sprintf (keystr, "\\%03o", key);
+
+ sprintf (curval, "%10.3f %10.3f %d %s %s\n",
+ sx, sy, 1, keystr, "");
+ }
+ iis_write (dataout, curval, sizeof(curval));
+ } else
+#endif
+ vx_retCursorVal (chan->dataout, sx, sy, wcs, 0, "");
+
+ } else {
+ /* Initiate a user triggered cursor read. */
+ char key = 'q';
+#ifdef HAVE_CDL
+ if (proxy) {
+ char curval[SZ_IMCURVAL], keystr[20];
+
+ cdl_readCursor (cdl[0], 0, &sx, &sy, &key);
+
+ /* Encode the cursor value. */
+ if (key == EOF)
+ sprintf (curval, "EOF\n");
+ else {
+ if (isprint (key) && !isspace(key)) {
+ keystr[0] = key;
+ keystr[1] = '\0';
+ } else
+ sprintf (keystr, "\\%03o", key);
+
+ sprintf (curval, "%10.3f %10.3f %d %s %s\n\0",
+ sx, sy, 1, keystr, "");
+ }
+ iis_write (chan->dataout, curval, sizeof(curval));
+ } else
+#endif
+ vx_retCursorVal (chan->dataout, 1., 1., 101, key, "");
+ }
+
+ } else {
+ /* Write (set) the logical image cursor position. */
+ register CtranPtr ct;
+ int sx = iis.x, sy = iis.y;
+ float wx = sx, wy = sy;
+ int wcs = iis.z;
+
+ if (verbose)
+ fprintf (stderr, "write cursor position: [%d,%d]\n", sx,sy);
+ if (wcs) {
+ ct = wcs_update (vxim, vxim->df_p);
+ if (ct->valid) {
+ if (abs(ct->a) > .001)
+ sx = (wx - ct->tx) / ct->a;
+ if (abs(ct->d) > .001)
+ sy = (wy - ct->ty) / ct->d;
+ }
+ }
+
+ cursor_x = sx;
+ cursor_y = sy;
+#ifdef HAVE_CDL
+ if (proxy)
+ cdl_setCursor (cdl[0], sx, sy, wcs);
+#endif
+ }
+ return;
+
+ default:
+ /* Ignore unsupported command input.
+ */
+ fprintf (stderr, "unsupported input: subunit=%03o\n",
+ iis.subunit & 077);
+ break;
+ }
+
+ /* Discard any data following the header. */
+ if (!(iis.tid & IIS_READ))
+ for (nbytes = ndatabytes; nbytes > 0; nbytes -= n) {
+ n = (nbytes < SZ_FIFOBUF) ? nbytes : SZ_FIFOBUF;
+ if ((n = iis_read (datain, buf, n)) <= 0)
+ break;
+ }
+}
+
+
+/* SET_FBCONFIG -- Set the frame buffer configuration, or add additional
+ * frames to the current configuration.
+ */
+#ifdef ANSI_FUNC
+
+static void
+set_fbconfig (IoChanPtr chan, int config, int frame)
+#else
+
+static void
+set_fbconfig (chan, config, frame)
+IoChanPtr chan;
+int config;
+int frame;
+#endif
+{
+ register VXimDataPtr vxim = (VXimDataPtr) chan->vxim;
+ register FrameBufPtr fb = &vxim->frames[frame-1];
+ register int i;
+
+ if (config != vxim->fb_configno) {
+ /* Change the frame buffer configuration. */
+ vx_initialize (vxim, config,
+ max (vxim->fb_config[config-1].nframes, frame), 1);
+
+ } else if (frame > vxim->nframes) {
+ /* Add additional frames. */
+ for (i=1; i <= frame; i++) {
+ fb = &vxim->frames[i-1];
+ if (fb->frameno != i)
+ vx_initFrame (vxim, i, frame, &vxim->fb_config[config-1]);
+ }
+ }
+
+ chan->reference_frame = frame;
+}
+
+
+/* DECODE_FRAMENO -- Decode encoded IIS register frame number.
+ */
+#ifdef ANSI_FUNC
+
+static int
+decode_frameno (register int z)
+#else
+
+static int
+decode_frameno (z)
+register int z;
+#endif
+{
+ register int n;
+
+ /* Get the frame number, encoded with a bit for each frame, 01 is
+ * frame 1, 02 is frame 2, 04 is frame 3, and so on.
+ */
+ if (!z) z = 1;
+ for (n=0; !(z & 1); z >>= 1)
+ n++;
+
+ return (max (1, n + 1));
+}
+
+
+/* BSWAP2 - Move bytes from array "a" to array "b", swapping successive
+ * pairs of bytes. The two arrays may be the same but may not be offset
+ * and overlapping.
+ */
+#ifdef ANSI_FUNC
+
+static void
+bswap2 (
+ char *a,
+ char *b, /* input array */
+ int nbytes /* number of bytes to swap */
+)
+#else
+
+static void
+bswap2 (a, b, nbytes)
+char *a, *b; /* input array */
+int nbytes; /* number of bytes to swap */
+#endif
+{
+ register char *ip=a, *op=b, *otop;
+ register unsigned temp;
+
+ /* Swap successive pairs of bytes.
+ */
+ for (otop = op + (nbytes & ~1); op < otop; ) {
+ temp = *ip++;
+ *op++ = *ip++;
+ *op++ = temp;
+ }
+
+ /* If there is an odd byte left, move it to the output array.
+ */
+ if (nbytes & 1)
+ *op = *ip;
+}
+
+
+/* VX_RETCURSORVAL -- Return the cursor value on the output datastream to
+ * the client which requested the cursor read.
+ */
+#ifdef ANSI_FUNC
+
+static void
+vx_retCursorVal (
+ register int dataout,
+ float sx,
+ float sy, /* cursor screen coordinates */
+ int wcs, /* nonzero if WCS coords desired */
+ int key, /* keystroke used as trigger */
+ char *strval /* optional string value */
+)
+#else
+
+static void
+vx_retCursorVal (dataout, sx, sy, wcs, key, strval)
+register int dataout;
+float sx, sy; /* cursor screen coordinates */
+int wcs; /* nonzero if WCS coords desired */
+int key; /* keystroke used as trigger */
+char *strval; /* optional string value */
+#endif
+{
+ char curval[SZ_IMCURVAL];
+ char keystr[20];
+
+ /* If running SERVER in interactive mode, allow the user to type
+ * in the cursor value on the standard input.
+ */
+ if (interactive) {
+ printf ("enter cursor value string (x y wcs key str): ");
+ fflush (stdout);
+ if (fgets (curval, SZ_IMCURVAL, stdin) != NULL)
+ goto ret;
+ }
+
+ /* Encode the cursor value. */
+ if (key == EOF)
+ sprintf (curval, "EOF\n");
+ else {
+ if (isprint (key) && !isspace(key)) {
+ keystr[0] = key;
+ keystr[1] = '\0';
+ } else
+ sprintf (keystr, "\\%03o", key);
+
+ sprintf (curval, "%10.3f %10.3f %d %s %s\n",
+ sx, sy, wcs, keystr, strval);
+ }
+ret:
+ fprintf (stderr, "%s", curval);
+
+ /* Send it to the client program and terminate cursor mode. */
+ write (dataout, curval, sizeof(curval));
+}
+
+
+/* WCS_UPDATE -- Load the screen WCS, if not yet validated, from the user
+ * wcs file, if any.
+ *
+ * File format (two lines):
+ *
+ * image title (imtool header label string)\n
+ * a b c d tx ty z1 z2 zt
+ *
+ * The WCS text is passed in via the data stream as a write to the subunit
+ * WCS and left in the buffer "wcsbuf".
+ */
+#ifdef ANSI_FUNC
+
+static CtranPtr
+wcs_update (register VXimDataPtr vxim, FrameBufPtr fr)
+#else
+
+static CtranPtr
+wcs_update (vxim, fr)
+register VXimDataPtr vxim;
+FrameBufPtr fr;
+#endif
+{
+ register CtranPtr ct = &fr->ctran;
+ char buf[1024], *format;
+
+ /* Get the new WCS. */
+ if (!ct->valid) {
+ fr->label[0] = '\0';
+ ct->zt = W_UNITARY;
+
+ /* Attempt to read the WCS and set up a unitary transformation
+ * if the information cannot be read.
+ */
+ if (sscanf (fr->wcsbuf, "%[^\n]\n%f%f%f%f%f%f%f%f%d",
+ buf, &ct->a, &ct->b, &ct->c, &ct->d, &ct->tx, &ct->ty,
+ &ct->z1, &ct->z2, &ct->zt) < 7) {
+
+ if (fr->wcsbuf[0])
+ fprintf (stderr, "vximtool: error decoding WCS\n");
+
+ strncpy (ct->imtitle, "[NO WCS]\n", SZ_IMTITLE);
+ ct->a = ct->d = 1;
+ ct->b = ct->c = 0;
+ ct->tx = ct->ty = 0;
+ ct->zt = W_UNITARY;
+
+ } else
+ strncpy (ct->imtitle, buf, SZ_IMTITLE);
+
+ ct->valid++;
+ }
+
+ /* Determine best format for wcs output. */
+ if (ct->valid && ct->zt == W_LINEAR) {
+ float z1, z2, zrange;
+ z1 = ct->z1;
+ z2 = ct->z2;
+ zrange = (z1 > z2) ? z1 - z2 : z2 - z1;
+ if (zrange < 100.0 && (abs(z1) + abs(z2)) / 2.0 < 200.0)
+ format = " %7.2f %7.2f %7.3f%c";
+ else if (zrange > 99999.0 || (abs(z1) + abs(z2)) / 2.0 > 99999.0)
+ format = " %7.2f %7.2f %7.3g%c";
+ else
+ format = W_DEFFORMAT;
+ } else
+ format = " %7.2f %7.2f %7.0f%c";
+
+ strcpy (ct->format, format);
+ return (ct);
+}
+
+
+/* VX_INITIALIZE -- Initialize the imaging subsystem. Read the config file
+ * and create the frame buffers, mappings, and colormaps.
+ */
+#ifdef ANSI_FUNC
+
+static void
+vx_initialize (register VXimDataPtr vxim, int config, int nframes, int reset)
+#else
+
+static void
+vx_initialize (vxim, config, nframes, reset)
+register VXimDataPtr vxim;
+int config;
+int nframes;
+int reset;
+#endif
+{
+ if (reset)
+ get_fbconfig (vxim);
+
+ vxim->fb_configno = config;
+ vxim->nframes = vxim->fb_config[config].nframes;
+ vxim->width = vxim->fb_config[config].width;
+ vxim->height = vxim->fb_config[config].height;
+ vx_initFrame (vxim, vxim->display_frame, nframes,
+ &vxim->fb_config[config-1]);
+}
+
+
+/* VX_INITFRAME -- Initialize a frame buffer.
+ */
+#ifdef ANSI_FUNC
+
+static void
+vx_initFrame (register VXimDataPtr vxim, int frame, int nframes, FbConfigPtr config)
+#else
+
+static void
+vx_initFrame (vxim, frame, nframes, config)
+register VXimDataPtr vxim;
+int frame, nframes;
+FbConfigPtr config;
+#endif
+{
+ register FrameBufPtr fb = &vxim->frames[frame-1];
+
+ if (frame < 1 || frame > MAX_FRAMES)
+ return;
+
+ /* Create the frame buffer. */
+ fb->frameno = frame;
+ if (keep_raster) {
+ if (fb->framebuf)
+ free (fb->framebuf);
+ fb->framebuf = (char *) malloc (config->width * config->height);
+ }
+ vxim->width = config->width;
+ vxim->height = config->height;
+ vxim->nframes = nframes;
+}
+
+/* VX_ERASEFRAME -- Erase a frame.
+ */
+#ifdef ANSI_FUNC
+
+static void
+vx_eraseFrame (register VXimDataPtr vxim, int frame)
+#else
+
+static void
+vx_eraseFrame (vxim, frame)
+register VXimDataPtr vxim;
+int frame;
+#endif
+{
+ register FrameBufPtr fb = &vxim->frames[frame-1];
+
+ if (keep_raster)
+ bzero (fb->framebuf, vxim->width * vxim->height);
+}
+
+
+/* GET_FBCONFIG -- Read the XIMTOOL startup file to get the set of possible
+ * frame buffer sizes.
+ *
+ * File format: configno nframes width height [extra fields]
+ * e.g., 1 2 512 512
+ * 2 2 800 800
+ * 3 1 1024 1024 # comment
+ */
+#ifdef ANSI_FUNC
+
+static void
+get_fbconfig (register VXimDataPtr vxim)
+#else
+
+static void
+get_fbconfig (vxim)
+register VXimDataPtr vxim;
+#endif
+{
+ register char *ip;
+ register FILE *fp = NULL;
+ int config, nframes, width, height, i;
+ char lbuf[SZ_LINE+1], *fname;
+ static char *fb_paths[] = {
+ "/usr/local/lib/imtoolrc",
+ "/opt/local/lib/imtoolrc",
+ "/iraf/iraf/dev/imtoolrc",
+ "/local/lib/imtoolrc",
+ "/usr/iraf/dev/imtoolrc",
+ "/usr/local/iraf/dev/imtoolrc",
+ NULL};
+
+ /* Initialize the config table. */
+ vxim->fb_configno = 1;
+ for (i=0; i < MAX_FBCONFIG; i++) {
+ vxim->fb_config[i].nframes = 1;
+ vxim->fb_config[i].width = DEF_FRAME_WIDTH;
+ vxim->fb_config[i].height = DEF_FRAME_HEIGHT;
+ }
+
+ /* Now add in some defaults for commonly used sizes based on the
+ * standard IRAF imtoolrc file, we'll avoid any instrument specific
+ * configurations.
+ */
+ vxim->fb_config[0].width = vxim->fb_config[0].height = 512;
+ vxim->fb_config[1].width = vxim->fb_config[1].height = 800;
+ vxim->fb_config[2].width = vxim->fb_config[2].height = 1024;
+ vxim->fb_config[3].width = vxim->fb_config[3].height = 1600;
+ vxim->fb_config[4].width = vxim->fb_config[4].height = 2048;
+ vxim->fb_config[5].width = vxim->fb_config[5].height = 4096;
+
+ /* Attempt to open the config file. */
+ if ((fname=getenv(FBCONFIG_ENV1)) || (fname=getenv(FBCONFIG_ENV2)))
+ fp = fopen (fname, "r");
+ if (!fp && (fname = getenv ("HOME"))) {
+ sprintf (lbuf, "%s/%s", fname, FBCONFIG_1);
+ fp = fopen (fname = lbuf, "r");
+ if (fp) {
+ vxim->imtoolrc = (char *) calloc (strlen(fname+1),sizeof(char));
+ strncpy (vxim->imtoolrc, fname, strlen(fname));
+ }
+ }
+ if (!fp)
+ fp = fopen (fname = vxim->imtoolrc, "r");
+ for (i=0; !fp && fb_paths[i]; i++) {
+ if ((fp = fopen (fname = fb_paths[i], "r"))) {
+ vxim->imtoolrc = (char *) calloc (strlen(fb_paths[i]+1),
+ sizeof(char));
+ strncpy (vxim->imtoolrc, fb_paths[i],strlen(fb_paths[i]));
+ break;
+ }
+ }
+ if (!fp) {
+ fprintf (stderr,
+ "Warning: No frame buffer configuration file found.\n");
+ return;
+ }
+
+
+ /* Scan the frame buffer configuration file.
+ */
+ while (fgets (lbuf, SZ_LINE, fp) != NULL) {
+ /* Skip comment lines and blank lines. */
+ for (ip=lbuf; *ip == ' ' || *ip == '\t'; ip++)
+ ;
+ if (*ip == '\n' || *ip == '#')
+ continue;
+ if (!isdigit (*ip))
+ continue;
+ switch (sscanf (ip, "%d%d%d%d", &config,&nframes,&width,&height)) {
+ case 4:
+ break; /* normal case */
+ case 3:
+ height = width; /* default to square format */
+ break;
+ default:
+ fprintf (stderr, "vximtool: bad config `%s'\n", ip);
+ continue;
+ }
+
+ nframes = max (1, nframes);
+ width = max (1, width);
+ height = max (1, height);
+
+ /* Since the frame buffer is stored in a memory pixrect
+ * (effectively), the line length should be an integral number
+ * of 16 bit words.
+ */
+ if (width & 1) {
+ fprintf (stderr, "imtool warning: fb config %d [%d-%dx%d] - ",
+ config, nframes, width, height);
+ fprintf (stderr, "frame width should be even, reset to %d\n",
+ --width);
+ }
+
+ config = max(1, min(MAX_FBCONFIG, config)) - 1;
+ vxim->fb_config[config].nframes = nframes;
+ vxim->fb_config[config].width = width;
+ vxim->fb_config[config].height = height;
+ }
+
+ fclose (fp);
+}
+
+
+
+/* USAGE -- Print a list of command-line options.
+ */
+#ifdef ANSI_FUNC
+
+static void
+Usage (void)
+#else
+
+static void
+Usage ()
+#endif
+{
+ fprintf (stderr, "Usage:\n\n");
+ printoption (" vximtool");
+ printoption ("[-background]"); /* run in background */
+ printoption ("[-config <num>]"); /* initial config */
+ printoption ("[-fifo <pipe>]"); /* fifo pipe */
+ printoption ("[-fifo_only]"); /* use fifo only */
+ printoption ("[-help]"); /* Print help */
+ printoption ("[-i]"); /* interactive */
+ printoption ("[-imtoolrc <file>]"); /* fbconfig file */
+ printoption ("[-inet_only | -port_only]"); /* use inet only */
+ printoption ("[-noraster]"); /* don't save pix */
+ printoption ("[-nframes <num>]"); /* # of frames */
+ printoption ("[-port <num>]"); /* inet port */
+ printoption ("[-nports <num>]"); /* No. inet ports */
+ printoption ("[-proxy]"); /* run a proxy server */
+ printoption ("[-verbose]"); /* verbose output */
+ printoption ("[-unix <name>]"); /* unix socket */
+ printoption ("[-unix_only]"); /* use unix only */
+ fprintf (stderr,"\n");
+}
+
+
+/* PRINTOPTION -- Pretty-print an option string.
+ */
+static int cpos = 0;
+#ifdef ANSI_FUNC
+
+static void
+printoption (char *st)
+#else
+
+static void
+printoption(st)
+char *st;
+#endif
+{
+ if (strlen(st) + cpos > 78) {
+ fprintf (stderr,"\n\t");
+ cpos = 8;
+ }
+ fprintf (stderr,"%s ",st);
+ cpos = cpos + strlen(st) + 1;
+}
+
+
+#ifdef HAVE_CDL
+/* VX_FLIP -- Reverse order of lines in raster.
+ */
+
+#ifdef ANSI_FUNC
+
+static void
+vx_flip (char *buffer, int nx, int ny)
+#else
+
+static void
+vx_flip (buffer, nx, ny)
+char *buffer;
+int nx;
+int ny;
+#endif
+{
+ register int i, j, v;
+ register char *buff1, *buff2;
+
+ for (i = 0; i < ny / 2; i++) {
+ buff1 = &buffer[i*nx];
+ buff2 = &buffer[(ny-1-i)*nx];
+ for (j = 0; j < nx; j++) {
+ v = *buff1;
+ *(buff1++) = *buff2;
+ *(buff2++) = v;
+ }
+ }
+}
+#endif
+
+
+/* ADD_MAPPING -- Add a mapping for the current frame.
+ *
+ * File format (two lines):
+ *
+ * image title (imtool header label string)\n
+ * a b c d tx ty z1 z2 zt \n
+ * region_name sx sy snx sny dx dy dnx dny\n
+ * object_ref
+ *
+ * The WCS text is passed in via the data stream as a write to the subunit
+ * WCS and left in the buffer "wcsbuf". Mapping information is parsed
+ * elsewhere if needed, our only purpose here is to extract the frame WCS.
+ */
+
+static void
+add_mapping (vxim, ctran, wcsbuf, fr)
+register VXimDataPtr vxim;
+CtranPtr ctran;
+char *wcsbuf;
+FrameBufPtr fr;
+{
+ register MappingPtr mp = &fr->mapping[fr->nmaps];
+ register CtranPtr ct = &mp->ctran;
+ register int i, j;
+ char buf[SZ_WCSBUF], *format;
+
+ /* Attempt to read the WCS and set up a unitary transformation
+ * if the information cannot be read.
+ */
+ if (sscanf (wcsbuf, "%[^\n]\n%f%f%f%f%f%f%f%f%d",
+ buf, &ct->a, &ct->b, &ct->c, &ct->d, &ct->tx, &ct->ty,
+ &ct->z1, &ct->z2, &ct->zt) < 7) {
+
+ if (wcsbuf[0])
+ fprintf (stderr, "vximtool: error decoding WCS\n");
+
+ strncpy (ct->imtitle, "[NO WCS]\n", SZ_IMTITLE);
+ ct->a = ct->d = 1;
+ ct->b = ct->c = 0;
+ ct->tx = ct->ty = 0;
+ ct->zt = W_UNITARY;
+ } else
+ strncpy (ct->imtitle, buf, SZ_IMTITLE);
+
+ ct->zt = W_UNITARY;
+ ct->valid = 1;
+
+
+ mp->ref[0] = '\0';
+ mp->region[0] = '\0';
+
+ /* Skip over the first two lines of WCS data.
+ */
+ strcpy (buf, wcsbuf);
+ for (i=0, j=0; j < 2 && buf[i]; i++)
+ if (buf[i] == '\n')
+ j++;
+
+ /* Attempt to read the mapping.
+ */
+ mp->id = mp->regid = ++objid;
+ if (sscanf (&buf[i], "%s%f%f%d%d%d%d%d%d\n%s\n",
+ mp->region, &mp->sx, &mp->sy, &mp->snx, &mp->sny,
+ &mp->dx, &mp->dy, &mp->dnx, &mp->dny, mp->ref) < 10) {
+
+ if (!wcsbuf[0])
+ fprintf (stderr, "vximtool: error decoding WCS mapping\n");
+ strncpy (mp->ref, "none", SZ_IMTITLE);
+
+ mp->sx = 1.0;
+ mp->sy = 1.0;
+ mp->snx = vxim->width;
+ mp->sny = vxim->height;
+ mp->dx = 1;
+ mp->dy = 1;
+ mp->dnx = vxim->width;
+ mp->dny = vxim->height;
+ }
+ memmove (ctran, &mp->ctran, sizeof (Ctran));
+
+ fr->nmaps++;
+}
+
+
+/* PRINT_MAPPINGS -- Debug routine to print all mappings on a frame.
+ */
+print_mappings (fr)
+FrameBufPtr fr;
+{
+ MappingPtr mp;
+ register int i;
+
+ if (fr->nmaps == 0) printf ("No mappings for frame %d\n", fr->frameno);
+ for (i=0; i < fr->nmaps; i++) {
+ mp = &fr->mapping[i];
+ printf ("Mapping %d frame=%d:\n", fr->nmaps, fr->frameno);
+ printf ("\t%s %f %f %d %d %d %d %d %d\n\t%s\n",
+ mp->region, mp->sx, mp->sy, mp->snx, mp->sny,
+ mp->dx, mp->dy, mp->dnx, mp->dny, mp->ref);
+ }
+}
+
+
+/* IIS_READ -- Read exactly "n" bytes from a descriptor.
+ */
+
+#ifdef ANSI_FUNC
+static int
+iis_read (int fd, void *vptr, int nbytes)
+
+#else
+static int
+iis_read (fd, vptr, nbytes)
+int fd;
+void *vptr;
+int nbytes;
+#endif
+{
+ char *ptr = vptr;
+ int nread = 0, nleft = nbytes, nb = 0;
+
+ while (nleft > 0) {
+ if ( (nb = read(fd, ptr, nleft)) < 0) {
+ if (errno == EINTR)
+ nb = 0; /* and call read() again */
+ else
+ return(-1);
+ } else if (nb == 0)
+ break; /* EOF */
+ nleft -= nb;
+ ptr += nb;
+ nread += nb;
+ }
+ return (nread); /* return no. of bytes read */
+}
+
+
+/* IIS_WRITE -- Write exactly "n" bytes to a descriptor.
+ */
+#ifdef ANSI_FUNC
+static int
+iis_write (int fd, void *vptr, int nbytes)
+
+#else
+
+static int
+iis_write (fd, vptr, nbytes)
+int fd;
+void *vptr;
+int nbytes;
+#endif
+
+{
+ char *ptr = vptr;
+ int nwritten = 0, nleft = nbytes, nb = 0;
+
+ while (nleft > 0) {
+ if ( (nb = write(fd, ptr, nleft)) <= 0) {
+ if (errno == EINTR)
+ nb = 0; /* and call write() again */
+ else
+ return(-1); /* error */
+ }
+ nleft -= nb;
+ ptr += nb;
+ nwritten += nb;
+ }
+ return (nwritten);
+}
diff --git a/vendor/x11iraf/vximtool/vximtool.man b/vendor/x11iraf/vximtool/vximtool.man
new file mode 100644
index 00000000..fd45b824
--- /dev/null
+++ b/vendor/x11iraf/vximtool/vximtool.man
@@ -0,0 +1,178 @@
+.\" @(#)vximtool.1 1.1 18-Jun-97 MJF
+.TH VXIMTOOL 1 "18 Jun 1997" "IRAF Project"
+.SH NAME
+vximtool \-- A virtual display server for IRAF IIS protocol clients
+.SH SYNOPSIS
+\fBvximtool\fP [ \fIoptions\fP ...]
+
+.SH "DESCRIPTION"
+.LP
+\fIVXIMTOOL\fR is a image display server process much like \fIXIMTOOL\fR,
+except that all it normally does is respond to datastream requests
+to read and write to internal frame buffers maintained as arrays in memory.
+Multiple frame buffers and frame buffer configurations are supported. It
+can be used to debug IIS protocol client programs by printing out the
+protocol packets recieved, or can simply be used as a dummy server in cases
+where no image display is really needed.
+
+The \fI-verbose\fR flag will log all datastream requests to the stderr,
+otherwise the task runs silently except for error messages. The process is
+terminated with an EOF on the stdin, if the task is intended to be run
+as a background job the \fI-background\fR flag should be enabled to shut
+off the check of the stdin and avoid a "waiting for tty input" message that
+would suspend the background job. Frame buffers are maintained as rasters
+in memory, up to four frames may currently be defined. If it not necessary
+to keep the displayed images in memory (i.e. the client will not need to
+read back any subrasters such as when doing overlay graphics), the
+\fI-noraster\fR flag can be used to disable the memory rasters. In this
+case any image readback will return an array of zero values.
+
+The default frame buffer size is 512x512, with 2 frames defined initially.
+The \fI-config\fR and \fI-nframes\fR flags can be used to change the
+startup frame buffers used. The frame buffer configuration table is normally
+taken to be /usr/local/lib/imtoolrc but can be overridden by using an
+IMTOOLRC environment variable, a \fI$HOME/.imtoolrc\fR file, or
+the \fI-imtoolrc\fR command-line flag respectively. The format of the
+frame buffer configuration file is
+
+ \fIconfigno nframes width height [extra fields]\fP
+ e.g.
+ 1 2 512 512
+ 2 2 800 800
+ 3 1 1024 1024 # comment
+
+and so on. At most 128 frame buffer sizes may be defined, each configuration
+may define up to 4 frames, configuration numbers need not be sequential.
+
+.SH OPTIONS
+.TP 5
+.B "-background"
+The task will be run in the background so don't listen to STDIN for an
+EOF to quit gracefully.
+.TP 5
+.B "-config \fInum\fP"
+Initial frame buffer configuration number. The default value is 1, indicating
+a 512x512 frame buffer with 2 frames. See below for information on the frame
+buffers.
+.TP 5
+.B "-fifo \fIpipe\fP"
+Specifies the name of the fifo pipe to be used, the \fIi\fP
+and \fIo\fP suffixes will be added automatically. The default pipe names
+will be /dev/imt1i (input pipe) and /dev/imt1o (output pipe).
+.TP 5
+.B "-fifo_only"
+If set, only fifo pipes will be used for communication with a client program,
+sockets will be disabled.
+.TP 5
+.B "-help"
+Print a summary of command line options to the screen.
+.TP 5
+.B "-interactive"
+Allow cursor value strings to be typed into the STDIN in response to cursor
+read requests from the client.
+.TP 5
+.B "-imtoolrc \fIfile\fP"
+Specifies the frame buffer configuration file to be used. See below for
+information on frame buffers.
+.TP 5
+.B "-inet_only"
+If set, only inet sockets will be used for communication with a client program,
+fifo pipes and unix sockets will be disabled.
+.TP 5
+.B "-noraster"
+If set no client data will be stored in memory, and image readback will
+return an array of zeroes.
+.TP 5
+.B "-nframes \fInum\fP"
+Specifies the number of frame buffers to configure at startup. By default
+there will be 2 frames available, a maximum of 4 frames are allowed.
+.TP 5
+.B "-port_only"
+Same as \fI-inet_only\fP option. If set, only inet sockets will be used for
+communication with a client program.
+.TP 5
+.B "-port \fInum\fP"
+Set the primary port to listen on for client connections. The default
+is 5137.
+.TP 5
+.B "-verbose"
+If set, print information about all IIS packets headers recieved to the
+STDERR stream.
+.TP 5
+.B "-unix \fIname\fP"
+Specifies the unix domain socket name to use. A "%d" in the filename will
+be replaced with the user id.
+.TP 5
+.B "-unix_only"
+If set, only unix domain sockets will be used for communication with a client
+program, inet sockets and fifos will be disabled.
+
+.SH "CLIENT CONNECTIONS"
+
+\fIVXImtool\fR allows clients to connect in any of the following ways:
+.TP 5
+.B "fifo pipes"
+The traditional approach. The default global /dev/imt1[io]
+pipes may be used, or a private set of fifos can be specified using the
+\fI-fifo\fP command line argument. Values should be specified as the root
+pathname to a pair of fifo pipes whose last character is 'i' or 'o',
+these characters will be added automatically when opening the pipes.
+For example, to use the default pipes the path would be specified as simply
+"/dev/imt1". A value of "none" disables this connection.
+.TP 5
+.B "tcp/ip sockets"
+Clients connect via a tcp/ip socket. The default port is \fI5137\fP, or a
+custom port may be specified using the \fI-port\fP command line switch.
+This permits connecting to the server over a remote network connection
+anywhere on the Internet. A port number of 0 (zero) disables this connection.
+.TP 5
+.B "unix domain sockets"
+Like a tcp/ip socket, but limited to a single host system. Usually faster
+than a tcp/ip socket, and comparable to a fifo. By default each user gets
+their own unix domain socket, so this option allows multiple users to run
+ximtools on the same host without having to customize things. The default
+value is "/tmp/.IMT%d", other sockets may be defined using the \fI-unix\fP
+command line switch. Legal values should be specified as a filename to be
+used for the socket, up to two "%d" fields are allowed and will be replaced
+by the userid. An empty string value disables this connection.
+.LP
+By default \fIvximtool\fR listens simultaneously for client connections on all
+three types of ports. Clients may connect simultaneously by different
+means allowing up to three different displays to be loading at the same
+time into different frames.
+
+.SH "COMMUNICATIONS PROTOCOL"
+
+Clients communicate with \fIvximtool\fR using a protocol developed originally
+for IIS (International Imaging Systems) Frame Buffer hardware, the so-called
+"IIS protocol"; other more modern protocols will likely be supported in the
+future. The IIS protocol is basically a command packet stream with a header
+describing the operation to be performed (select frame, load display, read
+cursor, etc), and an optional data packet containing e.g. pixels. It is
+beyond the scope of this document to describe fully the details of the
+protocol; interested users should contact \fIiraf@noao.edu\fP for further
+information.
+
+.SH "EXAMPLES"
+
+.TP 5
+1) Run the vximtool, logging output to the file named "spool":
+
+ \f(CW% vximtool -verbose >& spool\fR
+.TP 5
+2) Run the vximtool in the background, connect only on unix sockets, no output:
+
+ \f(CW% vximtool -b -unix_only &\fR
+.TP 5
+3) Don't store images in memory, start with initial 1024x1024 frame buffer:
+
+ \f(CW% vximtool -noraster -config 3\fR
+.TP 5
+4) Run the vximtool in the background, taking cursor input from a file:
+
+ \f(CW% vximtool -i < cursor_file &\fR
+
+.SH SEE ALSO
+ximtool(1)
+.SH COPYRIGHT
+Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
diff --git a/vendor/x11iraf/vximtool/vximtool.ps b/vendor/x11iraf/vximtool/vximtool.ps
new file mode 100644
index 00000000..aa4c686e
--- /dev/null
+++ b/vendor/x11iraf/vximtool/vximtool.ps
@@ -0,0 +1,1569 @@
+%!PS-Adobe-1.0
+%%Creator: devps (Pipeline Associates, Inc.)
+%%CreationDate: Thu Sep 11 15:23:35 1997
+%%Pages: (atend)
+%%DocumentFonts: (atend)
+
+/X{exch}def
+/r{rmoveto}def
+/m{moveto}def
+/l{lineto}def
+/rl{rlineto}def
+/lc{yc X xc X l st}def
+/mc{yc X xc X m}def
+/el{gs /a X def a div 1 X scale cp np a xc 2 div 0 360 arc st gr}def
+/ar{cp 7 2 roll np xc 5 1 roll atan 3 1 roll atan X arc st}def
+/sp{yc X xc X 6 2 roll yc X xc X 6 2 roll yc X xc X 6 2 roll ct}def
+/st{stroke}def
+/gs{gsave}def
+/gr{grestore}def
+/cp{currentpoint}def
+/np{newpath}def
+/ct{curveto}def
+/m0{0 0 moveto}def
+/BP{/devps-save save def m0}def
+/EP{
+clear devps-save restore
+showpage}def
+/res 10.000000 def
+/V{res neg div 792 add
+currentpoint pop X
+m}def
+/H{res div
+currentpoint X pop
+moveto}def
+/h{res div 0 r}def
+/v{res neg div 0 X r}def
+/xc{res div}def
+/yc{res neg div 792 add}def
+/S{X H show}def
+/psize 10 def
+/height 1 def
+/slant 0 def
+/FF{findfont X dup 12 div setlinewidth /psize X def
+ [psize 0 psize height mul slant sin slant cos div mul psize height mul 0 0]
+ makefont setfont}def
+/shade{gs
+ /dy X def
+ /dx X def
+ np m
+ setgray
+ 0 dy rl
+ dx 0 rl
+ 0 dy neg rl
+ dx neg 0 rl
+ closepath
+ fill
+gr}def
+1 setlinecap
+/R{/Times-Roman FF}def
+/B{/Times-Bold FF}def
+/I{/Times-Italic FF}def
+/C{/Courier FF}def
+%%EndProlog
+%%Page: 1 1
+BP
+/slant 0 def
+/height 1.000000 def
+10 R
+10 R
+480 V
+900(VXIMTOOL)S
+1448(\()S
+1497(1)S
+1563(\))S
+2787(USER COMMANDS )S
+4884(VXIMTOOL)S
+5432(\()S
+5481(1)S
+5547(\))S
+960 V
+9 B
+900(NAME)S
+1080 V
+10 R
+1260(vximtool)S
+1652(\261-)S
+1765(A)S
+1867(virtual)S
+2158(display)S
+2477(server)S
+2750(for)S
+2896(IRAF)S
+3154(IIS)S
+3306(protocol)S
+3669(clients)S
+1248 V
+9 B
+900(SYNOPSIS)S
+1368 V
+10 B
+1260(vximtool)S
+10 R
+1662([)S
+10 I
+1725(options)S
+10 R
+2050(...])S
+1656 V
+9 B
+900(DESCRIPTION)S
+1776 V
+10 I
+1260(VXIMTOOL)S
+10 R
+1793(is)S
+1899(a)S
+1982(image)S
+2265(display)S
+2593(server)S
+2875(process)S
+3213(much)S
+3475(like)S
+10 I
+3665(XIMTOOL)S
+10 R
+4098(,)S
+4163(except)S
+4463(that)S
+4653(all)S
+4793(it)S
+4889(normally)S
+5290(does)S
+5513(is)S
+1896 V
+1260(respond)S
+1632(to)S
+1766(datastream)S
+2254(requests)S
+2637(to)S
+2770(read)S
+2996(and)S
+3195(write)S
+3455(to)S
+3588(internal)S
+3948(frame)S
+4235(bu)S
+4335 H
+ (f)show 10 -.5 mul h (f)show
+10 R
+4396(ers)S
+4567(maintained)S
+5066(as)S
+5204(arrays)S
+5502(in)S
+2016 V
+1260(memory.)S
+1682(Multiple)S
+2062(frame)S
+2329(bu)S
+2429 H
+ (f)show 10 -.5 mul h (f)show
+10 R
+2490(ers)S
+2641(and)S
+2820(frame)S
+3087(bu)S
+3187 H
+ (f)show 10 -.5 mul h (f)show
+10 R
+3248(er)S
+3360(con\256gurations)S
+3967(are)S
+4123(supported.)S
+4607(It)S
+4703(can)S
+4876(be)S
+5005(used)S
+5223(to)S
+5336(debug)S
+2136 V
+1260(IIS)S
+1424(protocol)S
+1799(client)S
+2063(programs)S
+2482(by)S
+2624(printing)S
+2983(out)S
+3153(the)S
+3317(protocol)S
+3692(packets)S
+4033(recieved,)S
+4436(or)S
+4560(can)S
+4739(simply)S
+5053(be)S
+5188(used)S
+5412(as)S
+5536(a)S
+2256 V
+1260(dummy)S
+1596(server)S
+1869(in)S
+1977(cases)S
+2217(where)S
+2490(no)S
+2620(image)S
+2894(display)S
+3213(is)S
+3310(really)S
+3567(needed.)S
+2496 V
+1260(The)S
+10 I
+1448(-verbose)S
+10 R
+1824(\257ag)S
+2007(will)S
+2196(log)S
+2357(all)S
+2490(datastream)S
+2955(requests)S
+3315(to)S
+3426(the)S
+3581(stderr,)S
+3866(otherwise)S
+4287(the)S
+4442(task)S
+4636(runs)S
+4841(silently)S
+5170(except)S
+5464(for)S
+2616 V
+1260(error)S
+1485(messages.)S
+1949(The)S
+2136(process)S
+2467(is)S
+2566(terminated)S
+3025(with)S
+3234(an)S
+3359(EOF)S
+3579(on)S
+3710(the)S
+3863(stdin,)S
+4114(if)S
+4206(the)S
+4359(task)S
+4551(is)S
+4649(intended)S
+5024(to)S
+5133(be)S
+5258(run)S
+5422(as)S
+5536(a)S
+2736 V
+1260(background)S
+1772(job)S
+1941(the)S
+10 I
+2104(-background)S
+10 R
+2655(\257ag)S
+2846(should)S
+3154(be)S
+3289(enabled)S
+3640(to)S
+3760(shut)S
+3969(o)S
+4019 H
+ (f)show 10 -.5 mul h (f)show
+10 R
+4122(the)S
+4286(check)S
+4560(of)S
+4685(the)S
+4849(stdin)S
+5086(and)S
+5272(avoid)S
+5536(a)S
+2856 V
+1260("waiting)S
+1634(for)S
+1783(tty)S
+1922(input")S
+2202(message)S
+2573(that)S
+2756(would)S
+3039(suspend)S
+3394(the)S
+3549(background)S
+4053(job.)S
+4269(Frame)S
+4557(bu)S
+4657 H
+ (f)show 10 -.5 mul h (f)show
+10 R
+4718(ers)S
+4867(are)S
+5021(maintained)S
+5497(as)S
+2976 V
+1260(rasters)S
+1554(in)S
+1666(memory,)S
+2058(up)S
+2192(to)S
+2305(four)S
+2506(frames)S
+2812(may)S
+3019(currently)S
+3414(be)S
+3543(de\256ned.)S
+3927(If)S
+4028(it)S
+4119(not)S
+4282(necessary)S
+4704(to)S
+4817(keep)S
+5040(the)S
+5197(displayed)S
+3096 V
+1260(images)S
+1580(in)S
+1695(memory)S
+2065(\(i.e.)S
+2257(the)S
+2416(client)S
+2675(will)S
+2868(not)S
+3033(need)S
+3258(to)S
+3373(read)S
+3581(back)S
+3806(any)S
+3987(subrasters)S
+4423(such)S
+4643(as)S
+4763(when)S
+5016(doing)S
+5281(overlay)S
+3216 V
+1260(graphics\),)S
+1690(the)S
+10 I
+1846(-noraster)S
+10 R
+2252(\257ag)S
+2436(can)S
+2608(be)S
+2736(used)S
+2953(to)S
+3066(disable)S
+3384(the)S
+3541(memory)S
+3909(rasters.)S
+4259(In)S
+4377(this)S
+4557(case)S
+4763(any)S
+4942(image)S
+5221(readback)S
+3336 V
+1260(will)S
+1446(return)S
+1714(an)S
+1838(array)S
+2072(of)S
+2185(zero)S
+2386(values.)S
+3576 V
+1260(The)S
+1448(default)S
+1758(frame)S
+2023(bu)S
+2123 H
+ (f)show 10 -.5 mul h (f)show
+10 R
+2184(er)S
+2295(size)S
+2484(is)S
+2585(512x512,)S
+2994(with)S
+3206(2)S
+3290(frames)S
+3595(de\256ned)S
+3923(initially.)S
+4324(The)S
+10 I
+4513(-con\256g)S
+10 R
+4824(and)S
+10 I
+5002(-nframes)S
+10 R
+5391(\257ags)S
+3696 V
+1260(can)S
+1437(be)S
+1570(used)S
+1792(to)S
+1909(change)S
+2230(the)S
+2391(startup)S
+2702(frame)S
+2973(bu)S
+3073 H
+ (f)show 10 -.5 mul h (f)show
+10 R
+3134(ers)S
+3289(used.)S
+3566(The)S
+3760(frame)S
+4031(bu)S
+4131 H
+ (f)show 10 -.5 mul h (f)show
+10 R
+4192(er)S
+4308(con\256guration)S
+4880(table)S
+5113(is)S
+5219(normally)S
+3816 V
+1260(taken)S
+1507(to)S
+1616(be)S
+1741(/usr/local/lib/imtoolrc)S
+2645(but)S
+2804(can)S
+2973(be)S
+3098(overridden)S
+3561(by)S
+3692(using)S
+3941(an)S
+4067(IMTOOLRC)S
+4621(environment)S
+5158(variable,)S
+5536(a)S
+3936 V
+10 I
+1260($HOME/.imtoolrc)S
+10 R
+2029(\256le,)S
+2221(or)S
+2343(the)S
+10 I
+2504(-imtoolrc)S
+10 R
+2915(command-line)S
+3531(\257ag)S
+3719(respectively.)S
+4294(The)S
+4487(format)S
+4791(of)S
+4912(the)S
+5072(frame)S
+5342(bu)S
+5442 H
+ (f)show 10 -.5 mul h (f)show
+10 R
+5503(er)S
+4056 V
+1260(con\256guration)S
+1823(\256le)S
+1981(is)S
+4296 V
+10 I
+1410(con\256gno)S
+1784(nframes)S
+2136(width)S
+2389(height)S
+2669([extra)S
+2943(\256elds])S
+4416 V
+10 R
+1290(e.g.)S
+4536 V
+1560(1)S
+1670(2)S
+1780(512)S
+1990(512)S
+4656 V
+1560(2)S
+1670(2)S
+1780(800)S
+1990(800)S
+4776 V
+1560(3)S
+1670(1)S
+1750(1024)S
+1980(1024)S
+2480(#)S
+2560(comment)S
+5016 V
+1260(and)S
+1434(so)S
+1553(on.)S
+1738(At)S
+1868(most)S
+2093(128)S
+2273(frame)S
+2536(bu)S
+2636 H
+ (f)show 10 -.5 mul h (f)show
+10 R
+2697(er)S
+2805(sizes)S
+3030(may)S
+3233(be)S
+3358(de\256ned,)S
+3708(each)S
+3921(con\256guration)S
+4485(may)S
+4688(de\256ne)S
+4963(up)S
+5094(to)S
+5203(4)S
+5284(frames,)S
+5136 V
+1260(con\256guration)S
+1823(numbers)S
+2197(need)S
+2415(not)S
+2573(be)S
+2697(sequential.)S
+5424 V
+9 B
+900(OPTIONS)S
+5544 V
+10 B
+1260(-background)S
+5664 V
+10 R
+1510(The)S
+1695(task)S
+1886(will)S
+2072(be)S
+2196(run)S
+2359(in)S
+2467(the)S
+2619(background)S
+3120(so)S
+3239(don't)S
+3480(listen)S
+3727(to)S
+3835(STDIN)S
+4159(for)S
+4305(an)S
+4429(EOF)S
+4648(to)S
+4756(quit)S
+4942(gracefully.)S
+5832 V
+10 B
+1260(-con\256g)S
+10 I
+1579(num)S
+5952 V
+10 R
+1510(Initial)S
+1799(frame)S
+2081(bu)S
+2181 H
+ (f)show 10 -.5 mul h (f)show
+10 R
+2242(er)S
+2369(con\256guration)S
+2952(number.)S
+3362(The)S
+3567(default)S
+3894(value)S
+4160(is)S
+4277(1,)S
+4402(indicating)S
+4852(a)S
+4947(512x512)S
+5348(frame)S
+6072 V
+1510(bu)S
+1610 H
+ (f)show 10 -.5 mul h (f)show
+10 R
+1671(er)S
+1778(with)S
+1986(2)S
+2066(frames.)S
+2422(See)S
+2596(below)S
+2870(for)S
+3016(information)S
+3518(on)S
+3648(the)S
+3800(frame)S
+4062(bu)S
+4162 H
+ (f)show 10 -.5 mul h (f)show
+10 R
+4223(ers.)S
+6240 V
+10 B
+1260(-\256fo)S
+10 I
+1462(pipe)S
+6360 V
+10 R
+1510(Speci\256es)S
+1901(the)S
+2053(name)S
+2299(of)S
+2412(the)S
+2564(\256fo)S
+2733(pipe)S
+2936(to)S
+3045(be)S
+3170(used,)S
+3409(the)S
+10 I
+3562(i)S
+10 R
+3621(and)S
+10 I
+3796(o)S
+10 R
+3877(su)S
+3966 H
+ (f)show 10 -.5 mul h (\256)show
+10 R
+4050(xes)S
+4214(will)S
+4401(be)S
+4526(added)S
+4795(automatically.)S
+5425(The)S
+6480 V
+1510(default)S
+1817(pipe)S
+2019(names)S
+2304(will)S
+2490(be)S
+2614(/dev/imt1i)S
+3056(\(input)S
+3325(pipe\))S
+3560(and)S
+3734(/dev/imt1o)S
+4198(\(output)S
+4517(pipe\).)S
+6648 V
+10 B
+1260(-\256fo_only)S
+6768 V
+10 R
+1510(If)S
+1615(set,)S
+1790(only)S
+2007(\256fo)S
+2185(pipes)S
+2435(will)S
+2630(be)S
+2763(used)S
+2985(for)S
+3140(communication)S
+3801(with)S
+4018(a)S
+4101(client)S
+4363(program,)S
+4766(sockets)S
+5100(will)S
+5296(be)S
+5430(dis-)S
+6888 V
+1510(abled.)S
+7056 V
+10 B
+1260(-help)S
+10 R
+1510(Print)S
+1735(a)S
+1809(summary)S
+2211(of)S
+2324(command)S
+2748(line)S
+2928(options)S
+3253(to)S
+3361(the)S
+3513(screen.)S
+7224 V
+10 B
+1260(-interactive)S
+7704 V
+10 R
+900(IRAF Project)S
+2719(Last change: 18 Jun 1997)S
+5530(1)S
+7920 V
+EP
+%%Page: 2 2
+BP
+/slant 0 def
+/height 1.000000 def
+10 R
+10 R
+480 V
+900(VXIMTOOL)S
+1448(\()S
+1497(1)S
+1563(\))S
+2787(USER COMMANDS )S
+4884(VXIMTOOL)S
+5432(\()S
+5481(1)S
+5547(\))S
+960 V
+1510(Allow)S
+1792(cursor)S
+2073(value)S
+2321(strings)S
+2620(to)S
+2730(be)S
+2856(typed)S
+3110(into)S
+3299(the)S
+3454(STDIN)S
+3781(in)S
+3892(response)S
+4274(to)S
+4385(cursor)S
+4667(read)S
+4871(requests)S
+5231(from)S
+5458(the)S
+1080 V
+1510(client.)S
+1248 V
+10 B
+1260(-imtoolrc)S
+10 I
+1683(\256le)S
+1368 V
+10 R
+1510(Speci\256es)S
+1923(the)S
+2097(frame)S
+2381(bu)S
+2481 H
+ (f)show 10 -.5 mul h (f)show
+10 R
+2542(er)S
+2671(con\256guration)S
+3257(\256le)S
+3438(to)S
+3569(be)S
+3716(used.)S
+4007(See)S
+4204(below)S
+4501(for)S
+4670(information)S
+5195(on)S
+5348(frame)S
+1488 V
+1510(bu)S
+1610 H
+ (f)show 10 -.5 mul h (f)show
+10 R
+1671(ers.)S
+1656 V
+10 B
+1260(-inet_only)S
+1776 V
+10 R
+1510(If)S
+1611(set,)S
+1782(only)S
+1995(inet)S
+2180(sockets)S
+2509(will)S
+2700(be)S
+2829(used)S
+3047(for)S
+3198(communication)S
+3855(with)S
+4068(a)S
+4147(client)S
+4404(program,)S
+4802(\256fo)S
+4976(pipes)S
+5222(and)S
+5402(unix)S
+1896 V
+1510(sockets)S
+1834(will)S
+2020(be)S
+2144(disabled.)S
+2064 V
+10 B
+1260(-noraster)S
+2184 V
+10 R
+1510(If)S
+1606(set)S
+1747(no)S
+1877(client)S
+2129(data)S
+2325(will)S
+2511(be)S
+2635(stored)S
+2909(in)S
+3017(memory,)S
+3405(and)S
+3579(image)S
+3853(readback)S
+4242(will)S
+4428(return)S
+4696(an)S
+4820(array)S
+5054(of)S
+5167(zeroes.)S
+2352 V
+10 B
+1260(-nframes)S
+10 I
+1672(num)S
+2472 V
+10 R
+1510(Speci\256es)S
+1913(the)S
+2077(number)S
+2424(of)S
+2549(frame)S
+2823(bu)S
+2923 H
+ (f)show 10 -.5 mul h (f)show
+10 R
+2984(ers)S
+3142(to)S
+3262(con\256gure)S
+3681(at)S
+3795(startup.)S
+4164(By)S
+4323(default)S
+4642(there)S
+4883(will)S
+5081(be)S
+5217(2)S
+5309(frames)S
+2592 V
+1510(available,)S
+1925(a)S
+1999(maximum)S
+2435(of)S
+2548(4)S
+2628(frames)S
+2929(are)S
+3080(allowed.)S
+2760 V
+10 B
+1260(-port_only)S
+2880 V
+10 R
+1510(Same)S
+1770(as)S
+10 I
+1891(-inet_only)S
+10 R
+2334(option.)S
+2683(If)S
+2787(set,)S
+2961(only)S
+3177(inet)S
+3365(sockets)S
+3697(will)S
+3891(be)S
+4023(used)S
+4244(for)S
+4398(communication)S
+5058(with)S
+5275(a)S
+5358(client)S
+3000 V
+1510(program.)S
+3168 V
+10 B
+1260(-port)S
+10 I
+1506(num)S
+3288 V
+10 R
+1510(Set)S
+1668(the)S
+1820(primary)S
+2166(port)S
+2357(to)S
+2465(listen)S
+2712(on)S
+2842(for)S
+2988(client)S
+3240(connections.)S
+3802(The)S
+3987(default)S
+4294(is)S
+4391(5137.)S
+3456 V
+10 B
+1260(-verbose)S
+3576 V
+10 R
+1510(If)S
+1606(set,)S
+1772(print)S
+1991(information)S
+2493(about)S
+2745(all)S
+2875(IIS)S
+3027(packets)S
+3356(headers)S
+3690(recieved)S
+4057(to)S
+4165(the)S
+4317(STDERR)S
+4731(stream.)S
+3744 V
+10 B
+1260(-unix)S
+10 I
+1513(name)S
+3864 V
+10 R
+1510(Speci\256es)S
+1909(the)S
+2069(unix)S
+2285(domain)S
+2623(socket)S
+2916(name)S
+3170(to)S
+3286(use.)S
+3512(A)S
+3622("%d")S
+3876(in)S
+3993(the)S
+4154(\256lename)S
+4537(will)S
+4732(be)S
+4865(replaced)S
+5241(with)S
+5458(the)S
+3984 V
+1510(user)S
+1706(id.)S
+4152 V
+10 B
+1260(-unix_only)S
+4272 V
+10 R
+1510(If)S
+1607(set,)S
+1774(only)S
+1983(unix)S
+2192(domain)S
+2523(sockets)S
+2848(will)S
+3035(be)S
+3160(used)S
+3374(for)S
+3521(communication)S
+4174(with)S
+4383(a)S
+4458(client)S
+4711(program,)S
+5105(inet)S
+5286(sockets)S
+4392 V
+1510(and)S
+1684(\256fos)S
+1892(will)S
+2078(be)S
+2202(disabled.)S
+4680 V
+9 B
+900(CLIENT)S
+1272(CONNECTIONS)S
+4800 V
+10 I
+1260(VXImtool)S
+10 R
+1673(allows)S
+1964(clients)S
+2255(to)S
+2363(connect)S
+2703(in)S
+2811(any)S
+2985(of)S
+3098(the)S
+3250(following)S
+3669(ways:)S
+4968 V
+10 B
+1260(\256fo)S
+1429(pipes)S
+5088 V
+10 R
+1510(The)S
+1706(traditional)S
+2158(approach.)S
+2589(The)S
+2785(default)S
+3103(global)S
+3394(/dev/imt1[io])S
+3963(pipes)S
+4215(may)S
+4428(be)S
+4564(used,)S
+4814(or)S
+4939(a)S
+5025(private)S
+5344(set)S
+5497(of)S
+5208 V
+1510(\256fos)S
+1731(can)S
+1911(be)S
+2047(speci\256ed)S
+2444(using)S
+2703(the)S
+10 I
+2867(-\256fo)S
+10 R
+3070(command)S
+3506(line)S
+3698(argument.)S
+4172(Values)S
+4491(should)S
+4800(be)S
+4936(speci\256ed)S
+5333(as)S
+5458(the)S
+5328 V
+1510(root)S
+1701(pathname)S
+2119(to)S
+2227(a)S
+2301(pair)S
+2486(of)S
+2599(\256fo)S
+2768(pipes)S
+3009(whose)S
+3294(last)S
+3463(character)S
+3857(is)S
+3954('i')S
+4078(or)S
+4191('o',)S
+4362(these)S
+4597(characters)S
+5030(will)S
+5217(be)S
+5342(added)S
+5448 V
+1510(automatically)S
+2099(when)S
+2360(opening)S
+2727(the)S
+2894(pipes.)S
+3175(For)S
+3359(example,)S
+3767(to)S
+3890(use)S
+4068(the)S
+4234(default)S
+4555(pipes)S
+4810(the)S
+4976(path)S
+5192(would)S
+5486(be)S
+5568 V
+1510(speci\256ed)S
+1895(as)S
+2008(simply)S
+2311("/dev/imt1".)S
+2832(A)S
+2934(value)S
+3180(of)S
+3293("none")S
+3599(disables)S
+3951(this)S
+4126(connection.)S
+5736 V
+10 B
+1260(tcp/ip)S
+1535(sockets)S
+5856 V
+10 R
+1510(Clients)S
+1836(connect)S
+2188(via)S
+2352(a)S
+2438(tcp/ip)S
+2708(socket.)S
+3030(The)S
+3227(default)S
+3546(port)S
+3749(is)S
+10 I
+3858(5137)S
+10 R
+4058(,)S
+4125(or)S
+4250(a)S
+4337(custom)S
+4669(port)S
+4873(may)S
+5088(be)S
+5225(speci\256ed)S
+5976 V
+1510(using)S
+1760(the)S
+10 I
+1915(-port)S
+10 R
+2148(command)S
+2575(line)S
+2758(switch.)S
+3107(This)S
+3318(permits)S
+3650(connecting)S
+4120(to)S
+4230(the)S
+4384(server)S
+4659(over)S
+4868(a)S
+4944(remote)S
+5253(network)S
+6096 V
+1510(connection)S
+1978(anywhere)S
+2395(on)S
+2525(the)S
+2677(Internet.)S
+3072(A)S
+3174(port)S
+3365(number)S
+3700(of)S
+3813(0)S
+3893(\(zero\))S
+4160(disables)S
+4512(this)S
+4687(connection.)S
+6264 V
+10 B
+1260(unix)S
+1480(domain)S
+1833(sockets)S
+6384 V
+10 R
+1510(Like)S
+1733(a)S
+1817(tcp/ip)S
+2085(socket,)S
+2405(but)S
+2573(limited)S
+2898(to)S
+3017(a)S
+3102(single)S
+3382(host)S
+3590(system.)S
+3934(Usually)S
+4286(faster)S
+4548(than)S
+4761(a)S
+4846(tcp/ip)S
+5115(socket,)S
+5436(and)S
+6504 V
+1510(comparable)S
+2008(to)S
+2119(a)S
+2196(\256fo.)S
+2393(By)S
+2543(default)S
+2853(each)S
+3068(user)S
+3267(gets)S
+3460(their)S
+3675(own)S
+3879(unix)S
+4089(domain)S
+4421(socket,)S
+4733(so)S
+4854(this)S
+5031(option)S
+5319(allows)S
+6624 V
+1510(multiple)S
+1882(users)S
+2125(to)S
+2241(run)S
+2413(ximtools)S
+2803(on)S
+2942(the)S
+3103(same)S
+3347(host)S
+3553(without)S
+3898(having)S
+4209(to)S
+4326(customize)S
+4770(things.)S
+5109(The)S
+5303(default)S
+6744 V
+1510(value)S
+1758(is)S
+1857("/tmp/.IMT%d",)S
+2549(other)S
+2785(sockets)S
+3110(may)S
+3313(be)S
+3438(de\256ned)S
+3763(using)S
+4011(the)S
+10 I
+4164(-unix)S
+10 R
+4400(command)S
+4825(line)S
+5006(switch.)S
+5353(Legal)S
+6864 V
+1510(values)S
+1813(should)S
+2128(be)S
+2270(speci\256ed)S
+2673(as)S
+2804(a)S
+2896(\256lename)S
+3288(to)S
+3414(be)S
+3557(used)S
+3789(for)S
+3954(the)S
+4125(socket,)S
+4454(up)S
+4603(to)S
+4730(two)S
+4929("%d")S
+5193(\256elds)S
+5459(are)S
+6984 V
+1510(allowed)S
+1856(and)S
+2030(will)S
+2216(be)S
+2340(replaced)S
+2707(by)S
+2837(the)S
+2989(userid.)S
+3288(An)S
+3440(empty)S
+3720(string)S
+3978(value)S
+4224(disables)S
+4576(this)S
+4751(connection.)S
+7680 V
+900(IRAF Project)S
+2719(Last change: 18 Jun 1997)S
+5530(2)S
+7920 V
+EP
+%%Page: 3 3
+BP
+/slant 0 def
+/height 1.000000 def
+10 R
+10 R
+480 V
+900(VXIMTOOL)S
+1448(\()S
+1497(1)S
+1563(\))S
+2787(USER COMMANDS )S
+4884(VXIMTOOL)S
+5432(\()S
+5481(1)S
+5547(\))S
+960 V
+1260(By)S
+1408(default)S
+10 I
+1716(vximtool)S
+10 R
+2091(listens)S
+2378(simultaneously)S
+3015(for)S
+3162(client)S
+3415(connections)S
+3923(on)S
+4054(all)S
+4186(three)S
+4417(types)S
+4660(of)S
+4775(ports.)S
+5092(Clients)S
+5408(may)S
+1080 V
+1260(connect)S
+1614(simultaneously)S
+2264(by)S
+2408(di)S
+2486 H
+ (f)show 10 -.5 mul h (f)show
+10 R
+2547(erent)S
+2790(means)S
+3089(allowing)S
+3483(up)S
+3627(to)S
+3748(three)S
+3990(di)S
+4068 H
+ (f)show 10 -.5 mul h (f)show
+10 R
+4129(erent)S
+4371(displays)S
+4742(to)S
+4863(be)S
+5000(loading)S
+5343(at)S
+5458(the)S
+1200 V
+1260(same)S
+1495(time)S
+1703(into)S
+1889(di)S
+1967 H
+ (f)show 10 -.5 mul h (f)show
+10 R
+2028(erent)S
+2257(frames.)S
+1488 V
+9 B
+900(COMMUNICATIONS)S
+1807(PROTOCOL)S
+1608 V
+10 R
+1260(Clients)S
+1583(communicate)S
+2160(with)S
+10 I
+2377(vximtool)S
+10 R
+2760(using)S
+3016(a)S
+3099(protocol)S
+3471(developed)S
+3920(originally)S
+4348(for)S
+4503(IIS)S
+4664(\(International)S
+5247(Imaging)S
+1728 V
+1260(Systems\))S
+1659(Frame)S
+1946(Bu)S
+2063 H
+ (f)show 10 -.5 mul h (f)show
+10 R
+2124(er)S
+2232(hardware,)S
+2658(the)S
+2811(so-called)S
+3202("IIS)S
+3396(protocol";)S
+3829(other)S
+4065(more)S
+4301(modern)S
+4637(protocols)S
+5040(will)S
+5227(likely)S
+5486(be)S
+1848 V
+1260(supported)S
+1687(in)S
+1798(the)S
+1953(future.)S
+2279(The)S
+2467(IIS)S
+2622(protocol)S
+2988(is)S
+3088(basically)S
+3476(a)S
+3553(command)S
+3981(packet)S
+4275(stream)S
+4575(with)S
+4787(a)S
+4865(header)S
+5164(describing)S
+1968 V
+1260(the)S
+1421(operation)S
+1837(to)S
+1954(be)S
+2087(performed)S
+2541(\(select)S
+2840(frame,)S
+3136(load)S
+3347(display,)S
+3700(read)S
+3910(cursor,)S
+4223(etc\),)S
+4436(and)S
+4618(an)S
+4750(optional)S
+5116(data)S
+5320(packet)S
+2088 V
+1260(containing)S
+1712(e.g.)S
+1886(pixels.)S
+2180(It)S
+2271(is)S
+2368(beyond)S
+2692(the)S
+2844(scope)S
+3101(of)S
+3214(this)S
+3390(document)S
+3815(to)S
+3924(describe)S
+4287(fully)S
+4507(the)S
+4660(details)S
+4952(of)S
+5066(the)S
+5219(protocol;)S
+2208 V
+1260(interested)S
+1678(users)S
+1913(should)S
+2210(contact)S
+10 I
+2528(iraf@noao.edu)S
+10 R
+3164(for)S
+3310(further)S
+3611(information.)S
+2496 V
+9 B
+900(EXAMPLES)S
+2616 V
+10 R
+1260(1\))S
+1373(Run)S
+1570(the)S
+1722(vximtool,)S
+2139(logging)S
+2475(output)S
+2761(to)S
+2869(the)S
+3021(\256le)S
+3179(named)S
+3475("spool":)S
+2856 V
+10 C
+1750(%)S
+1870(vximtool)S
+2410(-verbose)S
+2950(>&)S
+3130(spool)S
+3024 V
+10 R
+1260(2\))S
+1373(Run)S
+1570(the)S
+1722(vximtool)S
+2114(in)S
+2222(the)S
+2374(background,)S
+2900(connect)S
+3240(only)S
+3448(on)S
+3578(unix)S
+3786(sockets,)S
+4135(no)S
+4265(output:)S
+3264 V
+10 C
+1750(%)S
+1870(vximtool)S
+2410(-b)S
+2590(-unix_only)S
+3250(&)S
+3432 V
+10 R
+1260(3\))S
+1373(Don't)S
+1636(store)S
+1860(images)S
+2173(in)S
+2281(memory,)S
+2669(start)S
+2871(with)S
+3079(initial)S
+3343(1024x1024)S
+3823(frame)S
+4085(bu)S
+4185 H
+ (f)show 10 -.5 mul h (f)show
+10 R
+4246(er:)S
+3672 V
+10 C
+1750(%)S
+1870(vximtool)S
+2410(-noraster)S
+3010(-config)S
+3490(3)S
+3840 V
+10 R
+1260(4\))S
+1373(Run)S
+1570(the)S
+1722(vximtool)S
+2114(in)S
+2222(the)S
+2374(background,)S
+2900(taking)S
+3180(cursor)S
+3459(input)S
+3695(from)S
+3919(a)S
+3993(\256le:)S
+4080 V
+10 C
+1750(%)S
+1870(vximtool)S
+2410(-i)S
+2590(<)S
+2710(cursor_file)S
+3430(&)S
+4368 V
+9 B
+900(SEE)S
+1112(ALSO)S
+4488 V
+10 R
+1260(ximtool\(1\))S
+4656 V
+9 B
+900(COPYRIGHT)S
+4776 V
+10 R
+1260(Copyright\(c\))S
+1806(1986)S
+2036(Association)S
+2538(of)S
+2651(Universities)S
+3164(for)S
+3310(Research)S
+3705(in)S
+3813(Astronomy)S
+4293(Inc.)S
+7680 V
+900(IRAF Project)S
+2719(Last change: 18 Jun 1997)S
+5530(3)S
+7920 V
+EP
+%%Trailer
+%%DocumentFonts: Times-Roman Times-Bold Times-Italic Courier
+%%Pages: 3
+ \ No newline at end of file
diff --git a/vendor/x11iraf/vximtool/vximtool_non_cdl.c b/vendor/x11iraf/vximtool/vximtool_non_cdl.c
new file mode 100644
index 00000000..d56040dc
--- /dev/null
+++ b/vendor/x11iraf/vximtool/vximtool_non_cdl.c
@@ -0,0 +1,1728 @@
+/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
+ */
+
+#ifdef AIXV3
+#include <sys/select.h>
+#endif
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/*
+ * VXIMTOOL.C -- Virtual image display server. This is a server process much
+ * like XIMTOOL, except that all the process does is respond to datastream
+ * requests to read and write to internal frame buffers maintained as arrays
+ * in memory. Multiple frame buffers and frame buffer configurations are
+ * supported. A log is kept to the stderr of all datastream requests. The
+ * process is terminated with an EOF on the stdin.
+ *
+ * Used to debug server i/o - NOT USED IN THE ONLINE PROGRAMS.
+ *
+ * To build: cc vximtool.c -o vximtool
+ * cc vximtool.c -o vximtool -lsocket # For Solaris systems
+ * cc -DANSI_FUNC vximtool.c # Use ANSI function prototypes
+ *
+ * Usage: vximtool -verbose >& spool # run server, log output
+ * vximtool -i # run interactively
+ * vximtool -noraster # don't store images in memory
+ * vximtool -i < cursor_file # take cursor input from file
+ *
+ * Options
+ *
+ * vximtool [-background] [-config <num>] [-fifo <pipe>] [-fifo_only] [-help]
+ * [-i] [-imtoolrc <file>] [-inet_only | -port_only] [-noraster]
+ * [-nframes <num>] [-port <num>] [-verbose] [-unix <name>] [-unix_only]
+ *
+ * Minimal match for command line options may be used. In interactive mode,
+ * cursor value strings may be typed in on the server stdin in response to
+ * cursor read requests from the client. Otherwise, a constant cursor value
+ * "1.0 1.0 101 q" is returned.
+ */
+
+
+/* Default values, size limiting values.
+ */
+#define MAX_FBCONFIG 128 /* max possible frame buf sizes */
+#define MAX_FRAMES 16 /* max number of frames */
+#define MAX_CLIENTS 8 /* max display server clients */
+#define DEF_NFRAMES 1 /* save memory; only one frame */
+#define DEF_FRAME_WIDTH 512 /* 512 square frame */
+#define DEF_FRAME_HEIGHT 512 /* 512 square frame */
+
+#define SZ_LABEL 256 /* main frame label string */
+#define SZ_IMTITLE 128 /* image title string */
+#define SZ_WCSBUF 320 /* WCS text buffer size */
+#define SZ_FIFOBUF 4000 /* transfer size for FIFO i/o */
+#define SZ_FNAME 256
+#define SZ_LINE 256
+
+/* Magic numbers. */
+#define DEF_PORT 5137 /* default tcp/ip socket */
+#define I_DEVNAME "/dev/imt1o" /* pseudo device names */
+#define O_DEVNAME "/dev/imt1i" /* our IN is client's OUT */
+#define DEF_UNIXADDR "/tmp/.IMT%d" /* default unix socket */
+#define FBCONFIG_1 ".imtoolrc"
+#define FBCONFIG_2 "/usr/local/lib/imtoolrc"
+#define FBCONFIG_ENV1 "imtoolrc"
+#define FBCONFIG_ENV2 "IMTOOLRC"
+
+/* IIS definitions. */
+#define IO_TIMEOUT 30
+#define MAXCONN 5
+#define SZ_IOBUF 65536 /* max size data transfer */
+#define SZ_FIFOBUF 4000
+#define SZ_WCSBUF 320 /* WCS text buffer size */
+#define SZ_FNAME 256
+#define SZ_IMCURVAL 160
+
+#define MEMORY 01 /* frame buffer i/o */
+#define LUT 02 /* lut i/o */
+#define FEEDBACK 05 /* used for frame clears */
+#define IMCURSOR 020 /* logical image cursor */
+#define WCS 021 /* used to set WCS */
+
+#define PACKED 0040000
+#define COMMAND 0100000
+#define IIS_READ 0100000
+#define IMC_SAMPLE 0040000
+#define IMT_FBCONFIG 077
+#define XYMASK 077777
+
+struct iism70 { /* DO NOT change the order of */
+ short tid; /* this structure. */
+ short thingct;
+ short subunit;
+ short checksum;
+ short x, y, z;
+ short t;
+};
+
+/* IIS data pixel values. */
+#define CMS_DATASTART 1
+#define CMS_DATAEND 200
+#define CMS_DATARANGE 200
+
+/* WCS definitions. */
+#define W_UNITARY 0
+#define W_LINEAR 1
+#define W_LOG 2
+#define W_DEFFORMAT " %7.2f %7.2f %7.1f%c"
+
+/* Rotation matrix defining world coordinate system (WCS) of a frame. */
+typedef struct {
+ int valid; /* has WCS been set? */
+ float a, b; /* x, y scale factors */
+ float c, d; /* x, y cross factors */
+ float tx, ty; /* x, y translation */
+ float z1, z2; /* greyscale range */
+ int zt; /* greyscale mapping */
+ char format[32]; /* wcs output format */
+ char imtitle[SZ_IMTITLE+1]; /* image title from WCS */
+} Ctran, *CtranPtr;
+
+/* The frame buffers. */
+typedef struct {
+ int frameno; /* frame number */
+ char *framebuf; /* frame buffer raster */
+ char label[SZ_LABEL+1]; /* frame label string */
+ Ctran ctran; /* world coordinate system */
+ char wcsbuf[SZ_WCSBUF]; /* wcs info string */
+} FrameBuf, *FrameBufPtr;
+
+/* Possible frame buffer sizes. */
+typedef struct {
+ int nframes; /* number of frames */
+ int width; /* frame buffer width */
+ int height; /* frame buffer height */
+} FbConfig, *FbConfigPtr;
+
+/* Client I/O channel. */
+typedef struct {
+ void *vxim; /* backpointer to vxim descriptor */
+ int type; /* channel type */
+ int listen_fd; /* socket server fd */
+ int datain; /* input channel */
+ int dataout; /* output channel */
+ int keepalive; /* used to keep input fifo ready */
+ int connected; /* channel is connected to client */
+ int port; /* inet port number */
+ char path[SZ_FNAME+1]; /* for unix sockets */
+ int reference_frame; /* reference (cmd i/o) frame */
+ FrameBufPtr rf_p; /* reference frame descriptor */
+} IoChan, *IoChanPtr;
+
+#define IO_FIFO 1
+#define IO_INET 2
+#define IO_UNIX 3
+
+
+/* Application runtime descriptor.
+ * --------------------------------
+ */
+typedef struct {
+ int def_config; /* default FB config */
+ int def_nframes; /* default number of frames */
+ char *imtoolrc; /* imtoolrc file name */
+ char *input_fifo; /* client's output */
+ char *output_fifo; /* client's input */
+ char *unixaddr; /* format for unix socket path */
+ int port; /* port for INET socket */
+
+ /* Internal state. */
+ int display_frame; /* currently displayed frame */
+ int fb_configno; /* current config number */
+ int nframes; /* current number of frame bufs */
+ int width, height; /* current width, height */
+ IoChan chan[MAX_CLIENTS]; /* client i/o descriptors */
+ FrameBufPtr df_p; /* display frame descriptor */
+ FrameBuf frames[MAX_FRAMES]; /* array of frame descriptors */
+ FbConfig fb_config[MAX_FBCONFIG]; /* fb config table */
+
+} VXimData, *VXimDataPtr;
+
+
+/* Initialize the structure with out starting values. These can be reset
+ * with command line options.
+ */
+VXimData server_data = {
+ 1, /* def_config */
+ DEF_NFRAMES, /* def_nframes */
+ FBCONFIG_2, /* def_imtoolrc */
+ O_DEVNAME, /* input_fifo */
+ I_DEVNAME, /* output_fifo */
+ DEF_UNIXADDR, /* unixaddr */
+ DEF_PORT, /* port */
+ 1, /* display_frame */
+ 1, /* fb_configno */
+ 2, /* nframes */
+ 512, 512 /* width, height */
+};
+
+/* Functions.
+ */
+#ifndef abs
+#define abs(a) (((a)<0)?(-(a)):(a))
+#endif
+#ifndef min
+#define min(a,b) ((a)<(b)?(a):(b))
+#endif
+#ifndef max
+#define max(a,b) ((a)<(b)?(b):(a))
+#endif
+
+#ifdef SOLARIS
+#define bzero(a,n) memset(a,0,n)
+#define bcopy(a,b,n) memmove(b,a,n)
+#endif
+
+#define SELWIDTH 32
+
+extern int errno;
+static int verbose = 0;
+static int background = 0;
+static int interactive = 0;
+static int keep_raster = 1;
+static float cursor_x = 1.0, cursor_y = 1.0;
+static fd_set fds, allset;
+
+
+#ifdef ANSI_FUNC
+
+int main(int argc, char **argv);
+static int vx_iisopen(register VXimDataPtr vxim);
+static void vx_iisclose(register VXimDataPtr vxim);
+static IoChanPtr open_fifo(register VXimDataPtr vxim);
+static IoChanPtr open_inet(register VXimDataPtr vxim);
+static IoChanPtr open_unix(register VXimDataPtr vxim);
+static void vx_connectClient(IoChanPtr chan, int *source);
+static void vx_disconnectClient(register IoChanPtr chan);
+static IoChanPtr get_iochan(register VXimDataPtr vxim);
+static void vx_iisio(IoChanPtr chan, int *fd_addr, int source);
+static void set_fbconfig(IoChanPtr chan, int config, int frame);
+static int decode_frameno(register int z);
+static int bswap2(char *a, char *b, int nbytes);
+static void vx_retCursorVal(register int dataout, float sx, float sy,
+ int wcs, int key, char *strval);
+static CtranPtr wcs_update(register VXimDataPtr vxim, FrameBufPtr fr);
+static void vx_initialize(register VXimDataPtr vxim, int config,
+ int nframes, int reset);
+static void vx_initFrame(register VXimDataPtr vxim, int frame,
+ int nframes, FbConfigPtr config);
+static void vx_eraseFrame(register VXimDataPtr vxim, int frame);
+static void get_fbconfig(register VXimDataPtr vxim);
+static void Usage(void);
+static void printoption(char *st);
+static int iis_read(int fd, void *vptr, int nbytes);
+static int iis_write(int fd, void *vptr, int nbytes);
+
+#else
+
+static void vx_iisclose(), vx_connectClient(), vx_disconnectClient();
+static void vx_iisio(), set_fbconfig(), vx_retCursorVal();
+static void vx_initialize(), vx_initFrame(), vx_eraseFrame();
+static void get_fbconfig(), Usage(), printoption();
+static int vx_iisopen(), decode_frameno(), bswap2();
+static int iis_read(), iis_write();
+static IoChanPtr open_fifo(), open_inet(), open_unix(), get_iochan();
+static CtranPtr wcs_update();
+
+#endif
+
+
+/*
+ * VXIMTOOL -- Virtual display server process. This task is an image display
+ * server like XImtool, responding to datastream requests on fifo pipes,
+ * inet sockets, or unix sockets. Up to 16 frames are supported, frame
+ * buffers may be any of the defined frames in the imtoolrc file. Images
+ * are stored in memory, allowing readback by the client. Cursor input can
+ * come from stdin (or a redirected file) allowing the user to respond to
+ * client cursor requests. The task is terminated with an EOF on stdin.
+ */
+
+#ifdef ANSI_FUNC
+
+int
+main (int argc, char **argv)
+#else
+
+main (argc, argv)
+int argc;
+char **argv;
+#endif
+{
+ register VXimDataPtr vxim = &server_data;
+ register IoChanPtr chan;
+ register int i, nopen, n;
+ char buf[SZ_FNAME];
+ int fd;
+
+ /* Process the command line arguments. */
+ for (i=1; i < argc; i++) {
+ if (strncmp (argv[i], "-background", 2) == 0) {
+ background = 1;
+ } else if (strncmp (argv[i], "-config", 2) == 0) {
+ vxim->def_config = atoi (argv[++i]);
+ } else if (strncmp (argv[i], "-fifo_only", 6) == 0) {
+ vxim->unixaddr = "none";
+ vxim->port = 0;
+ } else if (strncmp (argv[i], "-fifo", 5) == 0) {
+ vxim->input_fifo = (char *) calloc (SZ_FNAME, sizeof(char));
+ vxim->output_fifo = (char *) calloc (SZ_FNAME, sizeof(char));
+ sprintf (vxim->input_fifo, "%si", argv[++i]);
+ sprintf (vxim->output_fifo, "%so", argv[i]);
+ } else if (strncmp (argv[i], "-help", 2) == 0) {
+ Usage ();
+ exit (0);
+ } else if (strncmp (argv[i], "-imtoolrc", 3) == 0) {
+ vxim->imtoolrc = argv[++i];
+ } else if (strncmp (argv[i], "-inet_only", 3) == 0) {
+ vxim->input_fifo = "";
+ vxim->unixaddr = "none";
+ } else if (strcmp (argv[i], "-i") == 0) {
+ interactive++;
+ } else if (strncmp (argv[i], "-noraster", 3) == 0) {
+ keep_raster = 0;
+ } else if (strncmp (argv[i], "-nframes", 3) == 0) {
+ i++;
+ vxim->def_nframes = min (4, atoi (argv[i]));
+ } else if (strncmp (argv[i], "-port_only", 6) == 0) {
+ vxim->input_fifo = "";
+ vxim->unixaddr = "none";
+ } else if (strncmp (argv[i], "-port", 5) == 0) {
+ vxim->port = atoi (argv[++i]);
+ } else if (strncmp (argv[i], "-verbose", 2) == 0) {
+ verbose = 1;
+ } else if (strncmp (argv[i], "-unix_only", 6) == 0) {
+ vxim->input_fifo = "";
+ vxim->port = 0;
+ } else if (strncmp (argv[i], "-unix", 5) == 0) {
+ vxim->unixaddr = argv[++i];
+ }
+ }
+
+ /* Initialize the frame buffers */
+ vx_initialize (vxim, vxim->def_config, vxim->def_nframes, 1);
+
+ /* Listen for a client connection and initialize the fdset. */
+ if (! (nopen = vx_iisopen (vxim)))
+ exit (-1);
+ FD_ZERO (&allset);
+ for (i=0; i < nopen; i++) {
+ chan = &vxim->chan[i];
+ FD_SET (chan->datain, &allset);
+ }
+ if (!background || interactive)
+ FD_SET (fileno(stdin), &allset);
+
+ /* Sit in a loop waiting on input, processing the events. */
+ while (1) {
+ fds = allset; /* reset the FD set on each pass */
+
+ if ((n = select (SELWIDTH, &fds, NULL, NULL, NULL)) > 0) {
+
+ /* Loop over each of the open connections, checking for and
+ * processing input on any that are ready.
+ */
+ for (i=0; i < nopen; i++) {
+ chan = &vxim->chan[i];
+ fd = chan->datain;
+ if (FD_ISSET(fd, &fds)) {
+
+ /* Connect the client if not already connected. */
+ if (!chan->connected) {
+ if (verbose) {
+ if (chan->type == IO_UNIX)
+ fprintf (stderr,
+ "connecting client on %s\n",
+ chan->path);
+ else if (chan->type == IO_INET)
+ fprintf (stderr,
+ "connecting client on port %d\n",
+ vxim->port);
+ }
+ vx_connectClient (chan, &chan->datain);
+ }
+
+ /* Process any waiting input. */
+ vx_iisio (chan, &chan->datain, chan->type);
+ fflush (stdout); fflush (stderr);
+ }
+ }
+
+ /* Check the stdin for an EOF so we can quit gracefully. */
+ if (!background) {
+ if (FD_ISSET(fileno(stdin), &fds)) {
+ if ((n = read (fileno(stdin), buf, SZ_FNAME)) <= 0) {
+ /* Shut it down. */
+ vx_iisclose (vxim);
+ exit (0);
+ }
+ }
+ }
+
+ } else if (n < 0) {
+ fprintf (stderr, "select error\n");
+ exit (-1);
+ }
+ }
+}
+
+
+
+/* VX_IISOPEN -- Initialize the IIS protocol module and ready the module to
+ * accept client connections and begin processing client requests. Clients
+ * may connect to the server using a fifo connection or an internet or
+ * UNIX domain socket connection. All three types of server ports are
+ * simultaneously ready to receive client connections.
+ */
+#ifdef ANSI_FUNC
+
+static int
+vx_iisopen (register VXimDataPtr vxim)
+#else
+
+static int
+vx_iisopen (vxim)
+register VXimDataPtr vxim;
+#endif
+{
+ int nopen = 0;
+
+ if (open_fifo (vxim))
+ nopen++;
+ if (open_inet (vxim))
+ nopen++;
+ if (open_unix (vxim))
+ nopen++;
+
+ return (nopen);
+}
+
+
+/* VX_IISCLOSE -- Close down the IIS protocol module.
+ */
+#ifdef ANSI_FUNC
+
+static void
+vx_iisclose (register VXimDataPtr vxim)
+#else
+
+static void
+vx_iisclose (vxim)
+register VXimDataPtr vxim;
+#endif
+{
+ register IoChanPtr chan = NULL;
+ register FrameBufPtr fb;
+ register int i, j;
+
+ for (i=0; i < (sizeof(vxim->chan) / sizeof(vxim->chan[0])); i++) {
+ chan = &vxim->chan[i];
+
+ /* Free the in-memory frame buffer rasters. */
+ for (j=0; j < vxim->nframes; j++) {
+ fb = &vxim->frames[j];
+ if (keep_raster && fb->framebuf)
+ free (fb->framebuf);
+ }
+
+ /* Close the I/O channels. */
+ switch (chan->type) {
+ case IO_FIFO:
+ if (chan->keepalive >= 0)
+ close (chan->keepalive);
+ if (chan->datain >= 0)
+ close (chan->datain);
+ if (chan->dataout >= 0)
+ close (chan->dataout);
+ chan->type = 0;
+ break;
+
+ case IO_INET:
+ close (chan->datain);
+ chan->type = 0;
+ break;
+
+ case IO_UNIX:
+ close (chan->datain);
+ unlink (chan->path);
+ chan->type = 0;
+ break;
+ }
+ }
+}
+
+
+/* OPEN_FIFO -- Open the server fifo port and make ready to accept client
+ * connections and begin processing client requests. There is no client
+ * yet at this stage.
+ */
+#ifdef ANSI_FUNC
+
+static IoChanPtr
+open_fifo (register VXimDataPtr vxim)
+#else
+
+static IoChanPtr
+open_fifo (vxim)
+register VXimDataPtr vxim;
+#endif
+{
+ register IoChanPtr chan;
+ int datain, dataout;
+ int keepalive;
+
+ /* Setting the input fifo to "none" or the null string disables
+ * fifo support.
+ */
+ if (!vxim->input_fifo[0] || strcmp(vxim->input_fifo,"none")==0)
+ return (NULL);
+
+ datain = dataout = -1;
+
+ /* Open the output fifo (which is the client's input fifo). We have
+ * to open it ourselves first as a client to get around the fifo
+ * open-no-client error.
+ */
+ if ((datain = open (vxim->input_fifo, O_RDONLY|O_NDELAY)) != -1) {
+ if ((dataout = open (vxim->input_fifo, O_WRONLY|O_NDELAY)) != -1)
+ fcntl (dataout, F_SETFL, O_WRONLY);
+ else
+ goto done;
+ close (datain);
+ } else
+ goto done;
+
+ /* Open the input stream, a FIFO pseudodevice file used by
+ * applications to send us commands and data.
+ */
+ if ((datain = open (vxim->output_fifo, O_RDONLY|O_NDELAY)) == -1)
+ goto done;
+ else {
+ /* Clear O_NDELAY for reading. */
+ fcntl (datain, F_SETFL, O_RDONLY);
+
+ /* Open the client's output fifo as a pseudo-client to make it
+ * appear that a client is connected.
+ */
+ keepalive = open (vxim->output_fifo, O_WRONLY);
+ }
+done:
+ /* Allocate and fill in i/o channel descriptor. */
+ if (datain > 0 && dataout > 0 && (chan = get_iochan(vxim))) {
+ chan->vxim = (void *) vxim;
+ chan->type = IO_FIFO;
+ chan->datain = datain;
+ chan->dataout = dataout;
+ chan->keepalive = keepalive;
+ chan->connected = 1;
+ chan->reference_frame = 1;
+ chan->rf_p = &vxim->frames[0];
+ } else {
+ fprintf (stderr, "Warning: cannot open %s\n", vxim->output_fifo);
+ chan = NULL;
+ }
+
+ /* Register input callback. */
+ if (!chan) {
+ if (datain > 0)
+ close (datain);
+ if (dataout > 0)
+ close (dataout);
+ } else if (verbose) {
+ fprintf (stderr,
+ "Open to accept input on fifo: %s\n", vxim->input_fifo);
+ }
+
+ return (chan);
+}
+
+
+/* OPEN_INET -- Set up a port to be used for incoming client connections
+ * using internet domain sockets.
+ */
+#ifdef ANSI_FUNC
+
+static IoChanPtr
+open_inet (register VXimDataPtr vxim)
+#else
+
+static IoChanPtr
+open_inet (vxim)
+register VXimDataPtr vxim;
+#endif
+{
+ register int s = 0;
+ register IoChanPtr chan;
+ struct sockaddr_in sockaddr;
+
+ /* Setting the port to zero disables inet socket support. */
+ if (vxim->port <= 0)
+ return (NULL);
+
+ if ((s = socket (AF_INET, SOCK_STREAM, 0)) < 0)
+ goto err;
+
+ memset ((void *)&sockaddr, 0, sizeof(sockaddr));
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = htons((short)vxim->port);
+ sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ if (bind (s, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) < 0)
+ goto err;
+
+ if (listen (s, MAXCONN) < 0)
+ goto err;
+
+ /* Allocate and fill in i/o channel descriptor. */
+ if (chan = get_iochan(vxim)) {
+ chan->vxim = (void *) vxim;
+ chan->type = IO_INET;
+ chan->port = vxim->port;
+ chan->datain = s;
+ chan->dataout = s;
+ chan->listen_fd = s;
+ chan->connected = 0;
+ chan->reference_frame = 1;
+ chan->rf_p = &vxim->frames[0];
+ if (verbose)
+ fprintf (stderr,
+ "Open to accept input on inet: port %d\n", vxim->port);
+ return (chan);
+ }
+err:
+ fprintf (stderr, "vximtool: cannot open socket on port %d, errno=%d\n",
+ vxim->port, errno);
+ if (s)
+ close (s);
+ return (NULL);
+}
+
+
+/* OPEN_UNIX -- Set up a port to be used for incoming client connections
+ * using unix domain sockets.
+ */
+#ifdef ANSI_FUNC
+
+static IoChanPtr
+open_unix (register VXimDataPtr vxim)
+#else
+
+static IoChanPtr
+open_unix (vxim)
+register VXimDataPtr vxim;
+#endif
+{
+ register int s = 0;
+ register IoChanPtr chan;
+ struct sockaddr_un sockaddr;
+ char path[256];
+
+ /* Setting the addr to "none" or the null string disables unix
+ * socket support.
+ */
+ if (!vxim->unixaddr[0] || strcmp(vxim->unixaddr,"none")==0)
+ return (NULL);
+
+ /* Get path to be used for the unix domain socket. */
+ sprintf (path, vxim->unixaddr, getuid());
+ unlink (path);
+
+ if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
+ goto err;
+
+ memset ((void *)&sockaddr, 0, sizeof(sockaddr));
+ sockaddr.sun_family = AF_UNIX;
+ strcpy (sockaddr.sun_path, path);
+ if (bind (s, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) < 0)
+ goto err;
+
+ if (listen (s, MAXCONN) < 0)
+ goto err;
+
+ /* Allocate and fill in i/o channel descriptor. */
+ if (chan = get_iochan(vxim)) {
+ chan->vxim = (void *) vxim;
+ chan->type = IO_UNIX;
+ chan->datain = s;
+ chan->dataout = s;
+ chan->listen_fd = s;
+ chan->connected = 0;
+ chan->reference_frame = 1;
+ chan->rf_p = &vxim->frames[0];
+ strncpy (chan->path, path, SZ_FNAME);
+ if (verbose)
+ fprintf (stderr,
+ "Open to accept input on unix: %s\n", path);
+ return (chan);
+ }
+err:
+ fprintf (stderr, "vximtool: cannot open socket on port %s, errno=%d\n",
+ path, errno);
+ if (s)
+ close (s);
+ return (NULL);
+}
+
+
+/* VX_CONNECTCLIENT -- Called when a client has attempted a connection on
+ * a socket port. Accept the connection and set up a new i/o channel to
+ * communicate with the new client.
+ */
+#ifdef ANSI_FUNC
+
+static void
+vx_connectClient (IoChanPtr chan, int *source)
+#else
+
+static void
+vx_connectClient (chan, source)
+IoChanPtr chan;
+int *source;
+#endif
+{
+ register VXimDataPtr vxim = (VXimDataPtr) chan->vxim;
+ register int s;
+
+ /* Accept connection. */
+ if ((s = accept ((int)*source, (struct sockaddr *)0, (int *)0)) < 0)
+ return;
+ if (fcntl (s, F_SETFD, O_RDWR|O_NDELAY) < 0) {
+ close (s);
+ return;
+ }
+
+ /* Allocate and fill in i/o channel descriptor. */
+ FD_SET(s, &allset);
+ chan->datain = s;
+ chan->dataout = s;
+ chan->connected = 1;
+ chan->reference_frame = 1;
+ chan->rf_p = &vxim->frames[0];
+}
+
+
+/* VX_DISCONNECTCLIENT -- Called to close a client connection when EOF is
+ * seen on the input port. Close the connection and free the channel
+ * descriptor.
+ */
+#ifdef ANSI_FUNC
+
+static void
+vx_disconnectClient (register IoChanPtr chan)
+#else
+
+static void
+vx_disconnectClient (chan)
+register IoChanPtr chan;
+#endif
+{
+ switch (chan->type) {
+ case IO_INET:
+ if (verbose)
+ fprintf (stderr,
+ "disconnecting client on port %d\n", chan->port);
+ case IO_UNIX:
+ if (verbose && chan->type == IO_UNIX)
+ fprintf (stderr,
+ "disconnecting client on %s\n", chan->path);
+ FD_CLR(chan->datain, &allset);
+ close (chan->datain);
+ chan->datain = chan->dataout = chan->listen_fd;
+ chan->connected = 0;
+ break;
+ default:
+ break;
+ }
+}
+
+
+/* GET_IOCHAN --- Get an i/o channel descriptor.
+ */
+#ifdef ANSI_FUNC
+
+static IoChanPtr
+get_iochan (register VXimDataPtr vxim)
+#else
+
+static IoChanPtr
+get_iochan (vxim)
+register VXimDataPtr vxim;
+#endif
+{
+ register IoChanPtr chan;
+ register int i;
+
+ for (i=0; i < MAX_CLIENTS; i++)
+ if (!vxim->chan[i].type)
+ return (&vxim->chan[i]);
+
+ return (NULL);
+}
+
+
+/* VX_IISIO -- File i/o callback procedure, called when there is input
+ * pending on the data stream to the vximtool client.
+ */
+#ifdef ANSI_FUNC
+
+static void
+vx_iisio (IoChanPtr chan, int *fd_addr, int source)
+#else
+
+static void
+vx_iisio (chan, fd_addr, source)
+IoChanPtr chan;
+int *fd_addr;
+int source;
+#endif
+{
+ register VXimDataPtr vxim = (VXimDataPtr) chan->vxim;
+ register int sum, i;
+ register short *p;
+ int datain = *fd_addr;
+ int dataout = chan->dataout;
+ int ndatabytes, nbytes, n, ntrys=0;
+ struct iism70 iis;
+ char buf[SZ_FIFOBUF];
+ static int errmsg=0, bswap=0;
+
+
+ /* Get the IIS header. */
+ if ((n = iis_read (datain, (char *)&iis, sizeof(iis))) < sizeof(iis)) {
+ if (n <= 0)
+ vx_disconnectClient (chan);
+ else
+ fprintf (stderr, "vximtool: command input read error\n");
+ return;
+ } else if (bswap)
+ bswap2 ((char *)&iis, (char *)&iis, sizeof(iis));
+
+ /* Verify the checksum. If it fails swap the bytes and try again.
+ */
+ for (;;) {
+ for (i=0, sum=0, p=(short *)&iis; i < 8; i++)
+ sum += *p++;
+ if ((sum & 0177777) == 0177777)
+ break;
+
+ if (ntrys++) {
+ if (!errmsg++) {
+ fprintf (stderr, "vximtool: bad data header checksum\n");
+ if (bswap)
+ bswap2 ((char *)&iis, (char *)&iis, sizeof(iis));
+ fprintf (stderr, "noswap:");
+ for (i=0, p=(short *)&iis; i < 8; i++)
+ fprintf (stderr, " %6o", p[i]);
+ fprintf (stderr, "\n");
+
+ bswap2 ((char *)&iis, (char *)&iis, sizeof(iis));
+ fprintf (stderr, " swap:");
+ for (i=0, p=(short *)&iis; i < 8; i++)
+ fprintf (stderr, " %6o", p[i]);
+ fprintf (stderr, "\n");
+ }
+ break;
+
+ } else {
+ bswap2 ((char *)&iis, (char *)&iis, sizeof(iis));
+ bswap = !bswap;
+ }
+ }
+
+ ndatabytes = -iis.thingct;
+ if (!(iis.tid & PACKED))
+ ndatabytes *= 2;
+
+ if (verbose) {
+ fprintf (stderr, "%s: ", (source == IO_FIFO ? "fifo" :
+ (source == IO_INET ? "inet" : "unix")));
+ fprintf (stderr,
+ "subunit=%03o tid=%06o nbytes=%6d x=%06o y=%06o z=%06o t=%06o\n",
+ iis.subunit & 077,
+ iis.tid,
+ ndatabytes,
+ iis.x & 0177777,
+ iis.y & 0177777,
+ iis.z & 0177777,
+ iis.t & 0177777);
+ fflush (stdout);
+ }
+
+
+ switch (iis.subunit & 077) {
+ case FEEDBACK:
+ /* The feedback unit is used only to clear a frame.
+ */
+ chan->reference_frame = decode_frameno (iis.z & 07777);
+ vx_eraseFrame (vxim, chan->reference_frame);
+ if (verbose)
+ fprintf (stderr, "erase frame %d - ref = %d\n",
+ decode_frameno(iis.z & 07777), chan->reference_frame);
+ break;
+
+ case LUT:
+ /* Data mode writes to the frame lookup tables are not implemented.
+ * A command mode write to the LUT subunit is used to connect
+ * image memories up to the RGB channels, i.e., to select the frame
+ * to be displayed. We ignore any attempt to assign multiple
+ * frames to multiple color channels, and just do a simple frame
+ * select.
+ */
+ if (iis.subunit & COMMAND) {
+ int frame, z, n;
+ short x[14];
+
+ if (iis_read (datain, (char *)x, ndatabytes) == ndatabytes) {
+ if (bswap)
+ bswap2 ((char *)x, (char *)x, ndatabytes);
+
+ z = x[0];
+ if (!z) z = 1;
+ for (n=0; !(z & 1); z >>= 1)
+ n++;
+
+ frame = max (1, n + 1);
+ if (frame > vxim->nframes) {
+ if (frame < MAX_FRAMES) {
+ set_fbconfig (chan, vxim->fb_configno, frame);
+ if (verbose)
+ fprintf (stderr, "set_fbconfig (%d, %d)\n",
+ vxim->fb_configno, frame);
+ } else {
+ fprintf (stderr, "vximtool warning: ");
+ fprintf (stderr,
+ "attempt to display nonexistent frame %d\n",
+ frame);
+ return;
+ }
+ }
+
+ vxim->display_frame = frame;
+ if (verbose)
+ fprintf (stderr, "set_frame (%d)\n", frame);
+ return;
+ }
+ }
+
+ case MEMORY:
+ /* Load data into the frame buffer. Data is assumed to be byte
+ * packed.
+ */
+ if (iis.tid & IIS_READ) {
+ /* Read from the display.
+ */
+ register FrameBufPtr fb;
+ unsigned char *ip, iobuf[SZ_IOBUF];
+ int nbytes, nleft, n, x, y;
+ long starttime;
+
+ /* Get the frame to be read from. */
+ chan->reference_frame = decode_frameno (iis.z & 07777);
+ fb = &vxim->frames[chan->reference_frame-1];
+
+ nbytes = ndatabytes;
+ x = iis.x & XYMASK;
+ y = iis.y & XYMASK;
+
+ if (x < 0 || x >= vxim->width || y < 0 || y >= vxim->height) {
+ fprintf (stderr,
+ "vximtool: attempted read out of bounds on framebuf\n");
+ fprintf (stderr,
+ "read %d bytes at [%d,%d]\n", nbytes, x, y);
+ memset ((void *)iobuf, 0, nbytes);
+ } else {
+ if (verbose)
+ fprintf (stderr, "read %d bytes at [%d,%d]\n",
+ nbytes, x, y);
+ if (keep_raster)
+ bcopy(&fb->framebuf[(y * vxim->width)+x], iobuf, nbytes);
+ else
+ bzero (iobuf, nbytes);
+ }
+
+ /* Return the data from the frame buffer. */
+ starttime = time(0);
+ for (nleft=nbytes, ip=iobuf; nleft > 0; nleft -= n) {
+ n = (nleft < SZ_FIFOBUF) ? nleft : SZ_FIFOBUF;
+ if ((n = iis_write (dataout, ip, n)) <= 0) {
+ if (n < 0 || (time(0) - starttime > IO_TIMEOUT)) {
+ fprintf (stderr, "IMTOOL: timeout on write\n");
+ break;
+ }
+ } else
+ ip += n;
+ }
+
+ return;
+
+ } else {
+ /* Write to the display.
+ */
+ register FrameBufPtr fb;
+ unsigned char *op, iobuf[SZ_IOBUF];
+ int nbytes, nleft, n, x, y;
+ long starttime;
+
+ /* Get the frame to be written into (encoded with a bit for
+ * each frame, 01 is frame 1, 02 is frame 2, 04 is frame 3,
+ * and so on).
+ */
+ chan->reference_frame = decode_frameno (iis.z & 07777);
+ fb = &vxim->frames[chan->reference_frame-1];
+
+ nbytes = ndatabytes;
+ x = iis.x & XYMASK;
+ y = iis.y & XYMASK;
+
+ /* Read the data into the frame buffer.
+ */
+ starttime = time(0);
+ for (nleft=nbytes, op=iobuf; nleft > 0; nleft -= n) {
+ n = (nleft < SZ_FIFOBUF) ? nleft : SZ_FIFOBUF;
+ if ((n = iis_read (datain, op, n)) <= 0) {
+ if (n < 0 || (time(0) - starttime > IO_TIMEOUT))
+ break;
+ } else
+ op += n;
+ }
+
+ if (x < 0 || x >= vxim->width || y < 0 || y >= vxim->height) {
+ fprintf (stderr,
+ "vximtool: attempted write out of bounds on framebuf\n");
+ fprintf (stderr,
+ "write %d bytes at [%d,%d]\n", nbytes, x, y);
+ bzero ((void *)iobuf, nbytes);
+ } else {
+ if (verbose)
+ fprintf (stderr, "write %d bytes at x=%d, y=%d\n",
+ nbytes, x, y);
+ if (keep_raster)
+ bcopy(iobuf, &fb->framebuf[(y * vxim->width)+x], nbytes);
+ }
+
+ return;
+ }
+ break;
+
+ case WCS:
+ /* Read or write the WCS for a frame. The frame number to
+ * which the WCS applies is passed in Z and the frame buffer
+ * configuration in T. The client changes the frame buffer
+ * configuration in a WCS set. The WCS text follows the header
+ * as byte packed ASCII data.
+ */
+ if (iis.tid & IIS_READ) {
+ /* Return the WCS for the referenced frame.
+ */
+ char emsg[SZ_FNAME];
+ char *text;
+ int frame;
+
+ frame = decode_frameno (iis.z & 07777);
+ chan->reference_frame = frame;
+
+ if (chan->rf_p->frameno <= 0)
+ strcpy (text=emsg, "[NOSUCHFRAME]\n");
+ else
+ text = chan->rf_p->wcsbuf;
+
+ iis_write (dataout, text, SZ_WCSBUF);
+
+ if (verbose) {
+ fprintf (stderr, "query wcs:\n");
+ write (2, text, SZ_WCSBUF);
+ }
+
+ } else {
+ /* Set the WCS for the referenced frame.
+ */
+ register CtranPtr ct;
+ int fb_config, frame;
+
+ frame = decode_frameno (iis.z & 07777);
+ fb_config = (iis.t & 0777) + 1;
+
+ /* See if we need to change the frame buffer configuration,
+ * or allocate a new frame.
+
+ if (fb_config == 1) {
+ if (vxim->fb_config[0].width != vxim->width ||
+ vxim->fb_config[0].height != vxim->height)
+ set_fbconfig (chan, fb_config, frame);
+ } else
+ */
+ if (fb_config != vxim->fb_configno)
+ set_fbconfig (chan, fb_config, frame);
+ else if (frame > vxim->nframes && frame < MAX_FRAMES)
+ set_fbconfig (chan, vxim->fb_configno, frame);
+
+ /* Read in and set up the WCS. */
+ chan->reference_frame = frame;
+ if (iis_read (datain, buf, ndatabytes) == ndatabytes)
+ strncpy (chan->rf_p->wcsbuf, buf, SZ_WCSBUF);
+
+ if (verbose) {
+ fprintf (stderr, "set wcs:\n");
+ write (2, buf, ndatabytes);
+ }
+
+ strcpy (chan->rf_p->ctran.format, W_DEFFORMAT);
+ chan->rf_p->ctran.imtitle[0] = '\0';
+ chan->rf_p->ctran.valid = 0;
+
+ ct = wcs_update (vxim, chan->rf_p);
+ }
+ return;
+
+ case IMCURSOR:
+ /* Read or write the logical image cursor. This is an extension
+ * added to provide a high level cursor read facility; this is
+ * not the same as a low level access to the IIS cursor subunit.
+ * Cursor reads may be either nonblocking (immediate) or blocking,
+ * using the keyboard or mouse to terminate the read, and
+ * coordinates may be returned in either image (world) or frame
+ * buffer pixel coordinates.
+ */
+ if (iis.tid & IIS_READ) {
+ /* Read the logical image cursor. In the case of a blocking
+ * read all we do is initiate a cursor read; completion occurs
+ * when the user hits a key or button.
+ */
+ if (verbose)
+ fprintf (stderr, "read cursor position\n");
+ if (iis.tid & IMC_SAMPLE) {
+ /* Sample the cursor position and return the cursor value
+ * on the output datastream encoded in a fixed size
+ * ascii buffer.
+ */
+ int wcs = iis.z;
+ float sx, sy;
+
+ sx = cursor_x;
+ sy = cursor_y;
+ vx_retCursorVal (chan->dataout, sx, sy, wcs, 0, "");
+
+ } else {
+ /* Initiate a user triggered cursor read. */
+ int frame = chan->reference_frame;
+ char key = 'q';
+ vx_retCursorVal (chan->dataout, 1., 1., 101, key, "");
+ }
+
+ } else {
+ /* Write (set) the logical image cursor position. */
+ register CtranPtr ct;
+ int sx = iis.x, sy = iis.y;
+ float wx = sx, wy = sy;
+ int wcs = iis.z;
+
+ if (verbose)
+ fprintf (stderr, "write cursor position: [%d,%d]\n", sx,sy);
+ if (wcs) {
+ ct = wcs_update (vxim, vxim->df_p);
+ if (ct->valid) {
+ if (abs(ct->a) > .001)
+ sx = (wx - ct->tx) / ct->a;
+ if (abs(ct->d) > .001)
+ sy = (wy - ct->ty) / ct->d;
+ }
+ }
+
+ cursor_x = sx;
+ cursor_y = sy;
+ }
+ return;
+
+ default:
+ /* Ignore unsupported command input.
+ */
+ break;
+ }
+
+ /* Discard any data following the header. */
+ if (!(iis.tid & IIS_READ))
+ for (nbytes = ndatabytes; nbytes > 0; nbytes -= n) {
+ n = (nbytes < SZ_FIFOBUF) ? nbytes : SZ_FIFOBUF;
+ if ((n = iis_read (datain, buf, n)) <= 0)
+ break;
+ }
+}
+
+
+/* SET_FBCONFIG -- Set the frame buffer configuration, or add additional
+ * frames to the current configuration.
+ */
+#ifdef ANSI_FUNC
+
+static void
+set_fbconfig (IoChanPtr chan, int config, int frame)
+#else
+
+static void
+set_fbconfig (chan, config, frame)
+IoChanPtr chan;
+int config;
+int frame;
+#endif
+{
+ register VXimDataPtr vxim = (VXimDataPtr) chan->vxim;
+ register FrameBufPtr fb = &vxim->frames[frame-1];
+ register int i;
+
+ if (config != vxim->fb_configno) {
+ /* Change the frame buffer configuration. */
+ vx_initialize (vxim, config,
+ max (vxim->fb_config[config-1].nframes, frame), 1);
+
+ } else if (frame > vxim->nframes) {
+ /* Add additional frames. */
+ for (i=1; i <= frame; i++) {
+ fb = &vxim->frames[i-1];
+ if (fb->frameno != i)
+ vx_initFrame (vxim, i, frame, &vxim->fb_config[config-1]);
+ }
+ }
+
+ chan->reference_frame = frame;
+}
+
+
+/* DECODE_FRAMENO -- Decode encoded IIS register frame number.
+ */
+#ifdef ANSI_FUNC
+
+static int
+decode_frameno (register int z)
+#else
+
+static int
+decode_frameno (z)
+register int z;
+#endif
+{
+ register int n;
+
+ /* Get the frame number, encoded with a bit for each frame, 01 is
+ * frame 1, 02 is frame 2, 04 is frame 3, and so on.
+ */
+ if (!z) z = 1;
+ for (n=0; !(z & 1); z >>= 1)
+ n++;
+
+ return (max (1, n + 1));
+}
+
+
+/* BSWAP2 - Move bytes from array "a" to array "b", swapping successive
+ * pairs of bytes. The two arrays may be the same but may not be offset
+ * and overlapping.
+ */
+#ifdef ANSI_FUNC
+
+static int
+bswap2 (
+ char *a,
+ char *b, /* input array */
+ int nbytes /* number of bytes to swap */
+)
+#else
+
+static int
+bswap2 (a, b, nbytes)
+char *a, *b; /* input array */
+int nbytes; /* number of bytes to swap */
+#endif
+{
+ register char *ip=a, *op=b, *otop;
+ register unsigned temp;
+
+ /* Swap successive pairs of bytes.
+ */
+ for (otop = op + (nbytes & ~1); op < otop; ) {
+ temp = *ip++;
+ *op++ = *ip++;
+ *op++ = temp;
+ }
+
+ /* If there is an odd byte left, move it to the output array.
+ */
+ if (nbytes & 1)
+ *op = *ip;
+}
+
+
+/* VX_RETCURSORVAL -- Return the cursor value on the output datastream to
+ * the client which requested the cursor read.
+ */
+#ifdef ANSI_FUNC
+
+static void
+vx_retCursorVal (
+ register int dataout,
+ float sx,
+ float sy, /* cursor screen coordinates */
+ int wcs, /* nonzero if WCS coords desired */
+ int key, /* keystroke used as trigger */
+ char *strval /* optional string value */
+)
+#else
+
+static void
+vx_retCursorVal (dataout, sx, sy, wcs, key, strval)
+register int dataout;
+float sx, sy; /* cursor screen coordinates */
+int wcs; /* nonzero if WCS coords desired */
+int key; /* keystroke used as trigger */
+char *strval; /* optional string value */
+#endif
+{
+ char curval[SZ_IMCURVAL];
+ char keystr[20];
+
+ /* If running SERVER in interactive mode, allow the user to type
+ * in the cursor value on the standard input.
+ */
+ if (interactive) {
+ printf ("enter cursor value string (x y wcs key str): ");
+ fflush (stdout);
+ if (fgets (curval, SZ_IMCURVAL, stdin) != NULL)
+ goto ret;
+ }
+
+ /* Encode the cursor value. */
+ if (key == EOF)
+ sprintf (curval, "EOF\n");
+ else {
+ if (isprint (key) && !isspace(key)) {
+ keystr[0] = key;
+ keystr[1] = '\0';
+ } else
+ sprintf (keystr, "\\%03o", key);
+
+ sprintf (curval, "%10.3f %10.3f %d %s %s\n",
+ sx, sy, wcs, keystr, strval);
+ }
+ret:
+ fprintf (stderr, "%s", curval);
+
+ /* Send it to the client program and terminate cursor mode. */
+ write (dataout, curval, sizeof(curval));
+}
+
+
+/* WCS_UPDATE -- Load the screen WCS, if not yet validated, from the user
+ * wcs file, if any.
+ *
+ * File format (two lines):
+ *
+ * image title (imtool header label string)\n
+ * a b c d tx ty z1 z2 zt
+ *
+ * The WCS text is passed in via the data stream as a write to the subunit
+ * WCS and left in the buffer "wcsbuf".
+ */
+#ifdef ANSI_FUNC
+
+static CtranPtr
+wcs_update (register VXimDataPtr vxim, FrameBufPtr fr)
+#else
+
+static CtranPtr
+wcs_update (vxim, fr)
+register VXimDataPtr vxim;
+FrameBufPtr fr;
+#endif
+{
+ register CtranPtr ct = &fr->ctran;
+ char buf[1024], *format;
+
+ /* Get the new WCS. */
+ if (!ct->valid) {
+ fr->label[0] = '\0';
+ ct->zt = W_UNITARY;
+
+ /* Attempt to read the WCS and set up a unitary transformation
+ * if the information cannot be read.
+ */
+ if (sscanf (fr->wcsbuf, "%[^\n]\n%f%f%f%f%f%f%f%f%d",
+ buf, &ct->a, &ct->b, &ct->c, &ct->d, &ct->tx, &ct->ty,
+ &ct->z1, &ct->z2, &ct->zt) < 7) {
+
+ if (fr->wcsbuf[0])
+ fprintf (stderr, "vximtool: error decoding WCS\n");
+
+ strncpy (ct->imtitle, "[NO WCS]\n", SZ_IMTITLE);
+ ct->a = ct->d = 1;
+ ct->b = ct->c = 0;
+ ct->tx = ct->ty = 0;
+ ct->zt = W_UNITARY;
+
+ } else
+ strncpy (ct->imtitle, buf, SZ_IMTITLE);
+
+ ct->valid++;
+ }
+
+ /* Determine best format for wcs output. */
+ if (ct->valid && ct->zt == W_LINEAR) {
+ float z1, z2, zrange;
+ z1 = ct->z1;
+ z2 = ct->z2;
+ zrange = (z1 > z2) ? z1 - z2 : z2 - z1;
+ if (zrange < 100.0 && (abs(z1) + abs(z2)) / 2.0 < 200.0)
+ format = " %7.2f %7.2f %7.3f%c";
+ else if (zrange > 99999.0 || (abs(z1) + abs(z2)) / 2.0 > 99999.0)
+ format = " %7.2f %7.2f %7.3g%c";
+ else
+ format = W_DEFFORMAT;
+ } else
+ format = " %7.2f %7.2f %7.0f%c";
+
+ strcpy (ct->format, format);
+ return (ct);
+}
+
+
+/* VX_INITIALIZE -- Initialize the imaging subsystem. Read the config file
+ * and create the frame buffers, mappings, and colormaps.
+ */
+#ifdef ANSI_FUNC
+
+static void
+vx_initialize (register VXimDataPtr vxim, int config, int nframes, int reset)
+#else
+
+static void
+vx_initialize (vxim, config, nframes, reset)
+register VXimDataPtr vxim;
+int config;
+int nframes;
+int reset;
+#endif
+{
+ if (reset)
+ get_fbconfig (vxim);
+
+ vxim->fb_configno = config;
+ vxim->nframes = vxim->fb_config[config].nframes;
+ vxim->width = vxim->fb_config[config].width;
+ vxim->height = vxim->fb_config[config].height;
+ vx_initFrame (vxim, vxim->display_frame, nframes,
+ &vxim->fb_config[config-1]);
+}
+
+
+/* VX_INITFRAME -- Initialize a frame buffer.
+ */
+#ifdef ANSI_FUNC
+
+static void
+vx_initFrame (register VXimDataPtr vxim, int frame, int nframes, FbConfigPtr config)
+#else
+
+static void
+vx_initFrame (vxim, frame, nframes, config)
+register VXimDataPtr vxim;
+int frame, nframes;
+FbConfigPtr config;
+#endif
+{
+ register FrameBufPtr fb = &vxim->frames[frame-1];
+
+ if (frame < 1 || frame > MAX_FRAMES)
+ return;
+
+ /* Create the frame buffer. */
+ fb->frameno = frame;
+ if (keep_raster) {
+ if (fb->framebuf)
+ free (fb->framebuf);
+ fb->framebuf = (char *) malloc (config->width * config->height);
+ }
+ vxim->width = config->width;
+ vxim->height = config->height;
+ vxim->nframes = nframes;
+}
+
+/* VX_ERASEFRAME -- Erase a frame.
+ */
+#ifdef ANSI_FUNC
+
+static void
+vx_eraseFrame (register VXimDataPtr vxim, int frame)
+#else
+
+static void
+vx_eraseFrame (vxim, frame)
+register VXimDataPtr vxim;
+int frame;
+#endif
+{
+ register FrameBufPtr fb = &vxim->frames[frame-1];
+
+ if (keep_raster)
+ bzero (fb->framebuf, vxim->width * vxim->height);
+}
+
+
+/* GET_FBCONFIG -- Read the XIMTOOL startup file to get the set of possible
+ * frame buffer sizes.
+ *
+ * File format: configno nframes width height [extra fields]
+ * e.g., 1 2 512 512
+ * 2 2 800 800
+ * 3 1 1024 1024 # comment
+ */
+#ifdef ANSI_FUNC
+
+static void
+get_fbconfig (register VXimDataPtr vxim)
+#else
+
+static void
+get_fbconfig (vxim)
+register VXimDataPtr vxim;
+#endif
+{
+ register char *ip;
+ register FILE *fp = NULL;
+ int config, nframes, width, height, i;
+ char lbuf[SZ_LINE+1], *fname;
+
+ /* Initialize the config table. */
+ vxim->fb_configno = 1;
+ for (i=0; i < MAX_FBCONFIG; i++) {
+ vxim->fb_config[i].nframes = 1;
+ vxim->fb_config[i].width = DEF_FRAME_WIDTH;
+ vxim->fb_config[i].height = DEF_FRAME_HEIGHT;
+ }
+
+ /* Attempt to open the config file. */
+ if ((fname=getenv(FBCONFIG_ENV1)) || (fname=getenv(FBCONFIG_ENV2)))
+ fp = fopen (fname, "r");
+ if (!fp && (fname = getenv ("HOME"))) {
+ sprintf (lbuf, "%s/%s", fname, FBCONFIG_1);
+ fp = fopen (fname = lbuf, "r");
+ }
+ if (!fp)
+ fp = fopen (fname = vxim->imtoolrc, "r");
+ if (!fp)
+ return;
+
+ /* Scan the frame buffer configuration file.
+ */
+ lbuf[0] = '\0';
+ while (fgets (lbuf, SZ_LINE, fp) != NULL) {
+ /* Skip comment lines and blank lines. */
+ for (ip=lbuf; *ip == ' ' || *ip == '\t'; ip++)
+ ;
+ if (*ip == '\n' || *ip == '#')
+ continue;
+ if (!isdigit (*ip))
+ continue;
+ switch (sscanf (ip, "%d%d%d%d", &config,&nframes,&width,&height)) {
+ case 4:
+ break; /* normal case */
+ case 3:
+ height = width; /* default to square format */
+ break;
+ default:
+ fprintf (stderr, "vximtool: bad config `%s'\n", ip);
+ continue;
+ }
+
+ nframes = max (1, nframes);
+ width = max (1, width);
+ height = max (1, height);
+
+ /* Since the frame buffer is stored in a memory pixrect
+ * (effectively), the line length should be an integral number
+ * of 16 bit words.
+ */
+ if (width & 1) {
+ fprintf (stderr, "vximtool warning: fb config %d [%d-%dx%d] - ",
+ config, nframes, width, height);
+ fprintf (stderr, "frame width should be even, reset to %d\n",
+ --width);
+ }
+
+ config = max(1, min(MAX_FBCONFIG, config)) - 1;
+ vxim->fb_config[config].nframes = nframes;
+ vxim->fb_config[config].width = width;
+ vxim->fb_config[config].height = height;
+ }
+
+ fclose (fp);
+}
+
+
+
+/* IIS_READ -- Read exactly "n" bytes from a descriptor.
+ */
+
+#ifdef ANSI_FUNC
+static int
+iis_read (int fd, void *vptr, int nbytes)
+
+#else
+static int
+iis_read (fd, vptr, nbytes)
+int fd;
+void *vptr;
+int nbytes;
+#endif
+{
+ char *ptr = vptr;
+ int nread = 0, nleft = nbytes, nb = 0;
+
+ while (nleft > 0) {
+ if ( (nb = read(fd, ptr, nleft)) < 0) {
+ if (errno == EINTR)
+ nb = 0; /* and call read() again */
+ else
+ return(-1);
+ } else if (nb == 0)
+ break; /* EOF */
+ nleft -= nb;
+ ptr += nb;
+ nread += nb;
+ }
+ return (nread); /* return no. of bytes read */
+}
+
+
+/* IIS_WRITE -- Write exactly "n" bytes to a descriptor.
+ */
+#ifdef ANSI_FUNC
+static int
+iis_write (int fd, void *vptr, int nbytes)
+
+#else
+
+static int
+iis_write (fd, vptr, nbytes)
+int fd;
+void *vptr;
+int nbytes;
+#endif
+
+{
+ char *ptr = vptr;
+ int nwritten = 0, nleft = nbytes, nb = 0;
+
+ while (nleft > 0) {
+ if ( (nb = write(fd, ptr, nleft)) <= 0) {
+ if (errno == EINTR)
+ nb = 0; /* and call write() again */
+ else
+ return(-1); /* error */
+ }
+ nleft -= nb;
+ ptr += nb;
+ nwritten += nb;
+ }
+ return (nwritten);
+}
+
+
+/* USAGE -- Print a list of command-line options.
+ */
+#ifdef ANSI_FUNC
+
+static void
+Usage (void)
+#else
+
+static void
+Usage ()
+#endif
+{
+ fprintf (stderr, "Usage:\n\n");
+ printoption (" vximtool");
+ printoption ("[-config <num>]"); /* initial config */
+ printoption ("[-fifo <pipe>]"); /* fifo pipe */
+ printoption ("[-fifo_only]"); /* use fifo only */
+ printoption ("[-help]"); /* Print help */
+ printoption ("[-i]"); /* interactive */
+ printoption ("[-imtoolrc <file>]"); /* fbconfig file */
+ printoption ("[-inet_only | -port_only]"); /* use inet only */
+ printoption ("[-noraster]"); /* don't save pix */
+ printoption ("[-nframes <num>]"); /* # of frames */
+ printoption ("[-port <num>]"); /* inet port */
+ printoption ("[-verbose]"); /* verbose output */
+ printoption ("[-unix <name>]"); /* unix socket */
+ printoption ("[-unix_only]"); /* use unix only */
+ fprintf (stderr,"\n");
+}
+
+
+/* PRINTOPTION -- Pretty-print an option string.
+ */
+static int cpos = 0;
+#ifdef ANSI_FUNC
+
+static void
+printoption (char *st)
+#else
+
+static void
+printoption(st)
+char *st;
+#endif
+{
+ if (strlen(st) + cpos > 78) {
+ fprintf (stderr,"\n\t");
+ cpos = 8;
+ }
+ fprintf (stderr,"%s ",st);
+ cpos = cpos + strlen(st) + 1;
+}
+
+