[PATCH v3 0/4] MR11495: quartz: Emulate fullscreen mode in render graph when renderer does not support it.
-- v3: quartz: Implement entering and leaving emulated fullscreen mode. quartz: Introduce fullscreen mode emulation in filtergraph. quartz: Implement BaseControlWindowImpl_GetRestorePosition(). quartz/tests: Add tests for implicit fullscreen support by filter graph. https://gitlab.winehq.org/wine/wine/-/merge_requests/11495
From: Paul Gofman <pgofman@codeweavers.com> --- dlls/quartz/tests/filtergraph.c | 1376 +++++++++++++++++++++++++++++++ 1 file changed, 1376 insertions(+) diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c index dde4da0655c..e86014311a7 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -28,6 +28,17 @@ static const GUID testguid = {0xabbccdde}; +static void pump_messages(void) +{ + MSG msg; + + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessageA(&msg); + } +} + static BOOL compare_time(ULONGLONG x, ULONGLONG y, unsigned int max_diff) { ULONGLONG diff = x > y ? x - y : y - x; @@ -6086,6 +6097,1370 @@ static void test_event_dispatch(void) ok(!ref, "Got outstanding refcount %ld.\n", ref); } + +struct test_renderer_call +{ + const char *name; + ULONG64 p[4]; +}; + +static struct test_renderer_call test_renderer_calls[256]; +static unsigned int test_renderer_call_count; +static HWND test_renderer_hwnd, test_drain_hwnd; + +static void reset_renderer_calls(void) +{ + test_renderer_call_count = 0; +} + +#define RENDERER_CALL() do { \ + memset(&test_renderer_calls[test_renderer_call_count], 0, sizeof(*test_renderer_calls)); \ + test_renderer_calls[test_renderer_call_count++].name = __FUNCTION__; \ + } while (0) + +#define RENDERER_CALL_1(p1) do { \ + memset(&test_renderer_calls[test_renderer_call_count], 0, sizeof(*test_renderer_calls)); \ + test_renderer_calls[test_renderer_call_count].p[0] = (p1); \ + test_renderer_calls[test_renderer_call_count++].name = __FUNCTION__; \ + } while (0) + +#define RENDERER_CALL_4(p1, p2, p3, p4) do { \ + memset(&test_renderer_calls[test_renderer_call_count], 0, sizeof(*test_renderer_calls)); \ + test_renderer_calls[test_renderer_call_count].p[0] = (p1); \ + test_renderer_calls[test_renderer_call_count].p[1] = (p2); \ + test_renderer_calls[test_renderer_call_count].p[2] = (p3); \ + test_renderer_calls[test_renderer_call_count].p[3] = (p4); \ + test_renderer_calls[test_renderer_call_count++].name = __FUNCTION__; \ + } while (0) + +struct expected_renderer_call +{ + struct test_renderer_call call; +}; + +#define RENDERER_VIDEO_WIDTH 128 +#define RENDERER_VIDEO_HEIGHT 128 + +#define RENDERER_CALL_DYNAMIC ((ULONG64)0xd128) +#define RENDER_CALL_DISPLAY_LEFT ((RENDERER_CALL_DYNAMIC << 48) | 1) +#define RENDER_CALL_DISPLAY_TOP ((RENDERER_CALL_DYNAMIC << 48) | 2) +#define RENDER_CALL_DISPLAY_WIDTH ((RENDERER_CALL_DYNAMIC << 48) | 3) +#define RENDER_CALL_DISPLAY_HEIGHT ((RENDERER_CALL_DYNAMIC << 48) | 4) +#define RENDER_CALL_DEST_POS_X ((RENDERER_CALL_DYNAMIC << 48) | 5) +#define RENDER_CALL_DEST_POS_Y ((RENDERER_CALL_DYNAMIC << 48) | 6) +#define RENDER_CALL_DRAIN_HWND ((RENDERER_CALL_DYNAMIC << 48) | 7) + +static ULONG64 renderer_call_get_expected_value(ULONG64 val) +{ + MONITORINFO info = { .cbSize = sizeof(info) }; + unsigned int screen_x, screen_y, screen_cx, screen_cy; + + if ((val >> 48) != RENDERER_CALL_DYNAMIC) + return val; + + if (GetMonitorInfoW(MonitorFromWindow(test_renderer_hwnd, MONITOR_DEFAULTTONEAREST), &info)) + { + screen_x = info.rcMonitor.left; + screen_y = info.rcMonitor.top; + screen_cx = info.rcMonitor.right - info.rcMonitor.left; + screen_cy = info.rcMonitor.bottom - info.rcMonitor.top; + } + else + { + screen_x = screen_y = 0; + screen_cx = GetSystemMetrics(SM_CXSCREEN); + screen_cy = GetSystemMetrics(SM_CYSCREEN); + } + + switch (val) + { + case RENDER_CALL_DISPLAY_LEFT: + return screen_x; + case RENDER_CALL_DISPLAY_TOP: + return screen_y; + case RENDER_CALL_DISPLAY_WIDTH: + return screen_cx; + case RENDER_CALL_DISPLAY_HEIGHT: + return screen_cy; + case RENDER_CALL_DEST_POS_X: + /* Assume landscape display orientation. */ + return (screen_cx - screen_cy) / 2; + case RENDER_CALL_DEST_POS_Y: + return 0; + case RENDER_CALL_DRAIN_HWND: + return (ULONG_PTR)test_drain_hwnd; + default: + ok(0, "unhandled val %#I64x\n", val); + return val; + } +} + +#define check_renderer_calls(a) check_renderer_calls_(__LINE__, (a)) +static void check_renderer_calls_(unsigned int line, const struct expected_renderer_call *expected) +{ + ULONG64 expected_val; + unsigned int i, j; + + i = 0; + while (expected[i].call.name && i < test_renderer_call_count) + { + winetest_push_context("%u", i); + if (strcmp(expected[i].call.name, test_renderer_calls[i].name)) + { + ok_(__FILE__, line)(0, "expected %s, got %s.\n", expected[i].call.name, test_renderer_calls[i].name); + winetest_pop_context(); + break; + } + ++i; + winetest_pop_context(); + } + ok_(__FILE__,line)(i == test_renderer_call_count && !expected[i].call.name, "Mismatched sequence:\n"); + if (!(i == test_renderer_call_count && !expected[i].call.name)) + { + for (i = 0; i < test_renderer_call_count; ++i) + { + ok_(__FILE__,line)(0, "[%u] %s %#I64x %#I64x %#I64x %#I64x.\n", i, test_renderer_calls[i].name, + test_renderer_calls[i].p[0], test_renderer_calls[i].p[1], test_renderer_calls[i].p[2], + test_renderer_calls[i].p[3]); + } + return; + } + for (i = 0; i < test_renderer_call_count; ++i) + { + for (j = 0; j < ARRAY_SIZE(expected[i].call.p); ++j) + { + expected_val = renderer_call_get_expected_value(expected[i].call.p[j]); + ok_(__FILE__, line)(expected_val == test_renderer_calls[i].p[j], + "%s, parameter %u, expected %#I64x, got %#I64x.\n", + expected[i].call.name, j, expected_val, test_renderer_calls[i].p[j]); + } + } +} + +struct test_renderer +{ + struct strmbase_renderer renderer; + IVideoWindow IVideoWindow_iface; + IBasicVideo IBasicVideo_iface; + + IOverlay IOverlay_iface; +}; + +static inline struct test_renderer *impl_from_strmbase_renderer(struct strmbase_renderer *iface) +{ + return CONTAINING_RECORD(iface, struct test_renderer, renderer); +} + +static HRESULT test_renderer_render(struct strmbase_renderer *iface, IMediaSample *pSample) +{ + return S_OK; +} + +static HRESULT test_renderer_query_accept(struct strmbase_renderer *iface, const AM_MEDIA_TYPE *mt) +{ + return S_OK; +} + +static void test_renderer_destroy(struct strmbase_renderer *iface) +{ + struct test_renderer *filter = impl_from_strmbase_renderer(iface); + + strmbase_renderer_cleanup(&filter->renderer); + free(filter); +} + +static HRESULT test_renderer_query_interface(struct strmbase_renderer *iface, REFIID iid, void **out) +{ + struct test_renderer *filter = impl_from_strmbase_renderer(iface); + + if (IsEqualGUID(iid, &IID_IBasicVideo)) + *out = &filter->IBasicVideo_iface; + else if (IsEqualGUID(iid, &IID_IVideoWindow)) + *out = &filter->IVideoWindow_iface; + else + return E_NOINTERFACE; + + IUnknown_AddRef((IUnknown *)*out); + return S_OK; +} + +static HRESULT test_renderer_pin_query_interface(struct strmbase_renderer *iface, REFIID iid, void **out) +{ + struct test_renderer *filter = impl_from_strmbase_renderer(iface); + + if (IsEqualGUID(iid, &IID_IOverlay)) + *out = &filter->IOverlay_iface; + else + return E_NOINTERFACE; + + IUnknown_AddRef((IUnknown *)*out); + return S_OK; +} + +static void test_renderer_stop_stream(struct strmbase_renderer *iface) +{ +} + +static void test_renderer_init_stream(struct strmbase_renderer *iface) +{ +} + +static HRESULT test_renderer_connect(struct strmbase_renderer *iface, const AM_MEDIA_TYPE *mt) +{ + return S_OK; +} + +static const struct strmbase_renderer_ops test_renderer_ops = +{ + .renderer_query_accept = test_renderer_query_accept, + .renderer_render = test_renderer_render, + .renderer_init_stream = test_renderer_init_stream, + .renderer_stop_stream = test_renderer_stop_stream, + .renderer_destroy = test_renderer_destroy, + .renderer_query_interface = test_renderer_query_interface, + .renderer_pin_query_interface = test_renderer_pin_query_interface, + .renderer_connect = test_renderer_connect, +}; + +static inline struct test_renderer *impl_from_IOverlay(IOverlay *iface) +{ + return CONTAINING_RECORD(iface, struct test_renderer, IOverlay_iface); +} + +static HRESULT WINAPI overlay_QueryInterface(IOverlay *iface, REFIID iid, void **out) +{ + struct test_renderer *filter = impl_from_IOverlay(iface); + return IPin_QueryInterface(&filter->renderer.sink.pin.IPin_iface, iid, out); +} + +static ULONG WINAPI overlay_AddRef(IOverlay *iface) +{ + struct test_renderer *filter = impl_from_IOverlay(iface); + return IPin_AddRef(&filter->renderer.sink.pin.IPin_iface); +} + +static ULONG WINAPI overlay_Release(IOverlay *iface) +{ + struct test_renderer *filter = impl_from_IOverlay(iface); + return IPin_Release(&filter->renderer.sink.pin.IPin_iface); +} + +static HRESULT WINAPI overlay_GetPalette(IOverlay *iface, DWORD *count, PALETTEENTRY **palette) +{ + RENDERER_CALL(); + return E_NOTIMPL; +} + +static HRESULT WINAPI overlay_SetPalette(IOverlay *iface, DWORD count, PALETTEENTRY *palette) +{ + RENDERER_CALL(); + return E_NOTIMPL; +} + +static HRESULT WINAPI overlay_GetDefaultColorKey(IOverlay *iface, COLORKEY *key) +{ + RENDERER_CALL(); + return E_NOTIMPL; +} + +static HRESULT WINAPI overlay_GetColorKey(IOverlay *iface, COLORKEY *key) +{ + RENDERER_CALL(); + return E_NOTIMPL; +} + +static HRESULT WINAPI overlay_SetColorKey(IOverlay *iface, COLORKEY *key) +{ + RENDERER_CALL(); + return E_NOTIMPL; +} + +static HRESULT WINAPI overlay_GetWindowHandle(IOverlay *iface, HWND *window) +{ + RENDERER_CALL(); + *window = test_renderer_hwnd; + return S_OK; +} + +static HRESULT WINAPI overlay_GetClipList(IOverlay *iface, RECT *source, RECT *dest, RGNDATA **region) +{ + RENDERER_CALL(); + return E_NOTIMPL; +} + +static HRESULT WINAPI overlay_GetVideoPosition(IOverlay *iface, RECT *source, RECT *dest) +{ + RENDERER_CALL(); + return E_NOTIMPL; +} + +static HRESULT WINAPI overlay_Advise(IOverlay *iface, IOverlayNotify *sink, DWORD flags) +{ + RENDERER_CALL(); + return E_NOTIMPL; +} + +static HRESULT WINAPI overlay_Unadvise(IOverlay *iface) +{ + RENDERER_CALL(); + return E_NOTIMPL; +} + +static const IOverlayVtbl test_overlay_vtbl = +{ + overlay_QueryInterface, + overlay_AddRef, + overlay_Release, + overlay_GetPalette, + overlay_SetPalette, + overlay_GetDefaultColorKey, + overlay_GetColorKey, + overlay_SetColorKey, + overlay_GetWindowHandle, + overlay_GetClipList, + overlay_GetVideoPosition, + overlay_Advise, + overlay_Unadvise, +}; + + +static inline struct test_renderer *impl_from_IVideoWindow(IVideoWindow *iface) +{ + return CONTAINING_RECORD(iface, struct test_renderer, IVideoWindow_iface); +} + +HRESULT WINAPI test_window_QueryInterface(IVideoWindow *iface, REFIID iid, void **out) +{ + struct test_renderer *filter = impl_from_IVideoWindow(iface); + return IUnknown_QueryInterface(filter->renderer.filter.outer_unk, iid, out); +} + +ULONG WINAPI test_window_AddRef(IVideoWindow *iface) +{ + struct test_renderer *filter = impl_from_IVideoWindow(iface); + return IUnknown_AddRef(filter->renderer.filter.outer_unk); +} + +ULONG WINAPI test_window_Release(IVideoWindow *iface) +{ + struct test_renderer *filter = impl_from_IVideoWindow(iface); + return IUnknown_Release(filter->renderer.filter.outer_unk); +} + +HRESULT WINAPI test_window_GetTypeInfoCount(IVideoWindow *iface, UINT *count) +{ + *count = 1; + return S_OK; +} + +HRESULT WINAPI test_window_GetTypeInfo(IVideoWindow *iface, UINT index, + LCID lcid, ITypeInfo **typeinfo) +{ + return strmbase_get_typeinfo(IVideoWindow_tid, typeinfo); +} + +HRESULT WINAPI test_window_GetIDsOfNames(IVideoWindow *iface, REFIID iid, + LPOLESTR *names, UINT count, LCID lcid, DISPID *ids) +{ + ITypeInfo *typeinfo; + HRESULT hr; + + if (SUCCEEDED(hr = strmbase_get_typeinfo(IVideoWindow_tid, &typeinfo))) + { + hr = ITypeInfo_GetIDsOfNames(typeinfo, names, count, ids); + ITypeInfo_Release(typeinfo); + } + return hr; +} + +HRESULT WINAPI test_window_Invoke(IVideoWindow *iface, DISPID id, REFIID iid, LCID lcid, + WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *error_arg) +{ + ITypeInfo *typeinfo; + HRESULT hr; + + RENDERER_CALL(); + if (SUCCEEDED(hr = strmbase_get_typeinfo(IVideoWindow_tid, &typeinfo))) + { + hr = ITypeInfo_Invoke(typeinfo, iface, id, flags, params, result, excepinfo, error_arg); + ITypeInfo_Release(typeinfo); + } + return hr; +} + +HRESULT WINAPI test_window_put_Caption(IVideoWindow *iface, BSTR caption) +{ + RENDERER_CALL(); + return S_OK; +} + +HRESULT WINAPI test_window_get_Caption(IVideoWindow *iface, BSTR *caption) +{ + RENDERER_CALL(); + return S_OK; +} + +HRESULT WINAPI test_window_put_WindowStyle(IVideoWindow *iface, LONG style) +{ + RENDERER_CALL_1((ULONG)style); + return S_OK; +} + +HRESULT WINAPI test_window_get_WindowStyle(IVideoWindow *iface, LONG *style) +{ + RENDERER_CALL(); + *style = 0xdeadbeef; + return S_OK; +} + +HRESULT WINAPI test_window_put_WindowStyleEx(IVideoWindow *iface, LONG style) +{ + RENDERER_CALL_1((ULONG)style); + return S_OK; +} + +HRESULT WINAPI test_window_get_WindowStyleEx(IVideoWindow *iface, LONG *style) +{ + RENDERER_CALL(); + *style = 0xdeadbeef; + return S_OK; +} + +HRESULT WINAPI test_window_put_AutoShow(IVideoWindow *iface, LONG AutoShow) +{ + RENDERER_CALL_1(AutoShow); + return S_OK; +} + +HRESULT WINAPI test_window_get_AutoShow(IVideoWindow *iface, LONG *AutoShow) +{ + RENDERER_CALL(); + *AutoShow = OATRUE; + return S_OK; +} + +HRESULT WINAPI test_window_put_WindowState(IVideoWindow *iface, LONG state) +{ + RENDERER_CALL_1(state); + return S_OK; +} + +HRESULT WINAPI test_window_get_WindowState(IVideoWindow *iface, LONG *state) +{ + RENDERER_CALL(); + *state = SW_SHOW; + return S_OK; +} + +HRESULT WINAPI test_window_put_BackgroundPalette(IVideoWindow *iface, LONG BackgroundPalette) +{ + RENDERER_CALL(); + return S_OK; +} + +HRESULT WINAPI test_window_get_BackgroundPalette(IVideoWindow *iface, LONG *pBackgroundPalette) +{ + RENDERER_CALL(); + return S_OK; +} + +HRESULT WINAPI test_window_put_Visible(IVideoWindow *iface, LONG visible) +{ + RENDERER_CALL_1(visible); + return S_OK; +} + +HRESULT WINAPI test_window_get_Visible(IVideoWindow *iface, LONG *visible) +{ + RENDERER_CALL(); + *visible = OATRUE; + return S_OK; +} + +HRESULT WINAPI test_window_put_Left(IVideoWindow *iface, LONG left) +{ + RENDERER_CALL_1(left); + return S_OK; +} + +HRESULT WINAPI test_window_get_Left(IVideoWindow *iface, LONG *left) +{ + RENDERER_CALL(); + *left = 0; + return S_OK; +} + +HRESULT WINAPI test_window_put_Width(IVideoWindow *iface, LONG width) +{ + RENDERER_CALL_1(width); + return S_OK; +} + +HRESULT WINAPI test_window_get_Width(IVideoWindow *iface, LONG *width) +{ + RENDERER_CALL(); + *width = 256; + return S_OK; +} + +HRESULT WINAPI test_window_put_Top(IVideoWindow *iface, LONG top) +{ + RENDERER_CALL_1(top); + return S_OK; +} + +HRESULT WINAPI test_window_get_Top(IVideoWindow *iface, LONG *top) +{ + RENDERER_CALL(); + *top = 0; + return S_OK; +} + +HRESULT WINAPI test_window_put_Height(IVideoWindow *iface, LONG height) +{ + RENDERER_CALL_1(height); + return S_OK; +} + +HRESULT WINAPI test_window_get_Height(IVideoWindow *iface, LONG *height) +{ + RENDERER_CALL(); + *height = 256; + return S_OK; +} + +HRESULT WINAPI test_window_put_Owner(IVideoWindow *iface, OAHWND owner) +{ + RENDERER_CALL_1((ULONG_PTR)owner); + return S_OK; +} + +HRESULT WINAPI test_window_get_Owner(IVideoWindow *iface, OAHWND *Owner) +{ + RENDERER_CALL(); + *(HWND*)Owner = (HWND)0xdeadbeef; + return S_OK; +} + +HRESULT WINAPI test_window_put_MessageDrain(IVideoWindow *iface, OAHWND Drain) +{ + RENDERER_CALL_1((ULONG_PTR)Drain); + return S_OK; +} + +HRESULT WINAPI test_window_get_MessageDrain(IVideoWindow *iface, OAHWND *Drain) +{ + RENDERER_CALL(); + *Drain = 0xdeadbeef; + return S_OK; +} + +HRESULT WINAPI test_window_get_BorderColor(IVideoWindow *iface, LONG *Color) +{ + RENDERER_CALL(); + return S_OK; +} + +HRESULT WINAPI test_window_put_BorderColor(IVideoWindow *iface, LONG Color) +{ + RENDERER_CALL_1(Color); + return S_OK; +} + +HRESULT WINAPI test_window_get_FullScreenMode(IVideoWindow *iface, LONG *FullScreenMode) +{ + RENDERER_CALL(); + return E_NOTIMPL; +} + +HRESULT WINAPI test_window_put_FullScreenMode(IVideoWindow *iface, LONG fullscreen) +{ + RENDERER_CALL_1(fullscreen); + return E_NOTIMPL; +} + +HRESULT WINAPI test_window_SetWindowForeground(IVideoWindow *iface, LONG focus) +{ + RENDERER_CALL_1(focus); + return S_OK; +} + +HRESULT WINAPI test_window_SetWindowPosition(IVideoWindow *iface, + LONG left, LONG top, LONG width, LONG height) +{ + RENDERER_CALL_4(left, top, width, height); + return S_OK; +} + +HRESULT WINAPI test_window_GetWindowPosition(IVideoWindow *iface, + LONG *left, LONG *top, LONG *width, LONG *height) +{ + RENDERER_CALL(); + *left = 100; + *top = 100; + *width = 256; + *height = 256; + return S_OK; +} + +HRESULT WINAPI test_window_NotifyOwnerMessage(IVideoWindow *iface, + OAHWND hwnd, LONG message, LONG_PTR wparam, LONG_PTR lparam) +{ + RENDERER_CALL_1(message); + return 0xbeef; +} + +HRESULT WINAPI test_window_GetMinIdealImageSize(IVideoWindow *iface, LONG *width, LONG *height) +{ + RENDERER_CALL(); + *width = 256; + *height = 256; + return S_OK; +} + +HRESULT WINAPI test_window_GetMaxIdealImageSize(IVideoWindow *iface, LONG *width, LONG *height) +{ + RENDERER_CALL(); + *width = 256; + *height = 256; + return S_OK; +} + +HRESULT WINAPI test_window_GetRestorePosition(IVideoWindow *iface, LONG *pLeft, LONG *pTop, LONG *pWidth, LONG *pHeight) +{ + RENDERER_CALL(); + *pLeft = 0; + *pTop = 0; + *pWidth = 100; + *pHeight = 100; + return S_OK; +} + +HRESULT WINAPI test_window_HideCursor(IVideoWindow *iface, LONG hide) +{ + RENDERER_CALL_1(hide); + return S_OK; +} + +HRESULT WINAPI test_window_IsCursorHidden(IVideoWindow *iface, LONG *CursorHidden) +{ + RENDERER_CALL(); + *CursorHidden = OAFALSE; + return S_OK; +} + + +static const IVideoWindowVtbl test_window_vtbl = +{ + test_window_QueryInterface, + test_window_AddRef, + test_window_Release, + test_window_GetTypeInfoCount, + test_window_GetTypeInfo, + test_window_GetIDsOfNames, + test_window_Invoke, + test_window_put_Caption, + test_window_get_Caption, + test_window_put_WindowStyle, + test_window_get_WindowStyle, + test_window_put_WindowStyleEx, + test_window_get_WindowStyleEx, + test_window_put_AutoShow, + test_window_get_AutoShow, + test_window_put_WindowState, + test_window_get_WindowState, + test_window_put_BackgroundPalette, + test_window_get_BackgroundPalette, + test_window_put_Visible, + test_window_get_Visible, + test_window_put_Left, + test_window_get_Left, + test_window_put_Width, + test_window_get_Width, + test_window_put_Top, + test_window_get_Top, + test_window_put_Height, + test_window_get_Height, + test_window_put_Owner, + test_window_get_Owner, + test_window_put_MessageDrain, + test_window_get_MessageDrain, + test_window_get_BorderColor, + test_window_put_BorderColor, + test_window_get_FullScreenMode, + test_window_put_FullScreenMode, + test_window_SetWindowForeground, + test_window_NotifyOwnerMessage, + test_window_SetWindowPosition, + test_window_GetWindowPosition, + test_window_GetMinIdealImageSize, + test_window_GetMaxIdealImageSize, + test_window_GetRestorePosition, + test_window_HideCursor, + test_window_IsCursorHidden +}; + +static inline struct test_renderer *impl_from_IBasicVideo(IBasicVideo *iface) +{ + return CONTAINING_RECORD(iface, struct test_renderer, IBasicVideo_iface); +} + +static HRESULT WINAPI basic_video_QueryInterface(IBasicVideo *iface, REFIID iid, void **out) +{ + struct test_renderer *filter = impl_from_IBasicVideo(iface); + return IUnknown_QueryInterface(filter->renderer.filter.outer_unk, iid, out); +} + +static ULONG WINAPI basic_video_AddRef(IBasicVideo *iface) +{ + struct test_renderer *filter = impl_from_IBasicVideo(iface); + return IUnknown_AddRef(filter->renderer.filter.outer_unk); +} + +static ULONG WINAPI basic_video_Release(IBasicVideo *iface) +{ + struct test_renderer *filter = impl_from_IBasicVideo(iface); + return IUnknown_Release(filter->renderer.filter.outer_unk); +} + +static HRESULT WINAPI basic_video_GetTypeInfoCount(IBasicVideo *iface, UINT *count) +{ + *count = 1; + return S_OK; +} + +static HRESULT WINAPI basic_video_GetTypeInfo(IBasicVideo *iface, UINT index, + LCID lcid, ITypeInfo **typeinfo) +{ + return strmbase_get_typeinfo(IBasicVideo_tid, typeinfo); +} + +static HRESULT WINAPI basic_video_GetIDsOfNames(IBasicVideo *iface, REFIID iid, + LPOLESTR *names, UINT count, LCID lcid, DISPID *ids) +{ + ITypeInfo *typeinfo; + HRESULT hr; + + if (SUCCEEDED(hr = strmbase_get_typeinfo(IBasicVideo_tid, &typeinfo))) + { + hr = ITypeInfo_GetIDsOfNames(typeinfo, names, count, ids); + ITypeInfo_Release(typeinfo); + } + return hr; +} + +static HRESULT WINAPI basic_video_Invoke(IBasicVideo *iface, DISPID id, REFIID iid, LCID lcid, + WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *error_arg) +{ + ITypeInfo *typeinfo; + HRESULT hr; + + RENDERER_CALL(); + + if (SUCCEEDED(hr = strmbase_get_typeinfo(IBasicVideo_tid, &typeinfo))) + { + hr = ITypeInfo_Invoke(typeinfo, iface, id, flags, params, result, excepinfo, error_arg); + ITypeInfo_Release(typeinfo); + } + return hr; +} + +static HRESULT WINAPI basic_video_get_AvgTimePerFrame(IBasicVideo *iface, REFTIME *reftime) +{ + RENDERER_CALL(); + *reftime = 1.0; + return S_OK; +} + +static HRESULT WINAPI basic_video_get_BitRate(IBasicVideo *iface, LONG *rate) +{ + RENDERER_CALL(); + *rate = 60; + return S_OK; +} + +static HRESULT WINAPI basic_video_get_BitErrorRate(IBasicVideo *iface, LONG *rate) +{ + RENDERER_CALL(); + *rate = 10; + return S_OK; +} + +static HRESULT WINAPI basic_video_get_VideoWidth(IBasicVideo *iface, LONG *width) +{ + RENDERER_CALL(); + *width = RENDERER_VIDEO_WIDTH; + return S_OK; +} + +static HRESULT WINAPI basic_video_get_VideoHeight(IBasicVideo *iface, LONG *height) +{ + RENDERER_CALL(); + *height = RENDERER_VIDEO_HEIGHT; + return S_OK; +} + +static HRESULT WINAPI basic_video_put_SourceLeft(IBasicVideo *iface, LONG left) +{ + RENDERER_CALL_1(left); + return S_OK; +} + +static HRESULT WINAPI basic_video_get_SourceLeft(IBasicVideo *iface, LONG *left) +{ + RENDERER_CALL(); + *left = 10; + return S_OK; +} + +static HRESULT WINAPI basic_video_put_SourceWidth(IBasicVideo *iface, LONG width) +{ + RENDERER_CALL_1(width); + return S_OK; +} + +static HRESULT WINAPI basic_video_get_SourceWidth(IBasicVideo *iface, LONG *width) +{ + RENDERER_CALL(); + *width = 640; + return S_OK; +} + +static HRESULT WINAPI basic_video_put_SourceTop(IBasicVideo *iface, LONG top) +{ + RENDERER_CALL_1(top); + return S_OK; +} + +static HRESULT WINAPI basic_video_get_SourceTop(IBasicVideo *iface, LONG *top) +{ + RENDERER_CALL(); + *top = 10; + return S_OK; +} + +static HRESULT WINAPI basic_video_put_SourceHeight(IBasicVideo *iface, LONG height) +{ + RENDERER_CALL_1(height); + return S_OK; +} + +static HRESULT WINAPI basic_video_get_SourceHeight(IBasicVideo *iface, LONG *height) +{ + RENDERER_CALL(); + *height = 480; + return S_OK; +} + +static HRESULT WINAPI basic_video_put_DestinationLeft(IBasicVideo *iface, LONG left) +{ + RENDERER_CALL_1(left); + return S_OK; +} + +static HRESULT WINAPI basic_video_get_DestinationLeft(IBasicVideo *iface, LONG *left) +{ + RENDERER_CALL(); + *left = 10; + return S_OK; +} + +static HRESULT WINAPI basic_video_put_DestinationWidth(IBasicVideo *iface, LONG width) +{ + RENDERER_CALL_1(width); + return S_OK; +} + +static HRESULT WINAPI basic_video_get_DestinationWidth(IBasicVideo *iface, LONG *width) +{ + RENDERER_CALL(); + *width = 320; + return S_OK; +} + +static HRESULT WINAPI basic_video_put_DestinationTop(IBasicVideo *iface, LONG top) +{ + RENDERER_CALL_1(top); + return S_OK; +} + +static HRESULT WINAPI basic_video_get_DestinationTop(IBasicVideo *iface, LONG *top) +{ + RENDERER_CALL(); + *top = 10; + return S_OK; +} + +static HRESULT WINAPI basic_video_put_DestinationHeight(IBasicVideo *iface, LONG height) +{ + RENDERER_CALL_1(height); + return S_OK; +} + +static HRESULT WINAPI basic_video_get_DestinationHeight(IBasicVideo *iface, LONG *height) +{ + RENDERER_CALL(); + *height = 240; + return S_OK; +} + +static HRESULT WINAPI basic_video_SetSourcePosition(IBasicVideo *iface, + LONG left, LONG top, LONG width, LONG height) +{ + RENDERER_CALL_4(left, top, width, height); + return S_OK; +} + +static HRESULT WINAPI basic_video_GetSourcePosition(IBasicVideo *iface, + LONG *left, LONG *top, LONG *width, LONG *height) +{ + RENDERER_CALL(); + *left = 10; + *top = 10; + *width = 640; + *height = 480; + return S_OK; +} + +static HRESULT WINAPI basic_video_SetDefaultSourcePosition(IBasicVideo *iface) +{ + RENDERER_CALL(); + return S_OK; +} + +static HRESULT WINAPI basic_video_SetDestinationPosition(IBasicVideo *iface, + LONG left, LONG top, LONG width, LONG height) +{ + RENDERER_CALL_4(left, top, width, height); + return S_OK; +} + +static HRESULT WINAPI basic_video_GetDestinationPosition(IBasicVideo *iface, + LONG *left, LONG *top, LONG *width, LONG *height) +{ + RENDERER_CALL(); + *left = 100; + *top = 100; + *width = 320; + *height = 240; + return S_OK; +} + +static HRESULT WINAPI basic_video_SetDefaultDestinationPosition(IBasicVideo *iface) +{ + RENDERER_CALL(); + return S_OK; +} + +static HRESULT WINAPI basic_video_GetVideoSize(IBasicVideo *iface, LONG *width, LONG *height) +{ + RENDERER_CALL(); + *width = RENDERER_VIDEO_WIDTH; + *height = RENDERER_VIDEO_HEIGHT; + return S_OK; +} + +static HRESULT WINAPI basic_video_GetVideoPaletteEntries(IBasicVideo *iface, + LONG start, LONG count, LONG *ret_count, LONG *palette) +{ + RENDERER_CALL(); + return VFW_E_NO_PALETTE_AVAILABLE; +} + +static HRESULT WINAPI basic_video_GetCurrentImage(IBasicVideo *iface, LONG *size, LONG *image) +{ + RENDERER_CALL(); + return E_NOTIMPL; +} + +static HRESULT WINAPI basic_video_IsUsingDefaultSource(IBasicVideo *iface) +{ + RENDERER_CALL(); + return S_OK; +} + +static HRESULT WINAPI basic_video_IsUsingDefaultDestination(IBasicVideo *iface) +{ + RENDERER_CALL(); + return S_OK; +} + +static const IBasicVideoVtbl basic_video_vtbl = +{ + basic_video_QueryInterface, + basic_video_AddRef, + basic_video_Release, + basic_video_GetTypeInfoCount, + basic_video_GetTypeInfo, + basic_video_GetIDsOfNames, + basic_video_Invoke, + basic_video_get_AvgTimePerFrame, + basic_video_get_BitRate, + basic_video_get_BitErrorRate, + basic_video_get_VideoWidth, + basic_video_get_VideoHeight, + basic_video_put_SourceLeft, + basic_video_get_SourceLeft, + basic_video_put_SourceWidth, + basic_video_get_SourceWidth, + basic_video_put_SourceTop, + basic_video_get_SourceTop, + basic_video_put_SourceHeight, + basic_video_get_SourceHeight, + basic_video_put_DestinationLeft, + basic_video_get_DestinationLeft, + basic_video_put_DestinationWidth, + basic_video_get_DestinationWidth, + basic_video_put_DestinationTop, + basic_video_get_DestinationTop, + basic_video_put_DestinationHeight, + basic_video_get_DestinationHeight, + basic_video_SetSourcePosition, + basic_video_GetSourcePosition, + basic_video_SetDefaultSourcePosition, + basic_video_SetDestinationPosition, + basic_video_GetDestinationPosition, + basic_video_SetDefaultDestinationPosition, + basic_video_GetVideoSize, + basic_video_GetVideoPaletteEntries, + basic_video_GetCurrentImage, + basic_video_IsUsingDefaultSource, + basic_video_IsUsingDefaultDestination +}; + +static void test_renderer_create(IUnknown **out) +{ + struct test_renderer *object; + + object = calloc(1, sizeof(*object)); + strmbase_renderer_init(&object->renderer, NULL, &CLSID_VideoRenderer, L"In", &test_renderer_ops); + wcscpy(object->renderer.sink.pin.name, L"Input"); + + object->IOverlay_iface.lpVtbl = &test_overlay_vtbl; + object->IVideoWindow_iface.lpVtbl = &test_window_vtbl; + object->IBasicVideo_iface.lpVtbl = &basic_video_vtbl; + *out = &object->renderer.filter.IUnknown_inner; +} + + +static void test_implicit_fullscreen_support(void) +{ + static const struct expected_renderer_call empty_seq[] = + { + {{NULL}} + }; + static const struct expected_renderer_call set_fullscreen_seq[] = + { + {{"test_window_get_FullScreenMode"}}, + {{"test_window_get_AutoShow"}}, + {{"test_window_put_AutoShow"}}, + {{"basic_video_GetVideoSize"}}, + {{"overlay_GetWindowHandle"}}, + {{"test_window_GetMaxIdealImageSize"}}, + {{"test_window_put_AutoShow", {OATRUE}}}, + {{"test_window_put_Visible"}}, + {{"test_window_IsCursorHidden"}}, + {{"test_window_HideCursor", {OATRUE}}}, + {{"basic_video_GetSourcePosition"}}, + {{"basic_video_GetDestinationPosition"}}, + {{"basic_video_IsUsingDefaultSource"}}, + {{"basic_video_IsUsingDefaultDestination"}}, + {{"basic_video_SetDefaultSourcePosition"}}, + {{"basic_video_SetDestinationPosition", {RENDER_CALL_DEST_POS_X, RENDER_CALL_DEST_POS_Y, RENDER_CALL_DISPLAY_HEIGHT, RENDER_CALL_DISPLAY_HEIGHT}}}, + {{"test_window_GetRestorePosition"}}, + {{"test_window_get_WindowStyle"}}, + {{"test_window_put_WindowStyle", {WS_POPUP}}}, + {{"test_window_get_Owner"}}, + {{"test_window_put_Owner"}}, + {{"overlay_GetWindowHandle"}}, + {{"test_window_SetWindowPosition", {RENDER_CALL_DISPLAY_LEFT, RENDER_CALL_DISPLAY_TOP, RENDER_CALL_DISPLAY_WIDTH, RENDER_CALL_DISPLAY_HEIGHT}}}, + {{"test_window_get_MessageDrain"}}, + {{"test_window_put_MessageDrain", {RENDER_CALL_DRAIN_HWND}}}, + {{"test_window_put_Visible", {OATRUE}}}, + {{"test_window_SetWindowForeground", {OATRUE}}}, + {{"test_window_get_WindowStyleEx"}}, + {{"test_window_put_WindowStyleEx", {WS_EX_TOPMOST}}}, + {{NULL}} + }; + static const struct expected_renderer_call restore_seq[] = + { + {{"test_window_SetWindowPosition"}}, + {{"test_window_put_WindowStyleEx", {0xdeadbeef}}}, + {{"test_window_put_Visible"}}, + {{"test_window_put_WindowStyle", {0xdeadbeef}}}, + {{"test_window_put_MessageDrain", {0xdeadbeef}}}, + {{"test_window_HideCursor"}}, + {{"basic_video_SetSourcePosition", {10, 10, 640, 480}}}, + {{"basic_video_SetDestinationPosition", {100, 100, 320, 240}}}, + {{"basic_video_SetDefaultSourcePosition"}}, /* only if basic_video_IsUsingDefaultSource() returns S_OK */ + {{"basic_video_SetDefaultDestinationPosition"}}, /* only if basic_video_IsUsingDefaultDestination() returns S_OK */ + {{"test_window_put_Owner", {0xdeadbeef}}}, + {{"test_window_SetWindowPosition", {0, 0, 100, 100}}}, + {{"test_window_put_WindowState", {SW_NORMAL}}}, + {{NULL}} + }; + static const struct expected_renderer_call get_win_pos_seq[] = + { + {{"test_window_GetWindowPosition"}}, + {{NULL}} + }; + + WCHAR *filename = load_resource(L"test.avi"); + IUnknown *renderer_unk; + IBaseFilter *renderer; + IFilterGraph2 *graph; + IVideoWindow *window; + long x, y, cx, cy; + OAHWND oawnd; + HRESULT hr; + BSTR bstr; + LONG val; + + test_renderer_hwnd = CreateWindowA("static", NULL, WS_OVERLAPPEDWINDOW | WS_VISIBLE, 50, 50, 150, 150, NULL, NULL, NULL, NULL); + ok(!!test_renderer_hwnd, "got NULL.\n"); + + test_drain_hwnd = CreateWindowA("static", NULL, WS_OVERLAPPEDWINDOW, 50, 50, 150, 150, NULL, NULL, NULL, NULL); + ok(!!test_drain_hwnd, "got NULL.\n"); + + pump_messages(); + graph = create_graph(); + + test_renderer_create(&renderer_unk); + hr = IUnknown_QueryInterface(renderer_unk, &IID_IBaseFilter, (void **)&renderer); + ok(hr == S_OK, "got %#lx.\n", hr); + hr = IFilterGraph2_AddFilter(graph, renderer, L"Test Renderer"); + ok(hr == S_OK, "got %#lx.\n", hr); + IUnknown_Release(renderer_unk); + + hr = IFilterGraph2_QueryInterface(graph, &IID_IVideoWindow, (void **)&window); + ok(hr == S_OK, "got %#lx.\n", hr); + + hr = IVideoWindow_put_MessageDrain(window, (OAHWND)test_drain_hwnd); + ok(hr == S_OK, "got %#lx.\n", hr); + + hr = IVideoWindow_put_Owner(window, (OAHWND)test_drain_hwnd); + ok(hr == S_OK, "got %#lx.\n", hr); + + reset_renderer_calls(); + hr = IVideoWindow_get_FullScreenMode(window, &val); + ok(hr == S_OK, "got %#lx.\n", hr); + ok(val == OAFALSE, "got %ld.\n", val); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + + hr = IFilterGraph2_RenderFile(graph, filename, NULL); + ok(hr == S_OK, "got %#lx.\n", hr); + + reset_renderer_calls(); + + reset_renderer_calls(); + hr = IVideoWindow_get_FullScreenMode(window, &val); + ok(hr == S_OK, "got %#lx.\n", hr); + ok(val == OAFALSE, "got %ld.\n", val); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + + hr = IVideoWindow_put_FullScreenMode(window, OATRUE); + todo_wine ok(hr == S_OK, "got %#lx.\n", hr); + todo_wine check_renderer_calls(set_fullscreen_seq); + reset_renderer_calls(); + + hr = IVideoWindow_put_FullScreenMode(window, OATRUE); + todo_wine ok(hr == S_FALSE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + + hr = IVideoWindow_get_FullScreenMode(window, &val); + ok(hr == S_OK, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + + /* All video window calls in fullscreen mode. Nothing is forwarded, everything but NotifyOwnerMessage + * returns VFW_E_IN_FULLSCREEN_MODE. */ + hr = IVideoWindow_get_Caption(window, &bstr); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + hr = IVideoWindow_put_Caption(window, (BSTR)L"test"); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + + hr = IVideoWindow_get_WindowStyle(window, &val); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + hr = IVideoWindow_put_WindowStyle(window, WS_POPUP); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + + hr = IVideoWindow_get_WindowStyleEx(window, &val); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + hr = IVideoWindow_put_WindowStyleEx(window, WS_EX_TOOLWINDOW); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + + hr = IVideoWindow_get_AutoShow(window, &val); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + hr = IVideoWindow_put_AutoShow(window, 0); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + + hr = IVideoWindow_get_WindowState(window, &val); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + hr = IVideoWindow_put_WindowState(window, SW_SHOW); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + + hr = IVideoWindow_get_BackgroundPalette(window, &val); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + hr = IVideoWindow_put_BackgroundPalette(window, 0); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + + hr = IVideoWindow_get_Visible(window, &val); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + hr = IVideoWindow_put_Visible(window, OATRUE); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + + hr = IVideoWindow_get_Left(window, &val); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + hr = IVideoWindow_put_Left(window, 0); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + hr = IVideoWindow_get_Width(window, &val); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + hr = IVideoWindow_put_Width(window, 128); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + hr = IVideoWindow_get_Top(window, &val); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + hr = IVideoWindow_put_Top(window, 0); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + hr = IVideoWindow_get_Height(window, &val); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + hr = IVideoWindow_put_Height(window, 128); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + + hr = IVideoWindow_get_Owner(window, &oawnd); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + hr = IVideoWindow_put_Owner(window, 0); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + + hr = IVideoWindow_get_MessageDrain(window, &oawnd); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + hr = IVideoWindow_put_MessageDrain(window, 0); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + + hr = IVideoWindow_get_BorderColor(window, &val); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + hr = IVideoWindow_put_BorderColor(window, 0); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + + hr = IVideoWindow_SetWindowForeground(window, OATRUE); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + + hr = IVideoWindow_NotifyOwnerMessage(window, (OAHWND)test_renderer_hwnd, WM_USER, 0, 0); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + + hr = IVideoWindow_GetWindowPosition(window, &x, &y, &cx, &cy); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + hr = IVideoWindow_SetWindowPosition(window, 0, 0, 100, 100); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + + hr = IVideoWindow_GetMinIdealImageSize(window, &cx, &cy); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + hr = IVideoWindow_GetMaxIdealImageSize(window, &cx, &cy); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + + hr = IVideoWindow_GetRestorePosition(window, &x, &y, &cx, &cy); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + + hr = IVideoWindow_IsCursorHidden(window, &val); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + hr = IVideoWindow_HideCursor(window, OATRUE); + todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + todo_wine check_renderer_calls(empty_seq); + reset_renderer_calls(); + + /* Restore from fullscreen mode. */ + hr = IVideoWindow_put_FullScreenMode(window, OAFALSE); + todo_wine ok(hr == S_OK, "got %#lx.\n", hr); + todo_wine check_renderer_calls(restore_seq); + reset_renderer_calls(); + + hr = IVideoWindow_GetWindowPosition(window, &x, &y, &cx, &cy); + ok(hr == S_OK, "got %#lx.\n", hr); + check_renderer_calls(get_win_pos_seq); + reset_renderer_calls(); + + IVideoWindow_Release(window); + IFilterGraph2_Release(graph); + DeleteFileW(filename); + DestroyWindow(test_renderer_hwnd); + DestroyWindow(test_drain_hwnd); + pump_messages(); +} + START_TEST(filtergraph) { CoInitializeEx(NULL, COINIT_MULTITHREADED); @@ -6115,6 +7490,7 @@ START_TEST(filtergraph) test_set_notify_flags(); test_events(); test_event_dispatch(); + test_implicit_fullscreen_support(); CoUninitialize(); test_render_with_multithread(); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11495
From: Paul Gofman <pgofman@codeweavers.com> --- dlls/quartz/tests/videorenderer.c | 9 +++++++++ dlls/quartz/tests/vmr7.c | 9 +++++++++ dlls/quartz/tests/vmr9.c | 9 +++++++++ dlls/quartz/window.c | 19 ++++++++++++++++--- 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/dlls/quartz/tests/videorenderer.c b/dlls/quartz/tests/videorenderer.c index 54681e68304..666321dc844 100644 --- a/dlls/quartz/tests/videorenderer.c +++ b/dlls/quartz/tests/videorenderer.c @@ -2063,6 +2063,15 @@ static void test_video_window_position(IVideoWindow *window, HWND hwnd, HWND our ok(top == 200, "Got top %ld.\n", top); ok(width == 300, "Got width %ld.\n", width); ok(height == 400, "Got height %ld.\n", height); + + left = top = width = height = 0xdeadbeef; + hr = IVideoWindow_GetRestorePosition(window, &left, &top, &width, &height); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(left == 100, "Got left %ld.\n", left); + ok(top == 200, "Got top %ld.\n", top); + ok(width == 300, "Got width %ld.\n", width); + ok(height == 400, "Got height %ld.\n", height); + GetWindowRect(hwnd, &rect); ok(rect.left == 100, "Got window left %ld.\n", rect.left); ok(rect.top == 200, "Got window top %ld.\n", rect.top); diff --git a/dlls/quartz/tests/vmr7.c b/dlls/quartz/tests/vmr7.c index e1bb00a20de..3ead6105da9 100644 --- a/dlls/quartz/tests/vmr7.c +++ b/dlls/quartz/tests/vmr7.c @@ -2080,6 +2080,15 @@ static void test_video_window_position(IVideoWindow *window, HWND hwnd, HWND our ok(top == 200, "Got top %ld.\n", top); ok(width == 300, "Got width %ld.\n", width); ok(height == 400, "Got height %ld.\n", height); + + left = top = width = height = 0xdeadbeef; + hr = IVideoWindow_GetRestorePosition(window, &left, &top, &width, &height); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(left == 100, "Got left %ld.\n", left); + ok(top == 200, "Got top %ld.\n", top); + ok(width == 300, "Got width %ld.\n", width); + ok(height == 400, "Got height %ld.\n", height); + GetWindowRect(hwnd, &rect); ok(rect.left == 100, "Got window left %ld.\n", rect.left); ok(rect.top == 200, "Got window top %ld.\n", rect.top); diff --git a/dlls/quartz/tests/vmr9.c b/dlls/quartz/tests/vmr9.c index 1c24a1f70e7..ee7263382cd 100644 --- a/dlls/quartz/tests/vmr9.c +++ b/dlls/quartz/tests/vmr9.c @@ -2289,6 +2289,15 @@ static void test_video_window_position(IVideoWindow *window, HWND hwnd, HWND our ok(top == 200, "Got top %ld.\n", top); ok(width == 300, "Got width %ld.\n", width); ok(height == 400, "Got height %ld.\n", height); + + left = top = width = height = 0xdeadbeef; + hr = IVideoWindow_GetRestorePosition(window, &left, &top, &width, &height); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(left == 100, "Got left %ld.\n", left); + ok(top == 200, "Got top %ld.\n", top); + ok(width == 300, "Got width %ld.\n", width); + ok(height == 400, "Got height %ld.\n", height); + GetWindowRect(hwnd, &rect); ok(rect.left == 100, "Got window left %ld.\n", rect.left); ok(rect.top == 200, "Got window top %ld.\n", rect.top); diff --git a/dlls/quartz/window.c b/dlls/quartz/window.c index 50fee32946c..0d1e1f825e2 100644 --- a/dlls/quartz/window.c +++ b/dlls/quartz/window.c @@ -682,12 +682,25 @@ HRESULT WINAPI BaseControlWindowImpl_GetMaxIdealImageSize(IVideoWindow *iface, L return S_OK; } -HRESULT WINAPI BaseControlWindowImpl_GetRestorePosition(IVideoWindow *iface, LONG *pLeft, LONG *pTop, LONG *pWidth, LONG *pHeight) +HRESULT WINAPI BaseControlWindowImpl_GetRestorePosition(IVideoWindow *iface, LONG *left, LONG *top, LONG *width, LONG *height) { - struct video_window *This = impl_from_IVideoWindow(iface); + struct video_window *window = impl_from_IVideoWindow(iface); + MONITORINFO info = { .cbSize = sizeof(info) }; + WINDOWPLACEMENT p; + HMONITOR mon; + + TRACE("window %p, left %p, top %p, width %p, height %p.\n", window, left, top, width, height); - FIXME("(%p/%p)->(%p, %p, %p, %p): stub !!!\n", This, iface, pLeft, pTop, pWidth, pHeight); + if (!GetMonitorInfoW((mon = MonitorFromWindow(window->hwnd, MONITOR_DEFAULTTONEAREST)), &info)) + return E_FAIL; + + if (!GetWindowPlacement(window->hwnd, &p)) + return E_FAIL; + *left = p.rcNormalPosition.left + info.rcWork.left; + *top = p.rcNormalPosition.top + info.rcWork.top; + *width = p.rcNormalPosition.right - p.rcNormalPosition.left; + *height = p.rcNormalPosition.bottom - p.rcNormalPosition.top; return S_OK; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11495
From: Paul Gofman <pgofman@codeweavers.com> --- dlls/quartz/filtergraph.c | 252 +++++++++++++++++++++++++------- dlls/quartz/tests/filtergraph.c | 158 ++++++++++---------- 2 files changed, 275 insertions(+), 135 deletions(-) diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index b449ef3c32c..7e2ce69b456 100644 --- a/dlls/quartz/filtergraph.c +++ b/dlls/quartz/filtergraph.c @@ -151,6 +151,7 @@ struct filter_graph unsigned int needs_async_run : 1; unsigned int threaded : 1; + unsigned int in_emulated_fs_mode : 1; }; struct enum_filters @@ -3935,7 +3936,10 @@ static HRESULT WINAPI VideoWindow_put_Caption(IVideoWindow *iface, BSTR strCapti EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_put_Caption(pVideoWindow, strCaption); @@ -3955,7 +3959,10 @@ static HRESULT WINAPI VideoWindow_get_Caption(IVideoWindow *iface, BSTR *strCapt EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_get_Caption(pVideoWindow, strCaption); @@ -3975,7 +3982,10 @@ static HRESULT WINAPI VideoWindow_put_WindowStyle(IVideoWindow *iface, LONG Wind EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_put_WindowStyle(pVideoWindow, WindowStyle); @@ -3995,7 +4005,10 @@ static HRESULT WINAPI VideoWindow_get_WindowStyle(IVideoWindow *iface, LONG *Win EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_get_WindowStyle(pVideoWindow, WindowStyle); @@ -4015,7 +4028,10 @@ static HRESULT WINAPI VideoWindow_put_WindowStyleEx(IVideoWindow *iface, LONG Wi EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_put_WindowStyleEx(pVideoWindow, WindowStyleEx); @@ -4035,7 +4051,10 @@ static HRESULT WINAPI VideoWindow_get_WindowStyleEx(IVideoWindow *iface, LONG *W EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_get_WindowStyleEx(pVideoWindow, WindowStyleEx); @@ -4055,7 +4074,10 @@ static HRESULT WINAPI VideoWindow_put_AutoShow(IVideoWindow *iface, LONG AutoSho EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_put_AutoShow(pVideoWindow, AutoShow); @@ -4075,7 +4097,10 @@ static HRESULT WINAPI VideoWindow_get_AutoShow(IVideoWindow *iface, LONG *AutoSh EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_get_AutoShow(pVideoWindow, AutoShow); @@ -4095,7 +4120,10 @@ static HRESULT WINAPI VideoWindow_put_WindowState(IVideoWindow *iface, LONG Wind EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_put_WindowState(pVideoWindow, WindowState); @@ -4115,7 +4143,10 @@ static HRESULT WINAPI VideoWindow_get_WindowState(IVideoWindow *iface, LONG *Win EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_get_WindowState(pVideoWindow, WindowState); @@ -4135,7 +4166,10 @@ static HRESULT WINAPI VideoWindow_put_BackgroundPalette(IVideoWindow *iface, LON EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_put_BackgroundPalette(pVideoWindow, BackgroundPalette); @@ -4156,7 +4190,10 @@ static HRESULT WINAPI VideoWindow_get_BackgroundPalette(IVideoWindow *iface, EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_get_BackgroundPalette(pVideoWindow, pBackgroundPalette); @@ -4176,7 +4213,10 @@ static HRESULT WINAPI VideoWindow_put_Visible(IVideoWindow *iface, LONG Visible) EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_put_Visible(pVideoWindow, Visible); @@ -4196,7 +4236,10 @@ static HRESULT WINAPI VideoWindow_get_Visible(IVideoWindow *iface, LONG *pVisibl EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_get_Visible(pVideoWindow, pVisible); @@ -4216,7 +4259,10 @@ static HRESULT WINAPI VideoWindow_put_Left(IVideoWindow *iface, LONG Left) EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_put_Left(pVideoWindow, Left); @@ -4236,7 +4282,10 @@ static HRESULT WINAPI VideoWindow_get_Left(IVideoWindow *iface, LONG *pLeft) EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_get_Left(pVideoWindow, pLeft); @@ -4256,7 +4305,10 @@ static HRESULT WINAPI VideoWindow_put_Width(IVideoWindow *iface, LONG Width) EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_put_Width(pVideoWindow, Width); @@ -4276,7 +4328,10 @@ static HRESULT WINAPI VideoWindow_get_Width(IVideoWindow *iface, LONG *pWidth) EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_get_Width(pVideoWindow, pWidth); @@ -4296,7 +4351,10 @@ static HRESULT WINAPI VideoWindow_put_Top(IVideoWindow *iface, LONG Top) EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_put_Top(pVideoWindow, Top); @@ -4316,7 +4374,10 @@ static HRESULT WINAPI VideoWindow_get_Top(IVideoWindow *iface, LONG *pTop) EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_get_Top(pVideoWindow, pTop); @@ -4336,7 +4397,10 @@ static HRESULT WINAPI VideoWindow_put_Height(IVideoWindow *iface, LONG Height) EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_put_Height(pVideoWindow, Height); @@ -4356,7 +4420,10 @@ static HRESULT WINAPI VideoWindow_get_Height(IVideoWindow *iface, LONG *pHeight) EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_get_Height(pVideoWindow, pHeight); @@ -4376,7 +4443,10 @@ static HRESULT WINAPI VideoWindow_put_Owner(IVideoWindow *iface, OAHWND Owner) EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_put_Owner(pVideoWindow, Owner); @@ -4396,7 +4466,10 @@ static HRESULT WINAPI VideoWindow_get_Owner(IVideoWindow *iface, OAHWND *Owner) EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_get_Owner(pVideoWindow, Owner); @@ -4416,7 +4489,10 @@ static HRESULT WINAPI VideoWindow_put_MessageDrain(IVideoWindow *iface, OAHWND D EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_put_MessageDrain(pVideoWindow, Drain); @@ -4436,7 +4512,10 @@ static HRESULT WINAPI VideoWindow_get_MessageDrain(IVideoWindow *iface, OAHWND * EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_get_MessageDrain(pVideoWindow, Drain); @@ -4456,7 +4535,10 @@ static HRESULT WINAPI VideoWindow_get_BorderColor(IVideoWindow *iface, LONG *Col EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_get_BorderColor(pVideoWindow, Color); @@ -4476,7 +4558,10 @@ static HRESULT WINAPI VideoWindow_put_BorderColor(IVideoWindow *iface, LONG Colo EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_put_BorderColor(pVideoWindow, Color); @@ -4486,48 +4571,76 @@ static HRESULT WINAPI VideoWindow_put_BorderColor(IVideoWindow *iface, LONG Colo return hr; } -static HRESULT WINAPI VideoWindow_get_FullScreenMode(IVideoWindow *iface, LONG *FullScreenMode) +static HRESULT WINAPI VideoWindow_get_FullScreenMode(IVideoWindow *iface, LONG *fullscreen) { struct filter_graph *This = impl_from_IVideoWindow(iface); - IVideoWindow *pVideoWindow; + IVideoWindow *video_window; HRESULT hr; - TRACE("(%p/%p)->(%p)\n", This, iface, FullScreenMode); + TRACE("(%p/%p)->(%p)\n", This, iface, fullscreen); EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); - - if (hr == S_OK) - hr = IVideoWindow_get_FullScreenMode(pVideoWindow, FullScreenMode); - if (hr == E_NOTIMPL) + if (This->in_emulated_fs_mode) { - *FullScreenMode = OAFALSE; + *fullscreen = OATRUE; hr = S_OK; } + else + { + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&video_window); + if (hr == S_OK) + hr = IVideoWindow_get_FullScreenMode(video_window, fullscreen); + if (hr == E_NOTIMPL) + { + *fullscreen = OAFALSE; + hr = S_OK; + } + } LeaveCriticalSection(&This->cs); return hr; } -static HRESULT WINAPI VideoWindow_put_FullScreenMode(IVideoWindow *iface, LONG FullScreenMode) +static HRESULT WINAPI VideoWindow_put_FullScreenMode(IVideoWindow *iface, LONG fullscreen) { struct filter_graph *This = impl_from_IVideoWindow(iface); - IVideoWindow *pVideoWindow; + IVideoWindow *video_window = NULL; + BOOL emulated = FALSE; HRESULT hr; + LONG mode; - TRACE("graph %p, fullscreen %ld.\n", This, FullScreenMode); + TRACE("graph %p, fullscreen %ld.\n", This, fullscreen); EnterCriticalSection(&This->cs); + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&video_window); + if (SUCCEEDED(hr) && !(emulated = This->in_emulated_fs_mode)) + emulated = ((hr = IVideoWindow_get_FullScreenMode(video_window, &mode)) == E_NOTIMPL); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); - - if (hr == S_OK) - hr = IVideoWindow_put_FullScreenMode(pVideoWindow, FullScreenMode); - if (hr == E_NOTIMPL && FullScreenMode == OAFALSE) - hr = S_FALSE; - + if (emulated) + { + if (This->in_emulated_fs_mode && !fullscreen) + { + /* TODO: restore window from fullscreen.*/ + hr = S_OK; + This->in_emulated_fs_mode = FALSE; + } + else if (!This->in_emulated_fs_mode && fullscreen) + { + /* TODO: setup fullscreen window.*/ + hr = S_OK; + This->in_emulated_fs_mode = TRUE; + } + else + { + hr = S_FALSE; + } + } + else if (SUCCEEDED(hr)) + { + hr = IVideoWindow_put_FullScreenMode(video_window, fullscreen); + } LeaveCriticalSection(&This->cs); return hr; @@ -4543,7 +4656,10 @@ static HRESULT WINAPI VideoWindow_SetWindowForeground(IVideoWindow *iface, LONG EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_SetWindowForeground(pVideoWindow, Focus); @@ -4564,7 +4680,10 @@ static HRESULT WINAPI VideoWindow_NotifyOwnerMessage(IVideoWindow *iface, OAHWND EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_NotifyOwnerMessage(pVideoWindow, hwnd, uMsg, wParam, lParam); @@ -4585,7 +4704,10 @@ static HRESULT WINAPI VideoWindow_SetWindowPosition(IVideoWindow *iface, LONG Le EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_SetWindowPosition(pVideoWindow, Left, Top, Width, Height); @@ -4606,7 +4728,10 @@ static HRESULT WINAPI VideoWindow_GetWindowPosition(IVideoWindow *iface, LONG *p EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_GetWindowPosition(pVideoWindow, pLeft, pTop, pWidth, pHeight); @@ -4627,7 +4752,10 @@ static HRESULT WINAPI VideoWindow_GetMinIdealImageSize(IVideoWindow *iface, LONG EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_GetMinIdealImageSize(pVideoWindow, pWidth, pHeight); @@ -4648,7 +4776,10 @@ static HRESULT WINAPI VideoWindow_GetMaxIdealImageSize(IVideoWindow *iface, LONG EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_GetMaxIdealImageSize(pVideoWindow, pWidth, pHeight); @@ -4669,7 +4800,10 @@ static HRESULT WINAPI VideoWindow_GetRestorePosition(IVideoWindow *iface, LONG * EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_GetRestorePosition(pVideoWindow, pLeft, pTop, pWidth, pHeight); @@ -4689,7 +4823,10 @@ static HRESULT WINAPI VideoWindow_HideCursor(IVideoWindow *iface, LONG HideCurso EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_HideCursor(pVideoWindow, HideCursor); @@ -4709,7 +4846,10 @@ static HRESULT WINAPI VideoWindow_IsCursorHidden(IVideoWindow *iface, LONG *Curs EnterCriticalSection(&This->cs); - hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); + if (This->in_emulated_fs_mode) + hr = VFW_E_IN_FULLSCREEN_MODE; + else + hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) hr = IVideoWindow_IsCursorHidden(pVideoWindow, CursorHidden); diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c index e86014311a7..4991f6940e4 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -7261,190 +7261,190 @@ static void test_implicit_fullscreen_support(void) reset_renderer_calls(); hr = IVideoWindow_put_FullScreenMode(window, OATRUE); - todo_wine ok(hr == S_OK, "got %#lx.\n", hr); + ok(hr == S_OK, "got %#lx.\n", hr); todo_wine check_renderer_calls(set_fullscreen_seq); reset_renderer_calls(); hr = IVideoWindow_put_FullScreenMode(window, OATRUE); - todo_wine ok(hr == S_FALSE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == S_FALSE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_get_FullScreenMode(window, &val); ok(hr == S_OK, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + check_renderer_calls(empty_seq); reset_renderer_calls(); /* All video window calls in fullscreen mode. Nothing is forwarded, everything but NotifyOwnerMessage * returns VFW_E_IN_FULLSCREEN_MODE. */ hr = IVideoWindow_get_Caption(window, &bstr); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_put_Caption(window, (BSTR)L"test"); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_get_WindowStyle(window, &val); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_put_WindowStyle(window, WS_POPUP); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_get_WindowStyleEx(window, &val); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_put_WindowStyleEx(window, WS_EX_TOOLWINDOW); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_get_AutoShow(window, &val); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_put_AutoShow(window, 0); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_get_WindowState(window, &val); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_put_WindowState(window, SW_SHOW); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_get_BackgroundPalette(window, &val); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_put_BackgroundPalette(window, 0); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_get_Visible(window, &val); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_put_Visible(window, OATRUE); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_get_Left(window, &val); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_put_Left(window, 0); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_get_Width(window, &val); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_put_Width(window, 128); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_get_Top(window, &val); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_put_Top(window, 0); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_get_Height(window, &val); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_put_Height(window, 128); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_get_Owner(window, &oawnd); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_put_Owner(window, 0); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_get_MessageDrain(window, &oawnd); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_put_MessageDrain(window, 0); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_get_BorderColor(window, &val); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_put_BorderColor(window, 0); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_SetWindowForeground(window, OATRUE); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_NotifyOwnerMessage(window, (OAHWND)test_renderer_hwnd, WM_USER, 0, 0); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_GetWindowPosition(window, &x, &y, &cx, &cy); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_SetWindowPosition(window, 0, 0, 100, 100); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_GetMinIdealImageSize(window, &cx, &cy); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_GetMaxIdealImageSize(window, &cx, &cy); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_GetRestorePosition(window, &x, &y, &cx, &cy); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_IsCursorHidden(window, &val); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); hr = IVideoWindow_HideCursor(window, OATRUE); - todo_wine ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); - todo_wine check_renderer_calls(empty_seq); + ok(hr == VFW_E_IN_FULLSCREEN_MODE, "got %#lx.\n", hr); + check_renderer_calls(empty_seq); reset_renderer_calls(); /* Restore from fullscreen mode. */ hr = IVideoWindow_put_FullScreenMode(window, OAFALSE); - todo_wine ok(hr == S_OK, "got %#lx.\n", hr); + ok(hr == S_OK, "got %#lx.\n", hr); todo_wine check_renderer_calls(restore_seq); reset_renderer_calls(); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11495
From: Paul Gofman <pgofman@codeweavers.com> --- dlls/quartz/filtergraph.c | 160 +++++++++++++++++++++++++++++++- dlls/quartz/tests/filtergraph.c | 4 +- 2 files changed, 160 insertions(+), 4 deletions(-) diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index 7e2ce69b456..54a2b5d1ad9 100644 --- a/dlls/quartz/filtergraph.c +++ b/dlls/quartz/filtergraph.c @@ -77,6 +77,19 @@ struct filter BOOL sorting; }; +struct emulated_fullscreen_state +{ + long auto_show; + long cursor_hidden; + long source_left, source_top, source_width, source_height; + long dest_left, dest_top, dest_width, dest_height; + BOOL using_default_source, using_default_dest; + long restore_left, restore_top, restore_width, restore_height; + LONG style, style_ex; + OAHWND owner; + OAHWND drain; +}; + struct filter_graph { IUnknown IUnknown_inner; @@ -149,6 +162,9 @@ struct filter_graph REFERENCE_TIME stream_stop; LONGLONG current_pos; + OAHWND hwnd_drain; + struct emulated_fullscreen_state fs_state; + unsigned int needs_async_run : 1; unsigned int threaded : 1; unsigned int in_emulated_fs_mode : 1; @@ -4495,7 +4511,10 @@ static HRESULT WINAPI VideoWindow_put_MessageDrain(IVideoWindow *iface, OAHWND D hr = GetTargetInterface(This, &IID_IVideoWindow, (LPVOID*)&pVideoWindow); if (hr == S_OK) + { hr = IVideoWindow_put_MessageDrain(pVideoWindow, Drain); + This->hwnd_drain = Drain; + } LeaveCriticalSection(&This->cs); @@ -4603,6 +4622,143 @@ static HRESULT WINAPI VideoWindow_get_FullScreenMode(IVideoWindow *iface, LONG * return hr; } +static void leave_fullscreen_mode(struct filter_graph *graph, IVideoWindow *window) +{ + struct emulated_fullscreen_state *s = &graph->fs_state; + IBasicVideo *video = NULL; + + IVideoWindow_QueryInterface(window, &IID_IBasicVideo, (void **)&video); + + IVideoWindow_SetWindowPosition(window, 0, 0, 0, 0); + IVideoWindow_put_WindowStyleEx(window, s->style_ex); + IVideoWindow_put_Visible(window, OAFALSE); + IVideoWindow_put_WindowStyle(window, s->style); + IVideoWindow_put_MessageDrain(window, s->drain); + if (!s->cursor_hidden) + IVideoWindow_HideCursor(window, OAFALSE); + if (video) + { + IBasicVideo_SetSourcePosition(video, s->source_left, s->source_top, s->source_width, s->source_height); + IBasicVideo_SetDestinationPosition(video, s->dest_left, s->dest_top, s->dest_width, s->dest_height); + if (s->using_default_source) + IBasicVideo_SetDefaultSourcePosition(video); + if (s->using_default_dest) + IBasicVideo_SetDefaultDestinationPosition(video); + } + IVideoWindow_put_Owner(window, s->owner); + IVideoWindow_SetWindowPosition(window, s->restore_left, s->restore_top, s->restore_width, s->restore_height); + IVideoWindow_put_WindowState(window, SW_SHOWNORMAL); +} + +static void enter_fullscreen_mode(struct filter_graph *graph, IVideoWindow *window) +{ + unsigned int monitor_width, monitor_height, monitor_left, monitor_top; + unsigned int video_width, video_height, video_left, video_top; + struct emulated_fullscreen_state *s = &graph->fs_state; + MONITORINFO info = { .cbSize = sizeof(info) }; + IEnumPins *enum_pins = NULL; + IBaseFilter *filter = NULL; + IBasicVideo *video = NULL; + IOverlay *overlay = NULL; + long width, height; + IPin *pin = NULL; + HWND hwnd = NULL; + + IVideoWindow_QueryInterface(window, &IID_IBasicVideo, (void **)&video); + if (SUCCEEDED(IVideoWindow_QueryInterface(window, &IID_IBaseFilter, (void **)&filter)) + && SUCCEEDED(IBaseFilter_EnumPins(filter, &enum_pins)) + && IEnumPins_Next(enum_pins, 1, &pin, NULL) == S_OK) + IPin_QueryInterface(pin, &IID_IOverlay, (void **)&overlay); + if (pin) + IPin_Release(pin); + if (enum_pins) + IEnumPins_Release(enum_pins); + if (filter) + IBaseFilter_Release(filter); + + memset(s, 0, sizeof(*s)); + IVideoWindow_get_AutoShow(window, &s->auto_show); + IVideoWindow_put_AutoShow(window, OAFALSE); + width = height = 0; + if (video) + IBasicVideo_GetVideoSize(video, &width, &height); + if (overlay) + IOverlay_GetWindowHandle(overlay, &hwnd); + + if (hwnd && GetMonitorInfoW(MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST), &info)) + { + monitor_width = info.rcMonitor.right - info.rcMonitor.left; + monitor_height = info.rcMonitor.bottom - info.rcMonitor.top; + monitor_left = info.rcMonitor.left; + monitor_top = info.rcMonitor.top; + } + else + { + monitor_width = GetSystemMetrics(SM_CXSCREEN); + monitor_height = GetSystemMetrics(SM_CYSCREEN); + monitor_left = monitor_top = 0; + } + if (width && height) + { + if (monitor_width * height >= width * monitor_height) + { + video_height = monitor_height; + video_width = monitor_height * width / height; + video_top = 0; + video_left = (monitor_width - video_width) / 2; + } + else + { + video_width = monitor_width; + video_height = monitor_width * height / width; + video_left = 0; + video_top = (monitor_height - video_height) / 2; + } + } + else + { + video_left = video_top = 0; + video_width = monitor_width; + video_height = monitor_height; + } + + /* As tests show GetMaxIdealImageSize is called on Windows but not clear yet what the result affects. */ + IVideoWindow_GetMaxIdealImageSize(window, &width, &height); + IVideoWindow_put_AutoShow(window, OATRUE); + IVideoWindow_put_Visible(window, OAFALSE); + IVideoWindow_IsCursorHidden(window, &s->cursor_hidden); + if (!s->cursor_hidden) + IVideoWindow_HideCursor(window, OATRUE); + if (video) + { + IBasicVideo_GetSourcePosition(video, &s->source_left, &s->source_top, &s->source_width, &s->source_height); + IBasicVideo_GetDestinationPosition(video, &s->dest_left, &s->dest_top, &s->dest_width, &s->dest_height); + s->using_default_source = (IBasicVideo_IsUsingDefaultSource(video) == S_OK); + s->using_default_dest = (IBasicVideo_IsUsingDefaultDestination(video) == S_OK); + IBasicVideo_SetDefaultSourcePosition(video); + IBasicVideo_SetDestinationPosition(video, video_left, video_top, video_width, video_height); + } + IVideoWindow_GetRestorePosition(window, &s->restore_left, &s->restore_top, &s->restore_width, &s->restore_height); + IVideoWindow_get_WindowStyle(window, &s->style); + IVideoWindow_put_WindowStyle(window, WS_POPUP); + IVideoWindow_get_Owner(window, &s->owner); + IVideoWindow_put_Owner(window, 0); + if (overlay) + IOverlay_GetWindowHandle(overlay, &hwnd); + IVideoWindow_SetWindowPosition(window, monitor_left, monitor_top, monitor_width, monitor_height); + IVideoWindow_get_MessageDrain(window, &s->drain); + IVideoWindow_put_MessageDrain(window, graph->hwnd_drain); + IVideoWindow_put_Visible(window, OATRUE); + IVideoWindow_SetWindowForeground(window, OATRUE); + IVideoWindow_get_WindowStyleEx(window, &s->style_ex); + IVideoWindow_put_WindowStyleEx(window, WS_EX_TOPMOST); + + if (video) + IBasicVideo_Release(video); + if (overlay) + IOverlay_Release(overlay); +} + static HRESULT WINAPI VideoWindow_put_FullScreenMode(IVideoWindow *iface, LONG fullscreen) { struct filter_graph *This = impl_from_IVideoWindow(iface); @@ -4622,13 +4778,13 @@ static HRESULT WINAPI VideoWindow_put_FullScreenMode(IVideoWindow *iface, LONG f { if (This->in_emulated_fs_mode && !fullscreen) { - /* TODO: restore window from fullscreen.*/ + leave_fullscreen_mode(This, video_window); hr = S_OK; This->in_emulated_fs_mode = FALSE; } else if (!This->in_emulated_fs_mode && fullscreen) { - /* TODO: setup fullscreen window.*/ + enter_fullscreen_mode(This, video_window); hr = S_OK; This->in_emulated_fs_mode = TRUE; } diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c index 4991f6940e4..a2ef2a257c4 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -7262,7 +7262,7 @@ static void test_implicit_fullscreen_support(void) hr = IVideoWindow_put_FullScreenMode(window, OATRUE); ok(hr == S_OK, "got %#lx.\n", hr); - todo_wine check_renderer_calls(set_fullscreen_seq); + check_renderer_calls(set_fullscreen_seq); reset_renderer_calls(); hr = IVideoWindow_put_FullScreenMode(window, OATRUE); @@ -7445,7 +7445,7 @@ static void test_implicit_fullscreen_support(void) /* Restore from fullscreen mode. */ hr = IVideoWindow_put_FullScreenMode(window, OAFALSE); ok(hr == S_OK, "got %#lx.\n", hr); - todo_wine check_renderer_calls(restore_seq); + check_renderer_calls(restore_seq); reset_renderer_calls(); hr = IVideoWindow_GetWindowPosition(window, &x, &y, &cx, &cy); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11495
v3: - Fix a TRACE in now implemented BaseControlWindowImpl_GetRestorePosition. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11495#note_148753
participants (2)
-
Paul Gofman -
Paul Gofman (@gofman)