Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

afni_plugout.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002    Major portions of this software are copyrighted by the Medical College
00003    of Wisconsin, 1994-2000, and are released under the Gnu General Public
00004    License, Version 2.  See the file README.Copyright for details.
00005 ******************************************************************************/
00006 
00007 #undef MAIN
00008 #include "afni.h"
00009 #include "afni_plugout.h"
00010 
00011 #ifdef ALLOW_PLUGINS
00012 
00013 /** global data for plugouts **/
00014 
00015 static IOCHAN * ioc_control[NUM_TCP_CONTROL] ;  /* 21 Nov 2001: now an array */
00016 static char *   ioc_conname[NUM_TCP_CONTROL] ;
00017 
00018 static int            npout = 0 ;       /* number of plugouts allocated */
00019 static PLUGOUT_spec ** pout = NULL ;    /* malloc-ed array of plugouts */
00020 
00021 #undef RETRY
00022 
00023 static int verbose = 0 ;  /* 28 April 1998 */
00024 
00025 static int started = 0 ;  /* 07 Nov 2001 */
00026 
00027 /*-----------------------------------------------------------------------*/
00028 
00029 int AFNI_have_plugouts( void ){ return started ; }  /* 07 Nov 2001 */
00030 
00031 /*-----------------------------------------------------------------------
00032   Initialize plugouts: setup the work process
00033 -------------------------------------------------------------------------*/
00034 
00035 void AFNI_init_plugouts( void )
00036 {
00037    int cc ;
00038 
00039 ENTRY("AFNI_init_plugouts") ;
00040 
00041    if( started ) EXRETURN ;  /* 07 Nov 2001 */
00042 
00043    PLUTO_register_workproc( AFNI_plugout_workproc , NULL ) ;
00044    atexit( AFNI_plugout_exit ) ;
00045 
00046    verbose = (GLOBAL_argopt.plugout_code & 1) != 0 ;
00047 
00048    for( cc=0 ; cc < NUM_TCP_CONTROL ; cc++ ){       /* 21 Nov 2001: */
00049       ioc_control[cc] = NULL ;                      /* initialize control */
00050       ioc_conname[cc] = AFMALL(char, 32) ;          /* sockets and names  */
00051       sprintf(ioc_conname[cc],"tcp:*:%d",BASE_TCP_CONTROL+cc) ;
00052    }
00053 
00054    started = 1 ; EXRETURN ;
00055 }
00056 
00057 /*-----------------------------------------------------------------------
00058   Routine executed at AFNI exit: shutdown all plugout IOCHANs.
00059 -------------------------------------------------------------------------*/
00060 
00061 void AFNI_plugout_exit( void )
00062 {
00063    int jj , cc ;
00064 
00065    for( cc=0 ; cc < NUM_TCP_CONTROL ; cc++ ){  /* close any open  */
00066       iochan_set_cutoff( ioc_control[cc] ) ;   /* control sockets */
00067       iochan_close     ( ioc_control[cc] ) ;
00068    }
00069 
00070    for( jj=0 ; jj < npout ; jj++ ){            /* close any plugouts */
00071       if( pout[jj] != NULL && pout[jj]->ioc != NULL ){
00072          iochan_set_cutoff( pout[jj]->ioc ) ;
00073          iochan_close     ( pout[jj]->ioc ) ;
00074          if( verbose )
00075             fprintf(stderr,"PO: atexit closed channel from plugout %s\n",
00076                     pout[jj]->po_name ) ;
00077       }
00078    }
00079    return ;
00080 }
00081 
00082 /*-----------------------------------------------------------------------
00083   Plugout workprocess: listen for incoming control connections.
00084   (If the return is True, that means don't call this workproc again.
00085    If the return is False, that means call this workproc again.......)
00086 -------------------------------------------------------------------------*/
00087 
00088 #define CONTROL_BUFSIZE (16*1024)
00089 
00090 Boolean AFNI_plugout_workproc( XtPointer elvis )
00091 {
00092    int jj , ngood , pcode , ii , opcount=0 , cc ;
00093    PLUGOUT_spec * pp ;
00094 
00095    /********************************************/
00096    /** start up non-listening control sockets **/
00097 
00098    for( cc=0 ; cc < NUM_TCP_CONTROL ; cc++ ){
00099 
00100      if( ioc_control[cc] == NULL ){  /* not open now, so open it */
00101 
00102         ioc_control[cc] = iochan_init( ioc_conname[cc] , "accept" ) ;
00103 
00104 #ifdef RETRY
00105         if( ioc_control[cc] == NULL ){
00106            if( verbose )
00107               fprintf(stderr,"PO: waiting to listen on control channel") ;
00108            for( ii=0 ; ii < 10 ; ii++ ){
00109               if( verbose ) fprintf(stderr,".") ;
00110               iochan_sleep(VLONG_DELAY) ;  /* wait a bit, try again */
00111               ioc_control[cc] = iochan_init( ioc_conname[cc] , "accept" ) ;
00112               if( ioc_control[cc] != NULL ) break ;
00113            }
00114            if( verbose ) fprintf(stderr,"\n") ;
00115         }
00116 #endif /* RETRY */
00117 
00118         if( ioc_control[cc] != NULL ) opcount++ ;
00119      }
00120    }
00121 
00122    /****************************************/
00123    /** see if any control socket is ready **/
00124 
00125    for( cc=0 ; cc < NUM_TCP_CONTROL ; cc++ ){
00126 
00127      if( ioc_control[cc] == NULL ) continue ; /* not listening */
00128 
00129      jj = iochan_goodcheck(ioc_control[cc],SHORT_DELAY) ;
00130 
00131      if( jj == 0 ) continue ; /* not ready */
00132 
00133      if( jj == 1 ){           /* someone connected to the control socket! */
00134         int   npobuf ;
00135         char * pobuf ;
00136 
00137         /** check if the connection is trustworthy **/
00138 
00139         fprintf(stderr,"PO: plugout connection from host %s\n",ioc_control[cc]->name) ;
00140 
00141         if( !TRUST_host(ioc_control[cc]->name) ){
00142           fprintf(stderr,"PO: untrusted host: %s -- connection denied\n" ,
00143                   ioc_control[cc]->name) ;
00144           iochan_set_cutoff(ioc_control[cc]) ; IOCHAN_CLOSE(ioc_control[cc]) ;
00145           continue ; /* skip to next control socket */
00146         }
00147 
00148         /** read all data possible from the control channel **/
00149 
00150         npobuf = 0 ;  /* number of bytes received so far */
00151         pobuf  = (char *) malloc( sizeof(char) * CONTROL_BUFSIZE ) ;
00152 
00153         while(1){
00154            jj = iochan_recv( ioc_control[cc] , pobuf+npobuf , CONTROL_BUFSIZE-npobuf ) ;
00155            if( jj < 1 ) break ;  /* stop if nothing more comes in */
00156            npobuf += jj ;
00157            if( npobuf >= CONTROL_BUFSIZE ){  /* stop if overflow */
00158               fprintf(stderr,"PO: control channel buffer overflow!\n") ;
00159               break ;
00160            }
00161            for( ii=0 ; ii < npobuf ; ii++ ) if( pobuf[ii] == '\0' ) break ;
00162            if( ii < npobuf ) break ;      /* stop if found a NUL character */
00163 
00164            iochan_sleep( SHORT_DELAY ) ;  /* wait for some more? */
00165         }
00166 
00167         if( npobuf < 1 ){
00168           fprintf(stderr,"PO: control channel sent no data!\n") ;
00169           iochan_set_cutoff(ioc_control[cc]) ; IOCHAN_CLOSE(ioc_control[cc]) ;
00170           free(pobuf) ;
00171           continue ;    /* skip to next control socket */
00172         }
00173 
00174         /** process the input and make a new connection to a plugout program **/
00175 
00176         pp = new_PLUGOUT_spec( npobuf , pobuf ) ;
00177 
00178         if( pp == NULL ){
00179           fprintf(stderr,"PO: can't create PLUGOUT_spec.  Input was:\n%s\n",pobuf) ;
00180           PO_ACK_BAD(ioc_control[cc]) ;
00181           iochan_sleep(LONG_DELAY) ;
00182           iochan_set_cutoff(ioc_control[cc]) ; IOCHAN_CLOSE(ioc_control[cc]) ;
00183           free(pobuf) ;
00184           continue ;    /* skip to next control socket */
00185         } else {
00186           if( pp->do_ack ) PO_ACK_OK(ioc_control[cc]) ;
00187           iochan_sleep(LONG_DELAY) ;
00188           iochan_set_cutoff(ioc_control[cc]) ; IOCHAN_CLOSE(ioc_control[cc]) ;
00189           fprintf(stderr,"PO: plugout connection name is %s\n",pp->po_name) ;
00190         }
00191 
00192         if( npout == 0 ){
00193           pout = (PLUGOUT_spec **) malloc( sizeof(PLUGOUT_spec *) ) ;
00194         } else {
00195           pout = (PLUGOUT_spec **) realloc( pout , sizeof(PLUGOUT_spec *)*(npout+1) ) ;
00196         }
00197         pout[npout++] = pp ;
00198         free(pobuf) ;
00199         opcount++ ;
00200 
00201      } else if( jj == -1 ){  /* something bad happend to control socket */
00202 
00203 #if 0
00204        if( verbose )
00205           fprintf(stderr,"PO: failure while listening to control channel!\n") ;
00206 #endif
00207 
00208        iochan_set_cutoff(ioc_control[cc]) ; IOCHAN_CLOSE(ioc_control[cc]) ;
00209        continue ;    /* skip to next control socket */
00210 
00211      }
00212    } /* end of loop over control sockets */
00213 
00214    /*****************************************************/
00215    /** see if any of the existing plugouts sent data,  **/
00216    /** or needs to have data sent to it.               **/
00217 
00218    ngood = 0 ;
00219    for( jj=0 ; jj < npout ; jj++ ){
00220       if( pout[jj] != NULL ){
00221          pcode = AFNI_process_plugout( pout[jj] ) ;
00222          if( pcode < 0 ) DESTROY_PLUGOUT( pout[jj] ) ;
00223          else            ngood++ ;
00224 
00225          if( pcode ) opcount++ ;
00226       }
00227    }
00228 
00229    /* if all plugouts are deceased, free their array */
00230 
00231    if( ngood == 0 && pout != NULL ){ npout = 0 ; free(pout) ; pout = NULL ; }
00232 
00233    /* if nothing happened, take a short nap */
00234 
00235    if( opcount == 0 ) iochan_sleep(LONG_DELAY) ;
00236    return(False) ;
00237 }
00238 
00239 /*------------------------------------------------------------------------
00240    Process a plugout.  Return codes are:
00241        0 = nothing happened
00242       -1 = a fatal error for this plugout --> close it down!
00243        1 = data was sent to plugout
00244        2 = data was received from plugout
00245    Receiving data from a plugout has higher priority than sending
00246    data to a plugout.  Both will not occur in the same cycle.
00247 --------------------------------------------------------------------------*/
00248 
00249 #define PO_BUFSIZE (64*1024)  /* 14 Nov 2001: expand from 16K to 64K */
00250 
00251 #define MAX_STR 1024   /* 21 Nov 2001 */
00252 
00253 int AFNI_process_plugout( PLUGOUT_spec * pp )
00254 {
00255    int ii , jj , npobuf , nend , retval=0 ;
00256    Three_D_View * im3d ;
00257    static char pobuf[PO_BUFSIZE+1] ; /* I/O buffer */
00258    static char oobuf[1024] ;
00259 
00260    int         nstr ;                /* 21 Nov 2001: number of substrings */
00261    static char *str[MAX_STR] ;       /* pointers to substrings from plugout */
00262    int ss , bb,aa  ;
00263    char *spt ;
00264 
00265    /** find the lowest numbered open controller **/
00266 
00267    for( ii=0 ; ii < MAX_CONTROLLERS ; ii++ ){
00268       im3d = GLOBAL_library.controllers[ii] ;
00269       if( IM3D_OPEN(im3d) ) break ;
00270    }
00271    if( ii == MAX_CONTROLLERS ) return(0) ;  /* nothing available?  weird */
00272 
00273    /** if the IOCHAN isn't ready yet, see if it has become ready **/
00274 
00275    if( ! pp->ioc_ready ){
00276       ii = iochan_goodcheck( pp->ioc , SHORT_DELAY ) ;
00277       if( ii == 0 ) return( 0) ;   /* still waiting */
00278 
00279       if( ii <  0 ){               /* something bad */
00280          fprintf(stderr,"PO: plugout %s IOCHAN failed to establish.\n",
00281                  pp->po_name ) ;
00282          spt = iochan_error_string() ;
00283          if( spt != NULL ) fprintf(stderr,"  : %s\n",spt) ;
00284          return(-1) ;
00285       }
00286 
00287       pp->ioc_ready = 1 ;          /* mark that it is ready */
00288 
00289       if( verbose )
00290          fprintf(stderr,"PO: plugout %s IOCHAN connection established.\n",
00291                  pp->po_name ) ;
00292    }
00293 
00294    /***************************************************/
00295    /** See if the plugout wants to send us some data **/
00296 
00297    jj = iochan_readcheck( pp->ioc , SHORT_DELAY ) ;
00298 
00299    if( jj < 0 ){    /* something bad happened */
00300       fprintf(stderr,"PO: plugout %s has broken connection!\n",pp->po_name) ;
00301       spt = iochan_error_string() ;
00302       if( spt != NULL ) fprintf(stderr,"  : %s\n",spt) ;
00303       return(-1) ;
00304    }
00305 
00306    if( jj > 0 ){  /*** data is incoming: get it, and process the commands ***/
00307 
00308      /** read the incoming data **/
00309 
00310      npobuf = iochan_recv( pp->ioc , pobuf , PO_BUFSIZE ) ;
00311      if( npobuf <= 0 ){                                /* this error is unlikely */
00312         fprintf(stderr,"PO: failure to read data from plugout %s!\n",pp->po_name) ;
00313         spt = iochan_error_string() ;
00314         if( spt != NULL ) fprintf(stderr,"  : %s\n",spt) ;
00315         return(-1) ;
00316      }
00317 
00318      if( verbose )
00319         fprintf(stderr,"PO: plugout %s sent %d bytes of data\n",pp->po_name,npobuf ) ;
00320 
00321      /** ensure data is NUL terminated **/
00322 
00323      if( pobuf[npobuf-1] != '\0' ) pobuf[npobuf++] = '\0' ;
00324 
00325      /* 21 Nov 2001: break input into substrings (at NULs) */
00326 
00327      ss = aa = 0 ;  /* ss=substring index , aa=pobuf index at start of substring */
00328 
00329      while( ss < MAX_STR && aa < npobuf ){
00330 
00331        /* skip aa ahead to next non-blank, non-NUL */
00332 
00333        for( ; aa < npobuf &&
00334               (pobuf[aa]=='\0' || isspace(pobuf[aa])) ; aa++ ) ; /* nada */
00335 
00336        if( aa == npobuf ) break ;                  /* didn't find anything */
00337 
00338        for( bb=aa+1 ; pobuf[bb] != '\0' ; bb++ ) ; /* skip bb to next NUL */
00339 
00340        str[ss++] = pobuf+aa ;                      /* point to this substring */
00341 
00342        aa = bb+1 ;                                 /* start at next char */
00343      }
00344      nstr = ss ; if( nstr > 0 ) retval = 2 ;
00345 
00346      if( verbose && nstr > 1 )
00347         fprintf(stderr,"PO: received %d command strings at once\n",nstr) ;
00348 
00349      /** determine what to do with each substring **/
00350 
00351      for( ss=0 ; ss < nstr ; ss++ ){
00352 
00353       /* set Talairach coordinates */
00354 
00355       if( strncmp(str[ss],"TT_XYZ_SET",10) == 0 ){
00356         float xx , yy , zz ;
00357 
00358         ii = sscanf( str[ss] , "TT_XYZ_SET %f %f %f" , &xx , &yy , &zz ) ;
00359         if( ii < 3 ){
00360 
00361            fprintf(stderr,"PO: malformed TT_XYZ_SET string from plugout %s: %s\n",
00362                    pp->po_name , str[ss] ) ;
00363            if( pp->do_ack ) PO_ACK_BAD( pp->ioc ) ;
00364 
00365         } else if( im3d->vinfo->view_type != VIEW_TALAIRACH_TYPE ){
00366 
00367            fprintf(stderr,"PO: can't accept TT_XYZ_SET from plugout %s in %s\n",
00368                           pp->po_name , VIEW_typestr[im3d->vinfo->view_type]) ;
00369            if( pp->do_ack ) PO_ACK_BAD( pp->ioc ) ;
00370 
00371         } else {  /* actually change coordinates */
00372 
00373            if( verbose )
00374               fprintf(stderr,"PO: command TT_XYZ_SET %g %g %g\n",xx,yy,zz) ;
00375 
00376            jj = AFNI_jumpto_dicom( im3d , -xx,-yy,zz ) ;
00377            if( pp->do_ack ){
00378               if( jj < 0 ) PO_ACK_BAD( pp->ioc ) ;
00379               else         PO_ACK_OK ( pp->ioc ) ;
00380            }
00381 
00382         }
00383 
00384       /* set coordinates in DICOM order */
00385 
00386       } else if( strncmp(str[ss],"DICOM_XYZ_SET",13) == 0 ){
00387         float xx , yy , zz ;
00388 
00389         ii = sscanf( str[ss] , "DICOM_XYZ_SET %f %f %f" , &xx , &yy , &zz ) ;
00390         if( ii < 3 ){
00391 
00392            fprintf(stderr,"PO: malformed DICOM_XYZ_SET string from plugout %s: %s\n",
00393                    pp->po_name , str[ss] ) ;
00394            if( pp->do_ack ) PO_ACK_BAD( pp->ioc ) ;
00395 
00396         } else {         /* actually set coordinates */
00397 
00398            if( verbose )
00399               fprintf(stderr,"PO: command DICOM_XYZ_SET %g %g %g\n",xx,yy,zz) ;
00400 
00401            jj = AFNI_jumpto_dicom( im3d , xx,yy,zz ) ;
00402            if( pp->do_ack ){
00403               if( jj < 0 ) PO_ACK_BAD( pp->ioc ) ;
00404               else         PO_ACK_OK ( pp->ioc ) ;
00405            }
00406         }
00407 
00408       /* set voxel indexes */
00409 
00410       } else if( strncmp(str[ss],"DSET_IJK_SET",12) == 0 ){
00411         int ix , jy , kz ;
00412 
00413         ii = sscanf( str[ss] , "DSET_IJK_SET %d %d %d" , &ix , &jy , &kz ) ;
00414         if( ii < 3 ){
00415            fprintf(stderr,"PO: malformed DSET_IJK_SET string from plugout %s: %s\n",
00416                    pp->po_name , str[ss] ) ;
00417            if( pp->do_ack ) PO_ACK_BAD( pp->ioc ) ;
00418 
00419         } else {   /* actually set indexes */
00420 
00421            if( verbose )
00422               fprintf(stderr,"PO: command DSET_IJK_SET %d %d %d\n",ix,jy,kz) ;
00423 
00424            AFNI_set_viewpoint( im3d , ix,jy,kz , REDISPLAY_ALL ) ;
00425            if( pp->do_ack ) PO_ACK_OK ( pp->ioc ) ;
00426         }
00427 
00428       /* send voxel indexes back to plugout */
00429 
00430       } else if( strncmp(str[ss],"DSET_IJK_GET",12) == 0 ){
00431         int ix=im3d->vinfo->i1 , jy=im3d->vinfo->j2 , kz=im3d->vinfo->k3 ;
00432 
00433         if( verbose )
00434            fprintf(stderr,"PO: command DSET_IJK_GET -> %d %d %d\n",ix,jy,kz) ;
00435 
00436         sprintf(oobuf,"DSET_IJK %d %d %d\n" , ix,jy,kz ) ;  /* send result */
00437         PO_SEND( pp->ioc , oobuf ) ;
00438 
00439         if( pp->do_ack ){
00440           jj = iochan_readcheck( pp->ioc, -1 ) ;  /* wait for return message */
00441           if( jj == -1 ) return(-1) ;             /* something bad! */
00442           jj = iochan_recv( pp->ioc , oobuf , POACKSIZE ) ; /* read message */
00443           if( verbose )
00444              fprintf(stderr, (jj > 0) ? "PO: received acknowledgment\n"
00445                                       : "PO: did not receive acknowledgment\n" ) ;
00446         }
00447 
00448       /* set surface node ID */
00449 
00450       } else if( strncmp(str[ss],"SURFID",6) == 0 ){
00451         if( SUMA_ENABLED && SESSION_HAS_SUMA(im3d->ss_now) ){
00452            int id ;
00453 
00454            ii = sscanf( str[ss] , "SURFID %d" , &id ) ;
00455            if( ii < 1 ){
00456               fprintf(stderr,"PO: malformed SURFID string from plugout %s: %s\n",
00457                       pp->po_name , str[ss] ) ;
00458               if( pp->do_ack ) PO_ACK_BAD( pp->ioc ) ;
00459 
00460            } else {  /* find the node and jump to that location */
00461 
00462               if( verbose )
00463                  fprintf(stderr,"PO: command SURFID %d\n",id) ;
00464 
00465               ii = SUMA_find_node_id( im3d->ss_now->su_surf[0] , id ) ;
00466               if( ii < 0 ){
00467                  fprintf(stderr,"PO: unknown SURFID node number %d\n",id) ;
00468                  if( pp->do_ack ) PO_ACK_BAD( pp->ioc ) ;
00469               } else {
00470                  AFNI_jumpto_dicom( im3d ,
00471                                     im3d->ss_now->su_surf[0]->ixyz[ii].x ,
00472                                     im3d->ss_now->su_surf[0]->ixyz[ii].y ,
00473                                     im3d->ss_now->su_surf[0]->ixyz[ii].z  ) ;
00474                  if( pp->do_ack ) PO_ACK_OK ( pp->ioc ) ;
00475               }
00476            }
00477         }
00478 
00479       /*-- 07 Nov 2001: drive various AFNI user interface widgets --*/
00480 
00481       } else if( strncmp(str[ss],"DRIVE_AFNI",10) == 0 ){
00482         char cmd[1024]="\0" ;
00483 
00484         if( strlen(str[ss]) < 11 ){
00485           fprintf(stderr,"PO: DRIVE_AFNI from plugout %s lacks command\n",
00486                          pp->po_name ) ;
00487           if( pp->do_ack ) PO_ACK_BAD( pp->ioc ) ;
00488 
00489         } else {  /* the command is everything after "DRIVE_AFNI " */
00490 
00491           MCW_strncpy(cmd,str[ss]+11,1024) ;
00492           if( verbose )
00493             fprintf(stderr,"PO: command DRIVE_AFNI %s\n",cmd) ;
00494           ii = AFNI_driver( cmd ) ;  /* just do it */
00495           if( pp->do_ack ){
00496             if( ii < 0 ) PO_ACK_BAD( pp->ioc ) ;
00497             else         PO_ACK_OK ( pp->ioc ) ;
00498           }
00499         }
00500 
00501       /*-- unknown plugout command: drop a daisy cutter on them --*/
00502 
00503       } else {
00504         fprintf(stderr,"PO: plugout %s sent unknown command string: %s\n",
00505                 pp->po_name , str[ss] ) ;
00506         if( pp->do_ack ) PO_ACK_BAD( pp->ioc ) ;
00507       }
00508 
00509      } /* 21 Nov 2001: end of loop over substrings */
00510 
00511    } else {  /* no data incoming; maybe send something? */
00512 
00513    /****************************************************************/
00514    /** see if anything that has changed that we should tell about **/
00515 
00516       npobuf   = 0 ;
00517       pobuf[0] = '\0' ;
00518 
00519 #define FEQ(a,b) (fabs((a)-(b)) < 0.01)
00520 
00521       /** check each output mode, and format output string if needed **/
00522 
00523       for( ii=0 ; ii < pp->npomode ; ii++ ){
00524 
00525          switch( pp->pomode[ii] ){
00526 
00527             case POMODE_DICOM_XYZ_DELTA:{
00528                float xx , yy , zz ;
00529                xx = im3d->vinfo->xi ;
00530                yy = im3d->vinfo->yj ;
00531                zz = im3d->vinfo->zk ;
00532                if( !FEQ(xx,pp->xi) || !FEQ(yy,pp->yj) || !FEQ(zz,pp->zk) )
00533                   sprintf( pobuf + npobuf , "DICOM_XYZ %9.3f %9.3f %9.3f\n" , xx,yy,zz ) ;
00534             }
00535             break ;
00536 
00537             case POMODE_TT_XYZ_DELTA:{
00538                float xx , yy , zz ;
00539                xx = im3d->vinfo->xi ;
00540                yy = im3d->vinfo->yj ;
00541                zz = im3d->vinfo->zk ;
00542                if( im3d->vinfo->view_type == VIEW_TALAIRACH_TYPE &&
00543                   (!FEQ(xx,pp->xi) || !FEQ(yy,pp->yj) || !FEQ(zz,pp->zk)) )
00544                   sprintf( pobuf + npobuf , "TT_XYZ %9.3f %9.3f %9.3f\n" , -xx,-yy,zz ) ;
00545             }
00546             break ;
00547 
00548             case POMODE_DSET_IJK_DELTA:{
00549                int ix , jy , kz ;
00550                ix = im3d->vinfo->i1 ;
00551                jy = im3d->vinfo->j2 ;
00552                kz = im3d->vinfo->k3 ;
00553                if( ix != pp->ix || jy != pp->jy || kz != pp->kz )
00554                   sprintf( pobuf + npobuf , "DSET_IJK %d %d %d\n" , ix,jy,kz ) ;
00555             }
00556             break ;
00557 
00558             /* 11 Sep 2002 */
00559 
00560             case POMODE_UNDERLAY_DELTA:{
00561                if( !EQUIV_DSETS(pp->dset_underlay,im3d->anat_now) &&
00562                    ISVALID_DSET(im3d->anat_now)                     ){
00563 
00564                    sprintf( pobuf + npobuf , "UNDERLAY %s\n" ,
00565                             DSET_HEADNAME(im3d->anat_now) ) ;
00566                }
00567             }
00568             break ;
00569 
00570             case POMODE_OVERLAY_DELTA:{
00571                if( !EQUIV_DSETS(pp->dset_overlay,im3d->fim_now) &&
00572                    ISVALID_DSET(im3d->fim_now)                     ){
00573 
00574                    sprintf( pobuf + npobuf , "OVERLAY %s\n" ,
00575                             DSET_HEADNAME(im3d->fim_now) ) ;
00576                }
00577             }
00578             break ;
00579 
00580          } /* end of switch on modes */
00581 
00582          npobuf = strlen( pobuf ) ;
00583       }
00584 
00585       /** send string, if any, then wait for acknowledgement **/
00586 
00587       if( npobuf > 0 ){
00588          if( verbose )
00589             fprintf(stderr,"PO: sending plugout %s this string:\n    %s",
00590                     pp->po_name , pobuf ) ;
00591 
00592          PO_SEND( pp->ioc , pobuf ) ;            /* send */
00593          if( pp->do_ack ){
00594            jj = iochan_readcheck( pp->ioc, -1 ) ;  /* wait for return message */
00595            if( jj == -1 ) return(-1) ;             /* something bad! */
00596            jj = iochan_recv( pp->ioc , pobuf , POACKSIZE ) ; /* read message */
00597            if( verbose )
00598              fprintf(stderr, (jj > 0) ? "PO: received acknowledgment\n"
00599                                       : "PO: did not receive acknowledgment\n" ) ;
00600          }
00601          retval = 1 ;
00602       }
00603 
00604    } /* end of potentially sending stuff to the plugout */
00605 
00606    /******************************************/
00607    /** Load memory of the current situation **/
00608 
00609 Proust:
00610    pp->xi             = im3d->vinfo->xi ;
00611    pp->yj             = im3d->vinfo->yj ;
00612    pp->zk             = im3d->vinfo->zk ;
00613    pp->ix             = im3d->vinfo->i1 ;
00614    pp->jy             = im3d->vinfo->j2 ;
00615    pp->kz             = im3d->vinfo->k3 ;
00616    pp->time_index     = im3d->vinfo->time_index ;
00617    pp->view_type      = im3d->vinfo->view_type ;
00618    pp->sess_num       = im3d->vinfo->sess_num ;
00619    pp->anat_num       = im3d->vinfo->anat_num ;
00620    pp->func_num       = im3d->vinfo->func_num ;
00621    pp->func_threshold = im3d->vinfo->func_threshold ;
00622 
00623    pp->dset_underlay  = im3d->anat_now ;
00624    pp->dset_overlay   = im3d->fim_now  ;
00625 
00626    return(retval) ;
00627 }
00628 
00629 /*------------------------------------------------------------------------
00630    Create a new plugout,
00631    based on the control information in the buf string.
00632 --------------------------------------------------------------------------*/
00633 
00634 #define STARTER(st) (strncmp(buf,st,strlen(st)) == 0)
00635 #define NBUF        256
00636 
00637 PLUGOUT_spec * new_PLUGOUT_spec( int ninfo , char * info )
00638 {
00639    PLUGOUT_spec * pp ;
00640    char buf[NBUF] ;
00641    char opt[32] ;
00642    int ii , jj , nstart,nend , nuse , nbuf ;
00643 
00644 ENTRY("new_PLUGOUT_spec") ;
00645 
00646    /** check input for OK-osity **/
00647 
00648    if( ninfo <= 0 ) RETURN( NULL ) ;
00649    for( nend=0 ; nend < ninfo && info[nend] != '\0' ; nend++ ) ; /* nada */
00650    if( nend == ninfo ){
00651       fprintf(stderr,"PO: control string not NUL-terminated!\n") ;
00652       RETURN( NULL ) ;
00653    }
00654 
00655    /** initialize a new plugout specification **/
00656 
00657    pp = (PLUGOUT_spec *) malloc( sizeof(PLUGOUT_spec) ) ;
00658 
00659    pp->npomode     = 0 ;
00660    pp->ioc_name[0] = '\0' ;
00661    pp->ioc         = NULL ;
00662    strcpy(pp->po_name,"Old One-Eyed Dogface") ;
00663 
00664    pp->do_ack      = 1 ;   /* 06 Sep 2001 */
00665 
00666    if( verbose )
00667       fprintf(stderr,"PO: initializing new plugout -- got %d input bytes\n",nend) ;
00668 
00669    /** the input buffer should be of the form:
00670          IO_KEYWORD options
00671          IO_KEYWORD options
00672            ...
00673          IOCHAN iochan_specification
00674 
00675        where IO_KEYWORD specifies the type of
00676        input/output will be going from/to this plugout program. **/
00677 
00678    /******************************************/
00679    /** Scan ahead until next command string **/
00680 
00681    nstart = 0 ;
00682    while( nstart < nend ){
00683 
00684       /** skip whitespace **/
00685 
00686       for( ; nstart < nend && isspace(info[nstart]) ; nstart++ ) ; /* nada */
00687       if( nstart >= nend ) break ;
00688 
00689       /** copy characters into buf until the next '\n' or '\0' **/
00690 
00691       for( nbuf=0,jj=nstart ; nbuf < NBUF && info[jj] != '\n' && info[jj] != '\0' ; ){
00692          buf[nbuf++] = info[jj++] ;
00693       }
00694       if( nbuf == NBUF ){
00695          fprintf(stderr,"PO: line buffer overflow in control information!\n") ;
00696          nbuf-- ;
00697       }
00698       buf[nbuf] = '\0' ; nstart = jj ;
00699 
00700       /************************************/
00701       /*** Scan for legal input strings ***/
00702 
00703       if( verbose )
00704          fprintf(stderr,"PO: initializer command = %s\n",buf) ;
00705 
00706       if( STARTER("TT_XYZ_DELTA") ){
00707 
00708          pp->pomode[ pp->npomode ] = POMODE_TT_XYZ_DELTA ;
00709          pp->npomode ++ ;
00710 
00711       } else if( STARTER("DICOM_XYZ_DELTA") ){
00712 
00713          pp->pomode[ pp->npomode ] = POMODE_DICOM_XYZ_DELTA ;
00714          pp->npomode ++ ;
00715 
00716       } else if( STARTER("DSET_IJK_DELTA") ){
00717 
00718          pp->pomode[ pp->npomode ] = POMODE_DSET_IJK_DELTA ;
00719          pp->npomode ++ ;
00720 
00721       } else if( STARTER("SURFID_DELTA") ){  /* 05 Sep 2001 */
00722 
00723          pp->pomode[ pp->npomode ] = POMODE_SURFID_DELTA ;
00724          pp->npomode ++ ;
00725 
00726       } else if( STARTER("UNDERLAY_DELTA") ){  /* 11 Jan 2002 */
00727 
00728          pp->pomode[ pp->npomode ] = POMODE_UNDERLAY_DELTA ;
00729          pp->npomode ++ ;
00730 
00731       } else if( STARTER("OVERLAY_DELTA") ){
00732 
00733          pp->pomode[ pp->npomode ] = POMODE_OVERLAY_DELTA ;
00734          pp->npomode ++ ;
00735 
00736       } else if( STARTER("NO_ACK") ){        /* 06 Sep 2001 */
00737 
00738          pp->do_ack = 0 ;
00739 
00740       } else if( STARTER("IOCHAN") ){
00741          int kk ;
00742 
00743          sscanf( buf , "IOCHAN %127s" , pp->ioc_name ) ;
00744 
00745          for( kk=0 ; kk < 10 ; kk++ ){
00746             pp->ioc = iochan_init( pp->ioc_name , "accept" ) ;
00747             if( pp->ioc != NULL ) break ;
00748             iochan_sleep(VLONG_DELAY) ; /* wait a bit, try again */
00749          }
00750          if( pp->ioc == NULL )
00751             pp->ioc = iochan_init( pp->ioc_name , "accept" ) ;  /* last try */
00752 
00753          if( pp->ioc == NULL )
00754             fprintf(stderr,"PO: can't listen on IOCHAN %s\n",pp->ioc_name) ;
00755          pp->ioc_ready = 0 ;
00756 
00757       } else if( STARTER("PONAME") ){
00758 
00759          sscanf( buf , "PONAME %127s" , pp->po_name ) ;
00760 
00761       } else {
00762 
00763          fprintf(stderr,"PO: illegal control info=%s\n",buf) ;
00764       }
00765 
00766    }  /* end of loop over command buffers */
00767 
00768    /****************************************/
00769    /** check that something good happened **/
00770 
00771    if( pp->ioc == NULL ){
00772       fprintf(stderr,"PO: no IOCHAN connection established.\n") ;
00773       free(pp) ; RETURN( NULL ) ;
00774    }
00775 
00776    /** initialize memory of things past **/
00777 
00778    pp->xi = pp->yj = pp->zk = -987.654 ;
00779    pp->time_index = -1 ;
00780    pp->view_type  = -1 ;
00781    pp->sess_num   = pp->anat_num = pp->func_num = -1 ;
00782    pp->func_threshold = -0.987654 ;
00783 
00784    pp->dset_underlay = pp->dset_overlay = NULL ; /* 11 Jan 2002 */
00785 
00786    if( verbose )
00787       fprintf(stderr,"PO: initialization completed successfully.\n") ;
00788 
00789    RETURN( pp ) ;
00790 }
00791 
00792 /*************************************************************************/
00793 #else  /* ALLOW_PLUGINS not defined */
00794 
00795 void AFNI_init_plugouts( void ){ return ; }
00796 int AFNI_have_plugouts( void ){ return 0 ; }  /* 07 Nov 2001 */
00797 
00798 #endif /* ALLOW_PLUGINS */
 

Powered by Plone

This site conforms to the following standards: