Wiley.Games.on.Symbian.OS.A.Handbook.for.Mobile.Development.Apr.2008 (779888), страница 21
Текст из файла (страница 21)
Aslong as strong UI dependencies are avoided, then a control can be portedbetween UI platforms with ease.Figure 3.3 also serves to illustrate that different parts of the screen canbe owned by different processes. The status bar is usually owned by asystem process and drawn independently of the application that has themain focus. The system component that sorts out which process needs todraw what, and when, is the Symbian OS window server.3.5.2 The Symbian OS Window ServerThe Symbian OS window server (commonly abbreviated to WSERV) hastwo key roles.
It routes screen pointer events and keypad events to thecorrect window, and it handles the redrawing of regions of the screen,enabling partial updates of the screen. WSERV has many sophisticatedservices for rendering UI controls and for establishing transitions between70GRAPHICS ON SYMBIAN OSapplications, applying transparency effects to windows and so on. Butfor most kinds of games, the complex facilities provided by WSERV canbe ignored since they are mostly targeted at UI frameworks and systemcode.The two main types of drawing services that WSERV provides to thegames programmer are:• a graphics context for drawing graphics clipped to a window onscreen• direct screen access (DSA) for custom drawing code.In the first instance, WSERV takes a very active role in executing andclipping the drawing code to the correct area of screen.
For DSA, WSERVtakes a back seat, allowing an application to draw what it wants in aspecified region. WSERV only intervenes when an area of the screenbeing managed by DSA is obscured by another window for which it isresponsible.The rest of this chapter deals with writing custom controls. For morein depth information on the workings of WSERV and an introductionto writing GUI applications using the Symbian OS application framework, please see the recent Symbian Press book Symbian OS C++ forMobile Phones: Volume 3 by Richard Harrison and Mark Shackman.The book covers in depth how windows, controls, and redraws workon Symbian OS v9.
A lot of the information will be relevant if you arewriting games which use standard UI controls and elements from UIQ,S60 and MOAP, but it is beyond the scope of this chapter, which isspecifically about custom controls. If you are new to Symbian graphicsprogramming, the best way to understand the basic graphics servicesis to create a new GUI application in the Carbide.c++ IDE. Using theapplication wizard, find the Draw() function, which will have thedefault implementation of drawing ‘Hello World!’ to the screen, andstart playing around with the different drawing functions available inCGraphicsContext.From a games perspective, it is important to have a basic grasp of howWSERV deals with draws and redraws, since a game has to co-exist withother applications.
The next section covers basic drawing.3.5.3 Drawing a ControlStandard Application Drawing API OverviewLibraries to link againstws32.lib cone.libHeader files to includews32.h coecntrl.hA PRIMER ON DRAWING ON SYMBIAN OS71Standard Application Drawing API OverviewRequired platform security capabilities NoneKey classesCCoeControl, CWindowGcEach area on the screen where an application wishes to draw must havean associated window.
A handle to a window is represented by the classRWindow. It’s possible to create a RWindow object from an applicationor a console-based application, and handle drawing events directly, butfor most uses, a CCoeControl-derived custom control is recommended,because it simplifies the API for redrawing to a window.Typically, a game’s main screen will be a CCoeControl-derived classwhich will either fill the application area (meaning that the status bar isstill visible as shown in Figure 3.3) or will fill the entire screen. As soon asthe control is made visible, the Draw() function will be called in orderto render the initial state of the control.
The code fragment below showshow a CCoeControl object clears itself.void CGfxWorkbenchAppView::Draw(const TRect&{// Get the standard graphics contextCWindowGc& gc = SystemGc();aRect ) const// Clear the screengc.Clear(aRect);}This code introduces a class called CWindowGc, which is a typeof graphics context, and will be discussed later in this section. TheDraw() function must be quick, and is a const, non-leaving function,which means that it cannot allocate memory or modify the state of theapplication or game.
The binding contract of the Draw() method is thatit draws some model or state and, if the state is unchanged between twocalls of Draw(), the results should be exactly the same.A call to Draw() can be initiated by the application itself or by theoperating system:• Application-initiated drawing: after the game state has changed, thegame can call DrawNow() on the CCoeControl, which results inDraw() being called.• System-initiated drawing: for example, when the stacking order ofwindows changes so that the game comes to the foreground, Draw()will be called automatically by the system in order to refresh thedisplay.72GRAPHICS ON SYMBIAN OSIn fact, on some systems, windows may have their drawing commandscached in WSERV’s redraw store, preventing redraw requests from evergetting to the application. For this reason, it is vital that these drawrequests don’t modify the underlying game state.3.5.4 Handling a RedrawImagine the leftmost screen in Figure 3.4 as a full screen CONE4 control.Since this is a multitasking device, an incoming event or trigger may causethe control to be obscured at any time as illustrated by the ‘Battery Low!’alert dialog shown in the middle screen.
Any drawing to the heart controlwhile the battery low indicator is in the foreground will be clipped and sothere is no danger of overwriting the pixels of the dialog area. However,when the dialog window closes, shown in the screen on the right, thearea previously occupied by the dialog is marked as invalid.Battery Low!Figure 3.4 A sequence showing how a region of a control becomes invalidInvalid regions means that WSERV must locate each window thatintersects with that region and make a request to the window’s ownerto repaint the affected area.
In the case shown in Figure 3.4, no othercontrols are visible and so only the heart control will have its CCoeControl::Draw(TRect& aRect) method called.When a redraw is initiated by the system, the control must ensure thatall pixels in the invalid region represented by aRect are repainted inorder to maintain the integrity of the display. Typically, games renderframes to an off-screen bitmap and this makes it trivial to copy only theinvalid region back to the screen.4The Symbian OS control framework is sometimes referred to as CONE (as a contractionof the phrase ‘control environment.’) CONE provides a framework for creating user interfacecontrols, a framework for applications to handle user interface events, and environmentutilities for control creation and access to windowing functionality.A PRIMER ON DRAWING ON SYMBIAN OS733.5.5 Graphics ContextIn section 3.5.3, we saw basic use of a graphics context in the code.
Thecontrol simply called Clear() in order to blank the control, but thereare many more drawing functions provided.A graphics context is a fairly standard notion across different computingplatforms. It encapsulates information about the way things are drawn. Agraphics context API is always stateful in that information about things,like pen size and brush color, are built up by issuing separate commands.The Symbian OS class hierarchy for graphics contexts is shown inFigure 3.5. Class CGraphicsContext provides the main interface fordrawing geometric shapes and text.
Methods are provided for drawing andfilling various shapes (points, lines, polylines, arcs, rectangles, polygons,ellipses, rounded rectangles and pie slices), and for drawing text.CGraphicsContextCBitmapContextCWindowGcCFbsBitGcFigure 3.5 Symbian OS graphics context derivationIn practice, all graphics contexts used by a game will be a type ofCBitmapContext, which is a specialized graphics context adding thefollowing capabilities:• clearing and copying rectangular areas• bitmap block transfer.74GRAPHICS ON SYMBIAN OSCWindowGc is the window server client-side API which provides oneimplementation of a CBitmapContext. Flexible drawing code can bedeveloped by writing against the base class API CBitmapContext.
Thesame API is also used to draw directly to a bitmap based graphics context(CFbsBitGc), so drawing code can easily be re-used from one methodto the other.3.5.6 Window Graphics ContextTo understand what the window server does, let’s consider the algorithmfor drawing a simple line to a bitmap in memory.When calling CBitmapContext::DrawLine(aStartPoint,aEndPoint), the current pen color and width are retrieved from thegraphics context and the pixels corresponding to the line are colored in,overwriting the pixel values of the bitmap as the line is drawn.
A bitmapin memory is never obscured (by a window), and so clipping is a matterof containing drawing within the bitmap rectangle.The algorithm for drawing to a window (via CWindowGc) is morecomplex:• a window/control may be partially obscured which requires multipleclipping• a window may also be semi-transparent and so drawing operations may need to be combined with drawing code for backgroundwindows, in order to get the final pixel values for the screen.Symbian’s WSERV implementation contains a drawing commandbuffer to store commands in the application’s process before transferringthem in bulk for WSERV to execute. During a Draw(), the commandbuffer is filled with drawing commands and usually flushed by the UIframework after Draw() has been called on a control.