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
parent
eba0efe10e
commit
2089967513
|
|
@ -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.
|
||||
*/
|
||||
|
|
@ -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.
|
||||
*/
|
||||
|
|
@ -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.
|
||||
*/
|
||||
|
||||
Loading…
Reference in New Issue