Update shell xxxAW wrapper prototypes for fixed SHLWAPI functions.
[wine] / dlls / quartz / vidren.c
1 /*
2  * Implements CLSID_VideoRenderer.
3  *
4  * Copyright (C) Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
5  *
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.
10  *
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.
15  *
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * FIXME - use clock
21  */
22
23 #include "config.h"
24
25 #include <stdlib.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "winuser.h"
30 #include "winerror.h"
31 #include "mmsystem.h"
32 #include "strmif.h"
33 #include "control.h"
34 #include "vfwmsgs.h"
35 #include "uuids.h"
36 #include "amvideo.h"
37 #include "evcode.h"
38
39 #include "wine/debug.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
41
42 #include "quartz_private.h"
43 #include "vidren.h"
44 #include "seekpass.h"
45
46
47 static const WCHAR QUARTZ_VideoRenderer_Name[] =
48 { 'V','i','d','e','o',' ','R','e','n','d','e','r','e','r',0 };
49 static const WCHAR QUARTZ_VideoRendererPin_Name[] =
50 { 'I','n',0 };
51
52 #define VIDRENMSG_UPDATE        (WM_APP+0)
53 #define VIDRENMSG_ENDTHREAD     (WM_APP+1)
54
55 static const CHAR VIDREN_szWndClass[] = "Wine_VideoRenderer";
56 static const CHAR VIDREN_szWndName[] = "Wine Video Renderer";
57
58
59
60
61 static void VIDREN_OnPaint( CVideoRendererImpl* This, HWND hwnd )
62 {
63         PAINTSTRUCT ps;
64         const VIDEOINFOHEADER* pinfo;
65         const AM_MEDIA_TYPE* pmt;
66
67         TRACE("(%p,%08x)\n",This,hwnd);
68
69         if ( !BeginPaint( hwnd, &ps ) )
70                 return;
71
72         pmt = This->pPin->pin.pmtConn;
73         if ( (!This->m_bSampleIsValid) || pmt == NULL )
74                 goto err;
75
76         pinfo = (const VIDEOINFOHEADER*)pmt->pbFormat;
77
78         StretchDIBits(
79                 ps.hdc,
80                 0, 0,
81                 abs(pinfo->bmiHeader.biWidth), abs(pinfo->bmiHeader.biHeight),
82                 0, 0,
83                 abs(pinfo->bmiHeader.biWidth), abs(pinfo->bmiHeader.biHeight),
84                 This->m_pSampleData, (BITMAPINFO*)(&pinfo->bmiHeader),
85                 DIB_RGB_COLORS, SRCCOPY );
86
87 err:
88         EndPaint( hwnd, &ps );
89 }
90
91 static void VIDREN_OnQueryNewPalette( CVideoRendererImpl* This, HWND hwnd )
92 {
93         FIXME("(%p,%08x)\n",This,hwnd);
94 }
95
96 static void VIDREN_OnUpdate( CVideoRendererImpl* This, HWND hwnd )
97 {
98         MSG     msg;
99
100         TRACE("(%p,%08x)\n",This,hwnd);
101
102         InvalidateRect(hwnd,NULL,FALSE);
103         UpdateWindow(hwnd);
104
105         /* FIXME */
106         while ( PeekMessageA(&msg,hwnd,
107                 VIDRENMSG_UPDATE,VIDRENMSG_UPDATE,
108                 PM_REMOVE) != FALSE )
109         {
110                 /* discard this message. */
111         }
112 }
113
114
115 static LRESULT CALLBACK
116 VIDREN_WndProc(
117         HWND hwnd, UINT message,
118         WPARAM wParam, LPARAM lParam )
119 {
120         CVideoRendererImpl*     This = (CVideoRendererImpl*)
121                 GetWindowLongA( hwnd, 0L );
122
123         TRACE("(%p) - %u/%u/%ld\n",This,message,wParam,lParam);
124
125         if ( message == WM_NCCREATE )
126         {
127                 This = (CVideoRendererImpl*)(((CREATESTRUCTA*)lParam)->lpCreateParams);
128                 SetWindowLongA( hwnd, 0L, (LONG)This );
129                 This->m_hwnd = hwnd;
130         }
131
132         if ( message == WM_NCDESTROY )
133         {
134                 PostQuitMessage(0);
135                 This->m_hwnd = (HWND)NULL;
136                 SetWindowLongA( hwnd, 0L, (LONG)NULL );
137                 This = NULL;
138         }
139
140         if ( This != NULL )
141         {
142                 switch ( message )
143                 {
144                 case WM_PAINT:
145                         TRACE("WM_PAINT begin\n");
146                         EnterCriticalSection( &This->m_csReceive );
147                         VIDREN_OnPaint( This, hwnd );
148                         LeaveCriticalSection( &This->m_csReceive );
149                         TRACE("WM_PAINT end\n");
150                         return 0;
151                 case WM_CLOSE:
152                         ShowWindow( hwnd, SW_HIDE );
153                         return 0;
154                 case WM_PALETTECHANGED:
155                         if ( hwnd == (HWND)wParam )
156                                 break;
157                         /* fall through */
158                 case WM_QUERYNEWPALETTE:
159                         VIDREN_OnQueryNewPalette( This, hwnd );
160                         break;
161                 case VIDRENMSG_UPDATE:
162                         VIDREN_OnUpdate( This, hwnd );
163                         return 0;
164                 case VIDRENMSG_ENDTHREAD:
165                         DestroyWindow(hwnd);
166                         return 0;
167                 default:
168                         break;
169                 }
170         }
171
172         return DefWindowProcA( hwnd, message, wParam, lParam );
173 }
174
175 static BOOL VIDREN_Register( HINSTANCE hInst )
176 {
177         WNDCLASSA       wc;
178         ATOM    atom;
179
180         wc.style = 0;
181         wc.lpfnWndProc = VIDREN_WndProc;
182         wc.cbClsExtra = 0;
183         wc.cbWndExtra = sizeof(LONG);
184         wc.hInstance = hInst;
185         wc.hIcon = LoadIconA((HINSTANCE)NULL,IDI_WINLOGOA);
186         wc.hCursor = LoadCursorA((HINSTANCE)NULL,IDC_ARROWA);
187         wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
188         wc.lpszMenuName = NULL;
189         wc.lpszClassName = VIDREN_szWndClass;
190
191         atom = RegisterClassA( &wc );
192         if ( atom != (ATOM)0 )
193                 return TRUE;
194
195         /* FIXME */
196         return FALSE;
197 }
198
199 static HWND VIDREN_Create( HWND hwndOwner, CVideoRendererImpl* This )
200 {
201         HINSTANCE hInst = (HINSTANCE)GetModuleHandleA(NULL);
202         const VIDEOINFOHEADER* pinfo;
203         DWORD   dwExStyle = 0;
204         DWORD   dwStyle = WS_POPUP|WS_CAPTION|WS_CLIPCHILDREN;
205         RECT    rcWnd;
206         HWND    hwnd;
207
208         if ( !VIDREN_Register( hInst ) )
209                 return (HWND)NULL;
210
211         pinfo = (const VIDEOINFOHEADER*)This->pPin->pin.pmtConn->pbFormat;
212
213         TRACE("width %ld, height %ld\n", pinfo->bmiHeader.biWidth, pinfo->bmiHeader.biHeight);
214
215         rcWnd.left = 0;
216         rcWnd.top = 0;
217         rcWnd.right = pinfo->bmiHeader.biWidth;
218         rcWnd.bottom = abs(pinfo->bmiHeader.biHeight);
219         AdjustWindowRectEx( &rcWnd, dwStyle, FALSE, dwExStyle );
220
221         TRACE("window width %d,height %d\n",
222                 rcWnd.right-rcWnd.left,rcWnd.bottom-rcWnd.top);
223
224         hwnd = CreateWindowExA(
225                 dwExStyle,
226                 VIDREN_szWndClass, VIDREN_szWndName,
227                 dwStyle,
228                 100,100, /* FIXME */
229                 rcWnd.right-rcWnd.left, rcWnd.bottom-rcWnd.top,
230                 hwndOwner, (HMENU)NULL,
231                 hInst, (LPVOID)This );
232         if ( hwnd != (HWND)NULL )
233                 ShowWindow(hwnd,SW_SHOW);
234
235         return hwnd;
236 }
237
238 static DWORD WINAPI VIDREN_ThreadEntry( LPVOID pv )
239 {
240         CVideoRendererImpl*     This = (CVideoRendererImpl*)pv;
241         MSG     msg;
242
243         TRACE("(%p)\n",This);
244         if ( !VIDREN_Create( (HWND)NULL, This ) )
245                 return 0;
246         TRACE("VIDREN_Create succeeded\n");
247
248         SetEvent( This->m_hEventInit );
249         TRACE("Enter message loop\n");
250
251         while ( GetMessageA(&msg,(HWND)NULL,0,0) )
252         {
253                 TranslateMessage(&msg);
254                 DispatchMessageA(&msg);
255         }
256
257         return 0;
258 }
259
260 static HRESULT VIDREN_StartThread( CVideoRendererImpl* This )
261 {
262         DWORD dwRes;
263         DWORD dwThreadId;
264         HANDLE  hEvents[2];
265
266         if ( This->m_hEventInit != (HANDLE)NULL ||
267                  This->m_hwnd != (HWND)NULL ||
268                  This->m_hThread != (HANDLE)NULL ||
269                  This->pPin->pin.pmtConn == NULL )
270                 return E_UNEXPECTED;
271
272         This->m_hEventInit = CreateEventA(NULL,TRUE,FALSE,NULL);
273         if ( This->m_hEventInit == (HANDLE)NULL )
274                 return E_OUTOFMEMORY;
275
276         This->m_hThread = CreateThread(
277                 NULL, 0,
278                 VIDREN_ThreadEntry,
279                 (LPVOID)This,
280                 0, &dwThreadId );
281         if ( This->m_hThread == (HANDLE)NULL )
282                 return E_FAIL;
283
284         hEvents[0] = This->m_hEventInit;
285         hEvents[1] = This->m_hThread;
286
287         dwRes = WaitForMultipleObjects(2,hEvents,FALSE,INFINITE);
288         if ( dwRes != WAIT_OBJECT_0 )
289                 return E_FAIL;
290
291         return S_OK;
292 }
293
294 static void VIDREN_EndThread( CVideoRendererImpl* This )
295 {
296         if ( This->m_hwnd != (HWND)NULL )
297                 PostMessageA( This->m_hwnd, VIDRENMSG_ENDTHREAD, 0, 0 );
298
299         if ( This->m_hThread != (HANDLE)NULL )
300         {
301                 WaitForSingleObject( This->m_hThread, INFINITE );
302                 CloseHandle( This->m_hThread );
303                 This->m_hThread = (HANDLE)NULL;
304         }
305         if ( This->m_hEventInit != (HANDLE)NULL )
306         {
307                 CloseHandle( This->m_hEventInit );
308                 This->m_hEventInit = (HANDLE)NULL;
309         }
310 }
311
312
313
314 /***************************************************************************
315  *
316  *      CVideoRendererImpl methods
317  *
318  */
319
320 static HRESULT CVideoRendererImpl_OnActive( CBaseFilterImpl* pImpl )
321 {
322         CVideoRendererImpl_THIS(pImpl,basefilter);
323
324         FIXME( "(%p)\n", This );
325
326         This->m_bSampleIsValid = FALSE;
327
328         return NOERROR;
329 }
330
331 static HRESULT CVideoRendererImpl_OnInactive( CBaseFilterImpl* pImpl )
332 {
333         CVideoRendererImpl_THIS(pImpl,basefilter);
334
335         FIXME( "(%p)\n", This );
336
337         EnterCriticalSection( &This->m_csReceive );
338         This->m_bSampleIsValid = FALSE;
339         LeaveCriticalSection( &This->m_csReceive );
340
341         return NOERROR;
342 }
343
344 static const CBaseFilterHandlers filterhandlers =
345 {
346         CVideoRendererImpl_OnActive, /* pOnActive */
347         CVideoRendererImpl_OnInactive, /* pOnInactive */
348         NULL, /* pOnStop */
349 };
350
351 /***************************************************************************
352  *
353  *      CVideoRendererPinImpl methods
354  *
355  */
356
357 static HRESULT CVideoRendererPinImpl_OnPreConnect( CPinBaseImpl* pImpl, IPin* pPin )
358 {
359         CVideoRendererPinImpl_THIS(pImpl,pin);
360
361         TRACE("(%p,%p)\n",This,pPin);
362
363         return NOERROR;
364 }
365
366 static HRESULT CVideoRendererPinImpl_OnPostConnect( CPinBaseImpl* pImpl, IPin* pPin )
367 {
368         CVideoRendererPinImpl_THIS(pImpl,pin);
369         const VIDEOINFOHEADER* pinfo;
370         HRESULT hr;
371
372         TRACE("(%p,%p)\n",This,pPin);
373
374         if ( This->pRender->m_pSampleData != NULL )
375         {
376                 QUARTZ_FreeMem(This->pRender->m_pSampleData);
377                 This->pRender->m_pSampleData = NULL;
378         }
379         This->pRender->m_cbSampleData = 0;
380         This->pRender->m_bSampleIsValid = FALSE;
381
382         pinfo = (const VIDEOINFOHEADER*)This->pin.pmtConn->pbFormat;
383         if ( pinfo == NULL )
384                 return E_FAIL;
385
386         This->pRender->m_bSampleIsValid = FALSE;
387         This->pRender->m_cbSampleData = DIBSIZE(pinfo->bmiHeader);
388         This->pRender->m_pSampleData = (BYTE*)QUARTZ_AllocMem(This->pRender->m_cbSampleData);
389         if ( This->pRender->m_pSampleData == NULL )
390                 return E_OUTOFMEMORY;
391
392         hr = VIDREN_StartThread(This->pRender);
393         if ( FAILED(hr) )
394                 return hr;
395
396         return NOERROR;
397 }
398
399 static HRESULT CVideoRendererPinImpl_OnDisconnect( CPinBaseImpl* pImpl )
400 {
401         CVideoRendererPinImpl_THIS(pImpl,pin);
402
403         TRACE("(%p)\n",This);
404
405         VIDREN_EndThread(This->pRender);
406
407         if ( This->pRender->m_pSampleData != NULL )
408         {
409                 QUARTZ_FreeMem(This->pRender->m_pSampleData);
410                 This->pRender->m_pSampleData = NULL;
411         }
412         This->pRender->m_cbSampleData = 0;
413         This->pRender->m_bSampleIsValid = FALSE;
414
415         if ( This->meminput.pAllocator != NULL )
416         {
417                 IMemAllocator_Decommit(This->meminput.pAllocator);
418                 IMemAllocator_Release(This->meminput.pAllocator);
419                 This->meminput.pAllocator = NULL;
420         }
421
422         return NOERROR;
423 }
424
425 static HRESULT CVideoRendererPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt )
426 {
427         CVideoRendererPinImpl_THIS(pImpl,pin);
428         const VIDEOINFOHEADER* pinfo;
429
430         TRACE("(%p,%p)\n",This,pmt);
431
432         if ( !IsEqualGUID( &pmt->majortype, &MEDIATYPE_Video ) )
433                 return E_FAIL;
434         if ( !IsEqualGUID( &pmt->formattype, &FORMAT_VideoInfo ) )
435                 return E_FAIL;
436         /*
437          * check subtype.
438          */
439         if ( !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_RGB555 ) &&
440              !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_RGB565 ) &&
441              !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_RGB24 ) &&
442              !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_RGB32 ) )
443                 return E_FAIL;
444
445         /****
446          *
447          *
448         if ( !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_RGB8 ) &&
449              !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_RGB555 ) &&
450              !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_RGB565 ) &&
451              !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_RGB24 ) &&
452              !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_RGB32 ) )
453                 return E_FAIL;
454          *
455          ****/
456
457         pinfo = (const VIDEOINFOHEADER*)pmt->pbFormat;
458         if ( pinfo == NULL ||
459                  pinfo->bmiHeader.biSize < sizeof(BITMAPINFOHEADER) ||
460                  pinfo->bmiHeader.biWidth <= 0 ||
461                  pinfo->bmiHeader.biHeight == 0 ||
462                  pinfo->bmiHeader.biPlanes != 1 ||
463                  pinfo->bmiHeader.biCompression != 0 )
464                 return E_FAIL;
465
466         return NOERROR;
467 }
468
469 static HRESULT CVideoRendererPinImpl_Receive( CPinBaseImpl* pImpl, IMediaSample* pSample )
470 {
471         CVideoRendererPinImpl_THIS(pImpl,pin);
472         HWND hwnd;
473         BYTE*   pData = NULL;
474         LONG    lLength;
475         HRESULT hr;
476
477         TRACE( "(%p,%p)\n",This,pSample );
478
479         hwnd = This->pRender->m_hwnd;
480         if ( hwnd == (HWND)NULL ||
481                  This->pRender->m_hThread == (HWND)NULL )
482                 return E_UNEXPECTED;
483         if ( This->pRender->m_fInFlush )
484                 return S_FALSE;
485         if ( pSample == NULL )
486                 return E_POINTER;
487
488         /* FIXME - wait/skip/qualitycontrol */
489         
490
491         /* duplicate this sample. */
492         hr = IMediaSample_GetPointer(pSample,&pData);
493         if ( FAILED(hr) )
494                 return hr;
495         lLength = (LONG)IMediaSample_GetActualDataLength(pSample);
496         if ( lLength <= 0 || (lLength < (LONG)This->pRender->m_cbSampleData) )
497         {
498                 ERR( "invalid length: %ld\n", lLength );
499                 return NOERROR;
500         }
501
502         memcpy(This->pRender->m_pSampleData,pData,lLength);
503         This->pRender->m_bSampleIsValid = TRUE;
504         PostMessageA( hwnd, VIDRENMSG_UPDATE, 0, 0 );
505
506         return NOERROR;
507 }
508
509 static HRESULT CVideoRendererPinImpl_ReceiveCanBlock( CPinBaseImpl* pImpl )
510 {
511         CVideoRendererPinImpl_THIS(pImpl,pin);
512
513         TRACE( "(%p)\n", This );
514
515         /* might block. */
516         return S_OK;
517 }
518
519 static HRESULT CVideoRendererPinImpl_EndOfStream( CPinBaseImpl* pImpl )
520 {
521         CVideoRendererPinImpl_THIS(pImpl,pin);
522
523         FIXME( "(%p)\n", This );
524
525         This->pRender->m_fInFlush = FALSE;
526
527         /* FIXME - don't notify twice until stopped or seeked. */
528         return CBaseFilterImpl_MediaEventNotify(
529                 &This->pRender->basefilter, EC_COMPLETE,
530                 (LONG_PTR)S_OK, (LONG_PTR)(IBaseFilter*)(This->pRender) );
531 }
532
533 static HRESULT CVideoRendererPinImpl_BeginFlush( CPinBaseImpl* pImpl )
534 {
535         CVideoRendererPinImpl_THIS(pImpl,pin);
536
537         FIXME( "(%p)\n", This );
538
539         This->pRender->m_fInFlush = TRUE;
540         EnterCriticalSection( &This->pRender->m_csReceive );
541         This->pRender->m_bSampleIsValid = FALSE;
542         LeaveCriticalSection( &This->pRender->m_csReceive );
543
544         return NOERROR;
545 }
546
547 static HRESULT CVideoRendererPinImpl_EndFlush( CPinBaseImpl* pImpl )
548 {
549         CVideoRendererPinImpl_THIS(pImpl,pin);
550
551         FIXME( "(%p)\n", This );
552
553         This->pRender->m_fInFlush = FALSE;
554
555         return NOERROR;
556 }
557
558 static HRESULT CVideoRendererPinImpl_NewSegment( CPinBaseImpl* pImpl, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop, double rate )
559 {
560         CVideoRendererPinImpl_THIS(pImpl,pin);
561
562         FIXME( "(%p)\n", This );
563
564         This->pRender->m_fInFlush = FALSE;
565
566         return NOERROR;
567 }
568
569
570
571
572 static const CBasePinHandlers pinhandlers =
573 {
574         CVideoRendererPinImpl_OnPreConnect, /* pOnPreConnect */
575         CVideoRendererPinImpl_OnPostConnect, /* pOnPostConnect */
576         CVideoRendererPinImpl_OnDisconnect, /* pOnDisconnect */
577         CVideoRendererPinImpl_CheckMediaType, /* pCheckMediaType */
578         NULL, /* pQualityNotify */
579         CVideoRendererPinImpl_Receive, /* pReceive */
580         CVideoRendererPinImpl_ReceiveCanBlock, /* pReceiveCanBlock */
581         CVideoRendererPinImpl_EndOfStream, /* pEndOfStream */
582         CVideoRendererPinImpl_BeginFlush, /* pBeginFlush */
583         CVideoRendererPinImpl_EndFlush, /* pEndFlush */
584         CVideoRendererPinImpl_NewSegment, /* pNewSegment */
585 };
586
587
588 /***************************************************************************
589  *
590  *      new/delete CVideoRendererImpl
591  *
592  */
593
594 /* can I use offsetof safely? - FIXME? */
595 static QUARTZ_IFEntry FilterIFEntries[] =
596 {
597   { &IID_IPersist, offsetof(CVideoRendererImpl,basefilter)-offsetof(CVideoRendererImpl,unk) },
598   { &IID_IMediaFilter, offsetof(CVideoRendererImpl,basefilter)-offsetof(CVideoRendererImpl,unk) },
599   { &IID_IBaseFilter, offsetof(CVideoRendererImpl,basefilter)-offsetof(CVideoRendererImpl,unk) },
600   { &IID_IBasicVideo, offsetof(CVideoRendererImpl,basvid)-offsetof(CVideoRendererImpl,unk) },
601   { &IID_IBasicVideo2, offsetof(CVideoRendererImpl,basvid)-offsetof(CVideoRendererImpl,unk) },
602   { &IID_IVideoWindow, offsetof(CVideoRendererImpl,vidwin)-offsetof(CVideoRendererImpl,unk) },
603 };
604
605 static HRESULT CVideoRendererImpl_OnQueryInterface(
606         IUnknown* punk, const IID* piid, void** ppobj )
607 {
608         CVideoRendererImpl_THIS(punk,unk);
609
610         if ( This->pSeekPass == NULL )
611                 return E_NOINTERFACE;
612
613         if ( IsEqualGUID( &IID_IMediaPosition, piid ) ||
614                  IsEqualGUID( &IID_IMediaSeeking, piid ) )
615         {
616                 TRACE( "IMediaSeeking(or IMediaPosition) is queried\n" );
617                 return IUnknown_QueryInterface( (IUnknown*)(&This->pSeekPass->unk), piid, ppobj );
618         }
619
620         return E_NOINTERFACE;
621 }
622
623 static void QUARTZ_DestroyVideoRenderer(IUnknown* punk)
624 {
625         CVideoRendererImpl_THIS(punk,unk);
626
627         TRACE( "(%p)\n", This );
628         CVideoRendererImpl_OnInactive(&This->basefilter);
629         VIDREN_EndThread(This);
630
631         if ( This->pPin != NULL )
632         {
633                 IUnknown_Release(This->pPin->unk.punkControl);
634                 This->pPin = NULL;
635         }
636         if ( This->pSeekPass != NULL )
637         {
638                 IUnknown_Release((IUnknown*)&This->pSeekPass->unk);
639                 This->pSeekPass = NULL;
640         }
641
642         CVideoRendererImpl_UninitIBasicVideo2(This);
643         CVideoRendererImpl_UninitIVideoWindow(This);
644         CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
645
646         DeleteCriticalSection( &This->m_csReceive );
647 }
648
649 HRESULT QUARTZ_CreateVideoRenderer(IUnknown* punkOuter,void** ppobj)
650 {
651         CVideoRendererImpl*     This = NULL;
652         HRESULT hr;
653
654         TRACE("(%p,%p)\n",punkOuter,ppobj);
655
656         This = (CVideoRendererImpl*)
657                 QUARTZ_AllocObj( sizeof(CVideoRendererImpl) );
658         if ( This == NULL )
659                 return E_OUTOFMEMORY;
660         This->pSeekPass = NULL;
661         This->pPin = NULL;
662         This->m_fInFlush = FALSE;
663
664         This->m_hEventInit = (HANDLE)NULL;
665         This->m_hThread = (HANDLE)NULL;
666         This->m_hwnd = (HWND)NULL;
667         This->m_bSampleIsValid = FALSE;
668         This->m_pSampleData = NULL;
669         This->m_cbSampleData = 0;
670
671         QUARTZ_IUnkInit( &This->unk, punkOuter );
672         This->qiext.pNext = NULL;
673         This->qiext.pOnQueryInterface = &CVideoRendererImpl_OnQueryInterface;
674         QUARTZ_IUnkAddDelegation( &This->unk, &This->qiext );
675
676         hr = CBaseFilterImpl_InitIBaseFilter(
677                 &This->basefilter,
678                 This->unk.punkControl,
679                 &CLSID_VideoRenderer,
680                 QUARTZ_VideoRenderer_Name,
681                 &filterhandlers );
682         if ( SUCCEEDED(hr) )
683         {
684                 hr = CVideoRendererImpl_InitIBasicVideo2(This);
685                 if ( SUCCEEDED(hr) )
686                 {
687                         hr = CVideoRendererImpl_InitIVideoWindow(This);
688                         if ( FAILED(hr) )
689                         {
690                                 CVideoRendererImpl_UninitIBasicVideo2(This);
691                         }
692                 }
693                 if ( FAILED(hr) )
694                 {
695                         CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
696                 }
697         }
698
699         if ( FAILED(hr) )
700         {
701                 QUARTZ_FreeObj(This);
702                 return hr;
703         }
704
705         This->unk.pEntries = FilterIFEntries;
706         This->unk.dwEntries = sizeof(FilterIFEntries)/sizeof(FilterIFEntries[0]);
707         This->unk.pOnFinalRelease = QUARTZ_DestroyVideoRenderer;
708
709         InitializeCriticalSection( &This->m_csReceive );
710
711         hr = QUARTZ_CreateVideoRendererPin(
712                 This,
713                 &This->basefilter.csFilter,
714                 &This->m_csReceive,
715                 &This->pPin );
716         if ( SUCCEEDED(hr) )
717                 hr = QUARTZ_CompList_AddComp(
718                         This->basefilter.pInPins,
719                         (IUnknown*)&This->pPin->pin,
720                         NULL, 0 );
721         if ( SUCCEEDED(hr) )
722                 hr = QUARTZ_CreateSeekingPassThruInternal(
723                         (IUnknown*)&(This->unk), &This->pSeekPass,
724                         TRUE, (IPin*)&(This->pPin->pin) );
725
726         if ( FAILED(hr) )
727         {
728                 IUnknown_Release( This->unk.punkControl );
729                 return hr;
730         }
731
732         *ppobj = (void*)&(This->unk);
733
734         return S_OK;
735 }
736
737 /***************************************************************************
738  *
739  *      new/delete CVideoRendererPinImpl
740  *
741  */
742
743 /* can I use offsetof safely? - FIXME? */
744 static QUARTZ_IFEntry PinIFEntries[] =
745 {
746   { &IID_IPin, offsetof(CVideoRendererPinImpl,pin)-offsetof(CVideoRendererPinImpl,unk) },
747   { &IID_IMemInputPin, offsetof(CVideoRendererPinImpl,meminput)-offsetof(CVideoRendererPinImpl,unk) },
748 };
749
750 static void QUARTZ_DestroyVideoRendererPin(IUnknown* punk)
751 {
752         CVideoRendererPinImpl_THIS(punk,unk);
753
754         TRACE( "(%p)\n", This );
755
756         CPinBaseImpl_UninitIPin( &This->pin );
757         CMemInputPinBaseImpl_UninitIMemInputPin( &This->meminput );
758 }
759
760 HRESULT QUARTZ_CreateVideoRendererPin(
761         CVideoRendererImpl* pFilter,
762         CRITICAL_SECTION* pcsPin,
763         CRITICAL_SECTION* pcsPinReceive,
764         CVideoRendererPinImpl** ppPin)
765 {
766         CVideoRendererPinImpl*  This = NULL;
767         HRESULT hr;
768
769         TRACE("(%p,%p,%p,%p)\n",pFilter,pcsPin,pcsPinReceive,ppPin);
770
771         This = (CVideoRendererPinImpl*)
772                 QUARTZ_AllocObj( sizeof(CVideoRendererPinImpl) );
773         if ( This == NULL )
774                 return E_OUTOFMEMORY;
775
776         QUARTZ_IUnkInit( &This->unk, NULL );
777         This->pRender = pFilter;
778
779         hr = CPinBaseImpl_InitIPin(
780                 &This->pin,
781                 This->unk.punkControl,
782                 pcsPin, pcsPinReceive,
783                 &pFilter->basefilter,
784                 QUARTZ_VideoRendererPin_Name,
785                 FALSE,
786                 &pinhandlers );
787
788         if ( SUCCEEDED(hr) )
789         {
790                 hr = CMemInputPinBaseImpl_InitIMemInputPin(
791                         &This->meminput,
792                         This->unk.punkControl,
793                         &This->pin );
794                 if ( FAILED(hr) )
795                 {
796                         CPinBaseImpl_UninitIPin( &This->pin );
797                 }
798         }
799
800         if ( FAILED(hr) )
801         {
802                 QUARTZ_FreeObj(This);
803                 return hr;
804         }
805
806         This->unk.pEntries = PinIFEntries;
807         This->unk.dwEntries = sizeof(PinIFEntries)/sizeof(PinIFEntries[0]);
808         This->unk.pOnFinalRelease = QUARTZ_DestroyVideoRendererPin;
809
810         *ppPin = This;
811
812         TRACE("returned successfully.\n");
813
814         return S_OK;
815 }
816
817 /***************************************************************************
818  *
819  *      CVideoRendererImpl::IBasicVideo2
820  *
821  */
822
823
824 static HRESULT WINAPI
825 IBasicVideo2_fnQueryInterface(IBasicVideo2* iface,REFIID riid,void** ppobj)
826 {
827         CVideoRendererImpl_THIS(iface,basvid);
828
829         TRACE("(%p)->()\n",This);
830
831         return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
832 }
833
834 static ULONG WINAPI
835 IBasicVideo2_fnAddRef(IBasicVideo2* iface)
836 {
837         CVideoRendererImpl_THIS(iface,basvid);
838
839         TRACE("(%p)->()\n",This);
840
841         return IUnknown_AddRef(This->unk.punkControl);
842 }
843
844 static ULONG WINAPI
845 IBasicVideo2_fnRelease(IBasicVideo2* iface)
846 {
847         CVideoRendererImpl_THIS(iface,basvid);
848
849         TRACE("(%p)->()\n",This);
850
851         return IUnknown_Release(This->unk.punkControl);
852 }
853
854 static HRESULT WINAPI
855 IBasicVideo2_fnGetTypeInfoCount(IBasicVideo2* iface,UINT* pcTypeInfo)
856 {
857         CVideoRendererImpl_THIS(iface,basvid);
858
859         FIXME("(%p)->()\n",This);
860
861         return E_NOTIMPL;
862 }
863
864 static HRESULT WINAPI
865 IBasicVideo2_fnGetTypeInfo(IBasicVideo2* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
866 {
867         CVideoRendererImpl_THIS(iface,basvid);
868
869         FIXME("(%p)->()\n",This);
870
871         return E_NOTIMPL;
872 }
873
874 static HRESULT WINAPI
875 IBasicVideo2_fnGetIDsOfNames(IBasicVideo2* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
876 {
877         CVideoRendererImpl_THIS(iface,basvid);
878
879         FIXME("(%p)->()\n",This);
880
881         return E_NOTIMPL;
882 }
883
884 static HRESULT WINAPI
885 IBasicVideo2_fnInvoke(IBasicVideo2* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
886 {
887         CVideoRendererImpl_THIS(iface,basvid);
888
889         FIXME("(%p)->()\n",This);
890
891         return E_NOTIMPL;
892 }
893
894
895 static HRESULT WINAPI
896 IBasicVideo2_fnget_AvgTimePerFrame(IBasicVideo2* iface,REFTIME* prefTime)
897 {
898         CVideoRendererImpl_THIS(iface,basvid);
899
900         FIXME("(%p)->()\n",This);
901
902         return E_NOTIMPL;
903 }
904
905 static HRESULT WINAPI
906 IBasicVideo2_fnget_BitRate(IBasicVideo2* iface,long* plRate)
907 {
908         CVideoRendererImpl_THIS(iface,basvid);
909
910         FIXME("(%p)->()\n",This);
911
912         return E_NOTIMPL;
913 }
914
915 static HRESULT WINAPI
916 IBasicVideo2_fnget_BitErrorRate(IBasicVideo2* iface,long* plRate)
917 {
918         CVideoRendererImpl_THIS(iface,basvid);
919
920         FIXME("(%p)->()\n",This);
921
922         return E_NOTIMPL;
923 }
924
925 static HRESULT WINAPI
926 IBasicVideo2_fnget_VideoWidth(IBasicVideo2* iface,long* plWidth)
927 {
928         CVideoRendererImpl_THIS(iface,basvid);
929
930         FIXME("(%p)->()\n",This);
931
932         return E_NOTIMPL;
933 }
934
935 static HRESULT WINAPI
936 IBasicVideo2_fnget_VideoHeight(IBasicVideo2* iface,long* plHeight)
937 {
938         CVideoRendererImpl_THIS(iface,basvid);
939
940         FIXME("(%p)->()\n",This);
941
942         return E_NOTIMPL;
943 }
944
945 static HRESULT WINAPI
946 IBasicVideo2_fnput_SourceLeft(IBasicVideo2* iface,long lLeft)
947 {
948         CVideoRendererImpl_THIS(iface,basvid);
949
950         FIXME("(%p)->()\n",This);
951
952         return E_NOTIMPL;
953 }
954
955 static HRESULT WINAPI
956 IBasicVideo2_fnget_SourceLeft(IBasicVideo2* iface,long* plLeft)
957 {
958         CVideoRendererImpl_THIS(iface,basvid);
959
960         FIXME("(%p)->()\n",This);
961
962         return E_NOTIMPL;
963 }
964
965 static HRESULT WINAPI
966 IBasicVideo2_fnput_SourceWidth(IBasicVideo2* iface,long lWidth)
967 {
968         CVideoRendererImpl_THIS(iface,basvid);
969
970         FIXME("(%p)->()\n",This);
971
972         return E_NOTIMPL;
973 }
974
975 static HRESULT WINAPI
976 IBasicVideo2_fnget_SourceWidth(IBasicVideo2* iface,long* plWidth)
977 {
978         CVideoRendererImpl_THIS(iface,basvid);
979
980         FIXME("(%p)->()\n",This);
981
982         return E_NOTIMPL;
983 }
984
985 static HRESULT WINAPI
986 IBasicVideo2_fnput_SourceTop(IBasicVideo2* iface,long lTop)
987 {
988         CVideoRendererImpl_THIS(iface,basvid);
989
990         FIXME("(%p)->()\n",This);
991
992         return E_NOTIMPL;
993 }
994
995 static HRESULT WINAPI
996 IBasicVideo2_fnget_SourceTop(IBasicVideo2* iface,long* plTop)
997 {
998         CVideoRendererImpl_THIS(iface,basvid);
999
1000         FIXME("(%p)->()\n",This);
1001
1002         return E_NOTIMPL;
1003 }
1004
1005 static HRESULT WINAPI
1006 IBasicVideo2_fnput_SourceHeight(IBasicVideo2* iface,long lHeight)
1007 {
1008         CVideoRendererImpl_THIS(iface,basvid);
1009
1010         FIXME("(%p)->()\n",This);
1011
1012         return E_NOTIMPL;
1013 }
1014
1015 static HRESULT WINAPI
1016 IBasicVideo2_fnget_SourceHeight(IBasicVideo2* iface,long* plHeight)
1017 {
1018         CVideoRendererImpl_THIS(iface,basvid);
1019
1020         FIXME("(%p)->()\n",This);
1021
1022         return E_NOTIMPL;
1023 }
1024
1025 static HRESULT WINAPI
1026 IBasicVideo2_fnput_DestinationLeft(IBasicVideo2* iface,long lLeft)
1027 {
1028         CVideoRendererImpl_THIS(iface,basvid);
1029
1030         FIXME("(%p)->()\n",This);
1031
1032         return E_NOTIMPL;
1033 }
1034
1035 static HRESULT WINAPI
1036 IBasicVideo2_fnget_DestinationLeft(IBasicVideo2* iface,long* plLeft)
1037 {
1038         CVideoRendererImpl_THIS(iface,basvid);
1039
1040         FIXME("(%p)->()\n",This);
1041
1042         return E_NOTIMPL;
1043 }
1044
1045 static HRESULT WINAPI
1046 IBasicVideo2_fnput_DestinationWidth(IBasicVideo2* iface,long lWidth)
1047 {
1048         CVideoRendererImpl_THIS(iface,basvid);
1049
1050         FIXME("(%p)->()\n",This);
1051
1052         return E_NOTIMPL;
1053 }
1054
1055 static HRESULT WINAPI
1056 IBasicVideo2_fnget_DestinationWidth(IBasicVideo2* iface,long* plWidth)
1057 {
1058         CVideoRendererImpl_THIS(iface,basvid);
1059
1060         FIXME("(%p)->()\n",This);
1061
1062         return E_NOTIMPL;
1063 }
1064
1065 static HRESULT WINAPI
1066 IBasicVideo2_fnput_DestinationTop(IBasicVideo2* iface,long lTop)
1067 {
1068         CVideoRendererImpl_THIS(iface,basvid);
1069
1070         FIXME("(%p)->()\n",This);
1071
1072         return E_NOTIMPL;
1073 }
1074
1075 static HRESULT WINAPI
1076 IBasicVideo2_fnget_DestinationTop(IBasicVideo2* iface,long* plTop)
1077 {
1078         CVideoRendererImpl_THIS(iface,basvid);
1079
1080         FIXME("(%p)->()\n",This);
1081
1082         return E_NOTIMPL;
1083 }
1084
1085 static HRESULT WINAPI
1086 IBasicVideo2_fnput_DestinationHeight(IBasicVideo2* iface,long lHeight)
1087 {
1088         CVideoRendererImpl_THIS(iface,basvid);
1089
1090         FIXME("(%p)->()\n",This);
1091
1092         return E_NOTIMPL;
1093 }
1094
1095 static HRESULT WINAPI
1096 IBasicVideo2_fnget_DestinationHeight(IBasicVideo2* iface,long* plHeight)
1097 {
1098         CVideoRendererImpl_THIS(iface,basvid);
1099
1100         FIXME("(%p)->()\n",This);
1101
1102         return E_NOTIMPL;
1103 }
1104
1105 static HRESULT WINAPI
1106 IBasicVideo2_fnSetSourcePosition(IBasicVideo2* iface,long lLeft,long lTop,long lWidth,long lHeight)
1107 {
1108         CVideoRendererImpl_THIS(iface,basvid);
1109
1110         FIXME("(%p)->()\n",This);
1111
1112         return E_NOTIMPL;
1113 }
1114
1115 static HRESULT WINAPI
1116 IBasicVideo2_fnGetSourcePosition(IBasicVideo2* iface,long* plLeft,long* plTop,long* plWidth,long* plHeight)
1117 {
1118         CVideoRendererImpl_THIS(iface,basvid);
1119
1120         FIXME("(%p)->()\n",This);
1121
1122         return E_NOTIMPL;
1123 }
1124
1125 static HRESULT WINAPI
1126 IBasicVideo2_fnSetDefaultSourcePosition(IBasicVideo2* iface)
1127 {
1128         CVideoRendererImpl_THIS(iface,basvid);
1129
1130         FIXME("(%p)->()\n",This);
1131
1132         return E_NOTIMPL;
1133 }
1134
1135 static HRESULT WINAPI
1136 IBasicVideo2_fnSetDestinationPosition(IBasicVideo2* iface,long lLeft,long lTop,long lWidth,long lHeight)
1137 {
1138         CVideoRendererImpl_THIS(iface,basvid);
1139
1140         FIXME("(%p)->()\n",This);
1141
1142         return E_NOTIMPL;
1143 }
1144
1145 static HRESULT WINAPI
1146 IBasicVideo2_fnGetDestinationPosition(IBasicVideo2* iface,long* plLeft,long* plTop,long* plWidth,long* plHeight)
1147 {
1148         CVideoRendererImpl_THIS(iface,basvid);
1149
1150         FIXME("(%p)->()\n",This);
1151
1152         return E_NOTIMPL;
1153 }
1154
1155 static HRESULT WINAPI
1156 IBasicVideo2_fnSetDefaultDestinationPosition(IBasicVideo2* iface)
1157 {
1158         CVideoRendererImpl_THIS(iface,basvid);
1159
1160         FIXME("(%p)->()\n",This);
1161
1162         return E_NOTIMPL;
1163 }
1164
1165 static HRESULT WINAPI
1166 IBasicVideo2_fnGetVideoSize(IBasicVideo2* iface,long* plWidth,long* plHeight)
1167 {
1168         CVideoRendererImpl_THIS(iface,basvid);
1169
1170         FIXME("(%p)->()\n",This);
1171
1172         return E_NOTIMPL;
1173 }
1174
1175 static HRESULT WINAPI
1176 IBasicVideo2_fnGetVideoPaletteEntries(IBasicVideo2* iface,long lStart,long lCount,long* plRet,long* plPaletteEntry)
1177 {
1178         CVideoRendererImpl_THIS(iface,basvid);
1179
1180         FIXME("(%p)->()\n",This);
1181
1182         return E_NOTIMPL;
1183 }
1184
1185 static HRESULT WINAPI
1186 IBasicVideo2_fnGetCurrentImage(IBasicVideo2* iface,long* plBufferSize,long* plDIBBuffer)
1187 {
1188         CVideoRendererImpl_THIS(iface,basvid);
1189
1190         FIXME("(%p)->()\n",This);
1191
1192         return E_NOTIMPL;
1193 }
1194
1195 static HRESULT WINAPI
1196 IBasicVideo2_fnIsUsingDefaultSource(IBasicVideo2* iface)
1197 {
1198         CVideoRendererImpl_THIS(iface,basvid);
1199
1200         FIXME("(%p)->()\n",This);
1201
1202         return E_NOTIMPL;
1203 }
1204
1205 static HRESULT WINAPI
1206 IBasicVideo2_fnIsUsingDefaultDestination(IBasicVideo2* iface)
1207 {
1208         CVideoRendererImpl_THIS(iface,basvid);
1209
1210         FIXME("(%p)->()\n",This);
1211
1212         return E_NOTIMPL;
1213 }
1214
1215 static HRESULT WINAPI
1216 IBasicVideo2_fnGetPreferredAspectRatio(IBasicVideo2* iface,long* plRateX,long* plRateY)
1217 {
1218         CVideoRendererImpl_THIS(iface,basvid);
1219
1220         FIXME("(%p)->()\n",This);
1221
1222         return E_NOTIMPL;
1223 }
1224
1225
1226
1227
1228 static ICOM_VTABLE(IBasicVideo2) ibasicvideo =
1229 {
1230         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1231         /* IUnknown fields */
1232         IBasicVideo2_fnQueryInterface,
1233         IBasicVideo2_fnAddRef,
1234         IBasicVideo2_fnRelease,
1235         /* IDispatch fields */
1236         IBasicVideo2_fnGetTypeInfoCount,
1237         IBasicVideo2_fnGetTypeInfo,
1238         IBasicVideo2_fnGetIDsOfNames,
1239         IBasicVideo2_fnInvoke,
1240         /* IBasicVideo fields */
1241         IBasicVideo2_fnget_AvgTimePerFrame,
1242         IBasicVideo2_fnget_BitRate,
1243         IBasicVideo2_fnget_BitErrorRate,
1244         IBasicVideo2_fnget_VideoWidth,
1245         IBasicVideo2_fnget_VideoHeight,
1246         IBasicVideo2_fnput_SourceLeft,
1247         IBasicVideo2_fnget_SourceLeft,
1248         IBasicVideo2_fnput_SourceWidth,
1249         IBasicVideo2_fnget_SourceWidth,
1250         IBasicVideo2_fnput_SourceTop,
1251         IBasicVideo2_fnget_SourceTop,
1252         IBasicVideo2_fnput_SourceHeight,
1253         IBasicVideo2_fnget_SourceHeight,
1254         IBasicVideo2_fnput_DestinationLeft,
1255         IBasicVideo2_fnget_DestinationLeft,
1256         IBasicVideo2_fnput_DestinationWidth,
1257         IBasicVideo2_fnget_DestinationWidth,
1258         IBasicVideo2_fnput_DestinationTop,
1259         IBasicVideo2_fnget_DestinationTop,
1260         IBasicVideo2_fnput_DestinationHeight,
1261         IBasicVideo2_fnget_DestinationHeight,
1262         IBasicVideo2_fnSetSourcePosition,
1263         IBasicVideo2_fnGetSourcePosition,
1264         IBasicVideo2_fnSetDefaultSourcePosition,
1265         IBasicVideo2_fnSetDestinationPosition,
1266         IBasicVideo2_fnGetDestinationPosition,
1267         IBasicVideo2_fnSetDefaultDestinationPosition,
1268         IBasicVideo2_fnGetVideoSize,
1269         IBasicVideo2_fnGetVideoPaletteEntries,
1270         IBasicVideo2_fnGetCurrentImage,
1271         IBasicVideo2_fnIsUsingDefaultSource,
1272         IBasicVideo2_fnIsUsingDefaultDestination,
1273         /* IBasicVideo2 fields */
1274         IBasicVideo2_fnGetPreferredAspectRatio,
1275 };
1276
1277
1278 HRESULT CVideoRendererImpl_InitIBasicVideo2( CVideoRendererImpl* This )
1279 {
1280         TRACE("(%p)\n",This);
1281         ICOM_VTBL(&This->basvid) = &ibasicvideo;
1282
1283         return NOERROR;
1284 }
1285
1286 void CVideoRendererImpl_UninitIBasicVideo2( CVideoRendererImpl* This )
1287 {
1288         TRACE("(%p)\n",This);
1289 }
1290
1291 /***************************************************************************
1292  *
1293  *      CVideoRendererImpl::IVideoWindow
1294  *
1295  */
1296
1297
1298 static HRESULT WINAPI
1299 IVideoWindow_fnQueryInterface(IVideoWindow* iface,REFIID riid,void** ppobj)
1300 {
1301         CVideoRendererImpl_THIS(iface,vidwin);
1302
1303         TRACE("(%p)->()\n",This);
1304
1305         return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
1306 }
1307
1308 static ULONG WINAPI
1309 IVideoWindow_fnAddRef(IVideoWindow* iface)
1310 {
1311         CVideoRendererImpl_THIS(iface,vidwin);
1312
1313         TRACE("(%p)->()\n",This);
1314
1315         return IUnknown_AddRef(This->unk.punkControl);
1316 }
1317
1318 static ULONG WINAPI
1319 IVideoWindow_fnRelease(IVideoWindow* iface)
1320 {
1321         CVideoRendererImpl_THIS(iface,vidwin);
1322
1323         TRACE("(%p)->()\n",This);
1324
1325         return IUnknown_Release(This->unk.punkControl);
1326 }
1327
1328 static HRESULT WINAPI
1329 IVideoWindow_fnGetTypeInfoCount(IVideoWindow* iface,UINT* pcTypeInfo)
1330 {
1331         CVideoRendererImpl_THIS(iface,vidwin);
1332
1333         FIXME("(%p)->()\n",This);
1334
1335         return E_NOTIMPL;
1336 }
1337
1338 static HRESULT WINAPI
1339 IVideoWindow_fnGetTypeInfo(IVideoWindow* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
1340 {
1341         CVideoRendererImpl_THIS(iface,vidwin);
1342
1343         FIXME("(%p)->()\n",This);
1344
1345         return E_NOTIMPL;
1346 }
1347
1348 static HRESULT WINAPI
1349 IVideoWindow_fnGetIDsOfNames(IVideoWindow* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
1350 {
1351         CVideoRendererImpl_THIS(iface,vidwin);
1352
1353         FIXME("(%p)->()\n",This);
1354
1355         return E_NOTIMPL;
1356 }
1357
1358 static HRESULT WINAPI
1359 IVideoWindow_fnInvoke(IVideoWindow* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
1360 {
1361         CVideoRendererImpl_THIS(iface,vidwin);
1362
1363         FIXME("(%p)->()\n",This);
1364
1365         return E_NOTIMPL;
1366 }
1367
1368
1369
1370 static HRESULT WINAPI
1371 IVideoWindow_fnput_Caption(IVideoWindow* iface,BSTR strCaption)
1372 {
1373         CVideoRendererImpl_THIS(iface,vidwin);
1374         HRESULT hr = E_NOTIMPL;
1375
1376         FIXME("(%p)->()\n",This);
1377
1378         EnterCriticalSection ( &This->basefilter.csFilter );
1379         if ( This->m_hwnd == (HWND)NULL )
1380         {
1381                 hr = VFW_E_NOT_CONNECTED;
1382                 goto end;
1383         }
1384
1385         /* FIXME */
1386 end:
1387         LeaveCriticalSection ( &This->basefilter.csFilter );
1388
1389         return hr;
1390 }
1391
1392 static HRESULT WINAPI
1393 IVideoWindow_fnget_Caption(IVideoWindow* iface,BSTR* pstrCaption)
1394 {
1395         CVideoRendererImpl_THIS(iface,vidwin);
1396         HRESULT hr = E_NOTIMPL;
1397
1398         FIXME("(%p)->()\n",This);
1399
1400         EnterCriticalSection ( &This->basefilter.csFilter );
1401         if ( This->m_hwnd == (HWND)NULL )
1402         {
1403                 hr = VFW_E_NOT_CONNECTED;
1404                 goto end;
1405         }
1406
1407         /* FIXME */
1408 end:
1409         LeaveCriticalSection ( &This->basefilter.csFilter );
1410
1411         return hr;
1412 }
1413
1414 static HRESULT WINAPI
1415 IVideoWindow_fnput_WindowStyle(IVideoWindow* iface,long lStyle)
1416 {
1417         CVideoRendererImpl_THIS(iface,vidwin);
1418         HRESULT hr = E_NOTIMPL;
1419
1420         FIXME("(%p)->()\n",This);
1421
1422         EnterCriticalSection ( &This->basefilter.csFilter );
1423         if ( This->m_hwnd == (HWND)NULL )
1424         {
1425                 hr = VFW_E_NOT_CONNECTED;
1426                 goto end;
1427         }
1428
1429         SetLastError(0);
1430         if ( SetWindowLongA( This->m_hwnd, GWL_STYLE, (DWORD)lStyle ) == 0 &&
1431                  GetLastError() != 0 )
1432         {
1433                 hr = E_FAIL;
1434                 goto end;
1435         }
1436
1437         hr = S_OK;
1438 end:
1439         LeaveCriticalSection ( &This->basefilter.csFilter );
1440
1441         return hr;
1442 }
1443
1444 static HRESULT WINAPI
1445 IVideoWindow_fnget_WindowStyle(IVideoWindow* iface,long* plStyle)
1446 {
1447         CVideoRendererImpl_THIS(iface,vidwin);
1448         HRESULT hr = E_NOTIMPL;
1449
1450         FIXME("(%p)->()\n",This);
1451
1452         EnterCriticalSection ( &This->basefilter.csFilter );
1453         if ( This->m_hwnd == (HWND)NULL )
1454         {
1455                 hr = VFW_E_NOT_CONNECTED;
1456                 goto end;
1457         }
1458
1459         *plStyle = (LONG)GetWindowLongA( This->m_hwnd, GWL_STYLE );
1460         hr = S_OK;
1461 end:
1462         LeaveCriticalSection ( &This->basefilter.csFilter );
1463
1464         return hr;
1465 }
1466
1467 static HRESULT WINAPI
1468 IVideoWindow_fnput_WindowStyleEx(IVideoWindow* iface,long lExStyle)
1469 {
1470         CVideoRendererImpl_THIS(iface,vidwin);
1471         HRESULT hr = E_NOTIMPL;
1472
1473         FIXME("(%p)->()\n",This);
1474
1475         EnterCriticalSection ( &This->basefilter.csFilter );
1476         if ( This->m_hwnd == (HWND)NULL )
1477         {
1478                 hr = VFW_E_NOT_CONNECTED;
1479                 goto end;
1480         }
1481
1482         SetLastError(0);
1483         if ( SetWindowLongA( This->m_hwnd, GWL_EXSTYLE, (DWORD)lExStyle ) == 0 &&
1484                  GetLastError() != 0 )
1485         {
1486                 hr = E_FAIL;
1487                 goto end;
1488         }
1489
1490         hr = S_OK;
1491 end:
1492         LeaveCriticalSection ( &This->basefilter.csFilter );
1493
1494         return hr;
1495 }
1496
1497 static HRESULT WINAPI
1498 IVideoWindow_fnget_WindowStyleEx(IVideoWindow* iface,long* plExStyle)
1499 {
1500         CVideoRendererImpl_THIS(iface,vidwin);
1501         HRESULT hr = E_NOTIMPL;
1502
1503         FIXME("(%p)->()\n",This);
1504
1505         if ( plExStyle == NULL )
1506                 return E_POINTER;
1507
1508         EnterCriticalSection ( &This->basefilter.csFilter );
1509         if ( This->m_hwnd == (HWND)NULL )
1510         {
1511                 hr = VFW_E_NOT_CONNECTED;
1512                 goto end;
1513         }
1514
1515         *plExStyle = (LONG)GetWindowLongA( This->m_hwnd, GWL_EXSTYLE );
1516         hr = S_OK;
1517 end:
1518         LeaveCriticalSection ( &This->basefilter.csFilter );
1519
1520         return hr;
1521 }
1522
1523 static HRESULT WINAPI
1524 IVideoWindow_fnput_AutoShow(IVideoWindow* iface,long lAutoShow)
1525 {
1526         CVideoRendererImpl_THIS(iface,vidwin);
1527         HRESULT hr = E_NOTIMPL;
1528
1529         FIXME("(%p)->()\n",This);
1530
1531         EnterCriticalSection ( &This->basefilter.csFilter );
1532         if ( This->m_hwnd == (HWND)NULL )
1533         {
1534                 hr = VFW_E_NOT_CONNECTED;
1535                 goto end;
1536         }
1537
1538         /* FIXME */
1539 end:
1540         LeaveCriticalSection ( &This->basefilter.csFilter );
1541
1542         return hr;
1543 }
1544
1545 static HRESULT WINAPI
1546 IVideoWindow_fnget_AutoShow(IVideoWindow* iface,long* plAutoShow)
1547 {
1548         CVideoRendererImpl_THIS(iface,vidwin);
1549         HRESULT hr = E_NOTIMPL;
1550
1551         FIXME("(%p)->()\n",This);
1552
1553         EnterCriticalSection ( &This->basefilter.csFilter );
1554         if ( This->m_hwnd == (HWND)NULL )
1555         {
1556                 hr = VFW_E_NOT_CONNECTED;
1557                 goto end;
1558         }
1559
1560         /* FIXME */
1561 end:
1562         LeaveCriticalSection ( &This->basefilter.csFilter );
1563
1564         return hr;
1565 }
1566
1567 static HRESULT WINAPI
1568 IVideoWindow_fnput_WindowState(IVideoWindow* iface,long lState)
1569 {
1570         CVideoRendererImpl_THIS(iface,vidwin);
1571         HRESULT hr = E_NOTIMPL;
1572
1573         FIXME("(%p)->()\n",This);
1574
1575         EnterCriticalSection ( &This->basefilter.csFilter );
1576         if ( This->m_hwnd == (HWND)NULL )
1577         {
1578                 hr = VFW_E_NOT_CONNECTED;
1579                 goto end;
1580         }
1581
1582         /* FIXME */
1583 end:
1584         LeaveCriticalSection ( &This->basefilter.csFilter );
1585
1586         return hr;
1587 }
1588
1589 static HRESULT WINAPI
1590 IVideoWindow_fnget_WindowState(IVideoWindow* iface,long* plState)
1591 {
1592         CVideoRendererImpl_THIS(iface,vidwin);
1593         HRESULT hr = E_NOTIMPL;
1594
1595         FIXME("(%p)->()\n",This);
1596
1597         EnterCriticalSection ( &This->basefilter.csFilter );
1598         if ( This->m_hwnd == (HWND)NULL )
1599         {
1600                 hr = VFW_E_NOT_CONNECTED;
1601                 goto end;
1602         }
1603
1604         /* FIXME */
1605 end:
1606         LeaveCriticalSection ( &This->basefilter.csFilter );
1607
1608         return hr;
1609 }
1610
1611 static HRESULT WINAPI
1612 IVideoWindow_fnput_BackgroundPalette(IVideoWindow* iface,long lBackPal)
1613 {
1614         CVideoRendererImpl_THIS(iface,vidwin);
1615         HRESULT hr = E_NOTIMPL;
1616
1617         FIXME("(%p)->()\n",This);
1618
1619         EnterCriticalSection ( &This->basefilter.csFilter );
1620         if ( This->m_hwnd == (HWND)NULL )
1621         {
1622                 hr = VFW_E_NOT_CONNECTED;
1623                 goto end;
1624         }
1625
1626         /* FIXME */
1627 end:
1628         LeaveCriticalSection ( &This->basefilter.csFilter );
1629
1630         return hr;
1631 }
1632
1633 static HRESULT WINAPI
1634 IVideoWindow_fnget_BackgroundPalette(IVideoWindow* iface,long* plBackPal)
1635 {
1636         CVideoRendererImpl_THIS(iface,vidwin);
1637         HRESULT hr = E_NOTIMPL;
1638
1639         FIXME("(%p)->()\n",This);
1640
1641         EnterCriticalSection ( &This->basefilter.csFilter );
1642         if ( This->m_hwnd == (HWND)NULL )
1643         {
1644                 hr = VFW_E_NOT_CONNECTED;
1645                 goto end;
1646         }
1647
1648         /* FIXME */
1649 end:
1650         LeaveCriticalSection ( &This->basefilter.csFilter );
1651
1652         return hr;
1653 }
1654
1655 static HRESULT WINAPI
1656 IVideoWindow_fnput_Visible(IVideoWindow* iface,long lVisible)
1657 {
1658         CVideoRendererImpl_THIS(iface,vidwin);
1659         HRESULT hr = E_NOTIMPL;
1660
1661         FIXME("(%p)->()\n",This);
1662
1663         EnterCriticalSection ( &This->basefilter.csFilter );
1664         if ( This->m_hwnd == (HWND)NULL )
1665         {
1666                 hr = VFW_E_NOT_CONNECTED;
1667                 goto end;
1668         }
1669
1670         /* FIXME */
1671 end:
1672         LeaveCriticalSection ( &This->basefilter.csFilter );
1673
1674         return hr;
1675 }
1676
1677 static HRESULT WINAPI
1678 IVideoWindow_fnget_Visible(IVideoWindow* iface,long* plVisible)
1679 {
1680         CVideoRendererImpl_THIS(iface,vidwin);
1681         HRESULT hr = E_NOTIMPL;
1682
1683         FIXME("(%p)->()\n",This);
1684
1685         EnterCriticalSection ( &This->basefilter.csFilter );
1686         if ( This->m_hwnd == (HWND)NULL )
1687         {
1688                 hr = VFW_E_NOT_CONNECTED;
1689                 goto end;
1690         }
1691
1692         /* FIXME */
1693 end:
1694         LeaveCriticalSection ( &This->basefilter.csFilter );
1695
1696         return hr;
1697 }
1698
1699 static HRESULT WINAPI
1700 IVideoWindow_fnput_Left(IVideoWindow* iface,long lLeft)
1701 {
1702         CVideoRendererImpl_THIS(iface,vidwin);
1703         HRESULT hr = E_NOTIMPL;
1704         RECT    rc;
1705
1706         FIXME("(%p)->()\n",This);
1707
1708         EnterCriticalSection ( &This->basefilter.csFilter );
1709         if ( This->m_hwnd == (HWND)NULL )
1710         {
1711                 hr = VFW_E_NOT_CONNECTED;
1712                 goto end;
1713         }
1714
1715         if ( ! GetWindowRect( This->m_hwnd, &rc ) )
1716         {
1717                 hr = E_FAIL;
1718                 goto end;
1719         }
1720         if ( ! MoveWindow( This->m_hwnd, lLeft, rc.top, rc.right-rc.left, rc.bottom-rc.top, TRUE ) )
1721         {
1722                 hr = E_FAIL;
1723                 goto end;
1724         }
1725         hr = S_OK;
1726 end:
1727         LeaveCriticalSection ( &This->basefilter.csFilter );
1728
1729         return hr;
1730 }
1731
1732 static HRESULT WINAPI
1733 IVideoWindow_fnget_Left(IVideoWindow* iface,long* plLeft)
1734 {
1735         CVideoRendererImpl_THIS(iface,vidwin);
1736         HRESULT hr = E_NOTIMPL;
1737         RECT    rc;
1738
1739         FIXME("(%p)->()\n",This);
1740
1741         if ( plLeft == NULL )
1742                 return E_POINTER;
1743
1744         EnterCriticalSection ( &This->basefilter.csFilter );
1745         if ( This->m_hwnd == (HWND)NULL )
1746         {
1747                 hr = VFW_E_NOT_CONNECTED;
1748                 goto end;
1749         }
1750
1751         if ( ! GetWindowRect( This->m_hwnd, &rc ) )
1752         {
1753                 hr = E_FAIL;
1754                 goto end;
1755         }
1756         *plLeft = rc.left;
1757         hr = S_OK;
1758 end:
1759         LeaveCriticalSection ( &This->basefilter.csFilter );
1760
1761         return hr;
1762 }
1763
1764 static HRESULT WINAPI
1765 IVideoWindow_fnput_Width(IVideoWindow* iface,long lWidth)
1766 {
1767         CVideoRendererImpl_THIS(iface,vidwin);
1768         HRESULT hr = E_NOTIMPL;
1769         RECT    rc;
1770
1771         FIXME("(%p)->()\n",This);
1772
1773         if ( lWidth < 0 )
1774                 return E_INVALIDARG;
1775
1776         EnterCriticalSection ( &This->basefilter.csFilter );
1777         if ( This->m_hwnd == (HWND)NULL )
1778         {
1779                 hr = VFW_E_NOT_CONNECTED;
1780                 goto end;
1781         }
1782
1783         if ( ! GetWindowRect( This->m_hwnd, &rc ) )
1784         {
1785                 hr = E_FAIL;
1786                 goto end;
1787         }
1788         if ( ! MoveWindow( This->m_hwnd, rc.left, rc.top, lWidth, rc.bottom-rc.top, TRUE ) )
1789         {
1790                 hr = E_FAIL;
1791                 goto end;
1792         }
1793         hr = S_OK;
1794 end:
1795         LeaveCriticalSection ( &This->basefilter.csFilter );
1796
1797         return hr;
1798 }
1799
1800 static HRESULT WINAPI
1801 IVideoWindow_fnget_Width(IVideoWindow* iface,long* plWidth)
1802 {
1803         CVideoRendererImpl_THIS(iface,vidwin);
1804         HRESULT hr = E_NOTIMPL;
1805         RECT    rc;
1806
1807         FIXME("(%p)->()\n",This);
1808
1809         if ( plWidth == NULL )
1810                 return E_POINTER;
1811
1812         EnterCriticalSection ( &This->basefilter.csFilter );
1813         if ( This->m_hwnd == (HWND)NULL )
1814         {
1815                 hr = VFW_E_NOT_CONNECTED;
1816                 goto end;
1817         }
1818
1819         if ( ! GetWindowRect( This->m_hwnd, &rc ) )
1820         {
1821                 hr = E_FAIL;
1822                 goto end;
1823         }
1824         *plWidth = rc.right-rc.left;
1825         hr = S_OK;
1826 end:
1827         LeaveCriticalSection ( &This->basefilter.csFilter );
1828
1829         return hr;
1830 }
1831
1832 static HRESULT WINAPI
1833 IVideoWindow_fnput_Top(IVideoWindow* iface,long lTop)
1834 {
1835         CVideoRendererImpl_THIS(iface,vidwin);
1836         HRESULT hr = E_NOTIMPL;
1837         RECT    rc;
1838
1839         FIXME("(%p)->()\n",This);
1840
1841         EnterCriticalSection ( &This->basefilter.csFilter );
1842         if ( This->m_hwnd == (HWND)NULL )
1843         {
1844                 hr = VFW_E_NOT_CONNECTED;
1845                 goto end;
1846         }
1847
1848         if ( ! GetWindowRect( This->m_hwnd, &rc ) )
1849         {
1850                 hr = E_FAIL;
1851                 goto end;
1852         }
1853         if ( ! MoveWindow( This->m_hwnd, rc.left, lTop, rc.right-rc.left, rc.bottom-rc.top, TRUE ) )
1854         {
1855                 hr = E_FAIL;
1856                 goto end;
1857         }
1858         hr = S_OK;
1859 end:
1860         LeaveCriticalSection ( &This->basefilter.csFilter );
1861
1862         return hr;
1863 }
1864
1865 static HRESULT WINAPI
1866 IVideoWindow_fnget_Top(IVideoWindow* iface,long* plTop)
1867 {
1868         CVideoRendererImpl_THIS(iface,vidwin);
1869         HRESULT hr = E_NOTIMPL;
1870         RECT    rc;
1871
1872         FIXME("(%p)->()\n",This);
1873
1874         if ( plTop == NULL )
1875                 return E_POINTER;
1876
1877         EnterCriticalSection ( &This->basefilter.csFilter );
1878         if ( This->m_hwnd == (HWND)NULL )
1879         {
1880                 hr = VFW_E_NOT_CONNECTED;
1881                 goto end;
1882         }
1883
1884         if ( ! GetWindowRect( This->m_hwnd, &rc ) )
1885         {
1886                 hr = E_FAIL;
1887                 goto end;
1888         }
1889         *plTop = rc.top;
1890         hr = S_OK;
1891 end:
1892         LeaveCriticalSection ( &This->basefilter.csFilter );
1893
1894         return hr;
1895 }
1896
1897 static HRESULT WINAPI
1898 IVideoWindow_fnput_Height(IVideoWindow* iface,long lHeight)
1899 {
1900         CVideoRendererImpl_THIS(iface,vidwin);
1901         HRESULT hr = E_NOTIMPL;
1902         RECT    rc;
1903
1904         FIXME("(%p)->()\n",This);
1905
1906         if ( lHeight < 0 )
1907                 return E_INVALIDARG;
1908
1909         EnterCriticalSection ( &This->basefilter.csFilter );
1910         if ( This->m_hwnd == (HWND)NULL )
1911         {
1912                 hr = VFW_E_NOT_CONNECTED;
1913                 goto end;
1914         }
1915
1916         if ( ! GetWindowRect( This->m_hwnd, &rc ) )
1917         {
1918                 hr = E_FAIL;
1919                 goto end;
1920         }
1921         if ( ! MoveWindow( This->m_hwnd, rc.left, rc.top, rc.right-rc.left, lHeight, TRUE ) )
1922         {
1923                 hr = E_FAIL;
1924                 goto end;
1925         }
1926         hr = S_OK;
1927 end:
1928         LeaveCriticalSection ( &This->basefilter.csFilter );
1929
1930         return hr;
1931 }
1932
1933 static HRESULT WINAPI
1934 IVideoWindow_fnget_Height(IVideoWindow* iface,long* plHeight)
1935 {
1936         CVideoRendererImpl_THIS(iface,vidwin);
1937         HRESULT hr = E_NOTIMPL;
1938         RECT    rc;
1939
1940         FIXME("(%p)->()\n",This);
1941
1942         if ( plHeight == NULL )
1943                 return E_POINTER;
1944
1945         EnterCriticalSection ( &This->basefilter.csFilter );
1946         if ( This->m_hwnd == (HWND)NULL )
1947         {
1948                 hr = VFW_E_NOT_CONNECTED;
1949                 goto end;
1950         }
1951
1952         if ( ! GetWindowRect( This->m_hwnd, &rc ) )
1953         {
1954                 hr = E_FAIL;
1955                 goto end;
1956         }
1957         *plHeight = rc.bottom-rc.top;
1958         hr = S_OK;
1959 end:
1960         LeaveCriticalSection ( &This->basefilter.csFilter );
1961
1962         return hr;
1963 }
1964
1965 static HRESULT WINAPI
1966 IVideoWindow_fnput_Owner(IVideoWindow* iface,OAHWND hwnd)
1967 {
1968         CVideoRendererImpl_THIS(iface,vidwin);
1969         HRESULT hr = E_NOTIMPL;
1970         DWORD   dwStyle;
1971         RECT    rc;
1972
1973         FIXME("(%p)->()\n",This);
1974
1975         EnterCriticalSection ( &This->basefilter.csFilter );
1976         if ( This->m_hwnd == (HWND)NULL )
1977         {
1978                 hr = VFW_E_NOT_CONNECTED;
1979                 goto end;
1980         }
1981         if ( ! GetWindowRect( This->m_hwnd, &rc ) )
1982         {
1983                 hr = E_FAIL;
1984                 goto end;
1985         }
1986
1987         dwStyle = (DWORD)GetWindowLongA( This->m_hwnd, GWL_STYLE );
1988         if ( hwnd == (HWND)NULL )
1989                 SetWindowLongA( This->m_hwnd, GWL_STYLE, dwStyle & (~WS_CHILD) );
1990         SetParent( This->m_hwnd, (HWND)hwnd );
1991         if ( (HWND)hwnd != (HWND)NULL )
1992         {
1993                 SetWindowLongA( This->m_hwnd, GWL_STYLE, dwStyle | WS_CHILD );
1994                 MoveWindow( This->m_hwnd, 0, 0, rc.right-rc.left, rc.bottom-rc.top, TRUE );
1995         }
1996
1997         hr = S_OK;
1998 end:
1999         LeaveCriticalSection ( &This->basefilter.csFilter );
2000
2001         return hr;
2002 }
2003
2004 static HRESULT WINAPI
2005 IVideoWindow_fnget_Owner(IVideoWindow* iface,OAHWND* phwnd)
2006 {
2007         CVideoRendererImpl_THIS(iface,vidwin);
2008         HRESULT hr = E_NOTIMPL;
2009
2010         FIXME("(%p)->()\n",This);
2011
2012         if ( phwnd == NULL )
2013                 return E_POINTER;
2014
2015         EnterCriticalSection ( &This->basefilter.csFilter );
2016         if ( This->m_hwnd == (HWND)NULL )
2017         {
2018                 hr = VFW_E_NOT_CONNECTED;
2019                 goto end;
2020         }
2021
2022         *phwnd = (OAHWND)GetParent( This->m_hwnd );
2023         hr = S_OK;
2024 end:
2025         LeaveCriticalSection ( &This->basefilter.csFilter );
2026
2027         return hr;
2028 }
2029
2030 static HRESULT WINAPI
2031 IVideoWindow_fnput_MessageDrain(IVideoWindow* iface,OAHWND hwnd)
2032 {
2033         CVideoRendererImpl_THIS(iface,vidwin);
2034         HRESULT hr = E_NOTIMPL;
2035
2036         FIXME("(%p)->()\n",This);
2037
2038         EnterCriticalSection ( &This->basefilter.csFilter );
2039         if ( This->m_hwnd == (HWND)NULL )
2040         {
2041                 hr = VFW_E_NOT_CONNECTED;
2042                 goto end;
2043         }
2044
2045         /* FIXME */
2046 end:
2047         LeaveCriticalSection ( &This->basefilter.csFilter );
2048
2049         return hr;
2050 }
2051
2052 static HRESULT WINAPI
2053 IVideoWindow_fnget_MessageDrain(IVideoWindow* iface,OAHWND* phwnd)
2054 {
2055         CVideoRendererImpl_THIS(iface,vidwin);
2056         HRESULT hr = E_NOTIMPL;
2057
2058         FIXME("(%p)->()\n",This);
2059
2060         EnterCriticalSection ( &This->basefilter.csFilter );
2061         if ( This->m_hwnd == (HWND)NULL )
2062         {
2063                 hr = VFW_E_NOT_CONNECTED;
2064                 goto end;
2065         }
2066
2067         /* FIXME */
2068 end:
2069         LeaveCriticalSection ( &This->basefilter.csFilter );
2070
2071         return hr;
2072 }
2073
2074 static HRESULT WINAPI
2075 IVideoWindow_fnget_BorderColor(IVideoWindow* iface,long* plColor)
2076 {
2077         CVideoRendererImpl_THIS(iface,vidwin);
2078         HRESULT hr = E_NOTIMPL;
2079
2080         FIXME("(%p)->()\n",This);
2081
2082         EnterCriticalSection ( &This->basefilter.csFilter );
2083         if ( This->m_hwnd == (HWND)NULL )
2084         {
2085                 hr = VFW_E_NOT_CONNECTED;
2086                 goto end;
2087         }
2088
2089         /* FIXME */
2090 end:
2091         LeaveCriticalSection ( &This->basefilter.csFilter );
2092
2093         return hr;
2094 }
2095
2096 static HRESULT WINAPI
2097 IVideoWindow_fnput_BorderColor(IVideoWindow* iface,long lColor)
2098 {
2099         CVideoRendererImpl_THIS(iface,vidwin);
2100         HRESULT hr = E_NOTIMPL;
2101
2102         FIXME("(%p)->()\n",This);
2103
2104         EnterCriticalSection ( &This->basefilter.csFilter );
2105         if ( This->m_hwnd == (HWND)NULL )
2106         {
2107                 hr = VFW_E_NOT_CONNECTED;
2108                 goto end;
2109         }
2110
2111         /* FIXME */
2112 end:
2113         LeaveCriticalSection ( &This->basefilter.csFilter );
2114
2115         return hr;
2116 }
2117
2118 static HRESULT WINAPI
2119 IVideoWindow_fnget_FullScreenMode(IVideoWindow* iface,long* plMode)
2120 {
2121         CVideoRendererImpl_THIS(iface,vidwin);
2122         HRESULT hr = E_NOTIMPL;
2123
2124         FIXME("(%p)->()\n",This);
2125
2126         EnterCriticalSection ( &This->basefilter.csFilter );
2127         if ( This->m_hwnd == (HWND)NULL )
2128         {
2129                 hr = VFW_E_NOT_CONNECTED;
2130                 goto end;
2131         }
2132
2133         /* FIXME */
2134 end:
2135         LeaveCriticalSection ( &This->basefilter.csFilter );
2136
2137         return hr;
2138 }
2139
2140 static HRESULT WINAPI
2141 IVideoWindow_fnput_FullScreenMode(IVideoWindow* iface,long lMode)
2142 {
2143         CVideoRendererImpl_THIS(iface,vidwin);
2144         HRESULT hr = E_NOTIMPL;
2145
2146         FIXME("(%p)->()\n",This);
2147
2148         EnterCriticalSection ( &This->basefilter.csFilter );
2149         if ( This->m_hwnd == (HWND)NULL )
2150         {
2151                 hr = VFW_E_NOT_CONNECTED;
2152                 goto end;
2153         }
2154
2155         /* FIXME */
2156 end:
2157         LeaveCriticalSection ( &This->basefilter.csFilter );
2158
2159         return hr;
2160 }
2161
2162 static HRESULT WINAPI
2163 IVideoWindow_fnSetWindowForeground(IVideoWindow* iface,long lFocus)
2164 {
2165         CVideoRendererImpl_THIS(iface,vidwin);
2166         HRESULT hr = E_NOTIMPL;
2167
2168         FIXME("(%p)->()\n",This);
2169
2170         EnterCriticalSection ( &This->basefilter.csFilter );
2171         if ( This->m_hwnd == (HWND)NULL )
2172         {
2173                 hr = VFW_E_NOT_CONNECTED;
2174                 goto end;
2175         }
2176
2177         /* FIXME */
2178 end:
2179         LeaveCriticalSection ( &This->basefilter.csFilter );
2180
2181         return hr;
2182 }
2183
2184 static HRESULT WINAPI
2185 IVideoWindow_fnNotifyOwnerMessage(IVideoWindow* iface,OAHWND hwnd,long message,LONG_PTR wParam,LONG_PTR lParam)
2186 {
2187         CVideoRendererImpl_THIS(iface,vidwin);
2188         HRESULT hr = E_NOTIMPL;
2189
2190         FIXME("(%p)->()\n",This);
2191
2192         EnterCriticalSection ( &This->basefilter.csFilter );
2193         if ( This->m_hwnd == (HWND)NULL )
2194         {
2195                 hr = VFW_E_NOT_CONNECTED;
2196                 goto end;
2197         }
2198
2199         /* FIXME */
2200 end:
2201         LeaveCriticalSection ( &This->basefilter.csFilter );
2202
2203         return hr;
2204 }
2205
2206 static HRESULT WINAPI
2207 IVideoWindow_fnSetWindowPosition(IVideoWindow* iface,long lLeft,long lTop,long lWidth,long lHeight)
2208 {
2209         CVideoRendererImpl_THIS(iface,vidwin);
2210         HRESULT hr = E_NOTIMPL;
2211
2212         FIXME("(%p)->()\n",This);
2213
2214         EnterCriticalSection ( &This->basefilter.csFilter );
2215         if ( This->m_hwnd == (HWND)NULL )
2216         {
2217                 hr = VFW_E_NOT_CONNECTED;
2218                 goto end;
2219         }
2220
2221         if ( ! MoveWindow( This->m_hwnd, lLeft, lTop, lWidth, lHeight, TRUE ) )
2222         {
2223                 hr = E_FAIL;
2224                 goto end;
2225         }
2226         hr = S_OK;
2227 end:
2228         LeaveCriticalSection ( &This->basefilter.csFilter );
2229
2230         return hr;
2231 }
2232
2233 static HRESULT WINAPI
2234 IVideoWindow_fnGetWindowPosition(IVideoWindow* iface,long* plLeft,long* plTop,long* plWidth,long* plHeight)
2235 {
2236         CVideoRendererImpl_THIS(iface,vidwin);
2237         HRESULT hr = E_NOTIMPL;
2238         RECT    rc;
2239
2240         FIXME("(%p)->()\n",This);
2241
2242         if ( plLeft == NULL || plTop == NULL ||
2243                  plWidth == NULL || plHeight == NULL )
2244                 return E_POINTER;
2245
2246         EnterCriticalSection ( &This->basefilter.csFilter );
2247         if ( This->m_hwnd == (HWND)NULL )
2248         {
2249                 hr = VFW_E_NOT_CONNECTED;
2250                 goto end;
2251         }
2252
2253         /* FIXME */
2254         if ( ! GetWindowRect( This->m_hwnd, &rc ) )
2255         {
2256                 hr = E_FAIL;
2257                 goto end;
2258         }
2259
2260         *plLeft = rc.left;
2261         *plTop = rc.top;
2262         *plWidth = rc.right-rc.left;
2263         *plHeight = rc.bottom-rc.top;
2264         hr = S_OK;
2265
2266 end:
2267         LeaveCriticalSection ( &This->basefilter.csFilter );
2268
2269         return hr;
2270 }
2271
2272 static HRESULT WINAPI
2273 IVideoWindow_fnGetMinIdealImageSize(IVideoWindow* iface,long* plWidth,long* plHeight)
2274 {
2275         CVideoRendererImpl_THIS(iface,vidwin);
2276         HRESULT hr = E_NOTIMPL;
2277
2278         FIXME("(%p)->()\n",This);
2279
2280         EnterCriticalSection ( &This->basefilter.csFilter );
2281         if ( This->m_hwnd == (HWND)NULL )
2282         {
2283                 hr = VFW_E_NOT_CONNECTED;
2284                 goto end;
2285         }
2286
2287         /* FIXME */
2288 end:
2289         LeaveCriticalSection ( &This->basefilter.csFilter );
2290
2291         return hr;
2292 }
2293
2294 static HRESULT WINAPI
2295 IVideoWindow_fnGetMaxIdealImageSize(IVideoWindow* iface,long* plWidth,long* plHeight)
2296 {
2297         CVideoRendererImpl_THIS(iface,vidwin);
2298         HRESULT hr = E_NOTIMPL;
2299
2300         FIXME("(%p)->()\n",This);
2301
2302         EnterCriticalSection ( &This->basefilter.csFilter );
2303         if ( This->m_hwnd == (HWND)NULL )
2304         {
2305                 hr = VFW_E_NOT_CONNECTED;
2306                 goto end;
2307         }
2308
2309         /* FIXME */
2310 end:
2311         LeaveCriticalSection ( &This->basefilter.csFilter );
2312
2313         return hr;
2314 }
2315
2316 static HRESULT WINAPI
2317 IVideoWindow_fnGetRestorePosition(IVideoWindow* iface,long* plLeft,long* plTop,long* plWidth,long* plHeight)
2318 {
2319         CVideoRendererImpl_THIS(iface,vidwin);
2320         HRESULT hr = E_NOTIMPL;
2321
2322         FIXME("(%p)->()\n",This);
2323
2324         EnterCriticalSection ( &This->basefilter.csFilter );
2325         if ( This->m_hwnd == (HWND)NULL )
2326         {
2327                 hr = VFW_E_NOT_CONNECTED;
2328                 goto end;
2329         }
2330
2331         /* FIXME */
2332 end:
2333         LeaveCriticalSection ( &This->basefilter.csFilter );
2334
2335         return hr;
2336 }
2337
2338 static HRESULT WINAPI
2339 IVideoWindow_fnHideCursor(IVideoWindow* iface,long lHide)
2340 {
2341         CVideoRendererImpl_THIS(iface,vidwin);
2342         HRESULT hr = E_NOTIMPL;
2343
2344         FIXME("(%p)->()\n",This);
2345
2346         EnterCriticalSection ( &This->basefilter.csFilter );
2347         if ( This->m_hwnd == (HWND)NULL )
2348         {
2349                 hr = VFW_E_NOT_CONNECTED;
2350                 goto end;
2351         }
2352
2353         /* FIXME */
2354 end:
2355         LeaveCriticalSection ( &This->basefilter.csFilter );
2356
2357         return hr;
2358 }
2359
2360 static HRESULT WINAPI
2361 IVideoWindow_fnIsCursorHidden(IVideoWindow* iface,long* plHide)
2362 {
2363         CVideoRendererImpl_THIS(iface,vidwin);
2364         HRESULT hr = E_NOTIMPL;
2365
2366         FIXME("(%p)->()\n",This);
2367
2368         EnterCriticalSection ( &This->basefilter.csFilter );
2369         if ( This->m_hwnd == (HWND)NULL )
2370         {
2371                 hr = VFW_E_NOT_CONNECTED;
2372                 goto end;
2373         }
2374
2375         /* FIXME */
2376 end:
2377         LeaveCriticalSection ( &This->basefilter.csFilter );
2378
2379         return hr;
2380 }
2381
2382
2383
2384
2385 static ICOM_VTABLE(IVideoWindow) ivideowindow =
2386 {
2387         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2388         /* IUnknown fields */
2389         IVideoWindow_fnQueryInterface,
2390         IVideoWindow_fnAddRef,
2391         IVideoWindow_fnRelease,
2392         /* IDispatch fields */
2393         IVideoWindow_fnGetTypeInfoCount,
2394         IVideoWindow_fnGetTypeInfo,
2395         IVideoWindow_fnGetIDsOfNames,
2396         IVideoWindow_fnInvoke,
2397         /* IVideoWindow fields */
2398         IVideoWindow_fnput_Caption,
2399         IVideoWindow_fnget_Caption,
2400         IVideoWindow_fnput_WindowStyle,
2401         IVideoWindow_fnget_WindowStyle,
2402         IVideoWindow_fnput_WindowStyleEx,
2403         IVideoWindow_fnget_WindowStyleEx,
2404         IVideoWindow_fnput_AutoShow,
2405         IVideoWindow_fnget_AutoShow,
2406         IVideoWindow_fnput_WindowState,
2407         IVideoWindow_fnget_WindowState,
2408         IVideoWindow_fnput_BackgroundPalette,
2409         IVideoWindow_fnget_BackgroundPalette,
2410         IVideoWindow_fnput_Visible,
2411         IVideoWindow_fnget_Visible,
2412         IVideoWindow_fnput_Left,
2413         IVideoWindow_fnget_Left,
2414         IVideoWindow_fnput_Width,
2415         IVideoWindow_fnget_Width,
2416         IVideoWindow_fnput_Top,
2417         IVideoWindow_fnget_Top,
2418         IVideoWindow_fnput_Height,
2419         IVideoWindow_fnget_Height,
2420         IVideoWindow_fnput_Owner,
2421         IVideoWindow_fnget_Owner,
2422         IVideoWindow_fnput_MessageDrain,
2423         IVideoWindow_fnget_MessageDrain,
2424         IVideoWindow_fnget_BorderColor,
2425         IVideoWindow_fnput_BorderColor,
2426         IVideoWindow_fnget_FullScreenMode,
2427         IVideoWindow_fnput_FullScreenMode,
2428         IVideoWindow_fnSetWindowForeground,
2429         IVideoWindow_fnNotifyOwnerMessage,
2430         IVideoWindow_fnSetWindowPosition,
2431         IVideoWindow_fnGetWindowPosition,
2432         IVideoWindow_fnGetMinIdealImageSize,
2433         IVideoWindow_fnGetMaxIdealImageSize,
2434         IVideoWindow_fnGetRestorePosition,
2435         IVideoWindow_fnHideCursor,
2436         IVideoWindow_fnIsCursorHidden,
2437
2438 };
2439
2440
2441 HRESULT CVideoRendererImpl_InitIVideoWindow( CVideoRendererImpl* This )
2442 {
2443         TRACE("(%p)\n",This);
2444         ICOM_VTBL(&This->vidwin) = &ivideowindow;
2445
2446         return NOERROR;
2447 }
2448
2449 void CVideoRendererImpl_UninitIVideoWindow( CVideoRendererImpl* This )
2450 {
2451         TRACE("(%p)\n",This);
2452 }
2453