1 #include "afni.h"
2 
3 /*-----------------------------------------------------------------------
4     03 Nov 1998: allow locking of time index
5 -------------------------------------------------------------------------*/
6 
AFNI_time_lock_change_CB(Widget w,XtPointer cd,XtPointer calld)7 void AFNI_time_lock_change_CB( Widget w , XtPointer cd , XtPointer calld )
8 {
9    Three_D_View *im3d = (Three_D_View *) cd ;
10    Three_D_View *qq3d ;
11    int           bval , ii , bold ;
12 
13 ENTRY("AFNI_time_lock_change_CB") ;
14 
15    if( ! IM3D_VALID(im3d) ) EXRETURN ;
16 
17    /* get current global setting and compare to changed lock box */
18 
19    bold = GLOBAL_library.time_lock ;
20    bval = MCW_val_bbox( im3d->vwid->dmode->time_lock_bbox ) ;
21    if( bval == bold ) EXRETURN ;                     /* same --> nothing to do */
22 
23    /* new value --> save in global setting */
24 
25    GLOBAL_library.time_lock = bval ;
26 
27    /* set all other controller lock boxes to the same value */
28 
29    for( ii=0 ; ii < MAX_CONTROLLERS ; ii++ ){
30      qq3d = GLOBAL_library.controllers[ii] ;
31      if( qq3d == im3d || ! IM3D_VALID(qq3d) ) continue ;
32 
33      MCW_set_bbox( qq3d->vwid->dmode->time_lock_bbox , bval ) ;
34    }
35    RESET_AFNI_QUIT(im3d) ;
36    EXRETURN ;
37 }
38 
39 /*------------------------------------------------------------------------*/
40 /* Do the locking of time indexes */
41 
AFNI_time_lock_carryout(Three_D_View * im3d)42 void AFNI_time_lock_carryout( Three_D_View *im3d )
43 {
44    Three_D_View *qq3d ;
45    MCW_arrowval *tav ;
46    int new_index , qq_index , qq_top , cc , glock , ii ;
47    static int busy = 0 ;  /* !=0 if this routine is "busy" */
48 
49 ENTRY("AFNI_time_lock_carryout") ;
50 
51    /* first, determine if there is anything to do */
52 
53    glock = GLOBAL_library.controller_lock ;     /* not a handgun */
54 
55    if( busy )                       EXRETURN ;  /* routine already busy */
56    if( glock == 0 )                 EXRETURN ;  /* nothing to do */
57    if( !IM3D_OPEN(im3d) )           EXRETURN ;  /* bad input */
58    if( GLOBAL_library.ignore_lock ) EXRETURN ;  /* ordered not to do anything */
59    if( ! GLOBAL_library.time_lock ) EXRETURN ;  /* don't lock time */
60 
61    ii = AFNI_controller_index(im3d) ;           /* which one am I? */
62 
63    if( ii < 0 ) EXRETURN ;                      /* nobody? bad input! */
64    if( ((1<<ii) & glock) == 0 ) EXRETURN ;      /* input not locked */
65 
66    /* something to do? */
67 
68    busy = 1 ;  /* don't let this routine be called recursively */
69 
70    /* load time index of this controller => all others get this value, too*/
71 
72    new_index = im3d->vinfo->time_index ;
73 
74    /* loop through other controllers:
75         for those that ARE open, ARE NOT the current
76         one, and ARE locked, jump to the new time index */
77 
78    for( cc=0 ; cc < MAX_CONTROLLERS ; cc++ ){
79 
80      qq3d = GLOBAL_library.controllers[cc] ; /* controller */
81 
82      if( IM3D_OPEN(qq3d) && qq3d != im3d && ((1<<cc) & glock) != 0 ){
83 
84        qq_index = qq3d->vinfo->time_index ;           /* old index */
85        qq_top   = qq3d->vinfo->top_index ;            /* max allowed */
86 
87        if( qq3d->vinfo->time_on && qq_top > 1 && qq_index != new_index ){
88          tav = qq3d->vwid->imag->time_index_av ;
89          AV_assign_ival( tav , new_index ) ;         /* will check range */
90          if( tav->ival != qq_index )
91            AFNI_time_index_CB( tav , (XtPointer) qq3d ) ;
92        }
93      }
94    }
95 
96    busy = 0 ;  /* OK, let this routine be activated again */
97    EXRETURN ;
98 }
99 
100 /*-----------------------------------------------------------------------
101    The following routines for "locks" were added 04 Nov 1996
102 -------------------------------------------------------------------------*/
103 
AFNI_lock_enforce_CB(Widget w,XtPointer cd,XtPointer calld)104 void AFNI_lock_enforce_CB( Widget w , XtPointer cd , XtPointer calld )
105 {
106    Three_D_View *im3d = (Three_D_View *) cd ;
107 
108 ENTRY("AFNI_lock_enforce_CB") ;
109    if( !IM3D_OPEN(im3d) ) EXRETURN ;
110    AFNI_space_lock_carryout( im3d ) ;
111    AFNI_time_lock_carryout( im3d ) ;  /* 03 Nov 1998 */
112    RESET_AFNI_QUIT(im3d) ;
113    EXRETURN ;
114 }
115 
116 /*------------------------------------------------------------------------*/
117 
AFNI_lock_change_CB(Widget w,XtPointer cd,XtPointer calld)118 void AFNI_lock_change_CB( Widget w , XtPointer cd , XtPointer calld )
119 {
120    Three_D_View *im3d = (Three_D_View *) cd ;
121    Three_D_View *qq3d ;
122    int           bval , ii , bold ;
123 
124 ENTRY("AFNI_lock_change_CB") ;
125 
126    if( ! IM3D_VALID(im3d) ) EXRETURN ;
127 
128    /* get current global setting and compare to changed lock box */
129 
130    bold = GLOBAL_library.controller_lock ;
131    bval = MCW_val_bbox( im3d->vwid->dmode->lock_bbox ) ;
132    if( bval == bold ) EXRETURN ;                     /* same --> nothing to do */
133 
134    /* new value --> save in global setting */
135 
136    GLOBAL_library.controller_lock = bval ;
137 
138    /* set all other controller lock boxes to the same value */
139 
140    for( ii=0 ; ii < MAX_CONTROLLERS ; ii++ ){
141      qq3d = GLOBAL_library.controllers[ii] ;
142      if( qq3d == im3d || ! IM3D_VALID(qq3d) ) continue ;
143 
144      MCW_set_bbox( qq3d->vwid->dmode->lock_bbox , bval ) ;
145    }
146    RESET_AFNI_QUIT(im3d) ;
147    EXRETURN ;
148 }
149 
150 /*------------------------------------------------------------------------*/
151 
AFNI_lock_clear_CB(Widget w,XtPointer cd,XtPointer calld)152 void AFNI_lock_clear_CB( Widget w , XtPointer cd , XtPointer calld )
153 {
154    Three_D_View *qq3d ;
155    int ii ;
156 
157 ENTRY("AFNI_lock_clear_CB") ;
158 
159    GLOBAL_library.controller_lock = 0 ;
160    for( ii=0 ; ii < MAX_CONTROLLERS ; ii++ ){
161      qq3d = GLOBAL_library.controllers[ii] ;
162      if( IM3D_VALID(qq3d) )
163        MCW_set_bbox( qq3d->vwid->dmode->lock_bbox , 0 ) ;
164    }
165    if( w != (Widget)NULL ){
166     static int ncall = 0 ;
167     if( ncall == 0 )
168       (void)MCW_popup_message( w ,
169                                  " \n"
170                                  "*** WARNING:             ***\n"
171                                  "*** all AFNI controllers ***\n"
172                                  "*** have been unlocked!  ***\n"
173                                  "----------------------------\n"
174                                  "*** The 'Set All' button ***\n"
175                                  "*** can re-lock them :)  ***\n" ,
176                                MCW_USER_KILL | MCW_TIMER_KILL ) ;
177      ncall++ ;
178    }
179 
180    EXRETURN ;
181 }
182 
183 /*------------------------------------------------------------------------*/
184 
AFNI_lock_setall_CB(Widget w,XtPointer cd,XtPointer calld)185 void AFNI_lock_setall_CB( Widget w , XtPointer cd , XtPointer calld )
186 {
187    Three_D_View *qq3d ;
188    int ii ;
189 
190 ENTRY("AFNI_lock_setall_CB") ;
191 
192    GLOBAL_library.controller_lock = 0 ;
193    for( ii=0 ; ii < MAX_CONTROLLERS ; ii++ )
194      GLOBAL_library.controller_lock |= (1<<ii) ;
195 
196    for( ii=0 ; ii < MAX_CONTROLLERS ; ii++ ){
197      qq3d = GLOBAL_library.controllers[ii] ;
198      if( IM3D_VALID(qq3d) )
199        MCW_set_bbox( qq3d->vwid->dmode->lock_bbox ,
200                      GLOBAL_library.controller_lock ) ;
201    }
202    EXRETURN ;
203 }
204 
205 /*------------------------------------------------------------------------*/
206 /* Do the locking of spatial coordinates */
207 
AFNI_space_lock_carryout(Three_D_View * im3d)208 void AFNI_space_lock_carryout( Three_D_View *im3d )
209 {
210    Three_D_View *qq3d ;
211    int ii,jj,kk , cc , glock ;
212    THD_fvec3 old_fv , fv ;
213    THD_ivec3 iv ;
214    THD_dataxes *qaxes , *daxes ;
215    static int busy = 0 ;  /* !=0 if this routine is "busy" */
216 
217 ENTRY("AFNI_space_lock_carryout") ;
218 
219    /* first, determine if there is anything to do */
220 
221    glock = GLOBAL_library.controller_lock ;
222 
223    if( busy )                       EXRETURN ;  /* routine already busy */
224    if( glock == 0 )                 EXRETURN ;  /* nothing to do */
225    if( !IM3D_OPEN(im3d) )           EXRETURN ;  /* bad input */
226    if( GLOBAL_library.ignore_lock ) EXRETURN ;  /* ordered not to do anything */
227 
228    ii = AFNI_controller_index(im3d) ;           /* which one am I? */
229 
230    if( ii < 0 ) EXRETURN ;                      /* nobody? bad input! */
231    if( ((1<<ii) & glock) == 0 ) EXRETURN ;      /* input not locked */
232 
233    /* something to do? */
234 
235    busy = 1 ;  /* don't let this routine be called recursively */
236 
237    /* load Dicom location of current point of view in this controller */
238 
239    LOAD_FVEC3( old_fv , im3d->vinfo->xi, im3d->vinfo->yj, im3d->vinfo->zk ) ;
240 
241    LOAD_ANAT_VIEW(im3d) ;  /* prepare coordinates */
242    daxes = CURRENT_DAXES(im3d->anat_now) ;
243 
244    /* loop through other controllers:
245         for those that ARE open, ARE NOT the current one,
246         and ARE locked, transform the above vector to the
247         controller's dataset, and then jump to that point */
248 
249    for( cc=0 ; cc < MAX_CONTROLLERS ; cc++ ){
250 
251      qq3d = GLOBAL_library.controllers[cc] ; /* controller */
252 
253      if( IM3D_OPEN(qq3d) && qq3d != im3d && ((1<<cc) & glock) != 0 ){
254 
255        LOAD_ANAT_VIEW(qq3d) ;  /* prepare coordinates */
256        qaxes = CURRENT_DAXES(qq3d->anat_now) ;
257 
258        if( !GLOBAL_library.ijk_lock ){  /* xyz coord lock */
259 
260          fv = AFNI_transform_vector( im3d->anat_now, old_fv, qq3d->anat_now ) ;
261          fv = THD_dicomm_to_3dmm( qq3d->anat_now , fv ) ;
262          iv = THD_3dmm_to_3dind ( qq3d->anat_now , fv ) ;
263          ii = iv.ijk[0] ; jj = iv.ijk[1] ; kk = iv.ijk[2] ;
264 
265        } else {   /* 11 Sep 2000: ijk index lock */
266 
267          ii = im3d->vinfo->i1 * qaxes->nxx / daxes->nxx ;
268          jj = im3d->vinfo->j2 * qaxes->nyy / daxes->nyy ;
269          kk = im3d->vinfo->k3 * qaxes->nzz / daxes->nzz ;
270        }
271 
272        /* if have good new ijk coords, jump to them */
273 
274        if( ii >= 0 && ii < qaxes->nxx &&
275            jj >= 0 && jj < qaxes->nyy && kk >= 0 && kk < qaxes->nzz   ){
276 
277          SAVE_VPT(qq3d) ;
278          AFNI_set_viewpoint( qq3d , ii,jj,kk , REDISPLAY_ALL ) ; /* jump */
279        }
280      }
281    }
282 
283    busy = 0 ;  /* OK, let this routine be activated again */
284    EXRETURN ;
285 }
286 
287 /*-----------------------------------------------------------------------
288     11 Sep 2000: allow locking using ijk instead of xyz
289 -------------------------------------------------------------------------*/
290 
AFNI_ijk_lock_change_CB(Widget w,XtPointer cd,XtPointer calld)291 void AFNI_ijk_lock_change_CB( Widget w , XtPointer cd , XtPointer calld )
292 {
293    Three_D_View *im3d = (Three_D_View *) cd ;
294    Three_D_View *qq3d ;
295    int           bval , ii , bold ;
296 
297 ENTRY("AFNI_ijk_lock_change_CB") ;
298 
299    if( ! IM3D_VALID(im3d) ) EXRETURN ;
300 
301    /* get current global setting and compare to changed lock box */
302 
303    bold = GLOBAL_library.ijk_lock ;
304    bval = MCW_val_bbox( im3d->vwid->dmode->ijk_lock_bbox ) ;
305    if( bval == bold ) EXRETURN ;                     /* same --> nothing to do */
306 
307    /* new value --> save in global setting */
308 
309    GLOBAL_library.ijk_lock = bval ;
310 
311    /* set all other controller lock boxes to the same value */
312 
313    for( ii=0 ; ii < MAX_CONTROLLERS ; ii++ ){
314      qq3d = GLOBAL_library.controllers[ii] ;
315      if( qq3d == im3d || ! IM3D_VALID(qq3d) ) continue ;
316 
317      MCW_set_bbox( qq3d->vwid->dmode->ijk_lock_bbox , bval ) ;
318    }
319    RESET_AFNI_QUIT(im3d) ;
320    EXRETURN ;
321 }
322 
323 /*------------------------------------------------------------------------*/
324 
AFNI_bbox_thrlock_mask2val(int bval)325 int AFNI_bbox_thrlock_mask2val(int bval)
326 {
327    int ii;
328    for (ii=0; ii<3; ++ii) {
329       if (bval & 1<<ii) {
330          return(ii);
331       }
332    }
333    return(0);
334 }
335 
336 /*------------------------------------------------------------------------*/
337 
AFNI_set_all_thrlock_bboxes(Three_D_View * im3d,int bval)338 void AFNI_set_all_thrlock_bboxes(Three_D_View *im3d, int bval)
339 {
340    int ii;
341    Three_D_View *qq3d ;
342 
343    if (bval < 0) bval = 1<<AFNI_thresh_lock_env_val();
344 
345    /* set all other controller lock boxes to the same value */
346    for( ii=0 ; ii < MAX_CONTROLLERS ; ii++ ){
347      qq3d = GLOBAL_library.controllers[ii] ;
348      if( qq3d == im3d || ! IM3D_VALID(qq3d) ) continue ;
349      MCW_set_bbox( qq3d->vwid->dmode->thr_lock_bbox , bval ) ;
350    }
351 
352    GLOBAL_library.thr_lock = AFNI_bbox_thrlock_mask2val(bval);
353 
354    return;
355 }
356 
357 /*------------------------------------------------------------------------*/
358 
AFNI_func_thrlock_change_CB(Widget w,XtPointer cd,XtPointer calld)359 void AFNI_func_thrlock_change_CB( Widget w , XtPointer cd , XtPointer calld )
360 {
361    Three_D_View *im3d = (Three_D_View *) cd ;
362    int           bval , bold ;
363 
364 ENTRY("AFNI_func_thrlock_change_CB") ;
365 
366    if( ! IM3D_VALID(im3d) ) EXRETURN ;
367 
368    bold = 1<<GLOBAL_library.thr_lock ;
369    bval = MCW_val_bbox( im3d->vwid->dmode->thr_lock_bbox ) ;
370 
371    if( bval == bold ) EXRETURN ;                     /* same --> nothing to do */
372 
373    /* new value --> save in global setting */
374 
375    GLOBAL_library.thr_lock = AFNI_bbox_thrlock_mask2val(bval) ;
376 
377    /* And apply it to other controllers */
378    AFNI_set_all_thrlock_bboxes(im3d, bval);
379 
380    RESET_AFNI_QUIT(im3d) ;
381    EXRETURN ;
382 }
383 
384 /*------------------------------------------------------------------------*/
385 
AFNI_thresh_lock_env_val(void)386 int AFNI_thresh_lock_env_val(void)
387 {
388    int i=0;
389    char *eee=NULL;
390 
391    eee = getenv( "AFNI_THRESH_LOCK" ) ;          /* determine how to lock */
392    if( eee == NULL ) return(0) ;
393    if(*eee == 'V' || *eee == 'v') return(1);
394    if(*eee == 'P' || *eee == 'p') return(2);
395    return(0);
396 }
397 
398 /*------------------------------------------------------------------------*/
399 /* Do the locking of thresholds */
400 
AFNI_thresh_lock_carryout(Three_D_View * im3d)401 void AFNI_thresh_lock_carryout( Three_D_View *im3d )
402 {
403    Three_D_View *qq3d ;
404    static int busy = 0 ;  /* !=0 if this routine is "busy" */
405    int glock , cc,ii , dopval,dothresh ;
406    float thresh , pval=0.0f , tval ;
407    char cmd[64] ;
408 
409 ENTRY("AFNI_thresh_lock_carryout") ;
410 
411    /* first, determine if there is anything to do */
412 
413    glock = GLOBAL_library.controller_lock ;     /* not a handgun */
414 
415    if( busy )                         EXRETURN;  /* routine already busy */
416    if( glock == 0 )                   EXRETURN;  /* nothing to do */
417    if( !IM3D_OPEN(im3d) )             EXRETURN;  /* bad input */
418    if( GLOBAL_library.ignore_lock )   EXRETURN;  /* ordered not to do anything */
419    if (!GLOBAL_library.thr_lock)      EXRETURN;
420    dothresh = (GLOBAL_library.thr_lock == 1) ;
421    dopval   = (GLOBAL_library.thr_lock == 2) && im3d->fim_now != NULL ;
422    if( !dothresh && !dopval ) EXRETURN ;         /* no command? */
423 
424    ii = AFNI_controller_index(im3d) ;           /* which one am I? */
425 
426    if( ii < 0 ) EXRETURN ;                      /* nobody? bad input! */
427    if( ((1<<ii) & glock) == 0 ) EXRETURN ;      /* input not locked */
428 
429    /* something to do? */
430 
431    busy = 1 ;  /* don't let this routine be called recursively */
432 
433    /* get true threshold of this controller => all others get this value, too*/
434 
435    thresh = get_3Dview_func_thresh(im3d,1) ;
436 
437    /* get p-value corresponding, if that is what's being locked */
438 
439    if( dopval ){
440      pval = THD_stat_to_pval( thresh ,
441                 DSET_BRICK_STATCODE(im3d->fim_now,im3d->vinfo->thr_index) ,
442                 DSET_BRICK_STATAUX (im3d->fim_now,im3d->vinfo->thr_index)  ) ;
443      if( pval < 0.0 || pval > 1.0 ){ dopval = 0; dothresh = 1; }
444    }
445 
446    /* loop through other controllers:
447         for those that ARE open, ARE NOT the current
448         one, and ARE locked, set the new threshold */
449 
450    for( cc=0 ; cc < MAX_CONTROLLERS ; cc++ ){
451 
452      qq3d = GLOBAL_library.controllers[cc] ; /* controller */
453 
454      if( IM3D_OPEN(qq3d) && qq3d != im3d && ((1<<cc) & glock) != 0 ){
455 
456        if( dothresh )
457          sprintf( cmd , "SET_THRESHNEW %c %.4f **" , 'A'+cc , thresh ) ;
458        else if( dopval && qq3d->fim_now != NULL &&
459                 DSET_BRICK_STATCODE(qq3d->fim_now,qq3d->vinfo->thr_index) > 0 )
460          sprintf( cmd , "SET_THRESHNEW %c %g *p" , 'A'+cc , pval ) ;
461        else
462          continue ;  /* pval, but not a statistic? */
463 
464        AFNI_driver( cmd ) ;
465      }
466    }
467 
468    busy = 0 ;  /* OK, let this routine be activated again */
469    EXRETURN ;
470 }
471 
472 /*---------------------------------------------------------------*/
473 
AFNI_equate_pbars(Three_D_View * lh3d,Three_D_View * rh3d)474 void AFNI_equate_pbars( Three_D_View *lh3d , Three_D_View *rh3d )
475 {
476    MCW_pbar *lbar , *rbar ;
477    char cmd[1024] ;
478    int cc , qq ;
479    MCW_DCOV *ovc = GLOBAL_library.dc->ovc ;
480 
481 ENTRY("AFNI_equate_pbars") ;
482 
483    if( !IM3D_OPEN(lh3d) || !IM3D_OPEN(rh3d) ) EXRETURN ;
484 
485    lbar = lh3d->vwid->func->inten_pbar ;
486    rbar = rh3d->vwid->func->inten_pbar ;
487 
488    if( MCW_pbars_equivalent(lbar,rbar) ) EXRETURN ;  /* 07 Jul 2014 */
489 
490    cc = AFNI_controller_index(lh3d) ; if( cc < 0 ) EXRETURN ;
491 
492    if( !rbar->bigmode ){
493      sprintf(cmd,"SET_PBAR_ALL %c.%c%d" , 'A'+cc ,
494              (rbar->mode) ? '+' : '-' , rbar->num_panes ) ;
495      for( qq=0 ; qq < rbar->num_panes ; qq++ )
496        sprintf(cmd+strlen(cmd)," %s=%s",
497                AV_uformat_fval(rbar->pval[qq]) ,
498                ovc->label_ov[rbar->ov_index[qq]] ) ;
499    } else {
500      if( rbar->big31 == 0 )
501        sprintf(cmd,"SET_PBAR_ALL %c.%c%d %f %s\n" , 'A'+cc ,
502                (rbar->mode) ? '+' : '-' , 99 ,
503                rbar->bigtop , PBAR_get_bigmap(rbar) ) ;
504      else
505        sprintf(cmd,"SET_PBAR_ALL %c.%c%d %f::%f %s\n" , 'A'+cc ,
506                (rbar->mode) ? '+' : '-' , 99 ,
507                rbar->bigbot,rbar->bigtop , PBAR_get_bigmap(rbar) ) ;
508      if( rbar->bigflip )
509        sprintf(cmd+strlen(cmd)," FLIP") ;
510      if( rbar->bigrota )
511        sprintf(cmd+strlen(cmd)," ROTA=%d",rbar->bigrota) ;
512      lbar->big30 = rbar->big30 ;
513      lbar->big31 = rbar->big31 ;
514      lbar->big32 = rbar->big32 ;
515    }
516 
517    AFNI_driver(cmd) ; EXRETURN ;
518 }
519 
520 /*---------------------------------------------------------------*/
521 /* Do the locking of pbars */
522 
AFNI_pbar_lock_carryout(Three_D_View * im3d)523 void AFNI_pbar_lock_carryout( Three_D_View *im3d )
524 {
525    Three_D_View *qq3d ;
526    static int busy = 0 ;  /* !=0 if this routine is "busy" */
527    int glock , cc,ii ;
528 
529 ENTRY("AFNI_pbar_lock_carryout") ;
530 
531    /* first, determine if there is anything to do */
532 
533    glock = GLOBAL_library.controller_lock ;     /* not a handgun */
534 
535    if( busy )                         EXRETURN;  /* routine already busy */
536    if( glock == 0 )                   EXRETURN;  /* nothing to do */
537    if( !IM3D_OPEN(im3d) )             EXRETURN;  /* bad input */
538    if( GLOBAL_library.ignore_lock )   EXRETURN;  /* ordered not to do anything */
539    if( !AFNI_check_pbar_lock() )      EXRETURN;  /* not locked? */
540 
541    ii = AFNI_controller_index(im3d) ;           /* which one am I? */
542 
543    if( ii < 0 ) EXRETURN ;                      /* nobody? bad input! */
544    if( ((1<<ii) & glock) == 0 ) EXRETURN ;      /* input not locked */
545 
546 #if 0
547 INFO_message("AFNI_pbar_lock_carryout( %d ) ******************* ",ii) ;
548 TRACEBACK ;
549 #endif
550 
551    /* something to do? */
552 
553    busy = 1 ;  /* don't let this routine be called recursively */
554 
555    /* loop through other controllers:
556         for those that ARE open, ARE NOT the current one, and ARE locked */
557 
558    for( cc=0 ; cc < MAX_CONTROLLERS ; cc++ ){
559 
560      qq3d = GLOBAL_library.controllers[cc] ; /* controller */
561 
562      if( IM3D_OPEN(qq3d) && qq3d != im3d && ((1<<cc) & glock) != 0 ){
563 #if 0
564 ININFO_message(" equate_pbars( %d )",cc) ;
565 #endif
566        AFNI_equate_pbars( qq3d , im3d ) ;
567      }
568    }
569 
570    busy = 0 ;  /* OK, let this routine be activated again */
571    EXRETURN ;
572 }
573 
574 /*------------------------------------------------------------------------*/
575 /* Do the dynamic locking of dragging thresholds */
576 
AFNI_thrdrag_lock_carryout(Three_D_View * im3d)577 void AFNI_thrdrag_lock_carryout( Three_D_View *im3d )
578 {
579    Three_D_View *qq3d ;
580    static int busy = 0 ;  /* !=0 if this routine is "busy" */
581    int glock , cc,ii , dothresh,dopval , ival , stop ;
582    float thresh , pval=0.0f , tval ;
583 
584 ENTRY("AFNI_thrdrag_lock_carryout") ;
585 
586    /* first, determine if there is anything to do */
587 
588    glock = GLOBAL_library.controller_lock ;     /* not a handgun */
589 
590    if( busy )                         EXRETURN;  /* routine already busy */
591    if( glock == 0 )                   EXRETURN;  /* nothing to do */
592    if( !IM3D_OPEN(im3d) )             EXRETURN;  /* bad input */
593    if( GLOBAL_library.ignore_lock )   EXRETURN;  /* ordered not to do anything */
594 
595    if (!GLOBAL_library.thr_lock) EXRETURN;
596    dothresh = (GLOBAL_library.thr_lock == 1) ;
597    dopval   = (GLOBAL_library.thr_lock == 2) && im3d->fim_now != NULL ;
598    if( !dothresh && !dopval ) EXRETURN ;         /* no command? */
599 
600    ii = AFNI_controller_index(im3d) ;           /* which one am I? */
601 
602    if( ii < 0 ) EXRETURN ;                      /* nobody? bad input! */
603    if( ((1<<ii) & glock) == 0 ) EXRETURN ;      /* input not locked */
604 
605    /* something to do? */
606 
607    busy = 1 ;  /* don't let this routine be called recursively */
608 
609    ival   = rint(im3d->vinfo->func_threshold/THR_factor) ;
610    thresh = get_3Dview_func_thresh(im3d,1) ;
611    stop   = (int)( rint( pow(10.0,THR_top_expon) ) - 1.0 ) ;
612 
613    if( dopval ){
614      pval = THD_stat_to_pval( thresh ,
615                 DSET_BRICK_STATCODE(im3d->fim_now,im3d->vinfo->thr_index) ,
616                 DSET_BRICK_STATAUX (im3d->fim_now,im3d->vinfo->thr_index)  ) ;
617      if( pval < 0.0 || pval > 1.0 ){ dopval = 0; dothresh = 1; }
618    }
619 
620    /* loop through other controllers:
621         for those that ARE open, ARE NOT the current
622         one, and ARE locked, set the new threshold */
623 
624    for( cc=0 ; cc < MAX_CONTROLLERS ; cc++ ){
625 
626      qq3d = GLOBAL_library.controllers[cc] ; /* controller */
627 
628      if( IM3D_OPEN(qq3d) && qq3d != im3d && ((1<<cc) & glock) != 0 ){
629 
630        if( qq3d->vinfo->func_thresh_top == im3d->vinfo->func_thresh_top ){
631 
632          if( dopval && qq3d->fim_now != NULL &&
633              DSET_BRICK_STATCODE(qq3d->fim_now,qq3d->vinfo->thr_index) > 0 ){
634 
635            tval = THD_pval_to_stat( pval ,
636                     DSET_BRICK_STATCODE(qq3d->fim_now,qq3d->vinfo->thr_index),
637                     DSET_BRICK_STATAUX (qq3d->fim_now,qq3d->vinfo->thr_index) );
638            ival = rint( tval/(THR_factor*qq3d->vinfo->func_thresh_top) ) ;
639            if( ival < 0 ) ival = 0 ; else if( ival > stop ) ival = stop ;
640 
641          } else if( !dothresh ){
642            continue ;  /* skip this [dopval set, but not a statistic] */
643          }
644 
645          /* set the slider and pval marker */
646 
647          XmScaleSetValue( qq3d->vwid->func->thr_scale , ival ) ;
648          qq3d->vinfo->func_threshold = THR_factor * ival ;
649          AFNI_set_thr_pval( qq3d ) ;
650        }
651      }
652    }
653 
654    busy = 0 ;  /* OK, let this routine be activated again */
655    EXRETURN ;
656 }
657 
658 /*------------------------------------------------------------------------*/
659 
AFNI_check_pbar_lock()660 int AFNI_check_pbar_lock()
661 {
662    return AFNI_yesenv("AFNI_PBAR_LOCK") ;
663 }
664 
665 /*------------------------------------------------------------------------*/
666 
AFNI_check_range_lock()667 int AFNI_check_range_lock()
668 {
669    if( AFNI_yesenv("AFNI_RANGE_LOCK")           ) return 1 ;
670    if( PBAR_FULLRANGE && AFNI_check_pbar_lock() ) return 1 ;
671    return 0 ;
672 }
673 
674 /*------------------------------------------------------------------------*/
675 /* Do the locking of OLay ranges */
676 
AFNI_range_lock_carryout(Three_D_View * im3d)677 void AFNI_range_lock_carryout( Three_D_View *im3d )
678 {
679    Three_D_View *qq3d ;
680    static int busy = 0 ;  /* !=0 if this routine is "busy" */
681    int glock , cc,ii,nn , qdone=0 ;
682    float val ;
683    char cmd[64] ;
684 
685 ENTRY("AFNI_range_lock_carryout") ;
686 
687    /* first, determine if there is anything to do */
688 
689    glock = GLOBAL_library.controller_lock ;      /* not a handgun */
690 
691    if( busy )                         EXRETURN;  /* routine already busy */
692    if( glock == 0 )                   EXRETURN;  /* nothing to do */
693    if( !IM3D_OPEN(im3d) )             EXRETURN;  /* bad input */
694    if( GLOBAL_library.ignore_lock )   EXRETURN;  /* ordered not to do anything */
695    if( !AFNI_check_range_lock() )     EXRETURN;  /* not locked? */
696 
697    ii = AFNI_controller_index(im3d);             /* which one am I? */
698 
699    if( ii < 0 )                       EXRETURN;  /* nobody? bad input! */
700    if( ((1<<ii) & glock) == 0 )       EXRETURN;  /* input not locked */
701 
702    /* get range of this controller */
703 
704    val = im3d->vinfo->fim_range ;
705    if( val <= 0.0 )                   EXRETURN;  /* shouldn't happen */
706 
707    /* count how many OTHER controllers are are open and locked;
708       if none of them are, there is nothing to do [29 Apr 2005] */
709 
710    for( nn=cc=0 ; cc < MAX_CONTROLLERS ; cc++ ){
711      qq3d = GLOBAL_library.controllers[cc] ;
712      if( qq3d != im3d && IM3D_OPEN(qq3d) && ((1<<cc) & glock) != 0 ) nn++ ;
713    }
714    if( nn < 1 )                       EXRETURN ;
715 
716    /* something to do? */
717 
718    busy = 1 ;  /* don't let this routine be called recursively */
719 
720    /* loop through other controllers:
721         for those that ARE open, and ARE locked, set the new range */
722 
723    for( cc=0 ; cc < MAX_CONTROLLERS ; cc++ ){
724 
725      qq3d = GLOBAL_library.controllers[cc] ; /* controller */
726 
727      if( IM3D_OPEN(qq3d) && ((1<<cc) & glock) != 0 ){  /* open and locked */
728 
729        if( qq3d == im3d &&    /* no need to set current if not autoRanged */
730            MCW_val_bbox(im3d->vwid->func->range_bbox) == 0 ) continue;
731 
732        sprintf( cmd , "SET_FUNC_RANGE %c.%.6f" , 'A'+cc , val ) ;
733        AFNI_driver( cmd ) ;
734      }
735    }
736 
737    busy = 0 ;  /* OK, let this routine be activated again */
738    EXRETURN ;
739 }
740 
741 /*------------------------------------------------------------------------*/
742 
AFNI_set_all_rnglock_bboxes(Three_D_View * im3d,int bval)743 void AFNI_set_all_rnglock_bboxes(Three_D_View *im3d, int bval)
744 {
745    int ii;
746    Three_D_View *qq3d ;
747 
748    if( bval < 0 || bval > 1 )
749      bval = MCW_val_bbox( im3d->vwid->dmode->rng_lock_bbox ) ;
750 
751    /* set all other controller lock boxes to the same value */
752 
753    for( ii=0 ; ii < MAX_CONTROLLERS ; ii++ ){
754      qq3d = GLOBAL_library.controllers[ii] ;
755      if( qq3d == im3d || ! IM3D_VALID(qq3d) ) continue ;
756      MCW_set_bbox( qq3d->vwid->dmode->rng_lock_bbox , bval ) ;
757    }
758 
759    if( AFNI_check_range_lock() != bval )
760      AFNI_setenv( bval ? "AFNI_RANGE_LOCK=YES" : "AFNI_RANGE_LOCK=NO" ) ;
761 
762    return;
763 }
764 
765 /*------------------------------------------------------------------------*/
766 
AFNI_func_rnglock_change_CB(Widget w,XtPointer cd,XtPointer calld)767 void AFNI_func_rnglock_change_CB( Widget w , XtPointer cd , XtPointer calld )
768 {
769    Three_D_View *im3d = (Three_D_View *)cd ;
770    int           bval , bold ;
771 
772 ENTRY("AFNI_func_rnglock_change_CB") ;
773 
774    if( ! IM3D_VALID(im3d) ) EXRETURN ;
775 
776    bold = AFNI_check_range_lock() ;
777    bval = MCW_val_bbox( im3d->vwid->dmode->rng_lock_bbox ) ;
778 
779    if( bval == bold ) EXRETURN ;                     /* same --> nothing to do */
780 
781    /* New value ==> apply it to other controllers */
782 
783    AFNI_set_all_rnglock_bboxes(im3d,bval);
784    AFNI_range_lock_carryout(im3d) ;
785 
786    EXRETURN ;
787 }
788 
789 /*------------------------------------------------------------------------*/
790 
AFNI_set_all_pbarlock_bboxes(Three_D_View * im3d,int bval)791 void AFNI_set_all_pbarlock_bboxes(Three_D_View *im3d, int bval)
792 {
793    int ii;
794    Three_D_View *qq3d ;
795 
796    if( bval < 0 || bval > 1 )
797      bval = MCW_val_bbox( im3d->vwid->dmode->pbar_lock_bbox ) ;
798 
799    /* set all other controller lock boxes to the same value */
800 
801    for( ii=0 ; ii < MAX_CONTROLLERS ; ii++ ){
802      qq3d = GLOBAL_library.controllers[ii] ;
803      if( qq3d == im3d || ! IM3D_VALID(qq3d) ) continue ;
804      MCW_set_bbox( qq3d->vwid->dmode->pbar_lock_bbox , bval ) ;
805    }
806 
807    if( AFNI_check_pbar_lock() != bval )
808      AFNI_setenv( bval ? "AFNI_PBAR_LOCK=YES" : "AFNI_PBAR_LOCK=NO" ) ;
809 
810    return;
811 }
812 
813 /*------------------------------------------------------------------------*/
814 
AFNI_func_pbarlock_change_CB(Widget w,XtPointer cd,XtPointer calld)815 void AFNI_func_pbarlock_change_CB( Widget w , XtPointer cd , XtPointer calld )
816 {
817    Three_D_View *im3d = (Three_D_View *)cd ;
818    int           bval , bold ;
819 
820 ENTRY("AFNI_func_pbarlock_change_CB") ;
821 
822    if( ! IM3D_VALID(im3d) ) EXRETURN ;
823 
824    bold = AFNI_check_pbar_lock() ;
825    bval = MCW_val_bbox( im3d->vwid->dmode->pbar_lock_bbox ) ;
826 
827    if( bval == bold ) EXRETURN ;                     /* same --> nothing to do */
828 
829    /* New value ==> apply it to other controllers */
830 
831    AFNI_set_all_pbarlock_bboxes(im3d,bval);
832    AFNI_pbar_lock_carryout(im3d) ;
833 
834    EXRETURN ;
835 }
836 
837 /*-----------------------------------------------------------------------
838     10 Dec 2019: zoom/pan locking on or off
839 -------------------------------------------------------------------------*/
840 
AFNI_zoompan_lock_change_CB(Widget w,XtPointer cd,XtPointer calld)841 void AFNI_zoompan_lock_change_CB( Widget w , XtPointer cd , XtPointer calld )
842 {
843    Three_D_View *im3d = (Three_D_View *)cd ;
844    Three_D_View *qq3d ;
845    int           bval , ii , bold ;
846 
847 ENTRY("AFNI_zoompan_lock_change_CB") ;
848 
849    if( ! IM3D_VALID(im3d) ) EXRETURN ;
850 
851    /* get current global setting and compare to changed lock box */
852 
853    bold = GLOBAL_library.zoompan_lock ;
854    bval = MCW_val_bbox( im3d->vwid->dmode->zoompan_lock_bbox ) ;
855    if( bval == bold ) EXRETURN ;                     /* same --> nothing to do */
856 
857    /* new value --> save in global setting */
858 
859    GLOBAL_library.zoompan_lock = bval ;
860 
861    /* set all other controller lock boxes to the same value */
862 
863    for( ii=0 ; ii < MAX_CONTROLLERS ; ii++ ){
864      qq3d = GLOBAL_library.controllers[ii] ;
865      if( qq3d == im3d || ! IM3D_VALID(qq3d) ) continue ;
866 
867      MCW_set_bbox( qq3d->vwid->dmode->zoompan_lock_bbox , bval ) ;
868    }
869    RESET_AFNI_QUIT(im3d) ;
870    EXRETURN ;
871 }
872 
873 /*------------------------------------------------------------------------*/
874 /* Locking for the zoom+pan image viewers [10 Dec 2019] */
875 
AFNI_zoompan_lock_carryout(Three_D_View * im3d)876 void AFNI_zoompan_lock_carryout( Three_D_View *im3d )
877 {
878    static int busy = 0 ;  /* !=0 if this routine is "busy" */
879    Three_D_View *qq3d ;
880    MCW_imseq *seq ;
881    int ii,jj,kk , cc , glock ;
882    int axi_zlev=0 ; float axi_poff[2] ;
883    int sag_zlev=0 ; float sag_poff[2] ;
884    int cor_zlev=0 ; float cor_poff[2] ;
885 
886 ENTRY("AFNI_zoompan_locks_carryout") ;
887 
888    if( busy || !IM3D_VALID(im3d)    ) EXRETURN ;
889    if( GLOBAL_library.ignore_lock   ) EXRETURN ;
890    if( !GLOBAL_library.zoompan_lock ) EXRETURN ;
891    if( !IM3D_IMAGIZED(im3d)         ) EXRETURN ;
892 
893    glock = GLOBAL_library.controller_lock ;      /* not a handgun */
894    if( glock == 0 )                   EXRETURN ; /* nothing to do */
895 
896    ii = AFNI_controller_index(im3d) ;            /* which one am I? */
897 
898    if( ii < 0 )                       EXRETURN ; /* nobody? bad input! */
899    if( ((1<<ii) & glock) == 0 )       EXRETURN ; /* input not locked */
900 
901    /* something to do? */
902 
903    busy = 1 ;  /* don't let this routine be called recursively */
904 
905    /* find the zoom and pan parameters for the current image viewers */
906 
907    seq = IM3D_AXIALIMAGE(im3d) ;
908    if( seq != NULL ){
909      drive_MCW_imseq( seq, isqDR_get_zoom  , &axi_zlev ) ;
910      drive_MCW_imseq( seq, isqDR_get_panoff, axi_poff  ) ;
911    }
912 
913    seq = IM3D_SAGITTALIMAGE(im3d) ;
914    if( seq != NULL ){
915      drive_MCW_imseq( seq, isqDR_get_zoom  , &sag_zlev ) ;
916      drive_MCW_imseq( seq, isqDR_get_panoff, sag_poff  ) ;
917    }
918 
919    seq = IM3D_CORONALIMAGE(im3d) ;
920    if( seq != NULL ){
921      drive_MCW_imseq( seq, isqDR_get_zoom  , &cor_zlev ) ;
922      drive_MCW_imseq( seq, isqDR_get_panoff, cor_poff  ) ;
923    }
924 
925    /* loop through other controllers:
926         for those that ARE open, ARE NOT the current one,
927         and ARE locked, set zoom and pan to match
928         this controller's corresponding image viewers */
929 
930    for( cc=0 ; cc < MAX_CONTROLLERS ; cc++ ){
931 
932      qq3d = GLOBAL_library.controllers[cc] ; /* controller */
933 
934      if( IM3D_OPEN(qq3d) && qq3d != im3d && ((1<<cc) & glock) != 0 ){
935 
936        seq = IM3D_AXIALIMAGE(qq3d) ;
937        if( seq != NULL ){
938          drive_MCW_imseq( seq, isqDR_set_zoom  , &axi_zlev ) ;
939          drive_MCW_imseq( seq, isqDR_set_panoff, axi_poff  ) ;
940        }
941 
942        seq = IM3D_SAGITTALIMAGE(qq3d) ;
943        if( seq != NULL ){
944          drive_MCW_imseq( seq, isqDR_set_zoom  , &sag_zlev ) ;
945          drive_MCW_imseq( seq, isqDR_set_panoff, sag_poff  ) ;
946        }
947 
948        seq = IM3D_CORONALIMAGE(qq3d) ;
949        if( seq != NULL ){
950          drive_MCW_imseq( seq, isqDR_set_zoom  , &cor_zlev ) ;
951          drive_MCW_imseq( seq, isqDR_set_panoff, cor_poff  ) ;
952        }
953      }
954    }
955 
956    busy = 0 ;  /* OK, let this routine be activated again */
957    EXRETURN ;
958 }
959 
960 /*------------------------------------------------------------------------*/
961 /* Enforce all locks at the same time [03 Jul 2014] */
962 
AFNI_all_locks_carryout(Three_D_View * im3d)963 void AFNI_all_locks_carryout( Three_D_View *im3d )
964 {
965    static int busy = 0 ;  /* !=0 if this routine is "busy" */
966 
967 ENTRY("AFNI_all_locks_carryout") ;
968 
969    if( busy || !IM3D_VALID(im3d)  ) EXRETURN ;
970    if( GLOBAL_library.ignore_lock ) EXRETURN ;
971 
972 #if 0
973 INFO_message("AFNI_all_locks_carryout: im3d index = %d",AFNI_controller_index(im3d)) ;
974 #endif
975 
976    AFNI_space_lock_carryout  ( im3d ) ;
977    AFNI_time_lock_carryout   ( im3d ) ;
978    AFNI_thresh_lock_carryout ( im3d ) ;
979    AFNI_pbar_lock_carryout   ( im3d ) ;
980    AFNI_range_lock_carryout  ( im3d ) ;
981    AFNI_zoompan_lock_carryout( im3d ) ; /* 10 Dec 2019 */
982 
983    AFNI_sleep(1) ; busy = 0 ; EXRETURN ;
984 }
985