Rev 15807 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
/** R : A Computer Language for Statistical Data Analysis* file RMenus.c* Copyright (C) 1998-1999 Ross Ihaka* 2000-2001 Stefano M. Iacus and the R core team** This program is free software; you can redistribute it and/or modify* it under the terms of the GNU General Public License as published by* the Free Software Foundation; either version 2 of the License, or* (at your option) any later version.** This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the* GNU General Public License for more details.** You should have received a copy of the GNU General Public License* along with this program; if not, write to the Free Software* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*** This file is adapted from the public demos coming with the Waste library* distribution: WASTE Text Engine © 1993-2000 Marco Piovanelli.** This file was originally written by: Wing Kwong (Tiki), WAN 3/2/99* Code cleanup and fix for q() based quiting. Ihaka 30/6/99* Updated to last version of WasteLib library and complete control* over different windows.* Menu 'Windows' implemented correctly: Stefano M. Iacus, 2001** Original file was:* WEDemoMenus.c** WASTE Demo Project:* Macintosh Controls with Long Values** Copyright © 1993-1998 Marco Piovanelli* All Rights Reserved** C port by John C. Daub** Description** This file is based on the WASTE and WASTE demo, I had do some* modification to make it function as the way R want. The routine in* here is used to handle event (high or low level event.) There* have a lot of function which is related to the Menu of Console and* edit window in here. We will not using them, however, it is* pretty good to leave it in here. Because it is fully functional, and* it functions correctly, when you feel that you need to add a size,* font or color Menu..., what you need to do is to change the R.rsrc* file ('MBAR' resource), You can simply overwrite the resource with* ID 130 to ID 128. Then, a fully functional Menu will appear again.**//* INCLUDE HEADER FILE */#include <RCarbon.h>#ifndef __ALIASES__#include <Aliases.h>#endif#ifndef __DEVICES__#include <Devices.h>#endif#ifndef __ERRORS__#include <Errors.h>#endif#ifndef __LOWMEM__#include <LowMem.h>#endif#ifndef __STANDARDFILE__#include <StandardFile.h>#endif#ifndef __FILETYPESANDCREATORS__#include <FileTypesAndCreators.h>#endif#ifndef __TOOLUTILS__#include <ToolUtils.h>#endif#include <AppleEvents.h>#include <Processes.h>#include <PMApplication.h>//#include <PMDefinitions.h>//#include <PMCore.h>#ifndef __WEDEMOAPP__#include "RIntf.h"#endif#include "WETabs.h"#ifdef HAVE_CONFIG_H#include <config.h>#endif#include "Defn.h"#include <Scrap.h>#include "Graphics.h"#include <Rdevices.h>#include "Fileio.h"/* DEFINE CONSTANTS */#define eNoSuchFile 9#define eSelectNextTime 10#define kTypeMenuColorTable 'mctb'#define kFinderSig 'FNDR'#define kAEFinderEvents 'FNDR'#define kSystemType 'MACS'#define kAEOpenSelection 'sope'#define keySelection 'fsel'/* Global variables */Boolean HaveContent = false;Boolean PrintPicture;extern Boolean OnOpenSource;extern Boolean Interrupt;Handle myHandle=NULL;SInt32 curPaste, finalPaste;static Handle sColors; /* handle to the 'mctb' resource for the Color menu*/char mTitle[265], wTitle[265];extern OSErr DoSelectDirectory( void );extern char *mac_getenv(const char *name);MenuRef HelpMenu=NULL; /* This Handle willtake care of the Help Menu */static short RHelpMenuItem=-1;static short RTopicHelpItem=-1;static short RunExampleItem=-1;static short SearchHelpItem=-1;static short LinkHtmlHelpItem=-1;static short PreferencesItem=-1;// user structure passed to the NavEventFilter callbacktypedef struct NavCallbackData{ControlRef formatPopup ;ControlRef stationeryCheckbox ;SInt16 extraItemsID ;SInt16 numItems ;OSType fileType ;Boolean isStationery ;} NavCallbackData ;/* Extern Global variables */extern char *gbuf;extern SInt32 gbuflen;extern Handle gTextHdl;extern FSSpec gHelpFile;extern WindowPtr Console_Window;extern SInt32 gChangeAble, gpmtLh;extern Boolean gfinishedInput;extern Graphic_Ref gGReference[MAX_NUM_G_WIN + 1];extern Boolean gPrintStructureInited;extern PicHandle gPictureHdl;extern char InitFile[256];extern SInt16 Edit_Window;extern WindowPtr Edit_Windows[MAX_NUM_E_WIN + 1];extern Boolean defaultPort;extern SInt16 Help_Window;extern WindowPtr Help_Windows[MAX_NUM_H_WIN + 1];extern SInt16 gTextSize;extern int gScreenRes;extern Boolean finished;extern FSSpec tempeditFSS;/* Protocols */void assignPString (unsigned char* , char* , SInt16);OSErr FindAProcess (OSType, OSType, ProcessSerialNumber*);OSErr OpenSelection (FSSpecPtr theDoc);void ConsoleCopyAndPaste (void);OSErr DoOpenText(Boolean editable);OSStatus DoOpen(void);OSErr OldDoOpen(void);OSErr DoSource(void);OSErr SourceFile(FSSpec *myfss);int GetTextSize(void);int GetScreenRes(void);Boolean RunningOnCarbonX(void);void consolecmd(char *cmd);static pascal void NavEventFilter(NavEventCallbackMessage,NavCBRec *,void *);static OSStatus CreateNavTypeList(OSType,UInt16,const OSType *,NavTypeListHandle *);void DoHelpChoice(SInt16 menuItem);extern void Do_HelpOnTopic(void);extern void Do_RunExample(void);extern void Do_SearchHelp(void);/* Extern Global variables */extern void doWindowsMenu (SInt16);extern void doConfigMenu (SInt16);extern void changeGWinPtr (WindowPtr, Str255);extern void *dlopen (const char*, int);extern void savePreference (void);extern void DoGenKeyDown (const EventRecord *event, Boolean Console);extern Boolean EqualNumString(Str255 Str1, Str255 Str2, SInt16 Num);extern void adjustEditPtr(SInt16 EditIndex);extern void adjustHelpPtr(SInt16 HelpIndex);extern pascal OSErr FSpGetFullPath (const FSSpec*, short*, Handle*);extern void LoadWindow();extern void DoLineTo();extern void Do_EditObject();/*extern void PrintPicture();*/extern void printLoop(WindowPtr window);void DoPaste(WindowPtr window);extern void DoUpdate (WindowPtr window);extern void DoActivate (Boolean isActivating, WindowPtr window);extern void Do_About();void DoTools(SInt16 menuItem);SavingOption DoWeSaveIt(WindowPtr window);OSErr MyOpenDocument(FSSpec *documentFSSpec, SFTypeList *typeList);/* enum */enum {kButtonSave = 1,kButtonCancel,kButtonDontSave};/* SetDefaultDirectory*/void SetDefaultDirectory (const FSSpec * spec){// LMSetCurDirStore (spec->parID);// LMSetSFSaveDisk (- spec->vRefNum);}/* MySFDialogFilter*/static pascal BooleanMySFDialogFilter(DialogPtr dialog, EventRecord *event, SInt16 *item,void *yourData){#pragma unused (item, yourData)/* intercept window events directed to windows behind the dialog */if ((event->what == updateEvt) || (event->what == activateEvt)) {if ((WindowPtr) event->message != GetDialogWindow(dialog)) {DoWindowEvent(event);}}return false;}/* ModalFilterYDUPP*/static ModalFilterYDUPP GetMySFDialogFilter(void){#ifdef __cplusplusstatic ModalFilterYDUPP sFilterUPP =NewModalFilterYDProc(MySFDialogFilter);#elsestatic ModalFilterYDUPP sFilterUPP = nil;if (sFilterUPP == nil) {//sFilterUPP = NewModalFilterYDProc(MySFDialogFilter);}#endifreturn sFilterUPP;}/* FindMenuItemText*/SInt16 FindMenuItemText(MenuHandle menu, ConstStr255Param stringToFind){SInt16 item;Str255 itemString;for (item = CountMenuItems(menu); item >= 1; item--) {GetMenuItemText(menu, item, itemString);if (EqualString(itemString, stringToFind, false, false))break;}return item;}/* EqualColor : use to maintain the color menus*/Boolean EqualColor(const RGBColor *rgb1, const RGBColor *rgb2){return ((rgb1->red == rgb2->red) && (rgb1->green == rgb2->green) && (rgb1->blue == rgb2->blue));}/* PrepareMenus:Used to maintain which menus item ought to be enabled, and which isdisabled.This function will be called when you use a mouse and click on themenu bar.*/void PrepareMenus(void){WindowPtr window;WEReference we;MenuHandle menu=NULL;MenuCRsrcPtr pColors;SInt16 item;Str255 itemText;SInt32 selStart, selEnd;SInt32 threshold;WEActionKind actionKind;WEStyleMode mode;TextStyle ts;Boolean temp;SInt32 scrapOffset;SInt16 i;Str255 Cur_Title, Menu_Title;MenuHandle windowsMenu=NULL;OSStatus err;/* get a pointer to the frontmost window, if any*/window = FrontWindow ();/* get associated WE instance*/we = (window != nil) ? GetWindowWE (window) : nil;/* *** FILE MENU ****/menu = GetMenuHandle (kMenuFile);/* first disable all items*/for (item = CountMenuItems (menu); item >= 1; item --) {DisableMenuItem (menu, item);}if (isGraphicWindow(window)){SetMenuItemText(menu,kItemOpen, "\pActivate Graphic Device");SetMenuItemText(menu,kItemNew, "\pNew Graphic Device");SetItemCmd(menu, kItemOpen, 'A');SetItemCmd(menu, kItemNew, 'N');}else{SetMenuItemText(menu,kItemOpen, "\pSource File...");SetMenuItemText(menu,kItemNew, "\pNew Edit Window");SetItemCmd(menu, kItemOpen, 'O');SetItemCmd(menu, kItemNew, 'N');}/* New, Open, and Quit are always enabled*/if (isEditWindow(window)){EnableMenuItem (menu, kItemLoadW);EnableMenuItem (menu, kItemSaveWSAs);EnableMenuItem (menu , kItemEditObject);}if (window == Console_Window){EnableMenuItem (menu, kItemLoadW);EnableMenuItem (menu, kItemSaveWSAs);EnableMenuItem (menu , kItemEditObject);}EnableMenuItem (menu, kItemNew);EnableMenuItem (menu, kItemOpen);EnableMenuItem (menu, kItemEditFile);EnableMenuItem (menu, kItemShow);EnableMenuItem (menu, kItemPageSetup);EnableMenuItem (menu, kItemPrint);EnableMenuItem (menu, kItemQuit);/* Enable "Close" and "Save As" if there is an active window*/if (window != nil) {EnableMenuItem (menu, kItemClose);if (!isHelpWindow(window)) {EnableMenuItem (menu, kItemSaveAs);EnableMenuItem (menu, kItemSave);}if(isGraphicWindow(window) || isHelpWindow(window))DisableMenuItem(menu,kItemSave);}/* *** EDIT MENU ****/menu = GetMenuHandle (kMenuEdit);/* first, disable all items*/for (item = CountMenuItems(menu); item >= 1; item--) {DisableMenuItem(menu, item);}if (isGraphicWindow(window)) {EnableMenuItem (menu, kItemCopy);}/* by default, the Undo menu item should read "Can't Undo"*/GetIndString(itemText, kUndoStringsID, 1);SetMenuItemText(menu, kItemUndo, itemText);if (window != nil) {/* enable Paste if there's anything pasteable on the Clipboard*/we = GetWindowWE ( window ) ;// enable Paste if there's anything pasteable on the Clipboardif ( WECanPaste ( we ) ){if (!isGraphicWindow(window))EnableMenuItem ( menu, kItemPaste ) ;}/* enable Undo if anything can be undone*/actionKind = WEGetUndoInfo (&temp, we);if (actionKind != weAKNone) {EnableMenuItem (menu, kItemUndo);/* change the Undo menu item to "Undo/Redo"+ name of action to undo/redo*/GetIndString (itemText, kUndoStringsID, 2 * actionKind + temp);SetMenuItemText (menu, kItemUndo, itemText);}/* enable Select All if there is anything to select*/if (WEGetTextLength (we) > 0){EnableMenuItem (menu, kItemSelectAll);}/* get the current selection range*/WEGetSelection (&selStart, &selEnd, we);/* enable Cut, Copy, and Clear if the selection range is not empty*/if (FrontWindow() == Console_Window) {EnableMenuItem (menu, kItemCopyPaste);EnableMenuItem (menu, kItemCopy);EnableMenuItem (menu, kItemCopyPaste);}if (isEditWindow(window)) {EnableMenuItem (menu, kItemLineTo);EnableMenuItem (menu, kItemCut);EnableMenuItem (menu, kItemCopy);EnableMenuItem (menu, kItemClear);EnableMenuItem (menu, kItemPaste);EnableMenuItem (menu, kItemCopyPaste);}if (isHelpWindow(window)){DisableMenuItem (menu, kItemCut);DisableMenuItem (menu, kItemCopyPaste);DisableMenuItem (menu, kItemClear);DisableMenuItem (menu, kItemPaste);EnableMenuItem (menu, kItemCopy);EnableMenuItem (menu, kItemCopyPaste);}/* determine which style attributes are continuous overthe current selection range we'll need this informationin order to check the Font/Size/Style/Color menus properly*/mode = weDoAll; /* query about all attributes*/WEContinuousStyle (&mode, &ts, we);} else {mode = 0; /* no window, so check no items */}/* *** Window Menu *** */windowsMenu = GetMenuHandle(kMenuWindows);GetWTitle(window, (unsigned char *) &Cur_Title);for(i = 1; i <= CountMenuItems(windowsMenu); i++) {GetMenuItemText(windowsMenu, i , (unsigned char*)&Menu_Title);CopyPascalStringToC(Cur_Title,wTitle);CopyPascalStringToC(Menu_Title,mTitle);CheckMenuItem(windowsMenu, i, false);if (strcmp(wTitle,mTitle) == 0)CheckMenuItem(windowsMenu, i, true);}/* The config menu */windowsMenu = GetMenuHandle(kMenuConfig);if( OnOpenSource )CheckMenuItem(windowsMenu, kItemOnOpenSource, true);elseCheckMenuItem(windowsMenu, kItemOnOpenSource, false);if( Interrupt )CheckMenuItem(windowsMenu, kItemAllowInterrupt, true);elseCheckMenuItem(windowsMenu, kItemAllowInterrupt, false);menu = GetMenuHandle(kHMHelpMenuID);EnableMenuItem (menu, RHelpMenuItem);EnableMenuItem (menu, RTopicHelpItem);EnableMenuItem (menu, SearchHelpItem);EnableMenuItem (menu, RunExampleItem);EnableMenuItem (menu, LinkHtmlHelpItem);menu = GetMenuHandle(kMenuApple);EnableMenuCommand(menu, kHICommandPreferences);}void DoDeskAcc ( UInt16 menuItem ){/* if ( menuItem == kItemAbout ){DoAboutBox( kDialogAboutBox );}*/#if ! TARGET_API_MAC_CARBONelse{// open desk accessories (this is not required under Carbon)Str255 deskAccessoryName ;GetMenuItemText ( GetMenuHandle ( kMenuApple ), menuItem, deskAccessoryName ) ;OpenDeskAcc ( deskAccessoryName ) ;}#endif}/* DoNew*/OSErr DoNew(Boolean editable){/* create a new window from scratch*/return CreateWindow(nil,editable);}/* This routine returns a FSSpec with corresponding error. The secondargument is ignored for the moment. This routine is used to Sourcefiles and Show files.Jago, April 2001, Stefano M.Iacus*/OSErr MyOpenDocument(FSSpec *documentFSSpec, SFTypeList *typeList){NavDialogOptions dialogOptions;NavEventUPP eventProc = nil;NavObjectFilterUPP filterProc = nil;OSErr anErr = noErr;/* Specify default options for dialog box */anErr = NavGetDefaultDialogOptions(&dialogOptions);if (anErr == noErr){/* Adjust the options to fit our needsSet default location option*/dialogOptions.dialogOptionFlags |= kNavSelectDefaultLocation;dialogOptions.dialogOptionFlags |= kNavAllowInvisibleFiles;dialogOptions.dialogOptionFlags |= kNavAllFilesInPopup;if (anErr == noErr){/* Get 'open' resource. A nil handle being returned is OK, *//* this simply means no automatic file filtering. */NavReplyRecord reply;NavTypeListHandle deftypeList = (NavTypeListHandle)GetResource('open', 128);deftypeList = nil; /* we apply no filter for the moment *//* Call NavGetFile() with specified options anddeclare our app-defined functions and type list*/anErr = NavGetFile (nil, &reply, &dialogOptions,nil, nil, nil,deftypeList, nil);if (anErr == noErr && reply.validRecord){/* Deal with multiple file selection */long count;anErr = AECountItems(&(reply.selection), &count);// Set up index for file listif (anErr == noErr){long index;for (index = 1; index <= count; index++){AEKeyword theKeyword;DescType actualType;Size actualSize;/* Get a pointer to selected file */anErr = AEGetNthPtr(&(reply.selection), index,typeFSS, &theKeyword,&actualType,documentFSSpec,sizeof(FSSpec),&actualSize);}}/* Dispose of NavReplyRecord, resources, descriptors */NavDisposeReply(&reply);}if (typeList != NULL){ReleaseResource( (Handle)typeList);}}}cleanup:return anErr;}/* DoOpen has been updated to use NavServicesJago, April 2001, Stefano M.Iacus*/OSStatus DoOpen ( void ){OSErr err ;FSSpec myfss;SInt16 pathLen;Handle pathName=NULL;FILE *fp;SEXP img, lst;int i;SFTypeList typeList;typeList[0] = kTypeText;typeList[1] = 'BINA';err = MyOpenDocument(&myfss, &typeList);if(err!= noErr)return(err);FSpGetFullPath(&myfss, &pathLen, &pathName);HLock((Handle)pathName);strncpy(InitFile, *pathName, pathLen);InitFile[pathLen] = '\0';HUnlock((Handle) pathName);/*Routine now handles XDR object. Nov 2000 (Stefano M. Iacus)*/if(!(fp = R_fopen(InitFile, "rb"))) { /* binary file */warning("File cannot be opened !");/* warning here perhaps */return;}PROTECT(img = R_LoadFromFile(fp, 1));switch (TYPEOF(img)) {case LISTSXP:while (img != R_NilValue) {defineVar(TAG(img), CAR(img), R_GlobalEnv);img = CDR(img);}break;case VECSXP:for (i = 0; i < LENGTH(img); i++) {lst = VECTOR_ELT(img,i);while (lst != R_NilValue) {defineVar(TAG(lst), CAR(lst), R_GlobalEnv);lst = CDR(lst);}}break;}UNPROTECT(1);fclose(fp);return(err);}/* This routine is responsible to showing (and eventually edit)files selected by the userJago, April 2001, Stefano M. Iacus*/OSErr DoOpenText(Boolean editable){FInfo fileInfo;SFTypeList typeList;OSErr err = noErr;FSSpec myfss;typeList[0] = kTypeText;typeList[1] = ftSimpleTextDocument;err = MyOpenDocument(&myfss, &typeList);if(err!= noErr)return(err);err = FSpGetFInfo(&myfss, &fileInfo);if (err != noErr) return err;DoNew(editable);RemWinMenuItem();err = ReadTextFile(&myfss,GetWindowWE(Edit_Windows[Edit_Window-1]));// if(err != noErr)// REprintf("\n ReadTextFile error: %d\n",err);UniqueWinTitle();if(Edit_Window>2)RepositionWindow(Edit_Windows[Edit_Window - 1],Edit_Windows[Edit_Window - 2],kWindowCascadeOnParentWindow);SetWindowProxyFSSpec(Edit_Windows[Edit_Window - 1], &myfss);return err;}/* DoSource: this routine sources .R files. It is accessibile via menus.Jago, January 2001, Stefano M.Iacus*/OSErr DoSource(void){SFTypeList typeList;OSErr err = noErr;FSSpec myfss;typeList[0] = kTypeText;typeList[1] = ftSimpleTextDocument;err = MyOpenDocument(&myfss, &typeList);if(err!= noErr)return(err);return( SourceFile(&myfss) );}/* SourceFile: is a completion to DoSource routine.It allows the Alpha editor to run scripts in Rin the S+/R tcl-mode.Jago Easter 2001, Stefano M. Iacus*/OSErr SourceFile(FSSpec *myfss){OSErr err = noErr;char sourcefile[FILENAME_MAX];char cmd[FILENAME_MAX+25];SInt16 pathLen;Handle pathName=NULL;if(myfss == NULL)return(-1);cmd[0] = '\0';FSpGetFullPath(myfss, &pathLen, &pathName);HLock((Handle)pathName);strncpy(sourcefile, *pathName, pathLen);sourcefile[pathLen] = '\0';HUnlock((Handle) pathName);sprintf(cmd,"source(\"%s\")",sourcefile);consolecmd(cmd);if(pathName)DisposeHandle(pathName);}/* SaveWindow: routine updated to use Navigation ServicesJago, April 2001, Stefano M. Iacus*/OSErr SaveWindow(const FSSpec *pFileSpec, WindowPtr window){DocumentHandle hDocument;AliasHandle alias = nil;int menu_item=-1,i;OSErr err;MenuHandle windowsMenu;Str255 Cur_Title,curString;Boolean EqString;if(window==NULL)window = FrontWindow();hDocument = GetWindowDocument(window);if (isGraphicWindow(window)) {/* We don't save these here... */}else {GetWTitle(window, Cur_Title);windowsMenu = GetMenuHandle(kMenuWindows);for(i = 1; i <= CountMenuItems(windowsMenu); i++){GetMenuItemText(windowsMenu, i , curString);EqString = EqualNumString(Cur_Title, curString, curString[0]);if (EqString) {menu_item = i;break;}}/* save the text */if ((err = WriteTextFile(pFileSpec, (*hDocument)->we)) == noErr) {if(window != Console_Window){SetWTitle(window, pFileSpec->name);if(menu_item!= -1){DeleteMenuItem(windowsMenu, i);AppendMenu(windowsMenu, pFileSpec->name);}/* replace the old window alias (if any) with a new onecreated from pFileSpec*/NewAlias(nil, pFileSpec, &alias);}}}return err;}OSStatus DoSave ( WindowPtr window ){FSSpec spec;OSStatus err;// get the file spec associated with this window, if anyif ( ( err = GetWindowProxyFSSpec( window, & spec )) == noErr ){err = SaveWindow ( & spec, window ) ;}else{// if no file was previously associated with this window, or if the// alias resolution failed, prompt the user for a new destinationerr = DoSaveAs (nil, window ) ;}return err;}/* DoSaveAs*/OSErr DoSaveAs(const FSSpec *suggestedTarget, WindowPtr window){StringHandle hPrompt;Str255 defaultName;Point where = { -1, -1 }; /* autocenter's dialog */OSErr err = noErr;OSErr anErr = noErr;NavReplyRecord reply;NavDialogOptions dialogOptions;OSType fileTypeToSave = 'TEXT';OSType creatorType = 'ttxt';FSSpec mytarget;FInfo finderInfo ;hPrompt = GetString(kPromptStringID);HLockHi((Handle) hPrompt);if (suggestedTarget != nil) {/* if a suggested target file is provided,use its name as the default name*/PStringCopy(suggestedTarget->name, defaultName);SetDefaultDirectory(suggestedTarget);}else {/* otherwise use the window titleas default name for CustomPutFile*/GetWTitle(window, defaultName);}/* put up the standard Save dialog box*/anErr = NavGetDefaultDialogOptions(&dialogOptions);dialogOptions.dialogOptionFlags |= kNavSelectDefaultLocation;PStringCopy(defaultName,dialogOptions.savedFileName);anErr = NavPutFile( nil,&reply,&dialogOptions,nil,fileTypeToSave,creatorType,nil );if (anErr == noErr && reply.validRecord){AEKeyword theKeyword;DescType actualType;Size actualSize;/* Get a pointer to selected file */anErr = AEGetNthPtr(&(reply.selection), 1,typeFSS, &theKeyword,&actualType, &mytarget,sizeof(mytarget),&actualSize);err = SaveWindow(&mytarget, window);/* Dispose of NavReplyRecord, resources, descriptors */NavDisposeReply(&reply);}elseerr = userCanceledErr;HUnlock((Handle)hPrompt);if(err == noErr)SetWindowProxyFSSpec(window,&mytarget);return err;}/* DoClose:In here, you need to understand that different windows havedifferent close methods. For a Graphic window, when you close it, youneed to tell R to remove the corresponding device. For aConsolewindow, when you close, it implies that you close theapplication. Thus, you need to ensure that the application closed.For Console and Edit windows, when you close, you need to askwhether they want to save the content or not, but for graphicwindow, it is not necessary.*/OSErr DoClose(ClosingOption closing, SavingOption saving, WindowPtr window){Str255 s1, s2;SInt16 alertResult,win_num,i;OSErr err;Boolean haveCancel;Str255 Cur_Title,curString;MenuHandle windowsMenu;Boolean EqString = FALSE;Cursor arrow;static ModalFilterUPP sFilterProc = nil;SelectWindow(window);if ( (win_num=isHelpWindow(window)) ) {GetWTitle(Help_Windows[win_num], Cur_Title);//SelectWindow(Help_Windows[win_num]);RemWinMenuItem();adjustHelpPtr(win_num);DestroyWindow(window);return noErr;}err = noErr;if(!finished){saving = DoWeSaveIt(window);if(saving == savingCancel)return;if(saving == savingNo){finished=true;goto furtherstep;}goto nextstep;}if(isGraphicWindow(window))goto furtherstep;/* is this window dirty?*/if (WEGetModCount(GetWindowWE(window)) > 0) {/* do we have to ask the user whether to save changes?*/if (saving == savingAsk) {/* prepare the parametric strings to be used in theSave Changes alert box*/GetWTitle(window, s1);GetIndString(s2, kClosingQuittingStringsID, 1 + closing);ParamText(s1, s2, nil, nil);/* put up the Save Changes? alert box*/SetCursor ( GetQDGlobalsArrow ( & arrow ) ) ;alertResult = Alert(kAlertSaveChanges, sFilterProc);/* exit if the user canceled the alert box*/if (alertResult == kButtonCancel)return userCanceledErr;if (alertResult == kButtonSave)saving = savingYes;elsesaving = savingNo;}nextstep:if (saving == savingYes) {if (isGraphicWindow(window))err = doSaveAsGraCommand();else { /* isGraphic */if (window == Console_Window) {err = doRSave(&haveCancel);if (haveCancel){jump_to_toplevel();}else {if (err == noErr){R_SaveGlobalEnv();}elseerror("File Corrupt or Memory error. Unrecoverable!");}}else {if(saving != savingNo){if(!finished){err= SaveWindow(&tempeditFSS, window);finished=true;}elseDoSave(window);}}}}}furtherstep:/* if it is a graphic window, maintain the menus and title first.*/if (isGraphicWindow(window)){Mac_Dev_Kill(window); /* Mac_Dev_Kill provides menu deletion */return noErr;}else {if ( (win_num=isEditWindow(window)) ) {RemWinMenuItem();adjustEditPtr(win_num);}/* destroy the window */DestroyWindow(window);if (window == Console_Window)ExitToShell();}return err;}SavingOption DoWeSaveIt(WindowPtr window){SavingOption saving = savingNo;Str255 s1, s2;SInt16 alertResult,win_num,i;OSErr err;Boolean haveCancel;Str255 Cur_Title,curString;MenuHandle windowsMenu;Boolean EqString = FALSE;Cursor arrow;static ModalFilterUPP sFilterProc = nil;if(!window)return(savingNo);if (WEGetModCount(GetWindowWE(window)) > 0) {/* put up the Save Changes? alert box*/SetCursor ( GetQDGlobalsArrow ( & arrow ) ) ;alertResult = Alert(kAlertSaveObject, sFilterProc);/* exit if the user canceled the alert box*/if (alertResult == kButtonCancel)saving=savingCancel;elseif (alertResult == kButtonSave)saving = savingYes;elsesaving = savingNo;}return(saving);}void MacFinalCleanup(){WindowPtr window;OSErr err;SavingOption saving = 1;/* Close all windowsquery the user about contentsif "saving" is non-zero.*/do {if ((window = FrontWindow()) != nil) {if ((err = DoClose(closingApplication, saving, window)) != noErr) {return;}}}while (window != nil);/* set a flag so we drop out of the event loop */ExitToShell();}/* MySFDialogFilter*/OSErr DoQuit(SavingOption saving){WindowPtr window;OSErr err;/* Close all windowsquery the user about contentsif "saving" is non-zero.*/do {if ((window = FrontWindow()) != nil) {if ((err = DoClose(closingApplication, saving, window)) != noErr) {return err;}}}while (window != nil);/* set a flag so we drop out of the event loop*/ExitToShell();return noErr;}void DoHelpChoice(SInt16 menuItem){if(menuItem == RHelpMenuItem){consolecmd("help.start()");return;}if(menuItem == RTopicHelpItem){Do_HelpOnTopic();return;}if(menuItem == SearchHelpItem){Do_SearchHelp();return;}if(menuItem == RunExampleItem)Do_RunExample();if(menuItem == LinkHtmlHelpItem){consolecmd("link.html.help()");return;}}/* DoAppleChoice :Which will be called when you click on the apple icon on the topleft corner. When you choice 'R about', it will open the predefinedhtml files and launch Netscape.*/void DoAppleChoice(SInt16 menuItem){StandardFileReply fileReply;SFTypeList fileTypes;OSErr launchErr;if (menuItem == kItemAbout){Do_About();#ifdef Preference/* Test whether the predefine file exists or not.If not, you need to prompt out the stardandGet file dialog to query the user, where they put the file.*/launchErr = FSpSetFLock(&gHelpFile);/* File not found with a reference number -43,However, I would like to check more general.If you have any err, then, you need to select itby yourself*/if (launchErr){GWdoErrorAlert(eNoSuchFile);fileTypes[0] = 'TEXT';StandardGetFile(nil,1,fileTypes,&fileReply);if (fileReply.sfGood){gHelpFile = fileReply.sfFile;/* savePreference(); *//* not sure whether it is necessary or not. */OpenSelection(&gHelpFile);}elseGWdoErrorAlert(eSelectNextTime);}else{launchErr = FSpRstFLock(&gHelpFile);launchErr = OpenSelection(&gHelpFile);}#endif}elseDoDeskAcc(menuItem);/* Do another normal choice, like "control panel' */}/* DoFileChoice:Which is used to deal with the menus choice on under "File" We stillhave no agreement in this moment. Those I don't know when to chancethe codes about doNew, DoOpen, DoClose and DoSaveAs.*/void DoFileChoice(SInt16 menuItem, WindowPtr window){// WindowPtr window = FrontWindow();OSErr osError, err;EventRecord myEvent;SInt16 WinIndex;Boolean haveCancel;if(window == NULL)window = FrontWindow();switch(menuItem) {case kItemNew:if (isGraphicWindow(window)) {RWrite("macintosh()\r");myEvent.message = 140301;DoGenKeyDown (&myEvent, true);}elseDoNew(true);break;case kItemShow:DoOpenText(false);break;case kItemEditFile:DoOpenText(true);break;case kItemOpen:if (isGraphicWindow(window)){WinIndex = isGraphicWindow(window);selectDevice(deviceNumber((DevDesc *)gGReference[WinIndex].devdesc));}elseDoSource();break;case kItemEditObject:Do_EditObject();break;case kItemLoadW:if (isEditWindow(window)){LoadEditEnvironment();LoadWindow();}if (window == Console_Window) {err = DoOpen();if (err)jump_to_toplevel();}break;case kItemSaveWSAs:err = doRSaveAs(&haveCancel);if (haveCancel){// RWrite("\r");jump_to_toplevel();}break;case kItemClose:DoClose(closingWindow, savingAsk, window);break;case kItemSave:DoSave(window);break;case kItemSaveAs:if( isGraphicWindow(window) )doSaveAsGraCommand();else{if(!finished)SaveWindow(&tempeditFSS,window);elseDoSaveAs(nil, window);}break;case kItemPageSetup:DoPageSetup();break;case kItemPrint:do_Print();break;case kItemQuit:err = DoQuit(savingAsk);break;}HiliteMenu(0);}/* DoEditChoice:Which is dsigned to handle the Menus choice about "Edit". We havedifferent implemenation on different kind of window. In thePreference, you can assign the tab size, the number of History commandthat you can keep and .....*/void DoEditChoice(SInt16 menuItem){WindowPtr window;WEReference we;OSStatus err;SInt32 selEnd, selStart, i;long scrapOffset, rc;EventRecord myEvent;char TempChar;ScrapRef scrap;Size scraplength;/* do nothing if no window is active*/if ((window = FrontWindow()) == nil) {return;}we = GetWindowWE(window);switch (menuItem) {case kItemUndo:WEUndo(we);break;case kItemCut :if (window == Console_Window) {WEGetSelection(&selStart, &selEnd, we);if (inRange(selStart, selEnd, gChangeAble -1, gChangeAble - 1))SysBeep(10);else{if (selStart <= gChangeAble)gChangeAble = gChangeAble + selStart - selEnd;WECut(we);}}elseWECut(we);break;case kItemCopy:if (isGraphicWindow(window)) {GraphicCopy(window);}elseWECopy(we);break;case kItemPaste:DoPaste(window);break;case kItemClear:if (window == Console_Window) {WEGetSelection(&selStart, &selEnd, we);if (inRange(selStart, selEnd, gChangeAble -1, gChangeAble - 1))SysBeep(10);else{if (selStart <= gChangeAble)gChangeAble = gChangeAble + selStart - selEnd;WEDelete(we);}}elseWEDelete (we);break;case kItemCopyPaste:ConsoleCopyAndPaste();break;case kItemSelectAll:WESetSelection(0, LONG_MAX, we);break;case kItemLineTo:DoLineTo();break;/*case kItemPreference:DoPreference(kDialogAboutBox);break;*/}}void DoPaste(WindowPtr window){WEReference we=nil;OSStatus err;ScrapRef scrap;Size scraplength;int last =0,i;EventRecord myEvent;char TempChar;char *buffer;char strerr[100];if(window ==NULL)return;if (isGraphicWindow(window) != 0)return;we = GetWindowWE(window);if(window != Console_Window){WEPaste(we);return;}WESetSelection(WEGetTextLength(we), WEGetTextLength(we), we);if( (err = GetCurrentScrap(&scrap)) != noErr)return;if( (err = GetScrapFlavorSize(scrap,kScrapFlavorTypeText,&scraplength)) != noErr)return;if (scraplength < 1)return;ReserveMem(scraplength+1);err = MemError();if(err != noErr)return;myHandle = NewHandle(scraplength+1);if( (err = MemError()) != noErr)return;if( (err = GetScrapFlavorData(scrap,kScrapFlavorTypeText, &scraplength, *myHandle)) != noErr)return;HLock(myHandle);(*myHandle)[scraplength] = 0; /* make it ASCII */finalPaste = scraplength;for (i = 0; i <= scraplength; i++) {//if( (*myHandle)[i] == '\n' ) (*myHandle)[i] = '\r';TempChar = (*myHandle)[i];if ((TempChar == '\r') || (i == finalPaste)){RnWrite(*myHandle, i);if (i != finalPaste) {myEvent.message = 140301;DoKeyDown(&myEvent);}curPaste = i;break;}}finalPaste = scraplength;HUnlock(myHandle);if (scraplength != i)HaveContent = true;elseDisposeHandle(myHandle);}/* Only resolutions 72, 144, 300 and 600 are allowable */int GetScreenRes(void){gScreenRes = atoi(mac_getenv("ScreenRes"));if( gScreenRes != 72 && gScreenRes != 144 &&gScreenRes != 300 && gScreenRes != 600)gScreenRes = 72;return(gScreenRes);}int GetTextSize(void){gTextSize = atoi(mac_getenv("TextSize"));if(gTextSize < 8 || gTextSize > 14)gTextSize = 12;return(gTextSize);}void changeSize(WindowPtr window, SInt16 newSize){if(window)WESetOneAttribute ( kCurrentSelection, kCurrentSelection, weTagFontSize,& newSize, sizeof ( Fixed ), GetWindowWE ( window ) );}/* DoTools:Some usefule shortcuts*/void DoTools(SInt16 menuItem){WindowPtr window = FrontWindow();OSErr osError, err;EventRecord myEvent;SInt16 WinIndex;Boolean haveCancel;switch(menuItem) {case kItemShowWSpace:consolecmd("ls()");break;case kItemClrWSpace:consolecmd("rm(list=ls())");break;case kItemLoadWSpace:consolecmd("load(\".RData\")");break;case kItemSaveWSpace:consolecmd("save.image()");break;case kItemLoadHistory:consolecmd("loadhistory()");break;case kItemSaveHistory:consolecmd("savehistory()");break;case kItemShowHistory:consolecmd("history()");break;case kItemChangeDir:DoSelectDirectory();break;case kItemShowDir:consolecmd("getwd()");break;case kItemResetDir:consolecmd("setwd(R.home())");break;case kItemShowLibrary:consolecmd("library()");break;case kItemShowData:consolecmd("data()");break;}HiliteMenu(0);}/* DoMenuChoice:The main function on RMenus.c, it is used to handle where to dispatchthe event to the corresponding procedure to handle the correspondingmenus choice. Thus, if you need some Menus choice, it is the bestplace to start with.*/void DoMenuChoice(SInt32 menuChoice, EventModifiers modifiers, WindowPtr window){SInt16 menuID, menuItem;// extract menu ID and menu item from menuChoicemenuID = HiWord(menuChoice);menuItem = LoWord(menuChoice);// dispatch on menuIDswitch (menuID) {case kMenuApple:DoAppleChoice(menuItem);break;case kMenuFile:DoFileChoice(menuItem,window);break;case kMenuEdit:DoEditChoice(menuItem);break;case kMenuTools:DoTools(menuItem);break;case kMenuWindows:doWindowsMenu(menuItem);break;case kMenuConfig:doConfigMenu(menuItem);break;case kHMHelpMenuID: /* the help menu */DoHelpChoice(menuItem);break;}HiliteMenu(0);}/* InitializeMenus*/OSErr InitializeMenus(void){Handle menuBar = nil ;MenuRef menu ;OSErr err = noErr;#if TARGET_API_MAC_CARBONItemCount submenuCount ;ItemCount itemCount ;SInt32 gestaltResponse ;#endif// get the 'MBAR' resourcemenuBar = GetNewMBar ( kMenuBarID ) ;if ( ( err = ResError ( ) ) != noErr ){goto cleanup ;}err = memFullErr ;if ( ! menuBar ){goto cleanup ;}// install the menu barSetMenuBar ( menuBar ) ;/* Here we add some items to the Help Menu */HMGetHelpMenu(&HelpMenu,NULL);if (HelpMenu != nil) {AppendMenu(HelpMenu, "\pR Help");RHelpMenuItem=CountMenuItems(HelpMenu);SetItemCmd(HelpMenu,RHelpMenuItem,'?');AppendMenu(HelpMenu, "\pHelp On Topic...");RTopicHelpItem=CountMenuItems(HelpMenu);AppendMenu(HelpMenu,"\pSearch Help On...");SearchHelpItem=CountMenuItems(HelpMenu);AppendMenu(HelpMenu, "\pRun An Example...");RunExampleItem=CountMenuItems(HelpMenu);AppendMenu(HelpMenu, "\pLink Packages Help");LinkHtmlHelpItem=CountMenuItems(HelpMenu);}/* Appends the Preferences menuitem to the Config menu *//* This is not needed under OS X */if( !RunningOnCarbonX()){if( (menu = GetMenuHandle( kMenuConfig )) == NULL) goto cleanup;AppendMenu(menu, "\pPreferences...");PreferencesItem = CountMenuItems(menu);if( (err = SetMenuItemCommandID (menu, PreferencesItem, kHICommandPreferences)) != noErr)goto cleanup;}#if TARGET_API_MAC_CARBONif ( ( Gestalt ( gestaltMenuMgrAttr, & gestaltResponse ) == noErr ) &&( gestaltResponse & gestaltMenuMgrAquaLayoutMask ) ){if ( ( menu = GetMenuHandle ( kMenuFile ) ) != nil ){// assume the Quit item is the last item in the File menu and follows a separator lineitemCount = CountMenuItems ( menu ) ;if ( itemCount > 2 ){DeleteMenuItem ( menu, itemCount ) ;DeleteMenuItem ( menu, itemCount - 1 ) ;}}}#else// set up the Apple menu (this is not required under Carbon)if ( ( menu = GetMenuHandle ( kMenuApple ) ) != nil ){AppendResMenu ( menu, kTypeDeskAccessory ) ;}#endif// draw the menu barDrawMenuBar();err = noErr;cleanup :ForgetHandle ( & menuBar ) ;return err ;}Boolean RunningOnCarbonX(void){UInt32 response;return (Gestalt(gestaltSystemVersion,(SInt32 *) &response) == noErr)&& (response >= 0x01000);}/* do_PrintThis routine has been completely rewritten.If it is a Graphic window then the printLoopfunction passes the control to the Graphic Printingprocedure, otherwise it passes the contro tothe DoTextPrint function to print the textwindows (Help, Console etc)Jago, April 2001, Stefano M. Iacus*/void do_Print(void){WindowPtr window;WEReference we;DevDesc *dd;SInt16 WinIndex;GrafPtr savePort;GrafPtr picPort;Point linesize;Point *lp;Rect portRect;linesize.h = 10;linesize.v = 7;lp = &linesize;window = FrontWindow();we = GetWindowWE(window);printLoop(window);}extern PMPageFormat pageFormat;extern PMPrintSettings printSettings;extern PMPrintSession printSession;/* OpenSelection :Given a FSSpecPtr to either an application or a document,OpenSelection creates a finder Open Selection Apple event for theobject described by the FSSpec.*/OSErr OpenSelection(FSSpecPtr theDoc){AppleEvent aeEvent; // the event to create;AEDesc myAddressDesc; // descriptors for theAEDesc aeDirDesc;AEDesc listElem;AEDesc fileList; // our listFSSpec dirSpec;AliasHandle dirAlias; // alias to directory with our fileAliasHandle fileAlias; // alias of the file itselfProcessSerialNumber process; // the finder's psnOSErr myErr; // duh// Get the psn of the Finder and create the target address for the .if(FindAProcess(kFinderSig,kSystemType,&process))return procNotFound;myErr = AECreateDesc(typeProcessSerialNumber,(Ptr) &process,sizeof(process), &myAddressDesc);if(myErr)return myErr;// Create an emptymyErr = AECreateAppleEvent(kAEFinderEvents, kAEOpenSelection,&myAddressDesc, kAutoGenerateReturnID,kAnyTransactionID, &aeEvent);if(myErr)return myErr;// Make an FSSpec and alias for the parent folder, and an alias for the fileFSMakeFSSpec(theDoc->vRefNum,theDoc->parID,nil,&dirSpec);NewAlias(nil,&dirSpec,&dirAlias);NewAlias(nil,theDoc,&fileAlias);// Create the file list.if(myErr=AECreateList(nil,0,false,&fileList))return myErr;// Create the folder descriptorHLock((Handle)dirAlias);AECreateDesc(typeAlias, (Ptr) *dirAlias, GetHandleSize((Handle) dirAlias), &aeDirDesc);HUnlock((Handle)dirAlias);DisposeHandle((Handle)dirAlias);if((myErr = AEPutParamDesc(&aeEvent,keyDirectObject,&aeDirDesc)) == noErr) {AEDisposeDesc(&aeDirDesc);HLock((Handle)fileAlias);AECreateDesc(typeAlias, (Ptr)*fileAlias,GetHandleSize((Handle)fileAlias), &listElem);HUnlock((Handle)fileAlias);DisposeHandle((Handle)fileAlias);myErr = AEPutDesc(&fileList,0,&listElem);}if(myErr)return myErr;AEDisposeDesc(&listElem);if(myErr = AEPutParamDesc(&aeEvent,keySelection,&fileList))return myErr;myErr = AEDisposeDesc(&fileList);myErr = AESend(&aeEvent, nil,kAENoReply+kAEAlwaysInteract+kAECanSwitchLayer,kAENormalPriority, kAEDefaultTimeout, nil, nil);AEDisposeDesc(&aeEvent);}/* FindAProcess*/OSErr FindAProcess(OSType typeToFind, OSType creatorToFind,ProcessSerialNumberPtr processSN){ProcessInfoRec tempInfo;FSSpec procSpec;Str31 processName;OSErr myErr = noErr;// start at the beginning of the process listprocessSN->lowLongOfPSN = kNoProcess;processSN->highLongOfPSN = kNoProcess;// initialize the process information recordtempInfo.processInfoLength = sizeof(ProcessInfoRec);tempInfo.processName = (StringPtr)&processName;tempInfo.processAppSpec = &procSpec;while((tempInfo.processSignature != creatorToFind ||tempInfo.processType != typeToFind) ||myErr != noErr){myErr = GetNextProcess(processSN);if (myErr == noErr)GetProcessInformation(processSN, &tempInfo);}return(myErr);}/* assignPString :convert char* into unsigned char* with length howLong.*/void assignPString(unsigned char* input, char* buf, SInt16 howLong){SInt16 i;input[0] = howLong;for (i = 1; i <= howLong; i++){input[i] = buf[i - 1];}}/* ConsoleCopyAndPaste :A procedure which will be directly called when you chooseCopy and Paste from the Menus. It copies from any text windowto the R Console.Fixed on April 2001, Stefano M. Iacus*/void ConsoleCopyAndPaste(){WEReference we;SInt32 selStart, selEnd;we = GetWindowWE(FrontWindow());WECopy(we);SelectWindow(Console_Window);DoPaste(Console_Window);}/*This routine is intended to pass a command string to R ConsoleNothing special is done, just writing the command string 'cmd'as is and then send to the R application an Apple Event ofcarriage return.This is mainly tought to run "source" command fom the menu.Implemented on 9 Feb 2001, Stefano M. Iacus*/void consolecmd(char *cmd){long cmdlen;EventRecord myEvent;if((cmdlen = strlen(cmd))<1)return;SelectWindow(Console_Window);/* we just write the cmd as it is to the console */RnWrite(cmd, cmdlen);/* We send a '\r' event to the console */myEvent.message = 140301;DoKeyDown(&myEvent);}static pascal void NavEventFilter(NavEventCallbackMessage inSelector,NavCBRec * inPB,void * inUserData){NavCallbackData * cd = ( NavCallbackData * ) inUserData ;switch ( inSelector ){case kNavCBEvent :{EventRecord * event = inPB -> eventData . eventDataParms . event ;// intercept window events directed to windows behind the dialogif ( ( event->what == updateEvt ) || ( event->what == activateEvt ) ){if ( ( WindowRef ) event->message != inPB->window ){DoWindowEvent ( event ) ;}}}case kNavCBCustomize :{// do we need extra items?if ( ! cd ){return ;}// request an area for the extra itemsif ( ( inPB -> customRect . right == 0 ) && ( inPB -> customRect . bottom == 0 ) ){inPB -> customRect . right = inPB -> customRect . left + 240 ;inPB -> customRect . bottom = inPB -> customRect . top + 30 ;}break ;}case kNavCBStart :{DialogRef dialog = GetDialogFromWindow ( inPB -> window ) ;Handle extraItems =NULL;OSStatus err ;// do we need extra items?if ( ! cd ){return ;}// get the DITL resource containing the extra itemsif ( ( extraItems = GetResource ( FOUR_CHAR_CODE ( 'DITL' ), cd -> extraItemsID ) ) == nil ){return ;}DetachResource ( extraItems ) ;// add it to the nav dialog control listerr = NavCustomControl ( inPB -> context, kNavCtlAddControlList, extraItems ) ;DisposeHandle ( extraItems ) ;if ( err != noErr ){return ;}// count existing dialog itemsif ( ( err = NavCustomControl ( inPB -> context, kNavCtlGetFirstControlID, & cd -> numItems ) ) != noErr ){return ;}// get handles to our custom controls/* if ( ( err = GetDialogItemAsControl (dialog, cd -> numItems + kItemFormatPopup, & cd -> formatPopup ) ) != noErr ){return ;}if ( ( err = GetDialogItemAsControl ( dialog, cd -> numItems + kItemStationeryCheckbox, & cd -> stationeryCheckbox ) ) != noErr ){return ;}// set up the format popupSetControlValue ( cd -> formatPopup, ( cd -> fileType == kTypeText ) ? kItemTextFormat : kItemUnicodeTextFormat ) ;break ;*/}}}static OSStatus CreateNavTypeList(OSType inApplicationSignature,UInt16 inNumTypes,const OSType * inSFTypeList,NavTypeListHandle * outNavTypeList){OSStatus err ;// allocate the type list handle* outNavTypeList = ( NavTypeListHandle ) NewHandleClear ( ( sizeof ( NavTypeList ) - sizeof ( OSType ) ) +( inNumTypes * sizeof ( OSType ) ) ) ;if ( ( err = MemError ( ) ) != noErr ){return err ;}// fill it in( ** outNavTypeList ) -> componentSignature = inApplicationSignature ;( ** outNavTypeList ) -> osTypeCount = inNumTypes ;BlockMoveData ( inSFTypeList, ( ** outNavTypeList ) -> osType, inNumTypes * sizeof ( OSType ) ) ;return noErr ;}