diff options
author | Frans Englich <frans.englich@nokia.com> | 2009-10-16 08:11:14 (GMT) |
---|---|---|
committer | Frans Englich <frans.englich@nokia.com> | 2009-10-16 08:11:14 (GMT) |
commit | 4f48e43dc4f8237875d7d4a61bf4e55ab92e3941 (patch) | |
tree | 0436d256b8812a5ff638d799710d3b20b4459716 /src/plugins/gfxdrivers | |
parent | 9935ad5366463429ed4aa9b8db03c4605586f866 (diff) | |
parent | 2348200bfb277450cb2e79f6054d95b3041b10db (diff) | |
download | Qt-4f48e43dc4f8237875d7d4a61bf4e55ab92e3941.zip Qt-4f48e43dc4f8237875d7d4a61bf4e55ab92e3941.tar.gz Qt-4f48e43dc4f8237875d7d4a61bf4e55ab92e3941.tar.bz2 |
Merge commit 'origin/4.6' into mmfphonon
Diffstat (limited to 'src/plugins/gfxdrivers')
12 files changed, 236 insertions, 25 deletions
diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp index 8662df6..57b1950 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp @@ -207,7 +207,7 @@ void QDirectFBMouseHandlerPrivate::readMouseData() int wheel = 0; if (input.type == DIET_AXISMOTION) { -#ifdef QT_NO_DIRECTFB_LAYER +#if defined(QT_NO_DIRECTFB_LAYER) || defined(QT_DIRECTFB_WINDOW_AS_CURSOR) if (input.flags & DIEF_AXISABS) { switch (input.axis) { case DIAI_X: x = input.axisabs; break; diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 0f7a6de..449bc0d 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -99,8 +99,11 @@ public: qint64 cursorImageKey; QDirectFBScreen *q; + static QDirectFBScreen *instance; }; +QDirectFBScreen *QDirectFBScreenPrivate::instance = 0; + QDirectFBScreenPrivate::QDirectFBScreenPrivate(QDirectFBScreen *qptr) : QWSGraphicsSystem(qptr), dfb(0), flipFlags(DSFLIP_NONE), directFBFlags(QDirectFBScreen::NoFlags), alphaPixmapFormat(QImage::Format_Invalid), @@ -802,13 +805,21 @@ void QDirectFBScreenCursor::set(const QImage &image, int hotx, int hoty) QDirectFBScreen::QDirectFBScreen(int display_id) : QScreen(display_id, DirectFBClass), d_ptr(new QDirectFBScreenPrivate(this)) { + QDirectFBScreenPrivate::instance = this; } QDirectFBScreen::~QDirectFBScreen() { + if (QDirectFBScreenPrivate::instance == this) + QDirectFBScreenPrivate::instance = 0; delete d_ptr; } +QDirectFBScreen *QDirectFBScreen::instance() +{ + return QDirectFBScreenPrivate::instance; +} + int QDirectFBScreen::depth(DFBSurfacePixelFormat format) { switch (format) { @@ -1050,6 +1061,26 @@ static inline bool setIntOption(const QStringList &arguments, const QString &var return false; } +static inline QColor colorFromName(const QString &name) +{ + QRegExp rx("#([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])"); + rx.setCaseSensitivity(Qt::CaseInsensitive); + if (rx.exactMatch(name)) { + Q_ASSERT(rx.numCaptures() == 4); + int ints[4]; + int i; + for (i=0; i<4; ++i) { + bool ok; + ints[i] = rx.cap(i + 1).toUInt(&ok, 16); + if (!ok || ints[i] > 255) + break; + } + if (i == 4) + return QColor(ints[0], ints[1], ints[2], ints[3]); + } + return QColor(name); +} + bool QDirectFBScreen::connect(const QString &displaySpec) { DFBResult result = DFB_OK; @@ -1282,18 +1313,50 @@ bool QDirectFBScreen::connect(const QString &displaySpec) #endif #ifdef QT_DIRECTFB_WM surface->Release(surface); + QColor backgroundColor; #else - QRegExp backgroundColorRegExp(QLatin1String("bgcolor=?(.+)")); + QColor &backgroundColor = d_ptr->backgroundColor; +#endif + + QRegExp backgroundColorRegExp(QLatin1String("bgcolor=(.+)")); backgroundColorRegExp.setCaseSensitivity(Qt::CaseInsensitive); if (displayArgs.indexOf(backgroundColorRegExp) != -1) { - d_ptr->backgroundColor.setNamedColor(backgroundColorRegExp.cap(1)); + backgroundColor = colorFromName(backgroundColorRegExp.cap(1)); } - if (!d_ptr->backgroundColor.isValid()) - d_ptr->backgroundColor = Qt::green; - d_ptr->primarySurface->Clear(d_ptr->primarySurface, d_ptr->backgroundColor.red(), - d_ptr->backgroundColor.green(), d_ptr->backgroundColor.blue(), - d_ptr->backgroundColor.alpha()); +#ifdef QT_NO_DIRECTFB_WM + if (!backgroundColor.isValid()) + backgroundColor = Qt::green; + d_ptr->primarySurface->Clear(d_ptr->primarySurface, backgroundColor.red(), + backgroundColor.green(), backgroundColor.blue(), + backgroundColor.alpha()); d_ptr->primarySurface->Flip(d_ptr->primarySurface, 0, d_ptr->flipFlags); +#else + if (backgroundColor.isValid()) { + DFBResult result = d_ptr->dfbLayer->SetCooperativeLevel(d_ptr->dfbLayer, DLSCL_ADMINISTRATIVE); + if (result != DFB_OK) { + DirectFBError("QDirectFBScreen::connect " + "Unable to set cooperative level", result); + } + result = d_ptr->dfbLayer->SetBackgroundColor(d_ptr->dfbLayer, backgroundColor.red(), backgroundColor.green(), + backgroundColor.blue(), backgroundColor.alpha()); + if (result != DFB_OK) { + DirectFBError("QDirectFBScreenCursor::connect: " + "Unable to set background color", result); + } + + result = d_ptr->dfbLayer->SetBackgroundMode(d_ptr->dfbLayer, DLBM_COLOR); + if (result != DFB_OK) { + DirectFBError("QDirectFBScreenCursor::connect: " + "Unable to set background mode", result); + } + + result = d_ptr->dfbLayer->SetCooperativeLevel(d_ptr->dfbLayer, DLSCL_SHARED); + if (result != DFB_OK) { + DirectFBError("QDirectFBScreen::connect " + "Unable to set cooperative level", result); + } + + } #endif return true; diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h index 5e8c5c6..0520cdc 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h @@ -54,8 +54,8 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) -#if !defined QT_NO_DIRECTFB_SUBSURFACE && !defined QT_DIRECTFB_SUBSURFACE -#define QT_DIRECTFB_SUBSURFACE +#if !defined QT_DIRECTFB_SUBSURFACE && !defined QT_NO_DIRECTFB_SUBSURFACE +#define QT_NO_DIRECTFB_SUBSURFACE #endif #if !defined QT_NO_DIRECTFB_LAYER && !defined QT_DIRECTFB_LAYER #define QT_DIRECTFB_LAYER @@ -163,12 +163,7 @@ public: QWSWindowSurface *createSurface(QWidget *widget) const; QWSWindowSurface *createSurface(const QString &key) const; - static inline QDirectFBScreen *instance() { - QScreen *inst = QScreen::instance(); - Q_ASSERT(!inst || inst->classId() == QScreen::DirectFBClass); - return static_cast<QDirectFBScreen*>(inst); - } - + static QDirectFBScreen *instance(); void waitIdle(); IDirectFBSurface *surfaceForWidget(const QWidget *widget, QRect *rect) const; #ifdef QT_DIRECTFB_SUBSURFACE diff --git a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c index ac9dc8d..c1b655a 100644 --- a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c +++ b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.c @@ -617,6 +617,16 @@ void pvrQwsGetGeometry(PvrQwsDrawable *drawable, PvrQwsRect *rect) *rect = drawable->rect; } +void pvrQwsSetRotation(PvrQwsDrawable *drawable, int angle) +{ + if (drawable->rotationAngle != angle) { + drawable->rotationAngle = angle; + + /* Force the buffers to be recreated if the rotation angle changes */ + pvrQwsInvalidateBuffers(drawable); + } +} + int pvrQwsGetStride(PvrQwsDrawable *drawable) { if (drawable->backBuffersValid) diff --git a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.h b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.h index 952ff6f..b9e035f 100644 --- a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.h +++ b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable.h @@ -126,6 +126,9 @@ void pvrQwsSetGeometry(PvrQwsDrawable *drawable, const PvrQwsRect *rect); /* Get the current geometry for a drawable */ void pvrQwsGetGeometry(PvrQwsDrawable *drawable, PvrQwsRect *rect); +/* Set the rotation angle in degrees */ +void pvrQwsSetRotation(PvrQwsDrawable *drawable, int angle); + /* Get the line stride for a drawable. Returns zero if the buffers are not allocated or have been invalidated */ int pvrQwsGetStride(PvrQwsDrawable *drawable); diff --git a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable_p.h b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable_p.h index cf80a90..dcd4e4f 100644 --- a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable_p.h +++ b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwsdrawable_p.h @@ -114,6 +114,7 @@ struct _PvrQwsDrawable int isFullScreen; int strideBytes; int stridePixels; + int rotationAngle; PvrQwsSwapFunction swapFunction; void *userData; PvrQwsDrawable *nextWinId; diff --git a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwswsegl.c b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwswsegl.c index 253f39f..28b2251 100644 --- a/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwswsegl.c +++ b/src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwswsegl.c @@ -132,6 +132,16 @@ static WSEGLError wseglCloseDisplay(WSEGLDisplayHandle display) return WSEGL_SUCCESS; } +static WSEGLRotationAngle wseglRotationValue(int degrees) +{ + switch (degrees) { + case 90: return WSEGL_ROTATE_90; + case 180: return WSEGL_ROTATE_180; + case 270: return WSEGL_ROTATE_270; + default: return WSEGL_ROTATE_0; + } +} + /* Create the WSEGL drawable version of a native window */ static WSEGLError wseglCreateWindowDrawable (WSEGLDisplayHandle display, WSEGLConfig *config, @@ -152,7 +162,7 @@ static WSEGLError wseglCreateWindowDrawable *drawable = (WSEGLDrawableHandle)screen; if (!pvrQwsAllocBuffers(screen)) return WSEGL_OUT_OF_MEMORY; - *rotationAngle = WSEGL_ROTATE_0; + *rotationAngle = wseglRotationValue(screen->rotationAngle); return WSEGL_SUCCESS; } @@ -163,7 +173,7 @@ static WSEGLError wseglCreateWindowDrawable /* The drawable is ready to go */ *drawable = (WSEGLDrawableHandle)draw; - *rotationAngle = WSEGL_ROTATE_0; + *rotationAngle = wseglRotationValue(draw->rotationAngle); if (!pvrQwsAllocBuffers(draw)) return WSEGL_OUT_OF_MEMORY; return WSEGL_SUCCESS; diff --git a/src/plugins/gfxdrivers/powervr/README b/src/plugins/gfxdrivers/powervr/README index 4dce87f..322a6b2 100644 --- a/src/plugins/gfxdrivers/powervr/README +++ b/src/plugins/gfxdrivers/powervr/README @@ -51,6 +51,11 @@ on the device with: hellogl_es -qws +The driver also supports screen rotation if Qt is configured with the +-qt-gfx-transformed option and the QWS_DISPLAY variable is wrapped in a +"Transformed" declaration: + + Transformed:powervr:mmWidth40:mmHeight54:Rot90:0 Know Issues: * A QGLWidget may not have window decorations if it is a top-level window. diff --git a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp index 61f2225..1dec9ea 100644 --- a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp +++ b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.cpp @@ -44,6 +44,9 @@ #include "pvrqwsdrawable_p.h" #include <QRegExp> #include <qwindowsystem_qws.h> +#ifndef QT_NO_QWS_TRANSFORMED +#include <qscreentransformed_qws.h> +#endif #include <sys/stat.h> #include <sys/ioctl.h> #include <sys/kd.h> @@ -62,6 +65,7 @@ PvrEglScreen::PvrEglScreen(int displayId) ttyfd = -1; doGraphicsMode = true; oldKdMode = KD_TEXT; + parent = 0; // Make sure that the EGL layer is initialized and the drivers loaded. EGLDisplay dpy = eglGetDisplay((EGLNativeDisplayType)EGL_DEFAULT_DISPLAY); @@ -192,7 +196,7 @@ bool PvrEglScreen::hasOpenGL() QWSWindowSurface* PvrEglScreen::createSurface(QWidget *widget) const { if (qobject_cast<QGLWidget*>(widget)) - return new PvrEglWindowSurface(widget, (QScreen *)this, displayId); + return new PvrEglWindowSurface(widget, (PvrEglScreen *)this, displayId); return QScreen::createSurface(widget); } @@ -206,6 +210,67 @@ QWSWindowSurface* PvrEglScreen::createSurface(const QString &key) const } //![1] +#ifndef QT_NO_QWS_TRANSFORMED + +static const QScreen *parentScreen + (const QScreen *current, const QScreen *lookingFor) +{ + if (!current) + return 0; + switch (current->classId()) { + case QScreen::ProxyClass: + case QScreen::TransformedClass: { + const QScreen *child = + static_cast<const QProxyScreen *>(current)->screen(); + if (child == lookingFor) + return current; + else + return parentScreen(child, lookingFor); + } + // Not reached. + + case QScreen::MultiClass: { + QList<QScreen *> screens = current->subScreens(); + foreach (QScreen *screen, screens) { + if (screen == lookingFor) + return current; + const QScreen *parent = parentScreen(screen, lookingFor); + if (parent) + return parent; + } + } + break; + + default: break; + } + return 0; +} + +int PvrEglScreen::transformation() const +{ + // We need to search for our parent screen, which is assumed to be + // "Transformed". If it isn't, then there is no transformation. + // There is no direct method to get the parent screen so we need + // to search every screen until we find ourselves. + if (!parent && qt_screen != this) + parent = parentScreen(qt_screen, this); + if (!parent) + return 0; + if (parent->classId() != QScreen::TransformedClass) + return 0; + return 90 * static_cast<const QTransformedScreen *>(parent) + ->transformation(); +} + +#else + +int PvrEglScreen::transformation() const +{ + return 0; +} + +#endif + void PvrEglScreen::sync() { // Put code here to synchronize 2D and 3D operations if necessary. diff --git a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.h b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.h index 8bf42c7..5769e70 100644 --- a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.h +++ b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglscreen.h @@ -46,16 +46,18 @@ #include <QGLScreen> #include "pvrqwsdrawable.h" +class PvrEglScreen; + class PvrEglScreenSurfaceFunctions : public QGLScreenSurfaceFunctions { public: - PvrEglScreenSurfaceFunctions(QScreen *s, int screenNum) + PvrEglScreenSurfaceFunctions(PvrEglScreen *s, int screenNum) : screen(s), displayId(screenNum) {} bool createNativeWindow(QWidget *widget, EGLNativeWindowType *native); private: - QScreen *screen; + PvrEglScreen *screen; int displayId; }; @@ -80,6 +82,8 @@ public: QWSWindowSurface* createSurface(QWidget *widget) const; QWSWindowSurface* createSurface(const QString &key) const; + int transformation() const; + private: void sync(); void openTty(); @@ -89,6 +93,7 @@ private: int ttyfd, oldKdMode; QString ttyDevice; bool doGraphicsMode; + mutable const QScreen *parent; }; #endif diff --git a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.cpp b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.cpp index 2c5ac21..4a3787f 100644 --- a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.cpp +++ b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.cpp @@ -46,7 +46,7 @@ #include <QWSDisplay> PvrEglWindowSurface::PvrEglWindowSurface - (QWidget *widget, QScreen *screen, int screenNum) + (QWidget *widget, PvrEglScreen *screen, int screenNum) : QWSGLWindowSurface(widget) { setSurfaceFlags(QWSWindowSurface::Opaque); @@ -63,6 +63,7 @@ PvrEglWindowSurface::PvrEglWindowSurface pvrRect.y = pos.y(); pvrRect.width = size.width(); pvrRect.height = size.height(); + transformRects(&pvrRect, 1); // Try to recover a previous PvrQwsDrawable object for the widget // if there is one. This can happen when a PvrEglWindowSurface @@ -75,6 +76,7 @@ PvrEglWindowSurface::PvrEglWindowSurface pvrQwsSetGeometry(drawable, &pvrRect); else drawable = pvrQwsCreateWindow(screenNum, (long)widget, &pvrRect); + pvrQwsSetRotation(drawable, screen->transformation()); } PvrEglWindowSurface::PvrEglWindowSurface() @@ -113,7 +115,9 @@ void PvrEglWindowSurface::setGeometry(const QRect &rect) pvrRect.y = rect.y(); pvrRect.width = rect.width(); pvrRect.height = rect.height(); + transformRects(&pvrRect, 1); pvrQwsSetGeometry(drawable, &pvrRect); + pvrQwsSetRotation(drawable, screen->transformation()); } QWSGLWindowSurface::setGeometry(rect); } @@ -127,7 +131,9 @@ bool PvrEglWindowSurface::move(const QPoint &offset) pvrRect.y = rect.y(); pvrRect.width = rect.width(); pvrRect.height = rect.height(); + transformRects(&pvrRect, 1); pvrQwsSetGeometry(drawable, &pvrRect); + pvrQwsSetRotation(drawable, screen->transformation()); } return QWSGLWindowSurface::move(offset); } @@ -200,7 +206,9 @@ void PvrEglWindowSurface::setDirectRegion(const QRegion &r, int id) pvrRect.y = rect.y(); pvrRect.width = rect.width(); pvrRect.height = rect.height(); + transformRects(&pvrRect, 1); pvrQwsSetVisibleRegion(drawable, &pvrRect, 1); + pvrQwsSetRotation(drawable, screen->transformation()); if (!pvrQwsSwapBuffers(drawable, 1)) screen->solidFill(QColor(0, 0, 0), region); } else { @@ -213,9 +221,53 @@ void PvrEglWindowSurface::setDirectRegion(const QRegion &r, int id) pvrRects[index].width = rect.width(); pvrRects[index].height = rect.height(); } + transformRects(pvrRects, rects.size()); pvrQwsSetVisibleRegion(drawable, pvrRects, rects.size()); + pvrQwsSetRotation(drawable, screen->transformation()); if (!pvrQwsSwapBuffers(drawable, 1)) screen->solidFill(QColor(0, 0, 0), region); delete [] pvrRects; } } + +void PvrEglWindowSurface::transformRects(PvrQwsRect *rects, int count) const +{ + switch (screen->transformation()) { + case 0: break; + + case 90: + { + for (int index = 0; index < count; ++index) { + int x = rects[index].y; + int y = screen->height() - (rects[index].x + rects[index].width); + rects[index].x = x; + rects[index].y = y; + qSwap(rects[index].width, rects[index].height); + } + } + break; + + case 180: + { + for (int index = 0; index < count; ++index) { + int x = screen->width() - (rects[index].x + rects[index].width); + int y = screen->height() - (rects[index].y + rects[index].height); + rects[index].x = x; + rects[index].y = y; + } + } + break; + + case 270: + { + for (int index = 0; index < count; ++index) { + int x = screen->width() - (rects[index].y + rects[index].height); + int y = rects[index].x; + rects[index].x = x; + rects[index].y = y; + qSwap(rects[index].width, rects[index].height); + } + } + break; + } +} diff --git a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.h b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.h index 58a5fb2..b0a161c 100644 --- a/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.h +++ b/src/plugins/gfxdrivers/powervr/pvreglscreen/pvreglwindowsurface.h @@ -45,12 +45,12 @@ #include <private/qglwindowsurface_qws_p.h> #include "pvrqwsdrawable.h" -class QScreen; +class PvrEglScreen; class PvrEglWindowSurface : public QWSGLWindowSurface { public: - PvrEglWindowSurface(QWidget *widget, QScreen *screen, int screenNum); + PvrEglWindowSurface(QWidget *widget, PvrEglScreen *screen, int screenNum); PvrEglWindowSurface(); ~PvrEglWindowSurface(); @@ -76,8 +76,10 @@ public: private: QWidget *widget; PvrQwsDrawable *drawable; - QScreen *screen; + PvrEglScreen *screen; QPaintDevice *pdevice; + + void transformRects(PvrQwsRect *rects, int count) const; }; #endif |