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.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 /**********************************************************************/
00008 /* GPL/NIH AFNI:                                                      */
00009 /*    Analysis of Functional NeuroImages                              */
00010 /*                                                                    */
00011 /* Author: Robert W. Cox, PhD                                         */
00012 /*         Scientific and Statistical Computing Core                  */
00013 /*         National Institute of Mental Health                        */
00014 /*         Bethesda, MD 20892  USA                                    */
00015 /*                                                                    */
00016 /* Acknowledgments:                                                   */
00017 /*   + This program would have been much more difficult had           */
00018 /*     not Andrzej Jesmanowicz forged the way with FD.                */
00019 /*   + Many neuroscientists have made helpful suggestions along       */
00020 /*     the way, including Jeff Binder, Ted DeYoe, Jim Hyde, Steve     */
00021 /*     Rao, and Elliot Stein.                                         */
00022 /*   + Thanks are also due to Mike Beauchamp, who is perhaps the most */
00023 /*     sophisticated user of AFNI that I've met, and who has found    */
00024 /*     many bugs or gotchas in this code.                             */
00025 /*   + Doug Ward of MCW has contributed much to the overall package.  */
00026 /*   + Ziad Saad of NIH has also contributed many useful suggestions. */
00027 /*   + Peter Bandettini of NIH has asked many many "quick" questions. */
00028 /*   + Sean and Alex Bellgowan have contributed in their own way.     */
00029 /**********************************************************************/
00030 
00031 #define MAIN
00032 
00033 #include "afni.h"
00034 #include <X11/keysym.h>  /* 20 Feb 2003 */
00035 #include "afni_plugout.h"
00036 
00037 /*------------------------------------------------------*/
00038 #ifdef SHOWOFF
00039 # undef  SHSH
00040 # undef  SHSHSH
00041 # undef  SHSTRING
00042 # define SHSH(x)   #x
00043 # define SHSHSH(x) SHSH(x)
00044 # define SHSTRING  SHSHSH(SHOWOFF)   /* now in "quotes" */
00045 #else
00046 # undef  SHSTRING
00047 #endif
00048 /*------------------------------------------------------*/
00049 
00050 #ifdef SHSTRING
00051 #define ANNOUNCEMENT                                                           \
00052  "GPL AFNI: Analysis of Functional NeuroImages, by RW Cox (" COXEMAIL ")\n"    \
00053  "This is Version " VERSION               "\n"                                 \
00054  "[[Precompiled binary " SHSTRING ": " __DATE__ "]]\n\n"                       \
00055  " ** This software was designed to be used only for research purposes. **\n"  \
00056  " ** Clinical uses are not recommended, and have never been evaluated. **\n"  \
00057  " ** This software comes with no warranties of any kind whatsoever,    **\n"  \
00058  " ** and may not be useful for anything.  Use it at your own risk!     **\n"  \
00059  " ** If these terms are not acceptable, you aren't allowed to use AFNI.**\n"  \
00060  " ** See 'Define Datamode->Misc->License Info' for more details.       **\n\n"
00061 #else
00062 #define ANNOUNCEMENT                                                           \
00063  "GPL AFNI: Analysis of Functional NeuroImages, by RW Cox (" COXEMAIL ")\n"    \
00064  "This is Version " VERSION               "\n\n"                               \
00065  " ** This software was designed to be used only for research purposes. **\n"  \
00066  " ** Clinical uses are not recommended, and have never been evaluated. **\n"  \
00067  " ** This software comes with no warranties of any kind whatsoever,    **\n"  \
00068  " ** and may not be useful for anything.  Use it at your own risk!     **\n"  \
00069  " ** If these terms are not acceptable, you aren't allowed to use AFNI.**\n"  \
00070  " ** See 'Define Datamode->Misc->License Info' for more details.       **\n\n"
00071 #endif
00072 
00073 #define USE_FRIENDS
00074 
00075 #ifdef AFNI_DEBUG
00076 #  define REPORT_PROGRESS(str)  /* nada */
00077 #else
00078 #  define REPORT_PROGRESS(str)  \
00079     do{ if(AFNI_VERBOSE){printf(str);fflush(stdout);} } while(0)
00080 #endif
00081 
00082 #define EMPTY_STRING(str) ((str)[0] = '\0')
00083 
00084 #ifdef AFNI_DEBUG
00085 #  define USE_TRACING
00086 #endif
00087 
00088 /*----------------------------------------------------------------
00089    Global variables that used to be local variables in main()
00090 ------------------------------------------------------------------*/
00091 
00092 static XtAppContext   MAIN_app ;
00093 static XtErrorHandler MAIN_old_handler ;   /* no longer used */
00094 static Three_D_View * MAIN_im3d ;
00095 static MCW_DC *       MAIN_dc ;
00096 static Widget         MAIN_shell=NULL ;
00097 static int            MAIN_argc ;
00098 static char **        MAIN_argv ;
00099 static Boolean        MAIN_workprocess( XtPointer ) ;
00100 
00101 #define USE_SIDES  /* 01 Dec 1999: replace "left is xxx" */
00102                    /* labels with "sides" labels.        */
00103 
00104 /*----- Stuff saved from the '-com' command line arguments [29 Jul 2005] -----*/
00105 
00106 static int   COM_num = 0 ;
00107 static char *COM_com[1024] ;  /* only 1024 commands allowed!!! */
00108 
00109 /********************************************************************
00110    Print out some help information and then quit quit quit
00111 *********************************************************************/
00112 
00113 void AFNI_syntax(void)
00114 {
00115    printf(
00116      ANNOUNCEMENT
00117 
00118      "----------------------------------------------------------------\n"
00119      "USAGE 1: read in sessions of 3D datasets (created by to3d, etc.)\n"
00120      "----------------------------------------------------------------\n"
00121      "   afni [options] [session_directory ...]\n"
00122      "\n"
00123 #if MMAP_THRESHOLD > 0
00124      "   -purge       Conserve memory by purging data to disk.\n"
00125      "                  [Use this if you run out of memory when running AFNI.]\n"
00126      "                  [This will slow the code down, so use only if needed.]\n"
00127 #endif
00128      "   -posfunc     Set up the color 'pbar' to use only positive function values.\n"
00129      "   -R           Recursively search each session_directory for more session\n"
00130      "                  subdirectories.\n"
00131      "       WARNING: This will descend the entire filesystem hierarchy from\n"
00132      "                  each session_directory given on the command line.  On a\n"
00133      "                  large disk, this may take a long time.  To limit the\n"
00134      "                  recursion to 5 levels (for example), use -R5.\n"
00135      "   -ignore N    Tells the program to 'ignore' the first N points in\n"
00136      "                  time series for graphs and FIM calculations.\n"
00137      "   -im1 N       Tells the program to use image N as the first one for\n"
00138      "                  graphs and FIM calculations (same as '-ignore N-1')\n"
00139      "   -tlrc_small  These options set whether to use the 'small' or 'big'\n"
00140      "   -tlrc_big      Talairach brick size.  The compiled in default for\n"
00141      "                  the program is now 'big', unlike AFNI 1.0x.\n"
00142 #ifndef WARP_4D
00143      "   -warp_4D     Allows the program to Talairach transform and write\n"
00144      "                  to disk 3D+time datasets.  Note that the resulting\n"
00145      "                  disk files will be gigantic (100s of Megabytes).\n"
00146 #endif
00147      "   -no1D        Tells AFNI not to read *.1D timeseries files from\n"
00148      "                  the dataset directories.  The *.1D files in the\n"
00149      "                  directories listed in the AFNI_TSPATH environment\n"
00150      "                  variable will still be read (if this variable is\n"
00151      "                  not set, then './' will be scanned for *.1D files.)\n"
00152      "\n"
00153      "   -noqual      Tells AFNI not to enforce the 'quality' checks when\n"
00154      "                  making the transformations to +acpc and +tlrc.\n"
00155      "   -unique      Tells the program to create a unique set of colors\n"
00156      "                  for each AFNI controller window.  This allows\n"
00157      "                  different datasets to be viewed with different\n"
00158      "                  grayscales or colorscales.  Note that -unique\n"
00159      "                  will only work on displays that support 12 bit\n"
00160      "                  PseudoColor (e.g., SGI workstations) or TrueColor.\n"
00161      "   -orient code Tells afni the orientation in which to display\n"
00162      "                  x-y-z coordinates (upper left of control window).\n"
00163      "                  The code must be 3 letters, one each from the\n"
00164      "                  pairs {R,L} {A,P} {I,S}.  The first letter gives\n"
00165      "                  the orientation of the x-axis, the second the\n"
00166      "                  orientation of the y-axis, the third the z-axis:\n"
00167      "                   R = right-to-left         L = left-to-right\n"
00168      "                   A = anterior-to-posterior P = posterior-to-anterior\n"
00169      "                   I = inferior-to-superior  S = superior-to-inferior\n"
00170      "                  The default code is RAI ==> DICOM order.  This can\n"
00171      "                  be set with the environment variable AFNI_ORIENT.\n"
00172      "                  As a special case, using the code 'flipped' is\n"
00173      "                  equivalent to 'LPI' (this is for Steve Rao).\n"
00174 #ifdef ALLOW_PLUGINS
00175      "   -noplugins   Tells the program not to load plugins.\n"
00176      "                  (Plugins can also be disabled by setting the\n"
00177      "                   environment variable AFNI_NOPLUGINS.)\n"
00178      "   -yesplugouts Tells the program to listen for plugouts.\n"
00179      "                  (Plugouts can also be enabled by setting the\n"
00180      "                   environment variable AFNI_YESPLUGOUTS.)\n"
00181      "   -YESplugouts Makes the plugout code print out lots of messages\n"
00182      "                  (useful for debugging a new plugout).\n"
00183      "   -noplugouts  Tells the program NOT to listen for plugouts.\n"
00184      "                  (This option is available to override\n"
00185      "                   the AFNI_YESPLUGOUTS environment variable.)\n"
00186 #endif
00187      "   -skip_afnirc Tells the program NOT to read the file .afnirc\n"
00188      "                  in the home directory.  See README.setup for\n"
00189      "                  details on the use of .afnirc for initialization.\n"
00190      "   -layout fn   Tells AFNI to read the initial windows layout from\n"
00191      "                  file 'fn'.  If this option is not given, then\n"
00192      "                  environment variable AFNI_LAYOUT_FILE is used.\n"
00193      "                  If neither is present, then AFNI will do whatever\n"
00194      "                  it feels like.\n"
00195      "\n"
00196      "   -niml        If present, turns on listening for NIML-formatted\n"
00197      "                  data from SUMA.  Can also be turned on by setting\n"
00198      "                  environment variable AFNI_NIML_START to YES.\n"
00199      "   -np port     If present, sets the NIML socket port number to 'port'.\n"
00200      "                  This must be an integer between 1024 and 65535,\n"
00201      "                  and must be the same as the '-np port' number given\n"
00202      "                  to SUMA.  [default = 53211]\n"
00203      "\n"
00204      "   -com ccc     This option lets you specify 'command strings' to\n"
00205      "                  drive AFNI after the program startup is completed.\n"
00206      "                  Legal command strings are described in the file\n"
00207      "                  README.driver.  More than one '-com' option can\n"
00208      "                  be used, and the commands will be executed in\n"
00209      "                  the order they are given on the command line.\n"
00210      "            N.B.: Most commands to AFNI contain spaces, so the 'ccc'\n"
00211      "                  command strings will need to be enclosed in quotes.\n"
00212      "\n"
00213      " * If no session_directories are given, then the program will use\n"
00214      "    the current working directory (i.e., './').\n"
00215      " * The maximum number of sessions is now set to  %d.\n"
00216      " * The maximum number of datasets per session is %d.\n"
00217      " * To change these maximums, you must edit file '3ddata.h' and then\n"
00218      "    recompile this program.\n"
00219 
00220      , THD_MAX_NUM_SESSION , THD_MAX_SESSION_SIZE
00221    ) ;
00222 
00223    printf(
00224      "\n"
00225      "-----------------------------------------------------\n"
00226      "USAGE 2: read in images for 'quick and dirty' viewing\n"
00227      "-----------------------------------------------------\n"
00228      "(Most advanced features of AFNI will be disabled.)\n"
00229      "\n"
00230      "   afni -im [options] im1 im2 im3 ...\n"
00231      "\n"
00232      "   -im          Flag to read in images instead of 3D datasets\n"
00233      "                  (Talaraich and functional stuff won't work)\n"
00234      "   -dy yratio   Tells afni the downscreen pixel size is 'yratio' times\n"
00235      "                  the across-screen (x) pixel dimension (default=1.0)\n"
00236      "   -dz zratio   Tells afni the slice thickness is 'zratio' times\n"
00237      "                  the x pixel dimension (default=1.0)\n"
00238      "   -orient code Tells afni the orientation of the input images.\n"
00239      "                  The code must be 3 letters, one each from the\n"
00240      "                  pairs {R,L} {A,P} {I,S}.  The first letter gives\n"
00241      "                  the orientation of the x-axis, the second the\n"
00242      "                  orientation of the y-axis, the third the z-axis:\n"
00243      "                   R = right-to-left         L = left-to-right\n"
00244      "                   A = anterior-to-posterior P = posterior-to-anterior\n"
00245      "                   I = inferior-to-superior  S = superior-to-inferior\n"
00246      "                  (the default code is ASL ==> sagittal images).\n"
00247      "                  Note that this use of '-orient' is different from\n"
00248      "                  the use when viewing datasets.\n"
00249      "   -resize      Tells afni that all images should be resized to fit\n"
00250      "                  the size of the first one, if they don't already fit\n"
00251      "                  (by default, images must all 'fit' or afni will stop)\n"
00252      "   -datum type  Tells afni to convert input images into the type given:\n"
00253      "                  byte, short, float, complex are the legal types.\n"
00254      " The image files (im1 ...) are the same formats as accepted by to3d.\n"
00255      "\n"
00256      " New image display options (alternatives to -im) [19 Oct 1999]:\n"
00257      "   -tim         These options tell AFNI to arrange the input images\n"
00258      "   -tim:<nt>    into a internal time-dependent dataset.  Suppose that\n"
00259      "   -zim:<nz>    there are N input 2D slices on the command line.\n"
00260      "              * -tim alone means these are N points in time (1 slice).\n"
00261      "              * -tim:<nt> means there are nt points in time (nt is\n"
00262      "                  an integer > 1), so there are N/nt slices in space,\n"
00263      "                  and the images on the command line are input in\n"
00264      "                  time order first (like -time:tz in to3d).\n"
00265      "              * -zim:<nz> means there are nz slices in space (nz is\n"
00266      "                  an integer > 1), so there are N/nz points in time,\n"
00267      "                  and the images on the command line are input in\n"
00268      "                  slice order first (like -time:zt in to3d).\n"
00269      "\n"
00270      " N.B.: You may wish to use the -ignore option to set the number of\n"
00271      "        initial points to ignore in the time series graph if you use\n"
00272      "        -tim or -zim, since there is no way to change this from\n"
00273      "        within an AFNI run (the FIM menus are disabled).\n"
00274      " N.B.: The program 'aiv' (AFNI image viewer) can also be used to\n"
00275      "        look at images.\n"
00276    ) ;
00277 
00278    printf(
00279      "\n"
00280      "-------------------------------------------------------\n"
00281      "USAGE 3: read in datasets specified on the command line\n"
00282      "-------------------------------------------------------\n"
00283      "\n"
00284      "  afni -dset [options] dname1 dname2 ...\n"
00285      "\n"
00286      "where 'dname1' is the name of a dataset, etc.  With this option, only\n"
00287      "the chosen datasets are read in, and they are all put in the same\n"
00288      "'session'.  Follower datasets are not created.\n"
00289      "\n"
00290     MASTER_HELP_STRING
00291      "\n"
00292     CALC_HELP_STRING
00293    ) ;
00294 
00295    printf(
00296      "\n"
00297      "-------------------------------\n"
00298      "GENERAL OPTIONS (for any usage)\n"
00299      "-------------------------------\n"
00300      "\n"
00301      "   -q           Tells afni to be 'quiet' on startup\n"
00302      "   -Dname=val   Sets environment variable 'name' to 'val' inside AFNI;\n"
00303      "                  will supersede any value set in .afnirc.\n"
00304      "   -gamma gg    Tells afni that the gamma correction factor for the\n"
00305      "                  monitor is 'gg' (default gg is 1.0; greater than\n"
00306      "                  1.0 makes the image contrast larger -- this may\n"
00307      "                  also be adjusted interactively)\n"
00308      "   -install     Tells afni to install a new X11 Colormap.  This only\n"
00309      "                  means something for PseudoColor displays.  Also, it\n"
00310      "                  usually cause the notorious 'technicolor' effect.\n"
00311      "   -ncolors nn  Tells afni to use 'nn' gray levels for the image\n"
00312      "                  displays (default is %d)\n"
00313      "   -xtwarns     Tells afni to show any Xt warning messages that may\n"
00314      "                  occur; the default is to suppress these messages.\n"
00315      "   -tbar name   Uses 'name' instead of 'AFNI' in window titlebars.\n"
00316      "   -flipim and  The '-flipim' option tells afni to display images in the\n"
00317      "   -noflipim      'flipped' radiology convention (left on the right).\n"
00318      "                  The '-noflipim' option tells afni to display left on\n"
00319      "                  the left, as neuroscientists generally prefer.  This\n"
00320      "                  latter mode can also be set by the Unix environment\n"
00321      "                  variable 'AFNI_LEFT_IS_LEFT'.  The '-flipim' mode is\n"
00322      "                  the default.\n"
00323 #ifdef USE_TRACING
00324      "   -trace       Turns routine call tracing on, for debugging purposes.\n"
00325      "   -TRACE       Turns even more verbose tracing on, for more debugging.\n"
00326 #endif
00327 #ifdef USING_MCW_MALLOC
00328      "   -nomall      Disables use of the mcw_malloc() library routines.\n"
00329 #endif
00330      "\n"
00331      "N.B.: Many of these options, as well as the initial color set up,\n"
00332      "      can be controlled by appropriate X11 resources.  See the\n"
00333      "      file AFNI.Xdefaults for instructions and examples.\n"
00334 
00335      , DEFAULT_NGRAY
00336    ) ;
00337 
00338    printf(
00339     "\n"
00340     "----------\n"
00341     "REFERENCES\n"
00342     "----------\n"
00343     "The following papers describe some of the components of the AFNI package.\n"
00344     "\n"
00345     "RW Cox.  AFNI: Software for analysis and visualization of functional\n"
00346     "  magnetic resonance neuroimages.  Computers and Biomedical Research,\n"
00347     "  29: 162-173, 1996.\n"
00348     "\n"
00349     "  * The first AFNI paper, and the one I prefer you cite if you want to\n"
00350     "    refer to the AFNI package as a whole.\n"
00351     "\n"
00352     "RW Cox, A Jesmanowicz, and JS Hyde.  Real-time functional magnetic\n"
00353     "  resonance imaging.  Magnetic Resonance in Medicine, 33: 230-236, 1995.\n"
00354     "\n"
00355     "  * The first paper on realtime FMRI; describes the algorithm used in\n"
00356     "    3dfim+, the interactive FIM calculations, and in the realtime plugin.\n"
00357     "\n"
00358     "RW Cox and JS Hyde.  Software tools for analysis and visualization of\n"
00359     "  FMRI Data.  NMR in Biomedicine, 10: 171-178, 1997.\n"
00360     "\n"
00361     "  * A second paper about AFNI and design issues for FMRI software tools.\n"
00362     "\n"
00363     "RW Cox and A Jesmanowicz.  Real-time 3D image registration for\n"
00364     "  functional MRI.  Magnetic Resonance in Medicine, 42: 1014-1018, 1999.\n"
00365     "\n"
00366     "  * Describes the algorithm used for image registration in 3dvolreg\n"
00367     "    and in the realtime plugin.\n"
00368     "\n"
00369     "ZS Saad, KM Ropella, RW Cox, and EA DeYoe.  Analysis and use of FMRI\n"
00370     "  response delays.  Human Brain Mapping, 13: 74-93, 2001.\n"
00371     "\n"
00372     "  * Describes the algorithm used in 3ddelay (cf. '3ddelay -help').\n"
00373    ) ;
00374 
00375    printf("\n") ; exit(0) ;
00376 }
00377 
00378 /*----------------------------------------------------------------------
00379    parse command line switches and store results in a data structure
00380 ------------------------------------------------------------------------*/
00381 
00382 void AFNI_parse_args( int in_argc , char * in_argv[] )
00383 {
00384    int narg = 1 ;
00385    char * env_orient , * env ;
00386    int     argc=in_argc ,    new_argc      ; /* 18 Nov 1999 */
00387    char ** argv=in_argv , ** new_argv=NULL ;
00388 
00389 ENTRY("AFNI_parse_args") ;
00390 
00391    if( argc > 1 && strncmp(argv[1],"-help",2) == 0 ) AFNI_syntax() ;
00392 
00393    GLOBAL_argopt.dz       = 1.0 ;          /* set up defaults */
00394    GLOBAL_argopt.dy       = 1.0 ;
00395    GLOBAL_argopt.ignore   = INIT_ignore ;
00396    GLOBAL_argopt.elide_quality  = 0 ;      /* Dec 1997 */
00397    GLOBAL_argopt.no_frivolities = 0 ;      /* 01 Aug 1998 */
00398    GLOBAL_argopt.install_cmap   = 0 ;      /* 14 Sep 1998 */
00399    GLOBAL_argopt.read_1D        = 1 ;      /* 27 Jan 2000 */
00400 
00401    GLOBAL_argopt.enable_suma    = 1 ;      /* 29 Aug 2001 */
00402 
00403    GLOBAL_argopt.yes_niml       = AFNI_yesenv("AFNI_NIML_START") ;
00404    GLOBAL_argopt.port_niml      = 0 ;      /* 10 Dec 2002 */
00405 
00406 #if 0
00407    GLOBAL_argopt.allow_rt = 0 ;            /* April 1997 */
00408 #else                                      /* 09 Oct 2000 */
00409    GLOBAL_argopt.allow_rt = AFNI_yesenv("AFNI_REALTIME_Activate") ;
00410    GLOBAL_argopt.no_frivolities = (GLOBAL_argopt.allow_rt != 0) ;
00411 #endif
00412 
00413    SESSTRAIL = 1 ;
00414    env = getenv( "AFNI_SESSTRAIL" ) ;
00415    if( env != NULL ){
00416      SESSTRAIL = strtol(env,NULL,10) ;
00417      if( SESSTRAIL < 0 ) SESSTRAIL = 0 ;  /* 24 Aug 2000 */
00418    }
00419 
00420    GLOBAL_argopt.elide_quality = AFNI_yesenv("AFNI_MARKERS_NOQUAL") ;
00421 
00422    /* 24 Sep 2000: get the default layout name (add $HOME) */
00423 
00424    { char * lf = getenv("AFNI_LAYOUT_FILE") ;
00425      if( lf != NULL ){
00426         char * eh = getenv("HOME") , * ff ;
00427         int ll = strlen(lf) + 8 ;
00428         if( eh != NULL ) ll += strlen(eh) ;
00429         ff = AFMALL(char, ll) ;
00430         if( eh != NULL && lf[0] != '/' ){ strcpy(ff,eh) ; strcat(ff,"/") ; }
00431         else                            { ff[0] = '\0' ; }
00432         strcat(ff,lf) ;
00433         GLOBAL_argopt.layout_fname = ff ;
00434      }
00435    }
00436 
00437    /* 21 Jan 2003: get the startup script name */
00438 
00439    { char *lf = getenv("AFNI_STARTUP_SCRIPT") ;
00440      if( lf == NULL ) lf = ".afni.startup_script" ;
00441      if( lf != NULL ){
00442        char *eh = NULL , *ff ;
00443        int ll = strlen(lf) + 8 ;
00444        if( !THD_is_file(lf) && lf[0] != '/' ) eh = getenv("HOME") ;
00445        if( eh != NULL ) ll += strlen(eh) ;
00446        ff = AFMALL(char, ll) ;
00447        if( eh != NULL ){ strcpy(ff,eh) ; strcat(ff,"/") ; }
00448        else            { ff[0] = '\0' ; }
00449        strcat(ff,lf) ;
00450        GLOBAL_argopt.script_fname = ff ;
00451      }
00452    }
00453 
00454    /*-- 18 Nov 1999: Allow setting of options from environment --*/
00455 
00456    env = getenv( "AFNI_OPTIONS" ) ;
00457    if( env != NULL )
00458      prepend_string_to_args( env, in_argc, in_argv, &new_argc, &new_argv ) ;
00459    if( new_argv != NULL ){
00460       MAIN_argc = argc = new_argc ;
00461       MAIN_argv = argv = new_argv ;
00462    }
00463 
00464 #ifdef ALLOW_PLUGINS
00465    GLOBAL_argopt.noplugins  =  AFNI_yesenv( "AFNI_NOPLUGINS" ) ;
00466    GLOBAL_argopt.noplugouts = !AFNI_yesenv( "AFNI_YESPLUGOUTS" ) ;
00467 #endif
00468 
00469    env_orient = getenv( "AFNI_ORIENT" ) ;
00470 
00471    GLOBAL_argopt.read_sessions = True ;        /* exactly one of these should be True */
00472    GLOBAL_argopt.read_images   = False ;
00473    GLOBAL_argopt.read_dsets    = False ;       /* 17 Mar 2000 */
00474 
00475    GLOBAL_argopt.datum         = ILLEGAL_TYPE ;
00476 
00477    GLOBAL_argopt.gamma         = INIT_gamma ;
00478    GLOBAL_argopt.gsfac         = 0.0 ;
00479    GLOBAL_argopt.ncolor        = INIT_ngray ;
00480 #if MMAP_THRESHOLD > 0
00481    GLOBAL_argopt.auto_purge    = INIT_purge ;
00482 #else
00483    GLOBAL_argopt.auto_purge    = True ;
00484 #endif
00485    GLOBAL_argopt.resize_images = False ;       /* False means all images must match */
00486    GLOBAL_argopt.keep_logo     = False ;       /* For making pretty pictures? */
00487    GLOBAL_argopt.pos_func      = INIT_posfunc ;/* Positive valued functions? */
00488    GLOBAL_argopt.recurse       = 0 ;           /* Recurse on session directories? */
00489    GLOBAL_argopt.xtwarns       = False ;       /* True means keep Xt warnings turned on */
00490    GLOBAL_argopt.destruct      = False ;       /* True means allow overwrite of datasets */
00491                                                /* (Not yet properly implemented!) */
00492 
00493    GLOBAL_argopt.tlrc_big      = INIT_tlrc_big ; /* use the big Talairach box? */
00494 #ifndef WARP_4D
00495    GLOBAL_argopt.warp_4D       = False ;
00496 #else
00497    GLOBAL_argopt.warp_4D       = True ;
00498 #endif
00499 
00500    GLOBAL_argopt.unique_dcs    = False ;  /* 06 Nov 1996 */
00501 
00502    strcpy(GLOBAL_argopt.orient_code,"---") ;
00503 
00504    strcpy(GLOBAL_argopt.title_name,"AFNI") ;           /* default title bar name */
00505 
00506    GLOBAL_argopt.left_is_left = AFNI_yesenv( "AFNI_LEFT_IS_LEFT" ) ;
00507 
00508    GLOBAL_argopt.read_tim = 0 ;   /* 19 Oct 1999 */
00509 
00510    while( narg < argc ){
00511 
00512       if( argv[narg][0] != '-' ) break ;   /* no - ==> quit */
00513 
00514 #ifdef USE_TRACING
00515       if( strncmp(argv[narg],"-trace",5) == 0 ){
00516          DBG_trace = 1 ;
00517          narg++ ; continue ;
00518       }
00519       if( strncmp(argv[narg],"-TRACE",5) == 0 ){  /* 23 Aug 1998 */
00520          DBG_trace = 2 ;
00521          if( MAIN_shell != NULL )
00522             XSynchronize(XtDisplay(MAIN_shell),TRUE) ; /* 01 Dec 1999 */
00523          narg++ ; continue ;
00524       }
00525 #endif
00526 
00527       /*----- -Dname=val -- set environment variable [22 Mar 2005] -----*/
00528 
00529       if( strncmp(argv[narg],"-D",2) == 0 && strchr(argv[narg],'=') != NULL ){
00530         (void) AFNI_setenv( argv[narg]+2 ) ;
00531         narg++ ; continue ;                 /* go to next arg */
00532       }
00533 
00534       /*----- -layout (23 Sep 2000) -----*/
00535 
00536       if( strcmp(argv[narg],"-layout") == 0 ){
00537          if( narg+1 >= argc ) FatalError("need an argument after -layout!") ;
00538          GLOBAL_argopt.layout_fname = argv[++narg] ;  /* just a pointer */
00539          narg++ ; continue ;  /* go to next arg */
00540       }
00541 
00542       /*----- -no1D option (27 Jan 2000) ----- */
00543 
00544       if( strncmp(argv[narg],"-no1D",5) == 0 ){
00545          GLOBAL_argopt.read_1D = 0 ;
00546          narg++ ; continue ;  /* go to next arg */
00547       }
00548 
00549       /*----- -skip_afnirc option (14 Jul 1998) -----*/
00550 
00551       if( strncmp(argv[narg],"-skip_afnirc",12) == 0 ){
00552          GLOBAL_argopt.skip_afnirc  = 1 ;
00553          narg++ ; continue ;  /* go to next arg */
00554       }
00555 
00556       /*----- -rt option -----*/
00557 
00558       if( strncmp(argv[narg],"-rt",3) == 0 ){
00559          GLOBAL_argopt.allow_rt       = -1 ;
00560          GLOBAL_argopt.no_frivolities =  1 ;
00561 #if 0
00562 #ifdef USE_TRACING
00563          DBG_trace                    =  0 ;  /* 26 Jan 2001 */
00564 #endif
00565 #endif
00566          narg++ ; continue ;  /* go to next arg */
00567       }
00568 
00569       if( strncmp(argv[narg],"-nort",5) == 0 ){  /* 09 Oct 2000 */
00570          GLOBAL_argopt.allow_rt       = 0 ;
00571          GLOBAL_argopt.no_frivolities = 0 ;
00572          narg++ ; continue ;  /* go to next arg */
00573       }
00574 
00575       /*----- -noqual -----*/
00576 
00577       if( strncmp(argv[narg],"-noqual",6) == 0 ){
00578          GLOBAL_argopt.elide_quality = 1 ;
00579          narg++ ; continue ;  /* go to next arg */
00580       }
00581 
00582       /*---- -agni [29 Aug 2001] or -suma -----*/
00583 
00584       if( strcmp(argv[narg],"-agni")==0 || strcmp(argv[narg],"-suma")==0 ){
00585          fprintf(stderr,"\n-agni/-suma are now turned on by default\n") ;
00586          GLOBAL_argopt.enable_suma = 1 ;
00587          narg++ ; continue ;  /* go to next arg */
00588       }
00589 
00590       /*---- -com ccc [29 Jul 2005] ----*/
00591 
00592       if( strcmp(argv[narg],"-com") == 0 ){
00593         int ll ;
00594         if( ++narg >= argc ) FatalError("need an argument after -com!");
00595         ll = strlen(argv[narg]) ;
00596              if( ll > 255 ) ERROR_message("argument after -com is too long!" );
00597         else if( ll <   3 ) ERROR_message("argument after -com is too short!");
00598         else                COM_com[ COM_num++ ] = argv[narg] ;
00599 
00600         narg++ ; continue ;  /* go to next arg */
00601       }
00602 
00603       /*---- -niml [28 Feb 2002] -----*/
00604 
00605       if( strcmp(argv[narg],"-niml") == 0 ){
00606          if( GLOBAL_argopt.yes_niml )
00607            fprintf(stderr,"\n-niml is already turned on\n") ;
00608          GLOBAL_argopt.yes_niml++ ;
00609          narg++ ; continue ;  /* go to next arg */
00610       }
00611 
00612       /*---- -np port [10 Dec 2002] ----*/
00613 
00614       if( strcmp(argv[narg],"-np") == 0 ){
00615          float val ;
00616          if( narg+1 >= argc ) FatalError("need an argument after -np!");
00617 
00618          val = strtod( argv[++narg] , NULL ) ;
00619          if( val >= 1024 && val <= 65535 ) GLOBAL_argopt.port_niml = (int)val ;
00620          else fprintf(stderr,
00621                 "\n*** WARNING: -np %s is illegal!\n", argv[narg]);
00622          narg++ ; continue ;  /* go to next arg */
00623       }
00624 
00625       if( strcmp(argv[narg],"-noniml") == 0 ){
00626          GLOBAL_argopt.yes_niml-- ;
00627          if( GLOBAL_argopt.yes_niml < 0 ) GLOBAL_argopt.yes_niml = 0 ;
00628          narg++ ; continue ;  /* go to next arg */
00629       }
00630 
00631       /*----- -tbar 'name' option -----*/
00632 
00633       if( strncmp(argv[narg],"-tbar",5) == 0 ){
00634          if( narg+1 >= argc ) FatalError("need an argument after -tbar!");
00635          MCW_strncpy(GLOBAL_argopt.title_name,argv[++narg],32) ;
00636          narg++ ; continue ;  /* go to next arg */
00637       }
00638 
00639       /*----- -xtwarns option -----*/
00640 
00641       if( strncmp(argv[narg],"-xtwarns",6) == 0 ){
00642          GLOBAL_argopt.xtwarns = True ;
00643          narg++ ; continue ;  /* go to next arg */
00644       }
00645 
00646       /*----- -destruct option -----*/
00647 
00648       if( strncmp(argv[narg],"-destruct",6) == 0 ){   /** has no effect at present **/
00649          fprintf(stderr,"\n*** -destruct option not implemented at present! ***\n") ;
00650          GLOBAL_argopt.destruct = False ;
00651          narg++ ; continue ;  /* go to next arg */
00652       }
00653 
00654       /*----- -posfunc option -----*/
00655 
00656       if( strncmp(argv[narg],"-posfunc",6) == 0 ){
00657          GLOBAL_argopt.pos_func = True ;
00658          narg++ ; continue ;  /* go to next arg */
00659       }
00660 
00661       /*----- -R option -----*/
00662 
00663       if( strncmp(argv[narg],"-R",2) == 0 ){
00664          int ll = strlen(argv[narg]) ;
00665          if( ll == 2 ) GLOBAL_argopt.recurse = 999 ;
00666          else {
00667             ll = strtol( argv[narg]+2 , NULL , 10 ) ;
00668             if( ll > 0 ) GLOBAL_argopt.recurse = ll ;
00669             else FatalError("illegal -R option!") ;
00670          }
00671          narg++ ; continue ;  /* go to next arg */
00672       }
00673 
00674       /*----- -tlrc_big option -----*/
00675 
00676       if( strncmp(argv[narg],"-tlrc_big",7) == 0 ){
00677          GLOBAL_argopt.tlrc_big = True ;
00678          narg++ ; continue ;  /* go to next arg */
00679       }
00680 
00681       /*----- -unique option (06 Nov 1996) -----*/
00682 
00683       if( strncmp(argv[narg],"-unique",5) == 0 ){
00684          GLOBAL_argopt.unique_dcs = True ;
00685          narg++ ; continue ;  /* go to next arg */
00686       }
00687 
00688       /*----- -install option (14 Sep 1998) -----*/
00689 
00690       if( strncmp(argv[narg],"-install",5) == 0 ){
00691          GLOBAL_argopt.install_cmap = True ;
00692          narg++ ; continue ;  /* go to next arg */
00693       }
00694 
00695 #ifndef WARP_4D
00696       /*----- -warp_4D option -----*/
00697 
00698       if( strncmp(argv[narg],"-warp_4D",7) == 0 ){
00699          GLOBAL_argopt.warp_4D = True ;
00700          narg++ ; continue ;  /* go to next arg */
00701       }
00702 #endif
00703 
00704       /*----- -tlrc_small option -----*/
00705 
00706       if( strncmp(argv[narg],"-tlrc_small",7) == 0 ){
00707          GLOBAL_argopt.tlrc_big = False ;
00708          narg++ ; continue ;  /* go to next arg */
00709       }
00710 
00711       /*----- -logo option -----*/
00712 
00713       if( strncmp(argv[narg],"-logo",4) == 0 ){
00714          GLOBAL_argopt.keep_logo = True ;
00715          narg++ ; continue ;  /* go to next arg */
00716       }
00717 
00718       /*----- -resize option -----*/
00719 
00720       if( strncmp(argv[narg],"-resize",4) == 0 ){
00721          GLOBAL_argopt.resize_images = True ;
00722          narg++ ; continue ;  /* go to next arg */
00723       }
00724 
00725       /*----- -purge option -----*/
00726 
00727       if( strncmp(argv[narg],"-purge",4) == 0 ){
00728          GLOBAL_argopt.auto_purge = True ;
00729          narg++ ; continue ;  /* go to next arg */
00730       }
00731 
00732 #ifdef ALLOW_PLUGINS
00733       /*----- -noplugins option -----*/
00734 
00735       if( strncmp(argv[narg],"-noplugins",10) == 0 ){
00736          GLOBAL_argopt.noplugins = 1 ;
00737          narg++ ; continue ;  /* go to next arg */
00738       }
00739 
00740       /*----- -noplugouts option -----*/
00741 
00742       if( strncmp(argv[narg],"-noplugouts",10) == 0 ){
00743          GLOBAL_argopt.noplugouts = 1 ;
00744          narg++ ; continue ;  /* go to next arg */
00745       }
00746 
00747       /*----- -yesplugouts option -----*/
00748 
00749       if( strncmp(argv[narg],"-yesplugouts",10) == 0 ){
00750          GLOBAL_argopt.noplugouts   = 0 ;
00751          GLOBAL_argopt.plugout_code = 0 ;
00752          narg++ ; continue ;  /* go to next arg */
00753       }
00754 
00755       /*----- -yesplugouts option -----*/
00756 
00757       if( strncmp(argv[narg],"-YESplugouts",10) == 0 ){
00758          GLOBAL_argopt.noplugouts   = 0 ;
00759          GLOBAL_argopt.plugout_code = 1 ;
00760          narg++ ; continue ;  /* go to next arg */
00761       }
00762 #endif
00763 
00764       /*----- -flipim option -----*/
00765 
00766       if( strncmp(argv[narg],"-flipim",5) == 0 ){
00767          GLOBAL_argopt.left_is_left = 0 ;
00768          narg++ ; continue ;  /* go to next arg */
00769       }
00770 
00771       /*----- -noflipim option -----*/
00772 
00773       if( strncmp(argv[narg],"-noflipim",5) == 0 ){
00774          GLOBAL_argopt.left_is_left = 1 ;
00775          narg++ ; continue ;  /* go to next arg */
00776       }
00777 
00778       /*----- -orient code option -----*/
00779 
00780       if( strncmp(argv[narg],"-orient",4) == 0 ){
00781          if( narg+1 >= argc ) FatalError("need an argument after -orient!");
00782 
00783          MCW_strncpy(GLOBAL_argopt.orient_code,argv[++narg],4) ;
00784          narg++ ; continue ;  /* go to next arg */
00785       }
00786 
00787       /*----- -ignore # option -----*/
00788 
00789       if( strncmp(argv[narg],"-ignore",4) == 0 ){
00790          float val ;
00791          if( narg+1 >= argc ) FatalError("need an argument after -ignore!");
00792 
00793          val = strtod( argv[++narg] , NULL ) ;
00794          if( val >= 0 ) GLOBAL_argopt.ignore = (int) val ;
00795          else fprintf(stderr,
00796                 "\n*** WARNING: -ignore value %s illegal\n", argv[narg]);
00797 
00798          narg++ ; continue ;  /* go to next arg */
00799       }
00800 
00801       /*----- -im1 # option [must come before '-im' option!] -----*/
00802 
00803       if( strncmp(argv[narg],"-im1",4) == 0 ){
00804          float val ;
00805          if( narg+1 >= argc ) FatalError("need an argument after -im1!");
00806 
00807          val = strtod( argv[++narg] , NULL ) ;
00808          if( val >= 1 ) GLOBAL_argopt.ignore = (int) (val-1.0) ;
00809          else fprintf(stderr,
00810                 "\n*** WARNING: -ignore value %s illegal\n", argv[narg]);
00811 
00812          narg++ ; continue ;  /* go to next arg */
00813       }
00814 
00815 
00816       /*----- -dy # option -----*/
00817 
00818       if( strncmp(argv[narg],"-dy",3) == 0 ){
00819          float val ;
00820          if( narg+1 >= argc ) FatalError("need an argument after -dy!");
00821 
00822          val = strtod( argv[++narg] , NULL ) ;
00823          if( val > 0 ) GLOBAL_argopt.dy = val ;
00824          else fprintf(stderr,
00825                 "\n*** WARNING: -dy value %s illegal\n", argv[narg]);
00826 
00827          narg++ ; continue ;  /* go to next arg */
00828       }
00829 
00830       /*----- -dz # option -----*/
00831 
00832       if( strncmp(argv[narg],"-dz",3) == 0 ){
00833          float val ;
00834          if( narg+1 >= argc ) FatalError("need an argument after -dz!");
00835 
00836          val = strtod( argv[++narg] , NULL ) ;
00837          if( val > 0 ) GLOBAL_argopt.dz = val ;
00838          else fprintf(stderr,
00839                 "\n*** WARNING: -dz value %s illegal\n", argv[narg]);
00840 
00841          narg++ ; continue ;  /* go to next arg */
00842       }
00843 
00844       /*----- -gamma # option -----*/
00845 
00846       if( strncmp(argv[narg],"-gamma",4) == 0 ){
00847          float val ;
00848          if( narg+1 >= argc ) FatalError("need an argument after -gamma!");
00849 
00850          val = strtod( argv[++narg] , NULL ) ;
00851          if( val > 0 ) GLOBAL_argopt.gamma = val ;
00852          else fprintf(stderr,
00853                 "\n*** WARNING: -gamma value %s illegal\n", argv[narg]);
00854 
00855          narg++ ; continue ;  /* go to next arg */
00856       }
00857 
00858 #ifdef USE_GSFAC
00859       /*----- -gsfac # option -----*/
00860 
00861       if( strncmp(argv[narg],"-gsfac",4) == 0 ){
00862          float val ;
00863          if( narg+1 >= argc ) FatalError("need an argument after -gsfac!");
00864 
00865          val = strtod( argv[++narg] , NULL ) ;
00866          if( val != 0 ) GLOBAL_argopt.gsfac = val ;
00867          else fprintf(stderr,
00868                 "\n*** WARNING: -gsfac value %s illegal\n", argv[narg]);
00869 
00870          narg++ ; continue ;  /* go to next arg */
00871       }
00872 #endif
00873 
00874       /*----- -datum type option -----*/
00875 
00876       if( strncmp(argv[narg],"-datum",6) == 0 ){
00877          if( ++narg >= argc ) FatalError("need an argument after -datum!") ;
00878 
00879          if( strcmp(argv[narg],"short") == 0 ){
00880             GLOBAL_argopt.datum= MRI_short ;
00881          } else if( strcmp(argv[narg],"float") == 0 ){
00882             GLOBAL_argopt.datum= MRI_float ;
00883          } else if( strcmp(argv[narg],"complex") == 0 ){
00884             GLOBAL_argopt.datum= MRI_complex ;
00885          } else if( strcmp(argv[narg],"byte") == 0 ){
00886             GLOBAL_argopt.datum= MRI_byte ;
00887          } else {
00888             char buf[256] ;
00889             sprintf(buf,"-datum of type '%s' is not supported in AFNI!",
00890                    argv[narg] ) ;
00891             FatalError(buf) ;
00892          }
00893          narg++ ; continue ;  /* go to next arg */
00894       }
00895 
00896       /*----- -ncolor # option -----*/
00897 
00898       if( strncmp(argv[narg],"-ncolor",3) == 0 ){
00899          float val ;
00900          if( narg+1 >= argc ) FatalError("need an argument after -ncolor!");
00901 
00902          val = strtod( argv[++narg] , NULL ) ;
00903          if( val > 2 ) GLOBAL_argopt.ncolor = val ;
00904          else fprintf(stderr,
00905                 "\n*** WARNING: -ncolor value %s illegal\n", argv[narg]);
00906 
00907          narg++ ; continue ;  /* go to next arg */
00908       }
00909 
00910       /*----- -dset option [17 Mar 2000] -----*/
00911 
00912       if( strncmp(argv[narg],"-dset",5) == 0 ){
00913          GLOBAL_argopt.read_images   = False ;
00914          GLOBAL_argopt.read_sessions = False ;
00915          GLOBAL_argopt.read_dsets    = True  ;
00916          narg++ ; continue ;  /* go to next arg */
00917       }
00918 
00919       /*----- -im option -----*/
00920 
00921       if( strncmp(argv[narg],"-im",3) == 0 ){
00922          GLOBAL_argopt.read_images   = True ;
00923          GLOBAL_argopt.read_sessions = False ;
00924          GLOBAL_argopt.read_dsets    = False ;       /* 17 Mar 2000 */
00925          narg++ ; continue ;  /* go to next arg */
00926       }
00927 
00928       /*----- -tim option [19 Oct 1999] -----*/
00929 
00930       if( strncmp(argv[narg],"-tim",4)==0 || strncmp(argv[narg],"-zim",4)==0 ){
00931          int ll=strlen(argv[narg]) , nn ;
00932 
00933          GLOBAL_argopt.read_images   = True ;
00934          GLOBAL_argopt.read_sessions = False ;
00935          GLOBAL_argopt.read_dsets    = False ;  /* 17 Mar 2000 */
00936          GLOBAL_argopt.read_tim      = 1 ;
00937 
00938          if( ll > 5 && argv[narg][4] == ':' ){         /* 20 Oct 1999 */
00939             nn = strtol( argv[narg]+5 , NULL , 10 ) ;
00940             if( nn > 1 ){
00941                GLOBAL_argopt.read_tim = nn ; /* will be nz or nt */
00942             } else {
00943                fprintf(stderr,"** Error: illegal value in %s\n",argv[narg]);
00944                exit(1) ;
00945             }
00946          }
00947 
00948          /* negate flag for time-order first (-tim) vs z-order first (-zim) */
00949 
00950          if( strncmp(argv[narg],"-tim",4)==0 && GLOBAL_argopt.read_tim > 1 )
00951             GLOBAL_argopt.read_tim = - GLOBAL_argopt.read_tim ;
00952 
00953          narg++ ; continue ;  /* go to next arg */
00954       }
00955 
00956       /*----- -nomall option -----*/
00957 
00958       if( strncmp(argv[narg],"-nomall",5) == 0 ){    /* was handled in main() */
00959          narg++ ; continue ;  /* go to next arg */
00960       }
00961 
00962       /*----- -q option -----*/
00963 
00964       if( strcmp(argv[narg],"-q") == 0 ){            /* was handled in main() */
00965          narg++ ; continue ;  /* go to next arg */
00966       }
00967 
00968       /*----- -- option -----*/
00969 
00970       if( strcmp(argv[narg],"--") == 0 ){
00971          narg++ ; break ;  /* end of args */
00972       }
00973 
00974       /*----- if we get here, bad news for America! -----*/
00975 
00976       fprintf(stderr,"\n*** Unknown option %s ***",argv[narg]) ;
00977       fprintf(stderr,"\n*** Try 'afni -help' for a list of command line options.\n") ;
00978       exit(1) ;
00979 
00980    } /* end of loop over argv's starting with '-' */
00981 
00982 #if 0
00983 #ifdef USE_TRACING
00984    if( ALLOW_real_time ) DBG_trace = 0 ; /* 26 Jan 2001 */
00985 #endif
00986 #endif
00987 
00988    /** 16 July 1997: orientation code change **/
00989 
00990    if( GLOBAL_argopt.orient_code[0] == '-' ){
00991       if( GLOBAL_argopt.read_images )
00992          strcpy(GLOBAL_argopt.orient_code,"ASL") ;
00993       else if( env_orient != NULL )
00994          MCW_strncpy(GLOBAL_argopt.orient_code,env_orient,4) ;
00995       else
00996          strcpy(GLOBAL_argopt.orient_code,"RAI") ;
00997    }
00998 
00999    THD_coorder_fill( GLOBAL_argopt.orient_code , &GLOBAL_library.cord ) ;
01000 
01001 #if 0
01002 fprintf(stderr,"\ncoorder: signs = %d %d %d  order = %d %d %d\n" ,
01003         GLOBAL_library.cord.xxsign ,
01004         GLOBAL_library.cord.yysign ,
01005         GLOBAL_library.cord.zzsign ,
01006         GLOBAL_library.cord.first ,
01007         GLOBAL_library.cord.second ,
01008         GLOBAL_library.cord.third   ) ;
01009 #endif
01010 
01011    GLOBAL_argopt.first_file_arg = narg ;  /* rest of args must be files (I hope) */
01012 
01013    EXRETURN ;
01014 }
01015 
01016 /*-----------------------------------------------------------------------
01017    This routine is used if hiding Xt warnings is enabled.
01018    It simply does nothing -- it replaces the default Xt warning handler.
01019 -------------------------------------------------------------------------*/
01020 
01021 void AFNI_handler(char * msg){ return ; }
01022 
01023 /*! Avoid fatal X11 errors. */
01024 
01025 int AFNI_xerrhandler( Display *d , XErrorEvent *x ){ return 0; }
01026 
01027 /*-----------------------------------------------------------------------
01028    Fallback resources for AFNI.  May be overridden by the user's
01029    .Xdefaults file, or other resource sources.  AFNI does not come
01030    with an "app-defaults" file, since that would be too much like work.
01031 -------------------------------------------------------------------------*/
01032 
01033 static char * FALLback[] =
01034   {   "AFNI*fontList:              9x15bold=charset1"    ,
01035       "AFNI*pbar*fontList:         6x10=charset1"        ,
01036       "AFNI*imseq*fontList:        7x13=charset1"        ,
01037       "AFNI*background:            gray25"               ,
01038       "AFNI*menu*background:       gray15"               ,
01039       "AFNI*borderColor:           gray25"               ,
01040       "AFNI*foreground:            yellow"               ,
01041       "AFNI*borderWidth:           0"                    ,
01042       "AFNI*troughColor:           blue3"                ,
01043       "AFNI*XmLabel.translations:  #override<Btn2Down>:" , /* Motif 2.0 bug */
01044       "AFNI*help*background:       black"                ,
01045       "AFNI*help*foreground:       #ffff88"              ,
01046       "AFNI*help*helpborder:       False"                ,
01047       "AFNI*help*waitPeriod:       1066"                 ,
01048       "AFNI*help*fontList:         9x15bold=charset1"    ,
01049       "AFNI*cluefont:              9x15bold"             ,
01050       "AFNI*help*cancelWaitPeriod: 333"                  ,
01051    NULL } ;
01052 
01053 /*-----------------------------------------------------------------------*/
01054 
01055 #define CATCH_SIGNALS
01056 #ifdef CATCH_SIGNALS
01057 #include <signal.h>
01058 void AFNI_sigfunc(int sig)   /** signal handler for fatal errors **/
01059 {
01060    char * sname ;
01061    static volatile int fff=0 ;
01062    if( fff ) _exit(1) ; else fff = 1 ;
01063    switch(sig){
01064       default:      sname = "unknown" ; break ;
01065       case SIGINT:  sname = "SIGINT"  ; break ;
01066       case SIGPIPE: sname = "SIGPIPE" ; break ;
01067       case SIGSEGV: sname = "SIGSEGV" ; break ;
01068       case SIGBUS:  sname = "SIGBUS"  ; break ;
01069       case SIGTERM: sname = "SIGTERM" ; break ;
01070    }
01071    fprintf(stderr,"\nFatal Signal %d (%s) received\n",sig,sname); fflush(stderr);
01072    TRACEBACK ;
01073    fprintf(stderr,"*** Program Abort ***\n") ; fflush(stderr) ;
01074    exit(1) ;
01075 }
01076 #endif
01077 
01078 /*-------------------------------------------------------------------------*/
01079 /*! Check if a particular option is present; 1=yes, 0=no.  [15 Jan 2004]
01080 ---------------------------------------------------------------------------*/
01081 
01082 static int check_string( char *targ , int ns , char *ss[] )
01083 {
01084    int ii , lt ;
01085    if( targ == NULL || *targ == '\0' || ns <= 0 || ss == NULL ) return 0 ;
01086    lt = strlen(targ) ;
01087    for( ii=0 ; ii < ns ; ii++ )
01088      if( ss[ii] != NULL && strncmp(ss[ii],targ,lt) == 0 ) return 1 ;
01089    return 0 ;
01090 }
01091 
01092 /*=========================================================================
01093   The new AFNI main program.
01094     02 Aug 1999: Have moved much of the startup into a work process.
01095 ===========================================================================*/
01096 
01097 int main( int argc , char * argv[] )
01098 {
01099    int ii ;
01100 
01101    /*--- help the pitiful user? ---*/
01102 
01103    if( argc > 1 && strncmp(argv[1],"-help",2) == 0 ) AFNI_syntax() ;
01104 
01105    /** 15 Jan 2004: check for -skip_afnirc right away **/
01106 
01107    GLOBAL_argopt.skip_afnirc = check_string("-skip_afnirc",argc,argv) ;
01108    if( GLOBAL_argopt.skip_afnirc ) AFNI_mark_environ_done() ;
01109 
01110    /*--- Initialize some stuff ---*/
01111 
01112    machdep() ;                      /* RWCox: 20 Apr 2001 */
01113    THD_load_datablock_verbose(1) ;  /* 21 Aug 2002 */
01114 
01115 #ifdef CATCH_SIGNALS
01116    signal(SIGINT ,AFNI_sigfunc) ;   /* may be superseded by mainENTRY below */
01117    signal(SIGBUS ,AFNI_sigfunc) ;
01118    signal(SIGSEGV,AFNI_sigfunc) ;
01119    signal(SIGTERM,AFNI_sigfunc) ;
01120 #endif
01121 
01122    /** Check for -version [15 Aug 2003] **/
01123 
01124    if( check_string("-ver",argc,argv) || check_string("--ver",argc,argv) ){
01125      printf("Version " VERSION  "\n") ;
01126 #ifdef SHSTRING
01127        printf( "[[Precompiled binary " SHSTRING ": " __DATE__ "]]\n" ) ;
01128 #endif
01129      exit(0) ;
01130    }
01131 
01132    /** just print the SHOWOFF string [26 Oct 2004] **/
01133 
01134    if( check_string("-show",argc,argv) || check_string("--show",argc,argv) ){
01135 #ifdef SHSTRING
01136       printf( SHSTRING "\n" ) ;
01137 #else
01138       printf("Unknown\n") ;
01139 #endif
01140       exit(0) ;
01141    }
01142 
01143    /** debug stuff **/
01144 
01145 #ifdef USING_MCW_MALLOC
01146    if( !check_string("-nomall",argc,argv) && !check_string("-rt",argc,argv) )
01147      enable_mcw_malloc() ;
01148 #endif
01149 
01150 #ifdef USE_TRACING
01151    if( check_string("-trace",argc,argv) ) DBG_trace = 1 ;
01152    if( check_string("-TRACE",argc,argv) ) DBG_trace = 2 ;
01153 #endif
01154 
01155 #if 0
01156 #ifdef USE_TRACING
01157    if( ALLOW_real_time ) DBG_trace = 0 ; /* 26 Jan 2001 */
01158 #endif
01159 #endif
01160 
01161    /** 25 Oct 2001: check for -q (quiet) option right away **/
01162 
01163    GLOBAL_argopt.quiet = AFNI_yesenv("AFNI_QUIET") ;
01164    if( AFNI_VERBOSE && check_string("-q",argc,argv) ) GLOBAL_argopt.quiet = 1;
01165 
01166    /** 12 Dec 2002: scan for "-rt" now,
01167                     to see if we want to start the version check **/
01168 
01169    GLOBAL_argopt.allow_rt = check_string("-rt",argc,argv) ;
01170 
01171    if( !GLOBAL_argopt.quiet && !ALLOW_real_time )
01172      AFNI_start_version_check() ;               /* 21 Nov 2002 */
01173 
01174    /** set default values of some environment variables [22 Jun 2004] **/
01175 
01176    { char **ed , *eqn ;
01177      static char *edef[] = {
01178          "AFNI_SUMA_LINECOLOR"       , "blue3"  ,
01179          "AFNI_CROSSHAIR_LINES"      , "YES"    ,
01180          "AFNI_ALWAYS_LOCK"          , "YES"    ,
01181          "AFNI_IMAGE_SAVESQUARE"     , "YES"    ,
01182 #ifdef DARWIN
01183          "AFNI_X11_REDECORATE"       , "NO"     ,  /* 27 Dec 2004 */
01184 #endif
01185 
01186 #if 0
01187          "AFNI_IMAGE_LABEL_MODE"     , "1"      ,
01188          "AFNI_IMAGE_LABEL_SIZE"     , "2"      ,
01189          "AFNI_IMAGE_LABEL_SETBACK"  , "01"     ,
01190          "AFNI_IMAGE_LABEL_COLOR"    , "yellow" ,
01191 #endif
01192        NULL } ;
01193 
01194      for( ed=edef ; *ed != NULL && *(ed+1) != NULL ; ed+=2 ){
01195        if( getenv(*ed) == NULL ){
01196          eqn = (char *)malloc(128) ;
01197          sprintf(eqn,"%s=%s",*ed,*(ed+1)) ; putenv(eqn) ;
01198        }
01199      }
01200    }
01201 
01202    /** Start the debug traceback stuff **/
01203 
01204    mainENTRY("AFNI:main") ; /* 26 Jan 2001: replace ENTRY w/ mainENTRY */
01205 
01206    /** set the function to call if run out of memory when creating datasets **/
01207 
01208    THD_set_freeup( AFNI_purge_unused_dsets ) ;  /* 18 Oct 2001 */
01209 
01210 #if 0
01211    if( argc > 1 ) AFNI_logger("afni",argc,argv) ; /* 14 Aug 2001 */
01212 #endif
01213 
01214    srand48((long)time(NULL)) ;  /* initialize random number generator */
01215 
01216    REPORT_PROGRESS( "\n" ) ;         /* 02 Dec 2000 */
01217    REPORT_PROGRESS( ANNOUNCEMENT ) ;
01218 
01219    /*-- Be friendly --*/
01220 
01221 #ifdef USE_FRIENDS
01222    { char * sf = AFNI_get_friend() ;
01223      REPORT_PROGRESS( sf ) ;
01224      REPORT_PROGRESS( "\n\n" ) ;
01225      if( check_string("-friend",argc,argv) ) exit(0) ;
01226    }
01227 #endif
01228 
01229    /*-------------------------------------------------------------*/
01230    /*------------ initialize the controllers list ----------------*/
01231 
01232    for( ii=0 ; ii < MAX_CONTROLLERS ; ii++ )
01233      GLOBAL_library.controllers[ii] = NULL ;
01234    GLOBAL_library.dc = NULL ;
01235 
01236    GLOBAL_library.controller_lock = 0 ; ENABLE_LOCK ;
01237    GLOBAL_library.time_lock = 0 ;                      /* 03 Nov 1998 */
01238    GLOBAL_library.ijk_lock  = 0 ;                      /* 11 Sep 2000 */
01239    SET_FIM_bkthr(10.0) ;                               /* 02 Jun 1999 */
01240 
01241    GLOBAL_library.hints_on  = 0 ;                      /* 07 Aug 1999 */
01242 
01243 #ifdef ALLOW_PLUGINS
01244    GLOBAL_library.plugins   = NULL ;
01245 #endif
01246 
01247    GLOBAL_library.session   = NULL ;                   /* 20 Dec 2001 */
01248    GLOBAL_library.warptable = NULL ;                   /* 28 Aug 2002 */
01249 
01250    /*--------------------------------------------------------------------*/
01251    /*--- initialize X, toplevel window, defaults, and display context ---*/
01252 
01253    REPORT_PROGRESS("Initializing: X11");
01254 
01255    MAIN_shell = XtVaAppInitialize( &MAIN_app , "AFNI" , NULL , 0 ,
01256                                    &argc , argv , FALLback , NULL ) ;
01257 
01258    if( MAIN_shell == NULL ){
01259      fprintf(stderr,"\n*** Cannot initialize X11 ***\n") ; exit(1) ;
01260    }
01261    if( DBG_trace == 2 ){                           /* 01 Dec 1999 */
01262      XSynchronize(XtDisplay(MAIN_shell),TRUE) ;
01263      STATUS("XSynchronize is enabled") ;
01264    }
01265 
01266    MAIN_argc = argc ; MAIN_argv = argv ;  /* what's left after XtVaAppInit */
01267 
01268    REPORT_PROGRESS(".") ;
01269 
01270    /*-- 04 Jun 1999: modify order of loading arguments and defaults --*/
01271 
01272    if( ! GLOBAL_argopt.skip_afnirc ){
01273      char *sysenv = getenv("AFNI_SYSTEM_AFNIRC") ;        /* 12 Apr 2000 */
01274      if( sysenv != NULL ) AFNI_process_environ(sysenv) ;  /* 12 Apr 2000 */
01275 
01276      AFNI_process_environ(NULL) ;                         /* 07 Jun 1999 */
01277    } else {
01278      AFNI_mark_environ_done() ;                           /* 16 Apr 2000 */
01279    }
01280 
01281    AFNI_load_defaults( MAIN_shell ) ;
01282 
01283    if( ! GLOBAL_argopt.skip_afnirc ){          /* this line added 14 Jul 1998 */
01284       char * home = getenv("HOME") ; char fname[256] ;
01285       char * sysenv = getenv("AFNI_SYSTEM_AFNIRC") ;       /* 12 Apr 2000 */
01286 
01287       GPT = NULL ;  /* 19 Dec 1997 */
01288 
01289       if( sysenv != NULL )                                 /* 12 Apr 2000 */
01290         AFNI_process_setup( sysenv , SETUP_INIT_MODE , NULL ) ;
01291 
01292       if( home != NULL ){ strcpy(fname,home) ; strcat(fname,"/.afnirc") ; }
01293       else              { strcpy(fname,".afnirc") ; }
01294       AFNI_process_setup( fname , SETUP_INIT_MODE , NULL ) ;
01295 
01296 #ifdef AFNI_DEBUG
01297       home = dump_PBAR_palette_table(0) ;
01298       if( home != NULL ){ puts(home) ; free(home) ; }
01299 #endif
01300 
01301    } else {                                    /* these lines also 14 Jul 1998 */
01302       REPORT_PROGRESS( "[skip .afnirc]" ) ;
01303    }
01304 
01305    AFNI_parse_args( argc , argv ) ;  /* after Xt init above, only my args left */
01306 
01307    /* disable X11 and Xt error messages and crashes (we hope) */
01308 
01309    (void) XSetErrorHandler( AFNI_xerrhandler ) ;      /* 26 Jun 2003 */
01310    (void) XtAppSetErrorHandler(MAIN_app,AFNI_handler) ;
01311 
01312    if( GLOBAL_argopt.xtwarns == False )
01313      (void) XtAppSetWarningHandler(MAIN_app,AFNI_handler) ;  /* turn off */
01314 
01315    /* FIM background threshold */
01316 
01317    { char * lenv = getenv("AFNI_FIM_BKTHR") ;          /* 04 Jun 1999 */
01318      if( lenv != NULL ){
01319        float bk = strtod(lenv,NULL) ;
01320        if( bk >= 0.0 && bk < 100.0 ) SET_FIM_bkthr(bk) ;
01321      }
01322    }
01323 
01324    /* locking? */
01325 
01326    if( AFNI_yesenv("AFNI_ALWAYS_LOCK") ){
01327      for( ii=0 ; ii < MAX_CONTROLLERS ; ii++ )
01328        GLOBAL_library.controller_lock |= (1<<ii) ;
01329    }
01330 
01331    /*-- now create first display context: MAIN_dc --*/
01332 
01333    GLOBAL_library.dc = MAIN_dc =
01334         MCW_new_DC( MAIN_shell , GLOBAL_argopt.ncolor ,
01335                     INIT_ncolovr , INIT_colovr , INIT_labovr ,
01336                     GLOBAL_argopt.gamma , GLOBAL_argopt.install_cmap ) ;
01337 
01338    if( MAIN_dc->depth < 9 && MAIN_dc->visual_class != TrueColor && GLOBAL_argopt.unique_dcs ){
01339      GLOBAL_argopt.unique_dcs = False ;
01340      REPORT_PROGRESS("[-unique off]") ;
01341    }
01342 
01343    /*------------------------------------*/
01344    /*------- take it away, Goldie -------*/
01345    /*------------------------------------*/
01346 
01347 #if 0
01348    (void) XtAppAddWorkProc( MAIN_app, MAIN_workprocess, NULL ) ;
01349 #else
01350    PLUTO_register_workproc( MAIN_workprocess , NULL ) ;
01351 #endif
01352 
01353    MCW_disable_help() ;
01354 
01355 STATUS("start XtAppMainLoop") ;
01356 
01357    XtAppMainLoop(MAIN_app) ;
01358    exit(0) ;
01359 }
01360 
01361 #undef HUBERIZE
01362 #ifdef HUBERIZE
01363 #include "huber.c"
01364 #endif
01365 
01366 /*---------------------------------------------------------------------------------
01367    Xt work process to do most of the initialization stuff.
01368    (So we can so a splash screen to pacify and amuse the user.)
01369 -----------------------------------------------------------------------------------*/
01370 
01371 #define REFRESH XmUpdateDisplay(MAIN_im3d->vwid->top_shell)
01372 
01373 static Boolean MAIN_workprocess( XtPointer fred )
01374 {
01375    static int MAIN_calls = 0 ;  /* controls what happens */
01376    static int nosplash = 0 , nodown = 0 ;
01377    static double eltime=0.0 , max_splash=2.0 ;
01378    int ii ;
01379 
01380 ENTRY("MAIN_workprocess") ;  /* 23 Jan 2001: added ENTRY/RETURN to this routine */
01381 
01382 if(PRINT_TRACING){ char str[256]; sprintf(str,"MAIN_calls=%d",MAIN_calls); STATUS(str); }
01383 
01384    switch( MAIN_calls ){
01385 
01386       /*============================================================================
01387          This code is executed at the end (when MAIN_calls gets too big).
01388         ============================================================================*/
01389 
01390       default:{
01391 STATUS("default call") ;
01392 
01393          if( nosplash || nodown ) RETURN(True) ;
01394          if( !nodown &&
01395              COX_clock_time()-eltime >= max_splash ){ AFNI_splashdown(); RETURN(True); }
01396       }
01397       break ;
01398 
01399       /*============================================================================
01400          Stuff to popup the AFNI splash screen (see afni_splash.[ch]).
01401         ============================================================================*/
01402 
01403       case 0:{
01404 STATUS("call 0") ;
01405 
01406 #ifdef NO_FRIVOLITIES
01407         nosplash = 1 ;
01408 #else
01409         nosplash = AFNI_yesenv("AFNI_NOSPLASH") ;
01410 #endif
01411         if( !nosplash ){
01412           char * hh ;
01413           AFNI_splashup() ; eltime = COX_clock_time() ;
01414           hh = getenv("AFNI_SPLASHTIME") ;
01415           if( hh != NULL ) max_splash = strtod(hh,NULL) ;
01416         }
01417       }
01418       break ;
01419 
01420       /*** For the Mac users! ***/
01421 
01422       case 1:
01423         AFNI_speak("[[volm 0.65; inpt PHON; rate -10; pbas +5]]1AEf=nnnIY",0) ;  /* fall thru */
01424 
01425       case 2:
01426       case 3:
01427       case 4:
01428       case 5:
01429       case 6:
01430       case 7:
01431       case 8:
01432       case 9:
01433       case 10:
01434 STATUS("sleep call") ;
01435         if( !nosplash) iochan_sleep(1) ; /* waste time to let splash popup */
01436       break ;
01437 
01438       /*============================================================================
01439          Next, create the first AFNI controller window.
01440         ============================================================================*/
01441 
01442       case 11:{
01443 
01444         int do_images ;                           /* 19 Oct 1999 */
01445 
01446 STATUS("call 11") ;
01447 
01448         REPORT_PROGRESS(". Widgets") ;
01449 
01450         MCW_enable_help() ;
01451 
01452         do_images = GLOBAL_argopt.read_images ;
01453 
01454         MAIN_im3d = new_AFNI_controller( MAIN_shell , MAIN_dc ,
01455                                          do_images ? AFNI_IMAGES_VIEW
01456                                                    : AFNI_3DDATA_VIEW ) ;
01457 
01458         GLOBAL_library.controllers[0] = MAIN_im3d ;
01459 
01460         REPORT_PROGRESS(".") ;
01461 
01462         /* Always turn off Drag-n-Drop (courtesy the Motif FAQ) */
01463 
01464         XtVaSetValues( XmGetXmDisplay(XtDisplay(MAIN_im3d->vwid->top_shell)) ,
01465                           XmNdragInitiatorProtocolStyle , XmDRAG_NONE ,
01466                           XmNdragReceiverProtocolStyle  , XmDRAG_NONE ,
01467                        NULL ) ;
01468       }
01469       break ;
01470 
01471       /*============================================================================
01472          Next, read the input files (may take a while).
01473         ============================================================================*/
01474 
01475       case 12:{
01476 
01477 STATUS("call 12") ;
01478 
01479         REPORT_PROGRESS(". Input files:") ;
01480 
01481         AFNI_read_inputs( MAIN_argc , MAIN_argv ) ;
01482 
01483         if( GLOBAL_library.have_dummy_dataset && MAIN_im3d->type == AFNI_3DDATA_VIEW ){
01484           XtSetSensitive( MAIN_im3d->vwid->prog->clone_pb , False ) ;
01485           MAIN_im3d->dummied = 1 ;  /* 27 Jan 2004 */
01486         }
01487       }
01488       break ;
01489 
01490       /*============================================================================
01491          Next, setup the plugins, and things like that ...
01492         ============================================================================*/
01493 
01494       case 13:{
01495 
01496 STATUS("call 13") ;
01497 
01498         GLOBAL_library.registered_0D.num = 0 ;               /* initialize registry */
01499         GLOBAL_library.registered_1D.num = 0 ;               /* initialize registry */
01500         GLOBAL_library.registered_2D.num = 0 ;               /* initialize registry */
01501 
01502         GLOBAL_library.registered_fim.num = 0 ;              /* 30 Jan 2000 */
01503 
01504         GLOBAL_library.registered_slice_proj.num = 0 ;       /* 31 Jan 2002 */
01505 
01506         /* these functions are now in afni_transforms.c [01 Feb 2002] */
01507 
01508         AFNI_register_0D_function( "Log10" , log10_func ) ;
01509         AFNI_register_0D_function( "SSqrt" , ssqrt_func ) ;
01510 
01511         AFNI_register_1D_function( "Median3" , median3_func) ;
01512         AFNI_register_1D_function( "OSfilt3" , osfilt3_func) ;
01513         AFNI_register_1D_function( "|FFT()|" , absfft_func ) ;
01514 
01515         AFNI_register_2D_function( "Median9" , median9_box_func ) ;
01516         AFNI_register_2D_function( "Winsor9" , winsor9_box_func ) ;
01517         AFNI_register_2D_function( "OSfilt9" , osfilt9_box_func ) ;
01518 
01519         AFNI_register_2D_function( "Median21", median21_box_func );
01520         AFNI_register_2D_function( "Winsor21", winsor21_box_func );
01521 
01522         AFNI_register_2D_function( "|FFT2D|", fft2D_func );
01523 
01524         /* 01 Feb 2000: see afni_fimfunc.c */
01525 
01526         AFNI_register_fimfunc("Spearman CC",1,(generic_func *)spearman_fimfunc,NULL);
01527         AFNI_register_fimfunc("Quadrant CC",1,(generic_func *)quadrant_fimfunc,NULL);
01528 
01529         /* 31 Jan 2002 */
01530 
01531         AFNI_register_slice_proj( "Minimum" , min_proj   ) ;
01532         AFNI_register_slice_proj( "Maximum" , max_proj   ) ;
01533         AFNI_register_slice_proj( "Mean"    , mean_proj  ) ;
01534 
01535         AFNI_register_slice_proj( "Median"  , qmed_float ) ; /* in cs_qmed.c */
01536 
01537         AFNI_register_slice_proj( "Extreme" , extreme_proj ) ; /* 02 Feb 2002 */
01538 
01539 #ifdef HUBERIZE
01540         AFNI_register_1D_funcstr( "Huber Fit" , huber_func ) ;
01541 #endif
01542 
01543         /** plugins at last! **/
01544 
01545 #ifdef ALLOW_PLUGINS
01546         if( MAIN_im3d->type == AFNI_3DDATA_VIEW ){
01547           int nplug = 0 ;
01548           char str[128] ;
01549 
01550           if( ! GLOBAL_argopt.noplugins ){
01551 STATUS("initialize plugins") ;
01552             GLOBAL_library.plugins = PLUG_get_many_plugins( MAIN_argv[0] ) ;
01553             AFNI_plugin_button( MAIN_im3d ) ;
01554           }
01555 
01556           if( GLOBAL_library.plugins != NULL ) nplug = GLOBAL_library.plugins->num ;
01557           sprintf(str,"\n Plugins       = %d libraries read",nplug) ;
01558           REPORT_PROGRESS(str) ;
01559           if( nplug == 0 && ! GLOBAL_argopt.noplugins )  /* 18 May 2005 */
01560             REPORT_PROGRESS(
01561                       "\n ** Your Unix path must include the AFNI binary directory"
01562                       "\n ** OR you must setenv AFNI_PLUGINPATH to that directory!");
01563 
01564           /** and plugouts! **/
01565 
01566           if( !GLOBAL_argopt.noplugouts ){  /* June 1997 */
01567             AFNI_init_plugouts() ;
01568             if( MAIN_im3d->vwid->dmode->misc_plugout_pb != NULL ) /* 07 Nov 2001 */
01569               XtSetSensitive(MAIN_im3d->vwid->dmode->misc_plugout_pb,False) ;
01570             REPORT_PROGRESS("\n Plugouts      = listening for connections") ;
01571           }
01572         }
01573 #endif
01574 
01575       }
01576       break ;
01577 
01578       /*============================================================================
01579          Next, do the initial setup on entering the initial view.
01580         ============================================================================*/
01581 
01582       case 14:{
01583 
01584 STATUS("call 14") ;
01585 
01586         OPEN_CONTROLLER( MAIN_im3d ) ;
01587 
01588         AFNI_initialize_controller( MAIN_im3d ) ;  /* decide what to see */
01589         AFNI_initialize_view( NULL , MAIN_im3d ) ; /* set up to see it */
01590 
01591         /*--- Other small and quick startup stuff before AFNI can go ---*/
01592 
01593         MCW_help_CB( MAIN_im3d->vwid->top_shell,NULL,NULL ); /* initialize help */
01594 
01595         { char str[64] ;
01596           sprintf(str,"\n -orient       = %s", GLOBAL_library.cord.orcode ) ;
01597           REPORT_PROGRESS(str) ;
01598         }
01599 
01600         /* initialize hints */
01601 
01602         GLOBAL_library.hints_on = !AFNI_noenv("AFNI_HINTS") ;
01603         if( !GLOBAL_library.hints_on ) MCW_hint_toggle() ;
01604 
01605         if( MAIN_im3d->vwid->dmode->misc_hints_pb != NULL )
01606            MCW_set_bbox( MAIN_im3d->vwid->dmode->misc_hints_bbox ,
01607                          GLOBAL_library.hints_on ) ;
01608 
01609         /* Feb 1998: setup write compression from environment */
01610         /*           (read de-compression always works)       */
01611 
01612         ii = THD_enviro_write_compression() ;
01613         if( ii >= 0 && ii <= COMPRESS_LASTCODE ){
01614            char str[64] ;
01615            sprintf(str,"\n write compress= %s", COMPRESS_enviro[ii]) ;
01616            REPORT_PROGRESS(str) ;
01617         }
01618 
01619         if( ALLOW_real_time > 0 )
01620            REPORT_PROGRESS("\nRT: realtime plugin is active") ;
01621 
01622         /* 23 Sep 2000: this function will be called 0.123 seconds
01623                         from now to initialize the window layouts  */
01624 
01625         if( GLOBAL_argopt.layout_fname != NULL &&
01626             MAIN_im3d->type == AFNI_3DDATA_VIEW   ){
01627 
01628           (void) XtAppAddTimeOut( MAIN_app , 123 ,
01629                                   AFNI_startup_layout_CB , GLOBAL_argopt.layout_fname ) ;
01630 
01631           nodown = 1 ;  /* splashdown will be done in AFNI_startup_layout_CB */
01632         }
01633 
01634         /* 21 Jan 2003: this function will be called 0.246 seconds
01635                         from now to run the startup script, if any */
01636 
01637         if( GLOBAL_argopt.script_fname != NULL &&
01638             MAIN_im3d->type == AFNI_3DDATA_VIEW   ){
01639 
01640           (void) XtAppAddTimeOut( MAIN_app , 246 ,
01641                                   AFNI_startup_script_CB , GLOBAL_argopt.script_fname ) ;
01642         }
01643 
01644         /* this function will be called 1.234 seconds from now to finalize
01645            anything else that needs fixing up once AFNI is fully started   */
01646 
01647         PICTURE_ON(MAIN_im3d) ;
01648         (void) XtAppAddTimeOut( MAIN_app, 1234, AFNI_startup_timeout_CB, MAIN_im3d ) ;
01649 
01650         (void) TRUST_host(NULL) ; /* 21 Feb 2001: initialize trust mechanism */
01651 
01652         /* see if there is an initial FIM ideal timeseries */
01653 
01654         { char *eee = getenv( "AFNI_FIM_IDEAL" ) ;
01655           static MRI_IMAGE *tsim ;
01656           tsim = mri_read_1D( eee ) ;
01657           if( tsim != NULL ){
01658             float *far = MRI_FLOAT_PTR(tsim) ; int ii ; char *tname ;
01659             for( ii=0 ; ii < tsim->nvox ; ii++ )
01660                if( fabs(far[ii]) >= 33333.0 ) far[ii] = WAY_BIG ;
01661             tname = THD_trailname(eee,1) ;
01662             mri_add_name( tname , tsim ) ;
01663             AFNI_fimmer_setref( MAIN_im3d , tsim ) ;
01664           }
01665         }
01666 
01667         REPORT_PROGRESS("\n") ;
01668       }
01669       break ;
01670 
01671       /*============================================================================*/
01672 #if 0
01673       case 15:{  /* not used at present, but ready to be added when needed */
01674 STATUS("call 15") ;
01675       }
01676       break ;
01677 #endif
01678    }
01679 
01680    MAIN_calls++ ; RETURN(False) ;
01681 }
01682 
01683 /*-------------------------------------------------------------------------*/
01684 
01685 void FatalError(char * str)
01686 {
01687    fprintf(stderr,"\n**** Fatal Error ****\n %s\n",str) ;
01688    sleep(1) ; exit(1) ;
01689 }
01690 
01691 /*-------------------------------------------------------------------------*/
01692 
01693 static char * random_goodbye(void)
01694 {
01695    static char *bye[] = { "[[volm 0.64]] Farewell",
01696                           "[[volm 0.64]] Goodbye" ,
01697                           "[[volm 0.64]] Until next time" } ;
01698    int nn = sizeof(bye)/sizeof(char *) ;
01699    return bye[ lrand48() % nn ] ;
01700 }
01701 
01702 /*-------------------------------------------------------------------------
01703    Callback for the quit button.  If called with the widget == NULL,
01704    resets the button to the lowercase state.
01705 ---------------------------------------------------------------------------*/
01706 
01707 void AFNI_quit_CB( Widget wcall , XtPointer cd , XtPointer cbs )
01708 {
01709    Three_D_View * im3d = (Three_D_View *) cd ;
01710    XmPushButtonCallbackStruct * pbcbs = (XmPushButtonCallbackStruct *) cbs ;
01711 
01712 ENTRY("AFNI_quit_CB") ;
01713 
01714    if( ! IM3D_OPEN(im3d) ) EXRETURN ;
01715 
01716    /* NULL widget --> reset button to lowercase */
01717 
01718    if( wcall == NULL ){
01719       if( im3d->vwid->prog->quit_first == False ){
01720          MCW_set_widget_label( im3d->vwid->prog->quit_pb , "done " ) ;
01721          im3d->vwid->prog->quit_first = True ;
01722          if( im3d->vwid->picture != NULL && !GLOBAL_argopt.keep_logo )
01723            PICTURE_OFF( im3d ) ;
01724       }
01725       EXRETURN ;
01726    }
01727 
01728    /* Press of button with Shift or Control key pressed --> Death Now */
01729 
01730    if( pbcbs != NULL                       &&
01731        pbcbs->event != NULL                &&
01732        pbcbs->event->type == ButtonRelease &&
01733        ((XButtonEvent *)(pbcbs->event))->state &  /* note single & here! */
01734        (ShiftMask|ControlMask|Button2Mask|Button3Mask) ){
01735 
01736       XtCloseDisplay( XtDisplay(im3d->vwid->top_shell) ) ;
01737       AFNI_speak(random_goodbye(),0) ;
01738       exit(0) ;
01739    }
01740 
01741    /* First press --> just change button label */
01742 
01743    if( wcall == im3d->vwid->prog->quit_pb && im3d->vwid->prog->quit_first ){
01744       MCW_set_widget_label( im3d->vwid->prog->quit_pb , "DONE " ) ;
01745       im3d->vwid->prog->quit_first = False ;
01746       if( im3d->vwid->picture != NULL ) PICTURE_ON( im3d ) ;
01747 
01748       /* if not re-pressed in 5 seconds, will reset to lowercase */
01749 
01750       (void) XtAppAddTimeOut(
01751                XtWidgetToApplicationContext(im3d->vwid->prog->quit_pb) ,
01752                5000 , AFNI_quit_timeout_CB , im3d ) ;
01753 
01754       EXRETURN ;
01755    }
01756 
01757    /* close window callback OR button already uppercase --> close window */
01758 
01759    /* if no controller windows will be left, exit the program */
01760 
01761    if( AFNI_count_controllers() <= 1 ){
01762       XtCloseDisplay( XtDisplay(im3d->vwid->top_shell) ) ;
01763       AFNI_speak(random_goodbye(),0) ;
01764       STATUS("calling exit(0) -- farewell cruel world!") ;
01765       exit(0) ;
01766 
01767    } else {  /* otherwise, patch up the other windows and continue */
01768 
01769       CLOSE_CONTROLLER(im3d) ;     /* close window */
01770       AFNI_controller_clonify() ;  /* let other controllers know */
01771    }
01772    EXRETURN ;
01773 }
01774 
01775 /*----------------------------------------------------------------------
01776   Timeout routine to change 'DONE' button label back to 'done'
01777   after 5 seconds have passed.
01778 ------------------------------------------------------------------------*/
01779 
01780 void AFNI_quit_timeout_CB( XtPointer client_data , XtIntervalId * id )
01781 {
01782    Three_D_View * im3d = (Three_D_View *) client_data ;
01783 ENTRY("AFNI_quit_timeout_CB") ;
01784    RESET_AFNI_QUIT(im3d) ;
01785    EXRETURN ;
01786 }
01787 
01788 /*----------------------------------------------------------------------
01789   This function is called about 1 s after AFNI startup is completed.
01790   It's original purpose was to make sure that the help window was
01791   popped down - the help initializing routine does this, too, but
01792   it didn't work properly on the old Tektronix X-terminal at MCW.
01793   Thus, the timeout - waiting a little made things work OK.
01794 ------------------------------------------------------------------------*/
01795 
01796 void AFNI_startup_timeout_CB( XtPointer client_data , XtIntervalId * id )
01797 {
01798    Three_D_View * im3d = (Three_D_View *) client_data ;
01799    int vv ;
01800 
01801 ENTRY("AFNI_startup_timeout_CB") ;
01802 
01803    /* make sure help window is popped down */
01804 
01805    MCW_help_CB(NULL,NULL,NULL) ;
01806 
01807    /* NIML listening on [moved here 17 Mar 2002] */
01808 
01809    if( MAIN_im3d->type == AFNI_3DDATA_VIEW && GLOBAL_argopt.yes_niml ){
01810      AFNI_init_niml() ;
01811      XtSetSensitive(MAIN_im3d->vwid->dmode->misc_niml_pb,False) ;
01812    } else if( GLOBAL_argopt.port_niml > 0 ){  /* 10 Dec 2002 */
01813      fprintf(stderr,"*** WARNING: -np was given, but NIML is turned off.\n") ;
01814    }
01815 
01816    if( !AFNI_noenv("AFNI_STARTUP_WARNINGS") ){  /* 22 Jul 2003 */
01817 
01818 #ifdef LESSTIF_VERSION /* 13 Jan 2003: If LessTif was used for this AFNI */
01819 
01820     (void) MCW_popup_message( MAIN_im3d->vwid->picture ,
01821                                  " \n"
01822                                  "*** WARNING:                ***\n"
01823                                  "*** This  copy of AFNI  was ***\n"
01824                                  "*** built using the LessTif ***\n"
01825                                  "*** library.  You will find ***\n"
01826                                  "*** problems;  AFNI is best ***\n"
01827                                  "*** when built using  Motif ***\n"
01828                                  "*** or OpenMotif!           ***\n" ,
01829                               MCW_USER_KILL | MCW_TIMER_KILL ) ;
01830 #endif
01831 
01832 #ifdef BAD_BUTTON3_POPUPS /* 21 Jul 2003: If this is a stupid system */
01833 
01834     (void) MCW_popup_message( MAIN_im3d->vwid->imag->topper,
01835                               " \n"
01836                               "*** WARNING:                  ***\n"
01837                               "*** This computer system has  ***\n"
01838                               "*** a bug with Button-3 popup ***\n"
01839                               "*** menus -- to use a button  ***\n"
01840                               "*** on such a menu, you have  ***\n"
01841                               "*** to keep Button-3 pressed  ***\n"
01842                               "*** down and then click the   ***\n"
01843                               "*** menu button with Button-1 ***\n"
01844                               "*** at the same time.         ***\n" ,
01845                               MCW_USER_KILL | MCW_TIMER_KILL ) ;
01846 #endif
01847    }
01848 
01849    /* 21 Nov 2002: check the AFNI version */
01850 
01851    vv = AFNI_version_check() ; /* nada if AFNI_start_version_check() inactive */
01852 
01853    if( vv && vers_pixmap != XmUNSPECIFIED_PIXMAP ){     /* 08 Aug 2005 */
01854      int pp ;
01855      for( pp=0 ; pp < 19 ; pp++ ){   /* and flash it a few times */
01856        PICTURE_SET(im3d,vers_pixmap) ;
01857          XmUpdateDisplay(im3d->vwid->top_shell); iochan_sleep(166);
01858        PICTURE_OFF(im3d) ;
01859          XmUpdateDisplay(im3d->vwid->top_shell); iochan_sleep(166);
01860      }
01861      logo_pixmap = vers_pixmap ;     /* replace logo with version warning */
01862    }
01863 
01864 #ifdef SHSTRING
01865    if( vv ){  /* 20 Nov 2003: if version check shows a mismatch */
01866      char *sname = AFNI_make_update_script() ;
01867 
01868      if( sname != NULL ){
01869        char *cpt , *ddd ; int nn ;
01870        ddd = strdup(sname) ; cpt = THD_trailname(ddd,0) ; *cpt = '\0' ;
01871        cpt = THD_trailname(sname,0) ;
01872        fprintf(stderr,
01873                "\n"
01874                "*===================================================\n"
01875                "* A script to update AFNI binaries has been created.\n"
01876                "* To use it, quit AFNI now, then try the commands\n"
01877                "pushd %s\n"
01878                "source %s\n"
01879                "popd\n"
01880                "*===================================================\n" ,
01881                ddd , cpt ) ;
01882        free((void *)ddd) ;
01883        nn = THD_freemegabytes(sname) ;
01884        if( nn >= 0 && nn <= 300 ){
01885          fprintf(stderr,
01886                "* HOWEVER: you only have %d Mbytes free, which won't\n"
01887                "*          won't be enough to download and install\n"
01888                "*          the updated set of AFNI binaries!\n"
01889                "*===================================================\n" ,
01890                nn ) ;
01891        }
01892      } else {
01893        fprintf(stderr,
01894                "\n"
01895                "*==================================================\n"
01896                "* Can't create script for updating AFNI\n"
01897                "*   binaries in your AFNI directory.\n"
01898                "* You'll have to get your sysadmin to help, or\n"
01899                "*   do it yourself.  AFNI can be downloaded from\n"
01900                "*     http://afni.nimh.nih.gov/afni/download   *OR*\n"
01901                "*     ftp://afni.nimh.nih.gov/tgz\n"
01902                "*   You want file " SHSTRING ".tgz\n"
01903                "*==================================================\n" ) ;
01904      }
01905    }
01906 #endif
01907 
01908    /* finish up getting AFNI ready to be presented to the world */
01909 
01910    SHOW_AFNI_READY ;
01911    RESET_AFNI_QUIT(im3d) ;
01912    PICTURE_OFF(im3d) ;
01913 
01914    /* 29 Jul 2005: run any driver commands from the command line */
01915 
01916    for( vv=0 ; vv < COM_num ; vv++ ) AFNI_driver( COM_com[vv] ) ;
01917 
01918    MPROBE ;                       /* check mcw_malloc() for integrity */
01919    EXRETURN ;
01920 }
01921 
01922 /*----------------------------------------------------------------------
01923    routine to extract a plane of data from a 3D brick
01924    (used as a "get_image" routine for an MCW_imseq)
01925 ------------------------------------------------------------------------*/
01926 
01927 XtPointer AFNI_brick_to_mri( int n , int type , FD_brick * br )
01928 {
01929    MRI_IMAGE * im ;
01930    MCW_imseq_status * stat ;
01931    int i1,i2,jb,bb , dd1,dd2,tt1,tt2 ;
01932 
01933 ENTRY("AFNI_brick_to_mri") ;
01934 
01935 if(PRINT_TRACING){ char str[256] ; sprintf(str,"n=%d type=%d",n,type) ; STATUS(str) ; }
01936 
01937    /*-------------------------------------------------*/
01938    /*-------- May 1996: graph callbacks first --------*/
01939 
01940    if( type == graCR_getstatus ){
01941       MCW_grapher_status * grstat = myXtNew( MCW_grapher_status ) ;
01942 
01943       grstat->num_total  = grstat->num_series = br->dset->dblk->nvals ;
01944       grstat->nx         = br->n1 ;
01945       grstat->ny         = br->n2 ;
01946       grstat->nz         = br->n3 ;
01947 
01948       grstat->send_CB    = AFNI_gra_send_CB ;
01949       grstat->parent     = (XtPointer) br ;
01950       grstat->aux        = NULL ;
01951 
01952       grstat->transforms0D = & (GLOBAL_library.registered_0D) ;
01953       grstat->transforms1D = & (GLOBAL_library.registered_1D) ;
01954 
01955       strcpy( grstat->namecode , br->namecode ) ;
01956 
01957       RETURN( (XtPointer) grstat ) ;
01958    }
01959 
01960    if( type == graCR_getseries ){
01961       im = FD_brick_to_series( n , br ) ;
01962       RETURN( (XtPointer) im ) ;
01963    }
01964 
01965    /*----------------------------------------*/
01966    /*-------- Now do imseq callbacks --------*/
01967 
01968    if( n < 0 || n >= br->n3 ) RETURN(NULL) ;
01969 
01970    /*--- overlay # n ---*/
01971 
01972    if( type == isqCR_getoverlay  ){
01973       Three_D_View * im3d = (Three_D_View *) br->parent ;
01974 
01975 STATUS("get overlay") ;
01976 
01977       im = AFNI_overlay( n , br ) ;
01978       if( !AFNI_noenv("AFNI_VALUE_LABEL") ) AFNI_do_bkgd_lab( im3d ) ;
01979       RETURN( (XtPointer) im ) ;
01980    }
01981 
01982    /*--- status ---*/
01983 
01984    if( type == isqCR_getstatus ){
01985 
01986 STATUS("get status") ;
01987 
01988       stat = myXtNew( MCW_imseq_status ) ;
01989 
01990       stat->num_total  = br->n3 ;
01991       stat->num_series = br->n3 ;
01992       stat->send_CB    = AFNI_seq_send_CB ;
01993       stat->parent     = (XtPointer) br ;
01994       stat->aux        = NULL ;
01995 
01996       stat->transforms0D = & (GLOBAL_library.registered_0D) ;
01997       stat->transforms2D = & (GLOBAL_library.registered_2D) ;
01998       stat->slice_proj   = & (GLOBAL_library.registered_slice_proj) ;
01999 
02000       RETURN( (XtPointer) stat ) ;
02001    }
02002 
02003    /*--- 26 Feb 2001: return a memplot drawing struct ---*/
02004    /*--- 22 Mar 2002: add crosshairs to surface stuff ---*/
02005 
02006 #define RX 0.2
02007    if( type == isqCR_getmemplot ){
02008      Three_D_View *im3d = (Three_D_View *) br->parent ;
02009      int do_xhar=(im3d->vinfo->crosshair_visible && AFNI_yesenv("AFNI_CROSSHAIR_LINES"));
02010      int do_surf;
02011      MEM_plotdata *mp ;
02012      AFNI_surface_widgets *swid = im3d->vwid->view->swid ;  /* 19 Aug 2002 */
02013      THD_session *suss=im3d->ss_now ;                       /* 20 Jan 2004 */
02014      THD_dataxes *daxes=CURRENT_DAXES(br->dset) ;
02015 
02016      if( !IM3D_OPEN(im3d) )     RETURN(NULL) ;
02017 
02018      /* 20 Jan 2004: surfaces are now in the session, not on the dataset! */
02019 
02020      do_surf = SUMA_ENABLED && SESSION_HAS_SUMA(suss) ;
02021      if( !do_surf && !do_xhar ) RETURN(NULL) ;  /* nothing to do */
02022 
02023      /* get ready to plot */
02024 
02025 STATUS("creating memplot for image overlay") ;
02026      create_memplot_surely( "SUMA_plot" , 1.0 ) ;
02027      mp = get_active_memplot() ;
02028 
02029      /* plot surface stuff, if any */
02030 
02031     if( do_surf ){
02032      int ks ;
02033      int kbest=-1 , ibest=-1 ;          /* 24 Feb 2003 */
02034 
02035      AFNI_get_xhair_node( im3d , &kbest , &ibest ) ;   /* 24 Feb 2003 */
02036 
02037      for( ks=0 ; ks < suss->su_num ; ks++ ){  /* 14 Aug 2002: loop over surfaces */
02038       SUMA_surface *ag = suss->su_surf[ks] ;
02039       int nn , ii,jj ;
02040       SUMA_ixyz *nod ;
02041       THD_ivec3 iv,ivp,ivm ;
02042       THD_fvec3 fv,fvp,fvm ;
02043       float s1=1.0/br->n1 , s2=1.0/br->n2 , dxyz ;
02044       float rr_box=1.0,gg_box=0.0,bb_box=0.0 ;   /* white */
02045       float rr_lin=0.4,gg_lin=0.0,bb_lin=0.7 ;   /* dark blue */
02046       float rr_led=1.0,gg_led=0.0,bb_led=0.0 ;
02047       char str[32] , *eee ;
02048       float rx=RX ;         /* default rectangle halfsize */
02049       int   kkk=0 ;
02050       float xyz=0.0,xyzp,xyzm , rxm,rxp ;
02051       int skip_boxes=1 , skip_lines=0 , skip_lcen=0, skip_ledg=1 ;
02052       float boxsize=RX , linewidth=0.0 ;      /* 23 Feb 2003 */
02053       int firstb ;                            /* 23 Jan 2004 */
02054 
02055       if( ag == NULL ) continue ;             /* skip this non-existent one */
02056       nn = ag->num_ixyz ; nod = ag->ixyz ;
02057       if( nn < 1 || nod == NULL ) continue ;  /* nothing to do */
02058 
02059       /* define parameters for node boxes and triangle lines */
02060 
02061 STATUS("defining surface drawing parameters") ;
02062       if( swid != NULL && ks < swid->nrow ){     /* 19 Aug 2002: the new way */
02063         int cc, dd ;                             /*           to set colors: */
02064                                                  /* from the surface widgets */
02065 
02066         cc = MCW_val_bbox(swid->surf_bbox[ks]) ; /* 19 Feb 2003: skip it all? */
02067         if( cc == 0 ){
02068           skip_boxes = skip_lines = 1 ;
02069         } else {                                 /* see what is turned on */
02070           cc = swid->surf_node_av[ks]->ival ;
02071           skip_boxes = (cc == 0) ;
02072           if( !skip_boxes ){
02073             rr_box = DCOV_REDBYTE(im3d->dc,cc)   / 255.0 ;
02074             gg_box = DCOV_GREENBYTE(im3d->dc,cc) / 255.0 ;
02075             bb_box = DCOV_BLUEBYTE(im3d->dc,cc)  / 255.0 ;
02076           }
02077           cc = swid->surf_line_av[ks]->ival ;
02078           dd = swid->surf_ledg_av[ks]->ival ;             /* 26 Feb 2003 */
02079           skip_lcen  = (cc == 0) ;
02080           skip_ledg  = (dd == 0) ;
02081           skip_lines = (skip_lcen && skip_ledg) ;
02082           if( cc > 0 ){
02083             rr_lin = DCOV_REDBYTE(im3d->dc,cc)   / 255.0 ;
02084             gg_lin = DCOV_GREENBYTE(im3d->dc,cc) / 255.0 ;
02085             bb_lin = DCOV_BLUEBYTE(im3d->dc,cc)  / 255.0 ;
02086           }
02087           if( dd > 0 ){                                   /* 26 Feb 2003 */
02088             rr_led = DCOV_REDBYTE(im3d->dc,dd)   / 255.0 ;
02089             gg_led = DCOV_GREENBYTE(im3d->dc,dd) / 255.0 ;
02090             bb_led = DCOV_BLUEBYTE(im3d->dc,dd)  / 255.0 ;
02091           }
02092           boxsize   = swid->boxsize_av->ival   * 0.1   ;  /* 23 Feb 2003 */
02093           linewidth = swid->linewidth_av->ival * 0.002 ;
02094         }
02095 
02096       } else {                                   /* the old way    */
02097                                                  /* to set colors:  */
02098         eee = getenv("AFNI_SUMA_BOXCOLOR") ;     /* from environment */
02099         if( eee != NULL ){
02100           if( strcmp(eee,"none") == 0 || strcmp(eee,"skip") == 0 )
02101             skip_boxes = 1 ;                  /* don't do boxes */
02102           else
02103             DC_parse_color( im3d->dc , eee , &rr_box,&gg_box,&bb_box ) ;
02104         }
02105 
02106         eee = getenv("AFNI_SUMA_LINECOLOR") ;
02107         if( eee != NULL ){
02108           if( (strcmp(eee,"none")==0 || strcmp(eee,"skip")==0) )
02109             skip_lines = 1 ;
02110           else
02111             DC_parse_color( im3d->dc , eee , &rr_lin,&gg_lin,&bb_lin ) ;
02112         }
02113 
02114         eee = getenv("AFNI_SUMA_BOXSIZE") ;  /* maybe set boxsize? */
02115         if( eee != NULL ){
02116           float val=strtod(eee,NULL) ;
02117           if( val > 0.0 ) boxsize = val ;
02118         } else if( swid != NULL ){
02119           boxsize = swid->boxsize_av->ival * 0.1 ;
02120         }
02121 
02122         eee = getenv( "AFNI_SUMA_LINESIZE" ) ; /* maybe set linewidth? */
02123         if( eee != NULL ){
02124           float val = strtod(eee,NULL) ;
02125           if( val < 0.0 || val > 0.1 ) val = 0.0 ;
02126           linewidth = val ;
02127         } else if( swid != NULL ){
02128           linewidth = swid->linewidth_av->ival * 0.002 ;
02129         }
02130       }
02131 
02132       if( skip_boxes && skip_lines ) continue ; /* nothing to do? */
02133 
02134       /** 21 Mar 2002:
02135           We calculate plotting coordinates in "fdfind" coordinates,
02136           which are floating point indexes into the FD_brick.  However,
02137           these run from 0..n1-1 (in x), which are the centers of the
02138           voxels.  In turn these must be mapped to screen locations.
02139           For example, with n1=5, we have these voxels
02140 
02141               0   1   2   3   4    = index of voxel
02142             ---------------------
02143             |   |   |   |   |   |
02144             ---------------------
02145            0.0                 1.0 = screen coordinate (for memplot)
02146 
02147           Thus voxel index i maps to screen location (i+0.5)/n1.
02148           Previously, I forgot the +0.5, which didn't matter much,
02149           until the introduction of the image zoom feature last week. **/
02150 
02151       rx  = boxsize ;                /* 23 Feb 2003 */
02152       rxm = rx-0.5 ; rxp = rx+0.5 ;  /* The 0.5 voxel shift */
02153 
02154       /* find DICOM coordinates of next slice and previous slice */
02155 
02156       LOAD_IVEC3(iv,0,0,n+1) ;                     /* next */
02157       ivp = THD_fdind_to_3dind( br , iv ) ;
02158       fvp = THD_3dind_to_3dmm ( br->dset , ivp ) ;
02159       fvp = THD_3dmm_to_dicomm( br->dset , fvp ) ;
02160       LOAD_IVEC3(iv,0,0,n-1) ;                     /* previous */
02161       ivm = THD_fdind_to_3dind( br , iv ) ;
02162       fvm = THD_3dind_to_3dmm ( br->dset , ivm ) ;
02163       fvm = THD_3dmm_to_dicomm( br->dset , fvm ) ;
02164 
02165       /* threshold for determining which axis this slice is along */
02166 
02167       dxyz = MIN(br->del1,br->del2) ;
02168       dxyz = MIN(dxyz    ,br->del3) ; dxyz *= 0.1 ;
02169 
02170       set_color_memplot(rr_box,gg_box,bb_box) ;  /* box drawing colors */
02171       set_thick_memplot(0.0) ;
02172       firstb = 1 ;                               /* 23 Jan 2004 */
02173 
02174       /* find nodes inside this slice */
02175 
02176       if( skip_boxes ) STATUS("finding slice planes") ;
02177       else             STATUS("drawing node boxes") ;
02178 
02179       if( fabs(fvm.xyz[0]-fvp.xyz[0]) > dxyz ){               /* search x */
02180          float xb=fvm.xyz[0] , xt=fvp.xyz[0] , xm,xw ;        /* range of  */
02181          if( xb > xt ){ float t=xb ; xb=xt ; xt=t ; }         /* x in slice */
02182          xm = 0.5*(xb+xt); xw = 0.25*(xt-xb); xb = xm-xw; xt = xm+xw;
02183 STATUS(" - x plane") ;
02184          if( !skip_boxes ){
02185           for( ii=0 ; ii < nn ; ii++ ){
02186             if( nod[ii].x >= xb && nod[ii].x <= xt ){         /* inside?  */
02187                LOAD_FVEC3(fv,nod[ii].x,nod[ii].y,nod[ii].z) ; /* convert  */
02188                fv = THD_dicomm_to_3dmm( br->dset , fv ) ;     /* coords   */
02189                fv = THD_3dmm_to_3dfind( br->dset , fv ) ;     /* to slice */
02190                fv = THD_3dfind_to_fdfind( br , fv ) ;         /* indexes  */
02191 
02192                if( firstb ){
02193                  plotline_memplot( s1*(fv.xyz[0]-rxm), 1.0-s2*(fv.xyz[1]-rxm),
02194                                    s1*(fv.xyz[0]+rxp), 1.0-s2*(fv.xyz[1]+rxp)  );
02195                  firstb = 0 ;
02196                }
02197 
02198                plotrect_memplot( s1*(fv.xyz[0]-rxm), 1.0-s2*(fv.xyz[1]-rxm),
02199                                  s1*(fv.xyz[0]+rxp), 1.0-s2*(fv.xyz[1]+rxp)  ) ;
02200 
02201                if( ks == kbest && nod[ii].id == ibest ){   /* 24 Feb 2003 */
02202                  plotline_memplot( s1*(fv.xyz[0]-rxm), 1.0-s2*(fv.xyz[1]-rxm),
02203                                    s1*(fv.xyz[0]+rxp), 1.0-s2*(fv.xyz[1]+rxp)  );
02204                  plotline_memplot( s1*(fv.xyz[0]-rxm), 1.0-s2*(fv.xyz[1]+rxp),
02205                                    s1*(fv.xyz[0]+rxp), 1.0-s2*(fv.xyz[1]-rxm)  );
02206                  plotline_memplot( s1*(fv.xyz[0]-rxm), 1.0-s2*(fv.xyz[1]+0.5),
02207                                    s1*(fv.xyz[0]+rxp), 1.0-s2*(fv.xyz[1]+0.5)  );
02208                  plotline_memplot( s1*(fv.xyz[0]+0.5), 1.0-s2*(fv.xyz[1]-rxm),
02209                                    s1*(fv.xyz[0]+0.5), 1.0-s2*(fv.xyz[1]+rxp)  );
02210                }
02211             }
02212           }
02213          }
02214          kkk = 0; xyz = xm; xyzp = xt; xyzm = xb;  /* for the triangles/lines below */
02215       }
02216       else if( fabs(fvm.xyz[1]-fvp.xyz[1]) > dxyz ){          /* search y */
02217          float yb=fvm.xyz[1] , yt=fvp.xyz[1] , ym,yw ;
02218          if( yb > yt ){ float t=yb ; yb=yt ; yt=t ; }
02219          ym = 0.5*(yb+yt); yw = 0.25*(yt-yb); yb = ym-yw; yt = ym+yw;
02220 STATUS(" - y plane") ;
02221          if( !skip_boxes ){
02222           for( ii=0 ; ii < nn ; ii++ ){
02223             if( nod[ii].y >= yb && nod[ii].y <= yt ){
02224                LOAD_FVEC3(fv,nod[ii].x,nod[ii].y,nod[ii].z) ;
02225                fv = THD_dicomm_to_3dmm( br->dset , fv ) ;
02226                fv = THD_3dmm_to_3dfind( br->dset , fv ) ;
02227                fv = THD_3dfind_to_fdfind( br , fv ) ;
02228 
02229                if( firstb ){
02230                  plotline_memplot( s1*(fv.xyz[0]-rxm), 1.0-s2*(fv.xyz[1]-rxm),
02231                                    s1*(fv.xyz[0]+rxp), 1.0-s2*(fv.xyz[1]+rxp)  );
02232                  firstb = 0 ;
02233                }
02234 
02235                plotrect_memplot( s1*(fv.xyz[0]-rxm), 1.0-s2*(fv.xyz[1]-rxm),
02236                                  s1*(fv.xyz[0]+rxp), 1.0-s2*(fv.xyz[1]+rxp)  ) ;
02237 
02238                if( ks == kbest && nod[ii].id == ibest ){   /* 24 Feb 2003 */
02239                  plotline_memplot( s1*(fv.xyz[0]-rxm), 1.0-s2*(fv.xyz[1]-rxm),
02240                                    s1*(fv.xyz[0]+rxp), 1.0-s2*(fv.xyz[1]+rxp)  );
02241                  plotline_memplot( s1*(fv.xyz[0]-rxm), 1.0-s2*(fv.xyz[1]+rxp),
02242                                    s1*(fv.xyz[0]+rxp), 1.0-s2*(fv.xyz[1]-rxm)  );
02243                  plotline_memplot( s1*(fv.xyz[0]-rxm), 1.0-s2*(fv.xyz[1]+0.5),
02244                                    s1*(fv.xyz[0]+rxp), 1.0-s2*(fv.xyz[1]+0.5)  );
02245                  plotline_memplot( s1*(fv.xyz[0]+0.5), 1.0-s2*(fv.xyz[1]-rxm),
02246                                    s1*(fv.xyz[0]+0.5), 1.0-s2*(fv.xyz[1]+rxp)  );
02247                }
02248             }
02249           }
02250          }
02251          kkk = 1; xyz = ym; xyzp = yt; xyzm = yb;  /* for the triangles/lines below */
02252       }
02253       else if( fabs(fvm.xyz[2]-fvp.xyz[2]) > dxyz ){          /* search z */
02254          float zb=fvm.xyz[2] , zt=fvp.xyz[2] , zm,zw ;
02255          if( zb > zt ){ float t=zb ; zb=zt ; zt=t ; }
02256          zm = 0.5*(zb+zt); zw = 0.25*(zt-zb); zb = zm-zw; zt = zm+zw;
02257 STATUS(" - z plane") ;
02258          if( !skip_boxes ){
02259           for( ii=0 ; ii < nn ; ii++ ){
02260             if( nod[ii].z >= zb && nod[ii].z <= zt ){
02261                LOAD_FVEC3(fv,nod[ii].x,nod[ii].y,nod[ii].z) ;
02262                fv = THD_dicomm_to_3dmm( br->dset , fv ) ;
02263                fv = THD_3dmm_to_3dfind( br->dset , fv ) ;
02264                fv = THD_3dfind_to_fdfind( br , fv ) ;
02265 
02266                if( firstb ){
02267                  plotline_memplot( s1*(fv.xyz[0]-rxm), 1.0-s2*(fv.xyz[1]-rxm),
02268                                    s1*(fv.xyz[0]+rxp), 1.0-s2*(fv.xyz[1]+rxp)  );
02269                  firstb = 0 ;
02270                }
02271 
02272                plotrect_memplot( s1*(fv.xyz[0]-rxm), 1.0-s2*(fv.xyz[1]-rxm),
02273                                  s1*(fv.xyz[0]+rxp), 1.0-s2*(fv.xyz[1]+rxp)  ) ;
02274 
02275                if( ks == kbest && nod[ii].id == ibest ){   /* 24 Feb 2003 */
02276                  plotline_memplot( s1*(fv.xyz[0]-rxm), 1.0-s2*(fv.xyz[1]-rxm),
02277                                    s1*(fv.xyz[0]+rxp), 1.0-s2*(fv.xyz[1]+rxp)  );
02278                  plotline_memplot( s1*(fv.xyz[0]-rxm), 1.0-s2*(fv.xyz[1]+rxp),
02279                                    s1*(fv.xyz[0]+rxp), 1.0-s2*(fv.xyz[1]-rxm)  );
02280                  plotline_memplot( s1*(fv.xyz[0]-rxm), 1.0-s2*(fv.xyz[1]+0.5),
02281                                    s1*(fv.xyz[0]+rxp), 1.0-s2*(fv.xyz[1]+0.5)  );
02282                  plotline_memplot( s1*(fv.xyz[0]+0.5), 1.0-s2*(fv.xyz[1]-rxm),
02283                                    s1*(fv.xyz[0]+0.5), 1.0-s2*(fv.xyz[1]+rxp)  );
02284                }
02285             }
02286           }
02287          }
02288          kkk = 2; xyz = zm; xyzp = zt; xyzm = zb;  /* for the triangles/lines below */
02289       }
02290 
02291       /* 10 Mar 2002:
02292          For each triangle that crosses the plane of the slice,
02293          plot a line segment at the intersection of the plane and triangle.
02294          The plane is along DICOM axis #kkk at coordinate xyz;
02295          these variables were set just above in the node display code. */
02296 
02297       if( !skip_lines && ag->num_ijk > 0 && ag->ijk != NULL ){
02298         SUMA_ijk *tr = ag->ijk ;        /* triangle list  */
02299         int      ntr = ag->num_ijk ;    /* number of triangles */
02300         int id,jd,kd ;
02301         THD_fvec3 fvijk[3] ;
02302         float ci,cj,ck , xlev ;
02303         int ilev ;
02304 
02305         for( ilev=0 ; ilev <= 2 ; ilev++ ){  /* 26 Feb 2003: loop over levels: */
02306                                              /* slice center, top & bot edges  */
02307           if( ilev == 0 ){
02308             if( skip_lcen ) continue ;  /* don't do center plane */
02309             xlev = xyz ;
02310             set_color_memplot(rr_lin,gg_lin,bb_lin) ;  /* line drawing colors */
02311             set_thick_memplot(linewidth) ;
02312           } else {
02313             if( skip_ledg ) continue ;  /* don't do edge planes */
02314             xlev = (ilev == 1) ? xyzp : xyzm ;
02315             set_color_memplot(rr_led,gg_led,bb_led) ;
02316             set_thick_memplot(0.0) ;
02317           }
02318 
02319 STATUS("drawing triangle lines") ;
02320 
02321           /* loop over triangles */
02322 
02323           for( ii=0 ; ii < ntr ; ii++ ){
02324 
02325             /* get indexes of triangle's nodes (from their id's) */
02326 
02327             id = SUMA_find_node_id(ag,tr[ii].id); if( id < 0 ) continue;
02328             jd = SUMA_find_node_id(ag,tr[ii].jd); if( jd < 0 ) continue;
02329             kd = SUMA_find_node_id(ag,tr[ii].kd); if( kd < 0 ) continue;
02330 
02331             /* load DICOM coords of triangle's nodes */
02332 
02333             LOAD_FVEC3(fvijk[0], nod[id].x, nod[id].y, nod[id].z) ;
02334             LOAD_FVEC3(fvijk[1], nod[jd].x, nod[jd].y, nod[jd].z) ;
02335             LOAD_FVEC3(fvijk[2], nod[kd].x, nod[kd].y, nod[kd].z) ;
02336 
02337             /* want 1 node on one size of plane, and 2 on the other */
02338 
02339             ci = fvijk[0].xyz[kkk] - xlev;      /* differences from center */
02340             cj = fvijk[1].xyz[kkk] - xlev;      /* of current slice plane */
02341             ck = fvijk[2].xyz[kkk] - xlev;
02342             jj = 4*(ci > 0.0) + 2*(cj > 0.0) + (ck > 0.0) ;
02343             if( jj == 0 || jj == 7 ) continue ; /* all have same sign */
02344 
02345             /* setup id,jd,kd so fvijk[id] is on one side of plane,
02346                and so that fvijk[jd] and fvijk[kd] are on other side */
02347 
02348             switch( jj ){
02349                case 6:
02350                case 1: id = 2 ; jd = 0 ; kd = 1 ; break ;  /* kd is the 1 */
02351                case 5:
02352                case 2: id = 1 ; jd = 0 ; kd = 2 ; break ;  /* jd is the 1 */
02353                case 4:
02354                case 3: id = 0 ; jd = 1 ; kd = 2 ; break ;  /* id is the 1 */
02355             }
02356 
02357             /* linearly interpolate between fvijk[id] and fvijk[jd]
02358                to find the point where this line hits the slice plane */
02359 
02360             ci = fvijk[id].xyz[kkk] - xlev;
02361             cj = fvijk[id].xyz[kkk] - fvijk[jd].xyz[kkk] ;
02362             if( cj == 0.0 ) continue ;            /* should not happen */
02363             ck = ci / cj ;
02364             if( ck < 0.0 || ck > 1.0 ) continue ; /* should not happen */
02365             cj = 1.0 - ck ;
02366             fvp = SCLADD_FVEC3(cj,fvijk[id],ck,fvijk[jd]) ;
02367 
02368             /* linearly interpolate between fvijk[id] and fvijk[kd] */
02369 
02370             cj = fvijk[id].xyz[kkk] - fvijk[kd].xyz[kkk] ;
02371             if( cj == 0.0 ) continue ;
02372             ck = ci / cj ;
02373             if( ck < 0.0 || ck > 1.0 ) continue ;
02374             cj = 1.0 - ck ;
02375             fvm = SCLADD_FVEC3(cj,fvijk[id],ck,fvijk[kd]) ;
02376 
02377             /* transform interpolated points to FD_brick coords */
02378 
02379             fvp = THD_dicomm_to_3dmm( br->dset , fvp ) ;
02380             if( fvp.xyz[0] < daxes->xxmin ||
02381                 fvp.xyz[0] > daxes->xxmax ||
02382                 fvp.xyz[1] < daxes->yymin ||
02383                 fvp.xyz[1] > daxes->yymax ||
02384                 fvp.xyz[2] < daxes->zzmin ||
02385                 fvp.xyz[2] > daxes->zzmax   ) continue ;  /* 08 Jan 2004 */
02386             fvp = THD_3dmm_to_3dfind( br->dset , fvp ) ;
02387             fvp = THD_3dfind_to_fdfind( br , fvp ) ;
02388 
02389             fvm = THD_dicomm_to_3dmm( br->dset , fvm ) ;
02390             if( fvm.xyz[0] < daxes->xxmin ||
02391                 fvm.xyz[0] > daxes->xxmax ||
02392                 fvm.xyz[1] < daxes->yymin ||
02393                 fvm.xyz[1] > daxes->yymax ||
02394                 fvm.xyz[2] < daxes->zzmin ||
02395                 fvm.xyz[2] > daxes->zzmax   ) continue ;  /* 08 Jan 2004 */
02396             fvm = THD_3dmm_to_3dfind( br->dset , fvm ) ;
02397             fvm = THD_3dfind_to_fdfind( br , fvm ) ;
02398 
02399             /* plot a line segment between them, in the plane of the slice */
02400             /* [21 Mar 2002: include the 0.5 shift mentioned way up above] */
02401 
02402             plotline_memplot( s1*(fvp.xyz[0]+0.5) , 1.0-s2*(fvp.xyz[1]+0.5) ,
02403                               s1*(fvm.xyz[0]+0.5) , 1.0-s2*(fvm.xyz[1]+0.5)  ) ;
02404 
02405           } /* end of loop over triangles */
02406           set_thick_memplot(0.0) ;              /* 15 Jan 2003 */
02407         } /* end of loop over levels: 26 Feb 2003 */
02408       } /* end of if over doing lines */
02409      } /* end of loop over surface index ks */
02410     } /* end of plotting surface stuff */
02411 
02412      /*----- put crosshairs on with lines, if desired -----*/
02413      /****** 22 Mar 2002: adapted from pixel overlay  ******/
02414 
02415      if( do_xhar ){
02416       MCW_grapher * grapher = UNDERLAY_TO_GRAPHER(im3d,br) ;
02417 
02418       THD_ivec3 ib = THD_3dind_to_fdind( br ,
02419                                          TEMP_IVEC3( im3d->vinfo->i1 ,
02420                                                      im3d->vinfo->j2 ,
02421                                                      im3d->vinfo->k3  ) ) ;
02422 STATUS("drawing crosshairs") ;
02423       set_thick_memplot(0.0) ;
02424 
02425       if( n == ib.ijk[2] || im3d->vinfo->xhairs_all ){
02426          int jp,ip , jcen,icen , gappp , jj,ii ;
02427          int idown,iup,iskip , jdown,jup,jskip , imon,jmon ;
02428          int a1 = br->a123.ijk[0] ,   /* x axis of the brick?    */
02429              ax = abs(a1) - 1       ; /* 0,1,2 for dataset x,y,z */
02430          int a2 = br->a123.ijk[1] ,   /* y axis of the brick?    */
02431              ay = abs(a2) - 1       ; /* 0,1,2 for dataset x,y,z */
02432          int a3 = br->a123.ijk[2] ,   /* z axis of the brick?    */
02433              az = abs(a3) - 1       ; /* 0,1,2 for dataset x,y,z */
02434 
02435          int gap,icr,jcr , nx=br->n1 , ny=br->n2 ;
02436 
02437          float rr,gg,bb ;             /* colors */
02438          float s1=1.0/br->n1 , s2=1.0/br->n2 ;  /* scale pixels to plot coords */
02439 #define PSX(i) (s1*((i)+0.5))
02440 #define PSY(j) (1.0-s2*((j)+0.5))
02441 
02442          /* spatial orientations of image axes */
02443 
02444          int ox = (ax==0) ? br->dset->daxes->xxorient :
02445                   (ax==1) ? br->dset->daxes->yyorient : br->dset->daxes->zzorient ;
02446 
02447          int oy = (ay==0) ? br->dset->daxes->xxorient :
02448                   (ay==1) ? br->dset->daxes->yyorient : br->dset->daxes->zzorient ;
02449 
02450          jp = im3d->vinfo->crosshair_ovcolor ;
02451          rr = DCOV_REDBYTE  (im3d->dc,jp) / 255.0 ;
02452          gg = DCOV_GREENBYTE(im3d->dc,jp) / 255.0 ;
02453          bb = DCOV_BLUEBYTE (im3d->dc,jp) / 255.0 ;
02454          set_color_memplot(rr,gg,bb) ;
02455 
02456          gap  = (grapher==NULL) ? im3d->vinfo->crosshair_gap : (grapher->mat+1)/2 ;
02457 
02458          icen = ib.ijk[0] ;  /* x-index of image pixel at focus */
02459          jcen = ib.ijk[1] ;  /* y-index */
02460 
02461          /** initialize montage steps **/
02462 
02463          if( im3d->vinfo->xhairs_show_montage ){           /* in "Multi" mode */
02464             iskip = im3d->vinfo->xhairs_nskip.ijk[ax] + 1 ;
02465             jskip = im3d->vinfo->xhairs_nskip.ijk[ay] + 1 ;
02466             if( a1 > 0 ){
02467                idown = im3d->vinfo->xhairs_ndown.ijk[ax] ;
02468                iup   = im3d->vinfo->xhairs_nup.ijk[ax] ;
02469             } else {
02470                iup   = im3d->vinfo->xhairs_ndown.ijk[ax] ;
02471                idown = im3d->vinfo->xhairs_nup.ijk[ax] ;
02472             }
02473             if( a2 > 0 ){
02474                jdown = im3d->vinfo->xhairs_ndown.ijk[ay] ;
02475                jup   = im3d->vinfo->xhairs_nup.ijk[ay] ;
02476             } else {
02477                jup   = im3d->vinfo->xhairs_ndown.ijk[ay] ;
02478                jdown = im3d->vinfo->xhairs_nup.ijk[ay] ;
02479             }
02480 
02481          } else {                                          /* in "Single" Mode */
02482            idown = iup = jdown = jup = iskip = jskip = 0 ;
02483            if( grapher != NULL ){ idown=-(iup+1); jdown=-(jup+1); } /* skip lines? */
02484          }
02485 
02486          /* draw vertical lines first */
02487 
02488          if( (im3d->vinfo->xhairs_orimask & (1<<oy)) != 0 ){
02489            for( imon=-idown ; imon <= iup ; imon++ ){
02490              icr = icen + imon * iskip ;
02491 
02492              if( im3d->vinfo->xhairs_periodic ){
02493                 while( icr < 0 )   icr += nx ;
02494                 while( icr >= nx ) icr -= nx ;
02495              } else {
02496                 if( icr < 0 || icr >= nx ) continue ;
02497              }
02498 
02499              gappp = (abs(icr-icen) <= gap) ? gap : -1 ; /* no gap if far from center */
02500 
02501              if( gappp < 0 ){  /* no gap => 1 vertical line */
02502 
02503                 plotline_memplot( PSX(icr) , 0.0 , PSX(icr) , 1.0 ) ;
02504 
02505              } else {          /* gap => 2 vertical lines */
02506 
02507                 jj = jcen-gappp-1 ;
02508                 if( jj >= 0 )
02509                   plotline_memplot( PSX(icr) , 1.0 , PSX(icr) , PSY(jj+0.5) ) ;
02510 
02511                 jj = jcen+gappp+1 ;
02512                 if( jj < ny )
02513                   plotline_memplot( PSX(icr) , PSY(jj-0.5) , PSX(icr) , 0.0 ) ;
02514              }
02515 
02516            }
02517          }
02518 
02519          /* draw horizontal lines */
02520 
02521          if( (im3d->vinfo->xhairs_orimask & (1<<ox)) != 0 ){  /* 31 Dec 1998 */
02522            for( jmon=-jdown ; jmon <= jup ; jmon++ ){
02523              jcr = jcen + jmon * jskip ;
02524              if( im3d->vinfo->xhairs_periodic ){
02525                 while( jcr < 0 )   jcr += ny ;
02526                 while( jcr >= ny ) jcr -= ny ;
02527              } else {
02528                 if( jcr < 0 || jcr >= ny ) continue ;
02529              }
02530 
02531              gappp = (abs(jcr-jcen) <= gap) ? gap : -1 ; /* no gap if far from center */
02532 
02533              if( gappp < 0 ){  /* no gap => 1 horizontal line */
02534 
02535                 plotline_memplot( 0.0 , PSY(jcr) , 1.0 , PSY(jcr) ) ;
02536 
02537              } else {          /* gap => 2 horizontal lines */
02538 
02539                 ii = icen-gappp-1 ;
02540                 if( ii >= 0 )
02541                   plotline_memplot( 0.0 , PSY(jcr) , PSX(ii+0.5) , PSY(jcr) ) ;
02542 
02543                 ii = icen+gappp+1 ;
02544                 if( ii < nx )
02545                   plotline_memplot( PSX(ii-0.5) , PSY(jcr) , 1.0 , PSY(jcr) ) ;
02546              }
02547            }
02548          }
02549 
02550          /* draw grapher frame, if needed */
02551 
02552          if( grapher != NULL ){
02553             int gs = gap , gb = (grapher->mat +2)/2 ;
02554 
02555             jcr = jcen ; icr = icen ;
02556 
02557             ip = icr - gb ; if( ip < 0   ) ip = 0 ;
02558             ii = icr + gs ; if( ii >= nx ) ii = nx-1 ;
02559 
02560             jp = jcr - gb ; if( jp <  0  ) jp = 0 ;
02561             jj = jcr + gs ; if( jj >= ny ) jj = ny-1 ;
02562 
02563             plotline_memplot( PSX(ip+0.5),PSY(jp+0.5) , PSX(ii-0.5),PSY(jp+0.5) ) ;
02564             plotline_memplot( PSX(ii-0.5),PSY(jp+0.5) , PSX(ii-0.5),PSY(jj-0.5) ) ;
02565             plotline_memplot( PSX(ii-0.5),PSY(jj-0.5) , PSX(ip+0.5),PSY(jj-0.5) ) ;
02566             plotline_memplot( PSX(ip+0.5),PSY(jj-0.5) , PSX(ip+0.5),PSY(jp+0.5) ) ;
02567 
02568          } /* end if "if grapher exists" */
02569 
02570       } /* end of "if correct slice" (or do all slices) */
02571      } /* end of crosshairs */
02572 
02573      /*----- return the completed plot -----*/
02574 
02575      if( MEMPLOT_NLINE(mp) < 1 ) DESTROY_MEMPLOT(mp) ;
02576 
02577      RETURN(mp) ; /* will be destroyed in imseq */
02578    }
02579 
02580    /*--- 20 Sep 2001: image label ---*/
02581 
02582    if( type == isqCR_getlabel ){
02583       Three_D_View * im3d = (Three_D_View *) br->parent ;
02584       char *lab , str[32] , *dd ;
02585       THD_ivec3 iv,ivp,ivm ;
02586       THD_fvec3 fv,fvp,fvm ;
02587       float dxyz , cc ;
02588       int ii ;
02589 
02590       if( im3d->type != AFNI_3DDATA_VIEW ) RETURN(NULL) ;
02591 
02592       LOAD_IVEC3(iv,0,0,n) ;
02593       ivp = THD_fdind_to_3dind( br , iv ) ;
02594       fvp = THD_3dind_to_3dmm ( br->dset , ivp ) ;
02595       fvp = THD_3dmm_to_dicomm( br->dset , fvp ) ;
02596 
02597       if( n == 0 ) LOAD_IVEC3(iv,0,0,1) ;
02598       else         LOAD_IVEC3(iv,0,0,n-1) ;
02599       ivm = THD_fdind_to_3dind( br , iv ) ;
02600       fvm = THD_3dind_to_3dmm ( br->dset , ivm ) ;
02601       fvm = THD_3dmm_to_dicomm( br->dset , fvm ) ;
02602 
02603       dxyz = MIN(br->del1,br->del2) ;
02604       dxyz = MIN(dxyz    ,br->del3) ; dxyz *= 0.1 ;
02605 
02606       if( fabs(fvm.xyz[0]-fvp.xyz[0]) > dxyz ){ /* +=R -=L */
02607          cc = fvp.xyz[0] ;
02608          dd = ( cc >= 0.0 ) ? "L" : "R" ;
02609       } else if( fabs(fvm.xyz[1]-fvp.xyz[1]) > dxyz ){ /* +=P -=A */
02610          cc = fvp.xyz[1] ;
02611          dd = ( cc >= 0.0 ) ? "P" : "A" ;
02612       } else if( fabs(fvm.xyz[2]-fvp.xyz[2]) > dxyz ){ /* +=S -=I */
02613          cc = fvp.xyz[2] ;
02614          dd = ( cc >= 0.0 ) ? "S" : "I" ;
02615       } else {
02616         RETURN(NULL) ;   /* should never happen */
02617       }
02618 
02619       sprintf(str,"%6.2f",fabs(cc)) ;
02620       for( ii=strlen(str)-1 ; ii > 0 && str[ii] == '0' ; ii-- ) str[ii] = '\0' ;
02621       if( str[ii] == '.' ) str[ii] = '\0' ;
02622       strcat(str,dd) ; lab = strdup(str) ; RETURN(lab) ;
02623    }
02624 
02625    /*--- underlay image # n ---*/
02626 
02627    if( type == isqCR_getimage || type == isqCR_getqimage ){
02628       Three_D_View * im3d = (Three_D_View *) br->parent ;
02629       int ival ;
02630 
02631       /*** decide which 3D brick to extract data from (ival) ***/
02632 
02633       if( EQUIV_DSETS(br->dset,im3d->anat_now) )      /* underlay dataset */
02634         ival = im3d->vinfo->anat_index ;
02635       else if( EQUIV_DSETS(br->dset,im3d->fim_now) )  /* overlay dataset */
02636         ival = im3d->vinfo->fim_index ;
02637       else
02638         ival = 0 ;                                    /* shouldn't happen */
02639 
02640            if( type == isqCR_getqimage      ) ival = -1 ; /* get empty image */
02641       else if( ival >= DSET_NVALS(br->dset) ) ival = br->dset->dblk->nvals -1 ;
02642 
02643 if(PRINT_TRACING)
02644 { char str[256] ;
02645   sprintf(str,"getting image n1=%d n2=%d ival=%d",br->n1,br->n2,ival) ;
02646   STATUS(str) ; }
02647 
02648       LOAD_DSET_VIEWS(im3d) ;  /* 02 Nov 1996 */
02649 
02650       im = FD_warp_to_mri( n , ival , br ) ; /* actually get image from dataset */
02651 
02652       if( ival < 0 ) RETURN( (XtPointer) im ) ;  /* return fake image */
02653 
02654       /* Load value of current pixel into display label */
02655       /* April 1996: only if image is at current slice  */
02656 
02657       { char buf[64] = "\0" ; int ibest=-1 ;
02658         AFNI_set_valabel( br , n , im , buf ) ;
02659         if( buf[0] != '\0' ){
02660           if( im3d->vinfo->underlay_type == UNDERLAY_ANAT )
02661             strcpy( im3d->vinfo->anat_val , buf ) ;
02662           else
02663             im3d->vinfo->anat_val[0] = '\0' ;
02664 
02665           if( !AFNI_noenv("AFNI_VALUE_LABEL") ) AFNI_do_bkgd_lab( im3d ) ;
02666 
02667           if( im->kind != MRI_complex && im->kind != MRI_rgb ){
02668             char qbuf[64] = "bg =" ;
02669             strcat(qbuf,buf) ; strcpy(buf,qbuf) ;
02670           }
02671           AFNI_get_xhair_node( im3d , NULL , &ibest ) ;   /* 21 Feb 2003 */
02672           if( ibest >= 0 ){
02673             char qbuf[64]; sprintf(qbuf,"\nxh = #%d",ibest); strcat(buf,qbuf);
02674           }
02675           MCW_set_widget_label( im3d->vwid->imag->pop_bkgd_lab , buf ) ;
02676           XtManageChild( im3d->vwid->imag->pop_bkgd_lab ) ;
02677         }
02678       }
02679 
02680       RETURN( (XtPointer) im ) ;
02681    }
02682 
02683 STATUS("get something else, but I don't care!") ;
02684 
02685    RETURN( NULL ) ;
02686 }
02687 
02688 /*-----------------------------------------------------------------------------*/
02689 /*! Set a value label when the nsl-th image is in "im".
02690 -------------------------------------------------------------------------------*/
02691 
02692 void AFNI_set_valabel( FD_brick * br , int nsl , MRI_IMAGE * im , char * blab )
02693 {
02694    Three_D_View * im3d = (Three_D_View *) br->parent ;
02695    THD_ivec3 ib ;
02696 
02697 ENTRY("AFNI_set_valabel") ;
02698 
02699    if( ! IM3D_VALID(im3d) || ! im3d->vwid->imag->do_bkgd_lab ||
02700        im == NULL         || blab == NULL                      ) EXRETURN ;
02701 
02702    /* convert current voxel index location to FD_brick indexes */
02703 
02704    ib = THD_3dind_to_fdind( br , TEMP_IVEC3( im3d->vinfo->i1 ,
02705                                              im3d->vinfo->j2 ,
02706                                              im3d->vinfo->k3  ) ) ;
02707 
02708    /* if the input image slice index (nsl) doesn't match the current
02709       location of the crosshairs, then we don't care about this image */
02710 
02711    if( nsl != ib.ijk[2] ) EXRETURN ;
02712 
02713    /* otherwise, extract a value from the image and put into blab */
02714 
02715    switch( im->kind ){
02716 
02717       case MRI_byte:{
02718          int val = MRI_BYTE_2D(im , ib.ijk[0],ib.ijk[1]) ;
02719          sprintf( blab , "%6d" , val ) ;
02720       }
02721       break ;
02722 
02723       case MRI_short:{
02724          int val = MRI_SHORT_2D(im , ib.ijk[0],ib.ijk[1]) ;
02725          sprintf( blab , "%6d" , val ) ;
02726       }
02727       break ;
02728 
02729       case MRI_int:{
02730          int val = MRI_INT_2D(im , ib.ijk[0],ib.ijk[1]) ;
02731          sprintf( blab , "%6d" , val ) ;
02732       }
02733       break ;
02734 
02735       case MRI_float:{
02736          float val = MRI_FLOAT_2D(im , ib.ijk[0],ib.ijk[1]) ;
02737          AV_fval_to_char(val,blab) ;
02738       }
02739       break ;
02740 
02741       case MRI_complex:{
02742          int iblab ;
02743          complex val ;
02744          val = MRI_COMPLEX_2D(im , ib.ijk[0],ib.ijk[1]) ;
02745          AV_fval_to_char(val.r,blab) ; iblab = strlen(blab) ;
02746          if( val.i >= 0.0 ) blab[iblab++] = '+' ;
02747          AV_fval_to_char(val.i,blab+iblab) ; iblab = strlen(blab) ;
02748          blab[iblab++] = 'I' ; blab[iblab++] = '\0' ;
02749       }
02750       break ;
02751 
02752       case MRI_rgb:{
02753          byte *rgb = MRI_RGB_PTR(im) ;
02754          int ii = ib.ijk[0] + im->nx * ib.ijk[1] ;
02755          sprintf(blab,"(%d,%d,%d)",(int)rgb[3*ii],(int)rgb[3*ii+1],(int)rgb[3*ii+2]) ;
02756       }
02757       break ;
02758 
02759    }
02760    EXRETURN ;
02761 }
02762 
02763 /*----------------------------------------------------------------------
02764    read image files directly into a 3D dataset.
02765    this will be incomplete, but is enough for display purposes.
02766 ------------------------------------------------------------------------*/
02767 
02768 THD_3dim_dataset * AFNI_read_images( int nf , char * fname[] )
02769 {
02770    MRI_IMAGE * im , * shim ;
02771    char * bar ;
02772    register int     npix , ii ;
02773    int nx , ny , nz , lf , kz , kim ;
02774    MRI_IMARR * arr ;
02775    char str[256] ;
02776    THD_3dim_dataset * dset ;
02777    int datum = GLOBAL_argopt.datum , dsize ;
02778 
02779    int nvals , nzz , nzin=0 ;  /* 19 Oct 1999 */
02780    float dx=0.0, dy=0.0 , dz=0.0 ;  /* 29 Jul 2002 */
02781 
02782 ENTRY("AFNI_read_images") ;
02783 
02784    /*----- see if there are any images to read! -----*/
02785 
02786    if( nf < 1 ) FatalError("*** No images on command line!? ***") ;
02787 
02788    /* count total number of images */
02789 
02790    nz = 0 ;
02791    for( lf=0 ; lf < nf ; lf++ ){
02792       ii = mri_imcount( fname[lf] ) ;
02793       if( ii == 0 ){
02794          sprintf(str,"*** Illegal image file specifier: %s",fname[lf]) ;
02795          FatalError(str) ;
02796       }
02797       nz += ii ;
02798    }
02799    if( nz == 1 ) nz = 2 ;  /* special case for just one image */
02800 
02801    /*--- read 1st file to get sizes ---*/
02802 
02803    arr = mri_read_file( fname[0] ) ;
02804    if( arr == NULL || arr->num == 0 ){
02805       sprintf(str,"*** cannot read first image file: %s",fname[0]) ;
02806       FatalError(str) ;
02807    }
02808 
02809    im = arr->imarr[0] ;
02810    nx = im->nx ;
02811    ny = im->ny ; npix = nx * ny ;
02812 
02813    if( im->dw > 0.0 ){
02814      dx = fabs(im->dx); dy = fabs(im->dy); dz = fabs(im->dz);  /* 29 Jul 2002 */
02815    }
02816 
02817    if( datum < 0 ) datum = im->kind ;
02818    if( ! AFNI_GOOD_DTYPE(datum) )
02819       FatalError("*** Illegal datum type found ***") ;
02820 
02821    dsize = mri_datum_size( (MRI_TYPE) datum ) ;
02822    bar   = (char *) malloc( dsize * nx*ny*nz ) ;
02823    if( bar == NULL ){
02824       fprintf(stderr,"\n** Can't malloc memory for image input!\a\n") ;
02825       exit(1) ;
02826    }
02827 
02828    /*--- read all files, convert if needed, put in the cube ---*/
02829 
02830    kz = 0 ;
02831    for( lf=0 ; lf < nf ; lf++ ){
02832 
02833       /** read the file (except the first, which we already have **/
02834 
02835       if( lf != 0 ){
02836          arr = mri_read_file( fname[lf] ) ;
02837          if( arr == NULL || arr->num == 0 ){
02838            sprintf(str,"*** cannot read image file: %s",fname[lf]) ;
02839            FatalError(str) ;
02840          }
02841       }
02842 
02843       /** for each image in file ... **/
02844 
02845       for( kim=0 ; kim < arr->num ; kim++ ){
02846          im = arr->imarr[kim] ;
02847 
02848          /** check if image matches dimensions of first slice **/
02849 
02850          if( im->nx != nx || im->ny != ny ){
02851             if( ! GLOBAL_argopt.resize_images ){
02852                sprintf(str, "*** image size mismatch:\n"
02853                            " *** expected nx=%d ny=%d but got nx=%d ny=%d in file %s" ,
02854                            nx,ny,im->nx,im->ny , fname[lf] ) ;
02855                FatalError(str) ;
02856             } else {
02857                MRI_IMAGE * rim ;
02858                rim = mri_resize( im , nx , ny ) ;
02859                mri_free( im ) ;
02860                im = rim ;
02861             }
02862          }
02863 
02864          /** check if image data type matches the kind we want **/
02865 
02866          if( im->kind == datum ){
02867             shim = im ;
02868          } else {
02869             shim = mri_to_mri( datum , im ) ;
02870             if( shim == NULL ) FatalError("*** Illegal convert! ***") ;
02871             mri_free( im ) ;
02872          }
02873 
02874          /** copy bytes from slice into the "bar" brick **/
02875 
02876          memcpy( bar + dsize*npix*kz , mri_data_pointer(shim) , dsize*npix ) ;
02877          kz++ ;
02878 
02879          KILL_1MRI(shim) ;
02880          if( kz%10 == 5 ) REPORT_PROGRESS(".") ;
02881       }
02882       FREE_IMARR(arr) ;  /* not DESTROY_IMARR, since images are already gone */
02883    }
02884 
02885    /*** special case of one input image ***/
02886 
02887    if( kz == 1 && nz == 2 ){
02888       memcpy( bar + dsize*npix , bar , dsize*npix ) ;
02889    }
02890 
02891    /*** tell the user what all we've read ***/
02892 
02893    sprintf(str,": nx=%d ny=%d nslice=%d (%s)",nx,ny,nz,MRI_TYPE_name[datum]) ;
02894    REPORT_PROGRESS(str) ;
02895 
02896    /*- 19 Oct 1999: if we are doing a -tim read,
02897                     then have to setup the time and z dimensions -*/
02898 
02899    if( GLOBAL_argopt.read_tim != 0 ){
02900 
02901       if( GLOBAL_argopt.read_tim > 0 ){          /* 20 Oct 1999 */
02902          nzin  = nzz = GLOBAL_argopt.read_tim ;  /* -zim:nzz */
02903          nvals = nz / nzz ;
02904 
02905          if( nvals*nzz != nz )
02906             fprintf(stderr,
02907                     "\n** Warning: -zim:%d does not evenly divide"
02908                     "number of 2D slices read=%d\n",
02909                     nzz , nz ) ;
02910 
02911       } else {
02912          nvals = - GLOBAL_argopt.read_tim ;      /* -tim:nvals */
02913          nzin  = nzz = nz / nvals ;
02914 
02915          if( nvals*nzz != nz )
02916             fprintf(stderr,
02917                     "\n** Warning: -tim:%d does not evenly divide"
02918                     "number of 2D slices read=%d\n",
02919                     nvals , nz ) ;
02920       }
02921 
02922       if( nvals == 1 ){
02923          fprintf(stderr,
02924                  "\n** Error: -tim or -zim has only 1 point in time!\n") ;
02925          exit(1) ;
02926       }
02927 
02928       if( nzz == 1 ) nzz = 2 ;  /* can't have just 1 slice */
02929 
02930    } else {   /* the old code */
02931       nvals = 1 ;
02932       nzz   = nz ;
02933    }
02934 
02935    /*--- now create the rest of the data structure, as far as we can ---*/
02936 
02937    dset                = myXtNew( THD_3dim_dataset ) ;
02938    dset->dblk          = myXtNew( THD_datablock ) ;
02939    dset->daxes         = myXtNew( THD_dataxes ) ;
02940    dset->dblk->diskptr = myXtNew( THD_diskptr ) ;
02941    dset->markers       = NULL ;
02942    dset->warp          = NULL ;
02943    dset->vox_warp      = NULL ;
02944    dset->self_warp     = NULL ;  /* 26 Aug 2002 */
02945    dset->warp_parent   = NULL ;
02946    dset->anat_parent   = NULL ;
02947    dset->stats         = NULL ;
02948    dset->death_mark    = 0 ;
02949    dset->tcat_list     = NULL ;  /* 04 Aug 2004 */
02950    dset->tcat_num      = 0 ;
02951    dset->tcat_len      = NULL ;
02952    dset->taxis         = NULL ;
02953    dset->tagset        = NULL ;  /* Oct 1998 */
02954    ZERO_STAT_AUX( dset ) ;
02955 #ifdef ALLOW_DATASET_VLIST
02956    dset->pts           = NULL ;
02957 #endif
02958 
02959    INIT_KILL(dset->kl) ;
02960    INIT_KILL(dset->dblk->kl) ;
02961 
02962    dset->dblk->diskptr->type         = DISKPTR_TYPE ;
02963    dset->dblk->diskptr->rank         = 3 ;
02964    dset->dblk->diskptr->nvals        = nvals ;  /* modified 19 Oct 1999 */
02965    dset->dblk->diskptr->dimsizes[0]  = nx ;
02966    dset->dblk->diskptr->dimsizes[1]  = ny ;
02967    dset->dblk->diskptr->dimsizes[2]  = nzz ;    /* modified 19 Oct 1999 */
02968    dset->dblk->diskptr->storage_mode = STORAGE_UNDEFINED ;
02969    dset->dblk->diskptr->byte_order   = THD_get_write_order() ;  /* 25 April 1998 */
02970 
02971    EMPTY_STRING(dset->dblk->diskptr->prefix) ;
02972    EMPTY_STRING(dset->dblk->diskptr->viewcode) ;
02973    EMPTY_STRING(dset->dblk->diskptr->filecode) ;
02974    EMPTY_STRING(dset->dblk->diskptr->directory_name) ;
02975    EMPTY_STRING(dset->dblk->diskptr->header_name) ;
02976    EMPTY_STRING(dset->dblk->diskptr->brick_name) ;
02977 
02978    dset->dblk->type        = DATABLOCK_TYPE ;
02979    dset->dblk->nvals       = nvals ;            /* modified 19 Oct 1999 */
02980 
02981    /** here is where we attach "bar" to the dataset **/
02982 
02983    dset->dblk->malloc_type  = DATABLOCK_MEM_MALLOC ;
02984    dset->dblk->brick_fac    = NULL ; /* let THD_init_datablock_brick do these */
02985    dset->dblk->brick_bytes  = NULL ;
02986    dset->dblk->brick        = NULL ;
02987 
02988    DSET_lock(dset) ;  /* Feb 1998: lock into memory */
02989 
02990    dset->dblk->brick_lab      = NULL ; /* 30 Nov 1997 */
02991    dset->dblk->brick_keywords = NULL ;
02992    dset->dblk->brick_statcode = NULL ;
02993    dset->dblk->brick_stataux  = NULL ;
02994    dset->keywords             = NULL ;
02995 
02996    THD_init_datablock_brick( dset->dblk , datum , NULL ) ;
02997 
02998    if( nvals == 1 ){
02999 
03000       mri_fix_data_pointer( bar , DSET_BRICK(dset,0) ) ;  /* the attachment! */
03001 
03002    } else {   /* 19 Oct 1999: make up a lot of bricks and attach them all */
03003               /* 20 Oct 1999: allow for the 3rd dimension as well         */
03004 
03005       int iv , jj , kk ;
03006       char * qbar ;
03007 
03008       for( iv=0 ; iv < nvals ; iv++ ){
03009          qbar = (char *) malloc( dsize*npix*nzz ) ;  /* space for nzz slices */
03010 
03011          if( GLOBAL_argopt.read_tim > 0 ){
03012             for( jj=0 ; jj < nzz ; jj++ ){              /* copy slices */
03013                kk = MIN(jj,nzin-1) ;
03014                memcpy( qbar + jj*dsize*npix ,
03015                        bar + (iv*nzin+kk)*dsize*npix , dsize*npix ) ;
03016             }
03017          } else {
03018             for( jj=0 ; jj < nzz ; jj++ ){              /* copy slices */
03019                kk = MIN(jj,nzin-1) ;
03020                memcpy( qbar + jj*dsize*npix ,
03021                        bar + (kk*nvals+iv)*dsize*npix , dsize*npix ) ;
03022             }
03023          }
03024 
03025          mri_fix_data_pointer( qbar , DSET_BRICK(dset,iv) ) ;
03026       }
03027 
03028       free(bar) ;  /* not needed no more no how */
03029 
03030       EDIT_dset_items( dset , ADN_ntt,nvals , ADN_ttdel,1.0 , ADN_none ) ;
03031    }
03032 
03033    dset->dblk->natr   = dset->dblk->natr_alloc = 0 ;
03034    dset->dblk->atr    = NULL ;
03035    dset->dblk->parent = (XtPointer) dset ;
03036 
03037    dset->daxes->type  = DATAXES_TYPE ;
03038    dset->daxes->nxx   = nx ;
03039    dset->daxes->nyy   = ny ;
03040    dset->daxes->nzz   = nzz ;        /* modified 19 Oct 1999 */
03041    dset->daxes->xxdel = 1.0 ;        /* arbitary units */
03042    dset->daxes->yydel = GLOBAL_argopt.dy ;  /* these allow user to alter */
03043    dset->daxes->zzdel = GLOBAL_argopt.dz ;  /* the images' aspect ratio */
03044    dset->daxes->xxorg = dset->daxes->yyorg = dset->daxes->zzorg = 0.0 ;
03045    dset->daxes->parent= (XtPointer) dset ;
03046 
03047    if( dx > 0.0 ) dset->daxes->xxdel = dx ;  /* 29 Jul 2002 */
03048    if( dy > 0.0 ) dset->daxes->yydel = dy ;
03049    if( dz > 0.0 ) dset->daxes->zzdel = dz ;
03050 
03051    dset->idcode = MCW_new_idcode() ;
03052    ZERO_IDCODE(dset->anat_parent_idcode) ;
03053    ZERO_IDCODE(dset->warp_parent_idcode) ;
03054 
03055    /* set the daxes orientation codes from the command line argument */
03056 
03057 #define ORCODE(aa) \
03058   ( (aa)=='R' ? ORI_R2L_TYPE : (aa)=='L' ? ORI_L2R_TYPE : \
03059     (aa)=='P' ? ORI_P2A_TYPE : (aa)=='A' ? ORI_A2P_TYPE : \
03060     (aa)=='I' ? ORI_I2S_TYPE : (aa)=='S' ? ORI_S2I_TYPE : ILLEGAL_TYPE )
03061 
03062 #define OR3OK(x,y,z) ( ((x)&6) + ((y)&6) + ((z)&6) == 6 )
03063 
03064    { char acod ;
03065      int xx,yy,zz ;
03066 
03067      acod = toupper(GLOBAL_argopt.orient_code[0]) ; xx = ORCODE(acod) ;
03068      acod = toupper(GLOBAL_argopt.orient_code[1]) ; yy = ORCODE(acod) ;
03069      acod = toupper(GLOBAL_argopt.orient_code[2]) ; zz = ORCODE(acod) ;
03070 
03071      if( xx < 0 || yy < 0 || zz < 0 || ! OR3OK(xx,yy,zz) )
03072         FatalError("Unusable -orient code!") ;
03073 
03074      dset->daxes->xxorient = xx ;
03075      dset->daxes->yyorient = yy ;
03076      dset->daxes->zzorient = zz ;
03077    }
03078 
03079    dset->wod_flag  = False ;  /* no warp-on-demand */
03080    dset->wod_daxes = NULL ;   /* 02 Nov 1996 */
03081 
03082    dset->type      = GEN_ANAT_TYPE ;
03083    dset->view_type = dset->func_type = 0 ;
03084 
03085    MCW_strncpy(  dset->self_name , fname[0]             , THD_MAX_NAME  ) ;
03086    MCW_strncpy(  dset->label1    , "Image Display Mode" , THD_MAX_LABEL ) ;
03087    EMPTY_STRING( dset->label2 ) ;
03088    EMPTY_STRING( dset->warp_parent_name ) ;
03089    EMPTY_STRING( dset->anat_parent_name ) ;
03090 
03091    RETURN( dset ) ;
03092 }
03093 
03094 /*----------------------------------------------------------------------
03095    respond to events that one of the MCW_imseq's sends to us
03096 ------------------------------------------------------------------------*/
03097 
03098 void AFNI_seq_send_CB( MCW_imseq * seq , FD_brick * br , ISQ_cbs * cbs )
03099 {
03100    Three_D_View * im3d = (Three_D_View *) seq->parent ;
03101 
03102 ENTRY("AFNI_seq_send_CB") ;
03103 
03104 if(PRINT_TRACING)
03105 { char str[256] ; sprintf(str,"reason=%d",cbs->reason) ; STATUS(str) ; }
03106 
03107    if( ! IM3D_VALID(im3d) ||
03108        (   im3d->ignore_seq_callbacks == AFNI_IGNORE_EVERYTHING
03109         && cbs->reason                != isqCR_getxynim        ) ) EXRETURN ;
03110 
03111    switch( cbs->reason ){
03112 
03113       default: break ;
03114 
03115       case isqCR_destroy:{
03116          MCW_imseq * sxyz = im3d->s123 ,
03117                    * syzx = im3d->s231 ,
03118                    * szxy = im3d->s312  ;
03119          Widget w ;
03120          int a3 = br->a123.ijk[2] ,   /* z axis of the brick?    */
03121              az = abs(a3) - 1       ; /* 0,1,2 for dataset x,y,z */
03122 
03123               if( seq == sxyz ){
03124                  w = im3d->vwid->imag->image_xyz_pb ; im3d->s123 = NULL ; }
03125          else if( seq == syzx ){
03126                  w = im3d->vwid->imag->image_yzx_pb ; im3d->s231 = NULL ; }
03127          else if( seq == szxy ){
03128                  w = im3d->vwid->imag->image_zxy_pb ; im3d->s312 = NULL ; }
03129          else
03130                  EXRETURN ;  /* something goofy happened? */
03131 
03132 #if 1
03133          myXtFree( seq->status ) ; /* 28 Sep 1998: via Purify */
03134 #endif
03135          myXtFree( seq ) ;
03136          MCW_invert_widget(w) ;  /* back to normal */
03137          NORMAL_cursorize(w) ;   /* 20 Jul 2005 */
03138          INIT_BKGD_LAB(im3d) ;
03139          AFNI_view_setter(im3d,NULL) ;
03140 
03141          /* July 1996: redraw if we just lost a crosshair montage
03142             (it would have been in the z direction of the brick) */
03143 
03144          if( im3d->vinfo->xhairs_ndown.ijk[az] > 0 ||
03145              im3d->vinfo->xhairs_nup.ijk[az]   > 0   ){
03146 
03147 if(PRINT_TRACING)
03148 { char str[256] ;
03149   sprintf(str,"imseq close on axis %d --> lost xhairs in that direction",az) ;
03150   STATUS(str) ; }
03151 
03152             CLEAR_MONTAGE(im3d,br) ;
03153 
03154             if( im3d->vinfo->xhairs_show_montage &&
03155                 im3d->ignore_seq_callbacks == AFNI_IGNORE_NOTHING ){
03156 
03157                AFNI_set_viewpoint( im3d , -1,-1,-1 , REDISPLAY_OVERLAY ) ;
03158             }
03159          }
03160       }
03161       MPROBE ;
03162       break ;  /* end of destroy */
03163 
03164       case isqCR_buttonpress:{
03165          XButtonEvent *xev = (XButtonEvent *) cbs->event ;
03166 
03167 if(PRINT_TRACING){
03168  char str[256] ;
03169  sprintf(str,"isqCR_buttonpress: button=%d state=%x",xev->button,xev->state) ;
03170  STATUS(str) ; }
03171 
03172          im3d->vwid->butx = xev->x_root ;  /* 17 May 2005 */
03173          im3d->vwid->buty = xev->y_root ;
03174          switch( xev->button ){
03175 
03176             default: EXRETURN ;  /* unused button */
03177 
03178             case Button3:{  /* popup */
03179                XtVaSetValues( im3d->vwid->imag->popmenu ,
03180                                  XmNuserData , (XtPointer) seq ,   /* who */
03181                               NULL ) ;
03182                XmMenuPosition( im3d->vwid->imag->popmenu , xev ) ; /* where */
03183                XtManageChild ( im3d->vwid->imag->popmenu ) ;       /* pop */
03184             }
03185             break ;
03186 
03187             case Button1:{
03188                THD_ivec3 id ;
03189 
03190                /* April 1996:  only use this button press if
03191                                it is inside the confines of the brick */
03192 
03193 if(PRINT_TRACING)
03194 { char str[256] ;
03195   sprintf(str,"Button1 at %d %d %d",
03196           cbs->xim,cbs->yim,cbs->nim) ; STATUS(str) ; }
03197 
03198                if( cbs->xim >= 0 && cbs->xim < br->n1 &&
03199                    cbs->yim >= 0 && cbs->yim < br->n2 &&
03200                    cbs->nim >= 0 && cbs->nim < br->n3   ){
03201 
03202                   id = THD_fdind_to_3dind(
03203                           br , TEMP_IVEC3(cbs->xim,cbs->yim,cbs->nim) );
03204 
03205 if(PRINT_TRACING)
03206 { char str[256] ;
03207   sprintf(str," 3D dataset coordinates %d %d %d",
03208           id.ijk[0],id.ijk[1],id.ijk[2] ) ; STATUS(str) ; }
03209 
03210                   SAVE_VPT(im3d) ;  /* save current location as jumpback */
03211 
03212                   if( im3d->ignore_seq_callbacks == AFNI_IGNORE_NOTHING ){
03213 
03214                     /* 20 Feb 2003: set plane from which viewpoint is controlled */
03215 
03216                     AFNI_view_setter(im3d,seq) ;
03217                     AFNI_set_viewpoint(
03218                        im3d , id.ijk[0] , id.ijk[1] , id.ijk[2] ,
03219                        (im3d->vinfo->crosshair_visible==True) ?
03220                        REDISPLAY_OVERLAY : REDISPLAY_OPTIONAL ) ;
03221                   }
03222                }
03223             } /* end of button 1 */
03224             break ;
03225          } /* end of switch on which button */
03226       }
03227       break ;  /* end of button press */
03228 
03229       case isqCR_newimage:{
03230          THD_ivec3 id ;
03231 
03232          id = THD_fdind_to_3dind( br, TEMP_IVEC3(-99999,-99999,cbs->nim) );
03233 
03234 if(PRINT_TRACING)
03235 { char str[256] ;
03236   sprintf(str,"newimage input %d -> %d %d %d",
03237           cbs->nim , id.ijk[0],id.ijk[1],id.ijk[2] ) ;
03238   STATUS(str) ; }
03239 
03240          if( im3d->ignore_seq_callbacks == AFNI_IGNORE_NOTHING ){
03241 
03242             /* 20 Feb 2003: set plane from which viewpoint is controlled */
03243 
03244             AFNI_view_setter(im3d,seq) ;
03245             AFNI_set_viewpoint(
03246                im3d , id.ijk[0] , id.ijk[1] , id.ijk[2] ,
03247                (im3d->vinfo->crosshair_visible==True) ?
03248                REDISPLAY_OVERLAY : REDISPLAY_OPTIONAL ) ;
03249          }
03250       }
03251       break ;  /* end of new image */
03252 
03253       /** July 1996: an image viewer changed montage layout **/
03254 
03255       case isqCR_newmontage:{
03256          THD_ivec3 * minf = (THD_ivec3 *) cbs->userdata ;
03257          int ndown = minf->ijk[0], nup = minf->ijk[1], nskip = minf->ijk[2] ;
03258          int a3 = br->a123.ijk[2] ,   /* z axis of the brick?    */
03259              az = abs(a3) - 1       ; /* 0,1,2 for dataset x,y,z */
03260 
03261 if(PRINT_TRACING)
03262 { char str[256] ;
03263   sprintf(str,"newmontage: ndown=%d nup=%d nskip=%d a3=%d (on axis az=%d)",
03264           ndown,nup,nskip,a3,az) ; STATUS(str) ; }
03265 
03266          im3d->vinfo->xhairs_nskip.ijk[az] = nskip ;
03267 
03268          if( a3 > 0 ){
03269             im3d->vinfo->xhairs_ndown.ijk[az] = ndown ;
03270             im3d->vinfo->xhairs_nup.ijk[az]   = nup ;
03271          } else {
03272             im3d->vinfo->xhairs_ndown.ijk[az] = nup ;
03273             im3d->vinfo->xhairs_nup.ijk[az]   = ndown ;
03274          }
03275 
03276          if( im3d->ignore_seq_callbacks == AFNI_IGNORE_NOTHING )
03277             AFNI_set_viewpoint( im3d , -1,-1,-1 , REDISPLAY_OVERLAY ) ;
03278       }
03279       break ;
03280 
03281       /* 30 Dec 1998: return the current focus position */
03282 
03283       case isqCR_getxynim:{
03284          THD_ivec3 ib ;
03285 
03286          ib = THD_3dind_to_fdind( br , TEMP_IVEC3( im3d->vinfo->i1 ,
03287                                                    im3d->vinfo->j2 ,
03288                                                    im3d->vinfo->k3  ) ) ;
03289 
03290          cbs->xim = ib.ijk[0] ; cbs->yim = ib.ijk[1] ; cbs->nim = ib.ijk[2] ;
03291       }
03292       break ;  /* end of getxynim */
03293 
03294       /* Arrowpad stuff */
03295 
03296       case isqCR_appress:{
03297          if( im3d->ignore_seq_callbacks == AFNI_IGNORE_NOTHING ){
03298             AFNI_view_setter(im3d,seq) ;
03299             AFNI_crosshair_gap_CB( NULL , (XtPointer) im3d ) ;
03300          }
03301       }
03302       break ;  /* end of arrowpad center key press */
03303 
03304       case isqCR_dxplus:
03305       case isqCR_dxminus:
03306       case isqCR_dyplus:
03307       case isqCR_dyminus:{
03308          THD_ivec3 ib , id ;
03309          XButtonEvent * xev = (XButtonEvent *) cbs->event ;
03310          int step = 1 ;
03311          THD_dataxes *daxes ;
03312 
03313          if( xev != NULL &&
03314              ( xev->type == ButtonPress ||
03315                xev->type == ButtonRelease ) &&
03316              (xev->state & (ShiftMask | ControlMask)) ) step = INIT_bigscroll ;
03317 
03318          ib = THD_3dind_to_fdind( br , TEMP_IVEC3( im3d->vinfo->i1 ,
03319                                                    im3d->vinfo->j2 ,
03320                                                    im3d->vinfo->k3  ) ) ;
03321          switch( cbs->reason ){
03322             case isqCR_dxplus:   ib.ijk[0] += step ; break ;
03323             case isqCR_dxminus:  ib.ijk[0] -= step ; break ;
03324             case isqCR_dyplus:   ib.ijk[1] += step ; break ;
03325             case isqCR_dyminus:  ib.ijk[1] -= step ; break ;
03326          }
03327 
03328          id = THD_fdind_to_3dind( br , ib ) ;
03329 
03330          /* 13 May 2003: allow for wraparound */
03331 
03332          LOAD_DSET_VIEWS(im3d) ;  /* 20 Nov 2003 */
03333          daxes = CURRENT_DAXES(im3d->anat_now) ;
03334               if( id.ijk[0] <  0          ) id.ijk[0] += daxes->nxx ;
03335          else if( id.ijk[0] >= daxes->nxx ) id.ijk[0] -= daxes->nxx ;
03336               if( id.ijk[1] <  0          ) id.ijk[1] += daxes->nyy ;
03337          else if( id.ijk[1] >= daxes->nyy ) id.ijk[1] -= daxes->nyy ;
03338               if( id.ijk[2] <  0          ) id.ijk[2] += daxes->nzz ;
03339          else if( id.ijk[2] >= daxes->nzz ) id.ijk[2] -= daxes->nzz ;
03340 
03341          if( im3d->ignore_seq_callbacks == AFNI_IGNORE_NOTHING ){
03342 
03343             /* 20 Feb 2003: set plane from which viewpoint is controlled */
03344 
03345             AFNI_view_setter(im3d,seq) ;
03346             AFNI_set_viewpoint(
03347                im3d , id.ijk[0] , id.ijk[1] , id.ijk[2] ,
03348                (im3d->vinfo->crosshair_visible==True) ?
03349                REDISPLAY_OVERLAY : REDISPLAY_OPTIONAL ) ;
03350          }
03351       }
03352       break ;  /* end of arrowpad arrow press */
03353 
03354       case isqCR_keypress:{
03355 #if 0
03356          MCW_grapher * grapher = VIEWER_TO_GRAPHER(im3d,seq) ;
03357          if( grapher != NULL ){
03358             char buf[2] ;
03359             buf[0] = cbs->key ; buf[1] = '\0' ;
03360             GRA_handle_keypress( grapher , buf , cbs->event ) ;
03361          }
03362 #endif
03363       }
03364       break ; /* end of keyboard press */
03365 
03366       /*--- 20 Feb 2003: keypress while in button2 mode ---*/
03367 
03368       case isqCR_button2_key:{
03369         KeySym ks = (KeySym) cbs->key ;
03370 
03371         switch( ks ){
03372           case XK_Delete:
03373             AFNI_process_drawing( im3d , UNDO_MODE , 0,NULL,NULL,NULL ) ;
03374           break ;
03375         }
03376       }
03377       break ; /* end of button2 mode keypress */
03378 
03379       /*--- Feb 1998: list of coordinates from button2 drawing ---*/
03380 
03381       case isqCR_button2_points:{
03382          int npts = cbs->key , zim = cbs->nim ;
03383          int * xyout = (int *) cbs->userdata ;
03384          THD_ivec3 id ;
03385          int nvec , ii , xim,yim , fixed_plane ;
03386          int * xdset , * ydset , * zdset ;
03387 
03388          if( zim >= 0 && zim < br->n3 && npts > 0 ){  /* if input is good */
03389 
03390             /* make space for translated coordinates */
03391 
03392             xdset = (int *) malloc( npts * sizeof(int) ) ;
03393             ydset = (int *) malloc( npts * sizeof(int) ) ;
03394             zdset = (int *) malloc( npts * sizeof(int) ) ;
03395 
03396             /* translate coordinates to dataset xyz indices,
03397                casting out any that are outside the dataset brick */
03398 
03399             nvec = 0 ;
03400             for( ii=0 ; ii < npts ; ii++ ){
03401                xim = xyout[2*ii] ; yim = xyout[2*ii+1] ;
03402 
03403                /* skip points not in the volume */
03404 
03405                if( xim >= 0 && xim < br->n1 && yim >= 0 && yim < br->n2 ){
03406 
03407                   id = THD_fdind_to_3dind( br , TEMP_IVEC3(xim,yim,zim) );
03408                   xdset[nvec] = id.ijk[0] ;
03409                   ydset[nvec] = id.ijk[1] ;
03410                   zdset[nvec] = id.ijk[2] ;
03411 
03412                   /* skip sequentially duplicate points */
03413 
03414                   if( nvec == 0                    ||
03415                       xdset[nvec] != xdset[nvec-1] ||
03416                       ydset[nvec] != ydset[nvec-1] ||
03417                       zdset[nvec] != zdset[nvec-1]   ) nvec++ ;
03418                }
03419             }
03420 
03421             /* send coordinates to processing routine */
03422 
03423             fixed_plane = abs(br->a123.ijk[2]) ;
03424 
03425             if( nvec > 0 ) AFNI_process_drawing( im3d ,
03426                                                  PLANAR_MODE+fixed_plane ,
03427                                                  nvec,xdset,ydset,zdset ) ;
03428 
03429             /* free coordinate memory */
03430 
03431             free(xdset) ; free(ydset) ; free(zdset) ;
03432          }
03433       }
03434       break ; /* end of button2 coordinates */
03435 
03436       /*--- 22 Aug 1998: redraw everything ---*/
03437 
03438       case isqCR_force_redisplay:{
03439          AFNI_view_setter(im3d,seq) ;
03440          PLUTO_force_redisplay() ;  /* see afni_plugin.c */
03441          PLUTO_force_rebar() ;      /* ditto [23 Aug 1998] */
03442       }
03443       break ; /* end of forced redisplay */
03444 
03445    }  /* end of switch on reason for call */
03446 
03447    EXRETURN ;
03448 }
03449 
03450 /*----------------------------------------------------------------------
03451    respond to events that one of the MCW_grapher's sends to us
03452 ------------------------------------------------------------------------*/
03453 
03454 void AFNI_gra_send_CB( MCW_grapher *grapher , FD_brick *br , GRA_cbs *cbs )
03455 {
03456    Three_D_View *im3d = (Three_D_View *)grapher->parent ;
03457 
03458 ENTRY("AFNI_gra_send_CB") ;
03459 
03460 if(PRINT_TRACING)
03461 { char str[256] ; sprintf(str,"reason=%d",cbs->reason) ; STATUS(str) ; }
03462 
03463    if( ! IM3D_VALID(im3d) ||
03464        (im3d->ignore_seq_callbacks==AFNI_IGNORE_EVERYTHING) ) EXRETURN ;
03465 
03466    switch( cbs->reason ){
03467 
03468       default: break ;  /* unimplemented reasons */
03469 
03470       /*** Death ***/
03471 
03472       case graCR_destroy:{
03473          MCW_grapher * gxyz = im3d->g123 ,
03474                      * gyzx = im3d->g231 ,
03475                      * gzxy = im3d->g312  ;
03476          MCW_imseq * seq = GRAPHER_TO_VIEWER(im3d,grapher) ;
03477          Widget w ;
03478 
03479               if( grapher == gxyz ){
03480                  w = im3d->vwid->imag->graph_xyz_pb ; im3d->g123 = NULL ;
03481                  STATUS("destruction of g123") ;
03482          }
03483          else if( grapher == gyzx ){
03484                  w = im3d->vwid->imag->graph_yzx_pb ; im3d->g231 = NULL ;
03485                  STATUS("destruction of g231") ;
03486          }
03487          else if( grapher == gzxy ){
03488                  w = im3d->vwid->imag->graph_zxy_pb ; im3d->g312 = NULL ;
03489                  STATUS("destruction of g312") ;
03490          }
03491          else
03492                  EXRETURN ;  /* something goofy happened? */
03493 
03494          myXtFree( grapher->status ) ;  /* 08 Mar 1999: via mcw_malloc.c */
03495          myXtFree( grapher ) ;          /* free the data space */
03496          MCW_invert_widget(w) ;         /* back to normal */
03497          NORMAL_cursorize(w) ;          /* 20 Jul 2005 */
03498 
03499          /* redisplay the crosshairs, if needed */
03500 
03501          if( seq != NULL && im3d->vinfo->crosshair_visible==True &&
03502              im3d->ignore_seq_callbacks == AFNI_IGNORE_NOTHING     )
03503 
03504             drive_MCW_imseq( seq , isqDR_overlay , (XtPointer) -1 ) ;
03505       }
03506       MPROBE ;
03507       break ;  /* end of destroy */
03508 
03509       /*** User sets new location ***/
03510 
03511       case graCR_newxyzm:{
03512          THD_ivec3 id ;
03513 
03514          if( cbs->xcen >= 0 && cbs->xcen < br->n1 &&
03515              cbs->ycen >= 0 && cbs->ycen < br->n2 &&
03516              cbs->zcen >= 0 && cbs->zcen < br->n3   ){
03517 
03518             id = THD_fdind_to_3dind(
03519                     br , TEMP_IVEC3(cbs->xcen,cbs->ycen,cbs->zcen) );
03520 
03521 if(PRINT_TRACING)
03522 { char str[256] ;
03523   sprintf(str," 3D dataset coordinates %d %d %d",
03524           id.ijk[0],id.ijk[1],id.ijk[2] ) ; STATUS(str) ; }
03525 
03526             if( im3d->ignore_seq_callbacks == AFNI_IGNORE_NOTHING ){
03527                AFNI_view_setter(im3d,NULL) ;
03528                AFNI_set_viewpoint(
03529                   im3d ,
03530                   id.ijk[0] , id.ijk[1] , id.ijk[2] ,
03531                   (im3d->vinfo->crosshair_visible==True) ?
03532                   REDISPLAY_OVERLAY : REDISPLAY_OPTIONAL ) ;
03533             }
03534          }
03535       }
03536       break ; /* end of newxyzm */
03537 
03538       /*** User asks for a reference function ***/
03539 
03540       case graCR_pickref:{
03541 
03542 STATUS("graCR_pickref") ;
03543 
03544          if( IMARR_COUNT(GLOBAL_library.timeseries) > 0 ){
03545             int init_ts = AFNI_ts_in_library( im3d->fimdata->fimref ) ;
03546 
03547             MCW_choose_timeseries( grapher->fdw_graph , "FIM Reference Vector" ,
03548                                    GLOBAL_library.timeseries , init_ts ,
03549                                    AFNI_fimmer_pickref_CB , (XtPointer) im3d ) ;
03550          } else {
03551             (void) MCW_popup_message(
03552                       grapher->option_rowcol ,
03553                       "No timeseries library\nexists to pick from!" ,
03554                       MCW_USER_KILL | MCW_TIMER_KILL ) ;
03555          }
03556       }
03557       break ; /* end of pickref */
03558 
03559       /*** User asks for an ort function ***/
03560 
03561       case graCR_pickort:{
03562 
03563 STATUS("graCR_pickort") ;
03564 
03565          if( IMARR_COUNT(GLOBAL_library.timeseries) > 0 ){
03566             int init_ts = AFNI_ts_in_library( im3d->fimdata->fimort ) ;
03567 
03568             MCW_choose_timeseries( grapher->fdw_graph , "FIM Ort Vector" ,
03569                                    GLOBAL_library.timeseries , init_ts ,
03570                                    AFNI_fimmer_pickort_CB , (XtPointer) im3d ) ;
03571          } else {
03572             (void) MCW_popup_message(
03573                       grapher->option_rowcol ,
03574                       "No timeseries library\nexists to pick from!" ,
03575                       MCW_USER_KILL | MCW_TIMER_KILL ) ;
03576          }
03577       }
03578       break ; /* end of pickort */
03579 
03580 
03581       /*** User asks to clear FIM ***/
03582 
03583       case graCR_clearfim:{
03584          AFNI_fimmer_setref( im3d , NULL ) ;
03585          im3d->fimdata->refadd_count = 0 ;
03586       }
03587       break ; /* end of clearfim */
03588 
03589       /*** User asks to clear Ort ***/
03590 
03591       case graCR_clearort:{
03592          AFNI_fimmer_setort( im3d , NULL ) ;
03593       }
03594       break ; /* end of clearfim */
03595 
03596       /*** 27 Jan 2004:
03597            User toggled WinAver on in one graph window,
03598            so we toggle it off in the other windows.    ***/
03599 
03600       case graCR_winaver:{
03601         if( im3d->g123 != NULL && im3d->g123 != grapher )
03602           drive_MCW_grapher( im3d->g123 , graDR_winaver , 0 ) ;
03603         if( im3d->g231 != NULL && im3d->g231 != grapher )
03604           drive_MCW_grapher( im3d->g231 , graDR_winaver , 0 ) ;
03605         if( im3d->g312 != NULL && im3d->g312 != grapher )
03606           drive_MCW_grapher( im3d->g312 , graDR_winaver , 0 ) ;
03607       }
03608       break ; /* end of winaver */
03609 
03610       /*** 12 Nov 1996:
03611            User supplies a timeseries to add to the global library ***/
03612 
03613       case graCR_timeseries_library:{
03614          MRI_IMAGE * tsim = (MRI_IMAGE *) cbs->userdata ;
03615 
03616          AFNI_add_timeseries( tsim ) ;
03617       }
03618       break ; /* end of timeseries_library */
03619 
03620       /*** User supplies a timeseries for FIM (equals or add) ***/
03621 
03622       case graCR_refadd:
03623       case graCR_refequals:{
03624          MRI_IMAGE * tsim = (MRI_IMAGE *) cbs->userdata ;
03625          MRI_IMAGE * qim , * sim ;
03626          float * sar , * qar ;
03627 
03628          if( tsim != NULL ){
03629             qim = mri_to_float( tsim ) ;        /* make a copy of input */
03630             if( im3d->fimdata->fimref == NULL   ||
03631                 cbs->reason == graCR_refequals  ||
03632                 im3d->fimdata->refadd_count < 1   ){
03633 
03634                /** equals **/
03635 
03636                AFNI_fimmer_setref( im3d , qim ) ;
03637                im3d->fimdata->refadd_count = 1 ;
03638 
03639             } else {
03640                int jj,ii , nxs , nyy , nxq , nxx , npix ;
03641                float fs , fq ;
03642 
03643                /** average **/
03644 
03645                sim  = mri_to_float( im3d->fimdata->fimref ) ; /* add into this copy */
03646                sar  = MRI_FLOAT_PTR(sim) ;
03647                qar  = MRI_FLOAT_PTR(qim) ;
03648                nxs  = sim->nx ; nxq = qim->nx ; nxx = MIN(nxs,nxq) ;
03649                nyy  = MIN( sim->ny , qim->ny ) ;
03650                npix = MIN( sim->nvox , qim->nvox ) ;
03651 
03652                fq = 1.0/( im3d->fimdata->refadd_count + 1.0 ) ;
03653                fs = 1.0 - fq ;
03654 
03655                for( jj=0 ; jj < nyy ; jj++ ){
03656                   for( ii=0 ; ii < nxx ; ii++ ){
03657                      if( sar[ii+jj*nxs] >= WAY_BIG || qar[ii+jj*nxq] >= WAY_BIG )
03658                         sar[ii+jj*nxs] = WAY_BIG ;
03659                      else
03660                         sar[ii+jj*nxs] = fs * sar[ii+jj*nxs] + fq * qar[ii+jj*nxq] ;
03661                   }
03662                }
03663                mri_free( qim ) ;
03664 
03665                AFNI_fimmer_setref( im3d , sim ) ;  /* since caller may free it later */
03666                im3d->fimdata->refadd_count++ ;
03667             }
03668          }
03669       }
03670       break ;
03671 
03672       /*** User asks to smooth reference ***/
03673 
03674       case graCR_refsmooth:{
03675          if( im3d->fimdata->fimref != NULL ){
03676             MRI_IMAGE * sim = mri_to_float(im3d->fimdata->fimref) ; /* copy */
03677             float * sar = MRI_FLOAT_PTR(sim) ;
03678             float aa,bb,cc ;
03679             int ii,jj , nx=sim->nx , ny=sim->ny ;
03680 
03681             for( jj=0 ; jj < ny ; jj++ ){
03682                bb = sar[jj*nx] ; cc = sar[1+jj*nx] ;
03683                for( ii=1 ; ii < nx-1 ; ii++ ){
03684                   aa = bb ; bb = cc ; cc = sar[ii+1+jj*nx] ;
03685                   if( aa < WAY_BIG && bb < WAY_BIG &&
03686                       cc < WAY_BIG && ii > im3d->fimdata->init_ignore )
03687                      sar[ii+jj*nx] = OSFILT(aa,bb,cc) ;
03688                }
03689             }
03690             AFNI_fimmer_setref( im3d , sim ) ;
03691          }
03692       }
03693       break ;
03694 
03695       /*** User asks to do fim! ***/
03696 
03697       case graCR_dofim:{
03698          AFNI_fimmer_execute( im3d , cbs->key , cbs->mat ) ;
03699       }
03700       break ; /* end of dofim */
03701 
03702       /*** User sets initial ignore count ***/
03703 
03704       case graCR_setignore:{
03705          AFNI_fimmer_setignore( im3d , cbs->key ) ;
03706       }
03707       break ;
03708 
03709       /*** User sets the polort order [27 May 1999] ***/
03710 
03711       case graCR_polort:{
03712          AFNI_fimmer_setpolort( im3d , cbs->key ) ;
03713       }
03714       break ;
03715 
03716       /*** User sets time_index (from graph) ***/
03717       /*** 24 Jan 2001: or bucket index      ***/
03718       /*** 29 Jul 2003: time_index and anat_index are almost merged now ***/
03719 
03720       case graCR_setindex:{
03721          MCW_arrowval *tav = im3d->vwid->imag->time_index_av ;
03722          MCW_arrowval *aav = im3d->vwid->func->anat_buck_av ;
03723          int new_index = cbs->key ;
03724 
03725          if( new_index != im3d->vinfo->anat_index ){
03726            if( im3d->vinfo->time_on ){
03727              AV_assign_ival( tav , new_index ) ;               /* set time_index */
03728              AFNI_time_index_CB( tav, (XtPointer) im3d ); /* will set anat_index */
03729            } else {
03730              AV_assign_ival( aav, new_index ) ;       /* set anat index directly */
03731              AFNI_bucket_CB( aav, im3d ) ;
03732            }
03733          }
03734       }
03735       break ;
03736 
03737       /*** Feb 1998: user clicked button2 ***/
03738 
03739       case graCR_button2_points:{
03740          THD_ivec3 id ;
03741          int fixed_plane ;
03742 
03743          if( cbs->xcen >= 0 && cbs->xcen < br->n1 &&
03744              cbs->ycen >= 0 && cbs->ycen < br->n2 &&
03745              cbs->zcen >= 0 && cbs->zcen < br->n3   ){
03746 
03747             /* translate image to dataset coordinates */
03748 
03749             id = THD_fdind_to_3dind(
03750                     br , TEMP_IVEC3(cbs->xcen,cbs->ycen,cbs->zcen) );
03751 
03752             /* send a single point */
03753 
03754             fixed_plane = abs(br->a123.ijk[2]) ;
03755 
03756             AFNI_process_drawing( im3d , SINGLE_MODE + fixed_plane ,
03757                                   1, &id.ijk[0], &id.ijk[1], &id.ijk[2] ) ;
03758          }
03759       }
03760       break ;
03761 
03762    } /* end of switch on callback reasons */
03763 
03764   EXRETURN ;
03765 }
03766 
03767 /*----------------------------------------------------------------------
03768    read the files specified on the command line
03769    and create the data structures
03770 ------------------------------------------------------------------------*/
03771 
03772 void AFNI_read_inputs( int argc , char *argv[] )
03773 {
03774    int id , last_color ;
03775    Boolean isfunc ;
03776 
03777 ENTRY("AFNI_read_inputs") ;
03778 
03779    /* create empty library of dataset sessions */
03780 
03781    GLOBAL_library.sslist = myXtNew( THD_sessionlist ) ;
03782    GLOBAL_library.sslist->type = SESSIONLIST_TYPE ;
03783    BLANK_SESSIONLIST(GLOBAL_library.sslist) ;
03784    GLOBAL_library.sslist->parent = NULL ;
03785 
03786    /*----- read files -----*/
03787 
03788    if( GLOBAL_argopt.first_file_arg >= argc && GLOBAL_argopt.read_images ){
03789       FatalError("No image files on command line!!") ;
03790    }
03791 
03792    /*--- read directly from images (the old-fashioned way) ---*/
03793 
03794    if( GLOBAL_argopt.read_images ){
03795       THD_3dim_dataset *dset ;
03796       THD_session *new_ss ;
03797       int vv ;
03798       int gnim ;  /* 16 Mar 1998: names from globbing */
03799       char **gname ;
03800 
03801       MCW_warn_expand(1) ;  /* 13 Jul 2001 */
03802 
03803       MCW_file_expand( argc - GLOBAL_argopt.first_file_arg ,
03804                        &(argv[GLOBAL_argopt.first_file_arg]) ,
03805                        &gnim , &gname ) ;
03806 
03807       MCW_warn_expand(0) ;  /* 13 Jul 2001 */
03808 
03809       if( gnim < 1 )
03810         FatalError("No valid filenames on command line?!" ) ;
03811 
03812       dset = AFNI_read_images( gnim , gname ) ;
03813 
03814       if( dset == NULL )
03815         FatalError("Could not form 3D dataset from images!" ) ;
03816 
03817       MCW_free_expand( gnim , gname ) ;
03818 
03819       /* set up minuscule session and session list */
03820 
03821       new_ss              = myXtNew( THD_session ) ;
03822       new_ss->type        = SESSION_TYPE ;
03823       BLANK_SESSION(new_ss) ;
03824       new_ss->num_dsset   = 1 ;
03825       new_ss->dsset[0][0] = dset ;
03826       new_ss->parent      = NULL ;
03827 
03828       MCW_strncpy( new_ss->sessname ,
03829                    argv[GLOBAL_argopt.first_file_arg] , THD_MAX_NAME ) ;
03830       MCW_strncpy( new_ss->lastname ,
03831                    argv[GLOBAL_argopt.first_file_arg] , THD_MAX_NAME ) ;
03832 
03833       GLOBAL_library.sslist->num_sess   = 1 ;
03834       GLOBAL_library.sslist->ssar[0]    = new_ss ;
03835       GLOBAL_library.have_dummy_dataset = 1 ;
03836 
03837    } /** end of images input **/
03838 
03839    /*--- sessions of 3D datasets (from to3d or other AFNI programs) ---*/
03840 
03841    else if( GLOBAL_argopt.read_sessions ){
03842 
03843       char str[256] ;
03844       Boolean good ;
03845       int num_ss , qd , qs , vv=0 , no_args , jj , nskip_noanat=0 ;
03846       THD_string_array *flist , *dlist=NULL ;
03847       char *dname , *eee ;
03848       THD_session *new_ss ;
03849       int num_dsets=0 ;       /* 04 Jan 2000 */
03850       THD_session *gss=NULL ; /* 11 May 2002: global session */
03851       THD_session *dss ;      /* 28 Aug 2003: session for command-line datasets */
03852 
03853       /*-- 20 Dec 2001: Try to read a "global" session --*/
03854       /*-- 11 May 2002: Move read global session up here --*/
03855 
03856       eee = getenv( "AFNI_GLOBAL_SESSION" ) ;   /* where it's supposed to be */
03857       if( eee != NULL ){
03858          gss =
03859           GLOBAL_library.session = THD_init_session( eee ); /* try to read datasets */
03860 
03861          if( gss != NULL ){                               /* got at least one */
03862             gss->parent = NULL ;                          /* parentize them */
03863             for( qd=0 ; qd < gss->num_dsset ; qd++ )
03864               for( vv=0 ; vv <= LAST_VIEW_TYPE ; vv++ ){
03865                 PARENTIZE( gss->dsset[qd][vv] , NULL ) ;
03866                 DSET_MARK_FOR_IMMORTALITY( gss->dsset[qd][vv] ) ;
03867               }
03868          } else {
03869            sprintf(str,"\n*** No datasets in AFNI_GLOBAL_SESSION=%s",eee) ;
03870            REPORT_PROGRESS(str) ;
03871          }
03872       }
03873 
03874       /* 28 Aug 2003:
03875          set up session for datasets from command line (vs. directories) */
03876 
03877       dss         = myXtNew( THD_session ) ;
03878       dss->type   = SESSION_TYPE ;
03879       dss->parent = NULL ;
03880       BLANK_SESSION(dss) ;
03881       MCW_strncpy( dss->sessname , "from CLI" , THD_MAX_NAME ) ;
03882       MCW_strncpy( dss->lastname , "from CLI" , THD_MAX_NAME ) ;
03883 
03884       /* now get the list of strings to read as directories */
03885 
03886       num_ss  = argc - GLOBAL_argopt.first_file_arg ;
03887       no_args = (num_ss < 1) ;
03888 
03889       INIT_SARR(dlist) ;
03890       if( no_args ){
03891          if( GLOBAL_argopt.recurse > 0 ){
03892 STATUS("no args: recursion on ./") ;
03893             flist = THD_get_all_subdirs( GLOBAL_argopt.recurse , "./" ) ;
03894             if( flist != NULL ){
03895                for( jj=0 ; jj < flist->num ; jj++ ){
03896                  ADDTO_SARR(dlist,flist->ar[jj]) ;
03897                }
03898                DESTROY_SARR(flist) ;
03899             }
03900          } else {
03901 STATUS("no args: using ./") ;
03902            ADDTO_SARR(dlist,"./") ;
03903          }
03904       } else {
03905          for( id=0 ; id < num_ss ; id++ ){
03906             if( GLOBAL_argopt.recurse > 0 ){
03907                flist = THD_get_all_subdirs( GLOBAL_argopt.recurse ,
03908                                             argv[GLOBAL_argopt.first_file_arg+id] ) ;
03909                if( flist != NULL ){
03910                   for( jj=0 ; jj < flist->num ; jj++ ){
03911                     ADDTO_SARR(dlist,flist->ar[jj]) ;
03912                   }
03913                   DESTROY_SARR(flist) ;
03914                }
03915             } else {
03916               ADDTO_SARR(dlist,argv[GLOBAL_argopt.first_file_arg+id]) ;
03917             }
03918          }
03919       }
03920 
03921       if( dlist->num < 1 ) ADDTO_SARR(dlist,"./") ;  /* just in case */
03922 
03923       /** 09 Sep 1998: eliminate duplicates from the directory list **/
03924 
03925       { THD_string_array * qlist ;
03926 STATUS("normalizing directory list") ;
03927         qlist = THD_normalize_flist( dlist ) ;
03928         if( qlist != NULL ){ DESTROY_SARR(dlist) ; dlist = qlist ; }
03929       }
03930 
03931       REFRESH ;
03932 
03933       /* read each session, set parents, put into session list */
03934 
03935       num_ss = dlist->num ;
03936       for( id=0 ; id < num_ss ; id++ ){
03937 
03938 if(PRINT_TRACING)
03939 { char str[256] ;
03940   sprintf(str,"try to read directory %s",dlist->ar[id]) ; STATUS(str) ; }
03941 
03942          dname  = dlist->ar[id] ;                /* try to read datasets from */
03943          new_ss = THD_init_session( dname ) ;    /* this directory name       */
03944 
03945          REFRESH ;
03946 
03947          if( new_ss == NULL ){ /* 28 Aug 2003 */
03948            qd = dss->num_dsset ;
03949            if( qd < THD_MAX_SESSION_SIZE ){
03950              THD_3dim_dataset *dset = THD_open_dataset( dname ) ;
03951              if( dset != NULL ){
03952                dss->dsset[qd][dset->view_type] = dset ;
03953                dss->num_dsset ++ ;
03954              } else {
03955                fprintf(stderr,
03956                        "\n** Couldn't open %s as session OR as dataset!" ,
03957                        dname ) ;
03958              }
03959            }
03960          }
03961 
03962          if( new_ss != NULL && new_ss->num_dsset > 0 ){ /* got something? */
03963 
03964             /* set parent pointers */
03965 
03966             new_ss->parent = NULL ;
03967             for( qd=0 ; qd < new_ss->num_dsset ; qd++ )
03968               for( vv=0 ; vv <= LAST_VIEW_TYPE ; vv++ )
03969                 PARENTIZE( new_ss->dsset[qd][vv] , NULL ) ;
03970 
03971             /* put the new session into place in the list of sessions */
03972 
03973             GLOBAL_library.sslist->ssar[(GLOBAL_library.sslist->num_sess)++] = new_ss ;
03974 
03975             sprintf(str,"\n session #%3d  = %s ==> %d dataset%s" ,
03976                     GLOBAL_library.sslist->num_sess ,
03977                     new_ss->sessname , new_ss->num_dsset ,
03978                     (new_ss->num_dsset > 1) ? "s" : " " ) ;
03979             REPORT_PROGRESS(str) ;
03980 
03981             num_dsets += new_ss->num_dsset ;
03982 
03983             /* 28 Aug 2002: add any inter-dataset warps to global warptable */
03984 
03985             if( new_ss->warptable != NULL ){
03986               if( GLOBAL_library.warptable == NULL ) /* create global warptable */
03987                 GLOBAL_library.warptable = new_Htable(101) ;
03988               subsume_Htable( new_ss->warptable , GLOBAL_library.warptable ) ;
03989               destroy_Htable( new_ss->warptable ) ;
03990               new_ss->warptable = NULL ;
03991             }
03992 
03993             /* 11 May 2002: put global datasets into session now */
03994 
03995             if( new_ss != NULL && gss != NULL )
03996               AFNI_append_sessions( new_ss , gss ) ;
03997 
03998             /* if we've maxed out on sessions AND
03999                if this isn't the last command line argument ... */
04000 
04001             if( GLOBAL_library.sslist->num_sess == THD_MAX_NUM_SESSION &&
04002                 id < num_ss-1 ){
04003                sprintf(str,"\n *** reached max no. sessions (%d) ***",
04004                        THD_MAX_NUM_SESSION) ;
04005                REPORT_PROGRESS(str) ;
04006                break ;                            /* exit the loop over id */
04007             }
04008          }
04009 
04010       }  /* end of id loop (over input directory names) */
04011 
04012       /* 28 Aug 2003: if have dataset in session dss, use it */
04013 
04014       if( dss->num_dsset > 0 ){
04015         if( GLOBAL_library.sslist->num_sess < THD_MAX_NUM_SESSION ){
04016           GLOBAL_library.sslist->ssar[(GLOBAL_library.sslist->num_sess)++] = dss ;
04017           num_dsets += dss->num_dsset ;
04018           sprintf(str,"\n session #%3d  = %s ==> %d dataset%s" ,
04019                   GLOBAL_library.sslist->num_sess, dss->sessname, dss->num_dsset,
04020                   (dss->num_dsset > 1) ? "s" : " " ) ;
04021           REPORT_PROGRESS(str) ;
04022           if( gss != NULL ) AFNI_append_sessions( dss , gss ) ;
04023         } else {
04024           fprintf(stderr,"\n** Can't use command line datasets: session overflow!\n") ;
04025           free(dss) ;
04026         }
04027       } else {
04028         free(dss) ;
04029       }
04030 
04031       /* 11 May 2002: if have global session but no others, use it */
04032 
04033       if( gss != NULL && GLOBAL_library.sslist->num_sess == 0 ){
04034 
04035         GLOBAL_library.sslist->ssar[(GLOBAL_library.sslist->num_sess)++] = gss ;
04036 
04037         sprintf(str,"\n AFNI_GLOBAL_SESSION = %s %d datasets" ,
04038             gss->sessname , gss->num_dsset ) ;
04039 
04040         num_dsets += gss->num_dsset ;
04041 
04042         REPORT_PROGRESS(str) ;
04043       }
04044 
04045       /** if nothing read at all, make up a dummy **/
04046 
04047       GLOBAL_library.have_dummy_dataset = 0 ;
04048 
04049 #define QQ_NXYZ 16
04050 #define QQ_NT   12
04051 #define QQ_FOV  240.0
04052 
04053       if( GLOBAL_library.sslist->num_sess <= 0 ){
04054          byte * bar ;  /* as opposed to a bite bar */
04055          int ii , nbar , jj ;
04056          THD_ivec3 nxyz ;
04057          THD_fvec3 fxyz , oxyz ;
04058          char *snam = dlist->ar[0] ; /* 10 Mar 2002 */
04059 
04060          if( !THD_is_directory(snam) ) snam = "./" ;
04061 
04062          REPORT_PROGRESS("\n*** No datasets or sessions input -- Dummy dataset created.") ;
04063 
04064          /** manufacture a minimal session **/
04065 
04066          new_ss         = myXtNew( THD_session ) ;
04067          new_ss->type   = SESSION_TYPE ;
04068          new_ss->parent = NULL ;
04069          BLANK_SESSION(new_ss) ;
04070          MCW_strncpy( new_ss->sessname , snam , THD_MAX_NAME ) ; /* pretend dummy session */
04071          MCW_strncpy( new_ss->lastname , snam , THD_MAX_NAME ) ; /* is first argv directory */
04072          GLOBAL_library.sslist->num_sess   = 1 ;
04073          GLOBAL_library.sslist->ssar[0]    = new_ss ;
04074          GLOBAL_library.have_dummy_dataset = 1 ;
04075 
04076          /** manufacture a minimal dataset **/
04077 
04078          new_ss->num_dsset   = 1 ;
04079          new_ss->dsset[0][0] = EDIT_empty_copy(NULL) ;
04080          nxyz.ijk[0] = nxyz.ijk[1] = nxyz.ijk[2] = QQ_NXYZ ;
04081          fxyz.xyz[0] = fxyz.xyz[1] = fxyz.xyz[2] = QQ_FOV / QQ_NXYZ ;
04082          oxyz.xyz[0] = oxyz.xyz[1] = oxyz.xyz[2] = -0.5 * QQ_FOV ;
04083          ii = EDIT_dset_items( new_ss->dsset[0][0] ,
04084                                  ADN_datum_all     , MRI_byte            ,
04085                                  ADN_nxyz          , nxyz                ,
04086                                  ADN_xyzdel        , fxyz                ,
04087                                  ADN_xyzorg        , oxyz                ,
04088                                  ADN_directory_name, snam                ,
04089                                  ADN_prefix        , "Dummy"             ,
04090                                  ADN_nvals         , QQ_NT               ,
04091                                  ADN_malloc_type   , DATABLOCK_MEM_MALLOC,
04092                                  ADN_type          , HEAD_ANAT_TYPE      ,
04093                                  ADN_view_type     , VIEW_ORIGINAL_TYPE  ,
04094                                  ADN_func_type     , ANAT_EPI_TYPE       ,
04095 #if QQ_NT > 1
04096                                  ADN_ntt            , QQ_NT                ,
04097                                  ADN_ttdel          , 1.0                  ,
04098                                  ADN_ttorg          , 0.0                  ,
04099                                  ADN_ttdur          , 0.0                  ,
04100                                  ADN_tunits         , UNITS_SEC_TYPE       ,
04101 #endif
04102                               ADN_none ) ;
04103          if( ii > 0 ){
04104            fprintf(stderr,"\n%d errors creating dummy dataset!\a\n",ii) ;
04105            exit(1) ;
04106          }
04107          DSET_lock(new_ss->dsset[0][0]) ; /* lock into memory */
04108 
04109          nbar = DSET_BRICK_BYTES(new_ss->dsset[0][0],0) ;
04110 
04111 #ifdef NO_FRIVOLITIES
04112          for( jj=0 ; jj < QQ_NT ; jj++ ){
04113             bar    = (byte *) malloc( nbar ) ;
04114             bar[0] = (byte) (lrand48()%127) ;
04115             for( ii=1 ; ii < nbar ; ii++ )
04116                bar[ii] = bar[ii-1] + lrand48()%(jj+2) ;
04117             EDIT_substitute_brick( new_ss->dsset[0][0] , jj , MRI_byte , bar ) ;
04118          }
04119 #else
04120         { /* 11 Jun 1999: start of loading RWCOX images into dummy dataset */
04121           static byte rrr[QQ_NXYZ*QQ_NXYZ] = {
04122             0,0,0,0,10,94,135,135,135,135,135,135,135,135,135,135,
04123             0,0,0,32,216,255,255,255,255,255,255,255,255,255,255,255,
04124             0,0,4,171,255,255,255,255,255,255,255,255,255,255,255,255,
04125             0,0,22,255,255,255,255,241,162,75,75,140,255,255,255,255,
04126             0,0,22,255,255,255,255,100,0,0,0,92,255,255,255,255,
04127             0,0,22,255,255,255,255,71,0,0,0,92,255,255,255,255,
04128             0,0,13,213,255,255,255,234,193,105,105,160,255,255,255,255,
04129             0,0,0,95,255,255,255,255,255,255,255,255,255,255,255,255,
04130             0,0,0,0,75,209,255,255,255,250,239,245,255,255,255,255,
04131             0,0,0,0,22,220,255,255,255,105,0,92,255,255,255,255,
04132             0,0,0,0,118,255,255,255,243,45,0,92,255,255,255,255,
04133             0,0,0,21,228,255,255,255,157,0,0,92,255,255,255,255,
04134             0,0,0,124,255,255,255,255,63,0,0,92,255,255,255,255,
04135             0,0,18,237,255,255,255,205,11,0,0,92,255,255,255,255,
04136             0,0,73,255,255,255,255,85,0,0,0,92,255,255,255,255,
04137             0,6,128,134,134,134,134,37,0,0,0,48,134,134,134,134 } ;
04138 
04139           static byte www[QQ_NXYZ*QQ_NXYZ] = {
04140             0,45,135,135,0,0,0,135,135,95,0,0,5,135,135,135,
04141             0,74,255,255,11,0,10,255,255,255,0,0,85,255,255,205,
04142             0,0,254,255,86,0,84,255,255,255,15,0,100,255,255,155,
04143             0,0,234,255,106,0,105,255,255,255,85,0,170,255,255,85,
04144             0,0,169,255,171,0,169,255,255,255,110,0,195,255,255,60,
04145             0,0,99,255,201,0,200,255,255,255,170,0,255,255,255,0,
04146             0,0,84,255,255,1,254,255,255,255,205,35,255,255,180,0,
04147             0,0,5,254,255,81,255,255,135,255,255,85,255,255,170,0,
04148             0,0,0,249,255,170,255,255,85,249,255,135,255,255,85,0,
04149             0,0,0,169,255,220,255,255,35,170,255,255,255,255,75,0,
04150             0,0,0,114,255,255,255,240,0,154,255,255,255,255,0,0,
04151             0,0,0,84,255,255,255,171,0,85,255,255,255,195,0,0,
04152             0,0,0,20,254,255,255,145,0,59,255,255,255,170,0,0,
04153             0,0,0,0,254,255,255,86,0,0,255,255,255,100,0,0,
04154             0,0,0,0,179,255,255,50,0,0,179,255,255,50,0,0,
04155             0,0,0,0,89,134,134,0,0,0,89,134,134,0,0,0 } ;
04156 
04157           static byte ccc[QQ_NXYZ*QQ_NXYZ] = {
04158             0,0,0,0,2,94,160,255,255,219,135,92,9,0,0,0,
04159             0,0,0,17,165,255,255,255,255,255,255,255,214,41,2,0,
04160             0,0,4,128,255,255,255,255,255,255,255,255,255,255,38,0,
04161             0,0,22,255,255,255,242,108,75,111,244,255,255,255,167,2,
04162             0,0,116,255,255,255,202,0,0,0,113,255,255,255,255,44,
04163             0,0,94,165,165,165,72,0,0,0,15,223,255,255,255,131,
04164             0,0,0,0,0,0,0,0,0,0,0,216,255,255,255,183,
04165             0,0,0,0,0,0,0,0,0,0,0,216,255,255,255,255,
04166             0,0,0,0,0,0,0,0,0,0,0,216,255,255,255,247,
04167             0,0,0,0,0,0,0,0,0,0,0,216,255,255,255,131,
04168             0,0,94,166,166,136,0,0,0,0,55,241,255,255,255,131,
04169             0,0,116,255,255,242,85,0,0,0,114,255,255,255,255,44,
04170             0,0,15,225,255,255,243,109,76,112,244,255,255,255,166,2,
04171             0,0,0,109,255,255,255,255,255,255,255,255,255,217,31,0,
04172             0,0,0,3,105,219,255,255,255,255,255,255,162,28,0,0,
04173             0,0,0,0,0,9,97,134,225,160,134,91,2,0,0,0 } ;
04174 
04175           static byte ooo[QQ_NXYZ*QQ_NXYZ] = {
04176             0,0,0,0,0,12,121,135,255,255,234,107,11,0,0,0,
04177             0,0,0,0,58,236,255,255,255,255,255,255,224,108,4,0,
04178             0,0,0,60,234,255,255,255,255,255,255,255,255,255,51,0,
04179             0,0,10,197,255,255,255,171,75,75,163,255,255,255,224,11,
04180             0,0,80,255,255,255,224,39,0,0,31,233,255,255,255,107,
04181             0,0,164,255,255,255,151,0,0,0,0,180,255,255,255,135,
04182             0,12,202,255,255,255,151,0,0,0,0,180,255,255,255,185,
04183             0,29,255,255,255,255,151,0,0,0,0,180,255,255,255,255,
04184             0,27,249,255,255,255,151,0,0,0,0,180,255,255,255,248,
04185             0,0,164,255,255,255,151,0,0,0,0,180,255,255,255,135,
04186             0,0,164,255,255,255,169,3,0,0,0,180,255,255,255,135,
04187             0,0,79,255,255,255,255,44,0,0,60,233,255,255,255,50,
04188             0,0,10,197,255,255,255,171,76,90,234,255,255,255,174,3,
04189             0,0,0,59,233,255,255,255,255,255,255,255,255,223,40,0,
04190             0,0,0,0,57,186,255,255,255,255,255,255,139,19,0,0,
04191             0,0,0,0,0,5,119,134,191,134,134,49,3,0,0,0 } ;
04192 
04193           static byte xxx[QQ_NXYZ*QQ_NXYZ] = {
04194             0,0,21,131,135,135,135,8,0,0,3,100,135,135,135,128,
04195             0,0,0,108,255,255,255,86,0,0,115,255,255,255,255,121,
04196             0,0,0,21,216,255,255,213,0,19,223,255,255,255,187,5,
04197             0,0,0,0,92,244,255,255,114,114,255,255,255,234,58,0,
04198             0,0,0,0,0,174,255,255,252,230,255,255,255,130,0,0,
04199             0,0,0,0,0,58,244,255,255,255,255,255,228,29,0,0,
04200             0,0,0,0,0,0,118,255,255,255,255,255,74,0,0,0,
04201             0,0,0,0,0,0,55,248,255,255,255,199,3,0,0,0,
04202             0,0,0,0,0,5,170,255,255,255,255,227,32,0,0,0,
04203             0,0,0,0,0,104,255,255,255,255,255,255,140,5,0,0,
04204             0,0,0,0,13,217,255,255,252,215,255,255,255,67,0,0,
04205             0,0,0,0,159,255,255,255,212,23,233,255,255,187,7,0,
04206             0,0,0,81,241,255,255,255,85,0,72,255,255,255,66,0,
04207             0,0,16,206,255,255,255,212,0,0,8,193,255,255,237,12,
04208             0,0,94,255,255,255,255,86,0,0,0,73,255,255,255,121,
04209             0,14,129,134,134,134,85,1,0,0,0,3,106,134,134,127 } ;
04210 
04211           static byte bob[QQ_NXYZ*QQ_NXYZ] = {
04212                0,0,0,60,101,133,155,165,173,161,112,54,0,0,0,0,
04213                0,48,104,139,141,144,154,164,162,183,195,162,76,0,0,0,
04214                0,111,126,119,120,132,146,174,172,194,222,226,195,88,0,0,
04215                70,112,100,90,108,123,175,222,229,242,247,249,246,195,50,0,
04216                54,53,75,87,110,129,161,219,247,249,250,250,250,241,76,0,
04217                53,55,93,112,116,124,151,212,243,249,250,250,249,228,103,0,
04218                52,62,97,134,131,125,126,154,213,242,250,250,248,200,121,0,
04219                50,66,89,140,130,120,125,130,151,172,187,209,242,221,174,99,
04220                46,71,106,150,132,79,77,111,145,133,108,159,231,247,203,174,
04221                110,124,134,140,114,95,78,104,211,232,205,231,250,250,221,167,
04222                103,115,150,146,126,104,102,120,170,215,209,202,245,250,245,103,
04223                62,115,140,151,136,116,102,108,110,172,225,138,184,243,123,0,
04224                0,56,94,122,143,128,106,106,91,122,166,113,146,197,50,0,
04225                0,0,0,60,140,139,119,120,117,124,164,160,152,71,0,0,
04226                0,0,0,0,69,124,138,131,120,168,227,194,81,0,0,0,
04227                0,0,0,0,0,49,69,103,131,153,141,54,0,0,0,0 } ;
04228 
04229           static byte * rwcox[6] = { rrr,www,ccc,ooo,xxx,bob } ;
04230           int kk ;
04231 
04232             for( jj=0 ; jj < QQ_NT ; jj++ ){
04233                bar = (byte *) malloc( nbar ) ;
04234                for( kk=0 ; kk < QQ_NXYZ ; kk++ )
04235                   memcpy( bar + kk*QQ_NXYZ*QQ_NXYZ , rwcox[jj%6] , QQ_NXYZ*QQ_NXYZ ) ;
04236                EDIT_substitute_brick( new_ss->dsset[0][0] , jj , MRI_byte , bar ) ;
04237             }
04238           } /* end of loading RWCOX */
04239 #endif
04240 
04241          PARENTIZE( new_ss->dsset[0][0] , NULL ) ;
04242 
04243       } else {  /* 04 Jan 2000: show total number of datasets */
04244 
04245          sprintf(str,"\n dataset count = %d" , num_dsets ) ;
04246          GLOBAL_num_dsets = num_dsets ;
04247          REPORT_PROGRESS(str) ;
04248       }
04249 
04250       /*** read all timeseries files from all directories ***/
04251 
04252 STATUS("reading timeseries files") ;
04253 
04254       /* 27 Jan 2000: allow skipping *.1D files from dataset directories */
04255 
04256       GLOBAL_library.timeseries =
04257            THD_get_many_timeseries( (GLOBAL_argopt.read_1D) ? dlist : NULL ) ;
04258 
04259       REFRESH ;
04260 
04261       if( GLOBAL_library.timeseries == NULL )
04262          INIT_IMARR(GLOBAL_library.timeseries) ;
04263 
04264       sprintf( str , "\n Time series   = %d files read" ,
04265                IMARR_COUNT(GLOBAL_library.timeseries) ) ;
04266       REPORT_PROGRESS(str) ;
04267 
04268       /*** throw away the list of directories that were scanned ***/
04269 
04270       DESTROY_SARR(dlist) ;
04271 
04272       /* assign the warp and anatomy parent pointers;
04273          then, make any datasets that don't exist but logically
04274          descend from the warp and anatomy parents just assigned */
04275 
04276       if( !GLOBAL_library.have_dummy_dataset ){
04277 
04278         STATUS("checking idcodes for duplicates") ;
04279         THD_check_idcodes( GLOBAL_library.sslist ) ;     /* 08 Jun 1999 */
04280 
04281         STATUS("reconciling parent pointers") ;
04282         THD_reconcile_parents( GLOBAL_library.sslist ) ;
04283 
04284         STATUS("forcible adoption of unparented datasets") ;
04285         for( id=0 ; id < GLOBAL_library.sslist->num_sess ; id++ ){ /* functions w/o parents, */
04286           new_ss = GLOBAL_library.sslist->ssar[id] ;               /* forcibly get one */
04287           AFNI_force_adoption( new_ss , GLOBAL_argopt.warp_4D ) ;
04288        }
04289 
04290       } /* end of if don't have dummy dataset */
04291 
04292       if( GLOBAL_library.session != NULL )
04293          AFNI_force_adoption( GLOBAL_library.session , GLOBAL_argopt.warp_4D ) ;
04294 
04295 STATUS("making descendant datasets") ;
04296 
04297       AFNI_make_descendants( GLOBAL_library.sslist ) ;
04298 
04299    } /** end of sessions input **/
04300 
04301    else if( GLOBAL_argopt.read_dsets ){  /* 17 Mar 2000 */
04302 
04303       int nds = argc - GLOBAL_argopt.first_file_arg ;
04304       char str[256] ;
04305       THD_3dim_dataset * dset ;
04306       XtPointer_array * dsar ;
04307       MRI_IMARR * webtsar ;        /* 26 Mar 2001 */
04308       THD_session * new_ss ;
04309       int ii,nerr=0,vv,nn , dd ;
04310 
04311       if( nds <= 0 ){
04312          fprintf(stderr,"\a\n*** No datasets on command line?!\n"); exit(1);
04313       }
04314       nds = 0 ;
04315 
04316       /* set up minuscule session and session list */
04317 
04318       new_ss             = myXtNew( THD_session ) ;
04319       new_ss->type       = SESSION_TYPE ;
04320       BLANK_SESSION(new_ss) ;
04321       new_ss->parent     = NULL ;
04322 
04323       strcpy( new_ss->sessname , "." ) ;
04324       strcpy( new_ss->lastname , "." ) ;
04325 
04326       GLOBAL_library.sslist->num_sess   = 1 ;
04327       GLOBAL_library.sslist->ssar[0]    = new_ss ;
04328       GLOBAL_library.have_dummy_dataset = 0 ;
04329 
04330       /* read datasets from command line */
04331 
04332 STATUS("reading commandline dsets") ;
04333 
04334       INIT_IMARR(webtsar) ; /* 26 Mar 2001 */
04335 
04336       for( ii=GLOBAL_argopt.first_file_arg ; ii < argc ; ii++ ){
04337 
04338          /** 23 Mar 2001: modified code to deal with an array of
04339                           datasets, rather than just one at a time **/
04340 
04341          if( strstr(argv[ii],"://")      != NULL &&
04342              strstr(argv[ii],"AFNILIST") != NULL   ){ /** 23 Mar 2001: read from Web list **/
04343 
04344             dsar = THD_fetch_many_datasets( argv[ii] ) ;
04345             if( dsar == NULL || dsar->num == 0 ){
04346                fprintf(stderr,"\a\n*** Can't read datasets from %s\n",argv[ii]) ;
04347                nerr++ ; continue ; /* next ii */
04348             }
04349 
04350          } else { /** read from one file (local or Web), make a small array **/
04351 
04352             dset = THD_open_dataset( argv[ii] ) ;
04353             if( dset == NULL ){
04354                fprintf(stderr,"\a\n*** Can't read dataset %s\n",argv[ii]) ;
04355                nerr++ ; continue ; /* next ii */
04356             }
04357             INIT_XTARR(dsar) ; ADDTO_XTARR(dsar,dset) ; XTARR_IC(dsar,0) = IC_DSET ;
04358          }
04359 
04360          for( dd=0 ; dd < dsar->num ; dd++ ){  /* loop over all entries in array */
04361 
04362             /* 26 Mar 2001: might get some 1D files, too */
04363 
04364             if( XTARR_IC(dsar,dd) == IC_FLIM ){  /* save 1D file for later */
04365                MRI_IMAGE *im = (MRI_IMAGE *) XTARR_XT(dsar,dd) ;
04366                ADDTO_IMARR(webtsar,im) ;
04367                continue ;              /* next one */
04368             }
04369             if( XTARR_IC(dsar,dd) != IC_DSET ){
04370                fprintf(stderr,"\n** Unknown filetype returned from %s\n",argv[ii]) ;
04371                nerr++ ; continue ;   /* bad */
04372             }
04373 
04374             /* get to here ==> have a dataset */
04375 
04376             dset = (THD_3dim_dataset *) XTARR_XT(dsar,dd) ;
04377             if( !ISVALID_DSET(dset) ) continue ;            /* bad */
04378             nds++ ;   /* increment count of dataset */
04379             REFRESH ;
04380             vv = dset->view_type ;
04381             nn = new_ss->num_dsset ;
04382             if( nn >= THD_MAX_SESSION_SIZE ){
04383               fprintf(stderr,"\a\n*** too many datasets!\n") ;
04384               nerr++ ;
04385             } else {
04386               new_ss->dsset[nn][vv] = dset ;
04387               new_ss->num_dsset ++ ;
04388             }
04389          } /* end of loop over dd=datasets in dsar */
04390 
04391          FREE_XTARR(dsar) ;  /* don't need array no more */
04392 
04393       } /* end of loop over ii=command line arguments past options */
04394 
04395       if( nerr > 0 ){
04396          fprintf(stderr,"** FATAL ERRORS on input\n") ; exit(1) ;  /* bad */
04397       }
04398 
04399       sprintf(str,"\n dataset count = %d" , nds ) ;
04400       if( new_ss->num_dsset == 0 ){
04401          fprintf(stderr,"\n*** No datasets read from the list!\n") ;
04402          exit(1) ;
04403       }
04404       REPORT_PROGRESS(str) ;
04405 
04406 STATUS("reading timeseries files") ;
04407 
04408       GLOBAL_library.timeseries = THD_get_many_timeseries( NULL ) ;
04409 
04410       REFRESH ;
04411 
04412       if( GLOBAL_library.timeseries == NULL )
04413          INIT_IMARR(GLOBAL_library.timeseries) ;
04414 
04415       /* 26 Mar 2001: store timeseries fetched from the Web */
04416 
04417       for( dd=0 ; dd < IMARR_COUNT(webtsar) ; dd++ )
04418          AFNI_add_timeseries( IMARR_SUBIMAGE(webtsar,dd) ) ;
04419 
04420       FREE_IMARR(webtsar) ;
04421 
04422       sprintf( str , "\n Time series   = %d files read" ,
04423                IMARR_COUNT(GLOBAL_library.timeseries) ) ;
04424       REPORT_PROGRESS(str) ;
04425 
04426       /* assign the warp and anatomy parent pointers;
04427          then, make any datasets that don't exist but logically
04428          descend from the warp and anatomy parents just assigned */
04429 
04430 STATUS("checking idcodes for duplicates") ;
04431 
04432       THD_check_idcodes( GLOBAL_library.sslist ) ;
04433 
04434 #if 0
04435 STATUS("reconciling parent pointers") ;
04436 
04437       THD_reconcile_parents( GLOBAL_library.sslist ) ; /* parents from .HEAD files */
04438 
04439 STATUS("forcible adoption of unparented datasets") ;
04440 
04441       for( id=0 ; id < GLOBAL_library.sslist->num_sess ; id++ ){  /* functions w/o parents, */
04442          new_ss = GLOBAL_library.sslist->ssar[id] ;               /* forcibly get one */
04443          AFNI_force_adoption( new_ss , GLOBAL_argopt.warp_4D ) ;
04444       }
04445 #endif
04446 
04447    }  /** end of read datasets from command line **/
04448 
04449    else {  /* should never occur! */
04450 
04451      fprintf(stderr,"\a\n*** Illegal Usage configuration detected!\n"); exit(1);
04452    }
04453 
04454    /** done at last **/
04455 
04456    MPROBE ; EXRETURN ;
04457 }
04458 
04459 /*--------------------------------------------------------------------------
04460   Final adjustments before a controller is opened for use - 15 Jun 2000
04461 ----------------------------------------------------------------------------*/
04462 
04463 void AFNI_startup_3dview( Three_D_View * im3d )
04464 {
04465    static int old_0D_num=0 , old_2D_num=0 ;
04466 
04467 ENTRY("AFNI_startup_3dview") ;
04468 
04469    if( ! IM3D_VALID(im3d) ) EXRETURN ;
04470 
04471    /* the pbar Tran 0D menu */
04472 
04473    if( GLOBAL_library.registered_0D.num != old_0D_num ){
04474       old_0D_num = GLOBAL_library.registered_0D.num ;
04475       refit_MCW_optmenu( im3d->vwid->func->pbar_transform0D_av ,
04476                            0 ,                                 /* new minval */
04477                            GLOBAL_library.registered_0D.num ,  /* new maxval */
04478                            0 ,                                 /* new inival */
04479                            0 ,                                 /* new decim? */
04480                            ISQ_transform_label ,               /* text func  */
04481                            &(GLOBAL_library.registered_0D)     /* text data  */
04482                         ) ;
04483       XtManageChild( im3d->vwid->func->pbar_transform0D_av->wrowcol ) ;
04484    } else {
04485       if( old_0D_num == 0 )
04486         XtUnmanageChild( im3d->vwid->func->pbar_transform0D_av->wrowcol ) ;
04487    }
04488 
04489    im3d->vwid->func->pbar_transform0D_index = 0 ;
04490    im3d->vwid->func->pbar_transform0D_func  = NULL ;
04491 
04492    /* the pbar Tran 2D menu */
04493 
04494    if( GLOBAL_library.registered_2D.num != old_2D_num ){
04495       old_2D_num = GLOBAL_library.registered_2D.num ;
04496       refit_MCW_optmenu( im3d->vwid->func->pbar_transform2D_av ,
04497                            0 ,                                 /* new minval */
04498                            GLOBAL_library.registered_2D.num ,  /* new maxval */
04499                            0 ,                                 /* new inival */
04500                            0 ,                                 /* new decim? */
04501                            ISQ_transform_label ,               /* text func  */
04502                            &(GLOBAL_library.registered_2D)     /* text data  */
04503                         ) ;
04504       XtManageChild( im3d->vwid->func->pbar_transform2D_av->wrowcol ) ;
04505    } else {
04506       if( old_2D_num == 0 )
04507         XtUnmanageChild( im3d->vwid->func->pbar_transform2D_av->wrowcol ) ;
04508    }
04509 
04510    im3d->vwid->func->pbar_transform2D_index = 0 ;
04511    im3d->vwid->func->pbar_transform2D_func  = NULL ;
04512 
04513    /* 08 Apr 2005: the cursor on the pbar? */
04514 
04515    if( im3d->vwid->func->inten_pbar->bigmode )
04516      POPUP_cursorize( im3d->vwid->func->inten_pbar->panew ) ;
04517 
04518    /* Hey Rocky!  Watch me pull a rabbit out of my hat! */
04519 
04520    EXRETURN ;
04521 }
04522 
04523 /*--------------------------------------------------------------------------
04524    delete the viewers associated with this controller panel
04525 ---------------------------------------------------------------------------*/
04526 
04527 void AFNI_closedown_3dview( Three_D_View * im3d )
04528 {
04529 ENTRY("AFNI_closedown_3dview") ;
04530 
04531    if( ! IM3D_VALID(im3d) ) EXRETURN ;
04532 
04533    /* Mar 1999: shutoff receivers, if any */
04534 
04535    AFNI_receive_destroy( im3d ) ;
04536 
04537    /* destroy any viewers attached */
04538 
04539    drive_MCW_imseq( im3d->s123 , isqDR_destroy , NULL ) ;
04540    drive_MCW_imseq( im3d->s231 , isqDR_destroy , NULL ) ;
04541    drive_MCW_imseq( im3d->s312 , isqDR_destroy , NULL ) ;
04542 
04543    drive_MCW_grapher( im3d->g123 , graDR_destroy , NULL ) ;
04544    drive_MCW_grapher( im3d->g231 , graDR_destroy , NULL ) ;
04545    drive_MCW_grapher( im3d->g312 , graDR_destroy , NULL ) ;
04546 
04547    /* erase FD bricks */
04548 
04549    myXtFree(im3d->b123_anat) ;
04550    myXtFree(im3d->b231_anat) ;
04551    myXtFree(im3d->b312_anat) ;
04552 
04553    myXtFree(im3d->b123_fim)  ;
04554    myXtFree(im3d->b231_fim)  ;
04555    myXtFree(im3d->b312_fim)  ;
04556 
04557    im3d->b123_ulay = im3d->b231_ulay = im3d->b312_ulay = NULL ;
04558 
04559    if( XtIsManaged(im3d->vwid->view->frame) == True )
04560       AFNI_controller_panel_CB( NULL , im3d , NULL ) ;
04561 
04562    /* null out montage info */
04563 
04564    LOAD_IVEC3(im3d->vinfo->xhairs_ndown,0,0,0) ;
04565    LOAD_IVEC3(im3d->vinfo->xhairs_nup  ,0,0,0) ;
04566    LOAD_IVEC3(im3d->vinfo->xhairs_nskip,0,0,0) ;
04567 
04568    /* de-fim */
04569 
04570    AFNI_fimmer_setref(im3d,NULL) ; CLEAR_FIMDATA(im3d) ;
04571 
04572    RESET_AFNI_QUIT(im3d) ;
04573 
04574    im3d->anat_now = im3d->fim_now = NULL ;
04575 
04576    AFNI_purge_unused_dsets() ;
04577 
04578    /* 19 Aug 2002: close surface widgets, too */
04579 
04580    if( im3d->vwid->view->swid != NULL )
04581      XtUnmapWidget( im3d->vwid->view->swid->wtop ) ;
04582 
04583    MPROBE ;
04584    EXRETURN ;
04585 }
04586 
04587 /*-------------------------------------------------------------------------
04588   Open or close the viewing controls panel
04589 ---------------------------------------------------------------------------*/
04590 void AFNI_controller_panel_CB( Widget wcall , XtPointer cd , XtPointer cbs )
04591 {
04592    Three_D_View * im3d = (Three_D_View *) cd ;
04593 
04594 ENTRY("AFNI_controller_panel_CB") ;
04595 
04596    if( ! IM3D_OPEN(im3d) || im3d->vwid->prog->panel_pb == NULL ) EXRETURN ;
04597 
04598    /** if view frame is open, close it and all its children **/
04599 
04600    if( XtIsManaged(im3d->vwid->view->frame) == True ){
04601 
04602       if( XtIsManaged(im3d->vwid->marks->frame) == True ){
04603          AFNI_marks_action_CB( NULL , (XtPointer) im3d , NULL ) ;
04604       }
04605 
04606       if( XtIsManaged(im3d->vwid->func->frame) ){
04607          CLOSE_PANEL(im3d,func) ;
04608       }
04609 
04610       if( XtIsManaged(im3d->vwid->dmode->frame) ){
04611          CLOSE_PANEL(im3d,dmode) ;
04612       }
04613 
04614       XtUnmanageChild(im3d->vwid->view->frame) ;
04615       if( im3d->vwid->prog->panel_pb_inverted ){
04616          MCW_invert_widget(im3d->vwid->prog->panel_pb) ;
04617          im3d->vwid->prog->panel_pb_inverted = False ;
04618       }
04619 
04620    } else {  /** open the view frame (but not its children) **/
04621 
04622       XtManageChild(im3d->vwid->view->frame) ;
04623       if( ! im3d->vwid->prog->panel_pb_inverted ){
04624          MCW_invert_widget(im3d->vwid->prog->panel_pb) ;
04625          im3d->vwid->prog->panel_pb_inverted = True ;
04626       }
04627    }
04628 
04629    RESET_AFNI_QUIT(im3d) ;
04630    EXRETURN ;
04631 }
04632 
04633 /*-------------------------------------------------------------------------
04634   Called when the user selects a new option for crosshair visibility
04635 ---------------------------------------------------------------------------*/
04636 
04637 void AFNI_crosshair_visible_CB( MCW_arrowval * av , XtPointer client_data )
04638 {
04639    Three_D_View * im3d = (Three_D_View *) client_data ;
04640    int val , omold ;
04641 
04642 ENTRY("AFNI_crosshair_visible_CB") ;
04643 
04644    if( ! IM3D_VALID(im3d) ) EXRETURN ;
04645 
04646    if( av->ival == av->old_ival ) EXRETURN ;
04647 
04648    switch( av->ival ){
04649       case AFNI_XHAIRS_OFF:
04650          im3d->vinfo->crosshair_visible   = False ;
04651          im3d->vinfo->xhairs_show_montage = False ;
04652       break ;
04653 
04654       case AFNI_XHAIRS_SINGLE:
04655          im3d->vinfo->crosshair_visible   = True ;
04656          im3d->vinfo->xhairs_show_montage = False ;
04657       break ;
04658 
04659       default:                                     /* 31 Dec 1998:  */
04660       case AFNI_XHAIRS_MULTI:                      /*   new options */
04661          im3d->vinfo->crosshair_visible   = True ; /*   like Multi  */
04662          im3d->vinfo->xhairs_show_montage = True ;
04663       break ;
04664    }
04665 
04666    /* 31 Dec 1998: only allow crosshairs of some orientations */
04667 
04668    omold = im3d->vinfo->xhairs_orimask ;  /* 02 Jun 1999 */
04669 
04670    switch( av->ival ){
04671       default:                im3d->vinfo->xhairs_orimask = ORIMASK_ALL  ; break;
04672       case AFNI_XHAIRS_LR_AP: im3d->vinfo->xhairs_orimask = ORIMASK_LR_AP; break;
04673       case AFNI_XHAIRS_LR_IS: im3d->vinfo->xhairs_orimask = ORIMASK_LR_IS; break;
04674       case AFNI_XHAIRS_AP_IS: im3d->vinfo->xhairs_orimask = ORIMASK_AP_IS; break;
04675       case AFNI_XHAIRS_LR:    im3d->vinfo->xhairs_orimask = ORIMASK_LR   ; break;
04676       case AFNI_XHAIRS_AP:    im3d->vinfo->xhairs_orimask = ORIMASK_AP   ; break;
04677       case AFNI_XHAIRS_IS:    im3d->vinfo->xhairs_orimask = ORIMASK_IS   ; break;
04678    }
04679 
04680    AFNI_set_viewpoint( im3d , -1,-1,-1 , REDISPLAY_OVERLAY ) ;
04681 
04682    /* 02 Jun 1999: if xhairs layout has changed, send a notice */
04683 
04684    if( omold != im3d->vinfo->xhairs_orimask ) AFNI_process_viewpoint( im3d ) ;
04685 
04686    RESET_AFNI_QUIT(im3d) ;
04687    EXRETURN ;
04688 }
04689 
04690 /*-----------------------------------------------------------------*/
04691 
04692 void AFNI_wrap_bbox_CB( Widget w ,
04693                         XtPointer client_data , XtPointer call_data )
04694 {
04695    Three_D_View * im3d = (Three_D_View *) client_data ;
04696    int bval ;
04697 
04698 ENTRY("AFNI_wrap_bbox_CB") ;
04699 
04700    if( ! IM3D_VALID(im3d) ) EXRETURN ;
04701 
04702    bval = MCW_val_bbox( im3d->vwid->imag->wrap_bbox ) ;
04703 
04704    if( (Boolean) bval == im3d->vinfo->xhairs_periodic ) EXRETURN ;
04705 
04706    im3d->vinfo->xhairs_periodic = (Boolean) bval ;
04707 
04708    if( w != NULL ){
04709       drive_MCW_imseq( im3d->s123, isqDR_periodicmont, (XtPointer) bval );
04710       drive_MCW_imseq( im3d->s231, isqDR_periodicmont, (XtPointer) bval );
04711       drive_MCW_imseq( im3d->s312, isqDR_periodicmont, (XtPointer) bval );
04712    }
04713 
04714    RESET_AFNI_QUIT(im3d) ;
04715    EXRETURN ;
04716 }
04717 
04718 /*-----------------------------------------------------------------*/
04719 
04720 void AFNI_xhall_bbox_CB( Widget w ,
04721                          XtPointer client_data , XtPointer call_data )
04722 {
04723    Three_D_View * im3d = (Three_D_View *) client_data ;
04724    int bval ;
04725 
04726 ENTRY("AFNI_xhall_bbox_CB") ;
04727 
04728    if( ! IM3D_VALID(im3d) ) EXRETURN ;
04729 
04730    bval = MCW_val_bbox( im3d->vwid->imag->xhall_bbox ) ;
04731 
04732    if( (Boolean) bval == im3d->vinfo->xhairs_all ) EXRETURN ;
04733 
04734    im3d->vinfo->xhairs_all = (Boolean) bval ;
04735 
04736    if( im3d->vinfo->crosshair_visible ){
04737       AFNI_set_viewpoint( im3d , -1,-1,-1 , REDISPLAY_OVERLAY ) ;
04738    }
04739 
04740    RESET_AFNI_QUIT(im3d) ;
04741    EXRETURN ;
04742 }
04743 
04744 /*------------------------------------------------------------------------*/
04745 
04746 void AFNI_crosshair_color_CB( MCW_arrowval * av , XtPointer client_data )
04747 {
04748    Three_D_View * im3d = (Three_D_View *) client_data ;
04749    int ipx = av->ival ;
04750 
04751 ENTRY("AFNI_crosshair_color_CB") ;
04752 
04753    if( ! IM3D_VALID(im3d) ) EXRETURN ;
04754 
04755    im3d->vinfo->crosshair_ovcolor = ipx ;
04756    if( im3d->vinfo->crosshair_visible ){
04757       AFNI_set_viewpoint( im3d , -1,-1,-1 , REDISPLAY_OVERLAY ) ;
04758    }
04759 
04760    RESET_AFNI_QUIT(im3d) ;
04761    EXRETURN ;
04762 }
04763 
04764 /*------------------------------------------------------------------------*/
04765 
04766 void AFNI_crosshair_gap_CB( MCW_arrowval * av ,  XtPointer client_data )
04767 {
04768    Three_D_View * im3d = (Three_D_View *) client_data ;
04769    int ipx ;
04770 
04771 ENTRY("AFNI_crosshair_gap_CB") ;
04772 
04773    if( ! IM3D_VALID(im3d) ) EXRETURN ;
04774 
04775    if( av != NULL ){
04776       ipx = av->ival ;
04777    } else {
04778       if( im3d->vinfo->crosshair_gap_old > 0 ){
04779          ipx = im3d->vinfo->crosshair_gap_old ;
04780          im3d->vinfo->crosshair_gap_old = 0 ;
04781       } else {
04782          im3d->vinfo->crosshair_gap_old = im3d->vinfo->crosshair_gap ;
04783          ipx = 0 ;
04784       }
04785    }
04786 
04787    im3d->vinfo->crosshair_gap = ipx ;
04788    if( im3d->vinfo->crosshair_visible ){
04789       AFNI_set_viewpoint( im3d , -1,-1,-1 , REDISPLAY_OVERLAY ) ;
04790    }
04791 
04792    RESET_AFNI_QUIT(im3d) ;
04793    EXRETURN ;
04794 }
04795 
04796 /*------------------------------------------------------------------------*/
04797 
04798 void AFNI_time_index_CB( MCW_arrowval *av ,  XtPointer client_data )
04799 {
04800    Three_D_View *im3d = (Three_D_View *) client_data ;
04801    int ipx ;
04802 
04803 ENTRY("AFNI_time_index_CB") ;
04804 
04805    if( ! IM3D_VALID(im3d) ) EXRETURN ;
04806 
04807    ipx = av->ival ;
04808    if( ipx >= im3d->vinfo->top_index )    /* don't let index be too big */
04809       ipx = im3d->vinfo->top_index - 1 ;
04810 
04811    im3d->vinfo->time_index = ipx ;        /* change time index */
04812 
04813    /* 29 Jul 2003: slave underlay and overlay to time_index (maybe) */
04814 
04815    im3d->vinfo->anat_index = ipx ;
04816    if( im3d->vinfo->anat_index >= DSET_NVALS(im3d->anat_now) )
04817      im3d->vinfo->anat_index = DSET_NVALS(im3d->anat_now) - 1 ;
04818    AV_assign_ival( im3d->vwid->func->anat_buck_av , im3d->vinfo->anat_index ) ;
04819 
04820    if( ISVALID_DSET(im3d->fim_now) &&
04821        HAS_TIMEAXIS(im3d->fim_now) && !AFNI_noenv("AFNI_SLAVE_FUNCTIME") ){
04822 
04823      im3d->vinfo->fim_index = ipx ;
04824      if( im3d->vinfo->fim_index >= DSET_NVALS(im3d->fim_now) )
04825        im3d->vinfo->fim_index = DSET_NVALS(im3d->fim_now) - 1 ;
04826      AV_assign_ival( im3d->vwid->func->fim_buck_av , im3d->vinfo->fim_index ) ;
04827 
04828      if( AFNI_yesenv("AFNI_SLAVE_THRTIME") ){   /* 24 Jan 2005 - RWCox */
04829        im3d->vinfo->thr_index = ipx ;
04830        if( im3d->vinfo->thr_index >= DSET_NVALS(im3d->fim_now) )
04831          im3d->vinfo->thr_index = DSET_NVALS(im3d->fim_now) - 1 ;
04832        AV_assign_ival( im3d->vwid->func->thr_buck_av , im3d->vinfo->thr_index ) ;
04833      }
04834    }
04835 
04836    im3d->vinfo->tempflag = 1 ;
04837    AFNI_modify_viewing( im3d , False ) ;  /* setup new bricks to view */
04838 
04839    if( ISVALID_DSET(im3d->fim_now)       &&   /* if time index on */
04840        DSET_NUM_TIMES(im3d->fim_now) > 1   )  /* function changed */
04841      AFNI_process_funcdisplay( im3d ) ;       /* notify receivers */
04842 
04843    AFNI_time_lock_carryout( im3d ) ;  /* 03 Nov 1998 */
04844    AFNI_process_timeindex ( im3d ) ;  /* 29 Jan 2003 */
04845 
04846    RESET_AFNI_QUIT(im3d) ;
04847    EXRETURN ;
04848 }
04849 
04850 /*-------------------------------------------------------------------------
04851    Start a view (12-3, 23-1, or 31-2)
04852 ---------------------------------------------------------------------------*/
04853 
04854 static char * AFNI_image_help =
04855  "Button 1: Set crosshair location\n"
04856  "Button 3: Pop up image menu\n\n"
04857  "Shift/Ctrl/Alt + Button 3\n"
04858  "will open up the Disp/Mont/Save\n"
04859  "control panels, respectively.\n\n"
04860  "Shift+Button2: drag crop region\n\n"
04861  "q = close window (=Done)\n"
04862  "z = zoom out  Z = zoom in\n"
04863  "p = panning mode on & off\n"
04864  "> = Page Up   = forward 1 image\n"
04865  "< = Page Down = backward 1 image\n"
04866  "v/V = Video up/down\n"
04867  "r/R = Ricochet up/down\n"
04868  "Left/Right/Up/Down arrow keys\n"
04869  "  move crosshairs OR pan image\n" ;
04870 
04871 static char * AFNI_arrowpad_help =
04872    "Click arrows to scroll crosshair position\n"
04873    "Click button to open/close crosshair gap " ;
04874 
04875 static char * AFNI_arrowpad_hint[] = {
04876   "Scroll crosshairs down" ,
04877   "Scroll crosshairs up" ,
04878   "Scroll crosshairs left" ,
04879   "Scroll crosshairs right" ,
04880   "Close/open crosshairs gap"
04881 } ;
04882 
04883 /*.........................................................................*/
04884 
04885 void AFNI_view_xyz_CB( Widget w ,
04886                        XtPointer client_data , XtPointer call_data )
04887 {
04888    Three_D_View * im3d = (Three_D_View *) client_data ;
04889    MCW_imseq   * sxyz , * syzx , * szxy , ** snew = NULL ;
04890    MCW_grapher * gxyz , * gyzx , * gzxy , ** gnew = NULL ;
04891    Widget        pboff , pb_xyz , pb_yzx , pb_zxy ;
04892    Widget        groff , gr_xyz , gr_yzx , gr_zxy ;
04893    FD_brick    * brnew ;
04894    int mirror=0 ;
04895    int m2m=0 ;     /* 04 Nov 2003 */
04896 
04897 ENTRY("AFNI_view_xyz_CB") ;
04898 
04899    if( ! IM3D_VALID(im3d) ) EXRETURN ;
04900 
04901     sxyz = im3d->s123 ; gxyz = im3d->g123 ;
04902     syzx = im3d->s231 ; gyzx = im3d->g231 ;
04903     szxy = im3d->s312 ; gzxy = im3d->g312 ;
04904 
04905     pb_xyz = im3d->vwid->imag->image_xyz_pb ;
04906     pb_yzx = im3d->vwid->imag->image_yzx_pb ;
04907     pb_zxy = im3d->vwid->imag->image_zxy_pb ;
04908 
04909     gr_xyz = im3d->vwid->imag->graph_xyz_pb ;
04910     gr_yzx = im3d->vwid->imag->graph_yzx_pb ;
04911     gr_zxy = im3d->vwid->imag->graph_zxy_pb ;
04912 
04913     /* handle case of button press of already
04914        open window by bringing that window to the top */
04915 
04916     if( w == pb_xyz && sxyz != NULL ){
04917        if( ISQ_REALZ(sxyz) )
04918           XMapRaised( XtDisplay(sxyz->wtop) , XtWindow(sxyz->wtop) ) ;
04919        EXRETURN ;
04920     } else if( w == pb_yzx && syzx != NULL ){
04921        if( ISQ_REALZ(syzx) )
04922           XMapRaised( XtDisplay(syzx->wtop) , XtWindow(syzx->wtop) ) ;
04923        EXRETURN ;
04924     } else if( w == pb_zxy && szxy != NULL ){
04925        if( ISQ_REALZ(szxy) )
04926           XMapRaised( XtDisplay(szxy->wtop) , XtWindow(szxy->wtop) ) ;
04927        EXRETURN ;
04928     } else if( w == gr_xyz && gxyz != NULL ){
04929        if( GRA_REALZ(gxyz) )
04930           XMapRaised( XtDisplay(gxyz->fdw_graph) , XtWindow(gxyz->fdw_graph) ) ;
04931        EXRETURN ;
04932     } else if( w == gr_yzx && gyzx != NULL ){
04933        if( GRA_REALZ(gyzx) )
04934           XMapRaised( XtDisplay(gyzx->fdw_graph) , XtWindow(gyzx->fdw_graph) ) ;
04935        EXRETURN ;
04936     } else if( w == gr_zxy && gzxy != NULL ){
04937        if( GRA_REALZ(gzxy) )
04938           XMapRaised( XtDisplay(gzxy->fdw_graph) , XtWindow(gzxy->fdw_graph) ) ;
04939        EXRETURN ;
04940     }
04941 
04942     /* button pressed and window not open, so prepare to open it */
04943 
04944     m2m = AFNI_yesenv("AFNI_IMAGE_MINTOMAX") ;
04945 
04946     if( w == pb_xyz && sxyz == NULL ){         /* axial image */
04947        snew  = &(im3d->s123) ;
04948        brnew = im3d->b123_ulay ;
04949        pboff = pb_xyz ;
04950        mirror= GLOBAL_argopt.left_is_left ;
04951 
04952     } else if( w == pb_yzx && syzx == NULL ){  /* sagittal image */
04953        snew  = &(im3d->s231) ;
04954        brnew = im3d->b231_ulay ;
04955        pboff = pb_yzx ;
04956 
04957     } else if( w == pb_zxy && szxy == NULL ){  /* coronal image */
04958        snew  = &(im3d->s312) ;
04959        brnew = im3d->b312_ulay ;
04960        pboff = pb_zxy ;
04961        mirror= GLOBAL_argopt.left_is_left ;
04962 
04963     } else if( w == gr_xyz && gxyz == NULL ){  /* axial graph */
04964        gnew  = &(im3d->g123) ;
04965        brnew = im3d->b123_ulay ;
04966        pboff = gr_xyz ;
04967        mirror= GLOBAL_argopt.left_is_left ;
04968 
04969     } else if( w == gr_yzx && gyzx == NULL ){  /* sagittal graph */
04970        gnew  = &(im3d->g231) ;
04971        brnew = im3d->b231_ulay ;
04972        pboff = gr_yzx ;
04973 
04974     } else if( w == gr_zxy && gzxy == NULL ){  /* coronal graph */
04975        gnew  = &(im3d->g312) ;
04976        brnew = im3d->b312_ulay ;
04977        pboff = gr_zxy ;
04978        mirror= GLOBAL_argopt.left_is_left ;
04979 
04980     } else
04981        EXRETURN ;  /* something funny */
04982 
04983     /** Mar 1997: don't open if x or y dimension is 1 **/
04984 
04985     if( snew != NULL && (brnew->n1 < 2 || brnew->n2 < 2) ) EXRETURN  ;
04986 
04987     SHOW_AFNI_PAUSE ;
04988 
04989     if( snew != NULL ){
04990 STATUS("opening an image window") ;
04991       MCW_invert_widget(pboff) ;
04992       POPUP_cursorize(pboff) ;   /* 20 Jul 2005 */
04993       *snew = open_MCW_imseq( im3d->dc, AFNI_brick_to_mri, (XtPointer) brnew ) ;
04994 
04995       (*snew)->parent = (XtPointer) im3d ;
04996 
04997       INIT_BKGD_LAB(im3d) ;
04998 
04999       drive_MCW_imseq( *snew, isqDR_imhelptext, (XtPointer) AFNI_image_help ) ;
05000       drive_MCW_imseq( *snew, isqDR_arrowpadon, (XtPointer) AFNI_arrowpad_help ) ;
05001       drive_MCW_imseq( *snew, isqDR_arrowpadhint , (XtPointer) AFNI_arrowpad_hint );
05002 STATUS("realizing new image viewer") ;
05003       drive_MCW_imseq( *snew, isqDR_ignore_redraws, (XtPointer) 1 ) ; /* 16 Aug 2002 */
05004       drive_MCW_imseq( *snew, isqDR_realize, NULL ) ;
05005       drive_MCW_imseq( *snew, isqDR_title, (XtPointer) im3d->window_title ) ;
05006       drive_MCW_imseq( *snew, isqDR_periodicmont,
05007                       (XtPointer)(int) im3d->vinfo->xhairs_periodic );
05008 
05009       /* 09 Oct 1998: force L-R mirroring on axial and coronal images? */
05010       /* 04 Nov 2003: or min-to-max on grayscaling? */
05011 
05012       if( mirror | m2m ){
05013          ISQ_options opt ;
05014 
05015 STATUS("setting image view to be L-R mirrored") ;
05016 
05017          ISQ_DEFAULT_OPT(opt) ;
05018          if( mirror ) opt.mirror = TRUE ;
05019          if( m2m    ) opt.scale_range = ISQ_RNG_MINTOMAX ;
05020          drive_MCW_imseq( *snew,isqDR_options  ,(XtPointer) &opt ) ;
05021       }
05022 
05023 #if 0
05024       /* 23 Jan 2003: set opacity? */
05025 
05026       { char *eee = getenv("AFNI_DEFAULT_OPACITY") ;
05027         if( eee != NULL ){
05028           int opval = (int) strtod( eee , NULL ) ;
05029           if( opval > 0 && opval <= 9 )
05030             drive_MCW_imseq( *snew , isqDR_setopacity , (XtPointer)opval ) ;
05031         }
05032       }
05033 
05034       /* 23 Jan 2003: set default save? */
05035 
05036       drive_MCW_imseq( *snew , isqDR_setimsave ,
05037                        (XtPointer)getenv("AFNI_DEFAULT_IMSAVE") ) ;
05038 #endif
05039 
05040 #ifdef USE_SIDES
05041 #define LL 0
05042 #define RR 1
05043 #define AA 2
05044 #define PP 3
05045 #define SS 4
05046 #define II 5
05047       if( !AFNI_yesenv("AFNI_NO_SIDES_LABELS") ){
05048          static char * ssix[6] = { "Left"     , "Right"     ,
05049                                    "Anterior" , "Posterior" ,
05050                                    "Superior" , "Inferior"   } ;
05051          char * ws[4] ;
05052 
05053          if( *snew == im3d->s123 ){
05054            ws[0] = ssix[RR]; ws[1] = ssix[AA]; ws[2] = ssix[LL]; ws[3] = ssix[PP];
05055          } else if( *snew == im3d->s231 ){
05056            ws[0] = ssix[AA]; ws[1] = ssix[SS]; ws[2] = ssix[PP]; ws[3] = ssix[II];
05057          } else if( *snew == im3d->s312 ){
05058            ws[0] = ssix[RR]; ws[1] = ssix[SS]; ws[2] = ssix[LL]; ws[3] = ssix[II];
05059          } else {
05060            ws[0] = ws[1] = ws[2] = ws[3] = NULL ;
05061          }
05062 
05063 STATUS("setting image viewer 'sides'") ;
05064 
05065          drive_MCW_imseq( *snew,isqDR_winfosides,(XtPointer)ws ) ;
05066       }
05067 #undef LL
05068 #undef RR
05069 #undef AA
05070 #undef PP
05071 #undef SS
05072 #undef II
05073 #endif
05074 
05075       AFNI_toggle_drawing( im3d ) ;
05076 
05077 #ifndef DONT_INSTALL_ICONS
05078       if( afni48_good ){
05079          Pixmap pm = XmUNSPECIFIED_PIXMAP ;
05080 
05081               if( w == pb_xyz ) pm = afni48axi_pixmap ;
05082          else if( w == pb_yzx ) pm = afni48sag_pixmap ;
05083          else if( w == pb_zxy ) pm = afni48cor_pixmap ;
05084 
05085          drive_MCW_imseq( *snew, isqDR_icon , (XtPointer) pm ) ;
05086       }
05087 #endif
05088       { int ii=AFNI_controller_index(im3d) ;
05089         if( ii >= 0 )
05090          drive_MCW_imseq( *snew, isqDR_bgicon, (XtPointer)afni16_pixmap[ii] ) ;
05091       }
05092 
05093       drive_MCW_imseq( *snew, isqDR_ignore_redraws, (XtPointer) 0 ) ; /* 16 Aug 2002 */
05094 
05095       AFNI_view_setter ( im3d , *snew ) ;
05096       AFNI_range_setter( im3d , *snew ) ;  /* 04 Nov 2003 */
05097 
05098     } /* end of c