00001 
00002 #include "SUMA_suma.h"
00003 
00004 extern SUMA_CommonFields *SUMAg_CF;
00005 extern int SUMAg_N_DOv; 
00006 extern SUMA_DO *SUMAg_DOv;
00007 extern SUMA_SurfaceViewer *SUMAg_SVv;
00008 extern int SUMAg_N_SVv;
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 int SUMA_WhichViewerInMomentum(SUMA_SurfaceViewer *SVv, int N_SV, SUMA_SurfaceViewer *sv) 
00030 {
00031    static char FuncName[]={"SUMA_WhichViewerInMomentum"};
00032    int ii = -1;
00033    
00034    SUMA_ENTRY;
00035    
00036    if (!SVv) SUMA_RETURN(-1);
00037    
00038    for (ii=0; ii < SUMAg_N_SVv; ++ii) {
00039          if (SVv[ii].GVS[SVv[ii].StdView].ApplyMomentum) {
00040             if (!sv) { 
00041                SUMA_RETURN(ii);
00042             } else if (&(SUMAg_SVv[ii]) != sv) { 
00043                SUMA_RETURN(ii);
00044             }
00045          }
00046    }
00047    
00048    SUMA_RETURN(-1);
00049    
00050 }
00051  
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 SUMA_Boolean SUMA_LockEnum_LockType (SUMA_LINK_TYPES i, char *Name)
00062 {
00063    static char FuncName[]={"SUMA_LockEnum_LockType"};
00064    SUMA_ENTRY;   
00065    
00066    switch (i) {
00067       case SUMA_No_Lock:
00068          sprintf (Name, "No Lock");
00069          break;
00070       case SUMA_I_Lock:
00071          sprintf (Name, "Index Lock");
00072          break;
00073       case SUMA_XYZ_Lock:
00074          sprintf (Name, "XYZ Lock");
00075          break;
00076       default:
00077          sprintf (Name, "?");
00078          SUMA_RETURN (NOPE);
00079          
00080    }
00081    
00082    SUMA_RETURN (YUP);
00083 }
00084 
00085 
00086 
00087 SUMA_SurfaceViewer *SUMA_Alloc_SurfaceViewer_Struct (int N)
00088 {
00089    SUMA_SurfaceViewer *SV, *SVv;
00090    static char FuncName[]={"SUMA_Alloc_SurfaceViewer_Struct"};
00091    int i, j, n;
00092    
00093    SUMA_ENTRY;
00094 
00095    SVv =  (SUMA_SurfaceViewer *)SUMA_malloc(sizeof(SUMA_SurfaceViewer)*N);
00096    if (SVv == NULL) {
00097       fprintf(SUMA_STDERR,"Error %s: Failed to SUMA_malloc SV\n", FuncName);
00098       SUMA_RETURN (NULL);
00099    }
00100    for (i=0; i < N; ++i) {
00101       SV = &(SVv[i]);
00102       
00103       SV->N_GVS = SUMA_N_STANDARD_VIEWS;
00104       SV->GVS = (SUMA_GEOMVIEW_STRUCT *)SUMA_malloc(sizeof(SUMA_GEOMVIEW_STRUCT)*SV->N_GVS);
00105       if (!SV->GVS) {
00106          fprintf(SUMA_STDERR,"Error %s: Could not allocate for N_GVS.\n", FuncName);
00107          SUMA_RETURN (NULL);
00108       }
00109       SV->StdView = SUMA_3D; 
00110       
00111       
00112       SV->verbose = 1;
00113       {
00114          char *eee = getenv("SUMA_AdjustMouseMotionWithZoom");
00115          if (eee) {
00116             if (strcmp (eee, "YES") == 0) SV->ZoomCompensate = 1.0;
00117             else SV->ZoomCompensate = 0.0;
00118          } else {
00119             SV->ZoomCompensate = 1.0; 
00120          }
00121       }
00122       {
00123          char *eee = getenv("SUMA_ViewOrthographicProjection");
00124          if (eee) {
00125             if (strcmp (eee, "YES") == 0) SV->ortho = 1;
00126             else SV->ortho = 0;
00127          } else {
00128             SV->ortho = 0; 
00129          }
00130       }
00131 
00132       SV->Aspect = 1.0;
00133       SV->FOV = NULL;
00134       for (j=0; j < SV->N_GVS; ++j) {
00135          switch (j) {
00136             case SUMA_2D_Z0:
00137                SV->GVS[j].currentQuat[0] = 0.252199;
00138                SV->GVS[j].currentQuat[1] = -0.129341;
00139                SV->GVS[j].currentQuat[2] = -0.016295;
00140                SV->GVS[j].currentQuat[3] = 0.958854;
00141 
00142                SV->GVS[j].ApplyMomentum = False;
00143 
00144                SV->GVS[j].MinIdleDelta = 1;
00145                SV->GVS[j].TranslateGain = TRANSLATE_GAIN;
00146                SV->GVS[j].ArrowtranslateDeltaX = ARROW_TRANSLATE_DELTAX;
00147                SV->GVS[j].ArrowtranslateDeltaY = ARROW_TRANSLATE_DELTAY;
00148 
00149                SV->GVS[j].ViewCamUp[0] = 0.0;
00150                SV->GVS[j].ViewCamUp[1] = 1.0;
00151                SV->GVS[j].ViewCamUp[2] = 0.0;
00152 
00153                SV->GVS[j].ViewFrom[0] = 0.0;
00154                SV->GVS[j].ViewFrom[1] = 0.0;
00155                SV->GVS[j].ViewFrom[2] = SUMA_DEFAULT_VIEW_FROM;
00156 
00157                SV->GVS[j].ViewCenter[0] = 0.0;
00158                SV->GVS[j].ViewCenter[1] = 0.0;
00159                SV->GVS[j].ViewCenter[2] = 0.0;
00160 
00161                SV->GVS[j].RotaCenter[0] = 0.0;
00162                SV->GVS[j].RotaCenter[1] = 0.0;
00163                SV->GVS[j].RotaCenter[2] = 0.0;
00164                break;
00165             case SUMA_3D:
00166                SV->GVS[j].currentQuat[0] = 0.252199;
00167                SV->GVS[j].currentQuat[1] = -0.129341;
00168                SV->GVS[j].currentQuat[2] = -0.016295;
00169                SV->GVS[j].currentQuat[3] = 0.958854;
00170 
00171                SV->GVS[j].ApplyMomentum = False;
00172 
00173                SV->GVS[j].MinIdleDelta = 1;
00174                SV->GVS[j].TranslateGain = TRANSLATE_GAIN;
00175                SV->GVS[j].ArrowtranslateDeltaX = ARROW_TRANSLATE_DELTAX;
00176                SV->GVS[j].ArrowtranslateDeltaY = ARROW_TRANSLATE_DELTAY;
00177 
00178                SV->GVS[j].ViewCamUp[0] = 0.0;
00179                SV->GVS[j].ViewCamUp[1] = 1.0;
00180                SV->GVS[j].ViewCamUp[2] = 0.0;
00181 
00182                SV->GVS[j].ViewFrom[0] = 0.0;
00183                SV->GVS[j].ViewFrom[1] = 0.0;
00184                SV->GVS[j].ViewFrom[2] = 0.0;
00185 
00186                SV->GVS[j].ViewCenter[0] = 0.0;
00187                SV->GVS[j].ViewCenter[1] = 0.0;
00188                SV->GVS[j].ViewCenter[2] = 0.0;
00189 
00190                SV->GVS[j].RotaCenter[0] = 0.0;
00191                SV->GVS[j].RotaCenter[1] = 0.0;
00192                SV->GVS[j].RotaCenter[2] = 0.0;
00193                
00194                SV->GVS[j].translateVec[0] = 0.0;
00195                SV->GVS[j].translateVec[1] = 0.0;
00196                break;
00197             default:
00198                fprintf(SUMA_STDERR,"Error %s: Undefined viewing mode.\n", FuncName);
00199                SUMA_RETURN (NULL);
00200                
00201          }
00202       }
00203       
00204 
00205       SV->light0_position[0] = 0.0;
00206       SV->light0_position[1] = 0.0;
00207       
00208       SV->light0_position[2] = 1.0 * SUMA_INTITIAL_LIGHT0_SWITCH; 
00209       SV->light0_position[3] = 0.0;
00210 
00211       SV->light1_position[0] = 1.0;
00212       SV->light1_position[1] = 1.0;
00213       SV->light1_position[2] = 1.0;
00214       SV->light1_position[3] = 0.0;
00215 
00216       {
00217          static SUMA_Boolean err = NOPE;
00218          float fv3[3];
00219          char *eee = getenv("SUMA_BackgroundColor");
00220          if (eee && !err) {
00221             if (SUMA_StringToNum (eee, fv3, 3) != 3) { 
00222                err = YUP;
00223                SUMA_SL_Err("Syntax error in environment\n"
00224                            "variable SUMA_BackgroundColor");
00225                SV->clear_color[0] = SUMA_CLEAR_COLOR_R;
00226                SV->clear_color[1] = SUMA_CLEAR_COLOR_G;
00227                SV->clear_color[2] = SUMA_CLEAR_COLOR_B;
00228                SV->clear_color[3] = SUMA_CLEAR_COLOR_A;
00229             }else {
00230                SV->clear_color[0] = fv3[0];
00231                SV->clear_color[1] = fv3[1];
00232                SV->clear_color[2] = fv3[2];
00233                SV->clear_color[3] = SUMA_CLEAR_COLOR_A;  
00234             }
00235          }else {
00236             SV->clear_color[0] = SUMA_CLEAR_COLOR_R;
00237             SV->clear_color[1] = SUMA_CLEAR_COLOR_G;
00238             SV->clear_color[2] = SUMA_CLEAR_COLOR_B;
00239             SV->clear_color[3] = SUMA_CLEAR_COLOR_A;   
00240          } 
00241       }
00242       
00243       
00244       SV->WindWidth = 350;
00245       SV->WindHeight = 350;
00246       {
00247          char *eee = getenv("SUMA_ArrowRotAngle");
00248          if (eee) {
00249             float rotval = strtod(eee, NULL);
00250             if (rotval > 0.0 && rotval < 360.0) SV->ArrowRotationAngle = SUMA_PI * rotval / 180.0;
00251             else SV->ArrowRotationAngle = SUMA_PI * ARROW_ROTATION_ANGLE_DEG / 180.0;
00252          } else SV->ArrowRotationAngle = SUMA_PI * ARROW_ROTATION_ANGLE_DEG / 180.0;
00253       }
00254       
00255       SV->Open = NOPE;
00256       
00257       SV->RegisteredDO = (int *)SUMA_calloc( SUMA_MAX_DISPLAYABLE_OBJECTS, sizeof(int));
00258       if (SV->RegisteredDO == NULL) {
00259          fprintf(stderr,"Error SUMA_Alloc_SurfaceViewer_Struct: Failed to SUMA_malloc SV->RegisteredDO\n");
00260          SUMA_RETURN (NULL);
00261       }
00262       SV->N_DO = 0; 
00263 
00264       SV->ColList = (SUMA_COLORLIST_STRUCT *) SUMA_malloc( sizeof(SUMA_COLORLIST_STRUCT) * SUMA_MAX_DISPLAYABLE_OBJECTS);
00265       SV->N_ColList = 0; 
00266       
00267       for (j=0; j<SUMA_MAX_DISPLAYABLE_OBJECTS; ++j) {
00268          SV->ColList[j].idcode_str = NULL;
00269          SV->ColList[j].glar_ColorList = NULL;
00270          SV->ColList[j].N_glar_ColorList = 0;
00271          SV->ColList[j].Remix = NOPE;
00272       }
00273       
00274       
00275       SV->ShowEyeAxis = 1;
00276       SV->ShowMeshAxis = 0;      
00277       SV->ShowWorldAxis = SUMA_NO_WAX;
00278       
00279       
00280       SV->WAx = SUMA_Alloc_Axis ("Viewer World Axis");
00281 
00282       if (SV->WAx == NULL) {
00283          fprintf(SUMA_STDERR,"Error %s: Error Allocating axis\n", FuncName);
00284          SUMA_RETURN(NULL);
00285       }
00286       SV->WAx->type = SUMA_SCALE_BOX;
00287 
00288       SV->Ch = SUMA_Alloc_CrossHair ();
00289       if (SV->Ch == NULL) {
00290          fprintf(stderr,"Error SUMA_Alloc_SurfaceViewer_Struct: Failed in SUMA_Alloc_CrossHair\n");
00291          SUMA_RETURN (NULL); 
00292       } else SV->ShowCrossHair = 1;
00293       
00294       SV->X = (SUMA_X *)SUMA_malloc(sizeof(SUMA_X));
00295       if (SV->X == NULL) {
00296          fprintf(stderr,"Error SUMA_Alloc_SurfaceViewer_Struct: Failed to SUMA_malloc SV->X\n");
00297          SUMA_RETURN (NULL);
00298       }
00299 
00300       SV->X->Title = NULL;
00301       SV->X->LookAt_prmpt = NULL;
00302       SV->X->JumpIndex_prmpt = NULL;
00303       SV->X->JumpXYZ_prmpt = NULL;
00304       SV->X->JumpFocusNode_prmpt = NULL;
00305       SV->X->JumpFocusFace_prmpt = NULL;
00306       SV->X->HighlightBox_prmpt = NULL;
00307       SV->X->TOPLEVEL = NULL;
00308       SV->X->MOMENTUMID = 0;
00309       SV->X->REDISPLAYPENDING = 0;
00310       SV->X->DOUBLEBUFFER = True;
00311       SV->X->WIDTH = SV->X->HEIGHT = 300; 
00312       SV->X->ViewCont = SUMA_CreateViewContStruct();
00313       
00314       SV->Focus_SO_ID = -1;
00315       SV->Focus_DO_ID = -1;
00316       
00317       SV->VSv = NULL;
00318       SV->N_VSv = 0;
00319       SV->LastNonMapStateID = -1;
00320       
00321       SV->iCurGroup = -1;
00322       SV->CurGroupName = NULL;
00323       
00324       SV->PolyMode = SRM_Fill;
00325       
00326       #if SUMA_BACKFACE_CULL
00327          SV->BF_Cull = YUP;
00328       #else
00329          SV->BF_Cull = NOPE;
00330       #endif
00331 
00332       SV->ShowForeground = YUP;
00333       SV->ShowBackground = YUP;
00334       
00335       {
00336          char *eee = getenv("SUMA_CenterOnPatch");
00337          if (eee) {
00338             if (strcmp (eee, "YES") == 0) SV->UsePatchDims = YUP;
00339             else SV->UsePatchDims = NOPE;
00340          } else {
00341             SV->UsePatchDims = NOPE;
00342          }
00343       }
00344       SV->Back_Modfact = SUMA_BACKGROUND_MODULATION_FACTOR;
00345       
00346       SV->isShaded = NOPE; 
00347       
00348       SV->LinkAfniCrossHair = YUP;
00349       
00350       SV->ResetGLStateVariables = YUP;
00351       SV->NewGeom = NOPE;
00352       SV->BS = NULL;
00353       
00354       SV->ShowRight = YUP;
00355       SV->ShowLeft = YUP;
00356       SV->Record = NOPE;
00357       SV->rdc = SUMA_RDC_NOT_SET;
00358    }
00359    SUMA_RETURN (SVv);
00360 }
00361 
00362 SUMA_Boolean SUMA_Free_SurfaceViewer_Struct (SUMA_SurfaceViewer *SV)
00363 {
00364    static char FuncName[]={"SUMA_Free_SurfaceViewer_Struct"};
00365    int i;
00366    
00367    SUMA_ENTRY;
00368 
00369    if (SV->WAx) SUMA_Free_Axis(SV->WAx);
00370    if (SV->Ch) SUMA_Free_CrossHair (SV->Ch);
00371    if (SV->X->Title) SUMA_free(SV->X->Title);
00372    if (SV->X->LookAt_prmpt) SUMA_FreePromptDialogStruct (SV->X->LookAt_prmpt);
00373    if (SV->X->JumpIndex_prmpt) SUMA_FreePromptDialogStruct (SV->X->JumpIndex_prmpt);
00374    if (SV->X->JumpXYZ_prmpt) SUMA_FreePromptDialogStruct (SV->X->JumpXYZ_prmpt);
00375    if (SV->X->JumpFocusNode_prmpt) SUMA_FreePromptDialogStruct (SV->X->JumpFocusNode_prmpt);
00376    if (SV->X->JumpFocusFace_prmpt) SUMA_FreePromptDialogStruct (SV->X->JumpFocusFace_prmpt);
00377    if (SV->X->HighlightBox_prmpt) SUMA_FreePromptDialogStruct (SV->X->HighlightBox_prmpt);
00378    if (SV->X->ViewCont) SUMA_FreeViewContStruct(SV->X->ViewCont);
00379    if (SV->X) SUMA_free(SV->X);
00380    if (SV->RegisteredDO) SUMA_free(SV->RegisteredDO);
00381    if (SV->VSv) {
00382       for (i=0; i < SV->N_VSv; ++i) {
00383          if (!SUMA_Free_ViewState (&(SV->VSv[i]))) {
00384             fprintf (SUMA_STDERR,"Error %s: failed in SUMA_Free_ViewState.\n", FuncName);
00385          }
00386       }
00387    }
00388    
00389    if (SV->CurGroupName) SUMA_free(SV->CurGroupName); SV->CurGroupName= NULL;
00390    
00391    if (SV->GVS) SUMA_free(SV->GVS);
00392    if (SV->State) SV->State = NULL;  
00393    if (SV->ColList) {
00394       for (i=0; i < SV->N_ColList; ++i) {
00395          if (!SUMA_EmptyColorList (SV, NULL)) fprintf (SUMA_STDERR,"Error %s: failed in SUMA_EmptyColorList.\n", FuncName);
00396       }
00397       
00398       SUMA_free(SV->ColList); 
00399       SV->ColList = NULL; 
00400       SV->N_ColList = 0;
00401    }
00402    
00403    if (SV->BS) {
00404       SUMA_EmptyDestroyList(SV->BS);
00405    }
00406    
00407    SUMA_RETURN(YUP);
00408 }
00409 
00410 SUMA_Boolean SUMA_Free_SurfaceViewer_Struct_Vect (SUMA_SurfaceViewer *SVv, int N)
00411 {
00412    static char FuncName[]={"SUMA_Free_SurfaceViewer_Struct_Vect"};
00413    int i;
00414    SUMA_Boolean Ret= YUP;
00415    
00416    SUMA_ENTRY;
00417 
00418    for (i=0; i < N; ++i)  {
00419       if (&SVv[i] != NULL) {
00420          Ret = Ret * SUMA_Free_SurfaceViewer_Struct (&SVv[i]);
00421       }
00422    }
00423    
00424    if (SVv) SUMA_free(SVv);
00425    SUMA_RETURN(Ret);
00426 }
00427 
00428 
00429 
00430 
00431 
00432 
00433 
00434 
00435 
00436 
00437 
00438 
00439 
00440 
00441 SUMA_Boolean SUMA_FillColorList (SUMA_SurfaceViewer *sv, SUMA_SurfaceObject *SO)
00442 {
00443    static char FuncName[]={"SUMA_FillColorList"};
00444    int i;
00445    SUMA_Boolean LocalHead = NOPE;
00446    
00447    SUMA_ENTRY;
00448    
00449    if (LocalHead) fprintf (SUMA_STDERR,"%s: Filling a color list for surface %s (%s).\n", FuncName, SO->Label, SO->idcode_str);
00450 
00451    if (!SO->idcode_str) {
00452       fprintf (SUMA_STDERR,"Error %s: SO->idcode_str is NULL.\n", FuncName);
00453       SUMA_RETURN (NOPE);
00454    }
00455    
00456    
00457    for (i=0; i<sv->N_ColList; ++i) {
00458       if (strcmp (SO->idcode_str, sv->ColList[i].idcode_str) == 0) {
00459          fprintf (SUMA_STDERR,"Error %s: SO->idcode_str is already in sv->ColList.\n", FuncName);
00460          SUMA_RETURN (NOPE);
00461       }
00462    }
00463    
00464    
00465    if (sv->ColList[sv->N_ColList].glar_ColorList) {
00466       fprintf (SUMA_STDERR,"Error %s: glar_ColorList is not NULL. Cannot reallocate.\n", FuncName);
00467       SUMA_RETURN (NOPE);
00468    }
00469    
00470    SUMA_LH("Pre-alloc\n");
00471    sv->ColList[sv->N_ColList].glar_ColorList = (GLfloat *) SUMA_calloc (SO->N_Node*4, sizeof(GLfloat));
00472    sv->ColList[sv->N_ColList].idcode_str = (char *)SUMA_malloc((strlen(SO->idcode_str)+1) * sizeof(char));
00473    SUMA_LH("Post-alloc\n");
00474    
00475    if (!sv->ColList[sv->N_ColList].glar_ColorList || !sv->ColList[sv->N_ColList].idcode_str) {
00476       fprintf (SUMA_STDERR,"Error %s: Failed to allocate for glar_ColorList or idcode_str.\n", FuncName);
00477       SUMA_RETURN (NOPE);
00478    }
00479    
00480    sv->ColList[sv->N_ColList].idcode_str = strcpy (sv->ColList[sv->N_ColList].idcode_str, SO->idcode_str);
00481    if (LocalHead) fprintf (SUMA_STDERR, "%s: sv->ColList[%d].idcode_str=%s is about to be filled.\n", \
00482                FuncName, sv->N_ColList, sv->ColList[sv->N_ColList].idcode_str);
00483 
00484    
00485    sv->ColList[sv->N_ColList].N_glar_ColorList = SO->N_Node*4;
00486    i=0;
00487    while (i < sv->ColList[sv->N_ColList].N_glar_ColorList) {
00488       sv->ColList[sv->N_ColList].glar_ColorList[i] = SUMA_GRAY_NODE_COLOR; ++i;
00489       sv->ColList[sv->N_ColList].glar_ColorList[i] = SUMA_GRAY_NODE_COLOR; ++i;
00490       sv->ColList[sv->N_ColList].glar_ColorList[i] = SUMA_GRAY_NODE_COLOR; ++i;
00491       sv->ColList[sv->N_ColList].glar_ColorList[i] = SUMA_NODE_ALPHA; ++i;
00492    }
00493    sv->ColList[sv->N_ColList].Remix = YUP; 
00494 
00495    ++sv->N_ColList;
00496    
00497    SUMA_RETURN (YUP);
00498 
00499 }
00500 
00501 
00502 
00503 
00504 
00505 
00506 
00507 
00508 
00509 GLfloat * SUMA_GetColorList (SUMA_SurfaceViewer *sv, char *DO_idstr)
00510 {
00511    static char FuncName[]={"SUMA_GetColorList"};
00512    int i;
00513    GLfloat * glar_ColorList = NULL;
00514    SUMA_Boolean Found = NOPE;
00515    
00516    SUMA_ENTRY;
00517    
00518    if (!DO_idstr) {
00519       fprintf (SUMA_STDERR,"Error %s: DO_idstr is NULL, this should not be.\n", FuncName);
00520       SUMA_RETURN (NULL);
00521    }
00522    
00523    
00524    Found = NOPE;
00525    i = 0;
00526    while (!Found && i < sv->N_ColList) {
00527       if (strcmp (DO_idstr, sv->ColList[i].idcode_str) == 0) {
00528          Found = YUP;
00529          SUMA_RETURN (sv->ColList[i].glar_ColorList);      
00530       }
00531       ++i;
00532    }
00533    
00534    if (!Found) {
00535       fprintf (SUMA_STDERR,"Error %s: DO_idstr was not found.\n", FuncName);
00536       SUMA_RETURN (NULL);
00537    }
00538    
00539    
00540    fprintf (SUMA_STDERR,"Error %s: Logic error. Should not get here.\n", FuncName);
00541    SUMA_RETURN (NULL);
00542 
00543 }
00544 
00545 
00546 
00547 
00548 
00549 
00550 
00551 
00552 
00553 
00554 
00555 
00556 
00557 SUMA_Boolean SUMA_EmptyColorList (SUMA_SurfaceViewer *sv, char *DO_idstr)
00558 {
00559    static char FuncName[]={"SUMA_EmptyColorList"};
00560    int i;
00561    SUMA_Boolean Found = NOPE;
00562    
00563    SUMA_ENTRY;
00564    
00565    if (!sv->ColList) {
00566       fprintf (SUMA_STDERR,"Error %s: sv->ColList is NULL, this should not be.\n", FuncName);
00567       SUMA_RETURN (NOPE);
00568    } 
00569    
00570    if (!DO_idstr) {
00571       
00572       for (i=0; i < sv->N_ColList; ++i) {
00573          if (sv->ColList[i].glar_ColorList) SUMA_free(sv->ColList[i].glar_ColorList);
00574          sv->ColList[i].glar_ColorList = NULL;
00575          sv->ColList[i].N_glar_ColorList = 0;
00576          if (sv->ColList[i].idcode_str) SUMA_free(sv->ColList[i].idcode_str); 
00577          sv->ColList[i].idcode_str = NULL;
00578          sv->ColList[i].Remix = NOPE;
00579       }   
00580    } else { 
00581       Found = NOPE;
00582       i = 0;
00583       while (!Found && i < sv->N_ColList) {
00584          if (strcmp (DO_idstr, sv->ColList[i].idcode_str) == 0) {
00585             Found = YUP;
00586             
00587             if (sv->ColList[i].glar_ColorList) SUMA_free(sv->ColList[i].glar_ColorList);
00588             sv->ColList[i].glar_ColorList = NULL;
00589             sv->ColList[i].N_glar_ColorList = 0;
00590             if (sv->ColList[i].idcode_str) SUMA_free(sv->ColList[i].idcode_str); 
00591             sv->ColList[i].idcode_str = NULL;
00592             sv->ColList[i].Remix = NOPE;
00593             
00594             if (i < sv->N_ColList) {
00595                sv->ColList[i].glar_ColorList = sv->ColList[sv->N_ColList-1].glar_ColorList;
00596                sv->ColList[i].N_glar_ColorList = sv->ColList[sv->N_ColList-1].N_glar_ColorList;
00597                sv->ColList[i].idcode_str = sv->ColList[sv->N_ColList-1].idcode_str;
00598                sv->ColList[i].Remix = sv->ColList[sv->N_ColList-1].Remix;
00599                
00600                
00601                sv->ColList[sv->N_ColList-1].glar_ColorList = NULL;
00602                sv->ColList[sv->N_ColList-1].N_glar_ColorList = 0;
00603                sv->ColList[sv->N_ColList-1].idcode_str = NULL;
00604                sv->ColList[sv->N_ColList-1].Remix = NOPE;
00605                
00606                
00607                --sv->N_ColList;
00608             }
00609          } 
00610          ++i;
00611       }
00612       if (!Found) {
00613          fprintf (SUMA_STDERR,"Error %s: item %s was not found, this should not be.\n", FuncName, DO_idstr);
00614          SUMA_RETURN (NOPE);
00615       }
00616    }
00617    
00618    SUMA_RETURN (YUP);
00619 }
00620 
00621 
00622 
00623 
00624 
00625 
00626 
00627 
00628 
00629 
00630 
00631 SUMA_Boolean SUMA_SetShownLocalRemixFlag (SUMA_SurfaceViewer *sv)
00632 {
00633    static char FuncName[]={"SUMA_SetShownLocalRemixFlag"};
00634    int k;
00635       
00636    SUMA_ENTRY;
00637    
00638    for (k=0; k < sv->N_ColList; ++k) {
00639       sv->ColList[k].Remix = YUP;
00640    }
00641    
00642    SUMA_RETURN (YUP);
00643 }
00644 
00645 
00646 
00647 
00648 
00649 
00650 
00651 
00652 
00653 
00654 
00655 
00656 
00657 
00658 SUMA_Boolean SUMA_SetLocalRemixFlag (char *SO_idcode_str, SUMA_SurfaceViewer *sv)
00659 {  
00660    static char FuncName[]={"SUMA_SetLocalRemixFlag"};
00661    SUMA_SurfaceObject *SO1 = NULL, *SO2 = NULL;
00662    int k, kk, dov_id;   
00663    SUMA_Boolean Found = NOPE;
00664    
00665    SUMA_ENTRY;
00666    
00667    if (!SO_idcode_str || !sv) {
00668       fprintf (SUMA_STDERR,"Error %s: NULL sv or SO_idcode_str. BAD\n", FuncName);
00669       SUMA_RETURN (NOPE);
00670    }
00671 
00672    dov_id = SUMA_findSO_inDOv (SO_idcode_str, SUMAg_DOv, SUMAg_N_DOv);
00673    if (dov_id < 0) {
00674       fprintf (SUMA_STDERR,"Error %s: Failed to find object with idcode %s.\n", FuncName, SO_idcode_str);
00675       SUMA_RETURN (NOPE);
00676    }
00677    SO1 = (SUMA_SurfaceObject *)SUMAg_DOv[dov_id].OP;
00678    
00679    
00680    for (k=0; k < sv->N_DO; ++k) {
00681       SO2 = (SUMA_SurfaceObject *)SUMAg_DOv[sv->RegisteredDO[k]].OP;
00682       if (SUMA_isRelated (SO1, SO2, 1)) { 
00683          
00684          kk = 0;
00685          Found = NOPE;
00686          while (!Found && kk < sv->N_ColList) {
00687             if (strcmp (SO2->idcode_str, sv->ColList[kk].idcode_str) == 0) {
00688                Found = YUP;
00689                sv->ColList[kk].Remix = YUP;
00690             }
00691             ++kk;
00692          }
00693          if (!Found) {
00694             fprintf (SUMA_STDERR,"Error %s: Failed to find surface in ColList structs. BAD.\n", FuncName);
00695             SUMA_RETURN (NOPE);
00696          }
00697       }  
00698    } 
00699    
00700    SUMA_RETURN (YUP);
00701 }
00702 
00703 
00704 
00705 
00706 
00707 
00708 
00709 
00710 
00711 
00712 
00713 
00714 
00715 
00716 
00717 
00718 
00719 
00720 
00721 
00722 
00723 
00724 
00725 
00726 SUMA_Boolean SUMA_SetRemixFlag (char *SO_idcode_str, SUMA_SurfaceViewer *SVv, int N_SVv)
00727 {
00728    static char FuncName[]={"SUMA_SetRemixFlag"};
00729    SUMA_SurfaceViewer *sv;
00730    SUMA_SurfaceObject *SO1 = NULL, *SO2 = NULL;
00731    int i, k, kk, dov_id;   
00732    SUMA_Boolean Found = NOPE;
00733    SUMA_Boolean LocalHead = NOPE;
00734    
00735    SUMA_ENTRY;
00736    
00737    if (!SO_idcode_str || !SVv) {
00738       fprintf (SUMA_STDERR,"Error %s: NULL SVv or SO_idcode_str. BAD\n", FuncName);
00739       SUMA_RETURN (NOPE);
00740    }
00741    
00742    dov_id = SUMA_findSO_inDOv (SO_idcode_str, SUMAg_DOv, SUMAg_N_DOv);
00743    if (dov_id < 0) {
00744       fprintf (SUMA_STDERR,"Error %s: Failed to find object with idcode %s.\n", FuncName, SO_idcode_str);
00745       SUMA_RETURN (NOPE);
00746    }
00747    SO1 = (SUMA_SurfaceObject *)SUMAg_DOv[dov_id].OP;
00748    
00749    
00750    for (i=0; i < N_SVv; ++i) {
00751       if (LocalHead) fprintf (SUMA_STDERR,"%s: Searching viewer %d.\n", FuncName, i);
00752       sv = &(SVv[i]);
00753       
00754       for (k=0; k < sv->N_DO; ++k) {
00755          if (SUMA_isSO(SUMAg_DOv[sv->RegisteredDO[k]])) {
00756             SO2 = (SUMA_SurfaceObject *)SUMAg_DOv[sv->RegisteredDO[k]].OP;
00757             if (SUMA_isRelated (SO1, SO2, 1)) { 
00758                
00759                kk = 0;
00760                Found = NOPE;
00761                while (!Found && kk < sv->N_ColList) {
00762                   if (strcmp (SO2->idcode_str, sv->ColList[kk].idcode_str) == 0) {
00763                      Found = YUP;
00764                      sv->ColList[kk].Remix = YUP;
00765                   }
00766                   ++kk;
00767                }
00768                if (!Found) {
00769                   fprintf (SUMA_STDERR,"Error %s: Failed to find surface in ColList structs. BAD.\n", FuncName);
00770                   SUMA_RETURN (NOPE);
00771                }
00772             }
00773          }  
00774       } 
00775    }
00776    
00777    SUMA_RETURN (YUP);
00778 }
00779 
00780 
00781 
00782 
00783 
00784 
00785 
00786 
00787 SUMA_Boolean SUMA_SetAllRemixFlag (SUMA_SurfaceViewer *SVv, int N_SVv)
00788 {
00789    static char FuncName[]={"SUMA_SetAllRemixFlag"};
00790    SUMA_SurfaceViewer *sv;
00791    int i, kk;   
00792    SUMA_Boolean LocalHead = NOPE;
00793    
00794    SUMA_ENTRY;
00795    
00796    if (!SVv) {
00797       fprintf (SUMA_STDERR,"Error %s: NULL SVv . BAD\n", FuncName);
00798       SUMA_RETURN (NOPE);
00799    }
00800    
00801    
00802    for (i=0; i < N_SVv; ++i) {
00803       if (LocalHead) fprintf (SUMA_STDERR,"%s: Searching viewer %d.\n", FuncName, i);
00804       sv = &(SVv[i]);
00805       for (kk = 0; kk < sv->N_ColList; ++kk) sv->ColList[kk].Remix = YUP;
00806    }
00807    
00808    SUMA_RETURN (YUP);
00809 }
00810 
00811 
00812 
00813 
00814 
00815 SUMA_Boolean SUMA_UpdateViewPoint (SUMA_SurfaceViewer *SV, SUMA_DO *dov, int N_dov)
00816 {
00817    int i, do_id, TotWeight;
00818    float NewCenter[3], UsedCenter[3];
00819    SUMA_SurfaceObject *so_op;
00820    static char FuncName[]={"SUMA_UpdateViewPoint"};
00821       
00822    SUMA_ENTRY;
00823 
00824    NewCenter[0] = 0.0;
00825    NewCenter[1] = 0.0;
00826    NewCenter[2] = 0.0;
00827    TotWeight = 0;
00828    
00829    i = 0;
00830    while (i < SV->N_DO) {
00831       do_id = SV->RegisteredDO[i];
00832       switch (dov[do_id].ObjectType) {
00833          case SO_type:
00834             so_op = (SUMA_SurfaceObject *)dov[do_id].OP;
00835             if (SV->UsePatchDims) { SUMA_COPY_VEC(so_op->patchCenter, UsedCenter, 3, float, float);  } 
00836             else {  SUMA_COPY_VEC(so_op->Center, UsedCenter, 3, float, float); }
00837             if (so_op->ViewCenterWeight) {
00838                NewCenter[0] += so_op->ViewCenterWeight*UsedCenter[0];
00839                NewCenter[1] += so_op->ViewCenterWeight*UsedCenter[1];
00840                NewCenter[2] += so_op->ViewCenterWeight*UsedCenter[2];
00841                TotWeight += so_op->ViewCenterWeight;
00842             }
00843             break;
00844          default:
00845             break;
00846       } 
00847       ++i;
00848    }
00849    if (TotWeight) {
00850       SV->GVS[SV->StdView].ViewCenter[0] = NewCenter[0]/(float)TotWeight;
00851       SV->GVS[SV->StdView].ViewCenter[1] = NewCenter[1]/(float)TotWeight;
00852       SV->GVS[SV->StdView].ViewCenter[2] = NewCenter[2]/(float)TotWeight;
00853       SV->GVS[SV->StdView].ViewFrom[0] = SV->GVS[SV->StdView].ViewCenter[0];
00854       SV->GVS[SV->StdView].ViewFrom[1] = SV->GVS[SV->StdView].ViewCenter[1];
00855       SV->GVS[SV->StdView].ViewFrom[2] = SV->GVS[SV->StdView].ViewCenter[2]+SUMA_DEFAULT_VIEW_FROM;   
00856       SV->GVS[SV->StdView].ViewDistance = SUMA_DEFAULT_VIEW_FROM;   
00857       
00858    } else
00859    {
00860       SV->GVS[SV->StdView].ViewCenter[0] = SV->GVS[SV->StdView].ViewCenter[1] = SV->GVS[SV->StdView].ViewCenter[2] = 0.0;
00861       SV->GVS[SV->StdView].ViewFrom[0] = SV->GVS[SV->StdView].ViewFrom[1] = 0.0; SV->GVS[SV->StdView].ViewFrom[2] = SUMA_DEFAULT_VIEW_FROM;
00862       SV->GVS[SV->StdView].ViewDistance = SUMA_DEFAULT_VIEW_FROM;   
00863    }
00864    
00865       
00866       SV->GVS[SV->StdView].ViewCenterOrig[0] = SV->GVS[SV->StdView].ViewCenter[0];
00867       SV->GVS[SV->StdView].ViewCenterOrig[1] = SV->GVS[SV->StdView].ViewCenter[1];
00868       SV->GVS[SV->StdView].ViewCenterOrig[2] = SV->GVS[SV->StdView].ViewCenter[2];
00869       SV->GVS[SV->StdView].ViewFromOrig[0] = SV->GVS[SV->StdView].ViewFrom[0];
00870       SV->GVS[SV->StdView].ViewFromOrig[1] = SV->GVS[SV->StdView].ViewFrom[1];
00871       SV->GVS[SV->StdView].ViewFromOrig[2] = SV->GVS[SV->StdView].ViewFrom[2];
00872 
00873    SUMA_RETURN (YUP);
00874    
00875    
00876 }
00877 
00878 
00879 
00880 SUMA_Boolean SUMA_UpdateRotaCenter (SUMA_SurfaceViewer *SV, SUMA_DO *dov, int N_dov)
00881 {
00882    int i, do_id, TotWeight;
00883    float NewCenter[3], UsedCenter[3];
00884    SUMA_SurfaceObject *so_op;
00885    static char FuncName[]={"SUMA_UpdateRotaCenter"};
00886    
00887    SUMA_ENTRY;
00888 
00889    NewCenter[0] = 0.0;
00890    NewCenter[1] = 0.0;
00891    NewCenter[2] = 0.0;
00892    TotWeight = 0;
00893    
00894    
00895    i = 0;
00896    while (i < SV->N_DO) {
00897       do_id = SV->RegisteredDO[i];
00898       switch (dov[do_id].ObjectType) {
00899          case SO_type:
00900             so_op = (SUMA_SurfaceObject *)dov[do_id].OP;
00901             if (SV->UsePatchDims) { SUMA_COPY_VEC(so_op->patchCenter, UsedCenter, 3, float, float);  } 
00902             else {  SUMA_COPY_VEC(so_op->Center, UsedCenter, 3, float, float); }
00903             if (so_op->RotationWeight) {
00904                NewCenter[0] += so_op->RotationWeight*UsedCenter[0];
00905                NewCenter[1] += so_op->RotationWeight*UsedCenter[1];
00906                NewCenter[2] += so_op->RotationWeight*UsedCenter[2];
00907                TotWeight += so_op->RotationWeight;
00908             }
00909             break;
00910          default:
00911             break;
00912       } 
00913       ++i;
00914    }
00915    if (TotWeight) {
00916       SV->GVS[SV->StdView].RotaCenter[0] = NewCenter[0]/(float)TotWeight;
00917       SV->GVS[SV->StdView].RotaCenter[1] = NewCenter[1]/(float)TotWeight;
00918       SV->GVS[SV->StdView].RotaCenter[2] = NewCenter[2]/(float)TotWeight;
00919    } else
00920    {
00921       SV->GVS[SV->StdView].RotaCenter[0] = SV->GVS[SV->StdView].RotaCenter[1] = SV->GVS[SV->StdView].RotaCenter[2] = 0.0;
00922    }
00923    SUMA_RETURN (YUP);
00924    
00925 }
00926 
00927 
00928 
00929 
00930 void SUMA_Show_SurfaceViewer_Struct (SUMA_SurfaceViewer *SV, FILE *Out, int detail)
00931 {
00932    static char FuncName[]={"SUMA_Show_SurfaceViewer_Struct"};
00933    char *s = NULL;  
00934    
00935    SUMA_ENTRY;
00936 
00937    if (Out == NULL) Out = stdout;
00938    
00939    s = SUMA_SurfaceViewer_StructInfo (SV, detail);
00940    
00941    if (s) {
00942       fprintf(Out, "%s", s);
00943       SUMA_free(s); s = NULL;
00944    }else {
00945       SUMA_SL_Err("Failed in SUMA_SurfaceViewer_StructInfo");
00946    }
00947    
00948    SUMA_RETURNe;
00949 }
00950 
00951 char *SUMA_SurfaceViewer_StructInfo (SUMA_SurfaceViewer *SV, int detail)
00952 {
00953    static char FuncName[]={"SUMA_SurfaceViewer_StructInfo"};
00954    SUMA_STRING *SS = NULL;
00955    char *s=NULL;
00956    int i;
00957       
00958    SUMA_ENTRY;
00959    
00960    SS = SUMA_StringAppend (NULL, NULL);
00961    
00962    if (!SV) {
00963       SS = SUMA_StringAppend (SS,"NULL SV.\n");
00964       SS = SUMA_StringAppend (SS, NULL);
00965       
00966       s = SS->s;
00967       SUMA_free(SS);
00968       SUMA_RETURN(s);  
00969    }
00970    
00971    SS = SUMA_StringAppend(SS, "\nSV contents:\n");
00972    SS = SUMA_StringAppend_va(SS, "   verbose = %d\n", SV->verbose); 
00973    if (SV->ShowLeft) SS = SUMA_StringAppend_va(SS,"   Show Left = YES\n");
00974    else SS = SUMA_StringAppend_va(SS,"   Show Left = NO\n");
00975    if (SV->ShowRight) SS = SUMA_StringAppend_va(SS,"   Show Right = YES\n");
00976    else SS = SUMA_StringAppend_va(SS,"   Show Right = NO\n");
00977    
00978    if (SV->ortho) SS = SUMA_StringAppend_va(SS,"   Projection: Orthographic\n");
00979    else SS = SUMA_StringAppend_va(SS,"   Projection: Perspective\n");
00980    SS = SUMA_StringAppend_va(SS,"   Aspect = %f\n", SV->Aspect);
00981    SS = SUMA_StringAppend_va(SS,"   ViewFrom = [%f %f %f]\n", SV->GVS[SV->StdView].ViewFrom[0], SV->GVS[SV->StdView].ViewFrom[1], SV->GVS[SV->StdView].ViewFrom[2]);
00982    SS = SUMA_StringAppend_va(SS,"   ViewFromOrig = [%f %f %f]\n", SV->GVS[SV->StdView].ViewFromOrig[0], SV->GVS[SV->StdView].ViewFromOrig[1], SV->GVS[SV->StdView].ViewFromOrig[2]);
00983    SS = SUMA_StringAppend_va(SS,"   ViewCenter = [%f %f %f]\n", SV->GVS[SV->StdView].ViewCenter[0], SV->GVS[SV->StdView].ViewCenter[1], SV->GVS[SV->StdView].ViewCenter[2]);
00984    SS = SUMA_StringAppend_va(SS,"   ViewCenterOrig = [%f %f %f]\n", SV->GVS[SV->StdView].ViewCenterOrig[0], SV->GVS[SV->StdView].ViewCenterOrig[1], SV->GVS[SV->StdView].ViewCenterOrig[2]);
00985    SS = SUMA_StringAppend_va(SS,"   ViewCamUp = [%f %f %f]\n", SV->GVS[SV->StdView].ViewCamUp[0], SV->GVS[SV->StdView].ViewCamUp[1], SV->GVS[SV->StdView].ViewCamUp[2]);
00986    SS = SUMA_StringAppend_va(SS,"   RotaCenter = [%f %f %f]\n", SV->GVS[SV->StdView].RotaCenter[0], SV->GVS[SV->StdView].RotaCenter[1], SV->GVS[SV->StdView].RotaCenter[2]);
00987    SS = SUMA_StringAppend_va(SS,"   light0_position = [%f %f %f %f]\n", SV->light0_position[0], SV->light0_position[1], SV->light0_position[2], SV->light0_position[3]);
00988    SS = SUMA_StringAppend_va(SS,"   light1_position = [%f %f %f %f]\n", SV->light1_position[0], SV->light1_position[1], SV->light1_position[2], SV->light1_position[3]);
00989    SS = SUMA_StringAppend_va(SS,"   ZoomCompensate = %f\n", SV->ZoomCompensate);
00990    SS = SUMA_StringAppend_va(SS,"   WindWidth = %d\n", SV->WindWidth);
00991    SS = SUMA_StringAppend_va(SS,"   WindHeight = %d\n", SV->WindHeight);
00992    SS = SUMA_StringAppend_va(SS,"   ShowWorldAxis = %d\n", SV->ShowWorldAxis);
00993    if (SV->WAx) {
00994       SS = SUMA_StringAppend_va(SS,"   WorldAxis: Center = [%f %f %f] BR = [%f %f %f , %f %f %f]\n", 
00995                                     SV->WAx->Center[0], SV->WAx->Center[1], SV->WAx->Center[2],
00996                                     SV->WAx->BR[0][0], SV->WAx->BR[1][0],   SV->WAx->BR[2][0], 
00997                                     SV->WAx->BR[0][1], SV->WAx->BR[1][1],   SV->WAx->BR[2][1]);
00998    } else {
00999       SS = SUMA_StringAppend_va(SS,"   WorldAxis: NULL\n");
01000    }     
01001    SS = SUMA_StringAppend_va(SS,"   currentQuat = [%f %f %f %f]\n", SV->GVS[SV->StdView].currentQuat[0], SV->GVS[SV->StdView].currentQuat[1], SV->GVS[SV->StdView].currentQuat[2], SV->GVS[SV->StdView].currentQuat[3]);
01002    SS = SUMA_StringAppend_va(SS,"   deltaQuat = [%f %f %f %f]\n", SV->GVS[SV->StdView].deltaQuat[0], SV->GVS[SV->StdView].deltaQuat[1], SV->GVS[SV->StdView].deltaQuat[2], SV->GVS[SV->StdView].deltaQuat[3]);
01003    SS = SUMA_StringAppend_va(SS,"   ApplyMomentum = %d\n", SV->GVS[SV->StdView].ApplyMomentum);
01004    SS = SUMA_StringAppend_va(SS,"   MinIdleDelta = %d\n", SV->GVS[SV->StdView].MinIdleDelta);
01005    SS = SUMA_StringAppend_va(SS,"   zoomDelta = %f, zoomBegin = %f\n", SV->GVS[SV->StdView].zoomDelta, SV->GVS[SV->StdView].zoomBegin);
01006    SS = SUMA_StringAppend_va(SS,"   ArrowRotationAngle=%f rad (%f deg)\n", SV->ArrowRotationAngle, SV->ArrowRotationAngle * 180.0 / SUMA_PI);
01007    SS = SUMA_StringAppend_va(SS,"   spinDeltaX/Y = %.4f/%.4f\n", SV->GVS[SV->StdView].spinDeltaX, SV->GVS[SV->StdView].spinDeltaY);
01008    SS = SUMA_StringAppend_va(SS,"   spinBeginX/Y = %.4f/%.4f\n", SV->GVS[SV->StdView].spinBeginX, SV->GVS[SV->StdView].spinBeginY);   
01009    SS = SUMA_StringAppend_va(SS,"   TranslateGain = %f\n", SV->GVS[SV->StdView].TranslateGain);
01010    SS = SUMA_StringAppend_va(SS,"   ArrowtranslateDeltaX/Y = %f/%f\n", SV->GVS[SV->StdView].ArrowtranslateDeltaX, SV->GVS[SV->StdView].ArrowtranslateDeltaY);
01011    SS = SUMA_StringAppend_va(SS,"   translateBeginX/Y = %.4f/%.4f\n", SV->GVS[SV->StdView].translateBeginX, SV->GVS[SV->StdView].translateBeginY);
01012    SS = SUMA_StringAppend_va(SS,"   translateDeltaX/Y = %f/%f\n", SV->GVS[SV->StdView].translateDeltaX, SV->GVS[SV->StdView].translateDeltaY);
01013    SS = SUMA_StringAppend_va(SS,"   translateVec = [%f %f 0.0]\n", SV->GVS[SV->StdView].translateVec[0], SV->GVS[SV->StdView].translateVec[1]);
01014    SS = SUMA_StringAppend_va(SS,"   Show Mesh Axis %d\n", SV->ShowMeshAxis);
01015    SS = SUMA_StringAppend_va(SS,"   Show Eye Axis %d\n", SV->ShowEyeAxis);
01016    SS = SUMA_StringAppend_va(SS,"   Show Cross Hair %d\n", SV->ShowCrossHair);
01017    SS = SUMA_StringAppend_va(SS,"   PolyMode %d\n", SV->PolyMode);
01018    
01019    SS = SUMA_StringAppend_va(SS,"   Group Name %s, indexed %d\n", SV->CurGroupName, SV->iCurGroup);
01020    SS = SUMA_StringAppend_va(SS,"   Current State %s, indexed %d\n", SV->State, SV->iState);
01021    SS = SUMA_StringAppend_va(SS,"   N_DO = %d\n", SV->N_DO);
01022    SS = SUMA_StringAppend(SS, "   RegisteredDO = [");
01023 
01024    for (i=0; i< SV->N_DO; ++i) {
01025       SS = SUMA_StringAppend_va(SS,"%d, ", SV->RegisteredDO[i]); 
01026    } 
01027    SS = SUMA_StringAppend(SS,"]\n");
01028    if (SV->X == NULL) SS = SUMA_StringAppend_va(SS,"   X struct is NULL!\n");
01029    else {
01030    SS = SUMA_StringAppend_va(SS,"   X struct defined.\n");
01031    }
01032    
01033    SS = SUMA_StringAppend_va(SS,"   SO in focus %d\n", SV->Focus_SO_ID);
01034    SS = SUMA_StringAppend_va(SS,"   DO in focus %d\n", SV->Focus_DO_ID);
01035 
01036    
01037    SS = SUMA_StringAppend(SS, "\nView States:\n");
01038    for (i=0; i < SV->N_VSv; ++i) {
01039       SS = SUMA_StringAppend_va(SS,"\nView State %d/%d (FOV = %f):\n", i, SV->N_VSv-1, SV->FOV[i]);
01040       s = SUMA_ViewStateInfo (&(SV->VSv[i]), 0);
01041       if (!s) {
01042          SS = SUMA_StringAppend(SS, "*** Error in SUMA_Show_ViewState ***\n");
01043       } else {
01044          SS = SUMA_StringAppend(SS, s);
01045          SUMA_free(s); s = NULL;
01046       }
01047    }
01048    SS = SUMA_StringAppend_va(SS, "\nStandard viewing mode: %d\n", SV->StdView );
01049    SS = SUMA_StringAppend_va(SS, "\nBackground Modulation Factor= %f\n", SV->Back_Modfact);
01050    SS = SUMA_StringAppend_va(SS, "\nLast non mappable visited %d\n", SV->LastNonMapStateID);
01051    
01052    SS = SUMA_StringAppend(SS,"\n");
01053    
01054    
01055    SS = SUMA_StringAppend (SS, NULL);
01056    
01057    s = SS->s;
01058    SUMA_free(SS);
01059       
01060    SUMA_RETURN(s);
01061 }
01062 
01063 
01064 SUMA_Boolean SUMA_Show_ViewState(SUMA_ViewState *VS, FILE *Out, int detail) 
01065 {
01066    static char FuncName[]={"SUMA_Show_ViewState"};
01067    char *s = NULL;
01068    
01069    SUMA_ENTRY;
01070 
01071    if (Out == NULL) Out = stdout;
01072 
01073    s = SUMA_ViewStateInfo(VS,  detail);
01074    if (!s) {
01075       SUMA_SL_Err("Failed in SUMA_ViewStateInfo");
01076       SUMA_RETURN(NOPE);
01077    }  else {
01078       fprintf(Out, "%s", s);
01079       SUMA_free(s); s = NULL;
01080    }
01081    
01082    SUMA_RETURN(YUP);
01083 }
01084 
01085 
01086 char *SUMA_ViewStateInfo(SUMA_ViewState *VS, int detail) 
01087 {
01088    static char FuncName[]={"SUMA_ViewStateInfo"};
01089    int i;
01090    SUMA_STRING *SS = NULL;
01091    char *s=NULL;   
01092 
01093    SUMA_ENTRY;
01094 
01095    SS = SUMA_StringAppend (NULL, NULL);
01096    
01097    if (!VS) {
01098       SS = SUMA_StringAppend (SS,"NULL VS.\n");
01099       SS = SUMA_StringAppend (SS, NULL);
01100       
01101       s = SS->s;
01102       SUMA_free(SS);
01103       SUMA_RETURN(s);  
01104    }
01105 
01106    if (VS->Name) SS = SUMA_StringAppend_va(SS, "   Name: %s\n", VS->Name);
01107    else SS = SUMA_StringAppend_va(SS, "   Name: NULL\n");
01108    
01109    if (VS->Group) SS = SUMA_StringAppend_va(SS, "   Group: %s\n", VS->Group);
01110    else SS = SUMA_StringAppend_va(SS, "   Group: NULL\n");
01111    
01112    if (VS->N_MembSOs) {
01113       SS = SUMA_StringAppend_va(SS, "   %d MembSOs: ", VS->N_MembSOs);
01114       for (i=0; i < VS->N_MembSOs; ++i) SS = SUMA_StringAppend_va(SS, "%d, ", VS->MembSOs[i]);
01115       SS = SUMA_StringAppend_va(SS, "\n");
01116    } else {
01117       SS = SUMA_StringAppend_va(SS, "   No MembSOs\n");
01118    }
01119    
01120    if (VS->Hist) {
01121       if (VS->Hist->N_DO) {
01122          SS = SUMA_StringAppend_va(SS, "   Hist->N_DO = %d\nHist->RegisteredDO: ", VS->Hist->N_DO);
01123          for (i=0; i < VS->Hist->N_DO; ++i) {
01124             SS = SUMA_StringAppend_va(SS, "   %d, ", VS->Hist->RegisteredDO[i]);
01125          }
01126       }
01127    } else {
01128       SS = SUMA_StringAppend_va(SS, "   Hist is NULL\n");
01129    }
01130    
01131    SS = SUMA_StringAppend (SS, NULL);
01132    
01133    s = SS->s;
01134    SUMA_free(SS);
01135    
01136    SUMA_RETURN (s);
01137 }
01138 
01139 
01140 
01141 
01142 SUMA_ViewState_Hist *SUMA_Alloc_ViewState_Hist (void)
01143 {
01144    static char FuncName[]={"SUMA_Alloc_ViewState_Hist"};
01145    SUMA_ViewState_Hist *vsh;
01146    
01147    SUMA_ENTRY;
01148 
01149    vsh = (SUMA_ViewState_Hist *)SUMA_malloc(sizeof(SUMA_ViewState_Hist));
01150    if (vsh == NULL) {
01151       fprintf(SUMA_STDERR,"Error %s: Could not allocate for vsh.\n", FuncName);
01152       SUMA_RETURN (NULL);
01153    }
01154    vsh->RegisteredDO = NULL;
01155    vsh->N_DO = 0;
01156    SUMA_RETURN (vsh);
01157 }   
01158 SUMA_Boolean SUMA_Free_ViewState_Hist (SUMA_ViewState_Hist *vsh)
01159 {
01160    static char FuncName[]={"SUMA_Free_ViewState_Hist"};
01161    
01162    SUMA_ENTRY;
01163 
01164    if (vsh == NULL) SUMA_RETURN (YUP);
01165    if (vsh->RegisteredDO) SUMA_free(vsh->RegisteredDO);
01166    if (vsh) SUMA_free(vsh);
01167    SUMA_RETURN (YUP);
01168 }
01169 
01170 
01171 
01172 
01173 
01174 
01175 
01176 SUMA_Boolean SUMA_New_ViewState (SUMA_SurfaceViewer *cs)
01177 {
01178    static char FuncName[]={"SUMA_New_ViewState"};
01179 
01180    SUMA_ENTRY;
01181 
01182    
01183    if (!cs->VSv) { 
01184       cs->N_VSv = 1;
01185       cs->VSv = (SUMA_ViewState *)SUMA_malloc(sizeof(SUMA_ViewState));
01186    } else { 
01187       ++cs->N_VSv;
01188       cs->VSv = (SUMA_ViewState *)SUMA_realloc(cs->VSv, cs->N_VSv*sizeof(SUMA_ViewState) );
01189    }
01190    
01191    
01192    if (!cs->VSv) {
01193       SUMA_SL_Err("Failed to allocate");
01194       SUMA_RETURN(YUP);
01195    }
01196    
01197    
01198    cs->VSv[cs->N_VSv-1].Name = NULL;
01199    cs->VSv[cs->N_VSv-1].Group = NULL;
01200    cs->VSv[cs->N_VSv-1].MembSOs = NULL;
01201    cs->VSv[cs->N_VSv-1].N_MembSOs = 0;
01202    cs->VSv[cs->N_VSv-1].Hist = SUMA_Alloc_ViewState_Hist ();
01203    if (cs->VSv[cs->N_VSv-1].Hist == NULL) {
01204       fprintf(SUMA_STDERR,"Error %s: Could not allocate for cs->VSv->Hist.\n", FuncName);
01205       SUMA_free(cs->VSv);
01206       SUMA_RETURN (NOPE);
01207    }
01208    
01209    
01210    SUMA_RETURN(YUP);
01211    
01212 }
01213  
01214 
01215 
01216 
01217 SUMA_ViewState *SUMA_Alloc_ViewState (int N)
01218 {
01219    SUMA_ViewState *vs;
01220    int i;
01221    static char FuncName[]={"SUMA_Alloc_ViewState"};
01222    
01223    SUMA_ENTRY;
01224 
01225    SUMA_SL_Err("Should not be using this anymore.\n"
01226                "Start using SUMA_New_ViewState.\n"
01227                "     ZSS Jan 12 04 \n");
01228    SUMA_RETURN(NULL);
01229    vs = (SUMA_ViewState *)SUMA_malloc(sizeof(SUMA_ViewState)*N);
01230    if (vs == NULL) {
01231       fprintf(SUMA_STDERR,"Error %s: Could not allocate for vs.\n", FuncName);
01232       SUMA_RETURN (NULL);
01233    }
01234    for (i=0; i< N; ++i) {
01235       vs[i].Name = NULL;
01236       vs[i].Group = NULL;
01237       vs[i].MembSOs = NULL;
01238       vs[i].N_MembSOs = 0;
01239       vs[i].Hist = SUMA_Alloc_ViewState_Hist ();
01240       if (vs[i].Hist == NULL) {
01241          fprintf(SUMA_STDERR,"Error %s: Could not allocate for vs->Hist.\n", FuncName);
01242          SUMA_free(vs);
01243          SUMA_RETURN (NULL);
01244       }
01245    }
01246    SUMA_RETURN (vs);
01247 }   
01248 
01249 SUMA_Boolean SUMA_Free_ViewState (SUMA_ViewState *vs)
01250 {
01251    static char FuncName[]={"SUMA_Free_ViewState"};
01252    SUMA_ENTRY;
01253 
01254    if (vs == NULL) SUMA_RETURN (YUP);
01255    if (vs->Name) SUMA_free(vs->Name);
01256    if (vs->Group) SUMA_free(vs->Group);
01257    if (vs->MembSOs) SUMA_free(vs->MembSOs);
01258    if (vs->Hist) SUMA_Free_ViewState_Hist (vs->Hist);
01259    if (vs) SUMA_free(vs);
01260    SUMA_RETURN (YUP);
01261 }
01262 
01263 
01264 
01265 
01266 
01267 int SUMA_WhichSV (SUMA_SurfaceViewer *sv, SUMA_SurfaceViewer *SVv, int N_SVv)
01268 {
01269    static char FuncName[]={"SUMA_WhichSV"};
01270    int i = 0;
01271    
01272    SUMA_ENTRY;
01273    
01274    if (!SVv || !sv) {
01275       fprintf (SUMA_STDERR, "Error %s: NULL SVv or sv.\n", FuncName);
01276       SUMA_RETURN (-1);
01277    }
01278    
01279    for (i=0; i<N_SVv; ++i) {
01280       if (&(SVv[i]) == sv) {
01281          SUMA_RETURN (i);
01282       } 
01283    }
01284    
01285    
01286    SUMA_RETURN (-1);
01287 }
01288 
01289 
01290 
01291 
01292 
01293 int SUMA_WhichState (char *state, SUMA_SurfaceViewer *csv, char *ForceGroup)
01294 {
01295    static char FuncName[]={"SUMA_WhichState"};
01296    int i = 0;
01297    SUMA_Boolean LocalHead = NOPE;
01298    
01299    SUMA_ENTRY;
01300 
01301    if (!ForceGroup) {
01302       if (LocalHead) fprintf(SUMA_STDERR,"%s: Searching for: %s\n", 
01303                                  FuncName, state);
01304       while (i < csv->N_VSv) {
01305          if (LocalHead) fprintf(SUMA_STDERR,"   %d? %s ...\n", 
01306                                  i, csv->VSv[i].Name);
01307                                  
01308          if (!csv->VSv[i].Name || !state) {
01309             SUMA_SL_Err("Null Name or State \n");
01310             SUMA_RETURN (-1);
01311          }
01312          if (strcmp(csv->VSv[i].Name, state) == 0) {
01313             if (LocalHead) fprintf(SUMA_STDERR,"%s: FOUND, i=%d!\n", FuncName, i);
01314             SUMA_RETURN (i);
01315          }
01316          ++i;
01317       }
01318    } else {
01319       if (LocalHead) fprintf(SUMA_STDERR,"%s: Searching for: %s, %s...\n", 
01320                               FuncName, state, ForceGroup);
01321       while (i < csv->N_VSv) {
01322          if (LocalHead) fprintf(SUMA_STDERR,"   %d? %s, %s ...\n", 
01323                                  i, csv->VSv[i].Name, csv->VSv[i].Group);
01324          if (!csv->VSv[i].Name || !state || !csv->CurGroupName) {
01325             SUMA_SL_Err("Null Name or State or CurGroupName.\n");
01326             SUMA_RETURN (-1);
01327          }
01328          if (strcmp(csv->VSv[i].Name, state) == 0 && strcmp(csv->VSv[i].Group, ForceGroup) == 0 ) {
01329             if (LocalHead) fprintf(SUMA_STDERR,"%s: FOUND, i=%d!\n", FuncName, i);
01330             SUMA_RETURN (i);
01331          }
01332          ++i;
01333       }
01334    }
01335    SUMA_RETURN (-1);
01336 }
01337 
01338 
01339 
01340 
01341 
01342 
01343 SUMA_Boolean SUMA_RegisterSpecSO (SUMA_SurfSpecFile *Spec, SUMA_SurfaceViewer *csv, SUMA_DO* dov, int N_dov)
01344 {
01345    static char FuncName[]={"SUMA_RegisterSpecSO"};
01346    int is, i;
01347    static int iwarn=0;
01348    SUMA_SurfaceObject * SO;
01349    SUMA_Boolean LocalHead = NOPE;
01350    
01351    SUMA_ENTRY;
01352 
01353    if (LocalHead && SUMA_WhichSV(csv, SUMAg_SVv, SUMA_MAX_SURF_VIEWERS) != 0) {
01354       fprintf(SUMA_STDERR,"%s: Muted for viewer[%c]\n", FuncName, 65+SUMA_WhichSV(csv, SUMAg_SVv, SUMA_MAX_SURF_VIEWERS) );
01355       
01356       LocalHead = NOPE;
01357    }
01358    
01359 
01360    
01361    
01362    if (LocalHead) fprintf(SUMA_STDERR,"%s: Entering, Spec->Group[0] = %s ...\n", 
01363       FuncName, Spec->Group[0]);
01364    
01365    if (Spec->N_Groups != 1) {
01366       SUMA_SL_Err("A spec file is to have 1 and only 1 group in it");
01367       SUMA_RETURN(NOPE);
01368    }
01369    
01370    #if 0
01371       
01372       if (!csv->VSv) { 
01373          csv->VSv = SUMA_Alloc_ViewState (Spec->N_States);
01374          if (csv->VSv == NULL) {
01375             fprintf(SUMA_STDERR,"Error %s: Failed to allocate for VSv.\n", FuncName);
01376             SUMA_RETURN (NOPE);
01377          }
01378          csv->N_VSv = 0;
01379       } 
01380    #endif
01381    
01382    
01383    if (LocalHead) fprintf(SUMA_STDERR,"%s: Cycling through DOvs, looking for surfaces of group %s\n", FuncName, Spec->Group[0]);
01384    for (i=0; i < N_dov; ++i) {
01385       if (SUMA_isSO_G(dov[i], Spec->Group[0])) {
01386          SO = (SUMA_SurfaceObject *)(dov[i].OP);
01387          is = SUMA_WhichState (SO->State, csv, SO->Group);
01388          if (is < 0) {
01389             
01390             
01391             if (LocalHead) {
01392                fprintf(SUMA_STDERR,"%s: For %s\nState:%s,Group:%s to be added\n", 
01393                   FuncName, SO->Label, SO->State, SO->Group);
01394             }
01395             SUMA_New_ViewState (csv);
01396             csv->VSv[csv->N_VSv-1].Name = SUMA_copy_string(SO->State);
01397             csv->VSv[csv->N_VSv-1].Group = SUMA_copy_string(SO->Group); 
01398             if (!csv->VSv[csv->N_VSv-1].Name || !csv->VSv[csv->N_VSv-1].Group) {
01399                fprintf(SUMA_STDERR,"Error %s: Failed to allocate for csv->VSv[csv->N_VSv-1].Name or .Group.\n", FuncName);
01400                SUMA_RETURN (NOPE);
01401             }   
01402             csv->VSv[csv->N_VSv-1].N_MembSOs = 1;
01403          } else { 
01404             if (LocalHead) {
01405                fprintf(SUMA_STDERR,"%s: For %s\n State:%s,Group:%s found\n", 
01406                   FuncName, SO->Label, SO->State, SO->Group);
01407             }
01408             csv->VSv[is].N_MembSOs += 1;
01409          }
01410       }
01411    }
01412    
01413    SUMA_LH("Allocating...");   
01414    
01415    
01416    if (!csv->FOV) {
01417       csv->FOV = (float *)SUMA_calloc(csv->N_VSv, sizeof(float));
01418    } else {
01419       csv->FOV = (float *)SUMA_realloc(csv->FOV, csv->N_VSv * sizeof(float));
01420    }
01421    
01422    
01423 
01424    if (!iwarn) {
01425       SUMA_LH(  "WARNING: This block is resetting FOV\n"
01426                   "to all surface views regardless\n"
01427                   "of whether a new addition was made or not.\n"
01428                   "This message will not be shown again in this session.\n"
01429                   "Well, looks like it does no bad thing...");
01430                   ++iwarn;
01431    }
01432    for (i=0; i < csv->N_VSv; ++i) {
01433       csv->FOV[i] = FOV_INITIAL;
01434       if (!csv->VSv[i].MembSOs) {
01435          csv->VSv[i].MembSOs = (int *) SUMA_calloc(csv->VSv[i].N_MembSOs, sizeof(int));
01436       } else {
01437          csv->VSv[i].MembSOs = (int *) SUMA_realloc(csv->VSv[i].MembSOs, csv->VSv[i].N_MembSOs * sizeof(int));
01438       }
01439       if (csv->VSv[i].MembSOs == NULL) {
01440          fprintf(SUMA_STDERR,"Error %s: Failed to allocate for csv->VSv[i].MembSOs.\n", FuncName);
01441          SUMA_RETURN (NOPE);
01442       }   
01443       csv->VSv[i].N_MembSOs = 0;
01444    }
01445 
01446    
01447    
01448    
01449    
01450    for (i=0; i < N_dov; ++i) {
01451       if (SUMA_isSO(dov[i])) {
01452          SO = (SUMA_SurfaceObject *)(dov[i].OP);
01453          
01454          if (!SO->State || !SO->Group) {
01455             fprintf(SUMA_STDERR,"Error %s: Sent me SO (%s) with null State (%s) or null Group (%s)!\n", FuncName, SO->Label, SO->State, SO->Group);
01456             if (LocalHead) SUMA_Print_Surface_Object (SO, NULL);      
01457             SUMA_RETURN (NOPE);
01458          } 
01459          is = SUMA_WhichState (SO->State, csv, SO->Group);
01460          if (is < 0) {
01461             fprintf(SUMA_STDERR,"Error %s: This should not be.\nFailed to find %s %s in csv\n", FuncName, SO->State, SO->Group);
01462             SUMA_RETURN (NOPE);
01463          }
01464          if (LocalHead) {
01465             fprintf (SUMA_STDERR,"%s: Trying to house %s in: State[%d]\n", \
01466             FuncName, SO->Label, is);
01467          }
01468          
01469          csv->VSv[is].MembSOs[csv->VSv[is].N_MembSOs] = i; 
01470          csv->VSv[is].N_MembSOs += 1;  
01471       }
01472    }
01473    
01474    
01475 
01476    SUMA_RETURN (YUP);
01477 }
01478 
01479 
01480 
01481 
01482 SUMA_CommonFields * SUMA_Create_CommonFields ()
01483 {
01484    static char FuncName[]={"SUMA_Create_CommonFields"};
01485    SUMA_CommonFields *cf;
01486    int i, portn = -1, n, portn2;
01487    char *eee=NULL;
01488    SUMA_Boolean LocalHead = NOPE;
01489    
01490    
01491    cf = NULL;
01492    
01493    
01494    
01495    cf = (SUMA_CommonFields *)malloc(sizeof(SUMA_CommonFields));
01496    
01497    if (cf == NULL) {
01498       fprintf(SUMA_STDERR,"Error %s: Failed to allocate.\n", FuncName);
01499       SUMA_RETURN (cf);
01500    }
01501    
01502    cf->Dev = NOPE;
01503    cf->InOut_Notify = NOPE;
01504    cf->InOut_Level = 0;
01505    cf->MemTrace = NOPE;
01506    #ifdef USE_SUMA_MALLOC
01507    SUMA_SL_Err("NO LONGER SUPPORTED");
01508    return(NULL);
01509    cf->Mem = SUMA_Create_MemTrace();
01510    #else
01511    cf->Mem = NULL;
01512    #endif
01513    
01514    eee = getenv("SUMA_AFNI_TCP_PORT");
01515    if (eee) {
01516       portn = atoi(eee);
01517       if (portn < 1024 ||  portn > 65535) {
01518          fprintf (SUMA_STDERR, "Warning %s:\n"
01519                                "Environment variable SUMA_AFNI_TCP_PORT %d is invalid.\n"
01520                                "port must be between 1025 and 65534.\n"
01521                                "Using default of %d\n", FuncName, portn, SUMA_TCP_PORT);
01522          portn = SUMA_TCP_PORT;
01523       } 
01524    } else {
01525       portn = SUMA_TCP_PORT;
01526    }   
01527    
01528    eee = getenv("SUMA_AFNI_TCP_PORT2");
01529    if (eee) {
01530       portn2 = atoi(eee);
01531       if (portn2 < 1024 ||  portn2 > 65535) {
01532          fprintf (SUMA_STDERR, "Warning %s:\n"
01533                                "Environment variable SUMA_AFNI_TCP_PORT2 %d is invalid.\n"
01534                                "port must be between 1025 and 65534.\n"
01535                                "Using default of %d\n", FuncName, portn2, portn+1);
01536          portn2 = portn+1;
01537       } 
01538    } else {
01539       portn2 = portn+1;
01540    }   
01541     
01542    for (i=0; i<SUMA_MAX_STREAMS; ++i) {
01543       cf->ns_v[i] = NULL;
01544       cf->ns_flags_v[i] = 0;
01545       cf->Connected_v[i] = NOPE;
01546       cf->TrackingId_v[i] = 0;
01547       cf->NimlStream_v[i][0] = '\0';
01548       cf->HostName_v[i][0] = '\0';
01549       if (i==0) cf->TCP_port[i] = portn;           
01550       else if (i==1) cf->TCP_port[i] = portn2;     
01551       else cf->TCP_port[i] = SUMA_TCP_LISTEN_PORT0 + i - 2;   
01552    }
01553    cf->Listening = NOPE;
01554    cf->niml_work_on = NOPE;
01555    
01556    for (i=0; i<SUMA_MAX_SURF_VIEWERS; ++i) {
01557       cf->Locked[i] = SUMA_I_Lock;
01558       cf->ViewLocked[i] = NOPE;
01559    }
01560    
01561    eee = getenv("SUMA_SwapButtons_1_3");
01562    if (eee) {
01563       if (strcmp (eee, "YES") == 0) cf->SwapButtons_1_3 = YUP;
01564       else cf->SwapButtons_1_3 = NOPE;
01565    } else {
01566       cf->SwapButtons_1_3 = NOPE;
01567    }
01568 
01569    cf->X = (SUMA_X_AllView *)malloc(sizeof(SUMA_X_AllView));
01570    if (!cf->X) {
01571      fprintf(SUMA_STDERR,"Error %s: Failed to allocate.\n", FuncName);
01572      return (NULL); 
01573    }
01574    cf->X->SumaCont = SUMA_CreateSumaContStruct();
01575    cf->X->DrawROI = SUMA_CreateDrawROIStruct();
01576    cf->X->DPY_controller1 = NULL;
01577    
01578    eee = getenv("SUMA_ColorPattern");
01579    if (eee) {
01580       if (strcmp (eee, "AFNI") == 0) {
01581          cf->X->X_Resources = SXR_Afni;
01582          if (LocalHead) fprintf(SUMA_STDERR,"%s: Afni resources\n", FuncName);
01583       } else if (strcmp (eee, "EURO") == 0) {
01584          cf->X->X_Resources = SXR_Euro;
01585          if (LocalHead) fprintf(SUMA_STDERR,"%s: Euro resources\n", FuncName);
01586       } else if (strcmp (eee, "BONAIRE") == 0) {
01587          cf->X->X_Resources = SXR_Bonaire;
01588          if (LocalHead) fprintf(SUMA_STDERR,"%s: Bonaire resources\n", FuncName);
01589       } else if (strcmp (eee, "DEFAULT") == 0) {
01590          cf->X->X_Resources = SXR_default;
01591          if (LocalHead) fprintf(SUMA_STDERR,"%s: default resources\n", FuncName);
01592       } else {
01593          cf->X->X_Resources = SXR_Euro;
01594          fprintf(SUMA_STDERR,"%s:\nUnrecognized option %s for SUMA_ColorPattern.\nUsing default = EURO\n", FuncName, eee);
01595       }
01596    } else {
01597       cf->X->X_Resources = SXR_Euro;
01598       if (LocalHead) fprintf(SUMA_STDERR,"%s: Undefined environment. Using default\n", FuncName);
01599    }
01600    
01601    cf->X->Help_TextShell = NULL;
01602    cf->X->Help_Cmap_TextShell = NULL;
01603    cf->X->Log_TextShell = NULL;
01604    cf->X->FileSelectDlg = NULL;
01605    cf->X->N_ForeSmooth_prmpt = NULL;
01606    {
01607       char *eee = getenv("SUMA_NumForeSmoothing");
01608       if (eee) {
01609          int rotval = (int)strtod(eee, NULL);
01610          if (rotval >= 0) cf->X->NumForeSmoothing = rotval;
01611          else {
01612             fprintf (SUMA_STDERR,   "Warning %s:\n"
01613                                     "Bad value for environment variable SUMA_NumForeSmoothing\n"
01614                                     "Assuming default of 0", FuncName);
01615             cf->X->NumForeSmoothing = 0;
01616          }
01617       } else cf->X->NumForeSmoothing = 0;
01618    }
01619    
01620    {
01621       char *eee = getenv("SUMA_ThresholdScalePower");
01622       if (eee) {
01623          cf->SUMA_ThrScalePowerBias = (int)strtod(eee, NULL);
01624          if (cf->SUMA_ThrScalePowerBias < 2) {
01625             fprintf (SUMA_STDERR,   "Warning %s:\n"
01626                                     "Bad value for environment variable\n"
01627                                     "SUMA_ThresholdScalePower.\n"
01628                                     "Assuming default of 2", FuncName);
01629             cf->SUMA_ThrScalePowerBias = 2;
01630          }
01631       } else cf->SUMA_ThrScalePowerBias = 2; 
01632    }
01633    
01634    {
01635       char *eee = getenv("SUMA_WarnBeforeClose");
01636       if (eee) {
01637          if (strcmp(eee,"NO") == 0) cf->X->WarnClose = NOPE;
01638          else if (strcmp(eee,"YES") == 0) cf->X->WarnClose = YUP;
01639          else {
01640             fprintf (SUMA_STDERR,   "Warning %s:\n"
01641                                     "Bad value for environment variable SUMA_WarnBeforeClose\n"
01642                                     "Assuming default of YES", FuncName);
01643             cf->X->WarnClose = YUP;
01644          }
01645       } else cf->X->WarnClose = YUP;
01646    }
01647    cf->X->SwitchCmapLst = NULL;
01648    
01649    cf->MessageList = SUMA_CreateMessageList ();
01650    #ifdef USE_SUMA_MALLOC
01651    SUMA_SL_Err("NO LONGER SUPPORTED");
01652    return(NULL);
01653    
01654    #endif
01655    cf->ROI_mode = NOPE;
01656    cf->Pen_mode = NOPE;
01657    
01658    cf->nimlROI_Datum_type = NI_rowtype_define("SUMA_NIML_ROI_DATUM", "int,int,int,int[#3]");
01659    if (cf->nimlROI_Datum_type < 0) {
01660       fprintf(SUMA_STDERR,"Error %s: Failed defining niml code.", FuncName);
01661       return(NULL);
01662    }
01663    if (LocalHead) fprintf(SUMA_STDERR, "%s: roi_type code = %d\n", FuncName, cf->nimlROI_Datum_type) ;
01664    
01665    cf->ROI_CM = NULL;
01666    cf->ROI_FillMode = SUMA_ROI_FILL_TO_THISROI;
01667    cf->ROI2afni = NOPE;
01668    
01669    eee = getenv("SUMA_ColorMixingMode");
01670    if (eee) {
01671       if (strcmp (eee, "ORIG") == 0) {
01672          cf->ColMixMode = SUMA_ORIG_MIX_MODE;
01673       } else if (strcmp (eee, "MOD1") == 0) {
01674          cf->ColMixMode = SUMA_4AML;
01675       } else {
01676          cf->ColMixMode = SUMA_ORIG_MIX_MODE;
01677          fprintf(SUMA_STDERR,"%s:\nUnrecognized option %s for SUMA_ColorMixingMode.\nUsing default = ORIG\n", FuncName, eee);
01678       } 
01679    } else {
01680       cf->ColMixMode = SUMA_ORIG_MIX_MODE;
01681    }
01682    
01683    cf->GroupList = NULL;
01684    cf->N_Group = -1;
01685    
01686    cf->scm = NULL;
01687    cf->DsetList = (DList *)SUMA_malloc(sizeof(DList));
01688    dlist_init (cf->DsetList, SUMA_FreeDset);
01689    
01690    cf->IgnoreVolreg = NOPE;
01691    cf->isGraphical = NOPE;
01692    return (cf);
01693 
01694 }
01695 
01696 
01697 
01698 
01699 
01700  
01701 SUMA_rb_group *SUMA_CreateLock_rbg (int N_rb_group, int N_but) 
01702 {
01703    static char FuncName[]={"SUMA_CreateLock_rbg"};
01704    SUMA_rb_group *Lock_rb;
01705 
01706    Lock_rb = (SUMA_rb_group *) malloc(sizeof(SUMA_rb_group));
01707    if (!Lock_rb) { 
01708       fprintf (SUMA_STDERR,"Error %s: Failed to allocate.\n", FuncName);
01709       return(NULL);
01710    }
01711    Lock_rb->N_rb_group = N_rb_group;
01712    Lock_rb->N_but = N_but;
01713    Lock_rb->tb = (Widget *) calloc(N_rb_group*N_but, sizeof(Widget));
01714    Lock_rb->rb = (Widget *) calloc(N_rb_group, sizeof(Widget));
01715    Lock_rb->atb = (Widget *) calloc(N_but, sizeof(Widget));
01716    Lock_rb->arb = NULL;
01717    if (!Lock_rb->tb || !Lock_rb->rb || !Lock_rb->atb) {
01718       fprintf (SUMA_STDERR,"Error %s: Failed to allocate.\n", FuncName);
01719       return(NULL);
01720    }
01721    return(Lock_rb);
01722 
01723 }
01724 
01725 
01726 
01727 
01728 
01729 void * SUMA_FreeLock_rbg (SUMA_rb_group *Lock_rb)
01730 {
01731   static char FuncName[]={"SUMA_FreeLock_rb"};
01732   
01733   if (Lock_rb->rb) free(Lock_rb->rb);
01734   if (Lock_rb->tb) free(Lock_rb->tb);
01735   if (Lock_rb->atb) free (Lock_rb->atb);
01736   if (Lock_rb) free(Lock_rb);
01737 
01738   return (NULL);
01739 }
01740 
01741 
01742 
01743 
01744 
01745 
01746 
01747 SUMA_X_DrawROI *SUMA_CreateDrawROIStruct (void) 
01748 {
01749    static char FuncName[]={"SUMA_CreateDrawROIStruct"};
01750    SUMA_X_DrawROI *DrawROI = NULL;
01751    
01752    
01753    DrawROI = (SUMA_X_DrawROI *)malloc (sizeof(SUMA_X_DrawROI));
01754    DrawROI->AppShell = NULL;
01755    DrawROI->ROIval = (SUMA_ARROW_TEXT_FIELD *)malloc(sizeof(SUMA_ARROW_TEXT_FIELD));
01756    DrawROI->ROIlbl = (SUMA_ARROW_TEXT_FIELD *)malloc(sizeof(SUMA_ARROW_TEXT_FIELD));
01757    DrawROI->curDrawnROI = NULL;  
01758    DrawROI->SwitchROIlst = NULL;
01759    DrawROI->Delete_first = YUP;
01760    DrawROI->SaveMode = SW_DrawROI_SaveMode1D;
01761    DrawROI->SaveWhat = SW_DrawROI_SaveWhatThis;
01762    DrawROI->WhatDist = SW_DrawROI_WhatDistNothing;
01763    return (DrawROI);
01764 }
01765 
01766 
01767 
01768 
01769 
01770 
01771 
01772 SUMA_X_SumaCont *SUMA_CreateSumaContStruct (void) 
01773 {
01774    static char FuncName[]={"SUMA_CreateSumaContStruct"};
01775    SUMA_X_SumaCont *SumaCont = NULL;
01776    
01777    SumaCont = (SUMA_X_SumaCont *)malloc(sizeof(SUMA_X_SumaCont));
01778    SumaCont->AppShell = NULL;
01779    SumaCont->quit_pb = NULL;
01780    SumaCont->quit_first = YUP;
01781    SumaCont->Lock_rbg = SUMA_CreateLock_rbg (SUMA_MAX_SURF_VIEWERS, 3);
01782    if (!SumaCont->Lock_rbg) {
01783       fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_CreateLock_rb.\n", FuncName);
01784       return (NULL);
01785    }
01786    SumaCont->LockView_tbg = (Widget *)calloc (SUMA_MAX_SURF_VIEWERS, sizeof(Widget));
01787    SumaCont->LockAllView_tb = NULL;
01788    SumaCont->SumaInfo_TextShell = NULL;
01789    return (SumaCont);
01790 }
01791 
01792 
01793 
01794 
01795 
01796 void *SUMA_FreeSumaContStruct (SUMA_X_SumaCont *SumaCont)
01797 {
01798    static char FuncName[]={"SUMA_FreeSumaContStruct"};
01799 
01800    
01801    if (SumaCont->Lock_rbg) SUMA_FreeLock_rbg (SumaCont->Lock_rbg);
01802    if (SumaCont->LockView_tbg) free (SumaCont->LockView_tbg);
01803    if (SumaCont->SumaInfo_TextShell) { SUMA_SL_Warn("SumaCont->SumaInfo_TextShell is not being freed") };
01804    if (SumaCont) free(SumaCont);
01805    return (NULL);
01806 }
01807 
01808 
01809 
01810 
01811 void *SUMA_FreeDrawROIStruct (SUMA_X_DrawROI *DrawROI)
01812 {  
01813    static char FuncName[]={"SUMA_FreeDrawROIStruct"};
01814    
01815    
01816 
01817    if (DrawROI->ROIval) free (DrawROI->ROIval);
01818    if (DrawROI->ROIlbl) free (DrawROI->ROIlbl);
01819    if (DrawROI->SwitchROIlst) SUMA_FreeScrolledList (DrawROI->SwitchROIlst);
01820    if (DrawROI) free(DrawROI);
01821    
01822    return (NULL);
01823 }
01824 
01825 
01826 
01827 
01828 
01829 
01830 SUMA_X_ViewCont *SUMA_CreateViewContStruct (void) 
01831 {
01832    static char FuncName[]={"SUMA_CreateViewContStruct"};
01833    SUMA_X_ViewCont *ViewCont = NULL;
01834    
01835    ViewCont = (SUMA_X_ViewCont *)malloc(sizeof(SUMA_X_ViewCont));
01836    ViewCont->TopLevelShell = NULL;
01837    ViewCont->ViewerInfo_TextShell = NULL;
01838    ViewCont->Info_lb = NULL;
01839    ViewCont->ViewerInfo_pb = NULL;
01840    ViewCont->Mainform = NULL;
01841    ViewCont->SwitchGrouplst = NULL; 
01842    ViewCont->SwitchStatelst = NULL; 
01843    ViewCont->ViewerInfo_pb = NULL;
01844    return (ViewCont);
01845 }
01846 
01847 
01848 
01849 
01850 
01851 void *SUMA_FreeViewContStruct (SUMA_X_ViewCont *ViewCont)
01852 {
01853    static char FuncName[]={"SUMA_FreeViewContStruct"};
01854 
01855    
01856    if (ViewCont->TopLevelShell) {
01857       SUMA_SL_Warn("ViewCont->TopLevelShell is not being freed");
01858    }
01859    if (ViewCont->SwitchGrouplst) ViewCont->SwitchGrouplst = SUMA_FreeScrolledList(ViewCont->SwitchGrouplst);
01860    if (ViewCont->SwitchStatelst) ViewCont->SwitchStatelst = SUMA_FreeScrolledList(ViewCont->SwitchStatelst);
01861    if (ViewCont) free(ViewCont);
01862    return (NULL);
01863 }
01864 
01865 
01866 
01867 
01868 
01869 
01870 
01871 SUMA_X_SurfCont *SUMA_CreateSurfContStruct (char *idcode_str) 
01872 {
01873    static char FuncName[]={"SUMA_CreateSurfContStruct"};
01874    SUMA_X_SurfCont *SurfCont = NULL;
01875    
01876    
01877    
01878    SurfCont = (SUMA_X_SurfCont *)malloc(sizeof(SUMA_X_SurfCont));
01879    
01880    
01881    if (idcode_str) sprintf(SurfCont->owner_id, "%s", idcode_str);
01882    else SurfCont->owner_id[0] = '\0';
01883    SurfCont->N_links = 0;
01884    SurfCont->LinkedPtrType = SUMA_LINKED_SURFCONT_TYPE;
01885    
01886    SurfCont->DsetMap_fr = NULL;
01887    SurfCont->ColPlane_fr = NULL;
01888    SurfCont->Xhair_fr = NULL;
01889    SurfCont->TopLevelShell = NULL;
01890    SurfCont->SurfInfo_pb = NULL;
01891    SurfCont->SurfInfo_label = NULL;
01892    SurfCont->SurfInfo_TextShell = NULL;
01893    SurfCont->ColPlaneOrder = (SUMA_ARROW_TEXT_FIELD *)malloc(sizeof(SUMA_ARROW_TEXT_FIELD));
01894    SurfCont->ColPlaneOpacity = (SUMA_ARROW_TEXT_FIELD *)malloc(sizeof(SUMA_ARROW_TEXT_FIELD));
01895    SurfCont->ColPlaneDimFact = (SUMA_ARROW_TEXT_FIELD *)malloc(sizeof(SUMA_ARROW_TEXT_FIELD));
01896    SurfCont->XhairTable = SUMA_AllocTableField();
01897    SurfCont->SetRangeTable = SUMA_AllocTableField();
01898    SurfCont->SetThrScaleTable = SUMA_AllocTableField();
01899    SurfCont->RangeTable = SUMA_AllocTableField();
01900    SurfCont->NodeTable = SUMA_AllocTableField();
01901    SurfCont->FaceTable = SUMA_AllocTableField();
01902    SurfCont->DataTable = SUMA_AllocTableField();
01903    SurfCont->LabelTable = SUMA_AllocTableField();
01904    SurfCont->ColPlaneShow_tb = NULL;
01905    SurfCont->ColPlaneShowOne_tb = NULL;
01906    SurfCont->SymIrange_tb = NULL;
01907    SurfCont->AbsThresh_tb = NULL;
01908    SurfCont->ShowZero_tb = NULL;
01909    SurfCont->SwitchDsetlst = NULL;
01910    SurfCont->ColPlaneLabelTable = SUMA_AllocTableField();;
01911    SurfCont->curColPlane = NULL;
01912    SurfCont->ShowCurOnly = NOPE;
01913    SurfCont->curSOp = (void **)malloc(sizeof(void*));
01914    SurfCont->PosRef = NULL;
01915    SurfCont->cmp_ren = (SUMA_CMAP_RENDER_AREA *)SUMA_malloc(sizeof(SUMA_CMAP_RENDER_AREA));
01916    SurfCont->cmp_ren->cmap_wid = NULL;
01917    SurfCont->cmp_ren->FOV = SUMA_CMAP_FOV_INITIAL;
01918    SurfCont->cmp_ren->cmap_context = NULL;
01919    SurfCont->cmp_ren->translateVec[0] = SurfCont->cmp_ren->translateVec[0] = SurfCont->cmp_ren->translateVec[1] = 0.0;
01920    SurfCont->thr_sc = NULL;
01921    SurfCont->brt_sc = NULL;
01922    SurfCont->thr_lb = NULL;
01923    SurfCont->thrstat_lb = NULL;
01924    SurfCont->cmaptit_lb = NULL;
01925    SurfCont->cmapswtch_pb = NULL;
01926    SurfCont->CmapLoad_pb = NULL;
01927    SurfCont->SwitchIntMenu = NULL;
01928    SurfCont->SwitchBrtMenu = NULL;
01929    SurfCont->SwitchThrMenu = NULL;
01930    SurfCont->SwitchCmapMenu = NULL;
01931    SurfCont->rc_CmapCont = NULL;
01932    SurfCont->N_CmapMenu = -1;
01933    SurfCont->CoordBiasMenu[SW_CoordBias] = NULL;
01934    SurfCont->opts_rc = NULL;
01935    SurfCont->opts_form = NULL;
01936    SurfCont->rcvo = NULL;
01937    SurfCont->rcsw = NULL;
01938    SurfCont->rcsw_v1 = NULL;
01939    SurfCont->rcsw_v2 = NULL;
01940    SurfCont->rcswr = NULL;
01941    SurfCont->rccm = NULL;
01942    SurfCont->rccm_swcmap = NULL;
01943    SurfCont->IntRange_lb = NULL;
01944    SurfCont->Int_tb = NULL;
01945    SurfCont->Thr_tb = NULL;
01946    SurfCont->Brt_tb = NULL;
01947    SurfCont->IntRangeLocked = 0;
01948    SurfCont->BrtRangeLocked = 0;
01949    
01950 
01951 
01952   return (SurfCont);
01953 }
01954  
01955 
01956 
01957 
01958 
01959 void *SUMA_FreeSurfContStruct (SUMA_X_SurfCont *SurfCont)
01960 {
01961    static char FuncName[]={"SUMA_FreeSurfContStruct"};
01962 
01963    
01964    if (!SurfCont) return(NULL);
01965    
01966    if (SurfCont->N_links) {
01967       SurfCont = (SUMA_X_SurfCont*)SUMA_UnlinkFromPointer((void *)SurfCont);
01968       return (NULL);
01969    }
01970    
01971    
01972    if (SurfCont->ColPlaneOrder) free (SurfCont->ColPlaneOrder);
01973    if (SurfCont->ColPlaneOpacity) free (SurfCont->ColPlaneOpacity);
01974    if (SurfCont->ColPlaneDimFact) free (SurfCont->ColPlaneDimFact);
01975    if (SurfCont->SetRangeTable) SUMA_FreeTableField (SurfCont->SetRangeTable);
01976    if (SurfCont->RangeTable) SUMA_FreeTableField (SurfCont->RangeTable);
01977    if (SurfCont->XhairTable) SUMA_FreeTableField (SurfCont->XhairTable);
01978    if (SurfCont->NodeTable) SUMA_FreeTableField (SurfCont->NodeTable);
01979    if (SurfCont->FaceTable) SUMA_FreeTableField (SurfCont->FaceTable);
01980    if (SurfCont->DataTable) SUMA_FreeTableField (SurfCont->DataTable);
01981    if (SurfCont->LabelTable) SUMA_FreeTableField (SurfCont->LabelTable); 
01982    if (SurfCont->ColPlaneLabelTable) SUMA_FreeTableField (SurfCont->ColPlaneLabelTable); 
01983    if (SurfCont->SwitchDsetlst) SUMA_FreeScrolledList (SurfCont->SwitchDsetlst);
01984    if (SurfCont->SurfInfo_TextShell) { SUMA_SL_Warn("SurfCont->SurfInfo_TextShell is not being freed") };
01985    if (SurfCont->SwitchIntMenu) { XtDestroyWidget(SurfCont->SwitchIntMenu[0]); SUMA_free(SurfCont->SwitchIntMenu); }
01986    if (SurfCont->SwitchThrMenu) { XtDestroyWidget(SurfCont->SwitchThrMenu[0]); SUMA_free(SurfCont->SwitchThrMenu); }
01987    if (SurfCont->SwitchBrtMenu) { XtDestroyWidget(SurfCont->SwitchBrtMenu[0]); SUMA_free(SurfCont->SwitchBrtMenu); }
01988    if (SurfCont->SwitchCmapMenu) { XtDestroyWidget(SurfCont->SwitchCmapMenu[0]); SUMA_free(SurfCont->SwitchCmapMenu); }
01989    if (SurfCont->curSOp) free(SurfCont->curSOp);
01990    if (SurfCont->cmp_ren) free(SurfCont->cmp_ren);
01991    if (SurfCont) free(SurfCont);
01992    return (NULL);
01993 }
01994 
01995 
01996 
01997 
01998 
01999 SUMA_Boolean SUMA_Free_CommonFields (SUMA_CommonFields *cf)
02000 {
02001    static char FuncName[]={"SUMA_Free_CommonFields"};
02002    int i;
02003    
02004    
02005    if (cf->GroupList) {
02006       for (i=0; i< cf->N_Group; ++i) if (cf->GroupList[i]) SUMA_free(cf->GroupList[i]);
02007       SUMA_free(cf->GroupList); cf->GroupList = NULL;
02008    }
02009    if (cf->ROI_CM) SUMA_Free_ColorMap(cf->ROI_CM);  cf->ROI_CM = NULL;
02010    if (cf->X->FileSelectDlg) SUMA_FreeFileSelectionDialogStruct(cf->X->FileSelectDlg); cf->X->FileSelectDlg = NULL;
02011    if (cf->X->SumaCont) SUMA_FreeSumaContStruct (cf->X->SumaCont); cf->X->SumaCont = NULL;
02012    if (cf->X->DrawROI) SUMA_FreeDrawROIStruct (cf->X->DrawROI); cf->X->DrawROI = NULL;
02013    if (cf->X->N_ForeSmooth_prmpt) SUMA_FreePromptDialogStruct (cf->X->N_ForeSmooth_prmpt); cf->X->N_ForeSmooth_prmpt = NULL;
02014    if (cf->X->SwitchCmapLst) SUMA_FreeScrolledList (cf->X->SwitchCmapLst);
02015    if (cf->X) free(cf->X); cf->X = NULL;
02016    if (cf->MessageList) SUMA_EmptyDestroyList(cf->MessageList); cf->MessageList = NULL;
02017    if (cf->scm) cf->scm = SUMA_DestroyAfniColors (cf->scm); cf->scm = NULL;
02018    if (cf->DsetList) {
02019       dlist_destroy(cf->DsetList); 
02020       SUMA_free(cf->DsetList); cf->DsetList = NULL;
02021    }
02022    #ifdef USE_SUMA_MALLOC
02023    SUMA_SL_Err("NO LONGER SUPPORTED");
02024    return(NOPE);
02025    if (cf->Mem) SUMA_Free_MemTrace (cf->Mem); cf->Mem = NULL;
02026    #endif
02027    
02028     
02029 
02030 
02031 
02032    
02033    return (YUP);
02034 }
02035 
02036 void SUMA_Show_CommonFields (SUMA_CommonFields *cf, FILE *out)
02037 {
02038    static char FuncName[]={"SUMA_Show_CommonFields"};
02039    char *s=NULL;
02040    
02041    s = SUMA_CommonFieldsInfo (cf, 1);
02042    
02043    if (!out) fprintf(SUMA_STDERR,"%s", s);
02044    else fprintf(out,"%s", s);
02045    
02046    SUMA_RETURNe;
02047 }
02048 
02049 char * SUMA_CommonFieldsInfo (SUMA_CommonFields *cf, int detail)
02050 {
02051    static char FuncName[]={"SUMA_CommonFieldsInfo"};
02052    int i;
02053    char *s=NULL;
02054    SUMA_STRING *SS=NULL;
02055    
02056    SUMA_ENTRY;
02057 
02058    SS = SUMA_StringAppend_va(NULL, NULL);
02059    
02060    if (cf == NULL) {
02061       SS = SUMA_StringAppend_va(SS," NULL cf structure.\n", FuncName);
02062       SS = SUMA_StringAppend_va(SS, NULL);
02063       s = SS->s; SUMA_free(SS); SS= NULL;
02064       SUMA_RETURN(s);
02065    }
02066    
02067    for (i=0; i < SUMA_MAX_STREAMS; ++i) {
02068       SS = SUMA_StringAppend_va(SS,"   HostName: %s\n", cf->HostName_v[i]);
02069       SS = SUMA_StringAppend_va(SS,"   NimlStream: %s\n", cf->NimlStream_v[i]);
02070    }
02071    
02072    SS = SUMA_StringAppend_va(SS,"   Available Groups: %d\n", cf->N_Group);
02073    for (i=0; i<cf->N_Group; ++i) {
02074       SS = SUMA_StringAppend_va(SS,"      Group[%d]: %s\n", i, cf->GroupList[i]);
02075    }
02076    
02077    #ifdef USE_SUMA_MALLOC
02078       SUMA_SL_Err("NO LONGER SUPPORTED");
02079       SUMA_RETURN(NULL);
02080    #else 
02081       SS = SUMA_StringAppend_va(SS,"   DBG_trace = %d\n", DBG_trace);
02082       SS = SUMA_StringAppend_va(SS,"   InOut_Notify = %d\n", cf->InOut_Notify);
02083       SS = SUMA_StringAppend_va(SS,"   MemTrace = %d\n", cf->MemTrace);
02084    #endif
02085    
02086    
02087    if (cf->scm) {
02088       SS = SUMA_StringAppend(SS, "   Colormaps:\n");
02089       SS = SUMA_StringAppend(SS, SUMA_ColorMapVec_Info (cf->scm->CMv, cf->scm->N_maps, detail));
02090    } else {
02091       SS = SUMA_StringAppend_va(SS, "   No Colormaps.\n");
02092    }  
02093    
02094    
02095    SS = SUMA_StringAppend_va(SS, NULL);
02096    s = SS->s; SUMA_free(SS); SS= NULL;
02097    
02098    SUMA_RETURN(s);
02099 }
02100 
02101 
02102 
02103 
02104 
02105 
02106 
02107 
02108 
02109 
02110 
02111 
02112    
02113 SUMA_STANDARD_VIEWS SUMA_BestStandardView (SUMA_SurfaceViewer *sv, SUMA_DO *dov, int N_dov)
02114 {
02115    static char FuncName[] = {"SUMA_BestStandardView"};
02116    SUMA_STANDARD_VIEWS ans;
02117    int i, maxdim = -1, is;
02118    SUMA_SurfaceObject *SO = NULL;
02119    
02120    SUMA_ENTRY;
02121 
02122    is = sv->iState;
02123    if (is < 0) {
02124       fprintf(SUMA_STDERR, "Error %s: sv->iState undefined.\n", FuncName);
02125       SUMA_RETURN (SUMA_Dunno); 
02126    }
02127    
02128    for (i=0; i<sv->VSv[is].N_MembSOs; ++i) {   
02129       SO = (SUMA_SurfaceObject *)(dov[sv->VSv[is].MembSOs[i]].OP);
02130       if (SO == NULL) {
02131          fprintf(SUMA_STDERR,"Error %s: SO is null ???\n.", FuncName);
02132          SUMA_RETURN (SUMA_Dunno);
02133       }
02134       if (SO->EmbedDim > maxdim) maxdim = SO->EmbedDim;
02135    }
02136    
02137    switch (maxdim) {
02138       case 2:
02139          SUMA_RETURN (SUMA_2D_Z0);
02140       case 3:
02141          SUMA_RETURN(SUMA_3D);
02142       default:
02143          fprintf(SUMA_STDERR,"Error %s: No provision for such a maximum embedding dimension of %d.\n", FuncName, maxdim);
02144          SUMA_RETURN(SUMA_Dunno);
02145    }
02146 
02147 }
02148 
02149 
02150 
02151 
02152 SUMA_Boolean SUMA_AdoptSurfGroup(SUMA_SurfaceViewer *csv, SUMA_SurfaceObject *SO)
02153 {
02154    static char FuncName[]={"SUMA_AdoptSurfGroup"};
02155 
02156    SUMA_ENTRY;
02157 
02158    csv->iCurGroup = SUMA_WhichGroup(SUMAg_CF, SO->Group);
02159    if (csv->iCurGroup < 0) {
02160       SUMA_SL_Err("Bad, unexpected error.\nGroup was not found");
02161       SUMA_RETURN(NOPE);
02162    }
02163    if (csv->CurGroupName) SUMA_free(csv->CurGroupName);
02164 
02165    csv->CurGroupName = SUMA_copy_string(SO->Group);
02166    SUMA_RETURN(YUP);
02167 }
02168 
02169 
02170 
02171 
02172 SUMA_Boolean SUMA_AdoptGroup(SUMA_SurfaceViewer *csv, char *group)
02173 {
02174    static char FuncName[]={"SUMA_AdoptSurfGroup"};
02175 
02176    SUMA_ENTRY;
02177 
02178    csv->iCurGroup = SUMA_WhichGroup(SUMAg_CF, group);
02179    if (csv->iCurGroup < 0) {
02180       SUMA_SL_Err("Bad, unexpected error.\nGroup was not found");
02181       SUMA_RETURN(NOPE);
02182    }
02183    if (csv->CurGroupName) SUMA_free(csv->CurGroupName);
02184 
02185    csv->CurGroupName = SUMA_copy_string(group);
02186    SUMA_RETURN(YUP);
02187 }
02188 
02189 
02190 
02191 
02192 
02193 
02194 
02195 
02196 
02197 
02198 
02199 
02200 
02201 
02202 
02203 
02204 
02205 
02206 
02207 
02208 
02209 
02210 SUMA_Boolean SUMA_SetupSVforDOs (SUMA_SurfSpecFile Spec, SUMA_DO *DOv, int N_DOv, SUMA_SurfaceViewer *cSV)
02211 {
02212    static char FuncName[] = {"SUMA_SetupSVforDOs"};
02213    int kar;
02214    SUMA_SurfaceObject *SO;
02215    SUMA_Axis *EyeAxis;
02216    int EyeAxis_ID;
02217    SUMA_Boolean LocalHead = NOPE;
02218    
02219    SUMA_ENTRY;
02220 
02221    #if 0
02222    
02223    
02224    for (kar=0; kar < N_DOv; ++kar) {
02225       if (!SUMA_RegisterDO(kar, cSV)) {
02226          SUMA_error_message (FuncName,"Failed to register DO", 1);
02227          SUMA_RETURN(NOPE);
02228       }
02229    }
02230 
02231    
02232    {
02233       SUMA_Boolean SurfIn = NOPE;
02234       for (kar=0; kar < N_DOv; ++kar) {
02235          if (!SUMA_isSO(DOv[kar]) || !SurfIn)
02236          { 
02237             
02238             if (!SUMA_RegisterDO(kar, cSV)) {
02239                SUMA_error_message (FuncName,"Failed to register DO", 1);
02240                SUMA_RETURN(NOPE);
02241             }
02242          }
02243          if (SUMA_isSO(DOv[kar])) { SurfIn = YUP; }
02244       }
02245    }   
02246    #endif 
02247 
02248    #if 1
02249    
02250       
02251       if (LocalHead) {
02252          fprintf (SUMA_STDERR, "%s: Registering SpecSO with viewer [%d]%p, %d\n",
02253              FuncName, SUMA_WhichSV(cSV, SUMAg_SVv, SUMA_MAX_SURF_VIEWERS), cSV, SUMAg_N_SVv);
02254       }
02255       cSV->iCurGroup =  SUMA_WhichGroup(SUMAg_CF, Spec.Group[0]); 
02256       if (cSV->iCurGroup < 0) {
02257          SUMA_SL_Err("Group not found.\n");
02258          SUMA_RETURN(NOPE);
02259       } else {
02260          cSV->CurGroupName = SUMA_copy_string(SUMAg_CF->GroupList[cSV->iCurGroup]);
02261       }
02262       
02263       
02264       if (!SUMA_RegisterSpecSO(&Spec, cSV, DOv, N_DOv)) {
02265          fprintf(SUMA_STDERR,"Error %s: Failed in SUMA_RegisterSpecSO.\n", FuncName);
02266          SUMA_RETURN(NOPE);
02267       } 
02268       SUMA_LH("Done.");
02269 
02270       
02271       if (LocalHead) {
02272          fprintf(SUMA_STDERR,"%s: Registering All SO of the first group ...\n", FuncName);
02273          fprintf(SUMA_STDERR,"%s: cSV->VSv[0].N_MembSOs = %d\n", FuncName, cSV->VSv[0].N_MembSOs);
02274       }
02275       cSV->State = cSV->VSv[0].Name;
02276       cSV->iState = 0;
02277       for (kar=0; kar < cSV->VSv[0].N_MembSOs; ++ kar) {
02278           if (LocalHead) fprintf(SUMA_STDERR," About to register DOv[%d] ...\n", cSV->VSv[0].MembSOs[kar]);
02279             if (!SUMA_RegisterDO(cSV->VSv[0].MembSOs[kar], cSV)) {
02280                SUMA_error_message (FuncName,"Failed to register DO", 1);
02281                SUMA_RETURN(NOPE);
02282             }
02283       }
02284       
02285       
02286    if (LocalHead)   fprintf(SUMA_STDERR,"%s: Done.\n", FuncName);
02287 
02288    
02289    if (LocalHead) fprintf(SUMA_STDERR,"%s: Registering All Non SO ...", FuncName);
02290       for (kar=0; kar < N_DOv; ++kar) {
02291          if (!SUMA_isSO(DOv[kar]))
02292          { 
02293             
02294             if (!SUMA_RegisterDO(kar, cSV)) {
02295                SUMA_error_message (FuncName,"Failed to register DO", 1);
02296                SUMA_RETURN(NOPE);
02297             }
02298          }
02299       }
02300    if (LocalHead) fprintf(SUMA_STDERR,"%s: Done.\n", FuncName);
02301    #endif
02302 
02303    
02304    cSV->StdView = SUMA_BestStandardView (cSV, DOv, N_DOv);
02305    
02306    if (cSV->StdView == SUMA_Dunno) {
02307       fprintf(SUMA_STDERR,"Error %s: Could not determine the best standard view. Choosing default SUMA_3D\n", FuncName);
02308       cSV->StdView = SUMA_3D;
02309    }
02310 
02311    
02312    if (!SUMA_UpdateRotaCenter(cSV, DOv, N_DOv)) {
02313       fprintf (SUMA_STDERR,"Error %s: Failed to update center of rotation", FuncName);
02314       SUMA_RETURN(NOPE);
02315    }
02316 
02317    
02318    if (!SUMA_UpdateViewPoint(cSV, DOv, N_DOv)) {
02319       fprintf (SUMA_STDERR,"Error %s: Failed to update view point", FuncName);
02320       SUMA_RETURN(NOPE);
02321    }
02322 
02323    
02324    EyeAxis_ID = SUMA_GetEyeAxis (cSV, DOv);
02325    if (EyeAxis_ID < 0) {
02326       fprintf (SUMA_STDERR,"Error %s: Failed to get Eye Axis.\n", FuncName);
02327       SUMA_RETURN(NOPE);
02328    }
02329    SUMA_EyeAxisStandard ((SUMA_Axis *)DOv[EyeAxis_ID].OP, cSV);
02330 
02331 
02332    
02333    cSV->Focus_SO_ID = cSV->VSv[0].MembSOs[0];
02334    
02335    SO = (SUMA_SurfaceObject *)(DOv[cSV->Focus_SO_ID].OP);
02336    if (!SUMA_AdoptSurfGroup(cSV,SO)) {
02337       SUMA_SL_Err("Failed to adopt surface's group");
02338       SUMA_RETURN(NOPE);
02339    }
02340    
02341    
02342    if (SO->FileType == SUMA_SUREFIT || SO->FileType == SUMA_OPENDX_MESH) {
02343       SUMA_LH("Flippo for safety");
02344       cSV->light0_position[0] *= -1;
02345       cSV->light0_position[1] *= -1;      
02346       cSV->light0_position[2] *= -1;
02347    }
02348    
02349    
02350    SUMA_WorldAxisStandard (cSV->WAx, cSV);
02351 
02352 
02353    SUMA_RETURN(YUP);
02354 }
02355 
02356 
02357 
02358 
02359 void SUMA_UpdateAllViewerCursor()
02360 {
02361    static char FuncName[]={"SUMA_UpdateAllViewerCursor"};
02362    int i;
02363    
02364    SUMA_ENTRY;
02365    
02366    for (i=0; i<SUMAg_N_SVv; ++i) {
02367       if (SUMAg_SVv[i].X) {
02368          SUMA_UpdateViewerCursor(&(SUMAg_SVv[i]));
02369       } 
02370    }
02371    
02372    SUMA_RETURNe;
02373 }
02374 
02375 
02376 
02377 
02378 void SUMA_UpdateViewerCursor(SUMA_SurfaceViewer *sv)   
02379 {  
02380    static char FuncName[]={"SUMA_UpdateViewerCursor"};
02381    SUMA_Boolean LocalHead = NOPE;
02382 
02383    SUMA_ENTRY;
02384 
02385    if (!sv->X) SUMA_RETURNe;
02386    if (!sv->X->GLXAREA) SUMA_RETURNe;
02387    if (SUMAg_CF->ROI_mode) {
02388       if (SUMAg_CF->Pen_mode) MCW_set_widget_cursor( sv->X->GLXAREA  , -XC_pencil ) ;
02389       else  MCW_set_widget_cursor( sv->X->GLXAREA  , -XC_target ) ;
02390    } else {
02391       MCW_set_widget_cursor( sv->X->GLXAREA  , -XC_top_left_arrow ) ;
02392    }
02393    SUMA_RETURNe;
02394 }
02395 
02396 
02397 
02398 
02399 
02400 void SUMA_UpdateViewerTitle_old(SUMA_SurfaceViewer *sv)   
02401 {  
02402    static char FuncName[]={"SUMA_UpdateViewerTitle_old"};
02403    int isv, i, N_SOlist, nalloc;  
02404    char slabel[30], sside[30], srec[10], cl='\0', cr='\0', smoment[30];   
02405    SUMA_SurfaceObject *SO = NULL;   
02406    int SOlist[SUMA_MAX_DISPLAYABLE_OBJECTS];   
02407    SUMA_Boolean LeftSide, RightSide, RightShown, LeftShown;
02408    SUMA_Boolean LocalHead = NOPE;
02409    
02410    SUMA_ENTRY;
02411 
02412    if (!sv->X) SUMA_RETURNe;
02413    if (!sv->X->TOPLEVEL) SUMA_RETURNe;
02414 
02415    isv = SUMA_WhichSV (sv, SUMAg_SVv, SUMAg_N_SVv);   
02416    
02417    if (sv->X->Title) SUMA_free(sv->X->Title);
02418    sv->X->Title = NULL;
02419       
02420    if (isv >= 0) sprintf(slabel,"[%c] SUMA", 65+isv); 
02421    else sprintf(slabel,"[DOH] SUMA"); 
02422    
02423    N_SOlist = SUMA_RegisteredSOs(sv, SUMAg_DOv, SOlist);   
02424    
02425    i = 0; 
02426    nalloc = 0;  
02427    LeftSide = NOPE;
02428    LeftShown = NOPE;
02429    RightSide = NOPE;
02430    RightShown = NOPE;
02431    while (i < N_SOlist) {   
02432       SO = (SUMA_SurfaceObject *)(SUMAg_DOv[SOlist[i]].OP);   
02433       if (SO->Label) { 
02434          nalloc +=  (strlen(SO->Label)+5);  
02435       }
02436       if (SO->Side == SUMA_LEFT) {
02437          SUMA_LH("Left found");
02438          LeftSide = YUP;
02439          if (sv->ShowLeft) LeftShown = YUP;
02440       } else if (SO->Side == SUMA_RIGHT) {
02441          SUMA_LH("Right found");
02442          RightSide = YUP;  
02443          if (sv->ShowRight) RightShown = YUP; 
02444       }
02445       
02446       ++i;   
02447    }
02448    if (LeftSide && LeftShown) cl = 'L';
02449    else if (LeftSide && !LeftShown) cl = 'h';
02450    else cl = 'x';
02451    if (RightSide && RightShown) cr = 'R';
02452    else if (RightSide && !RightShown) cr = 'h';
02453    else cr = 'x';
02454    
02455    
02456    sprintf(sside, ":%c%c:", cl, cr);
02457    
02458    if (sv->Record) sprintf(srec,":Rec");
02459    else srec[0] = '\0';
02460    
02461    if (sv->GVS[sv->StdView].ApplyMomentum) sprintf(smoment,":M");
02462    else smoment[0] = '\0';
02463    
02464    if (LocalHead) fprintf (SUMA_STDERR, "%s: Found %d surface models.\n", FuncName, N_SOlist);
02465    
02466    i = 0; 
02467    if (N_SOlist >= 0) {   
02468       SUMA_LH("title surfaces found");
02469       sv->X->Title = (char *)SUMA_calloc(nalloc + strlen(slabel)+ 13, sizeof(char));      
02470       sv->X->Title[0] = '\0';
02471       while (i < N_SOlist) {   
02472          SO = (SUMA_SurfaceObject *)(SUMAg_DOv[SOlist[i]].OP);   
02473          if (LocalHead) fprintf (SUMA_STDERR,"%s: sv->Focus_SO_ID = %d,  SOlist[%d] = %d\n", FuncName, sv->Focus_SO_ID, i, SOlist[i]);
02474          if (!i)  {
02475             if (sv->Focus_SO_ID == SOlist[i]) {
02476                sprintf (sv->X->Title,"%s%s%s%s [%s]", slabel, srec, smoment, sside, SO->Label); 
02477             } else {
02478                sprintf (sv->X->Title,"%s%s%s%s %s", slabel, srec, smoment, sside, SO->Label); 
02479             }
02480          } else {
02481             sv->X->Title = strcat (sv->X->Title, " & ");
02482             if (sv->Focus_SO_ID == SOlist[i]) {
02483                sv->X->Title = strcat (sv->X->Title, " [");
02484                sv->X->Title = strcat (sv->X->Title, SO->Label); 
02485                sv->X->Title = strcat (sv->X->Title, "] "); 
02486             } else  {
02487                sv->X->Title = strcat (sv->X->Title, SO->Label); 
02488             }
02489          }
02490          ++i;   
02491       }  
02492    } else {   
02493       SUMA_LH("No title could be made up");
02494       sv->X->Title = (char *)SUMA_calloc(strlen(slabel)+3, sizeof(char));  
02495       sprintf (sv->X->Title,"%s:-", slabel);   
02496    }  
02497    
02498    XtVaSetValues(sv->X->TOPLEVEL,  
02499             XmNtitle, sv->X->Title,  
02500             NULL);
02501             
02502    SUMA_RETURNe;   
02503 }
02504 
02505 
02506 
02507 
02508 void SUMA_UpdateViewerTitle(SUMA_SurfaceViewer *sv)   
02509 {  
02510    static char FuncName[]={"SUMA_UpdateViewerTitle"};
02511    int isv, i, N_SOlist;  
02512    char cl='\0', cr='\0', *s=NULL;   
02513    SUMA_SurfaceObject *SO = NULL;   
02514    int SOlist[SUMA_MAX_DISPLAYABLE_OBJECTS];   
02515    SUMA_STRING *SS = NULL;
02516    SUMA_Boolean LeftSide, RightSide, RightShown, LeftShown;
02517    SUMA_Boolean LocalHead = NOPE;
02518    
02519    SUMA_ENTRY;
02520 
02521    if (!sv->X) SUMA_RETURNe;
02522    if (!sv->X->TOPLEVEL) SUMA_RETURNe;
02523 
02524    SUMA_LH("Finding SV");
02525    isv = SUMA_WhichSV (sv, SUMAg_SVv, SUMAg_N_SVv);   
02526    
02527    if (sv->X->Title) SUMA_free(sv->X->Title);
02528    sv->X->Title = NULL;
02529    
02530    SS = SUMA_StringAppend_va(NULL, NULL);
02531    
02532    SUMA_LH("Number");
02533    if (isv >= 0) SS = SUMA_StringAppend_va(SS, "[%c] SUMA", 65+isv); 
02534    else SS = SUMA_StringAppend_va(SS,"[DOH] SUMA"); 
02535    
02536    SUMA_LH("Rec");
02537    if (sv->Record) SS = SUMA_StringAppend_va(SS,":Rec");
02538    
02539    SUMA_LH("Momentum");
02540    if (sv->GVS[sv->StdView].ApplyMomentum) SS = SUMA_StringAppend_va(SS,":M");
02541    
02542    SUMA_LH("Surf List");
02543    N_SOlist = SUMA_RegisteredSOs(sv, SUMAg_DOv, SOlist);   
02544    
02545    i = 0; 
02546    LeftSide = NOPE;
02547    LeftShown = NOPE;
02548    RightSide = NOPE;
02549    RightShown = NOPE;
02550    while (i < N_SOlist) {   
02551       SUMA_LH("   + +");
02552       SO = (SUMA_SurfaceObject *)(SUMAg_DOv[SOlist[i]].OP);   
02553       if (SO->Side == SUMA_LEFT) {
02554          SUMA_LH("Left found");
02555          LeftSide = YUP;
02556          if (sv->ShowLeft) LeftShown = YUP;
02557       } else if (SO->Side == SUMA_RIGHT) {
02558          SUMA_LH("Right found");
02559          RightSide = YUP;  
02560          if (sv->ShowRight) RightShown = YUP; 
02561       }
02562       
02563       ++i;   
02564    }
02565    
02566    if (LeftSide && LeftShown) cl = 'L';
02567    else if (LeftSide && !LeftShown) cl = 'h';
02568    else cl = 'x';
02569    if (RightSide && RightShown) cr = 'R';
02570    else if (RightSide && !RightShown) cr = 'h';
02571    else cr = 'x';
02572    
02573    SUMA_LH("Sides");
02574    
02575    SS = SUMA_StringAppend_va(SS, ":%c%c:", cl, cr);
02576    
02577    if (LocalHead) fprintf (SUMA_STDERR, "%s: Found %d surface models.\n", FuncName, N_SOlist);
02578    
02579    
02580    if (LocalHead) {
02581       if (sv->CurGroupName) fprintf (SUMA_STDERR, "%s: Calling with sv->CurGroupName = %p\n", FuncName, sv->CurGroupName);
02582       else fprintf (SUMA_STDERR, "%s: Calling with NULL sv->CurGroupName\n", FuncName);
02583    }
02584       
02585    if (sv->CurGroupName) SS = SUMA_StringAppend_va(SS," %s:", sv->CurGroupName);
02586    else SS = SUMA_StringAppend_va(SS," xx:");
02587    
02588    i = 0; 
02589    if (N_SOlist >= 0) {   
02590       SUMA_LH("title surfaces found");
02591       while (i < N_SOlist) {   
02592          SO = (SUMA_SurfaceObject *)(SUMAg_DOv[SOlist[i]].OP);   
02593          if (LocalHead) fprintf (SUMA_STDERR,"%s: sv->Focus_SO_ID = %d,  SOlist[%d] = %d\n", FuncName, sv->Focus_SO_ID, i, SOlist[i]);
02594          if (!i)  {
02595             if (sv->Focus_SO_ID == SOlist[i]) {
02596                SS = SUMA_StringAppend_va(SS," [%s]",  SO->Label); 
02597             } else {
02598                SS = SUMA_StringAppend_va(SS," %s",  SO->Label); 
02599             }
02600          } else {
02601             SS = SUMA_StringAppend_va(SS," & ");
02602             if (sv->Focus_SO_ID == SOlist[i]) {
02603                SS = SUMA_StringAppend_va(SS, " [");
02604                SS = SUMA_StringAppend_va(SS, "%s", SO->Label); 
02605                SS = SUMA_StringAppend_va(SS, "] "); 
02606             } else  {
02607                SS = SUMA_StringAppend_va(SS, "%s", SO->Label); 
02608             }
02609          }
02610          ++i;   
02611       }  
02612    } else {   
02613       SUMA_LH("No title could be made up");
02614       SS = SUMA_StringAppend_va(SS,":-");   
02615    }  
02616    
02617    
02618    SS = SUMA_StringAppend_va(SS, NULL);
02619    
02620    sv->X->Title = SS->s;
02621    
02622    SUMA_free(SS); SS= NULL;
02623    
02624    XtVaSetValues(sv->X->TOPLEVEL,  
02625             XmNtitle, sv->X->Title,  
02626             NULL);
02627             
02628    SUMA_RETURNe;   
02629 }
02630 
02631 
02632 
02633 
02634 int SUMA_WhichGroup (SUMA_CommonFields *cf, char *nm)
02635 {
02636    static char FuncName[]={"SUMA_WhichGroup"};
02637    int i = -1;
02638    
02639    SUMA_ENTRY;
02640    
02641    if (!nm || !cf) {
02642       SUMA_SL_Err("Null nm or cf");
02643       SUMA_RETURN(i);
02644    }
02645    
02646    if (cf->N_Group <=0) { SUMA_RETURN(i); }
02647    
02648    for (i=0; i<cf->N_Group; ++i) {
02649       if (!strcmp(cf->GroupList[i], nm)) SUMA_RETURN(i);
02650    } 
02651    
02652    SUMA_RETURN(-1);
02653 }
02654 
02655 
02656 
02657 SUMA_Boolean SUMA_RegisterGroup (SUMA_CommonFields *cf, SUMA_SurfSpecFile *spec)
02658 {
02659    static char FuncName[]={"SUMA_RegisterGroup"};
02660    int n=0;
02661    SUMA_Boolean LocalHead = NOPE;
02662    
02663    SUMA_ENTRY;
02664    
02665    if (spec->N_Groups != 1) {
02666       SUMA_SL_Err("Spec->N_Groups != 1. This is unacceptable.\n");
02667       SUMA_RETURN(NOPE);
02668    }
02669    
02670    if (!cf->GroupList){
02671       cf->GroupList = (char **) SUMA_malloc(sizeof(char*)*SUMA_MAX_N_GROUPS);
02672       for (n=0; n<SUMA_MAX_N_GROUPS; ++n) cf->GroupList[n]=NULL;
02673       cf->N_Group = 0;
02674    }
02675    
02676    
02677    if (SUMA_WhichGroup (cf, spec->Group[0]) < 0) {
02678       
02679       SUMA_LH("Adding group");
02680       if (cf->N_Group >=  SUMA_MAX_N_GROUPS) {
02681          SUMA_SL_Err("Exceeding maximum number of groups allowed.\n");
02682          SUMA_RETURN(NOPE);
02683       }
02684       cf->GroupList[cf->N_Group] = SUMA_copy_string(spec->Group[0]);
02685       ++cf->N_Group;
02686    } else{ 
02687       
02688       SUMA_LH("Group exists already");
02689    }
02690    SUMA_RETURN(YUP);
02691    
02692 }
02693 
02694 
02695 
02696 
02697 
02698 
02699 
02700 
02701 
02702 
02703 
02704 
02705 SUMA_ASSEMBLE_LIST_STRUCT * SUMA_AssembleGroupList (SUMA_SurfaceViewer *sv) 
02706 {
02707    static char FuncName[]={"SUMA_AssembleGroupList"};
02708    SUMA_ASSEMBLE_LIST_STRUCT *clist_str = NULL;
02709    int i=-1, N_clist=-1; 
02710    char *store=NULL;
02711    char **clist=NULL;
02712    void **oplist=NULL;
02713    DList *list=NULL, *listop = NULL;
02714    DListElmt *Elm = NULL, *Elmop = NULL;
02715    SUMA_Boolean Found = NOPE;
02716    SUMA_Boolean LocalHead = NOPE;
02717    
02718    SUMA_ENTRY;
02719    
02720    list = (DList *)SUMA_malloc(sizeof(DList));
02721    listop = (DList *)SUMA_malloc(sizeof(DList));
02722    
02723    clist = NULL;
02724    N_clist = -1;
02725    
02726    dlist_init(list, NULL);
02727    dlist_init(listop, NULL);
02728    
02729    for (i=0; i< SUMAg_CF->N_Group; ++i) {
02730       store = SUMA_copy_string(SUMAg_CF->GroupList[i]);
02731       if (!list->size) {
02732          dlist_ins_next(list, dlist_tail(list), (void*)store);
02733          dlist_ins_next(listop, dlist_tail(listop), NULL);
02734       } else { 
02735          Elm = NULL;
02736          Elmop = NULL;
02737          do {
02738             Found = NOPE;
02739             if (!Elm) {
02740                Elm = dlist_head(list);
02741                Elmop = dlist_head(listop);
02742             } else {
02743                Elm = dlist_next(Elm);
02744                Elmop = dlist_next(Elmop);
02745             }
02746 
02747             if (strcmp(store, (char*)Elm->data) <= 0) {
02748                dlist_ins_prev(list, Elm, (void *)store);
02749                dlist_ins_prev(listop, Elmop, NULL);
02750                Found = YUP;
02751             } else if (Elm == dlist_tail(list)) {
02752                
02753                dlist_ins_next(list, Elm, (void *)store);
02754                dlist_ins_next(listop, Elmop, NULL);
02755                Found = YUP;
02756             }
02757          } while (!Found);
02758       }
02759    }
02760    
02761    if (!list->size) { 
02762       N_clist = 0;
02763       
02764    }else {
02765    
02766       Elm = NULL;
02767       Elmop = NULL;
02768       clist = (char **)SUMA_calloc(list->size, sizeof(char *));
02769       oplist = (void **)SUMA_calloc(list->size, sizeof(void*));
02770       for (i=0; i< list->size; ++i) {
02771          if (!Elm) {
02772             Elm = dlist_head(list);
02773             Elmop = dlist_head(listop);
02774          } else {
02775             Elm = dlist_next(Elm);
02776             Elmop = dlist_next(Elmop);
02777          }
02778          clist[i] = (char*)Elm->data;
02779          oplist[i] = Elmop->data;
02780       }
02781 
02782       N_clist = list->size;
02783       
02784       dlist_destroy(list);
02785       dlist_destroy(listop);
02786       SUMA_free(list);
02787       SUMA_free(listop);
02788    }
02789    
02790    clist_str = SUMA_CreateAssembleListStruct();
02791    clist_str->clist = clist;
02792    clist_str->oplist = oplist;
02793    clist_str->N_clist = N_clist;
02794    
02795    
02796    SUMA_RETURN (clist_str);  
02797 }
02798 
02799 
02800 
02801 
02802 SUMA_Boolean SUMA_SwitchGroups (SUMA_SurfaceViewer *sv, char *group) 
02803 {
02804    static char FuncName[]={"SUMA_SwitchGroups"};
02805    int ig, i, nxtstateID;
02806    SUMA_SurfaceObject *SO = NULL;
02807    DList *list = NULL;      
02808    SUMA_Boolean LocalHead = NOPE;
02809    
02810    SUMA_ENTRY;
02811    
02812    if (!group) {
02813       SUMA_SL_Err("NULL group");
02814       SUMA_RETURN(NOPE);
02815    }
02816    
02817    if (!strcmp(group, sv->CurGroupName)) {
02818       SUMA_LH("Same group, nothing to do.");
02819       SUMA_RETURN(YUP);
02820    }
02821    
02822    if (SUMAg_CF->N_Group == 1) {
02823       SUMA_LH("One group, nothing to do.");
02824       SUMA_RETURN(YUP);
02825    }
02826    
02827    
02828    ig = SUMA_WhichGroup (SUMAg_CF, group);
02829    
02830    if (ig < 0) {
02831       SUMA_SL_Err("No such group");
02832       SUMA_RETURN(NOPE);
02833    }
02834    
02835    
02836 
02837    
02838    SO = NULL;
02839    i = 0;
02840    while (!SUMA_isSO_G(SUMAg_DOv[i], group) && i < SUMAg_N_DOv) {
02841       ++i;
02842    } 
02843    if (i < SUMAg_N_DOv) { 
02844       SO = (SUMA_SurfaceObject *)SUMAg_DOv[i].OP;
02845    } else {
02846       SUMA_SL_Err("No candidate surface");
02847       SUMA_RETURN(NOPE);
02848    } 
02849    
02850    
02851    nxtstateID = SUMA_WhichState(SO->State, sv, SO->Group);
02852    if (nxtstateID < 0) {
02853       SUMA_SL_Err("Bad! State not found.");
02854       SUMA_RETURN(NOPE);
02855    }
02856    
02857    if (!SUMA_SwitchState (SUMAg_DOv, SUMAg_N_DOv, sv,  nxtstateID, group)) {
02858       SUMA_SL_Err("Failed to switch states");
02859       SUMA_RETURN(NOPE);
02860    }  
02861 
02862    
02863    
02864    #if 0
02865       
02866       if (!list) list = SUMA_CreateList();
02867       
02868       SUMA_REGISTER_HEAD_COMMAND_NO_DATA(list, SE_Redisplay, SES_Suma, sv);
02869 
02870       if (!SUMA_Engine (&list)) {
02871          fprintf(stderr, "Error %s: SUMA_Engine call failed.\n", FuncName);
02872       }
02873    #elif 0
02874                   
02875                   if (!list) list = SUMA_CreateList ();
02876                   SUMA_REGISTER_TAIL_COMMAND_NO_DATA(list, SE_RedisplayNow_AllOtherVisible, SES_SumaWidget, sv);
02877                   SUMA_Engine (&list);
02878                
02879                   
02880                   sv->ResetGLStateVariables = YUP;
02881                   SUMA_handleRedisplay((XtPointer)sv->X->GLXAREA);
02882    #elif 1
02883             
02884             
02885 
02886             for (i=0; i < SUMAg_N_SVv; ++i) {
02887                SUMA_SurfaceViewer *svtmp= &(SUMAg_SVv[i]);
02888                if (!svtmp->isShaded && svtmp->X->TOPLEVEL) {
02889                   if (!list) list = SUMA_CreateList();
02890                   SUMA_REGISTER_HEAD_COMMAND_NO_DATA(list, SE_Home, SES_Suma, svtmp); 
02891                   SUMA_REGISTER_HEAD_COMMAND_NO_DATA(list, SE_RedisplayNow, SES_Suma, svtmp); 
02892                   if (!SUMA_Engine (&list)) {
02893                         fprintf(stderr, "Error %s: SUMA_Engine call failed.\n", FuncName);
02894                   }
02895                }
02896             }
02897             
02898             if (!list) list = SUMA_CreateList();
02899             SUMA_REGISTER_HEAD_COMMAND_NO_DATA(list, SE_Redisplay_AllVisible, SES_Suma, sv);
02900             if (!SUMA_Engine (&list)) {
02901                            fprintf(stderr, "Error %s: SUMA_Engine call failed.\n", FuncName);
02902             }
02903             
02904    #endif
02905 
02906    
02907    SUMA_UpdateViewerTitle(sv);
02908    
02909    
02910    SUMA_RETURN(YUP);
02911 }