This document explains how an application can draw to multiple screens. It is aimed at a developer who is already familiar with creating a simple application GUI. In this document, the CONE and WSERV interfaces that support multiple screens are referred to.
The
first screen is indexed as zero and the nth screen is indexed as n-1. The
changes below should be made to the wsini.ini
file which
resides under \epoc32\data\z\system\data
.
[screen 0] [screen 1] [screen n-1]
The secondary screen is supported through TV-OUT
on H4 board. The H4 base port only supports landscape mode with 16 bpp resolution.
The ROM image must be built with -DWITH_TVOUT
as a parameter.
The following code is the basis for the examples that follow.
This is a wsini.ini
file
used to create two fixed screens:
AUTOCLEAR 1 STARTUP \SYS\BIN\Start WINDOWMODE COLOR64K KEYCLICKPLUGIN KeyClickRef TRANSPARENCY MULTIFOCUSPOLICY [screen 0] [screen 1]
This is a class CTRedControl
, which
draws a rectangle on the second screen:
const TInt KSndScreenNo = 1; class CTRedControl : public CCoeControl { public: CTRedControl(){}; ~CTRedControl(){}; void ConstructL(RWindowGroup* aWinGp); private: // From CCoeControl void Draw(const TRect& aRect) const; }; void CTRedControl::ConstructL(RWindowGroup* aWinGp) { CreateWindowL(aWinGp); SetExtent(TPoint(20,20),TSize(100,100)); SetFocus(ETrue); ActivateL(); } void CTRedControl::Draw(const TRect& aRect) const { CWindowGc& gc=SystemGc(); if (IsFocused()) { gc.SetPenColor(KRgbRed); } gc.DrawRect(aRect); }
Using the above example code as a basis, the following methods can be used to facilitate access to multiple screens:
Class RWsSession
provides
the interface to query WSERV about window groups on a particular screen and
the number of screens in the system. The application calls the function below
to get the number of screens supported on the phone:
iCoeEnv->WsSession().NumberOfScreens();
The class CWsScreenDevice
provides the interface to
query the physical limitations of the screen and set the parameters of the
corresponding logical screen. The class RWindowGroup
is the
client side handle to the server side window group. A pair of screen device
and window group is required to draw on a screen.
CONE maintains an array of screen devices and window groups. The screen number is used to index this array to retrieve a particular window group and its corresponding screen device.
The application calls ScreenDevice()
to get
the second screen device:
iCoeEnv->ScreenDevice(KSndScreenNo);
The
application calls RootWin()
to get the window group on the
second screen:
iCoeEnv->RootWin(KSndScreenNo);
The
application calls NumWindowGroups(
)
to
get the number of window groups with EAllPriorities
on the
second screen:
iCoeEnv->WsSession().NumWindowGroups(KSndScreenNo,EAllPriorities);
The application creates a new list and then populates it with WindowGroupList()
to
get the list of window groups with EAllPriorities
on the
second screen:
CArrayFixFlat<TInt>* list = new(ELeave) CArrayFixFlat<TInt>(1); iCoeEnv->WsSession().WindowGroupList(list,KSndScreenNo,EAllPriorities);
The
application calls GetFocusWindowGroup()
to get the window
group that has the keyboard focus on the second screen:
iCoeEnv->WsSession().GetFocusWindowGroup(KSndScreenNo);
Each screen has a default owning window group. The application calls GetDefaultOwningWindow()
to
get the default owning window group on the second screen:
iCoeEnv ->WsSession().GetDefaultOwningWindow(KSndScreenNo);
The application calls GetDefModeMaxNumColors()
to get
the maximum colour and display mode supported on the second screen:
TInt colour, grey; iCoeEnv->WsSession().GetDefModeMaxNumColors(KSndScreenNo,colour,grey);
The
application calls GetColorModeList()
to get the list of colour
modes supported on the second screen:
CArrayFixFlat<TInt>* list = new(Eleave) CArrayFixFlat<TInt>(1); iCoeEnv ->WsSession().GetColorModeList(KSndScreenNo, list);
Creating a control on a particular screen
A window group is associated with a screen device,
which in turn is associated to a screen. A control is associated with a window
group. Therefore a control is constructed on the second screen using the function
below, in the control’s ConstructL()
:
CTRedControl redControl=new(Eleave) CTRedControl(); redControl->ConstructL(CCoeEnv::Static()->RootWin(KSndScreenNo));
The
class CWindowGc
provides the interface for the application’s
window graphics context and can be activated on any window in the application.
This means that it can be used on any screen on the phone. The function call
below is used to find the screen device on which the graphics context was
last activated.
CCoeEnv::Static()->SystemGc().Device();
There
are two focus policies supported by WSERV. The default focus policy is that
there is only the focused window group on the focused screen receives key
events. The new policy is that any window group can receive key events and
can be switched on by defining the keyword MULTIFOCUSPOLICY
in
the wsini.ini
file.
The first screen created is also the primary screen in the system. It is important to note that only the primary screen can respond to pointer events. This is due to the fact that the kernel supports only one screen digitiser.
Due to limitations in the legacy implementation of Cone and the control sets implemented on top of it (for example, Eikon, Avkon or Qikon), it is nearly impossible to make the same application draw Cone-based UI on two different screens at the same time. However, a secondary screen can be used to draw non-Cone-based graphics (for example, a picture or PowerPoint slide-show, or a UI not using Cone for its widgets). If it must appear as if an application supports displaying itself on the secondary screen, then this can be done by moving that UI into a second application instance. This second instance could be a server application that only acts as a slave UI of the main application. In any case, that secondary application instance would have to set the secondary screen as its default screen. There are two main problems:
All controls have to be associated with a window, and window owning controls do not currently try to make sure that the window they create is associated with the screen that they should appear on. This means, for example, that a pop-out window created by a choice list widget will always appear on the application's primary screen, rather than on the screen on which the choice list itself is located.
None of the legacy
widget implementations referencing the screen device take into consideration
that there might be more than one screen on the device. These include CCoeControl
's SetExtentToWholeScreen()
, SetCornerAndSize()
, AccumulatedZoom()
, PositionRelativeToScreen()
,
and CEikAppUi's ClientRect()
and ApplicationRect()
).
Neither of these problems can be solved currently.