wineqtdecoder: Fix the spelling of a QTSplitter_loading_thread() variable.
[wine/multimedia.git] / dlls / wineqtdecoder / qtdatahandler.c
blobbe003c3f1708f385d6c0f8a9c8bb36b6d750b726
1 /*
2 * QuickTime Data Handler
4 * Copyright 2011 Aric Stewart for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "config.h"
23 #define ULONG CoreFoundation_ULONG
24 #define HRESULT CoreFoundation_HRESULT
26 #define LoadResource __carbon_LoadResource
27 #define CompareString __carbon_CompareString
28 #define GetCurrentThread __carbon_GetCurrentThread
29 #define GetCurrentProcess __carbon_GetCurrentProcess
30 #define AnimatePalette __carbon_AnimatePalette
31 #define EqualRgn __carbon_EqualRgn
32 #define FillRgn __carbon_FillRgn
33 #define FrameRgn __carbon_FrameRgn
34 #define GetPixel __carbon_GetPixel
35 #define InvertRgn __carbon_InvertRgn
36 #define LineTo __carbon_LineTo
37 #define OffsetRgn __carbon_OffsetRgn
38 #define PaintRgn __carbon_PaintRgn
39 #define Polygon __carbon_Polygon
40 #define ResizePalette __carbon_ResizePalette
41 #define SetRectRgn __carbon_SetRectRgn
43 #define CheckMenuItem __carbon_CheckMenuItem
44 #define DeleteMenu __carbon_DeleteMenu
45 #define DrawMenuBar __carbon_DrawMenuBar
46 #define EnableMenuItem __carbon_EnableMenuItem
47 #define EqualRect __carbon_EqualRect
48 #define FillRect __carbon_FillRect
49 #define FrameRect __carbon_FrameRect
50 #define GetCursor __carbon_GetCursor
51 #define GetMenu __carbon_GetMenu
52 #define InvertRect __carbon_InvertRect
53 #define IsWindowVisible __carbon_IsWindowVisible
54 #define MoveWindow __carbon_MoveWindow
55 #define OffsetRect __carbon_OffsetRect
56 #define PtInRect __carbon_PtInRect
57 #define SetCursor __carbon_SetCursor
58 #define SetRect __carbon_SetRect
59 #define ShowCursor __carbon_ShowCursor
60 #define ShowWindow __carbon_ShowWindow
61 #define UnionRect __carbon_UnionRect
63 #include <QuickTime/QuickTimeComponents.h>
65 #undef LoadResource
66 #undef CompareString
67 #undef GetCurrentThread
68 #undef _CDECL
69 #undef DPRINTF
70 #undef GetCurrentProcess
71 #undef AnimatePalette
72 #undef EqualRgn
73 #undef FillRgn
74 #undef FrameRgn
75 #undef GetPixel
76 #undef InvertRgn
77 #undef LineTo
78 #undef OffsetRgn
79 #undef PaintRgn
80 #undef Polygon
81 #undef ResizePalette
82 #undef SetRectRgn
83 #undef CheckMenuItem
84 #undef DeleteMenu
85 #undef DrawMenuBar
86 #undef EnableMenuItem
87 #undef EqualRect
88 #undef FillRect
89 #undef FrameRect
90 #undef GetCursor
91 #undef GetMenu
92 #undef InvertRect
93 #undef IsWindowVisible
94 #undef MoveWindow
95 #undef OffsetRect
96 #undef PtInRect
97 #undef SetCursor
98 #undef SetRect
99 #undef ShowCursor
100 #undef ShowWindow
101 #undef UnionRect
103 #undef ULONG
104 #undef HRESULT
105 #undef DPRINTF
106 #undef STDMETHODCALLTYPE
108 #include <assert.h>
109 #include <stdio.h>
110 #include <stdarg.h>
112 #define NONAMELESSSTRUCT
113 #define NONAMELESSUNION
114 #define COBJMACROS
116 #include "windef.h"
117 #include "winbase.h"
118 #include "wtypes.h"
119 #include "winuser.h"
120 #include "dshow.h"
122 #include <assert.h>
124 #include "wine/unicode.h"
125 #include "wine/debug.h"
127 #include "qtprivate.h"
129 WINE_DEFAULT_DEBUG_CHANNEL(qtdatahandler);
131 static ComponentDescription myType =
133 'dhlr',
134 'WINE',
135 'WINE',
140 typedef struct DHData
142 WineDataRefRecord dataRef;
144 Ptr AsyncPtr;
145 long AsyncRefCon;
146 DataHCompletionUPP AsyncCompletionRtn;
147 } DHData;
149 static pascal ComponentResult myComponentRoutineProc ( ComponentParameters *
150 cp, Handle componentStorage);
152 void RegisterWineDataHandler( void )
154 ComponentRoutineUPP MyComponentRoutineUPP;
156 MyComponentRoutineUPP = NewComponentRoutineUPP(&myComponentRoutineProc);
157 RegisterComponent( &myType , MyComponentRoutineUPP, 0, NULL, NULL, NULL);
160 static pascal ComponentResult myDataHCanUseDataRef ( DataHandler dh,
161 Handle dataRef,
162 long *useFlags
165 WineDataRefRecord *record = (WineDataRefRecord*)(*dataRef);
166 TRACE("%p %p %p\n",dh,dataRef,useFlags);
167 if (record->pReader == NULL)
168 return badComponentSelector;
169 *useFlags = kDataHCanRead;
170 return noErr;
173 static pascal ComponentResult myDataHSetDataRef ( DataHandler dh, Handle dataRef)
175 Handle storage = GetComponentInstanceStorage(dh);
176 DHData *data = (DHData*)*storage;
177 WineDataRefRecord* newRef = (WineDataRefRecord*)(*dataRef);
178 TRACE("\n");
179 if (newRef->pReader != data->dataRef.pReader)
180 IAsyncReader_AddRef(newRef->pReader);
181 data->dataRef = *newRef;
182 return noErr;
185 static pascal ComponentResult myDataHGetAvailableFileSize ( DataHandler dh,
186 long *fileSize)
188 Handle storage = GetComponentInstanceStorage(dh);
189 DHData *data = (DHData*)*storage;
190 LONGLONG total;
191 LONGLONG available;
193 TRACE("%p\n",dh);
195 IAsyncReader_Length(data->dataRef.pReader,&total,&available);
196 *fileSize = available;
197 return noErr;
200 static pascal ComponentResult myDataHGetFileSize ( DataHandler dh, long *fileSize)
202 Handle storage = GetComponentInstanceStorage(dh);
203 DHData *data = (DHData*)*storage;
204 LONGLONG total;
205 LONGLONG available;
207 TRACE("%p\n",dh);
209 IAsyncReader_Length(data->dataRef.pReader,&total,&available);
210 *fileSize = total;
211 return noErr;
214 static pascal ComponentResult myDataHScheduleData ( DataHandler dh,
215 Ptr PlaceToPutDataPtr,
216 long FileOffset,
217 long DataSize,
218 long RefCon,
219 DataHSchedulePtr scheduleRec,
220 DataHCompletionUPP CompletionRtn)
222 Handle storage = GetComponentInstanceStorage(dh);
223 DHData *data = (DHData*)*storage;
224 HRESULT hr;
225 LONGLONG offset = FileOffset;
226 BYTE* buffer = (BYTE*)PlaceToPutDataPtr;
228 TRACE("%p %p %li %li %li %p %p\n",dh, PlaceToPutDataPtr, FileOffset, DataSize, RefCon, scheduleRec, CompletionRtn);
230 hr = IAsyncReader_SyncRead(data->dataRef.pReader, offset, DataSize, buffer);
231 TRACE("result %x\n",hr);
232 if (CompletionRtn)
234 if (data->AsyncCompletionRtn)
235 InvokeDataHCompletionUPP(data->AsyncPtr, data->AsyncRefCon, noErr, data->AsyncCompletionRtn);
237 data->AsyncPtr = PlaceToPutDataPtr;
238 data->AsyncRefCon = RefCon;
239 data->AsyncCompletionRtn = CompletionRtn;
242 return noErr;
245 static pascal ComponentResult myDataHFinishData (DataHandler dh, Ptr PlaceToPutDataPtr, Boolean Cancel)
247 Handle storage = GetComponentInstanceStorage(dh);
248 DHData *data = (DHData*)*storage;
249 if (!data->AsyncCompletionRtn)
250 return noErr;
251 if (!PlaceToPutDataPtr || PlaceToPutDataPtr == data->AsyncPtr)
253 if (!Cancel)
254 InvokeDataHCompletionUPP(data->AsyncPtr, data->AsyncRefCon, noErr, data->AsyncCompletionRtn);
255 data->AsyncPtr = NULL;
256 data->AsyncRefCon = 0;
257 data->AsyncCompletionRtn = NULL;
259 return noErr;
262 static pascal ComponentResult myDataHGetData ( DataHandler dh,
263 Handle h,
264 long hOffset,
265 long offset,
266 long size)
268 Handle storage = GetComponentInstanceStorage(dh);
269 DHData *data = (DHData*)*storage;
270 BYTE *target = (BYTE*)*h;
271 LONGLONG off = offset;
272 HRESULT hr;
274 TRACE("%p %p %li %li %li\n",dh, h, hOffset, offset, size);
275 hr = IAsyncReader_SyncRead(data->dataRef.pReader, off, size, target+hOffset);
276 TRACE("result %x\n",hr);
278 return noErr;
281 static pascal ComponentResult myDataHCompareDataRef ( DataHandler dh,
282 Handle dataRef, Boolean *equal)
284 WineDataRefRecord *ptr1;
285 Handle storage = GetComponentInstanceStorage(dh);
286 DHData *data = (DHData*)*storage;
287 TRACE("\n");
289 ptr1 = (WineDataRefRecord*)dataRef;
291 *equal = (ptr1->pReader == data->dataRef.pReader);
292 return noErr;
295 static pascal ComponentResult myDataHGetDataRef ( DataHandler dh, Handle *dataRef)
297 Handle storage = GetComponentInstanceStorage(dh);
298 TRACE("\n");
299 *dataRef = storage;
300 HandToHand(dataRef);
301 return noErr;
304 static pascal ComponentResult myDataHGetScheduleAheadTime ( DataHandler dh,
305 long *millisecs)
307 TRACE("\n");
308 *millisecs = 1000;
309 return noErr;
312 static pascal ComponentResult myDataHGetInfoFlags ( DataHandler dh, UInt32 *flags)
314 TRACE("\n");
315 *flags = 0;
316 return noErr;
319 static pascal ComponentResult myDataHGetFileTypeOrdering ( DataHandler dh,
320 DataHFileTypeOrderingHandle *orderingListHandle)
322 OSType orderlist[1] = {kDataHFileTypeExtension};
323 TRACE("\n");
324 PtrToHand( &orderlist, (Handle*)orderingListHandle, sizeof(OSType));
325 return noErr;
328 typedef struct {
329 const CFStringRef fname;
330 const int sig_length;
331 const BYTE sig[10];
332 } signature;
334 static const signature stream_sigs[] = {
335 {CFSTR("video.asf"),4,{0x30,0x26,0xb2,0x75}},
336 {CFSTR("video.mov"),8,{0x00,0x00,0x00,0x14,0x66,0x74,0x79,0x70}},
337 {CFSTR("video.mp4"),8,{0x00,0x00,0x00,0x18,0x66,0x74,0x79,0x70}},
338 {CFSTR("video.m4v"),8,{0x00,0x00,0x00,0x1c,0x66,0x74,0x79,0x70}},
339 {CFSTR("video.flv"),4,{0x46,0x4C,0x56,0x01}},
340 {CFSTR("video.mpg"),3,{0x00,0x00,0x01}},
341 {CFSTR("avideo.rm"),4,{0x2E,0x52,0x4D,0x46}}
344 static pascal ComponentResult myDataHGetFileName ( DataHandler dh, Str255 str)
346 Handle storage = GetComponentInstanceStorage(dh);
347 DHData *data = (DHData*)*storage;
348 TRACE("%p %s\n",str,debugstr_guid(&data->dataRef.streamSubtype));
350 /* Todo Expand this list */
351 if (IsEqualIID(&data->dataRef.streamSubtype, &MEDIASUBTYPE_MPEG1Video) ||
352 IsEqualIID(&data->dataRef.streamSubtype, &MEDIASUBTYPE_MPEG1System))
353 CFStringGetPascalString(CFSTR("video.mpg"),str,256,kCFStringEncodingMacRoman);
354 else if(IsEqualIID(&data->dataRef.streamSubtype, &MEDIASUBTYPE_Asf))
355 CFStringGetPascalString(CFSTR("video.asf"),str,256,kCFStringEncodingMacRoman);
356 else if(IsEqualIID(&data->dataRef.streamSubtype, &MEDIASUBTYPE_Avi))
357 CFStringGetPascalString(CFSTR("video.avi"),str,256,kCFStringEncodingMacRoman);
358 else if(IsEqualIID(&data->dataRef.streamSubtype, &MEDIASUBTYPE_QTMovie))
359 CFStringGetPascalString(CFSTR("video.mov"),str,256,kCFStringEncodingMacRoman);
360 else
362 BYTE header[10] = {0,0,0,0,0,0,0,0,0,0};
363 int i;
364 IAsyncReader_SyncRead(data->dataRef.pReader, 0, 8, header);
366 for (i=0; i < sizeof(stream_sigs)/sizeof(signature); i++)
367 if (memcmp(header, stream_sigs[i].sig, stream_sigs[i].sig_length)==0)
369 CFStringGetPascalString(stream_sigs[i].fname,str,256,kCFStringEncodingMacRoman);
370 return noErr;
373 return badComponentSelector;
376 return noErr;
379 static pascal ComponentResult myDataHOpenForRead(DataHandler dh)
381 TRACE("\n");
382 return noErr;
385 static pascal ComponentResult myDataHTask(DataHandler dh)
387 Handle storage = GetComponentInstanceStorage(dh);
388 DHData *data = (DHData*)*storage;
390 if (data->AsyncCompletionRtn)
392 TRACE("Sending Completion\n");
393 InvokeDataHCompletionUPP(data->AsyncPtr, data->AsyncRefCon, noErr, data->AsyncCompletionRtn);
394 data->AsyncPtr = NULL;
395 data->AsyncRefCon = 0;
396 data->AsyncCompletionRtn = NULL;
398 return noErr;
401 static pascal ComponentResult myDataHPlaybackHints(DataHandler dh, long flags,
402 unsigned long minFileOffset, unsigned long maxFileOffset,
403 long bytesPerSecond)
405 TRACE("%lu %lu %li\n",minFileOffset, maxFileOffset, bytesPerSecond);
406 return noErr;
409 static pascal ComponentResult myDataHPlaybackHints64(DataHandler dh, long flags,
410 wide *minFileOffset, wide *maxFileOffset,
411 long bytesPerSecond)
413 if (TRACE_ON(qtdatahandler))
415 SInt64 minFileOffset64 = WideToSInt64(*minFileOffset);
416 LONGLONG minFileOffsetLL = minFileOffset64;
417 SInt64 maxFileOffset64 = WideToSInt64(*maxFileOffset);
418 LONGLONG maxFileOffsetLL = maxFileOffset64;
420 TRACE("%s %s %li\n",wine_dbgstr_longlong(minFileOffsetLL), wine_dbgstr_longlong(maxFileOffsetLL), bytesPerSecond);
422 return noErr;
425 static pascal ComponentResult myDataHGetFileSize64(DataHandler dh, wide * fileSize)
427 Handle storage = GetComponentInstanceStorage(dh);
428 DHData *data = (DHData*)*storage;
429 LONGLONG total;
430 LONGLONG available;
431 SInt64 total64;
433 TRACE("%p\n",dh);
435 IAsyncReader_Length(data->dataRef.pReader,&total,&available);
436 total64 = total;
437 *fileSize = SInt64ToWide(total64);
438 return noErr;
441 static pascal ComponentResult myDataHGetFileSizeAsync ( DataHandler dh, wide *fileSize, DataHCompletionUPP CompletionRtn, long RefCon )
443 Handle storage = GetComponentInstanceStorage(dh);
444 DHData *data = (DHData*)*storage;
445 LONGLONG total;
446 LONGLONG available;
447 SInt64 total64;
449 TRACE("%p\n",dh);
451 IAsyncReader_Length(data->dataRef.pReader,&total,&available);
452 total64 = total;
453 *fileSize = SInt64ToWide(total64);
455 if (CompletionRtn)
457 if (data->AsyncCompletionRtn)
458 InvokeDataHCompletionUPP(data->AsyncPtr, data->AsyncRefCon, noErr, data->AsyncCompletionRtn);
460 data->AsyncPtr = (Ptr)fileSize;
461 data->AsyncRefCon = RefCon;
462 data->AsyncCompletionRtn = CompletionRtn;
465 return noErr;
468 static pascal ComponentResult myDataHGetAvailableFileSize64(DataHandler dh, wide * fileSize)
470 Handle storage = GetComponentInstanceStorage(dh);
471 DHData *data = (DHData*)*storage;
472 LONGLONG total;
473 LONGLONG available;
474 SInt64 total64;
476 TRACE("%p\n",dh);
478 IAsyncReader_Length(data->dataRef.pReader,&total,&available);
479 total64 = available;
480 *fileSize = SInt64ToWide(total64);
481 return noErr;
484 static pascal ComponentResult myDataHScheduleData64( DataHandler dh,
485 Ptr PlaceToPutDataPtr,
486 const wide * FileOffset,
487 long DataSize,
488 long RefCon,
489 DataHSchedulePtr scheduleRec,
490 DataHCompletionUPP CompletionRtn)
492 Handle storage = GetComponentInstanceStorage(dh);
493 DHData *data = (DHData*)*storage;
494 HRESULT hr;
495 SInt64 fileOffset64 = WideToSInt64(*FileOffset);
496 LONGLONG offset = fileOffset64;
497 BYTE* buffer = (BYTE*)PlaceToPutDataPtr;
499 TRACE("%p %p %s %li %li %p %p\n",dh, PlaceToPutDataPtr, wine_dbgstr_longlong(offset), DataSize, RefCon, scheduleRec, CompletionRtn);
501 hr = IAsyncReader_SyncRead(data->dataRef.pReader, offset, DataSize, buffer);
502 TRACE("result %x\n",hr);
503 if (CompletionRtn)
505 if (data->AsyncCompletionRtn)
506 InvokeDataHCompletionUPP(data->AsyncPtr, data->AsyncRefCon, noErr, data->AsyncCompletionRtn);
508 data->AsyncPtr = PlaceToPutDataPtr;
509 data->AsyncRefCon = RefCon;
510 data->AsyncCompletionRtn = CompletionRtn;
513 return noErr;
516 static const struct { LPVOID proc; ProcInfoType type;} componentFunctions[] =
518 {NULL, 0}, /* 0 */
519 {NULL, 0}, /* 1 */
520 {myDataHGetData, kPascalStackBased
521 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
522 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
523 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Handle)))
524 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long)))
525 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long)))
526 | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(long)))
527 }, /* kDataHGetDataSelect */
528 {NULL, 0}, /* kDataHPutDataSelect */
529 {NULL, 0}, /* kDataHFlushDataSelect */
530 {NULL, 0}, /* kDataHOpenForWriteSelect */
531 {NULL, 0}, /* kDataHCloseForWriteSelect */
532 {NULL, 0}, /* 7 */
533 {myDataHOpenForRead, kPascalStackBased
534 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
535 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
536 }, /* kDataHOpenForReadSelect
538 {NULL, 0}, /* kDataHCloseForReadSelect */
539 {myDataHSetDataRef, kPascalStackBased
540 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
541 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
542 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Handle)))
543 }, /* kDataHSetDataRefSelect */
544 {myDataHGetDataRef, kPascalStackBased
545 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
546 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
547 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Handle)))
548 }, /* kDataHGetDataRefSelect */
549 {myDataHCompareDataRef, kPascalStackBased
550 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
551 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
552 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Handle)))
553 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(Boolean*)))
554 }, /* kDataHCompareDataRefSelect */
555 {myDataHTask, kPascalStackBased
556 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
557 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
558 }, /* kDataHTaskSelect */
559 {myDataHScheduleData, kPascalStackBased
560 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
561 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
562 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Ptr)))
563 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long)))
564 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long)))
565 | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(long)))
566 | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(DataHSchedulePtr)))
567 | STACK_ROUTINE_PARAMETER(7, SIZE_CODE(sizeof(DataHCompletionUPP)))
568 }, /* kDataHScheduleDataSelect */
569 {myDataHFinishData, kPascalStackBased
570 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
571 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
572 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Ptr)))
573 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(Boolean)))
574 }, /* kDataHFinishDataSelect */
575 {NULL, 0}, /* kDataHFlushCacheSelect 0x10 */
576 {NULL, 0}, /* kDataHResolveDataRefSelect */
577 {myDataHGetFileSize, kPascalStackBased
578 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
579 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
580 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long*)))
581 }, /* kDataHGetFileSizeSelect */
582 {myDataHCanUseDataRef, kPascalStackBased
583 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
584 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
585 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Handle)))
586 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(long*)))
587 }, /* kDataHCanUseDataRefSelect */
588 {NULL, 0}, /* kDataHGetVolumeListSelect */
589 {NULL, 0}, /* kDataHWriteSelect */
590 {NULL, 0}, /* kDataHPreextendSelect */
591 {NULL, 0}, /* kDataHSetFileSizeSelect */
592 {NULL, 0}, /* kDataHGetFreeSpaceSelect */
593 {NULL, 0}, /* kDataHCreateFileSelect */
594 {NULL, 0}, /* kDataHGetPreferredBlockSizeSelect */
595 {NULL, 0}, /* kDataHGetDeviceIndexSelect */
596 {NULL, 0}, /* kDataHIsStreamingDataHandlerSelect */
597 {NULL, 0}, /* kDataHGetDataInBufferSelect */
598 {myDataHGetScheduleAheadTime, kPascalStackBased
599 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
600 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
601 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long*)))
602 }, /* kDataHGetScheduleAheadTimeSelect */
603 /* End of Required List */
604 {NULL, 0}, /* kDataHSetCacheSizeLimitSelect */
605 {NULL, 0}, /* kDataHGetCacheSizeLimitSelect 0x20 */
606 {NULL, 0}, /* kDataHGetMovieSelect */
607 {NULL, 0}, /* kDataHAddMovieSelect */
608 {NULL, 0}, /* kDataHUpdateMovieSelect */
609 {NULL, 0}, /* kDataHDoesBufferSelect */
610 {myDataHGetFileName, kPascalStackBased
611 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
612 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
613 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Str255*)))
614 }, /* kDataHGetFileNameSelect */
615 {myDataHGetAvailableFileSize, kPascalStackBased
616 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
617 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
618 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long*)))
619 }, /* kDataHGetAvailableFileSizeSelect */
620 {NULL, 0}, /* kDataHGetMacOSFileTypeSelect */
621 {NULL, 0}, /* kDataHGetMIMETypeSelect */
622 {NULL, 0}, /* kDataHSetDataRefWithAnchorSelect */
623 {NULL, 0}, /* kDataHGetDataRefWithAnchorSelect */
624 {NULL, 0}, /* kDataHSetMacOSFileTypeSelect */
625 {NULL, 0}, /* kDataHSetTimeBaseSelect */
626 {myDataHGetInfoFlags, kPascalStackBased
627 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
628 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
629 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(UInt32*)))
630 }, /* kDataHGetInfoFlagsSelect */
631 {myDataHScheduleData64, kPascalStackBased
632 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
633 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
634 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(Ptr)))
635 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(wide*)))
636 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long)))
637 | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(long)))
638 | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(DataHSchedulePtr)))
639 | STACK_ROUTINE_PARAMETER(7, SIZE_CODE(sizeof(DataHCompletionUPP)))
640 }, /* kDataHScheduleData64Select */
641 {NULL, 0}, /* kDataHWrite64Select */
642 {myDataHGetFileSize64, kPascalStackBased
643 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
644 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
645 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(wide*)))
646 }, /* kDataHGetFileSize64Select 0x30 */
647 {NULL, 0}, /* kDataHPreextend64Select */
648 {NULL, 0}, /* kDataHSetFileSize64Select */
649 {NULL, 0}, /* kDataHGetFreeSpace64Select */
650 {NULL, 0}, /* kDataHAppend64Select */
651 {NULL, 0}, /* kDataHReadAsyncSelect */
652 {NULL, 0}, /* kDataHPollReadSelect */
653 {NULL, 0}, /* kDataHGetDataAvailabilitySelect */
654 {NULL, 0}, /* 0x0038 */
655 {NULL, 0}, /* 0x0039 */
656 {myDataHGetFileSizeAsync, kPascalStackBased
657 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
658 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
659 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(wide*)))
660 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(DataHCompletionUPP)))
661 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(long)))
662 }, /* kDataHGetFileSizeAsyncSelect */
663 {NULL, 0}, /* kDataHGetDataRefAsTypeSelect */
664 {NULL, 0}, /* kDataHSetDataRefExtensionSelect */
665 {NULL, 0}, /* kDataHGetDataRefExtensionSelect */
666 {NULL, 0}, /* kDataHGetMovieWithFlagsSelect */
667 {NULL, 0}, /* 0x3F */
668 {myDataHGetFileTypeOrdering, kPascalStackBased
669 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
670 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
671 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(DataHFileTypeOrderingHandle*)))
672 }, /* kDataHGetFileTypeOrderingSelect 0x40 */
673 {NULL, 0}, /* kDataHCreateFileWithFlagsSelect */
674 {NULL, 0}, /* kDataHGetMIMETypeAsyncSelect */
675 {NULL, 0}, /* kDataHGetInfoSelect */
676 {NULL, 0}, /* kDataHSetIdleManagerSelect */
677 {NULL, 0}, /* kDataHDeleteFileSelect */
678 {NULL, 0}, /* kDataHSetMovieUsageFlagsSelect */
679 {NULL, 0}, /* kDataHUseTemporaryDataRefSelect */
680 {NULL, 0}, /* kDataHGetTemporaryDataRefCapabilitiesSelect */
681 {NULL, 0}, /* kDataHRenameFileSelect */
682 {NULL, 0}, /* 0x4A */
683 {NULL, 0}, /* 0x4B */
684 {NULL, 0}, /* 0x4C */
685 {NULL, 0}, /* 0x4D */
686 {myDataHGetAvailableFileSize64, kPascalStackBased
687 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
688 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
689 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(wide*)))
690 }, /* kDataHGetAvailableFileSize64Select */
691 {NULL, 0}, /* kDataHGetDataAvailability64Select */
694 static const struct { LPVOID proc; ProcInfoType type;} componentFunctions_2[] =
696 {myDataHPlaybackHints, kPascalStackBased
697 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
698 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
699 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long)))
700 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(unsigned long)))
701 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(unsigned long)))
702 | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(long)))
703 }, /* kDataHPlaybackHintsSelect 0x103 */
704 {myDataHPlaybackHints64, kPascalStackBased
705 | RESULT_SIZE(SIZE_CODE(sizeof(ComponentResult)))
706 | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(DataHandler)))
707 | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(long)))
708 | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(wide*)))
709 | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(wide*)))
710 | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(long)))
711 }, /* kDataHPlaybackHints64Select 0x10E */
712 {NULL, 0}, /* kDataHGetDataRateSelect 0x110 */
713 {NULL, 0}, /* kDataHSetTimeHintsSelect 0x111 */
716 /* Component Functions */
718 static pascal ComponentResult myComponentOpen(ComponentInstance ci, ComponentInstance self)
720 DHData myData;
721 Handle storage;
723 ZeroMemory(&myData,sizeof(DHData));
724 PtrToHand( &myData, &storage, sizeof(DHData));
725 SetComponentInstanceStorage(self,storage);
727 return noErr;
730 static pascal ComponentResult myComponentClose(ComponentInstance ci, ComponentInstance self)
732 Handle storage = GetComponentInstanceStorage(self);
733 DHData *data;
734 if (storage)
736 data = (DHData*)*storage;
737 if (data && data->dataRef.pReader != NULL)
738 IAsyncReader_Release(data->dataRef.pReader);
739 DisposeHandle(storage);
740 SetComponentInstanceStorage(self,NULL);
742 return noErr;
745 static pascal ComponentResult myComponentCanDo(ComponentInstance ci, SInt16 ftnNumber)
747 TRACE("test 0x%x\n",ftnNumber);
748 if (ftnNumber <= kComponentOpenSelect && ftnNumber >= kComponentCanDoSelect)
749 return TRUE;
750 if (ftnNumber == kDataHPlaybackHintsSelect)
751 return TRUE;
752 if (ftnNumber == kDataHPlaybackHints64Select)
753 return TRUE;
754 if (ftnNumber > kDataHGetDataAvailability64Select)
755 return FALSE;
756 TRACE("impl? %i\n",(componentFunctions[ftnNumber].proc != NULL));
757 return (componentFunctions[ftnNumber].proc != NULL);
760 /* Main Proc */
762 static ComponentResult callOurFunction(LPVOID proc, ProcInfoType type, ComponentParameters * cp)
764 ComponentRoutineUPP myUUP;
765 ComponentResult result;
767 myUUP = NewComponentFunctionUPP(proc, type);
768 result = CallComponentFunction(cp, myUUP);
769 DisposeComponentFunctionUPP(myUUP);
770 return result;
773 static pascal ComponentResult myComponentRoutineProc ( ComponentParameters * cp,
774 Handle componentStorage)
776 switch (cp->what)
778 case kComponentOpenSelect:
779 return callOurFunction(myComponentOpen, uppCallComponentOpenProcInfo, cp);
780 case kComponentCloseSelect:
781 return callOurFunction(myComponentClose, uppCallComponentOpenProcInfo, cp);
782 case kComponentCanDoSelect:
783 return callOurFunction(myComponentCanDo, uppCallComponentCanDoProcInfo, cp);
784 case kDataHPlaybackHintsSelect:
785 return callOurFunction(componentFunctions_2[0].proc, componentFunctions_2[0].type, cp);
786 case kDataHPlaybackHints64Select:
787 return callOurFunction(componentFunctions_2[1].proc, componentFunctions_2[1].type, cp);
790 if (cp->what > 0 && cp->what <=kDataHGetDataAvailability64Select && componentFunctions[cp->what].proc)
791 return callOurFunction(componentFunctions[cp->what].proc, componentFunctions[cp->what].type, cp);
793 FIXME("unhandled select 0x%x\n",cp->what);
794 return badComponentSelector;