os/graphics/windowing/windowserver/nga/SERVER/openwfc/Direct.CPP
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// Direct Screen Access class, to allow the client to draw directly to the screen
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
#include <e32base.h>
sl@0
    19
#include "Direct.H"
sl@0
    20
#include "server.h"
sl@0
    21
#include "rootwin.h"
sl@0
    22
#include "wstop.h"
sl@0
    23
#include "panics.h"
sl@0
    24
#include <e32msgqueue.h>
sl@0
    25
sl@0
    26
const TInt KMsgQueueLength = 1;
sl@0
    27
sl@0
    28
CDsaMsgQueue* CDsaMsgQueue::NewL(CWsDirectScreenAccess* aDirect)
sl@0
    29
	{
sl@0
    30
	CDsaMsgQueue* self = new(ELeave)CDsaMsgQueue;
sl@0
    31
	CleanupStack::PushL(self);
sl@0
    32
	self->ConstructL(aDirect);
sl@0
    33
	CleanupStack::Pop(self);
sl@0
    34
	return self;
sl@0
    35
	}
sl@0
    36
sl@0
    37
CDsaMsgQueue::CDsaMsgQueue()
sl@0
    38
{}
sl@0
    39
sl@0
    40
CDsaMsgQueue::~CDsaMsgQueue()
sl@0
    41
	{
sl@0
    42
	delete iAborted;
sl@0
    43
	iSendQueue.Close();
sl@0
    44
	iRecQueue.Close();
sl@0
    45
	}
sl@0
    46
sl@0
    47
void CDsaMsgQueue::ConstructL(CWsDirectScreenAccess* aDirect)
sl@0
    48
	{
sl@0
    49
	iAborted=new(ELeave) CWsAbortDirect(aDirect,this);	
sl@0
    50
	}
sl@0
    51
sl@0
    52
void CDsaMsgQueue::Cancel()
sl@0
    53
	{
sl@0
    54
	//purge the queue of data
sl@0
    55
	TInt ret = KErrNone;
sl@0
    56
	do
sl@0
    57
		{
sl@0
    58
		TInt data = 0;
sl@0
    59
		ret = iRecQueue.Receive(&data,sizeof(TInt));
sl@0
    60
		}while(ret == KErrNone);
sl@0
    61
	iAborted->Cancel();
sl@0
    62
	}
sl@0
    63
sl@0
    64
TInt CDsaMsgQueue::Send(TInt aData)
sl@0
    65
	{
sl@0
    66
	return iSendQueue.Send(&aData,sizeof(TInt));
sl@0
    67
	}
sl@0
    68
sl@0
    69
TInt CDsaMsgQueue::CreateSendQueue()
sl@0
    70
	{
sl@0
    71
	if(iSendQueue.Handle() == 0)
sl@0
    72
		{
sl@0
    73
		return iSendQueue.CreateGlobal(KNullDesC,KMsgQueueLength,sizeof(TInt), EOwnerProcess);
sl@0
    74
		}
sl@0
    75
	else
sl@0
    76
		{
sl@0
    77
		return 0;
sl@0
    78
		}
sl@0
    79
	}
sl@0
    80
sl@0
    81
TInt CDsaMsgQueue::CreateRecQueue()
sl@0
    82
	{
sl@0
    83
	if(iRecQueue.Handle() == 0)
sl@0
    84
		{
sl@0
    85
		return iRecQueue.CreateGlobal(KNullDesC,KMsgQueueLength,sizeof(TInt), EOwnerProcess);
sl@0
    86
		}
sl@0
    87
	else
sl@0
    88
		{
sl@0
    89
		return 0;
sl@0
    90
		}
sl@0
    91
	}
sl@0
    92
sl@0
    93
RMsgQueueBase* CDsaMsgQueue::SendQueue()
sl@0
    94
	{
sl@0
    95
	return &iSendQueue;
sl@0
    96
	}
sl@0
    97
sl@0
    98
RMsgQueueBase* CDsaMsgQueue::RecQueue()
sl@0
    99
	{
sl@0
   100
	return &iRecQueue;
sl@0
   101
	}
sl@0
   102
sl@0
   103
void CDsaMsgQueue::Started()
sl@0
   104
	{
sl@0
   105
	iAborted->Started();
sl@0
   106
	}
sl@0
   107
	
sl@0
   108
void CDsaMsgQueue::Complete()
sl@0
   109
	{
sl@0
   110
	iAborted->Complete(RDirectScreenAccess::ETerminateCancel);	
sl@0
   111
	}
sl@0
   112
sl@0
   113
void CDsaMsgQueue::CompleteAbort()
sl@0
   114
	{
sl@0
   115
	iAborted->Complete(KErrNone);	
sl@0
   116
	}
sl@0
   117
sl@0
   118
TInt CDsaMsgQueue::ReceiveData()
sl@0
   119
	{
sl@0
   120
	TInt data = 0;
sl@0
   121
	iRecQueue.Receive(&data,sizeof(TInt));
sl@0
   122
	return data;
sl@0
   123
	}
sl@0
   124
sl@0
   125
/*CWsAbortDirect*/
sl@0
   126
sl@0
   127
CWsAbortDirect::CWsAbortDirect(CWsDirectScreenAccess* aDirect,CDsaMsgQueue* aParent) : CActive(EDirectAbort), iDirect(aDirect),iParent(aParent)
sl@0
   128
	{
sl@0
   129
	CActiveScheduler::Add(this);
sl@0
   130
	}
sl@0
   131
sl@0
   132
CWsAbortDirect::~CWsAbortDirect()
sl@0
   133
	{
sl@0
   134
	Cancel();
sl@0
   135
	}
sl@0
   136
sl@0
   137
void CWsAbortDirect::Started()
sl@0
   138
	{
sl@0
   139
	iStatus=KRequestPending;
sl@0
   140
	TRequestStatus& status = iStatus;	
sl@0
   141
	iParent->RecQueue()->NotifyDataAvailable(status);
sl@0
   142
	SetActive();
sl@0
   143
	}
sl@0
   144
sl@0
   145
void CWsAbortDirect::RunL()
sl@0
   146
	{
sl@0
   147
	iParent->ReceiveData();
sl@0
   148
	iParent->RecQueue()->CancelDataAvailable();
sl@0
   149
	iDirect->Aborted();
sl@0
   150
	}
sl@0
   151
sl@0
   152
void CWsAbortDirect::DoCancel()
sl@0
   153
	{
sl@0
   154
	iParent->RecQueue()->CancelDataAvailable();
sl@0
   155
	if (iStatus==KRequestPending)
sl@0
   156
		{
sl@0
   157
		Complete(KErrNone);
sl@0
   158
		}
sl@0
   159
	}
sl@0
   160
sl@0
   161
void CWsAbortDirect::Complete(TInt aReason)
sl@0
   162
	{
sl@0
   163
	if(IsActive())
sl@0
   164
		{
sl@0
   165
		TRequestStatus* status=&iStatus;
sl@0
   166
		iParent->RecQueue()->CancelDataAvailable();
sl@0
   167
		RThread().RequestComplete(status,aReason);
sl@0
   168
		}
sl@0
   169
	}
sl@0
   170
sl@0
   171
sl@0
   172
/*CWsDirectScreenAccess*/
sl@0
   173
sl@0
   174
CWsDirectScreenAccess* CWsDirectScreenAccess::NewL(CWsClient* aOwner,TBool aRegionTrackingOnly)
sl@0
   175
	{
sl@0
   176
	CWsDirectScreenAccess* self = new(ELeave) CWsDirectScreenAccess(aOwner);
sl@0
   177
	CleanupStack::PushL(self);
sl@0
   178
	self->ConstructL(aRegionTrackingOnly);
sl@0
   179
	CleanupStack::Pop(self);
sl@0
   180
	return self;
sl@0
   181
	}
sl@0
   182
sl@0
   183
CWsDirectScreenAccess::~CWsDirectScreenAccess()
sl@0
   184
	{
sl@0
   185
	iVisible.Close();
sl@0
   186
	if (iStatus!=EDirectStatusTimeNotCreated)
sl@0
   187
		{
sl@0
   188
		if (iStatus==EDirectStatusRunning)
sl@0
   189
			AbortNow();
sl@0
   190
		if (iStatus>=EDirectStatusAborted)
sl@0
   191
			CorrectScreen();
sl@0
   192
		}
sl@0
   193
	WS_ASSERT_DEBUG(!OnQueue(), EWsPanicDirectScreenAccess);
sl@0
   194
	if(!iRegionTrackingOnly)
sl@0
   195
		{
sl@0
   196
		CScreen* screen = Screen();
sl@0
   197
		__ASSERT_DEBUG(screen,Panic(EWsPanicNoScreen));
sl@0
   198
		screen->ReleaseDsaScreenDevice();
sl@0
   199
		}
sl@0
   200
	delete iMsgQueue;
sl@0
   201
	}
sl@0
   202
sl@0
   203
void CWsDirectScreenAccess::ConstructL(TBool aRegionTrackingOnly)
sl@0
   204
	{
sl@0
   205
	NewObjL();
sl@0
   206
	iMsgQueue = CDsaMsgQueue::NewL(this);
sl@0
   207
	iStatus=EDirectStatusNone;
sl@0
   208
	iRegionTrackingOnly = aRegionTrackingOnly;
sl@0
   209
	if(!iRegionTrackingOnly)
sl@0
   210
		{
sl@0
   211
		//The Direct Screen Access object is going to be used to draw to the screen so we need to:
sl@0
   212
		//1)allocate the buffer
sl@0
   213
		//2)initialize the DSA device and surface
sl@0
   214
		CScreen* screen = Screen();
sl@0
   215
		__ASSERT_DEBUG(screen,Panic(EWsPanicNoScreen));
sl@0
   216
		screen->AcquireDsaScreenDeviceL();	
sl@0
   217
		}
sl@0
   218
	}
sl@0
   219
sl@0
   220
void CWsDirectScreenAccess::Request(TInt handle)
sl@0
   221
	{
sl@0
   222
	if (iStatus!=EDirectStatusNone)
sl@0
   223
		{
sl@0
   224
		if (iStatus==EDirectStatusCompleted)
sl@0
   225
			{
sl@0
   226
			iMsgQueue->Cancel();
sl@0
   227
			}
sl@0
   228
		else
sl@0
   229
			{
sl@0
   230
			iWsOwner->PPanic(EWservPanicDirectMisuse);
sl@0
   231
			}
sl@0
   232
		}
sl@0
   233
	iWsOwner->HandleToClientWindow(handle,&iWin);
sl@0
   234
	STACK_REGION region;
sl@0
   235
	iWin->GenerateTopRegion(region);
sl@0
   236
	
sl@0
   237
	//clip the draw region with DSA buffer
sl@0
   238
	TRect dsaBuffer(TPoint(0,0), iScreen->DSASizeInPixels());
sl@0
   239
	MWsDisplayMapping *dispMap = iScreen->DisplayMapping();
sl@0
   240
	TRect dsaBufferInAppSpace;
sl@0
   241
	if(dispMap)
sl@0
   242
		{
sl@0
   243
		dispMap->MapCoordinates(EDirectScreenAccessSpace,dsaBuffer,EApplicationSpace,dsaBufferInAppSpace);
sl@0
   244
		}
sl@0
   245
	else
sl@0
   246
		{
sl@0
   247
		dsaBufferInAppSpace = dsaBuffer;
sl@0
   248
		}
sl@0
   249
	region.ClipRect(dsaBufferInAppSpace);
sl@0
   250
	const TInt regionCount=region.Count();
sl@0
   251
	region.Close();
sl@0
   252
	SetReply(regionCount);
sl@0
   253
	iStatus=EDirectStatusInitialising;
sl@0
   254
	}
sl@0
   255
sl@0
   256
void CWsDirectScreenAccess::GetRegion(TInt aNumRects)
sl@0
   257
	{
sl@0
   258
#if defined(_DEBUG)
sl@0
   259
	if (iStatus!=EDirectStatusInitialising)
sl@0
   260
		iWsOwner->PPanic(EWservPanicDirectMisuse);
sl@0
   261
#endif
sl@0
   262
	STACK_REGION winVisibleRegion, region;
sl@0
   263
	iWin->GenerateTopRegion(winVisibleRegion);
sl@0
   264
	//clip the draw region with DSA buffer
sl@0
   265
	TRect dsaBuffer(TPoint(0,0), iScreen->DSASizeInPixels());
sl@0
   266
	MWsDisplayMapping *dispMap = iScreen->DisplayMapping();
sl@0
   267
	TRect dsaBufferInAppSpace;
sl@0
   268
	if(dispMap)
sl@0
   269
		{
sl@0
   270
		dispMap->MapCoordinates(EDirectScreenAccessSpace,dsaBuffer,EApplicationSpace,dsaBufferInAppSpace);
sl@0
   271
		}
sl@0
   272
	else
sl@0
   273
		{
sl@0
   274
		dsaBufferInAppSpace = dsaBuffer;
sl@0
   275
		}
sl@0
   276
	region.Copy(winVisibleRegion);
sl@0
   277
	region.ClipRect(dsaBufferInAppSpace);
sl@0
   278
	
sl@0
   279
	const TInt regionCount=region.Count();
sl@0
   280
	if (region.Count()==aNumRects)
sl@0
   281
		{
sl@0
   282
		iVisible.Copy(winVisibleRegion);
sl@0
   283
		if (iVisible.CheckError())
sl@0
   284
			{
sl@0
   285
			iStatus=EDirectStatusNone;
sl@0
   286
			SetReply(KErrNotReady);
sl@0
   287
			}
sl@0
   288
		else
sl@0
   289
			{
sl@0
   290
			TInt error = Initiate();
sl@0
   291
			
sl@0
   292
			if (!error)
sl@0
   293
				{
sl@0
   294
				TPtrC8 rectList(REINTERPRET_CAST(const TUint8*,region.RectangleList()),region.Count()*sizeof(TRect));
sl@0
   295
				CWsClient::ReplyBuf(rectList);
sl@0
   296
				iStatus=EDirectStatusRunning;
sl@0
   297
				iMsgQueue->Started();
sl@0
   298
				SetReply(KMaxTInt);
sl@0
   299
				}
sl@0
   300
			else
sl@0
   301
				{
sl@0
   302
				iStatus=EDirectStatusNone;
sl@0
   303
				SetReply(error);
sl@0
   304
				}
sl@0
   305
			}
sl@0
   306
		}
sl@0
   307
	else
sl@0
   308
		{
sl@0
   309
		SetReply(region.Count());
sl@0
   310
		}
sl@0
   311
	region.Close();
sl@0
   312
	winVisibleRegion.Close();
sl@0
   313
	}
sl@0
   314
sl@0
   315
void CWsDirectScreenAccess::Cancel()
sl@0
   316
	{
sl@0
   317
	TInt ret = 0;
sl@0
   318
	switch (iStatus)
sl@0
   319
		{
sl@0
   320
#if defined(_DEBUG)
sl@0
   321
	case EDirectStatusInitialising:
sl@0
   322
		iWsOwner->PPanic(EWservPanicDirectMisuse);
sl@0
   323
#endif
sl@0
   324
	case EDirectStatusNone:
sl@0
   325
		break;
sl@0
   326
	case EDirectStatusRunning:
sl@0
   327
		Terminate1();
sl@0
   328
		Terminate2(); 
sl@0
   329
		/*Fall through*/
sl@0
   330
	case EDirectStatusCanceling:
sl@0
   331
		ret = 1;
sl@0
   332
		iMsgQueue->Send(RDirectScreenAccess::ETerminateCancel);	
sl@0
   333
		break;
sl@0
   334
	case EDirectStatusAbortedWindow:
sl@0
   335
	case EDirectStatusAbortedGlobal:
sl@0
   336
		CorrectScreen();
sl@0
   337
		break;
sl@0
   338
	case EDirectStatusCompleted:
sl@0
   339
		break;
sl@0
   340
	default:
sl@0
   341
			{
sl@0
   342
			}
sl@0
   343
		}
sl@0
   344
	SetReply(ret);
sl@0
   345
	iStatus=EDirectStatusNone;
sl@0
   346
	}
sl@0
   347
sl@0
   348
void CWsDirectScreenAccess::Aborted()
sl@0
   349
	{
sl@0
   350
	switch (iStatus)
sl@0
   351
		{
sl@0
   352
	case EDirectStatusRunning:
sl@0
   353
		Terminate1();
sl@0
   354
		Terminate2();
sl@0
   355
		iStatus=EDirectStatusCanceling;
sl@0
   356
		break;
sl@0
   357
	case EDirectStatusAbortedWindow:
sl@0
   358
	case EDirectStatusAbortedGlobal:
sl@0
   359
		CorrectScreen(); 
sl@0
   360
		/*Fall Through*/ 
sl@0
   361
	case EDirectStatusCompleted:
sl@0
   362
		iStatus=EDirectStatusNone;
sl@0
   363
		break;
sl@0
   364
	default:
sl@0
   365
		iWsOwner->PPanic(EWservPanicDirectMisuse);
sl@0
   366
		}
sl@0
   367
	}
sl@0
   368
sl@0
   369
void CWsDirectScreenAccess::AbortNow()
sl@0
   370
	{
sl@0
   371
	if (iStatus!=EDirectStatusRunning)
sl@0
   372
		{
sl@0
   373
		iWsOwner->PPanic(EWservPanicDirectMisuse);
sl@0
   374
		}
sl@0
   375
	SignalAbort(RDirectScreenAccess::ETerminateRegion);
sl@0
   376
	TRequestStatus timerStatus;
sl@0
   377
	RTimer& timer=CWsTop::Timer();
sl@0
   378
	timer.After(timerStatus,400000);		//0.4secs
sl@0
   379
	User::WaitForRequest(iMsgQueue->Status(),timerStatus);
sl@0
   380
	if (timerStatus!=KRequestPending)
sl@0
   381
		{
sl@0
   382
		Abort();
sl@0
   383
		}
sl@0
   384
	else
sl@0
   385
		{
sl@0
   386
		CancelAbortObject();
sl@0
   387
		timer.Cancel();
sl@0
   388
		User::WaitForRequest(timerStatus);
sl@0
   389
		}
sl@0
   390
	}
sl@0
   391
sl@0
   392
void CWsDirectScreenAccess::SignalAbort(RDirectScreenAccess::TTerminationReasons aReason)
sl@0
   393
	{
sl@0
   394
	iAbortReason=aReason;
sl@0
   395
	if (iStatus==EDirectStatusAbortedWindow)
sl@0
   396
		{
sl@0
   397
		WS_ASSERT_DEBUG(iAbortReason>RDirectScreenAccess::ETerminateRegion, EWsPanicDirectScreenAccess);
sl@0
   398
		Terminate2();
sl@0
   399
		return;
sl@0
   400
		}
sl@0
   401
	if (iStatus!=EDirectStatusRunning)
sl@0
   402
		{
sl@0
   403
		iWsOwner->PPanic(EWservPanicDirectMisuse);
sl@0
   404
		}
sl@0
   405
	iMsgQueue->Send(aReason);
sl@0
   406
	}
sl@0
   407
sl@0
   408
void CWsDirectScreenAccess::CancelAbortObject()
sl@0
   409
	{
sl@0
   410
	iMsgQueue->Complete();
sl@0
   411
	iMsgQueue->Cancel();
sl@0
   412
	iStatus=EDirectStatusNone;
sl@0
   413
	Terminate1();
sl@0
   414
	Terminate2();
sl@0
   415
	}
sl@0
   416
sl@0
   417
void CWsDirectScreenAccess::Abort()
sl@0
   418
	{
sl@0
   419
	if ( iStatus == EDirectStatusRunning ) 	
sl@0
   420
		{
sl@0
   421
		Terminate1();
sl@0
   422
		if (iMsgQueue->Status()==KRequestPending)
sl@0
   423
			iStatus=(iAbortReason<=RDirectScreenAccess::ETerminateRegion ? EDirectStatusAbortedWindow:EDirectStatusAbortedGlobal);
sl@0
   424
		else
sl@0
   425
			iStatus=EDirectStatusCompleted;
sl@0
   426
		if (iStatus!=EDirectStatusAbortedWindow)
sl@0
   427
			Terminate2();
sl@0
   428
		}
sl@0
   429
	}
sl@0
   430
sl@0
   431
TInt CWsDirectScreenAccess::GetSendQueue()
sl@0
   432
	{
sl@0
   433
	TInt ret = iMsgQueue->CreateSendQueue();
sl@0
   434
	if(ret == KErrNone)
sl@0
   435
		{
sl@0
   436
		iWsOwner->SetResponseHandle(iMsgQueue->SendQueue());	
sl@0
   437
		}
sl@0
   438
	return ret;
sl@0
   439
	}
sl@0
   440
sl@0
   441
TInt CWsDirectScreenAccess::GetRecQueue()
sl@0
   442
	{
sl@0
   443
	TInt ret = iMsgQueue->CreateRecQueue();
sl@0
   444
	if(ret == KErrNone)
sl@0
   445
		{
sl@0
   446
		iWsOwner->SetResponseHandle(iMsgQueue->RecQueue());	
sl@0
   447
		}
sl@0
   448
	return ret;
sl@0
   449
	}
sl@0
   450
sl@0
   451
void CWsDirectScreenAccess::CommandL(TInt aOpcode,const TAny* aCmdData)
sl@0
   452
	{
sl@0
   453
	TWsDirectCmdUnion pData;
sl@0
   454
	pData.any=aCmdData;
sl@0
   455
	switch(aOpcode)
sl@0
   456
		{
sl@0
   457
		case EWsDirectOpFree:
sl@0
   458
			delete this;
sl@0
   459
			break;
sl@0
   460
		case EWsDirectOpRequest:
sl@0
   461
			Request(*pData.Int);
sl@0
   462
			break;
sl@0
   463
		case EWsDirectOpInitFailed:
sl@0
   464
	#if defined(_DEBUG)
sl@0
   465
			if (iStatus!=EDirectStatusInitialising)
sl@0
   466
				{
sl@0
   467
				iWsOwner->PPanic(EWservPanicDirectMisuse);
sl@0
   468
				}
sl@0
   469
	#endif
sl@0
   470
			iStatus=EDirectStatusNone;
sl@0
   471
			break;
sl@0
   472
		case EWsDirectOpGetRegion:
sl@0
   473
			GetRegion(*pData.Int);
sl@0
   474
			break;
sl@0
   475
		case EWsDirectOpCancel:
sl@0
   476
			Cancel();
sl@0
   477
			break;
sl@0
   478
		case EWsDirectOpGetSendQueue:
sl@0
   479
			GetSendQueue();
sl@0
   480
			break;
sl@0
   481
		case EWsDirectOpGetRecQueue:
sl@0
   482
			GetRecQueue();
sl@0
   483
			break;
sl@0
   484
		default:
sl@0
   485
			OwnerPanic(EWservPanicOpcode);
sl@0
   486
			break;
sl@0
   487
		}
sl@0
   488
	}
sl@0
   489
sl@0
   490
TInt CWsDirectScreenAccess::Initiate()
sl@0
   491
	{
sl@0
   492
	const TInt err = iWin->AddDSA(*this);
sl@0
   493
	if(err)
sl@0
   494
		return err;
sl@0
   495
sl@0
   496
	iScreen->AddDirect(*this);
sl@0
   497
	return KErrNone;
sl@0
   498
	}
sl@0
   499
sl@0
   500
static TBool RegionsMatch(const TRegion & aOne, const TRegion & aTwo)
sl@0
   501
	{
sl@0
   502
	// Check if the regions have equal areas.
sl@0
   503
	const TRect* rect1 = aOne.RectangleList();
sl@0
   504
	TUint area1 = 0;
sl@0
   505
	for(TInt i = 0; i < aOne.Count(); ++i)
sl@0
   506
		{
sl@0
   507
		area1 += (rect1->Width() * rect1->Height());
sl@0
   508
		rect1++;
sl@0
   509
		}
sl@0
   510
sl@0
   511
	const TRect* rect2 = aTwo.RectangleList();
sl@0
   512
	TUint area2 = 0;
sl@0
   513
	for(TInt i = 0; i < aTwo.Count(); ++i)
sl@0
   514
		{
sl@0
   515
		area2 += (rect2->Width() * rect2->Height());
sl@0
   516
		rect2++;
sl@0
   517
		}
sl@0
   518
	
sl@0
   519
	if(area1 != area2)
sl@0
   520
		{
sl@0
   521
		return EFalse;
sl@0
   522
		}
sl@0
   523
sl@0
   524
	// Check if one region is completely contained within the other.
sl@0
   525
	STACK_REGION tempRegion;
sl@0
   526
	tempRegion.Copy(aOne);	
sl@0
   527
	tempRegion.SubRegion(aTwo);
sl@0
   528
sl@0
   529
	const TBool ret(tempRegion.IsEmpty());
sl@0
   530
	tempRegion.Close();
sl@0
   531
sl@0
   532
	return ret;
sl@0
   533
	}
sl@0
   534
sl@0
   535
TBool CWsDirectScreenAccess::IsAbortRequired(const TRegion& aTopVisibleRegion) const
sl@0
   536
	{
sl@0
   537
	return ( iStatus == EDirectStatusRunning ) && !RegionsMatch(aTopVisibleRegion, iVisible);
sl@0
   538
	}
sl@0
   539
sl@0
   540
void CWsDirectScreenAccess::Terminate1()
sl@0
   541
	{
sl@0
   542
	WS_ASSERT_DEBUG(!iWin->DSAs().IsEmpty(), EWsPanicDirectScreenAccess);
sl@0
   543
	iWin->RemoveDSA(*this);
sl@0
   544
	}
sl@0
   545
sl@0
   546
void CWsDirectScreenAccess::Terminate2()
sl@0
   547
	{
sl@0
   548
	iScreen->RemoveDirect(*this);
sl@0
   549
	WS_ASSERT_DEBUG(!OnQueue(), EWsPanicDirectScreenAccess);
sl@0
   550
	}
sl@0
   551
sl@0
   552
void CWsDirectScreenAccess::CorrectScreen()
sl@0
   553
	{
sl@0
   554
	if (iAbortReason<=RDirectScreenAccess::ETerminateRegion)
sl@0
   555
		{
sl@0
   556
		Terminate2();
sl@0
   557
		RootWindow()->Invalidate(&iVisible);
sl@0
   558
		}
sl@0
   559
	else
sl@0
   560
		RootWindow()->InvalidateWholeScreen();
sl@0
   561
sl@0
   562
	WS_ASSERT_DEBUG(!OnQueue(), EWsPanicDirectScreenAccess);
sl@0
   563
	iScreen->UpdateDsa();
sl@0
   564
	}
sl@0
   565
sl@0
   566
#if defined(_DEBUG)
sl@0
   567
TBool CWsDirectScreenAccess::OnQueue()
sl@0
   568
	{
sl@0
   569
	return iScreen->IsDirectOnQueue(this);
sl@0
   570
	}
sl@0
   571
#endif