Back to index

lightning-sunbird  0.9+nobinonly
SetupTypeWin.c
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla Communicator client code, released
00016  * March 31, 1998.
00017  *
00018  * The Initial Developer of the Original Code is
00019  * Netscape Communications Corporation.
00020  * Portions created by the Initial Developer are Copyright (C) 1999
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *   Samir Gehani <sgehani@netscape.com>
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either of the GNU General Public License Version 2 or later (the "GPL"),
00028  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 #include "MacInstallWizard.h"
00041 
00042 
00043 #include <Math64.h>
00044 
00045 
00046 /*-----------------------------------------------------------*
00047  *   Setup Type Window
00048  *-----------------------------------------------------------*/
00049 
00050 static long sDSNeededK = 0;  /* disk space needed in KB */
00051 static long sDSAvailK = 0;   /* disk space available in KB */
00052 
00053 void 
00054 ShowSetupTypeWin(void)
00055 {
00056        Str255                             next;
00057        Str255                             back;
00058        MenuHandle                  popupMenu;
00059        PopupPrivateData ** pvtDataHdl;
00060        unsigned char *             currMenuItem;
00061        short                       i;
00062 /*     
00063        short                       numVols;
00064        unsigned char **     volName;
00065 */
00066        Rect                        viewRect;
00067        long                        txtSize;
00068        Str255                      instLocTitle, selectFolder;
00069        GrafPtr                            oldPort;
00070        
00071        GetPort(&oldPort);
00072        
00073        if (gWPtr != NULL)
00074        {
00075               SetPort(gWPtr);
00076        
00077               gCurrWin = kSetupTypeID; 
00078               /* gControls->stw = (SetupTypeWin *) NewPtrClear(sizeof(SetupTypeWin));      */
00079 
00080               GetResourcedString(next, rInstList, sNextBtn);
00081               GetResourcedString(back, rInstList, sBackBtn);
00082        
00083               // malloc and get controls
00084               gControls->stw->instType = GetNewControl( rInstType, gWPtr);
00085               gControls->stw->instDescBox = GetNewControl( rInstDescBox, gWPtr);
00086               gControls->stw->destLocBox = GetNewControl( rDestLocBox, gWPtr);
00087               gControls->stw->destLoc = GetNewControl(rDestLoc, gWPtr);
00088               if (!gControls->stw->instType || !gControls->stw->instDescBox || 
00089                      !gControls->stw->destLocBox || !gControls->stw->destLoc)
00090               {
00091                      ErrorHandler(eMem, nil);
00092                      return;
00093               }
00094 
00095               // populate popup button menus
00096               HLock((Handle)gControls->stw->instType);
00097               pvtDataHdl = (PopupPrivateData **) (*(gControls->stw->instType))->contrlData;
00098               HLock((Handle)pvtDataHdl);
00099               popupMenu = (MenuHandle) (**pvtDataHdl).mHandle;
00100               for (i=0; i<gControls->cfg->numSetupTypes; i++)
00101               {
00102                      HLock(gControls->cfg->st[i].shortDesc);
00103                      currMenuItem = CToPascal(*gControls->cfg->st[i].shortDesc);           
00104                      HUnlock(gControls->cfg->st[i].shortDesc);
00105                      InsertMenuItem( popupMenu, currMenuItem, i);
00106               }
00107               HUnlock((Handle)pvtDataHdl);
00108               HUnlock((Handle)gControls->stw->instType);
00109               SetControlMaximum(gControls->stw->instType, gControls->cfg->numSetupTypes);
00110               SetControlValue(gControls->stw->instType, gControls->opt->instChoice);
00111        
00112               // setup type desc TE init and default item desc display
00113               HLock((Handle)gControls->stw->instDescBox);
00114               SetRect(&viewRect,  (*(gControls->stw->instDescBox))->contrlRect.left,
00115                                                  (*(gControls->stw->instDescBox))->contrlRect.top,
00116                                                  (*(gControls->stw->instDescBox))->contrlRect.right,
00117                                                  (*(gControls->stw->instDescBox))->contrlRect.bottom);
00118               HUnlock((Handle)gControls->stw->instDescBox);    
00119               InsetRect(&viewRect, kTxtRectPad, kTxtRectPad);
00120 
00121               TextFont(systemFont);
00122               TextFace(normal);
00123               TextSize(12); 
00124               gControls->stw->instDescTxt = TENew( &viewRect, &viewRect);
00125               HLock(gControls->cfg->st[gControls->opt->instChoice - 1].longDesc);
00126               txtSize = strlen(*gControls->cfg->st[gControls->opt->instChoice - 1].longDesc);
00127               TEInsert( *gControls->cfg->st[gControls->opt->instChoice - 1].longDesc, txtSize, gControls->stw->instDescTxt);
00128               TESetAlignment( teFlushDefault, gControls->stw->instDescTxt);
00129               HUnlock(gControls->cfg->st[gControls->opt->instChoice - 1].longDesc);
00130 
00131 /*
00132     volName = (unsigned char **)NewPtrClear(sizeof(unsigned char *));
00133        GetAllVInfo(volName, &numVols);    
00134        gControls->stw->numVols = numVols;
00135        HLock((Handle)gControls->stw->destLoc);
00136        pvtDataHdl = (PopupPrivateData **) (*(gControls->stw->destLoc))->contrlData;
00137        popupMenu = (MenuHandle) (**pvtDataHdl).mHandle;
00138        for (i=0; i<numVols; i++)
00139        {
00140               InsertMenuItem( popupMenu, volName[i], i);
00141        }
00142        InsertMenuItem( popupMenu, "\p-", i);
00143        GetIndString(selectFolder, rStringList, sSelectFolder);
00144        InsertMenuItem( popupMenu, selectFolder, i+1);   
00145        HUnlock((Handle)gControls->stw->destLoc);
00146        
00147        SetControlMaximum(gControls->stw->destLoc, numVols+2); // 2 extra for divider and "Select Folder..." item
00148        SetControlValue(gControls->stw->destLoc, 1);
00149 */
00150               GetResourcedString(selectFolder, rInstList, sSelectFolder);
00151               SetControlTitle(gControls->stw->destLoc, selectFolder);
00152               GetResourcedString(instLocTitle, rInstList, sInstLocTitle);
00153               SetControlTitle(gControls->stw->destLocBox, instLocTitle);     
00154        
00155               // show controls
00156               ShowControl(gControls->stw->instType);
00157               ShowControl(gControls->stw->destLoc);
00158               ShowNavButtons( back, next );
00159        
00160               DrawDiskNFolder(gControls->opt->vRefNum, gControls->opt->folder);
00161        }
00162               
00163        SetPort(oldPort);
00164 }
00165 
00166 void
00167 ShowSetupDescTxt(void)
00168 {
00169        Rect teRect; /* TextEdit rect */
00170        
00171        if (gControls->stw->instDescTxt)
00172        {
00173               teRect = (**(gControls->stw->instDescTxt)).viewRect;
00174               TEUpdate(&teRect, gControls->stw->instDescTxt);
00175        }
00176        
00177        DrawDiskNFolder(gControls->opt->vRefNum, gControls->opt->folder);
00178 }
00179 
00180 pascal void
00181 OurNavEventFunction(NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms,
00182                                    NavCallBackUserData callBackUD)
00183 {
00184        WindowPtr  windowPtr;
00185   
00186   if (!callBackParms || !callBackParms->eventData.eventDataParms.event)
00187        return;
00188 
00189        windowPtr = (WindowPtr)callBackParms->eventData.eventDataParms.event->message;
00190        if (!windowPtr)
00191               return;
00192               
00193        switch(callBackSelector)
00194        {
00195               case kNavCBEvent:
00196                      switch(callBackParms->eventData.eventDataParms.event->what)
00197                      {
00198                             case updateEvt:
00199                                    if(((WindowPeek) windowPtr)->windowKind != kDialogWindowKind)
00200                                           HandleUpdateEvt((EventRecord *) callBackParms->eventData.eventDataParms.event);
00201                                    break;
00202                      }
00203                      break;
00204        } 
00205 }
00206 
00207 static Boolean bFirstFolderSelection = true;
00208 
00209 void 
00210 InSetupTypeContent(EventRecord* evt, WindowPtr wCurrPtr)
00211 {      
00212        Point                       localPt;
00213        Rect                        r;
00214        ControlPartCode             part;  
00215        short                       cntlVal;
00216        long                        len;
00217        ControlHandle               currCntl;
00218        int                                instChoice;
00219        
00220        /* NavChooseFolder vars */
00221        NavReplyRecord              reply; 
00222        NavDialogOptions     dlgOpts;
00223        NavEventUPP                 eventProc;
00224        AEDesc                      resultDesc, initDesc;
00225        FSSpec                      folderSpec, tmp;
00226        OSErr                       err;
00227        long                        realDirID;
00228 
00229        GrafPtr                            oldPort;
00230        GetPort(&oldPort);
00231        SetPort(wCurrPtr);
00232        
00233        localPt = evt->where;
00234        GlobalToLocal( &localPt);
00235        
00236        HLock((Handle)gControls->stw->instType);
00237        SetRect(&r, (**(gControls->stw->instType)).contrlRect.left,
00238                             (**(gControls->stw->instType)).contrlRect.top,
00239                             (**(gControls->stw->instType)).contrlRect.right,
00240                             (**(gControls->stw->instType)).contrlRect.bottom);
00241        HUnlock((Handle)gControls->stw->instType);
00242        if (PtInRect(localPt, &r))
00243        {
00244               part = FindControl(localPt, gWPtr, &currCntl);
00245               part = TrackControl(currCntl, localPt, (ControlActionUPP) -1);
00246               
00247               gControls->opt->instChoice = GetControlValue(currCntl);
00248               instChoice = gControls->opt->instChoice - 1;
00249               
00250               SetRect(&r, (**(gControls->stw->instDescTxt)).viewRect.left,
00251                                    (**(gControls->stw->instDescTxt)).viewRect.top,
00252                                    (**(gControls->stw->instDescTxt)).viewRect.right,
00253                                    (**(gControls->stw->instDescTxt)).viewRect.bottom);
00254                                    
00255               HLock(gControls->cfg->st[instChoice].longDesc);
00256               len = strlen(*gControls->cfg->st[instChoice].longDesc);
00257               TESetText( *gControls->cfg->st[instChoice].longDesc, len, gControls->stw->instDescTxt);
00258               HUnlock(gControls->cfg->st[instChoice].longDesc);
00259 
00260               EraseRect( &r );
00261               TEUpdate( &r, gControls->stw->instDescTxt);
00262               
00263               ClearDiskSpaceMsgs();
00264               DrawDiskSpaceMsgs(gControls->opt->vRefNum);
00265               return;
00266        }
00267        
00268        HLockHi((Handle)gControls->stw->destLoc);
00269        SetRect(&r, (**(gControls->stw->destLoc)).contrlRect.left,
00270                             (**(gControls->stw->destLoc)).contrlRect.top,
00271                             (**(gControls->stw->destLoc)).contrlRect.right,
00272                             (**(gControls->stw->destLoc)).contrlRect.bottom);
00273        HUnlock((Handle)gControls->stw->destLoc);
00274        if (PtInRect(localPt, &r))
00275        {
00276               part = FindControl(localPt, gWPtr, &currCntl);
00277               part = TrackControl(currCntl, localPt, (ControlActionUPP) -1);
00278               cntlVal = GetControlValue(currCntl);
00279               
00280               err = NavGetDefaultDialogOptions(&dlgOpts);
00281               GetResourcedString( dlgOpts.message, rInstList, sFolderDlgMsg );
00282               eventProc = NewNavEventUPP( OurNavEventFunction );
00283               
00284               if (!bFirstFolderSelection)
00285                      GetParentID(gControls->opt->vRefNum, gControls->opt->dirID, "\p", &realDirID);
00286               else
00287               {
00288                      realDirID = gControls->opt->dirID;
00289                      bFirstFolderSelection = false;
00290               }
00291               FSMakeFSSpec(gControls->opt->vRefNum, realDirID, "\p", &tmp);
00292               ERR_CHECK(AECreateDesc(typeFSS, (void*) &tmp, sizeof(FSSpec), &initDesc));
00293               err = NavChooseFolder( &initDesc, &reply, &dlgOpts, eventProc, NULL, NULL );
00294               
00295               AEDisposeDesc(&initDesc);
00296               DisposeRoutineDescriptor(eventProc);
00297               
00298               if((reply.validRecord) && (err == noErr))
00299               {
00300                      if((err = AECoerceDesc(&(reply.selection),typeFSS,&resultDesc)) == noErr)
00301                      {
00302                             BlockMoveData(*resultDesc.dataHandle,&tmp,sizeof(FSSpec));
00303                             /* forces name to get filled */
00304                             FSMakeFSSpec(tmp.vRefNum, tmp.parID, tmp.name, &folderSpec); 
00305                             
00306                             /* NOTE: 
00307                             ** ----
00308                             ** gControls->opt->parID and gControls->opt->folder refer to the
00309                             ** same folder. The -dirID- is used by Install() when passing params to
00310                             ** the SDINST_DLL through its prescribed interface that just takes the
00311                             ** vRefNum and parID of the FSSpec that describes the folder.
00312                             ** Whilst, the -folder- string is used by DrawDiskNFolder() in repainting.
00313                             */
00314                             pstrcpy(gControls->opt->folder, folderSpec.name);
00315                             gControls->opt->vRefNum = tmp.vRefNum;
00316                             gControls->opt->dirID = tmp.parID;
00317                             DrawDiskNFolder(folderSpec.vRefNum, folderSpec.name);
00318                      }
00319             
00320                      AEDisposeDesc(&resultDesc);
00321                      NavDisposeReply(&reply);
00322               }
00323               
00324               return;
00325        }
00326                      
00327        HLock((Handle)gControls->nextB);                 
00328        r = (**(gControls->nextB)).contrlRect;
00329        HUnlock((Handle)gControls->nextB);
00330        if (PtInRect( localPt, &r))
00331        {
00332               part = TrackControl(gControls->nextB, evt->where, NULL);
00333               if (part)
00334               {
00335                      /* check if folder location contains legacy apps */
00336                      if (gControls->cfg->numLegacyChecks > 0)
00337                             if (LegacyFileCheck(gControls->opt->vRefNum, gControls->opt->dirID))
00338                             {
00339                                    /* user cancelled so don't do anything */
00340                                    return;
00341                             }
00342                      
00343                      /* if not custom setup type then perform disk space check */
00344                      if (gControls->opt->instChoice < gControls->cfg->numSetupTypes)
00345                      {
00346                      if (!VerifyDiskSpace())
00347                          return;
00348             }
00349                                                  
00350                      ClearDiskSpaceMsgs();
00351                      KillControls(gWPtr);
00352                      /* treat last setup type selection as custom */
00353                      if (gControls->opt->instChoice == gControls->cfg->numSetupTypes)
00354                             ShowComponentsWin();
00355                      else
00356                             ShowTerminalWin();
00357                      return;
00358               }
00359        }
00360        SetPort(oldPort);
00361 }
00362 
00363 void
00364 InsertCompList(int instChoice)
00365 {
00366        int compsDone, i, len;
00367        InstComp currComp;
00368        char compName[128];
00369        Boolean didOneComp = false;
00370        
00371        // if not cutsom setup type show components list
00372        if (gControls->opt->instChoice < gControls->cfg->numSetupTypes)
00373        {
00374               compsDone = 0;
00375               TEInsert("\r", 1, gControls->stw->instDescTxt);
00376               for(i=0; i<kMaxComponents; i++)
00377               {
00378                      if ( (gControls->cfg->st[instChoice].comp[i] == kInSetupType) &&
00379                              (!gControls->cfg->comp[i].invisible) &&
00380                              (compsDone < gControls->cfg->st[instChoice].numComps) )
00381                      {
00382                             currComp = gControls->cfg->comp[i];
00383                             HLock(currComp.shortDesc);
00384                             len = strlen(*currComp.shortDesc) + 4;
00385                             memset(compName, 0, 128);
00386                             if (didOneComp)
00387                                 sprintf(compName, ", %s", *currComp.shortDesc);
00388                             else
00389                             {
00390                                 sprintf(compName, "%s", *currComp.shortDesc);
00391                                 didOneComp = true;
00392                             }
00393                             TEInsert(compName, len, gControls->stw->instDescTxt);
00394                             HUnlock(currComp.shortDesc);
00395                      }
00396                      compsDone++;
00397               }
00398        }
00399 }
00400 
00401 void
00402 DrawDiskNFolder(short vRefNum, unsigned char *folder)
00403 {
00404        Str255               inFolderMsg, onDiskMsg, volName;
00405        char                 *cstr;
00406        Rect                 viewRect, dlb;
00407        TEHandle             pathInfo;
00408        short                bCmp, outVRefNum;
00409        OSErr                err = noErr;
00410        FSSpec               fsTarget;
00411        IconRef                     icon;
00412        SInt16               label;
00413        unsigned long   free, total;
00414        
00415 #define ICON_DIM 32
00416 
00417     dlb = (*gControls->stw->destLocBox)->contrlRect;
00418     SetRect(&viewRect, dlb.left+10, dlb.top+15, dlb.left+10+ICON_DIM, dlb.top+15+ICON_DIM);
00419    
00420        /* draw folder/volume icon */
00421        FSMakeFSSpec(gControls->opt->vRefNum, gControls->opt->dirID, "\p", &fsTarget);
00422        err = GetIconRefFromFile(&fsTarget, &icon, &label);
00423        if (err==noErr)
00424        {
00425               EraseRect(&viewRect);
00426               PlotIconRef(&viewRect, kAlignNone, kTransformNone, kIconServicesNormalUsageFlag, icon);
00427        }
00428        ReleaseIconRef(icon);       
00429        
00430        /* set up rect for disk and folder strings */
00431     SetRect(&viewRect, dlb.left+10+ICON_DIM+12, dlb.top+15, dlb.left+220, dlb.bottom-5);
00432     
00433        /* get vol and folder name */
00434        if ((err = HGetVInfo(vRefNum, volName, &outVRefNum, &free, &total)) == noErr)
00435        {      
00436               /* format and draw vol and disk name strings */
00437               TextFace(normal);
00438               TextSize(9);
00439               TextFont(applFont);
00440               EraseRect(&viewRect);
00441               pathInfo = TENew(&viewRect, &viewRect);
00442        
00443               if ( (bCmp = pstrcmp(folder, volName)) == 0)
00444               {
00445                      GetResourcedString( inFolderMsg, rInstList, sInFolder);
00446                      cstr = PascalToC(inFolderMsg);
00447                      TEInsert(cstr, strlen(cstr), pathInfo); 
00448                      DisposePtr(cstr);    
00449                             cstr = "\r\"\0";     TEInsert(cstr, strlen(cstr), pathInfo);
00450        
00451                      cstr = PascalToC(folder);
00452                      TEInsert(cstr, strlen(cstr), pathInfo);
00453                      DisposePtr(cstr);
00454                             cstr = "\"\r\0";     TEInsert(cstr, strlen(cstr), pathInfo);
00455               }
00456               
00457               GetResourcedString( onDiskMsg,   rInstList, sOnDisk);
00458               cstr = PascalToC(onDiskMsg);
00459               TEInsert(cstr, strlen(cstr), pathInfo);
00460               DisposePtr(cstr);
00461                      cstr = "\r\"\0";     TEInsert(cstr, strlen(cstr), pathInfo);
00462                      
00463               cstr = PascalToC(volName);
00464               TEInsert(cstr, strlen(cstr), pathInfo);
00465               DisposePtr(cstr);
00466                      cstr = "\"\0";       TEInsert(cstr, strlen(cstr), pathInfo);
00467                      
00468               TEUpdate(&viewRect, pathInfo);
00469               
00470               TextFont(systemFont);
00471               TextSize(12);
00472        }
00473        
00474        /* free mem blocks */
00475        TEDispose(pathInfo);
00476 
00477        DrawDiskSpaceMsgs(vRefNum);
00478 }
00479 
00480 void
00481 DrawDiskSpaceMsgs(short vRefNum)
00482 {
00483        XVolumeParam  pb;
00484        OSErr                err, reserr;
00485        short                msglen = 0;
00486        TEHandle             dsAvailH, dsNeededH;
00487        Rect                 instDescBox, viewRect;
00488        Handle               instDescRectH;
00489        Str255               msg;
00490        Str15                kb;
00491        char                 *cstr, *cmsg, *ckb, *cfreeSpace, *cSpaceNeeded;
00492        
00493        pb.ioCompletion = NULL;
00494        pb.ioVolIndex = 0;
00495        pb.ioNamePtr = NULL;
00496        pb.ioVRefNum = vRefNum;
00497        
00498        ERR_CHECK( PBXGetVolInfoSync(&pb) );
00499        sDSAvailK = U32SetU(U64Divide(pb.ioVFreeBytes, U64SetU(1024L), nil));
00500     
00501        instDescRectH = NULL;
00502        instDescRectH = Get1Resource('RECT', rCompListBox);
00503        reserr = ResError();
00504        if (reserr!=noErr || !instDescRectH)
00505        {
00506               ErrorHandler(reserr, nil);
00507               return;
00508        }
00509        
00510        HLock(instDescRectH);
00511        instDescBox = (Rect) **((Rect**)instDescRectH);
00512        SetRect( &viewRect, instDescBox.left, instDescBox.bottom + 2, 
00513                                           instDescBox.right, instDescBox.bottom + 14 );
00514        HUnlock(instDescRectH);     
00515        DetachResource(instDescRectH);
00516        DisposeHandle(instDescRectH); 
00517                                                  
00518        TextFace(normal);
00519        TextSize(9);
00520        TextFont(applFont);
00521        EraseRect(&viewRect);       
00522        dsAvailH = NULL;
00523        dsAvailH = TENew(&viewRect, &viewRect);
00524        if (!dsAvailH)
00525        {
00526               ErrorHandler(eMem, nil);
00527               return;
00528        }
00529        
00530        /* Get the "Disk Space Available: " string */
00531        GetResourcedString( msg, rInstList, sDiskSpcAvail );
00532        cstr = PascalToC(msg);
00533        msglen = strlen(cstr);
00534        cmsg = (char*)malloc(msglen+255);
00535        strncpy(cmsg, cstr, msglen);
00536        cmsg[msglen] = '\0';
00537        
00538        /* tack on the actual disk space in KB */
00539        cfreeSpace = ltoa(sDSAvailK);
00540        msglen += strlen(cfreeSpace);
00541        strcat( cmsg, cfreeSpace );
00542        cmsg[msglen] = '\0';
00543        
00544        /* tack on the "kilobyte" string: generally "K" but is rsrc'd */
00545        GetResourcedString( kb, rInstList, sKilobytes );
00546        ckb = PascalToC(kb);
00547        msglen += strlen(ckb);
00548        strcat( cmsg, ckb );
00549        cmsg[msglen] = '\0';
00550        
00551        /* draw the disk space available string */
00552        TEInsert( cmsg, strlen(cmsg), dsAvailH );
00553        TEUpdate( &viewRect, dsAvailH );
00554        
00555        /* recycle pointers */
00556        if (cstr)
00557               DisposePtr((Ptr)cstr);
00558        if (cmsg)
00559               free(cmsg);
00560        if (ckb)
00561               DisposePtr((Ptr)ckb);
00562        
00563        SetRect( &viewRect, instDescBox.right - 150, instDescBox.bottom + 2,
00564                                           instDescBox.right, instDescBox.bottom + 14 );
00565        dsNeededH = NULL;
00566        dsNeededH = TENew( &viewRect, &viewRect );
00567        if (!dsNeededH)
00568        {
00569               ErrorHandler(eMem, nil);
00570               return;
00571        }
00572        
00573        /* Get the "Disk Space Needed: " string */
00574        GetResourcedString( msg, rInstList, sDiskSpcNeeded );
00575        cstr = PascalToC(msg);
00576        msglen = strlen(cstr);
00577        cmsg = (char*)malloc(msglen+255);
00578        strncpy(cmsg, cstr, msglen);
00579        cmsg[msglen] = '\0';
00580        
00581        /* tack on space needed in KB */
00582        cSpaceNeeded = DiskSpaceNeeded();
00583        msglen += strlen(cSpaceNeeded);
00584        strcat( cmsg, cSpaceNeeded );
00585        cmsg[msglen] = '\0';
00586        
00587        /* tack on the "kilobyte" string: generally "K" but is rsrc'd */
00588        GetResourcedString( kb, rInstList, sKilobytes );
00589        ckb = PascalToC(kb);
00590        msglen += strlen(ckb);
00591        strcat( cmsg, ckb );
00592        cmsg[msglen] = '\0';
00593        
00594        /* draw the disk space available string */
00595        TEInsert( cmsg, strlen(cmsg), dsNeededH );
00596        TEUpdate( &viewRect, dsNeededH );
00597        
00598        if (dsAvailH)
00599               TEDispose(dsAvailH);
00600        if (dsNeededH)
00601               TEDispose(dsNeededH);
00602        
00603        if (ckb)
00604               DisposePtr((Ptr)ckb);
00605        if (cSpaceNeeded)
00606               free(cSpaceNeeded);         // malloc'd, not NewPtrClear'd
00607        if (cfreeSpace)
00608               free(cfreeSpace);
00609        if (cstr)
00610               DisposePtr((Ptr)cstr);
00611        if (cmsg)
00612               free(cmsg);
00613        TextFont(systemFont);
00614        TextSize(12);
00615 }
00616 
00617 char *
00618 DiskSpaceNeeded(void)
00619 {
00620        char *cSpaceNeeded;
00621        short i;
00622        long spaceNeeded = 0;
00623        int instChoice = gControls->opt->instChoice - 1;
00624        
00625        /* loop through all components cause they may be scattered through 
00626         * the array for this particular setup type 
00627         */
00628        for (i=0; i<kMaxComponents; i++)
00629        {      
00630               /* if "Custom Install" and it's selected... */
00631               if (gControls->opt->instChoice == gControls->cfg->numSetupTypes)
00632               {
00633                      if ((gControls->cfg->st[instChoice].comp[i] == kInSetupType) &&
00634                             (gControls->cfg->comp[i].selected == true))
00635                             spaceNeeded += gControls->cfg->comp[i].size;
00636               }
00637               
00638               /* or not custom install but in current setup type... */
00639               else if (gControls->cfg->st[instChoice].comp[i] == kInSetupType)
00640               {
00641                      spaceNeeded += gControls->cfg->comp[i].size;
00642               }
00643        }
00644        
00645        cSpaceNeeded = ltoa(spaceNeeded);
00646        sDSNeededK = spaceNeeded;
00647        
00648        return cSpaceNeeded;
00649 }
00650 
00651 void
00652 ClearDiskSpaceMsgs(void)
00653 {
00654        Rect instDescBox, viewRect;
00655        Handle instDescRectH;
00656        OSErr  reserr;
00657        GrafPtr       oldPort;
00658        
00659        GetPort(&oldPort);
00660        if (gWPtr)
00661               SetPort(gWPtr);
00662        
00663        instDescRectH = NULL;
00664        instDescRectH = Get1Resource('RECT', rCompListBox);
00665        reserr = ResError();
00666        if (reserr!=noErr || !instDescRectH)
00667        {
00668               ErrorHandler(reserr, nil);
00669               return;
00670        }
00671 
00672        HLock(instDescRectH);
00673        instDescBox = (Rect) **((Rect**)instDescRectH);
00674        SetRect( &viewRect, instDescBox.left, instDescBox.top, 
00675                                           instDescBox.right, instDescBox.bottom + 14 );
00676        HUnlock(instDescRectH);     
00677        DetachResource(instDescRectH);
00678        DisposeHandle(instDescRectH);
00679                                           
00680        EraseRect( &viewRect );
00681        InvalRect( &viewRect );
00682        
00683        SetPort(oldPort);
00684 }
00685 
00686 /*
00687 ** ltoa -- long to ascii
00688 **
00689 ** Converts a long to a C string. We allocate 
00690 ** a string of the appropriate size and the caller
00691 ** should assume ownership of the returned pointer.
00692 */
00693 #define kMaxLongLen  12
00694 char *
00695 ltoa(long n)
00696 {
00697        char   s[kMaxLongLen] = "";
00698        char *returnBuf;
00699        int i, j, sign;
00700        
00701        /* check sign and convert to positive to stringify numbers */
00702        if ( (sign = n) < 0)
00703               n = -n;
00704        i = 0;
00705        
00706        /* grow string as needed to add numbers from powers of 10 down till none left */
00707        do
00708        {
00709               s[i++] = n % 10 + '0';  /* '0' or 30 is where ASCII numbers start from */
00710        }
00711        while( (n /= 10) > 0);      
00712        
00713        /* tack on minus sign if we found earlier that this was negative */
00714        if (sign < 0)
00715        {
00716               s[i++] = '-';
00717        }
00718 
00719        s[i] = '\0';
00720        
00721        /* pop numbers (and sign) off of string to push back into right direction */
00722        for (i = 0, j = strlen(s) - 1; i < j; i++, j--)
00723        {
00724               char tmp = s[i];
00725               s[i] = s[j];
00726               s[j] = tmp;
00727        }
00728 
00729        returnBuf = (char *)malloc(strlen(s) + 1);
00730        strcpy(returnBuf, s);
00731        return returnBuf;
00732 }
00733 
00734 short
00735 pstrcmp(unsigned char* s1, unsigned char* s2)
00736 {
00737        long len;
00738        register short i;
00739        
00740        if ( *s1 != *s2)  /* different lengths */
00741               return false;
00742        
00743        len = *s1;
00744        for (i=0; i<len; i++)
00745        {
00746               s1++;
00747               s2++;
00748               if (*s1 != *s2)
00749                      return false;
00750        }
00751        
00752        return true;
00753 }
00754 
00755 unsigned char*
00756 pstrcpy(unsigned char* dest, unsigned char* src)
00757 {
00758        long len;
00759        register short i;
00760        unsigned char* origdest;
00761        
00762        if (!dest || !src)
00763               return nil;
00764        
00765        origdest = dest;
00766        len = *src;
00767        for (i=0; i<=len; i++)
00768        {
00769               *dest = *src;
00770               dest++;
00771               src++;
00772        }
00773               
00774        return origdest;
00775 }
00776        
00777 unsigned char*
00778 pstrcat(unsigned char* dst, unsigned char* src)
00779 {
00780        unsigned char        *origdst;
00781        long                 dlen, slen;
00782        register short       i;
00783        
00784        if (!dst || !src)
00785               return nil;
00786               
00787        origdst = dst;
00788        dlen = *dst;
00789        slen = *src;
00790        *dst = dlen+slen; 
00791        
00792        for (i=1; i<=slen; i++)
00793        {
00794               *(dst+dlen+i) = *(src+i);
00795        }
00796        
00797        return origdst;
00798 }
00799 
00800 void
00801 GetAllVInfo( unsigned char **volName, short *count)
00802 {
00803        QHdrPtr                            vcbQ;
00804        VCB *                       currVCB;
00805        register short              i;
00806        
00807        vcbQ = GetVCBQHdr();
00808        currVCB = (VCB *)vcbQ->qHead;
00809        i = 0;
00810        while(1)
00811        {
00812               volName[i] = currVCB->vcbVN;
00813               /* *vRefNum[i] = currVCB->vcbVRefNum; */
00814               
00815               i++;  // since i gets incremented pre-break, count is accurate
00816               if (currVCB == (VCB *) vcbQ->qTail)
00817                      break;
00818               currVCB = (VCB *)currVCB->qLink;
00819        }
00820        *count = i;
00821 }
00822 
00823 Boolean
00824 LegacyFileCheck(short vRefNum, long dirID)
00825 {
00826        Boolean       bRetry = false;
00827        int                  i, diffLevel;
00828        StringPtr     pFilepath = 0, pMessage = 0, pSubfolder = 0;
00829        FSSpec        legacy, fsDest;
00830        OSErr         err = noErr;
00831        short         dlgRV = 0;
00832        char          cFilepath[1024];
00833        AlertStdAlertParamRec *alertdlg;
00834        
00835        for (i = 0; i < gControls->cfg->numLegacyChecks; i++)
00836        {
00837               /* construct legacy files' FSSpecs in program dir */
00838               HLock(gControls->cfg->checks[i].filename);
00839               if (!**gControls->cfg->checks[i].filename)
00840               {
00841                      HUnlock(gControls->cfg->checks[i].filename);
00842                      continue;
00843               }
00844               HLock(gControls->cfg->checks[i].subfolder);
00845               memset(cFilepath, 0, 1024);
00846               strcpy(cFilepath, ":");
00847               strcat(cFilepath, *gControls->cfg->checks[i].subfolder);
00848               strcat(cFilepath, ":");
00849               strcat(cFilepath, *gControls->cfg->checks[i].filename);
00850               HUnlock(gControls->cfg->checks[i].filename);
00851               pSubfolder = CToPascal(*gControls->cfg->checks[i].subfolder);
00852               HUnlock(gControls->cfg->checks[i].subfolder);
00853               pFilepath = CToPascal(cFilepath);
00854               
00855               err = FSMakeFSSpec(vRefNum, dirID, pFilepath, &legacy);
00856               if (pFilepath)
00857                      DisposePtr((Ptr)pFilepath);
00858                      
00859               /* if legacy file exists */
00860               if (err == noErr)
00861               {
00862                      /* if new version is greater than old version */
00863                      diffLevel = CompareVersion( gControls->cfg->checks[i].version, 
00864                                                                       &legacy );
00865                      if (diffLevel > 0)
00866                      {
00867                             /* set up message dlg */
00868                             if (!gControls->cfg->checks[i].message || !(*gControls->cfg->checks[i].message))
00869                                    continue;
00870                             HLock(gControls->cfg->checks[i].message);
00871                             pMessage = CToPascal(*gControls->cfg->checks[i].message);
00872                             HUnlock(gControls->cfg->checks[i].message);
00873                             if (!pMessage)
00874                                    continue;
00875                             
00876                             /* set bRetry to retval of show message dlg */
00877                             alertdlg = (AlertStdAlertParamRec *)NewPtrClear(sizeof(AlertStdAlertParamRec));
00878                             alertdlg->defaultButton = kAlertStdAlertOKButton;
00879                             alertdlg->defaultText = (ConstStringPtr)NewPtrClear(kKeyMaxLen);
00880                             alertdlg->cancelText = (ConstStringPtr)NewPtrClear(kKeyMaxLen);
00881                          GetResourcedString((unsigned char *)alertdlg->defaultText, rInstList, sDeleteBtn);
00882                          GetResourcedString((unsigned char *)alertdlg->cancelText, rInstList, sCancel);
00883                             StandardAlert(kAlertCautionAlert, pMessage, nil, alertdlg, &dlgRV);
00884                             if (dlgRV == 1) /* default button id  ("Delete") */
00885                             {                    
00886                                    /* delete and move on to next screen */
00887                                    err = FSMakeFSSpec(gControls->opt->vRefNum, gControls->opt->dirID, pSubfolder, &fsDest);
00888                                    if (err == noErr) /* don't care if this fails */
00889                                           DeleteDirectoryContents(fsDest.vRefNum, fsDest.parID, fsDest.name);
00890                             }
00891                             else
00892                                    bRetry = true;
00893                                    
00894                             if (pMessage)
00895                                    DisposePtr((Ptr) pMessage);
00896                      }
00897               }
00898        }
00899        
00900        if (pSubfolder)
00901               DisposePtr((Ptr) pSubfolder);
00902               
00903        return bRetry;
00904 }
00905 
00906 int
00907 CompareVersion(Handle newVersion, FSSpecPtr file)
00908 {
00909        int                  diffLevel = 0, intVal;
00910        OSErr         err = noErr;
00911        short         fileRef;
00912        Handle        versRsrc = nil;
00913        char          oldRel, oldRev, oldFix, oldInternalStage, oldDevStage, oldRev_n_Fix;
00914        char          *newRel, *newRev, newFix[2], *newInternalStage, newDevStage, *newFix_n_DevStage;
00915        Ptr                  newVerCopy;
00916        
00917        /* no version supplied means show check always */
00918        if (!newVersion || !(*newVersion))
00919               return 6;
00920        
00921        /* if no valid filename then error so don't show message */
00922        if (!file)
00923               return -6;    
00924               
00925        /* get version from 'vers' res ID = 1 */         
00926        fileRef = FSpOpenResFile(file, fsRdPerm);
00927        if (fileRef == -1)
00928               return -9;
00929               
00930        versRsrc = Get1Resource('vers', 1);
00931        if (versRsrc == nil)
00932        {
00933               CloseResFile(fileRef);
00934               return -10;
00935        }
00936        
00937        // rel, rev, fix, internalStage, devStage
00938        HLock(versRsrc);
00939        oldRel = *(*versRsrc);
00940        oldRev_n_Fix = *((*versRsrc)+1);
00941        oldDevStage = *((*versRsrc)+2);
00942        oldInternalStage = *((*versRsrc)+3);
00943        HUnlock(versRsrc);
00944        CloseResFile(fileRef);
00945        
00946        oldRev = (oldRev_n_Fix & 0xF0) >> 4;
00947        oldFix =  oldRev_n_Fix & 0x0F;
00948        
00949        /* parse new version */
00950        HLock(newVersion);
00951        newVerCopy = NewPtrClear(strlen(*newVersion));
00952        BlockMove(*newVersion, newVerCopy, strlen(*newVersion));
00953        newRel = strtok(newVerCopy, ".");
00954        newRev = strtok(NULL, ".");
00955        newFix_n_DevStage = strtok(NULL, ".");
00956        newInternalStage = strtok(NULL, ".");
00957        HUnlock(newVersion);
00958        
00959        /* resolve fix and devStage 
00960         *(defaulting devStage to 0x80(==release) if not detected) 
00961         */
00962        newDevStage = 0x80;                              /* release */
00963        if (NULL != strchr(newFix_n_DevStage, 'd')) 
00964               newDevStage = 0x20;                              /* development */
00965        else if (NULL != strchr(newFix_n_DevStage, 'a'))
00966               newDevStage = 0x40;                              /* alpha */
00967        else if (NULL != strchr(newFix_n_DevStage, 'b')) 
00968               newDevStage = 0x60;                              /* beta */
00969               
00970        newFix[0] = *newFix_n_DevStage;
00971        newFix[1] = 0;
00972        
00973        /* compare 'vers' -- old version -- with supplied new version */
00974        intVal = atoi(newRel);
00975        if (oldRel < intVal)
00976        {
00977               diffLevel = 5;
00978               goto au_revoir;
00979        }
00980        else if (oldRel > intVal)
00981        {
00982               diffLevel = -5;
00983               goto au_revoir;
00984        }
00985               
00986        intVal = atoi(newRev);
00987        if (oldRev < intVal)
00988        {
00989               diffLevel = 4;
00990               goto au_revoir;
00991        }
00992        else if (oldRev > intVal)
00993        {
00994               diffLevel = -4;
00995               goto au_revoir;
00996        }
00997               
00998        intVal = atoi(newFix);
00999        if (oldFix < intVal)
01000        {      
01001               diffLevel = 3;
01002               goto au_revoir;
01003        }
01004        else if (oldFix > intVal)
01005        {
01006               diffLevel = -3;
01007               goto au_revoir;
01008        }
01009        
01010        intVal = atoi(newInternalStage);
01011        if (oldInternalStage < intVal)
01012        {
01013               diffLevel = 2;
01014               goto au_revoir;
01015        }
01016        else if (oldInternalStage > intVal)
01017        {
01018               diffLevel = -2;
01019               goto au_revoir;
01020        }
01021        
01022        if (oldDevStage < newDevStage)
01023        {
01024               diffLevel = 1;
01025               goto au_revoir;
01026        }
01027        else if (oldDevStage > newDevStage)
01028        {
01029               diffLevel = -1;
01030               goto au_revoir;
01031        }
01032        
01033        /* else they are equal */
01034        diffLevel = 0;
01035 
01036 au_revoir:
01037        if (newVerCopy)
01038               DisposePtr(newVerCopy);
01039                      
01040        return diffLevel;
01041 }
01042 
01043 Boolean
01044 VerifyDiskSpace(void)
01045 {
01046     char dsNeededStr[255], dsAvailStr[255];
01047     short alertRV;
01048     Str255 pMessage, pStr;
01049     AlertStdAlertParamRec *alertdlg;
01050     
01051     if (sDSNeededK > sDSAvailK)
01052     {
01053         sprintf(dsNeededStr, "%d", sDSNeededK);
01054         sprintf(dsAvailStr, "%d", sDSAvailK);
01055 
01056         GetResourcedString(pMessage, rInstList, sSpaceMsg1);
01057         pstrcat(pMessage, CToPascal(dsAvailStr));
01058         pstrcat(pMessage, CToPascal("KB \r"));
01059         GetResourcedString(pStr, rInstList, sSpaceMsg2);
01060         pstrcat(pStr, CToPascal(dsNeededStr));
01061         pstrcat(pStr, CToPascal("KB \r\r"));
01062         pstrcat(pMessage, pStr);
01063         GetResourcedString(pStr, rInstList, sSpaceMsg3);
01064         pstrcat(pMessage, pStr);
01065         alertdlg = (AlertStdAlertParamRec *)NewPtrClear(sizeof(AlertStdAlertParamRec));
01066         alertdlg->defaultButton = kAlertStdAlertCancelButton;
01067         alertdlg->defaultText = (ConstStringPtr)NewPtrClear(kKeyMaxLen);
01068         alertdlg->cancelText = (ConstStringPtr)NewPtrClear(kKeyMaxLen);
01069         GetResourcedString((unsigned char *)alertdlg->defaultText, rInstList, sOKBtn);
01070         GetResourcedString((unsigned char *)alertdlg->cancelText, rInstList, sQuitBtn);
01071         StandardAlert(kAlertCautionAlert, pMessage, nil, alertdlg, &alertRV);
01072         if (alertRV == 2)
01073         {
01074             gDone = true;
01075         }
01076         return false;
01077     }    
01078     
01079     return true;
01080 }
01081 
01082 void
01083 EnableSetupTypeWin(void)
01084 {
01085     EnableNavButtons();
01086        
01087     /* ensure 'Go Back' button is visbily disabled 
01088      * (since functionality is disconnected) 
01089      */
01090     if (gControls->backB)
01091         HiliteControl(gControls->backB, kDisableControl);
01092         
01093     if (gControls->stw->instType)
01094         HiliteControl(gControls->stw->instType, kEnableControl);
01095     if (gControls->stw->destLoc)
01096         HiliteControl(gControls->stw->destLoc, kEnableControl);
01097 }
01098 
01099 void
01100 DisableSetupTypeWin(void)
01101 {
01102        DisableNavButtons();
01103        
01104        if (gControls->stw->instType)
01105               HiliteControl(gControls->stw->instType, kDisableControl);
01106        if (gControls->stw->destLoc)
01107               HiliteControl(gControls->stw->destLoc, kDisableControl);
01108 }