Implement ResetDC and PHYSICALOFFSET[X|Y] devcaps.
[wine] / dlls / quartz / imseek.c
1 /*
2  * Implementation of IMediaSeeking for FilterGraph.
3  *
4  * FIXME - stub.
5  * FIXME - this interface should be allocated as a plug-in(?)
6  *
7  * Copyright (C) Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23
24 #include "config.h"
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "winuser.h"
30 #include "winerror.h"
31 #include "strmif.h"
32 #include "control.h"
33 #include "uuids.h"
34
35 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
37
38 #include "quartz_private.h"
39 #include "fgraph.h"
40
41
42
43 static HRESULT WINAPI
44 IMediaSeeking_fnQueryInterface(IMediaSeeking* iface,REFIID riid,void** ppobj)
45 {
46         CFilterGraph_THIS(iface,mediaseeking);
47
48         TRACE("(%p)->()\n",This);
49
50         return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
51 }
52
53 static ULONG WINAPI
54 IMediaSeeking_fnAddRef(IMediaSeeking* iface)
55 {
56         CFilterGraph_THIS(iface,mediaseeking);
57
58         TRACE("(%p)->()\n",This);
59
60         return IUnknown_AddRef(This->unk.punkControl);
61 }
62
63 static ULONG WINAPI
64 IMediaSeeking_fnRelease(IMediaSeeking* iface)
65 {
66         CFilterGraph_THIS(iface,mediaseeking);
67
68         TRACE("(%p)->()\n",This);
69
70         return IUnknown_Release(This->unk.punkControl);
71 }
72
73
74 static HRESULT WINAPI
75 IMediaSeeking_fnGetCapabilities(IMediaSeeking* iface,DWORD* pdwCaps)
76 {
77         CFilterGraph_THIS(iface,mediaseeking);
78         HRESULT hr = E_NOTIMPL;
79         HRESULT hrFilter;
80         DWORD   n;
81
82         TRACE("(%p)->()\n",This);
83
84         EnterCriticalSection( &This->m_csFilters );
85
86         for ( n = 0; n < This->m_cActiveFilters; n++ )
87         {
88                 if ( This->m_pActiveFilters[n].pSeeking != NULL )
89                 {
90                         hrFilter = IMediaSeeking_GetCapabilities( This->m_pActiveFilters[n].pSeeking, pdwCaps );
91                         if ( hr == E_NOTIMPL )
92                         {
93                                 hr = hrFilter;
94                         }
95                         else
96                         if ( hrFilter != E_NOTIMPL )
97                         {
98                                 if ( SUCCEEDED(hr) )
99                                         hr = hrFilter;
100                         }
101                 }
102         }
103
104         LeaveCriticalSection( &This->m_csFilters );
105
106         return hr;
107 }
108
109 static HRESULT WINAPI
110 IMediaSeeking_fnCheckCapabilities(IMediaSeeking* iface,DWORD* pdwCaps)
111 {
112         CFilterGraph_THIS(iface,mediaseeking);
113         HRESULT hr = E_NOTIMPL;
114         HRESULT hrFilter;
115         DWORD   n;
116
117         TRACE("(%p)->()\n",This);
118
119         EnterCriticalSection( &This->m_csFilters );
120
121         for ( n = 0; n < This->m_cActiveFilters; n++ )
122         {
123                 if ( This->m_pActiveFilters[n].pSeeking != NULL )
124                 {
125                         hrFilter = IMediaSeeking_CheckCapabilities( This->m_pActiveFilters[n].pSeeking, pdwCaps );
126                         if ( hr == E_NOTIMPL )
127                         {
128                                 hr = hrFilter;
129                         }
130                         else
131                         if ( hrFilter != E_NOTIMPL )
132                         {
133                                 if ( SUCCEEDED(hr) )
134                                         hr = hrFilter;
135                         }
136                 }
137         }
138
139         LeaveCriticalSection( &This->m_csFilters );
140
141         return hr;
142 }
143
144 static HRESULT WINAPI
145 IMediaSeeking_fnIsFormatSupported(IMediaSeeking* iface,const GUID* pidFormat)
146 {
147         CFilterGraph_THIS(iface,mediaseeking);
148         HRESULT hr = E_NOTIMPL;
149         HRESULT hrFilter;
150         DWORD   n;
151
152         TRACE("(%p)->()\n",This);
153
154         EnterCriticalSection( &This->m_csFilters );
155
156         for ( n = 0; n < This->m_cActiveFilters; n++ )
157         {
158                 if ( This->m_pActiveFilters[n].pSeeking != NULL )
159                 {
160                         hrFilter = IMediaSeeking_IsFormatSupported( This->m_pActiveFilters[n].pSeeking, pidFormat );
161                         if ( hr == E_NOTIMPL )
162                         {
163                                 hr = hrFilter;
164                         }
165                         else
166                         if ( hrFilter != E_NOTIMPL )
167                         {
168                                 if ( SUCCEEDED(hr) )
169                                         hr = hrFilter;
170                         }
171                 }
172         }
173
174         LeaveCriticalSection( &This->m_csFilters );
175
176         return hr;
177 }
178
179 static HRESULT WINAPI
180 IMediaSeeking_fnQueryPreferredFormat(IMediaSeeking* iface,GUID* pidFormat)
181 {
182         CFilterGraph_THIS(iface,mediaseeking);
183         HRESULT hr = E_NOTIMPL;
184         HRESULT hrFilter;
185         DWORD   n;
186
187         TRACE("(%p)->()\n",This);
188
189         EnterCriticalSection( &This->m_csFilters );
190
191         for ( n = 0; n < This->m_cActiveFilters; n++ )
192         {
193                 if ( This->m_pActiveFilters[n].pSeeking != NULL )
194                 {
195                         hrFilter = IMediaSeeking_QueryPreferredFormat( This->m_pActiveFilters[n].pSeeking, pidFormat );
196                         if ( hr == E_NOTIMPL )
197                         {
198                                 hr = hrFilter;
199                         }
200                         else
201                         if ( hrFilter != E_NOTIMPL )
202                         {
203                                 if ( SUCCEEDED(hr) )
204                                         hr = hrFilter;
205                         }
206                 }
207         }
208
209         LeaveCriticalSection( &This->m_csFilters );
210
211         return hr;
212 }
213
214 static HRESULT WINAPI
215 IMediaSeeking_fnGetTimeFormat(IMediaSeeking* iface,GUID* pidFormat)
216 {
217         CFilterGraph_THIS(iface,mediaseeking);
218         HRESULT hr = E_NOTIMPL;
219         HRESULT hrFilter;
220         DWORD   n;
221
222         TRACE("(%p)->()\n",This);
223
224         EnterCriticalSection( &This->m_csFilters );
225
226         for ( n = 0; n < This->m_cActiveFilters; n++ )
227         {
228                 if ( This->m_pActiveFilters[n].pSeeking != NULL )
229                 {
230                         hrFilter = IMediaSeeking_GetTimeFormat( This->m_pActiveFilters[n].pSeeking, pidFormat );
231                         if ( hr == E_NOTIMPL )
232                         {
233                                 hr = hrFilter;
234                         }
235                         else
236                         if ( hrFilter != E_NOTIMPL )
237                         {
238                                 if ( SUCCEEDED(hr) )
239                                         hr = hrFilter;
240                         }
241                 }
242         }
243
244         LeaveCriticalSection( &This->m_csFilters );
245
246         return hr;
247 }
248
249 static HRESULT WINAPI
250 IMediaSeeking_fnIsUsingTimeFormat(IMediaSeeking* iface,const GUID* pidFormat)
251 {
252         CFilterGraph_THIS(iface,mediaseeking);
253         HRESULT hr = E_NOTIMPL;
254         HRESULT hrFilter;
255         DWORD   n;
256
257         TRACE("(%p)->()\n",This);
258
259         EnterCriticalSection( &This->m_csFilters );
260
261         for ( n = 0; n < This->m_cActiveFilters; n++ )
262         {
263                 if ( This->m_pActiveFilters[n].pSeeking != NULL )
264                 {
265                         hrFilter = IMediaSeeking_IsUsingTimeFormat( This->m_pActiveFilters[n].pSeeking, pidFormat );
266                         if ( hr == E_NOTIMPL )
267                         {
268                                 hr = hrFilter;
269                         }
270                         else
271                         if ( hrFilter != E_NOTIMPL )
272                         {
273                                 if ( SUCCEEDED(hr) )
274                                         hr = hrFilter;
275                         }
276                 }
277         }
278
279         LeaveCriticalSection( &This->m_csFilters );
280
281         return hr;
282 }
283
284 static HRESULT WINAPI
285 IMediaSeeking_fnSetTimeFormat(IMediaSeeking* iface,const GUID* pidFormat)
286 {
287         CFilterGraph_THIS(iface,mediaseeking);
288         HRESULT hr = E_NOTIMPL;
289         HRESULT hrFilter;
290         DWORD   n;
291
292         TRACE("(%p)->()\n",This);
293
294         EnterCriticalSection( &This->m_csFilters );
295
296         for ( n = 0; n < This->m_cActiveFilters; n++ )
297         {
298                 if ( This->m_pActiveFilters[n].pSeeking != NULL )
299                 {
300                         hrFilter = IMediaSeeking_SetTimeFormat( This->m_pActiveFilters[n].pSeeking, pidFormat );
301                         if ( hr == E_NOTIMPL )
302                         {
303                                 hr = hrFilter;
304                         }
305                         else
306                         if ( hrFilter != E_NOTIMPL )
307                         {
308                                 if ( SUCCEEDED(hr) )
309                                         hr = hrFilter;
310                         }
311                 }
312         }
313
314         LeaveCriticalSection( &This->m_csFilters );
315
316         return hr;
317 }
318
319 static HRESULT WINAPI
320 IMediaSeeking_fnGetDuration(IMediaSeeking* iface,LONGLONG* pllDuration)
321 {
322         CFilterGraph_THIS(iface,mediaseeking);
323         HRESULT hr = E_NOTIMPL;
324         HRESULT hrFilter;
325         DWORD   n;
326
327         TRACE("(%p)->()\n",This);
328
329         EnterCriticalSection( &This->m_csFilters );
330
331         for ( n = 0; n < This->m_cActiveFilters; n++ )
332         {
333                 if ( This->m_pActiveFilters[n].pSeeking != NULL )
334                 {
335                         hrFilter = IMediaSeeking_GetDuration( This->m_pActiveFilters[n].pSeeking, pllDuration );
336                         if ( hr == E_NOTIMPL )
337                         {
338                                 hr = hrFilter;
339                         }
340                         else
341                         if ( hrFilter != E_NOTIMPL )
342                         {
343                                 if ( SUCCEEDED(hr) )
344                                         hr = hrFilter;
345                         }
346                 }
347         }
348
349         LeaveCriticalSection( &This->m_csFilters );
350
351         return hr;
352 }
353
354 static HRESULT WINAPI
355 IMediaSeeking_fnGetStopPosition(IMediaSeeking* iface,LONGLONG* pllPos)
356 {
357         CFilterGraph_THIS(iface,mediaseeking);
358         HRESULT hr = E_NOTIMPL;
359         HRESULT hrFilter;
360         DWORD   n;
361
362         TRACE("(%p)->()\n",This);
363
364         EnterCriticalSection( &This->m_csFilters );
365
366         for ( n = 0; n < This->m_cActiveFilters; n++ )
367         {
368                 if ( This->m_pActiveFilters[n].pSeeking != NULL )
369                 {
370                         hrFilter = IMediaSeeking_GetStopPosition( This->m_pActiveFilters[n].pSeeking, pllPos );
371                         if ( hr == E_NOTIMPL )
372                         {
373                                 hr = hrFilter;
374                         }
375                         else
376                         if ( hrFilter != E_NOTIMPL )
377                         {
378                                 if ( SUCCEEDED(hr) )
379                                         hr = hrFilter;
380                         }
381                 }
382         }
383
384         LeaveCriticalSection( &This->m_csFilters );
385
386         return hr;
387 }
388
389 static HRESULT WINAPI
390 IMediaSeeking_fnGetCurrentPosition(IMediaSeeking* iface,LONGLONG* pllPos)
391 {
392         CFilterGraph_THIS(iface,mediaseeking);
393         HRESULT hr = E_NOTIMPL;
394         HRESULT hrFilter;
395         DWORD   n;
396
397         TRACE("(%p)->()\n",This);
398
399         EnterCriticalSection( &This->m_csFilters );
400
401         for ( n = 0; n < This->m_cActiveFilters; n++ )
402         {
403                 if ( This->m_pActiveFilters[n].pSeeking != NULL )
404                 {
405                         hrFilter = IMediaSeeking_GetCurrentPosition( This->m_pActiveFilters[n].pSeeking, pllPos );
406                         if ( hr == E_NOTIMPL )
407                         {
408                                 hr = hrFilter;
409                         }
410                         else
411                         if ( hrFilter != E_NOTIMPL )
412                         {
413                                 if ( SUCCEEDED(hr) )
414                                         hr = hrFilter;
415                         }
416                 }
417         }
418
419         LeaveCriticalSection( &This->m_csFilters );
420
421         return hr;
422 }
423
424 static HRESULT WINAPI
425 IMediaSeeking_fnConvertTimeFormat(IMediaSeeking* iface,LONGLONG* pllOut,const GUID* pidFmtOut,LONGLONG llIn,const GUID* pidFmtIn)
426 {
427         CFilterGraph_THIS(iface,mediaseeking);
428         HRESULT hr = E_NOTIMPL;
429         HRESULT hrFilter;
430         DWORD   n;
431
432         TRACE("(%p)->()\n",This);
433
434         EnterCriticalSection( &This->m_csFilters );
435
436         for ( n = 0; n < This->m_cActiveFilters; n++ )
437         {
438                 if ( This->m_pActiveFilters[n].pSeeking != NULL )
439                 {
440                         hrFilter = IMediaSeeking_ConvertTimeFormat( This->m_pActiveFilters[n].pSeeking, pllOut, pidFmtOut, llIn, pidFmtIn );
441                         if ( hr == E_NOTIMPL )
442                         {
443                                 hr = hrFilter;
444                         }
445                         else
446                         if ( hrFilter != E_NOTIMPL )
447                         {
448                                 if ( SUCCEEDED(hr) )
449                                         hr = hrFilter;
450                         }
451                 }
452         }
453
454         LeaveCriticalSection( &This->m_csFilters );
455
456         return hr;
457 }
458
459 static HRESULT WINAPI
460 IMediaSeeking_fnSetPositions(IMediaSeeking* iface,LONGLONG* pllCur,DWORD dwCurFlags,LONGLONG* pllStop,DWORD dwStopFlags)
461 {
462         CFilterGraph_THIS(iface,mediaseeking);
463         HRESULT hr = E_NOTIMPL;
464         HRESULT hrFilter;
465         DWORD   n;
466
467         TRACE("(%p)->()\n",This);
468
469         EnterCriticalSection( &This->m_csFilters );
470
471         for ( n = 0; n < This->m_cActiveFilters; n++ )
472         {
473                 if ( This->m_pActiveFilters[n].pSeeking != NULL )
474                 {
475                         hrFilter = IMediaSeeking_SetPositions( This->m_pActiveFilters[n].pSeeking, pllCur, dwCurFlags, pllStop, dwStopFlags );
476                         if ( hr == E_NOTIMPL )
477                         {
478                                 hr = hrFilter;
479                         }
480                         else
481                         if ( hrFilter != E_NOTIMPL )
482                         {
483                                 if ( SUCCEEDED(hr) )
484                                         hr = hrFilter;
485                         }
486                 }
487         }
488
489         LeaveCriticalSection( &This->m_csFilters );
490
491         return hr;
492 }
493
494 static HRESULT WINAPI
495 IMediaSeeking_fnGetPositions(IMediaSeeking* iface,LONGLONG* pllCur,LONGLONG* pllStop)
496 {
497         CFilterGraph_THIS(iface,mediaseeking);
498         HRESULT hr = E_NOTIMPL;
499         HRESULT hrFilter;
500         DWORD   n;
501
502         TRACE("(%p)->()\n",This);
503
504         EnterCriticalSection( &This->m_csFilters );
505
506         for ( n = 0; n < This->m_cActiveFilters; n++ )
507         {
508                 if ( This->m_pActiveFilters[n].pSeeking != NULL )
509                 {
510                         hrFilter = IMediaSeeking_GetPositions( This->m_pActiveFilters[n].pSeeking, pllCur, pllStop );
511                         if ( hr == E_NOTIMPL )
512                         {
513                                 hr = hrFilter;
514                         }
515                         else
516                         if ( hrFilter != E_NOTIMPL )
517                         {
518                                 if ( SUCCEEDED(hr) )
519                                         hr = hrFilter;
520                         }
521                 }
522         }
523
524         LeaveCriticalSection( &This->m_csFilters );
525
526         return hr;
527 }
528
529 static HRESULT WINAPI
530 IMediaSeeking_fnGetAvailable(IMediaSeeking* iface,LONGLONG* pllFirst,LONGLONG* pllLast)
531 {
532         CFilterGraph_THIS(iface,mediaseeking);
533         HRESULT hr = E_NOTIMPL;
534         HRESULT hrFilter;
535         DWORD   n;
536
537         TRACE("(%p)->()\n",This);
538
539         EnterCriticalSection( &This->m_csFilters );
540
541         for ( n = 0; n < This->m_cActiveFilters; n++ )
542         {
543                 if ( This->m_pActiveFilters[n].pSeeking != NULL )
544                 {
545                         hrFilter = IMediaSeeking_GetAvailable( This->m_pActiveFilters[n].pSeeking, pllFirst, pllLast );
546                         if ( hr == E_NOTIMPL )
547                         {
548                                 hr = hrFilter;
549                         }
550                         else
551                         if ( hrFilter != E_NOTIMPL )
552                         {
553                                 if ( SUCCEEDED(hr) )
554                                         hr = hrFilter;
555                         }
556                 }
557         }
558
559         LeaveCriticalSection( &This->m_csFilters );
560
561         return hr;
562 }
563
564 static HRESULT WINAPI
565 IMediaSeeking_fnSetRate(IMediaSeeking* iface,double dblRate)
566 {
567         CFilterGraph_THIS(iface,mediaseeking);
568         HRESULT hr = E_NOTIMPL;
569         HRESULT hrFilter;
570         DWORD   n;
571
572         TRACE("(%p)->()\n",This);
573
574         EnterCriticalSection( &This->m_csFilters );
575
576         for ( n = 0; n < This->m_cActiveFilters; n++ )
577         {
578                 if ( This->m_pActiveFilters[n].pSeeking != NULL )
579                 {
580                         hrFilter = IMediaSeeking_SetRate( This->m_pActiveFilters[n].pSeeking, dblRate );
581                         if ( hr == E_NOTIMPL )
582                         {
583                                 hr = hrFilter;
584                         }
585                         else
586                         if ( hrFilter != E_NOTIMPL )
587                         {
588                                 if ( SUCCEEDED(hr) )
589                                         hr = hrFilter;
590                         }
591                 }
592         }
593
594         LeaveCriticalSection( &This->m_csFilters );
595
596         return hr;
597 }
598
599 static HRESULT WINAPI
600 IMediaSeeking_fnGetRate(IMediaSeeking* iface,double* pdblRate)
601 {
602         CFilterGraph_THIS(iface,mediaseeking);
603         HRESULT hr = E_NOTIMPL;
604         HRESULT hrFilter;
605         DWORD   n;
606
607         TRACE("(%p)->()\n",This);
608
609         EnterCriticalSection( &This->m_csFilters );
610
611         for ( n = 0; n < This->m_cActiveFilters; n++ )
612         {
613                 if ( This->m_pActiveFilters[n].pSeeking != NULL )
614                 {
615                         hrFilter = IMediaSeeking_GetRate( This->m_pActiveFilters[n].pSeeking, pdblRate );
616                         if ( hr == E_NOTIMPL )
617                         {
618                                 hr = hrFilter;
619                         }
620                         else
621                         if ( hrFilter != E_NOTIMPL )
622                         {
623                                 if ( SUCCEEDED(hr) )
624                                         hr = hrFilter;
625                         }
626                 }
627         }
628
629         LeaveCriticalSection( &This->m_csFilters );
630
631         return hr;
632 }
633
634 static HRESULT WINAPI
635 IMediaSeeking_fnGetPreroll(IMediaSeeking* iface,LONGLONG* pllPreroll)
636 {
637         CFilterGraph_THIS(iface,mediaseeking);
638         HRESULT hr = E_NOTIMPL;
639         HRESULT hrFilter;
640         DWORD   n;
641
642         TRACE("(%p)->()\n",This);
643
644         EnterCriticalSection( &This->m_csFilters );
645
646         for ( n = 0; n < This->m_cActiveFilters; n++ )
647         {
648                 if ( This->m_pActiveFilters[n].pSeeking != NULL )
649                 {
650                         hrFilter = IMediaSeeking_GetPreroll( This->m_pActiveFilters[n].pSeeking, pllPreroll );
651                         if ( hr == E_NOTIMPL )
652                         {
653                                 hr = hrFilter;
654                         }
655                         else
656                         if ( hrFilter != E_NOTIMPL )
657                         {
658                                 if ( SUCCEEDED(hr) )
659                                         hr = hrFilter;
660                         }
661                 }
662         }
663
664         LeaveCriticalSection( &This->m_csFilters );
665
666         return hr;
667 }
668
669
670
671
672 static ICOM_VTABLE(IMediaSeeking) imediaseeking =
673 {
674         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
675         /* IUnknown fields */
676         IMediaSeeking_fnQueryInterface,
677         IMediaSeeking_fnAddRef,
678         IMediaSeeking_fnRelease,
679         /* IMediaSeeking fields */
680         IMediaSeeking_fnGetCapabilities,
681         IMediaSeeking_fnCheckCapabilities,
682         IMediaSeeking_fnIsFormatSupported,
683         IMediaSeeking_fnQueryPreferredFormat,
684         IMediaSeeking_fnGetTimeFormat,
685         IMediaSeeking_fnIsUsingTimeFormat,
686         IMediaSeeking_fnSetTimeFormat,
687         IMediaSeeking_fnGetDuration,
688         IMediaSeeking_fnGetStopPosition,
689         IMediaSeeking_fnGetCurrentPosition,
690         IMediaSeeking_fnConvertTimeFormat,
691         IMediaSeeking_fnSetPositions,
692         IMediaSeeking_fnGetPositions,
693         IMediaSeeking_fnGetAvailable,
694         IMediaSeeking_fnSetRate,
695         IMediaSeeking_fnGetRate,
696         IMediaSeeking_fnGetPreroll,
697 };
698
699 HRESULT CFilterGraph_InitIMediaSeeking( CFilterGraph* pfg )
700 {
701         TRACE("(%p)\n",pfg);
702         ICOM_VTBL(&pfg->mediaseeking) = &imediaseeking;
703
704         return NOERROR;
705 }
706
707 void CFilterGraph_UninitIMediaSeeking( CFilterGraph* pfg )
708 {
709         TRACE("(%p)\n",pfg);
710 }