--- a/graphicsdeviceinterface/bitgdi/tbit/TDefect2.cpp Fri Sep 24 16:14:28 2010 +0300
+++ b/graphicsdeviceinterface/bitgdi/tbit/TDefect2.cpp Fri Sep 24 16:44:34 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2003-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -2125,13 +2125,18 @@
DeleteGraphicsContext();
DeleteScreenDevice();
TRAPD(err, iScrDev = CFbsScreenDevice::NewL(aScreenNo, aDisplayMode));
- if(err == KErrNotSupported)
+ if ( !iScrDev )
{
+ TESTE( err == KErrNotSupported, err );
return err;
}
TEST(err == KErrNone);
TEST(iScrDev->ScreenNo() == aScreenNo);
err = iScrDev->CreateContext((CGraphicsContext*&)iGc);
+ if ( !iGc )
+ {
+ return err;
+ }
TEST(err == KErrNone);
iGc->SetUserDisplayMode(aDisplayMode);
iScrDev->ChangeScreenDevice(NULL);
--- a/graphicshwdrivers/surfacemgr/inc/surface_hints.h Fri Sep 24 16:14:28 2010 +0300
+++ b/graphicshwdrivers/surfacemgr/inc/surface_hints.h Fri Sep 24 16:44:34 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -47,6 +47,12 @@
*/
const TInt KSurfaceProtection = 0x3;
+/** Hint about the surface’s characteristics or properties,
+ For example if a surface can be persisted by the effects engine.
+ @see TSurfaceCharacteristics for possible values.
+*/
+const TInt KSurfaceCharacteristics = 0x4;
+
/** Values used for the KSurfaceContent key */
enum TSurfaceContent
@@ -120,6 +126,17 @@
};
+/** Values used for the KSurfaceCharacteristics key. The values are bitmasks and can be combined.
+*/
+enum TSurfaceCharacteristics
+ {
+ /**
+ * Surface cannot be persisted once it has been closed by the creator
+ */
+ ENotPersistable = 1,
+ };
+
+
class TSurfaceUpdate
{
/** Constructor.
@@ -185,7 +202,7 @@
return ( iValue & 0x80000000 ) ? ETrue : EFalse;
}
-}; //namespace surfaceHints
+} //namespace surfaceHints
#endif //__SURFACE_HINTS_H__
--- a/graphicshwdrivers/surfacemgr/test/src/tsurfacemanager.cpp Fri Sep 24 16:14:28 2010 +0300
+++ b/graphicshwdrivers/surfacemgr/test/src/tsurfacemanager.cpp Fri Sep 24 16:44:34 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -21,6 +21,7 @@
@internalComponent - Internal Symbian test code
*/
+
#include "tsurfacemanager.h"
#include <e32base.h>
#include <e32cons.h>
@@ -29,6 +30,9 @@
#include <e32cmn.h>
#include <hal.h>
#include <e32def_private.h>
+#include <graphics/surface_hints.h>
+
+using namespace surfaceHints;
const TInt KCountLimit = 10000;
@@ -3188,36 +3192,32 @@
//Add HintPair1
RSurfaceManager::THintPair hintPair1;
- hintPair1.iKey.iUid = 0x123257;
- hintPair1.iValue = 300;
- hintPair1.iMutable = ETrue;
+ hintPair1.Set(TUid::Uid(KSurfaceContent), EStillImage, ETrue);
TEST(KErrNone == iSurfaceManager.AddSurfaceHint(surfaceId, hintPair1));
RSurfaceManager::THintPair hintPairCheck1;
- hintPairCheck1.iKey.iUid = 0x123257;
+ hintPairCheck1.iKey.iUid = KSurfaceContent;
CheckHintPair(surfaceId, hintPairCheck1, hintPair1);
//Add HintPair2
RSurfaceManager::THintPair hintPair2;
- hintPair2.iKey.iUid = 0x123267;
- hintPair2.iValue = 100;
+ hintPair2.iKey.iUid = KSurfaceProtection;
+ hintPair2.iValue = EAllowAnalog | EAllowDigital;
hintPair2.iMutable = EFalse;
TEST(KErrNone == iSurfaceManager.AddSurfaceHint(surfaceId, hintPair2));
RSurfaceManager::THintPair hintPairCheck2;
- hintPairCheck2.iKey.iUid = 0x123267;
+ hintPairCheck2.iKey.iUid = KSurfaceProtection;
CheckHintPair(surfaceId, hintPairCheck2, hintPair2);
CheckHintPair(surfaceId, hintPairCheck1, hintPair1);
//Add HintPair3
RSurfaceManager::THintPair hintPair3;
- hintPair3.iKey.iUid = 0x123324;
- hintPair3.iValue = 500;
- hintPair3.iMutable = ETrue;
+ hintPair3.Set(TUid::Uid(KSurfaceCharacteristics), ENotPersistable, EFalse);
TEST(KErrNone == iSurfaceManager.AddSurfaceHint(surfaceId, hintPair3));
RSurfaceManager::THintPair hintPairCheck3;
- hintPairCheck3.iKey.iUid = 0x123324;
+ hintPairCheck3.iKey.iUid = KSurfaceCharacteristics;
CheckHintPair(surfaceId, hintPairCheck3, hintPair3);
CheckHintPair(surfaceId, hintPairCheck2, hintPair2);
CheckHintPair(surfaceId, hintPairCheck1, hintPair1);
@@ -4439,3 +4439,4 @@
if(!aCondition)
User::Leave(TEST_ERROR_CODE); // leave with standard error code
}
+
--- a/graphicstest/graphicstestharness/group/bld.inf Fri Sep 24 16:14:28 2010 +0300
+++ b/graphicstest/graphicstestharness/group/bld.inf Fri Sep 24 16:44:34 2010 +0300
@@ -39,11 +39,15 @@
../rom/graphics_imagecomparison.iby /epoc32/rom/include/graphics_imagecomparison.iby
../rom/graphics_tprofiler.iby /epoc32/rom/include/graphics_tprofiler.iby
../rom/graphics_simload.iby /epoc32/rom/include/graphics_simload.iby
+../rom/minigui_chassis_bats.oby /epoc32/rom/include/minigui_chassis_bats.oby
+../rom/minigui_naviengine_smp.oby /epoc32/rom/include/minigui_naviengine_smp.oby
// WSINI
../rom/graphics_sirocco_wsini.hby /epoc32/rom/include/graphics_sirocco_wsini.hby
../rom/graphics_sirocco_wsini.iby /epoc32/rom/include/graphics_sirocco_wsini.iby
+../rom/graphics_sirocco_ne_wsini.iby /epoc32/rom/include/graphics_sirocco_ne_wsini.iby
../wsini/wsini_vasco.ini /epoc32/data/test_wsini/wsini_vasco.ini
+../wsini/wsini_naviengine.ini /epoc32/data/test_wsini/wsini_naviengine.ini
// ONB batch files
../batch/retain_files.cmd z:\graphicstest\retain_files.cmd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicstest/graphicstestharness/rom/graphics_sirocco_ne_wsini.iby Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,37 @@
+// Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description: Config for wsini.ini on NAVIENGINE
+//
+
+#ifndef __GRAPHICS_SIROCCO_NE_WSINI_IBY__
+#define __GRAPHICS_SIROCCO_NE_WSINI_IBY__
+
+#include <graphics_sirocco_wsini.hby>
+
+//#if WSERV_TEST_WSINI == WSERV_TEST_WSINI_ALF
+// data=DATAZ_\talf\wsini_vasco_alf.ini \system\data\wsini.ini
+//#elif WSERV_TEST_WSINI == WSERV_TEST_WSINI_BITGDIRENDERSTAGE
+// data=DATAZ_\wstest\tbitgdirenderstage\arm\wsini_bitgdirenderstage_vasco.ini \system\data\wsini.ini
+//#elif WSERV_TEST_WSINI == WSERV_TEST_WSINI_CSC
+// data=DATAZ_\wstest\wsini_vasco_tcsc.ini \system\data\wsini.ini
+//#elif WSERV_TEST_WSINI == WSERV_TEST_WSINI_GENERICPLUGIN
+// data=DATAZ_\wstest\genericplugin\wsini_vasco_genericplugin.ini \system\data\wsini.ini
+//#elif WSERV_TEST_WSINI == WSERV_TEST_WSINI_LAYERCOMPOSITION
+// data=DATAZ_\tlayercomposition\wsini_vasco_layercomposition.ini \system\data\wsini.ini
+//#elif WSERV_TEST_WSINI == WSERV_TEST_WSINI_RATELIMITER
+// data=DATAZ_\wstest\ratelimiter\wsini_vasco_ratelimiter.ini \system\data\wsini.ini
+//#else
+ data=EPOCROOT##epoc32\data\test_wsini\wsini_naviengine.ini \system\data\wsini.ini
+//#endif
+
+#endif // __GRAPHICS_SIROCCO_NE_WSINI_IBY__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicstest/graphicstestharness/rom/minigui_chassis_bats.oby Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,185 @@
+#ifndef __MINIGUI_OBY__
+#define __MINIGUI_OBY__
+
+// Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// This OBY File is used to build Mini-Gui ROM Images.
+//
+// Use the following buildrom command line, or similar:
+// buildrom -orombld.img -DUSE_SDIO_SD_MMC -DWITH_TVOUT -DUSE_24UBPP_DISPLAY_VARIANT_TV -D_INTERNAL_MMC -DUSE_DATA_PAGING h4hrp minigui pagedrom platsec
+// Note there is no need to specify -D_NAND2
+
+define OBEYFILE minigui
+define ROMDATE ##TODAY##
+
+// We used to define _NAND2 on the commandline to buildrom. However, it
+// does not make rombuild create a rofs image. Instead it needs to be
+// specified in the oby file itself.
+//#define _NAND2
+
+// Undefine things in global System Include that stops the NCP rom from working.
+#undef USE_CUSTOM_MMC_PARTITION
+#undef SYMBIAN_EXCLUDE_SCDV
+#undef SYMBIAN_GRAPHICS_USE_GCE
+#undef SYMBIAN_GRAPHICS_ADAPTATION
+#undef SGA_SW_NO_GRAPHICSRESOURCE
+#undef SYMBIAN_EXCLUDE_KEYMAP
+
+
+
+#define NO_METROTRK_APP // don't want metrotrk application
+#define HAS_ETHERNET // include etherDrv, ether802, DHCP
+#define SYMBIAN_EXCLUDE_FAX
+#undef __IPSEC
+#define SYMBIAN_EXCLUDE_OBEX
+
+#ifdef SYMBIAN_SYSTEM_STATE_MANAGEMENT
+#define _SSMSTARTUPMODE 8 //for ssma boot up.
+#else
+#define _STARTUPMODE8 // for sysstart.iby
+#endif
+
+// Various workarounds to avoid dependencies on UIKON
+
+#define __TLS_IBY__ // exclude TLS
+#define __TLSPROVIDER_IBY__ // exclude TLSPROVIDER
+#define __OBEXPROTOCOL_IBY__ // exclude obex.dll etc
+#define __WLANEAPMETHODS_IBY__ // exclude eap_tls.msy & friends
+//
+
+#ifndef SYMBIAN_BASE_USE_GCE
+#define SYMBIAN_BASE_USE_GCE
+#endif
+#ifndef SYMBIAN_GRAPHICS_USE_GCE
+#define SYMBIAN_GRAPHICS_USE_GCE
+#endif
+#include <header.iby> /* ROM header definitions */
+#include <base.iby> /* The lowest-level of the operating system */
+
+#ifdef SYMBIAN_SYSTEM_STATE_MANAGEMENT
+
+#include <ssma.iby> /*System State Management Architecture*/
+#include <ssplugins.iby> /*System State Management Plugins*/
+
+//Include SSM optional components to enable teams to build a plain textshell rom (on the lines of DEF128306),
+//following removal of h4_textshell_rom.oby.
+#include <amastart.iby>
+
+#include <shma.iby>
+#include <ssrefplugins.iby>
+#else
+#include <sysstart.iby>
+#include <sysstartconfig.iby>
+#endif // SYMBIAN_SYSTEM_STATE_MANAGEMENT
+
+#include <debug.iby>
+
+#include <eshell.iby>
+
+#include <centralrepository.iby>
+ file=ABI_DIR\BUILD_DIR\abclient.dll sys\bin\abclient.dll
+
+#include <crypto.iby>
+
+#include <c32.iby>
+#include <ecuart.iby>
+#include <irda.iby>
+#include <stdlib.iby>
+#include <gdi.iby>
+#include <fntstore.iby>
+#include <fbserv.iby>
+#include <bitgdi.iby>
+#include <iculayoutengine.iby>
+#include <freetype.iby>
+#include <directgdi.iby>
+#include <wserv.iby>
+#include <econs_wserv.iby>
+//data=DATAZ_\wsini_minigui.ini \system\data\wsini.ini
+
+#include <printers.iby>
+
+
+
+#include <traces.iby>
+
+#include <inetprotutil.iby> /* needed for mmfcontrollerframework.dll */
+#include <sysagent.iby>
+#include <network.iby>
+#include <dial.iby> // needed by commsdat
+#include <etel.iby>
+#include <smsstack.iby>
+#include <etelmm.iby>
+#include <etelpckt.iby>
+#include <mmtsy.iby>
+#include <etelsat.iby>
+#include <sysawatcher.iby>
+#include <bafl.iby>
+#include <ecom.iby>
+#include <store.iby>
+#include <dbms.iby>
+#include <pwrcli.iby>
+#include <xml.iby>
+#include <ups.iby>
+#include <securitycommonutils.iby>
+
+/* Feature Management run-time */
+#ifdef SYMBIAN_FEATURE_MANAGER
+
+// Include both old and new components when Feature Manager enabled
+#include <featmgr.iby>
+#include <featreg.iby>
+
+#else
+
+// Include only the original Feature Registry otherwise
+#include <featreg.iby>
+#ifndef ROM_FEATURE_MANAGEMENT
+/* Provide a default configuration file for the feature registry */
+data=EPOCROOT##epoc32\data\config\featreg_default.cfg private\102744CA\featreg.cfg
+#endif
+#endif
+
+// The following section are all indirect dependencies arising from TEF testexecute depending
+// on apparc
+#include <mmcommon.iby>
+#include <ezlib.iby>
+file=ABI_DIR\BUILD_DIR\Http.dll System\Libs\Http.dll
+file=ABI_DIR\BUILD_DIR\httputils.dll System\Libs\httputils.dll
+#include <asnpkcs.iby>
+#include <filetokens.iby>
+#include <imageconversion.iby>
+#include <ocsp.iby>
+#include <certman.iby>
+#include <swi.iby>
+#include <bluetooth.iby>
+#include <openenv.iby>
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+#include <scr.iby>
+#include <sts.iby>
+#include <sif.iby>
+#endif
+#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
+#include <scr.iby>
+#include <sts.iby>
+#include <sif.iby>
+#endif
+#include <caf.iby>
+#include <apparc.iby> /* Application architecture DLLs */
+#include <emime.iby> /* Mime recognition */
+// This is the end of the indirect dependencies arising from TEF testexecute
+// depending on apparc
+
+#include <testexecute.iby> // TEF
+
+#endif /* __MINIGUI_OBY__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicstest/graphicstestharness/rom/minigui_naviengine_smp.oby Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,21 @@
+// Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// This OBY File is used to build Minigui NaviEngine SMP ROM Images.
+//
+//
+
+#define SMP
+#include <naviengine.oby>
+#include <minigui_chassis_bats.oby>
+#include <platsec.oby>
Binary file graphicstest/graphicstestharness/wsini/wsini_naviengine.ini has changed
--- a/graphicstest/uibench/group/te_uibench.mmp Fri Sep 24 16:14:28 2010 +0300
+++ b/graphicstest/uibench/group/te_uibench.mmp Fri Sep 24 16:44:34 2010 +0300
@@ -43,6 +43,7 @@
SOURCE tspriteperf.cpp
SOURCE textendedbitmap.cpp
SOURCE tfbsglyphdata.cpp
+SOURCE trenderorientation.cpp
USERINCLUDE ../src
USERINCLUDE ../../../fbs/fontandbitmapserver/inc
--- a/graphicstest/uibench/group/te_uibench_gce.mmp Fri Sep 24 16:14:28 2010 +0300
+++ b/graphicstest/uibench/group/te_uibench_gce.mmp Fri Sep 24 16:44:34 2010 +0300
@@ -31,6 +31,7 @@
SOURCE tsimpledrawing_directgdi.cpp
SOURCE teventhandlingperf.cpp
SOURCE tflipframerate.cpp
+SOURCE trenderorientation.cpp
USERINCLUDE ../src
--- a/graphicstest/uibench/scripts/te_uibench_gce.script Fri Sep 24 16:14:28 2010 +0300
+++ b/graphicstest/uibench/scripts/te_uibench_gce.script Fri Sep 24 16:44:34 2010 +0300
@@ -64,6 +64,6 @@
RUN_TEST_STEP 4000 te_uibench_gce tsimpledrawing_directgdi z:\uibench\te_uibench_gce.ini
RUN_TEST_STEP 1000 te_uibench_gce teventhandlingperf z:\uibench\te_uibench_gce.ini
RUN_TEST_STEP 20000 te_uibench_gce tflipframerate z:\uibench\te_uibench_gce.ini
-
+RUN_TEST_STEP 4000 te_uibench_gce trenderoriention z:\uibench\te_uibench_gce.ini
PRINT Complete_te_uibench_gce_Tests
--- a/graphicstest/uibench/src/tgcesuiteserver.cpp Fri Sep 24 16:14:28 2010 +0300
+++ b/graphicstest/uibench/src/tgcesuiteserver.cpp Fri Sep 24 16:44:34 2010 +0300
@@ -26,6 +26,7 @@
#include "tdirectgdiperf.h"
#include "teventhandlingperf.h"
#include "tflipframerate.h"
+#include "trenderorientation.h"
/**
Same code for Secure and non-secure variants
@@ -102,6 +103,7 @@
CTestStep* CGceSuiteServer::CreateTestStep(const TDesC& aStepName)
{
CTestStep* testStep = NULL;
+
if(aStepName == KTGraphicsResource)
testStep = new CTGraphicsResource();
else if(aStepName == KTBitBltPerfDirectGdi)
@@ -114,5 +116,8 @@
testStep = new CTEventHandlingPerf();
else if(aStepName == KTFlipFramerate)
testStep = new CTFlipFramerate();
+ else if(aStepName == KTRenderOrientation)
+ testStep = new CTRenderOrientation;
+
return testStep;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicstest/uibench/src/trenderorientation.cpp Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,269 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+/**
+ @file
+ @test
+ @internalComponent - Internal Nokia test code
+*/
+
+#include <w32std.h>
+
+#include <wspublishandsubscribedata.h>
+#include "trenderorientation.h"
+
+const TInt KPublishTimeout = 1000000; // 1 second in microseconds
+const TInt KNumIterations = 20;
+
+// Values for the device orientation that we receive via P&S from the Theme Server
+// Must match those in renderorientationtracker.h, and, obviously, those used by the real theme server
+const TUid KThemeOrientationCategory = {0x20022E82}; // == KHbPsHardwareCoarseOrientationCategoryUid
+const TUint KThemeOrientationKey = 0x4F726965; // == KHbPsHardwareCoarseOrientationKey
+
+void CWindowStuff::ConstructL()
+ {
+ User::LeaveIfError(iWs.Connect());
+ iWs.SetAutoFlush(ETrue);
+
+ iWindowGroup = RWindowGroup(iWs);
+ User::LeaveIfError(iWindowGroup.Construct(reinterpret_cast<TUint32>(&iWindowGroup)));
+
+ iChildWindow = RWindow(iWs);
+ User::LeaveIfError(iChildWindow.Construct(iWindowGroup, reinterpret_cast<TUint32>(&iChildWindow)));
+ }
+
+CWindowStuff::~CWindowStuff()
+ {
+ Destroy();
+ }
+
+void CWindowStuff::Destroy()
+ {
+ iChildWindow.Close();
+ iWindowGroup.Close();
+ iWs.Close();
+ }
+
+CTRenderOrientation::CTRenderOrientation()
+ {
+ // check that these two enums are aligned
+ __ASSERT_COMPILE(EDisplayOrientationAuto == ENumWindowThings);
+
+ SetTestStepName(KTRenderOrientation);
+ }
+
+CTRenderOrientation::~CTRenderOrientation()
+ {
+ }
+
+TRenderOrientation CTRenderOrientation::GetRenderOrientationL()
+ {
+ return GetOrientationL(iWsRenderOrientationProperty);
+ }
+
+TRenderOrientation CTRenderOrientation::GetThemeOrientationL()
+ {
+ return GetOrientationL(iThemeOrientationProperty);
+ }
+
+TRenderOrientation CTRenderOrientation::GetOrientationL(RProperty& aProperty)
+ {
+ TInt orientation=EDisplayOrientationNormal;
+ User::LeaveIfError(aProperty.Get(orientation));
+
+ TESTL(orientation >= EDisplayOrientationNormal);
+ TESTL(orientation < EDisplayOrientationAuto);
+
+ return static_cast<TRenderOrientation>(orientation);
+ }
+
+void CTRenderOrientation::TestOrientationChangeL(const TDesC& aStepName, TTestPhase aTestPhase)
+ {
+ SetTestStepID(aStepName);
+
+ if(EThemeOrientationChange == aTestPhase)
+ {
+ TESTL(EDisplayOrientationNormal == GetThemeOrientationL());
+ iWindowStuff[EFirstWindowThing].Session().IndicateAppOrientation(EDisplayOrientationAuto);
+ }
+
+ TInt renderOrientation = GetRenderOrientationL();
+
+ // For consistancy, check that we are starting from the same orientation
+ TESTL(EDisplayOrientationNormal == renderOrientation);
+
+ // Set-up the timer
+ iProfiler->InitResults();
+ iTimingsTaken = 0;
+
+ // repeat numerous times to get a decent average
+ for(TInt iterations=0; iterations < KNumIterations; ++iterations)
+ {
+ renderOrientation = GetRenderOrientationL();
+ // For consistancy, check that we are starting from the same orientation
+ TESTL(EDisplayOrientationNormal == renderOrientation);
+
+ // loop through the orientations, ending up changing back to normal
+ for(++renderOrientation; renderOrientation <= EDisplayOrientationAuto; ++renderOrientation)
+ {
+ // % can be slow, do it outside of the timing
+ TRenderOrientation testOrientation = static_cast<TRenderOrientation>(renderOrientation%EDisplayOrientationAuto);
+
+ iWsRenderOrientationProperty.Subscribe(iRenderOrientationStatus);
+ // start the timeout timer
+ iTimeoutTimer.After(iTimeoutStatus, KPublishTimeout);
+ // start the results timer
+ iProfiler->StartTimer();
+
+ switch(aTestPhase)
+ {
+ case EIndicatedOrientationChange:
+ // Do the indicated orientation Change
+ iWindowStuff[EFirstWindowThing].Session().IndicateAppOrientation(testOrientation);
+ break;
+
+ case EWindowOrdinalChange:
+ // move the relevant window group to the front
+ // N.B. this will go wrong if the number of orientations and windows are not equal
+ iWindowStuff[testOrientation].WindowGroup().SetOrdinalPosition(0);
+ break;
+
+ case EThemeOrientationChange:
+ // Needs the focus window to be in auto mode
+ iThemeOrientationProperty.Set(testOrientation);
+ break;
+
+ default:
+ TESTL(EFalse);
+ }
+
+ // Wait for the update to have been published ( or time out while waiting )
+ User::WaitForRequest(iRenderOrientationStatus, iTimeoutStatus);
+
+ iProfiler->MarkResultSetL();
+ ++iTimingsTaken;
+
+ if(KErrNone != iRenderOrientationStatus.Int())
+ {
+ // timed out
+ iWsRenderOrientationProperty.Cancel();
+ TESTL(EFalse);
+ }
+ else
+ {
+ // Check that it is actually the expected orientation
+ TESTL(GetRenderOrientationL() == testOrientation);
+ }
+
+ if(KRequestPending == iTimeoutStatus.Int())
+ {
+ // as expected, so cancel the timeout timer
+ iTimeoutTimer.Cancel();
+ }
+ else
+ {
+ // timed out
+ TESTL(EFalse);
+ }
+ }
+ }
+
+ // wrap it up
+ iProfiler->ResultsAnalysis(KTRenderOrientation,KErrNotFound,ENone,ENone,iTimingsTaken);
+ }
+
+TVerdict CTRenderOrientation::doTestStepL()
+ {
+ INFO_PRINTF1(_L("Testing: Indicated Orientation Change"));
+ TestOrientationChangeL(_L("GRAPHICS-UI-BENCH-0xxx1"), EIndicatedOrientationChange);
+
+ INFO_PRINTF1(_L("Testing: Window Ordinal Position Change"));
+ TestOrientationChangeL(_L("GRAPHICS-UI-BENCH-0xxx2"), EWindowOrdinalChange);
+
+ INFO_PRINTF1(_L("Testing: Theme Orientation Change"));
+ TestOrientationChangeL(_L("GRAPHICS-UI-BENCH-0xxx3"), EThemeOrientationChange);
+
+ return TestStepResult();
+ }
+
+_LIT(KThemeServerPropertyDefine, "twsthemeserverpropertydefine.exe");
+_LIT(KThemeServerPropertyDefineCmdDefine, "define");
+_LIT(KThemeServerPropertyDefineCmdDelete, "delete");
+
+void CTRenderOrientation::ThemeServerProperty(const TDesC& aCmd)
+ {
+ /* This Process called with the argument KThemeServerPropertyDefineCmdDelete, deletes
+ the theme server RProperty. This is because an RProperty can only be defined and
+ deleted from within a process with the same UID3 as the RProperty catogory you are
+ trying to define/delete.*/
+ RProcess themeServerPropertyDefine;
+ TInt err = themeServerPropertyDefine.Create(KThemeServerPropertyDefine, aCmd);
+ if (KErrNone != err)
+ {
+ _LIT(KLog, "themeServerPropertyDefine.Create() failed with error: %d");
+ INFO_PRINTF2(KLog, err);
+ TEST(EFalse);
+ }
+
+ //wait for themeServerPropertyDefine process to terminate
+ TRequestStatus themeServerPropertyDefineLogonStatus;
+ themeServerPropertyDefine.Logon(themeServerPropertyDefineLogonStatus);
+ themeServerPropertyDefine.Resume();
+ User::WaitForRequest(themeServerPropertyDefineLogonStatus);
+ if (themeServerPropertyDefineLogonStatus != KErrNone)
+ {
+ _LIT(KLog, "themeServerPropertyDefine.Logon() failed with error: %d");
+ INFO_PRINTF2(KLog, themeServerPropertyDefineLogonStatus);
+ TEST(EFalse);
+ }
+ themeServerPropertyDefine.Close();
+ }
+
+TVerdict CTRenderOrientation::doTestStepPreambleL()
+ {
+ // Create in reverse order so that windowThing 0 is at the front
+ for(TInt windowThing = ENumWindowThings - 1; windowThing >= 0 ; --windowThing)
+ {
+ iWindowStuff[windowThing].ConstructL();
+ TRenderOrientation orientation = static_cast<TRenderOrientation>(windowThing%EDisplayOrientationAuto);
+ iWindowStuff[windowThing].Session().IndicateAppOrientation(orientation);
+ iWindowStuff[windowThing].WindowGroup().SetOrdinalPosition(0);
+ }
+
+ User::LeaveIfError(iWsRenderOrientationProperty.Attach(KRenderOrientationCategory, KRenderOrientationKey));
+
+ ThemeServerProperty(KThemeServerPropertyDefineCmdDefine);
+ User::LeaveIfError(iThemeOrientationProperty.Attach(KThemeOrientationCategory, KThemeOrientationKey));
+
+ User::LeaveIfError(iTimeoutTimer.CreateLocal());
+
+ return CTe_graphicsperformanceSuiteStepBase::doTestStepPreambleL();
+ }
+
+TVerdict CTRenderOrientation::doTestStepPostambleL()
+ {
+ iTimeoutTimer.Close();
+
+ iThemeOrientationProperty.Close();
+ ThemeServerProperty(KThemeServerPropertyDefineCmdDelete);
+ iWsRenderOrientationProperty.Close();
+
+ for(TInt windowThing = 0; windowThing < ENumWindowThings; ++windowThing)
+ {
+ iWindowStuff[windowThing].Destroy();
+ }
+
+ return CTe_graphicsperformanceSuiteStepBase::doTestStepPostambleL();
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicstest/uibench/src/trenderorientation.h Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,99 @@
+// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+/**
+ @file
+ @test
+ @internalComponent - Internal Symbian test code
+*/
+
+#ifndef TRENDERORIENTATION_H
+#define TRENDERORIENTATION_H
+
+#include <e32property.h>
+#include "te_graphicsperformanceSuiteStepBase.h"
+
+class CWindowStuff : public CBase
+ {
+public:
+ ~CWindowStuff();
+ void ConstructL();
+ void Destroy();
+
+ inline RWsSession& Session()
+ {return iWs;};
+ inline RWindowGroup& WindowGroup()
+ {return iWindowGroup;};
+
+private:
+ RWsSession iWs;
+ RWindowGroup iWindowGroup;
+ RWindow iChildWindow;
+ };
+
+class CTRenderOrientation : public CTe_graphicsperformanceSuiteStepBase
+ {
+public:
+ CTRenderOrientation();
+ ~CTRenderOrientation();
+
+ // From CTestStep
+ virtual TVerdict doTestStepPreambleL();
+ virtual TVerdict doTestStepPostambleL();
+
+ virtual TVerdict doTestStepL();
+
+private:
+ enum TWindowThing
+ {
+ // One per orientation
+ EFirstWindowThing,
+ ESecondWindowThing,
+ EThirdWindowThing,
+ EFourthWindowThing,
+
+ ENumWindowThings
+ };
+
+ enum TTestPhase
+ {
+ EIndicatedOrientationChange,
+ EWindowOrdinalChange,
+ EThemeOrientationChange,
+
+ ENumTestPhases
+ };
+
+ void TestOrientationChangeL(const TDesC& aStepName, TTestPhase aTestPhase);
+
+ TRenderOrientation GetRenderOrientationL();
+ TRenderOrientation GetThemeOrientationL();
+ TRenderOrientation GetOrientationL(RProperty& aProperty);
+ void ThemeServerProperty(const TDesC& aCmd);
+
+private:
+ CWindowStuff iWindowStuff[ENumWindowThings];
+ RProperty iWsRenderOrientationProperty;
+ RProperty iThemeOrientationProperty;
+
+ RTimer iTimeoutTimer;
+ TRequestStatus iTimeoutStatus;
+ TRequestStatus iRenderOrientationStatus;
+ TInt iTimingsTaken;
+ };
+
+_LIT(KTRenderOrientation,"trenderorientation");
+
+#endif /* TRENDERORIENTATION_H */
--- a/windowing/windowserver/SERVER/openwfc/panics.h Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/SERVER/openwfc/panics.h Fri Sep 24 16:44:34 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2003-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -162,6 +162,10 @@
EWsPanicInvalidRotation = 127, //Invalid rotation used
EWsPanicInvalidPointerOffset = 128, //The pointer offset value in wsini.ini is invalid.
EWsPanicArrayInsertFailed = 129, //Array insert failed.
+ EWsPanicAccessBeyondCommandBuf = 130, //Access beyond wserv command buffer
+ EWsPanicKeyEventRouterBadResult = 131, // Invalid result code from key event routing plug-in
+ EWsPanicKeyEventRouterBadWindowGroup = 132, // Invalid destination window group from key event routing plug-in
+ EWsPanicKeyEventRouterLeave = 133, // Invalid leave from Key event routing plug-in
};
void Panic(TWservPanic aPanic);
--- a/windowing/windowserver/SERVER/w32cmd.h Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/SERVER/w32cmd.h Fri Sep 24 16:44:34 2010 +0300
@@ -266,6 +266,7 @@
EWsClOpUnregisterAllTFXEffect,
EWsClOpOverrideEffectBuf,
EWsClOpOverrideEffectIPC,
+ EWsClOpIndicateAppOrientation,
EWsClOpLastEnumValue //Keep this at the end - used by test code
};
@@ -1059,6 +1060,7 @@
const TWsClCmdRegisterEffect* RegisterEffect;
const TWsClCmdUnRegisterEffect* UnRegisterEffect;
const TWsClCmdOverrideEffect* OverrideEffect;
+ const TRenderOrientation* Orientation;
};
// Window command structures
@@ -2132,6 +2134,7 @@
// Under WINS character code is passed in as HIWORD of the scan code,
// and will need to be removed in some situations
#define __REMOVE_WINS_CHARCODE &0x0000FFFF
+ #define __WINS_CHARCODE(c) ((c) & 0xFFFF0000)
#else
#define __REMOVE_WINS_CHARCODE
#endif
--- a/windowing/windowserver/bwins/WS322U.DEF Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/bwins/WS322U.DEF Fri Sep 24 16:44:34 2010 +0300
@@ -585,5 +585,5 @@
?OverrideEffects@RWsSession@@QAEXHHABV?$TBuf@$0BAA@@@00V?$TBitFlagsT@K@@@Z @ 584 NONAME ; void RWsSession::OverrideEffects(int, int, class TBuf<256> const &, class TBuf<256> const &, class TBuf<256> const &, class TBitFlagsT<unsigned long>)
?UnregisterEffect@RWsSession@@QAEXHHI@Z @ 585 NONAME ; void RWsSession::UnregisterEffect(int, int, unsigned int)
?UnregisterAllEffects@RWsSession@@QAEXXZ @ 586 NONAME ; void RWsSession::UnregisterAllEffects(void)
+ ?IndicateAppOrientation@RWsSession@@QAEXW4TRenderOrientation@@@Z @ 587 NONAME ; void RWsSession::IndicateAppOrientation(enum TRenderOrientation)
-
--- a/windowing/windowserver/bwins/ws32switchu.def Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/bwins/ws32switchu.def Fri Sep 24 16:44:34 2010 +0300
@@ -427,8 +427,8 @@
call_vector_426 @ 426 NONAME ; void RBlankWindow::SetColor(void)
call_vector_427 @ 427 NONAME ; int RWsSession::SetClientCursorMode(enum TPointerCursorMode)
call_vector_428 @ 428 NONAME ; class TRect RDrawableWindow::GetDrawRect(void) const
- call_vector_429 @ 429 NONAME
- call_vector_430 @ 430 NONAME
+ call_vector_429 @ 429 NONAME
+ call_vector_430 @ 430 NONAME
call_vector_431 @ 431 NONAME ; void CWindowGc::Reserved_CWindowGc_3(void)
call_vector_432 @ 432 NONAME ; void CWindowGc::Reserved_CWindowGc_4(void)
call_vector_433 @ 433 NONAME ; void CWindowGc::Reserved_CWindowGc_5(void)
@@ -512,20 +512,20 @@
call_vector_511 @ 511 NONAME ; int RWsSession::DebugInfo(int, int) const
call_vector_512 @ 512 NONAME ; unsigned long RWindowTreeNode::ClientHandle(void) const
call_vector_513 @ 513 NONAME ; int RWindowBase::SetBackgroundSurface(class TSurfaceId const &)
- call_vector_514 @ 514 NONAME
+ call_vector_514 @ 514 NONAME
call_vector_515 @ 515 NONAME ; class TRgb RWindowBase::KeyColor(void) const
- call_vector_516 @ 516 NONAME
- call_vector_517 @ 517 NONAME
- call_vector_518 @ 518 NONAME
- call_vector_519 @ 519 NONAME
- call_vector_520 @ 520 NONAME
+ call_vector_516 @ 516 NONAME
+ call_vector_517 @ 517 NONAME
+ call_vector_518 @ 518 NONAME
+ call_vector_519 @ 519 NONAME
+ call_vector_520 @ 520 NONAME
call_vector_521 @ 521 NONAME ; int RWindowBase::GetBackgroundSurface(class TSurfaceConfiguration &) const
- call_vector_522 @ 522 NONAME
+ call_vector_522 @ 522 NONAME
call_vector_523 @ 523 NONAME ; int RWsSession::PreferredSurfaceConfigurationSize(void) const
call_vector_524 @ 524 NONAME ; int RWsSession::RegisterSurface(int, class TSurfaceId const &)
- call_vector_525 @ 525 NONAME
+ call_vector_525 @ 525 NONAME
call_vector_526 @ 526 NONAME ; void RWindowBase::RemoveBackgroundSurface(int)
- call_vector_527 @ 527 NONAME
+ call_vector_527 @ 527 NONAME
call_vector_528 @ 528 NONAME ; int RWindowBase::SetBackgroundSurface(class TSurfaceConfiguration const &, int)
call_vector_529 @ 529 NONAME ; void RWsSession::UnregisterSurface(int, class TSurfaceId const &)
call_vector_530 @ 530 NONAME ; void RWindow::ClearRedrawStore(void)
@@ -585,4 +585,5 @@
call_vector_584 @ 584 NONAME ; void RWsSession::OverrideEffects(int, int, class TBuf<256> const &, class TBuf<256> const &, class TBuf<256> const &, class TBitFlagsT<unsigned long>)
call_vector_585 @ 585 NONAME ; void RWsSession::UnregisterEffect(int, int, unsigned int)
call_vector_586 @ 586 NONAME ; void RWsSession::UnregisterAllEffects(void)
+ call_vector_587 @ 587 NONAME ; void RWsSession::IndicateAppOrientation(enum TRenderOrientation)
--- a/windowing/windowserver/debuglog/DECODER.CPP Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/debuglog/DECODER.CPP Fri Sep 24 16:44:34 2010 +0300
@@ -834,7 +834,13 @@
_LIT(LogGetExitHighPressureThreshold,"EWsClOpGetExitHighPressureThreshold()");
aText.AppendFormat(LogGetExitHighPressureThreshold);
}
- break;
+ break;
+ case EWsClOpIndicateAppOrientation:
+ {
+ _LIT(LogIndicateAppOrientation,"EWsClOpIndicateAppOrientation(%d)");
+ aText.AppendFormat(LogIndicateAppOrientation, *pData.Orientation);
+ }
+ break;
case EWsClOpLastEnumValue:
{
_LIT(LogLastEnumValue,"EWsClOpLastEnumValue enum");
--- a/windowing/windowserver/eabi/WS322U.DEF Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/eabi/WS322U.DEF Fri Sep 24 16:44:34 2010 +0300
@@ -659,5 +659,5 @@
_ZN10RWsSession16UnregisterEffectEiij @ 658 NONAME
_ZN10RWsSession20UnregisterAllEffectsEv @ 659 NONAME
_ZN11RWindowBase15OverrideEffectsEiRK4TBufILi256EES3_S3_10TBitFlagsTImE @ 660 NONAME
+ _ZN10RWsSession22IndicateAppOrientationE18TRenderOrientation @ 661 NONAME
-
--- a/windowing/windowserver/group/openwfc/WServ_nga.MMP Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/group/openwfc/WServ_nga.MMP Fri Sep 24 16:44:34 2010 +0300
@@ -74,6 +74,7 @@
SOURCE drawresource.cpp
SOURCE devicemap.cpp
SOURCE wsdisplaychangeao.cpp
+SOURCE renderorientationtracker.cpp
SOURCEPATH ../../nga/SERVER/openwfc
--- a/windowing/windowserver/group/openwfc/bld.inf Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/group/openwfc/bld.inf Fri Sep 24 16:44:34 2010 +0300
@@ -78,6 +78,7 @@
../../inc/Graphics/wsdisplaypolicy.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(graphics/wsdisplaypolicy.h)
../../inc/Graphics/openwfc/wselement.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(graphics/wselement.h)
../../inc/Graphics/openwfc/wsscene.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(graphics/wsscene.h)
+../../inc/Graphics/wskeyrouter.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(graphics/wskeyrouter.h)
../../inc/Graphics/wscontentreadyforcomposition.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(graphics/wscontentreadyforcomposition.h)
//RemoteGc exports for partners
@@ -201,6 +202,7 @@
#ifdef SYMBIAN_BUILD_GCE
../../group/AUTODLL_nga.MMP support
../../test/TAutoServer/openwfc/TAutoServer_nga.mmp
+../../test/TAutoServer/tevent_captureapp.mmp
#endif
#ifdef WINS
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserver/group/twsthemeserverpropertydefine.mmp Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,33 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// This .exe is to define an RProperty for simulating the Theme Server.
+// It needs to have the same UID3 as the theme server.
+//
+
+TARGET twsthemeserverpropertydefine.exe
+CAPABILITY WriteDeviceData ReadDeviceData
+TARGETTYPE EXE
+//The UID3 value should be the same as the actual Theme Server UID3
+UID 0x00000000 0x20022E82
+VENDORID 0x70000001
+
+SOURCEPATH ../test/tauto
+SOURCE themeserverpropertydefine.cpp
+
+USERINCLUDE ../inc ../test/tauto
+OS_LAYER_SYSTEMINCLUDE
+
+LIBRARY euser.lib ws32.lib bafl.lib
+
+SMPSAFE
\ No newline at end of file
Binary file windowing/windowserver/group/wservu_multiscreen.ini has changed
Binary file windowing/windowserver/group/wservu_multiscreen_changetracking.ini has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserver/inc/Graphics/wskeyrouter.h Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,216 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Key Event Routing Plug-in API
+
+/**
+@file
+@publishedPartner
+@prototype
+*/
+
+#ifndef WSKEYROUTER_H
+#define WSKEYROUTER_H
+
+#include <e32base.h>
+#include <w32std.h>
+
+/**
+Interface Uid
+*/
+const TUid KKeyRouterPluginUid = { 0x102872e1 };
+
+/**
+Key Capture Type
+*/
+enum TKeyCaptureType
+ {
+ ECaptureTypeKey = 0,
+ ECaptureTypeLongKey = 1,
+ ECaptureTypeKeyUpDown = 2
+ };
+
+/**
+Key Capture Request
+*/
+struct TKeyCaptureRequest
+ {
+ /** Capture type */
+ TKeyCaptureType iType;
+
+ /** Keycode or scancode to be captured */
+ TUint iInputCode;
+
+ /** Output keycode or scancode. When iInputCode is captured, RouteKey()
+ places iOutputCode in TKeyEventRouterOutput.iKeyEvent */
+ TUint iOutputCode;
+
+ /** Bitmask of modifier keys of interest. Key events are captured only
+ when the modifier keys specified by iModifierMask are in the states
+ specified by iModifiers */
+ TUint iModifierMask;
+
+ /** Bitmask of modifier key states */
+ TUint iModifiers;
+
+ /** Opaque handle for this request */
+ TAny* iHandle;
+
+ /** Opaque handle to window group through which request was made */
+ TAny* iWindowGroup;
+
+ /** Identifier of the window group through which request was made */
+ TInt iWindowGroupId;
+
+ /** UID of application that made the capture request */
+ TUid iAppUid;
+
+ /** Capture priority for this request. If more than one window group has
+ requested capture for the same key event, the one with the highest
+ priority will capture it (unless overridden by application specific
+ rules). */
+ TInt iPriority;
+
+ /** Reserved for future use */
+ TInt iReserved[2];
+ };
+
+/**
+Input parameters for RouteKey()
+*/
+struct TKeyEventRouterInput
+ {
+ inline TKeyEventRouterInput(TKeyCaptureType aType, const TKeyEvent& aKeyEvent, TAny* aFocusWindowGroup, TUid aFocusAppUid);
+
+ /** Capture type */
+ TKeyCaptureType iType;
+
+ /** Input key event */
+ TKeyEvent iKeyEvent;
+
+ /** Opaque handle to current focussed window group */
+ TAny* iFocusWindowGroup;
+
+ /** UID of client application with current focussed window group */
+ TUid iFocusAppUid;
+
+ /** Reserved for future use */
+ TInt iReserved[2];
+ };
+
+/**
+Result codes for RouteKey()
+*/
+enum TKeyEventRouterResult
+ {
+ /** Key routed, no capture */
+ ERouted = 0,
+
+ /** Key captured and routed */
+ ECaptured = 1,
+
+ /** Key consumed, do not deliver event */
+ EConsumed = 2
+ };
+
+/**
+Output parameters for RouteKey()
+*/
+struct TKeyEventRouterOutput
+ {
+ /** Result code */
+ TKeyEventRouterResult iResult;
+
+ /** Output key event as translated by plug-in. Key code may be set by
+ RWindowGroup::CaptureLongKey() via TKeyCaptureRequest.iOutputCode **/
+ TKeyEvent iKeyEvent;
+
+ /** Opaque handle to destination window group or NULL if captured by WServ
+ (hotkey). Plug-in must set this to either the window group from the
+ matching capture request or to TKeyEventRouterInput.iFocusWindowGroup */
+ TAny* iWindowGroup;
+
+ /** Opaque handle from matching capture request or NULL if none */
+ TAny* iCaptureHandle;
+
+ /** Reserved for future use */
+ TInt iReserved[2];
+ };
+
+/**
+Key Event Router Interface
+
+This class is implemented by a plug-in DLL in order to perform customised
+routing of window server key events.
+
+The Key Event Routing plug-in is a polymorphic DLL that implements the
+CKeyEventRouter interface. Its UID1 and UID2 must be KDynamicLibraryUid and
+KKeyRouterPluginUid respectively. UID3 identifies a particular implementation
+of the plug-in. The first and only exported function should create and return
+an object of the CKeyEventRouter sub-class.
+*/
+class CKeyEventRouter : public CBase
+ {
+public:
+ /**
+ Create and return an instance of CKeyEventRouter
+
+ @return Pointer to new router instance
+ */
+ IMPORT_C static CKeyEventRouter* NewL();
+
+ /**
+ Add a new key capture request
+
+ @param aRequest Capture request details
+ */
+ virtual void AddCaptureKeyL(const TKeyCaptureRequest& aRequest) = 0;
+
+ /**
+ Update an existing key capture request
+
+ @param aRequest Updated capture request details
+ */
+ virtual void UpdateCaptureKeyL(const TKeyCaptureRequest& aRequest) = 0;
+
+ /**
+ Cancel a key capture request
+
+ @param aType Capture type
+ @param aHandle Opaque handle of request to be cancelled
+ */
+ virtual void CancelCaptureKey(TKeyCaptureType aType, TAny* aHandle) = 0;
+
+ /**
+ Route the key event described by aInput and return its destination
+ in iOutput.
+
+ @param aInput Input data with key event to be routed
+ @param aOutput Output key event and routing results
+ */
+ virtual void RouteKey(const TKeyEventRouterInput& aInput,
+ TKeyEventRouterOutput& aOutput) = 0;
+
+ /**
+ Reserved for future use
+ */
+private:
+ virtual void Reserved1() {};
+ virtual void Reserved2() {};
+ };
+
+inline TKeyEventRouterInput::TKeyEventRouterInput(TKeyCaptureType aType, const TKeyEvent& aKeyEvent, TAny* aFocusWindowGroup, TUid aFocusAppUid) : iType(aType), iKeyEvent(aKeyEvent), iFocusWindowGroup(aFocusWindowGroup), iFocusAppUid(aFocusAppUid)
+ {
+ }
+
+#endif // WSKEYROUTER_H
--- a/windowing/windowserver/inc/W32STD.H Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/inc/W32STD.H Fri Sep 24 16:44:34 2010 +0300
@@ -33,6 +33,7 @@
#include <advancedpointerevent.h>
#include <sizemode.h>
#include <babitflags.h>
+#include <wspublishandsubscribedata.h>
#ifndef SYMBIAN_ENABLE_SPLIT_HEADERS
#include <graphics/windowserverconstants.h>
@@ -1380,6 +1381,7 @@
line. */
ECustomTextCursorAlignBottom
};
+
//
public:
IMPORT_C RWsSession();
@@ -1538,6 +1540,9 @@
IMPORT_C void UnregisterAllEffects();
IMPORT_C void OverrideEffects(TInt aAction, TInt aPurpose, const TFileName& aResourceDir, const TFileName& aFilenameOutgoing, const TFileName& aFilenameIncoming, TBitFlags aFlags=0);
+//Application tells the window server the orientation of rendering it intends to use
+ IMPORT_C void IndicateAppOrientation(TRenderOrientation aOrientation);
+
// functions not exported, used by CWsGraphic
void GraphicMessageReady(TRequestStatus *aStat);
void GetGraphicMessage(TDes8& aData) const;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserver/inc/wspublishandsubscribedata.h Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,47 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Standard window server header file
+//
+//
+#ifndef WSPUBLISHANDSUBSCRIBEDATA_H
+#define WSPUBLISHANDSUBSCRIBEDATA_H
+
+#include <e32cmn.h>
+
+// Values for the render orientation P&S value that we publish
+// Used when the property is defined, attached to, and deleted
+const TUid KRenderOrientationCategory = {268450592}; // WServ UID3
+const TUint KRenderOrientationKey = 0x102872E5;
+
+/** The orientation of rendering the application intends to use.
+
+@see RWsSession::IndicateAppOrientation(TOrientation aOrientation)*/
+enum TRenderOrientation
+ {
+ /** Fixed default orientation */
+ EDisplayOrientationNormal,
+ /** 90° clockwise */
+ EDisplayOrientation90CW,
+ /** 180° */
+ EDisplayOrientation180,
+ /** 270° clockwise */
+ EDisplayOrientation270CW,
+ /** The orientation is from the P&S Key */
+ EDisplayOrientationAuto,
+ /** use the orientation specified by the next top level window(s) that does not have ignore flag set.
+ E.g. system dialog on top of foreground app. */
+ EDisplayOrientationIgnore
+ };
+
+#endif // WSPUBLISHANDSUBSCRIBEDATA_H
--- a/windowing/windowserver/nga/CLIENT/RWINDOW.CPP Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/nga/CLIENT/RWINDOW.CPP Fri Sep 24 16:44:34 2010 +0300
@@ -1363,7 +1363,7 @@
events from all detected pointers to this window.
This method must be called before the window is activated by calling RWindowBase::Activate().
-Otherwise this will be ignored (release build), or panic (debug build).
+Otherwise the client is panicked with the code EWservPanicUnableToEnableAdvPointer.
If this method is not called for the window, it is assumed that the window is not
able to receive events from multiple pointers, and thus only events from a single
@@ -2798,6 +2798,7 @@
description above.
@param aPriority A priority value - if more than one window group has requested
capture for the same key event, the one with the highest priority will capture it.
+The value must be greater than KMinTInt.
@return A handle identifying the capture key, or one of the system-wide error
codes (if <0). KErrPermissionDenied indicates that the requested key cannot be
captured by this window group, because it has been protected by another window group.
@@ -2866,6 +2867,7 @@
aModifierMask need to be set and which need to be unset.
@param aPriority A priority value - if more than one window group has requested
capture for the same key event, the one with the highest priority will capture it.
+The value must be greater than KMinTInt.
@return A handle identifying the capture key, or one of the system-wide error
codes (if < 0). KErrPermissionDenied indicates that the requested key cannot be captured by this
window group, because it has been protected by another window group. For more information, see
@@ -2937,6 +2939,7 @@
not set. Modifier key states are defined in TEventModifier.
@param aPriority If more than one window group has requested capture for the
same long key event, the one with the highest priority will capture the event.
+The value must be greater than KMinTInt.
@param aFlags Configures the long key capture behaviour. See the TLongCaptureFlags
enum.
@return Identifying value for the long key capture. For use with the CancelCaptureLongKey()
@@ -2972,6 +2975,7 @@
not set. Modifier key states are defined in TEventModifier.
@param aPriority If more than one window group has requested capture for the
same long key event, the one with the highest priority will capture the event.
+The value must be greater than KMinTInt.
@param aFlags Configures the long key capture behaviour. See the TLongCaptureFlags
enum.
@return Identifying value for the long key capture. For use with the CancelCaptureLongKey()
--- a/windowing/windowserver/nga/CLIENT/RWS.CPP Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/nga/CLIENT/RWS.CPP Fri Sep 24 16:44:34 2010 +0300
@@ -22,6 +22,7 @@
#include "CLIENT.H"
#include "graphics/windowserverconstants.h"
#include "rtfxeffect.h"
+#include <wspublishandsubscribedata.h>
const TInt KMaxWSERVMessagesSlot=-1;
@@ -2585,3 +2586,15 @@
RTFXEffect tfxEffect(iWsHandle, iBuffer);
tfxEffect.OverrideTFXEffect(RTFXEffect::ETFXSession, aAction, aPurpose, aResourceDir, aFilenameOutgoing, aFilenameIncoming, aFlags);
}
+
+EXPORT_C void RWsSession::IndicateAppOrientation(TRenderOrientation aOrientation)
+/**
+Application informs window server the orientation of rendering it intends to use
+
+@param aOrientation The orientation the application intends to use
+
+@publishedPartner
+*/
+ {
+ return(WriteInt(aOrientation,EWsClOpIndicateAppOrientation));
+ }
--- a/windowing/windowserver/nga/SERVER/CAPKEY.CPP Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/nga/SERVER/CAPKEY.CPP Fri Sep 24 16:44:34 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1995-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -24,9 +24,6 @@
_LIT(KWsProtectedKey, "PROTECTEDKEY");
_LIT(KWsProtectedWindowName, "PROTECTEDKEYWINDOWNAME");
-TPriQue<CWsCaptureKeyUpsAndDowns> CWsCaptureKeyUpsAndDowns::iCaptureKeysUpsAndDowns(_FOFF(CWsCaptureKeyUpsAndDowns,iLink));
-TPriQue<CWsCaptureLongKey> CWsCaptureLongKey::iCaptureLongKeys(_FOFF(CWsCaptureLongKey,iLink));
-
/*CWsCaptureKey*/
@@ -35,20 +32,38 @@
CWsCaptureKey::~CWsCaptureKey()
{
- TWindowServerEvent::CancelCaptureKey((TUint32)this);
+ TWindowServerEvent::CancelCaptureKey(ECaptureTypeKey, this);
}
-void CWsCaptureKey::CmdToParams(const TWsWinCmdCaptureKey &aCaptureKey, TCaptureKey &aParams)
+/**
+Convert a window server key capture command to a capture request for the
+key routing plug-in.
+
+@param aCaptureKey Input capture command
+@param aRequest Output capture request
+*/
+void CWsCaptureKey::CmdToRequest(const TWsWinCmdCaptureKey &aCaptureKey, TKeyCaptureRequest &aRequest)
{
- aParams.iModifiers.iMask=aCaptureKey.modifierMask;
- aParams.iModifiers.iValue=aCaptureKey.modifiers;
- aParams.iKeyCodePattern.iKeyCode=(TInt16)aCaptureKey.key;
- aParams.iKeyCodePattern.iPattern=EMatchKey;
- aParams.iKeyCodePattern.iFiller=STATIC_CAST(TUint8,aCaptureKey.priority);
- aParams.iApp=(TUint32)iWindowGroup;
- aParams.iHandle=(TUint32)this;
+ aRequest.iType = ECaptureTypeKey;
+ aRequest.iModifierMask = aCaptureKey.modifierMask;
+ aRequest.iModifiers = aCaptureKey.modifiers;
+ aRequest.iInputCode = aCaptureKey.key;
+ aRequest.iOutputCode = aCaptureKey.key;
+ aRequest.iPriority = aCaptureKey.priority;
+ aRequest.iWindowGroup = iWindowGroup;
+ aRequest.iWindowGroupId = iWindowGroup ? iWindowGroup->Identifier() : 0;
+ aRequest.iAppUid = iWsOwner ? TUid::Uid(iWsOwner->SecureId().iId) : KNullUid;
+ aRequest.iHandle = this;
}
+/**
+Check for protected key in a capture command
+
+@param aWindowGroup Window Group of capture request
+@param aCaptureKey Key capture command
+
+@leave KErrPermissionDenied Capture key is protected
+*/
void CheckProtectedKeyL(CWsWindowGroup* aWindowGroup,const TWsWinCmdCaptureKey &aCaptureKey)
{
//The key specified in the WSINI file with the keyword: PROTECTEDKEY can only be captured
@@ -56,7 +71,7 @@
TInt protectedKey;
if(WsIniFile->FindVar(KWsProtectedKey,protectedKey))
{
- if (aCaptureKey.key == (TUint)protectedKey)
+ if (aCaptureKey.key == static_cast<TUint>(protectedKey))
{
if (aWindowGroup->GroupName()==NULL)
{
@@ -73,20 +88,36 @@
}
}
+/**
+Construct a capture object for normal key events and make a capture request
+to the key routing plug-in.
+
+@param aCaptureKey Key capture command from RWindowGroup::CaptureKey(),
+ RWsSession::SetHotKey() or default hot key settings.
+*/
void CWsCaptureKey::ConstructL(const TWsWinCmdCaptureKey &aCaptureKey)
{
CheckProtectedKeyL(iWindowGroup, aCaptureKey);
NewObjL();
- TCaptureKey params;
- CmdToParams(aCaptureKey, params);
- TWindowServerEvent::AddCaptureKeyL(params);
+
+ TKeyCaptureRequest request;
+ CmdToRequest(aCaptureKey, request);
+ TWindowServerEvent::AddCaptureKeyL(request);
}
+/**
+Make a capture request update for normal key events to the key routing plug-in.
+
+@param aCaptureKey Key capture command from CWsHotKey::SetL()
+
+Note: this function is used only to disable hot key capture requests or to
+reset them to their defaults.
+*/
void CWsCaptureKey::SetL(const TWsWinCmdCaptureKey &aCaptureKey)
{
- TCaptureKey params;
- CmdToParams(aCaptureKey, params);
- TWindowServerEvent::SetCaptureKey((TUint32)this, params);
+ TKeyCaptureRequest request;
+ CmdToRequest(aCaptureKey, request);
+ TWindowServerEvent::UpdateCaptureKeyL(request);
}
void CWsCaptureKey::CommandL(TInt , const TAny *)
@@ -101,37 +132,39 @@
CWsCaptureKeyUpsAndDowns::~CWsCaptureKeyUpsAndDowns()
{
- iLink.Deque();
+ TWindowServerEvent::CancelCaptureKey(ECaptureTypeKeyUpDown, this);
}
+/**
+Construct a capture object for up/down key events and make a capture request
+to the key routing plug-in.
+
+@param aCaptureKey Key capture command from
+ RWindowGroup::CaptureKeyUpAndDowns().
+*/
void CWsCaptureKeyUpsAndDowns::ConstructL(const TWsWinCmdCaptureKey &aCaptureKey)
{
CheckProtectedKeyL(iWindowGroup, aCaptureKey);
NewObjL();
- iModifierMask=aCaptureKey.modifierMask;
- iModifierValue=aCaptureKey.modifiers;
- iScanCode=aCaptureKey.key;
- iLink.iPriority=aCaptureKey.priority + 1;
- iCaptureKeysUpsAndDowns.Add(*this);
- --iLink.iPriority;
+
+ TKeyCaptureRequest request;
+ request.iType = ECaptureTypeKeyUpDown;
+ request.iInputCode = aCaptureKey.key;
+ request.iOutputCode = aCaptureKey.key;
+ request.iModifiers = aCaptureKey.modifiers;
+ request.iModifierMask = aCaptureKey.modifierMask;
+ request.iPriority = aCaptureKey.priority;
+ request.iWindowGroup = iWindowGroup;
+ request.iWindowGroupId = iWindowGroup ? iWindowGroup->Identifier() : 0;
+ request.iAppUid = iWsOwner ? TUid::Uid(iWsOwner->SecureId().iId) : KNullUid;
+ request.iHandle = this;
+ TWindowServerEvent::AddCaptureKeyL(request);
}
void CWsCaptureKeyUpsAndDowns::CommandL(TInt , const TAny *)
{
}
-CWsWindowGroup *CWsCaptureKeyUpsAndDowns::CheckForCapture(TUint aScanCode, TUint aModifiers)
- {
- TDblQueIter<CWsCaptureKeyUpsAndDowns> iter(iCaptureKeysUpsAndDowns);
- CWsCaptureKeyUpsAndDowns* cap;
- while ((cap=iter++)!=NULL)
- {
- if (cap->iScanCode==aScanCode && (aModifiers&cap->iModifierMask)==cap->iModifierValue)
- return(cap->iWindowGroup);
- }
- return NULL;
- }
-
/*CWsCaptureLongKey*/
@@ -141,35 +174,40 @@
CWsCaptureLongKey::~CWsCaptureLongKey()
{
- iLink.Deque();
+ TWindowServerEvent::CancelCaptureKey(ECaptureTypeLongKey, this);
}
+/**
+Construct a capture object for long key events and make a capture request
+to the key routing plug-in.
+
+@param aCaptureKey Key capture command from RWindowGroup::CaptureLongKey()
+*/
void CWsCaptureLongKey::ConstructL(const TWsWinCmdCaptureLongKey &aCaptureKey)
{
NewObjL();
- iData=aCaptureKey;
- if (iData.delay.Int()<0)
+ iFlags = aCaptureKey.flags;
+ iDelay = aCaptureKey.delay;
+ if (iDelay.Int() < 0)
{
TTimeIntervalMicroSeconds32 time;
- CKeyboardRepeat::GetRepeatTime(iData.delay,time);
+ CKeyboardRepeat::GetRepeatTime(iDelay, time);
}
- iLink.iPriority=iData.priority + 1;
- iCaptureLongKeys.Add(*this);
- --iLink.iPriority;
+
+ TKeyCaptureRequest request;
+ request.iType = ECaptureTypeLongKey;
+ request.iInputCode = aCaptureKey.inputKey;
+ request.iOutputCode = aCaptureKey.outputKey;
+ request.iModifiers = aCaptureKey.modifiers;
+ request.iModifierMask = aCaptureKey.modifierMask;
+ request.iPriority = aCaptureKey.priority;
+ request.iWindowGroup = iWindowGroup;
+ request.iWindowGroupId = iWindowGroup ? iWindowGroup->Identifier() : 0;
+ request.iAppUid = iWsOwner ? TUid::Uid(iWsOwner->SecureId().iId) : KNullUid;
+ request.iHandle = this;
+ TWindowServerEvent::AddCaptureKeyL(request);
}
void CWsCaptureLongKey::CommandL(TInt , const TAny *)
{
}
-
-CWsCaptureLongKey* CWsCaptureLongKey::CheckForCapture(TUint aKeyCode, TInt aModifiers)
- {
- TDblQueIter<CWsCaptureLongKey> iter(iCaptureLongKeys);
- CWsCaptureLongKey* longCapture;
- while ((longCapture=iter++)!=NULL)
- {
- if (aKeyCode==longCapture->iData.inputKey && (aModifiers&longCapture->iData.modifierMask)==longCapture->iData.modifiers)
- return longCapture;
- }
- return NULL;
- }
--- a/windowing/windowserver/nga/SERVER/EVENT.CPP Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/nga/SERVER/EVENT.CPP Fri Sep 24 16:44:34 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1994-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -18,6 +18,7 @@
#include "EVENT.H"
#include "W32STD.H"
+#include <e32uid.h>
#include <hal.h>
#include <w32adll.h>
#include "W32CLICK.H"
@@ -32,12 +33,16 @@
#include "pointer.h"
#include "debugbar.h"
#include "advancedpointereventhelper.h"
+#include "Graphics/wsgraphicdrawerinternal.h"
GLREF_D CDebugLogBase *wsDebugLog;
GLREF_C void StateDump();
GLREF_C void HeapDump();
+_LIT(KDefaultKeyRouterPluginName, "keyrouter.dll");
+_LIT(KWSERVIniFileVarKeyRouterPlugin, "KEYROUTERPLUGIN");
+
#define IMPOSSIBLE 0xFFFFFFFF
const TWsWinCmdCaptureKey ImpossibleKeyPress=
@@ -160,6 +165,8 @@
TEventRequestQueue TWindowServerEvent::iScreenDeviceChangedQueue;
TTime TWindowServerEvent::iPrevOomMessageTime;
CCaptureKeys *TWindowServerEvent::iCaptureKeys;
+CKeyEventRouter* TWindowServerEvent::iKeyEventRouter;
+RLibrary TWindowServerEvent::iKeyEventRouterLibrary;
CWsHotKey *TWindowServerEvent::iHotKeys;
TInt TWindowServerEvent::iModifierState;
CRawEventReceiver *TWindowServerEvent::iEventReceiver;
@@ -172,12 +179,12 @@
TInt TWindowServerEvent::iEventHandlerCount=0;
TRepeatKey CKeyboardRepeat::iCurrentRepeat;
TRepeatKey CKeyboardRepeat::iAlternateRepeat;
+TRepeatKey CKeyboardRepeat::iLongRepeat;
TInt CKeyboardRepeat::iRepeatRollover=1;
CKeyboardRepeat::TRepeatType CKeyboardRepeat::iRepeating=ERepeatNone;
CKeyboardRepeat *CKeyboardRepeat::iThis=NULL;
TTimeIntervalMicroSeconds32 CKeyboardRepeat::iInitialTime;
TTimeIntervalMicroSeconds32 CKeyboardRepeat::iTime;
-CWsWindowGroup *CKeyboardRepeat::iFocus=NULL;
TBool CKeyboardRepeat::iAlternateRepeatExists=EFalse;
CWsCaptureLongKey* CKeyboardRepeat::iLongCapture=NULL;
@@ -198,6 +205,8 @@
{
DeleteHotKeys();
delete iCaptureKeys;
+ delete iKeyEventRouter;
+ iKeyEventRouterLibrary.Close();
CKeyboardRepeat::Destroy();
delete iKeyTranslator;
delete iEventReceiver;
@@ -231,8 +240,57 @@
iKeyTranslator->ChangeKeyData(keyDataDllName);
}
+ // CCaptureKeys is no longer used but a dummy object is required for
+ // calls to CKeyTranslator::TranslateKey() until capture functionality
+ // has been removed from ektran.dll.
iCaptureKeys=new(ELeave) CCaptureKeys;
iCaptureKeys->Construct();
+
+ // Load the key event routing plug-in. The DLL name may be overridden
+ // by setting the keyword KEYROUTERPLUGIN in wsini.ini.
+ TPtrC pluginName(KDefaultKeyRouterPluginName);
+ WsIniFile->FindVar(KWSERVIniFileVarKeyRouterPlugin, pluginName);
+ const TUidType uidType(KDynamicLibraryUid, KKeyRouterPluginUid);
+ TInt err = iKeyEventRouterLibrary.Load(pluginName, uidType);
+
+ if (wsDebugLog)
+ {
+ TLogMessageText buf;
+
+ if (err == KErrNone)
+ {
+ _LIT(KLogLoadOk, "Loaded plugin '%S' UID3 0x%x");
+ const TFileName& pluginPathname = iKeyEventRouterLibrary.FileName();
+ const TUid uid3 = iKeyEventRouterLibrary.Type()[2];
+ buf.Format(KLogLoadOk, &pluginPathname, uid3.iUid);
+ }
+ else
+ {
+ _LIT(KLogLoadError, "Failed to load plugin '%S' (error %d)");
+ buf.Format(KLogLoadError, &pluginName, err);
+ }
+
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogImportant, buf);
+ }
+
+ if (err != KErrNone)
+ {
+#ifdef _DEBUG
+ _LIT(KLoadError, "WServ: failed to load plugin '%S' (error %d)");
+ RDebug::Print(KLoadError, &pluginName, err);
+#endif
+ User::Leave(err);
+ }
+
+ // Create the key event router
+ typedef CKeyEventRouter* (*TCreateFunc)();
+ TCreateFunc newL = reinterpret_cast<TCreateFunc>(iKeyEventRouterLibrary.Lookup(1));
+ if (newL == NULL)
+ {
+ User::Leave(KErrNotFound);
+ }
+ iKeyEventRouter = (*newL)();
+
for (TInt index=0;index<TWindowServerEvent::ENumHotKeys;index++)
ConstructDefaultHotKeyL(index,DefaultHotKeys[index]);
CKeyboardRepeat::NewL();
@@ -312,6 +370,7 @@
captureKey.modifiers=aHotKey.modifiers;
captureKey.modifierMask=aHotKey.modifierMask;
captureKey.key=aHotKey.keycode;
+ captureKey.priority = 0;
hotKey->ConstructLD(captureKey);
//
LinkHotKey(hotKey);
@@ -622,6 +681,21 @@
TWsEvent event;
event.SetType(EEventDisplayChanged);
event.SetTimeNow();
+
+ // fill in the handle otherwise CONE will discard the notification
+ CWsObjectIx* clientObjList = aWsClient->ObjectIndex();
+ const TWsObject* ptr=clientObjList->FirstObject();
+ const TWsObject* end=ptr+clientObjList->Length();
+ while(++ptr<end) // first one should always have a NULL object
+ {
+ const CWsObject* obj=ptr->iObject;
+ if (obj && obj->Type()==WS_HANDLE_GROUP_WINDOW)
+ {
+ event.SetHandle(ptr->iHandle);
+ break;
+ }
+ }
+
TWsDisplayChangedEvent* dispEvent = event.DisplayChanged();
dispEvent->iDisplayNumber = aDisplayNumber;
dispEvent->iConfigurationChangeId = aConfigurationChangeId;
@@ -641,23 +715,68 @@
aWin->EventQueue()->QueueEvent(aEvent, aPriority);
}
-void TWindowServerEvent::QueueKeyPress(const TKeyData& aKey, TInt aScanCode, CWsWindowGroup* aRepeatFocus, TBool aCheckRepeat,TInt aRepeats)
+/**
+Process a key press event.
+
+This function is called for every input key event and uses the Key Event
+Routing plug-in to check for short and long key capture and determine the
+destination window group for the queued event(s).
+Window server hotkeys are also processed.
+Note that the key repeat timer is started here but the key repeat events
+generated by the timer go directly to QueueKeyPress().
+
+@param aKeyEvent Input key event
+@param aCheckRepeat Check for key repeat and long key capture
+@param aRepeats Repeat count
+*/
+void TWindowServerEvent::ProcessKeyPress(const TKeyEvent& aKeyEvent, TBool aCheckRepeat, TInt aRepeats)
{
- CWsWindowGroup* focusWin=CWsTop::FocusWindowGroup();
- TWsEvent event;
- TKeyEvent& keyEvent=*event.Key();
- keyEvent.iCode=aKey.iKeyCode;
- keyEvent.iScanCode=aScanCode;
- keyEvent.iModifiers=aKey.iModifiers;
- keyEvent.iRepeats=aRepeats;
- if (!aRepeatFocus && CClick::IsHandler())
- CClick::KeyEvent(EEventKey,keyEvent);
- CWsCaptureLongKey* longCapture=NULL;
- if (aCheckRepeat)
- longCapture=CWsCaptureLongKey::CheckForCapture(aKey.iKeyCode, aKey.iModifiers);
- if (aKey.iIsCaptureKey)
+ CWsWindowGroup* focusWin = CWsTop::FocusWindowGroup();
+ TUid focusAppUid = focusWin ? TUid::Uid(focusWin->Client()->SecureId().iId) : KNullUid;
+
+ // Route the key event and check for short key capture.
+ // Note that the Key Routing plugin may translate or block key events.
+ TKeyEventRouterInput input(ECaptureTypeKey, aKeyEvent, focusWin, focusAppUid);
+ TKeyEventRouterOutput output;
+
+#ifdef _DEBUG
+ // RouteKey() must not fail. Check for leaves in case the plug-in
+ // is badly behaved.
+ TRAPD(err, iKeyEventRouter->RouteKey(input, output));
+ WS_ASSERT_DEBUG(err == KErrNone, EWsPanicKeyEventRouterLeave);
+#else
+ iKeyEventRouter->RouteKey(input, output);
+#endif
+
+ WS_ASSERT_DEBUG(output.iResult == ERouted || output.iResult == ECaptured || output.iResult == EConsumed, EWsPanicKeyEventRouterBadResult);
+
+ if (output.iResult == EConsumed)
{
- if (aKey.iApp==NULL) // Captured by Wserv itself
+ focusWin = NULL;
+ }
+ else
+ {
+ focusWin = static_cast<CWsWindowGroup*>(output.iWindowGroup);
+ }
+ WS_ASSERT_DEBUG((focusWin == NULL || focusWin->Type() == WS_HANDLE_GROUP_WINDOW) && (output.iResult != ERouted || focusWin == CWsTop::FocusWindowGroup()), EWsPanicKeyEventRouterBadWindowGroup);
+
+ // Ensure that short event is not marked with EModifierLongKey
+ output.iKeyEvent.iModifiers &= ~EModifierLongKey;
+
+ // Generate key click unless the event is consumed. This is consistent
+ // with the behaviour when CKeyTranslator::TranslateKey() yields no
+ // translation for a particular scan code. (Click events for key up/down
+ // will still be generated by QueueKeyUpDown()). Note however that a long
+ // key press may still be captured even if the short event is consumed.
+ if (CClick::IsHandler() && output.iResult != EConsumed)
+ {
+ output.iKeyEvent.iRepeats = aRepeats;
+ CClick::KeyEvent(EEventKey, output.iKeyEvent);
+ }
+
+ if (output.iResult == ECaptured)
+ {
+ if (output.iWindowGroup == NULL) // Captured by Wserv itself
{
_LIT(KWSERVDebugLogCapturedKey,"WSERV Captured Key");
CScreen* focusScreen=CWsTop::CurrentFocusScreen();
@@ -668,7 +787,7 @@
CWsHotKey *hotKey=iHotKeys;
while(hotKey)
{
- if (hotKey->KeyHandle()==aKey.iHandle)
+ if (hotKey->KeyHandle() == reinterpret_cast<TInt>(output.iCaptureHandle))
{
switch(hotKey->HotKeyType())
{
@@ -753,22 +872,85 @@
WS_PANIC_ALWAYS(EWsPanicUnknownCaptureKey);
return;
}
- focusWin=((CWsWindowGroup *)aKey.iApp);
+
_LIT(KWSERVDebugLogKeyCapturedByApp,"Key captured by app %d");
if (wsDebugLog)
wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogKeyCapturedByApp,focusWin->Identifier());
if (CWsPassword::PasswordModeActive() && focusWin!=CWsPassword::PasswordWindow()->WinGroup())
return;
}
- if (aRepeatFocus && aRepeatFocus!=focusWin)
- CKeyboardRepeat::CancelRepeat(NULL); // Repeat is going to different window so cancel it and don't deliver this key
- else if (focusWin!=NULL && focusWin->CheckForPriorityKey(aKey,aScanCode)==EFalse)
+
+ CWsCaptureLongKey* longCapture = NULL;
+ TKeyEventRouterOutput longOutput;
+ if (aCheckRepeat)
{
- if (longCapture || (aCheckRepeat && !aRepeatFocus && aKey.iModifiers&EModifierAutorepeatable))
+ // Check for long key capture.
+ // Note that a long key event can only result from capture, there is
+ // no default detection or routing of long events.
+ input.iType = ECaptureTypeLongKey;
+#ifdef _DEBUG
+ TRAPD(err, iKeyEventRouter->RouteKey(input, longOutput));
+ WS_ASSERT_DEBUG(err == KErrNone, EWsPanicKeyEventRouterLeave);
+#else
+ iKeyEventRouter->RouteKey(input, longOutput);
+#endif
+
+ if (longOutput.iResult == ECaptured)
+ {
+ longCapture = static_cast<CWsCaptureLongKey*>(longOutput.iCaptureHandle);
+
+ // Mark long key events with EModifierLongKey so that applications
+ // can easily distinguish short and long events.
+ longOutput.iKeyEvent.iModifiers |= EModifierLongKey;
+
+ // Start timer to detect long key press
+ CKeyboardRepeat::StartRepeat(aKeyEvent.iScanCode, output, &longOutput);
+ }
+ else if (output.iResult != EConsumed && output.iKeyEvent.iModifiers & EModifierAutorepeatable)
{
- if (CKeyboardRepeat::StartRepeat(aKey,aScanCode,focusWin,longCapture))
- return;
+ // Start timer for key repeat
+ CKeyboardRepeat::StartRepeat(aKeyEvent.iScanCode, output, NULL);
}
+ }
+
+ // Queue the short event
+ if (!longCapture || longCapture->iFlags & ELongCaptureShortEventImmediately)
+ {
+ QueueKeyPress(output, EFalse, aRepeats);
+ }
+ }
+
+/**
+Queue a key press event.
+
+This function is called for each key event produced by ProcessKeyPress(),
+for every key repeat and long key event generated by the timer and also for
+delayed short key events from KeyUp().
+
+@param aOutput Output key event from routing plug-in
+@param aIsRepeat Event is due to key repeat
+@param aRepeats Repeat count
+*/
+void TWindowServerEvent::QueueKeyPress(const TKeyEventRouterOutput& aOutput, TBool aIsRepeat, TInt aRepeats)
+ {
+ if (aOutput.iResult == EConsumed)
+ {
+ // Don't deliver this key
+ return;
+ }
+
+ TWsEvent event;
+ TKeyEvent& keyEvent = *event.Key();
+ keyEvent = aOutput.iKeyEvent;
+ keyEvent.iRepeats = aRepeats;
+
+ CWsWindowGroup* focusWin = static_cast<CWsWindowGroup*>(aOutput.iWindowGroup);
+ WS_ASSERT_DEBUG(focusWin == NULL || focusWin->Type() == WS_HANDLE_GROUP_WINDOW, EWsPanicKeyEventRouterBadWindowGroup);
+
+ if (aIsRepeat && aOutput.iResult != ECaptured && focusWin != CWsTop::FocusWindowGroup())
+ CKeyboardRepeat::CancelRepeat(NULL); // Repeat is going to different window so cancel it and don't deliver this key
+ else if (focusWin != NULL && focusWin->CheckForPriorityKey(keyEvent) == EFalse)
+ {
event.SetType(EEventKey);
event.SetHandle(focusWin->ClientHandle());
if (aRepeats!=0)
@@ -776,18 +958,15 @@
CEventQueue* queue=focusWin->EventQueue();
queue->Wait();
const TWsEvent* prev=queue->PeekLastEvent();
- if (prev!=NULL && prev->Type()==EEventKey && prev->Key()->iRepeats>0)
+ if (prev != NULL && prev->Type() == EEventKey && prev->Key()->iRepeats > 0 && prev->Key()->iCode == keyEvent.iCode)
{
- event= *prev;
- event.Key()->iRepeats+=aRepeats;
- queue->UpdateLastEvent(event);
+ prev->Key()->iRepeats += aRepeats;
queue->Signal();
if (CClick::IsHandler())
- CClick::KeyEvent(EEventKeyRepeat,*event.Key());
+ CClick::KeyEvent(EEventKeyRepeat, *prev->Key());
return;
}
queue->Signal();
- event.Key()->iRepeats=aRepeats;
if (CClick::IsHandler())
CClick::KeyEvent(EEventKeyRepeat,keyEvent);
}
@@ -795,24 +974,69 @@
}
}
+/**
+Queue a key up/down event.
+
+@param aRawEvent Raw event
+*/
void TWindowServerEvent::QueueKeyUpDown(const TRawEvent &aRawEvent)
{
- CWsWindowGroup *focusWin=CWsCaptureKeyUpsAndDowns::CheckForCapture(aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE, iModifierState);
- if (!focusWin) // If not captured
- focusWin=CWsTop::FocusWindowGroup();
- TWsEvent event;
- TEventCode type=aRawEvent.Type()==TRawEvent::EKeyUp ? EEventKeyUp : EEventKeyDown;
- event.Key()->iCode=0;
+ TEventCode type = aRawEvent.Type() == TRawEvent::EKeyUp ? EEventKeyUp : EEventKeyDown;
+
+ // Check for key up/down capture
+ TKeyEvent keyEvent;
+ keyEvent.iScanCode = aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE;
+#if defined(__WINS__)
+ keyEvent.iCode = __WINS_CHARCODE(aRawEvent.ScanCode());
+#else
+ keyEvent.iCode = 0;
+#endif
+ keyEvent.iModifiers = iModifierState;
+ keyEvent.iRepeats = 0;
+
+ CWsWindowGroup* focusWin = CWsTop::FocusWindowGroup();
+ TUid focusAppUid = focusWin ? TUid::Uid(focusWin->Client()->SecureId().iId) : KNullUid;
+
+ TKeyEventRouterInput input(ECaptureTypeKeyUpDown, keyEvent, focusWin, focusAppUid);
+ TKeyEventRouterOutput output;
+#ifdef _DEBUG
+ TRAPD(err, iKeyEventRouter->RouteKey(input, output));
+ WS_ASSERT_DEBUG(err == KErrNone, EWsPanicKeyEventRouterLeave);
+#else
+ iKeyEventRouter->RouteKey(input, output);
+#endif
+
+ if (output.iResult == EConsumed)
+ {
+ // Don't deliver this key. A key click is still generated for the
+ // input event.
+ if (CClick::IsHandler())
+ {
+ CClick::KeyEvent(type, keyEvent);
+ }
+ return;
+ }
+ WS_ASSERT_DEBUG(output.iResult == ERouted || output.iResult == ECaptured, EWsPanicKeyEventRouterBadResult);
+
+ focusWin = static_cast<CWsWindowGroup*>(output.iWindowGroup);
+ WS_ASSERT_DEBUG((focusWin == NULL || focusWin->Type() == WS_HANDLE_GROUP_WINDOW) && (output.iResult != ERouted || focusWin == CWsTop::FocusWindowGroup()), EWsPanicKeyEventRouterBadWindowGroup);
#if defined(__WINS__)
if (focusWin && !focusWin->WsOwner()->RemoveKeyCode())
- event.Key()->iScanCode=aRawEvent.ScanCode();
- else
+ {
+ // Restore WINS character code
+ output.iKeyEvent.iScanCode |= output.iKeyEvent.iCode;
+ }
+ output.iKeyEvent.iCode = 0;
#endif
- event.Key()->iScanCode=aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE;
- event.Key()->iModifiers=iModifierState;
- event.Key()->iRepeats=0;
+
+ output.iKeyEvent.iRepeats = 0;
if (CClick::IsHandler())
- CClick::KeyEvent(type,*event.Key());
+ {
+ CClick::KeyEvent(type, output.iKeyEvent);
+ }
+
+ TWsEvent event;
+ *event.Key() = output.iKeyEvent;
if (focusWin!=NULL)
{
event.SetType(type);
@@ -921,6 +1145,11 @@
}
}
+/*
+Process a raw event
+
+@param aRawEvent Raw event
+*/
void TWindowServerEvent::ProcessRawEvent(const TRawEvent& aRawEvent)
//
// Event has completed.
@@ -1020,23 +1249,35 @@
case TRawEvent::EKeyDown:
{
_LIT(KWSERVDebugLogKeyDownArrival,"Key down arrives %d");
- if(CDebugBar* dbg = CWsTop::Screen()->DebugBar())
+ CScreen* screen = CWsTop::Screen();
+ WS_ASSERT_ALWAYS(screen, EWsPanicNoScreen);
+ if(CDebugBar* dbg = screen->DebugBar())
dbg->OnKeyEvent();
if (wsDebugLog)
wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogKeyDownArrival,aRawEvent.ScanCode());
CKeyboardRepeat::KeyDown();
TKeyData keyData;
+ // Note iCaptureKeys is needed as dummy arg only. Key capture is
+ // now handled in ProcessKeyPress().
TBool translated=iKeyTranslator->TranslateKey(aRawEvent.ScanCode(), EFalse,*iCaptureKeys,keyData);
ProcessModifierChanges();
QueueKeyUpDown(aRawEvent);
if (translated)
- QueueKeyPress(keyData,aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE,NULL,ETrue,0);
+ {
+ TKeyEvent keyEvent;
+ keyEvent.iScanCode = aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE;
+ keyEvent.iCode = keyData.iKeyCode;
+ keyEvent.iModifiers = keyData.iModifiers;
+ ProcessKeyPress(keyEvent, ETrue, 0);
+ }
}
break;
case TRawEvent::EKeyUp:
{
_LIT(KWSERVDebugLogKeyUpArrival,"Key up arrives %d");
- if(CDebugBar* dbg = CWsTop::Screen()->DebugBar())
+ CScreen* screen = CWsTop::Screen();
+ WS_ASSERT_ALWAYS(screen, EWsPanicNoScreen);
+ if(CDebugBar* dbg = screen->DebugBar())
dbg->OnKeyEvent();
if (wsDebugLog)
wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogKeyUpArrival,aRawEvent.ScanCode());
@@ -1048,7 +1289,11 @@
if (translated)
{
CKeyboardRepeat::CancelRepeat(NULL);
- QueueKeyPress(keyData,aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE,NULL,EFalse,0);
+ TKeyEvent keyEvent;
+ keyEvent.iScanCode = aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE;
+ keyEvent.iCode = keyData.iKeyCode;
+ keyEvent.iModifiers = keyData.iModifiers;
+ ProcessKeyPress(keyEvent, EFalse, 0);
}
}
break;
@@ -1079,14 +1324,11 @@
_LIT(KWSERVDebugLogRepeatingKeyArrival,"Repeating key arrives %d");
if (wsDebugLog)
wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogRepeatingKeyArrival,aRawEvent.ScanCode());
- TKeyData keyData;
- keyData.iModifiers=iKeyTranslator->GetModifierState();
- keyData.iApp=0;
- keyData.iHandle=0;
- keyData.iIsCaptureKey=EFalse;
- keyData.iKeyCode=aRawEvent.ScanCode();
- iCaptureKeys->ProcessCaptureKeys(keyData);
- QueueKeyPress(keyData, aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE,NULL,EFalse,aRawEvent.Repeats());
+ TKeyEvent keyEvent;
+ keyEvent.iScanCode = aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE;
+ keyEvent.iCode = aRawEvent.ScanCode();
+ keyEvent.iModifiers = iKeyTranslator->GetModifierState();
+ ProcessKeyPress(keyEvent, EFalse, aRawEvent.Repeats());
}
break;
default:
@@ -1096,33 +1338,26 @@
void TWindowServerEvent::ProcessKeyEvent(const TKeyEvent &aKeyEvent,TInt aRepeats)
{
- TKeyData keyData;
- keyData.iModifiers=aKeyEvent.iModifiers;
- keyData.iApp=0;
- keyData.iHandle=0;
- keyData.iIsCaptureKey=EFalse;
- keyData.iKeyCode=aKeyEvent.iCode;
if (CKeyboardRepeat::IsAreadyActive())
{
CKeyboardRepeat::CancelRepeat(NULL);
}
- iCaptureKeys->ProcessCaptureKeys(keyData);
- QueueKeyPress(keyData,aKeyEvent.iScanCode,NULL,aRepeats==0,aRepeats);
+ ProcessKeyPress(aKeyEvent, aRepeats == 0, aRepeats);
}
-void TWindowServerEvent::AddCaptureKeyL(const TCaptureKey &aCaptureKey)
+void TWindowServerEvent::AddCaptureKeyL(const TKeyCaptureRequest& aRequest)
{
- iCaptureKeys->AddCaptureKeyL(aCaptureKey,aCaptureKey.iKeyCodePattern.iFiller);
+ iKeyEventRouter->AddCaptureKeyL(aRequest);
}
-void TWindowServerEvent::SetCaptureKey(TUint32 aHandle, const TCaptureKey &aCaptureKey)
+void TWindowServerEvent::UpdateCaptureKeyL(const TKeyCaptureRequest& aRequest)
{
- iCaptureKeys->SetCaptureKey(aHandle, aCaptureKey,aCaptureKey.iKeyCodePattern.iFiller);
+ iKeyEventRouter->UpdateCaptureKeyL(aRequest);
}
-void TWindowServerEvent::CancelCaptureKey(TUint32 aHandle)
+void TWindowServerEvent::CancelCaptureKey(TKeyCaptureType aType, TAny* aHandle)
{
- iCaptureKeys->CancelCaptureKey(aHandle);
+ iKeyEventRouter->CancelCaptureKey(aType, aHandle);
}
TInt TWindowServerEvent::GetModifierState()
@@ -1463,21 +1698,27 @@
iTime=aTime;
}
+/**
+Process timer events.
+
+Called when the key repeat timer expires, this function generates the
+appropriate long key or repeated key event. If the timer was started for
+normal key repeat or if the long key event was captured with the automatic
+repeat option specified then the timer is restarted.
+*/
void CKeyboardRepeat::RunL()
{
User::ResetInactivityTime();
- //WS_ASSERT_DEBUG(iRepeating!=ERepeatNone, EWsPanicTemp);
+ WS_ASSERT_DEBUG(iRepeating != ERepeatNone, EWsPanicKeyRepeat);
TBool timer=ETrue;
if (iRepeating>=ERepeatLong)
{
// Defensive programming - iLongCapture should never be NULL if iRepeating >= ERepeatLong
+ WS_ASSERT_DEBUG(iLongCapture != NULL, EWsPanicKeyRepeat);
if (iLongCapture)
{
- iCurrentRepeat.iKey.iApp=REINTERPRET_CAST(TUint32,iLongCapture->iWindowGroup);
- iCurrentRepeat.iKey.iHandle=0;
- iCurrentRepeat.iKey.iIsCaptureKey=ETrue;
- iCurrentRepeat.iKey.iKeyCode=iLongCapture->iData.outputKey;
- timer=iLongCapture->iData.flags&ELongCaptureRepeatEvents;
+ iCurrentRepeat = iLongRepeat;
+ timer = iLongCapture->iFlags & ELongCaptureRepeatEvents;
iRepeating=ERepeatLongRepeated;
}
else
@@ -1491,53 +1732,67 @@
After(iTime);
else
iRepeating=ERepeatNone;
- TWindowServerEvent::QueueKeyPress(iCurrentRepeat.iKey,iCurrentRepeat.iScanCode,iFocus,EFalse,1);
+
+ TWindowServerEvent::QueueKeyPress(iCurrentRepeat.iOutput, ETrue, 1);
}
-TBool CKeyboardRepeat::StartRepeat(const TKeyData &aKey, TInt aScanCode, CWsWindowGroup *aRepeatFocus, CWsCaptureLongKey* aLongCapture)
+/**
+Start key repeat and long key press timer
+
+@param aInputScanCode Original scan code (before routing)
+@param aShortEvent Short key event (routing plug-in output)
+@param aLongEvent Pointer to long key event (routing plug-in output)
+ or NULL if none.
+
+Note: When aLongEvent != NULL, iCurrentRepeat reflects the short key event
+until the timer has expired. This is necessary to allow a delayed short key
+event to be delivered by KeyUp(). CancelRepeat() must therefore examine
+iCurrentRepeat or iLongRepeat according to the repeat type in iRepeat.
+*/
+void CKeyboardRepeat::StartRepeat(TInt aInputScanCode, const TKeyEventRouterOutput& aShortEvent, const TKeyEventRouterOutput* aLongEvent)
{
TTimeIntervalMicroSeconds32 time;
- TBool ret=EFalse;
- iCurrentRepeat.iScanCode=aScanCode;
- iCurrentRepeat.iKey=aKey;
+ iCurrentRepeat.iInputScanCode = aInputScanCode;
+ iCurrentRepeat.iOutput = aShortEvent;
- if (aLongCapture)
+ if (aLongEvent)
{
- iLongCapture=aLongCapture;
- iRepeating=ERepeatLong;
- time=aLongCapture->iData.delay;
- ret=!(aLongCapture->iData.flags&ELongCaptureShortEventImmediately);
- //need window group from long capture key or even better delete it altogether.
- iFocus=aLongCapture->WindowGroup();
+ iRepeating = ERepeatLong;
+ iLongRepeat.iInputScanCode = aInputScanCode;
+ iLongRepeat.iOutput = *aLongEvent;
+ iLongCapture = static_cast<CWsCaptureLongKey*>(aLongEvent->iCaptureHandle);
+ time = iLongCapture->iDelay;
}
else
{
- iFocus=aRepeatFocus;
+ iLongCapture = NULL;
iRepeating=ERepeatNormal;
time=iInitialTime;
}
iThis->After(time);
- return ret;
}
+/**
+Cancel key repeat processing
+*/
void CKeyboardRepeat::doCancelRepeat()
{
iRepeating=ERepeatNone;
iThis->Cancel();
}
+/**
+Cancel any key repeat associated with the specified window group
+
+@param aRepeatFocus Destination window group or NULL for all
+*/
void CKeyboardRepeat::CancelRepeat(CWsWindowGroup *aRepeatFocus)
{
- if (aRepeatFocus==NULL || aRepeatFocus==iFocus)
+ if (iRepeating != ERepeatNone)
{
- if (iRepeating)
- doCancelRepeat();
- iAlternateRepeatExists=EFalse;
- }
- else if (iRepeating >= ERepeatLong)
- {
- // Defensive programming - iLongCapture should never be NULL if iRepeating >= ERepeatLong
- if (iLongCapture && iLongCapture->iWindowGroup == aRepeatFocus)
+ if (aRepeatFocus == NULL ||
+ (iRepeating == ERepeatNormal) && (aRepeatFocus == iCurrentRepeat.iOutput.iWindowGroup) ||
+ (iRepeating >= ERepeatLong) && (aRepeatFocus == iLongRepeat.iOutput.iWindowGroup))
{
doCancelRepeat();
iAlternateRepeatExists=EFalse;
@@ -1545,36 +1800,38 @@
}
}
-void CKeyboardRepeat::CancelRepeat(CWsWindowGroup *aRepeatFocus,TUint aScanCode,TBool aLongCaptureFlag,TUint aModifiers)
+/**
+Cancel any key repeat associated with the specified capture handle
+
+@param aCaptureHandle Handle to capture request
+@param aLongCaptureFlag ETrue for long key capture, EFalse for normal key
+*/
+void CKeyboardRepeat::CancelRepeat(const TAny* aCaptureHandle, TBool aLongCaptureFlag)
{
if (aLongCaptureFlag)
{
- // long capture key is cancelled
- if (iRepeating >= ERepeatLong && iCurrentRepeat.iScanCode==aScanCode)
- {
- // Defensive programming - iLongCapture should never be NULL if iRepeating >= ERepeatLong
- if (iLongCapture && aRepeatFocus == iLongCapture->iWindowGroup &&
- (aModifiers & iLongCapture->iData.modifierMask) == iLongCapture->iData.modifiers)
- {
- doCancelRepeat();
- iAlternateRepeatExists=EFalse;
- }
- }
+ // Cancel repeat for long capture key
+ if (iRepeating >= ERepeatLong && aCaptureHandle == iLongRepeat.iOutput.iCaptureHandle)
+ {
+ doCancelRepeat();
+ iAlternateRepeatExists=EFalse;
+ }
}
else
{
- // normal capture key is cancelled
- if (aRepeatFocus==iFocus)
+ // Cancel repeat for normal capture key
+ if (iRepeating == ERepeatNormal && aCaptureHandle == iCurrentRepeat.iOutput.iCaptureHandle)
{
- if (iRepeating>=ERepeatNormal && iCurrentRepeat.iScanCode==aScanCode)
- {
- doCancelRepeat();
- }
+ doCancelRepeat();
iAlternateRepeatExists=EFalse;
}
}
}
+/**
+Process a key down event during key repeat.
+The current repeat data is saved for possible restoration after rollover.
+*/
void CKeyboardRepeat::KeyDown()
{
if (iRepeating!=ERepeatNone)
@@ -1588,18 +1845,26 @@
}
}
+/**
+Process a key up event during key repeat.
+Send delayed short key event if necessary for long key event processing.
+Switch to alternate repeat if rollover key was released.
+
+@param aScanCode Scan code
+*/
void CKeyboardRepeat::KeyUp(TInt aScanCode)
{
- if (iAlternateRepeatExists && iAlternateRepeat.iScanCode==aScanCode)
+ if (iAlternateRepeatExists && iAlternateRepeat.iInputScanCode == aScanCode)
iAlternateRepeatExists=EFalse;
- if (iRepeating!=ERepeatNone && iCurrentRepeat.iScanCode==aScanCode)
+ if (iRepeating != ERepeatNone && iCurrentRepeat.iInputScanCode == aScanCode)
{
if (iRepeating==ERepeatLong)
{
// Defensive programming - iLongCapture should never be NULL if iRepeating >= ERepeatLong
- if (iLongCapture && !(iLongCapture->iData.flags&ELongCaptureShortEventImmediately))
+ WS_ASSERT_DEBUG(iLongCapture != NULL, EWsPanicKeyRepeat);
+ if (iLongCapture && !(iLongCapture->iFlags & ELongCaptureShortEventImmediately))
{
- TWindowServerEvent::QueueKeyPress(iCurrentRepeat.iKey,iCurrentRepeat.iScanCode,NULL,EFalse,0);
+ TWindowServerEvent::QueueKeyPress(iCurrentRepeat.iOutput, EFalse, 0);
}
}
if (iAlternateRepeatExists)
--- a/windowing/windowserver/nga/SERVER/EVENT.H Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/nga/SERVER/EVENT.H Fri Sep 24 16:44:34 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1999-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -28,6 +28,7 @@
#include "EVQUEUE.H"
#include <w32adll.h>
#include "Graphics/WSGRAPHICDRAWER.H"
+#include <graphics/wskeyrouter.h>
class CWsClient;
class CWsWindowBase;
@@ -78,8 +79,8 @@
class TRepeatKey
{
public:
- TKeyData iKey;
- TInt iScanCode;
+ TKeyEventRouterOutput iOutput;
+ TInt iInputScanCode;
};
class CKeyboardRepeat : public CTimer
@@ -90,9 +91,9 @@
static void Destroy();
static void KeyDown();
static void KeyUp(TInt aScanCode);
- static TBool StartRepeat(const TKeyData &aKey, TInt aScanCode, CWsWindowGroup *aRepeatFocus, CWsCaptureLongKey* longCapture);
+ static void StartRepeat(TInt aInputScanCode, const TKeyEventRouterOutput& aShortEvent, const TKeyEventRouterOutput* aLongEvent);
static void CancelRepeat(CWsWindowGroup *aRepeatFocus);
- static void CancelRepeat(CWsWindowGroup *aRepeatFocus,TUint aScanCode,TBool aLongCaptureFlag,TUint aModifiers=0);
+ static void CancelRepeat(const TAny* aCaptureHandle, TBool aLongCaptureFlag);
static void SetRepeatTime(const TTimeIntervalMicroSeconds32 &aInitialTime, const TTimeIntervalMicroSeconds32 &aTime);
static void GetRepeatTime(TTimeIntervalMicroSeconds32 &aInitialTime, TTimeIntervalMicroSeconds32 &aTime);
static inline TBool IsAreadyActive();
@@ -108,13 +109,13 @@
static void doCancelRepeat();
void RunL();
private:
- static CWsWindowGroup *iFocus;
static CKeyboardRepeat *iThis; // Needed as CTimer derived parts can't be static
static TTimeIntervalMicroSeconds32 iInitialTime;
static TTimeIntervalMicroSeconds32 iTime;
+ static TRepeatType iRepeating;
static TRepeatKey iCurrentRepeat;
- static TRepeatType iRepeating;
static TRepeatKey iAlternateRepeat;
+ static TRepeatKey iLongRepeat;
static TBool iAlternateRepeatExists;
static CWsCaptureLongKey* iLongCapture;
static TInt iRepeatRollover;
@@ -174,9 +175,9 @@
static CWsHotKey* ClearHotKeysL(TInt aHotKey);
static void ResetDefaultHotKeyL(TInt aHotKey);
static void SetHotKeyL(const TWsClCmdSetHotKey &aHotKey);
- static void AddCaptureKeyL(const TCaptureKey &aCaptureKey);
- static void SetCaptureKey(TUint32 aHandle, const TCaptureKey &aCaptureKey);
- static void CancelCaptureKey(TUint32 aHandle);
+ static void AddCaptureKeyL(const TKeyCaptureRequest& aRequest);
+ static void UpdateCaptureKeyL(const TKeyCaptureRequest& aRequest);
+ static void CancelCaptureKey(TKeyCaptureType aType, TAny* aHandle);
static void ClientDestroyed(CWsClient *aClient);
static inline void AddToSwitchOnEventListL(const CWsWindowBase &aWindow, TEventControl aCircumstances);
static inline void RemoveFromSwitchOnEventList(const CWsWindowBase &aWindow);
@@ -207,7 +208,8 @@
static void SendScreenDeviceChangedEvent(const CWsWindowBase *aWindow);
static TBool ProcessErrorMessages(TWsErrorMessage::TErrorCategory aCategory, TInt aError);
static void NotifyOom();
- static void QueueKeyPress(const TKeyData& aKey, TInt aScanCode, CWsWindowGroup* aRepeatFocus, TBool aCheckRepeat,TInt aRepeats);
+ static void ProcessKeyPress(const TKeyEvent& aKeyEvent, TBool aCheckRepeat,TInt aRepeats);
+ static void QueueKeyPress(const TKeyEventRouterOutput& aOutput, TBool aIsRepeat, TInt aRepeats);
static void AddEventHandler(MEventHandler *aEventHandler, TBool aAdvancedPointersEnabled);
static void RemoveEventHandler(const MEventHandler *aEventHandler);
static void PotentialEventHandlerL(TInt aNum);
@@ -250,6 +252,8 @@
static TEventRequestQueue iScreenDeviceChangedQueue;
static TTime iPrevOomMessageTime;
static CCaptureKeys *iCaptureKeys;
+ static CKeyEventRouter *iKeyEventRouter;
+ static RLibrary iKeyEventRouterLibrary;
static CWsHotKey *iHotKeys;
static TInt iModifierState;
static CRawEventReceiver *iEventReceiver;
--- a/windowing/windowserver/nga/SERVER/PRIKEY.CPP Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/nga/SERVER/PRIKEY.CPP Fri Sep 24 16:44:34 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1996-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -23,7 +23,7 @@
__DECLARE_NAME(_S("CPriorityKey"));
}
-void CPriorityKey::PriorityKey(TInt aHandle, const TKeyData &aKey, TInt aScanCode)
+void CPriorityKey::PriorityKey(TInt aHandle, const TKeyEvent &aKeyEvent)
//
// Called when a priority key is pressed
//
@@ -31,8 +31,7 @@
if (!iEventMsg.IsNull())
{
iPriorityKeyHandle=aHandle;
- iPriorityKey=aKey;
- iScanCode=aScanCode;
+ iPriorityKey = aKeyEvent;
SignalEvent();
}
}
@@ -43,11 +42,8 @@
//
{
TWsPriorityKeyEvent event;
- TKeyEvent *key=event.Key();
- key->iScanCode=iScanCode;
- key->iCode=iPriorityKey.iKeyCode;
- key->iModifiers=iPriorityKey.iModifiers;
- key->iRepeats=0;
+ *event.Key() = iPriorityKey;
+ event.Key()->iRepeats = 0;
event.SetHandle(iPriorityKeyHandle);
CEventBase::GetData(&event,sizeof(event));
iPriorityKeyHandle=0;
@@ -65,7 +61,7 @@
return(iKeyCode==aKeycode && iModifierMask==aModifierMask && iModifiers==aModifiers);
}
-TInt TPriorityKey::KeyMatches(const TKeyData &aKey)
+TInt TPriorityKey::KeyMatches(const TKeyEvent &aKeyEvent)
{
- return(iKeyCode==aKey.iKeyCode && (iModifierMask&aKey.iModifiers)==iModifiers);
+ return(iKeyCode == aKeyEvent.iCode && (iModifierMask & aKeyEvent.iModifiers) == iModifiers);
}
--- a/windowing/windowserver/nga/SERVER/PRIKEY.H Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/nga/SERVER/PRIKEY.H Fri Sep 24 16:44:34 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1999-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -37,7 +37,7 @@
public:
TPriorityKey(TUint aKeycode,TUint aModifierMask,TUint aModifiers,TPriorityKey *aPriorityKeys);
TInt Equals(TUint aKeycode,TUint aModifierMask,TUint aModifiers);
- TInt KeyMatches(const TKeyData &aKey);
+ TInt KeyMatches(const TKeyEvent &aKeyEvent);
public:
TPriorityKey *iNext;
private:
@@ -50,12 +50,11 @@
{
public:
CPriorityKey(CWsClient *aOwner);
- void PriorityKey(TInt aHandle, const TKeyData &aKey, TInt aScanCode);
+ void PriorityKey(TInt aHandle, const TKeyEvent &aKeyEvent);
void GetData();
private:
TInt iPriorityKeyHandle;
- TKeyData iPriorityKey;
- TInt iScanCode;
+ TKeyEvent iPriorityKey;
};
#endif
--- a/windowing/windowserver/nga/SERVER/openwfc/CLIENT.CPP Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/nga/SERVER/openwfc/CLIENT.CPP Fri Sep 24 16:44:34 2010 +0300
@@ -1286,6 +1286,9 @@
case EWsClOpCreateDrawableSource:
CreateDrawableSourceL(*pData.CreateDrawableSource);
break;
+ case EWsClOpIndicateAppOrientation:
+ IndicateAppOrientation(*pData.Orientation);
+ break;
default:
PPanic(EWservPanicOpcode);
break;
@@ -2138,6 +2141,17 @@
drawableSource->ConstructL(aDrawableSourceData);
CleanupStack::Pop();
}
+
+void CWsClient::IndicateAppOrientation(TRenderOrientation aOrientation)
+ {
+ iIndicatedAppOrientation = aOrientation;
+ CWsTop::CheckRenderOrientation();
+ }
+
+TInt CWsClient::GetIndicatedAppOrientation()
+ {
+ return iIndicatedAppOrientation;
+ }
//
// class CWsCliObj
--- a/windowing/windowserver/nga/SERVER/openwfc/CLIENT.H Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/nga/SERVER/openwfc/CLIENT.H Fri Sep 24 16:44:34 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1999-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -146,7 +146,7 @@
inline void PurgePointerEvents();
// Key events
- inline void PriorityKeyPressed(TInt aHandle, const TKeyData &aKey, TInt aScanCode);
+ inline void PriorityKeyPressed(TInt aHandle, const TKeyEvent &aKeyEvent);
// Notification of misc events
void AddNotificationL(TInt aKey, const RMessage2& aClientMsg);
@@ -168,6 +168,9 @@
TBool RetryEvent(TEventCode aEventCode);
inline void WgMsgQueueOverflow();// Set flag window group message queue is overflow and has pending messages
+
+ //Get orientation value that app indicated
+ TInt GetIndicatedAppOrientation();
private: // from MWsClient
TInt SendMessage(const CWsGraphicDrawer* aOnBehalfOf, const TDesC8& aData);
@@ -255,6 +258,10 @@
// Misc
void SetComputeMode(RWsSession::TComputeMode aComputeMode);
+
+ //Set orientation that application indicated
+ void IndicateAppOrientation(TRenderOrientation aOrientation);
+
public:
static TWsCmdHeaderBase iCurrentCommand;
private:
@@ -293,6 +300,7 @@
RMessage2 iClientMessage;
RHandleBase* iResponseHandle;
TInt iMessageIdSeq;
+ TInt iIndicatedAppOrientation;
//Members for procerssing command buffer
static CWsClient* iCurrentClient; // Client who's buffer is currently being processed
@@ -363,8 +371,8 @@
inline void CWsClient::HandleClientRequestForPriorityKeyData()
{iPriorityKeyEvent->GetData();}
-inline void CWsClient::PriorityKeyPressed(TInt aHandle, const TKeyData &aKey, TInt aScanCode)
- {iPriorityKeyEvent->PriorityKey(aHandle,aKey,aScanCode);}
+inline void CWsClient::PriorityKeyPressed(TInt aHandle, const TKeyEvent &aKeyEvent)
+ {iPriorityKeyEvent->PriorityKey(aHandle, aKeyEvent);}
inline TInt CWsClient::ObjectHandle(const CWsObject* aThis) const
{return(iObjectIndex->At(aThis));}
--- a/windowing/windowserver/nga/SERVER/openwfc/GROUPWIN.CPP Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/nga/SERVER/openwfc/GROUPWIN.CPP Fri Sep 24 16:44:34 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1995-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -515,9 +515,8 @@
CWsObject *destroyObj = iWsOwner->HandleToObj(*pData.UInt, WS_HANDLE_CAPTURE_KEY);
if (destroyObj)
{
- //Cancel any repeat that is underway for this key
- const TWsWinCmdCaptureKey& capKey(*pData.CaptureKey);
- CKeyboardRepeat::CancelRepeat(this,capKey.key,EFalse,capKey.modifierMask);
+ // Cancel any repeat that is underway for this capture
+ CKeyboardRepeat::CancelRepeat(destroyObj, EFalse);
delete destroyObj;
}
else
@@ -535,9 +534,6 @@
CWsObject *destroyObj = iWsOwner->HandleToObj(*pData.UInt, WS_HANDLE_CAPTURE_KEY_UPDOWNS);
if (destroyObj)
{
- //Cancel any repeat that is underway for this key
- const TWsWinCmdCaptureKey& capKey(*pData.CaptureKey);
- CKeyboardRepeat::CancelRepeat(this,capKey.key,EFalse,capKey.modifierMask);
delete destroyObj;
}
else
@@ -555,9 +551,8 @@
CWsObject *destroyObj = iWsOwner->HandleToObj(*pData.UInt, WS_HANDLE_CAPTURE_LONG_KEY);
if (destroyObj)
{
- //Cancel any repeat that is underway for this key
- const TWsWinCmdCaptureLongKey& capKey(*pData.CaptureLongKey);
- CKeyboardRepeat::CancelRepeat(this,capKey.inputKey,ETrue,capKey.modifierMask);
+ // Cancel any repeat that is underway for this capture
+ CKeyboardRepeat::CancelRepeat(destroyObj, ETrue);
delete destroyObj;
}
else
@@ -906,6 +901,12 @@
TBool CWsWindowGroup::SetOrdinalPosition(TInt aPos,CWsWindowGroup* aClosingWindow)
{
TBool ret=ETrue;
+
+ // Remember if the window group tree is actually changed or not, so that we know whether to
+ // check the render orientation after the re-ordering is done ( see CWsTop::CheckRenderOrientation()
+ // call at end of this method
+ TBool changed = CheckOrdinalPositionChange(aPos);
+
if (!iQueue)
ret=DoSetOrdinalPosition1(aPos,aClosingWindow);
else
@@ -962,6 +963,11 @@
#endif
}
+ // If the ordinal positions have changed, check to see if there is a new render orientation
+ // and publish it if so
+ if(changed)
+ CWsTop::CheckRenderOrientation();
+
return ret;
}
@@ -1348,13 +1354,13 @@
}
}
-TBool CWsWindowGroup::CheckForPriorityKey(const TKeyData &aKey, TInt aScanCode)
+TBool CWsWindowGroup::CheckForPriorityKey(const TKeyEvent &aKeyEvent)
{
for(TPriorityKey *pk=iPriorityKeys;pk;pk=pk->iNext)
{
- if (pk->KeyMatches(aKey))
+ if (pk->KeyMatches(aKeyEvent))
{
- WsOwner()->PriorityKeyPressed(ClientHandle(),aKey, aScanCode);
+ WsOwner()->PriorityKeyPressed(ClientHandle(), aKeyEvent);
return(ETrue);
}
}
--- a/windowing/windowserver/nga/SERVER/openwfc/WSTOP.CPP Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/nga/SERVER/openwfc/WSTOP.CPP Fri Sep 24 16:44:34 2010 +0300
@@ -46,6 +46,7 @@
#include "registeredsurfacemap.h"
#include "windowelementset.h"
#include "wspluginmanager.h"
+#include "renderorientationtracker.h"
// IDs of p&s properties that optionally contain callbacks that may be used
// to release singletons owned by libraries at shutdown in order to make
@@ -209,6 +210,7 @@
TInt CWsTop::iCheckHeapResult=KErrNotReady;
TBool CWsTop::iDoHeapCheckAndRestart=EFalse;
#define RFbsSession_SendCommand_ShutDownMessage 1 // A FBS message that is not published yet and probably never will be.
+CWsRenderOrienationTracker* CWsTop::iRenderOrientationTracker=NULL;
static void DefineSingletonKey(const TUid& aSingletonKey)
/**
@@ -281,6 +283,8 @@
void CWsTop::DeleteStaticsL()
{
iShuttingDown=ETrue;
+ delete iRenderOrientationTracker;
+
CClick::DeleteStatics();
TWsPointer::Stop();
CWsClient::DeleteStatics();
@@ -553,6 +557,8 @@
StartShell();
}
UserSvr::WsRegisterSwitchOnScreenHandling(ETrue);
+
+ iRenderOrientationTracker = CWsRenderOrienationTracker::NewL();
}
@@ -958,6 +964,18 @@
return EFalse;
}
+/**
+Checks to see if the render orientation has changed, and publishes any new orientaion
+via publish and subscribe
+
+@see KRenderOrientationCategory
+@see KRenderOrientationKey
+*/
+void CWsTop::CheckRenderOrientation()
+ {
+ iRenderOrientationTracker->CheckRenderOrientation();
+ }
+
typedef TInt (*ShellEntryPoint)(TAny *);
#if defined(__WINS__)
--- a/windowing/windowserver/nga/SERVER/openwfc/server.h Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/nga/SERVER/openwfc/server.h Fri Sep 24 16:44:34 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1999-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -27,7 +27,9 @@
#include "OBJECT.H"
#include "CLIENT.H"
#include "ScrDev.H"
+#include <graphics/wskeyrouter.h>
#include <Graphics/WSGRAPHICDRAWERINTERFACE.H>
+#include "Graphics/wsgraphicdrawerinternal.h"
#include "WSGRAPHICDRAWERARRAY.H"
#include "panics.h"
@@ -150,7 +152,7 @@
inline CWsWindowGroup *WindowGroup();
inline const CWsWindowGroup *WindowGroup() const;
private:
- void CmdToParams(const TWsWinCmdCaptureKey &aCaptureKey, TCaptureKey &aParams);
+ void CmdToRequest(const TWsWinCmdCaptureKey &aCaptureKey, TKeyCaptureRequest &aParams);
private:
CWsWindowGroup *iWindowGroup;
};
@@ -181,21 +183,16 @@
~CWsCaptureKeyUpsAndDowns();
void ConstructL(const TWsWinCmdCaptureKey &aCaptureKey);
void CommandL(TInt aOpcode, const TAny *aCmdData);
- static CWsWindowGroup *CheckForCapture(TUint aScanCode, TUint aModifiers);
inline CWsWindowGroup *WindowGroup();
inline const CWsWindowGroup *WindowGroup() const;
private:
- TUint iModifierValue;
- TUint iModifierMask;
- TUint iScanCode;
- static TPriQue<CWsCaptureKeyUpsAndDowns> iCaptureKeysUpsAndDowns;
- TPriQueLink iLink;
CWsWindowGroup *iWindowGroup;
};
class CWsCaptureLongKey : public CWsObject
{
friend class CKeyboardRepeat;
+ friend class TWindowServerEvent;
public:
CWsCaptureLongKey(CWsWindowGroup *owner);
~CWsCaptureLongKey();
@@ -203,13 +200,10 @@
void CommandL(TInt aOpcode, const TAny *aCmdData);
inline CWsWindowGroup *WindowGroup();
inline const CWsWindowGroup *WindowGroup() const;
- static CWsCaptureLongKey* CheckForCapture(TUint aKeyCode, TInt aModifiers);
-public:
- static TPriQue<CWsCaptureLongKey> iCaptureLongKeys;
private:
- TPriQueLink iLink;
+ TTimeIntervalMicroSeconds32 iDelay;
+ TUint iFlags;
CWsWindowGroup *iWindowGroup;
- TWsWinCmdCaptureLongKey iData;
};
//--------------------------------
@@ -340,6 +334,7 @@
void StartL();
TInt SessionCount();
MWsAnimationScheduler* AnimationScheduler();
+ void PrepareShutdown();
TBool ReleaseMemory();
void DestroySessionsForShutdown();
void SetPinClientDescriptors(TBool aPin);
--- a/windowing/windowserver/nga/SERVER/openwfc/wstop.h Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/nga/SERVER/openwfc/wstop.h Fri Sep 24 16:44:34 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2003-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -56,6 +56,7 @@
#endif
};
+class CWsRenderOrienationTracker;
class CWsTop
{
enum {EShellBootModeReboot=0,EShellBootModeNoReboot=1,EShellBootModeExit=2};
@@ -122,6 +123,7 @@
static TBool MultiFocusPolicy();
static inline CWsPluginManager *PluginManager();
+ static void CheckRenderOrientation();
private:
static void InitLogging();
@@ -152,6 +154,7 @@
static TInt iCheckHeapResult;
static TBool iDoHeapCheckAndRestart;
static CWsPluginManager *iPluginManager;
+ static CWsRenderOrienationTracker* iRenderOrientationTracker;
};
NONSHARABLE_CLASS(CWsActiveScheduler): public CActiveScheduler, public MWsActiveSchedulerDebug
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserver/nga/SERVER/renderorientationtracker.cpp Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,567 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This material, including documentation and any related
+// computer programs, is protected by copyright controlled by
+// Nokia. All rights are reserved. Copying, including
+// reproducing, storing, adapting or translating, any
+// or all of this material requires the prior written consent of
+// Nokia. This material also contains confidential
+// information which may not be disclosed to others without the
+// prior written consent of Nokia.
+//
+// Description:
+// Render Orientation Tracking and Publication
+//
+
+#include <hal.h>
+#include <e32std.h>
+#include "renderorientationtracker.h"
+#include "rootwin.h"
+#include "windowgroup.h"
+#include "wstop.h"
+#include "..\debuglog\DEBUGLOG.H"
+
+extern CDebugLogBase* wsDebugLog;
+
+/** Convert a TRenderOrientation value into a TDigitiserOrientation.
+Note: The algorithm used makes use of the ordering of the values of the respective enums,
+thus this is checked for (at compile time) at the start of the function.
+@param aWservOrientation A value from the TRenderOrientation enums.
+@return The equivalent value from the TDigitiserOrientation enums.
+*/
+inline HALData::TDigitiserOrientation WservToDigitiser(TRenderOrientation aWservOrientation)
+ {
+ __ASSERT_COMPILE(EDisplayOrientationNormal+1 == EDisplayOrientation90CW);
+ __ASSERT_COMPILE(EDisplayOrientationNormal+2 == EDisplayOrientation180);
+ __ASSERT_COMPILE(EDisplayOrientationNormal+3 == EDisplayOrientation270CW);
+ __ASSERT_COMPILE(HALData::EDigitiserOrientation_000+1 == HALData::EDigitiserOrientation_090);
+ __ASSERT_COMPILE(HALData::EDigitiserOrientation_000+2 == HALData::EDigitiserOrientation_180);
+ __ASSERT_COMPILE(HALData::EDigitiserOrientation_000+3 == HALData::EDigitiserOrientation_270);
+ HALData::TDigitiserOrientation ret=static_cast<HALData::TDigitiserOrientation>
+ (HALData::EDigitiserOrientation_000 + (aWservOrientation - EDisplayOrientationNormal));
+ return ret;
+ }
+
+// Todo remove/undefine this for release
+#define TECHVIEW_TESTMODE
+
+CWsRenderOrienationTracker* CWsRenderOrienationTracker::NewL()
+ {
+ CWsRenderOrienationTracker* self = new(ELeave)CWsRenderOrienationTracker();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+CWsRenderOrienationTracker::CWsRenderOrienationTracker()
+ : CActive(CActive::EPriorityStandard),
+ iRenderOrientationTrackingType(EDisplayOrientationNormal),
+ iPublishedRenderOrientation(EDisplayOrientationNormal)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+void CWsRenderOrienationTracker::ConstructL()
+ {
+ const TSecurityPolicy KRenderOrientationReadSecurityPolicy(ECapability_None);
+ const TSecurityPolicy KRenderOrientationWriteSecurityPolicy(ECapabilityWriteDeviceData);
+
+ // Define P&S Property to publish to
+ TInt error = RProperty::Define( KRenderOrientationCategory,
+ KRenderOrientationKey,
+ RProperty::EInt,
+ KRenderOrientationReadSecurityPolicy,
+ KRenderOrientationWriteSecurityPolicy);
+
+ // Attach the publisher for real-time publishing
+ if(KErrNone == error)
+ error = iRenderOrientationPublisher.Attach( KRenderOrientationCategory,
+ KRenderOrientationKey);
+
+ // Publish the initial value
+ if(KErrNone == error)
+ error = DoPublishOrientation(EDisplayOrientationNormal);
+
+ //Set the initial value to HAL
+ if(KErrNone == error)
+ SetHALOrientation(EDisplayOrientationNormal);
+
+ if (wsDebugLog && KErrNone!=error)
+ {
+ _LIT(logText,"Orientation Tracker: failed to initialise with error %d");
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogImportant,logText,error);
+ }
+ User::LeaveIfError(error);
+ }
+
+CWsRenderOrienationTracker::~CWsRenderOrienationTracker()
+ {
+ Cancel();
+ iRenderOrientationPublisher.Delete(KRenderOrientationCategory, KRenderOrientationKey);
+ iRenderOrientationPublisher.Close();
+ }
+
+/**
+If the orientation of the given window group is useable updates aOrientationTrackingType with the orientation
+
+@param Input: the window group to check
+@param Output: the window group's orientation if usable ( otherwise unchanged )
+@return KErrNone if the orienation is usable, KErrNotFound if the orientation is not useable, KErrNotSupported if the orientation is unknown
+*/
+TInt CWsRenderOrienationTracker::CheckWindowGroupOrientation(const CWsWindowGroup& aWinGroup, TRenderOrientationTrackingType& aOrientationTrackingType)
+ {
+ TInt error = KErrNone;
+ TRenderOrientationTrackingType tempOrientationTrackingType = static_cast<TRenderOrientationTrackingType>(aWinGroup.WsOwner()->GetIndicatedAppOrientation());
+ switch(tempOrientationTrackingType)
+ {
+ case EDisplayOrientationNormal:
+ case EDisplayOrientation90CW:
+ case EDisplayOrientation180:
+ case EDisplayOrientation270CW:
+ case EDisplayOrientationAuto:
+ aOrientationTrackingType = tempOrientationTrackingType;
+ break;
+
+ case EDisplayOrientationIgnore:
+ error = KErrNotFound;
+ if (wsDebugLog)
+ {
+ _LIT(logText,"Orientation Tracker: winGroup %08x orientation is set to be ignored");
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,logText,reinterpret_cast<TInt>(&aWinGroup));
+ }
+ break;
+
+ default:
+ error = KErrNotSupported;
+ if (wsDebugLog)
+ {
+ _LIT(logText,"Orientation Tracker: winGroup %08x has undefined orientation, Error %d");
+ TBuf<LogTBufSize> buf;
+ buf.Format(logText, &aWinGroup, error);
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogIntermediate,buf);
+ }
+ break;
+ }
+
+ return error;
+ }
+
+/**
+Checks that the given group window is appropriate for dictating the render orientation
+
+@param Input: The group window to check
+@return ETrue is the group window is usable, else EFalse
+*/
+TBool CWsRenderOrienationTracker::UseableGroupWindow(const CWsWindowGroup& aWinGroup) const
+ {
+#ifdef TECHVIEW_TESTMODE
+ // for some reason IsFocusable seems to return 0 and 2, not 0 and 1
+ return NULL!=aWinGroup.Child() &&
+ (aWinGroup.IsFocusable() ? ETrue : EFalse);
+#else
+ return (NULL!=aWinGroup.Child());
+#endif
+ }
+
+/**
+Finds the topmost usable windowgroup which has a usable orientation, and outputs that orientation
+
+@param Output: The current render orientation
+@return KErrNone if successful, KErrNotFound if the focus window group is not usable, KErrNotSupported if an invalid orientation is found
+*/
+TInt CWsRenderOrienationTracker::GetFocusWindowOrientation(TRenderOrientationTrackingType& aOrientationTrackingType)
+ {
+ TInt error = KErrNone;
+ CWsWindowGroup* focusWinGroup = CWsTop::FocusWindowGroup();
+ if(!focusWinGroup)
+ {
+ _LIT(logText,"Orientation Tracker: focusWinGroup not found");
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,logText);
+ error = KErrNotFound;
+ }
+ else
+ {
+ error = CheckWindowGroupOrientation(*focusWinGroup, aOrientationTrackingType);
+ }
+ return error;
+ }
+
+/**
+Finds the topmost usable windowgroup which has a usable orientation, and outputs that orientation
+
+@param Output: The current render orientation
+@return KErrNone if successful, KErrNotSupported if an invalid orientation is found
+*/
+TInt CWsRenderOrienationTracker::FindOrientationFromWindowTree(TRenderOrientationTrackingType& aOrientationTrackingType)
+ {
+ TInt error = KErrNone;
+ TRenderOrientationTrackingType tempOrientationTrackingType = iRenderOrientationTrackingType;
+ CWsRootWindow* rootWin = CWsTop::CurrentFocusScreen()->RootWindow();
+ TBool finished = EFalse;
+ for(CWsWindowGroup* winGroup = rootWin->Child(); !finished && NULL != winGroup; winGroup = winGroup->NextSibling())
+ {
+ if (wsDebugLog)
+ {
+ _LIT(logText,"Orientation Tracker: winGroup %08x has priority %d, Orientation %d, Focusable %d, Child %08x");
+ TBuf<LogTBufSize> buf;
+ buf.Format(logText, winGroup, winGroup->OrdinalPriority(), winGroup->WsOwner()->GetIndicatedAppOrientation(),
+ winGroup->IsFocusable()?ETrue:EFalse, winGroup->Child());
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,buf);
+ }
+ // winGroup is a higher priority ordinal, so see if it has an orientation that can be used
+ // although we're only interested in window groups with child windows otherwise nothing is visible anyway
+ if(UseableGroupWindow(*winGroup))
+ {
+ error = CheckWindowGroupOrientation(*winGroup, tempOrientationTrackingType);
+ switch(error)
+ {
+ case KErrNone:
+ {
+ // List is in order, so just find the first one
+ if (wsDebugLog)
+ {
+ _LIT(logText,"Orientation Tracker: Found winGroup %08x with Orientation %d");
+ TBuf<LogTBufSize> buf;
+ buf.Format(logText, winGroup, winGroup->WsOwner()->GetIndicatedAppOrientation());
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,buf);
+ }
+ finished = ETrue;
+ break;
+ }
+
+ case KErrNotFound:
+ // so keep searching
+ break;
+
+ case KErrNotSupported:
+ default:
+ finished = ETrue;
+ break;
+
+ }
+
+ }
+ }
+ // Safe even in error code as won't have been changed by CheckWindowGroupOrientation
+ aOrientationTrackingType = tempOrientationTrackingType;
+
+ return error;
+ }
+
+/**
+First checks to see if the focus window group has a usable orientation, if so that is output.
+Otherwise, finds the topmost usable windowgroup which has a usable orientation, and outputs that
+
+@param Output: The current render orientation
+@return KErrNone if successful, KErrNotSupported if an invalid orientation is found
+ */
+TInt CWsRenderOrienationTracker::GetIndicatedOrientation(TRenderOrientationTrackingType& aOrientationTrackingType)
+ {
+ // First check the focus window group
+ TInt error = GetFocusWindowOrientation(aOrientationTrackingType);
+
+ // Don't look for another window if the focus window is usable
+ // or if an error has occured, then don't change current orientation
+ switch(error)
+ {
+ case KErrNone:
+ {
+ if(wsDebugLog)
+ {
+ _LIT(logText,"Orientation Tracker: Using focus window %08x for orientation");
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,logText,reinterpret_cast<TInt>(CWsTop::FocusWindowGroup()));
+ }
+ break;
+ }
+
+ case KErrNotFound:
+ {
+ // Can't use focus window group, so find the topmost windowgroup with a valid orientation
+ error = FindOrientationFromWindowTree(aOrientationTrackingType);
+ break;
+ }
+
+ default:
+ // Unrecoverable error, abort and leave published orientation unchanged
+ break;
+ }
+
+ return error;
+ }
+
+/**
+Checks to see if the render orientation has changed, and publishes any new orientaion
+via publish and subscribe
+
+@see KRenderOrientationCategory
+@see KRenderOrientationKey
+*/
+void CWsRenderOrienationTracker::CheckRenderOrientation()
+ {
+ TRenderOrientationTrackingType newOrientationTrackingType = iRenderOrientationTrackingType;
+ TInt error = GetIndicatedOrientation(newOrientationTrackingType);
+
+ // if the tracking type has changed...
+ if(KErrNone == error && iRenderOrientationTrackingType != newOrientationTrackingType)
+ {
+ if(EDisplayOrientationAuto == iRenderOrientationTrackingType)
+ {
+ // change from auto type, so we need to cancel request for updates from the theme server
+ Cancel();
+ }
+ iRenderOrientationTrackingType = newOrientationTrackingType;
+ if(EDisplayOrientationAuto == iRenderOrientationTrackingType)
+ {
+ // Change to auto type, so we need to request updates from the theme server
+ // Attach to the Theme server to get orientation change updates
+ error = iThemeOrientationProperty.Attach( KThemeOrientationCategory, KThemeOrientationKey );
+ if (wsDebugLog)
+ {
+ if(KErrNone == error)
+ {
+ // Information Log
+ _LIT(logText,"Orientation Tracker: Attached to theme orientation property");
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,logText);
+ }
+ else
+ {
+ // Error Log
+ _LIT(logText,"Orientation Tracker: Error %d attaching to theme orientation property");
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogIntermediate,logText, error);
+ }
+ }
+
+ RequestDeviceOrientationNotification();
+ }
+ // See if the has changed, and publish if it has
+ error = DoOrientationTracking();
+ }
+
+ if (wsDebugLog && KErrNone != error)
+ {
+ _LIT(logText,"Orientation Tracker: Error %d Checking Render Orientation");
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogImportant,logText, error);
+ }
+ }
+
+/**
+Requests notification of change of the theme server orientation
+
+@Pre iThemeOrientationProperty has had Attach called on it
+*/
+void CWsRenderOrienationTracker::RequestDeviceOrientationNotification()
+ {
+ if(!IsActive())
+ {
+ if (wsDebugLog)
+ {
+ _LIT(logText,"Orientation Tracker: Subscribing to theme orientation property");
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,logText);
+ }
+ // Request for Theme Server Orientation P&S
+ iThemeOrientationProperty.Subscribe(iStatus);
+ SetActive();
+ }
+ }
+
+/**
+Cancels and closes (detaches) from the theme orientation publish and subscribe
+*/
+void CWsRenderOrienationTracker::CancelDeviceOrientationNotification()
+ {
+ // Cancel Request for Theme Server Orientation P&S
+ iThemeOrientationProperty.Cancel();
+ iThemeOrientationProperty.Close();
+
+ if (wsDebugLog)
+ {
+ _LIT(logText,"Orientation Tracker: Cancelled/closed theme orientation property");
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,logText);
+ }
+ }
+
+/**
+Called when the theme servers orientation has changed.
+Re-requests unless cancelled
+*/
+void CWsRenderOrienationTracker::RunL()
+ {
+ TInt error = iStatus.Int();
+ if(KErrNone == error)
+ {
+ // Re-request
+ RequestDeviceOrientationNotification();
+
+ TInt error = DoOrientationTracking();
+ if (wsDebugLog && KErrNone != error)
+ {
+ _LIT(logText,"Orientation Tracker: Error %d processing theme orientation property");
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogImportant,logText, error);
+ }
+ }
+ else if (wsDebugLog && KErrCancel != error)
+ {
+ _LIT(logText,"Orientation Tracker: Error %d from theme orientation property, not resubscribed");
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogImportant,logText, error);
+ }
+ }
+
+/**
+Cancels the request for notification for changes to theme orientation
+*/
+void CWsRenderOrienationTracker::DoCancel()
+ {
+ CancelDeviceOrientationNotification();
+ }
+
+/**
+Gets the orientation published from theme server
+
+@param Output: the theme server orientation
+@return KErrNone if successful, KErrNotSupported if the theme server returns an unknown orientation, else any of the system wide error codes
+*/
+TInt CWsRenderOrienationTracker::GetThemeOrientation(TRenderOrientation& aThemeOrientation)
+ {
+ TInt themeOrientation=EDisplayOrientationNormal;
+ TInt error = iThemeOrientationProperty.Get(themeOrientation);
+ if(wsDebugLog && KErrNone != error)
+ {
+ _LIT(logText,"Orientation Tracker: Error %d getting theme orientation property");
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogIntermediate,logText, error);
+ }
+
+ if(KErrNone == error)
+ {
+ // Translate the received orientation
+ switch(themeOrientation)
+ {
+ case EDisplayOrientationNormal:
+ case EDisplayOrientation90CW:
+ case EDisplayOrientation180:
+ case EDisplayOrientation270CW:
+ // only update if orientation is supported
+ aThemeOrientation = static_cast<TRenderOrientation>(themeOrientation);
+ break;
+
+ default:
+ error = KErrNotSupported;
+ if (wsDebugLog)
+ {
+ _LIT(logText,"Orientation Tracker: Unsupported orientation %d from theme orientation property, Error %d");
+ TBuf<LogTBufSize> buf;
+ buf.Format(logText, themeOrientation, error);
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogIntermediate,buf);
+ }
+ break;
+ }
+ }
+ return error;
+ }
+
+/**
+Processes the indicated orientation into an actual orientation
+
+@return KErrNone for success, KErrNotSupported if the orientation is unknown, else any of the system wide error codes
+*/
+TInt CWsRenderOrienationTracker::DoOrientationTracking()
+ {
+ TInt error = KErrNone;
+ TRenderOrientation newDeviceOrientation;
+ switch(iRenderOrientationTrackingType)
+ {
+ case EDisplayOrientationNormal:
+ case EDisplayOrientation90CW:
+ case EDisplayOrientation180:
+ case EDisplayOrientation270CW:
+ newDeviceOrientation = iRenderOrientationTrackingType;
+ break;
+
+ case EDisplayOrientationAuto:
+ error = GetThemeOrientation(newDeviceOrientation);
+ break;
+
+ default:
+ error = KErrNotSupported;
+ if (wsDebugLog)
+ {
+ _LIT(logText,"Orientation Tracker: Unsupported orientation tracking type %d, error %d");
+ TBuf<LogTBufSize> buf;
+ buf.Format(logText, iRenderOrientationTrackingType, error);
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogIntermediate,buf);
+ }
+ break;
+ }
+
+ if(KErrNone == error)
+ {
+ error = PublishOrientation(newDeviceOrientation);
+ }
+
+ return error;
+ }
+
+/**
+Publishes the given value
+
+@param The render orientation to publish
+@return KErrNone for success, else any of the system wide erro codes
+*/
+TInt CWsRenderOrienationTracker::DoPublishOrientation(const TRenderOrientation aRenderOrientation)
+ {
+ TInt error = iRenderOrientationPublisher.Set(aRenderOrientation);
+
+ // if it's published OK, then remember the newly published value
+ if(KErrNone == error)
+ {
+ iPublishedRenderOrientation = aRenderOrientation;
+ if(wsDebugLog)
+ {
+ _LIT(logText,"Orientation Tracker: Published render orientation %d");
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything, logText, aRenderOrientation);
+ }
+ }
+ else if(wsDebugLog)
+ {
+ _LIT(logText,"Orientation Tracker: Error %d setting render orientation property");
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogIntermediate, logText, error);
+ }
+ return error;
+ }
+
+void CWsRenderOrienationTracker::SetHALOrientation(const TRenderOrientation aRenderOrientation)
+ {
+ // If the render orientation is EDisplayOrientationAuto then don't update HAL
+ // The application and HAL should always have the same state for the orientation.
+ if(EDisplayOrientationAuto != aRenderOrientation)
+ {
+ TInt error = HAL::Set(CWsTop::CurrentFocusScreen()->ScreenNumber(), HALData::EDigitiserOrientation, WservToDigitiser(iPublishedRenderOrientation));
+ //Just log the error if there is one.
+ if(wsDebugLog && error != KErrNone)
+ {
+ _LIT(logText,"Orientation Tracker: Error %d setting digitiser orientation");
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogIntermediate, logText, error);
+ }
+ }
+ }
+
+/**
+If the current orientation differs from the previously published value then publishes the current value
+
+@param The render orientation to check and publish
+@return KErrNone for success, else any of the system wide erro codes
+*/
+TInt CWsRenderOrienationTracker::PublishOrientation(const TRenderOrientation aRenderOrientation)
+ {
+ TInt error = KErrNone;
+
+ if(aRenderOrientation != iPublishedRenderOrientation)
+ {
+ // If the device Orientation has changed, publish it
+ error = DoPublishOrientation(aRenderOrientation);
+ if(KErrNone == error)
+ SetHALOrientation(aRenderOrientation);
+ }
+ return error;
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserver/nga/SERVER/renderorientationtracker.h Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,71 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This material, including documentation and any related
+// computer programs, is protected by copyright controlled by
+// Nokia. All rights are reserved. Copying, including
+// reproducing, storing, adapting or translating, any
+// or all of this material requires the prior written consent of
+// Nokia. This material also contains confidential
+// information which may not be disclosed to others without the
+// prior written consent of Nokia.
+//
+// Description:
+// Render Orientation Tracking and Publication
+//
+
+#ifndef renderorientationtracker_h
+#define renderorientationtracker_h
+
+#include <e32std.h>
+#include <e32base.h>
+#include <e32property.h>
+#include <w32std.h>
+#include <wspublishandsubscribedata.h>
+
+// Values for the device orientation that we receive via P&S from the Theme Server
+// Todo FIX THIS Category UID!!!
+const TUid KThemeOrientationCategory = {0x20022E82}; // == KHbPsHardwareCoarseOrientationCategoryUid
+const TUint KThemeOrientationKey = 0x4F726965; // == KHbPsHardwareCoarseOrientationKey
+
+typedef TRenderOrientation TRenderOrientationTrackingType;
+
+class CWsWindowGroup;
+
+class CWsRenderOrienationTracker : public CActive
+ {
+public:
+ static CWsRenderOrienationTracker* NewL();
+ ~CWsRenderOrienationTracker();
+
+ void CheckRenderOrientation();
+
+private:
+ CWsRenderOrienationTracker();
+ void ConstructL();
+
+ void RequestDeviceOrientationNotification();
+ void CancelDeviceOrientationNotification();
+
+ // CActive
+ void RunL();
+ void DoCancel();
+
+ TInt DoOrientationTracking();
+ TInt GetThemeOrientation(TRenderOrientation& aThemeOrientation);
+ TInt PublishOrientation(const TRenderOrientation aRenderOrientation);
+ TInt DoPublishOrientation(const TRenderOrientation aRenderOrientation);
+ TInt GetIndicatedOrientation(TRenderOrientationTrackingType& aOrientationTrackingType);
+ TInt CheckWindowGroupOrientation(const CWsWindowGroup& aWinGroup, TRenderOrientationTrackingType& aOrientationTrackingType);
+ TBool UseableGroupWindow(const CWsWindowGroup& aWinGroup) const;
+ TInt GetFocusWindowOrientation(TRenderOrientationTrackingType& aOrientationTrackingType);
+ TInt FindOrientationFromWindowTree(TRenderOrientationTrackingType& aOrientationTrackingType);
+ void SetHALOrientation(const TRenderOrientation aRenderOrientation);
+
+private:
+ TRenderOrientationTrackingType iRenderOrientationTrackingType;
+ TRenderOrientation iPublishedRenderOrientation;
+ RProperty iThemeOrientationProperty;
+ RProperty iRenderOrientationPublisher;
+ };
+
+#endif
--- a/windowing/windowserver/nga/SERVER/windowgroup.h Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/nga/SERVER/windowgroup.h Fri Sep 24 16:44:34 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -82,7 +82,7 @@
void AddPriorityKeyL(TUint aKeycode, TUint aModifierMask, TUint aModifiers);
void RemovePriorityKey(TUint aKeycode, TUint aModifierMask, TUint aModifiers);
void RemoveAllPriorityKeys();
- TBool CheckForPriorityKey(const TKeyData &aKey, TInt aScanCode);
+ TBool CheckForPriorityKey(const TKeyEvent &aKeyEvent);
inline CWsPointerCursor *GroupPointerCursor() const;
static CWsWindowGroup *WindowGroupFromIdentifier(TInt aIdentifier);
static CWsWindowGroup *WindowGroupFromIdentifierL(TInt aIdentifier);
@@ -110,7 +110,7 @@
void SetScreenDevice(DWsScreenDevice *aDevice);
static void SetEventQueueTestState(TBool aEventQueState);
TBool HasVisibleTranslucentChild();
- void ReleasePendedMessage();
+ void ReleasePendedMessage();
private:
void SwitchToOwningWindow(CWsWindowGroup *aClosingWindow);
void MoveChainedWindows(TDblQueIter<CWsWindowGroup>& aIter,TBool aForward,TInt aPos,CWsWindowGroup* aClosingWindow);
--- a/windowing/windowserver/nonnga/CLIENT/RWS.CPP Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/nonnga/CLIENT/RWS.CPP Fri Sep 24 16:44:34 2010 +0300
@@ -22,6 +22,7 @@
#include "CLIENT.H"
#include "wstraces.h"
#include "graphics/windowserverconstants.h"
+#include <wspublishandsubscribedata.h>
const TInt KMaxWSERVMessagesSlot=-1;
@@ -2422,3 +2423,10 @@
{
ASSERT(0);
}
+
+EXPORT_C void RWsSession::IndicateAppOrientation(TRenderOrientation aOrientation)
+ /** Dummy implementation in order to preserve compatibility with WSERV NGA.
+ @internalComponent */
+ {
+ ASSERT(0);
+ }
--- a/windowing/windowserver/test/TAutoServer/TAutoServer.cpp Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/test/TAutoServer/TAutoServer.cpp Fri Sep 24 16:44:34 2010 +0300
@@ -72,6 +72,7 @@
#include "TMULSCREENS.h"
#include "TBUFFERSECURITY.H"
#include "TFLICKERFREE.H"
+#include "tdevicerotation.h"
#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA
#include "TFADINGBITMAP.H"
#endif
@@ -86,6 +87,7 @@
#include "tdrawresource.h"
#include "twindowsizecache.h"
+
/* Path to the script
z:\GraphicsTest\gditest.script
*/
@@ -309,6 +311,8 @@
testStep = new CTBufferSecurityStep();
else if(aStepName == KTFlickerFreeStep)
testStep = new CTFlickerFreeStep();
+ else if(aStepName == KTDeviceRotationStep)
+ testStep = new CTDeviceRotationStep();
#ifdef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA
else if(aStepName == KTFadingBitmapStep)
testStep = new CTFadingBitmapStep();
--- a/windowing/windowserver/test/TAutoServer/openwfc/TAutoServer_nga.mmp Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/test/TAutoServer/openwfc/TAutoServer_nga.mmp Fri Sep 24 16:44:34 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -24,22 +24,19 @@
MACRO TEST_GRAPHICS_WSERV_TAUTOSERVER_NGA
MACRO SYMBIAN_GRAPHICS_GCE
-USERINCLUDE ../../../../../graphicstest/graphicstestharness/inc ../../../inc ../../../tauto ../../../tauto/openwfc
-USERINCLUDE ../../../tredir ../../../tlisten ../../../tframerate ../../../tcontaindrawer ../../t_gdcoverage ../../../tbufferdrawer
-USERINCLUDE ../../../tlib ../../
+USERINCLUDE ../../../../../graphicstest/graphicstestharness/inc ../../../inc ../../tauto ../../tauto/openwfc
+USERINCLUDE ../../tredir ../../tlisten ../../tframerate ../../tcontaindrawer ../../t_gdcoverage ../../tbufferdrawer
+USERINCLUDE ../../tlib ../../
-APP_LAYER_SYSTEMINCLUDE_SYMBIAN
-MW_LAYER_SYSTEMINCLUDE_SYMBIAN
-OS_LAYER_SYSTEMINCLUDE_SYMBIAN
-OS_LAYER_LIBC_SYSTEMINCLUDE
-
+OS_LAYER_SYSTEMINCLUDE
+OS_LAYER_LIBC_SYSTEMINCLUDE
SOURCEPATH ../
SOURCE TAutoServer.cpp
SOURCEPATH ../../
SOURCE PARSEINIDATA.CPP
-SOURCEPATH ../../../tauto
+SOURCEPATH ../../tauto
SOURCE AUTO.CPP
SOURCE TAUTODLL.CPP
SOURCE TEvent.CPP
@@ -102,6 +99,7 @@
SOURCE tmultiptrevent.cpp
SOURCE tdrawresource.cpp
SOURCE twindowsizecache.cpp
+SOURCE tdevicerotation.cpp
//Required to test CommamdBuffer::Play using MWsGraphicsContext in tgc
SOURCE directgdigcwrapper.cpp
--- a/windowing/windowserver/test/TAutoServer/openwfc/TAutoServer_nonnga.mmp Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/test/TAutoServer/openwfc/TAutoServer_nonnga.mmp Fri Sep 24 16:44:34 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -23,12 +23,11 @@
MACRO TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA
-USERINCLUDE ../../../../../graphicstest/graphicstestharness/inc ../../../inc ../../../tauto ../../../tauto/openwfc
-USERINCLUDE ../../../tredir ../../../tlisten ../../../tframerate ../../../tcontaindrawer ../../t_gdcoverage
-USERINCLUDE ../../../tlib ../../
+USERINCLUDE ../../../../../graphicstest/graphicstestharness/inc ../../../inc ../../tauto ../../tauto/openwfc
+USERINCLUDE ../../tredir ../../tlisten ../../tframerate ../../tcontaindrawer ../../t_gdcoverage
+USERINCLUDE ../../tlib ../../
-MW_LAYER_SYSTEMINCLUDE_SYMBIAN
-OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+OS_LAYER_SYSTEMINCLUDE
OS_LAYER_LIBC_SYSTEMINCLUDE
SOURCEPATH ../
@@ -36,7 +35,7 @@
SOURCEPATH ../../
SOURCE PARSEINIDATA.CPP
-SOURCEPATH ../../../tauto
+SOURCEPATH ../../tauto
SOURCE AUTO.CPP
SOURCE TAUTODLL.CPP
SOURCE TEvent.CPP
@@ -96,6 +95,7 @@
SOURCE THeartBeat.CPP
SOURCE tgc.cpp
SOURCE TGRAPHICSDRAWER.CPP
+SOURCE tdevicerotation.cpp
LIBRARY bitgdi.lib efsrv.lib euser.lib fbscli.lib
LIBRARY gdi.lib hal.lib tlib.lib ws32.lib
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserver/test/TAutoServer/tevent_captureapp.mmp Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,29 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Helper application for TEvent test case GRAPHICS-WSERV-417-61800-0004
+//
+
+TARGET tevent_captureapp.exe
+TARGETTYPE exe
+UID 0x00000000 0x102872e4
+VENDORID 0x70000001
+CAPABILITY SwEvent
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+SOURCEPATH ../tauto
+SOURCE tevent_captureapp.cpp
+
+LIBRARY euser.lib
+LIBRARY ws32.lib
--- a/windowing/windowserver/test/scripts/wstest_config.cmd Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/test/scripts/wstest_config.cmd Fri Sep 24 16:44:34 2010 +0300
@@ -1,22 +1,22 @@
@echo off
-rem Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
+rem Copyright (c) 2006-2010 Nokia Corporation and/or its subsidiary(-ies).
rem All rights reserved.
rem This component and the accompanying materials are made available
rem under the terms of "Eclipse Public License v1.0"
rem which accompanies this distribution, and is available
rem at the URL "http://www.eclipse.org/legal/epl-v10.html".
-rem
+rem
rem Initial Contributors:
rem Nokia Corporation - initial contribution.
-rem
+rem
rem Contributors:
-rem
+rem
rem Description:
rem @internalComponent - Internal Symbian
rem
rem
set nonnga=false
-if not defined EPOC_INI set EPOC_INI=\epoc32\data\epoc.ini
+if not defined EPOC_INI set EPOC_INI=%EPOCROOT%epoc32\data\epoc.ini
if /i "%2"=="nonnga" set nonnga=true
if /i "%3"=="nonnga" set nonnga=true
if "%nonnga%"=="true" echo Configuring for Non-NGA
@@ -33,7 +33,7 @@
call :doinstall %EMULATOR_DATA_DIR% multiscreen %2 %3
)
-echo If EPOC.INI isn't already backuped then backup EPOC.INI to EPOC.INI.bak
+rem If EPOC.INI isn't already backed up then backup EPOC.INI to EPOC.INI.bak
if not exist %EPOC_INI%.bak copy /y %EPOC_INI% %EPOC_INI%.bak
echo Editing EPOC.INI to use multiscreen.
@@ -46,7 +46,7 @@
:doinstall
-rem If WSINI.INI(s) aren't already backuped then backup WSINI.INI(s)
+rem If WSINI.INI(s) aren't already backed up then backup WSINI.INI(s)
if not exist %1\z\system\data\wsini.bak if exist %1\z\system\data\wsini.ini copy /y %1\z\system\data\wsini.ini %1\z\system\data\wsini.bak >nul
if not exist %1\z\resource\data\wsini.bak if exist %1\z\resource\data\wsini.ini copy /y %1\z\resource\data\wsini.ini %1\z\resource\data\wsini.bak >nul
@@ -84,7 +84,7 @@
call :doinstall_changetracking %EMULATOR_DATA_DIR% multiscreen %2 %3
)
-echo If EPOC.INI isn't already backuped then backup EPOC.INI to EPOC.INI.bak
+rem If EPOC.INI isn't already backed up then backup EPOC.INI to EPOC.INI.bak
if not exist %EPOC_INI%.bak copy /y %EPOC_INI% %EPOC_INI%.bak >nul
echo Editing EPOC.INI to use multiscreen.
@@ -128,9 +128,9 @@
call :douninstall %EMULATOR_DATA_DIR%
)
-echo If EPOC.INI was already backuped then restore EPOC.INI from EPOC.INI.bak
+rem If EPOC.INI was already backed up then restore EPOC.INI from EPOC.INI.bak
if exist %EPOC_INI%.bak (
- echo Restore EPOC.INI from backup
+ echo Restoring EPOC.INI from backup
copy /y %EPOC_INI%.bak %EPOC_INI% >nul
del /f /q %EPOC_INI%.bak >nul
)
@@ -139,7 +139,7 @@
:douninstall
-rem If WSINI.INI(s) were already backuped then restore WSINI.INI
+rem If WSINI.INI(s) were already backed up then restore WSINI.INI
if exist %1\z\system\data\wsini.bak (
copy /y %1\z\system\data\wsini.bak %1\z\system\data\wsini.ini >nul
del /f /q %1\z\system\data\wsini.bak >nul
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserver/test/scripts/wstest_t_devicerotation_s0_nga.script Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,31 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+PRINT Run WServ NGA device rotation tests on screen 0
+
+LOAD_SUITE tautoserver_nga
+
+//
+// Uncommenting the TMemLeakCheckEnable test will set Wserv into a mode where
+// between each test it effectively shuts itself down, checks for memory leaks,
+// then restarts. This is especially useful when the final TMemLeakCheckOneShot
+// test indicates a memory leak somewhere in the tests.
+// RUN_TEST_STEP 100 tautoserver_nga TMemLeakCheckEnable
+//
+
+RUN_TEST_STEP 100 tautoserver_nga TDeviceRotation
+
+// Run at the end and it will trigger a Wserv memory leak check
+RUN_TEST_STEP 100 tautoserver_nga TMemLeakCheckOneShot
--- a/windowing/windowserver/test/tauto/TCapKey.CPP Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/test/tauto/TCapKey.CPP Fri Sep 24 16:44:34 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1996-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -455,16 +455,39 @@
TInt retVal;
TInt resCount=Client()->iWs.ResourceCount();
for(TInt index=0;index<numErrorKeys;index++)
- {
- retVal = Client()->iGroup->GroupWin()->CaptureKey(errorKeys[index].keyCode,errorKeys[index].modifier_mask,errorKeys[index].modifiers);
+ {
+ retVal = Client()->iGroup->GroupWin()->CaptureKey(errorKeys[index].keyCode,errorKeys[index].modifier_mask,errorKeys[index].modifiers, errorKeys[index].priority);
TEST(retVal==KErrArgument);
if (retVal!=KErrArgument)
- INFO_PRINTF3(_L("Client()->iGroup->GroupWin()->CaptureKey() return value - Expected: %d, Actual: %d"), KErrArgument, retVal);
- }
+ {
+ _LIT(KMsg, "CaptureKey() with bad parameter set %d returned %d - expected KErrArgument (%d)");
+ LOG_MESSAGE4(KMsg, index, retVal, KErrArgument);
+ }
+
+ retVal = Client()->iGroup->GroupWin()->CaptureKeyUpAndDowns(errorKeys[index].keyCode, errorKeys[index].modifier_mask, errorKeys[index].modifiers, errorKeys[index].priority);
+ TEST(retVal == KErrArgument);
+ if (retVal != KErrArgument)
+ {
+ _LIT(KMsg, "CaptureKeyUpAndDowns() with bad parameter set %d returned %d - expected KErrArgument (%d)");
+ LOG_MESSAGE4(KMsg, index, retVal, KErrArgument);
+ }
+
+ retVal = Client()->iGroup->GroupWin()->CaptureLongKey(errorKeys[index].keyCode, errorKeys[index].keyCode, errorKeys[index].modifier_mask, errorKeys[index].modifiers, errorKeys[index].priority, ELongCaptureNormal);
+ TEST(retVal == KErrArgument);
+ if (retVal != KErrArgument)
+ {
+ _LIT(KMsg, "CaptureLongKey() with bad parameter set %d returned %d - expected KErrArgument (%d)");
+ LOG_MESSAGE4(KMsg, index, retVal, KErrArgument);
+ }
+ }
+
retVal = Client()->iWs.ResourceCount();
TEST(retVal==resCount);
if (retVal!=resCount)
- INFO_PRINTF3(_L("Client()->iWs.ResourceCount() return value - Expected: %d, Actual: %d"), resCount, retVal);
+ {
+ _LIT(KMsg, "Resource count %d - expected %d");
+ LOG_MESSAGE3(KMsg, retVal, resCount);
+ }
}
void CTCaptureKey::SetMode(TTestMode aMode)
@@ -801,8 +824,10 @@
@SYMTestStatus Implemented
@SYMTestActions Memorizes amount of objects that the server has allocated for that client.
- Tries to register 3 different capture keys with invalid
- modifiers and modifirs mask pair.
+ Tries to register capture keys with invalid modifiers and
+ modifier mask pairs, using each of the RWindowGroup capture
+ functions CaptureKey(), CaptureKeyUpAndDowns() and
+ CaptureLongKey().
@SYMTestExpectedResults Makes sure that the number of server-side objects for the
session didn't change.
--- a/windowing/windowserver/test/tauto/TCapKey.H Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/test/tauto/TCapKey.H Fri Sep 24 16:44:34 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1996-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -157,12 +157,21 @@
TInt keyCode;
TUint modifier_mask;
TUint modifiers;
+ TInt priority;
};
LOCAL_D SErrorCapKey errorKeys[]={
- {'a',EModifierFunc|EModifierShift,EModifierFunc|EModifierCtrl},
- {'1',0,EModifierFunc},
- {3,EModifierCtrl,EModifierCtrl|EModifierShift},
+ {'a', EModifierFunc|EModifierShift,EModifierFunc|EModifierCtrl, 0},
+ {'1', 0, EModifierFunc, 0},
+ {3, EModifierCtrl,EModifierCtrl|EModifierShift, 0},
+ // @SYMPREQ 417-61800: Check that attempts to capture keys with
+ // EModifierLong in the modifier mask fail with KErrArgument.
+ {'T', EModifierLongKey, 0, 0},
+ {'u', EModifierLongKey|EModifierAlt, EModifierLongKey, 0},
+ {'V', EModifierLongKey|EModifierShift, EModifierLongKey|EModifierShift, 0},
+ // @SYMPREQ 417-61800: Check that attempts to capture keys with a priority
+ // of KMinTInt fail with KErrArgument.
+ {'W', 0, 0, KMinTInt},
};
const TInt numCapKeys=sizeof(capKeys)/sizeof(capKeys[0]);
--- a/windowing/windowserver/test/tauto/TEVENT.H Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/test/tauto/TEVENT.H Fri Sep 24 16:44:34 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1996-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -38,6 +38,7 @@
const TInt EMaxEventQueueSize=32;
const TInt EMinQueueSize = 2;
+const TUint KModifiersIgnore = 0xffffffff;
class CTEventTest;
@@ -263,6 +264,11 @@
// Add additional enum values before this line
EMaxCancelCaptureKeyApis
};
+ enum TLongkeyCapPriorityTests
+ {
+ ELongkeyCaptureSamePriority,
+ ELongkeyCaptureDiffPriority
+ };
private:
void RunTestsL(TBool aNeedChildWindows=EFalse);
void RunTestsRestoreAreaL(TBool aNeedChildWindows);
@@ -285,13 +291,17 @@
void Password_NextSetOfEvents();
void GroupListChanged_NextSetOfEventsL();
void VisibilityChanged_NextSetOfEventsL();
+#ifndef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA
+ void KeyEventTranslation_NextSetOfEventsL();
+ void KeyEventBlocking_NextSetOfEventsL();
+ void KeyEventAppRestriction_NextSetOfEventsL();
+ void KeyEventAppPriority_NextSetOfEventsL();
#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
-#ifndef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA
void SurfaceVisibilityChanged1_NextSetOfEventsL();
void SurfaceVisibilityChanged2_NextSetOfEventsL();
void SurfaceVisibilityChanged3_NextSetOfEventsL();
+#endif //SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
#endif //TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA
-#endif //SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
void CheckTimeStamp_NextSetOfEventsL();
void RepeatableKeysL();
void PointerCapture_NextSetOfEventsL();
@@ -311,8 +321,8 @@
void EventHandlerRemoval_AddEventHandlerMultipleTimes();
void CheckPointerCursorInDifferentScreenMode(TSizeMode aMode,TPoint aOrigin);
void SimulateAndCheck(TPoint aOrigin,TSize aScale,TInt aXOffset,TInt aYOffset,TPointerEvent::TType aEventType,TRect aPointerCursorArea);
- void AddExpectedKey(TInt aEventCode, TInt aScanCode, TInt aCode=0, TInt aRepeats=0, TUint aModifiers=0);
- void AddExpectedKeyDownUp(TInt aScanCode, TInt aCode=0, TInt aRepeats=0, TUint aModifiers=0);
+ void AddExpectedKey(TInt aEventCode, TInt aScanCode, TInt aCode=0, TInt aRepeats=0, TUint aModifiers=KModifiersIgnore);
+ void AddExpectedKeyDownUp(TInt aScanCode, TInt aCode=0, TInt aRepeats=0, TUint aModifiers=KModifiersIgnore);
void AddExpectedEvent(TInt aEventCode, CTWinBase* aWin);
void AddExpectedEvent(TInt aEventCode);
void AddExpectedEvent(TInt aEventCode,RWindowGroup* aWindow);
@@ -358,6 +368,11 @@
#endif
void TestCaptureAndCancelCapturePair(TCaptureKeyApis aCaptureApi, TCancelCaptureKeyApis aCancelCaptureApi);
static TInt GenerateAnEvent(TAny* aEventTest);
+ void CheckLongkeyCaptureWithPriority(TLongkeyCapPriorityTests aTestType);
+ void DelayForRepeatEvents(TInt aNumeratorFracVal, TInt aDenominatorFracVal);
+#ifndef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA
+ void SpawnCaptureAppL(RProcess& aProcess);
+#endif
private:
CTBlankWindow* iBlankWin;
RBlankWindow iBackingWindow;
@@ -390,13 +405,17 @@
TBool iIs3DPointer;
TBool iPtrPluginLoaded;
TInt iYOffset;
+ TTimeIntervalMicroSeconds32 iKeyBoardRepeatInitialDelay;
+ TTimeIntervalMicroSeconds32 iKeyBoardRepeatNextDelay;
+#ifndef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA
+ RProcess iCaptureApp1;
+ RProcess iCaptureApp2;
#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
-#ifndef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA
TSurfaceId iSurfaceId;
RSurfaceManager iSurfaceManager;
CPeriodic* iTimeOutCallback;
+#endif // SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
#endif // TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA
-#endif // SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
};
class CTQueueWindowGroup : public CTWindowGroup
--- a/windowing/windowserver/test/tauto/TEvent.CPP Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/test/tauto/TEvent.CPP Fri Sep 24 16:44:34 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1996-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -37,6 +37,9 @@
_LIT(KKeyClickPluginDll, "click.dll");
+const TInt KLongKeyCaptureLowPriority = 1;
+const TInt KLongKeyCaptureHighPriority = 2;
+
CTQueueClient::CTQueueClient(CTEventTest *aTest) : iTest(aTest)
{
}
@@ -203,6 +206,7 @@
TestL(wsEvent.Type()==expectedEvent.Type() && wsEvent.Handle()==expectedEvent.Handle());
}
iLastEventError=(wsEvent.Type()==EEventErrorMessage);
+
switch(wsEvent.Type())
{
case EEventKey:
@@ -212,7 +216,7 @@
{
_LIT(KKeysDiff,"Count=%d Key Code Exp=%d (%c) Act=%d (%c)");
buf.Copy(KStartString);
- buf.AppendFormat(KKeysDiff,iEventCount,iEventCount,eKeyCode,eKeyCode,wsKeyCode,wsKeyCode);
+ buf.AppendFormat(KKeysDiff,iEventCount,eKeyCode,eKeyCode,wsKeyCode,wsKeyCode);
iTest->LOG_MESSAGE(buf);
}
wsKeyRepeat=wsEvent.Key()->iRepeats,eKeyRepeat=expectedEvent.Key()->iRepeats;
@@ -224,10 +228,15 @@
iTest->LOG_MESSAGE(buf);
}
#endif
- TestL(wsEvent.Key()->iCode==expectedEvent.Key()->iCode && wsEvent.Key()->iRepeats>=expectedEvent.Key()->iRepeats
- && (wsEvent.Key()->iRepeats>0)==(expectedEvent.Key()->iRepeats>0)); //Fall Through
+ TestL(wsEvent.Key()->iCode==expectedEvent.Key()->iCode &&
+ wsEvent.Key()->iRepeats>=expectedEvent.Key()->iRepeats &&
+ (wsEvent.Key()->iRepeats>0)==(expectedEvent.Key()->iRepeats>0));
+ // Fall Through
case EEventKeyDown:
case EEventKeyUp:
+ {
+ TUint wsModifiers = wsEvent.Key()->iModifiers;
+ TUint eModifiers = expectedEvent.Key()->iModifiers;
#if defined(FAIL_LOGGING)
wsKeyScan=wsEvent.Key()->iScanCode,eKeyScan=expectedEvent.Key()->iScanCode;
if (wsKeyScan!=eKeyScan)
@@ -237,8 +246,18 @@
buf.AppendFormat(KScanDiff,iEventCount,eKeyScan,eKeyScan,wsKeyScan,wsKeyScan);
iTest->LOG_MESSAGE(buf);
}
+
+ if (eModifiers != KModifiersIgnore && wsModifiers != eModifiers)
+ {
+ _LIT(KModDiff,"Count=%d Modifiers Exp=0x%x Act=0x%x");
+ buf.Copy(KStartString);
+ buf.AppendFormat(KModDiff, iEventCount, eModifiers, wsModifiers);
+ iTest->LOG_MESSAGE(buf);
+ }
#endif
- TestL(wsEvent.Key()->iScanCode==expectedEvent.Key()->iScanCode);
+ TestL(wsEvent.Key()->iScanCode == expectedEvent.Key()->iScanCode &&
+ (eModifiers == KModifiersIgnore || wsModifiers == eModifiers));
+ }
break;
case EEventModifiersChanged:
{
@@ -708,7 +727,8 @@
{
iIs3DPointer=EFalse;
}
-#endif
+#endif
+ TheClient->iWs.GetKeyboardRepeatRate(iKeyBoardRepeatInitialDelay, iKeyBoardRepeatNextDelay);
}
void CTEventTest::Failed()
@@ -820,7 +840,7 @@
group.SetOrdinalPosition(position,priority);
}
-void CTEventTest::AddExpectedKey(TInt aEventCode, TInt aScanCode, TInt aCode/*=0*/, TInt aRepeats/*=0*/, TUint aModifiers/*=0*/)
+void CTEventTest::AddExpectedKey(TInt aEventCode, TInt aScanCode, TInt aCode/*=0*/, TInt aRepeats/*=0*/, TUint aModifiers/*=KModifiersIgnore*/)
{
TPckgBuf<TWsEvent> evtPkg;
TWsEvent& event=evtPkg();
@@ -834,15 +854,27 @@
event.Key()->iRepeats=aRepeats;
iQueueClient->AddExpectedEvent(event);
if (iAddToClick)
+ {
+ if (aModifiers == KModifiersIgnore)
+ {
+ // Key click tests assume zero modifiers in click event by default
+ event.Key()->iModifiers = 0;
+ }
iClick.CommandReply(EClickEventAdd,evtPkg);
- }
-
-void CTEventTest::AddExpectedKeyDownUp(TInt aScanCode, TInt aCode/*=0*/, TInt aRepeats/*=0*/, TUint aModifiers/*=0*/)
+ }
+ }
+
+void CTEventTest::AddExpectedKeyDownUp(TInt aScanCode, TInt aCode/*=0*/, TInt aRepeats/*=0*/, TUint aModifiers/*=KModifiersIgnore*/)
{
__ASSERT_DEBUG(aScanCode<'a' || aScanCode>'z',AutoPanic(EAutoPanicScanCapital));
- AddExpectedKey(EEventKeyDown,aScanCode,0,aRepeats,aModifiers);
+ // EModiferAutorepeatable can be present in EEventKey but is never valid
+ // in EEventKeyDown and EEventKeyUp.
+ TUint modifiersDownUp = (aModifiers == KModifiersIgnore) ?
+ aModifiers : aModifiers & ~EModifierAutorepeatable;
+
+ AddExpectedKey(EEventKeyDown,aScanCode,0,aRepeats,modifiersDownUp);
AddExpectedKey(EEventKey,aScanCode,aCode,aRepeats,aModifiers);
- AddExpectedKey(EEventKeyUp,aScanCode,0,aRepeats,aModifiers);
+ AddExpectedKey(EEventKeyUp,aScanCode,0,aRepeats,modifiersDownUp);
}
void CTEventTest::AddExpectedEvent(TInt aEventCode, CTWinBase* aWin)
@@ -1160,20 +1192,32 @@
case 27:
RawEventRepeatTest_NextSetOfEventsL();
break;
-
-#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
+
#ifndef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA
case 28:
- SurfaceVisibilityChanged1_NextSetOfEventsL();
+ KeyEventTranslation_NextSetOfEventsL();
break;
case 29:
- SurfaceVisibilityChanged2_NextSetOfEventsL();
+ KeyEventBlocking_NextSetOfEventsL();
break;
case 30:
+ KeyEventAppRestriction_NextSetOfEventsL();
+ break;
+ case 31:
+ KeyEventAppPriority_NextSetOfEventsL();
+ break;
+#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
+ case 32:
+ SurfaceVisibilityChanged1_NextSetOfEventsL();
+ break;
+ case 33:
+ SurfaceVisibilityChanged2_NextSetOfEventsL();
+ break;
+ case 34:
SurfaceVisibilityChanged3_NextSetOfEventsL();
break;
+#endif // SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
#endif // TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA
-#endif // SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
default:
AutoPanic(EAutoPanicWrongTest);
@@ -3545,8 +3589,8 @@
break;
case 2:
AddExpectedKey(EEventKeyDown,EStdKeyRightShift,0,0,EModifierRightShift|EModifierShift);
- AddExpectedKeyDownUp('B','B',0,EModifierRightShift|EModifierShift);
- AddExpectedKeyDownUp('W','W',0,EModifierRightShift|EModifierShift);
+ AddExpectedKeyDownUp('B','B',0,EModifierRightShift|EModifierShift|EModifierAutorepeatable);
+ AddExpectedKeyDownUp('W','W',0,EModifierRightShift|EModifierShift|EModifierAutorepeatable);
AddExpectedKey(EEventKeyUp,EStdKeyRightShift);
iQueueClient->iWs.Flush();
iTest->SimulateKey(TRawEvent::EKeyDown,EStdKeyRightShift); //1 event
@@ -3854,11 +3898,9 @@
void CTEventTest::CaptureLong_NextSetOfEventsL()
{
- TTimeIntervalMicroSeconds32 initialTime,time;
- TheClient->iWs.GetKeyboardRepeatRate(initialTime,time);
#if defined(LOGGING)
TLogMessageText logMessageText;
- _LIT(KSet,"CaptureLong SetOfEvents: %d of 14");
+ _LIT(KSet,"CaptureLong SetOfEvents: %d of 23");
logMessageText.Format(KSet,iEventSet);
INFO_PRINTF1(logMessageText);
#endif
@@ -3872,53 +3914,72 @@
AddExpectedKeyDownUp('A','a');
break;
case 1:
- iCaptureKey=iQueueClient->iGroup->GroupWin()->CaptureLongKey(' ','a',0,0,2,ELongCaptureNormal);
+ // Test CaptureLongKey() with modifier value EModifierShift and flag value ELongCaptureNormal
+ iCaptureKey=iQueueClient->iGroup->GroupWin()->CaptureLongKey(' ','a',EModifierShift,EModifierShift,2,ELongCaptureNormal);
iQueueClient->iWs.Flush();
+ iTest->SimulateKey(TRawEvent::EKeyDown,EStdKeyLeftShift);
iTest->SimulateKey(TRawEvent::EKeyDown,EStdKeySpace);
TheClient->iWs.Flush();
- User::After(initialTime.Int()+time.Int()/3);
+ DelayForRepeatEvents(1, 3);
iTest->SimulateKey(TRawEvent::EKeyUp,EStdKeySpace);
+ iTest->SimulateKey(TRawEvent::EKeyUp,EStdKeyLeftShift);
+ AddExpectedKey(EEventKeyDown,EStdKeyLeftShift);
AddExpectedKey(EEventKeyDown,EStdKeySpace);
- AddExpectedKey(EEventKey,EStdKeySpace,' ');
- AddExpectedKey(EEventKey,EStdKeySpace,'a',1);
+ AddExpectedKey(EEventKey,EStdKeySpace,' ',0,EModifierLeftShift|EModifierShift|EModifierAutorepeatable);
+ AddExpectedKey(EEventKey,EStdKeySpace,'a',1,EModifierLongKey|EModifierLeftShift|EModifierShift|EModifierAutorepeatable);
AddExpectedKey(EEventKeyUp,EStdKeySpace);
+ AddExpectedKey(EEventKeyUp,EStdKeyLeftShift);
iQueueClient->iGroup->GroupWin()->CancelCaptureLongKey(iCaptureKey);
break;
- case 2:
- iCaptureKey=iQueueClient->iGroup->GroupWin()->CaptureLongKey(' ','a',0,0,2,ELongCaptureWaitShort);
+ case 2:
+ // Test CaptureLongKey() with modifier value EModifierFunc and flag value ELongCaptureWaitShort
+ iCaptureKey=iQueueClient->iGroup->GroupWin()->CaptureLongKey(EKeyEnter,'a',EModifierFunc,EModifierFunc,2,ELongCaptureWaitShort);
iQueueClient->iWs.Flush();
- iTest->SimulateKey(TRawEvent::EKeyDown,EStdKeySpace);
+ iTest->SimulateKey(TRawEvent::EKeyDown,EStdKeyLeftFunc);
+ iTest->SimulateKey(TRawEvent::EKeyDown,EStdKeyEnter);
TheClient->iWs.Flush();
- User::After(initialTime.Int()+time.Int()/3);
- iTest->SimulateKey(TRawEvent::EKeyUp,EStdKeySpace);
+ DelayForRepeatEvents(1, 3);
+ iTest->SimulateKey(TRawEvent::EKeyUp,EStdKeyEnter);
+ iTest->SimulateKey(TRawEvent::EKeyUp,EStdKeyLeftFunc);
iTest->SimulateKeyDownUp(EStdKeySpace);
- AddExpectedKey(EEventKeyDown,EStdKeySpace);
- AddExpectedKey(EEventKey,EStdKeySpace,'a',1);
- AddExpectedKey(EEventKeyUp,EStdKeySpace);
+ AddExpectedKey(EEventKeyDown,EStdKeyLeftFunc);
+ AddExpectedKey(EEventKeyDown,EStdKeyEnter);
+ AddExpectedKey(EEventKey,EStdKeyEnter,'a',1,EModifierLongKey|EModifierLeftFunc|EModifierFunc|EModifierAutorepeatable);
+ AddExpectedKey(EEventKeyUp,EStdKeyEnter);
+ AddExpectedKey(EEventKeyUp,EStdKeyLeftFunc);
AddExpectedKeyDownUp(EStdKeySpace,' ');
iQueueClient->iGroup->GroupWin()->CancelCaptureLongKey(iCaptureKey);
break;
case 3:
- iCaptureKey=iQueueClient->iGroup->GroupWin()->CaptureLongKey(' ','a',0,0,2,ELongCaptureNormal|ELongCaptureRepeatEvents);
+ // Test CaptureLongKey() with modifier values EModifierFunc|EModifierAlt and flag values ELongCaptureNormal|ELongCaptureRepeatEvents)
+ iCaptureKey=iQueueClient->iGroup->GroupWin()->CaptureLongKey(EKeyEnter,'a',EModifierFunc|EModifierAlt,EModifierFunc|EModifierAlt,2,ELongCaptureNormal|ELongCaptureRepeatEvents);
iQueueClient->iWs.Flush();
- iTest->SimulateKey(TRawEvent::EKeyDown,EStdKeySpace);
+ iTest->SimulateKey(TRawEvent::EKeyDown,EStdKeyLeftFunc);
+ iTest->SimulateKey(TRawEvent::EKeyDown,EStdKeyLeftAlt);
+ iTest->SimulateKey(TRawEvent::EKeyDown,EStdKeyEnter);
TheClient->iWs.Flush();
- User::After(initialTime.Int()+5*time.Int());
- iTest->SimulateKey(TRawEvent::EKeyUp,EStdKeySpace);
- AddExpectedKey(EEventKeyDown,EStdKeySpace);
- AddExpectedKey(EEventKey,EStdKeySpace,' ');
- AddExpectedKey(EEventKey,EStdKeySpace,'a',2);
- AddExpectedKey(EEventKeyUp,EStdKeySpace);
+ DelayForRepeatEvents(5, 1);
+ iTest->SimulateKey(TRawEvent::EKeyUp,EStdKeyEnter);
+ iTest->SimulateKey(TRawEvent::EKeyUp,EStdKeyLeftAlt);
+ iTest->SimulateKey(TRawEvent::EKeyUp,EStdKeyLeftFunc);
+ AddExpectedKey(EEventKeyDown,EStdKeyLeftFunc);
+ AddExpectedKey(EEventKeyDown,EStdKeyLeftAlt);
+ AddExpectedKey(EEventKeyDown,EStdKeyEnter);
+ AddExpectedKey(EEventKey,EStdKeyEnter,EKeyEnter,0,EModifierLeftFunc|EModifierFunc|EModifierLeftAlt|EModifierAlt|EModifierAutorepeatable);
+ AddExpectedKey(EEventKey,EStdKeyEnter,'a',2,EModifierLongKey|EModifierLeftFunc|EModifierFunc|EModifierLeftAlt|EModifierAlt|EModifierAutorepeatable);
+ AddExpectedKey(EEventKeyUp,EStdKeyEnter);
+ AddExpectedKey(EEventKeyUp,EStdKeyLeftAlt);
+ AddExpectedKey(EEventKeyUp,EStdKeyLeftFunc);
iQueueClient->iGroup->GroupWin()->CancelCaptureLongKey(iCaptureKey);
break;
case 4:
iQueueClient->iWs.Flush();
iTest->SimulateKey(TRawEvent::EKeyDown,'Z');
TheClient->iWs.Flush();
- User::After(initialTime.Int()+3*time.Int());
+ DelayForRepeatEvents(3, 1);
iTest->SimulateKey(TRawEvent::EKeyDown,'Y');
TheClient->iWs.Flush();
- User::After(initialTime.Int()+2*time.Int());
+ DelayForRepeatEvents(2, 1);
iTest->SimulateKey(TRawEvent::EKeyUp,'Z');
iTest->SimulateKey(TRawEvent::EKeyUp,'Y');
AddExpectedKey(EEventKeyDown,'Z');
@@ -3934,13 +3995,13 @@
iQueueClient->iWs.Flush();
iTest->SimulateKey(TRawEvent::EKeyDown,'Z');
TheClient->iWs.Flush();
- User::After(initialTime.Int()+3*time.Int());
+ DelayForRepeatEvents(3, 1);
iTest->SimulateKey(TRawEvent::EKeyDown,'Y');
TheClient->iWs.Flush();
- User::After(initialTime.Int()+5*time.Int()/2);
+ DelayForRepeatEvents(5, 2);
iTest->SimulateKey(TRawEvent::EKeyUp,'Y');
TheClient->iWs.Flush();
- User::After(initialTime.Int()+2*time.Int());
+ DelayForRepeatEvents(2, 1);
iTest->SimulateKey(TRawEvent::EKeyUp,'Z');
AddExpectedKey(EEventKeyDown,'Z');
AddExpectedKey(EEventKey,'Z','z');
@@ -3957,12 +4018,12 @@
iQueueClient->iWs.Flush();
iTest->SimulateKey(TRawEvent::EKeyDown,'X');
TheClient->iWs.Flush();
- User::After(initialTime.Int()+3*time.Int());
+ DelayForRepeatEvents(3, 1);
iTest->SimulateKeyDownUp(EStdKeySpace);
TheClient->iWs.Flush();
if(!iTest->IsFullRomL())
{
- User::After(initialTime.Int()+2*time.Int());
+ DelayForRepeatEvents(2, 1);
}
iTest->SimulateKey(TRawEvent::EKeyUp,'X');
AddExpectedKey(EEventKeyDown,'X');
@@ -3983,14 +4044,14 @@
iQueueClient->iWs.Flush();
iTest->SimulateKey(TRawEvent::EKeyDown,'X');
TheClient->iWs.Flush();
- User::After(initialTime.Int()+5*time.Int());
+ DelayForRepeatEvents(5, 1);
iTest->SimulateKey(TRawEvent::EKeyDown,EStdKeySpace);
TheClient->iWs.Flush();
- User::After(initialTime.Int()+time.Int()/3);
+ DelayForRepeatEvents(1, 3);
iTest->SimulateKey(TRawEvent::EKeyUp,EStdKeySpace);
TheClient->iWs.Flush();
User::ResetInactivityTime();
- User::After(initialTime.Int()+4*time.Int());
+ DelayForRepeatEvents(4, 1);
iTest->SimulateKey(TRawEvent::EKeyUp,'X');
AddExpectedKey(EEventKeyDown,'X');
AddExpectedKey(EEventKey,'X','x');
@@ -4008,7 +4069,7 @@
iQueueClient->iWs.Flush();
iTest->SimulateKey(TRawEvent::EKeyDown,EStdKeySpace);
TheClient->iWs.Flush();
- User::After(initialTime.Int()+5*time.Int());
+ DelayForRepeatEvents(5, 1);
iTest->SimulateKey(TRawEvent::EKeyUp,EStdKeySpace);
AddExpectedKey(EEventKeyDown,EStdKeySpace);
AddExpectedKey(EEventKey,EStdKeySpace,'c',1);
@@ -4022,10 +4083,10 @@
iQueueClient->iWs.Flush();
iTest->SimulateKey(TRawEvent::EKeyDown,EStdKeySpace);
TheClient->iWs.Flush();
- User::After(initialTime.Int()+5*time.Int()/2);
+ DelayForRepeatEvents(5, 2);
iTest->SimulateKeyDownUp(EStdKeyEscape);
TheClient->iWs.Flush();
- User::After(initialTime.Int()+3*time.Int());
+ DelayForRepeatEvents(3, 1);
iTest->SimulateKey(TRawEvent::EKeyUp,EStdKeySpace);
AddExpectedKey(EEventKeyDown,EStdKeySpace);
AddExpectedKey(EEventKey,EStdKeySpace,' ');
@@ -4045,33 +4106,36 @@
iTest->SimulateKey(TRawEvent::EKeyDown,EStdKeySpace);
TheClient->iWs.Flush();
iQueueClient->iGroup->GroupWin()->CancelCaptureLongKey(iCaptureKey);
- User::After(initialTime.Int()+5*time.Int());
+ DelayForRepeatEvents(5, 1);
iTest->SimulateKey(TRawEvent::EKeyUp,EStdKeySpace);
AddExpectedKey(EEventKeyDown,EStdKeySpace);
AddExpectedKey(EEventKey,EStdKeySpace,' ');
AddExpectedKey(EEventKeyUp,EStdKeySpace);
break;
case 11:
- //Cancel a capture key up and down event whilst a repeat is underway
- iCaptureKey=iQueueClient->iGroup->GroupWin()->CaptureKeyUpAndDowns(EStdKeySpace,0,0);
+ // Cancel a key up/down capture whilst a repeat is underway.
+ // This should have no effect since only key press events are
+ // repeated.
+ iCaptureKey=iQueueClient->iGroup->GroupWin()->CaptureKeyUpAndDowns('X',0,0);
iQueueClient->iWs.Flush();
iTest->SimulateKey(TRawEvent::EKeyDown,'X');
TheClient->iWs.Flush();
iQueueClient->iGroup->GroupWin()->CancelCaptureKeyUpAndDowns(iCaptureKey);
- User::After(initialTime.Int()+5*time.Int());
+ DelayForRepeatEvents(5, 1);
iTest->SimulateKey(TRawEvent::EKeyUp,'X');
AddExpectedKey(EEventKeyDown,'X');
AddExpectedKey(EEventKey,'X','x');
+ AddExpectedKey(EEventKey,'X','x',2);
AddExpectedKey(EEventKeyUp,'X');
break;
case 12:
//Cancel a capture key event whilst a repeat is underway
- iCaptureKey=iQueueClient->iGroup->GroupWin()->CaptureKey(EStdKeySpace,0,0);
+ iCaptureKey=iQueueClient->iGroup->GroupWin()->CaptureKey('y',0,0);
iQueueClient->iWs.Flush();
iTest->SimulateKey(TRawEvent::EKeyDown,'Y');
TheClient->iWs.Flush();
iQueueClient->iGroup->GroupWin()->CancelCaptureKey(iCaptureKey);
- User::After(initialTime.Int()+5*time.Int());
+ DelayForRepeatEvents(5, 1);
iTest->SimulateKey(TRawEvent::EKeyUp,'Y');
AddExpectedKey(EEventKeyDown,'Y');
AddExpectedKey(EEventKey,'Y','y');
@@ -4079,13 +4143,13 @@
break;
case 13:
//Variation on case 12 i.e. change in the timing of the CancelCaptureKey call
- iCaptureKey=iQueueClient->iGroup->GroupWin()->CaptureKey(EStdKeySpace,0,0);
+ iCaptureKey=iQueueClient->iGroup->GroupWin()->CaptureKey('z',0,0);
iQueueClient->iWs.Flush();
iTest->SimulateKey(TRawEvent::EKeyDown,'Z');
TheClient->iWs.Flush();
- User::After(initialTime.Int()+5*time.Int()/2);
+ DelayForRepeatEvents(5, 2);
iQueueClient->iGroup->GroupWin()->CancelCaptureKey(iCaptureKey);
- User::After(initialTime.Int()+5*time.Int()/2);
+ DelayForRepeatEvents(5, 2);
iTest->SimulateKey(TRawEvent::EKeyUp,'Z');
AddExpectedKey(EEventKeyDown,'Z');
AddExpectedKey(EEventKey,'Z','z');
@@ -4102,7 +4166,7 @@
iTest->SimulateKey(TRawEvent::EKeyDown,EStdKeySpace);
TheClient->iWs.Flush();
iQueueClient->iGroup->GroupWin()->CancelCaptureLongKey(iCaptureKey);
- User::After(initialTime.Int()+time.Int()/3);
+ DelayForRepeatEvents(1, 3);
TheClient->iGroup->GroupWin()->CancelCaptureKey(shortCaptKey);
iTest->SimulateKey(TRawEvent::EKeyUp,EStdKeySpace);
@@ -4110,6 +4174,132 @@
AddExpectedKey(EEventKeyUp,EStdKeySpace);
}
break;
+ case 15:
+ // @SYMPREQ 417-61800: Check that long key events are marked with
+ // EModifierLongKey and short events are not.
+ iCaptureKey = iQueueClient->iGroup->GroupWin()->CaptureLongKey('m', 'm', 0, 0, 0, ELongCaptureNormal);
+ iQueueClient->iWs.Flush();
+ iTest->SimulateKey(TRawEvent::EKeyDown, 'M');
+ TheClient->iWs.Flush();
+ DelayForRepeatEvents(1, 3);
+ iTest->SimulateKey(TRawEvent::EKeyUp, 'M');
+ AddExpectedKey(EEventKeyDown, 'M', 0, 0, 0);
+ AddExpectedKey(EEventKey, 'M', 'm', 0, EModifierAutorepeatable);
+ AddExpectedKey(EEventKey, 'M', 'm', 1, EModifierLongKey | EModifierAutorepeatable);
+ AddExpectedKey(EEventKeyUp, 'M', 0, 0, 0);
+ iQueueClient->iGroup->GroupWin()->CancelCaptureLongKey(iCaptureKey);
+ break;
+ case 16:
+ CheckLongkeyCaptureWithPriority(ELongkeyCaptureDiffPriority);
+ break;
+ case 17:
+ CheckLongkeyCaptureWithPriority(ELongkeyCaptureSamePriority);
+ break;
+ case 18:
+ // Test CaptureLongKey() with flag value ELongCaptureWaitShort
+ // when key is not held down long enough to generate a long event.
+ // Verify that short event is delivered when the key is released.
+ iCaptureKey = iQueueClient->iGroup->GroupWin()->CaptureLongKey('p', 'p', 0, 0, 0, ELongCaptureWaitShort);
+ iQueueClient->iWs.Flush();
+ iTest->SimulateKey(TRawEvent::EKeyDown, 'P');
+ TheClient->iWs.Flush();
+ User::After(iKeyBoardRepeatInitialDelay.Int() / 2);
+ iTest->SimulateKey(TRawEvent::EKeyUp, 'P');
+ TheClient->iWs.Flush();
+ iTest->SimulateKeyDownUp(EStdKeySpace);
+ AddExpectedKey(EEventKeyDown, 'P');
+ AddExpectedKey(EEventKey, 'P', 'p', 0, EModifierAutorepeatable);
+ AddExpectedKey(EEventKeyUp, 'P');
+ AddExpectedKeyDownUp(EStdKeySpace, ' ');
+ iQueueClient->iGroup->GroupWin()->CancelCaptureLongKey(iCaptureKey);
+ break;
+ case 19:
+ {
+ // Cancel a capture key event whilst a repeat is underway for a
+ // different capture. This should not cancel repeating.
+ iCaptureKey = iQueueClient->iGroup->GroupWin()->CaptureKey('q', 0, 0);
+ TInt captureKey2 = iQueueClient->iGroup->GroupWin()->CaptureKey('r', 0, 0);
+ iQueueClient->iWs.Flush();
+ iTest->SimulateKey(TRawEvent::EKeyDown, 'Q');
+ TheClient->iWs.Flush();
+ iQueueClient->iGroup->GroupWin()->CancelCaptureKey(captureKey2);
+ DelayForRepeatEvents(5, 1);
+ iTest->SimulateKey(TRawEvent::EKeyUp, 'Q');
+ AddExpectedKey(EEventKeyDown, 'Q');
+ AddExpectedKey(EEventKey, 'Q', 'q', 0, EModifierAutorepeatable);
+ AddExpectedKey(EEventKey, 'Q', 'q', 2, EModifierAutorepeatable);
+ AddExpectedKey(EEventKeyUp, 'Q');
+ iQueueClient->iGroup->GroupWin()->CancelCaptureKey(iCaptureKey);
+ }
+ break;
+ case 20:
+ {
+ // Cancel a long capture key event whilst a repeat is underway for
+ // a different capture. This should not cancel repeating.
+ iCaptureKey = iQueueClient->iGroup->GroupWin()->CaptureLongKey('s', 's', 0, 0, 2, ELongCaptureNormal|ELongCaptureRepeatEvents);
+ TInt captureKey2 = iQueueClient->iGroup->GroupWin()->CaptureLongKey('t', 't', 0, 0, 2, ELongCaptureNormal|ELongCaptureRepeatEvents);
+ iQueueClient->iWs.Flush();
+ iTest->SimulateKey(TRawEvent::EKeyDown, 'S');
+ TheClient->iWs.Flush();
+ iQueueClient->iGroup->GroupWin()->CancelCaptureLongKey(captureKey2);
+ DelayForRepeatEvents(5, 1);
+ iTest->SimulateKey(TRawEvent::EKeyUp, 'S');
+ AddExpectedKey(EEventKeyDown, 'S');
+ AddExpectedKey(EEventKey, 'S', 's', 0, EModifierAutorepeatable);
+ AddExpectedKey(EEventKey, 'S', 's', 2, EModifierLongKey | EModifierAutorepeatable);
+ AddExpectedKey(EEventKeyUp, 'S');
+ iQueueClient->iGroup->GroupWin()->CancelCaptureLongKey(iCaptureKey);
+ }
+ break;
+ case 21:
+ {
+ // Test CaptureLongKey() with a user specified initial repeat time.
+ // Simulate holding down the key for a period shorter than the
+ // specified delay. Verify that a long key event is NOT generated.
+ // (Note that the period is longer than the default initial repeat
+ // time, thus proving that CaptureLongKey() has honoured the delay
+ // argument.)
+ TTimeIntervalMicroSeconds32 delay(iKeyBoardRepeatInitialDelay.Int() * 4);
+ iCaptureKey = iQueueClient->iGroup->GroupWin()->CaptureLongKey(delay, 'u', 'u', 0, 0, 0, ELongCaptureNormal);
+ iQueueClient->iWs.Flush();
+ iTest->SimulateKey(TRawEvent::EKeyDown, 'U');
+ TheClient->iWs.Flush();
+ User::After(delay.Int() / 2);
+ iTest->SimulateKey(TRawEvent::EKeyUp, 'U');
+ TheClient->iWs.Flush();
+ iTest->SimulateKeyDownUp(EStdKeySpace);
+ AddExpectedKey(EEventKeyDown, 'U');
+ AddExpectedKey(EEventKey, 'U', 'u', 0, EModifierAutorepeatable);
+ AddExpectedKey(EEventKeyUp, 'U');
+ AddExpectedKeyDownUp(EStdKeySpace, ' ');
+ iQueueClient->iGroup->GroupWin()->CancelCaptureLongKey(iCaptureKey);
+ }
+ break;
+ case 22:
+ {
+ // Test CaptureLongKey() with a user specified initial repeat time.
+ // Simulate holding down the key for a period longer than the
+ // specified delay. Verify that a long key event is generated.
+ // (Note that the period is shorter than the default initial repeat
+ // time, thus proving that CaptureLongKey() has honoured the delay
+ // argument.)
+ TTimeIntervalMicroSeconds32 delay(iKeyBoardRepeatInitialDelay.Int() / 4);
+ iCaptureKey = iQueueClient->iGroup->GroupWin()->CaptureLongKey(delay, 'v', 'v', 0, 0, 0, ELongCaptureNormal);
+ iQueueClient->iWs.Flush();
+ iTest->SimulateKey(TRawEvent::EKeyDown, 'V');
+ TheClient->iWs.Flush();
+ User::After(delay.Int() * 2);
+ iTest->SimulateKey(TRawEvent::EKeyUp, 'V');
+ TheClient->iWs.Flush();
+ iTest->SimulateKeyDownUp(EStdKeySpace);
+ AddExpectedKey(EEventKeyDown, 'V');
+ AddExpectedKey(EEventKey, 'V', 'v', 0, EModifierAutorepeatable);
+ AddExpectedKey(EEventKey, 'V', 'v', 1, EModifierLongKey | EModifierAutorepeatable);
+ AddExpectedKey(EEventKeyUp, 'V');
+ AddExpectedKeyDownUp(EStdKeySpace, ' ');
+ iQueueClient->iGroup->GroupWin()->CancelCaptureLongKey(iCaptureKey);
+ }
+ break;
default:
CActiveScheduler::Stop();
break;
@@ -4117,6 +4307,485 @@
TheClient->iWs.Flush();
}
+/** Function used for checking CaptureLongKey() works fine with different priorities.
+
+If two window groups have requested capture of the same key with different priorities,
+then the event should be delivered to the group that specified higher priority
+(even if it is in the background).
+
+If two window groups have requested capture of the same key with same priorities,
+then the event should be delivered to the group that requested capture most recently.
+
+@param aTestType Enum value specifying test with same priority or with different priority
+*/
+void CTEventTest::CheckLongkeyCaptureWithPriority(TLongkeyCapPriorityTests aTestType)
+ {
+ TInt ordinalPriority = TheClient->iGroup->GroupWin()->OrdinalPriority();
+ TInt ordinalPosition = TheClient->iGroup->GroupWin()->OrdinalPosition();
+ // Bring other window group to foreground and request capture with lower/same priority
+ // And request capture from iQueueClient group window with higher priority
+ TheClient->iGroup->GroupWin()->SetOrdinalPosition(0, 10);
+ TInt capKeyFrontWin = TheClient->iGroup->GroupWin()->CaptureLongKey('m', 'm', 0, 0, (aTestType == ELongkeyCaptureDiffPriority ? KLongKeyCaptureLowPriority : KLongKeyCaptureHighPriority), ELongCaptureNormal);
+ iCaptureKey = iQueueClient->iGroup->GroupWin()->CaptureLongKey('m', 'm', 0, 0, KLongKeyCaptureHighPriority, ELongCaptureNormal);
+ iQueueClient->iWs.Flush();
+ iTest->SimulateKey(TRawEvent::EKeyDown, 'M');
+ TheClient->iWs.Flush();
+ DelayForRepeatEvents(1, 3);
+ iTest->SimulateKey(TRawEvent::EKeyUp, 'M');
+ AddExpectedEvent(EEventFocusLost);
+ //Note: Button down/up events along with immediate key events are not delivered to iQueueCLient's window group
+ //as they are sent to foreground/focused window group
+ AddExpectedKey(EEventKey, 'M', 'm', 1, EModifierLongKey | EModifierAutorepeatable);
+ iQueueClient->iGroup->GroupWin()->CancelCaptureLongKey(iCaptureKey);
+ TheClient->iGroup->GroupWin()->CancelCaptureLongKey(capKeyFrontWin);
+ TheClient->iGroup->GroupWin()->SetOrdinalPosition(ordinalPosition, ordinalPriority);
+ AddExpectedEvent(EEventFocusGained);
+ }
+
+/** Function used for delaying current thread so that repeat events can be generated.
+
+It uses iKeyBoardRepeatInitialDelay and iKeyBoardRepeatNextDelay variables to get the desired delay.
+The idea is to wait for initial delay + some extra value so that first repeat is generated.
+For more than one repeat events, wait will be initial delay + next delay + some extra value, and so on.
+
+The extra value is taken as fraction of iKeyBoardRepeatNextDelay.
+
+@param aNumeratorFracVal Numerator value of the fraction.
+@param aDenominatorFracVal Denominator value of the fraction.
+*/
+void CTEventTest::DelayForRepeatEvents(TInt aNumeratorFracVal, TInt aDenominatorFracVal)
+ {
+ if (!aNumeratorFracVal || !aDenominatorFracVal)
+ return;
+ User::After(iKeyBoardRepeatInitialDelay.Int() + (iKeyBoardRepeatNextDelay.Int()*aNumeratorFracVal/aDenominatorFracVal));
+ }
+
+#ifndef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA
+void CTEventTest::KeyEventTranslation_NextSetOfEventsL()
+ {
+ TTimeIntervalMicroSeconds32 initialTime;
+ TTimeIntervalMicroSeconds32 time;
+ TheClient->iWs.GetKeyboardRepeatRate(initialTime, time);
+
+ RWindowGroup* wg = iQueueClient->iGroup->GroupWin();
+
+ #if defined(LOGGING)
+ TLogMessageText logMessageText;
+ _LIT(KSet,"KeyEventTranslation SetOfEvents: %d of 5");
+ logMessageText.Format(KSet,iEventSet);
+ INFO_PRINTF1(logMessageText);
+ #endif
+
+ switch (iEventSet++)
+ {
+ case 0:
+ iQueueClient->iWs.Flush();
+ iTest->SimulateKeyDownUp('A');
+ AddExpectedEvent(EEventFocusGained);
+ AddExpectedKeyDownUp('A','a');
+ break;
+ case 1:
+ // Test key event translation using CaptureKey()
+ iCaptureKey = wg->CaptureKey(EKeyDevice0, 0, 0);
+ TEST(iCaptureKey >= 0);
+ iQueueClient->iWs.Flush();
+ iTest->SimulateKeyDownUp(EStdKeyDevice1);
+ TheClient->iWs.Flush();
+ AddExpectedKey(EEventKeyDown, EStdKeyDevice1, 0, 0);
+ AddExpectedKey(EEventKey, EStdKeyDevice1, EKeyDevice0, 0);
+ AddExpectedKey(EEventKeyUp, EStdKeyDevice1, 0, 0);
+ wg->CancelCaptureKey(iCaptureKey);
+ break;
+ case 2:
+ // Test key event translation using CaptureKeyUpAndDowns()
+ iCaptureKey = wg->CaptureKeyUpAndDowns(EStdKeyDevice0, 0, 0);
+ TEST(iCaptureKey >= 0);
+ iQueueClient->iWs.Flush();
+ iTest->SimulateKeyDownUp(EStdKeyDevice1);
+ TheClient->iWs.Flush();
+ AddExpectedKey(EEventKeyDown, EStdKeyDevice0, 0, 0);
+ AddExpectedKey(EEventKey, EStdKeyDevice1, EKeyDevice1, 0);
+ AddExpectedKey(EEventKeyUp, EStdKeyDevice0, 0, 0);
+ wg->CancelCaptureKeyUpAndDowns(iCaptureKey);
+ break;
+ case 3:
+ // Test key event translation using CaptureLongKey()
+ iCaptureKey = wg->CaptureLongKey(EKeyDevice0, EKeyDevice0, 0, 0, 0, ELongCaptureNormal);
+ TEST(iCaptureKey >= 0);
+ iQueueClient->iWs.Flush();
+
+ iTest->SimulateKey(TRawEvent::EKeyDown, EStdKeyDevice1);
+ TheClient->iWs.Flush();
+ User::After(initialTime.Int() + time.Int() / 3);
+ iTest->SimulateKey(TRawEvent::EKeyUp, EStdKeyDevice1);
+ TheClient->iWs.Flush();
+
+ AddExpectedKey(EEventKeyDown, EStdKeyDevice1, 0, 0);
+ AddExpectedKey(EEventKey, EStdKeyDevice1, EKeyDevice1, 0, EModifierAutorepeatable);
+ AddExpectedKey(EEventKey, EStdKeyDevice1, EKeyDevice0, 1, EModifierLongKey | EModifierAutorepeatable);
+ AddExpectedKey(EEventKeyUp, EStdKeyDevice1, 0, 0);
+
+ wg->CancelCaptureLongKey(iCaptureKey);
+ break;
+ case 4:
+ // Negative test: check that the capture key code listed in the
+ // translation table of the Key Routing Plug-in is not translated
+ // in the absence of any capture request for the mapped key.
+ iTest->SimulateKeyDownUp(EStdKeyDevice1);
+ TheClient->iWs.Flush();
+ AddExpectedKey(EEventKeyDown, EStdKeyDevice1, 0, 0);
+ AddExpectedKey(EEventKey, EStdKeyDevice1, EKeyDevice1, 0);
+ AddExpectedKey(EEventKeyUp, EStdKeyDevice1, 0, 0);
+ break;
+ default:
+ CActiveScheduler::Stop();
+ break;
+ }
+
+ TheClient->iWs.Flush();
+ }
+
+void CTEventTest::KeyEventBlocking_NextSetOfEventsL()
+ {
+ TTimeIntervalMicroSeconds32 initialTime;
+ TTimeIntervalMicroSeconds32 time;
+ TheClient->iWs.GetKeyboardRepeatRate(initialTime, time);
+
+ RWindowGroup* wg = iQueueClient->iGroup->GroupWin();
+
+ #if defined(LOGGING)
+ TLogMessageText logMessageText;
+ _LIT(KSet,"KeyEventBlocking SetOfEvents: %d of 5");
+ logMessageText.Format(KSet,iEventSet);
+ INFO_PRINTF1(logMessageText);
+ #endif
+
+ switch (iEventSet++)
+ {
+ case 0:
+ iQueueClient->iWs.Flush();
+ iTest->SimulateKeyDownUp('A');
+ AddExpectedEvent(EEventFocusGained);
+ AddExpectedKeyDownUp('A','a');
+ break;
+ case 1:
+ // Simulate pressing a blocked key (Device3) while no
+ // key capture is in effect.
+ iTest->SimulateKeyDownUp(EStdKeyDevice3);
+ iTest->SimulateKeyDownUp('B');
+ TheClient->iWs.Flush();
+ AddExpectedKeyDownUp('B','b');
+ break;
+ case 2:
+ // Use RWindowGroup::CaptureKey() to capture EKeyDevice3
+ // and simulate pressing the blocked key again.
+ iCaptureKey = wg->CaptureKey(EKeyDevice3, 0, 0);
+ TEST(iCaptureKey >= 0);
+ iQueueClient->iWs.Flush();
+ iTest->SimulateKeyDownUp(EStdKeyDevice3);
+ iTest->SimulateKeyDownUp('B');
+ TheClient->iWs.Flush();
+ AddExpectedKey(EEventKey, EStdKeyDevice3, EKeyDevice3, 0);
+ AddExpectedKeyDownUp('B','b');
+ wg->CancelCaptureKey(iCaptureKey);
+ break;
+ case 3:
+ // Repeat using CaptureKeyUpAndDowns()
+ iCaptureKey = wg->CaptureKeyUpAndDowns(EStdKeyDevice3, 0, 0);
+ TEST(iCaptureKey >= 0);
+ iQueueClient->iWs.Flush();
+ iTest->SimulateKeyDownUp(EStdKeyDevice3);
+ iTest->SimulateKeyDownUp('B');
+ TheClient->iWs.Flush();
+ AddExpectedKey(EEventKeyDown, EStdKeyDevice3, 0, 0);
+ AddExpectedKey(EEventKeyUp, EStdKeyDevice3, 0, 0);
+ AddExpectedKeyDownUp('B','b');
+ wg->CancelCaptureKeyUpAndDowns(iCaptureKey);
+ break;
+ case 4:
+ // Repeat using CaptureLongKey()
+ iCaptureKey = wg->CaptureLongKey(EKeyDevice3, EKeyDevice3, 0, 0, 0, ELongCaptureNormal);
+ TEST(iCaptureKey >= 0);
+ iQueueClient->iWs.Flush();
+ iTest->SimulateKey(TRawEvent::EKeyDown, EStdKeyDevice3);
+ TheClient->iWs.Flush();
+ User::After(initialTime.Int() + time.Int() / 3);
+ iTest->SimulateKey(TRawEvent::EKeyUp, EStdKeyDevice3);
+ iTest->SimulateKeyDownUp('B');
+ TheClient->iWs.Flush();
+ AddExpectedKey(EEventKey, EStdKeyDevice3, EKeyDevice3, 1, EModifierLongKey | EModifierAutorepeatable);
+ AddExpectedKeyDownUp('B','b');
+ wg->CancelCaptureLongKey(iCaptureKey);
+ break;
+ default:
+ CActiveScheduler::Stop();
+ break;
+ }
+
+ TheClient->iWs.Flush();
+ }
+
+void CTEventTest::KeyEventAppRestriction_NextSetOfEventsL()
+ {
+ TTimeIntervalMicroSeconds32 initialTime;
+ TTimeIntervalMicroSeconds32 time;
+ TheClient->iWs.GetKeyboardRepeatRate(initialTime, time);
+
+ RWindowGroup* wg = iQueueClient->iGroup->GroupWin();
+
+ #if defined(LOGGING)
+ TLogMessageText logMessageText;
+ _LIT(KSet,"KeyEventAppRestriction SetOfEvents: %d of 4");
+ logMessageText.Format(KSet,iEventSet);
+ INFO_PRINTF1(logMessageText);
+ #endif
+
+ switch (iEventSet++)
+ {
+ case 0:
+ // Make window group non-focusable so that it receives only
+ // keys that are captured and not those that are default-routed.
+ wg->EnableReceiptOfFocus(EFalse);
+ iQueueClient->iWs.Flush();
+ AddExpectedEvent(EEventFocusGained);
+ AddExpectedEvent(EEventFocusLost);
+ break;
+ case 1:
+ // Using RWindowGroup::CaptureKey(), attempt to capture a key
+ // that is restricted by UID to another application.
+ iCaptureKey = wg->CaptureKey(EKeyF20, 0, 0);
+ TEST(iCaptureKey == KErrPermissionDenied);
+ // Now capture a key that is restricted to the current
+ // application's UID and simulate pressing the restricted key.
+ iCaptureKey = wg->CaptureKey(EKeyF21, 0, 0);
+ TEST(iCaptureKey >= 0);
+ iQueueClient->iWs.Flush();
+ // Can't use SimulateKeyDownUp() here due to its check that scan
+ // codes are not in the range corresponding to lower case letters
+ iTest->SimulateKey(TRawEvent::EKeyDown, EStdKeyF21);
+ iTest->SimulateKey(TRawEvent::EKeyUp, EStdKeyF21);
+ TheClient->iWs.Flush();
+ AddExpectedKey(EEventKey, EStdKeyF21, EKeyF21, 0);
+ wg->CancelCaptureKey(iCaptureKey);
+ break;
+ case 2:
+ // Repeat using CaptureKeyUpAndDowns()
+ iCaptureKey = wg->CaptureKeyUpAndDowns(EStdKeyF20, 0, 0);
+ TEST(iCaptureKey == KErrPermissionDenied);
+ iCaptureKey = wg->CaptureKeyUpAndDowns(EStdKeyF21, 0, 0);
+ TEST(iCaptureKey >= 0);
+ iQueueClient->iWs.Flush();
+ iTest->SimulateKey(TRawEvent::EKeyDown, EStdKeyF21);
+ iTest->SimulateKey(TRawEvent::EKeyUp, EStdKeyF21);
+ TheClient->iWs.Flush();
+ AddExpectedKey(EEventKeyDown, EStdKeyF21, 0, 0);
+ AddExpectedKey(EEventKeyUp, EStdKeyF21, 0, 0);
+ wg->CancelCaptureKeyUpAndDowns(iCaptureKey);
+ break;
+ case 3:
+ // Repeat using CaptureLongKey()
+ iCaptureKey = wg->CaptureLongKey(EKeyF20, EKeyF20, 0, 0, 0, ELongCaptureNormal);
+ TEST(iCaptureKey == KErrPermissionDenied);
+ iCaptureKey = wg->CaptureLongKey(EKeyF21, EKeyF21, 0, 0, 0, ELongCaptureNormal);
+ TEST(iCaptureKey >= 0);
+ iQueueClient->iWs.Flush();
+ iTest->SimulateKey(TRawEvent::EKeyDown, EStdKeyF21);
+ TheClient->iWs.Flush();
+ User::After(initialTime.Int() + time.Int() / 3);
+ iTest->SimulateKey(TRawEvent::EKeyUp, EStdKeyF21);
+ TheClient->iWs.Flush();
+ AddExpectedKey(EEventKey, EStdKeyF21, EKeyF21, 1, EModifierLongKey | EModifierAutorepeatable);
+ wg->CancelCaptureLongKey(iCaptureKey);
+ break;
+ default:
+ CActiveScheduler::Stop();
+ break;
+ }
+
+ TheClient->iWs.Flush();
+ }
+
+void CTEventTest::KeyEventAppPriority_NextSetOfEventsL()
+ {
+ TTimeIntervalMicroSeconds32 initialTime;
+ TTimeIntervalMicroSeconds32 time;
+ TheClient->iWs.GetKeyboardRepeatRate(initialTime, time);
+
+ RWindowGroup* wg = iQueueClient->iGroup->GroupWin();
+ TInt handle1 = 0;
+ TInt handle2 = 0;
+ TInt handle3 = 0;
+ TInt handle4 = 0;
+ TInt handle5 = 0;
+ TInt handle6 = 0;
+
+ #if defined(LOGGING)
+ TLogMessageText logMessageText;
+ _LIT(KSet,"KeyEventAppPriority SetOfEvents: %d of 5");
+ logMessageText.Format(KSet,iEventSet);
+ INFO_PRINTF1(logMessageText);
+ #endif
+
+ switch (iEventSet++)
+ {
+ case 0:
+ SpawnCaptureAppL(iCaptureApp1);
+ iQueueClient->iWs.Flush();
+ AddExpectedEvent(EEventFocusGained);
+ AddExpectedEvent(EEventFocusLost);
+ break;
+ case 1:
+ // Use RWindowGroup::CaptureKey() to capture EKeyF22
+ // and EKeyF23 with priority 0. Simulate pressing both
+ // keys. Since the current application has precedence by UID
+ // for capture of EKeyF22, it should receive that key
+ // but should not receive EKeyF23.
+ handle1 = wg->CaptureKey(EKeyF22, 0, 0);
+ handle2 = wg->CaptureKey(EKeyF23, 0, 0);
+ TEST(handle1 >= 0);
+ TEST(handle2 >= 0);
+ iQueueClient->iWs.Flush();
+ iTest->SimulateKey(TRawEvent::EKeyDown, EStdKeyF22);
+ iTest->SimulateKey(TRawEvent::EKeyUp, EStdKeyF22);
+ iTest->SimulateKey(TRawEvent::EKeyDown, EStdKeyF23);
+ iTest->SimulateKey(TRawEvent::EKeyUp, EStdKeyF23);
+ TheClient->iWs.Flush();
+ AddExpectedKey(EEventKey, EStdKeyF22, EKeyF22, 0);
+ wg->CancelCaptureKey(handle1);
+ wg->CancelCaptureKey(handle2);
+ break;
+ case 2:
+ // Repeat using CaptureKeyUpAndDowns()
+ handle1 = wg->CaptureKeyUpAndDowns(EStdKeyF22, 0, 0);
+ handle2 = wg->CaptureKeyUpAndDowns(EStdKeyF23, 0, 0);
+ TEST(handle1 >= 0);
+ TEST(handle2 >= 0);
+ iQueueClient->iWs.Flush();
+ iTest->SimulateKey(TRawEvent::EKeyDown, EStdKeyF22);
+ iTest->SimulateKey(TRawEvent::EKeyUp, EStdKeyF22);
+ iTest->SimulateKey(TRawEvent::EKeyDown, EStdKeyF23);
+ iTest->SimulateKey(TRawEvent::EKeyUp, EStdKeyF23);
+ TheClient->iWs.Flush();
+ AddExpectedKey(EEventKeyDown, EStdKeyF22, 0, 0);
+ AddExpectedKey(EEventKeyUp, EStdKeyF22, 0, 0);
+ wg->CancelCaptureKeyUpAndDowns(handle1);
+ wg->CancelCaptureKeyUpAndDowns(handle2);
+ break;
+ case 3:
+ // Repeat using CaptureLongKey()
+ handle1 = wg->CaptureLongKey(EKeyF22, EKeyF22, 0, 0, 0, ELongCaptureNormal);
+ handle2 = wg->CaptureLongKey(EKeyF23, EKeyF23, 0, 0, 0, ELongCaptureNormal);
+ TEST(handle1 >= 0);
+ TEST(handle2 >= 0);
+ iQueueClient->iWs.Flush();
+
+ iTest->SimulateKey(TRawEvent::EKeyDown, EStdKeyF22);
+ TheClient->iWs.Flush();
+ User::After(initialTime.Int() + time.Int() / 3);
+ iTest->SimulateKey(TRawEvent::EKeyUp, EStdKeyF22);
+
+ iTest->SimulateKey(TRawEvent::EKeyDown, EStdKeyF23);
+ TheClient->iWs.Flush();
+ User::After(initialTime.Int() + time.Int() / 3);
+ iTest->SimulateKey(TRawEvent::EKeyUp, EStdKeyF23);
+ TheClient->iWs.Flush();
+
+ AddExpectedKey(EEventKey, EStdKeyF22, EKeyF22, 1, EModifierLongKey | EModifierAutorepeatable);
+ wg->CancelCaptureLongKey(handle1);
+ wg->CancelCaptureLongKey(handle2);
+ break;
+ case 4:
+ // Repeat with additional capture requests for improved code
+ // coverage. (Also verifies that UID-based precedence works even
+ // when another app makes the most recent capture request.)
+ // Spawn a second capture app so that requests occur in the
+ // following order:
+ // 1. CaptureApp1, priority 1 (outstanding)
+ // 2. Current App, priority 0, precedence by UID
+ // 3. CaptureApp2, priority 1
+ // Note that all three capture types are tested together here.
+ handle1 = wg->CaptureKey(EKeyF22, 0, 0);
+ handle2 = wg->CaptureKey(EKeyF23, 0, 0);
+ handle3 = wg->CaptureKeyUpAndDowns(EStdKeyF22, 0, 0);
+ handle4 = wg->CaptureKeyUpAndDowns(EStdKeyF23, 0, 0);
+ handle5 = wg->CaptureLongKey(EKeyF22, EKeyF22, 0, 0, 0, ELongCaptureNormal);
+ handle6 = wg->CaptureLongKey(EKeyF23, EKeyF23, 0, 0, 0, ELongCaptureNormal);
+ TEST(handle1 >= 0);
+ TEST(handle2 >= 0);
+ TEST(handle3 >= 0);
+ TEST(handle4 >= 0);
+ TEST(handle5 >= 0);
+ TEST(handle6 >= 0);
+ iQueueClient->iWs.Flush();
+
+ SpawnCaptureAppL(iCaptureApp2);
+
+ iTest->SimulateKey(TRawEvent::EKeyDown, EStdKeyF22);
+ TheClient->iWs.Flush();
+ User::After(initialTime.Int() + time.Int() / 3);
+ iTest->SimulateKey(TRawEvent::EKeyUp, EStdKeyF22);
+
+ iTest->SimulateKey(TRawEvent::EKeyDown, EStdKeyF23);
+ TheClient->iWs.Flush();
+ User::After(initialTime.Int() + time.Int() / 3);
+ iTest->SimulateKey(TRawEvent::EKeyUp, EStdKeyF23);
+ TheClient->iWs.Flush();
+
+ AddExpectedKey(EEventKeyDown, EStdKeyF22, 0, 0);
+ AddExpectedKey(EEventKey, EStdKeyF22, EKeyF22, 0);
+ AddExpectedKey(EEventKey, EStdKeyF22, EKeyF22, 1, EModifierLongKey | EModifierAutorepeatable);
+ AddExpectedKey(EEventKeyUp, EStdKeyF22, 0, 0);
+ wg->CancelCaptureKey(handle1);
+ wg->CancelCaptureKey(handle2);
+ wg->CancelCaptureKeyUpAndDowns(handle3);
+ wg->CancelCaptureKeyUpAndDowns(handle4);
+ wg->CancelCaptureLongKey(handle5);
+ wg->CancelCaptureLongKey(handle6);
+ break;
+ default:
+ iCaptureApp1.Kill(KErrNone);
+ iCaptureApp2.Kill(KErrNone);
+ iCaptureApp1.Close();
+ iCaptureApp2.Close();
+ CActiveScheduler::Stop();
+ break;
+ }
+
+ TheClient->iWs.Flush();
+ }
+
+/**
+Spawn another application that will capture the keys EKeyF22 and
+EKeyF23 with high priority.
+
+@param aProcess Process to create
+*/
+void CTEventTest::SpawnCaptureAppL(RProcess& aProcess)
+ {
+ _LIT(KCaptureApp, "tevent_captureapp.exe");
+ TInt error = aProcess.Create(KCaptureApp, KNullDesC);
+ if (error != KErrNone)
+ {
+#if defined(LOGGING)
+ TLogMessageText logMessageText;
+ _LIT(KLog, "Cannot create capture app - error %d");
+ logMessageText.Format(KLog, error);
+ INFO_PRINTF1(logMessageText);
+#endif
+ User::Leave(error);
+ }
+
+ // Make rendezvous request to capture app
+ TRequestStatus status;
+ aProcess.Rendezvous(status);
+ aProcess.Resume();
+
+ // Wait for capture app to make its capture requests
+ User::WaitForRequest(status);
+ TEST(status.Int() == KErrNone);
+ }
+#endif // TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA
+
#define PASSWORD_START_OF_DAY 4
void CTEventTest::Password_NextSetOfEvents()
{
@@ -6316,15 +6985,19 @@
_LIT(KTest25,"Mismatched Pointer Events");
_LIT(KTest26,"Pointer Buffer Purge");
_LIT(KTest27,"TRawEvent test for Repeats");
+#ifndef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA
+ _LIT(KTest28,"Translation of key events by routing plug-in");
+ _LIT(KTest29,"Blocking of key events by routing plug-in");
+ _LIT(KTest30,"App UID based restriction of key capture");
+ _LIT(KTest31,"App UID based routing of key events");
#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
-#ifndef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA
- _LIT(KTest28,"Transparent Surface Visibility Changed Events 1");
- _LIT(KTest29,"Transparent Surface Visibility Changed Events 2");
- _LIT(KTest30,"Transparent Surface Visibility Changed Events 3");
+ _LIT(KTest32,"Transparent Surface Visibility Changed Events 1");
+ _LIT(KTest33,"Transparent Surface Visibility Changed Events 2");
+ _LIT(KTest34,"Transparent Surface Visibility Changed Events 3");
+#endif // SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
#endif // TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA
-#endif // SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
- _LIT(KTest31A,"Initialize Queue Size without inactive queue");
- _LIT(KTest31B,"Initialize Queue Size with inactive queue");
+ _LIT(KTest35A,"Initialize Queue Size without inactive queue");
+ _LIT(KTest35B,"Initialize Queue Size with inactive queue");
if (!TestBase()->ConfigurationSupportsPointerEventTesting())
{
@@ -6644,15 +7317,16 @@
@SYMDEF DEF081259
-@SYMTestCaseDesc Send events for capturing large areas of text
+@SYMTestCaseDesc Test RWindowGroup::CaptureLongKey()
@SYMTestPriority High
@SYMTestStatus Implemented
-@SYMTestActions Send events for capturing large areas of text
-
-@SYMTestExpectedResults The events are sent to the window without
+@SYMTestActions Simulate long key presses and check that long key capture
+ and key repeat work as expected.
+
+@SYMTestExpectedResults The correct key events are sent to the window without
error
*/
case 15:
@@ -6925,8 +7599,118 @@
RunTestsL();
break;
+#ifndef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA
+/**
+@SYMTestCaseID GRAPHICS-WSERV-0751, GRAPHICS-WSERV-0752, GRAPHICS-WSERV-0753
+@SYMPREQ 417-61800
+@SYMTestCaseDesc Test translation of key events by Key Event Routing plug-in
+@SYMTestPriority High
+@SYMTestStatus Implemented
+@SYMTestActions Use RWindowGroup::CaptureKey() to capture pseudo key
+ Device0 (key code EKeyDevice0, scan code EStdKeyDevice0).
+ Simulate pressing key Device1.
+ Repeat using CaptureKeyUpAndDowns().
+ Repeat using CaptureLongKey().
+ Repeat without any capture requests.
+@SYMTestExpectedResults
+ The key event delivered contains the key or scan code for
+ Device0, if captured. When using CaptureKey() and
+ CaptureLongKey(), only the key code is translated. Using
+ CaptureKeyUpAndDowns(), only the scan code is translated.
+
+Note: this test requires an entry in the translation table of the Key Routing
+Plug-in to map Device0 to Device1 at capture request time.
+*/
+ case 28:
+ ((CTEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0751"));
+ iTest->LogSubTest(KTest28);
+ RunTestsL();
+ break;
+
+/**
+@SYMTestCaseID GRAPHICS-WSERV-0760, GRAPHICS-WSERV-0761, GRAPHICS-WSERV-0762
+@SYMPREQ 417-61800
+@SYMTestCaseDesc Test blocking of key events by Key Event Routing plug-in
+@SYMTestPriority High
+@SYMTestStatus Implemented
+@SYMTestActions Simulate pressing a blocked key (Device3) while no
+ key capture is in effect.
+ Use RWindowGroup::CaptureKey() to capture EKeyDevice3
+ and simulate pressing the blocked key again.
+ Repeat using CaptureKeyUpAndDowns().
+ Repeat using CaptureLongKey().
+@SYMTestExpectedResults
+ The blocked key event is only delivered when captured and
+ is not routed to the focussed window group by default.
+
+Note: this test requires entries in the Blocked Key Table of the Reference
+Key Routing Plug-in for EKeyDevice3 and EStdKeyDevice3.
+*/
+ case 29:
+ ((CTEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0760"));
+ iTest->LogSubTest(KTest29);
+ RunTestsL();
+ break;
+
+/**
+@SYMTestCaseID GRAPHICS-WSERV-0754, GRAPHICS-WSERV-0755, GRAPHICS-WSERV-0756
+@SYMPREQ 417-61800
+@SYMTestCaseDesc Test application UID-based restriction of key capture by
+ Key Event Routing plug-in.
+@SYMTestPriority High
+@SYMTestStatus Implemented
+@SYMTestActions Attempt to capture a key that is restricted by UID
+ to another application.
+ Use RWindowGroup::CaptureKey() to capture a key that is
+ restricted to the current application's UID.
+ Simulate pressing the second key.
+ Repeat using CaptureKeyUpAndDowns().
+ Repeat using CaptureLongKey().
+@SYMTestExpectedResults
+ Capture of the first key fails with KErrPermissionDenied.
+ Capture of the second key succeeds and the key event is
+ delivered.
+
+Note: this test requires entries in the Restricted Key Table of the Reference
+Key Routing Plug-in for the chosen keys.
+*/
+ case 30:
+ ((CTEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0754"));
+ iTest->LogSubTest(KTest30);
+ RunTestsL();
+ break;
+
+/**
+@SYMTestCaseID GRAPHICS-WSERV-0757, GRAPHICS-WSERV-0758, GRAPHICS-WSERV-0759
+@SYMPREQ 417-61800
+@SYMTestCaseDesc Test application UID-based routing of key events by
+ Key Event Routing plug-in.
+@SYMTestPriority High
+@SYMTestStatus Implemented
+@SYMTestActions Invoke another application to capture two different keys
+ with high priority using each of RWindowGroup::CaptureKey(),
+ CaptureKeyUpAndDowns() and CaptureLongKey(). One key of
+ each pair has precedence for capture by the current
+ application's UID (i.e. this test).
+ In the current application, use RWindowGroup::CaptureKey()
+ to capture both keys with lower priority.
+ Simulate pressing the keys.
+ Repeat using CaptureKeyUpAndDowns().
+ Repeat using CaptureLongKey().
+@SYMTestExpectedResults
+ The key event with UID-based precedence is delivered to
+ the current application but the other key is not.
+
+Note: this test requires entries in the Priority Application Table of the
+Reference Key Routing Plug-in for the chosen key.
+*/
+ case 31:
+ ((CTEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0757"));
+ iTest->LogSubTest(KTest31);
+ RunTestsL();
+ break;
+
#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
-#ifndef TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA
/**
@SYMTestCaseID GRAPHICS-WSERV-2669-0015
@SYMREQ REQ13202: Possibility for external layers to appear above UI layer
@@ -6938,9 +7722,9 @@
@SYMTestActions Call SetSurfaceTransparency(ETrue) on win2
@SYMTestExpectedResults Win1 receives visibility event
*/
- case 28:
+ case 32:
((CTEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-2669-0015"));
- iTest->LogSubTest(KTest28);
+ iTest->LogSubTest(KTest32);
RunTestsL();
break;
/**
@@ -6955,9 +7739,9 @@
@SYMTestActions Delete win3
@SYMTestExpectedResults Both win1 and win2 receive visibility events
*/
- case 29:
+ case 33:
((CTEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-2669-0016"));
- iTest->LogSubTest(KTest29);
+ iTest->LogSubTest(KTest33);
RunTestsL();
break;
/**
@@ -6971,13 +7755,13 @@
@SYMTestActions Move win2 to overlap win1
@SYMTestExpectedResults No visibility event is received (win1 is still fully visible)
*/
- case 30:
+ case 34:
((CTEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-2669-0017"));
- iTest->LogSubTest(KTest30);
+ iTest->LogSubTest(KTest34);
RunTestsL();
break;
+#endif // SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
#endif // TEST_GRAPHICS_WSERV_TAUTOSERVER_NONNGA
-#endif // SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
/**
@SYMTestCaseID GRAPHICS-WSERV-0559
@@ -6994,17 +7778,17 @@
case 28:
#else
#ifdef SYMBIAN_GRAPHICS_WSERV_QT_EFFECTS
- case 31:
+ case 35:
#else
- case 28:
+ case 32:
#endif
#endif
// This test was moved to be the last test in the test suite, because it sometimes leaves events in the event queue,
//it can affect the results of other tests. This test case should be the last test in the test suite.
((CTEventTestStep*)iStep)->SetTestStepID(_L("GRAPHICS-WSERV-0484"));
- iTest->LogSubTest(KTest31A);
+ iTest->LogSubTest(KTest35A);
InitializeQueueSizeTestL(EFalse);
- iTest->LogSubTest(KTest31B);
+ iTest->LogSubTest(KTest35B);
InitializeQueueSizeTestL(ETrue);
break;
--- a/windowing/windowserver/test/tauto/TOOM.CPP Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/test/tauto/TOOM.CPP Fri Sep 24 16:44:34 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1996-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -66,6 +66,9 @@
COomFailBase *CreateOomCaptureKeyUpDown(CTOom *aTest)
{return(new(ELeave) COomCaptureKeyUpDown(aTest));}
+COomFailBase *CreateOomLongKeyCapture(CTOom *aTest)
+ {return(new(ELeave) COomLongKeyCapture(aTest));}
+
COomFailBase *CreateOomHotKey(CTOom *aTest)
{return(new(ELeave) COomHotKey(aTest));}
@@ -113,6 +116,7 @@
CreateOomPriorityKey,
CreateOomCaptureKey,
CreateOomCaptureKeyUpDown,
+ CreateOomLongKeyCapture,
CreateOomHotKey,
CreateOomGroupName,
CreateOomSprite,
@@ -421,7 +425,18 @@
//
-COomCaptureKey::COomCaptureKey(CTOom *aTest) : COomSetup(aTest)
+COomCaptureKeyBase::COomCaptureKeyBase(CTOom *aTest) : COomSetup(aTest)
+ {}
+
+COomCaptureKeyBase::~COomCaptureKeyBase()
+ {}
+
+void COomCaptureKeyBase::ConstructL()
+ {
+ COomSetup::ConstructL();
+ }
+
+COomCaptureKey::COomCaptureKey(CTOom *aTest) : COomCaptureKeyBase(aTest)
{}
COomCaptureKey::~COomCaptureKey()
@@ -433,11 +448,6 @@
return(_L("Capture key"));
}
-void COomCaptureKey::ConstructL()
- {
- COomSetup::ConstructL();
- }
-
/** Requests a capture keys for a previously created window group
*/
TInt COomCaptureKey::Fail()
@@ -460,7 +470,7 @@
//
-COomCaptureKeyUpDown::COomCaptureKeyUpDown(CTOom *aTest) : COomSetup(aTest)
+COomCaptureKeyUpDown::COomCaptureKeyUpDown(CTOom *aTest) : COomCaptureKeyBase(aTest)
{}
COomCaptureKeyUpDown::~COomCaptureKeyUpDown()
@@ -472,11 +482,6 @@
return(_L("Capture up/down keys"));
}
-void COomCaptureKeyUpDown::ConstructL()
- {
- COomSetup::ConstructL();
- }
-
/** Requests the capture of key-up and key-down events for a previously created window group
*/
TInt COomCaptureKeyUpDown::Fail()
@@ -499,6 +504,42 @@
//
+COomLongKeyCapture::COomLongKeyCapture(CTOom *aTest) : COomCaptureKeyBase(aTest)
+ {}
+
+COomLongKeyCapture::~COomLongKeyCapture()
+ {
+ }
+
+TOomTestName COomLongKeyCapture::TestName()
+ {
+ _LIT(KLongKeyCapTestName, "Long key capture");
+ return KLongKeyCapTestName();
+ }
+
+/**
+Requests capture of long key events for a previously created window group
+*/
+TInt COomLongKeyCapture::Fail()
+ {
+ for (iIndex=0; iIndex < KNumCapKeyRequest; iIndex++)
+ {
+ TInt ret=iWinGroup.CaptureLongKey(' ','a',0,0,2,ELongCaptureNormal);
+ if (ret<0)
+ return(ret);
+ iCapKey[iIndex]=ret;
+ }
+ return(KErrNone);
+ }
+
+void COomLongKeyCapture::ClearUpL()
+ {
+ for (TInt index=0;index<iIndex;index++)
+ iWinGroup.CancelCaptureLongKey(iCapKey[index]);
+ }
+
+//
+
COomHotKey::COomHotKey(CTOom *aTest) : COomSetup(aTest)
{}
--- a/windowing/windowserver/test/tauto/TOOM.H Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/test/tauto/TOOM.H Fri Sep 24 16:44:34 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 1996-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -33,6 +33,8 @@
class CTOom;
+const TInt KNumCapKeyRequest = 20;
+
class COomFailBase : public CBase
{
@@ -192,32 +194,45 @@
TOomTestName TestName();
};
-class COomCaptureKey : public COomSetup
+class COomCaptureKeyBase : public COomSetup
+ {
+public:
+ COomCaptureKeyBase(CTOom *aTest);
+ ~COomCaptureKeyBase();
+ void ConstructL();
+protected:
+ TInt32 iCapKey[KNumCapKeyRequest];
+ TInt iIndex;
+ };
+
+class COomCaptureKey : public COomCaptureKeyBase
{
public:
COomCaptureKey(CTOom *aTest);
~COomCaptureKey();
- void ConstructL();
void ClearUpL();
TInt Fail();
TOomTestName TestName();
-private:
- TInt32 iCapKey[20];
- TInt iIndex;
};
-class COomCaptureKeyUpDown : public COomSetup
+class COomCaptureKeyUpDown : public COomCaptureKeyBase
{
public:
COomCaptureKeyUpDown(CTOom *aTest);
~COomCaptureKeyUpDown();
- void ConstructL();
void ClearUpL();
TInt Fail();
TOomTestName TestName();
-private:
- TInt32 iCapKey[20];
- TInt iIndex;
+ };
+
+class COomLongKeyCapture : public COomCaptureKeyBase
+ {
+public:
+ COomLongKeyCapture(CTOom *aTest);
+ ~COomLongKeyCapture();
+ void ClearUpL();
+ TInt Fail();
+ TOomTestName TestName();
};
class COomHotKey : public COomSetup
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserver/test/tauto/tdevicerotation.cpp Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,823 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Set of tests for Tracing Device Rotation. These tests generally test
+// RWsSession::IndicateAppOrientation(...).
+//
+
+/**
+ @file
+ @test
+ @internalComponent - Internal Nokia test code
+*/
+
+#include "tdevicerotation.h"
+#include "themeserverpropertydefine.h"
+#include "..\..\nga\server\renderorientationtracker.h"
+#include <hal.h>
+#include <hal_data.h>
+#include <w32std.h>
+
+const TInt KPublishTimeout = 1000000; // 1 second in microseconds
+
+//
+// CTDeviceRotation Definition
+//
+
+CTDeviceRotation::CTDeviceRotation(CTestStep* aStep):
+ CTGraphicsBase(aStep), iWaitForPublishOnNextTest(ETrue)
+ {
+ }
+
+CTDeviceRotation::~CTDeviceRotation()
+ {
+ iPublishTimer.Close();
+
+ iChildWindow.Close();
+ iWindowGroup.Close();
+ iWs.Close();
+
+ iSecondChildWindow.Close();
+ iSecondWindowGroup.Close();
+ iSecondWs.Close();
+
+ /* This Process called with the argument KThemeServerPropertyDefineCmdDelete, deletes
+ the theme server RProperty. This is because an RProperty can only be defined and
+ deleted from within a process with the same UID3 as the RProperty catogory you are
+ trying to define/delete.*/
+ RProcess themeServerPropertyDefine;
+ TInt err = themeServerPropertyDefine.Create(KThemeServerPropertyDefine,
+ KThemeServerPropertyDefineCmdDelete);
+ if (KErrNone != err)
+ {
+ _LIT(KLog, "themeServerPropertyDefine.Create() failed with error: %d");
+ INFO_PRINTF2(KLog, err);
+ TEST(EFalse);
+ }
+ //wait for themeServerPropertyDefine process to terminate
+ TRequestStatus themeServerPropertyDefineLogonStatus;
+ themeServerPropertyDefine.Logon(themeServerPropertyDefineLogonStatus);
+ themeServerPropertyDefine.Resume();
+ User::WaitForRequest(themeServerPropertyDefineLogonStatus);
+ if (themeServerPropertyDefineLogonStatus != KErrNone)
+ {
+ _LIT(KLog, "themeServerPropertyDefine.Logon() failed with error: %d");
+ INFO_PRINTF2(KLog, themeServerPropertyDefineLogonStatus);
+ TEST(EFalse);
+ }
+ themeServerPropertyDefine.Close();
+
+ iRenderOrientationProperty.Delete(KRenderOrientationCategory, KRenderOrientationKey);
+ iRenderOrientationProperty.Close();
+ iThemeServerOrientationProperty.Close();
+ }
+
+void CTDeviceRotation::ConstructL()
+ {
+ TInt err = iWs.Connect();
+ TESTL(err == KErrNone);
+
+ err = iSecondWs.Connect();
+ TESTL(KErrNone == err);
+
+ iWs.SetAutoFlush(ETrue);
+ iSecondWs.SetAutoFlush(ETrue);
+
+ iWindowGroup = RWindowGroup(iWs);
+ err = iWindowGroup.Construct(iWs.Handle());
+ TESTL(KErrNone == err);
+ iWindowGroup.SetOrdinalPosition(0,1);
+
+ iChildWindow = RWindow(iWs);
+ err = iChildWindow.Construct(iWindowGroup, reinterpret_cast<TUint32>(&iChildWindow));
+ TESTL(KErrNone == err);
+
+ iSecondWindowGroup = RWindowGroup(iSecondWs);
+ err = iSecondWindowGroup.Construct(iSecondWs.Handle());
+ TESTL(KErrNone == err);
+ iSecondWindowGroup.SetOrdinalPosition(1,1);
+
+ iSecondChildWindow = RWindow(iSecondWs);
+ err = iSecondChildWindow.Construct(iSecondWindowGroup, reinterpret_cast<TUint32>(&iSecondChildWindow));
+ TESTL(KErrNone == err);
+
+ err= iRenderOrientationProperty.Attach(KRenderOrientationCategory, KRenderOrientationKey, EOwnerThread);
+ TESTL(KErrNone == err);
+ iRenderOrientationProperty.Subscribe(iRenderOrientationStatus);
+
+ /* This Process called with the argument KThemeServerPropertyDefineCmdDefine, defines
+ the theme server catagory to be the same as the theme servers process ID. This is
+ because an RProperty can only be defined and deleted from within a process with the
+ same UID3 as the RProperty catogory you are trying to define/delete.*/
+ RProcess themeServerPropertyDefine;
+ err = themeServerPropertyDefine.Create(KThemeServerPropertyDefine,KThemeServerPropertyDefineCmdDefine);
+ TESTL(KErrNone == err);
+ TRequestStatus themeServerPropertyDefineLogonStatus;
+ themeServerPropertyDefine.Logon(themeServerPropertyDefineLogonStatus);
+ themeServerPropertyDefine.Resume();
+ User::WaitForRequest(themeServerPropertyDefineLogonStatus);
+ TESTL(KErrNone == themeServerPropertyDefineLogonStatus.Int());
+ themeServerPropertyDefine.Close();
+
+ err = iThemeServerOrientationProperty.Attach(KThemeOrientationCategory, KThemeOrientationKey, EOwnerThread);
+ TESTL(KErrNone == err);
+
+ SimulateThemeServerOrientation(EDisplayOrientationNormal);
+
+ iPublishTimer.CreateLocal();
+ }
+
+void CTDeviceRotation::SimulateThemeServerOrientation(TRenderOrientation aOrientation)
+ {
+ _LIT(KFunctionInfo, "SimulateThemeServerOrientation(aOrientation = %d)");
+ INFO_PRINTF2(KFunctionInfo, aOrientation);
+ TInt err = iThemeServerOrientationProperty.Set(aOrientation);
+ if (KErrNone != err)
+ {
+ _LIT(KLog,"iThemeServerOrientationProperty.Set(%d) failed with err %d");
+ INFO_PRINTF3(KLog,aOrientation,err);
+ TEST(EFalse);
+ }
+ switch(aOrientation)
+ {
+ case EDisplayOrientationNormal:
+ case EDisplayOrientation90CW:
+ case EDisplayOrientation180:
+ case EDisplayOrientation270CW:
+ {
+ if(KErrNone == err)
+ {
+ iCurrentThemeServerOrientation = aOrientation;
+ }
+ break;
+ }
+ default:
+ _LIT(KLog, "This orientation is not supported by theme server.");
+ INFO_PRINTF1(KLog);
+ }
+ }
+
+void CTDeviceRotation::IsOrientationCorrect(TRenderOrientation aExpectedOrientation)
+ {
+ // timer to timeout when nothing is published
+ iPublishTimer.After(iPublishTimerStatus, KPublishTimeout);
+
+ // wait for either
+ User::WaitForRequest(iRenderOrientationStatus, iPublishTimerStatus);
+
+ // check that the orientation was published or not, as expected
+ if(iWaitForPublishOnNextTest)
+ {
+ // Check that it really has published
+ if(iRenderOrientationStatus.Int()==KErrNone && iPublishTimerStatus.Int()==KRequestPending)
+ {
+ iPublishTimer.Cancel();
+ // re-subscribe
+ iRenderOrientationProperty.Subscribe(iRenderOrientationStatus);
+ }
+ else
+ {
+ _LIT(KLog,"Timed out (%d) while waiting for render orientation %d to be published");
+ INFO_PRINTF3(KLog,iRenderOrientationStatus.Int(),aExpectedOrientation);
+ TEST(EFalse);
+ }
+ }
+ else
+ {
+ // Check that it really hasn't published
+ if(iRenderOrientationStatus.Int()!=KRequestPending)
+ {
+ _LIT(KLog,"Render Orientation %d was published (%d) when not expected (timeout = %d)");
+ INFO_PRINTF4(KLog,aExpectedOrientation, iRenderOrientationStatus.Int(),iPublishTimerStatus.Int());
+ iPublishTimer.Cancel();
+ TEST(EFalse);
+ }
+ else if(iPublishTimerStatus.Int()!=KErrNone)
+ {
+ _LIT(KLog,"Timeout failure %d");
+ INFO_PRINTF2(KLog,iPublishTimerStatus.Int());
+ TEST(EFalse);
+ }
+
+ // reset to default
+ iWaitForPublishOnNextTest = ETrue;
+ }
+
+ // Retrieve the value.
+ TInt orientation;
+ TInt err = iRenderOrientationProperty.Get(orientation);
+ if(KErrNone != err)
+ {
+ _LIT(KLog,"iThemeServerOrientationProperty.Get(...) failed with err %d");
+ INFO_PRINTF2(KLog,err);
+ TEST(EFalse);
+ }
+ else if(aExpectedOrientation == EDisplayOrientationAuto)
+ {
+ TEST(orientation == iCurrentThemeServerOrientation);
+ CheckHalSetting(iCurrentThemeServerOrientation);
+ }
+ else
+ {
+ TEST(orientation == aExpectedOrientation);
+ CheckHalSetting(static_cast<TRenderOrientation>(orientation));
+ }
+ }
+
+void CTDeviceRotation::CheckHalSetting(TRenderOrientation aOrientation)
+ {
+ HALData::TDigitiserOrientation halOrientationExp = static_cast<HALData::TDigitiserOrientation>
+ (HALData::EDigitiserOrientation_000 + (aOrientation - EDisplayOrientationNormal));
+ TInt halOrientation;
+ TInt err = HAL::Get(iWs.GetFocusScreen(), HALData::EDigitiserOrientation, halOrientation);
+ if (err != KErrNotSupported)
+ {
+ if (err != KErrNone)
+ {
+ _LIT(KLog,"Getting HAL orientation attribute returned error %d when no error expected");
+ INFO_PRINTF2(KLog,err);
+ }
+ TEST(err==KErrNone);
+ if (halOrientationExp != halOrientation)
+ {
+ _LIT(KLog,"HAL orientation is %d when expected to be %d");
+ INFO_PRINTF3(KLog, halOrientation, halOrientationExp);
+ }
+ TEST(halOrientationExp==halOrientation);
+ }
+ else
+ {
+ _LIT(KLog,"HAL-Orientation HALData::EDigitiserOrientation isn't supported by Driver");
+ INFO_PRINTF1(KLog);
+ }
+ }
+
+void CTDeviceRotation::TestIndicateAppOrientation(TRenderOrientation aOrientation)
+ {
+ _LIT(KTestInfo, "TestIndicateAppOrientation(aOrientation = %d)");
+ INFO_PRINTF2(KTestInfo, aOrientation);
+ if (EDisplayOrientationIgnore == aOrientation)
+ {
+ TEST(EFalse);
+ _LIT(KLog, "TestIndicateAppOrientation(TRenderOrientation aOrientation) cannot be used with EDisplayOrientationIgnore");
+ INFO_PRINTF1(KLog);
+ }
+ iWs.IndicateAppOrientation(aOrientation);
+ iWindowGroup.SetOrdinalPosition(0);
+ IsOrientationCorrect(aOrientation);
+ }
+
+void CTDeviceRotation::TestIndicateAppOrientation(TRenderOrientation aOrientation, TRenderOrientation aSecondOrientation)
+ {
+ _LIT(KTestInfo, "TestIndicateAppOrientation(aOrientation = %d, aSecondOrientation = %d)");
+ INFO_PRINTF3(KTestInfo, aOrientation, aSecondOrientation);
+ //Inform window serve the orientation status
+ iWs.IndicateAppOrientation(aOrientation);
+ iSecondWs.IndicateAppOrientation(aSecondOrientation);
+
+ iWindowGroup.SetOrdinalPosition(0,1);
+ iSecondWindowGroup.SetOrdinalPosition(1,1);
+
+ if(aOrientation != EDisplayOrientationIgnore)
+ {
+ IsOrientationCorrect(aOrientation);
+ }
+ else
+ {
+ IsOrientationCorrect(aSecondOrientation);
+ }
+ }
+
+void CTDeviceRotation::TestAppOrientationOnSwap(TRenderOrientation aOrientation, TRenderOrientation aSecondOrientation)
+ {
+ _LIT(KTestInfo, "TestAppOrientationOnSwap(aOrientation = %d, aSecondOrientation = %d)");
+ INFO_PRINTF3(KTestInfo, aOrientation, aSecondOrientation);
+
+ iWs.IndicateAppOrientation(aOrientation);
+ iSecondWs.IndicateAppOrientation(aSecondOrientation);
+
+ iSecondWindowGroup.SetOrdinalPosition(0);
+ if (aSecondOrientation != EDisplayOrientationIgnore)
+ {
+ IsOrientationCorrect(aSecondOrientation);
+ }
+ else
+ {
+ IsOrientationCorrect(aOrientation);
+ }
+ }
+
+void CTDeviceRotation::RunTestCaseL(TInt aCurTestCase)
+ {
+ _LIT(KNewLine, "\n");
+ (reinterpret_cast<CTDeviceRotationStep*>(iStep))->SetTestStepID(KUnknownSYMTestCaseIDName);
+ switch(aCurTestCase)
+ {
+ case 1:
+ _LIT(KTestStepID1,"Test Initial Orientations");
+ (reinterpret_cast<CTDeviceRotationStep*>(iStep))->SetTestStepID(KTestStepID1);
+ INFO_PRINTF1(KNewLine);
+ INFO_PRINTF1(KTestStepID1);
+ TestInitialOrientation();
+ break;
+ case 2:
+ _LIT(KTestStepID2,"Test Fixed Orientations");
+ (reinterpret_cast<CTDeviceRotationStep*>(iStep))->SetTestStepID(KTestStepID2);
+ INFO_PRINTF1(KNewLine);
+ INFO_PRINTF1(KTestStepID2);
+ TestFixedOrientations();
+ break;
+ case 3:
+ _LIT(KTestStepID3,"Test Auto Orientation");
+ (reinterpret_cast<CTDeviceRotationStep*>(iStep))->SetTestStepID(KTestStepID3);
+ INFO_PRINTF1(KNewLine);
+ INFO_PRINTF1(KTestStepID3);
+ TestAutoOrientation();
+ break;
+ case 4:
+ _LIT(KTestStepID4,"Test Ignore Orientation");
+ (reinterpret_cast<CTDeviceRotationStep*>(iStep))->SetTestStepID(KTestStepID4);
+ INFO_PRINTF1(KNewLine);
+ INFO_PRINTF1(KTestStepID4);
+ TestIgnoreOrientation();
+ break;
+ case 5:
+ _LIT(KTestStepID5,"Test Swap Orientations");
+ (reinterpret_cast<CTDeviceRotationStep*>(iStep))->SetTestStepID(KTestStepID5);
+ INFO_PRINTF1(KNewLine);
+ INFO_PRINTF1(KTestStepID5);
+ TestFixedOrientationsOnWindowSwap();
+ break;
+ case 6:
+ _LIT(KTestStepID6,"Test Auto Swap Orientations");
+ (reinterpret_cast<CTDeviceRotationStep*>(iStep))->SetTestStepID(KTestStepID6);
+ INFO_PRINTF1(KNewLine);
+ INFO_PRINTF1(KTestStepID6);
+ TestAutoOrientationOnWindowSwap();
+ break;
+ case 7:
+ _LIT(KTestStepID7,"Test Ignore Swap Orientations");
+ (reinterpret_cast<CTDeviceRotationStep*>(iStep))->SetTestStepID(KTestStepID7);
+ INFO_PRINTF1(KNewLine);
+ INFO_PRINTF1(KTestStepID7);
+ TestIgnoreOrientationOnWindowSwap();
+ break;
+ case 8:
+ _LIT(KTestStepID8,"Test Auto Swap Orientations");
+ (reinterpret_cast<CTDeviceRotationStep*>(iStep))->SetTestStepID(KTestStepID8);
+ INFO_PRINTF1(KNewLine);
+ INFO_PRINTF1(KTestStepID8);
+ TestIgnoreAutoOrientationOnWindowSwap();
+ break;
+ case 9:
+ _LIT(KTestStepID9,"Test Invalid App Orientations");
+ (reinterpret_cast<CTDeviceRotationStep*>(iStep))->SetTestStepID(KTestStepID9);
+ INFO_PRINTF1(KNewLine);
+ INFO_PRINTF1(KTestStepID9);
+ TestInvalidAppOrientation();
+ break;
+ case 10:
+ _LIT(KTestStepID10,"Test Invalid Theme Server Orientations");
+ (reinterpret_cast<CTDeviceRotationStep*>(iStep))->SetTestStepID(KTestStepID10);
+ INFO_PRINTF1(KNewLine);
+ INFO_PRINTF1(KTestStepID10);
+ TestInvalidThemeServerOrientation();
+ break;
+ default:
+ (reinterpret_cast<CTDeviceRotationStep*>(iStep))->SetTestStepID(KNotATestSYMTestCaseIDName);
+ (reinterpret_cast<CTDeviceRotationStep*>(iStep))->CloseTMSGraphicsStep();
+ TestComplete();
+ }
+ (reinterpret_cast<CTDeviceRotationStep*>(iStep))->RecordTestResultL();
+ }
+
+
+/**
+ @SYMTestCaseID GRAPHICS-WSERV-DEVICEROTATION-0001
+ @SYMTestCaseDesc Test Auto Orientation
+ @SYMPREQ 460936 Tracking Device Rotation
+ @SYMTestPriority 1
+ @SYMTestPurpose To test that we can return the correct initial orientation value from
+ the windwoserver.
+ @SYMPrerequisites An RProperty is set up to subscribe to notifications of
+ windowserver orientation changes.
+ We have set up an RWindowGroup at the foreground and not altered its
+ indicated orientation.
+ @SYMTestActions 1) Get the value of the orientation as published by window server.
+
+ @SYMTestExpectedResults The windowserver should return EDisplayOrientationNormal
+ */
+void CTDeviceRotation::TestInitialOrientation()
+ {
+ iWaitForPublishOnNextTest = EFalse;
+ IsOrientationCorrect(EDisplayOrientationNormal);
+ }
+
+/**
+ @SYMTestCaseID GRAPHICS-WSERV-DEVICEROTATION-0002
+ @SYMTestCaseDesc Test Fixed Orientations
+ @SYMPREQ 460936 Tracking Device Rotation
+ @SYMTestPriority 1
+ @SYMTestPurpose To test that we can return the correct orientation value from
+ the windwoserver after we indicate the application orientation
+ as fixed values using RWsSession::IndicateAppOrientation. Any
+ theme server orientations should be ignored.
+ @SYMPrerequisites An RProperty is set up to subscribe to notifications of
+ windowserver orientation changes.
+ An RProperty is set up to publish Theme server Orientation changes.
+ We have set up an RWindowGroup in the foreground.
+ Windowserver orientation currently set to EDisplayOrientationNormal.
+
+ @SYMTestActions 1) Set Theme Server orientation to EDisplayOrientation90CW.
+ 2) Set the RWindowgroup in ordinal position 0 to a fixed orientation.
+ 3) Check the published orinetation value in windowserver.
+ 4) Repeat steps 2) and 3) for all fixed orientations
+ 3) Set Theme Server orientation to EDisplayOrientationNormal.
+ 4) Repeat Steps 2-4).
+
+ @SYMTestExpectedResults The orientation set in step 2) should always be the same as the
+ orientation set in step 2)
+ */
+void CTDeviceRotation::TestFixedOrientations()
+ {
+ iWaitForPublishOnNextTest = EFalse;
+ SimulateThemeServerOrientation(EDisplayOrientation90CW);
+ TestIndicateAppOrientation(EDisplayOrientationNormal);
+ TestIndicateAppOrientation(EDisplayOrientation90CW);
+ TestIndicateAppOrientation(EDisplayOrientation180);
+ TestIndicateAppOrientation(EDisplayOrientation270CW);
+
+ SimulateThemeServerOrientation(EDisplayOrientationNormal);
+ TestIndicateAppOrientation(EDisplayOrientationNormal);
+ TestIndicateAppOrientation(EDisplayOrientation90CW);
+ TestIndicateAppOrientation(EDisplayOrientation180);
+ TestIndicateAppOrientation(EDisplayOrientation270CW);
+
+ SimulateThemeServerOrientation(EDisplayOrientation180);
+ TestIndicateAppOrientation(EDisplayOrientationNormal);
+ TestIndicateAppOrientation(EDisplayOrientation90CW);
+ TestIndicateAppOrientation(EDisplayOrientation180);
+ TestIndicateAppOrientation(EDisplayOrientation270CW);
+
+ SimulateThemeServerOrientation(EDisplayOrientation270CW);
+ TestIndicateAppOrientation(EDisplayOrientationNormal);
+ TestIndicateAppOrientation(EDisplayOrientation90CW);
+ TestIndicateAppOrientation(EDisplayOrientation180);
+ TestIndicateAppOrientation(EDisplayOrientation270CW);
+ }
+
+/**
+ @SYMTestCaseID GRAPHICS-WSERV-DEVICEROTATION-0003
+ @SYMTestCaseDesc Test Auto Orientation
+ @SYMPREQ 460936 Tracking Device Rotation
+ @SYMTestPriority 1
+ @SYMTestPurpose To test that we can return the correct orientation value from
+ the windwoserver after we indicate the application orientation
+ as auto values using RWsSession::IndicateAppOrientation. The wserv
+ should publish the theme server orientation changes only.
+ @SYMPrerequisites An RProperty is set up to subscribe to notifications of
+ windowserver orientation changes.
+ An RProperty is set up to publish Theme server Orientation changes.
+ We have set up an RWindowGroup in the foreground.
+ WindowServer orinetation is not set to EDisplayOrientation90CW.
+
+ @SYMTestActions 1) Set Theme Server orientation to EDisplayOrientation90CW.
+ 2) Set the RWindowgroup in ordinal position 0 to auto orientation.
+ 3) Check the published orinetation value in windowserver.
+ 4) Set Theme Server orientation to EDisplayOrientationNormal.
+ 5) Check the value of the orientation as published by window server.
+ 6) Repeat 4) and 5) for EDisplayOrientation180 and
+ EDisplayOrientation270CW
+ 7) repeat 4) and 5) again for EDisplayOrientation270CW
+
+ @SYMTestExpectedResults We should get expected notifications where orientations have changed.
+ The orientation checked in step 3) should be the theme server
+ orientation set in step 1).
+ The orientations checked in step 5) should be the theme server
+ orientations set in step 4).
+ We should recieve no notification for step 7).
+ */
+void CTDeviceRotation::TestAutoOrientation()
+ {
+ SimulateThemeServerOrientation(EDisplayOrientation90CW);
+ TestIndicateAppOrientation(EDisplayOrientationAuto);
+ SimulateThemeServerOrientation(EDisplayOrientationNormal);
+ IsOrientationCorrect(iCurrentThemeServerOrientation);
+ // Now flip it upside down to ensure that nothing assumes this will only be updated incrementally
+ SimulateThemeServerOrientation(EDisplayOrientation180);
+ IsOrientationCorrect(iCurrentThemeServerOrientation);
+ SimulateThemeServerOrientation(EDisplayOrientation270CW);
+ IsOrientationCorrect(iCurrentThemeServerOrientation);
+
+ // And check that wserv doesn't publish if the theme server publishes the existing orientation
+ SimulateThemeServerOrientation(EDisplayOrientation270CW);
+ iWaitForPublishOnNextTest = EFalse;
+ IsOrientationCorrect(iCurrentThemeServerOrientation);
+ }
+
+/**
+ @SYMTestCaseID GRAPHICS-WSERV-DEVICEROTATION-0004
+ @SYMTestCaseDesc Test Ignore Orientation
+ @SYMPREQ 460936 Tracking Device Rotation
+ @SYMTestPriority 1
+ @SYMTestPurpose To test that we can return the correct orientation value from
+ the windwoserver after we indicate the front applications
+ orientation as ignore.
+ @SYMPrerequisites An RProperty is set up to subscribe to notifications of
+ windowserver orientation changes.
+ An RProperty is set up to publish Theme server Orientation changes.
+ We have set up two RWindowGroups in the ordinal positions 0 and 1.
+ WindowServer orinetation is not set to EDisplayOrientationNormal.
+
+ @SYMTestActions 1) Set Theme Server orientation to EDisplayOrientation90CW.
+ 2) Set the RWindowGroup in ordinal position 0 to a ignore orientation.
+ 3) Set the RWindowgroup in ordinal position 1 to a fixed orientation.
+ 4) Check the published orinetation value in windowserver.
+ 5) Repeat steps 2-4) varying the fixed orientation set in step 2).
+ 6) Set Theme Server orientation to EDisplayOrientation90CW.
+ 7) Set the RWindowGroup in ordinal position 0 to a ignore orientation.
+ 8) Set the RWindowgroup in ordinal position 1 to a fixed orientation.
+ 9) Check the published orinetation value in windowserver.
+ 10) Set Theme Server orientation to EDisplayOrientationNormal.
+ 11) Check the published orinetation value in windowserver.
+
+ @SYMTestExpectedResults We should get expected notifications where orientations have changed.
+ All orientations checked in step 4) should be the fixed orientations
+ of the windows in ordinal position 1, as set in step 3).
+ The orientation checked in step 9) should be the theme server
+ orientation set in step 6).
+ The orientation checked in step 11) should be the theme server
+ orientation set in step 10).
+ */
+void CTDeviceRotation::TestIgnoreOrientation()
+ {
+ SimulateThemeServerOrientation(EDisplayOrientation90CW);
+ TestIndicateAppOrientation(EDisplayOrientationIgnore, EDisplayOrientationNormal);
+ TestIndicateAppOrientation(EDisplayOrientationIgnore, EDisplayOrientation90CW);
+ TestIndicateAppOrientation(EDisplayOrientationIgnore, EDisplayOrientation180);
+ TestIndicateAppOrientation(EDisplayOrientationIgnore, EDisplayOrientation270CW);
+
+ SimulateThemeServerOrientation(EDisplayOrientation90CW);
+ TestIndicateAppOrientation(EDisplayOrientationIgnore, EDisplayOrientationAuto);
+ SimulateThemeServerOrientation(EDisplayOrientationNormal);
+ IsOrientationCorrect(iCurrentThemeServerOrientation);
+ }
+
+/**
+ @SYMTestCaseID GRAPHICS-WSERV-DEVICEROTATION-0005
+ @SYMTestCaseDesc Test Fixed Orientations On Swap
+ @SYMPREQ 460936 Tracking Device Rotation
+ @SYMTestPriority 1
+ @SYMTestPurpose To test that we get notifactation of a change in orientation and can
+ return the correct orientation value from the windwoserver after we
+ swap windows with varying fixed orienations.
+ @SYMPrerequisites An RProperty is set up to subscribe to notifications of
+ windowserver orientation changes.
+ We have set up two RWindowGroups in the ordinal positions 0 and 1.
+
+ @SYMTestActions 1) Set the RWindowGroup in ordinal position 0 to a fixed orientation.
+ 2) Set the RWindowgroup in ordinal position 1 to a fixed orientation.
+ 3) Check the published orinetation value in windowserver.
+ 4) Move the RWindowGroup ordinal position 1 to the ordinal position 0.
+ 5) Check the published orinetation value in windowserver.
+ 6) Repeat steps 1-5 but vary the values the fixed orientation of the
+ RWindows set in steps 1) and 2)
+
+ @SYMTestExpectedResults We should get expected notifications where orientations have changed.
+ All orientations checked in step 3) should be the fixed orientations
+ of the windows in ordinal position 0, as set in step 1).
+ The orientations checked in step 5) should be the fixed orientations
+ of the windows which was in ordinal position 1 before each swap, as
+ set in step 2).
+ */
+void CTDeviceRotation::TestFixedOrientationsOnWindowSwap()
+ {
+ iWaitForPublishOnNextTest = EFalse;
+ TestIndicateAppOrientation(EDisplayOrientationNormal, EDisplayOrientationNormal);
+ iWaitForPublishOnNextTest = EFalse;
+ TestAppOrientationOnSwap(EDisplayOrientationNormal, EDisplayOrientationNormal);
+ TestIndicateAppOrientation(EDisplayOrientationNormal, EDisplayOrientation90CW);
+ TestAppOrientationOnSwap(EDisplayOrientationNormal, EDisplayOrientation90CW);
+ TestIndicateAppOrientation(EDisplayOrientation90CW, EDisplayOrientationNormal);
+ TestAppOrientationOnSwap(EDisplayOrientation90CW, EDisplayOrientationNormal);
+ }
+
+/**
+ @SYMTestCaseID GRAPHICS-WSERV-DEVICEROTATION-0006
+ @SYMTestCaseDesc Test Auto Orientations On Swap
+ @SYMPREQ 460936 Tracking Device Rotation
+ @SYMTestPriority 1
+ @SYMTestPurpose To test that we get notifactation of a change in orientation and can
+ return the correct orientation value from the windwoserver after we
+ swap windows with auto orienations.
+ @SYMPrerequisites An RProperty is set up to subscribe to notifications of
+ windowserver orientation changes.
+ An RProperty is set up to publish Theme server Orientation changes.
+ We have set up two RWindowGroups in the ordinal positions 0 and 1.
+ WindowServer orinetation is not set to EDisplayOrientation270CW.
+
+ @SYMTestActions 1) Set the theme server orientation.
+ 2) Set the RWindowGroup in ordinal position 0 to a fixed orientation.
+ 3) Set the RWindowGroup in ordinal position 1 to auto orientation.
+ 4) Check the published orinetation value in windowserver.
+ 5) Move the RWindowGroup ordinal position 1 to the ordinal position 0.
+ 6) Check the published orinetation value in windowserver.
+ 7) Repeat steps 1-6 but vary the values of the theme server
+ orientation in step 1) and the fixed orientation of the frontwindow
+ in 2)
+ @SYMTestExpectedResults We should get expected notifications where orientations have changed.
+ All orientations checked in step 4) should be the fixed orientations
+ of the front windows, which have been set in step 2).
+ All orientations checked in step 6) should be the theme server
+ orientations set in step 1)
+ */
+void CTDeviceRotation::TestAutoOrientationOnWindowSwap()
+ {
+ SimulateThemeServerOrientation(EDisplayOrientation90CW);
+ TestIndicateAppOrientation(EDisplayOrientation270CW, EDisplayOrientationAuto);
+ TestAppOrientationOnSwap(EDisplayOrientation270CW, EDisplayOrientationAuto);
+ SimulateThemeServerOrientation(EDisplayOrientationNormal);
+ TestIndicateAppOrientation(EDisplayOrientationAuto, EDisplayOrientation180);
+ TestAppOrientationOnSwap(EDisplayOrientationAuto, EDisplayOrientation180);
+
+ SimulateThemeServerOrientation(EDisplayOrientation90CW);
+ TestIndicateAppOrientation(EDisplayOrientation90CW, EDisplayOrientationAuto);
+ iWaitForPublishOnNextTest = EFalse;
+ TestAppOrientationOnSwap(EDisplayOrientation90CW, EDisplayOrientationAuto);
+ SimulateThemeServerOrientation(EDisplayOrientationNormal);
+ TestIndicateAppOrientation(EDisplayOrientationAuto, EDisplayOrientationNormal);
+ iWaitForPublishOnNextTest = EFalse;
+ TestAppOrientationOnSwap(EDisplayOrientationAuto, EDisplayOrientationNormal);
+ }
+
+/**
+ @SYMTestCaseID GRAPHICS-WSERV-DEVICEROTATION-0007
+ @SYMTestCaseDesc Test Swap Orientations with Ignore Orientation
+ @SYMPREQ 460936 Tracking Device Rotation
+ @SYMTestPriority 1
+ @SYMTestPurpose To test that we get notifactation of a change in orientation and can
+ return the correct orientation value from the windwoserver after we
+ swap windows with ignore orienations.
+ @SYMPrerequisites An RProperty is set up to subscribe to notifications of
+ windowserver orientation changes.
+ An RProperty is set up to publish Theme server Orientation changes.
+ We have set up two RWindowGroups in the ordinal positions 0 and 1.
+
+ @SYMTestActions 1) Set the theme server orientation.
+ 2) Set the RWindowGroup in ordinal position 0 to ignore orientation.
+ 3) Set the RWindowGroup in ordinal position 1 to a fixed orientation.
+ 4) Check the published orinetation value in windowserver.
+ 5) Move the RWindowGroup ordinal position 1 to the ordinal position 0.
+ 6) Check the published orinetation value in windowserver.
+ 7) Repeat steps 1-6 but vary the values of the theme server
+ orientation in step 1) and the fixed orientation of the frontwindow
+ in 3)
+ 8) Set the theme server orientation.
+ 9) Set the RWindowGroup in ordinal position 0 to a fixedorientation.
+ 10) Set the RWindowGroup in ordinal position 1 to ignore orienation.
+ 11) Repeat steps 4-6)
+ 12) Repeat steps 8-11) but vary the values of the theme server
+ orientation in step 8) and the fixed orientation of the
+ RwindowGroup in 9)
+
+ @SYMTestExpectedResults We should get expected notifications where orientations have changed.
+ All orientations checked in step 4) and 6) should be the fixed
+ orientations RWindowGroups which have been set in step 3).
+ All orientations checked in step 11) should be the fixed orientations
+ of the front RWindowGroups which have been set in step 9).
+*/
+void CTDeviceRotation::TestIgnoreOrientationOnWindowSwap()
+ {
+ SimulateThemeServerOrientation(EDisplayOrientation90CW);
+ TestIndicateAppOrientation(EDisplayOrientationIgnore, EDisplayOrientation270CW);
+ TestAppOrientationOnSwap(EDisplayOrientationIgnore, EDisplayOrientation180);
+
+ SimulateThemeServerOrientation(EDisplayOrientationNormal);
+ TestIndicateAppOrientation(EDisplayOrientationIgnore, EDisplayOrientationNormal);
+ TestAppOrientationOnSwap(EDisplayOrientationIgnore, EDisplayOrientation90CW);
+
+ SimulateThemeServerOrientation(EDisplayOrientation90CW);
+ TestIndicateAppOrientation(EDisplayOrientation270CW, EDisplayOrientationIgnore);
+ TestAppOrientationOnSwap(EDisplayOrientation180, EDisplayOrientationIgnore);
+
+ SimulateThemeServerOrientation(EDisplayOrientationNormal);
+ TestIndicateAppOrientation(EDisplayOrientationNormal, EDisplayOrientationIgnore);
+ TestAppOrientationOnSwap(EDisplayOrientation90CW, EDisplayOrientationIgnore);
+ }
+
+/**
+ @SYMTestCaseID GRAPHICS-WSERV-DEVICEROTATION-0008
+ @SYMTestCaseDesc Test Swap Orientations with Auto and Ignore Orientations
+ @SYMPREQ 460936 Tracking Device Rotation
+ @SYMTestPriority 1
+ @SYMTestPurpose To test that we get notifactation of a change in orientation and can
+ return the correct orientation value from the windwoserver after we
+ swap windows with auto and ignore orienations.
+ @SYMPrerequisites An RProperty is set up to subscribe to notifications of
+ windowserver orientation changes.
+ An RProperty is set up to publish Theme server Orientation changes.
+ We have set up two RWindowGroups in the ordinal positions 0 and 1.
+ @SYMTestActions 1) Set the theme server orientation to EDisplayOrientationNormal.
+ 2) Set the RWindowGroup in ordinal position 0 to auto orientation.
+ 3) Set the RWindowGroup in ordinal position 1 to ignore orientation.
+ 4) Check the published orinetation value in windowserver.
+ 5) Set the theme server orientation to EDisplayOrientation90CW.
+ 6) Check the published orinetation value in windowserver.
+ 7) Set the theme server orientation to EDisplayOrientationNormal.
+ 8) Move the RWindowGroup in ordinal position 1 to ordinal position 0.
+ 9) Check the published orinetation value in windowserver.
+ 10) Set the theme server orientation to EDisplayOrientation90CW.
+ 11) Check the published orinetation value in windowserver.
+
+ @SYMTestExpectedResults We should get expected notifications where orientations have changed.
+ The orientations checked in step 4), 6), 9) and 11) should all be
+ the orientations set to the themeserver in steps 1), 5), 8) and 10)
+ respecvtively.
+*/
+void CTDeviceRotation::TestIgnoreAutoOrientationOnWindowSwap()
+ {
+ SimulateThemeServerOrientation(EDisplayOrientationNormal);
+ TestIndicateAppOrientation(EDisplayOrientationAuto, EDisplayOrientationIgnore);
+ SimulateThemeServerOrientation(EDisplayOrientation90CW);
+ IsOrientationCorrect(iCurrentThemeServerOrientation);
+
+ SimulateThemeServerOrientation(EDisplayOrientationNormal);
+ iSecondWindowGroup.SetOrdinalPosition(0);
+ IsOrientationCorrect(iCurrentThemeServerOrientation);
+ SimulateThemeServerOrientation(EDisplayOrientation90CW);
+ IsOrientationCorrect(iCurrentThemeServerOrientation);
+ }
+
+/**
+ @SYMTestCaseID GRAPHICS-WSERV-DEVICEROTATION-0009
+ @SYMTestCaseDesc Test Invalid App Orientation
+ @SYMPREQ ###TrackingDeviceRotation### TODO replace me
+ @SYMTestPriority 1
+ @SYMTestPurpose To test that an invalid orientation is ignored.
+ @SYMPrerequisites An RProperty is set up to subscribe to notifications of
+ windowserver orientation changes.
+ An RProperty is set up to publish Theme server Orientation changes.
+ We have set up an RWindowGroup in ordinal position 0.
+ @SYMTestActions 1) Set the theme server orientation to EDisplayOrientationNormal.
+ 2) Set the RWindowGroup in ordinal position 0 to
+ EDisplayOrientation90CW.
+ 4) Check the published orinetation value in windowserver.
+ 5) Set the RWindowGroup in ordinal position 0 to an invalid
+ orientation.
+ 6) Check the published orinetation value in windowserver.
+
+ @SYMTestExpectedResults Wserv should publish an orientation change for 2) but not for 5).
+ The orientations checked in steps 4) and 6) should both be the
+ orientation set in step 2).
+*/
+void CTDeviceRotation::TestInvalidAppOrientation()
+ {
+ SimulateThemeServerOrientation(EDisplayOrientationNormal);
+ TestIndicateAppOrientation(EDisplayOrientation90CW);
+ iWs.IndicateAppOrientation(static_cast<TRenderOrientation>(1000));
+ iWaitForPublishOnNextTest = EFalse;
+ IsOrientationCorrect(EDisplayOrientation90CW);
+ }
+
+/**
+ @SYMTestCaseID GRAPHICS-WSERV-DEVICEROTATION-0010
+ @SYMTestCaseDesc Test Invalid Theme Server Orientation
+ @SYMPREQ ###TrackingDeviceRotation### TODO replace me
+ @SYMTestPriority 1
+ @SYMTestPurpose To test that an invalid theme server orientation is ignored when
+ the app orientation has been set to auto.
+ @SYMPrerequisites An RProperty is set up to subscribe to notifications of
+ windowserver orientation changes.
+ An RProperty is set up to publish Theme server Orientation changes.
+ We have set up an RWindowGroup in ordinal position 0.
+ @SYMTestActions 1) Set the theme server orientation to EDisplayOrientationNormal.
+ 2) Set the RWindowGroup in ordinal position 0 to
+ EDisplayOrientationAuto.
+ 4) Check the published orinetation value in windowserver.
+ 5) Set the theme server orientation to an invalid orientation.
+ 6) Check the published orinetation value in windowserver.
+
+ @SYMTestExpectedResults Wserv should publish an orientation change for 2) but not for 5).
+ The orientations checked in steps 4) and 6) should both be the
+ theme server orientation set in step 1).
+*/
+void CTDeviceRotation::TestInvalidThemeServerOrientation()
+ {
+ SimulateThemeServerOrientation(EDisplayOrientationNormal);
+ TestIndicateAppOrientation(EDisplayOrientationAuto);
+ SimulateThemeServerOrientation(static_cast<TRenderOrientation>(5000));
+ iWaitForPublishOnNextTest = EFalse;
+ IsOrientationCorrect(EDisplayOrientationNormal);
+ }
+
+__CONSTRUCT_STEP__(DeviceRotation)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserver/test/tauto/tdevicerotation.h Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,110 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Set of tests for Tracing Device Rotation. These tests generally test
+// the RWsSession::IndicateAppOrientation(...) API.
+//
+
+/**
+ @file
+ @test
+ @internalComponent - Internal Nokia test code
+*/
+
+#ifndef __TDEVICERORATION_H__
+#define __TDEVICERORATION_H__
+
+#include <e32std.h>
+#include <w32std.h>
+#include <e32property.h>
+#include <test/testexecutestepbase.h>
+#include "../tlib/testbase.h"
+#include "AUTO.H"
+#include "TGraphicsHarness.h"
+#include <wspublishandsubscribedata.h>
+
+//
+// CTDeviceRotation Definition
+//
+
+class CTDeviceRotation: public CTGraphicsBase
+ {
+public:
+ CTDeviceRotation(CTestStep* aStep);
+ ~CTDeviceRotation();
+ /*Sets the windowing environment,*/
+ void ConstructL();
+
+protected:
+ //from CTGraphicsStep - Calls the device rotation test.
+ virtual void RunTestCaseL(TInt aCurTestCase);
+private:
+ //tool functions
+ void SimulateThemeServerOrientation(TRenderOrientation aExpectedaOrientation);
+ void CheckHalSetting(TRenderOrientation aOrientation);
+ void IsOrientationCorrect(TRenderOrientation aOrientation);
+ void TestIndicateAppOrientation(TRenderOrientation aOrientation);
+ void TestIndicateAppOrientation(TRenderOrientation aOrientation, TRenderOrientation aSecondOrientation);
+ void TestIgnoredAppOrientation(TRenderOrientation aSecondOrientation, TInt aThemeServerOrientation, TInt aExpectedOrientation);
+ void TestAppOrientationOnSwap(TRenderOrientation aOrientation, TRenderOrientation aSecondOrientation);
+ //For TESTL
+ inline void testBooleanTrueL(TBool aCondition, const TText8* aFile, TInt aLine)
+ {
+ iStep->testBooleanTrueL(aCondition, aFile, aLine, ETrue);
+ }
+private:
+ //Test Cases
+ void TestInitialOrientation();
+ void TestFixedOrientations();
+ void TestAutoOrientation();
+ void TestIgnoreOrientation();
+ void TestFixedOrientationsOnWindowSwap();
+ void TestAutoOrientationOnWindowSwap();
+ void TestIgnoreOrientationOnWindowSwap();
+ void TestIgnoreAutoOrientationOnWindowSwap();
+ void TestInvalidAppOrientation();
+ void TestInvalidThemeServerOrientation();
+
+private:
+ //members
+ // First Session and Window Group
+ RWsSession iWs;
+ RWindowGroup iWindowGroup;
+ RWindow iChildWindow;
+ // Second Session and Window Group
+ RWsSession iSecondWs;
+ RWindowGroup iSecondWindowGroup;
+ RWindow iSecondChildWindow;
+
+ RProperty iRenderOrientationProperty;
+ RTimer iPublishTimer;
+ TRequestStatus iPublishTimerStatus;
+ TRequestStatus iRenderOrientationStatus;
+ RProperty iThemeServerOrientationProperty;
+
+ TRenderOrientation iCurrentThemeServerOrientation;
+ TBool iWaitForPublishOnNextTest; //Set to EFalse to skip waiting for publish on next test, default ETrue, Resets to ETrue on each Test.
+ };
+
+class CTDeviceRotationStep : public CTGraphicsStep
+ {
+public:
+ CTDeviceRotationStep();
+protected:
+ //from CTGraphicsStep
+ virtual CTGraphicsBase* CreateTestL();
+ };
+
+_LIT(KTDeviceRotationStep,"TDeviceRotation");
+
+#endif //TDEVICERORATION
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserver/test/tauto/tevent_captureapp.cpp Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,67 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Helper application for TEvent test case GRAPHICS-WSERV-0757
+//
+
+#include <e32base.h>
+#include <e32debug.h>
+#include <w32std.h>
+
+const TInt KCapturePriority = 1;
+
+LOCAL_C void MainL()
+ {
+ RWsSession session;
+ User::LeaveIfError(session.Connect());
+ CleanupClosePushL(session);
+ RWindowGroup group(session);
+ User::LeaveIfError(group.Construct(0));
+
+ // Capture keys EKeyF22 and EKeyF23 with raised
+ // priority for each of the three capture types.
+ TInt handle1 = User::LeaveIfError(group.CaptureKey(EKeyF22, 0, 0, KCapturePriority));
+ TInt handle2 = User::LeaveIfError(group.CaptureKeyUpAndDowns(EStdKeyF22, 0, 0, KCapturePriority));
+ TInt handle3 = User::LeaveIfError(group.CaptureLongKey(EKeyF22, EKeyF22, 0, 0, KCapturePriority, ELongCaptureNormal));
+ TInt handle4 = User::LeaveIfError(group.CaptureKey(EKeyF23, 0, 0, KCapturePriority));
+ TInt handle5 = User::LeaveIfError(group.CaptureKeyUpAndDowns(EStdKeyF23, 0, 0, KCapturePriority));
+ TInt handle6 = User::LeaveIfError(group.CaptureLongKey(EKeyF23, EKeyF23, 0, 0, KCapturePriority, ELongCaptureNormal));
+
+ // Complete rendezvous with TEvent. This signals that all the capture
+ // requests have been made.
+ RProcess::Rendezvous(KErrNone);
+
+ // Wait until killed by TEvent
+ User::WaitForAnyRequest();
+
+ group.CancelCaptureKey(handle1);
+ group.CancelCaptureKeyUpAndDowns(handle2);
+ group.CancelCaptureLongKey(handle3);
+ group.CancelCaptureKey(handle4);
+ group.CancelCaptureKeyUpAndDowns(handle5);
+ group.CancelCaptureLongKey(handle6);
+
+ CleanupStack::PopAndDestroy(&session);
+ }
+
+GLDEF_C TInt E32Main()
+ {
+ __UHEAP_MARK;
+
+ CTrapCleanup* cleanupStack = CTrapCleanup::New();
+ TRAPD(ret, MainL());
+ delete cleanupStack;
+
+ __UHEAP_MARKEND;
+ return ret;
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserver/test/tauto/themeserverpropertydefine.cpp Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,88 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// This Process called with the argument KThemeServerPropertyDefineCmdDefine, defines
+// the theme server RProperty catagory to be the same as the theme servers process ID.
+// Called with the argument KThemeServerPropertyDefineCmdDelete, it will delete the
+// theme server RProperty. This is because an RProperty can only be defined and deleted
+// from within a process with the same UID3 as the RProperty catogory you are trying to
+// define/delete.
+//
+
+/**
+ @file
+ @test
+ @internalComponent - Internal Nokia test code
+ */
+
+#include <BACLINE.H>
+#include <e32base.h>
+#include <e32property.h>
+#include "..\..\nga\server\renderorientationtracker.h" //for KThemeOrientationCatagory and KThemeOrientationKey
+#include "themeserverpropertydefine.h"
+
+void DefineThemeServerPropertyL()
+ {
+ RProperty themeServerOrientationProperty;
+ const TSecurityPolicy KThemeOrientationReadSecurityPolicy(
+ TSecurityPolicy::EAlwaysPass);
+ const TSecurityPolicy KThemeOrientationWriteSecurityPolicy(
+ TSecurityPolicy::EAlwaysPass);
+ User::LeaveIfError(RProperty::Define( KThemeOrientationCategory,
+ KThemeOrientationKey,
+ RProperty::EInt,
+ KThemeOrientationReadSecurityPolicy,
+ KThemeOrientationWriteSecurityPolicy));
+ themeServerOrientationProperty.Close();
+ }
+
+void DeleteThemeServerPropertyL()
+ {
+ TInt err = KErrNone;
+ RProperty themeServerOrientationProperty;
+ User::LeaveIfError(themeServerOrientationProperty.Delete(
+ KThemeOrientationCategory, KThemeOrientationKey));
+ themeServerOrientationProperty.Close();
+ }
+
+void MainL()
+ {
+ CCommandLineArguments* args = CCommandLineArguments::NewLC();
+ TPtrC argumentPrt(args->Arg(1));
+ if (argumentPrt == KThemeServerPropertyDefineCmdDefine)
+ {
+ DefineThemeServerPropertyL();
+ }
+ else if (argumentPrt == KThemeServerPropertyDefineCmdDelete)
+ {
+ DeleteThemeServerPropertyL();
+ }
+ else
+ {
+ User::Leave(KErrNotSupported);
+ }
+ CleanupStack::PopAndDestroy(args);
+ }
+
+GLDEF_C TInt E32Main()
+ {
+ CTrapCleanup* cleanUpStack = CTrapCleanup::New();
+ if (cleanUpStack == NULL)
+ {
+ return KErrNoMemory;
+ }
+ TRAPD(err, MainL());
+ delete cleanUpStack;
+ return (err);
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserver/test/tauto/themeserverpropertydefine.h Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,29 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Header Defines the EXE name as well as the two possible command line
+// arguments for twsthemeserverdefine.exe
+
+/**
+ @file
+ @test
+ @internalComponent - Internal Nokia test code
+ */
+#ifndef THEMESERVERSIMULATION_H_
+#define THEMESERVERSIMULATION_H_
+
+_LIT(KThemeServerPropertyDefine, "twsthemeserverpropertydefine.exe");
+_LIT(KThemeServerPropertyDefineCmdDefine, "define");
+_LIT(KThemeServerPropertyDefineCmdDelete, "delete");
+
+#endif /* THEMESERVERSIMULATION_H_ */
--- a/windowing/windowserver/wins_switching/ws32_stubs.h Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserver/wins_switching/ws32_stubs.h Fri Sep 24 16:44:34 2010 +0300
@@ -5292,6 +5292,15 @@
_asm jmp common_dispatch
}
+__declspec(dllexport)
+__declspec(naked)
+void call_vector_587 ()
+ {
+ // ; void RWsSession::IndicateAppOrientation(enum TRenderOrientation)
+ _asm mov eax, 587
+ _asm jmp common_dispatch
+ }
+
}
-#define MAX_ORDINAL 587
-
+#define MAX_ORDINAL 588
+
--- a/windowing/windowserverplugins/group/bld.inf Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserverplugins/group/bld.inf Fri Sep 24 16:44:34 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
@@ -30,6 +30,8 @@
PRJ_MMPFILES
+#include "../keyeventrouting/group/bld.inf"
+
#ifndef SYMBIAN_GRAPHICS_BUILD_OPENWF_WSERV
#include "../restricted/group/BLD.INF"
#else
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserverplugins/keyeventrouting/bwins/keyrouteru.def Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,3 @@
+EXPORTS
+ ?NewL@CKeyEventRouter@@SAPAV1@XZ @ 1 NONAME ; class CKeyEventRouter * CKeyEventRouter::NewL(void)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserverplugins/keyeventrouting/eabi/keyrouteru.def Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,3 @@
+EXPORTS
+ _ZN15CKeyEventRouter4NewLEv @ 1 NONAME
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserverplugins/keyeventrouting/group/bld.inf Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,29 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Key Event Routing plug-in for Window Server
+//
+
+PRJ_EXPORTS
+../bwins/keyrouteru.def SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(graphics/def/bwins/keyrouteru.def)
+../eabi/keyrouteru.def SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(graphics/def/eabi/keyrouteru.def)
+keyeventrouting.iby /epoc32/rom/include/keyeventrouting.iby
+
+PRJ_TESTEXPORTS
+keyeventrouting_test.iby /epoc32/rom/include/keyeventrouting_test.iby
+
+PRJ_MMPFILES
+keyeventrouting.mmp
+
+PRJ_TESTMMPFILES
+keyeventrouting_test.mmp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserverplugins/keyeventrouting/group/keyeventrouting.iby Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,22 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Key Event Routing plug-in for Window Server
+//
+
+#ifndef __KEYEVENTROUTING_IBY__
+#define __KEYEVENTROUTING_IBY__
+
+file=ABI_DIR\BUILD_DIR\keyrouter.dll System\Libs\keyrouter.dll
+
+#endif // __KEYEVENTROUTING_IBY__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserverplugins/keyeventrouting/group/keyeventrouting.mmp Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,28 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Key Event Routing plug-in for Window Server
+//
+
+TARGET keyrouter.dll
+TARGETTYPE dll
+CAPABILITY PowerMgmt ReadDeviceData WriteDeviceData ProtServ
+UID 0x102872e1 0x102872e2
+VENDORID 0x70000001
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+SOURCEPATH ../src
+SOURCE keyrouter.cpp
+
+LIBRARY euser.lib
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserverplugins/keyeventrouting/group/keyeventrouting_test.iby Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,22 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Key Event Routing plug-in for Window Server: test version
+//
+
+#ifndef __KEYEVENTROUTING_TEST_IBY__
+#define __KEYEVENTROUTING_TEST_IBY__
+
+file=ABI_DIR\BUILD_DIR\keyrouter_test.dll System\Libs\keyrouter_test.dll
+
+#endif // __KEYEVENTROUTING_TEST_IBY__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserverplugins/keyeventrouting/group/keyeventrouting_test.mmp Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,32 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Key Event Routing plug-in for Window Server: test version
+//
+
+TARGET keyrouter_test.dll
+TARGETTYPE dll
+CAPABILITY PowerMgmt ReadDeviceData WriteDeviceData ProtServ
+UID 0x102872e1 0x102872e6
+VENDORID 0x70000001
+
+MACRO KEYROUTER_TEST
+
+DEFFILE keyrouter.def
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+SOURCEPATH ../src
+SOURCE keyrouter.cpp
+
+LIBRARY euser.lib
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserverplugins/keyeventrouting/src/keyaliases.h Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,108 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Key code and scan code aliases for platform specific keys.
+// The definitions are as per S60 <mw/eikon.hrh> with the addition of the
+// full set of scan codes.
+
+/**
+@file
+@internalTechnology
+@prototype
+*/
+
+#include <e32keys.h>
+
+/**
+TStdScanCode aliases
+*/
+#define EStdKeyOK EStdKeyDevice3
+#define EStdKeyCBA1 EStdKeyDevice0
+#define EStdKeyCBA2 EStdKeyDevice1
+#define EStdKeyPhoneSend EStdKeyYes
+#define EStdKeyPhoneEnd EStdKeyNo
+#define EStdKeyApplication EStdKeyApplication0
+#define EStdKeyPowerOff EStdKeyDevice2
+#define EStdKeyGripOpen EStdKeyDevice4
+#define EStdKeyGripClose EStdKeyDevice5
+#define EStdKeySide EStdKeyDevice6 // Voice key
+#define EStdKeyCamera EStdKeyDevice7
+#define EStdKeyTwistOpen EStdKeyDevice8
+#define EStdKeyTwistClose EStdKeyDevice9
+#define EStdKeyLeftUpArrow EStdKeyDevice10 // Diagonal arrow event
+#define EStdKeyRightUpArrow EStdKeyDevice11 // Diagonal arrow event
+#define EStdKeyRightDownArrow EStdKeyDevice12 // Diagonal arrow event
+#define EStdKeyLeftDownArrow EStdKeyDevice13 // Diagonal arrow event
+#define EStdKeyVolumeUp EStdKeyIncVolume
+#define EStdKeyVolumeDown EStdKeyDecVolume
+#define EStdKeyFlipOpen EStdKeyDeviceA
+#define EStdKeyFlipClose EStdKeyDeviceB
+#define EStdKeyPoC EStdKeyApplication1
+#define EStdKeyPlay EStdKeyApplication2
+#define EStdKeyStop EStdKeyApplication3
+#define EStdKeyForward EStdKeyApplication4
+#define EStdKeyRewind EStdKeyApplication5
+#define EStdKeyOperator EStdKeyApplication6
+#define EStdKeyQwertyOn EStdKeyApplication7
+#define EStdKeyQwertyOff EStdKeyApplication8
+#define EStdKeyNext EStdKeyApplication9
+#define EStdKeyPrevious EStdKeyApplicationA
+#define EStdKeyHoldSwitch EStdKeyApplicationB
+#define EStdKeyZoomIn EStdKeyApplicationC
+#define EStdKeyZoomOut EStdKeyApplicationD
+#define EStdKey4x10QwertyOn EStdKeyApplicationE
+#define EStdKey3x11QwertyOn EStdKeyApplication10
+#define EStdKeyHalfQwertyOn EStdKeyApplication11
+#define EStdKeyCustomKeyboardOn EStdKeyApplication12
+
+/**
+TKeyCode aliases
+*/
+#define EKeyOK EKeyDevice3
+#define EKeyCBA1 EKeyDevice0
+#define EKeyCBA2 EKeyDevice1
+#define EKeyPhoneSend EKeyYes
+#define EKeyPhoneEnd EKeyNo
+#define EKeyApplication EKeyApplication0
+#define EKeyPowerOff EKeyDevice2
+#define EKeyGripOpen EKeyDevice4
+#define EKeyGripClose EKeyDevice5
+#define EKeySide EKeyDevice6 // Voice key
+#define EKeyCamera EKeyDevice7
+#define EKeyTwistOpen EKeyDevice8
+#define EKeyTwistClose EKeyDevice9
+#define EKeyLeftUpArrow EKeyDevice10 // Diagonal arrow event
+#define EKeyRightUpArrow EKeyDevice11 // Diagonal arrow event
+#define EKeyRightDownArrow EKeyDevice12 // Diagonal arrow event
+#define EKeyLeftDownArrow EKeyDevice13 // Diagonal arrow event
+#define EKeyVolumeUp EKeyIncVolume
+#define EKeyVolumeDown EKeyDecVolume
+#define EKeyFlipOpen EKeyDeviceA
+#define EKeyFlipClose EKeyDeviceB
+#define EKeyPoC EKeyApplication1
+#define EKeyPlay EKeyApplication2
+#define EKeyStop EKeyApplication3
+#define EKeyForward EKeyApplication4
+#define EKeyRewind EKeyApplication5
+#define EKeyOperator EKeyApplication6
+#define EKeyQwertyOn EKeyApplication7
+#define EKeyQwertyOff EKeyApplication8
+#define EKeyNext EKeyApplication9
+#define EKeyPrevious EKeyApplicationA
+#define EKeyHoldSwitch EKeyApplicationB
+#define EKeyZoomIn EKeyApplicationC
+#define EKeyZoomOut EKeyApplicationD
+#define EKey4x10QwertyOn EKeyApplicationE
+#define EKey3x11QwertyOn EKeyApplication10
+#define EKeyHalfQwertyOn EKeyApplication11
+#define EKeyCustomKeyboardOn EKeyApplication12
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserverplugins/keyeventrouting/src/keyrouter.cpp Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,431 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Reference implementation of Key Event Routing plug-in
+
+/**
+@file
+@internalTechnology
+@prototype
+*/
+
+#include <e32cmn.h>
+#include <e32debug.h>
+#include "keyrouterimpl.h"
+#include "keyaliases.h"
+
+#ifdef KEYROUTER_TEST
+/**
+Privileged application UIDs
+*/
+const TInt KUidTAutoServer = 0x10205152;
+const TInt KUidReservedApp = 0x102872e3;
+
+/**
+Key Capture Translation Table
+
+The following scan codes and key codes are translated at capture-request time.
+
+@note The data in this table is for example/test purposes only.
+*/
+const TTranslationEntry KTranslations[] =
+ {
+ // Entry for TEvent test case GRAPHICS-WSERV-0751.
+ // Capture requests for psuedo key Device0 are mapped to capture
+ // the real key Device1.
+ // Req. scancode, Capture scancode, Req. keycode, Capture keycode
+ { EStdKeyDevice0, EStdKeyDevice1, EKeyDevice0, EKeyDevice1 }
+ };
+
+/**
+Restricted Key Table
+
+The following keys may be captured only by the specified application.
+
+@note The data in this table is for example/test purposes only.
+*/
+const TAppKeyEntry KRestrictedKeys[] =
+ {
+ // Examples:
+ // Only the Phone app is allowed to capture long End key events
+ // { EKeyPhoneEnd, ECaptureTypeLongKey, KUidPhoneApp },
+ // Only the Home Screen app is allowed to capture short Apps key events
+ // { EStdKeyApplication, ECaptureTypeKeyUpDown, KUidHomeScreenApp },
+ // { EKeyApplication, ECaptureTypeKey, KUidHomeScreenApp },
+ // Only SysApp is allowed to capture long Apps key events (for
+ // launching the task switcher).
+ // { EKeyApplication, ECaptureTypeLongKey, KUidSysApp },
+
+ // Test Case GRAPHICS-WSERV-0754. Only a reserved UID is allowed to
+ // capture F20 key events.
+ { EKeyF20, ECaptureTypeKey, KUidReservedApp },
+ { EKeyF20, ECaptureTypeLongKey, KUidReservedApp },
+ { EStdKeyF20, ECaptureTypeKeyUpDown, KUidReservedApp },
+ // Only TAuto tests are allowed to capture F21 key events
+ { EKeyF21, ECaptureTypeKey, KUidTAutoServer },
+ { EKeyF21, ECaptureTypeLongKey, KUidTAutoServer },
+ { EStdKeyF21, ECaptureTypeKeyUpDown, KUidTAutoServer }
+ };
+
+/**
+Priority Application Table
+
+The following applications have priority over other applications for capture
+of the specified key.
+
+@note The data in this table is for example/test purposes only.
+ If a key should be never be delivered to any other application, then
+ it should be placed in KRestrictedKeys[] instead.
+*/
+const TAppKeyEntry KPriorityAppKeys[] =
+ {
+ // Example:
+ // The Phone app has priority for capture of short Send and End
+ // key events
+ // { EStdKeyPhoneSend, ECaptureTypeKeyUpDown, KUidPhoneApp },
+ // { EKeyPhoneSend, ECaptureTypeKey, KUidPhoneApp },
+ // { EStdKeyPhoneEnd, ECaptureTypeKeyUpDown, KUidPhoneApp },
+ // { EKeyPhoneEnd, ECaptureTypeKey, KUidPhoneApp },
+
+ // Test Case GRAPHICS-WSERV-0757. TAuto tests have priority for
+ // capture of F22 key events.
+ { EStdKeyF22, ECaptureTypeKeyUpDown, KUidTAutoServer },
+ { EKeyF22, ECaptureTypeKey, KUidTAutoServer },
+ { EKeyF22, ECaptureTypeLongKey, KUidTAutoServer }
+ };
+
+/**
+Blocked key table.
+
+The following keys are not routed by default.
+
+@note The data in this table is for example/test purposes only.
+ Since long key events are never routed by default, there is no need
+ to list them here.
+*/
+const TBlockedKeyEntry KBlockedKeys[] =
+ {
+ // Entries for TEvent test case GRAPHICS-WSERV-0760
+ { EStdKeyDevice3, ECaptureTypeKeyUpDown },
+ { EKeyDevice3, ECaptureTypeKey }
+ };
+
+const TInt KNumTranslations = TABLE_SIZE(KTranslations);
+const TInt KNumRestrictedKeys = TABLE_SIZE(KRestrictedKeys);
+const TInt KNumPriorityAppKeys = TABLE_SIZE(KPriorityAppKeys);
+const TInt KNumBlockedKeys = TABLE_SIZE(KBlockedKeys);
+#endif // KEYROUTER_TEST
+
+const TInt KCaptureKeyArrayGranularity = 5;
+
+/**
+Create and return an instance of CKeyEventRouter
+
+@return Pointer to new router instance
+*/
+EXPORT_C CKeyEventRouter* CKeyEventRouter::NewL()
+ {
+ return new(ELeave) CKeyEventRouterImpl;
+ }
+
+CKeyEventRouterImpl::CKeyEventRouterImpl()
+: iCaptureKeys(KCaptureKeyArrayGranularity, _FOFF(TKeyCaptureRequest, iHandle))
+ {
+ }
+
+CKeyEventRouterImpl::~CKeyEventRouterImpl()
+ {
+ iCaptureKeys.Close();
+ }
+
+/**
+Add a new key capture request
+
+@param aRequest Capture request details
+
+@see CKeyEventRouter::AddCaptureKeyL
+*/
+void CKeyEventRouterImpl::AddCaptureKeyL(const TKeyCaptureRequest& aRequest)
+ {
+ CheckCaptureKeyL(aRequest);
+ iCaptureKeys.InsertL(aRequest, 0);
+#ifdef KEYROUTER_TEST
+ TranslateCaptureKey(aRequest.iType, iCaptureKeys[0].iInputCode);
+#endif
+ }
+
+/**
+Update an existing key capture request
+
+@param aRequest Updated capture request details
+
+@see CKeyEventRouter::UpdateCaptureKeyL
+*/
+void CKeyEventRouterImpl::UpdateCaptureKeyL(const TKeyCaptureRequest& aRequest)
+ {
+ CheckCaptureKeyL(aRequest);
+
+ TInt index = iCaptureKeys.Find(aRequest);
+ ASSERT(index != KErrNotFound);
+
+ if (index != KErrNotFound)
+ {
+ iCaptureKeys[index] = aRequest;
+ }
+ }
+
+/**
+Cancel a key capture request
+
+@param aType Capture type
+@param aHandle Opaque handle of request to be cancelled
+
+@see CKeyEventRouter::CancelCaptureKey
+
+Note: aType is unused in this implementation, but is present to permit
+implementations that use separate lists for each of the three capture types.
+*/
+void CKeyEventRouterImpl::CancelCaptureKey(TKeyCaptureType /*aType*/, TAny* aHandle)
+ {
+ TKeyCaptureRequest request;
+ request.iHandle = aHandle;
+
+ TInt index = iCaptureKeys.Find(request);
+ if (index != KErrNotFound)
+ {
+ iCaptureKeys.Remove(index);
+ }
+ }
+
+/**
+Route the key event described by aInput and return its destination in iOutput
+
+@param aInput Input data with key event to be routed
+@param aOutput Output key event and routing results
+
+@see CKeyEventRouter::RouteKey
+*/
+void CKeyEventRouterImpl::RouteKey(const TKeyEventRouterInput& aInput, TKeyEventRouterOutput& aOutput)
+ {
+ TUint inputCode = (aInput.iType == ECaptureTypeKeyUpDown) ?
+ aInput.iKeyEvent.iScanCode : aInput.iKeyEvent.iCode;
+#ifdef KEYROUTER_TEST
+ TInt priUid = PriorityAppUid(aInput.iType, inputCode);
+#endif
+ TInt priority = KMinTInt;
+ TInt captureCount = iCaptureKeys.Count();
+ TKeyCaptureRequest* matchRequest = NULL;
+
+ // Find the highest priority matching capture request. If there are
+ // multiple entries with the same priority then use the first one, i.e.
+ // the most recent request. Capture priorities are overridden if a
+ // particular application has precedence for capture of the key.
+ for (TInt index = 0; index < captureCount; index++)
+ {
+ TKeyCaptureRequest& request = iCaptureKeys[index];
+ if (request.iType == aInput.iType &&
+ request.iInputCode == inputCode &&
+ (aInput.iKeyEvent.iModifiers & request.iModifierMask) == request.iModifiers &&
+ (request.iPriority > priority
+#ifdef KEYROUTER_TEST
+ || priUid != 0 && request.iAppUid.iUid == priUid
+#endif
+ ))
+ {
+ matchRequest = &request;
+#ifdef KEYROUTER_TEST
+ if (priUid != 0 && request.iAppUid.iUid == priUid)
+ {
+ break;
+ }
+#endif
+ priority = request.iPriority;
+ }
+ }
+
+ if (matchRequest)
+ {
+ // Found matching capture request. Route the key event to the window
+ // group that made the capture request.
+ aOutput.iWindowGroup = matchRequest->iWindowGroup;
+ if (aInput.iType == ECaptureTypeKeyUpDown)
+ {
+ aOutput.iKeyEvent.iScanCode = matchRequest->iOutputCode;
+ aOutput.iKeyEvent.iCode = aInput.iKeyEvent.iCode;
+ }
+ else
+ {
+ aOutput.iKeyEvent.iScanCode = aInput.iKeyEvent.iScanCode;
+ aOutput.iKeyEvent.iCode = matchRequest->iOutputCode;
+ }
+ aOutput.iKeyEvent.iModifiers = aInput.iKeyEvent.iModifiers;
+ aOutput.iCaptureHandle = matchRequest->iHandle;
+ aOutput.iResult = ECaptured;
+ }
+#ifdef KEYROUTER_TEST
+ else if (IsKeyBlocked(aInput.iType, inputCode))
+ {
+ // No matching capture request and key is blocked. Do not route.
+ aOutput.iResult = EConsumed;
+ }
+#endif
+ else
+ {
+ // No matching capture request. Route the key event to the current
+ // focussed window group.
+ aOutput.iWindowGroup = aInput.iFocusWindowGroup;
+ aOutput.iKeyEvent = aInput.iKeyEvent;
+ aOutput.iCaptureHandle = NULL;
+ aOutput.iResult = ERouted;
+ }
+ }
+
+/**
+Check that capture request arguments are sane and capture is allowed
+
+@param aRequest Capture request details
+
+@leave KErrArgument if modifier state contains bits that are not in the
+ modifier mask or modifier mask contains EModifierLongKey or priority
+ is KMinTInt.
+ KErrPermissionDenied if key is restricted to capture by a specific
+ application UID and the UID of the requesting app does not match.
+
+@note Requests with a priority of KMinTint would never be captured: this was
+ also true of the previous implementation in ektran.dll but was ignored.
+ Client code must use the appropriate API function to capture short or
+ long key events, so including EModifierLongKey in the modifier mask is
+ not allowed. (Hotkeys are excepted since a mask of 0xffffffff is used
+ to disable them).
+*/
+void CKeyEventRouterImpl::CheckCaptureKeyL(const TKeyCaptureRequest& aRequest)
+ {
+ if ((aRequest.iModifiers & ~aRequest.iModifierMask) != 0 ||
+ (aRequest.iModifierMask & EModifierLongKey) != 0 && aRequest.iWindowGroup != NULL ||
+ aRequest.iPriority == KMinTInt)
+ {
+ User::Leave(KErrArgument);
+ }
+
+#ifdef KEYROUTER_TEST
+ if (aRequest.iWindowGroup != NULL && IsRestrictedKey(aRequest))
+ {
+ User::Leave(KErrPermissionDenied);
+ }
+#endif
+ }
+
+#ifdef KEYROUTER_TEST
+/**
+Check if the requested key capture is restricted by application UID
+
+@param aRequest Capture request details
+
+@return ETrue if key is restricted and requesting UID does not match,
+ otherwise EFalse.
+*/
+TBool CKeyEventRouterImpl::IsRestrictedKey(const TKeyCaptureRequest& aRequest)
+ {
+ for (const TAppKeyEntry* entry = KRestrictedKeys; entry < &KRestrictedKeys[KNumRestrictedKeys]; entry++)
+ {
+ if (entry->iCode == aRequest.iInputCode &&
+ entry->iType == aRequest.iType &&
+ entry->iAppUidValue != aRequest.iAppUid.iUid)
+ {
+ return ETrue;
+ }
+ }
+
+ return EFalse;
+ }
+
+/**
+Return the UID of the application with priority for capture of the specified
+key.
+
+@param aType Key capture type
+@param aCode Key code or scan code
+
+@return UID3 of the privileged application or zero if none.
+*/
+TInt CKeyEventRouterImpl::PriorityAppUid(TKeyCaptureType aType, TUint aCode)
+ {
+ for (const TAppKeyEntry* entry = KPriorityAppKeys; entry < &KPriorityAppKeys[KNumPriorityAppKeys]; entry++)
+ {
+ if (entry->iCode == aCode && entry->iType == aType)
+ {
+ return entry->iAppUidValue;
+ }
+ }
+
+ return 0;
+ }
+
+/**
+Check if the specified key is blocked from default routing
+
+@param aType Key capture type
+@param aCode Scan code or key code
+
+@return ETrue if key is blocked, otherwise EFalse.
+*/
+TBool CKeyEventRouterImpl::IsKeyBlocked(TKeyCaptureType aType, TUint aCode)
+ {
+ for (const TBlockedKeyEntry* entry = KBlockedKeys; entry < &KBlockedKeys[KNumBlockedKeys]; entry++)
+ {
+ if (entry->iCode == aCode && entry->iType == aType)
+ {
+ return ETrue;
+ }
+ }
+
+ return EFalse;
+ }
+
+/**
+Translate the scan or key code of a capture request
+
+@param aType Key capture type
+@param aCode Key code or scan code, updated to translated value (if any)
+
+@note This function is used to translate the input key or scan code of a
+ capture request on addition to the capture list. When a key event that
+ matches the list entry is routed, the output code will be taken from
+ TKeyCaptureRequest.iOutputCode and hence automatically translated again
+ (typically back to the original input code of the request, unless the
+ input and output codes were different). For example, a request to
+ capture key code A will be translated to key code B in the capture list.
+ When RouteKey() processes an event with key code B and selects that
+ list entry, it will output key code A for delivery to the application.
+*/
+void CKeyEventRouterImpl::TranslateCaptureKey(TKeyCaptureType aType, TUint& aCode)
+{
+ for (const TTranslationEntry* entry = KTranslations; entry < &KTranslations[KNumTranslations]; entry++)
+ {
+ if (aType == ECaptureTypeKeyUpDown)
+ {
+ if (aCode == entry->iRequestScanCode)
+ {
+ aCode = entry->iCaptureScanCode;
+ }
+ }
+ else
+ {
+ if (aCode == entry->iRequestKeyCode)
+ {
+ aCode = entry->iCaptureKeyCode;
+ }
+ }
+ }
+ }
+#endif // KEYROUTER_TEST
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserverplugins/keyeventrouting/src/keyrouterimpl.h Fri Sep 24 16:44:34 2010 +0300
@@ -0,0 +1,84 @@
+// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Reference implementation of Key Event Routing plug-in
+
+/**
+@file
+@internalTechnology
+@prototype
+*/
+
+#ifndef KEYROUTERIMPL_H
+#define KEYROUTERIMPL_H
+
+#include <graphics/wskeyrouter.h>
+
+#ifdef KEYROUTER_TEST
+/** Key Capture Translation Table entry */
+struct TTranslationEntry
+ {
+ TUint iRequestScanCode;
+ TUint iCaptureScanCode;
+ TUint iRequestKeyCode;
+ TUint iCaptureKeyCode;
+ };
+
+/** Entry for Restricted Key and Priority Application tables */
+struct TAppKeyEntry
+ {
+ TUint iCode;
+ TKeyCaptureType iType;
+ TInt iAppUidValue;
+ };
+
+/** Blocked Key Table entry */
+struct TBlockedKeyEntry
+ {
+ TUint iCode;
+ TKeyCaptureType iType;
+ };
+
+#define TABLE_SIZE(table) (sizeof(table) / sizeof((table)[0]))
+
+#endif // KEYROUTER_TEST
+
+/**
+Key Event Router implementation class
+*/
+NONSHARABLE_CLASS(CKeyEventRouterImpl) : public CKeyEventRouter
+ {
+public:
+ CKeyEventRouterImpl();
+ ~CKeyEventRouterImpl();
+
+ // From CKeyEventRouter
+ void AddCaptureKeyL(const TKeyCaptureRequest& aRequest);
+ void UpdateCaptureKeyL(const TKeyCaptureRequest& aRequest);
+ void CancelCaptureKey(TKeyCaptureType aType, TAny* aHandle);
+ void RouteKey(const TKeyEventRouterInput& aInput,
+ TKeyEventRouterOutput& aOutput);
+private:
+ void CheckCaptureKeyL(const TKeyCaptureRequest& aRequest);
+#ifdef KEYROUTER_TEST
+ TBool IsRestrictedKey(const TKeyCaptureRequest& aRequest);
+ TBool IsKeyBlocked(TKeyCaptureType aType, TUint aCode);
+ TInt PriorityAppUid(TKeyCaptureType aType, TUint aCode);
+ void TranslateCaptureKey(TKeyCaptureType aType, TUint& aCode);
+#endif
+
+private:
+ RArray<TKeyCaptureRequest> iCaptureKeys;
+ };
+
+#endif // KEYROUTERIMPL_H
--- a/windowing/windowserverplugins/openwfc/group/wserv_std_plugins.iby Fri Sep 24 16:14:28 2010 +0300
+++ b/windowing/windowserverplugins/openwfc/group/wserv_std_plugins.iby Fri Sep 24 16:44:34 2010 +0300
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
@@ -30,4 +30,6 @@
ECOM_PLUGIN(10286378.dll,10286378.rsc)
#endif
+#include <keyeventrouting.iby>
+
#endif // __WSERV_STD_PLUGINS_IBY__