From 4b5f35d0c7d275371739af5619e82defc82c3746 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Thu, 24 Jul 2008 13:09:11 -0700 Subject: [PATCH] quartz: Add support for IBasicVideo and IVideoWindow to VMR-9 --- dlls/quartz/tests/vmr9.c | 10 +- dlls/quartz/vmr9.c | 1460 +++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 1374 insertions(+), 96 deletions(-) diff --git a/dlls/quartz/tests/vmr9.c b/dlls/quartz/tests/vmr9.c index 4d8d427..76be37a 100644 --- a/dlls/quartz/tests/vmr9.c +++ b/dlls/quartz/tests/vmr9.c @@ -305,7 +305,7 @@ static void test_playback(IVMRWindowlessControl9 *windowless) if (!windowless) ok(WaitForSingleObject(handle, 100) == WAIT_TIMEOUT, "Waiting for Receive call to return didn't time out\n"); else - ok(WaitForSingleObject(handle, 100) == WAIT_OBJECT_0, "Waiting for Receive call to return timed out\n"); + todo_wine ok(WaitForSingleObject(handle, 100) == WAIT_OBJECT_0, "Waiting for Receive call to return timed out\n"); hr = IBaseFilter_GetState(base_vmr9, 0, &state); ok(hr == S_OK, "State check returned: %08x\n", hr); @@ -391,8 +391,8 @@ static void test_mode_queryinterface(VMR9Mode mode) if (mode == VMR9Mode_Windowed) { hr = IUnknown_QueryInterface(pvmr9, &IID_IBasicVideo, (LPVOID*)&iface); - todo_wine ok(hr == S_OK, "IUnknown_QueryInterface returned %x\n", hr); - todo_wine ok(iface != NULL, "Pointer is NULL\n"); + ok(hr == S_OK, "IUnknown_QueryInterface returned %x\n", hr); + ok(iface != NULL, "Pointer is NULL\n"); if (iface) { ref = IUnknown_Release(iface); @@ -411,8 +411,8 @@ static void test_mode_queryinterface(VMR9Mode mode) iface = NULL; hr = IUnknown_QueryInterface(pvmr9, &IID_IVideoWindow, (LPVOID*)&iface); - todo_wine ok(hr == S_OK, "IUnknown_QueryInterface returned %x\n", hr); - todo_wine ok(iface != NULL, "Pointer is NULL\n"); + ok(hr == S_OK, "IUnknown_QueryInterface returned %x\n", hr); + ok(iface != NULL, "Pointer is NULL\n"); if (iface) { ref = IUnknown_Release(iface); diff --git a/dlls/quartz/vmr9.c b/dlls/quartz/vmr9.c index f949af6..3329644 100644 --- a/dlls/quartz/vmr9.c +++ b/dlls/quartz/vmr9.c @@ -59,13 +59,19 @@ static const IVMRSurfaceAllocatorNotify9Vtbl IVMRSurfaceAllocatorNotify9_Vtbl; static const IVMRImagePresenter9Vtbl VMR9_ImagePresenter; static const IVMRSurfaceAllocatorEx9Vtbl VMR9_SurfaceAllocator; +static const IVideoWindowVtbl IVideoWindow_VTable; +static const IBasicVideoVtbl IBasicVideo_VTable; + typedef struct VMR9Impl { const IBaseFilterVtbl * lpVtbl; const IVMRFilterConfig9Vtbl *IVMRFilterConfig9_vtbl; const IVMRWindowlessControl9Vtbl *IVMRWindowlessControl9_vtbl; const IVMRSurfaceAllocatorNotify9Vtbl *IVMRSurfaceAllocatorNotify9_vtbl; - const IUnknownVtbl * IInner_vtbl; + const IUnknownVtbl *IInner_vtbl; + + const IVideoWindowVtbl *IVideoWindow_vtbl; + const IBasicVideoVtbl *IBasicVideo_vtbl; IVMRSurfaceAllocatorEx9 *allocator; BOOL allocator_is_ex; @@ -108,18 +114,18 @@ typedef struct VMR9Impl REFERENCE_TIME rtLastStop; VMR9AllocationInfo info; DWORD_PTR cookie; - HWND hwnd_last, hwnd_mine; + HWND hwnd_last, hwnd_mine, hwnd_drain; HDC hdc_last; HMONITOR mon_last; HANDLE thread_hwnd, state_handle, blocked; DWORD tid; - UINT syncmsg; - HANDLE ack; - BOOL reset; + BOOL reset, autoshow, next_visible; RECT source_rect; RECT target_rect; + RECT window_rect; + IMediaSample *sample_held; /* Memory allocator things */ /* Preferred memory allocator for input pins, no others are currently accepted */ @@ -356,14 +362,42 @@ static HRESULT VMR9_Sample(LPVOID iface, IMediaSample * pSample) return S_FALSE; } - IMediaSample_AddRef(pSample); + if (This->next_visible && This->hwnd_mine) + { + ShowWindow(This->hwnd_mine, SW_SHOW); + This->next_visible = FALSE; + } + + VMR9_SurfaceAllocator_UpdateDeviceReset(This); + if (!This->d3d9_dev) + { + WARN("Device has left me!\n"); + LeaveCriticalSection(&This->csFilter); + return S_OK; + } - hr = SendMessageW(This->hwnd_mine, This->syncmsg, (WPARAM)pSample, (LPARAM)&info); + hr = IVMRSurfaceAllocator9_GetSurface(This->allocator, This->cookie, (++This->cur_surface)%This->num_surfaces, 0, &info.lpSurf); + if (SUCCEEDED(hr)) + { + VMR9_SendSampleData(This, &info, pbSrcStream, cbSrcStream); + IDirect3DSurface9_Release(info.lpSurf); + } + else + { + LeaveCriticalSection(&This->csFilter); + return hr; + } SetEvent(This->state_handle); - LeaveCriticalSection(&This->csFilter); if (This->state == State_Paused) + { + This->sample_held = pSample; + LeaveCriticalSection(&This->csFilter); WaitForSingleObject(This->blocked, INFINITE); + This->sample_held = NULL; + } + else + LeaveCriticalSection(&This->csFilter); return hr; } @@ -643,6 +677,8 @@ HRESULT VMR9Impl_create(IUnknown * pUnkOuter, LPVOID * ppv) pVMR9->bUnkOuterValid = FALSE; pVMR9->bAggregatable = FALSE; pVMR9->IInner_vtbl = &IInner_VTable; + pVMR9->IBasicVideo_vtbl = &IBasicVideo_VTable; + pVMR9->IVideoWindow_vtbl = &IVideoWindow_VTable; pVMR9->lpVtbl = &VMR9_Vtbl; pVMR9->IVMRFilterConfig9_vtbl = &VMR9_FilterConfig_Vtbl; @@ -667,7 +703,7 @@ HRESULT VMR9Impl_create(IUnknown * pUnkOuter, LPVOID * ppv) pVMR9->ack = CreateEventW(NULL, 0, 0, NULL); pVMR9->allocator = NULL; pVMR9->presenter = NULL; - pVMR9->hwnd_last = pVMR9->hwnd_mine = NULL; + pVMR9->hwnd_last = pVMR9->hwnd_mine = pVMR9->hwnd_drain = NULL; pVMR9->hdc_last = NULL; pVMR9->mon_last = NULL; pVMR9->reset = 0; @@ -697,10 +733,16 @@ HRESULT VMR9Impl_create(IUnknown * pUnkOuter, LPVOID * ppv) *ppv = (LPVOID)pVMR9; ZeroMemory(&pVMR9->source_rect, sizeof(RECT)); ZeroMemory(&pVMR9->target_rect, sizeof(RECT)); - pVMR9->syncmsg = RegisterWindowMessageA("IVMR9 message for drawing a single surface"); - ERR("Created at %p\n", pVMR9); + ZeroMemory(&pVMR9->window_rect, sizeof(RECT)); + + TRACE("Created at %p\n", pVMR9); pVMR9->state_handle = CreateEventW(NULL, TRUE, TRUE, NULL); pVMR9->blocked = CreateEventW(NULL, FALSE, FALSE, NULL); + pVMR9->autoshow = TRUE; + pVMR9->next_visible = FALSE; + + IMemInputPin_NotifyAllocator((IMemInputPin *)&pVMR9->pInputPin->lpVtblMemInput, (IMemAllocator *)&pVMR9->memalloc, FALSE); + IMemAllocator_Release((IMemAllocator *)&pVMR9->memalloc); } else { @@ -719,7 +761,7 @@ static void VMR9Impl_destroy(VMR9Impl *This) { IPin *pConnectedTo; - ERR("Destroying\n"); + TRACE("Destroying\n"); if (This->pClock) IReferenceClock_Release(This->pClock); @@ -756,43 +798,35 @@ static LRESULT CALLBACK VideoWndProcW(HWND hwnd, UINT uMsg, WPARAM wParam, LPARA if (!pVMR9) return DefWindowProcW(hwnd, uMsg, wParam, lParam); - if (uMsg == pVMR9->syncmsg) - { - IMediaSample *sample = (IMediaSample *)wParam; - VMR9PresentationInfo *info = (VMR9PresentationInfo *)lParam; - HRESULT hr; - BYTE *pbSrcStream; - DWORD cbSrcStream; - - IMediaSample_GetPointer(sample, &pbSrcStream); - cbSrcStream = IMediaSample_GetActualDataLength(sample); - - /* Update everything first, this is needed because the surface might be destroyed in the reset */ - VMR9_SurfaceAllocator_UpdateDeviceReset(pVMR9); - - if (!pVMR9->d3d9_dev) - { - TRACE("Device has left me!\n"); - IMediaSample_Release(sample); - return S_OK; - } - - hr = IVMRSurfaceAllocator9_GetSurface(pVMR9->allocator, pVMR9->cookie, (++pVMR9->cur_surface)%pVMR9->num_surfaces, 0, &info->lpSurf); - - if (FAILED(hr)) - { - IMediaSample_Release(sample); - return hr; - } - - VMR9_SendSampleData(pVMR9, info, pbSrcStream, cbSrcStream); - IMediaSample_Release(info->lpSurf); - IMediaSample_Release(sample); - return hr; - } - switch(uMsg) { + case WM_KEYDOWN: + case WM_KEYUP: + case WM_LBUTTONDBLCLK: + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + case WM_MBUTTONDBLCLK: + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: + case WM_MOUSEACTIVATE: + case WM_MOUSEMOVE: + case WM_NCLBUTTONDBLCLK: + case WM_NCLBUTTONDOWN: + case WM_NCLBUTTONUP: + case WM_NCMBUTTONDBLCLK: + case WM_NCMBUTTONDOWN: + case WM_NCMBUTTONUP: + case WM_NCMOUSEMOVE: + case WM_NCRBUTTONDBLCLK: + case WM_NCRBUTTONDOWN: + case WM_NCRBUTTONUP: + case WM_RBUTTONDBLCLK: + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: + if (pVMR9->hwnd_drain) + PostMessageW(pVMR9->hwnd_drain, uMsg, wParam, lParam); + return TRUE; + case WM_WINDOWPOSCHANGING: { WINDOWPOS *pos = (WINDOWPOS *)lParam; @@ -803,7 +837,7 @@ static LRESULT CALLBACK VideoWndProcW(HWND hwnd, UINT uMsg, WPARAM wParam, LPARA rect.right = rect.left + pos->cx; lprect = ▭ - ERR("WM_WINDOWPOSCHANGING %d %d %d %d\n", lprect->left, lprect->top, lprect->right, lprect->bottom); + TRACE("WM_WINDOWPOSCHANGING %d %d %d %d\n", lprect->left, lprect->top, lprect->right, lprect->bottom); return TRUE; } case WM_WINDOWPOSCHANGED: @@ -816,16 +850,15 @@ static LRESULT CALLBACK VideoWndProcW(HWND hwnd, UINT uMsg, WPARAM wParam, LPARA rect.right = rect.left + pos->cx; lprect = ▭ - FIXME("Flags: %08x\n", pos->flags); - - ERR("WM_WINDOWPOSCHANGED %d %d %d %d\n", lprect->left, lprect->top, lprect->right, lprect->bottom); - GetWindowRect(hwnd, &pVMR9->target_rect); + TRACE("Flags: %08x\n", pos->flags); + TRACE("WM_WINDOWPOSCHANGED %d %d %d %d\n", lprect->left, lprect->top, lprect->right, lprect->bottom); + GetWindowRect(hwnd, &pVMR9->window_rect); if (pVMR9->mode == VMR9Mode_Windowed) { - pVMR9->target_rect.left += GetSystemMetrics(SM_CXFRAME); - pVMR9->target_rect.right -= GetSystemMetrics(SM_CXFRAME); - pVMR9->target_rect.top += GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYCAPTION); - pVMR9->target_rect.bottom -= GetSystemMetrics(SM_CYFRAME); + pVMR9->window_rect.left += GetSystemMetrics(SM_CXFRAME); + pVMR9->window_rect.right -= GetSystemMetrics(SM_CXFRAME); + pVMR9->window_rect.top += GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYCAPTION); + pVMR9->window_rect.bottom -= GetSystemMetrics(SM_CYFRAME); } if (!(pos->flags & SWP_NOSIZE)) pVMR9->reset = TRUE; @@ -833,23 +866,23 @@ static LRESULT CALLBACK VideoWndProcW(HWND hwnd, UINT uMsg, WPARAM wParam, LPARA } case WM_SIZING: - ERR("WM_SIZING %d %d %d %d\n", lprect->left, lprect->top, lprect->right, lprect->bottom); + TRACE("WM_SIZING %d %d %d %d\n", lprect->left, lprect->top, lprect->right, lprect->bottom); SetWindowPos(hwnd, NULL, lprect->left, lprect->top, lprect->right - lprect->left, lprect->bottom - lprect->top, SWP_NOZORDER); - ERR("WM_SIZING: target_rect=(%d,%d),(%d,%d)\n", - pVMR9->target_rect.left, - pVMR9->target_rect.top, - pVMR9->target_rect.right - pVMR9->target_rect.left, - pVMR9->target_rect.bottom - pVMR9->target_rect.top); + TRACE("WM_SIZING: target_rect=(%d,%d),(%d,%d)\n", + pVMR9->window_rect.left, + pVMR9->window_rect.top, + pVMR9->window_rect.right - pVMR9->window_rect.left, + pVMR9->window_rect.bottom - pVMR9->window_rect.top); return TRUE; case WM_SIZE: - ERR("WM_SIZE %d %d\n", LOWORD(lParam), HIWORD(lParam)); - GetClientRect(hwnd, &pVMR9->target_rect); - ERR("WM_SIZE: target_rect=(%d,%d),(%d,%d)\n", - pVMR9->target_rect.left, - pVMR9->target_rect.top, - pVMR9->target_rect.right - pVMR9->target_rect.left, - pVMR9->target_rect.bottom - pVMR9->target_rect.top); + TRACE("WM_SIZE %d %d\n", LOWORD(lParam), HIWORD(lParam)); + GetClientRect(hwnd, &pVMR9->window_rect); + TRACE("WM_SIZE: target_rect=(%d,%d),(%d,%d)\n", + pVMR9->window_rect.left, + pVMR9->window_rect.top, + pVMR9->window_rect.right - pVMR9->window_rect.left, + pVMR9->window_rect.bottom - pVMR9->window_rect.top); return TRUE; case WM_ERASEBKGND: @@ -925,23 +958,23 @@ static DWORD WINAPI MessageLoop(LPVOID lpParameter) if (This->mode == VMR9Mode_Windowed) { - if (!This->target_rect.bottom || !This->target_rect.right) + if (!This->window_rect.bottom || !This->window_rect.right) { - This->target_rect = This->source_rect; - This->target_rect.right += 2 * GetSystemMetrics(SM_CXFRAME); - This->target_rect.bottom += 2 * GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYCAPTION); + This->window_rect = This->source_rect; + This->window_rect.right += 2 * GetSystemMetrics(SM_CXFRAME); + This->window_rect.bottom += 2 * GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYCAPTION); } This->hwnd_mine = CreateWindowExW(0, winclass.lpszClassName, windowname, WS_SIZEBOX, - This->target_rect.left, This->target_rect.top, - This->target_rect.right - This->target_rect.left, - This->target_rect.bottom - This->target_rect.top, + This->window_rect.left, This->window_rect.top, + This->window_rect.right - This->window_rect.left, + This->window_rect.bottom - This->window_rect.top, NULL, NULL, NULL, NULL); } else This->hwnd_mine = CreateWindowExW(WS_EX_NOPARENTNOTIFY, winclass.lpszClassName, windowname, WS_CHILD, - This->target_rect.left, This->target_rect.top, - This->target_rect.right - This->target_rect.left, - This->target_rect.bottom - This->target_rect.top, + This->window_rect.left, This->window_rect.top, + This->window_rect.right - This->window_rect.left, + This->window_rect.bottom - This->window_rect.top, This->hwnd_last, NULL, NULL, NULL); SetWindowLongW(This->hwnd_mine, 0, (LONG)This); @@ -984,8 +1017,8 @@ static BOOL CreateRenderingWindow(VMR9Impl *This, VMR9AllocationInfo *info, DWOR d3dpp.Windowed = TRUE; d3dpp.hDeviceWindow = This->hwnd_mine; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; - d3dpp.BackBufferHeight = This->target_rect.bottom - This->target_rect.top; - d3dpp.BackBufferWidth = This->target_rect.right - This->target_rect.left; + d3dpp.BackBufferHeight = This->window_rect.bottom - This->window_rect.top; + d3dpp.BackBufferWidth = This->window_rect.right - This->window_rect.left; hr = IDirect3D9_CreateDevice(This->d3d9_ptr, d3d9_adapter, D3DDEVTYPE_HAL, NULL, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &This->d3d9_dev); if (FAILED(hr)) @@ -1044,6 +1077,10 @@ static HRESULT WINAPI VMR9Inner_QueryInterface(IUnknown * iface, REFIID riid, LP *ppv = (LPVOID)This; else if (IsEqualIID(riid, &IID_IMediaSeeking)) *ppv = &This->mediaSeeking; + else if (IsEqualIID(riid, &IID_IVideoWindow) && This->mode == VMR9Mode_Windowed) + *ppv = &This->IVideoWindow_vtbl; + else if (IsEqualIID(riid, &IID_IBasicVideo) && This->mode == VMR9Mode_Windowed) + *ppv = &This->IBasicVideo_vtbl; else if (IsEqualIID(riid, &IID_IVMRFilterConfig9)) *ppv = &This->IVMRFilterConfig9_vtbl; else if (IsEqualIID(riid, &IID_IVMRWindowlessControl9) && This->mode == VMR9Mode_Windowless) @@ -1268,7 +1305,7 @@ static HRESULT VMR9_maybe_init(VMR9Impl *This, BOOL force) return (force ? VFW_E_RUNTIME_ERROR : S_OK); ERR("Initializing\n"); -// info.dwFlags = VMR9AllocFlag_TextureSurface; + info.dwFlags = VMR9AllocFlag_TextureSurface; info.dwFlags = VMR9AllocFlag_OffscreenSurface; info.dwHeight = This->source_rect.bottom; info.dwWidth = This->source_rect.right; @@ -1327,6 +1364,8 @@ static HRESULT WINAPI VMR9_Run(IBaseFilter * iface, REFERENCE_TIME tStart) This->rtStreamStart = tStart; if (This->state != State_Running) { + This->next_visible = This->autoshow; + if (This->state == State_Stopped) ResetEvent(This->state_handle); @@ -1340,7 +1379,7 @@ static HRESULT WINAPI VMR9_Run(IBaseFilter * iface, REFERENCE_TIME tStart) } else hr = IVMRImagePresenter9_StartPresenting(This->presenter, This->cookie); } - ShowWindow(This->hwnd_mine, SW_SHOW); + if (SUCCEEDED(hr)) This->state = State_Running; This->pInputPin->end_of_stream = 0; @@ -1846,6 +1885,7 @@ static HRESULT VMR9_SurfaceAllocator_UpdateDeviceReset(VMR9Impl *This) void *bits = NULL; D3DPRESENT_PARAMETERS d3dpp; HRESULT hr; + RECT *target; assert(This->hwnd_mine); if (!This->d3d9_surfaces || !This->reset) @@ -1884,6 +1924,11 @@ static HRESULT VMR9_SurfaceAllocator_UpdateDeviceReset(VMR9Impl *This) return S_OK; } + if (This->target_rect.right && This->target_rect.bottom) + target = &This->target_rect; + else + target = &This->window_rect; + IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper((IVMRSurfaceAllocatorNotify9 *)&This->IVMRSurfaceAllocatorNotify9_vtbl, &This->info, &This->num_surfaces, This->d3d9_surfaces); @@ -1902,7 +1947,7 @@ static HRESULT VMR9_SurfaceAllocator_UpdateDeviceReset(VMR9Impl *This) { if (i % 2) { - t_vert[i].x = (float)This->target_rect.right - (float)This->target_rect.left - 0.5f; + t_vert[i].x = (float)target->right - (float)target->left - 0.5f; t_vert[i].u = (float)This->source_rect.right / (float)width; } else @@ -1918,7 +1963,7 @@ static HRESULT VMR9_SurfaceAllocator_UpdateDeviceReset(VMR9Impl *This) } else { - t_vert[i].y = (float)This->target_rect.bottom - (float)This->target_rect.top - 0.5f; + t_vert[i].y = (float)target->bottom - (float)target->top - 0.5f; t_vert[i].v = (float)This->source_rect.top / (float)height; } t_vert[i].z = 0.0f; @@ -1950,7 +1995,7 @@ static HRESULT WINAPI VMR9WindowlessControl_SetVideoPosition(IVMRWindowlessContr This->source_rect = *source; if (dest) { - This->target_rect = *dest; + This->window_rect = *dest; if (This->hwnd_mine) { FIXME("Output rectangle: starting at %dx%d, up to point %dx%d\n", dest->left, dest->top, dest->right, dest->bottom); @@ -1973,7 +2018,7 @@ static HRESULT WINAPI VMR9WindowlessControl_GetVideoPosition(IVMRWindowlessContr *source = This->source_rect; if (dest) - *dest = This->target_rect; + *dest = This->window_rect; FIXME("(%p/%p)->(%p/%p) stub\n", iface, This, source, dest); return S_OK; @@ -2169,7 +2214,7 @@ static HRESULT WINAPI VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper(IVMRSurfa INT i; HRESULT hr = S_OK; - FIXME("(%p/%p)->(%p, %p => %u, %p) semi-stub\n", iface, This, allocinfo, numbuffers, (numbuffers ? *numbuffers : 0), surface); + TRACE("(%p/%p)->(%p, %p => %u, %p) semi-stub\n", iface, This, allocinfo, numbuffers, (numbuffers ? *numbuffers : 0), surface); if (!allocinfo || !numbuffers || !surface) return E_POINTER; @@ -2340,7 +2385,10 @@ static HRESULT VMR9_ImagePresenter_PresentOffscreenSurface(VMR9Impl *This, IDire return hr; } - target_rect = This->target_rect; + if (This->target_rect.bottom && This->target_rect.right) + target_rect = This->target_rect; + else + target_rect = This->window_rect; target_rect.right -= target_rect.left; target_rect.bottom -= target_rect.top; target_rect.left = target_rect.top = 0; @@ -2516,9 +2564,9 @@ static HRESULT WINAPI VMR9_SurfaceAllocator_TerminateDevice(IVMRSurfaceAllocator return S_OK; } - hr = SendMessageW(This->hwnd_mine, WM_CLOSE, 0, 0); + SendMessageW(This->hwnd_mine, WM_CLOSE, 0, 0); hr = PostThreadMessageW(This->tid, WM_QUIT, 0, 0); - FIXME("SendMessageW: %08x\n", hr); + TRACE("SendMessageW: %08x\n", hr); WaitForSingleObject(This->thread_hwnd, INFINITE); This->thread_hwnd = NULL; This->hwnd_mine = NULL; @@ -2557,3 +2605,1233 @@ static const IVMRSurfaceAllocatorEx9Vtbl VMR9_SurfaceAllocator = VMR9_SurfaceAllocator_AdviseNotify, NULL /* This isn't the SurfaceAllocatorEx type yet, working on it */ }; + + +/*** IUnknown methods ***/ +static HRESULT WINAPI Basicvideo_QueryInterface(IBasicVideo *iface, + REFIID riid, + LPVOID*ppvObj) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj); + + return IBaseFilter_QueryInterface((IBaseFilter*)This, riid, ppvObj); +} + +static ULONG WINAPI Basicvideo_AddRef(IBasicVideo *iface) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->()\n", This, iface); + + return IBaseFilter_AddRef((IBaseFilter*)This); +} + +static ULONG WINAPI Basicvideo_Release(IBasicVideo *iface) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->()\n", This, iface); + + return IBaseFilter_Release((IBaseFilter*)This); +} + +/*** IDispatch methods ***/ +static HRESULT WINAPI Basicvideo_GetTypeInfoCount(IBasicVideo *iface, + UINT *pctinfo) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo); + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_GetTypeInfo(IBasicVideo *iface, + UINT iTInfo, + LCID lcid, + ITypeInfo**ppTInfo) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + FIXME("(%p/%p)->(%d, %d, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo); + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_GetIDsOfNames(IBasicVideo *iface, + REFIID riid, + LPOLESTR*rgszNames, + UINT cNames, + LCID lcid, + DISPID *rgDispId) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + FIXME("(%p/%p)->(%s (%p), %p, %d, %d, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId); + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_Invoke(IBasicVideo *iface, + DISPID dispIdMember, + REFIID riid, + LCID lcid, + WORD wFlags, + DISPPARAMS* pDispParams, + VARIANT* pVarResult, + EXCEPINFO*pExepInfo, + UINT*puArgErr) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + FIXME("(%p/%p)->(%d, %s (%p), %d, %04x, %p, %p, %p, %p): stub !!!\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr); + + return S_OK; +} + +/*** IBasicVideo methods ***/ +static HRESULT WINAPI Basicvideo_get_AvgTimePerFrame(IBasicVideo *iface, + REFTIME *pAvgTimePerFrame) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pAvgTimePerFrame); + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_get_BitRate(IBasicVideo *iface, + long *pBitRate) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pBitRate); + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_get_BitErrorRate(IBasicVideo *iface, + long *pBitErrorRate) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pBitErrorRate); + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_get_VideoWidth(IBasicVideo *iface, + long *pVideoWidth) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pVideoWidth); + + *pVideoWidth = This->info.dwWidth; + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_get_VideoHeight(IBasicVideo *iface, + long *pVideoHeight) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pVideoHeight); + + *pVideoHeight = This->info.dwHeight; + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_put_SourceLeft(IBasicVideo *iface, + long SourceLeft) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->(%ld)\n", This, iface, SourceLeft); + + This->source_rect.left = SourceLeft; + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_get_SourceLeft(IBasicVideo *iface, + long *pSourceLeft) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pSourceLeft); + + *pSourceLeft = This->source_rect.left; + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_put_SourceWidth(IBasicVideo *iface, + long SourceWidth) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->(%ld)\n", This, iface, SourceWidth); + + This->source_rect.right = This->source_rect.left + SourceWidth; + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_get_SourceWidth(IBasicVideo *iface, + long *pSourceWidth) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pSourceWidth); + + *pSourceWidth = This->source_rect.right - This->source_rect.left; + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_put_SourceTop(IBasicVideo *iface, + long SourceTop) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->(%ld)\n", This, iface, SourceTop); + + This->source_rect.top = SourceTop; + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_get_SourceTop(IBasicVideo *iface, + long *pSourceTop) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pSourceTop); + + *pSourceTop = This->source_rect.top; + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_put_SourceHeight(IBasicVideo *iface, + long SourceHeight) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->(%ld)\n", This, iface, SourceHeight); + + This->source_rect.bottom = This->source_rect.top + SourceHeight; + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_get_SourceHeight(IBasicVideo *iface, + long *pSourceHeight) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pSourceHeight); + + *pSourceHeight = This->source_rect.bottom - This->source_rect.top; + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_put_DestinationLeft(IBasicVideo *iface, + long DestinationLeft) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->(%ld)\n", This, iface, DestinationLeft); + + This->target_rect.left = DestinationLeft; + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_get_DestinationLeft(IBasicVideo *iface, + long *pDestinationLeft) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationLeft); + + *pDestinationLeft = This->target_rect.left; + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_put_DestinationWidth(IBasicVideo *iface, + long DestinationWidth) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->(%ld)\n", This, iface, DestinationWidth); + + This->target_rect.right = This->target_rect.left + DestinationWidth; + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_get_DestinationWidth(IBasicVideo *iface, + long *pDestinationWidth) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationWidth); + + *pDestinationWidth = This->target_rect.right - This->target_rect.left; + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_put_DestinationTop(IBasicVideo *iface, + long DestinationTop) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->(%ld)\n", This, iface, DestinationTop); + + This->target_rect.top = DestinationTop; + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_get_DestinationTop(IBasicVideo *iface, + long *pDestinationTop) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationTop); + + *pDestinationTop = This->target_rect.top; + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_put_DestinationHeight(IBasicVideo *iface, + long DestinationHeight) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->(%ld)\n", This, iface, DestinationHeight); + + This->target_rect.right = This->target_rect.left + DestinationHeight; + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_get_DestinationHeight(IBasicVideo *iface, + long *pDestinationHeight) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pDestinationHeight); + + *pDestinationHeight = This->target_rect.right - This->target_rect.left; + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_SetSourcePosition(IBasicVideo *iface, + long Left, + long Top, + long Width, + long Height) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->(%ld, %ld, %ld, %ld)\n", This, iface, Left, Top, Width, Height); + + This->source_rect.left = Left; + This->source_rect.top = Top; + This->source_rect.right = Left + Width; + This->source_rect.bottom = Top + Height; + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_GetSourcePosition(IBasicVideo *iface, + long *pLeft, + long *pTop, + long *pWidth, + long *pHeight) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight); + + *pLeft = This->source_rect.left; + *pTop = This->source_rect.top; + *pWidth = This->source_rect.right - This->source_rect.left; + *pHeight = This->source_rect.bottom - This->source_rect.top; + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_SetDefaultSourcePosition(IBasicVideo *iface) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->()\n", This, iface); + + This->source_rect.left = 0; + This->source_rect.top = 0; + This->source_rect.right = This->info.dwWidth; + This->source_rect.bottom = This->info.dwHeight; + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_SetDestinationPosition(IBasicVideo *iface, + long Left, + long Top, + long Width, + long Height) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->(%ld, %ld, %ld, %ld)\n", This, iface, Left, Top, Width, Height); + + This->target_rect.left = Left; + This->target_rect.top = Top; + This->target_rect.right = Left + Width; + This->target_rect.bottom = Top + Height; + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_GetDestinationPosition(IBasicVideo *iface, + long *pLeft, + long *pTop, + long *pWidth, + long *pHeight) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight); + + *pLeft = This->target_rect.left; + *pTop = This->target_rect.top; + *pWidth = This->target_rect.right - This->target_rect.left; + *pHeight = This->target_rect.bottom - This->target_rect.top; + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_SetDefaultDestinationPosition(IBasicVideo *iface) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + RECT rect; + + TRACE("(%p/%p)->()\n", This, iface); + + if (!GetClientRect(This->hwnd_mine, &rect)) + return E_FAIL; + + This->source_rect.left = 0; + This->source_rect.top = 0; + This->source_rect.right = rect.right; + This->source_rect.bottom = rect.bottom; + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_GetVideoSize(IBasicVideo *iface, + long *pWidth, + long *pHeight) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + TRACE("(%p/%p)->(%p, %p)\n", This, iface, pWidth, pHeight); + + *pWidth = This->info.dwWidth; + *pHeight = This->info.dwHeight; + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_GetVideoPaletteEntries(IBasicVideo *iface, + long StartIndex, + long Entries, + long *pRetrieved, + long *pPalette) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + FIXME("(%p/%p)->(%ld, %ld, %p, %p): stub !!!\n", This, iface, StartIndex, Entries, pRetrieved, pPalette); + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_GetCurrentImage(IBasicVideo *iface, + long *pBufferSize, + long *pDIBImage) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + BITMAPINFOHEADER *bmiHeader; + LONG needed_size; + AM_MEDIA_TYPE *amt = &This->pInputPin->pin.mtCurrent; + char *ptr; + + EnterCriticalSection(&This->csFilter); + + if (!This->sample_held) + { + LeaveCriticalSection(&This->csFilter); + return (This->state == State_Paused ? E_UNEXPECTED : VFW_E_NOT_PAUSED); + } + + FIXME("(%p/%p)->(%p, %p): partial stub\n", This, iface, pBufferSize, pDIBImage); + + if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo)) + { + bmiHeader = &((VIDEOINFOHEADER *)amt->pbFormat)->bmiHeader; + } + else if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo2)) + { + bmiHeader = &((VIDEOINFOHEADER2 *)amt->pbFormat)->bmiHeader; + } + else + { + FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype)); + LeaveCriticalSection(&This->csFilter); + return VFW_E_RUNTIME_ERROR; + } + + needed_size = bmiHeader->biSize; + needed_size += IMediaSample_GetActualDataLength(This->sample_held); + + if (!pDIBImage) + { + *pBufferSize = needed_size; + LeaveCriticalSection(&This->csFilter); + return S_OK; + } + + if (needed_size < *pBufferSize) + { + ERR("Buffer too small %u/%lu\n", needed_size, *pBufferSize); + LeaveCriticalSection(&This->csFilter); + return E_FAIL; + } + *pBufferSize = needed_size; + + memcpy(pDIBImage, bmiHeader, bmiHeader->biSize); + IMediaSample_GetPointer(This->sample_held, (BYTE **)&ptr); + memcpy((char *)pDIBImage + bmiHeader->biSize, ptr, IMediaSample_GetActualDataLength(This->sample_held)); + + LeaveCriticalSection(&This->csFilter); + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_IsUsingDefaultSource(IBasicVideo *iface) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + FIXME("(%p/%p)->(): stub !!!\n", This, iface); + + return S_OK; +} + +static HRESULT WINAPI Basicvideo_IsUsingDefaultDestination(IBasicVideo *iface) +{ + ICOM_THIS_MULTI(VMR9Impl, IBasicVideo_vtbl, iface); + + FIXME("(%p/%p)->(): stub !!!\n", This, iface); + + return S_OK; +} + + +static const IBasicVideoVtbl IBasicVideo_VTable = +{ + Basicvideo_QueryInterface, + Basicvideo_AddRef, + Basicvideo_Release, + Basicvideo_GetTypeInfoCount, + Basicvideo_GetTypeInfo, + Basicvideo_GetIDsOfNames, + Basicvideo_Invoke, + Basicvideo_get_AvgTimePerFrame, + Basicvideo_get_BitRate, + Basicvideo_get_BitErrorRate, + Basicvideo_get_VideoWidth, + Basicvideo_get_VideoHeight, + Basicvideo_put_SourceLeft, + Basicvideo_get_SourceLeft, + Basicvideo_put_SourceWidth, + Basicvideo_get_SourceWidth, + Basicvideo_put_SourceTop, + Basicvideo_get_SourceTop, + Basicvideo_put_SourceHeight, + Basicvideo_get_SourceHeight, + Basicvideo_put_DestinationLeft, + Basicvideo_get_DestinationLeft, + Basicvideo_put_DestinationWidth, + Basicvideo_get_DestinationWidth, + Basicvideo_put_DestinationTop, + Basicvideo_get_DestinationTop, + Basicvideo_put_DestinationHeight, + Basicvideo_get_DestinationHeight, + Basicvideo_SetSourcePosition, + Basicvideo_GetSourcePosition, + Basicvideo_SetDefaultSourcePosition, + Basicvideo_SetDestinationPosition, + Basicvideo_GetDestinationPosition, + Basicvideo_SetDefaultDestinationPosition, + Basicvideo_GetVideoSize, + Basicvideo_GetVideoPaletteEntries, + Basicvideo_GetCurrentImage, + Basicvideo_IsUsingDefaultSource, + Basicvideo_IsUsingDefaultDestination +}; + + +/*** IUnknown methods ***/ +static HRESULT WINAPI Videowindow_QueryInterface(IVideoWindow *iface, + REFIID riid, + LPVOID*ppvObj) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj); + + return IBaseFilter_QueryInterface((IBaseFilter*)This, riid, ppvObj); +} + +static ULONG WINAPI Videowindow_AddRef(IVideoWindow *iface) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->()\n", This, iface); + + return IBaseFilter_AddRef((IBaseFilter*)This); +} + +static ULONG WINAPI Videowindow_Release(IVideoWindow *iface) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->()\n", This, iface); + + return IBaseFilter_Release((IBaseFilter*)This); +} + +/*** IDispatch methods ***/ +static HRESULT WINAPI Videowindow_GetTypeInfoCount(IVideoWindow *iface, + UINT*pctinfo) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pctinfo); + + return S_OK; +} + +static HRESULT WINAPI Videowindow_GetTypeInfo(IVideoWindow *iface, + UINT iTInfo, + LCID lcid, + ITypeInfo**ppTInfo) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + FIXME("(%p/%p)->(%d, %d, %p): stub !!!\n", This, iface, iTInfo, lcid, ppTInfo); + + return S_OK; +} + +static HRESULT WINAPI Videowindow_GetIDsOfNames(IVideoWindow *iface, + REFIID riid, + LPOLESTR*rgszNames, + UINT cNames, + LCID lcid, + DISPID*rgDispId) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + FIXME("(%p/%p)->(%s (%p), %p, %d, %d, %p): stub !!!\n", This, iface, debugstr_guid(riid), riid, rgszNames, cNames, lcid, rgDispId); + + return S_OK; +} + +static HRESULT WINAPI Videowindow_Invoke(IVideoWindow *iface, + DISPID dispIdMember, + REFIID riid, + LCID lcid, + WORD wFlags, + DISPPARAMS*pDispParams, + VARIANT*pVarResult, + EXCEPINFO*pExepInfo, + UINT*puArgErr) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + FIXME("(%p/%p)->(%d, %s (%p), %d, %04x, %p, %p, %p, %p): stub !!!\n", This, iface, dispIdMember, debugstr_guid(riid), riid, lcid, wFlags, pDispParams, pVarResult, pExepInfo, puArgErr); + + return S_OK; +} + +/*** IVideoWindow methods ***/ +static HRESULT WINAPI Videowindow_put_Caption(IVideoWindow *iface, + BSTR strCaption) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->(%s (%p))\n", This, iface, debugstr_w(strCaption), strCaption); + + if (!SetWindowTextW(This->hwnd_mine, strCaption)) + return E_FAIL; + + return S_OK; +} + +static HRESULT WINAPI Videowindow_get_Caption(IVideoWindow *iface, + BSTR *strCaption) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, strCaption); + + GetWindowTextW(This->hwnd_mine, (LPWSTR)strCaption, 100); + + return S_OK; +} + +static HRESULT WINAPI Videowindow_put_WindowStyle(IVideoWindow *iface, + long WindowStyle) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + LONG old; + + old = GetWindowLongW(This->hwnd_mine, GWL_STYLE); + + TRACE("(%p/%p)->(%x -> %lx)\n", This, iface, old, WindowStyle); + + if (WindowStyle & (WS_DISABLED|WS_HSCROLL|WS_ICONIC|WS_MAXIMIZE|WS_MINIMIZE|WS_VSCROLL)) + return E_INVALIDARG; + + SetWindowLongW(This->hwnd_mine, GWL_STYLE, WindowStyle); + + return S_OK; +} + +static HRESULT WINAPI Videowindow_get_WindowStyle(IVideoWindow *iface, + long *WindowStyle) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, WindowStyle); + + *WindowStyle = GetWindowLongW(This->hwnd_mine, GWL_STYLE); + + return S_OK; +} + +static HRESULT WINAPI Videowindow_put_WindowStyleEx(IVideoWindow *iface, + long WindowStyleEx) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->(%ld)\n", This, iface, WindowStyleEx); + + if (WindowStyleEx & (WS_DISABLED|WS_HSCROLL|WS_ICONIC|WS_MAXIMIZE|WS_MINIMIZE|WS_VSCROLL)) + return E_INVALIDARG; + + if (!SetWindowLongW(This->hwnd_mine, GWL_EXSTYLE, WindowStyleEx)) + return E_FAIL; + + return S_OK; +} + +static HRESULT WINAPI Videowindow_get_WindowStyleEx(IVideoWindow *iface, + long *WindowStyleEx) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, WindowStyleEx); + + *WindowStyleEx = GetWindowLongW(This->hwnd_mine, GWL_EXSTYLE); + + return S_OK; +} + +static HRESULT WINAPI Videowindow_put_AutoShow(IVideoWindow *iface, + long AutoShow) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->(%ld)\n", This, iface, AutoShow); + + This->autoshow = This->next_visible = TRUE; /* FXIME: Should be AutoShow */ + + return S_OK; +} + +static HRESULT WINAPI Videowindow_get_AutoShow(IVideoWindow *iface, + long *AutoShow) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, AutoShow); + + *AutoShow = This->autoshow; + + return S_OK; +} + +static HRESULT WINAPI Videowindow_put_WindowState(IVideoWindow *iface, + long WindowState) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + FIXME("(%p/%p)->(%ld): stub !!!\n", This, iface, WindowState); + + return S_OK; +} + +static HRESULT WINAPI Videowindow_get_WindowState(IVideoWindow *iface, + long *WindowState) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, WindowState); + + return S_OK; +} + +static HRESULT WINAPI Videowindow_put_BackgroundPalette(IVideoWindow *iface, + long BackgroundPalette) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + FIXME("(%p/%p)->(%ld): stub !!!\n", This, iface, BackgroundPalette); + + return S_OK; +} + +static HRESULT WINAPI Videowindow_get_BackgroundPalette(IVideoWindow *iface, + long *pBackgroundPalette) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pBackgroundPalette); + + return S_OK; +} + +static HRESULT WINAPI Videowindow_put_Visible(IVideoWindow *iface, + long Visible) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->(%ld)\n", This, iface, Visible); + + ShowWindow(This->hwnd_mine, Visible ? SW_SHOW : SW_HIDE); + + return S_OK; +} + +static HRESULT WINAPI Videowindow_get_Visible(IVideoWindow *iface, + long *pVisible) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pVisible); + + *pVisible = IsWindowVisible(This->hwnd_mine); + + return S_OK; +} + +static HRESULT WINAPI Videowindow_put_Left(IVideoWindow *iface, + long Left) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->(%ld)\n", This, iface, Left); + + if (!SetWindowPos(This->hwnd_mine, NULL, Left, This->window_rect.top, 0, 0, SWP_NOZORDER|SWP_NOSIZE)) + return E_FAIL; + + return S_OK; +} + +static HRESULT WINAPI Videowindow_get_Left(IVideoWindow *iface, + long *pLeft) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pLeft); + + *pLeft = This->window_rect.left; + + return S_OK; +} + +static HRESULT WINAPI Videowindow_put_Width(IVideoWindow *iface, + long Width) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->(%ld)\n", This, iface, Width); + + if (!SetWindowPos(This->hwnd_mine, NULL, 0, 0, Width, This->window_rect.bottom-This->window_rect.top, SWP_NOZORDER|SWP_NOMOVE)) + return E_FAIL; + + This->window_rect.right = This->window_rect.left + Width; + + return S_OK; +} + +static HRESULT WINAPI Videowindow_get_Width(IVideoWindow *iface, + long *pWidth) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pWidth); + + *pWidth = This->window_rect.right - This->window_rect.left; + + return S_OK; +} + +static HRESULT WINAPI Videowindow_put_Top(IVideoWindow *iface, + long Top) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->(%ld)\n", This, iface, Top); + + if (!SetWindowPos(This->hwnd_mine, NULL, This->window_rect.left, Top, 0, 0, SWP_NOZORDER|SWP_NOSIZE)) + return E_FAIL; + + return S_OK; +} + +static HRESULT WINAPI Videowindow_get_Top(IVideoWindow *iface, + long *pTop) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pTop); + + *pTop = This->window_rect.top; + + return S_OK; +} + +static HRESULT WINAPI Videowindow_put_Height(IVideoWindow *iface, + long Height) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->(%ld)\n", This, iface, Height); + + if (!SetWindowPos(This->hwnd_mine, NULL, 0, 0, This->window_rect.right-This->window_rect.left, Height, SWP_NOZORDER|SWP_NOMOVE)) + return E_FAIL; + + This->window_rect.bottom = This->window_rect.top + Height; + + return S_OK; +} + +static HRESULT WINAPI Videowindow_get_Height(IVideoWindow *iface, + long *pHeight) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pHeight); + + *pHeight = This->window_rect.bottom - This->window_rect.top; + + return S_OK; +} + +static HRESULT WINAPI Videowindow_put_Owner(IVideoWindow *iface, + OAHWND Owner) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->(%08x)\n", This, iface, (DWORD) Owner); + + SetParent(This->hwnd_mine, (HWND)Owner); + + return S_OK; +} + +static HRESULT WINAPI Videowindow_get_Owner(IVideoWindow *iface, + OAHWND *Owner) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->(%08x)\n", This, iface, (DWORD) Owner); + + *(HWND*)Owner = GetParent(This->hwnd_mine); + + return S_OK; +} + +static HRESULT WINAPI Videowindow_put_MessageDrain(IVideoWindow *iface, + OAHWND Drain) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->(%08x)\n", This, iface, (DWORD) Drain); + + This->hwnd_drain = (HWND)Drain; + + return S_OK; +} + +static HRESULT WINAPI Videowindow_get_MessageDrain(IVideoWindow *iface, + OAHWND *Drain) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, Drain); + + *Drain = (OAHWND)This->hwnd_drain; + + return S_OK; +} + +static HRESULT WINAPI Videowindow_get_BorderColor(IVideoWindow *iface, + long *Color) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, Color); + + return S_OK; +} + +static HRESULT WINAPI Videowindow_put_BorderColor(IVideoWindow *iface, + long Color) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + FIXME("(%p/%p)->(%ld): stub !!!\n", This, iface, Color); + + return S_OK; +} + +static HRESULT WINAPI Videowindow_get_FullScreenMode(IVideoWindow *iface, + long *FullScreenMode) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, FullScreenMode); + + return S_OK; +} + +static HRESULT WINAPI Videowindow_put_FullScreenMode(IVideoWindow *iface, + long FullScreenMode) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + FIXME("(%p/%p)->(%ld): stub !!!\n", This, iface, FullScreenMode); + + return S_OK; +} + +static HRESULT WINAPI Videowindow_SetWindowForeground(IVideoWindow *iface, + long Focus) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + BOOL ret; + IPin* pPin; + HRESULT hr; + + TRACE("(%p/%p)->(%ld)\n", This, iface, Focus); + + if ((Focus != FALSE) && (Focus != TRUE)) + return E_INVALIDARG; + + hr = IPin_ConnectedTo((IPin *)This->pInputPin, &pPin); + if ((hr != S_OK) || !pPin) + return VFW_E_NOT_CONNECTED; + + if (Focus) + ret = SetForegroundWindow(This->hwnd_mine); + else + ret = SetWindowPos(This->hwnd_mine, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); + + if (!ret) + return E_FAIL; + + return S_OK; +} + +static HRESULT WINAPI Videowindow_NotifyOwnerMessage(IVideoWindow *iface, + OAHWND hwnd, + long uMsg, + LONG_PTR wParam, + LONG_PTR lParam) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->(%08x, %ld, %08lx, %08lx)\n", This, iface, (DWORD) hwnd, uMsg, wParam, lParam); + + if (!PostMessageW(This->hwnd_mine, uMsg, wParam, lParam)) + return E_FAIL; + + return S_OK; +} + +static HRESULT WINAPI Videowindow_SetWindowPosition(IVideoWindow *iface, + long Left, + long Top, + long Width, + long Height) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->(%ld, %ld, %ld, %ld)\n", This, iface, Left, Top, Width, Height); + + if (!SetWindowPos(This->hwnd_mine, NULL, Left, Top, Width, Height, SWP_NOZORDER)) + return E_FAIL; + + This->window_rect.left = Left; + This->window_rect.top = Top; + This->window_rect.right = Left + Width; + This->window_rect.bottom = Top + Height; + + return S_OK; +} + +static HRESULT WINAPI Videowindow_GetWindowPosition(IVideoWindow *iface, + long *pLeft, + long *pTop, + long *pWidth, + long *pHeight) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This, iface, pLeft, pTop, pWidth, pHeight); + + *pLeft = This->window_rect.left; + *pTop = This->window_rect.top; + *pWidth = This->window_rect.right - This->window_rect.left; + *pHeight = This->window_rect.bottom - This->window_rect.top; + + return S_OK; +} + +static HRESULT WINAPI Videowindow_GetMinIdealImageSize(IVideoWindow *iface, + long *pWidth, + long *pHeight) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + FIXME("(%p/%p)->(%p, %p): semi stub !!!\n", This, iface, pWidth, pHeight); + + *pWidth = This->info.dwWidth; + *pHeight = This->info.dwHeight; + + return S_OK; +} + +static HRESULT WINAPI Videowindow_GetMaxIdealImageSize(IVideoWindow *iface, + long *pWidth, + long *pHeight) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + FIXME("(%p/%p)->(%p, %p): semi stub !!!\n", This, iface, pWidth, pHeight); + + *pWidth = This->info.dwWidth; + *pHeight = This->info.dwHeight; + + return S_OK; +} + +static HRESULT WINAPI Videowindow_GetRestorePosition(IVideoWindow *iface, + long *pLeft, + long *pTop, + long *pWidth, + long *pHeight) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + FIXME("(%p/%p)->(%p, %p, %p, %p): stub !!!\n", This, iface, pLeft, pTop, pWidth, pHeight); + + return S_OK; +} + +static HRESULT WINAPI Videowindow_HideCursor(IVideoWindow *iface, + long HideCursor) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + FIXME("(%p/%p)->(%ld): stub !!!\n", This, iface, HideCursor); + + return S_OK; +} + +static HRESULT WINAPI Videowindow_IsCursorHidden(IVideoWindow *iface, + long *CursorHidden) +{ + ICOM_THIS_MULTI(VMR9Impl, IVideoWindow_vtbl, iface); + + FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, CursorHidden); + + return S_OK; +} + +static const IVideoWindowVtbl IVideoWindow_VTable = +{ + Videowindow_QueryInterface, + Videowindow_AddRef, + Videowindow_Release, + Videowindow_GetTypeInfoCount, + Videowindow_GetTypeInfo, + Videowindow_GetIDsOfNames, + Videowindow_Invoke, + Videowindow_put_Caption, + Videowindow_get_Caption, + Videowindow_put_WindowStyle, + Videowindow_get_WindowStyle, + Videowindow_put_WindowStyleEx, + Videowindow_get_WindowStyleEx, + Videowindow_put_AutoShow, + Videowindow_get_AutoShow, + Videowindow_put_WindowState, + Videowindow_get_WindowState, + Videowindow_put_BackgroundPalette, + Videowindow_get_BackgroundPalette, + Videowindow_put_Visible, + Videowindow_get_Visible, + Videowindow_put_Left, + Videowindow_get_Left, + Videowindow_put_Width, + Videowindow_get_Width, + Videowindow_put_Top, + Videowindow_get_Top, + Videowindow_put_Height, + Videowindow_get_Height, + Videowindow_put_Owner, + Videowindow_get_Owner, + Videowindow_put_MessageDrain, + Videowindow_get_MessageDrain, + Videowindow_get_BorderColor, + Videowindow_put_BorderColor, + Videowindow_get_FullScreenMode, + Videowindow_put_FullScreenMode, + Videowindow_SetWindowForeground, + Videowindow_NotifyOwnerMessage, + Videowindow_SetWindowPosition, + Videowindow_GetWindowPosition, + Videowindow_GetMinIdealImageSize, + Videowindow_GetMaxIdealImageSize, + Videowindow_GetRestorePosition, + Videowindow_HideCursor, + Videowindow_IsCursorHidden +}; -- 1.5.4.1