Symbian3/SDK/Source/GUID-A7E39E45-02BA-58F4-8807-EFABB8F6E5D0.dita
author Dominic Pinkman <dominic.pinkman@nokia.com>
Fri, 11 Jun 2010 12:39:03 +0100
changeset 8 ae94777fff8f
permissions -rw-r--r--
Week 23 contribution of SDK documentation content. See release notes for details. Fixes bugs Bug 2714, Bug 462.

<?xml version="1.0" encoding="utf-8"?>
<!-- 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 the License 
"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: 
-->
<!DOCTYPE concept
  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
<concept id="GUID-A7E39E45-02BA-58F4-8807-EFABB8F6E5D0" xml:lang="en"><title>Processing
pen events</title><shortdesc>This topic describes various events processed by Pen or Mouse.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
<section id="GUID-FB1CCFC8-F70A-4D6E-BF27-3652413359AE"><title>Simple drag
events</title> <p>In order for the FEP control to receive drag events occurring
in its window, all that is needed is to call <codeph>EnableDragEvents()</codeph> in
the control’s construction routine. Having done that, the control will receive
drag events as calls to its <codeph>HandlePointerEventL()</codeph> virtual
function. The <codeph>iType</codeph> member of <codeph>HandlePointerEventL()</codeph> ’s <codeph>aPointerEvent</codeph> parameter
is set to <codeph>TPointerEvent::EDrag</codeph> for drag events. </p> <p>This
method makes heavy use of IPC (inter-process communication) as the user drags
the mouse/pen around the FEP control’s window, which means that the FEP does
not get drag events at optimum frequency. This may be problematic for something
like handwriting recognition software. If there is a requirement to follow
the path traced by the mouse/pen as closely as possible, another method can
be used, namely buffered drag events. </p> </section>
<section id="GUID-739BD481-1EAF-42B3-B0F0-8C50D01CE488"><title>Buffered drag
events</title> <p>The advantage of buffered drag events over simple drag events
is that the window server client can receive multiple mouse/pen positions
in a single event, which reduces the IPC overhead. To enable this, the following
code needs to be called in the FEP control’s construction routine: </p> <codeblock id="GUID-3247B04E-05FD-534E-8F8D-C15DE2FEA33C" xml:space="preserve">User::LeaveIfError(DrawableWindow()-&gt;AllocPointerMoveBuffer(ENumberOfPointsInBuffer, 0));</codeblock> <p>This assumes that <codeph>ENumberOfPointsInBuffer</codeph> has been defined
elsewhere; TFEP2Plugin sets this constant to 32. The control
then receives drag events as calls to its <codeph>HandlePointerBufferReadyL()</codeph> virtual
function, rather than as calls to <codeph>HandlePointerEventL()</codeph>.
To retrieve these drag events, include the following code at the start of
the FEP control’s <codeph>HandlePointerBufferReadyL()</codeph> function: </p> <codeblock id="GUID-18B4F1EB-7090-5C6C-9EB4-98F6CF37FA88" xml:space="preserve">TPoint arrayOfPoints[ENumberOfPointsInBuffer];
TPtr8 bufferOfPoints(REINTERPRET_CAST(TUint8*, arrayOfPoints), 0, ENumberOfPointsInBuffer*sizeof(TPoint));
User::LeaveIfError(DrawableWindow()-&gt;RetrievePointerMoveBuffer(bufferOfPoints));
const TInt numberOfPointsInBuffer=bufferOfPoints.Length()/sizeof(TPoint);</codeblock> <p>Having
done that, <codeph>numberOfPointsInBuffer</codeph> of <codeph>arrayOfPoints</codeph> can
be used for whatever purpose the FEP requires, for example handwriting recognition.
Note that <codeph>AllocPointerMoveBuffer()</codeph> ’s counterpart <codeph>FreePointerMoveBuffer()</codeph> does
not need to be called in the FEP control’s destructor as this happens automatically
when the control’s window is destroyed. </p></section>
<section id="GUID-9E66280C-65AE-4AB1-9F00-65FBE6CF218D"><title>Intercepting
pen events anywhere on the screen</title> <p>In order to intercept mouse/pen
events anywhere on the screen it is necessary to write a plugin into the window
server (WSERV). This is in addition to the FEP plugin which plugs into the
FEP architecture. TFEP2plugin provides a working example of this (TFEP2be).
The details of how to write a window server plugin DLL are beyond the scope
of this document because the APIs involved belong to the window server. See <xref href="GUID-029C644B-BE0F-37C6-95E2-D27F974E6AD3.dita"><apiname>CAnim</apiname></xref> and <codeph>CAnimDll</codeph> in
the SDK for information on this. The way mouse/pen events can be intercepted
is by returning <codeph>ETrue</codeph> from the function overriding <codeph>MEventHandler::OfferRawEvent()</codeph> (<xref href="GUID-029C644B-BE0F-37C6-95E2-D27F974E6AD3.dita"><apiname>CAnim</apiname></xref> derives
from <xref href="GUID-F1B47E38-4585-3903-93C7-0BCB075465AA.dita"><apiname>MEventHandler</apiname></xref>). Events which are handled in this way
will not be sent to the relevant window server client, in other words, the
client who would otherwise have received this event. </p> <p>The sprite feature
of the window server (<xref href="GUID-75C09150-E93B-323D-AFBF-E42C7BD78229.dita"><apiname>RWsSprite</apiname></xref>, defined in <filepath>epoc32\include\W32STD.H</filepath>)
can be used to display to the user the path on the screen being traced out
by their mouse/pen movements. However, care should be taken when using sprites
for this purpose. Sprites use bitmaps, which in this context would need to
be the size of the screen. Because each running application has its own FEP,
which would have its own sprite, which in turn would have its own screen-sized
bitmap, it becomes apparent that some optimization must be done to avoid huge
amounts of memory being consumed. TFEP2Plugin solves this problem by using
a single bitmap shared between each sprite. It uses the 4 byte thread-local
storage of the window server plugin DLL to store the identifier of this bitmap.
The code which constructs the sprite is protected by a mutex (<xref href="GUID-C0FEA3A0-7DD3-3B87-A919-CB973BC05766.dita"><apiname>RMutex</apiname></xref>,
defined in <filepath>epoc32\include\E32STD.H</filepath>) as it tests to see
if the bitmap to be used by the sprite has already been created by a FEP running
the same code in another thread. If it has then it merely calls <codeph>CFbsBitmap::Duplicate()</codeph> which
simply increments the existing bitmap’s reference count, thus only one large
bitmap is created rather than one per running application. </p> <p>Intercepting
mouse/pen events anywhere on the screen is likely to be most useful to handwriting-interpreting
FEPs. Given that using this feature involves two polymorphic DLLs (plugging
into different frameworks) running in two separate threads in separate processes,
there is a choice regarding where the bulk of the FEP’s processing is done.
The advantage of the processing being done outside of the window server process
(in other words, in the FEP architecture plugin) is that bugs in the processing
code (for instance crashing or hanging) do not affect the whole machine. The
advantage of the processing being done inside the window server process (in
other words, in the window server plugin) is that the long lists of screen
positions (tracing out the path of where the user has dragged the mouse/pen)
do not need to be communicated between processes. </p></section>
</conbody></concept>