/* @(#)ididrv.c 17.1.1.1 (ESO-DMD) 01/25/02 17:33:37 */ /*=========================================================================== Copyright (C) 1995 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 ===========================================================================*/ /* @(#)ididrv.c 17.1.1.1 (OAA-ASTRONET) 01/25/02 17:33:37 */ /* * HEADER : ididrv.c - Vers 3.6.002 - Mar 1994 - L. Fini, OAA * - Vers 3.6.001 - Sep 1993 - L. Fini, OAA * - Vers 3.6.000 - Oct 1991 - L. Fini, OAA * * 891024: fix bug within AGLCUIDI KB * 891030: modify more KB * 891206: modify for correct colors F.Tribioli * 900105: use IIDQDC to get graphics channel no. KB * 901108: incorporate Midas-unit into graphics device name KB * 911029: Support for named colors and background color settings added (LF) * Upgraded to version 36 (LF). * Support for selecting Xor write mode added. LF * 920117: update test of status after IIDOPN_C call KB * 920305: do not use IICINC because it overrides previous cursor shapes KB * 930914: Support for different line widths added LF * * AGL device driver for a Midas IDI server * * This driver uses standard IDI calls to send data to an already open * IDI window. * * NB: This driver is based on a number of assumptions about the * way a display is used which will likely function only * with Midas implementations of IDI. * * In particular it assumes that a display has been created via a * proper Midas command, before the driver tries to access to it. * * The compilation of this module assumes a standard setting * of Midas dirctory tree * * .VERSION * * 010530 last modif * */ #include #include #include #include #include /* * The following entry points are defined: * * Function Entry point * * Initialize AGLINIDI * Cursor en. AGLCUIDI * Erase AGLERIDI * Escape AGLESIDI * Draw AGLPLIDI * Finish AGLTEIDI * Flush buff. AGLSEIDI */ #define N_DISPLAYS 4 /* Number of concurrent displays */ #define NO_DISPLAY (-1) #define TRUE 1 #define FALSE 0 #define PIXXLEN 0.030 /* We actually don't know the real value */ #define PIXYLEN 0.030 /* We actually don't know the real value */ #define VERSCODE 36 /* Declare driver version */ #define IDINWIDTH 9 #define IDIFLAGS INTERACTIVE|ERASEIT|SEPALPHA|SETBACKGR #define IDISOLID 1 /* Solid line selection */ #define CHARMULT 1.0 #define IDIBLACK 1 #define IDIRED 2 #define IDIGREEN 3 #define IDIBLUE 4 #define IDIYELLOW 5 #define IDIMAGENTA 6 #define IDICYAN 7 #define IDIWHITE 0 #define CVTX(c) ((int)((double)(c)*IdiFcx[idix]+0.5)); #define CVTY(c) ((int)((double)(c)*IdiFcy[idix]+0.5)); #define INVCVTX(c) ((double)(c)*IdiXfc[idix]); #define INVCVTY(c) ((double)(c)*IdiYfc[idix]); static int IdiId[N_DISPLAYS] = { NO_DISPLAY, NO_DISPLAY, NO_DISPLAY, NO_DISPLAY }; static int IdiDpth[N_DISPLAYS]; static int IdiNcol[N_DISPLAYS]; static int IdiXpix[N_DISPLAYS]; static int IdiYpix[N_DISPLAYS]; static int IdiClr[N_DISPLAYS]; static int IdiWdt[N_DISPLAYS]; static int IdiWrMod[N_DISPLAYS]; static int memid; static int ColorTbl[8] = { /* Color remapping table */ 2, /* 0 : White */ 1, /* 1 : Black */ 3, /* 2 : Red */ 4, /* 3 : Green */ 5, /* 4 : Blue */ 6, /* 5 : Yellow */ 7, /* 6 : Magenta */ 8 }; /* 7 : Cyan */ /* Black and White swapped for using */ /* White background */ static double IdiFcx[N_DISPLAYS]; static double IdiFcy[N_DISPLAYS]; static double IdiXfc[N_DISPLAYS]; static double IdiYfc[N_DISPLAYS]; void AGLCUIDI (AGLDVCOM) /* Read virtual cursor position */ struct bufcom *AGLDVCOM; { int idid,idix,stat; int ixx,iyy; char keycode; int mem=(-1); /* Display coordinates */ int ncurs, trgstat[32]; int pixval=0; idix = CHANNEL; idid = IdiId[idix]; /* was missing ... KB */ ncurs=IBUFFR(1); if(ncurs>0) ncurs=0; ixx = CVTX(RBUFFR(0)); /* Convert cursor coordinates */ iyy = CVTY(RBUFFR(1)); if (ncurs == 0) { /* first we just try to set the cursor coordinates */ stat = IICWCP_C(idid,mem,ncurs,ixx,iyy); /* Preset cursor position */ if (stat == CURNOTDEF) /* if not cursor defined, */ { stat = IICINC_C(idid,mem,0,0,0,ixx,iyy); /* also init cursor and */ stat = IICWCP_C(idid,mem,ncurs,ixx,iyy); /* set position again */ } if (stat == II_SUCCESS) stat = IICSCV_C(idid,ncurs,TRUE); /* Display the cursor */ if (stat != II_SUCCESS) { /* Error */ ERRCODE = DEVOPNSEV; return; } } if(ncurs==0) stat=IIIENI_C(idid,II_LOC,0,II_CURSOR, /* Bind cursor to mouse */ 0,II_MOVE,0); stat=IIIENI_C(idid,II_TRG, 0, /* Raise flag 0 */ 0, /* Object 0: no visible effect */ 0, /* Obj id 0 */ 0, /* Operation: appl. specific */ 0 ); /* Bind to trigger 0 */ stat=IIIENI_C(idid,II_TRG, 1, /* Raise flag 1 */ 0, /* Object 0: no visible effect */ 0, /* Obj id 0 */ 0, /* Operation: appl. specific */ 0 ); /* Bind to trigger 0 */ stat=IIIENI_C(idid,II_TRG, 2, /* Raise flag 2 */ 0, /* Object 0: no visible effect */ 0, /* Obj id 0 */ 0, /* Operation: appl. specific */ 0 ); /* Bind to trigger 0 */ stat=IIIENI_C(idid,II_EVLC, 3, /* Raise flag 3 */ 0, /* Object 0: no visible effect */ 0, /* Obj id 0 */ 0, /* Operation: appl. specific */ 0 ); /* Bind to trigger 0 */ do { stat=IIIEIW_C(idid,trgstat); /* loop on the events */ } while( (trgstat[1]==0)&& (trgstat[2]==0)&& (trgstat[3]==0)&& (trgstat[0]==0) ); if(trgstat[0] != 0) keycode = ' '; else if ((trgstat[1] != 0) || (trgstat[2] != 0)) /* Enter/Execute button */ keycode = 1; else { char cbuf[4]; stat=IIIGCE_C(idid,0,cbuf); keycode= *cbuf; } if(ncurs==0) { stat=IICRCP_C(idid,mem,0,&ixx,&iyy,&mem); RBUFFR(0)=INVCVTX(ixx); /* Convert back cursor coordinates */ RBUFFR(1)=INVCVTY(iyy); stat=IICSCV_C(idid,0,FALSE); /* Cancel the cursor */ } stat=IIISTI_C(idid); /* stop the interaction */ IBUFFR(1)=keycode; IBUFFR(2)=pixval; } void AGLINIDI (AGLDVCOM) /* Initialize */ struct bufcom *AGLDVCOM; /* This entry point will perform all */ /* the required initialization for */ /* the use of an IDI display as an */ /* AGL graphic device. */ { int idid,idix,stat; char *pt, cbuf[12], midunit[4]; int mem=0; ERRCODE=AGLNOERR; switch(IBUFFR(0)) { int i,itts,nomem,confmode; double xleng,yleng; case 0: /* device hardware initialization */ /* This function will attach to an existing */ /* display for subsequent operations. Up to */ /* N_DISPLAYS may be concurrently active */ pt=CHARBUF+strlen(CHARBUF)+1; /* Skip to display name */ /* build complete name "sxwXYmg" from */ /* "sxwmg" (m=0,1,2,3) */ cbuf[0] = *pt++; /* s */ cbuf[1] = *pt++; /* x */ cbuf[2] = *pt++; /* w */ OSY_GETSYMB("DAZUNIT",midunit,4); cbuf[3] = midunit[0]; /* X */ cbuf[4] = midunit[1]; /* Y */ cbuf[5] = *pt++; /* m */ cbuf[6] = *pt; /* g */ cbuf[7] = '\0'; AG_DMSG("Opening display:",cbuf); idix=(-1); for(i=0; i IdiNcol[CHANNEL]) IBUFFR(1) = IdiNcol[CHANNEL]; IdiClr[CHANNEL] = ColorTbl[IBUFFR(1)]; break; case 3: /* set line style */ break; /* Not used since AGL 3.3 */ case 4: /* set line width */ /* Line width is obtained by using the line */ /* style parameter of IIGPLY */ /* lstyl%10 will maintain the original mean- */ /* ing of line style selector */ /* lstyl/10 will select a line width with 0 */ /* being the only one currently used. */ IdiWdt[CHANNEL] = ((IBUFFR(1) < 0) ? 0 : IBUFFR(1))*10; break; case 5: switch(*CHARBUF) { default: case 's': case 'S': /* Only direct write and XOR supprted */ IdiWrMod[CHANNEL] = 0; break; case 'x': case 'X': IdiWrMod[CHANNEL] = 10; break; } break; case 6: { /* Coordinate roundoff */ int ixx,iyy; idix = CHANNEL; ixx = CVTX(RBUFFR(0)); iyy = CVTY(RBUFFR(1)); RBUFFR(0)=INVCVTX(ixx); RBUFFR(1)=INVCVTY(iyy); } break; default: break; } } void AGLERIDI (AGLDVCOM) /* Erase screen */ struct bufcom *AGLDVCOM; { int stat,idid,mem; int color=IBUFFR(0); idid = IdiId[CHANNEL]; if ((color>=IdiNcol[CHANNEL]) || (color<0)) color = IDIWHITE; ERRCODE = AGLNOERR; mem=memid; stat=IIMCMY_C (idid,&mem,1,ColorTbl[color]); if(stat!=II_SUCCESS) ERRCODE=DEVIOSEV; /* Access error */ } void AGLESIDI (AGLDVCOM) /* Escape function */ struct bufcom *AGLDVCOM; { ERRCODE = UNSFEATINF; } void AGLSEIDI (AGLDVCOM) struct bufcom *AGLDVCOM; /* Actual flushing of the buffer is */ { /* not performed. It is left to IDI */ int idix=CHANNEL; ERRCODE=AGLNOERR; } void AGLTEIDI (AGLDVCOM) /* Terminate */ struct bufcom *AGLDVCOM; { int stat,idid,idix; ERRCODE=AGLNOERR; idix=CHANNEL; idid=IdiId[idix]; stat=IIDCLO_C(idid); /* Close the display */ IdiId[idix]=NO_DISPLAY; /* Free the display slot */ if(stat!=II_SUCCESS) ERRCODE=DEVIOSEV; CHANNEL = (-1); } void AGLPLIDI (AGLDVCOM) /* Draw to next point */ struct bufcom *AGLDVCOM; { int i,n,idid; int idix; int lxx[400],lyy[400]; /* AGL Driver interface guarantees */ /* that 400 is enough */ float *vectx, *vecty; ERRCODE=AGLNOERR; idix=CHANNEL; idid = IdiId[idix]; n = NPOINTS; if(n>1) { if (n > 400) { (void) printf("AGL - ididrv: NPOINT = %d, truncated to 400\n",n); n = 400; } vectx = VECTX; vecty = VECTY; for(i=0;i