/*===========================================================================
  Copyright (C) 1995-2007 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
===========================================================================*/

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.IDENTIFIER  DCO
.LANGUAGE    C
.AUTHOR      K. Banse, R.M. van Hees IPG-ESO Garching
.KEYWORDS    High level image display interfaces
.PURPOSE     Takes care of opening and closing of display devices
.ALGORITHM   updates display keywords and global variables
             uses IDI interfaces
.COMMENTS    holds high level interfaces: DCOPEN, DCCLOS, DCGICH & DCPICH
                   static functions     : OpenIDI & CloseIDI

.ENVIRONment MIDAS and IDI
             #include <midas_def.h>   Prototypes for MIDAS interfaces
             #include <idinumd.h>     Global variables for DISPLAY interfaces

.VERSIONS    1.00       9406012       created from opnidi.c by R.M. van Hees

 071005		last modif
------------------------------------------------------------*/

/* Define _POSIX_SOURCE to indicate that this is a POSIX program */

#define  _POSIX_SOURCE 1

/* definition of the used functions in this module */

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

#include <idi.h>
#include <idinumd.h>
#include <proto_idi.h>
#include <midas_def.h>


char   dzmemc[IDI_CLEN];
int    dzdev[50]; 
int    dzmemi[IDI_ILEN];
float  dzmemr[IDI_RLEN];

static int YesIdi = 0;

/*

*/

/*++++++++++++++++++++++++++++++
.IDENTIFIER  OpenIDI
.PURPOSE     opens a image display, NO updating of global variables
.INPUT/OUTPUT
  call as    stat = OpenIDI( munit, disp_id, flag, dspinfo );

  input:
         char *munit   :	Midas unit (2 chars)
         char *disp_id :	display id (currently 1 char)
         int  flag     :	1 for display window
			        2 for graphics window
			        3 for zoom window (display)
  output:
         int  *dspinfo :	display no. + create_flag

.RETURNS     status: 0   if o.k.
                     retstat (!= 0) of idiserver if problems
.COMMENTS    static function
--------------------------------*/
#ifdef __STDC__
  static int OpenIDI(char *munit,char *disp_id,int flag,int *dspinfo)
#else
  static int OpenIDI(munit,disp_id,flag,dspinfo)
  char *munit, *disp_id;
  int  flag, *dspinfo;
#endif

{	
int stat;

char  file[16];

/*
 * build up name `sxwXYnZ'
 */

(void) strcpy( file, "sxw    " );
file[3] = munit[0];
file[4] = munit[1];

if ( flag == 2 )                        /* graphics window */
   file[6] = 'g';
else if ( flag == 3 )                   /* zoom window */
   file[6] = 'z';
else                                    /* display window */
   file[6] = '\0';

file[5] = *disp_id;

if ( (stat = IIDOPN_C(file,dspinfo)) == 0 )
   dspinfo[1] = 2;			/* new window created */
else if (stat == ENTRYFND)
   dspinfo[1] = 1;			/* existing window opened */
else
   return stat;				/* must be != 0 */

YesIdi = 1;

return 0;
}

/*

*/

/*++++++++++++++++++++++++++++++
.IDENTIFIER  CloseIDI
.PURPOSE     Closes a image display, NO updating of display keywords
.INPUT/OUTPUT
  call as    stat = CloseIDI( dispno );

  input:
         int  dispno     :	display number

.RETURNS     status: 0   if o.k.
                    -1   no window to close
                    -2   window died in the meantime

.COMMENTS    static function
--------------------------------*/
#ifdef __STDC__
  static int CloseIDI(int dispno)
#else
  static int CloseIDI(dispno)
  int  dispno;
#endif

{
if ( YesIdi == 0 ) return (-1);	   /* there was no connection with server */

if ( IIDCLO_C(dispno) == DEVNOTOP )
   return -2;				/* window died in the meantime */
else
   return  0;
}

/*

*/

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.IDENTIFIER  DCOPEN
.PURPOSE     connect to IDI device + save info in keyword IDIDEV
.INPUT/OUTPUT
  call as    DCOPEN( flag );
  input:
         int  flag :		1 for display window
			        2 for graphics window
			        3 for zoom window (display)
.RETURNS     nothing
-----------------------------------------------------------*/
#ifdef __STDC__
  void DCOPEN(int flag)
#else
  void DCOPEN(flag)
  int  flag;
#endif

{
int   null, unit, iav;
int   dspinfo[2];
int   nconf, xdev, ydev, depthdev, maxlutn, maxittn, kk;

char  dspid, midunit[2], cbuf[16];

static char *info_mes1 = 
             "display x-,y-size changed to %d, %d - reload last image...\n";



(void) SCKRDI("IDIDEV",1,25,&iav,dzdev,&unit,&null);

/* if NULL device, stop entire application */
if (dzdev[17] == -1) SCSEPI();


(void) SCKRDC("MID$SESS",1,1,12,&iav,cbuf,&unit,&null);
midunit[0] = cbuf[10];
midunit[1] = cbuf[11];

if ( flag == 2 )		        /* graphics w. */
   dspid = cbuf[6];
else                                    /* display or zoom window */
   dspid = cbuf[5];
if ( dspid == ' ' ) dspid = '0';

iav = OpenIDI(midunit,&dspid,flag,dspinfo);
if (iav != 0)					/* report error back */
   SCETER(iav,"DCOPEN: can not open display...");
 
QDZFND = dspinfo[1];
if (flag == 2)                        /* graphics window */
   GDSPNO = *dspinfo;
else if (flag == 3)                        /* zoom window */
   ZDSPNO = *dspinfo;
else
   QDSPNO = *dspinfo;


/* get size of display - may be it has changed in the meantime */

(void) IIDQDV_C(*dspinfo,&nconf,&xdev,&ydev,&depthdev,&maxlutn,&maxittn,&kk);

if (flag == 1)			/* display window */
   {
   if ((xdev != QDSZX) || (ydev != QDSZY))
      {
      (void) printf(info_mes1,xdev,ydev);
      if ((xdev > QDSZX) || (ydev > QDSZY))
         {
         QMSZX = xdev;		/* update also the memory size */
         QMSZY = ydev;
         }
      QDSZX = xdev;			/* update the display size */
      QDSZY = ydev;
      }
   }

else if ( flag == 3 )	 	        /* zoom window */
   {
   if ((xdev != QXAUX) || (ydev != QYAUX))
      {
      QXAUX = xdev;		/* update also the memory size */
      QYAUX = ydev;
      }
   }

(void) SCKWRI("IDIDEV",dzdev,1,25,&unit);		/* save device info */

if ((flag != 2) && (QIMCH != QOVCH))
   {
   iav = DCGICH(QIMCH);		/* get also the image memory info */
   if (iav < 0) SCETER(69,"DCOPEN: IDIserver out of sync...");
   }
}

/*

*/

/*++++++++++++++++++++++++++++++
.IDENTIFIER  DCCLOS
.PURPOSE     close display & save global array dzdev
.INPUT/OUTPUT
  call as    DAZOUT_C( dispno )

  input:
          int  dispno :		display number

.RETURNS     nothing
------------------------------*/
#ifdef __STDC__
  void DCCLOS(int dispno )
#else
  void DCCLOS(dispno)
  int  dispno;
#endif

{
int unit;

if ( CloseIDI( dispno ) != 0 )
   SCETER( 1, "DAZOUT: FATAL display was not opened..." );
else
   (void) SCKWRI( "IDIDEV", dzdev, 1, 26, &unit );
}

/*

*/

/*++++++++++++++++++++++++++++++
.IDENTIFIER  DCGICH
.PURPOSE     return info about given channel in the image display
.INPUT/OUTPUT
  call as    stat = DCGICH( chanl );
  input:
         int  chanl :		channel (image memory) number
.RETURNS     status: 0 = o.k.
		     1 = nothing loaded into channel
		    -1 = something wrong at server side!

--------------------------------*/
#ifdef __STDC__
  int DCGICH(int chanl)
#else
  int DCGICH(chanl)
  int  chanl;
#endif

{
int  stat, unit;

/* get loaded frame, related integer, real info  */

stat = IIEGDB_C(QDSPNO,1,chanl,dzmemc,dzmemi,dzmemr);
if (stat != II_SUCCESS) return (-1);

SCROLY += (QDSZY-1);		/* yscroll => top of display */
(void) SCKWRC("IDIMEMC",1,dzmemc,1,IDI_CLEN,&unit);
(void) SCKWRI("IDIMEMI",dzmemi,1,IDI_ILEN,&unit);
(void) SCKWRR("IDIMEMR",dzmemr,1,IDI_RLEN,&unit);

if (SOURCE == 0) 		/* nothing loaded */
   return 1;
else
   return 0;
}

/*

*/

/*++++++++++++++++++++++++++++++
.IDENTIFIER  DCPICH
.PURPOSE     writes info about given channel in the image display
.INPUT/OUTPUT
  call as    DCPICH(chanl)
  input:
         int  chanl :		channel (image memory) number
.RETURNS     nothing
--------------------------------*/
#ifdef __STDC__
  void DCPICH(int chanl)
#else
  void DCPICH(chanl)
  int  chanl;
#endif

{
int  unit;

(void) IIESDB_C(QDSPNO,1,chanl,dzmemc,dzmemi,dzmemr);	/* SCROLY not used.. */

(void) SCKWRC("IDIMEMC",1,dzmemc,1,IDI_CLEN,&unit);
(void) SCKWRI("IDIMEMI",dzmemi,1,IDI_ILEN,&unit);
(void) SCKWRR("IDIMEMR",dzmemr,1,IDI_RLEN,&unit);
}

/*

*/

/*++++++++++++++++++++++++++++++
.IDENTIFIER  DCSINF
.PURPOSE     send info to IDI Server
.INPUT/OUTPUT
  call as    DCSINF(dispno,option,ibuf,rbuf,cbuf)
  input:
	 int  option:		1 set parent window
				2 do XQueryTree
				3 do MapSubwindows
				4 do XGetWindowAttributes + XGetGeometry
.RETURNS     nothing
--------------------------------*/
#ifdef __STDC__
  int DCSINF(int dispno, int option, int* ibuf, float* rbuf, char* cbuf)
#else
  int DCSINF(dispno,option,ibuf,rbuf,cbuf)

  int  dispno, option, *ibuf;
  float *rbuf;
  char  *cbuf;
#endif

{
int  auxid;



option += 100;			/* option = 1, already used */
auxid = *ibuf;

(void) IIESDB_C(dispno,option,auxid,cbuf,&ibuf[1],rbuf);

return 0;
}




