Week 23 contribution of PDK 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-B1CB6374-2C2B-5D6C-9A7C-6E49D8F235B8" xml:lang="en"><title>Display
Control and Mapping in the Window Server Client</title><shortdesc>ScreenPlay provides support for externally connected displays,
such as TV-out. Previous versions of Symbian and the non-ScreenPlay variant
consider the size of each display to be fixed, assuming it to be built into
the phone. However, for High-Definition Multimedia Interface (HDMI) and composite
video connectors, there is a range of resolutions that can change dynamically.
ScreenPlay provides an optional feature that supports switching between resolutions
at runtime and notifies Window Server clients when there are changes to the
resolution and connectedness. </shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
<p>This topic builds on the introduction in <xref href="GUID-0EBE5733-A267-5F4A-85AD-87C3ECF80731.dita">Dynamic
Resolution Switching</xref>. </p>
<p>The <xref href="GUID-30479BE3-296E-3B4D-914D-B080ABD733E4.dita"><apiname>CWsScreenDevice</apiname></xref> Window Server client-side API has
a <codeph>GetInterface()</codeph> function, which you can use to return pointers
to the <codeph>MDisplayControl</codeph> and <codeph>MDisplayMapping</codeph> interfaces
or null if the interface is not supported. For example: </p>
<codeblock id="GUID-1F87BCBD-F4FB-5C20-8B94-01088F79CD73" xml:space="preserve">// Establish connection and get display control interface.
class CWindowClient : public CBase
{
...
RWsSession iSession;
CWsScreenDevice* iScreenDevice;
MDisplayControl* iDisplayControl;
MDisplayMapping* iDisplayMapping;
TWsDisplayChangedEvent iLastEvent;
}
void CWindowClient::ConstructL(TInt aDisplayNumber)
{
User::LeaveIfError(iSession.Connect());
iScreenDevice = new(ELeave) CWsScreenDevice(iSession);
User::LeaveIfError(iScreenDevice->Construct(aDisplayNumber));
iDisplayControl = iScreenDevice->GetInterface(EDisplayControl);
User::LeaveIfNull(iDisplayControl);
iDisplayMapping = iScreenDevice->GetInterface(EDisplayMapping);
User::LeaveIfNull(iDisplayMapping);
}</codeblock>
<p>In addition, <xref href="GUID-30479BE3-296E-3B4D-914D-B080ABD733E4.dita"><apiname>CWsScreenDevice</apiname></xref> provides the <codeph>IsCurrentModeDynamic()</codeph> and <codeph>IsModeDynamic()</codeph> functions
for querying whether the current screen mode and a given screen mode are dynamic.
If a screen mode is dynamic, the application extent always fills the full
UI space and the area returned by <xref href="GUID-30479BE3-296E-3B4D-914D-B080ABD733E4.dita#GUID-30479BE3-296E-3B4D-914D-B080ABD733E4/GUID-8E1B5729-FD1C-3D4A-AC73-C6364E7D5BBF"><apiname>CWsScreenDevice::SizeInPixels()</apiname></xref> always
matches the actual resolution that is in use. However, the <codeph>MDisplayMapping</codeph> interface
also provides features that enable you to draw outside the application UI
extent. </p>
<section id="GUID-00B91456-0C70-468E-8974-17DE3836849C"> <title>MDisplayControl</title> <p>The <xref href="GUID-0C384D35-77DD-318E-AF3E-C9ED5ADD9D11.dita"><apiname>MDisplayControl</apiname></xref> interface
provides Window Server clients with functions for setting and getting the
current display configuration, getting a list of available resolutions and
enabling display change event notifications (<codeph>EEventDisplayChanged</codeph>).
The following diagram shows the class hierarchy. </p> <fig id="GUID-F9D95387-151F-5725-8BDD-C44A3D333A97">
<title> Display control class diagram </title>
<image href="GUID-68E3609C-3429-5B1C-B8D9-C0EBBACEF357_d0e188429_href.png" placement="inline"/>
</fig> <p>Once you have obtained
the <xref href="GUID-0C384D35-77DD-318E-AF3E-C9ED5ADD9D11.dita"><apiname>MDisplayControl</apiname></xref> interface, you can call <codeph>GetResolutions()</codeph> on
it. For example: </p> <codeblock id="GUID-C82D0166-0E29-5F90-8087-800EDDE2D895" xml:space="preserve">// Get available resolutions
RArray<MDisplayControl::TResolution> resolutions;
User::LeaveIfError(iDisplayControl->GetResolutions(resolutions));
// Use resolution list.
</codeblock> <p>You can use the <codeph>EnableDisplayChangedEvents()</codeph> function
to register for notifications of the <codeph>EEventDisplayChanged</codeph> event.
This is generated when the display device is attached or detached or there
is a change in the current resolution, the resolution list or the current
configuration. For example, this can be generated by a render stage or the
composition engine in response to a hardware event (such as an external display
being connected or disconnected). The event is sometimes, but not always,
triggered by a change in the screen mode. </p> <p>There are therefore two
aspects to the event in that it can be triggered by a display change or a
configuration change. Typically you check the event against the previous one
to see what has changed. </p> <p>The following table provides a summary of
how this event compares to <codeph>EEventScreenDeviceChanged</codeph>. </p> <table id="GUID-50D8232A-E394-590F-A762-79567E4424C3">
<tgroup cols="3"><colspec colname="col0"/><colspec colname="col1"/><colspec colname="col2"/>
<thead>
<row>
<entry>Action</entry>
<entry><codeph>EEventScreenDeviceChanged</codeph> </entry>
<entry><codeph>EEventDisplayChanged</codeph> </entry>
</row>
</thead>
<tbody>
<row>
<entry><p>Screen mode change </p> </entry>
<entry><p>Always triggers this event </p> </entry>
<entry><p>Triggers this event only if it causes a change in the configuration. </p> </entry>
</row>
<row>
<entry><p>Display configuration change </p> </entry>
<entry><p>Generally does not trigger this event </p> </entry>
<entry><p>Generally triggers this event </p> </entry>
</row>
</tbody>
</tgroup>
</table> <p>The following example first registers for notification of <codeph>EEventDisplayChanged</codeph> events
and then changes the screen mode. The second part illustrates a simplified
handler for the events. It demonstrates checking the event against the previous
one to see whether the resolution or configuration has changed. </p> <codeblock id="GUID-E78D2CA8-4C1E-5E19-92EC-7E87B010E5BE" xml:space="preserve">// Establish connection and get display control interface.
iDisplayControl->EnableDisplayChangeEvents(ETrue);
iScreenDevice->SetScreenMode(2); // Number depends on WSINI.INI config.
iScreenDevice->SetAppScreenMode(2); // Ensure application windows are
// shown in the new mode.
...
// Simplified event handler.
TWsEvent event;
iSession.GetEvent(event);
switch (event.Type())
{
case EEventScreenDeviceChanged:
{
TSize screenSize = iScreenDevice->SizeInPixels();
// Re-layout windows for new application screen dimensions
}
break;
case Redraw:
{
// Draw content of window
}
break;
case EEventDisplayChanged:
{
TWsDisplayChangedEvent* newEvent;
newEvent = event.DisplayChanged();
if (newEvent->iResolutionListChangeId !=
iLastEvent.iResolutionListChangeId)
{
// ...
}
if (newEvent->iConfigurationChangeId !=
iLastEvent.iConfigurationChangeId)
{
TDisplayConfiguration config;
User::LeaveIfError(
iDisplayControl->GetConfiguration(config)));
// Handle updated configuration
// May be entirely handled by screen device changed event
}
iLastEvent = *newEvent;
}
break;
}</codeblock> <p>Here is an example of setting a new display resolution: </p> <codeblock id="GUID-B9C0254D-3990-5B41-9F63-1A81D30A3FB6" xml:space="preserve">TDisplayConfiguration config;
config.SetResolution(TSize(1280, 720));
config.SetRotation(MDisplayControl::ERotation180);
User::LeaveIfError(iDisplayControl->SetConfiguration(config));
</codeblock> </section>
<section id="GUID-EF610977-6881-4542-AEFF-C562A7022B21"> <title>MDisplayMapping</title> <p>The <xref href="GUID-BA6FEFAE-8891-3286-A38F-2EA522D7A27E.dita"><apiname>MDisplayMapping</apiname></xref> interface
enables Window Server clients to map between coordinate spaces, allowing for
translation and scaling of coordinates. For example, suppose an application
is to draw a virtual keyboard outside of the application's extent. This requires
knowing the extent of both the application and the full UI area. The application
can use the <xref href="GUID-BA6FEFAE-8891-3286-A38F-2EA522D7A27E.dita"><apiname>MDisplayMapping</apiname></xref> interface to get this information,
so that the virtual keyboard can be drawn within the full UI area but outside
of the application's extent. </p> <fig id="GUID-55BD49C6-9A51-53A7-A587-29A151FACF6B">
<title> Display mapping class diagram </title>
<image href="GUID-7293765E-2B1E-5F0D-B6A8-0E48729DC365_d0e188567_href.png" placement="inline"/>
</fig> <p> </p> <p>The <xref href="GUID-BA6FEFAE-8891-3286-A38F-2EA522D7A27E.dita"><apiname>MDisplayMapping</apiname></xref> interface is very
flexible. UIDs are used to signify the application UI coordinate space, the
full UI space, the composition/display coordinate space (which may be a different
scale to the UI coordinate space) and the Direct Screen Access (DSA) space
(which may match the full UI space, or be offset relative to the application
UI space). </p> <p>The <codeph>MapCoordinates()</codeph> function
takes a rectangle, a source space and a target space and returns the correspondingly
mapped rectangle in the target space. To map a point, use a rectangle with
a width and height of one pixel, because the scaling between UI space and
composition/display space may enlarge (or sometimes reduce) the rectangle’s
size. </p> <p>For example, consider the following diagram, in which the outer
rectangle represents the display area and the inner one represents the application
space (screen mode). </p> <fig id="GUID-6935A7BE-C651-5582-8E2A-11A18CDD531F">
<title>Display area and application extent </title>
<image href="GUID-09142C26-0AFA-510E-836D-010EE07A1549_d0e188596_href.png" placement="inline"/>
</fig> <p>The display resolution is 1280 x 720, the application size is 176
x 208 and a virtual resolution of 426 x 240 has been introduced, which gives
a scaling factor of three in each direction. All pixels are approximately
square, for simplicity. The application area has been centered in the display,
giving an <i>X</i> offset of (426-176)/2 and a <i>Y</i> offset of (240-208)/2,
or (125, 16). </p> <p>To put a window on screen to fill the display, create
a rectangle positioned at (0,0) with a size of the current resolution (426
x 240). Then pass this in with a source space of the full UI and target space
of the application. This results in a rectangle of the same size but at offset
(125,16). </p> <p>In addition, to use an external surface at the real resolution,
pass this rectangle in with a source space of the application UI and a target
space of the composition/display. This results in a rectangle with size of
1280 x 720, which you can then use when creating the surface. Because the
UI surface and external surface are scaled independently, the UI memory requirements
can remain low, even with high resolution video, viewfinder and games. For
an example code snippet, see <xref href="GUID-495EA1C8-E95F-54AE-B4D1-0F463003C2D7.dita">External
Surfaces Overview</xref>. </p> </section>
</conbody><related-links>
<link href="GUID-1F9A47CE-7F4C-52BD-8823-25D5D1BEF42F.dita"><linktext>Window Server
Client-Side Library Concepts</linktext></link>
<link href="GUID-0EBE5733-A267-5F4A-85AD-87C3ECF80731.dita"><linktext>Dynamic Resolution
Switching</linktext></link>
<link href="GUID-1D529BDC-6665-58E2-AB3F-7023D8A84F69.dita"><linktext>The wsini.ini
File Reference</linktext></link>
</related-links></concept>