wine/dlls/wineqtdecoder/qtdatahandler.c
2012-08-13 11:46:20 +02:00

794 lines
30 KiB
C

/*
* QuickTime Data Handler
*
* Copyright 2011 Aric Stewart for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#define ULONG CoreFoundation_ULONG
#define HRESULT CoreFoundation_HRESULT
#define LoadResource __carbon_LoadResource
#define CompareString __carbon_CompareString
#define GetCurrentThread __carbon_GetCurrentThread
#define GetCurrentProcess __carbon_GetCurrentProcess
#define AnimatePalette __carbon_AnimatePalette
#define EqualRgn __carbon_EqualRgn
#define FillRgn __carbon_FillRgn
#define FrameRgn __carbon_FrameRgn
#define GetPixel __carbon_GetPixel
#define InvertRgn __carbon_InvertRgn
#define LineTo __carbon_LineTo
#define OffsetRgn __carbon_OffsetRgn
#define PaintRgn __carbon_PaintRgn
#define Polygon __carbon_Polygon
#define ResizePalette __carbon_ResizePalette
#define SetRectRgn __carbon_SetRectRgn
#define CheckMenuItem __carbon_CheckMenuItem
#define DeleteMenu __carbon_DeleteMenu
#define DrawMenuBar __carbon_DrawMenuBar
#define EnableMenuItem __carbon_EnableMenuItem
#define EqualRect __carbon_EqualRect
#define FillRect __carbon_FillRect
#define FrameRect __carbon_FrameRect
#define GetCursor __carbon_GetCursor
#define GetMenu __carbon_GetMenu
#define InvertRect __carbon_InvertRect
#define IsWindowVisible __carbon_IsWindowVisible
#define MoveWindow __carbon_MoveWindow
#define OffsetRect __carbon_OffsetRect
#define PtInRect __carbon_PtInRect
#define SetCursor __carbon_SetCursor
#define SetRect __carbon_SetRect
#define ShowCursor __carbon_ShowCursor
#define ShowWindow __carbon_ShowWindow
#define UnionRect __carbon_UnionRect
#include <QuickTime/QuickTimeComponents.h>
#undef LoadResource
#undef CompareString
#undef GetCurrentThread
#undef _CDECL
#undef DPRINTF
#undef GetCurrentProcess
#undef AnimatePalette
#undef EqualRgn
#undef FillRgn
#undef FrameRgn
#undef GetPixel
#undef InvertRgn
#undef LineTo
#undef OffsetRgn
#undef PaintRgn
#undef Polygon
#undef ResizePalette
#undef SetRectRgn
#undef CheckMenuItem
#undef DeleteMenu
#undef DrawMenuBar
#undef EnableMenuItem
#undef EqualRect
#undef FillRect
#undef FrameRect
#undef GetCursor
#undef GetMenu
#undef InvertRect
#undef IsWindowVisible
#undef MoveWindow
#undef OffsetRect
#undef PtInRect
#undef SetCursor
#undef SetRect
#undef ShowCursor
#undef ShowWindow
#undef UnionRect
#undef ULONG
#undef HRESULT
#undef DPRINTF
#undef STDMETHODCALLTYPE
#include <assert.h>
#include <stdio.h>
#include <stdarg.h>
#define NONAMELESSSTRUCT
#define NONAMELESSUNION
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "wtypes.h"
#include "winuser.h"
#include "dshow.h"
#include "wine/unicode.h"
#include "wine/debug.h"
#include "qtprivate.h"
WINE_DEFAULT_DEBUG_CHANNEL(qtdatahandler);
static ComponentDescription myType =
{
'dhlr',
'WINE',
'WINE',
0,
0
};
typedef struct DHData
{
WineDataRefRecord dataRef;
Ptr AsyncPtr;
long AsyncRefCon;
DataHCompletionUPP AsyncCompletionRtn;
} DHData;
static pascal ComponentResult myComponentRoutineProc ( ComponentParameters *
cp, Handle componentStorage);
void RegisterWineDataHandler( void )
{
ComponentRoutineUPP MyComponentRoutineUPP;
MyComponentRoutineUPP = NewComponentRoutineUPP(&myComponentRoutineProc);
RegisterComponent( &myType , MyComponentRoutineUPP, 0, NULL, NULL, NULL);
}
static pascal ComponentResult myDataHCanUseDataRef ( DataHandler dh,
Handle dataRef,
long *useFlags
)
{
WineDataRefRecord *record = (WineDataRefRecord*)(*dataRef);
TRACE("%p %p %p\n",dh,dataRef,useFlags);
if (record->pReader == NULL)
return badComponentSelector;
*useFlags = kDataHCanRead;
return noErr;
}
static pascal ComponentResult myDataHSetDataRef ( DataHandler dh, Handle dataRef)
{
Handle storage = GetComponentInstanceStorage(dh);
DHData *data = (DHData*)*storage;
WineDataRefRecord* newRef = (WineDataRefRecord*)(*dataRef);
TRACE("\n");
if (newRef->pReader != data->dataRef.pReader)
IAsyncReader_AddRef(newRef->pReader);
data->dataRef = *newRef;
return noErr;
}
static pascal ComponentResult myDataHGetAvailableFileSize ( DataHandler dh,
long *fileSize)
{
Handle storage = GetComponentInstanceStorage(dh);
DHData *data = (DHData*)*storage;
LONGLONG total;
LONGLONG available;
TRACE("%p\n",dh);
IAsyncReader_Length(data->dataRef.pReader,&total,&available);
*fileSize = available;
return noErr;
}
static pascal ComponentResult myDataHGetFileSize ( DataHandler dh, long *fileSize)
{
Handle storage = GetComponentInstanceStorage(dh);
DHData *data = (DHData*)*storage;
LONGLONG total;
LONGLONG available;
TRACE("%p\n",dh);
IAsyncReader_Length(data->dataRef.pReader,&total,&available);
*fileSize = total;
return noErr;
}
static pascal ComponentResult myDataHScheduleData ( DataHandler dh,
Ptr PlaceToPutDataPtr,
long FileOffset,
long DataSize,
long RefCon,
DataHSchedulePtr scheduleRec,
DataHCompletionUPP CompletionRtn)
{
Handle storage = GetComponentInstanceStorage(dh);
DHData *data = (DHData*)*storage;
HRESULT hr;
LONGLONG offset = FileOffset;
BYTE* buffer = (BYTE*)PlaceToPutDataPtr;
TRACE("%p %p %li %li %li %p %p\n",dh, PlaceToPutDataPtr, FileOffset, DataSize, RefCon, scheduleRec, CompletionRtn);
hr = IAsyncReader_SyncRead(data->dataRef.pReader, offset, DataSize, buffer);
TRACE("result %x\n",hr);
if (CompletionRtn)
{
if (data->AsyncCompletionRtn)
InvokeDataHCompletionUPP(data->AsyncPtr, data->AsyncRefCon, noErr, data->AsyncCompletionRtn);
data->AsyncPtr = PlaceToPutDataPtr;
data->AsyncRefCon = RefCon;
data->AsyncCompletionRtn = CompletionRtn;
}
return noErr;
}
static pascal ComponentResult myDataHFinishData (DataHandler dh, Ptr PlaceToPutDataPtr, Boolean Cancel)
{
Handle storage = GetComponentInstanceStorage(dh);
DHData *data = (DHData*)*storage;
if (!data->AsyncCompletionRtn)
return noErr;
if (!PlaceToPutDataPtr || PlaceToPutDataPtr == data->AsyncPtr)
{
if (!Cancel)
InvokeDataHCompletionUPP(data->AsyncPtr, data->AsyncRefCon, noErr, data->AsyncCompletionRtn);
data->AsyncPtr = NULL;
data->AsyncRefCon = 0;
data->AsyncCompletionRtn = NULL;
}
return noErr;
}
static pascal ComponentResult myDataHGetData ( DataHandler dh,
Handle h,
long hOffset,
long offset,
long size)
{
Handle storage = GetComponentInstanceStorage(dh);
DHData *data = (DHData*)*storage;
BYTE *target = (BYTE*)*h;
LONGLONG off = offset;
HRESULT hr;
TRACE("%p %p %li %li %li\n",dh, h, hOffset, offset, size);
hr = IAsyncReader_SyncRead(data->dataRef.pReader, off, size, target+hOffset);
TRACE("result %x\n",hr);
return noErr;
}
static pascal ComponentResult myDataHCompareDataRef ( DataHandler dh,
Handle dataRef, Boolean *equal)
{
WineDataRefRecord *ptr1;
Handle storage = GetComponentInstanceStorage(dh);
DHData *data = (DHData*)*storage;
TRACE("\n");
ptr1 = (WineDataRefRecord*)dataRef;
*equal = (ptr1->pReader == data->dataRef.pReader);
return noErr;
}
static pascal ComponentResult myDataHGetDataRef ( DataHandler dh, Handle *dataRef)
{
Handle storage = GetComponentInstanceStorage(dh);
TRACE("\n");
*dataRef = storage;
HandToHand(dataRef);
return noErr;
}
static pascal ComponentResult myDataHGetScheduleAheadTime ( DataHandler dh,
long *millisecs)
{
TRACE("\n");
*millisecs = 1000;
return noErr;
}
static pascal ComponentResult myDataHGetInfoFlags ( DataHandler dh, UInt32 *flags)
{
TRACE("\n");
*flags = 0;
return noErr;
}
static pascal ComponentResult myDataHGetFileTypeOrdering ( DataHandler dh,
DataHFileTypeOrderingHandle *orderingListHandle)
{
OSType orderlist[1] = {kDataHFileTypeExtension};
TRACE("\n");
PtrToHand( &orderlist, (Handle*)orderingListHandle, sizeof(OSType));
return noErr;
}
typedef struct {
const char *const fname;
const int sig_length;
const BYTE sig[10];
} signature;
static const signature stream_sigs[] = {
{"video.asf",4,{0x30,0x26,0xb2,0x75}},
{"video.mov",8,{0x00,0x00,0x00,0x14,0x66,0x74,0x79,0x70}},
{"video.mp4",8,{0x00,0x00,0x00,0x18,0x66,0x74,0x79,0x70}},
{"video.m4v",8,{0x00,0x00,0x00,0x1c,0x66,0x74,0x79,0x70}},
{"video.flv",4,{0x46,0x4C,0x56,0x01}},
{"video.mpg",3,{0x00,0x00,0x01}},
{"avideo.rm",4,{0x2E,0x52,0x4D,0x46}}
};
static pascal ComponentResult myDataHGetFileName ( DataHandler dh, Str255 str)
{
Handle storage = GetComponentInstanceStorage(dh);
DHData *data = (DHData*)*storage;
TRACE("%p %s\n",str,debugstr_guid(&data->dataRef.streamSubtype));
/* Todo Expand this list */
if (IsEqualIID(&data->dataRef.streamSubtype, &MEDIASUBTYPE_MPEG1Video) ||
IsEqualIID(&data->dataRef.streamSubtype, &MEDIASUBTYPE_MPEG1System))
CFStringGetPascalString(CFSTR("video.mpg"),str,256,kCFStringEncodingMacRoman);
else if(IsEqualIID(&data->dataRef.streamSubtype, &MEDIASUBTYPE_Asf))
CFStringGetPascalString(CFSTR("video.asf"),str,256,kCFStringEncodingMacRoman);
else if(IsEqualIID(&data->dataRef.streamSubtype, &MEDIASUBTYPE_Avi))
CFStringGetPascalString(CFSTR("video.avi"),str,256,kCFStringEncodingMacRoman);
else if(IsEqualIID(&data->dataRef.streamSubtype, &MEDIASUBTYPE_QTMovie))
CFStringGetPascalString(CFSTR("video.mov"),str,256,kCFStringEncodingMacRoman);
else
{
BYTE header[10] = {0,0,0,0,0,0,0,0,0,0};
int i;
IAsyncReader_SyncRead(data->dataRef.pReader, 0, 8, header);
for (i=0; i < sizeof(stream_sigs)/sizeof(signature); i++)
if (memcmp(header, stream_sigs[i].sig, stream_sigs[i].sig_length)==0)
{
str[0] = strlen(stream_sigs[i].fname);
memcpy(str + 1, stream_sigs[i].fname, str[0]);
return noErr;
}
return badComponentSelector;
}
return noErr;
}
static pascal ComponentResult myDataHOpenForRead(DataHandler dh)
{
TRACE("\n");
return noErr;
}
static pascal ComponentResult myDataHTask(DataHandler dh)
{
Handle storage = GetComponentInstanceStorage(dh);
DHData *data = (DHData*)*storage;
if (data->AsyncCompletionRtn)
{
TRACE("Sending Completion\n");
InvokeDataHCompletionUPP(data->AsyncPtr, data->AsyncRefCon, noErr, data->AsyncCompletionRtn);
data->AsyncPtr = NULL;
data->AsyncRefCon = 0;
data->AsyncCompletionRtn = NULL;
}
return noErr;
}
static pascal ComponentResult myDataHPlaybackHints(DataHandler dh, long flags,
unsigned long minFileOffset, unsigned long maxFileOffset,
long bytesPerSecond)
{
TRACE("%lu %lu %li\n",minFileOffset, maxFileOffset, bytesPerSecond);
return noErr;
}
static pascal ComponentResult myDataHPlaybackHints64(DataHandler dh, long flags,
wide *minFileOffset, wide *maxFileOffset,
long bytesPerSecond)
{
if (TRACE_ON(qtdatahandler))
{
SInt64 minFileOffset64 = WideToSInt64(*minFileOffset);
LONGLONG minFileOffsetLL = minFileOffset64;
SInt64 maxFileOffset64 = WideToSInt64(*maxFileOffset);
LONGLONG maxFileOffsetLL = maxFileOffset64;
TRACE("%s %s %li\n",wine_dbgstr_longlong(minFileOffsetLL), wine_dbgstr_longlong(maxFileOffsetLL), bytesPerSecond);
}
return noErr;
}
static pascal ComponentResult myDataHGetFileSize64(DataHandler dh, wide * fileSize)
{
Handle storage = GetComponentInstanceStorage(dh);
DHData *data = (DHData*)*storage;
LONGLONG total;
LONGLONG available;
SInt64 total64;
TRACE("%p\n",dh);
IAsyncReader_Length(data->dataRef.pReader,&total,&available);
total64 = total;
*fileSize = SInt64ToWide(total64);
return noErr;
}
static pascal ComponentResult myDataHGetFileSizeAsync ( DataHandler dh, wide *fileSize, DataHCompletionUPP CompletionRtn, long RefCon )
{
Handle storage = GetComponentInstanceStorage(dh);
DHData *data = (DHData*)*storage;
LONGLONG total;
LONGLONG available;
SInt64 total64;
TRACE("%p\n",dh);
IAsyncReader_Length(data->dataRef.pReader,&total,&available);
total64 = total;
*fileSize = SInt64ToWide(total64);
if (CompletionRtn)
{
if (data->AsyncCompletionRtn)
InvokeDataHCompletionUPP(data->AsyncPtr, data->AsyncRefCon, noErr, data->AsyncCompletionRtn);
data->AsyncPtr = (Ptr)fileSize;
data->AsyncRefCon = RefCon;
data->AsyncCompletionRtn = CompletionRtn;
}
return noErr;
}
static pascal ComponentResult myDataHGetAvailableFileSize64(DataHandler dh, wide * fileSize)
{
Handle storage = GetComponentInstanceStorage(dh);
DHData *data = (DHData*)*storage;
LONGLONG total;
LONGLONG available;
SInt64 total64;
TRACE("%p\n",dh);
IAsyncReader_Length(data->dataRef.pReader,&total,&available);
total64 = available;
*fileSize = SInt64ToWide(total64);
return noErr;
}
static pascal ComponentResult myDataHScheduleData64( DataHandler dh,
Ptr PlaceToPutDataPtr,
const wide * FileOffset,
long DataSize,
long RefCon,
DataHSchedulePtr scheduleRec,
DataHCompletionUPP CompletionRtn)
{
Handle storage = GetComponentInstanceStorage(dh);
DHData *data = (DHData*)*storage;
HRESULT hr;
SInt64 fileOffset64 = WideToSInt64(*FileOffset);
LONGLONG offset = fileOffset64;
BYTE* buffer = (BYTE*)PlaceToPutDataPtr;
TRACE("%p %p %s %li %li %p %p\n",dh, PlaceToPutDataPtr, wine_dbgstr_longlong(offset), DataSize, RefCon, scheduleRec, CompletionRtn);
hr = IAsyncReader_SyncRead(data->dataRef.pReader, offset, DataSize, buffer);
TRACE("result %x\n",hr);
if (CompletionRtn)
{
if (data->AsyncCompletionRtn)
InvokeDataHCompletionUPP(data->AsyncPtr, data->AsyncRefCon, noErr, data->AsyncCompletionRtn);
data->AsyncPtr = PlaceToPutDataPtr;
data->AsyncRefCon = RefCon;
data->AsyncCompletionRtn = CompletionRtn;
}
return noErr;
}
static const struct { LPVOID proc; ProcInfoType type;} componentFunctions[] =
{
{NULL, 0}, /* 0 */
{NULL, 0}, /* 1 */
{myDataHGetData, kPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Handle)))
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long)))
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long)))
| STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(long)))
}, /* kDataHGetDataSelect */
{NULL, 0}, /* kDataHPutDataSelect */
{NULL, 0}, /* kDataHFlushDataSelect */
{NULL, 0}, /* kDataHOpenForWriteSelect */
{NULL, 0}, /* kDataHCloseForWriteSelect */
{NULL, 0}, /* 7 */
{myDataHOpenForRead, kPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
}, /* kDataHOpenForReadSelect
*/
{NULL, 0}, /* kDataHCloseForReadSelect */
{myDataHSetDataRef, kPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Handle)))
}, /* kDataHSetDataRefSelect */
{myDataHGetDataRef, kPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Handle)))
}, /* kDataHGetDataRefSelect */
{myDataHCompareDataRef, kPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Handle)))
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(Boolean*)))
}, /* kDataHCompareDataRefSelect */
{myDataHTask, kPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
}, /* kDataHTaskSelect */
{myDataHScheduleData, kPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Ptr)))
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long)))
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long)))
| STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(long)))
| STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(DataHSchedulePtr)))
| STACK_ROUTINE_PARAMETER(7, SIZE_CODE(sizeof(DataHCompletionUPP)))
}, /* kDataHScheduleDataSelect */
{myDataHFinishData, kPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Ptr)))
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(Boolean)))
}, /* kDataHFinishDataSelect */
{NULL, 0}, /* kDataHFlushCacheSelect 0x10 */
{NULL, 0}, /* kDataHResolveDataRefSelect */
{myDataHGetFileSize, kPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long*)))
}, /* kDataHGetFileSizeSelect */
{myDataHCanUseDataRef, kPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Handle)))
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long*)))
}, /* kDataHCanUseDataRefSelect */
{NULL, 0}, /* kDataHGetVolumeListSelect */
{NULL, 0}, /* kDataHWriteSelect */
{NULL, 0}, /* kDataHPreextendSelect */
{NULL, 0}, /* kDataHSetFileSizeSelect */
{NULL, 0}, /* kDataHGetFreeSpaceSelect */
{NULL, 0}, /* kDataHCreateFileSelect */
{NULL, 0}, /* kDataHGetPreferredBlockSizeSelect */
{NULL, 0}, /* kDataHGetDeviceIndexSelect */
{NULL, 0}, /* kDataHIsStreamingDataHandlerSelect */
{NULL, 0}, /* kDataHGetDataInBufferSelect */
{myDataHGetScheduleAheadTime, kPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long*)))
}, /* kDataHGetScheduleAheadTimeSelect */
/* End of Required List */
{NULL, 0}, /* kDataHSetCacheSizeLimitSelect */
{NULL, 0}, /* kDataHGetCacheSizeLimitSelect 0x20 */
{NULL, 0}, /* kDataHGetMovieSelect */
{NULL, 0}, /* kDataHAddMovieSelect */
{NULL, 0}, /* kDataHUpdateMovieSelect */
{NULL, 0}, /* kDataHDoesBufferSelect */
{myDataHGetFileName, kPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Str255*)))
}, /* kDataHGetFileNameSelect */
{myDataHGetAvailableFileSize, kPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long*)))
}, /* kDataHGetAvailableFileSizeSelect */
{NULL, 0}, /* kDataHGetMacOSFileTypeSelect */
{NULL, 0}, /* kDataHGetMIMETypeSelect */
{NULL, 0}, /* kDataHSetDataRefWithAnchorSelect */
{NULL, 0}, /* kDataHGetDataRefWithAnchorSelect */
{NULL, 0}, /* kDataHSetMacOSFileTypeSelect */
{NULL, 0}, /* kDataHSetTimeBaseSelect */
{myDataHGetInfoFlags, kPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(UInt32*)))
}, /* kDataHGetInfoFlagsSelect */
{myDataHScheduleData64, kPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Ptr)))
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(wide*)))
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long)))
| STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(long)))
| STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(DataHSchedulePtr)))
| STACK_ROUTINE_PARAMETER(7, SIZE_CODE(sizeof(DataHCompletionUPP)))
}, /* kDataHScheduleData64Select */
{NULL, 0}, /* kDataHWrite64Select */
{myDataHGetFileSize64, kPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(wide*)))
}, /* kDataHGetFileSize64Select 0x30 */
{NULL, 0}, /* kDataHPreextend64Select */
{NULL, 0}, /* kDataHSetFileSize64Select */
{NULL, 0}, /* kDataHGetFreeSpace64Select */
{NULL, 0}, /* kDataHAppend64Select */
{NULL, 0}, /* kDataHReadAsyncSelect */
{NULL, 0}, /* kDataHPollReadSelect */
{NULL, 0}, /* kDataHGetDataAvailabilitySelect */
{NULL, 0}, /* 0x0038 */
{NULL, 0}, /* 0x0039 */
{myDataHGetFileSizeAsync, kPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(wide*)))
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(DataHCompletionUPP)))
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long)))
}, /* kDataHGetFileSizeAsyncSelect */
{NULL, 0}, /* kDataHGetDataRefAsTypeSelect */
{NULL, 0}, /* kDataHSetDataRefExtensionSelect */
{NULL, 0}, /* kDataHGetDataRefExtensionSelect */
{NULL, 0}, /* kDataHGetMovieWithFlagsSelect */
{NULL, 0}, /* 0x3F */
{myDataHGetFileTypeOrdering, kPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(DataHFileTypeOrderingHandle*)))
}, /* kDataHGetFileTypeOrderingSelect 0x40 */
{NULL, 0}, /* kDataHCreateFileWithFlagsSelect */
{NULL, 0}, /* kDataHGetMIMETypeAsyncSelect */
{NULL, 0}, /* kDataHGetInfoSelect */
{NULL, 0}, /* kDataHSetIdleManagerSelect */
{NULL, 0}, /* kDataHDeleteFileSelect */
{NULL, 0}, /* kDataHSetMovieUsageFlagsSelect */
{NULL, 0}, /* kDataHUseTemporaryDataRefSelect */
{NULL, 0}, /* kDataHGetTemporaryDataRefCapabilitiesSelect */
{NULL, 0}, /* kDataHRenameFileSelect */
{NULL, 0}, /* 0x4A */
{NULL, 0}, /* 0x4B */
{NULL, 0}, /* 0x4C */
{NULL, 0}, /* 0x4D */
{myDataHGetAvailableFileSize64, kPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(wide*)))
}, /* kDataHGetAvailableFileSize64Select */
{NULL, 0}, /* kDataHGetDataAvailability64Select */
};
static const struct { LPVOID proc; ProcInfoType type;} componentFunctions_2[] =
{
{myDataHPlaybackHints, kPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long)))
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(unsigned long)))
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(unsigned long)))
| STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(long)))
}, /* kDataHPlaybackHintsSelect 0x103 */
{myDataHPlaybackHints64, kPascalStackBased
| RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
| STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
| STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long)))
| STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(wide*)))
| STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(wide*)))
| STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(long)))
}, /* kDataHPlaybackHints64Select 0x10E */
{NULL, 0}, /* kDataHGetDataRateSelect 0x110 */
{NULL, 0}, /* kDataHSetTimeHintsSelect 0x111 */
};
/* Component Functions */
static pascal ComponentResult myComponentOpen(ComponentInstance ci, ComponentInstance self)
{
DHData myData;
Handle storage;
ZeroMemory(&myData,sizeof(DHData));
PtrToHand( &myData, &storage, sizeof(DHData));
SetComponentInstanceStorage(self,storage);
return noErr;
}
static pascal ComponentResult myComponentClose(ComponentInstance ci, ComponentInstance self)
{
Handle storage = GetComponentInstanceStorage(self);
DHData *data;
if (storage)
{
data = (DHData*)*storage;
if (data && data->dataRef.pReader != NULL)
IAsyncReader_Release(data->dataRef.pReader);
DisposeHandle(storage);
SetComponentInstanceStorage(self,NULL);
}
return noErr;
}
static pascal ComponentResult myComponentCanDo(ComponentInstance ci, SInt16 ftnNumber)
{
TRACE("test 0x%x\n",ftnNumber);
if (ftnNumber <= kComponentOpenSelect && ftnNumber >= kComponentCanDoSelect)
return TRUE;
if (ftnNumber == kDataHPlaybackHintsSelect)
return TRUE;
if (ftnNumber == kDataHPlaybackHints64Select)
return TRUE;
if (ftnNumber > kDataHGetDataAvailability64Select)
return FALSE;
TRACE("impl? %i\n",(componentFunctions[ftnNumber].proc != NULL));
return (componentFunctions[ftnNumber].proc != NULL);
}
/* Main Proc */
static ComponentResult callOurFunction(LPVOID proc, ProcInfoType type, ComponentParameters * cp)
{
ComponentRoutineUPP myUUP;
ComponentResult result;
myUUP = NewComponentFunctionUPP(proc, type);
result = CallComponentFunction(cp, myUUP);
DisposeComponentFunctionUPP(myUUP);
return result;
}
static pascal ComponentResult myComponentRoutineProc ( ComponentParameters * cp,
Handle componentStorage)
{
switch (cp->what)
{
case kComponentOpenSelect:
return callOurFunction(myComponentOpen, uppCallComponentOpenProcInfo, cp);
case kComponentCloseSelect:
return callOurFunction(myComponentClose, uppCallComponentOpenProcInfo, cp);
case kComponentCanDoSelect:
return callOurFunction(myComponentCanDo, uppCallComponentCanDoProcInfo, cp);
case kDataHPlaybackHintsSelect:
return callOurFunction(componentFunctions_2[0].proc, componentFunctions_2[0].type, cp);
case kDataHPlaybackHints64Select:
return callOurFunction(componentFunctions_2[1].proc, componentFunctions_2[1].type, cp);
}
if (cp->what > 0 && cp->what <=kDataHGetDataAvailability64Select && componentFunctions[cp->what].proc)
return callOurFunction(componentFunctions[cp->what].proc, componentFunctions[cp->what].type, cp);
FIXME("unhandled select 0x%x\n",cp->what);
return badComponentSelector;
}