Sophie

Sophie

distrib > Fedora > 18 > x86_64 > by-pkgid > ff187cb994c94c614ecc64c5a8528b1b > files > 7111

qt-doc-4.8.5-10.fc18.noarch.rpm

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en_US" lang="en_US">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- svgalib.qdoc -->
  <title>Qt 4.8: Accelerated Graphics Driver Example</title>
  <link rel="stylesheet" type="text/css" href="style/style.css" />
  <script src="scripts/jquery.js" type="text/javascript"></script>
  <script src="scripts/functions.js" type="text/javascript"></script>
  <link rel="stylesheet" type="text/css" href="style/superfish.css" />
  <link rel="stylesheet" type="text/css" href="style/narrow.css" />
  <!--[if IE]>
<meta name="MSSmartTagsPreventParsing" content="true">
<meta http-equiv="imagetoolbar" content="no">
<![endif]-->
<!--[if lt IE 7]>
<link rel="stylesheet" type="text/css" href="style/style_ie6.css">
<![endif]-->
<!--[if IE 7]>
<link rel="stylesheet" type="text/css" href="style/style_ie7.css">
<![endif]-->
<!--[if IE 8]>
<link rel="stylesheet" type="text/css" href="style/style_ie8.css">
<![endif]-->

<script src="scripts/superfish.js" type="text/javascript"></script>
<script src="scripts/narrow.js" type="text/javascript"></script>

</head>
<body class="" onload="CheckEmptyAndLoadList();">
 <div class="header" id="qtdocheader">
    <div class="content"> 
    <div id="nav-logo">
      <a href="index.html">Home</a></div>
    <a href="index.html" class="qtref"><span>Qt Reference Documentation</span></a>
    <div id="narrowsearch"></div>
    <div id="nav-topright">
      <ul>
        <li class="nav-topright-home"><a href="http://qt.digia.com/">Qt HOME</a></li>
        <li class="nav-topright-dev"><a href="http://qt-project.org/">DEV</a></li>
        <li class="nav-topright-doc nav-topright-doc-active"><a href="http://qt-project.org/doc/">
          DOC</a></li>
        <li class="nav-topright-blog"><a href="http://blog.qt.digia.com/">BLOG</a></li>
      </ul>
    </div>
    <div id="shortCut">
      <ul>
        <li class="shortCut-topleft-inactive"><span><a href="index.html">Qt 4.8</a></span></li>
        <li class="shortCut-topleft-active"><a href="http://qt-project.org/doc/">ALL VERSIONS        </a></li>
      </ul>
     </div>
 <ul class="sf-menu" id="narrowmenu"> 
             <li><a href="#">API Lookup</a> 
                 <ul> 
                     <li><a href="classes.html">Class index</a></li> 
           <li><a href="functions.html">Function index</a></li> 
           <li><a href="modules.html">Modules</a></li> 
           <li><a href="namespaces.html">Namespaces</a></li> 
           <li><a href="qtglobal.html">Global Declarations</a></li> 
           <li><a href="qdeclarativeelements.html">QML elements</a></li> 
             </ul> 
             </li> 
             <li><a href="#">Qt Topics</a> 
                 <ul> 
                        <li><a href="qt-basic-concepts.html">Programming with Qt</a></li>  
                        <li><a href="qtquick.html">Device UIs &amp; Qt Quick</a></li>  
                        <li><a href="qt-gui-concepts.html">UI Design with Qt</a></li>  
                        <li><a href="supported-platforms.html">Supported Platforms</a></li>  
                        <li><a href="technology-apis.html">Qt and Key Technologies</a></li>  
                        <li><a href="best-practices.html">How-To's and Best Practices</a></li>  
              </ul> 
                 </li> 
                 <li><a href="#">Examples</a> 
                     <ul> 
                       <li><a href="all-examples.html">Examples</a></li> 
                       <li><a href="tutorials.html">Tutorials</a></li> 
                       <li><a href="demos.html">Demos</a></li> 
                       <li><a href="qdeclarativeexamples.html">QML Examples</a></li> 
                </ul> 
                     </li> 
                 </ul> 
    </div>
  </div>
  <div class="wrapper">
    <div class="hd">
      <span></span>
    </div>
    <div class="bd group">
      <div class="sidebar">
        <div class="searchlabel">
          Search index:</div>
        <div class="search" id="sidebarsearch">
          <form id="qtdocsearch" action="" onsubmit="return false;">
            <fieldset>
              <input type="text" name="searchstring" id="pageType" value="" />
 <div id="resultdialog"> 
 <a href="#" id="resultclose">Close</a> 
 <p id="resultlinks" class="all"><a href="#" id="showallresults">All</a> | <a href="#" id="showapiresults">API</a> | <a href="#" id="showarticleresults">Articles</a> | <a href="#" id="showexampleresults">Examples</a></p> 
 <p id="searchcount" class="all"><span id="resultcount"></span><span id="apicount"></span><span id="articlecount"></span><span id="examplecount"></span>&nbsp;results:</p> 
 <ul id="resultlist" class="all"> 
 </ul> 
 </div> 
            </fieldset>
          </form>
        </div>
        <div class="box first bottombar" id="lookup">
          <h2 title="API Lookup"><span></span>
            API Lookup</h2>
          <div  id="list001" class="list">
          <ul id="ul001" >
              <li class="defaultLink"><a href="classes.html">Class index</a></li>
              <li class="defaultLink"><a href="functions.html">Function index</a></li>
              <li class="defaultLink"><a href="modules.html">Modules</a></li>
              <li class="defaultLink"><a href="namespaces.html">Namespaces</a></li>
              <li class="defaultLink"><a href="qtglobal.html">Global Declarations</a></li>
              <li class="defaultLink"><a href="qdeclarativeelements.html">QML elements</a></li>
            </ul> 
          </div>
        </div>
        <div class="box bottombar" id="topics">
          <h2 title="Qt Topics"><span></span>
            Qt Topics</h2>
          <div id="list002" class="list">
            <ul id="ul002" >
               <li class="defaultLink"><a href="qt-basic-concepts.html">Programming with Qt</a></li> 
               <li class="defaultLink"><a href="qtquick.html">Device UIs &amp; Qt Quick</a></li> 
               <li class="defaultLink"><a href="qt-gui-concepts.html">UI Design with Qt</a></li> 
               <li class="defaultLink"><a href="supported-platforms.html">Supported Platforms</a></li>  
               <li class="defaultLink"><a href="technology-apis.html">Qt and Key Technologies</a></li> 
               <li class="defaultLink"><a href="best-practices.html">How-To's and Best Practices</a></li> 
            </ul>  
          </div>
        </div>
        <div class="box" id="examples">
          <h2 title="Examples"><span></span>
            Examples</h2>
          <div id="list003" class="list">
        <ul id="ul003">
              <li class="defaultLink"><a href="all-examples.html">Examples</a></li>
              <li class="defaultLink"><a href="tutorials.html">Tutorials</a></li>
              <li class="defaultLink"><a href="demos.html">Demos</a></li>
              <li class="defaultLink"><a href="qdeclarativeexamples.html">QML Examples</a></li>
            </ul> 
          </div>
        </div>
      </div>
      <div class="wrap">
        <div class="toolbar">
          <div class="breadcrumb toolblock">
            <ul>
              <li class="first"><a href="index.html">Home</a></li>
              <!--  Breadcrumbs go here -->
<li><a href="all-examples.html">Examples</a></li>
<li>Accelerated Graphics Driver Example</li>
            </ul>
          </div>
          <div class="toolbuttons toolblock">
            <ul>
              <li id="smallA" class="t_button">A</li>
              <li id="medA" class="t_button active">A</li>
              <li id="bigA" class="t_button">A</li>
              <li id="print" class="t_button"><a href="javascript:this.print();">
                <span>Print</span></a></li>
            </ul>
        </div>
        </div>
        <div class="content mainContent">
<div class="toc">
<h3><a name="toc">Contents</a></h3>
<ul>
<li class="level1"><a href="#step-1-creating-a-custom-graphics-driver">Step 1: Creating a Custom Graphics Driver</a></li>
<li class="level2"><a href="#svgalibscreen-class-implementation">SvgalibScreen Class Implementation</a></li>
<li class="level1"><a href="#step-2-implementing-a-custom-raster-paint-engine">Step 2: Implementing a Custom Raster Paint Engine</a></li>
<li class="level1"><a href="#step-3-making-the-widgets-aware-of-the-custom-paint-engine">Step 3: Making the Widgets Aware of the Custom Paint Engine</a></li>
<li class="level2"><a href="#implementing-a-custom-paint-device">Implementing a Custom Paint Device</a></li>
<li class="level2"><a href="#implementing-a-custom-window-surface">Implementing a Custom Window Surface</a></li>
<li class="level2"><a href="#adjusting-the-graphics-driver">Adjusting the Graphics Driver</a></li>
</ul>
</div>
<h1 class="title">Accelerated Graphics Driver Example</h1>
<span class="subtitle"></span>
<!-- $$$qws/svgalib-description -->
<div class="descr"> <a name="details"></a>
<p>Files:</p>
<ul>
<li><a href="qws-svgalib-svgalibpaintdevice-cpp.html">qws/svgalib/svgalibpaintdevice.cpp</a></li>
<li><a href="qws-svgalib-svgalibpaintdevice-h.html">qws/svgalib/svgalibpaintdevice.h</a></li>
<li><a href="qws-svgalib-svgalibpaintengine-cpp.html">qws/svgalib/svgalibpaintengine.cpp</a></li>
<li><a href="qws-svgalib-svgalibpaintengine-h.html">qws/svgalib/svgalibpaintengine.h</a></li>
<li><a href="qws-svgalib-svgalibplugin-cpp.html">qws/svgalib/svgalibplugin.cpp</a></li>
<li><a href="qws-svgalib-svgalibscreen-cpp.html">qws/svgalib/svgalibscreen.cpp</a></li>
<li><a href="qws-svgalib-svgalibscreen-h.html">qws/svgalib/svgalibscreen.h</a></li>
<li><a href="qws-svgalib-svgalibsurface-cpp.html">qws/svgalib/svgalibsurface.cpp</a></li>
<li><a href="qws-svgalib-svgalibsurface-h.html">qws/svgalib/svgalibsurface.h</a></li>
<li><a href="qws-svgalib-svgalib-pro.html">qws/svgalib/svgalib.pro</a></li>
</ul>
<p>The Accelerated Graphics Driver example shows how you can write your own accelerated graphics driver and <a href="qt-embedded-accel.html#add-your-graphics-driver-to-qt-for-embedded-linux">add your graphics driver to Qt for Embedded Linux</a>.<p>In <a href="qt-embedded-linux.html">Qt for Embedded Linux</a>, 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 <a href="qt-embedded-architecture.html">Qt for Embedded Linux Architecture</a> documentation for details.)</p>
<p>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:</p>
<ol class="1">
<li><a href="#step-1-creating-a-custom-graphics-driver">Creating a Custom Graphics Driver</a></li>
<li><a href="#step-2-implementing-a-custom-raster-paint-engine">Implementing a Custom Paint Engine</a></li>
<li><a href="#step-3-making-the-widgets-aware-of-the-custom-paint-engine">Making the Widgets Aware of the Custom Paint Engine</a></li>
</ol>
<p>After compiling the example code, install the graphics driver plugin with the command <tt>make install</tt>. To start an application using the graphics driver, you can either set the environment variable <a href="qt-embedded-envvars.html#qws-display">QWS_DISPLAY</a> and then run the application, or you can just run the application using the <tt>-display</tt> switch:</p>
<pre class="cpp"> myApplication -qws -display svgalib</pre>
<table class="generic">
<thead><tr class="qt-style"><th >SVGAlib</th></tr></thead>
<tr valign="top" class="odd"><td >Instead of interfacing the graphics hardware directly, this example relies on <a href="http://www.svgalib.org">SVGAlib</a> being installed on your system. <a href="http://www.svgalib.org">SVGAlib</a> 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.</td></tr>
</table>
<a name="step-1-creating-a-custom-graphics-driver"></a>
<h2>Step 1: Creating a Custom Graphics Driver</h2>
<p>The custom graphics driver is created by deriving from the <a href="qscreen.html">QScreen</a> class. <a href="qscreen.html">QScreen</a> is the base class for implementing screen/graphics drivers in Qt for Embedded Linux.</p>
<pre class="cpp"> <span class="keyword">class</span> SvgalibScreen : <span class="keyword">public</span> <span class="type"><a href="qscreen.html">QScreen</a></span>
 {
 <span class="keyword">public</span>:
     SvgalibScreen(<span class="type">int</span> displayId) : <span class="type"><a href="qscreen.html">QScreen</a></span>(displayId) {}
     <span class="operator">~</span>SvgalibScreen() {}

     <span class="type">bool</span> connect(<span class="keyword">const</span> <span class="type"><a href="qstring.html">QString</a></span> <span class="operator">&amp;</span>displaySpec);
     <span class="type">bool</span> initDevice();
     <span class="type">void</span> shutdownDevice();
     <span class="type">void</span> disconnect();

     <span class="type">void</span> setMode(<span class="type">int</span><span class="operator">,</span> <span class="type">int</span><span class="operator">,</span> <span class="type">int</span>) {}
     <span class="type">void</span> blank(<span class="type">bool</span>) {}

     <span class="type">void</span> blit(<span class="keyword">const</span> <span class="type"><a href="qimage.html">QImage</a></span> <span class="operator">&amp;</span>img<span class="operator">,</span> <span class="keyword">const</span> <span class="type"><a href="qpoint.html">QPoint</a></span> <span class="operator">&amp;</span>topLeft<span class="operator">,</span> <span class="keyword">const</span> <span class="type"><a href="qregion.html">QRegion</a></span> <span class="operator">&amp;</span>region);
     <span class="type">void</span> solidFill(<span class="keyword">const</span> <span class="type"><a href="qcolor.html">QColor</a></span> <span class="operator">&amp;</span>color<span class="operator">,</span> <span class="keyword">const</span> <span class="type"><a href="qregion.html">QRegion</a></span> <span class="operator">&amp;</span>region);

 <span class="keyword">private</span>:
     <span class="type">void</span> initColorMap();
     <span class="type">void</span> blit16To8(<span class="keyword">const</span> <span class="type"><a href="qimage.html">QImage</a></span> <span class="operator">&amp;</span>image<span class="operator">,</span>
                    <span class="keyword">const</span> <span class="type"><a href="qpoint.html">QPoint</a></span> <span class="operator">&amp;</span>topLeft<span class="operator">,</span> <span class="keyword">const</span> <span class="type"><a href="qregion.html">QRegion</a></span> <span class="operator">&amp;</span>region);
     <span class="type">void</span> blit32To8(<span class="keyword">const</span> <span class="type"><a href="qimage.html">QImage</a></span> <span class="operator">&amp;</span>image<span class="operator">,</span>
                    <span class="keyword">const</span> <span class="type"><a href="qpoint.html">QPoint</a></span> <span class="operator">&amp;</span>topLeft<span class="operator">,</span> <span class="keyword">const</span> <span class="type"><a href="qregion.html">QRegion</a></span> <span class="operator">&amp;</span>region);

     GraphicsContext <span class="operator">*</span>context;
 };</pre>
<p>The <a href="qscreen.html#connect">connect()</a>, <a href="qscreen.html#disconnect">disconnect()</a>, <a href="qscreen.html#initDevice">initDevice()</a> and <a href="qscreen.html#shutdownDevice">shutdownDevice()</a> functions are declared as pure virtual functions in <a href="qscreen.html">QScreen</a> and must be implemented. They are used to configure the hardware, or query its configuration: <a href="qscreen.html#connect">connect()</a> and <a href="qscreen.html#disconnect">disconnect()</a> are called by both the server and client processes, while the <a href="qscreen.html#initDevice">initDevice()</a> and <a href="qscreen.html#shutdownDevice">shutdownDevice()</a> functions are only called by the server process.</p>
<p><a href="qscreen.html">QScreen</a>'s <a href="qscreen.html#setMode">setMode()</a> and <a href="qscreen.html#blank">blank()</a> functions are also pure virtual, but our driver's implementations are trivial. The last two functions (<a href="qscreen.html#blit">blit()</a> and <a href="qscreen.html#solidFill">solidFill()</a>) are the ones involved in putting pixels on the screen, i.e&#x2e;, we reimplement these functions to perform the pixel copying acceleration.</p>
<p>Finally, the <tt>context</tt> variable is a pointer to a <a href="http://www.svgalib.org">SVGAlib</a> specific type. Note that the details of using the <a href="http://www.svgalib.org">SVGAlib</a> library is beyond the scope of this example.</p>
<a name="svgalibscreen-class-implementation"></a>
<h3>SvgalibScreen Class Implementation</h3>
<p>The <a href="qscreen.html#connect">connect()</a> function is the first function that is called after the constructor returns. It queries <a href="http://www.svgalib.org">SVGAlib</a> about the graphics mode and initializes the variables.</p>
<pre class="cpp"> <span class="type">bool</span> SvgalibScreen<span class="operator">::</span>connect(<span class="keyword">const</span> <span class="type"><a href="qstring.html">QString</a></span> <span class="operator">&amp;</span>displaySpec)
 {
     <span class="type">int</span> mode <span class="operator">=</span> vga_getdefaultmode();
     <span class="keyword">if</span> (mode <span class="operator">&lt;</span><span class="operator">=</span> <span class="number">0</span>) {
         <a href="qtglobal.html#qCritical">qCritical</a>(<span class="string">&quot;SvgalibScreen::connect(): invalid vga mode&quot;</span>);
         <span class="keyword">return</span> <span class="keyword">false</span>;
     }

     vga_modeinfo <span class="operator">*</span>modeinfo <span class="operator">=</span> vga_getmodeinfo(mode);

     <span class="type"><a href="qscreen.html">QScreen</a></span><span class="operator">::</span>lstep <span class="operator">=</span> modeinfo<span class="operator">-</span><span class="operator">&gt;</span>linewidth;
     <span class="type"><a href="qscreen.html">QScreen</a></span><span class="operator">::</span>dw <span class="operator">=</span> <span class="type"><a href="qscreen.html">QScreen</a></span><span class="operator">::</span>w <span class="operator">=</span> modeinfo<span class="operator">-</span><span class="operator">&gt;</span>width;
     <span class="type"><a href="qscreen.html">QScreen</a></span><span class="operator">::</span>dh <span class="operator">=</span> <span class="type"><a href="qscreen.html">QScreen</a></span><span class="operator">::</span>h <span class="operator">=</span> modeinfo<span class="operator">-</span><span class="operator">&gt;</span>height;
     <span class="type"><a href="qscreen.html">QScreen</a></span><span class="operator">::</span>d <span class="operator">=</span> getModeDepth(modeinfo);
     <span class="type"><a href="qscreen.html">QScreen</a></span><span class="operator">::</span>size <span class="operator">=</span> <span class="type"><a href="qscreen.html">QScreen</a></span><span class="operator">::</span>lstep <span class="operator">*</span> dh;
     <span class="type"><a href="qscreen.html">QScreen</a></span><span class="operator">::</span>data <span class="operator">=</span> <span class="number">0</span>;

     <span class="keyword">switch</span> (depth()) {
     <span class="keyword">case</span> <span class="number">32</span>:
         setPixelFormat(<span class="type"><a href="qimage.html">QImage</a></span><span class="operator">::</span>Format_ARGB32_Premultiplied);
         <span class="keyword">break</span>;
     <span class="keyword">case</span> <span class="number">24</span>:
         setPixelFormat(<span class="type"><a href="qimage.html">QImage</a></span><span class="operator">::</span>Format_RGB888);
         <span class="keyword">break</span>;
     <span class="keyword">case</span> <span class="number">16</span>:
         setPixelFormat(<span class="type"><a href="qimage.html">QImage</a></span><span class="operator">::</span>Format_RGB16);
         <span class="keyword">break</span>;
     <span class="keyword">case</span> <span class="number">15</span>:
         setPixelFormat(<span class="type"><a href="qimage.html">QImage</a></span><span class="operator">::</span>Format_RGB555);
         <span class="keyword">break</span>;
     <span class="keyword">default</span>:
         <span class="keyword">break</span>;
     }

     <span class="keyword">const</span> <span class="type">int</span> dpi <span class="operator">=</span> <span class="number">72</span>;
     <span class="type"><a href="qscreen.html">QScreen</a></span><span class="operator">::</span>physWidth <span class="operator">=</span> <a href="qtglobal.html#qRound">qRound</a>(<span class="type"><a href="qscreen.html">QScreen</a></span><span class="operator">::</span>dw <span class="operator">*</span> <span class="number">25.4</span> <span class="operator">/</span> dpi);
     <span class="type"><a href="qscreen.html">QScreen</a></span><span class="operator">::</span>physHeight <span class="operator">=</span> <a href="qtglobal.html#qRound">qRound</a>(<span class="type"><a href="qscreen.html">QScreen</a></span><span class="operator">::</span>dh <span class="operator">*</span> <span class="number">25.4</span> <span class="operator">/</span> dpi);

     <span class="keyword">const</span> <span class="type"><a href="qstringlist.html">QStringList</a></span> args <span class="operator">=</span> displaySpec<span class="operator">.</span>split(QLatin1Char(<span class="char">':'</span>)<span class="operator">,</span>
                                                <span class="type"><a href="qstring.html">QString</a></span><span class="operator">::</span>SkipEmptyParts);
     grayscale <span class="operator">=</span> args<span class="operator">.</span>contains(QLatin1String(<span class="string">&quot;grayscale&quot;</span>)<span class="operator">,</span> <span class="type"><a href="qt.html">Qt</a></span><span class="operator">::</span>CaseInsensitive);

     <span class="keyword">return</span> <span class="keyword">true</span>;
 }</pre>
<p>It is important that the <a href="qscreen.html#connect">connect()</a> function initializes the <tt>data</tt>, <tt>lstep</tt>, <tt>w</tt>, <tt>h</tt>, <tt>dw</tt>, <tt>dh</tt>, <tt>d</tt>, <tt>physWidth</tt> and <tt>physHeight</tt> variables (inherited from <a href="qscreen.html">QScreen</a>) to ensure that the driver is in a state consistent with the driver configuration.</p>
<p>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.</p>
<pre class="cpp"> <span class="type">bool</span> SvgalibScreen<span class="operator">::</span>initDevice()
 {
     <span class="keyword">if</span> (vga_init() <span class="operator">!</span><span class="operator">=</span> <span class="number">0</span>) {
         <a href="qtglobal.html#qCritical">qCritical</a>(<span class="string">&quot;SvgalibScreen::initDevice(): unable to initialize svgalib&quot;</span>);
         <span class="keyword">return</span> <span class="keyword">false</span>;
     }

     <span class="type">int</span> mode <span class="operator">=</span> vga_getdefaultmode();
     <span class="keyword">if</span> (vga_setmode(mode) <span class="operator">=</span><span class="operator">=</span> <span class="operator">-</span><span class="number">1</span>) {
         <a href="qtglobal.html#qCritical">qCritical</a>(<span class="string">&quot;SvgalibScreen::initialize(): unable to set graphics mode&quot;</span>);
         <span class="keyword">return</span> <span class="keyword">false</span>;
     }

     <span class="keyword">if</span> (gl_setcontextvga(mode) <span class="operator">!</span><span class="operator">=</span> <span class="number">0</span>) {
         <a href="qtglobal.html#qCritical">qCritical</a>(<span class="string">&quot;SvgalibScreen::initDevice(): unable to set vga context&quot;</span>);
         <span class="keyword">return</span> <span class="keyword">false</span>;
     }
     context <span class="operator">=</span> gl_allocatecontext();
     gl_getcontext(context);

     vga_modeinfo <span class="operator">*</span>modeinfo <span class="operator">=</span> vga_getmodeinfo(mode);
     <span class="keyword">if</span> (modeinfo<span class="operator">-</span><span class="operator">&gt;</span>flags <span class="operator">&amp;</span> IS_LINEAR)
         <span class="type"><a href="qscreen.html">QScreen</a></span><span class="operator">::</span>data <span class="operator">=</span> vga_getgraphmem();

     initColorMap();

     <span class="type"><a href="qscreencursor.html">QScreenCursor</a></span><span class="operator">::</span>initSoftwareCursor();
     <span class="keyword">return</span> <span class="keyword">true</span>;
 }</pre>
<p>When the <a href="qscreen.html#connect">connect()</a> function returns, the server process calls the <a href="qscreen.html#initDevice">initDevice()</a> function which is expected to do the necessary hardware initialization, leaving the hardware in a state consistent with the driver configuration.</p>
<p>Note that we have chosen to use the software cursor. If you want to use a hardware cursor, you should create a subclass of <a href="qscreencursor.html">QScreenCursor</a>, create an instance of it, and make the global variable <tt>qt_screencursor</tt> point to this instance.</p>
<pre class="cpp"> <span class="type">void</span> SvgalibScreen<span class="operator">::</span>shutdownDevice()
 {
     gl_freecontext(context);
     vga_setmode(TEXT);
 }

 <span class="type">void</span> SvgalibScreen<span class="operator">::</span>disconnect()
 {
 }</pre>
<p>Before exiting, the server process will call the <a href="qscreen.html#shutdownDevice">shutdownDevice()</a> 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 <a href="qscreen.html#shutdownDevice">shutdownDevice()</a> returns, the <a href="qscreen.html#disconnect">disconnect()</a> function is called. Our implementation of the latter function is trivial.</p>
<p>Note that, provided that the <tt>QScreen::data</tt> 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.</p>
<p>Whenever an area on the screen needs to be updated, the server will call the <a href="qscreen.html#exposeRegion">exposeRegion()</a> function that paints the given region on screen. The default implementation will do the necessary composing of the top-level windows and call <a href="qscreen.html#solidFill">solidFill()</a> and <a href="qscreen.html#blit">blit()</a> whenever it is required. We do not want to change this behavior in the driver so we do not reimplement <a href="qscreen.html#exposeRegion">exposeRegion()</a>.</p>
<p>To control how the pixels are put onto the screen we need to reimplement the <a href="qscreen.html#solidFill">solidFill()</a> and <a href="qscreen.html#blit">blit()</a> functions.</p>
<pre class="cpp"> <span class="type">void</span> SvgalibScreen<span class="operator">::</span>solidFill(<span class="keyword">const</span> <span class="type"><a href="qcolor.html">QColor</a></span> <span class="operator">&amp;</span>color<span class="operator">,</span> <span class="keyword">const</span> <span class="type"><a href="qregion.html">QRegion</a></span> <span class="operator">&amp;</span>reg)
 {
     <span class="type">int</span> c;
     <span class="keyword">if</span> (depth() <span class="operator">=</span><span class="operator">=</span> <span class="number">4</span> <span class="operator">|</span><span class="operator">|</span> depth() <span class="operator">=</span><span class="operator">=</span> <span class="number">8</span>)
         c <span class="operator">=</span> alloc(color<span class="operator">.</span>red()<span class="operator">,</span> color<span class="operator">.</span>green()<span class="operator">,</span> color<span class="operator">.</span>blue());
     <span class="keyword">else</span>
         c <span class="operator">=</span> gl_rgbcolor(color<span class="operator">.</span>red()<span class="operator">,</span> color<span class="operator">.</span>green()<span class="operator">,</span> color<span class="operator">.</span>blue());

     <span class="keyword">const</span> <span class="type"><a href="qvector.html">QVector</a></span><span class="operator">&lt;</span><span class="type"><a href="qrect.html">QRect</a></span><span class="operator">&gt;</span> rects <span class="operator">=</span> (reg <span class="operator">&amp;</span> region())<span class="operator">.</span>rects();
     <span class="keyword">for</span> (<span class="type">int</span> i <span class="operator">=</span> <span class="number">0</span>; i <span class="operator">&lt;</span> rects<span class="operator">.</span>size(); <span class="operator">+</span><span class="operator">+</span>i) {
         <span class="keyword">const</span> <span class="type"><a href="qrect.html">QRect</a></span> r <span class="operator">=</span> rects<span class="operator">.</span>at(i);
         gl_fillbox(r<span class="operator">.</span>left()<span class="operator">,</span> r<span class="operator">.</span>top()<span class="operator">,</span> r<span class="operator">.</span>width()<span class="operator">,</span> r<span class="operator">.</span>height()<span class="operator">,</span> c);
     }
 }

 <span class="type">void</span> SvgalibScreen<span class="operator">::</span>blit(<span class="keyword">const</span> <span class="type"><a href="qimage.html">QImage</a></span> <span class="operator">&amp;</span>img<span class="operator">,</span> <span class="keyword">const</span> <span class="type"><a href="qpoint.html">QPoint</a></span> <span class="operator">&amp;</span>topLeft<span class="operator">,</span>
                          <span class="keyword">const</span> <span class="type"><a href="qregion.html">QRegion</a></span> <span class="operator">&amp;</span>reg)
 {
     <span class="keyword">if</span> (depth() <span class="operator">=</span><span class="operator">=</span> <span class="number">8</span>) {
         <span class="keyword">switch</span> (img<span class="operator">.</span>format()) {
         <span class="keyword">case</span> <span class="type"><a href="qimage.html">QImage</a></span><span class="operator">::</span>Format_RGB16:
             blit16To8(img<span class="operator">,</span> topLeft<span class="operator">,</span> reg);
             <span class="keyword">return</span>;
         <span class="keyword">case</span> <span class="type"><a href="qimage.html">QImage</a></span><span class="operator">::</span>Format_RGB32:
         <span class="keyword">case</span> <span class="type"><a href="qimage.html">QImage</a></span><span class="operator">::</span>Format_ARGB32:
         <span class="keyword">case</span> <span class="type"><a href="qimage.html">QImage</a></span><span class="operator">::</span>Format_ARGB32_Premultiplied:
             blit32To8(img<span class="operator">,</span> topLeft<span class="operator">,</span> reg);
             <span class="keyword">return</span>;
         <span class="keyword">default</span>:
             <span class="keyword">break</span>;
         }
     }

     <span class="keyword">if</span> (img<span class="operator">.</span>format() <span class="operator">!</span><span class="operator">=</span> pixelFormat()) {
         <span class="keyword">if</span> (base())
             <span class="type"><a href="qscreen.html">QScreen</a></span><span class="operator">::</span>blit(img<span class="operator">,</span> topLeft<span class="operator">,</span> reg);
         <span class="keyword">return</span>;
     }

     <span class="keyword">const</span> <span class="type"><a href="qvector.html">QVector</a></span><span class="operator">&lt;</span><span class="type"><a href="qrect.html">QRect</a></span><span class="operator">&gt;</span> rects <span class="operator">=</span> (reg <span class="operator">&amp;</span> region())<span class="operator">.</span>rects();

     <span class="keyword">for</span> (<span class="type">int</span> i <span class="operator">=</span> <span class="number">0</span>; i <span class="operator">&lt;</span> rects<span class="operator">.</span>size(); <span class="operator">+</span><span class="operator">+</span>i) {
         <span class="keyword">const</span> <span class="type"><a href="qrect.html">QRect</a></span> r <span class="operator">=</span> rects<span class="operator">.</span>at(i);
         gl_putboxpart(r<span class="operator">.</span>x()<span class="operator">,</span> r<span class="operator">.</span>y()<span class="operator">,</span> r<span class="operator">.</span>width()<span class="operator">,</span> r<span class="operator">.</span>height()<span class="operator">,</span>
                       img<span class="operator">.</span>width()<span class="operator">,</span> img<span class="operator">.</span>height()<span class="operator">,</span>
                       <span class="keyword">static_cast</span><span class="operator">&lt;</span><span class="type">void</span><span class="operator">*</span><span class="operator">&gt;</span>(<span class="keyword">const_cast</span><span class="operator">&lt;</span><span class="type"><a href="qtglobal.html#uchar-typedef">uchar</a></span><span class="operator">*</span><span class="operator">&gt;</span>(img<span class="operator">.</span>bits()))<span class="operator">,</span>
                       r<span class="operator">.</span>x() <span class="operator">-</span> topLeft<span class="operator">.</span>x()<span class="operator">,</span> r<span class="operator">.</span>y() <span class="operator">-</span> topLeft<span class="operator">.</span>y());
     }
 }</pre>
<a name="step-2-implementing-a-custom-raster-paint-engine"></a>
<h2>Step 2: Implementing a Custom Raster Paint Engine</h2>
<p><a href="qt-embedded-linux.html">Qt for Embedded Linux</a> uses <a href="qrasterpaintengine.html">QRasterPaintEngine</a> (a raster-based implementation of <a href="qpaintengine.html">QPaintEngine</a>) to implement the painting operations.</p>
<p>Acceleration of the painting operations is done by deriving from <a href="qrasterpaintengine.html">QRasterPaintEngine</a> class. This is a powerful mechanism for accelerating graphic primitives while getting software fallbacks for all the primitives you do not accelerate.</p>
<pre class="cpp"> <span class="preprocessor">#include &lt;private/qpaintengine_raster_p.h&gt;</span>

 <span class="keyword">class</span> SvgalibPaintEngine : <span class="keyword">public</span> <span class="type"><a href="qrasterpaintengine.html">QRasterPaintEngine</a></span>
 {
 <span class="keyword">public</span>:
     SvgalibPaintEngine(<span class="type"><a href="qpaintdevice.html">QPaintDevice</a></span> <span class="operator">*</span>device);
     <span class="operator">~</span>SvgalibPaintEngine();

     <span class="type">bool</span> begin(<span class="type"><a href="qpaintdevice.html">QPaintDevice</a></span> <span class="operator">*</span>device);
     <span class="type">bool</span> end();
     <span class="type">void</span> updateState();
     <span class="type">void</span> drawRects(<span class="keyword">const</span> <span class="type"><a href="qrect.html">QRect</a></span> <span class="operator">*</span>rects<span class="operator">,</span> <span class="type">int</span> rectCount);

 <span class="keyword">private</span>:
     <span class="type">void</span> setClip(<span class="keyword">const</span> <span class="type"><a href="qregion.html">QRegion</a></span> <span class="operator">&amp;</span>region);
     <span class="type">void</span> updateClip();

     <span class="type"><a href="qpen.html">QPen</a></span> pen;
     <span class="type">bool</span> simplePen;
     <span class="type"><a href="qbrush.html">QBrush</a></span> brush;
     <span class="type">bool</span> simpleBrush;
     <span class="type"><a href="qtransform.html">QTransform</a></span> matrix;
     <span class="type">bool</span> simpleMatrix;
     <span class="type"><a href="qregion.html">QRegion</a></span> clip;
     <span class="type">bool</span> clipEnabled;
     <span class="type">bool</span> simpleClip;
     <span class="type">bool</span> opaque;
     <span class="type">bool</span> aliased;
     <span class="type">bool</span> sourceOver;
     <span class="type"><a href="qpaintdevice.html">QPaintDevice</a></span> <span class="operator">*</span>device;
 };</pre>
<p>In this example, we will only accelerate one of the <a href="qrasterpaintengine.html#drawRects">drawRects()</a> functions, i.e&#x2e;, 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.</p>
<p>The paint engine's state is stored in the private member variables, and we reimplement the <a href="qpaintengine.html#updateState">updateState()</a> function to ensure that our custom paint engine's state is updated properly whenever it is required. The private <tt>setClip()</tt> and <tt>updateClip()</tt> functions are only helper function used to simplify the <a href="qpaintengine.html#updateState">updateState()</a> implementation.</p>
<p>We also reimplement <a href="qrasterpaintengine.html">QRasterPaintEngine</a>'s <a href="qrasterpaintengine.html#begin">begin()</a> and <a href="qrasterpaintengine.html#end">end()</a> functions to initialize the paint engine and to do the cleanup when we are done rendering, respectively.</p>
<table class="generic">
<thead><tr class="qt-style"><th >Private Header Files</th></tr></thead>
<tr valign="top" class="odd"><td >Note the <tt>include</tt> statement used by this class. The files prefixed with <tt>private/</tt> are private headers file within <a href="qt-embedded-linux.html">Qt for Embedded Linux</a>. 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 <tt>qmake</tt> binary within a compiled <a href="qt-embedded-linux.html">Qt for Embedded Linux</a> package.<p><b>Warning:</b> Private header files may change without notice between releases.</p>
</td></tr>
</table>
<p>The <a href="qrasterpaintengine.html#begin">begin()</a> function initializes the internal state of the paint engine. Note that it also calls the base class implementation to initialize the parts inherited from <a href="qrasterpaintengine.html">QRasterPaintEngine</a>:</p>
<pre class="cpp"> <span class="type">bool</span> SvgalibPaintEngine<span class="operator">::</span>begin(<span class="type"><a href="qpaintdevice.html">QPaintDevice</a></span> <span class="operator">*</span>dev)
 {
     device <span class="operator">=</span> dev;
     pen <span class="operator">=</span> <span class="type"><a href="qt.html">Qt</a></span><span class="operator">::</span>NoPen;
     simplePen <span class="operator">=</span> <span class="keyword">true</span>;
     brush <span class="operator">=</span> <span class="type"><a href="qt.html">Qt</a></span><span class="operator">::</span>NoBrush;
     simpleBrush <span class="operator">=</span> <span class="keyword">true</span>;
     matrix <span class="operator">=</span> <span class="type"><a href="qtransform.html">QTransform</a></span>();
     simpleMatrix <span class="operator">=</span> <span class="keyword">true</span>;
     setClip(<span class="type"><a href="qrect.html">QRect</a></span>(<span class="number">0</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> device<span class="operator">-</span><span class="operator">&gt;</span>width()<span class="operator">,</span> device<span class="operator">-</span><span class="operator">&gt;</span>height()));
     opaque <span class="operator">=</span> <span class="keyword">true</span>;
     aliased <span class="operator">=</span> <span class="keyword">true</span>;
     sourceOver <span class="operator">=</span> <span class="keyword">true</span>;

     <span class="keyword">return</span> <span class="type"><a href="qrasterpaintengine.html">QRasterPaintEngine</a></span><span class="operator">::</span>begin(dev);
 }

 <span class="type">bool</span> SvgalibPaintEngine<span class="operator">::</span>end()
 {
     gl_setclippingwindow(<span class="number">0</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> device<span class="operator">-</span><span class="operator">&gt;</span>width() <span class="operator">-</span> <span class="number">1</span><span class="operator">,</span> device<span class="operator">-</span><span class="operator">&gt;</span>height() <span class="operator">-</span> <span class="number">1</span>);
     <span class="keyword">return</span> <span class="type"><a href="qrasterpaintengine.html">QRasterPaintEngine</a></span><span class="operator">::</span>end();
 }</pre>
<p>The implementation of the <a href="qrasterpaintengine.html#end">end()</a> function removes the clipping constraints that might have been set in <a href="http://www.svgalib.org">SVGAlib</a>, before calling the corresponding base class implementation.</p>
<pre class="cpp"> <span class="type">void</span> SvgalibPaintEngine<span class="operator">::</span>updateState()
 {
     <span class="type">QRasterPaintEngineState</span> <span class="operator">*</span>s <span class="operator">=</span> state();

     <span class="keyword">if</span> (s<span class="operator">-</span><span class="operator">&gt;</span>dirty <span class="operator">&amp;</span> DirtyTransform) {
         matrix <span class="operator">=</span> s<span class="operator">-</span><span class="operator">&gt;</span>matrix;
         simpleMatrix <span class="operator">=</span> (matrix<span class="operator">.</span>m12() <span class="operator">=</span><span class="operator">=</span> <span class="number">0</span> <span class="operator">&amp;</span><span class="operator">&amp;</span> matrix<span class="operator">.</span>m21() <span class="operator">=</span><span class="operator">=</span> <span class="number">0</span>);
     }

     <span class="keyword">if</span> (s<span class="operator">-</span><span class="operator">&gt;</span>dirty <span class="operator">&amp;</span> DirtyPen) {
         pen <span class="operator">=</span> s<span class="operator">-</span><span class="operator">&gt;</span>pen;
         simplePen <span class="operator">=</span> (pen<span class="operator">.</span>width() <span class="operator">=</span><span class="operator">=</span> <span class="number">0</span> <span class="operator">|</span><span class="operator">|</span> pen<span class="operator">.</span>widthF() <span class="operator">&lt;</span><span class="operator">=</span> <span class="number">1</span>)
                     <span class="operator">&amp;</span><span class="operator">&amp;</span> (pen<span class="operator">.</span>style() <span class="operator">=</span><span class="operator">=</span> <span class="type"><a href="qt.html">Qt</a></span><span class="operator">::</span>NoPen <span class="operator">|</span><span class="operator">|</span> pen<span class="operator">.</span>style() <span class="operator">=</span><span class="operator">=</span> <span class="type"><a href="qt.html">Qt</a></span><span class="operator">::</span>SolidLine)
                     <span class="operator">&amp;</span><span class="operator">&amp;</span> (pen<span class="operator">.</span>color()<span class="operator">.</span>alpha() <span class="operator">=</span><span class="operator">=</span> <span class="number">255</span>);
     }

     <span class="keyword">if</span> (s<span class="operator">-</span><span class="operator">&gt;</span>dirty <span class="operator">&amp;</span> DirtyBrush) {
         brush <span class="operator">=</span> s<span class="operator">-</span><span class="operator">&gt;</span>brush;
         simpleBrush <span class="operator">=</span> (brush<span class="operator">.</span>style() <span class="operator">=</span><span class="operator">=</span> <span class="type"><a href="qt.html">Qt</a></span><span class="operator">::</span>SolidPattern
                        <span class="operator">|</span><span class="operator">|</span> brush<span class="operator">.</span>style() <span class="operator">=</span><span class="operator">=</span> <span class="type"><a href="qt.html">Qt</a></span><span class="operator">::</span>NoBrush)
                       <span class="operator">&amp;</span><span class="operator">&amp;</span> (brush<span class="operator">.</span>color()<span class="operator">.</span>alpha() <span class="operator">=</span><span class="operator">=</span> <span class="number">255</span>);
     }

     <span class="keyword">if</span> (s<span class="operator">-</span><span class="operator">&gt;</span>dirty <span class="operator">&amp;</span> DirtyClipRegion)
         setClip(s<span class="operator">-</span><span class="operator">&gt;</span>clipRegion);

     <span class="keyword">if</span> (s<span class="operator">-</span><span class="operator">&gt;</span>dirty <span class="operator">&amp;</span> DirtyClipEnabled) {
         clipEnabled <span class="operator">=</span> s<span class="operator">-</span><span class="operator">&gt;</span>isClipEnabled();
         updateClip();
     }

     <span class="keyword">if</span> (s<span class="operator">-</span><span class="operator">&gt;</span>dirty <span class="operator">&amp;</span> DirtyClipPath) {
         setClip(<span class="type"><a href="qregion.html">QRegion</a></span>());
         simpleClip <span class="operator">=</span> <span class="keyword">false</span>;
     }

     <span class="keyword">if</span> (s<span class="operator">-</span><span class="operator">&gt;</span>dirty <span class="operator">&amp;</span> DirtyCompositionMode) {
         <span class="keyword">const</span> <span class="type"><a href="qpainter.html">QPainter</a></span><span class="operator">::</span>CompositionMode m <span class="operator">=</span> s<span class="operator">-</span><span class="operator">&gt;</span>composition_mode;
         sourceOver <span class="operator">=</span> (m <span class="operator">=</span><span class="operator">=</span> <span class="type"><a href="qpainter.html">QPainter</a></span><span class="operator">::</span>CompositionMode_SourceOver);
     }

     <span class="keyword">if</span> (s<span class="operator">-</span><span class="operator">&gt;</span>dirty <span class="operator">&amp;</span> DirtyOpacity)
         opaque <span class="operator">=</span> (s<span class="operator">-</span><span class="operator">&gt;</span>opacity <span class="operator">=</span><span class="operator">=</span> <span class="number">256</span>);

     <span class="keyword">if</span> (s<span class="operator">-</span><span class="operator">&gt;</span>dirty <span class="operator">&amp;</span> DirtyHints)
         aliased <span class="operator">=</span> <span class="operator">!</span>(s<span class="operator">-</span><span class="operator">&gt;</span>flags<span class="operator">.</span>antialiased);
 }</pre>
<p>The <a href="qpaintengine.html#updateState">updateState()</a> function updates our custom paint engine's state. The <a href="qpaintenginestate.html">QPaintEngineState</a> class provides information about the active paint engine's current state.</p>
<p>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 <a href="qpaintengine.html#updateState">QPaintEngine::updateState</a>() function is called to update the parts inherited from the base class.</p>
<pre class="cpp"> <span class="type">void</span> SvgalibPaintEngine<span class="operator">::</span>setClip(<span class="keyword">const</span> <span class="type"><a href="qregion.html">QRegion</a></span> <span class="operator">&amp;</span>region)
 {
     <span class="keyword">if</span> (region<span class="operator">.</span>isEmpty())
         clip <span class="operator">=</span> <span class="type"><a href="qrect.html">QRect</a></span>(<span class="number">0</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> device<span class="operator">-</span><span class="operator">&gt;</span>width()<span class="operator">,</span> device<span class="operator">-</span><span class="operator">&gt;</span>height());
     <span class="keyword">else</span>
         clip <span class="operator">=</span> matrix<span class="operator">.</span>map(region) <span class="operator">&amp;</span> <span class="type"><a href="qrect.html">QRect</a></span>(<span class="number">0</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> device<span class="operator">-</span><span class="operator">&gt;</span>width()<span class="operator">,</span> device<span class="operator">-</span><span class="operator">&gt;</span>height());
     clipEnabled <span class="operator">=</span> <span class="keyword">true</span>;
     updateClip();
 }

 <span class="type">void</span> SvgalibPaintEngine<span class="operator">::</span>updateClip()
 {
     <span class="type"><a href="qregion.html">QRegion</a></span> clipRegion <span class="operator">=</span> <span class="type"><a href="qrect.html">QRect</a></span>(<span class="number">0</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> device<span class="operator">-</span><span class="operator">&gt;</span>width()<span class="operator">,</span> device<span class="operator">-</span><span class="operator">&gt;</span>height());

     <span class="keyword">if</span> (<span class="operator">!</span>systemClip()<span class="operator">.</span>isEmpty())
         clipRegion <span class="operator">&amp;</span><span class="operator">=</span> systemClip();
     <span class="keyword">if</span> (clipEnabled)
         clipRegion <span class="operator">&amp;</span><span class="operator">=</span> clip;

     simpleClip <span class="operator">=</span> (clipRegion<span class="operator">.</span>rects()<span class="operator">.</span>size() <span class="operator">&lt;</span><span class="operator">=</span> <span class="number">1</span>);

     <span class="keyword">const</span> <span class="type"><a href="qrect.html">QRect</a></span> r <span class="operator">=</span> clipRegion<span class="operator">.</span>boundingRect();
     gl_setclippingwindow(r<span class="operator">.</span>left()<span class="operator">,</span> r<span class="operator">.</span>top()<span class="operator">,</span>
                          r<span class="operator">.</span>x() <span class="operator">+</span> r<span class="operator">.</span>width()<span class="operator">,</span>
                          r<span class="operator">.</span>y() <span class="operator">+</span> r<span class="operator">.</span>height());
 }</pre>
<p>The <tt>setClip()</tt> helper function is called from our custom implementation of <a href="qpaintengine.html#updateState">updateState()</a>, and enables clipping to the given region. An empty region means that clipping is disabled.</p>
<p>Our custom update function also makes use of the <tt>updateClip()</tt> helper function that checks if the clip is &quot;simple&quot;, i.e&#x2e;, that it can be represented by only one rectangle, and updates the clip region in <a href="http://www.svgalib.org">SVGAlib</a>.</p>
<pre class="cpp"> <span class="type">void</span> SvgalibPaintEngine<span class="operator">::</span>drawRects(<span class="keyword">const</span> <span class="type"><a href="qrect.html">QRect</a></span> <span class="operator">*</span>rects<span class="operator">,</span> <span class="type">int</span> rectCount)
 {
     <span class="keyword">const</span> <span class="type">bool</span> canAccelerate <span class="operator">=</span> simplePen <span class="operator">&amp;</span><span class="operator">&amp;</span> simpleBrush <span class="operator">&amp;</span><span class="operator">&amp;</span> simpleMatrix
                                <span class="operator">&amp;</span><span class="operator">&amp;</span> simpleClip <span class="operator">&amp;</span><span class="operator">&amp;</span> opaque <span class="operator">&amp;</span><span class="operator">&amp;</span> aliased
                                <span class="operator">&amp;</span><span class="operator">&amp;</span> sourceOver;
     <span class="keyword">if</span> (<span class="operator">!</span>canAccelerate) {
         <span class="type"><a href="qrasterpaintengine.html">QRasterPaintEngine</a></span><span class="operator">::</span>drawRects(rects<span class="operator">,</span> rectCount);
         <span class="keyword">return</span>;
     }

     <span class="keyword">for</span> (<span class="type">int</span> i <span class="operator">=</span> <span class="number">0</span>; i <span class="operator">&lt;</span> rectCount; <span class="operator">+</span><span class="operator">+</span>i) {
         <span class="keyword">const</span> <span class="type"><a href="qrect.html">QRect</a></span> r <span class="operator">=</span> matrix<span class="operator">.</span>mapRect(rects<span class="operator">[</span>i<span class="operator">]</span>);
         <span class="keyword">if</span> (brush <span class="operator">!</span><span class="operator">=</span> <span class="type"><a href="qt.html">Qt</a></span><span class="operator">::</span>NoBrush) {
             gl_fillbox(r<span class="operator">.</span>left()<span class="operator">,</span> r<span class="operator">.</span>top()<span class="operator">,</span> r<span class="operator">.</span>width()<span class="operator">,</span> r<span class="operator">.</span>height()<span class="operator">,</span>
                        brush<span class="operator">.</span>color()<span class="operator">.</span>rgba());
         }
         <span class="keyword">if</span> (pen <span class="operator">!</span><span class="operator">=</span> <span class="type"><a href="qt.html">Qt</a></span><span class="operator">::</span>NoPen) {
             <span class="keyword">const</span> <span class="type">int</span> c <span class="operator">=</span> pen<span class="operator">.</span>color()<span class="operator">.</span>rgba();
             gl_hline(r<span class="operator">.</span>left()<span class="operator">,</span> r<span class="operator">.</span>top()<span class="operator">,</span> r<span class="operator">.</span>right()<span class="operator">,</span> c);
             gl_hline(r<span class="operator">.</span>left()<span class="operator">,</span> r<span class="operator">.</span>bottom()<span class="operator">,</span> r<span class="operator">.</span>right()<span class="operator">,</span> c);
             gl_line(r<span class="operator">.</span>left()<span class="operator">,</span> r<span class="operator">.</span>top()<span class="operator">,</span> r<span class="operator">.</span>left()<span class="operator">,</span> r<span class="operator">.</span>bottom()<span class="operator">,</span> c);
             gl_line(r<span class="operator">.</span>right()<span class="operator">,</span> r<span class="operator">.</span>top()<span class="operator">,</span> r<span class="operator">.</span>right()<span class="operator">,</span> r<span class="operator">.</span>bottom()<span class="operator">,</span> c);
         }
     }
 }</pre>
<p>Finally, we accelerated that drawing of non-rotated, aliased and opaque rectangles in our reimplementation of the <a href="qrasterpaintengine.html#drawRects">drawRects()</a> function. The <a href="qrasterpaintengine.html">QRasterPaintEngine</a> fallback is used whenever the rectangle is not simple enough.</p>
<a name="step-3-making-the-widgets-aware-of-the-custom-paint-engine"></a>
<h2>Step 3: Making the Widgets Aware of the Custom Paint Engine</h2>
<p>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.</p>
<ul>
<li><a href="#implementing-a-custom-paint-device">Implementing a Custom Paint Device</a></li>
<li><a href="#implementing-a-custom-window-surface">Implementing a Custom Window Surface</a></li>
<li><a href="#adjusting-the-graphics-driver">Adjusting the Graphics Driver</a></li>
</ul>
<a name="implementing-a-custom-paint-device"></a>
<h3>Implementing a Custom Paint Device</h3>
<p>The custom paint device can be derived from the <a href="qcustomrasterpaintdevice.html">QCustomRasterPaintDevice</a> class. Reimplement its <a href="qpaintdevice.html#paintEngine">paintEngine()</a> and <a href="qcustomrasterpaintdevice.html#memory">memory()</a> functions to activate the accelerated paint engine:</p>
<pre class="cpp"> <span class="keyword">class</span> SvgalibPaintDevice : <span class="keyword">public</span> <span class="type"><a href="qcustomrasterpaintdevice.html">QCustomRasterPaintDevice</a></span>
 {
 <span class="keyword">public</span>:
     SvgalibPaintDevice(<span class="type"><a href="qwidget.html">QWidget</a></span> <span class="operator">*</span>w);
     <span class="operator">~</span>SvgalibPaintDevice();

     <span class="type">void</span><span class="operator">*</span> memory() <span class="keyword">const</span> { <span class="keyword">return</span> <span class="type"><a href="qscreen.html">QScreen</a></span><span class="operator">::</span>instance()<span class="operator">-</span><span class="operator">&gt;</span>base(); }

     <span class="type"><a href="qpaintengine.html">QPaintEngine</a></span> <span class="operator">*</span>paintEngine() <span class="keyword">const</span> { <span class="keyword">return</span> pengine; }
     <span class="type">int</span> metric(PaintDeviceMetric m) <span class="keyword">const</span>;

 <span class="keyword">private</span>:
     SvgalibPaintEngine <span class="operator">*</span>pengine;
 };</pre>
<p>The <a href="qpaintdevice.html#paintEngine">paintEngine()</a> function should return an instance of the <tt>SvgalibPaintEngine</tt> class. The <a href="qcustomrasterpaintdevice.html#memory">memory()</a> function should return a pointer to the buffer which should be used when drawing the widget.</p>
<p>Our example driver is rendering directly to the screen without any buffering, i.e&#x2e;, our custom pain device's <a href="qcustomrasterpaintdevice.html#memory">memory()</a> function returns a pointer to the framebuffer. For this reason, we must also reimplement the <a href="qpaintdevice.html#metric">metric()</a> function to reflect the metrics of framebuffer.</p>
<a name="implementing-a-custom-window-surface"></a>
<h3>Implementing a Custom Window Surface</h3>
<p>The custom window surface can be derived from the QWSWindowSurface class. QWSWindowSurface manages the memory used when drawing a window.</p>
<pre class="cpp"> <span class="keyword">class</span> SvgalibSurface : <span class="keyword">public</span> <span class="type">QWSWindowSurface</span>
 {
 <span class="keyword">public</span>:
     SvgalibSurface();
     SvgalibSurface(<span class="type"><a href="qwidget.html">QWidget</a></span> <span class="operator">*</span>w);
     <span class="operator">~</span>SvgalibSurface();

     <span class="type">void</span> setGeometry(<span class="keyword">const</span> <span class="type"><a href="qrect.html">QRect</a></span> <span class="operator">&amp;</span>rect);
     <span class="type">bool</span> isValid() <span class="keyword">const</span> { <span class="keyword">return</span> <span class="keyword">true</span>; }
     <span class="type">bool</span> scroll(<span class="keyword">const</span> <span class="type"><a href="qregion.html">QRegion</a></span> <span class="operator">&amp;</span>region<span class="operator">,</span> <span class="type">int</span> dx<span class="operator">,</span> <span class="type">int</span> dy);
     <span class="type"><a href="qstring.html">QString</a></span> key() <span class="keyword">const</span> { <span class="keyword">return</span> QLatin1String(<span class="string">&quot;svgalib&quot;</span>); }

     <span class="type">bool</span> attach(<span class="keyword">const</span> <span class="type"><a href="qbytearray.html">QByteArray</a></span> <span class="operator">&amp;</span>) { <span class="keyword">return</span> <span class="keyword">true</span>; }
     <span class="type">void</span> detach() {}

     <span class="type"><a href="qimage.html">QImage</a></span> image() <span class="keyword">const</span> { <span class="keyword">return</span> <span class="type"><a href="qimage.html">QImage</a></span>(); }
     <span class="type"><a href="qpaintdevice.html">QPaintDevice</a></span> <span class="operator">*</span>paintDevice() { <span class="keyword">return</span> pdevice; }
     <span class="type"><a href="qpoint.html">QPoint</a></span> painterOffset() <span class="keyword">const</span>;

 <span class="keyword">private</span>:
     SvgalibPaintDevice <span class="operator">*</span>pdevice;
 };</pre>
<p>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:</p>
<pre class="cpp"> <span class="type">bool</span> SvgalibSurface<span class="operator">::</span>scroll(<span class="keyword">const</span> <span class="type"><a href="qregion.html">QRegion</a></span> <span class="operator">&amp;</span>region<span class="operator">,</span> <span class="type">int</span> dx<span class="operator">,</span> <span class="type">int</span> dy)
 {
     <span class="keyword">const</span> <span class="type"><a href="qvector.html">QVector</a></span><span class="operator">&lt;</span><span class="type"><a href="qrect.html">QRect</a></span><span class="operator">&gt;</span> rects <span class="operator">=</span> region<span class="operator">.</span>rects();
     <span class="keyword">for</span> (<span class="type">int</span> i <span class="operator">=</span> <span class="number">0</span>; i <span class="operator">&lt;</span> rects<span class="operator">.</span>size(); <span class="operator">+</span><span class="operator">+</span>i) {
         <span class="keyword">const</span> <span class="type"><a href="qrect.html">QRect</a></span> r <span class="operator">=</span> rects<span class="operator">.</span>at(i);
         gl_copybox(r<span class="operator">.</span>left()<span class="operator">,</span> r<span class="operator">.</span>top()<span class="operator">,</span> r<span class="operator">.</span>width()<span class="operator">,</span> r<span class="operator">.</span>height()<span class="operator">,</span>
                    r<span class="operator">.</span>left() <span class="operator">+</span> dx<span class="operator">,</span> r<span class="operator">.</span>top() <span class="operator">+</span> dy);
     }

     <span class="keyword">return</span> <span class="keyword">true</span>;
 }</pre>
<a name="adjusting-the-graphics-driver"></a>
<h3>Adjusting the Graphics Driver</h3>
<p>Finally, we enable the graphics driver to recognize an instance of our custom window surface:</p>
<pre class="cpp"> <span class="type">QWSWindowSurface</span><span class="operator">*</span> SvgalibScreen<span class="operator">::</span>createSurface(<span class="type"><a href="qwidget.html">QWidget</a></span> <span class="operator">*</span>widget) <span class="keyword">const</span>
 {
     <span class="keyword">if</span> (base()) {
         <span class="keyword">static</span> <span class="type">int</span> onScreenPaint <span class="operator">=</span> <span class="operator">-</span><span class="number">1</span>;
         <span class="keyword">if</span> (onScreenPaint <span class="operator">=</span><span class="operator">=</span> <span class="operator">-</span><span class="number">1</span>)
             onScreenPaint <span class="operator">=</span> qgetenv(<span class="string">&quot;QT_ONSCREEN_PAINT&quot;</span>)<span class="operator">.</span>toInt();

         <span class="keyword">if</span> (onScreenPaint <span class="operator">&gt;</span> <span class="number">0</span> <span class="operator">|</span><span class="operator">|</span> widget<span class="operator">-</span><span class="operator">&gt;</span>testAttribute(<span class="type"><a href="qt.html">Qt</a></span><span class="operator">::</span>WA_PaintOnScreen))
             <span class="keyword">return</span> <span class="keyword">new</span> SvgalibSurface(widget);
     }
     <span class="keyword">return</span> <span class="type"><a href="qscreen.html">QScreen</a></span><span class="operator">::</span>createSurface(widget);
 }

 <span class="type">QWSWindowSurface</span><span class="operator">*</span> SvgalibScreen<span class="operator">::</span>createSurface(<span class="keyword">const</span> <span class="type"><a href="qstring.html">QString</a></span> <span class="operator">&amp;</span>key) <span class="keyword">const</span>
 {
     <span class="keyword">if</span> (key <span class="operator">=</span><span class="operator">=</span> QLatin1String(<span class="string">&quot;svgalib&quot;</span>))
         <span class="keyword">return</span> <span class="keyword">new</span> SvgalibSurface;
     <span class="keyword">return</span> <span class="type"><a href="qscreen.html">QScreen</a></span><span class="operator">::</span>createSurface(key);
 }</pre>
<p>The <a href="qscreen.html#createSurface">createSurface()</a> 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 <a href="qt.html#WidgetAttribute-enum">Qt::WA_PaintOnScreen</a> attribute or the <a href="qt-embedded-envvars.html#qt-onscreen-paint">QT_ONSCREEN_PAINT</a> environment variable is set.</p>
</div>
<!-- @@@qws/svgalib -->
      </div>
    </div>
    </div> 
    <div class="ft">
      <span></span>
    </div>
  </div> 
  <div class="footer">
    <p>
      <acronym title="Copyright">&copy;</acronym> 2013 Digia Plc and/or its
      subsidiaries. Documentation contributions included herein are the copyrights of
      their respective owners.</p>
    <br />
    <p>
      The documentation provided herein is licensed under the terms of the
      <a href="http://www.gnu.org/licenses/fdl.html">GNU Free Documentation
      License version 1.3</a> as published by the Free Software Foundation.</p>
    <p>
      Documentation sources may be obtained from <a href="http://www.qt-project.org">
      www.qt-project.org</a>.</p>
    <br />
    <p>
      Digia, Qt and their respective logos are trademarks of Digia Plc 
      in Finland and/or other countries worldwide. All other trademarks are property
      of their respective owners. <a title="Privacy Policy"
      href="http://en.gitorious.org/privacy_policy/">Privacy Policy</a></p>
  </div>

  <script src="scripts/functions.js" type="text/javascript"></script>
</body>
</html>