diff options
author | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-07-08 20:46:52 -0400 |
---|---|---|
committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-07-08 20:46:52 -0400 |
commit | fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch) | |
tree | bdda434976bc09c864f2e4fa6f16ba1952b1e555 /vendor/x11iraf/vximtool | |
download | iraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz |
Initial commit
Diffstat (limited to 'vendor/x11iraf/vximtool')
-rw-r--r-- | vendor/x11iraf/vximtool/Imakefile | 45 | ||||
-rw-r--r-- | vendor/x11iraf/vximtool/vximtool.c | 2147 | ||||
-rw-r--r-- | vendor/x11iraf/vximtool/vximtool.man | 178 | ||||
-rw-r--r-- | vendor/x11iraf/vximtool/vximtool.ps | 1569 | ||||
-rw-r--r-- | vendor/x11iraf/vximtool/vximtool_non_cdl.c | 1728 |
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; +} + + |