mfmediaengine: Remove unnecessary import library.
[wine.git] / dlls / quartz / window.c
blob5b172d5f108fbcbdbbb776a27efc91ce67fbc64c
1 /*
2 * Common implementation of IVideoWindow
4 * Copyright 2012 Aric Stewart, CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "quartz_private.h"
23 #define WM_QUARTZ_DESTROY (WM_USER + WM_DESTROY)
25 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
27 static const WCHAR class_name[] = L"wine_quartz_window";
29 static inline struct video_window *impl_from_IVideoWindow(IVideoWindow *iface)
31 return CONTAINING_RECORD(iface, struct video_window, IVideoWindow_iface);
34 static LRESULT CALLBACK WndProcW(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
36 struct video_window *window = (struct video_window *)GetWindowLongPtrW(hwnd, 0);
38 if (!window)
39 return DefWindowProcW(hwnd, message, wparam, lparam);
41 switch (message)
43 case WM_KEYDOWN:
44 case WM_KEYUP:
45 case WM_LBUTTONDBLCLK:
46 case WM_LBUTTONDOWN:
47 case WM_LBUTTONUP:
48 case WM_MBUTTONDBLCLK:
49 case WM_MBUTTONDOWN:
50 case WM_MBUTTONUP:
51 case WM_MOUSEACTIVATE:
52 case WM_MOUSEMOVE:
53 case WM_NCLBUTTONDBLCLK:
54 case WM_NCLBUTTONDOWN:
55 case WM_NCLBUTTONUP:
56 case WM_NCMBUTTONDBLCLK:
57 case WM_NCMBUTTONDOWN:
58 case WM_NCMBUTTONUP:
59 case WM_NCMOUSEMOVE:
60 case WM_NCRBUTTONDBLCLK:
61 case WM_NCRBUTTONDOWN:
62 case WM_NCRBUTTONUP:
63 case WM_RBUTTONDBLCLK:
64 case WM_RBUTTONDOWN:
65 case WM_RBUTTONUP:
66 if (window->hwndDrain)
68 PostMessageW(window->hwndDrain, message, wparam, lparam);
69 return 0;
71 break;
72 case WM_SIZE:
73 if (window->default_dst)
74 GetClientRect(window->hwnd, &window->dst);
75 break;
76 case WM_QUARTZ_DESTROY:
77 DestroyWindow(hwnd);
78 return 0;
79 case WM_CLOSE:
81 IFilterGraph *graph = window->pFilter->graph;
82 IMediaEventSink *event_sink;
83 IVideoWindow_put_Visible(&window->IVideoWindow_iface, OAFALSE);
84 if (graph && SUCCEEDED(IFilterGraph_QueryInterface(graph,
85 &IID_IMediaEventSink,
86 (void **)&event_sink)))
88 IMediaEventSink_Notify(event_sink, EC_USERABORT, 0, 0);
89 IMediaEventSink_Release(event_sink);
91 return 0;
95 return DefWindowProcW(hwnd, message, wparam, lparam);
98 HRESULT video_window_create_window(struct video_window *window)
100 WNDCLASSW winclass = {0};
102 winclass.lpfnWndProc = WndProcW;
103 winclass.cbWndExtra = sizeof(window);
104 winclass.hbrBackground = GetStockObject(BLACK_BRUSH);
105 winclass.lpszClassName = class_name;
106 if (!RegisterClassW(&winclass) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS)
108 ERR("Unable to register window class: %u\n", GetLastError());
109 return E_FAIL;
112 if (!(window->hwnd = CreateWindowExW(0, class_name, L"ActiveMovie Window",
113 WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
114 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
115 NULL, NULL, NULL, NULL)))
117 ERR("Unable to create window\n");
118 return E_FAIL;
121 SetWindowLongPtrW(window->hwnd, 0, (LONG_PTR)window);
123 return S_OK;
126 HRESULT WINAPI BaseControlWindowImpl_QueryInterface(IVideoWindow *iface, REFIID iid, void **out)
128 struct video_window *window = impl_from_IVideoWindow(iface);
129 return IUnknown_QueryInterface(window->pFilter->outer_unk, iid, out);
132 ULONG WINAPI BaseControlWindowImpl_AddRef(IVideoWindow *iface)
134 struct video_window *window = impl_from_IVideoWindow(iface);
135 return IUnknown_AddRef(window->pFilter->outer_unk);
138 ULONG WINAPI BaseControlWindowImpl_Release(IVideoWindow *iface)
140 struct video_window *window = impl_from_IVideoWindow(iface);
141 return IUnknown_Release(window->pFilter->outer_unk);
144 HRESULT WINAPI BaseControlWindowImpl_GetTypeInfoCount(IVideoWindow *iface, UINT *count)
146 TRACE("iface %p, count %p.\n", iface, count);
147 *count = 1;
148 return S_OK;
151 HRESULT WINAPI BaseControlWindowImpl_GetTypeInfo(IVideoWindow *iface, UINT index,
152 LCID lcid, ITypeInfo **typeinfo)
154 TRACE("iface %p, index %u, lcid %#x, typeinfo %p.\n", iface, index, lcid, typeinfo);
155 return strmbase_get_typeinfo(IVideoWindow_tid, typeinfo);
158 HRESULT WINAPI BaseControlWindowImpl_GetIDsOfNames(IVideoWindow *iface, REFIID iid,
159 LPOLESTR *names, UINT count, LCID lcid, DISPID *ids)
161 ITypeInfo *typeinfo;
162 HRESULT hr;
164 TRACE("iface %p, iid %s, names %p, count %u, lcid %#x, ids %p.\n",
165 iface, debugstr_guid(iid), names, count, lcid, ids);
167 if (SUCCEEDED(hr = strmbase_get_typeinfo(IVideoWindow_tid, &typeinfo)))
169 hr = ITypeInfo_GetIDsOfNames(typeinfo, names, count, ids);
170 ITypeInfo_Release(typeinfo);
172 return hr;
175 HRESULT WINAPI BaseControlWindowImpl_Invoke(IVideoWindow *iface, DISPID id, REFIID iid, LCID lcid,
176 WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *error_arg)
178 ITypeInfo *typeinfo;
179 HRESULT hr;
181 TRACE("iface %p, id %d, iid %s, lcid %#x, flags %#x, params %p, result %p, excepinfo %p, error_arg %p.\n",
182 iface, id, debugstr_guid(iid), lcid, flags, params, result, excepinfo, error_arg);
184 if (SUCCEEDED(hr = strmbase_get_typeinfo(IVideoWindow_tid, &typeinfo)))
186 hr = ITypeInfo_Invoke(typeinfo, iface, id, flags, params, result, excepinfo, error_arg);
187 ITypeInfo_Release(typeinfo);
189 return hr;
192 HRESULT WINAPI BaseControlWindowImpl_put_Caption(IVideoWindow *iface, BSTR caption)
194 struct video_window *window = impl_from_IVideoWindow(iface);
196 TRACE("window %p, caption %s.\n", window, debugstr_w(caption));
198 if (!SetWindowTextW(window->hwnd, caption))
199 return E_FAIL;
201 return S_OK;
204 HRESULT WINAPI BaseControlWindowImpl_get_Caption(IVideoWindow *iface, BSTR *caption)
206 struct video_window *window = impl_from_IVideoWindow(iface);
207 WCHAR *str;
208 int len;
210 TRACE("window %p, caption %p.\n", window, caption);
212 *caption = NULL;
214 len = GetWindowTextLengthW(window->hwnd) + 1;
215 if (!(str = heap_alloc(len * sizeof(WCHAR))))
216 return E_OUTOFMEMORY;
218 GetWindowTextW(window->hwnd, str, len);
219 *caption = SysAllocString(str);
220 heap_free(str);
221 return *caption ? S_OK : E_OUTOFMEMORY;
224 HRESULT WINAPI BaseControlWindowImpl_put_WindowStyle(IVideoWindow *iface, LONG style)
226 struct video_window *window = impl_from_IVideoWindow(iface);
228 TRACE("window %p, style %#x.\n", window, style);
230 if (style & (WS_DISABLED|WS_HSCROLL|WS_MAXIMIZE|WS_MINIMIZE|WS_VSCROLL))
231 return E_INVALIDARG;
233 SetWindowLongW(window->hwnd, GWL_STYLE, style);
234 SetWindowPos(window->hwnd, 0, 0, 0, 0, 0,
235 SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
236 return S_OK;
239 HRESULT WINAPI BaseControlWindowImpl_get_WindowStyle(IVideoWindow *iface, LONG *style)
241 struct video_window *window = impl_from_IVideoWindow(iface);
243 TRACE("window %p, style %p.\n", window, style);
245 *style = GetWindowLongW(window->hwnd, GWL_STYLE);
246 return S_OK;
249 HRESULT WINAPI BaseControlWindowImpl_put_WindowStyleEx(IVideoWindow *iface, LONG style)
251 struct video_window *window = impl_from_IVideoWindow(iface);
253 TRACE("window %p, style %#x.\n", window, style);
255 if (!SetWindowLongW(window->hwnd, GWL_EXSTYLE, style))
256 return E_FAIL;
257 return S_OK;
260 HRESULT WINAPI BaseControlWindowImpl_get_WindowStyleEx(IVideoWindow *iface, LONG *style)
262 struct video_window *window = impl_from_IVideoWindow(iface);
264 TRACE("window %p, style %p.\n", window, style);
266 *style = GetWindowLongW(window->hwnd, GWL_EXSTYLE);
267 return S_OK;
270 HRESULT WINAPI BaseControlWindowImpl_put_AutoShow(IVideoWindow *iface, LONG AutoShow)
272 struct video_window *This = impl_from_IVideoWindow(iface);
274 TRACE("(%p/%p)->(%d)\n", This, iface, AutoShow);
276 This->AutoShow = AutoShow;
278 return S_OK;
281 HRESULT WINAPI BaseControlWindowImpl_get_AutoShow(IVideoWindow *iface, LONG *AutoShow)
283 struct video_window *This = impl_from_IVideoWindow(iface);
285 TRACE("(%p/%p)->(%p)\n", This, iface, AutoShow);
287 *AutoShow = This->AutoShow;
289 return S_OK;
292 HRESULT WINAPI BaseControlWindowImpl_put_WindowState(IVideoWindow *iface, LONG state)
294 struct video_window *window = impl_from_IVideoWindow(iface);
296 TRACE("window %p, state %#x.\n", window, state);
298 ShowWindow(window->hwnd, state);
299 return S_OK;
302 HRESULT WINAPI BaseControlWindowImpl_get_WindowState(IVideoWindow *iface, LONG *state)
304 struct video_window *window = impl_from_IVideoWindow(iface);
305 DWORD style;
307 TRACE("window %p, state %p.\n", window, state);
309 style = GetWindowLongPtrW(window->hwnd, GWL_STYLE);
310 if (!(style & WS_VISIBLE))
311 *state = SW_HIDE;
312 else if (style & WS_MINIMIZE)
313 *state = SW_MINIMIZE;
314 else if (style & WS_MAXIMIZE)
315 *state = SW_MAXIMIZE;
316 else
317 *state = SW_SHOW;
319 return S_OK;
322 HRESULT WINAPI BaseControlWindowImpl_put_BackgroundPalette(IVideoWindow *iface, LONG BackgroundPalette)
324 struct video_window *This = impl_from_IVideoWindow(iface);
326 FIXME("(%p/%p)->(%d): stub !!!\n", This, iface, BackgroundPalette);
328 return S_OK;
331 HRESULT WINAPI BaseControlWindowImpl_get_BackgroundPalette(IVideoWindow *iface, LONG *pBackgroundPalette)
333 struct video_window *This = impl_from_IVideoWindow(iface);
335 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pBackgroundPalette);
337 return S_OK;
340 HRESULT WINAPI BaseControlWindowImpl_put_Visible(IVideoWindow *iface, LONG visible)
342 struct video_window *window = impl_from_IVideoWindow(iface);
344 TRACE("window %p, visible %d.\n", window, visible);
346 ShowWindow(window->hwnd, visible ? SW_SHOW : SW_HIDE);
347 return S_OK;
350 HRESULT WINAPI BaseControlWindowImpl_get_Visible(IVideoWindow *iface, LONG *visible)
352 struct video_window *window = impl_from_IVideoWindow(iface);
354 TRACE("window %p, visible %p.\n", window, visible);
356 if (!visible)
357 return E_POINTER;
359 *visible = IsWindowVisible(window->hwnd) ? OATRUE : OAFALSE;
360 return S_OK;
363 HRESULT WINAPI BaseControlWindowImpl_put_Left(IVideoWindow *iface, LONG left)
365 struct video_window *window = impl_from_IVideoWindow(iface);
366 RECT rect;
368 TRACE("window %p, left %d.\n", window, left);
370 GetWindowRect(window->hwnd, &rect);
371 if (!SetWindowPos(window->hwnd, NULL, left, rect.top, 0, 0,
372 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE))
373 return E_FAIL;
375 return S_OK;
378 HRESULT WINAPI BaseControlWindowImpl_get_Left(IVideoWindow *iface, LONG *left)
380 struct video_window *window = impl_from_IVideoWindow(iface);
381 RECT rect;
383 TRACE("window %p, left %p.\n", window, left);
385 GetWindowRect(window->hwnd, &rect);
386 *left = rect.left;
387 return S_OK;
390 HRESULT WINAPI BaseControlWindowImpl_put_Width(IVideoWindow *iface, LONG width)
392 struct video_window *window = impl_from_IVideoWindow(iface);
393 RECT rect;
395 TRACE("window %p, width %d.\n", window, width);
397 GetWindowRect(window->hwnd, &rect);
398 if (!SetWindowPos(window->hwnd, NULL, 0, 0, width, rect.bottom - rect.top,
399 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE))
400 return E_FAIL;
402 return S_OK;
405 HRESULT WINAPI BaseControlWindowImpl_get_Width(IVideoWindow *iface, LONG *width)
407 struct video_window *window = impl_from_IVideoWindow(iface);
408 RECT rect;
410 TRACE("window %p, width %p.\n", window, width);
412 GetWindowRect(window->hwnd, &rect);
413 *width = rect.right - rect.left;
414 return S_OK;
417 HRESULT WINAPI BaseControlWindowImpl_put_Top(IVideoWindow *iface, LONG top)
419 struct video_window *window = impl_from_IVideoWindow(iface);
420 RECT rect;
422 TRACE("window %p, top %d.\n", window, top);
424 GetWindowRect(window->hwnd, &rect);
425 if (!SetWindowPos(window->hwnd, NULL, rect.left, top, 0, 0,
426 SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE))
427 return E_FAIL;
429 return S_OK;
432 HRESULT WINAPI BaseControlWindowImpl_get_Top(IVideoWindow *iface, LONG *top)
434 struct video_window *window = impl_from_IVideoWindow(iface);
435 RECT rect;
437 TRACE("window %p, top %p.\n", window, top);
439 GetWindowRect(window->hwnd, &rect);
440 *top = rect.top;
441 return S_OK;
444 HRESULT WINAPI BaseControlWindowImpl_put_Height(IVideoWindow *iface, LONG height)
446 struct video_window *window = impl_from_IVideoWindow(iface);
447 RECT rect;
449 TRACE("window %p, height %d.\n", window, height);
451 GetWindowRect(window->hwnd, &rect);
452 if (!SetWindowPos(window->hwnd, NULL, 0, 0, rect.right - rect.left,
453 height, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE))
454 return E_FAIL;
456 return S_OK;
459 HRESULT WINAPI BaseControlWindowImpl_get_Height(IVideoWindow *iface, LONG *height)
461 struct video_window *window = impl_from_IVideoWindow(iface);
462 RECT rect;
464 TRACE("window %p, height %p.\n", window, height);
466 GetWindowRect(window->hwnd, &rect);
467 *height = rect.bottom - rect.top;
468 return S_OK;
471 HRESULT WINAPI BaseControlWindowImpl_put_Owner(IVideoWindow *iface, OAHWND owner)
473 struct video_window *window = impl_from_IVideoWindow(iface);
474 HWND hwnd = window->hwnd;
476 TRACE("window %p, owner %#lx.\n", window, owner);
478 /* Make sure we are marked as WS_CHILD before reparenting ourselves, so that
479 * we do not steal focus. LEGO Island depends on this. */
481 window->hwndOwner = (HWND)owner;
482 if (owner)
483 SetWindowLongPtrW(hwnd, GWL_STYLE, GetWindowLongPtrW(hwnd, GWL_STYLE) | WS_CHILD);
484 else
485 SetWindowLongPtrW(hwnd, GWL_STYLE, GetWindowLongPtrW(hwnd, GWL_STYLE) & ~WS_CHILD);
486 SetParent(hwnd, (HWND)owner);
488 return S_OK;
491 HRESULT WINAPI BaseControlWindowImpl_get_Owner(IVideoWindow *iface, OAHWND *Owner)
493 struct video_window *This = impl_from_IVideoWindow(iface);
495 TRACE("(%p/%p)->(%p)\n", This, iface, Owner);
497 *(HWND*)Owner = This->hwndOwner;
499 return S_OK;
502 HRESULT WINAPI BaseControlWindowImpl_put_MessageDrain(IVideoWindow *iface, OAHWND Drain)
504 struct video_window *This = impl_from_IVideoWindow(iface);
506 TRACE("(%p/%p)->(%08x)\n", This, iface, (DWORD) Drain);
508 This->hwndDrain = (HWND)Drain;
510 return S_OK;
513 HRESULT WINAPI BaseControlWindowImpl_get_MessageDrain(IVideoWindow *iface, OAHWND *Drain)
515 struct video_window *This = impl_from_IVideoWindow(iface);
517 TRACE("(%p/%p)->(%p)\n", This, iface, Drain);
519 *Drain = (OAHWND)This->hwndDrain;
521 return S_OK;
524 HRESULT WINAPI BaseControlWindowImpl_get_BorderColor(IVideoWindow *iface, LONG *Color)
526 struct video_window *This = impl_from_IVideoWindow(iface);
528 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, Color);
530 return S_OK;
533 HRESULT WINAPI BaseControlWindowImpl_put_BorderColor(IVideoWindow *iface, LONG Color)
535 struct video_window *This = impl_from_IVideoWindow(iface);
537 FIXME("(%p/%p)->(%d): stub !!!\n", This, iface, Color);
539 return S_OK;
542 HRESULT WINAPI BaseControlWindowImpl_get_FullScreenMode(IVideoWindow *iface, LONG *FullScreenMode)
544 TRACE("(%p)->(%p)\n", iface, FullScreenMode);
546 return E_NOTIMPL;
549 HRESULT WINAPI BaseControlWindowImpl_put_FullScreenMode(IVideoWindow *iface, LONG FullScreenMode)
551 TRACE("(%p)->(%d)\n", iface, FullScreenMode);
552 return E_NOTIMPL;
555 HRESULT WINAPI BaseControlWindowImpl_SetWindowForeground(IVideoWindow *iface, LONG focus)
557 struct video_window *window = impl_from_IVideoWindow(iface);
558 UINT flags = SWP_NOMOVE | SWP_NOSIZE;
560 TRACE("window %p, focus %d.\n", window, focus);
562 if (focus != OAFALSE && focus != OATRUE)
563 return E_INVALIDARG;
565 if (!window->pPin->peer)
566 return VFW_E_NOT_CONNECTED;
568 if (!focus)
569 flags |= SWP_NOACTIVATE;
570 SetWindowPos(window->hwnd, HWND_TOP, 0, 0, 0, 0, flags);
572 return S_OK;
575 HRESULT WINAPI BaseControlWindowImpl_SetWindowPosition(IVideoWindow *iface,
576 LONG left, LONG top, LONG width, LONG height)
578 struct video_window *window = impl_from_IVideoWindow(iface);
580 TRACE("window %p, left %d, top %d, width %d, height %d.\n", window, left, top, width, height);
582 if (!SetWindowPos(window->hwnd, NULL, left, top, width, height, SWP_NOACTIVATE | SWP_NOZORDER))
583 return E_FAIL;
584 return S_OK;
587 HRESULT WINAPI BaseControlWindowImpl_GetWindowPosition(IVideoWindow *iface,
588 LONG *left, LONG *top, LONG *width, LONG *height)
590 struct video_window *window = impl_from_IVideoWindow(iface);
591 RECT rect;
593 TRACE("window %p, left %p, top %p, width %p, height %p.\n", window, left, top, width, height);
595 GetWindowRect(window->hwnd, &rect);
596 *left = rect.left;
597 *top = rect.top;
598 *width = rect.right - rect.left;
599 *height = rect.bottom - rect.top;
600 return S_OK;
603 HRESULT WINAPI BaseControlWindowImpl_NotifyOwnerMessage(IVideoWindow *iface,
604 OAHWND hwnd, LONG message, LONG_PTR wparam, LONG_PTR lparam)
606 struct video_window *window = impl_from_IVideoWindow(iface);
608 TRACE("window %p, hwnd %#lx, message %#x, wparam %#lx, lparam %#lx.\n",
609 window, hwnd, message, wparam, lparam);
611 /* That these messages are forwarded, and no others, is stated by the
612 * DirectX documentation, and supported by manual testing. */
613 switch (message)
615 case WM_ACTIVATEAPP:
616 case WM_DEVMODECHANGE:
617 case WM_DISPLAYCHANGE:
618 case WM_PALETTECHANGED:
619 case WM_PALETTEISCHANGING:
620 case WM_QUERYNEWPALETTE:
621 case WM_SYSCOLORCHANGE:
622 SendMessageW(window->hwnd, message, wparam, lparam);
623 break;
626 return S_OK;
629 HRESULT WINAPI BaseControlWindowImpl_GetMinIdealImageSize(IVideoWindow *iface, LONG *width, LONG *height)
631 struct video_window *window = impl_from_IVideoWindow(iface);
632 RECT rect;
634 TRACE("window %p, width %p, height %p.\n", window, width, height);
636 rect = window->ops->get_default_rect(window);
637 *width = rect.right - rect.left;
638 *height = rect.bottom - rect.top;
639 return S_OK;
642 HRESULT WINAPI BaseControlWindowImpl_GetMaxIdealImageSize(IVideoWindow *iface, LONG *width, LONG *height)
644 struct video_window *window = impl_from_IVideoWindow(iface);
645 RECT rect;
647 TRACE("window %p, width %p, height %p.\n", window, width, height);
649 rect = window->ops->get_default_rect(window);
650 *width = rect.right - rect.left;
651 *height = rect.bottom - rect.top;
652 return S_OK;
655 HRESULT WINAPI BaseControlWindowImpl_GetRestorePosition(IVideoWindow *iface, LONG *pLeft, LONG *pTop, LONG *pWidth, LONG *pHeight)
657 struct video_window *This = impl_from_IVideoWindow(iface);
659 FIXME("(%p/%p)->(%p, %p, %p, %p): stub !!!\n", This, iface, pLeft, pTop, pWidth, pHeight);
661 return S_OK;
664 HRESULT WINAPI BaseControlWindowImpl_HideCursor(IVideoWindow *iface, LONG HideCursor)
666 struct video_window *This = impl_from_IVideoWindow(iface);
668 FIXME("(%p/%p)->(%d): stub !!!\n", This, iface, HideCursor);
670 return S_OK;
673 HRESULT WINAPI BaseControlWindowImpl_IsCursorHidden(IVideoWindow *iface, LONG *CursorHidden)
675 struct video_window *This = impl_from_IVideoWindow(iface);
677 FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, CursorHidden);
679 return S_OK;
682 static inline struct video_window *impl_from_IBasicVideo(IBasicVideo *iface)
684 return CONTAINING_RECORD(iface, struct video_window, IBasicVideo_iface);
687 static HRESULT WINAPI basic_video_QueryInterface(IBasicVideo *iface, REFIID iid, void **out)
689 struct video_window *window = impl_from_IBasicVideo(iface);
690 return IUnknown_QueryInterface(window->pFilter->outer_unk, iid, out);
693 static ULONG WINAPI basic_video_AddRef(IBasicVideo *iface)
695 struct video_window *window = impl_from_IBasicVideo(iface);
696 return IUnknown_AddRef(window->pFilter->outer_unk);
699 static ULONG WINAPI basic_video_Release(IBasicVideo *iface)
701 struct video_window *window = impl_from_IBasicVideo(iface);
702 return IUnknown_Release(window->pFilter->outer_unk);
705 static HRESULT WINAPI basic_video_GetTypeInfoCount(IBasicVideo *iface, UINT *count)
707 TRACE("iface %p, count %p.\n", iface, count);
708 *count = 1;
709 return S_OK;
712 static HRESULT WINAPI basic_video_GetTypeInfo(IBasicVideo *iface, UINT index,
713 LCID lcid, ITypeInfo **typeinfo)
715 TRACE("iface %p, index %u, lcid %#x, typeinfo %p.\n", iface, index, lcid, typeinfo);
716 return strmbase_get_typeinfo(IBasicVideo_tid, typeinfo);
719 static HRESULT WINAPI basic_video_GetIDsOfNames(IBasicVideo *iface, REFIID iid,
720 LPOLESTR *names, UINT count, LCID lcid, DISPID *ids)
722 ITypeInfo *typeinfo;
723 HRESULT hr;
725 TRACE("iface %p, iid %s, names %p, count %u, lcid %#x, ids %p.\n",
726 iface, debugstr_guid(iid), names, count, lcid, ids);
728 if (SUCCEEDED(hr = strmbase_get_typeinfo(IBasicVideo_tid, &typeinfo)))
730 hr = ITypeInfo_GetIDsOfNames(typeinfo, names, count, ids);
731 ITypeInfo_Release(typeinfo);
733 return hr;
736 static HRESULT WINAPI basic_video_Invoke(IBasicVideo *iface, DISPID id, REFIID iid, LCID lcid,
737 WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *error_arg)
739 ITypeInfo *typeinfo;
740 HRESULT hr;
742 TRACE("iface %p, id %d, iid %s, lcid %#x, flags %#x, params %p, result %p, excepinfo %p, error_arg %p.\n",
743 iface, id, debugstr_guid(iid), lcid, flags, params, result, excepinfo, error_arg);
745 if (SUCCEEDED(hr = strmbase_get_typeinfo(IBasicVideo_tid, &typeinfo)))
747 hr = ITypeInfo_Invoke(typeinfo, iface, id, flags, params, result, excepinfo, error_arg);
748 ITypeInfo_Release(typeinfo);
750 return hr;
753 static const VIDEOINFOHEADER *get_video_format(struct video_window *window)
755 /* Members of VIDEOINFOHEADER up to bmiHeader are identical to those of
756 * VIDEOINFOHEADER2. */
757 return (const VIDEOINFOHEADER *)window->pPin->mt.pbFormat;
760 static const BITMAPINFOHEADER *get_bitmap_header(struct video_window *window)
762 const AM_MEDIA_TYPE *mt = &window->pPin->mt;
763 if (IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo))
764 return &((VIDEOINFOHEADER *)mt->pbFormat)->bmiHeader;
765 else
766 return &((VIDEOINFOHEADER2 *)mt->pbFormat)->bmiHeader;
769 static HRESULT WINAPI basic_video_get_AvgTimePerFrame(IBasicVideo *iface, REFTIME *reftime)
771 struct video_window *window = impl_from_IBasicVideo(iface);
773 if (!reftime)
774 return E_POINTER;
775 if (!window->pPin->peer)
776 return VFW_E_NOT_CONNECTED;
778 TRACE("window %p, reftime %p.\n", window, reftime);
780 *reftime = (double)get_video_format(window)->AvgTimePerFrame / 1e7;
781 return S_OK;
784 static HRESULT WINAPI basic_video_get_BitRate(IBasicVideo *iface, LONG *rate)
786 struct video_window *window = impl_from_IBasicVideo(iface);
788 TRACE("window %p, rate %p.\n", window, rate);
790 if (!rate)
791 return E_POINTER;
792 if (!window->pPin->peer)
793 return VFW_E_NOT_CONNECTED;
795 *rate = get_video_format(window)->dwBitRate;
796 return S_OK;
799 static HRESULT WINAPI basic_video_get_BitErrorRate(IBasicVideo *iface, LONG *rate)
801 struct video_window *window = impl_from_IBasicVideo(iface);
803 TRACE("window %p, rate %p.\n", window, rate);
805 if (!rate)
806 return E_POINTER;
807 if (!window->pPin->peer)
808 return VFW_E_NOT_CONNECTED;
810 *rate = get_video_format(window)->dwBitErrorRate;
811 return S_OK;
814 static HRESULT WINAPI basic_video_get_VideoWidth(IBasicVideo *iface, LONG *width)
816 struct video_window *window = impl_from_IBasicVideo(iface);
818 TRACE("window %p, width %p.\n", window, width);
820 if (!width)
821 return E_POINTER;
823 *width = get_bitmap_header(window)->biWidth;
825 return S_OK;
828 static HRESULT WINAPI basic_video_get_VideoHeight(IBasicVideo *iface, LONG *height)
830 struct video_window *window = impl_from_IBasicVideo(iface);
832 TRACE("window %p, height %p.\n", window, height);
834 if (!height)
835 return E_POINTER;
837 *height = abs(get_bitmap_header(window)->biHeight);
839 return S_OK;
842 static HRESULT WINAPI basic_video_put_SourceLeft(IBasicVideo *iface, LONG left)
844 struct video_window *window = impl_from_IBasicVideo(iface);
846 TRACE("window %p, left %d.\n", window, left);
848 if (left < 0 || window->src.right + left - window->src.left > get_bitmap_header(window)->biWidth)
849 return E_INVALIDARG;
851 OffsetRect(&window->src, left - window->src.left, 0);
852 return S_OK;
855 static HRESULT WINAPI basic_video_get_SourceLeft(IBasicVideo *iface, LONG *left)
857 struct video_window *window = impl_from_IBasicVideo(iface);
859 TRACE("window %p, left %p.\n", window, left);
861 if (!left)
862 return E_POINTER;
864 *left = window->src.left;
865 return S_OK;
868 static HRESULT WINAPI basic_video_put_SourceWidth(IBasicVideo *iface, LONG width)
870 struct video_window *window = impl_from_IBasicVideo(iface);
872 TRACE("window %p, width %d.\n", window, width);
874 if (width <= 0 || window->src.left + width > get_bitmap_header(window)->biWidth)
875 return E_INVALIDARG;
877 window->src.right = window->src.left + width;
878 return S_OK;
881 static HRESULT WINAPI basic_video_get_SourceWidth(IBasicVideo *iface, LONG *width)
883 struct video_window *window = impl_from_IBasicVideo(iface);
885 TRACE("window %p, width %p.\n", window, width);
887 if (!width)
888 return E_POINTER;
890 *width = window->src.right - window->src.left;
891 return S_OK;
894 static HRESULT WINAPI basic_video_put_SourceTop(IBasicVideo *iface, LONG top)
896 struct video_window *window = impl_from_IBasicVideo(iface);
898 TRACE("window %p, top %d.\n", window, top);
900 if (top < 0 || window->src.bottom + top - window->src.top > get_bitmap_header(window)->biHeight)
901 return E_INVALIDARG;
903 OffsetRect(&window->src, 0, top - window->src.top);
904 return S_OK;
907 static HRESULT WINAPI basic_video_get_SourceTop(IBasicVideo *iface, LONG *top)
909 struct video_window *window = impl_from_IBasicVideo(iface);
911 TRACE("window %p, top %p.\n", window, top);
913 if (!top)
914 return E_POINTER;
916 *top = window->src.top;
917 return S_OK;
920 static HRESULT WINAPI basic_video_put_SourceHeight(IBasicVideo *iface, LONG height)
922 struct video_window *window = impl_from_IBasicVideo(iface);
924 TRACE("window %p, height %d.\n", window, height);
926 if (height <= 0 || window->src.top + height > get_bitmap_header(window)->biHeight)
927 return E_INVALIDARG;
929 window->src.bottom = window->src.top + height;
930 return S_OK;
933 static HRESULT WINAPI basic_video_get_SourceHeight(IBasicVideo *iface, LONG *height)
935 struct video_window *window = impl_from_IBasicVideo(iface);
937 TRACE("window %p, height %p\n", window, height);
939 if (!height)
940 return E_POINTER;
942 *height = window->src.bottom - window->src.top;
943 return S_OK;
946 static HRESULT WINAPI basic_video_put_DestinationLeft(IBasicVideo *iface, LONG left)
948 struct video_window *window = impl_from_IBasicVideo(iface);
950 TRACE("window %p, left %d.\n", window, left);
952 window->default_dst = FALSE;
953 OffsetRect(&window->dst, left - window->dst.left, 0);
954 return S_OK;
957 static HRESULT WINAPI basic_video_get_DestinationLeft(IBasicVideo *iface, LONG *left)
959 struct video_window *window = impl_from_IBasicVideo(iface);
961 TRACE("window %p, left %p.\n", window, left);
963 if (!left)
964 return E_POINTER;
966 *left = window->dst.left;
967 return S_OK;
970 static HRESULT WINAPI basic_video_put_DestinationWidth(IBasicVideo *iface, LONG width)
972 struct video_window *window = impl_from_IBasicVideo(iface);
974 TRACE("window %p, width %d.\n", window, width);
976 if (width <= 0)
977 return E_INVALIDARG;
979 window->default_dst = FALSE;
980 window->dst.right = window->dst.left + width;
981 return S_OK;
984 static HRESULT WINAPI basic_video_get_DestinationWidth(IBasicVideo *iface, LONG *width)
986 struct video_window *window = impl_from_IBasicVideo(iface);
988 TRACE("window %p, width %p.\n", window, width);
990 if (!width)
991 return E_POINTER;
993 *width = window->dst.right - window->dst.left;
994 return S_OK;
997 static HRESULT WINAPI basic_video_put_DestinationTop(IBasicVideo *iface, LONG top)
999 struct video_window *window = impl_from_IBasicVideo(iface);
1001 TRACE("window %p, top %d.\n", window, top);
1003 window->default_dst = FALSE;
1004 OffsetRect(&window->dst, 0, top - window->dst.top);
1005 return S_OK;
1008 static HRESULT WINAPI basic_video_get_DestinationTop(IBasicVideo *iface, LONG *top)
1010 struct video_window *window = impl_from_IBasicVideo(iface);
1012 TRACE("window %p, top %p.\n", window, top);
1014 if (!top)
1015 return E_POINTER;
1017 *top = window->dst.top;
1018 return S_OK;
1021 static HRESULT WINAPI basic_video_put_DestinationHeight(IBasicVideo *iface, LONG height)
1023 struct video_window *window = impl_from_IBasicVideo(iface);
1025 TRACE("window %p, height %d.\n", window, height);
1027 if (height <= 0)
1028 return E_INVALIDARG;
1030 window->default_dst = FALSE;
1031 window->dst.bottom = window->dst.top + height;
1032 return S_OK;
1035 static HRESULT WINAPI basic_video_get_DestinationHeight(IBasicVideo *iface, LONG *height)
1037 struct video_window *window = impl_from_IBasicVideo(iface);
1039 TRACE("window %p, height %p.\n", window, height);
1041 if (!height)
1042 return E_POINTER;
1044 *height = window->dst.bottom - window->dst.top;
1045 return S_OK;
1048 static HRESULT WINAPI basic_video_SetSourcePosition(IBasicVideo *iface,
1049 LONG left, LONG top, LONG width, LONG height)
1051 struct video_window *window = impl_from_IBasicVideo(iface);
1052 const BITMAPINFOHEADER *bitmap_header = get_bitmap_header(window);
1054 TRACE("window %p, left %d, top %d, width %d, height %d.\n", window, left, top, width, height);
1056 if (left < 0 || left + width > bitmap_header->biWidth || width <= 0)
1057 return E_INVALIDARG;
1058 if (top < 0 || top + height > bitmap_header->biHeight || height <= 0)
1059 return E_INVALIDARG;
1061 SetRect(&window->src, left, top, left + width, top + height);
1062 return S_OK;
1065 static HRESULT WINAPI basic_video_GetSourcePosition(IBasicVideo *iface,
1066 LONG *left, LONG *top, LONG *width, LONG *height)
1068 struct video_window *window = impl_from_IBasicVideo(iface);
1070 TRACE("window %p, left %p, top %p, width %p, height %p.\n", window, left, top, width, height);
1072 if (!left || !top || !width || !height)
1073 return E_POINTER;
1075 *left = window->src.left;
1076 *top = window->src.top;
1077 *width = window->src.right - window->src.left;
1078 *height = window->src.bottom - window->src.top;
1079 return S_OK;
1082 static HRESULT WINAPI basic_video_SetDefaultSourcePosition(IBasicVideo *iface)
1084 struct video_window *window = impl_from_IBasicVideo(iface);
1085 const BITMAPINFOHEADER *bitmap_header = get_bitmap_header(window);
1087 TRACE("window %p.\n", window);
1089 SetRect(&window->src, 0, 0, bitmap_header->biWidth, bitmap_header->biHeight);
1090 return S_OK;
1093 static HRESULT WINAPI basic_video_SetDestinationPosition(IBasicVideo *iface,
1094 LONG left, LONG top, LONG width, LONG height)
1096 struct video_window *window = impl_from_IBasicVideo(iface);
1098 TRACE("window %p, left %d, top %d, width %d, height %d.\n", window, left, top, width, height);
1100 if (width <= 0 || height <= 0)
1101 return E_INVALIDARG;
1103 window->default_dst = FALSE;
1104 SetRect(&window->dst, left, top, left + width, top + height);
1105 return S_OK;
1108 static HRESULT WINAPI basic_video_GetDestinationPosition(IBasicVideo *iface,
1109 LONG *left, LONG *top, LONG *width, LONG *height)
1111 struct video_window *window = impl_from_IBasicVideo(iface);
1113 TRACE("window %p, left %p, top %p, width %p, height %p.\n", window, left, top, width, height);
1115 if (!left || !top || !width || !height)
1116 return E_POINTER;
1118 *left = window->dst.left;
1119 *top = window->dst.top;
1120 *width = window->dst.right - window->dst.left;
1121 *height = window->dst.bottom - window->dst.top;
1122 return S_OK;
1125 static HRESULT WINAPI basic_video_SetDefaultDestinationPosition(IBasicVideo *iface)
1127 struct video_window *window = impl_from_IBasicVideo(iface);
1129 TRACE("window %p.\n", window);
1131 window->default_dst = TRUE;
1132 GetClientRect(window->hwnd, &window->dst);
1133 return S_OK;
1136 static HRESULT WINAPI basic_video_GetVideoSize(IBasicVideo *iface, LONG *width, LONG *height)
1138 struct video_window *window = impl_from_IBasicVideo(iface);
1139 const BITMAPINFOHEADER *bitmap_header = get_bitmap_header(window);
1141 TRACE("window %p, width %p, height %p.\n", window, width, height);
1143 if (!width || !height)
1144 return E_POINTER;
1146 *width = bitmap_header->biWidth;
1147 *height = bitmap_header->biHeight;
1148 return S_OK;
1151 static HRESULT WINAPI basic_video_GetVideoPaletteEntries(IBasicVideo *iface,
1152 LONG start, LONG count, LONG *ret_count, LONG *palette)
1154 struct video_window *window = impl_from_IBasicVideo(iface);
1156 FIXME("window %p, start %d, count %d, ret_count %p, palette %p, stub!\n",
1157 window, start, count, ret_count, palette);
1159 if (!ret_count || !palette)
1160 return E_POINTER;
1162 *ret_count = 0;
1163 return VFW_E_NO_PALETTE_AVAILABLE;
1166 static HRESULT WINAPI basic_video_GetCurrentImage(IBasicVideo *iface, LONG *size, LONG *image)
1168 struct video_window *window = impl_from_IBasicVideo(iface);
1170 TRACE("window %p, size %p, image %p.\n", window, size, image);
1172 if (!size || !image)
1173 return E_POINTER;
1175 return window->ops->get_current_image(window, size, image);
1178 static HRESULT WINAPI basic_video_IsUsingDefaultSource(IBasicVideo *iface)
1180 struct video_window *window = impl_from_IBasicVideo(iface);
1181 const BITMAPINFOHEADER *bitmap_header = get_bitmap_header(window);
1183 TRACE("window %p.\n", window);
1185 if (!window->src.left && !window->src.top
1186 && window->src.right == bitmap_header->biWidth
1187 && window->src.bottom == bitmap_header->biHeight)
1188 return S_OK;
1189 return S_FALSE;
1192 static HRESULT WINAPI basic_video_IsUsingDefaultDestination(IBasicVideo *iface)
1194 struct video_window *window = impl_from_IBasicVideo(iface);
1196 TRACE("window %p.\n", window);
1198 return window->default_dst ? S_OK : S_FALSE;
1201 static const IBasicVideoVtbl basic_video_vtbl =
1203 basic_video_QueryInterface,
1204 basic_video_AddRef,
1205 basic_video_Release,
1206 basic_video_GetTypeInfoCount,
1207 basic_video_GetTypeInfo,
1208 basic_video_GetIDsOfNames,
1209 basic_video_Invoke,
1210 basic_video_get_AvgTimePerFrame,
1211 basic_video_get_BitRate,
1212 basic_video_get_BitErrorRate,
1213 basic_video_get_VideoWidth,
1214 basic_video_get_VideoHeight,
1215 basic_video_put_SourceLeft,
1216 basic_video_get_SourceLeft,
1217 basic_video_put_SourceWidth,
1218 basic_video_get_SourceWidth,
1219 basic_video_put_SourceTop,
1220 basic_video_get_SourceTop,
1221 basic_video_put_SourceHeight,
1222 basic_video_get_SourceHeight,
1223 basic_video_put_DestinationLeft,
1224 basic_video_get_DestinationLeft,
1225 basic_video_put_DestinationWidth,
1226 basic_video_get_DestinationWidth,
1227 basic_video_put_DestinationTop,
1228 basic_video_get_DestinationTop,
1229 basic_video_put_DestinationHeight,
1230 basic_video_get_DestinationHeight,
1231 basic_video_SetSourcePosition,
1232 basic_video_GetSourcePosition,
1233 basic_video_SetDefaultSourcePosition,
1234 basic_video_SetDestinationPosition,
1235 basic_video_GetDestinationPosition,
1236 basic_video_SetDefaultDestinationPosition,
1237 basic_video_GetVideoSize,
1238 basic_video_GetVideoPaletteEntries,
1239 basic_video_GetCurrentImage,
1240 basic_video_IsUsingDefaultSource,
1241 basic_video_IsUsingDefaultDestination
1244 void video_window_unregister_class(void)
1246 if (!UnregisterClassW(class_name, NULL) && GetLastError() != ERROR_CLASS_DOES_NOT_EXIST)
1247 ERR("Failed to unregister class, error %u.\n", GetLastError());
1250 void video_window_init(struct video_window *window, const IVideoWindowVtbl *vtbl,
1251 struct strmbase_filter *owner, struct strmbase_pin *pin, const struct video_window_ops *ops)
1253 memset(window, 0, sizeof(*window));
1254 window->ops = ops;
1255 window->IVideoWindow_iface.lpVtbl = vtbl;
1256 window->IBasicVideo_iface.lpVtbl = &basic_video_vtbl;
1257 window->default_dst = TRUE;
1258 window->AutoShow = OATRUE;
1259 window->pFilter = owner;
1260 window->pPin = pin;
1263 void video_window_cleanup(struct video_window *window)
1265 if (window->hwnd)
1267 /* Media Player Classic deadlocks if WM_PARENTNOTIFY is sent, so clear
1268 * the child style first. Just like Windows, we don't actually unparent
1269 * the window, to prevent extra focus events from being generated since
1270 * it would become top-level for a brief period before being destroyed. */
1271 SetWindowLongW(window->hwnd, GWL_STYLE, GetWindowLongW(window->hwnd, GWL_STYLE) & ~WS_CHILD);
1273 SendMessageW(window->hwnd, WM_QUARTZ_DESTROY, 0, 0);
1274 window->hwnd = NULL;