Question

i'm studying this source base. Basically this is an Anim server client for Symbian 3rd edition for the purpose of grabbing input events without consuming them in a reliable way.

If you spot this line of the server, here it is basically setting the RProperty value (apparently to an increasing counter); it seems no actual processing of the input is done.

inside this client line, the client is supposed to be receiving the notification data, but it only calls Attach.

my understanding is that Attach is only required to be called once, but is not clear in the client what event is triggered every time the server sets the RProperty

How (and where) is the client supposed to access the RProperty value?

Was it helpful?

Solution

After Attaching the client will somewhere Subscribe to the property where it passes a TRequestStatus reference. The server will signal the request status property via the kernel when the asynchronous event has happened (in your case the property was changed). If your example source code is implemented in the right way, you will find an active object (AO; CActive derived class) hanging around and the iStatus of this AO will be passed to the RProperty API. In this case the RunL function of the AO will be called when the property has been changed.

It is essential in Symbian to understand the active object framework and quite few people do it actually. Unfortunately I did not find a really good description online (they are explained quite well in Symbian OS Internals book) but this page at least gives you a quick example.

Example

In the ConstructL of your CMyActive subclass of CActive:

CKeyEventsClient* iClient;
RProperty         iProperty;
// ...

void CMyActive::ConstructL() 
    {
    RProcess myProcess;
    TSecureId propertyCategory = myProcess.SecureId();
        // avoid interference with other properties by defining the category
        // as a secure ID of your process (perhaps it's the only allowed value)
    TUint propertyKey = 1; // whatever you want

    iClient = CKeyEventsClient::NewL(propertyCategory, propertyKey, ...);
    iClient->OpenNotificationPropertyL(&iProperty);

    // ...

    CActiveScheduler::Add(this);
    iProperty.Subscribe(iStatus);
    SetActive();
    }

Your RunL will be called when the property has been changed:

void CMyActive::RunL()
    {
    if (iStatus.Int() != KErrCancel) User::LeaveIfError(iStatus.Int());
         // forward the error to RunError

    // "To ensure that the subscriber does not miss updates, it should
    // re-issue a subscription request before retrieving the current value 
    // and acting on it." (from docs)
    iProperty.Subscribe(iStatus);

    TInt value; // this type is passed to RProperty::Define() in the client
    TInt err = iProperty.Get(value);
    if (err != KErrNotFound) User::LeaveIfError(err);

    SetActive();
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top