/*===========================================================================
  Copyright (C) 1994-2009 European Southern Observatory (ESO)
 
  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 ESO-MIDAS should be addressed as follows:
	Internet e-mail: midas@eso.org
	Postal address: European Southern Observatory
			Data Management Division 
			Karl-Schwarzschild-Strasse 2
			D 85748 Garching bei Muenchen 
			GERMANY
===========================================================================*/

/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

.IDENTIFICATION:
  routine GetCursor
.AUTHOR
  K. Banse         			ESO - Garching
  					vers. 1.00  940302
.KEYWORDS:
  display, cursor
.PURPOSE:
  high level interface to read the position of the two cursors
  on the Image display and get density of relevant pixel.
.ALGORITHM:
  Use enabled cursor(s) and read screen pixels, get real pixels and
  world coordinates, when the ENTER button is pressed.
  Exit by pressing EXIT button.
  also the keyword ACTION/C/5/3 is used, to determine if we want to work
  with a zoom window

.VERSIONS

 090706		last modif
-------------------------------------------------------------------  */

#include<stdio.h>
#include<string.h>

#include <midas_def.h>
#include <idinumd.h>
#include <proto_II.h>

#define MYMIN(a,b)   ((a) > (b) ? (b) : (a))

static int    npix[2], naxis;
static int    zsta[2];          /* parent start frame pixels */
static int    zpix[3];          /* no. of parent frame pixels used */
static int    zwsta[4];         /* [0,1] = start pixels in zoom w. (0,0)
                                   [2,3] = scaling factors for subimage */
static int    zinfo[5];         /* zoom window info */
static int    scrpix[4];        /* screen pixels of subimage in main display */
static int    scenter[2];       /* parent center screen pixels */

static float  pfrpix[2];        /* parent center frame pixels */
static float  cuts[4]={-1,-1,-1,-1};

static void LoadZw(), GetValue();
/*

*/

void GetCursor(action,frame,xyinfoa,stata,xyinfob,statb)

char *action;		/* IN: 4 action flags,
			       [0] = Y, get intensities at cursor position(s)
			       [1] = Y, draw a cross, circle or rectangle at
				        cursor position(s)
			       [2] = Y, show screen coords + value in
				        alphanumerics plane
			       [3] = Y, wait for ENTER button, else not
				   = N, return cursor coords only
				   = Z, return all info if changed */
char *frame;		/* IN/OUT: has to be set to ' ' on first call of the
                                   routine to mark the beginning
				   on return = name of frame in channel, where
				               cursor(s) are pointing to */
float *xyinfoa;		/* OUT: info about cursor 0 (7 values),
				[0,1] - screen pixels of cursor 0
				[2,3] - frame pixel no's for pos. of cursor 0
				[4,5] - world coordinates for above
				[6] - intensity at cursor position only filled,
                                      if action[0] = Y  */
int *stata;		/* OUT: status of cursor 0, 0 = off, 1 = on
                                if action[3] != 'Y' then stata = -1 or -2 if
                                ENTER-button or RETURN-key pushed
				stata = -8, if arrow or no. key pressed,
				stata = -9, if input char. from keyboard 
				(statb indicates which key was pushed) */
float *xyinfob;		/* OUT: info about cursor 1 (7 values),
				[0,1] - screen pixels of cursor 1
				[2,3] - frame pixel no's for pos. of cursor 1
				[4,5] - world coordinates for above
				[6] - intensity at cursor position only filled,
                                      if action[0] = Y  */
int *statb;		/* OUT: status of cursor 1, 0 = off, 1 = on
                                if action[3] != 'Y' then statb = -1 or -2 if
                                ENTER-button or RETURN-key pushed
				if stata = -9 (input from keyboard) then
				statb indicates which key was pushed */



{
int xya[5], xyb[5];
int n, iav, stat;
int curco[4], xfig[256], yfig[256];
int in[20], imnow, uni, nulo;
int ec;
static int xcross[5] = {0,0,0,-3,3}, ycross[5] = {-3,3,0,0,0};
static int kpack = 4;
static int oldmem, memo = -1;
static int planoff = 0, croi = 0;
static int xcont = -1, ycont = -1, xzont = -1, yzont = -1;
static int ymapa, ymape, maxsiz, virtsz, nlines, nlin2, stapix;
static int inopt, oldino, imno;
static int tsty, tstz, zflag, aveflg;
static int nocur, noc, trnoc;
static int splmod, magnif, znoc, zstat;

char output[80];
static char oldfra[80], zact, *pntrw; 
static char *errmes = "no image loaded... ";
static char *outma = " --- cursor #0 outside image --- ";
static char *outmb = " --- cursor #1 outside image --- ";
static char *magmes = "looking glass on - type `u' again to turn it off. ";
static unsigned char  *dpp;

static double dd1[3], dd2[3], dd3[3];		/* synchronize with fp2wc */

float rdata;
float Pixy();

void framdat();




/*  test, if we are here for the first time */

if (*frame == ' ')     
   {
   oldfra[0] = ' ';
   oldmem = -99;
   *frame = '_';            /* so we don't come here again... */
   stat = SCKRDI("MONITPAR",20,1,&iav,&maxsiz,&uni,&nulo);
   maxsiz = maxsiz * maxsiz;
      

   /*  get cursors involved + current split mode */

   stat = SCKRDI("DAZHOLD",1,16,&iav,in,&uni,&nulo);
   nocur = in[0];               /* noc = 0,1,2 for cursor 0, 1 or both = roi */
   if (nocur == 3)     
      noc = 2;                  /* 3 = 0 and 1 independently */
   else
      noc = nocur;
   if ((nocur == 2) && (in[1] == 2))     
      {
      croi = 1;
      nocur = 12 ;
      }
   else
      croi = 0;

   if ( (QRGBFL == 1) && (in[2] == 0) )      
      splmod = 0;                         /* in RGB + non-split mode */
   else
      splmod = 1;
   zact = 'C';			/* default to get/cursor */


   /*  open zoom window, if required */

   if (action[4] == 'Z') 
      {
      if (action[5] == 'V') zact = 'V';		/* view/image */
      znoc = 0;
      if (action[6] == '2')     
         znoc = 2;
      else if (action[6] == '3')     
         znoc = 3;
      trnoc = znoc;                       /* true no. of cursors */
      if (action[6] == '7')     
         {
         znoc = 12;
         croi = 1;                        /* indicate circles */
         }
      stat = SCKRDI("DAZIN",1,5,&iav,in,&uni,&nulo);  /* get window size */
      xya[0] = 1;                         /* display initial zoom factor */
      stat = Cauxwnd(0,in,xya,xyb);
      zflag = 1;                          /* this implies single cursor... */
      inopt = -1;
      }
   else
      {
      zflag = -1;
      inopt = 0;
      trnoc = noc;                        /* true no. of cursors */
      }

   Ccursin(QDSPNO,inopt,nocur,xya,stata,xyb,statb);

   if (action[3] == 'N')     
      inopt = 2;
   else if (action[3] == 'Z')     
      {
      inopt = 3;
      xcont = -1;
      ycont = -1;
      xzont = -1;
      yzont = -1;
      }
   else
      inopt = 1;
   oldino = inopt;
   magnif = -1;                           /* magnifying glass off */

   if (action[2] == 'Y') Alpcurs(trnoc,0);
   }

for (n=0; n<5; n++)			/* init xya + xyb arrays */
   {
   xya[n] = xyb[n] = 0;      
   }
   

/*
  read the cursor positions in main window
  ----------------------------------------
*/

Curs_loop:
if (zflag != 2)     
   {
   Ccursin(QDSPNO,inopt,nocur,xya,stata,xyb,statb);


   /*  look for arrow keys + other keys from keyboard */

   if (*stata < -7)
      {
      char  cc;

      if (*stata == -8)				/* arrow keys + no. keys */
         stat = Cauxwnd(4,statb,xya,xyb);

      else 
         {
         cc = (char) *statb;

         if ((cc == 'k') || (cc == 'l'))	/* modify LUT,ITT */
            stat = Cauxwnd(9,statb,xya,xyb);
         else if (cc == 'u')                    /* magnifying glass */
            {
            magnif = -magnif;
            if (magnif == 1)     
               {
               inopt = 2;
               SCTDIS(magmes,-9);
               SCTDIS(magmes,99);
               }
            else
               {
               inopt = oldino;
               (void) strcpy(output,"looking glass off...");
               SCTDIS(output,-9);
               SCTDIS(output,99);
               }
            }
         else if ((cc == 'x') || (cc == 'z')	/* handle zooming */
                 || (cc == 'c') || (cc == 'b')	/* handle LUT/ITT stuff */
                 || (cc == 'i') || (cc == 'j')	
                 || (cc == 'h'))		/* and the help */
            stat = Cauxwnd(11,statb,xya,xyb);
         else
            return;				/* return for any other key */
         }

      goto Curs_loop;				/* loop again */
      }


   if (*stata == 0) goto sect_1100;    /* if EXIT pushed get out of here */


   /*  get relevant memory board */

   if (splmod == 0)               /* in RGB + non-split mode */
      memo = QIMCH;               /* take last displayed channel as memory */
   else
      {
      if (trnoc != 1)                     /* for cursor #0 or both cursors */
         memo = xya[2];
      else
         memo = xyb[2];
      }
   }


/*  refresh drawings + check, if we work without a zoom window */

if (zact != 'V') 			/* NOT in continuous mode... */
   (void) Cdazvis(QDSPNO,QOVCH,2,1);

if (zflag == -1) goto sect_1060;

/*
  yes - we do have a zoom window
  ------------------------------
*/

if (magnif == 1)                  /* test, if we are in looking_glass_mode */
   {
   in[0] = memo;
   in[1] = QOVCH;
   stat = Cauxwnd(5,in,xya,xyb);
   goto Curs_loop;
   }


/*  test, if we are reading continuously from main window */

if (zact == 'V')     
   {
   zflag = 1;
   if (inopt == 3)     
      {
      if ((xcont != xya[0]) || (ycont != xya[1]))     
         {
         xcont = xya[0];
         ycont = xya[1];
         if (*stata >= 0)		/* if no enter was pushed */
            {
            zact = 'W';			/* indicate origin */
            goto sect_1060;		/* and return single cursor */
            }
         }
      else if (*stata >= 0)		/* if no enter was pushed */
         goto Curs_loop;		/* loop more */
      }
   in[0] = memo;
   in[1] = QOVCH;
   stat = Cauxwnd(10,in,xya,xyb);
   }

else
   {
   if (zflag == 1)      
      {
      scenter[0] = CGN_NINT( xya[0]);		/* screen center coords */
      scenter[1] = CGN_NINT( xya[1]);

      if (inopt == 3)      
         {
         if ((xcont != xya[0]) || (ycont != xya[1]))     
            {
            xcont = xya[0];
            ycont = xya[1];
            if (*stata >= 0) goto sect_1060;        /* return single cursor */
            }
         else if (*stata >= 0)                 /* if no enter was pushed */
            goto Curs_loop;                        /* loop more */
         }

      in[0] = memo;
      in[1] = QOVCH;
      stat = Cauxwnd(10,in,xya,xyb);


      /* first time: open displayed frame + init pixel conversion */

      if (oldfra[0] == ' ')
         {
         (void) strcpy(frame,dzmemc);	/* copy name of loaded image */
         n = 1;
         (void) SCPSET(F_FITS_PARM,&n);	/* don't read in ESO.xyz keywords */
         (void) SCFOPN(frame,D_R4_FORMAT,0,F_IMA_TYPE,&imno);
         (void) SCDRDI(imno,"NPIX",1,2,&iav,npix,&uni,&nulo);
         if (Pixconv("INIT",imno,dd1,dd2,dd3) > 0)       /* init wc conv. */
            SCETER(69,"initialization of world coord. conversion failed...");
         (void) SCDRDI(imno,"NAXIS",1,1,&iav,&naxis,&uni,&nulo);
         dd1[2] = dd2[2] = dd3[2] = 1.0;
         if (naxis > 2) dd1[2] = ZPLANE;
         (void) SCDRDR(imno,"LHCUTS",1,4,&iav,cuts,&uni,&nulo);
         if (cuts[0] >= cuts[1])
            {
            cuts[0] = cuts[2];
            cuts[1] = cuts[3];
            }
         framdat(frame);
         (void) strcpy(oldfra,frame);
         }

      in[0] = memo;                        /* copy area into zoom window */
      in[1] = QOVCH;
      in[2] = 0;
      in[3] = znoc;
      in[4] = inopt;

      dd1[0] = (double)scenter[0];
      dd1[1] = (double)scenter[1];
      stat = Pixconv("IRW",imno,dd1,dd2,dd3);
      if (stat != 0)
         {
         if (stat > 9) goto Exit_return;
         SCTDIS(outma,99);
         goto Curs_loop;
         }

      pfrpix[0] = (float) dd2[0];
      pfrpix[1] = (float) dd2[1];


      LoadZw(imno,cuts);
      stat = Cauxwnd(21,in,scrpix,xyb);
      }


   /*  get coordinates from zoom window */

   stat = Cauxwnd(22,zsta,xya,xyb);
   if (stat == 0)                         /* check for exit button */
      {
      in[0] = memo;
      in[1] = QOVCH;
      stat = Cauxwnd(3,in,xya,xyb);

      zflag = 1;
      stat = IIISTI_C(QDSPNO);
      Ccursin(QDSPNO,-1,nocur,xfig,stata,yfig,statb);
      goto Curs_loop;                              /* get out of this loop */
      }
   zflag = 2;

   dd1[0] = (double) xya[0];
   dd1[1] = (double) xya[1];
   stat = Pixconv("_RW",0,dd1,dd2,dd3) ;
   xyinfoa[4] = (float) dd3[0];
   xyinfoa[5] = (float) dd3[1];
   stat = Pixconv("_RS",0,dd1,dd2,dd3) ;
   curco[0] = CGN_NINT(dd3[0]);
   curco[1] = CGN_NINT(dd3[1]);
   xyinfoa[0] = (float) curco[0];
   xyinfoa[1] = (float) curco[1];
   xyinfoa[2] = (float) xya[0];
   xyinfoa[3] = (float) xya[1];
   GetValue(imno,xya,&xyinfoa[6]);

   if (action[1] == 'Y')                 /* mark cursor position... */
      {
      for (n=0; n<5; n++)
         {
         xfig[n] = xcross[n] + curco[0];
         yfig[n] = ycross[n] + curco[1];
         }
      stat = IIGPLY_C(QDSPNO,QOVCH,xfig,yfig,5,255,1);
      }


   if (trnoc > 1)
      {
      if (croi == 1)
         {
         xyinfob[0] = -1;
         xyinfob[1] = -1;
         xyinfob[2] = (float) xyb[0];
         xyinfob[3] = (float) xyb[1];
         xyinfob[4] = (float) xyb[2];
         }
      else
         {
         dd1[0] = (double) xyb[0];
         dd1[1] = (double) xyb[1];
         stat = Pixconv("_RW",0,dd1,dd2,dd3) ;
         xyinfob[2] = (float) xyb[0];
         xyinfob[3] = (float) xyb[1];
         xyinfob[4] = (float) dd3[0];
         xyinfob[5] = (float) dd3[1];
         GetValue(imno,xyb,&xyinfob[6]);
         }
      }

   return;
   }



/*
  get zoom + scroll values of image channel 
  -----------------------------------------
*/

sect_1060:
curco[0] = xya[3];				/* raw curs_coords */
curco[1] = xya[4];
curco[2] = xyb[3];
curco[3] = xyb[4];

xyinfoa[0] = curco[0];                     /* screen coords. of cursor 0 */
xyinfoa[1] = curco[1];
xyinfob[0] = curco[2];                     /* screen coords. of cursor 1 */
xyinfob[1] = curco[3];

zstat = DCGICH( memo ); 			/* we need `zstat' later on */
if (zact == 'W') goto sect_2000;
      

/*
  handle cursor input from main or zoom window
  --------------------------------------------
*/


sect_1100:
if (trnoc == 0)
   {
   if (*stata == 0)     			/* check status of cursor 0 */
      {
      if (zflag != -1)
         {
         in[0] = QOVCH;
         stat = Cauxwnd(3,in,xya,xyb);
         }
      goto Exit_return;
      }
   else
      {
      if ((inopt == 2) && (*stata != -1)) 
         goto Exit_return;              /* only continue on enter */

      if (inopt == 3)     		/* continuous readout */
         {
         if (zact != 'V') 		/* in VIEW we use xcont, not xzont */
            {
            if ((xzont != xya[0]) || (yzont != xya[1]))     
               {
               xzont = xya[0];
               yzont = xya[1];
               }
            else if (*stata >= 0)                 /* no enter was pushed, */
               goto Curs_loop;                        /* loop more */
            }
         goto sect_2000;
         }

      if (action[1] == 'Y')                 /* mark cursor position... */
         {
         for (n=0; n<5; n++)
            {
            xfig[n] = xcross[n] + curco[0];
            yfig[n] = ycross[n] + curco[1];
            }
         stat = IIGPLY_C(QDSPNO,QOVCH,xfig,yfig,5,255,1);
         }
      }
   }

else if (trnoc == 1)
   {					 /* check status of cursor 1 */
   if (*statb == 0) goto Exit_return;
    
   if ((inopt == 2) && (*statb != -1))
      goto Exit_return;                           /* only continue on ENTER */

   if (action[1] == 'Y')                 /* mark cursor position... */
      {
      for (n=0; n<5; n++)
         {
         xfig[n] = xcross[n] + curco[2];
         yfig[n] = ycross[n] + curco[3];
         }
      stat = IIGPLY_C(QDSPNO,QOVCH,xfig,yfig,5,255,1);
      }
   }

else
   {				 /*  check status of cursor 0 and 1 */
   if ( (*stata == 0) && (*statb == 0) )     
      {
      if (zflag != -1)
         {
         in[0] = QOVCH;
         stat = Cauxwnd(3,in,xya,xyb);
         }
      goto Exit_return;
      }
   else
      {
      float  arcs[2];

      if ((inopt == 2) && (*stata != -1)) goto Exit_return; 

      /* only continue on enter */

      arcs[0] = arcs[1] = -1.0;
      if (action[1] == 'Y')                 /* mark cursor position... */
         {
         if (croi == 1)				/* construct circle */
            {
            curco[2] = xyb[0];
            buildgra("CIR",curco,arcs,xfig,yfig,256,&n);
            stat = IIGPLY_C(QDSPNO,QOVCH,xfig,yfig,n,255,1);
            if (xyb[1] > 0)     		/* middle radius */
               {
               curco[2] = xyb[1];
               buildgra("CIR",curco,arcs,xfig,yfig,256,&n);
               stat = IIGPLY_C(QDSPNO,QOVCH,xfig,yfig,n,255,1);
               }
            if (xyb[2] > 0)     		/* outer radius */
               {
               curco[2] = xyb[2];
               buildgra("CIR",curco,arcs,xfig,yfig,256,&n);
               }
            }
         else 
            buildgra("REC",curco,arcs,xfig,yfig,5,&n);   /* build rectangle */

         stat = IIGPLY_C(QDSPNO,QOVCH,xfig,yfig,n,255,1);
         }
      }
   }
      

/*  here we join again for all cursors */

sect_2000:
if (oldmem != memo)     
   {
   if (zstat != 0)     
      {
      SCTPUT(errmes);           /* no image loaded */
      oldmem = -88;                       /* so we know later on... */
      *frame = 'x';
      goto sect_3000;
      }
       
   (void) strcpy(frame,dzmemc);	/* copy name of loaded image */
   oldmem = memo;
   }

/*
  if necessary map new frame into memory
  --------------------------------------
*/

if (strcmp(oldfra,frame) != 0)
   {
   n = 1;
   (void) SCPSET(F_FITS_PARM,&n); /* don't read in ESO.xyz keywords */
   stat = SCFOPN(frame,D_R4_FORMAT,0,F_IMA_TYPE,&imno);
   stat = SCDRDI(imno,"NPIX",1,2,&iav,npix,&uni,&nulo);
   if (ZPLANE == 0)
      planoff = 0;				/* 2-dim frame loaded */
   else
      planoff = (ZPLANE-1)*npix[0]*npix[1];	/* compute plane offset */
   if (SOURCE == 3) 
      aveflg = 1;
   else
      aveflg = 0;
   if (Pixconv("INIT",imno,dd1,dd2,dd3) > 0)       /* init wc conversion */
      SCETER(69,"initialization of world coord. conversion failed...");
   stat = SCDRDI(imno,"NAXIS",1,1,&iav,&naxis,&uni,&nulo);
   if (naxis > 2) 
      dd1[2] = ZPLANE;
   else
      dd1[2] = 0;

   if (action[0] == 'Y') 
      {
      ymapa = 0;
      ymape = -1;				/* enforce 1st time entry! */
      if (*oldfra == ' ')     
         {
         nlines = maxsiz / npix[0];		/* get multiple of lines */
         virtsz = nlines * npix[0];
         nlin2 = nlines / 2;
         stat = SCFINF("MIDXYZ",0,in);
         if (stat != 0)                      /* if not in FCT yet, create */
            {
            stat = SCFCRE("MIDXYZ",D_R4_FORMAT,F_X_MODE,F_IMA_TYPE,
                          virtsz,&imnow);
            stat = SCFMAP(imnow,F_X_MODE,1,virtsz,&iav,&pntrw);
            if (iav < virtsz) 
               SCETER(91,"could not alloc virtual memory ...");
            }
         }
      }

   framdat(frame);
   if (aveflg == 1)     
      {
      SCTPUT("Caution: frame pixels were averaged when loaded.");
      SCTPUT("Displayed intensities are average values! ");
      }
   (void) strcpy(oldfra,frame);
   }
      

/*
  now convert screen pixels to real pixels + world coordinates
  for ZACT = 'V' we need world coords. for corners of square
  ------------------------------------------------------------
*/

sect_3000:
if (zact == 'V') goto sect_3300;

if (zact == 'W')     
   {
   zact = 'V';
   goto sect_3100;
   }
else
   {
   if (croi == 1)                       /* here for circular roi */
      {
      if (oldmem < 0) return;

      dd1[0] = (double)xya[0];               /* cursor 0 only */
      dd1[1] = (double)xya[1];
      stat = Pixconv("IRW",imno,dd1,dd2,dd3);
      if (stat != 0)     
         {
         if (stat > 9) goto Exit_return;

         SCTDIS(outma,99);
         goto Curs_loop;
         }
       
      xyinfoa[2] = dd2[0];
      xyinfoa[3] = dd2[1];
      xyinfoa[4] = dd3[0];
      xyinfoa[5] = dd3[1];

      xyinfob[0] = -1;             /* that indicates the modified retparms */
      xyinfob[1] = -1;
      xyinfob[2] = xyb[0];
      xyinfob[3] = xyb[1];
      xyinfob[4] = xyb[2];
      goto sect_3500;
      }
   }
      

/*  here for cursor 0 */

if (trnoc == 0)
   {
sect_3100:
   if ((action[2] == 'Y') && (IDINUM != 11))     
      {
      stat = IIMRMY_C(QDSPNO,memo,1,xya[0],xya[1],8,kpack,0,dpp);
      in[0] = (int) *dpp;
      Alpcurs(0,1);
      }
   if (oldmem < 0) return;
      
   dd1[0] = (double)xya[0];               /* cursor 0 only */
   dd1[1] = (double)xya[1];
   stat = Pixconv("IRW",imno,dd1,dd2,dd3);
   if (stat != 0)     
      {
      if (stat > 9) goto Exit_return;

      SCTDIS(outma,99);
      goto Curs_loop;
      }
   else                                /* save world coords... */
      {
      xyinfoa[2] = dd2[0];
      xyinfoa[3] = dd2[1];
      xyinfoa[4] = dd3[0];
      xyinfoa[5] = dd3[1];
      }
   }
      

/*  here for cursor 1 */

else if (trnoc == 1)
   {
   if ((action[2] == 'Y') && (IDINUM != 11))     
      {
      stat = IIMRMY_C(QDSPNO,memo,1,xya[0],xya[1],8,kpack,0,dpp);
      in[1] = (int) *dpp;
      Alpcurs(1,1);
      }
   if (oldmem < 0) return;
      
   dd1[0] = (double)xyb[0];               /* cursor 1 only */
   dd1[1] = (double)xyb[1];
   stat = Pixconv("IRW",imno,dd1,dd2,dd3);
   if (stat != 0)     
      {
      if (stat > 9) goto Exit_return;

      SCTDIS(outmb,99);
      goto Curs_loop;
      }
   else                                /* save world coords... */
      {
      xyinfob[2] = dd2[0];
      xyinfob[3] = dd2[1];
      xyinfob[4] = dd3[0];
      xyinfob[5] = dd3[1];
      }
   }

    
/*  here for cursor 0 and 1 */

else
   {
sect_3300:
   if ((action[2] == 'Y') && (IDINUM != 11))     
      {
      stat = IIMRMY_C(QDSPNO,memo,1,xya[0],xya[1],8,kpack,0,dpp);
      in[0] = (int) *dpp;
      Alpcurs(0,1);
      stat = IIMRMY_C(QDSPNO,memo,1,xya[0],xya[1],8,kpack,0,dpp);
      in[1] = (int) *dpp;
      Alpcurs(1,1);
      }
   if (oldmem < 0) return;
      

   /*  make sure, we have lower-left and upper-right */

   if (xya[0] > xyb[0])     
      {
      n = xya[0];
      xya[0] = xyb[0];
      xyb[0] = n;
      }
   if (xya[1] > xyb[1])     
      {
      n = xya[1];
      xya[1] = xyb[1];
      xyb[1] = n;
      }

   dd1[0] = (double)xya[0];                 /* both cursors */
   dd1[1] = (double)xya[1];
   stat = Pixconv("IRW",imno,dd1,dd2,dd3);
   if (stat != 0)     
      {
      if (stat > 9) goto Exit_return;

      SCTDIS(outma,99);
      goto Curs_loop;
      }
   else                                /* save world coords... */
      {
      xyinfoa[2] = dd2[0];
      xyinfoa[3] = dd2[1];
      xyinfoa[4] = dd3[0];
      xyinfoa[5] = dd3[1];
      }
      
   dd1[0] = (double)xyb[0];
   dd1[1] = (double)xyb[1];
   stat = Pixconv("IRW",imno,dd1,dd2,dd3);
   if (stat != 0)     
      {
      if (stat > 9) goto Exit_return;

      SCTDIS(outmb,99);
      goto Curs_loop;
      }
   else                             /* save world coords... */
      {
      xyinfob[2] = dd2[0];
      xyinfob[3] = dd2[1];
      xyinfob[4] = dd3[0];
      xyinfob[5] = dd3[1];
      }
   }
      

/*
  now get the intensities
  -----------------------
*/

sect_3500:
if (action[0] != 'Y') return;       /* we don't want pixel values => go home */
      
tsty = CGN_NINT(xyinfoa[3]) - 1;     /* frame pixels begin at 1 not 0 */
tstz = CGN_NINT(xyinfoa[2]) - 1;
ec = 1;				    /* use `ec' as first-time flag */

sect_4000:
if (aveflg != 1)     
   iav = tsty;
else
   iav = tsty + SCALY;

if ((tsty < ymapa) || (iav > ymape))     
   {
   ymapa = tsty - nlin2;                          /* compute low, hi y-line */
   if (ymapa < 0) ymapa = 0;                      /* for map_area */
   ymape = ymapa + (nlines - 1);
   if (ymape >= npix[1]) ymape = npix[1]-1;
   stapix = (ymapa*npix[0]) + 1;	/* first pixel in map_area */
   stapix += planoff;			/* add plane offset */
   stat = SCFGET(imno,stapix,virtsz,&iav,pntrw);  /* first index is 1 ... */
   }

tsty -= ymapa;
rdata = Pixy( (float *) pntrw, npix[0], tstz, tsty, aveflg );

if (trnoc < 2)     
   xyinfoa[6] = rdata;
else if (ec > 1)     
   xyinfob[6] = rdata;
else                                /* for two cursors we loop */
   {
   xyinfoa[6] = rdata;
   if (nocur != 12)     
      {
      tsty = CGN_NINT(xyinfob[3]) - 1;
      tstz = CGN_NINT(xyinfob[2]) - 1;
      ec = 2;
      goto sect_4000;
      }
   }


/*  that's it folks - it was quite a job ... */

return;


/*
  here we get out when EXIT button is pushed
  ------------------------------------------
*/

Exit_return:
return;      
}

/*

*/

float Pixy(a,npix,kx,ky,avfla)
int npix, kx, ky, avfla;
float *a;

{
int m0, n, nn;

float sum, retval, *w;	


m0 = (ky * npix) + kx;			/* get to 1. pixel */

if (avfla == 0) return (*(a+m0));


/*  here we get the average */

retval = 0.;

for (n=0; n<SCALY; n++) 
   {
   w = a + m0;
   sum = 0.;
   for (nn=0; nn<SCALX; nn++)
      sum = sum + *w++;

   retval += sum;
   m0 += npix;                          /* move to next line */
   }

retval /= (SCALX*SCALY);
return (retval);

}
/*

*/

void framdat(frame)
char *frame;

{

char output[72], cbuf[4];

int  ibuf[5];



/*  get data format of frame */

(void) SCFINF(frame,2,ibuf);
 
if (ibuf[1] == D_R4_FORMAT)
   (void) strcpy(cbuf,"R4");
else if (ibuf[1] == D_I2_FORMAT) 
   (void) strcpy(cbuf,"I2");
else if (ibuf[1] == D_I1_FORMAT)
   (void) strcpy(cbuf,"I1");
else if (ibuf[1] == D_I4_FORMAT)
   (void) strcpy(cbuf,"I4");
else if (ibuf[1] == D_R8_FORMAT) 
   (void) strcpy(cbuf,"R8");
else if (ibuf[1] == D_UI2_FORMAT) 
   (void) strcpy(cbuf,"uI2");

(void) SCTDIS( output, -9 );              /* if something was there erase it */
(void) sprintf(output,"frame: %s  (data = %s)",frame,cbuf);
SCTPUT(output);

if (ZPLANE != 0)
   {
   (void) sprintf(output,"       plane_no %d loaded",ZPLANE);
   SCTPUT(output);
   }
}

/*

*/

/*++++++++++++++++++++++++++++++
.IDENTIFIER  LoadZw
.PURPOSE     display data in zoom window 
.INPUT/OUTPUT
  input:
             int   imno    :    id number of frame
             float *cuts   :    cuts in main window

.RETURNS     nothing
.COMMENTS    LOADWN uses global variables
------------------------------*/

#ifdef __STDC__
 static void LoadZw(int imno, float *cuts)
#else
 static void LoadZw(imno,cuts)
 int   imno;
 float *cuts;
#endif

{
int   naxpix[4], xya[2], xyb[2];
int   nmpix[2];
int  loadfl[2] = {-1, D_R4_FORMAT};    /* aux_window, R*4 data flag */
register int nr;

float  rr;

double  da[3], db[3], dc[3];




/* get size and effective zoom */

(void) Cauxwnd(6,zinfo,xya,xyb);                /* `zinfo' is static! */
ZDSPNO = *zinfo;
zwsta[2] = - zinfo[3];
zwsta[3] = - zinfo[4];

nmpix[0] = zinfo[1]/zinfo[3];   /* x-nopix to fit zoomed into aux_window */
nmpix[1] = zinfo[2]/zinfo[4];   /* y-nopix to fit zoomed into aux_window */


/* ensure, that start + end pixel remain inside */

zsta[0] = pfrpix[0] - nmpix[0]/2;
if (zsta[0] < 1) zsta[0] = 1;
zsta[1] = pfrpix[1] - nmpix[1]/2;
if (zsta[1] < 1) zsta[1] = 1;

zpix[0] = nmpix[0];
naxpix[0] = zsta[0] + nmpix[0];
nr = naxpix[0]  - npix[0];
if (nr > 0)                             /* spill over last x-pixel */
   {
   zsta[0] -= nr;
   if (zsta[0] < 1)
      {                                 /* use as much as possible */
      zsta[0] = 1;
      zpix[0] = MYMIN(nmpix[0],npix[0]);
      }
   }
naxpix[0] = zsta[0] + zpix[0] - 1;

zpix[1] = nmpix[1];
naxpix[1] = zsta[1] + nmpix[1];
nr = naxpix[1]  - npix[1];
if (nr > 0)                             /* spill over last y-line */
   {
   zsta[1] -= nr;
   if (zsta[1] < 1)
      {                                 /* use as much as possible */
      zsta[1] = 1;
      zpix[1] = MYMIN(nmpix[1],npix[1]);
      }
   }
naxpix[1] = zsta[1] + zpix[1] - 1;

/*
printf("debug::: pfrpix = %f, %f, nmpix = %d, %d\n",
pfrpix[0],pfrpix[1],nmpix[0],nmpix[1]);
printf("debug::: zsta = %d, %d, zpix = %d, %d\n",
zsta[0],zsta[1],zpix[0],zpix[1]);
*/

da[0] = (double) zsta[0];
da[1] = (double) zsta[1];
nr = Pixconv("_RS",imno,da,db,dc) ;
rr = (float) dc[0];
scrpix[0] = CGN_NINT(rr);
rr = (float) dc[1];
scrpix[1] = CGN_NINT(rr);

da[0] = (double) (zsta[0] + zpix[0] - 1);
da[1] = (double) (zsta[1] + zpix[1] - 1);
nr = Pixconv("_RS",imno,da,db,dc) ;
rr = (float) dc[0];
scrpix[2] = CGN_NINT(rr);
rr = (float) dc[1];
scrpix[3] = CGN_NINT(rr);

/* finally load the subimage into the zoom window */

LOADWN_C(loadfl,imno,npix,zsta,zpix,zwsta,cuts);
}

/*

*/

/*++++++++++++++++++++++++++++++
.IDENTIFIER  GetValue
.PURPOSE     get data value at cursor
.INPUT/OUTPUT
  input:
             int   imno    :    id number of frame
             float *cuts   :    cuts in main window

.RETURNS     nothing
.COMMENTS    LOADWN uses global variables
------------------------------*/

#ifdef __STDC__
 static void GetValue(int imno, int *frpix, float *value)
#else
 static void GetValue(imno,frpix,value)
 int   imno, *frpix;
 float *value;
#endif

{
int   actvals, mm, planoff, felem;
static int  oldfelem = -1;

char  *impntr;

static float  *pf;



mm = zinfo[2] * npix[0];		/* zinfo[2] = no. lines in zoom w. */
if (ZPLANE != 0) 
   planoff = (ZPLANE-1)*(npix[0]*npix[1]);
else
   planoff = 0;


/* point to beginning of first line in zoom window */

felem = planoff + (zsta[1]-1)*npix[0] + 1;

if (felem != oldfelem)
   {
   (void) SCFMAP(imno,F_I_MODE,felem,mm,&actvals,&impntr);
   pf = (float *)impntr;
   oldfelem = felem;
   }

*value = *(pf + (frpix[1]-zsta[1])*npix[0] + (frpix[0]-1));
} 


