Migrated the writing fshell commands guide to the wiki.
// btrace_keypress.cpp
//
// Copyright (c) 2008 - 2010 Accenture. All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the "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:
// Accenture - Initial contribution
//
#include <fshell/ltkutils.h>
#include "btrace_parser.h"
EXPORT_C CBtraceKeyPress* CBtraceKeyPress::NewL(CBtraceReader& aReader)
{
CBtraceKeyPress* self = new (ELeave) CBtraceKeyPress(aReader);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
CBtraceKeyPress::CBtraceKeyPress(CBtraceReader& aReader):
iReader(aReader)
{
}
EXPORT_C CBtraceKeyPress::~CBtraceKeyPress()
{
iReader.RemoveObserver(KAmTraceCategory, *this);
iKeyNotifs.Close();
iPointerNotifs.Close();
iGenericNotifs.Close();
iRawKeyNotifs.Close();
}
void CBtraceKeyPress::ConstructL()
{
iReader.AddObserverL(KAmTraceCategory, *this);
LtkUtils::W32CrackL(); // In case no-one's called it yet
}
//
// CBtraceKeyPress::HandleBtraceFrameL
// process the btrace frame, stripping out the key event data
//
void CBtraceKeyPress::HandleBtraceFrameL(const TBtraceFrame& aFrame)
{
if(aFrame.iCategory == KAmTraceCategory && aFrame.iSubCategory == EAmTraceSubCategoryEvCapture)
{
const TUint32* data = reinterpret_cast<const TUint32*>(aFrame.iData.Ptr());
const TAmTraceEventEvCapture event = static_cast<TAmTraceEventEvCapture>(*data++);
switch(event)
{
case EAmTraceEventEvCaptureKeyPress:
{
data += 1; // step over superfluous bytes
TKeyEvent* key = (TKeyEvent*) data;
SeenKeyL(aFrame.iTickCount, *key);
}
break;
case EAmTraceEventEvCapturePointer:
{
data += 1; // step over superfluous bytes
TPointerEvent* pointer = (TPointerEvent*) data;
SeenPointerL(aFrame.iTickCount, *pointer);
}
break;
case EAmTraceEventEvCaptureUnclassified:
{
TInt commandClass = *data++;
TInt opcode = *data++;
SeenUnclassifiedL(aFrame.iTickCount, commandClass, opcode, NULL);
}
break;
case EAmTraceEventEvCaptureRawScan:
{
TBool isKeyUp = *data++;
TInt scanCode = *data++;
SeenRawKeyL(aFrame.iTickCount, isKeyUp, scanCode);
}
break;
default:
// Ignore anything we don't know about.
break;
}
};
}
//
// CBtraceKeyPress::SeenKeyL
// inform any observers that a key event has occured
// & pass a reference back to the key event
//
void CBtraceKeyPress::SeenKeyL(const TBtraceTickCount& aTickCount, const TKeyEvent& aKey)
{
TInt ii = iKeyNotifs.Count();
while (--ii >= 0)
{
MBtraceKeyPressObserver* observer = iKeyNotifs[ii].iObserver;
if (iKeyNotifs[ii].iPersistence == ENotificationOneShot)
{
iKeyNotifs.Remove(ii);
}
observer->HandleKeyPressL(aTickCount, aKey);
}
}
void CBtraceKeyPress::SeenRawKeyL(const TBtraceTickCount& aTickCount, TBool aKeyUp, TInt aScanCode)
{
TInt ii = iRawKeyNotifs.Count();
while (--ii >= 0)
{
MBtraceKeyPressObserver* observer = iRawKeyNotifs[ii].iObserver;
if (iRawKeyNotifs[ii].iPersistence == ENotificationOneShot)
{
iRawKeyNotifs.Remove(ii);
}
observer->HandleRawKeyL(aTickCount, aKeyUp, aScanCode);
}
}
//
// CBtraceKeyPress::SeenPointerL
// inform any observers that a key event has occured
// & pass a reference back to the key event
//
void CBtraceKeyPress::SeenPointerL(const TBtraceTickCount& aTickCount, const TPointerEvent& aPointer)
{
TInt ii = iPointerNotifs.Count();
while (--ii >= 0)
{
MBtraceKeyPressObserver* observer = iPointerNotifs[ii].iObserver;
if (iPointerNotifs[ii].iPersistence == ENotificationOneShot)
{
iPointerNotifs.Remove(ii);
}
observer->HandlePointerPressL(aTickCount, aPointer);
}
}
//
// CBtraceKeyPress::SeenUnclassifiedL
// inform any observers that unknown/unclassified data
// has been received for a specific opcode
void CBtraceKeyPress::SeenUnclassifiedL(const TBtraceTickCount& aTickCount, const TInt aCommandClass, const TInt aOpcode, const TAny* aData)
{
TInt ii = iGenericNotifs.Count();
while (--ii >= 0)
{
MBtraceKeyPressObserver* observer = iGenericNotifs[ii].iObserver;
if (iGenericNotifs[ii].iPersistence == ENotificationOneShot)
{
iGenericNotifs.Remove(ii);
}
observer->HandleUnclassifiedDataL(aTickCount, aCommandClass, aOpcode, aData);
}
}
//
// CBtraceKeyPress::NotifyKeyEvent
// called by the client to register an
// interest in any key events captured
//
EXPORT_C void CBtraceKeyPress::NotifyKeyEventL(MBtraceKeyPressObserver& aObserver)
{
NotifyKeyEventL(aObserver, ENotificationOneShot);
}
EXPORT_C void CBtraceKeyPress::NotifyKeyEventL(MBtraceKeyPressObserver& aObserver, TBtraceNotificationPersistence aPersistence)
{
TKeyPressNotif notify(aObserver, aPersistence);
User::LeaveIfError(iKeyNotifs.Append(notify));
}
EXPORT_C void CBtraceKeyPress::CancelNotifyKeyEvent(MBtraceKeyPressObserver& aObserver)
{
for (TInt i=iKeyNotifs.Count()-1; i>=0; --i)
{
if (iKeyNotifs[i].iObserver == &aObserver)
{
iKeyNotifs.Remove(i);
}
}
}
EXPORT_C void CBtraceKeyPress::NotifyRawKeyEventL(MBtraceKeyPressObserver& aObserver)
{
NotifyRawKeyEventL(aObserver, ENotificationOneShot);
}
EXPORT_C void CBtraceKeyPress::NotifyRawKeyEventL(MBtraceKeyPressObserver& aObserver, TBtraceNotificationPersistence aPersistence)
{
TKeyPressNotif notify(aObserver, aPersistence);
User::LeaveIfError(iRawKeyNotifs.Append(notify));
}
EXPORT_C void CBtraceKeyPress::CancelNotifyRawKeyEvent(MBtraceKeyPressObserver& aObserver)
{
for (TInt i=iRawKeyNotifs.Count()-1; i>=0; --i)
{
if (iRawKeyNotifs[i].iObserver == &aObserver)
{
iRawKeyNotifs.Remove(i);
}
}
}
//
// CBtraceKeyPress::NotifyPointerEvent
// called by the client to register an
// interest in any pointer events captured
//
EXPORT_C void CBtraceKeyPress::NotifyPointerEventL(MBtraceKeyPressObserver& aObserver)
{
NotifyPointerEventL(aObserver, ENotificationOneShot);
}
EXPORT_C void CBtraceKeyPress::NotifyPointerEventL(MBtraceKeyPressObserver& aObserver, TBtraceNotificationPersistence aPersistence)
{
TKeyPressNotif notify(aObserver, aPersistence);
User::LeaveIfError(iPointerNotifs.Append(notify));
}
EXPORT_C void CBtraceKeyPress::CancelNotifyPointerEvent(MBtraceKeyPressObserver& aObserver)
{
for (TInt i=iPointerNotifs.Count()-1; i>=0; --i)
{
if (iPointerNotifs[i].iObserver == &aObserver)
{
iPointerNotifs.Remove(i);
}
}
}
//
// CBtraceKeyPress::NotifyUnclassifiedDataL
// called by the client to register an
// interest in any 'generic' events captured
//
EXPORT_C void CBtraceKeyPress::NotifyUnclassifiedDataL(MBtraceKeyPressObserver& aObserver)
{
NotifyUnclassifiedDataL(aObserver, ENotificationOneShot);
}
EXPORT_C void CBtraceKeyPress::NotifyUnclassifiedDataL(MBtraceKeyPressObserver& aObserver, TBtraceNotificationPersistence aPersistence)
{
TKeyPressNotif notify(aObserver, aPersistence);
User::LeaveIfError(iGenericNotifs.Append(notify));
}
EXPORT_C void CBtraceKeyPress::CancelNotifyUnclassifiedData(MBtraceKeyPressObserver& aObserver)
{
for (TInt i=iGenericNotifs.Count()-1; i>=0; --i)
{
if (iGenericNotifs[i].iObserver == &aObserver)
{
iGenericNotifs.Remove(i);
}
}
}
//
// TKeyPressNotif
// place holder for observers interested in key &/or pointer events
//
CBtraceKeyPress::TKeyPressNotif::TKeyPressNotif(MBtraceKeyPressObserver& aObserver, TBtraceNotificationPersistence aPersistence):
iObserver(&aObserver), iPersistence(aPersistence)
{
}