Beispiel #1
0
void TLevelWriter3gp::save(const TImageP &img, int frameIndex)
{
	if (m_cancelled)
		return;

	TRasterImageP image(img);
	int lx = image->getRaster()->getLx();
	int ly = image->getRaster()->getLy();
	//void *buffer = image->getRaster()->getRawData();
	int pixSize = image->getRaster()->getPixelSize();
	if (pixSize != 4)
		throw TImageException(getFilePath(), "Unsupported pixel type");

	QMutexLocker sl(&m_mutex);

	if (!m_properties)
		m_properties = new Tiio::MovWriterProperties();

	Tiio::MovWriterProperties *prop = (Tiio::MovWriterProperties *)(m_properties);

	//CodecType compression = StandardCompressionType;  prop->getCurrentCodec();
	//CodecQ quality = StandardQualityType;  prop->getCurrentQuality();

	if (!m_initDone) {
		//FSSpec fspec;
		Rect frame;
		long max_compressed_size;
		QDErr err;

		m_videoTrack = NewMovieTrack(m_movie, FixRatio((short)lx, 1), FixRatio((short)ly, 1), kNoVolume);

		if ((err = GetMoviesError() != noErr))
			throw TImageException(getFilePath(), "can't create video track");

		m_dataRef = nil;
		m_hMovieData = NewHandle(0);

		// Construct the Handle data reference
		err = PtrToHand(&m_hMovieData, &m_dataRef, sizeof(Handle));

		if ((err = GetMoviesError() != noErr))
			throw TImageException(getFilePath(), "can't create Data Ref");

		m_videoMedia = NewTrackMedia(m_videoTrack, VideoMediaType, (TINT32)m_frameRate, m_dataRef, HandleDataHandlerSubType);

		OpenADefaultComponent(MovieExportType, '3gpp', &m_myExporter);

		//  err = (short)MovieExportDoUserDialog(m_myExporter, m_movie, 0, 0, 0, &m_cancelled);

		//  if (m_cancelled)
		//	  throw TImageException(getFilePath(), "User abort of 3GP render");
		if ((err = GetMoviesError() != noErr))
			throw TImageException(getFilePath(), "can't create video media");
		if ((err = BeginMediaEdits(m_videoMedia)) != noErr)
			throw TImageException(getFilePath(), "can't begin edit video media");
		frame.left = 0;
		frame.top = 0;
		frame.right = lx;
		frame.bottom = ly;

#if 0
  if ((err = NewGWorld(&(m_gworld), pixSize * 8, &frame, 0, 0, 0))!=noErr)
#else /* Mac OSX 10.7 later */
		if ((err = QTNewGWorld(&(m_gworld), pixSize * 8, &frame, 0, 0, 0)) != noErr)
#endif
		throw TImageException(getFilePath(), "can't create movie buffer");
#ifdef WIN32
		LockPixels(m_gworld->portPixMap);
		if ((err = GetMaxCompressionSize(m_gworld->portPixMap, &frame, 0,
										 quality, compression, anyCodec,
										 &max_compressed_size)) != noErr)
			throw TImageException(getFilePath(), "can't get max compression size");

#else

#if 0
  PixMapHandle pixmapH = GetPortPixMap (m_gworld);
  LockPixels(pixmapH);
#else
		PixMapHandle pixmapH = NULL;
#endif
		max_compressed_size = lx * ly * 4 * 20;

/*if ((err = GetMaxCompressionSize(pixmapH, &frame, 0, 
                                quality,  compression,anyCodec, 
				 &max_compressed_size))!=noErr)
    throw TImageException(getFilePath(), "can't get max compression size");*/
#endif

		m_compressedData = NewHandle(max_compressed_size);

		if ((err = MemError()) != noErr)
			throw TImageException(getFilePath(), "can't allocate compressed data for movie");

		MoveHHi(m_compressedData);
		HLock(m_compressedData);
		if ((err = MemError()) != noErr)
			throw TImageException(getFilePath(), "can't allocate img handle");

#if 0
  m_pixmap = GetGWorldPixMap(m_gworld);
  
  
  if (!LockPixels(m_pixmap))
    throw TImageException(getFilePath(), "can't lock pixels");

  buf    = (PixelXRGB*) GetPixBaseAddr(m_pixmap);
#else
		m_pixmap = NULL;
		buf = NULL;
#endif
		buf_lx = lx;
		buf_ly = ly;

		m_initDone = true;
	}

	unsigned short rowBytes = (unsigned short)(((short)(*(m_pixmap))->rowBytes & ~(3 << 14)));

	Rect frame;
	ImageDescriptionHandle img_descr;
	Ptr compressed_data_ptr;
	QDErr err;

	frame.left = 0;
	frame.top = 0;
	frame.right = lx;
	frame.bottom = ly;

	TRasterP ras = image->getRaster();
#ifdef WIN32
	compressed_data_ptr = StripAddress(*(m_compressedData));
	copy(ras, buf, buf_lx, buf_ly);
#else
	compressed_data_ptr = *m_compressedData;
	copy(ras, buf, buf_lx, buf_ly, rowBytes);
#endif
	img_descr = (ImageDescriptionHandle)NewHandle(4);

#ifdef WIN32
	if ((err = CompressImage(m_gworld->portPixMap,
							 &frame,
							 quality, compression,
							 img_descr, compressed_data_ptr)) != noErr)
		throw TImageException(getFilePath(), "can't compress image");
#else

#if 0
 PixMapHandle pixmapH = GetPortPixMap (m_gworld);
 if ((err = CompressImage(pixmapH, 
	                 &frame, 
  			 codecNormalQuality, kJPEGCodecType,
			 img_descr, compressed_data_ptr))!=noErr)
	{
  throw TImageException(getFilePath(), "can't compress image");
}
#endif
#endif

	if ((err = AddMediaSample(m_videoMedia, m_compressedData, 0,
							  (*img_descr)->dataSize, 1,
							  (SampleDescriptionHandle)img_descr,
							  1, 0, 0)) != noErr)
		throw TImageException(getFilePath(), "can't add image to movie media");

	DisposeHandle((Handle)img_descr);
}
OSErr open_network_speaker()
{
    short block_size = kBlockSize;
    short connection_threshold = kConnectionThreshhold;
    OSErr error;

    assert(!speaker);
    assert(block_size>0&&block_size<=MAXIMUM_DOUBLE_BUFFER_SIZE);
    assert(connection_threshold>1&&connection_threshold<16);

    /* install our atexit cleanup procedure and build a routine descriptor */
    {
        static bool initialization= true;

        if (initialization) {
// ZZZ: Sorry, it looks like the CarbonSndPlayDoubleBuffer stuff really wants a plain C function
// pointer, sitting in the structure typed as a SndDoubleBackUPP.  (Don't ask me!)
#if defined(TARGET_API_MAC_CARBON)
            doubleback_routine_descriptor=
                (SndDoubleBackUPP)network_speaker_doubleback_procedure;
#else
            // Thomas Herzog fix
#if UNIVERSAL_INTERFACES_VERSION < 0x0340
            doubleback_routine_descriptor= NewSndDoubleBackProc(
                                               (ProcPtr)network_speaker_doubleback_procedure);
#else
            doubleback_routine_descriptor= NewSndDoubleBackUPP(
                                               network_speaker_doubleback_procedure);
#endif
            // doubleback_routine_descriptor= NewSndDoubleBackProc((ProcPtr)network_speaker_doubleback_procedure);
#endif
            assert(doubleback_routine_descriptor);

            atexit(close_network_speaker);
        }
    }

    speaker=
        (struct speaker_definition *) NewPtr(sizeof(struct speaker_definition));
    if ((error= MemError())==noErr) {
        speaker->random_seed= 1;
        speaker->block_size= block_size;
        speaker->connection_threshold= connection_threshold;

        speaker->channel= (SndChannelPtr) NewPtrClear(sizeof(SndChannel));
        speaker->header=
            (SndDoubleBufferHeaderPtr) NewPtrClear(sizeof(SndDoubleBufferHeader));
        speaker->queue= NewPtr(sizeof(byte)*MAXIMUM_QUEUE_SIZE);
        if ((error= MemError())==noErr) {
            SndDoubleBufferHeaderPtr header= speaker->header;

            header->dbhNumChannels= 1;
            header->dbhSampleSize= 8;
            header->dbhCompressionID= 0;
            header->dbhPacketSize= 0;
            header->dbhSampleRate= rate11025hz;
            header->dbhDoubleBack= doubleback_routine_descriptor;
            header->dbhBufferPtr[0]=
                (SndDoubleBufferPtr) NewPtrClear(
                    sizeof(SndDoubleBuffer)+MAXIMUM_DOUBLE_BUFFER_SIZE);
            header->dbhBufferPtr[1]=
                (SndDoubleBufferPtr) NewPtrClear(
                    sizeof(SndDoubleBuffer)+MAXIMUM_DOUBLE_BUFFER_SIZE);

            if ((error= MemError())==noErr) {
                speaker->channel->qLength= stdQLength;
#ifdef env68k
                speaker->channel->userInfo= (long) get_a5();
#endif

                error=
                    SndNewChannel(&speaker->channel, sampledSynth, initMono|initMACE6,
                                  NULL);
                if (error==noErr) {
                    quiet_network_speaker();                               /* to set defaults */
                }
            }
        }
    }

#ifdef SPEEX
    init_speex_decoder();
#endif

    /* if something went wrong, zero the speaker definition (without freeing any of our memory
            like we should) */
    if (error!=noErr) {
        speaker= (struct speaker_definition *) NULL;
    }

    return error;
}
Beispiel #3
0
/*
**	GetIconFromDesktopFile
**
**	INPUT a pointer to a non-existent Handle, because we'll allocate one
**
**	search each BNDL resource for the right fileCreator and once we get it
**		find the 'FREF' type in BNDL
**		for each localID in the type, open the FREF resource
**			if the FREF is the desired fileType
**				get its icon localID
**				get the ICN# type in BNDL
**				get the icon resource number from the icon localID
**				get the icon resource type from the desktop mgr's iconType
**				get the icon of that type and number
*/
static	OSErr	GetIconFromDesktopFile(ConstStr255Param volName,
									   short vRefNum,
									   short iconType,
									   OSType fileCreator,
									   OSType fileType,
									   Handle *iconHandle)
{
	OSErr			error;
	short			realVRefNum;
	Str255			desktopName;
	short			savedResFile;
	short			dfRefNum;
	BNDLRecHandle	theBndl = NULL;
	BundleTypePtr	theBundleType;
	short			iconLocalID;
	short			iconRsrcID;
	OSType			iconRsrcType;
	Handle			returnIconHandle;	
	char			bndlState;
	
	*iconHandle = NULL;
	
	error = DetermineVRefNum(volName, vRefNum, &realVRefNum);
	if ( error == noErr )
	{
		error = GetDesktopFileName(realVRefNum, desktopName);
		if ( error == noErr )
		{
			savedResFile = CurResFile();
		
			/*
			**	Open the 'Desktop' file in the root directory. (because
			**	opening the resource file could preload unwanted resources,
			**	bracket the call with SetResLoad(s))
			*/
			SetResLoad(false);
			dfRefNum = HOpenResFile(realVRefNum, fsRtDirID, desktopName, fsRdPerm);
			SetResLoad(true);
		
			if ( dfRefNum != -1 )
			{
				/*
				**	Find the BNDL resource with the specified creator.
				*/
				error = FindBundleGivenCreator(fileCreator, &theBndl);
				if ( error == noErr )
				{
					/* Lock the BNDL resource so it won't be purged when other resources are loaded */
					bndlState = HGetState((Handle)theBndl);
					HLock((Handle)theBndl);
					
					/* Find the 'FREF' BundleType record in the BNDL resource. */
					error = FindTypeInBundle(kFREFResType, theBndl, &theBundleType);
					if ( error == noErr )
					{
						/* Find the local ID in the 'FREF' resource with the specified fileType */
						error = GetLocalIDFromFREF(theBundleType, fileType, &iconLocalID);
						if ( error == noErr )
						{
							/* Find the 'ICN#' BundleType record in the BNDL resource. */
							error = FindTypeInBundle(kIconFamResType, theBndl, &theBundleType);
							if ( error == noErr )
							{
								/* Find the icon's resource ID in the 'ICN#' BundleType record */
								error = GetIconRsrcIDFromLocalID(theBundleType, iconLocalID, &iconRsrcID);
								if ( error == noErr )
								{
									/* Map Desktop Manager icon type to resource type */
									iconRsrcType = DTIconToResIcon(iconType);
									
									if ( iconRsrcType != (OSType)0 )
									{
										/* Load the icon */
										returnIconHandle = Get1Resource(iconRsrcType, iconRsrcID);
										if ( returnIconHandle != NULL )
										{
											/* Copy the resource handle, and return the copy */
											HandToHand(&returnIconHandle);
											if ( MemError() == noErr )
											{
												*iconHandle = returnIconHandle;
											}
											else
											{
												error = afpItemNotFound;
											}
										}
										else
										{
											error = afpItemNotFound;
										}
									}
								}
							}
						}
					}
					/* Restore the state of the BNDL resource */ 
					HSetState((Handle)theBndl, bndlState);
				}
				/* Restore the resource chain and close the Desktop file */
				UseResFile(savedResFile);
				CloseResFile(dfRefNum);
			}
			else
			{
				error = ResError(); /* could not open Desktop file */
			}
		}
		if ( (error != noErr) && (error != memFullErr) )
		{
			error = afpItemNotFound;	/* force an error we should return */
		}
	}
	
	return ( error );
}
Beispiel #4
0
OSErr
FSpPathFromLocation(
    FSSpec *spec,		/* The location we want a path for. */
    int *length,		/* Length of the resulting path. */
    Handle *fullPath)		/* Handle to path. */
{
    OSErr err;
    FSSpec tempSpec;
    CInfoPBRec pb;
	
    *fullPath = NULL;
	
    /* 
     * Make a copy of the input FSSpec that can be modified.
     */
    BlockMoveData(spec, &tempSpec, sizeof(FSSpec));
	
    if (tempSpec.parID == fsRtParID) {
	/* 
	 * The object is a volume.  Add a colon to make it a full 
	 * pathname.  Allocate a handle for it and we are done.
	 */
	tempSpec.name[0] += 2;
	tempSpec.name[tempSpec.name[0] - 1] = ':';
	tempSpec.name[tempSpec.name[0]] = '\0';
		
	err = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]);
    } else {
	/* 
	 * The object isn't a volume.  Is the object a file or a directory? 
	 */
	pb.dirInfo.ioNamePtr = tempSpec.name;
	pb.dirInfo.ioVRefNum = tempSpec.vRefNum;
	pb.dirInfo.ioDrDirID = tempSpec.parID;
	pb.dirInfo.ioFDirIndex = 0;
	err = PBGetCatInfoSync(&pb);

	if ((err == noErr) || (err == fnfErr)) {
	    /* 
	     * If the file doesn't currently exist we start over.  If the
	     * directory exists everything will work just fine.  Otherwise we
	     * will just fail later.  If the object is a directory, append a
	     * colon so full pathname ends with colon, but only if the name is
	     * not empty.  NavServices returns FSSpec's with the parent ID set,
	     * but the name empty...
	     */
	    if (err == fnfErr) {
		BlockMoveData(spec, &tempSpec, sizeof(FSSpec));
	    } else if ( (pb.hFileInfo.ioFlAttrib & ioDirMask) != 0 ) {
	        if (tempSpec.name[0] > 0) {
		    tempSpec.name[0] += 1;
		    tempSpec.name[tempSpec.name[0]] = ':';
		}
	    }
			
	    /* 
	     * Create a new Handle for the object - make it a C string.
	     */
	    tempSpec.name[0] += 1;
	    tempSpec.name[tempSpec.name[0]] = '\0';
	    err = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]);
	    if (err == noErr) {
		/* 
		 * Get the ancestor directory names - loop until we have an 
		 * error or find the root directory.
		 */
		pb.dirInfo.ioNamePtr = tempSpec.name;
		pb.dirInfo.ioVRefNum = tempSpec.vRefNum;
		pb.dirInfo.ioDrParID = tempSpec.parID;
		do {
		    pb.dirInfo.ioFDirIndex = -1;
		    pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID;
		    err = PBGetCatInfoSync(&pb);
		    if (err == noErr) {
			/* 
			 * Append colon to directory name and add 
			 * directory name to beginning of fullPath.
			 */
			++tempSpec.name[0];
			tempSpec.name[tempSpec.name[0]] = ':';
						
			(void) Munger(*fullPath, 0, NULL, 0, &tempSpec.name[1],
				tempSpec.name[0]);
			err = MemError();
		    }
		} while ( (err == noErr) &&
			(pb.dirInfo.ioDrDirID != fsRtDirID) );
	    }
	}
    }
    
    /*
     * On error Dispose the handle, set it to NULL & return the err.
     * Otherwise, set the length & return.
     */
    if (err == noErr) {
	*length = GetHandleSize(*fullPath) - 1;
    } else {
	if ( *fullPath != NULL ) {
	    DisposeHandle(*fullPath);
	}
	*fullPath = NULL;
	*length = 0;
    }

    return err;
}
OSErr QTDR_CopyRemoteFileToLocalFile (char *theURL, FSSpecPtr theFile)
{
	Handle				myReaderRef = NULL;			// data reference for the remote file
	Handle				myWriterRef = NULL;			// data reference for the local file
	ComponentResult		myErr = badComponentType;

	//////////
	//
	// create the local file with the desired type and creator
	//
	//////////
	
	// delete the target local file, if it already exists;
	// if it doesn't exist yet, we'll get an error (fnfErr), which we just ignore
	FSpDelete(theFile);
	
	myErr = FSpCreate(theFile, kTransFileCreator, kTransFileType, smSystemScript);
	if (myErr != noErr)
		goto bail;
	
	//////////
	//
	// create data references for the remote file and the local file
	//
	//////////
	
	myReaderRef = QTDR_MakeURLDataRef(theURL);
    if (myReaderRef == NULL)
    	goto bail;

	myWriterRef = QTDR_MakeFileDataRef(theFile);
    if (myWriterRef == NULL)
    	goto bail;

	//////////
	//
	// find and open the URL and file data handlers; connect the data references to them
	//
	//////////
	
	gDataReader = OpenComponent(GetDataHandler(myReaderRef, URLDataHandlerSubType, kDataHCanRead));
	if (gDataReader == NULL)
		goto bail;

	gDataWriter = OpenComponent(GetDataHandler(myWriterRef, rAliasType, kDataHCanWrite));
	if (gDataWriter == NULL)
		goto bail;
		
	// set the data reference for the URL data handler
	myErr = DataHSetDataRef(gDataReader, myReaderRef);
	if (myErr != noErr)
		goto bail;
	
	// set the data reference for the file data handler
	myErr = DataHSetDataRef(gDataWriter, myWriterRef);
	if (myErr != noErr)
		goto bail;
	
	//////////
	//
	// allocate a data buffer; the URL data handler copies data into this buffer,
	// and the file data handler copies data out of it
	//
	//////////
	
	gDataBuffer = NewPtrClear(kDataBufferSize);
	myErr = MemError();
	if (myErr != noErr)
		goto bail;
		
	//////////
	//
	// connect to the remote and local files
	//
	//////////
	
	// open a read-only path to the remote data reference
	myErr = DataHOpenForRead(gDataReader);
	if (myErr != noErr)
		goto bail;

	// get the size of the remote file
	myErr = DataHGetFileSize(gDataReader, &gBytesToTransfer); 
	if (myErr != noErr)
		goto bail;
	
	// open a write-only path to the local data reference
	myErr = DataHOpenForWrite(gDataWriter);
	if (myErr != noErr)
		goto bail;
		
	//////////
	//
	// start reading and writing data
	//
	//////////
	
	gDoneTransferring = false;
	gBytesTransferred = 0L;
	
	gReadDataHCompletionUPP = NewDataHCompletionUPP(QTDR_ReadDataCompletionProc);
	gWriteDataHCompletionUPP = NewDataHCompletionUPP(QTDR_WriteDataCompletionProc);
		
	// start retrieving the data; we do this by calling our own write completion routine,
	// pretending that we've just successfully finished writing 0 bytes of data
	QTDR_WriteDataCompletionProc(gDataBuffer, 0L, noErr);

bail:
	// if we encountered any error, close the data handler components
	if (myErr != noErr)
		QTDR_CloseDownHandlers();
	
	return((OSErr)myErr);
}
Beispiel #6
0
OSErr NetDDPOpenSocket(
    short *socketNumber,
    packetHandlerProcPtr packetHandler)
{
    OSErr     error;
    Handle    socket_listener_resource;
    ProcPtr   initialize_socket_listener, socket_listener;
    MPPPBPtr  myMPPPBPtr= (MPPPBPtr) NewPtrClear(sizeof(MPPParamBlock));

    static ProcPtr           initialize_upp = NULL;
    static UniversalProcPtr  packet_handler_upp = NULL;

    assert(packetHandler); /* canÕt have NULL packet handlers */
    assert(!ddpPacketBuffer); /* canÕt have more than one socket listener installed */

    socket_listener_resource = GetResource(SOCKET_LISTENER_RESOURCE_TYPE, SOCKET_LISTENER_ID);
    assert(socket_listener_resource);
    HLock(socket_listener_resource);
    HNoPurge(socket_listener_resource);

    initialize_socket_listener = (ProcPtr) StripAddress(*socket_listener_resource);

    ddpPacketBuffer= (DDPPacketBufferPtr) NewPtrClear(sizeof(DDPPacketBuffer));

    error= MemError();
    if (error==noErr)
    {
        if (packet_handler_upp == NULL)
        {
            packet_handler_upp = (UniversalProcPtr) NewRoutineDescriptor((ProcPtr) packetHandler,
                                 uppPacketHandlerProcInfo, GetCurrentISA());
        }
        assert(packet_handler_upp);

        if (initialize_upp == NULL)
        {
            initialize_upp = (ProcPtr) NewRoutineDescriptor((ProcPtr) initialize_socket_listener,
                             uppInitializeListenerProcInfo, kM68kISA); // it's in a 68k code resource
        }
        assert(initialize_upp);

#ifdef env68k  // it seems that we don't have CallUniversalProc() in the library. strange...
#ifndef VULCAN

        socket_listener = (ProcPtr) initialize_socket_listener(packet_handler_upp,
                          ddpPacketBuffer, 1);
#else
        debugstr("Hey, socket listener was never initialized");
#endif
#else
        socket_listener = (ProcPtr) CallUniversalProc((UniversalProcPtr) initialize_upp, uppInitializeListenerProcInfo,
                          packet_handler_upp, ddpPacketBuffer, 1);
#endif

        listenerUPP = (DDPSocketListenerUPP) NewRoutineDescriptor((ProcPtr) socket_listener, uppDDPSocketListenerProcInfo,
                      kM68kISA); // have to force it to realize that it's a 68K resource
        assert(listenerUPP);

        myMPPPBPtr->DDP.socket= 0;
        myMPPPBPtr->DDP.u.listener= listenerUPP;

        error= POpenSkt(myMPPPBPtr, FALSE);
        if (error==noErr)
        {
            *socketNumber= myMPPPBPtr->DDP.socket;
        }

        DisposePtr((Ptr)myMPPPBPtr);
    }

    return error;
}
Beispiel #7
0
pascal	OSErr	FSpGetFullPath(const FSSpec *spec,
							   short *fullPathLength,
							   Handle *fullPath)
{
	OSErr		result;
	OSErr		realResult;
	FSSpec		tempSpec;
	CInfoPBRec	pb;
	
	*fullPathLength = 0;
	*fullPath = NULL;
	
	
	/* Default to noErr */
	realResult = result = noErr;
	
	/* work around Nav Services "bug" (it returns invalid FSSpecs with empty names) */
	if ( spec->name[0] == 0 )
	{
		result = FSMakeFSSpecCompat(spec->vRefNum, spec->parID, spec->name, &tempSpec);
	}
	else
	{
		/* Make a copy of the input FSSpec that can be modified */
		BlockMoveData(spec, &tempSpec, sizeof(FSSpec));
	}
	
	if ( result == noErr )
	{
		if ( tempSpec.parID == fsRtParID )
		{
			/* The object is a volume */
			
			/* Add a colon to make it a full pathname */
			++tempSpec.name[0];
			tempSpec.name[tempSpec.name[0]] = ':';
			
			/* We're done */
			result = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]);
		}
		else
		{
			/* The object isn't a volume */
			
			/* Is the object a file or a directory? */
			pb.dirInfo.ioNamePtr = tempSpec.name;
			pb.dirInfo.ioVRefNum = tempSpec.vRefNum;
			pb.dirInfo.ioDrDirID = tempSpec.parID;
			pb.dirInfo.ioFDirIndex = 0;
			result = PBGetCatInfoSync(&pb);
			/* Allow file/directory name at end of path to not exist. */
			realResult = result;
			if ( (result == noErr) || (result == fnfErr) )
			{
				/* if the object is a directory, append a colon so full pathname ends with colon */
				if ( (result == noErr) && (pb.hFileInfo.ioFlAttrib & kioFlAttribDirMask) != 0 )
				{
					++tempSpec.name[0];
					tempSpec.name[tempSpec.name[0]] = ':';
				}
				
				/* Put the object name in first */
				result = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]);
				if ( result == noErr )
				{
					/* Get the ancestor directory names */
					pb.dirInfo.ioNamePtr = tempSpec.name;
					pb.dirInfo.ioVRefNum = tempSpec.vRefNum;
					pb.dirInfo.ioDrParID = tempSpec.parID;
					do	/* loop until we have an error or find the root directory */
					{
						pb.dirInfo.ioFDirIndex = -1;
						pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID;
						result = PBGetCatInfoSync(&pb);
						if ( result == noErr )
						{
							/* Append colon to directory name */
							++tempSpec.name[0];
							tempSpec.name[tempSpec.name[0]] = ':';
							
							/* Add directory name to beginning of fullPath */
							(void) Munger(*fullPath, 0, NULL, 0, &tempSpec.name[1], tempSpec.name[0]);
							result = MemError();
						}
					} while ( (result == noErr) && (pb.dirInfo.ioDrDirID != fsRtDirID) );
				}
			}
		}
	}
	
	if ( result == noErr )
	{
		/* Return the length */
		*fullPathLength = GetHandleSize(*fullPath);
		result = realResult;	/* return realResult in case it was fnfErr */
	}
	else
	{
		/* Dispose of the handle and return NULL and zero length */
		if ( *fullPath != NULL )
		{
			DisposeHandle(*fullPath);
		}
		*fullPath = NULL;
		*fullPathLength = 0;
	}
	
	return ( result );
}
extern pascal OSStatus InsertSystemSubMenu(MenuRef rootMenu,
										MenuRef parentMenu, UInt16 itemInParent, MenuRef childMenu)
	// See comment in interface part.
{
	long oldA4;
	OSStatus err;
	SubSysMenuEntry newEntry;
	SInt16 newIDForChildMenu;
	
	oldA4 = SetUpA4();

	assert(ValidateSystemMenuRef(rootMenu  ));
	assert(ValidateSystemMenuRef(parentMenu));
	assert(ValidateSystemMenuRef(childMenu ));
	
	assert(gMenuSelectState = kMenuSelectStatePre);
	
	// Validate parameters
	
	err = noErr;
	if ((rootMenu == NULL) || (parentMenu == NULL) || (childMenu == NULL)) {
		err = paramErr;
	}
	if (err == noErr && ((itemInParent == 0) || (itemInParent > CountMenuItems(parentMenu)))) {
		err = paramErr;
	}

	// Make sure rootMenu references a current system menu.
	// If it does, record the index of the root menu for
	// later use by HandleMenuSelect.  Also fill out the rest
	// of the fields of the sub-menu entry.

	if (err == noErr) {
		newEntry.rootMenuIndex = FindRootMenuByRef(rootMenu);
		newEntry.parentMenu    = parentMenu;
		newEntry.itemInParent  = itemInParent;
		newEntry.childMenu     = childMenu;
		
		if (newEntry.rootMenuIndex == kRootMenuNotFound) {
			err = paramErr;
		}
	}
	
	// Add newEntry to the sub-menu list, creating the sub-menu list if necessary.

	if (err == noErr) {
		if (gSubSysMenus == NULL) {
			gSubSysMenus = (SubSysMenuHandle) NewHandleSys(0);
			err = MemError();
		}
	}
	if (err == noErr) {
		err = PtrAndHand(&newEntry, (Handle) gSubSysMenus, sizeof(newEntry));
	}
	
	// Finally, insert the menu with a unique ID into the menu bar,
	// and set the parent item to reference its ID.
	
	if (err == noErr) {
		newIDForChildMenu = FindUniqueSubMenuID();
		(**childMenu).menuID = newIDForChildMenu;
		InsertMenu(childMenu, hierMenu);

		SetItemCmd(parentMenu, itemInParent, hMenuCmd);
		SetItemMark(parentMenu, itemInParent, newIDForChildMenu);
		
		// I added this after testing revealed that adding a sub-menu didn't 
		// force the menu size to be recalculated, so the item text of the
		// hierarchical item in the sub-menu was being truncated.  This
		// only appears to happen on Mac OS 8.5, but the fix is sufficiently
		// benign to be employed on all systems.
		
		CalcMenuSize(parentMenu);
	}
	
	(void) SetA4(oldA4);
	
	return err;
}
Beispiel #9
0
TQ3Status
E3CompressedPixmapTexture_CompressImage(TQ3CompressedPixmap *	compressedPixmap, 
										PixMapHandle 			sourcePixMap, 
										CodecType				codecType, 
										CodecComponent			codecComponent, 
										TQ3Int16				codedDepth, 
										CodecQ					codecQuality)
{


	// If we support QuickTime, compress the image
	ImageDescriptionHandle	imageDescH 			= NULL;
	long					maxCompressedSize	= 0;
	Handle					compressedDataH		= NULL;
	Ptr						compressedDataP		= NULL;
	OSErr					theErr				= noErr;
	Rect 					bounds				= (**sourcePixMap).bounds;
	TQ3StorageObject		compressedImage		= NULL;
	TQ3StorageObject		imageDesc			= NULL;



	// Make sure QuickTime is present
	if ((TQ3Uns32) EnterMovies == (TQ3Uns32) kUnresolvedCFragSymbolAddress)
		return(kQ3Failure);



	theErr = GetMaxCompressionSize(	sourcePixMap,
									&bounds, 
									codedDepth,
									codecQuality,
									codecType,
									(CompressorComponent)codecComponent,
									&maxCompressedSize);
									
	if ( theErr != noErr ) 
	{
		// paramErr or noCodecErr
		E3ErrorManager_PostError( kQ3ErrorInvalidParameter, kQ3False ) ;
		
		// failure
		return(kQ3Failure);
	}
	
	// allocate memory - we need to use Mac OS Handles for QuickTime
	imageDescH		= (ImageDescriptionHandle) NewHandle( 4 );
	compressedDataH = NewHandle( maxCompressedSize );
	
	if ( compressedDataH != NULL && imageDescH != NULL )
	{
		HLock(compressedDataH);
		compressedDataP = *compressedDataH;
	
		theErr = FCompressImage(sourcePixMap,
								&bounds,
								codedDepth,
								codecQuality,
								codecType,
								(CompressorComponent) codecComponent,
								NULL,
								0,
								0,
								NULL,
								NULL,
								imageDescH,
								compressedDataP);
		
		if ( theErr != noErr )
		{
			// post error
			if (MemError() !=  noErr)
				E3ErrorManager_PostError( kQ3ErrorOutOfMemory , kQ3False ) ;
			else
				E3ErrorManager_PostError( kQ3ErrorInvalidParameter , kQ3False ) ;

			//deallocate  handle storage
			DisposeHandle( (Handle)imageDescH);
			DisposeHandle( compressedDataH);
			
			// failure
			return(kQ3Failure) ;			
		}
		
	}
	// otherwise we have a memory error
	else
	{
		// deallocate handle storage
		if (imageDescH) 
			DisposeHandle( (Handle)imageDescH);
		if (compressedDataH) 
			DisposeHandle( compressedDataH);
		
		// post error
		E3ErrorManager_PostError( kQ3ErrorOutOfMemory , kQ3False ) ;
		
		//failure
		return( kQ3Failure) ;
		
	}
	
	
	if (imageDescH) 
		DisposeHandle( (Handle)imageDescH);
	if (compressedDataH) 
		DisposeHandle( compressedDataH);
	
	// lock the image desc handle
	HLock( (Handle) imageDescH ) ;
		
	// store the data in storage objects
	compressedImage = Q3MemoryStorage_New(	(unsigned char *) compressedDataP, 
											(TQ3Uns32)        (**imageDescH).dataSize ) ;
	imageDesc		= Q3MemoryStorage_New( 	(unsigned char *) imageDescH, 
											(TQ3Uns32)        (**imageDescH).idSize ) ;
	
		
	// make sure memory was allocated
	if( compressedImage == NULL && imageDesc == NULL )
	{
		if( compressedImage != NULL )
			Q3Object_Dispose( compressedImage ) ;
		if( imageDesc != NULL )
			Q3Object_Dispose( imageDesc ) ;
				
		// deallocate handle storage
		DisposeHandle( (Handle) imageDescH ) ;
		DisposeHandle( compressedDataH ) ;
		
		// we don't need to post a memory error because it
		// has already been done, return failure
		return(kQ3Failure);
	}
	
	
	// store the data in the compressed pixmap structure
	E3Shared_Acquire(&compressedPixmap->compressedImage, compressedImage);
	E3Shared_Acquire(&compressedPixmap->imageDesc,       imageDesc);
	
	// NOTE: we do not fill out the other fields of the data structure,
	// since this is the defined QD3D behaviour
	
	// deallocate handle storage
	DisposeHandle( (Handle) imageDescH ) ;
	DisposeHandle( compressedDataH ) ;
	
	return(kQ3Success) ;
}
static pascal SInt32 MenuSelectPatch(Point startPt)
	// This is our patch on MenuSelect.  The basic idea is to
	// call our clients to let them adjust their menus (and install
	// sub-menus by calling InsertSystemMenu), call through to
	// the old trap, call our clients to un-adjust their menus,
	// and then call HandleMenuSelect to see whether the chosen
	// menu was one of our system menus.  If it was, HandleMenuSelect
	// calls the client to tell them that their menu was chosen and
	// returns 0 so that we tell the host application that nothing
	// happened.
	//
	// Note that MenuSelect is called by MenuEvent, so this patch
	// covers that case as well.
{
	long oldA4;
	SInt32 result;
	SubSysMenuHandle tempSubSysMenus;
	
	oldA4 = SetUpA4();
	
	// Our patch should only be installed if InitMoreSystemMenus was successful.
	assert(gRootSysMenus != NULL);

	// Only do stuff if we're actually up and running.
	// If gHaveInsertedRootSysMenus is false, it means that
	// someone is calling MenuSelect before our InsertMenu patch
	// has run, ie before anyone has inserted any system menus,
	// ie before the Process Manager has launched.  I don't know
	// whether this ever happens, I'm use being cautious.
	
	// Also, if gMenuSelectState is not NULL then we're getting recursion
	// where we're not expecting it (probably from the kSystemMenuPreSelectAdjust
	// or kSystemMenuPostSelectAdjust callbacks, but possibly from another
	// trap patch), so we just call through to the system in that case.
	
	// We want debug versions to tell the client that they're recursing
	// in an unsupport fashion.
	
	assert(gMenuSelectState == kMenuSelectStateNil);
	
	if ( gHaveInsertedRootSysMenus && gMenuSelectState == kMenuSelectStateNil) {
	
		// OK, so we're up and running, so let's do our stuff.
		
		// First tell all clients that we're about to do a MenuSelect
		// (they can adjust their menus and insert sub-menus)...
		
		assert(gSubSysMenus == NULL);
		gMenuSelectState = kMenuSelectStatePre;
		CallAllClients(kSystemMenuPreSelectAdjust, NULL);
		
		// ... then call through to the old trap address...
		
		result = CallMenuSelectProc(gMenuSelectOldUPP, startPt);
		
		// ... and then tell all clients that we're done...
		
		gMenuSelectState = kMenuSelectStatePost;
		CallAllClients(kSystemMenuPostSelectAdjust, NULL);
		
		// Things get tricky here.  In order to allow the client
		// to post modal dialogs from its kSystemMenuActOnChosen callback,
		// we must be re-entrant at the time we call HandleMenuSelect
		// (because the ModalDialog routine will call MenuSelect).
		// But we want to avoid having sub-menus in the menu bar when
		// we're recursively called because we're going to call the
		// client's kSystemMenuPreSelectAdjust callback, which will
		// attempt to re-insert those menus.
		//
		// So, we remove our sub-menus now, before calling the
		// kSystemMenuActOnChosen callback, then we make the callback,
		// and then we dispose of the memory we used to track the
		// sub-menus.
		
		tempSubSysMenus = gSubSysMenus;
		gSubSysMenus = NULL;
		
		DeleteSubMenus(tempSubSysMenus);

		gMenuSelectState = kMenuSelectStateNil;

		// At this point we're prepared to accept recursion.
		// Call HandleMenuSelect to process the results
		// from the menu operation and call the appropriate
		// client if it was one of our menus.
		
		result = HandleMenuSelect(result, tempSubSysMenus);

		// Clean up.  If we created any sub-menu info,
		// dispose of it.
		
		if (tempSubSysMenus != NULL) {
			DisposeHandle( (Handle) tempSubSysMenus);
			assert(MemError() == noErr);
		}
	} else {
		result = CallMenuSelectProc(gMenuSelectOldUPP, startPt);
	}

	assert(gMenuSelectState == kMenuSelectStateNil);

	(void) SetA4(oldA4);
	
	return result;
}
extern pascal OSStatus InitMoreSystemMenus(void)
	// See comment in interface part.
{
	OSStatus err;
	UniversalProcPtr gMenuSelectPatchUPP;		// points to MenuSelectPatch
	UniversalProcPtr gInsertMenuPatchUPP;		// points to InsertMenuPatch
	
	// We need to use the callback routine SetUpA4 to set up
	// A4 in our trap patches.  In preparation for that, we
	// need to remember A4 in some PC-relative place.  The client
	// may have already done this, but doing it twice doesn't hurt.
	//
	// Note that this translates to a NOP for the CFM build.
	
	RememberA4();
	
	assert(IsSystemStartup());
	
	// To avoid allocating extra pointer blocks for each of our
	// routine descriptors, we just declare them statically
	// here, and then setup the gFooUPP pointers to point to
	// them.
	//
	// Of course, for the classic 68K case, we can just use
	// assign them directly.
	
	// Build our routine descriptors.
	
	#if TARGET_RT_MAC_CFM
		{
			static RoutineDescriptor gDetachIconActionRD = BUILD_ROUTINE_DESCRIPTOR(uppIconActionProcInfo, DetachIconAction);
			static RoutineDescriptor gMenuSelectPatchRD = BUILD_ROUTINE_DESCRIPTOR(uppMenuSelectProcInfo, MenuSelectPatch);
			static RoutineDescriptor gInsertMenuPatchRD = BUILD_ROUTINE_DESCRIPTOR(uppInsertMenuProcInfo, InsertMenuPatch);
			gDetachIconActionUPP = &gDetachIconActionRD;
			gMenuSelectPatchUPP = &gMenuSelectPatchRD;
			gInsertMenuPatchUPP = &gInsertMenuPatchRD;
		}
	#else
		gDetachIconActionUPP = (IconActionUPP)    DetachIconAction;
		gMenuSelectPatchUPP  = (UniversalProcPtr) MenuSelectPatch;
		gInsertMenuPatchUPP  = (UniversalProcPtr) InsertMenuPatch;
	#endif
	
	// Setup our global state.
	
	gMenuSelectState = kMenuSelectStateNil;
	gRootSysMenus = (RootSysMenuHandle) NewHandleSys(0);
	err = MemError();

	// If all goes well, install our patches.
	
	if (err == noErr) {
		gMenuSelectOldUPP = GetToolboxTrapAddress(_MenuSelect);
		gInsertMenuOldUPP = GetToolboxTrapAddress(_InsertMenu);

		SetToolboxTrapAddress(gMenuSelectPatchUPP, _MenuSelect);
		SetToolboxTrapAddress(gInsertMenuPatchUPP, _InsertMenu);
	}
	
	return err;
}
Beispiel #12
0
inline short memory_error() {return MemError();}
Beispiel #13
0
struct servent *getservent(void)
{
	static int	preferedProto = 0;
	OSStatus	err;
	long		len;
	ICAttr		attr;
	ICServices	*buf;
	ICServiceEntry tmpICSvc; /* We use this to store an aligned copy of *curSvc. */
	static ICServiceEntry *curICSvc = NULL;
	static struct servent svc = {NULL, NULL, 0, NULL};
  
	ncbi_ClearErrno(); 
  
	// Deallocate the last service name we returned.
	if (svc.s_name!=NULL)
	{
		free(svc.s_name);
		svc.s_name=NULL;
	}
  
	// If we haven't loaded the service table, load it now.
	if (gServices==NULL)
	{
		err=ICStart(&gConfig, 'Sock');
		if (err) {
			ncbi_SetOTErrno(err); 
			return NULL; 
		}
#if !TARGET_API_MAC_CARBON
	// Need to #ifdef this out for Carbon builds
		err=ICFindConfigFile(gConfig, 0, nil);
		if (err) { 
			ncbi_SetOTErrno(err);
			return NULL;
		}
	// End of #ifdef for Carbon
#endif

		len = 0;
		err = ICGetPref(gConfig, kICServices, &attr, NULL, &len);
		if (err) { 
			ncbi_SetOTErrno(err);
			return NULL;
		}
		buf=(ICServices*)NewPtr(len);
		if (buf==NULL || MemError()!=noErr) {
			ncbi_SetOTErrno(MemError());
			return NULL;
		}
		err=ICGetPref(gConfig, kICServices, &attr, (char*)buf, &len);
		if (err){
			ncbi_SetOTErrno(err);
			return NULL;
		}

		gServices=buf;
		curICSvc=&gServices->services[0];
		gServiceIndex=0;
	}
  
	/* If we are out of entries, return NULL. */
	if (curICSvc==NULL || gServiceIndex>=gServices->count)  return NULL;
  
	/* gServices is "packed", which means we cannot directly index gServices->services.
	 * So, we have to manually increment the current record pointer.  We also have to
	 * memmove any numbers into an aligned variable, because entries in gServices are
	 * not guaranteed to be on whatever boundary the current processor prefers. 
	 */

	/* Make an aligned copy of *curICSvc */
	memmove(tmpICSvc.name, curICSvc, ((char*)curICSvc)[0]+1);
	memmove(&tmpICSvc.port, (char*)curICSvc+((char*)curICSvc)[0]+1, 2);
	memmove(&tmpICSvc.flags, (char*)curICSvc+((char*)curICSvc)[0]+3, 2);

	/* Put together a servent based on the current service table entry. */
	len = tmpICSvc.name[0]+1;
	svc.s_name = malloc(len);
	if (svc.s_name == NULL) { 
		ncbi_SetOTErrno(memFullErr); 
		return NULL;
	}
	//memmove(svc.s_name, tmpICSvc.name, len);
	//p2cstr((StringPtr)svc.s_name);
	p2cstrcpy(svc.s_name, tmpICSvc.name);

	svc.s_aliases=(char**)&not_an_alias;

	svc.s_port=tmpICSvc.port;

	switch(preferedProto){
		case 0:
			switch(tmpICSvc.flags){
				case 0:
					svc.s_proto=(char*)prot_none;
					break;
				case kICServicesUDPMask:
					svc.s_proto=(char*)prot_udp;
					break;
				case kICServicesTCPMask:
					svc.s_proto=(char*)prot_tcp;
					break;
				case 3:
					svc.s_proto=(char*)prot_udp;
					preferedProto=kICServicesTCPMask;
					break;
			}
			break;
		case kICServicesUDPMask:
			svc.s_proto=(char*)prot_udp;      
			preferedProto=0;
			break;
		case kICServicesTCPMask:
			svc.s_proto=(char*)prot_tcp;
			preferedProto=0;
			break;
		default:
			// Assert_(0); /* We have set a preferedProto that we don't support. */
			break;
	}

	if (preferedProto==0){
		if ((++gServiceIndex)<gServices->count){
			/* Cast gCurrentService to char* so we can play pointer arithmetic games in
			 * byte-sized increments. The 5 is the length byte plus two 2-byte ints.
			 */
			curICSvc=(ICServiceEntry*)((char*)curICSvc+((char*)curICSvc)[0]+5);
		}
		else {
			curICSvc=NULL;
		}
	}
  
  return &svc;  
}
Beispiel #14
0
void MacQTStartRecording(char *path)
{
	OSStatus	err;
	CFStringRef str;
	CFURLRef	url;

	memset(&sqt, 0, sizeof(sqt));

	// storage

	str = CFStringCreateWithCString(kCFAllocatorDefault, path, MAC_PATH_ENCODING);
	url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, str, kCFURLPOSIXPathStyle, false);
	err = QTNewDataReferenceFromCFURL(url, 0, &(sqt.dataRef), &(sqt.dataRefType));
	CheckError(err, 21);
	CFRelease(url);
	CFRelease(str);
	
	err = CreateMovieStorage(sqt.dataRef, sqt.dataRefType, 'TVOD', smSystemScript, createMovieFileDeleteCurFile | newMovieActive, &(sqt.dataHandler), &(sqt.movie));
	CheckError(err, 22);
	
	// video

	MacQTOpenVideoComponent(&(sqt.vci));
	
	SCTemporalSettings	ts;

	err = SCGetInfo(sqt.vci, scTemporalSettingsType, &ts);
	ts.frameRate = FixRatio(Memory.ROMFramesPerSecond, 1);
	if (ts.keyFrameRate < 1)
		ts.keyFrameRate = Memory.ROMFramesPerSecond;
	sqt.keyFrame  = sqt.keyFrameCount  = ts.keyFrameRate;
	sqt.frameSkip = sqt.frameSkipCount = (macQTMovFlag & 0xFF00) >> 8;
	err = SCSetInfo(sqt.vci, scTemporalSettingsType, &ts);

	sqt.frame.top    = 0;
	sqt.frame.left   = 0;
	sqt.frame.right  = ((macQTMovFlag & kMovDoubleSize) ? 2 : 1) * SNES_WIDTH;
	sqt.frame.bottom = ((macQTMovFlag & kMovDoubleSize) ? 2 : 1) * ((macQTMovFlag & kMovExtendedHeight) ? SNES_HEIGHT_EXTENDED : SNES_HEIGHT);

	sqt.pw = sqt.ph = 0;
	sqt.firstFrame = true;
	
	Rect	rct;

	SetRect(&rct, 0, 0, SNES_WIDTH * 2, SNES_HEIGHT_EXTENDED * 2 + 4);
	InitGWorld(&(sqt.bw), &rct, 16);

	sqt.vTrack = NewMovieTrack(sqt.movie, FixRatio(sqt.frame.right, 1), FixRatio(sqt.frame.bottom, 1), kNoVolume);
	CheckError(GetMoviesError(), 23);
	
	sqt.vMedia = NewTrackMedia(sqt.vTrack, VideoMediaType, Memory.ROMFramesPerSecond, nil, 0);
	CheckError(GetMoviesError(), 24);
	
	err = BeginMediaEdits(sqt.vMedia);
	CheckError(err, 25);
	
	// sound
	
	sqt.soundDesc = (SoundDescriptionHandle) NewHandleClear(sizeof(SoundDescription));
	CheckError(MemError(), 26);

	(**sqt.soundDesc).descSize    = sizeof(SoundDescription);
#ifdef __BIG_ENDIAN__
	(**sqt.soundDesc).dataFormat  = Settings.SixteenBitSound ? k16BitBigEndianFormat    : k8BitOffsetBinaryFormat;
#else
	(**sqt.soundDesc).dataFormat  = Settings.SixteenBitSound ? k16BitLittleEndianFormat : k8BitOffsetBinaryFormat;
#endif
	(**sqt.soundDesc).numChannels = Settings.Stereo ? 2 : 1;
	(**sqt.soundDesc).sampleSize  = Settings.SixteenBitSound ? 16 : 8;
	(**sqt.soundDesc).sampleRate  = (UnsignedFixed) FixRatio(Settings.SoundPlaybackRate, 1);
	
	sqt.samplesPerSec = Settings.SoundPlaybackRate / Memory.ROMFramesPerSecond;
	
	sqt.soundBufferSize = sqt.samplesPerSec;
	if (Settings.SixteenBitSound)
		sqt.soundBufferSize <<= 1;
	if (Settings.Stereo)
		sqt.soundBufferSize <<= 1;

	sqt.soundBuffer = NewHandleClear(sqt.soundBufferSize);
	CheckError(MemError(), 27);
	HLock(sqt.soundBuffer);
	
	sqt.sTrack = NewMovieTrack(sqt.movie, 0, 0, kFullVolume);
	CheckError(GetMoviesError(), 28);

	sqt.sMedia = NewTrackMedia(sqt.sTrack, SoundMediaType, Settings.SoundPlaybackRate, nil, 0);
	CheckError(GetMoviesError(), 29);

	err = BeginMediaEdits(sqt.sMedia);
	CheckError(err, 30);
}
Beispiel #15
0
static OSStatus SetupSectionBaseAddresses(FragToFixInfo *fragToFix)
	// This routine initialises the section0Base and section1Base
	// base fields of fragToFix to the base addresses of the
	// instantiated fragment represented by the other fields
	// of fragToFix.  The process works in three states:
	//
	// 1. 	Find the contents of the relocated TVector of the 
	//      fragment's initialisation routine, provided to us by 
	//      the caller.
	//
	// 2.	Find the contents of the non-relocated TVector by 
	//      looking it up in the PEF loader info header and then 
	//      using that to read the TVector contents from disk.
	//      This yields the offsets from the section bases for 
	//      the init routine.
	//
	// 3.	Subtract 2 from 3.
{
	OSStatus 			err;
	TVector *			relocatedExport;
	SInt32				initSection;
	UInt32				initOffset;
	PEFSectionHeader *	initSectionHeader;
	Ptr					packedDataSection;
	Ptr					unpackedDataSection;
	TVector 			originalOffsets;

	packedDataSection   = nil;
	unpackedDataSection = nil;
	
	// Step 1.

	// First find the init routine's TVector, which gives us the relocated 
	// offsets of the init routine into the data and code sections.

	relocatedExport = (TVector *) fragToFix->initRoutine;
		
	// Step 2.
	
	// Now find the init routine's TVector's offsets in the data section on 
	// disk.  This gives us the raw offsets from the data and code section 
	// of the beginning of the init routine.
	
	err = noErr;
	initSection = fragToFix->loaderSection->initSection;
	initOffset  = fragToFix->loaderSection->initOffset;
	if (initSection == -1) {
		err = cfragFragmentUsageErr;
	}
	if (err == noErr) {
		MoreAssertQ( initSection >= 0 );		// Negative indexes are pseudo-sections which are just not allowed!
		MoreAssertQ( initSection < fragToFix->containerHeader.sectionCount );

		initSectionHeader = &fragToFix->sectionHeaders[initSection];
		
		// If the data section is packed, unpack it to a temporary buffer and then get the 
		// original offsets from that buffer.  If the data section is unpacked, just read 
		// the original offsets directly off the disk.
		
		if ( initSectionHeader->sectionKind == kPEFPackedDataSection ) {

			// Allocate space for packed and unpacked copies of the section.
			
			packedDataSection = NewPtr(initSectionHeader->containerLength);
			err = MemError();

			if (err == noErr) {
				unpackedDataSection = NewPtr(initSectionHeader->unpackedLength);
				err = MemError();
			}

			// Read the contents of the packed section.
			
			if (err == noErr) {
				err = FSReadAtOffset(	fragToFix->fileRef,
										fragToFix->locator.offset
										+ initSectionHeader->containerOffset,
										initSectionHeader->containerLength,
										packedDataSection);
			}
			
			// Unpack the data into the unpacked section.
			
			if (err == noErr) {
				err = UnpackPEFDataSection( (UInt8 *) packedDataSection,   initSectionHeader->containerLength,
								            (UInt8 *) unpackedDataSection, initSectionHeader->unpackedLength);
			}
			
			// Extract the init routine's TVector from the unpacked section.
			
			if (err == noErr) {
				BlockMoveData(unpackedDataSection + initOffset, &originalOffsets, sizeof(TVector));
			}
			
		} else {
			MoreAssertQ(fragToFix->sectionHeaders[initSection].sectionKind == kPEFUnpackedDataSection);
			err = FSReadAtOffset(fragToFix->fileRef, 
									fragToFix->locator.offset
									+ fragToFix->sectionHeaders[initSection].containerOffset
									+ initOffset,
									sizeof(TVector), 
									&originalOffsets);
		}
	}

	// Step 3.
		
	// Do the maths to subtract the unrelocated offsets from the current address 
	// to get the base address.
	
	if (err == noErr) {
		fragToFix->section0Base = ((char *) relocatedExport->codePtr) - (UInt32) originalOffsets.codePtr;
		fragToFix->section1Base = ((char *) relocatedExport->tocPtr)  - (UInt32) originalOffsets.tocPtr;
	}
	
	// Clean up.
	
	if (packedDataSection != nil) {
		DisposePtr(packedDataSection);
		MoreAssertQ( MemError() == noErr );
	}
	if (unpackedDataSection != nil) {
		DisposePtr(unpackedDataSection);
		MoreAssertQ( MemError() == noErr );
	}
	return err;
}
Beispiel #16
0
static OSStatus ReadContainerBasics(FragToFixInfo *fragToFix)
	// Reads some basic information from the container of the
	// fragment to fix and stores it in various fields of
	// fragToFix.  This includes:
	//
	// o containerHeader -- The contain header itself.
	// o sectionHeaders  -- The array of section headers (in a newly allocated pointer block).
	// o loaderSection   -- The entire loader section (in a newly allocated pointer block).
	//
	// Also sets disposeSectionPointers to indicate whether
	// the last two pointers should be disposed of.
	//
	// Finally, it leaves the container file open for later
	// folks who want to read data from it.
{
	OSStatus 	err;
	UInt16 		sectionIndex;
	Boolean 	found;

	MoreAssertQ(fragToFix != nil);
	MoreAssertQ(fragToFix->locator.fileSpec != nil);
	MoreAssertQ(fragToFix->connID != nil);
	MoreAssertQ(fragToFix->loaderSection == nil);
	MoreAssertQ(fragToFix->sectionHeaders == nil);
	MoreAssertQ(fragToFix->fileRef == 0);
	
	fragToFix->disposeSectionPointers = true;
	
	// Open up the file, read the container head, then read in
	// all the section headers, then go looking through the
	// section headers for the loader section (PEF defines
	// that there can be only one).
	
	err = FSpOpenDF(fragToFix->locator.fileSpec, fsRdPerm, &fragToFix->fileRef);
	if (err == noErr) {
		err = FSReadAtOffset(fragToFix->fileRef,
								fragToFix->locator.offset,
								sizeof(fragToFix->containerHeader),
								&fragToFix->containerHeader);
		if (err == noErr) {
			if (   fragToFix->containerHeader.tag1 != kPEFTag1
				|| fragToFix->containerHeader.tag2 != kPEFTag2
				|| fragToFix->containerHeader.architecture != kCompiledCFragArch
				|| fragToFix->containerHeader.formatVersion != kPEFVersion) {
				err = cfragFragmentFormatErr;
			}
		}
		if (err == noErr) {
			fragToFix->sectionHeaders = (PEFSectionHeader *) NewPtr(fragToFix->containerHeader.sectionCount * sizeof(PEFSectionHeader));
			err = MemError();
		}
		if (err == noErr) {
			err = FSReadAtOffset(fragToFix->fileRef,
									fragToFix->locator.offset + sizeof(fragToFix->containerHeader),
									fragToFix->containerHeader.sectionCount * sizeof(PEFSectionHeader), 
									fragToFix->sectionHeaders);
		}
		if (err == noErr) {
			sectionIndex = 0;
			found = false;
			while ( sectionIndex < fragToFix->containerHeader.sectionCount && ! found ) {
				found = (fragToFix->sectionHeaders[sectionIndex].sectionKind == kPEFLoaderSection);
				if ( ! found ) {
					sectionIndex += 1;
				}
			}
		}
		if (err == noErr && ! found) {
			err = cfragNoSectionErr;
		}
		
		// Now read allocate a pointer block and read the loader section into it.
		
		if (err == noErr) {
			fragToFix->loaderSection = (PEFLoaderInfoHeader *) NewPtr(fragToFix->sectionHeaders[sectionIndex].containerLength);
			err = MemError();
		}
		if (err == noErr) {
			err = FSReadAtOffset(fragToFix->fileRef, 
									fragToFix->locator.offset + fragToFix->sectionHeaders[sectionIndex].containerOffset,
									fragToFix->sectionHeaders[sectionIndex].containerLength, 
									fragToFix->loaderSection);
		}				
	}
	
	// No clean up.  The client must init fragToFix to zeros and then
	// clean up regardless of whether we return an error.
		
	return err;
}