|
1 // Copyright (c) 2000-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 // Client side classes for handling direct screen access |
|
15 // |
|
16 // |
|
17 |
|
18 #include <e32std.h> |
|
19 #include <e32base.h> |
|
20 #include "../SERVER/w32cmd.h" |
|
21 #include "CLIENT.H" |
|
22 #include "w32comm.h" |
|
23 #include <e32msgqueue.h> |
|
24 |
|
25 |
|
26 NONSHARABLE_CLASS(CDsaMsgQueue) : public CActive |
|
27 { |
|
28 public: |
|
29 CDsaMsgQueue(); |
|
30 ~CDsaMsgQueue(); |
|
31 void Request(TRequestStatus* aClientRequest); |
|
32 TBool Started() { return iStarted;} |
|
33 TBool Completed(); |
|
34 void OpenRecQueue(TInt aHandle); |
|
35 void OpenSendQueue(TInt aHandle); |
|
36 TInt Send(TInt aData); |
|
37 RMsgQueueBase& SendQueue() {return iSendQueue; } |
|
38 RMsgQueueBase& Queue() { return iRecQueue; } |
|
39 TRequestStatus* Status() { return &iStatus; } |
|
40 TBool RequestStarted() { return iStarted;} |
|
41 private: |
|
42 void DoCancel(); |
|
43 void RunL(); |
|
44 void Listen(); |
|
45 |
|
46 private: |
|
47 RMsgQueueBase iRecQueue; |
|
48 RMsgQueueBase iSendQueue; |
|
49 TRequestStatus* iClientRequest; |
|
50 TBool iStarted; |
|
51 RThread* iServer; |
|
52 }; |
|
53 |
|
54 // |
|
55 CDsaMsgQueue::CDsaMsgQueue() : CActive(RDirectScreenAccess::EPriorityVeryHigh) |
|
56 { |
|
57 CActiveScheduler::Add(this); |
|
58 } |
|
59 |
|
60 CDsaMsgQueue::~CDsaMsgQueue() |
|
61 { |
|
62 Cancel(); |
|
63 iRecQueue.Close(); |
|
64 iSendQueue.Close(); |
|
65 } |
|
66 |
|
67 TInt CDsaMsgQueue::Send(TInt aData) |
|
68 { |
|
69 return iSendQueue.Send(&aData,sizeof(TInt)); |
|
70 } |
|
71 |
|
72 void CDsaMsgQueue::OpenRecQueue(TInt aHandle) |
|
73 { |
|
74 iRecQueue.SetHandle(aHandle); |
|
75 // With RmessagePtr2 compelete using an RHandle the returned handle is already duplicated |
|
76 } |
|
77 |
|
78 void CDsaMsgQueue::OpenSendQueue(TInt aHandle) |
|
79 { |
|
80 iSendQueue.SetHandle(aHandle); |
|
81 // With RmessagePtr2 compelete using an RHandle the returned handle is already duplicated |
|
82 } |
|
83 |
|
84 void CDsaMsgQueue::DoCancel() |
|
85 { |
|
86 iRecQueue.CancelDataAvailable(); |
|
87 TInt ret = KErrNone; |
|
88 do |
|
89 { |
|
90 TInt data = 0; |
|
91 ret = iRecQueue.Receive(&data,sizeof(TInt)); |
|
92 }while(ret == KErrNone); |
|
93 if(iClientRequest) |
|
94 { |
|
95 RThread().RequestComplete(iClientRequest,KErrCancel); |
|
96 } |
|
97 } |
|
98 |
|
99 void CDsaMsgQueue::RunL() |
|
100 { |
|
101 // get the data from the msg queue |
|
102 TInt reason = 0; |
|
103 iRecQueue.Receive(&reason,sizeof(TInt)); |
|
104 |
|
105 if(iClientRequest) |
|
106 { |
|
107 // if there is an outstanding client request, complete and pass on the abort reason |
|
108 User::RequestComplete(iClientRequest,reason); |
|
109 iClientRequest = NULL; |
|
110 } |
|
111 } |
|
112 |
|
113 void CDsaMsgQueue::Listen() |
|
114 { |
|
115 if(!IsActive()) |
|
116 { |
|
117 SetActive(); |
|
118 iRecQueue.NotifyDataAvailable(iStatus); |
|
119 } |
|
120 } |
|
121 |
|
122 void CDsaMsgQueue::Request(TRequestStatus* aClientRequest) |
|
123 { |
|
124 __ASSERT_ALWAYS(!IsActive(),User::Invariant()); |
|
125 iClientRequest = aClientRequest; |
|
126 iStarted = ETrue; |
|
127 Listen(); |
|
128 } |
|
129 |
|
130 TBool CDsaMsgQueue::Completed() |
|
131 { |
|
132 if(iStarted) |
|
133 { |
|
134 Send(KErrNone); |
|
135 iStarted = EFalse; |
|
136 return ETrue; |
|
137 } |
|
138 return EFalse; |
|
139 } |
|
140 |
|
141 |
|
142 LOCAL_C inline TDeviceOrientation Graphics2DeviceOrientation(CFbsBitGc::TGraphicsOrientation aGraphicsOrientation) |
|
143 { |
|
144 return ((TDeviceOrientation)(1 << aGraphicsOrientation)); |
|
145 } |
|
146 |
|
147 // |
|
148 // RDirectScreenAccess |
|
149 // |
|
150 |
|
151 EXPORT_C RDirectScreenAccess::RDirectScreenAccess() |
|
152 /** Default constructor. |
|
153 |
|
154 Developers should use the other constructor overload instead. */ |
|
155 { |
|
156 } |
|
157 |
|
158 EXPORT_C RDirectScreenAccess::RDirectScreenAccess(RWsSession& aWs) : MWsClientClass(aWs.iBuffer), iWs(&aWs), iMsgQueue(NULL) |
|
159 /** C++ constructor with a connected window server session. |
|
160 |
|
161 Construct() must be called to complete construction. |
|
162 |
|
163 @param aWs Connected session with the window server. */ |
|
164 { |
|
165 } |
|
166 |
|
167 EXPORT_C TInt RDirectScreenAccess::Construct() |
|
168 /** Second phase constructor. |
|
169 |
|
170 Creates the server side resource and initialises the client's handle to it. |
|
171 |
|
172 This function always causes a flush of the window server buffer. |
|
173 |
|
174 @return KErrNone if successful, otherwise one of the system wide error codes. |
|
175 @panic TW32Panic 17 in debug builds if called on an already constructed object.*/ |
|
176 { |
|
177 __ASSERT_DEBUG(iWsHandle == KNullHandle, Panic(EW32PanicGraphicDoubleConstruction)); |
|
178 return Construct(EFalse); |
|
179 } |
|
180 |
|
181 EXPORT_C TInt RDirectScreenAccess::Construct(TBool aRegionTrackingOnly) |
|
182 /** Second phase constructor. |
|
183 |
|
184 Creates the server side resource and initialises the client's handle to it. |
|
185 |
|
186 This function always causes a flush of the window server buffer. |
|
187 |
|
188 @param aRegionTrackingOnly ETrue if the DSA is intended to be used for region tracking purposes only, |
|
189 EFalse if the DSA will be used to perform actual drawing. |
|
190 @return KErrNone if successful, otherwise one of the system wide error codes. |
|
191 @panic TW32Panic 17 in debug builds if called on an already constructed object.*/ |
|
192 { |
|
193 __ASSERT_DEBUG(iWsHandle == KNullHandle, Panic(EW32PanicGraphicDoubleConstruction)); |
|
194 TInt ret = KErrNone; |
|
195 TWsClientOpcodes requestedOpCode = aRegionTrackingOnly? EWsClOpCreateDirectScreenAccessRegionTrackingOnly : EWsClOpCreateDirectScreenAccess; |
|
196 |
|
197 if ((ret = iBuffer->WriteReplyWs(requestedOpCode)) >= 0) |
|
198 { |
|
199 iWsHandle = ret; |
|
200 TRAP(ret,iMsgQueue = new (ELeave)CDsaMsgQueue); |
|
201 if(ret == KErrNone) |
|
202 { |
|
203 // the servers send queue is the client receive queue |
|
204 TInt h = WriteReply(EWsDirectOpGetSendQueue); |
|
205 iMsgQueue->OpenRecQueue(h); |
|
206 |
|
207 // servers receive queue is the clients send queue |
|
208 h = WriteReply(EWsDirectOpGetRecQueue); |
|
209 iMsgQueue->OpenSendQueue(h); |
|
210 } |
|
211 else |
|
212 { |
|
213 Close(); |
|
214 } |
|
215 } |
|
216 return(ret); |
|
217 } |
|
218 |
|
219 EXPORT_C TInt RDirectScreenAccess::Request(RRegion*& aRegion,TRequestStatus& aStatus,const RWindowBase& aWindow) |
|
220 /** Issues a request to the window server for permission to perform direct screen |
|
221 access on a window. |
|
222 |
|
223 Direct access to the screen may be refused due to lack of memory or if the |
|
224 target window is completely obscured. |
|
225 |
|
226 If direct access is allowed, the function passes back a clipping region which |
|
227 is the part of the screen the caller can draw to. |
|
228 |
|
229 When direct screen access must stop, for instance because a dialog is to be |
|
230 displayed in front of the region where direct screen access is taking place, |
|
231 the window server completes the request. The recommended way to check for |
|
232 this is for aStatus to be the request status of an active object that will |
|
233 be run when the request completes, i.e. if Request() returns KErrNone, call |
|
234 SetActive(), and in the object's RunL(), you should immediately abort direct |
|
235 screen access. |
|
236 |
|
237 While the DSA is in operation, it is strongly advised that the client should |
|
238 not make any call to WSERV that will affect the visible area of the window in |
|
239 which the DSA is taking place. |
|
240 |
|
241 When WSERV tells the client that it needs to abort its DSA, it waits to receive |
|
242 the acknowledgment from the client that it has done so. However, it doesn't wait |
|
243 for ever, since the client may have entered some long running calculation or even |
|
244 an infinite loop. So WSERV also waits on a timer: if the timer expires before the |
|
245 client acknowledges, then WSERV continues; if, later on, WSERV gets notification |
|
246 from the client that it has aborted the DSA, then WSERV will invalidate the region |
|
247 in which the DSA was taking place, just in case there had been a conflict between |
|
248 the DSA and another client. |
|
249 |
|
250 |
|
251 This function always causes a flush of the window server buffer. |
|
252 |
|
253 @param aRegion On return, the clipping region that the caller can draw to. |
|
254 NULL if the function was not successful. |
|
255 If the target window is invisible or completely covered by other windows |
|
256 then the region will be empty. |
|
257 @param aStatus A request status that is set to a completion code by the window |
|
258 server when direct screen access must stop. |
|
259 @param aWindow The window that you want to perform the direct screen access |
|
260 on. |
|
261 @return KErrNone if the request was successful, KErrNone with empty region if |
|
262 none of the window is currently visible, otherwise one of the system wide error codes, |
|
263 e.g. KErrNoMemory if out of memory. */ |
|
264 { |
|
265 __ASSERT_ALWAYS(iMsgQueue,Panic(EW32PanicDirectMisuse)); |
|
266 |
|
267 aRegion = NULL; |
|
268 |
|
269 // Allocate the memory for the RRegion here so it is simple to back out |
|
270 // in case of failure |
|
271 TAny* regionMem = User::Alloc (sizeof (RRegion)); |
|
272 if (!regionMem) |
|
273 { |
|
274 return KErrNoMemory; |
|
275 } |
|
276 |
|
277 TInt ret = WriteReplyInt(aWindow.WsHandle(),EWsDirectOpRequest); |
|
278 if (ret<KErrNone) |
|
279 { |
|
280 User::Free (regionMem); |
|
281 return ret; |
|
282 } |
|
283 TRect* rectList = NULL; |
|
284 TRect* newRectList; |
|
285 TInt numRect; |
|
286 |
|
287 do |
|
288 { |
|
289 numRect = ret; |
|
290 newRectList = STATIC_CAST(TRect*,User::ReAlloc(rectList,numRect*sizeof(TRect))); |
|
291 if (!newRectList) |
|
292 { |
|
293 Write(EWsDirectOpInitFailed); |
|
294 User::Free (regionMem); |
|
295 delete rectList; |
|
296 return KErrNoMemory; |
|
297 } |
|
298 rectList = newRectList; |
|
299 TPtr8 ptr(REINTERPRET_CAST(TUint8*,rectList),ret*sizeof(TRect)); |
|
300 ret = WriteReplyIntP(ret,&ptr,EWsDirectOpGetRegion); |
|
301 } while(ret >=0 && ret != KMaxTInt); |
|
302 if (ret<0) |
|
303 { |
|
304 User::Free (regionMem); |
|
305 delete rectList; |
|
306 return ret; |
|
307 } |
|
308 |
|
309 aRegion = new (regionMem) RRegion (numRect, rectList); |
|
310 aStatus = KRequestPending; |
|
311 iMsgQueue->Request(&aStatus); |
|
312 iWs->DirectAcessActivation(ETrue); |
|
313 return KErrNone; |
|
314 } |
|
315 |
|
316 EXPORT_C void RDirectScreenAccess::Completed() |
|
317 /** Indicates to the window server that you have responded to the completion of |
|
318 the request status passed to Request(), by stopping direct screen access. */ |
|
319 { |
|
320 __ASSERT_ALWAYS(iMsgQueue->Started(),Panic(EW32PanicDirectMisuse)); |
|
321 if(iMsgQueue->Completed()) |
|
322 { |
|
323 iWs->DirectAcessActivation(EFalse); |
|
324 } |
|
325 } |
|
326 |
|
327 EXPORT_C void RDirectScreenAccess::Cancel() |
|
328 /** Indicates to the window server that you have finished performing direct screen |
|
329 access. */ |
|
330 { |
|
331 if(iMsgQueue->Started()) |
|
332 { |
|
333 Completed(); |
|
334 } |
|
335 TInt ret = WriteReply(EWsDirectOpCancel); |
|
336 if(ret != 0) // the server is sending us some data. |
|
337 { |
|
338 iMsgQueue->Queue().CancelDataAvailable(); |
|
339 TInt data = 0; |
|
340 iMsgQueue->Queue().ReceiveBlocking(&data,sizeof(TInt)); |
|
341 } |
|
342 iMsgQueue->Cancel(); |
|
343 } |
|
344 |
|
345 EXPORT_C void RDirectScreenAccess::Close() |
|
346 /** Calls Completed() then deletes the server side resource and sets the client's |
|
347 handle to it to NULL. */ |
|
348 { |
|
349 if (iBuffer && iWsHandle) |
|
350 { |
|
351 if(iMsgQueue && iMsgQueue->Started()) |
|
352 { |
|
353 Completed(); |
|
354 } |
|
355 Write(EWsDirectOpFree); |
|
356 delete iMsgQueue; |
|
357 iMsgQueue = NULL; |
|
358 } |
|
359 iWsHandle = NULL; |
|
360 } |
|
361 |
|
362 // |
|
363 // CDirectScreenAccess |
|
364 // |
|
365 |
|
366 EXPORT_C CDirectScreenAccess* CDirectScreenAccess::NewL(RWsSession& aWs,CWsScreenDevice& aScreenDevice,RWindowBase& aWin,MDirectScreenAccess& aAbort) |
|
367 /** Allocates and constructs the object and adds it to the current active scheduler. |
|
368 |
|
369 This function always causes a flush of the window server buffer. |
|
370 |
|
371 @param aWs A session with the window server. |
|
372 @param aScreenDevice Specifies the characteristics of the screen device to |
|
373 draw to. |
|
374 @param aWin The window to draw to directly. |
|
375 @param aAbort Defines an AbortNow() and a Restart() function which are both |
|
376 called on aborting, as part of the RunL(). Restart() is called from an idle |
|
377 time active object (CIdle). |
|
378 @return The newly constructed object. */ |
|
379 { |
|
380 return CDirectScreenAccess::NewL(aWs,aScreenDevice,aWin,aAbort,EFalse); |
|
381 } |
|
382 |
|
383 EXPORT_C CDirectScreenAccess* CDirectScreenAccess::NewL(RWsSession& aWs,CWsScreenDevice& aScreenDevice,RWindowBase& aWin,MDirectScreenAccess& aAbort,TBool aRegionTrackingOnly) |
|
384 /** Allocates and constructs the object and adds it to the current active scheduler. |
|
385 |
|
386 This function always causes a flush of the window server buffer. |
|
387 |
|
388 @param aWs A session with the window server. |
|
389 @param aScreenDevice Specifies the characteristics of the screen device to |
|
390 draw to. |
|
391 @param aWin The window to draw to directly. |
|
392 @param aAbort Defines an AbortNow() and a Restart() function which are both |
|
393 called on aborting, as part of the RunL(). Restart() is called from an idle |
|
394 time active object (CIdle). |
|
395 @param aRegionTrackingOnly The screen device and GC are allocated if this is EFalse, |
|
396 but not if it is ETrue. Only the DSA region data and updates to that are |
|
397 available in the latter case. Creating the screen device will trigger the dsa |
|
398 buffer allocationand it is an operation that could fail, should this happen |
|
399 the function will leave. |
|
400 @return The newly constructed object. */ |
|
401 { |
|
402 CDirectScreenAccess* self = new(ELeave) CDirectScreenAccess(aWs,&aScreenDevice,aWin,aAbort); |
|
403 CleanupStack::PushL(self); |
|
404 self->ConstructL(aWs,aRegionTrackingOnly); |
|
405 CleanupStack::Pop(self); |
|
406 return self; |
|
407 } |
|
408 |
|
409 CDirectScreenAccess::~CDirectScreenAccess() |
|
410 { |
|
411 __ASSERT_ALWAYS(!iAborting,Panic(EW32PanicDirectMisuse)); |
|
412 Cancel(); |
|
413 delete iGc; |
|
414 delete iScreenDevice; |
|
415 if (iDrawingRegion) |
|
416 iDrawingRegion->Destroy(); |
|
417 iDirectAccess.Close(); |
|
418 delete iRestart; |
|
419 } |
|
420 |
|
421 void CDirectScreenAccess::ConstructL(RWsSession& aWs,TBool aRegionTrackingOnly) |
|
422 { |
|
423 iScreenNumber = iWsScreenDevice->GetScreenNumber(); |
|
424 |
|
425 if(aRegionTrackingOnly) |
|
426 { |
|
427 iFlags |= EDirectRegionTrackingOnly; |
|
428 } |
|
429 User::LeaveIfError(iDirectAccess.Construct(aRegionTrackingOnly)); |
|
430 |
|
431 iRestart = CIdle::NewL(RDirectScreenAccess::EPriorityVeryHigh-5); |
|
432 CActiveScheduler::Add(this); |
|
433 if (aWs.GetColorModeList(NULL)>1) |
|
434 iFlags |= EDirectCheckModeChange; |
|
435 if (iWsScreenDevice->NumScreenModes() == 1) |
|
436 { |
|
437 if ((iWsScreenDevice->GetRotationsList(0,NULL) == 1) && !aRegionTrackingOnly) |
|
438 { |
|
439 return; |
|
440 } |
|
441 } |
|
442 iFlags |= EDirectCheckSizeModeChange; |
|
443 } |
|
444 |
|
445 void CDirectScreenAccess::CreateScreenObjectsL(TDisplayMode aCurrentMode) |
|
446 { |
|
447 __ASSERT_DEBUG(!(iFlags&EDirectRegionTrackingOnly),Panic(EW32PanicDirectMisuse)); |
|
448 delete iScreenDevice; |
|
449 iScreenDevice = NULL; |
|
450 |
|
451 iScreenDevice = CFbsScreenDevice::NewL(iScreenNumber,aCurrentMode); |
|
452 |
|
453 if (iGc) |
|
454 { |
|
455 iGc->Activate(iScreenDevice); |
|
456 } |
|
457 else |
|
458 { |
|
459 User::LeaveIfError(iScreenDevice->CreateContext(iGc)); |
|
460 if (!(iFlags&EDirectCheckSizeModeChange)) |
|
461 UpdateSizeAndRotation(iGc); |
|
462 } |
|
463 } |
|
464 |
|
465 EXPORT_C void CDirectScreenAccess::StartL() |
|
466 /** Informs the window server that you are going to start direct screen access |
|
467 and sets up a graphics context with which you can draw to the screen. |
|
468 |
|
469 It should also be called to restart direct screen access after Cancel() has |
|
470 been called to stop it. |
|
471 |
|
472 While the DSA is in operation, it is strongly advised that the client should |
|
473 not make any call to WSERV that will affect the visible area of the window in |
|
474 which the DSA is taking place. |
|
475 |
|
476 When WSERV tells the client that it needs to abort its DSA, it waits to receive |
|
477 the acknowledgment from the client that it has done so. However, it doesn't wait |
|
478 for ever, since the client may have entered some long running calculation or even |
|
479 an infinite loop. So WSERV also waits on a timer: if the timer expires before the |
|
480 client acknowledges, then WSERV continues; if, later on, WSERV gets notification |
|
481 from the client that it has aborted the DSA, then WSERV will invalidate the region |
|
482 in which the DSA was taking place, just in case there had been a conflict between |
|
483 the DSA and another client. |
|
484 |
|
485 |
|
486 This function always causes a flush of the window server buffer. */ |
|
487 { |
|
488 if (iDrawingRegion) |
|
489 iDrawingRegion->Destroy(); |
|
490 User::LeaveIfError(iDirectAccess.Request(iDrawingRegion,iStatus,iWindow)); |
|
491 SetActive(); |
|
492 if(!(iFlags&EDirectRegionTrackingOnly)) |
|
493 { |
|
494 if((iFlags&EDirectCheckModeChange) || iScreenDevice == NULL) |
|
495 { |
|
496 TDisplayMode currentDisplayMode = iWsScreenDevice->DisplayMode(); |
|
497 if (iScreenDevice == NULL || currentDisplayMode != iScreenDevice->DisplayMode()) |
|
498 { |
|
499 TRAPD(err,CreateScreenObjectsL(currentDisplayMode)); |
|
500 if (err != KErrNone) |
|
501 { |
|
502 Cancel(); |
|
503 User::Leave(err); |
|
504 } |
|
505 } |
|
506 } |
|
507 if (iFlags&EDirectCheckSizeModeChange) |
|
508 { |
|
509 UpdateSizeAndRotation(iGc); |
|
510 } |
|
511 iGc->SetOrigin(iWindow.AbsPosition()); |
|
512 } |
|
513 iDrawingRegion->ClipRect(iScreenSize); |
|
514 if(!(iFlags&EDirectRegionTrackingOnly)) |
|
515 { |
|
516 iGc->SetClippingRegion(iDrawingRegion); |
|
517 } |
|
518 } |
|
519 |
|
520 TInt CDirectScreenAccess::Restart(TAny* aDirect) //static |
|
521 { |
|
522 STATIC_CAST(CDirectScreenAccess*,aDirect)->Restart(); |
|
523 return(KErrNone); |
|
524 } |
|
525 |
|
526 void CDirectScreenAccess::Restart() |
|
527 { |
|
528 iAbort.Restart(iReason); |
|
529 } |
|
530 |
|
531 void CDirectScreenAccess::UpdateSizeAndRotation(CFbsBitGc*/* aGc*/) |
|
532 { |
|
533 TPixelsAndRotation sizeAndRotation; |
|
534 iWsScreenDevice->GetDefaultScreenSizeAndRotation(sizeAndRotation); |
|
535 iScreenSize = sizeAndRotation.iPixelSize; |
|
536 __ASSERT_ALWAYS(iScreenDevice,Panic(EW32PanicDirectMisuse)); |
|
537 iScreenDevice->SetDeviceOrientation(Graphics2DeviceOrientation(sizeAndRotation.iRotation)); |
|
538 MDisplayMapping* interface = static_cast<MDisplayMapping*> |
|
539 (iWsScreenDevice->GetInterface(MDisplayMapping::ETypeId)); |
|
540 |
|
541 if(interface) |
|
542 { |
|
543 TRect appAreaInDsa; |
|
544 interface->MapCoordinates(EApplicationSpace, iScreenSize, EDirectScreenAccessSpace, appAreaInDsa); |
|
545 if(!iDrawingRegion->BoundingRect().IsEmpty()) |
|
546 { |
|
547 //no point to set draw origin if draw region is empty |
|
548 //this also indicates the place to draw might be outside DSA buffer |
|
549 iScreenDevice->SetDrawDeviceOffset(appAreaInDsa.iTl); |
|
550 } |
|
551 } |
|
552 } |
|
553 |
|
554 void CDirectScreenAccess::RunL() |
|
555 { |
|
556 iAborting = ETrue; |
|
557 iReason = REINTERPRET_CAST(RDirectScreenAccess::TTerminationReasons&,iStatus); |
|
558 iAbort.AbortNow(iReason); |
|
559 iAborting = EFalse; |
|
560 iDirectAccess.Completed(); |
|
561 iRestart->Start(TCallBack(CDirectScreenAccess::Restart,this)); |
|
562 } |
|
563 |
|
564 void CDirectScreenAccess::DoCancel() |
|
565 { |
|
566 iDirectAccess.Cancel(); |
|
567 } |