|
1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include "directgdiadapter.h" |
|
17 #include "swdirectgdidriverimpl.h" |
|
18 #include "swdirectgdiimagesourceimpl.h" |
|
19 #include "swdirectgdiimagetargetimpl.h" |
|
20 #include "pixelutil.h" |
|
21 #include <e32cmn.h> |
|
22 #include <pixelformats.h> |
|
23 #include <graphics/sgimage_sw.h> |
|
24 |
|
25 /** |
|
26 @panic DGDIAdapter 6, if the reference count to DirectGDI driver is invalid. |
|
27 @panic DGDIAdapter 45, if objects are still in the source or target image array. |
|
28 */ |
|
29 CSwDirectGdiDriverImpl::~CSwDirectGdiDriverImpl() |
|
30 { |
|
31 GRAPHICS_ASSERT_DEBUG(iEngines.Count() == 0, EDirectGdiPanicDriverInvalidRefCount); |
|
32 GRAPHICS_ASSERT_DEBUG(iTargets.Count() == 0, EDirectGdiPanicItemsLeftInImageArray); |
|
33 GRAPHICS_ASSERT_DEBUG(iImageSources.Count() == 0, EDirectGdiPanicItemsLeftInImageArray); |
|
34 |
|
35 // Delete all the engines owned by this driver |
|
36 iEngines.ResetAndDestroy(); |
|
37 iTargets.ResetAndDestroy(); |
|
38 iImageSources.ResetAndDestroy(); |
|
39 } |
|
40 |
|
41 /** |
|
42 Constructor, which initialises base class. |
|
43 */ |
|
44 CSwDirectGdiDriverImpl::CSwDirectGdiDriverImpl(RLibrary aLibrary) |
|
45 : CDirectGdiDriverInternal(aLibrary) |
|
46 { |
|
47 } |
|
48 |
|
49 /** |
|
50 Empty function as this adaptation is synchronous. |
|
51 @see CDirectGdiDriverInternal::Flush() |
|
52 */ |
|
53 void CSwDirectGdiDriverImpl::Flush() |
|
54 { |
|
55 } |
|
56 |
|
57 /** |
|
58 Empty function as this adaptation is synchronous. |
|
59 @see CDirectGdiDriverInternal::Finish() |
|
60 */ |
|
61 void CSwDirectGdiDriverImpl::Finish() |
|
62 { |
|
63 } |
|
64 |
|
65 /** |
|
66 @see CDirectGdiDriver::GetError() |
|
67 */ |
|
68 TInt CSwDirectGdiDriverImpl::GetError() |
|
69 { |
|
70 TInt err = iErrorCode; |
|
71 iErrorCode = KErrNone; |
|
72 return err; |
|
73 } |
|
74 |
|
75 /** |
|
76 @see CDirectGdiDriverInternal::CloseDrawableSource() |
|
77 @panic DGDIAdapter 57, if aHandleRet is not KNullHandle (debug only). |
|
78 */ |
|
79 TInt CSwDirectGdiDriverImpl::CreateDrawableSource(TInt& aHandleRet, const RSgDrawable& aSgDrawable) |
|
80 { |
|
81 TInt err = KErrNotSupported; |
|
82 const TUid typeUid = aSgDrawable.DrawableType(); |
|
83 if(KSgImageTypeUid == typeUid) |
|
84 { |
|
85 CSwDirectGdiImageSourceImpl* imageSource = NULL; |
|
86 RSgImage* image = (RSgImage*) (&aSgDrawable); |
|
87 err = CSwDirectGdiImageSourceImpl::New(imageSource, *this, *image); |
|
88 |
|
89 if (err == KErrNone) |
|
90 { |
|
91 aHandleRet = reinterpret_cast<TInt>(imageSource); |
|
92 } |
|
93 } |
|
94 return err; |
|
95 } |
|
96 |
|
97 /** |
|
98 @see CDirectGdiDriverInternal::CreateDrawableSource() |
|
99 @panic DGDIAdapter 47, if the drawable source belonging to aHandle could not be found in the internal |
|
100 list of sources (debug only). |
|
101 */ |
|
102 void CSwDirectGdiDriverImpl::CloseDrawableSource(TInt& aHandle) |
|
103 { |
|
104 // Graphics Resource and DirectGDI reference implementation only support pixel based resource |
|
105 CSwDirectGdiImageSourceImpl* source = reinterpret_cast<CSwDirectGdiImageSourceImpl*>(aHandle); |
|
106 if (source) |
|
107 source->Close(); |
|
108 aHandle = KNullHandle; |
|
109 } |
|
110 |
|
111 /** |
|
112 @see CDirectGdiDriverInternal::CreateImageTarget() |
|
113 @panic DGDIAdapter 58, if aHandleRet is not KNullHandle (debug only). |
|
114 @panic DGDIAdapter 1023, if the attempt to get an RSgImage interface MSgImage_Sw failed. |
|
115 */ |
|
116 TInt CSwDirectGdiDriverImpl::CreateImageTarget(TInt& aHandleRet, const RSgImage& aImage) |
|
117 { |
|
118 TSgImageInfo info; |
|
119 TInt ret = aImage.GetInfo(info); |
|
120 if (ret != KErrNone) |
|
121 { |
|
122 return ret; |
|
123 } |
|
124 TDisplayMode displayMode = PixelFormatUtil::ConvertToDisplayMode(info.iPixelFormat); |
|
125 TSize size = info.iSizeInPixels; |
|
126 CFbsDrawDevice* device = NULL; |
|
127 const MSgImage_Sw* pImage; |
|
128 TInt err = aImage.GetInterface(pImage); |
|
129 GRAPHICS_ASSERT_DEBUG((err == KErrNone) && (pImage != NULL), EDirectGdiPanicInvalidInterfaceHandle); |
|
130 TRAP(err, device = CFbsDrawDevice::NewBitmapDeviceL(size, displayMode, pImage->DataStride())); |
|
131 if (err != KErrNone) |
|
132 { |
|
133 return err; |
|
134 } |
|
135 |
|
136 // Setup the new device with the memory from the image |
|
137 device->SetBits(pImage->DataAddress()); |
|
138 |
|
139 // Create a new image |
|
140 if (err == KErrNone) |
|
141 { |
|
142 CSwDirectGdiImageTargetImpl* target = NULL; |
|
143 err = CSwDirectGdiImageTargetImpl::New(target, *this, device, aImage); |
|
144 if (err == KErrNone) |
|
145 { |
|
146 // Make sure we aren't overwriting an exisiting valid handle. |
|
147 GRAPHICS_ASSERT_DEBUG(aHandleRet == KNullHandle, EDirectGdiPanicTargetHandleNotNull); |
|
148 aHandleRet = reinterpret_cast<TInt>(target); |
|
149 } |
|
150 } |
|
151 |
|
152 if (err != KErrNone) |
|
153 { |
|
154 delete device; |
|
155 } |
|
156 |
|
157 return err; |
|
158 } |
|
159 |
|
160 /** |
|
161 @see CDirectGdiDriverInternal::CloseImageTarget() |
|
162 @panic DGDIAdapter 40, if the image target associated with aHandle could not be found in the |
|
163 internal list of targets (debug only). |
|
164 */ |
|
165 void CSwDirectGdiDriverImpl::CloseImageTarget(TInt& aHandle) |
|
166 { |
|
167 CSwDirectGdiImageTargetImpl* target = reinterpret_cast<CSwDirectGdiImageTargetImpl*>(aHandle); |
|
168 if (target) |
|
169 target->Close(); |
|
170 aHandle = KNullHandle; |
|
171 } |
|
172 |
|
173 |
|
174 /** |
|
175 @see CDirectGdiDriverInteral::CreateEngine() |
|
176 */ |
|
177 TInt CSwDirectGdiDriverImpl::CreateEngine(MDirectGdiEngine*& aEngine) |
|
178 { |
|
179 TInt err = KErrNoMemory; |
|
180 CSwDirectGdiEngine* engine = new CSwDirectGdiEngine(this); |
|
181 aEngine = engine; |
|
182 if(engine != NULL) |
|
183 { |
|
184 // Put this in an array so we can destroy it on close |
|
185 err = iEngines.InsertInAddressOrder(engine); |
|
186 if (KErrNone != err) |
|
187 { |
|
188 delete engine; |
|
189 aEngine = NULL; |
|
190 } |
|
191 } |
|
192 return err; |
|
193 } |
|
194 |
|
195 /** |
|
196 @see CDirectGdiDriverInternal::DestroyEngine() |
|
197 @panic DGDIAdapter 60, if aEngine could not be found in the internal list of engines (debug only). |
|
198 */ |
|
199 void CSwDirectGdiDriverImpl::DestroyEngine(MDirectGdiEngine* aEngine) |
|
200 { |
|
201 TInt index = iEngines.FindInAddressOrder(aEngine); |
|
202 GRAPHICS_ASSERT_DEBUG(index != KErrNotFound, EDirectGdiPanicEngineNotFound); |
|
203 iEngines.Remove(index); |
|
204 delete (static_cast<CSwDirectGdiEngine*>(aEngine)); |
|
205 } |
|
206 |
|
207 /** |
|
208 @see CDirectGdiDriverInternal::SetError() |
|
209 */ |
|
210 void CSwDirectGdiDriverImpl::SetError(TInt aErr) |
|
211 { |
|
212 if (aErr != KErrNone && iErrorCode == KErrNone) |
|
213 { |
|
214 iErrorCode = aErr; |
|
215 } |
|
216 } |
|
217 |
|
218 /** |
|
219 No extensions interfaces are supported. |
|
220 |
|
221 @see CDirectGdiDriver::GetInterface() |
|
222 */ |
|
223 TInt CSwDirectGdiDriverImpl::GetInterface(TUid /*aInterfaceId*/, TAny*& aInterface) |
|
224 { |
|
225 aInterface = NULL; |
|
226 return KErrExtensionNotSupported; |
|
227 } |
|
228 |
|
229 /** |
|
230 Deactivate the target if it was the current target, decrement the reference count of the target as it can be shared |
|
231 across many DirectGDI contexts. |
|
232 |
|
233 @param aRenderingTarget The target object which you want to deactivate. |
|
234 |
|
235 @panic DGDIAdapter 55, if aRengeringTarget is NULL. |
|
236 */ |
|
237 void CSwDirectGdiDriverImpl::Deactivate(CSwDirectGdiImageTargetImpl* aRenderingTarget) |
|
238 { |
|
239 GRAPHICS_ASSERT_ALWAYS(aRenderingTarget, EDirectGdiPanicNullTargetDeactivate); |
|
240 aRenderingTarget->Close(); |
|
241 } |
|
242 |
|
243 /** |
|
244 Checks whether the image source handle is valid. |
|
245 |
|
246 @param aHandle The handle to an Image Source that should be found. |
|
247 @return ETrue if aHandle is a valid handle to an image registered with the driver, otherwise EFalse. |
|
248 */ |
|
249 TBool CSwDirectGdiDriverImpl::ValidImageSource(TInt aHandle) const |
|
250 { |
|
251 CSwDirectGdiImageSourceImpl* impl = reinterpret_cast<CSwDirectGdiImageSourceImpl*>(aHandle); |
|
252 return iImageSources.FindInAddressOrder(impl) != KErrNotFound; |
|
253 } |
|
254 |
|
255 /** |
|
256 Checks whether the target image handle is valid. |
|
257 |
|
258 @param aHandle The handle to an Image Target that should be found. |
|
259 @return ETrue if aHandle is a valid handle to an image registered with the driver, otherwise EFalse. |
|
260 */ |
|
261 TBool CSwDirectGdiDriverImpl::ValidImageTarget(TInt aHandle) const |
|
262 { |
|
263 CSwDirectGdiImageTargetImpl* impl = reinterpret_cast<CSwDirectGdiImageTargetImpl*>(aHandle); |
|
264 return iTargets.FindInAddressOrder(impl) != KErrNotFound; |
|
265 } |
|
266 |
|
267 /** |
|
268 Removes the specified image target from the internal list of targets. |
|
269 |
|
270 @param aImageTarget The image to remove. |
|
271 @return KErrNotFound if it could not be found in the internal list, otherwise KErrNone. |
|
272 */ |
|
273 TInt CSwDirectGdiDriverImpl::UnregisterTargetImage(const CSwDirectGdiImageTargetImpl& aImageTarget) |
|
274 { |
|
275 TInt err = KErrNone; |
|
276 TInt index = iTargets.FindInAddressOrder(&aImageTarget); |
|
277 if (index == KErrNotFound) |
|
278 { |
|
279 err = KErrNotFound; |
|
280 } |
|
281 else |
|
282 { |
|
283 iTargets.Remove(index); |
|
284 iTargets.GranularCompress(); |
|
285 } |
|
286 return err; |
|
287 } |
|
288 |
|
289 /** |
|
290 Removes the specified image source from the internal list of sources. |
|
291 |
|
292 @param aImageSource The image to remove. |
|
293 @return KErrNotFound if it could not be found in the internal list, otherwise KErrNone. |
|
294 */ |
|
295 TInt CSwDirectGdiDriverImpl::UnregisterSourceImage(const CSwDirectGdiImageSourceImpl& aImageSource) |
|
296 { |
|
297 TInt err = KErrNone; |
|
298 TInt index = iImageSources.FindInAddressOrder(&aImageSource); |
|
299 if (index == KErrNotFound) |
|
300 { |
|
301 err = KErrNotFound; |
|
302 } |
|
303 else |
|
304 { |
|
305 iImageSources.Remove(index); |
|
306 iImageSources.GranularCompress(); |
|
307 } |
|
308 return err; |
|
309 } |
|
310 |
|
311 /** |
|
312 Helper function. When an image source is constructed, it registers itself on the driver's internal |
|
313 list of image sources. |
|
314 @param aImageSource The image to add to the array. |
|
315 @return KErrNone if successful, otherwise one of the system-wide error codes. |
|
316 */ |
|
317 TInt CSwDirectGdiDriverImpl::RegisterSourceImage(const CSwDirectGdiImageSourceImpl& aImageSource) |
|
318 { |
|
319 return iImageSources.InsertInAddressOrder(&aImageSource); |
|
320 } |
|
321 |
|
322 /** |
|
323 Helper function. When an image target is constructed, it registers itself on the driver's internal |
|
324 list of image targets. |
|
325 @param aImageTarget The image to add to the array. |
|
326 @return KErrNone if successful, otherwise one of the system-wide error codes. |
|
327 */ |
|
328 TInt CSwDirectGdiDriverImpl::RegisterTargetImage(const CSwDirectGdiImageTargetImpl& aImageTarget) |
|
329 { |
|
330 return iTargets.InsertInAddressOrder(&aImageTarget); |
|
331 } |
|
332 |