diff options
author | Alexis Menard <alexis.menard@nokia.com> | 2009-04-17 14:06:06 (GMT) |
---|---|---|
committer | Alexis Menard <alexis.menard@nokia.com> | 2009-04-17 14:06:06 (GMT) |
commit | f15b8a83e2e51955776a3f07cb85ebfc342dd8ef (patch) | |
tree | c5dc684986051654898db11ce73e03b9fec8db99 /examples/qws | |
download | Qt-f15b8a83e2e51955776a3f07cb85ebfc342dd8ef.zip Qt-f15b8a83e2e51955776a3f07cb85ebfc342dd8ef.tar.gz Qt-f15b8a83e2e51955776a3f07cb85ebfc342dd8ef.tar.bz2 |
Initial import of statemachine branch from the old kinetic repository
Diffstat (limited to 'examples/qws')
37 files changed, 4784 insertions, 0 deletions
diff --git a/examples/qws/README b/examples/qws/README new file mode 100644 index 0000000..d7cf21a --- /dev/null +++ b/examples/qws/README @@ -0,0 +1,38 @@ +These examples show how to take advantage of features specifically designed +for use on systems with limited resources, specialized hardware, and small +screens. + + +The example launcher provided with Qt can be used to explore each of the +examples in this directory. + +Documentation for these examples can be found via the Tutorial and Examples +link in the main Qt documentation. + + +Finding the Qt Examples and Demos launcher +========================================== + +On Windows: + +The launcher can be accessed via the Windows Start menu. Select the menu +entry entitled "Qt Examples and Demos" entry in the submenu containing +the Qt tools. + +On Mac OS X: + +For the binary distribution, the qtdemo executable is installed in the +/Developer/Applications/Qt directory. For the source distribution, it is +installed alongside the other Qt tools on the path specified when Qt is +configured. + +On Unix/Linux: + +The qtdemo executable is installed alongside the other Qt tools on the path +specified when Qt is configured. + +On all platforms: + +The source code for the launcher can be found in the demos/qtdemo directory +in the Qt package. This example is built at the same time as the Qt libraries, +tools, examples, and demonstrations. diff --git a/examples/qws/ahigl/ahigl.pro b/examples/qws/ahigl/ahigl.pro new file mode 100644 index 0000000..1ee8e6e --- /dev/null +++ b/examples/qws/ahigl/ahigl.pro @@ -0,0 +1,16 @@ +TEMPLATE = lib +QT += opengl +CONFIG += plugin + +TARGET = qahiglscreen + +target.path = $$[QT_INSTALL_PLUGINS]/gfxdrivers +INSTALLS += target + +HEADERS = qwindowsurface_ahigl_p.h \ + qscreenahigl_qws.h + +SOURCES = qwindowsurface_ahigl.cpp \ + qscreenahigl_qws.cpp \ + qscreenahiglplugin.cpp + diff --git a/examples/qws/ahigl/qscreenahigl_qws.cpp b/examples/qws/ahigl/qscreenahigl_qws.cpp new file mode 100644 index 0000000..b5880b3 --- /dev/null +++ b/examples/qws/ahigl/qscreenahigl_qws.cpp @@ -0,0 +1,963 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscreenahigl_qws.h" +#include "qwindowsurface_ahigl_p.h" + +#include <QWSServer> +#include <QMap> +#include <QTimer> +#include <QTimeLine> + +#include <qwindowsystem_qws.h> +#include <private/qwindowsurface_qws_p.h> +#include <private/qfixed_p.h> + +#include <GLES/egl.h> +#include <GLES/gl.h> +#include <math.h> + +const int animationLength = 1500; +const int frameSpan = 20; + +static GLuint createTexture(const QImage &img); + +class QAhiGLCursor : public QScreenCursor +{ +public: + QAhiGLCursor() : texture(0) {} + ~QAhiGLCursor(); + + void set(const QImage &image, int hotx, int hoty); + + GLuint texture; +}; + +QAhiGLCursor::~QAhiGLCursor() +{ + if (texture) + glDeleteTextures(1, &texture); +} + +void QAhiGLCursor::set(const QImage &image, int hotx, int hoty) +{ + if (texture) + glDeleteTextures(1, &texture); + + if (image.isNull()) + texture = 0; + else + texture = createTexture(image.convertToFormat(QImage::Format_ARGB32)); + + QScreenCursor::set(image, hotx, hoty); +} + + +/*! + \class QAhiGLScreenPrivate + The QAhiGLScreenPrivate class contains state information for class QAhiGLScreen. + + An instance of this class points to the owning instance of + class QAhiGLScreen. This class uses a QTimer to limit the + update frequency. + */ +//! [0] +class QAhiGLScreenPrivate : public QObject +{ + Q_OBJECT + +public: + QAhiGLScreenPrivate(QAhiGLScreen *s); + +public slots: + void windowEvent(QWSWindow *w, QWSServer::WindowEvent e); + void redrawScreen(); + +public: + QAhiGLScreen *screen; + QAhiGLCursor *cursor; + + EGLContext eglContext; + EGLDisplay eglDisplay; + EGLSurface eglSurface; + + QTimer updateTimer; + bool doEffects; +}; +//! [0] + +//! [1] +class ShowAnimation : public QTimeLine +{ +public: + ShowAnimation(QAhiGLScreenPrivate *screen); + qreal valueForTime(int msec); +}; +//! [1] + +//! [2] +struct WindowInfo +{ + WindowInfo() : texture(0), animation(0) {} + + GLuint texture; + QPointer<ShowAnimation> animation; +}; + +static QMap<QWSWindow*, WindowInfo*> windowMap; +//! [2] + +/*! + Constructs the animation for the transition effect used + when the window associated with \a screen is displayed. + */ +//! [3] +ShowAnimation::ShowAnimation(QAhiGLScreenPrivate *screen) + : QTimeLine(animationLength) +{ + setUpdateInterval(frameSpan); + connect(this, SIGNAL(valueChanged(qreal)), screen, SLOT(redrawScreen())); + connect(this, SIGNAL(finished()), this, SLOT(deleteLater())); + start(); +} +//! [3] + +//! [4] +qreal ShowAnimation::valueForTime(int msec) +{ + const qreal t = msec / qreal(duration()); + return 3*t*t - 2*t*t*t; +} +//! [4] + +QAhiGLScreenPrivate::QAhiGLScreenPrivate(QAhiGLScreen *s) + : screen(s), cursor(0), doEffects(false) +{ + connect(&updateTimer, SIGNAL(timeout()), this, SLOT(redrawScreen())); +} + +/*! + This slot handles the \a event when the \l {QWSServer} + {window server} emits a window event for the specified + \a window. + + The \l {QWSServer::WindowEvent} {window events} handled + are \c Create, \c Destroy, and \c Show. The \c Create + event creates a new instance of \l {WindowInfo} and stores + it in a window map to mark the creation of a new window. + The \c Destroy event causes the \l {WindoInfo} instance + to be removed from the map and destroyed. + + The \c Show event is the most interesting. If the user + has started the application with -display ahigl:effects, + then the \c Show event is handled by creating a small + \l {ShowAnimation} {animation} for use when the window + is first shown. + */ +//! [5] +void QAhiGLScreenPrivate::windowEvent(QWSWindow *window, + QWSServer::WindowEvent event) +{ + switch (event) { + case QWSServer::Create: + windowMap[window] = new WindowInfo; + break; + case QWSServer::Show: + if (doEffects) + windowMap[window]->animation = new ShowAnimation(this); + break; + case QWSServer::Destroy: + delete windowMap[window]; + windowMap.remove(window); + break; + default: + break; + } +} +//! [5] + +/*! + This function assumes the updateTimer is still counting down and stops it + and then calls redrawScreen() in the public screen driver class QAhiGLScreen. + */ +//! [6] +void QAhiGLScreenPrivate::redrawScreen() +{ + updateTimer.stop(); + screen->redrawScreen(); +} +//! [6] + +/*! + \class QAhiGLScreen + + \brief The QAhiGLScreen class is the screen driver for the ATI handheld device interface. + + QAhiGLScreen is implemented with the d-pointer pattern. That is, + the only data member the class contains is a pointer called d_ptr, + which means data pointer. It points to an instance of a private + class called QAhiGLScreenPrivate, where all the screen driver's + context data members are defined. The d-pointer pattern is used + so that changes can be made to the screen driver's context data + members without destroying the binary compatibility of the public + screen driver class. + + The pure virtual functions found in the base class QScreen are + listed below. All must have implementations in any screen driver + class derived from QScreen. All are impemented in this example, + except for setMode(), which has only been given a stub + implementation to satisfy the compiler. + + bool connect(const QString & displaySpec); + void disconnect(); + bool initDevice(); + void setMode(int width, int height, int depth); + + The stub implementation of setMode() is not meant to indicate + setMode() can be ignored in your own screen driver class. It was + simply decided not to provide a fully implemented screen driver + class for the example, which would normally be tailored to your + device's specific requirements. + + The base class QGLScreen has only one pure virtual function, + hasOpenGL(), which must return true if your screen driver class + supports OpenGL. + + QWSWindowSurface * createSurface(const QString & key) const + QWSWindowSurface * createSurface(QWidget * widget) const + void exposeRegion(QRegion region, int windowIndex) + + */ + +/*! + Constructs a new, ATI handheld device screen driver. + + The displayId identifies the QWS server to connect to. + */ +QAhiGLScreen::QAhiGLScreen(int displayId) : QGLScreen(displayId) +{ + d_ptr = new QAhiGLScreenPrivate(this); + d_ptr->eglDisplay = EGL_NO_DISPLAY; + d_ptr->eglSurface = EGL_NO_SURFACE; +} + +/*! + Destroys this ATI handheld device screen driver. + */ +QAhiGLScreen::~QAhiGLScreen() +{ + delete d_ptr; +} + +/*! + \reimp + */ +//! [7] +bool QAhiGLScreen::connect(const QString &displaySpec) +{ + // Hardcoded values for this device + w = 480; + h = 640; + dw = w; + dh = h; + d = 16; + + const int dpi = 120; + physWidth = qRound(dw * 25.4 / dpi); + physHeight = qRound(dh * 25.4 / dpi); + + if (displaySpec.section(':', 1, 1).contains("effects")) + d_ptr->doEffects = true; + + return true; +} +//! [7] + +/*! + \reimp + */ +//! [8] +bool QAhiGLScreen::initDevice() +{ + EGLint version, subversion; + EGLint attrs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_STENCIL_SIZE, 8, EGL_DEPTH_SIZE, 16, + EGL_NONE }; + EGLint numConfig; + EGLConfig eglConfig; + + d_ptr->eglDisplay = eglGetDisplay(0); + if (d_ptr->eglDisplay == EGL_NO_DISPLAY) { + qCritical("QAhiGLScreen::initDevice(): eglGetDisplay failed: 0x%x", + eglGetError()); + return false; + } + + if (!eglInitialize(d_ptr->eglDisplay, &version, &subversion)) { + qCritical("QAhiGLScreen::initDevice(): eglInitialize failed: 0x%x", + eglGetError()); + return false; + } + + if (!eglChooseConfig(d_ptr->eglDisplay, attrs, &eglConfig, 1, &numConfig)) { + qCritical("QAhiGLScreen::initDevice(): eglChooseConfig failed: 0x%x", + eglGetError()); + return false; + } + + static DummyScreen win = { w, h }; + d_ptr->eglSurface = eglCreateWindowSurface(d_ptr->eglDisplay, eglConfig, + &win, 0); + if (d_ptr->eglSurface == EGL_NO_SURFACE) { + qCritical("QAhiGLScreen::initDevice(): eglCreateWindowSurface failed: 0x%x", + eglGetError()); + return false; + } + + d_ptr->eglContext = eglCreateContext(d_ptr->eglDisplay, eglConfig, + EGL_NO_CONTEXT, 0); + if (d_ptr->eglContext == EGL_NO_CONTEXT) { + qCritical("QAhiGLScreen::initDevice(): eglCreateContext failed: 0x%x", + eglGetError()); + return false; + } + + if (!eglMakeCurrent(d_ptr->eglDisplay, d_ptr->eglSurface, d_ptr->eglSurface, d_ptr->eglContext)) { + qCritical("QAhiGLScreen::initDevice(): eglMakeCurrent failed: 0x%x", + eglGetError()); + return false; + } + + d_ptr->connect(QWSServer::instance(), + SIGNAL(windowEvent(QWSWindow*, QWSServer::WindowEvent)), + SLOT(windowEvent(QWSWindow*, QWSServer::WindowEvent))); + + d_ptr->cursor = new QAhiGLCursor; + qt_screencursor = d_ptr->cursor; + + return true; +} +//! [8] + +/*! + \reimp + */ +//! [9] +void QAhiGLScreen::shutdownDevice() +{ + delete d_ptr->cursor; + d_ptr->cursor = 0; + qt_screencursor = 0; + + eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, + EGL_NO_SURFACE, EGL_NO_CONTEXT); + eglDestroyContext(d_ptr->eglDisplay, d_ptr->eglContext); + eglDestroySurface(d_ptr->eglDisplay, d_ptr->eglSurface); + eglTerminate(d_ptr->eglDisplay); +} +//! [9] + +/*! + \reimp + + In this case, the reimplimentation does nothing. It is + required because the function is declared as pure virtual + in the base class QScreen. + */ +void QAhiGLScreen::disconnect() +{ +} + +/* + This internal function rounds up to the next power of + two. If v is already a power of two, that same value is + returned. + */ +inline static uint nextPowerOfTwo(uint v) +{ + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + ++v; + return v; +} + +/* + This internal function creates a texture from the image img + and returns its texture identifier. + + The term "texture" is a graphics technology term that refers + to a pixmap constructed from an image by adding extra points + of contrast to the otherwise plain color image. The texture + has a, well, texture, that the original image doesn't have. + */ +static GLuint createTexture(const QImage &img) +{ + if (img.isNull()) + return 0; + + int width = img.width(); + int height = img.height(); + int textureWidth; + int textureHeight; + GLuint texture; + + glGenTextures(1, &texture); + textureWidth = nextPowerOfTwo(width); + textureHeight = nextPowerOfTwo(height); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + switch (img.format()) { + case QImage::Format_RGB16: + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, + textureWidth, + textureHeight, 0, + GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0); + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, + GL_RGB, GL_UNSIGNED_SHORT_5_6_5, img.bits()); + break; + + case QImage::Format_ARGB32_Premultiplied: + case QImage::Format_ARGB32: + case QImage::Format_RGB32: + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + textureWidth, + textureHeight, 0, + GL_RGBA, GL_UNSIGNED_BYTE, 0); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, + GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); + break; + + default: + break; + } + + return texture; +} + +/* + A helper function used by QAhiGLScreen::drawQuad(). + */ +static void drawQuad_helper(GLshort *coords, GLfloat *texCoords) +{ + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 0, texCoords); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_SHORT, 0, coords); + glEnable(GL_TEXTURE_2D); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glDisable(GL_TEXTURE_2D); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + +/* + A helper function used by QAhiGLScreen::drawQuadWavyFlag(). + */ +static void drawQuad_helper(GLshort *coords, GLfloat *texCoords, + int arraySize, int numArrays) +{ + glEnable(GL_TEXTURE_2D); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, 0, texCoords); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_SHORT, 0, coords); + + for (int i = 0; i < numArrays-1; ++i) + glDrawArrays(GL_TRIANGLE_STRIP, i*arraySize, arraySize); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisable(GL_TEXTURE_2D); +} + +/* + A convenience function used by QAhiGLScreen::drawQuad(). + */ +static void setRectCoords(GLshort *coords, QRect rect) +{ + coords[0] = GLshort(rect.left()); + coords[1] = GLshort(rect.top()); + + coords[2] = GLshort(rect.right()); + coords[3] = GLshort(rect.top()); + + coords[4] = GLshort(rect.right()); + coords[5] = GLshort(rect.bottom()); + + coords[6] = GLshort(rect.left()); + coords[7] = GLshort(rect.bottom()); +} + +/*! + A helper function used by QAhiGLScreen::drawWindow() and + QAhiGLScreen::redrawScreen(). + */ +void QAhiGLScreen::drawQuad(const QRect &textureGeometry, + const QRect &subGeometry, + const QRect &screenGeometry) +{ + qreal textureWidth = qreal(nextPowerOfTwo(textureGeometry.width())); + qreal textureHeight = qreal(nextPowerOfTwo(textureGeometry.height())); + + GLshort coords[8]; + setRectCoords(coords, screenGeometry); + + GLfloat texcoords[8]; + texcoords[0] = (subGeometry.left() - textureGeometry.left()) / textureWidth; + texcoords[1] = (subGeometry.top() - textureGeometry.top()) / textureHeight; + + texcoords[2] = (subGeometry.right() - textureGeometry.left()) / textureWidth; + texcoords[3] = (subGeometry.top() - textureGeometry.top()) / textureHeight; + + texcoords[4] = (subGeometry.right() - textureGeometry.left()) / textureWidth; + texcoords[5] = (subGeometry.bottom() - textureGeometry.top()) / textureHeight; + + texcoords[6] = (subGeometry.left() - textureGeometry.left()) / textureWidth; + texcoords[7] = (subGeometry.bottom() - textureGeometry.top()) / textureHeight; + + drawQuad_helper(coords, texcoords); +} + +/* + My own sine function. + */ +static qreal mySin(QFixed radians) +{ + const QFixed twoPI = QFixed::fromReal(2*M_PI); + + const int tableSize = 40; + static int *table = 0; + + if (!table) { + table = new int[tableSize]; + for (int i = 0; i < tableSize; ++i) { + table[i] = qRound(sin(M_PI*(i*360.0/40.0)/180.0) * 16776960.0); + } + } + + QFixed tableLookup = radians*tableSize/twoPI; + return table[tableLookup.truncate()%tableSize]/16776960.0; +} + +/* + My own cosine function. + */ +static qreal myCos(QFixed radians) +{ + const int twoPI = qRound(2*M_PI); + + const int tableSize = 40; + static int *table = 0; + + if (!table) { + table = new int[tableSize]; + for (int i = 0; i < tableSize; ++i) { + table[i] = int(cos(M_PI*(i*360.0/40.0)/180.0) * 16776960.0); + } + } + + QFixed tableLookup = radians*tableSize/twoPI; + return table[tableLookup.truncate()%tableSize]/16776960.0; +} + +// number of grid cells in wavy flag tesselation in x- and y-direction +const int subdivisions = 10; + +/* + A helper function used by drawQuadWavyFlag(). It computes + coordinates for grid cells for a wavy flag tesselation and + stores them in the array called coords. + */ +static void setFlagCoords(GLshort *coords, + QRectF screenGeometry, + int frameNum, + qreal progress) +{ + int coordIndex = 0; + qreal waveHeight = 30.0*(1.0-progress); + for (int j = 0; j < subdivisions-1; ++j) { + for (int i = 0; i < subdivisions; ++i) { + qreal c; + c = screenGeometry.left() + + (i * screenGeometry.width() / (subdivisions - 1)) + + waveHeight * qRound(mySin(QFixed::fromReal(M_PI * 20 * (frameNum + i) / 180.0))) + + waveHeight * qRound(myCos(QFixed::fromReal(M_PI * 20 * (frameNum + j) / 180.0))); + coords[coordIndex++] = qRound(c); + c = screenGeometry.top() + + (j * screenGeometry.height() / (subdivisions - 1)) + + waveHeight * mySin(QFixed::fromReal(M_PI * 20 * (frameNum + i) / 180.0)) + + waveHeight * myCos(QFixed::fromReal(M_PI * 20 * (frameNum + j) / 180.0)); + coords[coordIndex++] = qRound(c); + c = screenGeometry.left() + (i * screenGeometry.width() / (subdivisions - 1)) + + waveHeight * mySin(QFixed::fromReal(M_PI * 20 * (frameNum + i) / 180.0)) + + waveHeight * myCos(QFixed::fromReal(M_PI * 20 * (frameNum + (j+1)) / 180.0)); + coords[coordIndex++] = qRound(c); + + c = screenGeometry.top() + + ((j + 1) * screenGeometry.height() / (subdivisions - 1)) + + waveHeight * mySin(QFixed::fromReal(M_PI * 20 * (frameNum + i) / 180.0)) + + waveHeight * myCos(QFixed::fromReal(M_PI * 20 * (frameNum + (j + 1)) / 180.0)); + coords[coordIndex++] = qRound(c); + } + } +} + +static void setFlagTexCoords(GLfloat *texcoords, + const QRectF &subTexGeometry, + const QRectF &textureGeometry, + int textureWidth, int textureHeight) +{ + qreal topLeftX = (subTexGeometry.left() - textureGeometry.left())/textureWidth; + qreal topLeftY = (textureGeometry.height() - (subTexGeometry.top() - textureGeometry.top()))/textureHeight; + + qreal width = (subTexGeometry.right() - textureGeometry.left())/textureWidth - topLeftX; + qreal height = (textureGeometry.height() - (subTexGeometry.bottom() - textureGeometry.top()))/textureHeight - topLeftY; + + int coordIndex = 0; + qreal spacing = subdivisions - 1; + for (int j = 0; j < subdivisions-1; ++j) { + for (int i = 0; i < subdivisions; ++i) { + texcoords[coordIndex++] = topLeftX + (i*width) / spacing; + texcoords[coordIndex++] = topLeftY + (j*height) / spacing; + texcoords[coordIndex++] = topLeftX + (i*width) / spacing; + texcoords[coordIndex++] = topLeftY + ((j+1)*height) / spacing; + } + } +} + +void QAhiGLScreen::drawQuadWavyFlag(const QRect &textureGeometry, + const QRect &subTexGeometry, + const QRect &screenGeometry, + qreal progress) +{ + const int textureWidth = nextPowerOfTwo(textureGeometry.width()); + const int textureHeight = nextPowerOfTwo(textureGeometry.height()); + + static int frameNum = 0; + + GLshort coords[subdivisions*subdivisions*2*2]; + setFlagCoords(coords, screenGeometry, frameNum++, progress); + + GLfloat texcoords[subdivisions*subdivisions*2*2]; + setFlagTexCoords(texcoords, subTexGeometry, textureGeometry, + textureWidth, textureHeight); + + drawQuad_helper(coords, texcoords, subdivisions*2, subdivisions); +} + +void QAhiGLScreen::invalidateTexture(int windowIndex) +{ + if (windowIndex < 0) + return; + + QList<QWSWindow*> windows = QWSServer::instance()->clientWindows(); + if (windowIndex > windows.size() - 1) + return; + + QWSWindow *win = windows.at(windowIndex); + if (!win) + return; + + WindowInfo *info = windowMap[win]; + if (info->texture) { + glDeleteTextures(1, &info->texture); + info->texture = 0; + } +} + +void QAhiGLScreen::drawWindow(QWSWindow *win, qreal progress) +{ + const QRect screenRect = win->allocatedRegion().boundingRect(); + QRect drawRect = screenRect; + + glColor4f(1.0, 1.0, 1.0, progress); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + QWSWindowSurface *surface = win->windowSurface(); + if (!surface) + return; + + if (progress >= 1.0) { + if (surface->key() == QLatin1String("ahigl")) { + drawRect.setCoords(drawRect.left(), drawRect.bottom(), + drawRect.right(), drawRect.top()); + } + drawQuad(win->requestedRegion().boundingRect(), screenRect, drawRect); + return; + } + + const int dx = qRound((1 - progress) * drawRect.width() / 2); + const int dy = qRound((1 - progress) * drawRect.height() / 2); + + drawRect.adjust(dx, dy, -dx, -dy); + + if (surface->key() != QLatin1String("ahigl")) { + drawRect.setCoords(drawRect.left(), drawRect.bottom(), + drawRect.right(), drawRect.top()); + } + + drawQuadWavyFlag(win->requestedRegion().boundingRect(), screenRect, + drawRect, progress); +} + +/*! + The window compositions are constructed here. + */ +//! [10] +void QAhiGLScreen::redrawScreen() +{ + glBindFramebufferOES(GL_FRAMEBUFFER_EXT, 0); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrthof(0, w, h, 0, -999999, 999999); + glViewport(0, 0, w, h); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + // Fill background color + + QColor bgColor = QWSServer::instance()->backgroundBrush().color(); + glClearColor(bgColor.redF(), bgColor.greenF(), + bgColor.blueF(), bgColor.alphaF()); + glClear(GL_COLOR_BUFFER_BIT); +//! [10] + + // Draw all windows + + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glDisable(GL_STENCIL_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ZERO); + glDisable(GL_ALPHA_TEST); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + +//! [11] + QList<QWSWindow*> windows = QWSServer::instance()->clientWindows(); + for (int i = windows.size() - 1; i >= 0; --i) { + QWSWindow *win = windows.at(i); + QWSWindowSurface *surface = win->windowSurface(); + if (!surface) + continue; + + WindowInfo *info = windowMap[win]; + + if (!info->texture) { + if (surface->key() == QLatin1String("ahigl")) + info->texture = static_cast<QAhiGLWindowSurface*>(surface)->textureId(); + else + info->texture = createTexture(surface->image()); + } + qreal progress; + if (info->animation) + progress = info->animation->currentValue(); + else + progress = 1.0; + + glBindTexture(GL_TEXTURE_2D, info->texture); + drawWindow(win, progress); + } // for i +//! [11] //! [12] + + // Draw cursor + + const QAhiGLCursor *cursor = d_ptr->cursor; + if (cursor->texture) { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBindTexture(GL_TEXTURE_2D, d_ptr->cursor->texture); + drawQuad(cursor->boundingRect(), cursor->boundingRect(), + cursor->boundingRect()); + } + + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + + eglSwapBuffers(d_ptr->eglDisplay, d_ptr->eglSurface); +} +//! [12] + +/*! + \reimp + + */ +//! [13] +void QAhiGLScreen::exposeRegion(QRegion r, int windowIndex) +{ + if ((r & region()).isEmpty()) + return; + + invalidateTexture(windowIndex); + + if (!d_ptr->updateTimer.isActive()) + d_ptr->updateTimer.start(frameSpan); +} +//! [13] + +/*! + \reimp + + This overloading of createSurface() is called on the client side to + create a window surface for a new window. If the \a widget is a + QGLWidget, or if the widget's width and height are both less than or + equal to 256, it creates an instance of QAhiGLWindowSurface. + Otherwise, it calls QScreen::createSurface() to create a non-OpenGL + window surface. The pointer to the new window surface is returned. + + Note that this function first asks whether this application is the + server, and it only creates an instance of QAhiGLWindowSurface if + the answer is yes. What this means is we only let the server have + access to the OpenGL hardware, because of an implementation + restyriction in the OpenGL libraries we are using. Thus only clients + that are in the server process get to create OpenGL window surfaces. + */ +//! [14] +QWSWindowSurface* QAhiGLScreen::createSurface(QWidget *widget) const +{ + if (QApplication::type() == QApplication::GuiServer) { + if (qobject_cast<QGLWidget*>(widget)) { + return new QAhiGLWindowSurface(widget, + d_ptr->eglDisplay, + d_ptr->eglSurface, + d_ptr->eglContext); + } + + const QRect rect = widget->frameGeometry(); + if (rect.width() <= 256 && rect.height() <= 256) { + return new QAhiGLWindowSurface(widget, + d_ptr->eglDisplay, + d_ptr->eglSurface, + d_ptr->eglContext); + } + } + + return QScreen::createSurface(widget); +} +//! [14] + +/*! + \reimp + + This overloading of createSurface() is called on the server side + to manage a window surface corresponding to a window surface + already created on the client side. + + If the \a key is "ahigl", create an instance of QAhiGLWindowSurface + and return it. Otherwise, call QScreen::createSurface() and return + the window surface it creates. + + See QScreen::createSurface(). + */ +//! [15] +QWSWindowSurface* QAhiGLScreen::createSurface(const QString &key) const +{ + if (key == QLatin1String("ahigl")) { + return new QAhiGLWindowSurface(d_ptr->eglDisplay, + d_ptr->eglSurface, + d_ptr->eglContext); + } + + return QScreen::createSurface(key); +} +//! [15] + +/*! + This function would normally reset the frame buffer resolution + according to \a width, \a height, and the bit \a depth. It would + then notify other applications that their frame buffer size had + changed so they could redraw. The function is a no-op in this + example, which means the example screen driver can't change its + frame buffer resolution. There is no significance to that in the + example. You would normally implement setMode() in an OpenGL + screen driver. This no-op reimplementation is required here + because setMode() in QScreen is a pure virtual function. + + See QScreen::setMode() + */ +void QAhiGLScreen::setMode(int width, int height, int depth) +{ + Q_UNUSED(width); + Q_UNUSED(height); + Q_UNUSED(depth); +} + +/*! + This function would normally be reimplemented to prevent the + screen driver from updating the screen if \a on is true. It is a + no-op in this example, which means the screen driver can always + update the screen. + + See QScreen::blank(). + */ +void QAhiGLScreen::blank(bool on) +{ + Q_UNUSED(on); +} + +/*! + This function always returns true, since the purpose of + this screen driver class is to implement an OpenGL ES + screen driver. In some other class designed to handle both + OpenGL and non-OpenGL graphics, it might test the system to + determine whether OpenGL graphics are supported and return + true or false accordingly. + */ +bool QAhiGLScreen::hasOpenGL() +{ + return true; +} + +#include "qscreenahigl_qws.moc" diff --git a/examples/qws/ahigl/qscreenahigl_qws.h b/examples/qws/ahigl/qscreenahigl_qws.h new file mode 100644 index 0000000..332d5c3 --- /dev/null +++ b/examples/qws/ahigl/qscreenahigl_qws.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QAHIGLSCREEN_H +#define QAHIGLSCREEN_H + +#include <QGLScreen> +#include <QWSServer> + +QT_BEGIN_NAMESPACE +class QAhiGLScreenPrivate; +QT_END_NAMESPACE + +//! [0] +class QAhiGLScreen : public QGLScreen +{ +public: + QAhiGLScreen(int displayId); + virtual ~QAhiGLScreen(); + + bool initDevice(); + bool connect(const QString &displaySpec); + void disconnect(); + void shutdownDevice(); + + void setMode(int width, int height, int depth); + void blank(bool on); + + void exposeRegion(QRegion r, int changing); + + QWSWindowSurface* createSurface(QWidget *widget) const; + QWSWindowSurface* createSurface(const QString &key) const; + + bool hasOpenGL(); + +private: + void invalidateTexture(int windowIndex); + void redrawScreen(); + void drawWindow(QWSWindow *win, qreal progress); + void drawQuad(const QRect &textureGeometry, + const QRect &subGeometry, + const QRect &screenGeometry); + void drawQuadWavyFlag(const QRect &textureGeometry, + const QRect &subTexGeometry, + const QRect &screenGeometry, + float progress); + + QAhiGLScreenPrivate *d_ptr; + friend class QAhiGLScreenPrivate; +}; +//! [0] + +#endif // QAHIGLSCREEN_H diff --git a/examples/qws/ahigl/qscreenahiglplugin.cpp b/examples/qws/ahigl/qscreenahiglplugin.cpp new file mode 100644 index 0000000..828de82 --- /dev/null +++ b/examples/qws/ahigl/qscreenahiglplugin.cpp @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qscreenahigl_qws.h" + +#include <QScreenDriverPlugin> +#include <QStringList> + +//! [0] +class QAhiGLScreenPlugin : public QScreenDriverPlugin +{ +public: + QAhiGLScreenPlugin(); + + QStringList keys() const; + QScreen *create(const QString&, int displayId); +}; +//! [0] + +/*! + \class QAhiGLScreenPlugin + \brief The QAhiGLScreenPlugin class is the plugin for the ATI handheld device graphics driver. + + QAhiGLScreenPlugin inherits QScreenDriverPlugin. See + \l{How to Create Qt Plugins} for details. + */ + +/*! + This is the default constructor. + */ +QAhiGLScreenPlugin::QAhiGLScreenPlugin() + : QScreenDriverPlugin() +{ +} + +/*! + Returns a string list containing the string "ahigl" which + is the only screen driver supported by this plugin. + */ +QStringList QAhiGLScreenPlugin::keys() const +{ + return (QStringList() << "ahigl"); +} + +/*! + Creates a screen driver of the kind specified by \a driver. + The \a displayId identifies the Qt for Embedded Linux server to connect to. + */ +QScreen* QAhiGLScreenPlugin::create(const QString& driver, int displayId) +{ + if (driver.toLower() != "ahigl") + return 0; + + return new QAhiGLScreen(displayId); +} + +//! [1] +Q_EXPORT_PLUGIN2(qahiglscreen, QAhiGLScreenPlugin) +//! [1] diff --git a/examples/qws/ahigl/qwindowsurface_ahigl.cpp b/examples/qws/ahigl/qwindowsurface_ahigl.cpp new file mode 100644 index 0000000..79924f9 --- /dev/null +++ b/examples/qws/ahigl/qwindowsurface_ahigl.cpp @@ -0,0 +1,349 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwindowsurface_ahigl_p.h" +#include "qscreenahigl_qws.h" + +#include <qwsdisplay_qws.h> +#include <QtGui/QPaintDevice> +#include <QtGui/QWidget> +#include <QtOpenGL/private/qglpaintdevice_qws_p.h> +#include <QtOpenGL/private/qgl_p.h> +#include <GLES/gl.h> + +/*! + \class QAhiGLWindowSurfacePrivate + \internal + + \brief The QAhiGLWindowSurfacePrivate class is the private implementation + class for class QAhiGLWindowSurface. + + This class contains only state variables. + */ +//! [0] +class QAhiGLWindowSurfacePrivate +{ +public: + QAhiGLWindowSurfacePrivate(EGLDisplay eglDisplay, + EGLSurface eglSurface, + EGLContext eglContext); + + QPaintDevice *device; + + int textureWidth; + int textureHeight; + + GLuint texture; + GLuint frameBufferObject; + GLuint depthbuf; + + EGLDisplay display; + EGLSurface surface; + EGLContext context; +}; +//! [0] + +/*! + The construct just sets statwe variables using the ones + provided. + */ +QAhiGLWindowSurfacePrivate::QAhiGLWindowSurfacePrivate(EGLDisplay eglDisplay, + EGLSurface eglSurface, + EGLContext eglContext) + : texture(0), frameBufferObject(0), depthbuf(0), display(eglDisplay), + surface(eglSurface), context(eglContext) +{ +} + +inline static int nextPowerOfTwo(uint v) +{ + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + ++v; + return v; +} + +/*! + \class QAhiGLWindowSurface + \preliminary + \internal + + \brief The QAhiGLWindowSurface class provides the drawing area + for top-level windows using OpenGL for drawing on an ATI handheld + device. + + In \l{Qt for Embedded Linux}, the default behavior for each client is to + render widgets into an area of memory. The server then displays + the contents of that memory on the screen. For ATI handheld + devices using OpenGL, QAhiGLWindowSurface is the window surface + class that allocates and manages the memory areas in the clients + and the server. + + When a screen update is required, the server runs through all the + top-level windows that intersect with the region being updated, + ensuring that the clients have updated their window surfaces. Then + the server uses the screen driver to copy the contents of the + affected window surfaces into its composition and then display the + composition on the screen. + + \tableofcontents + + \section1 Pure Virtual Functions + + There are two window surface instances for each top-level window. + One is used by the application when drawing a window, and the + other is used by the server application to make its copy for + building a window composition to send to the screen. + + The key() function is implemented to uniquely identify this window + surface class as "ahigl", and the isValid() function is + implemented to determine whether the associated window is still + acceptable for representation by this window surface class. It + must either be a window using an \l {QGLWidget} {OpenGL widget}, + or it must be a window whose frame is no bigger than 256 x 256. + + The setGeometry() function is implemented to change the geometry + of the frame buffer whenever the geometry of the associated + top-level window changes. The image() function is called by the + window system when building window compositions to return an image + of the top-level window. + + The paintDevice() function is implemented to return the appropriate + paint device. + + \section1 Virtual Functions + + When painting onto the surface, the window system will always call + the beginPaint() function before any painting operations are + performed. It ensures that the correct frame buffer will be used + by the OpenGL library for painting operations. Likewise, the + endPaint() function is automatically called when the painting is + done, but it isn't implemented for this example. +*/ + +/*! + This is the client side constructor. + */ +//! [1] +QAhiGLWindowSurface::QAhiGLWindowSurface(QWidget *widget, + EGLDisplay eglDisplay, + EGLSurface eglSurface, + EGLContext eglContext) + : QWSGLWindowSurface(widget) +{ + d_ptr = new QAhiGLWindowSurfacePrivate(eglDisplay, eglSurface, eglContext); + d_ptr->device = new QWSGLPaintDevice(widget); + + setSurfaceFlags(QWSWindowSurface::Buffered); +} +//! [1] + +/*! + This is the server side constructor. + */ +//! [2] +QAhiGLWindowSurface::QAhiGLWindowSurface(EGLDisplay eglDisplay, + EGLSurface eglSurface, + EGLContext eglContext) +{ + d_ptr = new QAhiGLWindowSurfacePrivate(eglDisplay, eglSurface, eglContext); + setSurfaceFlags(QWSWindowSurface::Buffered); +} +//! [2] + +/*! + The destructor deletes the OpenGL structures held by the + private implementation class, and then it deletes the + private implementation class. + */ +QAhiGLWindowSurface::~QAhiGLWindowSurface() +{ + if (d_ptr->texture) + glDeleteTextures(1, &d_ptr->texture); + if (d_ptr->depthbuf) + glDeleteRenderbuffersOES(1, &d_ptr->depthbuf); + if (d_ptr->frameBufferObject) + glDeleteFramebuffersOES(1, &d_ptr->frameBufferObject); + + delete d_ptr; +} + +/*! + This function changes the geometry of the frame buffer + to the geometry in \a rect. It is called whenever the + geometry of the associated top-level window changes. It + also rebuilds the window surface's texture and binds + the OpenGL identifier to the texture for use by the + OpenGL library. + */ +//! [3] +void QAhiGLWindowSurface::setGeometry(const QRect &rect) +{ + QSize size = rect.size(); + + const QWidget *w = window(); + if (w && !w->mask().isEmpty()) { + const QRegion region = w->mask() + & rect.translated(-w->geometry().topLeft()); + size = region.boundingRect().size(); + } + + if (geometry().size() != size) { + + // Driver specific limitations: + // FBO maximimum size of 256x256 + // Depth buffer required + + d_ptr->textureWidth = qMin(256, nextPowerOfTwo(size.width())); + d_ptr->textureHeight = qMin(256, nextPowerOfTwo(size.height())); + + glGenTextures(1, &d_ptr->texture); + glBindTexture(GL_TEXTURE_2D, d_ptr->texture); + + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + const int bufSize = d_ptr->textureWidth * d_ptr->textureHeight * 2; + GLshort buf[bufSize]; + memset(buf, 0, sizeof(GLshort) * bufSize); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, d_ptr->textureWidth, + d_ptr->textureHeight, 0, + GL_RGBA, GL_UNSIGNED_BYTE, buf); + + glGenRenderbuffersOES(1, &d_ptr->depthbuf); + glBindRenderbufferOES(GL_RENDERBUFFER_EXT, d_ptr->depthbuf); + glRenderbufferStorageOES(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, + d_ptr->textureWidth, d_ptr->textureHeight); + + glGenFramebuffersOES(1, &d_ptr->frameBufferObject); + glBindFramebufferOES(GL_FRAMEBUFFER_EXT, d_ptr->frameBufferObject); + + glFramebufferTexture2DOES(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_2D, d_ptr->texture, 0); + glFramebufferRenderbufferOES(GL_FRAMEBUFFER_EXT, + GL_DEPTH_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, d_ptr->depthbuf); + glBindFramebufferOES(GL_FRAMEBUFFER_EXT, 0); + } + + QWSGLWindowSurface::setGeometry(rect); +} +//! [3] + +/*! + Returns the window surface's texture as a QByteArray. + */ +QByteArray QAhiGLWindowSurface::permanentState() const +{ + QByteArray array; + array.resize(sizeof(GLuint)); + + char *ptr = array.data(); + reinterpret_cast<GLuint*>(ptr)[0] = textureId(); + return array; +} + +/*! + Sets the window surface's texture to \a data. + */ +void QAhiGLWindowSurface::setPermanentState(const QByteArray &data) +{ + const char *ptr = data.constData(); + d_ptr->texture = reinterpret_cast<const GLuint*>(ptr)[0]; +} + +/*! + Returns the paint device being used for this window surface. + */ +QPaintDevice *QAhiGLWindowSurface::paintDevice() +{ + return d_ptr->device; +} + +/*! + Returns the window surface's texture. + */ +GLuint QAhiGLWindowSurface::textureId() const +{ + return d_ptr->texture; +} + +/*! + The \l {QWSServer} {window system} always calls this function + before any painting operations begin for this window surface. + It ensures that the correct frame buffer will be used by the + OpenGL library for painting operations. + */ +//! [4] +void QAhiGLWindowSurface::beginPaint(const QRegion ®ion) +{ + QWSGLWindowSurface::beginPaint(region); + + if (d_ptr->frameBufferObject) + glBindFramebufferOES(GL_FRAMEBUFFER_EXT, d_ptr->frameBufferObject); +} +//! [4] + +/*! + This function returns true if the window associated with + this window surface can still rendered using this window + surface class. Either the window's top-level widget must + be an \l {QGLWidget} {OpenGL widget}, or the window's + frame must be no bigger than 256 x 256. + */ +//! [5] +bool QAhiGLWindowSurface::isValid() const +{ + if (!qobject_cast<QGLWidget*>(window())) { + const QRect r = window()->frameGeometry(); + if (r.width() > 256 || r.height() > 256) + return false; + } + return true; +} +//! [5] diff --git a/examples/qws/ahigl/qwindowsurface_ahigl_p.h b/examples/qws/ahigl/qwindowsurface_ahigl_p.h new file mode 100644 index 0000000..40a82ed --- /dev/null +++ b/examples/qws/ahigl/qwindowsurface_ahigl_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINDOWSURFACE_AHIGL_P_H +#define QWINDOWSURFACE_AHIGL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of the QAhiGLWindowSurface class. This header file may change from +// version to version without notice, or even be removed. +// +// We mean it. +// + +#include <QtOpenGL/private/qglwindowsurface_qws_p.h> +#include <GLES/gl.h> +#include <GLES/egl.h> + +QT_BEGIN_NAMESPACE +class QAhiGLWindowSurfacePrivate; +QT_END_NAMESPACE + +//! [0] +class QAhiGLWindowSurface : public QWSGLWindowSurface +{ +public: + QAhiGLWindowSurface(QWidget *widget, EGLDisplay eglDisplay, + EGLSurface eglSurface, EGLContext eglContext); + QAhiGLWindowSurface(EGLDisplay eglDisplay, EGLSurface eglSurface, + EGLContext eglContext); + ~QAhiGLWindowSurface(); + + QString key() const { return QLatin1String("ahigl"); } + void setGeometry(const QRect &rect); + QPaintDevice *paintDevice(); + void beginPaint(const QRegion ®ion); + bool isValid() const; + + QByteArray permanentState() const; + void setPermanentState(const QByteArray &); + + QImage image() const { return QImage(); } + + GLuint textureId() const; + +private: + QAhiGLWindowSurfacePrivate *d_ptr; +}; +//! [0] + +#endif // QWINDOWSURFACE_AHIGL_P_H diff --git a/examples/qws/dbscreen/dbscreen.cpp b/examples/qws/dbscreen/dbscreen.cpp new file mode 100644 index 0000000..bd26848 --- /dev/null +++ b/examples/qws/dbscreen/dbscreen.cpp @@ -0,0 +1,99 @@ + /**************************************************************************** + ** + ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) + ** + ** This file is part of the examples of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ + ** + ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + ** + ****************************************************************************/ + +#include "dbscreen.h" +#include <QApplication> + +//! [0] +bool DBScreen::initDevice() +{ + if (!QLinuxFbScreen::initDevice()) + return false; + + QScreenCursor::initSoftwareCursor(); + image = new QImage(deviceWidth(), deviceHeight(), pixelFormat()); + painter = new QPainter(image); + + return true; +} +//! [0] + +//! [1] +void DBScreen::shutdownDevice() +{ + QLinuxFbScreen::shutdownDevice(); + delete painter; + delete image; +} +//! [1] + +//! [2] +void DBScreen::solidFill(const QColor &color, const QRegion ®ion) +{ + QVector<QRect> rects = region.rects(); + for (int i = 0; i < rects.size(); i++) + painter->fillRect(rects.at(i), color); +} +//! [2] + +//! [3] +void DBScreen::blit(const QImage &image, const QPoint &topLeft, const QRegion ®ion) +{ + QVector<QRect> rects = region.rects(); + for (int i = 0; i < rects.size(); i++) { + QRect destRect = rects.at(i); + QRect srcRect(destRect.x()-topLeft.x(), destRect.y()-topLeft.y(), destRect.width(), destRect.height()); + painter->drawImage(destRect.topLeft(), image, srcRect); + } +} +//! [3] + +//! [4] +void DBScreen::exposeRegion(QRegion region, int changing) +{ + QLinuxFbScreen::exposeRegion(region, changing); + QLinuxFbScreen::blit(*image, QPoint(0, 0), region); +} +//! [4] + diff --git a/examples/qws/dbscreen/dbscreen.h b/examples/qws/dbscreen/dbscreen.h new file mode 100644 index 0000000..00221e9 --- /dev/null +++ b/examples/qws/dbscreen/dbscreen.h @@ -0,0 +1,70 @@ + /**************************************************************************** + ** + ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) + ** + ** This file is part of the examples of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ + ** + ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + ** + ****************************************************************************/ + +#ifndef DBSCREEN_H +#define DBSCREEN_H + +#include <QLinuxFbScreen> +#include <QPainter> + +//! [0] +class DBScreen : public QLinuxFbScreen +{ +public: + DBScreen(int displayId) : QLinuxFbScreen(displayId) {}; + ~DBScreen() {} + bool initDevice(); + void shutdownDevice(); + void blit(const QImage &image, const QPoint &topLeft, const QRegion ®ion); + void solidFill(const QColor &color, const QRegion ®ion); + void exposeRegion(QRegion region, int changing); + +private: + QPainter *painter; + QImage *image; +}; +//! [0] + +#endif // DBSCREEN_H + diff --git a/examples/qws/dbscreen/dbscreen.pro b/examples/qws/dbscreen/dbscreen.pro new file mode 100644 index 0000000..172a02a --- /dev/null +++ b/examples/qws/dbscreen/dbscreen.pro @@ -0,0 +1,11 @@ +TEMPLATE = lib +CONFIG += plugin + +TARGET = dbscreen +target.path += $$[QT_INSTALL_PLUGINS]/gfxdrivers +INSTALLS += target + +HEADERS = dbscreen.h +SOURCES = dbscreendriverplugin.cpp \ + dbscreen.cpp + diff --git a/examples/qws/dbscreen/dbscreendriverplugin.cpp b/examples/qws/dbscreen/dbscreendriverplugin.cpp new file mode 100644 index 0000000..36587a1 --- /dev/null +++ b/examples/qws/dbscreen/dbscreendriverplugin.cpp @@ -0,0 +1,80 @@ + /**************************************************************************** + ** + ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) + ** + ** This file is part of the examples of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ + ** + ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + ** + ****************************************************************************/ + +#include <QScreenDriverPlugin> +#include "dbscreen.h" + +//! [0] +class DBScreenDriverPlugin : public QScreenDriverPlugin +{ +public: + DBScreenDriverPlugin(); + QScreen* create(const QString& key, int displayId); + QStringList keys () const; +}; +//! [0] + +DBScreenDriverPlugin::DBScreenDriverPlugin() : QScreenDriverPlugin() +{ +} + +//! [1] +QScreen* DBScreenDriverPlugin::create(const QString& key, int displayId) +{ + if (key.toLower() != "dbscreen") + return 0; + + return new DBScreen(displayId); +} +//! [1] + +//! [2] +QStringList DBScreenDriverPlugin::keys() const +{ + return QStringList() << "dbscreen"; +} +//! [2] //! [3] + +Q_EXPORT_PLUGIN2(dbscreen, DBScreenDriverPlugin) +//! [3] diff --git a/examples/qws/framebuffer/framebuffer.pro b/examples/qws/framebuffer/framebuffer.pro new file mode 100644 index 0000000..f9fe850 --- /dev/null +++ b/examples/qws/framebuffer/framebuffer.pro @@ -0,0 +1,11 @@ +TEMPLATE = app +TARGET = framebuffer +CONFIG -= qt + +SOURCES += main.c + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/qws/framebuffer +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS framebuffer.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/qws/framebuffer +INSTALLS += target sources diff --git a/examples/qws/framebuffer/main.c b/examples/qws/framebuffer/main.c new file mode 100644 index 0000000..2c2cf31 --- /dev/null +++ b/examples/qws/framebuffer/main.c @@ -0,0 +1,586 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <stdlib.h> +#include <unistd.h> +#include <stdio.h> +#include <fcntl.h> +#include <linux/fb.h> +#include <linux/kd.h> +#include <sys/mman.h> +#include <sys/ioctl.h> +#include <sys/time.h> +#include <string.h> +#include <errno.h> + +struct fb_var_screeninfo vinfo; +struct fb_fix_screeninfo finfo; +char *frameBuffer = 0; +int fbFd = 0; +int ttyFd = 0; + +void printFixedInfo() +{ + printf("Fixed screen info:\n" + "\tid: %s\n" + "\tsmem_start: 0x%lx\n" + "\tsmem_len: %d\n" + "\ttype: %d\n" + "\ttype_aux: %d\n" + "\tvisual: %d\n" + "\txpanstep: %d\n" + "\typanstep: %d\n" + "\tywrapstep: %d\n" + "\tline_length: %d\n" + "\tmmio_start: 0x%lx\n" + "\tmmio_len: %d\n" + "\taccel: %d\n" + "\n", + finfo.id, finfo.smem_start, finfo.smem_len, finfo.type, + finfo.type_aux, finfo.visual, finfo.xpanstep, finfo.ypanstep, + finfo.ywrapstep, finfo.line_length, finfo.mmio_start, + finfo.mmio_len, finfo.accel); +} + +void printVariableInfo() +{ + printf("Variable screen info:\n" + "\txres: %d\n" + "\tyres: %d\n" + "\txres_virtual: %d\n" + "\tyres_virtual: %d\n" + "\tyoffset: %d\n" + "\txoffset: %d\n" + "\tbits_per_pixel: %d\n" + "\tgrayscale: %d\n" + "\tred: offset: %2d, length: %2d, msb_right: %2d\n" + "\tgreen: offset: %2d, length: %2d, msb_right: %2d\n" + "\tblue: offset: %2d, length: %2d, msb_right: %2d\n" + "\ttransp: offset: %2d, length: %2d, msb_right: %2d\n" + "\tnonstd: %d\n" + "\tactivate: %d\n" + "\theight: %d\n" + "\twidth: %d\n" + "\taccel_flags: 0x%x\n" + "\tpixclock: %d\n" + "\tleft_margin: %d\n" + "\tright_margin: %d\n" + "\tupper_margin: %d\n" + "\tlower_margin: %d\n" + "\thsync_len: %d\n" + "\tvsync_len: %d\n" + "\tsync: %d\n" + "\tvmode: %d\n" + "\n", + vinfo.xres, vinfo.yres, vinfo.xres_virtual, vinfo.yres_virtual, + vinfo.xoffset, vinfo.yoffset, vinfo.bits_per_pixel, vinfo.grayscale, + vinfo.red.offset, vinfo.red.length, vinfo.red.msb_right, + vinfo.green.offset, vinfo.green.length, vinfo.green.msb_right, + vinfo.blue.offset, vinfo.blue.length, vinfo.blue.msb_right, + vinfo.transp.offset, vinfo.transp.length, vinfo.transp.msb_right, + vinfo.nonstd, vinfo.activate, vinfo.height, vinfo.width, + vinfo.accel_flags, vinfo.pixclock, vinfo.left_margin, + vinfo.right_margin, vinfo.upper_margin, vinfo.lower_margin, + vinfo.hsync_len, vinfo.vsync_len, vinfo.sync, vinfo.vmode); +} + +long switchToGraphicsMode() +{ + const char *const devs[] = {"/dev/tty0", "/dev/tty", "/dev/console", 0}; + const char * const *dev; + long oldMode = KD_TEXT; + + for (dev = devs; *dev; ++dev) { + ttyFd = open(*dev, O_RDWR); + if (ttyFd != -1) + break; + printf("Opening tty device %s failed: %s\n", *dev, strerror(errno)); + } + + ioctl(ttyFd, KDGETMODE, &oldMode); + if (oldMode == KD_GRAPHICS) { + printf("Was in graphics mode already. Skipping\n"); + return oldMode; + } + int ret = ioctl(ttyFd, KDSETMODE, KD_GRAPHICS); + if (ret == -1) { + printf("Switch to graphics mode failed: %s\n", strerror(errno)); + return oldMode; + } + + printf("Successfully switched to graphics mode.\n\n"); + + return oldMode; +} + +void restoreTextMode(long oldMode) +{ + if (ttyFd == -1) + return; + + ioctl(ttyFd, KDSETMODE, oldMode); + close(ttyFd); +} + +struct fb_cmap oldPalette; +struct fb_cmap palette; +int paletteSize = 0; + +void initPalette_16() +{ + if (finfo.type == FB_TYPE_PACKED_PIXELS) { + // We'll setup a grayscale map for 4bpp linear + int val = 0; + int i; + for (i = 0; i < 16; ++i) { + palette.red[i] = (val << 8) | val; + palette.green[i] = (val << 8) | val; + palette.blue[i] = (val << 8) | val; + val += 17; + } + return; + } + + // Default 16 colour palette + unsigned char reds[16] = { 0x00, 0x7F, 0xBF, 0xFF, 0xFF, 0xA2, + 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0x7F, + 0x00, 0x00, 0x00, 0x82 }; + unsigned char greens[16] = { 0x00, 0x7F, 0xBF, 0xFF, 0x00, 0xC5, + 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, + 0x00, 0x7F, 0x7F, 0x7F }; + unsigned char blues[16] = { 0x00, 0x7F, 0xBF, 0xFF, 0x00, 0x11, + 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x7F, + 0x7F, 0x7F, 0x00, 0x00 }; + + int i; + for (i = 0; i < 16; ++i) { + palette.red[i] = ((reds[i]) << 8) | reds[i]; + palette.green[i] = ((greens[i]) << 8) | greens[i]; + palette.blue[i] = ((blues[i]) << 8) | blues[i]; + palette.transp[i] = 0; + } +} + +void initPalette_256() +{ + if (vinfo.grayscale) { + int i; + for (i = 0; i < 256; ++i) { + unsigned short c = (i << 8) | i; + palette.red[i] = c; + palette.green[i] = c; + palette.blue[i] = c; + palette.transp[i] = 0; + } + return; + } + + // 6x6x6 216 color cube + int i = 0; + int ir, ig, ib; + for (ir = 0x0; ir <= 0xff; ir += 0x33) { + for (ig = 0x0; ig <= 0xff; ig += 0x33) { + for (ib = 0x0; ib <= 0xff; ib += 0x33) { + palette.red[i] = (ir << 8)|ir; + palette.green[i] = (ig << 8)|ig; + palette.blue[i] = (ib << 8)|ib; + palette.transp[i] = 0; + ++i; + } + } + } +} + +void initPalette() +{ + switch (vinfo.bits_per_pixel) { + case 8: paletteSize = 256; break; + case 4: paletteSize = 16; break; + default: break; + } + + if (!paletteSize) + return; /* not using a palette */ + + /* read old palette */ + oldPalette.start = 0; + oldPalette.len = paletteSize; + oldPalette.red = (unsigned short*)malloc(sizeof(unsigned short)*paletteSize); + oldPalette.green = (unsigned short*)malloc(sizeof(unsigned short)*paletteSize); + oldPalette.blue=(unsigned short*)malloc(sizeof(unsigned short)*paletteSize); + oldPalette.transp=(unsigned short*)malloc(sizeof(unsigned short)*paletteSize); + if (ioctl(ttyFd, FBIOGETCMAP, &oldPalette) == -1) + perror("initPalette: error reading palette"); + + /* create new palette */ + palette.start = 0; + palette.len = paletteSize; + palette.red = (unsigned short*)malloc(sizeof(unsigned short)*paletteSize); + palette.green = (unsigned short*)malloc(sizeof(unsigned short)*paletteSize); + palette.blue = (unsigned short*)malloc(sizeof(unsigned short)*paletteSize); + palette.transp = (unsigned short*)malloc(sizeof(unsigned short)*paletteSize); + switch (paletteSize) { + case 16: initPalette_16(); break; + case 256: initPalette_256(); break; + default: break; + } + + /* set new palette */ + if (ioctl(ttyFd, FBIOPUTCMAP, &palette) == -1) + perror("initPalette: error setting palette"); +} + +void resetPalette() +{ + if (paletteSize == 0) + return; + + if (ioctl(ttyFd, FBIOPUTCMAP, &oldPalette) == -1) + perror("resetPalette"); + + free(oldPalette.red); + free(oldPalette.green); + free(oldPalette.blue); + free(oldPalette.transp); + + free(palette.red); + free(palette.green); + free(palette.blue); + free(palette.transp); +} + +void drawRect_rgb32(int x0, int y0, int width, int height, int color) +{ + const int bytesPerPixel = 4; + const int stride = finfo.line_length / bytesPerPixel; + + int *dest = (int*)(frameBuffer) + + (y0 + vinfo.yoffset) * stride + + (x0 + vinfo.xoffset); + + int x, y; + for (y = 0; y < height; ++y) { + for (x = 0; x < width; ++x) { + dest[x] = color; + } + dest += stride; + } +} + +void drawRect_rgb18(int x0, int y0, int width, int height, int color) +{ + const int bytesPerPixel = 3; + const int stride = finfo.line_length - width * bytesPerPixel; + const int red = (color & 0xff0000) >> 16; + const int green = (color & 0xff00) >> 8; + const int blue = (color & 0xff); + const unsigned int packed = (blue >> 2) | + ((green >> 2) << 6) | + ((red >> 2) << 12); + const char color18[3] = { packed & 0xff, + (packed & 0xff00) >> 8, + (packed & 0xff0000) >> 16 }; + + char *dest = (char*)(frameBuffer) + + (y0 + vinfo.yoffset) * stride + + (x0 + vinfo.xoffset); + + int x, y; + for (y = 0; y < height; ++y) { + for (x = 0; x < width; ++x) { + *dest++ = color18[0]; + *dest++ = color18[1]; + *dest++ = color18[2]; + } + dest += stride; + } +} + +void drawRect_rgb16(int x0, int y0, int width, int height, int color) +{ + const int bytesPerPixel = 2; + const int stride = finfo.line_length / bytesPerPixel; + const int red = (color & 0xff0000) >> (16 + 3); + const int green = (color & 0xff00) >> (8 + 2); + const int blue = (color & 0xff) >> 3; + const short color16 = blue | (green << 5) | (red << (5 + 6)); + + short *dest = (short*)(frameBuffer) + + (y0 + vinfo.yoffset) * stride + + (x0 + vinfo.xoffset); + + int x, y; + for (y = 0; y < height; ++y) { + for (x = 0; x < width; ++x) { + dest[x] = color16; + } + dest += stride; + } +} + +void drawRect_rgb15(int x0, int y0, int width, int height, int color) +{ + const int bytesPerPixel = 2; + const int stride = finfo.line_length / bytesPerPixel; + const int red = (color & 0xff0000) >> (16 + 3); + const int green = (color & 0xff00) >> (8 + 3); + const int blue = (color & 0xff) >> 3; + const short color15 = blue | (green << 5) | (red << (5 + 5)); + + short *dest = (short*)(frameBuffer) + + (y0 + vinfo.yoffset) * stride + + (x0 + vinfo.xoffset); + + int x, y; + for (y = 0; y < height; ++y) { + for (x = 0; x < width; ++x) { + dest[x] = color15; + } + dest += stride; + } +} + +void drawRect_palette(int x0, int y0, int width, int height, int color) +{ + const int bytesPerPixel = 1; + const int stride = finfo.line_length / bytesPerPixel; + const unsigned char color8 = color; + + unsigned char *dest = (unsigned char*)(frameBuffer) + + (y0 + vinfo.yoffset) * stride + + (x0 + vinfo.xoffset); + + int x, y; + for (y = 0; y < height; ++y) { + for (x = 0; x < width; ++x) { + dest[x] = color8; + } + dest += stride; + } +} + +void drawRect(int x0, int y0, int width, int height, int color) +{ + switch (vinfo.bits_per_pixel) { + case 32: + drawRect_rgb32(x0, y0, width, height, color); + break; + case 18: + drawRect_rgb18(x0, y0, width, height, color); + break; + case 16: + drawRect_rgb16(x0, y0, width, height, color); + break; + case 15: + drawRect_rgb15(x0, y0, width, height, color); + break; + case 8: + drawRect_palette(x0, y0, width, height, color); + break; + case 4: + drawRect_palette(x0, y0, width, height, color); + break; + default: + printf("Warning: drawRect() not implemented for color depth %i\n", + vinfo.bits_per_pixel); + break; + } +} + +#define PERFORMANCE_RUN_COUNT 5 +void performSpeedTest(void* fb, int fbSize) +{ + int i, j, run; + + struct timeval startTime, endTime; + unsigned long long results[PERFORMANCE_RUN_COUNT]; + unsigned long long average; + + unsigned int* testImage; + + unsigned int randData[17] = { + 0x3A428472, 0x724B84D3, 0x26B898AB, 0x7D980E3C, 0x5345A084, + 0x6779B66B, 0x791EE4B4, 0x6E8EE3CC, 0x63AF504A, 0x18A21B33, + 0x0E26EB73, 0x022F708E, 0x1740F3B0, 0x7E2C699D, 0x0E8A570B, + 0x5F2C22FB, 0x6A742130 + }; + + printf("Frame Buffer Performance test...\n"); + + for (run=0; run<PERFORMANCE_RUN_COUNT; ++run) { + + /* Generate test image with random(ish) data: */ + testImage = (unsigned int*) malloc(fbSize); + j = run; + for (i=0; i < (int)(fbSize / sizeof(int)); ++i) { + testImage[i] = randData[j]; + j++; + if (j >= 17) + j = 0; + } + + gettimeofday(&startTime, NULL); + memcpy(fb, testImage, fbSize); + gettimeofday(&endTime, NULL); + + long secsDiff = endTime.tv_sec - startTime.tv_sec; + results[run] = secsDiff * 1000000 + (endTime.tv_usec - startTime.tv_usec); + + free(testImage); + } + + + average = 0; + for (i=0; i<PERFORMANCE_RUN_COUNT; ++i) + average += results[i]; + average = average / PERFORMANCE_RUN_COUNT; + + printf(" Average: %llu usecs\n", average); + printf(" Bandwidth: %.03f MByte/Sec\n", (fbSize / 1048576.0) / ((double)average / 1000000.0)); + printf(" Max. FPS: %.03f fps\n\n", 1000000.0 / (double)average); + + /* Clear the framebuffer back to black again: */ + memset(fb, 0, fbSize); +} + +int main(int argc, char **argv) +{ + long int screensize = 0; + int doGraphicsMode = 1; + long oldKdMode = KD_TEXT; + const char *devfile = "/dev/fb0"; + int nextArg = 1; + + if (nextArg < argc) { + if (strncmp("nographicsmodeswitch", argv[nextArg], + strlen("nographicsmodeswitch")) == 0) + { + ++nextArg; + doGraphicsMode = 0; + } + } + if (nextArg < argc) + devfile = argv[nextArg++]; + + /* Open the file for reading and writing */ + fbFd = open(devfile, O_RDWR); + if (fbFd == -1) { + perror("Error: cannot open framebuffer device"); + exit(1); + } + printf("The framebuffer device was opened successfully.\n\n"); + + /* Get fixed screen information */ + if (ioctl(fbFd, FBIOGET_FSCREENINFO, &finfo) == -1) { + perror("Error reading fixed information"); + exit(2); + } + + printFixedInfo(); + + /* Figure out the size of the screen in bytes */ + screensize = finfo.smem_len; + + /* Map the device to memory */ + frameBuffer = (char *)mmap(0, screensize, + PROT_READ | PROT_WRITE, MAP_SHARED, + fbFd, 0); + if (frameBuffer == MAP_FAILED) { + perror("Error: Failed to map framebuffer device to memory"); + exit(4); + } + printf("The framebuffer device was mapped to memory successfully.\n" + "\n"); + + if (doGraphicsMode) + oldKdMode = switchToGraphicsMode(); + + /* Get variable screen information */ + if (ioctl(fbFd, FBIOGET_VSCREENINFO, &vinfo) == -1) { + perror("Error reading variable information"); + exit(3); + } + + printVariableInfo(); + + performSpeedTest(frameBuffer, screensize); + + initPalette(); + + if (paletteSize == 0) { + printf("Will draw 3 rectangles on the screen,\n" + "they should be colored red, green and blue (in that order).\n"); + drawRect(vinfo.xres / 8, vinfo.yres / 8, + vinfo.xres / 4, vinfo.yres / 4, + 0xffff0000); + drawRect(vinfo.xres * 3 / 8, vinfo.yres * 3 / 8, + vinfo.xres / 4, vinfo.yres / 4, + 0xff00ff00); + drawRect(vinfo.xres * 5 / 8, vinfo.yres * 5 / 8, + vinfo.xres / 4, vinfo.yres / 4, + 0xff0000ff); + } else { + printf("Will rectangles from the 16 first entries in the color palette" + " on the screen\n"); + int y; + int x; + for (y = 0; y < 4; ++y) { + for (x = 0; x < 4; ++x) { + drawRect(vinfo.xres / 4 * x, vinfo.yres / 4 * y, + vinfo.xres / 4, vinfo.yres / 4, + 4 * y + x); + } + } + } + + sleep(5); + + resetPalette(); + + printf(" Done.\n"); + + if (doGraphicsMode) + restoreTextMode(oldKdMode); + + munmap(frameBuffer, screensize); + close(fbFd); + return 0; +} diff --git a/examples/qws/mousecalibration/calibration.cpp b/examples/qws/mousecalibration/calibration.cpp new file mode 100644 index 0000000..7e344e0 --- /dev/null +++ b/examples/qws/mousecalibration/calibration.cpp @@ -0,0 +1,145 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "calibration.h" + +#include <QWSPointerCalibrationData> +#include <QPainter> +#include <QFile> +#include <QTimer> +#include <QApplication> +#include <QDesktopWidget> +#include <QMouseEvent> +#include <QScreen> +#include <QWSServer> + +//! [0] +Calibration::Calibration() +{ + QRect desktop = QApplication::desktop()->geometry(); + desktop.moveTo(QPoint(0, 0)); + setGeometry(desktop); + + setFocusPolicy(Qt::StrongFocus); + setFocus(); + setModal(true); +//! [0] + +//! [1] + int width = qt_screen->deviceWidth(); + int height = qt_screen->deviceHeight(); + + int dx = width / 10; + int dy = height / 10; + + QPoint *points = data.screenPoints; + points[QWSPointerCalibrationData::TopLeft] = QPoint(dx, dy); + points[QWSPointerCalibrationData::BottomLeft] = QPoint(dx, height - dy); + points[QWSPointerCalibrationData::BottomRight] = QPoint(width - dx, height - dy); + points[QWSPointerCalibrationData::TopRight] = QPoint(width - dx, dy); + points[QWSPointerCalibrationData::Center] = QPoint(width / 2, height / 2); +//! [1] + +//! [2] + pressCount = 0; +} +//! [2] + +//! [3] +Calibration::~Calibration() +{ +} +//! [3] + +//! [4] +int Calibration::exec() +{ + QWSServer::mouseHandler()->clearCalibration(); + grabMouse(); + activateWindow(); + int ret = QDialog::exec(); + releaseMouse(); + return ret; +} +//! [4] + +//! [5] +void Calibration::paintEvent(QPaintEvent*) +{ + QPainter p(this); + p.fillRect(rect(), Qt::white); + + QPoint point = data.screenPoints[pressCount]; + + // Map to logical coordinates in case the screen is transformed + QSize screenSize(qt_screen->deviceWidth(), qt_screen->deviceHeight()); + point = qt_screen->mapFromDevice(point, screenSize); + + p.fillRect(point.x() - 6, point.y() - 1, 13, 3, Qt::black); + p.fillRect(point.x() - 1, point.y() - 6, 3, 13, Qt::black); +} +//! [5] + +//! [6] +void Calibration::mouseReleaseEvent(QMouseEvent *event) +{ + // Map from device coordinates in case the screen is transformed + QSize screenSize(qt_screen->width(), qt_screen->height()); + QPoint p = qt_screen->mapToDevice(event->pos(), screenSize); + + data.devPoints[pressCount] = p; + + if (++pressCount < 5) + repaint(); + else + accept(); +} +//! [6] + +//! [7] +void Calibration::accept() +{ + Q_ASSERT(pressCount == 5); + QWSServer::mouseHandler()->calibrate(&data); + QDialog::accept(); +} +//! [7] + diff --git a/examples/qws/mousecalibration/calibration.h b/examples/qws/mousecalibration/calibration.h new file mode 100644 index 0000000..ae862e5 --- /dev/null +++ b/examples/qws/mousecalibration/calibration.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CALIBRATION_H +#define CALIBRATION_H + +#include <QDialog> +#include <QWSPointerCalibrationData> + +//! [0] +class Calibration : public QDialog +{ +public: + Calibration(); + ~Calibration(); + int exec(); + +protected: + void paintEvent(QPaintEvent*); + void mouseReleaseEvent(QMouseEvent*); + void accept(); + +private: + QWSPointerCalibrationData data; + int pressCount; +}; +//! [0] + + +#endif diff --git a/examples/qws/mousecalibration/main.cpp b/examples/qws/mousecalibration/main.cpp new file mode 100644 index 0000000..c318383 --- /dev/null +++ b/examples/qws/mousecalibration/main.cpp @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QApplication> +#include <QMessageBox> +#include <QTimer> +#include <QWSServer> + +#include "calibration.h" +#include "scribblewidget.h" + +//! [0] +int main(int argc, char **argv) +{ + QApplication app(argc, argv, QApplication::GuiServer); + + if (!QWSServer::mouseHandler()) + qFatal("No mouse handler installed"); + + { + QMessageBox message; + message.setText("<p>Please press once at each of the marks " + "shown in the next screen.</p>" + "<p>This messagebox will timout after 10 seconds " + "if you are unable to close it.</p>"); + QTimer::singleShot(10 * 1000, &message, SLOT(accept())); + message.exec(); + } + +//! [0] //! [1] + Calibration cal; + cal.exec(); +//! [1] + +//! [2] + { + QMessageBox message; + message.setText("<p>The next screen will let you test the calibration " + "by drawing into a widget.</p><p>This program will " + "automatically close after 20 seconds.<p>"); + QTimer::singleShot(10 * 1000, &message, SLOT(accept())); + message.exec(); + } + + ScribbleWidget scribble; + scribble.showMaximized(); + scribble.show(); + + app.setActiveWindow(&scribble); + QTimer::singleShot(20 * 1000, &app, SLOT(quit())); + + return app.exec(); +} +//! [2] + diff --git a/examples/qws/mousecalibration/mousecalibration.pro b/examples/qws/mousecalibration/mousecalibration.pro new file mode 100644 index 0000000..bd31853 --- /dev/null +++ b/examples/qws/mousecalibration/mousecalibration.pro @@ -0,0 +1,11 @@ +HEADERS += calibration.h \ + scribblewidget.h +SOURCES += calibration.cpp \ + scribblewidget.cpp \ + main.cpp + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/qws/mousecalibration +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS *.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/qws/mousecalibration +INSTALLS += target sources diff --git a/examples/qws/mousecalibration/scribblewidget.cpp b/examples/qws/mousecalibration/scribblewidget.cpp new file mode 100644 index 0000000..255afd0 --- /dev/null +++ b/examples/qws/mousecalibration/scribblewidget.cpp @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "scribblewidget.h" + +ScribbleWidget::ScribbleWidget(QWidget *parent) + : QWidget(parent) +{ + scribbling = false; +} + +void ScribbleWidget::resizeEvent(QResizeEvent *e) +{ + image = QImage(e->size(), QImage::Format_RGB32); + image.fill(QColor(Qt::white).rgb()); +} + +void ScribbleWidget::mousePressEvent(QMouseEvent *event) +{ + if (event->button() != Qt::LeftButton) + return; + + lastPoint = event->pos(); + scribbling = true; +} + +void ScribbleWidget::mouseMoveEvent(QMouseEvent *event) +{ + if ((event->buttons() & Qt::LeftButton) && scribbling) + drawLineTo(event->pos()); +} + +void ScribbleWidget::mouseReleaseEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton && scribbling) { + drawLineTo(event->pos()); + scribbling = false; + } +} + +void ScribbleWidget::paintEvent(QPaintEvent *) +{ + QPainter painter(this); + painter.drawImage(QPoint(0, 0), image); +} + +void ScribbleWidget::drawLineTo(const QPoint &endPoint) +{ + QPainter painter(&image); + painter.setPen(QPen(Qt::blue, 1, Qt::SolidLine, + Qt::RoundCap, Qt::RoundJoin)); + painter.drawLine(lastPoint, endPoint); + update(); + lastPoint = endPoint; +} diff --git a/examples/qws/mousecalibration/scribblewidget.h b/examples/qws/mousecalibration/scribblewidget.h new file mode 100644 index 0000000..6693082 --- /dev/null +++ b/examples/qws/mousecalibration/scribblewidget.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SCRIBBLEWIDGET_H +#define SCRIBBLEWIDGET_H + +#include <QLabel> +#include <QMouseEvent> +#include <QResizeEvent> +#include <QImage> +#include <QPainter> + +class ScribbleWidget : public QWidget +{ +public: + ScribbleWidget(QWidget *parent = 0); + + void resizeEvent(QResizeEvent *e); + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void paintEvent(QPaintEvent *); + +private: + void drawLineTo(const QPoint &endPoint); + +private: + bool scribbling; + QPoint lastPoint; + QImage image; +}; + +#endif // SCRIBBLEWIDGET_H diff --git a/examples/qws/qws.pro b/examples/qws/qws.pro new file mode 100644 index 0000000..fb3c3c7 --- /dev/null +++ b/examples/qws/qws.pro @@ -0,0 +1,7 @@ +TEMPLATE = subdirs +SUBDIRS = framebuffer mousecalibration simpledecoration + +# install +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS README *.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/qws +INSTALLS += sources diff --git a/examples/qws/simpledecoration/analogclock.cpp b/examples/qws/simpledecoration/analogclock.cpp new file mode 100644 index 0000000..28155ba --- /dev/null +++ b/examples/qws/simpledecoration/analogclock.cpp @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui> + +#include "analogclock.h" + +AnalogClock::AnalogClock(QWidget *parent) + : QWidget(parent) +{ + QTimer *timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(update())); + timer->start(1000); + + setWindowTitle(tr("Analog Clock")); + resize(200, 200); +} + +void AnalogClock::paintEvent(QPaintEvent *) +{ + static const QPoint hourHand[3] = { + QPoint(7, 8), + QPoint(-7, 8), + QPoint(0, -40) + }; + static const QPoint minuteHand[3] = { + QPoint(7, 8), + QPoint(-7, 8), + QPoint(0, -70) + }; + + QColor hourColor(127, 0, 127); + QColor minuteColor(0, 127, 127, 191); + + int side = qMin(width(), height()); + QTime time = QTime::currentTime(); + + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + painter.translate(width() / 2, height() / 2); + painter.scale(side / 200.0, side / 200.0); + + painter.setPen(Qt::NoPen); + painter.setBrush(hourColor); + + painter.save(); + painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0))); + painter.drawConvexPolygon(hourHand, 3); + painter.restore(); + + painter.setPen(hourColor); + + for (int i = 0; i < 12; ++i) { + painter.drawLine(88, 0, 96, 0); + painter.rotate(30.0); + } + + painter.setPen(Qt::NoPen); + painter.setBrush(minuteColor); + + painter.save(); + painter.rotate(6.0 * (time.minute() + time.second() / 60.0)); + painter.drawConvexPolygon(minuteHand, 3); + painter.restore(); + + painter.setPen(minuteColor); + + for (int j = 0; j < 60; ++j) { + if ((j % 5) != 0) + painter.drawLine(92, 0, 96, 0); + painter.rotate(6.0); + } +} diff --git a/examples/qws/simpledecoration/analogclock.h b/examples/qws/simpledecoration/analogclock.h new file mode 100644 index 0000000..f779744 --- /dev/null +++ b/examples/qws/simpledecoration/analogclock.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ANALOGCLOCK_H +#define ANALOGCLOCK_H + +#include <QWidget> + +class AnalogClock : public QWidget +{ + Q_OBJECT + +public: + AnalogClock(QWidget *parent = 0); + +protected: + void paintEvent(QPaintEvent *event); +}; + +#endif diff --git a/examples/qws/simpledecoration/main.cpp b/examples/qws/simpledecoration/main.cpp new file mode 100644 index 0000000..597f5b3 --- /dev/null +++ b/examples/qws/simpledecoration/main.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QApplication> +#include "analogclock.h" +#include "mydecoration.h" + +//! [create application] +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + MyDecoration *decoration = new MyDecoration(); + app.qwsSetDecoration(decoration); +//! [create application] + +//! [start application] + AnalogClock clock; + clock.show(); + + return app.exec(); +} +//! [start application] diff --git a/examples/qws/simpledecoration/mydecoration.cpp b/examples/qws/simpledecoration/mydecoration.cpp new file mode 100644 index 0000000..282bc88 --- /dev/null +++ b/examples/qws/simpledecoration/mydecoration.cpp @@ -0,0 +1,375 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui> +#include "mydecoration.h" + +/* XPM */ +static const char * const _close_button[] = { +"16 16 3 1", +" c none", +". c #ffafaf", +"x c #000000", +" ", +" xxxxxxxxxxxxxx ", +" x............x ", +" x.x........x.x ", +" x..x......x..x ", +" x...x....x...x ", +" x....x..x....x ", +" x.....xx.....x ", +" x.....xx.....x ", +" x....x..x....x ", +" x...x....x...x ", +" x..x......x..x ", +" x.x........x.x ", +" x............x ", +" xxxxxxxxxxxxxx ", +" "}; + +static const char * const _normalize_button[] = { +"16 16 4 1", +" c none", +". c #dfdfff", +"o c #7f7f7f", +"x c #000000", +" ", +" xxxxxxxxxxxxxx ", +" xx...........x ", +" x.x..........x ", +" x..x..x......x ", +" x...xxx......x ", +" x...xxx......x ", +" x..xxxx......x ", +" x............x ", +" x.......xxxx.x ", +" x.......x..x.x ", +" x.......x..x.x ", +" x.......xxxx.x ", +" x............x ", +" xxxxxxxxxxxxxx ", +" "}; + +static const char * const _maximize_button[] = { +"16 16 4 1", +" c none", +". c #dfdfff", +"o c #7f7f7f", +"x c #000000", +" ", +" xxxxxxxxxxxxxx ", +" x............x ", +" x.......xxxx.x ", +" x........xxx.x ", +" x........xxx.x ", +" x.......x..x.x ", +" x......x.....x ", +" x.....x......x ", +" x.oooo.......x ", +" x.o..o.......x ", +" x.o..o.......x ", +" x.oooo.......x ", +" x............x ", +" xxxxxxxxxxxxxx ", +" "}; + +static const char * const _help_button[] = { +"16 16 3 1", +" c none", +". c #afffdf", +"x c #000000", +" ", +" xxxxxxxxxxxxxx ", +" x............x ", +" x....xxxx....x ", +" x..xx....xx..x ", +" x.xx......xx.x ", +" x.xx......xx.x ", +" x........xx..x ", +" x......xx....x ", +" x.....xx.....x ", +" x.....xx.....x ", +" x............x ", +" x.....xx.....x ", +" x............x ", +" xxxxxxxxxxxxxx ", +" "}; + +//! [constructor start] +MyDecoration::MyDecoration() + : QDecorationDefault() +{ + border = 4; + titleHeight = 24; + buttonWidth = 20; + buttonHeight = 20; + buttonMargin = 2; + buttonHints << Qt::Window + << Qt::WindowMaximizeButtonHint + << Qt::WindowContextHelpButtonHint; + //! [constructor start] + + //! [map window flags to decoration regions] + buttonHintMap[Qt::Window] = Close; + buttonHintMap[Qt::WindowMaximizeButtonHint] = Maximize; + buttonHintMap[Qt::WindowContextHelpButtonHint] = Help; + //! [map window flags to decoration regions] + + //! [map decoration regions to pixmaps] + normalButtonPixmaps[Close] = QPixmap(_close_button); + normalButtonPixmaps[Maximize] = QPixmap(_maximize_button); + normalButtonPixmaps[Normalize] = QPixmap(_normalize_button); + normalButtonPixmaps[Help] = QPixmap(_help_button); + + maximizedButtonPixmaps[Close] = QPixmap(_close_button); + maximizedButtonPixmaps[Maximize] = QPixmap(_normalize_button); + maximizedButtonPixmaps[Normalize] = QPixmap(_normalize_button); + maximizedButtonPixmaps[Help] = QPixmap(_help_button); + //! [map decoration regions to pixmaps] + + //! [constructor end] + stateRegions << Close << Maximize << Help; +} +//! [constructor end] + +//! [region start] +QRegion MyDecoration::region(const QWidget *widget, const QRect &insideRect, + int decorationRegion) +{ + //! [region start] + //! [calculate the positions of buttons based on the window flags used] + QHash<DecorationRegion, int> buttons; + Qt::WindowFlags flags = widget->windowFlags(); + int dx = -buttonMargin - buttonWidth; + + foreach (Qt::WindowType button, buttonHints) { + if (flags & button) { + int x = (buttons.size() + 1) * dx; + buttons[buttonHintMap[button]] = x; + } + } + //! [calculate the positions of buttons based on the window flags used] + + //! [calculate the extent of the title] + int titleRightMargin = buttons.size() * dx; + + QRect outsideRect(insideRect.left() - border, + insideRect.top() - titleHeight - border, + insideRect.width() + 2 * border, + insideRect.height() + titleHeight + 2 * border); + //! [calculate the extent of the title] + + //! [check for all regions] + QRegion region; + + if (decorationRegion == All) { + region += QRegion(outsideRect) - QRegion(insideRect); + return region; + } + //! [check for all regions] + + //! [compose a region based on the decorations specified] + if (decorationRegion & Title) { + QRect rect = outsideRect.adjusted(border, border, -border, 0); + rect.setHeight(titleHeight); + + // Adjust the width to accommodate buttons. + rect.setWidth(qMax(0, rect.width() + titleRightMargin)); + region += rect; + } + if (decorationRegion & Top) { + QRect rect = outsideRect.adjusted(border, 0, -border, 0); + rect.setHeight(border); + region += rect; + } + if (decorationRegion & Left) { + QRect rect = outsideRect.adjusted(0, border, 0, -border); + rect.setWidth(border); + region += rect; + } + if (decorationRegion & Right) { + QRect rect = outsideRect.adjusted(0, border, 0, -border); + rect.setLeft(rect.right() + 1 - border); + region += rect; + } + if (decorationRegion & Bottom) { + QRect rect = outsideRect.adjusted(border, 0, -border, 0); + rect.setTop(rect.bottom() + 1 - border); + region += rect; + } + if (decorationRegion & TopLeft) { + QRect rect = outsideRect; + rect.setWidth(border); + rect.setHeight(border); + region += rect; + } + if (decorationRegion & TopRight) { + QRect rect = outsideRect; + rect.setLeft(rect.right() + 1 - border); + rect.setHeight(border); + region += rect; + } + if (decorationRegion & BottomLeft) { + QRect rect = outsideRect; + rect.setWidth(border); + rect.setTop(rect.bottom() + 1 - border); + region += rect; + } + if (decorationRegion & BottomRight) { + QRect rect = outsideRect; + rect.setLeft(rect.right() + 1 - border); + rect.setTop(rect.bottom() + 1 - border); + region += rect; + } + //! [compose a region based on the decorations specified] + + //! [add a region for each button only if it is present] + foreach (QDecoration::DecorationRegion testRegion, stateRegions) { + if (decorationRegion & testRegion and buttons.contains(testRegion)) { + // Inside the title rectangle + QRect rect = outsideRect.adjusted(border, border, -border, 0); + rect.setHeight(titleHeight); + + dx = buttons[testRegion]; + rect.setLeft(rect.right() + 1 + dx); + rect.setWidth(buttonWidth + buttonMargin); + region += rect; + } + } + //! [add a region for each button only if it is present] + + //! [region end] + return region; +} +//! [region end] + +//! [paint start] +bool MyDecoration::paint(QPainter *painter, const QWidget *widget, + int decorationRegion, DecorationState state) +{ + if (decorationRegion == None) + return false; + //! [paint start] + + //! [paint different regions] + bool handled = false; + + QPalette palette = QApplication::palette(); + QHash<DecorationRegion, QPixmap> buttonPixmaps; + + if (widget->windowState() == Qt::WindowMaximized) + buttonPixmaps = maximizedButtonPixmaps; + else + buttonPixmaps = normalButtonPixmaps; + + if (decorationRegion & Title) { + QRect rect = QDecoration::region(widget, Title).boundingRect(); + painter->fillRect(rect, palette.brush(QPalette::Base)); + painter->save(); + painter->setPen(QPen(palette.color(QPalette::Text))); + painter->drawText(rect, Qt::AlignCenter, widget->windowTitle()); + painter->restore(); + handled = true; + } + if (decorationRegion & Top) { + QRect rect = QDecoration::region(widget, Top).boundingRect(); + painter->fillRect(rect, palette.brush(QPalette::Dark)); + handled = true; + } + if (decorationRegion & Left) { + QRect rect = QDecoration::region(widget, Left).boundingRect(); + painter->fillRect(rect, palette.brush(QPalette::Dark)); + handled = true; + } + if (decorationRegion & Right) { + QRect rect = QDecoration::region(widget, Right).boundingRect(); + painter->fillRect(rect, palette.brush(QPalette::Dark)); + handled = true; + } + if (decorationRegion & Bottom) { + QRect rect = QDecoration::region(widget, Bottom).boundingRect(); + painter->fillRect(rect, palette.brush(QPalette::Dark)); + handled = true; + } + if (decorationRegion & TopLeft) { + QRect rect = QDecoration::region(widget, TopLeft).boundingRect(); + painter->fillRect(rect, palette.brush(QPalette::Dark)); + handled = true; + } + if (decorationRegion & TopRight) { + QRect rect = QDecoration::region(widget, TopRight).boundingRect(); + painter->fillRect(rect, palette.brush(QPalette::Dark)); + handled = true; + } + if (decorationRegion & BottomLeft) { + QRect rect = QDecoration::region(widget, BottomLeft).boundingRect(); + painter->fillRect(rect, palette.brush(QPalette::Dark)); + handled = true; + } + if (decorationRegion & BottomRight) { + QRect rect = QDecoration::region(widget, BottomRight).boundingRect(); + painter->fillRect(rect, palette.brush(QPalette::Dark)); + handled = true; + } + //! [paint different regions] + + //! [paint buttons] + int margin = (titleHeight - 16) / 2; + Qt::WindowFlags flags = widget->windowFlags(); + + foreach (DecorationRegion testRegion, stateRegions) { + if (decorationRegion & testRegion && flags & buttonHintMap.key(testRegion)) { + QRect rect = QDecoration::region( + widget, testRegion).boundingRect(); + painter->fillRect(rect, palette.brush(QPalette::Base)); + + QRect buttonRect = rect.adjusted(0, margin, -buttonMargin - margin, + -buttonMargin); + painter->drawPixmap(buttonRect.topLeft(), buttonPixmaps[testRegion]); + handled = true; + } + } + //! [paint buttons] + + //! [paint end] + return handled; +} +//! [paint end] diff --git a/examples/qws/simpledecoration/mydecoration.h b/examples/qws/simpledecoration/mydecoration.h new file mode 100644 index 0000000..dffac30 --- /dev/null +++ b/examples/qws/simpledecoration/mydecoration.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MYDECORATION_H +#define MYDECORATION_H + +#include <QDecorationDefault> +#include <QHash> +#include <QPixmap> +#include <QRegion> +#include <Qt> + +//! [decoration class definition] +class MyDecoration : public QDecorationDefault +{ +public: + MyDecoration(); + QRegion region(const QWidget *widget, const QRect &insideRect, int decorationRegion); + bool paint(QPainter *painter, const QWidget *widget, int decorationRegion, DecorationState state); + +private: + int border; + int buttonHeight; + int buttonMargin; + int buttonWidth; + int titleHeight; + QHash<Qt::WindowType, DecorationRegion> buttonHintMap; + QHash<DecorationRegion, QPixmap> normalButtonPixmaps; + QHash<DecorationRegion, QPixmap> maximizedButtonPixmaps; + QVector<Qt::WindowType> buttonHints; + QVector<DecorationRegion> stateRegions; +}; +//! [decoration class definition] + +#endif diff --git a/examples/qws/simpledecoration/simpledecoration.pro b/examples/qws/simpledecoration/simpledecoration.pro new file mode 100644 index 0000000..b409878 --- /dev/null +++ b/examples/qws/simpledecoration/simpledecoration.pro @@ -0,0 +1,12 @@ +TEMPLATE = app +HEADERS = analogclock.h \ + mydecoration.h +SOURCES = analogclock.cpp \ + main.cpp \ + mydecoration.cpp + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/qws/simpledecoration +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS *.pro +sources.path = $$[QT_INSTALL_EXAMPLES]/qws/simpledecoration +INSTALLS += target sources diff --git a/examples/qws/svgalib/README b/examples/qws/svgalib/README new file mode 100644 index 0000000..0b2831f --- /dev/null +++ b/examples/qws/svgalib/README @@ -0,0 +1,5 @@ +This is the SVGA screen driver plugin example from Qt 4.4. The code does +not compile with Qt 4.5, because the internal graphics engine has changed. + +This is unsupported code, provided for convenience in case there is +interest in porting it to Qt 4.5. diff --git a/examples/qws/svgalib/svgalib.pro b/examples/qws/svgalib/svgalib.pro new file mode 100644 index 0000000..8a47c1d --- /dev/null +++ b/examples/qws/svgalib/svgalib.pro @@ -0,0 +1,19 @@ +TEMPLATE = lib +CONFIG += plugin + +LIBS += -lvgagl -lvga + +TARGET = svgalibscreen +target.path = $$[QT_INSTALL_PLUGINS]/gfxdrivers +INSTALLS += target + +HEADERS = svgalibscreen.h \ + svgalibpaintengine.h \ + svgalibsurface.h \ + svgalibpaintdevice.h +SOURCES = svgalibscreen.cpp \ + svgalibpaintengine.cpp \ + svgalibsurface.cpp \ + svgalibpaintdevice.cpp \ + svgalibplugin.cpp + diff --git a/examples/qws/svgalib/svgalibpaintdevice.cpp b/examples/qws/svgalib/svgalibpaintdevice.cpp new file mode 100644 index 0000000..b4e0276 --- /dev/null +++ b/examples/qws/svgalib/svgalibpaintdevice.cpp @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "svgalibpaintdevice.h" +#include "svgalibpaintengine.h" + +#include <QApplication> +#include <QDesktopWidget> + +SvgalibPaintDevice::SvgalibPaintDevice(QWidget *w) + : QCustomRasterPaintDevice(w) +{ + pengine = new SvgalibPaintEngine; +} + +SvgalibPaintDevice::~SvgalibPaintDevice() +{ + delete pengine; +} + +int SvgalibPaintDevice::metric(PaintDeviceMetric m) const +{ + if (m == PdmWidth) + return QApplication::desktop()->screenGeometry().width(); + else if (m == PdmHeight) + return QApplication::desktop()->screenGeometry().height(); + return QCustomRasterPaintDevice::metric(m); +} + diff --git a/examples/qws/svgalib/svgalibpaintdevice.h b/examples/qws/svgalib/svgalibpaintdevice.h new file mode 100644 index 0000000..bf6cc7a --- /dev/null +++ b/examples/qws/svgalib/svgalibpaintdevice.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SVGALIBPAINTDEVICE_H +#define SVGALIBPAINTDEVICE_H + +#include "svgalibpaintengine.h" +#include <private/qpaintengine_raster_p.h> +#include <qscreen_qws.h> + +//! [0] +class SvgalibPaintDevice : public QCustomRasterPaintDevice +{ +public: + SvgalibPaintDevice(QWidget *w); + ~SvgalibPaintDevice(); + + void* memory() const { return QScreen::instance()->base(); } + + QPaintEngine *paintEngine() const { return pengine; } + int metric(PaintDeviceMetric m) const; + +private: + SvgalibPaintEngine *pengine; +}; +//! [0] + +#endif // SVGALIBPAINTDEVICE_H diff --git a/examples/qws/svgalib/svgalibpaintengine.cpp b/examples/qws/svgalib/svgalibpaintengine.cpp new file mode 100644 index 0000000..3621db7 --- /dev/null +++ b/examples/qws/svgalib/svgalibpaintengine.cpp @@ -0,0 +1,192 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "svgalibpaintengine.h" + +#include <QColor> +#include <vga.h> +#include <vgagl.h> + +SvgalibPaintEngine::SvgalibPaintEngine() +{ +} + +SvgalibPaintEngine::~SvgalibPaintEngine() +{ +} + +//! [0] +bool SvgalibPaintEngine::begin(QPaintDevice *dev) +{ + device = dev; + pen = Qt::NoPen; + simplePen = true; + brush = Qt::NoBrush; + simpleBrush = true; + matrix = QMatrix(); + simpleMatrix = true; + setClip(QRect(0, 0, device->width(), device->height())); + opaque = true; + aliased = true; + sourceOver = true; + + return QRasterPaintEngine::begin(dev); +} +//! [0] + +//! [1] +bool SvgalibPaintEngine::end() +{ + gl_setclippingwindow(0, 0, device->width() - 1, device->height() - 1); + return QRasterPaintEngine::end(); +} +//! [1] + +//! [2] +void SvgalibPaintEngine::updateState(const QPaintEngineState &state) +{ + QPaintEngine::DirtyFlags flags = state.state(); + + if (flags & DirtyTransform) { + matrix = state.matrix(); + simpleMatrix = (matrix.m12() == 0 && matrix.m21() == 0); + } + + if (flags & DirtyPen) { + pen = state.pen(); + simplePen = (pen.width() == 0 || pen.widthF() <= 1) + && (pen.style() == Qt::NoPen || pen.style() == Qt::SolidLine) + && (pen.color().alpha() == 255); + } + + if (flags & DirtyBrush) { + brush = state.brush(); + simpleBrush = (brush.style() == Qt::SolidPattern + || brush.style() == Qt::NoBrush) + && (brush.color().alpha() == 255); + } + + if (flags & DirtyClipRegion) + setClip(state.clipRegion()); + + if (flags & DirtyClipEnabled) { + clipEnabled = state.isClipEnabled(); + updateClip(); + } + + if (flags & DirtyClipPath) { + setClip(QRegion()); + simpleClip = false; + } + + if (flags & DirtyCompositionMode) { + const QPainter::CompositionMode m = state.compositionMode(); + sourceOver = (m == QPainter::CompositionMode_SourceOver); + } + + if (flags & DirtyOpacity) + opaque = (state.opacity() == 256); + + if (flags & DirtyHints) + aliased = !(state.renderHints() & QPainter::Antialiasing); + + QRasterPaintEngine::updateState(state); +} +//! [2] + +//! [3] +void SvgalibPaintEngine::setClip(const QRegion ®ion) +{ + if (region.isEmpty()) + clip = QRect(0, 0, device->width(), device->height()); + else + clip = matrix.map(region) & QRect(0, 0, device->width(), device->height()); + clipEnabled = true; + updateClip(); +} +//! [3] + +//! [4] +void SvgalibPaintEngine::updateClip() +{ + QRegion clipRegion = QRect(0, 0, device->width(), device->height()); + + if (!systemClip().isEmpty()) + clipRegion &= systemClip(); + if (clipEnabled) + clipRegion &= clip; + + simpleClip = (clipRegion.rects().size() <= 1); + + const QRect r = clipRegion.boundingRect(); + gl_setclippingwindow(r.left(), r.top(), + r.x() + r.width(), + r.y() + r.height()); +} +//! [4] + +//! [5] +void SvgalibPaintEngine::drawRects(const QRect *rects, int rectCount) +{ + const bool canAccelerate = simplePen && simpleBrush && simpleMatrix + && simpleClip && opaque && aliased + && sourceOver; + if (!canAccelerate) { + QRasterPaintEngine::drawRects(rects, rectCount); + return; + } + + for (int i = 0; i < rectCount; ++i) { + const QRect r = matrix.mapRect(rects[i]); + if (brush != Qt::NoBrush) { + gl_fillbox(r.left(), r.top(), r.width(), r.height(), + brush.color().rgba()); + } + if (pen != Qt::NoPen) { + const int c = pen.color().rgba(); + gl_hline(r.left(), r.top(), r.right(), c); + gl_hline(r.left(), r.bottom(), r.right(), c); + gl_line(r.left(), r.top(), r.left(), r.bottom(), c); + gl_line(r.right(), r.top(), r.right(), r.bottom(), c); + } + } +} +//! [5] diff --git a/examples/qws/svgalib/svgalibpaintengine.h b/examples/qws/svgalib/svgalibpaintengine.h new file mode 100644 index 0000000..1fa9770 --- /dev/null +++ b/examples/qws/svgalib/svgalibpaintengine.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SVGALIBPAINTENGINE_H +#define SVGALIBPAINTENGINE_H + +//! [0] +#include <private/qpaintengine_raster_p.h> + +class SvgalibPaintEngine : public QRasterPaintEngine +{ +public: + SvgalibPaintEngine(); + ~SvgalibPaintEngine(); + + bool begin(QPaintDevice *device); + bool end(); + void updateState(const QPaintEngineState &state); + void drawRects(const QRect *rects, int rectCount); + +private: + void setClip(const QRegion ®ion); + void updateClip(); + + QPen pen; + bool simplePen; + QBrush brush; + bool simpleBrush; + QMatrix matrix; + bool simpleMatrix; + QRegion clip; + bool clipEnabled; + bool simpleClip; + bool opaque; + bool aliased; + bool sourceOver; + QPaintDevice *device; +}; +//! [0] + +#endif // SVGALIBPAINTENGINE_H diff --git a/examples/qws/svgalib/svgalibplugin.cpp b/examples/qws/svgalib/svgalibplugin.cpp new file mode 100644 index 0000000..080a350 --- /dev/null +++ b/examples/qws/svgalib/svgalibplugin.cpp @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "svgalibscreen.h" + +#include <QScreenDriverPlugin> +#include <QStringList> + +class SvgalibPlugin : public QScreenDriverPlugin +{ +public: + SvgalibPlugin(); + + QStringList keys() const; + QScreen *create(const QString&, int displayId); +}; + +SvgalibPlugin::SvgalibPlugin() + : QScreenDriverPlugin() +{ +} + +QStringList SvgalibPlugin::keys() const +{ + return (QStringList() << "svgalib"); +} + +QScreen* SvgalibPlugin::create(const QString& driver, int displayId) +{ + if (driver.toLower() != "svgalib") + return 0; + + return new SvgalibScreen(displayId); +} + +Q_EXPORT_STATIC_PLUGIN(Svgalib) +Q_EXPORT_PLUGIN2(svgalibscreendriver, SvgalibPlugin) diff --git a/examples/qws/svgalib/svgalibscreen.cpp b/examples/qws/svgalib/svgalibscreen.cpp new file mode 100644 index 0000000..1961d3c --- /dev/null +++ b/examples/qws/svgalib/svgalibscreen.cpp @@ -0,0 +1,354 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "svgalibscreen.h" +#include "svgalibsurface.h" + +#include <QVector> +#include <QApplication> +#include <QColor> +#include <QWidget> + +#include <math.h> + +static int getModeDepth(vga_modeinfo *mode) +{ + const int bits = int(log2(mode->colors)); + if (bits == 24 && mode->bytesperpixel == 4) + return 32; + return bits; +} + +//! [0] +bool SvgalibScreen::connect(const QString &displaySpec) +{ + int mode = vga_getdefaultmode(); + if (mode <= 0) { + qCritical("SvgalibScreen::connect(): invalid vga mode"); + return false; + } + + vga_modeinfo *modeinfo = vga_getmodeinfo(mode); + + QScreen::lstep = modeinfo->linewidth; + QScreen::dw = QScreen::w = modeinfo->width; + QScreen::dh = QScreen::h = modeinfo->height; + QScreen::d = getModeDepth(modeinfo); + QScreen::size = QScreen::lstep * dh; + QScreen::data = 0; + + switch (depth()) { + case 32: + setPixelFormat(QImage::Format_ARGB32_Premultiplied); + break; + case 24: + setPixelFormat(QImage::Format_RGB888); + break; + case 16: + setPixelFormat(QImage::Format_RGB16); + break; + case 15: + setPixelFormat(QImage::Format_RGB555); + break; + default: + break; + } + + const int dpi = 72; + QScreen::physWidth = qRound(QScreen::dw * 25.4 / dpi); + QScreen::physHeight = qRound(QScreen::dh * 25.4 / dpi); + + const QStringList args = displaySpec.split(QLatin1Char(':'), + QString::SkipEmptyParts); + grayscale = args.contains(QLatin1String("grayscale"), Qt::CaseInsensitive); + + return true; +} +//! [0] + +void SvgalibScreen::initColorMap() +{ + const int numColors = vga_getcolors(); + if (numColors == 2 || numColors > 256) { + screencols = 0; + return; // not a palette based mode + } + + if (numColors == 16) { + if (grayscale) { + for (int i = 0; i < 256; ++i) { + const int c = i * 16 / 256; + vga_setpalette(i, c, c, c); + } + screencols = 256; // XXX: takes advantage of optimization in alloc() + } else { // read in EGA palette + int r, g, b; + for (int i = 0; i < 16; ++i) { + vga_getpalette(i, &r, &g, &b); + screenclut[i] = qRgb(r, g, b); + } + screencols = 16; + } + + return; + } + + Q_ASSERT(numColors == 256); + + if (grayscale) { + for (int i = 0; i < 256; ++i) { + const int c = i * 64 / 256; + vga_setpalette(i, c, c, c); + } + } else { + int i = 0; + +#if 0 + // read in EGA palette + while (i < 16) { + int r, g, b; + vga_getpalette(i, &r, &g, &b); + screenclut[i] = qRgb(r, g, b); + ++i; + } + screencols = 16; +#endif + + // 6 * 6 * 6 color cube + for (int r = 0; r < 6; ++r) { + for (int g = 0; g < 6; ++g) { + for (int b = 0; b < 6; ++b) { + vga_setpalette(i, r * 64/6, g * 64/6, b * 64/6); + screenclut[i] = qRgb(r * 256/6, g * 256/6, b * 256/6); + ++i; + } + } + } + screencols = i; + + while (i < 256) { + screenclut[i] = qRgb(0, 0, 0); + ++i; + } + } +} + +//! [1] +bool SvgalibScreen::initDevice() +{ + if (vga_init() != 0) { + qCritical("SvgalibScreen::initDevice(): unable to initialize svgalib"); + return false; + } + + int mode = vga_getdefaultmode(); + if (vga_setmode(mode) == -1) { + qCritical("SvgalibScreen::initialize(): unable to set graphics mode"); + return false; + } + + if (gl_setcontextvga(mode) != 0) { + qCritical("SvgalibScreen::initDevice(): unable to set vga context"); + return false; + } + context = gl_allocatecontext(); + gl_getcontext(context); + + vga_modeinfo *modeinfo = vga_getmodeinfo(mode); + if (modeinfo->flags & IS_LINEAR) + QScreen::data = vga_getgraphmem(); + + initColorMap(); + + QScreenCursor::initSoftwareCursor(); + return true; +} +//! [1] + +//! [2] +void SvgalibScreen::shutdownDevice() +{ + gl_freecontext(context); + vga_setmode(TEXT); +} +//! [2] + +//! [3] +void SvgalibScreen::disconnect() +{ +} +//! [3] + +//! [4] +void SvgalibScreen::solidFill(const QColor &color, const QRegion ®) +{ + int c; + if (depth() == 4 || depth() == 8) + c = alloc(color.red(), color.green(), color.blue()); + else + c = gl_rgbcolor(color.red(), color.green(), color.blue()); + + const QVector<QRect> rects = (reg & region()).rects(); + for (int i = 0; i < rects.size(); ++i) { + const QRect r = rects.at(i); + gl_fillbox(r.left(), r.top(), r.width(), r.height(), c); + } +} +//! [4] + +void SvgalibScreen::blit16To8(const QImage &image, + const QPoint &topLeft, const QRegion ®ion) +{ + const int imageStride = image.bytesPerLine() / 2; + const QVector<QRect> rects = region.rects(); + + for (int i = 0; i < rects.size(); ++i) { + const QRect r = rects.at(i).translated(-topLeft); + int y = r.y(); + const quint16 *s = reinterpret_cast<const quint16*>(image.scanLine(y)); + + while (y <= r.bottom()) { + int x1 = r.x(); + while (x1 <= r.right()) { + const quint16 c = s[x1]; + int x2 = x1; + // find span length + while ((x2+1 < r.right()) && (s[x2+1] == c)) + ++x2; + gl_hline(x1 + topLeft.x(), y + topLeft.y(), x2 + topLeft.x(), + qt_colorConvert<quint8, quint16>(c, 0)); + x1 = x2 + 1; + } + s += imageStride; + ++y; + } + } +} + +void SvgalibScreen::blit32To8(const QImage &image, + const QPoint &topLeft, const QRegion ®ion) +{ + const int imageStride = image.bytesPerLine() / 4; + const QVector<QRect> rects = region.rects(); + + for (int i = 0; i < rects.size(); ++i) { + const QRect r = rects.at(i).translated(-topLeft); + int y = r.y(); + const quint32 *s = reinterpret_cast<const quint32*>(image.scanLine(y)); + + while (y <= r.bottom()) { + int x1 = r.x(); + while (x1 <= r.right()) { + const quint32 c = s[x1]; + int x2 = x1; + // find span length + while ((x2+1 < r.right()) && (s[x2+1] == c)) + ++x2; + gl_hline(x1 + topLeft.x(), y + topLeft.y(), x2 + topLeft.x(), + qt_colorConvert<quint8, quint32>(c, 0)); + x1 = x2 + 1; + } + s += imageStride; + ++y; + } + } +} + +//! [5] +void SvgalibScreen::blit(const QImage &img, const QPoint &topLeft, + const QRegion ®) +{ + if (depth() == 8) { + switch (img.format()) { + case QImage::Format_RGB16: + blit16To8(img, topLeft, reg); + return; + case QImage::Format_RGB32: + case QImage::Format_ARGB32: + case QImage::Format_ARGB32_Premultiplied: + blit32To8(img, topLeft, reg); + return; + default: + break; + } + } + + if (img.format() != pixelFormat()) { + if (base()) + QScreen::blit(img, topLeft, reg); + return; + } + + const QVector<QRect> rects = (reg & region()).rects(); + + for (int i = 0; i < rects.size(); ++i) { + const QRect r = rects.at(i); + gl_putboxpart(r.x(), r.y(), r.width(), r.height(), + img.width(), img.height(), + static_cast<void*>(const_cast<uchar*>(img.bits())), + r.x() - topLeft.x(), r.y() - topLeft.y()); + } +} +//! [5] + +//! [7] +QWSWindowSurface* SvgalibScreen::createSurface(QWidget *widget) const +{ + if (base()) { + static int onScreenPaint = -1; + if (onScreenPaint == -1) + onScreenPaint = qgetenv("QT_ONSCREEN_PAINT").toInt(); + + if (onScreenPaint > 0 || widget->testAttribute(Qt::WA_PaintOnScreen)) + return new SvgalibSurface(widget); + } + return QScreen::createSurface(widget); +} +//! [7] + +//! [8] +QWSWindowSurface* SvgalibScreen::createSurface(const QString &key) const +{ + if (key == QLatin1String("svgalib")) + return new SvgalibSurface; + return QScreen::createSurface(key); +} +//! [8] diff --git a/examples/qws/svgalib/svgalibscreen.h b/examples/qws/svgalib/svgalibscreen.h new file mode 100644 index 0000000..4d32b7c --- /dev/null +++ b/examples/qws/svgalib/svgalibscreen.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SVGALIBSCREEN_H +#define SVGALIBSCREEN_H + +#include <QScreen> + +#include <vga.h> +#include <vgagl.h> + +//! [0] +class SvgalibScreen : public QScreen +{ +public: + SvgalibScreen(int displayId) : QScreen(displayId) {} + ~SvgalibScreen() {} + + bool connect(const QString &displaySpec); + bool initDevice(); + void shutdownDevice(); + void disconnect(); + + void setMode(int, int, int) {} + void blank(bool) {} + + void blit(const QImage &img, const QPoint &topLeft, const QRegion ®ion); + void solidFill(const QColor &color, const QRegion ®ion); +//! [0] + + QWSWindowSurface* createSurface(QWidget *widget) const; + QWSWindowSurface* createSurface(const QString &key) const; + +//! [1] +private: + void initColorMap(); + void blit16To8(const QImage &image, + const QPoint &topLeft, const QRegion ®ion); + void blit32To8(const QImage &image, + const QPoint &topLeft, const QRegion ®ion); + + GraphicsContext *context; +}; +//! [1] + +#endif // SVGALIBSCREEN_H diff --git a/examples/qws/svgalib/svgalibsurface.cpp b/examples/qws/svgalib/svgalibsurface.cpp new file mode 100644 index 0000000..8e7e6b6 --- /dev/null +++ b/examples/qws/svgalib/svgalibsurface.cpp @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "svgalibsurface.h" +#include "svgalibpaintdevice.h" + +#include <vgagl.h> + +SvgalibSurface::SvgalibSurface() : QWSWindowSurface(), pdevice(0) +{ + setSurfaceFlags(Opaque); +} + +SvgalibSurface::SvgalibSurface(QWidget *w) + : QWSWindowSurface(w) +{ + setSurfaceFlags(Opaque); + pdevice = new SvgalibPaintDevice(w); +} + +SvgalibSurface::~SvgalibSurface() +{ + delete pdevice; +} + +void SvgalibSurface::setGeometry(const QRect &rect) +{ + QWSWindowSurface::setGeometry(rect); +} + +QPoint SvgalibSurface::painterOffset() const +{ + return geometry().topLeft() + QWSWindowSurface::painterOffset(); +} + +//! [0] +bool SvgalibSurface::scroll(const QRegion ®ion, int dx, int dy) +{ + const QVector<QRect> rects = region.rects(); + for (int i = 0; i < rects.size(); ++i) { + const QRect r = rects.at(i); + gl_copybox(r.left(), r.top(), r.width(), r.height(), + r.left() + dx, r.top() + dy); + } + + return true; +} +//! [0] + diff --git a/examples/qws/svgalib/svgalibsurface.h b/examples/qws/svgalib/svgalibsurface.h new file mode 100644 index 0000000..c33d51a --- /dev/null +++ b/examples/qws/svgalib/svgalibsurface.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SVGALIBSURFACE_H +#define SVGALIBSURFACE_H + +#include "svgalibpaintengine.h" +#include "svgalibpaintdevice.h" +#include <private/qwindowsurface_qws_p.h> + +class SvgalibPaintDevice; + +//! [0] +class SvgalibSurface : public QWSWindowSurface +{ +public: + SvgalibSurface(); + SvgalibSurface(QWidget *w); + ~SvgalibSurface(); + + void setGeometry(const QRect &rect); + bool isValid() const { return true; } + bool scroll(const QRegion ®ion, int dx, int dy); + QString key() const { return QLatin1String("svgalib"); } + + bool attach(const QByteArray &) { return true; } + void detach() {} + + QImage image() const { return QImage(); } + QPaintDevice *paintDevice() { return pdevice; } + QPoint painterOffset() const; + +private: + SvgalibPaintDevice *pdevice; +}; +//! [0] + +#endif // SVGALIBSURFACE_H |