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("Failed to register class, error %lu.\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 %#lx, 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 %#lx, 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 %ld, iid %s, lcid %#lx, 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 %#lx.\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 %#lx.\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("window %p, AutoShow %ld.\n", This
, 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 %ld.\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("window %p, palette %ld, stub!\n", This
, 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 %ld.\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 %ld.\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 %ld.\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 %ld.\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 %ld.\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 %#Ix.\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("window %p, drain %#Ix.\n", This
, 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 TRACE("window %p, colour %#lx.\n", This
, 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 fullscreen
)
551 struct video_window
*window
= impl_from_IVideoWindow(iface
);
553 TRACE("window %p, fullscreen %ld.\n", window
, fullscreen
);
558 HRESULT WINAPI
BaseControlWindowImpl_SetWindowForeground(IVideoWindow
*iface
, LONG focus
)
560 struct video_window
*window
= impl_from_IVideoWindow(iface
);
561 UINT flags
= SWP_NOMOVE
| SWP_NOSIZE
;
563 TRACE("window %p, focus %ld.\n", window
, focus
);
565 if (focus
!= OAFALSE
&& focus
!= OATRUE
)
568 if (!window
->pPin
->peer
)
569 return VFW_E_NOT_CONNECTED
;
572 flags
|= SWP_NOACTIVATE
;
573 SetWindowPos(window
->hwnd
, HWND_TOP
, 0, 0, 0, 0, flags
);
578 HRESULT WINAPI
BaseControlWindowImpl_SetWindowPosition(IVideoWindow
*iface
,
579 LONG left
, LONG top
, LONG width
, LONG height
)
581 struct video_window
*window
= impl_from_IVideoWindow(iface
);
583 TRACE("window %p, left %ld, top %ld, width %ld, height %ld.\n", window
, left
, top
, width
, height
);
585 if (!SetWindowPos(window
->hwnd
, NULL
, left
, top
, width
, height
, SWP_NOACTIVATE
| SWP_NOZORDER
))
590 HRESULT WINAPI
BaseControlWindowImpl_GetWindowPosition(IVideoWindow
*iface
,
591 LONG
*left
, LONG
*top
, LONG
*width
, LONG
*height
)
593 struct video_window
*window
= impl_from_IVideoWindow(iface
);
596 TRACE("window %p, left %p, top %p, width %p, height %p.\n", window
, left
, top
, width
, height
);
598 GetWindowRect(window
->hwnd
, &rect
);
601 *width
= rect
.right
- rect
.left
;
602 *height
= rect
.bottom
- rect
.top
;
606 HRESULT WINAPI
BaseControlWindowImpl_NotifyOwnerMessage(IVideoWindow
*iface
,
607 OAHWND hwnd
, LONG message
, LONG_PTR wparam
, LONG_PTR lparam
)
609 struct video_window
*window
= impl_from_IVideoWindow(iface
);
611 TRACE("window %p, hwnd %#Ix, message %#lx, wparam %#Ix, lparam %#Ix.\n",
612 window
, hwnd
, message
, wparam
, lparam
);
614 /* That these messages are forwarded, and no others, is stated by the
615 * DirectX documentation, and supported by manual testing. */
619 case WM_DEVMODECHANGE
:
620 case WM_DISPLAYCHANGE
:
621 case WM_PALETTECHANGED
:
622 case WM_PALETTEISCHANGING
:
623 case WM_QUERYNEWPALETTE
:
624 case WM_SYSCOLORCHANGE
:
625 SendMessageW(window
->hwnd
, message
, wparam
, lparam
);
632 HRESULT WINAPI
BaseControlWindowImpl_GetMinIdealImageSize(IVideoWindow
*iface
, LONG
*width
, LONG
*height
)
634 struct video_window
*window
= impl_from_IVideoWindow(iface
);
637 TRACE("window %p, width %p, height %p.\n", window
, width
, height
);
639 rect
= window
->ops
->get_default_rect(window
);
640 *width
= rect
.right
- rect
.left
;
641 *height
= rect
.bottom
- rect
.top
;
645 HRESULT WINAPI
BaseControlWindowImpl_GetMaxIdealImageSize(IVideoWindow
*iface
, LONG
*width
, LONG
*height
)
647 struct video_window
*window
= impl_from_IVideoWindow(iface
);
650 TRACE("window %p, width %p, height %p.\n", window
, width
, height
);
652 rect
= window
->ops
->get_default_rect(window
);
653 *width
= rect
.right
- rect
.left
;
654 *height
= rect
.bottom
- rect
.top
;
658 HRESULT WINAPI
BaseControlWindowImpl_GetRestorePosition(IVideoWindow
*iface
, LONG
*pLeft
, LONG
*pTop
, LONG
*pWidth
, LONG
*pHeight
)
660 struct video_window
*This
= impl_from_IVideoWindow(iface
);
662 FIXME("(%p/%p)->(%p, %p, %p, %p): stub !!!\n", This
, iface
, pLeft
, pTop
, pWidth
, pHeight
);
667 HRESULT WINAPI
BaseControlWindowImpl_HideCursor(IVideoWindow
*iface
, LONG hide
)
669 struct video_window
*window
= impl_from_IVideoWindow(iface
);
671 FIXME("window %p, hide %ld, stub!\n", window
, hide
);
676 HRESULT WINAPI
BaseControlWindowImpl_IsCursorHidden(IVideoWindow
*iface
, LONG
*CursorHidden
)
678 struct video_window
*This
= impl_from_IVideoWindow(iface
);
680 FIXME("(%p/%p)->(%p): stub !!!\n", This
, iface
, CursorHidden
);
685 static inline struct video_window
*impl_from_IBasicVideo(IBasicVideo
*iface
)
687 return CONTAINING_RECORD(iface
, struct video_window
, IBasicVideo_iface
);
690 static HRESULT WINAPI
basic_video_QueryInterface(IBasicVideo
*iface
, REFIID iid
, void **out
)
692 struct video_window
*window
= impl_from_IBasicVideo(iface
);
693 return IUnknown_QueryInterface(window
->pFilter
->outer_unk
, iid
, out
);
696 static ULONG WINAPI
basic_video_AddRef(IBasicVideo
*iface
)
698 struct video_window
*window
= impl_from_IBasicVideo(iface
);
699 return IUnknown_AddRef(window
->pFilter
->outer_unk
);
702 static ULONG WINAPI
basic_video_Release(IBasicVideo
*iface
)
704 struct video_window
*window
= impl_from_IBasicVideo(iface
);
705 return IUnknown_Release(window
->pFilter
->outer_unk
);
708 static HRESULT WINAPI
basic_video_GetTypeInfoCount(IBasicVideo
*iface
, UINT
*count
)
710 TRACE("iface %p, count %p.\n", iface
, count
);
715 static HRESULT WINAPI
basic_video_GetTypeInfo(IBasicVideo
*iface
, UINT index
,
716 LCID lcid
, ITypeInfo
**typeinfo
)
718 TRACE("iface %p, index %u, lcid %#lx, typeinfo %p.\n", iface
, index
, lcid
, typeinfo
);
719 return strmbase_get_typeinfo(IBasicVideo_tid
, typeinfo
);
722 static HRESULT WINAPI
basic_video_GetIDsOfNames(IBasicVideo
*iface
, REFIID iid
,
723 LPOLESTR
*names
, UINT count
, LCID lcid
, DISPID
*ids
)
728 TRACE("iface %p, iid %s, names %p, count %u, lcid %#lx, ids %p.\n",
729 iface
, debugstr_guid(iid
), names
, count
, lcid
, ids
);
731 if (SUCCEEDED(hr
= strmbase_get_typeinfo(IBasicVideo_tid
, &typeinfo
)))
733 hr
= ITypeInfo_GetIDsOfNames(typeinfo
, names
, count
, ids
);
734 ITypeInfo_Release(typeinfo
);
739 static HRESULT WINAPI
basic_video_Invoke(IBasicVideo
*iface
, DISPID id
, REFIID iid
, LCID lcid
,
740 WORD flags
, DISPPARAMS
*params
, VARIANT
*result
, EXCEPINFO
*excepinfo
, UINT
*error_arg
)
745 TRACE("iface %p, id %ld, iid %s, lcid %#lx, flags %#x, params %p, result %p, excepinfo %p, error_arg %p.\n",
746 iface
, id
, debugstr_guid(iid
), lcid
, flags
, params
, result
, excepinfo
, error_arg
);
748 if (SUCCEEDED(hr
= strmbase_get_typeinfo(IBasicVideo_tid
, &typeinfo
)))
750 hr
= ITypeInfo_Invoke(typeinfo
, iface
, id
, flags
, params
, result
, excepinfo
, error_arg
);
751 ITypeInfo_Release(typeinfo
);
756 static const VIDEOINFOHEADER
*get_video_format(struct video_window
*window
)
758 /* Members of VIDEOINFOHEADER up to bmiHeader are identical to those of
759 * VIDEOINFOHEADER2. */
760 return (const VIDEOINFOHEADER
*)window
->pPin
->mt
.pbFormat
;
763 static const BITMAPINFOHEADER
*get_bitmap_header(struct video_window
*window
)
765 const AM_MEDIA_TYPE
*mt
= &window
->pPin
->mt
;
766 if (IsEqualGUID(&mt
->formattype
, &FORMAT_VideoInfo
))
767 return &((VIDEOINFOHEADER
*)mt
->pbFormat
)->bmiHeader
;
769 return &((VIDEOINFOHEADER2
*)mt
->pbFormat
)->bmiHeader
;
772 static HRESULT WINAPI
basic_video_get_AvgTimePerFrame(IBasicVideo
*iface
, REFTIME
*reftime
)
774 struct video_window
*window
= impl_from_IBasicVideo(iface
);
778 if (!window
->pPin
->peer
)
779 return VFW_E_NOT_CONNECTED
;
781 TRACE("window %p, reftime %p.\n", window
, reftime
);
783 *reftime
= (double)get_video_format(window
)->AvgTimePerFrame
/ 1e7
;
787 static HRESULT WINAPI
basic_video_get_BitRate(IBasicVideo
*iface
, LONG
*rate
)
789 struct video_window
*window
= impl_from_IBasicVideo(iface
);
791 TRACE("window %p, rate %p.\n", window
, rate
);
795 if (!window
->pPin
->peer
)
796 return VFW_E_NOT_CONNECTED
;
798 *rate
= get_video_format(window
)->dwBitRate
;
802 static HRESULT WINAPI
basic_video_get_BitErrorRate(IBasicVideo
*iface
, LONG
*rate
)
804 struct video_window
*window
= impl_from_IBasicVideo(iface
);
806 TRACE("window %p, rate %p.\n", window
, rate
);
810 if (!window
->pPin
->peer
)
811 return VFW_E_NOT_CONNECTED
;
813 *rate
= get_video_format(window
)->dwBitErrorRate
;
817 static HRESULT WINAPI
basic_video_get_VideoWidth(IBasicVideo
*iface
, LONG
*width
)
819 struct video_window
*window
= impl_from_IBasicVideo(iface
);
821 TRACE("window %p, width %p.\n", window
, width
);
826 *width
= get_bitmap_header(window
)->biWidth
;
831 static HRESULT WINAPI
basic_video_get_VideoHeight(IBasicVideo
*iface
, LONG
*height
)
833 struct video_window
*window
= impl_from_IBasicVideo(iface
);
835 TRACE("window %p, height %p.\n", window
, height
);
840 *height
= abs(get_bitmap_header(window
)->biHeight
);
845 static HRESULT WINAPI
basic_video_put_SourceLeft(IBasicVideo
*iface
, LONG left
)
847 struct video_window
*window
= impl_from_IBasicVideo(iface
);
849 TRACE("window %p, left %ld.\n", window
, left
);
851 if (left
< 0 || window
->src
.right
+ left
- window
->src
.left
> get_bitmap_header(window
)->biWidth
)
854 OffsetRect(&window
->src
, left
- window
->src
.left
, 0);
858 static HRESULT WINAPI
basic_video_get_SourceLeft(IBasicVideo
*iface
, LONG
*left
)
860 struct video_window
*window
= impl_from_IBasicVideo(iface
);
862 TRACE("window %p, left %p.\n", window
, left
);
867 *left
= window
->src
.left
;
871 static HRESULT WINAPI
basic_video_put_SourceWidth(IBasicVideo
*iface
, LONG width
)
873 struct video_window
*window
= impl_from_IBasicVideo(iface
);
875 TRACE("window %p, width %ld.\n", window
, width
);
877 if (width
<= 0 || window
->src
.left
+ width
> get_bitmap_header(window
)->biWidth
)
880 window
->src
.right
= window
->src
.left
+ width
;
884 static HRESULT WINAPI
basic_video_get_SourceWidth(IBasicVideo
*iface
, LONG
*width
)
886 struct video_window
*window
= impl_from_IBasicVideo(iface
);
888 TRACE("window %p, width %p.\n", window
, width
);
893 *width
= window
->src
.right
- window
->src
.left
;
897 static HRESULT WINAPI
basic_video_put_SourceTop(IBasicVideo
*iface
, LONG top
)
899 struct video_window
*window
= impl_from_IBasicVideo(iface
);
901 TRACE("window %p, top %ld.\n", window
, top
);
903 if (top
< 0 || window
->src
.bottom
+ top
- window
->src
.top
> get_bitmap_header(window
)->biHeight
)
906 OffsetRect(&window
->src
, 0, top
- window
->src
.top
);
910 static HRESULT WINAPI
basic_video_get_SourceTop(IBasicVideo
*iface
, LONG
*top
)
912 struct video_window
*window
= impl_from_IBasicVideo(iface
);
914 TRACE("window %p, top %p.\n", window
, top
);
919 *top
= window
->src
.top
;
923 static HRESULT WINAPI
basic_video_put_SourceHeight(IBasicVideo
*iface
, LONG height
)
925 struct video_window
*window
= impl_from_IBasicVideo(iface
);
927 TRACE("window %p, height %ld.\n", window
, height
);
929 if (height
<= 0 || window
->src
.top
+ height
> get_bitmap_header(window
)->biHeight
)
932 window
->src
.bottom
= window
->src
.top
+ height
;
936 static HRESULT WINAPI
basic_video_get_SourceHeight(IBasicVideo
*iface
, LONG
*height
)
938 struct video_window
*window
= impl_from_IBasicVideo(iface
);
940 TRACE("window %p, height %p\n", window
, height
);
945 *height
= window
->src
.bottom
- window
->src
.top
;
949 static HRESULT WINAPI
basic_video_put_DestinationLeft(IBasicVideo
*iface
, LONG left
)
951 struct video_window
*window
= impl_from_IBasicVideo(iface
);
953 TRACE("window %p, left %ld.\n", window
, left
);
955 window
->default_dst
= FALSE
;
956 OffsetRect(&window
->dst
, left
- window
->dst
.left
, 0);
960 static HRESULT WINAPI
basic_video_get_DestinationLeft(IBasicVideo
*iface
, LONG
*left
)
962 struct video_window
*window
= impl_from_IBasicVideo(iface
);
964 TRACE("window %p, left %p.\n", window
, left
);
969 *left
= window
->dst
.left
;
973 static HRESULT WINAPI
basic_video_put_DestinationWidth(IBasicVideo
*iface
, LONG width
)
975 struct video_window
*window
= impl_from_IBasicVideo(iface
);
977 TRACE("window %p, width %ld.\n", window
, width
);
982 window
->default_dst
= FALSE
;
983 window
->dst
.right
= window
->dst
.left
+ width
;
987 static HRESULT WINAPI
basic_video_get_DestinationWidth(IBasicVideo
*iface
, LONG
*width
)
989 struct video_window
*window
= impl_from_IBasicVideo(iface
);
991 TRACE("window %p, width %p.\n", window
, width
);
996 *width
= window
->dst
.right
- window
->dst
.left
;
1000 static HRESULT WINAPI
basic_video_put_DestinationTop(IBasicVideo
*iface
, LONG top
)
1002 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1004 TRACE("window %p, top %ld.\n", window
, top
);
1006 window
->default_dst
= FALSE
;
1007 OffsetRect(&window
->dst
, 0, top
- window
->dst
.top
);
1011 static HRESULT WINAPI
basic_video_get_DestinationTop(IBasicVideo
*iface
, LONG
*top
)
1013 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1015 TRACE("window %p, top %p.\n", window
, top
);
1020 *top
= window
->dst
.top
;
1024 static HRESULT WINAPI
basic_video_put_DestinationHeight(IBasicVideo
*iface
, LONG height
)
1026 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1028 TRACE("window %p, height %ld.\n", window
, height
);
1031 return E_INVALIDARG
;
1033 window
->default_dst
= FALSE
;
1034 window
->dst
.bottom
= window
->dst
.top
+ height
;
1038 static HRESULT WINAPI
basic_video_get_DestinationHeight(IBasicVideo
*iface
, LONG
*height
)
1040 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1042 TRACE("window %p, height %p.\n", window
, height
);
1047 *height
= window
->dst
.bottom
- window
->dst
.top
;
1051 static HRESULT WINAPI
basic_video_SetSourcePosition(IBasicVideo
*iface
,
1052 LONG left
, LONG top
, LONG width
, LONG height
)
1054 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1055 const BITMAPINFOHEADER
*bitmap_header
= get_bitmap_header(window
);
1057 TRACE("window %p, left %ld, top %ld, width %ld, height %ld.\n", window
, left
, top
, width
, height
);
1059 if (left
< 0 || left
+ width
> bitmap_header
->biWidth
|| width
<= 0)
1060 return E_INVALIDARG
;
1061 if (top
< 0 || top
+ height
> bitmap_header
->biHeight
|| height
<= 0)
1062 return E_INVALIDARG
;
1064 SetRect(&window
->src
, left
, top
, left
+ width
, top
+ height
);
1068 static HRESULT WINAPI
basic_video_GetSourcePosition(IBasicVideo
*iface
,
1069 LONG
*left
, LONG
*top
, LONG
*width
, LONG
*height
)
1071 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1073 TRACE("window %p, left %p, top %p, width %p, height %p.\n", window
, left
, top
, width
, height
);
1075 if (!left
|| !top
|| !width
|| !height
)
1078 *left
= window
->src
.left
;
1079 *top
= window
->src
.top
;
1080 *width
= window
->src
.right
- window
->src
.left
;
1081 *height
= window
->src
.bottom
- window
->src
.top
;
1085 static HRESULT WINAPI
basic_video_SetDefaultSourcePosition(IBasicVideo
*iface
)
1087 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1088 const BITMAPINFOHEADER
*bitmap_header
= get_bitmap_header(window
);
1090 TRACE("window %p.\n", window
);
1092 SetRect(&window
->src
, 0, 0, bitmap_header
->biWidth
, bitmap_header
->biHeight
);
1096 static HRESULT WINAPI
basic_video_SetDestinationPosition(IBasicVideo
*iface
,
1097 LONG left
, LONG top
, LONG width
, LONG height
)
1099 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1101 TRACE("window %p, left %ld, top %ld, width %ld, height %ld.\n", window
, left
, top
, width
, height
);
1103 if (width
<= 0 || height
<= 0)
1104 return E_INVALIDARG
;
1106 window
->default_dst
= FALSE
;
1107 SetRect(&window
->dst
, left
, top
, left
+ width
, top
+ height
);
1111 static HRESULT WINAPI
basic_video_GetDestinationPosition(IBasicVideo
*iface
,
1112 LONG
*left
, LONG
*top
, LONG
*width
, LONG
*height
)
1114 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1116 TRACE("window %p, left %p, top %p, width %p, height %p.\n", window
, left
, top
, width
, height
);
1118 if (!left
|| !top
|| !width
|| !height
)
1121 *left
= window
->dst
.left
;
1122 *top
= window
->dst
.top
;
1123 *width
= window
->dst
.right
- window
->dst
.left
;
1124 *height
= window
->dst
.bottom
- window
->dst
.top
;
1128 static HRESULT WINAPI
basic_video_SetDefaultDestinationPosition(IBasicVideo
*iface
)
1130 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1132 TRACE("window %p.\n", window
);
1134 window
->default_dst
= TRUE
;
1135 GetClientRect(window
->hwnd
, &window
->dst
);
1139 static HRESULT WINAPI
basic_video_GetVideoSize(IBasicVideo
*iface
, LONG
*width
, LONG
*height
)
1141 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1142 const BITMAPINFOHEADER
*bitmap_header
= get_bitmap_header(window
);
1144 TRACE("window %p, width %p, height %p.\n", window
, width
, height
);
1146 if (!width
|| !height
)
1149 *width
= bitmap_header
->biWidth
;
1150 *height
= bitmap_header
->biHeight
;
1154 static HRESULT WINAPI
basic_video_GetVideoPaletteEntries(IBasicVideo
*iface
,
1155 LONG start
, LONG count
, LONG
*ret_count
, LONG
*palette
)
1157 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1159 FIXME("window %p, start %ld, count %ld, ret_count %p, palette %p, stub!\n",
1160 window
, start
, count
, ret_count
, palette
);
1162 if (!ret_count
|| !palette
)
1166 return VFW_E_NO_PALETTE_AVAILABLE
;
1169 static HRESULT WINAPI
basic_video_GetCurrentImage(IBasicVideo
*iface
, LONG
*size
, LONG
*image
)
1171 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1173 TRACE("window %p, size %p, image %p.\n", window
, size
, image
);
1175 if (!size
|| !image
)
1178 return window
->ops
->get_current_image(window
, size
, image
);
1181 static HRESULT WINAPI
basic_video_IsUsingDefaultSource(IBasicVideo
*iface
)
1183 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1184 const BITMAPINFOHEADER
*bitmap_header
= get_bitmap_header(window
);
1186 TRACE("window %p.\n", window
);
1188 if (!window
->src
.left
&& !window
->src
.top
1189 && window
->src
.right
== bitmap_header
->biWidth
1190 && window
->src
.bottom
== bitmap_header
->biHeight
)
1195 static HRESULT WINAPI
basic_video_IsUsingDefaultDestination(IBasicVideo
*iface
)
1197 struct video_window
*window
= impl_from_IBasicVideo(iface
);
1199 TRACE("window %p.\n", window
);
1201 return window
->default_dst
? S_OK
: S_FALSE
;
1204 static const IBasicVideoVtbl basic_video_vtbl
=
1206 basic_video_QueryInterface
,
1208 basic_video_Release
,
1209 basic_video_GetTypeInfoCount
,
1210 basic_video_GetTypeInfo
,
1211 basic_video_GetIDsOfNames
,
1213 basic_video_get_AvgTimePerFrame
,
1214 basic_video_get_BitRate
,
1215 basic_video_get_BitErrorRate
,
1216 basic_video_get_VideoWidth
,
1217 basic_video_get_VideoHeight
,
1218 basic_video_put_SourceLeft
,
1219 basic_video_get_SourceLeft
,
1220 basic_video_put_SourceWidth
,
1221 basic_video_get_SourceWidth
,
1222 basic_video_put_SourceTop
,
1223 basic_video_get_SourceTop
,
1224 basic_video_put_SourceHeight
,
1225 basic_video_get_SourceHeight
,
1226 basic_video_put_DestinationLeft
,
1227 basic_video_get_DestinationLeft
,
1228 basic_video_put_DestinationWidth
,
1229 basic_video_get_DestinationWidth
,
1230 basic_video_put_DestinationTop
,
1231 basic_video_get_DestinationTop
,
1232 basic_video_put_DestinationHeight
,
1233 basic_video_get_DestinationHeight
,
1234 basic_video_SetSourcePosition
,
1235 basic_video_GetSourcePosition
,
1236 basic_video_SetDefaultSourcePosition
,
1237 basic_video_SetDestinationPosition
,
1238 basic_video_GetDestinationPosition
,
1239 basic_video_SetDefaultDestinationPosition
,
1240 basic_video_GetVideoSize
,
1241 basic_video_GetVideoPaletteEntries
,
1242 basic_video_GetCurrentImage
,
1243 basic_video_IsUsingDefaultSource
,
1244 basic_video_IsUsingDefaultDestination
1247 void video_window_unregister_class(void)
1249 if (!UnregisterClassW(class_name
, NULL
) && GetLastError() != ERROR_CLASS_DOES_NOT_EXIST
)
1250 ERR("Failed to unregister class, error %lu.\n", GetLastError());
1253 void video_window_init(struct video_window
*window
, const IVideoWindowVtbl
*vtbl
,
1254 struct strmbase_filter
*owner
, struct strmbase_pin
*pin
, const struct video_window_ops
*ops
)
1256 memset(window
, 0, sizeof(*window
));
1258 window
->IVideoWindow_iface
.lpVtbl
= vtbl
;
1259 window
->IBasicVideo_iface
.lpVtbl
= &basic_video_vtbl
;
1260 window
->default_dst
= TRUE
;
1261 window
->AutoShow
= OATRUE
;
1262 window
->pFilter
= owner
;
1266 void video_window_cleanup(struct video_window
*window
)
1270 /* Media Player Classic deadlocks if WM_PARENTNOTIFY is sent, so clear
1271 * the child style first. Just like Windows, we don't actually unparent
1272 * the window, to prevent extra focus events from being generated since
1273 * it would become top-level for a brief period before being destroyed. */
1274 SetWindowLongW(window
->hwnd
, GWL_STYLE
, GetWindowLongW(window
->hwnd
, GWL_STYLE
) & ~WS_CHILD
);
1276 SendMessageW(window
->hwnd
, WM_QUARTZ_DESTROY
, 0, 0);
1277 window
->hwnd
= NULL
;