qdoc: Removed three qdoc files for qws example papges

qws is no longer relevant. These pages are now deleted:
deleted:    mousecalibration.qdoc
deleted:    simpledecoration.qdoc
deleted:    svgalib.qdoc

Change-Id: I6ca77627cc6c018245cf16047b52c1145721e175
Reviewed-by: Casper van Donderen <casper.vandonderen@nokia.com>
bb10
Martin Smith 2012-07-19 12:55:37 +02:00 committed by Qt by Nokia
parent eba0efe10e
commit 2089967513
3 changed files with 0 additions and 790 deletions

View File

@ -1,193 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** GNU Free Documentation License
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms
** and conditions contained in a signed written agreement between you
** and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\example qws/mousecalibration
\title Mouse Calibration Example
The Mouse Calibration example demonstrates how to write a simple
program using the mechanisms provided by the QWSMouseHandler class
to calibrate the mouse handler in \l{Qt for Embedded Linux}.
Calibration is the process of mapping between physical
(i.e. device) coordinates and logical coordinates.
The example consists of two classes in addition to the main program:
\list
\li \c Calibration is a dialog widget that retrieves the device coordinates.
\li \c ScribbleWidget is a minimal drawing program used to let the user
test the new mouse settings.
\endlist
First we will review the main program, then we will take a look at
the \c Calibration class. The \c ScribbleWidget class is only a
help tool in this context, and will not be covered here.
\section1 The Main Program
The program starts by presenting a message box informing the user
of what is going to happen:
\snippet examples/qws/mousecalibration/main.cpp 0
The QMessageBox class provides a modal dialog with a range of
different messages, roughly arranged along two axes: severity and
complexity. The message box has a different icon for each of the
severity levels, but the icon must be specified explicitly. In our
case we use the default QMessageBox::NoIcon value. In addition we
use the default complexity, i.e. a message box showing the given
text and an \gui OK button.
At this stage in the program, the mouse could be completely
uncalibrated, making the user unable to press the \gui OK button. For
that reason we use the static QTimer::singleShot() function to
make the message box disappear after 10 seconds. The QTimer class
provides repetitive and single-shot timers: The single shot
function calls the given slot after the specified interval.
\snippet examples/qws/mousecalibration/main.cpp 1
Next, we create an instance of the \c Calibration class which is a
dialog widget retrieving the required sample coordinates: The
dialog sequentially presents five marks for the user to press,
storing the device coordinates for the mouse press events.
\snippet examples/qws/mousecalibration/main.cpp 2
When the calibration dialog returns, we let the user test the new
mouse settings by drawing onto a \c ScribbleWidget object. Since
the mouse still can be uncalibrated, we continue to use the
QMessageBox and QTimer classes to inform the user about the
program's progress.
An improved calibration tool would let the user choose between
accepting the new calibration, reverting to the old one, and
restarting the calibration.
\section1 Calibration Class Definition
The \c Calibration class inherits from QDialog and is responsible
for retrieving the device coordinates from the user.
\snippet examples/qws/mousecalibration/calibration.h 0
We reimplement QDialog's \l {QDialog::exec()}{exec()} and \l
{QDialog::accept()}{accept()} slots, and QWidget's \l
{QWidget::paintEvent()}{paintEvent()} and \l
{QWidget::mouseReleaseEvent()}{mouseReleaseEvent()} functions.
In addition, we declare a couple of private variables, \c data and
\c pressCount, holding the \c Calibration object's number of mouse
press events and current calibration data. The \c pressCount
variable is a convenience variable, while the \c data is a
QWSPointerCalibrationData object (storing the physical and logical
coordinates) that is passed to the mouse handler. The
QWSPointerCalibrationData class is simply a container for
calibration data.
\section1 Calibration Class Implementation
In the constructor we first ensure that the \c Calibration dialog
fills up the entire screen, has focus and will receive mouse
events (the latter by making the dialog modal):
\snippet examples/qws/mousecalibration/calibration.cpp 0
Then we initialize the \l{QWSPointerCalibrationData::}{screenPoints}
array:
\snippet examples/qws/mousecalibration/calibration.cpp 1
In order to specify the calibration, the
\l{QWSPointerCalibrationData::screenPoints}{screenPoints} array must
contain the screen coordinates for the logical positions
represented by the QWSPointerCalibrationData::Location enum
(e.g. QWSPointerCalibrationData::TopLeft). Since non-linearity is
expected to increase on the edge of the screen, all points are
kept 10 percent within the screen. The \c qt_screen pointer is a
reference to the screen device. There can only be one screen
device per application.
\snippet examples/qws/mousecalibration/calibration.cpp 2
Finally, we initialize the variable which keeps track of the number of
mouse press events we have received.
\snippet examples/qws/mousecalibration/calibration.cpp 3
The destructor is trivial.
\snippet examples/qws/mousecalibration/calibration.cpp 4
The reimplementation of the QDialog::exec() slot is called from
the main program.
First we clear the current calibration making the following mouse
event delivered in raw device coordinates. Then we call the
QWidget::grabMouse() function to make sure no mouse events are
lost, and the QWidget::activateWindow() function to make the
top-level widget containing this dialog, the active window. When
the call to the QDialog::exec() base function returns, we call
QWidget::releaseMouse() to release the mouse grab before the
function returns.
\snippet examples/qws/mousecalibration/calibration.cpp 5
The QWidget::paintEvent() function is reimplemented to receive the
widget's paint events. A paint event is a request to repaint all
or parts of the widget. It can happen as a result of
QWidget::repaint() or QWidget::update(), or because the widget was
obscured and has now been uncovered, or for many other reasons.
In our reimplementation of the function we simply draw a cross at
the next point the user should press.
\snippet examples/qws/mousecalibration/calibration.cpp 6
We then reimplement the QWidget::mouseReleaseEvent() function to
receive the widget's move events, using the QMouseEvent object
passed as parameter to find the coordinates the user pressed, and
update the QWSPointerCalibrationData::devPoints array.
In order to complete the mapping between logical and physical
coordinates, the \l
{QWSPointerCalibrationData::devPoints}{devPoints} array must
contain the raw device coordinates for the logical positions
represented by the QWSPointerCalibrationData::Location enum
(e.g. QWSPointerCalibrationData::TopLeft)
We continue by drawing the next cross, or close the dialog by
calling the QDialog::accept() slot if we have collected all the
required coordinate samples.
\snippet examples/qws/mousecalibration/calibration.cpp 7
Our reimplementation of the QDialog::accept() slot simply activate
the new calibration data using the QWSMouseHandler::calibrate()
function. We also use the Q_ASSERT() macro to ensure that the number
of required samples are present.
*/

View File

@ -1,252 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** GNU Free Documentation License
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms
** and conditions contained in a signed written agreement between you
** and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\example qws/simpledecoration
\title Simple Decoration Example
\ingroup qt-embedded
The Simple Decoration example shows how to create a custom window decoration
for embedded applications.
\image embedded-simpledecoration-example.png
By default, Qt for Embedded Linux applications display windows with one of
the standard window decorations provided by Qt which are perfectly suitable
for many situations. Nonetheless, for certain applications and devices, it
is necessary to provide custom window decorations.
In this document, we examine the fundamental features of custom window
decorations, and create a simple decoration as an example.
\section1 Styles and Window Decorations
On many platforms, the style used for the contents of a window (including
scroll bars) and the style used for the window decorations (the title bar,
window borders, close, maximize and other buttons) are handled differently.
This is usually because each application is responsible for rendering the
contents of its own windows and the window manager renders the window
decorations.
Although the situation is not quite like this on Qt for Embedded Linux
because QApplication automatically handles window decorations as well,
there are still two style mechanisms at work: QStyle and its associated
classes are responsible for rendering widgets and subclasses of QDecoration
are responsible for rendering window decorations.
\image embedded-simpledecoration-example-styles.png
Three decorations are provided with Qt for Embedded Linux: \e default is
a basic style, \e windows resembles the classic Windows look and feel,
and \e styled uses the QStyle classes for QMdiSubWindow to draw window
decorations. Of these, \e styled is the most useful if you want to impose
a consistent look and feel, but the window decorations may be too large
for some use cases.
If none of these built-in decorations are suitable, a custom style can
easily be created and used. To do this, we simply need to create a
subclass of QDecorationDefault and apply it to a QApplication instance
in a running application.
\section1 MyDecoration Class Definition
The \c MyDecoration class is a subclass of QDecorationDefault, a subclass
of QDecoration that provides reasonable default behavior for a decoration:
\snippet examples/qws/simpledecoration/mydecoration.h decoration class definition
We only need to implement a constructor and reimplement the
\l{QDecorationDefault::}{region()} and \l{QDecorationDefault::}{paint()}
functions to provide our own custom appearance for window decorations.
To make things fairly general, we provide a number of private variables
to hold parameters which control certain aspects of the decoration's
appearance. We also define some data structures that we will use to
relate buttons in the window decorations to regions.
\section1 MyDecoration Class Implementation
In the constructor of the \c MyDecoration class, we set up some default
values for the decoration, specifying a thin window border, a title
bar that is just taller than the buttons it will hold, and we create a
list of buttons that we support:
\snippet examples/qws/simpledecoration/mydecoration.cpp constructor start
We map each of these Qt::WindowFlags to QDecoration::DecorationRegion
enum values to help with the implementation of the
\l{#Finding Regions}{region() function implementation}.
\snippet examples/qws/simpledecoration/mydecoration.cpp map window flags to decoration regions
In this decoration, we implement the buttons used in the decoration as
pixmaps. To help us relate regions of the window to these, we define
mappings between each \l{QDecoration::}{DecorationRegion} and its
corresponding pixmap for two situations: when a window is shown normally
and when it has been maximized. This is purely for cosmetic purposes.
\snippet examples/qws/simpledecoration/mydecoration.cpp map decoration regions to pixmaps
We finish the constructor by defining the regions for buttons that we
understand. This will be useful when we are asked to give regions for
window decoration buttons.
\snippet examples/qws/simpledecoration/mydecoration.cpp constructor end
\section2 Finding Regions
Each decoration needs to be able to describe the regions used for parts
of the window furniture, such as the close button, window borders and
title bar. We reimplement the \l{QDecorationDefault::}{region()} function
to do this for our decoration. This function returns a QRegion object
that describes an arbitrarily-shaped region of the screen that can itself
be made up of several distinct areas.
\snippet examples/qws/simpledecoration/mydecoration.cpp region start
The function is called for a given \e widget, occupying a region specified
by \e insideRect, and is expected to return a region for the collection of
\l{QDecoration::}{DecorationRegion} enum values supplied in the
\e decorationRegion parameter.
We begin by figuring out how much space in the decoration we will need to
allocate for buttons, and where to place them:
\snippet examples/qws/simpledecoration/mydecoration.cpp calculate the positions of buttons based on the window flags used
In a more sophisticated implementation, we might test the \e decorationRegion
supplied for regions related to buttons and the title bar, and only perform
this space allocation if asked for regions related to these.
We also use the information about the area occupied by buttons to determine
how large an area we can use for the window title:
\snippet examples/qws/simpledecoration/mydecoration.cpp calculate the extent of the title
With these basic calculations done, we can start to compose a region, first
checking whether we have been asked for all of the window, and we return
immediately if so.
\snippet examples/qws/simpledecoration/mydecoration.cpp check for all regions
We examine each decoration region in turn, adding the corresponding region
to the \c region object created earlier. We take care to avoid "off by one"
errors in the coordinate calculations.
\snippet examples/qws/simpledecoration/mydecoration.cpp compose a region based on the decorations specified
Unlike the window borders and title bar, the regions occupied by buttons
many of the window decorations do not occupy fixed places in the window.
Instead, their locations depend on which other buttons are present.
We only add regions for buttons we can handle (defined in the \c stateRegions)
member variable, and only for those that are present (defined in the
\c buttons hash).
\snippet examples/qws/simpledecoration/mydecoration.cpp add a region for each button only if it is present
The fully composed region can then be returned:
\snippet examples/qws/simpledecoration/mydecoration.cpp region end
The information returned by this function is used when the decoration is
painted. Ideally, this function should be implemented to perform all the
calculations necessary to place elements of the decoration; this makes
the implementation of the \c paint() function much easier.
\section2 Painting the Decoration
The \c paint() function is responsible for drawing each window element
for a given widget. Information about the decoration region, its state
and the widget itself is provided along with a QPainter object to use.
The first check we make is for a call with no regions:
\snippet examples/qws/simpledecoration/mydecoration.cpp paint start
We return false to indicate that we have not painted anything. If we paint
something, we must return true so that the window can be composed, if
necessary.
Just as with the \c region() function, we test the decoration region to
determine which elements need to be drawn. If we paint anything, we set
the \c handled variable to true so that we can return the correct value
when we have finished.
\snippet examples/qws/simpledecoration/mydecoration.cpp paint different regions
Note that we use our own \c region() implementation to determine where
to draw decorations.
Since the \c region() function performs calculations to place buttons, we
can simply test the window flags against the buttons we support (using the
\c buttonHintMap defined in the constructor), and draw each button in the
relevant region:
\snippet examples/qws/simpledecoration/mydecoration.cpp paint buttons
Finally, we return the value of \c handled to indicate whether any painting
was performed:
\snippet examples/qws/simpledecoration/mydecoration.cpp paint end
We now have a decoration class that we can use in an application.
\section1 Using the Decoration
In the \c main.cpp file, we set up the application as usual, but we also
create an instance of our decoration and set it as the standard decoration
for the application:
\snippet examples/qws/simpledecoration/main.cpp create application
This causes all windows opened by this application to use our decoration.
To demonstrate this, we show the analog clock widget from the
\l{Analog Clock Example}, which we build into the application:
\snippet examples/qws/simpledecoration/main.cpp start application
The application can be run either
\l{Running Qt for Embedded Linux Applications}{as a server or a client
application}. In both cases, it will use our decoration rather than the
default one provided with Qt.
\section1 Notes
This example does not cache any information about the state or buttons
used for each window. This means that the \c region() function calculates
the locations and regions of buttons in cases where it could re-use
existing information.
If you run the application as a window server, you may expect client
applications to use our decoration in preference to the default Qt
decoration. However, it is up to each application to draw its own
decoration, so this will not happen automatically. One way to achieve
this is to compile the decoration with each application that needs it;
another way is to build the decoration as a plugin, using the
QDecorationPlugin class, and load it into the server and client
applications.
*/

View File

@ -1,345 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** GNU Free Documentation License
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms
** and conditions contained in a signed written agreement between you
** and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\example qws/svgalib
\title Accelerated Graphics Driver Example
The Accelerated Graphics Driver example shows how you can write
your own accelerated graphics driver and \l {add your graphics
driver to Qt for Embedded Linux}. In \l{Qt for Embedded Linux},
painting is a pure software implementation and is normally performed
in two steps:
The clients render each window onto a corresponding surface
(stored in memory) using a paint engine, and then the server uses
the graphics driver to compose the surface images and copy them to
the screen. (See the \l{Qt for Embedded Linux Architecture} documentation
for details.)
The rendering can be accelerated in two ways: Either by
accelerating the copying of pixels to the screen, or by
accelerating the explicit painting operations. The first is done
in the graphics driver implementation, the latter is performed by
the paint engine implementation. Typically, both the pixel copying
and the painting operations are accelerated using the following
approach:
\list 1
\li \l {Step 1: Creating a Custom Graphics Driver}
{Creating a Custom Graphics Driver}
\li \l {Step 2: Implementing a Custom Raster Paint Engine}
{Implementing a Custom Paint Engine}
\li \l {Step 3: Making the Widgets Aware of the Custom Paint
Engine}{Making the Widgets Aware of the Custom Paint Engine}
\endlist
After compiling the example code, install the graphics driver
plugin with the command \c {make install}. To start an application
using the graphics driver, you can either set the environment
variable \l QWS_DISPLAY and then run the application, or you can
just run the application using the \c -display switch:
\snippet doc/src/snippets/code/doc_src_examples_svgalib.qdoc 0
\table
\header \li SVGAlib
\row \li
Instead of interfacing the graphics hardware directly, this
example relies on \l {http://www.svgalib.org}{SVGAlib} being
installed on your system. \l {http://www.svgalib.org}{SVGAlib} is
a small graphics library which provides acceleration for many
common graphics cards used on desktop computers. It should work on
most workstations and has a small and simple API.
\endtable
\section1 Step 1: Creating a Custom Graphics Driver
The custom graphics driver is created by deriving from the QScreen
class. QScreen is the base class for implementing screen/graphics
drivers in Qt for Embedded Linux.
\snippet examples/qws/svgalib/svgalibscreen.h 0
\codeline
\snippet examples/qws/svgalib/svgalibscreen.h 1
The \l {QScreen::}{connect()}, \l {QScreen::}{disconnect()}, \l
{QScreen::}{initDevice()} and \l {QScreen::}{shutdownDevice()}
functions are declared as pure virtual functions in QScreen and
must be implemented. They are used to configure the hardware, or
query its configuration: \l {QScreen::}{connect()} and \l
{QScreen::}{disconnect()} are called by both the server and client
processes, while the \l {QScreen::}{initDevice()} and \l
{QScreen::}{shutdownDevice()} functions are only called by the
server process.
QScreen's \l {QScreen::}{setMode()} and \l {QScreen::}{blank()}
functions are also pure virtual, but our driver's implementations
are trivial. The last two functions (\l {QScreen::}{blit()} and \l
{QScreen::}{solidFill()}) are the ones involved in putting pixels
on the screen, i.e., we reimplement these functions to perform the
pixel copying acceleration.
Finally, the \c context variable is a pointer to a \l
{http://www.svgalib.org}{SVGAlib} specific type. Note that the
details of using the \l {http://www.svgalib.org}{SVGAlib} library
is beyond the scope of this example.
\section2 SvgalibScreen Class Implementation
The \l {QScreen::}{connect()} function is the first function that
is called after the constructor returns. It queries \l
{http://www.svgalib.org}{SVGAlib} about the graphics mode and
initializes the variables.
\snippet examples/qws/svgalib/svgalibscreen.cpp 0
It is important that the \l {QScreen::}{connect()} function
initializes the \c data, \c lstep, \c w, \c h, \c dw, \c dh, \c d,
\c physWidth and \c physHeight variables (inherited from QScreen)
to ensure that the driver is in a state consistent with the driver
configuration.
In this particular example we do not have any information of the
real physical size of the screen, so we set these values with the
assumption of a screen with 72 DPI.
\snippet examples/qws/svgalib/svgalibscreen.cpp 1
When the \l {QScreen::}{connect()} function returns, the server
process calls the \l {QScreen::}{initDevice()} function which is
expected to do the necessary hardware initialization, leaving the
hardware in a state consistent with the driver configuration.
Note that we have chosen to use the software cursor. If you want
to use a hardware cursor, you should create a subclass of
QScreenCursor, create an instance of it, and make the global
variable \c qt_screencursor point to this instance.
\snippet examples/qws/svgalib/svgalibscreen.cpp 2
\codeline
\snippet examples/qws/svgalib/svgalibscreen.cpp 3
Before exiting, the server process will call the \l
{QScreen::}{shutdownDevice()} function to do the necessary
hardware cleanup. Again, it is important that the function leaves
the hardware in a state consistent with the driver
configuration. When \l {QScreen::}{shutdownDevice()} returns, the
\l {QScreen::}{disconnect()} function is called. Our
implementation of the latter function is trivial.
Note that, provided that the \c QScreen::data variable points to a
valid linear framebuffer, the graphics driver is fully functional
as a simple screen driver at this point. The rest of this example
will show where to take advantage of the accelerated capabilities
available on the hardware.
Whenever an area on the screen needs to be updated, the server will
call the \l {QScreen::}{exposeRegion()} function that paints the
given region on screen. The default implementation will do the
necessary composing of the top-level windows and call \l
{QScreen::}{solidFill()} and \l {QScreen::}{blit()} whenever it is
required. We do not want to change this behavior in the driver so
we do not reimplement \l {QScreen::}{exposeRegion()}.
To control how the pixels are put onto the screen we need to
reimplement the \l {QScreen::}{solidFill()} and \l
{QScreen::}{blit()} functions.
\snippet examples/qws/svgalib/svgalibscreen.cpp 4
\codeline
\snippet examples/qws/svgalib/svgalibscreen.cpp 5
\section1 Step 2: Implementing a Custom Raster Paint Engine
\l{Qt for Embedded Linux} uses QRasterPaintEngine (a raster-based
implementation of QPaintEngine) to implement the painting
operations.
Acceleration of the painting operations is done by deriving from
QRasterPaintEngine class. This is a powerful mechanism for
accelerating graphic primitives while getting software fallbacks
for all the primitives you do not accelerate.
\snippet examples/qws/svgalib/svgalibpaintengine.h 0
In this example, we will only accelerate one of the \l
{QRasterPaintEngine::}{drawRects()} functions, i.e., only
non-rotated, aliased and opaque rectangles will be rendered using
accelerated painting. All other primitives are rendered using the
base class's unaccelerated implementation.
The paint engine's state is stored in the private member
variables, and we reimplement the \l
{QPaintEngine::}{updateState()} function to ensure that our
custom paint engine's state is updated properly whenever it is
required. The private \c setClip() and \c updateClip() functions
are only helper function used to simplify the \l
{QPaintEngine::}{updateState()} implementation.
We also reimplement QRasterPaintEngine's \l
{QRasterPaintEngine::}{begin()} and \l
{QRasterPaintEngine::}{end()} functions to initialize the paint
engine and to do the cleanup when we are done rendering,
respectively.
\table
\header \li Private Header Files
\row
\li
Note the \c include statement used by this class. The files
prefixed with \c private/ are private headers file within
\l{Qt for Embedded Linux}. Private header files are not part of
the standard installation and are only present while
compiling Qt. To be able to compile using
private header files you need to use a \c qmake binary within a
compiled \l{Qt for Embedded Linux} package.
\warning Private header files may change without notice between
releases.
\endtable
The \l {QRasterPaintEngine::}{begin()} function initializes the
internal state of the paint engine. Note that it also calls the
base class implementation to initialize the parts inherited from
QRasterPaintEngine:
\snippet examples/qws/svgalib/svgalibpaintengine.cpp 0
\codeline
\snippet examples/qws/svgalib/svgalibpaintengine.cpp 1
The implementation of the \l {QRasterPaintEngine::}{end()}
function removes the clipping constraints that might have been set
in \l {http://www.svgalib.org}{SVGAlib}, before calling the
corresponding base class implementation.
\snippet examples/qws/svgalib/svgalibpaintengine.cpp 2
The \l {QPaintEngine::}{updateState()} function updates our
custom paint engine's state. The QPaintEngineState class provides
information about the active paint engine's current state.
Note that we only accept and save the current matrix if it doesn't
do any shearing. The pen is accepted if it is opaque and only one
pixel wide. The rest of the engine's properties are updated
following the same pattern. Again it is important that the
QPaintEngine::updateState() function is called to update the
parts inherited from the base class.
\snippet examples/qws/svgalib/svgalibpaintengine.cpp 3
\codeline
\snippet examples/qws/svgalib/svgalibpaintengine.cpp 4
The \c setClip() helper function is called from our custom
implementation of \l {QPaintEngine::}{updateState()}, and
enables clipping to the given region. An empty region means that
clipping is disabled.
Our custom update function also makes use of the \c updateClip()
helper function that checks if the clip is "simple", i.e., that it
can be represented by only one rectangle, and updates the clip
region in \l {http://www.svgalib.org}{SVGAlib}.
\snippet examples/qws/svgalib/svgalibpaintengine.cpp 5
Finally, we accelerated that drawing of non-rotated, aliased and
opaque rectangles in our reimplementation of the \l
{QRasterPaintEngine::}{drawRects()} function. The
QRasterPaintEngine fallback is used whenever the rectangle is not
simple enough.
\section1 Step 3: Making the Widgets Aware of the Custom Paint Engine
To activate the custom paint engine, we also need to implement a
corresponding paint device and window surface and make some minor
adjustments of the graphics driver.
\list
\li \l {Implementing a Custom Paint Device}
\li \l {Implementing a Custom Window Surface}
\li \l {Adjusting the Graphics Driver}
\endlist
\section2 Implementing a Custom Paint Device
The custom paint device can be derived from the
QCustomRasterPaintDevice class. Reimplement its \l
{QCustomRasterPaintDevice::}{paintEngine()} and \l
{QCustomRasterPaintDevice::}{memory()} functions to activate the
accelerated paint engine:
\snippet examples/qws/svgalib/svgalibpaintdevice.h 0
The \l {QCustomRasterPaintDevice::}{paintEngine()} function should
return an instance of the \c SvgalibPaintEngine class. The \l
{QCustomRasterPaintDevice::}{memory()} function should return a
pointer to the buffer which should be used when drawing the
widget.
Our example driver is rendering directly to the screen without any
buffering, i.e., our custom pain device's \l
{QCustomRasterPaintDevice::}{memory()} function returns a pointer
to the framebuffer. For this reason, we must also reimplement the
\l {QPaintDevice::}{metric()} function to reflect the metrics of
framebuffer.
\section2 Implementing a Custom Window Surface
The custom window surface can be derived from the QWSWindowSurface
class. QWSWindowSurface manages the memory used when drawing a
window.
\snippet examples/qws/svgalib/svgalibsurface.h 0
We can implement most of the pure virtual functions inherited from
QWSWindowSurface as trivial inline functions, except the scroll()
function that actually makes use of some hardware acceleration:
\snippet examples/qws/svgalib/svgalibsurface.cpp 0
\section2 Adjusting the Graphics Driver
Finally, we enable the graphics driver to recognize an instance of
our custom window surface:
\snippet examples/qws/svgalib/svgalibscreen.cpp 7
\codeline
\snippet examples/qws/svgalib/svgalibscreen.cpp 8
The \l {QScreen::}{createSurface()} functions are factory
functions that determines what kind of surface a top-level window
is using. In our example we only use the custom surface if the
given window has the Qt::WA_PaintOnScreen attribute or the
QT_ONSCREEN_PAINT environment variable is set.
*/