|
1 /* |
|
2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Screen buffer implementation |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 #include <coemain.h> |
|
21 |
|
22 #include "alflogger.h" |
|
23 #include "alf/alfenv.h" |
|
24 #include "alfclient.h" |
|
25 #include "alf/alfstatic.h" |
|
26 #include "alf/alfconstants.h" |
|
27 #include "alfuids.h" |
|
28 #include "alf/alfscreenbuffer.h" |
|
29 #include "alf/alfsymbiansbdrawer.h" |
|
30 |
|
31 #include <uiacceltk/HuiUtil.h> |
|
32 |
|
33 // *** class CAlfScreenBufferEventFetcher |
|
34 |
|
35 NONSHARABLE_CLASS(CAlfScreenBufferEventFetcher): public CActive |
|
36 { |
|
37 public: // Struct |
|
38 |
|
39 struct TScreenBufferInfo |
|
40 { |
|
41 MAlfScreenBufferObserver* iObserver; // Observer for this screen buffer. Not owned |
|
42 TUid iBufferUid; // Uid of the buffer to be observed. |
|
43 TInt iPriority; // Priority of the buffer. Not yet used. |
|
44 TInt iBitmapHandle; // Handle to the shared CFbsBitmap that contains the buffer. |
|
45 TInt iMaskHandle; // Mask handle |
|
46 TRect iLastDisplayRect; // Display rect |
|
47 TRect iLastDirtyRect; // Dirty rect |
|
48 }; |
|
49 |
|
50 |
|
51 public: // New methods |
|
52 |
|
53 CAlfScreenBufferEventFetcher(RAlfClient& aClient, MAlfScreenBufferObserver& aScreenBufferObs) |
|
54 :CActive(CActive::EPriorityHigh), iClient(aClient), iEventAsDescriptor(iEvent) |
|
55 { |
|
56 CAlfScreenBufferEventFetcher::TScreenBufferInfo info = {&aScreenBufferObs, KNullUid, 0, 0, 0, TRect(), TRect()}; |
|
57 iBufferInfo = info; |
|
58 CActiveScheduler::Add(this); |
|
59 } |
|
60 |
|
61 ~CAlfScreenBufferEventFetcher() |
|
62 { |
|
63 Cancel(); |
|
64 } |
|
65 |
|
66 // Request a new event |
|
67 void RequestBufferEvent() |
|
68 { |
|
69 if(!IsActive()) |
|
70 { |
|
71 SetActive(); |
|
72 iEvent.iBufferUid = iBufferInfo.iBufferUid; |
|
73 iEvent.iEventId = 0; |
|
74 iEvent.iDisplayRect = TRect(); |
|
75 iEvent.iDirtyRect = TRect(); |
|
76 iClient.SendAsyncCmd(EAlfSBufRequestEvent, iEventAsDescriptor, iStatus); |
|
77 } |
|
78 } |
|
79 |
|
80 // Return buffer info |
|
81 TScreenBufferInfo& ScreenBufferInfo() |
|
82 { |
|
83 return(iBufferInfo); |
|
84 } |
|
85 |
|
86 private: // From CActive |
|
87 |
|
88 void RunL() |
|
89 { |
|
90 if(iStatus.Int() != KErrNone) |
|
91 { |
|
92 USER_INVARIANT(); |
|
93 } |
|
94 |
|
95 // Issue a new event request first |
|
96 TAlfScreenBufferEvent event = iEvent; |
|
97 RequestBufferEvent(); |
|
98 |
|
99 // Handle event |
|
100 |
|
101 if (event.iEventId == MAlfScreenBufferObserver::ENone) // Buffer complete event |
|
102 { |
|
103 if (iBufferInfo.iObserver->BufferComplete(event.iBufferUid, event.iDisplayRect, event.iDirtyRect)) |
|
104 { |
|
105 // Request next buffer automatically |
|
106 TUid uidEvent = event.iBufferUid; |
|
107 TPckg<TUid> eventPckg(uidEvent); |
|
108 iClient.SendSyncCmd(EAlfSBufRequestNextBuffer, eventPckg); |
|
109 } |
|
110 } |
|
111 else |
|
112 { |
|
113 if (event.iEventId == MAlfScreenBufferObserver::ECreated) |
|
114 { |
|
115 // Add this buffer observer again to the array in Alf Server to get valid bitmap handles in return. |
|
116 TAlfScreenBufferBitmaps addObserverEvent = {iBufferInfo.iBufferUid, iBufferInfo.iPriority, NULL, NULL}; |
|
117 TPckg<TAlfScreenBufferBitmaps> eventPckg(addObserverEvent); |
|
118 iClient.SendSyncCmd(EAlfSBufAddObserver, eventPckg); |
|
119 |
|
120 // Update bitmap handles |
|
121 iBufferInfo.iBitmapHandle = addObserverEvent.iBitmapHandle; |
|
122 iBufferInfo.iMaskHandle = addObserverEvent.iMaskHandle; |
|
123 } |
|
124 else if (event.iEventId == MAlfScreenBufferObserver::EDeleted) |
|
125 { |
|
126 // Invalidate bitmap handles |
|
127 iBufferInfo.iBitmapHandle = NULL; |
|
128 iBufferInfo.iMaskHandle = NULL; |
|
129 } |
|
130 |
|
131 iBufferInfo.iObserver->HandleScreenBufferEvent(event.iBufferUid, event.iEventId); |
|
132 } |
|
133 } |
|
134 |
|
135 void DoCancel() |
|
136 { |
|
137 // Remove this AO from the observer array in Alf Server |
|
138 TAlfScreenBufferBitmaps event = {iBufferInfo.iBufferUid, 0, 0}; |
|
139 TPckg<TAlfScreenBufferBitmaps> eventPckg(event); |
|
140 iClient.SendSyncCmd(EAlfSBufRemoveObserver, eventPckg); |
|
141 } |
|
142 |
|
143 TInt RunError(TInt /*aError*/) |
|
144 { |
|
145 // Ignore error |
|
146 return KErrNone; |
|
147 } |
|
148 |
|
149 private: // Data |
|
150 |
|
151 RAlfClient& iClient; |
|
152 TAlfScreenBufferEvent iEvent; // Event data for pending buffer event. |
|
153 TPckg<TAlfScreenBufferEvent> iEventAsDescriptor; |
|
154 |
|
155 CAlfScreenBufferEventFetcher::TScreenBufferInfo iBufferInfo; // Buffer information |
|
156 }; |
|
157 |
|
158 |
|
159 |
|
160 // *** Array item for CAlfScreenBuffer |
|
161 |
|
162 struct TAlfScreenBufferHandlerItem |
|
163 { |
|
164 TAlfScreenBufferHandlerItem( TInt aId, CAlfScreenBufferEventFetcher* aAoPtr) |
|
165 :iId( aId ), iAoPtr( aAoPtr ) |
|
166 {}; |
|
167 TInt iId; // Buffer uid |
|
168 CAlfScreenBufferEventFetcher* iAoPtr; // Pointer to the active object that handles buffer events. Owned. |
|
169 }; |
|
170 |
|
171 |
|
172 // *** Private data for CAlfScreenBuffer |
|
173 |
|
174 NONSHARABLE_CLASS(CAlfScreenBuffer::CPrivateData):public CBase |
|
175 { |
|
176 public: |
|
177 ~CPrivateData() |
|
178 { |
|
179 iScreenBufferHandlers.Close(); |
|
180 if (iIsAlfEnvOwned) |
|
181 { |
|
182 delete(iEnv); |
|
183 } |
|
184 } |
|
185 |
|
186 CAlfEnv* iEnv; |
|
187 TBool iIsAlfEnvOwned; |
|
188 RArray<TAlfScreenBufferHandlerItem> iScreenBufferHandlers; // List of all buffer observer Active Objects |
|
189 }; |
|
190 |
|
191 |
|
192 // *** class CAlfScreenBuffer |
|
193 |
|
194 EXPORT_C CAlfScreenBuffer* CAlfScreenBuffer::NewL() |
|
195 { |
|
196 // Create own aAlf env if it does not exist. |
|
197 TBool isAlfEnvOwned = EFalse; |
|
198 CAlfEnv* env = CAlfEnv::Static(); |
|
199 if (!env) |
|
200 { |
|
201 isAlfEnvOwned = ETrue; |
|
202 env = CAlfEnv::NewL(); |
|
203 } |
|
204 |
|
205 // Create object |
|
206 CAlfScreenBuffer* self = new( ELeave ) CAlfScreenBuffer(); |
|
207 CleanupStack::PushL( self ); |
|
208 self->ConstructL(env, isAlfEnvOwned); |
|
209 CleanupStack::Pop( self ); |
|
210 return self; |
|
211 }; |
|
212 |
|
213 EXPORT_C CAlfScreenBuffer* CAlfScreenBuffer::NewL(CAlfEnv& aEnv) |
|
214 { |
|
215 CAlfScreenBuffer* self = new( ELeave ) CAlfScreenBuffer(); |
|
216 CleanupStack::PushL( self ); |
|
217 self->ConstructL(&aEnv, EFalse); |
|
218 CleanupStack::Pop( self ); |
|
219 return self; |
|
220 }; |
|
221 |
|
222 |
|
223 CAlfScreenBuffer::CAlfScreenBuffer() |
|
224 { |
|
225 } |
|
226 |
|
227 // @deprecated |
|
228 EXPORT_C CAlfScreenBuffer::CAlfScreenBuffer(CAlfEnv& /*aEnv*/) |
|
229 { |
|
230 } |
|
231 |
|
232 |
|
233 EXPORT_C CAlfScreenBuffer::~CAlfScreenBuffer() |
|
234 { |
|
235 for (TInt i = iData->iScreenBufferHandlers.Count()-1; i >= 0 ; i--) |
|
236 { |
|
237 RemoveObserver(iData->iScreenBufferHandlers[i].iAoPtr->ScreenBufferInfo().iBufferUid); |
|
238 } |
|
239 |
|
240 delete iData; |
|
241 } |
|
242 |
|
243 // @deprecated |
|
244 EXPORT_C void CAlfScreenBuffer::ConstructL() |
|
245 { |
|
246 // Not used, preserved for BC |
|
247 } |
|
248 |
|
249 void CAlfScreenBuffer::ConstructL(CAlfEnv* aEnv, TBool aIsAlfEnvOwned) |
|
250 { |
|
251 //@todo : should I check that only one instance is created per alf client? |
|
252 // Create private data |
|
253 iData = new (ELeave) CPrivateData; |
|
254 iData->iEnv = aEnv; |
|
255 iData->iIsAlfEnvOwned = aIsAlfEnvOwned; |
|
256 } |
|
257 |
|
258 |
|
259 EXPORT_C MAlfBufferDrawer* CAlfScreenBuffer::GetDrawingInterface(TUid aInterfaceUid, TUid aBufferUid) |
|
260 { |
|
261 // Symbian IF |
|
262 if (aInterfaceUid == KAlfSymbianBufferDrawerUid) |
|
263 { |
|
264 TAlfScreenBufferHandlerItem item( aBufferUid.iUid, NULL ); |
|
265 TInt index; |
|
266 if ( iData->iScreenBufferHandlers.FindInSignedKeyOrder( item, index ) == KErrNone ) |
|
267 { |
|
268 if (iData->iScreenBufferHandlers[index].iAoPtr->ScreenBufferInfo().iBitmapHandle) |
|
269 { |
|
270 CAlfSymbianBufferDrawer* drawer = NULL; |
|
271 TRAPD(err, drawer = CAlfSymbianBufferDrawer::NewL()); |
|
272 if (!err) |
|
273 { |
|
274 TRAP(err,drawer->SetBufferL( |
|
275 iData->iScreenBufferHandlers[index].iAoPtr->ScreenBufferInfo().iBitmapHandle, |
|
276 iData->iScreenBufferHandlers[index].iAoPtr->ScreenBufferInfo().iMaskHandle)); |
|
277 if (err) |
|
278 { |
|
279 delete drawer; |
|
280 return NULL; |
|
281 } |
|
282 else |
|
283 { |
|
284 return drawer; |
|
285 } |
|
286 } |
|
287 } |
|
288 } |
|
289 } |
|
290 return NULL; |
|
291 } |
|
292 |
|
293 |
|
294 EXPORT_C MAlfBufferGc* CAlfScreenBuffer::GetGraphicsContext(TUid /*aInterfaceUid*/, TUid /*aBufferUid*/) |
|
295 { |
|
296 return ((MAlfBufferGc*)NULL); |
|
297 } |
|
298 |
|
299 |
|
300 EXPORT_C void CAlfScreenBuffer::AddObserverL(TUid aBufferId, MAlfScreenBufferObserver* aObserver, TInt aPriority) |
|
301 { |
|
302 AddObserverL(aBufferId, CAlfScreenBuffer::EFlagNone, aObserver, aPriority); |
|
303 } |
|
304 |
|
305 |
|
306 EXPORT_C void CAlfScreenBuffer::AddObserverL(TUid aBufferId, TUint aFlags, MAlfScreenBufferObserver* aObserver, TInt aPriority) |
|
307 { |
|
308 // Add to the observer array in Alf Server, and get bitmap handles in return. |
|
309 TAlfScreenBufferBitmaps event = {aBufferId, aPriority, aFlags, NULL, NULL}; |
|
310 TPckg<TAlfScreenBufferBitmaps> eventPckg(event); |
|
311 User::LeaveIfError(iData->iEnv->Client().SendSyncCmd(EAlfSBufAddObserver, eventPckg)); |
|
312 |
|
313 // Append the handler to the client list |
|
314 CAlfScreenBufferEventFetcher* eventFetcher = new (ELeave) CAlfScreenBufferEventFetcher(iData->iEnv->Client(), *aObserver); |
|
315 CAlfScreenBufferEventFetcher::TScreenBufferInfo info = {eventFetcher->ScreenBufferInfo().iObserver, event.iBufferUid, aPriority, event.iBitmapHandle, event.iMaskHandle, TRect(), TRect()}; |
|
316 eventFetcher->ScreenBufferInfo() = info; |
|
317 // Transfers ownership of eventFetcher |
|
318 TInt err = iData->iScreenBufferHandlers.InsertInUnsignedKeyOrder(TAlfScreenBufferHandlerItem(aBufferId.iUid, eventFetcher)); |
|
319 |
|
320 if (err) |
|
321 { |
|
322 delete eventFetcher; |
|
323 RemoveObserver(aBufferId); |
|
324 User::Leave(err); |
|
325 } |
|
326 else |
|
327 { |
|
328 // Start observing any event |
|
329 eventFetcher->RequestBufferEvent(); |
|
330 } |
|
331 } |
|
332 |
|
333 |
|
334 // Note: This can be also called to already removed observers. In that case it has no effect. |
|
335 EXPORT_C void CAlfScreenBuffer::RemoveObserver(TUid aBufferId) |
|
336 { |
|
337 // Remove from the observer array in Alf Server |
|
338 TAlfScreenBufferBitmaps event = {aBufferId, 0, 0}; |
|
339 TPckg<TAlfScreenBufferBitmaps> eventPckg(event); |
|
340 iData->iEnv->Client().SendSyncCmd(EAlfSBufRemoveObserver, eventPckg); |
|
341 |
|
342 // Remove the handler from the client list |
|
343 TAlfScreenBufferHandlerItem item( aBufferId.iUid, NULL ); |
|
344 TInt index; |
|
345 if ( iData->iScreenBufferHandlers.FindInSignedKeyOrder( item, index ) == KErrNone ) |
|
346 { |
|
347 delete(iData->iScreenBufferHandlers[index].iAoPtr); |
|
348 iData->iScreenBufferHandlers.Remove(index); |
|
349 } |
|
350 } |
|
351 |
|
352 |
|
353 EXPORT_C void CAlfScreenBuffer::RequestNextBuffer(TUid aBufferId) |
|
354 { |
|
355 TAlfScreenBufferHandlerItem item( aBufferId.iUid, NULL ); |
|
356 TInt index; |
|
357 if ( iData->iScreenBufferHandlers.FindInSignedKeyOrder( item, index ) == KErrNone ) |
|
358 { |
|
359 TUid event = aBufferId; |
|
360 TPckg<TUid> eventPckg(event); |
|
361 iData->iEnv->Client().SendSyncCmd(EAlfSBufRequestNextBuffer, eventPckg); |
|
362 } |
|
363 else |
|
364 { |
|
365 // I am not a listener for this buffer |
|
366 __ALFLOGSTRING1( "CAlfScreenBuffer::RequestNextBuffer(). Observer not found for uid %x", aBufferId.iUid ); |
|
367 } |
|
368 } |
|
369 |
|
370 |
|
371 EXPORT_C void CAlfScreenBuffer::RequestBufferDraw(TUid aBufferId) |
|
372 { |
|
373 TAlfScreenBufferHandlerItem item( aBufferId.iUid, NULL ); |
|
374 TInt index; |
|
375 if ( iData->iScreenBufferHandlers.FindInSignedKeyOrder( item, index ) == KErrNone ) |
|
376 { |
|
377 TUid event = aBufferId; |
|
378 TPckg<TUid> eventPckg(event); |
|
379 iData->iEnv->Client().SendSyncCmd(EAlfSBufRequestBufferDraw, eventPckg); |
|
380 } |
|
381 else |
|
382 { |
|
383 // I am not a listener for this buffer |
|
384 __ALFLOGSTRING1( "CAlfScreenBuffer::RequestNextBuffer(). Observer not found for uid %x", aBufferId.iUid ); |
|
385 } |
|
386 } |
|
387 |
|
388 |
|
389 |
|
390 |
|
391 |
|
392 |
|
393 |
|
394 |