/* @(#)pco.c 17.1.1.1 (ESO-DMD) 01/25/02 17:35:35 */ /*=========================================================================== 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 ===========================================================================*/ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COPYRIGHT (c) 1993 European Southern Observatory .IDENTifer PCO .PURPOSE Takes care of opening and closing graphics devices .AUTHOR R.M. van Hees IPG-ESO Garching .KEYWORDS High level plot interface .LANGUAGE C .COMMENTS holds PCOPEN and PCCLOS .ENVIRONment MIDAS and AGL #include Prototypes for AGL application programs #include Symbols used by the OS interfaces #include Symbols used by the PLT interfaces #include Prototypes for MIDAS interfaces .VERSION 1.0 23-Sep-1993 FORTRAN --> C RvH 010905 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 #include #include #include #include #include #include /* * define some macros and constants */ #include #include #undef FATAL #define FATAL 1 /* error status FATAL */ #define MAXDEV 10 /* maximum number of different devices */ #define MAXLEN 80 /* maximum length of device name */ /* The routine PCOPEN makes use of several static functions. * They are used according to the following scheme: * * graphic display PCOPEN image display * | * PCDEV * | * <-------- ----------> * GRPCLP DISCLP * | * WC2PIX * | * | GETFRAME * PCSET * | * PCTSET * | * PCWND */ /* * definition of struct dev, containing device name and AGL ID-number */ struct dev { char name[21]; int id; }; /* */ /*++++++++++++++++++++++++++++ .IDENTifer PCDEV .PURPOSE get logical device name for current graphics window on both workstations and terminals input: char *kname: type of device output: char *lname: logical name of device .RETURNS .COMMENTS The length of the file AGL3CONFIG:agldevs.dat, also defines the number of supported graphics devices. This number should consist with the number of devices declared in the file PLTDEV.INC static function also defined in low level routine GETDEV ------------------------------*/ #ifdef __STDC__ static int PCDEV( char *kname, char *lname ) #else static int PCDEV( kname, lname ) char *kname, *lname; #endif { int fid, found; char devnam[84], *strtest; char *pldev = "AGL3CONFIG:agldevs.dat", *err_opn = "*** FATAL: PCDEV, Cannot open file with device definitions"; /* get rid of trailing blanks */ (void) strtok( kname, " " ); CGN_LOWSTR( kname ); /* read from AGLDEVS.dat */ if ( (fid = CGN_OPEN( pldev, READ )) == -1 ) SCETER( 1, err_opn ); /* keyword conversion or user input conversion */ if ( strncmp( kname+1, "_", 1 ) == 0 ) strtest = kname+2; /*full device name*/ else strtest = kname; /*normal device name*/ found = FALSE; while ( ! found && ( osaread( fid, devnam, MAXLEN )) >= 0 ) { if ( ! (*devnam == '#') ) { if ( ! strncmp( devnam, "unknown", 7 ) ) { (void) strcpy( lname, "unknown" ); found = TRUE; } else { (void) strtok( devnam, ":"); if ( strcmp( strtest, devnam ) == 0 ) { (void) strcpy( lname, strtest ); found = TRUE; } } } } (void) osaclose(fid); if ( found == FALSE ) { SCTPUT( "*** FATAL: PCDEV, Cannot find device definition" ); return FATAL; } else return ERR_NORMAL; } /* */ /*+++++++++++++++++++++++++++++++ .IDENTifer GRPCLP .PURPOSE find and write viewport CLIP values, on graphics display input: int plmode : plot mode char *device: name of plotting device output: float *clpl : clip limits .COMMENTS static function -------------------------------*/ #ifdef __STDC__ static void GRPCLP( int plmode, char *device, float *clpl ) #else static void GRPCLP( plmode, device, clpl ) char *device; int plmode; float *clpl; #endif { int actvals, xy, qdszy[2], knul, unit ; float aspect, xmxcl, maxcl[PLDIM2], devmm[PLDIM2], dval[PLDIM2], frmwc[PLDIM2], frmcl[PLDIM2], frmmm[PLDIM2], offset[PLDIM2], offusr[PLDIM2], scale[PLDIM3], scusr[PLDIM2], wndl[4]; char frame[5], cmnd[21], text[81], *offcoo[2], *scacoo[2], *errmmoff[PLDIM2], *errscoff[PLDIM2], *errnooff[PLDIM2], *errmmsca[PLDIM2], *errscsca[PLDIM2], *errnosca[PLDIM2], *errsiz[PLDIM2]; char *errtrm = "*** FATAL: (GRPCLP) terminal unknown to system", *errmin = " smallest possible scale:%13.6g units/mm", *errlarge = " largest possible size: %6.1f mm"; errmmoff[0] = "*** FATAL: maximum offset in x: %6.1f mm"; errmmoff[1] = "*** FATAL: maximum offset in y: %6.1f mm"; errscoff[0] = "*** FATAL: maximum offset in x: %6d screen pixels"; errscoff[1] = "*** FATAL: maximum offset in y: %6d screen pixels"; errnooff[0] = "*** FATAL: norm. offset in x must be between 0 and 1"; errnooff[1] = "*** FATAL: norm. offset in y must be between 0 and 1"; errmmsca[0] = "*** FATAL: maximum axis size in x: %6.1f mm"; errmmsca[1] = "*** FATAL: maximum axis size in y: %6.1f mm"; errscsca[0] = "*** FATAL: maximum axis size in x: %6d screen pixels"; errscsca[1] = "*** FATAL: maximum axis size in y: %6d screen pixels"; errnosca[0] = "*** FATAL: norm.axis size in x must be between 0 and 1"; errnosca[1] = "*** FATAL: norm.axis size in y must be between 0 and 1"; errsiz[0] = "*** FATAL: plot too large in x direction"; errsiz[1] = "*** FATAL: plot too large in y direction"; PCKRDR( "XWNDL", 4, &actvals, wndl ); frmwc[0] = (float) fabs( *(wndl+1) - *wndl ); PCKRDR( "YWNDL", 4, &actvals, wndl ); frmwc[1] = (float) fabs( *(wndl+1) - *wndl ); for ( xy = 0; xy < PLDIM2; xy++ ) offcoo[xy] = osmmget(5); for ( xy = 0; xy < PLDIM2; xy++ ) scacoo[xy] = osmmget(5); /* * get terminal characteristics, if failed exit */ if ( ( AG_RGET( "ASPE", &aspect ) != 1 ) || ( AG_RGET( "DEVD", dval ) != 2 ) ) SCETER( 1, errtrm ); for ( xy = 0; xy < PLDIM2; xy++ ) devmm[xy] = 10 * dval[xy]; /* * determine scaling parameters */ (void) SCKGETC( "MID$CMND", 1, 20, &actvals, cmnd ); if ( plmode != 2 || strncmp( QUAL, "AXES", 4 ) == 0 ) { clpl[0] = 0.15; clpl[1] = 0.95; clpl[2] = 0.1; clpl[3] = 0.95; } else /* plot mode equals 2 */ { clpl[0] = 0.15; clpl[1] = 0.8; clpl[2] = 0.1; clpl[3] = 0.95; } /* * read the x and Y coordinate unit for x and y offset */ PCKRDR( "XOFF", 1, &actvals, offusr ); PCKRDR( "YOFF", 1, &actvals, offusr+1 ); PCKRDC( "CXOF", 4, &actvals, offcoo[0] ); PCKRDC( "CYOF", 4, &actvals, offcoo[1] ); PCKRDR( "OFFS", 2, &actvals, offset ); for ( xy = 0; xy < PLDIM2; xy++ ) /* * set offset in mm */ if ( strncmp( offcoo[xy], "MM", 2 ) == 0 ) { offset[xy] = MYMAX( offusr[xy], offset[xy] ); if ( offset[xy] + 999 > PLT_EPS ) { if ( offset[xy] > devmm[xy] ) { (void) sprintf( text, errmmoff[xy], devmm[xy] ); SCETER( 3, text); } else { if ( xy == FOR_X ) clpl[0] = offset[0] / devmm[0]; else clpl[2] = offset[1] / devmm[1]; } } } /* * set offset in screen coordinates */ else if ( strncmp( offcoo[xy], "SC", 2 ) == 0 ) { (void) SCKRDI( "IDIDEV", 32, 2, &actvals, qdszy, &unit, &knul); if ( offset[xy] > qdszy[xy] ) { (void) sprintf( text, errscoff[xy], qdszy[xy] ); SCETER( 3, text); } else { if ( xy == FOR_X ) clpl[0] = offset[0]/qdszy[0]; else clpl[2] = offset[1]/qdszy[1]; } } /* * set offset in normlized coordinates */ else if ( strncmp( offcoo[xy], "NO", 2 ) == 0 ) { if ( offset[xy] < 0.0 || offset[xy] > 1.0 ) { (void) sprintf( text, errnooff[xy]); SCETER( 3, text); } else { if ( xy == FOR_X ) clpl[0] = offset[0]; else clpl[2] = offset[1]; } } /* * else we assume mm offset */ else { offset[xy] = MYMAX( offusr[xy], offset[xy] ); if ( offset[xy] + 999 > PLT_EPS ) { if ( offset[xy] > devmm[xy] ) { (void) sprintf( text, errmmoff[xy], devmm[xy] ); SCETER( 3, text); } else { if ( xy == FOR_X ) clpl[0] = offset[0] / devmm[0]; else clpl[2] = offset[1] / devmm[1]; } } } /* * X and Y scaling and position: */ PCKRDC( "FRAME", 4, &actvals, frame ); PCKRDR( "XSCA", 1, &actvals, scusr ); PCKRDR( "YSCA", 1, &actvals, scusr+1 ); PCKRDC( "CXSC", 4, &actvals, scacoo[0] ); PCKRDC( "CYSC", 4, &actvals, scacoo[1] ); PCKRDR( "SCAL", 3, &actvals, scale ); for ( xy = 0; xy < PLDIM2; xy++ ) /* * scale via command line or preset */ {if ( fabs( scale[xy] ) > PLT_EPS ) { if ( ( strncmp( scacoo[xy], "MM", 2 ) == 0 ) || ( scale[xy] < 0.0 ) ) /* scale in mm. or in neg. numbers*/ { if ( fabs(scale[xy]) > devmm[xy] ) { (void) sprintf( text, errmmsca[xy], devmm[xy] ); SCETER( 3, text); } else frmmm[xy] = (float) fabs( scale[xy]); /*viewport size*/ } else if ( strncmp( scacoo[xy], "SC", 2 ) == 0 ) /*screen. coord.*/ { (void) SCKRDI( "IDIDEV", 32, 2, &actvals, qdszy, &unit, &knul); if ( scale[xy] > qdszy[xy] ) { (void) sprintf( text, errscsca[xy], qdszy[xy] ); SCETER( 3, text); } else frmmm[xy] = scale[xy]/qdszy[xy]*devmm[xy]; /*viewport size*/ } else if ( strncmp( scacoo[xy], "NO", 2 ) == 0 ) /*norm.coord*/ { if ( scale[xy] < 0.0 || scale[xy] > 1.0 ) { (void) sprintf( text, errnosca[xy]); SCETER( 3, text); } else frmmm[xy] = scale[xy]*devmm[xy]; } else /*scale in wo per mm*/ frmmm[xy] = fabs( frmwc[xy]/scale[xy] ); frmcl[xy] = (float) fabs(frmmm[xy]/devmm[xy]); } /* *scale via PLRGRAP */ else if ( fabs( scusr[xy]) > PLT_EPS ) { if ( scusr[xy] < 0.0 ) /*scale in mm*/ frmmm[xy] = (float) fabs( scusr[xy] ); /*viewport size*/ else frmmm[xy] = frmwc[xy] / scusr[xy]; /*scale in wo/mm*/ frmcl[xy] = (float) fabs( frmmm[xy] / devmm[xy]); /*norm.view size*/ } else /*no scale given; use default*/ { if ( xy == FOR_X ) { if ( strncmp( frame, "SQ", 2 ) == 0 ) { xmxcl = clpl[1]; clpl[1] = clpl[0] + aspect* (clpl[3] - clpl[2]); if ( clpl[1] > xmxcl ) { clpl[1] = xmxcl; clpl[2] = clpl[3]-(clpl[1]-clpl[0])/aspect; } } frmcl[xy] = clpl[1] - clpl[0]; frmmm[xy] = devmm[xy] * frmcl[xy]; } else { frmcl[xy] = clpl[3] - clpl[2]; frmmm[xy] = devmm[xy] * frmcl[xy]; } } if ( xy == FOR_X ) maxcl[xy] = clpl[1] - clpl[0]; else maxcl[xy] = clpl[3] - clpl[2]; /* * check the size */ if ( frmcl[xy] > maxcl[xy]+0.01 && strncmp( device, "VERSATEC", 8 ) != 0 ) { if ( scale[xy] < 0.0 ) (void) sprintf( text, errlarge, maxcl[xy] * devmm[xy] ); else (void) sprintf( text, errmin, frmwc[xy]/( maxcl[xy] * devmm[xy])); SCTPUT( errsiz[xy] ); SCETER( 1, text ); } else /* size is ok */ { if ( xy == FOR_X ) clpl[1] = clpl[0] + frmcl[xy]; else { if ( fabs( offset[1] + 999 ) > PLT_EPS ) clpl[3] = clpl[2] + frmcl[xy]; else clpl[2] = clpl[3] - frmcl[xy]; } } } for ( xy = 0; xy < PLDIM2; xy++ ) scale[xy] = (float) fabs( frmwc[xy]/frmmm[xy]); PCKWRR( "SCAL", 2, scale ); /*store scale*/ PCKWRR( "CLPL", 4, clpl ); /*store clip values*/ for ( xy = 0; xy < PLDIM2; xy++ ) osmmfree(offcoo[xy]); for ( xy = 0; xy < PLDIM2; xy++ ) osmmfree(scacoo[xy]); return; } /* */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .IDENTifer GETFRAME .PURPOSE Get name of frame displayed on current active display channel output: char *frame .RETURNS 0 = o.k., else nothing loaded into channel .COMMENTS static function, also defined in PLOTAXES ------------------------------------------------------------*/ #ifdef __STDC__ static int GETFRAME( char *frame ) #else static int GETFRAME( frame ) char *frame; #endif { int iav; /* get the name of the frame loaded in the current image display */ (void) SCKGETC("IDIMEMC",1,80,&iav,frame); if (truelen(frame) == 0) return 1; else return ERR_NORMAL; } /* */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .IDENTifer WC2PIX .PURPOSE converts world coordinates to screen pixels input: float *wcpix: pixel in world coordimates output: float *scpix: pixel in screen coordinates .COMMENTS static function ------------------------------------------------------------*/ #ifdef __STDC__ static void WC2PIX( float *wcpix, float *scpix ) #else static void WC2PIX( wcpix, scpix ) float *wcpix, *scpix; #endif { int iac, imf, knul, qdszy, dzmemi[13], unit; float cx, cy, imgpix[2]; double start[2], step[2]; char frame[61]; char *err_fram = "*** FATAL: no frame loaded in the display channel"; /* * get the name of the loaded frame and it's characteristics */ if ( GETFRAME( frame ) != 0 ) SCETER( 1, err_fram ); (void) SCFOPN( frame, D_R4_FORMAT, 0, F_IMA_TYPE, &imf ); (void) SCDRDD( imf, "START", 1, PLDIM2, &iac, start, &unit, &knul ); (void) SCDRDD( imf, "STEP" , 1, PLDIM2, &iac, step , &unit, &knul ); (void) SCFCLO( imf ); /* * get display parameters */ (void) SCKRDI( "IDIMEMI", 1, 13, &iac, dzmemi, &unit, &knul); (void) SCKRDI( "IDIDEV", 3, 1, &iac, &qdszy, &unit, &knul); /* * calculate image pixel */ imgpix[0] = (float) ((wcpix[0] - start[0])/step[0] + 1); imgpix[1] = (float) ((wcpix[1] - start[1])/step[1] + 1); /* * take care of one real pixel + scaling */ if ( SCALX < 0 ) cx = - (imgpix[0] - (float) SFPX ) * (float) SCALX; else cx = (imgpix[0] - (float) SFPX ) / (float) SCALX; cx += SSPX; if ( SCALY < 0 ) cy = - (imgpix[1] - (float) SFPY ) * (float) SCALY; else cy = (imgpix[1] - (float) SFPY ) / (float) SCALY; cy += SSPY; scpix[0] = ( cx - SCROLX ) * ZOOMX; scpix[1] = ( cy - SCROLY ) * ZOOMY + qdszy - 1; return; } /* */ /*++++++++++++++++++++++++++++++ .IDENTifer DISCLP .PURPOSE find and write viewport CLIP values, on image display output: float *clpl : clip limits .COMMENTS static function --------------------------------*/ #ifdef __STDC__ static void DISCLP( float *clpl ) #else static void DISCLP( clpl ) float *clpl; #endif { int actvals, imf, knul, unit, xy, scale[PLDIM2], scrpx[PLDIM2]; float frmmm[PLDIM2], frmpx[PLDIM2], offmm[PLDIM2], wcpix1[PLDIM2], wndl[8], scpix1[PLDIM2], scpix2[PLDIM2], wcpix2[PLDIM2]; double step[2]; char frame[60]; char *err_fram = "*** FATAL: no frame loaded in the display channel"; /* * get the name of the loaded frame and it's characteristics */ if ( GETFRAME( frame ) != 0 ) SCETER( 1, err_fram ); (void) SCFOPN( frame, D_R4_FORMAT, 0, F_IMA_TYPE, &imf ); (void) SCDRDD( imf, "STEP" , 1, PLDIM2, &actvals, step , &unit, &knul ); (void) SCFCLO( imf ); /* * get display parameters */ (void) SCKRDI( "IDIDEV", 2, 2, &actvals, scrpx, &unit, &knul); (void) SCKRDI( "IDIMEMI", 8, 2, &actvals, scale, &unit, &knul); /* * do pixel convertion */ PCKRDR( "XWNDL", 2, &actvals, wndl ); PCKRDR( "YWNDL", 2, &actvals, wndl+2 ); /* wcpix1[0] = (float) (wndl[0] + step[0]/2.0); wcpix1[1] = (float) (wndl[2] + step[1]/2.0); wcpix2[0] = (float) (wndl[1] + step[0]/2.0); wcpix2[1] = (float) (wndl[3] + step[1]/2.0); */ wcpix1[0] = (float) (wndl[0]); wcpix1[1] = (float) (wndl[2]); wcpix2[0] = (float) (wndl[1]); wcpix2[1] = (float) (wndl[3]); WC2PIX( wcpix1, scpix1 ); WC2PIX( wcpix2, scpix2 ); /* * make the box 1/2 pixel larger */ if (scale[0] < 0.0) { scpix1[0] -= 0.5 * scale[0]; scpix2[0] -= 0.5 * scale[0]; } if (scale[1] < 0.0) { scpix1[1] -= 0.5 * scale[1]; scpix2[1] -= 0.5 * scale[1]; } /* * get terminal characteristics */ for ( xy = 0; xy < PLDIM2; xy++ ) { frmpx[xy] = (float) fabs((double) scpix2[xy] - scpix1[xy] ) + 1; frmmm[xy] = frmpx[xy] / scrpx[xy]; offmm[xy] = scpix1[xy] / scrpx[xy]; } /* * set the clip coordinates */ clpl[0] = MYMAX( offmm[0], 0.0 ); clpl[1] = MYMIN( offmm[0] + (float) fabs((double) frmmm[0] ), 1.0 ); clpl[2] = MYMAX( offmm[1], 0.0 ); clpl[3] = MYMIN( offmm[1] + (float) fabs((double) frmmm[1] ), 1.0 ); PCKWRR( "CLPL", 4, clpl ); /*store clip values*/ } /* */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .IDENTifer PCWND .PURPOSE Set the plot window in world coordinates input: float *wcfram plot window limits in world coordinated .COMMENTS static function, also defined as low level plot interface ------------------------------------------------------------*/ #ifdef __STDC__ static void PCWND( float *wcfram ) #else static void PCWND( wcfram ) float *wcfram; #endif { float wndl[4]; /* * copy input array because we are going to change it */ wndl[0] = wcfram[0]; wndl[1] = wcfram[1]; wndl[2] = wcfram[4]; wndl[3] = wcfram[5]; /* * set the window */ if ( wcfram[3] <= -2.0 ) /* logarithmic x-axis*/ { wndl[0] = exp( wcfram[0] ); wndl[1] = exp( wcfram[1] ); } else if ( wcfram[3] < 0.0 ) { wndl[0] = pow( 10.0, wcfram[0] ); wndl[1] = pow( 10.0, wcfram[1] ); } if ( wcfram[7] <= -2.0 ) /* logarithmic y-axis*/ { wndl[2] = exp( wcfram[4] ); wndl[3] = exp( wcfram[5] ); } else if ( wcfram[7] < 0.0 ) { wndl[2] = pow( 10.0, wcfram[4] ); wndl[3] = pow( 10.0, wcfram[5] ); } /* *define window */ AG_WDEF( wndl[0], wndl[1], wndl[2], wndl[3] ); AG_SSET( "liny" ); AG_SSET( "linx" ); if ( wcfram[3] < 0 ) AG_SSET( "logx" ); if ( wcfram[7] < 0 ) AG_SSET( "logy" ); return; } /* */ /*++++++++++++++++++++++++++++++ .IDENTifer PCSET .PURPOSE does a complete setup of the plot parameters and AGL .COMMENTS static function -------------------------------*/ #ifdef __STDC__ static void PCSET( void ) #else static void PCSET() #endif { int actvals, color, font, ltype, lwidth, twidth, ncol; float wcfram[8]; char clmod[5], text[81]; /* * set character font */ PCKRDI( "FONT", 1, &actvals, &font ); (void) sprintf( text, "font=%1d", font ); AG_SSET( text ); /* * set line style */ PCKRDI( "LTYPE", 1, &actvals, <ype ); if ( ltype > 0 ) { (void) sprintf( text, "lstyl=%1d", ltype - 1 ); AG_SSET( text ); } /* * set line width */ PCKRDI( "LWIDTH", 1, &actvals, &lwidth ); (void) sprintf( text, "lwidt=%1d", lwidth - 1 ); AG_SSET( text ); /* * set line width for text */ PCKRDI( "TWIDTH", 1, &actvals, &twidth ); (void) sprintf( text, "twidt=%1d", twidth ); AG_SSET( text ); /* * determine character and symbol sizes for the MIDAS layout */ PCTSET(); /* * set color */ (void) AG_IGET( "ncol", &ncol); PCKRDI( "COLOR", 1, &actvals, &color ); if ( ncol == 1 && color > 1 ) color = 1; (void) sprintf( text, "color=%1d", color ); AG_SSET( text ); /* * color mode */ PCKRDC( "COLMODE", 4, &actvals, clmod ); if ( strncmp( clmod, "X", 1 ) == 0 ) AG_SSET( "mode=Xor" ); else AG_SSET( "mode=Sub" ); /* * do a complete "manual" setting, which gives a default frame!! */ PCKRDR( "XWNDL", 4, &actvals, wcfram ); PCKRDR( "YWNDL", 4, &actvals, wcfram+FOR_Y ); PCWND( wcfram ); return; } /* */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .IDENTifier PCOPEN .PURPOSE Sets up the graphic device according to plot mode input: char *devnam: name of device to be activated char *plname: name of meta file int access : access mode: -1 = cursor, 1 = over plot, 0 = new plot. in/output: int *plmode: plot mode: 0 = no axis & no info, 1 = draw axes & some info, 2 = draw axes & full info, -1 take value from keyword PMODE .COMMENTS PCOPEN activates a given device, or the current (by MIDAS) defined device if no device name is given. A given device has to be present in the AGLDEVS.dat file. PCOPEN does not open or append to a meta file if PLNAME equals "NO"ne. If no name or a file name (without ".plt" extention) is given PCOPEN will open or append to a meta file (see access mode). Default for the name of the meta file is the name of the activated device extended with MIDAS session number with extention ".plt". PCOPEN reads the MIDAS graphics keywords, opens this device (on graphics or image display) according to the MIDAS settings. The coordinate box have to be defined BEFORE PCOPEN !!! Use the MIDAS routine PCKWRR, with parameters: XWNDL and YWNDL. ------------------------------------------------------------*/ void PCOPEN( devnam, plname, access, plmode ) char *devnam, *plname; int access, *plmode; { int actvals, amode, bcolor, iac, idev, meta, newdev, pmode; float ocount, rdef, clpl[4]; char *pntr, session[3], debug[5], erase[5], action[9], cmnd[21], device[21], dname[21], plmeta[81], text[81]; static int nrdev = 0; static struct dev devtbl[MAXDEV]; char *errpmode = "*** FATAL: PCOPEN, unknown plot mode ...", *errdev = "*** FATAL: PCOPEN, unknown or unavailable device", *errhlp = " use HELP [printers]", *errmxdev = "*** FATAL: PCOPEN, too many different devices opened (> 4)", *errplt = "*** FATAL: PCOPEN, no graphics device ==> No CURSOR", *errnopl = "*** FATAL: PCOPEN, no existing plot file to append", *errnoex = "*** FATAL: PCOPEN, no existing plot for graphics cursor"; /* * initialize device and meta-file name */ *device = *plmeta = '\0'; (void) strncat( device, devnam, 20 ); (void) strncat( plmeta, plname, 80 ); (void) SCKGETC( "MID$SESS", 11, 2, &iac, session ); PCKRDR( "OCOUNT", 1, &actvals, &ocount ); /* * Check plot mode */ if ( *plmode == -1 ) /* plmode = -1 => use PMODE */ { PCKRDI( "PMODE", 1, &actvals, &pmode ); *plmode = pmode; } /* * and check its value */ if ( *plmode < 0 && *plmode > 2 ) SCETER( 2, errpmode ); /* * debug mode */ PCKRDC( "DEBUG", 4, &actvals, debug ); if ( strncmp( debug, "ON", 2 ) == 0 ) AG_SSET( "msgw;debu=1;errf=aglerr.log" ); else AG_SSET( "msgn;debu=0" ); /* * get device name */ if ( truelen( device ) == 0 ) /* a device name given? */ (void) SCKGETC( "MID$PLOT", 1, 20, &iac, device ); if ( PCDEV( device, dname ) != ERR_NORMAL || strncmp( dname, "unknown", 7 ) == 0 ) { SCTPUT( errdev ); SCETER( 3, errhlp ); } newdev = TRUE; if ( nrdev == 0 ) /* are there devices opened? */ { nrdev = 1; idev = 0; (void) strcpy( devtbl[idev].name, dname ); } else { for ( idev = 0; idev < nrdev; idev++ ) if ( strcmp( dname, devtbl[idev].name ) == 0 ) break; if ( idev == nrdev ) /*new device*/ { if ( ++nrdev > MAXDEV ) SCETER( 4, errmxdev ); (void) strcpy( devtbl[idev].name, dname ); } else newdev = FALSE; } /* * set the access mode according to plot, overplot and cursor command */ (void) SCKGETC( "MID$CMND", 1, 20, &iac, cmnd ); if ( access == -1 ) /*reserved for cursor*/ { if ( strncmp( dname,"graph",5 ) != 0 && strncmp( dname,"image",5 ) != 0 ) SCETER( 4, errplt ); amode = -1; } else if ( access == 1 ) /*overplot command*/ { if ( strncmp( QUAL, "AX", 2 ) == 0 ) /*axes*/ amode = 2; else if ( strncmp( COMM, "LAB", 3 ) == 0 ) /*label graphics*/ amode = 3; else /*data*/ amode = 4; } else /*plot command*/ { PCKRDC( "CLEAR", 4, &actvals, erase ); if ( strncmp( QUAL, "AX", 2 ) == 0 ) /*axes*/ { if ( strncmp( erase, "ON", 2 ) == 0 || ocount < 1) amode = 1; /*erase*/ else amode = 2; /*no erase*/ } else /*data plotting*/ { if ( strncmp( erase, "ON", 2 ) == 0 || ocount < 1) amode = 5; /*erase*/ else amode = 6; /*no erase*/ } } /* * get the plot file */ meta = FALSE; /* default: no meta file*/ if ( amode > 0 ) { if ( strncmp( plmeta, "no", 2 ) != 0 ) { meta = TRUE; if ( amode == 1 || amode == 5 ) /*new plotfile*/ { if ( truelen( plmeta ) == 0 ) /*called with no name*/ { (void) strcpy( plmeta, dname ); if ( (pntr = strchr( plmeta, '.' )) == NULL ) (void) strcat( plmeta, session ); else (void) strcpy( pntr, session ); } if ( (pntr = strchr( plmeta, '.' )) == NULL ) (void) strcat( plmeta, ".plt" ); else (void) strcpy( pntr, ".plt" ); PCKWRC( "PLNAM", plmeta ); ocount = 0.0; } else /*overplot mode*/ { PCKRDC( "PLNAM", 80, &actvals, plmeta ); if ( ocount == 0.0 ) SCETER( 5, errnopl ); } } } /* * define default viewport setting */ clpl[0] = clpl[2] = 0.0; clpl[1] = clpl[3] = 1.0; /* * open viewport for device */ switch (amode) { case 1: /*PLOT AXES*/ case 5: /*PLOT DATA erase*/ (void) strcat( dname, ":" ); break; case -1: /*GET GCURSOR*/ if ( ocount == 0.0 ) SCETER( 6, errnoex ); /*none existing*/ PCKRDR( "CLPL", 4, &actvals, clpl ); case 3: /*LABEL GRAPH*/ if ( ocount == 0.0 ) break; case 2: /*OVER AXES*/ case 4: /*OVER DATA*/ case 6: /*PLOT DATA no-erase*/ (void) strcat( dname, "/n:" ); (void) strcat( plmeta, "/a" ); break; } if ( newdev ) devtbl[idev].id = AG_VDEF( dname, clpl[0], clpl[1], clpl[2], clpl[3], 0., 0. ); else AG_VSEL( devtbl[idev].id ); if ( meta ) { AG_MCLS(); /* close the still open meta file */ AG_MOPN( plmeta ); /* and open a new */ } if ( amode > 0 ) { if ( amode == 3 || amode == 4 ) PCKRDR( "CLPL", 4, &actvals, clpl ); else { if ( ! newdev ) { PCKWRR( "SCALES", 0, &rdef ); PCKWRR( "OFFSET", 0, &rdef ); } (void) SCKGETC( "ACTION", 1, 4, &iac, action ); if ( strncmp( action, "DISP", 4 ) == 0 ) DISCLP( clpl ); else GRPCLP( *plmode, device, clpl ); } ocount += 1; PCKWRR( "OCOUNT", 1, &ocount ); } else PCKRDR( "CLPL", 4, &actvals, clpl ); AG_CDEF( clpl[0], clpl[1], clpl[2], clpl[3] ); if ( amode == 1 || amode == 5 ) { PCKRDI( "BCOLOR", 1, &actvals, &bcolor ); (void) sprintf( text, "back=%1d", bcolor ); AG_SSET( text ); } PCSET(); return; } /* */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .IDENTifer PCCLOS .PURPOSE Close plot file, and terminate graphic operations ------------------------------------------------------------*/ void PCCLOS() { /* * terminate orderly the AGL operations */ AG_CLS(); return; }