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);
39 return DefWindowProcW(hwnd
, message
, wparam
, lparam
);
45 case WM_LBUTTONDBLCLK
:
48 case WM_MBUTTONDBLCLK
:
51 case WM_MOUSEACTIVATE
:
53 case WM_NCLBUTTONDBLCLK
:
54 case WM_NCLBUTTONDOWN
:
56 case WM_NCMBUTTONDBLCLK
:
57 case WM_NCMBUTTONDOWN
:
60 case WM_NCRBUTTONDBLCLK
:
61 case WM_NCRBUTTONDOWN
:
63 case WM_RBUTTONDBLCLK
:
66 if (window
->hwndDrain
)
68 PostMessageW(window
->hwndDrain
, message
, wparam
, lparam
);
73 if (window
->default_dst
)
74 GetClientRect(window
->hwnd
, &window
->dst
);
76 case WM_QUARTZ_DESTROY
:
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
,
86 (void **)&event_sink
)))
88 IMediaEventSink_Notify(event_sink
, EC_USERABORT
, 0, 0);
89 IMediaEventSink_Release(event_sink
);
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());
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");
121 SetWindowLongPtrW(window
->hwnd
, 0, (LONG_PTR
)window
);
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
);
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
)
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
);
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
)
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
);
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
))
204 HRESULT WINAPI
BaseControlWindowImpl_get_Caption(IVideoWindow
*iface
, BSTR
*caption
)
206 struct video_window
*window
= impl_from_IVideoWindow(iface
);
210 TRACE("window %p, caption %p.\n", window
, caption
);
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
);
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
))
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
);
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
);
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
))
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
);
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
;
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
;
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
);
302 HRESULT WINAPI
BaseControlWindowImpl_get_WindowState(IVideoWindow
*iface
, LONG
*state
)
304 struct video_window
*window
= impl_from_IVideoWindow(iface
);
307 TRACE("window %p, state %p.\n", window
, state
);
309 style
= GetWindowLongPtrW(window
->hwnd
, GWL_STYLE
);
310 if (!(style
& WS_VISIBLE
))
312 else if (style
& WS_MINIMIZE
)
313 *state
= SW_MINIMIZE
;
314 else if (style
& WS_MAXIMIZE
)
315 *state
= SW_MAXIMIZE
;
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
);
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
);
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
);
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
);
359 *visible
= IsWindowVisible(window
->hwnd
) ? OATRUE
: OAFALSE
;
363 HRESULT WINAPI
BaseControlWindowImpl_put_Left(IVideoWindow
*iface
, LONG left
)
365 struct video_window
*window
= impl_from_IVideoWindow(iface
);
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
))
378 HRESULT WINAPI
BaseControlWindowImpl_get_Left(IVideoWindow
*iface
, LONG
*left
)
380 struct video_window
*window
= impl_from_IVideoWindow(iface
);
383 TRACE("window %p, left %p.\n", window
, left
);
385 GetWindowRect(window
->hwnd
, &rect
);
390 HRESULT WINAPI
BaseControlWindowImpl_put_Width(IVideoWindow
*iface
, LONG width
)
392 struct video_window
*window
= impl_from_IVideoWindow(iface
);
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
))
405 HRESULT WINAPI
BaseControlWindowImpl_get_Width(IVideoWindow
*iface
, LONG
*width
)
407 struct video_window
*window
= impl_from_IVideoWindow(iface
);
410 TRACE("window %p, width %p.\n", window
, width
);
412 GetWindowRect(window
->hwnd
, &rect
);
413 *width
= rect
.right
- rect
.left
;
417 HRESULT WINAPI
BaseControlWindowImpl_put_Top(IVideoWindow
*iface
, LONG top
)
419 struct video_window
*window
= impl_from_IVideoWindow(iface
);
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
))
432 HRESULT WINAPI
BaseControlWindowImpl_get_Top(IVideoWindow
*iface
, LONG
*top
)
434 struct video_window
*window
= impl_from_IVideoWindow(iface
);
437 TRACE("window %p, top %p.\n", window
, top
);
439 GetWindowRect(window
->hwnd
, &rect
);
444 HRESULT WINAPI
BaseControlWindowImpl_put_Height(IVideoWindow
*iface
, LONG height
)
446 struct video_window
*window
= impl_from_IVideoWindow(iface
);
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
))
459 HRESULT WINAPI
BaseControlWindowImpl_get_Height(IVideoWindow
*iface
, LONG
*height
)
461 struct video_window
*window
= impl_from_IVideoWindow(iface
);
464 TRACE("window %p, height %p.\n", window
, height
);
466 GetWindowRect(window
->hwnd
, &rect
);
467 *height
= rect
.bottom
- rect
.top
;
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
;
483 SetWindowLongPtrW(hwnd
, GWL_STYLE
, GetWindowLongPtrW(hwnd
, GWL_STYLE
) | WS_CHILD
);
485 SetWindowLongPtrW(hwnd
, GWL_STYLE
, GetWindowLongPtrW(hwnd
, GWL_STYLE
) & ~WS_CHILD
);
486 SetParent(hwnd
, (HWND
)owner
);
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
;
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
;
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
;
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
);
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
);
542 HRESULT WINAPI
BaseControlWindowImpl_get_FullScreenMode(IVideoWindow
*iface
, LONG
*FullScreenMode
)
544 TRACE("(%p)->(%p)\n", iface
, FullScreenMode
);
549 HRESULT WINAPI
BaseControlWindowImpl_put_FullScreenMode(IVideoWindow
*iface
, LONG FullScreenMode
)
551 TRACE("(%p)->(%d)\n", iface
, FullScreenMode
);
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
)
565 if (!window
->pPin
->peer
)
566 return VFW_E_NOT_CONNECTED
;
569 flags
|= SWP_NOACTIVATE
;
570 SetWindowPos(window
->hwnd
, HWND_TOP
, 0, 0, 0, 0, flags
);
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
))
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
);
593 TRACE("window %p, left %p, top %p, width %p, height %p.\n", window
, left
, top
, width
, height
);
595 GetWindowRect(window
->hwnd
, &rect
);
598 *width
= rect
.right
- rect
.left
;
599 *height
= rect
.bottom
- rect
.top
;
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. */
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
);
629 HRESULT WINAPI
BaseControlWindowImpl_GetMinIdealImageSize(IVideoWindow
*iface
, LONG
*width
, LONG
*height
)
631 struct video_window
*window
= impl_from_IVideoWindow(iface
);
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
;
642 HRESULT WINAPI
BaseControlWindowImpl_GetMaxIdealImageSize(IVideoWindow
*iface
, LONG
*width
, LONG
*height
)
644 struct video_window
*window
= impl_from_IVideoWindow(iface
);
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
;
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
);
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
);
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
);
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
);
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
)
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
);
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
)
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
);
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
;
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
);
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
;
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
);
792 if (!window
->pPin
->peer
)
793 return VFW_E_NOT_CONNECTED
;
795 *rate
= get_video_format(window
)->dwBitRate
;
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
);
807 if (!window
->pPin
->peer
)
808 return VFW_E_NOT_CONNECTED
;
810 *rate
= get_video_format(window
)->dwBitErrorRate
;
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
);
823 *width
= get_bitmap_header(window
)->biWidth
;
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
);
837 *height
= abs(get_bitmap_header(window
)->biHeight
);
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
)
851 OffsetRect(&window
->src
, left
- window
->src
.left
, 0);
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
);
864 *left
= window
->src
.left
;
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
)
877 window
->src
.right
= window
->src
.left
+ width
;
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
);
890 *width
= window
->src
.right
- window
->src
.left
;
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
)
903 OffsetRect(&window
->src
, 0, top
- window
->src
.top
);
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
);
916 *top
= window
->src
.top
;
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
)
929 window
->src
.bottom
= window
->src
.top
+ height
;
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
);
942 *height
= window
->src
.bottom
- window
->src
.top
;
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);
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
);
966 *left
= window
->dst
.left
;
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
);
979 window
->default_dst
= FALSE
;
980 window
->dst
.right
= window
->dst
.left
+ width
;
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
);
993 *width
= window
->dst
.right
- window
->dst
.left
;
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
);
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
);
1017 *top
= window
->dst
.top
;
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
);
1028 return E_INVALIDARG
;
1030 window
->default_dst
= FALSE
;
1031 window
->dst
.bottom
= window
->dst
.top
+ height
;
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
);
1044 *height
= window
->dst
.bottom
- window
->dst
.top
;
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
);
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
)
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
;
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
);
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
);
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
)
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
;
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
);
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
)
1146 *width
= bitmap_header
->biWidth
;
1147 *height
= bitmap_header
->biHeight
;
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
)
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
)
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
)
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
,
1205 basic_video_Release
,
1206 basic_video_GetTypeInfoCount
,
1207 basic_video_GetTypeInfo
,
1208 basic_video_GetIDsOfNames
,
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
));
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
;
1263 void video_window_cleanup(struct video_window
*window
)
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
;