Merge branch 'master' of git://scm.dev.nokia.troll.no/qt/qtbase-staging

* 'master' of git://scm.dev.nokia.troll.no/qt/qtbase-staging:
  Full translucent background support in xcb and xlib backend.
  Lighthouse xcb and xlib: Add support for transparency of GLX windows.
  Lighthouse minimal: Add support for transparency
  Compile fixes for Xlib plugin.
This commit is contained in:
Qt Continuous Integration System 2011-05-20 03:08:34 +10:00
commit 3a88b3c9e6
18 changed files with 149 additions and 55 deletions

View File

@ -731,12 +731,19 @@ QPlatformWindowFormat QWidget::platformWindowFormat() const
{
Q_D(const QWidget);
QPlatformWindowFormat format;
QTLWExtra *extra = d->maybeTopData();
if (extra){
return extra->platformWindowFormat;
format = extra->platformWindowFormat;
} else {
return QPlatformWindowFormat::defaultFormat();
format = QPlatformWindowFormat::defaultFormat();
}
if (testAttribute(Qt::WA_TranslucentBackground))
format.setAlpha(true);
return format;
}
void QWidgetPrivate::createSysExtra()

View File

@ -150,6 +150,8 @@ bool QGLContext::chooseContext(const QGLContext* shareContext)
if (shareContext) {
winFormat.setSharedContext(shareContext->d_func()->platformContext);
}
if (widget->testAttribute(Qt::WA_TranslucentBackground))
winFormat.setAlpha(true);
winFormat.setWindowApi(QPlatformWindowFormat::OpenGL);
winFormat.setWindowSurface(false);
widget->setPlatformWindowFormat(winFormat);

View File

@ -542,19 +542,27 @@ void QGLWindowSurface::beginPaint(const QRegion &)
d_ptr->did_paint = true;
updateGeometry();
if (!context())
return;
int clearFlags = 0;
if (context()->d_func()->workaround_needsFullClearOnEveryFrame)
QGLContext *ctx = reinterpret_cast<QGLContext *>(window()->d_func()->extraData()->glContext);
if (!ctx)
return;
if (ctx->d_func()->workaround_needsFullClearOnEveryFrame)
clearFlags = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
else if (context()->format().alpha())
else if (ctx->format().alpha())
clearFlags = GL_COLOR_BUFFER_BIT;
if (clearFlags) {
if (d_ptr->fbo)
d_ptr->fbo->bind();
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(clearFlags);
if (d_ptr->fbo)
d_ptr->fbo->release();
}
}

View File

@ -5,3 +5,11 @@ HEADERS += \
SOURCES += \
$$PWD/qglxconvenience.cpp
CONFIG += xrender
xrender {
LIBS += -lXrender
} else {
DEFINES += QT_NO_XRENDER
}

View File

@ -43,6 +43,10 @@
#include <QtCore/QVector>
#ifndef QT_NO_XRENDER
#include <X11/extensions/Xrender.h>
#endif
enum {
XFocusOut = FocusOut,
XFocusIn = FocusIn,
@ -84,14 +88,15 @@ QVector<int> qglx_buildSpec(const QPlatformWindowFormat &format, int drawableBit
spec[i++] = GLX_ALPHA_SIZE; spec[i++] = (format.alphaBufferSize() == -1) ? 1 : format.alphaBufferSize();
}
spec[i++] = GLX_ACCUM_RED_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize();
spec[i++] = GLX_ACCUM_GREEN_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize();
spec[i++] = GLX_ACCUM_BLUE_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize();
if (format.accum()) {
spec[i++] = GLX_ACCUM_RED_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize();
spec[i++] = GLX_ACCUM_GREEN_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize();
spec[i++] = GLX_ACCUM_BLUE_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize();
if (format.alpha()) {
spec[i++] = GLX_ACCUM_ALPHA_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize();
if (format.alpha()) {
spec[i++] = GLX_ACCUM_ALPHA_SIZE; spec[i++] = (format.accumBufferSize() == -1) ? 1 : format.accumBufferSize();
}
}
} else {
spec[i++] = GLX_RENDER_TYPE; spec[i++] = GLX_COLOR_INDEX_BIT; //I'm really not sure if this works....
spec[i++] = GLX_BUFFER_SIZE; spec[i++] = 8;
@ -136,8 +141,17 @@ GLXFBConfig qglx_findConfig(Display *display, int screen , const QPlatformWindow
if (reducedFormat.alpha()) {
int alphaSize;
glXGetFBConfigAttrib(display,configs[i],GLX_ALPHA_SIZE,&alphaSize);
if (alphaSize > 0)
break;
if (alphaSize > 0) {
XVisualInfo *visual = glXGetVisualFromFBConfig(display, chosenConfig);
#if !defined(QT_NO_XRENDER)
XRenderPictFormat *pictFormat = XRenderFindVisualFormat(display, visual->visual);
if (pictFormat->direct.alphaMask > 0)
break;
#else
if (visual->depth == 32)
break;
#endif
}
} else {
break; // Just choose the first in the list if there's no alpha requested
}

View File

@ -50,8 +50,8 @@ QMinimalIntegration::QMinimalIntegration()
QMinimalScreen *mPrimaryScreen = new QMinimalScreen();
mPrimaryScreen->mGeometry = QRect(0, 0, 240, 320);
mPrimaryScreen->mDepth = 16;
mPrimaryScreen->mFormat = QImage::Format_RGB16;
mPrimaryScreen->mDepth = 32;
mPrimaryScreen->mFormat = QImage::Format_ARGB32_Premultiplied;
mScreens.append(mPrimaryScreen);
}

View File

@ -51,7 +51,7 @@ class QMinimalScreen : public QPlatformScreen
{
public:
QMinimalScreen()
: mDepth(16), mFormat(QImage::Format_RGB16) {}
: mDepth(32), mFormat(QImage::Format_ARGB32_Premultiplied) {}
QRect geometry() const { return mGeometry; }
int depth() const { return mDepth; }

View File

@ -132,10 +132,12 @@ void QWaylandXCompositeGLXContext::geometryChanged()
Colormap cmap = XCreateColormap(mGlxIntegration->xDisplay(),mGlxIntegration->rootWindow(),visualInfo->visual,AllocNone);
XSetWindowAttributes a;
a.background_pixel = WhitePixel(mGlxIntegration->xDisplay(), mGlxIntegration->screen());
a.border_pixel = BlackPixel(mGlxIntegration->xDisplay(), mGlxIntegration->screen());
a.colormap = cmap;
mXWindow = XCreateWindow(mGlxIntegration->xDisplay(), mGlxIntegration->rootWindow(),0, 0, size.width(), size.height(),
0, visualInfo->depth, InputOutput, visualInfo->visual,
CWColormap, &a);
CWBackPixel|CWBorderPixel|CWColormap, &a);
XCompositeRedirectWindow(mGlxIntegration->xDisplay(), mXWindow, CompositeRedirectManual);
XMapWindow(mGlxIntegration->xDisplay(), mXWindow);

View File

@ -113,7 +113,8 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
#if defined(XCB_USE_GLX) || defined(XCB_USE_EGL)
if (tlw->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL
&& QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL))
&& QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)
|| tlw->platformWindowFormat().alpha())
{
#if defined(XCB_USE_GLX)
XVisualInfo *visualInfo = qglx_findVisualInfo(DISPLAY_FROM_XCB(m_screen),m_screen->screenNumber(), tlw->platformWindowFormat());
@ -131,13 +132,17 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
visualInfo = XGetVisualInfo(DISPLAY_FROM_XCB(this), VisualIDMask, &visualInfoTemplate, &matchingCount);
#endif //XCB_USE_GLX
if (visualInfo) {
m_depth = visualInfo->depth;
m_format = (m_depth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(this), m_screen->root(), visualInfo->visual, AllocNone);
XSetWindowAttributes a;
a.background_pixel = WhitePixel(DISPLAY_FROM_XCB(this), m_screen->screenNumber());
a.border_pixel = BlackPixel(DISPLAY_FROM_XCB(this), m_screen->screenNumber());
a.colormap = cmap;
m_window = XCreateWindow(DISPLAY_FROM_XCB(this), m_screen->root(), tlw->x(), tlw->y(), tlw->width(), tlw->height(),
0, visualInfo->depth, InputOutput, visualInfo->visual,
CWColormap, &a);
CWBackPixel|CWBorderPixel|CWColormap, &a);
printf("created GL window: %d\n", m_window);
} else {
@ -147,6 +152,8 @@ QXcbWindow::QXcbWindow(QWidget *tlw)
#endif //defined(XCB_USE_GLX) || defined(XCB_USE_EGL)
{
m_window = xcb_generate_id(xcb_connection());
m_depth = m_screen->screen()->root_depth;
m_format = (m_depth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
Q_XCB_CALL(xcb_create_window(xcb_connection(),
XCB_COPY_FROM_PARENT, // depth -- same as root

View File

@ -44,6 +44,7 @@
#include <QtGui/QPlatformWindow>
#include <QtGui/QPlatformWindowFormat>
#include <QtGui/QImage>
#include <xcb/xcb.h>
#include <xcb/sync.h>
@ -74,6 +75,8 @@ public:
QPlatformGLContext *glContext() const;
xcb_window_t window() const { return m_window; }
uint depth() const { return m_depth; }
QImage::Format format() const { return m_format; }
void handleExposeEvent(const xcb_expose_event_t *event);
void handleClientMessageEvent(const xcb_client_message_event_t *event);
@ -99,6 +102,9 @@ private:
xcb_window_t m_window;
QPlatformGLContext *m_context;
uint m_depth;
QImage::Format m_format;
xcb_sync_int64_t m_syncValue;
xcb_sync_counter_t m_syncCounter;

View File

@ -54,11 +54,12 @@
#include <stdio.h>
#include <qdebug.h>
#include <qpainter.h>
class QXcbShmImage : public QXcbObject
{
public:
QXcbShmImage(QXcbScreen *connection, const QSize &size);
QXcbShmImage(QXcbScreen *connection, const QSize &size, uint depth, QImage::Format format);
~QXcbShmImage() { destroy(); }
QImage *image() { return &m_qimage; }
@ -81,7 +82,7 @@ private:
QRegion m_dirty;
};
QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size)
QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QImage::Format format)
: QXcbObject(screen->connection())
, m_gc(0)
, m_gc_window(0)
@ -91,7 +92,7 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size)
size.width(),
size.height(),
XCB_IMAGE_FORMAT_Z_PIXMAP,
screen->depth(),
depth,
0,
~0,
0);
@ -111,7 +112,7 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size)
if (shmctl(m_shm_info.shmid, IPC_RMID, 0) == -1)
qWarning() << "QXcbWindowSurface: Error while marking the shared memory segment to be destroyed";
m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, screen->format());
m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, format);
}
void QXcbShmImage::destroy()
@ -189,6 +190,16 @@ QPaintDevice *QXcbWindowSurface::paintDevice()
void QXcbWindowSurface::beginPaint(const QRegion &region)
{
m_image->preparePaint(region);
if (m_image->image()->hasAlphaChannel()) {
QPainter p(m_image->image());
p.setCompositionMode(QPainter::CompositionMode_Source);
const QVector<QRect> rects = region.rects();
const QColor blank = Qt::transparent;
for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
p.fillRect(*it, blank);
}
}
}
void QXcbWindowSurface::endPaint(const QRegion &)
@ -232,9 +243,10 @@ void QXcbWindowSurface::resize(const QSize &size)
QWindowSurface::resize(size);
QXcbScreen *screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWidget(window()));
QXcbWindow* win = static_cast<QXcbWindow *>(window()->platformWindow());
delete m_image;
m_image = new QXcbShmImage(screen, size);
m_image = new QXcbShmImage(screen, size, win->depth(), win->format());
Q_XCB_NOOP(connection());
m_syncingResize = true;

View File

@ -150,7 +150,7 @@ bool QXlibIntegration::hasOpenGL() const
{
#if !defined(QT_NO_OPENGL)
#if !defined(QT_OPENGL_ES_2)
QXlibScreen *screen = static_cast<const QXlibScreen *>(mScreens.at(0));
QXlibScreen *screen = static_cast<QXlibScreen *>(mScreens.at(0));
return glXQueryExtension(screen->display()->nativeDisplay(), 0, 0) != 0;
#else
static bool eglHasbeenInitialized = false;

View File

@ -41,6 +41,8 @@
#include "qxlibscreen.h"
#include <X11/extensions/Xfixes.h>
#include "qxlibcursor.h"
#include "qxlibwindow.h"
#include "qxlibkeyboard.h"
@ -54,8 +56,6 @@
#include <private/qapplication_p.h>
#include <X11/extensions/Xfixes.h>
QT_BEGIN_NAMESPACE
static int (*original_x_errhandler)(Display *dpy, XErrorEvent *);
@ -201,7 +201,7 @@ QXlibScreen::QXlibScreen()
#ifndef DONT_USE_MIT_SHM
Status MIT_SHM_extension_supported = XShmQueryExtension (mDisplay->nativeDisplay());
int MIT_SHM_extension_supported = XShmQueryExtension (mDisplay->nativeDisplay());
Q_ASSERT(MIT_SHM_extension_supported == True);
#endif
original_x_errhandler = XSetErrorHandler(qt_x_errhandler);

View File

@ -51,10 +51,6 @@
#include <QDebug>
#ifndef QT_NO_XFIXES
#include <X11/extensions/Xfixes.h>
#endif // QT_NO_XFIXES
static const char * x11_atomnames = {
// window-manager <-> client protocols
"WM_PROTOCOLS\0"

View File

@ -135,6 +135,7 @@ typedef char *XPointer;
#endif
#ifndef QT_NO_XFIXES
#include <X11/extensions/Xfixes.h>
typedef Bool (*PtrXFixesQueryExtension)(Display *, int *, int *);
typedef Status (*PtrXFixesQueryVersion)(Display *, int *, int *);
typedef void (*PtrXFixesSetCursorName)(Display *dpy, Cursor cursor, const char *name);

View File

@ -47,14 +47,6 @@
#include "qxlibstatic.h"
#include "qxlibdisplay.h"
#include <QtGui/QWindowSystemInterface>
#include <QSocketNotifier>
#include <QApplication>
#include <QDebug>
#include <QtGui/private/qwindowsurface_p.h>
#include <QtGui/private/qapplication_p.h>
#if !defined(QT_NO_OPENGL)
#if !defined(QT_OPENGL_ES_2)
#include "qglxintegration.h"
@ -66,6 +58,15 @@
#endif //QT_OPENGL_ES_2
#endif //QT_NO_OPENGL
#include <QtGui/QWindowSystemInterface>
#include <QSocketNotifier>
#include <QApplication>
#include <QDebug>
#include <QtGui/private/qwindowsurface_p.h>
#include <QtGui/private/qapplication_p.h>
//#define MYX11_DEBUG
QT_BEGIN_NAMESPACE
@ -80,9 +81,10 @@ QXlibWindow::QXlibWindow(QWidget *window)
int w = window->width();
int h = window->height();
if(window->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL
&& QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL) ) {
#if !defined(QT_NO_OPENGL)
if(window->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL
&& QApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL)
|| window->platformWindowFormat().alpha()) {
#if !defined(QT_OPENGL_ES_2)
XVisualInfo *visualInfo = qglx_findVisualInfo(mScreen->display()->nativeDisplay(),mScreen->xScreenNumber(),window->platformWindowFormat());
#else
@ -101,18 +103,28 @@ QXlibWindow::QXlibWindow(QWidget *window)
visualInfo = XGetVisualInfo(mScreen->display()->nativeDisplay(), VisualIDMask, &visualInfoTemplate, &matchingCount);
#endif //!defined(QT_OPENGL_ES_2)
if (visualInfo) {
Colormap cmap = XCreateColormap(mScreen->display()->nativeDisplay(),mScreen->rootWindow(),visualInfo->visual,AllocNone);
mDepth = visualInfo->depth;
mFormat = (mDepth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
mVisual = visualInfo->visual;
Colormap cmap = XCreateColormap(mScreen->display()->nativeDisplay(), mScreen->rootWindow(), visualInfo->visual, AllocNone);
XSetWindowAttributes a;
a.background_pixel = WhitePixel(mScreen->display()->nativeDisplay(), mScreen->xScreenNumber());
a.border_pixel = BlackPixel(mScreen->display()->nativeDisplay(), mScreen->xScreenNumber());
a.colormap = cmap;
x_window = XCreateWindow(mScreen->display()->nativeDisplay(), mScreen->rootWindow(),x, y, w, h,
0, visualInfo->depth, InputOutput, visualInfo->visual,
CWColormap, &a);
CWBackPixel|CWBorderPixel|CWColormap, &a);
} else {
qFatal("no window!");
}
} else
#endif //!defined(QT_NO_OPENGL)
} else {
{
mDepth = mScreen->depth();
mFormat = (mDepth == 32) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
mVisual = mScreen->defaultVisual();
x_window = XCreateSimpleWindow(mScreen->display()->nativeDisplay(), mScreen->rootWindow(),
x, y, w, h, 0 /*border_width*/,
mScreen->blackPixel(), mScreen->whitePixel());

View File

@ -122,6 +122,10 @@ public:
Window xWindow() const;
GC graphicsContext() const;
inline uint depth() const { return mDepth; }
QImage::Format format() const { return mFormat; }
Visual* visual() const { return mVisual; }
protected:
QVector<Atom> getNetWmState() const;
void setMWMHints(const QXlibMWMHints &mwmhints);
@ -135,6 +139,10 @@ private:
Window x_window;
GC gc;
uint mDepth;
QImage::Format mFormat;
Visual* mVisual;
GC createGC();
QPlatformGLContext *mGLContext;

View File

@ -49,6 +49,8 @@
#include "qxlibscreen.h"
#include "qxlibdisplay.h"
#include "qpainter.h"
# include <sys/ipc.h>
# include <sys/shm.h>
# include <X11/extensions/XShm.h>
@ -80,20 +82,19 @@ void QXlibShmImageInfo::destroy()
void QXlibWindowSurface::resizeShmImage(int width, int height)
{
QXlibScreen *screen = QXlibScreen::testLiteScreenForWidget(window());
QXlibWindow *win = static_cast<QXlibWindow*>(window()->platformWindow());
#ifdef DONT_USE_MIT_SHM
shm_img = QImage(width, height, QImage::Format_RGB32);
shm_img = QImage(width, height, win->format());
#else
QXlibScreen *screen = QXlibScreen::testLiteScreenForWidget(window());
if (image_info)
image_info->destroy();
else
image_info = new QXlibShmImageInfo(screen->display()->nativeDisplay());
Visual *visual = screen->defaultVisual();
XImage *image = XShmCreateImage (screen->display()->nativeDisplay(), visual, 24, ZPixmap, 0,
XImage *image = XShmCreateImage (screen->display()->nativeDisplay(), win->visual(), win->depth(), ZPixmap, 0,
&image_info->shminfo, width, height);
@ -109,7 +110,7 @@ void QXlibWindowSurface::resizeShmImage(int width, int height)
Q_ASSERT(shm_attach_status == True);
shm_img = QImage( (uchar*) image->data, image->width, image->height, image->bytes_per_line, QImage::Format_RGB32 );
shm_img = QImage( (uchar*) image->data, image->width, image->height, image->bytes_per_line, win->format() );
#endif
painted = false;
}
@ -160,11 +161,11 @@ void QXlibWindowSurface::flush(QWidget *widget, const QRegion &region, const QPo
#ifdef DONT_USE_MIT_SHM
// just convert the image every time...
if (!shm_img.isNull()) {
Visual *visual = DefaultVisual(screen->display(), screen->xScreenNumber());
QXlibWindow *win = static_cast<QXlibWindow*>(window()->platformWindow());
QImage image = shm_img;
//img.convertToFormat(
XImage *xi = XCreateImage(screen->display(), visual, 24, ZPixmap,
XImage *xi = XCreateImage(screen->display(), win->visual(), win->depth(), ZPixmap,
0, (char *) image.scanLine(0), image.width(), image.height(),
32, image.bytesPerLine());
@ -214,6 +215,16 @@ void QXlibWindowSurface::beginPaint(const QRegion &region)
{
Q_UNUSED(region);
resizeBuffer(size());
if (shm_img.hasAlphaChannel()) {
QPainter p(&shm_img);
p.setCompositionMode(QPainter::CompositionMode_Source);
const QVector<QRect> rects = region.rects();
const QColor blank = Qt::transparent;
for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
p.fillRect(*it, blank);
}
}
}
void QXlibWindowSurface::endPaint(const QRegion &region)