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

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

/* file iid1.c : contains the following routines
*
*   IIDINIT	  : initialize structures
*   IIDOPN_C      : Open Display;
* 
*   pars24		 : map 3 digits xyz -> co_flg, rd_flg, wr_flg
*					       = flag24[2], [1], [0]
* 
*************************************************************************
* V 1.1 871201: P. Santin - Trieste Astronomical Observatory            
* V 2.0 881130  Klaus Banse - ESO Garching                              
* 
* 090826	last modif
* 150827	DISPLAY may be very long string (Mac OSX 10.10)	  (KB)
*		so increase size of Xworkst[].name and buffer record in IIDOPN
*************************************************************************
*/

# include    <stdlib.h>             
# include    <stdio.h>


# include    <idi.h>             
# include    <idistruct.h>
# include    <proto_idi.h>             
# include    <midas_def.h>             
# include    <osparms.h>             


static int   f_wndw[MAX_WST], f_lut[MAX_WST], f_RGB[MAX_WST];
static int   start_flag = -1;

static char  ididir[64];

/*

*/

int pars24(ival,flags)
int  ival, *flags;

{
int  wf, rf, sf;
int mm;



if (ival > 99)
   {
   sf = ival/100;
   mm = ival - (sf*100);
   rf = mm/10;
   wf = mm - (rf*10);
   }
else if (ival > 9)
   {
   sf = 0;
   rf = ival/10;
   wf = ival - (rf*10);
   }
else                            /* no special flag for copy/display */
   {
   sf = rf = 0;
   wf = ival;
   }

if (wf == 2)                    /* 1 = on, 0 or 2 = off */
   flags[0] = 0;
else
   flags[0] = wf;
if (rf == 2)
   flags[1] = 0;
else
   flags[1] = rf;
if (sf == 2)
   flags[2] = 0;
else
   flags[2] = sf;

/*
printf("sf = %d, rf = %d, wf = %d\n",flags[2],flags[1],flags[0]); 
*/

return 0;
}

/*

*/

/************************************************************************/

void IIDINIT()

{
int   i, m;

char  muni[4];


for (i=0; i<MAX_DEV; i++)
   {
   ididev[i].opened = 0;
   ididev[i].screen = 0;
   ididev[i].devname[0] = '\0';
   }

OSY_GETSYMB("DAZUNIT",muni,4);
muni[2] = '\0';

for (i=0; i<MAX_WST; i++)
   {
   f_wndw[i] = 0;
   f_lut[i] = 1;
   Xworkst[i].name[0] = '\0';
   (void) strcpy(Xworkst[i].miduni,muni);		/* save MIDAS unit */
   }

(void) OSY_TRNLOG("MID_WORK",ididir,64,&m);

}

/*

*/

/************************************************************************
* IIDOPN_C routine : opens a new display for subsequent operations      *
*                                                                       *
* synopsis  IIDOPN_C (display, displayid);                              *
*                                                                       *
*       char[] display; input     device name                           *
*       int *displayid; output    display identifier                    *
************************************************************************/

int IIDOPN_C (display, displayid)
int  *displayid;
char display[];

{
int     x0, y0, fontno[4];
int     devxoff, devyoff, devxdim, devydim, dstatus;
int     shadow, ival[5], len, k1, screeno, gsize;
int     i, j, k, m;
int     limited, con_main, minlut, RGBmode, flag24;
int     fp;
register int nr;
unsigned int allbytes;

char    dspchar, cbuf[12], record[120], name[24];
char    *disp_var;

float   rval, fval;
double  dval;

LUT_DATA       *lut;
ITT_DATA       *itt;
CURS_DATA      *curs;
ALPH_DATA      *alph;
ROI_DATA       *roi;
CONF_DATA      *conf;
MEM_DATA       *mem;
INTER_DATA     *ixter;
LOCATOR        *loca;
TRIGGER        *trigg;
GLIST          *graph;
TLIST          *txt;
INTBAR         *bar;


/*  look, if we're here for the very first time */

if (start_flag == -1)
   {
   IIDINIT();				/* initialize the stuff */
   start_flag = 0;
   }

else if (display[0] == ' ')		/* we only wanted the connection */
   {
   for (i=0; i<MAX_DEV; i++)
      {
      if (ididev[i].devname[0] != '\0')
         {
         *displayid = i;
         ididev [i].opened = 1;
         loc_zero(i);                      /* reset locators  */
         return(ENTRYFND);                 /* indicate, that already there */
         }
      }
   }

 
/*  search through all opened ididevs  */

for (i=0; i<MAX_DEV; i++)
   {
   if (strcmp(display,ididev[i].devname) == 0)
      {
      *displayid = i;
      ididev [i].opened = 1;
      loc_zero(i);			/* reset locators  */
      return(ENTRYFND);			/* indicate, that already there */
      }
   }

/*  so look for empty ididev structure  */

for (i=0; i<MAX_DEV; i++)
   {
   if (ididev[i].devname[0] == '\0')
      {
      *displayid = i;
      goto first_time;
      }
   }

return (NOAVAILDEV);			/*  return with error  */



/* get ididev parameters from sxwAB...dat file    */
/* ---------------------------------------------- */


first_time:

shadow = -1;
limited = 0;
j = 5;

dspchar = display[j++];
switch (display[j])
   {
   case 'g':
    ididev[i].devtyp = 'g';		/* it's a graphics window */
    limited = 1;
    break;
   case 'z':				/* if "sxwAB0z", it's a zoom window */
    ididev[i].devtyp = 'z';
    break;
   case 'c':				/* if "sxwAB0c" => cursor window */
    ididev[i].devtyp = 'c';
    limited = 2;
    break;
   case 's':				/* "sxwAB0s", display shadow window */
    ididev[i].devtyp = 'i';
    shadow = 0;
    break;
   case 't':				 /* "sxwAB0t", graphic shadow window */
    ididev[i].devtyp = 'g';
    limited = 1;
    shadow = 0;
    break;
   default:
    ididev[i].devtyp = 'i';		/* everything else is image window */
   }
 
(void) strcpy(record,ididir);
if (display[0] == ' ')			/* we just wanted to connect */
   return(DCTFILERR);

(void) strcat(record,display);
(void) strcat(record,".dat");

fp = osaopen(record,READ);
if (fp < 0) 
   {					/* wait 1 sec + try one more time */
   unsigned int ms;

   ms = 1000;
   OSY_SLEEP(ms,0);	
   fp = osaopen(record,READ);
   if (fp < 0) 
      {
      (void) printf("IIDOPN: where is %s ?\n",record);
      return(DCTFILERR);
      }
   }

(void) strcpy (ididev[i].devname,display);
con_main = -1;


/*  first of all get Xworkstation name */

if ((len = osaread(fp,record,72)) < 1) goto file_err;
for (nr=0; nr<len; nr++)
   {
   if (record[nr] == ' ')
      {
      record[nr] = '\0';
      break;
      }
   }

if (strcmp(record,"default") == 0)
   {
   if (!(disp_var = getenv("DISPLAY")))
      {
      dstatus = 9;
      goto gen_err;
      }
   len = (int) strlen(disp_var);
   if (len > 119)			/* size of Xworkst[].name: 120 chars */
      {
      dstatus = 9;
      goto gen_err;
      }
   (void) strcpy(record,disp_var);
   }

else if ( ((record[0]=='z')&&(record[1]=='o')) ||
          ((record[0]=='c')&&(record[1]=='u')) )	/* zoom or cursor w. */
   {
   for (nr=0; nr<MAX_DEV; nr++)         /* look for main window */
      {
      if ( (nr != i) &&
          (ididev[nr].devname[0] != '\0') &&
          (ididev[nr].devname[5] == display[5]) )
         {
         con_main = nr;			/* save connected main window */
         if (record[4] != ',')                  /* same Xstation */
            {
            screeno = ididev[nr].screen;
            goto xwst_ok;
            }
         else
            {					/* zoom,Xstation */
            if (strcmp(&record[5],"default") == 0)
               {
               if (!(disp_var = getenv("DISPLAY")))
                  {
                  dstatus = 9;
                  goto gen_err;
                  }
               len = (int) strlen(disp_var);
               if (len > 119)
                  {
                  dstatus = 9;
                  goto gen_err;
                  }
               (void) strcpy(record,disp_var);
               }
            else
               (void) strcpy(record,&record[5]);	/* move to begin */
            goto find_Xst;
            }
         }
      }

   dstatus = WSTNAMERR;                  /*  no main window found */
   goto gen_err;
   }


/*  look for same Xstation or attach new one */

find_Xst:
for (nr=0; nr<MAX_WST; nr++)
   {
   if (strcmp(record,Xworkst[nr].name) == 0)
      {
      screeno = nr;
      goto xwst_ok;
      }
   }
for (nr=0; nr<MAX_WST; nr++)
   {
   if (Xworkst[nr].name[0] == '\0')
      {
      screeno = nr;
      (void) strcpy(Xworkst[nr].name,record);
      goto xwst_ok;
      }
   }

dstatus = WSTNAMERR;			/*  return with error  */
goto gen_err;


/* check if we are a shadow window => update owner entry */

xwst_ok:
ididev[i].screen = screeno;
ididev[i].ref = '\0';
for (j=0; j<MAX_DEV; j++) ididev[i].shadow[j] = -1;

if (shadow == 0)			/* read  "shadow,ref-id"  line  */
   {
   if ((len = osaread(fp,record,72)) < 1) goto file_err;
   len = CGN_INDEXC(record,',');
   (void) strncpy(cbuf,display,5);	/* construct name of ref. window */
   cbuf[5] = record[++len];
   if (ididev[i].devtyp == 'g')
      (void) strcpy(&cbuf[6],"g");
   else
      cbuf[6] = '\0';
   for (nr=0; nr<MAX_DEV; nr++)
      {
      if (strcmp(cbuf,ididev[nr].devname) == 0)
         {
         shadow = nr;                           /* save owner id for later */
         ididev[i].ref = cbuf[5];		/* save reference display */
         goto next_rec;
         }
      }
   dstatus = ILLSHADOW;			/* no reference display found */
   goto gen_err;
   }


/*  get alpha_memo flag, RGB mode, backgr. colour, 24bit flag  */

next_rec:
if ((len = osaread(fp,record,72)) > 0)
   len = CGN_CNVT(record,1,4,ival,&fval,&dval);
if (len < 4) goto file_err;
ididev[i].alpno = ival[0];
RGBmode = ival[1];
k = ival[2];
ididev[i].backpix = ival[2];		/* just save the index for now */
flag24 = ival[3];	/* serves as byte swap for special,read,write flag */


/* get display offset + dimensions   */

if ((len = osaread(fp,record,72)) > 0)
   len = CGN_CNVT(record,1,4,ival,&fval,&dval);
if (len < 4) goto file_err;
devxoff = ival[0];  devyoff = ival[1];
devxdim = ival[2];  devydim = ival[3];

                                      
/*  get noLUTS, maxLUTsize, minLUTsize, ownLUT, LUToffset  */

if ((len = osaread(fp,record,72)) > 0)
   len = CGN_CNVT(record,1,5,ival,&fval,&dval);
if (len < 5) goto file_err;
minlut = ival[2];
ididev[i].lutoff = ival[4];

if (f_wndw[screeno] == 0)
   {						/* connect to display */
   dstatus = Xwstinit(0,Xworkst[screeno].name,screeno,fontno,minlut);
   if (dstatus != II_SUCCESS) goto gen_err;
   Xworkst[screeno].nolut = ival[0];
   Xworkst[screeno].lutsize = ival[1];
   Xworkst[screeno].ownlut = ival[3];	   /* maybe modified by Xwstinit ... */
   }
                                      
                                      
/*  get font numbers for small, medium, large font */

if ((len = osaread(fp,record,72)) > 0)
   {
   len = CGN_CNVT(record,1,3,fontno,&fval,&dval);   /* fontno[4] is special */
   if (len < 3) goto file_err;				/* we need 3 fonts */
   }

ididev[i].opened = 1;
ididev[i].xsize  = devxdim;      /* set by display window section */
ididev[i].ysize  = devydim;      /* set by display window section */

ididev[i].trigger = 0;		     /* exit trigger is 0  */
ididev[i].inter_mask = 0;
ididev[i].n_inter = 0;
ididev[i].ncurs = 2;
ididev[i].lutsect = 0;		/* default to 1. (maybe only) LUT section  */
ididev[i].lookup = 0;
ididev[i].bar = 0;
ididev[i].hcopy = (char *) 0;
ididev[i].curswin = -1;
ididev[i].link[0] = 0;
ididev[i].link[1] = -1;



/* ----------------------- */
/* create virtual display  */
/* ----------------------- */


if (RGBmode == 1)
   name[0] = 'T';				/* TrueColor */
else
   {
   name[0] = 'P';				/* PseudoColor */
   if (RGBmode == 0)
      name[1] = 'S';
   else if (RGBmode == 2)
      name[1] = 'D';				/* on top of DirectColor */
   else 
      {
      RGBmode = 2;
      name[1] = 'T';				/* on top of TrueColor */
      }
   }

if (f_wndw[screeno] == 0)
   {					/* get fonts +  colour maps */ 
   if (ididev[i].devtyp == 'g')
      f_wndw[screeno] = 2;			/* graphics window is first */
   else
      f_wndw[screeno] = 1;			/* display window is first */

   dstatus = Xwstinit(f_wndw[screeno],name,screeno,fontno,minlut);
   if (dstatus != II_SUCCESS) goto gen_err;
   set_wcur(i,-1);				/* create all cursor shapes */
   if (Xworkst[screeno].lutflag != 0)
      f_wndw[screeno] = 1;			/* we did already everything */
   if (Xworkst[screeno].visual == 4)
      RGBmode = 2;			/* emulate Pseudo on DirectColor */
   
   f_RGB[screeno] = RGBmode;
   }

else if (f_wndw[screeno] == 2)
   {
   if (ididev[i].devtyp != 'g')		/* display window after graphics */
      {
      f_wndw[screeno] = 1;
      dstatus = Xwstinit(3,name,screeno,fontno,minlut);
      if (dstatus != II_SUCCESS) goto gen_err;
      }
   }

RGBmode = f_RGB[screeno];		/* so all windows have same RGBflag */

/* flag24 uses 3 digits: x y z		1 = on, 2 = off (also 0 = off) 
   used for special_flag (x), read_flag (y), write_flag (z) 
   Xworkst[screeno].flag24[0,1,2] = z,y,x  */

if (flag24 == 0)			/* if not set, check it here */
   {
   if (test_swap(i) == 1)		/* yes we swap bytes */
      flag24 = 11;
   }
(void) pars24(flag24,Xworkst[screeno].flag24);


if (ididev[i].alpno >= 90)
   {
   ididev[i].alphx = devxdim-2;		/* border width = 1 pixel  */
   ididev[i].alphy = 50;	
   ididev[i].alphxscal = 512./80.;
   ididev[i].alphlinsz = 12;		/* pixels per line  */
   m = devydim + ididev[i].alphy + 2;	/* add space for alpha subwindow  */
   dstatus = crea_win(i,devxoff,devyoff,devxdim,m,dspchar);
   crealph(i,devydim);		   /* create also the alphanumerics window  */
   }
else
   {
   ididev[i].alphy = -2;	
   dstatus = crea_win(i,devxoff,devyoff,devxdim,devydim,dspchar);
   if (ididev[i].devtyp == 'c')		/* cursor window have no alpha mem */
      {
      ididev[con_main].curswin = i;
      ididev[i].curswin = -con_main;		/* keep pointer to main w. */
      }
   }

if (dstatus != II_SUCCESS) goto gen_err;
sendX(i);				/* flush out Xstuff  */
x0 = ididev[i].xsize / 2; 
y0 = ididev[i].ysize / 2;
ididev[i].depth = Xworkst[screeno].depth;

dstatus = MEMALLERR;
for (j=0; j<ididev[i].ncurs; j++)
   {
   allbytes = sizeof(struct curs_data);
   curs = (struct curs_data *) malloc((size_t)allbytes);
   if (curs == II_NULL) goto gen_err;
   
   ididev[i].cursor[j] = curs;
   curs->sh    = -1;         /* sh = -1 : cursor not defined */
   curs->col   = 0;
   curs->vis   = 0;
   curs->xpos = x0;
   curs->ypos = y0;
   }

allbytes = sizeof(struct roi_data);
roi = (struct roi_data *) malloc((size_t)allbytes);
if (roi == II_NULL) goto gen_err;
       
ididev[i].roi = roi;
roi->sh    = -1;            /* roi_sh = -1 : ROI not defined */
roi->col   = 0;
roi->vis   = 0;
roi->xmin = x0 - 20;
roi->ymin = y0 - 20;
roi->xmax = x0 + 20;
roi->ymax = y0 + 20;
roi->radiusi = 20;
roi->radiusm = 0;
roi->radiuso = 0;
roi->radno = 4;

allbytes = sizeof(struct conf_data);
conf = (struct conf_data *) malloc((size_t)allbytes);
if (conf == II_NULL) goto gen_err;
       
ididev[i].confptr = conf;
conf->memid = 0;
conf->RGBmode = RGBmode;


/*  get no. of memories + size of GLIST segments  */

if ((len = osaread(fp,record,72)) > 0)
   len = CGN_CNVT(record,1,2,ival,&fval,&dval);
if (len < 2) goto file_err;

if (RGBmode == 1)
   k1 = 1;
else
   k1 = ival[0];
gsize = ival[1];

for (k=0; k<k1; k++)		/* loop over memories */
   {
   allbytes = sizeof(struct mem_data);
   mem = (struct mem_data *) malloc((size_t)allbytes);
   if (mem == II_NULL) goto gen_err;
      
   conf->memory[k] = mem;
   if ((len = osaread(fp,record,72)) > 0)
      len = CGN_CNVT(record,1,3,ival,&fval,&dval);
   if (len < 3) goto file_err;

   mem->xsize = ival[0];
   mem->ysize = ival[1];
   if (ival[2] < 0)
      mem->depth = ididev[i].depth;
   else
      mem->depth = ival[2];
      
   if (ididev[i].devtyp == 'g')
      mem->type = II_GRAPHIC | II_TEXT;
   else
      mem->type = II_IMAGE | II_GRAPHIC | II_TEXT;
   if (RGBmode == 1) mem->type = mem->type | II_RGB;
   mem->mmbm = (char *) 0;
   mem->zmbm = (char *) 0;
   mem->pixmap = 0;
   if (k == 0)
      mem->visibility = 1;		/* make first channel visible */
   else
      mem->visibility = 0;
   clmem(mem);				/* set all memory parameters  */
      
   if (ididev[i].alpno >= 90)
      {					/* allocate alpha memory */
      allbytes = sizeof(struct alph_data);
      alph = (struct alph_data *) malloc((size_t)allbytes);
      if (alph == II_NULL) goto gen_err;
      
      conf->alpmem[k] = alph;
      for (nr=0; nr<16; nr++)
         alph->savx[nr] = -1;
      }

   if (ididev[i].devtyp == 'g')
      mem->ittpntr = (ITT_DATA *)0;	/* no ITT for graph/cursor windows */
   else
      {
      allbytes = sizeof(struct itt_data);
      itt = (struct itt_data *) malloc((size_t)allbytes);
      if (itt == II_NULL) goto gen_err;
      mem->ittpntr = itt;
      itt->vis = 0;		    /* default to ITT visibility off  */
      for (nr=0; nr<Xworkst[screeno].lutlen; nr++)
         itt->val[nr] = nr; 
      }

   if (gsize <= 0)
      mem->gpntr = (GLIST *)0;			/* no graphics structure */
   else
      {
      allbytes = sizeof(struct glist);
      graph = (struct glist *) malloc((size_t)allbytes);
      if (graph == II_NULL) goto gen_err;
      mem->gpntr = graph;
      graph->geln = 0;
      graph->maxpnt = gsize;
      len = graph->maxpnt/2;
      allbytes = sizeof(int) * (2*graph->maxpnt + 4*len);	/* for x,y */
      graph->x = (int *) malloc((size_t)allbytes);		/* color, lwidth, */
      if (graph->x == II_NULL) goto gen_err;
      graph->y = graph->x + graph->maxpnt;
      graph->color = graph->y + graph->maxpnt;
      graph->lwidth = graph->color + len;
      graph->off = graph->lwidth + len;
      graph->count = graph->off + len;
      *(graph->off) = 0;
      }
         
   if (limited > 0)
      mem->tpntr = (TLIST *)0;
   else
      {
      allbytes = sizeof(struct tlist);
      txt = (struct tlist *) malloc((size_t)allbytes);
      if (txt == II_NULL) goto gen_err;
      mem->tpntr = txt;
      txt->teln = 0;
      txt->off[0] = 0;
      }
   mem->plane_no = 1;
   }

osaclose(fp);


/* for graphics window 
   the overlay channel is the image channel itself  */

if (ididev[i].devtyp == 'g')
   {
   conf->nmem = k1;
   conf->overlay = conf->memid;
   }
else
   {
   conf->nmem = k1 + 1;		/* add 1 for overlay channel */
   conf->overlay = k1;		/* last channel  */


   /*  now also init the structure for the added overlay/graphics channel  */
 
   allbytes = sizeof(struct mem_data);
   mem = (struct mem_data *) malloc((size_t)allbytes);
   if (mem == II_NULL) return(MEMALLERR);

   conf->memory[k1] = mem;
   mem->xsize = ival[0];		/* use values of last channel  */
   mem->ysize = ival[1];
   mem->depth = ival[2];
   mem->type = II_IMAGE | II_GRAPHIC | II_TEXT;
   if (RGBmode == 1) mem->type = mem->type | II_RGB;
   mem->mmbm = (char *) 0;
   mem->zmbm = (char *) 0;
   mem->pixmap = 0;
   mem->visibility = 1;		/* we enable overlay right away */
   clmem(mem);	
   mem->ittpntr = (ITT_DATA *)0;

   if (gsize <= 0)
      mem->gpntr = (GLIST *)0;			/* no graphics structure */
   else
      {
      allbytes = sizeof(struct glist);
      graph = (struct glist *) malloc((size_t)allbytes);
      if (graph == II_NULL) return(MEMALLERR);
      mem->gpntr = graph;
      graph->geln = 0;
      graph->maxpnt = gsize;
      len = graph->maxpnt/2;
      allbytes = sizeof(int) * (2*graph->maxpnt + 4*len);    /* for x,y */
      graph->x = (int *) malloc((size_t)allbytes);          /* color, lwidth, */
      if (graph->x == II_NULL) return(MEMALLERR);    /* off and count */
      graph->y = graph->x + graph->maxpnt;
      graph->color = graph->y + graph->maxpnt;
      graph->lwidth = graph->color + len;
      graph->off = graph->lwidth + len;
      graph->count = graph->off + len;
      *(graph->off) = 0;
      }
 
   allbytes = sizeof(struct tlist);
   txt = (struct tlist *) malloc((size_t)allbytes);
   if (txt == II_NULL) return(MEMALLERR);
   mem->tpntr = txt;
   txt->teln = 0;
   txt->off[0] = 0;
   mem->plane_no = 1;
   }

if (limited != 2)		/* not for cursor window */
   {
   for (j=0; j<MAX_INTER; j++)
      {
      allbytes = sizeof(struct inter_data);
      ixter = (struct inter_data *) malloc((size_t)allbytes);
      if (ixter == II_NULL) return(MEMALLERR);
       
      ididev[i].inter[j] = ixter;
      }

   intdevtable[i].nloc = MAX_LOC;
   intdevtable[i].ntrig = MAX_TRG;

   for (j=0; j<intdevtable[i].nloc; j++)
      {
      allbytes = sizeof(struct locator);
      loca = (struct locator *) malloc((size_t)allbytes);
      if (loca == II_NULL) return(MEMALLERR);
       
      if (j == 0)
         loca->interactor = II_MOUSE;
      else
         loca->interactor = II_KEYB;
      intdevtable[i].loc[j] = loca;
      }

   loc_zero(i);		/* reset all locators */

   for (j=0; j<intdevtable[i].ntrig; j++)
      {
      allbytes = sizeof(struct trigger);
      trigg = (struct trigger *) malloc((size_t)allbytes);
      if (trigg == II_NULL) return(MEMALLERR);
       
      if (j < 2)			/* assume 2 buttons on the mouse  */
         trigg->interactor = II_MOUSE;
      else
         trigg->interactor = II_KEYB;
      intdevtable[i].trig[j] = trigg;
      }
   }

if (shadow >= 0)			/* if shadow window update owner */
   {
   for (j=0; j<MAX_DEV; j++)
      {
      if (ididev[shadow].shadow[j] == -1)
         {
         ididev[shadow].shadow[j] = i;
         break;
         }
      }
   }



/*  create LUT bar structure  */

allbytes = sizeof(struct lut_bar);
bar = (struct lut_bar *) malloc((size_t)allbytes);
if (bar == II_NULL) return(MEMALLERR);

ididev[i].bar = bar;
bar->wp = 0;
bar->vis = 0;


/*   check if we have own LUT handling  */

if ( (limited > 0) ||
     ((Xworkst[screeno].visual != 4) && (Xworkst[screeno].ownlut == 0)) )
   return(II_SUCCESS);


if (Xworkst[screeno].ownlut == -1) 
   {
   for (nr=0; nr<256; nr++)		/* add LUT offset at least... */
      {
      j = nr + ididev[i].lutoff;
      if (j > 255) j = 0;
      Xworkst[screeno].mapin[nr] = j;
      Xworkst[screeno].mapout[j] = nr;
      }
   return(II_SUCCESS);
   }


allbytes = sizeof(struct lut_data);
lut = (struct lut_data *) malloc((size_t)allbytes);
if (lut == II_NULL) return(MEMALLERR);
ididev[i].lookup = lut;
lut->vis = 1;				/* make LUT always visible */


/* send black + white LUT only the very first time  */

if (f_lut[screeno] == 1) 
   {	
   float   lut0[768];

   f_lut[screeno] = 0;
   len = Xworkst[screeno].lutlen;
   rval = 1.0 / (len - 1.0);
   m = len + len;
   fval = 0.0;

   for (nr=0; nr<len; nr++)
      {
      lut0[nr] = fval;
      lut0[len + nr] = fval;
      lut0[m + nr] = fval;
      fval += rval;
      }
 
   m = IILWLT_C(i,0,0,len,lut0);
   LUTinstall(i);			/* install LUT if needed */
   }
else
   rd_lut(i,lut);			/* get current LUT */

return(II_SUCCESS);


gen_err:
 (void) osaclose(fp);
 return(dstatus);

file_err:
 (void) osaclose(fp);
 return(DCTREADERR);
}

