]> git.sesse.net Git - casparcg/blob - modules/flash/producer/FlashAxContainer.h
set svn:eol-style native on .h and .cpp files
[casparcg] / modules / flash / producer / FlashAxContainer.h
1 /*
2 * Copyright (c) 2011 Sveriges Television AB <info@casparcg.com>
3 *
4 * This file is part of CasparCG (www.casparcg.com).
5 *
6 * CasparCG is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * CasparCG 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
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Author: Nicklas P Andersson
20 */
21  
22 #ifndef _FLASHAXCONTAINER_H__
23 #define _FLASHAXCONTAINER_H__
24
25 #pragma once
26
27 #include <atlbase.h>
28 #include <atlcom.h>
29 #include <atlhost.h>
30 #include <ocmm.h>
31
32 #include <functional>
33 #include <vector>
34
35 #include <core/video_format.h>
36 #include "../interop/axflash.h"
37 //#import "progid:ShockwaveFlash.ShockwaveFlash.9" no_namespace, named_guids
38
39 #include <comdef.h>
40
41 #include "../interop/TimerHelper.h"
42
43 #include <InitGuid.h>
44 #include <ddraw.h>
45
46 #ifndef DEFINE_GUID2
47 #define DEFINE_GUID2(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
48                 const GUID name \
49                                 = { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } }
50 #endif     
51
52 _COM_SMARTPTR_TYPEDEF(IDirectDraw4, IID_IDirectDraw4);
53
54 namespace caspar {
55
56 namespace flash {
57
58 class TimerHelper;
59 struct DirtyRect {
60         DirtyRect(LONG l, LONG t, LONG r, LONG b, bool e) : bErase(e), bWhole(false) { 
61                 rect.left = l;
62                 rect.top = t;
63                 rect.right = r;
64                 rect.bottom = b; 
65         }
66         DirtyRect(const RECT& rc, bool e) : bErase(e), bWhole(false)  {
67                 rect.left = rc.left;
68                 rect.top = rc.top;
69                 rect.right = rc.right;
70                 rect.bottom = rc.bottom; 
71         }
72         explicit DirtyRect(bool b) : bWhole(b) {}
73
74         RECT    rect;
75         bool    bErase;
76         bool    bWhole;
77 };
78
79 extern _ATL_FUNC_INFO fnInfoFlashCallEvent;
80 extern _ATL_FUNC_INFO fnInfoReadyStateChangeEvent;
81
82 class ATL_NO_VTABLE FlashAxContainer : 
83                 public ATL::CComCoClass<FlashAxContainer , &CLSID_NULL>,
84                 public ATL::CComObjectRootEx<ATL::CComMultiThreadModel>,
85                 public IOleClientSite,
86                 public IOleContainer,
87                 public IOleControlSite,
88                 public IOleInPlaceSiteWindowless,
89                 public IObjectWithSiteImpl<FlashAxContainer>,
90                 public IServiceProvider,
91                 public IAdviseSink,
92                 public ITimerService,
93                 public ITimer,
94                 public IDispatchImpl<IDispatch>,
95                 public IDispEventSimpleImpl<0, FlashAxContainer, &DIID__IShockwaveFlashEvents>
96 {
97
98 public:
99
100         FlashAxContainer();
101         virtual ~FlashAxContainer();
102
103         DECLARE_NO_REGISTRY()
104         DECLARE_POLY_AGGREGATABLE(FlashAxContainer)
105         DECLARE_GET_CONTROLLING_UNKNOWN()
106
107         BEGIN_COM_MAP(FlashAxContainer)
108                 COM_INTERFACE_ENTRY(IDispatch)
109                 COM_INTERFACE_ENTRY(IOleClientSite)
110                 COM_INTERFACE_ENTRY(IObjectWithSite)
111                 COM_INTERFACE_ENTRY(IOleControlSite)
112                 COM_INTERFACE_ENTRY(IOleContainer)
113
114                 COM_INTERFACE_ENTRY(IOleInPlaceSiteWindowless)
115                 COM_INTERFACE_ENTRY(IOleInPlaceSiteEx)
116                 COM_INTERFACE_ENTRY(IOleInPlaceSite)
117                 COM_INTERFACE_ENTRY(IOleWindow)
118
119                 COM_INTERFACE_ENTRY(IServiceProvider)
120
121                 COM_INTERFACE_ENTRY(IAdviseSink)
122
123                 COM_INTERFACE_ENTRY(ITimerService)
124
125                 COM_INTERFACE_ENTRY(ITimer)
126         END_COM_MAP()
127
128         BEGIN_SINK_MAP(FlashAxContainer)
129                 SINK_ENTRY_INFO(0, DIID__IShockwaveFlashEvents, 0xc5, OnFlashCall, &fnInfoFlashCallEvent)
130                 SINK_ENTRY_INFO(0, DIID__IShockwaveFlashEvents, 0xfffffd9f, OnReadyStateChange, &fnInfoReadyStateChangeEvent)
131         END_SINK_MAP()
132
133         void STDMETHODCALLTYPE OnFlashCall(BSTR request);
134         void STDMETHODCALLTYPE OnReadyStateChange(long newState);
135
136 // IObjectWithSite
137         STDMETHOD(SetSite)(IUnknown* pUnkSite);
138
139 // IOleClientSite
140         STDMETHOD(SaveObject)();
141         STDMETHOD(GetMoniker)(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker** ppmk);
142         STDMETHOD(GetContainer)(IOleContainer** ppContainer);
143         STDMETHOD(ShowObject)();
144         STDMETHOD(OnShowWindow)(BOOL fShow);
145         STDMETHOD(RequestNewObjectLayout)();
146
147 // IOleInPlaceSite
148         STDMETHOD(GetWindow)(HWND* pHwnd);
149         STDMETHOD(ContextSensitiveHelp)(BOOL fEnterMode);
150         STDMETHOD(CanInPlaceActivate)();
151         STDMETHOD(OnInPlaceActivate)();
152         STDMETHOD(OnInPlaceDeactivate)();
153         STDMETHOD(OnUIActivate)();
154         STDMETHOD(OnUIDeactivate)(BOOL fUndoable);
155         STDMETHOD(GetWindowContext)(IOleInPlaceFrame** ppFrame, IOleInPlaceUIWindow** ppDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO pFrameInfo);
156         STDMETHOD(Scroll)(SIZE scrollExtant);
157         STDMETHOD(DiscardUndoState)();
158         STDMETHOD(DeactivateAndUndo)();
159         STDMETHOD(OnPosRectChange)(LPCRECT lprcPosRect);
160
161 // IOleInPlaceSiteEx
162         STDMETHOD(OnInPlaceActivateEx)(BOOL* pfNoRedraw, DWORD dwFlags);
163         STDMETHOD(OnInPlaceDeactivateEx)(BOOL fNoRedraw);
164         STDMETHOD(RequestUIActivate)();
165
166 // IOleInPlaceSiteWindowless
167         STDMETHOD(CanWindowlessActivate)();
168         STDMETHOD(GetCapture)();
169         STDMETHOD(SetCapture)(BOOL fCapture);
170         STDMETHOD(GetFocus)();
171         STDMETHOD(SetFocus)(BOOL fGotFocus);
172         STDMETHOD(GetDC)(LPCRECT pRect, DWORD grfFlags, HDC* phDC);
173         STDMETHOD(ReleaseDC)(HDC hDC);
174         STDMETHOD(InvalidateRect)(LPCRECT pRect, BOOL fErase);
175         STDMETHOD(InvalidateRgn)(HRGN hRGN, BOOL fErase);
176         STDMETHOD(ScrollRect)(INT dx, INT dy, LPCRECT pRectScroll, LPCRECT pRectClip);
177         STDMETHOD(AdjustRect)(LPRECT prc);
178         STDMETHOD(OnDefWindowMessage)(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT* plResult);
179
180 // IOleControlSite
181         STDMETHOD(OnControlInfoChanged)();
182         STDMETHOD(LockInPlaceActive)(BOOL fLock);
183         STDMETHOD(GetExtendedControl)(IDispatch** ppDisp);
184         STDMETHOD(TransformCoords)(POINTL* pPtlHimetric, POINTF* pPtfContainer, DWORD dwFlags);
185         STDMETHOD(TranslateAccelerator)(LPMSG lpMsg, DWORD grfModifiers);
186         STDMETHOD(OnFocus)(BOOL fGotFocus);
187         STDMETHOD(ShowPropertyFrame)();
188
189 // IAdviseSink
190         STDMETHOD_(void, OnDataChange)(FORMATETC* pFormatetc, STGMEDIUM* pStgmed);
191         STDMETHOD_(void, OnViewChange)(DWORD dwAspect, LONG lindex);
192         STDMETHOD_(void, OnRename)(IMoniker* pmk);
193         STDMETHOD_(void, OnSave)();
194         STDMETHOD_(void, OnClose)();
195
196 // IServiceProvider
197         STDMETHOD(QueryService)( REFGUID rsid, REFIID riid, void** ppvObj);
198
199 // IOleContainer
200         STDMETHOD(ParseDisplayName)(IBindCtx*, LPOLESTR, ULONG*, IMoniker**)
201         {
202                 ATLTRACENOTIMPL(_T("IOleContainer::ParseDisplayName"));
203         }
204         STDMETHOD(EnumObjects)(DWORD, IEnumUnknown** ppenum)
205         {
206                 if (ppenum == NULL)
207                         return E_POINTER;
208                 *ppenum = NULL;
209                 typedef CComObject<CComEnum<IEnumUnknown, &__uuidof(IEnumUnknown), IUnknown*, _CopyInterface<IUnknown> > > enumunk;
210                 enumunk* p = NULL;
211                 ATLTRY(p = new enumunk);
212                 if(p == NULL)
213                         return E_OUTOFMEMORY;
214                 IUnknown* pTemp = m_spUnknown;
215                 // There is always only one object.
216                 HRESULT hRes = p->Init(reinterpret_cast<IUnknown**>(&pTemp), reinterpret_cast<IUnknown**>(&pTemp + 1), GetControllingUnknown(), AtlFlagCopy);
217                 if (SUCCEEDED(hRes))
218                         hRes = p->QueryInterface(__uuidof(IEnumUnknown), (void**)ppenum);
219                 if (FAILED(hRes))
220                         delete p;
221                 return hRes;
222         }
223         STDMETHOD(LockContainer)(BOOL)
224         {
225                 ATLTRACENOTIMPL(_T("IOleContainer::LockContainer"));
226         }
227
228 //ITimerService
229         STDMETHOD(CreateTimer)(ITimer *pReferenceTimer, ITimer **ppNewTimer);
230         STDMETHOD(GetNamedTimer)(REFGUID rguidName, ITimer **ppTimer);
231         STDMETHOD(SetNamedTimerReference)(REFGUID rguidName, ITimer *pReferenceTimer);
232
233 //ITimer
234         STDMETHOD(Advise)(VARIANT vtimeMin, VARIANT vtimeMax, VARIANT vtimeInterval, DWORD dwFlags, ITimerSink *pTimerSink, DWORD *pdwCookie);
235         STDMETHOD(Unadvise)(DWORD dwCookie);
236         STDMETHOD(Freeze)(BOOL fFreeze);
237         STDMETHOD(GetTime)(VARIANT *pvtime);
238         double GetFPS();
239
240         void set_print(const std::function<std::wstring()>& print) { print_ = print;}
241
242         HRESULT CreateAxControl();
243         void DestroyAxControl();
244         HRESULT QueryControl(REFIID iid, void** ppUnk);
245
246         template <class Q>
247         HRESULT QueryControl(Q** ppUnk)
248         {
249                 return QueryControl(__uuidof(Q), (void**)ppUnk);
250         }
251
252 //      static ATL::CComObject<FlashAxContainer>* CreateInstance();
253
254         void Tick();
255         bool FlashCall(const std::wstring& str, std::wstring& result);
256         bool DrawControl(HDC targetDC);
257         bool InvalidRect() const { return bInvalidRect_; } 
258         bool IsEmpty() const { return bIsEmpty_; }
259
260         void SetSize(size_t width, size_t height);
261         bool IsReadyToRender() const;
262         void EnterFullscreen();
263
264         static bool CheckForFlashSupport();
265
266         ATL::CComPtr<IOleInPlaceObjectWindowless> m_spInPlaceObjectWindowless;
267
268 private:
269         std::function<std::wstring()> print_;
270         TimerHelper* pTimerHelper;
271         volatile bool bInvalidRect_;
272         volatile bool bCallSuccessful_;
273         volatile bool bReadyToRender_;
274         volatile bool bIsEmpty_;
275         volatile bool bHasNewTiming_;
276         std::vector<DirtyRect> bDirtyRects_;
277
278
279         IDirectDraw4Ptr *m_lpDD4;
280         static CComBSTR flashGUID_;
281
282         DWORD timerCount_;
283
284 //      state
285         bool            bUIActive_;
286         bool            bInPlaceActive_;
287         unsigned long           bHaveFocus_ : 1;
288         unsigned long           bCapture_ : 1;
289
290         DWORD m_dwOleObject;
291         DWORD m_dwMiscStatus;
292         SIZEL m_hmSize;
293         SIZEL m_pxSize;
294         RECT m_rcPos;
295
296         ATL::CComPtr<IUnknown> m_spUnknown;
297         ATL::CComPtr<IOleObject> m_spServices;
298         ATL::CComPtr<IOleObject> m_spOleObject;
299         ATL::CComPtr<IViewObjectEx> m_spViewObject;
300
301 //      ATL::CComPtr<ATL::CComObject<MyMoniker> > m_spMyMoniker;
302 };
303
304 }       //namespace flash
305 }       //namespace caspar
306
307 #endif  //_FLASHAXCONTAINER_H__