1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_canvas.hxx"
26 
27 #include <ctype.h> // don't ask. msdev breaks otherwise...
28 #include <canvas/debug.hxx>
29 #include <canvas/verbosetrace.hxx>
30 #include <tools/diagnose_ex.h>
31 
32 #include <canvas/canvastools.hxx>
33 
34 #include <osl/mutex.hxx>
35 
36 #include <com/sun/star/registry/XRegistryKey.hpp>
37 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
38 #include <com/sun/star/uno/XComponentContext.hpp>
39 #include <com/sun/star/lang/NoSupportException.hpp>
40 
41 #include <toolkit/helper/vclunohelper.hxx>
42 #include <cppuhelper/factory.hxx>
43 #include <cppuhelper/implementationentry.hxx>
44 #include <comphelper/servicedecl.hxx>
45 
46 #include <basegfx/matrix/b2dhommatrix.hxx>
47 #include <basegfx/point/b2dpoint.hxx>
48 #include <basegfx/tools/canvastools.hxx>
49 #include <basegfx/numeric/ftools.hxx>
50 
51 #include "dx_winstuff.hxx"
52 #include "dx_spritecanvas.hxx"
53 
54 #if DIRECTX_VERSION < 0x0900
55 # define CANVAS_TECH "DX5"
56 #else
57 # define CANVAS_TECH "DX9"
58 #endif
59 
60 #define SPRITECANVAS_SERVICE_NAME        "com.sun.star.rendering.SpriteCanvas."      CANVAS_TECH
61 #define SPRITECANVAS_IMPLEMENTATION_NAME "com.sun.star.comp.rendering.SpriteCanvas." CANVAS_TECH
62 
63 
64 using namespace ::com::sun::star;
65 
66 namespace dxcanvas
67 {
68     SpriteCanvas::SpriteCanvas( const uno::Sequence< uno::Any >&                aArguments,
69                                 const uno::Reference< uno::XComponentContext >& rxContext ) :
70         maArguments(aArguments),
71         mxComponentContext( rxContext )
72     {
73     }
74 
75     void SpriteCanvas::initialize()
76     {
77         // #i64742# Only call initialize when not in probe mode
78         if( maArguments.getLength() == 0 )
79             return;
80 
81         VERBOSE_TRACE( "SpriteCanvas::initialize called" );
82 
83         /* aArguments:
84            0: ptr to creating instance (Window or VirtualDevice)
85            1: SystemEnvData as a streamed Any (or empty for VirtualDevice)
86            2: current bounds of creating instance
87            3: bool, denoting always on top state for Window (always false for VirtualDevice)
88            4: XWindow for creating Window (or empty for VirtualDevice)
89            5: SystemGraphicsData as a streamed Any
90          */
91         ENSURE_ARG_OR_THROW( maArguments.getLength() >= 5 &&
92                              maArguments[4].getValueTypeClass() == uno::TypeClass_INTERFACE,
93                              "VCLSpriteCanvas::initialize: wrong number of arguments, or wrong types" );
94 
95         uno::Reference< awt::XWindow > xParentWindow;
96         maArguments[4] >>= xParentWindow;
97         Window* pParentWindow = VCLUnoHelper::GetWindow(xParentWindow);
98         if( !pParentWindow )
99             throw lang::NoSupportException(
100                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
101                                      "Parent window not VCL window, or canvas out-of-process!")),
102                 NULL);
103 
104         awt::Rectangle aRect;
105         maArguments[2] >>= aRect;
106 
107         sal_Bool bIsFullscreen( sal_False );
108         maArguments[3] >>= bIsFullscreen;
109 
110         // setup helper
111         maDeviceHelper.init( *pParentWindow,
112                              *this,
113                              aRect,
114                              bIsFullscreen );
115         maCanvasHelper.init( *this,
116                              maRedrawManager,
117                              maDeviceHelper.getRenderModule(),
118 							 maDeviceHelper.getSurfaceProxy(),
119                              maDeviceHelper.getBackBuffer(),
120                              ::basegfx::B2ISize() );
121         maArguments.realloc(0);
122     }
123 
124     void SAL_CALL SpriteCanvas::disposing()
125     {
126         ::osl::MutexGuard aGuard( m_aMutex );
127 
128         mxComponentContext.clear();
129 
130         // forward to parent
131         SpriteCanvasBaseT::disposing();
132     }
133 
134     ::sal_Bool SAL_CALL SpriteCanvas::showBuffer( ::sal_Bool bUpdateAll ) throw (uno::RuntimeException)
135     {
136         ::osl::MutexGuard aGuard( m_aMutex );
137 
138         // avoid repaints on hidden window (hidden: not mapped to
139         // screen). Return failure, since the screen really has _not_
140         // been updated (caller should try again later)
141         return !mbIsVisible ? false : SpriteCanvasBaseT::showBuffer( bUpdateAll );
142     }
143 
144     ::sal_Bool SAL_CALL SpriteCanvas::switchBuffer( ::sal_Bool bUpdateAll ) throw (uno::RuntimeException)
145     {
146         ::osl::MutexGuard aGuard( m_aMutex );
147 
148         // avoid repaints on hidden window (hidden: not mapped to
149         // screen). Return failure, since the screen really has _not_
150         // been updated (caller should try again later)
151         return !mbIsVisible ? false : SpriteCanvasBaseT::switchBuffer( bUpdateAll );
152     }
153 
154     sal_Bool SAL_CALL SpriteCanvas::updateScreen( sal_Bool bUpdateAll ) throw (uno::RuntimeException)
155     {
156         ::osl::MutexGuard aGuard( m_aMutex );
157 
158         // avoid repaints on hidden window (hidden: not mapped to
159         // screen). Return failure, since the screen really has _not_
160         // been updated (caller should try again later)
161         return !mbIsVisible ? false : maCanvasHelper.updateScreen(
162             ::basegfx::unotools::b2IRectangleFromAwtRectangle(maBounds),
163             bUpdateAll,
164             mbSurfaceDirty );
165     }
166 
167     ::rtl::OUString SAL_CALL SpriteCanvas::getServiceName(  ) throw (uno::RuntimeException)
168     {
169         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SPRITECANVAS_SERVICE_NAME ) );
170     }
171 
172     const IDXRenderModuleSharedPtr& SpriteCanvas::getRenderModule() const
173     {
174         ::osl::MutexGuard aGuard( m_aMutex );
175 
176         return maDeviceHelper.getRenderModule();
177     }
178 
179     const DXSurfaceBitmapSharedPtr& SpriteCanvas::getBackBuffer() const
180     {
181         ::osl::MutexGuard aGuard( m_aMutex );
182 
183         return maDeviceHelper.getBackBuffer();
184     }
185 
186     IBitmapSharedPtr SpriteCanvas::getBitmap() const
187     {
188         return maDeviceHelper.getBackBuffer();
189     }
190 
191     static uno::Reference<uno::XInterface> initCanvas( SpriteCanvas* pCanvas )
192     {
193         uno::Reference<uno::XInterface> xRet(static_cast<cppu::OWeakObject*>(pCanvas));
194         pCanvas->initialize();
195         return xRet;
196     }
197 
198     namespace sdecl = comphelper::service_decl;
199     sdecl::class_<SpriteCanvas, sdecl::with_args<true> > serviceImpl(&initCanvas);
200     const sdecl::ServiceDecl dxSpriteCanvasDecl(
201         serviceImpl,
202         SPRITECANVAS_IMPLEMENTATION_NAME,
203         SPRITECANVAS_SERVICE_NAME );
204 }
205 
206 // The C shared lib entry points
207 COMPHELPER_SERVICEDECL_EXPORTS1(dxcanvas::dxSpriteCanvasDecl);
208