How to - Multiple screens

Introduction

Purpose and scope

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.

How to create multiple screens

Configuration

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]

Building the ROM image

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.

Example Code

Setup example code

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);     
    }

Windows on multiple screens

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));

Graphics Context

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();

Window Group Focus Policy

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.

Limitations

Pointer Events

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.

Cone-Based UI

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:

  1. 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.

  2. 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.