/*===========================================================================
  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 idilocal3.c                 
*                                   
*   IDI  Device Dependent Routines 
*   (XWindows version)            
*                                
* V 1.00 940630  K. Banse  ESO - Garching                            
*
* file idilocal3.c : contains the following routines
*
*  draw_curs            : Draw different cursor shapes 
*  draw_rroi            : Draw Rectangular ROI;
*  draw_croi            : Draw Circular ROI;
*  destroy              : destroy Xstructures + free related memory
*  exposed              : look for Expose events
*  stopped 		: look for Exit button events 
*  iconify 		: iconify (or not) display window
*  send_event 		: send an event to a window
*   
 
 090424		last modif
************************************************************************/

# include    <idi.h>
# include    <idistruct.h>
# include    <x11defs.h>
# include    <filedef.h>
# include    <proto_idi.h>

#include    <stdio.h>



extern int CGN_OPEN(), CGN_CNVT(), OSY_SLEEP();
extern int osaopen(), osaread(), osaclose();
extern long int osaseek();

static int crossize = 20;
static int cursrad = 4, zoomf = 20;
static int xysiz[2], xy1off[2], xy2off[2] = {0,0};

static CONF_DATA  *conf;
static MEM_DATA   *mema, *memb;


/*

*/

/* ---- draw  cursor -------------------------------------------- */

/* flag = 0,   first time
        = 1,   normal mode
        = 2,   last time     */


void draw_curs(dspno,flag,dysize,curno,xcur,ycur,cursh,curcol)
int   dspno, flag, dysize, curno, xcur, ycur, cursh, curcol;

{
int   no, x1, x2, y1, y2, x3, x4, y3, y4;
int   xx1, xx2, yy1, yy2, xx3, xx4, yy3, yy4;
int   k, tmpx;
static int  count0[MAX_DEV], count1[MAX_DEV];


/*  erase old cursor */

no = ididev[dspno].screen;
if (flag > 0)
   {
   if (curno == 0)
      XDrawSegments(mydisp[no],mwndw[dspno],gcdraw[dspno],
                    &curso0[dspno][0],count0[dspno]);
   else
      XDrawSegments(mydisp[no],mwndw[dspno],gcdraw[dspno],
                    &curso1[dspno][0],count1[dspno]);
   
   if (flag > 1) return;
   }


ycur = dysize - ycur;

xx1 = xx2 = xx3 = xx4 = 0;
yy1 = yy2 = yy3 = yy4 = 0;

if (cursh == II_CROSSHAIR)
   {
   k = 2;
   x1 = 0;
   y1 = ycur;
   x2 = 2000;				/* let X do the clipping ... */
   y2 = y1;
   x3 = xcur;
   y3 = 0;
   x4 = x3;
   y4 = dysize;
   }

else if (cursh == II_SMALCROSS)
   {
   k = 2;
   tmpx = 7;
   x1 = xcur - tmpx;
   y1 = ycur;
   x2 = xcur + tmpx;
   y2 = y1;
   x3 = xcur;
   y3 = y1 - tmpx;
   x4 = x3;
   y4 = y1 + tmpx;
   }

else if (cursh == II_OPNCROSS)
   {
   k = 4;
   tmpx = crossize - 4;
   x1 = xcur - crossize;
   y1 = ycur;
   x2 = x1 + tmpx;
   y2 = y1;
   xx1 = xcur + crossize;
   yy1 = y1;
   xx2 = xx1 - tmpx;
   yy2 = y1;
   
   x3 = xcur;
   y3 = ycur - crossize;
   x4 = x3;
   y4 = y3 + tmpx;
   xx3 = x3;
   yy3 = ycur + crossize;
   xx4 = x3;
   yy4 = yy3 - tmpx;
   }
					/*  the default is II_CROSS ... */
else
   {
   k = 2;
   x1 = xcur - crossize;
   y1 = ycur;
   x2 = xcur + crossize;
   y2 = y1;
   x3 = xcur;
   y3 = y1 - crossize;
   x4 = x3;
   y4 = y1 + crossize;
   }


if (curno == 0)
   {
   count0[dspno] = k;
   curso0[dspno][0].x1 = x1;
   curso0[dspno][0].y1 = y1;
   curso0[dspno][0].x2 = x2;
   curso0[dspno][0].y2 = y2;
   curso0[dspno][1].x1 = x3;
   curso0[dspno][1].y1 = y3;
   curso0[dspno][1].x2 = x4;
   curso0[dspno][1].y2 = y4;
   if (count0[dspno] > 2)
      {
      curso0[dspno][2].x1 = xx1;
      curso0[dspno][2].y1 = yy1;
      curso0[dspno][2].x2 = xx2;
      curso0[dspno][2].y2 = yy2;
      curso0[dspno][3].x1 = xx3;
      curso0[dspno][3].y1 = yy3;
      curso0[dspno][3].x2 = xx4;
      curso0[dspno][3].y2 = yy4;
      }
   XDrawSegments(mydisp[no],mwndw[dspno],gcdraw[dspno],
                    &curso0[dspno][0],count0[dspno]);
   }

else
   {
   count1[dspno] = k;
   curso1[dspno][0].x1 = x1;
   curso1[dspno][0].y1 = y1;
   curso1[dspno][0].x2 = x2;
   curso1[dspno][0].y2 = y2;
   curso1[dspno][1].x1 = x3;
   curso1[dspno][1].y1 = y3;
   curso1[dspno][1].x2 = x4;
   curso1[dspno][1].y2 = y4;
   if (count1[dspno] > 2)
      {
      curso1[dspno][2].x1 = xx1;
      curso1[dspno][2].y1 = yy1;
      curso1[dspno][2].x2 = xx2;
      curso1[dspno][2].y2 = yy2;
      curso1[dspno][3].x1 = xx3;
      curso1[dspno][3].y1 = yy3;
      curso1[dspno][3].x2 = xx4;
      curso1[dspno][3].y2 = yy4;
      }
   XDrawSegments(mydisp[no],mwndw[dspno],gcdraw[dspno],
                 &curso1[dspno][0],count1[dspno]);
   }

if ((k = ididev[dspno].curswin) > -1)
   {
   conf = ididev [dspno].confptr;
   mema = conf->memory[conf->memid];
   conf = ididev [k].confptr;
   memb = conf->memory[0];			/* single memory */
   if (mema->load_dir == 0) ycur = dysize - ycur;  

   if (xcur < cursrad)				/* extract 11x11 subwindow */
      xy1off[0] = 0;
   else
      xy1off[0] = xcur - cursrad;
   if (ycur < cursrad)
      xy1off[1] = 0;
   else
      xy1off[1] = ycur - cursrad;
   tmpx = 2*cursrad + 1;
   if ((xcur+tmpx) >= ididev[dspno].xsize)
      xysiz[0] = ididev[dspno].xsize - xcur;
   else
      xysiz[0] = tmpx;
   if ((ycur+tmpx) >= dysize)
      xysiz[1] = dysize - ycur;
   else
      xysiz[1] = tmpx;

   copy_mem(dspno,mema,xy1off,memb,xy2off,xysiz,zoomf);
   smv(2,k,memb,0,memb->xscroll,memb->yscroll,memb->xsize,memb->ysize,0,0);
   zoomcross[0].x1 = 61;
   zoomcross[0].y1 = 90;
   zoomcross[0].x2 = 120;
   zoomcross[0].y2 = 90;
   zoomcross[1].x1 = 90;
   zoomcross[1].y1 = 61;
   zoomcross[1].x2 = 90;
   zoomcross[1].y2 = 120;
   XDrawSegments(mydisp[ididev[k].screen],mwndw[k],gcima[k],
                 zoomcross,2);
   zoomcross[0].x1 ++;
   zoomcross[0].y1 ++;
   zoomcross[0].x2 ++;
   zoomcross[0].y2 ++;
   zoomcross[1].x1 ++;
   zoomcross[1].y1 ++;
   zoomcross[1].x2 ++;
   zoomcross[1].y2 ++;
   XDrawSegments(mydisp[ididev[k].screen],mwndw[k],gcdraw[k],
                 zoomcross,2);
   }
}

/*

*/

/* ---- draw rectangular ROI ----------------------------------------- */

void draw_rroi(dspno,flag,dysize,x0,y0,x1,y1,roicol)
int   dspno, flag, dysize, x0, y0, x1, y1, roicol;

{
int   yd0, yd1, k, no, tmpx;
static int countr[MAX_DEV];


/*  erase old ROI */

no = ididev[dspno].screen;
if (flag > 0)
   {
   if (countr[dspno] == 5)
      XDrawSegments(mydisp[no],mwndw[dspno],gcdraw[dspno],
                    &roio[dspno][1],1);
   else
      XDrawSegments(mydisp[no],mwndw[dspno],gcdraw[dspno],
                    &roio[dspno][0],countr[dspno]);

   if (flag > 1) return;
   }


yd0 = dysize - y0;
yd1 = dysize - y1;

roio[dspno][0].x1 = x0;
roio[dspno][0].y1 = yd0;
roio[dspno][0].x2 = x1;
roio[dspno][0].y2 = yd0;

roio[dspno][1].x1 = x1;
roio[dspno][1].y1 = yd0;
roio[dspno][1].x2 = x1;
roio[dspno][1].y2 = yd1;

roio[dspno][2].x1 = x1;
roio[dspno][2].y1 = yd1;
roio[dspno][2].x2 = x0;
roio[dspno][2].y2 = yd1;

roio[dspno][3].x1 = x0;
roio[dspno][3].y1 = yd1;
roio[dspno][3].x2 = x0;
roio[dspno][3].y2 = yd0;


/* check, if ROI collapses to a line (or point)  */

countr[dspno] = 4;
if (y0 == y1) countr[dspno] = 1;
if (x0 == x1) countr[dspno] = 5;

if (countr[dspno] == 5)
   XDrawSegments(mydisp[no],mwndw[dspno],gcdraw[dspno],
                 &roio[dspno][1],1);
else
   XDrawSegments(mydisp[no],mwndw[dspno],gcdraw[dspno],
                 &roio[dspno][0],countr[dspno]);
 
if ((k = ididev[dspno].curswin) > -1)
   {
   conf = ididev [dspno].confptr;
   mema = conf->memory[conf->memid];
   conf = ididev [k].confptr;
   memb = conf->memory[0];                      /* single memory */
   if (mema->load_dir == 0) yd0 = dysize - yd0;      /* ycur <= dysize-ycur  */
 
   if (x0 < cursrad)                          /* extract 11x11 subwindow */
      xy1off[0] = 0;
   else
      xy1off[0] = x0 - cursrad;
   if (yd0 < cursrad)
      xy1off[1] = 0;
   else
      xy1off[1] = yd0 - cursrad;
   tmpx = 2*cursrad + 1;
   if ((x0+tmpx) >= ididev[dspno].xsize)
      xysiz[0] = ididev[dspno].xsize - x0;
   else
      xysiz[0] = tmpx;
   if ((yd0+tmpx) >= dysize)
      xysiz[1] = dysize - yd0;
   else
      xysiz[1] = tmpx;

   copy_mem(dspno,mema,xy1off,memb,xy2off,xysiz,zoomf);
   smv(2,k,memb,0,memb->xscroll,memb->yscroll,memb->xsize,memb->ysize,0,0);
   zoomcross[0].x1 = 61;
   zoomcross[0].y1 = 90;
   zoomcross[0].x2 = 120;
   zoomcross[0].y2 = 90;
   zoomcross[1].x1 = 90;
   zoomcross[1].y1 = 61;
   zoomcross[1].x2 = 90;
   zoomcross[1].y2 = 120;
   XDrawSegments(mydisp[ididev[k].screen],mwndw[k],gcima[k],
                 zoomcross,2);
   zoomcross[0].x1 ++;
   zoomcross[0].y1 ++;
   zoomcross[0].x2 ++;
   zoomcross[0].y2 ++;
   zoomcross[1].x1 ++;
   zoomcross[1].y1 ++;
   zoomcross[1].x2 ++;
   zoomcross[1].y2 ++;
   XDrawSegments(mydisp[ididev[k].screen],mwndw[k],gcdraw[k],
                 zoomcross,2);
   }
}

/*

*/

/* ---- draw circular ROI ----------------------------------------- */

/* 
     x0, y0 - center coords
     r1, r2, r3 - radius of inner, middle and outer circle
*/

void draw_croi(dspno,flag,dysize,x0,y0,r1,r2,r3,roicol)
int   dspno, flag, dysize, x0, y0, r1, r2, r3, roicol;

{
register int  wti, wtm, wto;
int   k, yd0, no, tmpx;
static int ang1 = 0;
static int ang2 = 23040;			/* 64 * 360 deg.  */
static int  ulxi[MAX_DEV], ulyi[MAX_DEV], ulxm[MAX_DEV];
static int  ulym[MAX_DEV], ulxo[MAX_DEV], ulyo[MAX_DEV];
static int countr[MAX_DEV];
static unsigned int  wi[MAX_DEV], wm[MAX_DEV], wo[MAX_DEV];

#define SZA  4
#define SZB  8


/*  erase old roi */

no = ididev[dspno].screen;
if (flag > 0)
   {
   if (countr[dspno] == 1)			/* just a single point */
      XDrawPoint(mydisp[no],mwndw[dspno],gcdraw[dspno],
                 ulxi[dspno],ulyi[dspno]);
   else
      {
      XDrawSegments(mydisp[no],mwndw[dspno],gcdraw[dspno],
                    &roio[dspno][0],4);

      XDrawArc(mydisp[no],mwndw[dspno],gcdraw[dspno],
                    ulxi[dspno],ulyi[dspno],wi[dspno],wi[dspno],ang1,ang2);
      if (wm[dspno] != 1)
         XDrawArc(mydisp[no],mwndw[dspno],gcdraw[dspno],
                       ulxm[dspno],ulym[dspno],wm[dspno],wm[dspno],ang1,ang2);
      if (wo[dspno] != 1)
         XDrawArc(mydisp[no],mwndw[dspno],gcdraw[dspno],
                       ulxo[dspno],ulyo[dspno],wo[dspno],wo[dspno],ang1,ang2);
      }

   if (flag > 1) return;
   }


yd0 = dysize - y0;

roio[dspno][0].x1 = x0 - SZB;
roio[dspno][0].y1 = yd0;
roio[dspno][0].x2 = x0 - SZA;
roio[dspno][0].y2 = yd0;
roio[dspno][1].x1 = x0 + SZB;
roio[dspno][1].y1 = yd0;
roio[dspno][1].x2 = x0 + SZA;
roio[dspno][1].y2 = yd0;
roio[dspno][2].x1 = x0;
roio[dspno][2].y1 = yd0 - SZB;
roio[dspno][2].x2 = x0;
roio[dspno][2].y2 = yd0 - SZA;
roio[dspno][3].x1 = x0;
roio[dspno][3].y1 = yd0 + SZB;
roio[dspno][3].x2 = x0;
roio[dspno][3].y2 = yd0 + SZA;


/* determine width (= height) of surrounding rectangle */

wti = r1 + r1 + 1;			/* always > 0 */
wtm = r2 + r2 + 1;
wto = r3 + r3 + 1;

if (wtm == wti) wtm = 1;
if (wto == wti)
   wto = 1;
else if (wto == wtm)
   wto = 1;

wi[dspno] = wti;
wm[dspno] = wtm;
wo[dspno] = wto;

ulxi[dspno] = x0 - r1;   ulyi[dspno] = yd0 - r1;     /* upper left corners */
ulxm[dspno] = x0 - r2;   ulym[dspno] = yd0 - r2;
ulxo[dspno] = x0 - r3;   ulyo[dspno] = yd0 - r3;


/* check, if ROI collapses to a point  */


if ((r1 == 0) && (r2 == 0) && (r3 == 0))
   {
   countr[dspno] = 1;
   XDrawPoint(mydisp[no],mwndw[dspno],gcdraw[dspno],ulxi[dspno],ulyi[dspno]);
   }
else
   {
   countr[dspno] = 99;

   XDrawSegments(mydisp[no],mwndw[dspno],gcdraw[dspno],
                 &roio[dspno][0],4);

   XDrawArc(mydisp[no],mwndw[dspno],gcdraw[dspno],
                 ulxi[dspno],ulyi[dspno],wi[dspno],wi[dspno],ang1,ang2);
   if (wm[dspno] != 1)
      XDrawArc(mydisp[no],mwndw[dspno],gcdraw[dspno],
               ulxm[dspno],ulym[dspno],wm[dspno],wm[dspno],ang1,ang2);
   if (wo[dspno] != 1)
      XDrawArc(mydisp[no],mwndw[dspno],gcdraw[dspno],
               ulxo[dspno],ulyo[dspno],wo[dspno],wo[dspno],ang1,ang2);
   }

if ((k = ididev[dspno].curswin) > -1)
   {
   conf = ididev [dspno].confptr;
   mema = conf->memory[conf->memid];
   conf = ididev [k].confptr;
   memb = conf->memory[0];                      /* single memory */
   if (mema->load_dir == 0) yd0 = dysize - yd0;      /* ycur <= dysize-ycur  */

   if (x0 < cursrad)                          /* extract 11x11 subwindow */
      xy1off[0] = 0;
   else
      xy1off[0] = x0 - cursrad;
   if (yd0 < cursrad)
      xy1off[1] = 0;
   else
      xy1off[1] = yd0 - cursrad;
   tmpx = 2*cursrad + 1;
   if ((x0+tmpx) >= ididev[dspno].xsize)
      xysiz[0] = ididev[dspno].xsize - x0;
   else
      xysiz[0] = tmpx;
   if ((yd0+tmpx) >= dysize)
      xysiz[1] = dysize - yd0;
   else
      xysiz[1] = tmpx;

   copy_mem(dspno,mema,xy1off,memb,xy2off,xysiz,zoomf);
   smv(2,k,memb,0,memb->xscroll,memb->yscroll,memb->xsize,memb->ysize,0,0);
   zoomcross[0].x1 = 61;
   zoomcross[0].y1 = 90;
   zoomcross[0].x2 = 120;
   zoomcross[0].y2 = 90;
   zoomcross[1].x1 = 90;
   zoomcross[1].y1 = 61;
   zoomcross[1].x2 = 90;
   zoomcross[1].y2 = 120;
   XDrawSegments(mydisp[ididev[k].screen],mwndw[k],gcima[k],
                 zoomcross,2);
   zoomcross[0].x1 ++;
   zoomcross[0].y1 ++;
   zoomcross[0].x2 ++;
   zoomcross[0].y2 ++;
   zoomcross[1].x1 ++;
   zoomcross[1].y1 ++;
   zoomcross[1].x2 ++;
   zoomcross[1].y2 ++;
   XDrawSegments(mydisp[ididev[k].screen],mwndw[k],gcdraw[k],
                 zoomcross,2);
   }
}

/*

*/
/* ----    Destroy Xstructures     ----------------------------------- */

void destroy(dspno,stri)
int  dspno;
char   *stri;

{
int   i, no;

CONF_DATA  *conf;
MEM_DATA   *mem;



no = ididev[dspno].screen;
if (*stri == 'h')			/* hardcopy stuff */
   XDestroyImage(hcopy[dspno]);

else if (*stri == 'a')			/* alpha memory stuff */
   {
   XFreeGC(mydisp[no],gcalph[dspno]);
   XDestroyWindow(mydisp[no],alphwnd[dspno]);
   }

else if (*stri == 'l')			/* LUT bar stuff */
   {
   XDestroyImage(lutxima[dspno]);
   XFreeGC(mydisp[no],gclut[dspno]);
   XDestroyWindow(mydisp[no],lutwnd[dspno]);
   }

else if (*stri == 'm')			/* all memories in configuration */
   {
   conf = ididev[dspno].confptr;

   for (i=0; i<conf->nmem; i++)
      {
      mem = conf->memory[i];
      if (mem->mmbm != (char *) 0)
         {
         if (mem->pixmap == 1) XFreePixmap(mydisp[no],mxpix[dspno][i]);
         XDestroyImage(mxima[dspno][i]);
         }
      }
   }

else if (*stri == 'd')			/* main display stuff  */
   {
   XFreeGC(mydisp[no],gcdraw[dspno]);
   XFreeGC(mydisp[no],gcima[dspno]);
   XDestroyWindow(mydisp[no],mwndw[dspno]);
   }

}

/*

*/
 
/* ----    process Expose events    ----------------------------------- */

int exposed(wstno,dispno)
int  wstno, dispno;

{
int  dspno, nk, k, i ;
int  oldw, oldh;

MEM_DATA    *mem;
CONF_DATA   *conf;
INTBAR      *bar;


/* process an Expose event for single screen + display window */

if (wstno >= 0)
   {
cle_events:				/* get rid of all Expose events */
   k = XCheckTypedWindowEvent
       (mydisp[wstno],mwndw[dispno],Expose,&myevent);
   if (k != 0) goto cle_events;

   bar = ididev[dispno].bar;
   if (bar != 0)			/* process color bar */
      {
      if (bar->wp != 0)
         idi_putimage(mydisp[wstno],lutwnd[dispno],gclut[dispno],
                   lutxima[dispno],0,0,0,0,bar->xsize,bar->ysize);
      }
   conf = ididev[dispno].confptr;

   for (i=0; i<conf->nmem; i++)
      {
      mem = conf->memory[i];
      if (mem->visibility == 1)
         {
         allrefr(dispno,mem,i,1);       /* refresh memory */
         if ( (ididev[dispno].alpno >= 90) && (conf->overlay != i) )
            alprfr(dispno,conf->alpmem[i]);	/* refresh alpha memory */
         }
      }
   return II_SUCCESS;
   }


/* test for all screens + display/graphic windows
   if an Expose or ConfigureNotify event occurred    */

for (nk=0; nk<MAX_WST; nk++)
   {
   if (Xworkst[nk].name[0] != '\0')
      {
      for (dspno=0; dspno<MAX_DEV; dspno++)
         {
         if (ididev[dspno].devname[0] != '\0')
            {
            k = XCheckTypedWindowEvent
                (mydisp[nk],mwndw[dspno],ConfigureNotify,&myevent);
            if (k != 0)
               {		/* move on to last event */
clean_confev:
               k = XCheckTypedWindowEvent
                   (mydisp[nk],mwndw[dspno],ConfigureNotify,&myevent);
               if (k != 0) goto clean_confev;

               oldw = ididev[dspno].xsize;		/* to comapre size */
               ididev[dspno].xsize = myevent.xconfigure.width;
               oldh = ididev[dspno].ysize;
               ididev[dspno].ysize = 
                  myevent.xconfigure.height - ididev[dspno].alphy - 2;

               if (ididev[dspno].hcopy != (char *) 0)	
                  {				/* see if we had a hardcopy */
                  destroy(dspno,"hcopy");
                  ididev[dspno].hcopy = (char *) 0;
                  }

               conf = ididev[dspno].confptr;
               mem = conf->memory[0];
               if ((mem->xsize < ididev[dspno].xsize) ||
                   (mem->ysize < ididev[dspno].ysize))
                  {
                  for (i=0; i<conf->nmem; i++)
                     {
                     mem = conf->memory[i];
                     if (mem->mmbm != (char *) 0)
                        {
                        if (mem->pixmap == 1) 
                           XFreePixmap(mydisp[nk],mxpix[dspno][i]);
                        XDestroyImage(mxima[dspno][i]);
                        mem->mmbm = (char *) 0;
                        }
                     mem->xsize = ididev[dspno].xsize;
                     mem->ysize = ididev[dspno].ysize;
                     }
                  }

               bar = ididev[dspno].bar;
               if (bar != 0)
                  {
                  if (bar->wp == 1)		/* LUT bar already created */
                     {
                     oldw -=ididev[dspno].xsize;
                     oldh -=ididev[dspno].ysize;
                     if ((oldw != 0) || (oldh != 0))
                        {
                        destroy(dspno,"lutbar");
                        if (bar->vis == 1) 
                           crelutbar(dspno,bar);
                        else
                           bar->wp = 0;
                        }
                     }
                  }

               if (ididev[dspno].alpno >= 90)
                  {
                  XDestroyWindow(mydisp[nk],alphwnd[dspno]);
                  ididev[dspno].alphx = ididev[dspno].xsize - 2;

                  alphwnd[dspno] = XCreateSimpleWindow(mydisp[nk],
                                   mwndw[dspno],0,ididev[dspno].ysize,
                                   ididev[dspno].alphx,ididev[dspno].alphy,
                                   1,Xworkst[nk].white,Xworkst[nk].black);
                  if (alphwnd[dspno] == 0) return(WINOTOPN);
                  XMapRaised (mydisp[nk],alphwnd[dspno]);
                  alprfr(dspno,conf->alpmem[conf->memid]);  /* refresh alpha */
                  }
               return II_SUCCESS;
               }


            k = XCheckTypedWindowEvent
                (mydisp[nk],mwndw[dspno],Expose,&myevent);
            if (k != 0)
               {		/* move on to last event */
clean_expev:
               k = XCheckTypedWindowEvent
                   (mydisp[nk],mwndw[dspno],Expose,&myevent);
               if (k != 0) goto clean_expev;

               if (ididev[dspno].bar != 0)	/* process color bar */
                  {
                  if (ididev[dspno].bar->wp != 0)
                     idi_putimage(mydisp[nk],lutwnd[dspno],gclut[dspno],
                               lutxima[dspno],0,0,0,0,
                               ididev[dspno].bar->xsize,
                               ididev[dspno].bar->ysize);
                  }
               conf = ididev[dspno].confptr;

               for (i=0; i<conf->nmem; i++)
                  {
                  mem = conf->memory[i];
                  if (mem->visibility == 1)
                     {
                     allrefr(dspno,mem,i,1);       /* refresh memory */
                     if ( (ididev[dspno].alpno >= 90) &&
                          (conf->overlay != i) )
                        alprfr(dspno,conf->alpmem[i]);   /* refresh alpha */
                     }
                  }
               }
            }
         }
      }
   }
return II_SUCCESS;
}

/*

*/
 
/* ----    process Exit button events    ----------------------------------- */

int stopped(dspno)
int  dspno;

{
int  no, k;


/* process an Exit button event for single screen + display window */

no = ididev[dspno].screen;
k = XCheckTypedWindowEvent
    (mydisp[no],mwndw[dspno],ButtonPress,&myevent);
if (k == 0) return(0);


cle_events:				/* get rid of all Expose events */
k = XCheckTypedWindowEvent
    (mydisp[no],mwndw[dspno],ButtonPress,&myevent);
if (k != 0) goto cle_events;

if (myevent.xbutton.button != 1)	/* if button 2 or 3 */
   return (1);
else
   return (0);

}

/*

*/

/* ---- get fonts  --------------------------------------- */

int font_load(flag,no,fontno)
int flag, no, *fontno;

{
int  fp, k, np, j, jj, tmpx;

XFontStruct *xfp;

char  record[104];
static char  *fonts1[4] = {"fixed",
           "-Adobe-Helvetica-Bold-R-Normal--18-180-75-75-P-103-ISO8859-1",
           "-Adobe-Helvetica-Bold-R-Normal--24-240-75-75-P-138-ISO8859-1",
           "-Adobe-Symbol-Medium-R-Normal--2*"};
static char  *fonts2[4] = {"fixed",
           "-Adobe-Helvetica-Bold-R-Normal--1*",
           "-Adobe-Helvetica-Bold-R-Normal--2*",
           "-Adobe-Symbol-Medium-R-Normal--2*"};




xfp = (XFontStruct *) 0;
fp = CGN_OPEN("MID_WORK:x11fonts.dat",READ);	/* first, try `own' Font file */
if (fp <0)					/* open system Font file */
   fp = CGN_OPEN("MID_SYSTAB:x11fonts.dat",READ);

jj = np = 0;

if (flag == 0) 
   {				/* here to initialize Fonts for display */
   myfont[no][3] = XLoadQueryFont(mydisp[no],fonts1[3]);
   if (myfont[no][3] == xfp)
      myfont[no][3] = XLoadQueryFont(mydisp[no],fonts2[3]);
   if (myfont[no][3] != xfp)
      fontno[3] = 2;				/* special font set */
   else
      fontno[3] = -1;				/* special font not found */


   if (fp == -1)
      {
      for (k=0; k<3; k++) fontno[k] = -1;
      (void) printf("Could not open Fonts file MID_SYSTAB:x11fonts.dat\n");
      }

   for (k=0; k<3; k++)
      {
      if (fontno[k] > 0)		/* font no. explicitely given */
         {
         (void)osaseek(fp,0L,FILE_START);	/* always rewind file */
         for (j=0; j<fontno[k]; j++)		/* and move to given record */
            jj = osaread(fp,record,100);
   
         fontno[k] = -1;			/* init to wrong data */
         if (jj > 5)
            {
            for (np=0; np<jj; np++)
               {
               if (record[np] == ':')
                  {
                  np += 2;			/* point to font name string */
                  fontno[k] = 1;		/* we found it! */
                  break;			/* get out of loop */
                  }
               }
            }
         }

      if (fontno[k] == 1)
         {
         myfont[no][k] = XLoadQueryFont(mydisp[no],&record[np]);
         if (myfont[no][k] == xfp) fontno[k] = -1;
         }

      if (fontno[k] < 1)
         {                                 /* try two different defaults */
         myfont[no][k] = XLoadQueryFont(mydisp[no],fonts1[k]);
         if (myfont[no][k] == xfp)
            myfont[no][k] = XLoadQueryFont(mydisp[no],fonts2[k]);
         if (myfont[no][k] != xfp) fontno[k] = 2;    /* indicate success */
         }
      }

   if (fp != -1) (void)osaclose(fp);

   tmpx = 0;
   if (fontno[2] < 0) tmpx |= 4;
   if (fontno[1] < 0) tmpx |= 2;
   if (fontno[0] < 0) tmpx |= 1;

   if (tmpx != 0)
      {
      switch (tmpx)
         {
         case 7:
         (void) printf("could not get any font...\n");
         return (-1);
   
         case 6:
         myfont[no][2] = myfont[no][0];
         myfont[no][1] = myfont[no][0];
         break;

         case 5:
         myfont[no][2] = myfont[no][1];
         myfont[no][0] = myfont[no][1];
         break;

         case 4:
         myfont[no][2] = myfont[no][1];
         break;

         case 3:
         myfont[no][1] = myfont[no][2];
         myfont[no][0] = myfont[no][2];
         break;

         case 2:
         myfont[no][1] = myfont[no][0];
         break;

         case 1:
         myfont[no][0] = myfont[no][1];
         }
      }

   if (fontno[3] < 0) myfont[no][3] = myfont[no][0];
   }

else
   {					/* load new Font for Font #4 */
   if (fp == -1)
      {
      (void) printf("Could not open Fonts file MID_SYSTAB:x11fonts.dat\n");
      return (-1);
      }

   k = -fontno[0];				/* new Font no. */
   if (k < 1) return (-2);

   (void)osaseek(fp,0L,FILE_START);		/* always rewind file */
   for (j=0; j<k; j++)				/* and move to given record */
      jj = osaread(fp,record,100);
  
   if (jj > 5)
      {
      for (np=0; np<jj; np++)
         {
         if (record[np] == ':')
            {
            np += 2;			/* point to font name string */
            break;			/* get out of loop */
            }
         }
      }

   (void)osaclose(fp);

   if (myfont[no][3] != xfp)			/* last font was o.k. */
      XFreeFont(mydisp[no],myfont[no][3]);	/* release old Font */

   myfont[no][3] = XLoadQueryFont(mydisp[no],&record[np]);
   if (myfont[no][3] == xfp) 
      {						/* invalid font string ... */
      (void) printf("Could not load Font:\n%s\n",&record[np]);
      myfont[no][3] = XLoadQueryFont(mydisp[no],"fixed");
      (void) printf("Use Font `fixed' instead\n");
      }
   }

return (0);
}

/*

*/

/* ---- iconify (de-iconify) display window ----------------------------- */

void iconify(dspno,flag)
int   dspno, flag;

{
int  no;


no = ididev[dspno].screen;
XUnmapWindow(mydisp[no],mwndw[dspno]);		/* unmap window */

if (flag == 1)
   xwmh.initial_state = IconicState;
else 
   xwmh.initial_state = NormalState;

XSetWMHints(mydisp[no],mwndw[dspno],&xwmh);
XMapRaised (mydisp[no],mwndw[dspno]);		/* map as icon or window */
}

/*

*/

/* ---- send an event to a window -------------------------------------*/

void send_event(dspno)
int   dspno;

{
int  no, evtype, reclen, ibuf[8], dysize;
int  delindx, epsi2;
long int evmask;
static int delay = 1000;			/* in msecs */

float  rbuf;

double dbuf;

char  evbuf[44];


read_auto_cursor:
reclen = osaread(auto_cursor_fid,evbuf,42);
if (evbuf[0] == '!')
   goto read_auto_cursor;			/* skip comment lines */

if (reclen > 0) 
   {
   no = CGN_CNVT(evbuf,1,8,ibuf,&rbuf,&dbuf);
   if (no > 0)
      {
      evtype = ibuf[0];
      if (evtype > -1) goto do_events;		/* (-1) => stop auto_cursor */
      }
   }

else if (reclen < 0) 					/* EOF reached */
   {
   (void) osaseek(auto_cursor_fid,0L,FILE_START);	/* rewind file */
   goto read_auto_cursor;
   }

else
   goto read_auto_cursor;			/* nothing there, skip */


/* here we are, if we want to get back into interactive cursor input */

osaclose(auto_cursor_fid);
auto_cursor_fid = -1;		/* stop automatic event generation */
evtype = 0;
no = 1;


/* beware, X11 has 0,0 at top left corner...
   the epsi2 business is needed for the way `curmove' works ... */

do_events:
dysize = ididev[dspno].ysize - 1;
epsi2 = 2;		/* has to be synchronized with `epsi2' in idiutil2.c */

if (evtype == 1)
   {				/* send ENTER (left Mouse Button) */
   delindx = 3;			/* index of delay value */
   myevent.type = ButtonPress;
   myevent.xbutton.x = ibuf[1] - epsi2;
   myevent.xbutton.y = dysize - ibuf[2] + epsi2;
   myevent.xbutton.button = 1;
   }

else if (evtype == 2)
   {				/* send arrow key input (for 2. cursor) */
   delindx = 2;			/* index of delay value */
   myevent.type = KeyPress;
   myevent.xkey.keycode = (unsigned int) (ibuf[1]+100);	/* is an unsigned no. */
   }

else				/* send EXIT (right Mouse Button) */
   {
   delindx = 1;			/* index of delay value */
   myevent.type = ButtonPress;
   if (no > 2)
      {
      myevent.xbutton.x = ibuf[1] - epsi2;
      myevent.xbutton.y = dysize - ibuf[2] + epsi2;
      }
   else
      {
      myevent.xbutton.x = 10;		/* arbitrary values */
      myevent.xbutton.y = 10;
      }
   myevent.xbutton.button = 3;
   }


evmask = 0;
no = ididev[dspno].screen;
(void) XSendEvent(mydisp[no],mwndw[dspno],False,evmask,&myevent);

if (no > delindx) delay = ibuf[delindx];
if (delay > 0) OSY_SLEEP(delay,1);
}
