#! /bin/sh
#------------------------------------------------
# This is an AIPS self-unpacking shell archive
# XAS source code and other files
#-----------------------------------------------
cat > catalog.c << "--XYZZY--"
#include "xas.h"

int CatInit (chan)
/*--------------------------------------------------------------------*/
/*! Image catalog inside XAS                                          */
/*# TV-IO                                                             */
/*--------------------------------------------------------------------*/
/*;  Copyright (C) 1996-2001, 2008, 2026                              */
/*;  Associated Universities, Inc. Washington DC, USA.                */
/*;  Eric W. Greisen                                                  */
/*;                                                                   */
/*;  This program is free software; you can redistribute it and/or    */
/*;  modify it under the terms of the GNU General Public License as   */
/*;  published by the Free Software Foundation; either version 2 of   */
/*;  the License, or (at your option) any later version.              */
/*;                                                                   */
/*;  This program is distributed in the hope that it will be useful,  */
/*;  but WITHOUT ANY WARRANTY; without even the implied warranty of   */
/*;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    */
/*;  GNU General Public License for more details.                     */
/*;                                                                   */
/*;  You should have received a copy of the GNU General Public        */
/*;  License along with this program; if not, write to the Free       */
/*;  Software Foundation, Inc., 675 Massachusetts Ave, Cambridge,     */
/*;  MA 02139, USA.                                                   */
/*;                                                                   */
/*;  Correspondence concerning AIPS should be addressed as follows:   */
/*;         Internet email: aipsmail@nrao.edu.                        */
/*;         Postal address: AIPS Project Office                       */
/*;                         National Radio Astronomy Observatory      */
/*;                         520 Edgemont Road                         */
/*;                         Charlottesville, VA 22903-2475 USA        */
/*--------------------------------------------------------------------*/
/*   Init the image catalog, one or all planes                        */
/*--------------------------------------------------------------------*/
int chan;
/*--------------------------------------------------------------------*/
{
   register int i, j;
   int  ic, ic1, ic2;

   if ((chan < 0) || (chan > NGRTOT)) {
      fprintf (stderr, "XAS: Illegal init catalog channel %d\n", chan);
      return (-1);
      }

                                          /* grey planes              */
   if (chan <= Ngrey) {
      if (chan == 0) {
         ic1 = 0;
         ic2 = Ngrey - 1;
         }
      else {
         ic1 = chan - 1;
         ic2 = chan - 1;
         }
      for (ic = ic1; ic <= ic2; ic++) {
         lastcat[ic] = 0;
         for (i = 0; i < MAXCAT; i++) {
            for (j = 0; j < 5; j++)
               dircat[ic][i][j] = 0;
            typcat[ic][i][0] = ' ';
            typcat[ic][i][1] = ' ';
            }
         }
      }
                                          /* graphics planes          */
   if ((chan == 0) || (chan > Ngrey)) {
      if (chan == 0) {
         ic1 = 0;
         ic2 = NGRAPH - 1;
         }
      else {
         ic1 = chan - Ngrey - 1;

         ic2 = chan - Ngrey - 1;
         }
      for (ic = ic1; ic <= ic2; ic++) {
         for (j = 0; j < 5; j++)
            dirgcat[ic][j] = 0;
         typgcat[ic][0] = ' ';
         typgcat[ic][1] = ' ';
         }
      }
   return (0);
}

int CatRead ()
/*--------------------------------------------------------------------*/
/*   Find header for TV position                                      */
/*--------------------------------------------------------------------*/
{
   register int i;
   int  chan, ix, iy, nl, ns, nn;

   chan = xbuf.parms[0];
   ix = xbuf.parms[1];
   iy = xbuf.parms[2];

   if ((chan < 1) || (chan > NGRTOT)) {             /* error          */
      fprintf (stderr, "XAS: Bad CatRead channel = %d\n", chan);
      return (-1);
      }

   if (chan > Ngrey) {                              /* graphics       */
      chan = chan - Ngrey - 1;
      if (dirgcat[chan][0] <= 0)
         return (-2);
      else {
         for (i = 0; i < 1024; i++)
             ybuf.u.data[i] = grpcat[chan][i] ;
         return (0);
         }
      }

   chan = chan - 1;                                 /* grey           */
   nl = 0;
   ns = -1;
   for (i = 0; i < MAXCAT; i++) {
      nn = dircat[chan][i][0];
      if (nn > nl) {
         if ((ix >= dircat[chan][i][1]) && (iy >= dircat[chan][i][2])
            && (ix <= dircat[chan][i][3])
            && (iy <= dircat[chan][i][4])) {
            nl = nn;
            ns = i;
            }
         }
      }

   if ((nl <= 0) || (ns < 0))
      return (-2) ;
   else {
      for (i = 0; i < 1024; i++)
         ybuf.u.data[i] = imgcat[chan][ns][i] ;
      return (0) ;
      }
}

int CatWrite ()
/*--------------------------------------------------------------------*/
/*   Update catalog for new window                                    */
/*--------------------------------------------------------------------*/
{
   register int i, j;
   int  chan, xl, xh, yl, yh, nl, ns, done;

   xl = xbuf.parms[0];
   yl = xbuf.parms[1];
   xh = xbuf.parms[2];
   yh = xbuf.parms[3];
   chan = ntohs (xbuf.u.idata[513]) ;

   if ((chan < 1) || (chan > NGRTOT)) {             /* error          */
      fprintf (stderr, "XAS: Bad CatWrite channel = %d\n", chan);
      return (-1);
      }

   if (chan > Ngrey) {                              /* graphics       */
      chan = chan - Ngrey - 1;
      if (XasDebug) fprintf (stderr, "CatWrite graphics %d\n", chan);
      dirgcat[chan][0] = 1;
      dirgcat[chan][1] = xl;
      dirgcat[chan][2] = yl;
      dirgcat[chan][3] = xh;
      dirgcat[chan][4] = yh;
      for (j = 0; j < 1024; j++)
         grpcat[chan][j] = xbuf.u.data[j] ;
      typgcat[chan][0] = xbuf.u.data[1024];
      typgcat[chan][1] = xbuf.u.data[1025];
      return (0);
      }

   chan = chan - 1;                                 /* grey           */
   done = 0;
   if (XasDebug) fprintf (stderr, "CatWrite grey %d\n", chan);
   for (i = 0; i < MAXCAT; i++) {
      if (dircat[chan][i][0] > 0)
         if ((xl <= dircat[chan][i][1]) && (yl <= dircat[chan][i][2])
            && (xh >= dircat[chan][i][3])
            && (yh >= dircat[chan][i][4]))
            dircat[chan][i][0] = 0 ;
      if ((dircat[chan][i][0] <= 0) && (done == 0)) {
         lastcat[chan] = lastcat[chan] + 1;
         if (XasDebug) fprintf (stderr, "CatWrite at %d %d\n", i,
            lastcat[chan]);
         dircat[chan][i][0] = lastcat[chan];
         dircat[chan][i][1] = xl;
         dircat[chan][i][2] = yl;
         dircat[chan][i][3] = xh;
         dircat[chan][i][4] = yh;
         for (j = 0; j < 1024; j++)
            imgcat[chan][i][j] = xbuf.u.data[j];
         typcat[chan][i][0] = xbuf.u.data[1024];
         typcat[chan][i][1] = xbuf.u.data[1025];
         done = 1;
         }
      }

   if (done <= 0)
      return (-2) ;
   else
      return (0) ;

}

int CatOver ()
/*--------------------------------------------------------------------*/
/*   do current channels have overlapping images                      */
/*--------------------------------------------------------------------*/
{
   register int i, j, k;
   int  over, xl, yl, xh, yh, chan;

   over = 0;
   for (k=0; k<Ngrey; k++) {
      chan = k + 1;
      if (active(chan)) {
         for (i = 0; i < MAXCAT; i++) {
            if (dircat[k][i][0] > 0) {
               xl = dircat[k][i][1] ;
               yl = dircat[k][i][2] ;
               xh = dircat[k][i][3] ;
               yh = dircat[k][i][4] ;

               for (j = 0; j < MAXCAT; j++) {
                  if ((dircat[k][j][0] > 0) && (j != i)) {
                     if ((xl >= dircat[k][j][1]) &&
                        (yl >= dircat[k][j][2]) &&
                        (xl <= dircat[k][j][3]) &&
                        (yl <= dircat[k][j][4])) over = over+1;
                     if ((xh >= dircat[k][j][1]) &&
                        (yh >= dircat[k][j][2]) &&
                        (xh <= dircat[k][j][3]) &&
                        (yh <= dircat[k][j][4])) over = over+2;
                     if ((XasDebug) && (over > 0)) {
                        fprintf (stderr,"CatOver %d at %d %d\n",
                           over, i, j);
                        fprintf (stderr,"CatOver i  %d %d %d %d\n",
                           xl, yl, xh, yh);
                        fprintf (stderr,"CatOver j  %d %d %d %d\n",
                           dircat[k][j][1], dircat[k][j][2],
                           dircat[k][j][3], dircat[k][j][4]);
                        }
                     }
                  if (over > 0) break;
                  }
               }
            if (over > 0) break ;
            }
         }
      if (over > 0) break ;
      }
   ybuf.u.data[0] = over;
   ybuf.u.data[1] = over;
   ybuf.u.data[2] = over;
   ybuf.u.data[3] = over;

   return (0) ;

}

int CatFind ()
/*--------------------------------------------------------------------*/
/*   Find header of unique visible image                              */
/*--------------------------------------------------------------------*/
{
   register int i, j;
   int  chan, ic, test, nc, jc, tot, cc, mask, ok, jj;

   chan = xbuf.parms[0];
   test = xbuf.parms[1];

   if ((chan < 1) || (chan > NGRTOT)) {             /* error          */
      fprintf (stderr, "XAS: Bad CatFind channel = %d\n", chan);
      return (-1);
      }

   tot = 0;
   nc = -1;
   jc = -1;
   mask = 1;
   cc = 0;

   for (ic = 0; ic < chan; ic ++) {
      if (ic >= Ngrey) {                           /* graphics        */
         j = ic - Ngrey;
         if (rwgraph & mask) {
            if (dirgcat[j][0] > 0) {
               tot = tot + 1;
               ok = 1;
               if (test > 0)
                  if ((typgcat[j][0] != xbuf.u.data[0]) ||
                     (typgcat[j][1] != xbuf.u.data[1])) ok = 0 ;
               if (ok == 1) {
                  cc = cc + 1;
                  if (cc == 1) nc = ic;
                  if (XasDebug) fprintf (stderr,
                     "CatFind graphics found %d %d\n", ic, cc);
                  }
               }
            }
         mask = mask * 2;
         }
      else {                                      /* grey             */
         jj = ic + 1;
         if (active(jj)) {
            for (j = 0; j < MAXCAT; j ++) {
               if (dircat[ic][j][0] > 0) {
                  tot = tot + 1;
                  ok = 1;
                  if (test > 0)
                     if ((typcat[ic][j][0] != xbuf.u.data[0]) ||
                        (typcat[ic][j][1] != xbuf.u.data[1])) ok = 0 ;
                  if (ok == 1) {
                     cc = cc + 1;
                    if (XasDebug) fprintf (stderr,
                       "CatFind grey %d %d %d\n", ic, j, cc);
                     if (cc == 1) {
                        nc = ic;
                        jc = j;
                        }
                     }
                  }
               }
            }
         }
      }

   if (cc != 1) {
      ybuf.u.data[1024] = 0;
      if (cc == 0) {
         ybuf.u.data[1025] = 1;
         ybuf.u.data[1026] = 1;
         }
      else {
         ybuf.u.data[1025] = 0;
         ybuf.u.data[1026] = 10;
         }
      }
   else {
      ybuf.u.data[1024] = nc + 1;
      ybuf.u.data[1025] = 1;
      if (tot > 1) ybuf.u.data[1025] = 0;
      ybuf.u.data[1026] = 0;
      if (nc < Ngrey) {
         for (i = 0; i < 1024; i++)
            ybuf.u.data[i] = imgcat[nc][jc][i] ;
         }
      else {
         jc = nc - Ngrey;
         for (i = 0; i < 1024; i++)
            ybuf.u.data[i] = grpcat[jc][i] ;
         }
      }

   return (0) ;
}

--XYZZY--
cat > colors.c << "--XYZZY--"
#include "xas.h"

int cmap_wlut()
/*--------------------------------------------------------------------*/
/*! set look-up tables (colormaps) --- XAS version                    */
/*# TV-IO                                                             */
/*--------------------------------------------------------------------*/
/*;  Copyright (C) 1995-2000, 2008, 2016                              */
/*;  Associated Universities, Inc. Washington DC, USA.                */
/*;                                                                   */
/*;  This program is free software; you can redistribute it and/or    */
/*;  modify it under the terms of the GNU General Public License as   */
/*;  published by the Free Software Foundation; either version 2 of   */
/*;  the License, or (at your option) any later version.              */
/*;                                                                   */
/*;  This program is distributed in the hope that it will be useful,  */
/*;  but WITHOUT ANY WARRANTY; without even the implied warranty of   */
/*;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    */
/*;  GNU General Public License for more details.                     */
/*;                                                                   */
/*;  You should have received a copy of the GNU General Public        */
/*;  License along with this program; if not, write to the Free       */
/*;  Software Foundation, Inc., 675 Massachusetts Ave, Cambridge,     */
/*;  MA 02139, USA.                                                   */
/*;                                                                   */
/*;  Correspondence concerning AIPS should be addressed as follows:   */
/*;         Internet email: aipsmail@nrao.edu.                        */
/*;         Postal address: AIPS Project Office                       */
/*;                         National Radio Astronomy Observatory      */
/*;                         520 Edgemont Road                         */
/*;                         Charlottesville, VA 22903-2475 USA        */
/*--------------------------------------------------------------------*/
/*   Write the NColour LookUpTable into memory and to colormap        */
/*--------------------------------------------------------------------*/
{
   register int i, j;
/*--------------------------------------------------------------------*/
   j = xbuf.parms[3] - 1;
   if ((xbuf.parms[3] < 1) || (xbuf.parms[3] > Ngrey)) {
      fprintf (stderr, "XAS: Illegal grey channel %d\n", xbuf.parms[3]);
      return (-1);
      }
   else {
      if (xbuf.parms[0] != 0)
         for (i = 0; i < NColour; ++i)
            rlut[j][i] = ntohs (xbuf.u.idata[i]) ;
      if (xbuf.parms[1] != 0)
         for (i = 0; i < NColour; ++i)
            glut[j][i] = ntohs (xbuf.u.idata[i]) ;
      if (xbuf.parms[2] != 0)
         for (i = 0; i < NColour; ++i)
            blut[j][i] =  ntohs (xbuf.u.idata[i]) ;
      if (using_24b) {
         if (active (xbuf.parms[3])) {
            if (XasDebug)
               fprintf (stderr, "DEBUG scrwrt called from camp_wlut\n");
            scrwrt (0, 0, Screen_Width - 1, Screen_Height - 1);
            }
         return (0);
         }
      else
         return (active (xbuf.parms[3]) ? cmap_change() : 0);
      }
}

int cmap_wlot()
/*--------------------------------------------------------------------*/
/*   Write the 256 old LookUpTable into memory and to colormap        */
/*   old 8-bit version                                                */
/*--------------------------------------------------------------------*/
{
   register int i, j;
/*--------------------------------------------------------------------*/
   j = xbuf.parms[3] - 1;
   if ((xbuf.parms[3] < 1) || (xbuf.parms[3] > Ngrey)) {
      fprintf (stderr, "XAS: Illegal grey channel %d\n", xbuf.parms[3]);
      return (-1);
      }
   else {
      if (xbuf.parms[0] != 0)
         for (i = 0; i < 256; ++i)
            rlut[j][i] = xbuf.u.data[i];
      if (xbuf.parms[1] != 0)
         for (i = 0; i < 256; ++i)
            glut[j][i] = xbuf.u.data[i];
      if (xbuf.parms[2] != 0)
         for (i = 0; i < 256; ++i)
            blut[j][i] =  xbuf.u.data[i];
      if (using_24b) {
         if (active (xbuf.parms[3])) {
            if (XasDebug)
               fprintf (stderr, "DEBUG scrwrt called from camp_wlot\n");
            scrwrt (0, 0, Screen_Width - 1, Screen_Height - 1);
            }
         return (0);
         }
      else
         return (active (xbuf.parms[3]) ? cmap_change() : 0);
      }
}

int cmap_rlut()
/*--------------------------------------------------------------------*/
/*   Read the NColour LookUpTable from memory                         */
/*--------------------------------------------------------------------*/
{
   register int i, j;
/*--------------------------------------------------------------------*/

   j = xbuf.parms[3] - 1;
   if ((j < 0) || (j > Ngrey-1)) {
      fprintf (stderr, "XAS: Illegal grey channel %d\n", j+1);
      return (-1);
      }
   else {
      if (xbuf.parms[0] != 0)
         for (i = 0; i < NColour; ++i)
            ybuf.u.idata[i] = rlut[j][i] ;
      if (xbuf.parms[1] != 0)
         for (i = 0; i < NColour; ++i)
            ybuf.u.idata[i] = glut[j][i];
      if (xbuf.parms[2] != 0)
         for (i = 0; i < NColour; ++i)
            ybuf.u.idata[i] = blut[j][i];
      for (i = 0; i < NColour; ++i)
         ybuf.u.idata[i] = htons (ybuf.u.idata[i]) ;
      return (0);
      }
}

int cmap_rlot()
/*--------------------------------------------------------------------*/
/*   Read the NColour LookUpTable from memory - old = 8-bit           */
/*--------------------------------------------------------------------*/
{
   register int i, j;
/*--------------------------------------------------------------------*/

   j = xbuf.parms[3] - 1;
   if ((j < 0) || (j > Ngrey-1)) {
      fprintf (stderr, "XAS: Illegal grey channel %d\n", j+1);
      return (-1);
      }
   else {
      if (xbuf.parms[0] != 0)
         for (i = 0; i < 256; ++i)
            ybuf.u.data[i] = rlut[j][i];
      if (xbuf.parms[1] != 0)
         for (i = 0; i < 256; ++i)
            ybuf.u.data[i] = glut[j][i];
      if (xbuf.parms[2] != 0)
         for (i = 0; i < 256; ++i)
            ybuf.u.data[i] = blut[j][i];
      return (0);
      }
}

int cmap_wofm()
/*--------------------------------------------------------------------*/
/*   Write the FNINTENS OutputFunction into memory and to colormap    */
/*--------------------------------------------------------------------*/
{
   register int i;
   int nofm;
/*--------------------------------------------------------------------*/
   if (using_24b)
      nofm = (FNINTENS);
   else
      nofm = 256;

   if (xbuf.parms[0] != 0)
      for (i = 0; i < nofm; ++i)
         rofm[i] = xbuf.u.data[i];
   if (xbuf.parms[1] != 0)
      for (i = 0; i < nofm; ++i)
         gofm[i] =  xbuf.u.data[i];
   if (xbuf.parms[2] != 0)
      for (i = 0; i < nofm; ++i)
         bofm[i] =  xbuf.u.data[i];

   if (using_24b) {
      if (XasDebug)
         fprintf (stderr, "DEBUG scrwrt called from camp_wofm\n");
      scrwrt (0, 0, Screen_Width - 1, Screen_Height - 1);
      return (0);
      }
   else
      return (cmap_change());
}

int cmap_wofmo()
/*--------------------------------------------------------------------*/
/*   Write the FNINTENS OutputFunction into memory and to colormap    */
/*   old 1024                                                         */
/*--------------------------------------------------------------------*/
{
   register int i;
   int nofm;
/*--------------------------------------------------------------------*/
   if (using_24b)
      nofm = 1024;
   else
      nofm = 256;

   if (xbuf.parms[0] != 0)
      for (i = 0; i < nofm; ++i)
         rofm[i] = xbuf.u.data[i];
   if (xbuf.parms[1] != 0)
      for (i = 0; i < nofm; ++i)
         gofm[i] =  xbuf.u.data[i];
   if (xbuf.parms[2] != 0)
      for (i = 0; i < nofm; ++i)
         bofm[i] =  xbuf.u.data[i];

   if (using_24b) {
      if (XasDebug)
         fprintf (stderr, "DEBUG scrwrt called from camp_wofm\n");
      scrwrt (0, 0, Screen_Width - 1, Screen_Height - 1);
      return (0);
      }
   else
      return (cmap_change());
}

int cmap_rofm()
/*--------------------------------------------------------------------*/
/*   Read the FNINTENS OutputFunction from memory                     */
/*--------------------------------------------------------------------*/
{
   register int i;
   int nofm;
/*--------------------------------------------------------------------*/
   if (using_24b)
      nofm = (FNINTENS);
   else
      nofm = 256;

   if (xbuf.parms[0] != 0)
      for (i = 0; i < nofm; ++i)
         ybuf.u.data[i] = rofm[i];
   if (xbuf.parms[1] != 0)
      for (i = 0; i < nofm; ++i)
         ybuf.u.data[i] = gofm[i];
   if (xbuf.parms[2] != 0)
      for (i = 0; i < nofm; ++i)
         ybuf.u.data[i] = bofm[i];

   return (0);
}

int cmap_rofmo()
/*--------------------------------------------------------------------*/
/*   Read the FNINTENS OutputFunction from memory - old 1024          */
/*--------------------------------------------------------------------*/
{
   register int i;
   int nofm;
/*--------------------------------------------------------------------*/
   if (using_24b)
      nofm = 1024;
   else
      nofm = 256;

   if (xbuf.parms[0] != 0)
      for (i = 0; i < nofm; ++i)
         ybuf.u.data[i] = rofm[i];
   if (xbuf.parms[1] != 0)
      for (i = 0; i < nofm; ++i)
         ybuf.u.data[i] = gofm[i];
   if (xbuf.parms[2] != 0)
      for (i = 0; i < nofm; ++i)
         ybuf.u.data[i] = bofm[i];

   return (0);
}

int cmap_change()
/*--------------------------------------------------------------------*/
/* Changes the colormap based on the stored LUTs and OFMs in core.    */
/* Adapted from a routine used in  SSS.                               */
/*--------------------------------------------------------------------*/
{
   register int i, ns, j;
/*--------------------------------------------------------------------*/
   j = cur_chan[0] - 1;
                                       /* do the NColor of image 1st  */
   if (cur_chan[0] > 0) {
      for (i = 0; i < NColour; ++i) {
         colour_table[i+OColour].red = rofm[rlut[j][i]] << COLORSHIFT;
         colour_table[i+OColour].green = gofm[glut[j][i]] << COLORSHIFT;
         colour_table[i+OColour].blue = bofm[blut[j][i]] << COLORSHIFT;
         }
      colour_table[OColour].red = colour_table[OColour].blue
        = colour_table[OColour].green = 0;
      }
                                       /* image is off                */
   else {
      for (i = 0; i < NColour; ++i) {
         colour_table[i+OColour].red = colour_table[i+OColour].blue
           = colour_table[i+OColour].green = 0;
         }
      }
/*                                      add in graphics               */
   ns = NColour;
   for (i = NColour; i < NValue; ++i) {
       colour_table[i+OColour].red = rgcol[i-ns] << COLORSHIFT;
       colour_table[i+OColour].green = ggcol[i-ns] << COLORSHIFT;
       colour_table[i+OColour].blue = bgcol[i-ns] << COLORSHIFT ;
       }
   XStoreColors (display, TV_colour, colour_table, NValue+OColour);

   return (0);
}

int cmap_graph()
/*--------------------------------------------------------------------*/
/*   Switch graphics plane(s) on or off.                              */
/*--------------------------------------------------------------------*/
{
   int prevgraph;
/*--------------------------------------------------------------------*/
   if ((xbuf.parms[0] < 1) || (xbuf.parms[0] > NGRAPH)) {
      fprintf (stderr, "XAS: Illegal graphics channel %d\n",
         xbuf.parms[0]);
      return (-1);
      }
   else {
      prevgraph = rwgraph;
      gph_mask = 1;
      if (xbuf.parms[0] == 2) gph_mask = 2;
      if (xbuf.parms[0] == 3) gph_mask = 4;
      if (xbuf.parms[0] == 4) gph_mask = 8;
      if (xbuf.parms[0] == 5) gph_mask = 16;
      if (xbuf.parms[0] == 6) gph_mask = 32;
      if (xbuf.parms[0] == 7) gph_mask = 64;
      if (xbuf.parms[0] == 8) gph_mask = 128;
      if (xbuf.parms[1] > 0)
         rwgraph = rwgraph | gph_mask;
      else
         rwgraph = rwgraph & (~ gph_mask);

      gph_mask = 1 << Ngrey;
      gph_mask = gph_mask - 1;
      params[64] = (params[64] && gph_mask) || (rwgraph << Ngrey) ;
      params[65] = (params[65] && gph_mask) || (rwgraph << Ngrey) ;
      params[66] = (params[66] && gph_mask) || (rwgraph << Ngrey) ;
      params[67] = (params[67] && gph_mask) || (rwgraph << Ngrey) ;

      if (prevgraph != rwgraph) {
         if (XasDebug)
            fprintf (stderr, "DEBUG scrwrt called from camp_graph\n");
         scrwrt (0, 0, Screen_Width - 1, Screen_Height - 1);
         if (using_24b)
            return (0);
         else
            return (cmap_change());
         }
      else
         return (0);
      }
}

int cmap_split()
/*--------------------------------------------------------------------*/
/*   Switch grey channel on or off.                                   */
/*   channel data in 16-bit integers                                  */
/*--------------------------------------------------------------------*/
{
   int redo, mask;
   register int i, j, k ;
/*--------------------------------------------------------------------*/
   redo = 0;
   if (xbuf.parms[0] != x_split) redo = 1;
   if (xbuf.parms[1] != y_split) redo = 1;
   x_split = xbuf.parms[0];
   y_split = xbuf.parms[1];
   params[30] = x_split;
   params[31] = y_split;

   mask = 1;
   Q_same = 1;
   cur_chan[0] = cur_chan[1] = cur_chan[2] = cur_chan[3] = 0;
   for (j = 0; j < 12; j++) xbuf.u.idata[j] = ntohs(xbuf.u.idata[j]);
   if (XasDebug)
      fprintf (stderr, "cmap_split data %d %d %d %d\n",
      xbuf.u.idata[0], xbuf.u.idata[1], xbuf.u.idata[2], xbuf.u.idata[3]);
   for (i=0; i < Ngrey; i++) {
      for (j=0; j < 4; j++) {
         k = mask & xbuf.u.idata[j];
         if (k != on_chan[i][0][j]) redo = 1;
         on_chan[i][0][j] = k;
         if ((cur_chan[j]==0) && (k!=0)) cur_chan[j] = i+1;
         if (on_chan[i][0][j] != on_chan[i][0][0]) Q_same = 0;
         k = mask & xbuf.u.idata[j+4];
         if (k != on_chan[i][1][j]) redo = 1;
         on_chan[i][1][j] = k;
         if ((cur_chan[j]==0) && (k!=0)) cur_chan[j] = i+1;
         if (on_chan[i][1][j] != on_chan[i][1][0]) Q_same = 0;
         k = mask & xbuf.u.idata[j+8];
         if (k != on_chan[i][2][j]) redo = 1;
         on_chan[i][2][j] = k;
         if ((cur_chan[j]==0) && (k!=0)) cur_chan[j] = i+1;
         if (on_chan[i][2][j] != on_chan[i][2][0]) Q_same = 0;
         }
      mask = 2 * mask;
      }
   if (using_24b) {                               /* true color    */
      if (redo) {
         if (XasDebug)
            fprintf (stderr, "DEBUG scrwrt called from camp_split\n");
         scrwrt (0, 0, Screen_Width - 1, Screen_Height - 1);
         }
      for (j = 0; j < 4; j++)                     /* TVLIMG */
         params[64+j] = xbuf.u.idata[j] || xbuf.u.idata[j+4] ||
            xbuf.u.idata[j+8] || (rwgraph << Ngrey) ;
      return (0) ;
      }
   else {                                         /* pseudo color  */
      if ((xbuf.parms[2] < 0) || (xbuf.parms[2] > Ngrey)) {
         fprintf (stderr, "XAS: Illegal grey channel %d\n",
            xbuf.parms[2]);
         return (-1);
         }
      else {
         params[64] = (1 << (cur_chan[0] -1)) ||  (rwgraph << Ngrey) ;
         params[65] = (1 << (cur_chan[1] -1)) ||  (rwgraph << Ngrey) ;
         params[66] = (1 << (cur_chan[2] -1)) ||  (rwgraph << Ngrey) ;
         params[67] = (1 << (cur_chan[3] -1)) ||  (rwgraph << Ngrey) ;
         if (redo) {
            if (XasDebug) fprintf (stderr,
               "DEBUG scrwrt called from cmap_split\n");
            scrwrt (0, 0, Screen_Width - 1, Screen_Height - 1);
            return (cmap_change());
            }
         else
            return (0);
         }
      }
}

int cmap_splat()
/*--------------------------------------------------------------------*/
/*   Switch grey channel on or off - made old in 02/08                */
/*      data in 8-bit integers - limit 8 channels                     */
/*--------------------------------------------------------------------*/
{
   int redo, mask;
   register int i, j, k ;
/*--------------------------------------------------------------------*/
   redo = 0;
   if (xbuf.parms[0] != x_split) redo = 1;
   if (xbuf.parms[1] != y_split) redo = 1;
   x_split = xbuf.parms[0];
   y_split = xbuf.parms[1];
   params[30] = x_split;
   params[31] = y_split;

   mask = 1;
   Q_same = 1;
   cur_chan[0] = cur_chan[1] = cur_chan[2] = cur_chan[3] = 0;
   if (XasDebug) fprintf (stderr, "camp_splat data %d\n",xbuf.u.data[0]);
   for (i=0; i < Ngrey; i++) {
      for (j=0; j < 4; j++) {
         k = mask & xbuf.u.data[j];
         if (k != on_chan[i][0][j]) redo = 1;
         on_chan[i][0][j] = k;
         if ((cur_chan[j]==0) && (k!=0)) cur_chan[j] = i+1;
         if (on_chan[i][0][j] != on_chan[i][0][0]) Q_same = 0;
         k = mask & xbuf.u.data[j+4];
         if (k != on_chan[i][1][j]) redo = 1;
         on_chan[i][1][j] = k;
         if ((cur_chan[j]==0) && (k!=0)) cur_chan[j] = i+1;
         if (on_chan[i][1][j] != on_chan[i][1][0]) Q_same = 0;
         k = mask & xbuf.u.data[j+8];
         if (k != on_chan[i][2][j]) redo = 1;
         on_chan[i][2][j] = k;
         if ((cur_chan[j]==0) && (k!=0)) cur_chan[j] = i+1;
         if (on_chan[i][2][j] != on_chan[i][2][0]) Q_same = 0;
         }
      mask = 2 * mask;
      }
   if (using_24b) {                               /* true color    */
      if (redo) {
         if (XasDebug)
            fprintf (stderr, "DEBUG scrwrt called from camp_split\n");
         scrwrt (0, 0, Screen_Width - 1, Screen_Height - 1);
         }
      for (j = 0; j < 4; j++)                     /* TVLIMG */
         params[64+j] = xbuf.u.data[j] || xbuf.u.data[j+4] ||
            xbuf.u.data[j+8] || (rwgraph << Ngrey) ;
      return (0) ;
      }
   else {                                         /* pseudo color  */
      if ((xbuf.parms[2] < 0) || (xbuf.parms[2] > Ngrey)) {
         fprintf (stderr, "XAS: Illegal grey channel %d\n",
            xbuf.parms[2]);
         return (-1);
         }
      else {
         params[64] = (1 << (cur_chan[0] -1)) ||  (rwgraph << Ngrey) ;
         params[65] = (1 << (cur_chan[1] -1)) ||  (rwgraph << Ngrey) ;
         params[66] = (1 << (cur_chan[2] -1)) ||  (rwgraph << Ngrey) ;
         params[67] = (1 << (cur_chan[3] -1)) ||  (rwgraph << Ngrey) ;
         if (redo) {
            if (XasDebug) fprintf (stderr,
               "DEBUG scrwrt called from cmap_splat\n");
            scrwrt (0, 0, Screen_Width - 1, Screen_Height - 1);
            return (cmap_change());
            }
         else
            return (0);
         }
      }
}

int cmap_splot()
/*--------------------------------------------------------------------*/
/*   Switch grey channel on or off: obsolete version                  */
/*--------------------------------------------------------------------*/
{
      int prevchan;
/*--------------------------------------------------------------------*/
      if ((xbuf.parms[0] < 0) || (xbuf.parms[0] > Ngrey)) {
         fprintf (stderr, "XAS: Illegal grey channel %d\n",
            xbuf.parms[0]);
         return (-1);
         }
      else if ((xbuf.parms[1] != xbuf.parms[0]) ||
         (xbuf.parms[2] != xbuf.parms[0]) ||
         (xbuf.parms[3] != xbuf.parms[0])) {
         fprintf (stderr, "XAS: Split not implemented %d %d %d %d\n",
            xbuf.parms[0], xbuf.parms[1], xbuf.parms[2], xbuf.parms[3]);
         return (-1);
         }
      else {
         if (using_24b) fprintf (stderr,
            "XAS: Old split called for 24-bit display\n");
         prevchan = cur_chan[0];
         cur_chan[0] = xbuf.parms[0];
         if (prevchan != cur_chan[0]) {
            scrwrt (0, 0, Screen_Width - 1, Screen_Height - 1);
            return (cmap_change());
            }
         else
            return (0);
         }
}

int active (ch)
/*--------------------------------------------------------------------*/
/*   is channel ch active         .                                   */
/*--------------------------------------------------------------------*/
   int ch;
/*--------------------------------------------------------------------*/
{
   int redo;
   register int i, j;

   redo = 0;
   if (using_24b) {
      for (i=0; i<3; i++)
         for (j=0; j<4; j++)
            redo = redo || on_chan[ch-1][i][j];
      }

   else {
      for (j=0; j<4; j++)
         if (cur_chan[j] == ch) redo = 1;
      }

   return (redo);
}

int cmap_wgrfx()
/*--------------------------------------------------------------------*/
/* Writes the cursor and graphics colour assignment.                  */
/*                                                                    */
/* MRC 90/Feb/15:                                                     */
/*--------------------------------------------------------------------*/
{
   int i;

   if ((xbuf.parms[0] < 0) || (xbuf.parms[0] > NGRAPH)) {
      fprintf (stderr, "XAS: Illegal grafix channel %d\n",
         xbuf.parms[0]);
      return (-1);
      }

   rgrfx[xbuf.parms[0]] = xbuf.parms[1];
   ggrfx[xbuf.parms[0]] = xbuf.parms[2];
   bgrfx[xbuf.parms[0]] = xbuf.parms[3];
                                        /* make cross colors          */
   crscol (rgrfx, rgcol);
   crscol (ggrfx, ggcol);
   crscol (bgrfx, bgcol);
                                        /* make cursor colors         */
   if (xbuf.parms[0] == 0) {
      if (fg_curs.pixel >= 0) {
         bg_curs.red = 0;
         bg_curs.green = 0;
         bg_curs.blue = 0;
         fg_curs.red = (rgcol[19] << COLORSHIFT) + rgcol[19];
         fg_curs.green = (ggcol[19] << COLORSHIFT) + ggcol[19];
         fg_curs.blue = (bgcol[19] << COLORSHIFT) + bgcol[19];
         XRecolorCursor (display, cursor, &fg_curs, &bg_curs);
         }
      return (0);
      }
                                        /* change the screen colors   */
   else
      if (using_24b) {
         if (XasDebug)
            fprintf (stderr, "DEBUG scrwrt called from camp_wgrfx\n");
         scrwrt (0, 0, Screen_Width - 1, Screen_Height - 1);
         return (0);
         }
      else
         return (cmap_change());

}

void crscol (grfx, gcol)
/*--------------------------------------------------------------------*/
/* converts grfx[9] to full set of colors gcol[16] where              */
/* Input:  grfx i[9]   cursor, 8 graphics values for a color          */
/* Output: gcol i[20]  graphics values 1-19, cursor for the color     */
/*--------------------------------------------------------------------*/
   int *grfx, *gcol;
/*--------------------------------------------------------------------*/
{
   *(gcol+0) = *(grfx+1);                /* grph 1-4 w cross colors */
   *(gcol+1) = *(grfx+2);
   *(gcol+2) = *(grfx+1) ^ *(grfx+2);
   *(gcol+3) = *(grfx+3);
   *(gcol+4) = *(grfx+1) ^ *(grfx+3);
   *(gcol+5) = *(grfx+2) ^ *(grfx+3);
   *(gcol+6) = *(grfx+1) ^ *(gcol+5);
   *(gcol+7) = *(grfx+4);
   *(gcol+8) = *(grfx+4) ^ *(gcol+0);
   *(gcol+9) = *(grfx+4) ^ *(gcol+1);
   *(gcol+10) = *(grfx+4) ^ *(gcol+2);
   *(gcol+11) = *(grfx+4) ^ *(gcol+3);
   *(gcol+12) = *(grfx+4) ^ *(gcol+4);
   *(gcol+13) = *(grfx+4) ^ *(gcol+5);
   *(gcol+14) = *(grfx+4) ^ *(gcol+6);

   *(gcol+15) = *(grfx+5);                /* grph 5-8 simple */
   *(gcol+16) = *(grfx+6);
   *(gcol+17) = *(grfx+7);
   *(gcol+18) = *(grfx+8);

   *(gcol+19) = *(grfx+0);                /* cursor */

   return;
}

int cmap_rgrfx()
/*--------------------------------------------------------------------*/
/* Reads the cursor and graphics colour assignment.                   */
/*                                                                    */
/* MRC 90/Feb/15:                                                     */
/*--------------------------------------------------------------------*/
{
   if ((xbuf.parms[0] < 0) || (xbuf.parms[0] > NGRAPH)) {
      fprintf (stderr, "XAS: Illegal grafix channel %d\n",
         xbuf.parms[0]);
      return (-1);
      }

   ybuf.u.data[0] = rgrfx[xbuf.parms[0]];
   ybuf.u.data[1] = ggrfx[xbuf.parms[0]];
   ybuf.u.data[2] = bgrfx[xbuf.parms[0]];

   return (0);
}
--XYZZY--
cat > comm.c << "--XYZZY--"
/*--------------------------------------------------------------------*/
/*! XAS communications package                                        */
/*# TV-IO                                                             */
/*--------------------------------------------------------------------*/
/*;  Copyright (C) 1995-2000, 2002-2003, 2008, 2012, 2024             */
/*;  Associated Universities, Inc. Washington DC, USA.                */
/*;                                                                   */
/*;  This program is free software; you can redistribute it and/or    */
/*;  modify it under the terms of the GNU General Public License as   */
/*;  published by the Free Software Foundation; either version 2 of   */
/*;  the License, or (at your option) any later version.              */
/*;                                                                   */
/*;  This program is distributed in the hope that it will be useful,  */
/*;  but WITHOUT ANY WARRANTY; without even the implied warranty of   */
/*;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    */
/*;  GNU General Public License for more details.                     */
/*;                                                                   */
/*;  You should have received a copy of the GNU General Public        */
/*;  License along with this program; if not, write to the Free       */
/*;  Software Foundation, Inc., 675 Massachusetts Ave, Cambridge,     */
/*;  MA 02139, USA.                                                   */
/*;                                                                   */
/*;  Correspondence concerning AIPS should be addressed as follows:   */
/*;         Internet email: aipsmail@nrao.edu.                        */
/*;         Postal address: AIPS Project Office                       */
/*;                         National Radio Astronomy Observatory      */
/*;                         520 Edgemont Road                         */
/*;                         Charlottesville, VA 22903-2475 USA        */
/*--------------------------------------------------------------------*/

#include "xas.h"

#if __STDC__
   short int swapbytes ( short int a )
#else
   short int swapbytes( a )
   short int a;
#endif
{
    union {
        short int shortint;
        struct {
            unsigned char lo, hi;
        }byte;
    }x;
    x.shortint = a;

    return x.byte.lo << 8 | x.byte.hi;
}

#if BSD

int MakeLink()
/*--------------------------------------------------------------------*/
/* Get a socket and bind it appropriately, if possible.  The          */
/* environmental variable TVDEV is expanded to find the AIPS TV       */
/* assignment which is in turn expanded to a device name. If the      */
/* device name contains a colon then the portion of the name before   */
/* the colon is taken to be a service name and an INET socket is      */
/* created. If the character before the colon is a 'b' then it is     */
/* omitted from the service name and certain opcodes may be buffered. */
/* If no colon is present the device name is taken to be the name of  */
/* a Unix domain socket.                                              */
/* Inet socket service = sssin...; else Unix domain                   */
/*--------------------------------------------------------------------*/
{
   char device[80];                     /* socket device name         */
   char service[16];                    /* INET service name          */
   char *tptr1, *tptr2;
   register int i;
/*--------------------------------------------------------------------*/
                                        /* Check that TVDEV is        */
                                        /* defined and that it        */
                                        /* contains the name of an    */
                                        /* environmental variable.    */
   if (getenv("TVDEV") == NULL) {
      fprintf (stderr, "XAS: MakeLink translate TVDEV once fails\n");
      perror ("MakeLink getenv(\"TVDEV\")");
      return (-1);
      }

   sprintf (device, "%s", getenv(getenv("TVDEV")));
                                               /* TVDEVn is undefined */
   if (strcmp(device, "(NULL)") == 0) {
      perror ("get_socket getenv");
      fprintf (stderr, "XAS: MakeLink translate TVDEV twice fails %s\n",
         device);
      return (-1);
      }
                                        /* INET domain                */
   if (strncmp(device,"sssin",5) == 0) {
      domain_type = INET_DOMAIN;
      tptr1 = device;
      tptr2 = service;
      while (*tptr1 != ':')
         *(tptr2++) = *(tptr1++);
      *tptr2 = '\0';
      if (*(--tptr2) == 'b') {
         buffered = True;
         *tptr2 = '\0';
         }
      else
         buffered = False;
      if ((sp_in = getservbyname (service, "tcp")) == NULL) {
         fprintf (stderr, "XAS: %s is not a service\n", service);
         fprintf (stderr,
              "XAS: Check /etc/services or YP/NIS services map\n");
         return (-1);
         }
      server_in.sin_family = AF_INET;
      server_in.sin_port = sp_in->s_port;
      if ((AipsSocket = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
         perror ("MakeLink: socket (INET)");
         return (-1);
         }
      if (bind(AipsSocket, (struct sockaddr *)&server_in,
         sizeof(server_in)) < 0){
         perror ("MakeLink: bind error (INET)");
         return (-1);
         }
      }
                                                       /* UNIX domain */
   else {
      domain_type = UNIX_DOMAIN;
      buffered = False;
      server_un.sun_family = AF_UNIX;
      if ((AipsSocket = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) {
         perror ("MakeLink: socket (UNIX)");
         return (-1);
         }
                                         /* Otherwise, open socket    */
      unlink (device);                   /* first unlink if it exists */
      strcpy (server_un.sun_path, device);
      if (bind (AipsSocket, (struct sockaddr *)&server_un,
         strlen(server_un.sun_path) + 2) < 0) {
         perror ("MakeLink: bind error (UNIX)");
         return (-1);
         }
      }
    listen (AipsSocket, 5);             /* Queue up to 5 requests     */

                                        /* Set up the opcodes we want */
                                        /* to buffer. Basically all   */
                                        /* the writes.                */
   for (i = 0; i < (NUMOP+1); i++)
      bufferop[i] = False;
   if (buffered) {
      bufferop[INIT]=True;
      bufferop[INITO]=True;
      bufferop[FILL]=True;
      bufferop[CLEAR]=True;
      bufferop[VECT]=True;
      bufferop[PSAVE]=True;
      bufferop[CHARS]=True;
      bufferop[VIEW]=True;
      bufferop[IMWRT]=True;
      bufferop[OIMWRT]=True;
      bufferop[WLUT]=True;
      bufferop[WLOT]=True;
      bufferop[WOFM]=True;
      bufferop[WOFMO]=True;
      bufferop[WCURS]=True;
      bufferop[GRAPH]=True;
      bufferop[SPLOT]=True;
      bufferop[SPLAT]=True;              /* but not SPLIT */
      bufferop[WGRFX]=True;
      bufferop[WZSCR]=True;
      bufferop[CATIN]=True;
      bufferop[CATWR]=True;
      }

   return (0);
} /* end MakeLink */
#endif

#if VMS
int MakeLink()
{
    (aipsname, AIPS_SOCKET);
    (xasname, XAS_SOCKET);
    int status,chan;

    /* create mailbox with logical name  "AipsSocket" */

    status = sys (0, &chan, maxmsg, bufquo, 0, 0, &aipsname);
    if (!(status & SS)) lib(status);

    AipsLink = chan;

    /* create mailbox with logical name  "XasSocket" */

    status = sys (0, &chan, maxmsg, bufquo, 0, 0, &xasname);
    if (!(status & SS)) lib(status);

    XasLink = chan;


   return (0);
} /* end MakeLink */
#endif

#if BSD

int ReadLink (link, in, out)
int link;
XASinput *in;
XASoutput *out;
{
   register int i;
   int bytes_togo, bytes_trans, ldata, lbytes, nbytes, optlen;
   short int lbuf[6];
   unsigned char *buffer;

                                        /* read header                */
   buffer = (unsigned char *) lbuf;
   bytes_togo =  6*size_i2;
   ldata = bytes_togo;
   while (bytes_togo > 0) {
      bytes_trans =  read (link, buffer+(ldata-bytes_togo),
         bytes_togo);
      if (bytes_trans <= 0) {
         out->status = -1;              /* error -> shutdown          */
         return (-1);
         }
      bytes_togo -= bytes_trans;
      }

   out->status = OK;
   in->opcode = ntohs (lbuf[0]);
   in->data_length = ntohs (lbuf[5]);
   for (i = 0; i < NPARMS; i++ )
      in->parms[i] =  ntohs (lbuf[i+1]);

   /* Note: in->data[] is unsigned char and is not swapped */
                                        /* "Variable length" data is  */
                                        /* in bytes, not words.       */
                                        /* Always read an even number */
                                        /* of bytes.                  */
   bytes_togo = in->data_length + (in->data_length)%2;
   ldata = bytes_togo;
   buffer = in->u.data;
                                         /* increase buffer size     */
   nbytes = bytes_togo;
   if ((Z_rcvbuf == Z_rcvini) && (nbytes > Z_rcvini)) {
      optlen = sizeof (Z_rcvbuf);
      Z_rcvbuf = 16400;
      if (setsockopt (link, SOL_SOCKET, SO_RCVBUF,
         (char *) &Z_rcvbuf, optlen) < 0) {
         perror ("XAS ReadLink increase rcvbuf size");
         Z_rcvbuf = Z_rcvini+1;
         }
      else
         if (Z_rcvini > 0) fprintf (stderr,
            "XAS ReadLink increased send buffer size\n");
      }
   while (bytes_togo > 0) {
      lbytes = bytes_togo;
      bytes_trans = read (link, (buffer+(ldata - bytes_togo)), lbytes);
      if (bytes_trans <= 0) {
         fprintf (stderr,
            "XAS: ReadLink read data error - shutdown?\n");
         out->status = -1;
         return (-1);
         }
      bytes_togo -= bytes_trans;
      }

   return (0);
} /* end ReadLink */


int WriteLink (link, in, out)
int link;
XASoutput *out;
XASinput *in;
{
   register int i, j;
   int buflen, lbytes, nbytes, optlen, mbytes;
   static short int packet[32768+2];
   unsigned char *pp;

   pp = (unsigned char *) packet;
   buflen = out->return_data_length;
   if (!bufferop[in->opcode]) {
      packet[0] = htons (out->status);
      packet[1] = htons (out->return_data_length);
      i = 2; j = 0;
      while (j < ((buflen+1)/size_i2))
         packet[i++] = out->u.idata[j++];
      buflen = buflen + 2 * size_i2;
                                         /* increase buffer size     */
      nbytes = buflen;
      if ((Z_sndbuf == Z_sndini) && (nbytes > Z_sndini)) {
         optlen = sizeof (Z_sndbuf);
         Z_sndbuf = 16400;
         if (setsockopt (link, SOL_SOCKET, SO_SNDBUF,
            (char *) &Z_sndbuf, optlen) < 0) {
            perror ("XAS WriteLink increase sndbuf size");
            Z_sndbuf = Z_sndini+1;
            }
         else
            if (Z_sndini > 0) fprintf (stderr,
               "XAS WriteLink increased send buffer size\n");
         }
      for (nbytes = buflen; nbytes > 0; nbytes -= mbytes) {
         lbytes = nbytes;
         mbytes = write (link, pp+(buflen-nbytes), lbytes);
         if (mbytes <= 0) {
            perror ("xas:WriteLink - ");
            out->status = -1;
            return (-1);
            }
         }
      }
   else {
      if (out->status != 0)
         fprintf (stderr, "XAS: Buffered op %d, istat=%d\n", in->opcode,
            out ->status);
      }
   out->status = OK;

   return (0);
} /* end WriteLink */
#endif

#if VMS

void XasAipsReadAST()
{
   if (!(read_status.ioresult & SS))
      fprintf (stderr, "XAS: ReadLink - ");

   if (ybuf.status == OK)  ProcessAipsRequest();

   read_in_progress = 0;

   WriteLink();

}

int ReadLink()
{
   int s;

   if (read_in_progress) return (0);

   read_in_progress = 1;

   s = sys (0, XasLink, IO, &read_status, &XasAipsReadAST,
      0, xbuf.buf, sizeof(xbuf.buf), 0, 0, 0, 0);
   if (!(s & SS)) {
      fprintf (stderr, "XAS: ReadLink - ");
      ybuf.status = -1;
      return (-1);
      }
   ybuf.status = OK;
   if (ByteSwapped) {
      xbuf.opcode = swapbytes (xbuf.opcode);
      xbuf.data_length = swapbytes (xbuf.data_length);
      for (i = 0; i < NPARMS; i++)
         xbuf.parms[i] = swapbytes (xbuf.parms[i]);
     /* Note: xbuf.u.data[] is unsigned char and is not swapped */
      }

   return (0);
} /* end ReadLink */


/* This could be real strange if more than one process tries to   */
/* send commands to this process. This assumes that the "master"  */
/* process is doing IO synchronusly(since it must wait for status)*/
/* Question: should all error checking be done by the AIPS process*/
/*           thus eliminating the need for synchronous IO???      */

void XasAipsWriteAST()
{
   if(!(write_status.ioresult & SS))
        fprintf(stderr,"XAS: WriteLink - ");


   write_in_progress = 0;

   /* Ready to do the next read */
   ReadLink();

   return;
}

int WriteLink()
{
    int s, i, buflen;

    if (write_in_progress)
       return;

   if (!bufferop[xbuf.opcode]) {
      write_in_progress = 1;

      buflen = ybuf.return_data_length;
      if (ByteSwapped) {
         ybuf.status = swapbytes (ybuf.status);
         ybuf.return_data_length = swapbytes (ybuf.return_data_length);

         /* the returned data is of type short int */
         for (i = 0; i < buflen; i++)
            ybuf.u.idata[i] = swapbytes (ybuf.u.idata[i]);
         }

      s = sys (0, AipsLink, IO,
            &write_status, &XasAipsWriteAST, 0, ybuf.status,
            4+2*buflen, 0, 0, 0, 0);
      if (!(s & SS)) fprintf (stderr, "XAS: WriteLink - ");
      }

   return (0);

} /* end WriteLink */
#endif

void closedown()
{
   int status, i;
#ifdef USE_SHM
   if (using_shm) {                      /* clean up SHM */
      if (using_24b) {
         XShmDetach (display, &line_info);
         XDestroyImage (line);
         shmdt (line_info.shmaddr);
         shmctl (line_info.shmid, IPC_RMID, 0);
         }
      else {
         for (i = 0; i < Ngrey; i++) {
            XShmDetach (display, &plane_info[i]);
            XDestroyImage (plane[i]);
            shmdt (plane_info[i].shmaddr);
            shmctl (plane_info[i].shmid, IPC_RMID, 0);
            }
         XShmDetach (display, &graph_info);
         XDestroyImage (graph);
         shmdt (graph_info.shmaddr);
         shmctl (graph_info.shmid, IPC_RMID, 0);
         XShmDetach (display, &line_info);
         XDestroyImage (line);
         shmdt (line_info.shmaddr);
         shmctl (line_info.shmid, IPC_RMID, 0);
         }
      }
#endif

   XFreeGC (display, ImageGC);
   zssslk (1, &i) ;

#if BSD
    if (domain_type == UNIX_DOMAIN)
        if( unlink(server_un.sun_path) < 0) {
            perror ("closedown: unlink");
        }
#endif
   fprintf(stderr, "XAS: Quitting NOW.\n");

#ifndef USE_SHM
   for (i = 0; i < Ngrey; i++ )
       XDestroyImage (plane[i]);
   XDestroyImage (graph);
   XDestroyImage (line);
#endif
   XCloseDisplay (display);

   shutdown(AipsSocket, 0);
   close(AipsSocket);

#if VMS
   status = sys(AipsLink);
   if (!(status & SS)) lib(status);
   status = sys(XasLink);
   if (!(status & SS)) lib(status);
#endif
/*   zssslk (1, &i) ; */
/*   fprintf(stderr, "XAS: Quitting NOW.\n"); */
   exit(1);

   return;
}

void printbufin()
{
    int i, j, limit;

    fprintf (stderr,"parms[]= %4d %4d %4d %4d\n", xbuf.parms[0],
        xbuf.parms[1], xbuf.parms[2], xbuf.parms[3]);
    fprintf (stderr, "data_length= %d\n", xbuf.data_length);
    limit = 16;                                  /* xbuf.data_length; */
    for (i = 0; i < limit; i += 16) {
       for (j = i; (j < i+16) && (j < limit); j++)
          fprintf (stderr, " %4d", xbuf.u.data[j]);
       fprintf (stderr, "\n");
       }

   return;
} /* end printfbuf */

void printbufout()
{
    int i, j, limit;

    fprintf (stderr, "status =  %4d\n", ybuf.status);
    fprintf (stderr, "parms[]= %4d %4d %4d %4d\n", xbuf.parms[0],
        xbuf.parms[1], xbuf.parms[2], xbuf.parms[3]);
    fprintf (stderr, "return_data_length= %d\n",
       ybuf.return_data_length);
    limit = ybuf.return_data_length;
    for (i = 0; i < limit; i += 16) {
       for (j = i; (j < i+16) && (j < limit); j++)
          fprintf (stderr," %4d", ybuf.u.data[j]);
       fprintf (stderr,"\n");
       }

   return;
} /* end printfbuf */

#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netdb.h>

#if __STDC__
   void zssslk (int opt, int *ierr)
#else
   void zssslk (opt, ierr)
   int opt;
   int *ierr;
#endif
/*--------------------------------------------------------------------*/
/*  Assign an i/o channel for TVlock device, send lock/unlock command */
/*  and then deassign the channel.  Uses BSD sockets                  */
/*  Inputs:                                                           */
/*     opt    I     0 unlock, 1, kill TVSERV                          */
/*  Outputs:                                                          */
/*     ierr   I     Error code: 0 => success                          */
/*                     1 => failure                                   */
/*                     2 => invalid device name                       */
/*  SUN - Berkeley 4.2 UNIX version.                                  */
/*--------------------------------------------------------------------*/
{
   char *device, data[3];
   int i, optlen, mbytes, lbytes, fcb[10];
   char *machine_in;
   struct sockaddr_un client;
   struct sockaddr_in client_in;
   struct servent *sp_in;
   struct hostent *hp_in;
/*--------------------------------------------------------------------*/
   *ierr = 0;
   errno = 0;
   data[1] = 'U';
   if (opt == 1) data[1] = 'D';
   data[2] = '\0';
                                        /* Value for TVDEVn/TVLCKn    */
   if ((device = getenv(getenv("TVDEV"))) == NULL) {
      fprintf(stderr, "zssslk: NO SUCH DEVICE = %s\n","TVDEV");
      *ierr = 2;
      goto exit;
      }
                                        /* open socket, INET domain   */
   if (strncmp(device,"sssin",5) == 0) {
      data[0] = *(device+5);
      if (strncmp(device,"sssinb",6) == 0) data[0] = *(device+6);
      if (strncmp(data,":",1) == 0) data[0] = '1';
      if (( machine_in = strchr (device,':')) == NULL) {
         fprintf(stderr,
            "zssslk: NO REMOTE MACHINE SPECIFIED IN %s\n",device);
         *ierr = 2;
         goto exit;
         }
      else
         machine_in++;
                                        /* malformed names go here    */
      if (!isalnum(*machine_in)) {
         fprintf(stderr, "zssslk: MALFORMED NAME = %s\n", machine_in);
         *ierr = 2;
         goto exit;
         }
      if ((sp_in = getservbyname("ssslock","tcp")) == NULL) {
         fprintf(stderr,"zssslk: tcp/ssslock NOT A SERVICE\n");
         *ierr = 2;
         goto exit;
         }
      if (( hp_in = gethostbyname(machine_in)) == NULL) {
         fprintf(stderr,"zssslk: %s: UNKNOWN HOST\n",machine_in);
         *ierr = 2;
         goto exit;
         }
      memset ((char *)&client_in, 0, sizeof(client_in));
      memcpy ((char *)&client_in.sin_addr, hp_in->h_addr,
         hp_in->h_length);
      client_in.sin_family = hp_in->h_addrtype;
      client_in.sin_port = sp_in->s_port;
      if ((fcb[0] = (int)socket(AF_INET, SOCK_STREAM, 0)) < 0) {
         perror("zssslk socket (INET)");
         *ierr = 1;
         goto exit;
         }
      if (connect(fcb[0], (struct sockaddr *) &client_in,
          sizeof(client_in)) < 0){
         perror("zssslk connect (INET)");
         *ierr = 1;
         goto exit;
         }
      }
                                        /* open socket, UNIX domain   */
   else {
      data[0] = '1';
      if ((device = getenv(getenv("TVLOK"))) == NULL) {
         fprintf(stderr, "zssslk: NO SUCH DEVICE = TVLOK\n");
         *ierr = 2;
         goto exit;
         }
      if ((*fcb = (int)socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
	 perror("zssslk socket (UNIX)");
	 *ierr = 1;
         }
      client.sun_family = AF_UNIX;
      strcpy(client.sun_path, device);

      if (connect((*fcb), (struct sockaddr *) &client,
         (sizeof(client.sun_path)+sizeof(client.sun_family))) < 0) {
         perror("zssslk connect (UNIX)");
         *ierr = 1;
         }
      }
                                        /* send data                  */
   lbytes = 2;
   if ((mbytes = write (fcb[0], data, lbytes)) != lbytes) {
      perror("zssslk write data");
      *ierr = 3;
      goto exit;
      }
                                        /* answer                     */
   if ((mbytes = read (fcb[0], data, lbytes)) != lbytes) {
      perror("zssslk read answer");
      *ierr = 3;
      goto exit;
      }
                                        /* system error in FTAB      */
exit:
   close(fcb[0]);

   return;
}


--XYZZY--
cat > cursor.c << "--XYZZY--"
/*--------------------------------------------------------------------*/
/*! XAS cursor handling routines                                      */
/*# TV-IO                                                             */
/*--------------------------------------------------------------------*/
/*;  Copyright (C) 1995-2000                                          */
/*;  Associated Universities, Inc. Washington DC, USA.                */
/*;                                                                   */
/*;  This program is free software; you can redistribute it and/or    */
/*;  modify it under the terms of the GNU General Public License as   */
/*;  published by the Free Software Foundation; either version 2 of   */
/*;  the License, or (at your option) any later version.              */
/*;                                                                   */
/*;  This program is distributed in the hope that it will be useful,  */
/*;  but WITHOUT ANY WARRANTY; without even the implied warranty of   */
/*;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    */
/*;  GNU General Public License for more details.                     */
/*;                                                                   */
/*;  You should have received a copy of the GNU General Public        */
/*;  License along with this program; if not, write to the Free       */
/*;  Software Foundation, Inc., 675 Massachusetts Ave, Cambridge,     */
/*;  MA 02139, USA.                                                   */
/*;                                                                   */
/*;  Correspondence concerning AIPS should be addressed as follows:   */
/*;         Internet email: aipsmail@nrao.edu.                        */
/*;         Postal address: AIPS Project Office                       */
/*;                         National Radio Astronomy Observatory      */
/*;                         520 Edgemont Road                         */
/*;                         Charlottesville, VA 22903-2475 USA        */
/*--------------------------------------------------------------------*/
/*  Description of keys enabled by this module                        */
/*                                                                    */
/*  Key    Alternate(s)          Action                               */
/*  ----------------------------------------------------------------- */
/*  F3     Keypad F1, A, a       AIPS button "A"                      */
/*  F4     Keypad F2, B, b       AIPS button "B"                      */
/*  F5     Keypad F3, C, c       AIPS button "C"                      */
/*  F6     Keypad F4, D, d       AIPS button "D"                      */
/*  F7     F2, Keypad '+'        Toggle screen size (small <-> large) */
/*  F8                           Toggle XAS debug flag                */
/*  F9                           Toggle Xwindow debug flag            */
/*  F20    ESC, Control C        Quit via call to closedown(AipsLink) */
/*                               -- not recommended!                  */
/*--------------------------------------------------------------------*/

#include "xas.h"

void RecordCursor (x, y)
int x, y;
{
                                        /* -> wrt to window           */
   cursor_x = x + sc_centre_x - sc_width2 + 1;
   cursor_y = y + sc_centre_y - sc_height2 + 1;

              /* guard against border crossings with a button pressed */
   if (cursor_x < 0) cursor_x = 0;
   if (cursor_y < 0) cursor_y = 0;
   if (cursor_x > Screen_Width - 1) cursor_x = Screen_Width - 1;
   if (cursor_y > Screen_Height - 1) cursor_y = Screen_Height - 1;

   return;
}

void CheckKey (key, AipsLink)
KeySym key;
int AipsLink;
{
   /* The keys F3, F4, F5 and F6 are the AIPS buttons A, B, C, D */
   switch (key) {
       case XK_F8:                     /* Toggle XAS debug flag */
           XasDebug = !XasDebug;
           fprintf (stderr,"XAS: Debugging toggled with button F8\n");
           break;
       case XK_F9:                     /* Toggle Xwin debug flag */
           XDebug = !XDebug;
           fprintf (stderr,"XAS: Window debugging toggled by F9\n");
           break;
       case XK_KP_F1:                  /* AIPS A button */
       case XK_F3:
       case XK_A:
       case XK_a:
           button_a += 1;
           break;
       case XK_KP_F2:                  /* AIPS B button */
       case XK_F4:
       case XK_B:
       case XK_b:
           button_b += 1;
           break;
       case XK_KP_F3:                  /* AIPS C button */
       case XK_F5:
       case XK_C:
       case XK_c:
           button_c += 1;
           break;
       case XK_KP_F4:                  /* AIPS D button */
       case XK_F6:
       case XK_D:
       case XK_d:
           button_d += 1;
           break;
       case XK_KP_Add:
       case XK_F7:
       case XK_F2:
           (void) resize_pressed();
           break;
       case XK_F20:
       case XK_Escape:
           closedown ();
           break;
       default:
           break;
      }

   return;
}

int GetCursor()
{
   ybuf.u.idata[0] = Aips_x (cursor_x);
   ybuf.u.idata[1] = Aips_y (cursor_y);

   ybuf.u.idata[0] = htons (ybuf.u.idata[0]);
   ybuf.u.idata[1] = htons (ybuf.u.idata[1]);
   return (0);
}

int movecursor()
{
   int xc, yc;

   cursor_x =  Memory_x (xbuf.parms[0]);
   cursor_y =  Memory_y (xbuf.parms[1]);
                                        /* -> wrt to window           */
   xc = cursor_x - sc_centre_x + sc_width2 - 1;
   yc = cursor_y - sc_centre_y + sc_height2 - 1;

                         /* move cursor only if it would be in window */
   if ((xc < sc_width) && (yc < sc_height) && (xc >= 0) && (yc >= 0))
      XWarpPointer (display, win, win, 0, 0, sc_width, sc_height,
         xc, yc);

    return (0);
}

int readbuttons()
{
    ybuf.u.idata[0] =  button_a;
    ybuf.u.idata[1] =  button_b;
    ybuf.u.idata[2] =  button_c;
    ybuf.u.idata[3] =  button_d;

    button_a = button_b = button_c = button_d = 0;

   ybuf.u.idata[0] = htons (ybuf.u.idata[0]);
   ybuf.u.idata[1] = htons (ybuf.u.idata[1]);
   ybuf.u.idata[2] = htons (ybuf.u.idata[2]);
   ybuf.u.idata[3] = htons (ybuf.u.idata[3]);
   return (0);
}

int cursor_button()
{
    int ii;

    ybuf.u.idata[0] = Aips_x (cursor_x);
    ybuf.u.idata[1] = Aips_y (cursor_y);

    ybuf.u.idata[2] =  button_a;
    ybuf.u.idata[3] =  button_b;
    ybuf.u.idata[4] =  button_c;
    ybuf.u.idata[5] =  button_d;

    button_a = button_b = button_c = button_d = 0;
    for (ii = 0; ii < 6; ii++)
       ybuf.u.idata[ii] = htons (ybuf.u.idata[ii]);

    return (0);
}

--XYZZY--
cat > image.c << "--XYZZY--"
/*--------------------------------------------------------------------*/
/*! XAS image handling routines                                       */
/*# TV-IO                                                             */
/*--------------------------------------------------------------------*/
/*;  Copyright (C) 1995-2000, 2002-2003, 2008, 2012, 2015, 2020       */
/*;  Associated Universities, Inc. Washington DC, USA.                */
/*;                                                                   */
/*;  This program is free software; you can redistribute it and/or    */
/*;  modify it under the terms of the GNU General Public License as   */
/*;  published by the Free Software Foundation; either version 2 of   */
/*;  the License, or (at your option) any later version.              */
/*;                                                                   */
/*;  This program is distributed in the hope that it will be useful,  */
/*;  but WITHOUT ANY WARRANTY; without even the implied warranty of   */
/*;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    */
/*;  GNU General Public License for more details.                     */
/*;                                                                   */
/*;  You should have received a copy of the GNU General Public        */
/*;  License along with this program; if not, write to the Free       */
/*;  Software Foundation, Inc., 675 Massachusetts Ave, Cambridge,     */
/*;  MA 02139, USA.                                                   */
/*;                                                                   */
/*;  Correspondence concerning AIPS should be addressed as follows:   */
/*;         Internet email: aipsmail@nrao.edu.                        */
/*;         Postal address: AIPS Project Office                       */
/*;                         National Radio Astronomy Observatory      */
/*;                         520 Edgemont Road                         */
/*;                         Charlottesville, VA 22903-2475 USA        */
/*--------------------------------------------------------------------*/

#include "xas.h"

int imwrt()
/*--------------------------------------------------------------------*/
/* IMWRT Writes an image plane or a graphics plane to the internal xas*/
/* arrays, then displays the array on the screen.                     */
/* used by the aips VERBS TVLOD TVMOVIE                               */
/* Modified to record when data is displayed                          */
/*--------------------------------------------------------------------*/
{
   register int i, npix;
   int xs, ys, iangl, channel, j, k, vv, items_row;
   short int *pd;
   unsigned char *pg;
/*--------------------------------------------------------------------*/
   channel = xbuf.parms[2];
   if ((channel < 1) || (channel > NGRTOT)) {
      fprintf (stderr, "XAS: Bad imwrt channel = %d\n", channel);
      return (-1);
      }
   else {                               /* Else channel OK            */
      TvStatus[channel-1] = 1;          /* record Data put on TV      */
      }                                 /* End if channel number bad  */

   npix = xbuf.data_length / 2;
   iangl = xbuf.parms[3];
   xs =  Memory_x (xbuf.parms[0]);
   ys =  Memory_y (xbuf.parms[1]);

   gph_mask = 0;
   if (channel == Ngrey+1) gph_mask = 1;
   if (channel == Ngrey+2) gph_mask = 2;
   if (channel == Ngrey+3) gph_mask = 4;
   if (channel == Ngrey+4) gph_mask = 8;
   if (channel == Ngrey+5) gph_mask = 16;
   if (channel == Ngrey+6) gph_mask = 32;
   if (channel == Ngrey+7) gph_mask = 64;
   if (channel == Ngrey+8) gph_mask = 128;
   j = channel - 1;

   for (i = 0; i < npix; i++)
       xbuf.u.idata[i] = ntohs (xbuf.u.idata[i]) ;

   if (using_24b) {
      items_row = Screen_Width;
      if (iangl == 0) {
         if (channel <= Ngrey) {        /* If writing Image           */
            pd = plane_data[j] + xs + ys * items_row;
            for (i = 0; i < npix; i++) {
               *pd++ = xbuf.u.idata[i];
               }
            }
         else {                         /* Else writing graph         */
            pg = graph_data + xs + ys * items_row;
            for (i = 0; i < npix; i++) {   /* For all pixels in line  */
               vv = *pg;
               chg_s (vv, xbuf.u.idata[i], gph_mask);
               *pg++ = vv;
               }
            }
                                        /* update if visible          */
         if ((active(channel)) || (rwgraph & gph_mask))
            scrwrt (xs, ys, xs + npix, ys);
         }
      else if (iangl == 1) {
         if (channel <= Ngrey) {
            pd = plane_data[j] + xs + ys * items_row;
            for (i = 0; i < npix; i++) {
               *pd = xbuf.u.idata[i];
               pd -= items_row;
               }
            }
         else {
            pg = graph_data + xs + ys * items_row;
            for (i = 0; i < npix; i++) {
               vv = *pg;
               chg_s (vv, xbuf.u.idata[i], gph_mask);
               *pg = vv;
                pg -= items_row;
               }
            }
         if ((active(channel)) || (rwgraph & gph_mask))
            scrwrt (xs, ys - npix, xs, ys);
         }
      else if (iangl == 2) {
         if (channel <= Ngrey) {
            pd = plane_data[j] + xs + ys * items_row;
            for (i = 0; i < npix; i++) {
               *pd-- = xbuf.u.idata[i];
               }
            }
         else {
            pg = graph_data + xs + ys * items_row;
            for (i = 0; i < npix; i++) {
               vv = *pg;
               chg_s (vv, xbuf.u.idata[i], gph_mask);
               *pg-- = vv;
               }
            }
         if ((active(channel)) || (rwgraph & gph_mask))
           scrwrt (xs - npix, ys, xs, ys);
         }
      else if (iangl == 3) {
         if (channel <= Ngrey) {
            pd = plane_data[j] + xs + ys * items_row;
            for (i = 0; i < npix; i++) {
               *pd = xbuf.u.idata[i];
               pd += items_row;
               }
            }
         else {
            pg = graph_data + xs + ys * items_row;
            for (i = 0; i < npix; i++) {
               vv = *pg;
               chg_s (vv, xbuf.u.idata[i], gph_mask);
               *pg = vv;
               pg += items_row;
               }
            }
         if ((active(channel)) || (rwgraph & gph_mask))
            scrwrt (xs, ys, xs, ys + npix);
         }
      }
   else {
      if (iangl == 0) {
         if (channel <= Ngrey)          /* If writing Image           */
            for (i = 0; i < npix; i++) {
               XPutPixel (plane[j], xs+i, ys, int2pix[xbuf.u.idata[i]]);
               }
         else {                         /* Else writing graph         */
            for (i = 0; i < npix; i++) {   /* For all pixels in line  */
               vv = XGetPixel(graph, xs+i, ys);
               chg_s (vv, xbuf.u.idata[i], gph_mask);
               XPutPixel (graph, xs+i, ys, vv);
               }
            }
                                        /* update if visible          */
         if ((active(channel)) || (rwgraph & gph_mask))
            scrwrt (xs, ys, xs + npix, ys);
         }
      else if (iangl == 1) {
         if (channel <= Ngrey)
            for (i = 0; i < npix; i++) {
               XPutPixel (plane[j], xs, ys-i, int2pix[xbuf.u.idata[i]]);
               }
         else {
            for (i = 0; i < npix; i++) {
               vv = XGetPixel(graph, xs, ys-i);
               chg_s (vv, xbuf.u.idata[i], gph_mask);
               XPutPixel (graph, xs, ys-i, vv);
               }
            }
         if ((active(channel)) || (rwgraph & gph_mask))
            scrwrt (xs, ys - npix, xs, ys);
         }
      else if (iangl == 2) {
         if (channel <= Ngrey)
            for (i = 0; i < npix; i++) {
               XPutPixel (plane[j], xs-i, ys, int2pix[xbuf.u.idata[i]]);
               }
         else {
            for (i = 0; i < npix; i++) {
               vv = XGetPixel(graph, xs-i, ys);
               chg_s (vv, xbuf.u.idata[i], gph_mask);
               XPutPixel (graph, xs-i, ys, vv);
               }
            }
         if ((active(channel)) || (rwgraph & gph_mask))
           scrwrt (xs - npix, ys, xs, ys);
         }
      else if (iangl == 3) {
         if (channel <= Ngrey)
            for (i = 0; i < npix; i++) {
               XPutPixel (plane[j], xs, ys+i, int2pix[xbuf.u.idata[i]]);
               }
         else {
            for (i = 0; i < npix; i++) {
               vv = XGetPixel(graph, xs, ys+i);
               chg_s (vv, xbuf.u.idata[i], gph_mask);
               XPutPixel (graph, xs, ys+i, vv);
               }
            }
         if ((active(channel)) || (rwgraph & gph_mask))
            scrwrt (xs, ys, xs, ys + npix);
         }
      }

    return (0);
} /* end imwrt */

int oimwrt()
/*--------------------------------------------------------------------*/
/* IMWRT Writes an image plane or a graphics plane to the internal xas*/
/* arrays, then displays the array on the screen.                     */
/* used by the aips VERBS TVLOD TVMOVIE                               */
/* Modified to record when data is displayed - old 8 bit              */
/*--------------------------------------------------------------------*/
{
   register int i, npix;
   int xs, ys, iangl, channel, j, k, vv, items_row;
   short int *pd;
   unsigned char *pg;
/*--------------------------------------------------------------------*/
   channel = xbuf.parms[2];
   if ((channel < 1) || (channel > NGRTOT)) {
      fprintf (stderr, "XAS: Bad imwrt channel = %d\n", channel);
      return (-1);
      }
   else {                               /* Else channel OK            */
      TvStatus[channel-1] = 1;          /* record Data put on TV      */
      }                                 /* End if channel number bad  */

   npix = xbuf.data_length;
   iangl = xbuf.parms[3];
   xs =  Memory_x (xbuf.parms[0]);
   ys =  Memory_y (xbuf.parms[1]);

   gph_mask = 0;
   if (channel == Ngrey+1) gph_mask = 1;
   if (channel == Ngrey+2) gph_mask = 2;
   if (channel == Ngrey+3) gph_mask = 4;
   if (channel == Ngrey+4) gph_mask = 8;
   if (channel == Ngrey+5) gph_mask = 16;
   if (channel == Ngrey+6) gph_mask = 32;
   if (channel == Ngrey+7) gph_mask = 64;
   if (channel == Ngrey+8) gph_mask = 128;
   j = channel - 1;

   if (using_24b) {
      items_row = Screen_Width;
      if (iangl == 0) {
         if (channel <= Ngrey) {        /* If writing Image           */
            pd = plane_data[j] + xs + ys * items_row;
            for (i = 0; i < npix; i++) {
               *pd++ = xbuf.u.data[i];
               }
            }
         else {                         /* Else writing graph         */
            pg = graph_data + xs + ys * items_row;
            for (i = 0; i < npix; i++) {   /* For all pixels in line  */
               vv = *pg;
               chg_s (vv, xbuf.u.data[i], gph_mask);
               *pg++ = vv;
               }
            }
                                        /* update if visible          */
         if ((active(channel)) || (rwgraph & gph_mask))
            scrwrt (xs, ys, xs + npix, ys);
         }
      else if (iangl == 1) {
         if (channel <= Ngrey) {
            pd = plane_data[j] + xs + ys * items_row;
            for (i = 0; i < npix; i++) {
               *pd = xbuf.u.data[i];
               pd -= items_row;
               }
            }
         else {
            pg = graph_data + xs + ys * items_row;
            for (i = 0; i < npix; i++) {
               vv = *pg;
               chg_s (vv, xbuf.u.data[i], gph_mask);
               *pg = vv;
                pg -= items_row;
               }
            }
         if ((active(channel)) || (rwgraph & gph_mask))
            scrwrt (xs, ys - npix, xs, ys);
         }
      else if (iangl == 2) {
         if (channel <= Ngrey) {
            pd = plane_data[j] + xs + ys * items_row;
            for (i = 0; i < npix; i++) {
               *pd-- = xbuf.u.data[i];
               }
            }
         else {
            pg = graph_data + xs + ys * items_row;
            for (i = 0; i < npix; i++) {
               vv = *pg;
               chg_s (vv, xbuf.u.data[i], gph_mask);
               *pg-- = vv;
               }
            }
         if ((active(channel)) || (rwgraph & gph_mask))
           scrwrt (xs - npix, ys, xs, ys);
         }
      else if (iangl == 3) {
         if (channel <= Ngrey) {
            pd = plane_data[j] + xs + ys * items_row;
            for (i = 0; i < npix; i++) {
               *pd = xbuf.u.data[i];
               pd += items_row;
               }
            }
         else {
            pg = graph_data + xs + ys * items_row;
            for (i = 0; i < npix; i++) {
               vv = *pg;
               chg_s (vv, xbuf.u.data[i], gph_mask);
               *pg = vv;
               pg += items_row;
               }
            }
         if ((active(channel)) || (rwgraph & gph_mask))
            scrwrt (xs, ys, xs, ys + npix);
         }
      }
   else {
      if (iangl == 0) {
         if (channel <= Ngrey)          /* If writing Image           */
            for (i = 0; i < npix; i++) {
               XPutPixel (plane[j], xs+i, ys, int2pix[xbuf.u.data[i]]);
               }
         else {                         /* Else writing graph         */
            for (i = 0; i < npix; i++) {   /* For all pixels in line  */
               vv = XGetPixel(graph, xs+i, ys);
               chg_s (vv, xbuf.u.data[i], gph_mask);
               XPutPixel (graph, xs+i, ys, vv);
               }
            }
                                        /* update if visible          */
         if ((active(channel)) || (rwgraph & gph_mask))
            scrwrt (xs, ys, xs + npix, ys);
         }
      else if (iangl == 1) {
         if (channel <= Ngrey)
            for (i = 0; i < npix; i++) {
               XPutPixel (plane[j], xs, ys-i, int2pix[xbuf.u.data[i]]);
               }
         else {
            for (i = 0; i < npix; i++) {
               vv = XGetPixel(graph, xs, ys-i);
               chg_s (vv, xbuf.u.data[i], gph_mask);
               XPutPixel (graph, xs, ys-i, vv);
               }
            }
         if ((active(channel)) || (rwgraph & gph_mask))
            scrwrt (xs, ys - npix, xs, ys);
         }
      else if (iangl == 2) {
         if (channel <= Ngrey)
            for (i = 0; i < npix; i++) {
               XPutPixel (plane[j], xs-i, ys, int2pix[xbuf.u.data[i]]);
               }
         else {
            for (i = 0; i < npix; i++) {
               vv = XGetPixel(graph, xs-i, ys);
               chg_s (vv, xbuf.u.data[i], gph_mask);
               XPutPixel (graph, xs-i, ys, vv);
               }
            }
         if ((active(channel)) || (rwgraph & gph_mask))
           scrwrt (xs - npix, ys, xs, ys);
         }
      else if (iangl == 3) {
         if (channel <= Ngrey)
            for (i = 0; i < npix; i++) {
               XPutPixel (plane[j], xs, ys+i, int2pix[xbuf.u.data[i]]);
               }
         else {
            for (i = 0; i < npix; i++) {
               vv = XGetPixel(graph, xs, ys+i);
               chg_s (vv, xbuf.u.data[i], gph_mask);
               XPutPixel (graph, xs, ys+i, vv);
               }
            }
         if ((active(channel)) || (rwgraph & gph_mask))
            scrwrt (xs, ys, xs, ys + npix);
         }
      }

    return (0);
} /* end oimwrt */

int imrd (nwpix)
/*--------------------------------------------------------------------*/
/* This subroutine returns an image line to the client.               */
/*--------------------------------------------------------------------*/
short int *nwpix;
/*--------------------------------------------------------------------*/
{
   int xs, ys, iangl, channel, j, vv;
   short int jj;
   register int i, npix;
   short int *pd;
   unsigned char *pg;
/*--------------------------------------------------------------------*/
   xs = Memory_x (xbuf.parms[0]);
   ys = Memory_y (xbuf.parms[1]);
   channel = xbuf.parms[2];
   iangl = xbuf.parms[3];
                                        /* special I*2 word in buffer */
   jj = xbuf.u.idata[0];
   npix =  ntohs (jj);
   *nwpix = 2 * npix;

   if ((channel < 1) || (channel > NGRTOT)) {
      fprintf (stderr, "XAS: Bad imrd channel = %d\n", channel);
      return (-1);
      }

   gph_mask = 0;
   if (channel == Ngrey+1) gph_mask = 1;
   if (channel == Ngrey+2) gph_mask = 2;
   if (channel == Ngrey+3) gph_mask = 4;
   if (channel == Ngrey+4) gph_mask = 8;
   if (channel == Ngrey+5) gph_mask = 16;
   if (channel == Ngrey+6) gph_mask = 32;
   if (channel == Ngrey+7) gph_mask = 64;
   if (channel == Ngrey+8) gph_mask = 128;
   j = channel - 1;

   if (using_24b) {
      if (iangl == 0) {
         if (channel <= Ngrey) {
            pd = plane_data[j] + xs + ys * Screen_Width;
            for (i = 0; i < npix; i++)
               ybuf.u.idata[i] = *pd++;
            }
         else {
            pg = graph_data + xs + ys * Screen_Width;
            for (i = 0; i < npix; i++)
               ybuf.u.idata[i] = chg_g (*pg++, gph_mask);
            }
         }
      else if (iangl == 1) {
         if (channel <= Ngrey) {
            pd = plane_data[j] + xs + ys * Screen_Width;
            for (i = 0; i < npix; i++) {
               ybuf.u.idata[i] = *pd;
               pd -= Screen_Width;
               }
            }
         else {
            pg = graph_data + xs + ys * Screen_Width;
            for (i = 0; i < npix; i++) {
               ybuf.u.idata[i] = chg_g (*pg, gph_mask);
               pg -= Screen_Width;
               }
            }
         }
      if (iangl == 2) {
         if (channel <= Ngrey) {
            pd = plane_data[j] + xs + ys * Screen_Width;
            for (i = 0; i < npix; i++)
               ybuf.u.idata[i] = *pd--;
            }
         else {
            pg = graph_data + xs + ys * Screen_Width;
            for (i = 0; i < npix; i++)
               ybuf.u.idata[i] = chg_g (*pg--, gph_mask);
            }
         }
      else if (iangl == 3) {
         if (channel <= Ngrey) {
            pd = plane_data[j] + xs + ys * Screen_Width;
            for (i = 0; i < npix; i++) {
               ybuf.u.idata[i] = *pd;
               pd += Screen_Width;
               }
            }
         else {
            pg = graph_data + xs + ys * Screen_Width;
            for (i = 0; i < npix; i++) {
               ybuf.u.idata[i] = chg_g (*pg, gph_mask);
               pg += Screen_Width;
               }
            }
         }
      }
   else {
      if (iangl == 0) {
         if (channel <= Ngrey)
            for (i = 0; i < npix; i++) {
               ybuf.u.idata[i] = pix2int[XGetPixel (plane[j], xs+i, ys)];
               }
         else
            for (i = 0; i < npix; i++) {
               ybuf.u.idata[i] = chg_g (XGetPixel (graph, xs+i, ys),
                  gph_mask);
               }
         }
      else if (iangl == 1) {
         if (channel <= Ngrey)
            for (i = 0; i < npix; i++) {
               ybuf.u.idata[i] = pix2int[XGetPixel (plane[j], xs, ys-i)];
               }
         else
            for (i = 0; i < npix; i++) {
               ybuf.u.idata[i] = chg_g (XGetPixel (graph, xs, ys-i),
                  gph_mask);
               }
         }
      if (iangl == 2) {
         if (channel <= Ngrey)
            for (i = 0; i < npix; i++) {
               ybuf.u.idata[i] = pix2int[XGetPixel (plane[j], xs-i, ys)];
               }
         else
            for (i = 0; i < npix; i++) {
               ybuf.u.idata[i] = chg_g (XGetPixel (graph, xs-i, ys),
                  gph_mask);
               }
         }
      else if (iangl == 3) {
         if (channel <= Ngrey)
            for (i = 0; i < npix; i++) {
               ybuf.u.idata[i] = pix2int[XGetPixel (plane[j], xs, ys+i)];
               }
         else
            for (i = 0; i < npix; i++) {
               ybuf.u.idata[i] = chg_g (XGetPixel (graph, xs, ys+i),
                  gph_mask);
               }
         }
      }

   for (i = 0; i < npix; i++)
      ybuf.u.idata[i] = htons (ybuf.u.idata[i]);

   return (0);
}

int oimrd (nwpix)
/*--------------------------------------------------------------------*/
/* This subroutine returns an image line to the client 8 bit data     */
/*--------------------------------------------------------------------*/
short int *nwpix;
/*--------------------------------------------------------------------*/
{
   int xs, ys, iangl, channel, j, vv;
   short int jj;
   register int i, npix;
   short int *pd;
   unsigned char *pg;
/*--------------------------------------------------------------------*/
   xs = Memory_x (xbuf.parms[0]);
   ys = Memory_y (xbuf.parms[1]);
   channel = xbuf.parms[2];
   iangl = xbuf.parms[3];
                                        /* special I*2 word in buffer */
   jj = xbuf.u.idata[0];
   npix =  ntohs (jj);
   *nwpix = npix;

   if ((channel < 1) || (channel > NGRTOT)) {
      fprintf (stderr, "XAS: Bad imrd channel = %d\n", channel);
      return (-1);
      }

   gph_mask = 0;
   if (channel == Ngrey+1) gph_mask = 1;
   if (channel == Ngrey+2) gph_mask = 2;
   if (channel == Ngrey+3) gph_mask = 4;
   if (channel == Ngrey+4) gph_mask = 8;
   if (channel == Ngrey+5) gph_mask = 16;
   if (channel == Ngrey+6) gph_mask = 32;
   if (channel == Ngrey+7) gph_mask = 64;
   if (channel == Ngrey+8) gph_mask = 128;
   j = channel - 1;

   if (using_24b) {
      if (iangl == 0) {
         if (channel <= Ngrey) {
            pd = plane_data[j] + xs + ys * Screen_Width;
            for (i = 0; i < npix; i++)
               ybuf.u.data[i] = *pd++;
            }
         else {
            pg = graph_data + xs + ys * Screen_Width;
            for (i = 0; i < npix; i++)
               ybuf.u.data[i] = chg_g (*pg++, gph_mask);
            }
         }
      else if (iangl == 1) {
         if (channel <= Ngrey) {
            pd = plane_data[j] + xs + ys * Screen_Width;
            for (i = 0; i < npix; i++) {
               ybuf.u.data[i] = *pd;
               pd -= Screen_Width;
               }
            }
         else {
            pg = graph_data + xs + ys * Screen_Width;
            for (i = 0; i < npix; i++) {
               ybuf.u.data[i] = chg_g (*pg, gph_mask);
               pg -= Screen_Width;
               }
            }
         }
      if (iangl == 2) {
         if (channel <= Ngrey) {
            pd = plane_data[j] + xs + ys * Screen_Width;
            for (i = 0; i < npix; i++)
               ybuf.u.data[i] = *pd--;
            }
         else {
            pg = graph_data + xs + ys * Screen_Width;
            for (i = 0; i < npix; i++)
               ybuf.u.data[i] = chg_g (*pg--, gph_mask);
            }
         }
      else if (iangl == 3) {
         if (channel <= Ngrey) {
            pd = plane_data[j] + xs + ys * Screen_Width;
            for (i = 0; i < npix; i++) {
               ybuf.u.data[i] = *pd;
               pd += Screen_Width;
               }
            }
         else {
            pg = graph_data + xs + ys * Screen_Width;
            for (i = 0; i < npix; i++) {
               ybuf.u.data[i] = chg_g (*pg, gph_mask);
               pg += Screen_Width;
               }
            }
         }
      }
   else {
      if (iangl == 0) {
         if (channel <= Ngrey)
            for (i = 0; i < npix; i++) {
               ybuf.u.data[i] = pix2int[XGetPixel (plane[j], xs+i, ys)];
               }
         else
            for (i = 0; i < npix; i++) {
               ybuf.u.data[i] = chg_g (XGetPixel (graph, xs+i, ys),
                  gph_mask);
               }
         }
      else if (iangl == 1) {
         if (channel <= Ngrey)
            for (i = 0; i < npix; i++) {
               ybuf.u.data[i] = pix2int[XGetPixel (plane[j], xs, ys-i)];
               }
         else
            for (i = 0; i < npix; i++) {
               ybuf.u.data[i] = chg_g (XGetPixel (graph, xs, ys-i),
                  gph_mask);
               }
         }
      if (iangl == 2) {
         if (channel <= Ngrey)
            for (i = 0; i < npix; i++) {
               ybuf.u.data[i] = pix2int[XGetPixel (plane[j], xs-i, ys)];
               }
         else
            for (i = 0; i < npix; i++) {
               ybuf.u.data[i] = chg_g (XGetPixel (graph, xs-i, ys),
                  gph_mask);
               }
         }
      else if (iangl == 3) {
         if (channel <= Ngrey)
            for (i = 0; i < npix; i++) {
               ybuf.u.data[i] = pix2int[XGetPixel (plane[j], xs, ys+i)];
               }
         else
            for (i = 0; i < npix; i++) {
               ybuf.u.data[i] = chg_g (XGetPixel (graph, xs, ys+i),
                  gph_mask);
               }
         }
      }

   return (0);
}

void resize_canvas (width, height, ix0, iy0)
/*--------------------------------------------------------------------*/
/* checks canvas size and position                                    */
/*--------------------------------------------------------------------*/
   int width, height, ix0, iy0;
/*--------------------------------------------------------------------*/
{
   int icx, icy, itx, ity;

   icx = ix0;
   icy = iy0;
   itx = width;
   ity = height;
                                        /* set widths                 */
   sc_width = min (itx, Screen_Width);
   sc_height = min (ity, Screen_Height);
   sc_width2 = sc_width / 2;
   sc_height2 = sc_height / 2;
                                        /* check frame coords         */
   itx = sc_width;
   ity = sc_height;
   icx += bwid;
   icy += bwid;
   icx = max (icx, SCREEN_LEFT);
   icy = max (icy, SCREEN_TOP);
   icx = min (icx, twidth - SCREEN_RIGHT - itx) - bwid;
   icy = min (icy, theight - SCREEN_BOTTOM - ity) - bwid;
                                        /* resize, bring into view    */
   if (/*(ix0 != icx) || (iy0 != icy) ||*/ (width != itx) ||
      (height != ity)) {
      Cur_Xsize = itx;
      Cur_Ysize = ity;
      XResizeWindow (display, win, itx, ity);
      if (XasDebug) fprintf (stderr,
         "force resize_canvas: W H %d %d\n", itx, ity);
/*    Cur_Xzero = icx;
      Cur_Yzero = icy; */
      }

   return;
} /* end resize_canvas */

void resize_pressed()
/*--------------------------------------------------------------------*/
/* Toggle between full screen and smaller window set by the window    */
/* manager.                                                           */
/*--------------------------------------------------------------------*/
{
   int itx, ity, icx, icy;

   big_screen = !big_screen;
   if (big_screen) {
      cur_xcorn = Cur_Xzero + bwid;
      cur_ycorn = Cur_Yzero + bwid;
      cur_xsize = Cur_Xsize;
      cur_ysize = Cur_Ysize;
      itx = Screen_Width;
      ity = Screen_Height;
      icx = 0;
      icy = 0;
      }
   else {
      itx = cur_xsize;
      ity = cur_ysize;
      icx = cur_xcorn;
      icy = cur_ycorn;
      }
   icx = max (icx, SCREEN_LEFT);
   icy = max (icy, SCREEN_TOP);
   icx = min (icx, twidth - SCREEN_RIGHT - itx) - bwid;
   icy = min (icy, theight - SCREEN_BOTTOM - ity) - bwid;

   Cur_Xzero = icx;
   Cur_Yzero = icy;
   Cur_Xsize = itx;
   Cur_Ysize = ity;

/*   XResizeWindow (display, win, itx, ity);
   if (XasDebug) fprintf (stderr,
     "resize_pressed: W H, %d %d\n", itx, ity); */
   XMoveResizeWindow (display, win, icx, icy, itx, ity);
   if (XasDebug) fprintf (stderr,
     "resize_pressed: W H, X Y %d %d, %d %d\n", itx, ity, icx, icy);

   return;
}

int windo_status()
/*--------------------------------------------------------------------*/
/*  Returns current window corners                                    */
/*--------------------------------------------------------------------*/
{
   int itx, ity, icx, icy;
/*--------------------------------------------------------------------*/
                                        /* force screen size          */
   if (xbuf.parms[0] > 0 && xbuf.parms[1] > 0
         && xbuf.parms[2] > 0 && xbuf.parms[3] > 0) {
      xbuf.parms[2] = min (xbuf.parms[2], Screen_Width);
      xbuf.parms[3] = min (xbuf.parms[3], Screen_Height);
      icx = Memory_x (xbuf.parms[0]);
      itx = Memory_x (xbuf.parms[2]);
      icy = Memory_y (xbuf.parms[3]);
      ity = Memory_y (xbuf.parms[1]);
      sc_width = itx - icx + 1;
      sc_height = ity - icy + 1;
      sc_centre_x = (icx + itx - 1) / 2;
      sc_centre_y = (icy + ity - 1) / 2;
      sc_width2 = sc_width / 2;
      sc_height2 = sc_height / 2;
      itx = sc_width;
      ity = sc_height;
      icx = Cur_Xzero + bwid;
      icy = Cur_Yzero + bwid;
      icx = max (icx, SCREEN_LEFT);
      icy = max (icy, SCREEN_TOP);
      icx = min (icx, twidth - SCREEN_RIGHT - itx) - bwid;
      icy = min (icy, theight - SCREEN_BOTTOM - ity) - bwid;

      if (XasDebug) fprintf (stderr,
         "windo_status: W H Cx Cy W H, %d %d, %d %d\n",
         sc_width, sc_height, sc_centre_x, sc_centre_y);

      Cur_Xzero = icx;
      Cur_Yzero = icy;
      Cur_Xsize = itx;
      Cur_Ysize = ity;
/*      XResizeWindow (display, win, itx, ity);
      if (XasDebug) fprintf (stderr,
         "windo_status: W H %d %d\n", itx, ity); */
      XMoveResizeWindow (display, win, icx, icy, itx, ity);
      if (XasDebug) fprintf (stderr,
         "windo_status: W H, X Y %d %d, %d %d\n",
         itx, ity, icx, icy);
      }
   ybuf.u.idata[0] = Aips_x (sc_centre_x - sc_width2 + 1);
   ybuf.u.idata[3] = Aips_y (sc_centre_y - sc_height2 + 1);
   ybuf.u.idata[2] = Aips_x (sc_centre_x + sc_width2);
   ybuf.u.idata[1] = Aips_y (sc_centre_y + sc_height2);

   ybuf.u.idata[0] = htons (ybuf.u.idata[0]);
   ybuf.u.idata[1] = htons (ybuf.u.idata[1]);
   ybuf.u.idata[2] = htons (ybuf.u.idata[2]);
   ybuf.u.idata[3] = htons (ybuf.u.idata[3]);
   return (0);
}

int Interogate (nparms)
/*--------------------------------------------------------------------*/
/* This subroutine returns the critical parameters of the TV to the   */
/* client in the order of DTVC.INC                                    */
/*--------------------------------------------------------------------*/
short int *nparms;
/*--------------------------------------------------------------------*/
{
   int ii;

   *nparms = 256;
   for (ii = 0; ii < *nparms; ii++)
      ybuf.u.ldata[ii] = params[ii];
   if (Ngrey != NgreyUser) {
      Ngrey = NgreyUser;
      InitXAS() ;
      if (XasDebug)
         fprintf (stderr, "DEBUG scrwrt called from Interogate\n");
      scrwrt (0, 0, Screen_Width - 1, Screen_Height - 1);
      }
   ybuf.u.ldata[0] = Ngrey;
   ybuf.u.ldata[1] = NGRAPH;
   ybuf.u.ldata[2] = (MAXCAT) ;
   ybuf.u.ldata[3] = Screen_Width;
   ybuf.u.ldata[4] = Screen_Height;
   ybuf.u.ldata[5] = NColour - 1;
   if (using_24b) {
      ybuf.u.ldata[6] = (NINTENS) - 1;
      ybuf.u.ldata[7] = (FNINTENS) - 1;
      }
   else {
      ybuf.u.ldata[6] = 255 ;
      ybuf.u.ldata[7] = 255 ;
      }
   ybuf.u.ldata[8] = 255;
   ybuf.u.ldata[9] = 1;
   ybuf.u.ldata[10] = 1;
   ybuf.u.ldata[11] = 1 - (MAXZOOM);
   if (using_24b)
      ybuf.u.ldata[12] = 4;
   else
      ybuf.u.ldata[12] = 4;
   ybuf.u.ldata[13] = 0;
   ybuf.u.ldata[14] = 3;
   ybuf.u.ldata[15] = 3;
   ybuf.u.ldata[16] = 0;
   ybuf.u.ldata[17] = 0;
   if (using_24b) ybuf.u.ldata[17] = 1;     /* capable tv */
   ybuf.u.ldata[18] = 1;         /* 1 when img catalogs here */
   ybuf.u.ldata[19] = 7 * char_mult;
   ybuf.u.ldata[20] = 9 * char_mult;
   ybuf.u.ldata[88] = Aips_x (sc_centre_x - sc_width2 + 1);
   ybuf.u.ldata[91] = Aips_y (sc_centre_y - sc_height2 + 1);
   ybuf.u.ldata[90] = Aips_x (sc_centre_x + sc_width2);
   ybuf.u.ldata[89] = Aips_y (sc_centre_y + sc_height2);
   ybuf.u.ldata[92] = scrhold;        /* synch */

    for (ii = 0; ii < *nparms; ii++)
       ybuf.u.ldata[ii] = htonl (ybuf.u.ldata[ii]);
   *nparms = *nparms * 4;
   return (0);
}

int InterogateO (nparms)
/*--------------------------------------------------------------------*/
/* This subroutine returns the critical parameters of the TV to the   */
/* client in the order of DTVC.INC old values                         */
/*--------------------------------------------------------------------*/
short int *nparms;
/*--------------------------------------------------------------------*/
{
   int ii;

   *nparms = 256;
   for (ii = 0; ii < *nparms; ii++)
      ybuf.u.idata[ii] = params[ii];
   if (Ngrey != 4) {
      Ngrey = 4;
      InitOldXAS() ;
      if (XasDebug)
         fprintf (stderr, "DEBUG scrwrt called from InterogateO\n");
      scrwrt (0, 0, Screen_Width - 1, Screen_Height - 1);
      }
   ybuf.u.idata[0] = Ngrey;
   ybuf.u.idata[1] = NGRAPH;
   ybuf.u.idata[2] = (MAXCAT) ;
   ybuf.u.idata[3] = Screen_Width;
   ybuf.u.idata[4] = Screen_Height;
   ybuf.u.idata[5] = 255;
   if (using_24b) {
      ybuf.u.idata[6] = 255;
      ybuf.u.idata[7] = 1023;
      }
   else {
      ybuf.u.idata[6] = 255 ;
      ybuf.u.idata[7] = 255 ;
      }
   ybuf.u.idata[8] = 255;
   ybuf.u.idata[9] = 1;
   ybuf.u.idata[10] = 1;
   ybuf.u.idata[11] = 1 - (MAXZOOM);
   if (using_24b)
      ybuf.u.idata[12] = 4;
   else
      ybuf.u.idata[12] = 4;
   ybuf.u.idata[13] = 0;
   ybuf.u.idata[14] = 3;
   ybuf.u.idata[15] = 3;
   ybuf.u.idata[16] = 0;
   ybuf.u.idata[17] = 0;
   if (using_24b) ybuf.u.idata[17] = 1;     /* capable tv */
   ybuf.u.idata[18] = 1;         /* 1 when img catalogs here */
   ybuf.u.idata[19] = 7 * char_mult;
   ybuf.u.idata[20] = 9 * char_mult;
   ybuf.u.idata[88] = Aips_x (sc_centre_x - sc_width2 + 1);
   ybuf.u.idata[91] = Aips_y (sc_centre_y - sc_height2 + 1);
   ybuf.u.idata[90] = Aips_x (sc_centre_x + sc_width2);
   ybuf.u.idata[89] = Aips_y (sc_centre_y + sc_height2);
   ybuf.u.idata[92] = scrhold;        /* synch */

    for (ii = 0; ii < *nparms; ii++)
       ybuf.u.idata[ii] = htons (ybuf.u.idata[ii]);
   *nparms = *nparms * 2;
   return (0);
}

int PSave ()
/*--------------------------------------------------------------------*/
/* This subroutine saves the critical parameters of the TV to the     */
/* client in the order of DTVC.INC                                    */
/*--------------------------------------------------------------------*/
{
   int ii;

   for (ii = 0; ii < 256; ii++)
       params[ii] = ntohl (xbuf.u.ldata[ii]);

   return (0);
}

int PSaveO ()
/*--------------------------------------------------------------------*/
/* This subroutine saves the critical parameters of the TV to the     */
/* client in the order of DTVC.INC                                    */
/*--------------------------------------------------------------------*/
{
   int ii;

   for (ii = 0; ii < 256; ii++)
       params[ii] = ntohs (xbuf.u.idata[ii]);

   return (0);
}

int ClearChan()
/*--------------------------------------------------------------------*/
/* ClearChan clears both graphics and image planes, if requested      */
/* Inputs                                                             */
/*   channel   I    If Channel is 0, all images and graphics cleared  */
/*                  If Channel <= Ngrey then one images is cleared    */
/*                  If Channel >  Ngrey then one graph is cleared     */
/*                  If Channel =  NGRTOT+1 then clear all graphs only */
/* Modified to clear more rapidly if only one graph plane is on       */
{  Bool OnlyWritten;
   int channel, imax, izero, bytes_row;
   register int i, j, k;
   short int *t1;
   unsigned char *t2;

   channel = xbuf.parms[0];
                                        /* If channel invalid, exit   */
   if ((channel < 0) || (channel > NGRTOT+1))
      return (-1);

   /* If only one graph and already cleared                           */
   /* If clearing channel=0, clear all for safty sake (no return)     */
   if (channel > 0 && channel <= NGRTOT && TvStatus[channel-1] == 0) {
      return (0);                       /* already done, return okay  */
      }

   if (channel == 0) {                  /* if clearing all channels   */
      OnlyWritten = True;
      for (j=0; j < NGRTOT; j++)
         TvStatus[j] = 0;               /* tell all are un-written    */
      }
   else {                               /* else clearing only some    */
      if (channel == NGRTOT+1) {        /* if clearing all graphs     */
         OnlyWritten = True;
         for (j=Ngrey; j < NGRTOT; j++)
            TvStatus[j] = 0;            /* tell graphs is clear       */
      	 }
      else {                            /* clearing one graph         */
         TvStatus[channel-1] = 0;       /* record Data put on TV      */
         OnlyWritten = True;            /* Assume only this 1 written */
         for (j=Ngrey; j < NGRAPH+Ngrey; j++) {
                                        /* If data in other graphics  */
            if ((j != channel-1) && (TvStatus[j] != 0))
               OnlyWritten = False;
            }
         }                              /* End if all graphs off      */
      }                                 /* End if all channels off    */

#ifdef USE_SHM
      if ((using_shm) && (!using_24b))
         bytes_row = line->bytes_per_line;
       else
#endif /* USE_SHM */
         bytes_row = Screen_Width;
   imax = Screen_Height * bytes_row;
   izero = int2pix[0];

   for (j = 0; j < Ngrey; j++) {        /* Clear Image                */
      if ((channel == 0) || (channel == j+1)) {
         if (using_24b) {                  /* 1char depth, quick clear*/
            t1 = plane_data[j];
            for (i = 0; i < imax; i++)
                *t1++ = izero;          /* set pixel to zero          */
            }
         else {                         /* Else slow clear            */
            for (i = 0; i < Screen_Width; i++) {
               for (k = 0; k < Screen_Height; k++)
                  XPutPixel (plane[j], i, k, izero);
               }
            }
         }
      }
   if (channel == 0 || OnlyWritten) {   /* If clearing all graphs     */
      t2 = graph_data;                  /* Clear graphics data        */
      for (i = 0; i < imax; i++)
         *t2++ = 0;
      }
   else {                               /* Else clearing only 1 graph */
      if (channel > Ngrey) {
         gph_mask = 255;
                                        /* set mask to all but channel*/
         if (channel == Ngrey + 1) gph_mask = 254;
         if (channel == Ngrey + 2) gph_mask = 253;
         if (channel == Ngrey + 3) gph_mask = 251;
         if (channel == Ngrey + 4) gph_mask = 247;
         if (channel == Ngrey + 5) gph_mask = 239;
         if (channel == Ngrey + 6) gph_mask = 223;
         if (channel == Ngrey + 7) gph_mask = 191;
         if (channel == Ngrey + 8) gph_mask = 127;
         t2 = graph_data;               /* point to begin graph plane */
         for (i = 0; i < imax; i++) {   /* for all pixels in graph pl */
            *t2 = *t2 & gph_mask;       /* zero this graph            */
            t2++;
            }
         }                              /* End if clear only one graph*/
      }                                 /* End if clering all         */

   if (XasDebug)
      fprintf (stderr, "DEBUG scrwrt from ClearChan\n");
   scrwrt (0, 0, Screen_Width - 1, Screen_Height - 1);

   return (0);
}

int FillChan()
/*--------------------------------------------------------------------*/
/* FillChan fills a window in graphics and image planes               */
{
   int channel, jvalu, ivalu, ixl, ixt, iyl, iyt, vv;
   register int i, j, k;
   short int *pd;
   unsigned char *pg;

   ixl =  Memory_x (xbuf.parms[0]);
   iyt =  Memory_y (xbuf.parms[1]);
   ixt =  Memory_x (xbuf.parms[2]);
   iyl =  Memory_y (xbuf.parms[3]);
   channel = ntohs (xbuf.u.idata[0]) ;
   jvalu = ntohs (xbuf.u.idata[1]) ;
/* if (XasDebug)
      fprintf (stderr, "FILL %d %d %d %d %d %d\n", ixl, iyl, ixt, iyt,
         channel, jvalu);  */
                                        /* If channel invalid, exit   */
   if ((channel < 1) || (channel > NGRTOT))
      return (-1);
                                       /* already done, return okay  */
   if (jvalu == 0 && TvStatus[channel-1] == 0)
      return (0);

   TvStatus[channel-1] = 1;

   ivalu = int2pix[jvalu];

   if (channel <= Ngrey) {
      j = channel-1;
      if (using_24b) {
         for (k = iyl; k <= iyt; k++) {
            pd = plane_data[j] + ixl + k * Screen_Width;
            for (i = ixl; i <= ixt; i++)
               *pd++ = ivalu;
            }
         }
      else {
         for (i = ixl; i <= ixt; i++) {
            for (k = iyl; k <= iyt; k++)
               XPutPixel (plane[j], i, k, ivalu);
            }
         }
      }
   else {
      gph_mask = 0;
      if (channel == Ngrey+1) gph_mask = 1;
      if (channel == Ngrey+2) gph_mask = 2;
      if (channel == Ngrey+3) gph_mask = 4;
      if (channel == Ngrey+4) gph_mask = 8;
      if (channel == Ngrey+5) gph_mask = 16;
      if (channel == Ngrey+6) gph_mask = 32;
      if (channel == Ngrey+7) gph_mask = 64;
      if (channel == Ngrey+8) gph_mask = 128;
      if (using_24b) {
         for (k = iyl; k <= iyt; k++) {
            pg = graph_data + ixl + k * Screen_Width;
            for (i = ixl; i <= ixt; i++) {
               vv = *pg;
               chg_s (vv, jvalu, gph_mask);
               *pg++ = vv;
               }
            }
         }
      else {
         for (i = ixl; i <= ixt; i++) {
            for (k = iyl; k <= iyt; k++) {
               vv = XGetPixel(graph, i, k);
               chg_s (vv, jvalu, gph_mask);
               XPutPixel (graph, i, k, vv);
               }
            }
         }
      }

   scrwrt (ixl, iyl, ixt, iyt);

   return (0);
}

int FillChon()
/*--------------------------------------------------------------------*/
/* FillChan fills a window in graphics and image planes: 8 bit        */
{
   int channel, jvalu, ivalu, ixl, ixt, iyl, iyt, vv;
   register int i, j, k;
   short int *pd;
   unsigned char *pg;

   ixl =  Memory_x (xbuf.parms[0]);
   iyt =  Memory_y (xbuf.parms[1]);
   ixt =  Memory_x (xbuf.parms[2]);
   iyl =  Memory_y (xbuf.parms[3]);
   channel = xbuf.u.data[0];
   jvalu = xbuf.u.data[1];
/* if (XasDebug)
      fprintf (stderr, "FILL %d %d %d %d %d %d\n", ixl, iyl, ixt, iyt,
         channel, jvalu);  */
                                        /* If channel invalid, exit   */
   if ((channel < 1) || (channel > NGRTOT))
      return (-1);
                                       /* already done, return okay  */
   if (jvalu == 0 && TvStatus[channel-1] == 0)
      return (0);

   TvStatus[channel-1] = 1;

   ivalu = int2pix[jvalu];

   if (channel <= Ngrey) {
      j = channel-1;
      if (using_24b) {
         for (k = iyl; k <= iyt; k++) {
            pd = plane_data[j] + ixl + k * Screen_Width;
            for (i = ixl; i <= ixt; i++)
               *pd++ = ivalu;
            }
         }
      else {
         for (i = ixl; i <= ixt; i++) {
            for (k = iyl; k <= iyt; k++)
               XPutPixel (plane[j], i, k, ivalu);
            }
         }
      }
   else {
      gph_mask = 0;
      if (channel == Ngrey+1) gph_mask = 1;
      if (channel == Ngrey+2) gph_mask = 2;
      if (channel == Ngrey+3) gph_mask = 4;
      if (channel == Ngrey+4) gph_mask = 8;
      if (channel == Ngrey+5) gph_mask = 16;
      if (channel == Ngrey+6) gph_mask = 32;
      if (channel == Ngrey+7) gph_mask = 64;
      if (channel == Ngrey+8) gph_mask = 128;
      if (using_24b) {
         for (k = iyl; k <= iyt; k++) {
            pg = graph_data + ixl + k * Screen_Width;
            for (i = ixl; i <= ixt; i++) {
               vv = *pg;
               chg_s (vv, jvalu, gph_mask);
               *pg++ = vv;
               }
            }
         }
      else {
         for (i = ixl; i <= ixt; i++) {
            for (k = iyl; k <= iyt; k++) {
               vv = XGetPixel(graph, i, k);
               chg_s (vv, xbuf.u.data[1], gph_mask);
               XPutPixel (graph, i, k, vv);
               }
            }
         }
      }

   scrwrt (ixl, iyl, ixt, iyt);

   return (0);
}

int VectChan()
/*--------------------------------------------------------------------*/
/* VectChan writes a vector to one channel                            */
{
   int channel, jvalu, ivalu, ixl, ixt, iyl, iyt, vv, ix1, ix2,
       iy1, iy2;
   register int i, j, k;
   float slope;
   short int *pd;
   unsigned char *pg;

   ix1 =  Memory_x (xbuf.parms[0]);
   iy1 =  Memory_y (xbuf.parms[1]);
   ix2 =  Memory_x (xbuf.parms[2]);
   iy2 =  Memory_y (xbuf.parms[3]);
   channel = ntohs (xbuf.u.idata[0]) ;
   jvalu = ntohs (xbuf.u.idata[1]) ;
   if (XasDebug)
      fprintf (stderr, "VECT %d %d %d %d %d %d\n", ix1, iy1, ix2, iy2,
         channel, jvalu);
                                        /* If channel invalid, exit   */
   if ((channel < 1) || (channel > NGRTOT))
      return (-1);
                                       /* already done, return okay  */
   if (jvalu == 0 && TvStatus[channel-1] == 0)
      return (0);

   TvStatus[channel-1] = 1;

   ivalu = int2pix[jvalu];

   gph_mask = 0;
   if (channel == Ngrey+1) gph_mask = 1;
   if (channel == Ngrey+2) gph_mask = 2;
   if (channel == Ngrey+3) gph_mask = 4;
   if (channel == Ngrey+4) gph_mask = 8;
   if (channel == Ngrey+5) gph_mask = 16;
   if (channel == Ngrey+6) gph_mask = 32;
   if (channel == Ngrey+7) gph_mask = 64;
   if (channel == Ngrey+8) gph_mask = 128;
   j = channel-1;

   ixl = min (ix1, ix2); ixt = max (ix1, ix2);
   iyl = min (iy1, iy2); iyt = max (iy1, iy2);

   if (using_24b) {
      if (ix1 == ix2) {
         if (channel <= Ngrey) {
            pd = plane_data[j] + ixl + iyl * Screen_Width;
            for (k = iyl; k <= iyt; k++) {
               *pd = ivalu;
               pd += Screen_Width;
               }
            }
         else {
            pg = graph_data + ixl + iyl * Screen_Width;
            for (k = iyl; k <= iyt; k++) {
               vv = *pg;
               chg_s (vv, jvalu, gph_mask);
               *pg = vv;
               pg += Screen_Width;
               }
            }
         }
      else if (iy1 == iy2) {
         if (channel <= Ngrey) {
            pd = plane_data[j] + ixl + iyl * Screen_Width;
            for (i = ixl; i <= ixt; i++)
               *pd++ = ivalu;
            }
         else {
            pg = graph_data + ixl + iyl * Screen_Width;
            for (i = ixl; i <= ixt; i++) {
               vv = *pg;
               chg_s (vv, jvalu, gph_mask);
               *pg++ = vv;
               }
            }
         }
      else if (ixt-ixl >= iyt-iyl) {
         if (ix1 > ix2) {
            iyt = iy1;
            iyl = iy2;
            }
         else {
            iyt = iy2;
            iyl = iy1;
            }
         slope = iyt - iyl;
         slope = slope / (ixt - ixl);
         for (i = ixl; i <= ixt; i++) {
            k = (i - ixl) * slope + iyl + 0.5;
            if (channel <= Ngrey) {
               pd = plane_data[j] + i + k * Screen_Width;
               *pd = ivalu;
               }
            else {
               pg = graph_data + i + k * Screen_Width;
               vv = *pg;
               chg_s (vv, jvalu, gph_mask);
               *pg = vv;
               }
            }
         }
      else {
         if (iy1 > iy2) {
            ixt = ix1;
            ixl = ix2;
            }
         else {
            ixt = ix2;
            ixl = ix1;
            }
         slope = ixt - ixl;
         slope = slope / (iyt - iyl);
         for (k = iyl; k <= iyt; k++) {
            i = (k - iyl) * slope + ixl + 0.5;
            if (channel <= Ngrey) {
               pd = plane_data[j] + i + k * Screen_Width;
               *pd = ivalu;
               }
            else {
               pg = graph_data + i + k * Screen_Width;
               vv = *pg;
               chg_s (vv, jvalu, gph_mask);
               *pg = vv;
               }
            }
         }
      }
   else {
      if (ix1 == ix2) {
         if (channel <= Ngrey) {
            for (k = iyl; k <= iyt; k++)
               XPutPixel (plane[j], ix1, k, ivalu);
            }
         else {
            for (k = iyl; k <= iyt; k++) {
               vv = XGetPixel(graph, ix1, k);
               chg_s (vv, jvalu, gph_mask);
               XPutPixel (graph, ix1, k, vv);
               }
            }
         }
      else if (iy1 == iy2) {
         if (channel <= Ngrey) {
            for (i = ixl; i <= ixt; i++)
               XPutPixel (plane[j], i, iy1, ivalu);
            }
         else {
            for (i = ixl; i <= ixt; i++) {
               vv = XGetPixel(graph, i, iy1);
               chg_s (vv, jvalu, gph_mask);
               XPutPixel (graph, i, iy1, vv);
               }
            }
         }
      else if (ixt-ixl >= iyt-iyl) {
         if (ix1 > ix2) {
            iyt = iy1;
            iyl = iy2;
            }
         else {
            iyt = iy2;
            iyl = iy1;
            }
         slope = iyt - iyl;
         slope = slope / (ixt - ixl);
         for (i = ixl; i <= ixt; i++) {
            k = (i - ixl) * slope + iyl + 0.5;
            if (channel <= Ngrey)
               XPutPixel (plane[j], i, k, ivalu);
            else {
               vv = XGetPixel(graph, i, k);
               chg_s (vv, jvalu, gph_mask);
               XPutPixel (graph, i, k, vv);
               }
            }
         }
      else {
         if (iy1 > iy2) {
            ixt = ix1;
            ixl = ix2;
            }
         else {
            ixt = ix2;
            ixl = ix1;
            }
         slope = ixt - ixl;
         slope = slope / (iyt - iyl);
         for (k = iyl; k <= iyt; k++) {
            i = (k - iyl) * slope + ixl + 0.5;
            if (channel <= Ngrey)
               XPutPixel (plane[j], i, k, ivalu);
            else {
               vv = XGetPixel(graph, i, k);
               chg_s (vv, jvalu, gph_mask);
               XPutPixel (graph, i, k, vv);
               }
            }
         }
      }

   ixl = min (ix1, ix2); ixt = max (ix1, ix2);
   iyl = min (iy1, iy2); iyt = max (iy1, iy2);
   scrwrt (ixl, iyl, ixt, iyt);

   return (0);
}

int VectChon()
/*--------------------------------------------------------------------*/
/* VectChan writes a vector to one channel - old 8 bit                */
{
   int channel, jvalu, ivalu, ixl, ixt, iyl, iyt, vv, ix1, ix2,
       iy1, iy2;
   register int i, j, k;
   float slope;
   short int *pd;
   unsigned char *pg;

   ix1 =  Memory_x (xbuf.parms[0]);
   iy1 =  Memory_y (xbuf.parms[1]);
   ix2 =  Memory_x (xbuf.parms[2]);
   iy2 =  Memory_y (xbuf.parms[3]);
   channel = xbuf.u.data[0];
   jvalu = xbuf.u.data[1];
   if (XasDebug)
      fprintf (stderr, "VECT %d %d %d %d %d %d\n", ix1, iy1, ix2, iy2,
         channel, jvalu);
                                        /* If channel invalid, exit   */
   if ((channel < 1) || (channel > NGRTOT))
      return (-1);
                                       /* already done, return okay  */
   if (jvalu == 0 && TvStatus[channel-1] == 0)
      return (0);

   TvStatus[channel-1] = 1;

   ivalu = int2pix[jvalu];

   gph_mask = 0;
   if (channel == Ngrey+1) gph_mask = 1;
   if (channel == Ngrey+2) gph_mask = 2;
   if (channel == Ngrey+3) gph_mask = 4;
   if (channel == Ngrey+4) gph_mask = 8;
   if (channel == Ngrey+5) gph_mask = 16;
   if (channel == Ngrey+6) gph_mask = 32;
   if (channel == Ngrey+7) gph_mask = 64;
   if (channel == Ngrey+8) gph_mask = 128;
   j = channel-1;

   ixl = min (ix1, ix2); ixt = max (ix1, ix2);
   iyl = min (iy1, iy2); iyt = max (iy1, iy2);

   if (using_24b) {
      if (ix1 == ix2) {
         if (channel <= Ngrey) {
            pd = plane_data[j] + ixl + iyl * Screen_Width;
            for (k = iyl; k <= iyt; k++) {
               *pd = ivalu;
               pd += Screen_Width;
               }
            }
         else {
            pg = graph_data + ixl + iyl * Screen_Width;
            for (k = iyl; k <= iyt; k++) {
               vv = *pg;
               chg_s (vv, xbuf.u.data[1], gph_mask);
               *pg = vv;
               pg += Screen_Width;
               }
            }
         }
      else if (iy1 == iy2) {
         if (channel <= Ngrey) {
            pd = plane_data[j] + ixl + iyl * Screen_Width;
            for (i = ixl; i <= ixt; i++)
               *pd++ = ivalu;
            }
         else {
            pg = graph_data + ixl + iyl * Screen_Width;
            for (i = ixl; i <= ixt; i++) {
               vv = *pg;
               chg_s (vv, xbuf.u.data[1], gph_mask);
               *pg++ = vv;
               }
            }
         }
      else if (ixt-ixl >= iyt-iyl) {
         if (ix1 > ix2) {
            iyt = iy1;
            iyl = iy2;
            }
         else {
            iyt = iy2;
            iyl = iy1;
            }
         slope = iyt - iyl;
         slope = slope / (ixt - ixl);
         for (i = ixl; i <= ixt; i++) {
            k = (i - ixl) * slope + iyl + 0.5;
            if (channel <= Ngrey) {
               pd = plane_data[j] + i + k * Screen_Width;
               *pd = ivalu;
               }
            else {
               pg = graph_data + i + k * Screen_Width;
               vv = *pg;
               chg_s (vv, xbuf.u.data[1], gph_mask);
               *pg = vv;
               }
            }
         }
      else {
         if (iy1 > iy2) {
            ixt = ix1;
            ixl = ix2;
            }
         else {
            ixt = ix2;
            ixl = ix1;
            }
         slope = ixt - ixl;
         slope = slope / (iyt - iyl);
         for (k = iyl; k <= iyt; k++) {
            i = (k - iyl) * slope + ixl + 0.5;
            if (channel <= Ngrey) {
               pd = plane_data[j] + i + k * Screen_Width;
               *pd = ivalu;
               }
            else {
               pg = graph_data + i + k * Screen_Width;
               vv = *pg;
               chg_s (vv, xbuf.u.data[1], gph_mask);
               *pg = vv;
               }
            }
         }
      }
   else {
      if (ix1 == ix2) {
         if (channel <= Ngrey) {
            for (k = iyl; k <= iyt; k++)
               XPutPixel (plane[j], ix1, k, ivalu);
            }
         else {
            for (k = iyl; k <= iyt; k++) {
               vv = XGetPixel(graph, ix1, k);
               chg_s (vv, xbuf.u.data[1], gph_mask);
               XPutPixel (graph, ix1, k, vv);
               }
            }
         }
      else if (iy1 == iy2) {
         if (channel <= Ngrey) {
            for (i = ixl; i <= ixt; i++)
               XPutPixel (plane[j], i, iy1, ivalu);
            }
         else {
            for (i = ixl; i <= ixt; i++) {
               vv = XGetPixel(graph, i, iy1);
               chg_s (vv, xbuf.u.data[1], gph_mask);
               XPutPixel (graph, i, iy1, vv);
               }
            }
         }
      else if (ixt-ixl >= iyt-iyl) {
         if (ix1 > ix2) {
            iyt = iy1;
            iyl = iy2;
            }
         else {
            iyt = iy2;
            iyl = iy1;
            }
         slope = iyt - iyl;
         slope = slope / (ixt - ixl);
         for (i = ixl; i <= ixt; i++) {
            k = (i - ixl) * slope + iyl + 0.5;
            if (channel <= Ngrey)
               XPutPixel (plane[j], i, k, ivalu);
            else {
               vv = XGetPixel(graph, i, k);
               chg_s (vv, xbuf.u.data[1], gph_mask);
               XPutPixel (graph, i, k, vv);
               }
            }
         }
      else {
         if (iy1 > iy2) {
            ixt = ix1;
            ixl = ix2;
            }
         else {
            ixt = ix2;
            ixl = ix1;
            }
         slope = ixt - ixl;
         slope = slope / (iyt - iyl);
         for (k = iyl; k <= iyt; k++) {
            i = (k - iyl) * slope + ixl + 0.5;
            if (channel <= Ngrey)
               XPutPixel (plane[j], i, k, ivalu);
            else {
               vv = XGetPixel(graph, i, k);
               chg_s (vv, xbuf.u.data[1], gph_mask);
               XPutPixel (graph, i, k, vv);
               }
            }
         }
      }

   ixl = min (ix1, ix2); ixt = max (ix1, ix2);
   iyl = min (iy1, iy2); iyt = max (iy1, iy2);
   scrwrt (ixl, iyl, ixt, iyt);

   return (0);
}

int CharChan()
/*--------------------------------------------------------------------*/
/* CharChan writes a character string to one channel                  */
{
   int   channel, jvalu, ivalu, ix0, iy0, vv, jback, iback, ic, nc,
         car[45][35], ixl, nchar, nxp, nyp;
   char  mask;
   short int *pd;
   unsigned char *pg;
   register int i, j, k, l, m, n;
   static char cdata[97][5] = {
/*                                       control chars all ?          */
      {  32,  64,  69,  72,  48 }, /* ? */
      {   0,   0,   0,   0,   0 }, /*   */
      {   0,   0, 121,   0,   0 }, /* ! */
      {   0, 112,   0, 112,   0 }, /* "" */
      {  20,  62,  20,  62,  20 }, /* # */
      {  18,  42, 127,  42,  36 }, /* $ */
      {   2,  36,   8,  18,  32 }, /* % */
      {  54,  73,  85,  34,   5 }, /* & */
      {   0,   0, 112,   0,   0 }, /* '' */
      {   0,  28,  34,  65,   0 }, /* ( */
      {   0,  65,  34,  28,   0 }, /* ) */
      {  20,   8,  62,   8,  20 }, /* * */
      {   8,   8,  62,   8,   8 }, /* + */
      {   0,   1,   6,   0,   0 }, /* , */
      {   0,   8,   8,   8,   0 }, /* - */
      {   0,   0,   1,   0,   0 }, /* . */
      {   2,   4,   8,  16,  32 }, /* / */
      {  62,  69,  73,  81,  62 }, /* 0 */
      {   0,  33, 127,   1,   0 }, /* 1 */
      {  35,  69,  73,  73,  49 }, /* 2 */
      {  66,  65,  73,  89, 102 }, /* 3 */
      {  12,  20,  36, 127,   4 }, /* 4 */
      { 114,  81,  81,  81,  78 }, /* 5 */
      {  30,  41,  73,  73,  70 }, /* 6 */
      {  64,  71,  72,  80,  96 }, /* 7 */
      {  54,  73,  73,  73,  54 }, /* 8 */
      {  49,  73,  73,  74,  60 }, /* 9 */
      {   0,   0,  18,   0,   0 }, /* : */
      {   0,   1,  22,   0,   0 }, /* ; */
      {   8,  20,  34,  65,   0 }, /* < */
      {  20,  20,  20,  20,   0 }, /* = */
      {  65,  34,  20,   8,   0 }, /* > */
      {  32,  64,  69,  72,  48 }, /* ? */
      {  18,  37,  37,  37,  30 }, /* @ */
      {  31,  36,  68,  36,  31 }, /* A */
      { 127,  73,  73,  73,  54 }, /* B */
      {  62,  65,  65,  65,  34 }, /* C */
      {  65, 127,  65,  65,  62 }, /* D */
      { 127,  73,  73,  73,  65 }, /* E */
      { 127,  72,  72,  64,  64 }, /* F */
      {  62,  65,  65,  69,  39 }, /* G */
      { 127,   8,   8,   8, 127 }, /* H */
      {   0,  65, 127,  65,   0 }, /* I */
      {   2,   1,   1,   1, 126 }, /* J */
      { 127,   8,  20,  34,  65 }, /* K */
      { 127,   1,   1,   1,   1 }, /* L */
      { 127,  32,  24,  32, 127 }, /* M */
      { 127,  16,   8,   4, 127 }, /* N */
      {  62,  65,  65,  65,  62 }, /* O */
      { 127,  72,  72,  72,  48 }, /* P */
      {  62,  65,  69,  66,  61 }, /* Q */
      { 127,  72,  76,  74,  49 }, /* R */
      {  50,  73,  73,  73,  38 }, /* S */
      {  64,  64, 127,  64,  64 }, /* T */
      { 126,   1,   1,   1, 126 }, /* U */
      { 112,  12,   3,  12, 112 }, /* V */
      { 126,   1,  14,   1, 126 }, /* W */
      {  99,  20,   8,  20,  99 }, /* X */
      {  96,  16,  15,  16,  96 }, /* Y */
      {  67,  69,  73,  81,  97 }, /* Z */
      {   0,   0, 127,  65,   0 }, /* [ */
      {  32,  16,   8,   4,   2 }, /* \ */
      {   0,  65, 127,   0,   0 }, /* ] */
      {  16,  32,  64,  32,  16 }, /* ^ */
      {   1,   1,   1,   1,   1 }, /* _ */
      {   0,  64,  32,  16,   0 }, /* `` */
      {  31,  36,  68,  36,  31 }, /* a */
      { 127,  73,  73,  73,  54 }, /* b */
      {  62,  65,  65,  65,  34 }, /* c */
      {  65, 127,  65,  65,  62 }, /* d */
      { 127,  73,  73,  73,  65 }, /* e */
      { 127,  72,  72,  64,  64 }, /* f */
      {  62,  65,  65,  69,  39 }, /* g */
      { 127,   8,   8,   8, 127 }, /* h */
      {  65,  65, 127,  65,  65 }, /* i */
      {   2,   1,   1,   1, 126 }, /* j */
      { 127,   8,  20,  34,  65 }, /* k */
      { 127,   1,   1,   1,   1 }, /* l */
      { 127,  32,  24,  32, 127 }, /* m */
      { 127,  16,   8,   4, 127 }, /* n */
      {  62,  65,  65,  65,  62 }, /* o */
      { 127,  72,  72,  72,  48 }, /* p */
      {  62,  65,  69,  66,  61 }, /* q */
      { 127,  72,  76,  74,  49 }, /* r */
      {  50,  73,  73,  73,  38 }, /* s */
      {  64,  64, 127,  64,  64 }, /* t */
      { 126,   1,   1,   1, 126 }, /* u */
      { 112,  12,   3,  12, 112 }, /* v */
      { 126,   1,  14,   1, 126 }, /* w */
      {  99,  20,   8,  20,  99 }, /* x */
      {  96,  16,  15,  16,  96 }, /* y */
      {  67,  69,  73,  81,  97 }, /* z */
      {   0,   8,  54,  65,   0 }, /* { */
      {   0,   0, 127,   0,   0 }, /* | */
      {   0,  65,  54,   8,   0 }, /* } */
      {   4,   8,   4,   2,   4 }, /* ~ */
      {  32,  64,  69,  72,  48 }  /* ? */
   };

   ix0 =  Memory_x (xbuf.parms[0]);
   iy0 =  Memory_y (xbuf.parms[1]);
   channel = xbuf.parms[2];
   nchar =  xbuf.parms[3];

   if (XasDebug)
      fprintf (stderr, "CHAR %d %d %d %d\n", ix0, iy0, channel, nchar);
                                        /* If channel invalid, exit   */
   if ((channel < 1) || (channel > NGRTOT))
      return (-1);

   TvStatus[channel-1] = 1;

/*   jvalu = NColour - 1; */
   jvalu = xbuf.u.ldata[0];
   ivalu = int2pix[jvalu];
   jback = 0;                          /* was 1 */
   if (channel > Ngrey) jback = 0;
   iback = int2pix[jback];

   gph_mask = 0;
   if (channel == Ngrey+1) gph_mask = 1;
   if (channel == Ngrey+2) gph_mask = 2;
   if (channel == Ngrey+3) gph_mask = 4;
   if (channel == Ngrey+4) gph_mask = 8;
   if (channel == Ngrey+5) gph_mask = 16;
   if (channel == Ngrey+6) gph_mask = 32;
   if (channel == Ngrey+7) gph_mask = 64;
   if (channel == Ngrey+8) gph_mask = 128;
   j = channel-1;
   nxp = 7 * char_mult;
   nyp = 9 * char_mult;

                                       /* loop over characters        */
   ixl = ix0 - nxp;
   for (nc = 4; nc < nchar+4; nc ++) {
      ic = xbuf.u.data[nc] - 31;
      if (ic < 0) ic = 0;
      ixl = ixl + nxp;

      if (channel <= Ngrey) {
         for (k = 0; k < nyp; k++)
            for (i = 0; i < nxp; i ++)
               car[k][i] = iback;
         mask = 1;
         for (k = char_mult; k < nyp-char_mult; k=k+char_mult) {
            for (i = char_mult; i < nxp-char_mult; i=i+char_mult) {
               l = i / char_mult - 1;
               if ((mask & cdata[ic][l]) != 0) {
                  for (n=0; n < char_mult; n++) {
                     for (m=0; m < char_mult; m++)
                        car[k+n][i+m] = ivalu;
                     }
                  }
               }
            mask = mask * 2;
            }
         if (using_24b) {
            for (k = 0; k < nyp; k++) {
               pd = plane_data[j] + ixl + (iy0-k) * Screen_Width;
               for (i = 0; i < nxp; i ++)
                  *pd++ = car[k][i];
               }
            }
         else {
            for (k = 0; k < nyp; k++)
               for (i = 0; i < nxp; i ++)
                  XPutPixel (plane[j], ixl+i, iy0-k, car[k][i]);
            }
         }
      else {
         for (k = 0; k < nyp; k++)
            for (i = 0; i < nxp; i ++)
               car[k][i] = jback;
         mask = 1;
         for (k = char_mult; k < nyp-char_mult; k=k+char_mult) {
            for (i = char_mult; i < nxp-char_mult; i=i+char_mult) {
               l = i / char_mult - 1;
               if ((mask & cdata[ic][l]) != 0) {
                  for (n=0; n < char_mult; n++) {
                     for (m=0; m < char_mult; m++)
                        car[k+n][i+m] = 255;
                     }
                  }
               }
            mask = mask * 2;
            }
         if (using_24b) {
            for (k = 0; k < nyp; k++) {
               pg = graph_data + ixl + (iy0-k) * Screen_Width;
               for (i = 0; i < nxp; i ++) {
                  vv = *pg;
                  chg_s (vv, car[k][i], gph_mask);
                  *pg++ = vv;
                  }
               }
            }
         else {
            for (k = 0; k < nyp; k++) {
               for (i = 0; i < nxp; i ++) {
                  vv = XGetPixel(graph, ixl+i, iy0-k);
                  chg_s (vv, car[k][i], gph_mask);
                  XPutPixel (graph, ixl+i, iy0-k, vv);
                  }
               }
            }
         }
      }

   ic = ix0 + nchar*nxp - 1;
   nc = iy0 - nyp + 1;
   scrwrt (ix0, nc, ic, iy0);

   return (0);
}

int ViewData()
/*--------------------------------------------------------------------*/
/* turns on/off command buffering by scrwrt()                         */
/*--------------------------------------------------------------------*/
{
   if ((scrhold) && (xbuf.parms[0] == 0)) {
      scrhold = 0;
      if (numhold > 0) scrwrt (uxs, uys, uxe, uye);
      numhold = 0;
      uxe = uye = 0;
      uxs = Screen_Width;
      uys = Screen_Height;
      }
   scrhold = xbuf.parms[0] ;
   if (Maxhold <= 1) scrhold = 0;

   return (0);
}

int zoom()
/*--------------------------------------------------------------------*/
/* Sets the zoom registers                                            */
/*--------------------------------------------------------------------*/
{
      int i;
/*--------------------------------------------------------------------*/
   if ((xbuf.parms[0] < 0) || (xbuf.parms[0] > NGRTOT)) {
      fprintf (stderr, "XAS: Illegal zoom channel %d\n", xbuf.parms[0]);
      return (-1);
      }
   else if (xbuf.parms[0] > Ngrey) {
      if (cur_chan[0] < 1) {
         if (XasDebug)
            fprintf (stderr, "DEBUG scrwrt from zoom\n");
         scrwrt (0, 0, Screen_Width - 1, Screen_Height - 1);
         }
      }
   else if (xbuf.parms[0] == 0) {
      upleft_mag = xbuf.parms[1];
      for (i = 0; i < Ngrey; i++) {
         upleft_x[i] = xbuf.parms[2];
         upleft_y[i] = xbuf.parms[3];
         }
      scrwrt (0, 0, Screen_Width - 1, Screen_Height - 1);
      }
   else {
      upleft_mag = xbuf.parms[1];
      upleft_x[xbuf.parms[0]-1] = xbuf.parms[2];
      upleft_y[xbuf.parms[0]-1] = xbuf.parms[3];
      if (active(xbuf.parms[0])) {
         if (XasDebug)
            fprintf (stderr, "DEBUG scrwrt from zoom\n");
         scrwrt (0, 0, Screen_Width - 1, Screen_Height - 1);
         }
      }
   return (0);
}
--XYZZY--
cat > init.c << "--XYZZY--"
/*--------------------------------------------------------------------*/
/*! XAS initialization routines                                       */
/*# TV-IO                                                             */
/*--------------------------------------------------------------------*/
/*;  Copyright (C) 1995-2001, 2003-2004, 2008, 2011-2012, 2015,       */
/*;  Copyright (C) 2022-2023, 2026                                    */
/*;  Associated Universities, Inc. Washington DC, USA.                */
/*;                                                                   */
/*;  This program is free software; you can redistribute it and/or    */
/*;  modify it under the terms of the GNU General Public License as   */
/*;  published by the Free Software Foundation; either version 2 of   */
/*;  the License, or (at your option) any later version.              */
/*;                                                                   */
/*;  This program is distributed in the hope that it will be useful,  */
/*;  but WITHOUT ANY WARRANTY; without even the implied warranty of   */
/*;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    */
/*;  GNU General Public License for more details.                     */
/*;                                                                   */
/*;  You should have received a copy of the GNU General Public        */
/*;  License along with this program; if not, write to the Free       */
/*;  Software Foundation, Inc., 675 Massachusetts Ave, Cambridge,     */
/*;  MA 02139, USA.                                                   */
/*;                                                                   */
/*;  Correspondence concerning AIPS should be addressed as follows:   */
/*;         Internet email: aipsmail@nrao.edu.                        */
/*;         Postal address: AIPS Project Office                       */
/*;                         National Radio Astronomy Observatory      */
/*;                         520 Edgemont Road                         */
/*;                         Charlottesville, VA 22903-2475 USA        */
/*--------------------------------------------------------------------*/

#include "xas.h"
#include <math.h>

extern int XLink;

/*--------------------------------------------------------------------*/

/* Icon position request flag - set to 1 if the user has requested an */
/* initial icon position. */
static int ic_pos_request;

/* Error Handler for I/O */

#define ERRMSGLEN 80
                     /* Max. length of an error message */

int XAS_IOHandler (display, XAS_Error_Event)
Display *display;
XErrorEvent *XAS_Error_Event;
{
   char msg[ERRMSGLEN+1];
/*--------------------------------------------------------------------*/
/* If there are events pending the server connection was probably     */
/* broken by the server.  In this case XAS_Error_Event will be garbage*/
/* and will cause a core dump if used in the call to get error text.  */
/* If there are no pending events this is assumed to be a normal      */
/* shutdown and no message will be displayed.                         */
   if (XPending(display) != 0) {
      XGetErrorText (display, XAS_Error_Event->error_code, msg,
                     ERRMSGLEN);
      fprintf (stderr, "XAS: Received error code %d, %s\n",
               XAS_Error_Event->error_code, msg);
   }
   closedown();
   exit(42);

   return (42);
}

void init()
{
    int i, j, k;
    union {
        short int shortint;
        struct {
            unsigned char lo, hi;
        }byte;
    }x;

    XasDebug = False;
    XDebug  = False;
    connected = False;

                                        /* check for byte swapped     */
    x.shortint = 17; /* any small number will do */
    if (x.shortint == x.byte.lo)
       ByteSwapped = True;
    else
       ByteSwapped = False;

   button_a = button_b = button_c = button_d = 0;

   rwgraph = 0;                       /* channel 1 on, graphics off */
   for (k = 0; k < 4; k++) {
      cur_chan[k] = 1;
      for (j = 0; j < 3; j++) {
         on_chan[0][j][k] = 1;
         for (i = 1; i < Ngrey; i++)
            on_chan[i][j][k] = 0;
         }
      }
   Q_same = 1;

   for (i = 0; i < Ngrey; i++)
      upleft_x[i] = upleft_y[i] = 0;

   for (i = 0; i < Ngrey; i++)          /* TV channels are off */
      TvStatus[i] = 0;

   for (i = 0; i < NGRAPH; i++)          /* Graphics channels are off */
      TvStatus[i+Ngrey] = 0;

   upleft_mag = 1;
                                              /* Default, buffer none */
   for (i = 0; i < (NUMOP+1); i++)
      bufferop[i] = False;

   size_i2 = sizeof(short int);

   return;
}

void SetupWindow (argc, argv)
int argc;
char *argv[];
{
   int offset = 0;
   int x = 0, y = 0;                /* window position */
   unsigned int border_width = 2;   /* border 2 pixels wide */
   unsigned long GCmask = 0;        /* ignore XGCValues, use defaults */
   char Window_name[36], Icon_name[16];
   char *window_name, *icon_name;
   /*   char *window_name = "X-AIPS TV-Screen-Server";
        char *icon_name = "AIPS TV"; */
   char *display_name = NULL;
   unsigned long event_mask, value_mask;
   char *option;
   char *BasicTV = "AIPStv";

   Pixmap icon_pixmap;
   static unsigned char icon_image[512] =          /* icon data      */
   {
#include "Xas.icon"
   };
   static unsigned char icon2_image[512] =          /* icon data      */
   {
#include "Xas2.icon"
   };
   unsigned long icon_xsize = 64;
   unsigned long icon_ysize = 48;

   XWMHints wm_hints;
   XSizeHints size_hints;
   XClassHint class_hints;
   XGCValues values;
   XSetWindowAttributes WinAtt;

   Visual *defauvis;                    /* type of visual root window */
   XVisualInfo template;                /* type of visual XAS uses    */
   XVisualInfo *vislist;                /* list of visuals matching   */
                                        /* the template               */
   int nvis;                            /* number of visuals in list  */

   XGCValues gc_values;                 /* X11 graphics context       */
                                        /* template                   */

   unsigned long plane_masks[15];       /* plane masks from XAlloc-   */
                                        /* Colorcells.                */
   int mjr, mnr, pixmaps;               /* Dummy variables for SHM    */
   register int i, j, k;
   int icx, icy, notdefault, vok;
   float temp;
   XIOErrorHandler old_handler;         /* Pointer to old I/O error   */
                                        /* handler                    */

   XPixmapFormatValues *pixmap_format;
   int pixmap_format_count, format;
   unsigned long rmask, gmask, bmask;
/*--------------------------------------------------------------------*/
                                        /* connect to X server        */
   if ((display = XOpenDisplay (display_name)) == NULL) {
      fprintf (stderr, "XAS: cannot connect to X server %s\n",
         XDisplayName(display_name));
      exit (-1);
      }
                                        /* get root screen number     */
   screen_num = DefaultScreen (display);
                                        /* set up I/O error handler   */
#ifndef X11R3
   old_handler =
#endif
   XSetIOErrorHandler (XAS_IOHandler);
                                        /* get root (full) screen size*/
   theight = DisplayHeight (display, screen_num);
   twidth = DisplayWidth (display, screen_num);

    /* Check that the server has sufficient depth for our needs */
   if ((depth = DisplayPlanes (display, screen_num)) < 6) {
      (void) fprintf (stderr, "XAS: X server color table too small\n");
      (void) fprintf (stderr, "XAS: Image display not possible\n");
      (void) fprintf (stderr, "XAS: Exiting...\n");
      exit (-1);
      }
                                       /* Find out whether the user   */
                                       /* Wants to use true color     */
   option = XGetDefault (display, BasicTV, "useTrueColor");
   using_24b = option ? atoi (option) : 1;
                                       /* Find out whether the user   */
                                       /* Wants to start in icon      */
   option = XGetDefault (display, BasicTV, "startIconic");
   start_icon = option ? atoi (option) : 0;

   if (depth > 8) {
      if (!using_24b) {
         fprintf (stderr, "XAS: ***********************************\n");
         fprintf (stderr, "XAS: **  depth = %d > 8!", depth);
         fprintf (stderr, "XAS: **  Sorry, must limit to 8\n");
         fprintf (stderr, "XAS: ***********************************\n");
         }
      depth = 8;
      }

   defauvis = DefaultVisual (display, screen_num);

   NValue = 1 << depth;
   NValue = NValue - 40;                /* be considerate, leave some */
   NValue = min (NValue, 256);          /* ZSSSX2 uses 8-bit chars    */
   NColour = NValue - NGRPHCOL;

   if (using_24b) {                     /* Find a TrueColor           */
      template.screen = DefaultScreen(display);
      template.depth = 24;
      template.class = DirectColor;
      template.class = TrueColor;

      vislist = XGetVisualInfo (display, VisualScreenMask|
         VisualDepthMask|VisualClassMask, &template, &nvis);

      if (nvis == 0) {
         using_24b = 0;
         fprintf (stderr, "XAS: ***********************************\n");
         fprintf (stderr, "XAS: **  No TrueColor found\n");
         fprintf (stderr, "XAS: **  Resorting to PseudoColor\n");
         fprintf (stderr, "XAS: ***********************************\n");
         }
      else {
         fprintf (stderr, "XAS: ** TrueColor FOUND!!! \n");
         depth = 24;
         visnum = 0;
         if (nvis > 1) {
            for (i = 0; i < nvis; i++) {
               if (vislist[i].visualid == defauvis->visualid) visnum=i;
               }
            }
         }
      }

   if (!using_24b) {                  /* Find a PseudoColor visual   */

      template.screen = DefaultScreen(display);
      template.depth = depth;
      template.class = PseudoColor;

      vislist = XGetVisualInfo (display, VisualScreenMask|
         VisualDepthMask|VisualClassMask, &template, &nvis);

      if (nvis == 0) {
         fprintf (stderr, "XAS: No pseudocolor visual");
         template.class = GrayScale;
         vislist = XGetVisualInfo (display, VisualScreenMask |
            VisualDepthMask | VisualClassMask, &template, &nvis);

         if (nvis == 0) {
            perror (" - No suitable visual");
            exit (1);
            }
         fprintf (stderr, "XAS: - using GrayScale visual instead\n");
         }

      if (nvis > 1) {
         for (i = 0; i < nvis; i++) {
            if (vislist[i].visualid == defauvis->visualid) visnum = i;
            }
         }
      else
         visnum = 0;
                                       /* Attempt to allocate colours */
                                       /* from default colourmap      */
      TV_colour = DefaultColormap (display, DefaultScreen(display));
      notdefault = 0;
                                        /* create color map if nec.   */
      if (defauvis->class != vislist[visnum].class) {
         fprintf (stderr,
            "XAS: Visual not = default, create colormap\n");
         TV_colour = XCreateColormap (display,
            RootWindow (display, screen_num), vislist[visnum].visual,
            AllocAll);
         notdefault = 1;
         }
      }

   if (using_24b) {                      /* 24b color                 */
      NValue = 8192;
      NColour = 8192;
      notdefault = 0;
                                        /* need bits_per_pixel       */
      BitsPerPixel = 0;
      pixmap_format = XListPixmapFormats(display, &pixmap_format_count);
      if (pixmap_format != NULL) {
         for (format = 0; format != pixmap_format_count; format++) {
            if (pixmap_format[format].depth == 24) {
               BitsPerPixel = pixmap_format[format].bits_per_pixel ;
               }
            }
         XFree(pixmap_format);
         }
                                        /* create color map if nec.   */
      if (defauvis->class != vislist[visnum].class) {
         fprintf (stderr,
            "XAS: Visual not = default, create 24-bit colormap\n");
         TV_colour = XCreateColormap (display,
            RootWindow (display, screen_num), vislist[visnum].visual,
            AllocNone);
         notdefault = 1;
         }
      }
                                        /* init gph table */
   for (i = 0; i < 256; i +=16) {
      for (j = 0; j < 16; j++) grfvc[i+j] = j;
      if (i != 0) grfvc[i] = 16;
      }
   grfvc[32] = grfvc[96] = grfvc[160] = grfvc[224] = 17;
   grfvc[64] = grfvc[192] = 18;
   grfvc[128] = 19;

   window_name = Window_name;
   icon_name = Icon_name;
   strcpy (window_name, "X-AIPS TV-Screen-Server");
   strcpy (icon_name, "AIPS TV");
                                        /* screen size details        */
   Screen_Width = twidth - SCREEN_LEFT - SCREEN_RIGHT;
   Screen_Height = theight - SCREEN_TOP - SCREEN_BOTTOM;
   Screen_Width = (Screen_Width / 2) * 2;
   Screen_Height = (Screen_Height / 2) * 2;

   user_options (argc, argv, window_name, icon_name);

   i = NColour - 1;
   fprintf (stderr,"XAS: Using screen width %d height %d,\n",
      Screen_Width, Screen_Height);
   fprintf (stderr,"     max grey level %d in %d grey-scale memories\n",
      i, Ngrey);
   if (char_mult > 1) {
      fprintf (stderr,"     characters multiplied by %d\n", char_mult);
   }
   ic_height = max (icon_xsize, icon_ysize);
   ic_width = ic_height;
   scrhold = numhold = uxe = uye = 0;
   uxs = Screen_Width;
   uys = Screen_Height;
                                        /* create opaque window       */
   value_mask = CWBorderPixel | CWBackPixel | CWBitGravity;
   WinAtt.bit_gravity = CenterGravity;
   WinAtt.border_pixel = curs_pixel[0] =
      WhitePixel (display, screen_num);
   WinAtt.background_pixel = curs_pixel[1] =
      BlackPixel (display, screen_num);
   if (defauvis->class != vislist[visnum].class) {
      WinAtt.colormap = TV_colour;
      value_mask |= CWColormap ;
      }
   win = XCreateWindow (display, RootWindow(display,screen_num),
      x, y, Screen_Width, Screen_Height, border_width, depth,
      InputOutput, vislist[visnum].visual, value_mask, &WinAtt);
   if (defauvis->class != vislist[visnum].class)
      XSetWindowColormap (display, win, TV_colour);

#ifdef AIX
   bwid = 0;
#else
   bwid = border_width;
#endif
                                        /* create pixmap of depth 1   */
                                        /* (bitmap) for icon          */
#if __STDC__
   if (using_24b)
      icon_pixmap = XCreateBitmapFromData (display, win,
         (const char *)icon2_image, icon_xsize, icon_ysize);
   else
      icon_pixmap = XCreateBitmapFromData (display, win,
         (const char *)icon_image, icon_xsize, icon_ysize);
#else
   if (using_24b)
      icon_pixmap = XCreateBitmapFromData (display, win,
         (char *)icon2_image, icon_xsize, icon_ysize);
   else
      icon_pixmap = XCreateBitmapFromData (display, win,
         (char *)icon_image, icon_xsize, icon_ysize);
#endif

                                        /* set size, class, other     */
                                        /* hints for Window Manager   */
   size_hints.min_width = 16;
   size_hints.min_height = 16;
   size_hints.max_width = Screen_Width;
   size_hints.max_height = Screen_Height;
   size_hints.flags = PMinSize | PMaxSize;
                                        /* Assure keyboard input      */
   wm_hints.input = True;
   /*   fprintf (stderr,"XAS: start_icon %d,\n", start_icon);         */
   if (start_icon > 0) {                /* Icon start or no           */
      wm_hints.initial_state = IconicState ;
      }
   else {
      wm_hints.initial_state = NormalState ;
      }
   wm_hints.flags = InputHint | StateHint | IconPixmapHint;
   if (ic_pos_request) wm_hints.flags |= IconPositionHint;
   wm_hints.icon_pixmap = icon_pixmap;
   wm_hints.icon_x = ic_xcorn;
   wm_hints.icon_y = ic_ycorn;
   class_hints.res_name = ProgName;
   class_hints.res_class = "AIPSServer" ;

#ifdef X11R3                            /* X11 Release 3 or earlier   */
   size_hints.x = cur_xcorn + SCREEN_LEFT - bwid;
   size_hints.y = cur_ycorn + SCREEN_TOP - bwid;
   size_hints.width = sc_width;
   size_hints.height = sc_height;
   size_hints.flags |= (PPosition | PSize);

                                        /* set properties for window  */
                                        /* manager (before mapping)   */
   XSetStandardProperties (display, win, window_name, icon_name,
      icon_pixmap, argv, argc, &size_hints);

   XSetWMHints (display, win, &wm_hints);

   XSetClassHint (display, win, &class_hints);

#else                                   /* X11 Release 4 or later     */
    {
    XTextProperty windowName, iconName;

    if (XStringListToTextProperty (&window_name, 1, &windowName) == 0) {
       fprintf (stderr,
          "XAS: structure allocation for windowName fails\n");
       exit (-1);
       }
    if (XStringListToTextProperty (&icon_name, 1, &iconName) == 0) {
       fprintf (stderr,
          "XAS: structure allocation for iconName fails\n");
       exit (-1);
       }

   XSetWMProperties (display, win, &windowName, &iconName, argv, argc,
      &size_hints, &wm_hints, &class_hints);
   }
#endif

                                        /* select event types wanted  */
   event_mask = ExposureMask | KeyPressMask | StructureNotifyMask |
                ButtonPressMask | ButtonMotionMask |
                EnterWindowMask | LeaveWindowMask;
   XSelectInput (display, win, event_mask);

                                        /* create all the images      */
   if (using_24b) {
      for (i = 0; i < Ngrey; i++) {
         plane_data[i] = (short int*) malloc (sizeof(short int) *
            Screen_Width * Screen_Height);
         }
      graph_data = (unsigned char*) malloc
        (Screen_Width * Screen_Height);
#ifdef USE_SHM
      if (using_shm) {
         line = XShmCreateImage (display, vislist[visnum].visual, depth,
            ZPixmap, NULL, &line_info, Screen_Width, Screen_Height);
         if ((line_info.shmid = shmget (IPC_PRIVATE,
            (line->bytes_per_line * line->height), IPC_CREAT|0777))
            ==-1) {
            perror ("Shared memory id failure");
            exit (1);
            }
         line_idata = shmat (line_info.shmid, NULL, 0);
         line->data = (char *) line_idata ;
         line_data =  (unsigned char *) line_idata ;
         line_info.shmaddr = line->data ;
         line_info.readOnly = False;
         if ( XShmAttach (display, &line_info) == False ) {
            perror ("Shared memory attach failed");
            exit (1);
            }
         ByteSwapDisp = ByteSwapped;
         rmask = line->red_mask;
         gmask = line->green_mask;
         bmask = line->blue_mask;
         RedBigger = rmask > bmask;
         }
      else {
#endif  /* USE_SHM */
        /*         line_idata = (int*) malloc (Screen_Width * Screen_Height *
                   sizeof(int)); */
         line_data = malloc (Screen_Width * Screen_Height * sizeof(int));
         line_idata = (int *) line_data;
         line = XCreateImage (display, vislist[visnum].visual, depth,
            ZPixmap, offset, (char *) line_idata, Screen_Width,
            Screen_Height, 32, 0);
         ByteSwapDisp = !line->byte_order;
         rmask = line->red_mask;
         gmask = line->green_mask;
         bmask = line->blue_mask;
         RedBigger = rmask > bmask;
#ifdef USE_SHM
          }
#endif
      }
   else {
#ifdef USE_SHM
      if (using_shm) {
         for (i = 0; i < Ngrey; i++) {
            plane[i] = XShmCreateImage (display, vislist[visnum].visual,
               depth, ZPixmap, NULL, &plane_info[i], Screen_Width,
               Screen_Height);
            if ((plane_info[i].shmid = shmget (IPC_PRIVATE,
               (plane[i]->bytes_per_line * plane[i]->height),
               IPC_CREAT|0777)) == -1 ) {
               perror ("Shared memory id failure");
               exit (1);
               }
            plane_short[i] = shmat (plane_info[i].shmid, NULL, 0);
            plane[i]->data = (char *) plane_short[i] ;
            plane_info[i].shmaddr = plane[i]->data ;
            plane_info[i].readOnly = False;
            if (XShmAttach (display, &plane_info[i]) == False) {
               perror ("Shared memory attach failed");
               exit (1);
               }
            }
         graph = XShmCreateImage (display, vislist[visnum].visual,
            depth, ZPixmap, NULL, &graph_info, Screen_Width,
            Screen_Height);
         if ((graph_info.shmid = shmget (IPC_PRIVATE,
            (graph->bytes_per_line * graph->height),
            IPC_CREAT|0777)) == -1) {
            perror ("Shared memory id failure");
            exit (1);
            }
         graph_data = shmat (graph_info.shmid, NULL, 0);
         graph->data = (char *) graph_data ;
         graph_info.shmaddr = graph->data;
         graph_info.readOnly = False;
         if (XShmAttach (display, &graph_info) == False ) {
            perror ("Shared memory attach failed");
            exit (1);
            }
         line = XShmCreateImage (display, vislist[visnum].visual, depth,
            ZPixmap, NULL, &line_info, Screen_Width, Screen_Height);
         if ((line_info.shmid = shmget (IPC_PRIVATE,
            (line->bytes_per_line * line->height), IPC_CREAT|0777))
            ==-1) {
            perror ("Shared memory id failure");
            exit (1);
            }
         line_data = shmat (line_info.shmid, NULL, 0);
         line->data = (char *) line_data ;
         line_info.shmaddr = line->data ;
         line_info.readOnly = False;
         if ( XShmAttach (display, &line_info) == False ) {
            perror ("Shared memory attach failed");
            exit (1);
            }
         }
      else {
#endif  /* USE_SHM */
         for (i = 0; i < Ngrey; i++) {
            plane_short[i] = (unsigned char*) malloc
               (Screen_Width * Screen_Height * ((depth+1) / 8));
            plane[i] = XCreateImage (display, vislist[visnum].visual,
               depth, ZPixmap, offset, (char *) plane_short[i],
               Screen_Width, Screen_Height, 8, 0);
            }
         graph_data = (unsigned char*) malloc
            (Screen_Width * Screen_Height * ((depth+1)/8));
         graph = XCreateImage (display, vislist[visnum].visual, depth,
            ZPixmap, offset, (char *) graph_data, Screen_Width,
            Screen_Height, 8, 0) ;
         line_data = (unsigned char*) malloc
            (Screen_Width * Screen_Height * ((depth+1)/8));
         line = XCreateImage (display, vislist[visnum].visual, depth,
            ZPixmap, offset, (char * ) line_data, Screen_Width,
            Screen_Height, 8, 0);
#ifdef USE_SHM
          }
#endif
      }
                                       /* Allocate space for lookups  */
   for (i = 0; i < Ngrey; i++) {
      rlut[i] = (int *) malloc (NColour * (sizeof (int)));
      glut[i] = (int *) malloc (NColour * (sizeof (int)));
      blut[i] = (int *) malloc (NColour * (sizeof (int)));
      }

                                       /* Allocate space for the      */
                                       /* colour table:               */
   if (using_24b) {
      int2pix = (unsigned long int *) malloc
        (NValue*(sizeof (long int)));
      for (i=0; i<NValue; i++)
         int2pix[i] = i;
      pix2int = (int *) malloc (256 * (sizeof (int)));
      for (i=0; i<256; i++)
         pix2int[i] = i;
      if ((colour_table = (XColor *) malloc
         (vislist[visnum].colormap_size * sizeof(XColor))) == NULL) {
         perror ("Cannot allocate space for colour table");
         exit (-1);
         }
         for (i = 0; i < vislist[visnum].colormap_size; i++) {
            colour_table[i].pixel = i;
            colour_table[i].flags = DoRed | DoGreen | DoBlue;
            }
         XQueryColors (display,
            DefaultColormap(display, DefaultScreen(display)),
            colour_table, vislist[visnum].colormap_size);
/*         XStoreColors (display, TV_colour, colour_table,
            vislist[visnum].colormap_size); */
      }
   else {
      int2pix = (unsigned long int *) malloc
        (NValue*(sizeof (long int)));
      pix2int = (int *) malloc ((1 << depth) * (sizeof (int)));

      if ((colour_table = (XColor *) malloc
         (vislist[visnum].colormap_size * sizeof(XColor))) == NULL) {
         perror ("Cannot allocate space for colour table");
         exit (-1);
         }
                                       /* Attempt to allocate colors  */
                                       /* from default colormap       */
      if (!notdefault) {
         if (XAllocColorCells (display, TV_colour, True, plane_masks, 0,
            int2pix, NValue) == 0) {
                                       /* Attempt failed --- create a */
                                       /* new (virtual) color map and */
                                       /* install it as the color map */
                                       /* for the AIPS TV:            */
            fprintf (stderr,
               "XAS: Warning -- creating virtual colormap\n");
            TV_colour = XCreateColormap (display, win,
               vislist[visnum].visual, AllocAll);
            notdefault = 1;
            }
         }
                                       /* Copy colours from default   */
                                       /* colourmap to virtual        */
                                       /* colourmap (retains as much  */
                                       /* of the rest of the screen   */
                                       /* as possible):               */
      if (notdefault) {
         for (i = 0; i < vislist[visnum].colormap_size; i++) {
            colour_table[i].pixel = i;
            colour_table[i].flags = DoRed | DoGreen | DoBlue;
            }
         XQueryColors (display,
            DefaultColormap(display, DefaultScreen(display)),
            colour_table, vislist[visnum].colormap_size);
         XStoreColors (display, TV_colour, colour_table,
            vislist[visnum].colormap_size);

                                       /* Avoid the basic colors     */
         OColour = vislist[visnum].colormap_size - NValue;
         j = 0;
         i = 0 ;
         for (j = 0; j < NValue+OColour; j++) {
            vok = 0;
            for (k = 0; k < OColour; k++)
               if (j == colour_table[k].pixel) vok++;
            if (vok == 0) int2pix[i++] = j;
            }
                                       /* Install the colourmap and  */
                                       /* let the window manager     */
                                       /* know that we want our own  */
                                       /* colour map on the canvas   */
                                       /* and the default colour map */
                                       /* on the button panel:       */
         XSetWindowColormap (display, win, TV_colour);
         }
                                       /* reverse translation        */
      for (i = 0; i < NValue; i++)
         pix2int[int2pix[i]] = i;
      }
                                       /* Set graphics contexts:     */
   gc_values.function = GXcopy;
   gc_values.plane_mask = AllPlanes;
   ImageGC = XCreateGC (display, win, GCFunction | GCPlaneMask,
      &gc_values);
                                        /* create cursor for window   */
   cursor = XCreateFontCursor (display, cursor_shape);
   XDefineCursor (display, win, cursor);
                                        /* color the cursor           */
   fg_curs.red = (rgcol[19] << COLORSHIFT) + rgcol[19];
   fg_curs.green = (ggcol[19] << COLORSHIFT) + ggcol[19];
   fg_curs.blue = (bgcol[19] << COLORSHIFT) + bgcol[19];
   bg_curs.red = 0;
   bg_curs.green = 0;
   bg_curs.blue = 0;
   fg_curs.flags = DoRed | DoGreen | DoBlue;
   bg_curs.flags = DoRed | DoGreen | DoBlue;
   fg_curs.pixel = curs_pixel[0];
   bg_curs.pixel = curs_pixel[1];
   XRecolorCursor (display, cursor, &fg_curs, &bg_curs);
                                        /* specify foreground since   */
                                        /* else may be white on white */
   XSetForeground (display, ImageGC, BlackPixel(display, screen_num));
                                        /* set initial sizes          */
   Cur_Xzero = cur_xcorn - bwid;
   Cur_Yzero = cur_ycorn - bwid;
   Cur_Xsize = cur_xsize = sc_width;
   Cur_Ysize = cur_ysize = sc_height;
   sc_width2   = sc_width/2;
   sc_height2  = sc_height/2;
   sc_centre_x = Screen_Width/2 - 1;
   sc_centre_y = Screen_Height/2 - 1;
   big_screen = False;
   XMoveResizeWindow (display, win, Cur_Xzero, Cur_Yzero, Cur_Xsize,
      Cur_Ysize);

   params[21] = Gamma * 1000 + 0.5;                   /* TVGAMA */

   InitXAS ();

   XasDebug = False;
   XDebug  = False;


   return;
} /* end SetupWindow */

void InitXAS()
{
   register int i, j, k;
   double xx, yy, zz;
   int imax, izero, bytes_row;
   short int *t1;
   unsigned char *t2;

   button_a = button_b = button_c = button_d = 0;

   rwgraph = 0;                        /* channel 1 on, graphics off */
   for (k = 0; k < 4; k++) {
      cur_chan[k] = 1;
      for (j = 0; j < 3; j++) {
         on_chan[0][j][k] = 1;
         for (i = 1; i < Ngrey; i++)
            on_chan[i][j][k] = 0;
         }
      }
   Q_same = 1;

   for (i = 0; i < Ngrey; i++)
      upleft_x[i] = upleft_y[i] = 0;

   for (i = 0; i < Ngrey; i++)          /* TV channels are off */
      TvStatus[i] = 0;

   for (i = 0; i < NGRAPH; i++)          /* Graphics channels are off */
      TvStatus[i+Ngrey] = 0;

   upleft_mag = 1;
                                        /* set OFM, Gamma = 2.2       */
   if (Gamma < 1.0) Gamma = 2.2;
   yy = NINTENS - 1;
   zz = 1.0 / Gamma;
   k = 0;
   for (i = 0; i < FNINTENS; i++) {
      xx = k / yy;
      rofm[i] = gofm[i] = bofm[i] = 255 * pow (xx, zz);
      k = k + 1;
      if (k == NINTENS) k = 0;
      }

   x_split = Screen_Width / 2;
   y_split = Screen_Height / 2;
                                        /* "zero" fill memories       */
#ifdef USE_SHM
      if ((using_shm) && (!using_24b))
         bytes_row = line->bytes_per_line;
       else
#endif /* USE_SHM */
         bytes_row = Screen_Width;
   imax = Screen_Height * bytes_row;
   izero = int2pix[0];
   for (j = 0; j < Ngrey; j++) {
      if (using_24b) {
         t1 = plane_data[j];
         for (i = 0; i < imax; i++)
            *t1++ = izero;
         }
      else {
         if (depth == 8) {
            t2 = plane_short[j];
            for (i = 0; i < imax; i++)
               *t2++ = izero;
            }
         else {
            for (i = 0; i < Screen_Width; i++) {
               for (k = 0; k < Screen_Height; k++)
                   XPutPixel (plane[j], i, k, izero);
               }
            }
         }
      }
   t2 = graph_data;
   for (i = 0; i < imax; i++)
      *t2++ = 0;
                                        /* Start up the window with a */
                                        /* linear transfer function:  */
   if (using_24b) {
      xx = NINTENS-1;
      xx = xx / (NColour - 1);
      for (i = 0; i < NValue; i++) {
          yy = xx * i;
          rlut[0][i] = glut[0][i] = blut[0][i] =  yy + 0.5;
          if (Ngrey > 1) {
            for (j = 1; j < Ngrey; j++)
               rlut[j][i] = glut[j][i] = blut[j][i] = rlut[0][i];
            }
/*       colour_table[i].pixel = i; */
/*       colour_table[i].flags = DoRed | DoGreen | DoBlue; */
/*       colour_table[i].red = colour_table[i].green =
            colour_table[i].blue = i << COLORSHIFT; */
         }
/*    XStoreColors (display, TV_colour, colour_table, NValue+OColour);*/
      XRecolorCursor (display, cursor, &fg_curs, &bg_curs);
      }
   else {
      zz = NColour - 1;
      zz = yy / zz;
      for (i = 0; i < NValue; i++) {
         colour_table[i+OColour].pixel = int2pix[i];
         colour_table[i+OColour].flags = DoRed | DoGreen | DoBlue;
         if (i < NColour) {
            rlut[0][i] = glut[0][i] = blut[0][i] =  i * zz;
            if (Ngrey > 1) {
               for (j = 1; j < Ngrey; j++)
                  rlut[j][i] = glut[j][i] = blut[j][i] = rlut[0][i];
               }
            colour_table[i+OColour].red =
               colour_table[i+OColour].green =
               colour_table[i+OColour].blue = rofm[rlut[0][i]]
                  << COLORSHIFT;
            }
         else {
            colour_table[i+OColour].red = rgcol[i-NColour]
               << COLORSHIFT;
            colour_table[i+OColour].blue = bgcol[i-NColour]
               << COLORSHIFT;
            colour_table[i+OColour].green = ggcol[i-NColour]
               << COLORSHIFT;
            }
         }

      XStoreColors (display, TV_colour, colour_table, NValue+OColour);
      XRecolorCursor (display, cursor, &fg_curs, &bg_curs);
      }

                                         /* set DTVC.INC              */
   imax = params[21];
   for (i = 0; i < 256; i++)
      params[i] = 0;
   params[0] = Ngrey;
   params[1] = NGRAPH;
   params[2] = (MAXCAT);
   params[3] = Screen_Width;
   params[4] = Screen_Height;
   params[5] = NColour - 1;
   if (using_24b) {
      params[6] = (NINTENS) - 1;
      params[7] = (FNINTENS) - 1;
      }
   else {
      params[6] = 255;
      params[7] = 255;
      }
   params[8] = 255;
   params[9] = 1;
   params[10] = 1;
   params[11] = 1 - (MAXZOOM);
   if (using_24b)
      params[12] = 4;
   else
      params[12] = 4;
   params[13] = 0;
   params[14] = 3;
   params[15] = 3;
   params[16] = 0;
   params[17] = 0;
   if (using_24b) params[17] = 1;     /* capable tv */
   params[18] = 1;         /* 1 when img catalogs here */
   params[19] = 7 * char_mult;
   params[20] = 9 * char_mult;
   params[21] = imax;                     /* TVGAMA */
   params[29] = 0;                        /* TVZOOM */
   params[30] = Screen_Width / 2;
   params[31] = Screen_Height / 2;
   params[64] = 1;                        /* TVLIMG */
   params[65] = 1;
   params[66] = 1;
   params[67] = 1;
   params[68] = x_split;
   params[69] = x_split;
   params[88] = Aips_x (sc_centre_x - sc_width2 + 1);
   params[91] = Aips_y (sc_centre_y - sc_height2 + 1);
   params[90] = Aips_x (sc_centre_x + sc_width2);
   params[89] = Aips_y (sc_centre_y + sc_height2);
   params[92] = scrhold;        /* synch */
   for (i=96; i<108; i++) params[i] = 1;  /* YBUFF(1-12) */
   params[108] = x_split;                 /* YBUFF(9-10) */
   params[109] = y_split;

   imax = CatInit ((int) 0);

   return;
}

void InitOldXAS()
{
   register int i, j, k;
   double xx, yy, zz;
   int imax, izero, bytes_row;
   short int *t1;
   unsigned char *t2;

   button_a = button_b = button_c = button_d = 0;

   rwgraph = 0;                        /* channel 1 on, graphics off */
   for (k = 0; k < 4; k++) {
      cur_chan[k] = 1;
      for (j = 0; j < 3; j++) {
         on_chan[0][j][k] = 1;
         for (i = 1; i < Ngrey; i++)
            on_chan[i][j][k] = 0;
         }
      }
   Q_same = 1;

   for (i = 0; i < Ngrey; i++)
      upleft_x[i] = upleft_y[i] = 0;

   for (i = 0; i < Ngrey; i++)          /* TV channels are off */
      TvStatus[i] = 0;

   for (i = 0; i < NGRAPH; i++)          /* Graphics channels are off */
      TvStatus[i+Ngrey] = 0;

   upleft_mag = 1;
                                        /* set OFM, Gamma = 2.2       */
   if (Gamma < 1.0) Gamma = 2.2;
   yy = 256 - 1;
   zz = 1.0 / Gamma;
   k = 0;
   for (i = 0; i < 1024; i++) {
      xx = k / yy;
      rofm[i] = gofm[i] = bofm[i] = 255 * pow (xx, zz);
      k = k + 1;
      if (k == 256) k = 0;
      }

   x_split = Screen_Width / 2;
   y_split = Screen_Height / 2;
                                        /* "zero" fill memories       */
#ifdef USE_SHM
      if ((using_shm) && (!using_24b))
         bytes_row = line->bytes_per_line;
       else
#endif /* USE_SHM */
         bytes_row = Screen_Width;
   imax = Screen_Height * bytes_row;
   izero = int2pix[0];
   for (j = 0; j < Ngrey; j++) {
      if (using_24b) {
         t1 = plane_data[j];
         for (i = 0; i < imax; i++)
            *t1++ = izero;
         }
      else {
         if (depth == 8) {
            t2 = plane_short[j];
            for (i = 0; i < imax; i++)
               *t2++ = izero;
            }
         else {
            for (i = 0; i < Screen_Width; i++) {
               for (k = 0; k < Screen_Height; k++)
                   XPutPixel (plane[j], i, k, izero);
               }
            }
         }
      }
   t2 = graph_data;
   for (i = 0; i < imax; i++)
      *t2++ = 0;
                                        /* Start up the window with a */
                                        /* linear transfer function:  */
   if (using_24b) {
      xx = 256 - 1;
      xx = xx / (256 - 1);
      for (i = 0; i < 256; i++) {
          yy = xx * i;
          rlut[0][i] = glut[0][i] = blut[0][i] =  yy + 0.5;
          if (Ngrey > 1) {
            for (j = 1; j < Ngrey; j++)
               rlut[j][i] = glut[j][i] = blut[j][i] = rlut[0][i];
            }
/*       colour_table[i].pixel = i; */
/*       colour_table[i].flags = DoRed | DoGreen | DoBlue; */
/*       colour_table[i].red = colour_table[i].green =
            colour_table[i].blue = i << COLORSHIFT; */
         }
/*    XStoreColors (display, TV_colour, colour_table, NValue+OColour);*/
      XRecolorCursor (display, cursor, &fg_curs, &bg_curs);
      }
   else {
      zz = NColour - 1;
      zz = yy / zz;
      for (i = 0; i < NValue; i++) {
         colour_table[i+OColour].pixel = int2pix[i];
         colour_table[i+OColour].flags = DoRed | DoGreen | DoBlue;
         if (i < NColour) {
            rlut[0][i] = glut[0][i] = blut[0][i] =  i * zz;
            if (Ngrey > 1) {
               for (j = 1; j < Ngrey; j++)
                  rlut[j][i] = glut[j][i] = blut[j][i] = rlut[0][i];
               }
            colour_table[i+OColour].red =
               colour_table[i+OColour].green =
               colour_table[i+OColour].blue = rofm[rlut[0][i]]
                  << COLORSHIFT;
            }
         else {
            colour_table[i+OColour].red = rgcol[i-NColour]
               << COLORSHIFT;
            colour_table[i+OColour].blue = bgcol[i-NColour]
               << COLORSHIFT;
            colour_table[i+OColour].green = ggcol[i-NColour]
               << COLORSHIFT;
            }
         }

      XStoreColors (display, TV_colour, colour_table, NValue+OColour);
      XRecolorCursor (display, cursor, &fg_curs, &bg_curs);
      }

                                         /* set DTVC.INC              */
   imax = params[21];
   for (i = 0; i < 256; i++)
      params[i] = 0;
   params[0] = Ngrey;
   params[1] = NGRAPH;
   params[2] = (MAXCAT);
   params[3] = Screen_Width;
   params[4] = Screen_Height;
   params[5] = NColour - 1;
   if (using_24b) {
      params[6] = 255;
      params[7] = 1023;
      }
   else {
      params[6] = 255;
      params[7] = 255;
      }
   params[8] = 255;
   params[9] = 1;
   params[10] = 1;
   params[11] = 1 - (MAXZOOM);
   if (using_24b)
      params[12] = 4;
   else
      params[12] = 4;
   params[13] = 0;
   params[14] = 3;
   params[15] = 3;
   params[16] = 0;
   params[17] = 0;
   if (using_24b) params[17] = 1;     /* capable tv */
   params[18] = 1;         /* 1 when img catalogs here */
   params[19] = 7 * char_mult;
   params[20] = 9 * char_mult;
   params[21] = imax;                     /* TVGAMA */
   params[29] = 0;                        /* TVZOOM */
   params[30] = Screen_Width / 2;
   params[31] = Screen_Height / 2;
   params[64] = 1;                        /* TVLIMG */
   params[65] = 1;
   params[66] = 1;
   params[67] = 1;
   params[68] = x_split;
   params[69] = x_split;
   params[88] = Aips_x (sc_centre_x - sc_width2 + 1);
   params[91] = Aips_y (sc_centre_y - sc_height2 + 1);
   params[90] = Aips_x (sc_centre_x + sc_width2);
   params[89] = Aips_y (sc_centre_y + sc_height2);
   params[92] = scrhold;        /* synch */
   for (i=96; i<108; i++) params[i] = 1;  /* YBUFF(1-12) */
   params[108] = x_split;                 /* YBUFF(9-10) */
   params[109] = y_split;

   imax = CatInit ((int) 0);

   return;
}

void user_options (argc, argv, w_n, i_n)
int argc;
char *argv[], *w_n, *i_n;
/*--------------------------------------------------------------------*/
/*   Set cursor, graphics colors reading users .Xdefaults file        */
/*   Also get the icon and window geometries from the command line or */
/*   from the .Xdefaults file.                                        */
/*--------------------------------------------------------------------*/
{
   char *option, *arg;
   char *IG, *ig, *WG, *wg, *uwg, *uig, g;
   char *BasicTV = "AIPStv";
   int mjr, mnr, pixmaps;               /* Dummy variables for SHM    */
   int i, j, xx, yy, wasi, wasw, jj;
   unsigned int ww, hh;
   long flags;
   float temp;
   char *xas_hostname, *xas_display;
   char xas_uc_disp[80];
/*--------------------------------------------------------------------*/
   ProgName = argv[0];

   cur_xcorn = cur_ycorn = ic_xcorn = ic_ycorn = -99999;
   sc_width = sc_height = 0;
   wasi = wasw = 0;

                                        /* Geometries                 */
                                        /* from Command line          */
   for (i = 1; i < argc; i++) {
      arg = argv[i];
      if (arg[0] == '-') {
         switch (arg[1]) {
            case 'I':                   /* Ig, IconGeometry           */
               if ((++i < argc) &&
                  ((arg[2] == 'g') || (arg[2] == 'c'))) {
                  IG = argv[i];
                  wasi = wasi + 1;
                  ic_pos_request = 1;
                   }
               continue;
            case 'i':                   /* ig, iconGeometry           */
               if ((++i < argc) &&
                  ((arg[2] == 'g') || (arg[2] == 'c'))) {
                  ig = argv[i];
                  wasi = wasi + 4;
                  ic_pos_request = 1;
                  }
               continue;
            case 'G':                   /* G, Geometry                */
               if (++i < argc) {
                  WG = argv[i];
                  wasw = wasw + 1;
                  }
               continue;
            case 'g':                   /* g, geometry                */
               if (++i < argc) {
                  wg = argv[i];
                  wasw = wasw + 4;
                  }
               continue;
            case 'N':                   /* N, icon name              */
            case 'n':                   /* n, icon name              */
               if (++i < argc) {
                  strcpy (i_n, argv[i]);
                  }
               continue;
            case 'T':                   /* T, window title           */
            case 't':                   /* t, window title           */
               if (++i < argc) {
                  strcpy (w_n, argv[i]);
                  }
               continue;
            default:
               continue;
            }
         }
      }
                                        /* and/or from .Xdefaults     */
   option = XGetDefault (display, BasicTV, "geometry");
   if (option) {
      wasw = wasw + 2;
      uwg = option;
      }
   option = XGetDefault (display, BasicTV, "iconGeometry");
   if (option) {
      wasi = wasi + 2;
      uig = option;
      ic_pos_request = 1;
      }
                                        /* user set number planes     */
   NgreyUser = 16;
   option = XGetDefault (display, BasicTV, "nPlanes");
   i = option ? atoi (option) : -1;
   if ((i >= 4) && (i <= 16)) NgreyUser = i;
   Ngrey = NgreyUser;
                                        /* user override screen size? */
   option = XGetDefault (display, BasicTV, "xPixels");
   i = option ? atoi (option) : -1;
   if ((i >= 128) && (i <= 16384)) Screen_Width = i;
   option = XGetDefault (display, BasicTV, "yPixels");
   i = option ? atoi (option) : -1;
   if ((i >= 128) && (i <= 16384)) Screen_Height = i;

                                        /* character size             */
   temp = (Screen_Width / 1024.0) * (Screen_Height / 1024.0);
   char_mult = sqrt (temp) + 0.5;
   if (Screen_Height < 1024) char_mult = 1;
   if (Screen_Width < 1024) char_mult = 1;
   if (char_mult < 1) char_mult = 1;
                                        /* user override char size?   */
   option = XGetDefault (display, BasicTV, "charMult");
   i = option ? atoi (option) : -1;
   if ((i >= 1) && (i <= 5)) char_mult = i;

                                        /* parse the window geometry  */
   if (wasw & 4) {
      flags = XParseGeometry (wg, &xx, &yy, &ww, &hh);
      if ((XValue & flags) && (cur_xcorn < 0)) {
         if (XNegative & flags) xx = -xx;
         if ((xx >= 0) && (xx < Screen_Width)) {
            if (XNegative & flags)
               cur_xcorn = Screen_Width + xx;
            else
               cur_xcorn = xx;
            }
         }
      if ((YValue & flags) && (cur_ycorn < 0)) {
         if (YNegative & flags) yy = -yy;
         if ((yy >= 0) && (yy < Screen_Height)) {
            if (YNegative & flags)
               cur_ycorn = Screen_Height + yy;
            else
               cur_ycorn = yy;
            }
         }
      if ((WidthValue & flags) && (sc_width <= 0)) {
         if ((ww > 0) && (ww <= Screen_Width)) sc_width = ww;
         }
      if ((HeightValue & flags) && (sc_height <= 0)) {
         if ((hh > 0) && (hh <= Screen_Height)) sc_height = hh;
         }
      }
   if (wasw & 2) {
      flags = XParseGeometry (uwg, &xx, &yy, &ww, &hh);
      if ((XValue & flags) && (cur_xcorn < 0)) {
         if (XNegative & flags) xx = -xx;
         if ((xx >= 0) && (xx < Screen_Width)) {
            if (XNegative & flags)
               cur_xcorn = Screen_Width + xx;
            else
               cur_xcorn = xx;
            }
         }
      if ((YValue & flags) && (cur_ycorn < 0)) {
         if (YNegative & flags) yy = -yy;
         if ((yy >= 0) && (yy < Screen_Height)) {
            if (YNegative & flags)
               cur_ycorn = Screen_Height + yy;
            else
               cur_ycorn = yy;
            }
         }
      if ((WidthValue & flags) && (sc_width <= 0)) {
         if ((ww > 0) && (ww <= Screen_Width)) sc_width = ww;
         }
      if ((HeightValue & flags) && (sc_height <= 0)) {
         if ((hh > 0) && (hh <= Screen_Height)) sc_height = hh;
         }
      }
   if (wasw & 1) {
      flags = XParseGeometry (WG, &xx, &yy, &ww, &hh);
      if ((XValue & flags) && (cur_xcorn < 0)) {
         if (XNegative & flags) xx = -xx;
         if ((xx >= 0) && (xx < Screen_Width)) {
            if (XNegative & flags)
               cur_xcorn = Screen_Width + xx;
            else
               cur_xcorn = xx;
            }
         }
      if ((YValue & flags) && (cur_ycorn < 0)) {
         if (YNegative & flags) yy = -yy;
         if ((yy >= 0) && (yy < Screen_Height)) {
            if (YNegative & flags)
               cur_ycorn = Screen_Height + yy;
            else
               cur_ycorn = yy;
            }
         }
      if ((WidthValue & flags) && (sc_width <= 0)) {
         if ((ww > 0) && (ww <= Screen_Width)) sc_width = ww;
         }
      if ((HeightValue & flags) && (sc_height <= 0)) {
         if ((hh > 0) && (hh <= Screen_Height)) sc_height = hh;
         }
      }

   if (sc_width <= 0) sc_width = 518;
   if (sc_height <= 0) sc_height = 518;
   cur_xcorn = max (0, cur_xcorn);
   cur_ycorn = max (0, cur_ycorn);
   if (cur_xcorn >= Screen_Width) cur_xcorn = twidth - SCREEN_RIGHT
      + Screen_Width - cur_xcorn - sc_width;
   if (cur_ycorn >= Screen_Height) cur_ycorn = theight - SCREEN_BOTTOM
      + Screen_Height - cur_ycorn - sc_height;
   cur_xcorn = cur_xcorn + SCREEN_LEFT;
   cur_ycorn = cur_ycorn + SCREEN_TOP;
   cur_xcorn = min (cur_xcorn, twidth - SCREEN_RIGHT - sc_width);
   cur_ycorn = min (cur_ycorn, theight - SCREEN_BOTTOM - sc_height);
   if (XasDebug) fprintf (stderr,"Initial window w,h,x,y %d %d %d %d\n",
      sc_width, sc_height, cur_xcorn, cur_ycorn);
                                        /* parse the icon geometry    */
   if (wasi & 4) {
      flags = XParseGeometry (ig, &xx, &yy, &ww, &hh);
      if ((XValue & flags) && (ic_xcorn < 0)) {
         if (XNegative & flags) xx = -xx;
         if ((xx >= 0) && (xx < twidth)) {
            if (XNegative & flags)
               ic_xcorn = twidth + xx;
            else
               ic_xcorn = xx;
            }
         }
      if ((YValue & flags) && (ic_ycorn < 0)) {
         if (YNegative & flags) yy = -yy;
         if ((yy >= 0) && (yy < theight)) {
            if (YNegative & flags)
               ic_ycorn = theight + yy;
            else
               ic_ycorn = yy;
            }
         }
      }
   if (wasi & 2) {
      flags = XParseGeometry (uig, &xx, &yy, &ww, &hh);
      if ((XValue & flags) && (ic_xcorn < 0)) {
         if (XNegative & flags) xx = -xx;
         if ((xx >= 0) && (xx < twidth)) {
            if (XNegative & flags)
               ic_xcorn = twidth + xx;
            else
               ic_xcorn = xx;
            }
         }
      if ((YValue & flags) && (ic_ycorn < 0)) {
         if (YNegative & flags) yy = -yy;
         if ((yy >= 0) && (yy < theight)) {
            if (YNegative & flags)
               ic_ycorn = theight + yy;
            else
               ic_ycorn = yy;
            }
         }
      }
   if (wasi & 1) {
      flags = XParseGeometry (IG, &xx, &yy, &ww, &hh);
      if ((XValue & flags) && (ic_xcorn < 0)) {
         if (XNegative & flags) xx = -xx;
         if ((xx >= 0) && (xx < twidth)) {
            if (XNegative & flags)
               ic_xcorn = twidth + xx;
            else
               ic_xcorn = xx;
            }
         }
      if ((YValue & flags) && (ic_ycorn < 0)) {
         if (YNegative & flags) yy = -yy;
         if ((yy >= 0) && (yy < theight)) {
            if (YNegative & flags)
               ic_ycorn = theight + yy;
            else
               ic_ycorn = yy;
            }
         }
      }

   if (ic_xcorn < 0) ic_xcorn = twidth;
   ic_ycorn = max (0, ic_ycorn);
   if (ic_xcorn >= twidth)
      ic_xcorn = 2 * twidth - ic_xcorn - ic_width;
   if (ic_ycorn >= theight)
      ic_ycorn = 2 * theight - ic_ycorn - ic_height;
   ic_xcorn = min (ic_xcorn, twidth - ic_width);
   ic_ycorn = min (ic_ycorn, theight - ic_height);
   if (XasDebug) fprintf (stderr, "Initial icon w,h,x,y %d %d %d %d\n",
      ic_width, ic_height, ic_xcorn, ic_ycorn);
                                        /* ONLY from .Xdefaults       */
                                        /* cursor shape               */
                                        /* 34 => XC_crosshair         */
   option = XGetDefault (display, BasicTV, "cursorShape");
   i = option ? atoi (option) : -1;
   cursor_shape = ((i >= 0) && (i <= 154)) ? i : 34;
   cursor_shape = (cursor_shape / 2) * 2;
                                        /* gamma                      */
   option = XGetDefault (display, BasicTV, "gamma");
   i = option ? atoi (option) : -1;
   Gamma = ((i > 100) && (i < 1000)) ? i/100.0 : 2.2 ;
                                        /* cursor colours             */
   option = XGetDefault (display, BasicTV, "cursorR");
   i = option ? atoi (option) : -1;
   rgrfx[0] = ((i >= 0) && (i <= 255)) ? i : 255;
   option = XGetDefault (display, BasicTV, "cursorG");
   i = option ? atoi (option) : -1;
   ggrfx[0] = ((i >= 0) && (i <= 255)) ? i : 0;
   option = XGetDefault (display, BasicTV, "cursorB");
   i = option ? atoi (option) : -1;
   bgrfx[0] = ((i >= 0) && (i <= 255)) ? i : 255;
                                        /* graphics colours           */
   option = XGetDefault (display, BasicTV, "graphics1R");
   i = option ? atoi (option) : -1;
   rgrfx[1] = ((i >= 0) && (i <= 255)) ? i : 255;
   option = XGetDefault (display, BasicTV, "graphics1G");
   i = option ? atoi (option) : -1;
   ggrfx[1] = ((i >= 0) && (i <= 255)) ? i : 255;
   option = XGetDefault (display, BasicTV, "graphics1B");
   i = option ? atoi (option) : -1;
   bgrfx[1] = ((i >= 0) && (i <= 255)) ? i : 0;
   option = XGetDefault (display, BasicTV, "graphics2R");
   i = option ? atoi (option) : -1;
   rgrfx[2] = ((i >= 0) && (i <= 255)) ? i : 16;
   option = XGetDefault (display, BasicTV, "graphics2G");
   i = option ? atoi (option) : -1;
   ggrfx[2] = ((i >= 0) && (i <= 255)) ? i : 255;
   option = XGetDefault (display, BasicTV, "graphics2B");
   i = option ? atoi (option) : -1;
   bgrfx[2] = ((i >= 0) && (i <= 255)) ? i : 0;
   option = XGetDefault (display, BasicTV, "graphics3R");
   i = option ? atoi (option) : -1;
   rgrfx[3] = ((i >= 0) && (i <= 255)) ? i : 255;
   option = XGetDefault (display, BasicTV, "graphics3G");
   i = option ? atoi (option) : -1;
   ggrfx[3] = ((i >= 0) && (i <= 255)) ? i : 171;
   option = XGetDefault (display, BasicTV, "graphics3B");
   i = option ? atoi (option) : -1;
   bgrfx[3] = ((i >= 0) && (i <= 255)) ? i : 255;
   option = XGetDefault (display, BasicTV, "graphics4R");
   i = option ? atoi (option) : -1;
   rgrfx[4] = ((i >= 0) && (i <= 255)) ? i : 0;
   option = XGetDefault (display, BasicTV, "graphics4G");
   i = option ? atoi (option) : -1;
   ggrfx[4] = ((i >= 0) && (i <= 255)) ? i : 255;
   option = XGetDefault (display, BasicTV, "graphics4B");
   i = option ? atoi (option) : -1;
   bgrfx[4] = ((i >= 0) && (i <= 255)) ? i : 255;
   option = XGetDefault (display, BasicTV, "graphics5R");
   i = option ? atoi (option) : -1;
   rgrfx[5] = ((i >= 0) && (i <= 255)) ? i : 255;
   option = XGetDefault (display, BasicTV, "graphics5G");
   i = option ? atoi (option) : -1;
   ggrfx[5] = ((i >= 0) && (i <= 255)) ? i : 45;
   option = XGetDefault (display, BasicTV, "graphics5B");
   i = option ? atoi (option) : -1;
   bgrfx[5] = ((i >= 0) && (i <= 255)) ? i : 45;
   option = XGetDefault (display, BasicTV, "graphics6R");
   i = option ? atoi (option) : -1;
   rgrfx[6] = ((i >= 0) && (i <= 255)) ? i : 153;
   option = XGetDefault (display, BasicTV, "graphics6G");
   i = option ? atoi (option) : -1;
   ggrfx[6] = ((i >= 0) && (i <= 255)) ? i : 153;
   option = XGetDefault (display, BasicTV, "graphics6B");
   i = option ? atoi (option) : -1;
   bgrfx[6] = ((i >= 0) && (i <= 255)) ? i : 255;
   option = XGetDefault (display, BasicTV, "graphics7R");
   i = option ? atoi (option) : -1;
   rgrfx[7] = ((i >= 0) && (i <= 255)) ? i : 255;
   option = XGetDefault (display, BasicTV, "graphics7G");
   i = option ? atoi (option) : -1;
   ggrfx[7] = ((i >= 0) && (i <= 255)) ? i : 204;
   option = XGetDefault (display, BasicTV, "graphics7B");
   i = option ? atoi (option) : -1;
   bgrfx[7] = ((i >= 0) && (i <= 255)) ? i : 102;
   option = XGetDefault (display, BasicTV, "graphics8R");
   i = option ? atoi (option) : -1;
   rgrfx[8] = ((i >= 0) && (i <= 63)) ? i : 0;
   option = XGetDefault (display, BasicTV, "graphics8G");
   i = option ? atoi (option) : -1;
   ggrfx[8] = ((i >= 0) && (i <= 63)) ? i : 0;
   option = XGetDefault (display, BasicTV, "graphics8B");
   i = option ? atoi (option) : -1;
   bgrfx[8] = ((i >= 0) && (i <= 63)) ? i : 0;
                                        /* make cross colors          */
   crscol (rgrfx, rgcol);
   crscol (ggrfx, ggcol);
   crscol (bgrfx, bgcol);

   using_shm = 0;
#ifdef USE_SHM
                                       /* Find out whether the user   */
                                       /* Wants to use shared memory  */
   option = XGetDefault (display, BasicTV, "useSharedMemory");
   using_shm = option ? atoi (option) : 1;
                                       /* Before asking, see if the   */
                                       /* connection is local/remote  */
   xas_hostname = getenv("HOST");
   xas_display  = getenv("DISPLAY");
                                       /* convert display host to uc */

   jj = strlen (xas_display);
   for (i = 0; (i < jj) && (xas_display[i] != ':'); i++)
      xas_uc_disp[i] = toupper (xas_display[i]);
   xas_uc_disp[i] = '\0';

                                       /* now for non-blank display, */
                                       /* compare hostname */
                                       /* Not Leopard, uses a named pipe*/
                                       /* in /tmp for X11 DISPLAY */

   if (xas_uc_disp[0] != '\0') {
      if (strcmp(xas_hostname, xas_uc_disp) != 0 &&
	  strncmp(xas_uc_disp, "/TMP", 4) != 0 &&
	  strncmp(xas_uc_disp, "/PRIVATE/TMP", 12) != 0) {
         fprintf (stderr,
            "XAS: Cannot use shared memory on remote XAS link\n");
	 fprintf (stderr,
	    "Host name is %s, display shows it at %s\n",
             xas_hostname, xas_uc_disp);
         using_shm=0;
      }
   }
                                       /* Find out whether the shared */
                                       /* memory extension is         */
                                       /* available:                  */
   if (using_shm) {
      using_shm = XShmQueryVersion (display, &mjr, &mnr, &pixmaps);
      if (!using_shm)
         fprintf (stderr, "XAS: @@@ Shared memory not available @@@\n");
      else
         fprintf (stderr,
            "XAS: ***  Using shared memory option for speed ***\n");
      }
   else
      fprintf (stderr, "XAS: !!! Shared memory not selected !!!\n");
#endif

                                       /* limit intensities ? */
   if (!using_24b) {
      option = XGetDefault (display, BasicTV, "maxGreyLevel");
      xx = 1 << depth;
      xx = min (xx, 256) - 1;
      xx = xx - NGRPHCOL - 2;   i = NColour - 1;
      j = option ? atoi (option) : i;
      j = min (xx, j);
      if (j != i) {
         NColour = j + 1;
         NValue = NColour + NGRPHCOL;
         }
      }
                                       /* limit scrwrt delay          */
   option = XGetDefault (display, BasicTV, "maxCommDelay");
   Maxhold = option ? atoi (option) : 16384;
   if (Maxhold != 16384)
      fprintf (stderr, "XAS: Max commands delayed = %d\n", Maxhold);

   return;
} /* end user_options */
--XYZZY--
cat > Makefile << "--XYZZY--"
# Makefile for xas
#-----------------------------------------------------------------------
#;  Copyright (C) 1995-2000, 2002-2003, 2005-2006, 2009, 2016-2017,
#;  Copyright (C) 2019, 2022, 2024, 2026
#;  Associated Universities, Inc. Washington DC, USA.
#;
#;  This program is free software; you can redistribute it and/or
#;  modify it under the terms of the GNU General Public License as
#;  published by the Free Software Foundation; either version 2 of
#;  the License, or (at your option) any later version.
#;
#;  This program is distributed in the hope that it will be useful,
#;  but WITHOUT ANY WARRANTY; without even the implied warranty of
#;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#;  GNU General Public License for more details.
#;
#;  You should have received a copy of the GNU General Public
#;  License along with this program; if not, write to the Free
#;  Software Foundation, Inc., 675 Massachusetts Ave, Cambridge,
#;  MA 02139, USA.
#;
#;  Correspondence concerning AIPS should be addressed as follows:
#;         Internet email: aipsmail@nrao.edu.
#;         Postal address: AIPS Project Office
#;                         National Radio Astronomy Observatory
#;                         520 Edgemont Road
#;                         Charlottesville, VA 22903-2475 USA
#-----------------------------------------------------------------------
#
# This makefile has been tested on the following:
# baboon    - Sun SparcStation 2, SunOS 4.1.2, SC2.0.1 compilers
# kochab    - Sun SparcStation 10, SunOS 5.5, SC4.2 compilers
# rhesus    - IBM RS/6000 model 580 (AIX 3.2.5)
# siamang   - Dec Alpha 266, OSF-1 4.0D
# ohsumi    - SGI, SG-Irix 6.4
# orangutan - Pentium Pro 200, Red Hat 5, Kernel 2.0.34 (egcs 1.0.3)
# mandrill  - Alpha 21164 clone, Red Hat 5, Kernel 2.0.34 (egcs 1.0.3)
#    contains commented out MACINT lines for gcc
#
# (old note for VMS, xas.h must be modified to define VMS as 1)

#   Destination for executable.  If you are building XAS on a system
#   that has AIPS installed this should be the same as the AIPS LOAD
#   area.  MAKE SURE "LOAD" IS DEFINED FIRST!!!!!  INSTEP1 should take
#   care of this, but otherwise it is done with "source LOGIN.CSH"
#   (c-shell) or ". LOGIN.SH" (bash, korn, bourne shells).
#   Most implementations of make allow the use of an environmental
#   variable as shown here: check your system documentation.

DESTDIR = $(LOAD)

#   Additional include files.  Some X Window System implementations do
#   not place their include in the standard Unix directory /usr/include.
#   The include directories should be listed here, each preceded by -I.
#   For Sun, make sure OPENWINHOME is set!  (/usr/openwin usually)

INCDIRS_ALPHA    =
INCDIRS_DEC      =
INCDIRS_IBM      =
INCDIRS_LINUX    =
INCDIRS_LNX64    =
INCDIRS_AXLINUX  =
INCDIRS_LINUXPPC =
INCDIRS_MACPPC   = -I/usr/X11R6/include
INCDIRS_MACINT   = -I/usr/X11/include
INCDIRS_MACARM   = -I/usr/X11/include
INCDIRS_HP       = -I/usr/include/X11R5
INCDIRS_HP2      = -I/usr/include/X11R5
INCDIRS_SGI      =
INCDIRS_SOL      = -I$(OPENWINHOME)/include
INCDIRS_SOL86    = -I$(OPENWINHOME)/include
INCDIRS_SUL      = -I$(OPENWINHOME)/include
INCDIRS_SUN4     = -I$(OPENWINHOME)/include

INCDIRS = $(INCDIRS_$(ARCH))

#   Library search path.  Standard Unix libraries are usually found in
#   /usr/lib; some X Window System implementations place their libraries
#   elsewhere.  These should be listed here, each preceded by -L.
#   IBM-SHR is for IBM systems shared memory.

LIBDIRS_ALPHA    = -L/usr/lib/X11
LIBDIRS_DEC      = -L/usr/lib/X11
LIBDIRS_HP       = -L/usr/lib/X11R5
LIBDIRS_HP2      = -L/usr/lib/X11R5
# For AIX 3.2.2 or earlier, use LIBDIRS_IBM = -L/usr/lpp/X11/Xamples/lib
#  if you have set up the X server to use MIT SHM shared memory.
LIBDIRS_IBM      =
# This should work for most Linux distributions.  The really old version
# of this was /usr/X386/lib which dates from the old SLS days.
LIBDIRS_LINUX    = -L/usr/X11R6/lib
LIBDIRS_LNX64    = -L/usr/X11R6/lib64
#LIBDIRS_LNX64    = -L/usr/X11R6/lib64 -Xlinker -rpath -Xlinker $(LIBR)/INTELCMP
#   on Intel compiler we use
#LIBDIRS_LINUX    = -L/usr/X11R6/lib -Xlinker -rpath -Xlinker $(LIBR)/INTELCMP
LIBDIRS_AXLINUX  = -L/usr/X11R6/lib
LIBDIRS_LINUXPPC = -L/usr/X11R6/lib
LIBDIRS_MACINT   = -L/usr/X11/lib -L/opt/local/lib
LIBDIRS_MACARM   = -L/usr/X11/lib -L/opt/local/lib
LIBDIRS_MACPPC   = -L/usr/X11R6/lib
LIBDIRS_SGI      =
# If you change LIBDIRS_SOL, make sure to change LOCALOPTS_SOL (-R argument)
LIBDIRS_SOL      = -L$(OPENWINHOME)/lib
LIBDIRS_SOL86    = -L$(OPENWINHOME)/lib
LIBDIRS_SUL      = -L$(OPENWINHOME)/lib
LIBDIRS_SUN4     = -L$(OPENWINHOME)/lib

LIBDIRS = $(LIBDIRS_$(ARCH))

#   In addition, there are apparently different requirements for
#   standard low-level libraries on the various systems and different
#   intolerance/requirement to include a library twice.

STDLIBS_ALPHA  	 =
STDLIBS_DEC    	 =
STDLIBS_HP     	 =
STDLIBS_HP2    	 =
STDLIBS_IBM    	 =
# for AIX 3.2.2 or earlier, set STDLIBS_IBM =-lXextSam
#  if you have set up the X server to use MIT SHM shared memory.
STDLIBS_LINUX  	 =
STDLIBS_LNX64  	 =
STDLIBS_AXLINUX  =
STDLIBS_LINUXPPC =
STDLIBS_MACPPC   =
STDLIBS_MACINT   =
STDLIBS_MACARM   =
STDLIBS_SGI    	 =
STDLIBS_SOL    	 =  -lsocket -lnsl  -R$(OPENWINHOME)/lib
STDLIBS_SOL86  	 =  -lsocket -lnsl  -R$(OPENWINHOME)/lib
STDLIBS_SUL    	 =  -lsocket -lnsl  -R$(OPENWINHOME)/lib
STDLIBS_SUN4   	 =  -lXext


STDLIBS = $(STDLIBS_$(ARCH))

#   The X Shared Memory Extension can significantly improve the
#   performance of XAS.  Depending on whether your X server supports
#   these (xdpyinfo should show it as MIT_SHM under the extensions
#   section), you may want to preserve  the OSOPTS_(architecture) value
#   below, or remove the -DUSE_SHM if it doesn't seem to work.  IBM X11
#   servers do not have it enabled by default but the X server can be
#   rebuilt to include it for AIX 3.2.2 or earlier versions

OSOPTS_ALPHA    = -D_BSD -DUSE_SHM
OSOPTS_DEC      = -D_BSD -DUSE_SHM
OSOPTS_HP       = -D_BSD -DUSE_SHM
OSOPTS_HP2      = -D_BSD -DUSE_SHM
OSOPTS_IBM      = -D_AIX -D_BSD
OSOPTS_LINUX    = -D_BSD -DUSE_SHM
OSOPTS_LNX64    = -D_BSD -DUSE_SHM
OSOPTS_AXLINUX  = -D_BSD -DUSE_SHM
OSOPTS_LINUXPPC = -D_BSD -DUSE_SHM
OSOPTS_MACPPC   = -D_BSD -DUSE_SHM
OSOPTS_MACINT   = -D_BSD -D_DARWIN_UNLIMITED_SELECT=1
OSOPTS_MACARM   = -D_BSD -D_DARWIN_UNLIMITED_SELECT=1
OSOPTS_SGI      = -D_BSD -DUSE_SHM
OSOPTS_SOL      = -D_BSD -DUSE_SHM
OSOPTS_SOL86    = -D_BSD -DUSE_SHM
OSOPTS_SUL      = -D_BSD -DUSE_SHM
OSOPTS_SUN4     = -D_BSD -DUSE_SHM

# XAS still works on some VMS platforms... OSOPTS_VMS     = -D_VMS

OSOPTS = $(OSOPTS_$(ARCH))

# Add local compiler/linker options here.  The -R under Solaris makes sure
# the library area used in LIBDIRS_SOL gets burned into the resulting
# binary.

LOCALOPTS_ALPHA    =
LOCALOPTS_DEC      =
LOCALOPTS_HP       =
LOCALOPTS_HP2      =
LOCALOPTS_IBM      =
LOCALOPTS_LINUX    = -O2
#LOCALOPTS_LNX64    = -O2 -axWPT
#LOCALOPTS_LNX64    = -O3 -ip -I -D_FILE_OFFSET_BITS=64 -DHAVE_LINUX_GLIBC
LOCALOPTS_LNX64    = -O3 -fomit-frame-pointer -funroll-loops -D_FILE_OFFSET_BITS=64 -DHAVE_LINUX_GLIBC -fcommon
#                                       Intel compiler
# LOCALOPTS_LINUX    = -O2 -axNP
LOCALOPTS_AXLINUX  = -O2
LOCALOPTS_LINUXPPC = -O2
LOCALOPTS_MACPPC   = -O2
#  LOCALOPTS_MACINT = -O3 -mmacosx-version-min=10.7
LOCALOPTS_MACINT   = -O3 -fomit-frame-pointer -funroll-loops -D_FILE_OFFSET_BITS=64 -mmacosx-version-min=10.10
LOCALOPTS_MACARM   = -O3 -fomit-frame-pointer -funroll-loops -D_FILE_OFFSET_BITS=64 -mmacosx-version-min=11.0 -fcommon
LOCALOPTS_SGI      =
# remove the -K PIC and -Xa if you are not using the Sun C compiler.
LOCALOPTS_SOL      = -O -v -K PIC -Xa
LOCALOPTS_SUL      = -O -v -K PIC -Xa
# The following good for Pentium or better. Use -m486 for 80486.
LOCALOPTS_SOL86    = -O2 -mpentium
LOCALOPTS_SUN4     =

LOCALOPTS = $(LOCALOPTS_$(ARCH))

# The C compiler, whatever works for you.

CC_SOL      = /opt/SUNWspro/bin/cc
CC_SOL86    = gcc
CC_SUL      = /opt/SUNWspro/bin/cc
CC_SUN4     = /usr/lang/cc
CC_ALPHA    = cc
CC_IBM      = cc
CC_LINUX    = gcc
#CC_LNX64    = /opt/intel/Compiler/11.0/074/bin/intel64/icc
#CC_LNX64    = /opt/intel/bin/icc
CC_LNX64    = /usr/bin/gcc
CC_AXLINUX  = gcc
CC_LINUXPPC = gcc
CC_MACPPC   = /usr/bin/gcc
#  CC_MACINT   = /usr/local/bin/icc
CC_MACINT   = /usr/bin/gcc
CC_MACARM   = /usr/bin/gcc
CC_HP       = cc
CC_HP2      = cc
CC_DEC      = cc
CC_SGI      = cc

CC = $(CC_$(ARCH))

#    Do not alter anything below this line
#--------------------------------------------------------------------

CCOPTS = $(INCDIRS) $(OSOPTS) $(LOCALOPTS) -c

OBJECTS = xas.o image.o comm.o cursor.o screen.o init.o colors.o catalog.o

.c.o :
	$(CC) $(CCOPTS) $<

install : xas
	touch $(DESTDIR)/XAS
	mv $(DESTDIR)/XAS $(DESTDIR)/XAS.OLD
	mv xas $(DESTDIR)/XAS

all:
	@ echo 'First make xas, then make install, then make clean'

xas : $(OBJECTS)
	$(CC) $(LIBDIRS) $(LOCALOPTS) $(OSOPTS) $(OBJECTS) -lXext -lX11 -lm $(STDLIBS) -o xas

xas.o   : xas.c    xas.h

image.o : image.c  xas.h

comm.o  : comm.c   xas.h

cursor.o: cursor.c xas.h

screen.o: screen.c xas.h

init.o  : init.c   xas.h  Xas.icon  Xas2.icon

colors.o: colors.c xas.h

catalog.o: catalog.c xas.h

clean:
	rm -f *.o xas XAS

--XYZZY--
cat > Makefile.DEC << "--XYZZY--"
# Makefile for xas

#   This makefile is a stripped down version of the generic Makefile for
#   XAS specifically for Ultrix.  It has been tested under Ultrix 4.3.
#
#   Destination for executable.  If you are building XAS on a
#   system that has AIPS installed this should be the same as
#   the AIPS LOAD area.  MAKE SURE "LOAD" IS DEFINED FIRST!!!!!
#   Usually this is done with "source LOGIN.CSH" or ". LOGIN.SH".
#   Some implementations of make allow the use of an environmental
#   variable as shown here: check your system documentation.
DESTDIR = $(LOAD)

#   Additional include files.  Some X Window System
#   implementations do not place their include in the standard
#   Unix directory /usr/include.  The include directories should
#   be listed here, each preceded by -I.
INCDIRS    = -I/usr/include/X11

#   Library search path.  Standard Unix libraries are usually found in
#   /usr/lib; some X Window System implementations place their libraries
#   elsewhere.  These should be listed here, each preceded by -L.
LIBDIRS    = -L/usr/lib/X11

#   The X Shared Memory Extension can significantly improve the
#   performance of XAS.  If you have the X Shared Memory
#   extension and your version of Unix supports shared memory
#   segments leave the following  definition as it is, otherwise
#   set the value to blank.
SHMOPT = -DUSE_SHM

#    Add OS-dependent options used inside XAS
#    On IBM    : OSOPTS = -D_AIX -D_BSD
#    On VMS    : OSOPTS = -D_VMS
#    On Unix   : OSOPTS = -D_BSD
OSOPTS = -D_BSD

#    Add local compiler/linker options here.
LOCALOPTS = -O

#    Your favourite C compiler
#    for Gnu C : CC=gcc
CC=cc

#    Do not alter anything below this line
#--------------------------------------------------------------------

.c.o :
	$(CC) $(CCOPTS) $<

CCOPTS = $(INCDIRS) $(SHMOPT) $(OSOPTS) $(LOCALOPTS) -c

OBJECTS = xas.o image.o comm.o cursor.o screen.o init.o colors.o catalog.o

install : xas
	mv xas $(DESTDIR)/XAS

all :
	@ echo 'First make xas, then make install, then make clean'

xas : $(OBJECTS)
	$(CC) $(LIBDIRS) $(LOCALOPTS) $(OSOPTS) $(OBJECTS) -lXext -lX11 -lm $(STDLIBS) -o xas

xas.o   : xas.c    xas.h

image.o : image.c  xas.h

comm.o  : comm.c   xas.h

cursor.o: cursor.c xas.h

screen.o: screen.c xas.h

init.o  : init.c   xas.h  Xas.icon

colors.o: colors.c xas.h

catalog.o: catalog.c xas.h

clean:
	rm -f *.o xas XAS

--XYZZY--
cat > Makefile.old << "--XYZZY--"
# Makefile for xas

#   This makefile has been tested on the following systems:
#   baboon   - Sun SparcStation 2, SunOS 4.1.2
#   rhesus   - IBM RS/6000 model 560 (AIX 3.2.2, MIT-SHM added)
#   bonobo   - Decstation 3100, Ultrix 4.0
#   pongo    - Dec Alpha AXP 3000/300, OSF-1/1.2
#   hpdemo   - HP 9000/755, HP-UX A.09.01 (X11R5)
#   tamarin  - Sun SparcStation LX, SunOS 5.2
#   tarsier  - Gateway 2000 486DX2/66 PC, Linux 0.99.12
#
#   The different settings for each architecture is indicated
#   in the comments.
#   Note for VMS, xas.h must be modified to define VMS as 1
#
#   Destination for executable.  If you are building XAS on a
#   system that has AIPS installed this should be the same as
#   the AIPS LOAD area.  MAKE SURE "LOAD" IS DEFINED FIRST!!!!!
#   Usually this is done with "source LOGIN.CSH" or ". LOGIN.SH".
#   Some implementations of make allow the use of an environmental
#   variable as shown here: check your system documentation.
DESTDIR = $(LOAD)

#   Additional include files.  Some X Window System
#   implementations do not place their include in the standard
#   Unix directory /usr/include.  The include directories should
#   be listed here, each preceded by -I.
#   On SUN4   : INCDIRS    = -I$(OPENWINHOME)/include
#   On SOL    : INCDIRS    = -I$(OPENWINHOME)/include
#   (cv sun's): INCDIRS    = -I/usr/local/include
#   On IBM    : INCDIRS    = -I/usr/include/X11
#   On HP     : INCDIRS    = -I/usr/include/X11R5
#   On DEC    : INCDIRS    = -I/usr/include/X11
#   On ALPHA  : INCDIRS    = -I/usr/include/X11
#   On LINUX  : INCDIRS    = -I/usr/include/X11
INCDIRS    = -I$(OPENWINHOME)/include

#   Library search path.  Standard Unix libraries are usually found in
#   /usr/lib; some X Window System implementations place their libraries
#   elsewhere.  These should be listed here, each preceded by -L.
#   IBM-SHR is for IBM systems shared memory.
#   On SUN4   : LIBDIRS    = -L$(OPENWINHOME)/lib
#   On SOL    : LIBDIRS    = -L$(OPENWINHOME)/lib
#   On IBM    : LIBDIRS    =
#   On IBM-SHR: LIBDIRS    = -L/usr/lpp/X11/Xamples/lib
#   On DEC    : LIBDIRS    = -L/usr/lib/X11
#   On ALPHA  : LIBDIRS    = -L/usr/lib/X11
#   On HP     : LIBDIRS    = -L/usr/lib/X11R5
#   On LINUX  : LIBDIRS    = -L/usr/X386/lib
LIBDIRS    = -L$(OPENWINHOME)/lib

#   In addition, there are apparently different requirements for
#   standard low-level libraries on the various systems and different
#   intolerance/requirement to include a library twice.
#   On SunOS 4.2 : STDLIBS  =  -lXext
#   On Solaris   : STDLIBS  =  -lsocket
#   On IBM (SHM) : STDLIBS  =  -lXextSam
STDLIBS  =  -lXext

#   The X Shared Memory Extension can significantly improve the
#   performance of XAS.  If you have the X Shared Memory
#   extension and your version of Unix supports shared memory
#   segments leave the following  definition as it is, otherwise
#   set the value to blank.  IBM X11 servers do not have it enabled
#   by default but the X server can be rebuilt to include it.
#   SHMOPT = -DUSE_SHM
#   SHMOPT =
SHMOPT =  -DUSE_SHM

#    Add OS-dependent options used inside XAS
#    On IBM    : OSOPTS = -D_AIX -D_BSD
#    On VMS    : OSOPTS = -D_VMS
#    On Unix   : OSOPTS = -D_BSD
OSOPTS = -D_BSD

#    Add local compiler/linker options here.  For example Sun 3s
#    will require a -f option to specify the floating point
#    hardware option.
#    On Debug  : LOCALOPTS = -g
#    Default   : LOCALOPTS = -O
#    On SOL    : LOCALOPTS = -O -v -K PIC -Xa
LOCALOPTS = -O

#    Your favourite C compiler
#    On SOL    : CC=/opt/SUNWspro/bin/cc
#    On SUN4   : CC=/usr/lang/cc
#    for Gnu C : CC=gcc
CC=cc

#    Do not alter anything below this line
#--------------------------------------------------------------------

.c.o :
	$(CC) $(CCOPTS) $<

CCOPTS = $(INCDIRS) $(SHMOPT) $(OSOPTS) $(LOCALOPTS) -c

OBJECTS = xas.o image.o comm.o cursor.o screen.o init.o colors.o catalog.o

install : $(DESTDIR)/XAS

$(DESTDIR)/XAS : xas
	mv xas $(DESTDIR)/XAS

all : xas

xas : $(OBJECTS)
	$(CC) $(LIBDIRS) $(LOCALOPTS) $(OBJECTS) -lXext -lX11 -lm $(STDLIBS) -o xas

xas.o   : xas.c    xas.h

image.o : image.c  xas.h

comm.o  : comm.c   xas.h

cursor.o: cursor.c xas.h

screen.o: screen.c xas.h

init.o  : init.c   xas.h  Xas.icon

colors.o: colors.c xas.h

catalog.o: catalog.c xas.h
--XYZZY--
cat > screen.c << "--XYZZY--"
/*--------------------------------------------------------------------*/
/*! XAS screen drawing package                                        */
/*# TV-IO                                                             */
/*--------------------------------------------------------------------*/
/*;  Copyright (C) 1995-2003, 2008-2009                               */
/*;  Associated Universities, Inc. Washington DC, USA.                */
/*;                                                                   */
/*;  This program is free software; you can redistribute it and/or    */
/*;  modify it under the terms of the GNU General Public License as   */
/*;  published by the Free Software Foundation; either version 2 of   */
/*;  the License, or (at your option) any later version.              */
/*;                                                                   */
/*;  This program is distributed in the hope that it will be useful,  */
/*;  but WITHOUT ANY WARRANTY; without even the implied warranty of   */
/*;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    */
/*;  GNU General Public License for more details.                     */
/*;                                                                   */
/*;  You should have received a copy of the GNU General Public        */
/*;  License along with this program; if not, write to the Free       */
/*;  Software Foundation, Inc., 675 Massachusetts Ave, Cambridge,     */
/*;  MA 02139, USA.                                                   */
/*;                                                                   */
/*;  Correspondence concerning AIPS should be addressed as follows:   */
/*;         Internet email: aipsmail@nrao.edu.                        */
/*;         Postal address: AIPS Project Office                       */
/*;                         National Radio Astronomy Observatory      */
/*;                         520 Edgemont Road                         */
/*;                         Charlottesville, VA 22903-2475 USA        */
/*--------------------------------------------------------------------*/

#include "xas.h"

int scrwrt (xs, ys, xe, ye)
/*--------------------------------------------------------------------*/
/* Draws from memory image to the screen taking account of zoom,      */
/* scroll and window offsets etc. Updates that rectangle enclosed by  */
/* xs, ys, xe, ye.  Dimensions are screen units.                      */
/*--------------------------------------------------------------------*/
   int xs, ys, xe, ye;
/*--------------------------------------------------------------------*/
{
   int qq, xl, xr, yl, yu;

   if (scrhold) {
      uxs = min (xs, uxs);
      uys = min (ys, uys);
      uxe = max (xe, uxe);
      uye = max (ye, uye);
      numhold = numhold + 1;
      if (numhold <= Maxhold) return (0) ;
      xs = uxs;
      ys = uys;
      xe = uxe;
      ye = uye;
      uxs = Screen_Width;
      uxe = 0;
      uys = Screen_Height;
      uye = 0;
      }

   qq = 0;

   if (Q_same)
      scrdo (qq, xs, ys, xe, ye);
   else {
      if (XasDebug) fprintf (stderr,
         "SCRWRT xs,ys,xe,ye,x/ysplit %d %d %d %d %d %d\n",
         xs, ys, xe, ye, x_split, y_split);
      if ((xs <= x_split-1) && (ys + y_split <= Screen_Height)) {
         qq = 1;
         xl = x_split + xs ;
         xr = x_split + xe ;
         xl = Screen_Width - x_split + xs;
         xr = Screen_Width - x_split + xe;
         xr = min (xr, Screen_Width-1);
         yl = y_split + ys;
         yu = min (Screen_Height-1, y_split + ye);
         scrdo (qq, xl, yl, xr, yu);
         }
      if ((xe >= x_split) && (ys + y_split <= Screen_Height)) {
         qq = 0;
         xl = max (0, xs + x_split - Screen_Width) ;
         xr = max (0, xe + x_split - Screen_Width) ;
         xl = max (0, xs-x_split+1);
         xr = xe - x_split;
         yl = y_split + ys;
         yu = min (Screen_Height-1, y_split + ye);
         scrdo (qq, xl, yl, xr, yu);
         }
      if ((xs <= x_split-1) && (ye + y_split > Screen_Height)) {
         qq = 2;
         xl = x_split + xs ;
         xr = x_split + xe ;
         xl = Screen_Width - x_split + xs;
         xr = Screen_Width - x_split + xe;
         xr = min (xr, Screen_Width-1);
         yl = max (0, y_split + ys - Screen_Height);
         yu = max (0, y_split + ye - Screen_Height);
         scrdo (qq, xl, yl, xr, yu);
         }
      if ((xe >= x_split) && (ye + y_split > Screen_Height)) {
         qq = 3;
         xl = max (0, xs + x_split - Screen_Width) ;
         xr = max (0, xe + x_split - Screen_Width) ;
         xl = max (0, xs-x_split+1);
         xr = xe - x_split;
         yl = max (0, y_split + ys - Screen_Height);
         yu = max (0, y_split + ye - Screen_Height);
         scrdo (qq, xl, yl, xr, yu);
         }
      }

   return (0);

}

void scrdo (qq, xs, ys, xe, ye)
/*--------------------------------------------------------------------*/
/* Draws from memory image to the screen taking account of zoom,      */
/* scroll and window offsets etc. Updates that rectangle enclosed by  */
/* xs, ys, xe, ye.  Dimensions are screen units.                      */
/*--------------------------------------------------------------------*/
   int qq, xs, ys, xe, ye;
/*--------------------------------------------------------------------*/
{
   int xmin, xmax, ymin, ymax, xext, yext, amin, amax, xoff, yoff;
   int choff;
/*--------------------------------------------------------------------*/
   numhold = 0;
                                        /* set center coords          */
   sc_centre_x = max (sc_centre_x, sc_width2 - 1);
   sc_centre_y = max (sc_centre_y, sc_height2 - 1);
   sc_centre_x = min (sc_centre_x, Screen_Width - sc_width2 - 1);
   sc_centre_y = min (sc_centre_y, Screen_Height - sc_height2 - 1);

   choff = max (0, cur_chan[qq] - 1);
/*                                      Upper left quadrant           */
/*                                         channel-dep scroll no work */
/* xmin = upleft_x[choff] * upleft_mag + sc_centre_x - sc_width2 + 1; */
/* xmax = upleft_x[choff] * upleft_mag + sc_centre_x + sc_width2;     */
   xmin = upleft_x[0] * upleft_mag + sc_centre_x - sc_width2 + 1;
   xmax = upleft_x[0] * upleft_mag + sc_centre_x + sc_width2;
   if (XasDebug) {
      fprintf (stderr,
         "SCRDO qq, choff, upl, sc_x, sc_w2 %d %d %d %d %d \n",
         qq, choff, upleft_x[0], sc_centre_x, sc_width2);
      fprintf (stderr, "SCRDO: xmin,xmax %d %d \n", xmin, xmax);
   }
   if (xmin >= Screen_Width * upleft_mag) {
      xmin -= Screen_Width * upleft_mag;
      xmax -= Screen_Width * upleft_mag;
      }
   xext = xmax - (Screen_Width - 1) * upleft_mag;
   if (xext > 0) xmax = (Screen_Width - 1) * upleft_mag;

/*                                         channel-dep scroll no work */
/* ymin = upleft_y[choff] * upleft_mag + sc_centre_y - sc_height2 + 1;*/
/* ymax = upleft_y[choff] * upleft_mag + sc_centre_y + sc_height2;    */
   ymin = upleft_y[0] * upleft_mag + sc_centre_y - sc_height2 + 1;
   ymax = upleft_y[0] * upleft_mag + sc_centre_y + sc_height2;
   if (XasDebug) {
      fprintf (stderr,
         "SCRDO qq, choff, upl, sc_y, sc_h2 %d %d %d %d %d \n",
         qq, choff, upleft_y[choff], sc_centre_y, sc_height2);
      fprintf (stderr, "SCRDO: ymin,ymax %d %d \n", ymin, ymax);
   }
   if (ymin >= Screen_Height * upleft_mag) {
      ymin -= Screen_Height * upleft_mag;
      ymax -= Screen_Height * upleft_mag;
      }
   yext = ymax - (Screen_Height - 1) * upleft_mag;
   if (yext > 0) ymax = (Screen_Height - 1) * upleft_mag;
   if (XasDebug) {
      fprintf (stderr, "SCRDO xext yext %d %d \n",
         xext, yext);
   }
   xoff = yoff = 0;
   scrdoit (qq, xs, ys, xe, ye, xmin, ymin, xmax, ymax, xoff, yoff);
/*                                         Upper right quadrant       */
   if (xext > 0) {
      amin = 0;
      amax = xext - upleft_mag;
      xoff = (xmax + upleft_mag - xmin);
      yoff = 0;
      scrdoit (qq, xs, ys, xe, ye, amin, ymin, amax, ymax, xoff, yoff);
      }
/*                                          Lower left quadrant       */
   if (yext > 0) {
      amin = 0;
      amax = yext - upleft_mag;
      xoff = 0;
      yoff = (ymax + upleft_mag - ymin);
      scrdoit (qq, xs, ys, xe, ye, xmin, amin, xmax, amax, xoff, yoff);
      }
/*                                          Lower right quadrant      */
   if ((xext > 0) && (yext > 0)) {
      xoff = (xmax + upleft_mag - xmin);
      yoff = (ymax + upleft_mag - ymin);
      amin = 0;
      amax = yext - upleft_mag;
      xmin = 0;
      xmax = xext - upleft_mag;
      scrdoit (qq, xs, ys, xe, ye, xmin, amin, xmax, amax, xoff, yoff);
      }

   return;
}

void scrdoit (qq, xs, ys, xe, ye, xmin, ymin, xmax, ymax, xoff, yoff)
/*--------------------------------------------------------------------*/
/* Draws from memory image to the screen taking account of zoom,      */
/* scroll and window offsets etc. Updates that rectangle enclosed     */
/* by xs, ys, xe, ye.  Dimensions are screen units before zoom for xs,*/
/* ys, xe, ye and AFTER zoom for the others.  This means that the left*/
/* column and upper row and right column and lower row may not be     */
/* replicated upleft_mag times in zoom.                               */
/* 24-bit IIS M70 emulation version                                   */
/*--------------------------------------------------------------------*/
   int qq, xs, ys, xe, ye, xmin, ymin, xmax, ymax, xoff, yoff;
/*--------------------------------------------------------------------*/
{

   if ((xmax >= xmin) && (ymax >= ymin)) {
      if (using_24b) {
         scrdo24 (qq,xs,ys,xe,ye,xmin,ymin,xmax,ymax,xoff,yoff);}
      else {
         scrdo8  (qq,xs,ys,xe,ye,xmin,ymin,xmax,ymax,xoff,yoff);}
   }
   return;
}

void scrdo24 (qq, xs, ys, xe, ye, xmin, ymin, xmax, ymax, xoff, yoff)
/*--------------------------------------------------------------------*/
/* Draws from memory image to the screen taking account of zoom,      */
/* scroll and window offsets etc. Updates that rectangle enclosed     */
/* by xs, ys, xe, ye.  Dimensions are screen units before zoom for xs,*/
/* ys, xe, ye and AFTER zoom for the others.  This means that the left*/
/* column and upper row and right column and lower row may not be     */
/* replicated upleft_mag times in zoom.                               */
/* 24-bit in 24/32 bits IIS M70 emulation version                     */
/*--------------------------------------------------------------------*/
   int qq, xs, ys, xe, ye, xmin, ymin, xmax, ymax, xoff, yoff;
/*--------------------------------------------------------------------*/
{
   int i, x, y, xt, offset, k, choff, yoffs, ytemp, rv, bv, gv, xq;
   unsigned char *gi, *gl, *mp, mem_full[16384][3], *pl, *plm, *pl0;
   short int *pi;
   int gphv, imv, xx, yy, nx, ny, items_row, nc, ncmag, ncx;
   unsigned long pv;
   register int j;
#ifdef USE_SHM
   XEvent event;
#endif
/*--------------------------------------------------------------------*/
   nc = 3;
   if (BitsPerPixel == 32) nc = 4;
   xq = qq;
   upleft_mag = max (1, upleft_mag);
   ncmag = nc * upleft_mag;
   if (XasDebug) {
      fprintf (stderr, "24bit xs,ys,xe,ye,mag %d %d %d %d %d\n",
         xs, ys, xe, ye, upleft_mag);
      fprintf (stderr, "xmin,xmax,ymin,ymax %d %d %d %d\n", xmin, xmax,
         ymin, ymax);
      fprintf (stderr, "xoff, yoff chan %d %d %d\n", xoff, yoff, xq);
      }
   xs = max (xs, xmin/upleft_mag);
   ys = max (ys, ymin/upleft_mag);
   xe = min (xe, xmax/upleft_mag);
   ye = min (ye, ymax/upleft_mag);
   if (XasDebug)
      fprintf (stderr, "DEBUG xs,ys,xe,ye,mag %d %d %d %d %d\n",
      xs, ys, xe, ye, upleft_mag);

   if ((xe >= xs) && (ye >= ys)) {
                                       /* find number x points        */
      nx = upleft_mag * (xe - xs + 1);
      offset = upleft_mag * xs - xmin + xoff;
      if (offset < 0) {
         nx += offset;
         offset = 0;
         }
      nx = min (nx, xmax - xmin - offset + xoff + upleft_mag);
      nx = min (nx, Screen_Width-offset);
      items_row = Screen_Width;
      plm = line_data + line->bytes_per_line * Screen_Height;
      for (i = ys; i <= ye; i++) {
         gi = graph_data + items_row * i + xs;
         for (j = xs; j <= xe; j++) {
            gphv = rwgraph & *gi++;   /* graphics sets color        */
            if (gphv > 0) {
               gphv = grfvc[gphv];
               rv = rgcol[gphv-1];
               gv = ggcol[gphv-1];
               bv = bgcol[gphv-1];
               }
            else {                    /* have to do images          */
               rv = gv = bv = 0;
               for (choff=0; choff<Ngrey; choff++) {
                  pi = plane_data[choff] + items_row * i + j;
                  if (on_chan[choff][0][xq])
                     rv = rv + rlut[choff][*pi];
                  if (on_chan[choff][1][xq])
                     gv = gv + glut[choff][*pi];
                  if (on_chan[choff][2][xq])
                     bv = bv + blut[choff][*pi];
                  }
               rv = rofm[rv];
               gv = gofm[gv];
               bv = bofm[bv];
               }
            mem_full[j][0] = bv ;
            mem_full[j][1] = gv ;
            mem_full[j][2] = rv ;
            }
         yy = upleft_mag * i - ymin + yoff;
         ny = upleft_mag;
         if (yy < 0) {
            ny += yy;
            yy = 0;
            }
         ny = min (ymax - ymin + yoff + upleft_mag - yy, ny);
         ny = min (ny, Screen_Height-yy);
                                        /* zoom a row                 */
         for (x = 0; x < upleft_mag; x++) {
            offset = upleft_mag * xs - xmin + x + xoff;
            pl0 = line_data + yy * line->bytes_per_line;
            pl = pl0 + nc * offset;
            ytemp = xs;
            if (offset < 0) {
               pl += ncmag;
               ytemp++;
               }
            xt = ytemp + (line->bytes_per_line - (pl-pl0)) / ncmag;
            xt = min (xt, xe);
            if (ByteSwapDisp == RedBigger) {
               if ((ByteSwapDisp) | (nc == 3)) {
                  for (j = ytemp; j <= xt; j++) {
                     *pl = mem_full[j][0];
                     *(pl+1) = mem_full[j][1];
                     *(pl+2) = mem_full[j][2];
                     pl += ncmag;
                     }
                  }
               else {
                  for (j = ytemp; j <= xt; j++) {
                     *(pl+1) = mem_full[j][0];
                     *(pl+2) = mem_full[j][1];
                     *(pl+3) = mem_full[j][2];
                     pl += ncmag;
                     }
                  }
               }
            else {
               if ((ByteSwapDisp) | (nc == 3)) {
                  for (j = ytemp; j <= xt; j++) {
                     *pl = mem_full[j][2];
                     *(pl+1) = mem_full[j][1];
                     *(pl+2) = mem_full[j][0];
                     pl += ncmag;
                     }
                  }
               else {
                  for (j = ytemp; j <= xt; j++) {
                     *(pl+1) = mem_full[j][2];
                     *(pl+2) = mem_full[j][1];
                     *(pl+3) = mem_full[j][0];
                     pl += ncmag;
                     }
                  }
               }
            }
                                         /* replicate the row         */
         offset = max (upleft_mag * xs - xmin + xoff, 0);
         yoffs = yy * line->bytes_per_line + offset*nc;
         ncx = nc * nx;
         for (y = 1; y < ny; y++)
            memcpy (line_data + line->bytes_per_line * y + yoffs,
               line_data + yoffs, ncx);
                                        /* move to the display        */
         } /* for i = ys:ye       */
      yy = upleft_mag * ys - ymin + yoff;
      ny = upleft_mag * (ye - ys + 1) ;
      if (yy < 0) {
         ny += yy;
         yy = 0;
         }
      ny = min (ymax - ymin + yoff + upleft_mag - yy, ny);
      ny = min (ny, Screen_Height-yy);
      if (XasDebug) {
         fprintf (stderr,
            "24 Blit xs,ys,xe,ye,mag %d %d %d %d %d\n",
            xs, ys, xe, ye, upleft_mag);
         fprintf (stderr, "Blit offset nx yy ny %d %d %d %d\n",
            offset, nx, yy, ny);
         }
#ifdef USE_SHM
      if (using_shm) {
         (void) XShmPutImage (display, win, ImageGC, line,
            offset, yy, offset, yy, nx, ny, True);
            XIfEvent (display, &event, is_complete, NULL);
         }
      else
#endif
         { XPutImage (display, win, ImageGC, line, offset, yy,
            offset, yy, nx, ny);}

      }           /* xe>=xs, ye>=ys      */

   return;
}

void scrdo8 (qq, xs, ys, xe, ye, xmin, ymin, xmax, ymax, xoff, yoff)
/*--------------------------------------------------------------------*/
/* Draws from memory image to the screen taking account of zoom,      */
/* scroll and window offsets etc. Updates that rectangle enclosed     */
/* by xs, ys, xe, ye.  Dimensions are screen units before zoom for xs,*/
/* ys, xe, ye and AFTER zoom for the others.  This means that the left*/
/* column and upper row and right column and lower row may not be     */
/* replicated upleft_mag times in zoom.                               */
/*--------------------------------------------------------------------*/
   int qq, xs, ys, xe, ye, xmin, ymin, xmax, ymax, xoff, yoff;
/*--------------------------------------------------------------------*/
{
   int i, x, y, offset, k, choff, yoffs, ytemp, xt;
   unsigned char *pl, *gi, *gl, *mp, *pl0;
   unsigned char *pi;
   int gphv, imv, mem_full[16384], xx, yy, nx, ny, bytes_row;
   unsigned long pv;
   register int j, jj;
#ifdef USE_SHM
   XEvent event;
#endif
/*--------------------------------------------------------------------*/
   upleft_mag = max (1, upleft_mag);
   if (XasDebug) {
      fprintf (stderr, "xs,ys,xe,ye,mag %d %d %d %d %d\n", xs, ys, xe,
         ye, upleft_mag);
      fprintf (stderr, "xmin,xmax,ymin,ymax %d %d %d %d\n", xmin, xmax,
         ymin, ymax);
      fprintf (stderr, "xoff, yoff %d %d\n", xoff, yoff);
      }
   xs = max (xs, xmin/upleft_mag);
   ys = max (ys, ymin/upleft_mag);
   xe = min (xe, xmax/upleft_mag);
   ye = min (ye, ymax/upleft_mag);
   choff = max (cur_chan[qq] - 1, 0);

   if ((xe >= xs) && (ye >= ys)) {
                                       /* find number x points        */
      nx = upleft_mag * (xe - xs + 1);
      offset = upleft_mag * xs - xmin + xoff;
      if (offset < 0) {
         nx += offset;
         offset = 0;
         }
      nx = min (nx, xmax - xmin - offset + xoff + upleft_mag);
      nx = min (nx, Screen_Width-offset);
#ifdef USE_SHM
      if (using_shm)
         bytes_row = line->bytes_per_line;
       else
#endif /* USE_SHM */
         bytes_row = Screen_Width;
                                       /* no graphics is faster       */
      if (rwgraph <= 0) {
                                       /* no zoom is easy             */
         if (upleft_mag <= 1) {
            yy = upleft_mag * ys - ymin + yoff;
            ny = upleft_mag * (ye - ys + 1) ;
            if (yy < 0) {
               ny += yy;
               yy = 0;
               }
            ny = min (ymax - ymin - yy + yoff + upleft_mag, ny);
            ny = min (ny, Screen_Height-yy);
#ifdef USE_SHM
	    if (using_shm) {
               (void) XShmPutImage (display, win, ImageGC,
                  plane[choff], xs, ys, offset, yy, nx, ny, True);
               XIfEvent (display, &event, is_complete, NULL);
               }
            else
#endif /* USE_SHM */
               XPutImage (display, win, ImageGC, plane[choff], xs, ys,
                  offset, yy, nx, ny);
            }
                                        /* zoomed by replication      */
         else {
                                        /* fast when 8-bit chars      */
            if (depth == 8) {
               for (i = ys; i <= ye; i++) {
                  yy = upleft_mag * i - ymin + yoff;
                  ny = upleft_mag;
                  if (yy < 0) {
                     ny += yy;
                     yy = 0;
                     }
                  ny = min (ymax - ymin + yoff + upleft_mag - yy, ny);
                  ny = min (ny, Screen_Height-yy);
                                        /* zoom a row                 */
                  for (x=0; x < upleft_mag; x++) {
                     offset = upleft_mag * xs - xmin + x + xoff;
                     pl = line_data + offset + yy * bytes_row;
                     pi = plane_short[choff] + bytes_row * i + xs;
                     xt = xs + (bytes_row - 1 - offset) / upleft_mag;
                     xt = min (xt, xe);
                     j = (xt - xs) + 1;
                     if (offset < 0) {
                        pl += upleft_mag;
                        pi += 1;
                        j--;
                        }
                     while (j--) {
                        *pl = *pi++;
                        pl += upleft_mag;
                        }
                     }
                                        /* replicate the row          */
                  offset = max (upleft_mag * xs - xmin + xoff, 0);
                  yoffs = bytes_row * yy + offset;
                  for (y = 1; y < ny; y++)
                     memcpy (line_data + (bytes_row * y + yoffs),
                        line_data + (yoffs), nx);
                                        /* move to the display        */
                  } /* for i = ys:ye       */
               yy = upleft_mag * ys - ymin + yoff;
               ny = upleft_mag * (ye - ys + 1) ;
               if (yy < 0) {
                  ny += yy;
                  yy = 0;
                  }
               ny = min (ymax - ymin - yy + yoff + upleft_mag, ny);
               ny = min (ny, Screen_Height-yy);
               if (XasDebug) {
                  fprintf (stderr,
                     "Blit xs,ys,xe,ye,mag %d %d %d %d %d\n",
                     xs, ys, xe,  ye, upleft_mag);
                  fprintf (stderr,
                     "Blit offset nx yy ny %d %d %d %d\n",
                     offset, nx, yy, ny);
                  }
#ifdef USE_SHM
               if (using_shm) {
                  (void) XShmPutImage (display, win, ImageGC,
                     line, offset, yy, offset, yy, nx, ny, True);
                  XIfEvent (display, &event, is_complete, NULL);
                  }
               else
#endif
                  XPutImage (display, win, ImageGC, line, offset, yy,
                     offset, yy, nx, ny);
               }     /* depth = 8 */
                                        /* Displays that are not      */
                                        /* 8-bit deep are handled     */
                                        /* with generic Xlib calls.   */
            else {
               for (i = ys; i <= ye; i++) {
                                        /* zoom a row                 */
                  offset = upleft_mag * xs - xmin + xoff;
                  for (j = xs; j <= xe; j++) {
                     pv = XGetPixel (plane[choff], j, i);
                     for (jj = 0; jj < upleft_mag; jj++) {
                        if ((offset > 0) && (offset < Screen_Width))
                           XPutPixel (line, offset, 0, pv);
                        offset++;
                        } /* jj */
                     } /* j = xs-xe */
                                        /* replicate the row          */
                  offset = upleft_mag * xs - xmin + xoff;
                  yy = upleft_mag * i - ymin + yoff;
                  ny = upleft_mag;
                  if (yy < 0) {
                     ny += yy;
                     yy = 0;
                     }
                  ny = min (ymax - ymin + yoff + upleft_mag - yy, ny);
                  ny = min (ny, Screen_Height-yy);
#ifdef USE_SHM
                  if (using_shm) {
                     for (y = 1; y < ny; y++) {
                        (void) XShmPutImage (display, win, ImageGC,
                           line, offset, 0, offset, yy + y, nx, 1, True);
                        XIfEvent (display, &event, is_complete, NULL);
	                }
                     }
                  else
#endif
                     for (y = 1; y < ny; y++)
                        XPutImage (display, win, ImageGC, line, offset,
                           0, offset, yy + y, nx, 1);
                  }  /* for i = ys:ye       */
               }     /* depth != 8 */
            }        /* else upleft_mag > 1 */
         }           /* rwgraph <= 0        */
                                        /* graphics are on            */
      else {
                                        /* zoomed by replication      */
                                        /* fast when 8-bit chars      */
         if (depth == 8) {
            for (i = ys; i <= ye; i++) {
                                        /* get graphics + image line  */
               pi = plane_short[choff] + bytes_row * i + xs;
               gi = graph_data + bytes_row * i + xs;
               jj = NColour - 1;
               for (j = xs; j <= xe; j++) {
                  gphv = rwgraph & *gi++;
                  imv = *pi++;
                  if (gphv > 0)
                     mem_full[j] = int2pix[jj + grfvc[gphv]];
                  else
                     mem_full[j] = imv;
                  }
               yy = upleft_mag * i - ymin + yoff;
               ny = upleft_mag;
               if (yy < 0) {
                  ny += yy;
                  yy = 0;
                  }
               ny = min (ymax - ymin + yoff + upleft_mag - yy, ny);
               ny = min (ny, Screen_Height-yy);
                                        /* zoom a row                 */
               for (x = 0; x < upleft_mag; x++) {
                  offset = upleft_mag * xs - xmin + x + xoff;
                  pl0 = line_data + yy * bytes_row;
                  pl = pl0 + offset;
                  ytemp = xs;
                  if (offset < 0) {
                     pl += upleft_mag;
                     ytemp++;
                     }
                  xt = ytemp + (bytes_row - 1 - (pl-pl0)) / upleft_mag;
                  xt = min (xt, xe);
                  for (j = ytemp; j <= xt; j++) {
                     *pl = mem_full[j];
                     pl += upleft_mag;
                     }
                  }
                                        /* replicate the row         */
               offset = max (upleft_mag * xs - xmin + xoff, 0);
               yoffs = bytes_row * yy + offset;
               for (y = 1; y < ny; y++)
                  memcpy (line_data + (bytes_row * y + yoffs),
                     line_data + (yoffs), nx);
                                        /* move to the display        */
               } /* for i = ys:ye       */
            yy = upleft_mag * ys - ymin + yoff;
            ny = upleft_mag * (ye - ys + 1) ;
            if (yy < 0) {
               ny += yy;
               yy = 0;
               }
            ny = min (ymax - ymin + yoff + upleft_mag - yy, ny);
            ny = min (ny, Screen_Height-yy);
            if (XasDebug) {
               fprintf (stderr,
                  "Blit xs,ys,xe,ye,mag %d %d %d %d %d\n",
                  xs, ys, xe, ye, upleft_mag);
               fprintf (stderr, "Blit offset nx yy ny %d %d %d %d\n",
                  offset, nx, yy, ny);
               }
#ifdef USE_SHM
           if (using_shm) {
               (void) XShmPutImage (display, win, ImageGC, line,
                  offset, yy, offset, yy, nx, ny, True);
               XIfEvent (display, &event, is_complete, NULL);
               }
            else
#endif
               XPutImage (display, win, ImageGC, line, offset, yy,
                  offset, yy, nx, ny);
            }     /* depth = 8 */
                                        /* Displays that are not      */
                                        /* 8-bit deep are handled     */
                                        /* with generic Xlib calls.   */
         else {
            for (i = ys; i <= ye; i++) {
                                        /* get graphics + image line  */
               offset = upleft_mag * xs - xmin + xoff;
               for (j = xs; j <= xe; j++) {
                  gphv = rwgraph & XGetPixel (graph, j, i);
                  if (gphv > 0)
                     pv = int2pix[jj + grfvc[gphv]];
                  else
                     pv = XGetPixel (plane[choff], j, i);
                                        /* zoom the pixel             */
                  for (jj = 0; jj < upleft_mag; jj++) {
                     if ((offset > 0) && (offset < Screen_Width))
                        XPutPixel (line, offset, 0, pv);
                     offset++;
                     } /* jj */
                  } /* j = xs-xe */
                                        /* replicate the row          */
               offset = upleft_mag * xs - xmin + xoff;
               yy = upleft_mag * i - ymin + yoff;
               ny = upleft_mag;
               if (yy < 0) {
                  ny += yy;
                  yy = 0;
                  }
               ny = min (ymax - ymin + yoff + upleft_mag - yy, ny);
               ny = min (ny, Screen_Height-yy);
#ifdef USE_SHM
               if (using_shm) {
                  for (y = 1; y < ny; y++) {
                     (void) XShmPutImage (display, win, ImageGC,
                        line, offset, 0, offset, yy + y, nx, ny,
                        True);
                     XIfEvent (display, &event, is_complete, NULL);
                     }
                  }
               else
#endif
                  for (y = 1; y < ny; y++)
                     XPutImage (display, win, ImageGC, line, offset, 0,
                        offset, yy + y, nx, 1);
               }  /* for i = ys:ye       */
            }     /* depth != 8 */
         }        /* rwgraph > 0         */
      }           /* xe>=xs, ye>=ys      */

   return;
}

#ifdef USE_SHM
                                 /* Predicate procedure for XIfEvent: */
Bool
is_complete (display, event, arg)
Display *display;
XEvent  *event;
char    *arg;
{
#if __STDC__
int XShmGetEventBase ( Display * );
#else
int XShmGetEventBase (/* Display * */);
#endif
   if (event->type == (XShmGetEventBase (display) + ShmCompletion))
      return True;
   else
      return False;
}
#endif
--XYZZY--
cat > xas.c << "--XYZZY--"
/*--------------------------------------------------------------------*/
/*! X-AIPS server                                                     */
/*# TV-IO                                                             */
/*--------------------------------------------------------------------*/
/*;  Copyright (C) 1995-2000, 2003, 2008, 2012, 2020, 2026            */
/*;  Associated Universities, Inc. Washington DC, USA.                */
/*;                                                                   */
/*;  This program is free software; you can redistribute it and/or    */
/*;  modify it under the terms of the GNU General Public License as   */
/*;  published by the Free Software Foundation; either version 2 of   */
/*;  the License, or (at your option) any later version.              */
/*;                                                                   */
/*;  This program is distributed in the hope that it will be useful,  */
/*;  but WITHOUT ANY WARRANTY; without even the implied warranty of   */
/*;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    */
/*;  GNU General Public License for more details.                     */
/*;                                                                   */
/*;  You should have received a copy of the GNU General Public        */
/*;  License along with this program; if not, write to the Free       */
/*;  Software Foundation, Inc., 675 Massachusetts Ave, Cambridge,     */
/*;  MA 02139, USA.                                                   */
/*;                                                                   */
/*;  Correspondence concerning AIPS should be addressed as follows:   */
/*;         Internet email: aipsmail@nrao.edu.                        */
/*;         Postal address: AIPS Project Office                       */
/*;                         National Radio Astronomy Observatory      */
/*;                         520 Edgemont Road                         */
/*;                         Charlottesville, VA 22903-2475 USA        */
/*--------------------------------------------------------------------*/

#include "defxas.h"
#include <sys/time.h>
#ifdef AIX
#include <sys/select.h>
#endif
#if BSD
#include <netinet/tcp.h>
#endif

int main (argc, argv)
int argc;
char *argv[];
{
    XEvent report;
    KeySym key;
    char CharBuf[4];
    XComposeStatus compose;
    int sx, sy, w, h, exposed, i, ierr;
#if BSD
    int select_size;
    int XLink, len, optlen;
    struct sockaddr_un from_un;
    struct sockaddr_in from_in;
    fd_set fdmask;
#endif
#if VMS
    int status;
#endif

    /* Init global variables */
    exposed = False;
    init();

    /* Connect to X server, get window ID and generate gray scale */
    SetupWindow (argc, argv);

#if BSD
    /* Create communications link with AIPS. */
    if (MakeLink() < 0) {
        (void) shutdown (AipsSocket, 0);
        (void) close (AipsSocket);
        closedown();
        exit(-1);
       }

                                        /* Get file descriptor of X */
                                        /* server socket */
    XLink = ConnectionNumber (display);
                                        /* on hpux, use posix form */
#if defined(__hpux) || defined(__STDC__)
    select_size = sysconf (_SC_OPEN_MAX);
#else
    select_size = getdtablesize();
#endif

#if VMS
    /* Create communications link with AIPS. */
    Makelink();
    write_in_progress = 0;
    read_in_progress = 0;

    /* wake up about once every 1/4 second */
    status = sys(&dtime,&delta);
    if (!(status & SS)) lib(status);
    status = sys(0,0,&delta,&delta);
    if (!(status & SS)) lib(status);

    /* Start the IO */
    ReadLink (AipsLink);
#endif

                                        /* display window             */
    XMapWindow (display, win);

    /*
     * Event loop, first Expose displays blank window;
     * Press ESC or control-c or F20 to exit.
     */
    while (1) {

#if VMS
        sys(0);
        while (XCheckWindowEvent (display, win, emask, &report))
        {
#endif

#if BSD
         if (XPending (display)) {
            XNextEvent (display, &report);
            }
         else {
            if (connected) {
                FD_ZERO (&fdmask);
                FD_SET (AipsLink, &fdmask);
                FD_SET (XLink, &fdmask);
                /* select for an X event or I/O from AIPS */
                if (select (select_size, &fdmask, (fd_set *)NULL,
                   (fd_set *)NULL, (struct timeval *)0) < 0) {
                   perror ("select error - AipsLink");
                   continue;
                   }
                if (FD_ISSET (XLink, &fdmask)) {
                   XNextEvent (display, &report);
                   }
                else {
                   ReadLink (AipsLink, &xbuf, &ybuf);
                   if (ybuf.status != OK) {
                      if (XasDebug) fprintf (stderr,
                         "XAS read fail => unlock & close\n");
                      zssslk (0, &ierr) ;
                      xbuf.opcode = CLOSE;
                      }
                   ProcessAipsRequest();
                   if (connected)
                      WriteLink (AipsLink, &xbuf, &ybuf);
                   continue;
                   }
               }
            else {  /* not connected */
                FD_ZERO (&fdmask);
                FD_SET (AipsSocket, &fdmask);
                FD_SET (XLink, &fdmask);
                /* select for an X event or connect request from AIPS */
                if (select (select_size, &fdmask, (fd_set *)NULL,
                    (fd_set *)NULL, (struct timeval *)0) < 0) {
                    perror ("select error - AipsSocket");
                    continue;
                   }
                if (FD_ISSET (XLink, &fdmask)) {
                   XNextEvent(display, &report);
                   }
                else {                  /* Connect to an AIPS task    */
                   if (domain_type == INET_DOMAIN ) {
                      len = sizeof(from_in);
                      if ((AipsLink = accept (AipsSocket,
                         (struct sockaddr *) &from_in,
                         (socklen_t *) &len)) < 0) {
                         perror ("Accept");
                         connected = False;
                         }
                      else {
                         connected = True;
                         }
                      }
                   else {               /* UNIX_DOMAIN                */
                      len = sizeof(from_un);
                      if ((AipsLink = accept (AipsSocket,
                         (struct sockaddr *) &from_un,
                         (socklen_t *) &len)) < 0) {
                         perror ("Accept");
                         connected = False;
                         }
                      else {
                         connected = True;
                         }
                      }
                   if (connected) {
                      optlen = sizeof (Z_sndbuf);
                      if (getsockopt (AipsLink, SOL_SOCKET, SO_SNDBUF,
                         (char *) &Z_sndbuf, (socklen_t *)&optlen) < 0) {
                         perror("XAS connect SO_SNDBUF get");
                         Z_sndbuf = 4096;
                         }
                      optlen = sizeof (Z_rcvbuf);
                      if (getsockopt (AipsLink, SOL_SOCKET, SO_RCVBUF,
                         (char *) &Z_rcvbuf, (socklen_t *) &optlen) < 0) {
                         perror("XAS connect SO_RCVBUF get");
                         Z_rcvbuf = 4096;
                         }
                      Z_sndini = Z_sndbuf;
                      Z_rcvini = Z_rcvbuf;
                      }
                   continue;
                   }
               }
           }
#endif
           if (XDebug)
               fprintf (stderr,"  %s\n",event_names[report.type]);
           switch (report.type) {
               case Expose:
                   while (XCheckTypedEvent (display, Expose, &report));
                   if (XasDebug) fprintf (stderr,
                      "expose event w,h,x,y %d %d %d %d\n",
                      Cur_Xsize, Cur_Ysize, Cur_Xzero, Cur_Yzero);
                                        /* first time force it       */
                   if (!exposed) XResizeWindow (display, win,
                      Cur_Xsize, Cur_Ysize);
                   exposed = True;
                                        /* repaint the picture       */
                   if (XasDebug) fprintf (stderr,
                      "DEBUG scrwrt called from main(expose)\n");
                   scrwrt (0, 0, Screen_Width - 1, Screen_Height - 1);
                   break;
               case ButtonPress:
                   RecordCursor (report.xbutton.x, report.xbutton.y);
                   break;
               case MotionNotify:
                   RecordCursor (report.xmotion.x, report.xmotion.y);
                   break;
               case KeyPress:
                   (void) XLookupString ((XKeyEvent *)&report, CharBuf,
                       sizeof(CharBuf), &key, &compose );
                   CheckKey (key, AipsLink);
                   break;
               case ConfigureNotify:
                   if (exposed) {
                      Cur_Xsize = report.xconfigure.width;
                      Cur_Ysize = report.xconfigure.height;
                      if ((report.xconfigure.x != 0) ||
                         (report.xconfigure.y != 0)) {
                         Cur_Xzero = report.xconfigure.x;
                         Cur_Yzero = report.xconfigure.y;
                         }
                      }
                   if (XasDebug) fprintf (stderr,
                      "configure event w,h,x,y %d %d %d %d\n",
                      Cur_Xsize, Cur_Ysize, Cur_Xzero, Cur_Yzero);
                   (void) resize_canvas (Cur_Xsize, Cur_Ysize,
                       Cur_Xzero, Cur_Yzero);
                   break;
               default:
                   /* all events selected by StructureNotifyMask
                    * except ConfigureNotify are thrown away here,
                    * since nothing is done with them                */
                   break;
              } /* end switch */
#if VMS
           } /* end while */
        sys(1);  /* enable ASTs while hibernating */
        sys();  /* go to sleep, wait for wakeup */
#endif
      } /* end while */
                                        /* close down by destroying */
                                        /* anything created in init */
                                        /* More needed here?  Maybe */
                                        /* shutdown (AipsSocket, 0) */
                                        /* and close (AipsSocket)   */
                                        /* first???                 */
   closedown();
#endif

   return (0);
} /* end main */


/*-------------------------------------------------------------------*/
void ProcessAipsRequest()
{

    ybuf.status = 0;
    ybuf.return_data_length = 0;
    if ((XDebug) && (xbuf.opcode != IMWRT) && (xbuf.opcode != RCURS)
       && (xbuf.opcode != RCURB)) {
       fprintf (stderr, "%s\n",opcodes[xbuf.opcode]);
       printbufin ();
       }
   switch (xbuf.opcode) {
      case OPEN:
         if (XasDebug) fprintf (stderr, "XAS Open \n");
         ybuf.status = 0;
         ybuf.return_data_length = 0;
         break;
      case CLOSE:
         if (XasDebug) fprintf (stderr, "XAS Close now \n");
#if BSD
         shutdown (AipsLink, 0);
         close (AipsLink);
#endif
         connected = False;
         break;
      case INTGT:
         if (XasDebug) fprintf (stderr, "XAS parameters requested");
         ybuf.status = Interogate (&ybuf.return_data_length);
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case INTGTO:
         if (XasDebug) fprintf (stderr, "XAS parameters requested");
         ybuf.status = InterogateO (&ybuf.return_data_length);
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case PSAVE:
         if (XasDebug) fprintf (stderr, "XAS parameters saved");
         ybuf.status = PSave ();
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case PSAVEO:
         if (XasDebug) fprintf (stderr, "XAS parameters saved");
         ybuf.status = PSaveO ();
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case WINDO:
         if (XasDebug) fprintf (stderr, "WINDO %d %d %d %d\n",
            xbuf.parms[0], xbuf.parms[1], xbuf.parms[2], xbuf.parms[3]);
         ybuf.status = windo_status();
         ybuf.return_data_length = 8;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case INIT:
         if (XasDebug) fprintf (stderr, "INIT");
         InitXAS() ;
         if (XasDebug)
            fprintf (stderr, "DEBUG scrwrt called from main(INIT)\n");
         scrwrt (0, 0, Screen_Width - 1, Screen_Height - 1);
         ybuf.status = 0;
         ybuf.return_data_length = 0;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case INITO:
         if (XasDebug) fprintf (stderr, "INITO");
         InitOldXAS() ;
         if (XasDebug)
            fprintf (stderr, "DEBUG scrwrt called from main(INITO)\n");
         scrwrt (0, 0, Screen_Width - 1, Screen_Height - 1);
         ybuf.status = 0;
         ybuf.return_data_length = 0;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case VIEW:
         if (XasDebug)
            fprintf (stderr, "VIEW %d", xbuf.parms[0]);
         ybuf.status = ViewData();
         ybuf.return_data_length = 0;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case XDIE:
         closedown();
         ybuf.status = 0;
         ybuf.return_data_length = 0;
         fprintf (stderr, "XAS told to shutdown\n");
         break;
      case IMWRT:
         ybuf.status = imwrt();
         ybuf.return_data_length = 0;
         break;
      case IMRD:
         ybuf.status = imrd (&ybuf.return_data_length);
         break;
      case OIMWRT:
         ybuf.status = oimwrt();
         ybuf.return_data_length = 0;
         break;
      case OIMRD:
         ybuf.status = oimrd (&ybuf.return_data_length);
         break;
      case FILL:
         if (XasDebug)
            fprintf (stderr, "FILL %d %d %d %d %d %d", xbuf.parms[0],
               xbuf.parms[1], xbuf.parms[2], xbuf.parms[3],
               ntohs(xbuf.u.idata[0]), ntohs(xbuf.u.data[1]));
         ybuf.status = FillChan();
         ybuf.return_data_length = 0;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case VECT:
         if (XasDebug)
            fprintf (stderr, "VECT %d %d %d %d %d %d", xbuf.parms[0],
               xbuf.parms[1], xbuf.parms[2], xbuf.parms[3],
               ntohs(xbuf.u.idata[0]), ntohs(xbuf.u.idata[1]));
         ybuf.status = VectChan();
         ybuf.return_data_length = 0;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case OFILL:
         if (XasDebug)
            fprintf (stderr, "FILL old %d %d %d %d %d %d", xbuf.parms[0],
               xbuf.parms[1], xbuf.parms[2], xbuf.parms[3],
               xbuf.u.data[0], xbuf.u.data[1]);
         ybuf.status = FillChon();
         ybuf.return_data_length = 0;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case OVECT:
         if (XasDebug)
            fprintf (stderr, "VECT old %d %d %d %d %d %d", xbuf.parms[0],
               xbuf.parms[1], xbuf.parms[2], xbuf.parms[3],
               xbuf.u.data[0], xbuf.u.data[1]);
         ybuf.status = VectChon();
         ybuf.return_data_length = 0;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case CHARS:
         if (XasDebug)
            fprintf (stderr, "CHARS %d %d %d %d %d", xbuf.parms[0],
               xbuf.parms[1], xbuf.parms[2], xbuf.parms[3], xbuf.u.ldata[0]);
         ybuf.status = CharChan();
         ybuf.return_data_length = 0;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case CATIN:
         if (XasDebug)
            fprintf (stderr, "CATIN %d", xbuf.parms[0]);
         ybuf.status = CatInit((int) xbuf.parms[0]);
         ybuf.return_data_length = 0;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case CATRD:
         if (XasDebug)
            fprintf (stderr, "CATRD %d %d %d", xbuf.parms[0],
               xbuf.parms[1], xbuf.parms[2]);
         ybuf.status = CatRead ();
         ybuf.return_data_length = 1024;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case CATWR:
         if (XasDebug)
            fprintf (stderr, "CATWR %d %d %d %d", xbuf.parms[0],
               xbuf.parms[1], xbuf.parms[2], xbuf.parms[3]);
         ybuf.status = CatWrite ();
         ybuf.return_data_length = 0;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case CATOV:
         if (XasDebug)
            fprintf (stderr, "CATOV ");
         ybuf.status = CatOver ();
         ybuf.return_data_length = 4;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case CATFI:
         if (XasDebug)
            fprintf (stderr, "CATFI %d %d", xbuf.parms[0],
               xbuf.parms[1]);
         ybuf.status = CatFind ();
         ybuf.return_data_length = 1027;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case CLEAR:
         if (XasDebug)
            fprintf (stderr, "CLEAR %d", xbuf.parms[0]);
         ybuf.status = ClearChan();
         ybuf.return_data_length = 0;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case WLOT:
         if (XasDebug) fprintf (stderr, "WLUT old %d", xbuf.parms[0]);
         ybuf.status = cmap_wlot();
         ybuf.return_data_length = 0;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case RLOT:
         if (XasDebug) fprintf (stderr, "RLUT old %d", xbuf.parms[0]);
         ybuf.status = cmap_rlot();
         ybuf.return_data_length = 256;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case WLUT:
         if (XasDebug) fprintf (stderr, "WLUT %d", xbuf.parms[0]);
         ybuf.status = cmap_wlut();
         ybuf.return_data_length = 0;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case RLUT:
         if (XasDebug) fprintf (stderr, "RLUT %d", xbuf.parms[0]);
         ybuf.status = cmap_rlut();
         ybuf.return_data_length = 2 * NColour;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case WOFM:
         if (XasDebug) fprintf (stderr, "WOFM %d", xbuf.parms[0]);
         ybuf.status = cmap_wofm();
         ybuf.return_data_length = 0;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case ROFM:
         if (XasDebug) fprintf (stderr, "ROFM %d", xbuf.parms[0]);
         ybuf.status = cmap_rofm();
         if (using_24b)
            ybuf.return_data_length = FNINTENS;
         else
            ybuf.return_data_length = 256;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case WOFMO:
         if (XasDebug) fprintf (stderr, "WOFM %d", xbuf.parms[0]);
         ybuf.status = cmap_wofmo();
         ybuf.return_data_length = 0;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case ROFMO:
         if (XasDebug) fprintf (stderr, "ROFM %d", xbuf.parms[0]);
         ybuf.status = cmap_rofmo();
         if (using_24b)
            ybuf.return_data_length = 1024;
         else
            ybuf.return_data_length = 256;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case GRAPH:
         if (XasDebug) fprintf (stderr, "GRAPH %d %d\n",
            xbuf.parms[0],xbuf.parms[1]);
         ybuf.status = cmap_graph();
         ybuf.return_data_length = 0;
         if (XasDebug) fprintf (stderr, " GRAPH done\n");
         break;
      case SPLOT:
         if (XasDebug) fprintf (stderr, "SPLOT %d", xbuf.parms[0]);
         ybuf.status = cmap_splot();
         ybuf.return_data_length = 0;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case SPLAT:
         if (XasDebug) fprintf (stderr, "SPLIT %d", xbuf.parms[0]);
         ybuf.status = cmap_splat();
         ybuf.return_data_length = 0;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case SPLIT:
         if (XasDebug) fprintf (stderr, "SPLIT %d", xbuf.parms[0]);
         ybuf.status = cmap_split();
         ybuf.return_data_length = 0;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case WGRFX:
         if (XasDebug) fprintf (stderr, "WGRFX %d", xbuf.parms[0]);
         ybuf.status = cmap_wgrfx();
         ybuf.return_data_length = 0;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case RGRFX:
         if (XasDebug) fprintf (stderr, "RGRFX %d", xbuf.parms[0]);
         ybuf.status = cmap_rgrfx();
         ybuf.return_data_length = 3;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case RCURS:
         ybuf.status = GetCursor();
         ybuf.return_data_length = 4;
         break;
      case RBUTT:
         ybuf.status = readbuttons();
         ybuf.return_data_length = 8;
         break;
      case WCURS:
         if (XasDebug) fprintf (stderr, "WCURS %d %d",
            xbuf.parms[0], xbuf.parms[1]);
         ybuf.status = movecursor();
         ybuf.return_data_length = 0;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case RCURB:
         ybuf.status = cursor_button();
         ybuf.return_data_length = 12;
         if ((XasDebug) && ((ybuf.u.idata[2] != 0)
            || (ybuf.u.idata[3] != 0) || (ybuf.u.idata[4] != 0)
            || (ybuf.u.idata[5] != 0)))
            fprintf (stderr, "RCURB returns %d %d %d %d %d %d\n",
               ntohs (ybuf.u.idata[0]), ntohs (ybuf.u.idata[1]),
               ntohs (ybuf.u.idata[2]), ntohs (ybuf.u.idata[3]),
               ntohs (ybuf.u.idata[4]), ntohs (ybuf.u.idata[5]));
         break;
      case CHMULT:
         if (XasDebug) fprintf (stderr, "CHMULT %d", xbuf.parms[0]);
         char_mult = xbuf.parms[0];
         ybuf.status = 0;
         ybuf.return_data_length = 0;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      case WZSCR:
         if (XasDebug) fprintf (stderr, "ZOOM %d %d %d %d",
            xbuf.parms[0], xbuf.parms[1], xbuf.parms[2], xbuf.parms[3]);
         ybuf.status = zoom();
         ybuf.return_data_length = 0;
         if (XasDebug) fprintf (stderr, " done\n");
         break;
      default:
         fprintf (stderr, "XAS: opcode %d not yet implemented.\n",
             xbuf.opcode);
         ybuf.status = -1;
         ybuf.return_data_length = 0;
         break;
         } /* end switch */

   return ;
} /* end ProcessAipsRequest */
--XYZZY--
cat > defxas.h << "--XYZZY--"
/*--------------------------------------------------------------------*/
/*! XAS header file defining in xas.c                                 */
/*# TV-IO                                                             */
/*--------------------------------------------------------------------*/
/*;  Copyright (C) 1995-2003, 2008, 2011-2012, 2026                   */
/*;  Associated Universities, Inc. Washington DC, USA.                */
/*;                                                                   */
/*;  This program is free software; you can redistribute it and/or    */
/*;  modify it under the terms of the GNU General Public License as   */
/*;  published by the Free Software Foundation; either version 2 of   */
/*;  the License, or (at your option) any later version.              */
/*;                                                                   */
/*;  This program is distributed in the hope that it will be useful,  */
/*;  but WITHOUT ANY WARRANTY; without even the implied warranty of   */
/*;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    */
/*;  GNU General Public License for more details.                     */
/*;                                                                   */
/*;  You should have received a copy of the GNU General Public        */
/*;  License along with this program; if not, write to the Free       */
/*;  Software Foundation, Inc., 675 Massachusetts Ave, Cambridge,     */
/*;  MA 02139, USA.                                                   */
/*;                                                                   */
/*;  Correspondence concerning AIPS should be addressed as follows:   */
/*;         Internet email: aipsmail@nrao.edu.                        */
/*;         Postal address: AIPS Project Office                       */
/*;                         National Radio Astronomy Observatory      */
/*;                         520 Edgemont Road                         */
/*;                         Charlottesville, VA 22903-2475 USA        */
/*--------------------------------------------------------------------*/
/* #define BSD 1  */                    /* Select operating system    */
/* #define VMS 0  */                    /* set desired system to 1    */
#ifdef _BSD                             /* Unix needs BSD = 1         */
#define BSD 1
#undef VMS                              /* Do not us VMS specific code*/
#endif
#ifdef _VMS                             /* DEC VMS                    */
#define VMS 1
#undef BSD                              /* No Unix-specific code      */
#endif
#ifdef _AIX                             /* IBM AIX needs BSD = 1 also */
#define AIX 1                           /* use AIX specific code      */
#undef VMS                              /* Do not us VMS specific code*/
#endif

#include <stdio.h>
                                        /* We must override MIT error */
                                        /* in prototype               */
#if __STDC__
#define XIOErrorHandler XFuckedUp1
#define XSetIOErrorHandler XFuckedUp2
#endif
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#if __STDC__
#undef  XIOErrorHandler
#undef  XSetIOErrorHandler
#endif

#if BSD

/* #include <X11/bitmaps/xlogo64> */

/* Header info needed for socket routines (including i/o) */

#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <ctype.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netdb.h>
#include <netinet/in.h>

/* Header for shared memory extension */

#ifdef USE_SHM
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/extensions/XShm.h>
#endif

struct sockaddr_un server_un;
struct sockaddr_in server_in;
struct servent *sp_in;

Bool connected;
int AipsSocket, AipsLink;
int domain_type;
#define UNIX_DOMAIN 0
#define INET_DOMAIN 1

#endif /* BSD */


#if VMS

/* ##include "xlogo64." */
#include <ssdef.h>
#include <iodef.h>
#include <descrip.h>

#define XAS_SOCKET "XasSocket"     /* mailbox name AIPS --> XAS */
#define AIPS_SOCKET "AipsSocket"   /* mailbox name XAS --> AIPS */

#define emask ExposureMask|KeyPressMask|StructureNotifyMask|PointerMotionMask

#define maxmsg 16400
#define bufquo 16400

typedef struct {
   short int ioresult;
   short int iolength;
   int unused;
} IOSB;

int XasLink, AipsLink;
IOSB read_status, write_status;
int read_in_progress, write_in_progress;
static  (dtime, "0 00:00:00.25");
int delta[2];

#endif /* VMS */

                                        /* Screen parameters          */
int Ngrey, NgreyUser;
#define NGREYMAX 16
#define NGRAPH   8
#define NGRPHCOL 19
                                        /* total number of planes     */
                                        /* (grey-scale + graphics)    */
#define NGRTOT   (NGREYMAX+NGRAPH)
#define MAXZOOM  16
#define MAXCAT   (MAXZOOM*MAXZOOM)
                                        /* Border allocations         */
/* #define TEXT_SPACE      0 */         /* empty space @ bottom screen*/
#define TEXT_SPACE      69              /* preferred at NRAO?         */
                                        /* I can find no way to ask   */
                                        /* the window manager the size*/
                                        /* of its top banner.         */
                                        /* They need to be visible to */
                                        /* allow window resize, move..*/
#ifdef AIX                              /* Numbers for IBM Motif      */
#define SCREEN_LEFT    11
#define SCREEN_RIGHT   11
#define SCREEN_TOP     34
#define SCREEN_BOTTOM  (11 + TEXT_SPACE)
#else                                   /* Numbers for SUN OpenLook   */
#define SCREEN_LEFT     5
#define SCREEN_RIGHT    5
#define SCREEN_TOP     26
#define SCREEN_BOTTOM   (5 + TEXT_SPACE)
#endif
                                        /* total screen size          */
                                        /* used in positioning        */
int twidth, theight, bwid;
                                        /* size of logical screen     */
                                        /* must be EVEN numbers !     */
int Screen_Height, Screen_Width, visnum;
int Cur_Xsize, Cur_Ysize, Cur_Xzero, Cur_Yzero;
                                        /* number grey levels in:     */
                                        /* total levels: NColour+1-19 */
int NColour, NValue, OColour;           /* for graphics, and cursor   */
                                        /* number of grey-scale (OFM) */
                                        /* intensities                */
#define NINTENS       2046
#define FNINTENS     (NGREYMAX*NINTENS)
#define COLORSHIFT      8               /* 255 max from ofm then shift*/
                                        /* 8 bits left for col table  */

                                        /* cursor [0], graphics [1-8] */
int rgrfx[9], ggrfx[9], bgrfx[9], rgcol[20], ggcol[20], bgcol[20];
int grfvc[256];
float Gamma ;

#define OK 0

#define NPARMS 4
typedef struct {
   short int
      opcode,
      parms[NPARMS],
      data_length;
   union {
      int ldata[8192];
      short int idata[16384];
      unsigned char data[32768];
      } u;
} XASinput;
typedef struct {
   short int
      return_data_length,
      status;
   union {
      int ldata[8192];
      short int idata[16384];
      unsigned char data[32768];
      } u;
} XASoutput;

                                        /* Global variables           */
XASinput xbuf;                          /* I/O buffer for AIPS        */
XASoutput ybuf;                         /* I/O buffer for AIPS        */
int Z_sndbuf, Z_rcvbuf, Z_sndini, Z_rcvini; /* I/O buffer sizes       */
Bool XasDebug;                          /* Toggle with F8             */
Bool XDebug;                            /* Toggle with F9             */
Bool ByteSwapped;                       /* Local byte swapped machine */
Bool ByteSwapDisp;                      /* Display byte swapped       */
Bool RedBigger;                         /* Color mask value R>B       */
Display *display;
int screen_num;
Cursor cursor;
Window win;
GC ImageGC;                             /* X11 graphics contexts for  */
                                        /* drawing images & graphics  */
                                        /* Image data structures:     */
XImage *plane[NGREYMAX];                /* grey-scale planes          */
XImage *line;                           /* buffer for zoomed img line */
XImage *gline;                          /* buffer for zoomed graphics */
                                        /* line                       */
/* All graphs are kept in one plane via a binary trick                */
/* a pixel value of 1 means only graph 1 on, 2 means only graph 2 on  */
/* a pixel value of 4 means only graph 3 on, 8 means only graph 4 on  */
/* a pixel value of 3 means both graph 1 and 2 on, 15 means all 4 on, */
/* etc. */
XImage *graph;                          /* graphics overlay           */
short int *plane_data[NGREYMAX];        /* data storage               */
unsigned char *plane_short[NGREYMAX];   /* data storage               */
unsigned char *line_data;
unsigned char *graph_data;
int *line_idata;

                                        /* Shared memory              */
int using_shm;                          /* set True if using SHM      */
#ifdef USE_SHM
XShmSegmentInfo plane_info[NGREYMAX];   /* shm info for image planes  */
XShmSegmentInfo graph_info;             /* shm info for graphics plane*/
XShmSegmentInfo line_info;              /* shm info for zoom buffers  */
#endif

int rwgraph, depth;
unsigned char gph_mask;

int using_24b, BitsPerPixel ;
int rofm[FNINTENS], gofm[FNINTENS],     /* red, green and blue OFM    */
    bofm[FNINTENS];                     /* registers                  */
                                        /* red, green and blue LUT    */
int *rlut[NGREYMAX], *glut[NGREYMAX], *blut[NGREYMAX];
int *pix2int;                           /* input int <- assigned pixv */
unsigned long *int2pix;                 /* input int -> assigned pixv */

int TvStatus[NGREYMAX+NGRAPH];          /* TV Image + Graphics status */

int params[256];                        /* DTVC.INC                   */

char imgcat[NGREYMAX][MAXCAT][1024] ;
char grpcat[NGRAPH][1024];
int  dircat[NGREYMAX][MAXCAT][5] ;
char typcat[NGREYMAX][MAXCAT][2] ;
int  dirgcat[NGRAPH][5] ;
char typgcat[NGRAPH][2] ;
int  lastcat[NGREYMAX];

int cur_chan[NGREYMAX], on_chan[NGREYMAX][3][4], x_split, y_split, Q_same;
int cursor_x, cursor_y;
int size_i2;
int char_mult;

int big_screen;                         /* True if screen is at max.  */
                                        /* size, FALSE otherwise      */
int cur_xcorn, cur_ycorn;               /* current location of top-   */
                                        /* left corner of smaller     */
                                        /* window                     */
int cur_xsize, cur_ysize;               /* current size of smaller    */
                                        /* window                     */

Colormap TV_colour;
XColor *colour_table;
XColor fg_curs, bg_curs;
int cursor_shape;                      /* standard cursor shape number*/
int start_icon;                        /* > 0 -> start in icon */
unsigned long curs_pixel[2];
unsigned char image_offset;
unsigned char graphics_offset;

int button_a, button_b, button_c, button_d;
int upleft_x[NGREYMAX], upleft_y[NGREYMAX], upleft_mag;
int sc_centre_x, sc_centre_y, sc_zoom_mag;
int sc_width, sc_height, sc_width2, sc_height2;
int ic_width, ic_height, ic_xcorn, ic_ycorn;
int scrhold, numhold, Maxhold, uxs, uxe, uys, uye;

char *ProgName;

                                        /* Useful macros              */
#ifndef min
#define min(a,b) ((a)<(b)?(a):(b))
#endif

#ifndef max
#define max(a,b) ((a)>(b)?(a):(b))
#endif

#define intswap(a,b) { int tmp; tmp=a; a=b; b=tmp; }

#define Memory_x(aips_x)  ((aips_x) - 1)
#define Memory_y(aips_y)  (Screen_Height - (aips_y))
#define Aips_x(memory_x)  ((memory_x) + 1)
#define Aips_y(memory_y)  (Screen_Height - (memory_y))
#define chg_s(var,val,msk) ((var) = ((var)&(~(msk)))|((val) ? (msk) : 0))
#define chg_g(var,msk) (((var)&(msk)) ? 1 : 0)

int buffered;                           /* True if socket is          */
                                        /* buffered                   */
/* Defined opcodes */
#define NUMOP   83                      /* Largest opcode             */

int bufferop[NUMOP+1];                  /* bufferop[OP] is True if    */
                                        /* there is no status return  */
                                        /* in buffered mode           */
#define INTGT   10     /* Interrogate: get XAS major parameters       */
#define OPEN    11     /* Opens the XAS connection                    */
#define CLOSE   12     /* Close the XAS, allows new connections       */
#define INTGTO  13     /* Interrogate: get XAS old major parameters   */
#define WINDO   14     /* Read, write the X window size               */
#define INITO   15     /* init the TV old form                        */
#define VIEW    16     /* Do/hold screen updates                      */
#define PSAVEO  17     /* save DTVC.INC parameters old                */
#define XDIE    18     /* close down XAS and lock servers             */
#define IMWRT   19     /* Write image line to some channel            */
#define IMRD    20     /* Read image line from some channel           */
#define OIMWRT  21     /* Write image line to some channel OLD        */
#define OIMRD   22     /* Read image line from some channel OLD       */
#define OFILL   23     /* fill area in some or all channels           */
#define CLEAR   24     /* Clear some or all channels                  */
#define OVECT   25     /* connect two points with line                */
#define CHARS   26     /* write character string                      */
#define FILL    27     /* fill area in some or all channels           */
#define VECT    28     /* connect two points with line                */
#define INIT    29     /* init the TV                                 */
#define CATIN   31     /* Init image catalog                          */
#define CATRD   32     /* Read image catalog                          */
#define CATWR   33     /* Write image catalog                         */
#define CATOV   34     /* Use image catalog - covered?                */
#define CATFI   35     /* Find from image catalog                     */
#define PSAVE   36     /* save DTVC.INC parameters                    */
#define WOFM    37     /* Write OFM.                                  */
#define ROFM    38     /* Read OFM.                                   */
#define WLUT    39     /* Write LUT to a channel.                     */
#define RLUT    40     /* Read LUT to a channel.                      */
#define WLOT    41     /* Write LUT to a channel old                  */
#define RLOT    42     /* Read LUT to a channel old                   */
#define WOFMO   43     /* Write OFM old form                          */
#define ROFMO   44     /* Read OFM old form                           */
#define GRAPH   45     /* On/off graphics channel(s)                  */
#define SPLOT   46     /* On/off image channels(s) - obsolete         */
#define SPLAT   47     /* On/off image channels(s) - replace 2/08     */
#define SPLIT   48     /* On/off image channels(s)                    */
#define WGRFX   51     /* Write graphics/cursor colours               */
#define RGRFX   52     /* Read  graphics/cursor colours               */
#define RCURS   61     /* Read the cursor position.                   */
#define RBUTT   62     /* Read the status of the buttons              */
#define WCURS   63     /* Write the cursor position.                  */
#define RCURB   64     /* Read the cursor position and buttons        */
#define CHMULT  82     /* Force character size multiply factor        */
#define WZSCR   83     /* Write zoom/scroll to XAS using ULC          */

static char *opcodes[NUMOP+1] = {

"CODE0 ","CODE1 ","CODE2 ","CODE3 ","CODE4 ",
"CODE5 ","CODE6 ","CODE7 ","CODE8 ","CODE9 ",
"INTGT ","OPEN  ","CLOSE ","INTGTO","WINDO ",
"INITO ","VIEW  ","PSAVEO","XDIE  ","IMWRT ",
"IMRD  ","OIMWRT","OIMRD ","OFILL ","CLEAR ",
"OVECT ","CHARS ","FILL  ","VECT  ","INIT  ",
"CODE30","CATIN ","CATRD ","CATWR ","CATOV ",
"CATFI ","PSAVE ","WOFM  ","ROFM  ","WLUT  ",
"RLUT  ","WLOT  ","RLOT  ","WOFMO ","ROFMO ",
"GRAPH ","SPLOT ","SPLAT ","SPLIT ","CODE49",
"CODE50","WGRFX ","RGRFX ","CODE53","CODE54",
"CODE55","CODE56","CODE57","CODE58","CODE59",
"CODE60","RCURS ","RBUTT ","WCURS ","RCURB ",
"CODE65","CODE66","CODE67","CODE68","CODE69",
"CODE70","CODE71","CODE72","CODE73","CODE74",
"CODE75","CODE76","CODE77","CODE78","CODE79",
"CODE80","CODE81","CHMULT","WZSCR "

   };

static char  *event_names[] = {
        "",
        "",
        "KeyPress",
        "KeyRelease",
        "ButtonPress",
        "ButtonRelease",
        "MotionNotify",
        "EnterNotify",
        "LeaveNotify",
        "FocusIn",
        "FocusOut",
        "KeymapNotify",
        "Expose",
        "GraphicsExpose",
        "NoExpose",
        "VisibilityNotify",
        "CreateNotify",
        "DestroyNotify",
        "UnmapNotify",
        "MapNotify",
        "MapRequest",
        "ReparentNotify",
        "ConfigureNotify",
        "ConfigureRequest",
        "GravityNotify",
        "ResizeRequest",
        "CirculateNotify",
        "CirculateRequest",
        "PropertyNotify",
        "SelectionClear",
        "SelectionRequest",
        "SelectionNotify",
        "ColormapNotify",
        "ClientMessage",
        "MappingNotify"
   };

/* Prototyp section */

/* Override the MIT Standard prototype declarations which are wrong */
/* on all machines                                                  */
#if __STDC__
   typedef int (*XIOErrorHandler) ( Display*, XErrorEvent * );

   extern XIOErrorHandler XSetIOErrorHandler ( XIOErrorHandler );
#endif

#if __STDC__
   void  ProcessAipsRequest ( void );
   int   scrwrt  ( int, int, int, int );
   void  scrdo   ( int, int, int, int, int );
   void  scrdoit ( int, int, int, int, int, int, int, int, int, int,
            int );
   void  scrdo8  ( int, int, int, int, int, int, int, int, int, int,
            int );
   void  scrdo24 ( int, int, int, int, int, int, int, int, int, int,
            int );
#ifdef USE_SHM
   Bool  is_complete ( Display *, XEvent *, char * );
#endif
   int XAS_IOHandler ( Display *, XErrorEvent * );
   void  init ( void );
   void  InitXAS ( void );
   void  InitOldXAS ( void );
   void  SetupWindow ( int, char ** );
   void  user_options ( int, char **, char *, char * );
   int   imwrt ( void );
   int   oimwrt ( void );
   int   imrd ( short int * );
   int   oimrd ( short int * );
   void  resize_canvas ( int, int, int, int );
   void  resize_pressed ( void );
   int   windo_status ( void );
   int   Interogate ( short int * );
   int   InterogateO ( short int * );
   int   PSave ( void );
   int   PSaveO ( void );
   int   ClearChan ( void );
   int   FillChan ( void );
   int   VectChan ( void );
   int   FillChon ( void );
   int   VectChon ( void );
   int   CharChan ( void );
   int   CatInit ( int );
   int   CatRead ( void );
   int   CatWrite ( void );
   int   CatOver ( void );
   int   CatFind ( void );
   int   ViewData ( void );
   int   zoom ( void );
   void  RecordCursor ( int, int );
   void  CheckKey ( KeySym, int );
   int   GetCursor ( void ) ;
   int   movecursor ( void );
   int   readbuttons ( void );
   int   cursor_button ( void );
   short int swapbytes ( short int );
   int   MakeLink ( void );
#if BSD
   int   ReadLink ( int, XASinput *, XASoutput * );
   int   WriteLink ( int, XASinput *, XASoutput * );
#endif
   void  zssslk ( int, int * ) ;
#if VMS
   void  XasAipsReadAST ( void );
   int   ReadLink ( void );
   void  XasAipsWriteAST ( void );
   int   WriteLink ( void );
#endif
   void  closedown ( void );
   void  printbufin ( void );
   void  printbufout ( void );
   int   cmap_wlot ( void );
   int   cmap_rlot ( void );
   int   cmap_wlut ( void );
   int   cmap_rlut ( void );
   int   cmap_wofm ( void );
   int   cmap_rofm ( void );
   int   cmap_wofmo ( void );
   int   cmap_rofmo ( void );
   int   cmap_change ( void );
   int   cmap_graph ( void );
   int   cmap_splot ( void );
   int   cmap_splat ( void );
   int   cmap_split ( void );
   int   cmap_wgrfx ( void );
   int   cmap_rgrfx ( void );
   void  crscol ( int *, int * );
   int   active ( int );

#else
   void  ProcessAipsRequest (/* void */);
   int   scrwrt  (/* int, int, int, int */);
   void  scrdo   (/* int, int, int, int, int */);
   void  scrdoit (/* int, int, int, int, int, int, int, int, int, int,
            int */);
   void  scrdo8  (/* int, int, int, int, int, int, int, int, int, int,
            int */);
   void  scrdo24 (/* int, int, int, int, int, int, int, int, int, int,
            int */);
#ifdef USE_SHM
   Bool  is_complete (/* Display *, XEvent *, char * */);
#endif
   int   XAS_IOHandler (/* Display *, XErrorEvent * */);
   void  init (/* void */);
   void  InitXAS (/* void */);
   void  InitOldXAS (/* void */);
   void  SetupWindow (/* int, char ** */);
   void  user_options (/* int, char **, char *, char * */);
   int   imwrt (/* void */);
   int   imrd (/* short int * */);
   int   oimwrt (/* void */);
   int   oimrd (/* short int * */);
   void  resize_canvas (/* int, int, int, int */);
   void  resize_pressed (/* void */);
   int   windo_status (/* void */);
   int   Interogate (/* short int * */);
   int   InterogateO (/* short int * */);
   int   PSave (/* void */);
   int   PSaveO (/* void */);
   int   ClearChan (/* void */);
   int   FillChan (/* void */);
   int   VectChan (/* void */);
   int   FillChon (/* void */);
   int   VectChon (/* void */);
   int   CharChan (/* void */);
   int   CatInit (/* int */);
   int   CatRead (/* void */);
   int   CatWrite (/* void */);
   int   CatOver (/* void */);
   int   CatFind (/* void */);
   int   ViewData (/* void */);
   int   zoom (/* void */);
   void  RecordCursor (/* int, int */);
   void  CheckKey (/* KeySym, int */);
   int   GetCursor (/* void */) ;
   int   movecursor (/* void */);
   int   readbuttons (/* void */);
   int   cursor_button (/* void */);
   short int swapbytes (/* short int */);
   int   MakeLink (/* void */);
#if BSD
   int   ReadLink (/* int, XASinput *, XASoutput * */);
   int   WriteLink (/* int, XASinput *, XASoutput * */);
#endif
   void  zssslk (/* int, int * */) ;
#if VMS
   void  XasAipsReadAST (/* void */);
   int   ReadLink (/* void */);
   void  XasAipsWriteAST (/* void */);
   int   WriteLink (/* void */);
#endif
   void  closedown (/* void */);
   void  printbufin (/* void */);
   void  printbufout (/* void */);
   int   cmap_wlot (/* void */);
   int   cmap_rlot (/* void */);
   int   cmap_wlut (/* void */);
   int   cmap_rlut (/* void */);
   int   cmap_wofm (/* void */);
   int   cmap_rofm (/* void */);
   int   cmap_wofmo (/* void */);
   int   cmap_rofmo (/* void */);
   int   cmap_change (/* void */);
   int   cmap_graph (/* void */);
   int   cmap_splot (/* void */);
   int   cmap_splat (/* void */);
   int   cmap_split (/* void */);
   int   cmap_wgrfx (/* void */);
   int   cmap_rgrfx (/* void */);
   void  crscol (/* int *, int * */);
   int   active (/* int */);

#endif
--XYZZY--
cat > xas.h << "--XYZZY--"
/*--------------------------------------------------------------------*/
/*! XAS header file                                                   */
/*# TV-IO                                                             */
/*--------------------------------------------------------------------*/
/*;  Copyright (C) 1995-2003, 2008, 2011-2012, 2026                   */
/*;  Associated Universities, Inc. Washington DC, USA.                */
/*;                                                                   */
/*;  This program is free software; you can redistribute it and/or    */
/*;  modify it under the terms of the GNU General Public License as   */
/*;  published by the Free Software Foundation; either version 2 of   */
/*;  the License, or (at your option) any later version.              */
/*;                                                                   */
/*;  This program is distributed in the hope that it will be useful,  */
/*;  but WITHOUT ANY WARRANTY; without even the implied warranty of   */
/*;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    */
/*;  GNU General Public License for more details.                     */
/*;                                                                   */
/*;  You should have received a copy of the GNU General Public        */
/*;  License along with this program; if not, write to the Free       */
/*;  Software Foundation, Inc., 675 Massachusetts Ave, Cambridge,     */
/*;  MA 02139, USA.                                                   */
/*;                                                                   */
/*;  Correspondence concerning AIPS should be addressed as follows:   */
/*;         Internet email: aipsmail@nrao.edu.                        */
/*;         Postal address: AIPS Project Office                       */
/*;                         National Radio Astronomy Observatory      */
/*;                         520 Edgemont Road                         */
/*;                         Charlottesville, VA 22903-2475 USA        */
/*--------------------------------------------------------------------*/
/* #define BSD 1  */                    /* Select operating system    */
/* #define VMS 0  */                    /* set desired system to 1    */
#ifdef _BSD                             /* Unix needs BSD = 1         */
#define BSD 1
#undef VMS                              /* Do not us VMS specific code*/
#endif
#ifdef _VMS                             /* DEC VMS                    */
#define VMS 1
#undef BSD                              /* No Unix-specific code      */
#endif
#ifdef _AIX                             /* IBM AIX needs BSD = 1 also */
#define AIX 1                           /* use AIX specific code      */
#undef VMS                              /* Do not us VMS specific code*/
#endif

#include <stdio.h>
                                        /* We must override MIT error */
                                        /* in prototype               */
#if __STDC__
#define XIOErrorHandler XFuckedUp1
#define XSetIOErrorHandler XFuckedUp2
#endif
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#if __STDC__
#undef  XIOErrorHandler
#undef  XSetIOErrorHandler
#endif

#if BSD

/* #include <X11/bitmaps/xlogo64> */

/* Header info needed for socket routines (including i/o) */

#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <ctype.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netdb.h>
#include <netinet/in.h>

/* Header for shared memory extension */

#ifdef USE_SHM
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/extensions/XShm.h>
#endif

extern struct sockaddr_un server_un;
extern struct sockaddr_in server_in;
extern struct servent *sp_in;

extern Bool connected;
extern int AipsSocket, AipsLink;
extern int domain_type;
#define UNIX_DOMAIN 0
#define INET_DOMAIN 1

#endif /* BSD */


#if VMS

/* ##include "xlogo64." */
#include <ssdef.h>
#include <iodef.h>
#include <descrip.h>

#define XAS_SOCKET "XasSocket"     /* mailbox name AIPS --> XAS */
#define AIPS_SOCKET "AipsSocket"   /* mailbox name XAS --> AIPS */

#define emask ExposureMask|KeyPressMask|StructureNotifyMask|PointerMotionMask

#define maxmsg 16400
#define bufquo 16400

typedef struct {
   short int ioresult;
   short int iolength;
   int unused;
} IOSB;

extern int XasLink, AipsLink;
extern IOSB read_status, write_status;
extern int read_in_progress, write_in_progress;
static  (dtime, "0 00:00:00.25");
extern int delta[2];

#endif /* VMS */

                                        /* Screen parameters          */
extern int Ngrey, NgreyUser;
#define NGREYMAX 16
#define NGRAPH   8
#define NGRPHCOL 19
                                        /* total number of planes     */
                                        /* (grey-scale + graphics)    */
#define NGRTOT   (NGREYMAX+NGRAPH)
#define MAXZOOM  16
#define MAXCAT   (MAXZOOM*MAXZOOM)
                                        /* Border allocations         */
/* #define TEXT_SPACE      0 */         /* empty space @ bottom screen*/
#define TEXT_SPACE      69              /* preferred at NRAO?         */
                                        /* I can find no way to ask   */
                                        /* the window manager the size*/
                                        /* of its top banner.         */
                                        /* They need to be visible to */
                                        /* allow window resize, move..*/
#ifdef AIX                              /* Numbers for IBM Motif      */
#define SCREEN_LEFT    11
#define SCREEN_RIGHT   11
#define SCREEN_TOP     34
#define SCREEN_BOTTOM  (11 + TEXT_SPACE)
#else                                   /* Numbers for SUN OpenLook   */
#define SCREEN_LEFT     5
#define SCREEN_RIGHT    5
#define SCREEN_TOP     26
#define SCREEN_BOTTOM   (5 + TEXT_SPACE)
#endif
                                        /* total screen size          */
                                        /* used in positioning        */
extern int twidth, theight, bwid;
                                        /* size of logical screen     */
                                        /* must be EVEN numbers !     */
extern int Screen_Height, Screen_Width, visnum;
extern int Cur_Xsize, Cur_Ysize, Cur_Xzero, Cur_Yzero;
                                        /* number grey levels in:     */
                                        /* total levels: NColour+1-19 */
extern int NColour, NValue, OColour;    /* for graphics, and cursor   */
                                        /* number of grey-scale (OFM) */
                                        /* intensities                */
#define NINTENS       2046
#define FNINTENS     (NGREYMAX*NINTENS)
#define COLORSHIFT      8               /* 255 max from ofm then shift*/
                                        /* 8 bits left for col table  */

                                        /* cursor [0], graphics [1-8] */
extern int rgrfx[9], ggrfx[9], bgrfx[9], rgcol[20], ggcol[20], bgcol[20];
extern int grfvc[256];
extern float Gamma ;

#define OK 0

#define NPARMS 4
typedef struct {
   short int
      opcode,
      parms[NPARMS],
      data_length;
   union {
      int ldata[8192];
      short int idata[16384];
      unsigned char data[32768];
      } u;
} XASinput;
typedef struct {
   short int
      return_data_length,
      status;
   union {
      int ldata[8192];
      short int idata[16384];
      unsigned char data[32768];
      } u;
} XASoutput;

                                        /* Global variables           */
extern XASinput xbuf;                   /* I/O buffer for AIPS        */
extern XASoutput ybuf;                  /* I/O buffer for AIPS        */
extern int Z_sndbuf, Z_rcvbuf, Z_sndini, Z_rcvini; /* I/O buffer sizes       */
extern Bool XasDebug;                          /* Toggle with F8             */
extern Bool XDebug;                            /* Toggle with F9             */
extern Bool ByteSwapped;                       /* Local byte swapped machine */
extern Bool ByteSwapDisp;                      /* Display byte swapped       */
extern Bool RedBigger;                         /* Color mask value R>B       */
extern Display *display;
extern int screen_num;
extern Cursor cursor;
extern Window win;
extern GC ImageGC;                             /* X11 graphics contexts for  */
                                        /* drawing images & graphics  */
                                        /* Image data structures:     */
extern XImage *plane[NGREYMAX];                /* grey-scale planes          */
extern XImage *line;                           /* buffer for zoomed img line */
extern XImage *gline;                          /* buffer for zoomed graphics */
                                        /* line                       */
/* All graphs are kept in one plane via a binary trick                */
/* a pixel value of 1 means only graph 1 on, 2 means only graph 2 on  */
/* a pixel value of 4 means only graph 3 on, 8 means only graph 4 on  */
/* a pixel value of 3 means both graph 1 and 2 on, 15 means all 4 on, */
/* etc. */
extern XImage *graph;                          /* graphics overlay           */
extern short int *plane_data[NGREYMAX];        /* data storage               */
extern unsigned char *plane_short[NGREYMAX];   /* data storage               */
extern unsigned char *line_data;
extern unsigned char *graph_data;
extern int *line_idata;

                                        /* Shared memory              */
extern int using_shm;                          /* set True if using SHM      */
#ifdef USE_SHM
extern XShmSegmentInfo plane_info[NGREYMAX];   /* shm info for image planes  */
extern XShmSegmentInfo graph_info;             /* shm info for graphics plane*/
extern XShmSegmentInfo line_info;              /* shm info for zoom buffers  */
#endif

extern int rwgraph, depth;
extern unsigned char gph_mask;

extern int using_24b, BitsPerPixel ;
extern int rofm[FNINTENS], gofm[FNINTENS],     /* red, green and blue OFM    */
    bofm[FNINTENS];                     /* registers                  */
                                        /* red, green and blue LUT    */
extern int *rlut[NGREYMAX], *glut[NGREYMAX], *blut[NGREYMAX];
extern int *pix2int;                           /* input int <- assigned pixv */
extern unsigned long *int2pix;                 /* input int -> assigned pixv */

extern int TvStatus[NGREYMAX+NGRAPH];          /* TV Image + Graphics status */

extern int params[256];                        /* DTVC.INC                   */

extern char imgcat[NGREYMAX][MAXCAT][1024] ;
extern char grpcat[NGRAPH][1024];
extern int  dircat[NGREYMAX][MAXCAT][5] ;
extern char typcat[NGREYMAX][MAXCAT][2] ;
extern int  dirgcat[NGRAPH][5] ;
extern char typgcat[NGRAPH][2] ;
extern int  lastcat[NGREYMAX];

extern int cur_chan[NGREYMAX], on_chan[NGREYMAX][3][4], x_split, y_split, Q_same;
extern int cursor_x, cursor_y;
extern int size_i2;
extern int char_mult;

extern int big_screen;                         /* True if screen is at max.  */
                                        /* size, FALSE otherwise      */
extern int cur_xcorn, cur_ycorn;               /* current location of top-   */
                                        /* left corner of smaller     */
                                        /* window                     */
extern int cur_xsize, cur_ysize;               /* current size of smaller    */
                                        /* window                     */

extern Colormap TV_colour;
extern XColor *colour_table;
extern XColor fg_curs, bg_curs;
extern int cursor_shape;                      /* standard cursor shape number*/
extern int start_icon;                        /* > 0 -> start in icon */
extern unsigned long curs_pixel[2];
extern unsigned char image_offset;
extern unsigned char graphics_offset;

extern int button_a, button_b, button_c, button_d;
extern int upleft_x[NGREYMAX], upleft_y[NGREYMAX], upleft_mag;
extern int sc_centre_x, sc_centre_y, sc_zoom_mag;
extern int sc_width, sc_height, sc_width2, sc_height2;
extern int ic_width, ic_height, ic_xcorn, ic_ycorn;
extern int scrhold, numhold, Maxhold, uxs, uxe, uys, uye;

extern char *ProgName;

                                        /* Useful macros              */
#ifndef min
#define min(a,b) ((a)<(b)?(a):(b))
#endif

#ifndef max
#define max(a,b) ((a)>(b)?(a):(b))
#endif

#define intswap(a,b) { int tmp; tmp=a; a=b; b=tmp; }

#define Memory_x(aips_x)  ((aips_x) - 1)
#define Memory_y(aips_y)  (Screen_Height - (aips_y))
#define Aips_x(memory_x)  ((memory_x) + 1)
#define Aips_y(memory_y)  (Screen_Height - (memory_y))
#define chg_s(var,val,msk) ((var) = ((var)&(~(msk)))|((val) ? (msk) : 0))
#define chg_g(var,msk) (((var)&(msk)) ? 1 : 0)

extern int buffered;                           /* True if socket is          */
                                        /* buffered                   */
/* Defined opcodes */
#define NUMOP   83                      /* Largest opcode             */

extern int bufferop[NUMOP+1];                  /* bufferop[OP] is True if    */
                                        /* there is no status return  */
                                        /* in buffered mode           */
#define INTGT   10     /* Interrogate: get XAS major parameters       */
#define OPEN    11     /* Opens the XAS connection                    */
#define CLOSE   12     /* Close the XAS, allows new connections       */
#define INTGTO  13     /* Interrogate: get XAS old major parameters   */
#define WINDO   14     /* Read, write the X window size               */
#define INITO   15     /* init the TV old form                        */
#define VIEW    16     /* Do/hold screen updates                      */
#define PSAVEO  17     /* save DTVC.INC parameters old                */
#define XDIE    18     /* close down XAS and lock servers             */
#define IMWRT   19     /* Write image line to some channel            */
#define IMRD    20     /* Read image line from some channel           */
#define OIMWRT  21     /* Write image line to some channel OLD        */
#define OIMRD   22     /* Read image line from some channel OLD       */
#define OFILL   23     /* fill area in some or all channels           */
#define CLEAR   24     /* Clear some or all channels                  */
#define OVECT   25     /* connect two points with line                */
#define CHARS   26     /* write character string                      */
#define FILL    27     /* fill area in some or all channels           */
#define VECT    28     /* connect two points with line                */
#define INIT    29     /* init the TV                                 */
#define CATIN   31     /* Init image catalog                          */
#define CATRD   32     /* Read image catalog                          */
#define CATWR   33     /* Write image catalog                         */
#define CATOV   34     /* Use image catalog - covered?                */
#define CATFI   35     /* Find from image catalog                     */
#define PSAVE   36     /* save DTVC.INC parameters                    */
#define WOFM    37     /* Write OFM.                                  */
#define ROFM    38     /* Read OFM.                                   */
#define WLUT    39     /* Write LUT to a channel.                     */
#define RLUT    40     /* Read LUT to a channel.                      */
#define WLOT    41     /* Write LUT to a channel old                  */
#define RLOT    42     /* Read LUT to a channel old                   */
#define WOFMO   43     /* Write OFM old form                          */
#define ROFMO   44     /* Read OFM old form                           */
#define GRAPH   45     /* On/off graphics channel(s)                  */
#define SPLOT   46     /* On/off image channels(s) - obsolete         */
#define SPLAT   47     /* On/off image channels(s) - replace 2/08     */
#define SPLIT   48     /* On/off image channels(s)                    */
#define WGRFX   51     /* Write graphics/cursor colours               */
#define RGRFX   52     /* Read  graphics/cursor colours               */
#define RCURS   61     /* Read the cursor position.                   */
#define RBUTT   62     /* Read the status of the buttons              */
#define WCURS   63     /* Write the cursor position.                  */
#define RCURB   64     /* Read the cursor position and buttons        */
#define CHMULT  82     /* Force character size multiply factor        */
#define WZSCR   83     /* Write zoom/scroll to XAS using ULC          */

static char *opcodes[NUMOP+1] = {

"CODE0 ","CODE1 ","CODE2 ","CODE3 ","CODE4 ",
"CODE5 ","CODE6 ","CODE7 ","CODE8 ","CODE9 ",
"INTGT ","OPEN  ","CLOSE ","INTGTO","WINDO ",
"INITO ","VIEW  ","PSAVEO","XDIE  ","IMWRT ",
"IMRD  ","OIMWRT","OIMRD ","OFILL ","CLEAR ",
"OVECT ","CHARS ","FILL  ","VECT  ","INIT  ",
"CODE30","CATIN ","CATRD ","CATWR ","CATOV ",
"CATFI ","PSAVE ","WOFM  ","ROFM  ","WLUT  ",
"RLUT  ","WLOT  ","RLOT  ","WOFMO ","ROFMO ",
"GRAPH ","SPLOT ","SPLAT ","SPLIT ","CODE49",
"CODE50","WGRFX ","RGRFX ","CODE53","CODE54",
"CODE55","CODE56","CODE57","CODE58","CODE59",
"CODE60","RCURS ","RBUTT ","WCURS ","RCURB ",
"CODE65","CODE66","CODE67","CODE68","CODE69",
"CODE70","CODE71","CODE72","CODE73","CODE74",
"CODE75","CODE76","CODE77","CODE78","CODE79",
"CODE80","CODE81","CHMULT","WZSCR "

   };

static char  *event_names[] = {
        "",
        "",
        "KeyPress",
        "KeyRelease",
        "ButtonPress",
        "ButtonRelease",
        "MotionNotify",
        "EnterNotify",
        "LeaveNotify",
        "FocusIn",
        "FocusOut",
        "KeymapNotify",
        "Expose",
        "GraphicsExpose",
        "NoExpose",
        "VisibilityNotify",
        "CreateNotify",
        "DestroyNotify",
        "UnmapNotify",
        "MapNotify",
        "MapRequest",
        "ReparentNotify",
        "ConfigureNotify",
        "ConfigureRequest",
        "GravityNotify",
        "ResizeRequest",
        "CirculateNotify",
        "CirculateRequest",
        "PropertyNotify",
        "SelectionClear",
        "SelectionRequest",
        "SelectionNotify",
        "ColormapNotify",
        "ClientMessage",
        "MappingNotify"
   };

/* Prototyp section */

/* Override the MIT Standard prototype declarations which are wrong */
/* on all machines                                                  */
#if __STDC__
   typedef int (*XIOErrorHandler) ( Display*, XErrorEvent * );

   extern XIOErrorHandler XSetIOErrorHandler ( XIOErrorHandler );
#endif

#if __STDC__
   void  ProcessAipsRequest ( void );
   int   scrwrt  ( int, int, int, int );
   void  scrdo   ( int, int, int, int, int );
   void  scrdoit ( int, int, int, int, int, int, int, int, int, int,
            int );
   void  scrdo8  ( int, int, int, int, int, int, int, int, int, int,
            int );
   void  scrdo24 ( int, int, int, int, int, int, int, int, int, int,
            int );
#ifdef USE_SHM
   Bool  is_complete ( Display *, XEvent *, char * );
#endif
   int XAS_IOHandler ( Display *, XErrorEvent * );
   void  init ( void );
   void  InitXAS ( void );
   void  InitOldXAS ( void );
   void  SetupWindow ( int, char ** );
   void  user_options ( int, char **, char *, char * );
   int   imwrt ( void );
   int   oimwrt ( void );
   int   imrd ( short int * );
   int   oimrd ( short int * );
   void  resize_canvas ( int, int, int, int );
   void  resize_pressed ( void );
   int   windo_status ( void );
   int   Interogate ( short int * );
   int   InterogateO ( short int * );
   int   PSave ( void );
   int   PSaveO ( void );
   int   ClearChan ( void );
   int   FillChan ( void );
   int   VectChan ( void );
   int   FillChon ( void );
   int   VectChon ( void );
   int   CharChan ( void );
   int   CatInit ( int );
   int   CatRead ( void );
   int   CatWrite ( void );
   int   CatOver ( void );
   int   CatFind ( void );
   int   ViewData ( void );
   int   zoom ( void );
   void  RecordCursor ( int, int );
   void  CheckKey ( KeySym, int );
   int   GetCursor ( void ) ;
   int   movecursor ( void );
   int   readbuttons ( void );
   int   cursor_button ( void );
   short int swapbytes ( short int );
   int   MakeLink ( void );
#if BSD
   int   ReadLink ( int, XASinput *, XASoutput * );
   int   WriteLink ( int, XASinput *, XASoutput * );
#endif
   void  zssslk ( int, int * ) ;
#if VMS
   void  XasAipsReadAST ( void );
   int   ReadLink ( void );
   void  XasAipsWriteAST ( void );
   int   WriteLink ( void );
#endif
   void  closedown ( void );
   void  printbufin ( void );
   void  printbufout ( void );
   int   cmap_wlot ( void );
   int   cmap_rlot ( void );
   int   cmap_wlut ( void );
   int   cmap_rlut ( void );
   int   cmap_wofm ( void );
   int   cmap_rofm ( void );
   int   cmap_wofmo ( void );
   int   cmap_rofmo ( void );
   int   cmap_change ( void );
   int   cmap_graph ( void );
   int   cmap_splot ( void );
   int   cmap_splat ( void );
   int   cmap_split ( void );
   int   cmap_wgrfx ( void );
   int   cmap_rgrfx ( void );
   void  crscol ( int *, int * );
   int   active ( int );

#else
   void  ProcessAipsRequest (/* void */);
   int   scrwrt  (/* int, int, int, int */);
   void  scrdo   (/* int, int, int, int, int */);
   void  scrdoit (/* int, int, int, int, int, int, int, int, int, int,
            int */);
   void  scrdo8  (/* int, int, int, int, int, int, int, int, int, int,
            int */);
   void  scrdo24 (/* int, int, int, int, int, int, int, int, int, int,
            int */);
#ifdef USE_SHM
   Bool  is_complete (/* Display *, XEvent *, char * */);
#endif
   int   XAS_IOHandler (/* Display *, XErrorEvent * */);
   void  init (/* void */);
   void  InitXAS (/* void */);
   void  InitOldXAS (/* void */);
   void  SetupWindow (/* int, char ** */);
   void  user_options (/* int, char **, char *, char * */);
   int   imwrt (/* void */);
   int   imrd (/* short int * */);
   int   oimwrt (/* void */);
   int   oimrd (/* short int * */);
   void  resize_canvas (/* int, int, int, int */);
   void  resize_pressed (/* void */);
   int   windo_status (/* void */);
   int   Interogate (/* short int * */);
   int   InterogateO (/* short int * */);
   int   PSave (/* void */);
   int   PSaveO (/* void */);
   int   ClearChan (/* void */);
   int   FillChan (/* void */);
   int   VectChan (/* void */);
   int   FillChon (/* void */);
   int   VectChon (/* void */);
   int   CharChan (/* void */);
   int   CatInit (/* int */);
   int   CatRead (/* void */);
   int   CatWrite (/* void */);
   int   CatOver (/* void */);
   int   CatFind (/* void */);
   int   ViewData (/* void */);
   int   zoom (/* void */);
   void  RecordCursor (/* int, int */);
   void  CheckKey (/* KeySym, int */);
   int   GetCursor (/* void */) ;
   int   movecursor (/* void */);
   int   readbuttons (/* void */);
   int   cursor_button (/* void */);
   short int swapbytes (/* short int */);
   int   MakeLink (/* void */);
#if BSD
   int   ReadLink (/* int, XASinput *, XASoutput * */);
   int   WriteLink (/* int, XASinput *, XASoutput * */);
#endif
   void  zssslk (/* int, int * */) ;
#if VMS
   void  XasAipsReadAST (/* void */);
   int   ReadLink (/* void */);
   void  XasAipsWriteAST (/* void */);
   int   WriteLink (/* void */);
#endif
   void  closedown (/* void */);
   void  printbufin (/* void */);
   void  printbufout (/* void */);
   int   cmap_wlot (/* void */);
   int   cmap_rlot (/* void */);
   int   cmap_wlut (/* void */);
   int   cmap_rlut (/* void */);
   int   cmap_wofm (/* void */);
   int   cmap_rofm (/* void */);
   int   cmap_wofmo (/* void */);
   int   cmap_rofmo (/* void */);
   int   cmap_change (/* void */);
   int   cmap_graph (/* void */);
   int   cmap_splot (/* void */);
   int   cmap_splat (/* void */);
   int   cmap_split (/* void */);
   int   cmap_wgrfx (/* void */);
   int   cmap_rgrfx (/* void */);
   void  crscol (/* int *, int * */);
   int   active (/* int */);

#endif
--XYZZY--
cat > Xas.icon << "--XYZZY--"
/* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=8
 This cannot be read by iconedit which uses 16-bit words only and which
 puts the bits in the reverse order!  Files below, Xas.iconedit and
 TEST.FOR, are for iconediting and conversion to this format.
  CVX ICON */
	0x00,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0x00,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0x00,0x80,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xC0,0x00,0x3F,0x1C,0xFE,0xFF,0xFF,0xFF,
	0x80,0x03,0xDE,0xEB,0xFD,0xFF,0xFF,0xFF,
	0x00,0x06,0xDC,0xEB,0xFD,0xFF,0xFF,0xFF,
	0x00,0x0E,0xD8,0xEB,0xFD,0xFF,0xFF,0xFF,
	0x00,0x3C,0xD8,0x1B,0xFE,0xFF,0xFF,0xFF,
	0x08,0x7C,0x38,0xE8,0xFD,0xFF,0xFF,0xFF,
	0x18,0xF8,0xF8,0xED,0xFD,0xFF,0xFF,0xFF,
	0x3C,0xF8,0xF9,0xEE,0xFD,0xEF,0xFF,0xFF,
	0xFC,0xF8,0x79,0x1F,0xFE,0xC0,0xFF,0xFF,
	0xFC,0xF9,0xF9,0xFF,0x3F,0x80,0xFF,0xFF,
	0xFC,0xF9,0xFF,0xFF,0x1F,0xB0,0xFF,0xFF,
	0xFC,0xF9,0xFF,0xFF,0x0F,0x32,0xFE,0xFF,
	0xFC,0xF9,0xFF,0xFF,0x07,0x01,0xFC,0xFF,
	0xFC,0xF9,0xFF,0xFF,0x07,0x01,0xF8,0xFF,
	0xFC,0xFB,0xFF,0xFF,0x00,0x03,0xF8,0xFF,
	0xFC,0xFF,0xFF,0x3F,0x00,0x40,0xF8,0xFF,
	0xFC,0xFF,0xFF,0x3F,0x00,0x80,0xFF,0xFF,
	0xFC,0xFF,0xFF,0x0F,0x00,0x00,0xFC,0xFF,
	0xFC,0xFF,0xFF,0x07,0x00,0x04,0xFE,0xFF,
	0xFC,0xFF,0xFF,0x07,0x00,0x88,0xFF,0xFF,
	0xFC,0xFF,0xFF,0x03,0x00,0xF0,0xFF,0xFF,
	0xFC,0xFF,0xFF,0x00,0x00,0xF8,0xFF,0xFF,
	0xFC,0xFF,0x7F,0x00,0x00,0xF8,0xFF,0xFF,
	0xFC,0xFF,0x03,0x00,0x00,0xF8,0xFF,0xFF,
	0xFC,0xFF,0x00,0x00,0x00,0xF8,0xFF,0xFF,
	0xFC,0xFF,0x00,0x00,0x00,0xF0,0xFF,0xFF,
	0xFC,0x7F,0x00,0x00,0x00,0xF0,0xFF,0xFF,
	0xFC,0x7F,0x00,0x00,0x00,0xE0,0xFF,0xFF,
	0xFC,0x7F,0x00,0x00,0x00,0xE0,0xFF,0xFF,
	0xFC,0xFF,0x00,0x00,0x00,0xC0,0xFF,0xFF,
	0xFC,0xFF,0x00,0x00,0x00,0xC0,0xFF,0xFF,
	0xFC,0xFF,0x00,0x00,0x60,0x80,0xFF,0xFF,
	0xFC,0xFF,0x00,0x00,0x90,0x01,0xFF,0xFF,
	0xFC,0xFF,0x00,0x80,0x8C,0x03,0xFF,0xFF,
	0xFC,0x7F,0x20,0xFA,0x0F,0x03,0xFE,0xFF,
	0xFC,0x7F,0xF0,0xFD,0x0F,0x0F,0xFC,0xFF,
	0xFC,0x3F,0x08,0xFC,0x1F,0x3F,0xF8,0xFF,
	0xFC,0x1F,0x08,0xFC,0x1F,0x3E,0xF0,0xFF,
	0xFC,0x1F,0x04,0xFE,0x0F,0x3E,0xF0,0xFF,
	0xFD,0x1F,0x04,0xFF,0x0F,0x1E,0xF0,0xFF,
	0xFF,0x0F,0x06,0xFE,0x0F,0x1E,0xF0,0xFF,
	0xFF,0x0F,0x06,0xF8,0x1F,0x3E,0xF0,0xFF,
	0xFF,0x1F,0x08,0xF8,0xFF,0x7F,0xF0,0xFF,
	0xFF,0x7F,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
--XYZZY--
cat > Xas.iconedit << "--XYZZY--"
/* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
 */
	0x000F,0xFFFF,0xFFFF,0xFFFF,
	0x0007,0xFFFF,0xFFFF,0xFFFF,
	0x0001,0xFFFF,0xFFFF,0xFFFF,
	0x0300,0xFC38,0x7FFF,0xFFFF,
	0x01C0,0x7BD7,0xBFFF,0xFFFF,
	0x0060,0x3BD7,0xBFFF,0xFFFF,
	0x0070,0x1BD7,0xBFFF,0xFFFF,
	0x003C,0x1BD8,0x7FFF,0xFFFF,
	0x103E,0x1C17,0xBFFF,0xFFFF,
	0x181F,0x1FB7,0xBFFF,0xFFFF,
	0x3C1F,0x9F77,0xBFF7,0xFFFF,
	0x3F1F,0x9EF8,0x7F03,0xFFFF,
	0x3F9F,0x9FFF,0xFC01,0xFFFF,
	0x3F9F,0xFFFF,0xF80D,0xFFFF,
	0x3F9F,0xFFFF,0xF04C,0x7FFF,
	0x3F9F,0xFFFF,0xE080,0x3FFF,
	0x3F9F,0xFFFF,0xE080,0x1FFF,
	0x3FDF,0xFFFF,0x00C0,0x1FFF,
	0x3FFF,0xFFFC,0x0002,0x1FFF,
	0x3FFF,0xFFFC,0x0001,0xFFFF,
	0x3FFF,0xFFF0,0x0000,0x3FFF,
	0x3FFF,0xFFE0,0x0020,0x7FFF,
	0x3FFF,0xFFE0,0x0011,0xFFFF,
	0x3FFF,0xFFC0,0x000F,0xFFFF,
	0x3FFF,0xFF00,0x001F,0xFFFF,
	0x3FFF,0xFE00,0x001F,0xFFFF,
	0x3FFF,0xC000,0x001F,0xFFFF,
	0x3FFF,0x0000,0x001F,0xFFFF,
	0x3FFF,0x0000,0x000F,0xFFFF,
	0x3FFE,0x0000,0x000F,0xFFFF,
	0x3FFE,0x0000,0x0007,0xFFFF,
	0x3FFE,0x0000,0x0007,0xFFFF,
	0x3FFF,0x0000,0x0003,0xFFFF,
	0x3FFF,0x0000,0x0003,0xFFFF,
	0x3FFF,0x0000,0x0601,0xFFFF,
	0x3FFF,0x0000,0x0980,0xFFFF,
	0x3FFF,0x0001,0x31C0,0xFFFF,
	0x3FFE,0x045F,0xF0C0,0x7FFF,
	0x3FFE,0x0FBF,0xF0F0,0x3FFF,
	0x3FFC,0x103F,0xF8FC,0x1FFF,
	0x3FF8,0x103F,0xF87C,0x0FFF,
	0x3FF8,0x207F,0xF07C,0x0FFF,
	0xBFF8,0x20FF,0xF078,0x0FFF,
	0xFFF0,0x607F,0xF078,0x0FFF,
	0xFFF0,0x601F,0xF87C,0x0FFF,
	0xFFF8,0x101F,0xFFFE,0x0FFF,
	0xFFFE,0x1FFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0x0000,0x0000,0x0000,0x0000,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
--XYZZY--
cat > Xas2.icon << "--XYZZY--"
/* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
 This cannot be read by iconedit which uses 16-bit words only and which
 puts the bits in the reverse order!  Files below, Xas.iconedit and
 TEST.FOR, are for iconediting and conversion to this format.
  CVX ICON */
	0x00,0xF0,0xFF,0xF0,0xF3,0x1F,0x9F,0xFF,
	0x00,0xE0,0x7F,0xE6,0xF1,0x3F,0x9F,0xFB,
	0x00,0x80,0x7F,0xE6,0xF1,0x3F,0xFF,0xF9,
	0xC0,0x00,0xFF,0xE7,0xF2,0x3F,0x88,0xE0,
	0x80,0x03,0xFE,0x73,0x72,0x20,0x93,0xF9,
	0x00,0x06,0xFC,0x79,0xF3,0x3F,0x93,0xF9,
	0x00,0x0E,0xF8,0x2C,0xC0,0x3F,0x93,0xF9,
	0x00,0x3C,0x78,0xE0,0xF3,0x3F,0x93,0xE9,
	0x08,0x7C,0x78,0xF0,0xE1,0x3F,0x08,0xF1,
	0x18,0xF8,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,
	0x3C,0xF8,0xF9,0xFF,0xFF,0xEF,0xFF,0xFF,
	0xFC,0xF8,0xF9,0xFF,0xFF,0xC0,0xFF,0xFF,
	0xFC,0xF9,0xF9,0xFF,0x3F,0x80,0xFF,0xFF,
	0xFC,0xF9,0xFF,0xFF,0x1F,0xB0,0xFF,0xFF,
	0xFC,0xF9,0xFF,0xFF,0x0F,0x32,0xFE,0xFF,
	0xFC,0xF9,0xFF,0xFF,0x07,0x01,0xFC,0xFF,
	0xFC,0xF9,0xFF,0xFF,0x07,0x01,0xF8,0xFF,
	0xFC,0xFB,0xFF,0xFF,0x00,0x03,0xF8,0xFF,
	0xFC,0xFF,0xFF,0x3F,0x00,0x40,0xF8,0xFF,
	0xFC,0xFF,0xFF,0x3F,0x00,0x80,0xFF,0xFF,
	0xFC,0xFF,0xFF,0x0F,0x00,0x00,0xFC,0xFF,
	0xFC,0xFF,0xFF,0x07,0x00,0x04,0xFE,0xFF,
	0xFC,0xFF,0xFF,0x07,0x00,0x88,0xFF,0xFF,
	0xFC,0xFF,0xFF,0x03,0x00,0xF0,0xFF,0xFF,
	0xFC,0xFF,0xFF,0x00,0x00,0xF8,0xFF,0xFF,
	0xFC,0xFF,0x7F,0x00,0x00,0xF8,0xFF,0xFF,
	0xFC,0xFF,0x03,0x00,0x00,0xF8,0xFF,0xFF,
	0xFC,0xFF,0x00,0x00,0x00,0xF8,0xFF,0xFF,
	0xFC,0xFF,0x00,0x00,0x00,0xF0,0xFF,0xFF,
	0xFC,0x7F,0x00,0x00,0x00,0xF0,0xFF,0xFF,
	0xFC,0x7F,0x00,0x00,0x00,0xE0,0xFF,0xFF,
	0xFC,0x7F,0x00,0x00,0x00,0xE0,0xFF,0xFF,
	0xFC,0xFF,0x00,0x00,0x00,0xC0,0xFF,0xFF,
	0xFC,0xFF,0x00,0x00,0x00,0xC0,0xFF,0xFF,
	0xFC,0xFF,0x00,0x00,0x60,0x80,0xFF,0xFF,
	0xFC,0xFF,0x00,0x00,0x90,0x01,0xFF,0xFF,
	0xFC,0xFF,0x00,0x80,0x8C,0x03,0xFF,0xFF,
	0xFC,0x7F,0x20,0xFA,0x0F,0x03,0xFE,0xFF,
	0xFC,0x7F,0xF0,0xFD,0x0F,0x0F,0xFC,0xFF,
	0xFC,0x3F,0x08,0xFC,0x1F,0x3F,0xF8,0xFF,
	0xFC,0x1F,0x08,0xFC,0x1F,0x3E,0xF0,0xFF,
	0xFC,0x1F,0x04,0xFE,0x0F,0x3E,0xF0,0xFF,
	0xFD,0x1F,0x04,0xFF,0x0F,0x1E,0xF0,0xFF,
	0xFF,0x0F,0x06,0xFE,0x0F,0x1E,0xF0,0xFF,
	0xFF,0x0F,0x06,0xF8,0x1F,0x3E,0xF0,0xFF,
	0xFF,0x1F,0x08,0xF8,0xFF,0x7F,0xF0,0xFF,
	0xFF,0x7F,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
--XYZZY--
cat > Xas2.iconedit << "--XYZZY--"
/* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
 */
	0x000F,0xFF0F,0xCFF8,0xF9FF,
	0x0007,0xFE67,0x8FFC,0xF9DF,
	0x0001,0xFE67,0x8FFC,0xFF9F,
	0x0300,0xFFE7,0x4FFC,0x1107,
	0x01C0,0x7FCE,0x4E04,0xC99F,
	0x0060,0x3F9E,0xCFFC,0xC99F,
	0x0070,0x1F34,0x03FC,0xC99F,
	0x003C,0x1E07,0xCFFC,0xC997,
	0x103E,0x1E0F,0x87FC,0x108F,
	0x181F,0x1FFF,0xFFFF,0xFFFF,
	0x3C1F,0x9FFF,0xFFF7,0xFFFF,
	0x3F1F,0x9FFF,0xFF03,0xFFFF,
	0x3F9F,0x9FFF,0xFC01,0xFFFF,
	0x3F9F,0xFFFF,0xF80D,0xFFFF,
	0x3F9F,0xFFFF,0xF04C,0x7FFF,
	0x3F9F,0xFFFF,0xE080,0x3FFF,
	0x3F9F,0xFFFF,0xE080,0x1FFF,
	0x3FDF,0xFFFF,0x00C0,0x1FFF,
	0x3FFF,0xFFFC,0x0002,0x1FFF,
	0x3FFF,0xFFFC,0x0001,0xFFFF,
	0x3FFF,0xFFF0,0x0000,0x3FFF,
	0x3FFF,0xFFE0,0x0020,0x7FFF,
	0x3FFF,0xFFE0,0x0011,0xFFFF,
	0x3FFF,0xFFC0,0x000F,0xFFFF,
	0x3FFF,0xFF00,0x001F,0xFFFF,
	0x3FFF,0xFE00,0x001F,0xFFFF,
	0x3FFF,0xC000,0x001F,0xFFFF,
	0x3FFF,0x0000,0x001F,0xFFFF,
	0x3FFF,0x0000,0x000F,0xFFFF,
	0x3FFE,0x0000,0x000F,0xFFFF,
	0x3FFE,0x0000,0x0007,0xFFFF,
	0x3FFE,0x0000,0x0007,0xFFFF,
	0x3FFF,0x0000,0x0003,0xFFFF,
	0x3FFF,0x0000,0x0003,0xFFFF,
	0x3FFF,0x0000,0x0601,0xFFFF,
	0x3FFF,0x0000,0x0980,0xFFFF,
	0x3FFF,0x0001,0x31C0,0xFFFF,
	0x3FFE,0x045F,0xF0C0,0x7FFF,
	0x3FFE,0x0FBF,0xF0F0,0x3FFF,
	0x3FFC,0x103F,0xF8FC,0x1FFF,
	0x3FF8,0x103F,0xF87C,0x0FFF,
	0x3FF8,0x207F,0xF07C,0x0FFF,
	0xBFF8,0x20FF,0xF078,0x0FFF,
	0xFFF0,0x607F,0xF078,0x0FFF,
	0xFFF0,0x601F,0xF87C,0x0FFF,
	0xFFF8,0x101F,0xFFFE,0x0FFF,
	0xFFFE,0x1FFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0x0000,0x0000,0x0000,0x0000,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
	0xFFFF,0xFFFF,0xFFFF,0xFFFF,
--XYZZY--
