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  

bbox.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 #include "bbox.h"
00008 
00009 /*-------------------------------------------------------------------------
00010    create a new MCW_bbox:
00011        parent    = parent Widget
00012        num_but   = number of buttons (from 1 to MCW_MAX_BB)
00013        label_but = array of strings of button labels
00014        bb_type   = MCW_BB_check      -> check box (any may be on)
00015                    MCW_BB_radio_one  -> radio box, exactly one will be on
00016                    MCW_BB_radio_zero -> radio box, zero or one will be on
00017        bb_frame  = MCW_BB_noframe    -> no frame around box
00018                  = MCW_BB_frame      -> put frame around box
00019        cb        = Callback procedure for Disarm (NULL for none)
00020        cb_data   = data to pass to Callback procedure (NULL for none)
00021 ---------------------------------------------------------------------------*/
00022 
00023 MCW_bbox * new_MCW_bbox( Widget parent ,
00024                          int num_but , char * label_but[] ,
00025                          int bb_type , int bb_frame ,
00026                          XtCallbackProc cb , XtPointer cb_data )
00027 {
00028    MCW_bbox * bb ;
00029    int ib , initial_value ;
00030    Widget rc_parent ;
00031    Arg wa[30] ;  int na ;
00032    Pixel  fg_pix ;
00033 
00034 ENTRY("new_MCW_bbox") ;
00035 
00036    if( num_but <= 0 || num_but >= 32 ){
00037       fprintf(stderr,"\n*** illegal new_MCW_bbox has %d buttons\n",num_but) ;
00038       EXIT(1) ;
00039    }
00040 
00041    bb = (MCW_bbox *) XtMalloc( sizeof(MCW_bbox) ) ;
00042 
00043    bb->nbut      = num_but ;
00044    initial_value = 0 ;
00045 
00046    /***--- create Frame, if desired ---***/
00047 
00048    switch( bb_frame ){
00049 
00050       case MCW_BB_frame:
00051          rc_parent = bb->wtop = bb->wframe =
00052             XtVaCreateManagedWidget(
00053                "frame" , xmFrameWidgetClass , parent ,
00054                    XmNshadowType , XmSHADOW_ETCHED_IN ,
00055                    XmNinitialResourcesPersistent , False ,
00056                NULL ) ;
00057          break ;
00058 
00059       case MCW_BB_noframe:
00060       default:
00061         rc_parent  = parent ;
00062         bb->wframe = NULL ;
00063         break ;
00064    }
00065 
00066    /***--- create RowColumn to hold the buttons ---***/
00067 
00068 #define MAX_PER_COL 8
00069 
00070    na = 0 ;
00071 
00072 #ifdef BBOX_COL
00073    XtSetArg( wa[na] , XmNpacking    , XmPACK_COLUMN )               ; na++ ;
00074    XtSetArg( wa[na] , XmNnumColumns , 1 + (num_but-1)/MAX_PER_COL ) ; na++ ;
00075 #else
00076    XtSetArg( wa[na] , XmNpacking    , XmPACK_TIGHT )                ; na++ ;
00077 #endif
00078 
00079    XtSetArg( wa[na] , XmNmarginHeight , 0 ) ; na++ ;  /* squash things in */
00080    XtSetArg( wa[na] , XmNmarginWidth  , 0 ) ; na++ ;
00081    XtSetArg( wa[na] , XmNspacing      , 1 ) ; na++ ;
00082 
00083    XtSetArg( wa[na] , XmNinitialResourcesPersistent , False ) ; na++ ;
00084 
00085    if( bb_type == MCW_BB_radio_zero || bb_type == MCW_BB_radio_one ){
00086 
00087       XtSetArg( wa[na] , XmNradioBehavior , True ) ; na++ ;
00088 
00089       if( bb_type == MCW_BB_radio_one ){
00090          initial_value = 1 ;
00091          XtSetArg( wa[na] , XmNradioAlwaysOne , True ) ; na++ ;
00092       } else {
00093          XtSetArg( wa[na] , XmNradioAlwaysOne , False ) ; na++ ;
00094       }
00095    }
00096 
00097    bb->wrowcol = XtCreateWidget(
00098                    "dialog" , xmRowColumnWidgetClass , rc_parent ,
00099                    wa , na ) ;
00100 
00101    if( bb->wframe == NULL ) bb->wtop = bb->wrowcol ;  /* topmost widget */
00102 
00103    XtVaGetValues( bb->wtop , XmNforeground , &fg_pix , NULL ) ;
00104 
00105    /***--- create the buttons ---***/
00106 
00107    for( ib=0 ; ib < num_but ; ib++ ){
00108       bb->wbut[ib] = XtVaCreateManagedWidget(
00109                         "dialog" , xmToggleButtonWidgetClass , bb->wrowcol ,
00110                            LABEL_ARG(label_but[ib]) ,
00111                            XmNmarginHeight  , 0 ,
00112                            XmNmarginWidth   , 0 ,
00113                            XmNselectColor   , fg_pix ,  /* 04 Nov 1996 */
00114                            XmNrecomputeSize , False ,
00115                            XmNtraversalOn   , False ,
00116                            XmNinitialResourcesPersistent , False ,
00117                         NULL ) ;
00118 
00119       if( cb != NULL )
00120          XtAddCallback( bb->wbut[ib] , XmNdisarmCallback , cb , cb_data ) ;
00121 
00122    }
00123    for( ib=num_but ; ib < MCW_MAX_BB ; ib++ ) bb->wbut[ib] = NULL ;
00124 
00125    MCW_set_bbox( bb , initial_value ) ;
00126    XtManageChild( bb->wrowcol ) ;
00127 
00128    bb->parent = bb->aux = NULL ;
00129    RETURN(bb) ;
00130 }
00131 
00132 /*------------------------------------------------------------------------*/
00133 
00134 void MCW_bbox_hints( MCW_bbox * bb , int nh , char ** hh )
00135 {
00136    int ib ;
00137 
00138    if( bb == NULL || nh == 0 || hh == NULL ) return ;
00139    if( nh > bb->nbut ) nh = bb->nbut ;
00140    for( ib=0 ; ib < nh ; ib++ )
00141      MCW_register_hint( bb->wbut[ib] , hh[ib] ) ;
00142    return ;
00143 }
00144 
00145 /*------------------------------------------------------------------------*/
00146 
00147 void MCW_set_bbox( MCW_bbox *bb , int val )
00148 {
00149    int     ib ;
00150    Boolean nset , oset ;
00151 
00152 ENTRY("MCW_set_bbox") ;
00153 
00154    if( bb == NULL ) EXRETURN ;  /* 01 Feb 2000 */
00155    bb->value = val ;
00156    for( ib=0 ; ib < bb->nbut ; ib++ ){
00157      nset = ( val & (1<<ib) ) ? (True) : (False) ;
00158      oset = XmToggleButtonGetState( bb->wbut[ib] ) ;
00159      if( nset != oset && XtIsSensitive(bb->wbut[ib]) ){
00160        XmToggleButtonSetState( bb->wbut[ib] , nset , False ) ;
00161        XmUpdateDisplay( bb->wbut[ib] ) ;
00162      }
00163    }
00164    EXRETURN ;
00165 }
00166 
00167 /*------------------------------------------------------------------------*/
00168 
00169 int MCW_val_bbox( MCW_bbox *bb )
00170 {
00171    int ib , val ;
00172    Boolean set ;
00173 
00174    if( bb == NULL ) return 0 ;  /* 01 Feb 2000 */
00175    val = 0 ;
00176    for( ib=0 ; ib < bb->nbut ; ib++ ){
00177      set = XmToggleButtonGetState( bb->wbut[ib] ) ;
00178      if( set ) val |= (1<<ib) ;
00179    }
00180    bb->value = val ;
00181    return val ;
00182 }
00183 
00184 /*----------------------------------------------------------------------
00185   Create a new MCW_arrowval:   [label] [v][^] [value]
00186     parent  = parent Widget
00187     label   = string to put to left of arrows (NULL means none)
00188     direc   = MCW_AV_downup    for down and up arrows
00189               MCW_AV_leftright for left and right arrows
00190               MCW_AV_optmenu   for option menu (completely different style!)
00191     minval  = smallest value allowed } value is like in Scales:
00192     maxval  = largest  value allowed }   an integer
00193     inival  = initial  value         }
00194     textype = MCW_AV_notext   to turn display of value off
00195               MCW_AV_editext  to allow user to edit the text
00196               MCW_AV_noactext like above, but no "activation" when the
00197                               cursor leaves the window
00198               MCW_AV_readtext to make the text display readonly
00199     decim   = # of decimals to shift to left for display of value
00200               (like Scales)
00201 
00202     delta_value = pointer to a function that will be called when the value
00203                   changes (due to arrows or text edit);  not used if NULL
00204     delta_data  = pointer to data to be passed to delta_value;
00205                      delta_value( av , delta_data ) ;
00206                   where av is a pointer to the MCW_arrowval that changed.
00207                   (N.B.: the old value is available as av->old_ival
00208                                                     or av->old_fval)
00209 
00210     text_proc   = pointer to a function that returns the text to display
00211                     in the value window;  if non-NULL, then textype is
00212                     forced to be MCW_AV_readtext;  the routine is called by
00213 
00214                       string = text_proc( av , text_data )
00215 
00216     text_data   = pointer to data to be passed to text_proc
00217 ---------------------------------------------------------------------------*/
00218 
00219 MCW_arrowval * new_MCW_arrowval( Widget parent ,
00220                                  char *label ,
00221                                  int    direc ,
00222                                  int    minval , int maxval , int inival ,
00223                                  int    textype ,  int decim ,
00224                                  gen_func *delta_value, XtPointer delta_data,
00225                                  str_func *text_proc  , XtPointer text_data
00226                                )
00227 {
00228    MCW_arrowval * av = NULL ;
00229    int asizx = 20 , asizy = 15 ;  /* arrow sizes */
00230 
00231 ENTRY("new_MCW_arrowval") ;
00232 
00233    /** July 1996: optmenu capability as a dropin for arrowval **/
00234 
00235    if( direc == MCW_AV_optmenu ){
00236       av = new_MCW_optmenu( parent , label , minval,maxval,inival , decim ,
00237                             delta_value , delta_data , text_proc , text_data ) ;
00238       RETURN(av) ;
00239    }
00240 
00241    av = myXtNew( MCW_arrowval ) ;
00242    av->wrowcol = XtVaCreateWidget(
00243                     "dialog" , xmRowColumnWidgetClass , parent ,
00244 
00245                        XmNpacking      , XmPACK_TIGHT ,
00246                        XmNorientation  , XmHORIZONTAL ,
00247                        XmNmarginHeight , 0 ,
00248                        XmNmarginWidth  , 0 ,
00249                        XmNspacing      , 0 ,
00250 #if 0
00251                        XmNresizeHeight , False ,
00252                        XmNresizeWidth  , False ,
00253 #endif
00254                        XmNinitialResourcesPersistent , False ,
00255                        XmNtraversalOn , False ,
00256                     NULL ) ;
00257 
00258    if( label != NULL && strlen(label) > 0 ){
00259       XmString   xstr = XmStringCreateLtoR( label , XmFONTLIST_DEFAULT_TAG );
00260       XmFontList xflist ;
00261 
00262       av->wlabel = XtVaCreateManagedWidget(
00263                     "dialog" , xmLabelWidgetClass , av->wrowcol ,
00264 
00265                        XmNlabelString   , xstr  ,
00266                        XmNrecomputeSize , False ,
00267                        XmNmarginWidth   , 0     ,
00268 
00269                        XmNinitialResourcesPersistent , False ,
00270                     NULL ) ;
00271 
00272       XtVaGetValues( av->wlabel , XmNfontList , &xflist , NULL ) ;
00273 
00274       asizy = XmStringHeight( xflist , xstr ) ;
00275       XmStringFree( xstr ) ;
00276 
00277    } else {
00278       av->wlabel = NULL ;
00279    }
00280 
00281    if( asizx < asizy ) asizx = asizy ;
00282    else                asizy = asizx ;
00283 
00284    av->wdown = XtVaCreateManagedWidget(
00285                   "arrow" , xmArrowButtonWidgetClass , av->wrowcol ,
00286 
00287                      XmNarrowDirection , (direc==MCW_AV_leftright)
00288                                          ? XmARROW_LEFT : XmARROW_DOWN ,
00289 
00290                      XmNheight , asizy , XmNwidth , asizx ,
00291                      XmNborderWidth , 0 ,
00292 
00293                      XmNinitialResourcesPersistent , False ,
00294                      XmNtraversalOn , False ,
00295                   NULL ) ;
00296 
00297    av->wup    = XtVaCreateManagedWidget(
00298                   "arrow" , xmArrowButtonWidgetClass , av->wrowcol ,
00299 
00300                      XmNarrowDirection , (direc==MCW_AV_leftright)
00301                                          ? XmARROW_RIGHT : XmARROW_UP ,
00302 
00303                      XmNheight , asizy , XmNwidth , asizx ,
00304                      XmNborderWidth , 0 ,
00305 
00306                      XmNinitialResourcesPersistent , False ,
00307                      XmNtraversalOn , False ,
00308                   NULL ) ;
00309 
00310    XtAddCallback( av->wdown , XmNarmCallback    , AV_press_CB , av ) ;
00311    XtAddCallback( av->wdown , XmNdisarmCallback , AV_press_CB , av ) ;
00312    XtAddCallback( av->wup   , XmNarmCallback    , AV_press_CB , av ) ;
00313    XtAddCallback( av->wup   , XmNdisarmCallback , AV_press_CB , av ) ;
00314 
00315    if( text_proc != NULL && textype != MCW_AV_notext )
00316       textype = MCW_AV_readtext ;
00317 
00318    switch( textype ){
00319 
00320       default:
00321       case MCW_AV_notext:
00322          av->wtext     = NULL ;
00323          av->text_CB   = NULL ;
00324          av->text_data = NULL ;
00325       break ;
00326 
00327       /* Note hardwire of 9 columns of text, here and in AV_fval_to_char;
00328          this CANNOT be changed just by changing AV_NCOL below, you must
00329          also edit the sprintf formats in AV_fval_to_char.
00330 
00331          If text_proc is not NULL, then av->wtext could have its dimensions
00332          changed later to handle the user supplied string.  My point above
00333          is that the default text_proc is hardwired to 9 characters wide.
00334       */
00335 
00336 #ifndef AV_NCOL
00337 #define AV_NCOL 9
00338 #endif
00339 
00340       case MCW_AV_readtext:
00341          av->wtext = XtVaCreateManagedWidget(
00342                        "dialog" , TEXT_CLASS , av->wrowcol ,
00343 
00344                           XmNcolumns         , AV_NCOL ,
00345                           XmNeditable        , False ,
00346                           XmNmaxLength       , AV_NCOL ,
00347                           XmNresizeWidth     , False ,
00348                           XmNshadowThickness , 0 ,
00349 #if 0
00350                           XmNsensitive       , False ,   /* looks bad */
00351 #endif
00352                           XmNmarginHeight    , 1 ,
00353                           XmNmarginWidth     , 1 ,
00354 
00355                           XmNcursorPositionVisible , False ,
00356 
00357                           XmNinitialResourcesPersistent , False ,
00358                           XmNtraversalOn , False ,
00359                        NULL ) ;
00360 
00361          av->text_CB   = (text_proc != NULL ) ? (text_proc)
00362                                               : (AV_default_text_CB) ;
00363          av->text_data = text_data ;
00364       break ;
00365 
00366       case MCW_AV_noactext:                   /* noactext added 08 Feb 1999 */
00367       case MCW_AV_editext:{
00368          Widget wf ; int maxlen ;
00369 
00370          if( textype == MCW_AV_noactext ){
00371             wf = XtVaCreateWidget( "dialog" , xmFrameWidgetClass , av->wrowcol ,
00372                                       XmNshadowType , XmSHADOW_OUT ,
00373                                       XmNshadowThickness , 1 ,
00374                                       XmNtraversalOn , False ,
00375                                       XmNinitialResourcesPersistent , False ,
00376                                    NULL ) ;
00377             maxlen = AV_MAXLEN ;
00378          } else {
00379             wf     = av->wrowcol ;
00380             maxlen = AV_NCOL ;
00381          }
00382 
00383          av->wtext = XtVaCreateManagedWidget(
00384                        "dialog" , TEXT_CLASS , wf ,
00385 
00386                           XmNcolumns         , AV_NCOL ,
00387                           XmNeditable        , True ,
00388                           XmNmaxLength       , maxlen ,
00389                           XmNresizeWidth     , False ,
00390 
00391                           XmNmarginHeight    , 1 ,
00392                           XmNmarginWidth     , 1 ,
00393 
00394                           XmNcursorPositionVisible , True ,
00395                           XmNblinkRate , 0 ,
00396                           XmNautoShowCursorPosition , True ,
00397 
00398                           XmNinitialResourcesPersistent , False ,
00399                           XmNtraversalOn , False ,
00400                        NULL ) ;
00401 
00402          if( textype == MCW_AV_noactext ) XtManageChild(wf) ;
00403 
00404          if( textype == MCW_AV_editext ){
00405             XtAddCallback( av->wtext , XmNactivateCallback    ,
00406                                        AV_textact_CB , av ) ; /* return key */
00407 
00408             XtAddCallback( av->wtext , XmNlosingFocusCallback ,
00409                                        AV_textact_CB , av ) ; /* tab key */
00410 
00411             XtInsertEventHandler( av->wtext ,        /* notify when */
00412                                   LeaveWindowMask ,  /* pointer leaves */
00413                                   FALSE ,            /* this window */
00414                                   AV_leave_EV ,
00415                                   (XtPointer) av ,
00416                                   XtListTail ) ;     /* last in queue */
00417          }
00418 
00419          av->text_CB   = AV_default_text_CB ;
00420          av->text_data = NULL ;
00421       }
00422       break ;
00423 
00424    }
00425 
00426    XtManageChild( av->wrowcol ) ;
00427 
00428    if( minval < maxval ){
00429       av->fmin = av->imin = minval ; AV_SHIFT_VAL(decim,av->fmin) ;
00430       av->fmax = av->imax = maxval ; AV_SHIFT_VAL(decim,av->fmax) ;
00431    } else {
00432       av->fmin = av->imin = -9999999 ; AV_SHIFT_VAL(decim,av->fmin) ;
00433       av->fmax = av->imax =  9999999 ; AV_SHIFT_VAL(decim,av->fmax) ;
00434    }
00435    av->decimals  = decim ;
00436    av->timer_id  = 0 ;
00437    av->fastdelay = MCW_AV_shortdelay ;  /* default delay on 2nd call */
00438 
00439    av->fval = av->ival = inival ; AV_SHIFT_VAL(decim,av->fval) ;
00440 
00441    av->sval = av->old_sval = NULL ;  /* string values */
00442 
00443    av->block_assign_actions = 0 ;    /* don't block these actions */
00444    av->wmenu  = NULL ;               /* signal that this is NOT an optmenu */
00445 
00446    AV_assign_ival( av , inival ) ;
00447 
00448    av->dval_CB   = delta_value ;
00449    av->dval_data = delta_data ;
00450 
00451    av->allow_wrap = 0 ;
00452 
00453    av->parent = av->aux = NULL ;
00454    av->fstep = 0.0 ;  /* 16 Feb 1999 */
00455    RETURN(av) ;
00456 }
00457 
00458 /*-----------------------------------------------------------------------*/
00459 
00460 int AV_colsize()                      /* 11 Dec 2001 */
00461 {
00462    int cc=20 ; char *ee ;
00463    ee = getenv("AFNI_MENU_COLSIZE") ;
00464    if( ee != NULL ){
00465       cc = (int) strtol(ee,NULL,10) ;
00466       if( cc < 9 ) cc = 10 ;
00467    }
00468    return cc ;
00469 }
00470 
00471 /*-----------------------------------------------------------------------
00472   This can be used as a "drop in" replacement for a arrowval with a
00473   small fixed number of elements.  The textype argument is missing because
00474   the only one that makes sense is MCW_AV_readtext (readonly text as button
00475   labels).  The direc argument is missing because that choice has already
00476   been made.
00477 -------------------------------------------------------------------------*/
00478 
00479 #define COLSIZE AV_colsize()  /* 11 Dec 2001: redefined from a constant */
00480 
00481 static void optmenu_EV( Widget,XtPointer,XEvent *,Boolean *) ; /* prototype */
00482 
00483 static volatile int allow_optmenu_EV = 1 ;
00484 
00485 void allow_MCW_optmenu_popup( int ii ){ allow_optmenu_EV = ii ; }
00486 
00487 #undef  USE_FIXUP
00488 #ifdef  USE_FIXUP
00489 static void optmenu_EV_fixup( Widget ww ) ;
00490 #endif
00491 
00492 MCW_arrowval * new_MCW_optmenu( Widget parent ,
00493                                 char * label ,
00494                                 int    minval , int maxval , int inival , int decim ,
00495                                 gen_func * delta_value, XtPointer delta_data,
00496                                 str_func * text_proc  , XtPointer text_data
00497                               )
00498 {
00499    MCW_arrowval * av = myXtNew( MCW_arrowval ) ;
00500    Widget wmenu , wbut ;
00501    Arg args[5] ;
00502    int nargs , ival ;
00503    XmString xstr ;
00504    char * butlabel , * blab ;
00505 
00506 ENTRY("new_MCW_optmenu") ;
00507 
00508    /** create the menu window **/
00509 
00510    av->wmenu = wmenu = XmCreatePulldownMenu( parent , "menu" , NULL , 0 ) ;
00511 
00512    VISIBILIZE_WHEN_MAPPED(wmenu) ;
00513 
00514    /** create the button that pops down the menu **/
00515 
00516    nargs = 0 ;
00517    XtSetArg( args[0] , XmNsubMenuId , wmenu ) ; nargs++ ;
00518 
00519    if( label == NULL ) label = " " ;  /* 24 Sep 2001 */
00520 
00521    xstr = XmStringCreateLtoR( label , XmFONTLIST_DEFAULT_TAG ) ;
00522    XtSetArg( args[1] , XmNlabelString , xstr ) ; nargs++ ;
00523 
00524    av->wrowcol = XmCreateOptionMenu( parent , "dialog" , args , nargs ) ;
00525    XmStringFree(xstr) ;
00526    XtVaSetValues( av->wrowcol ,
00527                      XmNmarginWidth  , 0 ,
00528                      XmNmarginHeight , 0 ,
00529                      XmNspacing      , 2 ,
00530                   NULL ) ;
00531 
00532    av->wlabel = XmOptionLabelGadget (av->wrowcol) ;
00533    av->wdown  = XmOptionButtonGadget(av->wrowcol) ;
00534    av->wup    = NULL ;
00535    av->wtext  = NULL ;  /* signal that this is NOT really an arrowval */
00536 
00537    XtVaSetValues( av->wlabel ,              /* label next to menu button */
00538                      XmNmarginWidth  , 0 ,
00539                      XmNmarginHeight , 0 ,
00540                      XmNmarginBottom , 0 ,
00541                      XmNmarginTop    , 0 ,
00542                      XmNmarginRight  , 0 ,
00543                      XmNmarginLeft   , 0 ,
00544                   NULL ) ;
00545 
00546    if( label == NULL || strlen(label) == 0 ){
00547       XtVaSetValues( av->wlabel  , XmNwidth   , 0 , NULL ) ;
00548       XtVaSetValues( av->wrowcol , XmNspacing , 2 , NULL ) ;
00549    }
00550 
00551    XtVaSetValues( av->wdown ,               /* menu button */
00552                      XmNmarginWidth  , 0 ,
00553                      XmNmarginHeight , 0 ,
00554                      XmNmarginBottom , 0 ,
00555                      XmNmarginTop    , 0 ,
00556                      XmNmarginRight  , 0 ,
00557                      XmNmarginLeft   , 0 ,
00558                      XmNhighlightThickness , 0 ,
00559                   NULL ) ;
00560 
00561    av->text_CB   = (text_proc != NULL ) ? (text_proc)
00562                                         : (AV_default_text_CB) ;
00563    av->text_data = text_data ;
00564    av->decimals  = decim ;
00565    av->fmin      = av->imin = minval ; AV_SHIFT_VAL(decim,av->fmin) ;
00566    av->fmax      = av->imax = maxval ; AV_SHIFT_VAL(decim,av->fmax) ;
00567    av->sval      = av->old_sval = NULL ;
00568 
00569    av->block_assign_actions = 1 ;    /* temporarily block these actions */
00570 
00571    /** create the buttons on the menu window **/
00572 
00573    for( ival=minval ; ival <= maxval ; ival++ ){
00574 
00575       AV_assign_ival( av , ival ) ;  /* just to create label */
00576 
00577       blab = butlabel = XtNewString( av->sval ) ;
00578       if( av->text_CB==AV_default_text_CB && butlabel[0]==' ' && minval >= 0 ){
00579          blab += 1 ;  /* deal with leading blanks in default routine */
00580       }
00581 
00582       xstr = XmStringCreateLtoR( blab , XmFONTLIST_DEFAULT_TAG ) ;
00583 
00584       wbut = XtVaCreateManagedWidget(
00585                 "dialog" , xmPushButtonWidgetClass , wmenu ,
00586                   XmNlabelString  , xstr ,
00587                   XmNmarginWidth  , 0 ,
00588                   XmNmarginHeight , 0 ,
00589                   XmNmarginBottom , 0 ,
00590                   XmNmarginTop    , 0 ,
00591                   XmNmarginRight  , 0 ,
00592                   XmNmarginLeft   , 0 ,
00593                   XmNuserData     , (XtPointer) ival ,    /* Who am I? */
00594                   XmNtraversalOn , False ,
00595                   XmNinitialResourcesPersistent , False ,
00596                 NULL ) ;
00597 
00598       XmStringFree(xstr) ; myXtFree(butlabel) ;
00599 
00600       XtAddCallback( wbut , XmNactivateCallback , AVOPT_press_CB , av ) ;
00601 
00602       if( ival == inival )
00603          XtVaSetValues( av->wrowcol ,  XmNmenuHistory , wbut , NULL ) ;
00604    }
00605 
00606    XtManageChild( av->wrowcol ) ;
00607 
00608    av->timer_id  = 0 ;  /* won't be used for this type of arrowval! */
00609    av->fastdelay = 0 ;
00610 
00611    av->block_assign_actions = 0 ;   /* unblock these actions */
00612 
00613    AV_assign_ival( av , inival ) ;  /* actual initial assignment */
00614 
00615    av->dval_CB   = delta_value ;
00616    av->dval_data = delta_data ;
00617 
00618    av->allow_wrap = 0 ;
00619 
00620    av->parent = av->aux = NULL ;
00621    av->fstep = 0.0 ;  /* 16 Feb 1999 */
00622 
00623    /* 11 Dec 2001: allow user to choose via Button-3 popup */
00624 
00625    if( allow_optmenu_EV ){
00626      XtInsertEventHandler( av->wrowcol ,      /* handle events in optmenu */
00627                            ButtonPressMask ,  /* button presses */
00628                            FALSE ,            /* nonmaskable events? */
00629                            optmenu_EV ,       /* handler */
00630                            (XtPointer) av ,   /* client data */
00631                            XtListTail ) ;     /* last in queue */
00632 #ifdef USE_FIXUP
00633      optmenu_EV_fixup( av->wrowcol ) ;
00634 #endif
00635    }
00636 
00637    RETURN(av) ;
00638 }
00639 
00640 /*----------------------------------------------------------------------------
00641    Relabels all the buttons on an optmenu, adding or unmanaging as needed.
00642    The label and action callback remain the same.
00643 ------------------------------------------------------------------------------*/
00644 
00645 void refit_MCW_optmenu( MCW_arrowval * av ,
00646                         int  minval , int maxval , int inival , int decim ,
00647                         str_func * text_proc  , XtPointer text_data )
00648 {
00649    Widget * children , wbut , wmenu ;
00650    int  num_children , ic , ival ;
00651    char * butlabel , * blab ;
00652    XmString xstr ;
00653    int maxbut ;   /* 23 Aug 2003 */
00654 
00655 ENTRY("refit_MCW_optmenu") ;
00656 
00657    /** sanity check **/
00658 
00659    if( av == NULL || av->wmenu == NULL ) EXRETURN ;
00660    wmenu = av->wmenu ;
00661 
00662    /** get all the existing children **/
00663 
00664 #if 0
00665    XtUnmanageChild( av->wrowcol ) ; XtUnmanageChild( wmenu ) ;
00666 #endif
00667 
00668    XtVaGetValues( wmenu ,
00669                      XmNchildren    , &children ,
00670                      XmNnumChildren , &num_children ,
00671                   NULL ) ;
00672 
00673    /* 23 Aug 2003: replace hard limit of 255 buttons
00674                    with maxbut from environment variable */
00675 
00676    maxbut = AFNI_numenv( "AFNI_MAX_OPTMENU" ) ;
00677         if( maxbut <= 0 ) maxbut = 255 ;
00678    else if( maxbut < 99 ) maxbut = 99 ;
00679    if( maxval > minval+maxbut ) maxval = minval+maxbut ;  /* 23 Mar 2003 */
00680 
00681    /** reset some internal parameters **/
00682 
00683    av->text_CB   = (text_proc != NULL ) ? (text_proc)
00684                                         : (AV_default_text_CB) ;
00685    av->text_data = text_data ;
00686    av->decimals  = decim ;
00687    av->fmin      = av->imin = minval ; AV_SHIFT_VAL(decim,av->fmin) ;
00688    av->fmax      = av->imax = maxval ; AV_SHIFT_VAL(decim,av->fmax) ;
00689 
00690    myXtFree(av->sval) ; myXtFree(av->old_sval) ;  /* 09 Mar 1999 */
00691 
00692    av->block_assign_actions = 1 ;    /* temporarily block these actions */
00693 
00694    /** create buttons anew **/
00695 
00696    for( ival=minval ; ival <= maxval ; ival++ ){
00697 
00698       ic = ival - minval ;           /* index into widget list */
00699 
00700       AV_assign_ival( av , ival ) ;  /* just to create label */
00701 
00702       blab = butlabel = XtNewString( av->sval ) ;
00703       if( av->text_CB==AV_default_text_CB && butlabel[0]==' ' && minval >= 0 ){
00704          blab += 1 ;  /* deal with leading blanks in default routine */
00705       }
00706 
00707       xstr = XmStringCreateLtoR( blab , XmFONTLIST_DEFAULT_TAG ) ;
00708 
00709       /** re-use old button if possible, otherwise add a new one **/
00710 
00711       if( ic < num_children ){
00712          XtPointer user_old ;
00713          int       ival_old ;
00714          XmString  xstr_old ;
00715 
00716          wbut = children[ic] ;
00717          XtVaGetValues( wbut ,
00718                            XmNlabelString , &xstr_old ,
00719                            XmNuserData    , &user_old ,
00720                         NULL ) ;
00721          ival_old = (int) user_old ;
00722 
00723          if( ival_old != ival || XmStringCompare(xstr_old,xstr) != True ){
00724             XtVaSetValues( wbut ,
00725                               XmNlabelString , xstr ,             /* change label */
00726                               XmNuserData    , (XtPointer) ival , /* Who am I? */
00727                            NULL ) ;
00728          }
00729          XmStringFree( xstr_old ) ;
00730          XtManageChild( wbut ) ;    /* if not now managed */
00731       } else {
00732          wbut = XtVaCreateManagedWidget(
00733                    "dialog" , xmPushButtonWidgetClass , wmenu ,
00734                      XmNlabelString  , xstr ,
00735                      XmNmarginWidth  , 0 ,
00736                      XmNmarginHeight , 0 ,
00737                      XmNmarginBottom , 0 ,
00738                      XmNmarginTop    , 0 ,
00739                      XmNmarginRight  , 0 ,
00740                      XmNmarginLeft   , 0 ,
00741                      XmNuserData     , (XtPointer) ival ,    /* Who am I? */
00742                      XmNtraversalOn , False ,
00743                      XmNinitialResourcesPersistent , False ,
00744                    NULL ) ;
00745          XtAddCallback( wbut , XmNactivateCallback , AVOPT_press_CB , av ) ;
00746       }
00747 
00748       XmStringFree(xstr) ; myXtFree(butlabel) ;
00749 
00750       if( ival == inival )
00751          XtVaSetValues( av->wrowcol ,  XmNmenuHistory , wbut , NULL ) ;
00752    }
00753 
00754    /** Unmanage extra children from an old incarnation **/
00755 
00756    ic = maxval-minval+1 ;  /* first child after those used above */
00757 
00758    if( ic < num_children )
00759       XtUnmanageChildren( children + ic , num_children - ic ) ;
00760 
00761    /** set number of columns to see **/
00762 
00763    AVOPT_columnize( av , 1+(maxval-minval)/COLSIZE ) ;
00764 
00765 #if 0
00766    XtManageChild( wmenu ) ;
00767    XtManageChild( av->wrowcol ) ;
00768 #endif
00769 
00770 #if 0
00771    RWC_XtPopdown( XtParent(wmenu) ) ;  /* 28 Apr 1997 */
00772 #endif
00773 
00774    av->block_assign_actions = 0 ;   /* unblock these actions */
00775    AV_assign_ival( av , inival ) ;  /* actual initial assignment */
00776 
00777    EXRETURN ;
00778 }
00779 
00780 /*--------------------------------------------------------------------------
00781   11 Dec 2001: Provide a Button 3 list to choose from for an optmenu
00782 ----------------------------------------------------------------------------*/
00783 
00784 static void optmenu_finalize( Widget w, XtPointer cd, MCW_choose_cbs * cbs )
00785 {
00786    MCW_arrowval *av = (MCW_arrowval *) cd ;
00787    int ival ;
00788 
00789 ENTRY("optmenu_finalize") ;
00790 
00791    if( av == NULL || av->wmenu == NULL ) EXRETURN ;
00792 
00793    ival = cbs->ival + av->imin ;
00794    AV_assign_ival( av , ival ) ;
00795 
00796    /* call user callback, if present */
00797 
00798    if( av->dval_CB != NULL && av->fval != av->old_fval )
00799 #if 0
00800       av->dval_CB( av , av->dval_data ) ;
00801 #else
00802       AFNI_CALL_VOID_2ARG( av->dval_CB ,
00803                            MCW_arrowval * , av ,
00804                            XtPointer      , av->dval_data ) ;
00805 #endif
00806 
00807    EXRETURN ;
00808 }
00809 
00810 /*--------------------------------------------------------------------------*/
00811 /* 15 Mar 2004: fix the cursors on the optmenus with popups */
00812 
00813 #ifdef USE_FIXUP
00814 static volatile int    nwid = 0    ;
00815 static volatile Widget *wid = NULL ;
00816 
00817 /*- called if an optmenu is destroyed, to remove it from the fixup list -*/
00818 
00819 static void optmenu_EV_fixup_CB( Widget ww , XtPointer xp, XtPointer cd )
00820 {
00821    int ii ;
00822 ENTRY("optmenu_EV_fixup_CB") ;
00823    for( ii=0 ; ii < nwid ; ii++ )
00824      if( wid[ii] == ww ) wid[ii] = (Widget)NULL ;
00825    EXRETURN ; ;
00826 }
00827 
00828 /*- called occasionally to see if anyone can be fixed yet -*/
00829 
00830 static volatile XtIntervalId timer_id = (XtIntervalId)0 ;
00831 static volatile XtAppContext timer_cx = (XtAppContext)NULL ;
00832 
00833 static void optmenu_EV_fixup_timer_CB( XtPointer cd , XtIntervalId *id )
00834 {
00835 ENTRY("optmenu_EV_fixup_timer_CB") ;
00836    optmenu_EV_fixup((Widget)NULL) ;
00837    timer_id = XtAppAddTimeOut( timer_cx, 3033, optmenu_EV_fixup_timer_CB, NULL ) ;
00838    EXRETURN ;
00839 }
00840 
00841 /*- called with NULL to fix anything on the current list;
00842     called with a Widget to put it on the to-be-fixed-up list -*/
00843 
00844 static void optmenu_EV_fixup( Widget ww )   /* 15 Mar 2004 - RWCox */
00845 {
00846    int ii , jj ;
00847    Widget *qwid ;
00848 
00849 ENTRY("optmenu_EV_fixup") ;
00850 
00851    if( ww == (Widget)NULL ){                   /* try to fix what's on the list */
00852      if( nwid == 0 ) EXRETURN ;  /* that was easy */
00853 if(PRINT_TRACING){ char str[256]; sprintf(str,"scanning %d widgets for fixing",nwid); STATUS(str); }
00854      for( ii=jj=0 ; ii < nwid ; ii++ ){
00855        if( wid[ii] != (Widget)NULL && XtIsRealized(wid[ii])      &&
00856            XtIsManaged(wid[ii])    && MCW_widget_visible(wid[ii])  ){
00857 if(PRINT_TRACING){ char str[256]; sprintf(str,"  about to fix ii=%d",ii); STATUS(str); }
00858          POPUP_cursorize(wid[ii]) ;
00859          XtRemoveCallback( wid[ii], XmNdestroyCallback, optmenu_EV_fixup_CB, NULL ) ;
00860          wid[ii] = NULL ; jj++ ;
00861 if(PRINT_TRACING){ char str[256]; sprintf(str,"  #%d cursor fixed",ii); STATUS(str); }
00862        }
00863 else if(PRINT_TRACING){ char str[256]; sprintf(str,"  #%d not fixable",ii); STATUS(str); }
00864      }
00865      if( jj == 0 ){ STATUS("nothing to fix"); EXRETURN; }
00866      if( jj >= nwid ){ STATUS("fixed them all"); free(wid); wid = NULL; nwid = 0; EXRETURN; }
00867      qwid = (Widget *) calloc( nwid , sizeof(Widget) ) ;
00868      for( ii=jj=0 ; ii < nwid ; ii++ )
00869        if( wid[ii] != (Widget)NULL ) qwid[jj++] = wid[ii] ;
00870      nwid = jj ;
00871      for( ii=0 ; ii < nwid ; ii++ ) wid[ii] = qwid[ii] ;
00872      free(qwid) ;
00873 if(PRINT_TRACING){ char str[256]; sprintf(str,"  %d left to fix later",nwid); STATUS(str); }
00874 
00875    } else {                               /* add to the list */
00876      wid = (Widget *)realloc( (void *)wid , sizeof(Widget)*(nwid+1) ) ;
00877      wid[nwid++] = ww ;
00878      XtAddCallback( ww, XmNdestroyCallback, optmenu_EV_fixup_CB, NULL ) ;
00879      if( timer_cx == (XtAppContext)NULL ){
00880 STATUS("  starting first timer callback") ;
00881        timer_cx = XtWidgetToApplicationContext(ww) ;
00882        timer_id = XtAppAddTimeOut( timer_cx, 5055, optmenu_EV_fixup_timer_CB, NULL ) ;
00883      }
00884 if(PRINT_TRACING){ char str[256]; sprintf(str," now have %d to fix",nwid); STATUS(str); }
00885    }
00886    EXRETURN ;
00887 }
00888 #endif  /* USE_FIXUP */
00889 
00890 /*--------------------------------------------------------------------------*/
00891 
00892 static void optmenu_EV( Widget w , XtPointer cd ,
00893                         XEvent *ev , Boolean *continue_to_dispatch )
00894 {
00895    MCW_arrowval *av = (MCW_arrowval *) cd ;
00896    int  ic , ival , sval , nstr ;
00897    XButtonEvent * bev = (XButtonEvent *) ev ;
00898    Dimension lw ;
00899    static char **strlist=NULL ;
00900    static  int  nstrlist=0 ;    /* 06 Aug 2002 */
00901    char *slab=NULL ;
00902    XmString xstr ;
00903 
00904    /*-- Attempt to fix a Motif problem with Button 2
00905         when the optmenu is itself in a popup menu.
00906         The pointer grab is never released, so the
00907         X server is effectively frozen forever (or
00908         until the afni process is SIGTERM-ed). Here,
00909         if we see Button 2, then we manually ungrab
00910         the pointer.  This has the side-effect of
00911         popping down the popup menu.  If the optmenu
00912         is NOT in a popup menu, it has no side effect. --*/
00913 
00914 #ifdef USE_FIXUP
00915    optmenu_EV_fixup(NULL) ;
00916 #endif
00917 
00918    if( bev->button == Button2 ){
00919      XUngrabPointer( bev->display , CurrentTime ) ;
00920      return ;
00921    }
00922 
00923    /*-- start of actual work --*/
00924 
00925 ENTRY("optmenu_EV") ;
00926 
00927    /** sanity checks **/
00928 
00929    if( w == NULL || av == NULL || av->wmenu == NULL ) EXRETURN ;
00930 
00931    if( bev->button != Button3 ) EXRETURN ;
00932 
00933    XtVaGetValues( av->wlabel , XmNwidth,&lw , NULL ) ;
00934    if( bev->x > lw ) EXRETURN ;
00935 
00936    /** get ready to popup a new list chooser **/
00937 
00938    POPDOWN_strlist_chooser ;
00939 
00940    av->block_assign_actions = 1 ;         /* temporarily block actions */
00941    sval = av->ival ;
00942 
00943    /* 06 Aug 2002: free old strings, if any */
00944 
00945    for( ic=0 ; ic < nstrlist ; ic++ ) free(strlist[ic]) ;
00946 
00947    /** make a list of strings **/
00948 
00949    nstrlist = nstr = av->imax - av->imin + 1 ;
00950    strlist = (char **) realloc( strlist , sizeof(char *)*nstr ) ;
00951 
00952    for( ival=av->imin ; ival <= av->imax ; ival++ ){
00953       AV_assign_ival( av , ival ) ;       /* just to create label */
00954       ic = ival - av->imin ;              /* index into widget list */
00955       strlist[ic] = strdup( av->sval ) ;  /* copy label */
00956    }
00957 
00958    AV_assign_ival( av , sval ) ;
00959    av->block_assign_actions = 0 ;         /* back to normal */
00960 
00961    /** actually choose something **/
00962 
00963    XtVaGetValues( av->wlabel , XmNlabelString , &xstr , NULL ) ;
00964    XmStringGetLtoR( xstr , XmFONTLIST_DEFAULT_TAG , &slab ) ;
00965    XmStringFree(xstr) ;
00966 
00967    MCW_choose_strlist( w , slab , nstr ,
00968                        sval - av->imin , strlist ,
00969                        optmenu_finalize , cd      ) ;
00970    EXRETURN ;
00971 }
00972 
00973 /*--------------------------------------------------------------------------
00974    Create a colormenu -- an optmenu with buttons colorized
00975 ----------------------------------------------------------------------------*/
00976 
00977 MCW_arrowval * new_MCW_colormenu( Widget parent , char * label , MCW_DC * dc ,
00978                                   int min_col , int max_col , int ini_col ,
00979                                   gen_func * delta_value, XtPointer delta_data
00980                                 )
00981 {
00982    MCW_arrowval * av ;
00983    Widget * children ;
00984    int  num_children , ic , icol ;
00985 
00986 ENTRY("new_MCW_colormenu") ;
00987 
00988    av = new_MCW_optmenu( parent , label ,
00989                          min_col , max_col , ini_col , 0 ,
00990                          delta_value , delta_data ,
00991                          MCW_DC_ovcolor_text , (XtPointer) dc ) ;
00992 
00993    XtVaGetValues( av->wmenu , XmNchildren    , &children ,
00994                               XmNnumChildren , &num_children , NULL ) ;
00995 
00996    for( ic=0 ; ic < num_children ; ic++ ){
00997       icol = min_col + ic ;
00998       if( icol > 0 ) MCW_set_widget_bg( children[ic] , 0 , dc->ovc->pix_ov[icol] ) ;
00999       else           MCW_set_widget_bg( children[ic] , "gray40" , 0 ) ;
01000    }
01001 
01002    if( max_col > COLSIZE ) AVOPT_columnize( av , 1+(max_col-1)/COLSIZE ) ;
01003 
01004    RETURN(av) ;
01005 }
01006 
01007 char * MCW_av_substring_CB( MCW_arrowval * av , XtPointer cd )
01008 {
01009    char ** str = (char **) cd ;
01010    return str[av->ival] ;
01011 }
01012 
01013 /*-----------------------------------------------------------------------*/
01014 
01015 void AVOPT_press_CB( Widget wbut, XtPointer client_data, XtPointer call_data )
01016 {
01017    MCW_arrowval * av = (MCW_arrowval *) client_data ;
01018    int newval ;
01019    XtPointer xval ;
01020 
01021    XtVaGetValues( wbut , XmNuserData , &xval , NULL ) ;
01022    newval = (int) xval ;
01023 
01024    AV_assign_ival( av , newval ) ;  /* assign */
01025 
01026    /* call user callback, if present */
01027 
01028    if( av->dval_CB != NULL && av->fval != av->old_fval )
01029 #if 0
01030       av->dval_CB( av , av->dval_data ) ;
01031 #else
01032       AFNI_CALL_VOID_2ARG( av->dval_CB ,
01033                            MCW_arrowval * , av ,
01034                            XtPointer      , av->dval_data ) ;
01035 #endif
01036 
01037    return ;
01038 }
01039 
01040 /*-----------------------------------------------------------------------*/
01041 
01042 void AV_press_CB( Widget warrow, XtPointer client_data, XtPointer call_data )
01043 {
01044    MCW_arrowval * av                 = (MCW_arrowval *) client_data ;
01045    XmArrowButtonCallbackStruct * cbs =
01046                         (XmArrowButtonCallbackStruct *) call_data ;
01047 
01048    XtIntervalId fake_id = 0 ;
01049 
01050    /* release of button */
01051 
01052    switch( cbs->reason ){
01053 
01054       default:
01055       case XmCR_DISARM:
01056          if( av->timer_id != 0 ) XtRemoveTimeOut( av->timer_id ) ; /* stop */
01057          av->timer_id = 0 ;
01058       break ;
01059 
01060       case XmCR_ARM:
01061               if( warrow == av->wup   ) av->incr =  1 ;  /* go up */
01062          else if( warrow == av->wdown ) av->incr = -1 ;  /* down  */
01063          else                           return ;
01064 
01065          if( cbs->event->type == ButtonPress ) av->delay = MCW_AV_longdelay ;
01066          else                                  av->delay = 0 ;
01067 
01068          av->xev = *(cbs->event) ;  /* copy event for user's info */
01069 
01070          AV_timer_CB( av , &fake_id ) ; /* do the work */
01071    }
01072    return;
01073 }
01074 
01075 /*------------------------------------------------------------------------*/
01076 
01077 void AV_timer_CB( XtPointer client_data , XtIntervalId * id )
01078 {
01079    MCW_arrowval * av = (MCW_arrowval *) client_data ;
01080    int newval ;
01081    double sval ;
01082 
01083    if( av->fstep == 0.0 ){   /* 16 Feb 1999: this is the old way */
01084 
01085       sval = av->fval ;  AV_SHIFT_VAL( -av->decimals , sval ) ;
01086 
01087       if( av->incr < 0 ){
01088          newval = (int) floor( 0.99 + sval + av->incr ) ;
01089       } else {
01090          newval = (int)  ceil(-0.99 + sval + av->incr ) ;
01091       }
01092 
01093       if( newval > av->imax && av->allow_wrap ){            /* out of range? wrap. */
01094          newval = av->imin ;
01095       } else if( newval < av->imin && av->allow_wrap ){
01096          newval = av->imax ;
01097 
01098       } else if( newval > av->imax || newval < av->imin ){  /* out of range? stop. */
01099          av->timer_id = 0 ;
01100          return ;
01101       }
01102 
01103       AV_assign_ival( av , newval ) ;  /* assign */
01104 
01105    } else {  /* 16 Feb 1999: this is the new way, if user sets fstep */
01106 
01107       if( av->incr > 0 )
01108          sval = av->fval + av->fstep ;
01109       else
01110          sval = av->fval - av->fstep ;
01111 
01112       if( sval > av->fmax || sval < av->fmin ){  /* out of range? stop. */
01113          av->timer_id = 0 ;
01114          return ;
01115       }
01116 
01117       AV_assign_fval( av , sval ) ;
01118    }
01119 
01120    /* call user callback, if present */
01121 
01122    if( av->dval_CB != NULL && av->fval != av->old_fval )
01123 #if 0
01124       av->dval_CB( av , av->dval_data ) ;
01125 #else
01126       AFNI_CALL_VOID_2ARG( av->dval_CB ,
01127                            MCW_arrowval * , av ,
01128                            XtPointer      , av->dval_data ) ;
01129 #endif
01130 
01131    /* delay and then call again, if desired */
01132 
01133    if( av->delay <= 0 ) return ;
01134 
01135    av->timer_id = XtAppAddTimeOut(
01136                      XtWidgetToApplicationContext( av->wrowcol ) ,
01137                      av->delay , AV_timer_CB , av ) ;
01138 
01139    if( av->delay == MCW_AV_longdelay )
01140       if( av->fastdelay > 0 ) av->delay = av->fastdelay ;
01141       else                    av->delay = MCW_AV_shortdelay ;
01142 
01143    return ;
01144 }
01145 
01146 /*------------------------------------------------------------------------*/
01147 
01148 void AV_assign_ival( MCW_arrowval * av , int nval )
01149 {
01150    int newival = nval ;
01151    char * cval ;
01152 
01153 ENTRY("AV_assign_ival") ;
01154 
01155    if( av == NULL ) EXRETURN ;  /* 01 Feb 2000 */
01156 
01157    if( newival > av->imax ) newival = av->imax ;
01158    if( newival < av->imin ) newival = av->imin ;
01159 
01160    /* assign */
01161 
01162    av->old_ival = av->ival ;
01163    av->old_fval = av->fval ;
01164 
01165    av->fval = av->ival = newival ;
01166 
01167    /* adjust decimal point */
01168 
01169    AV_SHIFT_VAL( av->decimals , av->fval ) ;
01170 
01171    /* change text display, if present */
01172 
01173    if( av->text_CB != NULL ){
01174 #if 0
01175       cval = av->text_CB( av , av->text_data ) ;            /* save   */
01176 #else
01177       AFNI_CALL_VALU_2ARG( av->text_CB , char * , cval ,
01178                            MCW_arrowval * , av ,
01179                            XtPointer      , av->text_data ) ;
01180 #endif
01181       myXtFree( av->old_sval ) ; av->old_sval = av->sval ;  /* string */
01182       av->sval = XtNewString( cval ) ;                      /* values */
01183 
01184       if( av->wtext != NULL && ! av->block_assign_actions )
01185          TEXT_SET( av->wtext , cval ) ;
01186    }
01187 
01188    /* if an option menu, change display */
01189 
01190    if( av->wmenu != NULL && ! av->block_assign_actions ){
01191 
01192       Widget * children , wbut ;
01193       int  num_children , ic ;
01194 
01195       XtVaGetValues( av->wmenu ,
01196                         XmNchildren    , &children ,
01197                         XmNnumChildren , &num_children ,
01198                      NULL ) ;
01199 
01200       XtVaGetValues( av->wrowcol , XmNmenuHistory , &wbut , NULL ) ;
01201 
01202       ic = newival - av->imin ;
01203 
01204       if( ic >= 0 && ic < num_children && wbut != children[ic] )
01205          XtVaSetValues( av->wrowcol ,  XmNmenuHistory , children[ic] , NULL ) ;
01206    }
01207 
01208    EXRETURN ;
01209 }
01210 
01211 /*-------------------------------------------------------------------------
01212   format a floating value for output
01213 ---------------------------------------------------------------------------*/
01214 
01215 char * AV_default_text_CB( MCW_arrowval * av , XtPointer junk )
01216 {
01217    static char buf[32] ;
01218 
01219    if( av == NULL ) buf[0] = '\0' ;
01220    else             AV_fval_to_char( av->fval , buf ) ;
01221    return &(buf[0]) ;
01222 }
01223 
01224 /*------------------------------------------------------------------------*/
01225 
01226 void AV_fval_to_char( float qval , char * buf )
01227 {
01228    float aval = fabs(qval) ;
01229    int lv ;
01230    char lbuf[16] ;
01231    int il ;
01232 
01233    /* special case if the value is an integer */
01234 
01235    lv = (fabs(qval) < 9999999.0) ? (int)qval : 10000001 ;
01236 
01237    if( qval == lv && abs(lv) < 10000000 ){
01238       if( lv >= 0 ) sprintf( buf , " %d" , lv ) ;
01239       else          sprintf( buf , "%d"  , lv ) ;
01240       return ;
01241    }
01242 
01243 /* macro to strip trailing zeros from output */
01244 
01245 #define BSTRIP \
01246    for( il=AV_NCOL-1 ; il>1 && lbuf[il]=='0' ; il-- ) lbuf[il] = '\0'
01247 
01248    /* noninteger: choose floating format based on magnitude */
01249 
01250    lv = (int) (10.0001 + log10(aval)) ;
01251 
01252    switch( lv ){
01253 
01254       default:
01255          if( qval > 0.0 ) sprintf( lbuf , "%9.3e" , qval ) ;
01256          else             sprintf( lbuf , "%9.2e" , qval ) ;
01257       break ;
01258 
01259       case  6:  /* 0.0001-0.001 */
01260       case  7:  /* 0.001 -0.01  */
01261       case  8:  /* 0.01  -0.1   */
01262       case  9:  /* 0.1   -1     */
01263       case 10:  /* 1     -9.99  */
01264          sprintf( lbuf , "%9.6f" , qval ) ; BSTRIP ; break ;
01265 
01266       case 11:  /* 10-99.9 */
01267          sprintf( lbuf , "%9.5f" , qval ) ; BSTRIP ; break ;
01268 
01269       case 12:  /* 100-999.9 */
01270          sprintf( lbuf , "%9.4f" , qval ) ; BSTRIP ; break ;
01271 
01272       case 13:  /* 1000-9999.9 */
01273          sprintf( lbuf , "%9.3f" , qval ) ; BSTRIP ; break ;
01274 
01275       case 14:  /* 10000-99999.9 */
01276          sprintf( lbuf , "%9.2f" , qval ) ; BSTRIP ; break ;
01277 
01278       case 15:  /* 100000-999999.9 */
01279          sprintf( lbuf , "%9.1f" , qval ) ; BSTRIP ; break ;
01280 
01281       case 16:  /* 1000000-9999999.9 */
01282          sprintf( lbuf , "%9.0f" , qval ) ; break ;
01283    }
01284 
01285    lv = strlen(lbuf) ;                /* length of result at this stage */
01286 
01287    if( lv <= AV_NCOL ){               /* length OK */
01288       strcpy(buf,lbuf) ;
01289    } else {                           /* too long (should not occur!) */
01290       sprintf( lbuf , "%%%d.%dg" , AV_NCOL , AV_NCOL-7 ) ;
01291       sprintf( buf , lbuf , qval ) ;
01292    }
01293    return ;
01294 }
01295 
01296 /*------------------------------------------------------------------------*/
01297 
01298 char * AV_format_fval( float fval )
01299 {
01300    static char buf[32] ;
01301    AV_fval_to_char( fval , buf ) ;
01302    return buf ;
01303 }
01304 
01305 /*------------------------------------------------------------------------*/
01306 
01307 char * AV_uformat_fval( float fval )
01308 {
01309    static char buf[32] ;
01310    AV_fval_to_char( fval , buf ) ;
01311    if( buf[0] == ' ' ) return (buf+1) ;
01312    return buf ;
01313 }
01314 
01315 /*------------------------------------------------------------------------*/
01316 
01317 void AV_assign_fval( MCW_arrowval * av , float qval )
01318 {
01319    double newfval = qval ;
01320    char * cval ;
01321 
01322    if( av == NULL ) return ; /* 01 Feb 2000 */
01323 
01324    if( newfval > av->fmax ) newfval = av->fmax ;
01325    if( newfval < av->fmin ) newfval = av->fmin ;
01326 
01327    /* assign */
01328 
01329    av->old_ival = av->ival ;
01330    av->old_fval = av->fval ;
01331 
01332    av->fval = newfval ;
01333 
01334    /* adjust decimal point */
01335 
01336    AV_SHIFT_VAL( -av->decimals , newfval ) ;
01337 
01338    av->ival = (int) floor(newfval) ;
01339 
01340    /* change text display, if present */
01341 
01342    if( av->text_CB != NULL ){
01343 #if 0
01344       cval = av->text_CB( av , av->text_data ) ;            /* save   */
01345 #else
01346       AFNI_CALL_VALU_2ARG( av->text_CB , char * , cval ,
01347                            MCW_arrowval * , av ,
01348                            XtPointer      , av->text_data ) ;
01349 #endif
01350       myXtFree( av->old_sval ) ; av->old_sval = av->sval ;  /* string */
01351       av->sval = XtNewString( cval ) ;                      /* values */
01352 
01353       if( av->wtext != NULL && ! av->block_assign_actions )
01354          TEXT_SET( av->wtext , cval ) ;
01355    }
01356 
01357    return ;
01358 }
01359 
01360 /*----------------------------------------------------------------------*/
01361 
01362 void AV_leave_EV( Widget w , XtPointer client_data ,
01363                   XEvent * ev , Boolean * continue_to_dispatch )
01364 {
01365    MCW_arrowval * av       = (MCW_arrowval *) client_data ;
01366    XLeaveWindowEvent * lev = (XLeaveWindowEvent *) ev ;
01367    XmAnyCallbackStruct cbs ;
01368 
01369    if( lev->type != LeaveNotify || av == NULL ) return ;
01370 
01371    cbs.reason = XmCR_ACTIVATE ;  /* simulate a return press */
01372    AV_textact_CB( av->wtext , (XtPointer) av , &cbs ) ;
01373 }
01374 
01375 /*----------------------------------------------------------------------*/
01376 
01377 void AV_textact_CB( Widget wtex, XtPointer client_data, XtPointer call_data )
01378 {
01379    MCW_arrowval * av         = (MCW_arrowval *) client_data ;
01380    XmAnyCallbackStruct * cbs = (XmAnyCallbackStruct *) call_data ;
01381 
01382    float sval ;
01383    int   ii ;
01384    char * str ;
01385 
01386 ENTRY("AV_textact_CB") ;
01387 
01388    if( (cbs->reason != XmCR_ACTIVATE && cbs->reason != XmCR_LOSING_FOCUS )
01389        || wtex != av->wtext ){
01390       fprintf(stderr,"\n*** Illegal call to AV_textact_CB ***\n") ;
01391       EXRETURN ;
01392    }
01393 
01394    str = TEXT_GET( wtex ) ;  /* get the new text */
01395 
01396    /* check if new text is any different from last value */
01397 
01398    if( av->sval != NULL && strcmp( av->sval , str ) == 0 ){
01399      myXtFree(str) ; EXRETURN ;
01400    }
01401 
01402    MCW_invert_widget( wtex ) ;  /* start flash */
01403 
01404    ii = sscanf( str , "%f" , &sval ) ;  /* convert to float in sval */
01405 
01406    if( ii == 0 ) sval = av->fval ;  /* bad float conversion */
01407 
01408    AV_assign_fval( av , sval ) ;  /* will alter ival,fval,sval in av */
01409 
01410    if( av->dval_CB != NULL && av->fval != av->old_fval )  /* value changed */
01411 #if 0
01412       av->dval_CB( av , av->dval_data ) ;
01413 #else
01414       AFNI_CALL_VOID_2ARG( av->dval_CB ,
01415                            MCW_arrowval * , av ,
01416                            XtPointer      , av->dval_data ) ;
01417 #endif
01418 
01419    myXtFree(str) ;  /* give it back */
01420 
01421    MCW_invert_widget( wtex ) ;  /* end flash */
01422    EXRETURN ;
01423 }
01424 
01425 /*----------------------------------------------------------------------
01426    NULL out the pointer to a popup widget when the widget is destroyed
01427 ------------------------------------------------------------------------*/
01428 
01429 void MCW_destroy_chooser_CB( Widget wpop ,
01430                              XtPointer client_data, XtPointer call_data )
01431 {
01432    Widget *wpointer = (Widget *) client_data ;
01433 ENTRY("MCW_destroy_chooser_CB") ;
01434    *wpointer = NULL ;
01435    EXRETURN ;
01436 }
01437 
01438 void MCW_kill_chooser_CB( Widget w ,
01439                           XtPointer client_data, XtPointer call_data )
01440 {
01441    Widget wpop = (Widget) client_data ;
01442 ENTRY("MCW_kill_chooser_CB") ;
01443    XtDestroyWidget(wpop) ;
01444 EXRETURN ;
01445 }
01446 
01447 /*-----------------------------------------------------------------------*/
01448 
01449 #undef RECOLOR_OPTMENU
01450 
01451 char * MCW_DC_ovcolor_text( MCW_arrowval * av , MCW_DC * dc )
01452 {
01453    int ii = av->ival ;
01454    Widget wfix ;
01455 
01456         if( ii < 0                    ) ii = 0 ;
01457    else if( ii > dc->ovc->ncol_ov - 1 ) ii = dc->ovc->ncol_ov - 1 ;
01458 
01459    wfix = av->wtext ;
01460 
01461    if( wfix != NULL ){
01462       if( ii > 0 ) MCW_set_widget_bg( wfix , 0 , dc->ovc->pix_ov[ii] ) ;
01463       else         MCW_set_widget_bg( wfix , "gray40" , 0 ) ;
01464    }
01465 
01466 #ifdef RECOLOR_OPTMENU
01467    /** make the option menu cascade button gadget be outlined in color **/
01468 
01469    else if( av->wmenu != NULL && XtIsRealized(av->wrowcol) ){
01470       Pixel ptop , pbot ;
01471       wfix = av->wrowcol ;
01472       if( ii > 0 ) pbot = ptop = dc->ovc->pix_ov[ii] ;
01473       else         XtVaGetValues( XtParent(wfix) ,
01474                                      XmNtopShadowColor    , &ptop ,
01475                                      XmNbottomShadowColor , &pbot ,
01476                                   NULL ) ;
01477       XtVaSetValues( wfix ,
01478                         XmNtopShadowColor    , ptop ,
01479                         XmNbottomShadowColor , pbot ,
01480                      NULL ) ;
01481    }
01482 #endif
01483 
01484    return dc->ovc->label_ov[ii] ;
01485 }
01486 
01487 /*------------------------------------------------------------------------
01488    Get a table index for a DC overlay color:
01489      pops up a shell to let the user make the selection
01490 
01491      wpar     = parent widget (where to popup)
01492      dc       = display context to choose colors from
01493      ovc_init = initial overlay color index
01494 
01495      func = routine to call when a selection is made:
01496              void func( Widget wpar,XtPointer func_data,MCW_choose_cbs * cbs )
01497      func_data = data to pass to func
01498 
01499      The "ival" stored in the MCW_choose_cbs will be the index into the
01500      DC overlay color table.  The pixel value is thus dc->ovc->pix_ov[cbs->ival].
01501      The color name is dc->ovc->name_ov[cbs->ival].  Etc.
01502 
01503      Note that cbs->ival = 0 means that the user choose the "None" color.
01504 
01505    This routine is coded in such a way that only one color chooser will be
01506    active at a time (per application).  This is a deliberate choice.
01507 --------------------------------------------------------------------------*/
01508 
01509 #define OVC_quit_label   "Quit"
01510 #define OVC_apply_label  "Apply"
01511 #define OVC_done_label   "Set"
01512 #define OVC_clear_label  "Clear"
01513 
01514 #define OVC_quit_help   "Press to close\nthis `chooser'"
01515 #define OVC_apply_help  "Press to apply\nthis choice and\nkeep this `chooser'"
01516 #define OVC_done_help   "Press to apply\nthis choice and\nclose this `chooser'"
01517 #define OVC_clear_help  "Press to clear\nthe entry"
01518 
01519 #define OVC_av_help   "Use arrows to\nsee what choices\nare available"
01520 #define OVC_opt_help  "Click this button\nto pop up a menu\nof overlay colors"
01521 
01522 #define OVC_list_help_1 "Click Button 1 on the\n"   \
01523                         "item of your choice,\n"    \
01524                         "then press one of the\n"   \
01525                         "control buttons below.\n"  \
01526                         "        ** OR **\n"        \
01527                         "Double-click Button 1\n"   \
01528                         "on an item to choose it."
01529 
01530 #define OVC_list_help_2 "Multiple Mode:\n"               \
01531                         "  Click Button 1 on items to\n" \
01532                         "  select or de-select them.\n"  \
01533                         "\n"                             \
01534                         "Extended Mode:\n"               \
01535                         "+ Click and drag Button 1 to\n" \
01536                         "   select ranges of items.\n"   \
01537                         "+ Press Ctrl (on keyboard)\n"   \
01538                         "   at same time to avoid\n"     \
01539                         "   de-selecting items that\n"   \
01540                         "   were selected previously."
01541 
01542 #define NUM_OVC_ACT 3
01543 #define NUM_CLR_ACT 4
01544 
01545 static MCW_action_item OVC_act[] = {
01546  { OVC_quit_label , MCW_choose_CB, NULL, OVC_quit_help ,"Close window"                 ,0 },
01547  { OVC_apply_label, MCW_choose_CB, NULL, OVC_apply_help,"Apply choice and keep window" ,0 },
01548  { OVC_done_label , MCW_choose_CB, NULL, OVC_done_help ,"Apply choice and close window",1 },
01549  { OVC_clear_label, MCW_choose_CB, NULL, OVC_clear_help,"Clear entry"                  ,0 }
01550 } ;
01551 
01552 #define NUM_LIST_MODES 2
01553 static char * list_modes[NUM_LIST_MODES] = { "Multiple" , "Extended" } ;
01554 
01555 void MCW_choose_ovcolor( Widget wpar , MCW_DC * dc , int ovc_init ,
01556                          gen_func * func , XtPointer func_data )
01557 {
01558    static Widget wpop = NULL , wrc ;
01559    static MCW_arrowval *  av = NULL ;
01560    static MCW_choose_data cd ;
01561    Position xx,yy ;
01562    int ib ;
01563 
01564 ENTRY("MCW_choose_ovcolor") ;
01565 
01566    /** destructor callback **/
01567 
01568    if( wpar == NULL ){
01569       if( wpop != NULL ){
01570          XtUnmapWidget( wpop ) ;
01571          XtRemoveCallback( wpop, XmNdestroyCallback, MCW_destroy_chooser_CB, &wpop ) ;
01572          XtDestroyWidget( wpop ) ;
01573       }
01574       wpop = NULL ; EXRETURN ;
01575    }
01576 
01577    if( ! XtIsRealized(wpar) || dc->ovc->ncol_ov < 2 ){  /* illegal call */
01578       fprintf(stderr,"\n*** illegal call to MCW_choose_ovcolor: %s %d\n",
01579              XtName(wpar) , dc->ovc->ncol_ov ) ;
01580       EXRETURN ;
01581    }
01582 
01583    if( ovc_init < 0 || ovc_init >= dc->ovc->ncol_ov ) ovc_init = 1 ;
01584 
01585    /*--- if popup widget already exists, destroy it ---*/
01586 
01587    if( wpop != NULL ){
01588       XtRemoveCallback( wpop, XmNdestroyCallback, MCW_destroy_chooser_CB, &wpop ) ;
01589       XtDestroyWidget( wpop ) ;
01590    }
01591 
01592    if( av != NULL ){
01593        myXtFree( av ) ; av = NULL ;
01594    }
01595 
01596    /*--- create popup widget ---*/
01597 
01598    wpop = XtVaCreatePopupShell(                        /* Popup Shell */
01599              "menu" , xmDialogShellWidgetClass , wpar ,
01600                 XmNtraversalOn , False ,
01601                 XmNinitialResourcesPersistent , False ,
01602              NULL ) ;
01603 
01604    if( MCW_isitmwm(wpar) ){
01605       XtVaSetValues( wpop ,
01606                         XmNmwmDecorations , MWM_DECOR_BORDER ,
01607                         XmNmwmFunctions   ,  MWM_FUNC_MOVE ,
01608                      NULL ) ;
01609    }
01610 
01611    XtAddCallback( wpop , XmNdestroyCallback , MCW_destroy_chooser_CB , &wpop ) ;
01612 
01613    XmAddWMProtocolCallback(
01614         wpop ,
01615         XmInternAtom( XtDisplay(wpop) , "WM_DELETE_WINDOW" , False ) ,
01616         MCW_kill_chooser_CB , wpop ) ;
01617 
01618    wrc  = XtVaCreateWidget(                    /* RowColumn to hold all */
01619              "menu" , xmRowColumnWidgetClass , wpop ,
01620                 XmNpacking      , XmPACK_TIGHT ,
01621                 XmNorientation  , XmVERTICAL ,
01622                 XmNtraversalOn , False ,
01623                 XmNinitialResourcesPersistent , False ,
01624              NULL ) ;
01625 
01626    av = new_MCW_colormenu( wrc , "Color " , dc ,
01627                            0 , dc->ovc->ncol_ov - 1 , ovc_init , NULL,NULL ) ;
01628    MCW_reghelp_children( av->wrowcol , OVC_opt_help ) ;
01629    MCW_reghint_children( av->wrowcol , "Overlay colors" ) ;
01630 
01631    cd.dc      = dc ;    /* data to be passed to pushbutton callback */
01632    cd.wpop    = wpop ;
01633    cd.wcaller = wpar ;
01634    cd.av      = av ;
01635    cd.sel_CB  = func ;
01636    cd.sel_cd  = func_data ;
01637    cd.ctype   = mcwCT_ovcolor ;
01638 
01639    for( ib=0 ; ib < NUM_OVC_ACT ; ib++ ) OVC_act[ib].data = &cd ;
01640 
01641    (void) MCW_action_area( wrc , OVC_act , NUM_OVC_ACT ) ;
01642 
01643    XtTranslateCoords( wpar , 15,15 , &xx , &yy ) ;
01644    XtVaSetValues( wpop , XmNx , (int) xx , XmNy , (int) yy , NULL ) ;
01645 
01646    XtManageChild( wrc ) ;
01647    XtPopup( wpop , XtGrabNone ) ;
01648 
01649    if( av->wtext != NULL )
01650       MCW_set_widget_bg( av->wtext , NULL , dc->ovc->pix_ov[ovc_init] ) ; /* after popup */
01651 
01652    RWC_visibilize_widget( wpop ) ;   /* 09 Nov 1999 */
01653    NORMAL_cursorize( wpop ) ;
01654 
01655    EXRETURN ;
01656 }
01657 
01658 /*-------------------------------------------------------------------------*/
01659 /*! Get a bunch of values [19 Mar 2004].
01660 ---------------------------------------------------------------------------*/
01661 
01662 void MCW_choose_vector( Widget wpar , char *label ,
01663                         int nvec , char **labvec , int *initvec ,
01664                         gen_func *func , XtPointer func_data )
01665 {
01666    static Widget wpop = NULL , wrc ;
01667    static MCW_arrowval **av = NULL ;
01668    static int           nav = 0 ;
01669    static MCW_choose_data cd ;
01670    Position xx,yy ;
01671    int ib , iv ;
01672 
01673 ENTRY("MCW_choose_vector") ;
01674 
01675    /** destructor callback **/
01676 
01677    if( wpar == NULL || nvec <= 0 ){
01678       if( wpop != NULL ){
01679          XtUnmapWidget( wpop ) ;
01680          XtRemoveCallback( wpop, XmNdestroyCallback, MCW_destroy_chooser_CB, &wpop ) ;
01681          XtDestroyWidget( wpop ) ;
01682       }
01683       wpop = NULL ; EXRETURN ;
01684    }
01685 
01686    if( ! XtIsRealized(wpar) ){  /* illegal call */
01687       fprintf(stderr,"\n*** illegal call to MCW_choose_vector: %s\n",
01688               XtName(wpar) ) ;
01689       EXRETURN ;
01690    }
01691 
01692    /*--- if popup widget already exists, destroy it ---*/
01693 
01694    if( wpop != NULL ){
01695       XtRemoveCallback( wpop, XmNdestroyCallback, MCW_destroy_chooser_CB, &wpop ) ;
01696       XtDestroyWidget( wpop ) ;
01697    }
01698 
01699    if( nav > 0 && av != NULL ){
01700      for( iv=0 ; iv < nav ; iv++ ) myXtFree( av[iv] ) ;
01701      myXtFree(av) ; av = NULL ; nav = 0 ;
01702    }
01703 
01704    /*--- create popup widget ---*/
01705 
01706    wpop = XtVaCreatePopupShell(                           /* Popup Shell */
01707              "menu" , xmDialogShellWidgetClass , wpar ,
01708                 XmNtraversalOn , False ,
01709                 XmNinitialResourcesPersistent , False ,
01710              NULL ) ;
01711 
01712    if( MCW_isitmwm(wpar) ){
01713       XtVaSetValues( wpop ,
01714                         XmNmwmDecorations , MWM_DECOR_BORDER ,
01715                         XmNmwmFunctions   ,  MWM_FUNC_MOVE ,
01716                      NULL ) ;
01717    }
01718 
01719    XtAddCallback( wpop , XmNdestroyCallback , MCW_destroy_chooser_CB , &wpop ) ;
01720 
01721    XmAddWMProtocolCallback(
01722         wpop ,
01723         XmInternAtom( XtDisplay(wpop) , "WM_DELETE_WINDOW" , False ) ,
01724         MCW_kill_chooser_CB , wpop ) ;
01725 
01726    wrc  = XtVaCreateWidget(                 /* RowColumn to hold all */
01727              "menu" , xmRowColumnWidgetClass , wpop ,
01728                 XmNpacking      , XmPACK_TIGHT ,
01729                 XmNorientation  , XmVERTICAL ,
01730                 XmNtraversalOn , False ,
01731                 XmNinitialResourcesPersistent , False ,
01732              NULL ) ;
01733 
01734    if( label != NULL ){
01735      (void) XtVaCreateManagedWidget(
01736                   "menu" , xmLabelWidgetClass , wrc ,
01737                      LABEL_ARG(label) ,
01738                      XmNinitialResourcesPersistent , False ,
01739                   NULL ) ;
01740      (void) XtVaCreateManagedWidget(
01741               "menu" , xmSeparatorWidgetClass , wrc ,
01742                   XmNseparatorType , XmSHADOW_ETCHED_IN ,
01743                   XmNinitialResourcesPersistent , False ,
01744               NULL ) ;
01745    }
01746 
01747    av = (MCW_arrowval **) XtMalloc( sizeof(MCW_arrowval *) * nvec ) ;
01748    for( iv=0 ; iv < nvec ; iv++ ){
01749      av[iv] = new_MCW_arrowval( wrc ,
01750                                 (labvec!=NULL) ? labvec[iv] : NULL ,
01751                                 MCW_AV_downup ,
01752                                 -99999,99999,
01753                                 (initvec!=NULL) ? initvec[iv] : 0 ,
01754                                 MCW_AV_edittext , 0 ,
01755                                 NULL , NULL , NULL , NULL ) ;
01756    }
01757 
01758    cd.wpop    = wpop ;  /* data to be passed to pushbutton callback */
01759    cd.wcaller = wpar ;
01760    cd.av      = (MCW_arrowval *)av ;  /* hack hack hack */
01761    cd.sel_CB  = func ;
01762    cd.sel_cd  = func_data ;
01763    cd.ctype   = mcwCT_vector ;
01764    cd.nvec    = nvec ;
01765 
01766    for( ib=0 ; ib < NUM_OVC_ACT ; ib++ ) OVC_act[ib].data = &cd ;
01767 
01768    (void) MCW_action_area( wrc , OVC_act , NUM_OVC_ACT ) ;
01769 
01770    XtTranslateCoords( wpar , 15,15 , &xx , &yy ) ;
01771    XtVaSetValues( wpop , XmNx , (int) xx , XmNy , (int) yy , NULL ) ;
01772 
01773    XtManageChild( wrc ) ;
01774    XtPopup( wpop , XtGrabNone ) ;
01775 
01776    RWC_visibilize_widget( wpop ) ;
01777    NORMAL_cursorize( wpop ) ;
01778 
01779    EXRETURN ;
01780 }
01781 
01782 /*-------------------------------------------------------------------------
01783    Get an integer:
01784      pops up a shell to let the user make the selection
01785 
01786      wpar         = parent widget (where to popup)
01787      label        = label for chooser
01788      bot,top,init = integers defining range and initial value
01789      func         = routine to call when a selection is made:
01790             void func( Widget wpar,XtPointer func_data,MCW_choose_cbs * cbs )
01791      func_data    = data to pass to func
01792 
01793      The "ival" stored in the MCW_choose_cbs will be the desired result.
01794 
01795    This routine is coded in such a way that only one chooser will be
01796    active at a time (per application).  This is a deliberate choice.
01797 ---------------------------------------------------------------------------*/
01798 
01799 void MCW_choose_integer( Widget wpar , char *label ,
01800                          int bot , int top , int init ,
01801                          gen_func *func , XtPointer func_data )
01802 {
01803    static Widget wpop = NULL , wrc ;
01804    static MCW_arrowval *  av = NULL ;
01805    static MCW_choose_data cd ;
01806    Position xx,yy ;
01807    int ib ;
01808 
01809 ENTRY("MCW_choose_integer") ;
01810 
01811    /** destructor callback **/
01812 
01813    if( wpar == NULL ){
01814       if( wpop != NULL ){
01815          XtUnmapWidget( wpop ) ;
01816          XtRemoveCallback( wpop, XmNdestroyCallback, MCW_destroy_chooser_CB, &wpop ) ;
01817          XtDestroyWidget( wpop ) ;
01818       }
01819       wpop = NULL ; EXRETURN ;
01820    }
01821 
01822    if( ! XtIsRealized(wpar) ){  /* illegal call */
01823       fprintf(stderr,"\n*** illegal call to MCW_choose_integer: %s\n",
01824               XtName(wpar) ) ;
01825       EXRETURN ;
01826    }
01827 
01828    /*--- if popup widget already exists, destroy it ---*/
01829 
01830    if( wpop != NULL ){
01831       XtRemoveCallback( wpop, XmNdestroyCallback, MCW_destroy_chooser_CB, &wpop ) ;
01832       XtDestroyWidget( wpop ) ;
01833    }
01834 
01835    if( av != NULL ){
01836       myXtFree( av ) ; av = NULL ;
01837    }
01838 
01839    /*--- create popup widget ---*/
01840 
01841    wpop = XtVaCreatePopupShell(                           /* Popup Shell */
01842              "menu" , xmDialogShellWidgetClass , wpar ,
01843                 XmNtraversalOn , False ,
01844                 XmNinitialResourcesPersistent , False ,
01845              NULL ) ;
01846 
01847    if( MCW_isitmwm(wpar) ){
01848       XtVaSetValues( wpop ,
01849                         XmNmwmDecorations , MWM_DECOR_BORDER ,
01850                         XmNmwmFunctions   ,  MWM_FUNC_MOVE ,
01851                      NULL ) ;
01852    }
01853 
01854    XtAddCallback( wpop , XmNdestroyCallback , MCW_destroy_chooser_CB , &wpop ) ;
01855 
01856    XmAddWMProtocolCallback(
01857         wpop ,
01858         XmInternAtom( XtDisplay(wpop) , "WM_DELETE_WINDOW" , False ) ,
01859         MCW_kill_chooser_CB , wpop ) ;
01860 
01861    wrc  = XtVaCreateWidget(                 /* RowColumn to hold all */
01862              "menu" , xmRowColumnWidgetClass , wpop ,
01863                 XmNpacking      , XmPACK_TIGHT ,
01864                 XmNorientation  , XmVERTICAL ,
01865                 XmNtraversalOn , False ,
01866                 XmNinitialResourcesPersistent , False ,
01867              NULL ) ;
01868 
01869    av = new_MCW_arrowval( wrc ,
01870                           label , MCW_AV_downup ,  /* selection */
01871                           bot,top,init ,
01872                           MCW_AV_edittext , 0 ,
01873                           NULL , NULL , NULL , NULL ) ;
01874 
01875    av->allow_wrap = 1 ;
01876 
01877    MCW_reghelp_children( av->wrowcol , OVC_av_help ) ;
01878    MCW_reghint_children( av->wrowcol , "Pick value" ) ;
01879 
01880    cd.wpop    = wpop ;  /* data to be passed to pushbutton callback */
01881    cd.wcaller = wpar ;
01882    cd.av      = av ;
01883    cd.sel_CB  = func ;
01884    cd.sel_cd  = func_data ;
01885    cd.ctype   = mcwCT_integer ;
01886 
01887    for( ib=0 ; ib < NUM_OVC_ACT ; ib++ ) OVC_act[ib].data = &cd ;
01888 
01889    (void) MCW_action_area( wrc , OVC_act , NUM_OVC_ACT ) ;
01890 
01891    XtTranslateCoords( wpar , 15,15 , &xx , &yy ) ;
01892    XtVaSetValues( wpop , XmNx , (int) xx , XmNy , (int) yy , NULL ) ;
01893 
01894    XtManageChild( wrc ) ;
01895    XtPopup( wpop , XtGrabNone ) ;
01896 
01897    RWC_visibilize_widget( wpop ) ;   /* 09 Nov 1999 */
01898    NORMAL_cursorize( wpop ) ;
01899 
01900    EXRETURN ;
01901 }
01902 
01903 /*-------------------------------------------------------------------------
01904                                 ^
01905   Create a new MCW_arrowpad:  < O >
01906                                 v
01907     parent  = parent Widget
01908 
01909     press_func = pointer to a function that will be called when an arrow or
01910                    the button at the center is pressed
01911     press_data =  pointer to data to be passed to press_func;
01912                      press_func( apad , press_data ) ;
01913                   where apad is a pointer to the MCW_arrowpad that was hit.
01914 
01915     If press_func is NULL, no callback occurs. You may create the arrowpad and
01916     later set the callback by apad->action_CB = press_func.
01917 ---------------------------------------------------------------------------*/
01918 
01919 MCW_arrowpad * new_MCW_arrowpad( Widget parent ,
01920                                  gen_func * press_func, XtPointer press_data
01921                                )
01922 {
01923    MCW_arrowpad * apad ;
01924    int asizx = 20 , asizy = 20 ;  /* arrow sizes */
01925    int iar ;
01926 
01927 ENTRY("new_MCW_arrowpad") ;
01928 
01929    apad = myXtNew( MCW_arrowpad ) ;
01930 
01931    /*--- form to hold the stuff: everything is tied to rubber positions ---*/
01932 
01933    apad->wform = XtVaCreateWidget(
01934                     "dialog" , xmFormWidgetClass , parent ,
01935                        XmNfractionBase , AP_FBASE ,
01936                        XmNinitialResourcesPersistent , False ,
01937                        XmNtraversalOn , False ,
01938                     NULL ) ;
01939 
01940    /*--- create the arrowbuttons ---*/
01941 
01942    for( iar = 0 ; iar < 4 ; iar++ ){
01943       apad->wbut[iar] =
01944          XtVaCreateManagedWidget(
01945                   "arrow" , xmArrowButtonWidgetClass , apad->wform ,
01946 
01947                      XmNtopAttachment    , XmATTACH_POSITION ,
01948                      XmNbottomAttachment , XmATTACH_POSITION ,
01949                      XmNleftAttachment   , XmATTACH_POSITION ,
01950                      XmNrightAttachment  , XmATTACH_POSITION ,
01951 
01952                      XmNarrowDirection , AP_but_def[iar].atype ,
01953                      XmNtopPosition    , AP_but_def[iar].atop ,
01954                      XmNbottomPosition , AP_but_def[iar].abottom ,
01955                      XmNleftPosition   , AP_but_def[iar].aleft ,
01956                      XmNrightPosition  , AP_but_def[iar].aright ,
01957 
01958                      XmNheight , asizy ,
01959                      XmNwidth  , asizx ,
01960                      XmNborderWidth , 0 ,
01961 
01962                      XmNinitialResourcesPersistent , False ,
01963                      XmNtraversalOn , False ,
01964                   NULL ) ;
01965 
01966 
01967       XtAddCallback( apad->wbut[iar], XmNarmCallback   , AP_press_CB, apad ) ;
01968       XtAddCallback( apad->wbut[iar], XmNdisarmCallback, AP_press_CB, apad ) ;
01969    }
01970 
01971    /*--- create the pushbutton in the middle ---*/
01972 
01973    apad->wbut[4] = XtVaCreateManagedWidget(
01974                    "arrow" , xmPushButtonWidgetClass , apad->wform ,
01975 
01976                      XmNtopAttachment    , XmATTACH_POSITION ,
01977                      XmNbottomAttachment , XmATTACH_POSITION ,
01978                      XmNleftAttachment   , XmATTACH_POSITION ,
01979                      XmNrightAttachment  , XmATTACH_POSITION ,
01980 
01981                      XmNtopPosition    , AP_but_def[4].atop ,
01982                      XmNbottomPosition , AP_but_def[4].abottom ,
01983                      XmNleftPosition   , AP_but_def[4].aleft ,
01984                      XmNrightPosition  , AP_but_def[4].aright ,
01985 
01986                      XtVaTypedArg , XmNlabelString , XmRString , " " , 2 ,
01987 
01988                      XmNheight , asizy ,
01989                      XmNwidth  , asizx ,
01990                      XmNborderWidth , 0 ,
01991                      XmNrecomputeSize , False ,
01992 
01993                      XmNinitialResourcesPersistent , False ,
01994                      XmNtraversalOn , False ,
01995                   NULL ) ;
01996 
01997    XtAddCallback( apad->wbut[4] , XmNactivateCallback , AP_press_CB , apad ) ;
01998 
01999    XtManageChild( apad->wform ) ;
02000 
02001    apad->action_CB   = press_func ;
02002    apad->action_data = press_data ;
02003    apad->fastdelay   = MCW_AV_shortdelay ;  /* default delay on 2nd call */
02004    apad->count       = 0 ;
02005 
02006    apad->parent = apad->aux = NULL ;
02007    RETURN(apad) ;
02008 }
02009 
02010 /*-------------------------------------------------------------------------*/
02011 
02012 void AP_press_CB( Widget wbut , XtPointer client_data , XtPointer call_data )
02013 {
02014    MCW_arrowpad * apad               = (MCW_arrowpad *) client_data ;
02015    XmArrowButtonCallbackStruct * cbs =
02016              (XmArrowButtonCallbackStruct *) call_data ;
02017 
02018    XtIntervalId fake_id = 0 ;
02019 
02020    switch( cbs->reason ){
02021 
02022       /*--- release of button (will only happen for arrows) ---*/
02023 
02024       default:
02025       case XmCR_DISARM:  /* time to stop */
02026          if( apad->timer_id != 0 ) XtRemoveTimeOut( apad->timer_id ) ;
02027          apad->timer_id = 0 ;
02028       break ;
02029 
02030       /*--- press of button ---*/
02031 
02032       case XmCR_ARM:        /* arrow press */
02033       case XmCR_ACTIVATE:{  /* button press */
02034          int iar ;
02035 
02036          for( iar=0 ; iar < 5 ; iar++ )
02037             if( wbut == apad->wbut[iar] ) break ;
02038 
02039          if( iar > 4 ) return ;  /* something wrong, exit */
02040 
02041          apad->which_pressed = iar ;
02042          apad->count         = 0 ;
02043 
02044          if( cbs->reason      == XmCR_ARM &&
02045              cbs->event->type == ButtonPress ) apad->delay = MCW_AV_longdelay;
02046          else                                  apad->delay = 0 ;
02047 
02048          apad->xev = *(cbs->event) ;  /* copy event for user's info */
02049 
02050          AP_timer_CB( apad , &fake_id ) ; /* do the work */
02051       }
02052    }
02053    return;
02054 }
02055 
02056 /*-------------------------------------------------------------------------*/
02057 
02058 void AP_timer_CB( XtPointer client_data , XtIntervalId * id )
02059 {
02060    MCW_arrowpad * apad = (MCW_arrowpad *) client_data ;
02061 
02062    /* call user callback */
02063 
02064    if( apad->action_CB != NULL )
02065 #if 0
02066       apad->action_CB( apad , apad->action_data ) ;
02067 #else
02068       AFNI_CALL_VOID_2ARG( apad->action_CB ,
02069                            MCW_arrowpad * , apad ,
02070                            XtPointer      , apad->action_data ) ;
02071 #endif
02072 
02073    /* delay and then call again, if desired */
02074 
02075    if( apad->delay <= 0 ) return ;
02076 
02077    (apad->count)++ ;
02078    if( apad->count > AP_MAXCOUNT ){
02079       apad->count = 0 ;
02080       return ;
02081    }
02082 
02083    apad->timer_id = XtAppAddTimeOut(
02084                      XtWidgetToApplicationContext( apad->wform ) ,
02085                      apad->delay , AP_timer_CB , apad ) ;
02086 
02087    if( apad->delay == MCW_AV_longdelay )
02088       if( apad->fastdelay > 0 ) apad->delay = apad->fastdelay ;
02089       else                      apad->delay = MCW_AV_shortdelay ;
02090 
02091    return ;
02092 }
02093 
02094 /*-------------------------------------------------------------------------
02095    Get a string:
02096      pops up a shell to let the user make the selection
02097 
02098      wpar           = parent widget (where to popup)
02099      label          = label for chooser
02100      default_string = initial value
02101      func           = routine to call when a selection is made:
02102             void func( Widget wpar,XtPointer func_data,MCW_choose_cbs * cbs )
02103      func_data      = data to pass to func
02104 
02105      The "cval" stored in the MCW_choose_cbs will be the desired result.
02106 
02107    This routine is coded in such a way that only one chooser will be
02108    active at a time (per application).  This is a deliberate choice.
02109 ---------------------------------------------------------------------------*/
02110 
02111 void MCW_choose_string( Widget wpar , char * label ,
02112                         char * default_string ,
02113                         gen_func * func , XtPointer func_data )
02114 {
02115    static Widget wpop = NULL , wrc , wtf , wlab ;
02116    static MCW_choose_data cd ;
02117    Position xx,yy ;
02118    int ib , ncol=0 ;
02119 
02120 ENTRY("MCW_choose_string") ;
02121 
02122    /** destructor callback **/
02123 
02124    if( wpar == NULL ){
02125       if( wpop != NULL ){
02126          XtUnmapWidget( wpop ) ;
02127          XtRemoveCallback( wpop, XmNdestroyCallback, MCW_destroy_chooser_CB, &wpop ) ;
02128          XtDestroyWidget( wpop ) ;
02129       }
02130       wpop = NULL ; EXRETURN ;
02131    }
02132 
02133    if( ! XtIsWidget(wpar) ) EXRETURN ;
02134 
02135    if( ! XtIsRealized(wpar) ){  /* illegal call */
02136       fprintf(stderr,"\n*** illegal call to MCW_choose_string: %s\n",
02137               XtName(wpar) ) ;
02138       EXRETURN ;
02139    }
02140 
02141    /*--- if popup widget already exists, destroy it ---*/
02142 
02143    if( wpop != NULL ){
02144       XtRemoveCallback( wpop, XmNdestroyCallback, MCW_destroy_chooser_CB, &wpop ) ;
02145       XtDestroyWidget( wpop ) ;
02146    }
02147 
02148    /*--- create popup widget ---*/
02149 
02150    wpop = XtVaCreatePopupShell(                           /* Popup Shell */
02151              "menu" , xmDialogShellWidgetClass , wpar ,
02152                 XmNtraversalOn , False ,
02153                 XmNinitialResourcesPersistent , False ,
02154              NULL ) ;
02155 
02156    if( MCW_isitmwm(wpar) ){
02157       XtVaSetValues( wpop ,
02158                         XmNmwmDecorations , MWM_DECOR_BORDER ,
02159                         XmNmwmFunctions   ,  MWM_FUNC_MOVE ,
02160                      NULL ) ;
02161    }
02162 
02163    XtAddCallback( wpop , XmNdestroyCallback , MCW_destroy_chooser_CB , &wpop ) ;
02164 
02165    XmAddWMProtocolCallback(
02166         wpop ,
02167         XmInternAtom( XtDisplay(wpop) , "WM_DELETE_WINDOW" , False ) ,
02168         MCW_kill_chooser_CB , wpop ) ;
02169 
02170    wrc  = XtVaCreateWidget(                 /* RowColumn to hold all */
02171              "menu" , xmRowColumnWidgetClass , wpop ,
02172                 XmNpacking      , XmPACK_TIGHT ,
02173                 XmNorientation  , XmVERTICAL ,
02174                 XmNtraversalOn , False ,
02175                 XmNinitialResourcesPersistent , False ,
02176              NULL ) ;
02177 
02178    if( label != NULL && (ncol=strlen(label)) > 0 ){
02179       char *cpt ;
02180       wlab = XtVaCreateManagedWidget(
02181                 "menu" , xmLabelWidgetClass , wrc ,
02182                    LABEL_ARG(label) ,
02183                    XmNinitialResourcesPersistent , False ,
02184                 NULL ) ;
02185 
02186       cpt = strstr(label,"\n") ;
02187       if( cpt != NULL ) ncol = cpt-label ;  /* 01 Nov 2001 */
02188    }
02189 
02190    if( default_string != NULL && default_string[0] != '\0' ){
02191       int qq = strlen(default_string) ;
02192       if( qq > ncol ) ncol = qq ;
02193    }
02194    if( ncol < AV_NCOL ) ncol = AV_NCOL ;
02195 
02196    wtf = XtVaCreateManagedWidget(
02197              "menu" , TEXT_CLASS , wrc ,
02198 
02199                  XmNcolumns         , ncol ,
02200                  XmNeditable        , True ,
02201                  XmNmaxLength       , ncol+64 ,
02202                  XmNresizeWidth     , False ,
02203 
02204                  XmNmarginHeight    , 1 ,
02205                  XmNmarginWidth     , 1 ,
02206 
02207                  XmNcursorPositionVisible , True ,
02208                  XmNblinkRate , 0 ,
02209                  XmNautoShowCursorPosition , True ,
02210 
02211                  XmNinitialResourcesPersistent , False ,
02212                  XmNtraversalOn , False ,
02213               NULL ) ;
02214 
02215    if( default_string != NULL && default_string[0] != '\0' ){
02216       int qq  = strlen(default_string) , ii ;
02217       for( ii=0 ; ii < qq ; ii++ ) if( default_string[ii] != ' ' ) break ;
02218       if( ii < qq ) TEXT_SET( wtf , default_string ) ;
02219    }
02220 
02221    cd.wpop    = wpop ;  /* data to be passed to pushbutton callback */
02222    cd.wcaller = wpar ;
02223    cd.wchoice = wtf ;
02224    cd.sel_CB  = func ;
02225    cd.sel_cd  = func_data ;
02226    cd.ctype   = mcwCT_string ;
02227 
02228    XtAddCallback( wtf, XmNactivateCallback, MCW_choose_CB, &cd ) ; /* return key */
02229 
02230    for( ib=0 ; ib < NUM_CLR_ACT ; ib++ ) OVC_act[ib].data = &cd ;
02231 
02232    (void) MCW_action_area( wrc , OVC_act , NUM_CLR_ACT ) ;
02233 
02234    XtTranslateCoords( wpar , 15,15 , &xx , &yy ) ;
02235    XtVaSetValues( wpop , XmNx , (int) xx , XmNy , (int) yy , NULL ) ;
02236 
02237    XtManageChild( wrc ) ;
02238    XtPopup( wpop , XtGrabNone ) ;
02239 
02240    RWC_visibilize_widget( wpop ) ;   /* 09 Nov 1999 */
02241    NORMAL_cursorize( wpop ) ;
02242 
02243    EXRETURN ;
02244 }
02245 
02246 /*-------------------------------------------------------------------------*/
02247 
02248 static int list_max = -1 , list_maxmax ;
02249 
02250 static void MCW_set_listmax( Widget wpar )
02251 {
02252    if( list_max < 0 ){
02253 #if 0
02254       char * xdef = XGetDefault( XtDisplay(wpar) , "AFNI" , "chooser_listmax" ) ;
02255 #else
02256       char * xdef = RWC_getname( XtDisplay(wpar) , "chooser_listmax" ) ;
02257 #endif
02258       if( xdef == NULL ) xdef = getenv("AFNI_MENU_COLSIZE") ;  /* 11 Dec 2001 */
02259       if( xdef != NULL )  list_max = strtol( xdef , NULL , 10 ) ;
02260       if( list_max <= 4 ) list_max = LIST_MAX ;
02261       list_maxmax = list_max + 5 ;
02262    }
02263    return ;
02264 }
02265 
02266 /*-------------------------------------------------------------------------
02267    Get an integer, as an index to an array of strings:
02268      pops up a shell to let the user make the selection, cycling through
02269      the string array
02270 
02271      wpar         = parent widget (where to popup)
02272      label        = label for chooser
02273      num_str      = number of strings
02274      init         = index of initial string
02275      strlist      = array of char *, pointing to strings
02276      func         = routine to call when a selection is made:
02277             void func( Widget wpar,XtPointer func_data,MCW_choose_cbs * cbs )
02278      func_data    = data to pass to func
02279 
02280      The "ival" stored in the MCW_choose_cbs will be the desired result
02281        (from 0 to num_str-1).
02282 
02283    This routine is coded in such a way that only one chooser will be
02284    active at a time (per application).  This is a deliberate choice.
02285 ---------------------------------------------------------------------------*/
02286 
02287 void MCW_choose_strlist( Widget wpar , char * label ,
02288                          int num_str , int init , char * strlist[] ,
02289                          gen_func * func , XtPointer func_data )
02290 {
02291    int initar[2] ;
02292    initar[0] = init ;
02293    initar[1] = -666 ;
02294 
02295    MCW_choose_multi_strlist( wpar , label , mcwCT_single_mode ,
02296                              num_str , initar , strlist , func , func_data ) ;
02297    return ;
02298 }
02299 
02300 void MCW_choose_multi_strlist( Widget wpar , char * label , int mode ,
02301                                int num_str , int * init , char * strlist[] ,
02302                                gen_func * func , XtPointer func_data )
02303 {
02304    static Widget wpop = NULL , wrc ;
02305    static MCW_choose_data cd ;
02306    Position xx,yy ;
02307    int ib , ll , ltop ;
02308    Widget wlist = NULL , wlab ;
02309    XmStringTable xmstr ;
02310    XmString xms ;
02311    char * lbuf ;
02312    int nvisible ;
02313 
02314 ENTRY("MCW_choose_multi_strlist") ;
02315 
02316    /** destructor callback **/
02317 
02318    if( wpar == NULL ){
02319       if( wpop != NULL ){
02320          XtUnmapWidget( wpop ) ;
02321          XtRemoveCallback( wpop, XmNdestroyCallback, MCW_destroy_chooser_CB, &wpop ) ;
02322          XtDestroyWidget( wpop ) ;
02323       }
02324       STATUS("destroying chooser") ;
02325       wpop = NULL ; EXRETURN ;
02326    }
02327 
02328    if( ! XtIsRealized(wpar) ){  /* illegal call */
02329       fprintf(stderr,"\n*** illegal call to MCW_choose_strlist %s\n",
02330               XtName(wpar) ) ;
02331       EXRETURN ;
02332    }
02333 
02334    MCW_set_listmax( wpar ) ;
02335 
02336    /*--- if popup widget already exists, destroy it ---*/
02337 
02338    if( wpop != NULL ){
02339       XtRemoveCallback( wpop, XmNdestroyCallback, MCW_destroy_chooser_CB, &wpop ) ;
02340       XtDestroyWidget( wpop ) ;
02341    }
02342 
02343    wlist = NULL ;
02344 
02345    /*--- create popup widget ---*/
02346 
02347    wpop = XtVaCreatePopupShell(                           /* Popup Shell */
02348              "menu" , xmDialogShellWidgetClass , wpar ,
02349                 XmNtraversalOn , False ,
02350                 XmNinitialResourcesPersistent , False ,
02351              NULL ) ;
02352 
02353    if( MCW_isitmwm(wpar) ){
02354       XtVaSetValues( wpop ,
02355                         XmNmwmDecorations ,  MWM_DECOR_BORDER ,
02356                         XmNmwmFunctions   ,  MWM_FUNC_MOVE
02357                                            | MWM_FUNC_CLOSE ,
02358                      NULL ) ;
02359    }
02360 
02361    XtAddCallback( wpop , XmNdestroyCallback , MCW_destroy_chooser_CB , &wpop ) ;
02362 
02363    XmAddWMProtocolCallback(
02364         wpop ,
02365         XmInternAtom( XtDisplay(wpop) , "WM_DELETE_WINDOW" , False ) ,
02366         MCW_kill_chooser_CB , wpop ) ;
02367 
02368    wrc  = XtVaCreateWidget(                 /* RowColumn to hold all */
02369              "menu" , xmRowColumnWidgetClass , wpop ,
02370                 XmNpacking     , XmPACK_TIGHT ,
02371                 XmNorientation , XmVERTICAL ,
02372                 XmNtraversalOn , False ,
02373                 XmNinitialResourcesPersistent , False ,
02374              NULL ) ;
02375 
02376    if( label != NULL && label[0] != '\0' ){
02377       lbuf = (char*)XtMalloc( strlen(label) + 32 ) ;
02378       sprintf( lbuf , "----Choose %s----\n%s" ,
02379                (mode == mcwCT_single_mode) ? "One" : "One or More" , label ) ;
02380    } else {
02381       lbuf = (char*)XtMalloc( 32 ) ;
02382       sprintf( lbuf , "----Choose %s----",
02383                (mode == mcwCT_single_mode) ? "One" : "One or More" ) ;
02384    }
02385    xms = XmStringCreateLtoR( lbuf , XmFONTLIST_DEFAULT_TAG ) ;
02386    wlab = XtVaCreateManagedWidget(
02387                 "menu" , xmLabelWidgetClass , wrc ,
02388                    XmNlabelString   , xms  ,
02389                    XmNalignment     , XmALIGNMENT_CENTER ,
02390                    XmNinitialResourcesPersistent , False ,
02391                 NULL ) ;
02392    myXtFree(lbuf) ; XmStringFree(xms) ;
02393 
02394    (void) XtVaCreateManagedWidget(
02395             "menu" , xmSeparatorWidgetClass , wrc ,
02396                 XmNseparatorType , XmSHADOW_ETCHED_IN ,
02397                 XmNinitialResourcesPersistent , False ,
02398             NULL ) ;
02399 
02400    xmstr = (XmStringTable) XtMalloc( num_str * sizeof(XmString *) ) ;
02401    for( ib=0 ; ib < num_str ; ib++ )
02402       xmstr[ib] = XmStringCreateSimple(strlist[ib]) ;
02403 
02404    wlist = XmCreateScrolledList( wrc , "menu" , NULL , 0 ) ;
02405 
02406    nvisible = (num_str < list_maxmax ) ? num_str : list_max ;
02407    XtVaSetValues( wlist ,
02408                     XmNitems            , xmstr ,
02409                     XmNitemCount        , num_str ,
02410                     XmNvisibleItemCount , nvisible ,
02411                     XmNtraversalOn      , True ,
02412                     XmNselectionPolicy  , (mode == mcwCT_single_mode)
02413                                           ? XmSINGLE_SELECT : XmMULTIPLE_SELECT ,
02414                   NULL ) ;
02415 
02416    if( init != NULL ){
02417       for( ib=0 ; init[ib] >= 0 && init[ib] < num_str ; ib++ ){
02418          XmListSelectPos( wlist , init[ib]+1 , False ) ;
02419       }
02420       if( ib > 0 && init[ib-1] > nvisible )
02421          XmListSetBottomPos( wlist , init[ib-1]+1 ) ;
02422    }
02423 
02424    XtManageChild(wlist) ;
02425 
02426    if( mode == mcwCT_multi_mode ){
02427       MCW_register_help( wlist , OVC_list_help_2 ) ;
02428       MCW_register_help( wlab  , OVC_list_help_2 ) ;
02429    } else {
02430       MCW_register_help( wlist , OVC_list_help_1 ) ;
02431       MCW_register_help( wlab  , OVC_list_help_1 ) ;
02432       XtAddCallback( wlist , XmNdefaultActionCallback , MCW_choose_CB , &cd ) ;
02433    }
02434 
02435    cd.wchoice = wlist ;
02436    cd.av      = NULL ;   /* this is NULL --> will use the list widget */
02437 
02438    for( ib=0 ; ib < num_str ; ib++ ) XmStringFree(xmstr[ib]) ;
02439    myXtFree(xmstr) ;
02440 
02441    cd.wpop    = wpop ;  /* data to be passed to pushbutton callback */
02442    cd.wcaller = wpar ;
02443    cd.sel_CB  = func ;
02444    cd.sel_cd  = func_data ;
02445    cd.ctype   = mcwCT_integer ;
02446 
02447    for( ib=0 ; ib < NUM_OVC_ACT ; ib++ ) OVC_act[ib].data = &cd ;
02448 
02449    (void) MCW_action_area( wrc , OVC_act , NUM_OVC_ACT ) ;
02450 
02451    if( mode == mcwCT_multi_mode ){
02452       MCW_arrowval * av ;
02453 
02454       (void) XtVaCreateManagedWidget(
02455                "menu" , xmSeparatorWidgetClass , wrc ,
02456                    XmNseparatorType , XmSHADOW_ETCHED_IN ,
02457                    XmNinitialResourcesPersistent , False ,
02458                NULL ) ;
02459 
02460       av = new_MCW_optmenu( wrc , "Selection Mode" , 0,NUM_LIST_MODES-1,0,0 ,
02461                             MCW_list_mode_CB , wlist ,
02462                             MCW_av_substring_CB , list_modes ) ;
02463 
02464       MCW_reghelp_children( av->wrowcol , OVC_list_help_2 ) ;
02465       MCW_reghint_children( av->wrowcol , "How list selections work" ) ;
02466    }
02467 
02468    XtTranslateCoords( wpar , 15,15 , &xx , &yy ) ;
02469    XtVaSetValues( wpop , XmNx , (int) xx , XmNy , (int) yy , NULL ) ;
02470 
02471    XtManageChild( wrc ) ;
02472    XtPopup( wpop , XtGrabNone ) ;
02473 
02474    RWC_visibilize_widget( wpop ) ;   /* 09 Nov 1999 */
02475    NORMAL_cursorize( wpop ) ;
02476 
02477    EXRETURN ;
02478 }
02479 
02480 void MCW_list_mode_CB( MCW_arrowval * av , XtPointer cd )
02481 {
02482    Widget wlist = (Widget) cd ;
02483 
02484    if( av == NULL || wlist == NULL ) return ;
02485 
02486    XtVaSetValues( wlist ,
02487                      XmNselectionPolicy ,
02488                      (av->ival == 0) ? XmMULTIPLE_SELECT
02489                                      : XmEXTENDED_SELECT ,
02490                   NULL ) ;
02491 }
02492 
02493 /*==================================================================================*/
02494 
02495 #define TSC_quit_label   "Quit"
02496 #define TSC_plot_label   "Plot"
02497 #define TSC_apply_label  "Apply"
02498 #define TSC_done_label   "Set"
02499 
02500 #define TSC_quit_help   "Press to close\nthis `chooser'"
02501 #define TSC_plot_help   "Press to popup\na graph of the\nselected time series"
02502 #define TSC_apply_help  "Press to apply\nthis choice and\nkeep this `chooser'"
02503 #define TSC_done_help   "Press to apply\nthis choice and\nclose this `chooser'"
02504 
02505 #define TSC_list_help_1  OVC_list_help_1
02506 
02507 #define NUM_TSC_ACT 4
02508 
02509 #undef DONT_USE_COXPLOT  /* for the long-delayed Plot option */
02510 
02511 #undef PCODE
02512 #ifdef DONT_USE_COXPLOT
02513 # define PCODE -1
02514 #else
02515 # define PCODE  0
02516 # include "coxplot.h"
02517 #endif
02518 
02519 static MCW_action_item TSC_act[] = {
02520  { TSC_quit_label , MCW_choose_CB, NULL, TSC_quit_help ,"Close window"              , 0 },
02521  { TSC_plot_label , MCW_choose_CB, NULL, TSC_plot_help ,"Plot data"                 , PCODE },
02522  { TSC_apply_label, MCW_choose_CB, NULL, TSC_apply_help,"Apply choice, keep window" , 0 },
02523  { TSC_done_label , MCW_choose_CB, NULL, TSC_done_help ,"Apply choice, close window", 1 }
02524 } ;
02525 
02526 #undef PCODE
02527 
02528 /*-------------------------------------------------------------------------
02529    Get a time series (1D MRI_IMAGE *) from an array of such things:
02530      pops up a shell to let the user make the selection, with a list
02531      of time series name
02532 
02533      wpar         = parent widget (where to popup)
02534      label        = label for chooser
02535      tsarr        = array of time series (1D images)
02536      init         = index of initial time series to select
02537      func         = routine to call when choice is made
02538             void func( Widget wpar,XtPointer func_data,MCW_choose_cbs * cbs )
02539      func_data    = data to pass to func
02540 
02541      The "ival" stored in the MCW_choose_cbs will the the index of the
02542        chosen timeseries in tsarr.  The "imval" be the pointer to the
02543        chosen timeseries itself.  Do NOT mri_free this, since it will just be a
02544        pointer to the correct entry in tsarr (which should not be modified
02545        by any other code during the lifetime of this popup!).
02546 
02547    This routine is coded in such a way that only one chooser will be
02548    active at a time (per application).  This is a deliberate choice.
02549 ---------------------------------------------------------------------------*/
02550 
02551 void MCW_choose_timeseries( Widget wpar , char *label ,
02552                             MRI_IMARR *tsarr , int init ,
02553                             gen_func *func , XtPointer func_data )
02554 {
02555    static Widget wpop = NULL , wrc ;
02556    static MCW_choose_data cd ;
02557    Position xx,yy ;
02558    int ib , ll , ltop , num_ts , nvisible , xd,yd ;
02559    Widget wlist = NULL , wlab ;
02560    XmStringTable xmstr ;
02561    XmString xms ;
02562    char *lbuf ;
02563    char pbuf[256] , qbuf[512] ;
02564    MRI_IMAGE *tsim ;
02565 
02566 ENTRY("MCW_choose_timeseries") ;
02567 
02568    /** destructor callback **/
02569 
02570    if( wpar == NULL ){
02571      if( wpop != NULL ){
02572 STATUS("popdown call") ;
02573        XtUnmapWidget( wpop ) ;
02574        XtRemoveCallback( wpop, XmNdestroyCallback, MCW_destroy_chooser_CB, &wpop ) ;
02575        XtDestroyWidget( wpop ) ;
02576      }
02577      wpop = NULL ; EXRETURN ;
02578    }
02579 
02580    if( ! XtIsRealized(wpar) ){  /* illegal call */
02581      fprintf(stderr,"\n*** illegal call to MCW_choose_timeseries %s\n",
02582              XtName(wpar) ) ;
02583      EXRETURN ;
02584    }
02585 
02586    MCW_set_listmax( wpar ) ;
02587 
02588    /*--- if popup widget already exists, destroy it ---*/
02589 
02590    if( wpop != NULL ){
02591 STATUS("destroying old widget") ;
02592      XtRemoveCallback( wpop, XmNdestroyCallback, MCW_destroy_chooser_CB, &wpop ) ;
02593      XtDestroyWidget( wpop ) ;
02594    }
02595 
02596    wlist = NULL ;
02597 
02598    /*--- sanity checks ---*/
02599 
02600    if( tsarr == NULL || tsarr->num == 0 ) EXRETURN ;
02601    num_ts = tsarr->num ;
02602 
02603 if(PRINT_TRACING){
02604  char str[256]; sprintf(str,"creation with %d choices",num_ts); STATUS(str);
02605 }
02606 
02607    /*--- create popup widget ---*/
02608 
02609    wpop = XtVaCreatePopupShell(                           /* Popup Shell */
02610              "menu" , xmDialogShellWidgetClass , wpar ,
02611                 XmNtraversalOn , False ,
02612                 XmNinitialResourcesPersistent , False ,
02613              NULL ) ;
02614 
02615    if( MCW_isitmwm(wpar) ){
02616      XtVaSetValues( wpop ,
02617                       XmNmwmDecorations ,  MWM_DECOR_BORDER ,
02618                       XmNmwmFunctions   ,  MWM_FUNC_MOVE
02619                                          | MWM_FUNC_CLOSE ,
02620                     NULL ) ;
02621    }
02622 
02623    XtAddCallback( wpop , XmNdestroyCallback , MCW_destroy_chooser_CB , &wpop ) ;
02624 
02625    XmAddWMProtocolCallback(
02626         wpop ,
02627         XmInternAtom( XtDisplay(wpop) , "WM_DELETE_WINDOW" , False ) ,
02628         MCW_kill_chooser_CB , wpop ) ;
02629 
02630    wrc  = XtVaCreateWidget(                 /* RowColumn to hold all */
02631              "menu" , xmRowColumnWidgetClass , wpop ,
02632                 XmNpacking     , XmPACK_TIGHT ,
02633                 XmNorientation , XmVERTICAL ,
02634                 XmNtraversalOn , False ,
02635                 XmNinitialResourcesPersistent , False ,
02636              NULL ) ;
02637 
02638    if( label != NULL ){
02639      lbuf = (char*)XtMalloc( strlen(label) + 32 ) ;
02640      sprintf( lbuf , "----Choose One----\n%s" , label ) ;
02641    } else {
02642      lbuf = (char*)XtMalloc( 32 ) ;
02643      sprintf( lbuf , "----Choose One----" ) ;
02644    }
02645    xms = XmStringCreateLtoR( lbuf , XmFONTLIST_DEFAULT_TAG ) ;
02646    wlab = XtVaCreateManagedWidget(
02647                 "menu" , xmLabelWidgetClass , wrc ,
02648                    XmNlabelString   , xms  ,
02649                    XmNalignment     , XmALIGNMENT_CENTER ,
02650                    XmNinitialResourcesPersistent , False ,
02651                 NULL ) ;
02652    myXtFree(lbuf) ; XmStringFree(xms) ;
02653 
02654    (void) XtVaCreateManagedWidget(
02655             "menu" , xmSeparatorWidgetClass , wrc ,
02656                 XmNseparatorType , XmSHADOW_ETCHED_IN ,
02657                 XmNinitialResourcesPersistent , False ,
02658             NULL ) ;
02659 
02660    xmstr = (XmStringTable) XtMalloc( num_ts * sizeof(XmString *) ) ;
02661 
02662    xd = yd = ltop = 1 ;
02663    for( ib=0 ; ib < num_ts ; ib++ ){
02664      tsim = IMARR_SUBIMAGE(tsarr,ib) ;
02665      if( tsim == NULL ){
02666        strcpy(pbuf,"** NULL series ??") ;
02667      } else {
02668        if( tsim->name != NULL )
02669          MCW_strncpy(pbuf,IMARR_SUBIMAGE(tsarr,ib)->name,254) ;
02670        else
02671          strcpy(pbuf,"** NO NAME ??") ;
02672 
02673        sprintf(qbuf,"%d",tsim->nx) ; ll = strlen(qbuf) ; xd = MAX(xd,ll) ;
02674        sprintf(qbuf,"%d",tsim->ny) ; ll = strlen(qbuf) ; yd = MAX(yd,ll) ;
02675      }
02676      ll = strlen(pbuf) ; ltop = MAX(ltop,ll) ;
02677    }
02678 
02679    for( ib=0 ; ib < num_ts ; ib++ ){
02680      tsim = IMARR_SUBIMAGE(tsarr,ib) ;
02681      if( tsim == NULL ){
02682        strcpy(qbuf,"** NULL series ??") ;
02683      } else {
02684        if( tsim->name != NULL )
02685          MCW_strncpy(pbuf,IMARR_SUBIMAGE(tsarr,ib)->name,254) ;
02686        else
02687          strcpy(pbuf,"** NO NAME ??") ;
02688 
02689         sprintf(qbuf,"%-*s [%*d x %*d]", ltop,pbuf , xd,tsim->nx , yd,tsim->ny ) ;
02690       }
02691       xmstr[ib] = XmStringCreateSimple( qbuf ) ;
02692    }
02693 
02694    wlist = XmCreateScrolledList( wrc , "menu" , NULL , 0 ) ;
02695 
02696    nvisible = (num_ts < list_maxmax ) ? num_ts : list_max ;
02697    XtVaSetValues( wlist ,
02698                     XmNitems            , xmstr ,
02699                     XmNitemCount        , num_ts ,
02700                     XmNvisibleItemCount , nvisible ,
02701                     XmNtraversalOn      , True ,
02702                     XmNselectionPolicy  , XmSINGLE_SELECT ,
02703                   NULL ) ;
02704    if( init >= 0 && init < num_ts ){
02705      XmListSelectPos( wlist , init+1 , False ) ;
02706      if( init+1 > nvisible ) XmListSetBottomPos( wlist , init+1 ) ;
02707    }
02708    XtManageChild(wlist) ;
02709 
02710    XtAddCallback( wlist , XmNdefaultActionCallback , MCW_choose_CB , &cd ) ;
02711 
02712    MCW_register_help( wlist , TSC_list_help_1 ) ;
02713    MCW_register_help( wlab  , TSC_list_help_1 ) ;
02714 
02715    cd.tsarr   = tsarr ;
02716    cd.wchoice = wlist ;
02717    cd.av      = NULL ;
02718 
02719 #if 1
02720    for( ib=0 ; ib < num_ts ; ib++ ) XmStringFree(xmstr[ib]) ;
02721    myXtFree(xmstr) ;
02722 #endif
02723 
02724    cd.wpop    = wpop ;  /* data to be passed to pushbutton callback */
02725    cd.wcaller = wpar ;
02726    cd.sel_CB  = func ;
02727    cd.sel_cd  = func_data ;
02728    cd.ctype   = mcwCT_timeseries ;
02729 
02730    for( ib=0 ; ib < NUM_TSC_ACT ; ib++ ) TSC_act[ib].data = &cd ;
02731 
02732    (void) MCW_action_area( wrc , TSC_act , NUM_TSC_ACT ) ;
02733 
02734    XtTranslateCoords( wpar , 15,15 , &xx , &yy ) ;
02735    XtVaSetValues( wpop , XmNx , (int) xx , XmNy , (int) yy , NULL ) ;
02736 
02737    XtManageChild( wrc ) ;
02738    XtPopup( wpop , XtGrabNone ) ;
02739 
02740    RWC_visibilize_widget( wpop ) ;   /* 09 Nov 1999 */
02741    NORMAL_cursorize( wpop ) ;
02742 
02743    EXRETURN ;
02744 }
02745 
02746 /*-------------------------------------------------------------------------
02747    Get an integer, as an index to an array of strings:
02748    * pops up a shell to let the user make the selection, cycling through
02749      the string array
02750    * allows the user to add to the string array
02751 
02752      wpar         = parent widget (where to popup)
02753      label        = label for chooser
02754      sar          = array of initial strings (see 3ddata.h)
02755                     [may be changed by the user during operations]
02756      init         = index of initial string
02757      func         = routine to call when a selection is made:
02758             void func( Widget wpar,XtPointer func_data,MCW_choose_cbs * cbs )
02759      func_data    = data to pass to func
02760 
02761      The "ival" stored in the MCW_choose_cbs will be the desired result.
02762 
02763    This routine is coded in such a way that only one chooser will be
02764    active at a time (per application).  This is a deliberate choice.
02765 ---------------------------------------------------------------------------*/
02766 
02767 void MCW_choose_editable_strlist( Widget wpar , char * label ,
02768                                   THD_string_array * sar ,
02769                                   int init , gen_func * func , XtPointer func_data )
02770 {
02771    int initar[2] ;
02772    initar[0] = init ;
02773    initar[1] = -666 ;
02774 
02775    MCW_choose_multi_editable_strlist( wpar , label , mcwCT_single_mode ,
02776                                       sar , initar , func , func_data ) ;
02777    return ;
02778 }
02779 
02780 void MCW_choose_multi_editable_strlist( Widget wpar , char * label , int mode ,
02781                                         THD_string_array * sar ,
02782                                         int * init ,
02783                                         gen_func * func , XtPointer func_data )
02784 {
02785    static Widget wpop = NULL , wrc , wrc2 ;
02786    static MCW_choose_data cd ;
02787    Position xx,yy ;
02788    int ib , ll , ltop , num_str ;
02789    Widget wlist = NULL , wlab , wtf , wadd ;
02790    XmStringTable xmstr ;
02791    XmString xms ;
02792    char * lbuf ;
02793    int nvisible ;
02794 
02795 ENTRY("MCW_choose_multi_editable_strlist") ;
02796 
02797    /** destructor callback **/
02798 
02799    if( wpar == NULL ){
02800       if( wpop != NULL ){
02801          XtUnmapWidget( wpop ) ;
02802          XtRemoveCallback( wpop, XmNdestroyCallback, MCW_destroy_chooser_CB, &wpop ) ;
02803          XtDestroyWidget( wpop ) ;
02804       }
02805       wpop = NULL ; EXRETURN ;
02806    }
02807 
02808    if( ! XtIsRealized(wpar) ){  /* illegal call */
02809       fprintf(stderr,"\n*** illegal call to MCW_choose_strlist %s\n",
02810               XtName(wpar) ) ;
02811       EXRETURN ;
02812    }
02813 
02814    MCW_set_listmax( wpar ) ;
02815 
02816    /*--- if popup widget already exists, destroy it ---*/
02817 
02818    if( wpop != NULL ){
02819       XtRemoveCallback( wpop, XmNdestroyCallback, MCW_destroy_chooser_CB, &wpop ) ;
02820       XtDestroyWidget( wpop ) ;
02821    }
02822 
02823    wlist = NULL ;
02824 
02825    /*--- create popup widget ---*/
02826 
02827    wpop = XtVaCreatePopupShell(                           /* Popup Shell */
02828              "menu" , xmDialogShellWidgetClass , wpar ,
02829                 XmNallowShellResize , True ,
02830                 XmNtraversalOn , False ,
02831                 XmNinitialResourcesPersistent , False ,
02832              NULL ) ;
02833 
02834    if( MCW_isitmwm(wpar) ){
02835       XtVaSetValues( wpop ,
02836                         XmNmwmDecorations ,  MWM_DECOR_BORDER ,
02837                         XmNmwmFunctions   ,  MWM_FUNC_MOVE
02838                                            | MWM_FUNC_CLOSE ,
02839                      NULL ) ;
02840    }
02841 
02842    XtAddCallback( wpop , XmNdestroyCallback , MCW_destroy_chooser_CB , &wpop ) ;
02843 
02844    XmAddWMProtocolCallback(
02845         wpop ,
02846         XmInternAtom( XtDisplay(wpop) , "WM_DELETE_WINDOW" , False ) ,
02847         MCW_kill_chooser_CB , wpop ) ;
02848 
02849    /* RowColumn to hold all */
02850 
02851    wrc  = XtVaCreateWidget(
02852              "menu" , xmRowColumnWidgetClass , wpop ,
02853                 XmNpacking     , XmPACK_TIGHT ,
02854                 XmNorientation , XmVERTICAL ,
02855                 XmNtraversalOn , False ,
02856                 XmNinitialResourcesPersistent , False ,
02857              NULL ) ;
02858 
02859    /* Label at the top */
02860 
02861    if( label != NULL ){
02862       lbuf = (char*)XtMalloc( strlen(label) + 32 ) ;
02863       sprintf( lbuf , "----Choose %s----\n%s" ,
02864                (mode == mcwCT_single_mode) ? "One" : "One or More" , label ) ;
02865    } else {
02866       lbuf = (char*)XtMalloc( 32 ) ;
02867       sprintf( lbuf , "----Choose %s----",
02868                (mode == mcwCT_single_mode) ? "One" : "One or More" ) ;
02869    }
02870    xms = XmStringCreateLtoR( lbuf , XmFONTLIST_DEFAULT_TAG ) ;
02871    wlab = XtVaCreateManagedWidget(
02872                 "menu" , xmLabelWidgetClass , wrc ,
02873                    XmNlabelString   , xms  ,
02874                    XmNalignment     , XmALIGNMENT_CENTER ,
02875                    XmNinitialResourcesPersistent , False ,
02876                 NULL ) ;
02877    myXtFree(lbuf) ; XmStringFree(xms) ;
02878 
02879    /* Separator line */
02880 
02881    (void) XtVaCreateManagedWidget(
02882             "menu" , xmSeparatorWidgetClass , wrc ,
02883                 XmNseparatorType , XmSHADOW_ETCHED_IN ,
02884                 XmNinitialResourcesPersistent , False ,
02885             NULL ) ;
02886 
02887    /* List to choose from */
02888 
02889    wlist = XmCreateScrolledList( wrc , "menu" , NULL , 0 ) ;
02890    XtVaSetValues( wlist ,
02891                     XmNtraversalOn      , True ,
02892                     XmNselectionPolicy  , (mode == mcwCT_single_mode)
02893                                           ? XmSINGLE_SELECT : XmMULTIPLE_SELECT ,
02894                   NULL ) ;
02895 
02896    num_str = SARR_NUM(sar) ;
02897 
02898    if( num_str > 0 ){
02899       xmstr = (XmStringTable) XtMalloc( num_str * sizeof(XmString *) ) ;
02900       for( ib=0 ; ib < num_str ; ib++ )
02901          xmstr[ib] = XmStringCreateSimple( SARR_STRING(sar,ib) ) ;
02902 
02903       nvisible = (num_str < list_maxmax ) ? num_str : list_max ;
02904       XtVaSetValues( wlist ,
02905                        XmNitems            , xmstr ,
02906                        XmNitemCount        , num_str ,
02907                        XmNvisibleItemCount , nvisible ,
02908                      NULL ) ;
02909 
02910       if( init != NULL ){
02911          for( ib=0 ; init[ib] >= 0 && init[ib] < num_str ; ib++ ){
02912             XmListSelectPos( wlist , init[ib]+1 , False ) ;
02913          }
02914          if( ib > 0 && init[ib-1] > nvisible )
02915             XmListSetBottomPos( wlist , init[ib-1]+1 ) ;
02916       }
02917 
02918       for( ib=0 ; ib < num_str ; ib++ ) XmStringFree(xmstr[ib]) ;
02919       myXtFree(xmstr) ;
02920    }
02921 
02922    XtManageChild(wlist) ;
02923 
02924    /* Some help? */
02925 
02926    if( mode == mcwCT_multi_mode ){
02927       MCW_register_help( wlist , OVC_list_help_2 ) ;
02928       MCW_register_help( wlab  , OVC_list_help_2 ) ;
02929    } else {
02930       MCW_register_help( wlist , OVC_list_help_1 ) ;
02931       MCW_register_help( wlab  , OVC_list_help_1 ) ;
02932       XtAddCallback( wlist , XmNdefaultActionCallback , MCW_choose_CB , &cd ) ;
02933    }
02934 
02935    cd.wchoice = wlist ;
02936    cd.av      = NULL ;   /* this is NULL --> will use the list widget */
02937 
02938    cd.wpop    = wpop ;  /* data to be passed to pushbutton callback */
02939    cd.wcaller = wpar ;
02940    cd.sel_CB  = func ;
02941    cd.sel_cd  = func_data ;
02942    cd.ctype   = mcwCT_integer ;
02943    cd.sar     = sar ;
02944 
02945    /* action buttons */
02946 
02947    for( ib=0 ; ib < NUM_OVC_ACT ; ib++ ) OVC_act[ib].data = &cd ;
02948 
02949    (void) MCW_action_area( wrc , OVC_act , NUM_OVC_ACT ) ;
02950 
02951    /* choosing mode, for multiple selections */
02952 
02953    if( mode == mcwCT_multi_mode ){
02954       MCW_arrowval * av ;
02955 
02956       (void) XtVaCreateManagedWidget(
02957                "menu" , xmSeparatorWidgetClass , wrc ,
02958                    XmNseparatorType , XmSHADOW_ETCHED_IN ,
02959                    XmNinitialResourcesPersistent , False ,
02960                NULL ) ;
02961 
02962       av = new_MCW_optmenu( wrc , "Selection Mode" , 0,NUM_LIST_MODES-1,0,0 ,
02963                             MCW_list_mode_CB , wlist ,
02964                             MCW_av_substring_CB , list_modes ) ;
02965 
02966       MCW_reghelp_children( av->wrowcol , OVC_list_help_2 ) ;
02967       MCW_reghint_children( av->wrowcol , "How list selections work" ) ;
02968    }
02969 
02970    /* Separator line */
02971 
02972    (void) XtVaCreateManagedWidget(
02973             "menu" , xmSeparatorWidgetClass , wrc ,
02974                 XmNseparatorType , XmSINGLE_LINE ,
02975                 XmNinitialResourcesPersistent , False ,
02976             NULL ) ;
02977 
02978    /*-- Stuff to string array --*/
02979 
02980    wrc2 = XtVaCreateWidget(                            /* Rowcol for stuff */
02981              "menu" , xmRowColumnWidgetClass , wrc ,
02982                 XmNpacking      , XmPACK_TIGHT ,
02983                 XmNorientation  , XmHORIZONTAL ,
02984                 XmNtraversalOn , False ,
02985                 XmNinitialResourcesPersistent , False ,
02986              NULL ) ;
02987 
02988    wtf = XtVaCreateManagedWidget(                      /* String to add */
02989              "menu" , TEXT_CLASS , wrc2 ,
02990 
02991                  XmNcolumns         , 24 ,
02992                  XmNeditable        , True ,
02993                  XmNmaxLength       , 128 ,
02994                  XmNresizeWidth     , False ,
02995 
02996                  XmNmarginHeight    , 1 ,
02997                  XmNmarginWidth     , 1 ,
02998 
02999                  XmNcursorPositionVisible , True ,
03000                  XmNblinkRate , 0 ,
03001                  XmNautoShowCursorPosition , True ,
03002 
03003                  XmNinitialResourcesPersistent , False ,
03004                  XmNtraversalOn , False ,
03005               NULL ) ;
03006 
03007    xms = XmStringCreateLtoR( "Add" , XmFONTLIST_DEFAULT_TAG ) ;
03008 
03009    wadd = XtVaCreateManagedWidget(                     /* Button to add it */
03010              "menu" , xmPushButtonWidgetClass , wrc2 ,
03011                 XmNlabelString  , xms ,
03012                 XmNtraversalOn , False ,
03013                 XmNinitialResourcesPersistent , False ,
03014              NULL ) ;
03015 
03016    XmStringFree(xms) ;
03017 
03018    MCW_set_widget_bg( wadd , MCW_hotcolor(wadd) , 0 ) ;
03019 
03020    XtAddCallback( wadd, XmNactivateCallback, MCW_stradd_CB, &cd ) ;
03021    XtAddCallback( wtf , XmNactivateCallback, MCW_stradd_CB, &cd ) ;
03022    cd.wtf = wtf ;
03023 
03024    MCW_reghelp_children( wrc2 , "Type an entry and press Add\n"
03025                                 "or hit Enter to make a new\n"
03026                                 "entry in the chooser list."   ) ;
03027 
03028    MCW_reghint_children( wrc2 , "Enter new item into chooser list" ) ;
03029 
03030    XtManageChild( wrc2 ) ;
03031 
03032    /* make it appear, like magic! */
03033 
03034    XtTranslateCoords( wpar , 15,15 , &xx , &yy ) ;
03035    XtVaSetValues( wpop , XmNx , (int) xx , XmNy , (int) yy , NULL ) ;
03036 
03037    XtManageChild( wrc ) ;
03038    XtPopup( wpop , XtGrabNone ) ;
03039 
03040    RWC_visibilize_widget( wpop ) ;   /* 09 Nov 1999 */
03041    NORMAL_cursorize( wpop ) ;
03042 
03043    EXRETURN ;
03044 }
03045 
03046 /*--------------------------------------------------------------------------*/
03047 
03048 void MCW_stradd_CB( Widget w, XtPointer client_data, XtPointer call_data )
03049 {
03050    MCW_choose_data * cd = (MCW_choose_data *) client_data ;
03051    char *nstr = TEXT_GET( cd->wtf ) ;
03052    int id , nvisible , num_str ;
03053    XmString xms ;
03054 
03055 ENTRY("MCW_stradd_CB") ;
03056 
03057    if( nstr == NULL || strlen(nstr) == 0 ){
03058      myXtFree(nstr); XBell(XtDisplay(w),100); EXRETURN;
03059    }
03060 
03061    /* see if new string is already in the list */
03062 
03063    for( id=0 ; id < SARR_NUM(cd->sar) ; id++ )
03064       if( strcmp(nstr,SARR_STRING(cd->sar,id)) == 0 ) break ;
03065 
03066    if( id < SARR_NUM(cd->sar) ){ /* found it, so just jump to it in the list */
03067 
03068       XmListSetBottomPos( cd->wchoice , id+1 ) ;      /* put on bottom */
03069       XmListSelectPos( cd->wchoice , id+1 , False ) ; /* select it */
03070 
03071    } else {                      /* is a new string, so add it to the list */
03072 
03073       ADDTO_SARR( cd->sar , nstr ) ;           /* add to internal list */
03074 
03075       xms = XmStringCreateSimple( nstr ) ;
03076       XmListAddItem( cd->wchoice , xms , 0 ) ; /* add to List widget */
03077       XmStringFree(xms) ;
03078 
03079       num_str = SARR_NUM(cd->sar) ;
03080       nvisible = (num_str < list_maxmax) ? num_str : list_max ;
03081       XtVaSetValues( cd->wchoice ,
03082                        XmNvisibleItemCount , nvisible ,
03083                      NULL ) ;
03084 
03085       XmListSetBottomPos( cd->wchoice , 0 ) ;      /* make sure it is visible */
03086       XmListSelectPos( cd->wchoice , 0 , False ) ; /* select it */
03087    }
03088 
03089    myXtFree(nstr) ; EXRETURN ;
03090 }
03091 
03092 /*--------------------------------------------------------------------------*/
03093 
03094 #define LIST_DBCLICK_UNKNOWN   -1
03095 #define LIST_DBCLICK_APPLY      1
03096 #define LIST_DBCLICK_DONE       2
03097 
03098 void MCW_choose_CB( Widget w , XtPointer client_data , XtPointer call_data )
03099 {
03100    MCW_choose_data *cd       = (MCW_choose_data *) client_data ;
03101    char *wname               = XtName(w) ;
03102    XmAnyCallbackStruct *icbs = (XmAnyCallbackStruct *) call_data ;
03103 
03104    static MCW_choose_cbs cbs ;  /* to be passed back to user */
03105    static int list_dbclick_use = LIST_DBCLICK_UNKNOWN ;
03106    Boolean clear ;
03107 
03108 ENTRY("MCW_choose_CB") ;
03109 
03110    /*--- set up what to do for list double clicks ---*/
03111 
03112    if( list_dbclick_use == LIST_DBCLICK_UNKNOWN ){
03113 #if 0
03114       char *xdef = XGetDefault( XtDisplay(w) , "AFNI" , "chooser_doubleclick" ) ;
03115 #else
03116       char *xdef = RWC_getname( XtDisplay(w) , "chooser_doubleclick" ) ;
03117 #endif
03118       if( xdef != NULL && strcmp(xdef,OVC_apply_label) == 0 )
03119          list_dbclick_use = LIST_DBCLICK_APPLY ;
03120       else
03121          list_dbclick_use = LIST_DBCLICK_DONE ;
03122    }
03123 
03124    /*--- branch on type of chooser that called this ---*/
03125 
03126    clear = (strcmp(wname,OVC_clear_label) == 0) ;
03127 
03128    if( clear && cd->ctype != mcwCT_string ){
03129       XBell( XtDisplay(cd->wpop) , 100 ) ;
03130       RWC_XtPopdown( cd->wpop ) ;
03131       EXRETURN ;
03132    }
03133 
03134    switch( cd->ctype ){
03135 
03136       default:                                   /* error! */
03137          XBell( XtDisplay(w) , 100 ) ;
03138          fprintf(stderr,
03139                  "\n*** unknown choose type=%d from %s\n", cd->ctype, wname ) ;
03140          EXRETURN ;
03141 
03142       /*.....................*/
03143 
03144       case mcwCT_vector:{                    /* vector chooser [19 Mar 2004] */
03145          Boolean done,call ;
03146          int iv ; float *vec ;
03147          MCW_arrowval **aav = (MCW_arrowval **)cd->av ;
03148 
03149          done = strcmp(wname,OVC_apply_label) != 0 ;
03150          call = strcmp(wname,OVC_quit_label)  != 0 ;
03151 
03152          if( done ) RWC_XtPopdown( cd->wpop ) ;
03153 
03154          if( call ){
03155             cbs.reason = mcwCR_vector ;  /* set structure for call to user */
03156             cbs.event  = icbs->event ;
03157             cbs.ival   = cd->nvec ;
03158             vec        = (float *)malloc(sizeof(float)*cd->nvec) ;
03159             cbs.cval   = (char *)vec ;
03160             for( iv=0 ; iv < cd->nvec ; iv++ ) vec[iv] = aav[iv]->fval ;
03161 
03162             if( !done ) MCW_invert_widget(w) ;              /* flash */
03163 #if 0
03164             cd->sel_CB( cd->wcaller , cd->sel_cd , &cbs ) ; /* call user */
03165 #else
03166             AFNI_CALL_VOID_3ARG( cd->sel_CB ,
03167                                  Widget           , cd->wcaller ,
03168                                  XtPointer        , cd->sel_cd  ,
03169                                  MCW_choose_cbs * , &cbs         ) ;
03170 #endif
03171             free((void *)vec) ; cbs.cval = NULL ;
03172             if( !done ) MCW_invert_widget(w) ;              /* flash */
03173          }
03174          EXRETURN ;
03175       }
03176 
03177       /*.....................*/
03178 
03179       case mcwCT_ovcolor:{                       /* color chooser */
03180          Boolean done , call ;
03181 
03182          done = strcmp(wname,OVC_apply_label) != 0 ;
03183          call = strcmp(wname,OVC_quit_label)  != 0 ;
03184 
03185          if( done ) RWC_XtPopdown( cd->wpop ) ;
03186 
03187          if( call ){
03188             cbs.reason = mcwCR_ovcolor ;  /* set structure for call to user */
03189             cbs.event  = icbs->event ;
03190             cbs.ival   = cd->av->ival ;
03191 
03192             if( !done ) MCW_invert_widget(w) ;              /* flash */
03193 #if 0
03194             cd->sel_CB( cd->wcaller , cd->sel_cd , &cbs ) ; /* call user */
03195 #else
03196             AFNI_CALL_VOID_3ARG( cd->sel_CB ,
03197                                  Widget           , cd->wcaller ,
03198                                  XtPointer        , cd->sel_cd  ,
03199                                  MCW_choose_cbs * , &cbs         ) ;
03200 #endif
03201             if( !done ) MCW_invert_widget(w) ;              /* flash */
03202          }
03203          EXRETURN ;
03204       }
03205 
03206       /*.....................*/
03207 
03208       case mcwCT_integer:{                       /* integer chooser */
03209          Boolean done , call , flash ;
03210 
03211          done  = strcmp(wname,OVC_apply_label) != 0 ;  /* done unless just "Apply" */
03212          flash = ! done ;                              /* flash if not done */
03213          call  = strcmp(wname,OVC_quit_label)  != 0 ;  /* call unless just "Quit" */
03214          if( w == cd->wchoice ){    /* Double click in List */
03215             done  = (list_dbclick_use == LIST_DBCLICK_DONE) ;
03216             flash = False ;
03217             call  = True ;
03218          }
03219 
03220          if( done ) RWC_XtPopdown( cd->wpop ) ;
03221 
03222          if( call ){
03223             int pos_count=0 , * pos_list=NULL , ib ;
03224             Boolean any ;
03225 
03226             cbs.reason = mcwCR_integer ;    /* set structure for call to user */
03227             cbs.event  = icbs->event ;
03228 
03229             if( cd->av != NULL ){           /* chooser was an arrowval */
03230                cbs.ival   = cd->av->ival ;
03231                cbs.fval   = cd->av->fval ;  /* 21 Jan 1997 */
03232                cbs.nilist = 1 ;
03233                cbs.ilist  = &(cbs.ival) ;
03234 
03235             } else {                        /* chooser was a List widget */
03236                any = XmListGetSelectedPos( cd->wchoice, &pos_list, &pos_count ) ;
03237                if( any ){
03238                   for( ib=0 ; ib < pos_count ; ib++ )  /* List indexes */
03239                      pos_list[ib]-- ;                  /* start at 1.  */
03240 
03241                   cbs.ival   = pos_list[0] ;           /* holds the first choice */
03242                   cbs.fval   = cbs.ival ;              /* 21 Jan 1997 */
03243                   cbs.nilist = pos_count ;             /* number of choices */
03244                   cbs.ilist  = pos_list ;              /* holds all choices */
03245                } else {
03246                   EXRETURN ;  /* no choice made */
03247                }
03248             }
03249 
03250             if( flash ) MCW_invert_widget(w) ;              /* flash */
03251 #if 0
03252             cd->sel_CB( cd->wcaller , cd->sel_cd , &cbs ) ; /* call user */
03253 #else
03254             AFNI_CALL_VOID_3ARG( cd->sel_CB ,
03255                                  Widget           , cd->wcaller ,
03256                                  XtPointer        , cd->sel_cd  ,
03257                                  MCW_choose_cbs * , &cbs         ) ;
03258 #endif
03259             if( flash ) MCW_invert_widget(w) ;              /* flash */
03260 
03261             myXtFree(pos_list) ;
03262          }
03263          EXRETURN ;
03264       }
03265 
03266       /*.....................*/
03267 
03268       case mcwCT_string:{                 /* string chooser */
03269          Boolean done , call , istextf ;
03270 
03271          /* special action: "Clear" button */
03272 
03273          if( clear ){ TEXT_SET( cd->wchoice , "" ) ; EXRETURN ; }
03274 
03275          /* find out if called by the text field itself */
03276 
03277          istextf = XtIsSubclass( w , TEXT_CLASS ) ;
03278 
03279          if( istextf == False ){                         /* check button names */
03280             done = strcmp(wname,OVC_apply_label) != 0 ;  /* to decide upon */
03281             call = strcmp(wname,OVC_quit_label)  != 0 ;  /* correct actions */
03282          } else {
03283             done = False ;   /* input from textfield == press "Apply" */
03284             call = True ;
03285          }
03286 
03287          if( done ) RWC_XtPopdown( cd->wpop ) ;
03288 
03289          if( call ){
03290             cbs.reason = mcwCR_string ;  /* set structure for call to user */
03291             cbs.event  = icbs->event ;
03292             cbs.cval   = TEXT_GET( cd->wchoice ) ;
03293 
03294             if( !done ) MCW_invert_widget(w) ;              /* flash */
03295 #if 0
03296             cd->sel_CB( cd->wcaller , cd->sel_cd , &cbs ) ; /* call user */
03297 #else
03298             AFNI_CALL_VOID_3ARG( cd->sel_CB ,
03299                                  Widget           , cd->wcaller ,
03300                                  XtPointer        , cd->sel_cd  ,
03301                                  MCW_choose_cbs * , &cbs         ) ;
03302 #endif
03303             if( !done ) MCW_invert_widget(w) ;              /* flash */
03304 
03305             myXtFree( cbs.cval ) ; cbs.cval = NULL ;
03306          }
03307          EXRETURN ;
03308       }
03309 
03310       /*.....................*/
03311 
03312       case mcwCT_timeseries:{                       /* timeseries chooser */
03313          Boolean done , call , flash , any , plot ;
03314          int pos_count , * pos_list ;
03315 
03316 #ifdef AFNI_DEBUG
03317 printf("MCW_choose_CB: timeseries choice made\n") ;
03318 #endif
03319 
03320          if( w == cd->wchoice ){  /* choice is from double click in List widget */
03321             done  = (list_dbclick_use == LIST_DBCLICK_DONE) ;
03322             flash = False ;
03323             plot  = False ;
03324             call  = True ;
03325          } else {                 /* choice is from control buttons */
03326 
03327             done  = (strcmp(wname,TSC_quit_label) == 0) ||   /* are we done with   */
03328                     (strcmp(wname,TSC_done_label) == 0)    ; /* this popup widget? */
03329 
03330             flash = ! done ;                                 /* flash if not done */
03331 
03332             call  = (strcmp(wname,TSC_apply_label) == 0) ||  /* do we call the  */
03333                     (strcmp(wname,TSC_done_label)  == 0)   ; /* user's routine? */
03334 
03335             plot  = (strcmp(wname,TSC_plot_label)  == 0) ;   /* do we plot a graph? */
03336          }
03337 
03338 #ifdef BBOX_DEBUG
03339 printf("MCW_choose_CB: done=%d  call=%d  plot=%d  flash=%d\n",
03340        (int)done , (int)call , (int)plot , (int)flash ) ;
03341 #endif
03342 
03343          if( done ) RWC_XtPopdown( cd->wpop ) ;
03344 
03345          if( call || plot ){  /* must find out what is selected */
03346             int pos_count , * pos_list , first ;
03347             MRI_IMAGE * fim ;
03348 
03349 #ifdef BBOX_DEBUG
03350 printf("MCW_choose_CB: querying list for choice\n") ;
03351 #endif
03352 
03353             any = XmListGetSelectedPos( cd->wchoice , &pos_list , &pos_count ) ;
03354 
03355 #ifdef BBOX_DEBUG
03356 printf("MCW_choose_CB: queryed list for choice\n") ;
03357 #endif
03358 
03359             if( any ){
03360                 first = pos_list[0] - 1 ;                 /* XmList index starts at 1 */
03361                 fim   = IMARR_SUBIMAGE(cd->tsarr,first) ;
03362                 myXtFree(pos_list) ;
03363             } else {  /* no choice made --> nothing to do! */
03364                 if( plot ) XBell( XtDisplay(w) , 100 ) ;
03365                 EXRETURN ;
03366             }
03367 
03368 #ifdef BBOX_DEBUG
03369 printf("MCW_choose_CB: choice index = %d\n",first) ;
03370 #endif
03371 
03372             if( call ){
03373                cbs.reason = mcwCR_timeseries ;  /* set structure for call to user */
03374                cbs.event  = icbs->event ;
03375                cbs.ival   = first ;
03376                cbs.imval  = fim ;
03377 
03378 #ifdef BBOX_DEBUG
03379 printf("MCW_choose_CB: calling user supplied routine\n") ;
03380 #endif
03381 
03382                if( flash ) MCW_invert_widget(w) ;              /* flash */
03383 #if 0
03384                cd->sel_CB( cd->wcaller , cd->sel_cd , &cbs ) ; /* call user */
03385 #else
03386                AFNI_CALL_VOID_3ARG( cd->sel_CB ,
03387                                     Widget           , cd->wcaller ,
03388                                     XtPointer        , cd->sel_cd  ,
03389                                     MCW_choose_cbs * , &cbs         ) ;
03390 #endif
03391                if( flash ) MCW_invert_widget(w) ;              /* flash */
03392                EXRETURN ;
03393             }
03394 
03395             if( plot ){
03396 
03397 #ifdef BBOX_DEBUG
03398 printf("MCW_choose_CB: plotting selected timeseries\n") ;
03399 #endif
03400 
03401             /*-- 17 Aug 1998: plotting code (at last!) --*/
03402 
03403 #ifdef DONT_USE_COXPLOT
03404                (void) MCW_popup_message( w , "Plot not yet\nimplemented." ,
03405                                          MCW_USER_KILL | MCW_TIMER_KILL ) ;
03406                EXRETURN ;
03407 #else
03408                if( fim->kind != MRI_float ){
03409                   (void) MCW_popup_message( w , "Can't plot\nnon-float data!" ,
03410                                             MCW_USER_KILL | MCW_TIMER_KILL ) ;
03411                   EXRETURN ;
03412                } else {
03413                   float ** yar , * far = MRI_FLOAT_PTR(fim) ;
03414                   char ** nar=NULL ;
03415                   int jj ;
03416 
03417 #undef USE_NAR  /* use labels for each column?  (just to test the code) */
03418 
03419                   yar = (float **) malloc( sizeof(float *) * fim->ny ) ;
03420                   for( jj=0 ; jj < fim->ny ; jj++ )
03421                      yar[jj] = far + jj * fim->nx ;
03422 
03423 #ifdef USE_NAR
03424                   nar = (char **)  malloc( sizeof(char * ) * fim->ny ) ;
03425                   for( jj=0 ; jj < fim->ny ; jj++ ){
03426                      nar[jj] = (char *) malloc( sizeof(char) * 32 ) ;
03427                      sprintf(nar[jj],"column %d",jj+1) ;
03428                   }
03429 #endif
03430                   plot_ts_lab( XtDisplay(w) ,
03431                                fim->nx , NULL , fim->ny , yar ,
03432                                "index" , NULL , fim->name , nar , NULL ) ;
03433 
03434                   if( nar != NULL ){
03435                      for( jj=0 ; jj < fim->ny ; jj++ ) free(nar[jj]) ;
03436                      free(nar) ;
03437                   }
03438                   free(yar) ;
03439                   EXRETURN ;
03440                }
03441 #endif /* DONT_USE_COXPLOT */
03442             }
03443 
03444          }
03445          EXRETURN ;
03446       }
03447 
03448    }  /* end of switch on ctype */
03449 
03450    EXRETURN ;  /* unreachable */
03451 }
 

Powered by Plone

This site conforms to the following standards: