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


/*++++++++++++++++++++++++  wndcrea  +++++++++++++++++++++
.LANGUAGE  C
.IDENTIFICATION	Module wndcrea
.AUTHOR		K. Banse                  ESO - Garching
.KEYWORDS
ImageDisplay, XWindows
.ALGORITHM
create new window or switch from one to another or delete a window
 
.INPUT/OUTPUT
keyword ACTION(6:8)    (6) = window type (I or G or Z)
                       (7) = C (create), D (delete), S (switch), P (parallel)
                       (8) = reference id (only for 'P')

for create + switch keyword INPUTI/I/1/11 holds the following info:
 (1,2,3,4) xoff,yoff,xdim,ydim of window
 (5)       no. of channels connected to display window
 (6,7,8)   xdim,ydim,depth of each channel
 (9)       overlay channel flag
 (10)      alpha memory flag
 (11)      no. of segments for glist structure of memories

.VERSION
  [1.00] 890307:  creation
 
 090709		last modif
----------------------------------------------------------------------*/
 
#include <midas_def.h>
#include <idinumd.h>
#include <idi.h>
#include <proto_idi.h>

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

#define WRITE   1
#define READ   0

#define MAX_DEV_2  2*MAX_DEV	


static float plrgrap[40];

static int   knp[20], dzsave[2];
static int   imnoa, idimemi[100];
static int   gglen, glen, hlen, dlen, rlen;

static char  cwtype[10], wtyp, hcilut[48], idimemc[100];
static char  midunit[2], devnam[MAX_DEV_2];
static char  plcdata[80], plcmeta[80];

/*

*/

void idimess(errno,mess)
int  errno;
char  *mess;

{
switch(errno)
   {

  case XCONNERR:
   (void) strcpy(mess,
  "We could not connect to the X-environment, check the DISPLAY variable ...");
   return;
 
  case NOFONTS:
   (void) strcpy(mess,
  "We could not find any fonts, run Xtest.exe to see the available fonts ...");
   return;
 
  case NOCOLALLO:
   (void) strcpy(mess,"We could not allocate at least 4 colour cells ...");
   return;
 
  case NOAVAILDEV:
   (void) strcpy(mess,
   "No more empty slots in IDI device table, delete some windows ...");
   return;
 
  case DCTFILERR:
   (void) strcpy(mess,"Could not open sxw.dat file in MID_WORK ...");
   return;
 
  case DCTREADERR:
   (void) strcpy(mess,"The sxw.dat file in MID_WORK is corrupt ...");
   return;
 
  case WSTNAMERR:
   (void) strcpy(mess,"Invalid name of X-display passed ...");
   return;
 
  case WINOTOPN:
   (void) strcpy(mess,"Problems with XCreateWindow ...");
   return;
 
  case MEMALLERR:
   (void) strcpy(mess,
   "We could not allocate virtual memory for IDI structures ...");
   return;
 
  case ILLSHADOW:
   (void) strcpy(mess,"Invalid name for shadow display ...");
   return;
 
  case BADVISUAL:
   if (QRGBFL == 1)
      (void) strcpy(mess,"We could not get TrueColor Visual ...");
   else
      (void) strcpy(mess,"We could not get PseudoColor Visual ...");
   return;
 
  case BADXWTYPE:
   (void) strcpy(mess,"No 8 bits/pixel display found ...");
   return;
 
  default:
   *mess = '\0';			/* indicate `no match'  */
   }
}
/*

*/

void dsc2key(direc,entrx)
char   direc;
int    entrx;

{
int  loff, iav, unit, null;
int  tzdev[50];
int  dzmask[8], dzlim;		/* start index, count for display/graphics */
register int  nr, mr;



if (direc == 'O')		/* OUT = save keywords to backing store */
   {
   loff = (entrx * 50) + 1;
   (void) SCDWRI(imnoa,"IDIDEVI",dzdev,loff,50,&unit);
   loff = (entrx * dlen) + 1;
   (void) SCDWRI(imnoa,"DAZDEVR",knp,loff,dlen,&unit);

   if (wtyp == 'i' )
      {
      loff = (entrx * hlen) + 1;
      (void) SCDWRC(imnoa,"HCITTLUT",1,hcilut,loff,hlen,&unit);
      }
   else
      {
      (void) SCKRDR("PLRGRAP",1,glen,&iav,plrgrap,&unit,&null);
      loff = (entrx * glen) + 1;
      (void) SCDWRR(imnoa,"PLRGRAP",plrgrap,loff,glen,&unit);
      (void) SCKRDC("PLCMETA",1,1,gglen,&iav,plcmeta,&unit,&null);
      loff = (entrx * gglen) + 1;
      (void) SCDWRC(imnoa,"PLCMETA",1,plcmeta,loff,gglen,&unit);
      (void) SCKRDC("PLCDATA",1,1,gglen,&iav,plcdata,&unit,&null);
      (void) SCDWRC(imnoa,"PLCDATA",1,plcdata,loff,gglen,&unit);
      }
   }

else				/* IN = fill keywords from backing store */
   {
   loff = (entrx * 50) + 1;
   (void) SCDRDI(imnoa,"IDIDEVI",loff,50,&iav,tzdev,&unit,&null);

   if (wtyp == 'i')
      {
      dzmask[0] = 0; dzmask[1] = 4; dzmask[2] = 8;
      dzmask[3] = 9; dzmask[4] = 18; dzmask[5] = 2;
      dzmask[6] = 25; dzmask[7] = 3;
      dzlim = 8;

      loff = (entrx * dlen) + 1;
      (void) SCDRDI(imnoa,"DAZDEVR",loff,dlen,&iav,knp,&unit,&null);
      knp[9] = dzsave[0];
      knp[10] = dzsave[1];
      (void) SCKWRI("DAZDEVR",knp,1,dlen,&unit);
      loff = (entrx * hlen) + 1;
      (void) SCDRDC(imnoa,"HCITTLUT",1,loff,hlen,&iav,hcilut,&unit,&null);
      (void) SCKWRC("HCITTLUT",1,hcilut,1,hlen,&unit);
      }
   else
      {
      dzmask[0] = 24; dzmask[1] = 1; dzmask[2] = 31;
      dzmask[3] = 3; dzmask[4] = 38; dzmask[5] = 5;
      dzlim = 6;
      
      loff = (entrx * glen) + 1; /*PN, SW 8/99 this was missing? */
      
      (void) SCDRDR(imnoa,"PLRGRAP",loff,glen,&iav,plrgrap,&unit,&null);
      (void) SCKWRR("PLRGRAP",plrgrap,1,glen,&unit);
      loff = (entrx * gglen) + 1;
      (void) SCDRDC(imnoa,"PLCMETA",1,loff,gglen,&iav,plcmeta,&unit,&null);
      (void) SCKWRC("PLCMETA",1,plcmeta,1,gglen,&unit);
      (void) SCDRDC(imnoa,"PLCDATA",1,loff,gglen,&iav,plcdata,&unit,&null);
      (void) SCKWRC("PLCDATA",1,plcdata,1,gglen,&unit);
      }

   for (nr=0; nr<dzlim; nr+=2)		/* filter out only the */
      {					/* display/graphics relevant stuff */
      iav = dzmask[nr];
      for (mr=0; mr<dzmask[nr+1]; mr ++)
         {
         dzdev[iav] = tzdev[iav];
         iav++;				/* on HP: dzdev[iav] = tzdev[iav++] */
         }			/* gives problems with normal optimization!! */
      }

   (void) SCKWRI("IDIDEV",dzdev,1,50,&unit);
   }
}
/*

*/

void M_delwin(opnstat)
int    opnstat;

{
int   null, iav, linfo[5], winbuf[20], vbuf[20], kbuf[MAX_DEV_2];
int   n, m, stat, unit;
register int nr;

float  rbuf[10];

char    filea[80], dspidb;
char    cbuf[60];



(void) SCKRDC("P1",1,1,2,&iav,cbuf,&unit,&null);
if (wtyp == 'g')
   (void) strcpy(filea,"sxw   g");
else if (wtyp == 'z')
   (void) strcpy(filea,"sxw   z");
else if (wtyp == 'c')
   (void) strcpy(filea,"sxw   c");
else
   (void) strcpy(filea,"sxw   ");
filea[3] = midunit[0];                    /* add Midas-unit  */
filea[4] = midunit[1];
dspidb = cbuf[0];
filea[5] = dspidb;

if (dspidb == '*')                 /* construct filename: *g or *i  */
   {
   filea[0] = '*';
   filea[1] = wtyp;
   filea[2] = '\0';
   stat = IIDDEL_C(filea,&iav,&n,&m);   /* OJO: open + closes the connection */
   if ((wtyp == 'g') || (wtyp == 't'))
      m = -1;
   else
      n = -1;
   }
else
   stat = IIDDEL_C(filea,&iav,&n,&m);   /* OJO: open + closes the connection */

if (stat == 0)
   {
   linfo[0] = stat;			/* save status */
   linfo[1] = iav;			/* no. of displays deleted */
   linfo[2] = n;			/* index of image display */
   linfo[3] = m;			/* index of graphics display */
   }
else
   {
   if (stat == DEVNAMERR)
      {
      linfo[0] = -2;
      (void) sprintf(filea,"invalid %s_id ...",cwtype);
      SCTPUT(filea);
      }
   else
      linfo[0] = -1;

   linfo[1] = 0;
   linfo[2] = -1;
   linfo[3] = -1;
   }

(void) SCKWRI("OUTPUTI",linfo,17,4,&unit);

if (dspidb == '*')
   {
   for (nr=0; nr<MAX_DEV_2; nr+=2)
      {
      if (devnam[nr] == wtyp)
         {
         devnam[nr] = ' ';
         devnam[nr+1] = ' ';
         }
      }
   }
else
   {		/* IIDDEL_C was a special call - we have to reconnect now */  
   stat = IIDOPN_C("  ",&iav);		/* just get a connection */
   stat = IIEGDB_C(iav,2,0,devnam,kbuf,rbuf);
   (void) IIDCLO_C(iav);
   }


/* we don't update WINOPEN buffer directly, in order not to lose 
   icons (WINOPEN[m] = 2 for iconized displ/graph windows)                  */

(void) SCKRDI("WINOPEN",1,20,&iav,winbuf,&unit,&null);	/* previous state */

for (nr=0; nr<20; nr++) vbuf[nr] = 0;
for (nr=0; nr<MAX_DEV_2; nr+=2)
   {
   if ((devnam[nr] == 'i') || (devnam[nr] == 's'))
      {
      m = devnam[nr+1] - 48;		/* q+d conversion to integer */
      if ((m < 0) || (m > 9))
         SCETER(33,"invalid display id...");
      vbuf[m] = 1;
      }
   else if ((devnam[nr] == 'g') || (devnam[nr] == 't'))
      {
      m = devnam[nr+1] - 48;            /* q+d conversion to integer */
      if ((m < 0) || (m > 9))
         SCETER(33,"invalid graphics id...");
      vbuf[m+10] = 1;
      }
   }
for (nr=0; nr<20; nr++) 
   {
   if (vbuf[nr] == 0) winbuf[nr] = 0;
   }
(void) SCKWRI("WINOPEN",winbuf,1,20,&unit);


if (opnstat == 0)         /* update entry in `devnam' */
   (void) SCDWRC(imnoa,"IDIDEVNAM",1,devnam,1,MAX_DEV_2,&unit);

}
/*

*/

int main()

{
int   ec, ed, el, ln0, ln1;
int   nr, inp[13];
int   n, m, dispno, xoff, dinfo[25], sinfo[7];
int   own_lut;
int   xdev, ydev, opnstat, lutsize, noluts, lutoff;
int   iav, unit, null,stat;
int   fid, fidx;

char  filea[80], dspida, dspidb;
char  actio[3], xwstnam[82], cbuf[60];
char  refid;



(void) SCSPRO("wndcrea");
(void) SCKRDC("ACTION",1,6,3,&iav,actio,&unit,&null);


/*  get current display/graphics id  */

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

if (actio[0] == 'G')
   {
   wtyp  = 'g';
   dspida = cbuf[6];                    /* graphics */
   (void) strcpy(cwtype,"graphics");
   }
else
   {
   if (actio[0] == 'Z')			/* aux. zoom image window */
      {
      wtyp  = 'z';
      (void) strcpy(cwtype,"zoom");
      }
   else if (actio[0] == 'C')		/* aux. cursor window */
      {
      wtyp  = 'c';
      (void) strcpy(cwtype,"cursor");
      }
   else
      {
      wtyp  = 'i';	
      (void) strcpy(cwtype,"display");
      }
   dspida = cbuf[5];                    /* image */
   }

if (dspida == '-') dspida = ' ';
 

/* now open the "backing store" file idisave.dat   */

(void) strcpy(filea,"MID_WORK:idisave  .dat");
filea[16] = midunit[0];
filea[17] = midunit[1];

(void) SCECNT("GET",&ec,&el,&ed);              /* don't stop on errors */
ln1 = 1; ln0 = 0;
(void) SCECNT("PUT",&ln1,&ln0,&ln0);
opnstat = SCFOPN(filea,D_R4_FORMAT,0,F_IMA_TYPE,&imnoa);
if (opnstat != ERR_NORMAL)
   {
   if (actio[1] == 'S')
      {
      SCTPUT("Warning: no window created yet...");
      (void) SCSEPI();
      }
   if (actio[1] != 'D')
      {				/* check, if at least in MID_INCLUDE */
      (void) strcpy(filea,"MID_INCLUDE:idisave.dat");
      opnstat = SCFOPN(filea,D_R4_FORMAT,0,F_IMA_TYPE,&imnoa);

      if (opnstat == ERR_NORMAL)
         {
         (void) SCFCLO(imnoa);
         SCETER(6,"No `idisaveXY.dat' in MID_WORK, restart via RESET/DISPLAY");
         }

      SCTPUT("Your Midas manager has to execute the MIDAS command: @ idisave");
      SCTPUT("in order to recreate the file `idisave.dat' in MID_INCLUDE");
      SCTPUT("After that, restart via RESET/DISPLAY");
      SCETER(66,"Midas installation out of sync...");
      }
   }

(void) SCECNT("PUT",&ec,&el,&ed);
(void) SCDRDI(imnoa,"NO_OF_SUPPORTED_DISPLAYS",1,1,&iav,&m,&unit,&null);
if (m > MAX_DEV)
   SCETER(34,"idisaveXY.dat file: no. of supported devices out of sync!");
(void) SCDRDC(imnoa,"IDIDEVNAM",1,1,MAX_DEV_2,&iav,devnam,&unit,&null);

if ( ((cbuf[5] == ' ') || (cbuf[5] == '-')) &&
     ((cbuf[6] == ' ') || (cbuf[6] == '-')) )	/* 1st time forces cleaning */
   {
   if (actio[1] == 'C')
      {
      memset((void *)devnam,32,(size_t)MAX_DEV_2);	/* clear descriptor */
      (void) SCDWRC(imnoa,"IDIDEVNAM",1,devnam,1,MAX_DEV_2,&unit);
      }
   else
      SCETER(12,"Invalid command option...");
   }


/* delete a display/zoom/cursor/graphics window */

if (actio[1] == 'D')
   {
   M_delwin(opnstat);
   dzsave[0] = 0;
   dzsave[1] = 0;
   if (wtyp == 'z')
      (void) SCKWRI("IDIDEV",dzsave,19,2,&unit);   /* clear QXAUX, QYAUX */
   else if (wtyp == 'c')
      (void) SCKWRI("IDIDEV",dzsave,26,2,&unit); 
   (void) SCSEPI();
   }

dlen = 20;
glen = 40;
gglen = 80;
hlen = 42;


/*
    get the display characteristics from keyword IDIDEV, DAZDEVR
    see MID_INCLUDE:idinumd.h for detailed description of `dzdev' array
*/

(void) SCKRDI("IDIDEV",1,50,&iav,dzdev,&unit,&null);
rlen = IDI_RLEN;

(void) SCKRDI("DAZDEVR",1,dlen,&iav,knp,&unit,&null);

/*
knp[0] = minLUTsize;
knp[1] = noLUTs;  knp[2] = maxLUTsize;  knp[3] = ownLUT flag;
knp[4] = lut offset to be used, if ownLUT = -1 (companion mode);
knp[8] = 24bit flag;
knp[9,10] = currently active image + graphics window (have to be preserved!);
knp[11,12] = width, height of screen (in pixels);
knp[13] will be set to visual returned from IDIserver;
knp[14,15,16] = number for small, medium, large font;
knp[17] = RGBflag;
*/

if ( (knp[1] < 1) || (knp[2] < 2) )		/* check noLUT + maxLUTsize */
   {
   char  dumbuf[80];

   if (knp[1] < 1) 
      {
      (void) sprintf(dumbuf,
             "Invalid noLUT (= %d) entered - reset to 1 ...",knp[1]);
      knp[1] = 1;
      }
   else
      {
      (void) sprintf(dumbuf,
             "Invalid LUTsize (= %d) entered - set to 100 ...",knp[2]);
      knp[2] = 100;
      }
   SCTPUT(dumbuf);
   (void) SCKWRI("DAZDEVR",knp,1,2,&unit);
   }

if ( (knp[0] < 1) || (knp[0] > knp[2]) ) 		/* minLUTsize */
   {
   char  dumbuf[80];

   m = knp[0];
   knp[0] = 4;
   if (knp[0] > knp[2]) knp[0] = 1;
   (void) sprintf(dumbuf,
          "Invalid minLUTsize (= %d) entered - set to %d ...",m,knp[0]);
   SCTPUT(dumbuf);
   (void) SCKWRI("DAZDEVR",knp,1,2,&unit);
   }

dzsave[0] = knp[9];
dzsave[1] = knp[10];
if ((actio[1] == 'C') && (dzdev[21] == 1))
   {
   QLUTSZ = knp[2];			/* copy LUTsize */
   QNOLUT = knp[1];			/* and noLUTs   */
   dzdev[21] = 0;			/* initialize flag ... */
   }

(void) SCKRDC("HCITTLUT",1,1,hlen,&iav,hcilut,&unit,&null);
hcilut[42] = '\0';

/*
hcilut[0 - 19] = current ITT;
hcilut[20 - 39] = current LUT;
hcilut[40] = Y or N, if ITT enabled or not;
hcilut[41] = Y or N, if LUT enabled or not;
*/
 

/*  and get the specific input values for the command  */

(void) SCKGETC("DAZDEVC",1,80,&iav,xwstnam);
(void) SCKRDI("INPUTI",1,12,&iav,inp,&unit,&null);

/*
inp[0,1] = xdim,ydim of display; inp[2,3] = xoff,yoff of display;
inp[4] = no. of memories;
inp[5,6] = xdim,ydim of channel; inp[7] = depth of memories;
inp[8] = 0/1 for no/yes overlay channel (currently not used!); 
inp[9] = 0/1 for no/yes alpha memory;
inp[10] = no. of graphics segments to be saved;
inp[11] = index of background color (as in plotting), e.g. 1 = black;
*/


if (wtyp == 'i')
   xoff = 6;
else
   {
   inp[9] = 0;		/* no alpha memory for graphics window */
   xoff = 7;
   }


/*  get new display_id    */

(void) SCKRDC("P1",1,1,1,&iav,&dspidb,&unit,&null);
if (dspidb == ' ')
   dspidb = '0';
else if (dspidb == '.')                 /* crude test of float data */
   {
   (void) sprintf(filea,"invalid %s_id ...",cwtype);
   SCETER(2,filea);
   }


/* if we create shadow window, we need info from reference window */

if (actio[1] == 'P')	
   {
   refid = actio[2];		/* id of reference window */

   for (nr=0; nr<MAX_DEV_2; nr+=2)
      {
      if ( (devnam[nr] == wtyp) && (devnam[nr+1] == refid) )
         goto ref_id_ok;
      }
   (void) sprintf(filea,"reference %s window %c not there...",cwtype,refid);
   SCETER(5,filea);

  ref_id_ok:
   (void) strcpy(cbuf,"MID_WORK:sxw");
   cbuf[12] = midunit[0];
   cbuf[13] = midunit[1];
   cbuf[14] = dspidb;
   if (wtyp == 'g')
      (void) strcpy(&cbuf[15],"t.dat");
   else
      (void) strcpy(&cbuf[15],"s.dat");

   fid = CGN_OPEN(cbuf,WRITE);		/* create new data file */
   if (fid < 0)
      {
      (void) sprintf(filea,"could not create file `%s' in $MID_WORK ...",cbuf);
      SCETER(4,filea);
      }
   (void) sprintf(filea,"%s                  Xwindow station name\n",xwstnam);
   (void)osawrite(fid,filea,(int) strlen(filea));

   (void) sprintf(filea,"shadow,%c",refid);
   (void)osawrite(fid,filea,(int) strlen(filea));

   cbuf[14] = refid;			/* now copy ref-id sxw file */
   if (wtyp == 'g')
      (void) strcpy(&cbuf[15],"g.dat");
   else
      (void) strcpy(&cbuf[15],".dat");
   fidx = CGN_OPEN(cbuf,READ);
   if (fidx < 0)
      {
      (void) sprintf(filea,"could not open file `%s' in $MID_WORK ...",cbuf);
      SCETER(4,filea);
      }
   (void)osaread(fidx,filea,72);	/* skip 1st line with Xstation name */

   SCKGETC("P2",1,40,&iav,cbuf);	/* look for "shadow,0,offx,offy" */
   opnstat = -1;
   n = CGN_INDEXC(cbuf,',');
   opnstat = CGN_INDEXC(&cbuf[++n],',');
   if (opnstat > 0)
      {
      m = opnstat + n + 1;
      if (CGN_INDEXC(&cbuf[m],',') > 0)
      (void) strcpy(cbuf,&cbuf[m]);		/* we need 3 commas */
      }
   (void)osaread(fidx,filea,72);		/* copy line with alpha flag */
   filea[72] = '\0';	
   (void)osawrite(fid,filea,(int) strlen(filea)); 
   if (opnstat > 0)
      {
      (void)osaread(fidx,filea,72);	/* read line with window offset */
      n = CGN_INDEXC(filea,' ');
      filea[n] = '\0';
      n = CGN_INDEXC(filea,',');	/* move to 1st comma */
      m = CGN_INDEXC(&filea[++n],',');	/* move to 2nd comma */
      (void) strcat(cbuf,&filea[m+n]);
      (void)osawrite(fid,cbuf,(int) strlen(cbuf)); 
      }
   while (osaread(fidx,filea,72) > 0)
      {
      filea[72] = '\0';			/* just to make sure */
      (void)osawrite(fid,filea,(int) strlen(filea)); 
      }
   (void)osaclose(fid);
   (void)osaclose(fidx);
   (void) strcpy(cbuf,"sxw   s");
   cbuf[3] = midunit[0];
   cbuf[4] = midunit[1];
   cbuf[5] = dspidb;
   if (wtyp == 'g') cbuf[6] = 't';
   goto win_open;
   }


/*  else if we switch, just get in the new settings */

else if (actio[1] == 'S')
   {
   if (dspida == dspidb)		/* check, if not already there */
      {
      (void) sprintf(filea,"%s window %c already active ...",cwtype,dspida);
      SCTPUT(filea);
      (void) SCSEPI();
      }

   for (nr=0; nr<MAX_DEV_2; nr+=2)		/* save current entry */
      {
      if ( (devnam[nr] == wtyp) && (devnam[nr+1] == dspida) )
         {
         dsc2key('O',nr);
         break;
         }
      }


   for (nr=0; nr<MAX_DEV_2; nr+=2)	/* new display must exist already */
      {
      if ( (devnam[nr] == wtyp) && (devnam[nr+1] == dspidb) )
         {		/* get previously saved values for new disp/graph-id */
         dsc2key('I',nr);
         (void) SCKWRC("MID$SESS",1,&dspidb,xoff,1,&unit);
         (void) SCSEPI();
         }
      }
   (void) sprintf(filea,"new %s window not created yet ... ",cwtype);
   SCETER(3,filea);
   }


/* here we want to create a window, so search if already an entry there */

for (nr=0; nr<MAX_DEV_2; nr+=2)
   {
   if ( (devnam[nr] == wtyp) && (devnam[nr+1] == dspidb) )
      {
      (void) sprintf(filea,"%s window %c already exists...",cwtype,dspidb);
      SCTPUT(filea);
      (void) SCSEPI();
      }
   }

for (nr=0; nr<MAX_DEV_2; nr+=2)	/* not there yet, so look for free entry */
   {
   if (devnam[nr] == ' ')
      {
      devnam[nr] = wtyp;
      devnam[nr+1] = dspidb;
      goto entry_found;
      }
   }
SCETER(1,"no more space in descr. IDIDEVNAM ...");


entry_found:
(void) SCDWRC(imnoa,"IDIDEVNAM",1,devnam,1,MAX_DEV_2,&unit);

if (dspida != ' ')		/* save current info in backing store */
   {
   for (nr=0; nr<MAX_DEV_2; nr+=2)	/* look for current id */
      {
      if ( (devnam[nr] == wtyp) && (devnam[nr+1] == dspida) )
         {
         dsc2key('O',nr);
         goto wr_file;
         }
      }

   (void) sprintf(filea,"No entry for %s window %c found ...",cwtype,dspida);
   SCETER(7,filea);
   }


/* here we create the windows */
 
wr_file:
own_lut = knp[3];

(void) strcpy(cbuf,"sxw    ");			/* 4 blanks */
cbuf[3] = midunit[0];
cbuf[4] = midunit[1];
cbuf[5] = dspidb;

if (wtyp == 'g')
   cbuf[6] = 'g';
else if (wtyp == 'z')
   cbuf[6] = 'z';
else if (wtyp == 'c')
   cbuf[6] = 'c';
else 			 /* store the new values into keyword IDIDEV */
   {
   QDSZX = inp[0];	   /* store xdim, ydim of display window  */
   QDSZY = inp[1];
   QGRSEG = inp[10];		/* no. of graphics segments to save */
   QALPNO = inp[9];		/* indicate alpha memory or not */
   QMSZX = inp[5];		/* store xdim, ydim of memories   */
   QMSZY = inp[6];
   if (inp[7] > 0) QMDEP = inp[7];
   QIMCH = 0;		      /* init current image channel to 0  */
   QLSTCH = inp[4];	/* "add" overlay channel as last one */
   QOVCH = QLSTCH;
   for (nr=0; nr<IDI_ILEN; nr++)  idimemi[nr] = 0;
   (void) SCKWRI("IDIMEMI",idimemi,1,IDI_ILEN,&unit);
   for (nr=0; nr<IDI_CLEN; nr++)  idimemc[nr] = ' ';
   (void) SCKWRC("IDIMEMC",1,idimemc,1,IDI_CLEN,&unit);
   
   cbuf[6] = '\0';
   }
   
(void) SCKWRC("MID$SESS",1,&dspidb,xoff,1,&unit);


/*  fill info array for SetupIDI   */

dinfo[0] = inp[9];
dinfo[1] = inp[0];
dinfo[2] = inp[1];
dinfo[3] = inp[2];
dinfo[4] = inp[3];
dinfo[5] = QNOLUT;
dinfo[6] = knp[2];
dinfo[7] = knp[0];
dinfo[8] = own_lut;
if (own_lut != -1)
   dinfo[9] = 0;		/* offset only needed for ownlut = -1 */
else
   dinfo[9] = knp[4];
dinfo[10] = knp[14];
dinfo[11] = knp[15];
dinfo[12] = knp[16];
dinfo[13] = inp[4];
dinfo[14] = inp[10];
dinfo[15] = inp[5];
dinfo[16] = inp[6];
dinfo[17] = inp[7];
dinfo[18] = QRGBFL;
dinfo[19] = inp[11];		/* background color */
dinfo[20] = knp[8];

if (QRGBFL == 1) 
   {
   dinfo[9] = 0;
   dinfo[13] = 3;		/* for RGB we use always 3 channels */
   }

stat = SetupIDI(cbuf,xwstnam,dinfo);
if (stat < 0) 
   {
   (void) 
   sprintf(filea,"could not create file `%s'.dat in $MID_WORK ...",cbuf);
   SCETER(4,filea);
   }


win_open:				/* now really open the window */
stat = IIDOPN_C(cbuf,&dispno);
if (stat == 0)
   QDZFND = 2;			/* new window was created */

else if (stat == ENTRYFND)
   QDZFND = 1;			/* existing window was accessed */

else 
   {
   idimess(stat,filea);			/* get error message for `stat' */
   if (filea[0] != '\0')
      SCETER(9,filea);
   else
      {
      (void) sprintf(filea,"Problems with IIDOPN (status = %d) ...\n",stat);
      SCTPUT(filea);
      SCETER(9,"Shut down the idiserver via 'reset/display' first.");
      }
   }


/* get depth of display */

IIDQDV_C(dispno,&n,&xdev,&ydev,&m,&iav,&iav,&iav);
QDDEP = m;
if (QRGBFL == 1) 
   {
   QMDEP = 8;
   QOVCH = 3;
   QLSTCH = 3;
   }
else
   QMDEP = QDDEP;


/* check, if lutsize has been changed  */
/* get no.of LUTs, LUTsize, LUToffset  */

if (actio[1] != 'P')
   {
   stat = IIDQCI_C(dispno,18,7,sinfo,&m); 	/* now 7 values returned */
   noluts = sinfo[0];
   lutsize = sinfo[1];
   lutoff = sinfo[2];
   if ((sinfo[3] > 0) && (sinfo[4] == 2))	/* private LUT in PseudoColor */
      {
      int  icount, wbuf[20];
      char  xbig[80];

      (void) SCKRDI("WINOPEN",1,20,&iav,wbuf,&unit,&null);
      icount = 0;
      for (nr=0; nr<20; nr++) 		/* is this the first window? */
         {
         if (wbuf[nr] != 0) icount++;
         }

      if (icount < 2)
         {
         (void) sprintf(xbig,
       "Not enough colors available (MinLUTsize = %d) - private LUT installed.",
         knp[0]);
         SCTPUT(xbig);
         }
      }

   if ((lutsize != 0) && (lutsize != QLUTSZ))
      {
      /*
      (void) sprintf(filea,"LUTsize has been changed from %d to %d",
                     QLUTSZ,lutsize);
      SCTPUT(filea);
      */
      QLUTSZ = lutsize;
      }

   if (noluts != QNOLUT)
      {
      QNOLUT = noluts;
      (void) sprintf(filea,"no. of LUTs has been changed to %d",noluts);
      SCTPUT(filea);
      }
   
   if (wtyp == 'i') 
      {
      if (QDZFND == 2)
         {
         QXAUX = 0;				/* clear aux_window size */
         QYAUX = 0;
         }
      else
         {
         dzdev[1] = dinfo[1];			/* display size */
         dzdev[2] = dinfo[2];
         dzdev[8] = inp[10];			/* save no. of graph. segm. */
         dzdev[10] = dinfo[15];			/* channel size */
         dzdev[11] = dinfo[16];
         }
      }

   if (wtyp == 'g')
      {
      dzdev[31] = dinfo[1];			/* graphics size */
      dzdev[32] = dinfo[2];
      dzdev[38] = inp[10];			/* save no. of graph. segm. */
      dzdev[40] = dinfo[1];			/* channel size */
      dzdev[41] = dinfo[2];
      }

   if (wtyp == 'z') 
      {
      stat = IIDQDV_C(dispno,&n,&xdev,&ydev,&m,&ec,&ed,&el);
      QXAUX = xdev;
      QYAUX = ydev;
      }

   knp[13] = sinfo[4];		/* get visual mode */
   dzdev[6] = knp[13] - 2;	/* OJO: client = 2, 3, 4, 5 */
				/*      server = 0, 1, 2, 3 */
   (void) SCKWRI("IDIDEV",dzdev,1,50,&unit);	/* update IDIDEV */

   knp[9] = dzsave[0];   knp[10] = dzsave[1];
   knp[11] = sinfo[5];   knp[12] = sinfo[6];	/* width, height of screen */

   if (noluts <= 0)
      knp[4] = -1;
   else
      knp[4] = lutoff;
   (void) SCKWRI("DAZDEVR",knp,1,dlen,&unit);	/* update DAZDEVR */
   }
   
if (wtyp == 'g')
   {
   n = 0;			/* use channel 0  */
   stat = IIMSMV_C(dispno,&n,1,1);			/* make it visible */
   stat = IICINC_C(dispno,-1,0,2,2,100,100);      /* init cursor */
   }
else	
   {
   if (QOVCH >= 0)
      {
      n = QOVCH;
      stat = IIMSMV_C(dispno,&n,1,1);  /* SET/OVERLAY */
      }
   }

(void) IIDCLO_C(dispno);
(void) SCSEPI();

return 0;			/* to make "gcc -wall' happy */
}

