os/graphics/windowing/windowserver/nonnga/SERVER/Direct.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
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
static TBool RegionsMatch(const TRegion & aOne, const TRegion & aTwo);		
sl@0
    29
sl@0
    30
sl@0
    31
CDsaMsgQueue* CDsaMsgQueue::NewL(CWsDirectScreenAccess* aDirect)
sl@0
    32
	{
sl@0
    33
	CDsaMsgQueue* self = new(ELeave)CDsaMsgQueue;
sl@0
    34
	CleanupStack::PushL(self);
sl@0
    35
	self->ConstructL(aDirect);
sl@0
    36
	CleanupStack::Pop(self);
sl@0
    37
	return self;
sl@0
    38
	}
sl@0
    39
sl@0
    40
CDsaMsgQueue::CDsaMsgQueue()
sl@0
    41
{}
sl@0
    42
sl@0
    43
CDsaMsgQueue::~CDsaMsgQueue()
sl@0
    44
	{
sl@0
    45
	delete iAborted;
sl@0
    46
	iSendQueue.Close();
sl@0
    47
	iRecQueue.Close();
sl@0
    48
	}
sl@0
    49
sl@0
    50
void CDsaMsgQueue::ConstructL(CWsDirectScreenAccess* aDirect)
sl@0
    51
	{
sl@0
    52
	iAborted=new(ELeave) CWsAbortDirect(aDirect,this);	
sl@0
    53
	}
sl@0
    54
sl@0
    55
void CDsaMsgQueue::Cancel()
sl@0
    56
	{
sl@0
    57
	//purge the queue of data
sl@0
    58
	TInt ret = KErrNone;
sl@0
    59
	do
sl@0
    60
		{
sl@0
    61
		TInt data = 0;
sl@0
    62
		ret = iRecQueue.Receive(&data,sizeof(TInt));
sl@0
    63
		}while(ret == KErrNone);
sl@0
    64
	iAborted->Cancel();
sl@0
    65
	}
sl@0
    66
sl@0
    67
TInt CDsaMsgQueue::Send(TInt aData)
sl@0
    68
	{
sl@0
    69
	return iSendQueue.Send(&aData,sizeof(TInt));
sl@0
    70
	}
sl@0
    71
sl@0
    72
TInt CDsaMsgQueue::CreateSendQueue()
sl@0
    73
	{
sl@0
    74
	if(iSendQueue.Handle() == 0)
sl@0
    75
		{
sl@0
    76
		return iSendQueue.CreateGlobal(KNullDesC,KMsgQueueLength,sizeof(TInt), EOwnerProcess);
sl@0
    77
		}
sl@0
    78
	else
sl@0
    79
		{
sl@0
    80
		return 0;
sl@0
    81
		}
sl@0
    82
	}
sl@0
    83
sl@0
    84
TInt CDsaMsgQueue::CreateRecQueue()
sl@0
    85
	{
sl@0
    86
	if(iRecQueue.Handle() == 0)
sl@0
    87
		{
sl@0
    88
		return iRecQueue.CreateGlobal(KNullDesC,KMsgQueueLength,sizeof(TInt), EOwnerProcess);
sl@0
    89
		}
sl@0
    90
	else
sl@0
    91
		{
sl@0
    92
		return 0;
sl@0
    93
		}
sl@0
    94
	}
sl@0
    95
sl@0
    96
RMsgQueueBase* CDsaMsgQueue::SendQueue()
sl@0
    97
	{
sl@0
    98
	return &iSendQueue;
sl@0
    99
	}
sl@0
   100
sl@0
   101
RMsgQueueBase* CDsaMsgQueue::RecQueue()
sl@0
   102
	{
sl@0
   103
	return &iRecQueue;
sl@0
   104
	}
sl@0
   105
sl@0
   106
void CDsaMsgQueue::Started()
sl@0
   107
	{
sl@0
   108
	iAborted->Started();
sl@0
   109
	}
sl@0
   110
	
sl@0
   111
void CDsaMsgQueue::Complete()
sl@0
   112
	{
sl@0
   113
	iAborted->Complete(RDirectScreenAccess::ETerminateCancel);	
sl@0
   114
	}
sl@0
   115
sl@0
   116
void CDsaMsgQueue::CompleteAbort()
sl@0
   117
	{
sl@0
   118
	iAborted->Complete(KErrNone);	
sl@0
   119
	}
sl@0
   120
sl@0
   121
TInt CDsaMsgQueue::ReceiveData()
sl@0
   122
	{
sl@0
   123
	TInt data = 0;
sl@0
   124
	iRecQueue.Receive(&data,sizeof(TInt));
sl@0
   125
	return data;
sl@0
   126
	}
sl@0
   127
sl@0
   128
/*CWsAbortDirect*/
sl@0
   129
sl@0
   130
CWsAbortDirect::CWsAbortDirect(CWsDirectScreenAccess* aDirect,CDsaMsgQueue* aParent) : CActive(EDirectAbort), iDirect(aDirect),iParent(aParent)
sl@0
   131
	{
sl@0
   132
	CActiveScheduler::Add(this);
sl@0
   133
	}
sl@0
   134
sl@0
   135
CWsAbortDirect::~CWsAbortDirect()
sl@0
   136
	{
sl@0
   137
	Cancel();
sl@0
   138
	}
sl@0
   139
sl@0
   140
void CWsAbortDirect::Started()
sl@0
   141
	{
sl@0
   142
	iStatus=KRequestPending;
sl@0
   143
	TRequestStatus& status = iStatus;	
sl@0
   144
	iParent->RecQueue()->NotifyDataAvailable(status);
sl@0
   145
	SetActive();
sl@0
   146
	}
sl@0
   147
sl@0
   148
void CWsAbortDirect::RunL()
sl@0
   149
	{
sl@0
   150
	iParent->ReceiveData();
sl@0
   151
	iParent->RecQueue()->CancelDataAvailable();
sl@0
   152
	iDirect->Aborted();
sl@0
   153
	}
sl@0
   154
sl@0
   155
void CWsAbortDirect::DoCancel()
sl@0
   156
	{
sl@0
   157
	iParent->RecQueue()->CancelDataAvailable();
sl@0
   158
	if (iStatus==KRequestPending)
sl@0
   159
		{
sl@0
   160
		Complete(KErrNone);
sl@0
   161
		}
sl@0
   162
	}
sl@0
   163
sl@0
   164
void CWsAbortDirect::Complete(TInt aReason)
sl@0
   165
	{
sl@0
   166
	if(IsActive())
sl@0
   167
		{
sl@0
   168
		TRequestStatus* status=&iStatus;
sl@0
   169
		RThread().RequestComplete(status,aReason);
sl@0
   170
		}
sl@0
   171
	}
sl@0
   172
sl@0
   173
sl@0
   174
/*CWsDirectScreenAccess*/
sl@0
   175
sl@0
   176
CWsDirectScreenAccess* CWsDirectScreenAccess::NewL(CWsClient* aOwner)
sl@0
   177
	{
sl@0
   178
	CWsDirectScreenAccess* self = new(ELeave) CWsDirectScreenAccess(aOwner);
sl@0
   179
	CleanupStack::PushL(self);
sl@0
   180
	self->ConstructL();
sl@0
   181
	CleanupStack::Pop(self);
sl@0
   182
	return self;
sl@0
   183
	}
sl@0
   184
sl@0
   185
CWsDirectScreenAccess::~CWsDirectScreenAccess()
sl@0
   186
	{
sl@0
   187
	DeleteRegionSyncWatchcat();
sl@0
   188
	iFrozenRegion.Close();
sl@0
   189
	iVisible.Close();
sl@0
   190
	if (iStatus!=EDirectStatusTimeNotCreated)
sl@0
   191
		{
sl@0
   192
		if (iStatus==EDirectStatusRunning)
sl@0
   193
			AbortNow();
sl@0
   194
		if (iStatus>=EDirectStatusAborted)
sl@0
   195
			CorrectScreen();
sl@0
   196
		}
sl@0
   197
	WS_ASSERT_DEBUG(!OnQueue(), EWsPanicDirectScreenAccess);
sl@0
   198
	delete iMsgQueue;
sl@0
   199
	}
sl@0
   200
sl@0
   201
void CWsDirectScreenAccess::ConstructL()
sl@0
   202
	{
sl@0
   203
	NewObjL();
sl@0
   204
	iMsgQueue = CDsaMsgQueue::NewL(this);
sl@0
   205
	iStatus=EDirectStatusNone;
sl@0
   206
	}
sl@0
   207
sl@0
   208
void CWsDirectScreenAccess::Request(TInt handle)
sl@0
   209
	{
sl@0
   210
	if (iStatus!=EDirectStatusNone)
sl@0
   211
		{
sl@0
   212
		if (iStatus==EDirectStatusCompleted)
sl@0
   213
			{
sl@0
   214
			iMsgQueue->Cancel();
sl@0
   215
			}
sl@0
   216
		else
sl@0
   217
			{
sl@0
   218
			iWsOwner->PPanic(EWservPanicDirectMisuse);
sl@0
   219
			}
sl@0
   220
		}
sl@0
   221
	iWsOwner->HandleToClientWindow(handle,&iWin);
sl@0
   222
	iScreen=iWin->Screen();
sl@0
   223
	STACK_REGION region;
sl@0
   224
	iWin->GenerateTopRegion(region);
sl@0
   225
	const TInt regionCount=region.Count();
sl@0
   226
	region.Close();
sl@0
   227
	SetReply(regionCount);
sl@0
   228
	iStatus=EDirectStatusInitialising;
sl@0
   229
	}
sl@0
   230
sl@0
   231
void CWsDirectScreenAccess::GetRegion(TInt aNumRects)
sl@0
   232
	{
sl@0
   233
#if defined(_DEBUG)
sl@0
   234
	if (iStatus!=EDirectStatusInitialising)
sl@0
   235
		iWsOwner->PPanic(EWservPanicDirectMisuse);
sl@0
   236
#endif
sl@0
   237
	STACK_REGION region;
sl@0
   238
	iWin->GenerateTopRegion(region);
sl@0
   239
	const TInt regionCount=region.Count();
sl@0
   240
	if (region.Count()==aNumRects)
sl@0
   241
		{
sl@0
   242
		iVisible.Copy(region);
sl@0
   243
		if (iVisible.CheckError())
sl@0
   244
			{
sl@0
   245
			iStatus=EDirectStatusNone;
sl@0
   246
			SetReply(KErrNotReady);
sl@0
   247
			}
sl@0
   248
		else
sl@0
   249
			{
sl@0
   250
			TPtrC8 rectList(REINTERPRET_CAST(const TUint8*,region.RectangleList()),region.Count()*sizeof(TRect));
sl@0
   251
			CWsClient::ReplyBuf(rectList);
sl@0
   252
			iStatus=EDirectStatusRunning;
sl@0
   253
			Initiate();
sl@0
   254
			iMsgQueue->Started();
sl@0
   255
			SetReply(KMaxTInt);
sl@0
   256
			}
sl@0
   257
		}
sl@0
   258
	else
sl@0
   259
		{
sl@0
   260
		SetReply(region.Count());
sl@0
   261
		}
sl@0
   262
	region.Close();
sl@0
   263
	}
sl@0
   264
sl@0
   265
void CWsDirectScreenAccess::Cancel()
sl@0
   266
	{
sl@0
   267
	TInt ret = 0;
sl@0
   268
	switch (iStatus)
sl@0
   269
		{
sl@0
   270
#if defined(_DEBUG)
sl@0
   271
	case EDirectStatusInitialising:
sl@0
   272
		iWsOwner->PPanic(EWservPanicDirectMisuse);
sl@0
   273
#endif
sl@0
   274
	case EDirectStatusNone:
sl@0
   275
		break;
sl@0
   276
	case EDirectStatusRunning:
sl@0
   277
		Terminate1();
sl@0
   278
		Terminate2(); 
sl@0
   279
		/*Fall through*/
sl@0
   280
	case EDirectStatusCanceling:
sl@0
   281
		ret = 1;
sl@0
   282
		iMsgQueue->Send(RDirectScreenAccess::ETerminateCancel);	
sl@0
   283
		break;
sl@0
   284
	case EDirectStatusAbortedWindow:
sl@0
   285
	case EDirectStatusAbortedGlobal:
sl@0
   286
		CorrectScreen();
sl@0
   287
		break;
sl@0
   288
	case EDirectStatusCompleted:
sl@0
   289
		break;
sl@0
   290
	default:
sl@0
   291
			{
sl@0
   292
			}
sl@0
   293
		}
sl@0
   294
	SetReply(ret);
sl@0
   295
	iStatus=EDirectStatusNone;
sl@0
   296
	}
sl@0
   297
sl@0
   298
void CWsDirectScreenAccess::Aborted()
sl@0
   299
	{
sl@0
   300
	switch (iStatus)
sl@0
   301
		{
sl@0
   302
	case EDirectStatusRunning:
sl@0
   303
		Terminate1();
sl@0
   304
		Terminate2();
sl@0
   305
		iStatus=EDirectStatusCanceling;
sl@0
   306
		break;
sl@0
   307
	case EDirectStatusAbortedWindow:
sl@0
   308
	case EDirectStatusAbortedGlobal:
sl@0
   309
		CorrectScreen(); 
sl@0
   310
		/*Fall through*/
sl@0
   311
	case EDirectStatusCompleted:
sl@0
   312
		iStatus=EDirectStatusNone;
sl@0
   313
		break;
sl@0
   314
	default:
sl@0
   315
		iWsOwner->PPanic(EWservPanicDirectMisuse);
sl@0
   316
		}
sl@0
   317
	}
sl@0
   318
sl@0
   319
void CWsDirectScreenAccess::AbortNow()
sl@0
   320
	{
sl@0
   321
	if (iStatus!=EDirectStatusRunning)
sl@0
   322
		{
sl@0
   323
		iWsOwner->PPanic(EWservPanicDirectMisuse);
sl@0
   324
		}
sl@0
   325
	SignalAbort(RDirectScreenAccess::ETerminateRegion);
sl@0
   326
	TRequestStatus timerStatus;
sl@0
   327
	RTimer& timer=CWsTop::Timer();
sl@0
   328
	timer.After(timerStatus,400000);		//0.4secs
sl@0
   329
	User::WaitForRequest(iMsgQueue->Status(),timerStatus);
sl@0
   330
	if (timerStatus!=KRequestPending)
sl@0
   331
		{
sl@0
   332
		Abort();
sl@0
   333
		}
sl@0
   334
	else
sl@0
   335
		{
sl@0
   336
		CancelAbortObject();
sl@0
   337
		timer.Cancel();
sl@0
   338
		User::WaitForRequest(timerStatus);
sl@0
   339
		}
sl@0
   340
	}
sl@0
   341
sl@0
   342
void CWsDirectScreenAccess::SignalAbort(RDirectScreenAccess::TTerminationReasons aReason)
sl@0
   343
	{
sl@0
   344
	DeleteRegionSyncWatchcat();
sl@0
   345
	
sl@0
   346
	iAbortReason=aReason;
sl@0
   347
	if (iStatus==EDirectStatusAbortedWindow)
sl@0
   348
		{
sl@0
   349
		WS_ASSERT_DEBUG(iAbortReason>RDirectScreenAccess::ETerminateRegion, EWsPanicDirectScreenAccess);
sl@0
   350
		Terminate2();
sl@0
   351
		return;
sl@0
   352
		}
sl@0
   353
	if (iStatus!=EDirectStatusRunning)
sl@0
   354
		{
sl@0
   355
		iWsOwner->PPanic(EWservPanicDirectMisuse);
sl@0
   356
		}
sl@0
   357
	if (RDirectScreenAccess::ETerminateCancel != aReason)
sl@0
   358
		{
sl@0
   359
		TInt err;
sl@0
   360
		TRAP(err, iRegionSync = CWsDirectScreenAccess::CDSARegionSyncTimer::NewL( *this ) );
sl@0
   361
		if ( KErrNone == err )
sl@0
   362
			{
sl@0
   363
			iFrozenRegion.Copy( iVisible );			
sl@0
   364
			Screen()->DSARegionSyncStart( *this );
sl@0
   365
			}
sl@0
   366
		}
sl@0
   367
	iMsgQueue->Send(aReason);
sl@0
   368
	}
sl@0
   369
sl@0
   370
void CWsDirectScreenAccess::CancelAbortObject()
sl@0
   371
	{
sl@0
   372
	iMsgQueue->Complete();
sl@0
   373
	iMsgQueue->Cancel();
sl@0
   374
	iStatus=EDirectStatusNone;
sl@0
   375
	Terminate1();
sl@0
   376
	Terminate2();
sl@0
   377
	}
sl@0
   378
sl@0
   379
void CWsDirectScreenAccess::Abort()
sl@0
   380
	{
sl@0
   381
	if ( iStatus == EDirectStatusRunning ) 	
sl@0
   382
		{
sl@0
   383
		Terminate1();
sl@0
   384
		if (iMsgQueue->Status()==KRequestPending)
sl@0
   385
			iStatus=(iAbortReason<=RDirectScreenAccess::ETerminateRegion ? EDirectStatusAbortedWindow:EDirectStatusAbortedGlobal);
sl@0
   386
		else
sl@0
   387
			iStatus=EDirectStatusCompleted;
sl@0
   388
		if (iStatus!=EDirectStatusAbortedWindow)
sl@0
   389
			Terminate2();
sl@0
   390
		}
sl@0
   391
	}
sl@0
   392
sl@0
   393
sl@0
   394
TInt CWsDirectScreenAccess::GetSendQueue()
sl@0
   395
	{
sl@0
   396
	TInt ret = iMsgQueue->CreateSendQueue();
sl@0
   397
	if(ret == KErrNone)
sl@0
   398
		{
sl@0
   399
		iWsOwner->SetResponseHandle(iMsgQueue->SendQueue());	
sl@0
   400
		}
sl@0
   401
	return ret;
sl@0
   402
	}
sl@0
   403
sl@0
   404
TInt CWsDirectScreenAccess::GetRecQueue()
sl@0
   405
	{
sl@0
   406
	TInt ret = iMsgQueue->CreateRecQueue();
sl@0
   407
	if(ret == KErrNone)
sl@0
   408
		{
sl@0
   409
		iWsOwner->SetResponseHandle(iMsgQueue->RecQueue());	
sl@0
   410
		}
sl@0
   411
	return ret;
sl@0
   412
	}
sl@0
   413
sl@0
   414
sl@0
   415
void CWsDirectScreenAccess::CommandL(TInt aOpcode,const TAny* aCmdData)
sl@0
   416
	{
sl@0
   417
	TWsDirectCmdUnion pData;
sl@0
   418
	pData.any=aCmdData;
sl@0
   419
	switch(aOpcode)
sl@0
   420
		{
sl@0
   421
		case EWsDirectOpFree:
sl@0
   422
			delete this;
sl@0
   423
			break;
sl@0
   424
		case EWsDirectOpRequest:
sl@0
   425
			Request(*pData.Int);
sl@0
   426
			break;
sl@0
   427
		case EWsDirectOpInitFailed:
sl@0
   428
	#if defined(_DEBUG)
sl@0
   429
			if (iStatus!=EDirectStatusInitialising)
sl@0
   430
				{
sl@0
   431
				iWsOwner->PPanic(EWservPanicDirectMisuse);
sl@0
   432
				}
sl@0
   433
	#endif
sl@0
   434
			iStatus=EDirectStatusNone;
sl@0
   435
			break;
sl@0
   436
		case EWsDirectOpGetRegion:
sl@0
   437
			GetRegion(*pData.Int);
sl@0
   438
			break;
sl@0
   439
		case EWsDirectOpCancel:
sl@0
   440
			Cancel();
sl@0
   441
			break;
sl@0
   442
		case EWsDirectOpGetSendQueue:
sl@0
   443
			GetSendQueue();
sl@0
   444
			break;
sl@0
   445
		case EWsDirectOpGetRecQueue:
sl@0
   446
			GetRecQueue();
sl@0
   447
			break;
sl@0
   448
		default:
sl@0
   449
			OwnerPanic(EWservPanicOpcode);
sl@0
   450
			break;
sl@0
   451
		}
sl@0
   452
	}
sl@0
   453
sl@0
   454
void CWsDirectScreenAccess::Initiate()
sl@0
   455
	{
sl@0
   456
	iWin->AddDSA(*this);
sl@0
   457
	iScreen->AddDirect(*this);
sl@0
   458
	if ( IsSyncTimeoutPending() )
sl@0
   459
		{
sl@0
   460
		Screen()->DSARegionSyncOver( *this );
sl@0
   461
		
sl@0
   462
		RRegion deltaRgn;
sl@0
   463
		deltaRgn.Copy( iFrozenRegion );
sl@0
   464
		
sl@0
   465
		deltaRgn.SubRegion( iVisible );
sl@0
   466
		deltaRgn.Tidy();
sl@0
   467
		
sl@0
   468
		if ( !deltaRgn.IsEmpty() )
sl@0
   469
			{
sl@0
   470
			Screen()->ScheduleRegionUpdate( &deltaRgn );
sl@0
   471
			}
sl@0
   472
		
sl@0
   473
		deltaRgn.Close();
sl@0
   474
		iFrozenRegion.Clear();
sl@0
   475
sl@0
   476
		DeleteRegionSyncWatchcat();
sl@0
   477
		}
sl@0
   478
	}
sl@0
   479
TBool CWsDirectScreenAccess::IsAbortRequired(const TRegion& aTopVisibleRegion) const
sl@0
   480
	{
sl@0
   481
	return ( iStatus == EDirectStatusRunning ) && !RegionsMatch(aTopVisibleRegion, iVisible);
sl@0
   482
	}
sl@0
   483
sl@0
   484
void CWsDirectScreenAccess::Terminate1()
sl@0
   485
	{
sl@0
   486
	WS_ASSERT_DEBUG(!iWin->DSAs().IsEmpty(), EWsPanicDirectScreenAccess);
sl@0
   487
	iWin->RemoveDSA(*this);
sl@0
   488
	}
sl@0
   489
sl@0
   490
void CWsDirectScreenAccess::Terminate2()
sl@0
   491
	{
sl@0
   492
	iScreen->RemoveDirect(*this);
sl@0
   493
	WS_ASSERT_DEBUG(!OnQueue(), EWsPanicDirectScreenAccess);
sl@0
   494
	}
sl@0
   495
sl@0
   496
void CWsDirectScreenAccess::CorrectScreen()
sl@0
   497
	{
sl@0
   498
	if (iAbortReason<=RDirectScreenAccess::ETerminateRegion)
sl@0
   499
		{
sl@0
   500
		Terminate2();
sl@0
   501
		RootWindow()->Invalidate(&iVisible);
sl@0
   502
		}
sl@0
   503
	else
sl@0
   504
		RootWindow()->InvalidateWholeScreen();
sl@0
   505
sl@0
   506
	WS_ASSERT_DEBUG(!OnQueue(), EWsPanicDirectScreenAccess);
sl@0
   507
	}
sl@0
   508
sl@0
   509
sl@0
   510
sl@0
   511
#if defined(_DEBUG)
sl@0
   512
TBool CWsDirectScreenAccess::OnQueue()
sl@0
   513
	{
sl@0
   514
	return iScreen->IsDirectOnQueue(this);
sl@0
   515
	}
sl@0
   516
#endif
sl@0
   517
sl@0
   518
sl@0
   519
TBool CWsDirectScreenAccess::IsSyncTimeoutPending() const
sl@0
   520
	{
sl@0
   521
	TBool res;
sl@0
   522
	res = ( NULL != iRegionSync ) && ( iRegionSync->IsActive() );
sl@0
   523
	return res; 
sl@0
   524
	}
sl@0
   525
sl@0
   526
void CWsDirectScreenAccess::CancelFrozenRegion()
sl@0
   527
	{
sl@0
   528
	if ( !iFrozenRegion.IsEmpty() )
sl@0
   529
		{
sl@0
   530
		Screen()->DSARegionSyncOver( *this );
sl@0
   531
		Screen()->ScheduleRegionUpdate( &iFrozenRegion );
sl@0
   532
		iFrozenRegion.Clear();
sl@0
   533
		}	
sl@0
   534
	}
sl@0
   535
sl@0
   536
void CWsDirectScreenAccess::DeleteRegionSyncWatchcat()
sl@0
   537
	{
sl@0
   538
	if ( NULL != iRegionSync )
sl@0
   539
		{
sl@0
   540
		if ( iRegionSync->IsActive() )
sl@0
   541
			{
sl@0
   542
			iRegionSync->Cancel();			
sl@0
   543
			}
sl@0
   544
		delete iRegionSync;
sl@0
   545
		iRegionSync = NULL;
sl@0
   546
		}
sl@0
   547
	CancelFrozenRegion();
sl@0
   548
	}	
sl@0
   549
sl@0
   550
void CWsDirectScreenAccess::RegionSyncTimeout()
sl@0
   551
	{
sl@0
   552
	CancelFrozenRegion();
sl@0
   553
	}
sl@0
   554
sl@0
   555
CWsDirectScreenAccess::CDSARegionSyncTimer* CWsDirectScreenAccess::CDSARegionSyncTimer::NewL(CWsDirectScreenAccess& aDSA)
sl@0
   556
	{
sl@0
   557
	CWsDirectScreenAccess::CDSARegionSyncTimer* self = new ( ELeave ) CWsDirectScreenAccess::CDSARegionSyncTimer( aDSA );
sl@0
   558
	
sl@0
   559
	CleanupStack::PushL( self );
sl@0
   560
	self->ConstructL();
sl@0
   561
	CleanupStack::Pop( self );
sl@0
   562
	
sl@0
   563
	CActiveScheduler::Add( self );
sl@0
   564
	self->After( TTimeIntervalMicroSeconds32( KRegionSyncTimeoutMicrosec ) );
sl@0
   565
	return self;
sl@0
   566
	}
sl@0
   567
	
sl@0
   568
void CWsDirectScreenAccess::CDSARegionSyncTimer::RunL()
sl@0
   569
	{
sl@0
   570
	iDSA.RegionSyncTimeout();
sl@0
   571
	}
sl@0
   572
sl@0
   573
CWsDirectScreenAccess::CDSARegionSyncTimer::CDSARegionSyncTimer(CWsDirectScreenAccess& aDSA):
sl@0
   574
	CTimer( CActive::EPriorityHigh ),
sl@0
   575
	iDSA( aDSA )
sl@0
   576
	{ } // empty	
sl@0
   577
sl@0
   578
sl@0
   579
static TBool RegionsMatch(const TRegion & aOne, const TRegion & aTwo)
sl@0
   580
	{
sl@0
   581
	// Check if the regions have equal areas.
sl@0
   582
	const TRect* rect1 = aOne.RectangleList();
sl@0
   583
	TUint area1 = 0;
sl@0
   584
	for(TInt i = 0; i < aOne.Count(); ++i)
sl@0
   585
		{
sl@0
   586
		area1 += (rect1->Width() * rect1->Height());
sl@0
   587
		rect1++;
sl@0
   588
		}
sl@0
   589
sl@0
   590
	const TRect* rect2 = aTwo.RectangleList();
sl@0
   591
	TUint area2 = 0;
sl@0
   592
	for(TInt i = 0; i < aTwo.Count(); ++i)
sl@0
   593
		{
sl@0
   594
		area2 += (rect2->Width() * rect2->Height());
sl@0
   595
		rect2++;
sl@0
   596
		}
sl@0
   597
	
sl@0
   598
	if(area1 != area2)
sl@0
   599
		{
sl@0
   600
		return EFalse;
sl@0
   601
		}
sl@0
   602
sl@0
   603
	// Check if one region is completely contained within the other.
sl@0
   604
	STACK_REGION tempRegion;
sl@0
   605
	tempRegion.Copy(aOne);	
sl@0
   606
	tempRegion.SubRegion(aTwo);
sl@0
   607
sl@0
   608
	const TBool ret(tempRegion.IsEmpty());
sl@0
   609
	tempRegion.Close();
sl@0
   610
sl@0
   611
	return ret;
sl@0
   612
	}
sl@0
   613