Fixes for -Wmissing-declaration and -Wwrite-string warnings.
[wine] / dlls / quartz / videorenderer.c
1 /*
2  * Video Renderer (Fullscreen and Windowed using Direct Draw)
3  *
4  * Copyright 2004 Christian Costa
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
21 #include "config.h"
22
23 #define NONAMELESSSTRUCT
24 #define NONAMELESSUNION
25 #include "quartz_private.h"
26 #include "control_private.h"
27 #include "pin.h"
28
29 #include "uuids.h"
30 #include "mmreg.h"
31 #include "vfwmsgs.h"
32 #include "amvideo.h"
33 #include "fourcc.h"
34 #include "windef.h"
35 #include "winbase.h"
36 #include "dshow.h"
37 #include "evcode.h"
38 #include "strmif.h"
39 #include "ddraw.h"
40
41 #include "wine/unicode.h"
42 #include "wine/debug.h"
43
44 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
45
46 static BOOL wnd_class_registered = FALSE;
47
48 static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0};
49
50 static const IBaseFilterVtbl VideoRenderer_Vtbl;
51 static const IBasicVideoVtbl IBasicVideo_VTable;
52 static const IVideoWindowVtbl IVideoWindow_VTable;
53 static const IPinVtbl VideoRenderer_InputPin_Vtbl;
54
55 typedef struct VideoRendererImpl
56 {
57     const IBaseFilterVtbl * lpVtbl;
58     const IBasicVideoVtbl * IBasicVideo_vtbl;
59     const IVideoWindowVtbl * IVideoWindow_vtbl;
60
61     ULONG refCount;
62     CRITICAL_SECTION csFilter;
63     FILTER_STATE state;
64     REFERENCE_TIME rtStreamStart;
65     IReferenceClock * pClock;
66     FILTER_INFO filterInfo;
67
68     InputPin * pInputPin;
69     IPin ** ppPins;
70
71     BOOL init;
72     HANDLE hThread;
73     DWORD ThreadID;
74     HANDLE hEvent;
75     BOOL ThreadResult;
76     HWND hWnd;
77     HWND hWndMsgDrain;
78     BOOL AutoShow;
79     RECT SourceRect;
80     RECT DestRect;
81     RECT WindowPos;
82     long VideoWidth;
83     long VideoHeight;
84 } VideoRendererImpl;
85
86 static LRESULT CALLBACK VideoWndProcA(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
87 {
88     VideoRendererImpl* pVideoRenderer = (VideoRendererImpl*)GetWindowLongA(hwnd, 0);
89     LPRECT lprect = (LPRECT)lParam;
90
91     if (pVideoRenderer && pVideoRenderer->hWndMsgDrain)
92     {
93         switch(uMsg)
94         {
95             case WM_KEYDOWN:
96             case WM_KEYUP:
97             case WM_LBUTTONDBLCLK:
98             case WM_LBUTTONDOWN:
99             case WM_LBUTTONUP:
100             case WM_MBUTTONDBLCLK:
101             case WM_MBUTTONDOWN:
102             case WM_MBUTTONUP:
103             case WM_MOUSEACTIVATE:
104             case WM_MOUSEMOVE:
105             case WM_NCLBUTTONDBLCLK:
106             case WM_NCLBUTTONDOWN:
107             case WM_NCLBUTTONUP:
108             case WM_NCMBUTTONDBLCLK:
109             case WM_NCMBUTTONDOWN:
110             case WM_NCMBUTTONUP:
111             case WM_NCMOUSEMOVE:
112             case WM_NCRBUTTONDBLCLK:
113             case WM_NCRBUTTONDOWN:
114             case WM_NCRBUTTONUP:
115             case WM_RBUTTONDBLCLK:
116             case WM_RBUTTONDOWN:
117             case WM_RBUTTONUP:
118                 PostMessageA(pVideoRenderer->hWndMsgDrain, uMsg, wParam, lParam);
119                 break;
120             default:
121                 break;
122         }
123     }
124
125     switch(uMsg)
126     {
127         case WM_SIZING:
128             /* TRACE("WM_SIZING %ld %ld %ld %ld\n", lprect->left, lprect->top, lprect->right, lprect->bottom); */
129             SetWindowPos(hwnd, NULL, lprect->left, lprect->top, lprect->right - lprect->left, lprect->bottom - lprect->top, SWP_NOZORDER);
130             GetClientRect(hwnd, &pVideoRenderer->DestRect);
131             return TRUE;
132         default:
133             return DefWindowProcA(hwnd, uMsg, wParam, lParam);
134     }
135     return 0;
136 }
137
138 static BOOL CreateRenderingWindow(VideoRendererImpl* This)
139 {
140     WNDCLASSA winclass;
141
142     TRACE("(%p)->()\n", This);
143     
144     winclass.style = 0;
145     winclass.lpfnWndProc = VideoWndProcA;
146     winclass.cbClsExtra = 0;
147     winclass.cbWndExtra = sizeof(VideoRendererImpl*);
148     winclass.hInstance = NULL;
149     winclass.hIcon = NULL;
150     winclass.hCursor = NULL;
151     winclass.hbrBackground = NULL;
152     winclass.lpszMenuName = NULL;
153     winclass.lpszClassName = "Wine ActiveMovie Class";
154
155     if (!wnd_class_registered)
156     {
157         if (!RegisterClassA(&winclass))
158         {
159             ERR("Unable to register window %lx\n", GetLastError());
160             return FALSE;
161         }
162         wnd_class_registered = TRUE;
163     }
164
165     This->hWnd = CreateWindowExA(0, "Wine ActiveMovie Class", "Wine ActiveMovie Window", WS_SIZEBOX,
166                                  CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL,
167                                  NULL, NULL, NULL);
168
169     if (!This->hWnd)
170     {
171         ERR("Unable to create window\n");
172         return FALSE;
173     }
174
175     SetWindowLongA(This->hWnd, 0, (LONG)This);
176
177     return TRUE;
178 }
179
180 static DWORD WINAPI MessageLoop(LPVOID lpParameter)
181 {
182     VideoRendererImpl* This = (VideoRendererImpl*) lpParameter;
183     MSG msg; 
184     BOOL fGotMessage;
185
186     TRACE("Starting message loop\n");
187
188     if (!CreateRenderingWindow(This))
189     {
190         This->ThreadResult = FALSE;
191         SetEvent(This->hEvent);
192         return 0;
193     }
194
195     This->ThreadResult = TRUE;
196     SetEvent(This->hEvent);
197
198     while ((fGotMessage = GetMessageA(&msg, (HWND) NULL, 0, 0)) != 0 && fGotMessage != -1) 
199     {
200         TranslateMessage(&msg); 
201         DispatchMessageA(&msg); 
202     }
203
204     TRACE("End of message loop\n");
205
206     return msg.wParam;
207 }
208
209 static BOOL CreateRenderingSubsystem(VideoRendererImpl* This)
210 {
211     This->hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
212     if (!This->hEvent)
213         return FALSE;
214
215     This->hThread = CreateThread(NULL, 0, MessageLoop, (LPVOID)This, 0, &This->ThreadID);
216     if (!This->hThread)
217     {
218         CloseHandle(This->hEvent);
219         return FALSE;
220     }
221
222     WaitForSingleObject(This->hEvent, INFINITE);
223     CloseHandle(This->hEvent);
224
225     if (!This->ThreadResult)
226     {
227         CloseHandle(This->hThread);
228         return FALSE;
229     }
230
231     return TRUE;
232 }
233
234 static const IMemInputPinVtbl MemInputPin_Vtbl = 
235 {
236     MemInputPin_QueryInterface,
237     MemInputPin_AddRef,
238     MemInputPin_Release,
239     MemInputPin_GetAllocator,
240     MemInputPin_NotifyAllocator,
241     MemInputPin_GetAllocatorRequirements,
242     MemInputPin_Receive,
243     MemInputPin_ReceiveMultiple,
244     MemInputPin_ReceiveCanBlock
245 };
246
247 static HRESULT VideoRenderer_InputPin_Construct(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
248 {
249     InputPin * pPinImpl;
250
251     *ppPin = NULL;
252
253     if (pPinInfo->dir != PINDIR_INPUT)
254     {
255         ERR("Pin direction(%x) != PINDIR_INPUT\n", pPinInfo->dir);
256         return E_INVALIDARG;
257     }
258
259     pPinImpl = CoTaskMemAlloc(sizeof(*pPinImpl));
260
261     if (!pPinImpl)
262         return E_OUTOFMEMORY;
263
264     if (SUCCEEDED(InputPin_Init(pPinInfo, pSampleProc, pUserData, pQueryAccept, pCritSec, pPinImpl)))
265     {
266         pPinImpl->pin.lpVtbl = &VideoRenderer_InputPin_Vtbl;
267         pPinImpl->lpVtblMemInput = &MemInputPin_Vtbl;
268       
269         *ppPin = (IPin *)(&pPinImpl->pin.lpVtbl);
270         return S_OK;
271     }
272     return E_FAIL;
273 }
274
275 static DWORD VideoRenderer_SendSampleData(VideoRendererImpl* This, LPBYTE data, DWORD size)
276 {
277     VIDEOINFOHEADER* format;
278     AM_MEDIA_TYPE amt;
279     HRESULT hr = S_OK;
280     DDSURFACEDESC sdesc;
281     int width;
282     int height;
283     LPBYTE palette = NULL;
284     HDC hDC;
285
286     TRACE("%p %p %ld\n", This, data, size);
287
288     sdesc.dwSize = sizeof(sdesc);
289     hr = IPin_ConnectionMediaType(This->ppPins[0], &amt);
290     if (FAILED(hr)) {
291         ERR("Unable to retrieve media type\n");
292         return hr;
293     }
294     format = (VIDEOINFOHEADER*)amt.pbFormat;
295
296     TRACE("biSize = %ld\n", format->bmiHeader.biSize);
297     TRACE("biWidth = %ld\n", format->bmiHeader.biWidth);
298     TRACE("biHeigth = %ld\n", format->bmiHeader.biHeight);
299     TRACE("biPlanes = %d\n", format->bmiHeader.biPlanes);
300     TRACE("biBitCount = %d\n", format->bmiHeader.biBitCount);
301     TRACE("biCompression = %s\n", debugstr_an((LPSTR)&(format->bmiHeader.biCompression), 4));
302     TRACE("biSizeImage = %ld\n", format->bmiHeader.biSizeImage);
303
304     width = format->bmiHeader.biWidth;
305     height = format->bmiHeader.biHeight;
306     palette = ((LPBYTE)&format->bmiHeader) + format->bmiHeader.biSize;
307  
308     if (!This->init)
309     {
310         /* Compute the size of the whole window so the client area size matches video one */
311         RECT wrect, crect;
312         int h, v;
313         GetWindowRect(This->hWnd, &wrect);
314         GetClientRect(This->hWnd, &crect);
315         h = (wrect.right - wrect.left) - (crect.right - crect.left);
316         v = (wrect.bottom - wrect.top) - (crect.bottom - crect.top);
317         SetWindowPos(This->hWnd, NULL, 0, 0, width + h +20, height + v+20, SWP_NOZORDER|SWP_NOMOVE);
318         This->WindowPos.left = 0;
319         This->WindowPos.top = 0;
320         This->WindowPos.right = width;
321         This->WindowPos.bottom = height;
322         GetClientRect(This->hWnd, &This->DestRect);
323         This->init  = TRUE;
324     }
325
326     hDC = GetDC(This->hWnd);
327
328     if (!hDC) {
329         ERR("Cannot get DC from window!\n");
330         return E_FAIL;
331     }
332
333     TRACE("Src Rect: %ld %ld %ld %ld\n", This->SourceRect.left, This->SourceRect.top, This->SourceRect.right, This->SourceRect.bottom);
334     TRACE("Dst Rect: %ld %ld %ld %ld\n", This->DestRect.left, This->DestRect.top, This->DestRect.right, This->DestRect.bottom);
335
336     StretchDIBits(hDC, This->DestRect.left, This->DestRect.top, This->DestRect.right -This->DestRect.left,
337                   This->DestRect.bottom - This->DestRect.top, This->SourceRect.left, This->SourceRect.top,
338                   This->SourceRect.right - This->SourceRect.left, This->SourceRect.bottom - This->SourceRect.top,
339                   data, (BITMAPINFO*)&format->bmiHeader, DIB_PAL_COLORS, SRCCOPY);
340
341     ReleaseDC(This->hWnd, hDC);
342     
343     if (This->AutoShow)
344         ShowWindow(This->hWnd, SW_SHOW);
345
346     return S_OK;
347 }
348
349 static HRESULT VideoRenderer_Sample(LPVOID iface, IMediaSample * pSample)
350 {
351     VideoRendererImpl *This = (VideoRendererImpl *)iface;
352     LPBYTE pbSrcStream = NULL;
353     long cbSrcStream = 0;
354     REFERENCE_TIME tStart, tStop;
355     HRESULT hr;
356
357     TRACE("%p %p\n", iface, pSample);
358     
359     hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
360     if (FAILED(hr))
361     {
362         ERR("Cannot get pointer to sample data (%lx)\n", hr);
363         return hr;
364     }
365
366     hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
367     if (FAILED(hr))
368         ERR("Cannot get sample time (%lx)\n", hr);
369
370     cbSrcStream = IMediaSample_GetActualDataLength(pSample);
371
372     TRACE("val %p %ld\n", pbSrcStream, cbSrcStream);
373
374 #if 0 /* For debugging purpose */
375     {
376         int i;
377         for(i = 0; i < cbSrcStream; i++)
378         {
379             if ((i!=0) && !(i%16))
380                 DPRINTF("\n");
381                 DPRINTF("%02x ", pbSrcStream[i]);
382         }
383         DPRINTF("\n");
384     }
385 #endif
386     
387     VideoRenderer_SendSampleData(This, pbSrcStream, cbSrcStream);
388
389     return S_OK;
390 }
391
392 static HRESULT VideoRenderer_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt)
393 {
394     if ((IsEqualIID(&pmt->majortype, &MEDIATYPE_Video) && IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB32)) ||
395         (IsEqualIID(&pmt->majortype, &MEDIATYPE_Video) && IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB24)) ||
396         (IsEqualIID(&pmt->majortype, &MEDIATYPE_Video) && IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB565)) ||
397         (IsEqualIID(&pmt->majortype, &MEDIATYPE_Video) && IsEqualIID(&pmt->subtype, &MEDIASUBTYPE_RGB8)))
398     {
399         VideoRendererImpl* This = (VideoRendererImpl*) iface;
400         VIDEOINFOHEADER* format = (VIDEOINFOHEADER*)pmt->pbFormat;
401         This->SourceRect.left = 0;
402         This->SourceRect.top = 0;
403         This->SourceRect.right = This->VideoWidth = format->bmiHeader.biWidth;
404         This->SourceRect.bottom = This->VideoHeight = format->bmiHeader.biHeight;
405         return S_OK;
406     }
407     return S_FALSE;
408 }
409
410 HRESULT VideoRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv)
411 {
412     HRESULT hr;
413     PIN_INFO piInput;
414     VideoRendererImpl * pVideoRenderer;
415
416     TRACE("(%p, %p)\n", pUnkOuter, ppv);
417
418     *ppv = NULL;
419
420     if (pUnkOuter)
421         return CLASS_E_NOAGGREGATION;
422     
423     pVideoRenderer = CoTaskMemAlloc(sizeof(VideoRendererImpl));
424
425     pVideoRenderer->lpVtbl = &VideoRenderer_Vtbl;
426     pVideoRenderer->IBasicVideo_vtbl = &IBasicVideo_VTable;
427     pVideoRenderer->IVideoWindow_vtbl = &IVideoWindow_VTable;
428     
429     pVideoRenderer->refCount = 1;
430     InitializeCriticalSection(&pVideoRenderer->csFilter);
431     pVideoRenderer->state = State_Stopped;
432     pVideoRenderer->pClock = NULL;
433     pVideoRenderer->init = 0;
434     pVideoRenderer->AutoShow = 1;
435     ZeroMemory(&pVideoRenderer->filterInfo, sizeof(FILTER_INFO));
436
437     pVideoRenderer->ppPins = CoTaskMemAlloc(1 * sizeof(IPin *));
438
439     /* construct input pin */
440     piInput.dir = PINDIR_INPUT;
441     piInput.pFilter = (IBaseFilter *)pVideoRenderer;
442     lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0]));
443
444     hr = VideoRenderer_InputPin_Construct(&piInput, VideoRenderer_Sample, (LPVOID)pVideoRenderer, VideoRenderer_QueryAccept, &pVideoRenderer->csFilter, (IPin **)&pVideoRenderer->pInputPin);
445
446     if (SUCCEEDED(hr))
447     {
448         pVideoRenderer->ppPins[0] = (IPin *)pVideoRenderer->pInputPin;
449         *ppv = (LPVOID)pVideoRenderer;
450     }
451     else
452     {
453         CoTaskMemFree(pVideoRenderer->ppPins);
454         DeleteCriticalSection(&pVideoRenderer->csFilter);
455         CoTaskMemFree(pVideoRenderer);
456     }
457
458     if (!CreateRenderingSubsystem(pVideoRenderer))
459         return E_FAIL;
460     
461     return hr;
462 }
463
464 static HRESULT WINAPI VideoRenderer_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv)
465 {
466     VideoRendererImpl *This = (VideoRendererImpl *)iface;
467     TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
468
469     *ppv = NULL;
470
471     if (IsEqualIID(riid, &IID_IUnknown))
472         *ppv = (LPVOID)This;
473     else if (IsEqualIID(riid, &IID_IPersist))
474         *ppv = (LPVOID)This;
475     else if (IsEqualIID(riid, &IID_IMediaFilter))
476         *ppv = (LPVOID)This;
477     else if (IsEqualIID(riid, &IID_IBaseFilter))
478         *ppv = (LPVOID)This;
479     else if (IsEqualIID(riid, &IID_IBasicVideo))
480         *ppv = (LPVOID)&(This->IBasicVideo_vtbl);
481     else if (IsEqualIID(riid, &IID_IVideoWindow))
482         *ppv = (LPVOID)&(This->IVideoWindow_vtbl);
483
484     if (*ppv)
485     {
486         IUnknown_AddRef((IUnknown *)(*ppv));
487         return S_OK;
488     }
489
490     FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
491
492     return E_NOINTERFACE;
493 }
494
495 static ULONG WINAPI VideoRenderer_AddRef(IBaseFilter * iface)
496 {
497     VideoRendererImpl *This = (VideoRendererImpl *)iface;
498     ULONG refCount = InterlockedIncrement(&This->refCount);
499
500     TRACE("(%p/%p)->() AddRef from %ld\n", This, iface, refCount - 1);
501
502     return refCount;
503 }
504
505 static ULONG WINAPI VideoRenderer_Release(IBaseFilter * iface)
506 {
507     VideoRendererImpl *This = (VideoRendererImpl *)iface;
508     ULONG refCount = InterlockedDecrement(&This->refCount);
509
510     TRACE("(%p/%p)->() Release from %ld\n", This, iface, refCount + 1);
511
512     if (!refCount)
513     {
514         DeleteCriticalSection(&This->csFilter);
515
516         DestroyWindow(This->hWnd);
517         PostThreadMessageA(This->ThreadID, WM_QUIT, 0, 0);
518         WaitForSingleObject(This->hThread, INFINITE);
519         CloseHandle(This->hThread);
520
521         if (This->pClock)
522             IReferenceClock_Release(This->pClock);
523         
524         IPin_Release(This->ppPins[0]);
525         
526         HeapFree(GetProcessHeap(), 0, This->ppPins);
527         This->lpVtbl = NULL;
528         
529         TRACE("Destroying Video Renderer\n");
530         CoTaskMemFree(This);
531         
532         return 0;
533     }
534     else
535         return refCount;
536 }
537
538 /** IPersist methods **/
539
540 static HRESULT WINAPI VideoRenderer_GetClassID(IBaseFilter * iface, CLSID * pClsid)
541 {
542     VideoRendererImpl *This = (VideoRendererImpl *)iface;
543
544     TRACE("(%p/%p)->(%p)\n", This, iface, pClsid);
545
546     *pClsid = CLSID_VideoRenderer;
547
548     return S_OK;
549 }
550
551 /** IMediaFilter methods **/
552
553 static HRESULT WINAPI VideoRenderer_Stop(IBaseFilter * iface)
554 {
555     VideoRendererImpl *This = (VideoRendererImpl *)iface;
556
557     TRACE("(%p/%p)->()\n", This, iface);
558
559     EnterCriticalSection(&This->csFilter);
560     {
561         This->state = State_Stopped;
562     }
563     LeaveCriticalSection(&This->csFilter);
564     
565     return S_OK;
566 }
567
568 static HRESULT WINAPI VideoRenderer_Pause(IBaseFilter * iface)
569 {
570     VideoRendererImpl *This = (VideoRendererImpl *)iface;
571     
572     TRACE("(%p/%p)->()\n", This, iface);
573
574     EnterCriticalSection(&This->csFilter);
575     {
576         This->state = State_Paused;
577     }
578     LeaveCriticalSection(&This->csFilter);
579
580     return S_OK;
581 }
582
583 static HRESULT WINAPI VideoRenderer_Run(IBaseFilter * iface, REFERENCE_TIME tStart)
584 {
585     VideoRendererImpl *This = (VideoRendererImpl *)iface;
586
587     TRACE("(%p/%p)->(%s)\n", This, iface, wine_dbgstr_longlong(tStart));
588
589     EnterCriticalSection(&This->csFilter);
590     {
591         This->rtStreamStart = tStart;
592         This->state = State_Running;
593     }
594     LeaveCriticalSection(&This->csFilter);
595
596     return S_OK;
597 }
598
599 static HRESULT WINAPI VideoRenderer_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
600 {
601     VideoRendererImpl *This = (VideoRendererImpl *)iface;
602
603     TRACE("(%p/%p)->(%ld, %p)\n", This, iface, dwMilliSecsTimeout, pState);
604
605     EnterCriticalSection(&This->csFilter);
606     {
607         *pState = This->state;
608     }
609     LeaveCriticalSection(&This->csFilter);
610
611     return S_OK;
612 }
613
614 static HRESULT WINAPI VideoRenderer_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock)
615 {
616     VideoRendererImpl *This = (VideoRendererImpl *)iface;
617
618     TRACE("(%p/%p)->(%p)\n", This, iface, pClock);
619
620     EnterCriticalSection(&This->csFilter);
621     {
622         if (This->pClock)
623             IReferenceClock_Release(This->pClock);
624         This->pClock = pClock;
625         if (This->pClock)
626             IReferenceClock_AddRef(This->pClock);
627     }
628     LeaveCriticalSection(&This->csFilter);
629
630     return S_OK;
631 }
632
633 static HRESULT WINAPI VideoRenderer_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock)
634 {
635     VideoRendererImpl *This = (VideoRendererImpl *)iface;
636
637     TRACE("(%p/%p)->(%p)\n", This, iface, ppClock);
638
639     EnterCriticalSection(&This->csFilter);
640     {
641         *ppClock = This->pClock;
642         IReferenceClock_AddRef(This->pClock);
643     }
644     LeaveCriticalSection(&This->csFilter);
645     
646     return S_OK;
647 }
648
649 /** IBaseFilter implementation **/
650
651 static HRESULT WINAPI VideoRenderer_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum)
652 {
653     ENUMPINDETAILS epd;
654     VideoRendererImpl *This = (VideoRendererImpl *)iface;
655
656     TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
657
658     epd.cPins = 1; /* input pin */
659     epd.ppPins = This->ppPins;
660     return IEnumPinsImpl_Construct(&epd, ppEnum);
661 }
662
663 static HRESULT WINAPI VideoRenderer_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin)
664 {
665     VideoRendererImpl *This = (VideoRendererImpl *)iface;
666
667     TRACE("(%p/%p)->(%p,%p)\n", This, iface, debugstr_w(Id), ppPin);
668
669     FIXME("VideoRenderer::FindPin(...)\n");
670
671     /* FIXME: critical section */
672
673     return E_NOTIMPL;
674 }
675
676 static HRESULT WINAPI VideoRenderer_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo)
677 {
678     VideoRendererImpl *This = (VideoRendererImpl *)iface;
679
680     TRACE("(%p/%p)->(%p)\n", This, iface, pInfo);
681
682     strcpyW(pInfo->achName, This->filterInfo.achName);
683     pInfo->pGraph = This->filterInfo.pGraph;
684
685     if (pInfo->pGraph)
686         IFilterGraph_AddRef(pInfo->pGraph);
687     
688     return S_OK;
689 }
690
691 static HRESULT WINAPI VideoRenderer_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName)
692 {
693     VideoRendererImpl *This = (VideoRendererImpl *)iface;
694
695     TRACE("(%p/%p)->(%p, %s)\n", This, iface, pGraph, debugstr_w(pName));
696
697     EnterCriticalSection(&This->csFilter);
698     {
699         if (pName)
700             strcpyW(This->filterInfo.achName, pName);
701         else
702             *This->filterInfo.achName = '\0';
703         This->filterInfo.pGraph = pGraph; /* NOTE: do NOT increase ref. count */
704     }
705     LeaveCriticalSection(&This->csFilter);
706
707     return S_OK;
708 }
709
710 static HRESULT WINAPI VideoRenderer_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo)
711 {
712     VideoRendererImpl *This = (VideoRendererImpl *)iface;
713     TRACE("(%p/%p)->(%p)\n", This, iface, pVendorInfo);
714     return E_NOTIMPL;
715 }
716
717 static const IBaseFilterVtbl VideoRenderer_Vtbl =
718 {
719     VideoRenderer_QueryInterface,
720     VideoRenderer_AddRef,
721     VideoRenderer_Release,
722     VideoRenderer_GetClassID,
723     VideoRenderer_Stop,
724     VideoRenderer_Pause,
725     VideoRenderer_Run,
726     VideoRenderer_GetState,
727     VideoRenderer_SetSyncSource,
728     VideoRenderer_GetSyncSource,
729     VideoRenderer_EnumPins,
730     VideoRenderer_FindPin,
731     VideoRenderer_QueryFilterInfo,
732     VideoRenderer_JoinFilterGraph,
733     VideoRenderer_QueryVendorInfo
734 };
735
736 static HRESULT WINAPI VideoRenderer_InputPin_EndOfStream(IPin * iface)
737 {
738     InputPin* This = (InputPin*)iface;
739     IMediaEventSink* pEventSink;
740     HRESULT hr;
741
742     TRACE("(%p/%p)->()\n", This, iface);
743
744     hr = IFilterGraph_QueryInterface(((VideoRendererImpl*)This->pin.pinInfo.pFilter)->filterInfo.pGraph, &IID_IMediaEventSink, (LPVOID*)&pEventSink);
745     if (SUCCEEDED(hr))
746     {
747         hr = IMediaEventSink_Notify(pEventSink, EC_COMPLETE, S_OK, 0);
748         IMediaEventSink_Release(pEventSink);
749     }
750
751     return hr;
752 }
753
754 static const IPinVtbl VideoRenderer_InputPin_Vtbl = 
755 {
756     InputPin_QueryInterface,
757     IPinImpl_AddRef,
758     InputPin_Release,
759     InputPin_Connect,
760     InputPin_ReceiveConnection,
761     IPinImpl_Disconnect,
762     IPinImpl_ConnectedTo,
763     IPinImpl_ConnectionMediaType,
764     IPinImpl_QueryPinInfo,
765     IPinImpl_QueryDirection,
766     IPinImpl_QueryId,
767     IPinImpl_QueryAccept,
768     IPinImpl_EnumMediaTypes,
769     IPinImpl_QueryInternalConnections,
770     VideoRenderer_InputPin_EndOfStream,
771     InputPin_BeginFlush,
772     InputPin_EndFlush,
773     InputPin_NewSegment
774 };
775
776 /*** IUnknown methods ***/
777 static HRESULT WINAPI Basicvideo_QueryInterface(IBasicVideo *iface,
778                                                 REFIID riid,
779                                                 LPVOID*ppvObj) {
780     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
781
782     TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
783
784     return VideoRenderer_QueryInterface((IBaseFilter*)This, riid, ppvObj);
785 }
786
787 static ULONG WINAPI Basicvideo_AddRef(IBasicVideo *iface) {
788     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
789
790     TRACE("(%p/%p)->()\n", This, iface);
791
792     return VideoRenderer_AddRef((IBaseFilter*)This);
793 }
794
795 static ULONG WINAPI Basicvideo_Release(IBasicVideo *iface) {
796     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
797
798     TRACE("(%p/%p)->()\n", This, iface);
799
800     return VideoRenderer_Release((IBaseFilter*)This);
801 }
802
803 /*** IDispatch methods ***/
804 static HRESULT WINAPI Basicvideo_GetTypeInfoCount(IBasicVideo *iface,
805                                                   UINT*pctinfo) {
806     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
807
808     FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo);
809
810     return S_OK;
811 }
812
813 static HRESULT WINAPI Basicvideo_GetTypeInfo(IBasicVideo *iface,
814                                              UINT iTInfo,
815                                              LCID lcid,
816                                              ITypeInfo**ppTInfo) {
817     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
818
819     FIXME("(%p/%p)->(%d, %ld, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo);
820
821     return S_OK;
822 }
823
824 static HRESULT WINAPI Basicvideo_GetIDsOfNames(IBasicVideo *iface,
825                                                REFIID riid,
826                                                LPOLESTR*rgszNames,
827                                                UINT cNames,
828                                                LCID lcid,
829                                                DISPID*rgDispId) {
830     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
831
832     FIXME("(%p/%p)->(%s (%p), %p, %d, %ld, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
833
834     return S_OK;
835 }
836
837 static HRESULT WINAPI Basicvideo_Invoke(IBasicVideo *iface,
838                                         DISPID dispIdMember,
839                                         REFIID riid,
840                                         LCID lcid,
841                                         WORD wFlags,
842                                         DISPPARAMS*pDispParams,
843                                         VARIANT*pVarResult,
844                                         EXCEPINFO*pExepInfo,
845                                         UINT*puArgErr) {
846     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
847
848     FIXME("(%p/%p)->(%ld, %s (%p), %ld, %04x, %p, %p, %p, %p): stub !!!\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
849
850     return S_OK;
851 }
852
853 /*** IBasicVideo methods ***/
854 static HRESULT WINAPI Basicvideo_get_AvgTimePerFrame(IBasicVideo *iface,
855                                                      REFTIME *pAvgTimePerFrame) {
856     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
857
858     FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pAvgTimePerFrame);
859
860     return S_OK;
861 }
862
863 static HRESULT WINAPI Basicvideo_get_BitRate(IBasicVideo *iface,
864                                              long *pBitRate) {
865     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
866
867     FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pBitRate);
868
869     return S_OK;
870 }
871
872 static HRESULT WINAPI Basicvideo_get_BitErrorRate(IBasicVideo *iface,
873                                                   long *pBitErrorRate) {
874     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
875
876     FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pBitErrorRate);
877
878     return S_OK;
879 }
880
881 static HRESULT WINAPI Basicvideo_get_VideoWidth(IBasicVideo *iface,
882                                                 long *pVideoWidth) {
883     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
884
885     TRACE("(%p/%p)->(%p)\n", This, iface, pVideoWidth);
886
887     *pVideoWidth = This->VideoWidth;
888
889     return S_OK;
890 }
891
892 static HRESULT WINAPI Basicvideo_get_VideoHeight(IBasicVideo *iface,
893                                                  long *pVideoHeight) {
894     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
895
896     TRACE("(%p/%p)->(%p)\n", This, iface, pVideoHeight);
897
898     *pVideoHeight = This->VideoHeight;
899
900     return S_OK;
901 }
902
903 static HRESULT WINAPI Basicvideo_put_SourceLeft(IBasicVideo *iface,
904                                                 long SourceLeft) {
905     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
906
907     TRACE("(%p/%p)->(%ld)\n", This, iface, SourceLeft);
908
909     This->SourceRect.left = SourceLeft;
910
911     return S_OK;
912 }
913
914 static HRESULT WINAPI Basicvideo_get_SourceLeft(IBasicVideo *iface,
915                                                 long *pSourceLeft) {
916     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
917
918     TRACE("(%p/%p)->(%p)\n", This, iface, pSourceLeft);
919
920     *pSourceLeft = This->SourceRect.left;
921
922     return S_OK;
923 }
924
925 static HRESULT WINAPI Basicvideo_put_SourceWidth(IBasicVideo *iface,
926                                                  long SourceWidth) {
927     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
928
929     TRACE("(%p/%p)->(%ld)\n", This, iface, SourceWidth);
930
931     This->SourceRect.right = This->SourceRect.left + SourceWidth;
932
933     return S_OK;
934 }
935
936 static HRESULT WINAPI Basicvideo_get_SourceWidth(IBasicVideo *iface,
937                                                  long *pSourceWidth) {
938     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
939
940     TRACE("(%p/%p)->(%p)\n", This, iface, pSourceWidth);
941
942     *pSourceWidth = This->SourceRect.right - This->SourceRect.left;
943     
944     return S_OK;
945 }
946
947 static HRESULT WINAPI Basicvideo_put_SourceTop(IBasicVideo *iface,
948                                                long SourceTop) {
949     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
950
951     TRACE("(%p/%p)->(%ld)\n", This, iface, SourceTop);
952
953     This->SourceRect.top = SourceTop;
954
955     return S_OK;
956 }
957
958 static HRESULT WINAPI Basicvideo_get_SourceTop(IBasicVideo *iface,
959                                                long *pSourceTop) {
960     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
961
962     TRACE("(%p/%p)->(%p)\n", This, iface, pSourceTop);
963
964     *pSourceTop = This->SourceRect.top;
965
966     return S_OK;
967 }
968
969 static HRESULT WINAPI Basicvideo_put_SourceHeight(IBasicVideo *iface,
970                                                   long SourceHeight) {
971     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
972
973     TRACE("(%p/%p)->(%ld)\n", This, iface, SourceHeight);
974
975     This->SourceRect.bottom = This->SourceRect.top + SourceHeight;
976
977     return S_OK;
978 }
979
980 static HRESULT WINAPI Basicvideo_get_SourceHeight(IBasicVideo *iface,
981                                                   long *pSourceHeight) {
982     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
983
984     TRACE("(%p/%p)->(%p)\n", This, iface, pSourceHeight);
985
986     *pSourceHeight = This->SourceRect.bottom - This->SourceRect.top;
987
988     return S_OK;
989 }
990
991 static HRESULT WINAPI Basicvideo_put_DestinationLeft(IBasicVideo *iface,
992                                                      long DestinationLeft) {
993     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
994
995     TRACE("(%p/%p)->(%ld)\n", This, iface, DestinationLeft);
996
997     This->DestRect.left = DestinationLeft;
998
999     return S_OK;
1000 }
1001
1002 static HRESULT WINAPI Basicvideo_get_DestinationLeft(IBasicVideo *iface,
1003                                                      long *pDestinationLeft) {
1004     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1005
1006     TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationLeft);
1007
1008     *pDestinationLeft = This->DestRect.left;
1009
1010     return S_OK;
1011 }
1012
1013 static HRESULT WINAPI Basicvideo_put_DestinationWidth(IBasicVideo *iface,
1014                                                       long DestinationWidth) {
1015     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1016
1017     TRACE("(%p/%p)->(%ld)\n", This, iface, DestinationWidth);
1018
1019     This->DestRect.right = This->DestRect.left + DestinationWidth;
1020
1021     return S_OK;
1022 }
1023
1024 static HRESULT WINAPI Basicvideo_get_DestinationWidth(IBasicVideo *iface,
1025                                                       long *pDestinationWidth) {
1026     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1027
1028     TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationWidth);
1029
1030     *pDestinationWidth = This->DestRect.right - This->DestRect.left;
1031
1032     return S_OK;
1033 }
1034
1035 static HRESULT WINAPI Basicvideo_put_DestinationTop(IBasicVideo *iface,
1036                                                     long DestinationTop) {
1037     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1038
1039     TRACE("(%p/%p)->(%ld)\n", This, iface, DestinationTop);
1040
1041     This->DestRect.top = DestinationTop;
1042     
1043     return S_OK;
1044 }
1045
1046 static HRESULT WINAPI Basicvideo_get_DestinationTop(IBasicVideo *iface,
1047                                                     long *pDestinationTop) {
1048     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1049
1050     TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationTop);
1051
1052     *pDestinationTop = This->DestRect.top;
1053
1054     return S_OK;
1055 }
1056
1057 static HRESULT WINAPI Basicvideo_put_DestinationHeight(IBasicVideo *iface,
1058                                                        long DestinationHeight) {
1059     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1060
1061     TRACE("(%p/%p)->(%ld)\n", This, iface, DestinationHeight);
1062
1063     This->DestRect.right = This->DestRect.left + DestinationHeight;
1064
1065     return S_OK;
1066 }
1067
1068 static HRESULT WINAPI Basicvideo_get_DestinationHeight(IBasicVideo *iface,
1069                                                        long *pDestinationHeight) {
1070     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1071
1072     TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationHeight);
1073
1074     *pDestinationHeight = This->DestRect.right - This->DestRect.left;
1075
1076     return S_OK;
1077 }
1078
1079 static HRESULT WINAPI Basicvideo_SetSourcePosition(IBasicVideo *iface,
1080                                                    long Left,
1081                                                    long Top,
1082                                                    long Width,
1083                                                    long Height) {
1084     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1085
1086     TRACE("(%p/%p)->(%ld, %ld, %ld, %ld)\n", This, iface, Left, Top, Width, Height);
1087
1088     This->SourceRect.left = Left;
1089     This->SourceRect.top = Top;
1090     This->SourceRect.right = Left + Width;
1091     This->SourceRect.bottom = Top + Height;
1092     
1093     return S_OK;
1094 }
1095
1096 static HRESULT WINAPI Basicvideo_GetSourcePosition(IBasicVideo *iface,
1097                                                    long *pLeft,
1098                                                    long *pTop,
1099                                                    long *pWidth,
1100                                                    long *pHeight) {
1101     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1102
1103     TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
1104
1105     *pLeft = This->SourceRect.left;
1106     *pTop = This->SourceRect.top;
1107     *pWidth = This->SourceRect.right - This->SourceRect.left;
1108     *pHeight = This->SourceRect.bottom - This->SourceRect.top;
1109     
1110     return S_OK;
1111 }
1112
1113 static HRESULT WINAPI Basicvideo_SetDefaultSourcePosition(IBasicVideo *iface) {
1114     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1115
1116     TRACE("(%p/%p)->()\n", This, iface);
1117
1118     This->SourceRect.left = 0;
1119     This->SourceRect.top = 0;
1120     This->SourceRect.right = This->VideoWidth;
1121     This->SourceRect.bottom = This->VideoHeight;
1122
1123     return S_OK;
1124 }
1125
1126 static HRESULT WINAPI Basicvideo_SetDestinationPosition(IBasicVideo *iface,
1127                                                         long Left,
1128                                                         long Top,
1129                                                         long Width,
1130                                                         long Height) {
1131     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1132
1133     TRACE("(%p/%p)->(%ld, %ld, %ld, %ld)\n", This, iface, Left, Top, Width, Height);
1134
1135     This->DestRect.left = Left;
1136     This->DestRect.top = Top;
1137     This->DestRect.right = Left + Width;
1138     This->DestRect.bottom = Top + Height;
1139
1140     return S_OK;
1141 }
1142
1143 static HRESULT WINAPI Basicvideo_GetDestinationPosition(IBasicVideo *iface,
1144                                                         long *pLeft,
1145                                                         long *pTop,
1146                                                         long *pWidth,
1147                                                         long *pHeight) {
1148     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1149
1150     TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
1151
1152     *pLeft = This->DestRect.left;
1153     *pTop = This->DestRect.top;
1154     *pWidth = This->DestRect.right - This->DestRect.left;
1155     *pHeight = This->DestRect.bottom - This->DestRect.top;
1156
1157     return S_OK;
1158 }
1159
1160 static HRESULT WINAPI Basicvideo_SetDefaultDestinationPosition(IBasicVideo *iface) {
1161     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1162     RECT rect;
1163
1164     TRACE("(%p/%p)->()\n", This, iface);
1165
1166     if (!GetClientRect(This->hWnd, &rect))
1167         return E_FAIL;
1168     
1169     This->SourceRect.left = 0;
1170     This->SourceRect.top = 0;
1171     This->SourceRect.right = rect.right;
1172     This->SourceRect.bottom = rect.bottom;
1173     
1174     return S_OK;
1175 }
1176
1177 static HRESULT WINAPI Basicvideo_GetVideoSize(IBasicVideo *iface,
1178                                               long *pWidth,
1179                                               long *pHeight) {
1180     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1181
1182     TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight);
1183
1184     *pWidth = This->VideoWidth;
1185     *pHeight = This->VideoHeight;
1186     
1187     return S_OK;
1188 }
1189
1190 static HRESULT WINAPI Basicvideo_GetVideoPaletteEntries(IBasicVideo *iface,
1191                                                         long StartIndex,
1192                                                         long Entries,
1193                                                         long *pRetrieved,
1194                                                         long *pPalette) {
1195     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1196
1197     FIXME("(%p/%p)->(%ld, %ld, %p, %p): stub !!!\n", This, iface, StartIndex, Entries, pRetrieved, pPalette);
1198
1199     return S_OK;
1200 }
1201
1202 static HRESULT WINAPI Basicvideo_GetCurrentImage(IBasicVideo *iface,
1203                                                  long *pBufferSize,
1204                                                  long *pDIBImage) {
1205     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1206
1207     FIXME("(%p/%p)->(%p, %p): stub !!!\n", This, iface, pBufferSize, pDIBImage);
1208
1209     return S_OK;
1210 }
1211
1212 static HRESULT WINAPI Basicvideo_IsUsingDefaultSource(IBasicVideo *iface) {
1213     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1214
1215     FIXME("(%p/%p)->(): stub !!!\n", This, iface);
1216
1217     return S_OK;
1218 }
1219
1220 static HRESULT WINAPI Basicvideo_IsUsingDefaultDestination(IBasicVideo *iface) {
1221     ICOM_THIS_MULTI(VideoRendererImpl, IBasicVideo_vtbl, iface);
1222
1223     FIXME("(%p/%p)->(): stub !!!\n", This, iface);
1224
1225     return S_OK;
1226 }
1227
1228
1229 static const IBasicVideoVtbl IBasicVideo_VTable =
1230 {
1231     Basicvideo_QueryInterface,
1232     Basicvideo_AddRef,
1233     Basicvideo_Release,
1234     Basicvideo_GetTypeInfoCount,
1235     Basicvideo_GetTypeInfo,
1236     Basicvideo_GetIDsOfNames,
1237     Basicvideo_Invoke,
1238     Basicvideo_get_AvgTimePerFrame,
1239     Basicvideo_get_BitRate,
1240     Basicvideo_get_BitErrorRate,
1241     Basicvideo_get_VideoWidth,
1242     Basicvideo_get_VideoHeight,
1243     Basicvideo_put_SourceLeft,
1244     Basicvideo_get_SourceLeft,
1245     Basicvideo_put_SourceWidth,
1246     Basicvideo_get_SourceWidth,
1247     Basicvideo_put_SourceTop,
1248     Basicvideo_get_SourceTop,
1249     Basicvideo_put_SourceHeight,
1250     Basicvideo_get_SourceHeight,
1251     Basicvideo_put_DestinationLeft,
1252     Basicvideo_get_DestinationLeft,
1253     Basicvideo_put_DestinationWidth,
1254     Basicvideo_get_DestinationWidth,
1255     Basicvideo_put_DestinationTop,
1256     Basicvideo_get_DestinationTop,
1257     Basicvideo_put_DestinationHeight,
1258     Basicvideo_get_DestinationHeight,
1259     Basicvideo_SetSourcePosition,
1260     Basicvideo_GetSourcePosition,
1261     Basicvideo_SetDefaultSourcePosition,
1262     Basicvideo_SetDestinationPosition,
1263     Basicvideo_GetDestinationPosition,
1264     Basicvideo_SetDefaultDestinationPosition,
1265     Basicvideo_GetVideoSize,
1266     Basicvideo_GetVideoPaletteEntries,
1267     Basicvideo_GetCurrentImage,
1268     Basicvideo_IsUsingDefaultSource,
1269     Basicvideo_IsUsingDefaultDestination
1270 };
1271
1272
1273 /*** IUnknown methods ***/
1274 static HRESULT WINAPI Videowindow_QueryInterface(IVideoWindow *iface,
1275                                                  REFIID riid,
1276                                                  LPVOID*ppvObj) {
1277     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1278
1279     TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
1280
1281     return VideoRenderer_QueryInterface((IBaseFilter*)This, riid, ppvObj);
1282 }
1283
1284 static ULONG WINAPI Videowindow_AddRef(IVideoWindow *iface) {
1285     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1286
1287     TRACE("(%p/%p)->()\n", This, iface);
1288
1289     return VideoRenderer_AddRef((IBaseFilter*)This);
1290 }
1291
1292 static ULONG WINAPI Videowindow_Release(IVideoWindow *iface) {
1293     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1294
1295     TRACE("(%p/%p)->()\n", This, iface);
1296
1297     return VideoRenderer_Release((IBaseFilter*)This);
1298 }
1299
1300 /*** IDispatch methods ***/
1301 static HRESULT WINAPI Videowindow_GetTypeInfoCount(IVideoWindow *iface,
1302                                                    UINT*pctinfo) {
1303     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1304
1305     FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo);
1306
1307     return S_OK;
1308 }
1309
1310 static HRESULT WINAPI Videowindow_GetTypeInfo(IVideoWindow *iface,
1311                                               UINT iTInfo,
1312                                               LCID lcid,
1313                                               ITypeInfo**ppTInfo) {
1314     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1315
1316     FIXME("(%p/%p)->(%d, %ld, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo);
1317
1318     return S_OK;
1319 }
1320
1321 static HRESULT WINAPI Videowindow_GetIDsOfNames(IVideoWindow *iface,
1322                                                 REFIID riid,
1323                                                 LPOLESTR*rgszNames,
1324                                                 UINT cNames,
1325                                                 LCID lcid,
1326                                                 DISPID*rgDispId) {
1327     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1328
1329     FIXME("(%p/%p)->(%s (%p), %p, %d, %ld, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId);
1330
1331     return S_OK;
1332 }
1333
1334 static HRESULT WINAPI Videowindow_Invoke(IVideoWindow *iface,
1335                                          DISPID dispIdMember,
1336                                          REFIID riid,
1337                                          LCID lcid,
1338                                          WORD wFlags,
1339                                          DISPPARAMS*pDispParams,
1340                                          VARIANT*pVarResult,
1341                                          EXCEPINFO*pExepInfo,
1342                                          UINT*puArgErr) {
1343     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1344
1345     FIXME("(%p/%p)->(%ld, %s (%p), %ld, %04x, %p, %p, %p, %p): stub !!!\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr);
1346
1347     return S_OK;
1348 }
1349
1350 /*** IVideoWindow methods ***/
1351 static HRESULT WINAPI Videowindow_put_Caption(IVideoWindow *iface,
1352                                               BSTR strCaption) {
1353     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1354
1355     TRACE("(%p/%p)->(%s (%p))\n", This, iface, debugstr_w(strCaption), strCaption);
1356
1357     if (!SetWindowTextW(This->hWnd, strCaption))
1358         return E_FAIL;
1359
1360     return S_OK;
1361 }
1362
1363 static HRESULT WINAPI Videowindow_get_Caption(IVideoWindow *iface,
1364                                               BSTR *strCaption) {
1365     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1366
1367     TRACE("(%p/%p)->(%p)\n", This, iface, strCaption);
1368
1369     GetWindowTextW(This->hWnd, (LPWSTR)strCaption, 100);
1370
1371     return S_OK;
1372 }
1373
1374 static HRESULT WINAPI Videowindow_put_WindowStyle(IVideoWindow *iface,
1375                                                   long WindowStyle) {
1376     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1377     LONG old;
1378
1379     old = GetWindowLongA(This->hWnd, GWL_STYLE);
1380     
1381     TRACE("(%p/%p)->(%lx -> %lx)\n", This, iface, old, WindowStyle);
1382
1383     if (WindowStyle & (WS_DISABLED|WS_HSCROLL|WS_ICONIC|WS_MAXIMIZE|WS_MINIMIZE|WS_VSCROLL))
1384         return E_INVALIDARG;
1385     
1386     SetWindowLongA(This->hWnd, GWL_STYLE, WindowStyle);
1387
1388     return S_OK;
1389 }
1390
1391 static HRESULT WINAPI Videowindow_get_WindowStyle(IVideoWindow *iface,
1392                                                   long *WindowStyle) {
1393     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1394
1395     TRACE("(%p/%p)->(%p)\n", This, iface, WindowStyle);
1396
1397     *WindowStyle = GetWindowLongA(This->hWnd, GWL_STYLE);
1398
1399     return S_OK;
1400 }
1401
1402 static HRESULT WINAPI Videowindow_put_WindowStyleEx(IVideoWindow *iface,
1403                                                     long WindowStyleEx) {
1404     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1405
1406     TRACE("(%p/%p)->(%ld)\n", This, iface, WindowStyleEx);
1407
1408     if (WindowStyleEx & (WS_DISABLED|WS_HSCROLL|WS_ICONIC|WS_MAXIMIZE|WS_MINIMIZE|WS_VSCROLL))
1409         return E_INVALIDARG;
1410
1411     if (!SetWindowLongA(This->hWnd, GWL_EXSTYLE, WindowStyleEx))
1412         return E_FAIL;
1413
1414     return S_OK;
1415 }
1416
1417 static HRESULT WINAPI Videowindow_get_WindowStyleEx(IVideoWindow *iface,
1418                                                     long *WindowStyleEx) {
1419     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1420
1421     TRACE("(%p/%p)->(%p)\n", This, iface, WindowStyleEx);
1422
1423     *WindowStyleEx = GetWindowLongA(This->hWnd, GWL_EXSTYLE);
1424
1425     return S_OK;
1426 }
1427
1428 static HRESULT WINAPI Videowindow_put_AutoShow(IVideoWindow *iface,
1429                                                long AutoShow) {
1430     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1431
1432     TRACE("(%p/%p)->(%ld)\n", This, iface, AutoShow);
1433
1434     This->AutoShow = 1; /* FXIME: Should be AutoShow */;
1435
1436     return S_OK;
1437 }
1438
1439 static HRESULT WINAPI Videowindow_get_AutoShow(IVideoWindow *iface,
1440                                                long *AutoShow) {
1441     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1442
1443     TRACE("(%p/%p)->(%p)\n", This, iface, AutoShow);
1444
1445     *AutoShow = This->AutoShow;
1446
1447     return S_OK;
1448 }
1449
1450 static HRESULT WINAPI Videowindow_put_WindowState(IVideoWindow *iface,
1451                                                   long WindowState) {
1452     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1453
1454     FIXME("(%p/%p)->(%ld): stub !!!\n", This, iface, WindowState);
1455
1456     return S_OK;
1457 }
1458
1459 static HRESULT WINAPI Videowindow_get_WindowState(IVideoWindow *iface,
1460                                                   long *WindowState) {
1461     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1462
1463     FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, WindowState);
1464
1465     return S_OK;
1466 }
1467
1468 static HRESULT WINAPI Videowindow_put_BackgroundPalette(IVideoWindow *iface,
1469                                                         long BackgroundPalette) {
1470     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1471
1472     FIXME("(%p/%p)->(%ld): stub !!!\n", This, iface, BackgroundPalette);
1473
1474     return S_OK;
1475 }
1476
1477 static HRESULT WINAPI Videowindow_get_BackgroundPalette(IVideoWindow *iface,
1478                                                         long *pBackgroundPalette) {
1479     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1480
1481     FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pBackgroundPalette);
1482
1483     return S_OK;
1484 }
1485
1486 static HRESULT WINAPI Videowindow_put_Visible(IVideoWindow *iface,
1487                                               long Visible) {
1488     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1489
1490     TRACE("(%p/%p)->(%ld)\n", This, iface, Visible);
1491
1492     ShowWindow(This->hWnd, Visible ? SW_SHOW : SW_HIDE);
1493
1494     return S_OK;
1495 }
1496
1497 static HRESULT WINAPI Videowindow_get_Visible(IVideoWindow *iface,
1498                                               long *pVisible) {
1499     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1500
1501     TRACE("(%p/%p)->(%p)\n", This, iface, pVisible);
1502
1503     *pVisible = IsWindowVisible(This->hWnd);
1504
1505     return S_OK;
1506 }
1507
1508 static HRESULT WINAPI Videowindow_put_Left(IVideoWindow *iface,
1509                                            long Left) {
1510     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1511
1512     TRACE("(%p/%p)->(%ld)\n", This, iface, Left);
1513
1514     if (!SetWindowPos(This->hWnd, NULL, Left, This->WindowPos.top, 0, 0, SWP_NOZORDER|SWP_NOSIZE))
1515         return E_FAIL;
1516
1517     This->WindowPos.left = Left;
1518
1519     return S_OK;
1520 }
1521
1522 static HRESULT WINAPI Videowindow_get_Left(IVideoWindow *iface,
1523                                            long *pLeft) {
1524     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1525
1526     TRACE("(%p/%p)->(%p)\n", This, iface, pLeft);
1527
1528     *pLeft = This->WindowPos.left;
1529
1530     return S_OK;
1531 }
1532
1533 static HRESULT WINAPI Videowindow_put_Width(IVideoWindow *iface,
1534                                             long Width) {
1535     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1536
1537     TRACE("(%p/%p)->(%ld)\n", This, iface, Width);
1538
1539     if (!SetWindowPos(This->hWnd, NULL, 0, 0, Width, This->WindowPos.bottom-This->WindowPos.top, SWP_NOZORDER|SWP_NOMOVE))
1540         return E_FAIL;
1541
1542     This->WindowPos.right = This->WindowPos.left + Width;
1543
1544     return S_OK;
1545 }
1546
1547 static HRESULT WINAPI Videowindow_get_Width(IVideoWindow *iface,
1548                                             long *pWidth) {
1549     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1550
1551     TRACE("(%p/%p)->(%p)\n", This, iface, pWidth);
1552
1553     *pWidth = This->WindowPos.right - This->WindowPos.left;
1554
1555     return S_OK;
1556 }
1557
1558 static HRESULT WINAPI Videowindow_put_Top(IVideoWindow *iface,
1559                                           long Top) {
1560     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1561
1562     TRACE("(%p/%p)->(%ld)\n", This, iface, Top);
1563
1564     if (!SetWindowPos(This->hWnd, NULL, This->WindowPos.left, Top, 0, 0, SWP_NOZORDER|SWP_NOSIZE))
1565         return E_FAIL;
1566
1567     This->WindowPos.top = Top;
1568
1569     return S_OK;
1570 }
1571
1572 static HRESULT WINAPI Videowindow_get_Top(IVideoWindow *iface,
1573                                           long *pTop) {
1574     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1575
1576     TRACE("(%p/%p)->(%p)\n", This, iface, pTop);
1577
1578     *pTop = This->WindowPos.top;
1579
1580     return S_OK;
1581 }
1582
1583 static HRESULT WINAPI Videowindow_put_Height(IVideoWindow *iface,
1584                                              long Height) {
1585     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1586
1587     TRACE("(%p/%p)->(%ld)\n", This, iface, Height);
1588
1589     if (!SetWindowPos(This->hWnd, NULL, 0, 0, This->WindowPos.right-This->WindowPos.left, Height, SWP_NOZORDER|SWP_NOMOVE))
1590         return E_FAIL;
1591
1592     This->WindowPos.bottom = This->WindowPos.top + Height;
1593
1594     return S_OK;
1595 }
1596
1597 static HRESULT WINAPI Videowindow_get_Height(IVideoWindow *iface,
1598                                              long *pHeight) {
1599     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1600
1601     TRACE("(%p/%p)->(%p)\n", This, iface, pHeight);
1602
1603     *pHeight = This->WindowPos.bottom - This->WindowPos.top;
1604
1605     return S_OK;
1606 }
1607
1608 static HRESULT WINAPI Videowindow_put_Owner(IVideoWindow *iface,
1609                                             OAHWND Owner) {
1610     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1611
1612     TRACE("(%p/%p)->(%08lx)\n", This, iface, (DWORD) Owner);
1613
1614     SetParent(This->hWnd, (HWND)Owner);
1615
1616     return S_OK;
1617 }
1618
1619 static HRESULT WINAPI Videowindow_get_Owner(IVideoWindow *iface,
1620                                             OAHWND *Owner) {
1621     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1622
1623     TRACE("(%p/%p)->(%08lx)\n", This, iface, (DWORD) Owner);
1624
1625     *(HWND*)Owner = GetParent(This->hWnd);
1626
1627     return S_OK;
1628 }
1629
1630 static HRESULT WINAPI Videowindow_put_MessageDrain(IVideoWindow *iface,
1631                                                    OAHWND Drain) {
1632     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1633
1634     TRACE("(%p/%p)->(%08lx)\n", This, iface, (DWORD) Drain);
1635
1636     This->hWndMsgDrain = (HWND)Drain;
1637
1638     return S_OK;
1639 }
1640
1641 static HRESULT WINAPI Videowindow_get_MessageDrain(IVideoWindow *iface,
1642                                                    OAHWND *Drain) {
1643     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1644
1645     TRACE("(%p/%p)->(%p)\n", This, iface, Drain);
1646
1647     *Drain = (OAHWND)This->hWndMsgDrain;
1648
1649     return S_OK;
1650 }
1651
1652 static HRESULT WINAPI Videowindow_get_BorderColor(IVideoWindow *iface,
1653                                                   long *Color) {
1654     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1655
1656     FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, Color);
1657
1658     return S_OK;
1659 }
1660
1661 static HRESULT WINAPI Videowindow_put_BorderColor(IVideoWindow *iface,
1662                                                   long Color) {
1663     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1664
1665     FIXME("(%p/%p)->(%ld): stub !!!\n", This, iface, Color);
1666
1667     return S_OK;
1668 }
1669
1670 static HRESULT WINAPI Videowindow_get_FullScreenMode(IVideoWindow *iface,
1671                                                      long *FullScreenMode) {
1672     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1673
1674     FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, FullScreenMode);
1675
1676     return S_OK;
1677 }
1678
1679 static HRESULT WINAPI Videowindow_put_FullScreenMode(IVideoWindow *iface,
1680                                                      long FullScreenMode) {
1681     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1682
1683     FIXME("(%p/%p)->(%ld): stub !!!\n", This, iface, FullScreenMode);
1684
1685     return S_OK;
1686 }
1687
1688 static HRESULT WINAPI Videowindow_SetWindowForeground(IVideoWindow *iface,
1689                                                       long Focus) {
1690     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1691     BOOL ret;
1692     IPin* pPin;
1693     HRESULT hr;
1694
1695     TRACE("(%p/%p)->(%ld)\n", This, iface, Focus);
1696
1697     if ((Focus != FALSE) && (Focus != TRUE))
1698         return E_INVALIDARG;
1699
1700     hr = IPin_ConnectedTo(This->ppPins[0], &pPin);
1701     if ((hr != S_OK) || !pPin)
1702         return VFW_E_NOT_CONNECTED;
1703
1704     if (Focus)
1705         ret = SetForegroundWindow(This->hWnd);
1706     else
1707         ret = SetWindowPos(This->hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
1708
1709     if (!ret)
1710         return E_FAIL;
1711
1712     return S_OK;
1713 }
1714
1715 static HRESULT WINAPI Videowindow_NotifyOwnerMessage(IVideoWindow *iface,
1716                                                      OAHWND hwnd,
1717                                                      long uMsg,
1718                                                      LONG_PTR wParam,
1719                                                      LONG_PTR lParam) {
1720     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1721
1722     TRACE("(%p/%p)->(%08lx, %ld, %08lx, %08lx)\n", This, iface, (DWORD) hwnd, uMsg, wParam, lParam);
1723
1724     if (!PostMessageA(This->hWnd, uMsg, wParam, lParam))
1725         return E_FAIL;
1726     
1727     return S_OK;
1728 }
1729
1730 static HRESULT WINAPI Videowindow_SetWindowPosition(IVideoWindow *iface,
1731                                                     long Left,
1732                                                     long Top,
1733                                                     long Width,
1734                                                     long Height) {
1735     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1736     
1737     TRACE("(%p/%p)->(%ld, %ld, %ld, %ld)\n", This, iface, Left, Top, Width, Height);
1738
1739     if (!SetWindowPos(This->hWnd, NULL, Left, Top, Width, Height, SWP_NOZORDER))
1740         return E_FAIL;
1741
1742     This->WindowPos.left = Left;
1743     This->WindowPos.top = Top;
1744     This->WindowPos.right = Left + Width;
1745     This->WindowPos.bottom = Top + Height;
1746     
1747     return S_OK;
1748 }
1749
1750 static HRESULT WINAPI Videowindow_GetWindowPosition(IVideoWindow *iface,
1751                                                     long *pLeft,
1752                                                     long *pTop,
1753                                                     long *pWidth,
1754                                                     long *pHeight) {
1755     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1756
1757     TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight);
1758
1759     *pLeft = This->WindowPos.left;
1760     *pTop = This->WindowPos.top;
1761     *pWidth = This->WindowPos.right - This->WindowPos.left;
1762     *pHeight = This->WindowPos.bottom - This->WindowPos.top;
1763
1764     return S_OK;
1765 }
1766
1767 static HRESULT WINAPI Videowindow_GetMinIdealImageSize(IVideoWindow *iface,
1768                                                        long *pWidth,
1769                                                        long *pHeight) {
1770     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1771
1772     FIXME("(%p/%p)->(%p, %p): semi stub !!!\n", This, iface, pWidth, pHeight);
1773
1774     *pWidth = This->VideoWidth;
1775     *pHeight = This->VideoHeight;
1776
1777     return S_OK;
1778 }
1779
1780 static HRESULT WINAPI Videowindow_GetMaxIdealImageSize(IVideoWindow *iface,
1781                                                        long *pWidth,
1782                                                        long *pHeight) {
1783     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1784
1785     FIXME("(%p/%p)->(%p, %p): semi stub !!!\n", This, iface, pWidth, pHeight);
1786
1787     *pWidth = This->VideoWidth;
1788     *pHeight = This->VideoHeight;
1789
1790     return S_OK;
1791 }
1792
1793 static HRESULT WINAPI Videowindow_GetRestorePosition(IVideoWindow *iface,
1794                                                      long *pLeft,
1795                                                      long *pTop,
1796                                                      long *pWidth,
1797                                                      long *pHeight) {
1798     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1799
1800     FIXME("(%p/%p)->(%p, %p, %p, %p): stub !!!\n", This, iface, pLeft, pTop, pWidth, pHeight);
1801
1802     return S_OK;
1803 }
1804
1805 static HRESULT WINAPI Videowindow_HideCursor(IVideoWindow *iface,
1806                                              long HideCursor) {
1807     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1808
1809     FIXME("(%p/%p)->(%ld): stub !!!\n", This, iface, HideCursor);
1810
1811     return S_OK;
1812 }
1813
1814 static HRESULT WINAPI Videowindow_IsCursorHidden(IVideoWindow *iface,
1815                                                  long *CursorHidden) {
1816     ICOM_THIS_MULTI(VideoRendererImpl, IVideoWindow_vtbl, iface);
1817
1818     FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, CursorHidden);
1819
1820     return S_OK;
1821 }
1822
1823 static const IVideoWindowVtbl IVideoWindow_VTable =
1824 {
1825     Videowindow_QueryInterface,
1826     Videowindow_AddRef,
1827     Videowindow_Release,
1828     Videowindow_GetTypeInfoCount,
1829     Videowindow_GetTypeInfo,
1830     Videowindow_GetIDsOfNames,
1831     Videowindow_Invoke,
1832     Videowindow_put_Caption,
1833     Videowindow_get_Caption,
1834     Videowindow_put_WindowStyle,
1835     Videowindow_get_WindowStyle,
1836     Videowindow_put_WindowStyleEx,
1837     Videowindow_get_WindowStyleEx,
1838     Videowindow_put_AutoShow,
1839     Videowindow_get_AutoShow,
1840     Videowindow_put_WindowState,
1841     Videowindow_get_WindowState,
1842     Videowindow_put_BackgroundPalette,
1843     Videowindow_get_BackgroundPalette,
1844     Videowindow_put_Visible,
1845     Videowindow_get_Visible,
1846     Videowindow_put_Left,
1847     Videowindow_get_Left,
1848     Videowindow_put_Width,
1849     Videowindow_get_Width,
1850     Videowindow_put_Top,
1851     Videowindow_get_Top,
1852     Videowindow_put_Height,
1853     Videowindow_get_Height,
1854     Videowindow_put_Owner,
1855     Videowindow_get_Owner,
1856     Videowindow_put_MessageDrain,
1857     Videowindow_get_MessageDrain,
1858     Videowindow_get_BorderColor,
1859     Videowindow_put_BorderColor,
1860     Videowindow_get_FullScreenMode,
1861     Videowindow_put_FullScreenMode,
1862     Videowindow_SetWindowForeground,
1863     Videowindow_NotifyOwnerMessage,
1864     Videowindow_SetWindowPosition,
1865     Videowindow_GetWindowPosition,
1866     Videowindow_GetMinIdealImageSize,
1867     Videowindow_GetMaxIdealImageSize,
1868     Videowindow_GetRestorePosition,
1869     Videowindow_HideCursor,
1870     Videowindow_IsCursorHidden
1871 };